Merge commit 'ea86293b0aae2ab43e317256fe042225209de6a0' into merge-pnacl-3.5

This merges in PNaCl's clang 3.5.

1.28.3

Conflicts:
	lib/AST/ASTContext.cpp
	lib/Driver/Driver.cpp
diff --git a/.arcconfig b/.arcconfig
index 7f45342..7540b46 100644
--- a/.arcconfig
+++ b/.arcconfig
@@ -1,4 +1,4 @@
 {
   "project_id" : "clang",
-  "conduit_uri" : "http://llvm-reviews.chandlerc.com/"
+  "conduit_uri" : "http://reviews.llvm.org/"
 }
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8d02bf0..02374e2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,76 +1,169 @@
+cmake_minimum_required(VERSION 2.8.8)
+
+# FIXME: It may be removed when we use 2.8.12.
+if(CMAKE_VERSION VERSION_LESS 2.8.12)
+  # Invalidate a couple of keywords.
+  set(cmake_2_8_12_INTERFACE)
+  set(cmake_2_8_12_PRIVATE)
+else()
+  # Use ${cmake_2_8_12_KEYWORD} intead of KEYWORD in target_link_libraries().
+  set(cmake_2_8_12_INTERFACE INTERFACE)
+  set(cmake_2_8_12_PRIVATE PRIVATE)
+  if(POLICY CMP0022)
+    cmake_policy(SET CMP0022 NEW) # automatic when 2.8.12 is required
+  endif()
+endif()
+
 # If we are not building as a part of LLVM, build Clang as an
 # standalone project, using LLVM as an external library:
 if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR )
   project(Clang)
-  cmake_minimum_required(VERSION 2.8)
 
-  set(CLANG_PATH_TO_LLVM_SOURCE "" CACHE PATH
-    "Path to LLVM source code. Not necessary if using an installed LLVM.")
-  set(CLANG_PATH_TO_LLVM_BUILD "" CACHE PATH
-    "Path to the directory where LLVM was built or installed.")
-
-  if( CLANG_PATH_TO_LLVM_SOURCE )
-    if( NOT EXISTS "${CLANG_PATH_TO_LLVM_SOURCE}/cmake/config-ix.cmake" )
-      message(FATAL_ERROR "Please set CLANG_PATH_TO_LLVM_SOURCE to the root directory of LLVM source code.")
+  # Rely on llvm-config.
+  set(CONFIG_OUTPUT)
+  find_program(LLVM_CONFIG "llvm-config")
+  if(LLVM_CONFIG)
+    message(STATUS "Found LLVM_CONFIG as ${LLVM_CONFIG}")
+    set(CONFIG_COMMAND ${LLVM_CONFIG}
+      "--assertion-mode"
+      "--bindir"
+      "--libdir"
+      "--includedir"
+      "--prefix"
+      "--src-root")
+    execute_process(
+      COMMAND ${CONFIG_COMMAND}
+      RESULT_VARIABLE HAD_ERROR
+      OUTPUT_VARIABLE CONFIG_OUTPUT
+    )
+    if(NOT HAD_ERROR)
+      string(REGEX REPLACE
+        "[ \t]*[\r\n]+[ \t]*" ";"
+        CONFIG_OUTPUT ${CONFIG_OUTPUT})
     else()
-      get_filename_component(LLVM_MAIN_SRC_DIR ${CLANG_PATH_TO_LLVM_SOURCE}
-	ABSOLUTE)
-      list(APPEND CMAKE_MODULE_PATH "${LLVM_MAIN_SRC_DIR}/cmake/modules")
+      string(REPLACE ";" " " CONFIG_COMMAND_STR "${CONFIG_COMMAND}")
+      message(STATUS "${CONFIG_COMMAND_STR}")
+      message(FATAL_ERROR "llvm-config failed with status ${HAD_ERROR}")
     endif()
-  endif()
-
-  if (EXISTS "${CLANG_PATH_TO_LLVM_BUILD}/bin/llvm-config${CMAKE_EXECUTABLE_SUFFIX}")
-    set (PATH_TO_LLVM_CONFIG "${CLANG_PATH_TO_LLVM_BUILD}/bin/llvm-config${CMAKE_EXECUTABLE_SUFFIX}")
-  elseif (EXISTS "${CLANG_PATH_TO_LLVM_BUILD}/bin/Debug/llvm-config${CMAKE_EXECUTABLE_SUFFIX}")
-    # Looking for bin/Debug/llvm-config is a complete hack. How can we get
-    # around this?
-    set (PATH_TO_LLVM_CONFIG "${CLANG_PATH_TO_LLVM_BUILD}/bin/Debug/llvm-config${CMAKE_EXECUTABLE_SUFFIX}")
   else()
-    message(FATAL_ERROR "Please set CLANG_PATH_TO_LLVM_BUILD to a directory containing a LLVM build.")
+    message(FATAL_ERROR "llvm-config not found -- ${LLVM_CONFIG}")
   endif()
 
-  list(APPEND CMAKE_MODULE_PATH "${CLANG_PATH_TO_LLVM_BUILD}/share/llvm/cmake")
+  list(GET CONFIG_OUTPUT 0 ENABLE_ASSERTIONS)
+  list(GET CONFIG_OUTPUT 1 TOOLS_BINARY_DIR)
+  list(GET CONFIG_OUTPUT 2 LIBRARY_DIR)
+  list(GET CONFIG_OUTPUT 3 INCLUDE_DIR)
+  list(GET CONFIG_OUTPUT 4 LLVM_OBJ_ROOT)
+  list(GET CONFIG_OUTPUT 5 MAIN_SRC_DIR)
 
-  get_filename_component(PATH_TO_LLVM_BUILD ${CLANG_PATH_TO_LLVM_BUILD}
-    ABSOLUTE)
+  if(NOT MSVC_IDE)
+    set(LLVM_ENABLE_ASSERTIONS ${ENABLE_ASSERTIONS}
+      CACHE BOOL "Enable assertions")
+    # Assertions should follow llvm-config's.
+    mark_as_advanced(LLVM_ENABLE_ASSERTIONS)
+  endif()
 
-  option(LLVM_INSTALL_TOOLCHAIN_ONLY "Only include toolchain files in the 'install' target." OFF)
+  set(LLVM_TOOLS_BINARY_DIR ${TOOLS_BINARY_DIR} CACHE PATH "Path to llvm/bin")
+  set(LLVM_LIBRARY_DIR ${LIBRARY_DIR} CACHE PATH "Path to llvm/lib")
+  set(LLVM_MAIN_INCLUDE_DIR ${INCLUDE_DIR} CACHE PATH "Path to llvm/include")
+  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")
+
+  find_program(LLVM_TABLEGEN_EXE "llvm-tblgen" ${LLVM_TOOLS_BINARY_DIR}
+    NO_DEFAULT_PATH)
+
+  set(LLVM_CMAKE_PATH "${LLVM_BINARY_DIR}/share/llvm/cmake")
+  set(LLVMCONFIG_FILE "${LLVM_CMAKE_PATH}/LLVMConfig.cmake")
+  if(EXISTS ${LLVMCONFIG_FILE})
+    list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_PATH}")
+    include(${LLVMCONFIG_FILE})
+  else()
+    message(FATAL_ERROR "Not found: ${LLVMCONFIG_FILE}")
+  endif()
+
+  # They are used as destination of target generators.
+  set(LLVM_RUNTIME_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin)
+  set(LLVM_LIBRARY_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib)
+
+  option(LLVM_INSTALL_TOOLCHAIN_ONLY
+    "Only include toolchain files in the 'install' target." OFF)
+
+  option(LLVM_FORCE_USE_OLD_HOST_TOOLCHAIN
+    "Set to ON to force using an old, unsupported host toolchain." OFF)
 
   include(AddLLVM)
   include(TableGen)
-  include("${CLANG_PATH_TO_LLVM_BUILD}/share/llvm/cmake/LLVMConfig.cmake")
   include(HandleLLVMOptions)
 
   set(PACKAGE_VERSION "${LLVM_PACKAGE_VERSION}")
 
-  set(LLVM_MAIN_INCLUDE_DIR "${LLVM_MAIN_SRC_DIR}/include")
-  set(LLVM_BINARY_DIR ${CMAKE_BINARY_DIR})
-
-  set(CMAKE_INCLUDE_CURRENT_DIR ON)
-  include_directories("${PATH_TO_LLVM_BUILD}/include" "${LLVM_MAIN_INCLUDE_DIR}")
-  link_directories("${PATH_TO_LLVM_BUILD}/lib")
-
-  exec_program("${PATH_TO_LLVM_CONFIG} --bindir" OUTPUT_VARIABLE LLVM_BINARY_DIR)
-  set(LLVM_TABLEGEN_EXE "${LLVM_BINARY_DIR}/llvm-tblgen${CMAKE_EXECUTABLE_SUFFIX}")
-
-  # Define the default arguments to use with 'lit', and an option for the user
-  # to override.
-  set(LIT_ARGS_DEFAULT "-sv")
-  if (MSVC OR XCODE)
-    set(LIT_ARGS_DEFAULT "${LIT_ARGS_DEFAULT} --no-progress-bar")
+  if (NOT DEFINED LLVM_INCLUDE_TESTS)
+    set(LLVM_INCLUDE_TESTS ON)
   endif()
-  set(LLVM_LIT_ARGS "${LIT_ARGS_DEFAULT}" CACHE STRING "Default options for lit")
+
+  include_directories("${LLVM_BINARY_DIR}/include" "${LLVM_MAIN_INCLUDE_DIR}")
+  link_directories("${LLVM_LIBRARY_DIR}")
 
   set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin )
   set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib )
   set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib )
 
-  set( CLANG_BUILT_STANDALONE 1 )
+  if(LLVM_INCLUDE_TESTS)
+    # Check prebuilt llvm/utils.
+    if(EXISTS ${LLVM_TOOLS_BINARY_DIR}/FileCheck${CMAKE_EXECUTABLE_SUFFIX}
+        AND EXISTS ${LLVM_TOOLS_BINARY_DIR}/count${CMAKE_EXECUTABLE_SUFFIX}
+        AND EXISTS ${LLVM_TOOLS_BINARY_DIR}/not${CMAKE_EXECUTABLE_SUFFIX})
+      set(LLVM_UTILS_PROVIDED ON)
+    endif()
 
-  find_package(LibXml2)
-  if (LIBXML2_FOUND)
-    set(CLANG_HAVE_LIBXML 1)
-  endif ()
+    if(EXISTS ${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py)
+      set(LLVM_LIT ${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py)
+      if(NOT LLVM_UTILS_PROVIDED)
+        add_subdirectory(${LLVM_MAIN_SRC_DIR}/utils/FileCheck utils/FileCheck)
+        add_subdirectory(${LLVM_MAIN_SRC_DIR}/utils/count utils/count)
+        add_subdirectory(${LLVM_MAIN_SRC_DIR}/utils/not utils/not)
+        set(LLVM_UTILS_PROVIDED ON)
+        set(CLANG_TEST_DEPS FileCheck count not)
+      endif()
+      set(UNITTEST_DIR ${LLVM_MAIN_SRC_DIR}/utils/unittest)
+      if(EXISTS ${UNITTEST_DIR}/googletest/include/gtest/gtest.h
+          AND NOT EXISTS ${LLVM_LIBRARY_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}gtest${CMAKE_STATIC_LIBRARY_SUFFIX}
+          AND EXISTS ${UNITTEST_DIR}/CMakeLists.txt)
+        add_subdirectory(${UNITTEST_DIR} utils/unittest)
+      endif()
+    else()
+      # Seek installed Lit.
+      find_program(LLVM_LIT "lit.py" ${LLVM_MAIN_SRC_DIR}/utils/lit
+        DOC "Path to lit.py")
+    endif()
+
+    if(LLVM_LIT)
+      # Define the default arguments to use with 'lit', and an option for the user
+      # to override.
+      set(LIT_ARGS_DEFAULT "-sv")
+      if (MSVC OR XCODE)
+        set(LIT_ARGS_DEFAULT "${LIT_ARGS_DEFAULT} --no-progress-bar")
+      endif()
+      set(LLVM_LIT_ARGS "${LIT_ARGS_DEFAULT}" CACHE STRING "Default options for lit")
+
+      # On Win32 hosts, provide an option to specify the path to the GnuWin32 tools.
+      if( WIN32 AND NOT CYGWIN )
+        set(LLVM_LIT_TOOLS_DIR "" CACHE PATH "Path to GnuWin32 tools")
+      endif()
+    else()
+      set(LLVM_INCLUDE_TESTS OFF)
+    endif()
+  endif()
+
+  set( CLANG_BUILT_STANDALONE 1 )
+  set(BACKEND_PACKAGE_STRING "LLVM ${LLVM_PACKAGE_VERSION}")
+else()
+  set(BACKEND_PACKAGE_STRING "${PACKAGE_STRING}")
+endif()
+
+find_package(LibXml2)
+if (LIBXML2_FOUND)
+  set(CLANG_HAVE_LIBXML 1)
 endif()
 
 set(CLANG_RESOURCE_DIR "" CACHE STRING
@@ -160,15 +253,11 @@
   endif()
 endif ()
 
-if (APPLE)
-  set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,-flat_namespace -Wl,-undefined -Wl,suppress")
-endif ()
-
 configure_file(
   ${CLANG_SOURCE_DIR}/include/clang/Config/config.h.cmake
   ${CLANG_BINARY_DIR}/include/clang/Config/config.h)
 
-include(LLVMParseArguments)
+include(CMakeParseArguments)
 
 function(clang_tablegen)
   # Syntax:
@@ -183,59 +272,29 @@
   # executing the custom command depending on output-file. It is
   # possible to list more files to depend after DEPENDS.
 
-  parse_arguments( CTG "SOURCE;TARGET;DEPENDS" "" ${ARGN} )
+  cmake_parse_arguments(CTG "" "SOURCE;TARGET" "" ${ARGN})
 
   if( NOT CTG_SOURCE )
     message(FATAL_ERROR "SOURCE source-file required by clang_tablegen")
   endif()
 
   set( LLVM_TARGET_DEFINITIONS ${CTG_SOURCE} )
-  tablegen( CLANG ${CTG_DEFAULT_ARGS} )
+  tablegen(CLANG ${CTG_UNPARSED_ARGUMENTS})
 
-  list( GET CTG_DEFAULT_ARGS 0 output_file )
-  if( CTG_TARGET )
-    add_custom_target( ${CTG_TARGET} DEPENDS ${output_file} ${CTG_DEPENDS} )
+  if(CTG_TARGET)
+    add_public_tablegen_target(${CTG_TARGET})
     set_target_properties( ${CTG_TARGET} PROPERTIES FOLDER "Clang tablegenning")
+    set_property(GLOBAL APPEND PROPERTY CLANG_TABLEGEN_TARGETS ${CTG_TARGET})
   endif()
 endfunction(clang_tablegen)
 
-# FIXME: Generalize and move to llvm.
-function(add_clang_symbol_exports target_name export_file)
-  # Makefile.rules contains special cases for different platforms.
-  # We restrict ourselves to Darwin for the time being.
-  if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
-    add_custom_command(OUTPUT symbol.exports
-      COMMAND sed -e "s/^/_/" < ${export_file} > symbol.exports
-      DEPENDS ${export_file}
-      VERBATIM
-      COMMENT "Creating export file for ${target_name}")
-    add_custom_target(${target_name}_exports DEPENDS symbol.exports)
-    set_property(DIRECTORY APPEND
-      PROPERTY ADDITIONAL_MAKE_CLEAN_FILES symbol.exports)
-
-    get_property(srcs TARGET ${target_name} PROPERTY SOURCES)
-    foreach(src ${srcs})
-      get_filename_component(extension ${src} EXT)
-      if(extension STREQUAL ".cpp")
-        set(first_source_file ${src})
-        break()
-      endif()
-    endforeach()
-  
-    # Force re-linking when the exports file changes. Actually, it
-    # forces recompilation of the source file. The LINK_DEPENDS target
-    # property only works for makefile-based generators.
-    set_property(SOURCE ${first_source_file} APPEND PROPERTY
-      OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/symbol.exports)
-  
-    set_property(TARGET ${target_name} APPEND_STRING PROPERTY
-                 LINK_FLAGS " -Wl,-exported_symbols_list,${CMAKE_CURRENT_BINARY_DIR}/symbol.exports")
-    add_dependencies(${target_name} ${target_name}_exports)
-  endif()
-endfunction(add_clang_symbol_exports)
-
 macro(add_clang_library name)
-  llvm_process_sources(srcs ${ARGN})
+  cmake_parse_arguments(ARG
+    ""
+    ""
+    "ADDITIONAL_HEADERS"
+    ${ARGN})
+  set(srcs)
   if(MSVC_IDE OR XCODE)
     # Add public headers
     file(RELATIVE_PATH lib_path
@@ -255,34 +314,32 @@
       source_group("TableGen descriptions" FILES ${tds})
       set_source_files_properties(${tds}} PROPERTIES HEADER_FILE_ONLY ON)
 
-      set(srcs ${srcs} ${headers} ${tds})
+      if(headers OR tds)
+	set(srcs ${headers} ${tds})
+      endif()
     endif()
   endif(MSVC_IDE OR XCODE)
-  if (MODULE)
-    set(libkind MODULE)
-  elseif (SHARED_LIBRARY)
-    set(libkind SHARED)
+  if(srcs OR ARG_ADDITIONAL_HEADERS)
+    set(srcs
+      ADDITIONAL_HEADERS
+      ${srcs}
+      ${ARG_ADDITIONAL_HEADERS} # It may contain unparsed unknown args.
+      )
+  endif()
+  llvm_add_library(${name} ${ARG_UNPARSED_ARGUMENTS} ${srcs})
+
+  if(TARGET ${name})
+    target_link_libraries(${name} ${cmake_2_8_12_INTERFACE} ${LLVM_COMMON_LIBS})
+
+    if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY OR ${name} STREQUAL "libclang")
+      install(TARGETS ${name}
+        LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
+        ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX}
+        RUNTIME DESTINATION bin)
+    endif()
   else()
-    set(libkind)
-  endif()
-  add_library( ${name} ${libkind} ${srcs} )
-  if( LLVM_COMMON_DEPENDS )
-    add_dependencies( ${name} ${LLVM_COMMON_DEPENDS} )
-  endif( LLVM_COMMON_DEPENDS )
-
-  llvm_config( ${name} ${LLVM_LINK_COMPONENTS} )
-  target_link_libraries( ${name} ${LLVM_COMMON_LIBS} )
-  link_system_libs( ${name} )
-  
-  if (SHARED_LIBRARY AND EXPORTED_SYMBOL_FILE)
-    add_clang_symbol_exports( ${name} ${EXPORTED_SYMBOL_FILE} ) 
-  endif()
-
-  if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY OR ${name} STREQUAL "libclang")
-    install(TARGETS ${name}
-      LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
-      ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX}
-      RUNTIME DESTINATION bin)
+    # Add empty "phony" target
+    add_custom_target(${name})
   endif()
 
   set_target_properties(${name} PROPERTIES FOLDER "Clang libraries")
@@ -293,13 +350,15 @@
   set_target_properties(${name} PROPERTIES FOLDER "Clang executables")
 endmacro(add_clang_executable)
 
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
 include_directories(BEFORE
   ${CMAKE_CURRENT_BINARY_DIR}/include
   ${CMAKE_CURRENT_SOURCE_DIR}/include
   )
 
 if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
-  install(DIRECTORY include/
+  install(DIRECTORY include/clang include/clang-c
     DESTINATION include
     FILES_MATCHING
     PATTERN "*.def"
@@ -308,7 +367,7 @@
     PATTERN ".svn" EXCLUDE
     )
 
-  install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/
+  install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/clang
     DESTINATION include
     FILES_MATCHING
     PATTERN "CMakeFiles" EXCLUDE
@@ -326,15 +385,17 @@
 add_definitions( -D_GNU_SOURCE )
 
 option(CLANG_ENABLE_ARCMT "Build ARCMT." ON)
-option(CLANG_ENABLE_REWRITER "Build rewriter." ON)
-option(CLANG_ENABLE_STATIC_ANALYZER "Build static analyzer." ON)
-
-if (NOT CLANG_ENABLE_REWRITER AND CLANG_ENABLE_ARCMT)
-  message(FATAL_ERROR "Cannot disable rewriter while enabling ARCMT")
+if (CLANG_ENABLE_ARCMT)
+  set(ENABLE_CLANG_ARCMT "1")
+else()
+  set(ENABLE_CLANG_ARCMT "0")
 endif()
 
-if (NOT CLANG_ENABLE_REWRITER AND CLANG_ENABLE_STATIC_ANALYZER)
-  message(FATAL_ERROR "Cannot disable rewriter while enabling static analyzer")
+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)
@@ -343,9 +404,7 @@
 
 if(CLANG_ENABLE_ARCMT)
   add_definitions(-DCLANG_ENABLE_ARCMT)
-endif()
-if(CLANG_ENABLE_REWRITER)
-  add_definitions(-DCLANG_ENABLE_REWRITER)
+  add_definitions(-DCLANG_ENABLE_OBJC_REWRITER)
 endif()
 if(CLANG_ENABLE_STATIC_ANALYZER)
   add_definitions(-DCLANG_ENABLE_STATIC_ANALYZER)
@@ -363,11 +422,21 @@
 add_subdirectory(utils/TableGen)
 
 add_subdirectory(include)
+
+# All targets below may depend on all tablegen'd files.
+get_property(CLANG_TABLEGEN_TARGETS GLOBAL PROPERTY CLANG_TABLEGEN_TARGETS)
+list(APPEND LLVM_COMMON_DEPENDS ${CLANG_TABLEGEN_TARGETS})
+
 add_subdirectory(lib)
 add_subdirectory(tools)
 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)
 
 option(CLANG_INCLUDE_TESTS
@@ -375,8 +444,30 @@
        ${LLVM_INCLUDE_TESTS})
 
 if( CLANG_INCLUDE_TESTS )
+  if(EXISTS ${LLVM_MAIN_SRC_DIR}/utils/unittest/googletest/include/gtest/gtest.h)
+    add_subdirectory(unittests)
+    list(APPEND CLANG_TEST_DEPS ClangUnitTests)
+    list(APPEND CLANG_TEST_PARAMS
+      clang_unit_site_config=${CMAKE_CURRENT_BINARY_DIR}/test/Unit/lit.site.cfg
+      )
+  endif()
   add_subdirectory(test)
-  add_subdirectory(unittests)
+
+  if(CLANG_BUILT_STANDALONE)
+    # Add a global check rule now that all subdirectories have been traversed
+    # and we know the total set of lit testsuites.
+    get_property(LLVM_LIT_TESTSUITES GLOBAL PROPERTY LLVM_LIT_TESTSUITES)
+    get_property(LLVM_LIT_PARAMS GLOBAL PROPERTY LLVM_LIT_PARAMS)
+    get_property(LLVM_LIT_DEPENDS GLOBAL PROPERTY LLVM_LIT_DEPENDS)
+    get_property(LLVM_LIT_EXTRA_ARGS GLOBAL PROPERTY LLVM_LIT_EXTRA_ARGS)
+    add_lit_target(check-all
+      "Running all regression tests"
+      ${LLVM_LIT_TESTSUITES}
+      PARAMS ${LLVM_LIT_PARAMS}
+      DEPENDS ${LLVM_LIT_DEPENDS}
+      ARGS ${LLVM_LIT_EXTRA_ARGS}
+      )
+  endif()
 endif()
 
 option(CLANG_INCLUDE_DOCS "Generate build targets for the Clang docs."
@@ -385,17 +476,5 @@
   add_subdirectory(docs)
 endif()
 
-# Workaround for MSVS10 to avoid the Dialog Hell
-# FIXME: This could be removed with future version of CMake.
-if( CLANG_BUILT_STANDALONE AND MSVC_VERSION EQUAL 1600 )
-  set(CLANG_SLN_FILENAME "${CMAKE_CURRENT_BINARY_DIR}/Clang.sln")
-  if( EXISTS "${CLANG_SLN_FILENAME}" )
-    file(APPEND "${CLANG_SLN_FILENAME}" "\n# This should be regenerated!\n")
-  endif()
-endif()
-
-set(BUG_REPORT_URL "http://llvm.org/bugs/" CACHE STRING
-  "Default URL where bug reports are to be submitted.")
-
 set(CLANG_ORDER_FILE "" CACHE FILEPATH
   "Order file to use when compiling clang in order to improve startup time.")
diff --git a/CODE_OWNERS.TXT b/CODE_OWNERS.TXT
index af50831..bbd3142 100644
--- a/CODE_OWNERS.TXT
+++ b/CODE_OWNERS.TXT
@@ -8,6 +8,10 @@
 (W), PGP key ID and fingerprint (P), description (D), and snail-mail address
 (S).
 
+N: Aaron Ballman
+E: aaron@aaronballman.com
+D: Clang attributes
+
 N: Chandler Carruth
 E: chandlerc@gmail.com
 E: chandlerc@google.com
diff --git a/LICENSE.TXT b/LICENSE.TXT
index e31223a..3b1153d 100644
--- a/LICENSE.TXT
+++ b/LICENSE.TXT
@@ -4,7 +4,7 @@
 University of Illinois/NCSA
 Open Source License
 
-Copyright (c) 2007-2013 University of Illinois at Urbana-Champaign.
+Copyright (c) 2007-2014 University of Illinois at Urbana-Champaign.
 All rights reserved.
 
 Developed by:
diff --git a/Makefile b/Makefile
index cb2566a..bbc521f 100644
--- a/Makefile
+++ b/Makefile
@@ -23,6 +23,12 @@
 endif
 endif
 
+ifeq ($(BUILD_EXAMPLES),1)
+  ENABLE_CLANG_EXAMPLES := 1
+else
+  ENABLE_CLANG_EXAMPLES := 0
+endif
+
 ifeq ($(MAKECMDGOALS),libs-only)
   DIRS := $(filter-out tools docs, $(DIRS))
   OPTIONAL_DIRS :=
diff --git a/NOTES.txt b/NOTES.txt
index 107ec5a..53f35a0 100644
--- a/NOTES.txt
+++ b/NOTES.txt
@@ -34,11 +34,11 @@
    3. File UIDs are created on request, not when files are opened.
  These changes make it possible to efficiently have FileEntry objects for
  files that exist on the file system, but have not been used yet.
- 
+
  Once this is done:
    1. DirectoryEntry gets a boolean value "has read entries".  When false, not
       all entries in the directory are in the file mgr, when true, they are.
-   2. Instead of stat'ing the file in FileManager::getFile, check to see if 
+   2. Instead of stat'ing the file in FileManager::getFile, check to see if
       the dir has been read.  If so, fail immediately, if not, read the dir,
       then retry.
    3. Reading the dir uses the getdirentries syscall, creating a FileEntry
@@ -55,18 +55,18 @@
 
 (1) If the user does not specify -triple, we default to the host triple.
 (2) If the user specifies a -arch, that overrides the arch in the host or
-    specified triple. 
+    specified triple.
 
 //===---------------------------------------------------------------------===//
 
 
-verifyInputConstraint and verifyOutputConstraint should not return bool. 
+verifyInputConstraint and verifyOutputConstraint should not return bool.
 
 Instead we should return something like:
 
 enum VerifyConstraintResult {
   Valid,
-  
+
   // Output only
   OutputOperandConstraintLacksEqualsCharacter,
   MatchingConstraintNotValidInOutputOperand,
@@ -74,7 +74,7 @@
   // Input only
   InputOperandConstraintContainsEqualsCharacter,
   MatchingConstraintReferencesInvalidOperandNumber,
-  
+
   // Both
   PercentConstraintUsedWithLastOperand
 };
diff --git a/README.txt b/README.txt
index 44ce723..474c67c 100644
--- a/README.txt
+++ b/README.txt
@@ -8,7 +8,7 @@
 
 Unlike many other compiler frontends, Clang is useful for a number of things
 beyond just compiling code: we intend for Clang to be host to a number of
-different source level tools.  One example of this is the Clang Static Analyzer.
+different source-level tools.  One example of this is the Clang Static Analyzer.
 
 If you're interested in more (including how to build Clang) it is best to read
 the relevant web sites.  Here are some pointers:
diff --git a/bindings/python/clang/cindex.py b/bindings/python/clang/cindex.py
index c103c70..517b3c1 100644
--- a/bindings/python/clang/cindex.py
+++ b/bindings/python/clang/cindex.py
@@ -272,7 +272,7 @@
             return False
         if other.file is None and self.start.file is None:
             pass
-        elif ( self.start.file.name != other.file.name or 
+        elif ( self.start.file.name != other.file.name or
                other.file.name != self.end.file.name):
             # same file name
             return False
@@ -361,13 +361,13 @@
 
     @property
     def category_number(self):
-        """The category number for this diagnostic."""
+        """The category number for this diagnostic or 0 if unavailable."""
         return conf.lib.clang_getDiagnosticCategory(self)
 
     @property
     def category_name(self):
         """The string name of the category for this diagnostic."""
-        return conf.lib.clang_getDiagnosticCategoryName(self.category_number)
+        return conf.lib.clang_getDiagnosticCategoryText(self)
 
     @property
     def option(self):
@@ -748,7 +748,7 @@
 # that has not yet been resolved to a specific function or function template.
 CursorKind.OVERLOADED_DECL_REF = CursorKind(49)
 
-# A reference to a variable that occurs in some non-expression 
+# A reference to a variable that occurs in some non-expression
 # context, e.g., a C++ lambda capture list.
 CursorKind.VARIABLE_REF = CursorKind(50)
 
@@ -937,7 +937,7 @@
 
 # Represents a C++ lambda expression that produces a local function
 # object.
-# 
+#
 #  \code
 #  void abssort(float *x, unsigned N) {
 #    std::sort(x, x + N,
@@ -947,7 +947,7 @@
 #  }
 #  \endcode
 CursorKind.LAMBDA_EXPR = CursorKind(144)
-  
+
 # Objective-c Boolean Literal.
 CursorKind.OBJ_BOOL_LITERAL_EXPR = CursorKind(145)
 
@@ -1079,6 +1079,13 @@
 CursorKind.ANNOTATE_ATTR = CursorKind(406)
 CursorKind.ASM_LABEL_ATTR = CursorKind(407)
 CursorKind.PACKED_ATTR = CursorKind(408)
+CursorKind.PURE_ATTR = CursorKind(409)
+CursorKind.CONST_ATTR = CursorKind(410)
+CursorKind.NODUPLICATE_ATTR = CursorKind(411)
+CursorKind.CUDACONSTANT_ATTR = CursorKind(412)
+CursorKind.CUDADEVICE_ATTR = CursorKind(413)
+CursorKind.CUDAGLOBAL_ATTR = CursorKind(414)
+CursorKind.CUDAHOST_ATTR = CursorKind(415)
 
 ###
 # Preprocessing
@@ -1159,10 +1166,6 @@
     @property
     def spelling(self):
         """Return the spelling of the entity pointed at by the cursor."""
-        if not self.kind.is_declaration():
-            # FIXME: clang_getCursorSpelling should be fixed to not assert on
-            # this, for consistency with clang_getCursorUSR.
-            return None
         if not hasattr(self, '_spelling'):
             self._spelling = conf.lib.clang_getCursorSpelling(self)
 
@@ -1205,6 +1208,17 @@
         return self._extent
 
     @property
+    def access_specifier(self):
+        """
+        Retrieves the access specifier (if any) of the entity pointed at by the
+        cursor.
+        """
+        if not hasattr(self, '_access_specifier'):
+            self._access_specifier = conf.lib.clang_getCXXAccessSpecifier(self)
+
+        return AccessSpecifier.from_id(self._access_specifier)
+
+    @property
     def type(self):
         """
         Retrieve the Type (if any) of the entity pointed at by the cursor.
@@ -1331,7 +1345,7 @@
     @property
     def referenced(self):
         """
-        For a cursor that is a reference, returns a cursor 
+        For a cursor that is a reference, returns a cursor
         representing the entity that it references.
         """
         if not hasattr(self, '_referenced'):
@@ -1343,7 +1357,7 @@
     def brief_comment(self):
         """Returns the brief comment text associated with that Cursor"""
         return conf.lib.clang_Cursor_getBriefCommentText(self)
-    
+
     @property
     def raw_comment(self):
         """Returns the raw comment text associated with that Cursor"""
@@ -1373,6 +1387,16 @@
             children)
         return iter(children)
 
+    def walk_preorder(self):
+        """Depth-first preorder walk over the cursor and its descendants.
+
+        Yields cursors.
+        """
+        yield self
+        for child in self.get_children():
+            for descendant in child.walk_preorder():
+                yield descendant
+
     def get_tokens(self):
         """Obtain Token instances formulating that compose this Cursor.
 
@@ -1426,6 +1450,54 @@
         res._tu = args[0]._tu
         return res
 
+### C++ access specifiers ###
+
+class AccessSpecifier(object):
+    """
+    Describes the access of a C++ class member
+    """
+
+    # The unique kind objects, index by id.
+    _kinds = []
+    _name_map = None
+
+    def __init__(self, value):
+        if value >= len(AccessSpecifier._kinds):
+            AccessSpecifier._kinds += [None] * (value - len(AccessSpecifier._kinds) + 1)
+        if AccessSpecifier._kinds[value] is not None:
+            raise ValueError,'AccessSpecifier already loaded'
+        self.value = value
+        AccessSpecifier._kinds[value] = self
+        AccessSpecifier._name_map = None
+
+    def from_param(self):
+        return self.value
+
+    @property
+    def name(self):
+        """Get the enumeration name of this access specifier."""
+        if self._name_map is None:
+            self._name_map = {}
+            for key,value in AccessSpecifier.__dict__.items():
+                if isinstance(value,AccessSpecifier):
+                    self._name_map[value] = key
+        return self._name_map[self]
+
+    @staticmethod
+    def from_id(id):
+        if id >= len(AccessSpecifier._kinds) or not AccessSpecifier._kinds[id]:
+            raise ValueError,'Unknown access specifier %d' % id
+        return AccessSpecifier._kinds[id]
+
+    def __repr__(self):
+        return 'AccessSpecifier.%s' % (self.name,)
+
+AccessSpecifier.INVALID = AccessSpecifier(0)
+AccessSpecifier.PUBLIC = AccessSpecifier(1)
+AccessSpecifier.PROTECTED = AccessSpecifier(2)
+AccessSpecifier.PRIVATE = AccessSpecifier(3)
+AccessSpecifier.NONE = AccessSpecifier(4)
+
 ### Type Kinds ###
 
 class TypeKind(object):
@@ -1820,7 +1892,7 @@
             # 5 : CompletionChunk.Kind("CurrentParameter"),
             6: '(',   # CompletionChunk.Kind("LeftParen"),
             7: ')',   # CompletionChunk.Kind("RightParen"),
-            8: ']',   # CompletionChunk.Kind("LeftBracket"),
+            8: '[',   # CompletionChunk.Kind("LeftBracket"),
             9: ']',   # CompletionChunk.Kind("RightBracket"),
             10: '{',  # CompletionChunk.Kind("LeftBrace"),
             11: '}',  # CompletionChunk.Kind("RightBrace"),
@@ -1934,7 +2006,7 @@
             return "<Availability: %s>" % self
 
     def __len__(self):
-        self.num_chunks
+        return self.num_chunks
 
     @CachedProperty
     def num_chunks(self):
@@ -2501,7 +2573,7 @@
     constants in this class.
     """
 
-    # An unknown error occured
+    # An unknown error occurred
     ERROR_UNKNOWN = 0
 
     # The database could not be loaded
@@ -2607,6 +2679,14 @@
         return conf.lib.clang_CompilationDatabase_getCompileCommands(self,
                                                                      filename)
 
+    def getAllCompileCommands(self):
+        """
+        Get an iterable object providing all the CompileCommands available from
+        the database.
+        """
+        return conf.lib.clang_CompilationDatabase_getAllCompileCommands(self)
+
+
 class Token(Structure):
     """Represents a single token from the preprocessor.
 
@@ -2673,6 +2753,11 @@
    c_object_p,
    CompilationDatabase.from_result),
 
+  ("clang_CompilationDatabase_getAllCompileCommands",
+   [c_object_p],
+   c_object_p,
+   CompileCommands.from_result),
+
   ("clang_CompilationDatabase_getCompileCommands",
    [c_object_p, c_char_p],
    c_object_p,
@@ -2909,8 +2994,8 @@
    [Diagnostic],
    c_uint),
 
-  ("clang_getDiagnosticCategoryName",
-   [c_uint],
+  ("clang_getDiagnosticCategoryText",
+   [Diagnostic],
    _CXString,
    _CXString.from_result),
 
@@ -3329,8 +3414,8 @@
         python bindings can disable the compatibility check. This will cause
         the python bindings to load, even though they are written for a newer
         version of libclang. Failures now arise if unsupported or incompatible
-        features are accessed. The user is required to test himself if the
-        features he is using are available and compatible between different
+        features are accessed. The user is required to test themselves if the
+        features they are using are available and compatible between different
         libclang versions.
         """
         if Config.loaded:
diff --git a/bindings/python/examples/cindex/cindex-dump.py b/bindings/python/examples/cindex/cindex-dump.py
index af7ddab..5556ad1 100644
--- a/bindings/python/examples/cindex/cindex-dump.py
+++ b/bindings/python/examples/cindex/cindex-dump.py
@@ -63,8 +63,8 @@
 
     parser = OptionParser("usage: %prog [options] {filename} [clang-args*]")
     parser.add_option("", "--show-ids", dest="showIDs",
-                      help="Don't compute cursor IDs (very slow)",
-                      default=False)
+                      help="Compute cursor IDs (very slow)",
+                      action="store_true", default=False)
     parser.add_option("", "--max-depth", dest="maxDepth",
                       help="Limit cursor expansion to depth N",
                       metavar="N", type=int, default=None)
diff --git a/bindings/python/tests/cindex/test_access_specifiers.py b/bindings/python/tests/cindex/test_access_specifiers.py
new file mode 100644
index 0000000..cfa04dc
--- /dev/null
+++ b/bindings/python/tests/cindex/test_access_specifiers.py
@@ -0,0 +1,34 @@
+
+from clang.cindex import AccessSpecifier
+from clang.cindex import Cursor
+from clang.cindex import TranslationUnit
+
+from .util import get_cursor
+from .util import get_tu
+
+def test_access_specifiers():
+    """Ensure that C++ access specifiers are available on cursors"""
+
+    tu = get_tu("""
+class test_class {
+public:
+  void public_member_function();
+protected:
+  void protected_member_function();
+private:
+  void private_member_function();
+};
+""", lang = 'cpp')
+
+    test_class = get_cursor(tu, "test_class")
+    assert test_class.access_specifier == AccessSpecifier.INVALID;
+
+    public = get_cursor(tu.cursor, "public_member_function")
+    assert public.access_specifier == AccessSpecifier.PUBLIC
+
+    protected = get_cursor(tu.cursor, "protected_member_function")
+    assert protected.access_specifier == AccessSpecifier.PROTECTED
+
+    private = get_cursor(tu.cursor, "private_member_function")
+    assert private.access_specifier == AccessSpecifier.PRIVATE
+
diff --git a/bindings/python/tests/cindex/test_cdb.py b/bindings/python/tests/cindex/test_cdb.py
index d0f580e..e1f824f 100644
--- a/bindings/python/tests/cindex/test_cdb.py
+++ b/bindings/python/tests/cindex/test_cdb.py
@@ -32,6 +32,27 @@
     cmds = cdb.getCompileCommands('/home/john.doe/MyProject/project.cpp')
     assert len(cmds) != 0
 
+def test_all_compilecommand():
+    """Check we get all results from the db"""
+    cdb = CompilationDatabase.fromDirectory(kInputsDir)
+    cmds = cdb.getAllCompileCommands()
+    assert len(cmds) == 3
+    expected = [
+        { 'wd': '/home/john.doe/MyProjectA',
+          'line': ['clang++', '-o', 'project2.o', '-c',
+                   '/home/john.doe/MyProject/project2.cpp']},
+        { 'wd': '/home/john.doe/MyProjectB',
+          'line': ['clang++', '-DFEATURE=1', '-o', 'project2-feature.o', '-c',
+                   '/home/john.doe/MyProject/project2.cpp']},
+        { 'wd': '/home/john.doe/MyProject',
+          'line': ['clang++', '-o', 'project.o', '-c',
+                   '/home/john.doe/MyProject/project.cpp']}
+        ]
+    for i in range(len(cmds)):
+        assert cmds[i].directory == expected[i]['wd']
+        for arg, exp in zip(cmds[i].arguments, expected[i]['line']):
+            assert arg == exp
+
 def test_1_compilecommand():
     """Check file with single compile command"""
     cdb = CompilationDatabase.fromDirectory(kInputsDir)
diff --git a/bindings/python/tests/cindex/test_cursor.py b/bindings/python/tests/cindex/test_cursor.py
index a27525c..4315045 100644
--- a/bindings/python/tests/cindex/test_cursor.py
+++ b/bindings/python/tests/cindex/test_cursor.py
@@ -8,9 +8,6 @@
 from .util import get_tu
 
 kInput = """\
-// FIXME: Find nicer way to drop builtins and other cruft.
-int start_decl;
-
 struct s0 {
   int a;
   int b;
@@ -33,11 +30,7 @@
 def test_get_children():
     tu = get_tu(kInput)
 
-    # Skip until past start_decl.
     it = tu.cursor.get_children()
-    while it.next().spelling != 'start_decl':
-        pass
-
     tu_nodes = list(it)
 
     assert len(tu_nodes) == 3
@@ -49,7 +42,7 @@
     assert tu_nodes[0].spelling == 's0'
     assert tu_nodes[0].is_definition() == True
     assert tu_nodes[0].location.file.name == 't.c'
-    assert tu_nodes[0].location.line == 4
+    assert tu_nodes[0].location.line == 1
     assert tu_nodes[0].location.column == 8
     assert tu_nodes[0].hash > 0
     assert tu_nodes[0].translation_unit is not None
diff --git a/bindings/python/tests/cindex/test_translation_unit.py b/bindings/python/tests/cindex/test_translation_unit.py
index f77998e..be6cd67 100644
--- a/bindings/python/tests/cindex/test_translation_unit.py
+++ b/bindings/python/tests/cindex/test_translation_unit.py
@@ -1,5 +1,6 @@
 import gc
 import os
+import tempfile
 
 from clang.cindex import CursorKind
 from clang.cindex import Cursor
@@ -93,15 +94,7 @@
 
     Returns the filename it was saved to.
     """
-
-    # FIXME Generate a temp file path using system APIs.
-    base = 'TEMP_FOR_TRANSLATIONUNIT_SAVE.c'
-    path = os.path.join(kInputsDir, base)
-
-    # Just in case.
-    if os.path.exists(path):
-        os.unlink(path)
-
+    _, path = tempfile.mkstemp()
     tu.save(path)
 
     return path
diff --git a/bindings/python/tests/cindex/util.py b/bindings/python/tests/cindex/util.py
index 8614b02..c53ba7c 100644
--- a/bindings/python/tests/cindex/util.py
+++ b/bindings/python/tests/cindex/util.py
@@ -39,52 +39,34 @@
 
     If the cursor is not found, None is returned.
     """
-    children = []
-    if isinstance(source, Cursor):
-        children = source.get_children()
-    else:
-        # Assume TU
-        children = source.cursor.get_children()
+    # Convenience for calling on a TU.
+    root_cursor = source if isinstance(source, Cursor) else source.cursor
 
-    for cursor in children:
+    for cursor in root_cursor.walk_preorder():
         if cursor.spelling == spelling:
             return cursor
 
-        # Recurse into children.
-        result = get_cursor(cursor, spelling)
-        if result is not None:
-            return result
-
     return None
- 
+
 def get_cursors(source, spelling):
     """Obtain all cursors from a source object with a specific spelling.
 
-    This provides a convenient search mechanism to find all cursors with specific
-    spelling within a source. The first argument can be either a
+    This provides a convenient search mechanism to find all cursors with
+    specific spelling within a source. The first argument can be either a
     TranslationUnit or Cursor instance.
 
     If no cursors are found, an empty list is returned.
     """
-    cursors = []
-    children = []
-    if isinstance(source, Cursor):
-        children = source.get_children()
-    else:
-        # Assume TU
-        children = source.cursor.get_children()
+    # Convenience for calling on a TU.
+    root_cursor = source if isinstance(source, Cursor) else source.cursor
 
-    for cursor in children:
+    cursors = []
+    for cursor in root_cursor.walk_preorder():
         if cursor.spelling == spelling:
             cursors.append(cursor)
 
-        # Recurse into children.
-        cursors.extend(get_cursors(cursor, spelling))
-
     return cursors
 
-    
-    
 
 __all__ = [
     'get_cursor',
diff --git a/bindings/xml/comment-xml-schema.rng b/bindings/xml/comment-xml-schema.rng
index a8913a3..43f3e54 100644
--- a/bindings/xml/comment-xml-schema.rng
+++ b/bindings/xml/comment-xml-schema.rng
@@ -580,6 +580,14 @@
         </data>
       </element>
       <element name="rawHTML">
+        <optional>
+          <!-- If not specified, the default value is 'false'. -->
+          <!-- The value 'false' or absence of the attribute does not imply
+               that the HTML is actually well-formed. -->
+          <attribute name="isMalformed">
+            <data type="boolean" />
+          </attribute>
+        </optional>
         <!-- Non-empty text content. -->
         <data type="string">
           <param name="pattern">.*\S.*</param>
diff --git a/docs/AddressSanitizer.rst b/docs/AddressSanitizer.rst
index 4d5944d..93a6a0e 100644
--- a/docs/AddressSanitizer.rst
+++ b/docs/AddressSanitizer.rst
@@ -16,6 +16,7 @@
 * Use-after-free
 * Use-after-return (to some extent)
 * Double-free, invalid free
+* Memory leaks (experimental)
 
 Typical slowdown introduced by AddressSanitizer is **2x**.
 
@@ -60,14 +61,14 @@
     % 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. Currently, AddressSanitizer does not symbolize
-its output, so you may need to use a separate script to symbolize the result
-offline (this will be fixed in future).
+exit with a non-zero exit code. To make AddressSanitizer symbolize its output
+you need to set the ``ASAN_SYMBOLIZER_PATH`` environment variable to point to
+the ``llvm-symbolizer`` binary (or make sure ``llvm-symbolizer`` is in your
+``$PATH``):
 
 .. code-block:: console
 
-    % ./a.out 2> log
-    % projects/compiler-rt/lib/asan/scripts/asan_symbolize.py / < log | c++filt
+    % ASAN_SYMBOLIZER_PATH=/usr/local/bin/llvm-symbolizer ./a.out
     ==9442== ERROR: AddressSanitizer heap-use-after-free on address 0x7f7ddab8c084 at pc 0x403c8c bp 0x7fff87fb82d0 sp 0x7fff87fb82c8
     READ of size 4 at 0x7f7ddab8c084 thread T0
         #0 0x403c8c in main example_UseAfterFree.cc:4
@@ -83,6 +84,23 @@
         #2 0x7f7ddabcac4d in __libc_start_main ??:0
     ==9442== ABORTING
 
+If that does not work for you (e.g. your process is sandboxed), you can use a
+separate script to symbolize the result offline (online symbolization can be
+force disabled by setting ``ASAN_OPTIONS=symbolize=0``):
+
+.. code-block:: console
+
+    % ASAN_OPTIONS=symbolize=0 ./a.out 2> log
+    % projects/compiler-rt/lib/asan/scripts/asan_symbolize.py / < log | c++filt
+    ==9442== ERROR: AddressSanitizer heap-use-after-free on address 0x7f7ddab8c084 at pc 0x403c8c bp 0x7fff87fb82d0 sp 0x7fff87fb82c8
+    READ of size 4 at 0x7f7ddab8c084 thread T0
+        #0 0x403c8c in main example_UseAfterFree.cc:4
+        #1 0x7f7ddabcac4d in __libc_start_main ??:0
+    ...
+
+Note that on OS X you may need to run ``dsymutil`` on your binary to have the
+file\:line info in the AddressSanitizer reports.
+
 AddressSanitizer exits on the first detected error. This is by design.
 One reason: it makes the generated code smaller and faster (both by
 ~5%). Another reason: this makes fixing bugs unavoidable. With Valgrind,
@@ -155,16 +173,22 @@
     type:*BadInitClassSubstring*=init
     src:bad/init/files/*=init
 
+Memory leak detection
+---------------------
+
+For the experimental memory leak detector in AddressSanitizer, see
+:doc:`LeakSanitizer`.
+
 Supported Platforms
 ===================
 
 AddressSanitizer is supported on
 
-* Linux i386/x86\_64 (tested on Ubuntu 10.04 and 12.04);
-* MacOS 10.6, 10.7 and 10.8 (i386/x86\_64).
+* Linux i386/x86\_64 (tested on Ubuntu 12.04);
+* MacOS 10.6 - 10.9 (i386/x86\_64).
+* Android ARM
 
-Support for Linux ARM (and Android ARM) is in progress (it may work, but
-is not guaranteed too).
+Ports to various other platforms are in progress.
 
 Limitations
 ===========
diff --git a/docs/AttributeReference.rst b/docs/AttributeReference.rst
new file mode 100644
index 0000000..115a217
--- /dev/null
+++ b/docs/AttributeReference.rst
@@ -0,0 +1,1116 @@
+..
+  -------------------------------------------------------------------
+  NOTE: This file is automatically generated by running clang-tblgen
+  -gen-attr-docs. Do not edit this file by hand!!
+  -------------------------------------------------------------------
+
+===================
+Attributes in Clang
+===================
+.. contents::
+   :local:
+
+Introduction
+============
+
+This page lists the attributes currently supported by Clang.
+
+Function Attributes
+===================
+
+
+interrupt
+---------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "X","","",""
+
+Clang supports the GNU style ``__attribute__((interrupt("TYPE")))`` attribute on
+ARM 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.
+
+The parameter passed to the interrupt attribute is optional, but if
+provided it must be a string literal with one of the following values: "IRQ",
+"FIQ", "SWI", "ABORT", "UNDEF".
+
+The semantics are as follows:
+
+- If the function is AAPCS, Clang instructs the backend to realign the stack to
+  8 bytes on entry. This is a general requirement of the AAPCS at public
+  interfaces, but may not hold when an exception is taken. Doing this allows
+  other AAPCS functions to be called.
+- If the CPU is M-class this is all that needs to be done since the architecture
+  itself is designed in such a way that functions obeying the normal AAPCS ABI
+  constraints are valid exception handlers.
+- If the CPU is not M-class, the prologue and epilogue are modified to save all
+  non-banked registers that are used, so that upon return the user-mode state
+  will not be corrupted. Note that to avoid unnecessary overhead, only
+  general-purpose (integer) registers are saved in this way. If VFP operations
+  are needed, that state must be saved manually.
+
+  Specifically, interrupt kinds other than "FIQ" will save all core registers
+  except "lr" and "sp". "FIQ" interrupts will save r0-r7.
+- If the CPU is not M-class, the return instruction is changed to one of the
+  canonical sequences permitted by the architecture for exception return. Where
+  possible the function itself will make the necessary "lr" adjustments so that
+  the "preferred return address" is selected.
+
+  Unfortunately the compiler is unable to make this guarantee for an "UNDEF"
+  handler, where the offset from "lr" to the preferred return address depends on
+  the execution state of the code which generated the exception. In this case
+  a sequence equivalent to "movs pc, lr" will be used.
+
+
+acquire_capability (acquire_shared_capability, clang::acquire_capability, clang::acquire_shared_capability)
+-----------------------------------------------------------------------------------------------------------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "X","X","",""
+
+Marks a function as acquiring a capability.
+
+
+assert_capability (assert_shared_capability, clang::assert_capability, clang::assert_shared_capability)
+-------------------------------------------------------------------------------------------------------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "X","X","",""
+
+Marks a function that dynamically tests whether a capability is held, and halts
+the program if it is not held.
+
+
+availability
+------------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "X","","",""
+
+The ``availability`` attribute can be placed on declarations to describe the
+lifecycle of that declaration relative to operating system versions.  Consider
+the function declaration for a hypothetical function ``f``:
+
+.. code-block:: c++
+
+  void f(void) __attribute__((availability(macosx,introduced=10.4,deprecated=10.6,obsoleted=10.7)));
+
+The availability attribute states that ``f`` was introduced in Mac OS X 10.4,
+deprecated in Mac OS X 10.6, and obsoleted in Mac OS X 10.7.  This information
+is used by Clang to determine when it is safe to use ``f``: for example, if
+Clang is instructed to compile code for Mac OS X 10.5, a call to ``f()``
+succeeds.  If Clang is instructed to compile code for Mac OS X 10.6, the call
+succeeds but Clang emits a warning specifying that the function is deprecated.
+Finally, if Clang is instructed to compile code for Mac OS X 10.7, the call
+fails because ``f()`` is no longer available.
+
+The availability attribute is a comma-separated list starting with the
+platform name and then including clauses specifying important milestones in the
+declaration's lifetime (in any order) along with additional information.  Those
+clauses can be:
+
+introduced=\ *version*
+  The first version in which this declaration was introduced.
+
+deprecated=\ *version*
+  The first version in which this declaration was deprecated, meaning that
+  users should migrate away from this API.
+
+obsoleted=\ *version*
+  The first version in which this declaration was obsoleted, meaning that it
+  was removed completely and can no longer be used.
+
+unavailable
+  This declaration is never available on this platform.
+
+message=\ *string-literal*
+  Additional message text that Clang will provide when emitting a warning or
+  error about use of a deprecated or obsoleted declaration.  Useful to direct
+  users to replacement APIs.
+
+Multiple availability attributes can be placed on a declaration, which may
+correspond to different platforms.  Only the availability attribute with the
+platform corresponding to the target platform will be used; any others will be
+ignored.  If no availability attribute specifies availability for the current
+target platform, the availability attributes are ignored.  Supported platforms
+are:
+
+``ios``
+  Apple's iOS operating system.  The minimum deployment target is specified by
+  the ``-mios-version-min=*version*`` or ``-miphoneos-version-min=*version*``
+  command-line arguments.
+
+``macosx``
+  Apple's Mac OS X operating system.  The minimum deployment target is
+  specified by the ``-mmacosx-version-min=*version*`` command-line argument.
+
+A declaration can be used even when deploying back to a platform version prior
+to when the declaration was introduced.  When this happens, the declaration is
+`weakly linked
+<https://developer.apple.com/library/mac/#documentation/MacOSX/Conceptual/BPFrameworks/Concepts/WeakLinking.html>`_,
+as if the ``weak_import`` attribute were added to the declaration.  A
+weakly-linked declaration may or may not be present a run-time, and a program
+can determine whether the declaration is present by checking whether the
+address of that declaration is non-NULL.
+
+If there are multiple declarations of the same entity, the availability
+attributes must either match on a per-platform basis or later
+declarations must not have availability attributes for that
+platform. For example:
+
+.. code-block:: c
+
+  void g(void) __attribute__((availability(macosx,introduced=10.4)));
+  void g(void) __attribute__((availability(macosx,introduced=10.4))); // okay, matches
+  void g(void) __attribute__((availability(ios,introduced=4.0))); // okay, adds a new platform
+  void g(void); // okay, inherits both macosx and ios availability from above.
+  void g(void) __attribute__((availability(macosx,introduced=10.5))); // error: mismatch
+
+When one method overrides another, the overriding method can be more widely available than the overridden method, e.g.,:
+
+.. code-block:: objc
+
+  @interface A
+  - (id)method __attribute__((availability(macosx,introduced=10.4)));
+  - (id)method2 __attribute__((availability(macosx,introduced=10.4)));
+  @end
+
+  @interface B : A
+  - (id)method __attribute__((availability(macosx,introduced=10.3))); // okay: method moved into base class later
+  - (id)method __attribute__((availability(macosx,introduced=10.5))); // error: this method was available via the base class in 10.4
+  @end
+
+
+_Noreturn
+---------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "","","","X"
+
+A function declared as ``_Noreturn`` shall not return to its caller. The
+compiler will generate a diagnostic for a function declared as ``_Noreturn``
+that appears to be capable of returning to its caller.
+
+
+noreturn
+--------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "","X","",""
+
+A function declared as ``[[noreturn]]`` shall not return to its caller. The
+compiler will generate a diagnostic for a function declared as ``[[noreturn]]``
+that appears to be capable of returning to its caller.
+
+
+carries_dependency
+------------------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "X","X","",""
+
+The ``carries_dependency`` attribute specifies dependency propagation into and
+out of functions.
+
+When specified on a function or Objective-C method, the ``carries_dependency``
+attribute means that the return value carries a dependency out of the function, 
+so that the implementation need not constrain ordering upon return from that
+function. Implementations of the function and its caller may choose to preserve
+dependencies instead of emitting memory ordering instructions such as fences.
+
+Note, this attribute does not change the meaning of the program, but may result
+in generation of more efficient code.
+
+
+enable_if
+---------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "X","","",""
+
+.. Note:: Some features of this attribute are experimental. The meaning of
+  multiple enable_if attributes on a single declaration is subject to change in
+  a future version of clang. Also, the ABI is not standardized and the name
+  mangling may change in future versions. To avoid that, use asm labels.
+
+The ``enable_if`` attribute can be placed on function declarations to control
+which overload is selected based on the values of the function's arguments.
+When combined with the ``overloadable`` attribute, this feature is also
+available in C.
+
+.. code-block:: c++
+
+  int isdigit(int c);
+  int isdigit(int c) __attribute__((enable_if(c <= -1 || c > 255, "chosen when 'c' is out of range"))) __attribute__((unavailable("'c' must have the value of an unsigned char or EOF")));
+  
+  void foo(char c) {
+    isdigit(c);
+    isdigit(10);
+    isdigit(-10);  // results in a compile-time error.
+  }
+
+The enable_if attribute takes two arguments, the first is an expression written
+in terms of the function parameters, the second is a string explaining why this
+overload candidate could not be selected to be displayed in diagnostics. The
+expression is part of the function signature for the purposes of determining
+whether it is a redeclaration (following the rules used when determining
+whether a C++ template specialization is ODR-equivalent), but is not part of
+the type.
+
+The enable_if expression is evaluated as if it were the body of a
+bool-returning constexpr function declared with the arguments of the function
+it is being applied to, then called with the parameters at the callsite. If the
+result is false or could not be determined through constant expression
+evaluation, then this overload will not be chosen and the provided string may
+be used in a diagnostic if the compile fails as a result.
+
+Because the enable_if expression is an unevaluated context, there are no global
+state changes, nor the ability to pass information from the enable_if
+expression to the function body. For example, suppose we want calls to
+strnlen(strbuf, maxlen) to resolve to strnlen_chk(strbuf, maxlen, size of
+strbuf) only if the size of strbuf can be determined:
+
+.. code-block:: c++
+
+  __attribute__((always_inline))
+  static inline size_t strnlen(const char *s, size_t maxlen)
+    __attribute__((overloadable))
+    __attribute__((enable_if(__builtin_object_size(s, 0) != -1))),
+                             "chosen when the buffer size is known but 'maxlen' is not")))
+  {
+    return strnlen_chk(s, maxlen, __builtin_object_size(s, 0));
+  }
+
+Multiple enable_if attributes may be applied to a single declaration. In this
+case, the enable_if expressions are evaluated from left to right in the
+following manner. First, the candidates whose enable_if expressions evaluate to
+false or cannot be evaluated are discarded. If the remaining candidates do not
+share ODR-equivalent enable_if expressions, the overload resolution is
+ambiguous. Otherwise, enable_if overload resolution continues with the next
+enable_if attribute on the candidates that have not been discarded and have
+remaining enable_if attributes. In this way, we pick the most specific
+overload out of a number of viable overloads using enable_if.
+
+.. code-block:: c++
+
+  void f() __attribute__((enable_if(true, "")));  // #1
+  void f() __attribute__((enable_if(true, ""))) __attribute__((enable_if(true, "")));  // #2
+  
+  void g(int i, int j) __attribute__((enable_if(i, "")));  // #1
+  void g(int i, int j) __attribute__((enable_if(j, ""))) __attribute__((enable_if(true)));  // #2
+
+In this example, a call to f() is always resolved to #2, as the first enable_if
+expression is ODR-equivalent for both declarations, but #1 does not have another
+enable_if expression to continue evaluating, so the next round of evaluation has
+only a single candidate. In a call to g(1, 1), the call is ambiguous even though
+#2 has more enable_if attributes, because the first enable_if expressions are
+not ODR-equivalent.
+
+Query for this feature with ``__has_attribute(enable_if)``.
+
+
+flatten (gnu::flatten)
+----------------------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "X","X","",""
+
+The ``flatten`` attribute causes calls within the attributed function to
+be inlined unless it is impossible to do so, for example if the body of the
+callee is unavailable or if the callee has the ``noinline`` attribute.
+
+
+format (gnu::format)
+--------------------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "X","X","",""
+
+Clang supports the ``format`` attribute, which indicates that the function
+accepts a ``printf`` or ``scanf``-like format string and corresponding
+arguments or a ``va_list`` that contains these arguments.
+
+Please see `GCC documentation about format attribute
+<http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html>`_ to find details
+about attribute syntax.
+
+Clang implements two kinds of checks with this attribute.
+
+#. Clang checks that the function with the ``format`` attribute is called with
+   a format string that uses format specifiers that are allowed, and that
+   arguments match the format string.  This is the ``-Wformat`` warning, it is
+   on by default.
+
+#. Clang checks that the format string argument is a literal string.  This is
+   the ``-Wformat-nonliteral`` warning, it is off by default.
+
+   Clang implements this mostly the same way as GCC, but there is a difference
+   for functions that accept a ``va_list`` argument (for example, ``vprintf``).
+   GCC does not emit ``-Wformat-nonliteral`` warning for calls to such
+   fuctions.  Clang does not warn if the format string comes from a function
+   parameter, where the function is annotated with a compatible attribute,
+   otherwise it warns.  For example:
+
+   .. code-block:: c
+
+     __attribute__((__format__ (__scanf__, 1, 3)))
+     void foo(const char* s, char *buf, ...) {
+       va_list ap;
+       va_start(ap, buf);
+
+       vprintf(s, ap); // warning: format string is not a string literal
+     }
+
+   In this case we warn because ``s`` contains a format string for a
+   ``scanf``-like function, but it is passed to a ``printf``-like function.
+
+   If the attribute is removed, clang still warns, because the format string is
+   not a string literal.
+
+   Another example:
+
+   .. code-block:: c
+
+     __attribute__((__format__ (__printf__, 1, 3)))
+     void foo(const char* s, char *buf, ...) {
+       va_list ap;
+       va_start(ap, buf);
+
+       vprintf(s, ap); // warning
+     }
+
+   In this case Clang does not warn because the format string ``s`` and
+   the corresponding arguments are annotated.  If the arguments are
+   incorrect, the caller of ``foo`` will receive a warning.
+
+
+noduplicate (clang::noduplicate)
+--------------------------------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "X","X","",""
+
+The ``noduplicate`` attribute can be placed on function declarations to control
+whether function calls to this function can be duplicated or not as a result of
+optimizations. This is required for the implementation of functions with
+certain special requirements, like the OpenCL "barrier" function, that might
+need to be run concurrently by all the threads that are executing in lockstep
+on the hardware. For example this attribute applied on the function
+"nodupfunc" in the code below avoids that:
+
+.. code-block:: c
+
+  void nodupfunc() __attribute__((noduplicate));
+  // Setting it as a C++11 attribute is also valid
+  // void nodupfunc() [[clang::noduplicate]];
+  void foo();
+  void bar();
+
+  nodupfunc();
+  if (a > n) {
+    foo();
+  } else {
+    bar();
+  }
+
+gets possibly modified by some optimizations into code similar to this:
+
+.. code-block:: c
+
+  if (a > n) {
+    nodupfunc();
+    foo();
+  } else {
+    nodupfunc();
+    bar();
+  }
+
+where the call to "nodupfunc" is duplicated and sunk into the two branches
+of the condition.
+
+
+no_sanitize_address (no_address_safety_analysis, gnu::no_address_safety_analysis, gnu::no_sanitize_address)
+-----------------------------------------------------------------------------------------------------------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "X","X","",""
+
+.. _langext-address_sanitizer:
+
+Use ``__attribute__((no_sanitize_address))`` on a function declaration to
+specify that address safety instrumentation (e.g. AddressSanitizer) should
+not be applied to that function.
+
+
+no_sanitize_memory
+------------------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "X","","",""
+
+.. _langext-memory_sanitizer:
+
+Use ``__attribute__((no_sanitize_memory))`` on a function declaration to
+specify that checks for uninitialized memory should not be inserted 
+(e.g. by MemorySanitizer). The function may still be instrumented by the tool
+to avoid false positives in other places.
+
+
+no_sanitize_thread
+------------------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "X","","",""
+
+.. _langext-thread_sanitizer:
+
+Use ``__attribute__((no_sanitize_thread))`` on a function declaration to
+specify that checks for data races on plain (non-atomic) memory accesses should
+not be inserted by ThreadSanitizer. The function is still instrumented by the
+tool to avoid false positives and provide meaningful stack traces.
+
+
+no_split_stack (gnu::no_split_stack)
+------------------------------------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "X","X","",""
+
+The ``no_split_stack`` attribute disables the emission of the split stack
+preamble for a particular function. It has no effect if ``-fsplit-stack``
+is not specified.
+
+
+objc_method_family
+------------------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "X","","",""
+
+Many methods in Objective-C have conventional meanings determined by their
+selectors. It is sometimes useful to be able to mark a method as having a
+particular conventional meaning despite not having the right selector, or as
+not having the conventional meaning that its selector would suggest. For these
+use cases, we provide an attribute to specifically describe the "method family"
+that a method belongs to.
+
+**Usage**: ``__attribute__((objc_method_family(X)))``, where ``X`` is one of
+``none``, ``alloc``, ``copy``, ``init``, ``mutableCopy``, or ``new``.  This
+attribute can only be placed at the end of a method declaration:
+
+.. code-block:: objc
+
+  - (NSString *)initMyStringValue __attribute__((objc_method_family(none)));
+
+Users who do not wish to change the conventional meaning of a method, and who
+merely want to document its non-standard retain and release semantics, should
+use the retaining behavior attributes (``ns_returns_retained``,
+``ns_returns_not_retained``, etc).
+
+Query for this feature with ``__has_attribute(objc_method_family)``.
+
+
+objc_requires_super
+-------------------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "X","","",""
+
+Some Objective-C classes allow a subclass to override a particular method in a
+parent class but expect that the overriding method also calls the overridden
+method in the parent class. For these cases, we provide an attribute to
+designate that a method requires a "call to ``super``" in the overriding
+method in the subclass.
+
+**Usage**: ``__attribute__((objc_requires_super))``.  This attribute can only
+be placed at the end of a method declaration:
+
+.. code-block:: objc
+
+  - (void)foo __attribute__((objc_requires_super));
+
+This attribute can only be applied the method declarations within a class, and
+not a protocol.  Currently this attribute does not enforce any placement of
+where the call occurs in the overriding method (such as in the case of
+``-dealloc`` where the call must appear at the end).  It checks only that it
+exists.
+
+Note that on both OS X and iOS that the Foundation framework provides a
+convenience macro ``NS_REQUIRES_SUPER`` that provides syntactic sugar for this
+attribute:
+
+.. code-block:: objc
+
+  - (void)foo NS_REQUIRES_SUPER;
+
+This macro is conditionally defined depending on the compiler's support for
+this attribute.  If the compiler does not support the attribute the macro
+expands to nothing.
+
+Operationally, when a method has this annotation the compiler will warn if the
+implementation of an override in a subclass does not call super.  For example:
+
+.. code-block:: objc
+
+   warning: method possibly missing a [super AnnotMeth] call
+   - (void) AnnotMeth{};
+                      ^
+
+
+optnone (clang::optnone)
+------------------------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "X","X","",""
+
+The ``optnone`` attribute suppresses essentially all optimizations
+on a function or method, regardless of the optimization level applied to
+the compilation unit as a whole.  This is particularly useful when you
+need to debug a particular function, but it is infeasible to build the
+entire application without optimization.  Avoiding optimization on the
+specified function can improve the quality of the debugging information
+for that function.
+
+This attribute is incompatible with the ``always_inline`` attribute.
+
+
+overloadable
+------------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "X","","",""
+
+Clang provides support for C++ function overloading in C.  Function overloading
+in C is introduced using the ``overloadable`` attribute.  For example, one
+might provide several overloaded versions of a ``tgsin`` function that invokes
+the appropriate standard function computing the sine of a value with ``float``,
+``double``, or ``long double`` precision:
+
+.. code-block:: c
+
+  #include <math.h>
+  float __attribute__((overloadable)) tgsin(float x) { return sinf(x); }
+  double __attribute__((overloadable)) tgsin(double x) { return sin(x); }
+  long double __attribute__((overloadable)) tgsin(long double x) { return sinl(x); }
+
+Given these declarations, one can call ``tgsin`` with a ``float`` value to
+receive a ``float`` result, with a ``double`` to receive a ``double`` result,
+etc.  Function overloading in C follows the rules of C++ function overloading
+to pick the best overload given the call arguments, with a few C-specific
+semantics:
+
+* Conversion from ``float`` or ``double`` to ``long double`` is ranked as a
+  floating-point promotion (per C99) rather than as a floating-point conversion
+  (as in C++).
+
+* A conversion from a pointer of type ``T*`` to a pointer of type ``U*`` is
+  considered a pointer conversion (with conversion rank) if ``T`` and ``U`` are
+  compatible types.
+
+* A conversion from type ``T`` to a value of type ``U`` is permitted if ``T``
+  and ``U`` are compatible types.  This conversion is given "conversion" rank.
+
+The declaration of ``overloadable`` functions is restricted to function
+declarations and definitions.  Most importantly, if any function with a given
+name is given the ``overloadable`` attribute, then all function declarations
+and definitions with that name (and in that scope) must have the
+``overloadable`` attribute.  This rule even applies to redeclarations of
+functions whose original declaration had the ``overloadable`` attribute, e.g.,
+
+.. code-block:: c
+
+  int f(int) __attribute__((overloadable));
+  float f(float); // error: declaration of "f" must have the "overloadable" attribute
+
+  int g(int) __attribute__((overloadable));
+  int g(int) { } // error: redeclaration of "g" must also have the "overloadable" attribute
+
+Functions marked ``overloadable`` must have prototypes.  Therefore, the
+following code is ill-formed:
+
+.. code-block:: c
+
+  int h() __attribute__((overloadable)); // error: h does not have a prototype
+
+However, ``overloadable`` functions are allowed to use a ellipsis even if there
+are no named parameters (as is permitted in C++).  This feature is particularly
+useful when combined with the ``unavailable`` attribute:
+
+.. code-block:: c++
+
+  void honeypot(...) __attribute__((overloadable, unavailable)); // calling me is an error
+
+Functions declared with the ``overloadable`` attribute have their names mangled
+according to the same rules as C++ function names.  For example, the three
+``tgsin`` functions in our motivating example get the mangled names
+``_Z5tgsinf``, ``_Z5tgsind``, and ``_Z5tgsine``, respectively.  There are two
+caveats to this use of name mangling:
+
+* Future versions of Clang may change the name mangling of functions overloaded
+  in C, so you should not depend on an specific mangling.  To be completely
+  safe, we strongly urge the use of ``static inline`` with ``overloadable``
+  functions.
+
+* The ``overloadable`` attribute has almost no meaning when used in C++,
+  because names will already be mangled and functions are already overloadable.
+  However, when an ``overloadable`` function occurs within an ``extern "C"``
+  linkage specification, it's name *will* be mangled in the same way as it
+  would in C.
+
+Query for this feature with ``__has_extension(attribute_overloadable)``.
+
+
+pcs (gnu::pcs)
+--------------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "X","X","",""
+
+On ARM targets, this can attribute can be used to select calling conventions,
+similar to ``stdcall`` on x86. Valid parameter values are "aapcs" and
+"aapcs-vfp".
+
+
+release_capability (release_shared_capability, clang::release_capability, clang::release_shared_capability)
+-----------------------------------------------------------------------------------------------------------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "X","X","",""
+
+Marks a function as releasing a capability.
+
+
+try_acquire_capability (try_acquire_shared_capability, clang::try_acquire_capability, clang::try_acquire_shared_capability)
+---------------------------------------------------------------------------------------------------------------------------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "X","X","",""
+
+Marks a function that attempts to acquire a capability. This function may fail to
+actually acquire the capability; they accept a Boolean value determining
+whether acquiring the capability means success (true), or failing to acquire
+the capability means success (false).
+
+
+Variable Attributes
+===================
+
+
+section (gnu::section, __declspec(allocate))
+--------------------------------------------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "X","X","X",""
+
+The ``section`` attribute allows you to specify a specific section a
+global variable or function should be in after translation.
+
+
+tls_model (gnu::tls_model)
+--------------------------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "X","X","",""
+
+The ``tls_model`` attribute allows you to specify which thread-local storage
+model to use. It accepts the following strings:
+
+* global-dynamic
+* local-dynamic
+* initial-exec
+* local-exec
+
+TLS models are mutually exclusive.
+
+
+thread
+------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "","","X",""
+
+The ``__declspec(thread)`` attribute declares a variable with thread local
+storage.  It is available under the ``-fms-extensions`` flag for MSVC
+compatibility.  Documentation for the Visual C++ attribute is available on MSDN_.
+
+.. _MSDN: http://msdn.microsoft.com/en-us/library/9w1sdazb.aspx
+
+In Clang, ``__declspec(thread)`` is generally equivalent in functionality to the
+GNU ``__thread`` keyword.  The variable must not have a destructor and must have
+a constant initializer, if any.  The attribute only applies to variables
+declared with static storage duration, such as globals, class static data
+members, and static locals.
+
+
+Type Attributes
+===============
+
+
+__single_inhertiance, __multiple_inheritance, __virtual_inheritance
+-------------------------------------------------------------------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "","","","X"
+
+This collection of keywords is enabled under ``-fms-extensions`` and controls
+the pointer-to-member representation used on ``*-*-win32`` targets.
+
+The ``*-*-win32`` targets utilize a pointer-to-member representation which
+varies in size and alignment depending on the definition of the underlying
+class.
+
+However, this is problematic when a forward declaration is only available and
+no definition has been made yet.  In such cases, Clang is forced to utilize the
+most general representation that is available to it.
+
+These keywords make it possible to use a pointer-to-member representation other
+than the most general one regardless of whether or not the definition will ever
+be present in the current translation unit.
+
+This family of keywords belong between the ``class-key`` and ``class-name``:
+
+.. code-block:: c++
+
+  struct __single_inheritance S;
+  int S::*i;
+  struct S {};
+
+This keyword can be applied to class templates but only has an effect when used
+on full specializations:
+
+.. code-block:: c++
+
+  template <typename T, typename U> struct __single_inheritance A; // warning: inheritance model ignored on primary template
+  template <typename T> struct __multiple_inheritance A<T, T>; // warning: inheritance model ignored on partial specialization
+  template <> struct __single_inheritance A<int, float>;
+
+Note that choosing an inheritance model less general than strictly necessary is
+an error:
+
+.. code-block:: c++
+
+  struct __multiple_inheritance S; // error: inheritance model does not match definition
+  int S::*i;
+  struct S {};
+
+
+Statement Attributes
+====================
+
+
+fallthrough (clang::fallthrough)
+--------------------------------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "","X","",""
+
+The ``clang::fallthrough`` attribute is used along with the
+``-Wimplicit-fallthrough`` argument to annotate intentional fall-through
+between switch labels.  It can only be applied to a null statement placed at a
+point of execution between any statement and the next switch label.  It is
+common to mark these places with a specific comment, but this attribute is
+meant to replace comments with a more strict annotation, which can be checked
+by the compiler.  This attribute doesn't change semantics of the code and can
+be used wherever an intended fall-through occurs.  It is designed to mimic
+control-flow statements like ``break;``, so it can be placed in most places
+where ``break;`` can, but only if there are no statements on the execution path
+between it and the next switch label.
+
+Here is an example:
+
+.. code-block:: c++
+
+  // compile with -Wimplicit-fallthrough
+  switch (n) {
+  case 22:
+  case 33:  // no warning: no statements between case labels
+    f();
+  case 44:  // warning: unannotated fall-through
+    g();
+    [[clang::fallthrough]];
+  case 55:  // no warning
+    if (x) {
+      h();
+      break;
+    }
+    else {
+      i();
+      [[clang::fallthrough]];
+    }
+  case 66:  // no warning
+    p();
+    [[clang::fallthrough]]; // warning: fallthrough annotation does not
+                            //          directly precede case label
+    q();
+  case 77:  // warning: unannotated fall-through
+    r();
+  }
+
+
+Consumed Annotation Checking
+============================
+Clang supports additional attributes for checking basic resource management
+properties, specifically for unique objects that have a single owning reference.
+The following attributes are currently supported, although **the implementation
+for these annotations is currently in development and are subject to change.**
+
+callable_when
+-------------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "X","","",""
+
+Use ``__attribute__((callable_when(...)))`` to indicate what states a method
+may be called in.  Valid states are unconsumed, consumed, or unknown.  Each
+argument to this attribute must be a quoted string.  E.g.:
+
+``__attribute__((callable_when("unconsumed", "unknown")))``
+
+
+consumable
+----------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "X","","",""
+
+Each ``class`` that uses any of the typestate annotations must first be marked
+using the ``consumable`` attribute.  Failure to do so will result in a warning.
+
+This attribute accepts a single parameter that must be one of the following:
+``unknown``, ``consumed``, or ``unconsumed``.
+
+
+param_typestate
+---------------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "X","","",""
+
+This attribute specifies expectations about function parameters.  Calls to an
+function with annotated parameters will issue a warning if the corresponding
+argument isn't in the expected state.  The attribute is also used to set the
+initial state of the parameter when analyzing the function's body.
+
+
+return_typestate
+----------------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "X","","",""
+
+The ``return_typestate`` attribute can be applied to functions or parameters.
+When applied to a function the attribute specifies the state of the returned
+value.  The function's body is checked to ensure that it always returns a value
+in the specified state.  On the caller side, values returned by the annotated
+function are initialized to the given state.
+
+When applied to a function parameter it modifies the state of an argument after
+a call to the function returns.  The function's body is checked to ensure that
+the parameter is in the expected state before returning.
+
+
+set_typestate
+-------------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "X","","",""
+
+Annotate methods that transition an object into a new state with
+``__attribute__((set_typestate(new_state)))``.  The new new state must be
+unconsumed, consumed, or unknown.
+
+
+test_typestate
+--------------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "X","","",""
+
+Use ``__attribute__((test_typestate(tested_state)))`` to indicate that a method
+returns true if the object is in the specified state..
+
+
+Type Safety Checking
+====================
+Clang supports additional attributes to enable checking type safety properties
+that can't be enforced by the C type system.  Use cases include:
+
+* MPI library implementations, where these attributes enable checking that
+  the buffer type matches the passed ``MPI_Datatype``;
+* for HDF5 library there is a similar use case to MPI;
+* checking types of variadic functions' arguments for functions like
+  ``fcntl()`` and ``ioctl()``.
+
+You can detect support for these attributes with ``__has_attribute()``.  For
+example:
+
+.. code-block:: c++
+
+  #if defined(__has_attribute)
+  #  if __has_attribute(argument_with_type_tag) && \
+        __has_attribute(pointer_with_type_tag) && \
+        __has_attribute(type_tag_for_datatype)
+  #    define ATTR_MPI_PWT(buffer_idx, type_idx) __attribute__((pointer_with_type_tag(mpi,buffer_idx,type_idx)))
+  /* ... other macros ...  */
+  #  endif
+  #endif
+
+  #if !defined(ATTR_MPI_PWT)
+  # define ATTR_MPI_PWT(buffer_idx, type_idx)
+  #endif
+
+  int MPI_Send(void *buf, int count, MPI_Datatype datatype /*, other args omitted */)
+      ATTR_MPI_PWT(1,3);
+
+argument_with_type_tag
+----------------------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "X","","",""
+
+Use ``__attribute__((argument_with_type_tag(arg_kind, arg_idx,
+type_tag_idx)))`` on a function declaration to specify that the function
+accepts a type tag that determines the type of some other argument.
+``arg_kind`` is an identifier that should be used when annotating all
+applicable type tags.
+
+This attribute is primarily useful for checking arguments of variadic functions
+(``pointer_with_type_tag`` can be used in most non-variadic cases).
+
+For example:
+
+.. code-block:: c++
+
+  int fcntl(int fd, int cmd, ...)
+      __attribute__(( argument_with_type_tag(fcntl,3,2) ));
+
+
+pointer_with_type_tag
+---------------------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "X","","",""
+
+Use ``__attribute__((pointer_with_type_tag(ptr_kind, ptr_idx, type_tag_idx)))``
+on a function declaration to specify that the function accepts a type tag that
+determines the pointee type of some other pointer argument.
+
+For example:
+
+.. code-block:: c++
+
+  int MPI_Send(void *buf, int count, MPI_Datatype datatype /*, other args omitted */)
+      __attribute__(( pointer_with_type_tag(mpi,1,3) ));
+
+
+type_tag_for_datatype
+---------------------
+.. csv-table:: Supported Syntaxes
+   :header: "GNU", "C++11", "__declspec", "Keyword"
+
+   "X","","",""
+
+Clang supports annotating type tags of two forms.
+
+* **Type tag that is an expression containing a reference to some declared
+  identifier.** Use ``__attribute__((type_tag_for_datatype(kind, type)))`` on a
+  declaration with that identifier:
+
+  .. code-block:: c++
+
+    extern struct mpi_datatype mpi_datatype_int
+        __attribute__(( type_tag_for_datatype(mpi,int) ));
+    #define MPI_INT ((MPI_Datatype) &mpi_datatype_int)
+
+* **Type tag that is an integral literal.** Introduce a ``static const``
+  variable with a corresponding initializer value and attach
+  ``__attribute__((type_tag_for_datatype(kind, type)))`` on that declaration,
+  for example:
+
+  .. code-block:: c++
+
+    #define MPI_INT ((MPI_Datatype) 42)
+    static const MPI_Datatype mpi_datatype_int
+        __attribute__(( type_tag_for_datatype(mpi,int) )) = 42
+
+The attribute also accepts an optional third argument that determines how the
+expression is compared to the type tag.  There are two supported flags:
+
+* ``layout_compatible`` will cause types to be compared according to
+  layout-compatibility rules (C++11 [class.mem] p 17, 18).  This is
+  implemented to support annotating types like ``MPI_DOUBLE_INT``.
+
+  For example:
+
+  .. code-block:: c++
+
+    /* In mpi.h */
+    struct internal_mpi_double_int { double d; int i; };
+    extern struct mpi_datatype mpi_datatype_double_int
+        __attribute__(( type_tag_for_datatype(mpi, struct internal_mpi_double_int, layout_compatible) ));
+
+    #define MPI_DOUBLE_INT ((MPI_Datatype) &mpi_datatype_double_int)
+
+    /* In user code */
+    struct my_pair { double a; int b; };
+    struct my_pair *buffer;
+    MPI_Send(buffer, 1, MPI_DOUBLE_INT /*, ...  */); // no warning
+
+    struct my_int_pair { int a; int b; }
+    struct my_int_pair *buffer2;
+    MPI_Send(buffer2, 1, MPI_DOUBLE_INT /*, ...  */); // warning: actual buffer element
+                                                      // type 'struct my_int_pair'
+                                                      // doesn't match specified MPI_Datatype
+
+* ``must_be_null`` specifies that the expression should be a null pointer
+  constant, for example:
+
+  .. code-block:: c++
+
+    /* In mpi.h */
+    extern struct mpi_datatype mpi_datatype_null
+        __attribute__(( type_tag_for_datatype(mpi, void, must_be_null) ));
+
+    #define MPI_DATATYPE_NULL ((MPI_Datatype) &mpi_datatype_null)
+
+    /* In user code */
+    MPI_Send(buffer, 1, MPI_DATATYPE_NULL /*, ...  */); // warning: MPI_DATATYPE_NULL
+                                                        // was specified but buffer
+                                                        // is not a null pointer
+
+
diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt
index 8528c7a..20a1396 100644
--- a/docs/CMakeLists.txt
+++ b/docs/CMakeLists.txt
@@ -22,6 +22,31 @@
     set(extra_search_mappings "")
   endif()
 
+  # If asked, configure doxygen for the creation of a Qt Compressed Help file.
+  if (LLVM_ENABLE_DOXYGEN_QT_HELP)
+    set(CLANG_DOXYGEN_QCH_FILENAME "org.llvm.clang.qch" CACHE STRING
+      "Filename of the Qt Compressed help file")
+    set(CLANG_DOXYGEN_QHP_NAMESPACE "org.llvm.clang" CACHE STRING
+      "Namespace under which the intermediate Qt Help Project file lives")
+    set(CLANG_DOXYGEN_QHP_CUST_FILTER_NAME "Clang ${CLANG_VERSION}" CACHE STRING
+      "See http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-filters")
+    set(CLANG_DOXYGEN_QHP_CUST_FILTER_ATTRS "Clang,${CLANG_VERSION}" CACHE STRING
+      "See http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes")
+    set(clang_doxygen_generate_qhp "YES")
+    set(clang_doxygen_qch_filename "${CLANG_DOXYGEN_QCH_FILENAME}")
+    set(clang_doxygen_qhp_namespace "${CLANG_DOXYGEN_QHP_NAMESPACE}")
+    set(clang_doxygen_qhelpgenerator_path "${LLVM_DOXYGEN_QHELPGENERATOR_PATH}")
+    set(clang_doxygen_qhp_cust_filter_name "${CLANG_DOXYGEN_QHP_CUST_FILTER_NAME}")
+    set(clang_doxygen_qhp_cust_filter_attrs "${CLANG_DOXYGEN_QHP_CUST_FILTER_ATTRS}")
+  else()
+    set(clang_doxygen_generate_qhp "NO")
+    set(clang_doxygen_qch_filename "")
+    set(clang_doxygen_qhp_namespace "")
+    set(clang_doxygen_qhelpgenerator_path "")
+    set(clang_doxygen_qhp_cust_filter_name "")
+    set(clang_doxygen_qhp_cust_filter_attrs "")
+  endif()
+
   configure_file(${CMAKE_CURRENT_SOURCE_DIR}/doxygen.cfg.in
     ${CMAKE_CURRENT_BINARY_DIR}/doxygen.cfg @ONLY)
 
@@ -33,6 +58,12 @@
   set(enable_server_based_search)
   set(enable_external_search)
   set(extra_search_mappings)
+  set(clang_doxygen_generate_qhp)
+  set(clang_doxygen_qch_filename)
+  set(clang_doxygen_qhp_namespace)
+  set(clang_doxygen_qhelpgenerator_path)
+  set(clang_doxygen_qhp_cust_filter_name)
+  set(clang_doxygen_qhp_cust_filter_attrs)
 
   add_custom_target(doxygen-clang
     COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/doxygen.cfg
@@ -49,3 +80,12 @@
   endif()
 endif()
 endif()
+
+if (LLVM_ENABLE_SPHINX)
+  if (SPHINX_FOUND)
+    include(AddSphinxTarget)
+    if (${SPHINX_OUTPUT_HTML})
+      add_sphinx_target(html clang)
+    endif()
+  endif()
+endif()
diff --git a/docs/ClangFormat.rst b/docs/ClangFormat.rst
index bc6b8a2..86c5ec5 100644
--- a/docs/ClangFormat.rst
+++ b/docs/ClangFormat.rst
@@ -146,7 +146,7 @@
 Visual Studio Integration
 =========================
 
-Download the latest Visual Studio plugin from the `alpha build site
+Download the latest Visual Studio extension from the `alpha build site
 <http://llvm.org/builds/>`_. The default key-binding is Ctrl-R,Ctrl-F.
 
 
@@ -158,21 +158,30 @@
 
 .. code-block:: console
 
-  usage: clang-format-diff.py [-h] [-p P] [-style STYLE]
+  usage: clang-format-diff.py [-h] [-i] [-p NUM] [-regex PATTERN] [-style STYLE]
 
-  Reformat changed lines in diff.
+  Reformat changed lines in diff. Without -i option just output the diff that
+  would be introduced.
 
   optional arguments:
-    -h, --help    show this help message and exit
-    -p P          strip the smallest prefix containing P slashes
-    -style STYLE  formatting style to apply (LLVM, Google, Chromium, Mozilla,
-                  WebKit)
+    -h, --help      show this help message and exit
+    -i              apply edits to files instead of displaying a diff
+    -p NUM          strip the smallest prefix containing P slashes
+    -regex PATTERN  custom pattern selecting file paths to reformat
+    -style STYLE    formatting style to apply (LLVM, Google, Chromium, Mozilla,
+                    WebKit)
 
 So to reformat all the lines in the latest :program:`git` commit, just do:
 
 .. code-block:: console
 
-  git diff -U0 HEAD^ | clang-format-diff.py -p1
+  git diff -U0 HEAD^ | clang-format-diff.py -i -p1
+
+In an SVN client, you can do:
+
+.. code-block:: console
+
+  svn diff --diff-cmd=diff -x-U0 | clang-format-diff.py -i
 
 The :option:`-U0` will create a diff without context lines (the script would format
 those as well).
diff --git a/docs/ClangFormatStyleOptions.rst b/docs/ClangFormatStyleOptions.rst
index d73801c..07febaf 100644
--- a/docs/ClangFormatStyleOptions.rst
+++ b/docs/ClangFormatStyleOptions.rst
@@ -106,6 +106,25 @@
   Allow putting all parameters of a function declaration onto
   the next line even if ``BinPackParameters`` is ``false``.
 
+**AllowShortBlocksOnASingleLine** (``bool``)
+  Allows contracting simple braced statements to a single line.
+
+  E.g., this allows ``if (a) { return; }`` to be put on a single line.
+
+**AllowShortFunctionsOnASingleLine** (``ShortFunctionStyle``)
+  Dependent on the value, ``int f() { return 0; }`` can be put
+  on a single line.
+
+  Possible values:
+
+  * ``SFS_None`` (in configuration: ``None``)
+    Never merge functions into a single line.
+  * ``SFS_Inline`` (in configuration: ``Inline``)
+    Only merge functions defined inside a class.
+  * ``SFS_All`` (in configuration: ``All``)
+    Merge all functions fitting on a single line.
+
+
 **AllowShortIfStatementsOnASingleLine** (``bool``)
   If ``true``, ``if (a) return;`` can be put on a single
   line.
@@ -142,8 +161,15 @@
     Like ``Attach``, but break before function definitions.
   * ``BS_Allman`` (in configuration: ``Allman``)
     Always break before braces.
+  * ``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.
 
 
+**BreakBeforeTernaryOperators** (``bool``)
+  If ``true``, ternary operators will be placed after line breaks.
+
 **BreakConstructorInitializersBeforeComma** (``bool``)
   Always break constructor initializers before commas and align
   the commas with the colon.
@@ -153,7 +179,11 @@
 
   A column limit of ``0`` means that there is no column limit. In this case,
   clang-format will respect the input's line breaking decisions within
-  statements.
+  statements unless they contradict other rules.
+
+**CommentPragmas** (``std::string``)
+  A regular expression that describes comments with special meaning,
+  which should not be split into lines or otherwise changed.
 
 **ConstructorInitializerAllOnOneLineOrOnePerLine** (``bool``)
   If the constructor initializers don't fit on a line, put each
@@ -163,6 +193,9 @@
   The number of characters to use for indentation of constructor
   initializer lists.
 
+**ContinuationIndentWidth** (``unsigned``)
+  Indent width for line continuations.
+
 **Cpp11BracedListStyle** (``bool``)
   If ``true``, format braced lists as best suited for C++11 braced
   lists.
@@ -178,8 +211,12 @@
   the parentheses of a function call with that name. If there is no name,
   a zero-length name is assumed.
 
-**DerivePointerBinding** (``bool``)
-  If ``true``, analyze the formatted file for the most common binding.
+**DerivePointerAlignment** (``bool``)
+  If ``true``, analyze the formatted file for the most common
+  alignment of & and \*. ``PointerAlignment`` is then used only as fallback.
+
+**DisableFormat** (``bool``)
+  Disables formatting at all.
 
 **ExperimentalAutoDetectBinPacking** (``bool``)
   If ``true``, clang-format detects whether function calls and
@@ -193,19 +230,50 @@
   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.
 
+**ForEachMacros** (``std::vector<std::string>``)
+  A vector of macros that should be interpreted as foreach loops
+  instead of as function calls.
+
+  These are expected to be macros of the form:
+  \code
+  FOREACH(<variable-declaration>, ...)
+  <loop-body>
+  \endcode
+
+  For example: BOOST_FOREACH.
+
 **IndentCaseLabels** (``bool``)
   Indent case labels one level from the switch statement.
 
   When ``false``, use the same indentation level as for the switch statement.
   Switch statement body is always indented one level more than case labels.
 
-**IndentFunctionDeclarationAfterType** (``bool``)
-  If ``true``, indent when breaking function declarations which
-  are not also definitions after the type.
-
 **IndentWidth** (``unsigned``)
   The number of columns to use for indentation.
 
+**IndentWrappedFunctionNames** (``bool``)
+  Indent if a function definition or declaration is wrapped after the
+  type.
+
+**KeepEmptyLinesAtTheStartOfBlocks** (``bool``)
+  If true, empty lines at the start of blocks are kept.
+
+**Language** (``LanguageKind``)
+  Language, this format style is targeted at.
+
+  Possible values:
+
+  * ``LK_None`` (in configuration: ``None``)
+    Do not use.
+  * ``LK_Cpp`` (in configuration: ``Cpp``)
+    Should be used for C, C++, ObjectiveC, ObjectiveC++.
+  * ``LK_JavaScript`` (in configuration: ``JavaScript``)
+    Should be used for JavaScript.
+  * ``LK_Proto`` (in configuration: ``Proto``)
+    Should be used for Protocol Buffers
+    (https://developers.google.com/protocol-buffers/).
+
+
 **MaxEmptyLinesToKeep** (``unsigned``)
   The maximum number of consecutive empty lines to keep.
 
@@ -222,10 +290,17 @@
     Indent in all namespaces.
 
 
+**ObjCSpaceAfterProperty** (``bool``)
+  Add a space after ``@property`` in Objective-C, i.e. use
+  ``\@property (readonly)`` instead of ``\@property(readonly)``.
+
 **ObjCSpaceBeforeProtocolList** (``bool``)
   Add a space in front of an Objective-C protocol list, i.e. use
   ``Foo <Protocol>`` instead of ``Foo<Protocol>``.
 
+**PenaltyBreakBeforeFirstCallParameter** (``unsigned``)
+  The penalty for breaking a function call after "call(".
+
 **PenaltyBreakComment** (``unsigned``)
   The penalty for each line break introduced inside a comment.
 
@@ -242,28 +317,62 @@
   Penalty for putting the return type of a function onto its own
   line.
 
-**PointerBindsToType** (``bool``)
-  Set whether & and * bind to the type as opposed to the variable.
+**PointerAlignment** (``PointerAlignmentStyle``)
+  Pointer and reference alignment style.
 
-**SpaceAfterControlStatementKeyword** (``bool``)
-  If ``true``, spaces will be inserted between 'for'/'if'/'while'/...
-  and '('.
+  Possible values:
+
+  * ``PAS_Left`` (in configuration: ``Left``)
+    Align pointer to the left.
+  * ``PAS_Right`` (in configuration: ``Right``)
+    Align pointer to the right.
+  * ``PAS_Middle`` (in configuration: ``Middle``)
+    Align pointer in the middle.
+
 
 **SpaceBeforeAssignmentOperators** (``bool``)
   If ``false``, spaces will be removed before assignment operators.
 
+**SpaceBeforeParens** (``SpaceBeforeParensOptions``)
+  Defines in which cases to put a space before opening parentheses.
+
+  Possible values:
+
+  * ``SBPO_Never`` (in configuration: ``Never``)
+    Never put a space before opening parentheses.
+  * ``SBPO_ControlStatements`` (in configuration: ``ControlStatements``)
+    Put a space before opening parentheses only after control statement
+    keywords (``for/if/while...``).
+  * ``SBPO_Always`` (in configuration: ``Always``)
+    Always put a space before opening parentheses, except when it's
+    prohibited by the syntax rules (in function-like macro definitions) or
+    when determined by other style rules (after unary operators, opening
+    parentheses, etc.)
+
+
 **SpaceInEmptyParentheses** (``bool``)
-  If ``false``, spaces may be inserted into '()'.
+  If ``true``, spaces may be inserted into '()'.
 
 **SpacesBeforeTrailingComments** (``unsigned``)
-  The number of spaces to before trailing line comments.
+  The number of spaces before trailing line comments
+  (``//`` - comments).
+
+  This does not affect trailing block comments (``/**/`` - comments) as those
+  commonly have different usage patterns and a number of special cases.
+
+**SpacesInAngles** (``bool``)
+  If ``true``, spaces will be inserted after '<' and before '>' in
+  template argument lists
 
 **SpacesInCStyleCastParentheses** (``bool``)
-  If ``false``, spaces may be inserted into C style casts.
+  If ``true``, spaces may be inserted into C style casts.
+
+**SpacesInContainerLiterals** (``bool``)
+  If ``true``, spaces are inserted inside container literals (e.g.
+  ObjC and Javascript array and dict literals).
 
 **SpacesInParentheses** (``bool``)
-  If ``true``, spaces will be inserted after every '(' and before
-  every ')'.
+  If ``true``, spaces will be inserted after '(' and before ')'.
 
 **Standard** (``LanguageStandard``)
   Format compatible with this standard, e.g. use
diff --git a/docs/ClangPlugins.rst b/docs/ClangPlugins.rst
index 7c5c65c..9a5bc14 100644
--- a/docs/ClangPlugins.rst
+++ b/docs/ClangPlugins.rst
@@ -47,70 +47,10 @@
 =======================
 
 Let's look at an example plugin that prints top-level function names.  This
-example is also checked into the clang repository; please also take a look at
-the latest `checked in version of PrintFunctionNames.cpp
+example is checked into the clang repository; please take a look at
+the `latest version of PrintFunctionNames.cpp
 <http://llvm.org/viewvc/llvm-project/cfe/trunk/examples/PrintFunctionNames/PrintFunctionNames.cpp?view=markup>`_.
 
-.. code-block:: c++
-
-    #include "clang/Frontend/FrontendPluginRegistry.h"
-    #include "clang/AST/ASTConsumer.h"
-    #include "clang/AST/AST.h"
-    #include "clang/Frontend/CompilerInstance.h"
-    #include "llvm/Support/raw_ostream.h"
-    using namespace clang;
-
-    namespace {
-
-    class PrintFunctionsConsumer : public ASTConsumer {
-    public:
-      virtual bool HandleTopLevelDecl(DeclGroupRef DG) {
-        for (DeclGroupRef::iterator i = DG.begin(), e = DG.end(); i != e; ++i) {
-          const Decl *D = *i;
-          if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
-            llvm::errs() << "top-level-decl: \"" << ND->getNameAsString() << "\"\n";
-        }
-
-        return true;
-      }
-    };
-
-    class PrintFunctionNamesAction : public PluginASTAction {
-    protected:
-      ASTConsumer *CreateASTConsumer(CompilerInstance &CI, llvm::StringRef) {
-        return new PrintFunctionsConsumer();
-      }
-
-      bool ParseArgs(const CompilerInstance &CI,
-                     const std::vector<std::string>& args) {
-        for (unsigned i = 0, e = args.size(); i != e; ++i) {
-          llvm::errs() << "PrintFunctionNames arg = " << args[i] << "\n";
-
-          // Example error handling.
-          if (args[i] == "-an-error") {
-            DiagnosticsEngine &D = CI.getDiagnostics();
-            unsigned DiagID = D.getCustomDiagID(
-              DiagnosticsEngine::Error, "invalid argument '" + args[i] + "'");
-            D.Report(DiagID);
-            return false;
-          }
-        }
-        if (args.size() && args[0] == "help")
-          PrintHelp(llvm::errs());
-
-        return true;
-      }
-      void PrintHelp(llvm::raw_ostream& ros) {
-        ros << "Help for PrintFunctionNames plugin goes here\n";
-      }
-
-    };
-
-    }
-
-    static FrontendPluginRegistry::Add<PrintFunctionNamesAction>
-    X("print-fns", "print function names");
-
 Running the plugin
 ==================
 
diff --git a/docs/ClangTools.rst b/docs/ClangTools.rst
index f8a7c36..8957541 100644
--- a/docs/ClangTools.rst
+++ b/docs/ClangTools.rst
@@ -93,9 +93,9 @@
 refactoring tools, e.g. to do a reformatting of all the lines changed during a
 renaming.
 
-``cpp11-migrate``
-~~~~~~~~~~~~~~~~~
-``cpp11-migrate`` migrates C++ code to use C++11 features where appropriate.
+``clang-modernize``
+~~~~~~~~~~~~~~~~~~~
+``clang-modernize`` migrates C++ code to use C++11 features where appropriate.
 Currently it can:
 
 * convert loops to range-based for loops;
diff --git a/docs/CrossCompilation.rst b/docs/CrossCompilation.rst
index e655d89..89f8777 100644
--- a/docs/CrossCompilation.rst
+++ b/docs/CrossCompilation.rst
@@ -190,7 +190,7 @@
 
 When you want to cross-compile to more than one configuration, for
 example hard-float-ARM and soft-float-ARM, you'll have to have multiple
-copies of you libraries and (possibly) headers.
+copies of your libraries and (possibly) headers.
 
 Some Linux distributions have support for Multilib, which handle that
 for you in an easier way, but if you're not careful and, for instance,
diff --git a/docs/ExternalClangExamples.rst b/docs/ExternalClangExamples.rst
index c7fd4c5..71d50c2 100644
--- a/docs/ExternalClangExamples.rst
+++ b/docs/ExternalClangExamples.rst
@@ -78,3 +78,10 @@
     "cldoc is a Clang based documentation generator for C and C++.
     cldoc tries to solve the issue of writing C/C++ software documentation
     with a modern, non-intrusive and robust approach."
+
+`<https://github.com/AlexDenisov/ToyClangPlugin>`_
+    "The simplest Clang plugin implementing a semantic check for Objective-C.
+    This example shows how to use the ``DiagnosticsEngine`` (emit warnings,
+    errors, fixit hints).  See also `<http://l.rw.rw/clang_plugin>`_ for
+    step-by-step instructions."
+
diff --git a/docs/InternalsManual.rst b/docs/InternalsManual.rst
index 6f55702..8e047db 100644
--- a/docs/InternalsManual.rst
+++ b/docs/InternalsManual.rst
@@ -87,7 +87,8 @@
 Since the enum is referenced in the C++ code that produces the diagnostic, it
 is somewhat useful for it to be reasonably short.
 
-The severity of the diagnostic comes from the set {``NOTE``, ``WARNING``,
+The severity of the diagnostic comes from the set {``NOTE``, ``REMARK``,
+``WARNING``,
 ``EXTENSION``, ``EXTWARN``, ``ERROR``}.  The ``ERROR`` severity is used for
 diagnostics indicating the program is never acceptable under any circumstances.
 When an error is emitted, the AST for the input code may not be fully built.
@@ -97,11 +98,13 @@
 code is non-portable.  The difference is that the former are ignored by
 default, and the later warn by default.  The ``WARNING`` severity is used for
 constructs that are valid in the currently selected source language but that
-are dubious in some way.  The ``NOTE`` level is used to staple more information
-onto previous diagnostics.
+are dubious in some way.  The ``REMARK`` severity provides generic information
+about the compilation that is not necessarily related to any dubious code.  The
+``NOTE`` level is used to staple more information onto previous diagnostics.
 
 These *severities* are mapped into a smaller set (the ``Diagnostic::Level``
-enum, {``Ignored``, ``Note``, ``Warning``, ``Error``, ``Fatal``}) of output
+enum, {``Ignored``, ``Note``, ``Remark``, ``Warning``, ``Error``, ``Fatal``}) of
+output
 *levels* by the diagnostics subsystem based on various configuration options.
 Clang internally supports a fully fine grained mapping mechanism that allows
 you to map almost any diagnostic to the output level that you want.  The only
@@ -1588,47 +1591,171 @@
 How to add an attribute
 -----------------------
 
-To add an attribute, you'll have to add it to the list of attributes, add it to
-the parsing phase, and look for it in the AST scan.
-`r124217 <http://llvm.org/viewvc/llvm-project?view=rev&revision=124217>`_
-has a good example of adding a warning attribute.
+Attribute Basics
+^^^^^^^^^^^^^^^^
 
-(Beware that this hasn't been reviewed/fixed by the people who designed the
-attributes system yet.)
+Attributes in clang come in two forms: parsed form, and semantic form. Both 
+forms are represented via a tablegen definition of the attribute, specified in
+Attr.td.
 
 
 ``include/clang/Basic/Attr.td``
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-First, add your attribute to the `include/clang/Basic/Attr.td file
-<http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?view=markup>`_.
+First, add your attribute to the `include/clang/Basic/Attr.td 
+<http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?view=markup>`_ 
+file.
 
 Each attribute gets a ``def`` inheriting from ``Attr`` or one of its
 subclasses.  ``InheritableAttr`` means that the attribute also applies to
-subsequent declarations of the same name.
+subsequent declarations of the same name.  ``InheritableParamAttr`` is similar 
+to ``InheritableAttr``, except that the attribute is written on a parameter 
+instead of a declaration, type or statement.  Attributes inheriting from 
+``TypeAttr`` are pure type attributes which generally are not given a 
+representation in the AST.  Attributes inheriting from ``TargetSpecificAttr`` 
+are attributes specific to one or more target architectures.  An attribute that 
+inherits from ``IgnoredAttr`` is parsed, but will generate an ignored attribute 
+diagnostic when used.  The attribute type may be useful when an attribute is 
+supported by another vendor, but not supported by clang.
 
 ``Spellings`` lists the strings that can appear in ``__attribute__((here))`` or
-``[[here]]``.  All such strings will be synonymous.  If you want to allow the
-``[[]]`` C++11 syntax, you have to define a list of ``Namespaces``, which will
-let users write ``[[namespace::spelling]]``.  Using the empty string for a
-namespace will allow users to write just the spelling with no "``::``".
-Attributes which g++-4.8 accepts should also have a
-``CXX11<"gnu", "spelling">`` spelling.
+``[[here]]``.  All such strings will be synonymous.  Possible ``Spellings`` 
+are: ``GNU`` (for use with GNU-style __attribute__ spellings), ``Declspec`` 
+(for use with Microsoft Visual Studio-style __declspec spellings), ``CXX11` 
+(for use with C++11-style [[foo]] and [[foo::bar]] spellings), and ``Keyword`` 
+(for use with attributes that are implemented as keywords, like C++11's 
+``override`` or ``final``). If you want to allow the ``[[]]`` C++11 syntax, you 
+have to define a list of ``Namespaces``, which will let users write 
+``[[namespace::spelling]]``.  Using the empty string for a namespace will allow 
+users to write just the spelling with no "``::``".  Attributes which g++-4.8 
+or later accepts should also have a ``CXX11<"gnu", "spelling">`` spelling.
 
 ``Subjects`` restricts what kinds of AST node to which this attribute can
-appertain (roughly, attach).
+appertain (roughly, attach).  The subjects are specified via a ``SubjectList``, 
+which specify the list of subjects. Additionally, subject-related diagnostics 
+can be specified to be warnings or errors, with the default being a warning.  
+The diagnostics displayed to the user are automatically determined based on 
+the subjects in the list, but a custom diagnostic parameter can also be 
+specified in the ``SubjectList``.  The diagnostics generated for subject list 
+violations are either ``diag::warn_attribute_wrong_decl_type`` or
+``diag::err_attribute_wrong_decl_type``, and the parameter enumeration is 
+found in `include/clang/Sema/AttributeList.h 
+<http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/AttributeList.h?view=markup>`_ 
+If you add new Decl nodes to the ``SubjectList``, you may need to update the 
+logic used to automatically determine the diagnostic parameter in `utils/TableGen/ClangAttrEmitter.cpp 
+<http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?view=markup>`_.
+
+Diagnostic checking for attribute subject lists is automated except when 
+``HasCustomParsing`` is set to ``1``.
+
+By default, all subjects in the SubjectList must either be a Decl node defined 
+in ``DeclNodes.td``, or a statement node defined in ``StmtNodes.td``.  However, 
+more complex subjects can be created by creating a ``SubsetSubject`` object.  
+Each such object has a base subject which it appertains to (which must be a 
+Decl or Stmt node, and not a SubsetSubject node), and some custom code which is 
+called when determining whether an attribute appertains to the subject.  For 
+instance, a ``NonBitField`` SubsetSubject appertains to a ``FieldDecl``, and 
+tests whether the given FieldDecl is a bit field.  When a SubsetSubject is 
+specified in a SubjectList, a custom diagnostic parameter must also be provided.
 
 ``Args`` names the arguments the attribute takes, in order.  If ``Args`` is
 ``[StringArgument<"Arg1">, IntArgument<"Arg2">]`` then
-``__attribute__((myattribute("Hello", 3)))`` will be a valid use.
+``__attribute__((myattribute("Hello", 3)))`` will be a valid use.  Attribute 
+arguments specify both the parsed form and the semantic form of the attribute.  
+The previous example shows an attribute which requires two attributes while 
+parsing, and the Attr subclass' constructor for the attribute will require a 
+string and integer argument.
+
+Diagnostic checking for argument counts is automated except when 
+``HasCustomParsing`` is set to ``1``, or when the attribute uses an optional or 
+variadic argument.  Diagnostic checking for argument semantics is not automated.
+
+If the parsed form of the attribute is more complex, or differs from the 
+semantic form, the ``HasCustomParsing`` bit can be set to ``1`` for the class, 
+and the parsing code in `Parser::ParseGNUAttributeArgs 
+<http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?view=markup>`_ 
+can be updated for the special case.  Note that this only applies to arguments 
+with a GNU spelling -- attributes with a __declspec spelling currently ignore 
+this flag and are handled by ``Parser::ParseMicrosoftDeclSpec``.
+
+Custom accessors can be generated for an attribute based on the spelling list 
+for that attribute.  For instance, if an attribute has two different spellings: 
+'Foo' and 'Bar', accessors can be created: 
+``[Accessor<"isFoo", [GNU<"Foo">]>, Accessor<"isBar", [GNU<"Bar">]>]``
+These accessors will be generated on the semantic form of the attribute, 
+accepting no arguments and returning a Boolean.
+
+Attributes which do not require an AST node should set the ``ASTNode`` field to 
+``0`` to avoid polluting the AST.  Note that anything inheriting from 
+``TypeAttr`` or ``IgnoredAttr`` automatically do not generate an AST node.  All 
+other attributes generate an AST node by default.  The AST node is the semantic 
+representation of the attribute.
+
+Attributes which do not require custom semantic handling should set the 
+``SemaHandler`` field to ``0``.  Note that anything inheriting from 
+``IgnoredAttr`` automatically do not get a semantic handler.  All other 
+attributes are assumed to use a semantic handler by default.  Attributes 
+without a semantic handler are not given a parsed attribute Kind enumeration.
+
+The ``LangOpts`` field can be used to specify a list of language options 
+required by the attribute.  For instance, all of the CUDA-specific attributes 
+specify ``[CUDA]`` for the ``LangOpts`` field, and when the CUDA language 
+option is not enabled, an "attribute ignored" warning diagnostic is emitted.  
+Since language options are not table generated nodes, new language options must 
+be created manually and should specify the spelling used by ``LangOptions`` class.
+
+Target-specific attribute sometimes share a spelling with other attributes in 
+different targets.  For instance, the ARM and MSP430 targets both have an 
+attribute spelled ``GNU<"interrupt">``, but with different parsing and semantic 
+requirements.  To support this feature, an attribute inheriting from 
+``TargetSpecificAttribute`` make specify a ``ParseKind`` field.  This field 
+should be the same value between all arguments sharing a spelling, and 
+corresponds to the parsed attribute's Kind enumeration.  This allows attributes 
+to share a parsed attribute kind, but have distinct semantic attribute classes.  
+For instance, ``AttributeList::AT_Interrupt`` is the shared parsed attribute 
+kind, but ARMInterruptAttr and MSP430InterruptAttr are the semantic attributes 
+generated.
+
+By default, when declarations are merging attributes, an attribute will not be 
+duplicated. However, if an attribute can be duplicated during this merging 
+stage, set ``DuplicatesAllowedWhileMerging`` to ``1``, and the attribute will 
+be merged.
+
+By default, attribute arguments are parsed in an evaluated context. If the 
+arguments for an attribute should be parsed in an unevaluated context (akin to 
+the way the argument to a ``sizeof`` expression is parsed), you can set 
+``ParseArgumentsAsUnevaluated`` to ``1``.
+
+If additional functionality is desired for the semantic form of the attribute, 
+the ``AdditionalMembers`` field specifies code to be copied verbatim into the 
+semantic attribute class object.
+
+All attributes must have one or more form of documentation, which is provided 
+in the ``Documentation`` list. Generally, the documentation for an attribute 
+is a stand-alone definition in `include/clang/Basic/AttrDocs.td 
+<http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AttdDocs.td?view=markup>`_
+that is named after the attribute being documented. Each documentation element 
+is given a ``Category`` (variable, function, or type) and ``Content``. A single 
+attribute may contain multiple documentation elements for distinct categories. 
+For instance, an attribute which can appertain to both function and types (such 
+as a calling convention attribute), should contain two documentation elements. 
+The ``Content`` for an attribute uses reStructuredText (RST) syntax.
+
+If an attribute is used internally by the compiler, but is not written by users 
+(such as attributes with an empty spelling list), it can use the 
+``Undocumented`` documentation element.
 
 Boilerplate
 ^^^^^^^^^^^
 
-Write a new ``HandleYourAttr()`` function in `lib/Sema/SemaDeclAttr.cpp
-<http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?view=markup>`_,
-and add a case to the switch in ``ProcessNonInheritableDeclAttr()`` or
-``ProcessInheritableDeclAttr()`` forwarding to it.
+All semantic processing of declaration attributes happens in `lib/Sema/SemaDeclAttr.cpp
+<http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?view=markup>`_, 
+and generally starts in the ``ProcessDeclAttribute`` function.  If your 
+attribute is a "simple" attribute -- meaning that it requires no custom 
+semantic processing aside from what is automatically  provided for you, you can 
+add a call to ``handleSimpleAttribute<YourAttr>(S, D, Attr);`` to the switch 
+statement. Otherwise, write a new ``handleYourAttr()`` function, and add that 
+to the switch statement.
 
 If your attribute causes extra warnings to fire, define a ``DiagGroup`` in
 `include/clang/Basic/DiagnosticGroups.td
@@ -1638,6 +1765,10 @@
 ``InGroup<DiagGroup<"your-attribute">>`` directly in `DiagnosticSemaKinds.td
 <http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?view=markup>`_
 
+All semantic diagnostics generated for your attribute, including automatically-
+generated ones (such as subjects and argument counts), should have a 
+corresponding test case.
+
 The meat of your attribute
 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -1721,13 +1852,14 @@
    * Make sure that ``children()`` visits all of the subexpressions.  This is
      important for a number of features (e.g., IDE support, C++ variadic
      templates).  If you have sub-types, you'll also need to visit those
-     sub-types in the ``RecursiveASTVisitor``.
-   * Add printing support (``StmtPrinter.cpp``) and dumping support
-     (``StmtDumper.cpp``) for your expression.
+     sub-types in ``RecursiveASTVisitor`` and ``DataRecursiveASTVisitor``.
+   * Add printing support (``StmtPrinter.cpp``) for your expression.
    * Add profiling support (``StmtProfile.cpp``) for your AST node, noting the
      distinguishing (non-source location) characteristics of an instance of
      your expression.  Omitting this step will lead to hard-to-diagnose
      failures regarding matching of template declarations.
+   * Add serialization support (``ASTReaderStmt.cpp``, ``ASTWriterStmt.cpp``)
+     for your AST node.
 
 #. Teach semantic analysis to build your AST node.  At this point, you can wire
    up your ``Sema::BuildXXX`` function to actually create your AST.  A few
diff --git a/docs/LanguageExtensions.rst b/docs/LanguageExtensions.rst
index ca1b7ea..35f759f 100644
--- a/docs/LanguageExtensions.rst
+++ b/docs/LanguageExtensions.rst
@@ -12,7 +12,7 @@
    ObjectiveCLiterals
    BlockLanguageSpec
    Block-ABI-Apple
-   AutomaticReferenceCounting   
+   AutomaticReferenceCounting
 
 Introduction
 ============
@@ -91,7 +91,7 @@
 
 .. _langext-has-feature-back-compat:
 
-For backwards compatibility reasons, ``__has_feature`` can also be used to test
+For backward compatibility, ``__has_feature`` can also be used to test
 for support for non-standardized features, i.e. features not prefixed ``c_``,
 ``cxx_`` or ``objc_``.
 
@@ -113,8 +113,8 @@
 -------------------
 
 This function-like macro takes a single identifier argument that is the name of
-an attribute.  It evaluates to 1 if the attribute is supported or 0 if not.  It
-can be used like this:
+an attribute.  It evaluates to 1 if the attribute is supported by the current
+compilation target, or 0 if not.  It can be used like this:
 
 .. code-block:: c++
 
@@ -134,6 +134,27 @@
 (double underscore) to avoid interference from a macro with the same name.  For
 instance, ``__always_inline__`` can be used instead of ``always_inline``.
 
+``__is_identifier``
+-------------------
+
+This function-like macro takes a single identifier argument that might be either
+a reserved word or a regular identifier. It evaluates to 1 if the argument is just
+a regular identifier and not a reserved word, in the sense that it can then be
+used as the name of a user-defined function or variable. Otherwise it evaluates
+to 0.  It can be used like this:
+
+.. code-block:: c++
+
+  ...
+  #ifdef __is_identifier          // Compatibility with non-clang compilers.
+    #if __is_identifier(__wchar_t)
+      typedef wchar_t __wchar_t;
+    #endif
+  #endif
+
+  __wchar_t WideCharacter;
+  ...
+
 Include File Checking Macros
 ============================
 
@@ -425,103 +446,6 @@
 framework search path.  For consistency, we recommend that such files never be
 included in installed versions of the framework.
 
-Availability attribute
-======================
-
-Clang introduces the ``availability`` attribute, which can be placed on
-declarations to describe the lifecycle of that declaration relative to
-operating system versions.  Consider the function declaration for a
-hypothetical function ``f``:
-
-.. code-block:: c++
-
-  void f(void) __attribute__((availability(macosx,introduced=10.4,deprecated=10.6,obsoleted=10.7)));
-
-The availability attribute states that ``f`` was introduced in Mac OS X 10.4,
-deprecated in Mac OS X 10.6, and obsoleted in Mac OS X 10.7.  This information
-is used by Clang to determine when it is safe to use ``f``: for example, if
-Clang is instructed to compile code for Mac OS X 10.5, a call to ``f()``
-succeeds.  If Clang is instructed to compile code for Mac OS X 10.6, the call
-succeeds but Clang emits a warning specifying that the function is deprecated.
-Finally, if Clang is instructed to compile code for Mac OS X 10.7, the call
-fails because ``f()`` is no longer available.
-
-The availability attribute is a comma-separated list starting with the
-platform name and then including clauses specifying important milestones in the
-declaration's lifetime (in any order) along with additional information.  Those
-clauses can be:
-
-introduced=\ *version*
-  The first version in which this declaration was introduced.
-
-deprecated=\ *version*
-  The first version in which this declaration was deprecated, meaning that
-  users should migrate away from this API.
-
-obsoleted=\ *version*
-  The first version in which this declaration was obsoleted, meaning that it
-  was removed completely and can no longer be used.
-
-unavailable
-  This declaration is never available on this platform.
-
-message=\ *string-literal*
-  Additional message text that Clang will provide when emitting a warning or
-  error about use of a deprecated or obsoleted declaration.  Useful to direct
-  users to replacement APIs.
-
-Multiple availability attributes can be placed on a declaration, which may
-correspond to different platforms.  Only the availability attribute with the
-platform corresponding to the target platform will be used; any others will be
-ignored.  If no availability attribute specifies availability for the current
-target platform, the availability attributes are ignored.  Supported platforms
-are:
-
-``ios``
-  Apple's iOS operating system.  The minimum deployment target is specified by
-  the ``-mios-version-min=*version*`` or ``-miphoneos-version-min=*version*``
-  command-line arguments.
-
-``macosx``
-  Apple's Mac OS X operating system.  The minimum deployment target is
-  specified by the ``-mmacosx-version-min=*version*`` command-line argument.
-
-A declaration can be used even when deploying back to a platform version prior
-to when the declaration was introduced.  When this happens, the declaration is
-`weakly linked
-<https://developer.apple.com/library/mac/#documentation/MacOSX/Conceptual/BPFrameworks/Concepts/WeakLinking.html>`_,
-as if the ``weak_import`` attribute were added to the declaration.  A
-weakly-linked declaration may or may not be present a run-time, and a program
-can determine whether the declaration is present by checking whether the
-address of that declaration is non-NULL.
-
-If there are multiple declarations of the same entity, the availability
-attributes must either match on a per-platform basis or later
-declarations must not have availability attributes for that
-platform. For example:
-
-.. code-block:: c
-
-  void g(void) __attribute__((availability(macosx,introduced=10.4)));
-  void g(void) __attribute__((availability(macosx,introduced=10.4))); // okay, matches
-  void g(void) __attribute__((availability(ios,introduced=4.0))); // okay, adds a new platform
-  void g(void); // okay, inherits both macosx and ios availability from above.
-  void g(void) __attribute__((availability(macosx,introduced=10.5))); // error: mismatch
-
-When one method overrides another, the overriding method can be more widely available than the overridden method, e.g.,:
-
-.. code-block:: objc
-
-  @interface A
-  - (id)method __attribute__((availability(macosx,introduced=10.4)));
-  - (id)method2 __attribute__((availability(macosx,introduced=10.4)));
-  @end
-
-  @interface B : A
-  - (id)method __attribute__((availability(macosx,introduced=10.3))); // okay: method moved into base class later
-  - (id)method __attribute__((availability(macosx,introduced=10.5))); // error: this method was available via the base class in 10.4
-  @end
-
 Checks for Standard Language Features
 =====================================
 
@@ -826,20 +750,18 @@
 C++1y generalized lambda capture
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Use ``__has_feature(cxx_init_capture)`` or
-``__has_extension(cxx_init_capture)`` to determine if support for
+Use ``__has_feature(cxx_init_captures)`` or
+``__has_extension(cxx_init_captures)`` to determine if support for
 lambda captures with explicit initializers is enabled
 (for instance, ``[n(0)] { return ++n; }``).
-Clang does not yet support this feature.
 
 C++1y generic lambdas
 ^^^^^^^^^^^^^^^^^^^^^
 
-Use ``__has_feature(cxx_generic_lambda)`` or
-``__has_extension(cxx_generic_lambda)`` to determine if support for generic
+Use ``__has_feature(cxx_generic_lambdas)`` or
+``__has_extension(cxx_generic_lambdas)`` to determine if support for generic
 (polymorphic) lambdas is enabled
 (for instance, ``[] (auto x) { return x + 1; }``).
-Clang does not yet support this feature.
 
 C++1y relaxed constexpr
 ^^^^^^^^^^^^^^^^^^^^^^^
@@ -872,7 +794,6 @@
 Use ``__has_feature(cxx_variable_templates)`` or
 ``__has_extension(cxx_variable_templates)`` to determine if support for
 templated variable declarations is enabled.
-Clang does not yet support this feature.
 
 C11
 ---
@@ -924,15 +845,33 @@
 Use ``__has_feature(c_thread_local)`` or ``__has_extension(c_thread_local)``
 to determine if support for ``_Thread_local`` variables is enabled.
 
-Checks for Type Traits
-======================
+Checks for Type Trait Primitives
+================================
+
+Type trait primitives are special builtin constant expressions that can be used
+by the standard C++ library to facilitate or simplify the implementation of
+user-facing type traits in the <type_traits> header.
+
+They are not intended to be used directly by user code because they are
+implementation-defined and subject to change -- as such they're tied closely to
+the supported set of system headers, currently:
+
+* LLVM's own libc++
+* GNU libstdc++
+* The Microsoft standard C++ library
 
 Clang supports the `GNU C++ type traits
 <http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html>`_ and a subset of the
 `Microsoft Visual C++ Type traits
-<http://msdn.microsoft.com/en-us/library/ms177194(v=VS.100).aspx>`_.  For each
-supported type trait ``__X``, ``__has_extension(X)`` indicates the presence of
-the type trait.  For example:
+<http://msdn.microsoft.com/en-us/library/ms177194(v=VS.100).aspx>`_.
+
+Feature detection is supported only for some of the primitives at present. User
+code should not use these checks because they bear no direct relation to the
+actual set of type traits supported by the C++ standard library.
+
+For type trait ``__X``, ``__has_extension(X)`` indicates the presence of the
+type trait primitive in the compiler. A simplistic usage example as might be
+seen in standard C++ headers follows:
 
 .. code-block:: c++
 
@@ -942,10 +881,10 @@
     static const bool value = __is_convertible_to(From, To);
   };
   #else
-  // Emulate type trait
+  // Emulate type trait for compatibility with other compilers.
   #endif
 
-The following type traits are supported by Clang:
+The following type trait primitives are supported by Clang:
 
 * ``__has_nothrow_assign`` (GNU, Microsoft)
 * ``__has_nothrow_copy`` (GNU, Microsoft)
@@ -980,6 +919,11 @@
   ``argtypes...`` such that no non-trivial functions are called as part of
   that initialization.  This trait is required to implement the C++11 standard
   library.
+* ``__is_destructible`` (MSVC 2013): partially implemented
+* ``__is_nothrow_destructible`` (MSVC 2013): partially implemented
+* ``__is_nothrow_assignable`` (MSVC 2013, clang)
+* ``__is_constructible`` (MSVC 2013, clang)
+* ``__is_nothrow_constructible`` (MSVC 2013, clang)
 
 Blocks
 ======
@@ -1174,77 +1118,6 @@
 ``__has_feature(objc_default_synthesize_properties)`` checks for availability
 of this feature in version of clang being used.
 
-.. _langext-objc_method_family:
-
-
-Objective-C requiring a call to ``super`` in an override
---------------------------------------------------------
-
-Some Objective-C classes allow a subclass to override a particular method in a
-parent class but expect that the overriding method also calls the overridden
-method in the parent class. For these cases, we provide an attribute to
-designate that a method requires a "call to ``super``" in the overriding
-method in the subclass.
-
-**Usage**: ``__attribute__((objc_requires_super))``.  This attribute can only
-be placed at the end of a method declaration:
-
-.. code-block:: objc
-
-  - (void)foo __attribute__((objc_requires_super));
-
-This attribute can only be applied the method declarations within a class, and
-not a protocol.  Currently this attribute does not enforce any placement of
-where the call occurs in the overriding method (such as in the case of
-``-dealloc`` where the call must appear at the end).  It checks only that it
-exists.
-
-Note that on both OS X and iOS that the Foundation framework provides a
-convenience macro ``NS_REQUIRES_SUPER`` that provides syntactic sugar for this
-attribute:
-
-.. code-block:: objc
-
-  - (void)foo NS_REQUIRES_SUPER;
-
-This macro is conditionally defined depending on the compiler's support for
-this attribute.  If the compiler does not support the attribute the macro
-expands to nothing.
-
-Operationally, when a method has this annotation the compiler will warn if the
-implementation of an override in a subclass does not call super.  For example:
-
-.. code-block:: objc
-
-   warning: method possibly missing a [super AnnotMeth] call
-   - (void) AnnotMeth{};
-                      ^
-
-Objective-C Method Families
----------------------------
-
-Many methods in Objective-C have conventional meanings determined by their
-selectors. It is sometimes useful to be able to mark a method as having a
-particular conventional meaning despite not having the right selector, or as
-not having the conventional meaning that its selector would suggest. For these
-use cases, we provide an attribute to specifically describe the "method family"
-that a method belongs to.
-
-**Usage**: ``__attribute__((objc_method_family(X)))``, where ``X`` is one of
-``none``, ``alloc``, ``copy``, ``init``, ``mutableCopy``, or ``new``.  This
-attribute can only be placed at the end of a method declaration:
-
-.. code-block:: objc
-
-  - (NSString *)initMyStringValue __attribute__((objc_method_family(none)));
-
-Users who do not wish to change the conventional meaning of a method, and who
-merely want to document its non-standard retain and release semantics, should
-use the :ref:`retaining behavior attributes <langext-objc-retain-release>`
-described below.
-
-Query for this feature with ``__has_attribute(objc_method_family)``.
-
 .. _langext-objc-retain-release:
 
 Objective-C retaining behavior attributes
@@ -1257,8 +1130,7 @@
 return values. However, there are exceptions, and so Clang provides attributes
 to allow these exceptions to be documented. This are used by ARC and the
 `static analyzer <http://clang-analyzer.llvm.org>`_ Some exceptions may be
-better described using the :ref:`objc_method_family
-<langext-objc_method_family>` attribute instead.
+better described using the ``objc_method_family`` attribute instead.
 
 **Usage**: The ``ns_returns_retained``, ``ns_returns_not_retained``,
 ``ns_returns_autoreleased``, ``cf_returns_retained``, and
@@ -1315,87 +1187,7 @@
 Query the presence of this new mangling with
 ``__has_feature(objc_protocol_qualifier_mangling)``.
 
-Function Overloading in C
-=========================
-
-Clang provides support for C++ function overloading in C.  Function overloading
-in C is introduced using the ``overloadable`` attribute.  For example, one
-might provide several overloaded versions of a ``tgsin`` function that invokes
-the appropriate standard function computing the sine of a value with ``float``,
-``double``, or ``long double`` precision:
-
-.. code-block:: c
-
-  #include <math.h>
-  float __attribute__((overloadable)) tgsin(float x) { return sinf(x); }
-  double __attribute__((overloadable)) tgsin(double x) { return sin(x); }
-  long double __attribute__((overloadable)) tgsin(long double x) { return sinl(x); }
-
-Given these declarations, one can call ``tgsin`` with a ``float`` value to
-receive a ``float`` result, with a ``double`` to receive a ``double`` result,
-etc.  Function overloading in C follows the rules of C++ function overloading
-to pick the best overload given the call arguments, with a few C-specific
-semantics:
-
-* Conversion from ``float`` or ``double`` to ``long double`` is ranked as a
-  floating-point promotion (per C99) rather than as a floating-point conversion
-  (as in C++).
-
-* A conversion from a pointer of type ``T*`` to a pointer of type ``U*`` is
-  considered a pointer conversion (with conversion rank) if ``T`` and ``U`` are
-  compatible types.
-
-* A conversion from type ``T`` to a value of type ``U`` is permitted if ``T``
-  and ``U`` are compatible types.  This conversion is given "conversion" rank.
-
-The declaration of ``overloadable`` functions is restricted to function
-declarations and definitions.  Most importantly, if any function with a given
-name is given the ``overloadable`` attribute, then all function declarations
-and definitions with that name (and in that scope) must have the
-``overloadable`` attribute.  This rule even applies to redeclarations of
-functions whose original declaration had the ``overloadable`` attribute, e.g.,
-
-.. code-block:: c
-
-  int f(int) __attribute__((overloadable));
-  float f(float); // error: declaration of "f" must have the "overloadable" attribute
-
-  int g(int) __attribute__((overloadable));
-  int g(int) { } // error: redeclaration of "g" must also have the "overloadable" attribute
-
-Functions marked ``overloadable`` must have prototypes.  Therefore, the
-following code is ill-formed:
-
-.. code-block:: c
-
-  int h() __attribute__((overloadable)); // error: h does not have a prototype
-
-However, ``overloadable`` functions are allowed to use a ellipsis even if there
-are no named parameters (as is permitted in C++).  This feature is particularly
-useful when combined with the ``unavailable`` attribute:
-
-.. code-block:: c++
-
-  void honeypot(...) __attribute__((overloadable, unavailable)); // calling me is an error
-
-Functions declared with the ``overloadable`` attribute have their names mangled
-according to the same rules as C++ function names.  For example, the three
-``tgsin`` functions in our motivating example get the mangled names
-``_Z5tgsinf``, ``_Z5tgsind``, and ``_Z5tgsine``, respectively.  There are two
-caveats to this use of name mangling:
-
-* Future versions of Clang may change the name mangling of functions overloaded
-  in C, so you should not depend on an specific mangling.  To be completely
-  safe, we strongly urge the use of ``static inline`` with ``overloadable``
-  functions.
-
-* The ``overloadable`` attribute has almost no meaning when used in C++,
-  because names will already be mangled and functions are already overloadable.
-  However, when an ``overloadable`` function occurs within an ``extern "C"``
-  linkage specification, it's name *will* be mangled in the same way as it
-  would in C.
-
-Query for this feature with ``__has_extension(attribute_overloadable)``.
+.. _langext-overloading:
 
 Initializer lists for complex numbers in C
 ==========================================
@@ -1654,6 +1446,24 @@
     return __builtin_addressof(value);
   }
 
+``__builtin_operator_new`` and ``__builtin_operator_delete``
+------------------------------------------------------------
+
+``__builtin_operator_new`` allocates memory just like a non-placement non-class
+*new-expression*. This is exactly like directly calling the normal
+non-placement ``::operator new``, except that it allows certain optimizations
+that the C++ standard does not permit for a direct function call to
+``::operator new`` (in particular, removing ``new`` / ``delete`` pairs and
+merging allocations).
+
+Likewise, ``__builtin_operator_delete`` deallocates memory just like a
+non-class *delete-expression*, and is exactly like directly calling the normal
+``::operator delete``, except that it permits optimizations. Only the unsized
+form of ``__builtin_operator_delete`` is currently available.
+
+These builtins are intended for use in the implementation of ``std::allocator``
+and other similar allocation libraries, and are only available in C++.
+
 Multiprecision Arithmetic Builtins
 ----------------------------------
 
@@ -1770,20 +1580,22 @@
 .. code-block:: c
 
   T __builtin_arm_ldrex(const volatile T *addr);
+  T __builtin_arm_ldaex(const volatile T *addr);
   int __builtin_arm_strex(T val, volatile T *addr);
+  int __builtin_arm_stlex(T val, volatile T *addr);
   void __builtin_arm_clrex(void);
 
 The types ``T`` currently supported are:
-* Integer types with width at most 64 bits.
+* Integer types with width at most 64 bits (or 128 bits on AArch64).
 * Floating-point types
 * Pointer types.
 
 Note that the compiler does not guarantee it will not insert stores which clear
-the exclusive monitor in between an ``ldrex`` and its paired ``strex``. In
-practice this is only usually a risk when the extra store is on the same cache
-line as the variable being modified and Clang will only insert stack stores on
-its own, so it is best not to use these operations on variables with automatic
-storage duration.
+the exclusive monitor in between an ``ldrex`` type operation and its paired
+``strex``. In practice this is only usually a risk when the extra store is on
+the same cache line as the variable being modified and Clang will only insert
+stack stores on its own, so it is best not to use these operations on variables
+with automatic storage duration.
 
 Also, loads and stores may be implicit in code written between the ``ldrex`` and
 ``strex``. Clang will not necessarily mitigate the effects of these either, so
@@ -1798,55 +1610,7 @@
 Clang's non-standard C++11 attributes live in the ``clang`` attribute
 namespace.
 
-The ``clang::fallthrough`` attribute
-------------------------------------
-
-The ``clang::fallthrough`` attribute is used along with the
-``-Wimplicit-fallthrough`` argument to annotate intentional fall-through
-between switch labels.  It can only be applied to a null statement placed at a
-point of execution between any statement and the next switch label.  It is
-common to mark these places with a specific comment, but this attribute is
-meant to replace comments with a more strict annotation, which can be checked
-by the compiler.  This attribute doesn't change semantics of the code and can
-be used wherever an intended fall-through occurs.  It is designed to mimic
-control-flow statements like ``break;``, so it can be placed in most places
-where ``break;`` can, but only if there are no statements on the execution path
-between it and the next switch label.
-
-Here is an example:
-
-.. code-block:: c++
-
-  // compile with -Wimplicit-fallthrough
-  switch (n) {
-  case 22:
-  case 33:  // no warning: no statements between case labels
-    f();
-  case 44:  // warning: unannotated fall-through
-    g();
-    [[clang::fallthrough]];
-  case 55:  // no warning
-    if (x) {
-      h();
-      break;
-    }
-    else {
-      i();
-      [[clang::fallthrough]];
-    }
-  case 66:  // no warning
-    p();
-    [[clang::fallthrough]]; // warning: fallthrough annotation does not
-                            //          directly precede case label
-    q();
-  case 77:  // warning: unannotated fall-through
-    r();
-  }
-
-``gnu::`` attributes
---------------------
-
-Clang also supports GCC's ``gnu`` attribute namespace. All GCC attributes which
+Clang supports GCC's ``gnu`` attribute namespace. All GCC attributes which
 are accepted with the ``__attribute__((foo))`` syntax are also accepted as
 ``[[gnu::foo]]``. This only extends to attributes which are specified by GCC
 (see the list of `GCC function attributes
@@ -1870,6 +1634,19 @@
 
 Clang supports some language features conditionally on some targets.
 
+ARM/AArch64 Language Extensions
+-------------------------------
+
+Memory Barrier Intrinsics
+^^^^^^^^^^^^^^^^^^^^^^^^^
+Clang implements the ``__dmb``, ``__dsb`` and ``__isb`` intrinsics as defined
+in the `ARM C Language Extensions Release 2.0
+<http://infocenter.arm.com/help/topic/com.arm.doc.ihi0053c/IHI0053C_acle_2_0.pdf>`_.
+Note that these intrinsics are implemented as motion barriers that block
+reordering of memory accesses and side effect instructions. Other instructions
+like simple arithmatic may be reordered around the intrinsic. If you expect to
+have no reordering at all, use inline assembly instead.
+
 X86/X86-64 Language Extensions
 ------------------------------
 
@@ -1902,48 +1679,6 @@
           movl    %gs:(%eax), %eax
           ret
 
-ARM Language Extensions
------------------------
-
-Interrupt attribute
-^^^^^^^^^^^^^^^^^^^
-
-Clang supports the GNU style ``__attribite__((interrupt("TYPE")))`` attribute on
-ARM targets. This attribute may be attached to a function definiton and
-instructs the backend to generate appropriate function entry/exit code so that
-it can be used directly as an interrupt service routine.
-
- The parameter passed to the interrupt attribute is optional, but if
-provided it must be a string literal with one of the following values: "IRQ",
-"FIQ", "SWI", "ABORT", "UNDEF".
-
-The semantics are as follows:
-
-- If the function is AAPCS, Clang instructs the backend to realign the stack to
-  8 bytes on entry. This is a general requirement of the AAPCS at public
-  interfaces, but may not hold when an exception is taken. Doing this allows
-  other AAPCS functions to be called.
-- If the CPU is M-class this is all that needs to be done since the architecture
-  itself is designed in such a way that functions obeying the normal AAPCS ABI
-  constraints are valid exception handlers.
-- If the CPU is not M-class, the prologue and epilogue are modified to save all
-  non-banked registers that are used, so that upon return the user-mode state
-  will not be corrupted. Note that to avoid unnecessary overhead, only
-  general-purpose (integer) registers are saved in this way. If VFP operations
-  are needed, that state must be saved manually.
-
-  Specifically, interrupt kinds other than "FIQ" will save all core registers
-  except "lr" and "sp". "FIQ" interrupts will save r0-r7.
-- If the CPU is not M-class, the return instruction is changed to one of the
-  canonical sequences permitted by the architecture for exception return. Where
-  possible the function itself will make the necessary "lr" adjustments so that
-  the "preferred return address" is selected.
-
-  Unfortunately the compiler is unable to make this guarantee for an "UNDEF"
-  handler, where the offset from "lr" to the preferred return address depends on
-  the execution state of the code which generated the exception. In this case
-  a sequence equivalent to "movs pc, lr" will be used.
-
 Extensions for Static Analysis
 ==============================
 
@@ -1957,450 +1692,156 @@
 Extensions for Dynamic Analysis
 ===============================
 
-.. _langext-address_sanitizer:
-
-AddressSanitizer
-----------------
-
 Use ``__has_feature(address_sanitizer)`` to check if the code is being built
 with :doc:`AddressSanitizer`.
 
-Use ``__attribute__((no_sanitize_address))``
-on a function declaration
-to specify that address safety instrumentation (e.g. AddressSanitizer) should
-not be applied to that function.
-
-.. _langext-thread_sanitizer:
-
-ThreadSanitizer
-----------------
-
 Use ``__has_feature(thread_sanitizer)`` to check if the code is being built
 with :doc:`ThreadSanitizer`.
 
-Use ``__attribute__((no_sanitize_thread))`` on a function declaration
-to specify that checks for data races on plain (non-atomic) memory accesses
-should not be inserted by ThreadSanitizer.
-The function is still instrumented by the tool to avoid false positives and
-provide meaningful stack traces.
-
-.. _langext-memory_sanitizer:
-
-MemorySanitizer
-----------------
 Use ``__has_feature(memory_sanitizer)`` to check if the code is being built
 with :doc:`MemorySanitizer`.
 
-Use ``__attribute__((no_sanitize_memory))`` on a function declaration
-to specify that checks for uninitialized memory should not be inserted 
-(e.g. by MemorySanitizer). The function may still be instrumented by the tool
-to avoid false positives in other places.
 
+Extensions for selectively disabling optimization
+=================================================
 
-Thread-Safety Annotation Checking
-=================================
+Clang provides a mechanism for selectively disabling optimizations in functions
+and methods.
 
-Clang supports additional attributes for checking basic locking policies in
-multithreaded programs.  Clang currently parses the following list of
-attributes, although **the implementation for these annotations is currently in
-development.** For more details, see the `GCC implementation
-<http://gcc.gnu.org/wiki/ThreadSafetyAnnotation>`_.
-
-``no_thread_safety_analysis``
------------------------------
-
-Use ``__attribute__((no_thread_safety_analysis))`` on a function declaration to
-specify that the thread safety analysis should not be run on that function.
-This attribute provides an escape hatch (e.g. for situations when it is
-difficult to annotate the locking policy).
-
-``lockable``
-------------
-
-Use ``__attribute__((lockable))`` on a class definition to specify that it has
-a lockable type (e.g. a Mutex class).  This annotation is primarily used to
-check consistency.
-
-``scoped_lockable``
--------------------
-
-Use ``__attribute__((scoped_lockable))`` on a class definition to specify that
-it has a "scoped" lockable type.  Objects of this type will acquire the lock
-upon construction and release it upon going out of scope.  This annotation is
-primarily used to check consistency.
-
-``guarded_var``
----------------
-
-Use ``__attribute__((guarded_var))`` on a variable declaration to specify that
-the variable must be accessed while holding some lock.
-
-``pt_guarded_var``
-------------------
-
-Use ``__attribute__((pt_guarded_var))`` on a pointer declaration to specify
-that the pointer must be dereferenced while holding some lock.
-
-``guarded_by(l)``
------------------
-
-Use ``__attribute__((guarded_by(l)))`` on a variable declaration to specify
-that the variable must be accessed while holding lock ``l``.
-
-``pt_guarded_by(l)``
---------------------
-
-Use ``__attribute__((pt_guarded_by(l)))`` on a pointer declaration to specify
-that the pointer must be dereferenced while holding lock ``l``.
-
-``acquired_before(...)``
-------------------------
-
-Use ``__attribute__((acquired_before(...)))`` on a declaration of a lockable
-variable to specify that the lock must be acquired before all attribute
-arguments.  Arguments must be lockable type, and there must be at least one
-argument.
-
-``acquired_after(...)``
------------------------
-
-Use ``__attribute__((acquired_after(...)))`` on a declaration of a lockable
-variable to specify that the lock must be acquired after all attribute
-arguments.  Arguments must be lockable type, and there must be at least one
-argument.
-
-``exclusive_lock_function(...)``
---------------------------------
-
-Use ``__attribute__((exclusive_lock_function(...)))`` on a function declaration
-to specify that the function acquires all listed locks exclusively.  This
-attribute takes zero or more arguments: either of lockable type or integers
-indexing into function parameters of lockable type.  If no arguments are given,
-the acquired lock is implicitly ``this`` of the enclosing object.
-
-``shared_lock_function(...)``
------------------------------
-
-Use ``__attribute__((shared_lock_function(...)))`` on a function declaration to
-specify that the function acquires all listed locks, although the locks may be
-shared (e.g. read locks).  This attribute takes zero or more arguments: either
-of lockable type or integers indexing into function parameters of lockable
-type.  If no arguments are given, the acquired lock is implicitly ``this`` of
-the enclosing object.
-
-``exclusive_trylock_function(...)``
------------------------------------
-
-Use ``__attribute__((exclusive_lock_function(...)))`` on a function declaration
-to specify that the function will try (without blocking) to acquire all listed
-locks exclusively.  This attribute takes one or more arguments.  The first
-argument is an integer or boolean value specifying the return value of a
-successful lock acquisition.  The remaining arugments are either of lockable
-type or integers indexing into function parameters of lockable type.  If only
-one argument is given, the acquired lock is implicitly ``this`` of the
-enclosing object.
-
-``shared_trylock_function(...)``
---------------------------------
-
-Use ``__attribute__((shared_lock_function(...)))`` on a function declaration to
-specify that the function will try (without blocking) to acquire all listed
-locks, although the locks may be shared (e.g. read locks).  This attribute
-takes one or more arguments.  The first argument is an integer or boolean value
-specifying the return value of a successful lock acquisition.  The remaining
-arugments are either of lockable type or integers indexing into function
-parameters of lockable type.  If only one argument is given, the acquired lock
-is implicitly ``this`` of the enclosing object.
-
-``unlock_function(...)``
-------------------------
-
-Use ``__attribute__((unlock_function(...)))`` on a function declaration to
-specify that the function release all listed locks.  This attribute takes zero
-or more arguments: either of lockable type or integers indexing into function
-parameters of lockable type.  If no arguments are given, the acquired lock is
-implicitly ``this`` of the enclosing object.
-
-``lock_returned(l)``
---------------------
-
-Use ``__attribute__((lock_returned(l)))`` on a function declaration to specify
-that the function returns lock ``l`` (``l`` must be of lockable type).  This
-annotation is used to aid in resolving lock expressions.
-
-``locks_excluded(...)``
------------------------
-
-Use ``__attribute__((locks_excluded(...)))`` on a function declaration to
-specify that the function must not be called with the listed locks.  Arguments
-must be lockable type, and there must be at least one argument.
-
-``exclusive_locks_required(...)``
----------------------------------
-
-Use ``__attribute__((exclusive_locks_required(...)))`` on a function
-declaration to specify that the function must be called while holding the
-listed exclusive locks.  Arguments must be lockable type, and there must be at
-least one argument.
-
-``shared_locks_required(...)``
-------------------------------
-
-Use ``__attribute__((shared_locks_required(...)))`` on a function declaration
-to specify that the function must be called while holding the listed shared
-locks.  Arguments must be lockable type, and there must be at least one
-argument.
-
-Consumed Annotation Checking
-============================
-
-Clang supports additional attributes for checking basic resource management
-properties, specifically for unique objects that have a single owning reference.
-The following attributes are currently supported, although **the implementation
-for these annotations is currently in development and are subject to change.**
-
-``consumable``
---------------
-
-Each class that uses any of the following annotations must first be marked
-using the consumable attribute.  Failure to do so will result in a warning.
-
-``set_typestate(new_state)``
-----------------------------
-
-Annotate methods that transition an object into a new state with
-``__attribute__((set_typestate(new_state)))``.  The new new state must be
-unconsumed, consumed, or unknown.
-
-``callable_when(...)``
-----------------------
-
-Use ``__attribute__((callable_when(...)))`` to indicate what states a method
-may be called in.  Valid states are unconsumed, consumed, or unknown.  Each
-argument to this attribute must be a quoted string.  E.g.:
-
-``__attribute__((callable_when("unconsumed", "unknown")))``
-
-``tests_typestate(tested_state)``
----------------------------------
-
-Use ``__attribute__((tests_typestate(tested_state)))`` to indicate that a method
-returns true if the object is in the specified state..
-
-``param_typestate(expected_state)``
------------------------------------
-
-This attribute specifies expectations about function parameters.  Calls to an
-function with annotated parameters will issue a warning if the corresponding
-argument isn't in the expected state.  The attribute is also used to set the
-initial state of the parameter when analyzing the function's body.
-
-``return_typestate(ret_state)``
--------------------------------
-
-The ``return_typestate`` attribute can be applied to functions or parameters.
-When applied to a function the attribute specifies the state of the returned
-value.  The function's body is checked to ensure that it always returns a value
-in the specified state.  On the caller side, values returned by the annotated
-function are initialized to the given state.
-
-If the attribute is applied to a function parameter it modifies the state of
-an argument after a call to the function returns.  The function's body is
-checked to ensure that the parameter is in the expected state before returning. 
-
-Type Safety Checking
-====================
-
-Clang supports additional attributes to enable checking type safety properties
-that can't be enforced by the C type system.  Use cases include:
-
-* MPI library implementations, where these attributes enable checking that
-  the buffer type matches the passed ``MPI_Datatype``;
-* for HDF5 library there is a similar use case to MPI;
-* checking types of variadic functions' arguments for functions like
-  ``fcntl()`` and ``ioctl()``.
-
-You can detect support for these attributes with ``__has_attribute()``.  For
-example:
+To disable optimizations in a single function definition, the GNU-style or C++11
+non-standard attribute ``optnone`` can be used.
 
 .. code-block:: c++
 
-  #if defined(__has_attribute)
-  #  if __has_attribute(argument_with_type_tag) && \
-        __has_attribute(pointer_with_type_tag) && \
-        __has_attribute(type_tag_for_datatype)
-  #    define ATTR_MPI_PWT(buffer_idx, type_idx) __attribute__((pointer_with_type_tag(mpi,buffer_idx,type_idx)))
-  /* ... other macros ...  */
-  #  endif
-  #endif
+  // The following functions will not be optimized.
+  // GNU-style attribute
+  __attribute__((optnone)) int foo() {
+    // ... code
+  }
+  // C++11 attribute
+  [[clang::optnone]] int bar() {
+    // ... code
+  }
 
-  #if !defined(ATTR_MPI_PWT)
-  # define ATTR_MPI_PWT(buffer_idx, type_idx)
-  #endif
+To facilitate disabling optimization for a range of function definitions, a
+range-based pragma is provided. Its syntax is ``#pragma clang optimize``
+followed by ``off`` or ``on``.
 
-  int MPI_Send(void *buf, int count, MPI_Datatype datatype /*, other args omitted */)
-      ATTR_MPI_PWT(1,3);
-
-``argument_with_type_tag(...)``
--------------------------------
-
-Use ``__attribute__((argument_with_type_tag(arg_kind, arg_idx,
-type_tag_idx)))`` on a function declaration to specify that the function
-accepts a type tag that determines the type of some other argument.
-``arg_kind`` is an identifier that should be used when annotating all
-applicable type tags.
-
-This attribute is primarily useful for checking arguments of variadic functions
-(``pointer_with_type_tag`` can be used in most non-variadic cases).
-
-For example:
+All function definitions in the region between an ``off`` and the following
+``on`` will be decorated with the ``optnone`` attribute unless doing so would
+conflict with explicit attributes already present on the function (e.g. the
+ones that control inlining).
 
 .. code-block:: c++
 
-  int fcntl(int fd, int cmd, ...)
-      __attribute__(( argument_with_type_tag(fcntl,3,2) ));
+  #pragma clang optimize off
+  // This function will be decorated with optnone.
+  int foo() {
+    // ... code
+  }
 
-``pointer_with_type_tag(...)``
-------------------------------
+  // optnone conflicts with always_inline, so bar() will not be decorated.
+  __attribute__((always_inline)) int bar() {
+    // ... code
+  }
+  #pragma clang optimize on
 
-Use ``__attribute__((pointer_with_type_tag(ptr_kind, ptr_idx, type_tag_idx)))``
-on a function declaration to specify that the function accepts a type tag that
-determines the pointee type of some other pointer argument.
+If no ``on`` is found to close an ``off`` region, the end of the region is the
+end of the compilation unit.
 
-For example:
+Note that a stray ``#pragma clang optimize on`` does not selectively enable
+additional optimizations when compiling at low optimization levels. This feature
+can only be used to selectively disable optimizations.
+
+The pragma has an effect on functions only at the point of their definition; for
+function templates, this means that the state of the pragma at the point of an
+instantiation is not necessarily relevant. Consider the following example:
 
 .. code-block:: c++
 
-  int MPI_Send(void *buf, int count, MPI_Datatype datatype /*, other args omitted */)
-      __attribute__(( pointer_with_type_tag(mpi,1,3) ));
+  template<typename T> T twice(T t) {
+    return 2 * t;
+  }
 
-``type_tag_for_datatype(...)``
-------------------------------
+  #pragma clang optimize off
+  template<typename T> T thrice(T t) {
+    return 3 * t;
+  }
 
-Clang supports annotating type tags of two forms.
+  int container(int a, int b) {
+    return twice(a) + thrice(b);
+  }
+  #pragma clang optimize on
 
-* **Type tag that is an expression containing a reference to some declared
-  identifier.** Use ``__attribute__((type_tag_for_datatype(kind, type)))`` on a
-  declaration with that identifier:
+In this example, the definition of the template function ``twice`` is outside
+the pragma region, whereas the definition of ``thrice`` is inside the region.
+The ``container`` function is also in the region and will not be optimized, but
+it causes the instantiation of ``twice`` and ``thrice`` with an ``int`` type; of
+these two instantiations, ``twice`` will be optimized (because its definition
+was outside the region) and ``thrice`` will not be optimized.
 
-  .. code-block:: c++
+.. _langext-pragma-loop:
 
-    extern struct mpi_datatype mpi_datatype_int
-        __attribute__(( type_tag_for_datatype(mpi,int) ));
-    #define MPI_INT ((MPI_Datatype) &mpi_datatype_int)
+Extensions for loop hint optimizations
+======================================
 
-* **Type tag that is an integral literal.** Introduce a ``static const``
-  variable with a corresponding initializer value and attach
-  ``__attribute__((type_tag_for_datatype(kind, type)))`` on that declaration,
-  for example:
+The ``#pragma clang loop`` directive is used to specify hints for optimizing the
+subsequent for, while, do-while, or c++11 range-based for loop. The directive
+provides options for vectorization and interleaving. Loop hints can be specified
+before any loop and will be ignored if the optimization is not safe to apply.
 
-  .. code-block:: c++
+A vectorized loop performs multiple iterations of the original loop
+in parallel using vector instructions. The instruction set of the target
+processor determines which vector instructions are available and their vector
+widths. This restricts the types of loops that can be vectorized. The vectorizer
+automatically determines if the loop is safe and profitable to vectorize. A
+vector instruction cost model is used to select the vector width.
 
-    #define MPI_INT ((MPI_Datatype) 42)
-    static const MPI_Datatype mpi_datatype_int
-        __attribute__(( type_tag_for_datatype(mpi,int) )) = 42
+Interleaving multiple loop iterations allows modern processors to further
+improve instruction-level parallelism (ILP) using advanced hardware features,
+such as multiple execution units and out-of-order execution. The vectorizer uses
+a cost model that depends on the register pressure and generated code size to
+select the interleaving count.
 
-The attribute also accepts an optional third argument that determines how the
-expression is compared to the type tag.  There are two supported flags:
+Vectorization is enabled by ``vectorize(enable)`` and interleaving is enabled
+by ``interleave(enable)``. This is useful when compiling with ``-Os`` to
+manually enable vectorization or interleaving.
 
-* ``layout_compatible`` will cause types to be compared according to
-  layout-compatibility rules (C++11 [class.mem] p 17, 18).  This is
-  implemented to support annotating types like ``MPI_DOUBLE_INT``.
+.. code-block:: c++
 
-  For example:
+  #pragma clang loop vectorize(enable)
+  #pragma clang loop interleave(enable)
+  for(...) {
+    ...
+  }
 
-  .. code-block:: c++
+The vector width is specified by ``vectorize_width(_value_)`` and the interleave
+count is specified by ``interleave_count(_value_)``, where
+_value_ is a positive integer. This is useful for specifying the optimal
+width/count of the set of target architectures supported by your application.
 
-    /* In mpi.h */
-    struct internal_mpi_double_int { double d; int i; };
-    extern struct mpi_datatype mpi_datatype_double_int
-        __attribute__(( type_tag_for_datatype(mpi, struct internal_mpi_double_int, layout_compatible) ));
+.. code-block:: c++
 
-    #define MPI_DOUBLE_INT ((MPI_Datatype) &mpi_datatype_double_int)
+  #pragma clang loop vectorize_width(2)
+  #pragma clang loop interleave_count(2)
+  for(...) {
+    ...
+  }
 
-    /* In user code */
-    struct my_pair { double a; int b; };
-    struct my_pair *buffer;
-    MPI_Send(buffer, 1, MPI_DOUBLE_INT /*, ...  */); // no warning
+Specifying a width/count of 1 disables the optimization, and is equivalent to
+``vectorize(disable)`` or ``interleave(disable)``.
 
-    struct my_int_pair { int a; int b; }
-    struct my_int_pair *buffer2;
-    MPI_Send(buffer2, 1, MPI_DOUBLE_INT /*, ...  */); // warning: actual buffer element
-                                                      // type 'struct my_int_pair'
-                                                      // doesn't match specified MPI_Datatype
+For convenience multiple loop hints can be specified on a single line.
 
-* ``must_be_null`` specifies that the expression should be a null pointer
-  constant, for example:
+.. code-block:: c++
 
-  .. code-block:: c++
+  #pragma clang loop vectorize_width(4) interleave_count(8)
+  for(...) {
+    ...
+  }
 
-    /* In mpi.h */
-    extern struct mpi_datatype mpi_datatype_null
-        __attribute__(( type_tag_for_datatype(mpi, void, must_be_null) ));
-
-    #define MPI_DATATYPE_NULL ((MPI_Datatype) &mpi_datatype_null)
-
-    /* In user code */
-    MPI_Send(buffer, 1, MPI_DATATYPE_NULL /*, ...  */); // warning: MPI_DATATYPE_NULL
-                                                        // was specified but buffer
-                                                        // is not a null pointer
-
-Format String Checking
-======================
-
-Clang supports the ``format`` attribute, which indicates that the function
-accepts a ``printf`` or ``scanf``-like format string and corresponding
-arguments or a ``va_list`` that contains these arguments.
-
-Please see `GCC documentation about format attribute
-<http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html>`_ to find details
-about attribute syntax.
-
-Clang implements two kinds of checks with this attribute.
-
-#. Clang checks that the function with the ``format`` attribute is called with
-   a format string that uses format specifiers that are allowed, and that
-   arguments match the format string.  This is the ``-Wformat`` warning, it is
-   on by default.
-
-#. Clang checks that the format string argument is a literal string.  This is
-   the ``-Wformat-nonliteral`` warning, it is off by default.
-
-   Clang implements this mostly the same way as GCC, but there is a difference
-   for functions that accept a ``va_list`` argument (for example, ``vprintf``).
-   GCC does not emit ``-Wformat-nonliteral`` warning for calls to such
-   fuctions.  Clang does not warn if the format string comes from a function
-   parameter, where the function is annotated with a compatible attribute,
-   otherwise it warns.  For example:
-
-   .. code-block:: c
-
-     __attribute__((__format__ (__scanf__, 1, 3)))
-     void foo(const char* s, char *buf, ...) {
-       va_list ap;
-       va_start(ap, buf);
-
-       vprintf(s, ap); // warning: format string is not a string literal
-     }
-
-   In this case we warn because ``s`` contains a format string for a
-   ``scanf``-like function, but it is passed to a ``printf``-like function.
-
-   If the attribute is removed, clang still warns, because the format string is
-   not a string literal.
-
-   Another example:
-
-   .. code-block:: c
-
-     __attribute__((__format__ (__printf__, 1, 3)))
-     void foo(const char* s, char *buf, ...) {
-       va_list ap;
-       va_start(ap, buf);
-
-       vprintf(s, ap); // warning
-     }
-
-   In this case Clang does not warn because the format string ``s`` and
-   the corresponding arguments are annotated.  If the arguments are
-   incorrect, the caller of ``foo`` will receive a warning.
+If an optimization cannot be applied any hints that apply to it will be ignored.
+For example, the hint ``vectorize_width(4)`` is ignored if the loop is not
+proven safe to vectorize. To identify and diagnose optimization issues use
+`-Rpass`, `-Rpass-missed`, and `-Rpass-analysis` command line options. See the
+user guide for details.
diff --git a/docs/LeakSanitizer.rst b/docs/LeakSanitizer.rst
index 09d02cf..b1071ef 100644
--- a/docs/LeakSanitizer.rst
+++ b/docs/LeakSanitizer.rst
@@ -8,21 +8,25 @@
 Introduction
 ============
 
-LeakSanitizer is a heap leak detector which is designed to be used on top of
-:doc:`AddressSanitizer` / :doc:`MemorySanitizer`, or as a standalone library.
-LeakSanitizer is a run-time tool which doesn't require compiler
-instrumentation.
+LeakSanitizer is a run-time memory leak detector. It can be combined with
+:doc:`AddressSanitizer` to get both memory error and leak detection.
+LeakSanitizer does not introduce any additional slowdown when used in this mode.
+The LeakSanitizer runtime can also be linked in separately to get leak detection
+only, at a minimal performance cost.
 
 Current status
 ==============
 
-LeakSanitizer is a work in progress, currently under development for
-x86\_64 Linux.
+LeakSanitizer is experimental and supported only on x86\_64 Linux.
+
+The combined mode has been tested on fairly large software projects. The
+stand-alone mode has received much less testing.
+
+There are plans to support LeakSanitizer in :doc:`MemorySanitizer` builds.
 
 More Information
 ================
 
-Design wiki:
-`https://code.google.com/p/address-sanitizer/wiki/LeakSanitizerDesignDocument
-<https://code.google.com/p/address-sanitizer/wiki/LeakSanitizerDesignDocument>`_
+`https://code.google.com/p/address-sanitizer/wiki/LeakSanitizer
+<https://code.google.com/p/address-sanitizer/wiki/LeakSanitizer>`_
 
diff --git a/docs/LibASTMatchersReference.html b/docs/LibASTMatchersReference.html
index 2c9b3aa..4988053 100644
--- a/docs/LibASTMatchersReference.html
+++ b/docs/LibASTMatchersReference.html
@@ -250,7 +250,7 @@
 <tr><td colspan="4" class="doc" id="methodDecl0"><pre>Matches method declarations.
 
 Example matches y
-  class X { void y() };
+  class X { void y(); };
 </pre></td></tr>
 
 
@@ -631,6 +631,15 @@
 </pre></td></tr>
 
 
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('exprWithCleanups0')"><a name="exprWithCleanups0Anchor">exprWithCleanups</a></td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1ExprWithCleanups.html">ExprWithCleanups</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="exprWithCleanups0"><pre>Matches expressions that introduce cleanups to be run at the end
+of the sub-expression's evaluation.
+
+Example matches std::string()
+  const std::string str = std::string();
+</pre></td></tr>
+
+
 <tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('floatLiteral0')"><a name="floatLiteral0Anchor">floatLiteral</a></td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1FloatingLiteral.html">FloatingLiteral</a>&gt;...</td></tr>
 <tr><td colspan="4" class="doc" id="floatLiteral0"><pre>Matches float literals of all sizes encodings, e.g.
 1.0, 1.0f, 1.0L and 1e10.
@@ -1311,7 +1320,7 @@
 </pre></td></tr>
 
 
-<tr><td>Matcher&lt;*&gt;</td><td class="name" onclick="toggle('unless0')"><a name="unless0Anchor">unless</a></td><td>Matcher&lt;*&gt;  InnerMatcher</td></tr>
+<tr><td>Matcher&lt;*&gt;</td><td class="name" onclick="toggle('unless0')"><a name="unless0Anchor">unless</a></td><td>Matcher&lt;*&gt;</td></tr>
 <tr><td colspan="4" class="doc" id="unless0"><pre>Matches if the provided matcher does not match.
 
 Example matches Y (matcher = recordDecl(unless(hasName("X"))))
@@ -1352,9 +1361,8 @@
 </pre></td></tr>
 
 
-<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructorDecl.html">CXXConstructorDecl</a>&gt;</td><td class="name" onclick="toggle('isImplicit0')"><a name="isImplicit0Anchor">isImplicit</a></td><td></td></tr>
-<tr><td colspan="4" class="doc" id="isImplicit0"><pre>Matches a constructor declaration that has been implicitly added
-by the compiler (eg. implicit defaultcopy constructors).
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>&gt;</td><td class="name" onclick="toggle('isListInitialization0')"><a name="isListInitialization0Anchor">isListInitialization</a></td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isListInitialization0"><pre>Matches a constructor call expression which uses list initialization.
 </pre></td></tr>
 
 
@@ -1422,6 +1430,18 @@
 </pre></td></tr>
 
 
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXMethodDecl.html">CXXMethodDecl</a>&gt;</td><td class="name" onclick="toggle('isPure0')"><a name="isPure0Anchor">isPure</a></td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isPure0"><pre>Matches if the given method declaration is pure.
+
+Given
+  class A {
+   public:
+    virtual void x() = 0;
+  };
+  matches A::x
+</pre></td></tr>
+
+
 <tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXMethodDecl.html">CXXMethodDecl</a>&gt;</td><td class="name" onclick="toggle('isVirtual0')"><a name="isVirtual0Anchor">isVirtual</a></td><td></td></tr>
 <tr><td colspan="4" class="doc" id="isVirtual0"><pre>Matches if the given method declaration is virtual.
 
@@ -1581,13 +1601,19 @@
 </pre></td></tr>
 
 
-<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('equalsNode0')"><a name="equalsNode0Anchor">equalsNode</a></td><td>Decl* Other</td></tr>
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('equalsNode0')"><a name="equalsNode0Anchor">equalsNode</a></td><td>Decl *Node</td></tr>
 <tr><td colspan="4" class="doc" id="equalsNode0"><pre>Matches if a node equals another node.
 
 Decl has pointer identity in the AST.
 </pre></td></tr>
 
 
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('isImplicit0')"><a name="isImplicit0Anchor">isImplicit</a></td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isImplicit0"><pre>Matches a declaration that has been implicitly added
+by the compiler (eg. implicit defaultcopy constructors).
+</pre></td></tr>
+
+
 <tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('isPrivate0')"><a name="isPrivate0Anchor">isPrivate</a></td><td></td></tr>
 <tr><td colspan="4" class="doc" id="isPrivate0"><pre>Matches private C++ declarations.
 
@@ -1874,7 +1900,7 @@
 </pre></td></tr>
 
 
-<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('equalsNode1')"><a name="equalsNode1Anchor">equalsNode</a></td><td>Stmt* Other</td></tr>
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('equalsNode1')"><a name="equalsNode1Anchor">equalsNode</a></td><td>Stmt *Node</td></tr>
 <tr><td colspan="4" class="doc" id="equalsNode1"><pre>Matches if a node equals another node.
 
 Stmt has pointer identity in the AST.
@@ -1940,6 +1966,31 @@
 </pre></td></tr>
 
 
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>&gt;</td><td class="name" onclick="toggle('hasGlobalStorage0')"><a name="hasGlobalStorage0Anchor">hasGlobalStorage</a></td><td></td></tr>
+<tr><td colspan="4" class="doc" id="hasGlobalStorage0"><pre>Matches a variable declaration that does not have local storage.
+
+Example matches y and z (matcher = varDecl(hasGlobalStorage())
+void f() {
+  int x;
+  static int y;
+}
+int z;
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>&gt;</td><td class="name" onclick="toggle('hasLocalStorage0')"><a name="hasLocalStorage0Anchor">hasLocalStorage</a></td><td></td></tr>
+<tr><td colspan="4" class="doc" id="hasLocalStorage0"><pre>Matches a variable declaration that has function scope and is a
+non-static local variable.
+
+Example matches x (matcher = varDecl(hasLocalStorage())
+void f() {
+  int x;
+  static int y;
+}
+int z;
+</pre></td></tr>
+
+
 <tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>&gt;</td><td class="name" onclick="toggle('isDefinition1')"><a name="isDefinition1Anchor">isDefinition</a></td><td></td></tr>
 <tr><td colspan="4" class="doc" id="isDefinition1"><pre>Matches if a declaration has a body attached.
 
@@ -2026,24 +2077,6 @@
 </pre></td></tr>
 
 
-<tr><td>Matcher&lt;*&gt;</td><td class="name" onclick="toggle('forEach0')"><a name="forEach0Anchor">forEach</a></td><td>Matcher&lt;*&gt;</td></tr>
-<tr><td colspan="4" class="doc" id="forEach0"><pre>Matches AST nodes that have child AST nodes that match the
-provided matcher.
-
-Example matches X, Y (matcher = recordDecl(forEach(recordDecl(hasName("X")))
-  class X {};  Matches X, because X::X is a class of name X inside X.
-  class Y { class X {}; };
-  class Z { class Y { class X {}; }; };  Does not match Z.
-
-ChildT must be an AST base type.
-
-As opposed to 'has', 'forEach' will cause a match for each result that
-matches instead of only on the first one.
-
-Usable as: Any Matcher
-</pre></td></tr>
-
-
 <tr><td>Matcher&lt;*&gt;</td><td class="name" onclick="toggle('forEachDescendant0')"><a name="forEachDescendant0Anchor">forEachDescendant</a></td><td>Matcher&lt;*&gt;</td></tr>
 <tr><td colspan="4" class="doc" id="forEachDescendant0"><pre>Matches AST nodes that have descendant AST nodes that match the
 provided matcher.
@@ -2068,17 +2101,20 @@
 </pre></td></tr>
 
 
-<tr><td>Matcher&lt;*&gt;</td><td class="name" onclick="toggle('has0')"><a name="has0Anchor">has</a></td><td>Matcher&lt;*&gt;</td></tr>
-<tr><td colspan="4" class="doc" id="has0"><pre>Matches AST nodes that have child AST nodes that match the
+<tr><td>Matcher&lt;*&gt;</td><td class="name" onclick="toggle('forEach0')"><a name="forEach0Anchor">forEach</a></td><td>Matcher&lt;*&gt;</td></tr>
+<tr><td colspan="4" class="doc" id="forEach0"><pre>Matches AST nodes that have child AST nodes that match the
 provided matcher.
 
-Example matches X, Y (matcher = recordDecl(has(recordDecl(hasName("X")))
+Example matches X, Y (matcher = recordDecl(forEach(recordDecl(hasName("X")))
   class X {};  Matches X, because X::X is a class of name X inside X.
   class Y { class X {}; };
   class Z { class Y { class X {}; }; };  Does not match Z.
 
 ChildT must be an AST base type.
 
+As opposed to 'has', 'forEach' will cause a match for each result that
+matches instead of only on the first one.
+
 Usable as: Any Matcher
 </pre></td></tr>
 
@@ -2112,6 +2148,21 @@
 </pre></td></tr>
 
 
+<tr><td>Matcher&lt;*&gt;</td><td class="name" onclick="toggle('has0')"><a name="has0Anchor">has</a></td><td>Matcher&lt;*&gt;</td></tr>
+<tr><td colspan="4" class="doc" id="has0"><pre>Matches AST nodes that have child AST nodes that match the
+provided matcher.
+
+Example matches X, Y (matcher = recordDecl(has(recordDecl(hasName("X")))
+  class X {};  Matches X, because X::X is a class of name X inside X.
+  class Y { class X {}; };
+  class Z { class Y { class X {}; }; };  Does not match Z.
+
+ChildT must be an AST base type.
+
+Usable as: Any Matcher
+</pre></td></tr>
+
+
 <tr><td>Matcher&lt;*&gt;</td><td class="name" onclick="toggle('hasParent0')"><a name="hasParent0Anchor">hasParent</a></td><td>Matcher&lt;*&gt;</td></tr>
 <tr><td colspan="4" class="doc" id="hasParent0"><pre>Matches AST nodes that have a parent that matches the provided
 matcher.
@@ -2313,8 +2364,6 @@
 
 Also usable as Matcher&lt;T&gt; for any T supporting the getDecl() member
 function. e.g. various subtypes of clang::Type and various expressions.
-FIXME: Add all node types for which this is matcher is usable due to
-getDecl().
 
 Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>&gt;,
   Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>&gt;,
@@ -2378,6 +2427,43 @@
 </pre></td></tr>
 
 
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXForRangeStmt.html">CXXForRangeStmt</a>&gt;</td><td class="name" onclick="toggle('hasBody3')"><a name="hasBody3Anchor">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="hasBody3"><pre>Matches a 'for', 'while', or 'do while' statement that has
+a given body.
+
+Given
+  for (;;) {}
+hasBody(compoundStmt())
+  matches 'for (;;) {}'
+with compoundStmt()
+  matching '{}'
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXForRangeStmt.html">CXXForRangeStmt</a>&gt;</td><td class="name" onclick="toggle('hasLoopVariable0')"><a name="hasLoopVariable0Anchor">hasLoopVariable</a></td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasLoopVariable0"><pre>Matches the initialization statement of a for loop.
+
+Example:
+    forStmt(hasLoopVariable(anything()))
+matches 'int x' in
+    for (int x : a) { }
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXForRangeStmt.html">CXXForRangeStmt</a>&gt;</td><td class="name" onclick="toggle('hasRangeInit0')"><a name="hasRangeInit0Anchor">hasRangeInit</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="hasRangeInit0"><pre>Matches the range initialization statement of a for loop.
+
+Example:
+    forStmt(hasRangeInit(anything()))
+matches 'a' in
+    for (int x : a) { }
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXMemberCallExpr.html">CXXMemberCallExpr</a>&gt;</td><td class="name" onclick="toggle('onImplicitObjectArgument0')"><a name="onImplicitObjectArgument0Anchor">onImplicitObjectArgument</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="onImplicitObjectArgument0"><pre></pre></td></tr>
+
+
 <tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXMemberCallExpr.html">CXXMemberCallExpr</a>&gt;</td><td class="name" onclick="toggle('on0')"><a name="on0Anchor">on</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="on0"><pre>Matches on the implicit object argument of a member call expression.
 
@@ -2389,15 +2475,17 @@
 </pre></td></tr>
 
 
-<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXMemberCallExpr.html">CXXMemberCallExpr</a>&gt;</td><td class="name" onclick="toggle('onImplicitObjectArgument0')"><a name="onImplicitObjectArgument0Anchor">onImplicitObjectArgument</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="onImplicitObjectArgument0"><pre></pre></td></tr>
-
-
 <tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXMemberCallExpr.html">CXXMemberCallExpr</a>&gt;</td><td class="name" onclick="toggle('thisPointerType1')"><a name="thisPointerType1Anchor">thisPointerType</a></td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt; InnerMatcher</td></tr>
 <tr><td colspan="4" class="doc" id="thisPointerType1"><pre>Overloaded to match the type's declaration.
 </pre></td></tr>
 
 
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXMemberCallExpr.html">CXXMemberCallExpr</a>&gt;</td><td class="name" onclick="toggle('thisPointerType0')"><a name="thisPointerType0Anchor">thisPointerType</a></td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="thisPointerType0"><pre>Matches if the expression's type either matches the specified
+matcher, or is a pointer to a type that matches the InnerMatcher.
+</pre></td></tr>
+
+
 <tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXMethodDecl.html">CXXMethodDecl</a>&gt;</td><td class="name" onclick="toggle('ofClass0')"><a name="ofClass0Anchor">ofClass</a></td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXRecordDecl.html">CXXRecordDecl</a>&gt; InnerMatcher</td></tr>
 <tr><td colspan="4" class="doc" id="ofClass0"><pre>Matches the class declaration that the given method declaration
 belongs to.
@@ -2466,6 +2554,24 @@
 </pre></td></tr>
 
 
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>&gt;</td><td class="name" onclick="toggle('callee0')"><a name="callee0Anchor">callee</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="callee0"><pre>Matches if the call expression's callee expression matches.
+
+Given
+  class Y { void x() { this-&gt;x(); x(); Y y; y.x(); } };
+  void f() { f(); }
+callExpr(callee(expr()))
+  matches this-&gt;x(), x(), y.x(), f()
+with callee(...)
+  matching this-&gt;x, x, y.x, f respectively
+
+Note: Callee cannot take the more general internal::Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt;
+because this introduces ambiguous overloads with calls to Callee taking a
+internal::Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;, as the matcher hierarchy is purely
+implemented in terms of implicit casts.
+</pre></td></tr>
+
+
 <tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>&gt;</td><td class="name" onclick="toggle('hasAnyArgument0')"><a name="hasAnyArgument0Anchor">hasAnyArgument</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="hasAnyArgument0"><pre>Matches any argument of a call expression or a constructor call
 expression.
@@ -2506,8 +2612,6 @@
 
 Also usable as Matcher&lt;T&gt; for any T supporting the getDecl() member
 function. e.g. various subtypes of clang::Type and various expressions.
-FIXME: Add all node types for which this is matcher is usable due to
-getDecl().
 
 Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>&gt;,
   Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>&gt;,
@@ -2647,8 +2751,6 @@
 
 Also usable as Matcher&lt;T&gt; for any T supporting the getDecl() member
 function. e.g. various subtypes of clang::Type and various expressions.
-FIXME: Add all node types for which this is matcher is usable due to
-getDecl().
 
 Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>&gt;,
   Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>&gt;,
@@ -2813,8 +2915,6 @@
 
 Also usable as Matcher&lt;T&gt; for any T supporting the getDecl() member
 function. e.g. various subtypes of clang::Type and various expressions.
-FIXME: Add all node types for which this is matcher is usable due to
-getDecl().
 
 Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>&gt;,
   Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>&gt;,
@@ -2852,6 +2952,17 @@
 </pre></td></tr>
 
 
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt;</td><td class="name" onclick="toggle('hasType0')"><a name="hasType0Anchor">hasType</a></td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasType0"><pre>Matches if the expression's or declaration's type matches a type
+matcher.
+
+Example matches x (matcher = expr(hasType(recordDecl(hasName("X")))))
+            and z (matcher = varDecl(hasType(recordDecl(hasName("X")))))
+ class X {};
+ void y(X &amp;x) { x; X z; }
+</pre></td></tr>
+
+
 <tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt;</td><td class="name" onclick="toggle('ignoringImpCasts0')"><a name="ignoringImpCasts0Anchor">ignoringImpCasts</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="ignoringImpCasts0"><pre>Matches expressions that match InnerMatcher after any implicit casts
 are stripped off.
@@ -3014,6 +3125,24 @@
 </pre></td></tr>
 
 
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1IfStmt.html">IfStmt</a>&gt;</td><td class="name" onclick="toggle('hasElse0')"><a name="hasElse0Anchor">hasElse</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="hasElse0"><pre>Matches the else-statement of an if statement.
+
+Examples matches the if statement
+  (matcher = ifStmt(hasElse(boolLiteral(equals(true)))))
+  if (false) false; else true;
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1IfStmt.html">IfStmt</a>&gt;</td><td class="name" onclick="toggle('hasThen0')"><a name="hasThen0Anchor">hasThen</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="hasThen0"><pre>Matches the then-statement of an if statement.
+
+Examples matches the if statement
+  (matcher = ifStmt(hasThen(boolLiteral(equals(true)))))
+  if (false) true; else false;
+</pre></td></tr>
+
+
 <tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1ImplicitCastExpr.html">ImplicitCastExpr</a>&gt;</td><td class="name" onclick="toggle('hasImplicitDestinationType0')"><a name="hasImplicitDestinationType0Anchor">hasImplicitDestinationType</a></td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt; InnerMatcher</td></tr>
 <tr><td colspan="4" class="doc" id="hasImplicitDestinationType0"><pre>Matches implicit casts whose destination type matches a given
 matcher.
@@ -3034,8 +3163,6 @@
 
 Also usable as Matcher&lt;T&gt; for any T supporting the getDecl() member
 function. e.g. various subtypes of clang::Type and various expressions.
-FIXME: Add all node types for which this is matcher is usable due to
-getDecl().
 
 Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>&gt;,
   Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>&gt;,
@@ -3058,8 +3185,6 @@
 
 Also usable as Matcher&lt;T&gt; for any T supporting the getDecl() member
 function. e.g. various subtypes of clang::Type and various expressions.
-FIXME: Add all node types for which this is matcher is usable due to
-getDecl().
 
 Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>&gt;,
   Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>&gt;,
@@ -3082,8 +3207,6 @@
 
 Also usable as Matcher&lt;T&gt; for any T supporting the getDecl() member
 function. e.g. various subtypes of clang::Type and various expressions.
-FIXME: Add all node types for which this is matcher is usable due to
-getDecl().
 
 Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>&gt;,
   Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>&gt;,
@@ -3165,12 +3288,6 @@
 </pre></td></tr>
 
 
-<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1NestedNameSpecifierLoc.html">NestedNameSpecifierLoc</a>&gt;</td><td class="name" onclick="toggle('loc1')"><a name="loc1Anchor">loc</a></td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1NestedNameSpecifier.html">NestedNameSpecifier</a>&gt;  InnerMatcher</td></tr>
-<tr><td colspan="4" class="doc" id="loc1"><pre>Matches NestedNameSpecifierLocs for which the given inner
-NestedNameSpecifier-matcher matches.
-</pre></td></tr>
-
-
 <tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1NestedNameSpecifierLoc.html">NestedNameSpecifierLoc</a>&gt;</td><td class="name" onclick="toggle('specifiesTypeLoc0')"><a name="specifiesTypeLoc0Anchor">specifiesTypeLoc</a></td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>&gt; InnerMatcher</td></tr>
 <tr><td colspan="4" class="doc" id="specifiesTypeLoc0"><pre>Matches nested name specifier locs that specify a type matching the
 given TypeLoc.
@@ -3290,8 +3407,6 @@
 
 Also usable as Matcher&lt;T&gt; for any T supporting the getDecl() member
 function. e.g. various subtypes of clang::Type and various expressions.
-FIXME: Add all node types for which this is matcher is usable due to
-getDecl().
 
 Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>&gt;,
   Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>&gt;,
@@ -3307,11 +3422,36 @@
 </pre></td></tr>
 
 
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt;</td><td class="name" onclick="toggle('pointsTo0')"><a name="pointsTo0Anchor">pointsTo</a></td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="pointsTo0"><pre>Matches if the matched type is a pointer type and the pointee type
+matches the specified matcher.
+
+Example matches y-&gt;x()
+    (matcher = callExpr(on(hasType(pointsTo(recordDecl(hasName("Y")))))))
+  class Y { public: void x(); };
+  void z() { Y *y; y-&gt;x(); }
+</pre></td></tr>
+
+
 <tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt;</td><td class="name" onclick="toggle('references1')"><a name="references1Anchor">references</a></td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt; InnerMatcher</td></tr>
 <tr><td colspan="4" class="doc" id="references1"><pre>Overloaded to match the referenced type's declaration.
 </pre></td></tr>
 
 
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt;</td><td class="name" onclick="toggle('references0')"><a name="references0Anchor">references</a></td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="references0"><pre>Matches if the matched type is a reference type and the referenced
+type matches the specified matcher.
+
+Example matches X &amp;x and const X &amp;y
+    (matcher = varDecl(hasType(references(recordDecl(hasName("X"))))))
+  class X {
+    void a(X b) {
+      X &amp;x = b;
+      const X &amp;y = b;
+  };
+</pre></td></tr>
+
+
 <tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1RecordType.html">RecordType</a>&gt;</td><td class="name" onclick="toggle('hasDeclaration5')"><a name="hasDeclaration5Anchor">hasDeclaration</a></td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;  InnerMatcher</td></tr>
 <tr><td colspan="4" class="doc" id="hasDeclaration5"><pre>Matches a node if the declaration associated with that node
 matches the given matcher.
@@ -3324,8 +3464,6 @@
 
 Also usable as Matcher&lt;T&gt; for any T supporting the getDecl() member
 function. e.g. various subtypes of clang::Type and various expressions.
-FIXME: Add all node types for which this is matcher is usable due to
-getDecl().
 
 Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>&gt;,
   Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>&gt;,
@@ -3405,8 +3543,6 @@
 
 Also usable as Matcher&lt;T&gt; for any T supporting the getDecl() member
 function. e.g. various subtypes of clang::Type and various expressions.
-FIXME: Add all node types for which this is matcher is usable due to
-getDecl().
 
 Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>&gt;,
   Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>&gt;,
@@ -3417,8 +3553,23 @@
 </pre></td></tr>
 
 
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>&gt;</td><td class="name" onclick="toggle('isExpr0')"><a name="isExpr0Anchor">isExpr</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="isExpr0"><pre>Matches a sugar TemplateArgument that refers to a certain expression.
+
+Given
+  template&lt;typename T&gt; struct A {};
+  struct B { B* next; };
+  A&lt;&amp;B::next&gt; a;
+templateSpecializationType(hasAnyTemplateArgument(
+  isExpr(hasDescendant(declRefExpr(to(fieldDecl(hasName("next"))))))))
+  matches the specialization A&lt;&amp;B::next&gt; with fieldDecl(...) matching
+    B::next
+</pre></td></tr>
+
+
 <tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>&gt;</td><td class="name" onclick="toggle('refersToDeclaration0')"><a name="refersToDeclaration0Anchor">refersToDeclaration</a></td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt; InnerMatcher</td></tr>
-<tr><td colspan="4" class="doc" id="refersToDeclaration0"><pre>Matches a TemplateArgument that refers to a certain declaration.
+<tr><td colspan="4" class="doc" id="refersToDeclaration0"><pre>Matches a canonical TemplateArgument that refers to a certain
+declaration.
 
 Given
   template&lt;typename T&gt; struct A {};
@@ -3444,6 +3595,20 @@
 </pre></td></tr>
 
 
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>&gt;</td><td class="name" onclick="toggle('hasAnyTemplateArgument1')"><a name="hasAnyTemplateArgument1Anchor">hasAnyTemplateArgument</a></td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasAnyTemplateArgument1"><pre>Matches classTemplateSpecializations that have at least one
+TemplateArgument matching the given InnerMatcher.
+
+Given
+  template&lt;typename T&gt; class A {};
+  template&lt;&gt; class A&lt;double&gt; {};
+  A&lt;int&gt; a;
+classTemplateSpecializationDecl(hasAnyTemplateArgument(
+    refersToType(asString("int"))))
+  matches the specialization A&lt;int&gt;
+</pre></td></tr>
+
+
 <tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>&gt;</td><td class="name" onclick="toggle('hasDeclaration3')"><a name="hasDeclaration3Anchor">hasDeclaration</a></td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;  InnerMatcher</td></tr>
 <tr><td colspan="4" class="doc" id="hasDeclaration3"><pre>Matches a node if the declaration associated with that node
 matches the given matcher.
@@ -3456,8 +3621,6 @@
 
 Also usable as Matcher&lt;T&gt; for any T supporting the getDecl() member
 function. e.g. various subtypes of clang::Type and various expressions.
-FIXME: Add all node types for which this is matcher is usable due to
-getDecl().
 
 Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>&gt;,
   Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>&gt;,
@@ -3468,6 +3631,20 @@
 </pre></td></tr>
 
 
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>&gt;</td><td class="name" onclick="toggle('hasTemplateArgument1')"><a name="hasTemplateArgument1Anchor">hasTemplateArgument</a></td><td>unsigned N, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasTemplateArgument1"><pre>Matches classTemplateSpecializations where the n'th TemplateArgument
+matches the given InnerMatcher.
+
+Given
+  template&lt;typename T, typename U&gt; class A {};
+  A&lt;bool, int&gt; b;
+  A&lt;int, bool&gt; c;
+classTemplateSpecializationDecl(hasTemplateArgument(
+    1, refersToType(asString("int"))))
+  matches the specialization A&lt;bool, int&gt;
+</pre></td></tr>
+
+
 <tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateTypeParmType.html">TemplateTypeParmType</a>&gt;</td><td class="name" onclick="toggle('hasDeclaration2')"><a name="hasDeclaration2Anchor">hasDeclaration</a></td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;  InnerMatcher</td></tr>
 <tr><td colspan="4" class="doc" id="hasDeclaration2"><pre>Matches a node if the declaration associated with that node
 matches the given matcher.
@@ -3480,8 +3657,6 @@
 
 Also usable as Matcher&lt;T&gt; for any T supporting the getDecl() member
 function. e.g. various subtypes of clang::Type and various expressions.
-FIXME: Add all node types for which this is matcher is usable due to
-getDecl().
 
 Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>&gt;,
   Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>&gt;,
@@ -3507,12 +3682,6 @@
 </pre></td></tr>
 
 
-<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>&gt;</td><td class="name" onclick="toggle('loc0')"><a name="loc0Anchor">loc</a></td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt;  InnerMatcher</td></tr>
-<tr><td colspan="4" class="doc" id="loc0"><pre>Matches TypeLocs for which the given inner
-QualType-matcher matches.
-</pre></td></tr>
-
-
 <tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>&gt;</td><td class="name" onclick="toggle('hasDeclaration1')"><a name="hasDeclaration1Anchor">hasDeclaration</a></td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;  InnerMatcher</td></tr>
 <tr><td colspan="4" class="doc" id="hasDeclaration1"><pre>Matches a node if the declaration associated with that node
 matches the given matcher.
@@ -3525,8 +3694,6 @@
 
 Also usable as Matcher&lt;T&gt; for any T supporting the getDecl() member
 function. e.g. various subtypes of clang::Type and various expressions.
-FIXME: Add all node types for which this is matcher is usable due to
-getDecl().
 
 Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>&gt;,
   Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>&gt;,
@@ -3567,8 +3734,6 @@
 
 Also usable as Matcher&lt;T&gt; for any T supporting the getDecl() member
 function. e.g. various subtypes of clang::Type and various expressions.
-FIXME: Add all node types for which this is matcher is usable due to
-getDecl().
 
 Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>&gt;,
   Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>&gt;,
@@ -3620,6 +3785,17 @@
 </pre></td></tr>
 
 
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1ValueDecl.html">ValueDecl</a>&gt;</td><td class="name" onclick="toggle('hasType1')"><a name="hasType1Anchor">hasType</a></td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasType1"><pre>Matches if the expression's or declaration's type matches a type
+matcher.
+
+Example matches x (matcher = expr(hasType(recordDecl(hasName("X")))))
+            and z (matcher = varDecl(hasType(recordDecl(hasName("X")))))
+ class X {};
+ void y(X &amp;x) { x; X z; }
+</pre></td></tr>
+
+
 <tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>&gt;</td><td class="name" onclick="toggle('hasInitializer0')"><a name="hasInitializer0Anchor">hasInitializer</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="hasInitializer0"><pre>Matches a variable declaration that has an initializer expression
 that matches the given matcher.
@@ -3665,6 +3841,18 @@
   if (true) {}
 </pre></td></tr>
 
+
+<tr><td>Matcher&lt;internal::BindableMatcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1NestedNameSpecifierLoc.html">NestedNameSpecifierLoc</a>&gt;&gt;</td><td class="name" onclick="toggle('loc1')"><a name="loc1Anchor">loc</a></td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1NestedNameSpecifier.html">NestedNameSpecifier</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="loc1"><pre>Matches NestedNameSpecifierLocs for which the given inner
+NestedNameSpecifier-matcher matches.
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt;internal::BindableMatcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>&gt;&gt;</td><td class="name" onclick="toggle('loc0')"><a name="loc0Anchor">loc</a></td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="loc0"><pre>Matches TypeLocs for which the given inner
+QualType-matcher matches.
+</pre></td></tr>
+
 <!--END_TRAVERSAL_MATCHERS -->
 </table>
 
diff --git a/docs/LibASTMatchersTutorial.rst b/docs/LibASTMatchersTutorial.rst
index 5bd62a1..1e88ec2 100644
--- a/docs/LibASTMatchersTutorial.rst
+++ b/docs/LibASTMatchersTutorial.rst
@@ -137,6 +137,10 @@
       using namespace clang::tooling;
       using namespace llvm;
 
+      // Apply a custom category to all command-line options so that they are the
+      // only ones displayed.
+      static llvm::cl::OptionCategory MyToolCategory("my-tool options");
+
       // CommonOptionsParser declares HelpMessage with a description of the common
       // command-line options related to the compilation database and input files.
       // It's nice to have this help message in all tools.
@@ -146,10 +150,10 @@
       static cl::extrahelp MoreHelp("\nMore help text...");
 
       int main(int argc, const char **argv) {
-        CommonOptionsParser OptionsParser(argc, argv);
+        CommonOptionsParser OptionsParser(argc, argv, MyToolCategory);
         ClangTool Tool(OptionsParser.getCompilations(),
                        OptionsParser.getSourcePathList());
-        return Tool.run(newFrontendActionFactory<clang::SyntaxOnlyAction>());
+        return Tool.run(newFrontendActionFactory<clang::SyntaxOnlyAction>().get());
       }
 
 And that's it! You can compile our new tool by running ninja from the
@@ -287,7 +291,7 @@
 .. code-block:: c++
 
       int main(int argc, const char **argv) {
-        CommonOptionsParser OptionsParser(argc, argv);
+        CommonOptionsParser OptionsParser(argc, argv, MyToolCategory);
         ClangTool Tool(OptionsParser.getCompilations(),
                        OptionsParser.getSourcePathList());
 
@@ -295,7 +299,7 @@
         MatchFinder Finder;
         Finder.addMatcher(LoopMatcher, &Printer);
 
-        return Tool.run(newFrontendActionFactory(&Finder));
+        return Tool.run(newFrontendActionFactory(&Finder).get());
       }
 
 Now, you should be able to recompile and run the code to discover for
diff --git a/docs/LibTooling.rst b/docs/LibTooling.rst
index a9c24c3..75ef6a0 100644
--- a/docs/LibTooling.rst
+++ b/docs/LibTooling.rst
@@ -60,13 +60,18 @@
 .. code-block:: c++
 
   #include "clang/Tooling/CommonOptionsParser.h"
+  #include "llvm/Support/CommandLine.h"
 
   using namespace clang::tooling;
 
+  // Apply a custom category to all command-line options so that they are the
+  // only ones displayed.
+  static llvm::cl::OptionCategory MyToolCategory("my-tool options");
+
   int main(int argc, const char **argv) {
     // CommonOptionsParser constructor will parse arguments and create a
     // CompilationDatabase.  In case of error it will terminate the program.
-    CommonOptionsParser OptionsParser(argc, argv);
+    CommonOptionsParser OptionsParser(argc, argv, MyToolCategory);
 
     // Use OptionsParser.getCompilations() and OptionsParser.getSourcePathList()
     // to retrieve CompilationDatabase and the list of input file paths.
@@ -94,13 +99,13 @@
   // on.  Thus, it takes a FrontendActionFactory as parameter.  To create a
   // FrontendActionFactory from a given FrontendAction type, we call
   // newFrontendActionFactory<clang::SyntaxOnlyAction>().
-  int result = Tool.run(newFrontendActionFactory<clang::SyntaxOnlyAction>());
+  int result = Tool.run(newFrontendActionFactory<clang::SyntaxOnlyAction>().get());
 
 Putting it together --- the first tool
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Now we combine the two previous steps into our first real tool.  This example
-tool is also checked into the clang tree at
+Now we combine the two previous steps into our first real tool.  A more advanced
+version of this example tool is also checked into the clang tree at
 ``tools/clang-check/ClangCheck.cpp``.
 
 .. code-block:: c++
@@ -115,6 +120,10 @@
   using namespace clang::tooling;
   using namespace llvm;
 
+  // Apply a custom category to all command-line options so that they are the
+  // only ones displayed.
+  static cl::OptionCategory MyToolCategory("my-tool options");
+
   // CommonOptionsParser declares HelpMessage with a description of the common
   // command-line options related to the compilation database and input files.
   // It's nice to have this help message in all tools.
@@ -124,10 +133,10 @@
   static cl::extrahelp MoreHelp("\nMore help text...");
 
   int main(int argc, const char **argv) {
-    CommonOptionsParser OptionsParser(argc, argv);
+    CommonOptionsParser OptionsParser(argc, argv, MyToolCategory);
     ClangTool Tool(OptionsParser.getCompilations(),
-    OptionsParser.getSourcePathList());
-    return Tool.run(newFrontendActionFactory<clang::SyntaxOnlyAction>());
+                   OptionsParser.getSourcePathList());
+    return Tool.run(newFrontendActionFactory<clang::SyntaxOnlyAction>().get());
   }
 
 Running the tool on some code
diff --git a/docs/MSVCCompatibility.rst b/docs/MSVCCompatibility.rst
new file mode 100644
index 0000000..32efb76
--- /dev/null
+++ b/docs/MSVCCompatibility.rst
@@ -0,0 +1,141 @@
+.. raw:: html
+
+  <style type="text/css">
+    .none { background-color: #FFCCCC }
+    .partial { background-color: #FFFF99 }
+    .good { background-color: #CCFF99 }
+  </style>
+
+.. role:: none
+.. role:: partial
+.. role:: good
+
+==================
+MSVC compatibility
+==================
+
+When Clang compiles C++ code for Windows, it attempts to be compatible with
+MSVC.  There are multiple dimensions to compatibility.
+
+First, Clang attempts to be ABI-compatible, meaning that Clang-compiled code
+should be able to link against MSVC-compiled code successfully.  However, C++
+ABIs are particularly large and complicated, and Clang's support for MSVC's C++
+ABI is a work in progress.  If you don't require MSVC ABI compatibility or don't
+want to use Microsoft's C and C++ runtimes, the mingw32 toolchain might be a
+better fit for your project.
+
+Second, Clang implements many MSVC language extensions, such as
+``__declspec(dllexport)`` and a handful of pragmas.  These are typically
+controlled by ``-fms-extensions``.
+
+Third, MSVC accepts some C++ code that Clang will typically diagnose as
+invalid.  When these constructs are present in widely included system headers,
+Clang attempts to recover and continue compiling the user's program.  Most
+parsing and semantic compatibility tweaks are controlled by
+``-fms-compatibility`` and ``-fdelayed-template-parsing``, and they are a work
+in progress.
+
+Finally, there is :ref:`clang-cl`, a driver program for clang that attempts to
+be compatible with MSVC's cl.exe.
+
+ABI features
+============
+
+The status of major ABI-impacting C++ features:
+
+* Record layout: :good:`Complete`.  We've tested this with a fuzzer and have
+  fixed all known bugs.
+
+* Class inheritance: :good:`Mostly complete`.  This covers all of the standard
+  OO features you would expect: virtual method inheritance, multiple
+  inheritance, and virtual inheritance.  Every so often we uncover a bug where
+  our tables are incompatible, but this is pretty well in hand.  This feature
+  has also been fuzz tested.
+
+* Name mangling: :good:`Ongoing`.  Every new C++ feature generally needs its own
+  mangling.  For example, member pointer template arguments have an interesting
+  and distinct mangling.  Fortunately, incorrect manglings usually do not result
+  in runtime errors.  Non-inline functions with incorrect manglings usually
+  result in link errors, which are relatively easy to diagnose.  Incorrect
+  manglings for inline functions and templates result in multiple copies in the
+  final image.  The C++ standard requires that those addresses be equal, but few
+  programs rely on this.
+
+* Member pointers: :good:`Mostly complete`.  Standard C++ member pointers are
+  fully implemented and should be ABI compatible.  Both `#pragma
+  pointers_to_members`_ and the `/vm`_ flags are supported. However, MSVC
+  supports an extension to allow creating a `pointer to a member of a virtual
+  base class`_.  Clang does not yet support this.
+
+.. _#pragma pointers_to_members:
+  http://msdn.microsoft.com/en-us/library/83cch5a6.aspx
+.. _/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 CodeView line tables into the
+  object file, similar to what MSVC emits when given the ``/Z7`` flag.
+  Microsoft's link.exe will read this information and use it to create a PDB,
+  enabling stack traces in all modern Windows debuggers.  Clang does not emit
+  any type info or description of variable layout.
+
+* RTTI: :good:`Complete`.  Generation of RTTI data structures has been
+  finished, along with support for the ``/GR`` flag.
+
+* Exceptions and SEH: :none:`Unstarted`.  Clang can parse both constructs, but
+  does not know how to emit compatible handlers.
+
+* Thread-safe initialization of local statics: :none:`Unstarted`.  We are ABI
+  compatible with MSVC 2013, which does not support thread-safe local statics.
+  MSVC "14" changed the ABI to make initialization of local statics thread safe,
+  and we have not yet implemented this.
+
+* Lambdas: :good:`Mostly complete`.  Clang is compatible with Microsoft's
+  implementation of lambdas except for providing overloads for conversion to
+  function pointer for different calling conventions.  However, Microsoft's
+  extension is non-conforming.
+
+Template instantiation and name lookup
+======================================
+
+MSVC allows many invalid constructs in class templates that Clang has
+historically rejected.  In order to parse widely distributed headers for
+libraries such as the Active Template Library (ATL) and Windows Runtime Library
+(WRL), some template rules have been relaxed or extended in Clang on Windows.
+
+The first major semantic difference is that MSVC appears to defer all parsing
+an analysis of inline method bodies in class templates until instantiation
+time.  By default on Windows, Clang attempts to follow suit.  This behavior is
+controlled by the ``-fdelayed-template-parsing`` flag.  While Clang delays
+parsing of method bodies, it still parses the bodies *before* template argument
+substitution, which is not what MSVC does.  The following compatibility tweaks
+are necessary to parse the the template in those cases.
+
+MSVC allows some name lookup into dependent base classes.  Even on other
+platforms, this has been a `frequently asked question`_ for Clang users.  A
+dependent base class is a base class that depends on the value of a template
+parameter.  Clang cannot see any of the names inside dependent bases while it
+is parsing your template, so the user is sometimes required to use the
+``typename`` keyword to assist the parser.  On Windows, Clang attempts to
+follow the normal lookup rules, but if lookup fails, it will assume that the
+user intended to find the name in a dependent base.  While parsing the
+following program, Clang will recover as if the user had written the
+commented-out code:
+
+.. _frequently asked question:
+  http://clang.llvm.org/compatibility.html#dep_lookup
+
+.. code-block:: c++
+
+  template <typename T>
+  struct Foo : T {
+    void f() {
+      /*typename*/ T::UnknownType x =  /*this->*/unknownMember;
+    }
+  };
+
+After recovery, Clang warns the user that this code is non-standard and issues
+a hint suggesting how to fix the problem.
+
+As of this writing, Clang is able to compile a simple ATL hello world
+application.  There are still issues parsing WRL headers for modern Windows 8
+apps, but they should be addressed soon.
diff --git a/docs/MemorySanitizer.rst b/docs/MemorySanitizer.rst
index 5fc7e74..9d6c22d 100644
--- a/docs/MemorySanitizer.rst
+++ b/docs/MemorySanitizer.rst
@@ -56,12 +56,10 @@
 
 .. code-block:: console
 
-    % ./a.out 2>log
-    % projects/compiler-rt/lib/asan/scripts/asan_symbolize.py / < log | c++filt
-    ==30106==  WARNING: MemorySanitizer: UMR (uninitialized-memory-read)
+    % ./a.out
+    WARNING: MemorySanitizer: use-of-uninitialized-value
         #0 0x7f45944b418a in main umr.cc:6
         #1 0x7f45938b676c in __libc_start_main libc-start.c:226
-    Exiting
 
 By default, MemorySanitizer exits on the first detected error.
 
@@ -101,6 +99,13 @@
 warnings will be suppressed and all values loaded from memory will be
 considered fully initialized.
 
+Report symbolization
+====================
+
+MemorySanitizer uses an external symbolizer to print files and line numbers in
+reports. Make sure that ``llvm-symbolizer`` binary is in ``PATH``,
+or set environment variable ``MSAN_SYMBOLIZER_PATH`` to point to it.
+
 Origin Tracking
 ===============
 
@@ -112,29 +117,59 @@
 .. code-block:: console
 
     % clang -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -g -O2 umr.cc
-    % ./a.out 2>log
-    % projects/compiler-rt/lib/asan/scripts/asan_symbolize.py / < log | c++filt
-    ==14425==  WARNING: MemorySanitizer: UMR (uninitialized-memory-read)
-    ==14425== WARNING: Trying to symbolize code, but external symbolizer is not initialized!
-        #0 0x7f8bdda3824b in main umr.cc:6
-        #1 0x7f8bdce3a76c in __libc_start_main libc-start.c:226
-      raw origin id: 2030043137
-      ORIGIN: heap allocation:
-        #0 0x7f8bdda4034b in operator new[](unsigned long) msan_new_delete.cc:39
-        #1 0x7f8bdda3814d in main umr.cc:4
-        #2 0x7f8bdce3a76c in __libc_start_main libc-start.c:226
-    Exiting
+    % ./a.out
+    WARNING: MemorySanitizer: use-of-uninitialized-value
+        #0 0x7f7893912f0b in main umr2.cc:6
+        #1 0x7f789249b76c in __libc_start_main libc-start.c:226
 
-Origin tracking has proved to be very useful for debugging UMR
+      Uninitialized value was created by a heap allocation
+        #0 0x7f7893901cbd in operator new[](unsigned long) msan_new_delete.cc:44
+        #1 0x7f7893912e06 in main umr2.cc:4
+
+Origin tracking has proved to be very useful for debugging MemorySanitizer
 reports. It slows down program execution by a factor of 1.5x-2x on top
 of the usual MemorySanitizer slowdown.
 
+MemorySanitizer can provide even more information with
+``-fsanitize-memory-track-origins=2`` flag. In this mode reports
+include information about intermediate stores the uninitialized value went
+through.
+
+.. code-block:: console
+
+    % cat umr2.cc
+    #include <stdio.h>
+
+    int main(int argc, char** argv) {
+      int* a = new int[10];
+      a[5] = 0;
+      volatile int b = a[argc];
+      if (b)
+        printf("xx\n");
+      return 0;
+    }
+
+    % clang -fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer -g -O2 umr2.cc
+    % ./a.out
+    WARNING: MemorySanitizer: use-of-uninitialized-value
+        #0 0x7f7893912f0b in main umr2.cc:7
+        #1 0x7f789249b76c in __libc_start_main libc-start.c:226
+
+      Uninitialized value was stored to memory at
+        #0 0x7f78938b5c25 in __msan_chain_origin msan.cc:484
+        #1 0x7f7893912ecd in main umr2.cc:6
+
+      Uninitialized value was created by a heap allocation
+        #0 0x7f7893901cbd in operator new[](unsigned long) msan_new_delete.cc:44
+        #1 0x7f7893912e06 in main umr2.cc:4
+
+
 Handling external code
 ============================
 
 MemorySanitizer requires that all program code is instrumented. This
 also includes any libraries that the program depends on, even libc.
-Failing to achieve this may result in false UMR reports.
+Failing to achieve this may result in false reports.
 
 Full MemorySanitizer instrumentation is very difficult to achieve. To
 make it easier, MemorySanitizer runtime library includes 70+
@@ -157,7 +192,7 @@
 
 MemorySanitizer is supported on
 
-* Linux x86\_64 (tested on Ubuntu 10.04 and 12.04);
+* Linux x86\_64 (tested on Ubuntu 12.04);
 
 Limitations
 ===========
diff --git a/docs/Modules.rst b/docs/Modules.rst
index 9fb4c77..ce1e717 100644
--- a/docs/Modules.rst
+++ b/docs/Modules.rst
@@ -144,7 +144,7 @@
 -----------
 The crucial link between modules and headers is described by a *module map*, which describes how a collection of existing headers maps on to the (logical) structure of a module. For example, one could imagine a module ``std`` covering the C standard library. Each of the C standard library headers (``<stdio.h>``, ``<stdlib.h>``, ``<math.h>``, etc.) would contribute to the ``std`` module, by placing their respective APIs into the corresponding submodule (``std.io``, ``std.lib``, ``std.math``, etc.). Having a list of the headers that are part of the ``std`` module allows the compiler to build the ``std`` module as a standalone entity, and having the mapping from header names to (sub)modules allows the automatic translation of ``#include`` directives to module imports.
 
-Module maps are specified as separate files (each named ``module.map``) alongside the headers they describe, which allows them to be added to existing software libraries without having to change the library headers themselves (in most cases [#]_). The actual `Module map language`_ is described in a later section.
+Module maps are specified as separate files (each named ``module.modulemap``) alongside the headers they describe, which allows them to be added to existing software libraries without having to change the library headers themselves (in most cases [#]_). The actual `Module map language`_ is described in a later section.
 
 .. note::
 
@@ -198,20 +198,63 @@
 ``-fmodule-map-file=<file>``
   Load the given module map file if a header from its directory or one of its subdirectories is loaded.
 
+``-fmodules-search-all``
+  If a symbol is not found, search modules referenced in the current module maps but not imported for symbols, so the error message can reference the module by name.  Note that if the global module index has not been built before, this might take some time as it needs to build all the modules.  Note that this option doesn't apply in module builds, to avoid the recursion.
+
+Module Semantics
+================
+
+Modules are modeled as if each submodule were a separate translation unit, and a module import makes names from the other translation unit visible. Each submodule starts with a new preprocessor state and an empty translation unit.
+
+.. note::
+
+  This behavior is currently only approximated when building a module. Entities within a submodule that has already been built are visible when building later submodules in that module. This can lead to fragile modules that depend on the build order used for the submodules of the module, and should not be relied upon.
+
+As an example, in C, this implies that if two structs are defined in different submodules with the same name, those two types are distinct types (but may be *compatible* types if their definitions match. In C++, two structs defined with the same name in different submodules are the *same* type, and must be equivalent under C++'s One Definition Rule.
+
+.. note::
+
+  Clang currently only performs minimal checking for violations of the One Definition Rule.
+
+Macros
+------
+
+The C and C++ preprocessor assumes that the input text is a single linear buffer, but with modules this is not the case. It is possible to import two modules that have conflicting definitions for a macro (or where one ``#define``\s a macro and the other ``#undef``\ines it). The rules for handling macro definitions in the presence of modules are as follows:
+
+* Each definition and undefinition of a macro is considered to be a distinct entity.
+* Such entities are *visible* if they are from the current submodule or translation unit, or if they were exported from a submodule that has been imported.
+* A ``#define X`` or ``#undef X`` directive *overrides* all definitions of ``X`` that are visible at the point of the directive.
+* A ``#define`` or ``#undef`` directive is *active* if it is visible and no visible directive overrides it.
+* A set of macro directives is *consistent* if it consists of only ``#undef`` directives, or if all ``#define`` directives in the set define the macro name to the same sequence of tokens (following the usual rules for macro redefinitions).
+* If a macro name is used and the set of active directives is not consistent, the program is ill-formed. Otherwise, the (unique) meaning of the macro name is used.
+
+For example, suppose:
+
+* ``<stdio.h>`` defines a macro ``getc`` (and exports its ``#define``)
+* ``<cstdio>`` imports the ``<stdio.h>`` module and undefines the macro (and exports its ``#undef``)
+  
+The ``#undef`` overrides the ``#define``, and a source file that imports both modules *in any order* will not see ``getc`` defined as a macro.
+
 Module Map Language
 ===================
 
 The module map language describes the mapping from header files to the
 logical structure of modules. To enable support for using a library as
-a module, one must write a ``module.map`` file for that library. The
-``module.map`` file is placed alongside the header files themselves,
+a module, one must write a ``module.modulemap`` file for that library. The
+``module.modulemap`` file is placed alongside the header files themselves,
 and is written in the module map language described below.
 
+.. note::
+    For compatibility with previous releases, if a module map file named
+    ``module.modulemap`` is not found, Clang will also search for a file named
+    ``module.map``. This behavior is deprecated and we plan to eventually
+    remove it.
+
 As an example, the module map file for the C standard library might look a bit like this:
 
 .. parsed-literal::
 
-  module std [system] {
+  module std [system] [extern_c] {
     module complex {
       header "complex.h"
       export *
@@ -285,13 +328,15 @@
 .. parsed-literal::
 
   Name.framework/
-    module.map                Module map for the framework
+    Modules/module.modulemap  Module map for the framework
     Headers/                  Subdirectory containing framework headers
     Frameworks/               Subdirectory containing embedded frameworks
     Resources/                Subdirectory containing additional resources
     Name                      Symbolic link to the shared library for the framework
 
-The ``system`` attribute specifies that the module is a system module. When a system module is rebuilt, all of the module's header will be considered system headers, which suppresses warnings. This is equivalent to placing ``#pragma GCC system_header`` in each of the module's headers. The form of attributes is described in the section Attributes_, below.
+The ``system`` attribute specifies that the module is a system module. When a system module is rebuilt, all of the module's headers will be considered system headers, which suppresses warnings. This is equivalent to placing ``#pragma GCC system_header`` in each of the module's headers. The form of attributes is described in the section Attributes_, below.
+
+The ``extern_c`` attribute specifies that the module contains C code that can be used from within C++. When such a module is built for use in C++ code, all of the module's headers will be treated as if they were contained within an implicit ``extern "C"`` block. An import for a module with this attribute can appear within an ``extern "C"`` block. No other restrictions are lifted, however: the module currently cannot be imported within an ``extern "C"`` block in a namespace.
 
 Modules can have a number of different kinds of members, each of which is described below:
 
@@ -573,7 +618,7 @@
     use B
   }
 
-When compiling a source file that implements a module, use the option ``-fmodule-name=``module-id to indicate that the source file is logically part of that module.
+When compiling a source file that implements a module, use the option ``-fmodule-name=module-id`` to indicate that the source file is logically part of that module.
 
 The compiler at present only applies restrictions to the module directly being built.
 
@@ -691,6 +736,63 @@
 
 Any *identifier* can be used as an attribute, and each declaration specifies what attributes can be applied to it.
 
+Private Module Map Files
+------------------------
+Module map files are typically named ``module.modulemap`` and live
+either alongside the headers they describe or in a parent directory of
+the headers they describe. These module maps typically describe all of
+the API for the library.
+
+However, in some cases, the presence or absence of particular headers
+is used to distinguish between the "public" and "private" APIs of a
+particular library. For example, a library may contain the headers
+``Foo.h`` and ``Foo_Private.h``, providing public and private APIs,
+respectively. Additionally, ``Foo_Private.h`` may only be available on
+some versions of library, and absent in others. One cannot easily
+express this with a single module map file in the library:
+
+.. parsed-literal::
+
+  module Foo {
+    header "Foo.h"
+    
+    explicit module Private {
+      header "Foo_Private.h"
+    }
+  }
+
+
+because the header ``Foo_Private.h`` won't always be available. The
+module map file could be customized based on whether
+``Foo_Private.h`` is available or not, but doing so requires custom
+build machinery.
+
+Private module map files, which are named ``module.private.modulemap``
+(or, for backward compatibility, ``module_private.map``), allow one to
+augment the primary module map file with an additional submodule. For
+example, we would split the module map file above into two module map
+files:
+
+.. code-block:: c
+
+  /* module.modulemap */
+  module Foo {
+    header "Foo.h"
+  }
+  
+  /* module.private.modulemap */
+  explicit module Foo.Private {
+    header "Foo_Private.h"
+  }
+
+
+When a ``module.private.modulemap`` file is found alongside a
+``module.modulemap`` file, it is loaded after the ``module.modulemap``
+file. In our example library, the ``module.private.modulemap`` file
+would be available when ``Foo_Private.h`` is available, making it
+easier to split a library's public and private APIs along header
+boundaries.
+
 Modularizing a Platform
 =======================
 To get any benefit out of modules, one needs to introduce module maps for software libraries starting at the bottom of the stack. This typically means introducing a module map covering the operating system's headers and the C standard library headers (in ``/usr/include``, for a Unix system). 
@@ -740,7 +842,7 @@
 =================================
 The Clang source code provides additional information about modules:
 
-``clang/lib/Headers/module.map``
+``clang/lib/Headers/module.modulemap``
   Module map for Clang's compiler-specific header files.
 
 ``clang/test/Modules/``
diff --git a/docs/ObjectiveCLiterals.rst b/docs/ObjectiveCLiterals.rst
index 8066d8f..8907c1e 100644
--- a/docs/ObjectiveCLiterals.rst
+++ b/docs/ObjectiveCLiterals.rst
@@ -91,7 +91,7 @@
 and ``YES`` and ``NO`` were macros that expand to ``(BOOL)1`` and
 ``(BOOL)0`` respectively. To support ``@YES`` and ``@NO`` expressions,
 these macros are now defined using new language keywords in
-``&LT;objc/objc.h&GT;``:
+``<objc/objc.h>``:
 
 .. code-block:: objc
 
@@ -251,7 +251,7 @@
 sub-expressions of a dictionary literal must be Objective-C object
 pointer typed, as in array literals. Key sub-expressions must be of an
 Objective-C object pointer type that implements the
-``&LT;NSCopying&GT;`` protocol.
+``<NSCopying>`` protocol.
 
 Discussion
 ----------
diff --git a/docs/PTHInternals.rst b/docs/PTHInternals.rst
index 10dda61..7401cf9 100644
--- a/docs/PTHInternals.rst
+++ b/docs/PTHInternals.rst
@@ -135,11 +135,11 @@
 an algorithmic level, especially when one considers header files of
 arbitrary size.
 
-There are plans to potentially implement an complementary PCH
-implementation for Clang based on the lazy deserialization of ASTs. This
-approach would theoretically have the same constant-time algorithmic
-advantages just mentioned but would also retain some of the strengths of
-PTH such as reduced memory pressure (ideal for multi-core builds).
+There is also a PCH implementation for Clang based on the lazy
+deserialization of ASTs. This approach theoretically has the same
+constant-time algorithmic advantages just mentioned but also retains some
+of the strengths of PTH such as reduced memory pressure (ideal for
+multi-core builds).
 
 Internal PTH Optimizations
 --------------------------
diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst
index 597d481..5ff136e 100644
--- a/docs/ReleaseNotes.rst
+++ b/docs/ReleaseNotes.rst
@@ -1,6 +1,6 @@
-=====================================
-Clang 3.4 (In-Progress) Release Notes
-=====================================
+=======================
+Clang 3.5 Release Notes
+=======================
 
 .. contents::
    :local:
@@ -8,17 +8,11 @@
 
 Written by the `LLVM Team <http://llvm.org/>`_
 
-.. warning::
-
-   These are in-progress notes for the upcoming Clang 3.4 release. You may
-   prefer the `Clang 3.3 Release Notes
-   <http://llvm.org/releases/3.3/tools/clang/docs/ReleaseNotes.html>`_.
-
 Introduction
 ============
 
 This document contains the release notes for the Clang C/C++/Objective-C
-frontend, part of the LLVM Compiler Infrastructure, release 3.4. Here we
+frontend, part of the LLVM Compiler Infrastructure, release 3.5. 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 +30,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 3.4?
+What's New in Clang 3.5?
 ========================
 
 Some of the major new features and improvements to Clang are listed
@@ -44,128 +38,216 @@
 infrastructure are described first, followed by language-specific
 sections with improvements to Clang's support for those languages.
 
-Last release which will build as C++98
---------------------------------------
-
-This is expected to be the last release of Clang which compiles using a C++98
-toolchain. We expect to start using some C++11 features in Clang starting after
-this release. That said, we are committed to supporting a reasonable set of
-modern C++ toolchains as the host compiler on all of the platforms. This will
-at least include Visual Studio 2012 on Windows, and Clang 3.1 or GCC 4.7.x on
-Mac and Linux. The final set of compilers (and the C++11 features they support)
-is not set in stone, but we wanted users of Clang to have a heads up that the
-next release will involve a substantial change in the host toolchain
-requirements.
-
-Note that this change is part of a change for the entire LLVM project, not just
-Clang.
-
 Major New Features
 ------------------
 
+- Clang uses the new MingW ABI
+  GCC 4.7 changed the mingw ABI. Clang 3.4 and older use the GCC 4.6
+  ABI. Clang 3.5 and newer use the GCC 4.7 abi.
+
+- The __has_attribute feature test is now target-aware. Older versions of Clang
+  would return true when the attribute spelling was known, regardless of whether
+  the attribute was available to the specific target. Clang now returns true
+  only when the attribute pertains to the current compilation target.
+  
+- Clang 3.5 now has parsing and semantic-analysis support for all OpenMP 3.1
+  pragmas (except atomics and ordered). LLVM's OpenMP runtime library,
+  originally developed by Intel, has been modified to work on ARM, PowerPC,
+  as well as X86. Code generation support is minimal at this point and will
+  continue to be developed for 3.6, along with the rest of OpenMP 3.1.
+  Support for OpenMP 4.0 features, such as SIMD and target accelerator
+  directives, is also in progress. Contributors to this work include AMD,
+  Argonne National Lab., IBM, Intel, Texas Instruments, University of Houston
+  and many others.
+
 Improvements to Clang's diagnostics
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Clang's diagnostics are constantly being improved to catch more issues,
 explain them more clearly, and provide more accurate source information
-about them. The improvements since the 3.3 release include:
+about them. The improvements since the 3.4 release include:
+
+- GCC compatibility: Clang displays a warning on unsupported gcc
+  optimization flags instead of an error.
+
+- Remarks system: Clang supports `-R` flags for enabling remarks. These are
+  diagnostic messages that provide information about the compilation process,
+  but don't suggest that a problem has been detected. As such, they cannot
+  be upgraded to errors with `-Werror` or `-Rerror`. A `-Reverything` flag
+  is provided (paralleling `-Weverything`) to turn on all remarks.
+
+- New remark `-Rpass`: Clang provides information about decisions made by
+  optimization passes during compilation. See :ref:`opt_rpass`.
+
+- New warning `-Wabsolute-value`: Clang warns about incorrect or useless usage
+  of the absolute functions (`abs`, `fabsf`, etc).
+
+  .. code-block:: c
+
+    #include <stdlib.h>
+    void foo() {
+     unsigned int i=0;
+     abs(i);
+    }
+
+  returns
+  `warning: taking the absolute value of unsigned type 'unsigned int' has no effect [-Wabsolute-value]`
+
+  or
+
+  .. code-block:: c
+
+    #include <stdlib.h>
+    void plop() {
+      long long i=0;
+      abs(i);
+    }
+
+  returns
+  `warning: absolute value function 'abs' given an argument of type 'long long' but has parameter of type 'int' which may cause truncation of value [-Wabsolute-value] use function 'llabs' instead`
+
+- New warning `-Wtautological-pointer-compare`:
+
+  .. code-block:: c++
+
+    #include <stddef.h>
+    void foo() {
+     int arr[5];
+     int x;
+     // warn on these conditionals
+     if (foo);
+     if (arr);
+     if (&x);
+     if (foo == NULL);
+     if (arr == NULL);
+     if (&x == NULL);
+    }
+
+  returns
+  `warning: comparison of address of 'x' equal to a null pointer is always false [-Wtautological-pointer-compare]`
+
+- New warning `-Wtautological-undefined-compare`: 
+
+  .. code-block:: c++
+
+    #include <stddef.h>
+    void f(int &x) {
+       if (&x == nullptr) { }
+    }
+
+  returns
+  `warning: reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false [-Wtautological-undefined-compare]`
 
 -  ...
 
 New Compiler Flags
 ------------------
 
-- Clang no longer special cases -O4 to enable lto. Explicitly pass -flto to
-  enable it.
-- Clang no longer fails on >= -O5. Uses -O3 instead.
-- Command line "clang -O3 -flto a.c -c" and "clang -emit-llvm a.c -c"
-  are no longer equivalent.
-- Clang now errors on unknown -m flags (``-munknown-to-clang``),
-  unknown -f flags (``-funknown-to-clang``) and unknown
-  options (``-what-is-this``).
+The integrated assembler is now turned on by default on ARM (and Thumb),
+so the use of the option `-fintegrated-as` is now redundant on those
+architectures. This is an important move to both *eat our own dog food*
+and to ease cross-compilation tremendously.
 
-C Language Changes in Clang
----------------------------
+We are aware of the problems that this may cause for code bases that
+rely on specific GNU syntax or extensions, and we're working towards
+getting them all fixed. Please, report bugs or feature requests if
+you find anything. In the meantime, use `-fno-integrated-as` to revert
+back the call to GNU assembler.
 
-- Added new checked arithmetic builtins for security critical applications.
+In order to provide better diagnostics, the integrated assembler validates
+inline assembly when the integrated assembler is enabled.  Because this is
+considered a feature of the compiler, it is controlled via the `fintegrated-as`
+and `fno-integrated-as` flags which enable and disable the integrated assembler
+respectively.  `-integrated-as` and `-no-integrated-as` are now considered
+legacy flags (but are available as an alias to prevent breaking existing users),
+and users are encouraged to switch to the equivalent new feature flag.
 
-C11 Feature Support
-^^^^^^^^^^^^^^^^^^^
+Deprecated flags `-faddress-sanitizer`, `-fthread-sanitizer`,
+`-fcatch-undefined-behavior` and `-fbounds-checking` were removed in favor of
+`-fsanitize=` family of flags.
 
-...
+It is now possible to get optimization reports from the major transformation
+passes via three new flags: `-Rpass`, `-Rpass-missed` and `-Rpass-analysis`.
+These flags take a POSIX regular expression which indicates the name
+of the pass (or passes) that should emit optimization remarks.
+
+Options `-u` and `-z` are forwarded to the linker on gnutools toolchains.
+
+
+New Pragmas in Clang
+-----------------------
+
+Loop optimization hints can be specified using the new `#pragma clang loop`
+directive just prior to the desired loop. The directive allows vectorization and
+interleaving to be enabled or disabled. Vector width as well as interleave count
+can be manually specified.  See :ref:`langext-pragma-loop` for details.
 
 C++ Language Changes in Clang
 -----------------------------
 
-- Fixed an ABI regression, introduced in Clang 3.2, which affected
-  member offsets for classes inheriting from certain classes with tail padding.
-  See PR16537.
+- Reference parameters and return values from functions are more aggressively
+  assumed to refer to valid objects when optimizing. Clang will attempt to
+  issue a warning by default if it sees null checks being performed on
+  references, and `-fsanitize=null` can be used to detect null references
+  being formed at runtime.
 
-- ...
-
-C++11 Feature Support
+C++17 Feature Support
 ^^^^^^^^^^^^^^^^^^^^^
 
-...
+Clang has experimental support for some proposed C++1z (tentatively, C++17)
+features. This support can be enabled using the `-std=c++1z` flag. The
+supported features are:
 
-Objective-C Language Changes in Clang
--------------------------------------
+- `static_assert(expr)` with no message
 
-...
+- `for (identifier : range)` as a synonym for `for (auto &&identifier : range)`
 
-OpenCL C Language Changes in Clang
-----------------------------------
+- `template<template<...> typename>` as a synonym for `template<template<...> class>`
 
-- OpenCL C "long" now always has a size of 64 bit, and all OpenCL C
-  types are aligned as specified in the OpenCL C standard. Also,
-  "char" is now always signed.
+Additionally, trigraphs are not recognized by default in this mode.
+`-ftrigraphs` can be used if you need to parse legacy code that uses trigraphs.
+Note that these features may be changed or removed in future Clang releases
+without notice.
+
+OpenMP C/C++ Language Changes in Clang
+--------------------------------------
+
+- `Status of supported OpenMP constructs 
+  <https://github.com/clang-omp/clang/wiki/Status-of-supported-OpenMP-constructs>`_.
+
 
 Internal API Changes
 --------------------
 
-These are major API changes that have happened since the 3.3 release of
+These are major API changes that have happened since the 3.4 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.
 
-Wide Character Types
-^^^^^^^^^^^^^^^^^^^^
-
-The ASTContext class now keeps track of two different types for wide character
-types: WCharTy and WideCharTy. WCharTy represents the built-in wchar_t type
-available in C++. WideCharTy is the type used for wide character literals; in
-C++ it is the same as WCharTy, but in C99, where wchar_t is a typedef, it is an
-integer type.
-
-...
-
-libclang
---------
-
-...
+- Clang uses `std::unique_ptr<T>` in many places where it used to use
+  raw `T *` pointers.
 
 Static Analyzer
 ---------------
 
-The static analyzer (which contains additional code checking beyond compiler
-warnings) has improved significantly in both in the core analysis engine and 
-also in the kinds of issues it can find.
+Check for code testing a variable for 0 after using it as a denominator.
+This new checker, alpha.core.TestAfterDivZero, catches issues like this:
 
-Core Analysis Improvements
-==========================
+.. code-block:: c
 
-- ...
+  int sum = ...
+  int avg = sum / count; // potential division by zero...
+  if (count == 0) { ... } // ...caught here
 
-New Issues Found
-================
 
-- ...
+The `-analyzer-config` options are now passed from scan-build through to
+ccc-analyzer and then to Clang.
 
-Python Binding Changes
-----------------------
+With the option `-analyzer-config stable-report-filename=true`,
+instead of `report-XXXXXX.html`, scan-build/clang analyzer generate
+`report-<filename>-<function, method name>-<function position>-<id>.html`.
+(id = i++ for several issues found in the same function/method).
 
-The following methods have been added:
-
--  ...
+List the function/method name in the index page of scan-build.
 
 Significant Known Problems
 ==========================
diff --git a/docs/SanitizerSpecialCaseList.rst b/docs/SanitizerSpecialCaseList.rst
index 8f4727c..a4165b2 100644
--- a/docs/SanitizerSpecialCaseList.rst
+++ b/docs/SanitizerSpecialCaseList.rst
@@ -24,7 +24,7 @@
   thread stack, bypassing the frame boundaries);
 * ignore a known problem.
 
-To achieve this, user may create a file listing the entities he wants to
+To achieve this, user may create a file listing the entities they want to
 ignore, and pass it to clang at compile-time using
 ``-fsanitize-blacklist`` flag. See :doc:`UsersManual` for details.
 
diff --git a/docs/ThreadSafetyAnalysis.rst b/docs/ThreadSafetyAnalysis.rst
new file mode 100644
index 0000000..dfef80b
--- /dev/null
+++ b/docs/ThreadSafetyAnalysis.rst
@@ -0,0 +1,818 @@
+
+======================
+Thread Safety Analysis
+======================
+
+Introduction
+============
+
+Clang Thread Safety Analysis is a C++ language extension which warns about
+potential race conditions in code.  The analysis is completely static (i.e.
+compile-time); there is no run-time overhead.  The analysis is still
+under active development, but it is mature enough to be deployed in an
+industrial setting.  It being developed by Google, and is used extensively
+on their internal code base.
+
+Thread safety analysis works very much like a type system for multi-threaded
+programs.  In addition to declaring the *type* of data (e.g. ``int``, ``float``,
+etc.), the programmer can (optionally) declare how access to that data is
+controlled in a multi-threaded environment.  For example, if ``foo`` is
+*guarded by* the mutex ``mu``, then the analysis will issue a warning whenever
+a piece of code reads or writes to ``foo`` without first locking ``mu``.
+Similarly, if there are particular routines that should only be called by
+the GUI thread, then the analysis will warn if other threads call those
+routines. 
+
+Getting Started
+----------------
+
+.. code-block:: c++
+
+  #include "mutex.h"
+
+  class BankAccount {
+  private:
+    Mutex mu;
+    int   balance GUARDED_BY(mu);
+  
+    void depositImpl(int amount) {
+      balance += amount;       // WARNING! Cannot write balance without locking mu.
+    }
+  
+    void withdrawImpl(int amount) EXCLUSIVE_LOCKS_REQUIRED(mu) {
+      balance -= amount;       // OK. Caller must have locked mu.
+    }
+  
+  public:
+    void withdraw(int amount) {
+      mu.Lock();
+      withdrawImpl(amount);    // OK.  We've locked mu.
+    }                          // WARNING!  Failed to unlock mu.
+  
+    void transferFrom(BankAccount& b, int amount) {
+      mu.Lock();
+      b.withdrawImpl(amount);  // WARNING!  Calling withdrawImpl() requires locking b.mu.
+      depositImpl(amount);     // OK.  depositImpl() has no requirements.
+      mu.Unlock();
+    }
+  };
+
+This example demonstrates the basic concepts behind the analysis.  The
+``GUARDED_BY`` attribute declares that a thread must lock ``mu`` before it can
+read or write to ``balance``, thus ensuring that the increment and decrement
+operations are atomic.  Similarly, ``EXCLUSIVE_LOCKS_REQUIRED`` declares that
+the calling thread must lock ``mu`` before calling ``withdrawImpl``.
+Because the caller is assumed to have locked ``mu``, it is safe to modify
+``balance`` within the body of the method.
+
+The ``depositImpl()`` method does not have ``EXCLUSIVE_LOCKS_REQUIRED``, so the
+analysis issues a warning.  Thread safety analysis is not inter-procedural, so
+caller requirements must be explicitly declared.
+There is also a warning in ``transferFrom()``, because although the method
+locks ``this->mu``, it does not lock ``b.mu``.  The analysis understands
+that these are two separate mutexes, in two different objects.  
+
+Finally, there is a warning in the ``withdraw()`` method, because it fails to
+unlock ``mu``.  Every lock must have a corresponding unlock, and the analysis
+will detect both double locks, and double unlocks.  A function is allowed to
+acquire a lock without releasing it, (or vice versa), but it must be annotated
+as such (using ``LOCK``/``UNLOCK_FUNCTION``).
+
+
+Running The Analysis
+--------------------
+
+To run the analysis, simply compile with the ``-Wthread-safety`` flag, e.g.
+
+.. code-block:: bash
+
+  clang -c -Wthread-safety example.cpp
+
+Note that this example assumes the presence of a suitably annotated
+:ref:`mutexheader` that declares which methods perform locking,
+unlocking, and so on. 
+
+
+Basic Concepts: Capabilities
+============================
+
+Thread safety analysis provides a way of protecting *resources* with
+*capabilities*.  A resource is either a data member, or a function/method
+that provides access to some underlying resource.  The analysis ensures that
+the calling thread cannot access the *resource* (i.e. call the function, or
+read/write the data) unless it has the *capability* to do so.
+
+Capabilities are associated with named C++ objects which declare specific
+methods to acquire and release the capability.  The name of the object serves
+to identify the capability.  The most common example is a mutex.  For example,
+if ``mu`` is a mutex, then calling ``mu.Lock()`` causes the calling thread
+to acquire the capability to access data that is protected by ``mu``. Similarly, 
+calling ``mu.Unlock()`` releases that capability.
+
+A thread may hold a capability either *exclusively* or *shared*.  An exclusive
+capability can be held by only one thread at a time, while a shared capability
+can be held by many threads at the same time.  This mechanism enforces a
+multiple-reader, single-writer pattern.  Write operations to protected data
+require exclusive access, while read operations require only shared access.  
+
+At any given moment during program execution, a thread holds a specific set of
+capabilities (e.g. the set of mutexes that it has locked.)  These act like keys
+or tokens that allow the thread to access a given resource.  Just like physical
+security keys, a thread cannot make copy of a capability, nor can it destroy
+one.  A thread can only release a capability to another thread, or acquire one
+from another thread.  The annotations are deliberately agnostic about the
+exact mechanism used to acquire and release capabilities; it assumes that the 
+underlying implementation (e.g. the Mutex implementation) does the handoff in
+an appropriate manner.
+
+The set of capabilities that are actually held by a given thread at a given
+point in program execution is a run-time concept.  The static analysis works
+by calculating an approximation of that set, called the *capability
+environment*.  The capability environment is calculated for every program point,
+and describes the set of capabilities that are statically known to be held, or
+not held, at that particular point.  This environment is a conservative
+approximation of the full set of capabilities that will actually held by a
+thread at run-time.
+
+
+Reference Guide
+===============
+
+The thread safety analysis uses attributes to declare threading constraints.
+Attributes must be attached to named declarations, such as classes, methods,
+and data members. Users are *strongly advised* to define macros for the various
+attributes; example definitions can be found in :ref:`mutexheader`, below.
+The following documentation assumes the use of macros.
+
+
+GUARDED_BY(c) and PT_GUARDED_BY(c)
+----------------------------------
+
+``GUARDED_BY`` is an attribute on data members, which declares that the data
+member is protected by the given capability.  Read operations on the data
+require shared access, while write operations require exclusive access.
+
+``PT_GUARDED_BY`` is similar, but is intended for use on pointers and smart
+pointers. There is no constraint on the data member itself, but the *data that
+it points to* is protected by the given capability.  
+
+.. code-block:: c++
+
+  Mutex mu;
+  int *p1            GUARDED_BY(mu);
+  int *p2            PT_GUARDED_BY(mu);
+  unique_ptr<int> p3 PT_GUARDED_BY(mu);
+  
+  void test() {
+    p1 = 0;             // Warning!
+  
+    p2 = new int;       // OK.
+    *p2 = 42;           // Warning!
+  
+    p3.reset(new int);  // OK.
+    *p3 = 42;           // Warning!
+  }
+
+
+EXCLUSIVE_LOCKS_REQUIRED(...), SHARED_LOCKS_REQUIRED(...)
+---------------------------------------------------------
+
+``EXCLUSIVE_LOCKS_REQUIRED`` is an attribute on functions or methods, which
+declares that the calling thread must have exclusive access to the given
+capabilities.  More than one capability may be specified.  The capabilities
+must be held on entry to the function, *and must still be held on exit*.  
+
+``SHARED_LOCKS_REQUIRED`` is similar, but requires only shared access.
+
+.. code-block:: c++
+
+  Mutex mu1, mu2;
+  int a GUARDED_BY(mu1);
+  int b GUARDED_BY(mu2);
+  
+  void foo() EXCLUSIVE_LOCKS_REQUIRED(mu1, mu2) {
+    a = 0;
+    b = 0;
+  }
+  
+  void test() {
+    mu1.Lock();
+    foo();         // Warning!  Requires mu2.
+    mu1.Unlock();
+  }
+
+
+EXCLUSIVE_LOCK_FUNCTION(...), SHARED_LOCK_FUNCTION(...), UNLOCK_FUNCTION(...)
+-----------------------------------------------------------------------------
+
+``EXCLUSIVE_LOCK_FUNCTION`` is an attribute on functions or methods, which
+declares that the function acquires a capability, but does not release it.  The
+caller must not hold the given capability on entry, and it will hold the
+capability on exit.  ``SHARED_LOCK_FUNCTION`` is similar. 
+
+``UNLOCK_FUNCTION`` declares that the function releases the given capability.
+The caller must hold the capability on entry, and will no longer hold it on
+exit. It does not matter whether the given capability is shared or exclusive.
+
+.. code-block:: c++
+
+  Mutex mu;
+  MyClass myObject GUARDED_BY(mu);
+  
+  void lockAndInit() EXCLUSIVE_LOCK_FUNCTION(mu) {
+    mu.Lock();
+    myObject.init();
+  }
+  
+  void cleanupAndUnlock() UNLOCK_FUNCTION(mu) {
+    myObject.cleanup();
+  }  // Warning!  Need to unlock mu.
+  
+  void test() {
+    lockAndInit();
+    myObject.doSomething();
+    cleanupAndUnlock();
+    myObject.doSomething();  // Warning, mu is not locked.
+  }
+
+If no argument is passed to ``(UN)LOCK_FUNCTION``, then the argument is assumed
+to be ``this``, and the analysis will not check the body of the function.  This
+pattern is intended for use by classes which hide locking details behind an
+abstract interface.  E.g.
+
+.. code-block:: c++
+
+  template <class T>
+  class LOCKABLE Container {
+  private:
+    Mutex mu;
+    T* data;
+  
+  public:
+    // Hide mu from public interface.
+    void Lock() EXCLUSIVE_LOCK_FUNCTION() { mu.Lock(); }
+    void Unlock() UNLOCK_FUNCTION() { mu.Unlock(); }
+  
+    T& getElem(int i) { return data[i]; }
+  };
+  
+  void test() {
+    Container<int> c;
+    c.Lock();
+    int i = c.getElem(0);
+    c.Unlock();
+  }
+
+
+LOCKS_EXCLUDED(...)
+-------------------
+
+``LOCKS_EXCLUDED`` is an attribute on functions or methods, which declares that
+the caller must *not* hold the given capabilities.  This annotation is
+used to prevent deadlock.  Many mutex implementations are not re-entrant, so
+deadlock can occur if the function in question acquires the mutex a second time.
+
+.. code-block:: c++
+
+  Mutex mu;
+  int a GUARDED_BY(mu);
+  
+  void clear() LOCKS_EXCLUDED(mu) {
+    mu.Lock();
+    a = 0;
+    mu.Unlock();
+  }
+  
+  void reset() {
+    mu.Lock();
+    clear();     // Warning!  Caller cannot hold 'mu'.
+    mu.Unlock();
+  }
+
+Unlike ``LOCKS_REQUIRED``, ``LOCKS_EXCLUDED`` is optional.  The analysis will
+not issue a warning if the attribute is missing.  See :ref:`limitations`.
+
+
+NO_THREAD_SAFETY_ANALYSIS
+-------------------------
+
+``NO_THREAD_SAFETY_ANALYSIS`` is an attribute on functions or methods, which
+turns off thread safety checking for that method.  It provides an escape hatch
+for functions which are either (1) deliberately thread-unsafe, or (2) are
+thread-safe, but too complicated for the analysis to understand.  Reasons for
+(2) will be described in the :ref:`limitations`, below.
+
+.. code-block:: c++
+
+  class Counter {
+    Mutex mu;
+    int a GUARDED_BY(mu);
+  
+    void unsafeIncrement() NO_THREAD_SAFETY_ANALYSIS { a++; }
+  };
+
+
+LOCK_RETURNED(c)
+----------------
+
+``LOCK_RETURNED`` is an attribute on functions or methods, which declares that
+the function returns a reference to the given capability.  It is used to
+annotate getter methods that return mutexes.
+
+.. code-block:: c++
+
+  class MyClass {
+  private:
+    Mutex mu;
+    int a GUARDED_BY(mu);
+  
+  public:
+    Mutex* getMu() LOCK_RETURNED(mu) { return &mu; }
+  
+    // analysis knows that getMu() == mu
+    void clear() EXCLUSIVE_LOCKS_REQUIRED(getMu()) { a = 0; }
+  };
+
+
+ACQUIRED_BEFORE(...), ACQUIRED_AFTER(...)
+-----------------------------------------
+
+``ACQUIRED_BEFORE`` and ``ACQUIRED_AFTER`` are attributes on member
+declarations, specifically declarations of mutexes or other capabilities.
+These declarations enforce a particular order in which the mutexes must be
+acquired, in order to prevent deadlock.
+
+.. code-block:: c++
+
+  Mutex m1;
+  Mutex m2 ACQUIRED_AFTER(m1);
+  
+  // Alternative declaration
+  // Mutex m2;
+  // Mutex m1 ACQUIRED_BEFORE(m2);
+  
+  void foo() {
+    m2.Lock();
+    m1.Lock();  // Warning!  m2 must be acquired after m1.
+    m1.Unlock();
+    m2.Unlock();
+  }
+
+
+LOCKABLE
+--------
+
+``LOCKABLE`` is an attribute on classes, which specifies that objects of the
+class can be used as a capability.  See the ``Container`` example given above,
+or the ``Mutex`` class in :ref:`mutexheader`.
+
+
+SCOPED_LOCKABLE
+---------------
+
+``SCOPED_LOCKABLE`` is an attribute on classes that implement RAII-style
+locking, in which a capability is acquired in the constructor, and released in
+the destructor.  Such classes require special handling because the constructor
+and destructor refer to the capability via different names; see the
+``MutexLocker`` class in :ref:`mutexheader`, below.
+
+
+EXCLUSIVE_TRYLOCK_FUNCTION(<bool>, ...), SHARED_TRYLOCK_FUNCTION(<bool>, ...)
+-----------------------------------------------------------------------------
+
+These are attributes on a function or method that tries to acquire the given
+capability, and returns a boolean value indicating success or failure.
+The first argument must be ``true`` or ``false``, to specify which return value
+indicates success, and the remaining arguments are interpreted in the same way
+as ``(UN)LOCK_FUNCTION``.  See :ref:`mutexheader`, below, for example uses.
+
+
+ASSERT_EXCLUSIVE_LOCK(...) and ASSERT_SHARED_LOCK(...)
+------------------------------------------------------
+
+These are attributes on a function or method that does a run-time test to see
+whether the calling thread holds the given capability.  The function is assumed
+to fail (no return) if the capability is not held.  See :ref:`mutexheader`,
+below, for example uses.
+
+
+GUARDED_VAR and PT_GUARDED_VAR
+------------------------------
+
+Use of these attributes has been deprecated.
+
+
+Warning flags
+-------------
+
+* ``-Wthread-safety``:  Umbrella flag which turns on the following three:
+
+  + ``-Wthread-safety-attributes``: Sanity checks on attribute syntax.
+  + ``-Wthread-safety-analysis``: The core analysis.
+  + ``-Wthread-safety-precise``: Requires that mutex expressions match precisely.
+    This warning can be disabled for code which has a lot of aliases.
+
+When new features and checks are added to the analysis, they can often introduce
+additional warnings.  Those warnings are initially released as *beta* warnings
+for a period of time, after which they are migrated to the standard analysis.  
+
+* ``-Wthread-safety-beta``:  New features.  Off by default. 
+
+
+.. _faq:
+
+Frequently Asked Questions
+==========================
+
+(Q) Should I put attributes in the header file, or in the .cc/.cpp/.cxx file?
+
+(A) Attributes should always go in the header.
+
+
+(Q) "*Mutex is not locked on every path through here?*"  What does that mean?
+
+(A) See :ref:`conditional_locks`, below.
+
+
+.. _limitations:
+
+Known Limitations 
+=================
+
+Lexical scope
+-------------
+
+Thread safety attributes contain ordinary C++ expressions, and thus follow
+ordinary C++ scoping rules.  In particular, this means that mutexes and other
+capabilities must be declared before they can be used in an attribute.
+Use-before-declaration is okay within a single class, because attributes are
+parsed at the same time as method bodies. (C++ delays parsing of method bodies
+until the end of the class.)  However, use-before-declaration is not allowed
+between classes, as illustrated below.  
+
+.. code-block:: c++
+
+  class Foo;
+
+  class Bar {
+    void bar(Foo* f) EXCLUSIVE_LOCKS_REQUIRED(f->mu);  // Error: mu undeclared.
+  };
+
+  class Foo {
+    Mutex mu;
+  };
+
+
+Private Mutexes
+---------------
+
+Good software engineering practice dictates that mutexes should be private
+members, because the locking mechanism used by a thread-safe class is part of
+its internal implementation.  However, private mutexes can sometimes leak into
+the public interface of a class.
+Thread safety attributes follow normal C++ access restrictions, so if ``mu``
+is a private member of ``c``, then it is an error to write ``c.mu`` in an
+attribute.
+
+One workround is to (ab)use the ``LOCK_RETURNED`` attribute to provide a public
+*name* for a private mutex, without actually exposing the underlying mutex.
+For example:
+
+.. code-block:: c++
+
+  class MyClass {
+  private:
+    Mutex mu;
+
+  public:
+    // For thread safety analysis only.  Does not actually return mu.
+    Mutex* getMu() LOCK_RETURNED(mu) { return 0; }
+
+    void doSomething() EXCLUSIVE_LOCKS_REQUIRED(mu); 
+  };
+
+  void doSomethingTwice(MyClass& c) EXCLUSIVE_LOCKS_REQUIRED(c.getMu()) {
+    // The analysis thinks that c.getMu() == c.mu
+    c.doSomething();
+    c.doSomething();
+  }
+
+In the above example, ``doSomethingTwice()`` is an external routine that
+requires ``c.mu`` to be locked, which cannot be declared directly because ``mu``
+is private.  This pattern is discouraged because it
+violates encapsulation, but it is sometimes necessary, especially when adding
+annotations to an existing code base.  The workaround is to define ``getMu()``
+as a fake getter method, which is provided only for the benefit of thread
+safety analysis.
+
+
+False negatives on pass by reference.
+-------------------------------------
+
+The current version of the analysis only checks operations which refer to
+guarded data members directly by name.  If the data members are accessed
+indirectly, via a pointer or reference, then no warning is generated.  Thus,
+no warnings will be generated for the following code:
+
+.. code-block:: c++
+
+  Mutex mu;
+  int a GUARDED_BY(mu);
+
+  void clear(int& ra) { ra = 0; }
+
+  void test() {
+    int *p = &a;
+    *p = 0;       // No warning.  *p is an alias to a.  
+       
+    clear(a);     // No warning.  'a' is passed by reference.
+  }
+
+This issue is by far the biggest source of false negatives in the current
+version of the analysis.  At a fundamental level, the
+false negatives are caused by the fact that annotations are attached to data
+members, rather than types.  The type of ``&a`` should really be
+``int GUARDED_BY(mu)*``, rather than ``int*``, and the statement ``p = &a``
+should thus generate a type error.  However, attaching attributes to types
+would be an invasive change to the C++ type system, with potential
+ramifications with respect to template instantation, function overloading,
+and so on.  Thus, a complete solution to this issue is simply not feasible.
+
+Future versions of the analysis will include better support for pointer
+alias analysis, along with limited checking of guarded types, in order to
+reduce the number of false negatives.
+
+
+.. _conditional_locks:
+
+No conditionally held locks.
+----------------------------
+
+The analysis must be able to determine whether a lock is held, or not held, at
+every program point.  Thus, sections of code where a lock *might be held* will
+generate spurious warnings (false positives).  For example:
+
+.. code-block:: c++
+
+  void foo() {
+    bool b = needsToLock();
+    if (b) mu.Lock();
+    ...  // Warning!  Mutex 'mu' is not held on every path through here. 
+    if (b) mu.Unlock();
+  }
+
+
+No checking inside constructors and destructors.
+------------------------------------------------
+
+The analysis currently does not do any checking inside constructors or
+destructors.  In other words, every constructor and destructor is treated as
+if it was annotated with ``NO_THREAD_SAFETY_ANALYSIS``.  
+The reason for this is that during initialization, only one thread typically
+has access to the object which is being initialized, and it is thus safe (and
+common practice) to initialize guarded members without acquiring any locks.
+The same is true of destructors.
+
+Ideally, the analysis would allow initialization of guarded members inside the
+object being initialized or destroyed, while still enforcing the usual access
+restrictions on everything else.  However, this is difficult to enforce in
+practice, because in complex pointer-based data structures, it is hard to
+determine what data is "owned by" the enclosing object.
+
+No inlining.
+------------
+
+Thread safety analysis is strictly intra-procedural, just like ordinary type
+checking.  It relies only on the declared attributes of a function, and will
+not attempt to "step inside", or inline any method calls.  As a result, code
+such as the following will not work:
+
+.. code-block:: c++
+
+  template<class T>
+  class AutoCleanup {
+    T* object;
+    void (T::*mp)();
+    
+  public:
+    AutoCleanup(T* obj, void (T::*imp)()) : object(obj), mp(imp) { }
+    ~AutoCleanup() { (object->*mp)(); }
+  };
+
+  Mutex mu;
+  void foo() {
+    mu.Lock();
+    AutoCleanup<Mutex>(&mu, &Mutex::Unlock); 
+    ...
+  }  // Warning, mu is not unlocked.
+
+In this case, the destructor of ``Autocleanup`` calls ``mu.Unlock()``, so
+the warning is bogus.  However,
+thread safety analysis cannot see the unlock, because it does not attempt to
+inline the destructor.  Moreover, there is no way to annotate the destructor,
+because the destructor is calling a function that is not statically known.
+This pattern is simply not supported. 
+
+
+LOCKS_EXCLUDED is not transitive.
+---------------------------------
+
+A function which calls a method marked with LOCKS_EXCLUDED is not required to
+put LOCKS_EXCLUDED in its own interface.  LOCKS_EXCLUDED behaves differently
+from LOCKS_REQUIRED in this respect, and it can result in false negatives:
+
+.. code-block:: c++
+
+  class Foo {
+    Mutex mu;
+    
+    void foo() {
+      mu.Lock();
+      bar();                // No warning
+      mu.Unlock();
+    }
+    
+    void bar() { baz(); }   // No warning.  (Should have LOCKS_EXCLUDED(mu).)
+    
+    void baz() LOCKS_EXCLUDED(mu);
+  };
+
+The lack of transitivity is due to the fact that LOCKS_EXCLUDED can easily
+break encapsulation; it would be a bad idea to require functions to list the
+names private locks which happen to be acquired internally.  
+
+
+No alias analysis.
+------------------
+
+The analysis currently does not track pointer aliases.  Thus, there can be
+false positives if two pointers both point to the same mutex.  
+
+
+.. code-block:: c++
+
+  class MutexUnlocker {
+    Mutex* mu;
+
+  public:
+    MutexUnlocker(Mutex* m) UNLOCK_FUNCTION(m) : mu(m)  { mu->Unlock(); }
+    ~MutexUnlocker() EXCLUSIVE_LOCK_FUNCTION(mu) { mu->Lock(); }
+  };
+
+  Mutex mutex;
+  void test() EXCLUSIVE_LOCKS_REQUIRED(mutex) {
+    { 
+      MutexUnlocker munl(&mutex);  // unlocks mutex
+      doSomeIO();
+    }                              // Warning: locks munl.mu
+  }
+
+The MutexUnlocker class is intended to be the dual of the MutexLocker class,
+defined in :ref:`mutexheader`.  However, it doesn't work because the analysis
+doesn't know that munl.mu == mutex.  The SCOPED_LOCKABLE attribute handles
+aliasing 
+
+
+ACQUIRED_BEFORE(...) and ACQUIRED_AFTER(...) are currently unimplemented.
+-------------------------------------------------------------------------
+
+To be fixed in a future update. 
+
+
+.. _mutexheader:
+
+mutex.h
+=======
+
+Thread safety analysis can be used with any threading library, but it does
+require that the threading API be wrapped in classes and methods which have the
+appropriate annotations.  The following code provides ``mutex.h`` as an example;
+these methods should be filled in to call the appropriate underlying
+implementation. 
+
+
+.. code-block:: c++
+
+  #ifndef THREAD_SAFETY_ANALYSIS_MUTEX_H
+  #define THREAD_SAFETY_ANALYSIS_MUTEX_H
+  
+  // Enable thread safety attributes only with clang.
+  // The attributes can be safely erased when compiling with other compilers.
+  #if defined(__clang__) && (!defined(SWIG))
+  #define THREAD_ANNOTATION_ATTRIBUTE__(x)   __attribute__((x))
+  #else
+  #define THREAD_ANNOTATION_ATTRIBUTE__(x)   // no-op
+  #endif
+  
+  #define THREAD_ANNOTATION_ATTRIBUTE__(x)   __attribute__((x))
+  
+  #define GUARDED_BY(x) \
+    THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
+  
+  #define GUARDED_VAR \
+    THREAD_ANNOTATION_ATTRIBUTE__(guarded)
+  
+  #define PT_GUARDED_BY(x) \
+    THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))
+  
+  #define PT_GUARDED_VAR \
+    THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded)
+  
+  #define ACQUIRED_AFTER(...) \
+    THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__))
+  
+  #define ACQUIRED_BEFORE(...) \
+    THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__))
+  
+  #define EXCLUSIVE_LOCKS_REQUIRED(...) \
+    THREAD_ANNOTATION_ATTRIBUTE__(exclusive_locks_required(__VA_ARGS__))
+  
+  #define SHARED_LOCKS_REQUIRED(...) \
+    THREAD_ANNOTATION_ATTRIBUTE__(shared_locks_required(__VA_ARGS__))
+  
+  #define LOCKS_EXCLUDED(...) \
+    THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))
+  
+  #define LOCK_RETURNED(x) \
+    THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
+  
+  #define LOCKABLE \
+    THREAD_ANNOTATION_ATTRIBUTE__(lockable)
+  
+  #define SCOPED_LOCKABLE \
+    THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
+  
+  #define EXCLUSIVE_LOCK_FUNCTION(...) \
+    THREAD_ANNOTATION_ATTRIBUTE__(exclusive_lock_function(__VA_ARGS__))
+  
+  #define SHARED_LOCK_FUNCTION(...) \
+    THREAD_ANNOTATION_ATTRIBUTE__(shared_lock_function(__VA_ARGS__))
+  
+  #define ASSERT_EXCLUSIVE_LOCK(...) \
+    THREAD_ANNOTATION_ATTRIBUTE__(assert_exclusive_lock(__VA_ARGS__))
+  
+  #define ASSERT_SHARED_LOCK(...) \
+    THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_lock(__VA_ARGS__))
+  
+  #define EXCLUSIVE_TRYLOCK_FUNCTION(...) \
+    THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock_function(__VA_ARGS__))
+  
+  #define SHARED_TRYLOCK_FUNCTION(...) \
+    THREAD_ANNOTATION_ATTRIBUTE__(shared_trylock_function(__VA_ARGS__))
+  
+  #define UNLOCK_FUNCTION(...) \
+    THREAD_ANNOTATION_ATTRIBUTE__(unlock_function(__VA_ARGS__))
+  
+  #define NO_THREAD_SAFETY_ANALYSIS \
+    THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)
+  
+  
+  // Defines an annotated interface for mutexes.
+  // These methods can be implemented to use any internal mutex implementation.
+  class LOCKABLE Mutex {
+  public:
+    // Acquire/lock this mutex exclusively.  Only one thread can have exclusive
+    // access at any one time.  Write operations to guarded data require an
+    // exclusive lock.
+    void Lock() EXCLUSIVE_LOCK_FUNCTION();
+  
+    // Acquire/lock this mutex for read operations, which require only a shared
+    // lock.  This assumes a multiple-reader, single writer semantics.  Multiple
+    // threads may acquire the mutex simultaneously as readers, but a writer must
+    // wait for all of them to release the mutex before it can acquire it
+    // exclusively.  
+    void ReaderLock() SHARED_LOCK_FUNCTION();
+  
+    // Release/unlock the mutex, regardless of whether it is exclusive or shared.
+    void Unlock() UNLOCK_FUNCTION();
+  
+    // Try to acquire the mutex.  Returns true on success, and false on failure.
+    bool TryLock() EXCLUSIVE_TRYLOCK_FUNCTION(true);
+  
+    // Try to acquire the mutex for read operations.
+    bool ReaderTryLock() SHARED_TRYLOCK_FUNCTION(true);
+  
+    // Assert that this mutex is currently held by the calling thread.
+    void AssertHeld() ASSERT_EXCLUSIVE_LOCK();
+  
+    // Assert that is mutex is currently held for read operations. 
+    void AssertReaderHeld() ASSERT_SHARED_LOCK();
+  };
+  
+  
+  // MutexLocker is an RAII class that acquires a mutex in its constructor, and
+  // releases it in its destructor.  
+  class SCOPED_LOCKABLE MutexLocker {
+  private:
+    Mutex* mut;
+  
+  public:
+    MutexLocker(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu) : mut(mu) {
+      mu->Lock();
+    }  
+    ~MutexLocker() UNLOCK_FUNCTION() {
+      mut->Unlock();
+    }
+  };
+  
+  #endif  // THREAD_SAFETY_ANALYSIS_MUTEX_H
diff --git a/docs/ThreadSanitizer.rst b/docs/ThreadSanitizer.rst
index 194ad4a..a1d81e9 100644
--- a/docs/ThreadSanitizer.rst
+++ b/docs/ThreadSanitizer.rst
@@ -18,9 +18,9 @@
 Supported Platforms
 -------------------
 
-ThreadSanitizer is supported on Linux x86_64 (tested on Ubuntu 10.04 and 12.04).
-Support for MacOS 10.7 (64-bit only) is planned for 2013.  Support for 32-bit
-platforms is problematic and not yet planned.
+ThreadSanitizer is supported on Linux x86_64 (tested on Ubuntu 12.04).
+Support for other 64-bit architectures is possible, contributions are welcome.
+Support for 32-bit platforms is problematic and is not planned.
 
 Usage
 -----
diff --git a/docs/UsersManual.rst b/docs/UsersManual.rst
index e0a6838..90f16ee 100644
--- a/docs/UsersManual.rst
+++ b/docs/UsersManual.rst
@@ -112,11 +112,11 @@
 
 .. option:: -w
 
-  Disable all warnings.
+  Disable all diagnostics.
 
 .. option:: -Weverything
 
-  :ref:`Enable all warnings. <diagnostics_enable_everything>`
+  :ref:`Enable all diagnostics. <diagnostics_enable_everything>`
 
 .. option:: -pedantic
 
@@ -265,11 +265,6 @@
 
            t.c +3:11: warning: conversion specifies type 'char *' but the argument has type 'int'
 
-**-f[no-]diagnostics-show-name**
-   Enable the display of the diagnostic name.
-   This option, which defaults to off, controls whether or not Clang
-   prints the associated name.
-
 .. _opt_fdiagnostics-show-option:
 
 **-f[no-]diagnostics-show-option**
@@ -536,6 +531,67 @@
 The -fno-crash-diagnostics flag can be helpful for speeding the process
 of generating a delta reduced test case.
 
+.. _opt_rpass:
+
+Options to Emit Optimization Reports
+------------------------------------
+
+Optimization reports trace, at a high-level, all the major decisions
+done by compiler transformations. For instance, when the inliner
+decides to inline function ``foo()`` into ``bar()``, or the loop unroller
+decides to unroll a loop N times, or the vectorizer decides to
+vectorize a loop body.
+
+Clang offers a family of flags which the optimizers can use to emit
+a diagnostic in three cases:
+
+1. When the pass makes a transformation (:option:`-Rpass`).
+
+2. When the pass fails to make a transformation (:option:`-Rpass-missed`).
+
+3. When the pass determines whether or not to make a transformation
+   (:option:`-Rpass-analysis`).
+
+NOTE: Although the discussion below focuses on :option:`-Rpass`, the exact
+same options apply to :option:`-Rpass-missed` and :option:`-Rpass-analysis`.
+
+Since there are dozens of passes inside the compiler, each of these flags
+take a regular expression that identifies the name of the pass which should
+emit the associated diagnostic. For example, to get a report from the inliner,
+compile the code with:
+
+.. code-block:: console
+
+   $ clang -O2 -Rpass=inline code.cc -o code
+   code.cc:4:25: remark: foo inlined into bar [-Rpass=inline]
+   int bar(int j) { return foo(j, j - 2); }
+                           ^
+
+Note that remarks from the inliner are identified with `[-Rpass=inline]`.
+To request a report from every optimization pass, you should use
+:option:`-Rpass=.*` (in fact, you can use any valid POSIX regular
+expression). However, do not expect a report from every transformation
+made by the compiler. Optimization remarks do not really make sense
+outside of the major transformations (e.g., inlining, vectorization,
+loop optimizations) and not every optimization pass supports this
+feature.
+
+Current limitations
+^^^^^^^^^^^^^^^^^^^
+
+1. Optimization remarks that refer to function names will display the
+   mangled name of the function. Since these remarks are emitted by the
+   back end of the compiler, it does not know anything about the input
+   language, nor its mangling rules.
+
+2. Some source locations are not displayed correctly. The front end has
+   a more detailed source location tracking than the locations included
+   in the debug info (e.g., the front end can locate code inside macro
+   expansions). However, the locations used by :option:`-Rpass` are
+   translated from debug annotations. That translation can be lossy,
+   which results in some remarks having no location information.
+
+
 Language and Target-Independent Features
 ========================================
 
@@ -587,6 +643,7 @@
 
 -  Ignored
 -  Note
+-  Remark
 -  Warning
 -  Error
 -  Fatal
@@ -704,17 +761,18 @@
 
   char b = 'ab'; // no warning
 
-The :option:`-isystem-prefix` and :option:`-ino-system-prefix` command-line
-arguments can be used to override whether subsets of an include path are
-treated as system headers. When the name in a ``#include`` directive is
-found within a header search path and starts with a system prefix, the
+The :option:`--system-header-prefix=` and :option:`--no-system-header-prefix=`
+command-line arguments can be used to override whether subsets of an include
+path are treated as system headers. When the name in a ``#include`` directive
+is found within a header search path and starts with a system prefix, the
 header is treated as a system header. The last prefix on the
 command-line which matches the specified header name takes precedence.
 For instance:
 
 .. code-block:: console
 
-  $ clang -Ifoo -isystem bar -isystem-prefix x/ -ino-system-prefix x/y/
+  $ clang -Ifoo -isystem bar --system-header-prefix=x/ \
+      --no-system-header-prefix=x/y/
 
 Here, ``#include "x/a.h"`` is treated as including a system header, even
 if the header is found in ``foo``, and ``#include "x/y/b.h"`` is treated
@@ -727,11 +785,12 @@
 
 .. _diagnostics_enable_everything:
 
-Enabling All Warnings
-^^^^^^^^^^^^^^^^^^^^^
+Enabling All Diagnostics
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 In addition to the traditional ``-W`` flags, one can enable **all**
-warnings by passing :option:`-Weverything`. This works as expected with
+diagnostics by passing :option:`-Weverything`. This works as expected
+with
 :option:`-Werror`, and also includes the warnings from :option:`-pedantic`.
 
 Note that when combined with :option:`-w` (which disables all warnings), that
@@ -765,7 +824,7 @@
 some of the work needed to process a corresponding header file. While
 details of precompiled headers vary between compilers, precompiled
 headers have been shown to be highly effective at speeding up program
-compilation on systems with very large system headers (e.g., Mac OS/X).
+compilation on systems with very large system headers (e.g., Mac OS X).
 
 Generating a PCH File
 ^^^^^^^^^^^^^^^^^^^^^
@@ -874,10 +933,6 @@
       ``-fsanitize=address``:
       :doc:`AddressSanitizer`, a memory error
       detector.
-   -  ``-fsanitize=init-order``: Make AddressSanitizer check for
-      dynamic initialization order problems. Implied by ``-fsanitize=address``.
-   -  ``-fsanitize=address-full``: AddressSanitizer with all the
-      experimental features listed below.
    -  ``-fsanitize=integer``: Enables checks for undefined or
       suspicious integer behavior.
    -  .. _opt_fsanitize_thread:
@@ -960,23 +1015,20 @@
    -  ``-fno-sanitize-blacklist``: don't use blacklist file, if it was
       specified earlier in the command line.
 
-   Experimental features of AddressSanitizer (not ready for widespread
-   use, require explicit ``-fsanitize=address``):
-
-   -  ``-fsanitize=use-after-return``: Check for use-after-return
-      errors (accessing local variable after the function exit).
-   -  ``-fsanitize=use-after-scope``: Check for use-after-scope errors
-      (accesing local variable after it went out of scope).
-
    Extra features of MemorySanitizer (require explicit
    ``-fsanitize=memory``):
 
-   -  ``-fsanitize-memory-track-origins``: Enables origin tracking in
+   -  ``-fsanitize-memory-track-origins[=level]``: Enables origin tracking in
       MemorySanitizer. Adds a second section to MemorySanitizer
       reports pointing to the heap or stack allocation the
       uninitialized bits came from. Slows down execution by additional
       1.5x-2x.
 
+      Possible values for level are 0 (off), 1 (default), 2. Level 2 adds more
+      sections to MemorySanitizer reports describing the order of memory stores
+      the uninitialized value went through. Beware, this mode may use a lot of
+      extra memory.
+
    Extra features of UndefinedBehaviorSanitizer:
 
    -  ``-fno-sanitize-recover``: By default, after a sanitizer diagnoses
@@ -1002,18 +1054,6 @@
    program. The ``-fsanitize=undefined`` checks can be combined with other
    sanitizers.
 
-**-f[no-]address-sanitizer**
-   Deprecated synonym for :ref:`-f[no-]sanitize=address
-   <opt_fsanitize_address>`.
-**-f[no-]thread-sanitizer**
-   Deprecated synonym for :ref:`-f[no-]sanitize=thread
-   <opt_fsanitize_thread>`.
-
-.. option:: -fcatch-undefined-behavior
-
-   Deprecated synonym for :ref:`-fsanitize=undefined
-   <opt_fsanitize_undefined>`.
-
 .. option:: -fno-assume-sane-operator-new
 
    Don't assume that the C++'s new operator is sane.
@@ -1066,6 +1106,240 @@
 
    CRC instructions are enabled by default on ARMv8.
 
+.. option:: -mgeneral-regs-only
+
+   Generate code which only uses the general purpose registers.
+
+   This option restricts the generated code to use general registers
+   only. This only applies to the AArch64 architecture.
+
+
+Profile Guided Optimization
+---------------------------
+
+Profile information enables better optimization. For example, knowing that a
+branch is taken very frequently helps the compiler make better decisions when
+ordering basic blocks. Knowing that a function ``foo`` is called more
+frequently than another function ``bar`` helps the inliner.
+
+Clang supports profile guided optimization with two different kinds of
+profiling. A sampling profiler can generate a profile with very low runtime
+overhead, or you can build an instrumented version of the code that collects
+more detailed profile information. Both kinds of profiles can provide execution
+counts for instructions in the code and information on branches taken and
+function invocation.
+
+Regardless of which kind of profiling you use, be careful to collect profiles
+by running your code with inputs that are representative of the typical
+behavior. Code that is not exercised in the profile will be optimized as if it
+is unimportant, and the compiler may make poor optimization choices for code
+that is disproportionately used while profiling.
+
+Using Sampling Profilers
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Sampling profilers are used to collect runtime information, such as
+hardware counters, while your application executes. They are typically
+very efficient and do not incur a large runtime overhead. The
+sample data collected by the profiler can be used during compilation
+to determine what the most executed areas of the code are.
+
+Using the data from a sample profiler requires some changes in the way
+a program is built. Before the compiler can use profiling information,
+the code needs to execute under the profiler. The following is the
+usual build cycle when using sample profilers for optimization:
+
+1. Build the code with source line table information. You can use all the
+   usual build flags that you always build your application with. The only
+   requirement is that you add ``-gline-tables-only`` or ``-g`` to the
+   command line. This is important for the profiler to be able to map
+   instructions back to source line locations.
+
+   .. code-block:: console
+
+     $ clang++ -O2 -gline-tables-only code.cc -o code
+
+2. Run the executable under a sampling profiler. The specific profiler
+   you use does not really matter, as long as its output can be converted
+   into the format that the LLVM optimizer understands. Currently, there
+   exists a conversion tool for the Linux Perf profiler
+   (https://perf.wiki.kernel.org/), so these examples assume that you
+   are using Linux Perf to profile your code.
+
+   .. code-block:: console
+
+     $ perf record -b ./code
+
+   Note the use of the ``-b`` flag. This tells Perf to use the Last Branch
+   Record (LBR) to record call chains. While this is not strictly required,
+   it provides better call information, which improves the accuracy of
+   the profile data.
+
+3. Convert the collected profile data to LLVM's sample profile format.
+   This is currently supported via the AutoFDO converter ``create_llvm_prof``.
+   It is available at http://github.com/google/autofdo. Once built and
+   installed, you can convert the ``perf.data`` file to LLVM using
+   the command:
+
+   .. code-block:: console
+
+     $ create_llvm_prof --binary=./code --out=code.prof
+
+   This will read ``perf.data`` and the binary file ``./code`` and emit
+   the profile data in ``code.prof``. Note that if you ran ``perf``
+   without the ``-b`` flag, you need to use ``--use_lbr=false`` when
+   calling ``create_llvm_prof``.
+
+4. Build the code again using the collected profile. This step feeds
+   the profile back to the optimizers. This should result in a binary
+   that executes faster than the original one. Note that you are not
+   required to build the code with the exact same arguments that you
+   used in the first step. The only requirement is that you build the code
+   with ``-gline-tables-only`` and ``-fprofile-sample-use``.
+
+   .. code-block:: console
+
+     $ clang++ -O2 -gline-tables-only -fprofile-sample-use=code.prof code.cc -o code
+
+
+Sample Profile Format
+"""""""""""""""""""""
+
+If you are not using Linux Perf to collect profiles, you will need to
+write a conversion tool from your profiler to LLVM's format. This section
+explains the file format expected by the backend.
+
+Sample profiles are written as ASCII text. The file is divided into sections,
+which correspond to each of the functions executed at runtime. Each
+section has the following format (taken from
+https://github.com/google/autofdo/blob/master/profile_writer.h):
+
+.. code-block:: console
+
+    function1:total_samples:total_head_samples
+    offset1[.discriminator]: number_of_samples [fn1:num fn2:num ... ]
+    offset2[.discriminator]: number_of_samples [fn3:num fn4:num ... ]
+    ...
+    offsetN[.discriminator]: number_of_samples [fn5:num fn6:num ... ]
+
+The file may contain blank lines between sections and within a
+section. However, the spacing within a single line is fixed. Additional
+spaces will result in an error while reading the file.
+
+Function names must be mangled in order for the profile loader to
+match them in the current translation unit. The two numbers in the
+function header specify how many total samples were accumulated in the
+function (first number), and the total number of samples accumulated
+in the prologue of the function (second number). This head sample
+count provides an indicator of how frequently the function is invoked.
+
+Each sampled line may contain several items. Some are optional (marked
+below):
+
+a. Source line offset. This number represents the line number
+   in the function where the sample was collected. The line number is
+   always relative to the line where symbol of the function is
+   defined. So, if the function has its header at line 280, the offset
+   13 is at line 293 in the file.
+
+   Note that this offset should never be a negative number. This could
+   happen in cases like macros. The debug machinery will register the
+   line number at the point of macro expansion. So, if the macro was
+   expanded in a line before the start of the function, the profile
+   converter should emit a 0 as the offset (this means that the optimizers
+   will not be able to associate a meaningful weight to the instructions
+   in the macro).
+
+b. [OPTIONAL] Discriminator. This is used if the sampled program
+   was compiled with DWARF discriminator support
+   (http://wiki.dwarfstd.org/index.php?title=Path_Discriminators).
+   DWARF discriminators are unsigned integer values that allow the
+   compiler to distinguish between multiple execution paths on the
+   same source line location.
+
+   For example, consider the line of code ``if (cond) foo(); else bar();``.
+   If the predicate ``cond`` is true 80% of the time, then the edge
+   into function ``foo`` should be considered to be taken most of the
+   time. But both calls to ``foo`` and ``bar`` are at the same source
+   line, so a sample count at that line is not sufficient. The
+   compiler needs to know which part of that line is taken more
+   frequently.
+
+   This is what discriminators provide. In this case, the calls to
+   ``foo`` and ``bar`` will be at the same line, but will have
+   different discriminator values. This allows the compiler to correctly
+   set edge weights into ``foo`` and ``bar``.
+
+c. Number of samples. This is an integer quantity representing the
+   number of samples collected by the profiler at this source
+   location.
+
+d. [OPTIONAL] Potential call targets and samples. If present, this
+   line contains a call instruction. This models both direct and
+   number of samples. For example,
+
+   .. code-block:: console
+
+     130: 7  foo:3  bar:2  baz:7
+
+   The above means that at relative line offset 130 there is a call
+   instruction that calls one of ``foo()``, ``bar()`` and ``baz()``,
+   with ``baz()`` being the relatively more frequently called target.
+
+
+Profiling with Instrumentation
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Clang also supports profiling via instrumentation. This requires building a
+special instrumented version of the code and has some runtime
+overhead during the profiling, but it provides more detailed results than a
+sampling profiler. It also provides reproducible results, at least to the
+extent that the code behaves consistently across runs.
+
+Here are the steps for using profile guided optimization with
+instrumentation:
+
+1. Build an instrumented version of the code by compiling and linking with the
+   ``-fprofile-instr-generate`` option.
+
+   .. code-block:: console
+
+     $ clang++ -O2 -fprofile-instr-generate code.cc -o code
+
+2. Run the instrumented executable with inputs that reflect the typical usage.
+   By default, the profile data will be written to a ``default.profraw`` file
+   in the current directory. You can override that default by setting the
+   ``LLVM_PROFILE_FILE`` environment variable to specify an alternate file.
+   Any instance of ``%p`` in that file name will be replaced by the process
+   ID, so that you can easily distinguish the profile output from multiple
+   runs.
+
+   .. code-block:: console
+
+     $ LLVM_PROFILE_FILE="code-%p.profraw" ./code
+
+3. Combine profiles from multiple runs and convert the "raw" profile format to
+   the input expected by clang. Use the ``merge`` command of the llvm-profdata
+   tool to do this.
+
+   .. code-block:: console
+
+     $ llvm-profdata merge -output=code.profdata code-*.profraw
+
+   Note that this step is necessary even when there is only one "raw" profile,
+   since the merge operation also changes the file format.
+
+4. Build the code again using the ``-fprofile-instr-use`` option to specify the
+   collected profile data.
+
+   .. code-block:: console
+
+     $ clang++ -O2 -fprofile-instr-use=code.profdata code.cc -o code
+
+   You can repeat step 4 as often as you like without regenerating the
+   profile. As you make changes to your code, clang may no longer be able to
+   use the profile data. It will warn you when this happens.
+
 
 Controlling Size of Debug Information
 -------------------------------------
@@ -1086,23 +1360,70 @@
   doesn't contain any other data (e.g. description of local variables or
   function parameters).
 
+.. option:: -fstandalone-debug
+
+  Clang supports a number of optimizations to reduce the size of debug
+  information in the binary. They work based on the assumption that
+  the debug type information can be spread out over multiple
+  compilation units.  For instance, Clang will not emit type
+  definitions for types that are not needed by a module and could be
+  replaced with a forward declaration.  Further, Clang will only emit
+  type info for a dynamic C++ class in the module that contains the
+  vtable for the class.
+
+  The **-fstandalone-debug** option turns off these optimizations.
+  This is useful when working with 3rd-party libraries that don't come
+  with debug information.  Note that Clang will never emit type
+  information for types that are not referenced at all by the program.
+
+.. option:: -fno-standalone-debug
+
+   On Darwin **-fstandalone-debug** is enabled by default. The
+   **-fno-standalone-debug** option can be used to get to turn on the
+   vtable-based optimization described above.
+
 .. option:: -g
 
   Generate complete debug info.
 
 Comment Parsing Options
---------------------------
+-----------------------
 
 Clang parses Doxygen and non-Doxygen style documentation comments and attaches
 them to the appropriate declaration nodes.  By default, it only parses
 Doxygen-style comments and ignores ordinary comments starting with ``//`` and
 ``/*``.
 
+.. option:: -Wdocumentation
+
+  Emit warnings about use of documentation comments.  This warning group is off
+  by default.
+
+  This includes checking that ``\param`` commands name parameters that actually
+  present in the function signature, checking that ``\returns`` is used only on
+  functions that actually return a value etc.
+
+.. option:: -Wno-documentation-unknown-command
+
+  Don't warn when encountering an unknown Doxygen command.
+
 .. option:: -fparse-all-comments
 
   Parse all comments as documentation comments (including ordinary comments
   starting with ``//`` and ``/*``).
 
+.. option:: -fcomment-block-commands=[commands]
+
+  Define custom documentation commands as block commands.  This allows Clang to
+  construct the correct AST for these custom commands, and silences warnings
+  about unknown commands.  Several commands must be separated by a comma
+  *without trailing space*; e.g. ``-fcomment-block-commands=foo,bar`` defines
+  custom commands ``\foo`` and ``\bar``.
+
+  It is also possible to use ``-fcomment-block-commands`` several times; e.g.
+  ``-fcomment-block-commands=foo -fcomment-block-commands=bar`` does the same
+  as above.
+
 .. _c:
 
 C Language Features
@@ -1238,23 +1559,23 @@
 --------------------
 
 clang has some experimental support for extensions from Microsoft Visual
-C++; to enable it, use the -fms-extensions command-line option. This is
+C++; to enable it, use the ``-fms-extensions`` command-line option. This is
 the default for Windows targets. Note that the support is incomplete.
-Some constructs such as dllexport on classes are ignored with a warning,
+Some constructs such as ``dllexport`` on classes are ignored with a warning,
 and others such as `Microsoft IDL annotations
 <http://msdn.microsoft.com/en-us/library/8tesw2eh.aspx>`_ are silently
 ignored.
 
-clang has a -fms-compatibility flag that makes clang accept enough
+clang has a ``-fms-compatibility`` flag that makes clang accept enough
 invalid C++ to be able to parse most Microsoft headers. For example, it
 allows `unqualified lookup of dependent base class members
 <http://clang.llvm.org/compatibility.html#dep_lookup_bases>`_, which is
 a common compatibility issue with clang. This flag is enabled by default
 for Windows targets.
 
--fdelayed-template-parsing lets clang delay all template instantiation
-until the end of a translation unit. This flag is enabled by default for
-Windows targets.
+``-fdelayed-template-parsing`` lets clang delay parsing of function template
+definitions until the end of a translation unit. This flag is enabled by
+default for Windows targets.
 
 -  clang allows setting ``_MSC_VER`` with ``-fmsc-version=``. It defaults to
    1700 which is the same as Visual C/C++ 2012. Any number is supported
@@ -1280,8 +1601,8 @@
 =====================
 
 clang fully implements all of standard C++98 except for exported
-templates (which were removed in C++11), and `many C++11
-features <http://clang.llvm.org/cxx_status.html>`_ are also implemented.
+templates (which were removed in C++11), and all of standard C++11
+and the current draft standard for C++1y.
 
 Controlling implementation limits
 ---------------------------------
@@ -1329,14 +1650,21 @@
 ^^^
 
 The support for X86 (both 32-bit and 64-bit) is considered stable on
-Darwin (Mac OS/X), Linux, FreeBSD, and Dragonfly BSD: it has been tested
+Darwin (Mac OS X), Linux, FreeBSD, and Dragonfly BSD: it has been tested
 to correctly compile many large C, C++, Objective-C, and Objective-C++
 codebases.
 
-On ``x86_64-mingw32``, passing i128(by value) is incompatible to Microsoft
-x64 calling conversion. You might need to tweak
+On ``x86_64-mingw32``, passing i128(by value) is incompatible with the
+Microsoft x64 calling convention. You might need to tweak
 ``WinX86_64ABIInfo::classify()`` in lib/CodeGen/TargetInfo.cpp.
 
+For the X86 target, clang supports the :option:`-m16` command line
+argument which enables 16-bit code output. This is broadly similar to
+using ``asm(".code16gcc")`` with the GNU toolchain. The generated code
+and the ABI remains 32-bit but the assembler emits instructions
+appropriate for a CPU running in 16-bit mode, with address-size and
+operand-size prefixes to enable 32-bit addressing and operations.
+
 ARM
 ^^^
 
@@ -1377,15 +1705,16 @@
 Operating System Features and Limitations
 -----------------------------------------
 
-Darwin (Mac OS/X)
+Darwin (Mac OS X)
 ^^^^^^^^^^^^^^^^^
 
-None
+Thread Sanitizer is not supported.
 
 Windows
 ^^^^^^^
 
-Experimental supports are on Cygming.
+Clang has experimental support for targeting "Cygming" (Cygwin / MinGW)
+platforms.
 
 See also :ref:`Microsoft Extensions <c_ms>`.
 
@@ -1479,55 +1808,92 @@
 
   ::
 
-    /?                     Display available options
-    /c                     Compile only
-    /D <macro[=value]>     Define macro
-    /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
-    /Fe<file or directory> Set output executable file or directory (ends in / or \)
-    /FI<value>             Include file before parsing
-    /Fo<file or directory> Set output object file, or directory (ends in / or \)
-    /GF-                   Disable string pooling
-    /GR-                   Disable RTTI
-    /GR                    Enable RTTI
-    /help                  Display available options
-    /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
-    /Ob0                   Disable inlining
-    /Od                    Disable optimization
-    /Oi-                   Disable use of builtin functions
-    /Oi                    Enable use of builtin functions
-    /Os                    Optimize for size
-    /Ot                    Optimize for speed
-    /Ox                    Maximum optimization
-    /Oy-                   Disable frame pointer omission
-    /Oy                    Enable frame pointer omission
-    /O<n>                  Optimization level
-    /P                     Only run the preprocessor
-    /showIncludes          Print info about included files to stderr
-    /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
-    /W0                    Disable all warnings
-    /W1                    Enable -Wall
-    /W2                    Enable -Wall
-    /W3                    Enable -Wall
-    /W4                    Enable -Wall
-    /Wall                  Enable -Wall
-    /WX-                   Do not treat warnings as errors
-    /WX                    Treat warnings as errors
-    /w                     Disable all warnings
-    /Zs                    Syntax-check only
+    CL.EXE COMPATIBILITY OPTIONS:
+      /?                     Display available options
+      /arch:<value>          Set architecture for code generation
+      /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
+      /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
+      /Fo<file or directory> Set output object file, or directory (ends in / or \)
+      /GF-                   Disable string pooling
+      /GR-                   Disable emission of RTTI data
+      /GR                    Enable emission of RTTI data
+      /Gw-                   Don't put each data item in its own section
+      /Gw                    Put each data item in its own section
+      /Gy-                   Don't put each function in its own section
+      /Gy                    Put each function in its own section
+      /help                  Display available options
+      /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
+      /Ob0                   Disable inlining
+      /Od                    Disable optimization
+      /Oi-                   Disable use of builtin functions
+      /Oi                    Enable use of builtin functions
+      /Os                    Optimize for size
+      /Ot                    Optimize for speed
+      /Ox                    Maximum optimization
+      /Oy-                   Disable frame pointer omission
+      /Oy                    Enable frame pointer omission
+      /O<n>                  Optimization level
+      /P                     Preprocess to file
+      /showIncludes          Print info about included files to stderr
+      /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
+      /W0                    Disable all warnings
+      /W1                    Enable -Wall
+      /W2                    Enable -Wall
+      /W3                    Enable -Wall
+      /W4                    Enable -Wall
+      /Wall                  Enable -Wall
+      /WX-                   Do not treat warnings as errors
+      /WX                    Treat warnings as errors
+      /w                     Disable all warnings
+      /Zi                    Enable debug information
+      /Zs                    Syntax-check only
+
+    OPTIONS:
+      -###                  Print (but do not run) the commands to run for this compilation
+      -fms-compatibility-version=<value>
+                            Dot-separated value representing the Microsoft compiler version
+                            number to report in _MSC_VER (0 = don't define it (default))
+      -fmsc-version=<value> Microsoft compiler version number to report in _MSC_VER (0 = don't
+                            define it (default))
+      -fsanitize-blacklist=<value>
+                            Path to blacklist file for sanitizers
+      -fsanitize=<check>    Enable runtime instrumentation for bug detection: address (memory
+                            errors) | thread (race detection) | undefined (miscellaneous
+                            undefined behavior)
+      -mllvm <value>        Additional arguments to forward to LLVM's option processing
+      -Qunused-arguments    Don't emit warning for unused driver arguments
+      --target=<value>      Generate code for the given target
+      -v                    Show commands to run and use verbose output
+      -W<warning>           Enable the specified warning
+      -Xclang <arg>         Pass <arg> to the clang compiler
 
 The /fallback Option
 ^^^^^^^^^^^^^^^^^^^^
diff --git a/docs/analyzer/conf.py b/docs/analyzer/conf.py
index 3690f93..1514708 100644
--- a/docs/analyzer/conf.py
+++ b/docs/analyzer/conf.py
@@ -41,7 +41,7 @@
 
 # General information about the project.
 project = u'Clang Static Analyzer'
-copyright = u'2013, Analyzer Team'
+copyright = u'2013-2014, Analyzer Team'
 
 # The version info for the project you're documenting, acts as replacement for
 # |version| and |release|, also used in various other places throughout the
diff --git a/docs/conf.py b/docs/conf.py
index 183a285..1963a05 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -41,16 +41,16 @@
 
 # General information about the project.
 project = u'Clang'
-copyright = u'2007-2013, The Clang Team'
+copyright = u'2007-2014, The Clang Team'
 
 # The version info for the project you're documenting, acts as replacement for
 # |version| and |release|, also used in various other places throughout the
 # built documents.
 #
 # The short X.Y version.
-version = '3.4'
+version = '3.5'
 # The full version, including alpha/beta/rc tags.
-release = '3.4'
+release = '3.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 61c0bd8..2372e04 100644
--- a/docs/doxygen.cfg.in
+++ b/docs/doxygen.cfg.in
@@ -697,6 +697,59 @@
 
 TOC_EXPAND             = NO
 
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and 
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated 
+# that can be used as input for Qt's qhelpgenerator to generate a 
+# Qt Compressed Help (.qch) of the generated HTML documentation.
+
+GENERATE_QHP           = @clang_doxygen_generate_qhp@
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can 
+# be used to specify the file name of the resulting .qch file. 
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE               = @clang_doxygen_qch_filename@
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating 
+# Qt Help Project output. For more information please see 
+# http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace
+
+QHP_NAMESPACE          = @clang_doxygen_qhp_namespace@
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating 
+# Qt Help Project output. For more information please see 
+# http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to 
+# add. For more information please see 
+# http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME   = @clang_doxygen_qhp_cust_filter_name@
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the 
+# custom filter to add. For more information please see 
+# <a href="http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-filters"> 
+# Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS  = @clang_doxygen_qhp_cust_filter_attrs@
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this 
+# project's 
+# filter section matches. 
+# <a href="http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes"> 
+# Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS  = 
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can 
+# be used to specify the location of Qt's qhelpgenerator. 
+# If non-empty doxygen will try to run qhelpgenerator on the generated 
+# .qhp file.
+
+QHG_LOCATION           = @clang_doxygen_qhelpgenerator_path@
+
 # The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
 # top of each HTML page. The value NO (the default) enables the index and 
 # the value YES disables it.
diff --git a/docs/index.rst b/docs/index.rst
index d026864..bf2de7e 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -18,20 +18,19 @@
 
    UsersManual
    LanguageExtensions
+   AttributeReference
    CrossCompilation
+   ThreadSafetyAnalysis
    AddressSanitizer
    ThreadSanitizer
    MemorySanitizer
    DataFlowSanitizer
+   LeakSanitizer
    SanitizerSpecialCaseList
    Modules
+   MSVCCompatibility
    FAQ
 
-.. toctree::
-   :hidden:
-
-   LeakSanitizer
-
 Using Clang as a Library
 ========================
 
diff --git a/docs/tools/clang.pod b/docs/tools/clang.pod
index a58986c..f7d2eaf 100644
--- a/docs/tools/clang.pod
+++ b/docs/tools/clang.pod
@@ -237,7 +237,7 @@
 
 =item B<-mmacosx-version-min>=I<version>
 
-When building for Mac OS/X, specify the minimum version supported by your
+When building for Mac OS X, specify the minimum version supported by your
 application.
 
 =item B<-miphoneos-version-min>
@@ -310,8 +310,23 @@
 =item B<-g>
 
 Generate debug information.  Note that Clang debug information works best at
-B<-O0>.  At higher optimization levels, only line number information is
-currently available.
+B<-O0>.
+
+=item B<-fstandalone-debug> B<-fno-standalone-debug>
+
+Clang supports a number of optimizations to reduce the size of debug
+information in the binary. They work based on the assumption that the
+debug type information can be spread out over multiple compilation
+units.  For instance, Clang will not emit type definitions for types
+that are not needed by a module and could be replaced with a forward
+declaration.  Further, Clang will only emit type info for a dynamic
+C++ class in the module that contains the vtable for the class.
+
+The B<-fstandalone-debug> option turns off these optimizations.  This
+is useful when working with 3rd-party libraries that don't come with
+debug information.  This is the default on Darwin.  Note that Clang
+will never emit type information for types that are not referenced at
+all by the program.
 
 =item B<-fexceptions>
 
@@ -366,7 +381,7 @@
 
 =item B<-###>
 
-Print the commands to run for this compilation.
+Print (but do not run) the commands to run for this compilation.
 
 =item B<--help>
 
diff --git a/docs/tools/dump_ast_matchers.py b/docs/tools/dump_ast_matchers.py
index 564dc38..4ece46a 100644
--- a/docs/tools/dump_ast_matchers.py
+++ b/docs/tools/dump_ast_matchers.py
@@ -119,9 +119,9 @@
   # arguments.
   elif ('Matcher<' not in args or
         name in ['allOf', 'anyOf', 'anything', 'unless']):
-    narrowing_matchers[result_type + name] = matcher_html
+    narrowing_matchers[result_type + name + esc(args)] = matcher_html
   else:
-    traversal_matchers[result_type + name] = matcher_html
+    traversal_matchers[result_type + name + esc(args)] = matcher_html
 
 def act_on_decl(declaration, comment, allowed_types):
   """Parse the matcher out of the given declaration and comment.
@@ -204,6 +204,25 @@
         add_matcher(result_type, name, args, comment)
       return
 
+    m = re.match(r"""^\s*AST_MATCHER_FUNCTION(_P)?(.?)(?:_OVERLOAD)?\(
+                       (?:\s*([^\s,]+)\s*,)?
+                          \s*([^\s,]+)\s*
+                       (?:,\s*([^\s,]+)\s*
+                          ,\s*([^\s,]+)\s*)?
+                       (?:,\s*([^\s,]+)\s*
+                          ,\s*([^\s,]+)\s*)?
+                       (?:,\s*\d+\s*)?
+                      \)\s*{\s*$""", declaration, flags=re.X)
+    if m:
+      p, n, result, name = m.groups()[0:4]
+      args = m.groups()[4:]
+      if n not in ['', '2']:
+        raise Exception('Cannot parse "%s"' % declaration)
+      args = ', '.join('%s %s' % (args[i], args[i+1])
+                       for i in range(0, len(args), 2) if args[i])
+      add_matcher(result, name, args, comment)
+      return
+
     m = re.match(r"""^\s*AST_MATCHER(_P)?(.?)(?:_OVERLOAD)?\(
                        (?:\s*([^\s,]+)\s*,)?
                           \s*([^\s,]+)\s*
@@ -242,12 +261,17 @@
 
     # Parse Variadic operator matchers.
     m = re.match(
-        r"""^.*VariadicOperatorMatcherFunc\s*([a-zA-Z]*)\s*=\s*{.*};$""",
+        r"""^.*VariadicOperatorMatcherFunc\s*<\s*([^,]+),\s*([^\s>]+)\s*>\s*
+              ([a-zA-Z]*)\s*=\s*{.*};$""",
         declaration, flags=re.X)
     if m:
-      name = m.groups()[0]
-      add_matcher('*', name, 'Matcher<*>, ..., Matcher<*>', comment)
-      return
+      min_args, max_args, name = m.groups()[:3]
+      if max_args == '1':
+        add_matcher('*', name, 'Matcher<*>', comment)
+        return
+      elif max_args == 'UINT_MAX':
+        add_matcher('*', name, 'Matcher<*>, ..., Matcher<*>', comment)
+        return
 
 
     # Parse free standing matcher functions, like:
diff --git a/docs/tools/dump_format_style.py b/docs/tools/dump_format_style.py
old mode 100644
new mode 100755
index 0c8ca6d..66bad8b
--- a/docs/tools/dump_format_style.py
+++ b/docs/tools/dump_format_style.py
@@ -98,7 +98,7 @@
         enum = Enum(name, comment)
       elif line.endswith(';'):
         state = State.InStruct
-        field_type, field_name = re.match(r'(\w+)\s+(\w+);', line).groups()
+        field_type, field_name = re.match(r'([<>:\w]+)\s+(\w+);', line).groups()
         option = Option(str(field_name), str(field_type), comment)
         options.append(option)
       else:
@@ -122,7 +122,8 @@
     raise Exception('Not finished by the end of file')
 
   for option in options:
-    if not option.type in ['bool', 'unsigned', 'int']:
+    if not option.type in ['bool', 'unsigned', 'int', 'std::string',
+                           'std::vector<std::string>']:
       if enums.has_key(option.type):
         option.enum = enums[option.type]
       else:
diff --git a/emscripten-version.txt b/emscripten-version.txt
index b7825b8..a5096ba 100644
--- a/emscripten-version.txt
+++ b/emscripten-version.txt
@@ -1,2 +1,2 @@
-1.28.2
+1.28.3
 
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 84a5d2c..5d4b5fc 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -1,7 +1,10 @@
 if(NOT CLANG_BUILD_EXAMPLES)
   set_property(DIRECTORY PROPERTY EXCLUDE_FROM_ALL ON)
+  set(EXCLUDE_FROM_ALL ON)
 endif()
 
+if(CLANG_ENABLE_STATIC_ANALYZER)
 add_subdirectory(analyzer-plugin)
+endif()
 add_subdirectory(clang-interpreter)
 add_subdirectory(PrintFunctionNames)
diff --git a/examples/PrintFunctionNames/CMakeLists.txt b/examples/PrintFunctionNames/CMakeLists.txt
index ba6a350..e700281 100644
--- a/examples/PrintFunctionNames/CMakeLists.txt
+++ b/examples/PrintFunctionNames/CMakeLists.txt
@@ -1,24 +1,21 @@
-set(MODULE TRUE)
+# If we don't need RTTI or EH, there's no reason to export anything
+# from the plugin.
+if( NOT MSVC ) # MSVC mangles symbols differently, and
+                # PrintFunctionNames.export contains C++ symbols.
+  if( NOT LLVM_REQUIRES_RTTI )
+    if( NOT LLVM_REQUIRES_EH )
+      set(LLVM_EXPORTED_SYMBOL_FILE ${CMAKE_CURRENT_SOURCE_DIR}/PrintFunctionNames.exports)
+    endif()
+  endif()
+endif()
 
-set( LLVM_LINK_COMPONENTS support mc)
+add_llvm_loadable_module(PrintFunctionNames PrintFunctionNames.cpp)
 
-add_clang_library(PrintFunctionNames PrintFunctionNames.cpp)
-
-add_dependencies(PrintFunctionNames
-  ClangAttrClasses
-  ClangAttrList
-  ClangCommentNodes
-  ClangDeclNodes
-  ClangDiagnosticCommon
-  ClangStmtNodes
-  )
-
-target_link_libraries(PrintFunctionNames
-  clangFrontend
-  clangAST
-  )
-
-set_target_properties(PrintFunctionNames
-  PROPERTIES
-  LINKER_LANGUAGE CXX
-  PREFIX "")
+if(LLVM_ENABLE_PLUGINS AND (WIN32 OR CYGWIN))
+  target_link_libraries(PrintFunctionNames ${cmake_2_8_12_PRIVATE}
+    clangAST
+    clangBasic
+    clangFrontend
+    LLVMSupport
+    )
+endif()
diff --git a/examples/PrintFunctionNames/Makefile b/examples/PrintFunctionNames/Makefile
index 23a5305..5865098 100644
--- a/examples/PrintFunctionNames/Makefile
+++ b/examples/PrintFunctionNames/Makefile
@@ -19,7 +19,7 @@
 endif
 
 LINK_LIBS_IN_SHARED = 0
-SHARED_LIBRARY = 1
+LOADABLE_MODULE = 1
 
 include $(CLANG_LEVEL)/Makefile
 
diff --git a/examples/PrintFunctionNames/PrintFunctionNames.cpp b/examples/PrintFunctionNames/PrintFunctionNames.cpp
index f6e75cc..3f18cd4 100644
--- a/examples/PrintFunctionNames/PrintFunctionNames.cpp
+++ b/examples/PrintFunctionNames/PrintFunctionNames.cpp
@@ -48,9 +48,9 @@
       // Example error handling.
       if (args[i] == "-an-error") {
         DiagnosticsEngine &D = CI.getDiagnostics();
-        unsigned DiagID = D.getCustomDiagID(
-          DiagnosticsEngine::Error, "invalid argument '" + args[i] + "'");
-        D.Report(DiagID);
+        unsigned DiagID = D.getCustomDiagID(DiagnosticsEngine::Error,
+                                            "invalid argument '%0'");
+        D.Report(DiagID) << args[i];
         return false;
       }
     }
diff --git a/examples/PrintFunctionNames/PrintFunctionNames.exports b/examples/PrintFunctionNames/PrintFunctionNames.exports
index 0ff590d..e69de29 100644
--- a/examples/PrintFunctionNames/PrintFunctionNames.exports
+++ b/examples/PrintFunctionNames/PrintFunctionNames.exports
@@ -1 +0,0 @@
-_ZN4llvm8Registry*
diff --git a/examples/analyzer-plugin/CMakeLists.txt b/examples/analyzer-plugin/CMakeLists.txt
index ba73030..1788d6c 100644
--- a/examples/analyzer-plugin/CMakeLists.txt
+++ b/examples/analyzer-plugin/CMakeLists.txt
@@ -1,23 +1,10 @@
-set(MODULE TRUE)
+add_llvm_loadable_module(SampleAnalyzerPlugin MainCallChecker.cpp)
 
-set( LLVM_LINK_COMPONENTS support mc)
-
-add_clang_library(SampleAnalyzerPlugin MainCallChecker.cpp)
-
-add_dependencies(SampleAnalyzerPlugin
-  ClangAttrClasses
-  ClangAttrList
-  ClangCommentNodes
-  ClangDeclNodes
-  ClangDiagnosticCommon
-  ClangStmtNodes
-  )
-
-target_link_libraries(SampleAnalyzerPlugin
-  clangStaticAnalyzerCore
-  )
-
-set_target_properties(SampleAnalyzerPlugin
-  PROPERTIES
-  LINKER_LANGUAGE CXX
-  PREFIX "")
+if(LLVM_ENABLE_PLUGINS AND (WIN32 OR CYGWIN))
+  target_link_libraries(SampleAnalyzerPlugin ${cmake_2_8_12_PRIVATE}
+    clangAnalysis
+    clangAST
+    clangStaticAnalyzerCore
+    LLVMSupport
+    )
+endif()
diff --git a/examples/analyzer-plugin/MainCallChecker.cpp b/examples/analyzer-plugin/MainCallChecker.cpp
index 8801f9a..2ad8c84 100644
--- a/examples/analyzer-plugin/MainCallChecker.cpp
+++ b/examples/analyzer-plugin/MainCallChecker.cpp
@@ -8,7 +8,7 @@
 
 namespace {
 class MainCallChecker : public Checker < check::PreStmt<CallExpr> > {
-  mutable OwningPtr<BugType> BT;
+  mutable std::unique_ptr<BugType> BT;
 
 public:
   void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
@@ -35,7 +35,7 @@
       return;
 
     if (!BT)
-      BT.reset(new BugType("call to main", "example analyzer plugin"));
+      BT.reset(new BugType(this, "call to main", "example analyzer plugin"));
 
     BugReport *report = new BugReport(*BT, BT->getName(), N);
     report->addRange(Callee->getSourceRange());
diff --git a/examples/clang-interpreter/CMakeLists.txt b/examples/clang-interpreter/CMakeLists.txt
index 451b4b8..3c66881 100644
--- a/examples/clang-interpreter/CMakeLists.txt
+++ b/examples/clang-interpreter/CMakeLists.txt
@@ -1,15 +1,9 @@
 set(LLVM_LINK_COMPONENTS
-  jit
-  interpreter
-  nativecodegen
-  asmparser
-  bitreader
-  bitwriter
-  irreader
-  codegen
-  ipo
-  linker
-  selectiondag
+  Core
+  ExecutionEngine
+  JIT
+  Support
+  native
   )
 
 add_clang_executable(clang-interpreter
@@ -21,19 +15,8 @@
   )
 
 target_link_libraries(clang-interpreter
-  clangFrontend
-  clangSerialization
-  clangDriver
-  clangCodeGen
-  clangSema
-  clangStaticAnalyzerFrontend
-  clangStaticAnalyzerCheckers
-  clangStaticAnalyzerCore
-  clangAnalysis
-  clangRewriteCore
-  clangRewriteFrontend
-  clangAST
-  clangParse
-  clangLex
   clangBasic
+  clangCodeGen
+  clangDriver
+  clangFrontend
   )
diff --git a/examples/clang-interpreter/Makefile b/examples/clang-interpreter/Makefile
index 55a8e6f..d571337 100644
--- a/examples/clang-interpreter/Makefile
+++ b/examples/clang-interpreter/Makefile
@@ -16,11 +16,11 @@
 TOOL_NO_EXPORTS = 1
 
 LINK_COMPONENTS := jit interpreter nativecodegen bitreader bitwriter irreader \
-	ipo linker selectiondag asmparser instrumentation option
+	ipo linker selectiondag asmparser instrumentation objcarcopts option
 USEDLIBS = clangFrontend.a clangSerialization.a clangDriver.a clangCodeGen.a \
            clangParse.a clangSema.a clangStaticAnalyzerFrontend.a \
            clangStaticAnalyzerCheckers.a clangStaticAnalyzerCore.a \
-           clangAnalysis.a clangRewriteCore.a clangRewriteFrontend.a \
+           clangAnalysis.a clangRewrite.a clangRewriteFrontend.a \
            clangEdit.a clangAST.a clangLex.a clangBasic.a
 
 include $(CLANG_LEVEL)/Makefile
diff --git a/examples/clang-interpreter/main.cpp b/examples/clang-interpreter/main.cpp
index e00583d..8b8ccfd 100644
--- a/examples/clang-interpreter/main.cpp
+++ b/examples/clang-interpreter/main.cpp
@@ -16,7 +16,6 @@
 #include "clang/Frontend/CompilerInvocation.h"
 #include "clang/Frontend/FrontendDiagnostic.h"
 #include "clang/Frontend/TextDiagnosticPrinter.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ExecutionEngine/ExecutionEngine.h"
 #include "llvm/ExecutionEngine/JIT.h"
@@ -27,6 +26,7 @@
 #include "llvm/Support/Path.h"
 #include "llvm/Support/TargetSelect.h"
 #include "llvm/Support/raw_ostream.h"
+#include <memory>
 using namespace clang;
 using namespace clang::driver;
 
@@ -46,8 +46,8 @@
   llvm::InitializeNativeTarget();
 
   std::string Error;
-  OwningPtr<llvm::ExecutionEngine> EE(
-    llvm::ExecutionEngine::createJIT(Mod, &Error));
+  std::unique_ptr<llvm::ExecutionEngine> EE(
+      llvm::ExecutionEngine::create(Mod, /*ForceInterpreter*/ false, &Error));
   if (!EE) {
     llvm::errs() << "unable to make execution engine: " << Error << "\n";
     return 255;
@@ -75,15 +75,16 @@
 
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
   DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagClient);
-  Driver TheDriver(Path, llvm::sys::getProcessTriple(), "a.out", Diags);
+  Driver TheDriver(Path, llvm::sys::getProcessTriple(), Diags);
   TheDriver.setTitle("clang interpreter");
+  TheDriver.setCheckInputsExist(false);
 
   // FIXME: This is a hack to try to force the driver to do something we can
   // recognize. We need to extend the driver library to support this use model
   // (basically, exactly one input, and the operation mode is hard wired).
   SmallVector<const char *, 16> Args(argv, argv + argc);
   Args.push_back("-fsyntax-only");
-  OwningPtr<Compilation> C(TheDriver.BuildCompilation(Args));
+  std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(Args));
   if (!C)
     return 0;
 
@@ -108,7 +109,7 @@
 
   // Initialize a compiler invocation object from the clang (-cc1) arguments.
   const driver::ArgStringList &CCArgs = Cmd->getArguments();
-  OwningPtr<CompilerInvocation> CI(new CompilerInvocation);
+  std::unique_ptr<CompilerInvocation> CI(new CompilerInvocation);
   CompilerInvocation::CreateFromArgs(*CI,
                                      const_cast<const char **>(CCArgs.data()),
                                      const_cast<const char **>(CCArgs.data()) +
@@ -126,7 +127,7 @@
 
   // Create a compiler instance to handle the actual work.
   CompilerInstance Clang;
-  Clang.setInvocation(CI.take());
+  Clang.setInvocation(CI.release());
 
   // Create the compilers actual diagnostics engine.
   Clang.createDiagnostics();
@@ -140,7 +141,7 @@
       CompilerInvocation::GetResourcesPath(argv[0], MainAddr);
 
   // Create and execute the frontend to generate an LLVM bitcode module.
-  OwningPtr<CodeGenAction> Act(new EmitLLVMOnlyAction());
+  std::unique_ptr<CodeGenAction> Act(new EmitLLVMOnlyAction());
   if (!Clang.ExecuteAction(*Act))
     return 1;
 
diff --git a/include/clang-c/BuildSystem.h b/include/clang-c/BuildSystem.h
new file mode 100644
index 0000000..ed3e8d9
--- /dev/null
+++ b/include/clang-c/BuildSystem.h
@@ -0,0 +1,148 @@
+/*==-- clang-c/BuildSystem.h - Utilities for use by build systems -*- C -*-===*\
+|*                                                                            *|
+|*                     The LLVM Compiler Infrastructure                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This header provides various utilities for use by build systems.           *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef CLANG_C_BUILD_SYSTEM_H
+#define CLANG_C_BUILD_SYSTEM_H
+
+#include "clang-c/Platform.h"
+#include "clang-c/CXErrorCode.h"
+#include "clang-c/CXString.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup BUILD_SYSTEM Build system utilities
+ * @{
+ */
+
+/**
+ * \brief Return the timestamp for use with Clang's
+ * \c -fbuild-session-timestamp= option.
+ */
+CINDEX_LINKAGE unsigned long long clang_getBuildSessionTimestamp(void);
+
+/**
+ * \brief Object encapsulating information about overlaying virtual
+ * file/directories over the real file system.
+ */
+typedef struct CXVirtualFileOverlayImpl *CXVirtualFileOverlay;
+
+/**
+ * \brief Create a \c CXVirtualFileOverlay object.
+ * Must be disposed with \c clang_VirtualFileOverlay_dispose().
+ *
+ * \param options is reserved, always pass 0.
+ */
+CINDEX_LINKAGE CXVirtualFileOverlay
+clang_VirtualFileOverlay_create(unsigned options);
+
+/**
+ * \brief Map an absolute virtual file path to an absolute real one.
+ * The virtual path must be canonicalized (not contain "."/"..").
+ * \returns 0 for success, non-zero to indicate an error.
+ */
+CINDEX_LINKAGE enum CXErrorCode
+clang_VirtualFileOverlay_addFileMapping(CXVirtualFileOverlay,
+                                        const char *virtualPath,
+                                        const char *realPath);
+
+/**
+ * \brief Set the case sensitivity for the \c CXVirtualFileOverlay object.
+ * The \c CXVirtualFileOverlay object is case-sensitive by default, this
+ * option can be used to override the default.
+ * \returns 0 for success, non-zero to indicate an error.
+ */
+CINDEX_LINKAGE enum CXErrorCode
+clang_VirtualFileOverlay_setCaseSensitivity(CXVirtualFileOverlay,
+											int caseSensitive);
+
+/**
+ * \brief Write out the \c CXVirtualFileOverlay object to a char buffer.
+ *
+ * \param options is reserved, always pass 0.
+ * \param out_buffer_ptr pointer to receive the buffer pointer, which should be
+ * disposed using \c free().
+ * \param out_buffer_size pointer to receive the buffer size.
+ * \returns 0 for success, non-zero to indicate an error.
+ */
+CINDEX_LINKAGE enum CXErrorCode
+clang_VirtualFileOverlay_writeToBuffer(CXVirtualFileOverlay, unsigned options,
+                                       char **out_buffer_ptr,
+                                       unsigned *out_buffer_size);
+
+/**
+ * \brief Dispose a \c CXVirtualFileOverlay object.
+ */
+CINDEX_LINKAGE void clang_VirtualFileOverlay_dispose(CXVirtualFileOverlay);
+
+/**
+ * \brief Object encapsulating information about a module.map file.
+ */
+typedef struct CXModuleMapDescriptorImpl *CXModuleMapDescriptor;
+
+/**
+ * \brief Create a \c CXModuleMapDescriptor object.
+ * Must be disposed with \c clang_ModuleMapDescriptor_dispose().
+ *
+ * \param options is reserved, always pass 0.
+ */
+CINDEX_LINKAGE CXModuleMapDescriptor
+clang_ModuleMapDescriptor_create(unsigned options);
+
+/**
+ * \brief Sets the framework module name that the module.map describes.
+ * \returns 0 for success, non-zero to indicate an error.
+ */
+CINDEX_LINKAGE enum CXErrorCode
+clang_ModuleMapDescriptor_setFrameworkModuleName(CXModuleMapDescriptor,
+                                                 const char *name);
+
+/**
+ * \brief Sets the umbrealla header name that the module.map describes.
+ * \returns 0 for success, non-zero to indicate an error.
+ */
+CINDEX_LINKAGE enum CXErrorCode
+clang_ModuleMapDescriptor_setUmbrellaHeader(CXModuleMapDescriptor,
+                                            const char *name);
+
+/**
+ * \brief Write out the \c CXModuleMapDescriptor object to a char buffer.
+ *
+ * \param options is reserved, always pass 0.
+ * \param out_buffer_ptr pointer to receive the buffer pointer, which should be
+ * disposed using \c free().
+ * \param out_buffer_size pointer to receive the buffer size.
+ * \returns 0 for success, non-zero to indicate an error.
+ */
+CINDEX_LINKAGE enum CXErrorCode
+clang_ModuleMapDescriptor_writeToBuffer(CXModuleMapDescriptor, unsigned options,
+                                       char **out_buffer_ptr,
+                                       unsigned *out_buffer_size);
+
+/**
+ * \brief Dispose a \c CXModuleMapDescriptor object.
+ */
+CINDEX_LINKAGE void clang_ModuleMapDescriptor_dispose(CXModuleMapDescriptor);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CLANG_C_BUILD_SYSTEM_H */
+
diff --git a/include/clang-c/CXErrorCode.h b/include/clang-c/CXErrorCode.h
new file mode 100644
index 0000000..a026c95
--- /dev/null
+++ b/include/clang-c/CXErrorCode.h
@@ -0,0 +1,64 @@
+/*===-- clang-c/CXErrorCode.h - C Index Error Codes  --------------*- C -*-===*\
+|*                                                                            *|
+|*                     The LLVM Compiler Infrastructure                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This header provides the CXErrorCode enumerators.                          *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef CLANG_C_CXERRORCODE_H
+#define CLANG_C_CXERRORCODE_H
+
+#include "clang-c/Platform.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Error codes returned by libclang routines.
+ *
+ * Zero (\c CXError_Success) is the only error code indicating success.  Other
+ * error codes, including not yet assigned non-zero values, indicate errors.
+ */
+enum CXErrorCode {
+  /**
+   * \brief No error.
+   */
+  CXError_Success = 0,
+
+  /**
+   * \brief A generic error code, no further details are available.
+   *
+   * Errors of this kind can get their own specific error codes in future
+   * libclang versions.
+   */
+  CXError_Failure = 1,
+
+  /**
+   * \brief libclang crashed while performing the requested operation.
+   */
+  CXError_Crashed = 2,
+
+  /**
+   * \brief The function detected that the arguments violate the function
+   * contract.
+   */
+  CXError_InvalidArguments = 3,
+
+  /**
+   * \brief An AST deserialization error has occurred.
+   */
+  CXError_ASTReadError = 4
+};
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff --git a/include/clang-c/CXString.h b/include/clang-c/CXString.h
index 592c4dc..cf198cb 100644
--- a/include/clang-c/CXString.h
+++ b/include/clang-c/CXString.h
@@ -31,7 +31,7 @@
  * \brief A character string.
  *
  * The \c CXString type is used to return strings from the interface when
- * the ownership of that string might different from one call to the next.
+ * the ownership of that string might differ from one call to the next.
  * Use \c clang_getCString() to retrieve the string data and, once finished
  * with the string data, call \c clang_disposeString() to free the string.
  */
diff --git a/include/clang-c/Documentation.h b/include/clang-c/Documentation.h
new file mode 100644
index 0000000..ad2da07
--- /dev/null
+++ b/include/clang-c/Documentation.h
@@ -0,0 +1,554 @@
+/*==-- clang-c/Documentation.h - Utilities for comment processing -*- C -*-===*\
+|*                                                                            *|
+|*                     The LLVM Compiler Infrastructure                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This header provides a supplementary interface for inspecting              *|
+|* documentation comments.                                                    *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef CLANG_C_DOCUMENTATION_H
+#define CLANG_C_DOCUMENTATION_H
+
+#include "clang-c/Index.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup CINDEX_COMMENT Comment introspection
+ *
+ * The routines in this group provide access to information in documentation
+ * comments. These facilities are distinct from the core and may be subject to
+ * their own schedule of stability and deprecation.
+ *
+ * @{
+ */
+
+/**
+ * \brief A parsed comment.
+ */
+typedef struct {
+  const void *ASTNode;
+  CXTranslationUnit TranslationUnit;
+} CXComment;
+
+/**
+ * \brief Given a cursor that represents a documentable entity (e.g.,
+ * declaration), return the associated parsed comment as a
+ * \c CXComment_FullComment AST node.
+ */
+CINDEX_LINKAGE CXComment clang_Cursor_getParsedComment(CXCursor C);
+
+/**
+ * \brief Describes the type of the comment AST node (\c CXComment).  A comment
+ * node can be considered block content (e. g., paragraph), inline content
+ * (plain text) or neither (the root AST node).
+ */
+enum CXCommentKind {
+  /**
+   * \brief Null comment.  No AST node is constructed at the requested location
+   * because there is no text or a syntax error.
+   */
+  CXComment_Null = 0,
+
+  /**
+   * \brief Plain text.  Inline content.
+   */
+  CXComment_Text = 1,
+
+  /**
+   * \brief A command with word-like arguments that is considered inline content.
+   *
+   * For example: \\c command.
+   */
+  CXComment_InlineCommand = 2,
+
+  /**
+   * \brief HTML start tag with attributes (name-value pairs).  Considered
+   * inline content.
+   *
+   * For example:
+   * \verbatim
+   * <br> <br /> <a href="http://example.org/">
+   * \endverbatim
+   */
+  CXComment_HTMLStartTag = 3,
+
+  /**
+   * \brief HTML end tag.  Considered inline content.
+   *
+   * For example:
+   * \verbatim
+   * </a>
+   * \endverbatim
+   */
+  CXComment_HTMLEndTag = 4,
+
+  /**
+   * \brief A paragraph, contains inline comment.  The paragraph itself is
+   * block content.
+   */
+  CXComment_Paragraph = 5,
+
+  /**
+   * \brief A command that has zero or more word-like arguments (number of
+   * word-like arguments depends on command name) and a paragraph as an
+   * argument.  Block command is block content.
+   *
+   * Paragraph argument is also a child of the block command.
+   *
+   * For example: \\brief has 0 word-like arguments and a paragraph argument.
+   *
+   * AST nodes of special kinds that parser knows about (e. g., \\param
+   * command) have their own node kinds.
+   */
+  CXComment_BlockCommand = 6,
+
+  /**
+   * \brief A \\param or \\arg command that describes the function parameter
+   * (name, passing direction, description).
+   *
+   * For example: \\param [in] ParamName description.
+   */
+  CXComment_ParamCommand = 7,
+
+  /**
+   * \brief A \\tparam command that describes a template parameter (name and
+   * description).
+   *
+   * For example: \\tparam T description.
+   */
+  CXComment_TParamCommand = 8,
+
+  /**
+   * \brief A verbatim block command (e. g., preformatted code).  Verbatim
+   * block has an opening and a closing command and contains multiple lines of
+   * text (\c CXComment_VerbatimBlockLine child nodes).
+   *
+   * For example:
+   * \\verbatim
+   * aaa
+   * \\endverbatim
+   */
+  CXComment_VerbatimBlockCommand = 9,
+
+  /**
+   * \brief A line of text that is contained within a
+   * CXComment_VerbatimBlockCommand node.
+   */
+  CXComment_VerbatimBlockLine = 10,
+
+  /**
+   * \brief A verbatim line command.  Verbatim line has an opening command,
+   * a single line of text (up to the newline after the opening command) and
+   * has no closing command.
+   */
+  CXComment_VerbatimLine = 11,
+
+  /**
+   * \brief A full comment attached to a declaration, contains block content.
+   */
+  CXComment_FullComment = 12
+};
+
+/**
+ * \brief The most appropriate rendering mode for an inline command, chosen on
+ * command semantics in Doxygen.
+ */
+enum CXCommentInlineCommandRenderKind {
+  /**
+   * \brief Command argument should be rendered in a normal font.
+   */
+  CXCommentInlineCommandRenderKind_Normal,
+
+  /**
+   * \brief Command argument should be rendered in a bold font.
+   */
+  CXCommentInlineCommandRenderKind_Bold,
+
+  /**
+   * \brief Command argument should be rendered in a monospaced font.
+   */
+  CXCommentInlineCommandRenderKind_Monospaced,
+
+  /**
+   * \brief Command argument should be rendered emphasized (typically italic
+   * font).
+   */
+  CXCommentInlineCommandRenderKind_Emphasized
+};
+
+/**
+ * \brief Describes parameter passing direction for \\param or \\arg command.
+ */
+enum CXCommentParamPassDirection {
+  /**
+   * \brief The parameter is an input parameter.
+   */
+  CXCommentParamPassDirection_In,
+
+  /**
+   * \brief The parameter is an output parameter.
+   */
+  CXCommentParamPassDirection_Out,
+
+  /**
+   * \brief The parameter is an input and output parameter.
+   */
+  CXCommentParamPassDirection_InOut
+};
+
+/**
+ * \param Comment AST node of any kind.
+ *
+ * \returns the type of the AST node.
+ */
+CINDEX_LINKAGE enum CXCommentKind clang_Comment_getKind(CXComment Comment);
+
+/**
+ * \param Comment AST node of any kind.
+ *
+ * \returns number of children of the AST node.
+ */
+CINDEX_LINKAGE unsigned clang_Comment_getNumChildren(CXComment Comment);
+
+/**
+ * \param Comment AST node of any kind.
+ *
+ * \param ChildIdx child index (zero-based).
+ *
+ * \returns the specified child of the AST node.
+ */
+CINDEX_LINKAGE
+CXComment clang_Comment_getChild(CXComment Comment, unsigned ChildIdx);
+
+/**
+ * \brief A \c CXComment_Paragraph node is considered whitespace if it contains
+ * only \c CXComment_Text nodes that are empty or whitespace.
+ *
+ * Other AST nodes (except \c CXComment_Paragraph and \c CXComment_Text) are
+ * never considered whitespace.
+ *
+ * \returns non-zero if \c Comment is whitespace.
+ */
+CINDEX_LINKAGE unsigned clang_Comment_isWhitespace(CXComment Comment);
+
+/**
+ * \returns non-zero if \c Comment is inline content and has a newline
+ * immediately following it in the comment text.  Newlines between paragraphs
+ * do not count.
+ */
+CINDEX_LINKAGE
+unsigned clang_InlineContentComment_hasTrailingNewline(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_Text AST node.
+ *
+ * \returns text contained in the AST node.
+ */
+CINDEX_LINKAGE CXString clang_TextComment_getText(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_InlineCommand AST node.
+ *
+ * \returns name of the inline command.
+ */
+CINDEX_LINKAGE
+CXString clang_InlineCommandComment_getCommandName(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_InlineCommand AST node.
+ *
+ * \returns the most appropriate rendering mode, chosen on command
+ * semantics in Doxygen.
+ */
+CINDEX_LINKAGE enum CXCommentInlineCommandRenderKind
+clang_InlineCommandComment_getRenderKind(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_InlineCommand AST node.
+ *
+ * \returns number of command arguments.
+ */
+CINDEX_LINKAGE
+unsigned clang_InlineCommandComment_getNumArgs(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_InlineCommand AST node.
+ *
+ * \param ArgIdx argument index (zero-based).
+ *
+ * \returns text of the specified argument.
+ */
+CINDEX_LINKAGE
+CXString clang_InlineCommandComment_getArgText(CXComment Comment,
+                                               unsigned ArgIdx);
+
+/**
+ * \param Comment a \c CXComment_HTMLStartTag or \c CXComment_HTMLEndTag AST
+ * node.
+ *
+ * \returns HTML tag name.
+ */
+CINDEX_LINKAGE CXString clang_HTMLTagComment_getTagName(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_HTMLStartTag AST node.
+ *
+ * \returns non-zero if tag is self-closing (for example, &lt;br /&gt;).
+ */
+CINDEX_LINKAGE
+unsigned clang_HTMLStartTagComment_isSelfClosing(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_HTMLStartTag AST node.
+ *
+ * \returns number of attributes (name-value pairs) attached to the start tag.
+ */
+CINDEX_LINKAGE unsigned clang_HTMLStartTag_getNumAttrs(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_HTMLStartTag AST node.
+ *
+ * \param AttrIdx attribute index (zero-based).
+ *
+ * \returns name of the specified attribute.
+ */
+CINDEX_LINKAGE
+CXString clang_HTMLStartTag_getAttrName(CXComment Comment, unsigned AttrIdx);
+
+/**
+ * \param Comment a \c CXComment_HTMLStartTag AST node.
+ *
+ * \param AttrIdx attribute index (zero-based).
+ *
+ * \returns value of the specified attribute.
+ */
+CINDEX_LINKAGE
+CXString clang_HTMLStartTag_getAttrValue(CXComment Comment, unsigned AttrIdx);
+
+/**
+ * \param Comment a \c CXComment_BlockCommand AST node.
+ *
+ * \returns name of the block command.
+ */
+CINDEX_LINKAGE
+CXString clang_BlockCommandComment_getCommandName(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_BlockCommand AST node.
+ *
+ * \returns number of word-like arguments.
+ */
+CINDEX_LINKAGE
+unsigned clang_BlockCommandComment_getNumArgs(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_BlockCommand AST node.
+ *
+ * \param ArgIdx argument index (zero-based).
+ *
+ * \returns text of the specified word-like argument.
+ */
+CINDEX_LINKAGE
+CXString clang_BlockCommandComment_getArgText(CXComment Comment,
+                                              unsigned ArgIdx);
+
+/**
+ * \param Comment a \c CXComment_BlockCommand or
+ * \c CXComment_VerbatimBlockCommand AST node.
+ *
+ * \returns paragraph argument of the block command.
+ */
+CINDEX_LINKAGE
+CXComment clang_BlockCommandComment_getParagraph(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_ParamCommand AST node.
+ *
+ * \returns parameter name.
+ */
+CINDEX_LINKAGE
+CXString clang_ParamCommandComment_getParamName(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_ParamCommand AST node.
+ *
+ * \returns non-zero if the parameter that this AST node represents was found
+ * in the function prototype and \c clang_ParamCommandComment_getParamIndex
+ * function will return a meaningful value.
+ */
+CINDEX_LINKAGE
+unsigned clang_ParamCommandComment_isParamIndexValid(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_ParamCommand AST node.
+ *
+ * \returns zero-based parameter index in function prototype.
+ */
+CINDEX_LINKAGE
+unsigned clang_ParamCommandComment_getParamIndex(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_ParamCommand AST node.
+ *
+ * \returns non-zero if parameter passing direction was specified explicitly in
+ * the comment.
+ */
+CINDEX_LINKAGE
+unsigned clang_ParamCommandComment_isDirectionExplicit(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_ParamCommand AST node.
+ *
+ * \returns parameter passing direction.
+ */
+CINDEX_LINKAGE
+enum CXCommentParamPassDirection clang_ParamCommandComment_getDirection(
+                                                            CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_TParamCommand AST node.
+ *
+ * \returns template parameter name.
+ */
+CINDEX_LINKAGE
+CXString clang_TParamCommandComment_getParamName(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_TParamCommand AST node.
+ *
+ * \returns non-zero if the parameter that this AST node represents was found
+ * in the template parameter list and
+ * \c clang_TParamCommandComment_getDepth and
+ * \c clang_TParamCommandComment_getIndex functions will return a meaningful
+ * value.
+ */
+CINDEX_LINKAGE
+unsigned clang_TParamCommandComment_isParamPositionValid(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_TParamCommand AST node.
+ *
+ * \returns zero-based nesting depth of this parameter in the template parameter list.
+ *
+ * For example,
+ * \verbatim
+ *     template<typename C, template<typename T> class TT>
+ *     void test(TT<int> aaa);
+ * \endverbatim
+ * for C and TT nesting depth is 0,
+ * for T nesting depth is 1.
+ */
+CINDEX_LINKAGE
+unsigned clang_TParamCommandComment_getDepth(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_TParamCommand AST node.
+ *
+ * \returns zero-based parameter index in the template parameter list at a
+ * given nesting depth.
+ *
+ * For example,
+ * \verbatim
+ *     template<typename C, template<typename T> class TT>
+ *     void test(TT<int> aaa);
+ * \endverbatim
+ * for C and TT nesting depth is 0, so we can ask for index at depth 0:
+ * at depth 0 C's index is 0, TT's index is 1.
+ *
+ * For T nesting depth is 1, so we can ask for index at depth 0 and 1:
+ * at depth 0 T's index is 1 (same as TT's),
+ * at depth 1 T's index is 0.
+ */
+CINDEX_LINKAGE
+unsigned clang_TParamCommandComment_getIndex(CXComment Comment, unsigned Depth);
+
+/**
+ * \param Comment a \c CXComment_VerbatimBlockLine AST node.
+ *
+ * \returns text contained in the AST node.
+ */
+CINDEX_LINKAGE
+CXString clang_VerbatimBlockLineComment_getText(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_VerbatimLine AST node.
+ *
+ * \returns text contained in the AST node.
+ */
+CINDEX_LINKAGE CXString clang_VerbatimLineComment_getText(CXComment Comment);
+
+/**
+ * \brief Convert an HTML tag AST node to string.
+ *
+ * \param Comment a \c CXComment_HTMLStartTag or \c CXComment_HTMLEndTag AST
+ * node.
+ *
+ * \returns string containing an HTML tag.
+ */
+CINDEX_LINKAGE CXString clang_HTMLTagComment_getAsString(CXComment Comment);
+
+/**
+ * \brief Convert a given full parsed comment to an HTML fragment.
+ *
+ * Specific details of HTML layout are subject to change.  Don't try to parse
+ * this HTML back into an AST, use other APIs instead.
+ *
+ * Currently the following CSS classes are used:
+ * \li "para-brief" for \\brief paragraph and equivalent commands;
+ * \li "para-returns" for \\returns paragraph and equivalent commands;
+ * \li "word-returns" for the "Returns" word in \\returns paragraph.
+ *
+ * Function argument documentation is rendered as a \<dl\> list with arguments
+ * sorted in function prototype order.  CSS classes used:
+ * \li "param-name-index-NUMBER" for parameter name (\<dt\>);
+ * \li "param-descr-index-NUMBER" for parameter description (\<dd\>);
+ * \li "param-name-index-invalid" and "param-descr-index-invalid" are used if
+ * parameter index is invalid.
+ *
+ * Template parameter documentation is rendered as a \<dl\> list with
+ * parameters sorted in template parameter list order.  CSS classes used:
+ * \li "tparam-name-index-NUMBER" for parameter name (\<dt\>);
+ * \li "tparam-descr-index-NUMBER" for parameter description (\<dd\>);
+ * \li "tparam-name-index-other" and "tparam-descr-index-other" are used for
+ * names inside template template parameters;
+ * \li "tparam-name-index-invalid" and "tparam-descr-index-invalid" are used if
+ * parameter position is invalid.
+ *
+ * \param Comment a \c CXComment_FullComment AST node.
+ *
+ * \returns string containing an HTML fragment.
+ */
+CINDEX_LINKAGE CXString clang_FullComment_getAsHTML(CXComment Comment);
+
+/**
+ * \brief Convert a given full parsed comment to an XML document.
+ *
+ * A Relax NG schema for the XML can be found in comment-xml-schema.rng file
+ * inside clang source tree.
+ *
+ * \param Comment a \c CXComment_FullComment AST node.
+ *
+ * \returns string containing an XML document.
+ */
+CINDEX_LINKAGE CXString clang_FullComment_getAsXML(CXComment Comment);
+
+/**
+ * @}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CLANG_C_DOCUMENTATION_H */
+
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
index 95d54c2..f69f567 100644
--- a/include/clang-c/Index.h
+++ b/include/clang-c/Index.h
@@ -19,7 +19,9 @@
 #include <time.h>
 
 #include "clang-c/Platform.h"
+#include "clang-c/CXErrorCode.h"
 #include "clang-c/CXString.h"
+#include "clang-c/BuildSystem.h"
 
 /**
  * \brief The version constants for the libclang API.
@@ -30,7 +32,7 @@
  * compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
  */
 #define CINDEX_VERSION_MAJOR 0
-#define CINDEX_VERSION_MINOR 20
+#define CINDEX_VERSION_MINOR 27
 
 #define CINDEX_VERSION_ENCODE(major, minor) ( \
       ((major) * 10000)                       \
@@ -599,6 +601,32 @@
 CINDEX_LINKAGE CXSourceLocation clang_getRangeEnd(CXSourceRange range);
 
 /**
+ * \brief Identifies an array of ranges.
+ */
+typedef struct {
+  /** \brief The number of ranges in the \c ranges array. */
+  unsigned count;
+  /**
+   * \brief An array of \c CXSourceRanges.
+   */
+  CXSourceRange *ranges;
+} CXSourceRangeList;
+
+/**
+ * \brief Retrieve all ranges that were skipped by the preprocessor.
+ *
+ * The preprocessor will skip lines when they are surrounded by an
+ * if/ifdef/ifndef directive whose condition does not evaluate to true.
+ */
+CINDEX_LINKAGE CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit tu,
+                                                         CXFile file);
+
+/**
+ * \brief Destroy the given \c CXSourceRangeList.
+ */
+CINDEX_LINKAGE void clang_disposeSourceRangeList(CXSourceRangeList *ranges);
+
+/**
  * @}
  */
 
@@ -1050,10 +1078,27 @@
                                          struct CXUnsavedFile *unsaved_files);
 
 /**
- * \brief Create a translation unit from an AST file (-emit-ast).
+ * \brief Same as \c clang_createTranslationUnit2, but returns
+ * the \c CXTranslationUnit instead of an error code.  In case of an error this
+ * routine returns a \c NULL \c CXTranslationUnit, without further detailed
+ * error codes.
  */
-CINDEX_LINKAGE CXTranslationUnit clang_createTranslationUnit(CXIndex,
-                                             const char *ast_filename);
+CINDEX_LINKAGE CXTranslationUnit clang_createTranslationUnit(
+    CXIndex CIdx,
+    const char *ast_filename);
+
+/**
+ * \brief Create a translation unit from an AST file (\c -emit-ast).
+ *
+ * \param[out] out_TU A non-NULL pointer to store the created
+ * \c CXTranslationUnit.
+ *
+ * \returns Zero on success, otherwise returns an error code.
+ */
+CINDEX_LINKAGE enum CXErrorCode clang_createTranslationUnit2(
+    CXIndex CIdx,
+    const char *ast_filename,
+    CXTranslationUnit *out_TU);
 
 /**
  * \brief Flags that control the creation of translation units.
@@ -1167,7 +1212,22 @@
  * set of optimizations enabled may change from one version to the next.
  */
 CINDEX_LINKAGE unsigned clang_defaultEditingTranslationUnitOptions(void);
-  
+
+/**
+ * \brief Same as \c clang_parseTranslationUnit2, but returns
+ * the \c CXTranslationUnit instead of an error code.  In case of an error this
+ * routine returns a \c NULL \c CXTranslationUnit, without further detailed
+ * error codes.
+ */
+CINDEX_LINKAGE CXTranslationUnit
+clang_parseTranslationUnit(CXIndex CIdx,
+                           const char *source_filename,
+                           const char *const *command_line_args,
+                           int num_command_line_args,
+                           struct CXUnsavedFile *unsaved_files,
+                           unsigned num_unsaved_files,
+                           unsigned options);
+
 /**
  * \brief Parse the given source file and the translation unit corresponding
  * to that file.
@@ -1182,7 +1242,7 @@
  * associated.
  *
  * \param source_filename The name of the source file to load, or NULL if the
- * source file is included in \p command_line_args.
+ * source file is included in \c command_line_args.
  *
  * \param command_line_args The command-line arguments that would be
  * passed to the \c clang executable if it were being invoked out-of-process.
@@ -1191,7 +1251,7 @@
  * '-emit-ast', '-fsyntax-only' (which is the default), and '-o \<output file>'.
  *
  * \param num_command_line_args The number of command-line arguments in
- * \p command_line_args.
+ * \c command_line_args.
  *
  * \param unsaved_files the files that have not yet been saved to disk
  * but may be required for parsing, including the contents of
@@ -1206,18 +1266,22 @@
  * is managed but not its compilation. This should be a bitwise OR of the
  * CXTranslationUnit_XXX flags.
  *
- * \returns A new translation unit describing the parsed code and containing
- * any diagnostics produced by the compiler. If there is a failure from which
- * the compiler cannot recover, returns NULL.
+ * \param[out] out_TU A non-NULL pointer to store the created
+ * \c CXTranslationUnit, describing the parsed code and containing any
+ * diagnostics produced by the compiler.
+ *
+ * \returns Zero on success, otherwise returns an error code.
  */
-CINDEX_LINKAGE CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
-                                                    const char *source_filename,
-                                         const char * const *command_line_args,
-                                                      int num_command_line_args,
-                                            struct CXUnsavedFile *unsaved_files,
-                                                     unsigned num_unsaved_files,
-                                                            unsigned options);
-  
+CINDEX_LINKAGE enum CXErrorCode
+clang_parseTranslationUnit2(CXIndex CIdx,
+                            const char *source_filename,
+                            const char *const *command_line_args,
+                            int num_command_line_args,
+                            struct CXUnsavedFile *unsaved_files,
+                            unsigned num_unsaved_files,
+                            unsigned options,
+                            CXTranslationUnit *out_TU);
+
 /**
  * \brief Flags that control how translation units are saved.
  *
@@ -1369,10 +1433,11 @@
  * The function \c clang_defaultReparseOptions() produces a default set of
  * options recommended for most uses, based on the translation unit.
  *
- * \returns 0 if the sources could be reparsed. A non-zero value will be
+ * \returns 0 if the sources could be reparsed.  A non-zero error code will be
  * returned if reparsing was impossible, such that the translation unit is
- * invalid. In such cases, the only valid call for \p TU is 
- * \c clang_disposeTranslationUnit(TU).
+ * invalid. In such cases, the only valid call for \c TU is
+ * \c clang_disposeTranslationUnit(TU).  The error codes returned by this
+ * routine are described by the \c CXErrorCode enum.
  */
 CINDEX_LINKAGE int clang_reparseTranslationUnit(CXTranslationUnit TU,
                                                 unsigned num_unsaved_files,
@@ -1669,7 +1734,7 @@
 
   /**
    * \brief An expression that refers to some value declaration, such
-   * as a function, varible, or enumerator.
+   * as a function, variable, or enumerator.
    */
   CXCursor_DeclRefExpr                   = 101,
 
@@ -1907,7 +1972,7 @@
    */
   CXCursor_ObjCBoolLiteralExpr           = 145,
 
-  /** \brief Represents the "self" expression in a ObjC method.
+  /** \brief Represents the "self" expression in an Objective-C method.
    */
   CXCursor_ObjCSelfExpr                  = 146,
 
@@ -2070,7 +2135,67 @@
    */
   CXCursor_OMPParallelDirective          = 232,
 
-  CXCursor_LastStmt                      = CXCursor_OMPParallelDirective,
+  /** \brief OpenMP simd directive.
+   */
+  CXCursor_OMPSimdDirective              = 233,
+
+  /** \brief OpenMP for directive.
+   */
+  CXCursor_OMPForDirective               = 234,
+
+  /** \brief OpenMP sections directive.
+   */
+  CXCursor_OMPSectionsDirective          = 235,
+
+  /** \brief OpenMP section directive.
+   */
+  CXCursor_OMPSectionDirective           = 236,
+
+  /** \brief OpenMP single directive.
+   */
+  CXCursor_OMPSingleDirective            = 237,
+
+  /** \brief OpenMP parallel for directive.
+   */
+  CXCursor_OMPParallelForDirective       = 238,
+
+  /** \brief OpenMP parallel sections directive.
+   */
+  CXCursor_OMPParallelSectionsDirective  = 239,
+
+  /** \brief OpenMP task directive.
+   */
+  CXCursor_OMPTaskDirective              = 240,
+
+  /** \brief OpenMP master directive.
+   */
+  CXCursor_OMPMasterDirective            = 241,
+
+  /** \brief OpenMP critical directive.
+   */
+  CXCursor_OMPCriticalDirective          = 242,
+
+  /** \brief OpenMP taskyield directive.
+   */
+  CXCursor_OMPTaskyieldDirective         = 243,
+
+  /** \brief OpenMP barrier directive.
+   */
+  CXCursor_OMPBarrierDirective           = 244,
+
+  /** \brief OpenMP taskwait directive.
+   */
+  CXCursor_OMPTaskwaitDirective          = 245,
+
+  /** \brief OpenMP flush directive.
+   */
+  CXCursor_OMPFlushDirective             = 246,
+
+  /** \brief Windows Structured Exception Handling's leave statement.
+   */
+  CXCursor_SEHLeaveStmt                  = 247,
+
+  CXCursor_LastStmt                      = CXCursor_SEHLeaveStmt,
 
   /**
    * \brief Cursor that represents the translation unit itself.
@@ -2096,8 +2221,15 @@
   CXCursor_AnnotateAttr                  = 406,
   CXCursor_AsmLabelAttr                  = 407,
   CXCursor_PackedAttr                    = 408,
-  CXCursor_LastAttr                      = CXCursor_PackedAttr,
-     
+  CXCursor_PureAttr                      = 409,
+  CXCursor_ConstAttr                     = 410,
+  CXCursor_NoDuplicateAttr               = 411,
+  CXCursor_CUDAConstantAttr              = 412,
+  CXCursor_CUDADeviceAttr                = 413,
+  CXCursor_CUDAGlobalAttr                = 414,
+  CXCursor_CUDAHostAttr                  = 415,
+  CXCursor_LastAttr                      = CXCursor_CUDAHostAttr,
+
   /* Preprocessing */
   CXCursor_PreprocessingDirective        = 500,
   CXCursor_MacroDefinition               = 501,
@@ -2141,14 +2273,6 @@
 } CXCursor;
 
 /**
- * \brief A comment AST node.
- */
-typedef struct {
-  const void *ASTNode;
-  CXTranslationUnit TranslationUnit;
-} CXComment;
-
-/**
  * \defgroup CINDEX_CURSOR_MANIP Cursor manipulations
  *
  * @{
@@ -2369,7 +2493,7 @@
 /**
  * \brief Describe the "language" of the entity referred to by a cursor.
  */
-CINDEX_LINKAGE enum CXLanguageKind {
+enum CXLanguageKind {
   CXLanguage_Invalid = 0,
   CXLanguage_C,
   CXLanguage_ObjC,
@@ -2435,10 +2559,10 @@
  * void C::f() { }
  * \endcode
  *
- * In the out-of-line definition of \c C::f, the semantic parent is the 
+ * In the out-of-line definition of \c C::f, the semantic parent is
  * the class \c C, of which this function is a member. The lexical parent is
  * the place where the declaration actually occurs in the source code; in this
- * case, the definition occurs in the translation unit. In general, the 
+ * case, the definition occurs in the translation unit. In general, the
  * lexical parent for a given entity can change without affecting the semantics
  * of the program, and the lexical parent of different declarations of the
  * same entity may be different. Changing the semantic parent of a declaration,
@@ -2470,10 +2594,10 @@
  * void C::f() { }
  * \endcode
  *
- * In the out-of-line definition of \c C::f, the semantic parent is the 
+ * In the out-of-line definition of \c C::f, the semantic parent is
  * the class \c C, of which this function is a member. The lexical parent is
  * the place where the declaration actually occurs in the source code; in this
- * case, the definition occurs in the translation unit. In general, the 
+ * case, the definition occurs in the translation unit. In general, the
  * lexical parent for a given entity can change without affecting the semantics
  * of the program, and the lexical parent of different declarations of the
  * same entity may be different. Changing the semantic parent of a declaration,
@@ -2598,7 +2722,7 @@
  *
  * The extent of a cursor starts with the file/line/column pointing at the
  * first character within the source construct that the cursor refers to and
- * ends with the last character withinin that source construct. For a
+ * ends with the last character within that source construct. For a
  * declaration, the extent covers the declaration itself. For a reference,
  * the extent covers the location of the reference (e.g., where the referenced
  * entity was actually used).
@@ -2620,7 +2744,7 @@
  */
 enum CXTypeKind {
   /**
-   * \brief Reprents an invalid type (e.g., where no type is available).
+   * \brief Represents an invalid type (e.g., where no type is available).
    */
   CXType_Invalid = 0,
 
@@ -2854,14 +2978,14 @@
 CINDEX_LINKAGE enum CXCallingConv clang_getFunctionTypeCallingConv(CXType T);
 
 /**
- * \brief Retrieve the result type associated with a function type.
+ * \brief Retrieve the return type associated with a function type.
  *
  * If a non-function type is passed in, an invalid type is returned.
  */
 CINDEX_LINKAGE CXType clang_getResultType(CXType T);
 
 /**
- * \brief Retrieve the number of non-variadic arguments associated with a
+ * \brief Retrieve the number of non-variadic parameters associated with a
  * function type.
  *
  * If a non-function type is passed in, -1 is returned.
@@ -2869,7 +2993,7 @@
 CINDEX_LINKAGE int clang_getNumArgTypes(CXType T);
 
 /**
- * \brief Retrieve the type of an argument of a function type.
+ * \brief Retrieve the type of a parameter of a function type.
  *
  * If a non-function type is passed in or the function does not have enough
  * parameters, an invalid type is returned.
@@ -2882,7 +3006,7 @@
 CINDEX_LINKAGE unsigned clang_isFunctionTypeVariadic(CXType T);
 
 /**
- * \brief Retrieve the result type associated with a given cursor.
+ * \brief Retrieve the return type associated with a given cursor.
  *
  * This only returns a valid type if the cursor refers to a function or method.
  */
@@ -3012,6 +3136,24 @@
 };
 
 /**
+ * \brief Returns the number of template arguments for given class template
+ * specialization, or -1 if type \c T is not a class template specialization.
+ *
+ * Variadic argument packs count as only one argument, and can not be inspected
+ * further.
+ */
+CINDEX_LINKAGE int clang_Type_getNumTemplateArguments(CXType T);
+
+/**
+ * \brief Returns the type template argument of a template class specialization
+ * at given index.
+ *
+ * This function only returns template type arguments and does not handle
+ * template template arguments or variadic packs.
+ */
+CINDEX_LINKAGE CXType clang_Type_getTemplateArgumentAsType(CXType T, unsigned i);
+
+/**
  * \brief Retrieve the ref-qualifier kind of a function or method.
  *
  * The ref-qualifier is returned for C++ functions or methods. For other types
@@ -3274,8 +3416,8 @@
 /**
  * \brief Retrieve a range for a piece that forms the cursors spelling name.
  * Most of the times there is only one range for the complete spelling but for
- * objc methods and objc message expressions, there are multiple pieces for each
- * selector identifier.
+ * Objective-C methods and Objective-C message expressions, there are multiple
+ * pieces for each selector identifier.
  * 
  * \param pieceIndex the index of the spelling name piece. If this is greater
  * than the actual number of pieces, it will return a NULL (invalid) range.
@@ -3371,25 +3513,25 @@
 
 
 /**
- * \brief If the cursor points to a selector identifier in a objc method or
- * message expression, this returns the selector index.
+ * \brief If the cursor points to a selector identifier in an Objective-C
+ * method or message expression, this returns the selector index.
  *
  * After getting a cursor with #clang_getCursor, this can be called to
  * determine if the location points to a selector identifier.
  *
- * \returns The selector index if the cursor is an objc method or message
+ * \returns The selector index if the cursor is an Objective-C method or message
  * expression and the cursor is pointing to a selector identifier, or -1
  * otherwise.
  */
 CINDEX_LINKAGE int clang_Cursor_getObjCSelectorIndex(CXCursor);
 
 /**
- * \brief Given a cursor pointing to a C++ method call or an ObjC message,
- * returns non-zero if the method/message is "dynamic", meaning:
+ * \brief Given a cursor pointing to a C++ method call or an Objective-C
+ * message, returns non-zero if the method/message is "dynamic", meaning:
  * 
  * For a C++ method: the call is virtual.
- * For an ObjC message: the receiver is an object instance, not 'super' or a
- * specific class.
+ * For an Objective-C message: the receiver is an object instance, not 'super'
+ * or a specific class.
  * 
  * If the method/message is "static" or the cursor does not point to a
  * method/message, it will return zero.
@@ -3397,8 +3539,8 @@
 CINDEX_LINKAGE int clang_Cursor_isDynamicCall(CXCursor C);
 
 /**
- * \brief Given a cursor pointing to an ObjC message, returns the CXType of the
- * receiver.
+ * \brief Given a cursor pointing to an Objective-C message, returns the CXType
+ * of the receiver.
  */
 CINDEX_LINKAGE CXType clang_Cursor_getReceiverType(CXCursor C);
 
@@ -3433,7 +3575,7 @@
 
 /**
  * \brief 'Qualifiers' written next to the return and parameter types in
- * ObjC method declarations.
+ * Objective-C method declarations.
  */
 typedef enum {
   CXObjCDeclQualifier_None = 0x0,
@@ -3446,15 +3588,16 @@
 } CXObjCDeclQualifierKind;
 
 /**
- * \brief Given a cursor that represents an ObjC method or parameter
- * declaration, return the associated ObjC qualifiers for the return type or the
- * parameter respectively. The bits are formed from CXObjCDeclQualifierKind.
+ * \brief Given a cursor that represents an Objective-C method or parameter
+ * declaration, return the associated Objective-C qualifiers for the return
+ * type or the parameter respectively. The bits are formed from
+ * CXObjCDeclQualifierKind.
  */
 CINDEX_LINKAGE unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C);
 
 /**
- * \brief Given a cursor that represents an ObjC method or property declaration,
- * return non-zero if the declaration was affected by "@optional".
+ * \brief Given a cursor that represents an Objective-C method or property
+ * declaration, return non-zero if the declaration was affected by "@optional".
  * Returns zero if the cursor is not such a declaration or it is "@required".
  */
 CINDEX_LINKAGE unsigned clang_Cursor_isObjCOptional(CXCursor C);
@@ -3485,13 +3628,6 @@
 CINDEX_LINKAGE CXString clang_Cursor_getBriefCommentText(CXCursor C);
 
 /**
- * \brief Given a cursor that represents a documentable entity (e.g.,
- * declaration), return the associated parsed comment as a
- * \c CXComment_FullComment AST node.
- */
-CINDEX_LINKAGE CXComment clang_Cursor_getParsedComment(CXCursor C);
-
-/**
  * @}
  */
 
@@ -3511,6 +3647,12 @@
 CINDEX_LINKAGE CXModule clang_Cursor_getModule(CXCursor C);
 
 /**
+ * \brief Given a CXFile header file, return the module that contains it, if one
+ * exists.
+ */
+CINDEX_LINKAGE CXModule clang_getModuleForFile(CXTranslationUnit, CXFile);
+
+/**
  * \param Module a module object.
  *
  * \returns the module file where the provided module object came from.
@@ -3543,6 +3685,13 @@
 /**
  * \param Module a module object.
  *
+ * \returns non-zero if the module is a system one.
+ */
+CINDEX_LINKAGE int clang_Module_isSystem(CXModule Module);
+
+/**
+ * \param Module a module object.
+ *
  * \returns the number of top level headers associated with this module.
  */
 CINDEX_LINKAGE unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit,
@@ -3564,514 +3713,6 @@
  */
 
 /**
- * \defgroup CINDEX_COMMENT Comment AST introspection
- *
- * The routines in this group provide access to information in the
- * documentation comment ASTs.
- *
- * @{
- */
-
-/**
- * \brief Describes the type of the comment AST node (\c CXComment).  A comment
- * node can be considered block content (e. g., paragraph), inline content
- * (plain text) or neither (the root AST node).
- */
-enum CXCommentKind {
-  /**
-   * \brief Null comment.  No AST node is constructed at the requested location
-   * because there is no text or a syntax error.
-   */
-  CXComment_Null = 0,
-
-  /**
-   * \brief Plain text.  Inline content.
-   */
-  CXComment_Text = 1,
-
-  /**
-   * \brief A command with word-like arguments that is considered inline content.
-   *
-   * For example: \\c command.
-   */
-  CXComment_InlineCommand = 2,
-
-  /**
-   * \brief HTML start tag with attributes (name-value pairs).  Considered
-   * inline content.
-   *
-   * For example:
-   * \verbatim
-   * <br> <br /> <a href="http://example.org/">
-   * \endverbatim
-   */
-  CXComment_HTMLStartTag = 3,
-
-  /**
-   * \brief HTML end tag.  Considered inline content.
-   *
-   * For example:
-   * \verbatim
-   * </a>
-   * \endverbatim
-   */
-  CXComment_HTMLEndTag = 4,
-
-  /**
-   * \brief A paragraph, contains inline comment.  The paragraph itself is
-   * block content.
-   */
-  CXComment_Paragraph = 5,
-
-  /**
-   * \brief A command that has zero or more word-like arguments (number of
-   * word-like arguments depends on command name) and a paragraph as an
-   * argument.  Block command is block content.
-   *
-   * Paragraph argument is also a child of the block command.
-   *
-   * For example: \\brief has 0 word-like arguments and a paragraph argument.
-   *
-   * AST nodes of special kinds that parser knows about (e. g., \\param
-   * command) have their own node kinds.
-   */
-  CXComment_BlockCommand = 6,
-
-  /**
-   * \brief A \\param or \\arg command that describes the function parameter
-   * (name, passing direction, description).
-   *
-   * For example: \\param [in] ParamName description.
-   */
-  CXComment_ParamCommand = 7,
-
-  /**
-   * \brief A \\tparam command that describes a template parameter (name and
-   * description).
-   *
-   * For example: \\tparam T description.
-   */
-  CXComment_TParamCommand = 8,
-
-  /**
-   * \brief A verbatim block command (e. g., preformatted code).  Verbatim
-   * block has an opening and a closing command and contains multiple lines of
-   * text (\c CXComment_VerbatimBlockLine child nodes).
-   *
-   * For example:
-   * \\verbatim
-   * aaa
-   * \\endverbatim
-   */
-  CXComment_VerbatimBlockCommand = 9,
-
-  /**
-   * \brief A line of text that is contained within a
-   * CXComment_VerbatimBlockCommand node.
-   */
-  CXComment_VerbatimBlockLine = 10,
-
-  /**
-   * \brief A verbatim line command.  Verbatim line has an opening command,
-   * a single line of text (up to the newline after the opening command) and
-   * has no closing command.
-   */
-  CXComment_VerbatimLine = 11,
-
-  /**
-   * \brief A full comment attached to a declaration, contains block content.
-   */
-  CXComment_FullComment = 12
-};
-
-/**
- * \brief The most appropriate rendering mode for an inline command, chosen on
- * command semantics in Doxygen.
- */
-enum CXCommentInlineCommandRenderKind {
-  /**
-   * \brief Command argument should be rendered in a normal font.
-   */
-  CXCommentInlineCommandRenderKind_Normal,
-
-  /**
-   * \brief Command argument should be rendered in a bold font.
-   */
-  CXCommentInlineCommandRenderKind_Bold,
-
-  /**
-   * \brief Command argument should be rendered in a monospaced font.
-   */
-  CXCommentInlineCommandRenderKind_Monospaced,
-
-  /**
-   * \brief Command argument should be rendered emphasized (typically italic
-   * font).
-   */
-  CXCommentInlineCommandRenderKind_Emphasized
-};
-
-/**
- * \brief Describes parameter passing direction for \\param or \\arg command.
- */
-enum CXCommentParamPassDirection {
-  /**
-   * \brief The parameter is an input parameter.
-   */
-  CXCommentParamPassDirection_In,
-
-  /**
-   * \brief The parameter is an output parameter.
-   */
-  CXCommentParamPassDirection_Out,
-
-  /**
-   * \brief The parameter is an input and output parameter.
-   */
-  CXCommentParamPassDirection_InOut
-};
-
-/**
- * \param Comment AST node of any kind.
- *
- * \returns the type of the AST node.
- */
-CINDEX_LINKAGE enum CXCommentKind clang_Comment_getKind(CXComment Comment);
-
-/**
- * \param Comment AST node of any kind.
- *
- * \returns number of children of the AST node.
- */
-CINDEX_LINKAGE unsigned clang_Comment_getNumChildren(CXComment Comment);
-
-/**
- * \param Comment AST node of any kind.
- *
- * \param ChildIdx child index (zero-based).
- *
- * \returns the specified child of the AST node.
- */
-CINDEX_LINKAGE
-CXComment clang_Comment_getChild(CXComment Comment, unsigned ChildIdx);
-
-/**
- * \brief A \c CXComment_Paragraph node is considered whitespace if it contains
- * only \c CXComment_Text nodes that are empty or whitespace.
- *
- * Other AST nodes (except \c CXComment_Paragraph and \c CXComment_Text) are
- * never considered whitespace.
- *
- * \returns non-zero if \c Comment is whitespace.
- */
-CINDEX_LINKAGE unsigned clang_Comment_isWhitespace(CXComment Comment);
-
-/**
- * \returns non-zero if \c Comment is inline content and has a newline
- * immediately following it in the comment text.  Newlines between paragraphs
- * do not count.
- */
-CINDEX_LINKAGE
-unsigned clang_InlineContentComment_hasTrailingNewline(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_Text AST node.
- *
- * \returns text contained in the AST node.
- */
-CINDEX_LINKAGE CXString clang_TextComment_getText(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_InlineCommand AST node.
- *
- * \returns name of the inline command.
- */
-CINDEX_LINKAGE
-CXString clang_InlineCommandComment_getCommandName(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_InlineCommand AST node.
- *
- * \returns the most appropriate rendering mode, chosen on command
- * semantics in Doxygen.
- */
-CINDEX_LINKAGE enum CXCommentInlineCommandRenderKind
-clang_InlineCommandComment_getRenderKind(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_InlineCommand AST node.
- *
- * \returns number of command arguments.
- */
-CINDEX_LINKAGE
-unsigned clang_InlineCommandComment_getNumArgs(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_InlineCommand AST node.
- *
- * \param ArgIdx argument index (zero-based).
- *
- * \returns text of the specified argument.
- */
-CINDEX_LINKAGE
-CXString clang_InlineCommandComment_getArgText(CXComment Comment,
-                                               unsigned ArgIdx);
-
-/**
- * \param Comment a \c CXComment_HTMLStartTag or \c CXComment_HTMLEndTag AST
- * node.
- *
- * \returns HTML tag name.
- */
-CINDEX_LINKAGE CXString clang_HTMLTagComment_getTagName(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_HTMLStartTag AST node.
- *
- * \returns non-zero if tag is self-closing (for example, &lt;br /&gt;).
- */
-CINDEX_LINKAGE
-unsigned clang_HTMLStartTagComment_isSelfClosing(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_HTMLStartTag AST node.
- *
- * \returns number of attributes (name-value pairs) attached to the start tag.
- */
-CINDEX_LINKAGE unsigned clang_HTMLStartTag_getNumAttrs(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_HTMLStartTag AST node.
- *
- * \param AttrIdx attribute index (zero-based).
- *
- * \returns name of the specified attribute.
- */
-CINDEX_LINKAGE
-CXString clang_HTMLStartTag_getAttrName(CXComment Comment, unsigned AttrIdx);
-
-/**
- * \param Comment a \c CXComment_HTMLStartTag AST node.
- *
- * \param AttrIdx attribute index (zero-based).
- *
- * \returns value of the specified attribute.
- */
-CINDEX_LINKAGE
-CXString clang_HTMLStartTag_getAttrValue(CXComment Comment, unsigned AttrIdx);
-
-/**
- * \param Comment a \c CXComment_BlockCommand AST node.
- *
- * \returns name of the block command.
- */
-CINDEX_LINKAGE
-CXString clang_BlockCommandComment_getCommandName(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_BlockCommand AST node.
- *
- * \returns number of word-like arguments.
- */
-CINDEX_LINKAGE
-unsigned clang_BlockCommandComment_getNumArgs(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_BlockCommand AST node.
- *
- * \param ArgIdx argument index (zero-based).
- *
- * \returns text of the specified word-like argument.
- */
-CINDEX_LINKAGE
-CXString clang_BlockCommandComment_getArgText(CXComment Comment,
-                                              unsigned ArgIdx);
-
-/**
- * \param Comment a \c CXComment_BlockCommand or
- * \c CXComment_VerbatimBlockCommand AST node.
- *
- * \returns paragraph argument of the block command.
- */
-CINDEX_LINKAGE
-CXComment clang_BlockCommandComment_getParagraph(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_ParamCommand AST node.
- *
- * \returns parameter name.
- */
-CINDEX_LINKAGE
-CXString clang_ParamCommandComment_getParamName(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_ParamCommand AST node.
- *
- * \returns non-zero if the parameter that this AST node represents was found
- * in the function prototype and \c clang_ParamCommandComment_getParamIndex
- * function will return a meaningful value.
- */
-CINDEX_LINKAGE
-unsigned clang_ParamCommandComment_isParamIndexValid(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_ParamCommand AST node.
- *
- * \returns zero-based parameter index in function prototype.
- */
-CINDEX_LINKAGE
-unsigned clang_ParamCommandComment_getParamIndex(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_ParamCommand AST node.
- *
- * \returns non-zero if parameter passing direction was specified explicitly in
- * the comment.
- */
-CINDEX_LINKAGE
-unsigned clang_ParamCommandComment_isDirectionExplicit(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_ParamCommand AST node.
- *
- * \returns parameter passing direction.
- */
-CINDEX_LINKAGE
-enum CXCommentParamPassDirection clang_ParamCommandComment_getDirection(
-                                                            CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_TParamCommand AST node.
- *
- * \returns template parameter name.
- */
-CINDEX_LINKAGE
-CXString clang_TParamCommandComment_getParamName(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_TParamCommand AST node.
- *
- * \returns non-zero if the parameter that this AST node represents was found
- * in the template parameter list and
- * \c clang_TParamCommandComment_getDepth and
- * \c clang_TParamCommandComment_getIndex functions will return a meaningful
- * value.
- */
-CINDEX_LINKAGE
-unsigned clang_TParamCommandComment_isParamPositionValid(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_TParamCommand AST node.
- *
- * \returns zero-based nesting depth of this parameter in the template parameter list.
- *
- * For example,
- * \verbatim
- *     template<typename C, template<typename T> class TT>
- *     void test(TT<int> aaa);
- * \endverbatim
- * for C and TT nesting depth is 0,
- * for T nesting depth is 1.
- */
-CINDEX_LINKAGE
-unsigned clang_TParamCommandComment_getDepth(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_TParamCommand AST node.
- *
- * \returns zero-based parameter index in the template parameter list at a
- * given nesting depth.
- *
- * For example,
- * \verbatim
- *     template<typename C, template<typename T> class TT>
- *     void test(TT<int> aaa);
- * \endverbatim
- * for C and TT nesting depth is 0, so we can ask for index at depth 0:
- * at depth 0 C's index is 0, TT's index is 1.
- *
- * For T nesting depth is 1, so we can ask for index at depth 0 and 1:
- * at depth 0 T's index is 1 (same as TT's),
- * at depth 1 T's index is 0.
- */
-CINDEX_LINKAGE
-unsigned clang_TParamCommandComment_getIndex(CXComment Comment, unsigned Depth);
-
-/**
- * \param Comment a \c CXComment_VerbatimBlockLine AST node.
- *
- * \returns text contained in the AST node.
- */
-CINDEX_LINKAGE
-CXString clang_VerbatimBlockLineComment_getText(CXComment Comment);
-
-/**
- * \param Comment a \c CXComment_VerbatimLine AST node.
- *
- * \returns text contained in the AST node.
- */
-CINDEX_LINKAGE CXString clang_VerbatimLineComment_getText(CXComment Comment);
-
-/**
- * \brief Convert an HTML tag AST node to string.
- *
- * \param Comment a \c CXComment_HTMLStartTag or \c CXComment_HTMLEndTag AST
- * node.
- *
- * \returns string containing an HTML tag.
- */
-CINDEX_LINKAGE CXString clang_HTMLTagComment_getAsString(CXComment Comment);
-
-/**
- * \brief Convert a given full parsed comment to an HTML fragment.
- *
- * Specific details of HTML layout are subject to change.  Don't try to parse
- * this HTML back into an AST, use other APIs instead.
- *
- * Currently the following CSS classes are used:
- * \li "para-brief" for \\brief paragraph and equivalent commands;
- * \li "para-returns" for \\returns paragraph and equivalent commands;
- * \li "word-returns" for the "Returns" word in \\returns paragraph.
- *
- * Function argument documentation is rendered as a \<dl\> list with arguments
- * sorted in function prototype order.  CSS classes used:
- * \li "param-name-index-NUMBER" for parameter name (\<dt\>);
- * \li "param-descr-index-NUMBER" for parameter description (\<dd\>);
- * \li "param-name-index-invalid" and "param-descr-index-invalid" are used if
- * parameter index is invalid.
- *
- * Template parameter documentation is rendered as a \<dl\> list with
- * parameters sorted in template parameter list order.  CSS classes used:
- * \li "tparam-name-index-NUMBER" for parameter name (\<dt\>);
- * \li "tparam-descr-index-NUMBER" for parameter description (\<dd\>);
- * \li "tparam-name-index-other" and "tparam-descr-index-other" are used for
- * names inside template template parameters;
- * \li "tparam-name-index-invalid" and "tparam-descr-index-invalid" are used if
- * parameter position is invalid.
- *
- * \param Comment a \c CXComment_FullComment AST node.
- *
- * \returns string containing an HTML fragment.
- */
-CINDEX_LINKAGE CXString clang_FullComment_getAsHTML(CXComment Comment);
-
-/**
- * \brief Convert a given full parsed comment to an XML document.
- *
- * A Relax NG schema for the XML can be found in comment-xml-schema.rng file
- * inside clang source tree.
- *
- * \param Comment a \c CXComment_FullComment AST node.
- *
- * \returns string containing an XML document.
- */
-CINDEX_LINKAGE CXString clang_FullComment_getAsXML(CXComment Comment);
-
-/**
- * @}
- */
-
-/**
  * \defgroup CINDEX_CPP C++ AST introspection
  *
  * The routines in this group provide access information in the ASTs specific
@@ -4100,6 +3741,12 @@
 CINDEX_LINKAGE unsigned clang_CXXMethod_isVirtual(CXCursor C);
 
 /**
+ * \brief Determine if a C++ member function or member function template is
+ * declared 'const'.
+ */
+CINDEX_LINKAGE unsigned clang_CXXMethod_isConst(CXCursor C);
+
+/**
  * \brief Given a cursor that represents a template, determine
  * the cursor kind of the specializations would be generated by instantiating
  * the template.
@@ -4189,7 +3836,7 @@
    * Non-contiguous names occur in Objective-C when a selector with two or more
    * parameters is used, or in C++ when using an operator:
    * \code
-   * [object doSomething:here withValue:there]; // ObjC
+   * [object doSomething:here withValue:there]; // Objective-C
    * return some_vector[1]; // C++
    * \endcode
    */
@@ -5022,7 +4669,7 @@
                                              unsigned Index);
 
 /**
- * \brief Determines what compeltions are appropriate for the context
+ * \brief Determines what completions are appropriate for the context
  * the given code completion.
  * 
  * \param Results the code completion results to query
@@ -5472,7 +5119,7 @@
   const CXIdxContainerInfo *declAsContainer;
   /**
    * \brief Whether the declaration exists in code or was created implicitly
-   * by the compiler, e.g. implicit objc methods for properties.
+   * by the compiler, e.g. implicit Objective-C methods for properties.
    */
   int isImplicit;
   const CXIdxAttrInfo *const *attributes;
@@ -5545,8 +5192,8 @@
    */
   CXIdxEntityRef_Direct = 1,
   /**
-   * \brief An implicit reference, e.g. a reference of an ObjC method via the
-   * dot syntax.
+   * \brief An implicit reference, e.g. a reference of an Objective-C method
+   * via the dot syntax.
    */
   CXIdxEntityRef_Implicit = 2
 } CXIdxEntityRefKind;
@@ -5740,7 +5387,7 @@
 
   /**
    * \brief Skip a function/method body that was already parsed during an
-   * indexing session assosiated with a \c CXIndexAction object.
+   * indexing session associated with a \c CXIndexAction object.
    * Bodies in system headers are always skipped.
    */
   CXIndexOpt_SkipParsedBodiesInSession = 0x10
@@ -5763,11 +5410,12 @@
  * \param index_options A bitmask of options that affects how indexing is
  * performed. This should be a bitwise OR of the CXIndexOpt_XXX flags.
  *
- * \param out_TU [out] pointer to store a CXTranslationUnit that can be reused
- * after indexing is finished. Set to NULL if you do not require it.
+ * \param[out] out_TU pointer to store a \c CXTranslationUnit that can be
+ * reused after indexing is finished. Set to \c NULL if you do not require it.
  *
- * \returns If there is a failure from which the there is no recovery, returns
- * non-zero, otherwise returns 0.
+ * \returns 0 on success or if there were errors from which the compiler could
+ * recover.  If there is a failure from which the there is no recovery, returns
+ * a non-zero \c CXErrorCode.
  *
  * The rest of the parameters are the same as #clang_parseTranslationUnit.
  */
@@ -5836,6 +5484,9 @@
  * @}
  */
 
+/* Include the comment API for compatibility. This will eventually go away. */
+#include "clang-c/Documentation.h"
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/clang-c/module.modulemap b/include/clang-c/module.modulemap
new file mode 100644
index 0000000..95a59d6
--- /dev/null
+++ b/include/clang-c/module.modulemap
@@ -0,0 +1,4 @@
+module Clang_C {
+  umbrella "."
+  module * { export * }
+}
diff --git a/include/clang/ARCMigrate/ARCMT.h b/include/clang/ARCMigrate/ARCMT.h
index 196f6c0..ad4f23c 100644
--- a/include/clang/ARCMigrate/ARCMT.h
+++ b/include/clang/ARCMigrate/ARCMT.h
@@ -113,7 +113,7 @@
     virtual void remove(CharSourceRange range) { }
   };
 
-  bool applyTransform(TransformFn trans, RewriteListener *listener = 0);
+  bool applyTransform(TransformFn trans, RewriteListener *listener = nullptr);
 
   FileRemapper &getRemapper() { return Remapper; }
 };
diff --git a/include/clang/ARCMigrate/ARCMTActions.h b/include/clang/ARCMigrate/ARCMTActions.h
index 45c8b4e..b3e74b9 100644
--- a/include/clang/ARCMigrate/ARCMTActions.h
+++ b/include/clang/ARCMigrate/ARCMTActions.h
@@ -12,14 +12,14 @@
 
 #include "clang/ARCMigrate/FileRemapper.h"
 #include "clang/Frontend/FrontendAction.h"
-#include "llvm/ADT/OwningPtr.h"
+#include <memory>
 
 namespace clang {
 namespace arcmt {
 
 class CheckAction : public WrapperFrontendAction {
 protected:
-  virtual bool BeginInvocation(CompilerInstance &CI);
+  bool BeginInvocation(CompilerInstance &CI) override;
 
 public:
   CheckAction(FrontendAction *WrappedAction);
@@ -27,7 +27,7 @@
 
 class ModifyAction : public WrapperFrontendAction {
 protected:
-  virtual bool BeginInvocation(CompilerInstance &CI);
+  bool BeginInvocation(CompilerInstance &CI) override;
 
 public:
   ModifyAction(FrontendAction *WrappedAction);
@@ -36,9 +36,9 @@
 class MigrateSourceAction : public ASTFrontendAction {
   FileRemapper Remapper;
 protected:
-  virtual bool BeginInvocation(CompilerInstance &CI);
-  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
-                                         StringRef InFile);
+  bool BeginInvocation(CompilerInstance &CI) override;
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
 };
 
 class MigrateAction : public WrapperFrontendAction {
@@ -46,7 +46,7 @@
   std::string PlistOut;
   bool EmitPremigrationARCErros;
 protected:
-  virtual bool BeginInvocation(CompilerInstance &CI);
+  bool BeginInvocation(CompilerInstance &CI) override;
 
 public:
   MigrateAction(FrontendAction *WrappedAction, StringRef migrateDir,
@@ -65,8 +65,9 @@
                     unsigned migrateAction);
 
 protected:
-  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,StringRef InFile);
-  virtual bool BeginInvocation(CompilerInstance &CI);
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
+  bool BeginInvocation(CompilerInstance &CI) override;
 };
 
 }
diff --git a/include/clang/ARCMigrate/FileRemapper.h b/include/clang/ARCMigrate/FileRemapper.h
index f7677cc..e094301 100644
--- a/include/clang/ARCMigrate/FileRemapper.h
+++ b/include/clang/ARCMigrate/FileRemapper.h
@@ -12,9 +12,9 @@
 
 #include "clang/Basic/LLVM.h"
 #include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/PointerUnion.h"
 #include "llvm/ADT/StringRef.h"
+#include <memory>
 
 namespace llvm {
   class MemoryBuffer;
@@ -30,7 +30,7 @@
 
 class FileRemapper {
   // FIXME: Reuse the same FileManager for multiple ASTContexts.
-  OwningPtr<FileManager> FileMgr;
+  std::unique_ptr<FileManager> FileMgr;
 
   typedef llvm::PointerUnion<const FileEntry *, llvm::MemoryBuffer *> Target;
   typedef llvm::DenseMap<const FileEntry *, Target> MappingsTy;
@@ -56,8 +56,6 @@
 
   void applyMappings(PreprocessorOptions &PPOpts) const;
 
-  void transferMappingsAndClear(PreprocessorOptions &PPOpts);
-
   void clear(StringRef outputDir = StringRef());
 
 private:
diff --git a/include/clang/AST/APValue.h b/include/clang/AST/APValue.h
index b4fd2af..e58c219 100644
--- a/include/clang/AST/APValue.h
+++ b/include/clang/AST/APValue.h
@@ -80,7 +80,7 @@
   struct Vec {
     APValue *Elts;
     unsigned NumElts;
-    Vec() : Elts(0), NumElts(0) {}
+    Vec() : Elts(nullptr), NumElts(0) {}
     ~Vec() { delete[] Elts; }
   };
   struct Arr {
@@ -108,34 +108,33 @@
   };
   struct MemberPointerData;
 
-  enum {
-    MaxSize = (sizeof(ComplexAPSInt) > sizeof(ComplexAPFloat) ?
-               sizeof(ComplexAPSInt) : sizeof(ComplexAPFloat))
-  };
+  // We ensure elsewhere that Data is big enough for LV and MemberPointerData.
+  typedef llvm::AlignedCharArrayUnion<void *, APSInt, APFloat, ComplexAPSInt,
+                                      ComplexAPFloat, Vec, Arr, StructData,
+                                      UnionData, AddrLabelDiffData> DataType;
+  static const size_t DataSize = sizeof(DataType);
 
-  union {
-    void *Aligner;
-    char Data[MaxSize];
-  };
+  DataType Data;
 
 public:
   APValue() : Kind(Uninitialized) {}
-  explicit APValue(const APSInt &I) : Kind(Uninitialized) {
-    MakeInt(); setInt(I);
+  explicit APValue(APSInt I) : Kind(Uninitialized) {
+    MakeInt(); setInt(std::move(I));
   }
-  explicit APValue(const APFloat &F) : Kind(Uninitialized) {
-    MakeFloat(); setFloat(F);
+  explicit APValue(APFloat F) : Kind(Uninitialized) {
+    MakeFloat(); setFloat(std::move(F));
   }
   explicit APValue(const APValue *E, unsigned N) : Kind(Uninitialized) {
     MakeVector(); setVector(E, N);
   }
-  APValue(const APSInt &R, const APSInt &I) : Kind(Uninitialized) {
-    MakeComplexInt(); setComplexInt(R, I);
+  APValue(APSInt R, APSInt I) : Kind(Uninitialized) {
+    MakeComplexInt(); setComplexInt(std::move(R), std::move(I));
   }
-  APValue(const APFloat &R, const APFloat &I) : Kind(Uninitialized) {
-    MakeComplexFloat(); setComplexFloat(R, I);
+  APValue(APFloat R, APFloat I) : Kind(Uninitialized) {
+    MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I));
   }
   APValue(const APValue &RHS);
+  APValue(APValue &&RHS) : Kind(Uninitialized) { swap(RHS); }
   APValue(LValueBase B, const CharUnits &O, NoLValuePath N, unsigned CallIndex)
       : Kind(Uninitialized) {
     MakeLValue(); setLValue(B, O, N, CallIndex);
@@ -200,7 +199,7 @@
 
   APSInt &getInt() {
     assert(isInt() && "Invalid accessor");
-    return *(APSInt*)(char*)Data;
+    return *(APSInt*)(char*)Data.buffer;
   }
   const APSInt &getInt() const {
     return const_cast<APValue*>(this)->getInt();
@@ -208,7 +207,7 @@
 
   APFloat &getFloat() {
     assert(isFloat() && "Invalid accessor");
-    return *(APFloat*)(char*)Data;
+    return *(APFloat*)(char*)Data.buffer;
   }
   const APFloat &getFloat() const {
     return const_cast<APValue*>(this)->getFloat();
@@ -216,7 +215,7 @@
 
   APSInt &getComplexIntReal() {
     assert(isComplexInt() && "Invalid accessor");
-    return ((ComplexAPSInt*)(char*)Data)->Real;
+    return ((ComplexAPSInt*)(char*)Data.buffer)->Real;
   }
   const APSInt &getComplexIntReal() const {
     return const_cast<APValue*>(this)->getComplexIntReal();
@@ -224,7 +223,7 @@
 
   APSInt &getComplexIntImag() {
     assert(isComplexInt() && "Invalid accessor");
-    return ((ComplexAPSInt*)(char*)Data)->Imag;
+    return ((ComplexAPSInt*)(char*)Data.buffer)->Imag;
   }
   const APSInt &getComplexIntImag() const {
     return const_cast<APValue*>(this)->getComplexIntImag();
@@ -232,7 +231,7 @@
 
   APFloat &getComplexFloatReal() {
     assert(isComplexFloat() && "Invalid accessor");
-    return ((ComplexAPFloat*)(char*)Data)->Real;
+    return ((ComplexAPFloat*)(char*)Data.buffer)->Real;
   }
   const APFloat &getComplexFloatReal() const {
     return const_cast<APValue*>(this)->getComplexFloatReal();
@@ -240,7 +239,7 @@
 
   APFloat &getComplexFloatImag() {
     assert(isComplexFloat() && "Invalid accessor");
-    return ((ComplexAPFloat*)(char*)Data)->Imag;
+    return ((ComplexAPFloat*)(char*)Data.buffer)->Imag;
   }
   const APFloat &getComplexFloatImag() const {
     return const_cast<APValue*>(this)->getComplexFloatImag();
@@ -259,20 +258,20 @@
   APValue &getVectorElt(unsigned I) {
     assert(isVector() && "Invalid accessor");
     assert(I < getVectorLength() && "Index out of range");
-    return ((Vec*)(char*)Data)->Elts[I];
+    return ((Vec*)(char*)Data.buffer)->Elts[I];
   }
   const APValue &getVectorElt(unsigned I) const {
     return const_cast<APValue*>(this)->getVectorElt(I);
   }
   unsigned getVectorLength() const {
     assert(isVector() && "Invalid accessor");
-    return ((const Vec*)(const void *)Data)->NumElts;
+    return ((const Vec*)(const void *)Data.buffer)->NumElts;
   }
 
   APValue &getArrayInitializedElt(unsigned I) {
     assert(isArray() && "Invalid accessor");
     assert(I < getArrayInitializedElts() && "Index out of range");
-    return ((Arr*)(char*)Data)->Elts[I];
+    return ((Arr*)(char*)Data.buffer)->Elts[I];
   }
   const APValue &getArrayInitializedElt(unsigned I) const {
     return const_cast<APValue*>(this)->getArrayInitializedElt(I);
@@ -283,35 +282,35 @@
   APValue &getArrayFiller() {
     assert(isArray() && "Invalid accessor");
     assert(hasArrayFiller() && "No array filler");
-    return ((Arr*)(char*)Data)->Elts[getArrayInitializedElts()];
+    return ((Arr*)(char*)Data.buffer)->Elts[getArrayInitializedElts()];
   }
   const APValue &getArrayFiller() const {
     return const_cast<APValue*>(this)->getArrayFiller();
   }
   unsigned getArrayInitializedElts() const {
     assert(isArray() && "Invalid accessor");
-    return ((const Arr*)(const void *)Data)->NumElts;
+    return ((const Arr*)(const void *)Data.buffer)->NumElts;
   }
   unsigned getArraySize() const {
     assert(isArray() && "Invalid accessor");
-    return ((const Arr*)(const void *)Data)->ArrSize;
+    return ((const Arr*)(const void *)Data.buffer)->ArrSize;
   }
 
   unsigned getStructNumBases() const {
     assert(isStruct() && "Invalid accessor");
-    return ((const StructData*)(const char*)Data)->NumBases;
+    return ((const StructData*)(const char*)Data.buffer)->NumBases;
   }
   unsigned getStructNumFields() const {
     assert(isStruct() && "Invalid accessor");
-    return ((const StructData*)(const char*)Data)->NumFields;
+    return ((const StructData*)(const char*)Data.buffer)->NumFields;
   }
   APValue &getStructBase(unsigned i) {
     assert(isStruct() && "Invalid accessor");
-    return ((StructData*)(char*)Data)->Elts[i];
+    return ((StructData*)(char*)Data.buffer)->Elts[i];
   }
   APValue &getStructField(unsigned i) {
     assert(isStruct() && "Invalid accessor");
-    return ((StructData*)(char*)Data)->Elts[getStructNumBases() + i];
+    return ((StructData*)(char*)Data.buffer)->Elts[getStructNumBases() + i];
   }
   const APValue &getStructBase(unsigned i) const {
     return const_cast<APValue*>(this)->getStructBase(i);
@@ -322,11 +321,11 @@
 
   const FieldDecl *getUnionField() const {
     assert(isUnion() && "Invalid accessor");
-    return ((const UnionData*)(const char*)Data)->Field;
+    return ((const UnionData*)(const char*)Data.buffer)->Field;
   }
   APValue &getUnionValue() {
     assert(isUnion() && "Invalid accessor");
-    return *((UnionData*)(char*)Data)->Value;
+    return *((UnionData*)(char*)Data.buffer)->Value;
   }
   const APValue &getUnionValue() const {
     return const_cast<APValue*>(this)->getUnionValue();
@@ -338,41 +337,41 @@
 
   const AddrLabelExpr* getAddrLabelDiffLHS() const {
     assert(isAddrLabelDiff() && "Invalid accessor");
-    return ((const AddrLabelDiffData*)(const char*)Data)->LHSExpr;
+    return ((const AddrLabelDiffData*)(const char*)Data.buffer)->LHSExpr;
   }
   const AddrLabelExpr* getAddrLabelDiffRHS() const {
     assert(isAddrLabelDiff() && "Invalid accessor");
-    return ((const AddrLabelDiffData*)(const char*)Data)->RHSExpr;
+    return ((const AddrLabelDiffData*)(const char*)Data.buffer)->RHSExpr;
   }
 
-  void setInt(const APSInt &I) {
+  void setInt(APSInt I) {
     assert(isInt() && "Invalid accessor");
-    *(APSInt*)(char*)Data = I;
+    *(APSInt *)(char *)Data.buffer = std::move(I);
   }
-  void setFloat(const APFloat &F) {
+  void setFloat(APFloat F) {
     assert(isFloat() && "Invalid accessor");
-    *(APFloat*)(char*)Data = F;
+    *(APFloat *)(char *)Data.buffer = std::move(F);
   }
   void setVector(const APValue *E, unsigned N) {
     assert(isVector() && "Invalid accessor");
-    ((Vec*)(char*)Data)->Elts = new APValue[N];
-    ((Vec*)(char*)Data)->NumElts = N;
+    ((Vec*)(char*)Data.buffer)->Elts = new APValue[N];
+    ((Vec*)(char*)Data.buffer)->NumElts = N;
     for (unsigned i = 0; i != N; ++i)
-      ((Vec*)(char*)Data)->Elts[i] = E[i];
+      ((Vec*)(char*)Data.buffer)->Elts[i] = E[i];
   }
-  void setComplexInt(const APSInt &R, const APSInt &I) {
+  void setComplexInt(APSInt R, APSInt I) {
     assert(R.getBitWidth() == I.getBitWidth() &&
            "Invalid complex int (type mismatch).");
     assert(isComplexInt() && "Invalid accessor");
-    ((ComplexAPSInt*)(char*)Data)->Real = R;
-    ((ComplexAPSInt*)(char*)Data)->Imag = I;
+    ((ComplexAPSInt *)(char *)Data.buffer)->Real = std::move(R);
+    ((ComplexAPSInt *)(char *)Data.buffer)->Imag = std::move(I);
   }
-  void setComplexFloat(const APFloat &R, const APFloat &I) {
+  void setComplexFloat(APFloat R, APFloat I) {
     assert(&R.getSemantics() == &I.getSemantics() &&
            "Invalid complex float (type mismatch).");
     assert(isComplexFloat() && "Invalid accessor");
-    ((ComplexAPFloat*)(char*)Data)->Real = R;
-    ((ComplexAPFloat*)(char*)Data)->Imag = I;
+    ((ComplexAPFloat *)(char *)Data.buffer)->Real = std::move(R);
+    ((ComplexAPFloat *)(char *)Data.buffer)->Imag = std::move(I);
   }
   void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
                  unsigned CallIndex);
@@ -381,13 +380,13 @@
                  unsigned CallIndex);
   void setUnion(const FieldDecl *Field, const APValue &Value) {
     assert(isUnion() && "Invalid accessor");
-    ((UnionData*)(char*)Data)->Field = Field;
-    *((UnionData*)(char*)Data)->Value = Value;
+    ((UnionData*)(char*)Data.buffer)->Field = Field;
+    *((UnionData*)(char*)Data.buffer)->Value = Value;
   }
   void setAddrLabelDiff(const AddrLabelExpr* LHSExpr,
                         const AddrLabelExpr* RHSExpr) {
-    ((AddrLabelDiffData*)(char*)Data)->LHSExpr = LHSExpr;
-    ((AddrLabelDiffData*)(char*)Data)->RHSExpr = RHSExpr;
+    ((AddrLabelDiffData*)(char*)Data.buffer)->LHSExpr = LHSExpr;
+    ((AddrLabelDiffData*)(char*)Data.buffer)->RHSExpr = RHSExpr;
   }
 
   /// Assign by swapping from a copy of the RHS.
@@ -404,46 +403,46 @@
   }
   void MakeInt() {
     assert(isUninit() && "Bad state change");
-    new ((void*)Data) APSInt(1);
+    new ((void*)Data.buffer) APSInt(1);
     Kind = Int;
   }
   void MakeFloat() {
     assert(isUninit() && "Bad state change");
-    new ((void*)(char*)Data) APFloat(0.0);
+    new ((void*)(char*)Data.buffer) APFloat(0.0);
     Kind = Float;
   }
   void MakeVector() {
     assert(isUninit() && "Bad state change");
-    new ((void*)(char*)Data) Vec();
+    new ((void*)(char*)Data.buffer) Vec();
     Kind = Vector;
   }
   void MakeComplexInt() {
     assert(isUninit() && "Bad state change");
-    new ((void*)(char*)Data) ComplexAPSInt();
+    new ((void*)(char*)Data.buffer) ComplexAPSInt();
     Kind = ComplexInt;
   }
   void MakeComplexFloat() {
     assert(isUninit() && "Bad state change");
-    new ((void*)(char*)Data) ComplexAPFloat();
+    new ((void*)(char*)Data.buffer) ComplexAPFloat();
     Kind = ComplexFloat;
   }
   void MakeLValue();
   void MakeArray(unsigned InitElts, unsigned Size);
   void MakeStruct(unsigned B, unsigned M) {
     assert(isUninit() && "Bad state change");
-    new ((void*)(char*)Data) StructData(B, M);
+    new ((void*)(char*)Data.buffer) StructData(B, M);
     Kind = Struct;
   }
   void MakeUnion() {
     assert(isUninit() && "Bad state change");
-    new ((void*)(char*)Data) UnionData();
+    new ((void*)(char*)Data.buffer) UnionData();
     Kind = Union;
   }
   void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
                          ArrayRef<const CXXRecordDecl*> Path);
   void MakeAddrLabelDiff() {
     assert(isUninit() && "Bad state change");
-    new ((void*)(char*)Data) AddrLabelDiffData();
+    new ((void*)(char*)Data.buffer) AddrLabelDiffData();
     Kind = AddrLabelDiff;
   }
 };
diff --git a/include/clang/AST/ASTConsumer.h b/include/clang/AST/ASTConsumer.h
index 7b6fa94..736a10b 100644
--- a/include/clang/AST/ASTConsumer.h
+++ b/include/clang/AST/ASTConsumer.h
@@ -18,10 +18,10 @@
 
 namespace clang {
   class ASTContext;
+  class CXXMethodDecl;
   class CXXRecordDecl;
   class Decl;
   class DeclGroupRef;
-  class HandleTagDeclDefinition;
   class ASTMutationListener;
   class ASTDeserializationListener; // layering violation because void* is ugly
   class SemaConsumer; // layering violation required for safe SemaConsumer
@@ -50,13 +50,15 @@
   virtual void Initialize(ASTContext &Context) {}
 
   /// HandleTopLevelDecl - Handle the specified top-level declaration.  This is
-  /// called by the parser to process every top-level Decl*. Note that D can be
-  /// the head of a chain of Decls (e.g. for `int a, b` the chain will have two
-  /// elements). Use Decl::getNextDeclarator() to walk the chain.
+  /// called by the parser to process every top-level Decl*.
   ///
   /// \returns true to continue parsing, or false to abort parsing.
   virtual bool HandleTopLevelDecl(DeclGroupRef D);
 
+  /// \brief This callback is invoked each time an inline method definition is
+  /// completed.
+  virtual void HandleInlineMethodDefinition(CXXMethodDecl *D) {}
+
   /// HandleInterestingDecl - Handle the specified interesting declaration. This
   /// is called by the AST reader when deserializing things that might interest
   /// the consumer. The default implementation forwards to HandleTopLevelDecl.
@@ -136,12 +138,12 @@
   /// \brief If the consumer is interested in entities getting modified after
   /// their initial creation, it should return a pointer to
   /// an ASTMutationListener here.
-  virtual ASTMutationListener *GetASTMutationListener() { return 0; }
+  virtual ASTMutationListener *GetASTMutationListener() { return nullptr; }
 
   /// \brief If the consumer is interested in entities being deserialized from
   /// AST files, it should return a pointer to a ASTDeserializationListener here
   virtual ASTDeserializationListener *GetASTDeserializationListener() {
-    return 0;
+    return nullptr;
   }
 
   /// PrintStats - If desired, print any statistics.
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index f420e85..8134f6b 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -19,6 +19,7 @@
 #include "clang/AST/CanonicalType.h"
 #include "clang/AST/CommentCommandTraits.h"
 #include "clang/AST/Decl.h"
+#include "clang/AST/ExternalASTSource.h"
 #include "clang/AST/NestedNameSpecifier.h"
 #include "clang/AST/PrettyPrinter.h"
 #include "clang/AST/RawCommentList.h"
@@ -33,10 +34,10 @@
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/TinyPtrVector.h"
 #include "llvm/Support/Allocator.h"
+#include <memory>
 #include <vector>
 
 namespace llvm {
@@ -51,7 +52,6 @@
   class CharUnits;
   class DiagnosticsEngine;
   class Expr;
-  class ExternalASTSource;
   class ASTMutationListener;
   class IdentifierTable;
   class MaterializeTemporaryExpr;
@@ -66,6 +66,7 @@
   class UnresolvedSetIterator;
   class UsingDecl;
   class UsingShadowDecl;
+  class VTableContextBase;
 
   namespace Builtin { class Context; }
 
@@ -82,7 +83,7 @@
   mutable llvm::FoldingSet<ExtQuals> ExtQualNodes;
   mutable llvm::FoldingSet<ComplexType> ComplexTypes;
   mutable llvm::FoldingSet<PointerType> PointerTypes;
-  mutable llvm::FoldingSet<DecayedType> DecayedTypes;
+  mutable llvm::FoldingSet<AdjustedType> AdjustedTypes;
   mutable llvm::FoldingSet<BlockPointerType> BlockPointerTypes;
   mutable llvm::FoldingSet<LValueReferenceType> LValueReferenceTypes;
   mutable llvm::FoldingSet<RValueReferenceType> RValueReferenceTypes;
@@ -364,6 +365,7 @@
   /// \brief Side-table of mangling numbers for declarations which rarely
   /// need them (like static local vars).
   llvm::DenseMap<const NamedDecl *, unsigned> MangleNumbers;
+  llvm::DenseMap<const VarDecl *, unsigned> StaticLocalNumbers;
 
   /// \brief Mapping that stores parameterIndex values for ParmVarDecls when
   /// that value exceeds the bitfield size of ParmVarDeclBits.ParameterIndex.
@@ -392,7 +394,7 @@
   PartialDiagnostic::StorageAllocator DiagAllocator;
 
   /// \brief The current C++ ABI.
-  OwningPtr<CXXABI> ABI;
+  std::unique_ptr<CXXABI> ABI;
   CXXABI *createCXXABI(const TargetInfo &T);
 
   /// \brief The logical -> physical address space map.
@@ -415,14 +417,16 @@
   SelectorTable &Selectors;
   Builtin::Context &BuiltinInfo;
   mutable DeclarationNameTable DeclarationNames;
-  OwningPtr<ExternalASTSource> ExternalSource;
+  IntrusiveRefCntPtr<ExternalASTSource> ExternalSource;
   ASTMutationListener *Listener;
 
   /// \brief Contains parents of a node.
-  typedef llvm::SmallVector<ast_type_traits::DynTypedNode, 1> ParentVector;
+  typedef llvm::SmallVector<ast_type_traits::DynTypedNode, 2> ParentVector;
 
   /// \brief Maps from a node to its parents.
-  typedef llvm::DenseMap<const void *, ParentVector> ParentMap;
+  typedef llvm::DenseMap<const void *,
+                         llvm::PointerUnion<ast_type_traits::DynTypedNode *,
+                                            ParentVector *>> ParentMap;
 
   /// \brief Returns the parents of the given node.
   ///
@@ -601,9 +605,9 @@
   ///
   /// \param OriginalDecl if not NULL, is set to declaration AST node that had
   /// the comment, if the comment we found comes from a redeclaration.
-  const RawComment *getRawCommentForAnyRedecl(
-                                      const Decl *D,
-                                      const Decl **OriginalDecl = NULL) const;
+  const RawComment *
+  getRawCommentForAnyRedecl(const Decl *D,
+                            const Decl **OriginalDecl = nullptr) const;
 
   /// Return parsed documentation comment attached to a given declaration.
   /// Returns NULL if no comment is attached.
@@ -624,6 +628,43 @@
 private:
   mutable comments::CommandTraits CommentCommandTraits;
 
+  /// \brief Iterator that visits import declarations.
+  class import_iterator {
+    ImportDecl *Import;
+
+  public:
+    typedef ImportDecl               *value_type;
+    typedef ImportDecl               *reference;
+    typedef ImportDecl               *pointer;
+    typedef int                       difference_type;
+    typedef std::forward_iterator_tag iterator_category;
+
+    import_iterator() : Import() {}
+    explicit import_iterator(ImportDecl *Import) : Import(Import) {}
+
+    reference operator*() const { return Import; }
+    pointer operator->() const { return Import; }
+
+    import_iterator &operator++() {
+      Import = ASTContext::getNextLocalImport(Import);
+      return *this;
+    }
+
+    import_iterator operator++(int) {
+      import_iterator Other(*this);
+      ++(*this);
+      return Other;
+    }
+
+    friend bool operator==(import_iterator X, import_iterator Y) {
+      return X.Import == Y.Import;
+    }
+
+    friend bool operator!=(import_iterator X, import_iterator Y) {
+      return X.Import != Y.Import;
+    }
+  };
+
 public:
   comments::CommandTraits &getCommentCommandTraits() const {
     return CommentCommandTraits;
@@ -710,47 +751,10 @@
     return Import->NextLocalImport;
   }
   
-  /// \brief Iterator that visits import declarations.
-  class import_iterator {
-    ImportDecl *Import;
-    
-  public:
-    typedef ImportDecl               *value_type;
-    typedef ImportDecl               *reference;
-    typedef ImportDecl               *pointer;
-    typedef int                       difference_type;
-    typedef std::forward_iterator_tag iterator_category;
-    
-    import_iterator() : Import() { }
-    explicit import_iterator(ImportDecl *Import) : Import(Import) { }
-    
-    reference operator*() const { return Import; }
-    pointer operator->() const { return Import; }
-    
-    import_iterator &operator++() {
-      Import = ASTContext::getNextLocalImport(Import);
-      return *this;
-    }
-
-    import_iterator operator++(int) {
-      import_iterator Other(*this);
-      ++(*this);
-      return Other;
-    }
-    
-    friend bool operator==(import_iterator X, import_iterator Y) {
-      return X.Import == Y.Import;
-    }
-
-    friend bool operator!=(import_iterator X, import_iterator Y) {
-      return X.Import != Y.Import;
-    }
-  };
-  
-  import_iterator local_import_begin() const { 
-    return import_iterator(FirstLocalImport); 
+  typedef llvm::iterator_range<import_iterator> import_range;
+  import_range local_imports() const {
+    return import_range(import_iterator(FirstLocalImport), import_iterator());
   }
-  import_iterator local_import_end() const { return import_iterator(); }
 
   Decl *getPrimaryMergedDecl(Decl *D) {
     Decl *Result = MergedDecls.lookup(D);
@@ -797,11 +801,8 @@
   // The type is built when constructing 'BuiltinVaListDecl'.
   mutable QualType VaListTagTy;
 
-  ASTContext(LangOptions& LOpts, SourceManager &SM, const TargetInfo *t,
-             IdentifierTable &idents, SelectorTable &sels,
-             Builtin::Context &builtins,
-             unsigned size_reserve,
-             bool DelayInitialization = false);
+  ASTContext(LangOptions &LOpts, SourceManager &SM, IdentifierTable &idents,
+             SelectorTable &sels, Builtin::Context &builtins);
 
   ~ASTContext();
 
@@ -810,11 +811,13 @@
   /// The external AST source provides the ability to load parts of
   /// the abstract syntax tree as needed from some external storage,
   /// e.g., a precompiled header.
-  void setExternalSource(OwningPtr<ExternalASTSource> &Source);
+  void setExternalSource(IntrusiveRefCntPtr<ExternalASTSource> Source);
 
   /// \brief Retrieve a pointer to the external AST source associated
   /// with this AST context, if any.
-  ExternalASTSource *getExternalSource() const { return ExternalSource.get(); }
+  ExternalASTSource *getExternalSource() const {
+    return ExternalSource.get();
+  }
 
   /// \brief Attach an AST mutation listener to the AST context.
   ///
@@ -832,6 +835,14 @@
   void PrintStats() const;
   const SmallVectorImpl<Type *>& getTypes() const { return Types; }
 
+  /// \brief Create a new implicit TU-level CXXRecordDecl or RecordDecl
+  /// declaration.
+  RecordDecl *buildImplicitRecord(StringRef Name,
+                                  RecordDecl::TagKind TK = TTK_Struct) const;
+
+  /// \brief Create a new implicit TU-level typedef declaration.
+  TypedefDecl *buildImplicitTypedef(QualType T, StringRef Name) const;
+
   /// \brief Retrieve the declaration for the 128-bit signed integer type.
   TypedefDecl *getInt128Decl() const;
 
@@ -840,7 +851,7 @@
 
   /// \brief Retrieve the declaration for a 128-bit float stub type.
   TypeDecl *getFloat128StubType() const;
-  
+
   //===--------------------------------------------------------------------===//
   //                           Type Constructors
   //===--------------------------------------------------------------------===//
@@ -915,6 +926,14 @@
     return CanQualType::CreateUnsafe(getPointerType((QualType) T));
   }
 
+  /// \brief Return the uniqued reference to a type adjusted from the original
+  /// type to a new type.
+  QualType getAdjustedType(QualType Orig, QualType New) const;
+  CanQualType getAdjustedType(CanQualType Orig, CanQualType New) const {
+    return CanQualType::CreateUnsafe(
+        getAdjustedType((QualType)Orig, (QualType)New));
+  }
+
   /// \brief Return the uniqued reference to the decayed version of the given
   /// type.  Can only be called on array and function types which decay to
   /// pointer types.
@@ -1041,7 +1060,7 @@
   /// \brief Return the unique reference to the type for the specified type
   /// declaration.
   QualType getTypeDeclType(const TypeDecl *Decl,
-                           const TypeDecl *PrevDecl = 0) const {
+                           const TypeDecl *PrevDecl = nullptr) const {
     assert(Decl && "Passed null for Decl param");
     if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
 
@@ -1075,9 +1094,10 @@
                                           const TemplateTypeParmType *Replaced,
                                             const TemplateArgument &ArgPack);
 
-  QualType getTemplateTypeParmType(unsigned Depth, unsigned Index,
-                                   bool ParameterPack,
-                                   TemplateTypeParmDecl *ParmDecl = 0) const;
+  QualType
+  getTemplateTypeParmType(unsigned Depth, unsigned Index,
+                          bool ParameterPack,
+                          TemplateTypeParmDecl *ParmDecl = nullptr) const;
 
   QualType getTemplateSpecializationType(TemplateName T,
                                          const TemplateArgument *Args,
@@ -1121,11 +1141,18 @@
                                 Optional<unsigned> NumExpansions);
 
   QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
-                                ObjCInterfaceDecl *PrevDecl = 0) const;
+                                ObjCInterfaceDecl *PrevDecl = nullptr) const;
 
   QualType getObjCObjectType(QualType Base,
                              ObjCProtocolDecl * const *Protocols,
                              unsigned NumProtocols) const;
+  
+  bool ObjCObjectAdoptsQTypeProtocols(QualType QT, ObjCInterfaceDecl *Decl);
+  /// QIdProtocolsAdoptObjCObjectProtocols - Checks that protocols in
+  /// QT's qualified-id protocol list adopt all protocols in IDecl's list
+  /// of protocols.
+  bool QIdProtocolsAdoptObjCObjectProtocols(QualType QT,
+                                            ObjCInterfaceDecl *IDecl);
 
   /// \brief Return a ObjCObjectPointerType type for the given ObjCObjectType.
   QualType getObjCObjectPointerType(QualType OIT) const;
@@ -1344,7 +1371,11 @@
   ///
   /// If \p Field is specified then record field names are also encoded.
   void getObjCEncodingForType(QualType T, std::string &S,
-                              const FieldDecl *Field=0) const;
+                              const FieldDecl *Field=nullptr) const;
+
+  /// \brief Emit the Objective-C property type encoding for the given
+  /// type \p T into \p S.
+  void getObjCEncodingForPropertyType(QualType T, std::string &S) const;
 
   void getLegacyIntegralTypeEncoding(QualType &t) const;
 
@@ -1382,6 +1413,10 @@
 
   bool ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto,
                                       ObjCProtocolDecl *rProto) const;
+  
+  ObjCPropertyImplDecl *getObjCPropertyImplDeclForPropertyDecl(
+                                                  const ObjCPropertyDecl *PD,
+                                                  const Decl *Container) const;
 
   /// \brief Return the size of type \p T for Objective-C encoding purpose,
   /// in characters.
@@ -1542,7 +1577,7 @@
   /// arguments to the builtin that are required to be integer constant
   /// expressions.
   QualType GetBuiltinType(unsigned ID, GetBuiltinTypeError &Error,
-                          unsigned *IntegerConstantArgs = 0) const;
+                          unsigned *IntegerConstantArgs = nullptr) const;
 
 private:
   CanQualType getFromTargetType(unsigned Type) const;
@@ -1704,6 +1739,8 @@
 
   bool isNearlyEmpty(const CXXRecordDecl *RD) const;
 
+  VTableContextBase *getVTableContext();
+
   MangleContext *createMangleContext();
   
   void DeepCollectObjCIvars(const ObjCInterfaceDecl *OI, bool leafClass,
@@ -1745,6 +1782,10 @@
     return getCanonicalType(T1) == getCanonicalType(T2);
   }
 
+  bool hasSameType(const Type *T1, const Type *T2) const {
+    return getCanonicalType(T1) == getCanonicalType(T2);
+  }
+
   /// \brief Return this type as a completely-unqualified array type,
   /// capturing the qualifiers in \p Quals.
   ///
@@ -1994,9 +2035,9 @@
                       bool Unqualified = false, bool BlockReturnType = false);
   QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false,
                               bool Unqualified = false);
-  QualType mergeFunctionArgumentTypes(QualType, QualType,
-                                      bool OfBlockPointer=false,
-                                      bool Unqualified = false);
+  QualType mergeFunctionParameterTypes(QualType, QualType,
+                                       bool OfBlockPointer = false,
+                                       bool Unqualified = false);
   QualType mergeTransparentUnionType(QualType, QualType,
                                      bool OfBlockPointer=false,
                                      bool Unqualified = false);
@@ -2008,7 +2049,7 @@
          const FunctionProtoType *ToFunctionType);
 
   void ResetObjCLayout(const ObjCContainerDecl *CD) {
-    ObjCLayouts[CD] = 0;
+    ObjCLayouts[CD] = nullptr;
   }
 
   //===--------------------------------------------------------------------===//
@@ -2027,14 +2068,12 @@
   //===--------------------------------------------------------------------===//
   //                    Type Iterators.
   //===--------------------------------------------------------------------===//
+  typedef llvm::iterator_range<SmallVectorImpl<Type *>::const_iterator>
+    type_const_range;
 
-  typedef SmallVectorImpl<Type *>::iterator       type_iterator;
-  typedef SmallVectorImpl<Type *>::const_iterator const_type_iterator;
-
-  type_iterator types_begin() { return Types.begin(); }
-  type_iterator types_end() { return Types.end(); }
-  const_type_iterator types_begin() const { return Types.begin(); }
-  const_type_iterator types_end() const { return Types.end(); }
+  type_const_range types() const {
+    return type_const_range(Types.begin(), Types.end());
+  }
 
   //===--------------------------------------------------------------------===//
   //                    Integer Values
@@ -2125,7 +2164,7 @@
   /// when it is called.
   void AddDeallocation(void (*Callback)(void*), void *Data);
 
-  GVALinkage GetGVALinkageForFunction(const FunctionDecl *FD);
+  GVALinkage GetGVALinkageForFunction(const FunctionDecl *FD) const;
   GVALinkage GetGVALinkageForVariable(const VarDecl *VD);
 
   /// \brief Determines if the decl can be CodeGen'ed or deserialized from PCH
@@ -2139,6 +2178,9 @@
   void setManglingNumber(const NamedDecl *ND, unsigned Number);
   unsigned getManglingNumber(const NamedDecl *ND) const;
 
+  void setStaticLocalNumber(const VarDecl *VD, unsigned Number);
+  unsigned getStaticLocalNumber(const VarDecl *VD) const;
+
   /// \brief Retrieve the context for computing mangling numbers in the given
   /// DeclContext.
   MangleNumberingContext &getManglingNumberContext(const DeclContext *DC);
@@ -2212,9 +2254,7 @@
   /// \brief Initialize built-in types.
   ///
   /// This routine may only be invoked once for a given ASTContext object.
-  /// It is normally invoked by the ASTContext constructor. However, the
-  /// constructor can be asked to delay initialization, which places the burden
-  /// of calling this function on the user of that object.
+  /// It is normally invoked after ASTContext construction.
   ///
   /// \param Target The target 
   void InitBuiltinTypes(const TargetInfo &Target);
@@ -2238,17 +2278,21 @@
   void getObjCEncodingForStructureImpl(RecordDecl *RD, std::string &S,
                                        const FieldDecl *Field,
                                        bool includeVBases = true) const;
-
+public:
   // Adds the encoding of a method parameter or return type.
   void getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT,
                                          QualType T, std::string& S,
                                          bool Extended) const;
 
+  /// \brief Returns true if this is an inline-initialized static data member
+  /// which is treated as a definition for MSVC compatibility.
+  bool isMSStaticDataMemberInlineDefinition(const VarDecl *VD) const;
+  
+private:
   const ASTRecordLayout &
   getObjCLayout(const ObjCInterfaceDecl *D,
                 const ObjCImplementationDecl *Impl) const;
 
-private:
   /// \brief A set of deallocations that should be performed when the
   /// ASTContext is destroyed.
   typedef llvm::SmallDenseMap<void(*)(void*), llvm::SmallVector<void*, 16> >
@@ -2263,8 +2307,11 @@
   friend class DeclContext;
   friend class DeclarationNameTable;
   void ReleaseDeclContextMaps();
+  void ReleaseParentMapEntries();
 
-  llvm::OwningPtr<ParentMap> AllParents;
+  std::unique_ptr<ParentMap> AllParents;
+
+  std::unique_ptr<VTableContextBase> VTContext;
 };
 
 /// \brief Utility function for constructing a nullary selector.
@@ -2363,4 +2410,18 @@
   C.Deallocate(Ptr);
 }
 
+/// \brief Create the representation of a LazyGenerationalUpdatePtr.
+template <typename Owner, typename T,
+          void (clang::ExternalASTSource::*Update)(Owner)>
+typename clang::LazyGenerationalUpdatePtr<Owner, T, Update>::ValueType
+    clang::LazyGenerationalUpdatePtr<Owner, T, Update>::makeValue(
+        const clang::ASTContext &Ctx, T Value) {
+  // Note, this is implemented here so that ExternalASTSource.h doesn't need to
+  // include ASTContext.h. We explicitly instantiate it for all relevant types
+  // in ASTContext.cpp.
+  if (auto *Source = Ctx.getExternalSource())
+    return new (Ctx) LazyData(Source, Value);
+  return Value;
+}
+
 #endif
diff --git a/include/clang/AST/ASTDiagnostic.h b/include/clang/AST/ASTDiagnostic.h
index 1635511..484ca4c 100644
--- a/include/clang/AST/ASTDiagnostic.h
+++ b/include/clang/AST/ASTDiagnostic.h
@@ -36,12 +36,9 @@
   void FormatASTNodeDiagnosticArgument(
       DiagnosticsEngine::ArgumentKind Kind,
       intptr_t Val,
-      const char *Modifier,
-      unsigned ModLen,
-      const char *Argument,
-      unsigned ArgLen,
-      const DiagnosticsEngine::ArgumentValue *PrevArgs,
-      unsigned NumPrevArgs,
+      StringRef Modifier,
+      StringRef Argument,
+      ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs,
       SmallVectorImpl<char> &Output,
       void *Cookie,
       ArrayRef<intptr_t> QualTypeVals);
diff --git a/include/clang/AST/ASTImporter.h b/include/clang/AST/ASTImporter.h
index b74c8ee..a335f98 100644
--- a/include/clang/AST/ASTImporter.h
+++ b/include/clang/AST/ASTImporter.h
@@ -278,7 +278,7 @@
     /// happens especially for anonymous structs.  If the original of the second
     /// RecordDecl can be found, we can complete it without the need for
     /// importation, eliminating this loop.
-    virtual Decl *GetOriginalDecl(Decl *To) { return NULL; }
+    virtual Decl *GetOriginalDecl(Decl *To) { return nullptr; }
     
     /// \brief Determine whether the given types are structurally
     /// equivalent.
diff --git a/include/clang/AST/ASTLambda.h b/include/clang/AST/ASTLambda.h
index 358ac71..9af016b 100644
--- a/include/clang/AST/ASTLambda.h
+++ b/include/clang/AST/ASTLambda.h
@@ -36,9 +36,9 @@
   return isLambdaCallOperator(cast<CXXMethodDecl>(DC));
 }
 
-inline bool isGenericLambdaCallOperatorSpecialization(CXXMethodDecl *MD) {
+inline bool isGenericLambdaCallOperatorSpecialization(const CXXMethodDecl *MD) {
   if (!MD) return false;
-  CXXRecordDecl *LambdaClass = MD->getParent();
+  const CXXRecordDecl *LambdaClass = MD->getParent();
   if (LambdaClass && LambdaClass->isGenericLambda())
     return isLambdaCallOperator(MD) && 
                     MD->isFunctionTemplateSpecialization();
diff --git a/include/clang/AST/ASTMutationListener.h b/include/clang/AST/ASTMutationListener.h
index 6d12a92..a89bfed 100644
--- a/include/clang/AST/ASTMutationListener.h
+++ b/include/clang/AST/ASTMutationListener.h
@@ -65,6 +65,10 @@
   virtual void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD,
                                               const FunctionDecl *D) {}
 
+  /// \brief A function's exception specification has been evaluated or
+  /// instantiated.
+  virtual void ResolvedExceptionSpec(const FunctionDecl *FD) {}
+
   /// \brief A function's return type has been deduced.
   virtual void DeducedReturnType(const FunctionDecl *FD, QualType ReturnType);
 
@@ -74,6 +78,9 @@
   /// \brief A static data member was implicitly instantiated.
   virtual void StaticDataMemberInstantiated(const VarDecl *D) {}
 
+  /// \brief A function template's definition was instantiated.
+  virtual void FunctionDefinitionInstantiated(const FunctionDecl *D) {}
+
   /// \brief A new objc category class was added for an interface.
   virtual void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
                                             const ObjCInterfaceDecl *IFD) {}
diff --git a/include/clang/AST/ASTTypeTraits.h b/include/clang/AST/ASTTypeTraits.h
index 087ad56..0e06e26 100644
--- a/include/clang/AST/ASTTypeTraits.h
+++ b/include/clang/AST/ASTTypeTraits.h
@@ -57,11 +57,18 @@
   bool isSame(ASTNodeKind Other) const;
 
   /// \brief Returns \c true if \c this is a base kind of (or same as) \c Other.
-  bool isBaseOf(ASTNodeKind Other) const;
+  /// \param Distance If non-null, used to return the distance between \c this
+  /// and \c Other in the class hierarchy.
+  bool isBaseOf(ASTNodeKind Other, unsigned *Distance = nullptr) const;
 
   /// \brief String representation of the kind.
   StringRef asStringRef() const;
 
+  /// \brief Strict weak ordering for ASTNodeKind.
+  bool operator<(const ASTNodeKind &Other) const {
+    return KindId < Other.KindId;
+  }
+
 private:
   /// \brief Kind ids.
   ///
@@ -91,7 +98,9 @@
 
   /// \brief Returns \c true if \c Base is a base kind of (or same as) \c
   ///   Derived.
-  static bool isBaseOf(NodeKindId Base, NodeKindId Derived);
+  /// \param Distance If non-null, used to return the distance between \c Base
+  /// and \c Derived in the class hierarchy.
+  static bool isBaseOf(NodeKindId Base, NodeKindId Derived, unsigned *Distance);
 
   /// \brief Helper meta-function to convert a kind T to its enum value.
   ///
@@ -133,6 +142,11 @@
 #include "clang/AST/TypeNodes.def"
 #undef KIND_TO_KIND_ID
 
+inline raw_ostream &operator<<(raw_ostream &OS, ASTNodeKind K) {
+  OS << K.asStringRef();
+  return OS;
+}
+
 /// \brief A dynamically typed AST node container.
 ///
 /// Stores an AST node in a type safe way. This allows writing code that
@@ -198,8 +212,8 @@
     return getMemoizationData() < Other.getMemoizationData();
   }
   bool operator==(const DynTypedNode &Other) const {
-    // Nodes with different types cannot be equal.
-    if (!NodeKind.isSame(Other.NodeKind))
+    if (!NodeKind.isBaseOf(Other.NodeKind) &&
+        !Other.NodeKind.isBaseOf(NodeKind))
       return false;
 
     // FIXME: Implement for other types.
@@ -223,7 +237,7 @@
     static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
       if (ASTNodeKind::getFromNodeKind<BaseT>().isBaseOf(NodeKind))
         return dyn_cast<T>(*reinterpret_cast<BaseT *const *>(Storage));
-      return NULL;
+      return nullptr;
     }
     static DynTypedNode create(const BaseT &Node) {
       DynTypedNode Result;
@@ -238,7 +252,7 @@
     static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
       if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
         return *reinterpret_cast<T *const *>(Storage);
-      return NULL;
+      return nullptr;
     }
     static DynTypedNode create(const T &Node) {
       DynTypedNode Result;
@@ -253,7 +267,7 @@
     static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
       if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
         return reinterpret_cast<const T *>(Storage);
-      return NULL;
+      return nullptr;
     }
     static DynTypedNode create(const T &Node) {
       DynTypedNode Result;
@@ -283,18 +297,18 @@
 
 template <typename T>
 struct DynTypedNode::BaseConverter<
-    T, typename llvm::enable_if<llvm::is_base_of<
-           Decl, T> >::type> : public DynCastPtrConverter<T, Decl> {};
+    T, typename std::enable_if<std::is_base_of<Decl, T>::value>::type>
+    : public DynCastPtrConverter<T, Decl> {};
 
 template <typename T>
 struct DynTypedNode::BaseConverter<
-    T, typename llvm::enable_if<llvm::is_base_of<
-           Stmt, T> >::type> : public DynCastPtrConverter<T, Stmt> {};
+    T, typename std::enable_if<std::is_base_of<Stmt, T>::value>::type>
+    : public DynCastPtrConverter<T, Stmt> {};
 
 template <typename T>
 struct DynTypedNode::BaseConverter<
-    T, typename llvm::enable_if<llvm::is_base_of<
-           Type, T> >::type> : public DynCastPtrConverter<T, Type> {};
+    T, typename std::enable_if<std::is_base_of<Type, T>::value>::type>
+    : public DynCastPtrConverter<T, Type> {};
 
 template <>
 struct DynTypedNode::BaseConverter<
@@ -341,7 +355,7 @@
   } else if (ASTNodeKind::getFromNodeKind<NestedNameSpecifier>().isBaseOf(NodeKind)) {
     return BaseConverter<NestedNameSpecifier>::get(NodeKind, Storage.buffer);
   }
-  return NULL;
+  return nullptr;
 }
 
 } // end namespace ast_type_traits
diff --git a/include/clang/AST/ASTUnresolvedSet.h b/include/clang/AST/ASTUnresolvedSet.h
index e8be670..84b0842 100644
--- a/include/clang/AST/ASTUnresolvedSet.h
+++ b/include/clang/AST/ASTUnresolvedSet.h
@@ -32,9 +32,6 @@
 
   DeclsTy Decls;
 
-  ASTUnresolvedSet(const ASTUnresolvedSet &) LLVM_DELETED_FUNCTION;
-  void operator=(const ASTUnresolvedSet &) LLVM_DELETED_FUNCTION;
-
   friend class LazyASTUnresolvedSet;
 
 public:
diff --git a/include/clang/AST/ASTVector.h b/include/clang/AST/ASTVector.h
index 6db918e..d92167e 100644
--- a/include/clang/AST/ASTVector.h
+++ b/include/clang/AST/ASTVector.h
@@ -26,30 +26,6 @@
 #include <cstring>
 #include <memory>
 
-#ifdef _MSC_VER
-namespace std {
-#if _MSC_VER <= 1310
-  // Work around flawed VC++ implementation of std::uninitialized_copy.  Define
-  // additional overloads so that elements with pointer types are recognized as
-  // scalars and not objects, causing bizarre type conversion errors.
-  template<class T1, class T2>
-  inline _Scalar_ptr_iterator_tag _Ptr_cat(T1 **, T2 **) {
-    _Scalar_ptr_iterator_tag _Cat;
-    return _Cat;
-  }
-
-  template<class T1, class T2>
-  inline _Scalar_ptr_iterator_tag _Ptr_cat(T1* const *, T2 **) {
-    _Scalar_ptr_iterator_tag _Cat;
-    return _Cat;
-  }
-#else
-  // FIXME: It is not clear if the problem is fixed in VS 2005.  What is clear
-  // is that the above hack won't work if it wasn't fixed.
-#endif
-}
-#endif
-
 namespace clang {
   class ASTContext;
 
@@ -69,15 +45,30 @@
 
 public:
   // Default ctor - Initialize to empty.
-  ASTVector() : Begin(0), End(0), Capacity(0, false) {}
+  ASTVector() : Begin(nullptr), End(nullptr), Capacity(nullptr, false) {}
+
+  ASTVector(ASTVector &&O) : Begin(O.Begin), End(O.End), Capacity(O.Capacity) {
+    O.Begin = O.End = nullptr;
+    O.Capacity.setPointer(nullptr);
+    O.Capacity.setInt(false);
+  }
 
   ASTVector(const ASTContext &C, unsigned N)
-      : Begin(0), End(0), Capacity(0, false) {
+      : Begin(nullptr), End(nullptr), Capacity(nullptr, false) {
     reserve(C, N);
   }
 
+  ASTVector &operator=(ASTVector &&RHS) {
+    ASTVector O(std::move(RHS));
+    using std::swap;
+    swap(Begin, O.Begin);
+    swap(End, O.End);
+    swap(Capacity, O.Capacity);
+    return *this;
+  }
+
   ~ASTVector() {
-    if (llvm::is_class<T>::value) {
+    if (std::is_class<T>::value) {
       // Destroy the constructed elements in the vector.
       destroy_range(Begin, End);
     }
@@ -147,7 +138,7 @@
   }
 
   void clear() {
-    if (llvm::is_class<T>::value) {
+    if (std::is_class<T>::value) {
       destroy_range(Begin, End);
     }
     End = Begin;
@@ -392,7 +383,7 @@
   T *NewElts = new (C, llvm::alignOf<T>()) T[NewCapacity];
 
   // Copy the elements over.
-  if (llvm::is_class<T>::value) {
+  if (std::is_class<T>::value) {
     std::uninitialized_copy(Begin, End, NewElts);
     // Destroy the original elements.
     destroy_range(Begin, End);
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index 7dbf413..fc48816 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -26,8 +26,8 @@
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/raw_ostream.h"
+#include <algorithm>
 #include <cassert>
-#include <cstring>
 
 namespace clang {
   class ASTContext;
@@ -48,10 +48,9 @@
   /// An index into the spelling list of an
   /// attribute defined in Attr.td file.
   unsigned SpellingListIndex : 4;
-
   bool Inherited : 1;
-
   bool IsPackExpansion : 1;
+  bool Implicit : 1;
 
   virtual ~Attr();
 
@@ -76,7 +75,7 @@
 protected:
   Attr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex = 0)
     : Range(R), AttrKind(AK), SpellingListIndex(SpellingListIndex),
-      Inherited(false), IsPackExpansion(false) {}
+      Inherited(false), IsPackExpansion(false), Implicit(false) {}
 
 public:
 
@@ -85,6 +84,7 @@
   }
   
   unsigned getSpellingListIndex() const { return SpellingListIndex; }
+  virtual const char *getSpelling() const = 0;
 
   SourceLocation getLocation() const { return Range.getBegin(); }
   SourceRange getRange() const { return Range; }
@@ -92,6 +92,11 @@
 
   bool isInherited() const { return Inherited; }
 
+  /// \brief Returns true if the attribute has been implicitly created instead
+  /// of explicitly written by the user.
+  bool isImplicit() const { return Implicit; }
+  void setImplicit(bool I) { Implicit = I; }
+
   void setPackExpansion(bool PE) { IsPackExpansion = PE; }
   bool isPackExpansion() const { return IsPackExpansion; }
 
@@ -103,6 +108,11 @@
   // Pretty print this attribute.
   virtual void printPretty(raw_ostream &OS,
                            const PrintingPolicy &Policy) const = 0;
+
+  /// \brief By default, attributes cannot be duplicated when being merged;
+  /// however, an attribute can override this. Returns true if the attribute
+  /// can be duplicated when merging.
+  virtual bool duplicatesAllowed() const { return false; }
 };
 
 class InheritableAttr : public Attr {
@@ -121,7 +131,7 @@
 };
 
 class InheritableParamAttr : public InheritableAttr {
-  virtual void anchor();
+  void anchor() override;
 protected:
   InheritableParamAttr(attr::Kind AK, SourceRange R,
                        unsigned SpellingListIndex = 0)
@@ -136,23 +146,21 @@
   }
 };
 
-class MSInheritanceAttr : public InheritableAttr {
-  virtual void anchor();
-protected:
-  MSInheritanceAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex = 0)
-    : InheritableAttr(AK, R, SpellingListIndex) {}
-
-public:
-  // Implement isa/cast/dyncast/etc.
-  static bool classof(const Attr *A) {
-    // Relies on relative order of enum emission with respect to param attrs.
-    return (A->getKind() <= attr::LAST_MS_INHERITANCE &&
-            A->getKind() > attr::LAST_INHERITABLE_PARAM);
-  }
-};
-
 #include "clang/AST/Attrs.inc"
 
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                           const Attr *At) {
+  DB.AddTaggedVal(reinterpret_cast<intptr_t>(At),
+                  DiagnosticsEngine::ak_attr);
+  return DB;
+}
+
+inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+                                           const Attr *At) {
+  PD.AddTaggedVal(reinterpret_cast<intptr_t>(At),
+                  DiagnosticsEngine::ak_attr);
+  return PD;
+}
 }  // end namespace clang
 
 #endif
diff --git a/include/clang/AST/AttrIterator.h b/include/clang/AST/AttrIterator.h
index 8bd8fbe..39ee81f 100644
--- a/include/clang/AST/AttrIterator.h
+++ b/include/clang/AST/AttrIterator.h
@@ -43,7 +43,7 @@
 typedef SmallVector<const Attr*, 2> ConstAttrVec;
 
 /// specific_attr_iterator - Iterates over a subrange of an AttrVec, only
-/// providing attributes that are of a specifc type.
+/// providing attributes that are of a specific type.
 template <typename SpecificAttr, typename Container = AttrVec>
 class specific_attr_iterator {
   typedef typename Container::const_iterator Iterator;
@@ -53,7 +53,7 @@
   /// specifically requested, we don't necessarily advance this all the
   /// way. Instead, we advance it when an operation is requested; if the
   /// operation is acting on what should be a past-the-end iterator,
-  /// then we offer no guarantees, but this way we do not dererence a
+  /// then we offer no guarantees, but this way we do not dereference a
   /// past-the-end iterator when we move to a past-the-end position.
   mutable Iterator Current;
 
@@ -98,7 +98,7 @@
 
   friend bool operator==(specific_attr_iterator Left,
                          specific_attr_iterator Right) {
-    assert((Left.Current == 0) == (Right.Current == 0));
+    assert((Left.Current == nullptr) == (Right.Current == nullptr));
     if (Left.Current < Right.Current)
       Left.AdvanceToNext(Right.Current); 
     else
@@ -134,7 +134,7 @@
   if (i != specific_attr_end<SpecificAttr>(container))
     return *i;
   else
-    return 0;
+    return nullptr;
 }
 
 }  // end namespace clang
diff --git a/include/clang/AST/CMakeLists.txt b/include/clang/AST/CMakeLists.txt
index ba54fa2..260734f 100644
--- a/include/clang/AST/CMakeLists.txt
+++ b/include/clang/AST/CMakeLists.txt
@@ -13,6 +13,11 @@
   SOURCE ../Basic/Attr.td
   TARGET ClangAttrDump)
 
+clang_tablegen(AttrVisitor.inc -gen-clang-attr-ast-visitor
+  -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
+  SOURCE ../Basic/Attr.td
+  TARGET ClangAttrVisitor)
+
 clang_tablegen(StmtNodes.inc -gen-clang-stmt-nodes
   SOURCE ../Basic/StmtNodes.td
   TARGET ClangStmtNodes)
diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h
index dbe4ad0..37f6748 100644
--- a/include/clang/AST/CXXInheritance.h
+++ b/include/clang/AST/CXXInheritance.h
@@ -177,8 +177,8 @@
                         bool RecordPaths = true,
                         bool DetectVirtual = true)
     : FindAmbiguities(FindAmbiguities), RecordPaths(RecordPaths),
-      DetectVirtual(DetectVirtual), DetectedVirtual(0), DeclsFound(0),
-      NumDeclsFound(0) { }
+      DetectVirtual(DetectVirtual), DetectedVirtual(nullptr),
+      DeclsFound(nullptr), NumDeclsFound(0) { }
   
   ~CXXBasePaths() { delete [] DeclsFound; }
   
@@ -190,8 +190,8 @@
   CXXBasePath&       front()       { return Paths.front(); }
   const CXXBasePath& front() const { return Paths.front(); }
   
-  decl_iterator found_decls_begin();
-  decl_iterator found_decls_end();
+  typedef llvm::iterator_range<decl_iterator> decl_range;
+  decl_range found_decls();
   
   /// \brief Determine whether the path from the most-derived type to the
   /// given base type is ambiguous (i.e., it refers to multiple subobjects of
@@ -232,7 +232,8 @@
 /// \brief Uniquely identifies a virtual method within a class
 /// hierarchy by the method itself and a class subobject number.
 struct UniqueVirtualMethod {
-  UniqueVirtualMethod() : Method(0), Subobject(0), InVirtualSubobject(0) { }
+  UniqueVirtualMethod()
+    : Method(nullptr), Subobject(0), InVirtualSubobject(nullptr) { }
 
   UniqueVirtualMethod(CXXMethodDecl *Method, unsigned Subobject,
                       const CXXRecordDecl *InVirtualSubobject)
diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h
index 9c699b7..7cccef6 100644
--- a/include/clang/AST/CanonicalType.h
+++ b/include/clang/AST/CanonicalType.h
@@ -17,7 +17,6 @@
 
 #include "clang/AST/Type.h"
 #include "llvm/Support/Casting.h"
-#include "llvm/Support/type_traits.h"
 #include <iterator>
 
 namespace clang {
@@ -60,9 +59,9 @@
 
   /// \brief Converting constructor that permits implicit upcasting of
   /// canonical type pointers.
-  template<typename U>
-  CanQual(const CanQual<U>& Other,
-          typename llvm::enable_if<llvm::is_base_of<T, U>, int>::type = 0);
+  template <typename U>
+  CanQual(const CanQual<U> &Other,
+          typename std::enable_if<std::is_base_of<T, U>::value, int>::type = 0);
 
   /// \brief Retrieve the underlying type pointer, which refers to a
   /// canonical type.
@@ -541,39 +540,39 @@
 
 template<>
 struct CanProxyAdaptor<FunctionType> : public CanProxyBase<FunctionType> {
-  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
 };
 
 template<>
 struct CanProxyAdaptor<FunctionNoProtoType>
   : public CanProxyBase<FunctionNoProtoType> {
-  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
 };
 
 template<>
 struct CanProxyAdaptor<FunctionProtoType>
   : public CanProxyBase<FunctionProtoType> {
-  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
+  LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
-  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumArgs)
-  CanQualType getArgType(unsigned i) const {
-    return CanQualType::CreateUnsafe(this->getTypePtr()->getArgType(i));
+  LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumParams)
+  CanQualType getParamType(unsigned i) const {
+    return CanQualType::CreateUnsafe(this->getTypePtr()->getParamType(i));
   }
 
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariadic)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getTypeQuals)
 
-  typedef CanTypeIterator<FunctionProtoType::arg_type_iterator>
-    arg_type_iterator;
+  typedef CanTypeIterator<FunctionProtoType::param_type_iterator>
+  param_type_iterator;
 
-  arg_type_iterator arg_type_begin() const {
-    return arg_type_iterator(this->getTypePtr()->arg_type_begin());
+  param_type_iterator param_type_begin() const {
+    return param_type_iterator(this->getTypePtr()->param_type_begin());
   }
 
-  arg_type_iterator arg_type_end() const {
-    return arg_type_iterator(this->getTypePtr()->arg_type_end());
+  param_type_iterator param_type_end() const {
+    return param_type_iterator(this->getTypePtr()->param_type_end());
   }
 
   // Note: canonical function types never have exception specifications
diff --git a/include/clang/AST/CharUnits.h b/include/clang/AST/CharUnits.h
index 09ff682..72ca9f5 100644
--- a/include/clang/AST/CharUnits.h
+++ b/include/clang/AST/CharUnits.h
@@ -165,7 +165,7 @@
       /// RoundUpToAlignment - Returns the next integer (mod 2**64) that is
       /// greater than or equal to this quantity and is a multiple of \p Align.
       /// Align must be non-zero.
-      CharUnits RoundUpToAlignment(const CharUnits &Align) {
+      CharUnits RoundUpToAlignment(const CharUnits &Align) const {
         return CharUnits(llvm::RoundUpToAlignment(Quantity, 
                                                   Align.Quantity));
       }
@@ -173,12 +173,7 @@
       /// Given that this is a non-zero alignment value, what is the
       /// alignment at the given offset?
       CharUnits alignmentAtOffset(CharUnits offset) {
-        // alignment: 0010000
-        // offset:    1011100
-        // lowBits:   0001011
-        // result:    0000100
-        QuantityType lowBits = (Quantity-1) & (offset.Quantity-1);
-        return CharUnits((lowBits + 1) & ~lowBits);
+        return CharUnits(llvm::MinAlign(Quantity, offset.Quantity));
       }
 
 
diff --git a/include/clang/AST/Comment.h b/include/clang/AST/Comment.h
index 28849f5..e18fe9a 100644
--- a/include/clang/AST/Comment.h
+++ b/include/clang/AST/Comment.h
@@ -100,16 +100,26 @@
   };
   enum { NumInlineCommandCommentBits = NumInlineContentCommentBits + 10 };
 
+  class HTMLTagCommentBitfields {
+    friend class HTMLTagComment;
+
+    unsigned : NumInlineContentCommentBits;
+
+    /// True if we found that this tag is malformed in some way.
+    unsigned IsMalformed : 1;
+  };
+  enum { NumHTMLTagCommentBits = NumInlineContentCommentBits + 1 };
+
   class HTMLStartTagCommentBitfields {
     friend class HTMLStartTagComment;
 
-    unsigned : NumInlineContentCommentBits;
+    unsigned : NumHTMLTagCommentBits;
 
     /// True if this tag is self-closing (e. g., <br />).  This is based on tag
     /// spelling in comment (plain <br> would not set this flag).
     unsigned IsSelfClosing : 1;
   };
-  enum { NumHTMLStartTagCommentBits = NumInlineContentCommentBits + 1 };
+  enum { NumHTMLStartTagCommentBits = NumHTMLTagCommentBits + 1 };
 
   class ParagraphCommentBitfields {
     friend class ParagraphComment;
@@ -155,6 +165,7 @@
     InlineContentCommentBitfields InlineContentCommentBits;
     TextCommentBitfields TextCommentBits;
     InlineCommandCommentBitfields InlineCommandCommentBits;
+    HTMLTagCommentBitfields HTMLTagCommentBits;
     HTMLStartTagCommentBitfields HTMLStartTagCommentBits;
     ParagraphCommentBitfields ParagraphCommentBits;
     BlockCommandCommentBitfields BlockCommandCommentBits;
@@ -194,9 +205,9 @@
 
   const char *getCommentKindName() const;
 
-  LLVM_ATTRIBUTE_USED void dump() const;
-  LLVM_ATTRIBUTE_USED void dumpColor() const;
-  LLVM_ATTRIBUTE_USED void dump(const ASTContext &Context) const;
+  void dump() const;
+  void dumpColor() const;
+  void dump(const ASTContext &Context) const;
   void dump(raw_ostream &OS, const CommandTraits *Traits,
             const SourceManager *SM) const;
 
@@ -267,9 +278,9 @@
     return C->getCommentKind() == TextCommentKind;
   }
 
-  child_iterator child_begin() const { return NULL; }
+  child_iterator child_begin() const { return nullptr; }
 
-  child_iterator child_end() const { return NULL; }
+  child_iterator child_end() const { return nullptr; }
 
   StringRef getText() const LLVM_READONLY { return Text; }
 
@@ -325,9 +336,9 @@
     return C->getCommentKind() == InlineCommandCommentKind;
   }
 
-  child_iterator child_begin() const { return NULL; }
+  child_iterator child_begin() const { return nullptr; }
 
-  child_iterator child_end() const { return NULL; }
+  child_iterator child_end() const { return nullptr; }
 
   unsigned getCommandID() const {
     return InlineCommandCommentBits.CommandID;
@@ -360,8 +371,7 @@
 };
 
 /// Abstract class for opening and closing HTML tags.  HTML tags are always
-/// treated as inline content (regardless HTML semantics); opening and closing
-/// tags are not matched.
+/// treated as inline content (regardless HTML semantics).
 class HTMLTagComment : public InlineContentComment {
 protected:
   StringRef TagName;
@@ -377,6 +387,7 @@
       TagName(TagName),
       TagNameRange(TagNameBegin, TagNameEnd) {
     setLocation(TagNameBegin);
+    HTMLTagCommentBits.IsMalformed = 0;
   }
 
 public:
@@ -392,6 +403,14 @@
     return SourceRange(L.getLocWithOffset(1),
                        L.getLocWithOffset(1 + TagName.size()));
   }
+
+  bool isMalformed() const {
+    return HTMLTagCommentBits.IsMalformed;
+  }
+
+  void setIsMalformed() {
+    HTMLTagCommentBits.IsMalformed = 1;
+  }
 };
 
 /// An opening HTML tag with attributes.
@@ -450,9 +469,9 @@
     return C->getCommentKind() == HTMLStartTagCommentKind;
   }
 
-  child_iterator child_begin() const { return NULL; }
+  child_iterator child_begin() const { return nullptr; }
 
-  child_iterator child_end() const { return NULL; }
+  child_iterator child_end() const { return nullptr; }
 
   unsigned getNumAttrs() const {
     return Attributes.size();
@@ -505,9 +524,9 @@
     return C->getCommentKind() == HTMLEndTagCommentKind;
   }
 
-  child_iterator child_begin() const { return NULL; }
+  child_iterator child_begin() const { return nullptr; }
 
-  child_iterator child_end() const { return NULL; }
+  child_iterator child_end() const { return nullptr; }
 };
 
 /// Block content (contains inline content).
@@ -601,7 +620,7 @@
                       unsigned CommandID,
                       CommandMarkerKind CommandMarker) :
       BlockContentComment(K, LocBegin, LocEnd),
-      Paragraph(NULL) {
+      Paragraph(nullptr) {
     setLocation(getCommandNameBeginLoc());
     BlockCommandCommentBits.CommandID = CommandID;
     BlockCommandCommentBits.CommandMarker = CommandMarker;
@@ -613,7 +632,7 @@
                       unsigned CommandID,
                       CommandMarkerKind CommandMarker) :
       BlockContentComment(BlockCommandCommentKind, LocBegin, LocEnd),
-      Paragraph(NULL) {
+      Paragraph(nullptr) {
     setLocation(getCommandNameBeginLoc());
     BlockCommandCommentBits.CommandID = CommandID;
     BlockCommandCommentBits.CommandMarker = CommandMarker;
@@ -699,7 +718,7 @@
   unsigned ParamIndex;
 
 public:
-  enum LLVM_ENUM_INT_TYPE(unsigned) {
+  enum : unsigned {
     InvalidParamIndex = ~0U,
     VarArgParamIndex = ~0U/*InvalidParamIndex*/ - 1U
   };
@@ -861,9 +880,9 @@
     return C->getCommentKind() == VerbatimBlockLineCommentKind;
   }
 
-  child_iterator child_begin() const { return NULL; }
+  child_iterator child_begin() const { return nullptr; }
 
-  child_iterator child_end() const { return NULL; }
+  child_iterator child_end() const { return nullptr; }
 
   StringRef getText() const LLVM_READONLY {
     return Text;
@@ -948,9 +967,9 @@
     return C->getCommentKind() == VerbatimLineCommentKind;
   }
 
-  child_iterator child_begin() const { return NULL; }
+  child_iterator child_begin() const { return nullptr; }
 
-  child_iterator child_end() const { return NULL; }
+  child_iterator child_end() const { return nullptr; }
 
   StringRef getText() const {
     return Text;
@@ -981,9 +1000,9 @@
   /// that we consider a "function".
   ArrayRef<const ParmVarDecl *> ParamVars;
 
-  /// Function result type if \c CommentDecl is something that we consider
+  /// Function return type if \c CommentDecl is something that we consider
   /// a "function".
-  QualType ResultType;
+  QualType ReturnType;
 
   /// Template parameters that can be referenced by \\tparam if \c CommentDecl is
   /// a template (\c IsTemplateDecl or \c IsTemplatePartialSpecialization is
diff --git a/include/clang/AST/CommentCommands.td b/include/clang/AST/CommentCommands.td
index ed323da..958ee03 100644
--- a/include/clang/AST/CommentCommands.td
+++ b/include/clang/AST/CommentCommands.td
@@ -146,7 +146,7 @@
 def Version    : BlockCommand<"version">;
 def Warning    : BlockCommand<"warning">;
 // HeaderDoc commands
-def Abstract      : BlockCommand<"abstract">;
+def Abstract      : BlockCommand<"abstract"> { let IsBriefCommand = 1; }
 def ClassDesign   : RecordLikeDetailCommand<"classdesign">;
 def CoClass       : RecordLikeDetailCommand<"coclass">;
 def Dependency    : RecordLikeDetailCommand<"dependency">;
diff --git a/include/clang/AST/CommentHTMLTags.td b/include/clang/AST/CommentHTMLTags.td
index f98e32d..2514900 100644
--- a/include/clang/AST/CommentHTMLTags.td
+++ b/include/clang/AST/CommentHTMLTags.td
@@ -52,3 +52,16 @@
 def Th      : Tag<"th"> { let EndTagOptional = 1; }
 def Td      : Tag<"td"> { let EndTagOptional = 1; }
 
+// Define a blacklist of attributes that are not safe to pass through to HTML
+// output if the input is untrusted.
+//
+// FIXME: this should be a whitelist.  When changing this to a whitelist, don't
+// forget to change the default in the TableGen backend.
+class Attribute<string spelling> {
+  string Spelling = spelling;
+  bit IsSafeToPassThrough = 1;
+}
+class EventHandlerContentAttribute<string spelling> : Attribute<spelling> {
+  let IsSafeToPassThrough = 0;
+}
+
diff --git a/include/clang/AST/CommentLexer.h b/include/clang/AST/CommentLexer.h
index f152c77..a6e3ed8 100644
--- a/include/clang/AST/CommentLexer.h
+++ b/include/clang/AST/CommentLexer.h
@@ -14,8 +14,8 @@
 #ifndef LLVM_CLANG_AST_COMMENT_LEXER_H
 #define LLVM_CLANG_AST_COMMENT_LEXER_H
 
-#include "clang/Basic/SourceManager.h"
 #include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceManager.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
@@ -293,17 +293,7 @@
   StringRef resolveHTMLHexCharacterReference(StringRef Name) const;
 
   void formTokenWithChars(Token &Result, const char *TokEnd,
-                          tok::TokenKind Kind) {
-    const unsigned TokLen = TokEnd - BufferPtr;
-    Result.setLocation(getSourceLocation(BufferPtr));
-    Result.setKind(Kind);
-    Result.setLength(TokLen);
-#ifndef NDEBUG
-    Result.TextPtr = "<UNSET>";
-    Result.IntVal = 7;
-#endif
-    BufferPtr = TokEnd;
-  }
+                          tok::TokenKind Kind);
 
   void formTextToken(Token &Result, const char *TokEnd) {
     StringRef Text(BufferPtr, TokEnd - BufferPtr);
@@ -362,7 +352,7 @@
 
   StringRef getSpelling(const Token &Tok,
                         const SourceManager &SourceMgr,
-                        bool *Invalid = NULL) const;
+                        bool *Invalid = nullptr) const;
 };
 
 } // end namespace comments
diff --git a/include/clang/AST/CommentSema.h b/include/clang/AST/CommentSema.h
index 3910960..027c3b9 100644
--- a/include/clang/AST/CommentSema.h
+++ b/include/clang/AST/CommentSema.h
@@ -84,8 +84,8 @@
       T *Mem = Allocator.Allocate<T>(Size);
       std::uninitialized_copy(Source.begin(), Source.end(), Mem);
       return llvm::makeArrayRef(Mem, Size);
-    } else
-      return llvm::makeArrayRef(static_cast<T *>(NULL), 0);
+    }
+    return ArrayRef<T>();
   }
 
   ParagraphComment *actOnParagraphComment(
diff --git a/include/clang/AST/DataRecursiveASTVisitor.h b/include/clang/AST/DataRecursiveASTVisitor.h
new file mode 100644
index 0000000..9ef0087
--- /dev/null
+++ b/include/clang/AST/DataRecursiveASTVisitor.h
@@ -0,0 +1,2519 @@
+//===--- DataRecursiveASTVisitor.h - Data-Recursive AST Visitor -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the DataRecursiveASTVisitor interface, which recursively
+//  traverses the entire AST, using data recursion for Stmts/Exprs.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_AST_DATARECURSIVEASTVISITOR_H
+#define LLVM_CLANG_AST_DATARECURSIVEASTVISITOR_H
+
+#include "clang/AST/Attr.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclFriend.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclOpenMP.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtCXX.h"
+#include "clang/AST/StmtObjC.h"
+#include "clang/AST/StmtOpenMP.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/AST/TemplateName.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/TypeLoc.h"
+
+// The following three macros are used for meta programming.  The code
+// using them is responsible for defining macro OPERATOR().
+
+// All unary operators.
+#define UNARYOP_LIST()                                                         \
+  OPERATOR(PostInc) OPERATOR(PostDec) OPERATOR(PreInc) OPERATOR(PreDec)        \
+      OPERATOR(AddrOf) OPERATOR(Deref) OPERATOR(Plus) OPERATOR(Minus)          \
+      OPERATOR(Not) OPERATOR(LNot) OPERATOR(Real) OPERATOR(Imag)               \
+      OPERATOR(Extension)
+
+// All binary operators (excluding compound assign operators).
+#define BINOP_LIST()                                                           \
+  OPERATOR(PtrMemD) OPERATOR(PtrMemI) OPERATOR(Mul) OPERATOR(Div)              \
+      OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) OPERATOR(Shl) OPERATOR(Shr)    \
+      OPERATOR(LT) OPERATOR(GT) OPERATOR(LE) OPERATOR(GE) OPERATOR(EQ)         \
+      OPERATOR(NE) OPERATOR(And) OPERATOR(Xor) OPERATOR(Or) OPERATOR(LAnd)     \
+      OPERATOR(LOr) OPERATOR(Assign) OPERATOR(Comma)
+
+// All compound assign operators.
+#define CAO_LIST()                                                             \
+  OPERATOR(Mul) OPERATOR(Div) OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub)        \
+      OPERATOR(Shl) OPERATOR(Shr) OPERATOR(And) OPERATOR(Or) OPERATOR(Xor)
+
+namespace clang {
+
+// Reduce the diff between RecursiveASTVisitor / DataRecursiveASTVisitor to
+// make it easier to track changes and keep the two in sync.
+#define RecursiveASTVisitor DataRecursiveASTVisitor
+
+// A helper macro to implement short-circuiting when recursing.  It
+// invokes CALL_EXPR, which must be a method call, on the derived
+// object (s.t. a user of RecursiveASTVisitor can override the method
+// in CALL_EXPR).
+#define TRY_TO(CALL_EXPR)                                                      \
+  do {                                                                         \
+    if (!getDerived().CALL_EXPR)                                               \
+      return false;                                                            \
+  } while (0)
+
+/// \brief A class that does preorder depth-first traversal on the
+/// entire Clang AST and visits each node.
+///
+/// This class performs three distinct tasks:
+///   1. traverse the AST (i.e. go to each node);
+///   2. at a given node, walk up the class hierarchy, starting from
+///      the node's dynamic type, until the top-most class (e.g. Stmt,
+///      Decl, or Type) is reached.
+///   3. given a (node, class) combination, where 'class' is some base
+///      class of the dynamic type of 'node', call a user-overridable
+///      function to actually visit the node.
+///
+/// These tasks are done by three groups of methods, respectively:
+///   1. TraverseDecl(Decl *x) does task #1.  It is the entry point
+///      for traversing an AST rooted at x.  This method simply
+///      dispatches (i.e. forwards) to TraverseFoo(Foo *x) where Foo
+///      is the dynamic type of *x, which calls WalkUpFromFoo(x) and
+///      then recursively visits the child nodes of x.
+///      TraverseStmt(Stmt *x) and TraverseType(QualType x) work
+///      similarly.
+///   2. WalkUpFromFoo(Foo *x) does task #2.  It does not try to visit
+///      any child node of x.  Instead, it first calls WalkUpFromBar(x)
+///      where Bar is the direct parent class of Foo (unless Foo has
+///      no parent), and then calls VisitFoo(x) (see the next list item).
+///   3. VisitFoo(Foo *x) does task #3.
+///
+/// These three method groups are tiered (Traverse* > WalkUpFrom* >
+/// Visit*).  A method (e.g. Traverse*) may call methods from the same
+/// tier (e.g. other Traverse*) or one tier lower (e.g. WalkUpFrom*).
+/// It may not call methods from a higher tier.
+///
+/// Note that since WalkUpFromFoo() calls WalkUpFromBar() (where Bar
+/// is Foo's super class) before calling VisitFoo(), the result is
+/// that the Visit*() methods for a given node are called in the
+/// top-down order (e.g. for a node of type NamespaceDecl, the order will
+/// be VisitDecl(), VisitNamedDecl(), and then VisitNamespaceDecl()).
+///
+/// This scheme guarantees that all Visit*() calls for the same AST
+/// node are grouped together.  In other words, Visit*() methods for
+/// different nodes are never interleaved.
+///
+/// Stmts are traversed internally using a data queue to avoid a stack overflow
+/// with hugely nested ASTs.
+///
+/// Clients of this visitor should subclass the visitor (providing
+/// themselves as the template argument, using the curiously recurring
+/// template pattern) and override any of the Traverse*, WalkUpFrom*,
+/// and Visit* methods for declarations, types, statements,
+/// expressions, or other AST nodes where the visitor should customize
+/// behavior.  Most users only need to override Visit*.  Advanced
+/// users may override Traverse* and WalkUpFrom* to implement custom
+/// traversal strategies.  Returning false from one of these overridden
+/// functions will abort the entire traversal.
+///
+/// By default, this visitor tries to visit every part of the explicit
+/// source code exactly once.  The default policy towards templates
+/// is to descend into the 'pattern' class or function body, not any
+/// explicit or implicit instantiations.  Explicit specializations
+/// are still visited, and the patterns of partial specializations
+/// are visited separately.  This behavior can be changed by
+/// overriding shouldVisitTemplateInstantiations() in the derived class
+/// to return true, in which case all known implicit and explicit
+/// instantiations will be visited at the same time as the pattern
+/// from which they were produced.
+template <typename Derived> class RecursiveASTVisitor {
+public:
+  /// \brief Return a reference to the derived class.
+  Derived &getDerived() { return *static_cast<Derived *>(this); }
+
+  /// \brief Return whether this visitor should recurse into
+  /// template instantiations.
+  bool shouldVisitTemplateInstantiations() const { return false; }
+
+  /// \brief Return whether this visitor should recurse into the types of
+  /// TypeLocs.
+  bool shouldWalkTypesOfTypeLocs() const { return true; }
+
+  /// \brief Recursively visit a statement or expression, by
+  /// dispatching to Traverse*() based on the argument's dynamic type.
+  ///
+  /// \returns false if the visitation was terminated early, true
+  /// otherwise (including when the argument is NULL).
+  bool TraverseStmt(Stmt *S);
+
+  /// \brief Recursively visit a type, by dispatching to
+  /// Traverse*Type() based on the argument's getTypeClass() property.
+  ///
+  /// \returns false if the visitation was terminated early, true
+  /// otherwise (including when the argument is a Null type).
+  bool TraverseType(QualType T);
+
+  /// \brief Recursively visit a type with location, by dispatching to
+  /// Traverse*TypeLoc() based on the argument type's getTypeClass() property.
+  ///
+  /// \returns false if the visitation was terminated early, true
+  /// otherwise (including when the argument is a Null type location).
+  bool TraverseTypeLoc(TypeLoc TL);
+
+  /// \brief Recursively visit an attribute, by dispatching to
+  /// Traverse*Attr() based on the argument's dynamic type.
+  ///
+  /// \returns false if the visitation was terminated early, true
+  /// otherwise (including when the argument is a Null type location).
+  bool TraverseAttr(Attr *At);
+
+  /// \brief Recursively visit a declaration, by dispatching to
+  /// Traverse*Decl() based on the argument's dynamic type.
+  ///
+  /// \returns false if the visitation was terminated early, true
+  /// otherwise (including when the argument is NULL).
+  bool TraverseDecl(Decl *D);
+
+  /// \brief Recursively visit a C++ nested-name-specifier.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS);
+
+  /// \brief Recursively visit a C++ nested-name-specifier with location
+  /// information.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
+
+  /// \brief Recursively visit a name with its location information.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseDeclarationNameInfo(DeclarationNameInfo NameInfo);
+
+  /// \brief Recursively visit a template name and dispatch to the
+  /// appropriate method.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseTemplateName(TemplateName Template);
+
+  /// \brief Recursively visit a template argument and dispatch to the
+  /// appropriate method for the argument type.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  // FIXME: migrate callers to TemplateArgumentLoc instead.
+  bool TraverseTemplateArgument(const TemplateArgument &Arg);
+
+  /// \brief Recursively visit a template argument location and dispatch to the
+  /// appropriate method for the argument type.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc);
+
+  /// \brief Recursively visit a set of template arguments.
+  /// This can be overridden by a subclass, but it's not expected that
+  /// will be needed -- this visitor always dispatches to another.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  // FIXME: take a TemplateArgumentLoc* (or TemplateArgumentListInfo) instead.
+  bool TraverseTemplateArguments(const TemplateArgument *Args,
+                                 unsigned NumArgs);
+
+  /// \brief Recursively visit a constructor initializer.  This
+  /// automatically dispatches to another visitor for the initializer
+  /// expression, but not for the name of the initializer, so may
+  /// be overridden for clients that need access to the name.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseConstructorInitializer(CXXCtorInitializer *Init);
+
+  /// \brief Recursively visit a lambda capture.
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C);
+
+  /// \brief Recursively visit the body of a lambda expression.
+  ///
+  /// This provides a hook for visitors that need more context when visiting
+  /// \c LE->getBody().
+  ///
+  /// \returns false if the visitation was terminated early, true otherwise.
+  bool TraverseLambdaBody(LambdaExpr *LE);
+
+  // ---- Methods on Attrs ----
+
+  // \brief Visit an attribute.
+  bool VisitAttr(Attr *A) { return true; }
+
+// Declare Traverse* and empty Visit* for all Attr classes.
+#define ATTR_VISITOR_DECLS_ONLY
+#include "clang/AST/AttrVisitor.inc"
+#undef ATTR_VISITOR_DECLS_ONLY
+
+// ---- Methods on Stmts ----
+
+// Declare Traverse*() for all concrete Stmt classes.
+#define ABSTRACT_STMT(STMT)
+#define STMT(CLASS, PARENT) bool Traverse##CLASS(CLASS *S);
+#include "clang/AST/StmtNodes.inc"
+  // The above header #undefs ABSTRACT_STMT and STMT upon exit.
+
+  // Define WalkUpFrom*() and empty Visit*() for all Stmt classes.
+  bool WalkUpFromStmt(Stmt *S) { return getDerived().VisitStmt(S); }
+  bool VisitStmt(Stmt *S) { return true; }
+#define STMT(CLASS, PARENT)                                                    \
+  bool WalkUpFrom##CLASS(CLASS *S) {                                           \
+    TRY_TO(WalkUpFrom##PARENT(S));                                             \
+    TRY_TO(Visit##CLASS(S));                                                   \
+    return true;                                                               \
+  }                                                                            \
+  bool Visit##CLASS(CLASS *S) { return true; }
+#include "clang/AST/StmtNodes.inc"
+
+// Define Traverse*(), WalkUpFrom*(), and Visit*() for unary
+// operator methods.  Unary operators are not classes in themselves
+// (they're all opcodes in UnaryOperator) but do have visitors.
+#define OPERATOR(NAME)                                                         \
+  bool TraverseUnary##NAME(UnaryOperator *S) {                                 \
+    TRY_TO(WalkUpFromUnary##NAME(S));                                          \
+    StmtQueueAction StmtQueue(*this);                                          \
+    StmtQueue.queue(S->getSubExpr());                                          \
+    return true;                                                               \
+  }                                                                            \
+  bool WalkUpFromUnary##NAME(UnaryOperator *S) {                               \
+    TRY_TO(WalkUpFromUnaryOperator(S));                                        \
+    TRY_TO(VisitUnary##NAME(S));                                               \
+    return true;                                                               \
+  }                                                                            \
+  bool VisitUnary##NAME(UnaryOperator *S) { return true; }
+
+  UNARYOP_LIST()
+#undef OPERATOR
+
+// Define Traverse*(), WalkUpFrom*(), and Visit*() for binary
+// operator methods.  Binary operators are not classes in themselves
+// (they're all opcodes in BinaryOperator) but do have visitors.
+#define GENERAL_BINOP_FALLBACK(NAME, BINOP_TYPE)                               \
+  bool TraverseBin##NAME(BINOP_TYPE *S) {                                      \
+    TRY_TO(WalkUpFromBin##NAME(S));                                            \
+    StmtQueueAction StmtQueue(*this);                                          \
+    StmtQueue.queue(S->getLHS());                                              \
+    StmtQueue.queue(S->getRHS());                                              \
+    return true;                                                               \
+  }                                                                            \
+  bool WalkUpFromBin##NAME(BINOP_TYPE *S) {                                    \
+    TRY_TO(WalkUpFrom##BINOP_TYPE(S));                                         \
+    TRY_TO(VisitBin##NAME(S));                                                 \
+    return true;                                                               \
+  }                                                                            \
+  bool VisitBin##NAME(BINOP_TYPE *S) { return true; }
+
+#define OPERATOR(NAME) GENERAL_BINOP_FALLBACK(NAME, BinaryOperator)
+  BINOP_LIST()
+#undef OPERATOR
+
+// Define Traverse*(), WalkUpFrom*(), and Visit*() for compound
+// assignment methods.  Compound assignment operators are not
+// classes in themselves (they're all opcodes in
+// CompoundAssignOperator) but do have visitors.
+#define OPERATOR(NAME)                                                         \
+  GENERAL_BINOP_FALLBACK(NAME##Assign, CompoundAssignOperator)
+
+  CAO_LIST()
+#undef OPERATOR
+#undef GENERAL_BINOP_FALLBACK
+
+// ---- Methods on Types ----
+// FIXME: revamp to take TypeLoc's rather than Types.
+
+// Declare Traverse*() for all concrete Type classes.
+#define ABSTRACT_TYPE(CLASS, BASE)
+#define TYPE(CLASS, BASE) bool Traverse##CLASS##Type(CLASS##Type *T);
+#include "clang/AST/TypeNodes.def"
+  // The above header #undefs ABSTRACT_TYPE and TYPE upon exit.
+
+  // Define WalkUpFrom*() and empty Visit*() for all Type classes.
+  bool WalkUpFromType(Type *T) { return getDerived().VisitType(T); }
+  bool VisitType(Type *T) { return true; }
+#define TYPE(CLASS, BASE)                                                      \
+  bool WalkUpFrom##CLASS##Type(CLASS##Type *T) {                               \
+    TRY_TO(WalkUpFrom##BASE(T));                                               \
+    TRY_TO(Visit##CLASS##Type(T));                                             \
+    return true;                                                               \
+  }                                                                            \
+  bool Visit##CLASS##Type(CLASS##Type *T) { return true; }
+#include "clang/AST/TypeNodes.def"
+
+// ---- Methods on TypeLocs ----
+// FIXME: this currently just calls the matching Type methods
+
+// Declare Traverse*() for all concrete TypeLoc classes.
+#define ABSTRACT_TYPELOC(CLASS, BASE)
+#define TYPELOC(CLASS, BASE) bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL);
+#include "clang/AST/TypeLocNodes.def"
+  // The above header #undefs ABSTRACT_TYPELOC and TYPELOC upon exit.
+
+  // Define WalkUpFrom*() and empty Visit*() for all TypeLoc classes.
+  bool WalkUpFromTypeLoc(TypeLoc TL) { return getDerived().VisitTypeLoc(TL); }
+  bool VisitTypeLoc(TypeLoc TL) { return true; }
+
+  // QualifiedTypeLoc and UnqualTypeLoc are not declared in
+  // TypeNodes.def and thus need to be handled specially.
+  bool WalkUpFromQualifiedTypeLoc(QualifiedTypeLoc TL) {
+    return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc());
+  }
+  bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { return true; }
+  bool WalkUpFromUnqualTypeLoc(UnqualTypeLoc TL) {
+    return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc());
+  }
+  bool VisitUnqualTypeLoc(UnqualTypeLoc TL) { return true; }
+
+// Note that BASE includes trailing 'Type' which CLASS doesn't.
+#define TYPE(CLASS, BASE)                                                      \
+  bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL) {                         \
+    TRY_TO(WalkUpFrom##BASE##Loc(TL));                                         \
+    TRY_TO(Visit##CLASS##TypeLoc(TL));                                         \
+    return true;                                                               \
+  }                                                                            \
+  bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { return true; }
+#include "clang/AST/TypeNodes.def"
+
+// ---- Methods on Decls ----
+
+// Declare Traverse*() for all concrete Decl classes.
+#define ABSTRACT_DECL(DECL)
+#define DECL(CLASS, BASE) bool Traverse##CLASS##Decl(CLASS##Decl *D);
+#include "clang/AST/DeclNodes.inc"
+  // The above header #undefs ABSTRACT_DECL and DECL upon exit.
+
+  // Define WalkUpFrom*() and empty Visit*() for all Decl classes.
+  bool WalkUpFromDecl(Decl *D) { return getDerived().VisitDecl(D); }
+  bool VisitDecl(Decl *D) { return true; }
+#define DECL(CLASS, BASE)                                                      \
+  bool WalkUpFrom##CLASS##Decl(CLASS##Decl *D) {                               \
+    TRY_TO(WalkUpFrom##BASE(D));                                               \
+    TRY_TO(Visit##CLASS##Decl(D));                                             \
+    return true;                                                               \
+  }                                                                            \
+  bool Visit##CLASS##Decl(CLASS##Decl *D) { return true; }
+#include "clang/AST/DeclNodes.inc"
+
+private:
+  // These are helper methods used by more than one Traverse* method.
+  bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL);
+  bool TraverseClassInstantiations(ClassTemplateDecl *D);
+  bool TraverseVariableInstantiations(VarTemplateDecl *D);
+  bool TraverseFunctionInstantiations(FunctionTemplateDecl *D);
+  bool TraverseTemplateArgumentLocsHelper(const TemplateArgumentLoc *TAL,
+                                          unsigned Count);
+  bool TraverseArrayTypeLocHelper(ArrayTypeLoc TL);
+  bool TraverseRecordHelper(RecordDecl *D);
+  bool TraverseCXXRecordHelper(CXXRecordDecl *D);
+  bool TraverseDeclaratorHelper(DeclaratorDecl *D);
+  bool TraverseDeclContextHelper(DeclContext *DC);
+  bool TraverseFunctionHelper(FunctionDecl *D);
+  bool TraverseVarHelper(VarDecl *D);
+  bool TraverseOMPExecutableDirective(OMPExecutableDirective *S);
+  bool TraverseOMPClause(OMPClause *C);
+#define OPENMP_CLAUSE(Name, Class) bool Visit##Class(Class *C);
+#include "clang/Basic/OpenMPKinds.def"
+  /// \brief Process clauses with list of variables.
+  template <typename T> bool VisitOMPClauseList(T *Node);
+
+  typedef SmallVector<Stmt *, 16> StmtsTy;
+  typedef SmallVector<StmtsTy *, 4> QueuesTy;
+
+  QueuesTy Queues;
+
+  class NewQueueRAII {
+    RecursiveASTVisitor &RAV;
+
+  public:
+    NewQueueRAII(StmtsTy &queue, RecursiveASTVisitor &RAV) : RAV(RAV) {
+      RAV.Queues.push_back(&queue);
+    }
+    ~NewQueueRAII() { RAV.Queues.pop_back(); }
+  };
+
+  StmtsTy &getCurrentQueue() {
+    assert(!Queues.empty() && "base TraverseStmt was never called?");
+    return *Queues.back();
+  }
+
+public:
+  class StmtQueueAction {
+    StmtsTy &CurrQueue;
+
+  public:
+    explicit StmtQueueAction(RecursiveASTVisitor &RAV)
+        : CurrQueue(RAV.getCurrentQueue()) {}
+
+    void queue(Stmt *S) { CurrQueue.push_back(S); }
+  };
+};
+
+#define DISPATCH(NAME, CLASS, VAR)                                             \
+  return getDerived().Traverse##NAME(static_cast<CLASS *>(VAR))
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S) {
+  if (!S)
+    return true;
+
+  StmtsTy Queue, StmtsToEnqueue;
+  Queue.push_back(S);
+  NewQueueRAII NQ(StmtsToEnqueue, *this);
+
+  while (!Queue.empty()) {
+    S = Queue.pop_back_val();
+    if (!S)
+      continue;
+
+    StmtsToEnqueue.clear();
+
+#define DISPATCH_STMT(NAME, CLASS, VAR)                                        \
+  TRY_TO(Traverse##NAME(static_cast<CLASS *>(VAR)));                           \
+  break
+
+    // If we have a binary expr, dispatch to the subcode of the binop.  A smart
+    // optimizer (e.g. LLVM) will fold this comparison into the switch stmt
+    // below.
+    if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) {
+      switch (BinOp->getOpcode()) {
+#define OPERATOR(NAME)                                                         \
+  case BO_##NAME:                                                              \
+    DISPATCH_STMT(Bin##NAME, BinaryOperator, S);
+
+        BINOP_LIST()
+#undef OPERATOR
+#undef BINOP_LIST
+
+#define OPERATOR(NAME)                                                         \
+  case BO_##NAME##Assign:                                                      \
+    DISPATCH_STMT(Bin##NAME##Assign, CompoundAssignOperator, S);
+
+        CAO_LIST()
+#undef OPERATOR
+#undef CAO_LIST
+      }
+    } else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(S)) {
+      switch (UnOp->getOpcode()) {
+#define OPERATOR(NAME)                                                         \
+  case UO_##NAME:                                                              \
+    DISPATCH_STMT(Unary##NAME, UnaryOperator, S);
+
+        UNARYOP_LIST()
+#undef OPERATOR
+#undef UNARYOP_LIST
+      }
+    } else {
+
+      // Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt.
+      switch (S->getStmtClass()) {
+      case Stmt::NoStmtClass:
+        break;
+#define ABSTRACT_STMT(STMT)
+#define STMT(CLASS, PARENT)                                                    \
+  case Stmt::CLASS##Class:                                                     \
+    DISPATCH_STMT(CLASS, CLASS, S);
+#include "clang/AST/StmtNodes.inc"
+      }
+    }
+
+    for (SmallVectorImpl<Stmt *>::reverse_iterator RI = StmtsToEnqueue.rbegin(),
+                                                   RE = StmtsToEnqueue.rend();
+         RI != RE; ++RI)
+      Queue.push_back(*RI);
+  }
+
+  return true;
+}
+
+#undef DISPATCH_STMT
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseType(QualType T) {
+  if (T.isNull())
+    return true;
+
+  switch (T->getTypeClass()) {
+#define ABSTRACT_TYPE(CLASS, BASE)
+#define TYPE(CLASS, BASE)                                                      \
+  case Type::CLASS:                                                            \
+    DISPATCH(CLASS##Type, CLASS##Type, const_cast<Type *>(T.getTypePtr()));
+#include "clang/AST/TypeNodes.def"
+  }
+
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTypeLoc(TypeLoc TL) {
+  if (TL.isNull())
+    return true;
+
+  switch (TL.getTypeLocClass()) {
+#define ABSTRACT_TYPELOC(CLASS, BASE)
+#define TYPELOC(CLASS, BASE)                                                   \
+  case TypeLoc::CLASS:                                                         \
+    return getDerived().Traverse##CLASS##TypeLoc(TL.castAs<CLASS##TypeLoc>());
+#include "clang/AST/TypeLocNodes.def"
+  }
+
+  return true;
+}
+
+// Define the Traverse*Attr(Attr* A) methods
+#define VISITORCLASS RecursiveASTVisitor
+#include "clang/AST/AttrVisitor.inc"
+#undef VISITORCLASS
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseDecl(Decl *D) {
+  if (!D)
+    return true;
+
+  // As a syntax visitor, we want to ignore declarations for
+  // implicitly-defined declarations (ones not typed explicitly by the
+  // user).
+  if (D->isImplicit())
+    return true;
+
+  switch (D->getKind()) {
+#define ABSTRACT_DECL(DECL)
+#define DECL(CLASS, BASE)                                                      \
+  case Decl::CLASS:                                                            \
+    if (!getDerived().Traverse##CLASS##Decl(static_cast<CLASS##Decl *>(D)))    \
+      return false;                                                            \
+    break;
+#include "clang/AST/DeclNodes.inc"
+  }
+
+  // Visit any attributes attached to this declaration.
+  for (auto *I : D->attrs()) {
+    if (!getDerived().TraverseAttr(I))
+      return false;
+  }
+  return true;
+}
+
+#undef DISPATCH
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifier(
+    NestedNameSpecifier *NNS) {
+  if (!NNS)
+    return true;
+
+  if (NNS->getPrefix())
+    TRY_TO(TraverseNestedNameSpecifier(NNS->getPrefix()));
+
+  switch (NNS->getKind()) {
+  case NestedNameSpecifier::Identifier:
+  case NestedNameSpecifier::Namespace:
+  case NestedNameSpecifier::NamespaceAlias:
+  case NestedNameSpecifier::Global:
+    return true;
+
+  case NestedNameSpecifier::TypeSpec:
+  case NestedNameSpecifier::TypeSpecWithTemplate:
+    TRY_TO(TraverseType(QualType(NNS->getAsType(), 0)));
+  }
+
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifierLoc(
+    NestedNameSpecifierLoc NNS) {
+  if (!NNS)
+    return true;
+
+  if (NestedNameSpecifierLoc Prefix = NNS.getPrefix())
+    TRY_TO(TraverseNestedNameSpecifierLoc(Prefix));
+
+  switch (NNS.getNestedNameSpecifier()->getKind()) {
+  case NestedNameSpecifier::Identifier:
+  case NestedNameSpecifier::Namespace:
+  case NestedNameSpecifier::NamespaceAlias:
+  case NestedNameSpecifier::Global:
+    return true;
+
+  case NestedNameSpecifier::TypeSpec:
+  case NestedNameSpecifier::TypeSpecWithTemplate:
+    TRY_TO(TraverseTypeLoc(NNS.getTypeLoc()));
+    break;
+  }
+
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseDeclarationNameInfo(
+    DeclarationNameInfo NameInfo) {
+  switch (NameInfo.getName().getNameKind()) {
+  case DeclarationName::CXXConstructorName:
+  case DeclarationName::CXXDestructorName:
+  case DeclarationName::CXXConversionFunctionName:
+    if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo())
+      TRY_TO(TraverseTypeLoc(TSInfo->getTypeLoc()));
+
+    break;
+
+  case DeclarationName::Identifier:
+  case DeclarationName::ObjCZeroArgSelector:
+  case DeclarationName::ObjCOneArgSelector:
+  case DeclarationName::ObjCMultiArgSelector:
+  case DeclarationName::CXXOperatorName:
+  case DeclarationName::CXXLiteralOperatorName:
+  case DeclarationName::CXXUsingDirective:
+    break;
+  }
+
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateName(TemplateName Template) {
+  if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
+    TRY_TO(TraverseNestedNameSpecifier(DTN->getQualifier()));
+  else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
+    TRY_TO(TraverseNestedNameSpecifier(QTN->getQualifier()));
+
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateArgument(
+    const TemplateArgument &Arg) {
+  switch (Arg.getKind()) {
+  case TemplateArgument::Null:
+  case TemplateArgument::Declaration:
+  case TemplateArgument::Integral:
+  case TemplateArgument::NullPtr:
+    return true;
+
+  case TemplateArgument::Type:
+    return getDerived().TraverseType(Arg.getAsType());
+
+  case TemplateArgument::Template:
+  case TemplateArgument::TemplateExpansion:
+    return getDerived().TraverseTemplateName(
+        Arg.getAsTemplateOrTemplatePattern());
+
+  case TemplateArgument::Expression:
+    return getDerived().TraverseStmt(Arg.getAsExpr());
+
+  case TemplateArgument::Pack:
+    return getDerived().TraverseTemplateArguments(Arg.pack_begin(),
+                                                  Arg.pack_size());
+  }
+
+  return true;
+}
+
+// FIXME: no template name location?
+// FIXME: no source locations for a template argument pack?
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc(
+    const TemplateArgumentLoc &ArgLoc) {
+  const TemplateArgument &Arg = ArgLoc.getArgument();
+
+  switch (Arg.getKind()) {
+  case TemplateArgument::Null:
+  case TemplateArgument::Declaration:
+  case TemplateArgument::Integral:
+  case TemplateArgument::NullPtr:
+    return true;
+
+  case TemplateArgument::Type: {
+    // FIXME: how can TSI ever be NULL?
+    if (TypeSourceInfo *TSI = ArgLoc.getTypeSourceInfo())
+      return getDerived().TraverseTypeLoc(TSI->getTypeLoc());
+    else
+      return getDerived().TraverseType(Arg.getAsType());
+  }
+
+  case TemplateArgument::Template:
+  case TemplateArgument::TemplateExpansion:
+    if (ArgLoc.getTemplateQualifierLoc())
+      TRY_TO(getDerived().TraverseNestedNameSpecifierLoc(
+          ArgLoc.getTemplateQualifierLoc()));
+    return getDerived().TraverseTemplateName(
+        Arg.getAsTemplateOrTemplatePattern());
+
+  case TemplateArgument::Expression:
+    return getDerived().TraverseStmt(ArgLoc.getSourceExpression());
+
+  case TemplateArgument::Pack:
+    return getDerived().TraverseTemplateArguments(Arg.pack_begin(),
+                                                  Arg.pack_size());
+  }
+
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateArguments(
+    const TemplateArgument *Args, unsigned NumArgs) {
+  for (unsigned I = 0; I != NumArgs; ++I) {
+    TRY_TO(TraverseTemplateArgument(Args[I]));
+  }
+
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseConstructorInitializer(
+    CXXCtorInitializer *Init) {
+  if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo())
+    TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
+
+  if (Init->isWritten())
+    TRY_TO(TraverseStmt(Init->getInit()));
+  return true;
+}
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::TraverseLambdaCapture(LambdaExpr *LE,
+                                                    const LambdaCapture *C) {
+  if (C->isInitCapture())
+    TRY_TO(TraverseDecl(C->getCapturedVar()));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseLambdaBody(LambdaExpr *LE) {
+  StmtQueueAction StmtQueue(*this);
+  StmtQueue.queue(LE->getBody());
+  return true;
+}
+
+// ----------------- Type traversal -----------------
+
+// This macro makes available a variable T, the passed-in type.
+#define DEF_TRAVERSE_TYPE(TYPE, CODE)                                          \
+  template <typename Derived>                                                  \
+  bool RecursiveASTVisitor<Derived>::Traverse##TYPE(TYPE *T) {                 \
+    TRY_TO(WalkUpFrom##TYPE(T));                                               \
+    { CODE; }                                                                  \
+    return true;                                                               \
+  }
+
+DEF_TRAVERSE_TYPE(BuiltinType, {})
+
+DEF_TRAVERSE_TYPE(ComplexType, { TRY_TO(TraverseType(T->getElementType())); })
+
+DEF_TRAVERSE_TYPE(PointerType, { TRY_TO(TraverseType(T->getPointeeType())); })
+
+DEF_TRAVERSE_TYPE(BlockPointerType,
+                  { TRY_TO(TraverseType(T->getPointeeType())); })
+
+DEF_TRAVERSE_TYPE(LValueReferenceType,
+                  { TRY_TO(TraverseType(T->getPointeeType())); })
+
+DEF_TRAVERSE_TYPE(RValueReferenceType,
+                  { TRY_TO(TraverseType(T->getPointeeType())); })
+
+DEF_TRAVERSE_TYPE(MemberPointerType, {
+  TRY_TO(TraverseType(QualType(T->getClass(), 0)));
+  TRY_TO(TraverseType(T->getPointeeType()));
+})
+
+DEF_TRAVERSE_TYPE(AdjustedType, { TRY_TO(TraverseType(T->getOriginalType())); })
+
+DEF_TRAVERSE_TYPE(DecayedType, { TRY_TO(TraverseType(T->getOriginalType())); })
+
+DEF_TRAVERSE_TYPE(ConstantArrayType,
+                  { TRY_TO(TraverseType(T->getElementType())); })
+
+DEF_TRAVERSE_TYPE(IncompleteArrayType,
+                  { TRY_TO(TraverseType(T->getElementType())); })
+
+DEF_TRAVERSE_TYPE(VariableArrayType, {
+  TRY_TO(TraverseType(T->getElementType()));
+  TRY_TO(TraverseStmt(T->getSizeExpr()));
+})
+
+DEF_TRAVERSE_TYPE(DependentSizedArrayType, {
+  TRY_TO(TraverseType(T->getElementType()));
+  if (T->getSizeExpr())
+    TRY_TO(TraverseStmt(T->getSizeExpr()));
+})
+
+DEF_TRAVERSE_TYPE(DependentSizedExtVectorType, {
+  if (T->getSizeExpr())
+    TRY_TO(TraverseStmt(T->getSizeExpr()));
+  TRY_TO(TraverseType(T->getElementType()));
+})
+
+DEF_TRAVERSE_TYPE(VectorType, { TRY_TO(TraverseType(T->getElementType())); })
+
+DEF_TRAVERSE_TYPE(ExtVectorType, { TRY_TO(TraverseType(T->getElementType())); })
+
+DEF_TRAVERSE_TYPE(FunctionNoProtoType,
+                  { TRY_TO(TraverseType(T->getReturnType())); })
+
+DEF_TRAVERSE_TYPE(FunctionProtoType, {
+  TRY_TO(TraverseType(T->getReturnType()));
+
+  for (const auto &A : T->param_types()) {
+    TRY_TO(TraverseType(A));
+  }
+
+  for (const auto &E : T->exceptions()) {
+    TRY_TO(TraverseType(E));
+  }
+})
+
+DEF_TRAVERSE_TYPE(UnresolvedUsingType, {})
+DEF_TRAVERSE_TYPE(TypedefType, {})
+
+DEF_TRAVERSE_TYPE(TypeOfExprType,
+                  { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); })
+
+DEF_TRAVERSE_TYPE(TypeOfType, { TRY_TO(TraverseType(T->getUnderlyingType())); })
+
+DEF_TRAVERSE_TYPE(DecltypeType,
+                  { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); })
+
+DEF_TRAVERSE_TYPE(UnaryTransformType, {
+  TRY_TO(TraverseType(T->getBaseType()));
+  TRY_TO(TraverseType(T->getUnderlyingType()));
+})
+
+DEF_TRAVERSE_TYPE(AutoType, { TRY_TO(TraverseType(T->getDeducedType())); })
+
+DEF_TRAVERSE_TYPE(RecordType, {})
+DEF_TRAVERSE_TYPE(EnumType, {})
+DEF_TRAVERSE_TYPE(TemplateTypeParmType, {})
+DEF_TRAVERSE_TYPE(SubstTemplateTypeParmType, {})
+DEF_TRAVERSE_TYPE(SubstTemplateTypeParmPackType, {})
+
+DEF_TRAVERSE_TYPE(TemplateSpecializationType, {
+  TRY_TO(TraverseTemplateName(T->getTemplateName()));
+  TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
+})
+
+DEF_TRAVERSE_TYPE(InjectedClassNameType, {})
+
+DEF_TRAVERSE_TYPE(AttributedType,
+                  { TRY_TO(TraverseType(T->getModifiedType())); })
+
+DEF_TRAVERSE_TYPE(ParenType, { TRY_TO(TraverseType(T->getInnerType())); })
+
+DEF_TRAVERSE_TYPE(ElaboratedType, {
+  if (T->getQualifier()) {
+    TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
+  }
+  TRY_TO(TraverseType(T->getNamedType()));
+})
+
+DEF_TRAVERSE_TYPE(DependentNameType,
+                  { TRY_TO(TraverseNestedNameSpecifier(T->getQualifier())); })
+
+DEF_TRAVERSE_TYPE(DependentTemplateSpecializationType, {
+  TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
+  TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
+})
+
+DEF_TRAVERSE_TYPE(PackExpansionType, { TRY_TO(TraverseType(T->getPattern())); })
+
+DEF_TRAVERSE_TYPE(ObjCInterfaceType, {})
+
+DEF_TRAVERSE_TYPE(ObjCObjectType, {
+  // We have to watch out here because an ObjCInterfaceType's base
+  // type is itself.
+  if (T->getBaseType().getTypePtr() != T)
+    TRY_TO(TraverseType(T->getBaseType()));
+})
+
+DEF_TRAVERSE_TYPE(ObjCObjectPointerType,
+                  { TRY_TO(TraverseType(T->getPointeeType())); })
+
+DEF_TRAVERSE_TYPE(AtomicType, { TRY_TO(TraverseType(T->getValueType())); })
+
+#undef DEF_TRAVERSE_TYPE
+
+// ----------------- TypeLoc traversal -----------------
+
+// This macro makes available a variable TL, the passed-in TypeLoc.
+// If requested, it calls WalkUpFrom* for the Type in the given TypeLoc,
+// in addition to WalkUpFrom* for the TypeLoc itself, such that existing
+// clients that override the WalkUpFrom*Type() and/or Visit*Type() methods
+// continue to work.
+#define DEF_TRAVERSE_TYPELOC(TYPE, CODE)                                       \
+  template <typename Derived>                                                  \
+  bool RecursiveASTVisitor<Derived>::Traverse##TYPE##Loc(TYPE##Loc TL) {       \
+    if (getDerived().shouldWalkTypesOfTypeLocs())                              \
+      TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE *>(TL.getTypePtr())));           \
+    TRY_TO(WalkUpFrom##TYPE##Loc(TL));                                         \
+    { CODE; }                                                                  \
+    return true;                                                               \
+  }
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::TraverseQualifiedTypeLoc(QualifiedTypeLoc TL) {
+  // Move this over to the 'main' typeloc tree.  Note that this is a
+  // move -- we pretend that we were really looking at the unqualified
+  // typeloc all along -- rather than a recursion, so we don't follow
+  // the normal CRTP plan of going through
+  // getDerived().TraverseTypeLoc.  If we did, we'd be traversing
+  // twice for the same type (once as a QualifiedTypeLoc version of
+  // the type, once as an UnqualifiedTypeLoc version of the type),
+  // which in effect means we'd call VisitTypeLoc twice with the
+  // 'same' type.  This solves that problem, at the cost of never
+  // seeing the qualified version of the type (unless the client
+  // subclasses TraverseQualifiedTypeLoc themselves).  It's not a
+  // perfect solution.  A perfect solution probably requires making
+  // QualifiedTypeLoc a wrapper around TypeLoc -- like QualType is a
+  // wrapper around Type* -- rather than being its own class in the
+  // type hierarchy.
+  return TraverseTypeLoc(TL.getUnqualifiedLoc());
+}
+
+DEF_TRAVERSE_TYPELOC(BuiltinType, {})
+
+// FIXME: ComplexTypeLoc is unfinished
+DEF_TRAVERSE_TYPELOC(ComplexType, {
+  TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+})
+
+DEF_TRAVERSE_TYPELOC(PointerType,
+                     { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
+
+DEF_TRAVERSE_TYPELOC(BlockPointerType,
+                     { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
+
+DEF_TRAVERSE_TYPELOC(LValueReferenceType,
+                     { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
+
+DEF_TRAVERSE_TYPELOC(RValueReferenceType,
+                     { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
+
+// FIXME: location of base class?
+// We traverse this in the type case as well, but how is it not reached through
+// the pointee type?
+DEF_TRAVERSE_TYPELOC(MemberPointerType, {
+  TRY_TO(TraverseType(QualType(TL.getTypePtr()->getClass(), 0)));
+  TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
+})
+
+DEF_TRAVERSE_TYPELOC(AdjustedType,
+                     { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); })
+
+DEF_TRAVERSE_TYPELOC(DecayedType,
+                     { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); })
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseArrayTypeLocHelper(ArrayTypeLoc TL) {
+  // This isn't available for ArrayType, but is for the ArrayTypeLoc.
+  TRY_TO(TraverseStmt(TL.getSizeExpr()));
+  return true;
+}
+
+DEF_TRAVERSE_TYPELOC(ConstantArrayType, {
+  TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+  return TraverseArrayTypeLocHelper(TL);
+})
+
+DEF_TRAVERSE_TYPELOC(IncompleteArrayType, {
+  TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+  return TraverseArrayTypeLocHelper(TL);
+})
+
+DEF_TRAVERSE_TYPELOC(VariableArrayType, {
+  TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+  return TraverseArrayTypeLocHelper(TL);
+})
+
+DEF_TRAVERSE_TYPELOC(DependentSizedArrayType, {
+  TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+  return TraverseArrayTypeLocHelper(TL);
+})
+
+// FIXME: order? why not size expr first?
+// FIXME: base VectorTypeLoc is unfinished
+DEF_TRAVERSE_TYPELOC(DependentSizedExtVectorType, {
+  if (TL.getTypePtr()->getSizeExpr())
+    TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
+  TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+})
+
+// FIXME: VectorTypeLoc is unfinished
+DEF_TRAVERSE_TYPELOC(VectorType, {
+  TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+})
+
+// FIXME: size and attributes
+// FIXME: base VectorTypeLoc is unfinished
+DEF_TRAVERSE_TYPELOC(ExtVectorType, {
+  TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+})
+
+DEF_TRAVERSE_TYPELOC(FunctionNoProtoType,
+                     { TRY_TO(TraverseTypeLoc(TL.getReturnLoc())); })
+
+// FIXME: location of exception specifications (attributes?)
+DEF_TRAVERSE_TYPELOC(FunctionProtoType, {
+  TRY_TO(TraverseTypeLoc(TL.getReturnLoc()));
+
+  const FunctionProtoType *T = TL.getTypePtr();
+
+  for (unsigned I = 0, E = TL.getNumParams(); I != E; ++I) {
+    if (TL.getParam(I)) {
+      TRY_TO(TraverseDecl(TL.getParam(I)));
+    } else if (I < T->getNumParams()) {
+      TRY_TO(TraverseType(T->getParamType(I)));
+    }
+  }
+
+  for (const auto &E : T->exceptions()) {
+    TRY_TO(TraverseType(E));
+  }
+})
+
+DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, {})
+DEF_TRAVERSE_TYPELOC(TypedefType, {})
+
+DEF_TRAVERSE_TYPELOC(TypeOfExprType,
+                     { TRY_TO(TraverseStmt(TL.getUnderlyingExpr())); })
+
+DEF_TRAVERSE_TYPELOC(TypeOfType, {
+  TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
+})
+
+// FIXME: location of underlying expr
+DEF_TRAVERSE_TYPELOC(DecltypeType, {
+  TRY_TO(TraverseStmt(TL.getTypePtr()->getUnderlyingExpr()));
+})
+
+DEF_TRAVERSE_TYPELOC(UnaryTransformType, {
+  TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_TYPELOC(AutoType, {
+  TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
+})
+
+DEF_TRAVERSE_TYPELOC(RecordType, {})
+DEF_TRAVERSE_TYPELOC(EnumType, {})
+DEF_TRAVERSE_TYPELOC(TemplateTypeParmType, {})
+DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmType, {})
+DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmPackType, {})
+
+// FIXME: use the loc for the template name?
+DEF_TRAVERSE_TYPELOC(TemplateSpecializationType, {
+  TRY_TO(TraverseTemplateName(TL.getTypePtr()->getTemplateName()));
+  for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
+    TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
+  }
+})
+
+DEF_TRAVERSE_TYPELOC(InjectedClassNameType, {})
+
+DEF_TRAVERSE_TYPELOC(ParenType, { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
+
+DEF_TRAVERSE_TYPELOC(AttributedType,
+                     { TRY_TO(TraverseTypeLoc(TL.getModifiedLoc())); })
+
+DEF_TRAVERSE_TYPELOC(ElaboratedType, {
+  if (TL.getQualifierLoc()) {
+    TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
+  }
+  TRY_TO(TraverseTypeLoc(TL.getNamedTypeLoc()));
+})
+
+DEF_TRAVERSE_TYPELOC(DependentNameType, {
+  TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
+})
+
+DEF_TRAVERSE_TYPELOC(DependentTemplateSpecializationType, {
+  if (TL.getQualifierLoc()) {
+    TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
+  }
+
+  for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
+    TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
+  }
+})
+
+DEF_TRAVERSE_TYPELOC(PackExpansionType,
+                     { TRY_TO(TraverseTypeLoc(TL.getPatternLoc())); })
+
+DEF_TRAVERSE_TYPELOC(ObjCInterfaceType, {})
+
+DEF_TRAVERSE_TYPELOC(ObjCObjectType, {
+  // We have to watch out here because an ObjCInterfaceType's base
+  // type is itself.
+  if (TL.getTypePtr()->getBaseType().getTypePtr() != TL.getTypePtr())
+    TRY_TO(TraverseTypeLoc(TL.getBaseLoc()));
+})
+
+DEF_TRAVERSE_TYPELOC(ObjCObjectPointerType,
+                     { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
+
+DEF_TRAVERSE_TYPELOC(AtomicType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
+
+#undef DEF_TRAVERSE_TYPELOC
+
+// ----------------- Decl traversal -----------------
+//
+// For a Decl, we automate (in the DEF_TRAVERSE_DECL macro) traversing
+// the children that come from the DeclContext associated with it.
+// Therefore each Traverse* only needs to worry about children other
+// than those.
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) {
+  if (!DC)
+    return true;
+
+  for (auto *Child : DC->decls()) {
+    // BlockDecls and CapturedDecls are traversed through BlockExprs and
+    // CapturedStmts respectively.
+    if (!isa<BlockDecl>(Child) && !isa<CapturedDecl>(Child))
+      TRY_TO(TraverseDecl(Child));
+  }
+
+  return true;
+}
+
+// This macro makes available a variable D, the passed-in decl.
+#define DEF_TRAVERSE_DECL(DECL, CODE)                                          \
+  template <typename Derived>                                                  \
+  bool RecursiveASTVisitor<Derived>::Traverse##DECL(DECL *D) {                 \
+    TRY_TO(WalkUpFrom##DECL(D));                                               \
+    { CODE; }                                                                  \
+    TRY_TO(TraverseDeclContextHelper(dyn_cast<DeclContext>(D)));               \
+    return true;                                                               \
+  }
+
+DEF_TRAVERSE_DECL(AccessSpecDecl, {})
+
+DEF_TRAVERSE_DECL(BlockDecl, {
+  if (TypeSourceInfo *TInfo = D->getSignatureAsWritten())
+    TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
+  TRY_TO(TraverseStmt(D->getBody()));
+  for (const auto &I : D->captures()) {
+    if (I.hasCopyExpr()) {
+      TRY_TO(TraverseStmt(I.getCopyExpr()));
+    }
+  }
+  // This return statement makes sure the traversal of nodes in
+  // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
+  // is skipped - don't remove it.
+  return true;
+})
+
+DEF_TRAVERSE_DECL(CapturedDecl, {
+  TRY_TO(TraverseStmt(D->getBody()));
+  // This return statement makes sure the traversal of nodes in
+  // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
+  // is skipped - don't remove it.
+  return true;
+})
+
+DEF_TRAVERSE_DECL(EmptyDecl, {})
+
+DEF_TRAVERSE_DECL(FileScopeAsmDecl,
+                  { TRY_TO(TraverseStmt(D->getAsmString())); })
+
+DEF_TRAVERSE_DECL(ImportDecl, {})
+
+DEF_TRAVERSE_DECL(FriendDecl, {
+  // Friend is either decl or a type.
+  if (D->getFriendType())
+    TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
+  else
+    TRY_TO(TraverseDecl(D->getFriendDecl()));
+})
+
+DEF_TRAVERSE_DECL(FriendTemplateDecl, {
+  if (D->getFriendType())
+    TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
+  else
+    TRY_TO(TraverseDecl(D->getFriendDecl()));
+  for (unsigned I = 0, E = D->getNumTemplateParameters(); I < E; ++I) {
+    TemplateParameterList *TPL = D->getTemplateParameterList(I);
+    for (TemplateParameterList::iterator ITPL = TPL->begin(), ETPL = TPL->end();
+         ITPL != ETPL; ++ITPL) {
+      TRY_TO(TraverseDecl(*ITPL));
+    }
+  }
+})
+
+DEF_TRAVERSE_DECL(ClassScopeFunctionSpecializationDecl,
+                  { TRY_TO(TraverseDecl(D->getSpecialization())); })
+
+DEF_TRAVERSE_DECL(LinkageSpecDecl, {})
+
+DEF_TRAVERSE_DECL(ObjCPropertyImplDecl, {// FIXME: implement this
+                                        })
+
+DEF_TRAVERSE_DECL(StaticAssertDecl, {
+  TRY_TO(TraverseStmt(D->getAssertExpr()));
+  TRY_TO(TraverseStmt(D->getMessage()));
+})
+
+DEF_TRAVERSE_DECL(
+    TranslationUnitDecl,
+    {// Code in an unnamed namespace shows up automatically in
+     // decls_begin()/decls_end().  Thus we don't need to recurse on
+     // D->getAnonymousNamespace().
+    })
+
+DEF_TRAVERSE_DECL(NamespaceAliasDecl, {
+  // We shouldn't traverse an aliased namespace, since it will be
+  // defined (and, therefore, traversed) somewhere else.
+  //
+  // This return statement makes sure the traversal of nodes in
+  // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
+  // is skipped - don't remove it.
+  return true;
+})
+
+DEF_TRAVERSE_DECL(LabelDecl, {// There is no code in a LabelDecl.
+                             })
+
+DEF_TRAVERSE_DECL(
+    NamespaceDecl,
+    {// Code in an unnamed namespace shows up automatically in
+     // decls_begin()/decls_end().  Thus we don't need to recurse on
+     // D->getAnonymousNamespace().
+    })
+
+DEF_TRAVERSE_DECL(ObjCCompatibleAliasDecl, {// FIXME: implement
+                                           })
+
+DEF_TRAVERSE_DECL(ObjCCategoryDecl, {// FIXME: implement
+                                    })
+
+DEF_TRAVERSE_DECL(ObjCCategoryImplDecl, {// FIXME: implement
+                                        })
+
+DEF_TRAVERSE_DECL(ObjCImplementationDecl, {// FIXME: implement
+                                          })
+
+DEF_TRAVERSE_DECL(ObjCInterfaceDecl, {// FIXME: implement
+                                     })
+
+DEF_TRAVERSE_DECL(ObjCProtocolDecl, {// FIXME: implement
+                                    })
+
+DEF_TRAVERSE_DECL(ObjCMethodDecl, {
+  if (D->getReturnTypeSourceInfo()) {
+    TRY_TO(TraverseTypeLoc(D->getReturnTypeSourceInfo()->getTypeLoc()));
+  }
+  for (ObjCMethodDecl::param_iterator I = D->param_begin(), E = D->param_end();
+       I != E; ++I) {
+    TRY_TO(TraverseDecl(*I));
+  }
+  if (D->isThisDeclarationADefinition()) {
+    TRY_TO(TraverseStmt(D->getBody()));
+  }
+  return true;
+})
+
+DEF_TRAVERSE_DECL(ObjCPropertyDecl, {
+  if (D->getTypeSourceInfo())
+    TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
+  else
+    TRY_TO(TraverseType(D->getType()));
+  return true;
+})
+
+DEF_TRAVERSE_DECL(UsingDecl, {
+  TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+  TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
+})
+
+DEF_TRAVERSE_DECL(UsingDirectiveDecl, {
+  TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+})
+
+DEF_TRAVERSE_DECL(UsingShadowDecl, {})
+
+DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, {
+  for (auto *I : D->varlists()) {
+    TRY_TO(TraverseStmt(I));
+  }
+})
+
+// A helper method for TemplateDecl's children.
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper(
+    TemplateParameterList *TPL) {
+  if (TPL) {
+    for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end();
+         I != E; ++I) {
+      TRY_TO(TraverseDecl(*I));
+    }
+  }
+  return true;
+}
+
+// A helper method for traversing the implicit instantiations of a
+// class template.
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseClassInstantiations(
+    ClassTemplateDecl *D) {
+  for (auto *SD : D->specializations()) {
+    for (auto *RD : SD->redecls()) {
+      // We don't want to visit injected-class-names in this traversal.
+      if (cast<CXXRecordDecl>(RD)->isInjectedClassName())
+        continue;
+
+      switch (
+          cast<ClassTemplateSpecializationDecl>(RD)->getSpecializationKind()) {
+      // Visit the implicit instantiations with the requested pattern.
+      case TSK_Undeclared:
+      case TSK_ImplicitInstantiation:
+        TRY_TO(TraverseDecl(RD));
+        break;
+
+      // We don't need to do anything on an explicit instantiation
+      // or explicit specialization because there will be an explicit
+      // node for it elsewhere.
+      case TSK_ExplicitInstantiationDeclaration:
+      case TSK_ExplicitInstantiationDefinition:
+      case TSK_ExplicitSpecialization:
+        break;
+      }
+    }
+  }
+
+  return true;
+}
+
+DEF_TRAVERSE_DECL(ClassTemplateDecl, {
+  CXXRecordDecl *TempDecl = D->getTemplatedDecl();
+  TRY_TO(TraverseDecl(TempDecl));
+  TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
+
+  // By default, we do not traverse the instantiations of
+  // class templates since they do not appear in the user code. The
+  // following code optionally traverses them.
+  //
+  // We only traverse the class instantiations when we see the canonical
+  // declaration of the template, to ensure we only visit them once.
+  if (getDerived().shouldVisitTemplateInstantiations() &&
+      D == D->getCanonicalDecl())
+    TRY_TO(TraverseClassInstantiations(D));
+
+  // Note that getInstantiatedFromMemberTemplate() is just a link
+  // from a template instantiation back to the template from which
+  // it was instantiated, and thus should not be traversed.
+})
+
+// A helper method for traversing the implicit instantiations of a
+// class template.
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseVariableInstantiations(
+    VarTemplateDecl *D) {
+  for (auto *SD : D->specializations()) {
+    for (auto *RD : SD->redecls()) {
+      switch (
+          cast<VarTemplateSpecializationDecl>(RD)->getSpecializationKind()) {
+      // Visit the implicit instantiations with the requested pattern.
+      case TSK_Undeclared:
+      case TSK_ImplicitInstantiation:
+        TRY_TO(TraverseDecl(RD));
+        break;
+
+      // We don't need to do anything on an explicit instantiation
+      // or explicit specialization because there will be an explicit
+      // node for it elsewhere.
+      case TSK_ExplicitInstantiationDeclaration:
+      case TSK_ExplicitInstantiationDefinition:
+      case TSK_ExplicitSpecialization:
+        break;
+      }
+    }
+  }
+
+  return true;
+}
+
+DEF_TRAVERSE_DECL(VarTemplateDecl, {
+  VarDecl *TempDecl = D->getTemplatedDecl();
+  TRY_TO(TraverseDecl(TempDecl));
+  TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
+
+  // By default, we do not traverse the instantiations of
+  // variable templates since they do not appear in the user code. The
+  // following code optionally traverses them.
+  //
+  // We only traverse the variable instantiations when we see the canonical
+  // declaration of the template, to ensure we only visit them once.
+  if (getDerived().shouldVisitTemplateInstantiations() &&
+      D == D->getCanonicalDecl())
+    TRY_TO(TraverseVariableInstantiations(D));
+
+  // Note that getInstantiatedFromMemberTemplate() is just a link
+  // from a template instantiation back to the template from which
+  // it was instantiated, and thus should not be traversed.
+})
+
+// A helper method for traversing the instantiations of a
+// function while skipping its specializations.
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseFunctionInstantiations(
+    FunctionTemplateDecl *D) {
+  for (auto *FD : D->specializations()) {
+    for (auto *RD : FD->redecls()) {
+      switch (RD->getTemplateSpecializationKind()) {
+      case TSK_Undeclared:
+      case TSK_ImplicitInstantiation:
+        // We don't know what kind of FunctionDecl this is.
+        TRY_TO(TraverseDecl(RD));
+        break;
+
+      // No need to visit explicit instantiations, we'll find the node
+      // eventually.
+      // FIXME: This is incorrect; there is no other node for an explicit
+      // instantiation of a function template specialization.
+      case TSK_ExplicitInstantiationDeclaration:
+      case TSK_ExplicitInstantiationDefinition:
+        break;
+
+      case TSK_ExplicitSpecialization:
+        break;
+      }
+    }
+  }
+
+  return true;
+}
+
+DEF_TRAVERSE_DECL(FunctionTemplateDecl, {
+  TRY_TO(TraverseDecl(D->getTemplatedDecl()));
+  TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
+
+  // By default, we do not traverse the instantiations of
+  // function templates since they do not appear in the user code. The
+  // following code optionally traverses them.
+  //
+  // We only traverse the function instantiations when we see the canonical
+  // declaration of the template, to ensure we only visit them once.
+  if (getDerived().shouldVisitTemplateInstantiations() &&
+      D == D->getCanonicalDecl())
+    TRY_TO(TraverseFunctionInstantiations(D));
+})
+
+DEF_TRAVERSE_DECL(TemplateTemplateParmDecl, {
+  // D is the "T" in something like
+  //   template <template <typename> class T> class container { };
+  TRY_TO(TraverseDecl(D->getTemplatedDecl()));
+  if (D->hasDefaultArgument()) {
+    TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
+  }
+  TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
+})
+
+DEF_TRAVERSE_DECL(TemplateTypeParmDecl, {
+  // D is the "T" in something like "template<typename T> class vector;"
+  if (D->getTypeForDecl())
+    TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
+  if (D->hasDefaultArgument())
+    TRY_TO(TraverseTypeLoc(D->getDefaultArgumentInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_DECL(TypedefDecl, {
+  TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
+  // We shouldn't traverse D->getTypeForDecl(); it's a result of
+  // declaring the typedef, not something that was written in the
+  // source.
+})
+
+DEF_TRAVERSE_DECL(TypeAliasDecl, {
+  TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
+  // We shouldn't traverse D->getTypeForDecl(); it's a result of
+  // declaring the type alias, not something that was written in the
+  // source.
+})
+
+DEF_TRAVERSE_DECL(TypeAliasTemplateDecl, {
+  TRY_TO(TraverseDecl(D->getTemplatedDecl()));
+  TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
+})
+
+DEF_TRAVERSE_DECL(UnresolvedUsingTypenameDecl, {
+  // A dependent using declaration which was marked with 'typename'.
+  //   template<class T> class A : public B<T> { using typename B<T>::foo; };
+  TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+  // We shouldn't traverse D->getTypeForDecl(); it's a result of
+  // declaring the type, not something that was written in the
+  // source.
+})
+
+DEF_TRAVERSE_DECL(EnumDecl, {
+  if (D->getTypeForDecl())
+    TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
+
+  TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+  // The enumerators are already traversed by
+  // decls_begin()/decls_end().
+})
+
+// Helper methods for RecordDecl and its children.
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseRecordHelper(RecordDecl *D) {
+  // We shouldn't traverse D->getTypeForDecl(); it's a result of
+  // declaring the type, not something that was written in the source.
+
+  TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseCXXRecordHelper(CXXRecordDecl *D) {
+  if (!TraverseRecordHelper(D))
+    return false;
+  if (D->isCompleteDefinition()) {
+    for (const auto &I : D->bases()) {
+      TRY_TO(TraverseTypeLoc(I.getTypeSourceInfo()->getTypeLoc()));
+    }
+    // We don't traverse the friends or the conversions, as they are
+    // already in decls_begin()/decls_end().
+  }
+  return true;
+}
+
+DEF_TRAVERSE_DECL(RecordDecl, { TRY_TO(TraverseRecordHelper(D)); })
+
+DEF_TRAVERSE_DECL(CXXRecordDecl, { TRY_TO(TraverseCXXRecordHelper(D)); })
+
+DEF_TRAVERSE_DECL(ClassTemplateSpecializationDecl, {
+  // For implicit instantiations ("set<int> x;"), we don't want to
+  // recurse at all, since the instatiated class isn't written in
+  // the source code anywhere.  (Note the instatiated *type* --
+  // set<int> -- is written, and will still get a callback of
+  // TemplateSpecializationType).  For explicit instantiations
+  // ("template set<int>;"), we do need a callback, since this
+  // is the only callback that's made for this instantiation.
+  // We use getTypeAsWritten() to distinguish.
+  if (TypeSourceInfo *TSI = D->getTypeAsWritten())
+    TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
+
+  if (!getDerived().shouldVisitTemplateInstantiations() &&
+      D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization)
+    // Returning from here skips traversing the
+    // declaration context of the ClassTemplateSpecializationDecl
+    // (embedded in the DEF_TRAVERSE_DECL() macro)
+    // which contains the instantiated members of the class.
+    return true;
+})
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper(
+    const TemplateArgumentLoc *TAL, unsigned Count) {
+  for (unsigned I = 0; I < Count; ++I) {
+    TRY_TO(TraverseTemplateArgumentLoc(TAL[I]));
+  }
+  return true;
+}
+
+DEF_TRAVERSE_DECL(ClassTemplatePartialSpecializationDecl, {
+  // The partial specialization.
+  if (TemplateParameterList *TPL = D->getTemplateParameters()) {
+    for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end();
+         I != E; ++I) {
+      TRY_TO(TraverseDecl(*I));
+    }
+  }
+  // The args that remains unspecialized.
+  TRY_TO(TraverseTemplateArgumentLocsHelper(
+      D->getTemplateArgsAsWritten()->getTemplateArgs(),
+      D->getTemplateArgsAsWritten()->NumTemplateArgs));
+
+  // Don't need the ClassTemplatePartialSpecializationHelper, even
+  // though that's our parent class -- we already visit all the
+  // template args here.
+  TRY_TO(TraverseCXXRecordHelper(D));
+
+  // Instantiations will have been visited with the primary template.
+})
+
+DEF_TRAVERSE_DECL(EnumConstantDecl, { TRY_TO(TraverseStmt(D->getInitExpr())); })
+
+DEF_TRAVERSE_DECL(UnresolvedUsingValueDecl, {
+  // Like UnresolvedUsingTypenameDecl, but without the 'typename':
+  //    template <class T> Class A : public Base<T> { using Base<T>::foo; };
+  TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+  TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
+})
+
+DEF_TRAVERSE_DECL(IndirectFieldDecl, {})
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) {
+  TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+  if (D->getTypeSourceInfo())
+    TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
+  else
+    TRY_TO(TraverseType(D->getType()));
+  return true;
+}
+
+DEF_TRAVERSE_DECL(MSPropertyDecl, { TRY_TO(TraverseDeclaratorHelper(D)); })
+
+DEF_TRAVERSE_DECL(FieldDecl, {
+  TRY_TO(TraverseDeclaratorHelper(D));
+  if (D->isBitField())
+    TRY_TO(TraverseStmt(D->getBitWidth()));
+  else if (D->hasInClassInitializer())
+    TRY_TO(TraverseStmt(D->getInClassInitializer()));
+})
+
+DEF_TRAVERSE_DECL(ObjCAtDefsFieldDecl, {
+  TRY_TO(TraverseDeclaratorHelper(D));
+  if (D->isBitField())
+    TRY_TO(TraverseStmt(D->getBitWidth()));
+  // FIXME: implement the rest.
+})
+
+DEF_TRAVERSE_DECL(ObjCIvarDecl, {
+  TRY_TO(TraverseDeclaratorHelper(D));
+  if (D->isBitField())
+    TRY_TO(TraverseStmt(D->getBitWidth()));
+  // FIXME: implement the rest.
+})
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
+  TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+  TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
+
+  // If we're an explicit template specialization, iterate over the
+  // template args that were explicitly specified.  If we were doing
+  // this in typing order, we'd do it between the return type and
+  // the function args, but both are handled by the FunctionTypeLoc
+  // above, so we have to choose one side.  I've decided to do before.
+  if (const FunctionTemplateSpecializationInfo *FTSI =
+          D->getTemplateSpecializationInfo()) {
+    if (FTSI->getTemplateSpecializationKind() != TSK_Undeclared &&
+        FTSI->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) {
+      // A specialization might not have explicit template arguments if it has
+      // a templated return type and concrete arguments.
+      if (const ASTTemplateArgumentListInfo *TALI =
+              FTSI->TemplateArgumentsAsWritten) {
+        TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getTemplateArgs(),
+                                                  TALI->NumTemplateArgs));
+      }
+    }
+  }
+
+  // Visit the function type itself, which can be either
+  // FunctionNoProtoType or FunctionProtoType, or a typedef.  This
+  // also covers the return type and the function parameters,
+  // including exception specifications.
+  TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
+
+  if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
+    // Constructor initializers.
+    for (auto *I : Ctor->inits()) {
+      TRY_TO(TraverseConstructorInitializer(I));
+    }
+  }
+
+  if (D->isThisDeclarationADefinition()) {
+    TRY_TO(TraverseStmt(D->getBody())); // Function body.
+  }
+  return true;
+}
+
+DEF_TRAVERSE_DECL(FunctionDecl, {
+  // We skip decls_begin/decls_end, which are already covered by
+  // TraverseFunctionHelper().
+  return TraverseFunctionHelper(D);
+})
+
+DEF_TRAVERSE_DECL(CXXMethodDecl, {
+  // We skip decls_begin/decls_end, which are already covered by
+  // TraverseFunctionHelper().
+  return TraverseFunctionHelper(D);
+})
+
+DEF_TRAVERSE_DECL(CXXConstructorDecl, {
+  // We skip decls_begin/decls_end, which are already covered by
+  // TraverseFunctionHelper().
+  return TraverseFunctionHelper(D);
+})
+
+// CXXConversionDecl is the declaration of a type conversion operator.
+// It's not a cast expression.
+DEF_TRAVERSE_DECL(CXXConversionDecl, {
+  // We skip decls_begin/decls_end, which are already covered by
+  // TraverseFunctionHelper().
+  return TraverseFunctionHelper(D);
+})
+
+DEF_TRAVERSE_DECL(CXXDestructorDecl, {
+  // We skip decls_begin/decls_end, which are already covered by
+  // TraverseFunctionHelper().
+  return TraverseFunctionHelper(D);
+})
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseVarHelper(VarDecl *D) {
+  TRY_TO(TraverseDeclaratorHelper(D));
+  // Default params are taken care of when we traverse the ParmVarDecl.
+  if (!isa<ParmVarDecl>(D))
+    TRY_TO(TraverseStmt(D->getInit()));
+  return true;
+}
+
+DEF_TRAVERSE_DECL(VarDecl, { TRY_TO(TraverseVarHelper(D)); })
+
+DEF_TRAVERSE_DECL(VarTemplateSpecializationDecl, {
+  // For implicit instantiations, we don't want to
+  // recurse at all, since the instatiated class isn't written in
+  // the source code anywhere.
+  if (TypeSourceInfo *TSI = D->getTypeAsWritten())
+    TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
+
+  if (!getDerived().shouldVisitTemplateInstantiations() &&
+      D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization)
+    // Returning from here skips traversing the
+    // declaration context of the VarTemplateSpecializationDecl
+    // (embedded in the DEF_TRAVERSE_DECL() macro).
+    return true;
+})
+
+DEF_TRAVERSE_DECL(VarTemplatePartialSpecializationDecl, {
+  // The partial specialization.
+  if (TemplateParameterList *TPL = D->getTemplateParameters()) {
+    for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end();
+         I != E; ++I) {
+      TRY_TO(TraverseDecl(*I));
+    }
+  }
+  // The args that remains unspecialized.
+  TRY_TO(TraverseTemplateArgumentLocsHelper(
+      D->getTemplateArgsAsWritten()->getTemplateArgs(),
+      D->getTemplateArgsAsWritten()->NumTemplateArgs));
+
+  // Don't need the VarTemplatePartialSpecializationHelper, even
+  // though that's our parent class -- we already visit all the
+  // template args here.
+  TRY_TO(TraverseVarHelper(D));
+
+  // Instantiations will have been visited with the primary
+  // template.
+})
+
+DEF_TRAVERSE_DECL(ImplicitParamDecl, { TRY_TO(TraverseVarHelper(D)); })
+
+DEF_TRAVERSE_DECL(NonTypeTemplateParmDecl, {
+  // A non-type template parameter, e.g. "S" in template<int S> class Foo ...
+  TRY_TO(TraverseDeclaratorHelper(D));
+  TRY_TO(TraverseStmt(D->getDefaultArgument()));
+})
+
+DEF_TRAVERSE_DECL(ParmVarDecl, {
+  TRY_TO(TraverseVarHelper(D));
+
+  if (D->hasDefaultArg() && D->hasUninstantiatedDefaultArg() &&
+      !D->hasUnparsedDefaultArg())
+    TRY_TO(TraverseStmt(D->getUninstantiatedDefaultArg()));
+
+  if (D->hasDefaultArg() && !D->hasUninstantiatedDefaultArg() &&
+      !D->hasUnparsedDefaultArg())
+    TRY_TO(TraverseStmt(D->getDefaultArg()));
+})
+
+#undef DEF_TRAVERSE_DECL
+
+// ----------------- Stmt traversal -----------------
+//
+// For stmts, we automate (in the DEF_TRAVERSE_STMT macro) iterating
+// over the children defined in children() (every stmt defines these,
+// though sometimes the range is empty).  Each individual Traverse*
+// method only needs to worry about children other than those.  To see
+// what children() does for a given class, see, e.g.,
+//   http://clang.llvm.org/doxygen/Stmt_8cpp_source.html
+
+// This macro makes available a variable S, the passed-in stmt.
+#define DEF_TRAVERSE_STMT(STMT, CODE)                                          \
+  template <typename Derived>                                                  \
+  bool RecursiveASTVisitor<Derived>::Traverse##STMT(STMT *S) {                 \
+    TRY_TO(WalkUpFrom##STMT(S));                                               \
+    StmtQueueAction StmtQueue(*this);                                          \
+    { CODE; }                                                                  \
+    for (Stmt::child_range range = S->children(); range; ++range) {            \
+      StmtQueue.queue(*range);                                                 \
+    }                                                                          \
+    return true;                                                               \
+  }
+
+DEF_TRAVERSE_STMT(GCCAsmStmt, {
+  StmtQueue.queue(S->getAsmString());
+  for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) {
+    StmtQueue.queue(S->getInputConstraintLiteral(I));
+  }
+  for (unsigned I = 0, E = S->getNumOutputs(); I < E; ++I) {
+    StmtQueue.queue(S->getOutputConstraintLiteral(I));
+  }
+  for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) {
+    StmtQueue.queue(S->getClobberStringLiteral(I));
+  }
+  // children() iterates over inputExpr and outputExpr.
+})
+
+DEF_TRAVERSE_STMT(
+    MSAsmStmt,
+    {// FIXME: MS Asm doesn't currently parse Constraints, Clobbers, etc.  Once
+     // added this needs to be implemented.
+    })
+
+DEF_TRAVERSE_STMT(CXXCatchStmt, {
+  TRY_TO(TraverseDecl(S->getExceptionDecl()));
+  // children() iterates over the handler block.
+})
+
+DEF_TRAVERSE_STMT(DeclStmt, {
+  for (auto *I : S->decls()) {
+    TRY_TO(TraverseDecl(I));
+  }
+  // Suppress the default iteration over children() by
+  // returning.  Here's why: A DeclStmt looks like 'type var [=
+  // initializer]'.  The decls above already traverse over the
+  // initializers, so we don't have to do it again (which
+  // children() would do).
+  return true;
+})
+
+// These non-expr stmts (most of them), do not need any action except
+// iterating over the children.
+DEF_TRAVERSE_STMT(BreakStmt, {})
+DEF_TRAVERSE_STMT(CXXTryStmt, {})
+DEF_TRAVERSE_STMT(CaseStmt, {})
+DEF_TRAVERSE_STMT(CompoundStmt, {})
+DEF_TRAVERSE_STMT(ContinueStmt, {})
+DEF_TRAVERSE_STMT(DefaultStmt, {})
+DEF_TRAVERSE_STMT(DoStmt, {})
+DEF_TRAVERSE_STMT(ForStmt, {})
+DEF_TRAVERSE_STMT(GotoStmt, {})
+DEF_TRAVERSE_STMT(IfStmt, {})
+DEF_TRAVERSE_STMT(IndirectGotoStmt, {})
+DEF_TRAVERSE_STMT(LabelStmt, {})
+DEF_TRAVERSE_STMT(AttributedStmt, {})
+DEF_TRAVERSE_STMT(NullStmt, {})
+DEF_TRAVERSE_STMT(ObjCAtCatchStmt, {})
+DEF_TRAVERSE_STMT(ObjCAtFinallyStmt, {})
+DEF_TRAVERSE_STMT(ObjCAtSynchronizedStmt, {})
+DEF_TRAVERSE_STMT(ObjCAtThrowStmt, {})
+DEF_TRAVERSE_STMT(ObjCAtTryStmt, {})
+DEF_TRAVERSE_STMT(ObjCForCollectionStmt, {})
+DEF_TRAVERSE_STMT(ObjCAutoreleasePoolStmt, {})
+DEF_TRAVERSE_STMT(CXXForRangeStmt, {})
+DEF_TRAVERSE_STMT(MSDependentExistsStmt, {
+  TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+  TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
+})
+DEF_TRAVERSE_STMT(ReturnStmt, {})
+DEF_TRAVERSE_STMT(SwitchStmt, {})
+DEF_TRAVERSE_STMT(WhileStmt, {})
+
+DEF_TRAVERSE_STMT(CXXDependentScopeMemberExpr, {
+  TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+  TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
+  if (S->hasExplicitTemplateArgs()) {
+    TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
+                                              S->getNumTemplateArgs()));
+  }
+})
+
+DEF_TRAVERSE_STMT(DeclRefExpr, {
+  TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+  TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
+  TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
+                                            S->getNumTemplateArgs()));
+})
+
+DEF_TRAVERSE_STMT(DependentScopeDeclRefExpr, {
+  TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+  TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
+  if (S->hasExplicitTemplateArgs()) {
+    TRY_TO(TraverseTemplateArgumentLocsHelper(
+        S->getExplicitTemplateArgs().getTemplateArgs(),
+        S->getNumTemplateArgs()));
+  }
+})
+
+DEF_TRAVERSE_STMT(MemberExpr, {
+  TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+  TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
+  TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
+                                            S->getNumTemplateArgs()));
+})
+
+DEF_TRAVERSE_STMT(
+    ImplicitCastExpr,
+    {// We don't traverse the cast type, as it's not written in the
+     // source code.
+    })
+
+DEF_TRAVERSE_STMT(CStyleCastExpr, {
+  TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(CXXFunctionalCastExpr, {
+  TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(CXXConstCastExpr, {
+  TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(CXXDynamicCastExpr, {
+  TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(CXXReinterpretCastExpr, {
+  TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(CXXStaticCastExpr, {
+  TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
+
+// InitListExpr is a tricky one, because we want to do all our work on
+// the syntactic form of the listexpr, but this method takes the
+// semantic form by default.  We can't use the macro helper because it
+// calls WalkUp*() on the semantic form, before our code can convert
+// to the syntactic form.
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseInitListExpr(InitListExpr *S) {
+  if (InitListExpr *Syn = S->getSyntacticForm())
+    S = Syn;
+  TRY_TO(WalkUpFromInitListExpr(S));
+  StmtQueueAction StmtQueue(*this);
+  // All we need are the default actions.  FIXME: use a helper function.
+  for (Stmt::child_range range = S->children(); range; ++range) {
+    StmtQueue.queue(*range);
+  }
+  return true;
+}
+
+// GenericSelectionExpr is a special case because the types and expressions
+// are interleaved.  We also need to watch out for null types (default
+// generic associations).
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseGenericSelectionExpr(
+    GenericSelectionExpr *S) {
+  TRY_TO(WalkUpFromGenericSelectionExpr(S));
+  StmtQueueAction StmtQueue(*this);
+  StmtQueue.queue(S->getControllingExpr());
+  for (unsigned i = 0; i != S->getNumAssocs(); ++i) {
+    if (TypeSourceInfo *TS = S->getAssocTypeSourceInfo(i))
+      TRY_TO(TraverseTypeLoc(TS->getTypeLoc()));
+    StmtQueue.queue(S->getAssocExpr(i));
+  }
+  return true;
+}
+
+// PseudoObjectExpr is a special case because of the wierdness with
+// syntactic expressions and opaque values.
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::TraversePseudoObjectExpr(PseudoObjectExpr *S) {
+  TRY_TO(WalkUpFromPseudoObjectExpr(S));
+  StmtQueueAction StmtQueue(*this);
+  StmtQueue.queue(S->getSyntacticForm());
+  for (PseudoObjectExpr::semantics_iterator i = S->semantics_begin(),
+                                            e = S->semantics_end();
+       i != e; ++i) {
+    Expr *sub = *i;
+    if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(sub))
+      sub = OVE->getSourceExpr();
+    StmtQueue.queue(sub);
+  }
+  return true;
+}
+
+DEF_TRAVERSE_STMT(CXXScalarValueInitExpr, {
+  // This is called for code like 'return T()' where T is a built-in
+  // (i.e. non-class) type.
+  TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(CXXNewExpr, {
+  // The child-iterator will pick up the other arguments.
+  TRY_TO(TraverseTypeLoc(S->getAllocatedTypeSourceInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(OffsetOfExpr, {
+  // The child-iterator will pick up the expression representing
+  // the field.
+  // FIMXE: for code like offsetof(Foo, a.b.c), should we get
+  // making a MemberExpr callbacks for Foo.a, Foo.a.b, and Foo.a.b.c?
+  TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(UnaryExprOrTypeTraitExpr, {
+  // The child-iterator will pick up the arg if it's an expression,
+  // but not if it's a type.
+  if (S->isArgumentType())
+    TRY_TO(TraverseTypeLoc(S->getArgumentTypeInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(CXXTypeidExpr, {
+  // The child-iterator will pick up the arg if it's an expression,
+  // but not if it's a type.
+  if (S->isTypeOperand())
+    TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(MSPropertyRefExpr, {
+  TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+})
+
+DEF_TRAVERSE_STMT(CXXUuidofExpr, {
+  // The child-iterator will pick up the arg if it's an expression,
+  // but not if it's a type.
+  if (S->isTypeOperand())
+    TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(TypeTraitExpr, {
+  for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
+    TRY_TO(TraverseTypeLoc(S->getArg(I)->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(ArrayTypeTraitExpr, {
+  TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(ExpressionTraitExpr,
+                  { StmtQueue.queue(S->getQueriedExpression()); })
+
+DEF_TRAVERSE_STMT(VAArgExpr, {
+  // The child-iterator will pick up the expression argument.
+  TRY_TO(TraverseTypeLoc(S->getWrittenTypeInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(CXXTemporaryObjectExpr, {
+  // This is called for code like 'return T()' where T is a class type.
+  TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+})
+
+// Walk only the visible parts of lambda expressions.
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseLambdaExpr(LambdaExpr *S) {
+  TRY_TO(WalkUpFromLambdaExpr(S));
+
+  for (LambdaExpr::capture_iterator C = S->explicit_capture_begin(),
+                                    CEnd = S->explicit_capture_end();
+       C != CEnd; ++C) {
+    TRY_TO(TraverseLambdaCapture(S, C));
+  }
+
+  if (S->hasExplicitParameters() || S->hasExplicitResultType()) {
+    TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
+    if (S->hasExplicitParameters() && S->hasExplicitResultType()) {
+      // Visit the whole type.
+      TRY_TO(TraverseTypeLoc(TL));
+    } else if (FunctionProtoTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) {
+      if (S->hasExplicitParameters()) {
+        // Visit parameters.
+        for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I) {
+          TRY_TO(TraverseDecl(Proto.getParam(I)));
+        }
+      } else {
+        TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
+      }
+    }
+  }
+
+  TRY_TO(TraverseLambdaBody(S));
+  return true;
+}
+
+DEF_TRAVERSE_STMT(CXXUnresolvedConstructExpr, {
+  // This is called for code like 'T()', where T is a template argument.
+  TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+})
+
+// These expressions all might take explicit template arguments.
+// We traverse those if so.  FIXME: implement these.
+DEF_TRAVERSE_STMT(CXXConstructExpr, {})
+DEF_TRAVERSE_STMT(CallExpr, {})
+DEF_TRAVERSE_STMT(CXXMemberCallExpr, {})
+
+// These exprs (most of them), do not need any action except iterating
+// over the children.
+DEF_TRAVERSE_STMT(AddrLabelExpr, {})
+DEF_TRAVERSE_STMT(ArraySubscriptExpr, {})
+DEF_TRAVERSE_STMT(BlockExpr, {
+  TRY_TO(TraverseDecl(S->getBlockDecl()));
+  return true; // no child statements to loop through.
+})
+DEF_TRAVERSE_STMT(ChooseExpr, {})
+DEF_TRAVERSE_STMT(CompoundLiteralExpr, {
+  TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+})
+DEF_TRAVERSE_STMT(CXXBindTemporaryExpr, {})
+DEF_TRAVERSE_STMT(CXXBoolLiteralExpr, {})
+DEF_TRAVERSE_STMT(CXXDefaultArgExpr, {})
+DEF_TRAVERSE_STMT(CXXDefaultInitExpr, {})
+DEF_TRAVERSE_STMT(CXXDeleteExpr, {})
+DEF_TRAVERSE_STMT(ExprWithCleanups, {})
+DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, {})
+DEF_TRAVERSE_STMT(CXXStdInitializerListExpr, {})
+DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, {
+  TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+  if (TypeSourceInfo *ScopeInfo = S->getScopeTypeInfo())
+    TRY_TO(TraverseTypeLoc(ScopeInfo->getTypeLoc()));
+  if (TypeSourceInfo *DestroyedTypeInfo = S->getDestroyedTypeInfo())
+    TRY_TO(TraverseTypeLoc(DestroyedTypeInfo->getTypeLoc()));
+})
+DEF_TRAVERSE_STMT(CXXThisExpr, {})
+DEF_TRAVERSE_STMT(CXXThrowExpr, {})
+DEF_TRAVERSE_STMT(UserDefinedLiteral, {})
+DEF_TRAVERSE_STMT(DesignatedInitExpr, {})
+DEF_TRAVERSE_STMT(ExtVectorElementExpr, {})
+DEF_TRAVERSE_STMT(GNUNullExpr, {})
+DEF_TRAVERSE_STMT(ImplicitValueInitExpr, {})
+DEF_TRAVERSE_STMT(ObjCBoolLiteralExpr, {})
+DEF_TRAVERSE_STMT(ObjCEncodeExpr, {
+  if (TypeSourceInfo *TInfo = S->getEncodedTypeSourceInfo())
+    TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
+})
+DEF_TRAVERSE_STMT(ObjCIsaExpr, {})
+DEF_TRAVERSE_STMT(ObjCIvarRefExpr, {})
+DEF_TRAVERSE_STMT(ObjCMessageExpr, {
+  if (TypeSourceInfo *TInfo = S->getClassReceiverTypeInfo())
+    TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
+})
+DEF_TRAVERSE_STMT(ObjCPropertyRefExpr, {})
+DEF_TRAVERSE_STMT(ObjCSubscriptRefExpr, {})
+DEF_TRAVERSE_STMT(ObjCProtocolExpr, {})
+DEF_TRAVERSE_STMT(ObjCSelectorExpr, {})
+DEF_TRAVERSE_STMT(ObjCIndirectCopyRestoreExpr, {})
+DEF_TRAVERSE_STMT(ObjCBridgedCastExpr, {
+  TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
+DEF_TRAVERSE_STMT(ParenExpr, {})
+DEF_TRAVERSE_STMT(ParenListExpr, {})
+DEF_TRAVERSE_STMT(PredefinedExpr, {})
+DEF_TRAVERSE_STMT(ShuffleVectorExpr, {})
+DEF_TRAVERSE_STMT(ConvertVectorExpr, {})
+DEF_TRAVERSE_STMT(StmtExpr, {})
+DEF_TRAVERSE_STMT(UnresolvedLookupExpr, {
+  TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+  if (S->hasExplicitTemplateArgs()) {
+    TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
+                                              S->getNumTemplateArgs()));
+  }
+})
+
+DEF_TRAVERSE_STMT(UnresolvedMemberExpr, {
+  TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+  if (S->hasExplicitTemplateArgs()) {
+    TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
+                                              S->getNumTemplateArgs()));
+  }
+})
+
+DEF_TRAVERSE_STMT(SEHTryStmt, {})
+DEF_TRAVERSE_STMT(SEHExceptStmt, {})
+DEF_TRAVERSE_STMT(SEHFinallyStmt, {})
+DEF_TRAVERSE_STMT(SEHLeaveStmt, {})
+DEF_TRAVERSE_STMT(CapturedStmt, { TRY_TO(TraverseDecl(S->getCapturedDecl())); })
+
+DEF_TRAVERSE_STMT(CXXOperatorCallExpr, {})
+DEF_TRAVERSE_STMT(OpaqueValueExpr, {})
+DEF_TRAVERSE_STMT(CUDAKernelCallExpr, {})
+
+// These operators (all of them) do not need any action except
+// iterating over the children.
+DEF_TRAVERSE_STMT(BinaryConditionalOperator, {})
+DEF_TRAVERSE_STMT(ConditionalOperator, {})
+DEF_TRAVERSE_STMT(UnaryOperator, {})
+DEF_TRAVERSE_STMT(BinaryOperator, {})
+DEF_TRAVERSE_STMT(CompoundAssignOperator, {})
+DEF_TRAVERSE_STMT(CXXNoexceptExpr, {})
+DEF_TRAVERSE_STMT(PackExpansionExpr, {})
+DEF_TRAVERSE_STMT(SizeOfPackExpr, {})
+DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, {})
+DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, {})
+DEF_TRAVERSE_STMT(FunctionParmPackExpr, {})
+DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, {})
+DEF_TRAVERSE_STMT(AtomicExpr, {})
+
+// These literals (all of them) do not need any action.
+DEF_TRAVERSE_STMT(IntegerLiteral, {})
+DEF_TRAVERSE_STMT(CharacterLiteral, {})
+DEF_TRAVERSE_STMT(FloatingLiteral, {})
+DEF_TRAVERSE_STMT(ImaginaryLiteral, {})
+DEF_TRAVERSE_STMT(StringLiteral, {})
+DEF_TRAVERSE_STMT(ObjCStringLiteral, {})
+DEF_TRAVERSE_STMT(ObjCBoxedExpr, {})
+DEF_TRAVERSE_STMT(ObjCArrayLiteral, {})
+DEF_TRAVERSE_STMT(ObjCDictionaryLiteral, {})
+
+// Traverse OpenCL: AsType, Convert.
+DEF_TRAVERSE_STMT(AsTypeExpr, {})
+
+// OpenMP directives.
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseOMPExecutableDirective(
+    OMPExecutableDirective *S) {
+  for (auto *C : S->clauses()) {
+    TRY_TO(TraverseOMPClause(C));
+  }
+  return true;
+}
+
+DEF_TRAVERSE_STMT(OMPParallelDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPSimdDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPForDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPSectionsDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPSectionDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPSingleDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPMasterDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPCriticalDirective, {
+  TRY_TO(TraverseDeclarationNameInfo(S->getDirectiveName()));
+  TRY_TO(TraverseOMPExecutableDirective(S));
+})
+
+DEF_TRAVERSE_STMT(OMPParallelForDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPParallelSectionsDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTaskDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTaskyieldDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPBarrierDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTaskwaitDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPFlushDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+// OpenMP clauses.
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
+  if (!C)
+    return true;
+  switch (C->getClauseKind()) {
+#define OPENMP_CLAUSE(Name, Class)                                             \
+  case OMPC_##Name:                                                            \
+    TRY_TO(Visit##Class(static_cast<Class *>(C)));                             \
+    break;
+#include "clang/Basic/OpenMPKinds.def"
+  case OMPC_threadprivate:
+  case OMPC_unknown:
+    break;
+  }
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPIfClause(OMPIfClause *C) {
+  TRY_TO(TraverseStmt(C->getCondition()));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPFinalClause(OMPFinalClause *C) {
+  TRY_TO(TraverseStmt(C->getCondition()));
+  return true;
+}
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) {
+  TRY_TO(TraverseStmt(C->getNumThreads()));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPSafelenClause(OMPSafelenClause *C) {
+  TRY_TO(TraverseStmt(C->getSafelen()));
+  return true;
+}
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::VisitOMPCollapseClause(OMPCollapseClause *C) {
+  TRY_TO(TraverseStmt(C->getNumForLoops()));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPDefaultClause(OMPDefaultClause *) {
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPProcBindClause(OMPProcBindClause *) {
+  return true;
+}
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::VisitOMPScheduleClause(OMPScheduleClause *C) {
+  TRY_TO(TraverseStmt(C->getChunkSize()));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPOrderedClause(OMPOrderedClause *) {
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPNowaitClause(OMPNowaitClause *) {
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPUntiedClause(OMPUntiedClause *) {
+  return true;
+}
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::VisitOMPMergeableClause(OMPMergeableClause *) {
+  return true;
+}
+
+template <typename Derived>
+template <typename T>
+bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
+  for (auto *E : Node->varlists()) {
+    TRY_TO(TraverseStmt(E));
+  }
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPPrivateClause(OMPPrivateClause *C) {
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPFirstprivateClause(
+    OMPFirstprivateClause *C) {
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPLastprivateClause(
+    OMPLastprivateClause *C) {
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPSharedClause(OMPSharedClause *C) {
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPLinearClause(OMPLinearClause *C) {
+  TRY_TO(TraverseStmt(C->getStep()));
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPAlignedClause(OMPAlignedClause *C) {
+  TRY_TO(TraverseStmt(C->getAlignment()));
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPCopyinClause(OMPCopyinClause *C) {
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPCopyprivateClause(
+    OMPCopyprivateClause *C) {
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::VisitOMPReductionClause(OMPReductionClause *C) {
+  TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
+  TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPFlushClause(OMPFlushClause *C) {
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+// FIXME: look at the following tricky-seeming exprs to see if we
+// need to recurse on anything.  These are ones that have methods
+// returning decls or qualtypes or nestednamespecifier -- though I'm
+// not sure if they own them -- or just seemed very complicated, or
+// had lots of sub-types to explore.
+//
+// VisitOverloadExpr and its children: recurse on template args? etc?
+
+// FIXME: go through all the stmts and exprs again, and see which of them
+// create new types, and recurse on the types (TypeLocs?) of those.
+// Candidates:
+//
+//    http://clang.llvm.org/doxygen/classclang_1_1CXXTypeidExpr.html
+//    http://clang.llvm.org/doxygen/classclang_1_1UnaryExprOrTypeTraitExpr.html
+//    http://clang.llvm.org/doxygen/classclang_1_1TypesCompatibleExpr.html
+//    Every class that has getQualifier.
+
+#undef DEF_TRAVERSE_STMT
+
+#undef TRY_TO
+
+#undef RecursiveASTVisitor
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIBCLANG_RECURSIVEASTVISITOR_H
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 244a7b8..ce8b8b7 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -21,6 +21,7 @@
 #include "clang/AST/Redeclarable.h"
 #include "clang/AST/Type.h"
 #include "clang/Basic/Linkage.h"
+#include "clang/Basic/OperatorKinds.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/Support/Compiler.h"
@@ -51,8 +52,7 @@
 /// A client can read the relevant info using TypeLoc wrappers, e.g:
 /// @code
 /// TypeLoc TL = TypeSourceInfo->getTypeLoc();
-/// if (PointerLoc *PL = dyn_cast<PointerLoc>(&TL))
-///   PL->getStarLoc().print(OS, SrcMgr);
+/// TL.getStartLoc().print(OS, SrcMgr);
 /// @endcode
 ///
 class TypeSourceInfo {
@@ -79,9 +79,9 @@
   NamespaceDecl *AnonymousNamespace;
 
   explicit TranslationUnitDecl(ASTContext &ctx)
-    : Decl(TranslationUnit, 0, SourceLocation()),
+    : Decl(TranslationUnit, nullptr, SourceLocation()),
       DeclContext(TranslationUnit),
-      Ctx(ctx), AnonymousNamespace(0) {}
+      Ctx(ctx), AnonymousNamespace(nullptr) {}
 public:
   ASTContext &getASTContext() const { return Ctx; }
 
@@ -110,7 +110,7 @@
   DeclarationName Name;
 
 private:
-  NamedDecl *getUnderlyingDeclImpl();
+  NamedDecl *getUnderlyingDeclImpl() LLVM_READONLY;
 
 protected:
   NamedDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N)
@@ -161,9 +161,8 @@
   void printQualifiedName(raw_ostream &OS) const;
   void printQualifiedName(raw_ostream &OS, const PrintingPolicy &Policy) const;
 
-  // FIXME: Remove string versions.
+  // FIXME: Remove string version.
   std::string getQualifiedNameAsString() const;
-  std::string getQualifiedNameAsString(const PrintingPolicy &Policy) const;
 
   /// getNameForDiagnostic - Appends a human-readable name for this
   /// declaration into the given stream.
@@ -204,9 +203,8 @@
     // C++0x [class.mem]p1:
     //   The enumerators of an unscoped enumeration defined in
     //   the class are members of the class.
-    // FIXME: support C++0x scoped enumerations.
     if (isa<EnumDecl>(DC))
-      DC = DC->getParent();
+      DC = DC->getRedeclContext();
 
     return DC->isRecord();
   }
@@ -259,6 +257,16 @@
   /// checking. Should always return true.
   bool isLinkageValid() const;
 
+  /// \brief True if something has required us to compute the linkage
+  /// of this declaration.
+  ///
+  /// Language features which can retroactively change linkage (like a
+  /// typedef name for linkage purposes) may need to consider this,
+  /// but hopefully only in transitory ways during parsing.
+  bool hasLinkageBeenComputed() const {
+    return hasCachedLinkage();
+  }
+
   /// \brief Looks through UsingDecls and ObjCCompatibleAliasDecls for
   /// the underlying named decl.
   NamedDecl *getUnderlyingDecl() {
@@ -295,7 +303,7 @@
 /// location of the statement.  For GNU local labels (__label__), the decl
 /// location is where the __label__ is.
 class LabelDecl : public NamedDecl {
-  virtual void anchor();
+  void anchor() override;
   LabelStmt *TheStmt;
   /// LocStart - For normal labels, this is the same as the main declaration
   /// label, i.e., the location of the identifier; for GNU local labels,
@@ -320,7 +328,7 @@
   bool isGnuLocal() const { return LocStart != getLocation(); }
   void setLocStart(SourceLocation L) { LocStart = L; }
 
-  SourceRange getSourceRange() const LLVM_READONLY {
+  SourceRange getSourceRange() const override LLVM_READONLY {
     return SourceRange(LocStart, getLocation());
   }
 
@@ -333,8 +341,6 @@
 class NamespaceDecl : public NamedDecl, public DeclContext, 
                       public Redeclarable<NamespaceDecl> 
 {
-  virtual void anchor();
-
   /// LocStart - The starting location of the source range, pointing
   /// to either the namespace or the inline keyword.
   SourceLocation LocStart;
@@ -347,21 +353,15 @@
   /// boolean value indicating whether this is an inline namespace.
   llvm::PointerIntPair<NamespaceDecl *, 1, bool> AnonOrFirstNamespaceAndInline;
 
-  NamespaceDecl(DeclContext *DC, bool Inline, SourceLocation StartLoc,
-                SourceLocation IdLoc, IdentifierInfo *Id,
-                NamespaceDecl *PrevDecl);
-  
+  NamespaceDecl(ASTContext &C, DeclContext *DC, bool Inline,
+                SourceLocation StartLoc, SourceLocation IdLoc,
+                IdentifierInfo *Id, NamespaceDecl *PrevDecl);
+
   typedef Redeclarable<NamespaceDecl> redeclarable_base;
-  virtual NamespaceDecl *getNextRedeclaration() {
-    return RedeclLink.getNext();
-  }
-  virtual NamespaceDecl *getPreviousDeclImpl() {
-    return getPreviousDecl();
-  }
-  virtual NamespaceDecl *getMostRecentDeclImpl() {
-    return getMostRecentDecl();
-  }
-  
+  NamespaceDecl *getNextRedeclarationImpl() override;
+  NamespaceDecl *getPreviousDeclImpl() override;
+  NamespaceDecl *getMostRecentDeclImpl() override;
+
 public:
   static NamespaceDecl *Create(ASTContext &C, DeclContext *DC,
                                bool Inline, SourceLocation StartLoc,
@@ -370,9 +370,11 @@
 
   static NamespaceDecl *CreateDeserialized(ASTContext &C, unsigned ID);
 
+  typedef redeclarable_base::redecl_range redecl_range;
   typedef redeclarable_base::redecl_iterator redecl_iterator;
   using redeclarable_base::redecls_begin;
   using redeclarable_base::redecls_end;
+  using redeclarable_base::redecls;
   using redeclarable_base::getPreviousDecl;
   using redeclarable_base::getMostRecentDecl;
   using redeclarable_base::isFirstDecl;
@@ -432,14 +434,14 @@
   }
 
   /// Retrieves the canonical declaration of this namespace.
-  NamespaceDecl *getCanonicalDecl() {
+  NamespaceDecl *getCanonicalDecl() override {
     return getOriginalNamespace();
   }
   const NamespaceDecl *getCanonicalDecl() const {
     return getOriginalNamespace();
   }
-  
-  virtual SourceRange getSourceRange() const LLVM_READONLY {
+
+  SourceRange getSourceRange() const override LLVM_READONLY {
     return SourceRange(LocStart, RBraceLoc);
   }
 
@@ -466,7 +468,7 @@
 /// an lvalue) a function (in which case it is a function designator) or
 /// an enum constant.
 class ValueDecl : public NamedDecl {
-  virtual void anchor();
+  void anchor() override;
   QualType DeclType;
 
 protected:
@@ -505,7 +507,8 @@
   TemplateParameterList** TemplParamLists;
 
   /// Default constructor.
-  QualifierInfo() : QualifierLoc(), NumTemplParamLists(0), TemplParamLists(0) {}
+  QualifierInfo()
+    : QualifierLoc(), NumTemplParamLists(0), TemplParamLists(nullptr) {}
 
   /// setTemplateParameterListsInfo - Sets info about "outer" template
   /// parameter lists.
@@ -567,7 +570,7 @@
   /// range taking into account any outer template declarations.
   SourceLocation getOuterLocStart() const;
 
-  virtual SourceRange getSourceRange() const LLVM_READONLY;
+  SourceRange getSourceRange() const override LLVM_READONLY;
   SourceLocation getLocStart() const LLVM_READONLY {
     return getOuterLocStart();
   }
@@ -576,7 +579,7 @@
   /// declaration, if it was present in the source.
   NestedNameSpecifier *getQualifier() const {
     return hasExtInfo() ? getExtInfo()->QualifierLoc.getNestedNameSpecifier()
-                        : 0;
+                        : nullptr;
   }
 
   /// \brief Retrieve the nested-name-specifier (with source-location
@@ -764,23 +767,27 @@
     ParmVarDeclBitfields ParmVarDeclBits;
   };
 
-  VarDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
+  VarDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
           SourceLocation IdLoc, IdentifierInfo *Id, QualType T,
           TypeSourceInfo *TInfo, StorageClass SC);
 
   typedef Redeclarable<VarDecl> redeclarable_base;
-  virtual VarDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
-  virtual VarDecl *getPreviousDeclImpl() {
+  VarDecl *getNextRedeclarationImpl() override {
+    return getNextRedeclaration();
+  }
+  VarDecl *getPreviousDeclImpl() override {
     return getPreviousDecl();
   }
-  virtual VarDecl *getMostRecentDeclImpl() {
+  VarDecl *getMostRecentDeclImpl() override {
     return getMostRecentDecl();
   }
 
 public:
+  typedef redeclarable_base::redecl_range redecl_range;
   typedef redeclarable_base::redecl_iterator redecl_iterator;
   using redeclarable_base::redecls_begin;
   using redeclarable_base::redecls_end;
+  using redeclarable_base::redecls;
   using redeclarable_base::getPreviousDecl;
   using redeclarable_base::getMostRecentDecl;
   using redeclarable_base::isFirstDecl;
@@ -791,8 +798,8 @@
                          StorageClass S);
 
   static VarDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-  
-  virtual SourceRange getSourceRange() const LLVM_READONLY;
+
+  SourceRange getSourceRange() const override LLVM_READONLY;
 
   /// \brief Returns the storage class as written in the source. For the
   /// computed linkage of symbol, see getLinkage.
@@ -803,22 +810,12 @@
 
   void setTSCSpec(ThreadStorageClassSpecifier TSC) {
     VarDeclBits.TSCSpec = TSC;
+    assert(VarDeclBits.TSCSpec == TSC && "truncation");
   }
   ThreadStorageClassSpecifier getTSCSpec() const {
     return static_cast<ThreadStorageClassSpecifier>(VarDeclBits.TSCSpec);
   }
-  TLSKind getTLSKind() const {
-    switch (VarDeclBits.TSCSpec) {
-    case TSCS_unspecified:
-      return TLS_None;
-    case TSCS___thread: // Fall through.
-    case TSCS__Thread_local:
-      return TLS_Static;
-    case TSCS_thread_local:
-      return TLS_Dynamic;
-    }
-    llvm_unreachable("Unknown thread storage class specifier!");
-  }
+  TLSKind getTLSKind() const;
 
   /// hasLocalStorage - Returns true if a variable with function scope
   ///  is a non-static local variable.
@@ -827,6 +824,10 @@
       // Second check is for C++11 [dcl.stc]p4.
       return !isFileVarDecl() && getTSCSpec() == TSCS_unspecified;
 
+    // Global Named Register (GNU extension)
+    if (getStorageClass() == SC_Register && !isLocalVarDecl())
+      return false;
+
     // Return true for:  Auto, Register.
     // Return false for: Extern, Static, PrivateExtern, OpenCLWorkGroupLocal.
 
@@ -913,7 +914,7 @@
     return getKind() != Decl::ParmVar && getDeclContext()->isRecord();
   }
 
-  virtual VarDecl *getCanonicalDecl();
+  VarDecl *getCanonicalDecl() override;
   const VarDecl *getCanonicalDecl() const {
     return const_cast<VarDecl*>(this)->getCanonicalDecl();
   }
@@ -960,7 +961,7 @@
 
   /// \brief Determine whether this is or was instantiated from an out-of-line
   /// definition of a static data member.
-  virtual bool isOutOfLine() const;
+  bool isOutOfLine() const override;
 
   /// \brief If this is a static data member, find its out-of-line definition.
   VarDecl *getOutOfLineDefinition();
@@ -996,7 +997,7 @@
   }
   const Expr *getInit() const {
     if (Init.isNull())
-      return 0;
+      return nullptr;
 
     const Stmt *S = Init.dyn_cast<Stmt *>();
     if (!S) {
@@ -1007,7 +1008,7 @@
   }
   Expr *getInit() {
     if (Init.isNull())
-      return 0;
+      return nullptr;
 
     Stmt *S = Init.dyn_cast<Stmt *>();
     if (!S) {
@@ -1058,7 +1059,7 @@
       if (Eval->WasEvaluated)
         return &Eval->Evaluated;
 
-    return 0;
+    return nullptr;
   }
 
   /// \brief Determines whether it is already known whether the
@@ -1208,18 +1209,18 @@
 };
 
 class ImplicitParamDecl : public VarDecl {
-  virtual void anchor();
+  void anchor() override;
 public:
   static ImplicitParamDecl *Create(ASTContext &C, DeclContext *DC,
                                    SourceLocation IdLoc, IdentifierInfo *Id,
                                    QualType T);
 
   static ImplicitParamDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-  
-  ImplicitParamDecl(DeclContext *DC, SourceLocation IdLoc,
+
+  ImplicitParamDecl(ASTContext &C, DeclContext *DC, SourceLocation IdLoc,
                     IdentifierInfo *Id, QualType Type)
-    : VarDecl(ImplicitParam, DC, IdLoc, IdLoc, Id, Type,
-              /*tinfo*/ 0, SC_None) {
+    : VarDecl(ImplicitParam, C, DC, IdLoc, IdLoc, Id, Type,
+              /*tinfo*/ nullptr, SC_None) {
     setImplicit();
   }
 
@@ -1235,11 +1236,10 @@
   enum { MaxFunctionScopeIndex = 255 };
 
 protected:
-  ParmVarDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
-              SourceLocation IdLoc, IdentifierInfo *Id,
-              QualType T, TypeSourceInfo *TInfo,
-              StorageClass S, Expr *DefArg)
-    : VarDecl(DK, DC, StartLoc, IdLoc, Id, T, TInfo, S) {
+  ParmVarDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
+              SourceLocation IdLoc, IdentifierInfo *Id, QualType T,
+              TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
+      : VarDecl(DK, C, DC, StartLoc, IdLoc, Id, T, TInfo, S) {
     assert(ParmVarDeclBits.HasInheritedDefaultArg == false);
     assert(ParmVarDeclBits.IsKNRPromoted == false);
     assert(ParmVarDeclBits.IsObjCMethodParam == false);
@@ -1254,8 +1254,8 @@
                              StorageClass S, Expr *DefArg);
 
   static ParmVarDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-  
-  virtual SourceRange getSourceRange() const LLVM_READONLY;
+
+  SourceRange getSourceRange() const override LLVM_READONLY;
 
   void setObjCMethodScopeInfo(unsigned parameterIndex) {
     ParmVarDeclBits.IsObjCMethodParam = true;
@@ -1362,9 +1362,7 @@
   /// real default argument via setDefaultArg when the class
   /// definition enclosing the function declaration that owns this
   /// default argument is completed.
-  void setUnparsedDefaultArg() {
-    Init = (UnparsedDefaultArgument *)0;
-  }
+  void setUnparsedDefaultArg() { Init = (UnparsedDefaultArgument *)nullptr; }
 
   bool hasInheritedDefaultArg() const {
     return ParmVarDeclBits.HasInheritedDefaultArg;
@@ -1538,7 +1536,7 @@
   void setParams(ASTContext &C, ArrayRef<ParmVarDecl *> NewParamInfo);
 
 protected:
-  FunctionDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
+  FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
                const DeclarationNameInfo &NameInfo,
                QualType T, TypeSourceInfo *TInfo,
                StorageClass S, bool isInlineSpecified,
@@ -1546,7 +1544,8 @@
     : DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo,
                      StartLoc),
       DeclContext(DK),
-      ParamInfo(0), Body(),
+      redeclarable_base(C),
+      ParamInfo(nullptr), Body(),
       SClass(S),
       IsInline(isInlineSpecified), IsInlineSpecified(isInlineSpecified),
       IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false),
@@ -1559,18 +1558,22 @@
       DNLoc(NameInfo.getInfo()) {}
 
   typedef Redeclarable<FunctionDecl> redeclarable_base;
-  virtual FunctionDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
-  virtual FunctionDecl *getPreviousDeclImpl() {
+  FunctionDecl *getNextRedeclarationImpl() override {
+    return getNextRedeclaration();
+  }
+  FunctionDecl *getPreviousDeclImpl() override {
     return getPreviousDecl();
   }
-  virtual FunctionDecl *getMostRecentDeclImpl() {
+  FunctionDecl *getMostRecentDeclImpl() override {
     return getMostRecentDecl();
   }
 
 public:
+  typedef redeclarable_base::redecl_range redecl_range;
   typedef redeclarable_base::redecl_iterator redecl_iterator;
   using redeclarable_base::redecls_begin;
   using redeclarable_base::redecls_end;
+  using redeclarable_base::redecls;
   using redeclarable_base::getPreviousDecl;
   using redeclarable_base::getMostRecentDecl;
   using redeclarable_base::isFirstDecl;
@@ -1605,13 +1608,12 @@
     return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
   }
 
-  virtual void getNameForDiagnostic(raw_ostream &OS,
-                                    const PrintingPolicy &Policy,
-                                    bool Qualified) const;
+  void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
+                            bool Qualified) const override;
 
   void setRangeEnd(SourceLocation E) { EndRangeLoc = E; }
 
-  virtual SourceRange getSourceRange() const LLVM_READONLY;
+  SourceRange getSourceRange() const override LLVM_READONLY;
 
   /// \brief Returns true if the function has a body (definition). The
   /// function body might be in any of the (re-)declarations of this
@@ -1620,7 +1622,7 @@
   /// containing the body (if there is one).
   bool hasBody(const FunctionDecl *&Definition) const;
 
-  virtual bool hasBody() const {
+  bool hasBody() const override {
     const FunctionDecl* Definition;
     return hasBody(Definition);
   }
@@ -1648,7 +1650,7 @@
   /// unnecessary AST de-serialization of the body.
   Stmt *getBody(const FunctionDecl *&Definition) const;
 
-  virtual Stmt *getBody() const {
+   Stmt *getBody() const override {
     const FunctionDecl* Definition;
     return getBody(Definition);
   }
@@ -1828,7 +1830,7 @@
   void setPreviousDeclaration(FunctionDecl * PrevDecl);
 
   virtual const FunctionDecl *getCanonicalDecl() const;
-  virtual FunctionDecl *getCanonicalDecl();
+  FunctionDecl *getCanonicalDecl() override;
 
   unsigned getBuiltinID() const;
 
@@ -1836,12 +1838,24 @@
   unsigned param_size() const { return getNumParams(); }
   typedef ParmVarDecl **param_iterator;
   typedef ParmVarDecl * const *param_const_iterator;
+  typedef llvm::iterator_range<param_iterator> param_range;
+  typedef llvm::iterator_range<param_const_iterator> param_const_range;
 
-  param_iterator param_begin() { return ParamInfo; }
-  param_iterator param_end()   { return ParamInfo+param_size(); }
+  param_iterator param_begin() { return param_iterator(ParamInfo); }
+  param_iterator param_end() {
+    return param_iterator(ParamInfo + param_size());
+  }
+  param_range params() { return param_range(param_begin(), param_end()); }
 
-  param_const_iterator param_begin() const { return ParamInfo; }
-  param_const_iterator param_end() const   { return ParamInfo+param_size(); }
+  param_const_iterator param_begin() const {
+    return param_const_iterator(ParamInfo);
+  }
+  param_const_iterator param_end() const {
+    return param_const_iterator(ParamInfo + param_size());
+  }
+  param_const_range params() const {
+    return param_const_range(param_begin(), param_end());
+  }
 
   /// getNumParams - Return the number of parameters this function must have
   /// based on its FunctionType.  This is the length of the ParamInfo array
@@ -1860,6 +1874,12 @@
     setParams(getASTContext(), NewParamInfo);
   }
 
+  // ArrayRef iterface to parameters.
+  // FIXME: Should one day replace iterator interface.
+  ArrayRef<ParmVarDecl*> parameters() const {
+    return llvm::makeArrayRef(ParamInfo, getNumParams());
+  }
+
   const ArrayRef<NamedDecl *> &getDeclsInPrototypeScope() const {
     return DeclsInPrototypeScope;
   }
@@ -1871,10 +1891,15 @@
   /// arguments (in C++).
   unsigned getMinRequiredArguments() const;
 
-  QualType getResultType() const {
-    return getType()->getAs<FunctionType>()->getResultType();
+  QualType getReturnType() const {
+    return getType()->getAs<FunctionType>()->getReturnType();
   }
 
+  /// \brief Attempt to compute an informative source range covering the
+  /// function return type. This may omit qualifiers and other information with
+  /// limited representation in the AST.
+  SourceRange getReturnTypeSourceRange() const;
+
   /// \brief Determine the type of an expression that calls this function.
   QualType getCallResultType() const {
     return getType()->getAs<FunctionType>()->getCallResultType(getASTContext());
@@ -1906,6 +1931,8 @@
 
   bool isInlineDefinitionExternallyVisible() const;
 
+  bool isMSExternInline() const;
+
   bool doesDeclarationForceExternallyVisibleDefinition() const;
 
   /// isOverloadedOperator - Whether this function declaration
@@ -1981,7 +2008,7 @@
   /// \brief Determine whether this function is a function template
   /// specialization.
   bool isFunctionTemplateSpecialization() const {
-    return getPrimaryTemplate() != 0;
+    return getPrimaryTemplate() != nullptr;
   }
 
   /// \brief Retrieve the class scope template pattern that this function
@@ -2054,11 +2081,11 @@
   /// \param PointOfInstantiation point at which the function template
   /// specialization was first instantiated.
   void setFunctionTemplateSpecialization(FunctionTemplateDecl *Template,
-                                      const TemplateArgumentList *TemplateArgs,
-                                         void *InsertPos,
-                    TemplateSpecializationKind TSK = TSK_ImplicitInstantiation,
-                    const TemplateArgumentListInfo *TemplateArgsAsWritten = 0,
-                    SourceLocation PointOfInstantiation = SourceLocation()) {
+                const TemplateArgumentList *TemplateArgs,
+                void *InsertPos,
+                TemplateSpecializationKind TSK = TSK_ImplicitInstantiation,
+                const TemplateArgumentListInfo *TemplateArgsAsWritten = nullptr,
+                SourceLocation PointOfInstantiation = SourceLocation()) {
     setFunctionTemplateSpecialization(getASTContext(), Template, TemplateArgs,
                                       InsertPos, TSK, TemplateArgsAsWritten,
                                       PointOfInstantiation);
@@ -2095,7 +2122,7 @@
 
   /// \brief Determine whether this is or was instantiated from an out-of-line
   /// definition of a member function.
-  virtual bool isOutOfLine() const;
+  bool isOutOfLine() const override;
 
   /// \brief Identify a memory copying or setting function.
   /// If the given function is a memory copy or setting function, returns
@@ -2181,7 +2208,7 @@
   bool isAnonymousStructOrUnion() const;
 
   Expr *getBitWidth() const {
-    return isBitField() ? InitializerOrBitWidth.getPointer() : 0;
+    return isBitField() ? InitializerOrBitWidth.getPointer() : nullptr;
   }
   unsigned getBitWidthValue(const ASTContext &Ctx) const;
 
@@ -2192,7 +2219,7 @@
   // Note: used by some clients (i.e., do not remove it).
   void removeBitWidth() {
     assert(isBitField() && "no bitfield width to remove");
-    InitializerOrBitWidth.setPointer(0);
+    InitializerOrBitWidth.setPointer(nullptr);
   }
 
   /// getInClassInitStyle - Get the kind of (C++11) in-class initializer which
@@ -2211,7 +2238,8 @@
   /// in-class initializer, but this returns null, then we have not parsed and
   /// attached it yet.
   Expr *getInClassInitializer() const {
-    return hasInClassInitializer() ? InitializerOrBitWidth.getPointer() : 0;
+    return hasInClassInitializer() ? InitializerOrBitWidth.getPointer()
+                                   : nullptr;
   }
   /// setInClassInitializer - Set the C++11 in-class initializer for this
   /// member.
@@ -2220,7 +2248,7 @@
   /// member.
   void removeInClassInitializer() {
     assert(hasInClassInitializer() && "no initializer to remove");
-    InitializerOrBitWidth.setPointer(0);
+    InitializerOrBitWidth.setPointer(nullptr);
     InitializerOrBitWidth.setInt(ICIS_NoInit);
   }
 
@@ -2234,10 +2262,10 @@
     return cast<RecordDecl>(getDeclContext());
   }
 
-  SourceRange getSourceRange() const LLVM_READONLY;
+  SourceRange getSourceRange() const override LLVM_READONLY;
 
   /// Retrieves the canonical declaration of this field.
-  FieldDecl *getCanonicalDecl() { return getFirstDecl(); }
+  FieldDecl *getCanonicalDecl() override { return getFirstDecl(); }
   const FieldDecl *getCanonicalDecl() const { return getFirstDecl(); }
 
   // Implement isa/cast/dyncast/etc.
@@ -2276,10 +2304,10 @@
   void setInitExpr(Expr *E) { Init = (Stmt*) E; }
   void setInitVal(const llvm::APSInt &V) { Val = V; }
 
-  SourceRange getSourceRange() const LLVM_READONLY;
+  SourceRange getSourceRange() const override LLVM_READONLY;
 
   /// Retrieves the canonical declaration of this enumerator.
-  EnumConstantDecl *getCanonicalDecl() { return getFirstDecl(); }
+  EnumConstantDecl *getCanonicalDecl() override { return getFirstDecl(); }
   const EnumConstantDecl *getCanonicalDecl() const { return getFirstDecl(); }
 
   // Implement isa/cast/dyncast/etc.
@@ -2293,7 +2321,7 @@
 /// field injected from an anonymous union/struct into the parent scope.
 /// IndirectFieldDecl are always implicit.
 class IndirectFieldDecl : public ValueDecl {
-  virtual void anchor();
+  void anchor() override;
   NamedDecl **Chaining;
   unsigned ChainingSize;
 
@@ -2310,8 +2338,13 @@
   static IndirectFieldDecl *CreateDeserialized(ASTContext &C, unsigned ID);
   
   typedef NamedDecl * const *chain_iterator;
-  chain_iterator chain_begin() const { return Chaining; }
-  chain_iterator chain_end() const  { return Chaining+ChainingSize; }
+  typedef llvm::iterator_range<chain_iterator> chain_range;
+
+  chain_range chain() const { return chain_range(chain_begin(), chain_end()); }
+  chain_iterator chain_begin() const { return chain_iterator(Chaining); }
+  chain_iterator chain_end() const {
+    return chain_iterator(Chaining + ChainingSize);
+  }
 
   unsigned getChainingSize() const { return ChainingSize; }
 
@@ -2334,7 +2367,7 @@
 /// TypeDecl - Represents a declaration of a type.
 ///
 class TypeDecl : public NamedDecl {
-  virtual void anchor();
+  void anchor() override;
   /// TypeForDecl - This indicates the Type object that represents
   /// this TypeDecl.  It is a cache maintained by
   /// ASTContext::getTypedefType, ASTContext::getTagDeclType, and
@@ -2343,16 +2376,11 @@
   /// LocStart - The start of the source range for this declaration.
   SourceLocation LocStart;
   friend class ASTContext;
-  friend class DeclContext;
-  friend class TagDecl;
-  friend class TemplateTypeParmDecl;
-  friend class TagType;
-  friend class ASTReader;
 
 protected:
   TypeDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
            SourceLocation StartL = SourceLocation())
-    : NamedDecl(DK, DC, L, Id), TypeForDecl(0), LocStart(StartL) {}
+    : NamedDecl(DK, DC, L, Id), TypeForDecl(nullptr), LocStart(StartL) {}
 
 public:
   // Low-level accessor. If you just want the type defined by this node,
@@ -2364,7 +2392,7 @@
 
   SourceLocation getLocStart() const LLVM_READONLY { return LocStart; }
   void setLocStart(SourceLocation L) { LocStart = L; }
-  virtual SourceRange getSourceRange() const LLVM_READONLY {
+  SourceRange getSourceRange() const override LLVM_READONLY {
     if (LocStart.isValid())
       return SourceRange(LocStart, getLocation());
     else
@@ -2379,31 +2407,34 @@
 
 /// Base class for declarations which introduce a typedef-name.
 class TypedefNameDecl : public TypeDecl, public Redeclarable<TypedefNameDecl> {
-  virtual void anchor();
+  void anchor() override;
   typedef std::pair<TypeSourceInfo*, QualType> ModedTInfo;
   llvm::PointerUnion<TypeSourceInfo*, ModedTInfo*> MaybeModedTInfo;
 
 protected:
-  TypedefNameDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
-                  SourceLocation IdLoc, IdentifierInfo *Id,
-                  TypeSourceInfo *TInfo)
-    : TypeDecl(DK, DC, IdLoc, Id, StartLoc), MaybeModedTInfo(TInfo) {}
+  TypedefNameDecl(Kind DK, ASTContext &C, DeclContext *DC,
+                  SourceLocation StartLoc, SourceLocation IdLoc,
+                  IdentifierInfo *Id, TypeSourceInfo *TInfo)
+      : TypeDecl(DK, DC, IdLoc, Id, StartLoc), redeclarable_base(C),
+        MaybeModedTInfo(TInfo) {}
 
   typedef Redeclarable<TypedefNameDecl> redeclarable_base;
-  virtual TypedefNameDecl *getNextRedeclaration() {
-    return RedeclLink.getNext();
+  TypedefNameDecl *getNextRedeclarationImpl() override {
+    return getNextRedeclaration();
   }
-  virtual TypedefNameDecl *getPreviousDeclImpl() {
+  TypedefNameDecl *getPreviousDeclImpl() override {
     return getPreviousDecl();
   }
-  virtual TypedefNameDecl *getMostRecentDeclImpl() {
+  TypedefNameDecl *getMostRecentDeclImpl() override {
     return getMostRecentDecl();
   }
 
 public:
+  typedef redeclarable_base::redecl_range redecl_range;
   typedef redeclarable_base::redecl_iterator redecl_iterator;
   using redeclarable_base::redecls_begin;
   using redeclarable_base::redecls_end;
+  using redeclarable_base::redecls;
   using redeclarable_base::getPreviousDecl;
   using redeclarable_base::getMostRecentDecl;
   using redeclarable_base::isFirstDecl;
@@ -2428,7 +2459,7 @@
   }
 
   /// Retrieves the canonical declaration of this typedef-name.
-  TypedefNameDecl *getCanonicalDecl() { return getFirstDecl(); }
+  TypedefNameDecl *getCanonicalDecl() override { return getFirstDecl(); }
   const TypedefNameDecl *getCanonicalDecl() const { return getFirstDecl(); }
 
   // Implement isa/cast/dyncast/etc.
@@ -2441,17 +2472,17 @@
 /// TypedefDecl - Represents the declaration of a typedef-name via the 'typedef'
 /// type specifier.
 class TypedefDecl : public TypedefNameDecl {
-  TypedefDecl(DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc,
-              IdentifierInfo *Id, TypeSourceInfo *TInfo)
-    : TypedefNameDecl(Typedef, DC, StartLoc, IdLoc, Id, TInfo) {}
+  TypedefDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
+              SourceLocation IdLoc, IdentifierInfo *Id, TypeSourceInfo *TInfo)
+      : TypedefNameDecl(Typedef, C, DC, StartLoc, IdLoc, Id, TInfo) {}
 
 public:
   static TypedefDecl *Create(ASTContext &C, DeclContext *DC,
                              SourceLocation StartLoc, SourceLocation IdLoc,
                              IdentifierInfo *Id, TypeSourceInfo *TInfo);
   static TypedefDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-  
-  SourceRange getSourceRange() const LLVM_READONLY;
+
+  SourceRange getSourceRange() const override LLVM_READONLY;
 
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -2461,9 +2492,9 @@
 /// TypeAliasDecl - Represents the declaration of a typedef-name via a C++0x
 /// alias-declaration.
 class TypeAliasDecl : public TypedefNameDecl {
-  TypeAliasDecl(DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc,
-                IdentifierInfo *Id, TypeSourceInfo *TInfo)
-    : TypedefNameDecl(TypeAlias, DC, StartLoc, IdLoc, Id, TInfo) {}
+  TypeAliasDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
+                SourceLocation IdLoc, IdentifierInfo *Id, TypeSourceInfo *TInfo)
+      : TypedefNameDecl(TypeAlias, C, DC, StartLoc, IdLoc, Id, TInfo) {}
 
 public:
   static TypeAliasDecl *Create(ASTContext &C, DeclContext *DC,
@@ -2471,7 +2502,7 @@
                                IdentifierInfo *Id, TypeSourceInfo *TInfo);
   static TypeAliasDecl *CreateDeserialized(ASTContext &C, unsigned ID);
 
-  SourceRange getSourceRange() const LLVM_READONLY;
+  SourceRange getSourceRange() const override LLVM_READONLY;
 
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -2559,24 +2590,27 @@
   }
 
 protected:
-  TagDecl(Kind DK, TagKind TK, DeclContext *DC, SourceLocation L,
-          IdentifierInfo *Id, TagDecl *PrevDecl, SourceLocation StartL)
-      : TypeDecl(DK, DC, L, Id, StartL), DeclContext(DK), TagDeclKind(TK),
-        IsCompleteDefinition(false), IsBeingDefined(false),
+  TagDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC,
+          SourceLocation L, IdentifierInfo *Id, TagDecl *PrevDecl,
+          SourceLocation StartL)
+      : TypeDecl(DK, DC, L, Id, StartL), DeclContext(DK), redeclarable_base(C),
+        TagDeclKind(TK), IsCompleteDefinition(false), IsBeingDefined(false),
         IsEmbeddedInDeclarator(false), IsFreeStanding(false),
         IsCompleteDefinitionRequired(false),
-        NamedDeclOrQualifier((NamedDecl *)0) {
+        NamedDeclOrQualifier((NamedDecl *)nullptr) {
     assert((DK != Enum || TK == TTK_Enum) &&
            "EnumDecl not matched with TTK_Enum");
     setPreviousDecl(PrevDecl);
   }
 
   typedef Redeclarable<TagDecl> redeclarable_base;
-  virtual TagDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
-  virtual TagDecl *getPreviousDeclImpl() {
+  TagDecl *getNextRedeclarationImpl() override {
+    return getNextRedeclaration();
+  }
+  TagDecl *getPreviousDeclImpl() override {
     return getPreviousDecl();
   }
-  virtual TagDecl *getMostRecentDeclImpl() {
+  TagDecl *getMostRecentDeclImpl() override {
     return getMostRecentDecl();
   }
 
@@ -2586,9 +2620,11 @@
   void completeDefinition();
 
 public:
+  typedef redeclarable_base::redecl_range redecl_range;
   typedef redeclarable_base::redecl_iterator redecl_iterator;
   using redeclarable_base::redecls_begin;
   using redeclarable_base::redecls_end;
+  using redeclarable_base::redecls;
   using redeclarable_base::getPreviousDecl;
   using redeclarable_base::getMostRecentDecl;
   using redeclarable_base::isFirstDecl;
@@ -2603,10 +2639,10 @@
   /// getOuterLocStart - Return SourceLocation representing start of source
   /// range taking into account any outer template declarations.
   SourceLocation getOuterLocStart() const;
-  virtual SourceRange getSourceRange() const LLVM_READONLY;
+  SourceRange getSourceRange() const override LLVM_READONLY;
 
-  virtual TagDecl* getCanonicalDecl();
-  const TagDecl* getCanonicalDecl() const {
+  TagDecl *getCanonicalDecl() override;
+  const TagDecl *getCanonicalDecl() const {
     return const_cast<TagDecl*>(this)->getCanonicalDecl();
   }
 
@@ -2673,8 +2709,7 @@
     IsCompleteDefinitionRequired = V;
   }
 
-  // FIXME: Return StringRef;
-  const char *getKindName() const {
+  StringRef getKindName() const {
     return TypeWithKeyword::getTagTypeKindName(getTagKind());
   }
 
@@ -2714,12 +2749,12 @@
         NamedDeclOrQualifier.get<NamedDecl *>());
   }
   DeclaratorDecl *getDeclaratorForAnonDecl() const {
-    return hasExtInfo() ? 0 : dyn_cast_or_null<DeclaratorDecl>(
+    return hasExtInfo() ? nullptr : dyn_cast_or_null<DeclaratorDecl>(
                                   NamedDeclOrQualifier.get<NamedDecl *>());
   }
 
   TypedefNameDecl *getTypedefNameForAnonDecl() const {
-    return hasExtInfo() ? 0 : dyn_cast_or_null<TypedefNameDecl>(
+    return hasExtInfo() ? nullptr : dyn_cast_or_null<TypedefNameDecl>(
                                   NamedDeclOrQualifier.get<NamedDecl *>());
   }
 
@@ -2731,7 +2766,7 @@
   /// declaration, if it was present in the source.
   NestedNameSpecifier *getQualifier() const {
     return hasExtInfo() ? getExtInfo()->QualifierLoc.getNestedNameSpecifier()
-                        : 0;
+                        : nullptr;
   }
 
   /// \brief Retrieve the nested-name-specifier (with source-location
@@ -2773,7 +2808,7 @@
 /// with a fixed underlying type, and in C we allow them to be forward-declared
 /// with no underlying type as an extension.
 class EnumDecl : public TagDecl {
-  virtual void anchor();
+  void anchor() override;
   /// IntegerType - This represent the integer type that the enum corresponds
   /// to for code generation purposes.  Note that the enumerator constants may
   /// have a different type than this does.
@@ -2802,13 +2837,13 @@
   /// information.
   MemberSpecializationInfo *SpecializationInfo;
 
-  EnumDecl(DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc,
-           IdentifierInfo *Id, EnumDecl *PrevDecl,
+  EnumDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
+           SourceLocation IdLoc, IdentifierInfo *Id, EnumDecl *PrevDecl,
            bool Scoped, bool ScopedUsingClassTag, bool Fixed)
-    : TagDecl(Enum, TTK_Enum, DC, IdLoc, Id, PrevDecl, StartLoc),
-      SpecializationInfo(0) {
+      : TagDecl(Enum, TTK_Enum, C, DC, IdLoc, Id, PrevDecl, StartLoc),
+        SpecializationInfo(nullptr) {
     assert(Scoped || !ScopedUsingClassTag);
-    IntegerType = (const Type*)0;
+    IntegerType = (const Type *)nullptr;
     NumNegativeBits = 0;
     NumPositiveBits = 0;
     IsScoped = Scoped;
@@ -2819,7 +2854,7 @@
   void setInstantiationOfMemberEnum(ASTContext &C, EnumDecl *ED,
                                     TemplateSpecializationKind TSK);
 public:
-  EnumDecl *getCanonicalDecl() {
+  EnumDecl *getCanonicalDecl() override {
     return cast<EnumDecl>(TagDecl::getCanonicalDecl());
   }
   const EnumDecl *getCanonicalDecl() const {
@@ -2865,6 +2900,12 @@
   // enumerator_iterator - Iterates through the enumerators of this
   // enumeration.
   typedef specific_decl_iterator<EnumConstantDecl> enumerator_iterator;
+  typedef llvm::iterator_range<specific_decl_iterator<EnumConstantDecl>>
+    enumerator_range;
+
+  enumerator_range enumerators() const {
+    return enumerator_range(enumerator_begin(), enumerator_end());
+  }
 
   enumerator_iterator enumerator_begin() const {
     const EnumDecl *E = getDefinition();
@@ -2888,27 +2929,32 @@
   void setPromotionType(QualType T) { PromotionType = T; }
 
   /// getIntegerType - Return the integer type this enum decl corresponds to.
-  /// This returns a null qualtype for an enum forward definition.
+  /// This returns a null QualType for an enum forward definition with no fixed
+  /// underlying type.
   QualType getIntegerType() const {
     if (!IntegerType)
       return QualType();
-    if (const Type* T = IntegerType.dyn_cast<const Type*>())
+    if (const Type *T = IntegerType.dyn_cast<const Type*>())
       return QualType(T, 0);
-    return IntegerType.get<TypeSourceInfo*>()->getType();
+    return IntegerType.get<TypeSourceInfo*>()->getType().getUnqualifiedType();
   }
 
   /// \brief Set the underlying integer type.
   void setIntegerType(QualType T) { IntegerType = T.getTypePtrOrNull(); }
 
   /// \brief Set the underlying integer type source info.
-  void setIntegerTypeSourceInfo(TypeSourceInfo* TInfo) { IntegerType = TInfo; }
+  void setIntegerTypeSourceInfo(TypeSourceInfo *TInfo) { IntegerType = TInfo; }
 
   /// \brief Return the type source info for the underlying integer type,
   /// if no type source info exists, return 0.
-  TypeSourceInfo* getIntegerTypeSourceInfo() const {
+  TypeSourceInfo *getIntegerTypeSourceInfo() const {
     return IntegerType.dyn_cast<TypeSourceInfo*>();
   }
 
+  /// \brief Retrieve the source range that covers the underlying type if
+  /// specified.
+  SourceRange getIntegerTypeRange() const LLVM_READONLY;
+
   /// \brief Returns the width in bits required to store all the
   /// non-negative enumerators of this enum.
   unsigned getNumPositiveBits() const {
@@ -3024,14 +3070,14 @@
   friend class DeclContext;
 
 protected:
-  RecordDecl(Kind DK, TagKind TK, DeclContext *DC,
+  RecordDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC,
              SourceLocation StartLoc, SourceLocation IdLoc,
              IdentifierInfo *Id, RecordDecl *PrevDecl);
 
 public:
   static RecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC,
                             SourceLocation StartLoc, SourceLocation IdLoc,
-                            IdentifierInfo *Id, RecordDecl* PrevDecl = 0);
+                            IdentifierInfo *Id, RecordDecl* PrevDecl = nullptr);
   static RecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID);
 
   RecordDecl *getPreviousDecl() {
@@ -3106,7 +3152,9 @@
   // the non-static data members of this class, ignoring any static
   // data members, functions, constructors, destructors, etc.
   typedef specific_decl_iterator<FieldDecl> field_iterator;
+  typedef llvm::iterator_range<specific_decl_iterator<FieldDecl>> field_range;
 
+  field_range fields() const { return field_range(field_begin(), field_end()); }
   field_iterator field_begin() const;
 
   field_iterator field_end() const {
@@ -3155,7 +3203,7 @@
   SourceLocation getAsmLoc() const { return getLocation(); }
   SourceLocation getRParenLoc() const { return RParenLoc; }
   void setRParenLoc(SourceLocation L) { RParenLoc = L; }
-  SourceRange getSourceRange() const LLVM_READONLY {
+  SourceRange getSourceRange() const override LLVM_READONLY {
     return SourceRange(getAsmLoc(), getRParenLoc());
   }
 
@@ -3206,7 +3254,7 @@
     /// is not from outside the immediately enclosing function/block.
     bool isNested() const { return VariableAndFlags.getInt() & flag_isNested; }
 
-    bool hasCopyExpr() const { return CopyExpr != 0; }
+    bool hasCopyExpr() const { return CopyExpr != nullptr; }
     Expr *getCopyExpr() const { return CopyExpr; }
     void setCopyExpr(Expr *e) { CopyExpr = e; }
   };
@@ -3237,9 +3285,9 @@
     : Decl(Block, DC, CaretLoc), DeclContext(Block),
       IsVariadic(false), CapturesCXXThis(false),
       BlockMissingReturnType(true), IsConversionFromLambda(false),
-      ParamInfo(0), NumParams(0), Body(0),
-      SignatureAsWritten(0), Captures(0), NumCaptures(0),
-      ManglingNumber(0), ManglingContextDecl(0) {}
+      ParamInfo(nullptr), NumParams(0), Body(nullptr),
+      SignatureAsWritten(nullptr), Captures(nullptr), NumCaptures(0),
+      ManglingNumber(0), ManglingContextDecl(nullptr) {}
 
 public:
   static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L); 
@@ -3251,7 +3299,7 @@
   void setIsVariadic(bool value) { IsVariadic = value; }
 
   CompoundStmt *getCompoundBody() const { return (CompoundStmt*) Body; }
-  Stmt *getBody() const { return (Stmt*) Body; }
+  Stmt *getBody() const override { return (Stmt*) Body; }
   void setBody(CompoundStmt *B) { Body = (Stmt*) B; }
 
   void setSignatureAsWritten(TypeSourceInfo *Sig) { SignatureAsWritten = Sig; }
@@ -3261,13 +3309,31 @@
   unsigned param_size() const { return getNumParams(); }
   typedef ParmVarDecl **param_iterator;
   typedef ParmVarDecl * const *param_const_iterator;
+  typedef llvm::iterator_range<param_iterator> param_range;
+  typedef llvm::iterator_range<param_const_iterator> param_const_range;
+
+  // ArrayRef access to formal parameters.
+  // FIXME: Should eventual replace iterator access.
+  ArrayRef<ParmVarDecl*> parameters() const {
+    return llvm::makeArrayRef(ParamInfo, param_size());
+  }
 
   bool param_empty() const { return NumParams == 0; }
-  param_iterator param_begin()  { return ParamInfo; }
-  param_iterator param_end()   { return ParamInfo+param_size(); }
+  param_range params() { return param_range(param_begin(), param_end()); }
+  param_iterator param_begin() { return param_iterator(ParamInfo); }
+  param_iterator param_end() {
+    return param_iterator(ParamInfo + param_size());
+  }
 
-  param_const_iterator param_begin() const { return ParamInfo; }
-  param_const_iterator param_end() const   { return ParamInfo+param_size(); }
+  param_const_range params() const {
+    return param_const_range(param_begin(), param_end());
+  }
+  param_const_iterator param_begin() const {
+    return param_const_iterator(ParamInfo);
+  }
+  param_const_iterator param_end() const {
+    return param_const_iterator(ParamInfo + param_size());
+  }
 
   unsigned getNumParams() const { return NumParams; }
   const ParmVarDecl *getParamDecl(unsigned i) const {
@@ -3290,6 +3356,16 @@
 
   typedef const Capture *capture_iterator;
   typedef const Capture *capture_const_iterator;
+  typedef llvm::iterator_range<capture_iterator> capture_range;
+  typedef llvm::iterator_range<capture_const_iterator> capture_const_range;
+
+  capture_range captures() {
+    return capture_range(capture_begin(), capture_end());
+  }
+  capture_const_range captures() const {
+    return capture_const_range(capture_begin(), capture_end());
+  }
+
   capture_iterator capture_begin() { return Captures; }
   capture_iterator capture_end() { return Captures + NumCaptures; }
   capture_const_iterator capture_begin() const { return Captures; }
@@ -3321,7 +3397,7 @@
     ManglingContextDecl = Ctx;
   }
 
-  virtual SourceRange getSourceRange() const LLVM_READONLY;
+  SourceRange getSourceRange() const override LLVM_READONLY;
 
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -3340,12 +3416,14 @@
 private:
   /// \brief The number of parameters to the outlined function.
   unsigned NumParams;
+  /// \brief The position of context parameter in list of parameters.
+  unsigned ContextParam;
   /// \brief The body of the outlined function.
-  Stmt *Body;
+  llvm::PointerIntPair<Stmt *, 1, bool> BodyAndNothrow;
 
   explicit CapturedDecl(DeclContext *DC, unsigned NumParams)
     : Decl(Captured, DC, SourceLocation()), DeclContext(Captured),
-      NumParams(NumParams), Body(0) { }
+      NumParams(NumParams), ContextParam(0), BodyAndNothrow(nullptr, false) { }
 
   ImplicitParamDecl **getParams() const {
     return reinterpret_cast<ImplicitParamDecl **>(
@@ -3353,12 +3431,16 @@
   }
 
 public:
-  static CapturedDecl *Create(ASTContext &C, DeclContext *DC, unsigned NumParams);
+  static CapturedDecl *Create(ASTContext &C, DeclContext *DC,
+                              unsigned NumParams);
   static CapturedDecl *CreateDeserialized(ASTContext &C, unsigned ID,
                                           unsigned NumParams);
 
-  Stmt *getBody() const { return Body; }
-  void setBody(Stmt *B) { Body = B; }
+  Stmt *getBody() const override { return BodyAndNothrow.getPointer(); }
+  void setBody(Stmt *B) { BodyAndNothrow.setPointer(B); }
+
+  bool isNothrow() const { return BodyAndNothrow.getInt(); }
+  void setNothrow(bool Nothrow = true) { BodyAndNothrow.setInt(Nothrow); }
 
   unsigned getNumParams() const { return NumParams; }
 
@@ -3372,15 +3454,28 @@
   }
 
   /// \brief Retrieve the parameter containing captured variables.
-  ImplicitParamDecl *getContextParam() const { return getParam(0); }
-  void setContextParam(ImplicitParamDecl *P) { setParam(0, P); }
+  ImplicitParamDecl *getContextParam() const {
+    assert(ContextParam < NumParams);
+    return getParam(ContextParam);
+  }
+  void setContextParam(unsigned i, ImplicitParamDecl *P) {
+    assert(i < NumParams);
+    ContextParam = i;
+    setParam(i, P);
+  }
+  unsigned getContextParamPosition() const { return ContextParam; }
 
   typedef ImplicitParamDecl **param_iterator;
+  typedef llvm::iterator_range<param_iterator> param_range;
+
   /// \brief Retrieve an iterator pointing to the first parameter decl.
   param_iterator param_begin() const { return getParams(); }
   /// \brief Retrieve an iterator one past the last parameter decl.
   param_iterator param_end() const { return getParams() + NumParams; }
 
+  /// \brief Retrieve an iterator range for the parameter declarations.
+  param_range params() const { return param_range(param_begin(), param_end()); }
+
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
   static bool classofKind(Kind K) { return K == Captured; }
@@ -3455,9 +3550,9 @@
   /// This will return an empty array if the locations of the individual
   /// identifiers aren't available.
   ArrayRef<SourceLocation> getIdentifierLocs() const;
-  
-  virtual SourceRange getSourceRange() const LLVM_READONLY;
-  
+
+  SourceRange getSourceRange() const override LLVM_READONLY;
+
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
   static bool classofKind(Kind K) { return K == Import; }
 };
@@ -3496,6 +3591,8 @@
 void Redeclarable<decl_type>::setPreviousDecl(decl_type *PrevDecl) {
   // Note: This routine is implemented here because we need both NamedDecl
   // and Redeclarable to be defined.
+  assert(RedeclLink.NextIsLatest() &&
+         "setPreviousDecl on a decl already in a redeclaration chain");
 
   decl_type *First;
 
@@ -3505,7 +3602,7 @@
     // redeclaration is invalid, it won't be PrevDecl, but we want it anyway.
     First = PrevDecl->getFirstDecl();
     assert(First->RedeclLink.NextIsLatest() && "Expected first");
-    decl_type *MostRecent = First->RedeclLink.getNext();
+    decl_type *MostRecent = First->getNextRedeclaration();
     RedeclLink = PreviousDeclLink(cast<decl_type>(MostRecent));
 
     // If the declaration was previously visible, a redeclaration of it remains
@@ -3519,7 +3616,8 @@
   }
 
   // First one will point to this one as latest.
-  First->RedeclLink = LatestDeclLink(static_cast<decl_type*>(this));
+  First->RedeclLink.setLatest(static_cast<decl_type*>(this));
+
   assert(!isa<NamedDecl>(static_cast<decl_type*>(this)) ||
          cast<NamedDecl>(static_cast<decl_type*>(this))->isLinkageValid());
 }
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index 26eea64..607ca4e 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -16,9 +16,9 @@
 
 #include "clang/AST/AttrIterator.h"
 #include "clang/AST/DeclarationName.h"
-#include "clang/Basic/Linkage.h"
 #include "clang/Basic/Specifiers.h"
 #include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/iterator_range.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/PrettyStackTrace.h"
 
@@ -32,6 +32,8 @@
 class DependentDiagnostic;
 class EnumDecl;
 class FunctionDecl;
+class FunctionType;
+enum Linkage : unsigned char;
 class LinkageComputer;
 class LinkageSpecDecl;
 class Module;
@@ -52,20 +54,6 @@
 class UsingDirectiveDecl;
 }
 
-namespace llvm {
-// DeclContext* is only 4-byte aligned on 32-bit systems.
-template<>
-  class PointerLikeTypeTraits<clang::DeclContext*> {
-  typedef clang::DeclContext* PT;
-public:
-  static inline void *getAsVoidPointer(PT P) { return P; }
-  static inline PT getFromVoidPointer(void *P) {
-    return static_cast<PT>(P);
-  }
-  enum { NumLowBitsAvailable = 2 };
-};
-}
-
 namespace clang {
 
   /// \brief Captures the result of checking the availability of a
@@ -302,8 +290,24 @@
 
   template<typename decl_type> friend class Redeclarable;
 
+  /// \brief Allocate memory for a deserialized declaration.
+  ///
+  /// This routine must be used to allocate memory for any declaration that is
+  /// deserialized from a module file.
+  ///
+  /// \param Size The size of the allocated object.
+  /// \param Ctx The context in which we will allocate memory.
+  /// \param ID The global ID of the deserialized declaration.
+  /// \param Extra The amount of extra space to allocate after the object.
+  void *operator new(std::size_t Size, const ASTContext &Ctx, unsigned ID,
+                     std::size_t Extra = 0);
+
+  /// \brief Allocate memory for a non-deserialized declaration.
+  void *operator new(std::size_t Size, const ASTContext &Ctx,
+                     DeclContext *Parent, std::size_t Extra = 0);
+
 private:
-  void CheckAccessDeclContext() const;
+  bool AccessDeclContextSanity() const;
 
 protected:
 
@@ -330,18 +334,6 @@
 
   virtual ~Decl();
 
-  /// \brief Allocate memory for a deserialized declaration.
-  ///
-  /// This routine must be used to allocate memory for any declaration that is
-  /// deserialized from a module file.
-  ///
-  /// \param Context The context in which we will allocate memory.
-  /// \param ID The global ID of the deserialized declaration.
-  /// \param Size The size of the allocated object.
-  static void *AllocateDeserializedDecl(const ASTContext &Context,
-                                        unsigned ID,
-                                        unsigned Size);
-
   /// \brief Update a potentially out-of-date declaration.
   void updateOutOfDate(IdentifierInfo &II) const;
 
@@ -405,19 +397,17 @@
 
   bool isInAnonymousNamespace() const;
 
+  bool isInStdNamespace() const;
+
   ASTContext &getASTContext() const LLVM_READONLY;
 
   void setAccess(AccessSpecifier AS) {
     Access = AS;
-#ifndef NDEBUG
-    CheckAccessDeclContext();
-#endif
+    assert(AccessDeclContextSanity());
   }
 
   AccessSpecifier getAccess() const {
-#ifndef NDEBUG
-    CheckAccessDeclContext();
-#endif
+    assert(AccessDeclContextSanity());
     return AccessSpecifier(Access);
   }
 
@@ -445,14 +435,17 @@
   }
 
   typedef AttrVec::const_iterator attr_iterator;
+  typedef llvm::iterator_range<attr_iterator> attr_range;
 
-  // FIXME: Do not rely on iterators having comparable singular values.
-  //        Note that this should error out if they do not.
+  attr_range attrs() const {
+    return attr_range(attr_begin(), attr_end());
+  }
+
   attr_iterator attr_begin() const {
-    return hasAttrs() ? getAttrs().begin() : 0;
+    return hasAttrs() ? getAttrs().begin() : nullptr;
   }
   attr_iterator attr_end() const {
-    return hasAttrs() ? getAttrs().end() : 0;
+    return hasAttrs() ? getAttrs().end() : nullptr;
   }
 
   template <typename T>
@@ -467,6 +460,12 @@
   }
 
   template <typename T>
+  llvm::iterator_range<specific_attr_iterator<T>> specific_attrs() const {
+    return llvm::iterator_range<specific_attr_iterator<T>>(
+        specific_attr_begin<T>(), specific_attr_end<T>());
+  }
+
+  template <typename T>
   specific_attr_iterator<T> specific_attr_begin() const {
     return specific_attr_iterator<T>(attr_begin());
   }
@@ -476,7 +475,7 @@
   }
 
   template<typename T> T *getAttr() const {
-    return hasAttrs() ? getSpecificAttr<T>(getAttrs()) : 0;
+    return hasAttrs() ? getSpecificAttr<T>(getAttrs()) : nullptr;
   }
   template<typename T> bool hasAttr() const {
     return hasAttrs() && hasSpecificAttr<T>(getAttrs());
@@ -573,14 +572,14 @@
   /// AR_Available, will be set to a (possibly empty) message
   /// describing why the declaration has not been introduced, is
   /// deprecated, or is unavailable.
-  AvailabilityResult getAvailability(std::string *Message = 0) const;
+  AvailabilityResult getAvailability(std::string *Message = nullptr) const;
 
   /// \brief Determine whether this declaration is marked 'deprecated'.
   ///
   /// \param Message If non-NULL and the declaration is deprecated,
   /// this will be set to the message describing why the declaration
   /// was deprecated (which may be empty).
-  bool isDeprecated(std::string *Message = 0) const {
+  bool isDeprecated(std::string *Message = nullptr) const {
     return getAvailability(Message) == AR_Deprecated;
   }
 
@@ -589,7 +588,7 @@
   /// \param Message If non-NULL and the declaration is unavailable,
   /// this will be set to the message describing why the declaration
   /// was made unavailable (which may be empty).
-  bool isUnavailable(std::string *Message = 0) const {
+  bool isUnavailable(std::string *Message = nullptr) const {
     return getAvailability(Message) == AR_Unavailable;
   }
 
@@ -636,7 +635,7 @@
 public:
   Module *getOwningModule() const {
     if (!isFromASTFile())
-      return 0;
+      return nullptr;
 
     return getOwningModuleSlow();
   }
@@ -691,7 +690,7 @@
   /// roughly global variables and functions, but also handles enums (which
   /// could be defined inside or outside a function etc).
   bool isDefinedOutsideFunctionOrMethod() const {
-    return getParentFunctionOrMethod() == 0;
+    return getParentFunctionOrMethod() == nullptr;
   }
 
   /// \brief If this decl is defined inside a function/method/block it returns
@@ -716,16 +715,16 @@
   ///
   /// Decl subclasses that can be redeclared should override this method so that
   /// Decl::redecl_iterator can iterate over them.
-  virtual Decl *getNextRedeclaration() { return this; }
+  virtual Decl *getNextRedeclarationImpl() { return this; }
 
   /// \brief Implementation of getPreviousDecl(), to be overridden by any
   /// subclass that has a redeclaration chain.
-  virtual Decl *getPreviousDeclImpl() { return 0; }
-  
+  virtual Decl *getPreviousDeclImpl() { return nullptr; }
+
   /// \brief Implementation of getMostRecentDecl(), to be overridden by any
-  /// subclass that has a redeclaration chain.  
+  /// subclass that has a redeclaration chain.
   virtual Decl *getMostRecentDeclImpl() { return this; }
-  
+
 public:
   /// \brief Iterates through all the redeclarations of the same decl.
   class redecl_iterator {
@@ -740,7 +739,7 @@
     typedef std::forward_iterator_tag iterator_category;
     typedef std::ptrdiff_t difference_type;
 
-    redecl_iterator() : Current(0) { }
+    redecl_iterator() : Current(nullptr) { }
     explicit redecl_iterator(Decl *C) : Current(C), Starter(C) { }
 
     reference operator*() const { return Current; }
@@ -749,9 +748,9 @@
     redecl_iterator& operator++() {
       assert(Current && "Advancing while iterator has reached end");
       // Get either previous decl or latest decl.
-      Decl *Next = Current->getNextRedeclaration();
+      Decl *Next = Current->getNextRedeclarationImpl();
       assert(Next && "Should return next redeclaration or itself, never null!");
-      Current = (Next != Starter ? Next : 0);
+      Current = (Next != Starter) ? Next : nullptr;
       return *this;
     }
 
@@ -769,10 +768,16 @@
     }
   };
 
-  /// \brief Returns iterator for all the redeclarations of the same decl.
-  /// It will iterate at least once (when this decl is the only one).
+  typedef llvm::iterator_range<redecl_iterator> redecl_range;
+
+  /// \brief Returns an iterator range for all the redeclarations of the same
+  /// decl. It will iterate at least once (when this decl is the only one).
+  redecl_range redecls() const {
+    return redecl_range(redecls_begin(), redecls_end());
+  }
+
   redecl_iterator redecls_begin() const {
-    return redecl_iterator(const_cast<Decl*>(this));
+    return redecl_iterator(const_cast<Decl *>(this));
   }
   redecl_iterator redecls_end() const { return redecl_iterator(); }
 
@@ -788,7 +793,7 @@
 
   /// \brief True if this is the first declaration in its redeclaration chain.
   bool isFirstDecl() const {
-    return getPreviousDecl() == 0;
+    return getPreviousDecl() == nullptr;
   }
 
   /// \brief Retrieve the most recent declaration that declares the same entity
@@ -804,13 +809,13 @@
   /// getBody - If this Decl represents a declaration for a body of code,
   ///  such as a function or method definition, this method returns the
   ///  top-level Stmt* of that body.  Otherwise this method returns null.
-  virtual Stmt* getBody() const { return 0; }
+  virtual Stmt* getBody() const { return nullptr; }
 
   /// \brief Returns true if this \c Decl represents a declaration for a body of
   /// code, such as a function or method definition.
   /// Note that \c hasBody can also return true if any redeclaration of this
   /// \c Decl represents a declaration for a body of code.
-  virtual bool hasBody() const { return getBody() != 0; }
+  virtual bool hasBody() const { return getBody() != nullptr; }
 
   /// getBodyRBrace - Gets the right brace of the body, if a body exists.
   /// This works whether the body is a CompoundStmt or a CXXTryStmt.
@@ -836,7 +841,19 @@
   bool isTemplateDecl() const;
 
   /// \brief Whether this declaration is a function or function template.
-  bool isFunctionOrFunctionTemplate() const;
+  bool isFunctionOrFunctionTemplate() const {
+    return (DeclKind >= Decl::firstFunction &&
+            DeclKind <= Decl::lastFunction) ||
+           DeclKind == FunctionTemplate;
+  }
+
+  /// \brief Returns the function itself, or the templated function if this is a
+  /// function template.
+  FunctionDecl *getAsFunction() LLVM_READONLY;
+
+  const FunctionDecl *getAsFunction() const {
+    return const_cast<Decl *>(this)->getAsFunction();
+  }
 
   /// \brief Changes the namespace of this declaration to reflect that it's
   /// a function-local extern declaration.
@@ -938,11 +955,16 @@
                          raw_ostream &Out, const PrintingPolicy &Policy,
                          unsigned Indentation = 0);
   // Debuggers don't usually respect default arguments.
-  LLVM_ATTRIBUTE_USED void dump() const;
+  void dump() const;
   // Same as dump(), but forces color printing.
-  LLVM_ATTRIBUTE_USED void dumpColor() const;
+  void dumpColor() const;
   void dump(raw_ostream &Out) 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
+  /// have a FunctionType.
+  const FunctionType *getFunctionType(bool BlocksToo = true) const;
+
 private:
   void setAttrsImpl(const AttrVec& Attrs, ASTContext &Ctx);
   void setDeclContextsImpl(DeclContext *SemaDC, DeclContext *LexicalDC,
@@ -975,10 +997,10 @@
                        SourceManager &sm, const char *Msg)
   : TheDecl(theDecl), Loc(L), SM(sm), Message(Msg) {}
 
-  virtual void print(raw_ostream &OS) const;
+  void print(raw_ostream &OS) const override;
 };
 
-typedef llvm::MutableArrayRef<NamedDecl*> DeclContextLookupResult;
+typedef MutableArrayRef<NamedDecl *> DeclContextLookupResult;
 
 typedef ArrayRef<NamedDecl *> DeclContextLookupConstResult;
 
@@ -1048,8 +1070,8 @@
   DeclContext(Decl::Kind K)
       : DeclKind(K), ExternalLexicalStorage(false),
         ExternalVisibleStorage(false),
-        NeedToReconcileExternalVisibleStorage(false), LookupPtr(0, false),
-        FirstDecl(0), LastDecl(0) {}
+        NeedToReconcileExternalVisibleStorage(false), LookupPtr(nullptr, false),
+        FirstDecl(nullptr), LastDecl(nullptr) {}
 
 public:
   ~DeclContext();
@@ -1136,6 +1158,8 @@
     return DeclKind == Decl::Namespace;
   }
 
+  bool isStdNamespace() const;
+
   bool isInlineNamespace() const;
 
   /// \brief Determines whether this context is dependent on a
@@ -1256,7 +1280,7 @@
     typedef std::forward_iterator_tag iterator_category;
     typedef std::ptrdiff_t            difference_type;
 
-    decl_iterator() : Current(0) { }
+    decl_iterator() : Current(nullptr) { }
     explicit decl_iterator(Decl *C) : Current(C) { }
 
     reference operator*() const { return Current; }
@@ -1282,8 +1306,11 @@
     }
   };
 
+  typedef llvm::iterator_range<decl_iterator> decl_range;
+
   /// decls_begin/decls_end - Iterate over the declarations stored in
   /// this context.
+  decl_range decls() const { return decl_range(decls_begin(), decls_end()); }
   decl_iterator decls_begin() const;
   decl_iterator decls_end() const { return decl_iterator(); }
   bool decls_empty() const;
@@ -1291,7 +1318,10 @@
   /// noload_decls_begin/end - Iterate over the declarations stored in this
   /// context that are currently loaded; don't attempt to retrieve anything
   /// from an external source.
-  decl_iterator noload_decls_begin() const;
+  decl_range noload_decls() const {
+    return decl_range(noload_decls_begin(), noload_decls_end());
+  }
+  decl_iterator noload_decls_begin() const { return decl_iterator(FirstDecl); }
   decl_iterator noload_decls_end() const { return decl_iterator(); }
 
   /// specific_decl_iterator - Iterates over a subrange of
@@ -1537,6 +1567,11 @@
   /// of looking up every possible name.
   class all_lookups_iterator;
 
+  typedef llvm::iterator_range<all_lookups_iterator> lookups_range;
+
+  lookups_range lookups() const;
+  lookups_range noload_lookups() const;
+
   /// \brief Iterators over all possible lookups within this context.
   all_lookups_iterator lookups_begin() const;
   all_lookups_iterator lookups_end() const;
@@ -1547,26 +1582,15 @@
   all_lookups_iterator noload_lookups_begin() const;
   all_lookups_iterator noload_lookups_end() const;
 
-  /// udir_iterator - Iterates through the using-directives stored
-  /// within this context.
-  typedef UsingDirectiveDecl * const * udir_iterator;
+  typedef llvm::iterator_range<UsingDirectiveDecl * const *> udir_range;
 
-  typedef std::pair<udir_iterator, udir_iterator> udir_iterator_range;
-
-  udir_iterator_range getUsingDirectives() const;
-
-  udir_iterator using_directives_begin() const {
-    return getUsingDirectives().first;
-  }
-
-  udir_iterator using_directives_end() const {
-    return getUsingDirectives().second;
-  }
+  udir_range using_directives() const;
 
   // These are all defined in DependentDiagnostic.h.
   class ddiag_iterator;
-  inline ddiag_iterator ddiag_begin() const;
-  inline ddiag_iterator ddiag_end() const;
+  typedef llvm::iterator_range<DeclContext::ddiag_iterator> ddiag_range;
+
+  inline ddiag_range ddiags() const;
 
   // Low-level accessors
     
@@ -1616,12 +1640,12 @@
   static bool classof(const Decl *D);
   static bool classof(const DeclContext *D) { return true; }
 
-  LLVM_ATTRIBUTE_USED void dumpDeclContext() const;
-  LLVM_ATTRIBUTE_USED void dumpLookups() const;
-  LLVM_ATTRIBUTE_USED void dumpLookups(llvm::raw_ostream &OS) const;
+  void dumpDeclContext() const;
+  void dumpLookups() const;
+  void dumpLookups(llvm::raw_ostream &OS) const;
 
 private:
-  void reconcileExternalVisibleStorage();
+  void reconcileExternalVisibleStorage() const;
   void LoadLexicalDeclsFromExternalStorage() const;
 
   /// @brief Makes a declaration visible within this context, but
@@ -1650,7 +1674,7 @@
 
 // Specialization selected when ToTy is not a known subclass of DeclContext.
 template <class ToTy,
-          bool IsKnownSubtype = ::llvm::is_base_of< DeclContext, ToTy>::value>
+          bool IsKnownSubtype = ::std::is_base_of<DeclContext, ToTy>::value>
 struct cast_convert_decl_context {
   static const ToTy *doit(const DeclContext *Val) {
     return static_cast<const ToTy*>(Decl::castFromDeclContext(Val));
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index dbc4132..72fad7c 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -17,13 +17,12 @@
 #define LLVM_CLANG_AST_DECLCXX_H
 
 #include "clang/AST/ASTUnresolvedSet.h"
+#include "clang/AST/Attr.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/Expr.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/TypeLoc.h"
+#include "clang/AST/LambdaCapture.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/Support/Compiler.h"
 
 namespace clang {
@@ -122,14 +121,14 @@
   /// \brief Sets the location of the colon.
   void setColonLoc(SourceLocation CLoc) { ColonLoc = CLoc; }
 
-  SourceRange getSourceRange() const LLVM_READONLY {
+  SourceRange getSourceRange() const override LLVM_READONLY {
     return SourceRange(getAccessSpecifierLoc(), getColonLoc());
   }
 
   static AccessSpecDecl *Create(ASTContext &C, AccessSpecifier AS,
                                 DeclContext *DC, SourceLocation ASLoc,
                                 SourceLocation ColonLoc) {
-    return new (C) AccessSpecDecl(AS, DC, ASLoc, ColonLoc);
+    return new (C, DC) AccessSpecDecl(AS, DC, ASLoc, ColonLoc);
   }
   static AccessSpecDecl *CreateDeserialized(ASTContext &C, unsigned ID);
 
@@ -258,20 +257,31 @@
   TypeSourceInfo *getTypeSourceInfo() const { return BaseTypeInfo; }
 };
 
-/// The inheritance model to use for member pointers of a given CXXRecordDecl.
-enum MSInheritanceModel {
-  MSIM_Single,
-  MSIM_SinglePolymorphic,
-  MSIM_Multiple,
-  MSIM_MultiplePolymorphic,
-  MSIM_Virtual,
-  MSIM_Unspecified
+/// \brief A lazy pointer to the definition data for a declaration.
+/// FIXME: This is a little CXXRecordDecl-specific that the moment.
+template<typename Decl, typename T> class LazyDefinitionDataPtr {
+  llvm::PointerUnion<T *, Decl *> DataOrCanonicalDecl;
+
+  LazyDefinitionDataPtr update() {
+    if (Decl *Canon = DataOrCanonicalDecl.template dyn_cast<Decl*>()) {
+      if (Canon->isCanonicalDecl())
+        Canon->getMostRecentDecl();
+      else
+        // Declaration isn't canonical any more;
+        // update it and perform path compression.
+        *this = Canon->getPreviousDecl()->DefinitionData.update();
+    }
+    return *this;
+  }
+
+public:
+  LazyDefinitionDataPtr(Decl *Canon) : DataOrCanonicalDecl(Canon) {}
+  LazyDefinitionDataPtr(T *Data) : DataOrCanonicalDecl(Data) {}
+  T *getNotUpdated() { return DataOrCanonicalDecl.template dyn_cast<T*>(); }
+  T *get() { return update().getNotUpdated(); }
 };
 
 /// \brief Represents a C++ struct/union/class.
-///
-/// FIXME: This class will disappear once we've properly taught RecordDecl
-/// to deal with C++-specific things.
 class CXXRecordDecl : public RecordDecl {
 
   friend void TagDecl::startDefinition();
@@ -350,10 +360,15 @@
     /// \brief True if this class (or any subobject) has mutable fields.
     bool HasMutableFields : 1;
 
+    /// \brief True if this class (or any nested anonymous struct or union)
+    /// has variant members.
+    bool HasVariantMembers : 1;
+
     /// \brief True if there no non-field members declared by the user.
     bool HasOnlyCMembers : 1;
 
-    /// \brief True if any field has an in-class initializer.
+    /// \brief True if any field has an in-class initializer, including those
+    /// within anonymous unions or structs.
     bool HasInClassInitializer : 1;
 
     /// \brief True if any field is of reference type, and does not have an
@@ -409,7 +424,7 @@
     /// \brief True if this class has a constexpr default constructor.
     ///
     /// This is true for either a user-declared constexpr default constructor
-    /// or an implicitly declared constexpr default constructor..
+    /// or an implicitly declared constexpr default constructor.
     bool HasConstexprDefaultConstructor : 1;
 
     /// \brief True when this class contains at least one non-static data
@@ -447,6 +462,9 @@
     /// \brief Whether this class describes a C++ lambda.
     bool IsLambda : 1;
 
+    /// \brief Whether we are currently parsing base specifiers.
+    bool IsParsingBaseSpecifiers : 1;
+
     /// \brief The number of base class specifiers in Bases.
     unsigned NumBases;
 
@@ -486,33 +504,39 @@
     /// \brief Retrieve the set of direct base classes.
     CXXBaseSpecifier *getBases() const {
       if (!Bases.isOffset())
-        return Bases.get(0);
+        return Bases.get(nullptr);
       return getBasesSlowCase();
     }
 
     /// \brief Retrieve the set of virtual base classes.
     CXXBaseSpecifier *getVBases() const {
       if (!VBases.isOffset())
-        return VBases.get(0);
+        return VBases.get(nullptr);
       return getVBasesSlowCase();
     }
 
   private:
     CXXBaseSpecifier *getBasesSlowCase() const;
     CXXBaseSpecifier *getVBasesSlowCase() const;
-  } *DefinitionData;
+  };
+
+  typedef LazyDefinitionDataPtr<CXXRecordDecl, struct DefinitionData>
+      DefinitionDataPtr;
+  friend class LazyDefinitionDataPtr<CXXRecordDecl, struct DefinitionData>;
+
+  mutable DefinitionDataPtr DefinitionData;
 
   /// \brief Describes a C++ closure type (generated by a lambda expression).
   struct LambdaDefinitionData : public DefinitionData {
-    typedef LambdaExpr::Capture Capture;
-    
-       LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info, 
+    typedef LambdaCapture Capture;
+
+    LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info, 
                          bool Dependent, bool IsGeneric, 
                          LambdaCaptureDefault CaptureDefault) 
       : DefinitionData(D), Dependent(Dependent), IsGenericLambda(IsGeneric), 
         CaptureDefault(CaptureDefault), NumCaptures(0), NumExplicitCaptures(0), 
-        ManglingNumber(0), ContextDecl(0), Captures(0), MethodTyInfo(Info)
-    {
+        ManglingNumber(0), ContextDecl(nullptr), Captures(nullptr),
+        MethodTyInfo(Info) {
       IsLambda = true;
     }
 
@@ -557,23 +581,20 @@
        
   };
 
-  struct DefinitionData &data() {
-    assert(DefinitionData && "queried property of class with no definition");
-    return *DefinitionData;
-  }
-
-  const struct DefinitionData &data() const {
-    assert(DefinitionData && "queried property of class with no definition");
-    return *DefinitionData;
+  struct DefinitionData &data() const {
+    auto *DD = DefinitionData.get();
+    assert(DD && "queried property of class with no definition");
+    return *DD;
   }
 
   struct LambdaDefinitionData &getLambdaData() const {
-    assert(DefinitionData && "queried property of lambda with no definition");
-    assert(DefinitionData->IsLambda && 
-           "queried lambda property of non-lambda class");
-    return static_cast<LambdaDefinitionData &>(*DefinitionData);
+    // No update required: a merged definition cannot change any lambda
+    // properties.
+    auto *DD = DefinitionData.getNotUpdated();
+    assert(DD && DD->IsLambda && "queried lambda property of non-lambda class");
+    return static_cast<LambdaDefinitionData&>(*DD);
   }
-  
+
   /// \brief The template or declaration that this declaration
   /// describes or was instantiated from, respectively.
   ///
@@ -610,7 +631,7 @@
   FriendDecl *getFirstFriend() const;
 
 protected:
-  CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
+  CXXRecordDecl(Kind K, TagKind TK, const ASTContext &C, DeclContext *DC,
                 SourceLocation StartLoc, SourceLocation IdLoc,
                 IdentifierInfo *Id, CXXRecordDecl *PrevDecl);
 
@@ -621,17 +642,7 @@
   /// \brief Iterator that traverses the base classes of a class.
   typedef const CXXBaseSpecifier* base_class_const_iterator;
 
-  /// \brief Iterator that traverses the base classes of a class in reverse
-  /// order.
-  typedef std::reverse_iterator<base_class_iterator>
-    reverse_base_class_iterator;
-
-  /// \brief Iterator that traverses the base classes of a class in reverse
-  /// order.
-  typedef std::reverse_iterator<base_class_const_iterator>
-    reverse_base_class_const_iterator;
-
-  virtual CXXRecordDecl *getCanonicalDecl() {
+  CXXRecordDecl *getCanonicalDecl() override {
     return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl());
   }
   virtual const CXXRecordDecl *getCanonicalDecl() const {
@@ -656,19 +667,20 @@
   }
 
   CXXRecordDecl *getDefinition() const {
-    if (!DefinitionData) return 0;
-    return data().Definition;
+    auto *DD = DefinitionData.get();
+    return DD ? DD->Definition : nullptr;
   }
 
-  bool hasDefinition() const { return DefinitionData != 0; }
+  bool hasDefinition() const { return DefinitionData.get(); }
 
   static CXXRecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC,
                                SourceLocation StartLoc, SourceLocation IdLoc,
-                               IdentifierInfo *Id, CXXRecordDecl* PrevDecl=0,
+                               IdentifierInfo *Id,
+                               CXXRecordDecl *PrevDecl = nullptr,
                                bool DelayTypeCreation = false);
   static CXXRecordDecl *CreateLambda(const ASTContext &C, DeclContext *DC,
                                      TypeSourceInfo *Info, SourceLocation Loc,
-                                     bool DependentLambda, bool IsGeneric, 
+                                     bool DependentLambda, bool IsGeneric,
                                      LambdaCaptureDefault CaptureDefault);
   static CXXRecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID);
 
@@ -676,52 +688,52 @@
     return data().Polymorphic || data().NumVBases != 0;
   }
 
+  void setIsParsingBaseSpecifiers() { data().IsParsingBaseSpecifiers = true; }
+
+  bool isParsingBaseSpecifiers() const {
+    return data().IsParsingBaseSpecifiers;
+  }
+
   /// \brief Sets the base classes of this struct or class.
   void setBases(CXXBaseSpecifier const * const *Bases, unsigned NumBases);
 
   /// \brief Retrieves the number of base classes of this class.
   unsigned getNumBases() const { return data().NumBases; }
 
+  typedef llvm::iterator_range<base_class_iterator> base_class_range;
+  typedef llvm::iterator_range<base_class_const_iterator>
+    base_class_const_range;
+
+  base_class_range bases() {
+    return base_class_range(bases_begin(), bases_end());
+  }
+  base_class_const_range bases() const {
+    return base_class_const_range(bases_begin(), bases_end());
+  }
+
   base_class_iterator bases_begin() { return data().getBases(); }
   base_class_const_iterator bases_begin() const { return data().getBases(); }
   base_class_iterator bases_end() { return bases_begin() + data().NumBases; }
   base_class_const_iterator bases_end() const {
     return bases_begin() + data().NumBases;
   }
-  reverse_base_class_iterator       bases_rbegin() {
-    return reverse_base_class_iterator(bases_end());
-  }
-  reverse_base_class_const_iterator bases_rbegin() const {
-    return reverse_base_class_const_iterator(bases_end());
-  }
-  reverse_base_class_iterator bases_rend() {
-    return reverse_base_class_iterator(bases_begin());
-  }
-  reverse_base_class_const_iterator bases_rend() const {
-    return reverse_base_class_const_iterator(bases_begin());
-  }
 
   /// \brief Retrieves the number of virtual base classes of this class.
   unsigned getNumVBases() const { return data().NumVBases; }
 
+  base_class_range vbases() {
+    return base_class_range(vbases_begin(), vbases_end());
+  }
+  base_class_const_range vbases() const {
+    return base_class_const_range(vbases_begin(), vbases_end());
+  }
+
   base_class_iterator vbases_begin() { return data().getVBases(); }
   base_class_const_iterator vbases_begin() const { return data().getVBases(); }
   base_class_iterator vbases_end() { return vbases_begin() + data().NumVBases; }
   base_class_const_iterator vbases_end() const {
     return vbases_begin() + data().NumVBases;
   }
-  reverse_base_class_iterator vbases_rbegin() {
-    return reverse_base_class_iterator(vbases_end());
-  }
-  reverse_base_class_const_iterator vbases_rbegin() const {
-    return reverse_base_class_const_iterator(vbases_end());
-  }
-  reverse_base_class_iterator vbases_rend() {
-    return reverse_base_class_iterator(vbases_begin());
-  }
-  reverse_base_class_const_iterator vbases_rend() const {
-    return reverse_base_class_const_iterator(vbases_begin());
- }
 
   /// \brief Determine whether this class has any dependent base classes which
   /// are not the current instantiation.
@@ -731,6 +743,12 @@
   /// all method members of the class, including non-instance methods,
   /// special methods, etc.
   typedef specific_decl_iterator<CXXMethodDecl> method_iterator;
+  typedef llvm::iterator_range<specific_decl_iterator<CXXMethodDecl>>
+    method_range;
+
+  method_range methods() const {
+    return method_range(method_begin(), method_end());
+  }
 
   /// \brief Method begin iterator.  Iterates in the order the methods
   /// were declared.
@@ -744,6 +762,10 @@
 
   /// Iterator access to constructor members.
   typedef specific_decl_iterator<CXXConstructorDecl> ctor_iterator;
+  typedef llvm::iterator_range<specific_decl_iterator<CXXConstructorDecl>>
+    ctor_range;
+
+  ctor_range ctors() const { return ctor_range(ctor_begin(), ctor_end()); }
 
   ctor_iterator ctor_begin() const {
     return ctor_iterator(decls_begin());
@@ -755,6 +777,9 @@
   /// An iterator over friend declarations.  All of these are defined
   /// in DeclFriend.h.
   class friend_iterator;
+  typedef llvm::iterator_range<friend_iterator> friend_range;
+
+  friend_range friends() const;
   friend_iterator friend_begin() const;
   friend_iterator friend_end() const;
   void pushFriendDecl(FriendDecl *FD);
@@ -984,7 +1009,11 @@
   }
 
   /// \brief Determine whether this class describes a lambda function object.
-  bool isLambda() const { return hasDefinition() && data().IsLambda; }
+  bool isLambda() const {
+    // An update record can't turn a non-lambda into a lambda.
+    auto *DD = DefinitionData.getNotUpdated();
+    return DD && DD->IsLambda;
+  }
 
   /// \brief Determine whether this class describes a generic 
   /// lambda function object (i.e. function call operator is
@@ -1025,12 +1054,18 @@
   void getCaptureFields(llvm::DenseMap<const VarDecl *, FieldDecl *> &Captures,
                         FieldDecl *&ThisCapture) const;
 
-  typedef const LambdaExpr::Capture* capture_const_iterator;
+  typedef const LambdaCapture *capture_const_iterator;
+  typedef llvm::iterator_range<capture_const_iterator> capture_const_range;
+
+  capture_const_range captures() const {
+    return capture_const_range(captures_begin(), captures_end());
+  }
   capture_const_iterator captures_begin() const {
-    return isLambda() ? getLambdaData().Captures : NULL;
+    return isLambda() ? getLambdaData().Captures : nullptr;
   }
   capture_const_iterator captures_end() const {
-    return isLambda() ? captures_begin() + getLambdaData().NumCaptures : NULL;
+    return isLambda() ? captures_begin() + getLambdaData().NumCaptures
+                      : nullptr;
   }
 
   typedef UnresolvedSetIterator conversion_iterator;
@@ -1058,7 +1093,8 @@
   bool isAggregate() const { return data().Aggregate; }
 
   /// \brief Whether this class has any in-class initializers
-  /// for non-static data members.
+  /// for non-static data members (including those in anonymous unions or
+  /// structs).
   bool hasInClassInitializer() const { return data().HasInClassInitializer; }
 
   /// \brief Whether this class or any of its subobjects has any members of
@@ -1117,6 +1153,9 @@
   /// contains a mutable field.
   bool hasMutableFields() const { return data().HasMutableFields; }
 
+  /// \brief Determine whether this class has any variant members.
+  bool hasVariantMembers() const { return data().HasVariantMembers; }
+
   /// \brief Determine whether this class has a trivial default constructor
   /// (C++11 [class.ctor]p5).
   bool hasTrivialDefaultConstructor() const {
@@ -1144,7 +1183,7 @@
   /// would be constexpr.
   bool defaultedDefaultConstructorIsConstexpr() const {
     return data().DefaultedDefaultConstructorIsConstexpr &&
-           (!isUnion() || hasInClassInitializer());
+           (!isUnion() || hasInClassInitializer() || !hasVariantMembers());
   }
 
   /// \brief Determine whether this class has a constexpr default constructor.
@@ -1546,7 +1585,7 @@
   void finishedDefaultedOrDeletedMember(CXXMethodDecl *MD);
 
   /// \brief Indicates that the definition of this class is now complete.
-  virtual void completeDefinition();
+  void completeDefinition() override;
 
   /// \brief Indicates that the definition of this class is now complete,
   /// and provides a final overrider map to help determine
@@ -1599,7 +1638,25 @@
   }
 
   /// \brief Returns the inheritance model used for this record.
-  MSInheritanceModel getMSInheritanceModel() const;
+  MSInheritanceAttr::Spelling getMSInheritanceModel() const;
+  /// \brief Calculate what the inheritance model would be for this class.
+  MSInheritanceAttr::Spelling calculateInheritanceModel() const;
+
+  /// In the Microsoft C++ ABI, use zero for the field offset of a null data
+  /// member pointer if we can guarantee that zero is not a valid field offset,
+  /// or if the member pointer has multiple fields.  Polymorphic classes have a
+  /// vfptr at offset zero, so we can use zero for null.  If there are multiple
+  /// fields, we can use zero even if it is a valid field offset because
+  /// null-ness testing will check the other fields.
+  bool nullFieldOffsetIsZero() const {
+    return !MSInheritanceAttr::hasOnlyOneField(/*IsMemberFunction=*/false,
+                                               getMSInheritanceModel()) ||
+           (hasDefinition() && isPolymorphic());
+  }
+
+  /// \brief Controls when vtordisps will be emitted if this record is used as a
+  /// virtual base.
+  MSVtorDispAttr::Mode getMSVtorDispMode() const;
 
   /// \brief Determine whether this lambda expression was known to be dependent
   /// at the time it was created, even if its context does not appear to be
@@ -1636,14 +1693,14 @@
 /// In the terminology of the C++ Standard, these are the (static and
 /// non-static) member functions, whether virtual or not.
 class CXXMethodDecl : public FunctionDecl {
-  virtual void anchor();
+  void anchor() override;
 protected:
-  CXXMethodDecl(Kind DK, CXXRecordDecl *RD, SourceLocation StartLoc,
-                const DeclarationNameInfo &NameInfo,
+  CXXMethodDecl(Kind DK, ASTContext &C, CXXRecordDecl *RD,
+                SourceLocation StartLoc, const DeclarationNameInfo &NameInfo,
                 QualType T, TypeSourceInfo *TInfo,
                 StorageClass SC, bool isInline,
                 bool isConstexpr, SourceLocation EndLocation)
-    : FunctionDecl(DK, RD, StartLoc, NameInfo, T, TInfo,
+    : FunctionDecl(DK, C, RD, StartLoc, NameInfo, T, TInfo,
                    SC, isInline, isConstexpr) {
     if (EndLocation.isValid())
       setRangeEnd(EndLocation);
@@ -1683,9 +1740,9 @@
     CXXMethodDecl *CD =
       cast<CXXMethodDecl>(const_cast<CXXMethodDecl*>(this)->getCanonicalDecl());
 
-    // Methods declared in interfaces are automatically (pure) virtual.
-    if (CD->isVirtualAsWritten() ||
-          (CD->getParent()->isInterface() && CD->isUserProvided()))
+    // Member function is virtual if it is marked explicitly so, or if it is
+    // declared in __interface -- then it is automatically pure virtual.
+    if (CD->isVirtualAsWritten() || CD->isPure())
       return true;
 
     return (CD->begin_overridden_methods() != CD->end_overridden_methods());
@@ -1703,10 +1760,10 @@
   /// \brief Determine whether this is a move assignment operator.
   bool isMoveAssignmentOperator() const;
 
-  CXXMethodDecl *getCanonicalDecl() {
+  CXXMethodDecl *getCanonicalDecl() override {
     return cast<CXXMethodDecl>(FunctionDecl::getCanonicalDecl());
   }
-  const CXXMethodDecl *getCanonicalDecl() const {
+  const CXXMethodDecl *getCanonicalDecl() const override {
     return const_cast<CXXMethodDecl*>(this)->getCanonicalDecl();
   }
 
@@ -1921,7 +1978,7 @@
   /// In-class member initializers (also known as "non-static data member
   /// initializations", NSDMIs) were introduced in C++11.
   bool isInClassMemberInitializer() const {
-    return isa<CXXDefaultInitExpr>(Init);
+    return Init->getStmtClass() == Stmt::CXXDefaultInitExprClass;
   }
 
   /// \brief Determine whether this initializer is creating a delegating
@@ -1968,20 +2025,20 @@
   FieldDecl *getMember() const {
     if (isMemberInitializer())
       return Initializee.get<FieldDecl*>();
-    return 0;
+    return nullptr;
   }
   FieldDecl *getAnyMember() const {
     if (isMemberInitializer())
       return Initializee.get<FieldDecl*>();
     if (isIndirectMemberInitializer())
       return Initializee.get<IndirectFieldDecl*>()->getAnonField();
-    return 0;
+    return nullptr;
   }
 
   IndirectFieldDecl *getIndirectMember() const {
     if (isIndirectMemberInitializer())
       return Initializee.get<IndirectFieldDecl*>();
-    return 0;
+    return nullptr;
   }
 
   SourceLocation getMemberLocation() const {
@@ -2066,7 +2123,7 @@
 /// };
 /// \endcode
 class CXXConstructorDecl : public CXXMethodDecl {
-  virtual void anchor();
+  void anchor() override;
   /// \brief Whether this constructor declaration has the \c explicit keyword
   /// specified.
   bool IsExplicitSpecified : 1;
@@ -2078,14 +2135,14 @@
   unsigned NumCtorInitializers;
   /// \}
 
-  CXXConstructorDecl(CXXRecordDecl *RD, SourceLocation StartLoc,
+  CXXConstructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
                      const DeclarationNameInfo &NameInfo,
                      QualType T, TypeSourceInfo *TInfo,
                      bool isExplicitSpecified, bool isInline,
                      bool isImplicitlyDeclared, bool isConstexpr)
-    : CXXMethodDecl(CXXConstructor, RD, StartLoc, NameInfo, T, TInfo,
+    : CXXMethodDecl(CXXConstructor, C, RD, StartLoc, NameInfo, T, TInfo,
                     SC_None, isInline, isConstexpr, SourceLocation()),
-      IsExplicitSpecified(isExplicitSpecified), CtorInitializers(0),
+      IsExplicitSpecified(isExplicitSpecified), CtorInitializers(nullptr),
       NumCtorInitializers(0) {
     setImplicit(isImplicitlyDeclared);
   }
@@ -2115,6 +2172,14 @@
   /// \brief Iterates through the member/base initializer list.
   typedef CXXCtorInitializer * const * init_const_iterator;
 
+  typedef llvm::iterator_range<init_iterator> init_range;
+  typedef llvm::iterator_range<init_const_iterator> init_const_range;
+
+  init_range inits() { return init_range(init_begin(), init_end()); }
+  init_const_range inits() const {
+    return init_const_range(init_begin(), init_end());
+  }
+
   /// \brief Retrieve an iterator to the first initializer.
   init_iterator       init_begin()       { return CtorInitializers; }
   /// \brief Retrieve an iterator to the first initializer.
@@ -2240,10 +2305,10 @@
   /// \brief Set the constructor that this inheriting constructor is based on.
   void setInheritedConstructor(const CXXConstructorDecl *BaseCtor);
 
-  const CXXConstructorDecl *getCanonicalDecl() const {
+  const CXXConstructorDecl *getCanonicalDecl() const override {
     return cast<CXXConstructorDecl>(FunctionDecl::getCanonicalDecl());
   }
-  CXXConstructorDecl *getCanonicalDecl() {
+  CXXConstructorDecl *getCanonicalDecl() override {
     return cast<CXXConstructorDecl>(FunctionDecl::getCanonicalDecl());
   }
 
@@ -2266,17 +2331,17 @@
 /// };
 /// \endcode
 class CXXDestructorDecl : public CXXMethodDecl {
-  virtual void anchor();
+  void anchor() override;
 
   FunctionDecl *OperatorDelete;
 
-  CXXDestructorDecl(CXXRecordDecl *RD, SourceLocation StartLoc,
+  CXXDestructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
                     const DeclarationNameInfo &NameInfo,
                     QualType T, TypeSourceInfo *TInfo,
                     bool isInline, bool isImplicitlyDeclared)
-    : CXXMethodDecl(CXXDestructor, RD, StartLoc, NameInfo, T, TInfo,
+    : CXXMethodDecl(CXXDestructor, C, RD, StartLoc, NameInfo, T, TInfo,
                     SC_None, isInline, /*isConstexpr=*/false, SourceLocation()),
-      OperatorDelete(0) {
+      OperatorDelete(nullptr) {
     setImplicit(isImplicitlyDeclared);
   }
 
@@ -2289,8 +2354,12 @@
                                    bool isImplicitlyDeclared);
   static CXXDestructorDecl *CreateDeserialized(ASTContext & C, unsigned ID);
 
-  void setOperatorDelete(FunctionDecl *OD) { OperatorDelete = OD; }
-  const FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
+  void setOperatorDelete(FunctionDecl *OD) {
+    cast<CXXDestructorDecl>(getFirstDecl())->OperatorDelete = OD;
+  }
+  const FunctionDecl *getOperatorDelete() const {
+    return cast<CXXDestructorDecl>(getFirstDecl())->OperatorDelete;
+  }
 
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -2311,18 +2380,18 @@
 /// };
 /// \endcode
 class CXXConversionDecl : public CXXMethodDecl {
-  virtual void anchor();
+  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++0x feature.
   bool IsExplicitSpecified : 1;
 
-  CXXConversionDecl(CXXRecordDecl *RD, SourceLocation StartLoc,
+  CXXConversionDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
                     const DeclarationNameInfo &NameInfo,
                     QualType T, TypeSourceInfo *TInfo,
                     bool isInline, bool isExplicitSpecified,
                     bool isConstexpr, SourceLocation EndLocation)
-    : CXXMethodDecl(CXXConversion, RD, StartLoc, NameInfo, T, TInfo,
+    : CXXMethodDecl(CXXConversion, C, RD, StartLoc, NameInfo, T, TInfo,
                     SC_None, isInline, isConstexpr, EndLocation),
       IsExplicitSpecified(isExplicitSpecified) { }
 
@@ -2351,7 +2420,7 @@
 
   /// \brief Returns the type that this conversion function is converting to.
   QualType getConversionType() const {
-    return getType()->getAs<FunctionType>()->getResultType();
+    return getType()->getAs<FunctionType>()->getReturnType();
   }
 
   /// \brief Determine whether this conversion function is a conversion from
@@ -2440,7 +2509,7 @@
     return decls_empty() ? getLocation() : decls_begin()->getLocEnd();
   }
 
-  SourceRange getSourceRange() const LLVM_READONLY {
+  SourceRange getSourceRange() const override LLVM_READONLY {
     return SourceRange(ExternLoc, getLocEnd());
   }
 
@@ -2465,7 +2534,7 @@
 /// artificial names for all using-directives in order to store
 /// them in DeclContext effectively.
 class UsingDirectiveDecl : public NamedDecl {
-  virtual void anchor();
+  void anchor() override;
   /// \brief The location of the \c using keyword.
   SourceLocation UsingLoc;
 
@@ -2546,8 +2615,8 @@
                                     NamedDecl *Nominated,
                                     DeclContext *CommonAncestor);
   static UsingDirectiveDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-  
-  SourceRange getSourceRange() const LLVM_READONLY {
+
+  SourceRange getSourceRange() const override LLVM_READONLY {
     return SourceRange(UsingLoc, getLocation());
   }
 
@@ -2568,7 +2637,7 @@
 /// namespace Foo = Bar;
 /// \endcode
 class NamespaceAliasDecl : public NamedDecl {
-  virtual void anchor();
+  void anchor() override;
 
   /// \brief The location of the \c namespace keyword.
   SourceLocation NamespaceLoc;
@@ -2641,8 +2710,8 @@
                                     NamedDecl *Namespace);
 
   static NamespaceAliasDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-  
-  virtual SourceRange getSourceRange() const LLVM_READONLY {
+
+  SourceRange getSourceRange() const override LLVM_READONLY {
     return SourceRange(NamespaceLoc, IdentLoc);
   }
 
@@ -2664,7 +2733,7 @@
 /// }
 /// \endcode
 class UsingShadowDecl : public NamedDecl, public Redeclarable<UsingShadowDecl> {
-  virtual void anchor();
+  void anchor() override;
 
   /// The referenced declaration.
   NamedDecl *Underlying;
@@ -2674,10 +2743,10 @@
   NamedDecl *UsingOrNextShadow;
   friend class UsingDecl;
 
-  UsingShadowDecl(DeclContext *DC, SourceLocation Loc, UsingDecl *Using,
-                  NamedDecl *Target)
+  UsingShadowDecl(ASTContext &C, DeclContext *DC, SourceLocation Loc,
+                  UsingDecl *Using, NamedDecl *Target)
     : NamedDecl(UsingShadow, DC, Loc, DeclarationName()),
-      Underlying(Target),
+      redeclarable_base(C), Underlying(Target),
       UsingOrNextShadow(reinterpret_cast<NamedDecl *>(Using)) {
     if (Target) {
       setDeclName(Target->getDeclName());
@@ -2687,13 +2756,13 @@
   }
 
   typedef Redeclarable<UsingShadowDecl> redeclarable_base;
-  virtual UsingShadowDecl *getNextRedeclaration() {
-    return RedeclLink.getNext();
+  UsingShadowDecl *getNextRedeclarationImpl() override {
+    return getNextRedeclaration();
   }
-  virtual UsingShadowDecl *getPreviousDeclImpl() {
+  UsingShadowDecl *getPreviousDeclImpl() override {
     return getPreviousDecl();
   }
-  virtual UsingShadowDecl *getMostRecentDeclImpl() {
+  UsingShadowDecl *getMostRecentDeclImpl() override {
     return getMostRecentDecl();
   }
 
@@ -2701,21 +2770,23 @@
   static UsingShadowDecl *Create(ASTContext &C, DeclContext *DC,
                                  SourceLocation Loc, UsingDecl *Using,
                                  NamedDecl *Target) {
-    return new (C) UsingShadowDecl(DC, Loc, Using, Target);
+    return new (C, DC) UsingShadowDecl(C, DC, Loc, Using, Target);
   }
 
   static UsingShadowDecl *CreateDeserialized(ASTContext &C, unsigned ID);
 
+  typedef redeclarable_base::redecl_range redecl_range;
   typedef redeclarable_base::redecl_iterator redecl_iterator;
   using redeclarable_base::redecls_begin;
   using redeclarable_base::redecls_end;
+  using redeclarable_base::redecls;
   using redeclarable_base::getPreviousDecl;
   using redeclarable_base::getMostRecentDecl;
 
-  virtual UsingShadowDecl *getCanonicalDecl() {
+  UsingShadowDecl *getCanonicalDecl() override {
     return getFirstDecl();
   }
-  virtual const UsingShadowDecl *getCanonicalDecl() const {
+  const UsingShadowDecl *getCanonicalDecl() const {
     return getFirstDecl();
   }
 
@@ -2754,7 +2825,7 @@
 ///    using someNameSpace::someIdentifier;
 /// \endcode
 class UsingDecl : public NamedDecl {
-  virtual void anchor();
+  void anchor() override;
 
   /// \brief The source location of the 'using' keyword itself.
   SourceLocation UsingLocation;
@@ -2778,7 +2849,7 @@
             const DeclarationNameInfo &NameInfo, bool HasTypenameKeyword)
     : NamedDecl(Using, DC, NameInfo.getLoc(), NameInfo.getName()),
       UsingLocation(UL), QualifierLoc(QualifierLoc),
-      DNLoc(NameInfo.getInfo()), FirstUsingShadow(0, HasTypenameKeyword) {
+      DNLoc(NameInfo.getInfo()), FirstUsingShadow(nullptr, HasTypenameKeyword) {
   }
 
 public:
@@ -2823,7 +2894,7 @@
     typedef std::forward_iterator_tag iterator_category;
     typedef std::ptrdiff_t            difference_type;
 
-    shadow_iterator() : Current(0) { }
+    shadow_iterator() : Current(nullptr) { }
     explicit shadow_iterator(UsingShadowDecl *C) : Current(C) { }
 
     reference operator*() const { return Current; }
@@ -2848,6 +2919,11 @@
     }
   };
 
+  typedef llvm::iterator_range<shadow_iterator> shadow_range;
+
+  shadow_range shadows() const {
+    return shadow_range(shadow_begin(), shadow_end());
+  }
   shadow_iterator shadow_begin() const {
     return shadow_iterator(FirstUsingShadow.getPointer());
   }
@@ -2870,7 +2946,7 @@
 
   static UsingDecl *CreateDeserialized(ASTContext &C, unsigned ID);
 
-  SourceRange getSourceRange() const LLVM_READONLY;
+  SourceRange getSourceRange() const override LLVM_READONLY;
 
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
   static bool classofKind(Kind K) { return K == Using; }
@@ -2891,7 +2967,7 @@
 /// };
 /// \endcode
 class UnresolvedUsingValueDecl : public ValueDecl {
-  virtual void anchor();
+  void anchor() override;
 
   /// \brief The source location of the 'using' keyword
   SourceLocation UsingLocation;
@@ -2944,7 +3020,7 @@
   static UnresolvedUsingValueDecl *
   CreateDeserialized(ASTContext &C, unsigned ID);
 
-  SourceRange getSourceRange() const LLVM_READONLY;
+  SourceRange getSourceRange() const override LLVM_READONLY;
 
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
   static bool classofKind(Kind K) { return K == UnresolvedUsingValue; }
@@ -2965,7 +3041,7 @@
 /// The type associated with an unresolved using typename decl is
 /// currently always a typename type.
 class UnresolvedUsingTypenameDecl : public TypeDecl {
-  virtual void anchor();
+  void anchor() override;
 
   /// \brief The source location of the 'typename' keyword
   SourceLocation TypenameLocation;
@@ -3043,7 +3119,7 @@
 
   SourceLocation getRParenLoc() const { return RParenLoc; }
 
-  SourceRange getSourceRange() const LLVM_READONLY {
+  SourceRange getSourceRange() const override LLVM_READONLY {
     return SourceRange(getLocation(), getRParenLoc());
   }
 
@@ -3083,21 +3159,24 @@
 class MSPropertyDecl : public DeclaratorDecl {
   IdentifierInfo *GetterId, *SetterId;
 
-public:
-  MSPropertyDecl(DeclContext *DC, SourceLocation L,
-                 DeclarationName N, QualType T, TypeSourceInfo *TInfo,
-                 SourceLocation StartL, IdentifierInfo *Getter,
-                 IdentifierInfo *Setter):
-  DeclaratorDecl(MSProperty, DC, L, N, T, TInfo, StartL), GetterId(Getter),
-  SetterId(Setter) {}
+  MSPropertyDecl(DeclContext *DC, SourceLocation L, DeclarationName N,
+                 QualType T, TypeSourceInfo *TInfo, SourceLocation StartL,
+                 IdentifierInfo *Getter, IdentifierInfo *Setter)
+      : DeclaratorDecl(MSProperty, DC, L, N, T, TInfo, StartL),
+        GetterId(Getter), SetterId(Setter) {}
 
+public:
+  static MSPropertyDecl *Create(ASTContext &C, DeclContext *DC,
+                                SourceLocation L, DeclarationName N, QualType T,
+                                TypeSourceInfo *TInfo, SourceLocation StartL,
+                                IdentifierInfo *Getter, IdentifierInfo *Setter);
   static MSPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID);
 
   static bool classof(const Decl *D) { return D->getKind() == MSProperty; }
 
-  bool hasGetter() const { return GetterId != NULL; }
+  bool hasGetter() const { return GetterId != nullptr; }
   IdentifierInfo* getGetterId() const { return GetterId; }
-  bool hasSetter() const { return SetterId != NULL; }
+  bool hasSetter() const { return SetterId != nullptr; }
   IdentifierInfo* getSetterId() const { return SetterId; }
 
   friend class ASTDeclReader;
diff --git a/include/clang/AST/DeclContextInternals.h b/include/clang/AST/DeclContextInternals.h
index 9c626c8..9068c00 100644
--- a/include/clang/AST/DeclContextInternals.h
+++ b/include/clang/AST/DeclContextInternals.h
@@ -46,10 +46,8 @@
 public:
   StoredDeclsList() {}
 
-  StoredDeclsList(const StoredDeclsList &RHS) : Data(RHS.Data) {
-    if (DeclsTy *RHSVec = RHS.getAsVector())
-      Data = DeclsAndHasExternalTy(new DeclsTy(*RHSVec),
-                                   RHS.hasExternalDecls());
+  StoredDeclsList(StoredDeclsList &&RHS) : Data(RHS.Data) {
+    RHS.Data = (NamedDecl *)nullptr;
   }
 
   ~StoredDeclsList() {
@@ -58,12 +56,11 @@
       delete Vector;
   }
 
-  StoredDeclsList &operator=(const StoredDeclsList &RHS) {
+  StoredDeclsList &operator=(StoredDeclsList &&RHS) {
     if (DeclsTy *Vector = getAsVector())
       delete Vector;
     Data = RHS.Data;
-    if (DeclsTy *RHSVec = RHS.getAsVector())
-      Data = DeclsAndHasExternalTy(new DeclsTy(*RHSVec), hasExternalDecls());
+    RHS.Data = (NamedDecl *)nullptr;
     return *this;
   }
 
@@ -110,7 +107,7 @@
     if (NamedDecl *Singleton = getAsDecl()) {
       assert(Singleton == D && "list is different singleton");
       (void)Singleton;
-      Data = (NamedDecl *)0;
+      Data = (NamedDecl *)nullptr;
       return;
     }
 
@@ -145,8 +142,8 @@
   /// represents.
   DeclContext::lookup_result getLookupResult() {
     if (isNull())
-      return DeclContext::lookup_result(DeclContext::lookup_iterator(0),
-                                        DeclContext::lookup_iterator(0));
+      return DeclContext::lookup_result(DeclContext::lookup_iterator(nullptr),
+                                        DeclContext::lookup_iterator(nullptr));
 
     // If we have a single NamedDecl, return it.
     if (getAsDecl()) {
@@ -255,7 +252,7 @@
 
 class DependentStoredDeclsMap : public StoredDeclsMap {
 public:
-  DependentStoredDeclsMap() : FirstDiagnostic(0) {}
+  DependentStoredDeclsMap() : FirstDiagnostic(nullptr) {}
 
 private:
   friend class DependentDiagnostic;
diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h
index be6f2eb..12b93b4 100644
--- a/include/clang/AST/DeclFriend.h
+++ b/include/clang/AST/DeclFriend.h
@@ -17,6 +17,7 @@
 
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclTemplate.h"
+#include "clang/AST/TypeLoc.h"
 #include "llvm/Support/Compiler.h"
 
 namespace clang {
@@ -91,7 +92,7 @@
 
   FriendDecl *getNextFriend() {
     if (!NextFriend.isOffset())
-      return cast_or_null<FriendDecl>(NextFriend.get(0));
+      return cast_or_null<FriendDecl>(NextFriend.get(nullptr));
     return getNextFriendSlowCase();
   }
   FriendDecl *getNextFriendSlowCase();
@@ -132,10 +133,14 @@
   }
 
   /// Retrieves the source range for the friend declaration.
-  SourceRange getSourceRange() const LLVM_READONLY {
+  SourceRange getSourceRange() const override LLVM_READONLY {
     if (NamedDecl *ND = getFriendDecl()) {
+      if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND))
+        return FD->getSourceRange();
       if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(ND))
         return FTD->getSourceRange();
+      if (ClassTemplateDecl *CTD = dyn_cast<ClassTemplateDecl>(ND))
+        return CTD->getSourceRange();
       if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(ND)) {
         if (DD->getOuterLocStart() != DD->getInnerLocStart())
           return DD->getSourceRange();
@@ -224,7 +229,11 @@
 }
 
 inline CXXRecordDecl::friend_iterator CXXRecordDecl::friend_end() const {
-  return friend_iterator(0);
+  return friend_iterator(nullptr);
+}
+
+inline CXXRecordDecl::friend_range CXXRecordDecl::friends() const {
+  return friend_range(friend_begin(), friend_end());
 }
 
 inline void CXXRecordDecl::pushFriendDecl(FriendDecl *FD) {
diff --git a/include/clang/AST/DeclGroup.h b/include/clang/AST/DeclGroup.h
index cda6ae5..bd3dbd8 100644
--- a/include/clang/AST/DeclGroup.h
+++ b/include/clang/AST/DeclGroup.h
@@ -63,7 +63,7 @@
   }
 
 public:
-  DeclGroupRef() : D(0) {}
+  DeclGroupRef() : D(nullptr) {}
 
   explicit DeclGroupRef(Decl* d) : D(d) {}
   explicit DeclGroupRef(DeclGroup* dg)
@@ -80,7 +80,7 @@
   typedef Decl** iterator;
   typedef Decl* const * const_iterator;
 
-  bool isNull() const { return D == 0; }
+  bool isNull() const { return D == nullptr; }
   bool isSingleDecl() const { return getKind() == SingleDeclKind; }
   bool isDeclGroup() const { return getKind() == DeclGroupKind; }
 
@@ -102,26 +102,26 @@
 
   iterator begin() {
     if (isSingleDecl())
-      return D ? &D : 0;
+      return D ? &D : nullptr;
     return &getDeclGroup()[0];
   }
 
   iterator end() {
     if (isSingleDecl())
-      return D ? &D+1 : 0;
+      return D ? &D+1 : nullptr;
     DeclGroup &G = getDeclGroup();
     return &G[0] + G.size();
   }
 
   const_iterator begin() const {
     if (isSingleDecl())
-      return D ? &D : 0;
+      return D ? &D : nullptr;
     return &getDeclGroup()[0];
   }
 
   const_iterator end() const {
     if (isSingleDecl())
-      return D ? &D+1 : 0;
+      return D ? &D+1 : nullptr;
     const DeclGroup &G = getDeclGroup();
     return &G[0] + G.size();
   }
diff --git a/include/clang/AST/DeclLookups.h b/include/clang/AST/DeclLookups.h
index c16975a..d2016af 100644
--- a/include/clang/AST/DeclLookups.h
+++ b/include/clang/AST/DeclLookups.h
@@ -68,38 +68,40 @@
   }
 };
 
-inline DeclContext::all_lookups_iterator DeclContext::lookups_begin() const {
+inline DeclContext::lookups_range DeclContext::lookups() const {
   DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext();
   if (Primary->hasExternalVisibleStorage())
     getParentASTContext().getExternalSource()->completeVisibleDeclsMap(Primary);
   if (StoredDeclsMap *Map = Primary->buildLookup())
-    return all_lookups_iterator(Map->begin(), Map->end());
-  return all_lookups_iterator();
+    return lookups_range(all_lookups_iterator(Map->begin(), Map->end()),
+                         all_lookups_iterator(Map->end(), Map->end()));
+  return lookups_range();
+}
+
+inline DeclContext::all_lookups_iterator DeclContext::lookups_begin() const {
+  return lookups().begin();
 }
 
 inline DeclContext::all_lookups_iterator DeclContext::lookups_end() const {
+  return lookups().end();
+}
+
+inline DeclContext::lookups_range DeclContext::noload_lookups() const {
   DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext();
-  if (Primary->hasExternalVisibleStorage())
-    getParentASTContext().getExternalSource()->completeVisibleDeclsMap(Primary);
-  if (StoredDeclsMap *Map = Primary->buildLookup())
-    return all_lookups_iterator(Map->end(), Map->end());
-  return all_lookups_iterator();
+  if (StoredDeclsMap *Map = Primary->getLookupPtr())
+    return lookups_range(all_lookups_iterator(Map->begin(), Map->end()),
+                         all_lookups_iterator(Map->end(), Map->end()));
+  return lookups_range();
 }
 
 inline
 DeclContext::all_lookups_iterator DeclContext::noload_lookups_begin() const {
-  DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext();
-  if (StoredDeclsMap *Map = Primary->getLookupPtr())
-    return all_lookups_iterator(Map->begin(), Map->end());
-  return all_lookups_iterator();
+  return noload_lookups().begin();
 }
 
 inline
 DeclContext::all_lookups_iterator DeclContext::noload_lookups_end() const {
-  DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext();
-  if (StoredDeclsMap *Map = Primary->getLookupPtr())
-    return all_lookups_iterator(Map->end(), Map->end());
-  return all_lookups_iterator();
+  return noload_lookups().end();
 }
 
 } // end namespace clang
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index 2e760d6..db3b084 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -41,7 +41,7 @@
   unsigned NumElts;
 
 public:
-  ObjCListBase() : List(0), NumElts(0) {}
+  ObjCListBase() : List(nullptr), NumElts(0) {}
   unsigned size() const { return NumElts; }
   bool empty() const { return NumElts == 0; }
 
@@ -79,7 +79,7 @@
   using ObjCList<ObjCProtocolDecl>::set;
 
 public:
-  ObjCProtocolList() : ObjCList<ObjCProtocolDecl>(), Locations(0) { }
+  ObjCProtocolList() : ObjCList<ObjCProtocolDecl>(), Locations(nullptr) { }
 
   typedef const SourceLocation *loc_iterator;
   loc_iterator loc_begin() const { return Locations; }
@@ -162,11 +162,11 @@
   /// \brief Indicates if the method was a definition but its body was skipped.
   unsigned HasSkippedBody : 1;
 
-  // Result type of this method.
+  // Return type of this method.
   QualType MethodDeclType;
 
-  // Type source information for the result type.
-  TypeSourceInfo *ResultTInfo;
+  // Type source information for the return type.
+  TypeSourceInfo *ReturnTInfo;
 
   /// \brief Array of ParmVarDecls for the formal parameters of this method
   /// and optionally followed by selector locations.
@@ -224,54 +224,44 @@
                            ArrayRef<SourceLocation> SelLocs);
 
   ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc,
-                 Selector SelInfo, QualType T,
-                 TypeSourceInfo *ResultTInfo,
-                 DeclContext *contextDecl,
-                 bool isInstance = true,
-                 bool isVariadic = false,
-                 bool isPropertyAccessor = false,
-                 bool isImplicitlyDeclared = false,
-                 bool isDefined = false,
+                 Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo,
+                 DeclContext *contextDecl, bool isInstance = true,
+                 bool isVariadic = false, bool isPropertyAccessor = false,
+                 bool isImplicitlyDeclared = false, bool isDefined = false,
                  ImplementationControl impControl = None,
                  bool HasRelatedResultType = false)
-  : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo),
-    DeclContext(ObjCMethod), Family(InvalidObjCMethodFamily),
-    IsInstance(isInstance), IsVariadic(isVariadic),
-    IsPropertyAccessor(isPropertyAccessor),
-    IsDefined(isDefined), IsRedeclaration(0), HasRedeclaration(0),
-    DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None),
-    RelatedResultType(HasRelatedResultType),
-    SelLocsKind(SelLoc_StandardNoSpace), IsOverriding(0), HasSkippedBody(0),
-    MethodDeclType(T), ResultTInfo(ResultTInfo),
-    ParamsAndSelLocs(0), NumParams(0),
-    DeclEndLoc(endLoc), Body(), SelfDecl(0), CmdDecl(0) {
+      : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo),
+        DeclContext(ObjCMethod), Family(InvalidObjCMethodFamily),
+        IsInstance(isInstance), IsVariadic(isVariadic),
+        IsPropertyAccessor(isPropertyAccessor), IsDefined(isDefined),
+        IsRedeclaration(0), HasRedeclaration(0), DeclImplementation(impControl),
+        objcDeclQualifier(OBJC_TQ_None),
+        RelatedResultType(HasRelatedResultType),
+        SelLocsKind(SelLoc_StandardNoSpace), IsOverriding(0), HasSkippedBody(0),
+        MethodDeclType(T), ReturnTInfo(ReturnTInfo), ParamsAndSelLocs(nullptr),
+        NumParams(0), DeclEndLoc(endLoc), Body(), SelfDecl(nullptr),
+        CmdDecl(nullptr) {
     setImplicit(isImplicitlyDeclared);
   }
 
   /// \brief A definition will return its interface declaration.
   /// An interface declaration will return its definition.
   /// Otherwise it will return itself.
-  virtual ObjCMethodDecl *getNextRedeclaration();
+  ObjCMethodDecl *getNextRedeclarationImpl() override;
 
 public:
-  static ObjCMethodDecl *Create(ASTContext &C,
-                                SourceLocation beginLoc,
-                                SourceLocation endLoc,
-                                Selector SelInfo,
-                                QualType T,
-                                TypeSourceInfo *ResultTInfo,
-                                DeclContext *contextDecl,
-                                bool isInstance = true,
-                                bool isVariadic = false,
-                                bool isPropertyAccessor = false,
-                                bool isImplicitlyDeclared = false,
-                                bool isDefined = false,
-                                ImplementationControl impControl = None,
-                                bool HasRelatedResultType = false);
+  static ObjCMethodDecl *
+  Create(ASTContext &C, SourceLocation beginLoc, SourceLocation endLoc,
+         Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo,
+         DeclContext *contextDecl, bool isInstance = true,
+         bool isVariadic = false, bool isPropertyAccessor = false,
+         bool isImplicitlyDeclared = false, bool isDefined = false,
+         ImplementationControl impControl = None,
+         bool HasRelatedResultType = false);
 
   static ObjCMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-  
-  virtual ObjCMethodDecl *getCanonicalDecl();
+
+  ObjCMethodDecl *getCanonicalDecl() override;
   const ObjCMethodDecl *getCanonicalDecl() const {
     return const_cast<ObjCMethodDecl*>(this)->getCanonicalDecl();
   }
@@ -300,7 +290,7 @@
   // Location information, modeled after the Stmt API.
   SourceLocation getLocStart() const LLVM_READONLY { return getLocation(); }
   SourceLocation getLocEnd() const LLVM_READONLY;
-  virtual SourceRange getSourceRange() const LLVM_READONLY {
+  SourceRange getSourceRange() const override LLVM_READONLY {
     return SourceRange(getLocation(), getLocEnd());
   }
 
@@ -314,8 +304,7 @@
     if (hasStandardSelLocs())
       return getStandardSelectorLoc(Index, getSelector(),
                                    getSelLocsKind() == SelLoc_StandardWithSpace,
-                      llvm::makeArrayRef(const_cast<ParmVarDecl**>(getParams()),
-                                         NumParams),
+                                    parameters(),
                                    DeclEndLoc);
     return getStoredSelLocs()[Index];
   }
@@ -338,32 +327,52 @@
 
   Selector getSelector() const { return getDeclName().getObjCSelector(); }
 
-  QualType getResultType() const { return MethodDeclType; }
-  void setResultType(QualType T) { MethodDeclType = T; }
+  QualType getReturnType() const { return MethodDeclType; }
+  void setReturnType(QualType T) { MethodDeclType = T; }
 
   /// \brief Determine the type of an expression that sends a message to this
   /// function.
   QualType getSendResultType() const {
-    return getResultType().getNonLValueExprType(getASTContext());
+    return getReturnType().getNonLValueExprType(getASTContext());
   }
 
-  TypeSourceInfo *getResultTypeSourceInfo() const { return ResultTInfo; }
-  void setResultTypeSourceInfo(TypeSourceInfo *TInfo) { ResultTInfo = TInfo; }
+  TypeSourceInfo *getReturnTypeSourceInfo() const { return ReturnTInfo; }
+  void setReturnTypeSourceInfo(TypeSourceInfo *TInfo) { ReturnTInfo = TInfo; }
 
   // Iterator access to formal parameters.
   unsigned param_size() const { return NumParams; }
   typedef const ParmVarDecl *const *param_const_iterator;
   typedef ParmVarDecl *const *param_iterator;
-  param_const_iterator param_begin() const { return getParams(); }
-  param_const_iterator param_end() const { return getParams() + NumParams; }
-  param_iterator param_begin() { return getParams(); }
-  param_iterator param_end() { return getParams() + NumParams; }
+  typedef llvm::iterator_range<param_iterator> param_range;
+  typedef llvm::iterator_range<param_const_iterator> param_const_range;
+
+  param_range params() { return param_range(param_begin(), param_end()); }
+  param_const_range params() const {
+    return param_const_range(param_begin(), param_end());
+  }
+
+  param_const_iterator param_begin() const {
+    return param_const_iterator(getParams());
+  }
+  param_const_iterator param_end() const {
+    return param_const_iterator(getParams() + NumParams);
+  }
+  param_iterator param_begin() { return param_iterator(getParams()); }
+  param_iterator param_end() { return param_iterator(getParams() + NumParams); }
+
   // This method returns and of the parameters which are part of the selector
   // name mangling requirements.
   param_const_iterator sel_param_end() const {
     return param_begin() + getSelector().getNumArgs();
   }
 
+  // ArrayRef access to formal parameters.  This should eventually
+  // replace the iterator interface above.
+  ArrayRef<ParmVarDecl*> parameters() const {
+    return llvm::makeArrayRef(const_cast<ParmVarDecl**>(getParams()),
+                              NumParams);
+  }
+
   /// \brief Sets the method's parameters and selector source locations.
   /// If the method is implicit (not coming from source) \p SelLocs is
   /// ignored.
@@ -375,12 +384,12 @@
   // Iterator access to parameter types.
   typedef std::const_mem_fun_t<QualType, ParmVarDecl> deref_fun;
   typedef llvm::mapped_iterator<param_const_iterator, deref_fun>
-      arg_type_iterator;
+  param_type_iterator;
 
-  arg_type_iterator arg_type_begin() const {
+  param_type_iterator param_type_begin() const {
     return llvm::map_iterator(param_begin(), deref_fun(&ParmVarDecl::getType));
   }
-  arg_type_iterator arg_type_end() const {
+  param_type_iterator param_type_end() const {
     return llvm::map_iterator(param_end(), deref_fun(&ParmVarDecl::getType));
   }
 
@@ -451,11 +460,24 @@
     return ImplementationControl(DeclImplementation);
   }
 
+  /// Returns true if this specific method declaration is marked with the
+  /// designated initializer attribute.
+  bool isThisDeclarationADesignatedInitializer() const;
+
+  /// Returns true if the method selector resolves to a designated initializer
+  /// in the class's interface.
+  ///
+  /// \param InitMethod if non-null and the function returns true, it receives
+  /// the method declaration that was marked with the designated initializer
+  /// attribute.
+  bool isDesignatedInitializerForTheInterface(
+      const ObjCMethodDecl **InitMethod = nullptr) const;
+
   /// \brief Determine whether this method has a body.
-  virtual bool hasBody() const { return Body.isValid(); }
+  bool hasBody() const override { return Body.isValid(); }
 
   /// \brief Retrieve the body of this method, if it has one.
-  virtual Stmt *getBody() const;
+  Stmt *getBody() const override;
 
   void setLazyBody(uint64_t Offset) { Body = Offset; }
 
@@ -484,7 +506,7 @@
 /// ObjCProtocolDecl, and ObjCImplDecl.
 ///
 class ObjCContainerDecl : public NamedDecl, public DeclContext {
-  virtual void anchor();
+  void anchor() override;
 
   SourceLocation AtStart;
 
@@ -500,6 +522,10 @@
 
   // Iterator access to properties.
   typedef specific_decl_iterator<ObjCPropertyDecl> prop_iterator;
+  typedef llvm::iterator_range<specific_decl_iterator<ObjCPropertyDecl>>
+    prop_range;
+
+  prop_range properties() const { return prop_range(prop_begin(), prop_end()); }
   prop_iterator prop_begin() const {
     return prop_iterator(decls_begin());
   }
@@ -509,6 +535,12 @@
 
   // Iterator access to instance/class methods.
   typedef specific_decl_iterator<ObjCMethodDecl> method_iterator;
+  typedef llvm::iterator_range<specific_decl_iterator<ObjCMethodDecl>>
+    method_range;
+
+  method_range methods() const {
+    return method_range(meth_begin(), meth_end());
+  }
   method_iterator meth_begin() const {
     return method_iterator(decls_begin());
   }
@@ -519,6 +551,11 @@
   typedef filtered_decl_iterator<ObjCMethodDecl,
                                  &ObjCMethodDecl::isInstanceMethod>
     instmeth_iterator;
+  typedef llvm::iterator_range<instmeth_iterator> instmeth_range;
+
+  instmeth_range instance_methods() const {
+    return instmeth_range(instmeth_begin(), instmeth_end());
+  }
   instmeth_iterator instmeth_begin() const {
     return instmeth_iterator(decls_begin());
   }
@@ -529,6 +566,11 @@
   typedef filtered_decl_iterator<ObjCMethodDecl,
                                  &ObjCMethodDecl::isClassMethod>
     classmeth_iterator;
+  typedef llvm::iterator_range<classmeth_iterator> classmeth_range;
+
+  classmeth_range class_methods() const {
+    return classmeth_range(classmeth_begin(), classmeth_end());
+  }
   classmeth_iterator classmeth_begin() const {
     return classmeth_iterator(decls_begin());
   }
@@ -575,7 +617,7 @@
     AtEnd = atEnd;
   }
 
-  virtual SourceRange getSourceRange() const LLVM_READONLY {
+  SourceRange getSourceRange() const override LLVM_READONLY {
     return SourceRange(AtStart, getAtEndRange().getEnd());
   }
 
@@ -621,7 +663,7 @@
 ///
 class ObjCInterfaceDecl : public ObjCContainerDecl
                         , public Redeclarable<ObjCInterfaceDecl> {
-  virtual void anchor();
+  void anchor() override;
 
   /// TypeForDecl - This indicates the Type object that represents this
   /// TypeDecl.  It is a cache maintained by ASTContext::getObjCInterfaceType
@@ -661,6 +703,22 @@
     /// declared in the implementation.
     mutable bool IvarListMissingImplementation : 1;
 
+    /// Indicates that this interface decl contains at least one initializer
+    /// marked with the 'objc_designated_initializer' attribute.
+    bool HasDesignatedInitializers : 1;
+
+    enum InheritedDesignatedInitializersState {
+      /// We didn't calculate whether the designated initializers should be
+      /// inherited or not.
+      IDI_Unknown = 0,
+      /// Designated initializers are inherited for the super class.
+      IDI_Inherited = 1,
+      /// The class does not inherit designated initializers.
+      IDI_NotInherited = 2
+    };
+    /// One of the \c InheritedDesignatedInitializersState enumeratos.
+    mutable unsigned InheritedDesignatedInitializers : 2;
+
     /// \brief The location of the superclass, if any.
     SourceLocation SuperClassLoc;
     
@@ -671,12 +729,14 @@
 
     DefinitionData() : Definition(), SuperClass(), CategoryList(), IvarList(), 
                        ExternallyCompleted(),
-                       IvarListMissingImplementation(true) { }
+                       IvarListMissingImplementation(true),
+                       HasDesignatedInitializers(),
+                       InheritedDesignatedInitializers(IDI_Unknown) { }
   };
 
-  ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
-                    SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl,
-                    bool isInternal);
+  ObjCInterfaceDecl(const ASTContext &C, DeclContext *DC, SourceLocation AtLoc,
+                    IdentifierInfo *Id, SourceLocation CLoc,
+                    ObjCInterfaceDecl *PrevDecl, bool IsInternal);
 
   void LoadExternalDefinition() const;
 
@@ -696,13 +756,13 @@
   void allocateDefinitionData();
   
   typedef Redeclarable<ObjCInterfaceDecl> redeclarable_base;
-  virtual ObjCInterfaceDecl *getNextRedeclaration() { 
-    return RedeclLink.getNext();
+  ObjCInterfaceDecl *getNextRedeclarationImpl() override {
+    return getNextRedeclaration();
   }
-  virtual ObjCInterfaceDecl *getPreviousDeclImpl() {
+  ObjCInterfaceDecl *getPreviousDeclImpl() override {
     return getPreviousDecl();
   }
-  virtual ObjCInterfaceDecl *getMostRecentDeclImpl() {
+  ObjCInterfaceDecl *getMostRecentDeclImpl() override {
     return getMostRecentDecl();
   }
 
@@ -714,9 +774,9 @@
                                    SourceLocation ClassLoc = SourceLocation(),
                                    bool isInternal = false);
 
-  static ObjCInterfaceDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+  static ObjCInterfaceDecl *CreateDeserialized(const ASTContext &C, unsigned ID);
 
-  virtual SourceRange getSourceRange() const LLVM_READONLY {
+  SourceRange getSourceRange() const override LLVM_READONLY {
     if (isThisDeclarationADefinition())
       return ObjCContainerDecl::getSourceRange();
     
@@ -728,6 +788,20 @@
   /// when a complete class is required.
   void setExternallyCompleted();
 
+  /// Indicate that this interface decl contains at least one initializer
+  /// marked with the 'objc_designated_initializer' attribute.
+  void setHasDesignatedInitializers();
+
+  /// Returns true if this interface decl contains at least one initializer
+  /// marked with the 'objc_designated_initializer' attribute.
+  bool hasDesignatedInitializers() const;
+
+  /// Returns true if this interface decl declares a designated initializer
+  /// or it inherites one from its super class.
+  bool declaresOrInheritsDesignatedInitializers() const {
+    return hasDesignatedInitializers() || inheritsDesignatedInitializers();
+  }
+
   const ObjCProtocolList &getReferencedProtocols() const {
     assert(hasDefinition() && "Caller did not check for forward reference!");
     if (data().ExternallyCompleted)
@@ -750,7 +824,11 @@
   }
 
   typedef ObjCProtocolList::iterator protocol_iterator;
+  typedef llvm::iterator_range<protocol_iterator> protocol_range;
 
+  protocol_range protocols() const {
+    return protocol_range(protocol_begin(), protocol_end());
+  }
   protocol_iterator protocol_begin() const {
     // FIXME: Should make sure no callers ever do this.
     if (!hasDefinition())
@@ -773,7 +851,11 @@
   }
 
   typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
+  typedef llvm::iterator_range<protocol_loc_iterator> protocol_loc_range;
 
+  protocol_loc_range protocol_locs() const {
+    return protocol_loc_range(protocol_loc_begin(), protocol_loc_end());
+  }
   protocol_loc_iterator protocol_loc_begin() const {
     // FIXME: Should make sure no callers ever do this.
     if (!hasDefinition())
@@ -797,7 +879,12 @@
   }
 
   typedef ObjCList<ObjCProtocolDecl>::iterator all_protocol_iterator;
+  typedef llvm::iterator_range<all_protocol_iterator> all_protocol_range;
 
+  all_protocol_range all_referenced_protocols() const {
+    return all_protocol_range(all_referenced_protocol_begin(),
+                              all_referenced_protocol_end());
+  }
   all_protocol_iterator all_referenced_protocol_begin() const {
     // FIXME: Should make sure no callers ever do this.
     if (!hasDefinition())
@@ -824,7 +911,9 @@
   }
 
   typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
+  typedef llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>> ivar_range;
 
+  ivar_range ivars() const { return ivar_range(ivar_begin(), ivar_end()); }
   ivar_iterator ivar_begin() const { 
     if (const ObjCInterfaceDecl *Def = getDefinition())
       return ivar_iterator(Def->decls_begin()); 
@@ -867,6 +956,31 @@
                                        unsigned Num,
                                        ASTContext &C);
 
+  /// Produce a name to be used for class's metadata. It comes either via
+  /// objc_runtime_name attribute or class name.
+  StringRef getObjCRuntimeNameAsString() const;
+
+  /// Returns the designated initializers for the interface.
+  ///
+  /// If this declaration does not have methods marked as designated
+  /// initializers then the interface inherits the designated initializers of
+  /// its super class.
+  void getDesignatedInitializers(
+                  llvm::SmallVectorImpl<const ObjCMethodDecl *> &Methods) const;
+
+  /// Returns true if the given selector is a designated initializer for the
+  /// interface.
+  ///
+  /// If this declaration does not have methods marked as designated
+  /// initializers then the interface inherits the designated initializers of
+  /// its super class.
+  ///
+  /// \param InitMethod if non-null and the function returns true, it receives
+  /// the method that was marked as a designated initializer.
+  bool
+  isDesignatedInitializer(Selector Sel,
+                          const ObjCMethodDecl **InitMethod = nullptr) const;
+
   /// \brief Determine whether this particular declaration of this class is
   /// actually also a definition.
   bool isThisDeclarationADefinition() const { 
@@ -894,14 +1008,14 @@
   /// has been forward-declared (with \@class) but not yet defined (with 
   /// \@interface).
   ObjCInterfaceDecl *getDefinition() {
-    return hasDefinition()? Data.getPointer()->Definition : 0;
+    return hasDefinition()? Data.getPointer()->Definition : nullptr;
   }
 
   /// \brief Retrieve the definition of this class, or NULL if this class 
   /// has been forward-declared (with \@class) but not yet defined (with 
   /// \@interface).
   const ObjCInterfaceDecl *getDefinition() const {
-    return hasDefinition()? Data.getPointer()->Definition : 0;
+    return hasDefinition()? Data.getPointer()->Definition : nullptr;
   }
 
   /// \brief Starts the definition of this Objective-C class, taking it from
@@ -911,7 +1025,7 @@
   ObjCInterfaceDecl *getSuperClass() const {
     // FIXME: Should make sure no callers ever do this.
     if (!hasDefinition())
-      return 0;
+      return nullptr;
     
     if (data().ExternallyCompleted)
       LoadExternalDefinition();
@@ -943,7 +1057,7 @@
     typedef std::ptrdiff_t          difference_type;
     typedef std::input_iterator_tag iterator_category;
 
-    filtered_category_iterator() : Current(0) { }
+    filtered_category_iterator() : Current(nullptr) { }
     explicit filtered_category_iterator(ObjCCategoryDecl *Current)
       : Current(Current)
     {
@@ -984,6 +1098,14 @@
   typedef filtered_category_iterator<isVisibleCategory>
     visible_categories_iterator;
 
+  typedef llvm::iterator_range<visible_categories_iterator>
+    visible_categories_range;
+
+  visible_categories_range visible_categories() const {
+    return visible_categories_range(visible_categories_begin(),
+                                    visible_categories_end());
+  }
+
   /// \brief Retrieve an iterator to the beginning of the visible-categories
   /// list.
   visible_categories_iterator visible_categories_begin() const {
@@ -1010,6 +1132,13 @@
   /// \brief Iterator that walks over all of the known categories and
   /// extensions, including those that are hidden.
   typedef filtered_category_iterator<isKnownCategory> known_categories_iterator;
+  typedef llvm::iterator_range<known_categories_iterator>
+    known_categories_range;
+
+  known_categories_range known_categories() const {
+    return known_categories_range(known_categories_begin(),
+                                  known_categories_end());
+  }
 
   /// \brief Retrieve an iterator to the beginning of the known-categories
   /// list.
@@ -1039,6 +1168,14 @@
   typedef filtered_category_iterator<isVisibleExtension>
     visible_extensions_iterator;
 
+  typedef llvm::iterator_range<visible_extensions_iterator>
+    visible_extensions_range;
+
+  visible_extensions_range visible_extensions() const {
+    return visible_extensions_range(visible_extensions_begin(),
+                                    visible_extensions_end());
+  }
+
   /// \brief Retrieve an iterator to the beginning of the visible-extensions
   /// list.
   visible_extensions_iterator visible_extensions_begin() const {
@@ -1065,6 +1202,13 @@
   /// \brief Iterator that walks over all of the known extensions.
   typedef filtered_category_iterator<isKnownExtension>
     known_extensions_iterator;
+  typedef llvm::iterator_range<known_extensions_iterator>
+    known_extensions_range;
+
+  known_extensions_range known_extensions() const {
+    return known_extensions_range(known_extensions_begin(),
+                                  known_extensions_end());
+  }
 
   /// \brief Retrieve an iterator to the beginning of the known-extensions
   /// list.
@@ -1087,7 +1231,7 @@
   ObjCCategoryDecl* getCategoryListRaw() const {
     // FIXME: Should make sure no callers ever do this.
     if (!hasDefinition())
-      return 0;
+      return nullptr;
     
     if (data().ExternallyCompleted)
       LoadExternalDefinition();
@@ -1104,14 +1248,14 @@
   ObjCPropertyDecl
     *FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId) const;
 
-  virtual void collectPropertiesToImplement(PropertyMap &PM,
-                                            PropertyDeclOrder &PO) const;
+  void collectPropertiesToImplement(PropertyMap &PM,
+                                    PropertyDeclOrder &PO) const override;
 
   /// isSuperClassOf - Return true if this class is the specified class or is a
   /// super class of the specified interface class.
   bool isSuperClassOf(const ObjCInterfaceDecl *I) const {
     // If RHS is derived from LHS it is OK; else it is not OK.
-    while (I != NULL) {
+    while (I != nullptr) {
       if (declaresSameEntity(this, I))
         return true;
       
@@ -1141,15 +1285,18 @@
   // Lookup a method. First, we search locally. If a method isn't
   // found, we search referenced protocols and class categories.
   ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance,
-                               bool shallowCategoryLookup= false,
-                               const ObjCCategoryDecl *C= 0) const;
-  ObjCMethodDecl *lookupInstanceMethod(Selector Sel,
-                            bool shallowCategoryLookup = false) const {
-    return lookupMethod(Sel, true/*isInstance*/, shallowCategoryLookup);
+                               bool shallowCategoryLookup = false,
+                               bool followSuper = true,
+                               const ObjCCategoryDecl *C = nullptr) const;
+
+  /// Lookup an instance method for a given selector.
+  ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const {
+    return lookupMethod(Sel, true/*isInstance*/);
   }
-  ObjCMethodDecl *lookupClassMethod(Selector Sel,
-                     bool shallowCategoryLookup = false) const {
-    return lookupMethod(Sel, false/*isInstance*/, shallowCategoryLookup);
+
+  /// Lookup a class method for a given selector.
+  ObjCMethodDecl *lookupClassMethod(Selector Sel) const {
+    return lookupMethod(Sel, false/*isInstance*/);
   }
   ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName);
 
@@ -1167,7 +1314,9 @@
   ObjCMethodDecl *lookupPropertyAccessor(const Selector Sel,
                                          const ObjCCategoryDecl *Cat) const {
     return lookupMethod(Sel, true/*isInstance*/,
-                        false/*shallowCategoryLookup*/, Cat);
+                        false/*shallowCategoryLookup*/,
+                        true /* followsSuper */,
+                        Cat);
   }
                           
   SourceLocation getEndOfDefinitionLoc() const { 
@@ -1196,15 +1345,17 @@
                                bool lookupCategory,
                                bool RHSIsQualifiedID = false);
 
+  typedef redeclarable_base::redecl_range redecl_range;
   typedef redeclarable_base::redecl_iterator redecl_iterator;
   using redeclarable_base::redecls_begin;
   using redeclarable_base::redecls_end;
+  using redeclarable_base::redecls;
   using redeclarable_base::getPreviousDecl;
   using redeclarable_base::getMostRecentDecl;
   using redeclarable_base::isFirstDecl;
 
   /// Retrieves the canonical declaration of this Objective-C class.
-  ObjCInterfaceDecl *getCanonicalDecl() { return getFirstDecl(); }
+  ObjCInterfaceDecl *getCanonicalDecl() override { return getFirstDecl(); }
   const ObjCInterfaceDecl *getCanonicalDecl() const { return getFirstDecl(); }
 
   // Low-level accessor
@@ -1217,6 +1368,10 @@
   friend class ASTReader;
   friend class ASTDeclReader;
   friend class ASTDeclWriter;
+
+private:
+  const ObjCInterfaceDecl *findInterfaceWithDesignatedInitializers() const;
+  bool inheritsDesignatedInitializers() const;
 };
 
 /// ObjCIvarDecl - Represents an ObjC instance variable. In general, ObjC
@@ -1235,7 +1390,7 @@
 ///   }
 ///
 class ObjCIvarDecl : public FieldDecl {
-  virtual void anchor();
+  void anchor() override;
 
 public:
   enum AccessControl {
@@ -1246,21 +1401,18 @@
   ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation StartLoc,
                SourceLocation IdLoc, IdentifierInfo *Id,
                QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW,
-               bool synthesized,
-               bool backingIvarReferencedInAccessor)
+               bool synthesized)
     : FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW,
                 /*Mutable=*/false, /*HasInit=*/ICIS_NoInit),
-      NextIvar(0), DeclAccess(ac), Synthesized(synthesized),
-      BackingIvarReferencedInAccessor(backingIvarReferencedInAccessor) {}
+      NextIvar(nullptr), DeclAccess(ac), Synthesized(synthesized) {}
 
 public:
   static ObjCIvarDecl *Create(ASTContext &C, ObjCContainerDecl *DC,
                               SourceLocation StartLoc, SourceLocation IdLoc,
                               IdentifierInfo *Id, QualType T,
                               TypeSourceInfo *TInfo,
-                              AccessControl ac, Expr *BW = NULL,
-                              bool synthesized=false,
-                              bool backingIvarReferencedInAccessor=false);
+                              AccessControl ac, Expr *BW = nullptr,
+                              bool synthesized=false);
 
   static ObjCIvarDecl *CreateDeserialized(ASTContext &C, unsigned ID);
   
@@ -1282,13 +1434,6 @@
     return DeclAccess == None ? Protected : AccessControl(DeclAccess);
   }
 
-  void setBackingIvarReferencedInAccessor(bool val) {
-    BackingIvarReferencedInAccessor = val;
-  }
-  bool getBackingIvarReferencedInAccessor() const {
-    return BackingIvarReferencedInAccessor;
-  }
-  
   void setSynthesize(bool synth) { Synthesized = synth; }
   bool getSynthesize() const { return Synthesized; }
 
@@ -1303,18 +1448,17 @@
   // NOTE: VC++ treats enums as signed, avoid using the AccessControl enum
   unsigned DeclAccess : 3;
   unsigned Synthesized : 1;
-  unsigned BackingIvarReferencedInAccessor : 1;
 };
 
 
 /// \brief Represents a field declaration created by an \@defs(...).
 class ObjCAtDefsFieldDecl : public FieldDecl {
-  virtual void anchor();
+  void anchor() override;
   ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation StartLoc,
                       SourceLocation IdLoc, IdentifierInfo *Id,
                       QualType T, Expr *BW)
     : FieldDecl(ObjCAtDefsField, DC, StartLoc, IdLoc, Id, T,
-                /*TInfo=*/0, // FIXME: Do ObjCAtDefs have declarators ?
+                /*TInfo=*/nullptr, // FIXME: Do ObjCAtDefs have declarators ?
                 BW, /*Mutable=*/false, /*HasInit=*/ICIS_NoInit) {}
 
 public:
@@ -1362,7 +1506,7 @@
 ///
 class ObjCProtocolDecl : public ObjCContainerDecl,
                          public Redeclarable<ObjCProtocolDecl> {
-  virtual void anchor();
+  void anchor() override;
 
   struct DefinitionData {
     // \brief The declaration that defines this protocol.
@@ -1384,20 +1528,20 @@
     return *Data.getPointer();
   }
   
-  ObjCProtocolDecl(DeclContext *DC, IdentifierInfo *Id,
+  ObjCProtocolDecl(ASTContext &C, DeclContext *DC, IdentifierInfo *Id,
                    SourceLocation nameLoc, SourceLocation atStartLoc,
                    ObjCProtocolDecl *PrevDecl);
 
   void allocateDefinitionData();
 
   typedef Redeclarable<ObjCProtocolDecl> redeclarable_base;
-  virtual ObjCProtocolDecl *getNextRedeclaration() { 
-    return RedeclLink.getNext(); 
+  ObjCProtocolDecl *getNextRedeclarationImpl() override {
+    return getNextRedeclaration();
   }
-  virtual ObjCProtocolDecl *getPreviousDeclImpl() {
+  ObjCProtocolDecl *getPreviousDeclImpl() override {
     return getPreviousDecl();
   }
-  virtual ObjCProtocolDecl *getMostRecentDeclImpl() {
+  ObjCProtocolDecl *getMostRecentDeclImpl() override {
     return getMostRecentDecl();
   }
 
@@ -1409,12 +1553,17 @@
                                   ObjCProtocolDecl *PrevDecl);
 
   static ObjCProtocolDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-                           
+
   const ObjCProtocolList &getReferencedProtocols() const {
     assert(hasDefinition() && "No definition available!");
     return data().ReferencedProtocols;
   }
   typedef ObjCProtocolList::iterator protocol_iterator;
+  typedef llvm::iterator_range<protocol_iterator> protocol_range;
+
+  protocol_range protocols() const {
+    return protocol_range(protocol_begin(), protocol_end());
+  }
   protocol_iterator protocol_begin() const {
     if (!hasDefinition())
       return protocol_iterator();
@@ -1428,6 +1577,11 @@
     return data().ReferencedProtocols.end(); 
   }
   typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
+  typedef llvm::iterator_range<protocol_loc_iterator> protocol_loc_range;
+
+  protocol_loc_range protocol_locs() const {
+    return protocol_loc_range(protocol_loc_begin(), protocol_loc_end());
+  }
   protocol_loc_iterator protocol_loc_begin() const {
     if (!hasDefinition())
       return protocol_loc_iterator();
@@ -1486,12 +1640,12 @@
 
   /// \brief Retrieve the definition of this protocol, if any.
   ObjCProtocolDecl *getDefinition() {
-    return hasDefinition()? Data.getPointer()->Definition : 0;
+    return hasDefinition()? Data.getPointer()->Definition : nullptr;
   }
 
   /// \brief Retrieve the definition of this protocol, if any.
   const ObjCProtocolDecl *getDefinition() const {
-    return hasDefinition()? Data.getPointer()->Definition : 0;
+    return hasDefinition()? Data.getPointer()->Definition : nullptr;
   }
 
   /// \brief Determine whether this particular declaration is also the 
@@ -1503,29 +1657,35 @@
   /// \brief Starts the definition of this Objective-C protocol.
   void startDefinition();
 
-  virtual SourceRange getSourceRange() const LLVM_READONLY {
+  /// Produce a name to be used for protocol's metadata. It comes either via
+  /// objc_runtime_name attribute or protocol name.
+  StringRef getObjCRuntimeNameAsString() const;
+
+  SourceRange getSourceRange() const override LLVM_READONLY {
     if (isThisDeclarationADefinition())
       return ObjCContainerDecl::getSourceRange();
    
     return SourceRange(getAtStartLoc(), getLocation());
   }
    
+  typedef redeclarable_base::redecl_range redecl_range;
   typedef redeclarable_base::redecl_iterator redecl_iterator;
   using redeclarable_base::redecls_begin;
   using redeclarable_base::redecls_end;
+  using redeclarable_base::redecls;
   using redeclarable_base::getPreviousDecl;
   using redeclarable_base::getMostRecentDecl;
   using redeclarable_base::isFirstDecl;
 
   /// Retrieves the canonical declaration of this Objective-C protocol.
-  ObjCProtocolDecl *getCanonicalDecl() { return getFirstDecl(); }
+  ObjCProtocolDecl *getCanonicalDecl() override { return getFirstDecl(); }
   const ObjCProtocolDecl *getCanonicalDecl() const { return getFirstDecl(); }
 
-  virtual void collectPropertiesToImplement(PropertyMap &PM,
-                                            PropertyDeclOrder &PO) const;
-                           
-void collectInheritedProtocolProperties(const ObjCPropertyDecl *Property,
-                                        ProtocolPropertyMap &PM) const;
+  void collectPropertiesToImplement(PropertyMap &PM,
+                                    PropertyDeclOrder &PO) const override;
+
+  void collectInheritedProtocolProperties(const ObjCPropertyDecl *Property,
+                                          ProtocolPropertyMap &PM) const;
 
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
   static bool classofKind(Kind K) { return K == ObjCProtocol; }
@@ -1553,7 +1713,7 @@
 /// don't support this level of dynamism, which is both powerful and dangerous.
 ///
 class ObjCCategoryDecl : public ObjCContainerDecl {
-  virtual void anchor();
+  void anchor() override;
 
   /// Interface belonging to this category
   ObjCInterfaceDecl *ClassInterface;
@@ -1578,7 +1738,7 @@
                    SourceLocation IvarLBraceLoc=SourceLocation(),
                    SourceLocation IvarRBraceLoc=SourceLocation())
     : ObjCContainerDecl(ObjCCategory, DC, Id, ClassNameLoc, AtLoc),
-      ClassInterface(IDecl), NextClassCategory(0),
+      ClassInterface(IDecl), NextClassCategory(nullptr),
       CategoryNameLoc(CategoryNameLoc),
       IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc) {
   }
@@ -1613,10 +1773,22 @@
   }
 
   typedef ObjCProtocolList::iterator protocol_iterator;
-  protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();}
+  typedef llvm::iterator_range<protocol_iterator> protocol_range;
+
+  protocol_range protocols() const {
+    return protocol_range(protocol_begin(), protocol_end());
+  }
+  protocol_iterator protocol_begin() const {
+    return ReferencedProtocols.begin();
+  }
   protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
   unsigned protocol_size() const { return ReferencedProtocols.size(); }
   typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
+  typedef llvm::iterator_range<protocol_loc_iterator> protocol_loc_range;
+
+  protocol_loc_range protocol_locs() const {
+    return protocol_loc_range(protocol_loc_begin(), protocol_loc_end());
+  }
   protocol_loc_iterator protocol_loc_begin() const {
     return ReferencedProtocols.loc_begin();
   }
@@ -1632,9 +1804,12 @@
     return NextClassCategory;
   }
 
-  bool IsClassExtension() const { return getIdentifier() == 0; }
+  bool IsClassExtension() const { return getIdentifier() == nullptr; }
 
   typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
+  typedef llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>> ivar_range;
+
+  ivar_range ivars() const { return ivar_range(ivar_begin(), ivar_end()); }
   ivar_iterator ivar_begin() const {
     return ivar_iterator(decls_begin());
   }
@@ -1664,7 +1839,7 @@
 };
 
 class ObjCImplDecl : public ObjCContainerDecl {
-  virtual void anchor();
+  void anchor() override;
 
   /// Class interface for this class/category implementation
   ObjCInterfaceDecl *ClassInterface;
@@ -1674,7 +1849,8 @@
                ObjCInterfaceDecl *classInterface,
                SourceLocation nameLoc, SourceLocation atStartLoc)
     : ObjCContainerDecl(DK, DC,
-                        classInterface? classInterface->getIdentifier() : 0,
+                        classInterface? classInterface->getIdentifier()
+                                      : nullptr,
                         nameLoc, atStartLoc),
       ClassInterface(classInterface) {}
 
@@ -1701,6 +1877,12 @@
 
   // Iterator access to properties.
   typedef specific_decl_iterator<ObjCPropertyImplDecl> propimpl_iterator;
+  typedef llvm::iterator_range<specific_decl_iterator<ObjCPropertyImplDecl>>
+    propimpl_range;
+
+  propimpl_range property_impls() const {
+    return propimpl_range(propimpl_begin(), propimpl_end());
+  }
   propimpl_iterator propimpl_begin() const {
     return propimpl_iterator(decls_begin());
   }
@@ -1728,7 +1910,7 @@
 ///
 /// ObjCCategoryImplDecl
 class ObjCCategoryImplDecl : public ObjCImplDecl {
-  virtual void anchor();
+  void anchor() override;
 
   // Category name
   IdentifierInfo *Id;
@@ -1753,8 +1935,8 @@
 
   /// getIdentifier - Get the identifier that names the category
   /// interface associated with this implementation.
-  /// FIXME: This is a bad API, we are overriding the NamedDecl::getIdentifier()
-  /// to mean something different. For example:
+  /// FIXME: This is a bad API, we are hiding NamedDecl::getIdentifier()
+  /// with a different meaning. For example:
   /// ((NamedDecl *)SomeCategoryImplDecl)->getIdentifier()
   /// returns the class interface name, whereas
   /// ((ObjCCategoryImplDecl *)SomeCategoryImplDecl)->getIdentifier()
@@ -1771,11 +1953,9 @@
   /// getName - Get the name of identifier for the class interface associated
   /// with this implementation as a StringRef.
   //
-  // FIXME: This is a bad API, we are overriding the NamedDecl::getName, to mean
-  // something different.
-  StringRef getName() const {
-    return Id ? Id->getNameStart() : "";
-  }
+  // FIXME: This is a bad API, we are hiding NamedDecl::getName with a different
+  // meaning.
+  StringRef getName() const { return Id ? Id->getName() : StringRef(); }
 
   /// @brief Get the name of the class associated with this interface.
   //
@@ -1802,13 +1982,16 @@
 /// \@end
 /// @endcode
 ///
-/// Typically, instance variables are specified in the class interface,
-/// *not* in the implementation. Nevertheless (for legacy reasons), we
-/// allow instance variables to be specified in the implementation.  When
-/// specified, they need to be *identical* to the interface.
+/// In a non-fragile runtime, instance variables can appear in the class
+/// interface, class extensions (nameless categories), and in the implementation
+/// itself, as well as being synthesized as backing storage for properties.
 ///
+/// In a fragile runtime, instance variables are specified in the class
+/// interface, \em not in the implementation. Nevertheless (for legacy reasons),
+/// we allow instance variables to be specified in the implementation. When
+/// specified, they need to be \em identical to the interface.
 class ObjCImplementationDecl : public ObjCImplDecl {
-  virtual void anchor();
+  void anchor() override;
   /// Implementation Class's super class.
   ObjCInterfaceDecl *SuperClass;
   SourceLocation SuperLoc;
@@ -1839,7 +2022,7 @@
     : ObjCImplDecl(ObjCImplementation, DC, classInterface, nameLoc, atStartLoc),
        SuperClass(superDecl), SuperLoc(superLoc), IvarLBraceLoc(IvarLBraceLoc),
        IvarRBraceLoc(IvarRBraceLoc),
-       IvarInitializers(0), NumIvarInitializers(0),
+       IvarInitializers(nullptr), NumIvarInitializers(0),
        HasNonZeroConstructors(false), HasDestructors(false) {}
 public:
   static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC,
@@ -1859,6 +2042,14 @@
   /// init_const_iterator - Iterates through the ivar initializer list.
   typedef CXXCtorInitializer * const * init_const_iterator;
 
+  typedef llvm::iterator_range<init_iterator> init_range;
+  typedef llvm::iterator_range<init_const_iterator> init_const_range;
+
+  init_range inits() { return init_range(init_begin(), init_end()); }
+  init_const_range inits() const {
+    return init_const_range(init_begin(), init_end());
+  }
+
   /// init_begin() - Retrieve an iterator to the first initializer.
   init_iterator       init_begin()       { return IvarInitializers; }
   /// begin() - Retrieve an iterator to the first initializer.
@@ -1904,8 +2095,8 @@
   /// getName - Get the name of identifier for the class interface associated
   /// with this implementation as a StringRef.
   //
-  // FIXME: This is a bad API, we are overriding the NamedDecl::getName, to mean
-  // something different.
+  // FIXME: This is a bad API, we are hiding NamedDecl::getName with a different
+  // meaning.
   StringRef getName() const {
     assert(getIdentifier() && "Name is not a simple identifier");
     return getIdentifier()->getName();
@@ -1917,6 +2108,10 @@
   std::string getNameAsString() const {
     return getName();
   }
+    
+  /// Produce a name to be used for class's metadata. It comes either via
+  /// class's objc_runtime_name attribute or class name.
+  StringRef getObjCRuntimeNameAsString() const;
 
   const ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
   ObjCInterfaceDecl *getSuperClass() { return SuperClass; }
@@ -1930,6 +2125,9 @@
   SourceLocation getIvarRBraceLoc() const { return IvarRBraceLoc; }
   
   typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
+  typedef llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>> ivar_range;
+
+  ivar_range ivars() const { return ivar_range(ivar_begin(), ivar_end()); }
   ivar_iterator ivar_begin() const {
     return ivar_iterator(decls_begin());
   }
@@ -1955,7 +2153,7 @@
 /// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is
 /// declared as \@compatibility_alias alias class.
 class ObjCCompatibleAliasDecl : public NamedDecl {
-  virtual void anchor();
+  void anchor() override;
   /// Class that this is an alias of.
   ObjCInterfaceDecl *AliasedClass;
 
@@ -1986,7 +2184,7 @@
 /// \@property (assign, readwrite) int MyProperty;
 /// \endcode
 class ObjCPropertyDecl : public NamedDecl {
-  virtual void anchor();
+  void anchor() override;
 public:
   enum PropertyAttributeKind {
     OBJC_PR_noattr    = 0x00,
@@ -2038,7 +2236,9 @@
       PropertyImplementation(None),
       GetterName(Selector()),
       SetterName(Selector()),
-      GetterMethodDecl(0), SetterMethodDecl(0) , PropertyIvarDecl(0) {}
+      GetterMethodDecl(nullptr), SetterMethodDecl(nullptr),
+      PropertyIvarDecl(nullptr) {}
+
 public:
   static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC,
                                   SourceLocation L,
@@ -2145,7 +2345,7 @@
     return PropertyIvarDecl;
   }
 
-  virtual SourceRange getSourceRange() const LLVM_READONLY {
+  SourceRange getSourceRange() const override LLVM_READONLY {
     return SourceRange(AtLoc, getLocation());
   }
   
@@ -2202,7 +2402,7 @@
                        SourceLocation ivarLoc)
     : Decl(ObjCPropertyImpl, DC, L), AtLoc(atLoc),
       IvarLoc(ivarLoc), PropertyDecl(property), PropertyIvarDecl(ivarDecl),
-      GetterCXXConstructor(0), SetterCXXAssignment(0) {
+      GetterCXXConstructor(nullptr), SetterCXXAssignment(nullptr) {
     assert (PK == Dynamic || PropertyIvarDecl);
   }
 
@@ -2215,8 +2415,8 @@
                                       SourceLocation ivarLoc);
 
   static ObjCPropertyImplDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-  
-  virtual SourceRange getSourceRange() const LLVM_READONLY;
+
+  SourceRange getSourceRange() const override LLVM_READONLY;
 
   SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
   void setAtLoc(SourceLocation Loc) { AtLoc = Loc; }
diff --git a/include/clang/AST/DeclOpenMP.h b/include/clang/AST/DeclOpenMP.h
index 42fe907..1b329dc 100644
--- a/include/clang/AST/DeclOpenMP.h
+++ b/include/clang/AST/DeclOpenMP.h
@@ -47,10 +47,10 @@
                    NumVars);
   }
 
-  llvm::MutableArrayRef<Expr *> getVars() {
-    return llvm::MutableArrayRef<Expr *>(
-                                 reinterpret_cast<Expr **>(this + 1),
-                                 NumVars);
+  MutableArrayRef<Expr *> getVars() {
+    return MutableArrayRef<Expr *>(
+                           reinterpret_cast<Expr **>(this + 1),
+                           NumVars);
   }
 
   void setVars(ArrayRef<Expr *> VL);
@@ -62,11 +62,20 @@
   static OMPThreadPrivateDecl *CreateDeserialized(ASTContext &C,
                                                   unsigned ID, unsigned N);
 
-  typedef llvm::MutableArrayRef<Expr *>::iterator varlist_iterator;
+  typedef MutableArrayRef<Expr *>::iterator varlist_iterator;
   typedef ArrayRef<const Expr *>::iterator varlist_const_iterator;
+  typedef llvm::iterator_range<varlist_iterator> varlist_range;
+  typedef llvm::iterator_range<varlist_const_iterator> varlist_const_range;
 
   unsigned varlist_size() const { return NumVars; }
   bool varlist_empty() const { return NumVars == 0; }
+
+  varlist_range varlists() {
+    return varlist_range(varlist_begin(), varlist_end());
+  }
+  varlist_const_range varlists() const {
+    return varlist_const_range(varlist_begin(), varlist_end());
+  }
   varlist_iterator varlist_begin() { return getVars().begin(); }
   varlist_iterator varlist_end() { return getVars().end(); }
   varlist_const_iterator varlist_begin() const { return getVars().begin(); }
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index 24bd28a..980a06e 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -86,11 +86,11 @@
 
   unsigned size() const { return NumParams; }
 
-  llvm::ArrayRef<NamedDecl*> asArray() {
-    return llvm::ArrayRef<NamedDecl*>(begin(), size());
+  ArrayRef<NamedDecl*> asArray() {
+    return ArrayRef<NamedDecl*>(begin(), size());
   }
-  llvm::ArrayRef<const NamedDecl*> asArray() const {
-    return llvm::ArrayRef<const NamedDecl*>(begin(), size());
+  ArrayRef<const NamedDecl*> asArray() const {
+    return ArrayRef<const NamedDecl*>(begin(), size());
   }
 
   NamedDecl* getParam(unsigned Idx) {
@@ -203,8 +203,8 @@
   const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); }
 
   /// \brief Produce this as an array ref.
-  llvm::ArrayRef<TemplateArgument> asArray() const {
-    return llvm::ArrayRef<TemplateArgument>(data(), size());
+  ArrayRef<TemplateArgument> asArray() const {
+    return ArrayRef<TemplateArgument>(data(), size());
   }
 
   /// \brief Retrieve the number of template arguments in this
@@ -227,18 +227,20 @@
 /// The TemplateDecl class stores the list of template parameters and a
 /// reference to the templated scoped declaration: the underlying AST node.
 class TemplateDecl : public NamedDecl {
-  virtual void anchor();
+  void anchor() override;
 protected:
   // This is probably never used.
   TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
                DeclarationName Name)
-    : NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(0) { }
+    : NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr),
+      TemplateParams(nullptr) {}
 
   // Construct a template decl with the given name and parameters.
   // Used when there is not templated element (tt-params, alias?).
   TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
                DeclarationName Name, TemplateParameterList *Params)
-    : NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(Params) { }
+    : NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr),
+      TemplateParams(Params) {}
 
   // Construct a template decl with name, parameters, and templated element.
   TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
@@ -261,7 +263,7 @@
     return K >= firstTemplate && K <= lastTemplate;
   }
 
-  SourceRange getSourceRange() const LLVM_READONLY {
+  SourceRange getSourceRange() const override LLVM_READONLY {
     return SourceRange(TemplateParams->getTemplateLoc(),
                        TemplatedDecl->getSourceRange().getEnd());
   }
@@ -274,8 +276,8 @@
   /// \brief Initialize the underlying templated declaration and
   /// template parameters.
   void init(NamedDecl *templatedDecl, TemplateParameterList* templateParams) {
-    assert(TemplatedDecl == 0 && "TemplatedDecl already set!");
-    assert(TemplateParams == 0 && "TemplateParams already set!");
+    assert(!TemplatedDecl && "TemplatedDecl already set!");
+    assert(!TemplateParams && "TemplateParams already set!");
     TemplatedDecl = templatedDecl;
     TemplateParams = templateParams;
   }
@@ -378,16 +380,15 @@
   }
 
   void Profile(llvm::FoldingSetNodeID &ID) {
-    Profile(ID, TemplateArguments->data(),
-            TemplateArguments->size(),
+    Profile(ID, TemplateArguments->asArray(),
             Function->getASTContext());
   }
 
   static void
-  Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
-          unsigned NumTemplateArgs, ASTContext &Context) {
-    ID.AddInteger(NumTemplateArgs);
-    for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
+  Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
+          ASTContext &Context) {
+    ID.AddInteger(TemplateArgs.size());
+    for (unsigned Arg = 0; Arg != TemplateArgs.size(); ++Arg)
       TemplateArgs[Arg].Profile(ID, Context);
   }
 };
@@ -530,13 +531,13 @@
                                  public Redeclarable<RedeclarableTemplateDecl> 
 {
   typedef Redeclarable<RedeclarableTemplateDecl> redeclarable_base;
-  virtual RedeclarableTemplateDecl *getNextRedeclaration() {
-    return RedeclLink.getNext();
+  RedeclarableTemplateDecl *getNextRedeclarationImpl() override {
+    return getNextRedeclaration();
   }
-  virtual RedeclarableTemplateDecl *getPreviousDeclImpl() {
+  RedeclarableTemplateDecl *getPreviousDeclImpl() override {
     return getPreviousDecl();
   }
-  virtual RedeclarableTemplateDecl *getMostRecentDeclImpl() {
+  RedeclarableTemplateDecl *getMostRecentDeclImpl() override {
     return getMostRecentDecl();
   }
 
@@ -595,11 +596,10 @@
 
   template <class EntryType> typename SpecEntryTraits<EntryType>::DeclType*
   findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
-                         const TemplateArgument *Args, unsigned NumArgs,
-                         void *&InsertPos);
+                         ArrayRef<TemplateArgument> Args, void *&InsertPos);
 
   struct CommonBase {
-    CommonBase() : InstantiatedFromMember(0, false) { }
+    CommonBase() : InstantiatedFromMember(nullptr, false) { }
 
     /// \brief The template from which this was most
     /// directly instantiated (or null).
@@ -622,16 +622,19 @@
   virtual CommonBase *newCommon(ASTContext &C) const = 0;
 
   // Construct a template decl with name, parameters, and templated element.
-  RedeclarableTemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
-                           DeclarationName Name, TemplateParameterList *Params,
-                           NamedDecl *Decl)
-    : TemplateDecl(DK, DC, L, Name, Params, Decl), 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() {}
 
 public:
   template <class decl_type> friend class RedeclarableTemplate;
 
   /// \brief Retrieves the canonical declaration of this template.
-  RedeclarableTemplateDecl *getCanonicalDecl() { return getFirstDecl(); }
+  RedeclarableTemplateDecl *getCanonicalDecl() override {
+    return getFirstDecl();
+  }
   const RedeclarableTemplateDecl *getCanonicalDecl() const {
     return getFirstDecl();
   }
@@ -710,9 +713,11 @@
     getCommonPtr()->InstantiatedFromMember.setPointer(TD);
   }
 
+  typedef redeclarable_base::redecl_range redecl_range;
   typedef redeclarable_base::redecl_iterator redecl_iterator;
   using redeclarable_base::redecls_begin;
   using redeclarable_base::redecls_end;
+  using redeclarable_base::redecls;
   using redeclarable_base::getPreviousDecl;
   using redeclarable_base::getMostRecentDecl;
   using redeclarable_base::isFirstDecl;
@@ -769,11 +774,13 @@
     uint32_t *LazySpecializations;
   };
 
-  FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
-                       TemplateParameterList *Params, NamedDecl *Decl)
-    : RedeclarableTemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl) { }
+  FunctionTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
+                       DeclarationName Name, TemplateParameterList *Params,
+                       NamedDecl *Decl)
+      : RedeclarableTemplateDecl(FunctionTemplate, C, DC, L, Name, Params,
+                                 Decl) {}
 
-  CommonBase *newCommon(ASTContext &C) const;
+  CommonBase *newCommon(ASTContext &C) const override;
 
   Common *getCommonPtr() const {
     return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
@@ -810,10 +817,10 @@
 
   /// \brief Return the specialization with the provided arguments if it exists,
   /// otherwise return the insertion point.
-  FunctionDecl *findSpecialization(const TemplateArgument *Args,
-                                   unsigned NumArgs, void *&InsertPos);
+  FunctionDecl *findSpecialization(ArrayRef<TemplateArgument> Args,
+                                   void *&InsertPos);
 
-  FunctionTemplateDecl *getCanonicalDecl() {
+  FunctionTemplateDecl *getCanonicalDecl() override {
     return cast<FunctionTemplateDecl>(
              RedeclarableTemplateDecl::getCanonicalDecl());
   }
@@ -842,7 +849,11 @@
   }
 
   typedef SpecIterator<FunctionTemplateSpecializationInfo> spec_iterator;
+  typedef llvm::iterator_range<spec_iterator> spec_range;
 
+  spec_range specializations() const {
+    return spec_range(spec_begin(), spec_end());
+  }
   spec_iterator spec_begin() const {
     return makeSpecIterator(getSpecializations(), false);
   }
@@ -892,12 +903,9 @@
 /// This class is inheritedly privately by different kinds of template
 /// parameters and is not part of the Decl hierarchy. Just a facility.
 class TemplateParmPosition {
-protected:
-  // FIXME: This should probably never be called, but it's here as
-  TemplateParmPosition()
-    : Depth(0), Position(0)
-  { /* llvm_unreachable("Cannot create positionless template parameter"); */ }
+  TemplateParmPosition() LLVM_DELETED_FUNCTION;
 
+protected:
   TemplateParmPosition(unsigned D, unsigned P)
     : Depth(D), Position(P)
   { }
@@ -967,7 +975,7 @@
 
   /// \brief Determine whether this template parameter has a default
   /// argument.
-  bool hasDefaultArgument() const { return DefaultArgument != 0; }
+  bool hasDefaultArgument() const { return DefaultArgument != nullptr; }
 
   /// \brief Retrieve the default argument, if any.
   QualType getDefaultArgument() const { return DefaultArgument->getType(); }
@@ -992,7 +1000,7 @@
 
   /// \brief Removes the default argument of this template parameter.
   void removeDefaultArgument() {
-    DefaultArgument = 0;
+    DefaultArgument = nullptr;
     InheritedDefault = false;
   }
 
@@ -1009,7 +1017,7 @@
   /// \brief Returns whether this is a parameter pack.
   bool isParameterPack() const;
 
-  SourceRange getSourceRange() const LLVM_READONLY;
+  SourceRange getSourceRange() const override LLVM_READONLY;
 
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -1046,7 +1054,7 @@
                           IdentifierInfo *Id, QualType T,
                           bool ParameterPack, TypeSourceInfo *TInfo)
     : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
-      TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false),
+      TemplateParmPosition(D, P), DefaultArgumentAndInherited(nullptr, false),
       ParameterPack(ParameterPack), ExpandedParameterPack(false),
       NumExpandedTypes(0)
   { }
@@ -1086,12 +1094,12 @@
   using TemplateParmPosition::setPosition;
   using TemplateParmPosition::getIndex;
 
-  SourceRange getSourceRange() const LLVM_READONLY;
+  SourceRange getSourceRange() const override LLVM_READONLY;
 
   /// \brief Determine whether this template parameter has a default
   /// argument.
   bool hasDefaultArgument() const {
-    return DefaultArgumentAndInherited.getPointer() != 0;
+    return DefaultArgumentAndInherited.getPointer() != nullptr;
   }
 
   /// \brief Retrieve the default argument, if any.
@@ -1118,7 +1126,7 @@
 
   /// \brief Removes the default argument of this template parameter.
   void removeDefaultArgument() {
-    DefaultArgumentAndInherited.setPointer(0);
+    DefaultArgumentAndInherited.setPointer(nullptr);
     DefaultArgumentAndInherited.setInt(false);
   }
 
@@ -1206,7 +1214,7 @@
 class TemplateTemplateParmDecl : public TemplateDecl, 
                                  protected TemplateParmPosition 
 {
-  virtual void anchor();
+  void anchor() override;
 
   /// DefaultArgument - The default template argument, if any.
   TemplateArgumentLoc DefaultArgument;
@@ -1347,7 +1355,7 @@
     DefaultArgumentWasInherited = false;
   }
 
-  SourceRange getSourceRange() const LLVM_READONLY {
+  SourceRange getSourceRange() const override LLVM_READONLY {
     SourceLocation End = getLocation();
     if (hasDefaultArgument() && !defaultArgumentWasInherited())
       End = getDefaultArgument().getSourceRange().getEnd();
@@ -1405,7 +1413,7 @@
     SourceLocation TemplateKeywordLoc;
 
     ExplicitSpecializationInfo()
-      : TypeAsWritten(0), ExternLoc(), TemplateKeywordLoc() {}
+      : TypeAsWritten(nullptr), ExternLoc(), TemplateKeywordLoc() {}
   };
 
   /// \brief Further info for explicit template specialization/instantiation.
@@ -1431,7 +1439,7 @@
                                   unsigned NumArgs,
                                   ClassTemplateSpecializationDecl *PrevDecl);
 
-  explicit ClassTemplateSpecializationDecl(Kind DK);
+  explicit ClassTemplateSpecializationDecl(ASTContext &C, Kind DK);
 
 public:
   static ClassTemplateSpecializationDecl *
@@ -1444,10 +1452,14 @@
   static ClassTemplateSpecializationDecl *
   CreateDeserialized(ASTContext &C, unsigned ID);
 
-  virtual void getNameForDiagnostic(raw_ostream &OS,
-                                    const PrintingPolicy &Policy,
-                                    bool Qualified) const;
+  void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
+                            bool Qualified) const override;
 
+  // FIXME: This is broken. CXXRecordDecl::getMostRecentDecl() returns a
+  // different "most recent" declaration from this function for the same
+  // declaration, because we don't override getMostRecentDeclImpl(). But
+  // it's not clear that we should override that, because the most recent
+  // declaration as a CXXRecordDecl sometimes is the injected-class-name.
   ClassTemplateSpecializationDecl *getMostRecentDecl() {
     CXXRecordDecl *Recent = static_cast<CXXRecordDecl *>(
                               this)->getMostRecentDecl();
@@ -1516,17 +1528,11 @@
   llvm::PointerUnion<ClassTemplateDecl *,
                      ClassTemplatePartialSpecializationDecl *>
   getInstantiatedFrom() const {
-    if (getSpecializationKind() != TSK_ImplicitInstantiation &&
-        getSpecializationKind() != TSK_ExplicitInstantiationDefinition &&
-        getSpecializationKind() != TSK_ExplicitInstantiationDeclaration)
+    if (!isTemplateInstantiation(getSpecializationKind()))
       return llvm::PointerUnion<ClassTemplateDecl *,
                                 ClassTemplatePartialSpecializationDecl *>();
 
-    if (SpecializedPartialSpecialization *PartialSpec
-          = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
-      return PartialSpec->PartialSpecialization;
-
-    return SpecializedTemplate.get<ClassTemplateDecl*>();
+    return getSpecializedTemplateOrPartial();
   }
 
   /// \brief Retrieve the class template or class template partial
@@ -1592,7 +1598,7 @@
   /// \brief Gets the type of this specialization as it was written by
   /// the user, if it was so written.
   TypeSourceInfo *getTypeAsWritten() const {
-    return ExplicitInfo ? ExplicitInfo->TypeAsWritten : 0;
+    return ExplicitInfo ? ExplicitInfo->TypeAsWritten : nullptr;
   }
 
   /// \brief Gets the location of the extern keyword, if present.
@@ -1617,17 +1623,17 @@
     return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
   }
 
-  SourceRange getSourceRange() const LLVM_READONLY;
+  SourceRange getSourceRange() const override LLVM_READONLY;
 
   void Profile(llvm::FoldingSetNodeID &ID) const {
-    Profile(ID, TemplateArgs->data(), TemplateArgs->size(), getASTContext());
+    Profile(ID, TemplateArgs->asArray(), getASTContext());
   }
 
   static void
-  Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
-          unsigned NumTemplateArgs, ASTContext &Context) {
-    ID.AddInteger(NumTemplateArgs);
-    for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
+  Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
+          ASTContext &Context) {
+    ID.AddInteger(TemplateArgs.size());
+    for (unsigned Arg = 0; Arg != TemplateArgs.size(); ++Arg)
       TemplateArgs[Arg].Profile(ID, Context);
   }
 
@@ -1643,7 +1649,7 @@
 
 class ClassTemplatePartialSpecializationDecl
   : public ClassTemplateSpecializationDecl {
-  virtual void anchor();
+  void anchor() override;
 
   /// \brief The list of template parameters
   TemplateParameterList* TemplateParams;
@@ -1671,9 +1677,10 @@
                                const ASTTemplateArgumentListInfo *ArgsAsWritten,
                                ClassTemplatePartialSpecializationDecl *PrevDecl);
 
-  ClassTemplatePartialSpecializationDecl()
-    : ClassTemplateSpecializationDecl(ClassTemplatePartialSpecialization),
-      TemplateParams(0), ArgsAsWritten(0), InstantiatedFromMember(0, false) { }
+  ClassTemplatePartialSpecializationDecl(ASTContext &C)
+    : ClassTemplateSpecializationDecl(C, ClassTemplatePartialSpecialization),
+      TemplateParams(nullptr), ArgsAsWritten(nullptr),
+      InstantiatedFromMember(nullptr, false) {}
 
 public:
   static ClassTemplatePartialSpecializationDecl *
@@ -1832,15 +1839,12 @@
   llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
   getPartialSpecializations();
 
-  ClassTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
-                    TemplateParameterList *Params, NamedDecl *Decl)
-    : RedeclarableTemplateDecl(ClassTemplate, 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(EmptyShell Empty)
-    : RedeclarableTemplateDecl(ClassTemplate, 0, SourceLocation(),
-                               DeclarationName(), 0, 0) { }
-
-  CommonBase *newCommon(ASTContext &C) const;
+  CommonBase *newCommon(ASTContext &C) const override;
 
   Common *getCommonPtr() const {
     return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
@@ -1872,14 +1876,13 @@
   /// \brief Return the specialization with the provided arguments if it exists,
   /// otherwise return the insertion point.
   ClassTemplateSpecializationDecl *
-  findSpecialization(const TemplateArgument *Args, unsigned NumArgs,
-                     void *&InsertPos);
+  findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
 
   /// \brief Insert the specified specialization knowing that it is not already
   /// in. InsertPos must be obtained from findSpecialization.
   void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos);
 
-  ClassTemplateDecl *getCanonicalDecl() {
+  ClassTemplateDecl *getCanonicalDecl() override {
     return cast<ClassTemplateDecl>(
              RedeclarableTemplateDecl::getCanonicalDecl());
   }
@@ -1919,8 +1922,7 @@
   /// \brief Return the partial specialization with the provided arguments if it
   /// exists, otherwise return the insertion point.
   ClassTemplatePartialSpecializationDecl *
-  findPartialSpecialization(const TemplateArgument *Args, unsigned NumArgs,
-                            void *&InsertPos);
+  findPartialSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
 
   /// \brief Insert the specified partial specialization knowing that it is not
   /// already in. InsertPos must be obtained from findPartialSpecialization.
@@ -1970,6 +1972,11 @@
   QualType getInjectedClassNameSpecialization();
 
   typedef SpecIterator<ClassTemplateSpecializationDecl> spec_iterator;
+  typedef llvm::iterator_range<spec_iterator> spec_range;
+
+  spec_range specializations() const {
+    return spec_range(spec_begin(), spec_end());
+  }
 
   spec_iterator spec_begin() const {
     return makeSpecIterator(getSpecializations(), false);
@@ -1979,17 +1986,6 @@
     return makeSpecIterator(getSpecializations(), true);
   }
 
-  typedef SpecIterator<ClassTemplatePartialSpecializationDecl>
-          partial_spec_iterator;
-
-  partial_spec_iterator partial_spec_begin() {
-    return makeSpecIterator(getPartialSpecializations(), false);
-  }
-
-  partial_spec_iterator partial_spec_end() {
-    return makeSpecIterator(getPartialSpecializations(), true);
-  }
-
   // Implement isa/cast/dyncast support
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
   static bool classofKind(Kind K) { return K == ClassTemplate; }
@@ -2045,7 +2041,7 @@
   FriendTemplateDecl(EmptyShell Empty)
     : Decl(Decl::FriendTemplate, Empty),
       NumParams(0),
-      Params(0)
+      Params(nullptr)
   {}
 
 public:
@@ -2105,11 +2101,13 @@
 protected:
   typedef CommonBase Common;
 
-  TypeAliasTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
-                        TemplateParameterList *Params, NamedDecl *Decl)
-    : RedeclarableTemplateDecl(TypeAliasTemplate, DC, L, Name, Params, Decl) { }
+  TypeAliasTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
+                        DeclarationName Name, TemplateParameterList *Params,
+                        NamedDecl *Decl)
+      : RedeclarableTemplateDecl(TypeAliasTemplate, C, DC, L, Name, Params,
+                                 Decl) {}
 
-  CommonBase *newCommon(ASTContext &C) const;
+  CommonBase *newCommon(ASTContext &C) const override;
 
   Common *getCommonPtr() {
     return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
@@ -2122,7 +2120,7 @@
   }
 
 
-  TypeAliasTemplateDecl *getCanonicalDecl() {
+  TypeAliasTemplateDecl *getCanonicalDecl() override {
     return cast<TypeAliasTemplateDecl>(
              RedeclarableTemplateDecl::getCanonicalDecl());
   }
@@ -2172,7 +2170,7 @@
 
 /// \brief Declaration of a function specialization at template class scope.
 ///
-/// This is a non standard extension needed to support MSVC.
+/// This is a non-standard extension needed to support MSVC.
 ///
 /// For example:
 /// \code
@@ -2214,9 +2212,8 @@
                                                       CXXMethodDecl *FD,
                                                    bool HasExplicitTemplateArgs,
                                         TemplateArgumentListInfo TemplateArgs) {
-    return new (C) ClassScopeFunctionSpecializationDecl(DC , Loc, FD,
-                                                        HasExplicitTemplateArgs,
-                                                        TemplateArgs);
+    return new (C, DC) ClassScopeFunctionSpecializationDecl(
+        DC, Loc, FD, HasExplicitTemplateArgs, TemplateArgs);
   }
 
   static ClassScopeFunctionSpecializationDecl *
@@ -2279,7 +2276,7 @@
     SourceLocation TemplateKeywordLoc;
 
     ExplicitSpecializationInfo()
-        : TypeAsWritten(0), ExternLoc(), TemplateKeywordLoc() {}
+        : TypeAsWritten(nullptr), ExternLoc(), TemplateKeywordLoc() {}
   };
 
   /// \brief Further info for explicit template specialization/instantiation.
@@ -2298,14 +2295,14 @@
   unsigned SpecializationKind : 3;
 
 protected:
-  VarTemplateSpecializationDecl(ASTContext &Context, Kind DK, DeclContext *DC,
+  VarTemplateSpecializationDecl(Kind DK, ASTContext &Context, DeclContext *DC,
                                 SourceLocation StartLoc, SourceLocation IdLoc,
                                 VarTemplateDecl *SpecializedTemplate,
                                 QualType T, TypeSourceInfo *TInfo,
                                 StorageClass S, const TemplateArgument *Args,
                                 unsigned NumArgs);
 
-  explicit VarTemplateSpecializationDecl(Kind DK);
+  explicit VarTemplateSpecializationDecl(Kind DK, ASTContext &Context);
 
 public:
   static VarTemplateSpecializationDecl *
@@ -2316,9 +2313,8 @@
   static VarTemplateSpecializationDecl *CreateDeserialized(ASTContext &C,
                                                            unsigned ID);
 
-  virtual void getNameForDiagnostic(raw_ostream &OS,
-                                    const PrintingPolicy &Policy,
-                                    bool Qualified) const;
+  void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
+                            bool Qualified) const override;
 
   VarTemplateSpecializationDecl *getMostRecentDecl() {
     VarDecl *Recent = static_cast<VarDecl *>(this)->getMostRecentDecl();
@@ -2461,7 +2457,7 @@
   /// \brief Gets the type of this specialization as it was written by
   /// the user, if it was so written.
   TypeSourceInfo *getTypeAsWritten() const {
-    return ExplicitInfo ? ExplicitInfo->TypeAsWritten : 0;
+    return ExplicitInfo ? ExplicitInfo->TypeAsWritten : nullptr;
   }
 
   /// \brief Gets the location of the extern keyword, if present.
@@ -2487,14 +2483,14 @@
   }
 
   void Profile(llvm::FoldingSetNodeID &ID) const {
-    Profile(ID, TemplateArgs->data(), TemplateArgs->size(), getASTContext());
+    Profile(ID, TemplateArgs->asArray(), getASTContext());
   }
 
   static void Profile(llvm::FoldingSetNodeID &ID,
-                      const TemplateArgument *TemplateArgs,
-                      unsigned NumTemplateArgs, ASTContext &Context) {
-    ID.AddInteger(NumTemplateArgs);
-    for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
+                      ArrayRef<TemplateArgument> TemplateArgs,
+                      ASTContext &Context) {
+    ID.AddInteger(TemplateArgs.size());
+    for (unsigned Arg = 0; Arg != TemplateArgs.size(); ++Arg)
       TemplateArgs[Arg].Profile(ID, Context);
   }
 
@@ -2510,7 +2506,7 @@
 
 class VarTemplatePartialSpecializationDecl
     : public VarTemplateSpecializationDecl {
-  virtual void anchor();
+  void anchor() override;
 
   /// \brief The list of template parameters
   TemplateParameterList *TemplateParams;
@@ -2534,9 +2530,10 @@
       StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
       const ASTTemplateArgumentListInfo *ArgInfos);
 
-  VarTemplatePartialSpecializationDecl()
-      : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization),
-        TemplateParams(0), ArgsAsWritten(0), InstantiatedFromMember(0, false) {}
+  VarTemplatePartialSpecializationDecl(ASTContext &Context)
+    : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context),
+      TemplateParams(nullptr), ArgsAsWritten(nullptr),
+      InstantiatedFromMember(nullptr, false) {}
 
 public:
   static VarTemplatePartialSpecializationDecl *
@@ -2677,15 +2674,12 @@
   llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
   getPartialSpecializations();
 
-  VarTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
-                  TemplateParameterList *Params, NamedDecl *Decl)
-      : RedeclarableTemplateDecl(VarTemplate, DC, L, Name, Params, Decl) {}
+  VarTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
+                  DeclarationName Name, TemplateParameterList *Params,
+                  NamedDecl *Decl)
+      : RedeclarableTemplateDecl(VarTemplate, C, DC, L, Name, Params, Decl) {}
 
-  VarTemplateDecl(EmptyShell Empty)
-      : RedeclarableTemplateDecl(VarTemplate, 0, SourceLocation(),
-                                 DeclarationName(), 0, 0) {}
-
-  CommonBase *newCommon(ASTContext &C) const;
+  CommonBase *newCommon(ASTContext &C) const override;
 
   Common *getCommonPtr() const {
     return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
@@ -2708,8 +2702,8 @@
   /// \brief Create a variable template node.
   static VarTemplateDecl *Create(ASTContext &C, DeclContext *DC,
                                  SourceLocation L, DeclarationName Name,
-                                 TemplateParameterList *Params, NamedDecl *Decl,
-                                 VarTemplateDecl *PrevDecl);
+                                 TemplateParameterList *Params,
+                                 VarDecl *Decl);
 
   /// \brief Create an empty variable template node.
   static VarTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
@@ -2717,14 +2711,13 @@
   /// \brief Return the specialization with the provided arguments if it exists,
   /// otherwise return the insertion point.
   VarTemplateSpecializationDecl *
-  findSpecialization(const TemplateArgument *Args, unsigned NumArgs,
-                     void *&InsertPos);
+  findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
 
   /// \brief Insert the specified specialization knowing that it is not already
   /// in. InsertPos must be obtained from findSpecialization.
   void AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos);
 
-  VarTemplateDecl *getCanonicalDecl() {
+  VarTemplateDecl *getCanonicalDecl() override {
     return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl());
   }
   const VarTemplateDecl *getCanonicalDecl() const {
@@ -2754,8 +2747,7 @@
   /// \brief Return the partial specialization with the provided arguments if it
   /// exists, otherwise return the insertion point.
   VarTemplatePartialSpecializationDecl *
-  findPartialSpecialization(const TemplateArgument *Args, unsigned NumArgs,
-                            void *&InsertPos);
+  findPartialSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
 
   /// \brief Insert the specified partial specialization knowing that it is not
   /// already in. InsertPos must be obtained from findPartialSpecialization.
@@ -2780,6 +2772,11 @@
       VarTemplatePartialSpecializationDecl *D);
 
   typedef SpecIterator<VarTemplateSpecializationDecl> spec_iterator;
+  typedef llvm::iterator_range<spec_iterator> spec_range;
+
+  spec_range specializations() const {
+    return spec_range(spec_begin(), spec_end());
+  }
 
   spec_iterator spec_begin() const {
     return makeSpecIterator(getSpecializations(), false);
@@ -2789,17 +2786,6 @@
     return makeSpecIterator(getSpecializations(), true);
   }
 
-  typedef SpecIterator<VarTemplatePartialSpecializationDecl>
-  partial_spec_iterator;
-
-  partial_spec_iterator partial_spec_begin() {
-    return makeSpecIterator(getPartialSpecializations(), false);
-  }
-
-  partial_spec_iterator partial_spec_end() {
-    return makeSpecIterator(getPartialSpecializations(), true);
-  }
-
   // Implement isa/cast/dyncast support
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
   static bool classofKind(Kind K) { return K == VarTemplate; }
diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h
index 00766c2..3076b30 100644
--- a/include/clang/AST/DeclarationName.h
+++ b/include/clang/AST/DeclarationName.h
@@ -29,6 +29,7 @@
   class DeclarationNameExtra;
   class IdentifierInfo;
   class MultiKeywordSelector;
+  enum OverloadedOperatorKind : int;
   class QualType;
   class Type;
   class TypeSourceInfo;
@@ -116,20 +117,20 @@
     NameKind Kind = getNameKind();
     if (Kind >= CXXConstructorName && Kind <= CXXConversionFunctionName)
       return reinterpret_cast<CXXSpecialName *>(Ptr & ~PtrMask);
-    return 0;
+    return nullptr;
   }
 
   /// getAsCXXOperatorIdName
   CXXOperatorIdName *getAsCXXOperatorIdName() const {
     if (getNameKind() == CXXOperatorName)
       return reinterpret_cast<CXXOperatorIdName *>(Ptr & ~PtrMask);
-    return 0;
+    return nullptr;
   }
 
   CXXLiteralOperatorIdName *getAsCXXLiteralOperatorIdName() const {
     if (getNameKind() == CXXLiteralOperatorName)
       return reinterpret_cast<CXXLiteralOperatorIdName *>(Ptr & ~PtrMask);
-    return 0;
+    return nullptr;
   }
 
   // Construct a declaration name from the name of a C++ constructor,
@@ -221,7 +222,7 @@
   IdentifierInfo *getAsIdentifierInfo() const {
     if (isIdentifier())
       return reinterpret_cast<IdentifierInfo *>(Ptr);
-    return 0;
+    return nullptr;
   }
 
   /// getAsOpaqueInteger - Get the representation of this declaration
diff --git a/include/clang/AST/DependentDiagnostic.h b/include/clang/AST/DependentDiagnostic.h
index 004b45d..63047ec 100644
--- a/include/clang/AST/DependentDiagnostic.h
+++ b/include/clang/AST/DependentDiagnostic.h
@@ -123,7 +123,7 @@
 /// An iterator over the dependent diagnostics in a dependent context.
 class DeclContext::ddiag_iterator {
 public:
-  ddiag_iterator() : Ptr(0) {}
+  ddiag_iterator() : Ptr(nullptr) {}
   explicit ddiag_iterator(DependentDiagnostic *Ptr) : Ptr(Ptr) {}
 
   typedef DependentDiagnostic *value_type;
@@ -171,18 +171,16 @@
   DependentDiagnostic *Ptr;
 };
 
-inline DeclContext::ddiag_iterator DeclContext::ddiag_begin() const {
+inline DeclContext::ddiag_range DeclContext::ddiags() const {
   assert(isDependentContext()
          && "cannot iterate dependent diagnostics of non-dependent context");
   const DependentStoredDeclsMap *Map
     = static_cast<DependentStoredDeclsMap*>(getPrimaryContext()->getLookupPtr());
 
-  if (!Map) return ddiag_iterator();
-  return ddiag_iterator(Map->FirstDiagnostic);
-}
+  if (!Map)
+    return ddiag_range();
 
-inline DeclContext::ddiag_iterator DeclContext::ddiag_end() const {
-  return ddiag_iterator();
+  return ddiag_range(ddiag_iterator(Map->FirstDiagnostic), ddiag_iterator());
 }
 
 }
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index f2648b9..b4bb0b6 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -293,8 +293,8 @@
   /// \param Loc [in,out] - A source location which *may* be filled
   /// in with the location of the expression making this a
   /// non-modifiable lvalue, if specified.
-  isModifiableLvalueResult isModifiableLvalue(ASTContext &Ctx,
-                                              SourceLocation *Loc = 0) const;
+  isModifiableLvalueResult
+  isModifiableLvalue(ASTContext &Ctx, SourceLocation *Loc = nullptr) const;
 
   /// \brief The return type of classify(). Represents the C++11 expression
   ///        taxonomy.
@@ -372,7 +372,7 @@
   /// lvalues and xvalues are collectively referred to as glvalues, while
   /// prvalues and xvalues together form rvalues.
   Classification Classify(ASTContext &Ctx) const {
-    return ClassifyImpl(Ctx, 0);
+    return ClassifyImpl(Ctx, nullptr);
   }
 
   /// \brief ClassifyModifiable - Classify this expression according to the
@@ -483,10 +483,10 @@
   /// Note: This does not perform the implicit conversions required by C++11
   /// [expr.const]p5.
   bool isIntegerConstantExpr(llvm::APSInt &Result, const ASTContext &Ctx,
-                             SourceLocation *Loc = 0,
+                             SourceLocation *Loc = nullptr,
                              bool isEvaluated = true) const;
   bool isIntegerConstantExpr(const ASTContext &Ctx,
-                             SourceLocation *Loc = 0) const;
+                             SourceLocation *Loc = nullptr) const;
 
   /// isCXX98IntegralConstantExpr - Return true if this expression is an
   /// integral constant expression in C++98. Can only be used in C++.
@@ -497,8 +497,8 @@
   ///
   /// Note: This does not perform the implicit conversions required by C++11
   /// [expr.const]p5.
-  bool isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result = 0,
-                           SourceLocation *Loc = 0) const;
+  bool isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result = nullptr,
+                           SourceLocation *Loc = nullptr) const;
 
   /// isPotentialConstantExpr - Return true if this function's definition
   /// might be usable in a constant expression in C++11, if it were marked
@@ -508,9 +508,22 @@
                                       SmallVectorImpl<
                                         PartialDiagnosticAt> &Diags);
 
+  /// isPotentialConstantExprUnevaluted - Return true if this expression might
+  /// be usable in a constant expression in C++11 in an unevaluated context, if
+  /// it were in function FD marked constexpr. Return false if the function can
+  /// never produce a constant expression, along with diagnostics describing
+  /// why not.
+  static bool isPotentialConstantExprUnevaluated(Expr *E,
+                                                 const FunctionDecl *FD,
+                                                 SmallVectorImpl<
+                                                   PartialDiagnosticAt> &Diags);
+
   /// isConstantInitializer - Returns true if this expression can be emitted to
   /// IR as a constant, and thus can be used as a constant initializer in C.
-  bool isConstantInitializer(ASTContext &Ctx, bool ForRef) const;
+  /// If this expression is not constant and Culprit is non-null,
+  /// it is used to store the address of first non constant expr.
+  bool isConstantInitializer(ASTContext &Ctx, bool ForRef,
+                             const Expr **Culprit = nullptr) const;
 
   /// EvalStatus is a struct with detailed info about an evaluation in progress.
   struct EvalStatus {
@@ -527,7 +540,7 @@
     /// expression *is* a constant expression, no notes will be produced.
     SmallVectorImpl<PartialDiagnosticAt> *Diag;
 
-    EvalStatus() : HasSideEffects(false), Diag(0) {}
+    EvalStatus() : HasSideEffects(false), Diag(nullptr) {}
 
     // hasSideEffects - Return true if the evaluated expression has
     // side effects.
@@ -584,7 +597,7 @@
   /// integer. This must be called on an expression that constant folds to an
   /// integer.
   llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx,
-                          SmallVectorImpl<PartialDiagnosticAt> *Diag=0) const;
+                    SmallVectorImpl<PartialDiagnosticAt> *Diag = nullptr) const;
 
   void EvaluateForOverflow(const ASTContext &Ctx) const;
 
@@ -600,6 +613,14 @@
                              const VarDecl *VD,
                              SmallVectorImpl<PartialDiagnosticAt> &Notes) const;
 
+  /// EvaluateWithSubstitution - Evaluate an expression as if from the context
+  /// of a call to the given function with the given arguments, inside an
+  /// unevaluated context. Returns true if the expression could be folded to a
+  /// constant.
+  bool EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx,
+                                const FunctionDecl *Callee,
+                                ArrayRef<const Expr*> Args) const;
+
   /// \brief Enumeration used to describe the kind of Null pointer constant
   /// returned from \c isNullPointerConstant().
   enum NullPointerConstantKind {
@@ -681,6 +702,9 @@
   /// or CastExprs, returning their operand.
   Expr *IgnoreParenCasts() LLVM_READONLY;
 
+  /// Ignore casts.  Strip off any CastExprs, returning their operand.
+  Expr *IgnoreCasts() LLVM_READONLY;
+
   /// IgnoreParenImpCasts - Ignore parentheses and implicit casts.  Strip off
   /// any ParenExpr or ImplicitCastExprs, returning their operand.
   Expr *IgnoreParenImpCasts() LLVM_READONLY;
@@ -742,6 +766,11 @@
   const Expr *IgnoreParenCasts() const LLVM_READONLY {
     return const_cast<Expr*>(this)->IgnoreParenCasts();
   }
+  /// Strip off casts, but keep parentheses.
+  const Expr *IgnoreCasts() const LLVM_READONLY {
+    return const_cast<Expr*>(this)->IgnoreCasts();
+  }
+
   const Expr *IgnoreParenNoopCasts(ASTContext &Ctx) const LLVM_READONLY {
     return const_cast<Expr*>(this)->IgnoreParenNoopCasts(Ctx);
   }
@@ -764,11 +793,6 @@
       SmallVectorImpl<const Expr *> &CommaLHS,
       SmallVectorImpl<SubobjectAdjustment> &Adjustments) const;
 
-  /// Skip irrelevant expressions to find what should be materialize for
-  /// binding with a reference.
-  const Expr *
-  findMaterializedTemporary(const MaterializeTemporaryExpr *&MTE) const;
-
   static bool classof(const Stmt *T) {
     return T->getStmtClass() >= firstExprConstant &&
            T->getStmtClass() <= lastExprConstant;
@@ -793,7 +817,7 @@
 public:
   OpaqueValueExpr(SourceLocation Loc, QualType T, ExprValueKind VK,
                   ExprObjectKind OK = OK_Ordinary,
-                  Expr *SourceExpr = 0)
+                  Expr *SourceExpr = nullptr)
     : Expr(OpaqueValueExprClass, T, VK, OK,
            T->isDependentType(), 
            T->isDependentType() || 
@@ -937,25 +961,19 @@
     computeDependence(D->getASTContext());
   }
 
-  static DeclRefExpr *Create(const ASTContext &Context,
-                             NestedNameSpecifierLoc QualifierLoc,
-                             SourceLocation TemplateKWLoc,
-                             ValueDecl *D,
-                             bool isEnclosingLocal,
-                             SourceLocation NameLoc,
-                             QualType T, ExprValueKind VK,
-                             NamedDecl *FoundD = 0,
-                             const TemplateArgumentListInfo *TemplateArgs = 0);
+  static DeclRefExpr *
+  Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc,
+         SourceLocation TemplateKWLoc, ValueDecl *D, bool isEnclosingLocal,
+         SourceLocation NameLoc, QualType T, ExprValueKind VK,
+         NamedDecl *FoundD = nullptr,
+         const TemplateArgumentListInfo *TemplateArgs = nullptr);
 
-  static DeclRefExpr *Create(const ASTContext &Context,
-                             NestedNameSpecifierLoc QualifierLoc,
-                             SourceLocation TemplateKWLoc,
-                             ValueDecl *D,
-                             bool isEnclosingLocal,
-                             const DeclarationNameInfo &NameInfo,
-                             QualType T, ExprValueKind VK,
-                             NamedDecl *FoundD = 0,
-                             const TemplateArgumentListInfo *TemplateArgs = 0);
+  static DeclRefExpr *
+  Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc,
+         SourceLocation TemplateKWLoc, ValueDecl *D, bool isEnclosingLocal,
+         const DeclarationNameInfo &NameInfo, QualType T, ExprValueKind VK,
+         NamedDecl *FoundD = nullptr,
+         const TemplateArgumentListInfo *TemplateArgs = nullptr);
 
   /// \brief Construct an empty declaration reference expression.
   static DeclRefExpr *CreateEmpty(const ASTContext &Context,
@@ -985,7 +1003,7 @@
   /// that precedes the name. Otherwise, returns NULL.
   NestedNameSpecifier *getQualifier() const {
     if (!hasQualifier())
-      return 0;
+      return nullptr;
 
     return getInternalQualifierLoc().getNestedNameSpecifier();
   }
@@ -1021,7 +1039,7 @@
   /// \brief Return the optional template keyword and arguments info.
   ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() {
     if (!hasTemplateKWAndArgsInfo())
-      return 0;
+      return nullptr;
 
     if (hasFoundDecl())
       return reinterpret_cast<ASTTemplateKWAndArgsInfo *>(
@@ -1085,7 +1103,7 @@
   /// This points to the same data as getExplicitTemplateArgs(), but
   /// returns null if there are no explicit template arguments.
   const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const {
-    if (!hasExplicitTemplateArgs()) return 0;
+    if (!hasExplicitTemplateArgs()) return nullptr;
     return &getExplicitTemplateArgs();
   }
 
@@ -1100,7 +1118,7 @@
   /// template-id.
   const TemplateArgumentLoc *getTemplateArgs() const {
     if (!hasExplicitTemplateArgs())
-      return 0;
+      return nullptr;
 
     return getExplicitTemplateArgs().getTemplateArgs();
   }
@@ -1151,6 +1169,7 @@
     Function,
     LFunction,  // Same as Function, but as wide string.
     FuncDName,
+    FuncSig,
     PrettyFunction,
     /// PrettyFunctionNoVirtual - The same as PrettyFunction, except that the
     /// 'virtual' keyword is omitted for virtual member functions.
@@ -1862,7 +1881,7 @@
 
   explicit OffsetOfExpr(unsigned numComps, unsigned numExprs)
     : Expr(OffsetOfExprClass, EmptyShell()),
-      TSInfo(0), NumComps(numComps), NumExprs(numExprs) {}
+      TSInfo(nullptr), NumComps(numComps), NumExprs(numExprs) {}
 
 public:
 
@@ -2213,6 +2232,13 @@
 
   typedef ExprIterator arg_iterator;
   typedef ConstExprIterator const_arg_iterator;
+  typedef llvm::iterator_range<arg_iterator> arg_range;
+  typedef llvm::iterator_range<const_arg_iterator> arg_const_range;
+
+  arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
+  arg_const_range arguments() const {
+    return arg_const_range(arg_begin(), arg_end());
+  }
 
   arg_iterator arg_begin() { return SubExprs+PREARGS_START+getNumPreArgs(); }
   arg_iterator arg_end() {
@@ -2238,9 +2264,9 @@
   /// this function call.
   unsigned getNumCommas() const { return NumArgs ? NumArgs - 1 : 0; }
 
-  /// isBuiltinCall - If this is a call to a builtin, return the builtin ID.  If
-  /// not, return 0.
-  unsigned isBuiltinCall() const;
+  /// getBuiltinCallee - If this is a call to a builtin, return the builtin ID
+  /// of the callee. If not, return 0.
+  unsigned getBuiltinCallee() const;
 
   /// \brief Returns \c true if this is a call to a builtin which does not
   /// evaluate side-effects within its arguments.
@@ -2392,14 +2418,14 @@
   /// \brief Determines whether this member expression actually had
   /// a C++ nested-name-specifier prior to the name of the member, e.g.,
   /// x->Base::foo.
-  bool hasQualifier() const { return getQualifier() != 0; }
+  bool hasQualifier() const { return getQualifier() != nullptr; }
 
   /// \brief If the member name was qualified, retrieves the
   /// nested-name-specifier that precedes the member name. Otherwise, returns
   /// NULL.
   NestedNameSpecifier *getQualifier() const {
     if (!HasQualifierOrFoundDecl)
-      return 0;
+      return nullptr;
 
     return getMemberQualifier()->QualifierLoc.getNestedNameSpecifier();
   }
@@ -2417,7 +2443,7 @@
   /// \brief Return the optional template keyword and arguments info.
   ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() {
     if (!HasTemplateKWAndArgsInfo)
-      return 0;
+      return nullptr;
 
     if (!HasQualifierOrFoundDecl)
       return reinterpret_cast<ASTTemplateKWAndArgsInfo *>(this + 1);
@@ -2485,7 +2511,7 @@
   /// This points to the same data as getExplicitTemplateArgs(), but
   /// returns null if there are no explicit template arguments.
   const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const {
-    if (!hasExplicitTemplateArgs()) return 0;
+    if (!hasExplicitTemplateArgs()) return nullptr;
     return &getExplicitTemplateArgs();
   }
 
@@ -2493,7 +2519,7 @@
   /// template-id.
   const TemplateArgumentLoc *getTemplateArgs() const {
     if (!hasExplicitTemplateArgs())
-      return 0;
+      return nullptr;
 
     return getExplicitTemplateArgs().getTemplateArgs();
   }
@@ -2633,7 +2659,7 @@
 private:
   Stmt *Op;
 
-  void CheckCastConsistency() const;
+  bool CastConsistency() const;
 
   const CXXBaseSpecifier * const *path_buffer() const {
     return const_cast<CastExpr*>(this)->path_buffer();
@@ -2664,9 +2690,7 @@
     assert(kind != CK_Invalid && "creating cast with invalid cast kind");
     CastExprBits.Kind = kind;
     setBasePathSize(BasePathSize);
-#ifndef NDEBUG
-    CheckCastConsistency();
-#endif
+    assert(CastConsistency());
   }
 
   /// \brief Construct an empty cast.
@@ -3422,7 +3446,7 @@
 
   /// \brief Build an empty vector-shuffle expression.
   explicit ShuffleVectorExpr(EmptyShell Empty)
-    : Expr(ShuffleVectorExprClass, Empty), SubExprs(0) { }
+    : Expr(ShuffleVectorExprClass, Empty), SubExprs(nullptr) { }
 
   SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
   void setBuiltinLoc(SourceLocation L) { BuiltinLoc = L; }
@@ -3774,6 +3798,14 @@
   void setInit(unsigned Init, Expr *expr) {
     assert(Init < getNumInits() && "Initializer access out of range!");
     InitExprs[Init] = expr;
+
+    if (expr) {
+      ExprBits.TypeDependent |= expr->isTypeDependent();
+      ExprBits.ValueDependent |= expr->isValueDependent();
+      ExprBits.InstantiationDependent |= expr->isInstantiationDependent();
+      ExprBits.ContainsUnexpandedParameterPack |=
+          expr->containsUnexpandedParameterPack();
+    }
   }
 
   /// \brief Reserve space for some number of initializers.
@@ -3824,8 +3856,8 @@
     return const_cast<InitListExpr *>(this)->getInitializedFieldInUnion();
   }
   void setInitializedFieldInUnion(FieldDecl *FD) {
-    assert((FD == 0
-            || getInitializedFieldInUnion() == 0
+    assert((FD == nullptr
+            || getInitializedFieldInUnion() == nullptr
             || getInitializedFieldInUnion() == FD)
            && "Only one field of a union may be initialized at a time!");
     ArrayFillerOrUnionFieldInit = FD;
@@ -3848,10 +3880,10 @@
 
   bool isSemanticForm() const { return AltForm.getInt(); }
   InitListExpr *getSemanticForm() const {
-    return isSemanticForm() ? 0 : AltForm.getPointer();
+    return isSemanticForm() ? nullptr : AltForm.getPointer();
   }
   InitListExpr *getSyntacticForm() const {
-    return isSemanticForm() ? AltForm.getPointer() : 0;
+    return isSemanticForm() ? AltForm.getPointer() : nullptr;
   }
 
   void setSyntacticForm(InitListExpr *Init) {
@@ -3877,6 +3909,7 @@
 
   // Iterators
   child_range children() {
+    // FIXME: This does not include the array filler expression.
     if (InitExprs.empty()) return child_range();
     return child_range(&InitExprs[0], &InitExprs[0] + InitExprs.size());
   }
@@ -3953,7 +3986,7 @@
 
   explicit DesignatedInitExpr(unsigned NumSubExprs)
     : Expr(DesignatedInitExprClass, EmptyShell()),
-      NumDesignators(0), NumSubExprs(NumSubExprs), Designators(0) { }
+      NumDesignators(0), NumSubExprs(NumSubExprs), Designators(nullptr) { }
 
 public:
   /// A field designator, e.g., ".x".
@@ -4050,7 +4083,7 @@
     FieldDecl *getField() const {
       assert(Kind == FieldDesignator && "Only valid on a field designator");
       if (Field.NameOrField & 0x01)
-        return 0;
+        return nullptr;
       else
         return reinterpret_cast<FieldDecl *>(Field.NameOrField);
     }
@@ -4134,6 +4167,17 @@
     return Designators + NumDesignators;
   }
 
+  typedef llvm::iterator_range<designators_iterator> designators_range;
+  designators_range designators() {
+    return designators_range(designators_begin(), designators_end());
+  }
+
+  typedef llvm::iterator_range<const_designators_iterator>
+          designators_const_range;
+  designators_const_range designators() const {
+    return designators_const_range(designators_begin(), designators_end());
+  }
+
   typedef std::reverse_iterator<designators_iterator>
           reverse_designators_iterator;
   reverse_designators_iterator designators_rbegin() {
@@ -4186,18 +4230,14 @@
   /// and array-range designators.
   unsigned getNumSubExprs() const { return NumSubExprs; }
 
-  Expr *getSubExpr(unsigned Idx) {
+  Expr *getSubExpr(unsigned Idx) const {
     assert(Idx < NumSubExprs && "Subscript out of range");
-    char* Ptr = static_cast<char*>(static_cast<void *>(this));
-    Ptr += sizeof(DesignatedInitExpr);
-    return reinterpret_cast<Expr**>(reinterpret_cast<void**>(Ptr))[Idx];
+    return cast<Expr>(reinterpret_cast<Stmt *const *>(this + 1)[Idx]);
   }
 
   void setSubExpr(unsigned Idx, Expr *E) {
     assert(Idx < NumSubExprs && "Subscript out of range");
-    char* Ptr = static_cast<char*>(static_cast<void *>(this));
-    Ptr += sizeof(DesignatedInitExpr);
-    reinterpret_cast<Expr**>(reinterpret_cast<void**>(Ptr))[Idx] = E;
+    reinterpret_cast<Stmt **>(this + 1)[Idx] = E;
   }
 
   /// \brief Replaces the designator at index @p Idx with the series
@@ -4621,7 +4661,7 @@
 public:
   /// NoResult - A value for the result index indicating that there is
   /// no semantic result.
-  enum LLVM_ENUM_INT_TYPE(unsigned) { NoResult = ~0U };
+  enum : unsigned { NoResult = ~0U };
 
   static PseudoObjectExpr *Create(const ASTContext &Context, Expr *syntactic,
                                   ArrayRef<Expr*> semantic,
@@ -4646,7 +4686,7 @@
   /// Return the result-bearing expression, or null if there is none.
   Expr *getResultExpr() {
     if (PseudoObjectExprBits.ResultIndex == 0)
-      return 0;
+      return nullptr;
     return getSubExprsBuffer()[PseudoObjectExprBits.ResultIndex];
   }
   const Expr *getResultExpr() const {
@@ -4713,6 +4753,16 @@
     BI_First = 0
   };
 
+  // The ABI values for various atomic memory orderings.
+  enum AtomicOrderingKind {
+    AO_ABI_memory_order_relaxed = 0,
+    AO_ABI_memory_order_consume = 1,
+    AO_ABI_memory_order_acquire = 2,
+    AO_ABI_memory_order_release = 3,
+    AO_ABI_memory_order_acq_rel = 4,
+    AO_ABI_memory_order_seq_cst = 5
+  };
+
 private:
   enum { PTR, ORDER, VAL1, ORDER_FAIL, VAL2, WEAK, END_EXPR };
   Stmt* SubExprs[END_EXPR];
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 6356ee7..3a43d6d 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -20,7 +20,7 @@
 #include "clang/AST/TemplateBase.h"
 #include "clang/AST/UnresolvedSet.h"
 #include "clang/Basic/ExpressionTraits.h"
-#include "clang/Basic/Lambda.h"
+#include "clang/AST/LambdaCapture.h"
 #include "clang/Basic/TypeTraits.h"
 #include "llvm/Support/Compiler.h"
 
@@ -486,7 +486,7 @@
   Stmt *SubExpr;
 
   CXXStdInitializerListExpr(EmptyShell Empty)
-    : Expr(CXXStdInitializerListExprClass, Empty), SubExpr(0) {}
+    : Expr(CXXStdInitializerListExprClass, Empty), SubExpr(nullptr) {}
 
 public:
   CXXStdInitializerListExpr(QualType Ty, Expr *SubExpr)
@@ -553,9 +553,9 @@
   CXXTypeidExpr(EmptyShell Empty, bool isExpr)
     : Expr(CXXTypeidExprClass, Empty) {
     if (isExpr)
-      Operand = (Expr*)0;
+      Operand = (Expr*)nullptr;
     else
-      Operand = (TypeSourceInfo*)0;
+      Operand = (TypeSourceInfo*)nullptr;
   }
 
   /// Determine whether this typeid has a type operand which is potentially
@@ -692,9 +692,9 @@
   CXXUuidofExpr(EmptyShell Empty, bool isExpr)
     : Expr(CXXUuidofExprClass, Empty) {
     if (isExpr)
-      Operand = (Expr*)0;
+      Operand = (Expr*)nullptr;
     else
-      Operand = (TypeSourceInfo*)0;
+      Operand = (TypeSourceInfo*)nullptr;
   }
 
   bool isTypeOperand() const { return Operand.is<TypeSourceInfo *>(); }
@@ -737,8 +737,8 @@
 
   /// Grabs __declspec(uuid()) off a type, or returns 0 if we cannot resolve to
   /// a single GUID.
-  static UuidAttr *GetUuidAttrOfType(QualType QT,
-                                     bool *HasMultipleGUIDsPtr = 0);
+  static const UuidAttr *GetUuidAttrOfType(QualType QT,
+                                           bool *HasMultipleGUIDsPtr = nullptr);
 
   // Iterators
   child_range children() {
@@ -832,7 +832,7 @@
 
   SourceLocation getLocStart() const LLVM_READONLY { return ThrowLoc; }
   SourceLocation getLocEnd() const LLVM_READONLY {
-    if (getSubExpr() == 0)
+    if (!getSubExpr())
       return ThrowLoc;
     return getSubExpr()->getLocEnd();
   }
@@ -1031,7 +1031,7 @@
 
 public:
   CXXBindTemporaryExpr(EmptyShell Empty)
-    : Expr(CXXBindTemporaryExprClass, Empty), Temp(0), SubExpr(0) {}
+    : Expr(CXXBindTemporaryExprClass, Empty), Temp(nullptr), SubExpr(nullptr) {}
 
   static CXXBindTemporaryExpr *Create(const ASTContext &C, CXXTemporary *Temp,
                                       Expr* SubExpr);
@@ -1077,6 +1077,7 @@
   bool Elidable : 1;
   bool HadMultipleCandidates : 1;
   bool ListInitialization : 1;
+  bool StdInitListInitialization : 1;
   bool ZeroInitialization : 1;
   unsigned ConstructKind : 2;
   Stmt **Args;
@@ -1088,24 +1089,25 @@
                    ArrayRef<Expr *> Args,
                    bool HadMultipleCandidates,
                    bool ListInitialization,
+                   bool StdInitListInitialization,
                    bool ZeroInitialization,
                    ConstructionKind ConstructKind,
                    SourceRange ParenOrBraceRange);
 
   /// \brief Construct an empty C++ construction expression.
   CXXConstructExpr(StmtClass SC, EmptyShell Empty)
-    : Expr(SC, Empty), Constructor(0), NumArgs(0), Elidable(false),
+    : Expr(SC, Empty), Constructor(nullptr), NumArgs(0), Elidable(false),
       HadMultipleCandidates(false), ListInitialization(false),
-      ZeroInitialization(false), ConstructKind(0), Args(0)
+      ZeroInitialization(false), ConstructKind(0), Args(nullptr)
   { }
 
 public:
   /// \brief Construct an empty C++ construction expression.
   explicit CXXConstructExpr(EmptyShell Empty)
-    : Expr(CXXConstructExprClass, Empty), Constructor(0),
+    : Expr(CXXConstructExprClass, Empty), Constructor(nullptr),
       NumArgs(0), Elidable(false), HadMultipleCandidates(false),
       ListInitialization(false), ZeroInitialization(false),
-      ConstructKind(0), Args(0)
+      ConstructKind(0), Args(nullptr)
   { }
 
   static CXXConstructExpr *Create(const ASTContext &C, QualType T,
@@ -1114,6 +1116,7 @@
                                   ArrayRef<Expr *> Args,
                                   bool HadMultipleCandidates,
                                   bool ListInitialization,
+                                  bool StdInitListInitialization,
                                   bool ZeroInitialization,
                                   ConstructionKind ConstructKind,
                                   SourceRange ParenOrBraceRange);
@@ -1137,6 +1140,13 @@
   bool isListInitialization() const { return ListInitialization; }
   void setListInitialization(bool V) { ListInitialization = V; }
 
+  /// \brief Whether this constructor call was written as list-initialization,
+  /// but was interpreted as forming a std::initializer_list<T> from the list
+  /// and passing that as a single constructor argument.
+  /// See C++11 [over.match.list]p1 bullet 1.
+  bool isStdInitListInitialization() const { return StdInitListInitialization; }
+  void setStdInitListInitialization(bool V) { StdInitListInitialization = V; }
+
   /// \brief Whether this construction first requires
   /// zero-initialization before the initializer is called.
   bool requiresZeroInitialization() const { return ZeroInitialization; }
@@ -1161,7 +1171,10 @@
   const_arg_iterator arg_begin() const { return Args; }
   const_arg_iterator arg_end() const { return Args + NumArgs; }
 
-  Expr **getArgs() const { return reinterpret_cast<Expr **>(Args); }
+  Expr **getArgs() { return reinterpret_cast<Expr **>(Args); }
+  const Expr *const *getArgs() const {
+    return const_cast<CXXConstructExpr *>(this)->getArgs();
+  }
   unsigned getNumArgs() const { return NumArgs; }
 
   /// \brief Return the specified argument.
@@ -1269,6 +1282,7 @@
                          SourceRange ParenOrBraceRange,
                          bool HadMultipleCandidates,
                          bool ListInitialization,
+                         bool StdInitListInitialization,
                          bool ZeroInitialization);
   explicit CXXTemporaryObjectExpr(EmptyShell Empty)
     : CXXConstructExpr(CXXTemporaryObjectExprClass, Empty), Type() { }
@@ -1307,18 +1321,6 @@
 /// includes an initializing expression (rather than capturing a variable),
 /// and which can never occur implicitly.
 class LambdaExpr : public Expr {
-  enum {
-    /// \brief Flag used by the Capture class to indicate that the given
-    /// capture was implicit.
-    Capture_Implicit = 0x01,
-
-    /// \brief Flag used by the Capture class to indicate that the
-    /// given capture was by-copy.
-    ///
-    /// This includes the case of a non-reference init-capture.
-    Capture_ByCopy = 0x02
-  };
-
   /// \brief The source range that covers the lambda introducer ([...]).
   SourceRange IntroducerRange;
 
@@ -1357,93 +1359,8 @@
   // expression, along with the index variables used to initialize by-copy
   // array captures.
 
-public:
-  /// \brief Describes the capture of a variable or of \c this, or of a
-  /// C++1y init-capture.
-  class Capture {
-    llvm::PointerIntPair<Decl *, 2> DeclAndBits;
-    SourceLocation Loc;
-    SourceLocation EllipsisLoc;
-    
-    friend class ASTStmtReader;
-    friend class ASTStmtWriter;
-    
-  public:
-    /// \brief Create a new capture of a variable or of \c this.
-    ///
-    /// \param Loc The source location associated with this capture.
-    ///
-    /// \param Kind The kind of capture (this, byref, bycopy), which must
-    /// not be init-capture.
-    ///
-    /// \param Implicit Whether the capture was implicit or explicit.
-    ///
-    /// \param Var The local variable being captured, or null if capturing
-    /// \c this.
-    ///
-    /// \param EllipsisLoc The location of the ellipsis (...) for a
-    /// capture that is a pack expansion, or an invalid source
-    /// location to indicate that this is not a pack expansion.
-    Capture(SourceLocation Loc, bool Implicit,
-            LambdaCaptureKind Kind, VarDecl *Var = 0,
-            SourceLocation EllipsisLoc = SourceLocation());
+  typedef LambdaCapture Capture;
 
-    /// \brief Determine the kind of capture.
-    LambdaCaptureKind getCaptureKind() const;
-
-    /// \brief Determine whether this capture handles the C++ \c this
-    /// pointer.
-    bool capturesThis() const { return DeclAndBits.getPointer() == 0; }
-
-    /// \brief Determine whether this capture handles a variable.
-    bool capturesVariable() const {
-      return dyn_cast_or_null<VarDecl>(DeclAndBits.getPointer());
-    }
-
-    /// \brief Determine whether this is an init-capture.
-    bool isInitCapture() const {
-      return capturesVariable() && getCapturedVar()->isInitCapture();
-    }
-
-    /// \brief Retrieve the declaration of the local variable being
-    /// captured.
-    ///
-    /// This operation is only valid if this capture is a variable capture
-    /// (other than a capture of \c this).
-    VarDecl *getCapturedVar() const {
-      assert(capturesVariable() && "No variable available for 'this' capture");
-      return cast<VarDecl>(DeclAndBits.getPointer());
-    }
-
-    /// \brief Determine whether this was an implicit capture (not
-    /// written between the square brackets introducing the lambda).
-    bool isImplicit() const { return DeclAndBits.getInt() & Capture_Implicit; }
-
-    /// \brief Determine whether this was an explicit capture (written
-    /// between the square brackets introducing the lambda).
-    bool isExplicit() const { return !isImplicit(); }
-
-    /// \brief Retrieve the source location of the capture.
-    ///
-    /// For an explicit capture, this returns the location of the
-    /// explicit capture in the source. For an implicit capture, this
-    /// returns the location at which the variable or \c this was first
-    /// used.
-    SourceLocation getLocation() const { return Loc; }
-
-    /// \brief Determine whether this capture is a pack expansion,
-    /// which captures a function parameter pack.
-    bool isPackExpansion() const { return EllipsisLoc.isValid(); }
-
-    /// \brief Retrieve the location of the ellipsis for a capture
-    /// that is a pack expansion.
-    SourceLocation getEllipsisLoc() const {
-      assert(isPackExpansion() && "No ellipsis location for a non-expansion");
-      return EllipsisLoc;
-    }
-  };
-
-private:
   /// \brief Construct a lambda expression.
   LambdaExpr(QualType T, SourceRange IntroducerRange,
              LambdaCaptureDefault CaptureDefault,
@@ -1462,7 +1379,7 @@
     : Expr(LambdaExprClass, Empty),
       NumCaptures(NumCaptures), CaptureDefault(LCD_None), ExplicitParams(false),
       ExplicitResultType(false), HasArrayIndexVars(true) { 
-    getStoredStmts()[NumCaptures] = 0;
+    getStoredStmts()[NumCaptures] = nullptr;
   }
   
   Stmt **getStoredStmts() const {
@@ -1520,6 +1437,12 @@
   /// both implicit and explicit.
   typedef const Capture *capture_iterator;
 
+  /// \brief An iterator over a range of lambda captures.
+  typedef llvm::iterator_range<capture_iterator> capture_range;
+
+  /// \brief Retrieve this lambda's captures.
+  capture_range captures() const;
+  
   /// \brief Retrieve an iterator pointing to the first lambda capture.
   capture_iterator capture_begin() const;
 
@@ -1529,6 +1452,9 @@
 
   /// \brief Determine the number of captures in this lambda.
   unsigned capture_size() const { return NumCaptures; }
+
+  /// \brief Retrieve this lambda's explicit captures.
+  capture_range explicit_captures() const;
   
   /// \brief Retrieve an iterator pointing to the first explicit
   /// lambda capture.
@@ -1538,6 +1464,9 @@
   /// explicit lambda captures.
   capture_iterator explicit_capture_end() const;
 
+  /// \brief Retrieve this lambda's implicit captures.
+  capture_range implicit_captures() const;
+
   /// \brief Retrieve an iterator pointing to the first implicit
   /// lambda capture.
   capture_iterator implicit_capture_begin() const;
@@ -1550,6 +1479,12 @@
   /// arguments.
   typedef Expr **capture_init_iterator;
 
+  /// \brief Retrieve the initialization expressions for this lambda's captures.
+  llvm::iterator_range<capture_init_iterator> capture_inits() const {
+    return llvm::iterator_range<capture_init_iterator>(capture_init_begin(),
+                                                       capture_init_end());
+  }
+
   /// \brief Retrieve the first initialization argument for this
   /// lambda expression (which initializes the first capture field).
   capture_init_iterator capture_init_begin() const {
@@ -1717,7 +1652,7 @@
              QualType ty, TypeSourceInfo *AllocatedTypeInfo,
              SourceRange Range, SourceRange directInitRange);
   explicit CXXNewExpr(EmptyShell Shell)
-    : Expr(CXXNewExprClass, Shell), SubExprs(0) { }
+    : Expr(CXXNewExprClass, Shell), SubExprs(nullptr) { }
 
   void AllocateArgsArray(const ASTContext &C, bool isArray,
                          unsigned numPlaceArgs, bool hasInitializer);
@@ -1751,10 +1686,10 @@
 
   bool isArray() const { return Array; }
   Expr *getArraySize() {
-    return Array ? cast<Expr>(SubExprs[0]) : 0;
+    return Array ? cast<Expr>(SubExprs[0]) : nullptr;
   }
   const Expr *getArraySize() const {
-    return Array ? cast<Expr>(SubExprs[0]) : 0;
+    return Array ? cast<Expr>(SubExprs[0]) : nullptr;
   }
 
   unsigned getNumPlacementArgs() const { return NumPlacementArgs; }
@@ -1788,10 +1723,10 @@
 
   /// \brief The initializer of this new-expression.
   Expr *getInitializer() {
-    return hasInitializer() ? cast<Expr>(SubExprs[Array]) : 0;
+    return hasInitializer() ? cast<Expr>(SubExprs[Array]) : nullptr;
   }
   const Expr *getInitializer() const {
-    return hasInitializer() ? cast<Expr>(SubExprs[Array]) : 0;
+    return hasInitializer() ? cast<Expr>(SubExprs[Array]) : nullptr;
   }
 
   /// \brief Returns the CXXConstructExpr from this new-expression, or null.
@@ -1885,7 +1820,8 @@
       ArrayForm(arrayForm), ArrayFormAsWritten(arrayFormAsWritten),
       UsualArrayDeleteWantsSize(usualArrayDeleteWantsSize) { }
   explicit CXXDeleteExpr(EmptyShell Shell)
-    : Expr(CXXDeleteExprClass, Shell), OperatorDelete(0), Argument(0) { }
+    : Expr(CXXDeleteExprClass, Shell), OperatorDelete(nullptr),
+      Argument(nullptr) {}
 
   bool isGlobalDelete() const { return GlobalDelete; }
   bool isArrayForm() const { return ArrayForm; }
@@ -2017,7 +1953,7 @@
 
   explicit CXXPseudoDestructorExpr(EmptyShell Shell)
     : Expr(CXXPseudoDestructorExprClass, Shell),
-      Base(0), IsArrow(false), QualifierLoc(), ScopeType(0) { }
+      Base(nullptr), IsArrow(false), QualifierLoc(), ScopeType(nullptr) { }
 
   Expr *getBase() const { return cast<Expr>(Base); }
 
@@ -2110,138 +2046,12 @@
   child_range children() { return child_range(&Base, &Base + 1); }
 };
 
-/// \brief Represents a GCC or MS unary type trait, as used in the
-/// implementation of TR1/C++11 type trait templates.
-///
-/// Example:
-/// \code
-///   __is_pod(int) == true
-///   __is_enum(std::string) == false
-/// \endcode
-class UnaryTypeTraitExpr : public Expr {
-  /// \brief The trait. A UnaryTypeTrait enum in MSVC compatible unsigned.
-  unsigned UTT : 31;
-  /// The value of the type trait. Unspecified if dependent.
-  bool Value : 1;
-
-  /// \brief The location of the type trait keyword.
-  SourceLocation Loc;
-
-  /// \brief The location of the closing paren.
-  SourceLocation RParen;
-
-  /// \brief The type being queried.
-  TypeSourceInfo *QueriedType;
-
-public:
-  UnaryTypeTraitExpr(SourceLocation loc, UnaryTypeTrait utt,
-                     TypeSourceInfo *queried, bool value,
-                     SourceLocation rparen, QualType ty)
-    : Expr(UnaryTypeTraitExprClass, ty, VK_RValue, OK_Ordinary,
-           false,  queried->getType()->isDependentType(),
-           queried->getType()->isInstantiationDependentType(),
-           queried->getType()->containsUnexpandedParameterPack()),
-      UTT(utt), Value(value), Loc(loc), RParen(rparen), QueriedType(queried) { }
-
-  explicit UnaryTypeTraitExpr(EmptyShell Empty)
-    : Expr(UnaryTypeTraitExprClass, Empty), UTT(0), Value(false),
-      QueriedType() { }
-
-  SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
-  SourceLocation getLocEnd() const LLVM_READONLY { return RParen; }
-
-  UnaryTypeTrait getTrait() const { return static_cast<UnaryTypeTrait>(UTT); }
-
-  QualType getQueriedType() const { return QueriedType->getType(); }
-
-  TypeSourceInfo *getQueriedTypeSourceInfo() const { return QueriedType; }
-
-  bool getValue() const { return Value; }
-
-  static bool classof(const Stmt *T) {
-    return T->getStmtClass() == UnaryTypeTraitExprClass;
-  }
-
-  // Iterators
-  child_range children() { return child_range(); }
-
-  friend class ASTStmtReader;
-};
-
-/// \brief Represents a GCC or MS binary type trait, as used in the
-/// implementation of TR1/C++11 type trait templates.
-///
-/// Example:
-/// \code
-///   __is_base_of(Base, Derived) == true
-/// \endcode
-class BinaryTypeTraitExpr : public Expr {
-  /// \brief The trait. A BinaryTypeTrait enum in MSVC compatible unsigned.
-  unsigned BTT : 8;
-
-  /// The value of the type trait. Unspecified if dependent.
-  bool Value : 1;
-
-  /// \brief The location of the type trait keyword.
-  SourceLocation Loc;
-
-  /// \brief The location of the closing paren.
-  SourceLocation RParen;
-
-  /// \brief The lhs type being queried.
-  TypeSourceInfo *LhsType;
-
-  /// \brief The rhs type being queried.
-  TypeSourceInfo *RhsType;
-
-public:
-  BinaryTypeTraitExpr(SourceLocation loc, BinaryTypeTrait btt,
-                     TypeSourceInfo *lhsType, TypeSourceInfo *rhsType,
-                     bool value, SourceLocation rparen, QualType ty)
-    : Expr(BinaryTypeTraitExprClass, ty, VK_RValue, OK_Ordinary, false,
-           lhsType->getType()->isDependentType() ||
-           rhsType->getType()->isDependentType(),
-           (lhsType->getType()->isInstantiationDependentType() ||
-            rhsType->getType()->isInstantiationDependentType()),
-           (lhsType->getType()->containsUnexpandedParameterPack() ||
-            rhsType->getType()->containsUnexpandedParameterPack())),
-      BTT(btt), Value(value), Loc(loc), RParen(rparen),
-      LhsType(lhsType), RhsType(rhsType) { }
-
-
-  explicit BinaryTypeTraitExpr(EmptyShell Empty)
-    : Expr(BinaryTypeTraitExprClass, Empty), BTT(0), Value(false),
-      LhsType(), RhsType() { }
-
-  SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
-  SourceLocation getLocEnd() const LLVM_READONLY { return RParen; }
-
-  BinaryTypeTrait getTrait() const {
-    return static_cast<BinaryTypeTrait>(BTT);
-  }
-
-  QualType getLhsType() const { return LhsType->getType(); }
-  QualType getRhsType() const { return RhsType->getType(); }
-
-  TypeSourceInfo *getLhsTypeSourceInfo() const { return LhsType; }
-  TypeSourceInfo *getRhsTypeSourceInfo() const { return RhsType; }
-
-  bool getValue() const { assert(!isTypeDependent()); return Value; }
-
-  static bool classof(const Stmt *T) {
-    return T->getStmtClass() == BinaryTypeTraitExprClass;
-  }
-
-  // Iterators
-  child_range children() { return child_range(); }
-
-  friend class ASTStmtReader;
-};
-
 /// \brief A type trait used in the implementation of various C++11 and
 /// Library TR1 trait templates.
 ///
 /// \code
+///   __is_pod(int) == true
+///   __is_enum(std::string) == false
 ///   __is_trivially_constructible(vector<int>, int*, int*)
 /// \endcode
 class TypeTraitExpr : public Expr {
@@ -2334,7 +2144,7 @@
   friend class ASTStmtWriter;
 
 };
-  
+
 /// \brief An Embarcadero array type trait, as used in the implementation of
 /// __array_rank and __array_extent.
 ///
@@ -2504,7 +2314,7 @@
                bool KnownContainsUnexpandedParameterPack);
 
   OverloadExpr(StmtClass K, EmptyShell Empty)
-    : Expr(K, Empty), QualifierLoc(), Results(0), NumResults(0),
+    : Expr(K, Empty), QualifierLoc(), Results(nullptr), NumResults(0),
       HasTemplateKWAndArgsInfo(false) { }
 
   void initializeResults(const ASTContext &C,
@@ -2554,6 +2364,9 @@
   decls_iterator decls_end() const {
     return UnresolvedSetIterator(Results + NumResults);
   }
+  llvm::iterator_range<decls_iterator> decls() const {
+    return llvm::iterator_range<decls_iterator>(decls_begin(), decls_end());
+  }
 
   /// \brief Gets the number of declarations in the unresolved set.
   unsigned getNumDecls() const { return NumResults; }
@@ -2634,7 +2447,7 @@
   /// This points to the same data as getExplicitTemplateArgs(), but
   /// returns null if there are no explicit template arguments.
   const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const {
-    if (!hasExplicitTemplateArgs()) return 0;
+    if (!hasExplicitTemplateArgs()) return nullptr;
     return &getExplicitTemplateArgs();
   }
 
@@ -2691,7 +2504,7 @@
 
   UnresolvedLookupExpr(EmptyShell Empty)
     : OverloadExpr(UnresolvedLookupExprClass, Empty),
-      RequiresADL(false), Overloaded(false), NamingClass(0)
+      RequiresADL(false), Overloaded(false), NamingClass(nullptr)
   {}
 
   friend class ASTStmtReader;
@@ -2706,7 +2519,7 @@
                                       UnresolvedSetIterator End) {
     return new(C) UnresolvedLookupExpr(C, NamingClass, QualifierLoc,
                                        SourceLocation(), NameInfo,
-                                       ADL, Overloaded, 0, Begin, End);
+                                       ADL, Overloaded, nullptr, Begin, End);
   }
 
   static UnresolvedLookupExpr *Create(const ASTContext &C,
@@ -2781,7 +2594,7 @@
 
   /// \brief Return the optional template keyword and arguments info.
   ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() {
-    if (!HasTemplateKWAndArgsInfo) return 0;
+    if (!HasTemplateKWAndArgsInfo) return nullptr;
     return reinterpret_cast<ASTTemplateKWAndArgsInfo*>(this + 1);
   }
   /// \brief Return the optional template keyword and arguments info.
@@ -2875,7 +2688,7 @@
   /// This points to the same data as getExplicitTemplateArgs(), but
   /// returns null if there are no explicit template arguments.
   const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const {
-    if (!hasExplicitTemplateArgs()) return 0;
+    if (!hasExplicitTemplateArgs()) return nullptr;
     return &getExplicitTemplateArgs();
   }
 
@@ -3151,7 +2964,7 @@
 
   /// \brief Return the optional template keyword and arguments info.
   ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() {
-    if (!HasTemplateKWAndArgsInfo) return 0;
+    if (!HasTemplateKWAndArgsInfo) return nullptr;
     return reinterpret_cast<ASTTemplateKWAndArgsInfo*>(this + 1);
   }
   /// \brief Return the optional template keyword and arguments info.
@@ -3296,7 +3109,7 @@
   /// This points to the same data as getExplicitTemplateArgs(), but
   /// returns null if there are no explicit template arguments.
   const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const {
-    if (!hasExplicitTemplateArgs()) return 0;
+    if (!hasExplicitTemplateArgs()) return nullptr;
     return &getExplicitTemplateArgs();
   }
 
@@ -3398,7 +3211,7 @@
 
   UnresolvedMemberExpr(EmptyShell Empty)
     : OverloadExpr(UnresolvedMemberExprClass, Empty), IsArrow(false),
-      HasUnresolvedUsing(false), Base(0) { }
+      HasUnresolvedUsing(false), Base(nullptr) { }
 
   friend class ASTStmtReader;
 
@@ -3612,7 +3425,7 @@
 };
 
 inline ASTTemplateKWAndArgsInfo *OverloadExpr::getTemplateKWAndArgsInfo() {
-  if (!HasTemplateKWAndArgsInfo) return 0;
+  if (!HasTemplateKWAndArgsInfo) return nullptr;
   if (isa<UnresolvedLookupExpr>(this))
     return reinterpret_cast<ASTTemplateKWAndArgsInfo*>
       (cast<UnresolvedLookupExpr>(this) + 1);
@@ -3904,39 +3717,51 @@
 /// temporary. When either happens, the expression will also track the
 /// declaration which is responsible for the lifetime extension.
 class MaterializeTemporaryExpr : public Expr {
-public:
-  /// \brief The temporary-generating expression whose value will be
-  /// materialized.
-  Stmt *Temporary;
+private:
+  struct ExtraState {
+    /// \brief The temporary-generating expression whose value will be
+    /// materialized.
+    Stmt *Temporary;
 
-  /// \brief The declaration which lifetime-extended this reference, if any.
-  /// Either a VarDecl, or (for a ctor-initializer) a FieldDecl.
-  const ValueDecl *ExtendingDecl;
+    /// \brief The declaration which lifetime-extended this reference, if any.
+    /// Either a VarDecl, or (for a ctor-initializer) a FieldDecl.
+    const ValueDecl *ExtendingDecl;
+
+    unsigned ManglingNumber;
+  };
+  llvm::PointerUnion<Stmt *, ExtraState *> State;
 
   friend class ASTStmtReader;
   friend class ASTStmtWriter;
 
+  void initializeExtraState(const ValueDecl *ExtendedBy,
+                            unsigned ManglingNumber);
+
 public:
   MaterializeTemporaryExpr(QualType T, Expr *Temporary,
-                           bool BoundToLvalueReference,
-                           const ValueDecl *ExtendedBy)
+                           bool BoundToLvalueReference)
     : Expr(MaterializeTemporaryExprClass, T,
            BoundToLvalueReference? VK_LValue : VK_XValue, OK_Ordinary,
            Temporary->isTypeDependent(), Temporary->isValueDependent(),
            Temporary->isInstantiationDependent(),
            Temporary->containsUnexpandedParameterPack()),
-      Temporary(Temporary), ExtendingDecl(ExtendedBy) {
-  }
+        State(Temporary) {}
 
   MaterializeTemporaryExpr(EmptyShell Empty)
     : Expr(MaterializeTemporaryExprClass, Empty) { }
 
+  Stmt *getTemporary() const {
+    return State.is<Stmt *>() ? State.get<Stmt *>()
+                              : State.get<ExtraState *>()->Temporary;
+  }
+
   /// \brief Retrieve the temporary-generating subexpression whose value will
   /// be materialized into a glvalue.
-  Expr *GetTemporaryExpr() const { return static_cast<Expr *>(Temporary); }
+  Expr *GetTemporaryExpr() const { return static_cast<Expr *>(getTemporary()); }
 
   /// \brief Retrieve the storage duration for the materialized temporary.
   StorageDuration getStorageDuration() const {
+    const ValueDecl *ExtendingDecl = getExtendingDecl();
     if (!ExtendingDecl)
       return SD_FullExpression;
     // FIXME: This is not necessarily correct for a temporary materialized
@@ -3948,10 +3773,15 @@
 
   /// \brief Get the declaration which triggered the lifetime-extension of this
   /// temporary, if any.
-  const ValueDecl *getExtendingDecl() const { return ExtendingDecl; }
+  const ValueDecl *getExtendingDecl() const {
+    return State.is<Stmt *>() ? nullptr
+                              : State.get<ExtraState *>()->ExtendingDecl;
+  }
 
-  void setExtendingDecl(const ValueDecl *ExtendedBy) {
-    ExtendingDecl = ExtendedBy;
+  void setExtendingDecl(const ValueDecl *ExtendedBy, unsigned ManglingNumber);
+
+  unsigned getManglingNumber() const {
+    return State.is<Stmt *>() ? 0 : State.get<ExtraState *>()->ManglingNumber;
   }
 
   /// \brief Determine whether this materialized temporary is bound to an
@@ -3961,10 +3791,10 @@
   }
 
   SourceLocation getLocStart() const LLVM_READONLY {
-    return Temporary->getLocStart();
+    return getTemporary()->getLocStart();
   }
   SourceLocation getLocEnd() const LLVM_READONLY {
-    return Temporary->getLocEnd();
+    return getTemporary()->getLocEnd();
   }
 
   static bool classof(const Stmt *T) {
@@ -3972,7 +3802,13 @@
   }
 
   // Iterators
-  child_range children() { return child_range(&Temporary, &Temporary + 1); }
+  child_range children() {
+    if (State.is<Stmt *>())
+      return child_range(State.getAddrOfPtr1(), State.getAddrOfPtr1() + 1);
+
+    auto ES = State.get<ExtraState *>();
+    return child_range(&ES->Temporary, &ES->Temporary + 1);
+  }
 };
 
 }  // end namespace clang
diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h
index aeb55da..817c0cc 100644
--- a/include/clang/AST/ExprObjC.h
+++ b/include/clang/AST/ExprObjC.h
@@ -215,7 +215,7 @@
 } // end namespace clang
 
 namespace llvm {
-template <> struct isPodLike<clang::ObjCDictionaryElement> : llvm::true_type {};
+template <> struct isPodLike<clang::ObjCDictionaryElement> : std::true_type {};
 }
 
 namespace clang {
@@ -277,14 +277,14 @@
 
   ExpansionData *getExpansionData() {
     if (!HasPackExpansions)
-      return 0;
+      return nullptr;
     
     return reinterpret_cast<ExpansionData *>(getKeyValues() + NumElements);
   }
 
   const ExpansionData *getExpansionData() const {
     if (!HasPackExpansions)
-      return 0;
+      return nullptr;
     
     return reinterpret_cast<const ExpansionData *>(getKeyValues()+NumElements);
   }
@@ -683,13 +683,13 @@
     if (isExplicitProperty()) {
       const ObjCPropertyDecl *PDecl = getExplicitProperty();
       if (const ObjCMethodDecl *Getter = PDecl->getGetterMethodDecl())
-        ResultType = Getter->getResultType();
+        ResultType = Getter->getReturnType();
       else
         ResultType = PDecl->getType();
     } else {
       const ObjCMethodDecl *Getter = getImplicitPropertyGetter();
       if (Getter)
-        ResultType = Getter->getResultType(); // with reference!
+        ResultType = Getter->getReturnType(); // with reference!
     }
     return ResultType;
   }
@@ -743,7 +743,7 @@
   void setExplicitProperty(ObjCPropertyDecl *D, unsigned methRefFlags) {
     PropertyOrGetter.setPointer(D);
     PropertyOrGetter.setInt(false);
-    SetterAndMethodRefFlags.setPointer(0);
+    SetterAndMethodRefFlags.setPointer(nullptr);
     SetterAndMethodRefFlags.setInt(methRefFlags);
   }
   void setImplicitProperty(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
@@ -1174,7 +1174,7 @@
     if (getReceiverKind() == Instance)
       return static_cast<Expr *>(getReceiverPointer());
 
-    return 0;
+    return nullptr;
   }
   const Expr *getInstanceReceiver() const {
     return const_cast<ObjCMessageExpr*>(this)->getInstanceReceiver();
@@ -1201,7 +1201,7 @@
   TypeSourceInfo *getClassReceiverTypeInfo() const {
     if (getReceiverKind() == Class)
       return reinterpret_cast<TypeSourceInfo *>(getReceiverPointer());
-    return 0;
+    return nullptr;
   }
 
   void setClassReceiver(TypeSourceInfo *TSInfo) {
@@ -1270,14 +1270,14 @@
     if (HasMethod)
       return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod);
 
-    return 0;
+    return nullptr;
   }
 
   ObjCMethodDecl *getMethodDecl() { 
     if (HasMethod)
       return reinterpret_cast<ObjCMethodDecl *>(SelectorOrMethod);
 
-    return 0;
+    return nullptr;
   }
 
   void setMethodDecl(ObjCMethodDecl *MD) { 
diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h
index b077426..1e8eff3 100644
--- a/include/clang/AST/ExternalASTSource.h
+++ b/include/clang/AST/ExternalASTSource.h
@@ -45,7 +45,7 @@
   /// no additional processing is required.
   ELR_AlreadyLoaded
 };
-  
+
 /// \brief Abstract interface for external sources of AST nodes.
 ///
 /// External AST sources provide AST nodes constructed from some
@@ -53,7 +53,11 @@
 /// sources can resolve types and declarations from abstract IDs into
 /// actual type and declaration nodes, and read parts of declaration
 /// contexts.
-class ExternalASTSource {
+class ExternalASTSource : public RefCountedBase<ExternalASTSource> {
+  /// Generation number for this external AST source. Must be increased
+  /// whenever we might have added new redeclarations for existing decls.
+  uint32_t CurrentGeneration;
+
   /// \brief Whether this AST source also provides information for
   /// semantic analysis.
   bool SemaSource;
@@ -61,7 +65,7 @@
   friend class ExternalSemaSource;
 
 public:
-  ExternalASTSource() : SemaSource(false) { }
+  ExternalASTSource() : CurrentGeneration(0), SemaSource(false) { }
 
   virtual ~ExternalASTSource();
 
@@ -79,6 +83,11 @@
     }
   };
 
+  /// \brief Get the current generation of this AST source. This number
+  /// is incremented each time the AST source lazily extends an existing
+  /// entity.
+  uint32_t getGeneration() const { return CurrentGeneration; }
+
   /// \brief Resolve a declaration ID into a declaration, potentially
   /// building a new declaration.
   ///
@@ -138,7 +147,7 @@
   virtual void completeVisibleDeclsMap(const DeclContext *DC);
 
   /// \brief Retrieve the module that corresponds to the given module ID.
-  virtual Module *getModule(unsigned ID) { return 0; }
+  virtual Module *getModule(unsigned ID) { return nullptr; }
 
   /// \brief Finds all declarations lexically contained within the given
   /// DeclContext, after applying an optional filter predicate.
@@ -160,7 +169,7 @@
   /// \return true if an error occurred
   ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
                                 SmallVectorImpl<Decl*> &Result) {
-    return FindExternalLexicalDecls(DC, 0, Result);
+    return FindExternalLexicalDecls(DC, nullptr, Result);
   }
 
   template <typename DeclTy>
@@ -171,43 +180,50 @@
 
   /// \brief Get the decls that are contained in a file in the Offset/Length
   /// range. \p Length can be 0 to indicate a point at \p Offset instead of
-  /// a range. 
-  virtual void FindFileRegionDecls(FileID File, unsigned Offset,unsigned Length,
-                                   SmallVectorImpl<Decl *> &Decls) {}
+  /// a range.
+  virtual void FindFileRegionDecls(FileID File, unsigned Offset,
+                                   unsigned Length,
+                                   SmallVectorImpl<Decl *> &Decls);
+
+  /// \brief Gives the external AST source an opportunity to complete
+  /// the redeclaration chain for a declaration. Called each time we
+  /// need the most recent declaration of a declaration after the
+  /// generation count is incremented.
+  virtual void CompleteRedeclChain(const Decl *D);
 
   /// \brief Gives the external AST source an opportunity to complete
   /// an incomplete type.
-  virtual void CompleteType(TagDecl *Tag) {}
+  virtual void CompleteType(TagDecl *Tag);
 
   /// \brief Gives the external AST source an opportunity to complete an
   /// incomplete Objective-C class.
   ///
   /// This routine will only be invoked if the "externally completed" bit is
-  /// set on the ObjCInterfaceDecl via the function 
+  /// set on the ObjCInterfaceDecl via the function
   /// \c ObjCInterfaceDecl::setExternallyCompleted().
-  virtual void CompleteType(ObjCInterfaceDecl *Class) { }
+  virtual void CompleteType(ObjCInterfaceDecl *Class);
 
   /// \brief Loads comment ranges.
-  virtual void ReadComments() { }
+  virtual void ReadComments();
 
   /// \brief Notify ExternalASTSource that we started deserialization of
   /// a decl or type so until FinishedDeserializing is called there may be
   /// decls that are initializing. Must be paired with FinishedDeserializing.
   ///
   /// The default implementation of this method is a no-op.
-  virtual void StartedDeserializing() { }
+  virtual void StartedDeserializing();
 
   /// \brief Notify ExternalASTSource that we finished the deserialization of
   /// a decl or type. Must be paired with StartedDeserializing.
   ///
   /// The default implementation of this method is a no-op.
-  virtual void FinishedDeserializing() { }
+  virtual void FinishedDeserializing();
 
   /// \brief Function that will be invoked when we begin parsing a new
   /// translation unit involving this external AST source.
   ///
   /// The default implementation of this method is a no-op.
-  virtual void StartTranslationUnit(ASTConsumer *Consumer) { }
+  virtual void StartTranslationUnit(ASTConsumer *Consumer);
 
   /// \brief Print any statistics that have been gathered regarding
   /// the external AST source.
@@ -243,16 +259,12 @@
   /// out according to the ABI.
   /// 
   /// \returns true if the record layout was provided, false otherwise.
-  virtual bool 
-  layoutRecordType(const RecordDecl *Record,
-                   uint64_t &Size, uint64_t &Alignment,
-                   llvm::DenseMap<const FieldDecl *, uint64_t> &FieldOffsets,
-                 llvm::DenseMap<const CXXRecordDecl *, CharUnits> &BaseOffsets,
-          llvm::DenseMap<const CXXRecordDecl *, CharUnits> &VirtualBaseOffsets)
-  { 
-    return false;
-  }
-  
+  virtual bool layoutRecordType(
+      const RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
+      llvm::DenseMap<const FieldDecl *, uint64_t> &FieldOffsets,
+      llvm::DenseMap<const CXXRecordDecl *, CharUnits> &BaseOffsets,
+      llvm::DenseMap<const CXXRecordDecl *, CharUnits> &VirtualBaseOffsets);
+
   //===--------------------------------------------------------------------===//
   // Queries for performance analysis.
   //===--------------------------------------------------------------------===//
@@ -284,6 +296,9 @@
   static DeclContextLookupResult
   SetNoExternalVisibleDeclsForName(const DeclContext *DC,
                                    DeclarationName Name);
+
+  /// \brief Increment the current generation.
+  uint32_t incrementGeneration(ASTContext &C);
 };
 
 /// \brief A lazy pointer to an AST node (of base type T) that resides
@@ -354,6 +369,100 @@
   }
 };
 
+/// \brief A lazy value (of type T) that is within an AST node of type Owner,
+/// where the value might change in later generations of the external AST
+/// source.
+template<typename Owner, typename T, void (ExternalASTSource::*Update)(Owner)>
+struct LazyGenerationalUpdatePtr {
+  /// A cache of the value of this pointer, in the most recent generation in
+  /// which we queried it.
+  struct LazyData {
+    LazyData(ExternalASTSource *Source, T Value)
+        : ExternalSource(Source), LastGeneration(0), LastValue(Value) {}
+    ExternalASTSource *ExternalSource;
+    uint32_t LastGeneration;
+    T LastValue;
+  };
+
+  // Our value is represented as simply T if there is no external AST source.
+  typedef llvm::PointerUnion<T, LazyData*> ValueType;
+  ValueType Value;
+
+  LazyGenerationalUpdatePtr(ValueType V) : Value(V) {}
+
+  // Defined in ASTContext.h
+  static ValueType makeValue(const ASTContext &Ctx, T Value);
+
+public:
+  explicit LazyGenerationalUpdatePtr(const ASTContext &Ctx, T Value = T())
+      : Value(makeValue(Ctx, Value)) {}
+
+  /// Create a pointer that is not potentially updated by later generations of
+  /// the external AST source.
+  enum NotUpdatedTag { NotUpdated };
+  LazyGenerationalUpdatePtr(NotUpdatedTag, T Value = T())
+      : Value(Value) {}
+
+  /// Forcibly set this pointer (which must be lazy) as needing updates.
+  void markIncomplete() {
+    Value.template get<LazyData *>()->LastGeneration = 0;
+  }
+
+  /// Set the value of this pointer, in the current generation.
+  void set(T NewValue) {
+    if (LazyData *LazyVal = Value.template dyn_cast<LazyData*>()) {
+      LazyVal->LastValue = NewValue;
+      return;
+    }
+    Value = NewValue;
+  }
+
+  /// Set the value of this pointer, for this and all future generations.
+  void setNotUpdated(T NewValue) { Value = NewValue; }
+
+  /// Get the value of this pointer, updating its owner if necessary.
+  T get(Owner O) {
+    if (LazyData *LazyVal = Value.template dyn_cast<LazyData*>()) {
+      if (LazyVal->LastGeneration != LazyVal->ExternalSource->getGeneration()) {
+        LazyVal->LastGeneration = LazyVal->ExternalSource->getGeneration();
+        (LazyVal->ExternalSource->*Update)(O);
+      }
+      return LazyVal->LastValue;
+    }
+    return Value.template get<T>();
+  }
+
+  /// Get the most recently computed value of this pointer without updating it.
+  T getNotUpdated() const {
+    if (LazyData *LazyVal = Value.template dyn_cast<LazyData*>())
+      return LazyVal->LastValue;
+    return Value.template get<T>();
+  }
+
+  void *getOpaqueValue() { return Value.getOpaqueValue(); }
+  static LazyGenerationalUpdatePtr getFromOpaqueValue(void *Ptr) {
+    return LazyGenerationalUpdatePtr(ValueType::getFromOpaqueValue(Ptr));
+  }
+};
+} // end namespace clang
+
+/// Specialize PointerLikeTypeTraits to allow LazyGenerationalUpdatePtr to be
+/// placed into a PointerUnion.
+namespace llvm {
+template<typename Owner, typename T,
+         void (clang::ExternalASTSource::*Update)(Owner)>
+struct PointerLikeTypeTraits<
+    clang::LazyGenerationalUpdatePtr<Owner, T, Update>> {
+  typedef clang::LazyGenerationalUpdatePtr<Owner, T, Update> Ptr;
+  static void *getAsVoidPointer(Ptr P) { return P.getOpaqueValue(); }
+  static Ptr getFromVoidPointer(void *P) { return Ptr::getFromOpaqueValue(P); }
+  enum {
+    NumLowBitsAvailable = PointerLikeTypeTraits<T>::NumLowBitsAvailable - 1
+  };
+};
+}
+
+namespace clang {
 /// \brief Represents a lazily-loaded vector of data.
 ///
 /// The lazily-loaded vector of data contains data that is partially loaded
@@ -519,7 +628,7 @@
     
     if (From.Position < 0) {
       Loaded.erase(Loaded.end() + From.Position, Loaded.end());
-      From = begin(0, true);
+      From = begin(nullptr, true);
     }
     
     Local.erase(Local.begin() + From.Position, Local.begin() + To.Position);
diff --git a/include/clang/AST/LambdaCapture.h b/include/clang/AST/LambdaCapture.h
new file mode 100644
index 0000000..8633c97
--- /dev/null
+++ b/include/clang/AST/LambdaCapture.h
@@ -0,0 +1,123 @@
+//===--- LambdaCapture.h - Types for C++ Lambda Captures --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the LambdaCapture class.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_LAMBDACAPTURE_H
+#define LLVM_CLANG_AST_LAMBDACAPTURE_H
+
+#include "clang/AST/Decl.h"
+#include "clang/Basic/Lambda.h"
+#include "llvm/ADT/PointerIntPair.h"
+
+namespace clang {
+
+/// \brief Describes the capture of a variable or of \c this, or of a
+/// C++1y init-capture.
+class LambdaCapture {
+  enum {
+    /// \brief Flag used by the Capture class to indicate that the given
+    /// capture was implicit.
+    Capture_Implicit = 0x01,
+
+    /// \brief Flag used by the Capture class to indicate that the
+    /// given capture was by-copy.
+    ///
+    /// This includes the case of a non-reference init-capture.
+    Capture_ByCopy = 0x02
+  };
+
+  llvm::PointerIntPair<Decl *, 2> DeclAndBits;
+  SourceLocation Loc;
+  SourceLocation EllipsisLoc;
+
+  friend class ASTStmtReader;
+  friend class ASTStmtWriter;
+
+public:
+  /// \brief Create a new capture of a variable or of \c this.
+  ///
+  /// \param Loc The source location associated with this capture.
+  ///
+  /// \param Kind The kind of capture (this, byref, bycopy), which must
+  /// not be init-capture.
+  ///
+  /// \param Implicit Whether the capture was implicit or explicit.
+  ///
+  /// \param Var The local variable being captured, or null if capturing
+  /// \c this.
+  ///
+  /// \param EllipsisLoc The location of the ellipsis (...) for a
+  /// capture that is a pack expansion, or an invalid source
+  /// location to indicate that this is not a pack expansion.
+  LambdaCapture(SourceLocation Loc, bool Implicit, LambdaCaptureKind Kind,
+                VarDecl *Var = nullptr,
+                SourceLocation EllipsisLoc = SourceLocation());
+
+  /// \brief Determine the kind of capture.
+  LambdaCaptureKind getCaptureKind() const;
+
+  /// \brief Determine whether this capture handles the C++ \c this
+  /// pointer.
+  bool capturesThis() const { return DeclAndBits.getPointer() == nullptr; }
+
+  /// \brief Determine whether this capture handles a variable.
+  bool capturesVariable() const {
+    return dyn_cast_or_null<VarDecl>(DeclAndBits.getPointer());
+  }
+
+  /// \brief Determine whether this is an init-capture.
+  bool isInitCapture() const {
+    return capturesVariable() && getCapturedVar()->isInitCapture();
+  }
+
+  /// \brief Retrieve the declaration of the local variable being
+  /// captured.
+  ///
+  /// This operation is only valid if this capture is a variable capture
+  /// (other than a capture of \c this).
+  VarDecl *getCapturedVar() const {
+    assert(capturesVariable() && "No variable available for 'this' capture");
+    return cast<VarDecl>(DeclAndBits.getPointer());
+  }
+
+  /// \brief Determine whether this was an implicit capture (not
+  /// written between the square brackets introducing the lambda).
+  bool isImplicit() const { return DeclAndBits.getInt() & Capture_Implicit; }
+
+  /// \brief Determine whether this was an explicit capture (written
+  /// between the square brackets introducing the lambda).
+  bool isExplicit() const { return !isImplicit(); }
+
+  /// \brief Retrieve the source location of the capture.
+  ///
+  /// For an explicit capture, this returns the location of the
+  /// explicit capture in the source. For an implicit capture, this
+  /// returns the location at which the variable or \c this was first
+  /// used.
+  SourceLocation getLocation() const { return Loc; }
+
+  /// \brief Determine whether this capture is a pack expansion,
+  /// which captures a function parameter pack.
+  bool isPackExpansion() const { return EllipsisLoc.isValid(); }
+
+  /// \brief Retrieve the location of the ellipsis for a capture
+  /// that is a pack expansion.
+  SourceLocation getEllipsisLoc() const {
+    assert(isPackExpansion() && "No ellipsis location for a non-expansion");
+    return EllipsisLoc;
+  }
+};
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_AST_LAMBDACAPTURE_H
diff --git a/include/clang/AST/Makefile b/include/clang/AST/Makefile
index ae84bcf..85e6449 100644
--- a/include/clang/AST/Makefile
+++ b/include/clang/AST/Makefile
@@ -1,6 +1,6 @@
 CLANG_LEVEL := ../../..
 TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic
-BUILT_SOURCES = Attrs.inc AttrImpl.inc AttrDump.inc \
+BUILT_SOURCES = Attrs.inc AttrImpl.inc AttrDump.inc AttrVisitor.inc \
                 StmtNodes.inc DeclNodes.inc \
                 CommentNodes.inc CommentHTMLTags.inc \
                 CommentHTMLTagsProperties.inc \
@@ -30,6 +30,12 @@
 	$(Verb) $(ClangTableGen) -gen-clang-attr-dump -o $(call SYSPATH, $@) \
 		-I $(PROJ_SRC_DIR)/../../ $<
 
+$(ObjDir)/AttrVisitor.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
+                                $(ObjDir)/.dir
+	$(Echo) "Building Clang attribute AST visitor with tblgen"
+	$(Verb) $(ClangTableGen) -gen-clang-attr-ast-visitor -o $(call SYSPATH, $@) \
+		-I $(PROJ_SRC_DIR)/../../ $<
+
 $(ObjDir)/StmtNodes.inc.tmp : $(TD_SRC_DIR)/StmtNodes.td $(CLANG_TBLGEN) \
                               $(ObjDir)/.dir
 	$(Echo) "Building Clang statement node tables with tblgen"
diff --git a/include/clang/AST/Mangle.h b/include/clang/AST/Mangle.h
index e875c31..a8d1199 100644
--- a/include/clang/AST/Mangle.h
+++ b/include/clang/AST/Mangle.h
@@ -31,36 +31,10 @@
   class FunctionDecl;
   class NamedDecl;
   class ObjCMethodDecl;
-  class VarDecl;
+  class StringLiteral;
   struct ThisAdjustment;
   struct ThunkInfo;
-
-/// MangleBuffer - a convenient class for storing a name which is
-/// either the result of a mangling or is a constant string with
-/// external memory ownership.
-class MangleBuffer {
-public:
-  void setString(StringRef Ref) {
-    String = Ref;
-  }
-
-  SmallVectorImpl<char> &getBuffer() {
-    return Buffer;
-  }
-
-  StringRef getString() const {
-    if (!String.empty()) return String;
-    return Buffer.str();
-  }
-
-  operator StringRef() const {
-    return getString();
-  }
-
-private:
-  StringRef String;
-  SmallString<256> Buffer;
-};
+  class VarDecl;
 
 /// MangleContext - Context for tracking state which persists across multiple
 /// calls to the C++ name mangler.
@@ -80,6 +54,7 @@
 
   llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds;
   llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
+  llvm::DenseMap<const TagDecl*, uint64_t> AnonStructIds;
 
 public:
   ManglerKind getKind() const { return Kind; }
@@ -104,12 +79,19 @@
       Result = BlockIds.insert(std::make_pair(BD, BlockIds.size()));
     return Result.first->second;
   }
-  
+
+  uint64_t getAnonymousStructId(const TagDecl *TD) {
+    std::pair<llvm::DenseMap<const TagDecl *, uint64_t>::iterator, bool>
+        Result = AnonStructIds.insert(std::make_pair(TD, AnonStructIds.size()));
+    return Result.first->second;
+  }
+
   /// @name Mangler Entry Points
   /// @{
 
   bool shouldMangleDeclName(const NamedDecl *D);
   virtual bool shouldMangleCXXName(const NamedDecl *D) = 0;
+  virtual bool shouldMangleStringLiteral(const StringLiteral *SL) = 0;
 
   // FIXME: consider replacing raw_ostream & with something like SmallString &.
   void mangleName(const NamedDecl *D, raw_ostream &);
@@ -121,6 +103,7 @@
                                   const ThisAdjustment &ThisAdjustment,
                                   raw_ostream &) = 0;
   virtual void mangleReferenceTemporary(const VarDecl *D,
+                                        unsigned ManglingNumber,
                                         raw_ostream &) = 0;
   virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0;
   virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0;
@@ -128,6 +111,7 @@
                              raw_ostream &) = 0;
   virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
                              raw_ostream &) = 0;
+  virtual void mangleStringLiteral(const StringLiteral *SL, raw_ostream &) = 0;
 
   void mangleGlobalBlock(const BlockDecl *BD,
                          const NamedDecl *ID,
@@ -148,6 +132,12 @@
   virtual void mangleDynamicAtExitDestructor(const VarDecl *D,
                                              raw_ostream &) = 0;
 
+  /// Generates a unique string for an externally visible type for use with TBAA
+  /// or type uniquing.
+  /// TODO: Extend this to internal types by generating names that are unique
+  /// across translation units so it can be used with LTO.
+  virtual void mangleTypeName(QualType T, raw_ostream &) = 0;
+
   /// @}
 };
 
@@ -194,7 +184,22 @@
                                 raw_ostream &Out) = 0;
 
   virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
-                                        int OffsetInVFTable, raw_ostream &) = 0;
+                                        raw_ostream &) = 0;
+
+  virtual void mangleCXXRTTIBaseClassDescriptor(
+      const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
+      uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) = 0;
+
+  virtual void mangleCXXRTTIBaseClassArray(const CXXRecordDecl *Derived,
+                                           raw_ostream &Out) = 0;
+  virtual void
+  mangleCXXRTTIClassHierarchyDescriptor(const CXXRecordDecl *Derived,
+                                        raw_ostream &Out) = 0;
+
+  virtual void
+  mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *Derived,
+                                     ArrayRef<const CXXRecordDecl *> BasePath,
+                                     raw_ostream &Out) = 0;
 
   static bool classof(const MangleContext *C) {
     return C->getKind() == MK_Microsoft;
diff --git a/include/clang/AST/MangleNumberingContext.h b/include/clang/AST/MangleNumberingContext.h
index 5a227f2..56c9952 100644
--- a/include/clang/AST/MangleNumberingContext.h
+++ b/include/clang/AST/MangleNumberingContext.h
@@ -33,7 +33,6 @@
 class MangleNumberingContext 
     : public RefCountedBase<MangleNumberingContext> {
   llvm::DenseMap<const Type *, unsigned> ManglingNumbers;
-  llvm::DenseMap<IdentifierInfo*, unsigned> TagManglingNumbers;
 
 public:
   virtual ~MangleNumberingContext() {}
@@ -46,13 +45,18 @@
   /// context.
   unsigned getManglingNumber(const BlockDecl *BD);
 
-  /// \brief Retrieve the mangling number of a static local variable within
-  /// this context.
-  virtual unsigned getManglingNumber(const VarDecl *VD) = 0;
+  /// Static locals are numbered by source order.
+  unsigned getStaticLocalNumber(const VarDecl *VD);
 
   /// \brief Retrieve the mangling number of a static local variable within
   /// this context.
-  unsigned getManglingNumber(const TagDecl *TD);
+  virtual unsigned getManglingNumber(const VarDecl *VD,
+                                     unsigned MSLocalManglingNumber) = 0;
+
+  /// \brief Retrieve the mangling number of a static local variable within
+  /// this context.
+  virtual unsigned getManglingNumber(const TagDecl *TD,
+                                     unsigned MSLocalManglingNumber) = 0;
 };
   
 } // end namespace clang
diff --git a/include/clang/AST/NestedNameSpecifier.h b/include/clang/AST/NestedNameSpecifier.h
index b332b15..fc719bd 100644
--- a/include/clang/AST/NestedNameSpecifier.h
+++ b/include/clang/AST/NestedNameSpecifier.h
@@ -88,7 +88,8 @@
 
 private:
   /// \brief Builds the global specifier.
-  NestedNameSpecifier() : Prefix(0, StoredIdentifier), Specifier(0) { }
+  NestedNameSpecifier()
+    : Prefix(nullptr, StoredIdentifier), Specifier(nullptr) {}
 
   /// \brief Copy constructor used internally to clone nested name
   /// specifiers.
@@ -160,7 +161,7 @@
     if (Prefix.getInt() == StoredIdentifier)
       return (IdentifierInfo *)Specifier;
 
-    return 0;
+    return nullptr;
   }
 
   /// \brief Retrieve the namespace stored in this nested name
@@ -177,7 +178,7 @@
         Prefix.getInt() == StoredTypeSpecWithTemplate)
       return (const Type *)Specifier;
 
-    return 0;
+    return nullptr;
   }
 
   /// \brief Whether this nested name specifier refers to a dependent
@@ -222,7 +223,7 @@
 
 public:
   /// \brief Construct an empty nested-name-specifier.
-  NestedNameSpecifierLoc() : Qualifier(0), Data(0) { }
+  NestedNameSpecifierLoc() : Qualifier(nullptr), Data(nullptr) { }
 
   /// \brief Construct a nested-name-specifier with source location information
   /// from
@@ -344,7 +345,8 @@
 
 public:
   NestedNameSpecifierLocBuilder()
-    : Representation(0), Buffer(0), BufferSize(0), BufferCapacity(0) { }
+    : Representation(nullptr), Buffer(nullptr), BufferSize(0),
+      BufferCapacity(0) {}
 
   NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other);
 
@@ -457,7 +459,7 @@
   /// \brief Clear out this builder, and prepare it to build another
   /// nested-name-specifier with source-location information.
   void Clear() {
-    Representation = 0;
+    Representation = nullptr;
     BufferSize = 0;
   }
 
diff --git a/include/clang/AST/OpenMPClause.h b/include/clang/AST/OpenMPClause.h
new file mode 100644
index 0000000..3345959
--- /dev/null
+++ b/include/clang/AST/OpenMPClause.h
@@ -0,0 +1,1455 @@
+//===- OpenMPClause.h - Classes for OpenMP clauses --------------*- 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 OpenMP AST classes for clauses.
+/// There are clauses for executable directives, clauses for declarative
+/// directives and clauses which can be used in both kinds of directives.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_OPENMPCLAUSE_H
+#define LLVM_CLANG_AST_OPENMPCLAUSE_H
+
+#include "clang/AST/Expr.h"
+#include "clang/AST/Stmt.h"
+#include "clang/Basic/OpenMPKinds.h"
+#include "clang/Basic/SourceLocation.h"
+
+namespace clang {
+
+//===----------------------------------------------------------------------===//
+// AST classes for clauses.
+//===----------------------------------------------------------------------===//
+
+/// \brief This is a basic class for representing single OpenMP clause.
+///
+class OMPClause {
+  /// \brief Starting location of the clause (the clause keyword).
+  SourceLocation StartLoc;
+  /// \brief Ending location of the clause.
+  SourceLocation EndLoc;
+  /// \brief Kind of the clause.
+  OpenMPClauseKind Kind;
+
+protected:
+  OMPClause(OpenMPClauseKind K, SourceLocation StartLoc, SourceLocation EndLoc)
+      : StartLoc(StartLoc), EndLoc(EndLoc), Kind(K) {}
+
+public:
+  /// \brief Returns the starting location of the clause.
+  SourceLocation getLocStart() const { return StartLoc; }
+  /// \brief Returns the ending location of the clause.
+  SourceLocation getLocEnd() const { return EndLoc; }
+
+  /// \brief Sets the starting location of the clause.
+  void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
+  /// \brief Sets the ending location of the clause.
+  void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
+
+  /// \brief Returns kind of OpenMP clause (private, shared, reduction, etc.).
+  OpenMPClauseKind getClauseKind() const { return Kind; }
+
+  bool isImplicit() const { return StartLoc.isInvalid(); }
+
+  StmtRange children();
+  ConstStmtRange children() const {
+    return const_cast<OMPClause *>(this)->children();
+  }
+  static bool classof(const OMPClause *T) { return true; }
+};
+
+/// \brief This represents clauses with the list of variables like 'private',
+/// 'firstprivate', 'copyin', 'shared', or 'reduction' clauses in the
+/// '#pragma omp ...' directives.
+template <class T> class OMPVarListClause : public OMPClause {
+  friend class OMPClauseReader;
+  /// \brief Location of '('.
+  SourceLocation LParenLoc;
+  /// \brief Number of variables in the list.
+  unsigned NumVars;
+
+protected:
+  /// \brief Fetches list of variables associated with this clause.
+  MutableArrayRef<Expr *> getVarRefs() {
+    return MutableArrayRef<Expr *>(
+        reinterpret_cast<Expr **>(
+            reinterpret_cast<char *>(this) +
+            llvm::RoundUpToAlignment(sizeof(T), llvm::alignOf<Expr *>())),
+        NumVars);
+  }
+
+  /// \brief Sets the list of variables for this clause.
+  void setVarRefs(ArrayRef<Expr *> VL) {
+    assert(VL.size() == NumVars &&
+           "Number of variables is not the same as the preallocated buffer");
+    std::copy(
+        VL.begin(), VL.end(),
+        reinterpret_cast<Expr **>(
+            reinterpret_cast<char *>(this) +
+            llvm::RoundUpToAlignment(sizeof(T), llvm::alignOf<Expr *>())));
+  }
+
+  /// \brief Build a clause with \a N variables
+  ///
+  /// \param K Kind of the clause.
+  /// \param StartLoc Starting location of the clause (the clause keyword).
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param N Number of the variables in the clause.
+  ///
+  OMPVarListClause(OpenMPClauseKind K, SourceLocation StartLoc,
+                   SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N)
+      : OMPClause(K, StartLoc, EndLoc), LParenLoc(LParenLoc), NumVars(N) {}
+
+public:
+  typedef MutableArrayRef<Expr *>::iterator varlist_iterator;
+  typedef ArrayRef<const Expr *>::iterator varlist_const_iterator;
+  typedef llvm::iterator_range<varlist_iterator> varlist_range;
+  typedef llvm::iterator_range<varlist_const_iterator> varlist_const_range;
+
+  unsigned varlist_size() const { return NumVars; }
+  bool varlist_empty() const { return NumVars == 0; }
+
+  varlist_range varlists() {
+    return varlist_range(varlist_begin(), varlist_end());
+  }
+  varlist_const_range varlists() const {
+    return varlist_const_range(varlist_begin(), varlist_end());
+  }
+
+  varlist_iterator varlist_begin() { return getVarRefs().begin(); }
+  varlist_iterator varlist_end() { return getVarRefs().end(); }
+  varlist_const_iterator varlist_begin() const { return getVarRefs().begin(); }
+  varlist_const_iterator varlist_end() const { return getVarRefs().end(); }
+
+  /// \brief Sets the location of '('.
+  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+  /// \brief Returns the location of '('.
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+
+  /// \brief Fetches list of all variables in the clause.
+  ArrayRef<const Expr *> getVarRefs() const {
+    return ArrayRef<const Expr *>(
+        reinterpret_cast<const Expr *const *>(
+            reinterpret_cast<const char *>(this) +
+            llvm::RoundUpToAlignment(sizeof(T), llvm::alignOf<Expr *>())),
+        NumVars);
+  }
+};
+
+/// \brief This represents 'if' clause in the '#pragma omp ...' directive.
+///
+/// \code
+/// #pragma omp parallel if(a > 5)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has simple 'if'
+/// clause with condition 'a > 5'.
+///
+class OMPIfClause : public OMPClause {
+  friend class OMPClauseReader;
+  /// \brief Location of '('.
+  SourceLocation LParenLoc;
+  /// \brief Condition of the 'if' clause.
+  Stmt *Condition;
+
+  /// \brief Set condition.
+  ///
+  void setCondition(Expr *Cond) { Condition = Cond; }
+
+public:
+  /// \brief Build 'if' clause with condition \a Cond.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param Cond Condition of the clause.
+  /// \param EndLoc Ending location of the clause.
+  ///
+  OMPIfClause(Expr *Cond, SourceLocation StartLoc, SourceLocation LParenLoc,
+              SourceLocation EndLoc)
+      : OMPClause(OMPC_if, StartLoc, EndLoc), LParenLoc(LParenLoc),
+        Condition(Cond) {}
+
+  /// \brief Build an empty clause.
+  ///
+  OMPIfClause()
+      : OMPClause(OMPC_if, SourceLocation(), SourceLocation()),
+        LParenLoc(SourceLocation()), Condition(nullptr) {}
+
+  /// \brief Sets the location of '('.
+  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+  /// \brief Returns the location of '('.
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+
+  /// \brief Returns condition.
+  Expr *getCondition() const { return cast_or_null<Expr>(Condition); }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_if;
+  }
+
+  StmtRange children() { return StmtRange(&Condition, &Condition + 1); }
+};
+
+/// \brief This represents 'final' clause in the '#pragma omp ...' directive.
+///
+/// \code
+/// #pragma omp task final(a > 5)
+/// \endcode
+/// In this example directive '#pragma omp task' has simple 'final'
+/// clause with condition 'a > 5'.
+///
+class OMPFinalClause : public OMPClause {
+  friend class OMPClauseReader;
+  /// \brief Location of '('.
+  SourceLocation LParenLoc;
+  /// \brief Condition of the 'if' clause.
+  Stmt *Condition;
+
+  /// \brief Set condition.
+  ///
+  void setCondition(Expr *Cond) { Condition = Cond; }
+
+public:
+  /// \brief Build 'final' clause with condition \a Cond.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param Cond Condition of the clause.
+  /// \param EndLoc Ending location of the clause.
+  ///
+  OMPFinalClause(Expr *Cond, SourceLocation StartLoc, SourceLocation LParenLoc,
+                 SourceLocation EndLoc)
+      : OMPClause(OMPC_final, StartLoc, EndLoc), LParenLoc(LParenLoc),
+        Condition(Cond) {}
+
+  /// \brief Build an empty clause.
+  ///
+  OMPFinalClause()
+      : OMPClause(OMPC_final, SourceLocation(), SourceLocation()),
+        LParenLoc(SourceLocation()), Condition(nullptr) {}
+
+  /// \brief Sets the location of '('.
+  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+  /// \brief Returns the location of '('.
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+
+  /// \brief Returns condition.
+  Expr *getCondition() const { return cast_or_null<Expr>(Condition); }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_final;
+  }
+
+  StmtRange children() { return StmtRange(&Condition, &Condition + 1); }
+};
+
+/// \brief This represents 'num_threads' clause in the '#pragma omp ...'
+/// directive.
+///
+/// \code
+/// #pragma omp parallel num_threads(6)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has simple 'num_threads'
+/// clause with number of threads '6'.
+///
+class OMPNumThreadsClause : public OMPClause {
+  friend class OMPClauseReader;
+  /// \brief Location of '('.
+  SourceLocation LParenLoc;
+  /// \brief Condition of the 'num_threads' clause.
+  Stmt *NumThreads;
+
+  /// \brief Set condition.
+  ///
+  void setNumThreads(Expr *NThreads) { NumThreads = NThreads; }
+
+public:
+  /// \brief Build 'num_threads' clause with condition \a NumThreads.
+  ///
+  /// \param NumThreads Number of threads for the construct.
+  /// \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) {}
+
+  /// \brief Build an empty clause.
+  ///
+  OMPNumThreadsClause()
+      : OMPClause(OMPC_num_threads, SourceLocation(), SourceLocation()),
+        LParenLoc(SourceLocation()), NumThreads(nullptr) {}
+
+  /// \brief Sets the location of '('.
+  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+  /// \brief Returns the location of '('.
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+
+  /// \brief Returns number of threads.
+  Expr *getNumThreads() const { return cast_or_null<Expr>(NumThreads); }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_num_threads;
+  }
+
+  StmtRange children() { return StmtRange(&NumThreads, &NumThreads + 1); }
+};
+
+/// \brief This represents 'safelen' clause in the '#pragma omp ...'
+/// directive.
+///
+/// \code
+/// #pragma omp simd safelen(4)
+/// \endcode
+/// In this example directive '#pragma omp simd' has clause 'safelen'
+/// with single expression '4'.
+/// If the safelen clause is used then no two iterations executed
+/// concurrently with SIMD instructions can have a greater distance
+/// in the logical iteration space than its value. The parameter of
+/// the safelen clause must be a constant positive integer expression.
+///
+class OMPSafelenClause : public OMPClause {
+  friend class OMPClauseReader;
+  /// \brief Location of '('.
+  SourceLocation LParenLoc;
+  /// \brief Safe iteration space distance.
+  Stmt *Safelen;
+
+  /// \brief Set safelen.
+  void setSafelen(Expr *Len) { Safelen = Len; }
+
+public:
+  /// \brief Build 'safelen' clause.
+  ///
+  /// \param Len Expression associated with this clause.
+  /// \param StartLoc Starting location of the clause.
+  /// \param EndLoc Ending location of the clause.
+  ///
+  OMPSafelenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc,
+                   SourceLocation EndLoc)
+      : OMPClause(OMPC_safelen, StartLoc, EndLoc), LParenLoc(LParenLoc),
+        Safelen(Len) {}
+
+  /// \brief Build an empty clause.
+  ///
+  explicit OMPSafelenClause()
+      : OMPClause(OMPC_safelen, SourceLocation(), SourceLocation()),
+        LParenLoc(SourceLocation()), Safelen(nullptr) {}
+
+  /// \brief Sets the location of '('.
+  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+  /// \brief Returns the location of '('.
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+
+  /// \brief Return safe iteration space distance.
+  Expr *getSafelen() const { return cast_or_null<Expr>(Safelen); }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_safelen;
+  }
+
+  StmtRange children() { return StmtRange(&Safelen, &Safelen + 1); }
+};
+
+/// \brief This represents 'collapse' clause in the '#pragma omp ...'
+/// directive.
+///
+/// \code
+/// #pragma omp simd collapse(3)
+/// \endcode
+/// In this example directive '#pragma omp simd' has clause 'collapse'
+/// with single expression '3'.
+/// The parameter must be a constant positive integer expression, it specifies
+/// the number of nested loops that should be collapsed into a single iteration
+/// space.
+///
+class OMPCollapseClause : public OMPClause {
+  friend class OMPClauseReader;
+  /// \brief Location of '('.
+  SourceLocation LParenLoc;
+  /// \brief Number of for-loops.
+  Stmt *NumForLoops;
+
+  /// \brief Set the number of associated for-loops.
+  void setNumForLoops(Expr *Num) { NumForLoops = Num; }
+
+public:
+  /// \brief Build 'collapse' clause.
+  ///
+  /// \param Num Expression associated with this clause.
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  ///
+  OMPCollapseClause(Expr *Num, SourceLocation StartLoc,
+                    SourceLocation LParenLoc, SourceLocation EndLoc)
+      : OMPClause(OMPC_collapse, StartLoc, EndLoc), LParenLoc(LParenLoc),
+        NumForLoops(Num) {}
+
+  /// \brief Build an empty clause.
+  ///
+  explicit OMPCollapseClause()
+      : OMPClause(OMPC_collapse, SourceLocation(), SourceLocation()),
+        LParenLoc(SourceLocation()), NumForLoops(nullptr) {}
+
+  /// \brief Sets the location of '('.
+  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+  /// \brief Returns the location of '('.
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+
+  /// \brief Return the number of associated for-loops.
+  Expr *getNumForLoops() const { return cast_or_null<Expr>(NumForLoops); }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_collapse;
+  }
+
+  StmtRange children() { return StmtRange(&NumForLoops, &NumForLoops + 1); }
+};
+
+/// \brief This represents 'default' clause in the '#pragma omp ...' directive.
+///
+/// \code
+/// #pragma omp parallel default(shared)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has simple 'default'
+/// clause with kind 'shared'.
+///
+class OMPDefaultClause : public OMPClause {
+  friend class OMPClauseReader;
+  /// \brief Location of '('.
+  SourceLocation LParenLoc;
+  /// \brief A kind of the 'default' clause.
+  OpenMPDefaultClauseKind Kind;
+  /// \brief Start location of the kind in source code.
+  SourceLocation KindKwLoc;
+
+  /// \brief Set kind of the clauses.
+  ///
+  /// \param K Argument of clause.
+  ///
+  void setDefaultKind(OpenMPDefaultClauseKind K) { Kind = K; }
+
+  /// \brief Set argument location.
+  ///
+  /// \param KLoc Argument location.
+  ///
+  void setDefaultKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; }
+
+public:
+  /// \brief Build 'default' clause with argument \a A ('none' or 'shared').
+  ///
+  /// \param A Argument of the clause ('none' or 'shared').
+  /// \param ALoc Starting location of the argument.
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  ///
+  OMPDefaultClause(OpenMPDefaultClauseKind A, SourceLocation ALoc,
+                   SourceLocation StartLoc, SourceLocation LParenLoc,
+                   SourceLocation EndLoc)
+      : OMPClause(OMPC_default, StartLoc, EndLoc), LParenLoc(LParenLoc),
+        Kind(A), KindKwLoc(ALoc) {}
+
+  /// \brief Build an empty clause.
+  ///
+  OMPDefaultClause()
+      : OMPClause(OMPC_default, SourceLocation(), SourceLocation()),
+        LParenLoc(SourceLocation()), Kind(OMPC_DEFAULT_unknown),
+        KindKwLoc(SourceLocation()) {}
+
+  /// \brief Sets the location of '('.
+  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+  /// \brief Returns the location of '('.
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+
+  /// \brief Returns kind of the clause.
+  OpenMPDefaultClauseKind getDefaultKind() const { return Kind; }
+
+  /// \brief Returns location of clause kind.
+  SourceLocation getDefaultKindKwLoc() const { return KindKwLoc; }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_default;
+  }
+
+  StmtRange children() { return StmtRange(); }
+};
+
+/// \brief This represents 'proc_bind' clause in the '#pragma omp ...'
+/// directive.
+///
+/// \code
+/// #pragma omp parallel proc_bind(master)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has simple 'proc_bind'
+/// clause with kind 'master'.
+///
+class OMPProcBindClause : public OMPClause {
+  friend class OMPClauseReader;
+  /// \brief Location of '('.
+  SourceLocation LParenLoc;
+  /// \brief A kind of the 'proc_bind' clause.
+  OpenMPProcBindClauseKind Kind;
+  /// \brief Start location of the kind in source code.
+  SourceLocation KindKwLoc;
+
+  /// \brief Set kind of the clause.
+  ///
+  /// \param K Kind of clause.
+  ///
+  void setProcBindKind(OpenMPProcBindClauseKind K) { Kind = K; }
+
+  /// \brief Set clause kind location.
+  ///
+  /// \param KLoc Kind location.
+  ///
+  void setProcBindKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; }
+
+public:
+  /// \brief Build 'proc_bind' clause with argument \a A ('master', 'close' or
+  ///        'spread').
+  ///
+  /// \param A Argument of the clause ('master', 'close' or 'spread').
+  /// \param ALoc Starting location of the argument.
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  ///
+  OMPProcBindClause(OpenMPProcBindClauseKind A, SourceLocation ALoc,
+                    SourceLocation StartLoc, SourceLocation LParenLoc,
+                    SourceLocation EndLoc)
+      : OMPClause(OMPC_proc_bind, StartLoc, EndLoc), LParenLoc(LParenLoc),
+        Kind(A), KindKwLoc(ALoc) {}
+
+  /// \brief Build an empty clause.
+  ///
+  OMPProcBindClause()
+      : OMPClause(OMPC_proc_bind, SourceLocation(), SourceLocation()),
+        LParenLoc(SourceLocation()), Kind(OMPC_PROC_BIND_unknown),
+        KindKwLoc(SourceLocation()) {}
+
+  /// \brief Sets the location of '('.
+  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+  /// \brief Returns the location of '('.
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+
+  /// \brief Returns kind of the clause.
+  OpenMPProcBindClauseKind getProcBindKind() const { return Kind; }
+
+  /// \brief Returns location of clause kind.
+  SourceLocation getProcBindKindKwLoc() const { return KindKwLoc; }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_proc_bind;
+  }
+
+  StmtRange children() { return StmtRange(); }
+};
+
+/// \brief This represents 'schedule' clause in the '#pragma omp ...' directive.
+///
+/// \code
+/// #pragma omp for schedule(static, 3)
+/// \endcode
+/// In this example directive '#pragma omp for' has 'schedule' clause with
+/// arguments 'static' and '3'.
+///
+class OMPScheduleClause : public OMPClause {
+  friend class OMPClauseReader;
+  /// \brief Location of '('.
+  SourceLocation LParenLoc;
+  /// \brief A kind of the 'schedule' clause.
+  OpenMPScheduleClauseKind Kind;
+  /// \brief Start location of the schedule ind in source code.
+  SourceLocation KindLoc;
+  /// \brief Location of ',' (if any).
+  SourceLocation CommaLoc;
+  /// \brief Chunk size.
+  Stmt *ChunkSize;
+
+  /// \brief Set schedule kind.
+  ///
+  /// \param K Schedule kind.
+  ///
+  void setScheduleKind(OpenMPScheduleClauseKind K) { Kind = K; }
+  /// \brief Sets the location of '('.
+  ///
+  /// \param Loc Location of '('.
+  ///
+  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+  /// \brief Set schedule kind start location.
+  ///
+  /// \param KLoc Schedule kind location.
+  ///
+  void setScheduleKindLoc(SourceLocation KLoc) { KindLoc = KLoc; }
+  /// \brief Set location of ','.
+  ///
+  /// \param Loc Location of ','.
+  ///
+  void setCommaLoc(SourceLocation Loc) { CommaLoc = Loc; }
+  /// \brief Set chunk size.
+  ///
+  /// \param E Chunk size.
+  ///
+  void setChunkSize(Expr *E) { ChunkSize = E; }
+
+public:
+  /// \brief Build 'schedule' clause with schedule kind \a Kind and chunk size
+  /// expression \a ChunkSize.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param KLoc Starting location of the argument.
+  /// \param CommaLoc Location of ','.
+  /// \param EndLoc Ending location of the clause.
+  /// \param Kind Schedule kind.
+  /// \param ChunkSize Chunk size.
+  ///
+  OMPScheduleClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+                    SourceLocation KLoc, SourceLocation CommaLoc,
+                    SourceLocation EndLoc, OpenMPScheduleClauseKind Kind,
+                    Expr *ChunkSize)
+      : OMPClause(OMPC_schedule, StartLoc, EndLoc), LParenLoc(LParenLoc),
+        Kind(Kind), KindLoc(KLoc), CommaLoc(CommaLoc), ChunkSize(ChunkSize) {}
+
+  /// \brief Build an empty clause.
+  ///
+  explicit OMPScheduleClause()
+      : OMPClause(OMPC_schedule, SourceLocation(), SourceLocation()),
+        Kind(OMPC_SCHEDULE_unknown), ChunkSize(nullptr) {}
+
+  /// \brief Get kind of the clause.
+  ///
+  OpenMPScheduleClauseKind getScheduleKind() const { return Kind; }
+  /// \brief Get location of '('.
+  ///
+  SourceLocation getLParenLoc() { return LParenLoc; }
+  /// \brief Get kind location.
+  ///
+  SourceLocation getScheduleKindLoc() { return KindLoc; }
+  /// \brief Get location of ','.
+  ///
+  SourceLocation getCommaLoc() { return CommaLoc; }
+  /// \brief Get chunk size.
+  ///
+  Expr *getChunkSize() { return dyn_cast_or_null<Expr>(ChunkSize); }
+  /// \brief Get chunk size.
+  ///
+  Expr *getChunkSize() const { return dyn_cast_or_null<Expr>(ChunkSize); }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_schedule;
+  }
+
+  StmtRange children() { return StmtRange(&ChunkSize, &ChunkSize + 1); }
+};
+
+/// \brief This represents 'ordered' clause in the '#pragma omp ...' directive.
+///
+/// \code
+/// #pragma omp for ordered
+/// \endcode
+/// In this example directive '#pragma omp for' has 'ordered' clause.
+///
+class OMPOrderedClause : public OMPClause {
+public:
+  /// \brief Build 'ordered' clause.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param EndLoc Ending location of the clause.
+  ///
+  OMPOrderedClause(SourceLocation StartLoc, SourceLocation EndLoc)
+      : OMPClause(OMPC_ordered, StartLoc, EndLoc) {}
+
+  /// \brief Build an empty clause.
+  ///
+  OMPOrderedClause()
+      : OMPClause(OMPC_ordered, SourceLocation(), SourceLocation()) {}
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_ordered;
+  }
+
+  StmtRange children() { return StmtRange(); }
+};
+
+/// \brief This represents 'nowait' clause in the '#pragma omp ...' directive.
+///
+/// \code
+/// #pragma omp for nowait
+/// \endcode
+/// In this example directive '#pragma omp for' has 'nowait' clause.
+///
+class OMPNowaitClause : public OMPClause {
+public:
+  /// \brief Build 'nowait' clause.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param EndLoc Ending location of the clause.
+  ///
+  OMPNowaitClause(SourceLocation StartLoc, SourceLocation EndLoc)
+      : OMPClause(OMPC_nowait, StartLoc, EndLoc) {}
+
+  /// \brief Build an empty clause.
+  ///
+  OMPNowaitClause()
+      : OMPClause(OMPC_nowait, SourceLocation(), SourceLocation()) {}
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_nowait;
+  }
+
+  StmtRange children() { return StmtRange(); }
+};
+
+/// \brief This represents 'untied' clause in the '#pragma omp ...' directive.
+///
+/// \code
+/// #pragma omp task untied
+/// \endcode
+/// In this example directive '#pragma omp task' has 'untied' clause.
+///
+class OMPUntiedClause : public OMPClause {
+public:
+  /// \brief Build 'untied' clause.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param EndLoc Ending location of the clause.
+  ///
+  OMPUntiedClause(SourceLocation StartLoc, SourceLocation EndLoc)
+      : OMPClause(OMPC_untied, StartLoc, EndLoc) {}
+
+  /// \brief Build an empty clause.
+  ///
+  OMPUntiedClause()
+      : OMPClause(OMPC_untied, SourceLocation(), SourceLocation()) {}
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_untied;
+  }
+
+  StmtRange children() { return StmtRange(); }
+};
+
+/// \brief This represents 'mergeable' clause in the '#pragma omp ...'
+/// directive.
+///
+/// \code
+/// #pragma omp task mergeable
+/// \endcode
+/// In this example directive '#pragma omp task' has 'mergeable' clause.
+///
+class OMPMergeableClause : public OMPClause {
+public:
+  /// \brief Build 'mergeable' clause.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param EndLoc Ending location of the clause.
+  ///
+  OMPMergeableClause(SourceLocation StartLoc, SourceLocation EndLoc)
+      : OMPClause(OMPC_mergeable, StartLoc, EndLoc) {}
+
+  /// \brief Build an empty clause.
+  ///
+  OMPMergeableClause()
+      : OMPClause(OMPC_mergeable, SourceLocation(), SourceLocation()) {}
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_mergeable;
+  }
+
+  StmtRange children() { return StmtRange(); }
+};
+
+/// \brief This represents clause 'private' in the '#pragma omp ...' directives.
+///
+/// \code
+/// #pragma omp parallel private(a,b)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has clause 'private'
+/// with the variables 'a' and 'b'.
+///
+class OMPPrivateClause : public OMPVarListClause<OMPPrivateClause> {
+  /// \brief Build clause with number of variables \a N.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param N Number of the variables in the clause.
+  ///
+  OMPPrivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+                   SourceLocation EndLoc, unsigned N)
+      : OMPVarListClause<OMPPrivateClause>(OMPC_private, StartLoc, LParenLoc,
+                                           EndLoc, N) {}
+
+  /// \brief Build an empty clause.
+  ///
+  /// \param N Number of variables.
+  ///
+  explicit OMPPrivateClause(unsigned N)
+      : OMPVarListClause<OMPPrivateClause>(OMPC_private, SourceLocation(),
+                                           SourceLocation(), SourceLocation(),
+                                           N) {}
+
+public:
+  /// \brief Creates clause with a list of variables \a VL.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param VL List of references to the variables.
+  ///
+  static OMPPrivateClause *Create(const ASTContext &C, SourceLocation StartLoc,
+                                  SourceLocation LParenLoc,
+                                  SourceLocation EndLoc, ArrayRef<Expr *> VL);
+  /// \brief Creates an empty clause with the place for \a N variables.
+  ///
+  /// \param C AST context.
+  /// \param N The number of variables.
+  ///
+  static OMPPrivateClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+  StmtRange children() {
+    return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+                     reinterpret_cast<Stmt **>(varlist_end()));
+  }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_private;
+  }
+};
+
+/// \brief This represents clause 'firstprivate' in the '#pragma omp ...'
+/// directives.
+///
+/// \code
+/// #pragma omp parallel firstprivate(a,b)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has clause 'firstprivate'
+/// with the variables 'a' and 'b'.
+///
+class OMPFirstprivateClause : public OMPVarListClause<OMPFirstprivateClause> {
+  /// \brief Build clause with number of variables \a N.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param N Number of the variables in the clause.
+  ///
+  OMPFirstprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+                        SourceLocation EndLoc, unsigned N)
+      : OMPVarListClause<OMPFirstprivateClause>(OMPC_firstprivate, StartLoc,
+                                                LParenLoc, EndLoc, N) {}
+
+  /// \brief Build an empty clause.
+  ///
+  /// \param N Number of variables.
+  ///
+  explicit OMPFirstprivateClause(unsigned N)
+      : OMPVarListClause<OMPFirstprivateClause>(
+            OMPC_firstprivate, SourceLocation(), SourceLocation(),
+            SourceLocation(), N) {}
+
+public:
+  /// \brief Creates clause with a list of variables \a VL.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param VL List of references to the variables.
+  ///
+  static OMPFirstprivateClause *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
+         SourceLocation EndLoc, ArrayRef<Expr *> VL);
+  /// \brief Creates an empty clause with the place for \a N variables.
+  ///
+  /// \param C AST context.
+  /// \param N The number of variables.
+  ///
+  static OMPFirstprivateClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+  StmtRange children() {
+    return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+                     reinterpret_cast<Stmt **>(varlist_end()));
+  }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_firstprivate;
+  }
+};
+
+/// \brief This represents clause 'lastprivate' in the '#pragma omp ...'
+/// directives.
+///
+/// \code
+/// #pragma omp simd lastprivate(a,b)
+/// \endcode
+/// In this example directive '#pragma omp simd' has clause 'lastprivate'
+/// with the variables 'a' and 'b'.
+///
+class OMPLastprivateClause : public OMPVarListClause<OMPLastprivateClause> {
+  /// \brief Build clause with number of variables \a N.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param N Number of the variables in the clause.
+  ///
+  OMPLastprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+                       SourceLocation EndLoc, unsigned N)
+      : OMPVarListClause<OMPLastprivateClause>(OMPC_lastprivate, StartLoc,
+                                               LParenLoc, EndLoc, N) {}
+
+  /// \brief Build an empty clause.
+  ///
+  /// \param N Number of variables.
+  ///
+  explicit OMPLastprivateClause(unsigned N)
+      : OMPVarListClause<OMPLastprivateClause>(
+            OMPC_lastprivate, SourceLocation(), SourceLocation(),
+            SourceLocation(), N) {}
+
+public:
+  /// \brief Creates clause with a list of variables \a VL.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param VL List of references to the variables.
+  ///
+  static OMPLastprivateClause *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
+         SourceLocation EndLoc, ArrayRef<Expr *> VL);
+  /// \brief Creates an empty clause with the place for \a N variables.
+  ///
+  /// \param C AST context.
+  /// \param N The number of variables.
+  ///
+  static OMPLastprivateClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+  StmtRange children() {
+    return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+                     reinterpret_cast<Stmt **>(varlist_end()));
+  }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_lastprivate;
+  }
+};
+
+/// \brief This represents clause 'shared' in the '#pragma omp ...' directives.
+///
+/// \code
+/// #pragma omp parallel shared(a,b)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has clause 'shared'
+/// with the variables 'a' and 'b'.
+///
+class OMPSharedClause : public OMPVarListClause<OMPSharedClause> {
+  /// \brief Build clause with number of variables \a N.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param N Number of the variables in the clause.
+  ///
+  OMPSharedClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+                  SourceLocation EndLoc, unsigned N)
+      : OMPVarListClause<OMPSharedClause>(OMPC_shared, StartLoc, LParenLoc,
+                                          EndLoc, N) {}
+
+  /// \brief Build an empty clause.
+  ///
+  /// \param N Number of variables.
+  ///
+  explicit OMPSharedClause(unsigned N)
+      : OMPVarListClause<OMPSharedClause>(OMPC_shared, SourceLocation(),
+                                          SourceLocation(), SourceLocation(),
+                                          N) {}
+
+public:
+  /// \brief Creates clause with a list of variables \a VL.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param VL List of references to the variables.
+  ///
+  static OMPSharedClause *Create(const ASTContext &C, SourceLocation StartLoc,
+                                 SourceLocation LParenLoc,
+                                 SourceLocation EndLoc, ArrayRef<Expr *> VL);
+  /// \brief Creates an empty clause with \a N variables.
+  ///
+  /// \param C AST context.
+  /// \param N The number of variables.
+  ///
+  static OMPSharedClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+  StmtRange children() {
+    return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+                     reinterpret_cast<Stmt **>(varlist_end()));
+  }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_shared;
+  }
+};
+
+/// \brief This represents clause 'reduction' in the '#pragma omp ...'
+/// directives.
+///
+/// \code
+/// #pragma omp parallel reduction(+:a,b)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has clause 'reduction'
+/// with operator '+' and the variables 'a' and 'b'.
+///
+class OMPReductionClause : public OMPVarListClause<OMPReductionClause> {
+  friend class OMPClauseReader;
+  /// \brief Location of ':'.
+  SourceLocation ColonLoc;
+  /// \brief Nested name specifier for C++.
+  NestedNameSpecifierLoc QualifierLoc;
+  /// \brief Name of custom operator.
+  DeclarationNameInfo NameInfo;
+
+  /// \brief Build clause with number of variables \a N.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param ColonLoc Location of ':'.
+  /// \param N Number of the variables in the clause.
+  /// \param QualifierLoc The nested-name qualifier with location information
+  /// \param NameInfo The full name info for reduction identifier.
+  ///
+  OMPReductionClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+                     SourceLocation ColonLoc, SourceLocation EndLoc, unsigned N,
+                     NestedNameSpecifierLoc QualifierLoc,
+                     const DeclarationNameInfo &NameInfo)
+      : OMPVarListClause<OMPReductionClause>(OMPC_reduction, StartLoc,
+                                             LParenLoc, EndLoc, N),
+        ColonLoc(ColonLoc), QualifierLoc(QualifierLoc), NameInfo(NameInfo) {}
+
+  /// \brief Build an empty clause.
+  ///
+  /// \param N Number of variables.
+  ///
+  explicit OMPReductionClause(unsigned N)
+      : OMPVarListClause<OMPReductionClause>(OMPC_reduction, SourceLocation(),
+                                             SourceLocation(), SourceLocation(),
+                                             N),
+        ColonLoc(), QualifierLoc(), NameInfo() {}
+
+  /// \brief Sets location of ':' symbol in clause.
+  void setColonLoc(SourceLocation CL) { ColonLoc = CL; }
+  /// \brief Sets the name info for specified reduction identifier.
+  void setNameInfo(DeclarationNameInfo DNI) { NameInfo = DNI; }
+  /// \brief Sets the nested name specifier.
+  void setQualifierLoc(NestedNameSpecifierLoc NSL) { QualifierLoc = NSL; }
+
+public:
+  /// \brief Creates clause with a list of variables \a VL.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param ColonLoc Location of ':'.
+  /// \param EndLoc Ending location of the clause.
+  /// \param VL The variables in the clause.
+  /// \param QualifierLoc The nested-name qualifier with location information
+  /// \param NameInfo The full name info for reduction identifier.
+  ///
+  static OMPReductionClause *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
+         SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL,
+         NestedNameSpecifierLoc QualifierLoc,
+         const DeclarationNameInfo &NameInfo);
+  /// \brief Creates an empty clause with the place for \a N variables.
+  ///
+  /// \param C AST context.
+  /// \param N The number of variables.
+  ///
+  static OMPReductionClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+  /// \brief Gets location of ':' symbol in clause.
+  SourceLocation getColonLoc() const { return ColonLoc; }
+  /// \brief Gets the name info for specified reduction identifier.
+  const DeclarationNameInfo &getNameInfo() const { return NameInfo; }
+  /// \brief Gets the nested name specifier.
+  NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
+
+  StmtRange children() {
+    return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+                     reinterpret_cast<Stmt **>(varlist_end()));
+  }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_reduction;
+  }
+};
+
+/// \brief This represents clause 'linear' in the '#pragma omp ...'
+/// directives.
+///
+/// \code
+/// #pragma omp simd linear(a,b : 2)
+/// \endcode
+/// In this example directive '#pragma omp simd' has clause 'linear'
+/// with variables 'a', 'b' and linear step '2'.
+///
+class OMPLinearClause : public OMPVarListClause<OMPLinearClause> {
+  friend class OMPClauseReader;
+  /// \brief Location of ':'.
+  SourceLocation ColonLoc;
+
+  /// \brief Sets the linear step for clause.
+  void setStep(Expr *Step) { *varlist_end() = Step; }
+
+  /// \brief Build 'linear' clause with given number of variables \a NumVars.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param ColonLoc Location of ':'.
+  /// \param EndLoc Ending location of the clause.
+  /// \param NumVars Number of variables.
+  ///
+  OMPLinearClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+                  SourceLocation ColonLoc, SourceLocation EndLoc,
+                  unsigned NumVars)
+      : OMPVarListClause<OMPLinearClause>(OMPC_linear, StartLoc, LParenLoc,
+                                          EndLoc, NumVars),
+        ColonLoc(ColonLoc) {}
+
+  /// \brief Build an empty clause.
+  ///
+  /// \param NumVars Number of variables.
+  ///
+  explicit OMPLinearClause(unsigned NumVars)
+      : OMPVarListClause<OMPLinearClause>(OMPC_linear, SourceLocation(),
+                                          SourceLocation(), SourceLocation(),
+                                          NumVars),
+        ColonLoc(SourceLocation()) {}
+
+public:
+  /// \brief Creates clause with a list of variables \a VL and a linear step
+  /// \a Step.
+  ///
+  /// \param C AST Context.
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param ColonLoc Location of ':'.
+  /// \param EndLoc Ending location of the clause.
+  /// \param VL List of references to the variables.
+  /// \param Step Linear step.
+  static OMPLinearClause *Create(const ASTContext &C, SourceLocation StartLoc,
+                                 SourceLocation LParenLoc,
+                                 SourceLocation ColonLoc, SourceLocation EndLoc,
+                                 ArrayRef<Expr *> VL, Expr *Step);
+
+  /// \brief Creates an empty clause with the place for \a NumVars variables.
+  ///
+  /// \param C AST context.
+  /// \param NumVars Number of variables.
+  ///
+  static OMPLinearClause *CreateEmpty(const ASTContext &C, unsigned NumVars);
+
+  /// \brief Sets the location of ':'.
+  void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
+  /// \brief Returns the location of '('.
+  SourceLocation getColonLoc() const { return ColonLoc; }
+
+  /// \brief Returns linear step.
+  Expr *getStep() { return *varlist_end(); }
+  /// \brief Returns linear step.
+  const Expr *getStep() const { return *varlist_end(); }
+
+  StmtRange children() {
+    return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+                     reinterpret_cast<Stmt **>(varlist_end() + 1));
+  }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_linear;
+  }
+};
+
+/// \brief This represents clause 'aligned' in the '#pragma omp ...'
+/// directives.
+///
+/// \code
+/// #pragma omp simd aligned(a,b : 8)
+/// \endcode
+/// In this example directive '#pragma omp simd' has clause 'aligned'
+/// with variables 'a', 'b' and alignment '8'.
+///
+class OMPAlignedClause : public OMPVarListClause<OMPAlignedClause> {
+  friend class OMPClauseReader;
+  /// \brief Location of ':'.
+  SourceLocation ColonLoc;
+
+  /// \brief Sets the alignment for clause.
+  void setAlignment(Expr *A) { *varlist_end() = A; }
+
+  /// \brief Build 'aligned' clause with given number of variables \a NumVars.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param ColonLoc Location of ':'.
+  /// \param EndLoc Ending location of the clause.
+  /// \param NumVars Number of variables.
+  ///
+  OMPAlignedClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+                   SourceLocation ColonLoc, SourceLocation EndLoc,
+                   unsigned NumVars)
+      : OMPVarListClause<OMPAlignedClause>(OMPC_aligned, StartLoc, LParenLoc,
+                                           EndLoc, NumVars),
+        ColonLoc(ColonLoc) {}
+
+  /// \brief Build an empty clause.
+  ///
+  /// \param NumVars Number of variables.
+  ///
+  explicit OMPAlignedClause(unsigned NumVars)
+      : OMPVarListClause<OMPAlignedClause>(OMPC_aligned, SourceLocation(),
+                                           SourceLocation(), SourceLocation(),
+                                           NumVars),
+        ColonLoc(SourceLocation()) {}
+
+public:
+  /// \brief Creates clause with a list of variables \a VL and alignment \a A.
+  ///
+  /// \param C AST Context.
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param ColonLoc Location of ':'.
+  /// \param EndLoc Ending location of the clause.
+  /// \param VL List of references to the variables.
+  /// \param A Alignment.
+  static OMPAlignedClause *Create(const ASTContext &C, SourceLocation StartLoc,
+                                  SourceLocation LParenLoc,
+                                  SourceLocation ColonLoc,
+                                  SourceLocation EndLoc, ArrayRef<Expr *> VL,
+                                  Expr *A);
+
+  /// \brief Creates an empty clause with the place for \a NumVars variables.
+  ///
+  /// \param C AST context.
+  /// \param NumVars Number of variables.
+  ///
+  static OMPAlignedClause *CreateEmpty(const ASTContext &C, unsigned NumVars);
+
+  /// \brief Sets the location of ':'.
+  void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
+  /// \brief Returns the location of ':'.
+  SourceLocation getColonLoc() const { return ColonLoc; }
+
+  /// \brief Returns alignment.
+  Expr *getAlignment() { return *varlist_end(); }
+  /// \brief Returns alignment.
+  const Expr *getAlignment() const { return *varlist_end(); }
+
+  StmtRange children() {
+    return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+                     reinterpret_cast<Stmt **>(varlist_end() + 1));
+  }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_aligned;
+  }
+};
+
+/// \brief This represents clause 'copyin' in the '#pragma omp ...' directives.
+///
+/// \code
+/// #pragma omp parallel copyin(a,b)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has clause 'copyin'
+/// with the variables 'a' and 'b'.
+///
+class OMPCopyinClause : public OMPVarListClause<OMPCopyinClause> {
+  /// \brief Build clause with number of variables \a N.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param N Number of the variables in the clause.
+  ///
+  OMPCopyinClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+                  SourceLocation EndLoc, unsigned N)
+      : OMPVarListClause<OMPCopyinClause>(OMPC_copyin, StartLoc, LParenLoc,
+                                          EndLoc, N) {}
+
+  /// \brief Build an empty clause.
+  ///
+  /// \param N Number of variables.
+  ///
+  explicit OMPCopyinClause(unsigned N)
+      : OMPVarListClause<OMPCopyinClause>(OMPC_copyin, SourceLocation(),
+                                          SourceLocation(), SourceLocation(),
+                                          N) {}
+
+public:
+  /// \brief Creates clause with a list of variables \a VL.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param VL List of references to the variables.
+  ///
+  static OMPCopyinClause *Create(const ASTContext &C, SourceLocation StartLoc,
+                                 SourceLocation LParenLoc,
+                                 SourceLocation EndLoc, ArrayRef<Expr *> VL);
+  /// \brief Creates an empty clause with \a N variables.
+  ///
+  /// \param C AST context.
+  /// \param N The number of variables.
+  ///
+  static OMPCopyinClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+  StmtRange children() {
+    return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+                     reinterpret_cast<Stmt **>(varlist_end()));
+  }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_copyin;
+  }
+};
+
+/// \brief This represents clause 'copyprivate' in the '#pragma omp ...'
+/// directives.
+///
+/// \code
+/// #pragma omp single copyprivate(a,b)
+/// \endcode
+/// In this example directive '#pragma omp single' has clause 'copyprivate'
+/// with the variables 'a' and 'b'.
+///
+class OMPCopyprivateClause : public OMPVarListClause<OMPCopyprivateClause> {
+  /// \brief Build clause with number of variables \a N.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param N Number of the variables in the clause.
+  ///
+  OMPCopyprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+                       SourceLocation EndLoc, unsigned N)
+      : OMPVarListClause<OMPCopyprivateClause>(OMPC_copyprivate, StartLoc,
+                                               LParenLoc, EndLoc, N) {}
+
+  /// \brief Build an empty clause.
+  ///
+  /// \param N Number of variables.
+  ///
+  explicit OMPCopyprivateClause(unsigned N)
+      : OMPVarListClause<OMPCopyprivateClause>(
+            OMPC_copyprivate, SourceLocation(), SourceLocation(),
+            SourceLocation(), N) {}
+
+public:
+  /// \brief Creates clause with a list of variables \a VL.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param VL List of references to the variables.
+  ///
+  static OMPCopyprivateClause *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
+         SourceLocation EndLoc, ArrayRef<Expr *> VL);
+  /// \brief Creates an empty clause with \a N variables.
+  ///
+  /// \param C AST context.
+  /// \param N The number of variables.
+  ///
+  static OMPCopyprivateClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+  StmtRange children() {
+    return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+                     reinterpret_cast<Stmt **>(varlist_end()));
+  }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_copyprivate;
+  }
+};
+
+/// \brief This represents pseudo clause 'flush' for the '#pragma omp flush'
+/// directive.
+///
+/// \code
+/// #pragma omp flush(a,b)
+/// \endcode
+/// In this example directive '#pragma omp flush' has pseudo clause 'flush'
+/// with the variables 'a' and 'b'.
+///
+class OMPFlushClause : public OMPVarListClause<OMPFlushClause> {
+  /// \brief Build clause with number of variables \a N.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param N Number of the variables in the clause.
+  ///
+  OMPFlushClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+                 SourceLocation EndLoc, unsigned N)
+      : OMPVarListClause<OMPFlushClause>(OMPC_flush, StartLoc, LParenLoc,
+                                         EndLoc, N) {}
+
+  /// \brief Build an empty clause.
+  ///
+  /// \param N Number of variables.
+  ///
+  explicit OMPFlushClause(unsigned N)
+      : OMPVarListClause<OMPFlushClause>(OMPC_flush, SourceLocation(),
+                                         SourceLocation(), SourceLocation(),
+                                         N) {}
+
+public:
+  /// \brief Creates clause with a list of variables \a VL.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param EndLoc Ending location of the clause.
+  /// \param VL List of references to the variables.
+  ///
+  static OMPFlushClause *Create(const ASTContext &C, SourceLocation StartLoc,
+                                SourceLocation LParenLoc, SourceLocation EndLoc,
+                                ArrayRef<Expr *> VL);
+  /// \brief Creates an empty clause with \a N variables.
+  ///
+  /// \param C AST context.
+  /// \param N The number of variables.
+  ///
+  static OMPFlushClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+  StmtRange children() {
+    return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+                     reinterpret_cast<Stmt **>(varlist_end()));
+  }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_flush;
+  }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/AST/OperationKinds.h b/include/clang/AST/OperationKinds.h
index 5e41d95..aba88d6 100644
--- a/include/clang/AST/OperationKinds.h
+++ b/include/clang/AST/OperationKinds.h
@@ -295,7 +295,10 @@
   CK_BuiltinFnToFnPtr,
 
   // Convert a zero value for OpenCL event_t initialization.
-  CK_ZeroToOCLEvent
+  CK_ZeroToOCLEvent,
+
+  // Convert a pointer to a different address space.
+  CK_AddressSpaceConversion
 };
 
 static const CastKind CK_Invalid = static_cast<CastKind>(-1);
diff --git a/include/clang/AST/ParentMap.h b/include/clang/AST/ParentMap.h
index bd2ebf5..eece851 100644
--- a/include/clang/AST/ParentMap.h
+++ b/include/clang/AST/ParentMap.h
@@ -53,7 +53,7 @@
   }
 
   bool hasParent(Stmt* S) const {
-    return getParent(S) != 0;
+    return getParent(S) != nullptr;
   }
 
   bool isConsumedExpr(Expr *E) const;
diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h
index 7642699..349f4c4 100644
--- a/include/clang/AST/PrettyPrinter.h
+++ b/include/clang/AST/PrettyPrinter.h
@@ -41,7 +41,8 @@
       ConstantArraySizeAsWritten(false), AnonymousTagLocations(true),
       SuppressStrongLifetime(false), SuppressLifetimeQualifiers(false),
       Bool(LO.Bool), TerseOutput(false), PolishForDeclaration(false),
-      MSWChar(LO.MicrosoftExt && !LO.WChar) { }
+      Half(LO.Half), MSWChar(LO.MicrosoftExt && !LO.WChar),
+      IncludeNewlines(true) { }
 
   /// \brief What language we're printing.
   LangOptions LangOpts;
@@ -125,7 +126,7 @@
   
   /// \brief When printing an anonymous tag name, also print the location of
   /// that entity (e.g., "enum <anonymous at t.h:10:5>"). Otherwise, just 
-  /// prints "<anonymous>" for the name.
+  /// prints "(anonymous)" for the name.
   bool AnonymousTagLocations : 1;
   
   /// \brief When true, suppress printing of the __strong lifetime qualifier in
@@ -152,9 +153,16 @@
   ///
   unsigned PolishForDeclaration : 1;
 
+  /// \brief When true, print the half-precision floating-point type as 'half'
+  /// instead of '__fp16'
+  unsigned Half : 1;
+
   /// \brief When true, print the built-in wchar_t type as __wchar_t. For use in
   /// Microsoft mode when wchar_t is not available.
   unsigned MSWChar : 1;
+
+  /// \brief When true, include newlines after statements like "break", etc.
+  unsigned IncludeNewlines : 1;
 };
 
 } // end namespace clang
diff --git a/include/clang/AST/RawCommentList.h b/include/clang/AST/RawCommentList.h
index a4fcc10..8ba85c4 100644
--- a/include/clang/AST/RawCommentList.h
+++ b/include/clang/AST/RawCommentList.h
@@ -193,9 +193,7 @@
   SourceManager &SourceMgr;
   std::vector<RawComment *> Comments;
 
-  void addCommentsToFront(const std::vector<RawComment *> &C) {
-    Comments.insert(Comments.begin(), C.begin(), C.end());
-  }
+  void addDeserializedComments(ArrayRef<RawComment *> DeserializedComments);
 
   friend class ASTReader;
 };
diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h
index 7268b3a..4befb45 100644
--- a/include/clang/AST/RecordLayout.h
+++ b/include/clang/AST/RecordLayout.h
@@ -66,6 +66,10 @@
   // Alignment - Alignment of record in characters.
   CharUnits Alignment;
 
+  /// RequiredAlignment - The required alignment of the object.  In the MS-ABI
+  /// the __declspec(align()) trumps #pramga pack and must always be obeyed.
+  CharUnits RequiredAlignment;
+
   /// FieldOffsets - Array of field offsets in bits.
   uint64_t *FieldOffsets;
 
@@ -78,9 +82,9 @@
     /// the size of the object without virtual bases.
     CharUnits NonVirtualSize;
 
-    /// NonVirtualAlign - The non-virtual alignment (in chars) of an object,
+    /// NonVirtualAlignment - The non-virtual alignment (in chars) of an object,
     /// which is the alignment of the object without virtual bases.
-    CharUnits NonVirtualAlign;
+    CharUnits NonVirtualAlignment;
 
     /// SizeOfLargestEmptySubobject - The size of the largest empty subobject
     /// (either a base or a member). Will be zero if the class doesn't contain
@@ -100,10 +104,15 @@
     /// a primary base class.
     bool HasExtendableVFPtr : 1;
 
-    /// AlignAfterVBases - Force appropriate alignment after virtual bases are
-    /// laid out in MS-C++-ABI.
-    bool AlignAfterVBases : 1;
-    
+    /// HasZeroSizedSubObject - True if this class contains a zero sized member
+    /// or base or a base with a zero sized member or base.  Only used for
+    /// MS-ABI.
+    bool HasZeroSizedSubObject : 1;
+
+    /// \brief True if this class is zero sized or first base is zero sized or
+    /// has this property.  Only used for MS-ABI.
+    bool LeadsWithZeroSizedBase : 1;
+
     /// PrimaryBase - The primary base info for this record.
     llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> PrimaryBase;
 
@@ -127,6 +136,7 @@
   friend class ASTContext;
 
   ASTRecordLayout(const ASTContext &Ctx, CharUnits size, CharUnits alignment,
+                  CharUnits requiredAlignment,
                   CharUnits datasize, const uint64_t *fieldoffsets,
                   unsigned fieldcount);
 
@@ -134,16 +144,18 @@
   typedef CXXRecordLayoutInfo::BaseOffsetsMapTy BaseOffsetsMapTy;
   ASTRecordLayout(const ASTContext &Ctx,
                   CharUnits size, CharUnits alignment,
+                  CharUnits requiredAlignment,
                   bool hasOwnVFPtr, bool hasExtendableVFPtr,
                   CharUnits vbptroffset,
                   CharUnits datasize,
                   const uint64_t *fieldoffsets, unsigned fieldcount,
-                  CharUnits nonvirtualsize, CharUnits nonvirtualalign,
+                  CharUnits nonvirtualsize, CharUnits nonvirtualalignment,
                   CharUnits SizeOfLargestEmptySubobject,
                   const CXXRecordDecl *PrimaryBase,
                   bool IsPrimaryBaseVirtual,
                   const CXXRecordDecl *BaseSharingVBPtr,
-                  bool ForceAlign,
+                  bool HasZeroSizedSubObject,
+                  bool LeadsWithZeroSizedBase,
                   const BaseOffsetsMapTy& BaseOffsets,
                   const VBaseOffsetsMapTy& VBaseOffsets);
 
@@ -187,10 +199,10 @@
 
   /// getNonVirtualSize - Get the non-virtual alignment (in chars) of an object,
   /// which is the alignment of the object without virtual bases.
-  CharUnits getNonVirtualAlign() const {
+  CharUnits getNonVirtualAlignment() const {
     assert(CXXInfo && "Record layout does not have C++ specific info!");
 
-    return CXXInfo->NonVirtualAlign;
+    return CXXInfo->NonVirtualAlignment;
   }
 
   /// getPrimaryBase - Get the primary base for this record.
@@ -267,9 +279,17 @@
     return !CXXInfo->VBPtrOffset.isNegative();
   }
 
-  bool getAlignAfterVBases() const {
+  CharUnits getRequiredAlignment() const {
+    return RequiredAlignment;
+  }
+
+  bool hasZeroSizedSubObject() const {
+    return CXXInfo && CXXInfo->HasZeroSizedSubObject;
+  }
+
+  bool leadsWithZeroSizedBase() const {
     assert(CXXInfo && "Record layout does not have C++ specific info!");
-    return CXXInfo->AlignAfterVBases;
+    return CXXInfo->LeadsWithZeroSizedBase;
   }
 
   /// getVBPtrOffset - Get the offset for virtual base table pointer.
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index d09550f..ff46ffb 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -14,6 +14,7 @@
 #ifndef LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
 #define LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
 
+#include "clang/AST/Attr.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclFriend.h"
@@ -37,34 +38,24 @@
 // using them is responsible for defining macro OPERATOR().
 
 // All unary operators.
-#define UNARYOP_LIST()                          \
-  OPERATOR(PostInc)   OPERATOR(PostDec)         \
-  OPERATOR(PreInc)    OPERATOR(PreDec)          \
-  OPERATOR(AddrOf)    OPERATOR(Deref)           \
-  OPERATOR(Plus)      OPERATOR(Minus)           \
-  OPERATOR(Not)       OPERATOR(LNot)            \
-  OPERATOR(Real)      OPERATOR(Imag)            \
-  OPERATOR(Extension)
+#define UNARYOP_LIST()                                                         \
+  OPERATOR(PostInc) OPERATOR(PostDec) OPERATOR(PreInc) OPERATOR(PreDec)        \
+      OPERATOR(AddrOf) OPERATOR(Deref) OPERATOR(Plus) OPERATOR(Minus)          \
+      OPERATOR(Not) OPERATOR(LNot) OPERATOR(Real) OPERATOR(Imag)               \
+      OPERATOR(Extension)
 
 // All binary operators (excluding compound assign operators).
-#define BINOP_LIST() \
-  OPERATOR(PtrMemD)              OPERATOR(PtrMemI)    \
-  OPERATOR(Mul)   OPERATOR(Div)  OPERATOR(Rem)        \
-  OPERATOR(Add)   OPERATOR(Sub)  OPERATOR(Shl)        \
-  OPERATOR(Shr)                                       \
-                                                      \
-  OPERATOR(LT)    OPERATOR(GT)   OPERATOR(LE)         \
-  OPERATOR(GE)    OPERATOR(EQ)   OPERATOR(NE)         \
-  OPERATOR(And)   OPERATOR(Xor)  OPERATOR(Or)         \
-  OPERATOR(LAnd)  OPERATOR(LOr)                       \
-                                                      \
-  OPERATOR(Assign)                                    \
-  OPERATOR(Comma)
+#define BINOP_LIST()                                                           \
+  OPERATOR(PtrMemD) OPERATOR(PtrMemI) OPERATOR(Mul) OPERATOR(Div)              \
+      OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) OPERATOR(Shl) OPERATOR(Shr)    \
+      OPERATOR(LT) OPERATOR(GT) OPERATOR(LE) OPERATOR(GE) OPERATOR(EQ)         \
+      OPERATOR(NE) OPERATOR(And) OPERATOR(Xor) OPERATOR(Or) OPERATOR(LAnd)     \
+      OPERATOR(LOr) OPERATOR(Assign) OPERATOR(Comma)
 
 // All compound assign operators.
-#define CAO_LIST()                                                      \
-  OPERATOR(Mul) OPERATOR(Div) OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) \
-  OPERATOR(Shl) OPERATOR(Shr) OPERATOR(And) OPERATOR(Or)  OPERATOR(Xor)
+#define CAO_LIST()                                                             \
+  OPERATOR(Mul) OPERATOR(Div) OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub)        \
+      OPERATOR(Shl) OPERATOR(Shr) OPERATOR(And) OPERATOR(Or) OPERATOR(Xor)
 
 namespace clang {
 
@@ -72,8 +63,11 @@
 // invokes CALL_EXPR, which must be a method call, on the derived
 // object (s.t. a user of RecursiveASTVisitor can override the method
 // in CALL_EXPR).
-#define TRY_TO(CALL_EXPR) \
-  do { if (!getDerived().CALL_EXPR) return false; } while (0)
+#define TRY_TO(CALL_EXPR)                                                      \
+  do {                                                                         \
+    if (!getDerived().CALL_EXPR)                                               \
+      return false;                                                            \
+  } while (0)
 
 /// \brief A class that does preorder depth-first traversal on the
 /// entire Clang AST and visits each node.
@@ -136,11 +130,10 @@
 /// to return true, in which case all known implicit and explicit
 /// instantiations will be visited at the same time as the pattern
 /// from which they were produced.
-template<typename Derived>
-class RecursiveASTVisitor {
+template <typename Derived> class RecursiveASTVisitor {
 public:
   /// \brief Return a reference to the derived class.
-  Derived &getDerived() { return *static_cast<Derived*>(this); }
+  Derived &getDerived() { return *static_cast<Derived *>(this); }
 
   /// \brief Return whether this visitor should recurse into
   /// template instantiations.
@@ -182,6 +175,13 @@
   /// otherwise (including when the argument is a Null type location).
   bool TraverseTypeLoc(TypeLoc TL);
 
+  /// \brief Recursively visit an attribute, by dispatching to
+  /// Traverse*Attr() based on the argument's dynamic type.
+  ///
+  /// \returns false if the visitation was terminated early, true
+  /// otherwise (including when the argument is a Null type location).
+  bool TraverseAttr(Attr *At);
+
   /// \brief Recursively visit a declaration, by dispatching to
   /// Traverse*Decl() based on the argument's dynamic type.
   ///
@@ -244,7 +244,7 @@
   /// \brief Recursively visit a lambda capture.
   ///
   /// \returns false if the visitation was terminated early, true otherwise.
-  bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaExpr::Capture *C);
+  bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C);
 
   /// \brief Recursively visit the body of a lambda expression.
   ///
@@ -254,107 +254,114 @@
   /// \returns false if the visitation was terminated early, true otherwise.
   bool TraverseLambdaBody(LambdaExpr *LE);
 
-  // ---- Methods on Stmts ----
+  // ---- Methods on Attrs ----
 
-  // Declare Traverse*() for all concrete Stmt classes.
+  // \brief Visit an attribute.
+  bool VisitAttr(Attr *A) { return true; }
+
+// Declare Traverse* and empty Visit* for all Attr classes.
+#define ATTR_VISITOR_DECLS_ONLY
+#include "clang/AST/AttrVisitor.inc"
+#undef ATTR_VISITOR_DECLS_ONLY
+
+// ---- Methods on Stmts ----
+
+// Declare Traverse*() for all concrete Stmt classes.
 #define ABSTRACT_STMT(STMT)
-#define STMT(CLASS, PARENT)                                     \
-  bool Traverse##CLASS(CLASS *S);
+#define STMT(CLASS, PARENT) bool Traverse##CLASS(CLASS *S);
 #include "clang/AST/StmtNodes.inc"
   // The above header #undefs ABSTRACT_STMT and STMT upon exit.
 
   // Define WalkUpFrom*() and empty Visit*() for all Stmt classes.
   bool WalkUpFromStmt(Stmt *S) { return getDerived().VisitStmt(S); }
   bool VisitStmt(Stmt *S) { return true; }
-#define STMT(CLASS, PARENT)                                     \
-  bool WalkUpFrom##CLASS(CLASS *S) {                            \
-    TRY_TO(WalkUpFrom##PARENT(S));                              \
-    TRY_TO(Visit##CLASS(S));                                    \
-    return true;                                                \
-  }                                                             \
+#define STMT(CLASS, PARENT)                                                    \
+  bool WalkUpFrom##CLASS(CLASS *S) {                                           \
+    TRY_TO(WalkUpFrom##PARENT(S));                                             \
+    TRY_TO(Visit##CLASS(S));                                                   \
+    return true;                                                               \
+  }                                                                            \
   bool Visit##CLASS(CLASS *S) { return true; }
 #include "clang/AST/StmtNodes.inc"
 
-  // Define Traverse*(), WalkUpFrom*(), and Visit*() for unary
-  // operator methods.  Unary operators are not classes in themselves
-  // (they're all opcodes in UnaryOperator) but do have visitors.
-#define OPERATOR(NAME)                                           \
-  bool TraverseUnary##NAME(UnaryOperator *S) {                  \
-    TRY_TO(WalkUpFromUnary##NAME(S));                           \
-    TRY_TO(TraverseStmt(S->getSubExpr()));                      \
-    return true;                                                \
-  }                                                             \
-  bool WalkUpFromUnary##NAME(UnaryOperator *S) {                \
-    TRY_TO(WalkUpFromUnaryOperator(S));                         \
-    TRY_TO(VisitUnary##NAME(S));                                \
-    return true;                                                \
-  }                                                             \
+// Define Traverse*(), WalkUpFrom*(), and Visit*() for unary
+// operator methods.  Unary operators are not classes in themselves
+// (they're all opcodes in UnaryOperator) but do have visitors.
+#define OPERATOR(NAME)                                                         \
+  bool TraverseUnary##NAME(UnaryOperator *S) {                                 \
+    TRY_TO(WalkUpFromUnary##NAME(S));                                          \
+    TRY_TO(TraverseStmt(S->getSubExpr()));                                     \
+    return true;                                                               \
+  }                                                                            \
+  bool WalkUpFromUnary##NAME(UnaryOperator *S) {                               \
+    TRY_TO(WalkUpFromUnaryOperator(S));                                        \
+    TRY_TO(VisitUnary##NAME(S));                                               \
+    return true;                                                               \
+  }                                                                            \
   bool VisitUnary##NAME(UnaryOperator *S) { return true; }
 
   UNARYOP_LIST()
 #undef OPERATOR
 
-  // Define Traverse*(), WalkUpFrom*(), and Visit*() for binary
-  // operator methods.  Binary operators are not classes in themselves
-  // (they're all opcodes in BinaryOperator) but do have visitors.
-#define GENERAL_BINOP_FALLBACK(NAME, BINOP_TYPE)                \
-  bool TraverseBin##NAME(BINOP_TYPE *S) {                       \
-    TRY_TO(WalkUpFromBin##NAME(S));                             \
-    TRY_TO(TraverseStmt(S->getLHS()));                          \
-    TRY_TO(TraverseStmt(S->getRHS()));                          \
-    return true;                                                \
-  }                                                             \
-  bool WalkUpFromBin##NAME(BINOP_TYPE *S) {                     \
-    TRY_TO(WalkUpFrom##BINOP_TYPE(S));                          \
-    TRY_TO(VisitBin##NAME(S));                                  \
-    return true;                                                \
-  }                                                             \
+// Define Traverse*(), WalkUpFrom*(), and Visit*() for binary
+// operator methods.  Binary operators are not classes in themselves
+// (they're all opcodes in BinaryOperator) but do have visitors.
+#define GENERAL_BINOP_FALLBACK(NAME, BINOP_TYPE)                               \
+  bool TraverseBin##NAME(BINOP_TYPE *S) {                                      \
+    TRY_TO(WalkUpFromBin##NAME(S));                                            \
+    TRY_TO(TraverseStmt(S->getLHS()));                                         \
+    TRY_TO(TraverseStmt(S->getRHS()));                                         \
+    return true;                                                               \
+  }                                                                            \
+  bool WalkUpFromBin##NAME(BINOP_TYPE *S) {                                    \
+    TRY_TO(WalkUpFrom##BINOP_TYPE(S));                                         \
+    TRY_TO(VisitBin##NAME(S));                                                 \
+    return true;                                                               \
+  }                                                                            \
   bool VisitBin##NAME(BINOP_TYPE *S) { return true; }
 
 #define OPERATOR(NAME) GENERAL_BINOP_FALLBACK(NAME, BinaryOperator)
   BINOP_LIST()
 #undef OPERATOR
 
-  // Define Traverse*(), WalkUpFrom*(), and Visit*() for compound
-  // assignment methods.  Compound assignment operators are not
-  // classes in themselves (they're all opcodes in
-  // CompoundAssignOperator) but do have visitors.
-#define OPERATOR(NAME) \
+// Define Traverse*(), WalkUpFrom*(), and Visit*() for compound
+// assignment methods.  Compound assignment operators are not
+// classes in themselves (they're all opcodes in
+// CompoundAssignOperator) but do have visitors.
+#define OPERATOR(NAME)                                                         \
   GENERAL_BINOP_FALLBACK(NAME##Assign, CompoundAssignOperator)
 
   CAO_LIST()
 #undef OPERATOR
 #undef GENERAL_BINOP_FALLBACK
 
-  // ---- Methods on Types ----
-  // FIXME: revamp to take TypeLoc's rather than Types.
+// ---- Methods on Types ----
+// FIXME: revamp to take TypeLoc's rather than Types.
 
-  // Declare Traverse*() for all concrete Type classes.
+// Declare Traverse*() for all concrete Type classes.
 #define ABSTRACT_TYPE(CLASS, BASE)
-#define TYPE(CLASS, BASE) \
-  bool Traverse##CLASS##Type(CLASS##Type *T);
+#define TYPE(CLASS, BASE) bool Traverse##CLASS##Type(CLASS##Type *T);
 #include "clang/AST/TypeNodes.def"
   // The above header #undefs ABSTRACT_TYPE and TYPE upon exit.
 
   // Define WalkUpFrom*() and empty Visit*() for all Type classes.
   bool WalkUpFromType(Type *T) { return getDerived().VisitType(T); }
   bool VisitType(Type *T) { return true; }
-#define TYPE(CLASS, BASE)                                       \
-  bool WalkUpFrom##CLASS##Type(CLASS##Type *T) {                \
-    TRY_TO(WalkUpFrom##BASE(T));                                \
-    TRY_TO(Visit##CLASS##Type(T));                              \
-    return true;                                                \
-  }                                                             \
+#define TYPE(CLASS, BASE)                                                      \
+  bool WalkUpFrom##CLASS##Type(CLASS##Type *T) {                               \
+    TRY_TO(WalkUpFrom##BASE(T));                                               \
+    TRY_TO(Visit##CLASS##Type(T));                                             \
+    return true;                                                               \
+  }                                                                            \
   bool Visit##CLASS##Type(CLASS##Type *T) { return true; }
 #include "clang/AST/TypeNodes.def"
 
-  // ---- Methods on TypeLocs ----
-  // FIXME: this currently just calls the matching Type methods
+// ---- Methods on TypeLocs ----
+// FIXME: this currently just calls the matching Type methods
 
-  // Declare Traverse*() for all concrete TypeLoc classes.
+// Declare Traverse*() for all concrete TypeLoc classes.
 #define ABSTRACT_TYPELOC(CLASS, BASE)
-#define TYPELOC(CLASS, BASE) \
-  bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL);
+#define TYPELOC(CLASS, BASE) bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL);
 #include "clang/AST/TypeLocNodes.def"
   // The above header #undefs ABSTRACT_TYPELOC and TYPELOC upon exit.
 
@@ -373,34 +380,33 @@
   }
   bool VisitUnqualTypeLoc(UnqualTypeLoc TL) { return true; }
 
-  // Note that BASE includes trailing 'Type' which CLASS doesn't.
-#define TYPE(CLASS, BASE)                                       \
-  bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL) {          \
-    TRY_TO(WalkUpFrom##BASE##Loc(TL));                          \
-    TRY_TO(Visit##CLASS##TypeLoc(TL));                          \
-    return true;                                                \
-  }                                                             \
+// Note that BASE includes trailing 'Type' which CLASS doesn't.
+#define TYPE(CLASS, BASE)                                                      \
+  bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL) {                         \
+    TRY_TO(WalkUpFrom##BASE##Loc(TL));                                         \
+    TRY_TO(Visit##CLASS##TypeLoc(TL));                                         \
+    return true;                                                               \
+  }                                                                            \
   bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { return true; }
 #include "clang/AST/TypeNodes.def"
 
-  // ---- Methods on Decls ----
+// ---- Methods on Decls ----
 
-  // Declare Traverse*() for all concrete Decl classes.
+// Declare Traverse*() for all concrete Decl classes.
 #define ABSTRACT_DECL(DECL)
-#define DECL(CLASS, BASE) \
-  bool Traverse##CLASS##Decl(CLASS##Decl *D);
+#define DECL(CLASS, BASE) bool Traverse##CLASS##Decl(CLASS##Decl *D);
 #include "clang/AST/DeclNodes.inc"
   // The above header #undefs ABSTRACT_DECL and DECL upon exit.
 
   // Define WalkUpFrom*() and empty Visit*() for all Decl classes.
   bool WalkUpFromDecl(Decl *D) { return getDerived().VisitDecl(D); }
   bool VisitDecl(Decl *D) { return true; }
-#define DECL(CLASS, BASE)                                       \
-  bool WalkUpFrom##CLASS##Decl(CLASS##Decl *D) {                \
-    TRY_TO(WalkUpFrom##BASE(D));                                \
-    TRY_TO(Visit##CLASS##Decl(D));                              \
-    return true;                                                \
-  }                                                             \
+#define DECL(CLASS, BASE)                                                      \
+  bool WalkUpFrom##CLASS##Decl(CLASS##Decl *D) {                               \
+    TRY_TO(WalkUpFrom##BASE(D));                                               \
+    TRY_TO(Visit##CLASS##Decl(D));                                             \
+    return true;                                                               \
+  }                                                                            \
   bool Visit##CLASS##Decl(CLASS##Decl *D) { return true; }
 #include "clang/AST/DeclNodes.inc"
 
@@ -422,13 +428,12 @@
   bool TraverseDeclContextHelper(DeclContext *DC);
   bool TraverseFunctionHelper(FunctionDecl *D);
   bool TraverseVarHelper(VarDecl *D);
+  bool TraverseOMPExecutableDirective(OMPExecutableDirective *S);
   bool TraverseOMPClause(OMPClause *C);
-#define OPENMP_CLAUSE(Name, Class)                                      \
-  bool Visit##Class(Class *C);
+#define OPENMP_CLAUSE(Name, Class) bool Visit##Class(Class *C);
 #include "clang/Basic/OpenMPKinds.def"
   /// \brief Process clauses with list of variables.
-  template <typename T>
-  void VisitOMPClauseList(T *Node);
+  template <typename T> bool VisitOMPClauseList(T *Node);
 
   struct EnqueueJob {
     Stmt *S;
@@ -440,7 +445,7 @@
   bool dataTraverseNode(Stmt *S, bool &EnqueueChildren);
 };
 
-template<typename Derived>
+template <typename Derived>
 bool RecursiveASTVisitor<Derived>::dataTraverse(Stmt *S) {
 
   SmallVector<EnqueueJob, 16> Queue;
@@ -457,7 +462,8 @@
     if (getDerived().shouldUseDataRecursionFor(CurrS)) {
       if (job.StmtIt == Stmt::child_iterator()) {
         bool EnqueueChildren = true;
-        if (!dataTraverseNode(CurrS, EnqueueChildren)) return false;
+        if (!dataTraverseNode(CurrS, EnqueueChildren))
+          return false;
         if (!EnqueueChildren) {
           Queue.pop_back();
           continue;
@@ -481,53 +487,57 @@
   return true;
 }
 
-template<typename Derived>
+template <typename Derived>
 bool RecursiveASTVisitor<Derived>::dataTraverseNode(Stmt *S,
                                                     bool &EnqueueChildren) {
 
-  // Dispatch to the corresponding WalkUpFrom* function only if the derived
-  // class didn't override Traverse* (and thus the traversal is trivial).
-#define DISPATCH_WALK(NAME, CLASS, VAR) \
-  { \
-    bool (Derived::*DerivedFn)(CLASS*) = &Derived::Traverse##NAME; \
-    bool (Derived::*BaseFn)(CLASS*) = &RecursiveASTVisitor::Traverse##NAME; \
-    if (DerivedFn == BaseFn) \
-      return getDerived().WalkUpFrom##NAME(static_cast<CLASS*>(VAR)); \
-  } \
-  EnqueueChildren = false; \
-  return getDerived().Traverse##NAME(static_cast<CLASS*>(VAR));
+// Dispatch to the corresponding WalkUpFrom* function only if the derived
+// class didn't override Traverse* (and thus the traversal is trivial).
+#define DISPATCH_WALK(NAME, CLASS, VAR)                                        \
+  {                                                                            \
+    bool (Derived::*DerivedFn)(CLASS *) = &Derived::Traverse##NAME;            \
+    bool (Derived::*BaseFn)(CLASS *) = &RecursiveASTVisitor::Traverse##NAME;   \
+    if (DerivedFn == BaseFn)                                                   \
+      return getDerived().WalkUpFrom##NAME(static_cast<CLASS *>(VAR));         \
+  }                                                                            \
+  EnqueueChildren = false;                                                     \
+  return getDerived().Traverse##NAME(static_cast<CLASS *>(VAR));
 
   if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) {
     switch (BinOp->getOpcode()) {
-#define OPERATOR(NAME) \
-    case BO_##NAME: DISPATCH_WALK(Bin##NAME, BinaryOperator, S);
+#define OPERATOR(NAME)                                                         \
+  case BO_##NAME:                                                              \
+    DISPATCH_WALK(Bin##NAME, BinaryOperator, S);
 
-    BINOP_LIST()
+      BINOP_LIST()
 #undef OPERATOR
 
-#define OPERATOR(NAME)                                          \
-    case BO_##NAME##Assign:                          \
+#define OPERATOR(NAME)                                                         \
+  case BO_##NAME##Assign:                                                      \
     DISPATCH_WALK(Bin##NAME##Assign, CompoundAssignOperator, S);
 
-    CAO_LIST()
+      CAO_LIST()
 #undef OPERATOR
     }
   } else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(S)) {
     switch (UnOp->getOpcode()) {
-#define OPERATOR(NAME)                                                  \
-    case UO_##NAME: DISPATCH_WALK(Unary##NAME, UnaryOperator, S);
+#define OPERATOR(NAME)                                                         \
+  case UO_##NAME:                                                              \
+    DISPATCH_WALK(Unary##NAME, UnaryOperator, S);
 
-    UNARYOP_LIST()
+      UNARYOP_LIST()
 #undef OPERATOR
     }
   }
 
   // Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt.
   switch (S->getStmtClass()) {
-  case Stmt::NoStmtClass: break;
+  case Stmt::NoStmtClass:
+    break;
 #define ABSTRACT_STMT(STMT)
-#define STMT(CLASS, PARENT) \
-  case Stmt::CLASS##Class: DISPATCH_WALK(CLASS, CLASS, S);
+#define STMT(CLASS, PARENT)                                                    \
+  case Stmt::CLASS##Class:                                                     \
+    DISPATCH_WALK(CLASS, CLASS, S);
 #include "clang/AST/StmtNodes.inc"
   }
 
@@ -536,14 +546,16 @@
   return true;
 }
 
-#define DISPATCH(NAME, CLASS, VAR) \
-  return getDerived().Traverse##NAME(static_cast<CLASS*>(VAR))
+#define DISPATCH(NAME, CLASS, VAR)                                             \
+  return getDerived().Traverse##NAME(static_cast<CLASS *>(VAR))
 
-template<typename Derived>
+template <typename Derived>
 bool RecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S) {
   if (!S)
     return true;
 
+#define DISPATCH_STMT(NAME, CLASS, VAR) DISPATCH(NAME, CLASS, VAR)
+
   if (getDerived().shouldUseDataRecursionFor(S))
     return dataTraverse(S);
 
@@ -552,27 +564,29 @@
   // below.
   if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) {
     switch (BinOp->getOpcode()) {
-#define OPERATOR(NAME) \
-    case BO_##NAME: DISPATCH(Bin##NAME, BinaryOperator, S);
+#define OPERATOR(NAME)                                                         \
+  case BO_##NAME:                                                              \
+    DISPATCH_STMT(Bin##NAME, BinaryOperator, S);
 
-    BINOP_LIST()
+      BINOP_LIST()
 #undef OPERATOR
 #undef BINOP_LIST
 
-#define OPERATOR(NAME)                                          \
-    case BO_##NAME##Assign:                          \
-      DISPATCH(Bin##NAME##Assign, CompoundAssignOperator, S);
+#define OPERATOR(NAME)                                                         \
+  case BO_##NAME##Assign:                                                      \
+    DISPATCH_STMT(Bin##NAME##Assign, CompoundAssignOperator, S);
 
-    CAO_LIST()
+      CAO_LIST()
 #undef OPERATOR
 #undef CAO_LIST
     }
   } else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(S)) {
     switch (UnOp->getOpcode()) {
-#define OPERATOR(NAME)                                                  \
-    case UO_##NAME: DISPATCH(Unary##NAME, UnaryOperator, S);
+#define OPERATOR(NAME)                                                         \
+  case UO_##NAME:                                                              \
+    DISPATCH_STMT(Unary##NAME, UnaryOperator, S);
 
-    UNARYOP_LIST()
+      UNARYOP_LIST()
 #undef OPERATOR
 #undef UNARYOP_LIST
     }
@@ -580,41 +594,45 @@
 
   // Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt.
   switch (S->getStmtClass()) {
-  case Stmt::NoStmtClass: break;
+  case Stmt::NoStmtClass:
+    break;
 #define ABSTRACT_STMT(STMT)
-#define STMT(CLASS, PARENT) \
-  case Stmt::CLASS##Class: DISPATCH(CLASS, CLASS, S);
+#define STMT(CLASS, PARENT)                                                    \
+  case Stmt::CLASS##Class:                                                     \
+    DISPATCH_STMT(CLASS, CLASS, S);
 #include "clang/AST/StmtNodes.inc"
   }
 
   return true;
 }
 
-template<typename Derived>
+#undef DISPATCH_STMT
+
+template <typename Derived>
 bool RecursiveASTVisitor<Derived>::TraverseType(QualType T) {
   if (T.isNull())
     return true;
 
   switch (T->getTypeClass()) {
 #define ABSTRACT_TYPE(CLASS, BASE)
-#define TYPE(CLASS, BASE) \
-  case Type::CLASS: DISPATCH(CLASS##Type, CLASS##Type, \
-                             const_cast<Type*>(T.getTypePtr()));
+#define TYPE(CLASS, BASE)                                                      \
+  case Type::CLASS:                                                            \
+    DISPATCH(CLASS##Type, CLASS##Type, const_cast<Type *>(T.getTypePtr()));
 #include "clang/AST/TypeNodes.def"
   }
 
   return true;
 }
 
-template<typename Derived>
+template <typename Derived>
 bool RecursiveASTVisitor<Derived>::TraverseTypeLoc(TypeLoc TL) {
   if (TL.isNull())
     return true;
 
   switch (TL.getTypeLocClass()) {
 #define ABSTRACT_TYPELOC(CLASS, BASE)
-#define TYPELOC(CLASS, BASE) \
-  case TypeLoc::CLASS: \
+#define TYPELOC(CLASS, BASE)                                                   \
+  case TypeLoc::CLASS:                                                         \
     return getDerived().Traverse##CLASS##TypeLoc(TL.castAs<CLASS##TypeLoc>());
 #include "clang/AST/TypeLocNodes.def"
   }
@@ -622,8 +640,12 @@
   return true;
 }
 
+// Define the Traverse*Attr(Attr* A) methods
+#define VISITORCLASS RecursiveASTVisitor
+#include "clang/AST/AttrVisitor.inc"
+#undef VISITORCLASS
 
-template<typename Derived>
+template <typename Derived>
 bool RecursiveASTVisitor<Derived>::TraverseDecl(Decl *D) {
   if (!D)
     return true;
@@ -635,19 +657,27 @@
 
   switch (D->getKind()) {
 #define ABSTRACT_DECL(DECL)
-#define DECL(CLASS, BASE) \
-  case Decl::CLASS: DISPATCH(CLASS##Decl, CLASS##Decl, D);
+#define DECL(CLASS, BASE)                                                      \
+  case Decl::CLASS:                                                            \
+    if (!getDerived().Traverse##CLASS##Decl(static_cast<CLASS##Decl *>(D)))    \
+      return false;                                                            \
+    break;
 #include "clang/AST/DeclNodes.inc"
- }
+  }
 
+  // Visit any attributes attached to this declaration.
+  for (auto *I : D->attrs()) {
+    if (!getDerived().TraverseAttr(I))
+      return false;
+  }
   return true;
 }
 
 #undef DISPATCH
 
-template<typename Derived>
+template <typename Derived>
 bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifier(
-                                                    NestedNameSpecifier *NNS) {
+    NestedNameSpecifier *NNS) {
   if (!NNS)
     return true;
 
@@ -669,14 +699,14 @@
   return true;
 }
 
-template<typename Derived>
+template <typename Derived>
 bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifierLoc(
-                                                  NestedNameSpecifierLoc NNS) {
+    NestedNameSpecifierLoc NNS) {
   if (!NNS)
     return true;
 
-   if (NestedNameSpecifierLoc Prefix = NNS.getPrefix())
-     TRY_TO(TraverseNestedNameSpecifierLoc(Prefix));
+  if (NestedNameSpecifierLoc Prefix = NNS.getPrefix())
+    TRY_TO(TraverseNestedNameSpecifierLoc(Prefix));
 
   switch (NNS.getNestedNameSpecifier()->getKind()) {
   case NestedNameSpecifier::Identifier:
@@ -694,9 +724,9 @@
   return true;
 }
 
-template<typename Derived>
+template <typename Derived>
 bool RecursiveASTVisitor<Derived>::TraverseDeclarationNameInfo(
-                                                 DeclarationNameInfo NameInfo) {
+    DeclarationNameInfo NameInfo) {
   switch (NameInfo.getName().getNameKind()) {
   case DeclarationName::CXXConstructorName:
   case DeclarationName::CXXDestructorName:
@@ -719,7 +749,7 @@
   return true;
 }
 
-template<typename Derived>
+template <typename Derived>
 bool RecursiveASTVisitor<Derived>::TraverseTemplateName(TemplateName Template) {
   if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
     TRY_TO(TraverseNestedNameSpecifier(DTN->getQualifier()));
@@ -729,9 +759,9 @@
   return true;
 }
 
-template<typename Derived>
+template <typename Derived>
 bool RecursiveASTVisitor<Derived>::TraverseTemplateArgument(
-                                                const TemplateArgument &Arg) {
+    const TemplateArgument &Arg) {
   switch (Arg.getKind()) {
   case TemplateArgument::Null:
   case TemplateArgument::Declaration:
@@ -745,7 +775,7 @@
   case TemplateArgument::Template:
   case TemplateArgument::TemplateExpansion:
     return getDerived().TraverseTemplateName(
-                                          Arg.getAsTemplateOrTemplatePattern());
+        Arg.getAsTemplateOrTemplatePattern());
 
   case TemplateArgument::Expression:
     return getDerived().TraverseStmt(Arg.getAsExpr());
@@ -760,9 +790,9 @@
 
 // FIXME: no template name location?
 // FIXME: no source locations for a template argument pack?
-template<typename Derived>
+template <typename Derived>
 bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc(
-                                           const TemplateArgumentLoc &ArgLoc) {
+    const TemplateArgumentLoc &ArgLoc) {
   const TemplateArgument &Arg = ArgLoc.getArgument();
 
   switch (Arg.getKind()) {
@@ -784,9 +814,9 @@
   case TemplateArgument::TemplateExpansion:
     if (ArgLoc.getTemplateQualifierLoc())
       TRY_TO(getDerived().TraverseNestedNameSpecifierLoc(
-                                            ArgLoc.getTemplateQualifierLoc()));
+          ArgLoc.getTemplateQualifierLoc()));
     return getDerived().TraverseTemplateName(
-                                         Arg.getAsTemplateOrTemplatePattern());
+        Arg.getAsTemplateOrTemplatePattern());
 
   case TemplateArgument::Expression:
     return getDerived().TraverseStmt(ArgLoc.getSourceExpression());
@@ -799,10 +829,9 @@
   return true;
 }
 
-template<typename Derived>
+template <typename Derived>
 bool RecursiveASTVisitor<Derived>::TraverseTemplateArguments(
-                                                  const TemplateArgument *Args,
-                                                            unsigned NumArgs) {
+    const TemplateArgument *Args, unsigned NumArgs) {
   for (unsigned I = 0; I != NumArgs; ++I) {
     TRY_TO(TraverseTemplateArgument(Args[I]));
   }
@@ -810,9 +839,9 @@
   return true;
 }
 
-template<typename Derived>
+template <typename Derived>
 bool RecursiveASTVisitor<Derived>::TraverseConstructorInitializer(
-                                                     CXXCtorInitializer *Init) {
+    CXXCtorInitializer *Init) {
   if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo())
     TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
 
@@ -821,197 +850,164 @@
   return true;
 }
 
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseLambdaCapture(
-    LambdaExpr *LE, const LambdaExpr::Capture *C) {
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::TraverseLambdaCapture(LambdaExpr *LE,
+                                                    const LambdaCapture *C) {
   if (C->isInitCapture())
     TRY_TO(TraverseDecl(C->getCapturedVar()));
   return true;
 }
 
-template<typename Derived>
+template <typename Derived>
 bool RecursiveASTVisitor<Derived>::TraverseLambdaBody(LambdaExpr *LE) {
   TRY_TO(TraverseStmt(LE->getBody()));
   return true;
 }
 
-
 // ----------------- Type traversal -----------------
 
 // This macro makes available a variable T, the passed-in type.
-#define DEF_TRAVERSE_TYPE(TYPE, CODE)                     \
-  template<typename Derived>                                           \
-  bool RecursiveASTVisitor<Derived>::Traverse##TYPE (TYPE *T) {        \
-    TRY_TO(WalkUpFrom##TYPE (T));                                      \
-    { CODE; }                                                          \
-    return true;                                                       \
+#define DEF_TRAVERSE_TYPE(TYPE, CODE)                                          \
+  template <typename Derived>                                                  \
+  bool RecursiveASTVisitor<Derived>::Traverse##TYPE(TYPE *T) {                 \
+    TRY_TO(WalkUpFrom##TYPE(T));                                               \
+    { CODE; }                                                                  \
+    return true;                                                               \
   }
 
-DEF_TRAVERSE_TYPE(BuiltinType, { })
+DEF_TRAVERSE_TYPE(BuiltinType, {})
 
-DEF_TRAVERSE_TYPE(ComplexType, {
-    TRY_TO(TraverseType(T->getElementType()));
-  })
+DEF_TRAVERSE_TYPE(ComplexType, { TRY_TO(TraverseType(T->getElementType())); })
 
-DEF_TRAVERSE_TYPE(PointerType, {
-    TRY_TO(TraverseType(T->getPointeeType()));
-  })
+DEF_TRAVERSE_TYPE(PointerType, { TRY_TO(TraverseType(T->getPointeeType())); })
 
-DEF_TRAVERSE_TYPE(BlockPointerType, {
-    TRY_TO(TraverseType(T->getPointeeType()));
-  })
+DEF_TRAVERSE_TYPE(BlockPointerType,
+                  { TRY_TO(TraverseType(T->getPointeeType())); })
 
-DEF_TRAVERSE_TYPE(LValueReferenceType, {
-    TRY_TO(TraverseType(T->getPointeeType()));
-  })
+DEF_TRAVERSE_TYPE(LValueReferenceType,
+                  { TRY_TO(TraverseType(T->getPointeeType())); })
 
-DEF_TRAVERSE_TYPE(RValueReferenceType, {
-    TRY_TO(TraverseType(T->getPointeeType()));
-  })
+DEF_TRAVERSE_TYPE(RValueReferenceType,
+                  { TRY_TO(TraverseType(T->getPointeeType())); })
 
 DEF_TRAVERSE_TYPE(MemberPointerType, {
-    TRY_TO(TraverseType(QualType(T->getClass(), 0)));
-    TRY_TO(TraverseType(T->getPointeeType()));
-  })
+  TRY_TO(TraverseType(QualType(T->getClass(), 0)));
+  TRY_TO(TraverseType(T->getPointeeType()));
+})
 
-DEF_TRAVERSE_TYPE(DecayedType, {
-    TRY_TO(TraverseType(T->getOriginalType()));
-  })
+DEF_TRAVERSE_TYPE(AdjustedType, { TRY_TO(TraverseType(T->getOriginalType())); })
 
-DEF_TRAVERSE_TYPE(ConstantArrayType, {
-    TRY_TO(TraverseType(T->getElementType()));
-  })
+DEF_TRAVERSE_TYPE(DecayedType, { TRY_TO(TraverseType(T->getOriginalType())); })
 
-DEF_TRAVERSE_TYPE(IncompleteArrayType, {
-    TRY_TO(TraverseType(T->getElementType()));
-  })
+DEF_TRAVERSE_TYPE(ConstantArrayType,
+                  { TRY_TO(TraverseType(T->getElementType())); })
+
+DEF_TRAVERSE_TYPE(IncompleteArrayType,
+                  { TRY_TO(TraverseType(T->getElementType())); })
 
 DEF_TRAVERSE_TYPE(VariableArrayType, {
-    TRY_TO(TraverseType(T->getElementType()));
-    TRY_TO(TraverseStmt(T->getSizeExpr()));
-  })
+  TRY_TO(TraverseType(T->getElementType()));
+  TRY_TO(TraverseStmt(T->getSizeExpr()));
+})
 
 DEF_TRAVERSE_TYPE(DependentSizedArrayType, {
-    TRY_TO(TraverseType(T->getElementType()));
-    if (T->getSizeExpr())
-      TRY_TO(TraverseStmt(T->getSizeExpr()));
-  })
+  TRY_TO(TraverseType(T->getElementType()));
+  if (T->getSizeExpr())
+    TRY_TO(TraverseStmt(T->getSizeExpr()));
+})
 
 DEF_TRAVERSE_TYPE(DependentSizedExtVectorType, {
-    if (T->getSizeExpr())
-      TRY_TO(TraverseStmt(T->getSizeExpr()));
-    TRY_TO(TraverseType(T->getElementType()));
-  })
+  if (T->getSizeExpr())
+    TRY_TO(TraverseStmt(T->getSizeExpr()));
+  TRY_TO(TraverseType(T->getElementType()));
+})
 
-DEF_TRAVERSE_TYPE(VectorType, {
-    TRY_TO(TraverseType(T->getElementType()));
-  })
+DEF_TRAVERSE_TYPE(VectorType, { TRY_TO(TraverseType(T->getElementType())); })
 
-DEF_TRAVERSE_TYPE(ExtVectorType, {
-    TRY_TO(TraverseType(T->getElementType()));
-  })
+DEF_TRAVERSE_TYPE(ExtVectorType, { TRY_TO(TraverseType(T->getElementType())); })
 
-DEF_TRAVERSE_TYPE(FunctionNoProtoType, {
-    TRY_TO(TraverseType(T->getResultType()));
-  })
+DEF_TRAVERSE_TYPE(FunctionNoProtoType,
+                  { TRY_TO(TraverseType(T->getReturnType())); })
 
 DEF_TRAVERSE_TYPE(FunctionProtoType, {
-    TRY_TO(TraverseType(T->getResultType()));
+  TRY_TO(TraverseType(T->getReturnType()));
 
-    for (FunctionProtoType::arg_type_iterator A = T->arg_type_begin(),
-                                           AEnd = T->arg_type_end();
-         A != AEnd; ++A) {
-      TRY_TO(TraverseType(*A));
-    }
+  for (const auto &A : T->param_types()) {
+    TRY_TO(TraverseType(A));
+  }
 
-    for (FunctionProtoType::exception_iterator E = T->exception_begin(),
-                                            EEnd = T->exception_end();
-         E != EEnd; ++E) {
-      TRY_TO(TraverseType(*E));
-    }
-  })
+  for (const auto &E : T->exceptions()) {
+    TRY_TO(TraverseType(E));
+  }
+})
 
-DEF_TRAVERSE_TYPE(UnresolvedUsingType, { })
-DEF_TRAVERSE_TYPE(TypedefType, { })
+DEF_TRAVERSE_TYPE(UnresolvedUsingType, {})
+DEF_TRAVERSE_TYPE(TypedefType, {})
 
-DEF_TRAVERSE_TYPE(TypeOfExprType, {
-    TRY_TO(TraverseStmt(T->getUnderlyingExpr()));
-  })
+DEF_TRAVERSE_TYPE(TypeOfExprType,
+                  { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); })
 
-DEF_TRAVERSE_TYPE(TypeOfType, {
-    TRY_TO(TraverseType(T->getUnderlyingType()));
-  })
+DEF_TRAVERSE_TYPE(TypeOfType, { TRY_TO(TraverseType(T->getUnderlyingType())); })
 
-DEF_TRAVERSE_TYPE(DecltypeType, {
-    TRY_TO(TraverseStmt(T->getUnderlyingExpr()));
-  })
+DEF_TRAVERSE_TYPE(DecltypeType,
+                  { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); })
 
 DEF_TRAVERSE_TYPE(UnaryTransformType, {
-    TRY_TO(TraverseType(T->getBaseType()));
-    TRY_TO(TraverseType(T->getUnderlyingType()));
-    })
+  TRY_TO(TraverseType(T->getBaseType()));
+  TRY_TO(TraverseType(T->getUnderlyingType()));
+})
 
-DEF_TRAVERSE_TYPE(AutoType, {
-    TRY_TO(TraverseType(T->getDeducedType()));
-  })
+DEF_TRAVERSE_TYPE(AutoType, { TRY_TO(TraverseType(T->getDeducedType())); })
 
-DEF_TRAVERSE_TYPE(RecordType, { })
-DEF_TRAVERSE_TYPE(EnumType, { })
-DEF_TRAVERSE_TYPE(TemplateTypeParmType, { })
-DEF_TRAVERSE_TYPE(SubstTemplateTypeParmType, { })
-DEF_TRAVERSE_TYPE(SubstTemplateTypeParmPackType, { })
+DEF_TRAVERSE_TYPE(RecordType, {})
+DEF_TRAVERSE_TYPE(EnumType, {})
+DEF_TRAVERSE_TYPE(TemplateTypeParmType, {})
+DEF_TRAVERSE_TYPE(SubstTemplateTypeParmType, {})
+DEF_TRAVERSE_TYPE(SubstTemplateTypeParmPackType, {})
 
 DEF_TRAVERSE_TYPE(TemplateSpecializationType, {
-    TRY_TO(TraverseTemplateName(T->getTemplateName()));
-    TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
-  })
+  TRY_TO(TraverseTemplateName(T->getTemplateName()));
+  TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
+})
 
-DEF_TRAVERSE_TYPE(InjectedClassNameType, { })
+DEF_TRAVERSE_TYPE(InjectedClassNameType, {})
 
-DEF_TRAVERSE_TYPE(AttributedType, {
-    TRY_TO(TraverseType(T->getModifiedType()));
-  })
+DEF_TRAVERSE_TYPE(AttributedType,
+                  { TRY_TO(TraverseType(T->getModifiedType())); })
 
-DEF_TRAVERSE_TYPE(ParenType, {
-    TRY_TO(TraverseType(T->getInnerType()));
-  })
+DEF_TRAVERSE_TYPE(ParenType, { TRY_TO(TraverseType(T->getInnerType())); })
 
 DEF_TRAVERSE_TYPE(ElaboratedType, {
-    if (T->getQualifier()) {
-      TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
-    }
-    TRY_TO(TraverseType(T->getNamedType()));
-  })
-
-DEF_TRAVERSE_TYPE(DependentNameType, {
+  if (T->getQualifier()) {
     TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
-  })
+  }
+  TRY_TO(TraverseType(T->getNamedType()));
+})
+
+DEF_TRAVERSE_TYPE(DependentNameType,
+                  { TRY_TO(TraverseNestedNameSpecifier(T->getQualifier())); })
 
 DEF_TRAVERSE_TYPE(DependentTemplateSpecializationType, {
-    TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
-    TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
-  })
+  TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
+  TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
+})
 
-DEF_TRAVERSE_TYPE(PackExpansionType, {
-    TRY_TO(TraverseType(T->getPattern()));
-  })
+DEF_TRAVERSE_TYPE(PackExpansionType, { TRY_TO(TraverseType(T->getPattern())); })
 
-DEF_TRAVERSE_TYPE(ObjCInterfaceType, { })
+DEF_TRAVERSE_TYPE(ObjCInterfaceType, {})
 
 DEF_TRAVERSE_TYPE(ObjCObjectType, {
-    // We have to watch out here because an ObjCInterfaceType's base
-    // type is itself.
-    if (T->getBaseType().getTypePtr() != T)
-      TRY_TO(TraverseType(T->getBaseType()));
-  })
+  // We have to watch out here because an ObjCInterfaceType's base
+  // type is itself.
+  if (T->getBaseType().getTypePtr() != T)
+    TRY_TO(TraverseType(T->getBaseType()));
+})
 
-DEF_TRAVERSE_TYPE(ObjCObjectPointerType, {
-    TRY_TO(TraverseType(T->getPointeeType()));
-  })
+DEF_TRAVERSE_TYPE(ObjCObjectPointerType,
+                  { TRY_TO(TraverseType(T->getPointeeType())); })
 
-DEF_TRAVERSE_TYPE(AtomicType, {
-    TRY_TO(TraverseType(T->getValueType()));
-  })
+DEF_TRAVERSE_TYPE(AtomicType, { TRY_TO(TraverseType(T->getValueType())); })
 
 #undef DEF_TRAVERSE_TYPE
 
@@ -1022,19 +1018,19 @@
 // in addition to WalkUpFrom* for the TypeLoc itself, such that existing
 // clients that override the WalkUpFrom*Type() and/or Visit*Type() methods
 // continue to work.
-#define DEF_TRAVERSE_TYPELOC(TYPE, CODE)                                \
-  template<typename Derived>                                            \
-  bool RecursiveASTVisitor<Derived>::Traverse##TYPE##Loc(TYPE##Loc TL) { \
-    if (getDerived().shouldWalkTypesOfTypeLocs())                       \
-      TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE*>(TL.getTypePtr())));     \
-    TRY_TO(WalkUpFrom##TYPE##Loc(TL));                                  \
-    { CODE; }                                                           \
-    return true;                                                        \
+#define DEF_TRAVERSE_TYPELOC(TYPE, CODE)                                       \
+  template <typename Derived>                                                  \
+  bool RecursiveASTVisitor<Derived>::Traverse##TYPE##Loc(TYPE##Loc TL) {       \
+    if (getDerived().shouldWalkTypesOfTypeLocs())                              \
+      TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE *>(TL.getTypePtr())));           \
+    TRY_TO(WalkUpFrom##TYPE##Loc(TL));                                         \
+    { CODE; }                                                                  \
+    return true;                                                               \
   }
 
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseQualifiedTypeLoc(
-    QualifiedTypeLoc TL) {
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::TraverseQualifiedTypeLoc(QualifiedTypeLoc TL) {
   // Move this over to the 'main' typeloc tree.  Note that this is a
   // move -- we pretend that we were really looking at the unqualified
   // typeloc all along -- rather than a recursion, so we don't follow
@@ -1053,42 +1049,40 @@
   return TraverseTypeLoc(TL.getUnqualifiedLoc());
 }
 
-DEF_TRAVERSE_TYPELOC(BuiltinType, { })
+DEF_TRAVERSE_TYPELOC(BuiltinType, {})
 
 // FIXME: ComplexTypeLoc is unfinished
 DEF_TRAVERSE_TYPELOC(ComplexType, {
-    TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
-  })
+  TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+})
 
-DEF_TRAVERSE_TYPELOC(PointerType, {
-    TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
-  })
+DEF_TRAVERSE_TYPELOC(PointerType,
+                     { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
 
-DEF_TRAVERSE_TYPELOC(BlockPointerType, {
-    TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
-  })
+DEF_TRAVERSE_TYPELOC(BlockPointerType,
+                     { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
 
-DEF_TRAVERSE_TYPELOC(LValueReferenceType, {
-    TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
-  })
+DEF_TRAVERSE_TYPELOC(LValueReferenceType,
+                     { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
 
-DEF_TRAVERSE_TYPELOC(RValueReferenceType, {
-    TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
-  })
+DEF_TRAVERSE_TYPELOC(RValueReferenceType,
+                     { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
 
 // FIXME: location of base class?
 // We traverse this in the type case as well, but how is it not reached through
 // the pointee type?
 DEF_TRAVERSE_TYPELOC(MemberPointerType, {
-    TRY_TO(TraverseType(QualType(TL.getTypePtr()->getClass(), 0)));
-    TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
-  })
+  TRY_TO(TraverseType(QualType(TL.getTypePtr()->getClass(), 0)));
+  TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
+})
 
-DEF_TRAVERSE_TYPELOC(DecayedType, {
-    TRY_TO(TraverseTypeLoc(TL.getOriginalLoc()));
-  })
+DEF_TRAVERSE_TYPELOC(AdjustedType,
+                     { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); })
 
-template<typename Derived>
+DEF_TRAVERSE_TYPELOC(DecayedType,
+                     { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); })
+
+template <typename Derived>
 bool RecursiveASTVisitor<Derived>::TraverseArrayTypeLocHelper(ArrayTypeLoc TL) {
   // This isn't available for ArrayType, but is for the ArrayTypeLoc.
   TRY_TO(TraverseStmt(TL.getSizeExpr()));
@@ -1096,158 +1090,147 @@
 }
 
 DEF_TRAVERSE_TYPELOC(ConstantArrayType, {
-    TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
-    return TraverseArrayTypeLocHelper(TL);
-  })
+  TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+  return TraverseArrayTypeLocHelper(TL);
+})
 
 DEF_TRAVERSE_TYPELOC(IncompleteArrayType, {
-    TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
-    return TraverseArrayTypeLocHelper(TL);
-  })
+  TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+  return TraverseArrayTypeLocHelper(TL);
+})
 
 DEF_TRAVERSE_TYPELOC(VariableArrayType, {
-    TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
-    return TraverseArrayTypeLocHelper(TL);
-  })
+  TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+  return TraverseArrayTypeLocHelper(TL);
+})
 
 DEF_TRAVERSE_TYPELOC(DependentSizedArrayType, {
-    TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
-    return TraverseArrayTypeLocHelper(TL);
-  })
+  TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+  return TraverseArrayTypeLocHelper(TL);
+})
 
 // FIXME: order? why not size expr first?
 // FIXME: base VectorTypeLoc is unfinished
 DEF_TRAVERSE_TYPELOC(DependentSizedExtVectorType, {
-    if (TL.getTypePtr()->getSizeExpr())
-      TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
-    TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
-  })
+  if (TL.getTypePtr()->getSizeExpr())
+    TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
+  TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+})
 
 // FIXME: VectorTypeLoc is unfinished
 DEF_TRAVERSE_TYPELOC(VectorType, {
-    TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
-  })
+  TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+})
 
 // FIXME: size and attributes
 // FIXME: base VectorTypeLoc is unfinished
 DEF_TRAVERSE_TYPELOC(ExtVectorType, {
-    TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
-  })
+  TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+})
 
-DEF_TRAVERSE_TYPELOC(FunctionNoProtoType, {
-    TRY_TO(TraverseTypeLoc(TL.getResultLoc()));
-  })
+DEF_TRAVERSE_TYPELOC(FunctionNoProtoType,
+                     { TRY_TO(TraverseTypeLoc(TL.getReturnLoc())); })
 
 // FIXME: location of exception specifications (attributes?)
 DEF_TRAVERSE_TYPELOC(FunctionProtoType, {
-    TRY_TO(TraverseTypeLoc(TL.getResultLoc()));
+  TRY_TO(TraverseTypeLoc(TL.getReturnLoc()));
 
-    const FunctionProtoType *T = TL.getTypePtr();
+  const FunctionProtoType *T = TL.getTypePtr();
 
-    for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
-      if (TL.getArg(I)) {
-        TRY_TO(TraverseDecl(TL.getArg(I)));
-      } else if (I < T->getNumArgs()) {
-        TRY_TO(TraverseType(T->getArgType(I)));
-      }
+  for (unsigned I = 0, E = TL.getNumParams(); I != E; ++I) {
+    if (TL.getParam(I)) {
+      TRY_TO(TraverseDecl(TL.getParam(I)));
+    } else if (I < T->getNumParams()) {
+      TRY_TO(TraverseType(T->getParamType(I)));
     }
+  }
 
-    for (FunctionProtoType::exception_iterator E = T->exception_begin(),
-                                            EEnd = T->exception_end();
-         E != EEnd; ++E) {
-      TRY_TO(TraverseType(*E));
-    }
-  })
+  for (const auto &E : T->exceptions()) {
+    TRY_TO(TraverseType(E));
+  }
+})
 
-DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, { })
-DEF_TRAVERSE_TYPELOC(TypedefType, { })
+DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, {})
+DEF_TRAVERSE_TYPELOC(TypedefType, {})
 
-DEF_TRAVERSE_TYPELOC(TypeOfExprType, {
-    TRY_TO(TraverseStmt(TL.getUnderlyingExpr()));
-  })
+DEF_TRAVERSE_TYPELOC(TypeOfExprType,
+                     { TRY_TO(TraverseStmt(TL.getUnderlyingExpr())); })
 
 DEF_TRAVERSE_TYPELOC(TypeOfType, {
-    TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
-  })
+  TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
+})
 
 // FIXME: location of underlying expr
 DEF_TRAVERSE_TYPELOC(DecltypeType, {
-    TRY_TO(TraverseStmt(TL.getTypePtr()->getUnderlyingExpr()));
-  })
+  TRY_TO(TraverseStmt(TL.getTypePtr()->getUnderlyingExpr()));
+})
 
 DEF_TRAVERSE_TYPELOC(UnaryTransformType, {
-    TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
-  })
+  TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
+})
 
 DEF_TRAVERSE_TYPELOC(AutoType, {
-    TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
-  })
+  TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
+})
 
-DEF_TRAVERSE_TYPELOC(RecordType, { })
-DEF_TRAVERSE_TYPELOC(EnumType, { })
-DEF_TRAVERSE_TYPELOC(TemplateTypeParmType, { })
-DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmType, { })
-DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmPackType, { })
+DEF_TRAVERSE_TYPELOC(RecordType, {})
+DEF_TRAVERSE_TYPELOC(EnumType, {})
+DEF_TRAVERSE_TYPELOC(TemplateTypeParmType, {})
+DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmType, {})
+DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmPackType, {})
 
 // FIXME: use the loc for the template name?
 DEF_TRAVERSE_TYPELOC(TemplateSpecializationType, {
-    TRY_TO(TraverseTemplateName(TL.getTypePtr()->getTemplateName()));
-    for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
-      TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
-    }
-  })
+  TRY_TO(TraverseTemplateName(TL.getTypePtr()->getTemplateName()));
+  for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
+    TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
+  }
+})
 
-DEF_TRAVERSE_TYPELOC(InjectedClassNameType, { })
+DEF_TRAVERSE_TYPELOC(InjectedClassNameType, {})
 
-DEF_TRAVERSE_TYPELOC(ParenType, {
-    TRY_TO(TraverseTypeLoc(TL.getInnerLoc()));
-  })
+DEF_TRAVERSE_TYPELOC(ParenType, { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
 
-DEF_TRAVERSE_TYPELOC(AttributedType, {
-    TRY_TO(TraverseTypeLoc(TL.getModifiedLoc()));
-  })
+DEF_TRAVERSE_TYPELOC(AttributedType,
+                     { TRY_TO(TraverseTypeLoc(TL.getModifiedLoc())); })
 
 DEF_TRAVERSE_TYPELOC(ElaboratedType, {
-    if (TL.getQualifierLoc()) {
-      TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
-    }
-    TRY_TO(TraverseTypeLoc(TL.getNamedTypeLoc()));
-  })
+  if (TL.getQualifierLoc()) {
+    TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
+  }
+  TRY_TO(TraverseTypeLoc(TL.getNamedTypeLoc()));
+})
 
 DEF_TRAVERSE_TYPELOC(DependentNameType, {
-    TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
-  })
+  TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
+})
 
 DEF_TRAVERSE_TYPELOC(DependentTemplateSpecializationType, {
-    if (TL.getQualifierLoc()) {
-      TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
-    }
+  if (TL.getQualifierLoc()) {
+    TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
+  }
 
-    for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
-      TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
-    }
-  })
+  for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
+    TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
+  }
+})
 
-DEF_TRAVERSE_TYPELOC(PackExpansionType, {
-    TRY_TO(TraverseTypeLoc(TL.getPatternLoc()));
-  })
+DEF_TRAVERSE_TYPELOC(PackExpansionType,
+                     { TRY_TO(TraverseTypeLoc(TL.getPatternLoc())); })
 
-DEF_TRAVERSE_TYPELOC(ObjCInterfaceType, { })
+DEF_TRAVERSE_TYPELOC(ObjCInterfaceType, {})
 
 DEF_TRAVERSE_TYPELOC(ObjCObjectType, {
-    // We have to watch out here because an ObjCInterfaceType's base
-    // type is itself.
-    if (TL.getTypePtr()->getBaseType().getTypePtr() != TL.getTypePtr())
-      TRY_TO(TraverseTypeLoc(TL.getBaseLoc()));
-  })
+  // We have to watch out here because an ObjCInterfaceType's base
+  // type is itself.
+  if (TL.getTypePtr()->getBaseType().getTypePtr() != TL.getTypePtr())
+    TRY_TO(TraverseTypeLoc(TL.getBaseLoc()));
+})
 
-DEF_TRAVERSE_TYPELOC(ObjCObjectPointerType, {
-    TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
-  })
+DEF_TRAVERSE_TYPELOC(ObjCObjectPointerType,
+                     { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
 
-DEF_TRAVERSE_TYPELOC(AtomicType, {
-    TRY_TO(TraverseTypeLoc(TL.getValueLoc()));
-  })
+DEF_TRAVERSE_TYPELOC(AtomicType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
 
 #undef DEF_TRAVERSE_TYPELOC
 
@@ -1258,195 +1241,191 @@
 // Therefore each Traverse* only needs to worry about children other
 // than those.
 
-template<typename Derived>
+template <typename Derived>
 bool RecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) {
   if (!DC)
     return true;
 
-  for (DeclContext::decl_iterator Child = DC->decls_begin(),
-           ChildEnd = DC->decls_end();
-       Child != ChildEnd; ++Child) {
+  for (auto *Child : DC->decls()) {
     // BlockDecls and CapturedDecls are traversed through BlockExprs and
     // CapturedStmts respectively.
-    if (!isa<BlockDecl>(*Child) && !isa<CapturedDecl>(*Child))
-      TRY_TO(TraverseDecl(*Child));
+    if (!isa<BlockDecl>(Child) && !isa<CapturedDecl>(Child))
+      TRY_TO(TraverseDecl(Child));
   }
 
   return true;
 }
 
 // This macro makes available a variable D, the passed-in decl.
-#define DEF_TRAVERSE_DECL(DECL, CODE)                           \
-template<typename Derived>                                      \
-bool RecursiveASTVisitor<Derived>::Traverse##DECL (DECL *D) {   \
-  TRY_TO(WalkUpFrom##DECL (D));                                 \
-  { CODE; }                                                     \
-  TRY_TO(TraverseDeclContextHelper(dyn_cast<DeclContext>(D)));  \
-  return true;                                                  \
-}
+#define DEF_TRAVERSE_DECL(DECL, CODE)                                          \
+  template <typename Derived>                                                  \
+  bool RecursiveASTVisitor<Derived>::Traverse##DECL(DECL *D) {                 \
+    TRY_TO(WalkUpFrom##DECL(D));                                               \
+    { CODE; }                                                                  \
+    TRY_TO(TraverseDeclContextHelper(dyn_cast<DeclContext>(D)));               \
+    return true;                                                               \
+  }
 
-DEF_TRAVERSE_DECL(AccessSpecDecl, { })
+DEF_TRAVERSE_DECL(AccessSpecDecl, {})
 
 DEF_TRAVERSE_DECL(BlockDecl, {
-    if (TypeSourceInfo *TInfo = D->getSignatureAsWritten())
-      TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
-    TRY_TO(TraverseStmt(D->getBody()));
-    // This return statement makes sure the traversal of nodes in
-    // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
-    // is skipped - don't remove it.
-    return true;
-  })
-
-DEF_TRAVERSE_DECL(CapturedDecl, {
-    TRY_TO(TraverseStmt(D->getBody()));
-    // This return statement makes sure the traversal of nodes in
-    // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
-    // is skipped - don't remove it.
-    return true;
-  })
-
-DEF_TRAVERSE_DECL(EmptyDecl, { })
-
-DEF_TRAVERSE_DECL(FileScopeAsmDecl, {
-    TRY_TO(TraverseStmt(D->getAsmString()));
-  })
-
-DEF_TRAVERSE_DECL(ImportDecl, { })
-
-DEF_TRAVERSE_DECL(FriendDecl, {
-    // Friend is either decl or a type.
-    if (D->getFriendType())
-      TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
-    else
-      TRY_TO(TraverseDecl(D->getFriendDecl()));
-  })
-
-DEF_TRAVERSE_DECL(FriendTemplateDecl, {
-    if (D->getFriendType())
-      TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
-    else
-      TRY_TO(TraverseDecl(D->getFriendDecl()));
-    for (unsigned I = 0, E = D->getNumTemplateParameters(); I < E; ++I) {
-      TemplateParameterList *TPL = D->getTemplateParameterList(I);
-      for (TemplateParameterList::iterator ITPL = TPL->begin(),
-                                           ETPL = TPL->end();
-           ITPL != ETPL; ++ITPL) {
-        TRY_TO(TraverseDecl(*ITPL));
-      }
+  if (TypeSourceInfo *TInfo = D->getSignatureAsWritten())
+    TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
+  TRY_TO(TraverseStmt(D->getBody()));
+  for (const auto &I : D->captures()) {
+    if (I.hasCopyExpr()) {
+      TRY_TO(TraverseStmt(I.getCopyExpr()));
     }
-  })
-
-DEF_TRAVERSE_DECL(ClassScopeFunctionSpecializationDecl, {
-    TRY_TO(TraverseDecl(D->getSpecialization()));
-
-    if (D->hasExplicitTemplateArgs()) {
-      const TemplateArgumentListInfo& args = D->templateArgs();
-      TRY_TO(TraverseTemplateArgumentLocsHelper(
-          args.getArgumentArray(), args.size()));
-    }
- })
-
-DEF_TRAVERSE_DECL(LinkageSpecDecl, { })
-
-DEF_TRAVERSE_DECL(ObjCPropertyImplDecl, {
-    // FIXME: implement this
-  })
-
-DEF_TRAVERSE_DECL(StaticAssertDecl, {
-    TRY_TO(TraverseStmt(D->getAssertExpr()));
-    TRY_TO(TraverseStmt(D->getMessage()));
-  })
-
-DEF_TRAVERSE_DECL(TranslationUnitDecl, {
-    // Code in an unnamed namespace shows up automatically in
-    // decls_begin()/decls_end().  Thus we don't need to recurse on
-    // D->getAnonymousNamespace().
-  })
-
-DEF_TRAVERSE_DECL(NamespaceAliasDecl, {
-    // We shouldn't traverse an aliased namespace, since it will be
-    // defined (and, therefore, traversed) somewhere else.
-    //
-    // This return statement makes sure the traversal of nodes in
-    // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
-    // is skipped - don't remove it.
-    return true;
-  })
-
-DEF_TRAVERSE_DECL(LabelDecl, {
-  // There is no code in a LabelDecl.
+  }
+  // This return statement makes sure the traversal of nodes in
+  // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
+  // is skipped - don't remove it.
+  return true;
 })
 
+DEF_TRAVERSE_DECL(CapturedDecl, {
+  TRY_TO(TraverseStmt(D->getBody()));
+  // This return statement makes sure the traversal of nodes in
+  // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
+  // is skipped - don't remove it.
+  return true;
+})
 
-DEF_TRAVERSE_DECL(NamespaceDecl, {
-    // Code in an unnamed namespace shows up automatically in
-    // decls_begin()/decls_end().  Thus we don't need to recurse on
-    // D->getAnonymousNamespace().
-  })
+DEF_TRAVERSE_DECL(EmptyDecl, {})
 
-DEF_TRAVERSE_DECL(ObjCCompatibleAliasDecl, {
-    // FIXME: implement
-  })
+DEF_TRAVERSE_DECL(FileScopeAsmDecl,
+                  { TRY_TO(TraverseStmt(D->getAsmString())); })
 
-DEF_TRAVERSE_DECL(ObjCCategoryDecl, {
-    // FIXME: implement
-  })
+DEF_TRAVERSE_DECL(ImportDecl, {})
 
-DEF_TRAVERSE_DECL(ObjCCategoryImplDecl, {
-    // FIXME: implement
-  })
+DEF_TRAVERSE_DECL(FriendDecl, {
+  // Friend is either decl or a type.
+  if (D->getFriendType())
+    TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
+  else
+    TRY_TO(TraverseDecl(D->getFriendDecl()));
+})
 
-DEF_TRAVERSE_DECL(ObjCImplementationDecl, {
-    // FIXME: implement
-  })
+DEF_TRAVERSE_DECL(FriendTemplateDecl, {
+  if (D->getFriendType())
+    TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
+  else
+    TRY_TO(TraverseDecl(D->getFriendDecl()));
+  for (unsigned I = 0, E = D->getNumTemplateParameters(); I < E; ++I) {
+    TemplateParameterList *TPL = D->getTemplateParameterList(I);
+    for (TemplateParameterList::iterator ITPL = TPL->begin(), ETPL = TPL->end();
+         ITPL != ETPL; ++ITPL) {
+      TRY_TO(TraverseDecl(*ITPL));
+    }
+  }
+})
 
-DEF_TRAVERSE_DECL(ObjCInterfaceDecl, {
-    // FIXME: implement
-  })
+DEF_TRAVERSE_DECL(ClassScopeFunctionSpecializationDecl, {
+  TRY_TO(TraverseDecl(D->getSpecialization()));
 
-DEF_TRAVERSE_DECL(ObjCProtocolDecl, {
-    // FIXME: implement
-  })
+  if (D->hasExplicitTemplateArgs()) {
+    const TemplateArgumentListInfo &args = D->templateArgs();
+    TRY_TO(TraverseTemplateArgumentLocsHelper(args.getArgumentArray(),
+                                              args.size()));
+  }
+})
+
+DEF_TRAVERSE_DECL(LinkageSpecDecl, {})
+
+DEF_TRAVERSE_DECL(ObjCPropertyImplDecl, {// FIXME: implement this
+                                        })
+
+DEF_TRAVERSE_DECL(StaticAssertDecl, {
+  TRY_TO(TraverseStmt(D->getAssertExpr()));
+  TRY_TO(TraverseStmt(D->getMessage()));
+})
+
+DEF_TRAVERSE_DECL(
+    TranslationUnitDecl,
+    {// Code in an unnamed namespace shows up automatically in
+     // decls_begin()/decls_end().  Thus we don't need to recurse on
+     // D->getAnonymousNamespace().
+    })
+
+DEF_TRAVERSE_DECL(NamespaceAliasDecl, {
+  // We shouldn't traverse an aliased namespace, since it will be
+  // defined (and, therefore, traversed) somewhere else.
+  //
+  // This return statement makes sure the traversal of nodes in
+  // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
+  // is skipped - don't remove it.
+  return true;
+})
+
+DEF_TRAVERSE_DECL(LabelDecl, {// There is no code in a LabelDecl.
+                             })
+
+DEF_TRAVERSE_DECL(
+    NamespaceDecl,
+    {// Code in an unnamed namespace shows up automatically in
+     // decls_begin()/decls_end().  Thus we don't need to recurse on
+     // D->getAnonymousNamespace().
+    })
+
+DEF_TRAVERSE_DECL(ObjCCompatibleAliasDecl, {// FIXME: implement
+                                           })
+
+DEF_TRAVERSE_DECL(ObjCCategoryDecl, {// FIXME: implement
+                                    })
+
+DEF_TRAVERSE_DECL(ObjCCategoryImplDecl, {// FIXME: implement
+                                        })
+
+DEF_TRAVERSE_DECL(ObjCImplementationDecl, {// FIXME: implement
+                                          })
+
+DEF_TRAVERSE_DECL(ObjCInterfaceDecl, {// FIXME: implement
+                                     })
+
+DEF_TRAVERSE_DECL(ObjCProtocolDecl, {// FIXME: implement
+                                    })
 
 DEF_TRAVERSE_DECL(ObjCMethodDecl, {
-    if (D->getResultTypeSourceInfo()) {
-      TRY_TO(TraverseTypeLoc(D->getResultTypeSourceInfo()->getTypeLoc()));
-    }
-    for (ObjCMethodDecl::param_iterator
-           I = D->param_begin(), E = D->param_end(); I != E; ++I) {
-      TRY_TO(TraverseDecl(*I));
-    }
-    if (D->isThisDeclarationADefinition()) {
-      TRY_TO(TraverseStmt(D->getBody()));
-    }
-    return true;
-  })
+  if (D->getReturnTypeSourceInfo()) {
+    TRY_TO(TraverseTypeLoc(D->getReturnTypeSourceInfo()->getTypeLoc()));
+  }
+  for (ObjCMethodDecl::param_iterator I = D->param_begin(), E = D->param_end();
+       I != E; ++I) {
+    TRY_TO(TraverseDecl(*I));
+  }
+  if (D->isThisDeclarationADefinition()) {
+    TRY_TO(TraverseStmt(D->getBody()));
+  }
+  return true;
+})
 
 DEF_TRAVERSE_DECL(ObjCPropertyDecl, {
-    // FIXME: implement
-  })
+  if (D->getTypeSourceInfo())
+    TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
+  else
+    TRY_TO(TraverseType(D->getType()));
+  return true;
+})
 
 DEF_TRAVERSE_DECL(UsingDecl, {
-    TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
-    TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
-  })
+  TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+  TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
+})
 
 DEF_TRAVERSE_DECL(UsingDirectiveDecl, {
-    TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
-  })
+  TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+})
 
-DEF_TRAVERSE_DECL(UsingShadowDecl, { })
+DEF_TRAVERSE_DECL(UsingShadowDecl, {})
 
 DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, {
-    for (OMPThreadPrivateDecl::varlist_iterator I = D->varlist_begin(),
-                                                E = D->varlist_end();
-         I != E; ++I) {
-      TRY_TO(TraverseStmt(*I));
-    }
-  })
+  for (auto *I : D->varlists()) {
+    TRY_TO(TraverseStmt(I));
+  }
+})
 
 // A helper method for TemplateDecl's children.
-template<typename Derived>
+template <typename Derived>
 bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper(
     TemplateParameterList *TPL) {
   if (TPL) {
@@ -1458,65 +1437,84 @@
   return true;
 }
 
-#define DEF_TRAVERSE_TMPL_INST(TMPLDECLKIND)                                 \
-/* A helper method for traversing the implicit instantiations of a
-   class or variable template. */                                            \
-template<typename Derived>                                                   \
-bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(           \
-    TMPLDECLKIND##TemplateDecl *D) {                                         \
-  TMPLDECLKIND##TemplateDecl::spec_iterator end = D->spec_end();             \
-  for (TMPLDECLKIND##TemplateDecl::spec_iterator it = D->spec_begin();       \
-       it != end; ++it) {                                                    \
-    TMPLDECLKIND##TemplateSpecializationDecl* SD = *it;                      \
-                                                                             \
-    switch (SD->getSpecializationKind()) {                                   \
-    /* Visit the implicit instantiations with the requested pattern. */      \
-    case TSK_Undeclared:                                                     \
-    case TSK_ImplicitInstantiation:                                          \
-      TRY_TO(TraverseDecl(SD));                                              \
-      break;                                                                 \
-                                                                             \
-    /* We don't need to do anything on an explicit instantiation             
-       or explicit specialization because there will be an explicit
-       node for it elsewhere. */                                             \
-    case TSK_ExplicitInstantiationDeclaration:                               \
-    case TSK_ExplicitInstantiationDefinition:                                \
-    case TSK_ExplicitSpecialization:                                         \
-      break;                                                                 \
-    }                                                                        \
-  }                                                                          \
-                                                                             \
-  return true;                                                               \
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
+    ClassTemplateDecl *D) {
+  for (auto *SD : D->specializations()) {
+    for (auto *RD : SD->redecls()) {
+      // We don't want to visit injected-class-names in this traversal.
+      if (cast<CXXRecordDecl>(RD)->isInjectedClassName())
+        continue;
+
+      switch (
+          cast<ClassTemplateSpecializationDecl>(RD)->getSpecializationKind()) {
+      // Visit the implicit instantiations with the requested pattern.
+      case TSK_Undeclared:
+      case TSK_ImplicitInstantiation:
+        TRY_TO(TraverseDecl(RD));
+        break;
+
+      // We don't need to do anything on an explicit instantiation
+      // or explicit specialization because there will be an explicit
+      // node for it elsewhere.
+      case TSK_ExplicitInstantiationDeclaration:
+      case TSK_ExplicitInstantiationDefinition:
+      case TSK_ExplicitSpecialization:
+        break;
+      }
+    }
+  }
+
+  return true;
 }
-   
-DEF_TRAVERSE_TMPL_INST(Class)
-DEF_TRAVERSE_TMPL_INST(Var)
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
+    VarTemplateDecl *D) {
+  for (auto *SD : D->specializations()) {
+    for (auto *RD : SD->redecls()) {
+      switch (
+          cast<VarTemplateSpecializationDecl>(RD)->getSpecializationKind()) {
+      case TSK_Undeclared:
+      case TSK_ImplicitInstantiation:
+        TRY_TO(TraverseDecl(RD));
+        break;
+
+      case TSK_ExplicitInstantiationDeclaration:
+      case TSK_ExplicitInstantiationDefinition:
+      case TSK_ExplicitSpecialization:
+        break;
+      }
+    }
+  }
+
+  return true;
+}
 
 // A helper method for traversing the instantiations of a
 // function while skipping its specializations.
-template<typename Derived>
+template <typename Derived>
 bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
     FunctionTemplateDecl *D) {
-  FunctionTemplateDecl::spec_iterator end = D->spec_end();
-  for (FunctionTemplateDecl::spec_iterator it = D->spec_begin(); it != end;
-       ++it) {
-    FunctionDecl* FD = *it;
-    switch (FD->getTemplateSpecializationKind()) {
-    case TSK_Undeclared:
-    case TSK_ImplicitInstantiation:
-      // We don't know what kind of FunctionDecl this is.
-      TRY_TO(TraverseDecl(FD));
-      break;
+  for (auto *FD : D->specializations()) {
+    for (auto *RD : FD->redecls()) {
+      switch (RD->getTemplateSpecializationKind()) {
+      case TSK_Undeclared:
+      case TSK_ImplicitInstantiation:
+        // We don't know what kind of FunctionDecl this is.
+        TRY_TO(TraverseDecl(RD));
+        break;
 
-    // FIXME: For now traverse explicit instantiations here. Change that
-    // once they are represented as dedicated nodes in the AST.
-    case TSK_ExplicitInstantiationDeclaration:
-    case TSK_ExplicitInstantiationDefinition:
-      TRY_TO(TraverseDecl(FD));
-      break;
+      // FIXME: For now traverse explicit instantiations here. Change that
+      // once they are represented as dedicated nodes in the AST.
+      case TSK_ExplicitInstantiationDeclaration:
+      case TSK_ExplicitInstantiationDefinition:
+        TRY_TO(TraverseDecl(RD));
+        break;
 
-    case TSK_ExplicitSpecialization:
-      break;
+      case TSK_ExplicitSpecialization:
+        break;
+      }
     }
   }
 
@@ -1525,24 +1523,24 @@
 
 // This macro unifies the traversal of class, variable and function
 // template declarations.
-#define DEF_TRAVERSE_TMPL_DECL(TMPLDECLKIND)                                 \
-DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateDecl, {                              \
-    TRY_TO(TraverseDecl(D->getTemplatedDecl()));                             \
-    TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); \
-                                                                             \
-    /* By default, we do not traverse the instantiations of
-       class templates since they do not appear in the user code. The
-       following code optionally traverses them.
-       
-       We only traverse the class instantiations when we see the canonical
-       declaration of the template, to ensure we only visit them once. */    \
-    if (getDerived().shouldVisitTemplateInstantiations() &&                  \
-        D == D->getCanonicalDecl())                                          \
-      TRY_TO(TraverseTemplateInstantiations(D));                             \
-                                                                             \
-    /* Note that getInstantiatedFromMemberTemplate() is just a link
-       from a template instantiation back to the template from which
-       it was instantiated, and thus should not be traversed. */             \
+#define DEF_TRAVERSE_TMPL_DECL(TMPLDECLKIND)                                   \
+  DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateDecl, {                              \
+    TRY_TO(TraverseDecl(D->getTemplatedDecl()));                               \
+    TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));   \
+                                                                               \
+    /* By default, we do not traverse the instantiations of                    \
+       class templates since they do not appear in the user code. The          \
+       following code optionally traverses them.                               \
+                                                                               \
+       We only traverse the class instantiations when we see the canonical     \
+       declaration of the template, to ensure we only visit them once. */      \
+    if (getDerived().shouldVisitTemplateInstantiations() &&                    \
+        D == D->getCanonicalDecl())                                            \
+      TRY_TO(TraverseTemplateInstantiations(D));                               \
+                                                                               \
+    /* Note that getInstantiatedFromMemberTemplate() is just a link            \
+       from a template instantiation back to the template from which           \
+       it was instantiated, and thus should not be traversed. */               \
   })
 
 DEF_TRAVERSE_TMPL_DECL(Class)
@@ -1550,65 +1548,63 @@
 DEF_TRAVERSE_TMPL_DECL(Function)
 
 DEF_TRAVERSE_DECL(TemplateTemplateParmDecl, {
-    // D is the "T" in something like
-    //   template <template <typename> class T> class container { };
-    TRY_TO(TraverseDecl(D->getTemplatedDecl()));
-    if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) {
-      TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
-    }
-    TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
-  })
+  // D is the "T" in something like
+  //   template <template <typename> class T> class container { };
+  TRY_TO(TraverseDecl(D->getTemplatedDecl()));
+  if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) {
+    TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
+  }
+  TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
+})
 
 DEF_TRAVERSE_DECL(TemplateTypeParmDecl, {
-    // D is the "T" in something like "template<typename T> class vector;"
-    if (D->getTypeForDecl())
-      TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
-    if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
-      TRY_TO(TraverseTypeLoc(D->getDefaultArgumentInfo()->getTypeLoc()));
-  })
+  // D is the "T" in something like "template<typename T> class vector;"
+  if (D->getTypeForDecl())
+    TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
+  if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
+    TRY_TO(TraverseTypeLoc(D->getDefaultArgumentInfo()->getTypeLoc()));
+})
 
 DEF_TRAVERSE_DECL(TypedefDecl, {
-    TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
-    // We shouldn't traverse D->getTypeForDecl(); it's a result of
-    // declaring the typedef, not something that was written in the
-    // source.
-  })
+  TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
+  // We shouldn't traverse D->getTypeForDecl(); it's a result of
+  // declaring the typedef, not something that was written in the
+  // source.
+})
 
 DEF_TRAVERSE_DECL(TypeAliasDecl, {
-    TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
-    // We shouldn't traverse D->getTypeForDecl(); it's a result of
-    // declaring the type alias, not something that was written in the
-    // source.
-  })
+  TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
+  // We shouldn't traverse D->getTypeForDecl(); it's a result of
+  // declaring the type alias, not something that was written in the
+  // source.
+})
 
 DEF_TRAVERSE_DECL(TypeAliasTemplateDecl, {
-    TRY_TO(TraverseDecl(D->getTemplatedDecl()));
-    TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
-  })
+  TRY_TO(TraverseDecl(D->getTemplatedDecl()));
+  TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
+})
 
 DEF_TRAVERSE_DECL(UnresolvedUsingTypenameDecl, {
-    // A dependent using declaration which was marked with 'typename'.
-    //   template<class T> class A : public B<T> { using typename B<T>::foo; };
-    TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
-    // We shouldn't traverse D->getTypeForDecl(); it's a result of
-    // declaring the type, not something that was written in the
-    // source.
-  })
+  // A dependent using declaration which was marked with 'typename'.
+  //   template<class T> class A : public B<T> { using typename B<T>::foo; };
+  TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+  // We shouldn't traverse D->getTypeForDecl(); it's a result of
+  // declaring the type, not something that was written in the
+  // source.
+})
 
 DEF_TRAVERSE_DECL(EnumDecl, {
-    if (D->getTypeForDecl())
-      TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
+  if (D->getTypeForDecl())
+    TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
 
-    TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
-    // The enumerators are already traversed by
-    // decls_begin()/decls_end().
-  })
-
+  TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+  // The enumerators are already traversed by
+  // decls_begin()/decls_end().
+})
 
 // Helper methods for RecordDecl and its children.
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseRecordHelper(
-    RecordDecl *D) {
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseRecordHelper(RecordDecl *D) {
   // We shouldn't traverse D->getTypeForDecl(); it's a result of
   // declaring the type, not something that was written in the source.
 
@@ -1616,16 +1612,13 @@
   return true;
 }
 
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseCXXRecordHelper(
-    CXXRecordDecl *D) {
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseCXXRecordHelper(CXXRecordDecl *D) {
   if (!TraverseRecordHelper(D))
     return false;
   if (D->isCompleteDefinition()) {
-    for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
-                                            E = D->bases_end();
-         I != E; ++I) {
-      TRY_TO(TraverseTypeLoc(I->getTypeSourceInfo()->getTypeLoc()));
+    for (const auto &I : D->bases()) {
+      TRY_TO(TraverseTypeLoc(I.getTypeSourceInfo()->getTypeLoc()));
     }
     // We don't traverse the friends or the conversions, as they are
     // already in decls_begin()/decls_end().
@@ -1633,34 +1626,30 @@
   return true;
 }
 
-DEF_TRAVERSE_DECL(RecordDecl, {
-    TRY_TO(TraverseRecordHelper(D));
-  })
+DEF_TRAVERSE_DECL(RecordDecl, { TRY_TO(TraverseRecordHelper(D)); })
 
-DEF_TRAVERSE_DECL(CXXRecordDecl, {
-    TRY_TO(TraverseCXXRecordHelper(D));
-  })
+DEF_TRAVERSE_DECL(CXXRecordDecl, { TRY_TO(TraverseCXXRecordHelper(D)); })
 
-#define DEF_TRAVERSE_TMPL_SPEC_DECL(TMPLDECLKIND) \
-DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateSpecializationDecl, {                \
-    /* For implicit instantiations ("set<int> x;"), we don't want to
-       recurse at all, since the instatiated template isn't written in
-       the source code anywhere.  (Note the instatiated *type* --
-       set<int> -- is written, and will still get a callback of
-       TemplateSpecializationType).  For explicit instantiations
-       ("template set<int>;"), we do need a callback, since this
-       is the only callback that's made for this instantiation.
-       We use getTypeAsWritten() to distinguish. */                          \
-    if (TypeSourceInfo *TSI = D->getTypeAsWritten())                         \
-      TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));                            \
-                                                                             \
-    if (!getDerived().shouldVisitTemplateInstantiations() &&                 \
-        D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization)    \
-      /* Returning from here skips traversing the
-         declaration context of the *TemplateSpecializationDecl
-         (embedded in the DEF_TRAVERSE_DECL() macro)
-         which contains the instantiated members of the template. */         \
-      return true;                                                           \
+#define DEF_TRAVERSE_TMPL_SPEC_DECL(TMPLDECLKIND)                              \
+  DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateSpecializationDecl, {                \
+    /* For implicit instantiations ("set<int> x;"), we don't want to           \
+       recurse at all, since the instatiated template isn't written in         \
+       the source code anywhere.  (Note the instatiated *type* --              \
+       set<int> -- is written, and will still get a callback of                \
+       TemplateSpecializationType).  For explicit instantiations               \
+       ("template set<int>;"), we do need a callback, since this               \
+       is the only callback that's made for this instantiation.                \
+       We use getTypeAsWritten() to distinguish. */                            \
+    if (TypeSourceInfo *TSI = D->getTypeAsWritten())                           \
+      TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));                              \
+                                                                               \
+    if (!getDerived().shouldVisitTemplateInstantiations() &&                   \
+        D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization)      \
+      /* Returning from here skips traversing the                              \
+         declaration context of the *TemplateSpecializationDecl                \
+         (embedded in the DEF_TRAVERSE_DECL() macro)                           \
+         which contains the instantiated members of the template. */           \
+      return true;                                                             \
   })
 
 DEF_TRAVERSE_TMPL_SPEC_DECL(Class)
@@ -1675,45 +1664,43 @@
   return true;
 }
 
-#define DEF_TRAVERSE_TMPL_PART_SPEC_DECL(TMPLDECLKIND, DECLKIND) \
-DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplatePartialSpecializationDecl, {         \
-    /* The partial specialization. */                                        \
-    if (TemplateParameterList *TPL = D->getTemplateParameters()) {           \
-      for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end(); \
-           I != E; ++I) {                                                    \
-        TRY_TO(TraverseDecl(*I));                                            \
-      }                                                                      \
-    }                                                                        \
-    /* The args that remains unspecialized. */                               \
-    TRY_TO(TraverseTemplateArgumentLocsHelper(                               \
-                      D->getTemplateArgsAsWritten()->getTemplateArgs(),      \
-                      D->getTemplateArgsAsWritten()->NumTemplateArgs));      \
-                                                                             \
-    /* Don't need the *TemplatePartialSpecializationHelper, even
-       though that's our parent class -- we already visit all the
-       template args here. */                                                \
-    TRY_TO(Traverse##DECLKIND##Helper(D));                                   \
-                                                                             \
-    /* Instantiations will have been visited with the primary template. */   \
+#define DEF_TRAVERSE_TMPL_PART_SPEC_DECL(TMPLDECLKIND, DECLKIND)               \
+  DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplatePartialSpecializationDecl, {         \
+    /* The partial specialization. */                                          \
+    if (TemplateParameterList *TPL = D->getTemplateParameters()) {             \
+      for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end();   \
+           I != E; ++I) {                                                      \
+        TRY_TO(TraverseDecl(*I));                                              \
+      }                                                                        \
+    }                                                                          \
+    /* The args that remains unspecialized. */                                 \
+    TRY_TO(TraverseTemplateArgumentLocsHelper(                                 \
+        D->getTemplateArgsAsWritten()->getTemplateArgs(),                      \
+        D->getTemplateArgsAsWritten()->NumTemplateArgs));                      \
+                                                                               \
+    /* Don't need the *TemplatePartialSpecializationHelper, even               \
+       though that's our parent class -- we already visit all the              \
+       template args here. */                                                  \
+    TRY_TO(Traverse##DECLKIND##Helper(D));                                     \
+                                                                               \
+    /* Instantiations will have been visited with the primary template. */     \
   })
 
 DEF_TRAVERSE_TMPL_PART_SPEC_DECL(Class, CXXRecord)
 DEF_TRAVERSE_TMPL_PART_SPEC_DECL(Var, Var)
 
-DEF_TRAVERSE_DECL(EnumConstantDecl, {
-    TRY_TO(TraverseStmt(D->getInitExpr()));
-  })
+DEF_TRAVERSE_DECL(EnumConstantDecl, { TRY_TO(TraverseStmt(D->getInitExpr())); })
 
 DEF_TRAVERSE_DECL(UnresolvedUsingValueDecl, {
-    // Like UnresolvedUsingTypenameDecl, but without the 'typename':
-    //    template <class T> Class A : public Base<T> { using Base<T>::foo; };
-    TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
-    TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
-  })
+  // Like UnresolvedUsingTypenameDecl, but without the 'typename':
+  //    template <class T> Class A : public Base<T> { using Base<T>::foo; };
+  TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+  TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
+})
 
 DEF_TRAVERSE_DECL(IndirectFieldDecl, {})
 
-template<typename Derived>
+template <typename Derived>
 bool RecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) {
   TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
   if (D->getTypeSourceInfo())
@@ -1723,33 +1710,31 @@
   return true;
 }
 
-DEF_TRAVERSE_DECL(MSPropertyDecl, {
-    TRY_TO(TraverseDeclaratorHelper(D));
-  })
+DEF_TRAVERSE_DECL(MSPropertyDecl, { TRY_TO(TraverseDeclaratorHelper(D)); })
 
 DEF_TRAVERSE_DECL(FieldDecl, {
-    TRY_TO(TraverseDeclaratorHelper(D));
-    if (D->isBitField())
-      TRY_TO(TraverseStmt(D->getBitWidth()));
-    else if (D->hasInClassInitializer())
-      TRY_TO(TraverseStmt(D->getInClassInitializer()));
-  })
+  TRY_TO(TraverseDeclaratorHelper(D));
+  if (D->isBitField())
+    TRY_TO(TraverseStmt(D->getBitWidth()));
+  else if (D->hasInClassInitializer())
+    TRY_TO(TraverseStmt(D->getInClassInitializer()));
+})
 
 DEF_TRAVERSE_DECL(ObjCAtDefsFieldDecl, {
-    TRY_TO(TraverseDeclaratorHelper(D));
-    if (D->isBitField())
-      TRY_TO(TraverseStmt(D->getBitWidth()));
-    // FIXME: implement the rest.
-  })
+  TRY_TO(TraverseDeclaratorHelper(D));
+  if (D->isBitField())
+    TRY_TO(TraverseStmt(D->getBitWidth()));
+  // FIXME: implement the rest.
+})
 
 DEF_TRAVERSE_DECL(ObjCIvarDecl, {
-    TRY_TO(TraverseDeclaratorHelper(D));
-    if (D->isBitField())
-      TRY_TO(TraverseStmt(D->getBitWidth()));
-    // FIXME: implement the rest.
-  })
+  TRY_TO(TraverseDeclaratorHelper(D));
+  if (D->isBitField())
+    TRY_TO(TraverseStmt(D->getBitWidth()));
+  // FIXME: implement the rest.
+})
 
-template<typename Derived>
+template <typename Derived>
 bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
   TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
   TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
@@ -1760,13 +1745,13 @@
   // the function args, but both are handled by the FunctionTypeLoc
   // above, so we have to choose one side.  I've decided to do before.
   if (const FunctionTemplateSpecializationInfo *FTSI =
-      D->getTemplateSpecializationInfo()) {
+          D->getTemplateSpecializationInfo()) {
     if (FTSI->getTemplateSpecializationKind() != TSK_Undeclared &&
         FTSI->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) {
       // A specialization might not have explicit template arguments if it has
       // a templated return type and concrete arguments.
       if (const ASTTemplateArgumentListInfo *TALI =
-          FTSI->TemplateArgumentsAsWritten) {
+              FTSI->TemplateArgumentsAsWritten) {
         TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getTemplateArgs(),
                                                   TALI->NumTemplateArgs));
       }
@@ -1785,58 +1770,57 @@
     // declarations do not have valid TypeSourceInfo, so to visit them
     // we need to traverse the declarations explicitly.
     for (FunctionDecl::param_const_iterator I = D->param_begin(),
-                                            E = D->param_end(); I != E; ++I)
+                                            E = D->param_end();
+         I != E; ++I)
       TRY_TO(TraverseDecl(*I));
   }
 
   if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
     // Constructor initializers.
-    for (CXXConstructorDecl::init_iterator I = Ctor->init_begin(),
-                                           E = Ctor->init_end();
-         I != E; ++I) {
-      TRY_TO(TraverseConstructorInitializer(*I));
+    for (auto *I : Ctor->inits()) {
+      TRY_TO(TraverseConstructorInitializer(I));
     }
   }
 
   if (D->isThisDeclarationADefinition()) {
-    TRY_TO(TraverseStmt(D->getBody()));  // Function body.
+    TRY_TO(TraverseStmt(D->getBody())); // Function body.
   }
   return true;
 }
 
 DEF_TRAVERSE_DECL(FunctionDecl, {
-    // We skip decls_begin/decls_end, which are already covered by
-    // TraverseFunctionHelper().
-    return TraverseFunctionHelper(D);
-  })
+  // We skip decls_begin/decls_end, which are already covered by
+  // TraverseFunctionHelper().
+  return TraverseFunctionHelper(D);
+})
 
 DEF_TRAVERSE_DECL(CXXMethodDecl, {
-    // We skip decls_begin/decls_end, which are already covered by
-    // TraverseFunctionHelper().
-    return TraverseFunctionHelper(D);
-  })
+  // We skip decls_begin/decls_end, which are already covered by
+  // TraverseFunctionHelper().
+  return TraverseFunctionHelper(D);
+})
 
 DEF_TRAVERSE_DECL(CXXConstructorDecl, {
-    // We skip decls_begin/decls_end, which are already covered by
-    // TraverseFunctionHelper().
-    return TraverseFunctionHelper(D);
-  })
+  // We skip decls_begin/decls_end, which are already covered by
+  // TraverseFunctionHelper().
+  return TraverseFunctionHelper(D);
+})
 
 // CXXConversionDecl is the declaration of a type conversion operator.
 // It's not a cast expression.
 DEF_TRAVERSE_DECL(CXXConversionDecl, {
-    // We skip decls_begin/decls_end, which are already covered by
-    // TraverseFunctionHelper().
-    return TraverseFunctionHelper(D);
-  })
+  // We skip decls_begin/decls_end, which are already covered by
+  // TraverseFunctionHelper().
+  return TraverseFunctionHelper(D);
+})
 
 DEF_TRAVERSE_DECL(CXXDestructorDecl, {
-    // We skip decls_begin/decls_end, which are already covered by
-    // TraverseFunctionHelper().
-    return TraverseFunctionHelper(D);
-  })
+  // We skip decls_begin/decls_end, which are already covered by
+  // TraverseFunctionHelper().
+  return TraverseFunctionHelper(D);
+})
 
-template<typename Derived>
+template <typename Derived>
 bool RecursiveASTVisitor<Derived>::TraverseVarHelper(VarDecl *D) {
   TRY_TO(TraverseDeclaratorHelper(D));
   // Default params are taken care of when we traverse the ParmVarDecl.
@@ -1846,34 +1830,28 @@
   return true;
 }
 
-DEF_TRAVERSE_DECL(VarDecl, {
-    TRY_TO(TraverseVarHelper(D));
-  })
+DEF_TRAVERSE_DECL(VarDecl, { TRY_TO(TraverseVarHelper(D)); })
 
-DEF_TRAVERSE_DECL(ImplicitParamDecl, {
-    TRY_TO(TraverseVarHelper(D));
-  })
+DEF_TRAVERSE_DECL(ImplicitParamDecl, { TRY_TO(TraverseVarHelper(D)); })
 
 DEF_TRAVERSE_DECL(NonTypeTemplateParmDecl, {
-    // A non-type template parameter, e.g. "S" in template<int S> class Foo ...
-    TRY_TO(TraverseDeclaratorHelper(D));
-    if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
-      TRY_TO(TraverseStmt(D->getDefaultArgument()));
-  })
+  // A non-type template parameter, e.g. "S" in template<int S> class Foo ...
+  TRY_TO(TraverseDeclaratorHelper(D));
+  if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
+    TRY_TO(TraverseStmt(D->getDefaultArgument()));
+})
 
 DEF_TRAVERSE_DECL(ParmVarDecl, {
-    TRY_TO(TraverseVarHelper(D));
+  TRY_TO(TraverseVarHelper(D));
 
-    if (D->hasDefaultArg() &&
-        D->hasUninstantiatedDefaultArg() &&
-        !D->hasUnparsedDefaultArg())
-      TRY_TO(TraverseStmt(D->getUninstantiatedDefaultArg()));
+  if (D->hasDefaultArg() && D->hasUninstantiatedDefaultArg() &&
+      !D->hasUnparsedDefaultArg())
+    TRY_TO(TraverseStmt(D->getUninstantiatedDefaultArg()));
 
-    if (D->hasDefaultArg() &&
-        !D->hasUninstantiatedDefaultArg() &&
-        !D->hasUnparsedDefaultArg())
-      TRY_TO(TraverseStmt(D->getDefaultArg()));
-  })
+  if (D->hasDefaultArg() && !D->hasUninstantiatedDefaultArg() &&
+      !D->hasUnparsedDefaultArg())
+    TRY_TO(TraverseStmt(D->getDefaultArg()));
+})
 
 #undef DEF_TRAVERSE_DECL
 
@@ -1887,78 +1865,77 @@
 //   http://clang.llvm.org/doxygen/Stmt_8cpp_source.html
 
 // This macro makes available a variable S, the passed-in stmt.
-#define DEF_TRAVERSE_STMT(STMT, CODE)                                   \
-template<typename Derived>                                              \
-bool RecursiveASTVisitor<Derived>::Traverse##STMT (STMT *S) {           \
-  TRY_TO(WalkUpFrom##STMT(S));                                          \
-  { CODE; }                                                             \
-  for (Stmt::child_range range = S->children(); range; ++range) {       \
-    TRY_TO(TraverseStmt(*range));                                       \
-  }                                                                     \
-  return true;                                                          \
-}
+#define DEF_TRAVERSE_STMT(STMT, CODE)                                          \
+  template <typename Derived>                                                  \
+  bool RecursiveASTVisitor<Derived>::Traverse##STMT(STMT *S) {                 \
+    TRY_TO(WalkUpFrom##STMT(S));                                               \
+    { CODE; }                                                                  \
+    for (Stmt::child_range range = S->children(); range; ++range) {            \
+      TRY_TO(TraverseStmt(*range));                                            \
+    }                                                                          \
+    return true;                                                               \
+  }
 
 DEF_TRAVERSE_STMT(GCCAsmStmt, {
-    TRY_TO(TraverseStmt(S->getAsmString()));
-    for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) {
-      TRY_TO(TraverseStmt(S->getInputConstraintLiteral(I)));
-    }
-    for (unsigned I = 0, E = S->getNumOutputs(); I < E; ++I) {
-      TRY_TO(TraverseStmt(S->getOutputConstraintLiteral(I)));
-    }
-    for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) {
-      TRY_TO(TraverseStmt(S->getClobberStringLiteral(I)));
-    }
-    // children() iterates over inputExpr and outputExpr.
-  })
+  TRY_TO(TraverseStmt(S->getAsmString()));
+  for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) {
+    TRY_TO(TraverseStmt(S->getInputConstraintLiteral(I)));
+  }
+  for (unsigned I = 0, E = S->getNumOutputs(); I < E; ++I) {
+    TRY_TO(TraverseStmt(S->getOutputConstraintLiteral(I)));
+  }
+  for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) {
+    TRY_TO(TraverseStmt(S->getClobberStringLiteral(I)));
+  }
+  // children() iterates over inputExpr and outputExpr.
+})
 
-DEF_TRAVERSE_STMT(MSAsmStmt, { 
-    // FIXME: MS Asm doesn't currently parse Constraints, Clobbers, etc.  Once
-    // added this needs to be implemented.
-  })
+DEF_TRAVERSE_STMT(
+    MSAsmStmt,
+    {// FIXME: MS Asm doesn't currently parse Constraints, Clobbers, etc.  Once
+     // added this needs to be implemented.
+    })
 
 DEF_TRAVERSE_STMT(CXXCatchStmt, {
-    TRY_TO(TraverseDecl(S->getExceptionDecl()));
-    // children() iterates over the handler block.
-  })
+  TRY_TO(TraverseDecl(S->getExceptionDecl()));
+  // children() iterates over the handler block.
+})
 
 DEF_TRAVERSE_STMT(DeclStmt, {
-    for (DeclStmt::decl_iterator I = S->decl_begin(), E = S->decl_end();
-         I != E; ++I) {
-      TRY_TO(TraverseDecl(*I));
-    }
-    // Suppress the default iteration over children() by
-    // returning.  Here's why: A DeclStmt looks like 'type var [=
-    // initializer]'.  The decls above already traverse over the
-    // initializers, so we don't have to do it again (which
-    // children() would do).
-    return true;
-  })
-
+  for (auto *I : S->decls()) {
+    TRY_TO(TraverseDecl(I));
+  }
+  // Suppress the default iteration over children() by
+  // returning.  Here's why: A DeclStmt looks like 'type var [=
+  // initializer]'.  The decls above already traverse over the
+  // initializers, so we don't have to do it again (which
+  // children() would do).
+  return true;
+})
 
 // These non-expr stmts (most of them), do not need any action except
 // iterating over the children.
-DEF_TRAVERSE_STMT(BreakStmt, { })
-DEF_TRAVERSE_STMT(CXXTryStmt, { })
-DEF_TRAVERSE_STMT(CaseStmt, { })
-DEF_TRAVERSE_STMT(CompoundStmt, { })
-DEF_TRAVERSE_STMT(ContinueStmt, { })
-DEF_TRAVERSE_STMT(DefaultStmt, { })
-DEF_TRAVERSE_STMT(DoStmt, { })
-DEF_TRAVERSE_STMT(ForStmt, { })
-DEF_TRAVERSE_STMT(GotoStmt, { })
-DEF_TRAVERSE_STMT(IfStmt, { })
-DEF_TRAVERSE_STMT(IndirectGotoStmt, { })
-DEF_TRAVERSE_STMT(LabelStmt, { })
-DEF_TRAVERSE_STMT(AttributedStmt, { })
-DEF_TRAVERSE_STMT(NullStmt, { })
-DEF_TRAVERSE_STMT(ObjCAtCatchStmt, { })
-DEF_TRAVERSE_STMT(ObjCAtFinallyStmt, { })
-DEF_TRAVERSE_STMT(ObjCAtSynchronizedStmt, { })
-DEF_TRAVERSE_STMT(ObjCAtThrowStmt, { })
-DEF_TRAVERSE_STMT(ObjCAtTryStmt, { })
-DEF_TRAVERSE_STMT(ObjCForCollectionStmt, { })
-DEF_TRAVERSE_STMT(ObjCAutoreleasePoolStmt, { })
+DEF_TRAVERSE_STMT(BreakStmt, {})
+DEF_TRAVERSE_STMT(CXXTryStmt, {})
+DEF_TRAVERSE_STMT(CaseStmt, {})
+DEF_TRAVERSE_STMT(CompoundStmt, {})
+DEF_TRAVERSE_STMT(ContinueStmt, {})
+DEF_TRAVERSE_STMT(DefaultStmt, {})
+DEF_TRAVERSE_STMT(DoStmt, {})
+DEF_TRAVERSE_STMT(ForStmt, {})
+DEF_TRAVERSE_STMT(GotoStmt, {})
+DEF_TRAVERSE_STMT(IfStmt, {})
+DEF_TRAVERSE_STMT(IndirectGotoStmt, {})
+DEF_TRAVERSE_STMT(LabelStmt, {})
+DEF_TRAVERSE_STMT(AttributedStmt, {})
+DEF_TRAVERSE_STMT(NullStmt, {})
+DEF_TRAVERSE_STMT(ObjCAtCatchStmt, {})
+DEF_TRAVERSE_STMT(ObjCAtFinallyStmt, {})
+DEF_TRAVERSE_STMT(ObjCAtSynchronizedStmt, {})
+DEF_TRAVERSE_STMT(ObjCAtThrowStmt, {})
+DEF_TRAVERSE_STMT(ObjCAtTryStmt, {})
+DEF_TRAVERSE_STMT(ObjCForCollectionStmt, {})
+DEF_TRAVERSE_STMT(ObjCAutoreleasePoolStmt, {})
 DEF_TRAVERSE_STMT(CXXForRangeStmt, {
   if (!getDerived().shouldVisitImplicitCode()) {
     TRY_TO(TraverseStmt(S->getLoopVarStmt()));
@@ -1969,82 +1946,82 @@
   }
 })
 DEF_TRAVERSE_STMT(MSDependentExistsStmt, {
-    TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
-    TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
+  TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+  TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
 })
-DEF_TRAVERSE_STMT(ReturnStmt, { })
-DEF_TRAVERSE_STMT(SwitchStmt, { })
-DEF_TRAVERSE_STMT(WhileStmt, { })
-
+DEF_TRAVERSE_STMT(ReturnStmt, {})
+DEF_TRAVERSE_STMT(SwitchStmt, {})
+DEF_TRAVERSE_STMT(WhileStmt, {})
 
 DEF_TRAVERSE_STMT(CXXDependentScopeMemberExpr, {
-    TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
-    TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
-    if (S->hasExplicitTemplateArgs()) {
-      TRY_TO(TraverseTemplateArgumentLocsHelper(
-          S->getTemplateArgs(), S->getNumTemplateArgs()));
-    }
-  })
+  TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+  TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
+  if (S->hasExplicitTemplateArgs()) {
+    TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
+                                              S->getNumTemplateArgs()));
+  }
+})
 
 DEF_TRAVERSE_STMT(DeclRefExpr, {
-    TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
-    TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
-    TRY_TO(TraverseTemplateArgumentLocsHelper(
-        S->getTemplateArgs(), S->getNumTemplateArgs()));
-  })
+  TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+  TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
+  TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
+                                            S->getNumTemplateArgs()));
+})
 
 DEF_TRAVERSE_STMT(DependentScopeDeclRefExpr, {
-    TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
-    TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
-    if (S->hasExplicitTemplateArgs()) {
-      TRY_TO(TraverseTemplateArgumentLocsHelper(
-          S->getExplicitTemplateArgs().getTemplateArgs(),
-          S->getNumTemplateArgs()));
-    }
-  })
+  TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+  TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
+  if (S->hasExplicitTemplateArgs()) {
+    TRY_TO(TraverseTemplateArgumentLocsHelper(
+        S->getExplicitTemplateArgs().getTemplateArgs(),
+        S->getNumTemplateArgs()));
+  }
+})
 
 DEF_TRAVERSE_STMT(MemberExpr, {
-    TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
-    TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
-    TRY_TO(TraverseTemplateArgumentLocsHelper(
-        S->getTemplateArgs(), S->getNumTemplateArgs()));
-  })
+  TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+  TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
+  TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
+                                            S->getNumTemplateArgs()));
+})
 
-DEF_TRAVERSE_STMT(ImplicitCastExpr, {
-    // We don't traverse the cast type, as it's not written in the
-    // source code.
-  })
+DEF_TRAVERSE_STMT(
+    ImplicitCastExpr,
+    {// We don't traverse the cast type, as it's not written in the
+     // source code.
+    })
 
 DEF_TRAVERSE_STMT(CStyleCastExpr, {
-    TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
-  })
+  TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
 
 DEF_TRAVERSE_STMT(CXXFunctionalCastExpr, {
-    TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
-  })
+  TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
 
 DEF_TRAVERSE_STMT(CXXConstCastExpr, {
-    TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
-  })
+  TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
 
 DEF_TRAVERSE_STMT(CXXDynamicCastExpr, {
-    TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
-  })
+  TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
 
 DEF_TRAVERSE_STMT(CXXReinterpretCastExpr, {
-    TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
-  })
+  TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
 
 DEF_TRAVERSE_STMT(CXXStaticCastExpr, {
-    TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
-  })
+  TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
 
 // InitListExpr is a tricky one, because we want to do all our work on
 // the syntactic form of the listexpr, but this method takes the
 // semantic form by default.  We can't use the macro helper because it
 // calls WalkUp*() on the semantic form, before our code can convert
 // to the syntactic form.
-template<typename Derived>
+template <typename Derived>
 bool RecursiveASTVisitor<Derived>::TraverseInitListExpr(InitListExpr *S) {
   if (InitListExpr *Syn = S->getSyntacticForm())
     S = Syn;
@@ -2059,9 +2036,9 @@
 // GenericSelectionExpr is a special case because the types and expressions
 // are interleaved.  We also need to watch out for null types (default
 // generic associations).
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::
-TraverseGenericSelectionExpr(GenericSelectionExpr *S) {
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseGenericSelectionExpr(
+    GenericSelectionExpr *S) {
   TRY_TO(WalkUpFromGenericSelectionExpr(S));
   TRY_TO(TraverseStmt(S->getControllingExpr()));
   for (unsigned i = 0; i != S->getNumAssocs(); ++i) {
@@ -2074,13 +2051,14 @@
 
 // PseudoObjectExpr is a special case because of the wierdness with
 // syntactic expressions and opaque values.
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::
-TraversePseudoObjectExpr(PseudoObjectExpr *S) {
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::TraversePseudoObjectExpr(PseudoObjectExpr *S) {
   TRY_TO(WalkUpFromPseudoObjectExpr(S));
   TRY_TO(TraverseStmt(S->getSyntacticForm()));
-  for (PseudoObjectExpr::semantics_iterator
-         i = S->semantics_begin(), e = S->semantics_end(); i != e; ++i) {
+  for (PseudoObjectExpr::semantics_iterator i = S->semantics_begin(),
+                                            e = S->semantics_end();
+       i != e; ++i) {
     Expr *sub = *i;
     if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(sub))
       sub = OVE->getSourceExpr();
@@ -2090,57 +2068,48 @@
 }
 
 DEF_TRAVERSE_STMT(CXXScalarValueInitExpr, {
-    // This is called for code like 'return T()' where T is a built-in
-    // (i.e. non-class) type.
-    TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
-  })
+  // This is called for code like 'return T()' where T is a built-in
+  // (i.e. non-class) type.
+  TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+})
 
 DEF_TRAVERSE_STMT(CXXNewExpr, {
   // The child-iterator will pick up the other arguments.
   TRY_TO(TraverseTypeLoc(S->getAllocatedTypeSourceInfo()->getTypeLoc()));
-  })
+})
 
 DEF_TRAVERSE_STMT(OffsetOfExpr, {
-    // The child-iterator will pick up the expression representing
-    // the field.
-    // FIMXE: for code like offsetof(Foo, a.b.c), should we get
-    // making a MemberExpr callbacks for Foo.a, Foo.a.b, and Foo.a.b.c?
-    TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
-  })
+  // The child-iterator will pick up the expression representing
+  // the field.
+  // FIMXE: for code like offsetof(Foo, a.b.c), should we get
+  // making a MemberExpr callbacks for Foo.a, Foo.a.b, and Foo.a.b.c?
+  TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+})
 
 DEF_TRAVERSE_STMT(UnaryExprOrTypeTraitExpr, {
-    // The child-iterator will pick up the arg if it's an expression,
-    // but not if it's a type.
-    if (S->isArgumentType())
-      TRY_TO(TraverseTypeLoc(S->getArgumentTypeInfo()->getTypeLoc()));
-  })
+  // The child-iterator will pick up the arg if it's an expression,
+  // but not if it's a type.
+  if (S->isArgumentType())
+    TRY_TO(TraverseTypeLoc(S->getArgumentTypeInfo()->getTypeLoc()));
+})
 
 DEF_TRAVERSE_STMT(CXXTypeidExpr, {
-    // The child-iterator will pick up the arg if it's an expression,
-    // but not if it's a type.
-    if (S->isTypeOperand())
-      TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
-  })
+  // The child-iterator will pick up the arg if it's an expression,
+  // but not if it's a type.
+  if (S->isTypeOperand())
+    TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
+})
 
 DEF_TRAVERSE_STMT(MSPropertyRefExpr, {
   TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
 })
 
 DEF_TRAVERSE_STMT(CXXUuidofExpr, {
-    // The child-iterator will pick up the arg if it's an expression,
-    // but not if it's a type.
-    if (S->isTypeOperand())
-      TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
-  })
-
-DEF_TRAVERSE_STMT(UnaryTypeTraitExpr, {
-    TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
-  })
-
-DEF_TRAVERSE_STMT(BinaryTypeTraitExpr, {
-    TRY_TO(TraverseTypeLoc(S->getLhsTypeSourceInfo()->getTypeLoc()));
-    TRY_TO(TraverseTypeLoc(S->getRhsTypeSourceInfo()->getTypeLoc()));
-  })
+  // The child-iterator will pick up the arg if it's an expression,
+  // but not if it's a type.
+  if (S->isTypeOperand())
+    TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
+})
 
 DEF_TRAVERSE_STMT(TypeTraitExpr, {
   for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
@@ -2148,30 +2117,29 @@
 })
 
 DEF_TRAVERSE_STMT(ArrayTypeTraitExpr, {
-    TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
-  })
+  TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
+})
 
-DEF_TRAVERSE_STMT(ExpressionTraitExpr, {
-    TRY_TO(TraverseStmt(S->getQueriedExpression()));
-  })
+DEF_TRAVERSE_STMT(ExpressionTraitExpr,
+                  { TRY_TO(TraverseStmt(S->getQueriedExpression())); })
 
 DEF_TRAVERSE_STMT(VAArgExpr, {
-    // The child-iterator will pick up the expression argument.
-    TRY_TO(TraverseTypeLoc(S->getWrittenTypeInfo()->getTypeLoc()));
-  })
+  // The child-iterator will pick up the expression argument.
+  TRY_TO(TraverseTypeLoc(S->getWrittenTypeInfo()->getTypeLoc()));
+})
 
 DEF_TRAVERSE_STMT(CXXTemporaryObjectExpr, {
-    // This is called for code like 'return T()' where T is a class type.
-    TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
-  })
+  // This is called for code like 'return T()' where T is a class type.
+  TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+})
 
-// Walk only the visible parts of lambda expressions.  
-template<typename Derived>
+// Walk only the visible parts of lambda expressions.
+template <typename Derived>
 bool RecursiveASTVisitor<Derived>::TraverseLambdaExpr(LambdaExpr *S) {
   TRY_TO(WalkUpFromLambdaExpr(S));
 
   for (LambdaExpr::capture_iterator C = S->explicit_capture_begin(),
-                                 CEnd = S->explicit_capture_end();
+                                    CEnd = S->explicit_capture_end();
        C != CEnd; ++C) {
     TRY_TO(TraverseLambdaCapture(S, C));
   }
@@ -2184,12 +2152,12 @@
     } else if (FunctionProtoTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) {
       if (S->hasExplicitParameters()) {
         // Visit parameters.
-        for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I) {
-          TRY_TO(TraverseDecl(Proto.getArg(I)));
+        for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I) {
+          TRY_TO(TraverseDecl(Proto.getParam(I)));
         }
       } else {
-        TRY_TO(TraverseTypeLoc(Proto.getResultLoc()));
-      }        
+        TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
+      }
     }
   }
 
@@ -2198,36 +2166,36 @@
 }
 
 DEF_TRAVERSE_STMT(CXXUnresolvedConstructExpr, {
-    // This is called for code like 'T()', where T is a template argument.
-    TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
-  })
+  // This is called for code like 'T()', where T is a template argument.
+  TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+})
 
 // These expressions all might take explicit template arguments.
 // We traverse those if so.  FIXME: implement these.
-DEF_TRAVERSE_STMT(CXXConstructExpr, { })
-DEF_TRAVERSE_STMT(CallExpr, { })
-DEF_TRAVERSE_STMT(CXXMemberCallExpr, { })
+DEF_TRAVERSE_STMT(CXXConstructExpr, {})
+DEF_TRAVERSE_STMT(CallExpr, {})
+DEF_TRAVERSE_STMT(CXXMemberCallExpr, {})
 
 // These exprs (most of them), do not need any action except iterating
 // over the children.
-DEF_TRAVERSE_STMT(AddrLabelExpr, { })
-DEF_TRAVERSE_STMT(ArraySubscriptExpr, { })
+DEF_TRAVERSE_STMT(AddrLabelExpr, {})
+DEF_TRAVERSE_STMT(ArraySubscriptExpr, {})
 DEF_TRAVERSE_STMT(BlockExpr, {
   TRY_TO(TraverseDecl(S->getBlockDecl()));
   return true; // no child statements to loop through.
 })
-DEF_TRAVERSE_STMT(ChooseExpr, { })
+DEF_TRAVERSE_STMT(ChooseExpr, {})
 DEF_TRAVERSE_STMT(CompoundLiteralExpr, {
   TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
 })
-DEF_TRAVERSE_STMT(CXXBindTemporaryExpr, { })
-DEF_TRAVERSE_STMT(CXXBoolLiteralExpr, { })
-DEF_TRAVERSE_STMT(CXXDefaultArgExpr, { })
-DEF_TRAVERSE_STMT(CXXDefaultInitExpr, { })
-DEF_TRAVERSE_STMT(CXXDeleteExpr, { })
-DEF_TRAVERSE_STMT(ExprWithCleanups, { })
-DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, { })
-DEF_TRAVERSE_STMT(CXXStdInitializerListExpr, { })
+DEF_TRAVERSE_STMT(CXXBindTemporaryExpr, {})
+DEF_TRAVERSE_STMT(CXXBoolLiteralExpr, {})
+DEF_TRAVERSE_STMT(CXXDefaultArgExpr, {})
+DEF_TRAVERSE_STMT(CXXDefaultInitExpr, {})
+DEF_TRAVERSE_STMT(CXXDeleteExpr, {})
+DEF_TRAVERSE_STMT(ExprWithCleanups, {})
+DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, {})
+DEF_TRAVERSE_STMT(CXXStdInitializerListExpr, {})
 DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, {
   TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
   if (TypeSourceInfo *ScopeInfo = S->getScopeTypeInfo())
@@ -2235,38 +2203,38 @@
   if (TypeSourceInfo *DestroyedTypeInfo = S->getDestroyedTypeInfo())
     TRY_TO(TraverseTypeLoc(DestroyedTypeInfo->getTypeLoc()));
 })
-DEF_TRAVERSE_STMT(CXXThisExpr, { })
-DEF_TRAVERSE_STMT(CXXThrowExpr, { })
-DEF_TRAVERSE_STMT(UserDefinedLiteral, { })
-DEF_TRAVERSE_STMT(DesignatedInitExpr, { })
-DEF_TRAVERSE_STMT(ExtVectorElementExpr, { })
-DEF_TRAVERSE_STMT(GNUNullExpr, { })
-DEF_TRAVERSE_STMT(ImplicitValueInitExpr, { })
-DEF_TRAVERSE_STMT(ObjCBoolLiteralExpr, { })
+DEF_TRAVERSE_STMT(CXXThisExpr, {})
+DEF_TRAVERSE_STMT(CXXThrowExpr, {})
+DEF_TRAVERSE_STMT(UserDefinedLiteral, {})
+DEF_TRAVERSE_STMT(DesignatedInitExpr, {})
+DEF_TRAVERSE_STMT(ExtVectorElementExpr, {})
+DEF_TRAVERSE_STMT(GNUNullExpr, {})
+DEF_TRAVERSE_STMT(ImplicitValueInitExpr, {})
+DEF_TRAVERSE_STMT(ObjCBoolLiteralExpr, {})
 DEF_TRAVERSE_STMT(ObjCEncodeExpr, {
   if (TypeSourceInfo *TInfo = S->getEncodedTypeSourceInfo())
     TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
 })
-DEF_TRAVERSE_STMT(ObjCIsaExpr, { })
-DEF_TRAVERSE_STMT(ObjCIvarRefExpr, { })
+DEF_TRAVERSE_STMT(ObjCIsaExpr, {})
+DEF_TRAVERSE_STMT(ObjCIvarRefExpr, {})
 DEF_TRAVERSE_STMT(ObjCMessageExpr, {
   if (TypeSourceInfo *TInfo = S->getClassReceiverTypeInfo())
     TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
 })
-DEF_TRAVERSE_STMT(ObjCPropertyRefExpr, { })
-DEF_TRAVERSE_STMT(ObjCSubscriptRefExpr, { })
-DEF_TRAVERSE_STMT(ObjCProtocolExpr, { })
-DEF_TRAVERSE_STMT(ObjCSelectorExpr, { })
-DEF_TRAVERSE_STMT(ObjCIndirectCopyRestoreExpr, { })
+DEF_TRAVERSE_STMT(ObjCPropertyRefExpr, {})
+DEF_TRAVERSE_STMT(ObjCSubscriptRefExpr, {})
+DEF_TRAVERSE_STMT(ObjCProtocolExpr, {})
+DEF_TRAVERSE_STMT(ObjCSelectorExpr, {})
+DEF_TRAVERSE_STMT(ObjCIndirectCopyRestoreExpr, {})
 DEF_TRAVERSE_STMT(ObjCBridgedCastExpr, {
   TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
 })
-DEF_TRAVERSE_STMT(ParenExpr, { })
-DEF_TRAVERSE_STMT(ParenListExpr, { })
-DEF_TRAVERSE_STMT(PredefinedExpr, { })
-DEF_TRAVERSE_STMT(ShuffleVectorExpr, { })
-DEF_TRAVERSE_STMT(ConvertVectorExpr, { })
-DEF_TRAVERSE_STMT(StmtExpr, { })
+DEF_TRAVERSE_STMT(ParenExpr, {})
+DEF_TRAVERSE_STMT(ParenListExpr, {})
+DEF_TRAVERSE_STMT(PredefinedExpr, {})
+DEF_TRAVERSE_STMT(ShuffleVectorExpr, {})
+DEF_TRAVERSE_STMT(ConvertVectorExpr, {})
+DEF_TRAVERSE_STMT(StmtExpr, {})
 DEF_TRAVERSE_STMT(UnresolvedLookupExpr, {
   TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
   if (S->hasExplicitTemplateArgs()) {
@@ -2285,97 +2253,263 @@
 
 DEF_TRAVERSE_STMT(SEHTryStmt, {})
 DEF_TRAVERSE_STMT(SEHExceptStmt, {})
-DEF_TRAVERSE_STMT(SEHFinallyStmt,{})
-DEF_TRAVERSE_STMT(CapturedStmt, {
-  TRY_TO(TraverseDecl(S->getCapturedDecl()));
-})
+DEF_TRAVERSE_STMT(SEHFinallyStmt, {})
+DEF_TRAVERSE_STMT(SEHLeaveStmt, {})
+DEF_TRAVERSE_STMT(CapturedStmt, { TRY_TO(TraverseDecl(S->getCapturedDecl())); })
 
-DEF_TRAVERSE_STMT(CXXOperatorCallExpr, { })
-DEF_TRAVERSE_STMT(OpaqueValueExpr, { })
-DEF_TRAVERSE_STMT(CUDAKernelCallExpr, { })
+DEF_TRAVERSE_STMT(CXXOperatorCallExpr, {})
+DEF_TRAVERSE_STMT(OpaqueValueExpr, {})
+DEF_TRAVERSE_STMT(CUDAKernelCallExpr, {})
 
 // These operators (all of them) do not need any action except
 // iterating over the children.
-DEF_TRAVERSE_STMT(BinaryConditionalOperator, { })
-DEF_TRAVERSE_STMT(ConditionalOperator, { })
-DEF_TRAVERSE_STMT(UnaryOperator, { })
-DEF_TRAVERSE_STMT(BinaryOperator, { })
-DEF_TRAVERSE_STMT(CompoundAssignOperator, { })
-DEF_TRAVERSE_STMT(CXXNoexceptExpr, { })
-DEF_TRAVERSE_STMT(PackExpansionExpr, { })
-DEF_TRAVERSE_STMT(SizeOfPackExpr, { })
-DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, { })
-DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, { })
-DEF_TRAVERSE_STMT(FunctionParmPackExpr, { })
-DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, { })
-DEF_TRAVERSE_STMT(AtomicExpr, { })
+DEF_TRAVERSE_STMT(BinaryConditionalOperator, {})
+DEF_TRAVERSE_STMT(ConditionalOperator, {})
+DEF_TRAVERSE_STMT(UnaryOperator, {})
+DEF_TRAVERSE_STMT(BinaryOperator, {})
+DEF_TRAVERSE_STMT(CompoundAssignOperator, {})
+DEF_TRAVERSE_STMT(CXXNoexceptExpr, {})
+DEF_TRAVERSE_STMT(PackExpansionExpr, {})
+DEF_TRAVERSE_STMT(SizeOfPackExpr, {})
+DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, {})
+DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, {})
+DEF_TRAVERSE_STMT(FunctionParmPackExpr, {})
+DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, {})
+DEF_TRAVERSE_STMT(AtomicExpr, {})
 
 // These literals (all of them) do not need any action.
-DEF_TRAVERSE_STMT(IntegerLiteral, { })
-DEF_TRAVERSE_STMT(CharacterLiteral, { })
-DEF_TRAVERSE_STMT(FloatingLiteral, { })
-DEF_TRAVERSE_STMT(ImaginaryLiteral, { })
-DEF_TRAVERSE_STMT(StringLiteral, { })
-DEF_TRAVERSE_STMT(ObjCStringLiteral, { })
-DEF_TRAVERSE_STMT(ObjCBoxedExpr, { })
-DEF_TRAVERSE_STMT(ObjCArrayLiteral, { })
-DEF_TRAVERSE_STMT(ObjCDictionaryLiteral, { })
-  
+DEF_TRAVERSE_STMT(IntegerLiteral, {})
+DEF_TRAVERSE_STMT(CharacterLiteral, {})
+DEF_TRAVERSE_STMT(FloatingLiteral, {})
+DEF_TRAVERSE_STMT(ImaginaryLiteral, {})
+DEF_TRAVERSE_STMT(StringLiteral, {})
+DEF_TRAVERSE_STMT(ObjCStringLiteral, {})
+DEF_TRAVERSE_STMT(ObjCBoxedExpr, {})
+DEF_TRAVERSE_STMT(ObjCArrayLiteral, {})
+DEF_TRAVERSE_STMT(ObjCDictionaryLiteral, {})
+
 // Traverse OpenCL: AsType, Convert.
-DEF_TRAVERSE_STMT(AsTypeExpr, { })
+DEF_TRAVERSE_STMT(AsTypeExpr, {})
 
 // OpenMP directives.
-DEF_TRAVERSE_STMT(OMPParallelDirective, {
-  ArrayRef<OMPClause *> Clauses = S->clauses();
-  for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
-       I != E; ++I)
-    if (!TraverseOMPClause(*I)) return false;
-})
-
-// OpenMP clauses.
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
-  if (!C) return true;
-  switch (C->getClauseKind()) {
-#define OPENMP_CLAUSE(Name, Class)                                      \
-  case OMPC_##Name:                                                     \
-    return getDerived().Visit##Class(static_cast<Class*>(C));
-#include "clang/Basic/OpenMPKinds.def"
-  default: break;
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseOMPExecutableDirective(
+    OMPExecutableDirective *S) {
+  for (auto *C : S->clauses()) {
+    TRY_TO(TraverseOMPClause(C));
   }
   return true;
 }
 
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPDefaultClause(OMPDefaultClause *C) {
+DEF_TRAVERSE_STMT(OMPParallelDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPSimdDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPForDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPSectionsDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPSectionDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPSingleDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPMasterDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPCriticalDirective, {
+  TRY_TO(TraverseDeclarationNameInfo(S->getDirectiveName()));
+  TRY_TO(TraverseOMPExecutableDirective(S));
+})
+
+DEF_TRAVERSE_STMT(OMPParallelForDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPParallelSectionsDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTaskDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTaskyieldDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPBarrierDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTaskwaitDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPFlushDirective,
+                  { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+// OpenMP clauses.
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
+  if (!C)
+    return true;
+  switch (C->getClauseKind()) {
+#define OPENMP_CLAUSE(Name, Class)                                             \
+  case OMPC_##Name:                                                            \
+    TRY_TO(Visit##Class(static_cast<Class *>(C)));                             \
+    break;
+#include "clang/Basic/OpenMPKinds.def"
+  case OMPC_threadprivate:
+  case OMPC_unknown:
+    break;
+  }
   return true;
 }
 
-template<typename Derived>
-template<typename T>
-void RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
-  for (typename T::varlist_iterator I = Node->varlist_begin(),
-                                    E = Node->varlist_end();
-         I != E; ++I)
-    TraverseStmt(*I);
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPIfClause(OMPIfClause *C) {
+  TRY_TO(TraverseStmt(C->getCondition()));
+  return true;
 }
 
-template<typename Derived>
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPFinalClause(OMPFinalClause *C) {
+  TRY_TO(TraverseStmt(C->getCondition()));
+  return true;
+}
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) {
+  TRY_TO(TraverseStmt(C->getNumThreads()));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPSafelenClause(OMPSafelenClause *C) {
+  TRY_TO(TraverseStmt(C->getSafelen()));
+  return true;
+}
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::VisitOMPCollapseClause(OMPCollapseClause *C) {
+  TRY_TO(TraverseStmt(C->getNumForLoops()));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPDefaultClause(OMPDefaultClause *) {
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPProcBindClause(OMPProcBindClause *) {
+  return true;
+}
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::VisitOMPScheduleClause(OMPScheduleClause *C) {
+  TRY_TO(TraverseStmt(C->getChunkSize()));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPOrderedClause(OMPOrderedClause *) {
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPNowaitClause(OMPNowaitClause *) {
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPUntiedClause(OMPUntiedClause *) {
+  return true;
+}
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::VisitOMPMergeableClause(OMPMergeableClause *) {
+  return true;
+}
+
+template <typename Derived>
+template <typename T>
+bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
+  for (auto *E : Node->varlists()) {
+    TRY_TO(TraverseStmt(E));
+  }
+  return true;
+}
+
+template <typename Derived>
 bool RecursiveASTVisitor<Derived>::VisitOMPPrivateClause(OMPPrivateClause *C) {
-  VisitOMPClauseList(C);
+  TRY_TO(VisitOMPClauseList(C));
   return true;
 }
 
-template<typename Derived>
+template <typename Derived>
 bool RecursiveASTVisitor<Derived>::VisitOMPFirstprivateClause(
-                                                    OMPFirstprivateClause *C) {
-  VisitOMPClauseList(C);
+    OMPFirstprivateClause *C) {
+  TRY_TO(VisitOMPClauseList(C));
   return true;
 }
 
-template<typename Derived>
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPLastprivateClause(
+    OMPLastprivateClause *C) {
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
 bool RecursiveASTVisitor<Derived>::VisitOMPSharedClause(OMPSharedClause *C) {
-  VisitOMPClauseList(C);
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPLinearClause(OMPLinearClause *C) {
+  TRY_TO(TraverseStmt(C->getStep()));
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPAlignedClause(OMPAlignedClause *C) {
+  TRY_TO(TraverseStmt(C->getAlignment()));
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPCopyinClause(OMPCopyinClause *C) {
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPCopyprivateClause(
+    OMPCopyprivateClause *C) {
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::VisitOMPReductionClause(OMPReductionClause *C) {
+  TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
+  TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
+  TRY_TO(VisitOMPClauseList(C));
+  return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPFlushClause(OMPFlushClause *C) {
+  TRY_TO(VisitOMPClauseList(C));
   return true;
 }
 
diff --git a/include/clang/AST/Redeclarable.h b/include/clang/AST/Redeclarable.h
index cfe5a90..7aa11d4 100644
--- a/include/clang/AST/Redeclarable.h
+++ b/include/clang/AST/Redeclarable.h
@@ -14,6 +14,7 @@
 #ifndef LLVM_CLANG_AST_REDECLARABLE_H
 #define LLVM_CLANG_AST_REDECLARABLE_H
 
+#include "clang/AST/ExternalASTSource.h"
 #include "llvm/ADT/PointerIntPair.h"
 #include "llvm/Support/Casting.h"
 #include <iterator>
@@ -23,26 +24,82 @@
 /// \brief Provides common interface for the Decls that can be redeclared.
 template<typename decl_type>
 class Redeclarable {
-
 protected:
   class DeclLink {
-    llvm::PointerIntPair<decl_type *, 1, bool> NextAndIsPrevious;
-  public:
-    DeclLink(decl_type *D, bool isLatest)
-      : NextAndIsPrevious(D, isLatest) { }
+    /// A pointer to a known latest declaration, either statically known or
+    /// generationally updated as decls are added by an external source.
+    typedef LazyGenerationalUpdatePtr<const Decl*, Decl*,
+                                      &ExternalASTSource::CompleteRedeclChain>
+                                          KnownLatest;
 
-    bool NextIsPrevious() const { return !NextAndIsPrevious.getInt(); }
-    bool NextIsLatest() const { return NextAndIsPrevious.getInt(); }
-    decl_type *getNext() const { return NextAndIsPrevious.getPointer(); }
-    void setNext(decl_type *D) { NextAndIsPrevious.setPointer(D); }
+    typedef const ASTContext *UninitializedLatest;
+    typedef Decl *Previous;
+
+    /// A pointer to either an uninitialized latest declaration (where either
+    /// we've not yet set the previous decl or there isn't one), or to a known
+    /// previous declaration.
+    typedef llvm::PointerUnion<Previous, UninitializedLatest> NotKnownLatest;
+
+    mutable llvm::PointerUnion<NotKnownLatest, KnownLatest> Next;
+
+  public:
+    enum PreviousTag { PreviousLink };
+    enum LatestTag { LatestLink };
+
+    DeclLink(LatestTag, const ASTContext &Ctx)
+        : Next(NotKnownLatest(&Ctx)) {}
+    DeclLink(PreviousTag, decl_type *D)
+        : Next(NotKnownLatest(Previous(D))) {}
+
+    bool NextIsPrevious() const {
+      return Next.is<NotKnownLatest>() &&
+             // FIXME: 'template' is required on the next line due to an
+             // apparent clang bug.
+             Next.get<NotKnownLatest>().template is<Previous>();
+    }
+
+    bool NextIsLatest() const { return !NextIsPrevious(); }
+
+    decl_type *getNext(const decl_type *D) const {
+      if (Next.is<NotKnownLatest>()) {
+        NotKnownLatest NKL = Next.get<NotKnownLatest>();
+        if (NKL.is<Previous>())
+          return static_cast<decl_type*>(NKL.get<Previous>());
+
+        // Allocate the generational 'most recent' cache now, if needed.
+        Next = KnownLatest(*NKL.get<UninitializedLatest>(),
+                           const_cast<decl_type *>(D));
+      }
+
+      return static_cast<decl_type*>(Next.get<KnownLatest>().get(D));
+    }
+
+    void setPrevious(decl_type *D) {
+      assert(NextIsPrevious() && "decl became non-canonical unexpectedly");
+      Next = Previous(D);
+    }
+
+    void setLatest(decl_type *D) {
+      assert(NextIsLatest() && "decl became canonical unexpectedly");
+      if (Next.is<NotKnownLatest>()) {
+        NotKnownLatest NKL = Next.get<NotKnownLatest>();
+        Next = KnownLatest(*NKL.get<UninitializedLatest>(), D);
+      } else {
+        auto Latest = Next.get<KnownLatest>();
+        Latest.set(D);
+        Next = Latest;
+      }
+    }
+
+    void markIncomplete() { Next.get<KnownLatest>().markIncomplete(); }
   };
 
   static DeclLink PreviousDeclLink(decl_type *D) {
-    return DeclLink(D, false);
+    return DeclLink(DeclLink::PreviousLink, D);
   }
 
-  static DeclLink LatestDeclLink(decl_type *D) {
-    return DeclLink(D, true);
+  static DeclLink LatestDeclLink(const ASTContext &Ctx) {
+    return DeclLink(DeclLink::LatestLink, Ctx);
   }
 
   /// \brief Points to the next redeclaration in the chain.
@@ -58,15 +115,20 @@
   /// If there is only one declaration, it is <pointer to self, true>
   DeclLink RedeclLink;
 
+  decl_type *getNextRedeclaration() const {
+    return RedeclLink.getNext(static_cast<const decl_type *>(this));
+  }
+
 public:
-  Redeclarable() : RedeclLink(LatestDeclLink(static_cast<decl_type*>(this))) { }
+  Redeclarable(const ASTContext &Ctx)
+      : RedeclLink(LatestDeclLink(Ctx)) {}
 
   /// \brief Return the previous declaration of this declaration or NULL if this
   /// is the first declaration.
   decl_type *getPreviousDecl() {
     if (RedeclLink.NextIsPrevious())
-      return RedeclLink.getNext();
-    return 0;
+      return getNextRedeclaration();
+    return nullptr;
   }
   const decl_type *getPreviousDecl() const {
     return const_cast<decl_type *>(
@@ -96,14 +158,14 @@
 
   /// \brief Returns the most recent (re)declaration of this declaration.
   decl_type *getMostRecentDecl() {
-    return getFirstDecl()->RedeclLink.getNext();
+    return getFirstDecl()->getNextRedeclaration();
   }
 
   /// \brief Returns the most recent (re)declaration of this declaration.
   const decl_type *getMostRecentDecl() const {
-    return getFirstDecl()->RedeclLink.getNext();
+    return getFirstDecl()->getNextRedeclaration();
   }
-  
+
   /// \brief Set the previous declaration. If PrevDecl is NULL, set this as the
   /// first and only declaration.
   void setPreviousDecl(decl_type *PrevDecl);
@@ -122,7 +184,7 @@
     typedef std::forward_iterator_tag iterator_category;
     typedef std::ptrdiff_t            difference_type;
 
-    redecl_iterator() : Current(0) { }
+    redecl_iterator() : Current(nullptr) { }
     explicit redecl_iterator(decl_type *C)
       : Current(C), Starter(C), PassedFirst(false) { }
 
@@ -135,15 +197,15 @@
       if (Current->isFirstDecl()) {
         if (PassedFirst) {
           assert(0 && "Passed first decl twice, invalid redecl chain!");
-          Current = 0;
+          Current = nullptr;
           return *this;
         }
         PassedFirst = true;
       }
 
       // Get either previous decl or latest decl.
-      decl_type *Next = Current->RedeclLink.getNext();
-      Current = (Next != Starter ? Next : 0);
+      decl_type *Next = Current->getNextRedeclaration();
+      Current = (Next != Starter) ? Next : nullptr;
       return *this;
     }
 
@@ -161,13 +223,18 @@
     }
   };
 
-  /// \brief Returns iterator for all the redeclarations of the same decl.
-  /// It will iterate at least once (when this decl is the only one).
-  redecl_iterator redecls_begin() const {
-    return redecl_iterator(const_cast<decl_type*>(
-                                          static_cast<const decl_type*>(this)));
+  typedef llvm::iterator_range<redecl_iterator> redecl_range;
+
+  /// \brief Returns an iterator range for all the redeclarations of the same
+  /// decl. It will iterate at least once (when this decl is the only one).
+  redecl_range redecls() const {
+    return redecl_range(redecl_iterator(const_cast<decl_type *>(
+                            static_cast<const decl_type *>(this))),
+                        redecl_iterator());
   }
-  redecl_iterator redecls_end() const { return redecl_iterator(); }
+
+  redecl_iterator redecls_begin() const { return redecls().begin(); }
+  redecl_iterator redecls_end() const { return redecls().end(); }
 
   friend class ASTDeclReader;
   friend class ASTDeclWriter;
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index ace53d8..fb94097 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -62,7 +62,7 @@
     Stmt** I;
   public:
     ExprIterator(Stmt** i) : I(i) {}
-    ExprIterator() : I(0) {}
+    ExprIterator() : I(nullptr) {}
     ExprIterator& operator++() { ++I; return *this; }
     ExprIterator operator-(size_t i) { return I-i; }
     ExprIterator operator+(size_t i) { return I+i; }
@@ -81,7 +81,7 @@
     const Stmt * const *I;
   public:
     ConstExprIterator(const Stmt * const *i) : I(i) {}
-    ConstExprIterator() : I(0) {}
+    ConstExprIterator() : I(nullptr) {}
     ConstExprIterator& operator++() { ++I; return *this; }
     ConstExprIterator operator+(size_t i) const { return I+i; }
     ConstExprIterator operator-(size_t i) const { return I-i; }
@@ -371,12 +371,12 @@
 
   /// \brief Dumps the specified AST fragment and all subtrees to
   /// \c llvm::errs().
-  LLVM_ATTRIBUTE_USED void dump() const;
-  LLVM_ATTRIBUTE_USED void dump(SourceManager &SM) const;
+  void dump() const;
+  void dump(SourceManager &SM) const;
   void dump(raw_ostream &OS, SourceManager &SM) const;
 
   /// dumpColor - same as dump(), but forces color highlighting.
-  LLVM_ATTRIBUTE_USED void dumpColor() const;
+  void dumpColor() const;
 
   /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST
   /// back to its original source language syntax.
@@ -485,7 +485,13 @@
 
   typedef DeclGroupRef::iterator decl_iterator;
   typedef DeclGroupRef::const_iterator const_decl_iterator;
+  typedef llvm::iterator_range<decl_iterator> decl_range;
+  typedef llvm::iterator_range<const_decl_iterator> decl_const_range;
 
+  decl_range decls() { return decl_range(decl_begin(), decl_end()); }
+  decl_const_range decls() const {
+    return decl_const_range(decl_begin(), decl_end());
+  }
   decl_iterator decl_begin() { return DG.begin(); }
   decl_iterator decl_end() { return DG.end(); }
   const_decl_iterator decl_begin() const { return DG.begin(); }
@@ -549,13 +555,13 @@
 
   // \brief Build an empty compound statement with a location.
   explicit CompoundStmt(SourceLocation Loc)
-    : Stmt(CompoundStmtClass), Body(0), LBracLoc(Loc), RBracLoc(Loc) {
+    : Stmt(CompoundStmtClass), Body(nullptr), LBracLoc(Loc), RBracLoc(Loc) {
     CompoundStmtBits.NumStmts = 0;
   }
 
   // \brief Build an empty compound statement.
   explicit CompoundStmt(EmptyShell Empty)
-    : Stmt(CompoundStmtClass, Empty), Body(0) {
+    : Stmt(CompoundStmtClass, Empty), Body(nullptr) {
     CompoundStmtBits.NumStmts = 0;
   }
 
@@ -565,9 +571,12 @@
   unsigned size() const { return CompoundStmtBits.NumStmts; }
 
   typedef Stmt** body_iterator;
+  typedef llvm::iterator_range<body_iterator> body_range;
+
+  body_range body() { return body_range(body_begin(), body_end()); }
   body_iterator body_begin() { return Body; }
   body_iterator body_end() { return Body + size(); }
-  Stmt *body_back() { return !body_empty() ? Body[size()-1] : 0; }
+  Stmt *body_back() { return !body_empty() ? Body[size()-1] : nullptr; }
 
   void setLastStmt(Stmt *S) {
     assert(!body_empty() && "setLastStmt");
@@ -575,9 +584,16 @@
   }
 
   typedef Stmt* const * const_body_iterator;
+  typedef llvm::iterator_range<const_body_iterator> body_const_range;
+
+  body_const_range body() const {
+    return body_const_range(body_begin(), body_end());
+  }
   const_body_iterator body_begin() const { return Body; }
   const_body_iterator body_end() const { return Body + size(); }
-  const Stmt *body_back() const { return !body_empty() ? Body[size()-1] : 0; }
+  const Stmt *body_back() const {
+    return !body_empty() ? Body[size() - 1] : nullptr;
+  }
 
   typedef std::reverse_iterator<body_iterator> reverse_body_iterator;
   reverse_body_iterator body_rbegin() {
@@ -612,11 +628,11 @@
 
   // Iterators
   child_range children() {
-    return child_range(&Body[0], &Body[0]+CompoundStmtBits.NumStmts);
+    return child_range(Body, Body + CompoundStmtBits.NumStmts);
   }
 
   const_child_range children() const {
-    return child_range(&Body[0], &Body[0]+CompoundStmtBits.NumStmts);
+    return child_range(Body, Body + CompoundStmtBits.NumStmts);
   }
 };
 
@@ -630,10 +646,11 @@
   SourceLocation ColonLoc;
 
   SwitchCase(StmtClass SC, SourceLocation KWLoc, SourceLocation ColonLoc)
-    : Stmt(SC), NextSwitchCase(0), KeywordLoc(KWLoc), ColonLoc(ColonLoc) {}
+    : Stmt(SC), NextSwitchCase(nullptr), KeywordLoc(KWLoc), ColonLoc(ColonLoc) {
+  }
 
   SwitchCase(StmtClass SC, EmptyShell)
-    : Stmt(SC), NextSwitchCase(0) {}
+    : Stmt(SC), NextSwitchCase(nullptr) {}
 
 public:
   const SwitchCase *getNextSwitchCase() const { return NextSwitchCase; }
@@ -670,7 +687,7 @@
   CaseStmt(Expr *lhs, Expr *rhs, SourceLocation caseLoc,
            SourceLocation ellipsisLoc, SourceLocation colonLoc)
     : SwitchCase(CaseStmtClass, caseLoc, colonLoc) {
-    SubExprs[SUBSTMT] = 0;
+    SubExprs[SUBSTMT] = nullptr;
     SubExprs[LHS] = reinterpret_cast<Stmt*>(lhs);
     SubExprs[RHS] = reinterpret_cast<Stmt*>(rhs);
     EllipsisLoc = ellipsisLoc;
@@ -802,21 +819,25 @@
   Stmt *SubStmt;
   SourceLocation AttrLoc;
   unsigned NumAttrs;
-  const Attr *Attrs[1];
 
   friend class ASTStmtReader;
 
   AttributedStmt(SourceLocation Loc, ArrayRef<const Attr*> Attrs, Stmt *SubStmt)
     : Stmt(AttributedStmtClass), SubStmt(SubStmt), AttrLoc(Loc),
       NumAttrs(Attrs.size()) {
-    memcpy(this->Attrs, Attrs.data(), Attrs.size() * sizeof(Attr*));
+    memcpy(getAttrArrayPtr(), Attrs.data(), Attrs.size() * sizeof(Attr *));
   }
 
   explicit AttributedStmt(EmptyShell Empty, unsigned NumAttrs)
     : Stmt(AttributedStmtClass, Empty), NumAttrs(NumAttrs) {
-    memset(Attrs, 0, NumAttrs * sizeof(Attr*));
+    memset(getAttrArrayPtr(), 0, NumAttrs * sizeof(Attr *));
   }
 
+  Attr *const *getAttrArrayPtr() const {
+    return reinterpret_cast<Attr *const *>(this + 1);
+  }
+  Attr **getAttrArrayPtr() { return reinterpret_cast<Attr **>(this + 1); }
+
 public:
   static AttributedStmt *Create(const ASTContext &C, SourceLocation Loc,
                                 ArrayRef<const Attr*> Attrs, Stmt *SubStmt);
@@ -825,7 +846,7 @@
 
   SourceLocation getAttrLoc() const { return AttrLoc; }
   ArrayRef<const Attr*> getAttrs() const {
-    return ArrayRef<const Attr*>(Attrs, NumAttrs);
+    return ArrayRef<const Attr*>(getAttrArrayPtr(), NumAttrs);
   }
   Stmt *getSubStmt() { return SubStmt; }
   const Stmt *getSubStmt() const { return SubStmt; }
@@ -852,7 +873,8 @@
 
 public:
   IfStmt(const ASTContext &C, SourceLocation IL, VarDecl *var, Expr *cond,
-         Stmt *then, SourceLocation EL = SourceLocation(), Stmt *elsev = 0);
+         Stmt *then, SourceLocation EL = SourceLocation(),
+         Stmt *elsev = nullptr);
 
   /// \brief Build an empty if/then/else statement
   explicit IfStmt(EmptyShell Empty) : Stmt(IfStmtClass, Empty) { }
@@ -1320,7 +1342,8 @@
 
 public:
   ReturnStmt(SourceLocation RL)
-    : Stmt(ReturnStmtClass), RetExpr(0), RetLoc(RL), NRVOCandidate(0) { }
+    : Stmt(ReturnStmtClass), RetExpr(nullptr), RetLoc(RL),
+      NRVOCandidate(nullptr) {}
 
   ReturnStmt(SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate)
     : Stmt(ReturnStmtClass), RetExpr((Stmt*) E), RetLoc(RL),
@@ -1389,7 +1412,7 @@
 public:
   /// \brief Build an empty inline-assembly statement.
   explicit AsmStmt(StmtClass SC, EmptyShell Empty) :
-    Stmt(SC, Empty), Exprs(0) { }
+    Stmt(SC, Empty), Exprs(nullptr) { }
 
   SourceLocation getAsmLoc() const { return AsmLoc; }
   void setAsmLoc(SourceLocation L) { AsmLoc = L; }
@@ -1454,6 +1477,8 @@
 
   typedef ExprIterator inputs_iterator;
   typedef ConstExprIterator const_inputs_iterator;
+  typedef llvm::iterator_range<inputs_iterator> inputs_range;
+  typedef llvm::iterator_range<const_inputs_iterator> inputs_const_range;
 
   inputs_iterator begin_inputs() {
     return &Exprs[0] + NumOutputs;
@@ -1463,6 +1488,8 @@
     return &Exprs[0] + NumOutputs + NumInputs;
   }
 
+  inputs_range inputs() { return inputs_range(begin_inputs(), end_inputs()); }
+
   const_inputs_iterator begin_inputs() const {
     return &Exprs[0] + NumOutputs;
   }
@@ -1471,10 +1498,16 @@
     return &Exprs[0] + NumOutputs + NumInputs;
   }
 
+  inputs_const_range inputs() const {
+    return inputs_const_range(begin_inputs(), end_inputs());
+  }
+
   // Output expr iterators.
 
   typedef ExprIterator outputs_iterator;
   typedef ConstExprIterator const_outputs_iterator;
+  typedef llvm::iterator_range<outputs_iterator> outputs_range;
+  typedef llvm::iterator_range<const_outputs_iterator> outputs_const_range;
 
   outputs_iterator begin_outputs() {
     return &Exprs[0];
@@ -1482,6 +1515,9 @@
   outputs_iterator end_outputs() {
     return &Exprs[0] + NumOutputs;
   }
+  outputs_range outputs() {
+    return outputs_range(begin_outputs(), end_outputs());
+  }
 
   const_outputs_iterator begin_outputs() const {
     return &Exprs[0];
@@ -1489,6 +1525,9 @@
   const_outputs_iterator end_outputs() const {
     return &Exprs[0] + NumOutputs;
   }
+  outputs_const_range outputs() const {
+    return outputs_const_range(begin_outputs(), end_outputs());
+  }
 
   child_range children() {
     return child_range(&Exprs[0], &Exprs[0] + NumOutputs + NumInputs);
@@ -1517,7 +1556,7 @@
 
   /// \brief Build an empty inline-assembly statement.
   explicit GCCAsmStmt(EmptyShell Empty) : AsmStmt(GCCAsmStmtClass, Empty),
-    Constraints(0), Clobbers(0), Names(0) { }
+    Constraints(nullptr), Clobbers(nullptr), Names(nullptr) { }
 
   SourceLocation getRParenLoc() const { return RParenLoc; }
   void setRParenLoc(SourceLocation L) { RParenLoc = L; }
@@ -1693,7 +1732,7 @@
 
   /// \brief Build an empty MS-style inline-assembly statement.
   explicit MSAsmStmt(EmptyShell Empty) : AsmStmt(MSAsmStmtClass, Empty),
-    NumAsmToks(0), AsmToks(0), Constraints(0), Clobbers(0) { }
+    NumAsmToks(0), AsmToks(nullptr), Constraints(nullptr), Clobbers(nullptr) { }
 
   SourceLocation getLBraceLoc() const { return LBraceLoc; }
   void setLBraceLoc(SourceLocation L) { LBraceLoc = L; }
@@ -1767,7 +1806,7 @@
   }
 
   child_range children() {
-    return child_range(&Exprs[0], &Exprs[0]);
+    return child_range(&Exprs[0], &Exprs[NumInputs + NumOutputs]);
   }
 };
 
@@ -1853,22 +1892,24 @@
   bool            IsCXXTry;
   SourceLocation  TryLoc;
   Stmt           *Children[2];
+  int             HandlerIndex;
+  int             HandlerParentIndex;
 
   enum { TRY = 0, HANDLER = 1 };
 
   SEHTryStmt(bool isCXXTry, // true if 'try' otherwise '__try'
-             SourceLocation TryLoc,
-             Stmt *TryBlock,
-             Stmt *Handler);
+             SourceLocation TryLoc, Stmt *TryBlock, Stmt *Handler,
+             int HandlerIndex, int HandlerParentIndex);
 
   friend class ASTReader;
   friend class ASTStmtReader;
   explicit SEHTryStmt(EmptyShell E) : Stmt(SEHTryStmtClass, E) { }
 
 public:
-  static SEHTryStmt* Create(const ASTContext &C, bool isCXXTry,
+  static SEHTryStmt *Create(const ASTContext &C, bool isCXXTry,
                             SourceLocation TryLoc, Stmt *TryBlock,
-                            Stmt *Handler);
+                            Stmt *Handler, int HandlerIndex,
+                            int HandlerParentIndex);
 
   SourceLocation getLocStart() const LLVM_READONLY { return getTryLoc(); }
   SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
@@ -1895,6 +1936,34 @@
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == SEHTryStmtClass;
   }
+
+  int getHandlerIndex() const { return HandlerIndex; }
+  int getHandlerParentIndex() const { return HandlerParentIndex; }
+};
+
+/// Represents a __leave statement.
+///
+class SEHLeaveStmt : public Stmt {
+  SourceLocation LeaveLoc;
+public:
+  explicit SEHLeaveStmt(SourceLocation LL)
+      : Stmt(SEHLeaveStmtClass), LeaveLoc(LL) {}
+
+  /// \brief Build an empty __leave statement.
+  explicit SEHLeaveStmt(EmptyShell Empty) : Stmt(SEHLeaveStmtClass, Empty) { }
+
+  SourceLocation getLeaveLoc() const { return LeaveLoc; }
+  void setLeaveLoc(SourceLocation L) { LeaveLoc = L; }
+
+  SourceLocation getLocStart() const LLVM_READONLY { return LeaveLoc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return LeaveLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == SEHLeaveStmtClass;
+  }
+
+  // Iterators
+  child_range children() { return child_range(); }
 };
 
 /// \brief This captures a statement into a function. For example, the following
@@ -1928,11 +1997,12 @@
     ///
     /// \param Var The variable being captured, or null if capturing this.
     ///
-    Capture(SourceLocation Loc, VariableCaptureKind Kind, VarDecl *Var = 0)
+    Capture(SourceLocation Loc, VariableCaptureKind Kind,
+            VarDecl *Var = nullptr)
       : VarAndKind(Var, Kind), Loc(Loc) {
       switch (Kind) {
       case VCK_This:
-        assert(Var == 0 && "'this' capture cannot have a variable!");
+        assert(!Var && "'this' capture cannot have a variable!");
         break;
       case VCK_ByRef:
         assert(Var && "capturing by reference must have a variable!");
@@ -2042,6 +2112,15 @@
   /// \brief An iterator that walks over the captures.
   typedef Capture *capture_iterator;
   typedef const Capture *const_capture_iterator;
+  typedef llvm::iterator_range<capture_iterator> capture_range;
+  typedef llvm::iterator_range<const_capture_iterator> capture_const_range;
+
+  capture_range captures() {
+    return capture_range(capture_begin(), capture_end());
+  }
+  capture_const_range captures() const {
+    return capture_const_range(capture_begin(), capture_end());
+  }
 
   /// \brief Retrieve an iterator pointing to the first capture.
   capture_iterator capture_begin() { return getStoredCaptures(); }
@@ -2058,6 +2137,11 @@
 
   /// \brief Iterator that walks over the capture initialization arguments.
   typedef Expr **capture_init_iterator;
+  typedef llvm::iterator_range<capture_init_iterator> capture_init_range;
+
+  capture_init_range capture_inits() const {
+    return capture_init_range(capture_init_begin(), capture_init_end());
+  }
 
   /// \brief Retrieve the first initialization argument.
   capture_init_iterator capture_init_begin() const {
diff --git a/include/clang/AST/StmtCXX.h b/include/clang/AST/StmtCXX.h
index df98d41..837dc45 100644
--- a/include/clang/AST/StmtCXX.h
+++ b/include/clang/AST/StmtCXX.h
@@ -39,7 +39,7 @@
     HandlerBlock(handlerBlock) {}
 
   CXXCatchStmt(EmptyShell Empty)
-  : Stmt(CXXCatchStmtClass), ExceptionDecl(0), HandlerBlock(0) {}
+  : Stmt(CXXCatchStmtClass), ExceptionDecl(nullptr), HandlerBlock(nullptr) {}
 
   SourceLocation getLocStart() const LLVM_READONLY { return CatchLoc; }
   SourceLocation getLocEnd() const LLVM_READONLY {
diff --git a/include/clang/AST/StmtIterator.h b/include/clang/AST/StmtIterator.h
index fbc8e5d..18c5516 100644
--- a/include/clang/AST/StmtIterator.h
+++ b/include/clang/AST/StmtIterator.h
@@ -14,8 +14,8 @@
 #ifndef LLVM_CLANG_AST_STMT_ITR_H
 #define LLVM_CLANG_AST_STMT_ITR_H
 
-#include "llvm/Support/DataTypes.h"
 #include "llvm/Support/Compiler.h"
+#include "llvm/Support/DataTypes.h"
 #include <cassert>
 #include <cstddef>
 #include <iterator>
@@ -64,10 +64,10 @@
 
   Stmt*& GetDeclExpr() const;
 
-  StmtIteratorBase(Stmt **s) : stmt(s), DGI(0), RawVAPtr(0) {}
+  StmtIteratorBase(Stmt **s) : stmt(s), DGI(nullptr), RawVAPtr(0) {}
   StmtIteratorBase(const VariableArrayType *t);
   StmtIteratorBase(Decl **dgi, Decl **dge);
-  StmtIteratorBase() : stmt(0), DGI(0), RawVAPtr(0) {}
+  StmtIteratorBase() : stmt(nullptr), DGI(nullptr), RawVAPtr(0) {}
 };
 
 
diff --git a/include/clang/AST/StmtObjC.h b/include/clang/AST/StmtObjC.h
index bfb4a9b..d0527e2 100644
--- a/include/clang/AST/StmtObjC.h
+++ b/include/clang/AST/StmtObjC.h
@@ -107,7 +107,7 @@
   SourceLocation getLocStart() const LLVM_READONLY { return AtCatchLoc; }
   SourceLocation getLocEnd() const LLVM_READONLY { return Body->getLocEnd(); }
 
-  bool hasEllipsis() const { return getCatchParamDecl() == 0; }
+  bool hasEllipsis() const { return getCatchParamDecl() == nullptr; }
 
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == ObjCAtCatchStmtClass;
@@ -222,13 +222,13 @@
   /// \brief Retrieve the \@finally statement, if any.
   const ObjCAtFinallyStmt *getFinallyStmt() const {
     if (!HasFinally)
-      return 0;
+      return nullptr;
     
     return cast_or_null<ObjCAtFinallyStmt>(getStmts()[1 + NumCatchStmts]);
   }
   ObjCAtFinallyStmt *getFinallyStmt() {
     if (!HasFinally)
-      return 0;
+      return nullptr;
     
     return cast_or_null<ObjCAtFinallyStmt>(getStmts()[1 + NumCatchStmts]);
   }
diff --git a/include/clang/AST/StmtOpenMP.h b/include/clang/AST/StmtOpenMP.h
index 8570d88..db02afe 100644
--- a/include/clang/AST/StmtOpenMP.h
+++ b/include/clang/AST/StmtOpenMP.h
@@ -1,4 +1,4 @@
-//===- StmtOpenMP.h - Classes for OpenMP directives and clauses --*- C++ -*-===//
+//===- StmtOpenMP.h - Classes for OpenMP directives  ------------*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -15,359 +15,15 @@
 #ifndef LLVM_CLANG_AST_STMTOPENMP_H
 #define LLVM_CLANG_AST_STMTOPENMP_H
 
+#include "clang/AST/Expr.h"
+#include "clang/AST/OpenMPClause.h"
+#include "clang/AST/Stmt.h"
 #include "clang/Basic/OpenMPKinds.h"
 #include "clang/Basic/SourceLocation.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/Stmt.h"
 
 namespace clang {
 
 //===----------------------------------------------------------------------===//
-// AST classes for clauses.
-//===----------------------------------------------------------------------===//
-
-/// \brief This is a basic class for representing single OpenMP clause.
-///
-class OMPClause {
-  /// \brief Starting location of the clause (the clause keyword).
-  SourceLocation StartLoc;
-  /// \brief Ending location of the clause.
-  SourceLocation EndLoc;
-  /// \brief Kind of the clause.
-  OpenMPClauseKind Kind;
-protected:
-  OMPClause(OpenMPClauseKind K, SourceLocation StartLoc, SourceLocation EndLoc)
-    : StartLoc(StartLoc), EndLoc(EndLoc), Kind(K) {}
-
-public:
-
-  /// \brief Returns the starting location of the clause.
-  SourceLocation getLocStart() const { return StartLoc; }
-  /// \brief Returns the ending location of the clause.
-  SourceLocation getLocEnd() const { return EndLoc; }
-
-  /// \brief Sets the starting location of the clause.
-  void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
-  /// \brief Sets the ending location of the clause.
-  void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
-
-  /// \brief Returns kind of OpenMP clause (private, shared, reduction, etc.).
-  OpenMPClauseKind getClauseKind() const { return Kind; }
-
-  bool isImplicit() const { return StartLoc.isInvalid();}
-
-  StmtRange children();
-  ConstStmtRange children() const {
-    return const_cast<OMPClause *>(this)->children();
-  }
-  static bool classof(const OMPClause *T) {
-    return true;
-  }
-};
-
-/// \brief This represents clauses with the list of variables like 'private',
-/// 'firstprivate', 'copyin', 'shared', or 'reduction' clauses in the
-/// '#pragma omp ...' directives.
-template <class T>
-class OMPVarList {
-  friend class OMPClauseReader;
-  /// \brief Location of '('.
-  SourceLocation LParenLoc;
-  /// \brief Number of variables in the list.
-  unsigned NumVars;
-protected:
-  /// \brief Fetches list of variables associated with this clause.
-  llvm::MutableArrayRef<Expr *> getVarRefs() {
-    return llvm::MutableArrayRef<Expr *>(
-                         reinterpret_cast<Expr **>(static_cast<T *>(this) + 1),
-                         NumVars);
-  }
-
-  /// \brief Sets the list of variables for this clause.
-  void setVarRefs(ArrayRef<Expr *> VL) {
-    assert(VL.size() == NumVars &&
-           "Number of variables is not the same as the preallocated buffer");
-    std::copy(VL.begin(), VL.end(),
-              reinterpret_cast<Expr **>(static_cast<T *>(this) + 1));
-  }
-
-  /// \brief Build clause with number of variables \a N.
-  ///
-  /// \param N Number of the variables in the clause.
-  ///
-  OMPVarList(SourceLocation LParenLoc, unsigned N)
-    : LParenLoc(LParenLoc), NumVars(N) { }
-public:
-  typedef llvm::MutableArrayRef<Expr *>::iterator varlist_iterator;
-  typedef ArrayRef<const Expr *>::iterator varlist_const_iterator;
-
-  unsigned varlist_size() const { return NumVars; }
-  bool varlist_empty() const { return NumVars == 0; }
-  varlist_iterator varlist_begin() { return getVarRefs().begin(); }
-  varlist_iterator varlist_end() { return getVarRefs().end(); }
-  varlist_const_iterator varlist_begin() const { return getVarRefs().begin(); }
-  varlist_const_iterator varlist_end() const { return getVarRefs().end(); }
-
-  /// \brief Sets the location of '('.
-  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
-  /// \brief Returns the location of '('.
-  SourceLocation getLParenLoc() const { return LParenLoc; }
-
-  /// \brief Fetches list of all variables in the clause.
-  ArrayRef<const Expr *> getVarRefs() const {
-    return ArrayRef<const Expr *>(
-       reinterpret_cast<const Expr *const *>(static_cast<const T *>(this) + 1),
-       NumVars);
-  }
-};
-
-/// \brief This represents 'default' clause in the '#pragma omp ...' directive.
-///
-/// \code
-/// #pragma omp parallel default(shared)
-/// \endcode
-/// In this example directive '#pragma omp parallel' has simple 'default'
-/// clause with kind 'shared'.
-///
-class OMPDefaultClause : public OMPClause {
-  friend class OMPClauseReader;
-  /// \brief Location of '('.
-  SourceLocation LParenLoc;
-  /// \brief A kind of the 'default' clause.
-  OpenMPDefaultClauseKind Kind;
-  /// \brief Start location of the kind in source code.
-  SourceLocation KindKwLoc;
-
-  /// \brief Set kind of the clauses.
-  ///
-  /// \param K Argument of clause.
-  ///
-  void setDefaultKind(OpenMPDefaultClauseKind K) { Kind = K; }
-
-  /// \brief Set argument location.
-  ///
-  /// \param KLoc Argument location.
-  ///
-  void setDefaultKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; }
-public:
-  /// \brief Build 'default' clause with argument \a A ('none' or 'shared').
-  ///
-  /// \param A Argument of the clause ('none' or 'shared').
-  /// \param ALoc Starting location of the argument.
-  /// \param StartLoc Starting location of the clause.
-  /// \param LParenLoc Location of '('.
-  /// \param EndLoc Ending location of the clause.
-  ///
-  OMPDefaultClause(OpenMPDefaultClauseKind A, SourceLocation ALoc,
-                   SourceLocation StartLoc, SourceLocation LParenLoc,
-                   SourceLocation EndLoc)
-    : OMPClause(OMPC_default, StartLoc, EndLoc), LParenLoc(LParenLoc),
-      Kind(A), KindKwLoc(ALoc) { }
-
-  /// \brief Build an empty clause.
-  ///
-  OMPDefaultClause()
-    : OMPClause(OMPC_default, SourceLocation(), SourceLocation()),
-      LParenLoc(SourceLocation()), Kind(OMPC_DEFAULT_unknown),
-      KindKwLoc(SourceLocation()) { }
-
-  /// \brief Sets the location of '('.
-  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
-  /// \brief Returns the location of '('.
-  SourceLocation getLParenLoc() const { return LParenLoc; }
-
-  /// \brief Returns kind of the clause.
-  OpenMPDefaultClauseKind getDefaultKind() const { return Kind; }
-
-  /// \brief Returns location of clause kind.
-  SourceLocation getDefaultKindKwLoc() const { return KindKwLoc; }
-
-  static bool classof(const OMPClause *T) {
-    return T->getClauseKind() == OMPC_default;
-  }
-
-  StmtRange children() {
-    return StmtRange();
-  }
-};
-
-/// \brief This represents clause 'private' in the '#pragma omp ...' directives.
-///
-/// \code
-/// #pragma omp parallel private(a,b)
-/// \endcode
-/// In this example directive '#pragma omp parallel' has clause 'private'
-/// with the variables 'a' and 'b'.
-///
-class OMPPrivateClause : public OMPClause, public OMPVarList<OMPPrivateClause> {
-  /// \brief Build clause with number of variables \a N.
-  ///
-  /// \param StartLoc Starting location of the clause.
-  /// \param LParenLoc Location of '('.
-  /// \param EndLoc Ending location of the clause.
-  /// \param N Number of the variables in the clause.
-  ///
-  OMPPrivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
-                   SourceLocation EndLoc, unsigned N)
-    : OMPClause(OMPC_private, StartLoc, EndLoc),
-      OMPVarList<OMPPrivateClause>(LParenLoc, N) { }
-
-  /// \brief Build an empty clause.
-  ///
-  /// \param N Number of variables.
-  ///
-  explicit OMPPrivateClause(unsigned N)
-    : OMPClause(OMPC_private, SourceLocation(), SourceLocation()),
-      OMPVarList<OMPPrivateClause>(SourceLocation(), N) { }
-public:
-  /// \brief Creates clause with a list of variables \a VL.
-  ///
-  /// \param C AST context.
-  /// \param StartLoc Starting location of the clause.
-  /// \param LParenLoc Location of '('.
-  /// \param EndLoc Ending location of the clause.
-  /// \param VL List of references to the variables.
-  ///
-  static OMPPrivateClause *Create(const ASTContext &C, SourceLocation StartLoc,
-                                  SourceLocation LParenLoc,
-                                  SourceLocation EndLoc,
-                                  ArrayRef<Expr *> VL);
-  /// \brief Creates an empty clause with the place for \a N variables.
-  ///
-  /// \param C AST context.
-  /// \param N The number of variables.
-  ///
-  static OMPPrivateClause *CreateEmpty(const ASTContext &C, unsigned N);
-
-  StmtRange children() {
-    return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
-                     reinterpret_cast<Stmt **>(varlist_end()));
-  }
-
-  static bool classof(const OMPClause *T) {
-    return T->getClauseKind() == OMPC_private;
-  }
-};
-
-/// \brief This represents clause 'firstprivate' in the '#pragma omp ...'
-/// directives.
-///
-/// \code
-/// #pragma omp parallel firstprivate(a,b)
-/// \endcode
-/// In this example directive '#pragma omp parallel' has clause 'firstprivate'
-/// with the variables 'a' and 'b'.
-///
-class OMPFirstprivateClause : public OMPClause,
-                              public OMPVarList<OMPFirstprivateClause> {
-  /// \brief Build clause with number of variables \a N.
-  ///
-  /// \param StartLoc Starting location of the clause.
-  /// \param LParenLoc Location of '('.
-  /// \param EndLoc Ending location of the clause.
-  /// \param N Number of the variables in the clause.
-  ///
-  OMPFirstprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
-                   SourceLocation EndLoc, unsigned N)
-    : OMPClause(OMPC_firstprivate, StartLoc, EndLoc),
-      OMPVarList<OMPFirstprivateClause>(LParenLoc, N) { }
-
-  /// \brief Build an empty clause.
-  ///
-  /// \param N Number of variables.
-  ///
-  explicit OMPFirstprivateClause(unsigned N)
-    : OMPClause(OMPC_firstprivate, SourceLocation(), SourceLocation()),
-      OMPVarList<OMPFirstprivateClause>(SourceLocation(), N) { }
-public:
-  /// \brief Creates clause with a list of variables \a VL.
-  ///
-  /// \param C AST context.
-  /// \param StartLoc Starting location of the clause.
-  /// \param LParenLoc Location of '('.
-  /// \param EndLoc Ending location of the clause.
-  /// \param VL List of references to the variables.
-  ///
-  static OMPFirstprivateClause *Create(const ASTContext &C,
-                                       SourceLocation StartLoc,
-                                       SourceLocation LParenLoc,
-                                       SourceLocation EndLoc,
-                                       ArrayRef<Expr *> VL);
-  /// \brief Creates an empty clause with the place for \a N variables.
-  ///
-  /// \param C AST context.
-  /// \param N The number of variables.
-  ///
-  static OMPFirstprivateClause *CreateEmpty(const ASTContext &C, unsigned N);
-
-  StmtRange children() {
-    return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
-                     reinterpret_cast<Stmt **>(varlist_end()));
-  }
-
-  static bool classof(const OMPClause *T) {
-    return T->getClauseKind() == OMPC_firstprivate;
-  }
-};
-
-/// \brief This represents clause 'shared' in the '#pragma omp ...' directives.
-///
-/// \code
-/// #pragma omp parallel shared(a,b)
-/// \endcode
-/// In this example directive '#pragma omp parallel' has clause 'shared'
-/// with the variables 'a' and 'b'.
-///
-class OMPSharedClause : public OMPClause, public OMPVarList<OMPSharedClause> {
-  /// \brief Build clause with number of variables \a N.
-  ///
-  /// \param StartLoc Starting location of the clause.
-  /// \param LParenLoc Location of '('.
-  /// \param EndLoc Ending location of the clause.
-  /// \param N Number of the variables in the clause.
-  ///
-  OMPSharedClause(SourceLocation StartLoc, SourceLocation LParenLoc,
-                  SourceLocation EndLoc, unsigned N)
-    : OMPClause(OMPC_shared, StartLoc, EndLoc),
-      OMPVarList<OMPSharedClause>(LParenLoc, N) { }
-
-  /// \brief Build an empty clause.
-  ///
-  /// \param N Number of variables.
-  ///
-  explicit OMPSharedClause(unsigned N)
-    : OMPClause(OMPC_shared, SourceLocation(), SourceLocation()),
-      OMPVarList<OMPSharedClause>(SourceLocation(), N) { }
-public:
-  /// \brief Creates clause with a list of variables \a VL.
-  ///
-  /// \param C AST context.
-  /// \param StartLoc Starting location of the clause.
-  /// \param LParenLoc Location of '('.
-  /// \param EndLoc Ending location of the clause.
-  /// \param VL List of references to the variables.
-  ///
-  static OMPSharedClause *Create(const ASTContext &C, SourceLocation StartLoc,
-                                 SourceLocation LParenLoc,
-                                 SourceLocation EndLoc, ArrayRef<Expr *> VL);
-  /// \brief Creates an empty clause with \a N variables.
-  ///
-  /// \param C AST context.
-  /// \param N The number of variables.
-  ///
-  static OMPSharedClause *CreateEmpty(const ASTContext &C, unsigned N);
-
-  StmtRange children() {
-    return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
-                     reinterpret_cast<Stmt **>(varlist_end()));
-  }
-
-  static bool classof(const OMPClause *T) {
-    return T->getClauseKind() == OMPC_shared;
-  }
-};
-
-//===----------------------------------------------------------------------===//
 // AST classes for directives.
 //===----------------------------------------------------------------------===//
 
@@ -382,10 +38,23 @@
   SourceLocation StartLoc;
   /// \brief Ending location of the directive.
   SourceLocation EndLoc;
-  /// \brief Pointer to the list of clauses.
-  llvm::MutableArrayRef<OMPClause *> Clauses;
-  /// \brief Associated statement (if any) and expressions.
-  llvm::MutableArrayRef<Stmt *> StmtAndExpressions;
+  /// \brief Numbers of clauses.
+  const unsigned NumClauses;
+  /// \brief Number of child expressions/stmts.
+  const unsigned NumChildren;
+  /// \brief Offset from this to the start of clauses.
+  /// There are NumClauses pointers to clauses, they are followed by
+  /// NumChildren pointers to child stmts/exprs (if the directive type
+  /// requires an associated stmt, then it has to be the first of them).
+  const unsigned ClausesOffset;
+
+  /// \brief Get the clauses storage.
+  MutableArrayRef<OMPClause *> getClauses() {
+    OMPClause **ClauseStorage = reinterpret_cast<OMPClause **>(
+        reinterpret_cast<char *>(this) + ClausesOffset);
+    return MutableArrayRef<OMPClause *>(ClauseStorage, NumClauses);
+  }
+
 protected:
   /// \brief Build instance of directive of class \a K.
   ///
@@ -397,12 +66,12 @@
   template <typename T>
   OMPExecutableDirective(const T *, StmtClass SC, OpenMPDirectiveKind K,
                          SourceLocation StartLoc, SourceLocation EndLoc,
-                         unsigned NumClauses, unsigned NumberOfExpressions)
-    : Stmt(SC), Kind(K), StartLoc(StartLoc), EndLoc(EndLoc),
-      Clauses(reinterpret_cast<OMPClause **>(static_cast<T *>(this) + 1),
-              NumClauses),
-      StmtAndExpressions(reinterpret_cast<Stmt **>(Clauses.end()),
-                         NumberOfExpressions) { }
+                         unsigned NumClauses, unsigned NumChildren)
+      : Stmt(SC), Kind(K), StartLoc(std::move(StartLoc)),
+        EndLoc(std::move(EndLoc)), NumClauses(NumClauses),
+        NumChildren(NumChildren),
+        ClausesOffset(llvm::RoundUpToAlignment(sizeof(T),
+                                               llvm::alignOf<OMPClause *>())) {}
 
   /// \brief Sets the list of variables for this clause.
   ///
@@ -415,10 +84,50 @@
   /// /param S Associated statement.
   ///
   void setAssociatedStmt(Stmt *S) {
-    StmtAndExpressions[0] = S;
+    assert(hasAssociatedStmt() && "no associated statement.");
+    *child_begin() = S;
   }
 
 public:
+  /// \brief Iterates over a filtered subrange of clauses applied to a
+  /// directive.
+  ///
+  /// This iterator visits only those declarations that meet some run-time
+  /// criteria.
+  template <class FilterPredicate> class filtered_clause_iterator {
+    ArrayRef<OMPClause *>::const_iterator Current;
+    ArrayRef<OMPClause *>::const_iterator End;
+    FilterPredicate Pred;
+    void SkipToNextClause() {
+      while (Current != End && !Pred(*Current))
+        ++Current;
+    }
+
+  public:
+    typedef const OMPClause *value_type;
+    filtered_clause_iterator() : Current(), End() {}
+    filtered_clause_iterator(ArrayRef<OMPClause *> Arr, FilterPredicate Pred)
+        : Current(Arr.begin()), End(Arr.end()), Pred(Pred) {
+      SkipToNextClause();
+    }
+    value_type operator*() const { return *Current; }
+    value_type operator->() const { return *Current; }
+    filtered_clause_iterator &operator++() {
+      ++Current;
+      SkipToNextClause();
+      return *this;
+    }
+
+    filtered_clause_iterator operator++(int) {
+      filtered_clause_iterator tmp(*this);
+      ++(*this);
+      return tmp;
+    }
+
+    bool operator!() { return Current == End; }
+    operator bool() { return Current != End; }
+  };
+
   /// \brief Returns starting location of directive kind.
   SourceLocation getLocStart() const { return StartLoc; }
   /// \brief Returns ending location of directive.
@@ -436,20 +145,21 @@
   void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
 
   /// \brief Get number of clauses.
-  unsigned getNumClauses() const { return Clauses.size(); }
+  unsigned getNumClauses() const { return NumClauses; }
 
   /// \brief Returns specified clause.
   ///
   /// \param i Number of clause.
   ///
-  OMPClause *getClause(unsigned i) const {
-    assert(i < Clauses.size() && "index out of bound!");
-    return Clauses[i];
-  }
+  OMPClause *getClause(unsigned i) const { return clauses()[i]; }
+
+  /// \brief Returns true if directive has associated statement.
+  bool hasAssociatedStmt() const { return NumChildren > 0; }
 
   /// \brief Returns statement associated with the directive.
   Stmt *getAssociatedStmt() const {
-    return StmtAndExpressions[0];
+    assert(hasAssociatedStmt() && "no associated statement.");
+    return const_cast<Stmt *>(*child_begin());
   }
 
   OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
@@ -460,12 +170,17 @@
   }
 
   child_range children() {
-    return child_range(StmtAndExpressions.begin(), StmtAndExpressions.end());
+    if (!hasAssociatedStmt())
+      return child_range();
+    Stmt **ChildStorage = reinterpret_cast<Stmt **>(getClauses().end());
+    return child_range(ChildStorage, ChildStorage + NumChildren);
   }
 
-  ArrayRef<OMPClause *> clauses() { return Clauses; }
+  ArrayRef<OMPClause *> clauses() { return getClauses(); }
 
-  ArrayRef<OMPClause *> clauses() const { return Clauses; }
+  ArrayRef<OMPClause *> clauses() const {
+    return const_cast<OMPExecutableDirective *>(this)->getClauses();
+  }
 };
 
 /// \brief This represents '#pragma omp parallel' directive.
@@ -484,17 +199,19 @@
   /// \param EndLoc Ending Location of the directive.
   ///
   OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
-                       unsigned N)
-    : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
-                             StartLoc, EndLoc, N, 1) { }
+                       unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
+                               StartLoc, EndLoc, NumClauses, 1) {}
 
   /// \brief Build an empty directive.
   ///
-  /// \param N Number of clauses.
+  /// \param NumClauses Number of clauses.
   ///
-  explicit OMPParallelDirective(unsigned N)
-    : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
-                             SourceLocation(), SourceLocation(), N, 1) { }
+  explicit OMPParallelDirective(unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
+                               SourceLocation(), SourceLocation(), NumClauses,
+                               1) {}
+
 public:
   /// \brief Creates directive with a list of \a Clauses.
   ///
@@ -504,25 +221,813 @@
   /// \param Clauses List of clauses.
   /// \param AssociatedStmt Statement associated with the directive.
   ///
-  static OMPParallelDirective *Create(const ASTContext &C,
-                                      SourceLocation StartLoc,
-                                      SourceLocation EndLoc,
-                                      ArrayRef<OMPClause *> Clauses,
-                                      Stmt *AssociatedStmt);
+  static OMPParallelDirective *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
 
   /// \brief Creates an empty directive with the place for \a N clauses.
   ///
   /// \param C AST context.
-  /// \param N The number of clauses.
+  /// \param NumClauses Number of clauses.
   ///
-  static OMPParallelDirective *CreateEmpty(const ASTContext &C, unsigned N,
-                                           EmptyShell);
+  static OMPParallelDirective *CreateEmpty(const ASTContext &C,
+                                           unsigned NumClauses, EmptyShell);
 
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == OMPParallelDirectiveClass;
   }
 };
 
-}  // end namespace clang
+/// \brief This represents '#pragma omp simd' directive.
+///
+/// \code
+/// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d)
+/// \endcode
+/// In this example directive '#pragma omp simd' has clauses 'private'
+/// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
+/// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
+///
+class OMPSimdDirective : public OMPExecutableDirective {
+  friend class ASTStmtReader;
+  /// \brief Number of collapsed loops as specified by 'collapse' clause.
+  unsigned CollapsedNum;
+  /// \brief Build directive with the given start and end location.
+  ///
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending location of the directive.
+  /// \param CollapsedNum Number of collapsed nested loops.
+  /// \param NumClauses Number of clauses.
+  ///
+  OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+                   unsigned CollapsedNum, unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPSimdDirectiveClass, OMPD_simd, StartLoc,
+                               EndLoc, NumClauses, 1),
+        CollapsedNum(CollapsedNum) {}
+
+  /// \brief Build an empty directive.
+  ///
+  /// \param CollapsedNum Number of collapsed nested loops.
+  /// \param NumClauses Number of clauses.
+  ///
+  explicit OMPSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPSimdDirectiveClass, OMPD_simd,
+                               SourceLocation(), SourceLocation(), NumClauses,
+                               1),
+        CollapsedNum(CollapsedNum) {}
+
+public:
+  /// \brief Creates directive with a list of \a Clauses.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  /// \param CollapsedNum Number of collapsed loops.
+  /// \param Clauses List of clauses.
+  /// \param AssociatedStmt Statement, associated with the directive.
+  ///
+  static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc,
+                                  SourceLocation EndLoc, unsigned CollapsedNum,
+                                  ArrayRef<OMPClause *> Clauses,
+                                  Stmt *AssociatedStmt);
+
+  /// \brief Creates an empty directive with the place
+  /// for \a NumClauses clauses.
+  ///
+  /// \param C AST context.
+  /// \param CollapsedNum Number of collapsed nested loops.
+  /// \param NumClauses Number of clauses.
+  ///
+  static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
+                                       unsigned CollapsedNum, EmptyShell);
+
+  unsigned getCollapsedNumber() const { return CollapsedNum; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPSimdDirectiveClass;
+  }
+};
+
+/// \brief This represents '#pragma omp for' directive.
+///
+/// \code
+/// #pragma omp for private(a,b) reduction(+:c,d)
+/// \endcode
+/// In this example directive '#pragma omp for' has clauses 'private' with the
+/// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c'
+/// and 'd'.
+///
+class OMPForDirective : public OMPExecutableDirective {
+  friend class ASTStmtReader;
+  /// \brief Number of collapsed loops as specified by 'collapse' clause.
+  unsigned CollapsedNum;
+  /// \brief Build directive with the given start and end location.
+  ///
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending location of the directive.
+  /// \param CollapsedNum Number of collapsed nested loops.
+  /// \param NumClauses Number of clauses.
+  ///
+  OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+                  unsigned CollapsedNum, unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPForDirectiveClass, OMPD_for, StartLoc,
+                               EndLoc, NumClauses, 1),
+        CollapsedNum(CollapsedNum) {}
+
+  /// \brief Build an empty directive.
+  ///
+  /// \param CollapsedNum Number of collapsed nested loops.
+  /// \param NumClauses Number of clauses.
+  ///
+  explicit OMPForDirective(unsigned CollapsedNum, unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPForDirectiveClass, OMPD_for,
+                               SourceLocation(), SourceLocation(), NumClauses,
+                               1),
+        CollapsedNum(CollapsedNum) {}
+
+public:
+  /// \brief Creates directive with a list of \a Clauses.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  /// \param CollapsedNum Number of collapsed loops.
+  /// \param Clauses List of clauses.
+  /// \param AssociatedStmt Statement, associated with the directive.
+  ///
+  static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc,
+                                 SourceLocation EndLoc, unsigned CollapsedNum,
+                                 ArrayRef<OMPClause *> Clauses,
+                                 Stmt *AssociatedStmt);
+
+  /// \brief Creates an empty directive with the place
+  /// for \a NumClauses clauses.
+  ///
+  /// \param C AST context.
+  /// \param CollapsedNum Number of collapsed nested loops.
+  /// \param NumClauses Number of clauses.
+  ///
+  static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
+                                      unsigned CollapsedNum, EmptyShell);
+
+  unsigned getCollapsedNumber() const { return CollapsedNum; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPForDirectiveClass;
+  }
+};
+
+/// \brief This represents '#pragma omp sections' directive.
+///
+/// \code
+/// #pragma omp sections private(a,b) reduction(+:c,d)
+/// \endcode
+/// In this example directive '#pragma omp sections' has clauses 'private' with
+/// the variables 'a' and 'b' and 'reduction' with operator '+' and variables
+/// 'c' and 'd'.
+///
+class OMPSectionsDirective : public OMPExecutableDirective {
+  friend class ASTStmtReader;
+  /// \brief Build directive with the given start and end location.
+  ///
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending location of the directive.
+  /// \param NumClauses Number of clauses.
+  ///
+  OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+                       unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
+                               StartLoc, EndLoc, NumClauses, 1) {}
+
+  /// \brief Build an empty directive.
+  ///
+  /// \param NumClauses Number of clauses.
+  ///
+  explicit OMPSectionsDirective(unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
+                               SourceLocation(), SourceLocation(), NumClauses,
+                               1) {}
+
+public:
+  /// \brief Creates directive with a list of \a Clauses.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  /// \param Clauses List of clauses.
+  /// \param AssociatedStmt Statement, associated with the directive.
+  ///
+  static OMPSectionsDirective *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
+
+  /// \brief Creates an empty directive with the place for \a NumClauses
+  /// clauses.
+  ///
+  /// \param C AST context.
+  /// \param NumClauses Number of clauses.
+  ///
+  static OMPSectionsDirective *CreateEmpty(const ASTContext &C,
+                                           unsigned NumClauses, EmptyShell);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPSectionsDirectiveClass;
+  }
+};
+
+/// \brief This represents '#pragma omp section' directive.
+///
+/// \code
+/// #pragma omp section
+/// \endcode
+///
+class OMPSectionDirective : public OMPExecutableDirective {
+  friend class ASTStmtReader;
+  /// \brief Build directive with the given start and end location.
+  ///
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending location of the directive.
+  ///
+  OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc)
+      : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
+                               StartLoc, EndLoc, 0, 1) {}
+
+  /// \brief Build an empty directive.
+  ///
+  explicit OMPSectionDirective()
+      : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
+                               SourceLocation(), SourceLocation(), 0, 1) {}
+
+public:
+  /// \brief Creates directive.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  /// \param AssociatedStmt Statement, associated with the directive.
+  ///
+  static OMPSectionDirective *Create(const ASTContext &C,
+                                     SourceLocation StartLoc,
+                                     SourceLocation EndLoc,
+                                     Stmt *AssociatedStmt);
+
+  /// \brief Creates an empty directive.
+  ///
+  /// \param C AST context.
+  ///
+  static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPSectionDirectiveClass;
+  }
+};
+
+/// \brief This represents '#pragma omp single' directive.
+///
+/// \code
+/// #pragma omp single private(a,b) copyprivate(c,d)
+/// \endcode
+/// In this example directive '#pragma omp single' has clauses 'private' with
+/// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'.
+///
+class OMPSingleDirective : public OMPExecutableDirective {
+  friend class ASTStmtReader;
+  /// \brief Build directive with the given start and end location.
+  ///
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending location of the directive.
+  /// \param NumClauses Number of clauses.
+  ///
+  OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+                     unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
+                               StartLoc, EndLoc, NumClauses, 1) {}
+
+  /// \brief Build an empty directive.
+  ///
+  /// \param NumClauses Number of clauses.
+  ///
+  explicit OMPSingleDirective(unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
+                               SourceLocation(), SourceLocation(), NumClauses,
+                               1) {}
+
+public:
+  /// \brief Creates directive with a list of \a Clauses.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  /// \param Clauses List of clauses.
+  /// \param AssociatedStmt Statement, associated with the directive.
+  ///
+  static OMPSingleDirective *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
+
+  /// \brief Creates an empty directive with the place for \a NumClauses
+  /// clauses.
+  ///
+  /// \param C AST context.
+  /// \param NumClauses Number of clauses.
+  ///
+  static OMPSingleDirective *CreateEmpty(const ASTContext &C,
+                                         unsigned NumClauses, EmptyShell);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPSingleDirectiveClass;
+  }
+};
+
+/// \brief This represents '#pragma omp master' directive.
+///
+/// \code
+/// #pragma omp master
+/// \endcode
+///
+class OMPMasterDirective : public OMPExecutableDirective {
+  friend class ASTStmtReader;
+  /// \brief Build directive with the given start and end location.
+  ///
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending location of the directive.
+  ///
+  OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc)
+      : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
+                               StartLoc, EndLoc, 0, 1) {}
+
+  /// \brief Build an empty directive.
+  ///
+  explicit OMPMasterDirective()
+      : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
+                               SourceLocation(), SourceLocation(), 0, 1) {}
+
+public:
+  /// \brief Creates directive.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  /// \param AssociatedStmt Statement, associated with the directive.
+  ///
+  static OMPMasterDirective *Create(const ASTContext &C,
+                                    SourceLocation StartLoc,
+                                    SourceLocation EndLoc,
+                                    Stmt *AssociatedStmt);
+
+  /// \brief Creates an empty directive.
+  ///
+  /// \param C AST context.
+  ///
+  static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPMasterDirectiveClass;
+  }
+};
+
+/// \brief This represents '#pragma omp critical' directive.
+///
+/// \code
+/// #pragma omp critical
+/// \endcode
+///
+class OMPCriticalDirective : public OMPExecutableDirective {
+  friend class ASTStmtReader;
+  /// \brief Name of the directive.
+  DeclarationNameInfo DirName;
+  /// \brief Build directive with the given start and end location.
+  ///
+  /// \param Name Name of the directive.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending location of the directive.
+  ///
+  OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc,
+                       SourceLocation EndLoc)
+      : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
+                               StartLoc, EndLoc, 0, 1),
+        DirName(Name) {}
+
+  /// \brief Build an empty directive.
+  ///
+  explicit OMPCriticalDirective()
+      : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
+                               SourceLocation(), SourceLocation(), 0, 1),
+        DirName() {}
+
+  /// \brief Set name of the directive.
+  ///
+  /// \param Name Name of the directive.
+  ///
+  void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; }
+
+public:
+  /// \brief Creates directive.
+  ///
+  /// \param C AST context.
+  /// \param Name Name of the directive.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  /// \param AssociatedStmt Statement, associated with the directive.
+  ///
+  static OMPCriticalDirective *
+  Create(const ASTContext &C, const DeclarationNameInfo &Name,
+         SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt);
+
+  /// \brief Creates an empty directive.
+  ///
+  /// \param C AST context.
+  ///
+  static OMPCriticalDirective *CreateEmpty(const ASTContext &C, EmptyShell);
+
+  /// \brief Return name of the directive.
+  ///
+  DeclarationNameInfo getDirectiveName() const { return DirName; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPCriticalDirectiveClass;
+  }
+};
+
+/// \brief This represents '#pragma omp parallel for' directive.
+///
+/// \code
+/// #pragma omp parallel for private(a,b) reduction(+:c,d)
+/// \endcode
+/// In this example directive '#pragma omp parallel for' has clauses 'private'
+/// with the variables 'a' and 'b' and 'reduction' with operator '+' and
+/// variables 'c' and 'd'.
+///
+class OMPParallelForDirective : public OMPExecutableDirective {
+  friend class ASTStmtReader;
+  /// \brief Number of collapsed loops as specified by 'collapse' clause.
+  unsigned CollapsedNum;
+  /// \brief Build directive with the given start and end location.
+  ///
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending location of the directive.
+  /// \param CollapsedNum Number of collapsed nested loops.
+  /// \param NumClauses Number of clauses.
+  ///
+  OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+                          unsigned CollapsedNum, unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPParallelForDirectiveClass,
+                               OMPD_parallel_for, StartLoc, EndLoc, NumClauses,
+                               1),
+        CollapsedNum(CollapsedNum) {}
+
+  /// \brief Build an empty directive.
+  ///
+  /// \param CollapsedNum Number of collapsed nested loops.
+  /// \param NumClauses Number of clauses.
+  ///
+  explicit OMPParallelForDirective(unsigned CollapsedNum, unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPParallelForDirectiveClass,
+                               OMPD_parallel_for, SourceLocation(),
+                               SourceLocation(), NumClauses, 1),
+        CollapsedNum(CollapsedNum) {}
+
+public:
+  /// \brief Creates directive with a list of \a Clauses.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  /// \param CollapsedNum Number of collapsed loops.
+  /// \param Clauses List of clauses.
+  /// \param AssociatedStmt Statement, associated with the directive.
+  ///
+  static OMPParallelForDirective *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
+         Stmt *AssociatedStmt);
+
+  /// \brief Creates an empty directive with the place
+  /// for \a NumClauses clauses.
+  ///
+  /// \param C AST context.
+  /// \param CollapsedNum Number of collapsed nested loops.
+  /// \param NumClauses Number of clauses.
+  ///
+  static OMPParallelForDirective *CreateEmpty(const ASTContext &C,
+                                              unsigned NumClauses,
+                                              unsigned CollapsedNum,
+                                              EmptyShell);
+
+  unsigned getCollapsedNumber() const { return CollapsedNum; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPParallelForDirectiveClass;
+  }
+};
+
+/// \brief This represents '#pragma omp parallel sections' directive.
+///
+/// \code
+/// #pragma omp parallel sections private(a,b) reduction(+:c,d)
+/// \endcode
+/// In this example directive '#pragma omp parallel sections' has clauses
+/// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
+/// and variables 'c' and 'd'.
+///
+class OMPParallelSectionsDirective : public OMPExecutableDirective {
+  friend class ASTStmtReader;
+  /// \brief Build directive with the given start and end location.
+  ///
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending location of the directive.
+  /// \param NumClauses Number of clauses.
+  ///
+  OMPParallelSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+                               unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
+                               OMPD_parallel_sections, StartLoc, EndLoc,
+                               NumClauses, 1) {}
+
+  /// \brief Build an empty directive.
+  ///
+  /// \param NumClauses Number of clauses.
+  ///
+  explicit OMPParallelSectionsDirective(unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
+                               OMPD_parallel_sections, SourceLocation(),
+                               SourceLocation(), NumClauses, 1) {}
+
+public:
+  /// \brief Creates directive with a list of \a Clauses.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  /// \param Clauses List of clauses.
+  /// \param AssociatedStmt Statement, associated with the directive.
+  ///
+  static OMPParallelSectionsDirective *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
+
+  /// \brief Creates an empty directive with the place for \a NumClauses
+  /// clauses.
+  ///
+  /// \param C AST context.
+  /// \param NumClauses Number of clauses.
+  ///
+  static OMPParallelSectionsDirective *
+  CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPParallelSectionsDirectiveClass;
+  }
+};
+
+/// \brief This represents '#pragma omp task' directive.
+///
+/// \code
+/// #pragma omp task private(a,b) final(d)
+/// \endcode
+/// In this example directive '#pragma omp task' has clauses 'private' with the
+/// variables 'a' and 'b' and 'final' with condition 'd'.
+///
+class OMPTaskDirective : public OMPExecutableDirective {
+  friend class ASTStmtReader;
+  /// \brief Build directive with the given start and end location.
+  ///
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending location of the directive.
+  /// \param NumClauses Number of clauses.
+  ///
+  OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+                   unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task, StartLoc,
+                               EndLoc, NumClauses, 1) {}
+
+  /// \brief Build an empty directive.
+  ///
+  /// \param NumClauses Number of clauses.
+  ///
+  explicit OMPTaskDirective(unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task,
+                               SourceLocation(), SourceLocation(), NumClauses,
+                               1) {}
+
+public:
+  /// \brief Creates directive with a list of \a Clauses.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  /// \param Clauses List of clauses.
+  /// \param AssociatedStmt Statement, associated with the directive.
+  ///
+  static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc,
+                                  SourceLocation EndLoc,
+                                  ArrayRef<OMPClause *> Clauses,
+                                  Stmt *AssociatedStmt);
+
+  /// \brief Creates an empty directive with the place for \a NumClauses
+  /// clauses.
+  ///
+  /// \param C AST context.
+  /// \param NumClauses Number of clauses.
+  ///
+  static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
+                                       EmptyShell);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPTaskDirectiveClass;
+  }
+};
+
+/// \brief This represents '#pragma omp taskyield' directive.
+///
+/// \code
+/// #pragma omp taskyield
+/// \endcode
+///
+class OMPTaskyieldDirective : public OMPExecutableDirective {
+  friend class ASTStmtReader;
+  /// \brief Build directive with the given start and end location.
+  ///
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending location of the directive.
+  ///
+  OMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
+      : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
+                               StartLoc, EndLoc, 0, 0) {}
+
+  /// \brief Build an empty directive.
+  ///
+  explicit OMPTaskyieldDirective()
+      : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
+                               SourceLocation(), SourceLocation(), 0, 0) {}
+
+public:
+  /// \brief Creates directive.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  ///
+  static OMPTaskyieldDirective *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
+
+  /// \brief Creates an empty directive.
+  ///
+  /// \param C AST context.
+  ///
+  static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPTaskyieldDirectiveClass;
+  }
+};
+
+/// \brief This represents '#pragma omp barrier' directive.
+///
+/// \code
+/// #pragma omp barrier
+/// \endcode
+///
+class OMPBarrierDirective : public OMPExecutableDirective {
+  friend class ASTStmtReader;
+  /// \brief Build directive with the given start and end location.
+  ///
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending location of the directive.
+  ///
+  OMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
+      : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
+                               StartLoc, EndLoc, 0, 0) {}
+
+  /// \brief Build an empty directive.
+  ///
+  explicit OMPBarrierDirective()
+      : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
+                               SourceLocation(), SourceLocation(), 0, 0) {}
+
+public:
+  /// \brief Creates directive.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  ///
+  static OMPBarrierDirective *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
+
+  /// \brief Creates an empty directive.
+  ///
+  /// \param C AST context.
+  ///
+  static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPBarrierDirectiveClass;
+  }
+};
+
+/// \brief This represents '#pragma omp taskwait' directive.
+///
+/// \code
+/// #pragma omp taskwait
+/// \endcode
+///
+class OMPTaskwaitDirective : public OMPExecutableDirective {
+  friend class ASTStmtReader;
+  /// \brief Build directive with the given start and end location.
+  ///
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending location of the directive.
+  ///
+  OMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc)
+      : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
+                               StartLoc, EndLoc, 0, 0) {}
+
+  /// \brief Build an empty directive.
+  ///
+  explicit OMPTaskwaitDirective()
+      : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
+                               SourceLocation(), SourceLocation(), 0, 0) {}
+
+public:
+  /// \brief Creates directive.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  ///
+  static OMPTaskwaitDirective *
+  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
+
+  /// \brief Creates an empty directive.
+  ///
+  /// \param C AST context.
+  ///
+  static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C, EmptyShell);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPTaskwaitDirectiveClass;
+  }
+};
+
+/// \brief This represents '#pragma omp flush' directive.
+///
+/// \code
+/// #pragma omp flush(a,b)
+/// \endcode
+/// In this example directive '#pragma omp flush' has 2 arguments- variables 'a'
+/// and 'b'.
+/// 'omp flush' directive does not have clauses but have an optional list of
+/// variables to flush. This list of variables is stored within some fake clause
+/// FlushClause.
+class OMPFlushDirective : public OMPExecutableDirective {
+  friend class ASTStmtReader;
+  /// \brief Build directive with the given start and end location.
+  ///
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending location of the directive.
+  /// \param NumClauses Number of clauses.
+  ///
+  OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+                    unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
+                               StartLoc, EndLoc, NumClauses, 0) {}
+
+  /// \brief Build an empty directive.
+  ///
+  /// \param NumClauses Number of clauses.
+  ///
+  explicit OMPFlushDirective(unsigned NumClauses)
+      : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
+                               SourceLocation(), SourceLocation(), NumClauses,
+                               0) {}
+
+public:
+  /// \brief Creates directive with a list of \a Clauses.
+  ///
+  /// \param C AST context.
+  /// \param StartLoc Starting location of the directive kind.
+  /// \param EndLoc Ending Location of the directive.
+  /// \param Clauses List of clauses (only single OMPFlushClause clause is
+  /// allowed).
+  ///
+  static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc,
+                                   SourceLocation EndLoc,
+                                   ArrayRef<OMPClause *> Clauses);
+
+  /// \brief Creates an empty directive with the place for \a NumClauses
+  /// clauses.
+  ///
+  /// \param C AST context.
+  /// \param NumClauses Number of clauses.
+  ///
+  static OMPFlushDirective *CreateEmpty(const ASTContext &C,
+                                        unsigned NumClauses, EmptyShell);
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == OMPFlushDirectiveClass;
+  }
+};
+
+} // end namespace clang
 
 #endif
diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h
index 6c40eb1..1026a78 100644
--- a/include/clang/AST/TemplateBase.h
+++ b/include/clang/AST/TemplateBase.h
@@ -18,6 +18,7 @@
 #include "clang/AST/TemplateName.h"
 #include "clang/AST/Type.h"
 #include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/iterator_range.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -34,8 +35,7 @@
 class TypeSourceInfo;
 class ValueDecl;
 
-/// \brief Represents a template argument within a class template
-/// specialization.
+/// \brief Represents a template argument.
 class TemplateArgument {
 public:
   /// \brief The kind of template argument we're storing.
@@ -52,16 +52,19 @@
     /// was provided for a non-type template parameter.
     NullPtr,
     /// The template argument is an integral value stored in an llvm::APSInt
-    /// that was provided for an integral non-type template parameter. 
+    /// that was provided for an integral non-type template parameter.
     Integral,
-    /// The template argument is a template name that was provided for a 
+    /// The template argument is a template name that was provided for a
     /// template template parameter.
     Template,
-    /// The template argument is a pack expansion of a template name that was 
+    /// The template argument is a pack expansion of a template name that was
     /// provided for a template template parameter.
     TemplateExpansion,
-    /// The template argument is a value- or type-dependent expression or a
-    /// non-dependent __uuidof expression stored in an Expr*.
+    /// The template argument is an expression, and we've not resolved it to one
+    /// of the other forms yet, either because it's dependent or because we're
+    /// representing a non-canonical template argument (for instance, in a
+    /// TemplateSpecializationType). Also used to represent a non-dependent
+    /// __uuidof expression (a Microsoft extension).
     Expression,
     /// The template argument is actually a parameter pack. Arguments are stored
     /// in the Args struct.
@@ -202,7 +205,7 @@
   }
 
   static TemplateArgument getEmptyPack() {
-    return TemplateArgument((TemplateArgument*)0, 0);
+    return TemplateArgument((TemplateArgument*)nullptr, 0);
   }
 
   /// \brief Create a new template argument pack by copying the given set of
@@ -325,6 +328,12 @@
     return Args.Args + Args.NumArgs;
   }
 
+  /// \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());
+  }
+
   /// \brief The number of template arguments in the given template argument
   /// pack.
   unsigned pack_size() const {
@@ -333,9 +342,9 @@
   }
 
   /// \brief Return the array of arguments in this template argument pack.
-  llvm::ArrayRef<TemplateArgument> getPackAsArray() const {
+  ArrayRef<TemplateArgument> getPackAsArray() const {
     assert(getKind() == Pack);
-    return llvm::ArrayRef<TemplateArgument>(Args.Args, Args.NumArgs);
+    return ArrayRef<TemplateArgument>(Args.Args, Args.NumArgs);
   }
 
   /// \brief Determines whether two template arguments are superficially the
@@ -541,6 +550,10 @@
     return Arguments[I];
   }
 
+  TemplateArgumentLoc &operator[](unsigned I) {
+    return Arguments[I];
+  }
+
   void addArgument(const TemplateArgumentLoc &Loc) {
     Arguments.push_back(Loc);
   }
@@ -565,7 +578,8 @@
 
     /// Force ASTTemplateArgumentListInfo to the right alignment
     /// for the following array of TemplateArgumentLocs.
-    void *Aligner;
+    llvm::AlignedCharArray<
+        llvm::AlignOf<TemplateArgumentLoc>::Alignment, 1> Aligner;
   };
 
   /// \brief Retrieve the template arguments
diff --git a/include/clang/AST/TemplateName.h b/include/clang/AST/TemplateName.h
index 0b9d4c8..f3d23b9 100644
--- a/include/clang/AST/TemplateName.h
+++ b/include/clang/AST/TemplateName.h
@@ -15,7 +15,6 @@
 #define LLVM_CLANG_AST_TEMPLATENAME_H
 
 #include "clang/Basic/LLVM.h"
-#include "clang/Basic/OperatorKinds.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/PointerUnion.h"
 
@@ -25,13 +24,14 @@
 class DependentTemplateName;
 class DiagnosticBuilder;
 class IdentifierInfo;
+class NamedDecl;
 class NestedNameSpecifier;
+enum OverloadedOperatorKind : int;
 class OverloadedTemplateStorage;
 struct PrintingPolicy;
 class QualifiedTemplateName;
-class NamedDecl;
-class SubstTemplateTemplateParmStorage;
 class SubstTemplateTemplateParmPackStorage;
+class SubstTemplateTemplateParmStorage;
 class TemplateArgument;
 class TemplateDecl;
 class TemplateTemplateParmDecl;
@@ -71,19 +71,19 @@
   OverloadedTemplateStorage *getAsOverloadedStorage()  {
     return Bits.Kind == Overloaded
              ? reinterpret_cast<OverloadedTemplateStorage *>(this) 
-             : 0;
+             : nullptr;
   }
   
   SubstTemplateTemplateParmStorage *getAsSubstTemplateTemplateParm() {
     return Bits.Kind == SubstTemplateTemplateParm
              ? reinterpret_cast<SubstTemplateTemplateParmStorage *>(this)
-             : 0;
+             : nullptr;
   }
 
   SubstTemplateTemplateParmPackStorage *getAsSubstTemplateTemplateParmPack() {
     return Bits.Kind == SubstTemplateTemplateParmPack
              ? reinterpret_cast<SubstTemplateTemplateParmPackStorage *>(this)
-             : 0;
+             : nullptr;
   }
 };
   
@@ -243,7 +243,7 @@
                               Storage.dyn_cast<UncommonTemplateNameStorage *>())
       return Uncommon->getAsOverloadedStorage();
     
-    return 0;
+    return nullptr;
   }
 
   /// \brief Retrieve the substituted template template parameter, if 
@@ -256,7 +256,7 @@
           Storage.dyn_cast<UncommonTemplateNameStorage *>())
       return uncommon->getAsSubstTemplateTemplateParm();
     
-    return 0;
+    return nullptr;
   }
 
   /// \brief Retrieve the substituted template template parameter pack, if 
@@ -270,7 +270,7 @@
         Storage.dyn_cast<UncommonTemplateNameStorage *>())
       return Uncommon->getAsSubstTemplateTemplateParmPack();
     
-    return 0;
+    return nullptr;
   }
 
   /// \brief Retrieve the underlying qualified template name
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index fb829e4..09862e4f 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -18,20 +18,19 @@
 #include "clang/AST/TemplateName.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/ExceptionSpecificationType.h"
-#include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/Linkage.h"
 #include "clang/Basic/PartialDiagnostic.h"
 #include "clang/Basic/Specifiers.h"
 #include "clang/Basic/Visibility.h"
-#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/APInt.h"
 #include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/iterator_range.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/PointerIntPair.h"
 #include "llvm/ADT/PointerUnion.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/type_traits.h"
 
 namespace clang {
   enum {
@@ -500,14 +499,14 @@
   /// The local qualifiers.
   Qualifiers Quals;
 
-  SplitQualType() : Ty(0), Quals() {}
+  SplitQualType() : Ty(nullptr), Quals() {}
   SplitQualType(const Type *ty, Qualifiers qs) : Ty(ty), Quals(qs) {}
 
   SplitQualType getSingleStepDesugaredType() const; // end of this file
 
-  // Make llvm::tie work.
-  operator std::pair<const Type *,Qualifiers>() const {
-    return std::pair<const Type *,Qualifiers>(Ty, Quals);
+  // Make std::tie work.
+  std::pair<const Type *,Qualifiers> asPair() const {
+    return std::pair<const Type *, Qualifiers>(Ty, Quals);
   }
 
   friend bool operator==(SplitQualType a, SplitQualType b) {
@@ -1438,7 +1437,7 @@
   /// \brief Def If non-NULL, and the type refers to some kind of declaration
   /// that can be completed (such as a C struct, C++ class, or Objective-C
   /// class), will be set to the declaration.
-  bool isIncompleteType(NamedDecl **Def = 0) const;
+  bool isIncompleteType(NamedDecl **Def = nullptr) const;
 
   /// isIncompleteOrObjectType - Return true if this is an incomplete or object
   /// type, in other words, not a function type.
@@ -1797,7 +1796,7 @@
     return CanonicalType;
   }
   CanQualType getCanonicalTypeUnqualified() const; // in CanonicalType.h
-  LLVM_ATTRIBUTE_USED void dump() const;
+  void dump() const;
 
   friend class ASTReader;
   friend class ASTWriter;
@@ -1996,39 +1995,59 @@
   static bool classof(const Type *T) { return T->getTypeClass() == Pointer; }
 };
 
-/// \brief Represents a pointer type decayed from an array or function type.
-class DecayedType : public Type, public llvm::FoldingSetNode {
-  QualType OriginalType;
-  QualType DecayedPointer;
+/// \brief Represents a type which was implicitly adjusted by the semantic
+/// engine for arbitrary reasons.  For example, array and function types can
+/// decay, and function types can have their calling conventions adjusted.
+class AdjustedType : public Type, public llvm::FoldingSetNode {
+  QualType OriginalTy;
+  QualType AdjustedTy;
 
-  DecayedType(QualType OriginalType, QualType DecayedPointer,
-              QualType CanonicalPtr)
-      : Type(Decayed, CanonicalPtr, OriginalType->isDependentType(),
-             OriginalType->isInstantiationDependentType(),
-             OriginalType->isVariablyModifiedType(),
-             OriginalType->containsUnexpandedParameterPack()),
-        OriginalType(OriginalType), DecayedPointer(DecayedPointer) {
-    assert(isa<PointerType>(DecayedPointer));
+protected:
+  AdjustedType(TypeClass TC, QualType OriginalTy, QualType AdjustedTy,
+               QualType CanonicalPtr)
+      : Type(TC, CanonicalPtr, OriginalTy->isDependentType(),
+             OriginalTy->isInstantiationDependentType(),
+             OriginalTy->isVariablyModifiedType(),
+             OriginalTy->containsUnexpandedParameterPack()),
+        OriginalTy(OriginalTy), AdjustedTy(AdjustedTy) {}
+
+  friend class ASTContext;  // ASTContext creates these.
+
+public:
+  QualType getOriginalType() const { return OriginalTy; }
+  QualType getAdjustedType() const { return AdjustedTy; }
+
+  bool isSugared() const { return true; }
+  QualType desugar() const { return AdjustedTy; }
+
+  void Profile(llvm::FoldingSetNodeID &ID) {
+    Profile(ID, OriginalTy, AdjustedTy);
+  }
+  static void Profile(llvm::FoldingSetNodeID &ID, QualType Orig, QualType New) {
+    ID.AddPointer(Orig.getAsOpaquePtr());
+    ID.AddPointer(New.getAsOpaquePtr());
+  }
+
+  static bool classof(const Type *T) {
+    return T->getTypeClass() == Adjusted || T->getTypeClass() == Decayed;
+  }
+};
+
+/// \brief Represents a pointer type decayed from an array or function type.
+class DecayedType : public AdjustedType {
+
+  DecayedType(QualType OriginalType, QualType DecayedPtr, QualType CanonicalPtr)
+      : AdjustedType(Decayed, OriginalType, DecayedPtr, CanonicalPtr) {
+    assert(isa<PointerType>(getAdjustedType()));
   }
 
   friend class ASTContext;  // ASTContext creates these.
 
 public:
-  QualType getDecayedType() const { return DecayedPointer; }
-  QualType getOriginalType() const { return OriginalType; }
+  QualType getDecayedType() const { return getAdjustedType(); }
 
   QualType getPointeeType() const {
-    return cast<PointerType>(DecayedPointer)->getPointeeType();
-  }
-
-  bool isSugared() const { return true; }
-  QualType desugar() const { return DecayedPointer; }
-
-  void Profile(llvm::FoldingSetNodeID &ID) {
-    Profile(ID, OriginalType);
-  }
-  static void Profile(llvm::FoldingSetNodeID &ID, QualType OriginalType) {
-    ID.AddPointer(OriginalType.getAsOpaquePtr());
+    return cast<PointerType>(getDecayedType())->getPointeeType();
   }
 
   static bool classof(const Type *T) { return T->getTypeClass() == Decayed; }
@@ -2185,6 +2204,7 @@
   }
 
   const Type *getClass() const { return Class; }
+  CXXRecordDecl *getMostRecentCXXRecordDecl() const;
 
   bool isSugared() const { return false; }
   QualType desugar() const { return QualType(this, 0); }
@@ -2758,8 +2778,7 @@
   unsigned getTypeQuals() const { return FunctionTypeBits.TypeQuals; }
 
 public:
-
-  QualType getResultType() const { return ResultType; }
+  QualType getReturnType() const { return ResultType; }
 
   bool getHasRegParm() const { return getExtInfo().getHasRegParm(); }
   unsigned getRegParmType() const { return getExtInfo().getRegParm(); }
@@ -2776,7 +2795,7 @@
   /// \brief Determine the type of an expression that calls a function of
   /// this type.
   QualType getCallResultType(ASTContext &Context) const {
-    return getResultType().getNonLValueExprType(Context);
+    return getReturnType().getNonLValueExprType(Context);
   }
 
   static StringRef getNameForCallConv(CallingConv CC);
@@ -2805,7 +2824,7 @@
   QualType desugar() const { return QualType(this, 0); }
 
   void Profile(llvm::FoldingSetNodeID &ID) {
-    Profile(ID, getResultType(), getExtInfo());
+    Profile(ID, getReturnType(), getExtInfo());
   }
   static void Profile(llvm::FoldingSetNodeID &ID, QualType ResultType,
                       ExtInfo Info) {
@@ -2818,27 +2837,28 @@
   }
 };
 
-/// FunctionProtoType - Represents a prototype with argument type info, e.g.
+/// FunctionProtoType - Represents a prototype with parameter type info, e.g.
 /// 'int foo(int)' or 'int foo(void)'.  'void' is represented as having no
-/// arguments, not as having a single void argument. Such a type can have an
+/// parameters, not as having a single void parameter. Such a type can have an
 /// exception specification, but this specification is not part of the canonical
 /// type.
 class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
 public:
   /// ExtProtoInfo - Extra information about a function prototype.
   struct ExtProtoInfo {
-    ExtProtoInfo() :
-      Variadic(false), HasTrailingReturn(false), TypeQuals(0),
-      ExceptionSpecType(EST_None), RefQualifier(RQ_None),
-      NumExceptions(0), Exceptions(0), NoexceptExpr(0),
-      ExceptionSpecDecl(0), ExceptionSpecTemplate(0),
-      ConsumedArguments(0) {}
+    ExtProtoInfo()
+        : Variadic(false), HasTrailingReturn(false), TypeQuals(0),
+          ExceptionSpecType(EST_None), RefQualifier(RQ_None), NumExceptions(0),
+          Exceptions(nullptr), NoexceptExpr(nullptr),
+          ExceptionSpecDecl(nullptr), ExceptionSpecTemplate(nullptr),
+          ConsumedParameters(nullptr) {}
 
     ExtProtoInfo(CallingConv CC)
         : ExtInfo(CC), Variadic(false), HasTrailingReturn(false), TypeQuals(0),
           ExceptionSpecType(EST_None), RefQualifier(RQ_None), NumExceptions(0),
-          Exceptions(0), NoexceptExpr(0), ExceptionSpecDecl(0),
-          ExceptionSpecTemplate(0), ConsumedArguments(0) {}
+          Exceptions(nullptr), NoexceptExpr(nullptr),
+          ExceptionSpecDecl(nullptr), ExceptionSpecTemplate(nullptr),
+          ConsumedParameters(nullptr) {}
 
     FunctionType::ExtInfo ExtInfo;
     bool Variadic : 1;
@@ -2851,7 +2871,7 @@
     Expr *NoexceptExpr;
     FunctionDecl *ExceptionSpecDecl;
     FunctionDecl *ExceptionSpecTemplate;
-    const bool *ConsumedArguments;
+    const bool *ConsumedParameters;
   };
 
 private:
@@ -2866,11 +2886,11 @@
     return false;
   }
 
-  FunctionProtoType(QualType result, ArrayRef<QualType> args,
+  FunctionProtoType(QualType result, ArrayRef<QualType> params,
                     QualType canonical, const ExtProtoInfo &epi);
 
-  /// NumArgs - The number of arguments this function has, not counting '...'.
-  unsigned NumArgs : 15;
+  /// The number of parameters this function has, not counting '...'.
+  unsigned NumParams : 15;
 
   /// NumExceptions - The number of types in the exception spec, if any.
   unsigned NumExceptions : 9;
@@ -2878,8 +2898,8 @@
   /// ExceptionSpecType - The type of exception specification this function has.
   unsigned ExceptionSpecType : 3;
 
-  /// HasAnyConsumedArgs - Whether this function has any consumed arguments.
-  unsigned HasAnyConsumedArgs : 1;
+  /// HasAnyConsumedParams - Whether this function has any consumed parameters.
+  unsigned HasAnyConsumedParams : 1;
 
   /// Variadic - Whether the function is variadic.
   unsigned Variadic : 1;
@@ -2892,8 +2912,8 @@
   /// This is a value of type \c RefQualifierKind.
   unsigned RefQualifier : 2;
 
-  // ArgInfo - There is an variable size array after the class in memory that
-  // holds the argument types.
+  // ParamInfo - There is an variable size array after the class in memory that
+  // holds the parameter types.
 
   // Exceptions - There is another variable size array after ArgInfo that
   // holds the exception types.
@@ -2906,17 +2926,17 @@
   // instantiate this function type's exception specification, and the function
   // from which it should be instantiated.
 
-  // ConsumedArgs - A variable size array, following Exceptions
-  // and of length NumArgs, holding flags indicating which arguments
-  // are consumed.  This only appears if HasAnyConsumedArgs is true.
+  // ConsumedParameters - A variable size array, following Exceptions
+  // and of length NumParams, holding flags indicating which parameters
+  // are consumed.  This only appears if HasAnyConsumedParams is true.
 
   friend class ASTContext;  // ASTContext creates these.
 
-  const bool *getConsumedArgsBuffer() const {
-    assert(hasAnyConsumedArgs());
+  const bool *getConsumedParamsBuffer() const {
+    assert(hasAnyConsumedParams());
 
     // Find the end of the exceptions.
-    Expr * const *eh_end = reinterpret_cast<Expr * const *>(arg_type_end());
+    Expr *const *eh_end = reinterpret_cast<Expr *const *>(param_type_end());
     if (getExceptionSpecType() != EST_ComputedNoexcept)
       eh_end += NumExceptions;
     else
@@ -2926,13 +2946,13 @@
   }
 
 public:
-  unsigned getNumArgs() const { return NumArgs; }
-  QualType getArgType(unsigned i) const {
-    assert(i < NumArgs && "Invalid argument number!");
-    return arg_type_begin()[i];
+  unsigned getNumParams() const { return NumParams; }
+  QualType getParamType(unsigned i) const {
+    assert(i < NumParams && "invalid parameter index");
+    return param_type_begin()[i];
   }
-  ArrayRef<QualType> getArgTypes() const {
-    return ArrayRef<QualType>(arg_type_begin(), arg_type_end());
+  ArrayRef<QualType> getParamTypes() const {
+    return ArrayRef<QualType>(param_type_begin(), param_type_end());
   }
 
   ExtProtoInfo getExtProtoInfo() const {
@@ -2954,8 +2974,8 @@
     } else if (EPI.ExceptionSpecType == EST_Unevaluated) {
       EPI.ExceptionSpecDecl = getExceptionSpecDecl();
     }
-    if (hasAnyConsumedArgs())
-      EPI.ConsumedArguments = getConsumedArgsBuffer();
+    if (hasAnyConsumedParams())
+      EPI.ConsumedParameters = getConsumedParamsBuffer();
     return EPI;
   }
 
@@ -2992,9 +3012,9 @@
   }
   Expr *getNoexceptExpr() const {
     if (getExceptionSpecType() != EST_ComputedNoexcept)
-      return 0;
+      return nullptr;
     // NoexceptExpr sits where the arguments end.
-    return *reinterpret_cast<Expr *const *>(arg_type_end());
+    return *reinterpret_cast<Expr *const *>(param_type_end());
   }
   /// \brief If this function type has an exception specification which hasn't
   /// been determined yet (either because it has not been evaluated or because
@@ -3003,8 +3023,8 @@
   FunctionDecl *getExceptionSpecDecl() const {
     if (getExceptionSpecType() != EST_Uninstantiated &&
         getExceptionSpecType() != EST_Unevaluated)
-      return 0;
-    return reinterpret_cast<FunctionDecl * const *>(arg_type_end())[0];
+      return nullptr;
+    return reinterpret_cast<FunctionDecl *const *>(param_type_end())[0];
   }
   /// \brief If this function type has an uninstantiated exception
   /// specification, this is the function whose exception specification
@@ -3012,18 +3032,13 @@
   /// this type.
   FunctionDecl *getExceptionSpecTemplate() const {
     if (getExceptionSpecType() != EST_Uninstantiated)
-      return 0;
-    return reinterpret_cast<FunctionDecl * const *>(arg_type_end())[1];
+      return nullptr;
+    return reinterpret_cast<FunctionDecl *const *>(param_type_end())[1];
   }
-  bool isNothrow(const ASTContext &Ctx) const {
-    ExceptionSpecificationType EST = getExceptionSpecType();
-    assert(EST != EST_Unevaluated && EST != EST_Uninstantiated);
-    if (EST == EST_DynamicNone || EST == EST_BasicNoexcept)
-      return true;
-    if (EST != EST_ComputedNoexcept)
-      return false;
-    return getNoexceptSpec(Ctx) == NR_Nothrow;
-  }
+  /// \brief Determine whether this function type has a non-throwing exception
+  /// specification. If this depends on template arguments, returns
+  /// \c ResultIfDependent.
+  bool isNothrow(const ASTContext &Ctx, bool ResultIfDependent = false) const;
 
   bool isVariadic() const { return Variadic; }
 
@@ -3045,16 +3060,28 @@
     return static_cast<RefQualifierKind>(RefQualifier);
   }
 
-  typedef const QualType *arg_type_iterator;
-  arg_type_iterator arg_type_begin() const {
+  typedef const QualType *param_type_iterator;
+  typedef llvm::iterator_range<param_type_iterator> param_type_range;
+
+  param_type_range param_types() const {
+    return param_type_range(param_type_begin(), param_type_end());
+  }
+  param_type_iterator param_type_begin() const {
     return reinterpret_cast<const QualType *>(this+1);
   }
-  arg_type_iterator arg_type_end() const { return arg_type_begin()+NumArgs; }
+  param_type_iterator param_type_end() const {
+    return param_type_begin() + NumParams;
+  }
 
   typedef const QualType *exception_iterator;
+  typedef llvm::iterator_range<exception_iterator> exception_range;
+
+  exception_range exceptions() const {
+    return exception_range(exception_begin(), exception_end());
+  }
   exception_iterator exception_begin() const {
     // exceptions begin where arguments end
-    return arg_type_end();
+    return param_type_end();
   }
   exception_iterator exception_end() const {
     if (getExceptionSpecType() != EST_Dynamic)
@@ -3062,13 +3089,11 @@
     return exception_begin() + NumExceptions;
   }
 
-  bool hasAnyConsumedArgs() const {
-    return HasAnyConsumedArgs;
-  }
-  bool isArgConsumed(unsigned I) const {
-    assert(I < getNumArgs() && "argument index out of range!");
-    if (hasAnyConsumedArgs())
-      return getConsumedArgsBuffer()[I];
+  bool hasAnyConsumedParams() const { return HasAnyConsumedParams; }
+  bool isParamConsumed(unsigned I) const {
+    assert(I < getNumParams() && "parameter index out of range");
+    if (hasAnyConsumedParams())
+      return getConsumedParamsBuffer()[I];
     return false;
   }
 
@@ -3084,7 +3109,7 @@
 
   void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx);
   static void Profile(llvm::FoldingSetNodeID &ID, QualType Result,
-                      arg_type_iterator ArgTys, unsigned NumArgs,
+                      param_type_iterator ArgTys, unsigned NumArgs,
                       const ExtProtoInfo &EPI, const ASTContext &Context);
 };
 
@@ -3495,7 +3520,7 @@
   bool isParameterPack() const { return getCanTTPTInfo().ParameterPack; }
 
   TemplateTypeParmDecl *getDecl() const {
-    return isCanonicalUnqualified() ? 0 : TTPDecl;
+    return isCanonicalUnqualified() ? nullptr : TTPDecl;
   }
 
   IdentifierInfo *getIdentifier() const;
@@ -3956,9 +3981,9 @@
 
   static bool KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword);
 
-  static const char *getKeywordName(ElaboratedTypeKeyword Keyword);
+  static StringRef getKeywordName(ElaboratedTypeKeyword Keyword);
 
-  static const char *getTagTypeKindName(TagTypeKind Kind) {
+  static StringRef getTagTypeKindName(TagTypeKind Kind) {
     return getKeywordName(getKeywordForTagTypeKind(Kind));
   }
 
@@ -3990,7 +4015,7 @@
                       NamedType->isVariablyModifiedType(),
                       NamedType->containsUnexpandedParameterPack()),
       NNS(NNS), NamedType(NamedType) {
-    assert(!(Keyword == ETK_None && NNS == 0) &&
+    assert(!(Keyword == ETK_None && NNS == nullptr) &&
            "ElaboratedType cannot have elaborated type keyword "
            "and name qualifier both null.");
   }
@@ -4032,11 +4057,14 @@
 /// dependent.
 ///
 /// DependentNameType represents a class of dependent types that involve a
-/// dependent nested-name-specifier (e.g., "T::") followed by a (dependent)
+/// possibly dependent nested-name-specifier (e.g., "T::") followed by a
 /// name of a type. The DependentNameType may start with a "typename" (for a
 /// typename-specifier), "class", "struct", "union", or "enum" (for a
 /// dependent elaborated-type-specifier), or nothing (in contexts where we
 /// know that we must be referring to a type, e.g., in a base class specifier).
+/// Typically the nested-name-specifier is dependent, but in MSVC compatibility
+/// mode, this type is used with non-dependent names to delay name lookup until
+/// instantiation.
 class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode {
 
   /// \brief The nested name specifier containing the qualifier.
@@ -4051,10 +4079,7 @@
                       /*InstantiationDependent=*/true,
                       /*VariablyModified=*/false,
                       NNS->containsUnexpandedParameterPack()),
-      NNS(NNS), Name(Name) {
-    assert(NNS->isDependent() &&
-           "DependentNameType requires a dependent nested-name-specifier");
-  }
+      NNS(NNS), Name(Name) {}
 
   friend class ASTContext;  // ASTContext creates these
 
@@ -4199,7 +4224,7 @@
                     Optional<unsigned> NumExpansions)
     : Type(PackExpansion, Canon, /*Dependent=*/Pattern->isDependentType(),
            /*InstantiationDependent=*/true,
-           /*VariableModified=*/Pattern->isVariablyModifiedType(),
+           /*VariablyModified=*/Pattern->isVariablyModifiedType(),
            /*ContainsUnexpandedParameterPack=*/false),
       Pattern(Pattern),
       NumExpansions(NumExpansions? *NumExpansions + 1: 0) { }
@@ -4326,7 +4351,9 @@
   ObjCInterfaceDecl *getInterface() const;
 
   typedef ObjCProtocolDecl * const *qual_iterator;
+  typedef llvm::iterator_range<qual_iterator> qual_range;
 
+  qual_range quals() const { return qual_range(qual_begin(), qual_end()); }
   qual_iterator qual_begin() const { return getProtocolStorage(); }
   qual_iterator qual_end() const { return qual_begin() + getNumProtocols(); }
 
@@ -4430,7 +4457,7 @@
   if (const ObjCInterfaceType *T =
         getBaseType()->getAs<ObjCInterfaceType>())
     return T->getDecl();
-  return 0;
+  return nullptr;
 }
 
 /// ObjCObjectPointerType - Used to represent a pointer to an
@@ -4528,7 +4555,9 @@
   /// for convenience.  This will always iterate over the full set of
   /// protocols on a type, not just those provided directly.
   typedef ObjCObjectType::qual_iterator qual_iterator;
+  typedef llvm::iterator_range<qual_iterator> qual_range;
 
+  qual_range quals() const { return qual_range(qual_begin(), qual_end()); }
   qual_iterator qual_begin() const {
     return getObjectType()->qual_begin();
   }
@@ -4633,7 +4662,7 @@
 }
 
 inline const Type *QualType::getTypePtrOrNull() const {
-  return (isNull() ? 0 : getCommonPtr()->BaseType);
+  return (isNull() ? nullptr : getCommonPtr()->BaseType);
 }
 
 inline SplitQualType QualType::split() const {
@@ -5022,7 +5051,7 @@
   if (const BuiltinType *BT = dyn_cast<BuiltinType>(this))
     if (BT->isPlaceholderType())
       return BT;
-  return 0;
+  return nullptr;
 }
 
 inline bool Type::isSpecificPlaceholderType(unsigned K) const {
@@ -5159,10 +5188,9 @@
 
 // Helper class template that is used by Type::getAs to ensure that one does
 // not try to look through a qualified type to get to an array type.
-template<typename T,
-         bool isArrayType = (llvm::is_same<T, ArrayType>::value ||
-                             llvm::is_base_of<ArrayType, T>::value)>
-struct ArrayType_cannot_be_used_with_getAs { };
+template <typename T, bool isArrayType = (std::is_same<T, ArrayType>::value ||
+                                          std::is_base_of<ArrayType, T>::value)>
+struct ArrayType_cannot_be_used_with_getAs {};
 
 template<typename T>
 struct ArrayType_cannot_be_used_with_getAs<T, true>;
@@ -5178,7 +5206,7 @@
 
   // If the canonical form of this type isn't the right kind, reject it.
   if (!isa<T>(CanonicalType))
-    return 0;
+    return nullptr;
 
   // If this is a typedef for the type, strip the typedef off without
   // losing all typedef information.
@@ -5192,7 +5220,7 @@
 
   // If the canonical form of this type isn't the right kind, reject it.
   if (!isa<ArrayType>(CanonicalType))
-    return 0;
+    return nullptr;
 
   // If this is a typedef for the type, strip the typedef off without
   // losing all typedef information.
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index 8ddfac7..3648d2a 100644
--- a/include/clang/AST/TypeLoc.h
+++ b/include/clang/AST/TypeLoc.h
@@ -81,7 +81,7 @@
     Qualified
   };
 
-  TypeLoc() : Ty(0), Data(0) { }
+  TypeLoc() : Ty(nullptr), Data(nullptr) { }
   TypeLoc(QualType ty, void *opaqueData)
     : Ty(ty.getAsOpaquePtr()), Data(opaqueData) { }
   TypeLoc(const Type *ty, void *opaqueData)
@@ -631,7 +631,7 @@
   bool isDefinition() const {
     TagDecl *D = getDecl();
     return D->isCompleteDefinition() &&
-         (D->getIdentifier() == 0 || D->getLocation() == getNameLoc());
+           (D->getIdentifier() == nullptr || D->getLocation() == getNameLoc());
   }
 };
 
@@ -786,7 +786,7 @@
     setAttrNameLoc(loc);
     if (hasAttrExprOperand()) {
       setAttrOperandParensRange(SourceRange(loc));
-      setAttrExprOperand(0);
+      setAttrExprOperand(nullptr);
     } else if (hasAttrEnumOperand()) {
       setAttrOperandParensRange(SourceRange(loc));
       setAttrEnumOperandLoc(loc);
@@ -978,12 +978,10 @@
 }
 
 
-struct DecayedLocInfo { }; // Nothing.
+struct AdjustedLocInfo { }; // Nothing.
 
-/// \brief Wrapper for source info for pointers decayed from arrays and
-/// functions.
-class DecayedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, DecayedTypeLoc,
-                                              DecayedType, DecayedLocInfo> {
+class AdjustedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AdjustedTypeLoc,
+                                               AdjustedType, AdjustedLocInfo> {
 public:
   TypeLoc getOriginalLoc() const {
     return getInnerTypeLoc();
@@ -1004,12 +1002,17 @@
   }
 
   unsigned getLocalDataSize() const {
-    // sizeof(DecayedLocInfo) is 1, but we don't need its address to be unique
+    // sizeof(AdjustedLocInfo) is 1, but we don't need its address to be unique
     // anyway.  TypeLocBuilder can't handle data sizes of 1.
     return 0;  // No data.
   }
 };
 
+/// \brief Wrapper for source info for pointers decayed from arrays and
+/// functions.
+class DecayedTypeLoc : public InheritingConcreteTypeLoc<
+                           AdjustedTypeLoc, DecayedTypeLoc, DecayedType> {
+};
 
 struct PointerLikeLocInfo {
   SourceLocation StarLoc;
@@ -1098,7 +1101,7 @@
 
   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
     setSigilLoc(Loc);
-    setClassTInfo(0);
+    setClassTInfo(nullptr);
   }
 
   SourceRange getLocalSourceRange() const {
@@ -1205,23 +1208,23 @@
   }
 
   ArrayRef<ParmVarDecl *> getParams() const {
-    return ArrayRef<ParmVarDecl *>(getParmArray(), getNumArgs());
+    return ArrayRef<ParmVarDecl *>(getParmArray(), getNumParams());
   }
 
-  // ParmVarDecls* are stored after Info, one for each argument.
+  // ParmVarDecls* are stored after Info, one for each parameter.
   ParmVarDecl **getParmArray() const {
     return (ParmVarDecl**) getExtraLocalData();
   }
 
-  unsigned getNumArgs() const {
+  unsigned getNumParams() const {
     if (isa<FunctionNoProtoType>(getTypePtr()))
       return 0;
-    return cast<FunctionProtoType>(getTypePtr())->getNumArgs();
+    return cast<FunctionProtoType>(getTypePtr())->getNumParams();
   }
-  ParmVarDecl *getArg(unsigned i) const { return getParmArray()[i]; }
-  void setArg(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
+  ParmVarDecl *getParam(unsigned i) const { return getParmArray()[i]; }
+  void setParam(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
 
-  TypeLoc getResultLoc() const {
+  TypeLoc getReturnLoc() const {
     return getInnerTypeLoc();
   }
 
@@ -1234,21 +1237,21 @@
     setLParenLoc(Loc);
     setRParenLoc(Loc);
     setLocalRangeEnd(Loc);
-    for (unsigned i = 0, e = getNumArgs(); i != e; ++i)
-      setArg(i, NULL);
+    for (unsigned i = 0, e = getNumParams(); i != e; ++i)
+      setParam(i, nullptr);
   }
 
   /// \brief Returns the size of the type source info data block that is
   /// specific to this type.
   unsigned getExtraLocalDataSize() const {
-    return getNumArgs() * sizeof(ParmVarDecl*);
+    return getNumParams() * sizeof(ParmVarDecl *);
   }
 
   unsigned getExtraLocalDataAlignment() const {
     return llvm::alignOf<ParmVarDecl*>();
   }
 
-  QualType getInnerType() const { return getTypePtr()->getResultType(); }
+  QualType getInnerType() const { return getTypePtr()->getReturnType(); }
 };
 
 class FunctionProtoTypeLoc :
@@ -1311,7 +1314,7 @@
   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
     setLBracketLoc(Loc);
     setRBracketLoc(Loc);
-    setSizeExpr(NULL);
+    setSizeExpr(nullptr);
   }
 
   QualType getInnerType() const { return getTypePtr()->getElementType(); }
@@ -1771,7 +1774,7 @@
       // template specialization type, we won't record the nested-name-specifier
       // location information when this type-source location information is
       // part of a nested-name-specifier.
-      getLocalData()->QualifierData = 0;
+      getLocalData()->QualifierData = nullptr;
       return;
     }
 
diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def
index 3126f48..3b2665b 100644
--- a/include/clang/AST/TypeNodes.def
+++ b/include/clang/AST/TypeNodes.def
@@ -81,7 +81,8 @@
 DEPENDENT_TYPE(UnresolvedUsing, Type)
 NON_CANONICAL_TYPE(Paren, Type)
 NON_CANONICAL_TYPE(Typedef, Type)
-NON_CANONICAL_TYPE(Decayed, Type)
+NON_CANONICAL_TYPE(Adjusted, Type)
+NON_CANONICAL_TYPE(Decayed, AdjustedType)
 NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOfExpr, Type)
 NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOf, Type)
 NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Decltype, Type)
diff --git a/include/clang/AST/UnresolvedSet.h b/include/clang/AST/UnresolvedSet.h
index 759af25..2ef5800 100644
--- a/include/clang/AST/UnresolvedSet.h
+++ b/include/clang/AST/UnresolvedSet.h
@@ -27,7 +27,7 @@
 /// non-const iterator.
 class UnresolvedSetIterator {
 private:
-  typedef llvm::MutableArrayRef<DeclAccessPair> DeclsTy;
+  typedef MutableArrayRef<DeclAccessPair> DeclsTy;
   typedef DeclsTy::iterator IteratorTy;
 
   IteratorTy ir;
diff --git a/include/clang/AST/VTableBuilder.h b/include/clang/AST/VTableBuilder.h
index 4e45132..4e24bdd 100644
--- a/include/clang/AST/VTableBuilder.h
+++ b/include/clang/AST/VTableBuilder.h
@@ -19,8 +19,9 @@
 #include "clang/AST/GlobalDecl.h"
 #include "clang/AST/RecordLayout.h"
 #include "clang/Basic/ABI.h"
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SetVector.h"
-#include "llvm/ADT/DenseSet.h"
+#include <memory>
 #include <utility>
 
 namespace clang {
@@ -208,11 +209,11 @@
   typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy;
 private:
   uint64_t NumVTableComponents;
-  llvm::OwningArrayPtr<VTableComponent> VTableComponents;
+  std::unique_ptr<VTableComponent[]> VTableComponents;
 
   /// \brief Contains thunks needed by vtables, sorted by indices.
   uint64_t NumVTableThunks;
-  llvm::OwningArrayPtr<VTableThunkTy> VTableThunks;
+  std::unique_ptr<VTableThunkTy[]> VTableThunks;
 
   /// \brief Address points for all vtables.
   AddressPointsMapTy AddressPoints;
@@ -270,6 +271,10 @@
 public:
   typedef SmallVector<ThunkInfo, 1> ThunkInfoVectorTy;
 
+  bool isMicrosoft() const { return IsMicrosoftABI; }
+
+  virtual ~VTableContextBase() {}
+
 protected:
   typedef llvm::DenseMap<const CXXMethodDecl *, ThunkInfoVectorTy> ThunksMapTy;
 
@@ -280,7 +285,7 @@
   /// offset offsets, thunks etc) for the given record decl.
   virtual void computeVTableRelatedInformation(const CXXRecordDecl *RD) = 0;
 
-  virtual ~VTableContextBase() {}
+  VTableContextBase(bool MS) : IsMicrosoftABI(MS) {}
 
 public:
   virtual const ThunkInfoVectorTy *getThunkInfo(GlobalDecl GD) {
@@ -292,16 +297,17 @@
     ThunksMapTy::const_iterator I = Thunks.find(MD);
     if (I == Thunks.end()) {
       // We did not find a thunk for this method.
-      return 0;
+      return nullptr;
     }
 
     return &I->second;
   }
+
+  bool IsMicrosoftABI;
 };
 
 class ItaniumVTableContext : public VTableContextBase {
 private:
-  bool IsMicrosoftABI;
 
   /// \brief Contains the index (relative to the vtable address point)
   /// where the function pointer for a virtual function is stored.
@@ -323,7 +329,7 @@
     VirtualBaseClassOffsetOffsetsMapTy;
   VirtualBaseClassOffsetOffsetsMapTy VirtualBaseClassOffsetOffsets;
 
-  void computeVTableRelatedInformation(const CXXRecordDecl *RD);
+  void computeVTableRelatedInformation(const CXXRecordDecl *RD) override;
 
 public:
   ItaniumVTableContext(ASTContext &Context);
@@ -355,49 +361,83 @@
   /// Base must be a virtual base class or an unambiguous base.
   CharUnits getVirtualBaseOffsetOffset(const CXXRecordDecl *RD,
                                        const CXXRecordDecl *VBase);
+
+  static bool classof(const VTableContextBase *VT) {
+    return !VT->isMicrosoft();
+  }
 };
 
-struct VFPtrInfo {
+/// Holds information about the inheritance path to a virtual base or function
+/// table pointer.  A record may contain as many vfptrs or vbptrs as there are
+/// base subobjects.
+struct VPtrInfo {
   typedef SmallVector<const CXXRecordDecl *, 1> BasePath;
 
-  // Don't pass the PathToMangle as it should be calculated later.
-  VFPtrInfo(CharUnits VFPtrOffset, const BasePath &PathToBaseWithVFPtr)
-      : VBTableIndex(0), LastVBase(0), VFPtrOffset(VFPtrOffset),
-        PathToBaseWithVFPtr(PathToBaseWithVFPtr), VFPtrFullOffset(VFPtrOffset) {
-  }
+  VPtrInfo(const CXXRecordDecl *RD)
+      : ReusingBase(RD), BaseWithVPtr(RD), NextBaseToMangle(RD) {}
 
-  // Don't pass the PathToMangle as it should be calculated later.
-  VFPtrInfo(uint64_t VBTableIndex, const CXXRecordDecl *LastVBase,
-            CharUnits VFPtrOffset, const BasePath &PathToBaseWithVFPtr,
-            CharUnits VFPtrFullOffset)
-      : VBTableIndex(VBTableIndex), LastVBase(LastVBase),
-        VFPtrOffset(VFPtrOffset), PathToBaseWithVFPtr(PathToBaseWithVFPtr),
-        VFPtrFullOffset(VFPtrFullOffset) {
-    assert(VBTableIndex && "The full constructor should only be used "
-                           "for vfptrs in virtual bases");
-    assert(LastVBase);
-  }
+  // Copy constructor.
+  // FIXME: Uncomment when we've moved to C++11.
+  // VPtrInfo(const VPtrInfo &) = default;
 
-  /// If nonzero, holds the vbtable index of the virtual base with the vfptr.
-  uint64_t VBTableIndex;
+  /// The vtable will hold all of the virtual bases or virtual methods of
+  /// ReusingBase.  This may or may not be the same class as VPtrSubobject.Base.
+  /// A derived class will reuse the vptr of the first non-virtual base
+  /// subobject that has one.
+  const CXXRecordDecl *ReusingBase;
 
-  /// Stores the last vbase on the path from the complete type to the vfptr.
-  const CXXRecordDecl *LastVBase;
+  /// BaseWithVPtr is at this offset from its containing complete object or
+  /// virtual base.
+  CharUnits NonVirtualOffset;
 
-  /// This is the offset of the vfptr from the start of the last vbase,
-  /// or the complete type if there are no virtual bases.
-  CharUnits VFPtrOffset;
+  /// The vptr is stored inside this subobject.
+  const CXXRecordDecl *BaseWithVPtr;
+
+  /// The bases from the inheritance path that got used to mangle the vbtable
+  /// name.  This is not really a full path like a CXXBasePath.  It holds the
+  /// subset of records that need to be mangled into the vbtable symbol name in
+  /// order to get a unique name.
+  BasePath MangledPath;
+
+  /// The next base to push onto the mangled path if this path is ambiguous in a
+  /// derived class.  If it's null, then it's already been pushed onto the path.
+  const CXXRecordDecl *NextBaseToMangle;
+
+  /// The set of possibly indirect vbases that contain this vbtable.  When a
+  /// derived class indirectly inherits from the same vbase twice, we only keep
+  /// vtables and their paths from the first instance.
+  BasePath ContainingVBases;
 
   /// This holds the base classes path from the complete type to the first base
-  /// with the given vfptr offset, in the base-to-derived order.
-  BasePath PathToBaseWithVFPtr;
+  /// with the given vfptr offset, in the base-to-derived order.  Only used for
+  /// vftables.
+  BasePath PathToBaseWithVPtr;
 
-  /// This holds the subset of records that need to be mangled into the vftable
-  /// symbol name in order to get a unique name, in the derived-to-base order.
-  BasePath PathToMangle;
+  /// Static offset from the top of the most derived class to this vfptr,
+  /// including any virtual base offset.  Only used for vftables.
+  CharUnits FullOffsetInMDC;
 
-  /// This is the full offset of the vfptr from the start of the complete type.
-  CharUnits VFPtrFullOffset;
+  /// The vptr is stored inside the non-virtual component of this virtual base.
+  const CXXRecordDecl *getVBaseWithVPtr() const {
+    return ContainingVBases.empty() ? nullptr : ContainingVBases.front();
+  }
+};
+
+typedef SmallVector<VPtrInfo *, 2> VPtrInfoVector;
+
+/// All virtual base related information about a given record decl.  Includes
+/// information on all virtual base tables and the path components that are used
+/// to mangle them.
+struct VirtualBaseInfo {
+  ~VirtualBaseInfo() { llvm::DeleteContainerPointers(VBPtrPaths); }
+
+  /// A map from virtual base to vbtable index for doing a conversion from the
+  /// the derived class to the a base.
+  llvm::DenseMap<const CXXRecordDecl *, unsigned> VBTableIndices;
+
+  /// Information on all virtual base tables used when this record is the most
+  /// derived class.
+  VPtrInfoVector VBPtrPaths;
 };
 
 class MicrosoftVTableContext : public VTableContextBase {
@@ -418,7 +458,7 @@
     uint64_t Index;
 
     MethodVFTableLocation()
-        : VBTableIndex(0), VBase(0), VFPtrOffset(CharUnits::Zero()),
+        : VBTableIndex(0), VBase(nullptr), VFPtrOffset(CharUnits::Zero()),
           Index(0) {}
 
     MethodVFTableLocation(uint64_t VBTableIndex, const CXXRecordDecl *VBase,
@@ -431,16 +471,11 @@
         assert(VBase != other.VBase);
         return VBTableIndex < other.VBTableIndex;
       }
-      if (VFPtrOffset != other.VFPtrOffset)
-        return VFPtrOffset < other.VFPtrOffset;
-      if (Index != other.Index)
-        return Index < other.Index;
-      return false;
+      return std::tie(VFPtrOffset, Index) <
+             std::tie(other.VFPtrOffset, other.Index);
     }
   };
 
-  typedef SmallVector<VFPtrInfo, 1> VFPtrListTy;
-
 private:
   ASTContext &Context;
 
@@ -448,7 +483,7 @@
     MethodVFTableLocationsTy;
   MethodVFTableLocationsTy MethodVFTableLocations;
 
-  typedef llvm::DenseMap<const CXXRecordDecl *, VFPtrListTy>
+  typedef llvm::DenseMap<const CXXRecordDecl *, VPtrInfoVector *>
     VFPtrLocationsMapTy;
   VFPtrLocationsMapTy VFPtrLocations;
 
@@ -456,47 +491,40 @@
   typedef llvm::DenseMap<VFTableIdTy, const VTableLayout *> VFTableLayoutMapTy;
   VFTableLayoutMapTy VFTableLayouts;
 
-  typedef llvm::SmallSetVector<const CXXRecordDecl *, 8> BasesSetVectorTy;
-  void enumerateVFPtrs(const CXXRecordDecl *MostDerivedClass,
-                       const ASTRecordLayout &MostDerivedClassLayout,
-                       BaseSubobject Base, const CXXRecordDecl *LastVBase,
-                       const VFPtrInfo::BasePath &PathFromCompleteClass,
-                       BasesSetVectorTy &VisitedVBases,
-                       MicrosoftVTableContext::VFPtrListTy &Result);
+  llvm::DenseMap<const CXXRecordDecl *, VirtualBaseInfo *> VBaseInfo;
 
-  void enumerateVFPtrs(const CXXRecordDecl *ForClass,
-                       MicrosoftVTableContext::VFPtrListTy &Result);
+  void enumerateVFPtrs(const CXXRecordDecl *ForClass, VPtrInfoVector &Result);
 
-  void computeVTableRelatedInformation(const CXXRecordDecl *RD);
+  void computeVTableRelatedInformation(const CXXRecordDecl *RD) override;
 
   void dumpMethodLocations(const CXXRecordDecl *RD,
                            const MethodVFTableLocationsTy &NewMethods,
                            raw_ostream &);
 
-  typedef std::pair<const CXXRecordDecl *, const CXXRecordDecl *> ClassPairTy;
-  typedef llvm::DenseMap<ClassPairTy, unsigned> VBTableIndicesTy;
-  VBTableIndicesTy VBTableIndices;
-  llvm::DenseSet<const CXXRecordDecl *> ComputedVBTableIndices;
+  const VirtualBaseInfo *
+  computeVBTableRelatedInformation(const CXXRecordDecl *RD);
 
-  void computeVBTableRelatedInformation(const CXXRecordDecl *RD);
+  void computeVTablePaths(bool ForVBTables, const CXXRecordDecl *RD,
+                          VPtrInfoVector &Paths);
 
 public:
-  MicrosoftVTableContext(ASTContext &Context) : Context(Context) {}
+  MicrosoftVTableContext(ASTContext &Context)
+      : VTableContextBase(/*MS=*/true), Context(Context) {}
 
-  ~MicrosoftVTableContext() { llvm::DeleteContainerSeconds(VFTableLayouts); }
+  ~MicrosoftVTableContext();
 
-  const VFPtrListTy &getVFPtrOffsets(const CXXRecordDecl *RD);
+  const VPtrInfoVector &getVFPtrOffsets(const CXXRecordDecl *RD);
 
   const VTableLayout &getVFTableLayout(const CXXRecordDecl *RD,
                                        CharUnits VFPtrOffset);
 
   const MethodVFTableLocation &getMethodVFTableLocation(GlobalDecl GD);
 
-  const ThunkInfoVectorTy *getThunkInfo(GlobalDecl GD) {
+  const ThunkInfoVectorTy *getThunkInfo(GlobalDecl GD) override {
     // Complete destructors don't have a slot in a vftable, so no thunks needed.
     if (isa<CXXDestructorDecl>(GD.getDecl()) &&
         GD.getDtorType() == Dtor_Complete)
-      return 0;
+      return nullptr;
     return VTableContextBase::getThunkInfo(GD);
   }
 
@@ -505,14 +533,13 @@
   /// The vbtable is an array of i32 offsets.  The first entry is a self entry,
   /// and the rest are offsets from the vbptr to virtual bases.
   unsigned getVBTableIndex(const CXXRecordDecl *Derived,
-                           const CXXRecordDecl *VBase) {
-    computeVBTableRelatedInformation(Derived);
-    ClassPairTy Pair(Derived, VBase);
-    assert(VBTableIndices.count(Pair) == 1 &&
-           "VBase must be a vbase of Derived");
-    return VBTableIndices[Pair];
-  }
+                           const CXXRecordDecl *VBase);
+
+  const VPtrInfoVector &enumerateVBTables(const CXXRecordDecl *RD);
+
+  static bool classof(const VTableContextBase *VT) { return VT->isMicrosoft(); }
 };
-}
+
+} // namespace clang
 
 #endif
diff --git a/include/clang/ASTMatchers/ASTMatchFinder.h b/include/clang/ASTMatchers/ASTMatchFinder.h
index db0a83d..8af0546 100644
--- a/include/clang/ASTMatchers/ASTMatchFinder.h
+++ b/include/clang/ASTMatchers/ASTMatchFinder.h
@@ -222,13 +222,13 @@
     if (NodeT *Node = I->getNodeAs<NodeT>(BoundTo))
       return Node;
   }
-  return NULL;
+  return nullptr;
 }
 
 namespace internal {
 class CollectMatchesCallback : public MatchFinder::MatchCallback {
 public:
-  virtual void run(const MatchFinder::MatchResult &Result) {
+  void run(const MatchFinder::MatchResult &Result) override {
     Nodes.push_back(Result.Nodes);
   }
   SmallVector<BoundNodes, 1> Nodes;
diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h
index 0a3157d..1ff4ab3 100644
--- a/include/clang/ASTMatchers/ASTMatchers.h
+++ b/include/clang/ASTMatchers/ASTMatchers.h
@@ -311,6 +311,12 @@
   return Node.getAccess() == AS_private;
 }
 
+/// \brief Matches a declaration that has been implicitly added
+/// by the compiler (eg. implicit default/copy constructors).
+AST_MATCHER(Decl, isImplicit) {
+  return Node.isImplicit();
+}
+
 /// \brief Matches classTemplateSpecializations that have at least one
 /// TemplateArgument matching the given InnerMatcher.
 ///
@@ -323,9 +329,13 @@
 /// classTemplateSpecializationDecl(hasAnyTemplateArgument(
 ///     refersToType(asString("int"))))
 ///   matches the specialization \c A<int>
-AST_MATCHER_P(ClassTemplateSpecializationDecl, hasAnyTemplateArgument,
-              internal::Matcher<TemplateArgument>, InnerMatcher) {
-  llvm::ArrayRef<TemplateArgument> List = Node.getTemplateArgs().asArray();
+AST_POLYMORPHIC_MATCHER_P(
+    hasAnyTemplateArgument,
+    AST_POLYMORPHIC_SUPPORTED_TYPES_2(ClassTemplateSpecializationDecl,
+                                      TemplateSpecializationType),
+    internal::Matcher<TemplateArgument>, InnerMatcher) {
+  ArrayRef<TemplateArgument> List =
+      internal::getTemplateSpecializationArgs(Node);
   return matchesFirstInRange(InnerMatcher, List.begin(), List.end(), Finder,
                              Builder);
 }
@@ -419,12 +429,16 @@
 /// classTemplateSpecializationDecl(hasTemplateArgument(
 ///     1, refersToType(asString("int"))))
 ///   matches the specialization \c A<bool, int>
-AST_MATCHER_P2(ClassTemplateSpecializationDecl, hasTemplateArgument,
-               unsigned, N, internal::Matcher<TemplateArgument>, InnerMatcher) {
-  const TemplateArgumentList &List = Node.getTemplateArgs();
+AST_POLYMORPHIC_MATCHER_P2(
+    hasTemplateArgument,
+    AST_POLYMORPHIC_SUPPORTED_TYPES_2(ClassTemplateSpecializationDecl,
+                                      TemplateSpecializationType),
+    unsigned, N, internal::Matcher<TemplateArgument>, InnerMatcher) {
+  ArrayRef<TemplateArgument> List =
+      internal::getTemplateSpecializationArgs(Node);
   if (List.size() <= N)
     return false;
-  return InnerMatcher.matches(List.get(N), Finder, Builder);
+  return InnerMatcher.matches(List[N], Finder, Builder);
 }
 
 /// \brief Matches a TemplateArgument that refers to a certain type.
@@ -445,7 +459,8 @@
   return InnerMatcher.matches(Node.getAsType(), Finder, Builder);
 }
 
-/// \brief Matches a TemplateArgument that refers to a certain declaration.
+/// \brief Matches a canonical TemplateArgument that refers to a certain
+/// declaration.
 ///
 /// Given
 /// \code
@@ -464,6 +479,24 @@
   return false;
 }
 
+/// \brief Matches a sugar TemplateArgument that refers to a certain expression.
+///
+/// Given
+/// \code
+///   template<typename T> struct A {};
+///   struct B { B* next; };
+///   A<&B::next> a;
+/// \endcode
+/// templateSpecializationType(hasAnyTemplateArgument(
+///   isExpr(hasDescendant(declRefExpr(to(fieldDecl(hasName("next"))))))))
+///   matches the specialization \c A<&B::next> with \c fieldDecl(...) matching
+///     \c B::next
+AST_MATCHER_P(TemplateArgument, isExpr, internal::Matcher<Expr>, InnerMatcher) {
+  if (Node.getKind() == TemplateArgument::Expression)
+    return InnerMatcher.matches(*Node.getAsExpr(), Finder, Builder);
+  return false;
+}
+
 /// \brief Matches C++ constructor declarations.
 ///
 /// Example matches Foo::Foo() and Foo::Foo(int)
@@ -518,7 +551,7 @@
 ///
 /// Example matches y
 /// \code
-///   class X { void y() };
+///   class X { void y(); };
 /// \endcode
 const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl> methodDecl;
 
@@ -635,6 +668,16 @@
   Stmt,
   CXXMemberCallExpr> memberCallExpr;
 
+/// \brief Matches expressions that introduce cleanups to be run at the end
+/// of the sub-expression's evaluation.
+///
+/// Example matches std::string()
+/// \code
+///   const std::string str = std::string();
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Stmt, ExprWithCleanups>
+exprWithCleanups;
+
 /// \brief Matches init list expressions.
 ///
 /// Given
@@ -643,10 +686,23 @@
 ///   struct B { int x, y; };
 ///   B b = { 5, 6 };
 /// \endcode
-/// initList()
+/// initListExpr()
 ///   matches "{ 1, 2 }" and "{ 5, 6 }"
 const internal::VariadicDynCastAllOfMatcher<Stmt, InitListExpr> initListExpr;
 
+/// \brief Matches substitutions of non-type template parameters.
+///
+/// Given
+/// \code
+///   template <int N>
+///   struct A { static const int n = N; };
+///   struct B : public A<42> {};
+/// \endcode
+/// substNonTypeTemplateParmExpr()
+///   matches "N" in the right-hand side of "static const int n = N;"
+const internal::VariadicDynCastAllOfMatcher<Stmt, SubstNonTypeTemplateParmExpr>
+substNonTypeTemplateParmExpr;
+
 /// \brief Matches using declarations.
 ///
 /// Given
@@ -658,6 +714,18 @@
 ///   matches \code using X::x \endcode
 const internal::VariadicDynCastAllOfMatcher<Decl, UsingDecl> usingDecl;
 
+/// \brief Matches using namespace declarations.
+///
+/// Given
+/// \code
+///   namespace X { int x; }
+///   using namespace X;
+/// \endcode
+/// usingDirectiveDecl()
+///   matches \code using namespace X \endcode
+const internal::VariadicDynCastAllOfMatcher<Decl, UsingDirectiveDecl>
+    usingDirectiveDecl;
+
 /// \brief Matches unresolved using value declarations.
 ///
 /// Given
@@ -842,15 +910,6 @@
 /// \endcode
 const internal::VariadicDynCastAllOfMatcher<Stmt, ForStmt> forStmt;
 
-/// \brief Matches range-based for statements.
-///
-/// forRangeStmt() matches 'for (auto a : i)'
-/// \code
-///   int i[] =  {1, 2, 3}; for (auto a : i);
-///   for(int j = 0; j < 5; ++j);
-/// \endcode
-const internal::VariadicDynCastAllOfMatcher<Stmt, CXXForRangeStmt> forRangeStmt;
-
 /// \brief Matches the increment statement of a for loop.
 ///
 /// Example:
@@ -862,7 +921,7 @@
 AST_MATCHER_P(ForStmt, hasIncrement, internal::Matcher<Stmt>,
               InnerMatcher) {
   const Stmt *const Increment = Node.getInc();
-  return (Increment != NULL &&
+  return (Increment != nullptr &&
           InnerMatcher.matches(*Increment, Finder, Builder));
 }
 
@@ -877,7 +936,44 @@
 AST_MATCHER_P(ForStmt, hasLoopInit, internal::Matcher<Stmt>,
               InnerMatcher) {
   const Stmt *const Init = Node.getInit();
-  return (Init != NULL && InnerMatcher.matches(*Init, Finder, Builder));
+  return (Init != nullptr && InnerMatcher.matches(*Init, Finder, Builder));
+}
+
+/// \brief Matches range-based for statements.
+///
+/// forRangeStmt() matches 'for (auto a : i)'
+/// \code
+///   int i[] =  {1, 2, 3}; for (auto a : i);
+///   for(int j = 0; j < 5; ++j);
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXForRangeStmt> forRangeStmt;
+
+/// \brief Matches the initialization statement of a for loop.
+///
+/// Example:
+///     forStmt(hasLoopVariable(anything()))
+/// matches 'int x' in
+/// \code
+///     for (int x : a) { }
+/// \endcode
+AST_MATCHER_P(CXXForRangeStmt, hasLoopVariable, internal::Matcher<VarDecl>,
+              InnerMatcher) {
+  const VarDecl *const Var = Node.getLoopVariable();
+  return (Var != nullptr && InnerMatcher.matches(*Var, Finder, Builder));
+}
+
+/// \brief Matches the range initialization statement of a for loop.
+///
+/// Example:
+///     forStmt(hasRangeInit(anything()))
+/// matches 'a' in
+/// \code
+///     for (int x : a) { }
+/// \endcode
+AST_MATCHER_P(CXXForRangeStmt, hasRangeInit, internal::Matcher<Expr>,
+              InnerMatcher) {
+  const Expr *const Init = Node.getRangeInit();
+  return (Init != nullptr && InnerMatcher.matches(*Init, Finder, Builder));
 }
 
 /// \brief Matches while statements.
@@ -1317,21 +1413,21 @@
 /// \c b.
 ///
 /// Usable as: Any Matcher
-const internal::VariadicOperatorMatcherFunc eachOf = {
+const internal::VariadicOperatorMatcherFunc<2, UINT_MAX> eachOf = {
   internal::EachOfVariadicOperator
 };
 
 /// \brief Matches if any of the given matchers matches.
 ///
 /// Usable as: Any Matcher
-const internal::VariadicOperatorMatcherFunc anyOf = {
+const internal::VariadicOperatorMatcherFunc<2, UINT_MAX> anyOf = {
   internal::AnyOfVariadicOperator
 };
 
 /// \brief Matches if all given matchers match.
 ///
 /// Usable as: Any Matcher
-const internal::VariadicOperatorMatcherFunc allOf = {
+const internal::VariadicOperatorMatcherFunc<2, UINT_MAX> allOf = {
   internal::AllOfVariadicOperator
 };
 
@@ -1458,14 +1554,14 @@
 /// line and \c recordDecl(hasMethod(hasOverloadedOperatorName("*"))) matches
 /// the declaration of \c A.
 ///
-/// Usable as: Matcher<CXXOperatorCallExpr>, Matcher<CXXMethodDecl>
+/// Usable as: Matcher<CXXOperatorCallExpr>, Matcher<FunctionDecl>
 inline internal::PolymorphicMatcherWithParam1<
     internal::HasOverloadedOperatorNameMatcher, StringRef,
-    AST_POLYMORPHIC_SUPPORTED_TYPES_2(CXXOperatorCallExpr, CXXMethodDecl)>
+    AST_POLYMORPHIC_SUPPORTED_TYPES_2(CXXOperatorCallExpr, FunctionDecl)>
 hasOverloadedOperatorName(const StringRef Name) {
   return internal::PolymorphicMatcherWithParam1<
       internal::HasOverloadedOperatorNameMatcher, StringRef,
-      AST_POLYMORPHIC_SUPPORTED_TYPES_2(CXXOperatorCallExpr, CXXMethodDecl)>(
+      AST_POLYMORPHIC_SUPPORTED_TYPES_2(CXXOperatorCallExpr, FunctionDecl)>(
       Name);
 }
 
@@ -1671,12 +1767,9 @@
 /// \endcode
 ///
 /// Usable as: Any Matcher
-template <typename M>
-internal::PolymorphicMatcherWithParam1<internal::NotMatcher, M>
-unless(const M &InnerMatcher) {
-  return internal::PolymorphicMatcherWithParam1<
-    internal::NotMatcher, M>(InnerMatcher);
-}
+const internal::VariadicOperatorMatcherFunc<1, 1> unless = {
+  internal::NotUnaryOperator
+};
 
 /// \brief Matches a node if the declaration associated with that node
 /// matches the given matcher.
@@ -1718,7 +1811,7 @@
               InnerMatcher) {
   const Expr *ExprNode = Node.getImplicitObjectArgument()
                             ->IgnoreParenImpCasts();
-  return (ExprNode != NULL &&
+  return (ExprNode != nullptr &&
           InnerMatcher.matches(*ExprNode, Finder, Builder));
 }
 
@@ -1741,7 +1834,7 @@
 AST_MATCHER_P(CallExpr, callee, internal::Matcher<Stmt>,
               InnerMatcher) {
   const Expr *ExprNode = Node.getCallee();
-  return (ExprNode != NULL &&
+  return (ExprNode != nullptr &&
           InnerMatcher.matches(*ExprNode, Finder, Builder));
 }
 
@@ -1896,7 +1989,7 @@
 AST_MATCHER_P(CXXMemberCallExpr, onImplicitObjectArgument,
               internal::Matcher<Expr>, InnerMatcher) {
   const Expr *ExprNode = Node.getImplicitObjectArgument();
-  return (ExprNode != NULL &&
+  return (ExprNode != nullptr &&
           InnerMatcher.matches(*ExprNode, Finder, Builder));
 }
 
@@ -1929,7 +2022,7 @@
 AST_MATCHER_P(DeclRefExpr, to, internal::Matcher<Decl>,
               InnerMatcher) {
   const Decl *DeclNode = Node.getDecl();
-  return (DeclNode != NULL &&
+  return (DeclNode != nullptr &&
           InnerMatcher.matches(*DeclNode, Finder, Builder));
 }
 
@@ -1986,10 +2079,39 @@
     VarDecl, hasInitializer, internal::Matcher<Expr>,
     InnerMatcher) {
   const Expr *Initializer = Node.getAnyInitializer();
-  return (Initializer != NULL &&
+  return (Initializer != nullptr &&
           InnerMatcher.matches(*Initializer, Finder, Builder));
 }
 
+/// \brief Matches a variable declaration that has function scope and is a
+/// non-static local variable.
+///
+/// Example matches x (matcher = varDecl(hasLocalStorage())
+/// \code
+/// void f() {
+///   int x;
+///   static int y;
+/// }
+/// int z;
+/// \endcode
+AST_MATCHER(VarDecl, hasLocalStorage) {
+  return Node.hasLocalStorage();
+}
+
+/// \brief Matches a variable declaration that does not have local storage.
+///
+/// Example matches y and z (matcher = varDecl(hasGlobalStorage())
+/// \code
+/// void f() {
+///   int x;
+///   static int y;
+/// }
+/// int z;
+/// \endcode
+AST_MATCHER(VarDecl, hasGlobalStorage) {
+  return Node.hasGlobalStorage();
+}
+
 /// \brief Checks that a call expression or a constructor call expression has
 /// a specific number of arguments (including absent default arguments).
 ///
@@ -2098,7 +2220,7 @@
 AST_MATCHER_P(CXXCtorInitializer, forField,
               internal::Matcher<FieldDecl>, InnerMatcher) {
   const FieldDecl *NodeAsDecl = Node.getMember();
-  return (NodeAsDecl != NULL &&
+  return (NodeAsDecl != nullptr &&
       InnerMatcher.matches(*NodeAsDecl, Finder, Builder));
 }
 
@@ -2118,7 +2240,7 @@
 AST_MATCHER_P(CXXCtorInitializer, withInitializer,
               internal::Matcher<Expr>, InnerMatcher) {
   const Expr* NodeAsExpr = Node.getInit();
-  return (NodeAsExpr != NULL &&
+  return (NodeAsExpr != nullptr &&
       InnerMatcher.matches(*NodeAsExpr, Finder, Builder));
 }
 
@@ -2139,12 +2261,6 @@
   return Node.isWritten();
 }
 
-/// \brief Matches a constructor declaration that has been implicitly added
-/// by the compiler (eg. implicit default/copy constructors).
-AST_MATCHER(CXXConstructorDecl, isImplicit) {
-  return Node.isImplicit();
-}
-
 /// \brief Matches any argument of a call expression or a constructor call
 /// expression.
 ///
@@ -2175,6 +2291,11 @@
   return false;
 }
 
+/// \brief Matches a constructor call expression which uses list initialization.
+AST_MATCHER(CXXConstructExpr, isListInitialization) {
+  return Node.isListInitialization();
+}
+
 /// \brief Matches the n'th parameter of a function declaration.
 ///
 /// Given
@@ -2234,7 +2355,7 @@
 ///   matches int f() { return 1; }
 AST_MATCHER_P(FunctionDecl, returns,
               internal::Matcher<QualType>, InnerMatcher) {
-  return InnerMatcher.matches(Node.getResultType(), Finder, Builder);
+  return InnerMatcher.matches(Node.getReturnType(), Finder, Builder);
 }
 
 /// \brief Matches extern "C" function declarations.
@@ -2263,19 +2384,33 @@
                       IfStmt, ForStmt, WhileStmt, DoStmt, ConditionalOperator),
     internal::Matcher<Expr>, InnerMatcher) {
   const Expr *const Condition = Node.getCond();
-  return (Condition != NULL &&
+  return (Condition != nullptr &&
           InnerMatcher.matches(*Condition, Finder, Builder));
 }
 
-namespace internal {
-struct NotEqualsBoundNodePredicate {
-  bool operator()(const internal::BoundNodesMap &Nodes) const {
-    return Nodes.getNode(ID) != Node;
-  }
-  std::string ID;
-  ast_type_traits::DynTypedNode Node;
-};
-} // namespace internal
+/// \brief Matches the then-statement of an if statement.
+///
+/// Examples matches the if statement
+///   (matcher = ifStmt(hasThen(boolLiteral(equals(true)))))
+/// \code
+///   if (false) true; else false;
+/// \endcode
+AST_MATCHER_P(IfStmt, hasThen, internal::Matcher<Stmt>, InnerMatcher) {
+  const Stmt *const Then = Node.getThen();
+  return (Then != nullptr && InnerMatcher.matches(*Then, Finder, Builder));
+}
+
+/// \brief Matches the else-statement of an if statement.
+///
+/// Examples matches the if statement
+///   (matcher = ifStmt(hasElse(boolLiteral(equals(true)))))
+/// \code
+///   if (false) false; else true;
+/// \endcode
+AST_MATCHER_P(IfStmt, hasElse, internal::Matcher<Stmt>, InnerMatcher) {
+  const Stmt *const Else = Node.getElse();
+  return (Else != nullptr && InnerMatcher.matches(*Else, Finder, Builder));
+}
 
 /// \brief Matches if a node equals a previously bound node.
 ///
@@ -2325,7 +2460,7 @@
               internal::Matcher<DeclStmt>, InnerMatcher) {
   const DeclStmt* const DeclarationStatement =
     Node.getConditionVariableDeclStmt();
-  return DeclarationStatement != NULL &&
+  return DeclarationStatement != nullptr &&
          InnerMatcher.matches(*DeclarationStatement, Finder, Builder);
 }
 
@@ -2373,11 +2508,13 @@
 ///   matches 'for (;;) {}'
 /// with compoundStmt()
 ///   matching '{}'
-AST_POLYMORPHIC_MATCHER_P(
-    hasBody, AST_POLYMORPHIC_SUPPORTED_TYPES_3(DoStmt, ForStmt, WhileStmt),
-    internal::Matcher<Stmt>, InnerMatcher) {
+AST_POLYMORPHIC_MATCHER_P(hasBody,
+                          AST_POLYMORPHIC_SUPPORTED_TYPES_4(DoStmt, ForStmt,
+                                                            WhileStmt,
+                                                            CXXForRangeStmt),
+                          internal::Matcher<Stmt>, InnerMatcher) {
   const Stmt *const Statement = Node.getBody();
-  return (Statement != NULL &&
+  return (Statement != nullptr &&
           InnerMatcher.matches(*Statement, Finder, Builder));
 }
 
@@ -2451,7 +2588,7 @@
 AST_MATCHER_P(BinaryOperator, hasLHS,
               internal::Matcher<Expr>, InnerMatcher) {
   Expr *LeftHandSide = Node.getLHS();
-  return (LeftHandSide != NULL &&
+  return (LeftHandSide != nullptr &&
           InnerMatcher.matches(*LeftHandSide, Finder, Builder));
 }
 
@@ -2464,7 +2601,7 @@
 AST_MATCHER_P(BinaryOperator, hasRHS,
               internal::Matcher<Expr>, InnerMatcher) {
   Expr *RightHandSide = Node.getRHS();
-  return (RightHandSide != NULL &&
+  return (RightHandSide != nullptr &&
           InnerMatcher.matches(*RightHandSide, Finder, Builder));
 }
 
@@ -2484,7 +2621,7 @@
 AST_MATCHER_P(UnaryOperator, hasUnaryOperand,
               internal::Matcher<Expr>, InnerMatcher) {
   const Expr * const Operand = Node.getSubExpr();
-  return (Operand != NULL &&
+  return (Operand != nullptr &&
           InnerMatcher.matches(*Operand, Finder, Builder));
 }
 
@@ -2498,7 +2635,7 @@
 AST_MATCHER_P(CastExpr, hasSourceExpression,
               internal::Matcher<Expr>, InnerMatcher) {
   const Expr* const SubExpression = Node.getSubExpr();
-  return (SubExpression != NULL &&
+  return (SubExpression != nullptr &&
           InnerMatcher.matches(*SubExpression, Finder, Builder));
 }
 
@@ -2530,7 +2667,7 @@
 AST_MATCHER_P(ConditionalOperator, hasTrueExpression,
               internal::Matcher<Expr>, InnerMatcher) {
   Expr *Expression = Node.getTrueExpr();
-  return (Expression != NULL &&
+  return (Expression != nullptr &&
           InnerMatcher.matches(*Expression, Finder, Builder));
 }
 
@@ -2543,7 +2680,7 @@
 AST_MATCHER_P(ConditionalOperator, hasFalseExpression,
               internal::Matcher<Expr>, InnerMatcher) {
   Expr *Expression = Node.getFalseExpr();
-  return (Expression != NULL &&
+  return (Expression != nullptr &&
           InnerMatcher.matches(*Expression, Finder, Builder));
 }
 
@@ -2585,7 +2722,7 @@
 AST_MATCHER_P(CXXMethodDecl, ofClass,
               internal::Matcher<CXXRecordDecl>, InnerMatcher) {
   const CXXRecordDecl *Parent = Node.getParent();
-  return (Parent != NULL &&
+  return (Parent != nullptr &&
           InnerMatcher.matches(*Parent, Finder, Builder));
 }
 
@@ -2603,6 +2740,20 @@
   return Node.isVirtual();
 }
 
+/// \brief Matches if the given method declaration is pure.
+///
+/// Given
+/// \code
+///   class A {
+///    public:
+///     virtual void x() = 0;
+///   };
+/// \endcode
+///   matches A::x
+AST_MATCHER(CXXMethodDecl, isPure) {
+  return Node.isPure();
+}
+
 /// \brief Matches if the given method declaration is const.
 ///
 /// Given
@@ -2822,8 +2973,8 @@
 
 /// \brief Matches \c TypeLocs for which the given inner
 /// QualType-matcher matches.
-inline internal::BindableMatcher<TypeLoc> loc(
-    const internal::Matcher<QualType> &InnerMatcher) {
+AST_MATCHER_FUNCTION_P_OVERLOAD(internal::BindableMatcher<TypeLoc>, loc,
+                                internal::Matcher<QualType>, InnerMatcher, 0) {
   return internal::BindableMatcher<TypeLoc>(
       new internal::TypeLocTypeMatcher(InnerMatcher));
 }
@@ -3306,8 +3457,9 @@
 
 /// \brief Matches \c NestedNameSpecifierLocs for which the given inner
 /// NestedNameSpecifier-matcher matches.
-inline internal::BindableMatcher<NestedNameSpecifierLoc> loc(
-    const internal::Matcher<NestedNameSpecifier> &InnerMatcher) {
+AST_MATCHER_FUNCTION_P_OVERLOAD(
+    internal::BindableMatcher<NestedNameSpecifierLoc>, loc,
+    internal::Matcher<NestedNameSpecifier>, InnerMatcher, 1) {
   return internal::BindableMatcher<NestedNameSpecifierLoc>(
       new internal::LocMatcher<NestedNameSpecifierLoc, NestedNameSpecifier>(
           InnerMatcher));
@@ -3325,7 +3477,7 @@
 ///   matches "A::"
 AST_MATCHER_P(NestedNameSpecifier, specifiesType,
               internal::Matcher<QualType>, InnerMatcher) {
-  if (Node.getAsType() == NULL)
+  if (!Node.getAsType())
     return false;
   return InnerMatcher.matches(QualType(Node.getAsType(), 0), Finder, Builder);
 }
@@ -3343,7 +3495,7 @@
 ///   matches "A::"
 AST_MATCHER_P(NestedNameSpecifierLoc, specifiesTypeLoc,
               internal::Matcher<TypeLoc>, InnerMatcher) {
-  return InnerMatcher.matches(Node.getTypeLoc(), Finder, Builder);
+  return Node && InnerMatcher.matches(Node.getTypeLoc(), Finder, Builder);
 }
 
 /// \brief Matches on the prefix of a \c NestedNameSpecifier.
@@ -3359,7 +3511,7 @@
                        internal::Matcher<NestedNameSpecifier>, InnerMatcher,
                        0) {
   NestedNameSpecifier *NextNode = Node.getPrefix();
-  if (NextNode == NULL)
+  if (!NextNode)
     return false;
   return InnerMatcher.matches(*NextNode, Finder, Builder);
 }
@@ -3394,7 +3546,7 @@
 ///   matches "ns::"
 AST_MATCHER_P(NestedNameSpecifier, specifiesNamespace,
               internal::Matcher<NamespaceDecl>, InnerMatcher) {
-  if (Node.getAsNamespace() == NULL)
+  if (!Node.getAsNamespace())
     return false;
   return InnerMatcher.matches(*Node.getAsNamespace(), Finder, Builder);
 }
@@ -3406,14 +3558,14 @@
 /// \brief Matches if a node equals another node.
 ///
 /// \c Decl has pointer identity in the AST.
-AST_MATCHER_P_OVERLOAD(Decl, equalsNode, Decl*, Other, 0) {
+AST_MATCHER_P_OVERLOAD(Decl, equalsNode, const Decl*, Other, 0) {
   return &Node == Other;
 }
 /// \brief Matches if a node equals another node.
 ///
 /// \c Stmt has pointer identity in the AST.
 ///
-AST_MATCHER_P_OVERLOAD(Stmt, equalsNode, Stmt*, Other, 1) {
+AST_MATCHER_P_OVERLOAD(Stmt, equalsNode, const Stmt*, Other, 1) {
   return &Node == Other;
 }
 
@@ -3463,11 +3615,9 @@
               internal::Matcher<CXXCtorInitializer>, InnerMatcher) {
   BoundNodesTreeBuilder Result;
   bool Matched = false;
-  for (CXXConstructorDecl::init_const_iterator I = Node.init_begin(),
-                                               E = Node.init_end();
-       I != E; ++I) {
+  for (const auto *I : Node.inits()) {
     BoundNodesTreeBuilder InitBuilder(*Builder);
-    if (InnerMatcher.matches(**I, Finder, &InitBuilder)) {
+    if (InnerMatcher.matches(*I, Finder, &InitBuilder)) {
       Matched = true;
       Result.addMatch(InitBuilder);
     }
diff --git a/include/clang/ASTMatchers/ASTMatchersInternal.h b/include/clang/ASTMatchers/ASTMatchersInternal.h
index 69cee2e..94435fd 100644
--- a/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ b/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -44,7 +44,6 @@
 #include "clang/AST/Type.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/VariadicFunction.h"
-#include "llvm/Support/type_traits.h"
 #include <map>
 #include <string>
 #include <vector>
@@ -52,11 +51,6 @@
 namespace clang {
 namespace ast_matchers {
 
-/// FIXME: Move into the llvm support library.
-template <bool> struct CompileAssert {};
-#define TOOLING_COMPILE_ASSERT(Expr, Msg) \
-  typedef CompileAssert<(bool(Expr))> Msg[bool(Expr) ? 1 : -1]
-
 class BoundNodes;
 
 namespace internal {
@@ -80,7 +74,7 @@
   const T *getNodeAs(StringRef ID) const {
     IDToNodeMap::const_iterator It = NodeMap.find(ID);
     if (It == NodeMap.end()) {
-      return NULL;
+      return nullptr;
     }
     return It->second.get<T>();
   }
@@ -198,9 +192,9 @@
 
 private:
   /// Implements MatcherInterface::Matches.
-  virtual bool matches(const T &Node,
-                       ASTMatchFinder * /* Finder */,
-                       BoundNodesTreeBuilder * /*  Builder */) const {
+  bool matches(const T &Node,
+               ASTMatchFinder * /* Finder */,
+               BoundNodesTreeBuilder * /*  Builder */) const override {
     return matchesNode(Node);
   }
 };
@@ -225,9 +219,8 @@
   /// Requires \c T to be derived from \c From.
   template <typename From>
   Matcher(const Matcher<From> &Other,
-          typename llvm::enable_if_c<
-            llvm::is_base_of<From, T>::value &&
-            !llvm::is_same<From, T>::value >::type* = 0)
+          typename std::enable_if<std::is_base_of<From, T>::value &&
+                                  !std::is_same<From, T>::value>::type * = 0)
       : Implementation(new ImplicitCastMatcher<From>(Other)) {}
 
   /// \brief Implicitly converts \c Matcher<Type> to \c Matcher<QualType>.
@@ -235,9 +228,9 @@
   /// The resulting matcher is not strict, i.e. ignores qualifiers.
   template <typename TypeT>
   Matcher(const Matcher<TypeT> &Other,
-          typename llvm::enable_if_c<
-            llvm::is_same<T, QualType>::value &&
-            llvm::is_same<TypeT, Type>::value >::type* = 0)
+          typename std::enable_if<
+            std::is_same<T, QualType>::value &&
+            std::is_same<TypeT, Type>::value>::type* = 0)
       : Implementation(new TypeToQualType<TypeT>(Other)) {}
 
   /// \brief Forwards the call to the underlying MatcherInterface<T> pointer.
@@ -257,7 +250,7 @@
   uint64_t getID() const {
     /// FIXME: Document the requirements this imposes on matcher
     /// implementations (no new() implementation_ during a Matches()).
-    return reinterpret_cast<uint64_t>(Implementation.getPtr());
+    return reinterpret_cast<uint64_t>(Implementation.get());
   }
 
   /// \brief Allows the conversion of a \c Matcher<Type> to a \c
@@ -272,9 +265,8 @@
     TypeToQualType(const Matcher<TypeT> &InnerMatcher)
         : InnerMatcher(InnerMatcher) {}
 
-    virtual bool matches(const QualType &Node,
-                         ASTMatchFinder *Finder,
-                         BoundNodesTreeBuilder *Builder) const {
+    bool matches(const QualType &Node, ASTMatchFinder *Finder,
+                 BoundNodesTreeBuilder *Builder) const override {
       if (Node.isNull())
         return false;
       return InnerMatcher.matches(*Node, Finder, Builder);
@@ -292,9 +284,8 @@
     explicit ImplicitCastMatcher(const Matcher<Base> &From)
         : From(From) {}
 
-    virtual bool matches(const T &Node,
-                         ASTMatchFinder *Finder,
-                         BoundNodesTreeBuilder *Builder) const {
+    bool matches(const T &Node, ASTMatchFinder *Finder,
+                 BoundNodesTreeBuilder *Builder) const override {
       return From.matches(Node, Finder, Builder);
     }
 
@@ -379,9 +370,7 @@
   ///   matcher can handle a value of T.
   ///
   /// If it is not compatible, then this matcher will never match anything.
-  template <typename T> Matcher<T> unconditionalConvertTo() const {
-    return Matcher<T>(new WrappedMatcher<T>(*this));
-  }
+  template <typename T> Matcher<T> unconditionalConvertTo() const;
 
 private:
   class MatcherStorage : public RefCountedBaseVPTR {
@@ -410,9 +399,6 @@
   /// \brief Typed implementation of \c MatcherStorage.
   template <typename T> class TypedMatcherStorage;
 
-  /// \brief Simple MatcherInterface<T> wrapper around a DynTypedMatcher.
-  template <typename T> class WrappedMatcher;
-
   IntrusiveRefCntPtr<const MatcherStorage> Storage;
 };
 
@@ -425,15 +411,15 @@
         InnerMatcher(Other), AllowBind(AllowBind) {}
 
   bool matches(const ast_type_traits::DynTypedNode DynNode,
-               ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const
-      LLVM_OVERRIDE {
+               ASTMatchFinder *Finder,
+               BoundNodesTreeBuilder *Builder) const override {
     if (const T *Node = DynNode.get<T>()) {
       return InnerMatcher.matches(*Node, Finder, Builder);
     }
     return false;
   }
 
-  llvm::Optional<DynTypedMatcher> tryBind(StringRef ID) const LLVM_OVERRIDE {
+  llvm::Optional<DynTypedMatcher> tryBind(StringRef ID) const override {
     if (!AllowBind)
       return llvm::Optional<DynTypedMatcher>();
     return DynTypedMatcher(BindableMatcher<T>(InnerMatcher).bind(ID));
@@ -452,22 +438,6 @@
 inline DynTypedMatcher::DynTypedMatcher(const BindableMatcher<T> &M)
     : Storage(new TypedMatcherStorage<T>(M, true)) {}
 
-template <typename T>
-class DynTypedMatcher::WrappedMatcher : public MatcherInterface<T> {
-public:
-  explicit WrappedMatcher(const DynTypedMatcher &Matcher) : Inner(Matcher) {}
-  virtual ~WrappedMatcher() {}
-
-  bool matches(const T &Node, ASTMatchFinder *Finder,
-               BoundNodesTreeBuilder *Builder) const {
-    return Inner.matches(ast_type_traits::DynTypedNode::create(Node), Finder,
-                         Builder);
-  }
-
-private:
-  const DynTypedMatcher Inner;
-};
-
 /// \brief Specialization of the conversion functions for QualType.
 ///
 /// These specializations provide the Matcher<Type>->Matcher<QualType>
@@ -537,7 +507,7 @@
   static char (&f(CheckT<int Default::*, &C::getDecl>*))[1];
   template<typename C> static char (&f(...))[2];
 
-  static bool const value = sizeof(f<Derived>(0)) == 2;
+  static bool const value = sizeof(f<Derived>(nullptr)) == 2;
 };
 
 /// \brief Matches overloaded operators with a specific name.
@@ -546,16 +516,17 @@
 /// PolymorphicMatcherWithParam1 and should be StringRef.
 template <typename T, typename ArgT>
 class HasOverloadedOperatorNameMatcher : public SingleNodeMatcherInterface<T> {
-  TOOLING_COMPILE_ASSERT((llvm::is_same<T, CXXOperatorCallExpr>::value ||
-                          llvm::is_same<T, CXXMethodDecl>::value),
-                         unsupported_class_for_matcher);
-  TOOLING_COMPILE_ASSERT((llvm::is_same<ArgT, StringRef>::value),
-                         argument_type_must_be_StringRef);
+  static_assert(std::is_same<T, CXXOperatorCallExpr>::value ||
+                std::is_base_of<FunctionDecl, T>::value,
+                "unsupported class for matcher");
+  static_assert(std::is_same<ArgT, StringRef>::value,
+                "argument type must be StringRef");
+
 public:
   explicit HasOverloadedOperatorNameMatcher(const StringRef Name)
       : SingleNodeMatcherInterface<T>(), Name(Name) {}
 
-  virtual bool matchesNode(const T &Node) const LLVM_OVERRIDE {
+  bool matchesNode(const T &Node) const override {
     return matchesSpecialized(Node);
   }
 
@@ -570,7 +541,7 @@
 
   /// \brief Returns true only if CXXMethodDecl represents an overloaded
   /// operator and has the given operator name.
-  bool matchesSpecialized(const CXXMethodDecl &Node) const {
+  bool matchesSpecialized(const FunctionDecl &Node) const {
     return Node.isOverloadedOperator() &&
            getOperatorSpelling(Node.getOverloadedOperator()) == Name;
   }
@@ -584,16 +555,15 @@
 /// not actually used.
 template <typename T, typename DeclMatcherT>
 class HasDeclarationMatcher : public MatcherInterface<T> {
-  TOOLING_COMPILE_ASSERT((llvm::is_same< DeclMatcherT,
-                                         Matcher<Decl> >::value),
-                          instantiated_with_wrong_types);
+  static_assert(std::is_same<DeclMatcherT, Matcher<Decl>>::value,
+                "instantiated with wrong types");
+
 public:
   explicit HasDeclarationMatcher(const Matcher<Decl> &InnerMatcher)
       : InnerMatcher(InnerMatcher) {}
 
-  virtual bool matches(const T &Node,
-                       ASTMatchFinder *Finder,
-                       BoundNodesTreeBuilder *Builder) const {
+  bool matches(const T &Node, ASTMatchFinder *Finder,
+               BoundNodesTreeBuilder *Builder) const override {
     return matchesSpecialized(Node, Finder, Builder);
   }
 
@@ -603,7 +573,7 @@
   template <typename U>
   bool matchesSpecialized(
       const U &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
-      typename llvm::enable_if<has_getDecl<U>, int>::type = 0) const {
+      typename std::enable_if<has_getDecl<U>::value, int>::type = 0) const {
     return matchesDecl(Node.getDecl(), Finder, Builder);
   }
 
@@ -656,7 +626,7 @@
   bool matchesDecl(const Decl *Node,
                    ASTMatchFinder *Finder,
                    BoundNodesTreeBuilder *Builder) const {
-    return Node != NULL && InnerMatcher.matches(*Node, Finder, Builder);
+    return Node != nullptr && InnerMatcher.matches(*Node, Finder, Builder);
   }
 
   const Matcher<Decl> InnerMatcher;
@@ -667,14 +637,14 @@
 template <typename T>
 struct IsBaseType {
   static const bool value =
-      (llvm::is_same<T, Decl>::value ||
-       llvm::is_same<T, Stmt>::value ||
-       llvm::is_same<T, QualType>::value ||
-       llvm::is_same<T, Type>::value ||
-       llvm::is_same<T, TypeLoc>::value ||
-       llvm::is_same<T, NestedNameSpecifier>::value ||
-       llvm::is_same<T, NestedNameSpecifierLoc>::value ||
-       llvm::is_same<T, CXXCtorInitializer>::value);
+      std::is_same<T, Decl>::value ||
+      std::is_same<T, Stmt>::value ||
+      std::is_same<T, QualType>::value ||
+      std::is_same<T, Type>::value ||
+      std::is_same<T, TypeLoc>::value ||
+      std::is_same<T, NestedNameSpecifier>::value ||
+      std::is_same<T, NestedNameSpecifierLoc>::value ||
+      std::is_same<T, CXXCtorInitializer>::value;
 };
 template <typename T>
 const bool IsBaseType<T>::value;
@@ -740,14 +710,13 @@
                       BoundNodesTreeBuilder *Builder,
                       TraversalKind Traverse,
                       BindKind Bind) {
-    TOOLING_COMPILE_ASSERT(
-        (llvm::is_base_of<Decl, T>::value ||
-         llvm::is_base_of<Stmt, T>::value ||
-         llvm::is_base_of<NestedNameSpecifier, T>::value ||
-         llvm::is_base_of<NestedNameSpecifierLoc, T>::value ||
-         llvm::is_base_of<TypeLoc, T>::value ||
-         llvm::is_base_of<QualType, T>::value),
-        unsupported_type_for_recursive_matching);
+    static_assert(std::is_base_of<Decl, T>::value ||
+                  std::is_base_of<Stmt, T>::value ||
+                  std::is_base_of<NestedNameSpecifier, T>::value ||
+                  std::is_base_of<NestedNameSpecifierLoc, T>::value ||
+                  std::is_base_of<TypeLoc, T>::value ||
+                  std::is_base_of<QualType, T>::value,
+                  "unsupported type for recursive matching");
    return matchesChildOf(ast_type_traits::DynTypedNode::create(Node),
                           Matcher, Builder, Traverse, Bind);
   }
@@ -757,14 +726,13 @@
                            const DynTypedMatcher &Matcher,
                            BoundNodesTreeBuilder *Builder,
                            BindKind Bind) {
-    TOOLING_COMPILE_ASSERT(
-        (llvm::is_base_of<Decl, T>::value ||
-         llvm::is_base_of<Stmt, T>::value ||
-         llvm::is_base_of<NestedNameSpecifier, T>::value ||
-         llvm::is_base_of<NestedNameSpecifierLoc, T>::value ||
-         llvm::is_base_of<TypeLoc, T>::value ||
-         llvm::is_base_of<QualType, T>::value),
-        unsupported_type_for_recursive_matching);
+    static_assert(std::is_base_of<Decl, T>::value ||
+                  std::is_base_of<Stmt, T>::value ||
+                  std::is_base_of<NestedNameSpecifier, T>::value ||
+                  std::is_base_of<NestedNameSpecifierLoc, T>::value ||
+                  std::is_base_of<TypeLoc, T>::value ||
+                  std::is_base_of<QualType, T>::value,
+                  "unsupported type for recursive matching");
     return matchesDescendantOf(ast_type_traits::DynTypedNode::create(Node),
                                Matcher, Builder, Bind);
   }
@@ -775,9 +743,9 @@
                          const DynTypedMatcher &Matcher,
                          BoundNodesTreeBuilder *Builder,
                          AncestorMatchMode MatchMode) {
-    TOOLING_COMPILE_ASSERT((llvm::is_base_of<Decl, T>::value ||
-                            llvm::is_base_of<Stmt, T>::value),
-                           only_Decl_or_Stmt_allowed_for_recursive_matching);
+    static_assert(std::is_base_of<Decl, T>::value ||
+                  std::is_base_of<Stmt, T>::value,
+                  "only Decl or Stmt allowed for recursive matching");
     return matchesAncestorOf(ast_type_traits::DynTypedNode::create(Node),
                              Matcher, Builder, MatchMode);
   }
@@ -820,7 +788,7 @@
   /// \brief The first type on the list.
   typedef T1 head;
 
-  /// \brief A sub list with the tail. ie everything but the head.
+  /// \brief A sublist with the tail. ie everything but the head.
   ///
   /// This type is used to do recursion. TypeList<>/EmptyTypeList indicates the
   /// end of the list.
@@ -852,7 +820,7 @@
 template <typename AnyTypeList, typename T>
 struct TypeListContainsSuperOf {
   static const bool value =
-      llvm::is_base_of<typename AnyTypeList::head, T>::value ||
+      std::is_base_of<typename AnyTypeList::head, T>::value ||
       TypeListContainsSuperOf<typename AnyTypeList::tail, T>::value;
 };
 template <typename T>
@@ -952,8 +920,8 @@
   typedef typename ExtractFunctionArgMeta<ReturnTypesF>::type ReturnTypes;
   template <typename T>
   operator Matcher<T>() const {
-    TOOLING_COMPILE_ASSERT((TypeListContainsSuperOf<ReturnTypes, T>::value),
-                           right_polymorphic_conversion);
+    static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
+                  "right polymorphic conversion");
     return Matcher<T>(new MatcherT<T>());
   }
 };
@@ -970,8 +938,8 @@
 
   template <typename T>
   operator Matcher<T>() const {
-    TOOLING_COMPILE_ASSERT((TypeListContainsSuperOf<ReturnTypes, T>::value),
-                           right_polymorphic_conversion);
+    static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
+                  "right polymorphic conversion");
     return Matcher<T>(new MatcherT<T, P1>(Param1));
   }
 
@@ -991,8 +959,8 @@
 
   template <typename T>
   operator Matcher<T>() const {
-    TOOLING_COMPILE_ASSERT((TypeListContainsSuperOf<ReturnTypes, T>::value),
-                           right_polymorphic_conversion);
+    static_assert(TypeListContainsSuperOf<ReturnTypes, T>::value,
+                  "right polymorphic conversion");
     return Matcher<T>(new MatcherT<T, P1, P2>(Param1, Param2));
   }
 
@@ -1018,7 +986,7 @@
 template <typename T>
 class TrueMatcher : public SingleNodeMatcherInterface<T>  {
 public:
-  virtual bool matchesNode(const T &Node) const {
+  bool matchesNode(const T &Node) const override {
     return true;
   }
 };
@@ -1033,9 +1001,8 @@
   IdMatcher(StringRef ID, const Matcher<T> &InnerMatcher)
       : ID(ID), InnerMatcher(InnerMatcher) {}
 
-  virtual bool matches(const T &Node,
-                       ASTMatchFinder *Finder,
-                       BoundNodesTreeBuilder *Builder) const {
+  bool matches(const T &Node, ASTMatchFinder *Finder,
+               BoundNodesTreeBuilder *Builder) const override {
     bool Result = InnerMatcher.matches(Node, Finder, Builder);
     if (Result) {
       Builder->setBinding(ID, &Node);
@@ -1074,15 +1041,15 @@
 /// ChildT must be an AST base type.
 template <typename T, typename ChildT>
 class HasMatcher : public MatcherInterface<T> {
-  TOOLING_COMPILE_ASSERT(IsBaseType<ChildT>::value,
-                         has_only_accepts_base_type_matcher);
+  static_assert(IsBaseType<ChildT>::value,
+                "has only accepts base type matcher");
+
 public:
   explicit HasMatcher(const Matcher<ChildT> &ChildMatcher)
       : ChildMatcher(ChildMatcher) {}
 
-  virtual bool matches(const T &Node,
-                       ASTMatchFinder *Finder,
-                       BoundNodesTreeBuilder *Builder) const {
+  bool matches(const T &Node, ASTMatchFinder *Finder,
+               BoundNodesTreeBuilder *Builder) const override {
     return Finder->matchesChildOf(
         Node, ChildMatcher, Builder,
         ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,
@@ -1100,15 +1067,15 @@
 /// for each child that matches.
 template <typename T, typename ChildT>
 class ForEachMatcher : public MatcherInterface<T> {
-  TOOLING_COMPILE_ASSERT(IsBaseType<ChildT>::value,
-                         for_each_only_accepts_base_type_matcher);
+  static_assert(IsBaseType<ChildT>::value,
+                "for each only accepts base type matcher");
+
  public:
   explicit ForEachMatcher(const Matcher<ChildT> &ChildMatcher)
       : ChildMatcher(ChildMatcher) {}
 
-  virtual bool matches(const T& Node,
-                       ASTMatchFinder* Finder,
-                       BoundNodesTreeBuilder* Builder) const {
+  bool matches(const T& Node, ASTMatchFinder* Finder,
+               BoundNodesTreeBuilder* Builder) const override {
     return Finder->matchesChildOf(
       Node, ChildMatcher, Builder,
       ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses,
@@ -1119,38 +1086,6 @@
   const Matcher<ChildT> ChildMatcher;
 };
 
-/// \brief Matches nodes of type T if the given Matcher<T> does not match.
-///
-/// Type argument MatcherT is required by PolymorphicMatcherWithParam1
-/// but not actually used. It will always be instantiated with a type
-/// convertible to Matcher<T>.
-template <typename T, typename MatcherT>
-class NotMatcher : public MatcherInterface<T> {
-public:
-  explicit NotMatcher(const Matcher<T> &InnerMatcher)
-      : InnerMatcher(InnerMatcher) {}
-
-  virtual bool matches(const T &Node,
-                       ASTMatchFinder *Finder,
-                       BoundNodesTreeBuilder *Builder) const {
-    // The 'unless' matcher will always discard the result:
-    // If the inner matcher doesn't match, unless returns true,
-    // but the inner matcher cannot have bound anything.
-    // If the inner matcher matches, the result is false, and
-    // any possible binding will be discarded.
-    // We still need to hand in all the bound nodes up to this
-    // point so the inner matcher can depend on bound nodes,
-    // and we need to actively discard the bound nodes, otherwise
-    // the inner matcher will reset the bound nodes if it doesn't
-    // match, but this would be inversed by 'unless'.
-    BoundNodesTreeBuilder Discard(*Builder);
-    return !InnerMatcher.matches(Node, Finder, &Discard);
-  }
-
-private:
-  const Matcher<T> InnerMatcher;
-};
-
 /// \brief VariadicOperatorMatcher related types.
 /// @{
 
@@ -1165,22 +1100,18 @@
 class VariadicOperatorMatcherInterface : public MatcherInterface<T> {
 public:
   VariadicOperatorMatcherInterface(VariadicOperatorFunction Func,
-                                   ArrayRef<const Matcher<T> *> InputMatchers)
-      : Func(Func) {
-    for (size_t i = 0, e = InputMatchers.size(); i != e; ++i) {
-      InnerMatchers.push_back(*InputMatchers[i]);
-    }
-  }
+                                   std::vector<DynTypedMatcher> InnerMatchers)
+      : Func(Func), InnerMatchers(std::move(InnerMatchers)) {}
 
-  virtual bool matches(const T &Node, ASTMatchFinder *Finder,
-                       BoundNodesTreeBuilder *Builder) const {
+  bool matches(const T &Node, ASTMatchFinder *Finder,
+               BoundNodesTreeBuilder *Builder) const override {
     return Func(ast_type_traits::DynTypedNode::create(Node), Finder, Builder,
                 InnerMatchers);
   }
 
 private:
   const VariadicOperatorFunction Func;
-  std::vector<DynTypedMatcher> InnerMatchers;
+  const std::vector<DynTypedMatcher> InnerMatchers;
 };
 
 /// \brief "No argument" placeholder to use as template paratemers.
@@ -1192,46 +1123,55 @@
 /// Input matchers can have any type (including other polymorphic matcher
 /// types), and the actual Matcher<T> is generated on demand with an implicit
 /// coversion operator.
-template <typename P1, typename P2,
+template <typename P1, typename P2 = VariadicOperatorNoArg,
           typename P3 = VariadicOperatorNoArg,
           typename P4 = VariadicOperatorNoArg,
-          typename P5 = VariadicOperatorNoArg>
+          typename P5 = VariadicOperatorNoArg,
+          typename P6 = VariadicOperatorNoArg,
+          typename P7 = VariadicOperatorNoArg,
+          typename P8 = VariadicOperatorNoArg,
+          typename P9 = VariadicOperatorNoArg>
 class VariadicOperatorMatcher {
 public:
   VariadicOperatorMatcher(VariadicOperatorFunction Func, const P1 &Param1,
-                          const P2 &Param2,
+                          const P2 &Param2 = VariadicOperatorNoArg(),
                           const P3 &Param3 = VariadicOperatorNoArg(),
                           const P4 &Param4 = VariadicOperatorNoArg(),
-                          const P5 &Param5 = VariadicOperatorNoArg())
+                          const P5 &Param5 = VariadicOperatorNoArg(),
+                          const P6 &Param6 = VariadicOperatorNoArg(),
+                          const P7 &Param7 = VariadicOperatorNoArg(),
+                          const P8 &Param8 = VariadicOperatorNoArg(),
+                          const P9 &Param9 = VariadicOperatorNoArg())
       : Func(Func), Param1(Param1), Param2(Param2), Param3(Param3),
-        Param4(Param4), Param5(Param5) {}
+        Param4(Param4), Param5(Param5), Param6(Param6), Param7(Param7),
+        Param8(Param8), Param9(Param9) {}
 
   template <typename T> operator Matcher<T>() const {
-    Matcher<T> *Array[5];
-    size_t Size = 0;
-
-    addMatcher<T>(Param1, Array, Size);
-    addMatcher<T>(Param2, Array, Size);
-    addMatcher<T>(Param3, Array, Size);
-    addMatcher<T>(Param4, Array, Size);
-    addMatcher<T>(Param5, Array, Size);
-    Matcher<T> Result(new VariadicOperatorMatcherInterface<T>(
-        Func, ArrayRef<const Matcher<T> *>(Array, Size)));
-    for (size_t i = 0, e = Size; i != e; ++i) delete Array[i];
-    return Result;
+    std::vector<DynTypedMatcher> Matchers;
+    addMatcher<T>(Param1, Matchers);
+    addMatcher<T>(Param2, Matchers);
+    addMatcher<T>(Param3, Matchers);
+    addMatcher<T>(Param4, Matchers);
+    addMatcher<T>(Param5, Matchers);
+    addMatcher<T>(Param6, Matchers);
+    addMatcher<T>(Param7, Matchers);
+    addMatcher<T>(Param8, Matchers);
+    addMatcher<T>(Param9, Matchers);
+    return Matcher<T>(
+        new VariadicOperatorMatcherInterface<T>(Func, std::move(Matchers)));
   }
 
 private:
   template <typename T>
-  static void addMatcher(const Matcher<T> &M, Matcher<T> **Array,
-                         size_t &Size) {
-    Array[Size++] = new Matcher<T>(M);
+  static void addMatcher(const Matcher<T> &M,
+                         std::vector<DynTypedMatcher> &Matchers) {
+    Matchers.push_back(M);
   }
 
   /// \brief Overload to ignore \c VariadicOperatorNoArg arguments.
   template <typename T>
-  static void addMatcher(VariadicOperatorNoArg, Matcher<T> **Array,
-                         size_t &Size) {}
+  static void addMatcher(VariadicOperatorNoArg,
+                         std::vector<DynTypedMatcher> &Matchers) {}
 
   const VariadicOperatorFunction Func;
   const P1 Param1;
@@ -1239,40 +1179,100 @@
   const P3 Param3;
   const P4 Param4;
   const P5 Param5;
+  const P6 Param6;
+  const P7 Param7;
+  const P8 Param8;
+  const P9 Param9;
 };
 
 /// \brief Overloaded function object to generate VariadicOperatorMatcher
 ///   objects from arbitrary matchers.
 ///
-/// It supports 2-5 argument overloaded operator(). More can be added if needed.
+/// It supports 1-9 argument overloaded operator(). More can be added if needed.
+template <unsigned MinCount, unsigned MaxCount>
 struct VariadicOperatorMatcherFunc {
   VariadicOperatorFunction Func;
 
+  template <unsigned Count, typename T>
+  struct EnableIfValidArity
+      : public std::enable_if<MinCount <= Count && Count <= MaxCount, T> {};
+
+  template <typename M1>
+  typename EnableIfValidArity<1, VariadicOperatorMatcher<M1> >::type
+  operator()(const M1 &P1) const {
+    return VariadicOperatorMatcher<M1>(Func, P1);
+  }
   template <typename M1, typename M2>
-  VariadicOperatorMatcher<M1, M2> operator()(const M1 &P1, const M2 &P2) const {
+  typename EnableIfValidArity<2, VariadicOperatorMatcher<M1, M2> >::type
+  operator()(const M1 &P1, const M2 &P2) const {
     return VariadicOperatorMatcher<M1, M2>(Func, P1, P2);
   }
   template <typename M1, typename M2, typename M3>
-  VariadicOperatorMatcher<M1, M2, M3> operator()(const M1 &P1, const M2 &P2,
-                                                 const M3 &P3) const {
+  typename EnableIfValidArity<3, VariadicOperatorMatcher<M1, M2, M3> >::type
+  operator()(const M1 &P1, const M2 &P2, const M3 &P3) const {
     return VariadicOperatorMatcher<M1, M2, M3>(Func, P1, P2, P3);
   }
   template <typename M1, typename M2, typename M3, typename M4>
-  VariadicOperatorMatcher<M1, M2, M3, M4>
+  typename EnableIfValidArity<4, VariadicOperatorMatcher<M1, M2, M3, M4> >::type
   operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4) const {
     return VariadicOperatorMatcher<M1, M2, M3, M4>(Func, P1, P2, P3, P4);
   }
   template <typename M1, typename M2, typename M3, typename M4, typename M5>
-  VariadicOperatorMatcher<M1, M2, M3, M4, M5>
+  typename EnableIfValidArity<
+      5, VariadicOperatorMatcher<M1, M2, M3, M4, M5> >::type
   operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4,
              const M5 &P5) const {
     return VariadicOperatorMatcher<M1, M2, M3, M4, M5>(Func, P1, P2, P3, P4,
                                                        P5);
   }
+  template <typename M1, typename M2, typename M3, typename M4, typename M5,
+            typename M6>
+  typename EnableIfValidArity<
+      6, VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6> >::type
+  operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4,
+             const M5 &P5, const M6 &P6) const {
+    return VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6>(
+        Func, P1, P2, P3, P4, P5, P6);
+  }
+  template <typename M1, typename M2, typename M3, typename M4, typename M5,
+            typename M6, typename M7>
+  typename EnableIfValidArity<
+      7, VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7> >::type
+  operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4,
+             const M5 &P5, const M6 &P6, const M7 &P7) const {
+    return VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7>(
+        Func, P1, P2, P3, P4, P5, P6, P7);
+  }
+  template <typename M1, typename M2, typename M3, typename M4, typename M5,
+            typename M6, typename M7, typename M8>
+  typename EnableIfValidArity<
+      8, VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7, M8> >::type
+  operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4,
+             const M5 &P5, const M6 &P6, const M7 &P7, const M8 &P8) const {
+    return VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7, M8>(
+        Func, P1, P2, P3, P4, P5, P6, P7, P8);
+  }
+  template <typename M1, typename M2, typename M3, typename M4, typename M5,
+            typename M6, typename M7, typename M8, typename M9>
+  typename EnableIfValidArity<
+      9, VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7, M8, M9> >::type
+  operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4,
+             const M5 &P5, const M6 &P6, const M7 &P7, const M8 &P8,
+             const M9 &P9) const {
+    return VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7, M8, M9>(
+        Func, P1, P2, P3, P4, P5, P6, P7, P8, P9);
+  }
 };
 
 /// @}
 
+/// \brief Matches nodes that do not match the provided matcher.
+///
+/// Uses the variadic matcher interface, but fails if InnerMatchers.size()!=1.
+bool NotUnaryOperator(const ast_type_traits::DynTypedNode DynNode,
+                      ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
+                      ArrayRef<DynTypedMatcher> InnerMatchers);
+
 /// \brief Matches nodes for which all provided matchers match.
 bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
                            ASTMatchFinder *Finder,
@@ -1293,12 +1293,22 @@
                            BoundNodesTreeBuilder *Builder,
                            ArrayRef<DynTypedMatcher> InnerMatchers);
 
+template <typename T>
+inline Matcher<T> DynTypedMatcher::unconditionalConvertTo() const {
+  return Matcher<T>(new VariadicOperatorMatcherInterface<T>(
+      AllOfVariadicOperator, llvm::makeArrayRef(*this)));
+}
+
 /// \brief Creates a Matcher<T> that matches if all inner matchers match.
 template<typename T>
 BindableMatcher<T> makeAllOfComposite(
     ArrayRef<const Matcher<T> *> InnerMatchers) {
+  std::vector<DynTypedMatcher> DynMatchers;
+  for (size_t i = 0, e = InnerMatchers.size(); i != e; ++i) {
+    DynMatchers.push_back(*InnerMatchers[i]);
+  }
   return BindableMatcher<T>(new VariadicOperatorMatcherInterface<T>(
-      AllOfVariadicOperator, InnerMatchers));
+      AllOfVariadicOperator, std::move(DynMatchers)));
 }
 
 /// \brief Creates a Matcher<T> that matches if
@@ -1320,15 +1330,15 @@
 /// DescendantT must be an AST base type.
 template <typename T, typename DescendantT>
 class HasDescendantMatcher : public MatcherInterface<T> {
-  TOOLING_COMPILE_ASSERT(IsBaseType<DescendantT>::value,
-                         has_descendant_only_accepts_base_type_matcher);
+  static_assert(IsBaseType<DescendantT>::value,
+                "has descendant only accepts base type matcher");
+
 public:
   explicit HasDescendantMatcher(const Matcher<DescendantT> &DescendantMatcher)
       : DescendantMatcher(DescendantMatcher) {}
 
-  virtual bool matches(const T &Node,
-                       ASTMatchFinder *Finder,
-                       BoundNodesTreeBuilder *Builder) const {
+  bool matches(const T &Node, ASTMatchFinder *Finder,
+               BoundNodesTreeBuilder *Builder) const override {
     return Finder->matchesDescendantOf(
         Node, DescendantMatcher, Builder, ASTMatchFinder::BK_First);
   }
@@ -1343,15 +1353,15 @@
 /// \c ParentT must be an AST base type.
 template <typename T, typename ParentT>
 class HasParentMatcher : public MatcherInterface<T> {
-  TOOLING_COMPILE_ASSERT(IsBaseType<ParentT>::value,
-                         has_parent_only_accepts_base_type_matcher);
+  static_assert(IsBaseType<ParentT>::value,
+                "has parent only accepts base type matcher");
+
 public:
   explicit HasParentMatcher(const Matcher<ParentT> &ParentMatcher)
       : ParentMatcher(ParentMatcher) {}
 
-  virtual bool matches(const T &Node,
-                       ASTMatchFinder *Finder,
-                       BoundNodesTreeBuilder *Builder) const {
+  bool matches(const T &Node, ASTMatchFinder *Finder,
+               BoundNodesTreeBuilder *Builder) const override {
     return Finder->matchesAncestorOf(
         Node, ParentMatcher, Builder, ASTMatchFinder::AMM_ParentOnly);
   }
@@ -1366,15 +1376,15 @@
 /// \c AncestorT must be an AST base type.
 template <typename T, typename AncestorT>
 class HasAncestorMatcher : public MatcherInterface<T> {
-  TOOLING_COMPILE_ASSERT(IsBaseType<AncestorT>::value,
-                         has_ancestor_only_accepts_base_type_matcher);
+  static_assert(IsBaseType<AncestorT>::value,
+                "has ancestor only accepts base type matcher");
+
 public:
   explicit HasAncestorMatcher(const Matcher<AncestorT> &AncestorMatcher)
       : AncestorMatcher(AncestorMatcher) {}
 
-  virtual bool matches(const T &Node,
-                       ASTMatchFinder *Finder,
-                       BoundNodesTreeBuilder *Builder) const {
+  bool matches(const T &Node, ASTMatchFinder *Finder,
+               BoundNodesTreeBuilder *Builder) const override {
     return Finder->matchesAncestorOf(
         Node, AncestorMatcher, Builder, ASTMatchFinder::AMM_All);
   }
@@ -1391,16 +1401,16 @@
 /// for each descendant node that matches instead of only for the first.
 template <typename T, typename DescendantT>
 class ForEachDescendantMatcher : public MatcherInterface<T> {
-  TOOLING_COMPILE_ASSERT(IsBaseType<DescendantT>::value,
-                         for_each_descendant_only_accepts_base_type_matcher);
+  static_assert(IsBaseType<DescendantT>::value,
+                "for each descendant only accepts base type matcher");
+
  public:
   explicit ForEachDescendantMatcher(
       const Matcher<DescendantT>& DescendantMatcher)
       : DescendantMatcher(DescendantMatcher) {}
 
-  virtual bool matches(const T& Node,
-                       ASTMatchFinder* Finder,
-                       BoundNodesTreeBuilder* Builder) const {
+  bool matches(const T& Node, ASTMatchFinder* Finder,
+               BoundNodesTreeBuilder* Builder) const override {
     return Finder->matchesDescendantOf(Node, DescendantMatcher, Builder,
                                        ASTMatchFinder::BK_All);
   }
@@ -1413,17 +1423,17 @@
 /// the value the ValueEqualsMatcher was constructed with.
 template <typename T, typename ValueT>
 class ValueEqualsMatcher : public SingleNodeMatcherInterface<T> {
-  TOOLING_COMPILE_ASSERT((llvm::is_base_of<CharacterLiteral, T>::value ||
-                         llvm::is_base_of<CXXBoolLiteralExpr,
-                                          T>::value ||
-                         llvm::is_base_of<FloatingLiteral, T>::value ||
-                         llvm::is_base_of<IntegerLiteral, T>::value),
-                         the_node_must_have_a_getValue_method);
+  static_assert(std::is_base_of<CharacterLiteral, T>::value ||
+                std::is_base_of<CXXBoolLiteralExpr, T>::value ||
+                std::is_base_of<FloatingLiteral, T>::value ||
+                std::is_base_of<IntegerLiteral, T>::value,
+                "the node must have a getValue method");
+
 public:
   explicit ValueEqualsMatcher(const ValueT &ExpectedValue)
       : ExpectedValue(ExpectedValue) {}
 
-  virtual bool matchesNode(const T &Node) const {
+  bool matchesNode(const T &Node) const override {
     return Node.getValue() == ExpectedValue;
   }
 
@@ -1478,9 +1488,8 @@
   explicit LocMatcher(const Matcher<T> &InnerMatcher)
     : InnerMatcher(InnerMatcher) {}
 
-  virtual bool matches(const TLoc &Node,
-                       ASTMatchFinder *Finder,
-                       BoundNodesTreeBuilder *Builder) const {
+  bool matches(const TLoc &Node, ASTMatchFinder *Finder,
+               BoundNodesTreeBuilder *Builder) const override {
     if (!Node)
       return false;
     return InnerMatcher.matches(*extract(Node), Finder, Builder);
@@ -1503,9 +1512,8 @@
   explicit TypeLocTypeMatcher(const Matcher<QualType> &InnerMatcher)
       : InnerMatcher(InnerMatcher) {}
 
-  virtual bool matches(const TypeLoc &Node,
-                       ASTMatchFinder *Finder,
-                       BoundNodesTreeBuilder *Builder) const {
+  bool matches(const TypeLoc &Node, ASTMatchFinder *Finder,
+               BoundNodesTreeBuilder *Builder) const override {
     if (!Node)
       return false;
     return InnerMatcher.matches(Node.getType(), Finder, Builder);
@@ -1525,9 +1533,8 @@
                                QualType (T::*TraverseFunction)() const)
       : InnerMatcher(InnerMatcher), TraverseFunction(TraverseFunction) {}
 
-  virtual bool matches(const T &Node,
-                       ASTMatchFinder *Finder,
-                       BoundNodesTreeBuilder *Builder) const {
+  bool matches(const T &Node, ASTMatchFinder *Finder,
+               BoundNodesTreeBuilder *Builder) const override {
     QualType NextNode = (Node.*TraverseFunction)();
     if (NextNode.isNull())
       return false;
@@ -1549,9 +1556,8 @@
                                   TypeLoc (T::*TraverseFunction)() const)
       : InnerMatcher(InnerMatcher), TraverseFunction(TraverseFunction) {}
 
-  virtual bool matches(const T &Node,
-                       ASTMatchFinder *Finder,
-                       BoundNodesTreeBuilder *Builder) const {
+  bool matches(const T &Node, ASTMatchFinder *Finder,
+               BoundNodesTreeBuilder *Builder) const override {
     TypeLoc NextNode = (Node.*TraverseFunction)();
     if (!NextNode)
       return false;
@@ -1612,6 +1618,26 @@
   return Self(InnerMatchers);
 }
 
+// FIXME: unify ClassTemplateSpecializationDecl and TemplateSpecializationType's
+// APIs for accessing the template argument list.
+inline ArrayRef<TemplateArgument>
+getTemplateSpecializationArgs(const ClassTemplateSpecializationDecl &D) {
+  return D.getTemplateArgs().asArray();
+}
+
+inline ArrayRef<TemplateArgument>
+getTemplateSpecializationArgs(const TemplateSpecializationType &T) {
+  return ArrayRef<TemplateArgument>(T.getArgs(), T.getNumArgs());
+}
+
+struct NotEqualsBoundNodePredicate {
+  bool operator()(const internal::BoundNodesMap &Nodes) const {
+    return Nodes.getNode(ID) != Node;
+  }
+  std::string ID;
+  ast_type_traits::DynTypedNode Node;
+};
+
 } // end namespace internal
 } // end namespace ast_matchers
 } // end namespace clang
diff --git a/include/clang/ASTMatchers/ASTMatchersMacros.h b/include/clang/ASTMatchers/ASTMatchersMacros.h
index b5d5303..563372a 100644
--- a/include/clang/ASTMatchers/ASTMatchersMacros.h
+++ b/include/clang/ASTMatchers/ASTMatchersMacros.h
@@ -37,6 +37,25 @@
 #ifndef LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_MACROS_H
 #define LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_MACROS_H
 
+/// \brief AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param) {
+/// defines a single-parameter function named DefineMatcher() that returns a
+/// ReturnType object.
+///
+/// The code between the curly braces has access to the following variables:
+///
+///   Param:                 the parameter passed to the function; its type
+///                          is ParamType.
+///
+/// The code should return an instance of ReturnType.
+#define AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param)    \
+  AST_MATCHER_FUNCTION_P_OVERLOAD(ReturnType, DefineMatcher, ParamType, Param, \
+                                  0)
+#define AST_MATCHER_FUNCTION_P_OVERLOAD(ReturnType, DefineMatcher, ParamType,  \
+                                        Param, OverloadId)                     \
+  inline ReturnType DefineMatcher(ParamType const &Param);                     \
+  typedef ReturnType (&DefineMatcher##_Type##OverloadId)(ParamType const &);   \
+  inline ReturnType DefineMatcher(ParamType const &Param)
+
 /// \brief AST_MATCHER(Type, DefineMatcher) { ... }
 /// defines a zero parameter function named DefineMatcher() that returns a
 /// Matcher<Type> object.
@@ -53,8 +72,8 @@
   class matcher_##DefineMatcher##Matcher : public MatcherInterface<Type> {     \
   public:                                                                      \
     explicit matcher_##DefineMatcher##Matcher() {}                             \
-    virtual bool matches(const Type &Node, ASTMatchFinder *Finder,             \
-                         BoundNodesTreeBuilder *Builder) const;                \
+    bool matches(const Type &Node, ASTMatchFinder *Finder,                     \
+                 BoundNodesTreeBuilder *Builder) const override;               \
   };                                                                           \
   }                                                                            \
   inline internal::Matcher<Type> DefineMatcher() {                             \
@@ -88,21 +107,21 @@
       : public MatcherInterface<Type> {                                        \
   public:                                                                      \
     explicit matcher_##DefineMatcher##OverloadId##Matcher(                     \
-        const ParamType &A##Param)                                             \
+        ParamType const &A##Param)                                             \
         : Param(A##Param) {}                                                   \
-    virtual bool matches(const Type &Node, ASTMatchFinder *Finder,             \
-                         BoundNodesTreeBuilder *Builder) const;                \
+    bool matches(const Type &Node, ASTMatchFinder *Finder,                     \
+                 BoundNodesTreeBuilder *Builder) const override;               \
                                                                                \
   private:                                                                     \
-    const ParamType Param;                                                     \
+    ParamType const Param;                                                     \
   };                                                                           \
   }                                                                            \
-  inline internal::Matcher<Type> DefineMatcher(const ParamType &Param) {       \
+  inline internal::Matcher<Type> DefineMatcher(ParamType const &Param) {       \
     return internal::makeMatcher(                                              \
         new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param));    \
   }                                                                            \
   typedef internal::Matcher<Type>(&DefineMatcher##_Type##OverloadId)(          \
-      const ParamType &Param);                                                 \
+      ParamType const &Param);                                                 \
   inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
       const Type &Node, ASTMatchFinder *Finder,                                \
       BoundNodesTreeBuilder *Builder) const
@@ -132,25 +151,25 @@
   class matcher_##DefineMatcher##OverloadId##Matcher                           \
       : public MatcherInterface<Type> {                                        \
   public:                                                                      \
-    matcher_##DefineMatcher##OverloadId##Matcher(const ParamType1 &A##Param1,  \
-                                                 const ParamType2 &A##Param2)  \
+    matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1,  \
+                                                 ParamType2 const &A##Param2)  \
         : Param1(A##Param1), Param2(A##Param2) {}                              \
-    virtual bool matches(const Type &Node, ASTMatchFinder *Finder,             \
-                         BoundNodesTreeBuilder *Builder) const;                \
+    bool matches(const Type &Node, ASTMatchFinder *Finder,                     \
+                 BoundNodesTreeBuilder *Builder) const override;               \
                                                                                \
   private:                                                                     \
-    const ParamType1 Param1;                                                   \
-    const ParamType2 Param2;                                                   \
+    ParamType1 const Param1;                                                   \
+    ParamType2 const Param2;                                                   \
   };                                                                           \
   }                                                                            \
-  inline internal::Matcher<Type> DefineMatcher(const ParamType1 &Param1,       \
-                                               const ParamType2 &Param2) {     \
+  inline internal::Matcher<Type> DefineMatcher(ParamType1 const &Param1,       \
+                                               ParamType2 const &Param2) {     \
     return internal::makeMatcher(                                              \
         new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param1,     \
                                                                    Param2));   \
   }                                                                            \
   typedef internal::Matcher<Type>(&DefineMatcher##_Type##OverloadId)(          \
-      const ParamType1 &Param1, const ParamType2 &Param2);                     \
+      ParamType1 const &Param1, ParamType2 const &Param2);                     \
   inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
       const Type &Node, ASTMatchFinder *Finder,                                \
       BoundNodesTreeBuilder *Builder) const
@@ -184,8 +203,8 @@
   template <typename NodeType>                                                 \
   class matcher_##DefineMatcher##Matcher : public MatcherInterface<NodeType> { \
   public:                                                                      \
-    virtual bool matches(const NodeType &Node, ASTMatchFinder *Finder,         \
-                         BoundNodesTreeBuilder *Builder) const;                \
+    bool matches(const NodeType &Node, ASTMatchFinder *Finder,                 \
+                 BoundNodesTreeBuilder *Builder) const override;               \
   };                                                                           \
   }                                                                            \
   inline internal::PolymorphicMatcherWithParam0<                               \
@@ -221,18 +240,18 @@
       : public MatcherInterface<NodeType> {                                    \
   public:                                                                      \
     explicit matcher_##DefineMatcher##OverloadId##Matcher(                     \
-        const ParamType &A##Param)                                             \
+        ParamType const &A##Param)                                             \
         : Param(A##Param) {}                                                   \
-    virtual bool matches(const NodeType &Node, ASTMatchFinder *Finder,         \
-                         BoundNodesTreeBuilder *Builder) const;                \
+    bool matches(const NodeType &Node, ASTMatchFinder *Finder,                 \
+                 BoundNodesTreeBuilder *Builder) const override;               \
                                                                                \
   private:                                                                     \
-    const ParamType Param;                                                     \
+    ParamType const Param;                                                     \
   };                                                                           \
   }                                                                            \
   inline internal::PolymorphicMatcherWithParam1<                               \
       internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType,       \
-      ReturnTypesF> DefineMatcher(const ParamType &Param) {                    \
+      ReturnTypesF> DefineMatcher(ParamType const &Param) {                    \
     return internal::PolymorphicMatcherWithParam1<                             \
         internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType,     \
         ReturnTypesF>(Param);                                                  \
@@ -240,7 +259,7 @@
   typedef internal::PolymorphicMatcherWithParam1<                              \
       internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType,       \
       ReturnTypesF>(&DefineMatcher##_Type##OverloadId)(                        \
-      const ParamType &Param);                                                 \
+      ParamType const &Param);                                                 \
   template <typename NodeType, typename ParamT>                                \
   bool internal::matcher_##DefineMatcher##OverloadId##Matcher<                 \
       NodeType, ParamT>::matches(const NodeType &Node, ASTMatchFinder *Finder, \
@@ -267,21 +286,21 @@
   class matcher_##DefineMatcher##OverloadId##Matcher                           \
       : public MatcherInterface<NodeType> {                                    \
   public:                                                                      \
-    matcher_##DefineMatcher##OverloadId##Matcher(const ParamType1 &A##Param1,  \
-                                                 const ParamType2 &A##Param2)  \
+    matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1,  \
+                                                 ParamType2 const &A##Param2)  \
         : Param1(A##Param1), Param2(A##Param2) {}                              \
-    virtual bool matches(const NodeType &Node, ASTMatchFinder *Finder,         \
-                         BoundNodesTreeBuilder *Builder) const;                \
+     bool matches(const NodeType &Node, ASTMatchFinder *Finder,                \
+                  BoundNodesTreeBuilder *Builder) const override;              \
                                                                                \
   private:                                                                     \
-    const ParamType1 Param1;                                                   \
-    const ParamType2 Param2;                                                   \
+    ParamType1 const Param1;                                                   \
+    ParamType2 const Param2;                                                   \
   };                                                                           \
   }                                                                            \
   inline internal::PolymorphicMatcherWithParam2<                               \
       internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1,      \
-      ParamType2, ReturnTypesF> DefineMatcher(const ParamType1 &Param1,        \
-                                              const ParamType2 &Param2) {      \
+      ParamType2, ReturnTypesF> DefineMatcher(ParamType1 const &Param1,        \
+                                              ParamType2 const &Param2) {      \
     return internal::PolymorphicMatcherWithParam2<                             \
         internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1,    \
         ParamType2, ReturnTypesF>(Param1, Param2);                             \
@@ -289,7 +308,7 @@
   typedef internal::PolymorphicMatcherWithParam2<                              \
       internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1,      \
       ParamType2, ReturnTypesF>(&DefineMatcher##_Type##OverloadId)(            \
-      const ParamType1 &Param1, const ParamType2 &Param2);                     \
+      ParamType1 const &Param1, ParamType2 const &Param2);                     \
   template <typename NodeType, typename ParamT1, typename ParamT2>             \
   bool internal::matcher_##DefineMatcher##OverloadId##Matcher<                 \
       NodeType, ParamT1, ParamT2>::matches(                                    \
diff --git a/include/clang/ASTMatchers/Dynamic/Diagnostics.h b/include/clang/ASTMatchers/Dynamic/Diagnostics.h
index aec0c0e..82a14f1 100644
--- a/include/clang/ASTMatchers/Dynamic/Diagnostics.h
+++ b/include/clang/ASTMatchers/Dynamic/Diagnostics.h
@@ -15,15 +15,14 @@
 #ifndef LLVM_CLANG_AST_MATCHERS_DYNAMIC_DIAGNOSTICS_H
 #define LLVM_CLANG_AST_MATCHERS_DYNAMIC_DIAGNOSTICS_H
 
-#include <string>
-#include <vector>
-
 #include "clang/ASTMatchers/Dynamic/VariantValue.h"
 #include "clang/Basic/LLVM.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/Support/raw_ostream.h"
+#include <string>
+#include <vector>
 
 namespace clang {
 namespace ast_matchers {
@@ -61,11 +60,12 @@
   enum ErrorType {
     ET_None = 0,
 
-    ET_RegistryNotFound = 1,
+    ET_RegistryMatcherNotFound = 1,
     ET_RegistryWrongArgCount = 2,
     ET_RegistryWrongArgType = 3,
     ET_RegistryNotBindable = 4,
     ET_RegistryAmbiguousOverload = 5,
+    ET_RegistryValueNotFound = 6,
 
     ET_ParserStringError = 100,
     ET_ParserNoOpenParen = 101,
diff --git a/include/clang/ASTMatchers/Dynamic/Parser.h b/include/clang/ASTMatchers/Dynamic/Parser.h
index bb6ac76..4045f57 100644
--- a/include/clang/ASTMatchers/Dynamic/Parser.h
+++ b/include/clang/ASTMatchers/Dynamic/Parser.h
@@ -18,13 +18,14 @@
 ///
 /// \code
 /// Grammar for the expressions supported:
-/// <Expression>        := <Literal> | <MatcherExpression>
+/// <Expression>        := <Literal> | <NamedValue> | <MatcherExpression>
 /// <Literal>           := <StringLiteral> | <Unsigned>
 /// <StringLiteral>     := "quoted string"
 /// <Unsigned>          := [0-9]+
-/// <MatcherExpression> := <MatcherName>(<ArgumentList>) |
-///                        <MatcherName>(<ArgumentList>).bind(<StringLiteral>)
-/// <MatcherName>       := [a-zA-Z]+
+/// <NamedValue>        := <Identifier>
+/// <MatcherExpression> := <Identifier>(<ArgumentList>) |
+///                        <Identifier>(<ArgumentList>).bind(<StringLiteral>)
+/// <Identifier>        := [a-zA-Z]+
 /// <ArgumentList>      := <Expression> | <Expression>,<ArgumentList>
 /// \endcode
 ///
@@ -34,6 +35,7 @@
 #define LLVM_CLANG_AST_MATCHERS_DYNAMIC_PARSER_H
 
 #include "clang/ASTMatchers/Dynamic/Diagnostics.h"
+#include "clang/ASTMatchers/Dynamic/Registry.h"
 #include "clang/ASTMatchers/Dynamic/VariantValue.h"
 #include "clang/Basic/LLVM.h"
 #include "llvm/ADT/ArrayRef.h"
@@ -61,11 +63,22 @@
   public:
     virtual ~Sema();
 
+    /// \brief Lookup a value by name.
+    ///
+    /// This can be used in the Sema layer to declare known constants or to
+    /// allow to split an expression in pieces.
+    ///
+    /// \param Name The name of the value to lookup.
+    ///
+    /// \return The named value. It could be any type that VariantValue
+    ///   supports. An empty value means that the name is not recognized.
+    virtual VariantValue getNamedValue(StringRef Name);
+
     /// \brief Process a matcher expression.
     ///
     /// All the arguments passed here have already been processed.
     ///
-    /// \param MatcherName The matcher name found by the parser.
+    /// \param Ctor A matcher constructor looked up by lookupMatcherCtor.
     ///
     /// \param NameRange The location of the name in the matcher source.
     ///   Useful for error reporting.
@@ -78,11 +91,36 @@
     /// \return The matcher objects constructed by the processor, or a null
     ///   matcher if an error occurred. In that case, \c Error will contain a
     ///   description of the error.
-    virtual VariantMatcher actOnMatcherExpression(StringRef MatcherName,
+    virtual VariantMatcher actOnMatcherExpression(MatcherCtor Ctor,
                                                   const SourceRange &NameRange,
                                                   StringRef BindID,
                                                   ArrayRef<ParserValue> Args,
                                                   Diagnostics *Error) = 0;
+
+    /// \brief Look up a matcher by name.
+    ///
+    /// \param MatcherName The matcher name found by the parser.
+    ///
+    /// \return The matcher constructor, or Optional<MatcherCtor>() if not
+    /// found.
+    virtual llvm::Optional<MatcherCtor>
+    lookupMatcherCtor(StringRef MatcherName) = 0;
+  };
+
+  /// \brief Sema implementation that uses the matcher registry to process the
+  ///   tokens.
+  class RegistrySema : public Parser::Sema {
+   public:
+    virtual ~RegistrySema();
+
+    llvm::Optional<MatcherCtor>
+    lookupMatcherCtor(StringRef MatcherName) override;
+
+    VariantMatcher actOnMatcherExpression(MatcherCtor Ctor,
+                                          const SourceRange &NameRange,
+                                          StringRef BindID,
+                                          ArrayRef<ParserValue> Args,
+                                          Diagnostics *Error) override;
   };
 
   /// \brief Parse a matcher expression, creating matchers from the registry.
@@ -129,19 +167,37 @@
   static bool parseExpression(StringRef Code, Sema *S,
                               VariantValue *Value, Diagnostics *Error);
 
+  /// \brief Complete an expression at the given offset.
+  ///
+  /// \return The list of completions, which may be empty if there are no
+  /// available completions or if an error occurred.
+  static std::vector<MatcherCompletion>
+  completeExpression(StringRef Code, unsigned CompletionOffset);
+
 private:
   class CodeTokenizer;
+  struct ScopedContextEntry;
   struct TokenInfo;
 
   Parser(CodeTokenizer *Tokenizer, Sema *S,
          Diagnostics *Error);
 
   bool parseExpressionImpl(VariantValue *Value);
-  bool parseMatcherExpressionImpl(VariantValue *Value);
+  bool parseMatcherExpressionImpl(const TokenInfo &NameToken,
+                                  VariantValue *Value);
+  bool parseIdentifierPrefixImpl(VariantValue *Value);
+
+  void addCompletion(const TokenInfo &CompToken, StringRef TypedText,
+                     StringRef Decl);
+  void addExpressionCompletions();
 
   CodeTokenizer *const Tokenizer;
   Sema *const S;
   Diagnostics *const Error;
+
+  typedef std::vector<std::pair<MatcherCtor, unsigned> > ContextStackTy;
+  ContextStackTy ContextStack;
+  std::vector<MatcherCompletion> Completions;
 };
 
 }  // namespace dynamic
diff --git a/include/clang/ASTMatchers/Dynamic/Registry.h b/include/clang/ASTMatchers/Dynamic/Registry.h
index c113c14..faa9254 100644
--- a/include/clang/ASTMatchers/Dynamic/Registry.h
+++ b/include/clang/ASTMatchers/Dynamic/Registry.h
@@ -21,20 +21,69 @@
 #include "clang/ASTMatchers/Dynamic/VariantValue.h"
 #include "clang/Basic/LLVM.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
 #include "llvm/ADT/StringRef.h"
 
 namespace clang {
 namespace ast_matchers {
 namespace dynamic {
 
+namespace internal {
+class MatcherDescriptor;
+}
+
+typedef const internal::MatcherDescriptor *MatcherCtor;
+
+struct MatcherCompletion {
+  MatcherCompletion() {}
+  MatcherCompletion(StringRef TypedText, StringRef MatcherDecl)
+      : TypedText(TypedText), MatcherDecl(MatcherDecl) {}
+
+  /// \brief The text to type to select this matcher.
+  std::string TypedText;
+
+  /// \brief The "declaration" of the matcher, with type information.
+  std::string MatcherDecl;
+
+  bool operator==(const MatcherCompletion &Other) const {
+    return TypedText == Other.TypedText && MatcherDecl == Other.MatcherDecl;
+  }
+};
+
 class Registry {
 public:
-  /// \brief Construct a matcher from the registry by name.
+  /// \brief Look up a matcher in the registry by name,
   ///
-  /// Consult the registry of known matchers and construct the appropriate
-  /// matcher by name.
+  /// \return An opaque value which may be used to refer to the matcher
+  /// constructor, or Optional<MatcherCtor>() if not found.
+  static llvm::Optional<MatcherCtor> lookupMatcherCtor(StringRef MatcherName);
+
+  /// \brief Compute the list of completions for \p Context.
   ///
-  /// \param MatcherName The name of the matcher to instantiate.
+  /// Each element of \p Context represents a matcher invocation, going from
+  /// outermost to innermost. Elements are pairs consisting of a reference to the
+  /// matcher constructor and the index of the next element in the argument list
+  /// of that matcher (or for the last element, the index of the completion
+  /// point in the argument list). An empty list requests completion for the
+  /// root matcher.
+  ///
+  /// The completions are ordered first by decreasing relevance, then
+  /// alphabetically.  Relevance is determined by how closely the matcher's
+  /// type matches that of the context. For example, if the innermost matcher
+  /// takes a FunctionDecl matcher, the FunctionDecl matchers are returned
+  /// first, followed by the ValueDecl matchers, then NamedDecl, then Decl, then
+  /// polymorphic matchers.
+  ///
+  /// Matchers which are technically convertible to the innermost context but
+  /// which would match either all or no nodes are excluded. For example,
+  /// namedDecl and varDecl are excluded in a FunctionDecl context, because
+  /// those matchers would match respectively all or no nodes in such a context.
+  static std::vector<MatcherCompletion>
+  getCompletions(ArrayRef<std::pair<MatcherCtor, unsigned> > Context);
+
+  /// \brief Construct a matcher from the registry.
+  ///
+  /// \param Ctor The matcher constructor to instantiate.
   ///
   /// \param NameRange The location of the name in the matcher source.
   ///   Useful for error reporting.
@@ -44,10 +93,10 @@
   ///   will return an error.
   ///
   /// \return The matcher object constructed if no error was found.
-  ///   A null matcher if the matcher is not found, or if the number of
-  ///   arguments or argument types do not match the signature.
-  ///   In that case \c Error will contain the description of the error.
-  static VariantMatcher constructMatcher(StringRef MatcherName,
+  ///   A null matcher if the number of arguments or argument types do not match
+  ///   the signature.  In that case \c Error will contain the description of
+  ///   the error.
+  static VariantMatcher constructMatcher(MatcherCtor Ctor,
                                          const SourceRange &NameRange,
                                          ArrayRef<ParserValue> Args,
                                          Diagnostics *Error);
@@ -58,7 +107,7 @@
   /// matcher to the specified \c BindID.
   /// If the matcher is not bindable, it sets an error in \c Error and returns
   /// a null matcher.
-  static VariantMatcher constructBoundMatcher(StringRef MatcherName,
+  static VariantMatcher constructBoundMatcher(MatcherCtor Ctor,
                                               const SourceRange &NameRange,
                                               StringRef BindID,
                                               ArrayRef<ParserValue> Args,
diff --git a/include/clang/ASTMatchers/Dynamic/VariantValue.h b/include/clang/ASTMatchers/Dynamic/VariantValue.h
index b9bc017..b25267b 100644
--- a/include/clang/ASTMatchers/Dynamic/VariantValue.h
+++ b/include/clang/ASTMatchers/Dynamic/VariantValue.h
@@ -17,14 +17,13 @@
 #ifndef LLVM_CLANG_AST_MATCHERS_DYNAMIC_VARIANT_VALUE_H
 #define LLVM_CLANG_AST_MATCHERS_DYNAMIC_VARIANT_VALUE_H
 
-#include <vector>
-
 #include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/ASTMatchers/ASTMatchersInternal.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/Twine.h"
-#include "llvm/Support/type_traits.h"
+#include <memory>
+#include <vector>
 
 namespace clang {
 namespace ast_matchers {
@@ -50,7 +49,8 @@
   class MatcherOps {
   public:
     virtual ~MatcherOps();
-    virtual bool canConstructFrom(const DynTypedMatcher &Matcher) const = 0;
+    virtual bool canConstructFrom(const DynTypedMatcher &Matcher,
+                                  bool &IsExactMatch) const = 0;
     virtual void constructFrom(const DynTypedMatcher &Matcher) = 0;
     virtual void constructVariadicOperator(
         ast_matchers::internal::VariadicOperatorFunction Func,
@@ -78,14 +78,15 @@
   /// \brief Clones the provided matchers.
   ///
   /// They should be the result of a polymorphic matcher.
-  static VariantMatcher PolymorphicMatcher(ArrayRef<DynTypedMatcher> Matchers);
+  static VariantMatcher
+  PolymorphicMatcher(std::vector<DynTypedMatcher> Matchers);
 
   /// \brief Creates a 'variadic' operator matcher.
   ///
   /// It will bind to the appropriate type on getTypedMatcher<T>().
   static VariantMatcher VariadicOperatorMatcher(
       ast_matchers::internal::VariadicOperatorFunction Func,
-      ArrayRef<VariantMatcher> Args);
+      std::vector<VariantMatcher> Args);
 
   /// \brief Makes the matcher the "null" matcher.
   void reset();
@@ -145,7 +146,10 @@
   public:
     typedef ast_matchers::internal::Matcher<T> MatcherT;
 
-    virtual bool canConstructFrom(const DynTypedMatcher &Matcher) const {
+    virtual bool canConstructFrom(const DynTypedMatcher &Matcher,
+                                  bool &IsExactMatch) const {
+      IsExactMatch = Matcher.getSupportedKind().isSame(
+          ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
       return Matcher.canConvertTo<T>();
     }
 
@@ -156,34 +160,25 @@
     virtual void constructVariadicOperator(
         ast_matchers::internal::VariadicOperatorFunction Func,
         ArrayRef<VariantMatcher> InnerMatchers) {
-      const size_t NumArgs = InnerMatchers.size();
-      MatcherT **InnerArgs = new MatcherT *[NumArgs]();
-      bool HasError = false;
-      for (size_t i = 0; i != NumArgs; ++i) {
+      std::vector<DynTypedMatcher> DynMatchers;
+      for (size_t i = 0, e = InnerMatchers.size(); i != e; ++i) {
         // Abort if any of the inner matchers can't be converted to
         // Matcher<T>.
         if (!InnerMatchers[i].hasTypedMatcher<T>()) {
-          HasError = true;
-          break;
+          return;
         }
-        InnerArgs[i] = new MatcherT(InnerMatchers[i].getTypedMatcher<T>());
+        DynMatchers.push_back(InnerMatchers[i].getTypedMatcher<T>());
       }
-      if (!HasError) {
-        Out.reset(new MatcherT(
-            new ast_matchers::internal::VariadicOperatorMatcherInterface<T>(
-                Func, ArrayRef<const MatcherT *>(InnerArgs, NumArgs))));
-      }
-      for (size_t i = 0; i != NumArgs; ++i) {
-        delete InnerArgs[i];
-      }
-      delete[] InnerArgs;
+      Out.reset(new MatcherT(
+          new ast_matchers::internal::VariadicOperatorMatcherInterface<T>(
+              Func, DynMatchers)));
     }
 
-    bool hasMatcher() const { return Out.get() != NULL; }
+    bool hasMatcher() const { return Out.get() != nullptr; }
     const MatcherT &matcher() const { return *Out; }
 
   private:
-    OwningPtr<MatcherT> Out;
+    std::unique_ptr<MatcherT> Out;
   };
 
   IntrusiveRefCntPtr<const Payload> Value;
@@ -214,6 +209,10 @@
   VariantValue(const std::string &String);
   VariantValue(const VariantMatcher &Matchers);
 
+  /// \brief Returns true iff this is not an empty value.
+  LLVM_EXPLICIT operator bool() const { return hasValue(); }
+  bool hasValue() const { return Type != VT_Nothing; }
+
   /// \brief Unsigned value functions.
   bool isUnsigned() const;
   unsigned getUnsigned() const;
diff --git a/include/clang/Analysis/Analyses/Consumed.h b/include/clang/Analysis/Analyses/Consumed.h
index 23a094a..36e07c2 100644
--- a/include/clang/Analysis/Analyses/Consumed.h
+++ b/include/clang/Analysis/Analyses/Consumed.h
@@ -18,8 +18,8 @@
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/StmtCXX.h"
-#include "clang/Analysis/AnalysisContext.h"
 #include "clang/Analysis/Analyses/PostOrderCFGView.h"
+#include "clang/Analysis/AnalysisContext.h"
 #include "clang/Basic/SourceLocation.h"
 
 namespace clang {
@@ -142,7 +142,7 @@
     TmpMapType TmpMap;
     
   public:
-    ConsumedStateMap() : Reachable(true), From(NULL) {}
+    ConsumedStateMap() : Reachable(true), From(nullptr) {}
     ConsumedStateMap(const ConsumedStateMap &Other)
       : Reachable(Other.Reachable), From(Other.From), VarMap(Other.VarMap),
         TmpMap() {}
@@ -185,8 +185,8 @@
     /// \brief Set the consumed state of a given temporary value.
     void setState(const CXXBindTemporaryExpr *Tmp, ConsumedState State);
     
-    /// \brief Remove the variable from our state map.
-    void remove(const VarDecl *Var);
+    /// \brief Remove the temporary value from our state map.
+    void remove(const CXXBindTemporaryExpr *Tmp);
     
     /// \brief Tests to see if there is a mismatch in the states stored in two
     /// maps.
@@ -201,9 +201,10 @@
     
   public:
     ConsumedBlockInfo() { }
-    
+    ~ConsumedBlockInfo() { llvm::DeleteContainerPointers(StateMapsArray); }
+
     ConsumedBlockInfo(unsigned int NumBlocks, PostOrderCFGView *SortedGraph)
-        : StateMapsArray(NumBlocks, 0), VisitOrder(NumBlocks, 0) {
+        : StateMapsArray(NumBlocks, nullptr), VisitOrder(NumBlocks, 0) {
       unsigned int VisitOrderCounter = 0;
       for (PostOrderCFGView::iterator BI = SortedGraph->begin(),
            BE = SortedGraph->end(); BI != BE; ++BI) {
diff --git a/include/clang/Analysis/Analyses/Dominators.h b/include/clang/Analysis/Analyses/Dominators.h
index 2a806c8..6c6d923 100644
--- a/include/clang/Analysis/Analyses/Dominators.h
+++ b/include/clang/Analysis/Analyses/Dominators.h
@@ -17,9 +17,15 @@
 #include "clang/Analysis/AnalysisContext.h"
 #include "clang/Analysis/CFG.h"
 #include "llvm/ADT/GraphTraits.h"
-#include "llvm/Analysis/DominatorInternals.h"
-#include "llvm/Analysis/Dominators.h"
-#include "llvm/IR/Module.h"
+#include "llvm/Support/GenericDomTree.h"
+#include "llvm/Support/GenericDomTreeConstruction.h"
+
+// FIXME: There is no good reason for the domtree to require a print method
+// which accepts an LLVM Module, so remove this (and the method's argument that
+// needs it) when that is fixed.
+namespace llvm {
+class Module;
+}
 
 namespace clang {
 
@@ -147,7 +153,7 @@
 
   /// \brief This method converts the dominator tree to human readable form.
   ///
-  virtual void print(raw_ostream &OS, const llvm::Module* M= 0) const {
+  virtual void print(raw_ostream &OS, const llvm::Module* M= nullptr) const {
     DT->print(OS);
   }
 
@@ -155,11 +161,6 @@
   CFG *cfg;
 };
 
-inline void WriteAsOperand(raw_ostream &OS, const CFGBlock *BB,
-                          bool t) {
-  OS << "BB#" << BB->getBlockID();
-}
-
 } // end namespace clang
 
 //===-------------------------------------
diff --git a/include/clang/Analysis/Analyses/FormatString.h b/include/clang/Analysis/Analyses/FormatString.h
index c9516b5..76fe9dd 100644
--- a/include/clang/Analysis/Analyses/FormatString.h
+++ b/include/clang/Analysis/Analyses/FormatString.h
@@ -83,7 +83,7 @@
   };
 
   LengthModifier()
-    : Position(0), kind(None) {}
+    : Position(nullptr), kind(None) {}
   LengthModifier(const char *pos, Kind k)
     : Position(pos), kind(k) {}
 
@@ -169,10 +169,11 @@
   };
 
   ConversionSpecifier(bool isPrintf = true)
-    : IsPrintf(isPrintf), Position(0), EndScanList(0), kind(InvalidSpecifier) {}
+    : IsPrintf(isPrintf), Position(nullptr), EndScanList(nullptr),
+      kind(InvalidSpecifier) {}
 
   ConversionSpecifier(bool isPrintf, const char *pos, Kind k)
-    : IsPrintf(isPrintf), Position(pos), EndScanList(0), kind(k) {}
+    : IsPrintf(isPrintf), Position(pos), EndScanList(nullptr), kind(k) {}
 
   const char *getStart() const {
     return Position;
@@ -226,10 +227,11 @@
   const char *Name;
   bool Ptr;
 public:
-  ArgType(Kind k = UnknownTy, const char *n = 0) : K(k), Name(n), Ptr(false) {}
-  ArgType(QualType t, const char *n = 0)
+  ArgType(Kind k = UnknownTy, const char *n = nullptr)
+      : K(k), Name(n), Ptr(false) {}
+  ArgType(QualType t, const char *n = nullptr)
       : K(SpecificTy), T(t), Name(n), Ptr(false) {}
-  ArgType(CanQualType t) : K(SpecificTy), T(t), Name(0), Ptr(false) {}
+  ArgType(CanQualType t) : K(SpecificTy), T(t), Name(nullptr), Ptr(false) {}
 
   static ArgType Invalid() { return ArgType(InvalidTy); }
   bool isValid() const { return K != InvalidTy; }
@@ -262,7 +264,7 @@
   UsesPositionalArg(usesPositionalArg), UsesDotPrefix(0) {}
 
   OptionalAmount(bool valid = true)
-  : start(0),length(0), hs(valid ? NotSpecified : Invalid), amt(0),
+  : start(nullptr),length(0), hs(valid ? NotSpecified : Invalid), amt(0),
   UsesPositionalArg(0), UsesDotPrefix(0) {}
 
   bool isInvalid() const {
@@ -389,7 +391,7 @@
   public analyze_format_string::ConversionSpecifier  {
 public:
   PrintfConversionSpecifier()
-    : ConversionSpecifier(true, 0, InvalidSpecifier) {}
+    : ConversionSpecifier(true, nullptr, InvalidSpecifier) {}
 
   PrintfConversionSpecifier(const char *pos, Kind k)
     : ConversionSpecifier(true, pos, k) {}
@@ -525,7 +527,7 @@
     public analyze_format_string::ConversionSpecifier  {
 public:
   ScanfConversionSpecifier()
-    : ConversionSpecifier(false, 0, InvalidSpecifier) {}
+    : ConversionSpecifier(false, nullptr, InvalidSpecifier) {}
 
   ScanfConversionSpecifier(const char *pos, Kind k)
     : ConversionSpecifier(false, pos, k) {}
@@ -572,7 +574,8 @@
 
   ArgType getArgType(ASTContext &Ctx) const;
 
-  bool fixType(QualType QT, const LangOptions &LangOpt, ASTContext &Ctx);
+  bool fixType(QualType QT, QualType RawQT, const LangOptions &LangOpt,
+               ASTContext &Ctx);
 
   void toString(raw_ostream &os) const;
 
diff --git a/include/clang/Analysis/Analyses/LiveVariables.h b/include/clang/Analysis/Analyses/LiveVariables.h
index bbd2b02..7842271 100644
--- a/include/clang/Analysis/Analyses/LiveVariables.h
+++ b/include/clang/Analysis/Analyses/LiveVariables.h
@@ -38,7 +38,7 @@
     bool equals(const LivenessValues &V) const;
 
     LivenessValues()
-      : liveStmts(0), liveDecls(0) {}
+      : liveStmts(nullptr), liveDecls(nullptr) {}
 
     LivenessValues(llvm::ImmutableSet<const Stmt *> LiveStmts,
                    llvm::ImmutableSet<const VarDecl *> LiveDecls)
diff --git a/include/clang/Analysis/Analyses/PostOrderCFGView.h b/include/clang/Analysis/Analyses/PostOrderCFGView.h
index 4e3244e..91bf51c 100644
--- a/include/clang/Analysis/Analyses/PostOrderCFGView.h
+++ b/include/clang/Analysis/Analyses/PostOrderCFGView.h
@@ -52,7 +52,7 @@
       // make sure that Block is non-null.  Moreover, the CFGBlock iterator will
       // occasionally hand out null pointers for pruned edges, so we catch those
       // here.
-      if (Block == 0)
+      if (!Block)
         return false;  // if an edge is trivially false.
       if (VisitedBlockIDs.test(Block->getBlockID()))
         return false;
@@ -76,14 +76,18 @@
   BlockOrderTy BlockOrder;
 
 public:
-  typedef std::vector<const CFGBlock*>::reverse_iterator iterator;
+  typedef std::vector<const CFGBlock *>::reverse_iterator iterator;
+  typedef std::vector<const CFGBlock *>::const_reverse_iterator const_iterator;
 
   PostOrderCFGView(const CFG *cfg);
 
   iterator begin() { return Blocks.rbegin(); }
   iterator end()   { return Blocks.rend(); }
 
-  bool empty() { return begin() == end(); }
+  const_iterator begin() const { return Blocks.rbegin(); }
+  const_iterator end() const { return Blocks.rend(); }
+
+  bool empty() const { return begin() == end(); }
 
   struct BlockOrderCompare;
   friend struct BlockOrderCompare;
diff --git a/include/clang/Analysis/Analyses/ReachableCode.h b/include/clang/Analysis/Analyses/ReachableCode.h
index 30c5b2d..90a6d01 100644
--- a/include/clang/Analysis/Analyses/ReachableCode.h
+++ b/include/clang/Analysis/Analyses/ReachableCode.h
@@ -27,6 +27,7 @@
 namespace clang {
   class AnalysisDeclContext;
   class CFGBlock;
+  class Preprocessor;
 }
 
 //===----------------------------------------------------------------------===//
@@ -36,11 +37,22 @@
 namespace clang {
 namespace reachable_code {
 
+/// Classifications of unreachable code.
+enum UnreachableKind {
+  UK_Return,
+  UK_Break,
+  UK_Loop_Increment,
+  UK_Other
+};
+
 class Callback {
   virtual void anchor();
 public:
   virtual ~Callback() {}
-  virtual void HandleUnreachable(SourceLocation L, SourceRange R1,
+  virtual void HandleUnreachable(UnreachableKind UK,
+                                 SourceLocation L,
+                                 SourceRange ConditionVal,
+                                 SourceRange R1,
                                  SourceRange R2) = 0;
 };
 
@@ -49,7 +61,8 @@
 unsigned ScanReachableFromBlock(const CFGBlock *Start,
                                 llvm::BitVector &Reachable);
 
-void FindUnreachableCode(AnalysisDeclContext &AC, Callback &CB);
+void FindUnreachableCode(AnalysisDeclContext &AC, Preprocessor &PP,
+                         Callback &CB);
 
 }} // end namespace clang::reachable_code
 
diff --git a/include/clang/Analysis/Analyses/ThreadSafety.h b/include/clang/Analysis/Analyses/ThreadSafety.h
index 5def3dd..b533c1d 100644
--- a/include/clang/Analysis/Analyses/ThreadSafety.h
+++ b/include/clang/Analysis/Analyses/ThreadSafety.h
@@ -39,7 +39,8 @@
 /// mutex.
 enum LockKind {
   LK_Shared, ///< Shared/reader lock of a mutex.
-  LK_Exclusive ///< Exclusive/writer lock of a mutex.
+  LK_Exclusive, ///< Exclusive/writer lock of a mutex.
+  LK_Generic  ///<  Can be either Shared or Exclusive
 };
 
 /// This enum distinguishes between different ways to access (read or write) a
@@ -72,27 +73,46 @@
   virtual ~ThreadSafetyHandler();
 
   /// Warn about lock expressions which fail to resolve to lockable objects.
+  /// \param Kind -- the capability's name parameter (role, mutex, etc).
   /// \param Loc -- the SourceLocation of the unresolved expression.
-  virtual void handleInvalidLockExp(SourceLocation Loc) {}
+  virtual void handleInvalidLockExp(StringRef Kind, SourceLocation Loc) {}
 
   /// Warn about unlock function calls that do not have a prior matching lock
   /// expression.
+  /// \param Kind -- the capability's name parameter (role, mutex, etc).
   /// \param LockName -- A StringRef name for the lock expression, to be printed
   /// in the error message.
   /// \param Loc -- The SourceLocation of the Unlock
-  virtual void handleUnmatchedUnlock(Name LockName, SourceLocation Loc) {}
+  virtual void handleUnmatchedUnlock(StringRef Kind, Name LockName,
+                                     SourceLocation Loc) {}
+
+  /// Warn about an unlock function call that attempts to unlock a lock with
+  /// the incorrect lock kind. For instance, a shared lock being unlocked
+  /// exclusively, or vice versa.
+  /// \param LockName -- A StringRef name for the lock expression, to be printed
+  /// in the error message.
+  /// \param Kind -- the capability's name parameter (role, mutex, etc).
+  /// \param Expected -- the kind of lock expected.
+  /// \param Received -- the kind of lock received.
+  /// \param Loc -- The SourceLocation of the Unlock.
+  virtual void handleIncorrectUnlockKind(StringRef Kind, Name LockName,
+                                         LockKind Expected, LockKind Received,
+                                         SourceLocation Loc) {}
 
   /// Warn about lock function calls for locks which are already held.
+  /// \param Kind -- the capability's name parameter (role, mutex, etc).
   /// \param LockName -- A StringRef name for the lock expression, to be printed
   /// in the error message.
   /// \param Loc -- The location of the second lock expression.
-  virtual void handleDoubleLock(Name LockName, SourceLocation Loc) {}
+  virtual void handleDoubleLock(StringRef Kind, Name LockName,
+                                SourceLocation Loc) {}
 
   /// Warn about situations where a mutex is sometimes held and sometimes not.
   /// The three situations are:
   /// 1. a mutex is locked on an "if" branch but not the "else" branch,
   /// 2, or a mutex is only held at the start of some loop iterations,
   /// 3. or when a mutex is locked but not unlocked inside a function.
+  /// \param Kind -- the capability's name parameter (role, mutex, etc).
   /// \param LockName -- A StringRef name for the lock expression, to be printed
   /// in the error message.
   /// \param LocLocked -- The location of the lock expression where the mutex is
@@ -100,50 +120,56 @@
   /// \param LocEndOfScope -- The location of the end of the scope where the
   ///               mutex is no longer held
   /// \param LEK -- which of the three above cases we should warn for
-  virtual void handleMutexHeldEndOfScope(Name LockName,
+  virtual void handleMutexHeldEndOfScope(StringRef Kind, Name LockName,
                                          SourceLocation LocLocked,
                                          SourceLocation LocEndOfScope,
-                                         LockErrorKind LEK){}
+                                         LockErrorKind LEK) {}
 
   /// Warn when a mutex is held exclusively and shared at the same point. For
   /// example, if a mutex is locked exclusively during an if branch and shared
   /// during the else branch.
+  /// \param Kind -- the capability's name parameter (role, mutex, etc).
   /// \param LockName -- A StringRef name for the lock expression, to be printed
   /// in the error message.
   /// \param Loc1 -- The location of the first lock expression.
   /// \param Loc2 -- The location of the second lock expression.
-  virtual void handleExclusiveAndShared(Name LockName, SourceLocation Loc1,
+  virtual void handleExclusiveAndShared(StringRef Kind, Name LockName,
+                                        SourceLocation Loc1,
                                         SourceLocation Loc2) {}
 
   /// Warn when a protected operation occurs while no locks are held.
+  /// \param Kind -- the capability's name parameter (role, mutex, etc).
   /// \param D -- The decl for the protected variable or function
   /// \param POK -- The kind of protected operation (e.g. variable access)
   /// \param AK -- The kind of access (i.e. read or write) that occurred
   /// \param Loc -- The location of the protected operation.
-  virtual void handleNoMutexHeld(const NamedDecl *D, ProtectedOperationKind POK,
-                                 AccessKind AK, SourceLocation Loc) {}
+  virtual void handleNoMutexHeld(StringRef Kind, const NamedDecl *D,
+                                 ProtectedOperationKind POK, AccessKind AK,
+                                 SourceLocation Loc) {}
 
   /// Warn when a protected operation occurs while the specific mutex protecting
   /// the operation is not locked.
+  /// \param Kind -- the capability's name parameter (role, mutex, etc).
   /// \param D -- The decl for the protected variable or function
   /// \param POK -- The kind of protected operation (e.g. variable access)
   /// \param LockName -- A StringRef name for the lock expression, to be printed
   /// in the error message.
   /// \param LK -- The kind of access (i.e. read or write) that occurred
   /// \param Loc -- The location of the protected operation.
-  virtual void handleMutexNotHeld(const NamedDecl *D,
+  virtual void handleMutexNotHeld(StringRef Kind, const NamedDecl *D,
                                   ProtectedOperationKind POK, Name LockName,
                                   LockKind LK, SourceLocation Loc,
-                                  Name *PossibleMatch=0) {}
+                                  Name *PossibleMatch = nullptr) {}
 
   /// Warn when a function is called while an excluded mutex is locked. For
   /// example, the mutex may be locked inside the function.
+  /// \param Kind -- the capability's name parameter (role, mutex, etc).
   /// \param FunName -- The name of the function
   /// \param LockName -- A StringRef name for the lock expression, to be printed
   /// in the error message.
   /// \param Loc -- The location of the function call.
-  virtual void handleFunExcludesLock(Name FunName, Name LockName,
-                                     SourceLocation Loc) {}
+  virtual void handleFunExcludesLock(StringRef Kind, Name FunName,
+                                     Name LockName, SourceLocation Loc) {}
 
   bool issueBetaWarnings() { return IssueBetaWarnings; }
   void setIssueBetaWarnings(bool b) { IssueBetaWarnings = b; }
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyCommon.h b/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
new file mode 100644
index 0000000..09c614c
--- /dev/null
+++ b/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
@@ -0,0 +1,393 @@
+//===- ThreadSafetyCommon.h ------------------------------------*- C++ --*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Parts of thread safety analysis that are not specific to thread safety
+// itself have been factored into classes here, where they can be potentially
+// used by other analyses.  Currently these include:
+//
+// * Generalize clang CFG visitors.
+// * Conversion of the clang CFG to SSA form.
+// * Translation of clang Exprs to TIL SExprs
+//
+// UNDER CONSTRUCTION.  USE AT YOUR OWN RISK.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_THREAD_SAFETY_COMMON_H
+#define LLVM_CLANG_THREAD_SAFETY_COMMON_H
+
+#include "clang/Analysis/Analyses/PostOrderCFGView.h"
+#include "clang/Analysis/Analyses/ThreadSafetyTIL.h"
+#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Basic/OperatorKinds.h"
+
+#include <memory>
+#include <vector>
+
+
+namespace clang {
+namespace threadSafety {
+
+// This class defines the interface of a clang CFG Visitor.
+// CFGWalker will invoke the following methods.
+// Note that methods are not virtual; the visitor is templatized.
+class CFGVisitor {
+  // Enter the CFG for Decl D, and perform any initial setup operations.
+  void enterCFG(CFG *Cfg, const NamedDecl *D, const CFGBlock *First) {}
+
+  // Enter a CFGBlock.
+  void enterCFGBlock(const CFGBlock *B) {}
+
+  // Returns true if this visitor implements handlePredecessor
+  bool visitPredecessors() { return true; }
+
+  // Process a predecessor edge.
+  void handlePredecessor(const CFGBlock *Pred) {}
+
+  // Process a successor back edge to a previously visited block.
+  void handlePredecessorBackEdge(const CFGBlock *Pred) {}
+
+  // Called just before processing statements.
+  void enterCFGBlockBody(const CFGBlock *B) {}
+
+  // Process an ordinary statement.
+  void handleStatement(const Stmt *S) {}
+
+  // Process a destructor call
+  void handleDestructorCall(const VarDecl *VD, const CXXDestructorDecl *DD) {}
+
+  // Called after all statements have been handled.
+  void exitCFGBlockBody(const CFGBlock *B) {}
+
+  // Return true
+  bool visitSuccessors() { return true; }
+
+  // Process a successor edge.
+  void handleSuccessor(const CFGBlock *Succ) {}
+
+  // Process a successor back edge to a previously visited block.
+  void handleSuccessorBackEdge(const CFGBlock *Succ) {}
+
+  // Leave a CFGBlock.
+  void exitCFGBlock(const CFGBlock *B) {}
+
+  // Leave the CFG, and perform any final cleanup operations.
+  void exitCFG(const CFGBlock *Last) {}
+};
+
+
+// Walks the clang CFG, and invokes methods on a given CFGVisitor.
+class CFGWalker {
+public:
+  CFGWalker() : CFGraph(nullptr), ACtx(nullptr), SortedGraph(nullptr) {}
+
+  // Initialize the CFGWalker.  This setup only needs to be done once, even
+  // if there are multiple passes over the CFG.
+  bool init(AnalysisDeclContext &AC) {
+    ACtx = &AC;
+    CFGraph = AC.getCFG();
+    if (!CFGraph)
+      return false;
+
+    // Ignore anonymous functions.
+    if (!dyn_cast_or_null<NamedDecl>(AC.getDecl()))
+      return false;
+
+    SortedGraph = AC.getAnalysis<PostOrderCFGView>();
+    if (!SortedGraph)
+      return false;
+
+    return true;
+  }
+
+  // Traverse the CFG, calling methods on V as appropriate.
+  template <class Visitor>
+  void walk(Visitor &V) {
+    PostOrderCFGView::CFGBlockSet VisitedBlocks(CFGraph);
+
+    V.enterCFG(CFGraph, getDecl(), &CFGraph->getEntry());
+
+    for (const auto *CurrBlock : *SortedGraph) {
+      VisitedBlocks.insert(CurrBlock);
+
+      V.enterCFGBlock(CurrBlock);
+
+      // Process predecessors, handling back edges last
+      if (V.visitPredecessors()) {
+        SmallVector<CFGBlock*, 4> BackEdges;
+        // Process successors
+        for (CFGBlock::const_pred_iterator SI = CurrBlock->pred_begin(),
+                                           SE = CurrBlock->pred_end();
+             SI != SE; ++SI) {
+          if (*SI == nullptr)
+            continue;
+
+          if (!VisitedBlocks.alreadySet(*SI)) {
+            BackEdges.push_back(*SI);
+            continue;
+          }
+          V.handlePredecessor(*SI);
+        }
+
+        for (auto *Blk : BackEdges)
+          V.handlePredecessorBackEdge(Blk);
+      }
+
+      V.enterCFGBlockBody(CurrBlock);
+
+      // Process statements
+      for (const auto &BI : *CurrBlock) {
+        switch (BI.getKind()) {
+        case CFGElement::Statement: {
+          V.handleStatement(BI.castAs<CFGStmt>().getStmt());
+          break;
+        }
+        case CFGElement::AutomaticObjectDtor: {
+          CFGAutomaticObjDtor AD = BI.castAs<CFGAutomaticObjDtor>();
+          CXXDestructorDecl *DD = const_cast<CXXDestructorDecl*>(
+              AD.getDestructorDecl(ACtx->getASTContext()));
+          VarDecl *VD = const_cast<VarDecl*>(AD.getVarDecl());
+          V.handleDestructorCall(VD, DD);
+          break;
+        }
+        default:
+          break;
+        }
+      }
+
+      V.exitCFGBlockBody(CurrBlock);
+
+      // Process successors, handling back edges first.
+      if (V.visitSuccessors()) {
+        SmallVector<CFGBlock*, 8> ForwardEdges;
+
+        // Process successors
+        for (CFGBlock::const_succ_iterator SI = CurrBlock->succ_begin(),
+                                           SE = CurrBlock->succ_end();
+             SI != SE; ++SI) {
+          if (*SI == nullptr)
+            continue;
+
+          if (!VisitedBlocks.alreadySet(*SI)) {
+            ForwardEdges.push_back(*SI);
+            continue;
+          }
+          V.handleSuccessorBackEdge(*SI);
+        }
+
+        for (auto *Blk : ForwardEdges)
+          V.handleSuccessor(Blk);
+      }
+
+      V.exitCFGBlock(CurrBlock);
+    }
+    V.exitCFG(&CFGraph->getExit());
+  }
+
+  const CFG *getGraph() const { return CFGraph; }
+  CFG *getGraph() { return CFGraph; }
+
+  const NamedDecl *getDecl() const {
+    return dyn_cast<NamedDecl>(ACtx->getDecl());
+  }
+
+  const PostOrderCFGView *getSortedGraph() const { return SortedGraph; }
+
+private:
+  CFG *CFGraph;
+  AnalysisDeclContext *ACtx;
+  PostOrderCFGView *SortedGraph;
+};
+
+
+// Translate clang::Expr to til::SExpr.
+class SExprBuilder {
+public:
+  /// \brief Encapsulates the lexical context of a function call.  The lexical
+  /// context includes the arguments to the call, including the implicit object
+  /// argument.  When an attribute containing a mutex expression is attached to
+  /// a method, the expression may refer to formal parameters of the method.
+  /// Actual arguments must be substituted for formal parameters to derive
+  /// the appropriate mutex expression in the lexical context where the function
+  /// is called.  PrevCtx holds the context in which the arguments themselves
+  /// should be evaluated; multiple calling contexts can be chained together
+  /// by the lock_returned attribute.
+  struct CallingContext {
+    const NamedDecl *AttrDecl;  // The decl to which the attr is attached.
+    const Expr *SelfArg;        // Implicit object argument -- e.g. 'this'
+    unsigned NumArgs;           // Number of funArgs
+    const Expr *const *FunArgs; // Function arguments
+    CallingContext *Prev;       // The previous context; or 0 if none.
+    bool SelfArrow;             // is Self referred to with -> or .?
+
+    CallingContext(const NamedDecl *D = nullptr, const Expr *S = nullptr,
+                   unsigned N = 0, const Expr *const *A = nullptr,
+                   CallingContext *P = nullptr)
+        : AttrDecl(D), SelfArg(S), NumArgs(N), FunArgs(A), Prev(P),
+          SelfArrow(false)
+    {}
+  };
+
+  SExprBuilder(til::MemRegionRef A)
+      : Arena(A), SelfVar(nullptr), Scfg(nullptr), CurrentBB(nullptr),
+        CurrentBlockInfo(nullptr) {
+    // FIXME: we don't always have a self-variable.
+    SelfVar = new (Arena) til::Variable(nullptr);
+    SelfVar->setKind(til::Variable::VK_SFun);
+  }
+
+  // Translate a clang statement or expression to a TIL expression.
+  // Also performs substitution of variables; Ctx provides the context.
+  // Dispatches on the type of S.
+  til::SExpr *translate(const Stmt *S, CallingContext *Ctx);
+  til::SCFG  *buildCFG(CFGWalker &Walker);
+
+  til::SExpr *lookupStmt(const Stmt *S);
+
+  til::BasicBlock *lookupBlock(const CFGBlock *B) {
+    return BlockMap[B->getBlockID()];
+  }
+
+  const til::SCFG *getCFG() const { return Scfg; }
+  til::SCFG *getCFG() { return Scfg; }
+
+private:
+  til::SExpr *translateDeclRefExpr(const DeclRefExpr *DRE,
+                                   CallingContext *Ctx) ;
+  til::SExpr *translateCXXThisExpr(const CXXThisExpr *TE, CallingContext *Ctx);
+  til::SExpr *translateMemberExpr(const MemberExpr *ME, CallingContext *Ctx);
+  til::SExpr *translateCallExpr(const CallExpr *CE, CallingContext *Ctx);
+  til::SExpr *translateCXXMemberCallExpr(const CXXMemberCallExpr *ME,
+                                         CallingContext *Ctx);
+  til::SExpr *translateCXXOperatorCallExpr(const CXXOperatorCallExpr *OCE,
+                                           CallingContext *Ctx);
+  til::SExpr *translateUnaryOperator(const UnaryOperator *UO,
+                                     CallingContext *Ctx);
+  til::SExpr *translateBinOp(til::TIL_BinaryOpcode Op,
+                             const BinaryOperator *BO,
+                             CallingContext *Ctx, bool Reverse = false);
+  til::SExpr *translateBinAssign(til::TIL_BinaryOpcode Op,
+                                 const BinaryOperator *BO,
+                                 CallingContext *Ctx, bool Assign = false);
+  til::SExpr *translateBinaryOperator(const BinaryOperator *BO,
+                                      CallingContext *Ctx);
+  til::SExpr *translateCastExpr(const CastExpr *CE, CallingContext *Ctx);
+  til::SExpr *translateArraySubscriptExpr(const ArraySubscriptExpr *E,
+                                          CallingContext *Ctx);
+  til::SExpr *translateConditionalOperator(const ConditionalOperator *C,
+                                           CallingContext *Ctx);
+  til::SExpr *translateBinaryConditionalOperator(
+      const BinaryConditionalOperator *C, CallingContext *Ctx);
+
+  til::SExpr *translateDeclStmt(const DeclStmt *S, CallingContext *Ctx);
+
+  // Map from statements in the clang CFG to SExprs in the til::SCFG.
+  typedef llvm::DenseMap<const Stmt*, til::SExpr*> StatementMap;
+
+  // Map from clang local variables to indices in a LVarDefinitionMap.
+  typedef llvm::DenseMap<const ValueDecl *, unsigned> LVarIndexMap;
+
+  // Map from local variable indices to SSA variables (or constants).
+  typedef std::pair<const ValueDecl *, til::SExpr *> NameVarPair;
+  typedef CopyOnWriteVector<NameVarPair> LVarDefinitionMap;
+
+  struct BlockInfo {
+    LVarDefinitionMap ExitMap;
+    bool HasBackEdges;
+    unsigned UnprocessedSuccessors;   // Successors yet to be processed
+    unsigned ProcessedPredecessors;   // Predecessors already processed
+
+    BlockInfo()
+        : HasBackEdges(false), UnprocessedSuccessors(0),
+          ProcessedPredecessors(0) {}
+    BlockInfo(BlockInfo &&RHS)
+        : ExitMap(std::move(RHS.ExitMap)),
+          HasBackEdges(RHS.HasBackEdges),
+          UnprocessedSuccessors(RHS.UnprocessedSuccessors),
+          ProcessedPredecessors(RHS.ProcessedPredecessors) {}
+
+    BlockInfo &operator=(BlockInfo &&RHS) {
+      if (this != &RHS) {
+        ExitMap = std::move(RHS.ExitMap);
+        HasBackEdges = RHS.HasBackEdges;
+        UnprocessedSuccessors = RHS.UnprocessedSuccessors;
+        ProcessedPredecessors = RHS.ProcessedPredecessors;
+      }
+      return *this;
+    }
+
+  private:
+    BlockInfo(const BlockInfo &) LLVM_DELETED_FUNCTION;
+    void operator=(const BlockInfo &) LLVM_DELETED_FUNCTION;
+  };
+
+  // We implement the CFGVisitor API
+  friend class CFGWalker;
+
+  void enterCFG(CFG *Cfg, const NamedDecl *D, const CFGBlock *First);
+  void enterCFGBlock(const CFGBlock *B);
+  bool visitPredecessors() { return true; }
+  void handlePredecessor(const CFGBlock *Pred);
+  void handlePredecessorBackEdge(const CFGBlock *Pred);
+  void enterCFGBlockBody(const CFGBlock *B);
+  void handleStatement(const Stmt *S);
+  void handleDestructorCall(const VarDecl *VD, const CXXDestructorDecl *DD);
+  void exitCFGBlockBody(const CFGBlock *B);
+  bool visitSuccessors() { return true; }
+  void handleSuccessor(const CFGBlock *Succ);
+  void handleSuccessorBackEdge(const CFGBlock *Succ);
+  void exitCFGBlock(const CFGBlock *B);
+  void exitCFG(const CFGBlock *Last);
+
+  void insertStmt(const Stmt *S, til::SExpr *E) {
+    SMap.insert(std::make_pair(S, E));
+  }
+  til::SExpr *getCurrentLVarDefinition(const ValueDecl *VD);
+
+  til::SExpr *addStatement(til::SExpr *E, const Stmt *S,
+                           const ValueDecl *VD = nullptr);
+  til::SExpr *lookupVarDecl(const ValueDecl *VD);
+  til::SExpr *addVarDecl(const ValueDecl *VD, til::SExpr *E);
+  til::SExpr *updateVarDecl(const ValueDecl *VD, til::SExpr *E);
+
+  void makePhiNodeVar(unsigned i, unsigned NPreds, til::SExpr *E);
+  void mergeEntryMap(LVarDefinitionMap Map);
+  void mergeEntryMapBackEdge();
+  void mergePhiNodesBackEdge(const CFGBlock *Blk);
+
+private:
+  til::MemRegionRef Arena;
+  til::Variable *SelfVar;       // Variable to use for 'this'.  May be null.
+  til::SCFG *Scfg;
+
+  StatementMap SMap;                       // Map from Stmt to TIL Variables
+  LVarIndexMap LVarIdxMap;                 // Indices of clang local vars.
+  std::vector<til::BasicBlock *> BlockMap; // Map from clang to til BBs.
+  std::vector<BlockInfo> BBInfo;           // Extra information per BB.
+                                           // Indexed by clang BlockID.
+  std::unique_ptr<SExprBuilder::CallingContext> CallCtx; // Root calling context
+
+  LVarDefinitionMap CurrentLVarMap;
+  std::vector<til::Variable*> CurrentArguments;
+  std::vector<til::Variable*> CurrentInstructions;
+  std::vector<til::Variable*> IncompleteArgs;
+  til::BasicBlock *CurrentBB;
+  BlockInfo *CurrentBlockInfo;
+};
+
+
+// Dump an SCFG to llvm::errs().
+void printSCFG(CFGWalker &Walker);
+
+
+} // end namespace threadSafety
+
+} // end namespace clang
+
+#endif  // LLVM_CLANG_THREAD_SAFETY_COMMON_H
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyLogical.h b/include/clang/Analysis/Analyses/ThreadSafetyLogical.h
new file mode 100644
index 0000000..c4f4b21
--- /dev/null
+++ b/include/clang/Analysis/Analyses/ThreadSafetyLogical.h
@@ -0,0 +1,108 @@
+//===- ThreadSafetyLogical.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 a representation for logical expressions with SExpr leaves
+// that are used as part of fact-checking capability expressions.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_THREAD_SAFETY_LOGICAL_H
+#define LLVM_CLANG_THREAD_SAFETY_LOGICAL_H
+
+#include "clang/Analysis/Analyses/ThreadSafetyTIL.h"
+
+namespace clang {
+namespace threadSafety {
+namespace lexpr {
+
+class LExpr {
+public:
+  enum Opcode {
+    Terminal,
+    And,
+    Or,
+    Not
+  };
+  Opcode kind() const { return Kind; }
+
+  /// \brief Logical implication. Returns true if the LExpr implies RHS, i.e. if
+  /// the LExpr holds, then RHS must hold. For example, (A & B) implies A.
+  inline bool implies(const LExpr *RHS) const;
+
+protected:
+  LExpr(Opcode Kind) : Kind(Kind) {}
+
+private:
+  Opcode Kind;
+};
+
+class Terminal : public LExpr {
+  til::SExprRef Expr;
+
+public:
+  Terminal(til::SExpr *Expr) : LExpr(LExpr::Terminal), Expr(Expr) {}
+
+  const til::SExpr *expr() const { return Expr.get(); }
+  til::SExpr *expr() { return Expr.get(); }
+
+  static bool classof(const LExpr *E) { return E->kind() == LExpr::Terminal; }
+};
+
+class BinOp : public LExpr {
+  LExpr *LHS, *RHS;
+
+protected:
+  BinOp(LExpr *LHS, LExpr *RHS, Opcode Code) : LExpr(Code), LHS(LHS), RHS(RHS) {}
+
+public:
+  const LExpr *left() const { return LHS; }
+  LExpr *left() { return LHS; }
+
+  const LExpr *right() const { return RHS; }
+  LExpr *right() { return RHS; }
+};
+
+class And : public BinOp {
+public:
+  And(LExpr *LHS, LExpr *RHS) : BinOp(LHS, RHS, LExpr::And) {}
+
+  static bool classof(const LExpr *E) { return E->kind() == LExpr::And; }
+};
+
+class Or : public BinOp {
+public:
+  Or(LExpr *LHS, LExpr *RHS) : BinOp(LHS, RHS, LExpr::Or) {}
+
+  static bool classof(const LExpr *E) { return E->kind() == LExpr::Or; }
+};
+
+class Not : public LExpr {
+  LExpr *Exp;
+
+public:
+  Not(LExpr *Exp) : LExpr(LExpr::Not), Exp(Exp) {}
+
+  const LExpr *exp() const { return Exp; }
+  LExpr *exp() { return Exp; }
+
+  static bool classof(const LExpr *E) { return E->kind() == LExpr::Not; }
+};
+
+/// \brief Logical implication. Returns true if LHS implies RHS, i.e. if LHS
+/// holds, then RHS must hold. For example, (A & B) implies A.
+bool implies(const LExpr *LHS, const LExpr *RHS);
+
+bool LExpr::implies(const LExpr *RHS) const {
+  return lexpr::implies(this, RHS);
+}
+
+}
+}
+}
+
+#endif // LLVM_CLANG_THREAD_SAFETY_LOGICAL_H
+
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyOps.def b/include/clang/Analysis/Analyses/ThreadSafetyOps.def
new file mode 100644
index 0000000..6ebc95d
--- /dev/null
+++ b/include/clang/Analysis/Analyses/ThreadSafetyOps.def
@@ -0,0 +1,54 @@
+//===- ThreadSafetyTIL.h ---------------------------------------*- C++ --*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the list of core opcodes for the Thread Safety
+// Typed Intermediate language.  Please see ThreadSafetyTIL.h for more
+// information.
+//
+//===----------------------------------------------------------------------===//
+
+
+TIL_OPCODE_DEF(Future)
+TIL_OPCODE_DEF(Undefined)
+TIL_OPCODE_DEF(Wildcard)
+
+TIL_OPCODE_DEF(Literal)
+TIL_OPCODE_DEF(LiteralPtr)
+TIL_OPCODE_DEF(Variable)
+TIL_OPCODE_DEF(Function)
+TIL_OPCODE_DEF(SFunction)
+TIL_OPCODE_DEF(Code)
+TIL_OPCODE_DEF(Field)
+
+TIL_OPCODE_DEF(Apply)
+TIL_OPCODE_DEF(SApply)
+TIL_OPCODE_DEF(Project)
+
+TIL_OPCODE_DEF(Call)
+TIL_OPCODE_DEF(Alloc)
+TIL_OPCODE_DEF(Load)
+TIL_OPCODE_DEF(Store)
+TIL_OPCODE_DEF(ArrayIndex)
+TIL_OPCODE_DEF(ArrayAdd)
+
+TIL_OPCODE_DEF(UnaryOp)
+TIL_OPCODE_DEF(BinaryOp)
+TIL_OPCODE_DEF(Cast)
+
+TIL_OPCODE_DEF(SCFG)
+TIL_OPCODE_DEF(BasicBlock)
+TIL_OPCODE_DEF(Phi)
+TIL_OPCODE_DEF(Goto)
+TIL_OPCODE_DEF(Branch)
+
+// pseudo-terms
+TIL_OPCODE_DEF(Identifier)
+TIL_OPCODE_DEF(IfThenElse)
+TIL_OPCODE_DEF(Let)
+
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyTIL.h b/include/clang/Analysis/Analyses/ThreadSafetyTIL.h
new file mode 100644
index 0000000..8e4299e
--- /dev/null
+++ b/include/clang/Analysis/Analyses/ThreadSafetyTIL.h
@@ -0,0 +1,1813 @@
+//===- ThreadSafetyTIL.h ---------------------------------------*- C++ --*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT in the llvm repository for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a simple Typed Intermediate Language, or TIL, that is used
+// by the thread safety analysis (See ThreadSafety.cpp).  The TIL is intended
+// to be largely independent of clang, in the hope that the analysis can be
+// reused for other non-C++ languages.  All dependencies on clang/llvm should
+// go in ThreadSafetyUtil.h.
+//
+// Thread safety analysis works by comparing mutex expressions, e.g.
+//
+// class A { Mutex mu; int dat GUARDED_BY(this->mu); }
+// class B { A a; }
+//
+// void foo(B* b) {
+//   (*b).a.mu.lock();     // locks (*b).a.mu
+//   b->a.dat = 0;         // substitute &b->a for 'this';
+//                         // requires lock on (&b->a)->mu
+//   (b->a.mu).unlock();   // unlocks (b->a.mu)
+// }
+//
+// As illustrated by the above example, clang Exprs are not well-suited to
+// represent mutex expressions directly, since there is no easy way to compare
+// Exprs for equivalence.  The thread safety analysis thus lowers clang Exprs
+// into a simple intermediate language (IL).  The IL supports:
+//
+// (1) comparisons for semantic equality of expressions
+// (2) SSA renaming of variables
+// (3) wildcards and pattern matching over expressions
+// (4) hash-based expression lookup
+//
+// The TIL is currently very experimental, is intended only for use within
+// the thread safety analysis, and is subject to change without notice.
+// After the API stabilizes and matures, it may be appropriate to make this
+// more generally available to other analyses.
+//
+// UNDER CONSTRUCTION.  USE AT YOUR OWN RISK.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_THREAD_SAFETY_TIL_H
+#define LLVM_CLANG_THREAD_SAFETY_TIL_H
+
+// All clang include dependencies for this file must be put in
+// ThreadSafetyUtil.h.
+#include "ThreadSafetyUtil.h"
+
+#include <stdint.h>
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <utility>
+
+
+namespace clang {
+namespace threadSafety {
+namespace til {
+
+
+enum TIL_Opcode {
+#define TIL_OPCODE_DEF(X) COP_##X,
+#include "ThreadSafetyOps.def"
+#undef TIL_OPCODE_DEF
+};
+
+enum TIL_UnaryOpcode : unsigned char {
+  UOP_Minus,        //  -
+  UOP_BitNot,       //  ~
+  UOP_LogicNot      //  !
+};
+
+enum TIL_BinaryOpcode : unsigned char {
+  BOP_Mul,          //  *
+  BOP_Div,          //  /
+  BOP_Rem,          //  %
+  BOP_Add,          //  +
+  BOP_Sub,          //  -
+  BOP_Shl,          //  <<
+  BOP_Shr,          //  >>
+  BOP_BitAnd,       //  &
+  BOP_BitXor,       //  ^
+  BOP_BitOr,        //  |
+  BOP_Eq,           //  ==
+  BOP_Neq,          //  !=
+  BOP_Lt,           //  <
+  BOP_Leq,          //  <=
+  BOP_LogicAnd,     //  &&
+  BOP_LogicOr       //  ||
+};
+
+enum TIL_CastOpcode : unsigned char {
+  CAST_none = 0,
+  CAST_extendNum,   // extend precision of numeric type
+  CAST_truncNum,    // truncate precision of numeric type
+  CAST_toFloat,     // convert to floating point type
+  CAST_toInt,       // convert to integer type
+};
+
+const TIL_Opcode       COP_Min  = COP_Future;
+const TIL_Opcode       COP_Max  = COP_Branch;
+const TIL_UnaryOpcode  UOP_Min  = UOP_Minus;
+const TIL_UnaryOpcode  UOP_Max  = UOP_LogicNot;
+const TIL_BinaryOpcode BOP_Min  = BOP_Mul;
+const TIL_BinaryOpcode BOP_Max  = BOP_LogicOr;
+const TIL_CastOpcode   CAST_Min = CAST_none;
+const TIL_CastOpcode   CAST_Max = CAST_toInt;
+
+StringRef getUnaryOpcodeString(TIL_UnaryOpcode Op);
+StringRef getBinaryOpcodeString(TIL_BinaryOpcode Op);
+
+
+// ValueTypes are data types that can actually be held in registers.
+// All variables and expressions must have a vBNF_Nonealue type.
+// Pointer types are further subdivided into the various heap-allocated
+// types, such as functions, records, etc.
+// Structured types that are passed by value (e.g. complex numbers)
+// require special handling; they use BT_ValueRef, and size ST_0.
+struct ValueType {
+  enum BaseType : unsigned char {
+    BT_Void = 0,
+    BT_Bool,
+    BT_Int,
+    BT_Float,
+    BT_String,    // String literals
+    BT_Pointer,
+    BT_ValueRef
+  };
+
+  enum SizeType : unsigned char {
+    ST_0 = 0,
+    ST_1,
+    ST_8,
+    ST_16,
+    ST_32,
+    ST_64,
+    ST_128
+  };
+
+  inline static SizeType getSizeType(unsigned nbytes);
+
+  template <class T>
+  inline static ValueType getValueType();
+
+  ValueType(BaseType B, SizeType Sz, bool S, unsigned char VS)
+      : Base(B), Size(Sz), Signed(S), VectSize(VS)
+  { }
+
+  BaseType      Base;
+  SizeType      Size;
+  bool          Signed;
+  unsigned char VectSize;  // 0 for scalar, otherwise num elements in vector
+};
+
+
+inline ValueType::SizeType ValueType::getSizeType(unsigned nbytes) {
+  switch (nbytes) {
+    case 1: return ST_8;
+    case 2: return ST_16;
+    case 4: return ST_32;
+    case 8: return ST_64;
+    case 16: return ST_128;
+    default: return ST_0;
+  }
+}
+
+
+template<>
+inline ValueType ValueType::getValueType<void>() {
+  return ValueType(BT_Void, ST_0, false, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<bool>() {
+  return ValueType(BT_Bool, ST_1, false, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<int8_t>() {
+  return ValueType(BT_Int, ST_8, true, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<uint8_t>() {
+  return ValueType(BT_Int, ST_8, false, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<int16_t>() {
+  return ValueType(BT_Int, ST_16, true, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<uint16_t>() {
+  return ValueType(BT_Int, ST_16, false, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<int32_t>() {
+  return ValueType(BT_Int, ST_32, true, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<uint32_t>() {
+  return ValueType(BT_Int, ST_32, false, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<int64_t>() {
+  return ValueType(BT_Int, ST_64, true, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<uint64_t>() {
+  return ValueType(BT_Int, ST_64, false, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<float>() {
+  return ValueType(BT_Float, ST_32, true, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<double>() {
+  return ValueType(BT_Float, ST_64, true, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<long double>() {
+  return ValueType(BT_Float, ST_128, true, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<StringRef>() {
+  return ValueType(BT_String, getSizeType(sizeof(StringRef)), false, 0);
+}
+
+template<>
+inline ValueType ValueType::getValueType<void*>() {
+  return ValueType(BT_Pointer, getSizeType(sizeof(void*)), false, 0);
+}
+
+
+
+// Base class for AST nodes in the typed intermediate language.
+class SExpr {
+public:
+  TIL_Opcode opcode() const { return static_cast<TIL_Opcode>(Opcode); }
+
+  // Subclasses of SExpr must define the following:
+  //
+  // This(const This& E, ...) {
+  //   copy constructor: construct copy of E, with some additional arguments.
+  // }
+  //
+  // template <class V>
+  // typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+  //   traverse all subexpressions, following the traversal/rewriter interface.
+  // }
+  //
+  // template <class C> typename C::CType compare(CType* E, C& Cmp) {
+  //   compare all subexpressions, following the comparator interface
+  // }
+
+  void *operator new(size_t S, MemRegionRef &R) {
+    return ::operator new(S, R);
+  }
+
+  // SExpr objects cannot be deleted.
+  // This declaration is public to workaround a gcc bug that breaks building
+  // with REQUIRES_EH=1.
+  void operator delete(void *) LLVM_DELETED_FUNCTION;
+
+protected:
+  SExpr(TIL_Opcode Op) : Opcode(Op), Reserved(0), Flags(0) {}
+  SExpr(const SExpr &E) : Opcode(E.Opcode), Reserved(0), Flags(E.Flags) {}
+
+  const unsigned char Opcode;
+  unsigned char Reserved;
+  unsigned short Flags;
+
+private:
+  SExpr() LLVM_DELETED_FUNCTION;
+
+  // SExpr objects must be created in an arena.
+  void *operator new(size_t) LLVM_DELETED_FUNCTION;
+};
+
+
+// Class for owning references to SExprs.
+// Includes attach/detach logic for counting variable references and lazy
+// rewriting strategies.
+class SExprRef {
+public:
+  SExprRef() : Ptr(nullptr) { }
+  SExprRef(std::nullptr_t P) : Ptr(nullptr) { }
+  SExprRef(SExprRef &&R) : Ptr(R.Ptr) { R.Ptr = nullptr; }
+
+  // Defined after Variable and Future, below.
+  inline SExprRef(SExpr *P);
+  inline ~SExprRef();
+
+  SExpr       *get()       { return Ptr; }
+  const SExpr *get() const { return Ptr; }
+
+  SExpr       *operator->()       { return get(); }
+  const SExpr *operator->() const { return get(); }
+
+  SExpr       &operator*()        { return *Ptr; }
+  const SExpr &operator*() const  { return *Ptr; }
+
+  bool operator==(const SExprRef &R) const { return Ptr == R.Ptr; }
+  bool operator!=(const SExprRef &R) const { return !operator==(R); }
+  bool operator==(const SExpr *P)    const { return Ptr == P; }
+  bool operator!=(const SExpr *P)    const { return !operator==(P); }
+  bool operator==(std::nullptr_t)    const { return Ptr == nullptr; }
+  bool operator!=(std::nullptr_t)    const { return Ptr != nullptr; }
+
+  inline void reset(SExpr *E);
+
+private:
+  inline void attach();
+  inline void detach();
+
+  SExpr *Ptr;
+};
+
+
+// Contains various helper functions for SExprs.
+namespace ThreadSafetyTIL {
+  inline bool isTrivial(const SExpr *E) {
+    unsigned Op = E->opcode();
+    return Op == COP_Variable || Op == COP_Literal || Op == COP_LiteralPtr;
+  }
+}
+
+// Nodes which declare variables
+class Function;
+class SFunction;
+class BasicBlock;
+class Let;
+
+
+// A named variable, e.g. "x".
+//
+// There are two distinct places in which a Variable can appear in the AST.
+// A variable declaration introduces a new variable, and can occur in 3 places:
+//   Let-expressions:           (Let (x = t) u)
+//   Functions:                 (Function (x : t) u)
+//   Self-applicable functions  (SFunction (x) t)
+//
+// If a variable occurs in any other location, it is a reference to an existing
+// variable declaration -- e.g. 'x' in (x * y + z). To save space, we don't
+// allocate a separate AST node for variable references; a reference is just a
+// pointer to the original declaration.
+class Variable : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Variable; }
+
+  // Let-variable, function parameter, or self-variable
+  enum VariableKind {
+    VK_Let,
+    VK_LetBB,
+    VK_Fun,
+    VK_SFun
+  };
+
+  // These are defined after SExprRef contructor, below
+  inline Variable(SExpr *D, const clang::ValueDecl *Cvd = nullptr);
+  inline Variable(StringRef s, SExpr *D = nullptr);
+  inline Variable(const Variable &Vd, SExpr *D);
+
+  VariableKind kind() const { return static_cast<VariableKind>(Flags); }
+
+  const StringRef name() const { return Name; }
+  const clang::ValueDecl *clangDecl() const { return Cvdecl; }
+
+  // Returns the definition (for let vars) or type (for parameter & self vars)
+  SExpr *definition() { return Definition.get(); }
+  const SExpr *definition() const { return Definition.get(); }
+
+  void attachVar() const { ++NumUses; }
+  void detachVar() const { assert(NumUses > 0); --NumUses; }
+
+  unsigned getID() const { return Id; }
+  unsigned getBlockID() const { return BlockID; }
+
+  void setName(StringRef S) { Name = S; }
+  void setID(unsigned Bid, unsigned I) {
+    BlockID = static_cast<unsigned short>(Bid);
+    Id = static_cast<unsigned short>(I);
+  }
+  void setClangDecl(const clang::ValueDecl *VD) { Cvdecl = VD; }
+  void setDefinition(SExpr *E);
+  void setKind(VariableKind K) { Flags = K; }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    // This routine is only called for variable references.
+    return Vs.reduceVariableRef(this);
+  }
+
+  template <class C> typename C::CType compare(Variable* E, C& Cmp) {
+    return Cmp.compareVariableRefs(this, E);
+  }
+
+private:
+  friend class Function;
+  friend class SFunction;
+  friend class BasicBlock;
+  friend class Let;
+
+  StringRef Name;                  // The name of the variable.
+  SExprRef  Definition;            // The TIL type or definition
+  const clang::ValueDecl *Cvdecl;  // The clang declaration for this variable.
+
+  unsigned short BlockID;
+  unsigned short Id;
+  mutable unsigned NumUses;
+};
+
+
+// Placeholder for an expression that has not yet been created.
+// Used to implement lazy copy and rewriting strategies.
+class Future : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Future; }
+
+  enum FutureStatus {
+    FS_pending,
+    FS_evaluating,
+    FS_done
+  };
+
+  Future() :
+    SExpr(COP_Future), Status(FS_pending), Result(nullptr), Location(nullptr)
+  {}
+private:
+  virtual ~Future() LLVM_DELETED_FUNCTION;
+public:
+
+  // Registers the location in the AST where this future is stored.
+  // Forcing the future will automatically update the AST.
+  static inline void registerLocation(SExprRef *Member) {
+    if (Future *F = dyn_cast_or_null<Future>(Member->get()))
+      F->Location = Member;
+  }
+
+  // A lazy rewriting strategy should subclass Future and override this method.
+  virtual SExpr *create() { return nullptr; }
+
+  // Return the result of this future if it exists, otherwise return null.
+  SExpr *maybeGetResult() {
+    return Result;
+  }
+
+  // Return the result of this future; forcing it if necessary.
+  SExpr *result() {
+    switch (Status) {
+    case FS_pending:
+      force();
+      return Result;
+    case FS_evaluating:
+      return nullptr; // infinite loop; illegal recursion.
+    case FS_done:
+      return Result;
+    }
+  }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    assert(Result && "Cannot traverse Future that has not been forced.");
+    return Vs.traverse(Result, Ctx);
+  }
+
+  template <class C> typename C::CType compare(Future* E, C& Cmp) {
+    if (!Result || !E->Result)
+      return Cmp.comparePointers(this, E);
+    return Cmp.compare(Result, E->Result);
+  }
+
+private:
+  // Force the future.
+  inline void force();
+
+  FutureStatus Status;
+  SExpr *Result;
+  SExprRef *Location;
+};
+
+
+inline void SExprRef::attach() {
+  if (!Ptr)
+    return;
+
+  TIL_Opcode Op = Ptr->opcode();
+  if (Op == COP_Variable) {
+    cast<Variable>(Ptr)->attachVar();
+  } else if (Op == COP_Future) {
+    cast<Future>(Ptr)->registerLocation(this);
+  }
+}
+
+inline void SExprRef::detach() {
+  if (Ptr && Ptr->opcode() == COP_Variable) {
+    cast<Variable>(Ptr)->detachVar();
+  }
+}
+
+inline SExprRef::SExprRef(SExpr *P) : Ptr(P) {
+  attach();
+}
+
+inline SExprRef::~SExprRef() {
+  detach();
+}
+
+inline void SExprRef::reset(SExpr *P) {
+  detach();
+  Ptr = P;
+  attach();
+}
+
+
+inline Variable::Variable(StringRef s, SExpr *D)
+    : SExpr(COP_Variable), Name(s), Definition(D), Cvdecl(nullptr),
+      BlockID(0), Id(0), NumUses(0) {
+  Flags = VK_Let;
+}
+
+inline Variable::Variable(SExpr *D, const clang::ValueDecl *Cvd)
+    : SExpr(COP_Variable), Name(Cvd ? Cvd->getName() : "_x"),
+      Definition(D), Cvdecl(Cvd), BlockID(0), Id(0), NumUses(0) {
+  Flags = VK_Let;
+}
+
+inline Variable::Variable(const Variable &Vd, SExpr *D) // rewrite constructor
+    : SExpr(Vd), Name(Vd.Name), Definition(D), Cvdecl(Vd.Cvdecl),
+      BlockID(0), Id(0), NumUses(0) {
+  Flags = Vd.kind();
+}
+
+inline void Variable::setDefinition(SExpr *E) {
+  Definition.reset(E);
+}
+
+void Future::force() {
+  Status = FS_evaluating;
+  SExpr *R = create();
+  Result = R;
+  if (Location)
+    Location->reset(R);
+  Status = FS_done;
+}
+
+
+// Placeholder for C++ expressions that cannot be represented in the TIL.
+class Undefined : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Undefined; }
+
+  Undefined(const clang::Stmt *S = nullptr) : SExpr(COP_Undefined), Cstmt(S) {}
+  Undefined(const Undefined &U) : SExpr(U), Cstmt(U.Cstmt) {}
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    return Vs.reduceUndefined(*this);
+  }
+
+  template <class C> typename C::CType compare(Undefined* E, C& Cmp) {
+    return Cmp.comparePointers(Cstmt, E->Cstmt);
+  }
+
+private:
+  const clang::Stmt *Cstmt;
+};
+
+
+// Placeholder for a wildcard that matches any other expression.
+class Wildcard : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Wildcard; }
+
+  Wildcard() : SExpr(COP_Wildcard) {}
+  Wildcard(const Wildcard &W) : SExpr(W) {}
+
+  template <class V> typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    return Vs.reduceWildcard(*this);
+  }
+
+  template <class C> typename C::CType compare(Wildcard* E, C& Cmp) {
+    return Cmp.trueResult();
+  }
+};
+
+
+template <class T> class LiteralT;
+
+// Base class for literal values.
+class Literal : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Literal; }
+
+  Literal(const clang::Expr *C)
+     : SExpr(COP_Literal), ValType(ValueType::getValueType<void>()), Cexpr(C)
+  { }
+  Literal(ValueType VT) : SExpr(COP_Literal), ValType(VT), Cexpr(nullptr) {}
+  Literal(const Literal &L) : SExpr(L), ValType(L.ValType), Cexpr(L.Cexpr) {}
+
+  // The clang expression for this literal.
+  const clang::Expr *clangExpr() const { return Cexpr; }
+
+  ValueType valueType() const { return ValType; }
+
+  template<class T> const LiteralT<T>& as() const {
+    return *static_cast<const LiteralT<T>*>(this);
+  }
+  template<class T> LiteralT<T>& as() {
+    return *static_cast<LiteralT<T>*>(this);
+  }
+
+  template <class V> typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx);
+
+  template <class C> typename C::CType compare(Literal* E, C& Cmp) {
+    // TODO -- use value, not pointer equality
+    return Cmp.comparePointers(Cexpr, E->Cexpr);
+  }
+
+private:
+  const ValueType ValType;
+  const clang::Expr *Cexpr;
+};
+
+
+// Derived class for literal values, which stores the actual value.
+template<class T>
+class LiteralT : public Literal {
+public:
+  LiteralT(T Dat) : Literal(ValueType::getValueType<T>()), Val(Dat) { }
+  LiteralT(const LiteralT<T> &L) : Literal(L), Val(L.Val) { }
+
+  T  value() const { return Val;}
+  T& value() { return Val; }
+
+private:
+  T Val;
+};
+
+
+
+template <class V>
+typename V::R_SExpr Literal::traverse(V &Vs, typename V::R_Ctx Ctx) {
+  if (Cexpr)
+    return Vs.reduceLiteral(*this);
+
+  switch (ValType.Base) {
+  case ValueType::BT_Void:
+    break;
+  case ValueType::BT_Bool:
+    return Vs.reduceLiteralT(as<bool>());
+  case ValueType::BT_Int: {
+    switch (ValType.Size) {
+    case ValueType::ST_8:
+      if (ValType.Signed)
+        return Vs.reduceLiteralT(as<int8_t>());
+      else
+        return Vs.reduceLiteralT(as<uint8_t>());
+    case ValueType::ST_16:
+      if (ValType.Signed)
+        return Vs.reduceLiteralT(as<int16_t>());
+      else
+        return Vs.reduceLiteralT(as<uint16_t>());
+    case ValueType::ST_32:
+      if (ValType.Signed)
+        return Vs.reduceLiteralT(as<int32_t>());
+      else
+        return Vs.reduceLiteralT(as<uint32_t>());
+    case ValueType::ST_64:
+      if (ValType.Signed)
+        return Vs.reduceLiteralT(as<int64_t>());
+      else
+        return Vs.reduceLiteralT(as<uint64_t>());
+    default:
+      break;
+    }
+  }
+  case ValueType::BT_Float: {
+    switch (ValType.Size) {
+    case ValueType::ST_32:
+      return Vs.reduceLiteralT(as<float>());
+    case ValueType::ST_64:
+      return Vs.reduceLiteralT(as<double>());
+    default:
+      break;
+    }
+  }
+  case ValueType::BT_String:
+    return Vs.reduceLiteralT(as<StringRef>());
+  case ValueType::BT_Pointer:
+    return Vs.reduceLiteralT(as<void*>());
+  case ValueType::BT_ValueRef:
+    break;
+  }
+  return Vs.reduceLiteral(*this);
+}
+
+
+// Literal pointer to an object allocated in memory.
+// At compile time, pointer literals are represented by symbolic names.
+class LiteralPtr : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_LiteralPtr; }
+
+  LiteralPtr(const clang::ValueDecl *D) : SExpr(COP_LiteralPtr), Cvdecl(D) {}
+  LiteralPtr(const LiteralPtr &R) : SExpr(R), Cvdecl(R.Cvdecl) {}
+
+  // The clang declaration for the value that this pointer points to.
+  const clang::ValueDecl *clangDecl() const { return Cvdecl; }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    return Vs.reduceLiteralPtr(*this);
+  }
+
+  template <class C> typename C::CType compare(LiteralPtr* E, C& Cmp) {
+    return Cmp.comparePointers(Cvdecl, E->Cvdecl);
+  }
+
+private:
+  const clang::ValueDecl *Cvdecl;
+};
+
+
+// A function -- a.k.a. lambda abstraction.
+// Functions with multiple arguments are created by currying,
+// e.g. (function (x: Int) (function (y: Int) (add x y)))
+class Function : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Function; }
+
+  Function(Variable *Vd, SExpr *Bd)
+      : SExpr(COP_Function), VarDecl(Vd), Body(Bd) {
+    Vd->setKind(Variable::VK_Fun);
+  }
+  Function(const Function &F, Variable *Vd, SExpr *Bd) // rewrite constructor
+      : SExpr(F), VarDecl(Vd), Body(Bd) {
+    Vd->setKind(Variable::VK_Fun);
+  }
+
+  Variable *variableDecl()  { return VarDecl; }
+  const Variable *variableDecl() const { return VarDecl; }
+
+  SExpr *body() { return Body.get(); }
+  const SExpr *body() const { return Body.get(); }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    // This is a variable declaration, so traverse the definition.
+    auto E0 = Vs.traverse(VarDecl->Definition, Vs.typeCtx(Ctx));
+    // Tell the rewriter to enter the scope of the function.
+    Variable *Nvd = Vs.enterScope(*VarDecl, E0);
+    auto E1 = Vs.traverse(Body, Vs.declCtx(Ctx));
+    Vs.exitScope(*VarDecl);
+    return Vs.reduceFunction(*this, Nvd, E1);
+  }
+
+  template <class C> typename C::CType compare(Function* E, C& Cmp) {
+    typename C::CType Ct =
+      Cmp.compare(VarDecl->definition(), E->VarDecl->definition());
+    if (Cmp.notTrue(Ct))
+      return Ct;
+    Cmp.enterScope(variableDecl(), E->variableDecl());
+    Ct = Cmp.compare(body(), E->body());
+    Cmp.leaveScope();
+    return Ct;
+  }
+
+private:
+  Variable *VarDecl;
+  SExprRef Body;
+};
+
+
+// A self-applicable function.
+// A self-applicable function can be applied to itself.  It's useful for
+// implementing objects and late binding
+class SFunction : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_SFunction; }
+
+  SFunction(Variable *Vd, SExpr *B)
+      : SExpr(COP_SFunction), VarDecl(Vd), Body(B) {
+    assert(Vd->Definition == nullptr);
+    Vd->setKind(Variable::VK_SFun);
+    Vd->Definition.reset(this);
+  }
+  SFunction(const SFunction &F, Variable *Vd, SExpr *B) // rewrite constructor
+      : SExpr(F), VarDecl(Vd), Body(B) {
+    assert(Vd->Definition == nullptr);
+    Vd->setKind(Variable::VK_SFun);
+    Vd->Definition.reset(this);
+  }
+
+  Variable *variableDecl() { return VarDecl; }
+  const Variable *variableDecl() const { return VarDecl; }
+
+  SExpr *body() { return Body.get(); }
+  const SExpr *body() const { return Body.get(); }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    // A self-variable points to the SFunction itself.
+    // A rewrite must introduce the variable with a null definition, and update
+    // it after 'this' has been rewritten.
+    Variable *Nvd = Vs.enterScope(*VarDecl, nullptr);
+    auto E1 = Vs.traverse(Body, Vs.declCtx(Ctx));
+    Vs.exitScope(*VarDecl);
+    // A rewrite operation will call SFun constructor to set Vvd->Definition.
+    return Vs.reduceSFunction(*this, Nvd, E1);
+  }
+
+  template <class C> typename C::CType compare(SFunction* E, C& Cmp) {
+    Cmp.enterScope(variableDecl(), E->variableDecl());
+    typename C::CType Ct = Cmp.compare(body(), E->body());
+    Cmp.leaveScope();
+    return Ct;
+  }
+
+private:
+  Variable *VarDecl;
+  SExprRef Body;
+};
+
+
+// A block of code -- e.g. the body of a function.
+class Code : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Code; }
+
+  Code(SExpr *T, SExpr *B) : SExpr(COP_Code), ReturnType(T), Body(B) {}
+  Code(const Code &C, SExpr *T, SExpr *B) // rewrite constructor
+      : SExpr(C), ReturnType(T), Body(B) {}
+
+  SExpr *returnType() { return ReturnType.get(); }
+  const SExpr *returnType() const { return ReturnType.get(); }
+
+  SExpr *body() { return Body.get(); }
+  const SExpr *body() const { return Body.get(); }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Nt = Vs.traverse(ReturnType, Vs.typeCtx(Ctx));
+    auto Nb = Vs.traverse(Body,       Vs.lazyCtx(Ctx));
+    return Vs.reduceCode(*this, Nt, Nb);
+  }
+
+  template <class C> typename C::CType compare(Code* E, C& Cmp) {
+    typename C::CType Ct = Cmp.compare(returnType(), E->returnType());
+    if (Cmp.notTrue(Ct))
+      return Ct;
+    return Cmp.compare(body(), E->body());
+  }
+
+private:
+  SExprRef ReturnType;
+  SExprRef Body;
+};
+
+
+// A typed, writable location in memory
+class Field : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Field; }
+
+  Field(SExpr *R, SExpr *B) : SExpr(COP_Field), Range(R), Body(B) {}
+  Field(const Field &C, SExpr *R, SExpr *B) // rewrite constructor
+      : SExpr(C), Range(R), Body(B) {}
+
+  SExpr *range() { return Range.get(); }
+  const SExpr *range() const { return Range.get(); }
+
+  SExpr *body() { return Body.get(); }
+  const SExpr *body() const { return Body.get(); }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Nr = Vs.traverse(Range, Vs.typeCtx(Ctx));
+    auto Nb = Vs.traverse(Body,  Vs.lazyCtx(Ctx));
+    return Vs.reduceField(*this, Nr, Nb);
+  }
+
+  template <class C> typename C::CType compare(Field* E, C& Cmp) {
+    typename C::CType Ct = Cmp.compare(range(), E->range());
+    if (Cmp.notTrue(Ct))
+      return Ct;
+    return Cmp.compare(body(), E->body());
+  }
+
+private:
+  SExprRef Range;
+  SExprRef Body;
+};
+
+
+// Apply an argument to a function
+class Apply : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Apply; }
+
+  Apply(SExpr *F, SExpr *A) : SExpr(COP_Apply), Fun(F), Arg(A) {}
+  Apply(const Apply &A, SExpr *F, SExpr *Ar)  // rewrite constructor
+      : SExpr(A), Fun(F), Arg(Ar)
+  {}
+
+  SExpr *fun() { return Fun.get(); }
+  const SExpr *fun() const { return Fun.get(); }
+
+  SExpr *arg() { return Arg.get(); }
+  const SExpr *arg() const { return Arg.get(); }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Nf = Vs.traverse(Fun, Vs.subExprCtx(Ctx));
+    auto Na = Vs.traverse(Arg, Vs.subExprCtx(Ctx));
+    return Vs.reduceApply(*this, Nf, Na);
+  }
+
+  template <class C> typename C::CType compare(Apply* E, C& Cmp) {
+    typename C::CType Ct = Cmp.compare(fun(), E->fun());
+    if (Cmp.notTrue(Ct))
+      return Ct;
+    return Cmp.compare(arg(), E->arg());
+  }
+
+private:
+  SExprRef Fun;
+  SExprRef Arg;
+};
+
+
+// Apply a self-argument to a self-applicable function
+class SApply : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_SApply; }
+
+  SApply(SExpr *Sf, SExpr *A = nullptr) : SExpr(COP_SApply), Sfun(Sf), Arg(A) {}
+  SApply(SApply &A, SExpr *Sf, SExpr *Ar = nullptr) // rewrite constructor
+      : SExpr(A), Sfun(Sf), Arg(Ar) {}
+
+  SExpr *sfun() { return Sfun.get(); }
+  const SExpr *sfun() const { return Sfun.get(); }
+
+  SExpr *arg() { return Arg.get() ? Arg.get() : Sfun.get(); }
+  const SExpr *arg() const { return Arg.get() ? Arg.get() : Sfun.get(); }
+
+  bool isDelegation() const { return Arg == nullptr; }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Nf = Vs.traverse(Sfun, Vs.subExprCtx(Ctx));
+    typename V::R_SExpr Na = Arg.get() ? Vs.traverse(Arg, Vs.subExprCtx(Ctx))
+                                       : nullptr;
+    return Vs.reduceSApply(*this, Nf, Na);
+  }
+
+  template <class C> typename C::CType compare(SApply* E, C& Cmp) {
+    typename C::CType Ct = Cmp.compare(sfun(), E->sfun());
+    if (Cmp.notTrue(Ct) || (!arg() && !E->arg()))
+      return Ct;
+    return Cmp.compare(arg(), E->arg());
+  }
+
+private:
+  SExprRef Sfun;
+  SExprRef Arg;
+};
+
+
+// Project a named slot from a C++ struct or class.
+class Project : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Project; }
+
+  Project(SExpr *R, StringRef SName)
+      : SExpr(COP_Project), Rec(R), SlotName(SName), Cvdecl(nullptr)
+  { }
+  Project(SExpr *R, clang::ValueDecl *Cvd)
+      : SExpr(COP_Project), Rec(R), SlotName(Cvd->getName()), Cvdecl(Cvd)
+  { }
+  Project(const Project &P, SExpr *R)
+      : SExpr(P), Rec(R), SlotName(P.SlotName), Cvdecl(P.Cvdecl)
+  { }
+
+  SExpr *record() { return Rec.get(); }
+  const SExpr *record() const { return Rec.get(); }
+
+  const clang::ValueDecl *clangValueDecl() const { return Cvdecl; }
+
+  StringRef slotName() const {
+    if (Cvdecl)
+      return Cvdecl->getName();
+    else
+      return SlotName;
+  }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Nr = Vs.traverse(Rec, Vs.subExprCtx(Ctx));
+    return Vs.reduceProject(*this, Nr);
+  }
+
+  template <class C> typename C::CType compare(Project* E, C& Cmp) {
+    typename C::CType Ct = Cmp.compare(record(), E->record());
+    if (Cmp.notTrue(Ct))
+      return Ct;
+    return Cmp.comparePointers(Cvdecl, E->Cvdecl);
+  }
+
+private:
+  SExprRef Rec;
+  StringRef SlotName;
+  clang::ValueDecl *Cvdecl;
+};
+
+
+// Call a function (after all arguments have been applied).
+class Call : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Call; }
+
+  Call(SExpr *T, const clang::CallExpr *Ce = nullptr)
+      : SExpr(COP_Call), Target(T), Cexpr(Ce) {}
+  Call(const Call &C, SExpr *T) : SExpr(C), Target(T), Cexpr(C.Cexpr) {}
+
+  SExpr *target() { return Target.get(); }
+  const SExpr *target() const { return Target.get(); }
+
+  const clang::CallExpr *clangCallExpr() const { return Cexpr; }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Nt = Vs.traverse(Target, Vs.subExprCtx(Ctx));
+    return Vs.reduceCall(*this, Nt);
+  }
+
+  template <class C> typename C::CType compare(Call* E, C& Cmp) {
+    return Cmp.compare(target(), E->target());
+  }
+
+private:
+  SExprRef Target;
+  const clang::CallExpr *Cexpr;
+};
+
+
+// Allocate memory for a new value on the heap or stack.
+class Alloc : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Call; }
+
+  enum AllocKind {
+    AK_Stack,
+    AK_Heap
+  };
+
+  Alloc(SExpr *D, AllocKind K) : SExpr(COP_Alloc), Dtype(D) { Flags = K; }
+  Alloc(const Alloc &A, SExpr *Dt) : SExpr(A), Dtype(Dt) { Flags = A.kind(); }
+
+  AllocKind kind() const { return static_cast<AllocKind>(Flags); }
+
+  SExpr *dataType() { return Dtype.get(); }
+  const SExpr *dataType() const { return Dtype.get(); }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Nd = Vs.traverse(Dtype, Vs.declCtx(Ctx));
+    return Vs.reduceAlloc(*this, Nd);
+  }
+
+  template <class C> typename C::CType compare(Alloc* E, C& Cmp) {
+    typename C::CType Ct = Cmp.compareIntegers(kind(), E->kind());
+    if (Cmp.notTrue(Ct))
+      return Ct;
+    return Cmp.compare(dataType(), E->dataType());
+  }
+
+private:
+  SExprRef Dtype;
+};
+
+
+// Load a value from memory.
+class Load : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Load; }
+
+  Load(SExpr *P) : SExpr(COP_Load), Ptr(P) {}
+  Load(const Load &L, SExpr *P) : SExpr(L), Ptr(P) {}
+
+  SExpr *pointer() { return Ptr.get(); }
+  const SExpr *pointer() const { return Ptr.get(); }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Np = Vs.traverse(Ptr, Vs.subExprCtx(Ctx));
+    return Vs.reduceLoad(*this, Np);
+  }
+
+  template <class C> typename C::CType compare(Load* E, C& Cmp) {
+    return Cmp.compare(pointer(), E->pointer());
+  }
+
+private:
+  SExprRef Ptr;
+};
+
+
+// Store a value to memory.
+// Source is a pointer, destination is the value to store.
+class Store : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Store; }
+
+  Store(SExpr *P, SExpr *V) : SExpr(COP_Store), Dest(P), Source(V) {}
+  Store(const Store &S, SExpr *P, SExpr *V) : SExpr(S), Dest(P), Source(V) {}
+
+  SExpr *destination() { return Dest.get(); }  // Address to store to
+  const SExpr *destination() const { return Dest.get(); }
+
+  SExpr *source() { return Source.get(); }     // Value to store
+  const SExpr *source() const { return Source.get(); }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Np = Vs.traverse(Dest,   Vs.subExprCtx(Ctx));
+    auto Nv = Vs.traverse(Source, Vs.subExprCtx(Ctx));
+    return Vs.reduceStore(*this, Np, Nv);
+  }
+
+  template <class C> typename C::CType compare(Store* E, C& Cmp) {
+    typename C::CType Ct = Cmp.compare(destination(), E->destination());
+    if (Cmp.notTrue(Ct))
+      return Ct;
+    return Cmp.compare(source(), E->source());
+  }
+
+private:
+  SExprRef Dest;
+  SExprRef Source;
+};
+
+
+// If p is a reference to an array, then first(p) is a reference to the first
+// element.  The usual array notation p[i]  becomes first(p + i).
+class ArrayIndex : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_ArrayIndex; }
+
+  ArrayIndex(SExpr *A, SExpr *N) : SExpr(COP_ArrayIndex), Array(A), Index(N) {}
+  ArrayIndex(const ArrayIndex &E, SExpr *A, SExpr *N)
+    : SExpr(E), Array(A), Index(N) {}
+
+  SExpr *array() { return Array.get(); }
+  const SExpr *array() const { return Array.get(); }
+
+  SExpr *index() { return Index.get(); }
+  const SExpr *index() const { return Index.get(); }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Na = Vs.traverse(Array, Vs.subExprCtx(Ctx));
+    auto Ni = Vs.traverse(Index, Vs.subExprCtx(Ctx));
+    return Vs.reduceArrayIndex(*this, Na, Ni);
+  }
+
+  template <class C> typename C::CType compare(ArrayIndex* E, C& Cmp) {
+    typename C::CType Ct = Cmp.compare(array(), E->array());
+    if (Cmp.notTrue(Ct))
+      return Ct;
+    return Cmp.compare(index(), E->index());
+  }
+
+private:
+  SExprRef Array;
+  SExprRef Index;
+};
+
+
+// Pointer arithmetic, restricted to arrays only.
+// If p is a reference to an array, then p + n, where n is an integer, is
+// a reference to a subarray.
+class ArrayAdd : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_ArrayAdd; }
+
+  ArrayAdd(SExpr *A, SExpr *N) : SExpr(COP_ArrayAdd), Array(A), Index(N) {}
+  ArrayAdd(const ArrayAdd &E, SExpr *A, SExpr *N)
+    : SExpr(E), Array(A), Index(N) {}
+
+  SExpr *array() { return Array.get(); }
+  const SExpr *array() const { return Array.get(); }
+
+  SExpr *index() { return Index.get(); }
+  const SExpr *index() const { return Index.get(); }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Na = Vs.traverse(Array, Vs.subExprCtx(Ctx));
+    auto Ni = Vs.traverse(Index, Vs.subExprCtx(Ctx));
+    return Vs.reduceArrayAdd(*this, Na, Ni);
+  }
+
+  template <class C> typename C::CType compare(ArrayAdd* E, C& Cmp) {
+    typename C::CType Ct = Cmp.compare(array(), E->array());
+    if (Cmp.notTrue(Ct))
+      return Ct;
+    return Cmp.compare(index(), E->index());
+  }
+
+private:
+  SExprRef Array;
+  SExprRef Index;
+};
+
+
+// Simple unary operation -- e.g. !, ~, etc.
+class UnaryOp : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_UnaryOp; }
+
+  UnaryOp(TIL_UnaryOpcode Op, SExpr *E) : SExpr(COP_UnaryOp), Expr0(E) {
+    Flags = Op;
+  }
+  UnaryOp(const UnaryOp &U, SExpr *E) : SExpr(U), Expr0(E) { Flags = U.Flags; }
+
+  TIL_UnaryOpcode unaryOpcode() const {
+    return static_cast<TIL_UnaryOpcode>(Flags);
+  }
+
+  SExpr *expr() { return Expr0.get(); }
+  const SExpr *expr() const { return Expr0.get(); }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Ne = Vs.traverse(Expr0, Vs.subExprCtx(Ctx));
+    return Vs.reduceUnaryOp(*this, Ne);
+  }
+
+  template <class C> typename C::CType compare(UnaryOp* E, C& Cmp) {
+    typename C::CType Ct =
+      Cmp.compareIntegers(unaryOpcode(), E->unaryOpcode());
+    if (Cmp.notTrue(Ct))
+      return Ct;
+    return Cmp.compare(expr(), E->expr());
+  }
+
+private:
+  SExprRef Expr0;
+};
+
+
+// Simple binary operation -- e.g. +, -, etc.
+class BinaryOp : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_BinaryOp; }
+
+  BinaryOp(TIL_BinaryOpcode Op, SExpr *E0, SExpr *E1)
+      : SExpr(COP_BinaryOp), Expr0(E0), Expr1(E1) {
+    Flags = Op;
+  }
+  BinaryOp(const BinaryOp &B, SExpr *E0, SExpr *E1)
+      : SExpr(B), Expr0(E0), Expr1(E1) {
+    Flags = B.Flags;
+  }
+
+  TIL_BinaryOpcode binaryOpcode() const {
+    return static_cast<TIL_BinaryOpcode>(Flags);
+  }
+
+  SExpr *expr0() { return Expr0.get(); }
+  const SExpr *expr0() const { return Expr0.get(); }
+
+  SExpr *expr1() { return Expr1.get(); }
+  const SExpr *expr1() const { return Expr1.get(); }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Ne0 = Vs.traverse(Expr0, Vs.subExprCtx(Ctx));
+    auto Ne1 = Vs.traverse(Expr1, Vs.subExprCtx(Ctx));
+    return Vs.reduceBinaryOp(*this, Ne0, Ne1);
+  }
+
+  template <class C> typename C::CType compare(BinaryOp* E, C& Cmp) {
+    typename C::CType Ct =
+      Cmp.compareIntegers(binaryOpcode(), E->binaryOpcode());
+    if (Cmp.notTrue(Ct))
+      return Ct;
+    Ct = Cmp.compare(expr0(), E->expr0());
+    if (Cmp.notTrue(Ct))
+      return Ct;
+    return Cmp.compare(expr1(), E->expr1());
+  }
+
+private:
+  SExprRef Expr0;
+  SExprRef Expr1;
+};
+
+
+// Cast expression
+class Cast : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Cast; }
+
+  Cast(TIL_CastOpcode Op, SExpr *E) : SExpr(COP_Cast), Expr0(E) { Flags = Op; }
+  Cast(const Cast &C, SExpr *E) : SExpr(C), Expr0(E) { Flags = C.Flags; }
+
+  TIL_CastOpcode castOpcode() const {
+    return static_cast<TIL_CastOpcode>(Flags);
+  }
+
+  SExpr *expr() { return Expr0.get(); }
+  const SExpr *expr() const { return Expr0.get(); }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Ne = Vs.traverse(Expr0, Vs.subExprCtx(Ctx));
+    return Vs.reduceCast(*this, Ne);
+  }
+
+  template <class C> typename C::CType compare(Cast* E, C& Cmp) {
+    typename C::CType Ct =
+      Cmp.compareIntegers(castOpcode(), E->castOpcode());
+    if (Cmp.notTrue(Ct))
+      return Ct;
+    return Cmp.compare(expr(), E->expr());
+  }
+
+private:
+  SExprRef Expr0;
+};
+
+
+class SCFG;
+
+
+class Phi : public SExpr {
+public:
+  // TODO: change to SExprRef
+  typedef SimpleArray<SExpr *> ValArray;
+
+  // In minimal SSA form, all Phi nodes are MultiVal.
+  // During conversion to SSA, incomplete Phi nodes may be introduced, which
+  // are later determined to be SingleVal, and are thus redundant.
+  enum Status {
+    PH_MultiVal = 0, // Phi node has multiple distinct values.  (Normal)
+    PH_SingleVal,    // Phi node has one distinct value, and can be eliminated
+    PH_Incomplete    // Phi node is incomplete
+  };
+
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Phi; }
+
+  Phi() : SExpr(COP_Phi) {}
+  Phi(MemRegionRef A, unsigned Nvals) : SExpr(COP_Phi), Values(A, Nvals) {}
+  Phi(const Phi &P, ValArray &&Vs)    : SExpr(P), Values(std::move(Vs)) {}
+
+  const ValArray &values() const { return Values; }
+  ValArray &values() { return Values; }
+
+  Status status() const { return static_cast<Status>(Flags); }
+  void setStatus(Status s) { Flags = s; }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    typename V::template Container<typename V::R_SExpr>
+      Nvs(Vs, Values.size());
+
+    for (auto *Val : Values) {
+      Nvs.push_back( Vs.traverse(Val, Vs.subExprCtx(Ctx)) );
+    }
+    return Vs.reducePhi(*this, Nvs);
+  }
+
+  template <class C> typename C::CType compare(Phi *E, C &Cmp) {
+    // TODO: implement CFG comparisons
+    return Cmp.comparePointers(this, E);
+  }
+
+private:
+  ValArray Values;
+};
+
+
+// A basic block is part of an SCFG, and can be treated as a function in
+// continuation passing style.  It consists of a sequence of phi nodes, which
+// are "arguments" to the function, followed by a sequence of instructions.
+// Both arguments and instructions define new variables.  It ends with a
+// branch or goto to another basic block in the same SCFG.
+class BasicBlock : public SExpr {
+public:
+  typedef SimpleArray<Variable*>   VarArray;
+  typedef SimpleArray<BasicBlock*> BlockArray;
+
+  static bool classof(const SExpr *E) { return E->opcode() == COP_BasicBlock; }
+
+  explicit BasicBlock(MemRegionRef A, BasicBlock* P = nullptr)
+      : SExpr(COP_BasicBlock), Arena(A), CFGPtr(nullptr), BlockID(0),
+        Parent(P), Terminator(nullptr)
+  { }
+  BasicBlock(BasicBlock &B, VarArray &&As, VarArray &&Is, SExpr *T)
+      : SExpr(COP_BasicBlock), Arena(B.Arena), CFGPtr(nullptr), BlockID(0),
+        Parent(nullptr), Args(std::move(As)), Instrs(std::move(Is)),
+        Terminator(T)
+  { }
+
+  unsigned blockID() const { return BlockID; }
+  unsigned numPredecessors() const { return Predecessors.size(); }
+
+  const SCFG* cfg() const { return CFGPtr; }
+  SCFG* cfg() { return CFGPtr; }
+
+  const BasicBlock *parent() const { return Parent; }
+  BasicBlock *parent() { return Parent; }
+
+  const VarArray &arguments() const { return Args; }
+  VarArray &arguments() { return Args; }
+
+  const VarArray &instructions() const { return Instrs; }
+  VarArray &instructions() { return Instrs; }
+
+  const BlockArray &predecessors() const { return Predecessors; }
+  BlockArray &predecessors() { return Predecessors; }
+
+  const SExpr *terminator() const { return Terminator.get(); }
+  SExpr *terminator() { return Terminator.get(); }
+
+  void setBlockID(unsigned i)   { BlockID = i; }
+  void setParent(BasicBlock *P) { Parent = P;  }
+  void setTerminator(SExpr *E)  { Terminator.reset(E); }
+
+  // Add a new argument.  V must define a phi-node.
+  void addArgument(Variable *V) {
+    V->setKind(Variable::VK_LetBB);
+    Args.reserveCheck(1, Arena);
+    Args.push_back(V);
+  }
+  // Add a new instruction.
+  void addInstruction(Variable *V) {
+    V->setKind(Variable::VK_LetBB);
+    Instrs.reserveCheck(1, Arena);
+    Instrs.push_back(V);
+  }
+  // Add a new predecessor, and return the phi-node index for it.
+  // Will add an argument to all phi-nodes, initialized to nullptr.
+  unsigned addPredecessor(BasicBlock *Pred);
+
+  // Reserve space for Nargs arguments.
+  void reserveArguments(unsigned Nargs)   { Args.reserve(Nargs, Arena); }
+
+  // Reserve space for Nins instructions.
+  void reserveInstructions(unsigned Nins) { Instrs.reserve(Nins, Arena); }
+
+  // Reserve space for NumPreds predecessors, including space in phi nodes.
+  void reservePredecessors(unsigned NumPreds);
+
+  // Return the index of BB, or Predecessors.size if BB is not a predecessor.
+  unsigned findPredecessorIndex(const BasicBlock *BB) const {
+    auto I = std::find(Predecessors.cbegin(), Predecessors.cend(), BB);
+    return std::distance(Predecessors.cbegin(), I);
+  }
+
+  // Set id numbers for variables.
+  void renumberVars();
+
+  template <class V>
+  typename V::R_BasicBlock traverse(V &Vs, typename V::R_Ctx Ctx) {
+    typename V::template Container<Variable*> Nas(Vs, Args.size());
+    typename V::template Container<Variable*> Nis(Vs, Instrs.size());
+
+    // Entering the basic block should do any scope initialization.
+    Vs.enterBasicBlock(*this);
+
+    for (auto *A : Args) {
+      auto Ne = Vs.traverse(A->Definition, Vs.subExprCtx(Ctx));
+      Variable *Nvd = Vs.enterScope(*A, Ne);
+      Nas.push_back(Nvd);
+    }
+    for (auto *I : Instrs) {
+      auto Ne = Vs.traverse(I->Definition, Vs.subExprCtx(Ctx));
+      Variable *Nvd = Vs.enterScope(*I, Ne);
+      Nis.push_back(Nvd);
+    }
+    auto Nt = Vs.traverse(Terminator, Ctx);
+
+    // Exiting the basic block should handle any scope cleanup.
+    Vs.exitBasicBlock(*this);
+
+    return Vs.reduceBasicBlock(*this, Nas, Nis, Nt);
+  }
+
+  template <class C> typename C::CType compare(BasicBlock *E, C &Cmp) {
+    // TODO: implement CFG comparisons
+    return Cmp.comparePointers(this, E);
+  }
+
+private:
+  friend class SCFG;
+
+  MemRegionRef Arena;
+
+  SCFG       *CFGPtr;       // The CFG that contains this block.
+  unsigned   BlockID;       // unique id for this BB in the containing CFG
+  BasicBlock *Parent;       // The parent block is the enclosing lexical scope.
+                            // The parent dominates this block.
+  BlockArray Predecessors;  // Predecessor blocks in the CFG.
+  VarArray   Args;          // Phi nodes.  One argument per predecessor.
+  VarArray   Instrs;        // Instructions.
+  SExprRef   Terminator;    // Branch or Goto
+};
+
+
+// An SCFG is a control-flow graph.  It consists of a set of basic blocks, each
+// of which terminates in a branch to another basic block.  There is one
+// entry point, and one exit point.
+class SCFG : public SExpr {
+public:
+  typedef SimpleArray<BasicBlock *> BlockArray;
+  typedef BlockArray::iterator iterator;
+  typedef BlockArray::const_iterator const_iterator;
+
+  static bool classof(const SExpr *E) { return E->opcode() == COP_SCFG; }
+
+  SCFG(MemRegionRef A, unsigned Nblocks)
+    : SExpr(COP_SCFG), Arena(A), Blocks(A, Nblocks),
+      Entry(nullptr), Exit(nullptr) {
+    Entry = new (A) BasicBlock(A, nullptr);
+    Exit  = new (A) BasicBlock(A, Entry);
+    auto *V = new (A) Variable(new (A) Phi());
+    Exit->addArgument(V);
+    add(Entry);
+    add(Exit);
+  }
+  SCFG(const SCFG &Cfg, BlockArray &&Ba) // steals memory from Ba
+      : SExpr(COP_SCFG), Arena(Cfg.Arena), Blocks(std::move(Ba)),
+        Entry(nullptr), Exit(nullptr) {
+    // TODO: set entry and exit!
+  }
+
+  iterator begin() { return Blocks.begin(); }
+  iterator end() { return Blocks.end(); }
+
+  const_iterator begin() const { return cbegin(); }
+  const_iterator end() const { return cend(); }
+
+  const_iterator cbegin() const { return Blocks.cbegin(); }
+  const_iterator cend() const { return Blocks.cend(); }
+
+  const BasicBlock *entry() const { return Entry; }
+  BasicBlock *entry() { return Entry; }
+  const BasicBlock *exit() const { return Exit; }
+  BasicBlock *exit() { return Exit; }
+
+  inline void add(BasicBlock *BB) {
+    assert(BB->CFGPtr == nullptr || BB->CFGPtr == this);
+    BB->setBlockID(Blocks.size());
+    BB->CFGPtr = this;
+    Blocks.reserveCheck(1, Arena);
+    Blocks.push_back(BB);
+  }
+
+  void setEntry(BasicBlock *BB) { Entry = BB; }
+  void setExit(BasicBlock *BB)  { Exit = BB;  }
+
+  // Set varable ids in all blocks.
+  void renumberVars();
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    Vs.enterCFG(*this);
+    typename V::template Container<BasicBlock *> Bbs(Vs, Blocks.size());
+    for (auto *B : Blocks) {
+      Bbs.push_back( B->traverse(Vs, Vs.subExprCtx(Ctx)) );
+    }
+    Vs.exitCFG(*this);
+    return Vs.reduceSCFG(*this, Bbs);
+  }
+
+  template <class C> typename C::CType compare(SCFG *E, C &Cmp) {
+    // TODO -- implement CFG comparisons
+    return Cmp.comparePointers(this, E);
+  }
+
+private:
+  MemRegionRef Arena;
+  BlockArray   Blocks;
+  BasicBlock   *Entry;
+  BasicBlock   *Exit;
+};
+
+
+class Goto : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Goto; }
+
+  Goto(BasicBlock *B, unsigned I)
+      : SExpr(COP_Goto), TargetBlock(B), Index(I) {}
+  Goto(const Goto &G, BasicBlock *B, unsigned I)
+      : SExpr(COP_Goto), TargetBlock(B), Index(I) {}
+
+  const BasicBlock *targetBlock() const { return TargetBlock; }
+  BasicBlock *targetBlock() { return TargetBlock; }
+
+  unsigned index() const { return Index; }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    BasicBlock *Ntb = Vs.reduceBasicBlockRef(TargetBlock);
+    return Vs.reduceGoto(*this, Ntb);
+  }
+
+  template <class C> typename C::CType compare(Goto *E, C &Cmp) {
+    // TODO -- implement CFG comparisons
+    return Cmp.comparePointers(this, E);
+  }
+
+private:
+  BasicBlock *TargetBlock;
+  unsigned Index;   // Index into Phi nodes of target block.
+};
+
+
+class Branch : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Branch; }
+
+  Branch(SExpr *C, BasicBlock *T, BasicBlock *E, unsigned TI, unsigned EI)
+      : SExpr(COP_Branch), Condition(C), ThenBlock(T), ElseBlock(E),
+        ThenIndex(TI), ElseIndex(EI)
+  {}
+  Branch(const Branch &Br, SExpr *C, BasicBlock *T, BasicBlock *E,
+         unsigned TI, unsigned EI)
+      : SExpr(COP_Branch), Condition(C), ThenBlock(T), ElseBlock(E),
+        ThenIndex(TI), ElseIndex(EI)
+  {}
+
+  const SExpr *condition() const { return Condition; }
+  SExpr *condition() { return Condition; }
+
+  const BasicBlock *thenBlock() const { return ThenBlock; }
+  BasicBlock *thenBlock() { return ThenBlock; }
+
+  const BasicBlock *elseBlock() const { return ElseBlock; }
+  BasicBlock *elseBlock() { return ElseBlock; }
+
+  unsigned thenIndex() const { return ThenIndex; }
+  unsigned elseIndex() const { return ElseIndex; }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Nc = Vs.traverse(Condition, Vs.subExprCtx(Ctx));
+    BasicBlock *Ntb = Vs.reduceBasicBlockRef(ThenBlock);
+    BasicBlock *Nte = Vs.reduceBasicBlockRef(ElseBlock);
+    return Vs.reduceBranch(*this, Nc, Ntb, Nte);
+  }
+
+  template <class C> typename C::CType compare(Branch *E, C &Cmp) {
+    // TODO -- implement CFG comparisons
+    return Cmp.comparePointers(this, E);
+  }
+
+private:
+  SExpr *Condition;
+  BasicBlock *ThenBlock;
+  BasicBlock *ElseBlock;
+  unsigned ThenIndex;
+  unsigned ElseIndex;
+};
+
+
+// An identifier, e.g. 'foo' or 'x'.
+// This is a pseduo-term; it will be lowered to a variable or projection.
+class Identifier : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Identifier; }
+
+  Identifier(StringRef Id): SExpr(COP_Identifier), Name(Id) { }
+  Identifier(const Identifier& I) : SExpr(I), Name(I.Name)  { }
+
+  StringRef name() const { return Name; }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    return Vs.reduceIdentifier(*this);
+  }
+
+  template <class C> typename C::CType compare(Identifier* E, C& Cmp) {
+    return Cmp.compareStrings(name(), E->name());
+  }
+
+private:
+  StringRef Name;
+};
+
+
+// An if-then-else expression.
+// This is a pseduo-term; it will be lowered to a branch in a CFG.
+class IfThenElse : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_IfThenElse; }
+
+  IfThenElse(SExpr *C, SExpr *T, SExpr *E)
+    : SExpr(COP_IfThenElse), Condition(C), ThenExpr(T), ElseExpr(E)
+  { }
+  IfThenElse(const IfThenElse &I, SExpr *C, SExpr *T, SExpr *E)
+    : SExpr(I), Condition(C), ThenExpr(T), ElseExpr(E)
+  { }
+
+  SExpr *condition() { return Condition.get(); }   // Address to store to
+  const SExpr *condition() const { return Condition.get(); }
+
+  SExpr *thenExpr() { return ThenExpr.get(); }     // Value to store
+  const SExpr *thenExpr() const { return ThenExpr.get(); }
+
+  SExpr *elseExpr() { return ElseExpr.get(); }     // Value to store
+  const SExpr *elseExpr() const { return ElseExpr.get(); }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    auto Nc = Vs.traverse(Condition, Vs.subExprCtx(Ctx));
+    auto Nt = Vs.traverse(ThenExpr,  Vs.subExprCtx(Ctx));
+    auto Ne = Vs.traverse(ElseExpr,  Vs.subExprCtx(Ctx));
+    return Vs.reduceIfThenElse(*this, Nc, Nt, Ne);
+  }
+
+  template <class C> typename C::CType compare(IfThenElse* E, C& Cmp) {
+    typename C::CType Ct = Cmp.compare(condition(), E->condition());
+    if (Cmp.notTrue(Ct))
+      return Ct;
+    Ct = Cmp.compare(thenExpr(), E->thenExpr());
+    if (Cmp.notTrue(Ct))
+      return Ct;
+    return Cmp.compare(elseExpr(), E->elseExpr());
+  }
+
+private:
+  SExprRef Condition;
+  SExprRef ThenExpr;
+  SExprRef ElseExpr;
+};
+
+
+// A let-expression,  e.g.  let x=t; u.
+// This is a pseduo-term; it will be lowered to instructions in a CFG.
+class Let : public SExpr {
+public:
+  static bool classof(const SExpr *E) { return E->opcode() == COP_Let; }
+
+  Let(Variable *Vd, SExpr *Bd) : SExpr(COP_Let), VarDecl(Vd), Body(Bd) {
+    Vd->setKind(Variable::VK_Let);
+  }
+  Let(const Let &L, Variable *Vd, SExpr *Bd) : SExpr(L), VarDecl(Vd), Body(Bd) {
+    Vd->setKind(Variable::VK_Let);
+  }
+
+  Variable *variableDecl()  { return VarDecl; }
+  const Variable *variableDecl() const { return VarDecl; }
+
+  SExpr *body() { return Body.get(); }
+  const SExpr *body() const { return Body.get(); }
+
+  template <class V>
+  typename V::R_SExpr traverse(V &Vs, typename V::R_Ctx Ctx) {
+    // This is a variable declaration, so traverse the definition.
+    auto E0 = Vs.traverse(VarDecl->Definition, Vs.subExprCtx(Ctx));
+    // Tell the rewriter to enter the scope of the let variable.
+    Variable *Nvd = Vs.enterScope(*VarDecl, E0);
+    auto E1 = Vs.traverse(Body, Ctx);
+    Vs.exitScope(*VarDecl);
+    return Vs.reduceLet(*this, Nvd, E1);
+  }
+
+  template <class C> typename C::CType compare(Let* E, C& Cmp) {
+    typename C::CType Ct =
+      Cmp.compare(VarDecl->definition(), E->VarDecl->definition());
+    if (Cmp.notTrue(Ct))
+      return Ct;
+    Cmp.enterScope(variableDecl(), E->variableDecl());
+    Ct = Cmp.compare(body(), E->body());
+    Cmp.leaveScope();
+    return Ct;
+  }
+
+private:
+  Variable *VarDecl;
+  SExprRef Body;
+};
+
+
+
+SExpr *getCanonicalVal(SExpr *E);
+void simplifyIncompleteArg(Variable *V, til::Phi *Ph);
+
+
+} // end namespace til
+} // end namespace threadSafety
+} // end namespace clang
+
+#endif // LLVM_CLANG_THREAD_SAFETY_TIL_H
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h b/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h
new file mode 100644
index 0000000..bc1490b
--- /dev/null
+++ b/include/clang/Analysis/Analyses/ThreadSafetyTraverse.h
@@ -0,0 +1,936 @@
+//===- ThreadSafetyTraverse.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 a framework for doing generic traversals and rewriting
+// operations over the Thread Safety TIL.
+//
+// UNDER CONSTRUCTION.  USE AT YOUR OWN RISK.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_THREAD_SAFETY_TRAVERSE_H
+#define LLVM_CLANG_THREAD_SAFETY_TRAVERSE_H
+
+#include "ThreadSafetyTIL.h"
+
+namespace clang {
+namespace threadSafety {
+namespace til {
+
+// Defines an interface used to traverse SExprs.  Traversals have been made as
+// generic as possible, and are intended to handle any kind of pass over the
+// AST, e.g. visiters, copying, non-destructive rewriting, destructive
+// (in-place) rewriting, hashing, typing, etc.
+//
+// Traversals implement the functional notion of a "fold" operation on SExprs.
+// Each SExpr class provides a traverse method, which does the following:
+//   * e->traverse(v):
+//       // compute a result r_i for each subexpression e_i
+//       for (i = 1..n)  r_i = v.traverse(e_i);
+//       // combine results into a result for e,  where X is the class of e
+//       return v.reduceX(*e, r_1, .. r_n).
+//
+// A visitor can control the traversal by overriding the following methods:
+//   * v.traverse(e):
+//       return v.traverseByCase(e), which returns v.traverseX(e)
+//   * v.traverseX(e):   (X is the class of e)
+//       return e->traverse(v).
+//   * v.reduceX(*e, r_1, .. r_n):
+//       compute a result for a node of type X
+//
+// The reduceX methods control the kind of traversal (visitor, copy, etc.).
+// They are defined in derived classes.
+//
+// Class R defines the basic interface types (R_SExpr).
+template <class Self, class R>
+class Traversal {
+public:
+  Self *self() { return static_cast<Self *>(this); }
+
+  // Traverse an expression -- returning a result of type R_SExpr.
+  // Override this method to do something for every expression, regardless
+  // of which kind it is.
+  typename R::R_SExpr traverse(SExprRef &E, typename R::R_Ctx Ctx) {
+    return traverse(E.get(), Ctx);
+  }
+
+  typename R::R_SExpr traverse(SExpr *E, typename R::R_Ctx Ctx) {
+    return traverseByCase(E, Ctx);
+  }
+
+  // Helper method to call traverseX(e) on the appropriate type.
+  typename R::R_SExpr traverseByCase(SExpr *E, typename R::R_Ctx Ctx) {
+    switch (E->opcode()) {
+#define TIL_OPCODE_DEF(X)                                                   \
+    case COP_##X:                                                           \
+      return self()->traverse##X(cast<X>(E), Ctx);
+#include "ThreadSafetyOps.def"
+#undef TIL_OPCODE_DEF
+    }
+  }
+
+// Traverse e, by static dispatch on the type "X" of e.
+// Override these methods to do something for a particular kind of term.
+#define TIL_OPCODE_DEF(X)                                                   \
+  typename R::R_SExpr traverse##X(X *e, typename R::R_Ctx Ctx) {            \
+    return e->traverse(*self(), Ctx);                                       \
+  }
+#include "ThreadSafetyOps.def"
+#undef TIL_OPCODE_DEF
+};
+
+
+// Base class for simple reducers that don't much care about the context.
+class SimpleReducerBase {
+public:
+  enum TraversalKind {
+    TRV_Normal,
+    TRV_Decl,
+    TRV_Lazy,
+    TRV_Type
+  };
+
+  // R_Ctx defines a "context" for the traversal, which encodes information
+  // about where a term appears.  This can be used to encoding the
+  // "current continuation" for CPS transforms, or other information.
+  typedef TraversalKind R_Ctx;
+
+  // Create context for an ordinary subexpression.
+  R_Ctx subExprCtx(R_Ctx Ctx) { return TRV_Normal; }
+
+  // Create context for a subexpression that occurs in a declaration position
+  // (e.g. function body).
+  R_Ctx declCtx(R_Ctx Ctx) { return TRV_Decl; }
+
+  // Create context for a subexpression that occurs in a position that
+  // should be reduced lazily.  (e.g. code body).
+  R_Ctx lazyCtx(R_Ctx Ctx) { return TRV_Lazy; }
+
+  // Create context for a subexpression that occurs in a type position.
+  R_Ctx typeCtx(R_Ctx Ctx) { return TRV_Type; }
+};
+
+
+// Base class for traversals that rewrite an SExpr to another SExpr.
+class CopyReducerBase : public SimpleReducerBase {
+public:
+  // R_SExpr is the result type for a traversal.
+  // A copy or non-destructive rewrite returns a newly allocated term.
+  typedef SExpr *R_SExpr;
+  typedef BasicBlock *R_BasicBlock;
+
+  // Container is a minimal interface used to store results when traversing
+  // SExprs of variable arity, such as Phi, Goto, and SCFG.
+  template <class T> class Container {
+  public:
+    // Allocate a new container with a capacity for n elements.
+    Container(CopyReducerBase &S, unsigned N) : Elems(S.Arena, N) {}
+
+    // Push a new element onto the container.
+    void push_back(T E) { Elems.push_back(E); }
+
+    SimpleArray<T> Elems;
+  };
+
+  CopyReducerBase(MemRegionRef A) : Arena(A) {}
+
+protected:
+  MemRegionRef Arena;
+};
+
+
+// Implements a traversal that makes a deep copy of an SExpr.
+// The default behavior of reduce##X(...) is to create a copy of the original.
+// Subclasses can override reduce##X to implement non-destructive rewriting
+// passes.
+template<class Self>
+class CopyReducer : public Traversal<Self, CopyReducerBase>,
+                    public CopyReducerBase {
+public:
+  CopyReducer(MemRegionRef A) : CopyReducerBase(A) {}
+
+public:
+  R_SExpr reduceNull() {
+    return nullptr;
+  }
+  // R_SExpr reduceFuture(...)  is never used.
+
+  R_SExpr reduceUndefined(Undefined &Orig) {
+    return new (Arena) Undefined(Orig);
+  }
+  R_SExpr reduceWildcard(Wildcard &Orig) {
+    return new (Arena) Wildcard(Orig);
+  }
+
+  R_SExpr reduceLiteral(Literal &Orig) {
+    return new (Arena) Literal(Orig);
+  }
+  template<class T>
+  R_SExpr reduceLiteralT(LiteralT<T> &Orig) {
+    return new (Arena) LiteralT<T>(Orig);
+  }
+  R_SExpr reduceLiteralPtr(LiteralPtr &Orig) {
+    return new (Arena) LiteralPtr(Orig);
+  }
+
+  R_SExpr reduceFunction(Function &Orig, Variable *Nvd, R_SExpr E0) {
+    return new (Arena) Function(Orig, Nvd, E0);
+  }
+  R_SExpr reduceSFunction(SFunction &Orig, Variable *Nvd, R_SExpr E0) {
+    return new (Arena) SFunction(Orig, Nvd, E0);
+  }
+  R_SExpr reduceCode(Code &Orig, R_SExpr E0, R_SExpr E1) {
+    return new (Arena) Code(Orig, E0, E1);
+  }
+  R_SExpr reduceField(Field &Orig, R_SExpr E0, R_SExpr E1) {
+    return new (Arena) Field(Orig, E0, E1);
+  }
+
+  R_SExpr reduceApply(Apply &Orig, R_SExpr E0, R_SExpr E1) {
+    return new (Arena) Apply(Orig, E0, E1);
+  }
+  R_SExpr reduceSApply(SApply &Orig, R_SExpr E0, R_SExpr E1) {
+    return new (Arena) SApply(Orig, E0, E1);
+  }
+  R_SExpr reduceProject(Project &Orig, R_SExpr E0) {
+    return new (Arena) Project(Orig, E0);
+  }
+  R_SExpr reduceCall(Call &Orig, R_SExpr E0) {
+    return new (Arena) Call(Orig, E0);
+  }
+
+  R_SExpr reduceAlloc(Alloc &Orig, R_SExpr E0) {
+    return new (Arena) Alloc(Orig, E0);
+  }
+  R_SExpr reduceLoad(Load &Orig, R_SExpr E0) {
+    return new (Arena) Load(Orig, E0);
+  }
+  R_SExpr reduceStore(Store &Orig, R_SExpr E0, R_SExpr E1) {
+    return new (Arena) Store(Orig, E0, E1);
+  }
+  R_SExpr reduceArrayIndex(ArrayIndex &Orig, R_SExpr E0, R_SExpr E1) {
+    return new (Arena) ArrayIndex(Orig, E0, E1);
+  }
+  R_SExpr reduceArrayAdd(ArrayAdd &Orig, R_SExpr E0, R_SExpr E1) {
+    return new (Arena) ArrayAdd(Orig, E0, E1);
+  }
+  R_SExpr reduceUnaryOp(UnaryOp &Orig, R_SExpr E0) {
+    return new (Arena) UnaryOp(Orig, E0);
+  }
+  R_SExpr reduceBinaryOp(BinaryOp &Orig, R_SExpr E0, R_SExpr E1) {
+    return new (Arena) BinaryOp(Orig, E0, E1);
+  }
+  R_SExpr reduceCast(Cast &Orig, R_SExpr E0) {
+    return new (Arena) Cast(Orig, E0);
+  }
+
+  R_SExpr reduceSCFG(SCFG &Orig, Container<BasicBlock *> &Bbs) {
+    return nullptr;  // FIXME: implement CFG rewriting
+  }
+  R_BasicBlock reduceBasicBlock(BasicBlock &Orig, Container<Variable *> &As,
+                                Container<Variable *> &Is, R_SExpr T) {
+    return nullptr;  // FIXME: implement CFG rewriting
+  }
+  R_SExpr reducePhi(Phi &Orig, Container<R_SExpr> &As) {
+    return new (Arena) Phi(Orig, std::move(As.Elems));
+  }
+  R_SExpr reduceGoto(Goto &Orig, BasicBlock *B) {
+    return new (Arena) Goto(Orig, B, 0);  // FIXME: set index
+  }
+  R_SExpr reduceBranch(Branch &O, R_SExpr C, BasicBlock *B0, BasicBlock *B1) {
+    return new (Arena) Branch(O, C, B0, B1, 0, 0);  // FIXME: set indices
+  }
+
+  R_SExpr reduceIdentifier(Identifier &Orig) {
+    return new (Arena) Identifier(Orig);
+  }
+  R_SExpr reduceIfThenElse(IfThenElse &Orig, R_SExpr C, R_SExpr T, R_SExpr E) {
+    return new (Arena) IfThenElse(Orig, C, T, E);
+  }
+  R_SExpr reduceLet(Let &Orig, Variable *Nvd, R_SExpr B) {
+    return new (Arena) Let(Orig, Nvd, B);
+  }
+
+  // Create a new variable from orig, and push it onto the lexical scope.
+  Variable *enterScope(Variable &Orig, R_SExpr E0) {
+    return new (Arena) Variable(Orig, E0);
+  }
+  // Exit the lexical scope of orig.
+  void exitScope(const Variable &Orig) {}
+
+  void enterCFG(SCFG &Cfg) {}
+  void exitCFG(SCFG &Cfg) {}
+  void enterBasicBlock(BasicBlock &BB) {}
+  void exitBasicBlock(BasicBlock &BB) {}
+
+  // Map Variable references to their rewritten definitions.
+  Variable *reduceVariableRef(Variable *Ovd) { return Ovd; }
+
+  // Map BasicBlock references to their rewritten definitions.
+  BasicBlock *reduceBasicBlockRef(BasicBlock *Obb) { return Obb; }
+};
+
+
+class SExprCopier : public CopyReducer<SExprCopier> {
+public:
+  typedef SExpr *R_SExpr;
+
+  SExprCopier(MemRegionRef A) : CopyReducer(A) { }
+
+  // Create a copy of e in region a.
+  static SExpr *copy(SExpr *E, MemRegionRef A) {
+    SExprCopier Copier(A);
+    return Copier.traverse(E, TRV_Normal);
+  }
+};
+
+
+
+// Base class for visit traversals.
+class VisitReducerBase : public SimpleReducerBase {
+public:
+  // A visitor returns a bool, representing success or failure.
+  typedef bool R_SExpr;
+  typedef bool R_BasicBlock;
+
+  // A visitor "container" is a single bool, which accumulates success.
+  template <class T> class Container {
+  public:
+    Container(VisitReducerBase &S, unsigned N) : Success(true) {}
+    void push_back(bool E) { Success = Success && E; }
+
+    bool Success;
+  };
+};
+
+
+// Implements a traversal that visits each subexpression, and returns either
+// true or false.
+template <class Self>
+class VisitReducer : public Traversal<Self, VisitReducerBase>,
+                     public VisitReducerBase {
+public:
+  VisitReducer() {}
+
+public:
+  R_SExpr reduceNull() { return true; }
+  R_SExpr reduceUndefined(Undefined &Orig) { return true; }
+  R_SExpr reduceWildcard(Wildcard &Orig) { return true; }
+
+  R_SExpr reduceLiteral(Literal &Orig) { return true; }
+  template<class T>
+  R_SExpr reduceLiteralT(LiteralT<T> &Orig) { return true; }
+  R_SExpr reduceLiteralPtr(Literal &Orig) { return true; }
+
+  R_SExpr reduceFunction(Function &Orig, Variable *Nvd, R_SExpr E0) {
+    return Nvd && E0;
+  }
+  R_SExpr reduceSFunction(SFunction &Orig, Variable *Nvd, R_SExpr E0) {
+    return Nvd && E0;
+  }
+  R_SExpr reduceCode(Code &Orig, R_SExpr E0, R_SExpr E1) {
+    return E0 && E1;
+  }
+  R_SExpr reduceField(Field &Orig, R_SExpr E0, R_SExpr E1) {
+    return E0 && E1;
+  }
+  R_SExpr reduceApply(Apply &Orig, R_SExpr E0, R_SExpr E1) {
+    return E0 && E1;
+  }
+  R_SExpr reduceSApply(SApply &Orig, R_SExpr E0, R_SExpr E1) {
+    return E0 && E1;
+  }
+  R_SExpr reduceProject(Project &Orig, R_SExpr E0) { return E0; }
+  R_SExpr reduceCall(Call &Orig, R_SExpr E0) { return E0; }
+  R_SExpr reduceAlloc(Alloc &Orig, R_SExpr E0) { return E0; }
+  R_SExpr reduceLoad(Load &Orig, R_SExpr E0) { return E0; }
+  R_SExpr reduceStore(Store &Orig, R_SExpr E0, R_SExpr E1) { return E0 && E1; }
+  R_SExpr reduceArrayIndex(Store &Orig, R_SExpr E0, R_SExpr E1) {
+    return E0 && E1;
+  }
+  R_SExpr reduceArrayAdd(Store &Orig, R_SExpr E0, R_SExpr E1) {
+    return E0 && E1;
+  }
+  R_SExpr reduceUnaryOp(UnaryOp &Orig, R_SExpr E0) { return E0; }
+  R_SExpr reduceBinaryOp(BinaryOp &Orig, R_SExpr E0, R_SExpr E1) {
+    return E0 && E1;
+  }
+  R_SExpr reduceCast(Cast &Orig, R_SExpr E0) { return E0; }
+
+  R_SExpr reduceSCFG(SCFG &Orig, Container<BasicBlock *> Bbs) {
+    return Bbs.Success;
+  }
+  R_BasicBlock reduceBasicBlock(BasicBlock &Orig, Container<Variable *> &As,
+                                Container<Variable *> &Is, R_SExpr T) {
+    return (As.Success && Is.Success && T);
+  }
+  R_SExpr reducePhi(Phi &Orig, Container<R_SExpr> &As) {
+    return As.Success;
+  }
+  R_SExpr reduceGoto(Goto &Orig, BasicBlock *B) {
+    return true;
+  }
+  R_SExpr reduceBranch(Branch &O, R_SExpr C, BasicBlock *B0, BasicBlock *B1) {
+    return C;
+  }
+
+  R_SExpr reduceIdentifier(Identifier &Orig) {
+    return true;
+  }
+  R_SExpr reduceIfThenElse(IfThenElse &Orig, R_SExpr C, R_SExpr T, R_SExpr E) {
+    return C && T && E;
+  }
+  R_SExpr reduceLet(Let &Orig, Variable *Nvd, R_SExpr B) {
+    return Nvd && B;
+  }
+
+  Variable *enterScope(Variable &Orig, R_SExpr E0) { return &Orig; }
+  void exitScope(const Variable &Orig) {}
+  void enterCFG(SCFG &Cfg) {}
+  void exitCFG(SCFG &Cfg) {}
+  void enterBasicBlock(BasicBlock &BB) {}
+  void exitBasicBlock(BasicBlock &BB) {}
+
+  Variable   *reduceVariableRef  (Variable *Ovd)   { return Ovd; }
+  BasicBlock *reduceBasicBlockRef(BasicBlock *Obb) { return Obb; }
+
+public:
+  bool traverse(SExpr *E, TraversalKind K = TRV_Normal) {
+    Success = Success && this->traverseByCase(E);
+    return Success;
+  }
+
+  static bool visit(SExpr *E) {
+    Self Visitor;
+    return Visitor.traverse(E, TRV_Normal);
+  }
+
+private:
+  bool Success;
+};
+
+
+// Basic class for comparison operations over expressions.
+template <typename Self>
+class Comparator {
+protected:
+  Self *self() { return reinterpret_cast<Self *>(this); }
+
+public:
+  bool compareByCase(SExpr *E1, SExpr* E2) {
+    switch (E1->opcode()) {
+#define TIL_OPCODE_DEF(X)                                                     \
+    case COP_##X:                                                             \
+      return cast<X>(E1)->compare(cast<X>(E2), *self());
+#include "ThreadSafetyOps.def"
+#undef TIL_OPCODE_DEF
+    }
+  }
+};
+
+
+class EqualsComparator : public Comparator<EqualsComparator> {
+public:
+  // Result type for the comparison, e.g. bool for simple equality,
+  // or int for lexigraphic comparison (-1, 0, 1).  Must have one value which
+  // denotes "true".
+  typedef bool CType;
+
+  CType trueResult() { return true; }
+  bool notTrue(CType ct) { return !ct; }
+
+  bool compareIntegers(unsigned i, unsigned j)       { return i == j; }
+  bool compareStrings (StringRef s, StringRef r)     { return s == r; }
+  bool comparePointers(const void* P, const void* Q) { return P == Q; }
+
+  bool compare(SExpr *E1, SExpr* E2) {
+    if (E1->opcode() != E2->opcode())
+      return false;
+    return compareByCase(E1, E2);
+  }
+
+  // TODO -- handle alpha-renaming of variables
+  void enterScope(Variable* V1, Variable* V2) { }
+  void leaveScope() { }
+
+  bool compareVariableRefs(Variable* V1, Variable* V2) {
+    return V1 == V2;
+  }
+
+  static bool compareExprs(SExpr *E1, SExpr* E2) {
+    EqualsComparator Eq;
+    return Eq.compare(E1, E2);
+  }
+};
+
+
+// Pretty printer for TIL expressions
+template <typename Self, typename StreamType>
+class PrettyPrinter {
+private:
+  bool Verbose;  // Print out additional information
+  bool Cleanup;  // Omit redundant decls.
+
+public:
+  PrettyPrinter(bool V = false, bool C = true) : Verbose(V), Cleanup(C) { }
+
+  static void print(SExpr *E, StreamType &SS) {
+    Self printer;
+    printer.printSExpr(E, SS, Prec_MAX);
+  }
+
+protected:
+  Self *self() { return reinterpret_cast<Self *>(this); }
+
+  void newline(StreamType &SS) {
+    SS << "\n";
+  }
+
+  // TODO: further distinguish between binary operations.
+  static const unsigned Prec_Atom = 0;
+  static const unsigned Prec_Postfix = 1;
+  static const unsigned Prec_Unary = 2;
+  static const unsigned Prec_Binary = 3;
+  static const unsigned Prec_Other = 4;
+  static const unsigned Prec_Decl = 5;
+  static const unsigned Prec_MAX = 6;
+
+  // Return the precedence of a given node, for use in pretty printing.
+  unsigned precedence(SExpr *E) {
+    switch (E->opcode()) {
+      case COP_Future:     return Prec_Atom;
+      case COP_Undefined:  return Prec_Atom;
+      case COP_Wildcard:   return Prec_Atom;
+
+      case COP_Literal:    return Prec_Atom;
+      case COP_LiteralPtr: return Prec_Atom;
+      case COP_Variable:   return Prec_Atom;
+      case COP_Function:   return Prec_Decl;
+      case COP_SFunction:  return Prec_Decl;
+      case COP_Code:       return Prec_Decl;
+      case COP_Field:      return Prec_Decl;
+
+      case COP_Apply:      return Prec_Postfix;
+      case COP_SApply:     return Prec_Postfix;
+      case COP_Project:    return Prec_Postfix;
+
+      case COP_Call:       return Prec_Postfix;
+      case COP_Alloc:      return Prec_Other;
+      case COP_Load:       return Prec_Postfix;
+      case COP_Store:      return Prec_Other;
+      case COP_ArrayIndex: return Prec_Postfix;
+      case COP_ArrayAdd:   return Prec_Postfix;
+
+      case COP_UnaryOp:    return Prec_Unary;
+      case COP_BinaryOp:   return Prec_Binary;
+      case COP_Cast:       return Prec_Unary;
+
+      case COP_SCFG:       return Prec_Decl;
+      case COP_BasicBlock: return Prec_MAX;
+      case COP_Phi:        return Prec_Atom;
+      case COP_Goto:       return Prec_Atom;
+      case COP_Branch:     return Prec_Atom;
+
+      case COP_Identifier: return Prec_Atom;
+      case COP_IfThenElse: return Prec_Other;
+      case COP_Let:        return Prec_Decl;
+    }
+    return Prec_MAX;
+  }
+
+  void printBlockLabel(StreamType & SS, BasicBlock *BB, unsigned index) {
+    if (!BB) {
+      SS << "BB_null";
+      return;
+    }
+    SS << "BB_";
+    SS << BB->blockID();
+    SS << ":";
+    SS << index;
+  }
+
+  void printSExpr(SExpr *E, StreamType &SS, unsigned P) {
+    if (!E) {
+      self()->printNull(SS);
+      return;
+    }
+    if (self()->precedence(E) > P) {
+      // Wrap expr in () if necessary.
+      SS << "(";
+      self()->printSExpr(E, SS, Prec_MAX);
+      SS << ")";
+      return;
+    }
+
+    switch (E->opcode()) {
+#define TIL_OPCODE_DEF(X)                                                  \
+    case COP_##X:                                                          \
+      self()->print##X(cast<X>(E), SS);                                    \
+      return;
+#include "ThreadSafetyOps.def"
+#undef TIL_OPCODE_DEF
+    }
+  }
+
+  void printNull(StreamType &SS) {
+    SS << "#null";
+  }
+
+  void printFuture(Future *E, StreamType &SS) {
+    self()->printSExpr(E->maybeGetResult(), SS, Prec_Atom);
+  }
+
+  void printUndefined(Undefined *E, StreamType &SS) {
+    SS << "#undefined";
+  }
+
+  void printWildcard(Wildcard *E, StreamType &SS) {
+    SS << "_";
+  }
+
+  template<class T>
+  void printLiteralT(LiteralT<T> *E, StreamType &SS) {
+    SS << E->value();
+  }
+
+  void printLiteralT(LiteralT<uint8_t> *E, StreamType &SS) {
+    SS << "'" << E->value() << "'";
+  }
+
+  void printLiteral(Literal *E, StreamType &SS) {
+    if (E->clangExpr()) {
+      SS << getSourceLiteralString(E->clangExpr());
+      return;
+    }
+    else {
+      ValueType VT = E->valueType();
+      switch (VT.Base) {
+      case ValueType::BT_Void: {
+        SS << "void";
+        return;
+      }
+      case ValueType::BT_Bool: {
+        if (E->as<bool>().value())
+          SS << "true";
+        else
+          SS << "false";
+        return;
+      }
+      case ValueType::BT_Int: {
+        switch (VT.Size) {
+        case ValueType::ST_8:
+          if (VT.Signed)
+            printLiteralT(&E->as<int8_t>(), SS);
+          else
+            printLiteralT(&E->as<uint8_t>(), SS);
+          return;
+        case ValueType::ST_16:
+          if (VT.Signed)
+            printLiteralT(&E->as<int16_t>(), SS);
+          else
+            printLiteralT(&E->as<uint16_t>(), SS);
+          return;
+        case ValueType::ST_32:
+          if (VT.Signed)
+            printLiteralT(&E->as<int32_t>(), SS);
+          else
+            printLiteralT(&E->as<uint32_t>(), SS);
+          return;
+        case ValueType::ST_64:
+          if (VT.Signed)
+            printLiteralT(&E->as<int64_t>(), SS);
+          else
+            printLiteralT(&E->as<uint64_t>(), SS);
+          return;
+        default:
+          break;
+        }
+        break;
+      }
+      case ValueType::BT_Float: {
+        switch (VT.Size) {
+        case ValueType::ST_32:
+          printLiteralT(&E->as<float>(), SS);
+          return;
+        case ValueType::ST_64:
+          printLiteralT(&E->as<double>(), SS);
+          return;
+        default:
+          break;
+        }
+        break;
+      }
+      case ValueType::BT_String: {
+        SS << "\"";
+        printLiteralT(&E->as<StringRef>(), SS);
+        SS << "\"";
+        return;
+      }
+      case ValueType::BT_Pointer: {
+        SS << "#ptr";
+        return;
+      }
+      case ValueType::BT_ValueRef: {
+        SS << "#vref";
+        return;
+      }
+      }
+    }
+    SS << "#lit";
+  }
+
+  void printLiteralPtr(LiteralPtr *E, StreamType &SS) {
+    SS << E->clangDecl()->getNameAsString();
+  }
+
+  void printVariable(Variable *V, StreamType &SS, bool IsVarDecl = false) {
+    if (!IsVarDecl && Cleanup) {
+      SExpr* E = getCanonicalVal(V);
+      if (E != V) {
+        printSExpr(E, SS, Prec_Atom);
+        return;
+      }
+    }
+    if (V->kind() == Variable::VK_LetBB)
+      SS << V->name() << V->getBlockID() << "_" << V->getID();
+    else
+      SS << V->name() << V->getID();
+  }
+
+  void printFunction(Function *E, StreamType &SS, unsigned sugared = 0) {
+    switch (sugared) {
+      default:
+        SS << "\\(";   // Lambda
+        break;
+      case 1:
+        SS << "(";     // Slot declarations
+        break;
+      case 2:
+        SS << ", ";    // Curried functions
+        break;
+    }
+    self()->printVariable(E->variableDecl(), SS, true);
+    SS << ": ";
+    self()->printSExpr(E->variableDecl()->definition(), SS, Prec_MAX);
+
+    SExpr *B = E->body();
+    if (B && B->opcode() == COP_Function)
+      self()->printFunction(cast<Function>(B), SS, 2);
+    else {
+      SS << ")";
+      self()->printSExpr(B, SS, Prec_Decl);
+    }
+  }
+
+  void printSFunction(SFunction *E, StreamType &SS) {
+    SS << "@";
+    self()->printVariable(E->variableDecl(), SS, true);
+    SS << " ";
+    self()->printSExpr(E->body(), SS, Prec_Decl);
+  }
+
+  void printCode(Code *E, StreamType &SS) {
+    SS << ": ";
+    self()->printSExpr(E->returnType(), SS, Prec_Decl-1);
+    SS << " -> ";
+    self()->printSExpr(E->body(), SS, Prec_Decl);
+  }
+
+  void printField(Field *E, StreamType &SS) {
+    SS << ": ";
+    self()->printSExpr(E->range(), SS, Prec_Decl-1);
+    SS << " = ";
+    self()->printSExpr(E->body(), SS, Prec_Decl);
+  }
+
+  void printApply(Apply *E, StreamType &SS, bool sugared = false) {
+    SExpr *F = E->fun();
+    if (F->opcode() == COP_Apply) {
+      printApply(cast<Apply>(F), SS, true);
+      SS << ", ";
+    } else {
+      self()->printSExpr(F, SS, Prec_Postfix);
+      SS << "(";
+    }
+    self()->printSExpr(E->arg(), SS, Prec_MAX);
+    if (!sugared)
+      SS << ")$";
+  }
+
+  void printSApply(SApply *E, StreamType &SS) {
+    self()->printSExpr(E->sfun(), SS, Prec_Postfix);
+    if (E->isDelegation()) {
+      SS << "@(";
+      self()->printSExpr(E->arg(), SS, Prec_MAX);
+      SS << ")";
+    }
+  }
+
+  void printProject(Project *E, StreamType &SS) {
+    self()->printSExpr(E->record(), SS, Prec_Postfix);
+    SS << ".";
+    SS << E->slotName();
+  }
+
+  void printCall(Call *E, StreamType &SS) {
+    SExpr *T = E->target();
+    if (T->opcode() == COP_Apply) {
+      self()->printApply(cast<Apply>(T), SS, true);
+      SS << ")";
+    }
+    else {
+      self()->printSExpr(T, SS, Prec_Postfix);
+      SS << "()";
+    }
+  }
+
+  void printAlloc(Alloc *E, StreamType &SS) {
+    SS << "new ";
+    self()->printSExpr(E->dataType(), SS, Prec_Other-1);
+  }
+
+  void printLoad(Load *E, StreamType &SS) {
+    self()->printSExpr(E->pointer(), SS, Prec_Postfix);
+    SS << "^";
+  }
+
+  void printStore(Store *E, StreamType &SS) {
+    self()->printSExpr(E->destination(), SS, Prec_Other-1);
+    SS << " := ";
+    self()->printSExpr(E->source(), SS, Prec_Other-1);
+  }
+
+  void printArrayIndex(ArrayIndex *E, StreamType &SS) {
+    self()->printSExpr(E->array(), SS, Prec_Postfix);
+    SS << "[";
+    self()->printSExpr(E->index(), SS, Prec_MAX);
+    SS << "]";
+  }
+
+  void printArrayAdd(ArrayAdd *E, StreamType &SS) {
+    self()->printSExpr(E->array(), SS, Prec_Postfix);
+    SS << " + ";
+    self()->printSExpr(E->index(), SS, Prec_Atom);
+  }
+
+  void printUnaryOp(UnaryOp *E, StreamType &SS) {
+    SS << getUnaryOpcodeString(E->unaryOpcode());
+    self()->printSExpr(E->expr(), SS, Prec_Unary);
+  }
+
+  void printBinaryOp(BinaryOp *E, StreamType &SS) {
+    self()->printSExpr(E->expr0(), SS, Prec_Binary-1);
+    SS << " " << getBinaryOpcodeString(E->binaryOpcode()) << " ";
+    self()->printSExpr(E->expr1(), SS, Prec_Binary-1);
+  }
+
+  void printCast(Cast *E, StreamType &SS) {
+    SS << "%";
+    self()->printSExpr(E->expr(), SS, Prec_Unary);
+  }
+
+  void printSCFG(SCFG *E, StreamType &SS) {
+    SS << "CFG {\n";
+    for (auto BBI : *E) {
+      printBasicBlock(BBI, SS);
+    }
+    SS << "}";
+    newline(SS);
+  }
+
+  void printBasicBlock(BasicBlock *E, StreamType &SS) {
+    SS << "BB_" << E->blockID() << ":";
+    if (E->parent())
+      SS << " BB_" << E->parent()->blockID();
+    newline(SS);
+    for (auto *A : E->arguments()) {
+      SS << "let ";
+      self()->printVariable(A, SS, true);
+      SS << " = ";
+      self()->printSExpr(A->definition(), SS, Prec_MAX);
+      SS << ";";
+      newline(SS);
+    }
+    for (auto *I : E->instructions()) {
+      if (I->definition()->opcode() != COP_Store) {
+        SS << "let ";
+        self()->printVariable(I, SS, true);
+        SS << " = ";
+      }
+      self()->printSExpr(I->definition(), SS, Prec_MAX);
+      SS << ";";
+      newline(SS);
+    }
+    SExpr *T = E->terminator();
+    if (T) {
+      self()->printSExpr(T, SS, Prec_MAX);
+      SS << ";";
+      newline(SS);
+    }
+    newline(SS);
+  }
+
+  void printPhi(Phi *E, StreamType &SS) {
+    SS << "phi(";
+    if (E->status() == Phi::PH_SingleVal)
+      self()->printSExpr(E->values()[0], SS, Prec_MAX);
+    else {
+      unsigned i = 0;
+      for (auto V : E->values()) {
+        if (i++ > 0)
+          SS << ", ";
+        self()->printSExpr(V, SS, Prec_MAX);
+      }
+    }
+    SS << ")";
+  }
+
+  void printGoto(Goto *E, StreamType &SS) {
+    SS << "goto ";
+    printBlockLabel(SS, E->targetBlock(), E->index());
+  }
+
+  void printBranch(Branch *E, StreamType &SS) {
+    SS << "branch (";
+    self()->printSExpr(E->condition(), SS, Prec_MAX);
+    SS << ") ";
+    printBlockLabel(SS, E->thenBlock(), E->thenIndex());
+    SS << " ";
+    printBlockLabel(SS, E->elseBlock(), E->elseIndex());
+  }
+
+  void printIdentifier(Identifier *E, StreamType &SS) {
+    SS << E->name();
+  }
+
+  void printIfThenElse(IfThenElse *E, StreamType &SS) {
+    SS << "if (";
+    printSExpr(E->condition(), SS, Prec_MAX);
+    SS << ") then ";
+    printSExpr(E->thenExpr(), SS, Prec_Other);
+    SS << " else ";
+    printSExpr(E->elseExpr(), SS, Prec_Other);
+  }
+
+  void printLet(Let *E, StreamType &SS) {
+    SS << "let ";
+    printVariable(E->variableDecl(), SS, true);
+    SS << " = ";
+    printSExpr(E->variableDecl()->definition(), SS, Prec_Decl-1);
+    SS << "; ";
+    printSExpr(E->body(), SS, Prec_Decl-1);
+  }
+};
+
+
+} // end namespace til
+} // end namespace threadSafety
+} // end namespace clang
+
+#endif  // LLVM_CLANG_THREAD_SAFETY_TRAVERSE_H
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyUtil.h b/include/clang/Analysis/Analyses/ThreadSafetyUtil.h
new file mode 100644
index 0000000..31200a3
--- /dev/null
+++ b/include/clang/Analysis/Analyses/ThreadSafetyUtil.h
@@ -0,0 +1,316 @@
+//===- ThreadSafetyUtil.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 some basic utility classes for use by ThreadSafetyTIL.h
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_THREAD_SAFETY_UTIL_H
+#define LLVM_CLANG_THREAD_SAFETY_UTIL_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/AlignOf.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Compiler.h"
+#include "clang/AST/ExprCXX.h"
+
+#include <cassert>
+#include <cstddef>
+#include <vector>
+#include <utility>
+
+namespace clang {
+namespace threadSafety {
+namespace til {
+
+// Simple wrapper class to abstract away from the details of memory management.
+// SExprs are allocated in pools, and deallocated all at once.
+class MemRegionRef {
+private:
+  union AlignmentType {
+    double d;
+    void *p;
+    long double dd;
+    long long ii;
+  };
+
+public:
+  MemRegionRef() : Allocator(nullptr) {}
+  MemRegionRef(llvm::BumpPtrAllocator *A) : Allocator(A) {}
+
+  void *allocate(size_t Sz) {
+    return Allocator->Allocate(Sz, llvm::AlignOf<AlignmentType>::Alignment);
+  }
+
+  template <typename T> T *allocateT() { return Allocator->Allocate<T>(); }
+
+  template <typename T> T *allocateT(size_t NumElems) {
+    return Allocator->Allocate<T>(NumElems);
+  }
+
+private:
+  llvm::BumpPtrAllocator *Allocator;
+};
+
+
+} // end namespace til
+} // end namespace threadSafety
+} // end namespace clang
+
+
+inline void *operator new(size_t Sz,
+                          clang::threadSafety::til::MemRegionRef &R) {
+  return R.allocate(Sz);
+}
+
+
+namespace clang {
+namespace threadSafety {
+
+std::string getSourceLiteralString(const clang::Expr *CE);
+
+using llvm::StringRef;
+using clang::SourceLocation;
+
+namespace til {
+
+
+// A simple fixed size array class that does not manage its own memory,
+// suitable for use with bump pointer allocation.
+template <class T> class SimpleArray {
+public:
+  SimpleArray() : Data(nullptr), Size(0), Capacity(0) {}
+  SimpleArray(T *Dat, size_t Cp, size_t Sz = 0)
+      : Data(Dat), Size(Sz), Capacity(Cp) {}
+  SimpleArray(MemRegionRef A, size_t Cp)
+      : Data(Cp == 0 ? nullptr : A.allocateT<T>(Cp)), Size(0), Capacity(Cp) {}
+  SimpleArray(SimpleArray<T> &&A)
+      : Data(A.Data), Size(A.Size), Capacity(A.Capacity) {
+    A.Data = nullptr;
+    A.Size = 0;
+    A.Capacity = 0;
+  }
+
+  SimpleArray &operator=(SimpleArray &&RHS) {
+    if (this != &RHS) {
+      Data = RHS.Data;
+      Size = RHS.Size;
+      Capacity = RHS.Capacity;
+
+      RHS.Data = nullptr;
+      RHS.Size = RHS.Capacity = 0;
+    }
+    return *this;
+  }
+
+  // Reserve space for at least Ncp items, reallocating if necessary.
+  void reserve(size_t Ncp, MemRegionRef A) {
+    if (Ncp <= Capacity)
+      return;
+    T *Odata = Data;
+    Data = A.allocateT<T>(Ncp);
+    Capacity = Ncp;
+    memcpy(Data, Odata, sizeof(T) * Size);
+    return;
+  }
+
+  // Reserve space for at least N more items.
+  void reserveCheck(size_t N, MemRegionRef A) {
+    if (Capacity == 0)
+      reserve(u_max(InitialCapacity, N), A);
+    else if (Size + N < Capacity)
+      reserve(u_max(Size + N, Capacity * 2), A);
+  }
+
+  typedef T *iterator;
+  typedef const T *const_iterator;
+
+  size_t size() const { return Size; }
+  size_t capacity() const { return Capacity; }
+
+  T &operator[](unsigned i) {
+    assert(i < Size && "Array index out of bounds.");
+    return Data[i];
+  }
+  const T &operator[](unsigned i) const {
+    assert(i < Size && "Array index out of bounds.");
+    return Data[i];
+  }
+
+  iterator begin() { return Data; }
+  iterator end() { return Data + Size; }
+
+  const_iterator cbegin() const { return Data; }
+  const_iterator cend() const { return Data + Size; }
+
+  void push_back(const T &Elem) {
+    assert(Size < Capacity);
+    Data[Size++] = Elem;
+  }
+
+  void setValues(unsigned Sz, const T& C) {
+    assert(Sz <= Capacity);
+    Size = Sz;
+    for (unsigned i = 0; i < Sz; ++i) {
+      Data[i] = C;
+    }
+  }
+
+  template <class Iter> unsigned append(Iter I, Iter E) {
+    size_t Osz = Size;
+    size_t J = Osz;
+    for (; J < Capacity && I != E; ++J, ++I)
+      Data[J] = *I;
+    Size = J;
+    return J - Osz;
+  }
+
+private:
+  // std::max is annoying here, because it requires a reference,
+  // thus forcing InitialCapacity to be initialized outside the .h file.
+  size_t u_max(size_t i, size_t j) { return (i < j) ? j : i; }
+
+  static const size_t InitialCapacity = 4;
+
+  SimpleArray(const SimpleArray<T> &A) LLVM_DELETED_FUNCTION;
+
+  T *Data;
+  size_t Size;
+  size_t Capacity;
+};
+
+}  // end namespace til
+
+
+// A copy on write vector.
+// The vector can be in one of three states:
+// * invalid -- no operations are permitted.
+// * read-only -- read operations are permitted.
+// * writable -- read and write operations are permitted.
+// The init(), destroy(), and makeWritable() methods will change state.
+template<typename T>
+class CopyOnWriteVector {
+  class VectorData {
+  public:
+    VectorData() : NumRefs(1) { }
+    VectorData(const VectorData &VD) : NumRefs(1), Vect(VD.Vect) { }
+
+    unsigned NumRefs;
+    std::vector<T> Vect;
+  };
+
+  // No copy constructor or copy assignment.  Use clone() with move assignment.
+  CopyOnWriteVector(const CopyOnWriteVector &V) LLVM_DELETED_FUNCTION;
+  void operator=(const CopyOnWriteVector &V) LLVM_DELETED_FUNCTION;
+
+public:
+  CopyOnWriteVector() : Data(nullptr) {}
+  CopyOnWriteVector(CopyOnWriteVector &&V) : Data(V.Data) { V.Data = nullptr; }
+  ~CopyOnWriteVector() { destroy(); }
+
+  // Returns true if this holds a valid vector.
+  bool valid() const  { return Data; }
+
+  // Returns true if this vector is writable.
+  bool writable() const { return Data && Data->NumRefs == 1; }
+
+  // If this vector is not valid, initialize it to a valid vector.
+  void init() {
+    if (!Data) {
+      Data = new VectorData();
+    }
+  }
+
+  // Destroy this vector; thus making it invalid.
+  void destroy() {
+    if (!Data)
+      return;
+    if (Data->NumRefs <= 1)
+      delete Data;
+    else
+      --Data->NumRefs;
+    Data = nullptr;
+  }
+
+  // Make this vector writable, creating a copy if needed.
+  void makeWritable() {
+    if (!Data) {
+      Data = new VectorData();
+      return;
+    }
+    if (Data->NumRefs == 1)
+      return;   // already writeable.
+    --Data->NumRefs;
+    Data = new VectorData(*Data);
+  }
+
+  // Create a lazy copy of this vector.
+  CopyOnWriteVector clone() { return CopyOnWriteVector(Data); }
+
+  CopyOnWriteVector &operator=(CopyOnWriteVector &&V) {
+    destroy();
+    Data = V.Data;
+    V.Data = nullptr;
+    return *this;
+  }
+
+  typedef typename std::vector<T>::const_iterator const_iterator;
+
+  const std::vector<T> &elements() const { return Data->Vect; }
+
+  const_iterator begin() const { return elements().cbegin(); }
+  const_iterator end() const { return elements().cend(); }
+
+  const T& operator[](unsigned i) const { return elements()[i]; }
+
+  unsigned size() const { return Data ? elements().size() : 0; }
+
+  // Return true if V and this vector refer to the same data.
+  bool sameAs(const CopyOnWriteVector &V) const { return Data == V.Data; }
+
+  // Clear vector.  The vector must be writable.
+  void clear() {
+    assert(writable() && "Vector is not writable!");
+    Data->Vect.clear();
+  }
+
+  // Push a new element onto the end.  The vector must be writable.
+  void push_back(const T &Elem) {
+    assert(writable() && "Vector is not writable!");
+    Data->Vect.push_back(Elem);
+  }
+
+  // Gets a mutable reference to the element at index(i).
+  // The vector must be writable.
+  T& elem(unsigned i) {
+    assert(writable() && "Vector is not writable!");
+    return Data->Vect[i];
+  }
+
+  // Drops elements from the back until the vector has size i.
+  void downsize(unsigned i) {
+    assert(writable() && "Vector is not writable!");
+    Data->Vect.erase(Data->Vect.begin() + i, Data->Vect.end());
+  }
+
+private:
+  CopyOnWriteVector(VectorData *D) : Data(D) {
+    if (!Data)
+      return;
+    ++Data->NumRefs;
+  }
+
+  VectorData *Data;
+};
+
+
+} // end namespace threadSafety
+} // end namespace clang
+
+#endif  // LLVM_CLANG_THREAD_SAFETY_UTIL_H
diff --git a/include/clang/Analysis/AnalysisContext.h b/include/clang/Analysis/AnalysisContext.h
index b6f183d..08e3354 100644
--- a/include/clang/Analysis/AnalysisContext.h
+++ b/include/clang/Analysis/AnalysisContext.h
@@ -19,8 +19,8 @@
 #include "clang/Analysis/CFG.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/Support/Allocator.h"
+#include <memory>
 
 namespace clang {
 
@@ -69,16 +69,16 @@
 
   const Decl * const D;
 
-  OwningPtr<CFG> cfg, completeCFG;
-  OwningPtr<CFGStmtMap> cfgStmtMap;
+  std::unique_ptr<CFG> cfg, completeCFG;
+  std::unique_ptr<CFGStmtMap> cfgStmtMap;
 
   CFG::BuildOptions cfgBuildOptions;
   CFG::BuildOptions::ForcedBlkExprs *forcedBlkExprs;
 
   bool builtCFG, builtCompleteCFG;
-  OwningPtr<ParentMap> PM;
-  OwningPtr<PseudoConstantAnalysis> PCA;
-  OwningPtr<CFGReverseBlockReachabilityAnalysis> CFA;
+  std::unique_ptr<ParentMap> PM;
+  std::unique_ptr<PseudoConstantAnalysis> PCA;
+  std::unique_ptr<CFGReverseBlockReachabilityAnalysis> CFA;
 
   llvm::BumpPtrAllocator A;
 
@@ -252,7 +252,7 @@
   virtual void Profile(llvm::FoldingSetNodeID &ID) = 0;
 
   void dumpStack(raw_ostream &OS, StringRef Indent = "") const;
-  LLVM_ATTRIBUTE_USED void dumpStack() const;
+  void dumpStack() const;
 
 public:
   static void ProfileCommon(llvm::FoldingSetNodeID &ID,
@@ -287,11 +287,11 @@
   const CFGBlock *getCallSiteBlock() const { return Block; }
 
   /// Return true if the current LocationContext has no caller context.
-  virtual bool inTopFrame() const { return getParent() == 0;  }
+  bool inTopFrame() const override { return getParent() == nullptr;  }
 
   unsigned getIndex() const { return Index; }
 
-  void Profile(llvm::FoldingSetNodeID &ID);
+  void Profile(llvm::FoldingSetNodeID &ID) override;
 
   static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx,
                       const LocationContext *parent, const Stmt *s,
@@ -317,7 +317,7 @@
 public:
   ~ScopeContext() {}
 
-  void Profile(llvm::FoldingSetNodeID &ID);
+  void Profile(llvm::FoldingSetNodeID &ID) override;
 
   static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx,
                       const LocationContext *parent, const Stmt *s) {
@@ -349,7 +349,7 @@
   
   const void *getContextData() const { return ContextData; }
 
-  void Profile(llvm::FoldingSetNodeID &ID);
+  void Profile(llvm::FoldingSetNodeID &ID) override;
 
   static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx,
                       const LocationContext *parent, const BlockDecl *bd,
@@ -409,7 +409,8 @@
                              bool addInitializers = false,
                              bool addTemporaryDtors = false,
                              bool synthesizeBodies = false,
-                             bool addStaticInitBranches = false);
+                             bool addStaticInitBranches = false,
+                             bool addCXXNewAllocator = true);
 
   ~AnalysisDeclContextManager();
 
@@ -437,7 +438,8 @@
 
   // Get the top level stack frame.
   const StackFrameContext *getStackFrame(const Decl *D) {
-    return LocContexts.getStackFrame(getContext(D), 0, 0, 0, 0);
+    return LocContexts.getStackFrame(getContext(D), nullptr, nullptr, nullptr,
+                                     0);
   }
 
   // Get a stack frame with parent.
diff --git a/include/clang/Analysis/CFG.h b/include/clang/Analysis/CFG.h
index 14b7ab8..891fb90 100644
--- a/include/clang/Analysis/CFG.h
+++ b/include/clang/Analysis/CFG.h
@@ -21,13 +21,14 @@
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/GraphTraits.h"
 #include "llvm/ADT/Optional.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/PointerIntPair.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/Casting.h"
+#include "llvm/Support/raw_ostream.h"
 #include <bitset>
 #include <cassert>
 #include <iterator>
+#include <memory>
 
 namespace clang {
   class CXXDestructorDecl;
@@ -45,6 +46,8 @@
   class ASTContext;
   class CXXRecordDecl;
   class CXXDeleteExpr;
+  class CXXNewExpr;
+  class BinaryOperator;
 
 /// CFGElement - Represents a top-level expression in a basic block.
 class CFGElement {
@@ -53,6 +56,7 @@
     // main kind
     Statement,
     Initializer,
+    NewAllocator,
     // dtor kind
     AutomaticObjectDtor,
     DeleteDtor,
@@ -68,9 +72,11 @@
   llvm::PointerIntPair<void *, 2> Data1;
   llvm::PointerIntPair<void *, 2> Data2;
 
-  CFGElement(Kind kind, const void *Ptr1, const void *Ptr2 = 0)
+  CFGElement(Kind kind, const void *Ptr1, const void *Ptr2 = nullptr)
     : Data1(const_cast<void*>(Ptr1), ((unsigned) kind) & 0x3),
-      Data2(const_cast<void*>(Ptr2), (((unsigned) kind) >> 2) & 0x3) {}
+      Data2(const_cast<void*>(Ptr2), (((unsigned) kind) >> 2) & 0x3) {
+    assert(getKind() == kind);
+  }
 
   CFGElement() {}
 public:
@@ -141,12 +147,31 @@
   }
 };
 
+/// CFGNewAllocator - Represents C++ allocator call.
+class CFGNewAllocator : public CFGElement {
+public:
+  explicit CFGNewAllocator(const CXXNewExpr *S)
+    : CFGElement(NewAllocator, S) {}
+
+  // Get the new expression.
+  const CXXNewExpr *getAllocatorExpr() const {
+    return static_cast<CXXNewExpr *>(Data1.getPointer());
+  }
+
+private:
+  friend class CFGElement;
+  CFGNewAllocator() {}
+  static bool isKind(const CFGElement &elem) {
+    return elem.getKind() == NewAllocator;
+  }
+};
+
 /// CFGImplicitDtor - Represents C++ object destructor implicitly generated
 /// by compiler on various occasions.
 class CFGImplicitDtor : public CFGElement {
 protected:
   CFGImplicitDtor() {}
-  CFGImplicitDtor(Kind kind, const void *data1, const void *data2 = 0)
+  CFGImplicitDtor(Kind kind, const void *data1, const void *data2 = nullptr)
     : CFGElement(kind, data1, data2) {
     assert(kind >= DTOR_BEGIN && kind <= DTOR_END);
   }
@@ -237,7 +262,7 @@
 class CFGMemberDtor : public CFGImplicitDtor {
 public:
   CFGMemberDtor(const FieldDecl *field)
-      : CFGImplicitDtor(MemberDtor, field, 0) {}
+      : CFGImplicitDtor(MemberDtor, field, nullptr) {}
 
   const FieldDecl *getFieldDecl() const {
     return static_cast<const FieldDecl*>(Data1.getPointer());
@@ -256,7 +281,7 @@
 class CFGTemporaryDtor : public CFGImplicitDtor {
 public:
   CFGTemporaryDtor(CXXBindTemporaryExpr *expr)
-      : CFGImplicitDtor(TemporaryDtor, expr, 0) {}
+      : CFGImplicitDtor(TemporaryDtor, expr, nullptr) {}
 
   const CXXBindTemporaryExpr *getBindTemporaryExpr() const {
     return static_cast<const CXXBindTemporaryExpr *>(Data1.getPointer());
@@ -388,9 +413,64 @@
   ///   of the CFG.
   unsigned BlockID;
 
+public:
+  /// This class represents a potential adjacent block in the CFG.  It encodes
+  /// whether or not the block is actually reachable, or can be proved to be
+  /// trivially unreachable.  For some cases it allows one to encode scenarios
+  /// where a block was substituted because the original (now alternate) block
+  /// is unreachable.
+  class AdjacentBlock {
+    enum Kind {
+      AB_Normal,
+      AB_Unreachable,
+      AB_Alternate
+    };
+
+    CFGBlock *ReachableBlock;
+    llvm::PointerIntPair<CFGBlock*, 2> UnreachableBlock;
+
+  public:
+    /// Construct an AdjacentBlock with a possibly unreachable block.
+    AdjacentBlock(CFGBlock *B, bool IsReachable);
+    
+    /// Construct an AdjacentBlock with a reachable block and an alternate
+    /// unreachable block.
+    AdjacentBlock(CFGBlock *B, CFGBlock *AlternateBlock);
+
+    /// Get the reachable block, if one exists.
+    CFGBlock *getReachableBlock() const {
+      return ReachableBlock;
+    }
+
+    /// Get the potentially unreachable block.
+    CFGBlock *getPossiblyUnreachableBlock() const {
+      return UnreachableBlock.getPointer();
+    }
+
+    /// Provide an implicit conversion to CFGBlock* so that
+    /// AdjacentBlock can be substituted for CFGBlock*.
+    operator CFGBlock*() const {
+      return getReachableBlock();
+    }
+
+    CFGBlock& operator *() const {
+      return *getReachableBlock();
+    }
+
+    CFGBlock* operator ->() const {
+      return getReachableBlock();
+    }
+
+    bool isReachable() const {
+      Kind K = (Kind) UnreachableBlock.getInt();
+      return K == AB_Normal || K == AB_Alternate;
+    }
+  };
+
+private:
   /// Predecessors/Successors - Keep track of the predecessor / successor
   /// CFG blocks.
-  typedef BumpVector<CFGBlock*> AdjacentBlocks;
+  typedef BumpVector<AdjacentBlock> AdjacentBlocks;
   AdjacentBlocks Preds;
   AdjacentBlocks Succs;
 
@@ -410,7 +490,7 @@
 
 public:
   explicit CFGBlock(unsigned blockid, BumpVectorContext &C, CFG *parent)
-    : Elements(C), Label(NULL), Terminator(NULL), LoopTarget(NULL), 
+    : Elements(C), Label(nullptr), Terminator(nullptr), LoopTarget(nullptr), 
       BlockID(blockid), Preds(C, 1), Succs(C, 1), HasNoReturnElement(false),
       Parent(parent) {}
   ~CFGBlock() {}
@@ -480,9 +560,11 @@
   class FilterOptions {
   public:
     FilterOptions() {
+      IgnoreNullPredecessors = 1;
       IgnoreDefaultsWithCoveredEnums = 0;
     }
 
+    unsigned IgnoreNullPredecessors : 1;
     unsigned IgnoreDefaultsWithCoveredEnums : 1;
   };
 
@@ -495,11 +577,14 @@
     IMPL I, E;
     const FilterOptions F;
     const CFGBlock *From;
-   public:
+  public:
     explicit FilteredCFGBlockIterator(const IMPL &i, const IMPL &e,
-              const CFGBlock *from,
-              const FilterOptions &f)
-      : I(i), E(e), F(f), From(from) {}
+                                      const CFGBlock *from,
+                                      const FilterOptions &f)
+        : I(i), E(e), F(f), From(from) {
+      while (hasMore() && Filter(*I))
+        ++I;
+    }
 
     bool hasMore() const { return I != E; }
 
@@ -531,7 +616,7 @@
 
   // Manipulation of block contents
 
-  void setTerminator(Stmt *Statement) { Terminator = Statement; }
+  void setTerminator(CFGTerminator Term) { Terminator = Term; }
   void setLabel(Stmt *Statement) { Label = Statement; }
   void setLoopTarget(const Stmt *loopTarget) { LoopTarget = loopTarget; }
   void setHasNoReturnElement() { HasNoReturnElement = true; }
@@ -539,10 +624,10 @@
   CFGTerminator getTerminator() { return Terminator; }
   const CFGTerminator getTerminator() const { return Terminator; }
 
-  Stmt *getTerminatorCondition();
+  Stmt *getTerminatorCondition(bool StripParens = true);
 
-  const Stmt *getTerminatorCondition() const {
-    return const_cast<CFGBlock*>(this)->getTerminatorCondition();
+  const Stmt *getTerminatorCondition(bool StripParens = true) const {
+    return const_cast<CFGBlock*>(this)->getTerminatorCondition(StripParens);
   }
 
   const Stmt *getLoopTarget() const { return LoopTarget; }
@@ -556,17 +641,19 @@
 
   CFG *getParent() const { return Parent; }
 
+  void dump() const;
+
   void dump(const CFG *cfg, const LangOptions &LO, bool ShowColors = false) const;
   void print(raw_ostream &OS, const CFG* cfg, const LangOptions &LO,
              bool ShowColors) const;
   void printTerminator(raw_ostream &OS, const LangOptions &LO) const;
-
-  void addSuccessor(CFGBlock *Block, BumpVectorContext &C) {
-    if (Block)
-      Block->Preds.push_back(this, C);
-    Succs.push_back(Block, C);
+  void printAsOperand(raw_ostream &OS, bool /*PrintType*/) {
+    OS << "BB#" << getBlockID();
   }
 
+  /// Adds a (potentially unreachable) successor block to the current block.
+  void addSuccessor(AdjacentBlock Succ, BumpVectorContext &C);
+
   void appendStmt(Stmt *statement, BumpVectorContext &C) {
     Elements.push_back(CFGStmt(statement), C);
   }
@@ -576,6 +663,11 @@
     Elements.push_back(CFGInitializer(initializer), C);
   }
 
+  void appendNewAllocator(CXXNewExpr *NE,
+                          BumpVectorContext &C) {
+    Elements.push_back(CFGNewAllocator(NE), C);
+  }
+
   void appendBaseDtor(const CXXBaseSpecifier *BS, BumpVectorContext &C) {
     Elements.push_back(CFGBaseDtor(BS), C);
   }
@@ -601,7 +693,8 @@
   // the elements beginning at the last position in prepared space.
   iterator beginAutomaticObjDtorsInsert(iterator I, size_t Cnt,
       BumpVectorContext &C) {
-    return iterator(Elements.insert(I.base(), Cnt, CFGAutomaticObjDtor(0, 0), C));
+    return iterator(Elements.insert(I.base(), Cnt,
+                                    CFGAutomaticObjDtor(nullptr, 0), C));
   }
   iterator insertAutomaticObjDtor(iterator I, VarDecl *VD, Stmt *S) {
     *I = CFGAutomaticObjDtor(VD, S);
@@ -609,6 +702,17 @@
   }
 };
 
+/// \brief CFGCallback defines methods that should be called when a logical
+/// operator error is found when building the CFG.
+class CFGCallback {
+public:
+  CFGCallback() {}
+  virtual void compareAlwaysTrue(const BinaryOperator *B, bool isAlwaysTrue) {}
+  virtual void compareBitwiseEquality(const BinaryOperator *B,
+                                      bool isAlwaysTrue) {}
+  virtual ~CFGCallback() {}
+};
+
 /// CFG - Represents a source-level, intra-procedural CFG that represents the
 ///  control-flow of a Stmt.  The Stmt can represent an entire function body,
 ///  or a single expression.  A CFG will always contain one empty block that
@@ -627,13 +731,14 @@
   public:
     typedef llvm::DenseMap<const Stmt *, const CFGBlock*> ForcedBlkExprs;
     ForcedBlkExprs **forcedBlkExprs;
-
+    CFGCallback *Observer;
     bool PruneTriviallyFalseEdges;
     bool AddEHEdges;
     bool AddInitializers;
     bool AddImplicitDtors;
     bool AddTemporaryDtors;
     bool AddStaticInitBranches;
+    bool AddCXXNewAllocator;
 
     bool alwaysAdd(const Stmt *stmt) const {
       return alwaysAddMask[stmt->getStmtClass()];
@@ -650,12 +755,11 @@
     }
 
     BuildOptions()
-    : forcedBlkExprs(0), PruneTriviallyFalseEdges(true)
-      ,AddEHEdges(false)
-      ,AddInitializers(false)
-      ,AddImplicitDtors(false)
-      ,AddTemporaryDtors(false)
-      ,AddStaticInitBranches(false) {}
+      : forcedBlkExprs(nullptr), Observer(nullptr),
+        PruneTriviallyFalseEdges(true), AddEHEdges(false),
+        AddInitializers(false), AddImplicitDtors(false),
+        AddTemporaryDtors(false), AddStaticInitBranches(false),
+        AddCXXNewAllocator(false) {}
   };
 
   /// \brief Provides a custom implementation of the iterator class to have the
@@ -845,8 +949,9 @@
   // Internal: constructors and data.
   //===--------------------------------------------------------------------===//
 
-  CFG() : Entry(NULL), Exit(NULL), IndirectGotoBlock(NULL), NumBlockIDs(0),
-          Blocks(BlkBVC, 10) {}
+  CFG()
+    : Entry(nullptr), Exit(nullptr), IndirectGotoBlock(nullptr), NumBlockIDs(0),
+      Blocks(BlkBVC, 10) {}
 
   llvm::BumpPtrAllocator& getAllocator() {
     return BlkBVC.getAllocator();
diff --git a/include/clang/Analysis/FlowSensitive/DataflowSolver.h b/include/clang/Analysis/FlowSensitive/DataflowSolver.h
deleted file mode 100644
index c611ea2..0000000
--- a/include/clang/Analysis/FlowSensitive/DataflowSolver.h
+++ /dev/null
@@ -1,342 +0,0 @@
-//===--- DataflowSolver.h - Skeleton Dataflow Analysis Code -----*- 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 skeleton code for implementing dataflow analyses.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSES_DATAFLOW_SOLVER
-#define LLVM_CLANG_ANALYSES_DATAFLOW_SOLVER
-
-#include "functional" // STL
-#include "clang/Analysis/CFG.h"
-#include "clang/Analysis/FlowSensitive/DataflowValues.h"
-#include "clang/Analysis/ProgramPoint.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallVector.h"
-
-namespace clang {
-
-//===----------------------------------------------------------------------===//
-/// DataflowWorkListTy - Data structure representing the worklist used for
-///  dataflow algorithms.
-//===----------------------------------------------------------------------===//
-
-class DataflowWorkListTy {
-  llvm::DenseMap<const CFGBlock*, unsigned char> BlockSet;
-  SmallVector<const CFGBlock *, 10> BlockQueue;
-public:
-  /// enqueue - Add a block to the worklist.  Blocks already on the
-  ///  worklist are not added a second time.
-  void enqueue(const CFGBlock *B) {
-    unsigned char &x = BlockSet[B];
-    if (x == 1)
-      return;
-    x = 1;
-    BlockQueue.push_back(B);
-  }
-
-  /// dequeue - Remove a block from the worklist.
-  const CFGBlock *dequeue() {
-    assert(!BlockQueue.empty());
-    const CFGBlock *B = BlockQueue.pop_back_val();
-    BlockSet[B] = 0;
-    return B;
-  }
-
-  /// isEmpty - Return true if the worklist is empty.
-  bool isEmpty() const { return BlockQueue.empty(); }
-};
-
-//===----------------------------------------------------------------------===//
-// BlockItrTraits - Traits classes that allow transparent iteration
-//  over successors/predecessors of a block depending on the direction
-//  of our dataflow analysis.
-//===----------------------------------------------------------------------===//
-
-namespace dataflow {
-template<typename Tag> struct ItrTraits {};
-
-template <> struct ItrTraits<forward_analysis_tag> {
-  typedef CFGBlock::const_pred_iterator PrevBItr;
-  typedef CFGBlock::const_succ_iterator NextBItr;
-  typedef CFGBlock::const_iterator      StmtItr;
-
-  static PrevBItr PrevBegin(const CFGBlock *B) { return B->pred_begin(); }
-  static PrevBItr PrevEnd(const CFGBlock *B) { return B->pred_end(); }
-
-  static NextBItr NextBegin(const CFGBlock *B) { return B->succ_begin(); }
-  static NextBItr NextEnd(const CFGBlock *B) { return B->succ_end(); }
-
-  static StmtItr StmtBegin(const CFGBlock *B) { return B->begin(); }
-  static StmtItr StmtEnd(const CFGBlock *B) { return B->end(); }
-
-  static BlockEdge PrevEdge(const CFGBlock *B, const CFGBlock *Prev) {
-    return BlockEdge(Prev, B, 0);
-  }
-
-  static BlockEdge NextEdge(const CFGBlock *B, const CFGBlock *Next) {
-    return BlockEdge(B, Next, 0);
-  }
-};
-
-template <> struct ItrTraits<backward_analysis_tag> {
-  typedef CFGBlock::const_succ_iterator    PrevBItr;
-  typedef CFGBlock::const_pred_iterator    NextBItr;
-  typedef CFGBlock::const_reverse_iterator StmtItr;
-
-  static PrevBItr PrevBegin(const CFGBlock *B) { return B->succ_begin(); }
-  static PrevBItr PrevEnd(const CFGBlock *B) { return B->succ_end(); }
-
-  static NextBItr NextBegin(const CFGBlock *B) { return B->pred_begin(); }
-  static NextBItr NextEnd(const CFGBlock *B) { return B->pred_end(); }
-
-  static StmtItr StmtBegin(const CFGBlock *B) { return B->rbegin(); }
-  static StmtItr StmtEnd(const CFGBlock *B) { return B->rend(); }
-
-  static BlockEdge PrevEdge(const CFGBlock *B, const CFGBlock *Prev) {
-    return BlockEdge(B, Prev, 0);
-  }
-
-  static BlockEdge NextEdge(const CFGBlock *B, const CFGBlock *Next) {
-    return BlockEdge(Next, B, 0);
-  }
-};
-} // end namespace dataflow
-
-//===----------------------------------------------------------------------===//
-/// DataflowSolverTy - Generic dataflow solver.
-//===----------------------------------------------------------------------===//
-
-template <typename _DFValuesTy,      // Usually a subclass of DataflowValues
-          typename _TransferFuncsTy,
-          typename _MergeOperatorTy,
-          typename _Equal = std::equal_to<typename _DFValuesTy::ValTy> >
-class DataflowSolver {
-
-  //===----------------------------------------------------===//
-  // Type declarations.
-  //===----------------------------------------------------===//
-
-public:
-  typedef _DFValuesTy                              DFValuesTy;
-  typedef _TransferFuncsTy                         TransferFuncsTy;
-  typedef _MergeOperatorTy                         MergeOperatorTy;
-
-  typedef typename _DFValuesTy::AnalysisDirTag     AnalysisDirTag;
-  typedef typename _DFValuesTy::ValTy              ValTy;
-  typedef typename _DFValuesTy::EdgeDataMapTy      EdgeDataMapTy;
-  typedef typename _DFValuesTy::BlockDataMapTy     BlockDataMapTy;
-
-  typedef dataflow::ItrTraits<AnalysisDirTag>      ItrTraits;
-  typedef typename ItrTraits::NextBItr             NextBItr;
-  typedef typename ItrTraits::PrevBItr             PrevBItr;
-  typedef typename ItrTraits::StmtItr              StmtItr;
-
-  //===----------------------------------------------------===//
-  // External interface: constructing and running the solver.
-  //===----------------------------------------------------===//
-
-public:
-  DataflowSolver(DFValuesTy& d) : D(d), TF(d.getAnalysisData()) {}
-  ~DataflowSolver() {}
-
-  /// runOnCFG - Computes dataflow values for all blocks in a CFG.
-  void runOnCFG(CFG& cfg, bool recordStmtValues = false) {
-    // Set initial dataflow values and boundary conditions.
-    D.InitializeValues(cfg);
-    // Solve the dataflow equations.  This will populate D.EdgeDataMap
-    // with dataflow values.
-    SolveDataflowEquations(cfg, recordStmtValues);
-  }
-
-  /// runOnBlock - Computes dataflow values for a given block.  This
-  ///  should usually be invoked only after previously computing
-  ///  dataflow values using runOnCFG, as runOnBlock is intended to
-  ///  only be used for querying the dataflow values within a block
-  ///  with and Observer object.
-  void runOnBlock(const CFGBlock *B, bool recordStmtValues) {
-    BlockDataMapTy& M = D.getBlockDataMap();
-    typename BlockDataMapTy::iterator I = M.find(B);
-
-    if (I != M.end()) {
-      TF.getVal().copyValues(I->second);
-      ProcessBlock(B, recordStmtValues, AnalysisDirTag());
-    }
-  }
-
-  void runOnBlock(const CFGBlock &B, bool recordStmtValues) {
-    runOnBlock(&B, recordStmtValues);
-  }
-  void runOnBlock(CFG::iterator &I, bool recordStmtValues) {
-    runOnBlock(*I, recordStmtValues);
-  }
-  void runOnBlock(CFG::const_iterator &I, bool recordStmtValues) {
-    runOnBlock(*I, recordStmtValues);
-  }
-
-  void runOnAllBlocks(const CFG& cfg, bool recordStmtValues = false) {
-    for (CFG::const_iterator I=cfg.begin(), E=cfg.end(); I!=E; ++I)
-      runOnBlock(I, recordStmtValues);
-  }
-
-  //===----------------------------------------------------===//
-  // Internal solver logic.
-  //===----------------------------------------------------===//
-
-private:
-
-  /// SolveDataflowEquations - Perform the actual worklist algorithm
-  ///  to compute dataflow values.
-  void SolveDataflowEquations(CFG& cfg, bool recordStmtValues) {
-    EnqueueBlocksOnWorklist(cfg, AnalysisDirTag());
-
-    while (!WorkList.isEmpty()) {
-      const CFGBlock *B = WorkList.dequeue();
-      ProcessMerge(cfg, B);
-      ProcessBlock(B, recordStmtValues, AnalysisDirTag());
-      UpdateEdges(cfg, B, TF.getVal());
-    }
-  }
-
-  void EnqueueBlocksOnWorklist(CFG &cfg, dataflow::forward_analysis_tag) {
-    // Enqueue all blocks to ensure the dataflow values are computed
-    // for every block.  Not all blocks are guaranteed to reach the exit block.
-    for (CFG::iterator I=cfg.begin(), E=cfg.end(); I!=E; ++I)
-      WorkList.enqueue(&**I);
-  }
-
-  void EnqueueBlocksOnWorklist(CFG &cfg, dataflow::backward_analysis_tag) {
-    // Enqueue all blocks to ensure the dataflow values are computed
-    // for every block.  Not all blocks are guaranteed to reach the exit block.
-    // Enqueue in reverse order since that will more likely match with
-    // the order they should ideally processed by the dataflow algorithm.
-    for (CFG::reverse_iterator I=cfg.rbegin(), E=cfg.rend(); I!=E; ++I)
-      WorkList.enqueue(&**I);
-  }
-
-  void ProcessMerge(CFG& cfg, const CFGBlock *B) {
-    ValTy& V = TF.getVal();
-    TF.SetTopValue(V);
-
-    // Merge dataflow values from all predecessors of this block.
-    MergeOperatorTy Merge;
-
-    EdgeDataMapTy& M = D.getEdgeDataMap();
-    bool firstMerge = true;
-    bool noEdges = true;
-    for (PrevBItr I=ItrTraits::PrevBegin(B),E=ItrTraits::PrevEnd(B); I!=E; ++I){
-
-      CFGBlock *PrevBlk = *I;
-
-      if (!PrevBlk)
-        continue;
-
-      typename EdgeDataMapTy::iterator EI =
-        M.find(ItrTraits::PrevEdge(B, PrevBlk));
-
-      if (EI != M.end()) {
-        noEdges = false;
-        if (firstMerge) {
-          firstMerge = false;
-          V.copyValues(EI->second);
-        }
-        else
-          Merge(V, EI->second);
-      }
-    }
-
-    bool isInitialized = true;
-    typename BlockDataMapTy::iterator BI = D.getBlockDataMap().find(B);
-    if(BI == D.getBlockDataMap().end()) {
-      isInitialized = false;
-      BI = D.getBlockDataMap().insert( std::make_pair(B,ValTy()) ).first;
-    }
-    // If no edges have been found, it means this is the first time the solver 
-    // has been called on block B, we copy the initialization values (if any)
-    // as current value for V (which will be used as edge data)
-    if(noEdges && isInitialized) 
-      Merge(V, BI->second);
-
-    // Set the data for the block.
-    BI->second.copyValues(V);
-  }
-
-  /// ProcessBlock - Process the transfer functions for a given block.
-  void ProcessBlock(const CFGBlock *B, bool recordStmtValues,
-                    dataflow::forward_analysis_tag) {
-
-    TF.setCurrentBlock(B);
-    
-    for (StmtItr I=ItrTraits::StmtBegin(B), E=ItrTraits::StmtEnd(B); I!=E;++I) {
-      CFGElement El = *I;
-      if (const CFGStmt *S = El.getAs<CFGStmt>())
-        ProcessStmt(S->getStmt(), recordStmtValues, AnalysisDirTag());
-    }
-
-    TF.VisitTerminator(const_cast<CFGBlock*>(B));
-  }
-
-  void ProcessBlock(const CFGBlock *B, bool recordStmtValues,
-                    dataflow::backward_analysis_tag) {
-
-    TF.setCurrentBlock(B);
-    
-    TF.VisitTerminator(const_cast<CFGBlock*>(B));
-
-    for (StmtItr I=ItrTraits::StmtBegin(B), E=ItrTraits::StmtEnd(B); I!=E;++I) {
-      CFGElement El = *I;
-      if (const CFGStmt *S = El.getAs<CFGStmt>())
-        ProcessStmt(S->getStmt(), recordStmtValues, AnalysisDirTag());
-    }
-  }
-
-  void ProcessStmt(const Stmt *S, bool record, dataflow::forward_analysis_tag) {
-    if (record) D.getStmtDataMap()[S] = TF.getVal();
-    TF.BlockStmt_Visit(const_cast<Stmt*>(S));
-  }
-
-  void ProcessStmt(const Stmt *S, bool record, dataflow::backward_analysis_tag){
-    TF.BlockStmt_Visit(const_cast<Stmt*>(S));
-    if (record) D.getStmtDataMap()[S] = TF.getVal();
-  }
-
-  /// UpdateEdges - After processing the transfer functions for a
-  ///   block, update the dataflow value associated with the block's
-  ///   outgoing/incoming edges (depending on whether we do a
-  //    forward/backward analysis respectively)
-  void UpdateEdges(CFG& cfg, const CFGBlock *B, ValTy& V) {
-    for (NextBItr I=ItrTraits::NextBegin(B), E=ItrTraits::NextEnd(B); I!=E; ++I)
-      if (CFGBlock *NextBlk = *I)
-        UpdateEdgeValue(ItrTraits::NextEdge(B, NextBlk),V, NextBlk);
-  }
-
-  /// UpdateEdgeValue - Update the value associated with a given edge.
-  void UpdateEdgeValue(BlockEdge E, ValTy& V, const CFGBlock *TargetBlock) {
-    EdgeDataMapTy& M = D.getEdgeDataMap();
-    typename EdgeDataMapTy::iterator I = M.find(E);
-
-    if (I == M.end()) {  // First computed value for this edge?
-      M[E].copyValues(V);
-      WorkList.enqueue(TargetBlock);
-    }
-    else if (!_Equal()(V,I->second)) {
-      I->second.copyValues(V);
-      WorkList.enqueue(TargetBlock);
-    }
-  }
-
-private:
-  DFValuesTy& D;
-  DataflowWorkListTy WorkList;
-  TransferFuncsTy TF;
-};
-
-} // end namespace clang
-#endif
diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h
index 333329d..57324d0 100644
--- a/include/clang/Analysis/ProgramPoint.h
+++ b/include/clang/Analysis/ProgramPoint.h
@@ -77,9 +77,9 @@
   ProgramPoint(const void *P,
                Kind k,
                const LocationContext *l,
-               const ProgramPointTag *tag = 0)
+               const ProgramPointTag *tag = nullptr)
     : Data1(P),
-      Data2(0, (((unsigned) k) >> 0) & 0x3),
+      Data2(nullptr, (((unsigned) k) >> 0) & 0x3),
       L(l, (((unsigned) k) >> 2) & 0x3),
       Tag(tag, (((unsigned) k) >> 4) & 0x3) {
         assert(getKind() == k);
@@ -91,7 +91,7 @@
                const void *P2,
                Kind k,
                const LocationContext *l,
-               const ProgramPointTag *tag = 0)
+               const ProgramPointTag *tag = nullptr)
     : Data1(P1),
       Data2(P2, (((unsigned) k) >> 0) & 0x3),
       L(l, (((unsigned) k) >> 2) & 0x3),
@@ -193,7 +193,7 @@
 class BlockEntrance : public ProgramPoint {
 public:
   BlockEntrance(const CFGBlock *B, const LocationContext *L,
-                const ProgramPointTag *tag = 0)
+                const ProgramPointTag *tag = nullptr)
     : ProgramPoint(B, BlockEntranceKind, L, tag) {    
     assert(B && "BlockEntrance requires non-null block");
   }
@@ -263,7 +263,7 @@
 class PreStmt : public StmtPoint {
 public:
   PreStmt(const Stmt *S, const LocationContext *L, const ProgramPointTag *tag,
-          const Stmt *SubStmt = 0)
+          const Stmt *SubStmt = nullptr)
     : StmtPoint(S, SubStmt, PreStmtKind, L, tag) {}
 
   const Stmt *getSubStmt() const { return (const Stmt*) getData2(); }
@@ -280,17 +280,17 @@
 protected:
   PostStmt() {}
   PostStmt(const Stmt *S, const void *data, Kind k, const LocationContext *L,
-           const ProgramPointTag *tag = 0)
+           const ProgramPointTag *tag = nullptr)
     : StmtPoint(S, data, k, L, tag) {}
 
 public:
-  explicit PostStmt(const Stmt *S, Kind k, 
-                    const LocationContext *L, const ProgramPointTag *tag = 0)
-    : StmtPoint(S, NULL, k, L, tag) {}
+  explicit PostStmt(const Stmt *S, Kind k, const LocationContext *L,
+                    const ProgramPointTag *tag = nullptr)
+    : StmtPoint(S, nullptr, k, L, tag) {}
 
   explicit PostStmt(const Stmt *S, const LocationContext *L,
-                    const ProgramPointTag *tag = 0)
-    : StmtPoint(S, NULL, PostStmtKind, L, tag) {}
+                    const ProgramPointTag *tag = nullptr)
+    : StmtPoint(S, nullptr, PostStmtKind, L, tag) {}
 
 private:
   friend class ProgramPoint;
@@ -304,7 +304,7 @@
 class PostCondition : public PostStmt {
 public:
   PostCondition(const Stmt *S, const LocationContext *L,
-                const ProgramPointTag *tag = 0)
+                const ProgramPointTag *tag = nullptr)
     : PostStmt(S, PostConditionKind, L, tag) {}
 
 private:
@@ -320,7 +320,7 @@
   LocationCheck() {}
   LocationCheck(const Stmt *S, const LocationContext *L,
                 ProgramPoint::Kind K, const ProgramPointTag *tag)
-    : StmtPoint(S, NULL, K, L, tag) {}
+    : StmtPoint(S, nullptr, K, L, tag) {}
     
 private:
   friend class ProgramPoint;
@@ -333,7 +333,7 @@
 class PreLoad : public LocationCheck {
 public:
   PreLoad(const Stmt *S, const LocationContext *L,
-          const ProgramPointTag *tag = 0)
+          const ProgramPointTag *tag = nullptr)
     : LocationCheck(S, L, PreLoadKind, tag) {}
   
 private:
@@ -347,7 +347,7 @@
 class PreStore : public LocationCheck {
 public:
   PreStore(const Stmt *S, const LocationContext *L,
-           const ProgramPointTag *tag = 0)
+           const ProgramPointTag *tag = nullptr)
   : LocationCheck(S, L, PreStoreKind, tag) {}
   
 private:
@@ -361,7 +361,7 @@
 class PostLoad : public PostStmt {
 public:
   PostLoad(const Stmt *S, const LocationContext *L,
-           const ProgramPointTag *tag = 0)
+           const ProgramPointTag *tag = nullptr)
     : PostStmt(S, PostLoadKind, L, tag) {}
 
 private:
@@ -379,9 +379,9 @@
   /// \param Loc can be used to store the information about the location 
   /// used in the form it was uttered in the code.
   PostStore(const Stmt *S, const LocationContext *L, const void *Loc,
-            const ProgramPointTag *tag = 0)
+            const ProgramPointTag *tag = nullptr)
     : PostStmt(S, PostStoreKind, L, tag) {
-    assert(getData2() == 0);
+    assert(getData2() == nullptr);
     setData2(Loc);
   }
 
@@ -402,7 +402,7 @@
 class PostLValue : public PostStmt {
 public:
   PostLValue(const Stmt *S, const LocationContext *L,
-             const ProgramPointTag *tag = 0)
+             const ProgramPointTag *tag = nullptr)
     : PostStmt(S, PostLValueKind, L, tag) {}
 
 private:
@@ -418,8 +418,8 @@
 class PreStmtPurgeDeadSymbols : public StmtPoint {
 public:
   PreStmtPurgeDeadSymbols(const Stmt *S, const LocationContext *L,
-                       const ProgramPointTag *tag = 0)
-    : StmtPoint(S, 0, PreStmtPurgeDeadSymbolsKind, L, tag) { }
+                       const ProgramPointTag *tag = nullptr)
+    : StmtPoint(S, nullptr, PreStmtPurgeDeadSymbolsKind, L, tag) { }
 
 private:
   friend class ProgramPoint;
@@ -434,8 +434,8 @@
 class PostStmtPurgeDeadSymbols : public StmtPoint {
 public:
   PostStmtPurgeDeadSymbols(const Stmt *S, const LocationContext *L,
-                       const ProgramPointTag *tag = 0)
-    : StmtPoint(S, 0, PostStmtPurgeDeadSymbolsKind, L, tag) { }
+                       const ProgramPointTag *tag = nullptr)
+    : StmtPoint(S, nullptr, PostStmtPurgeDeadSymbolsKind, L, tag) { }
 
 private:
   friend class ProgramPoint;
@@ -527,8 +527,8 @@
 /// Explicit calls will appear as PreStmt program points.
 class PreImplicitCall : public ImplicitCallPoint {
 public:
-  PreImplicitCall(const Decl *D, SourceLocation Loc,
-                  const LocationContext *L, const ProgramPointTag *Tag = 0)
+  PreImplicitCall(const Decl *D, SourceLocation Loc, const LocationContext *L,
+                  const ProgramPointTag *Tag = nullptr)
     : ImplicitCallPoint(D, Loc, PreImplicitCallKind, L, Tag) {}
 
 private:
@@ -544,8 +544,8 @@
 /// Explicit calls will appear as PostStmt program points.
 class PostImplicitCall : public ImplicitCallPoint {
 public:
-  PostImplicitCall(const Decl *D, SourceLocation Loc,
-                   const LocationContext *L, const ProgramPointTag *Tag = 0)
+  PostImplicitCall(const Decl *D, SourceLocation Loc, const LocationContext *L,
+                   const ProgramPointTag *Tag = nullptr)
     : ImplicitCallPoint(D, Loc, PostImplicitCallKind, L, Tag) {}
 
 private:
@@ -562,7 +562,7 @@
 public:
   CallEnter(const Stmt *stmt, const StackFrameContext *calleeCtx, 
             const LocationContext *callerCtx)
-    : ProgramPoint(stmt, calleeCtx, CallEnterKind, callerCtx, 0) {}
+    : ProgramPoint(stmt, calleeCtx, CallEnterKind, callerCtx, nullptr) {}
 
   const Stmt *getCallExpr() const {
     return static_cast<const Stmt *>(getData1());
@@ -593,7 +593,7 @@
 public:
   // CallExitBegin uses the callee's location context.
   CallExitBegin(const StackFrameContext *L)
-    : ProgramPoint(0, CallExitBeginKind, L, 0) {}
+    : ProgramPoint(nullptr, CallExitBeginKind, L, nullptr) {}
 
 private:
   friend class ProgramPoint;
@@ -610,7 +610,7 @@
   // CallExitEnd uses the caller's location context.
   CallExitEnd(const StackFrameContext *CalleeCtx,
               const LocationContext *CallerCtx)
-    : ProgramPoint(CalleeCtx, CallExitEndKind, CallerCtx, 0) {}
+    : ProgramPoint(CalleeCtx, CallExitEndKind, CallerCtx, nullptr) {}
 
   const StackFrameContext *getCalleeContext() const {
     return static_cast<const StackFrameContext *>(getData1());
@@ -629,7 +629,8 @@
 class EpsilonPoint : public ProgramPoint {
 public:
   EpsilonPoint(const LocationContext *L, const void *Data1,
-               const void *Data2 = 0, const ProgramPointTag *tag = 0)
+               const void *Data2 = nullptr,
+               const ProgramPointTag *tag = nullptr)
     : ProgramPoint(Data1, Data2, EpsilonKind, L, tag) {}
 
   const void *getData() const { return getData1(); }
@@ -647,7 +648,7 @@
 /// description and potentially other information.
 class ProgramPointTag {
 public:
-  ProgramPointTag(void *tagKind = 0) : TagKind(tagKind) {}
+  ProgramPointTag(void *tagKind = nullptr) : TagKind(tagKind) {}
   virtual ~ProgramPointTag();
   virtual StringRef getTagDescription() const = 0;    
 
@@ -658,12 +659,12 @@
 private:
   const void *TagKind;
 };
-  
+
 class SimpleProgramPointTag : public ProgramPointTag {
-  std::string desc;
+  std::string Desc;
 public:
-  SimpleProgramPointTag(StringRef description);
-  StringRef getTagDescription() const;
+  SimpleProgramPointTag(StringRef MsgProvider, StringRef Msg);
+  StringRef getTagDescription() const override;
 };
 
 } // end namespace clang
@@ -676,13 +677,13 @@
 static inline clang::ProgramPoint getEmptyKey() {
   uintptr_t x =
    reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getEmptyKey()) & ~0x7;
-  return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), 0);
+  return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), nullptr);
 }
 
 static inline clang::ProgramPoint getTombstoneKey() {
   uintptr_t x =
    reinterpret_cast<uintptr_t>(DenseMapInfo<void*>::getTombstoneKey()) & ~0x7;
-  return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), 0);
+  return clang::BlockEntrance(reinterpret_cast<clang::CFGBlock*>(x), nullptr);
 }
 
 static unsigned getHashValue(const clang::ProgramPoint &Loc) {
diff --git a/include/clang/Analysis/Support/BumpVector.h b/include/clang/Analysis/Support/BumpVector.h
index 387e779..6d0427b 100644
--- a/include/clang/Analysis/Support/BumpVector.h
+++ b/include/clang/Analysis/Support/BumpVector.h
@@ -55,12 +55,12 @@
 public:
   // Default ctor - Initialize to empty.
   explicit BumpVector(BumpVectorContext &C, unsigned N)
-  : Begin(NULL), End(NULL), Capacity(NULL) {
+  : Begin(nullptr), End(nullptr), Capacity(nullptr) {
     reserve(C, N);
   }
   
   ~BumpVector() {
-    if (llvm::is_class<T>::value) {
+    if (std::is_class<T>::value) {
       // Destroy the constructed elements in the vector.
       destroy_range(Begin, End);
     }
@@ -130,7 +130,7 @@
   }
   
   void clear() {
-    if (llvm::is_class<T>::value) {
+    if (std::is_class<T>::value) {
       destroy_range(Begin, End);
     }
     End = Begin;
@@ -223,7 +223,7 @@
   T *NewElts = C.getAllocator().template Allocate<T>(NewCapacity);
   
   // Copy the elements over.
-  if (llvm::is_class<T>::value) {
+  if (std::is_class<T>::value) {
     std::uninitialized_copy(Begin, End, NewElts);
     // Destroy the original elements.
     destroy_range(Begin, End);
diff --git a/include/clang/Basic/ABI.h b/include/clang/Basic/ABI.h
index 3b3d59e..9e8ef2e 100644
--- a/include/clang/Basic/ABI.h
+++ b/include/clang/Basic/ABI.h
@@ -186,10 +186,10 @@
   /// an ABI-specific comparator.
   const CXXMethodDecl *Method;
 
-  ThunkInfo() : Method(0) { }
+  ThunkInfo() : Method(nullptr) { }
 
   ThunkInfo(const ThisAdjustment &This, const ReturnAdjustment &Return,
-            const CXXMethodDecl *Method = 0)
+            const CXXMethodDecl *Method = nullptr)
       : This(This), Return(Return), Method(Method) {}
 
   friend bool operator==(const ThunkInfo &LHS, const ThunkInfo &RHS) {
@@ -197,7 +197,9 @@
            LHS.Method == RHS.Method;
   }
 
-  bool isEmpty() const { return This.isEmpty() && Return.isEmpty() && Method == 0; }
+  bool isEmpty() const {
+    return This.isEmpty() && Return.isEmpty() && Method == nullptr;
+  }
 };  
 
 } // end namespace clang
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index a149a6a..704a375 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -1,8 +1,59 @@
-////////////////////////////////////////////////////////////////////////////////
-// Note: This file is a work in progress. Please do not apply non-trivial
-// updates unless you have talked to Sean Hunt <rideau3@gmail.com> prior.
-// Merely adding a new attribute is a trivial update.
-////////////////////////////////////////////////////////////////////////////////
+//==--- Attr.td - attribute definitions -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// The documentation is organized by category. Attributes can have category-
+// specific documentation that is collated within the larger document.
+class DocumentationCategory<string name> {
+  string Name = name;
+  code Content = [{}];
+}
+def DocCatFunction : DocumentationCategory<"Function Attributes">;
+def DocCatVariable : DocumentationCategory<"Variable Attributes">;
+def DocCatType : DocumentationCategory<"Type Attributes">;
+def DocCatStmt : DocumentationCategory<"Statement Attributes">;
+// Attributes listed under the Undocumented category do not generate any public
+// documentation. Ideally, this category should be used for internal-only
+// attributes which contain no spellings.
+def DocCatUndocumented : DocumentationCategory<"Undocumented">;
+
+class DocDeprecated<string replacement = ""> {
+  // If the Replacement field is empty, no replacement will be listed with the
+  // documentation. Otherwise, the documentation will specify the attribute has
+  // been superseded by this replacement.
+  string Replacement = replacement;
+}
+
+// Specifies the documentation to be associated with the given category.
+class Documentation {
+  DocumentationCategory Category;
+  code Content;
+
+  // If the heading is empty, one may be picked automatically. If the attribute
+  // only has one spelling, no heading is required as the attribute's sole
+  // spelling is sufficient. If all spellings are semantically common, the
+  // heading will be the semantic spelling. If the spellings are not
+  // semantically common and no heading is provided, an error will be emitted.
+  string Heading = "";
+
+  // When set, specifies that the attribute is deprecated and can optionally
+  // specify a replacement attribute.
+  DocDeprecated Deprecated;
+}
+
+// Specifies that the attribute is explicitly undocumented. This can be a
+// helpful placeholder for the attribute while working on the implementation,
+// but should not be used once feature work has been completed.
+def Undocumented : Documentation {
+  let Category = DocCatUndocumented;
+}
+
+include "clang/Basic/AttrDocs.td"
 
 // An attribute's subject is whatever it appertains to. In this file, it is
 // more accurately a list of things that an attribute can appertain to. All
@@ -16,31 +67,63 @@
 // A subset-subject is an AttrSubject constrained to operate only on some subset
 // of that subject.
 //
-// The description is used in output messages to specify what the subject
-// represents. FIXME: Deal with translation issues.
-//
 // The code fragment is a boolean expression that will confirm that the subject
 // meets the requirements; the subject will have the name S, and will have the
 // type specified by the base. It should be a simple boolean expression.
-class SubsetSubject<AttrSubject base, string description, code check>
-    : AttrSubject {
+class SubsetSubject<AttrSubject base, code check> : AttrSubject {
   AttrSubject Base = base;
-  string Description = description;
   code CheckCode = check;
 }
 
 // This is the type of a variable which C++11 allows alignas(...) to appertain
 // to.
-def NormalVar : SubsetSubject<Var, "non-register, non-parameter variable",
+def NormalVar : SubsetSubject<Var,
                               [{S->getStorageClass() != VarDecl::Register &&
                                 S->getKind() != Decl::ImplicitParam &&
                                 S->getKind() != Decl::ParmVar &&
                                 S->getKind() != Decl::NonTypeTemplateParm}]>;
-def CXXVirtualMethod : SubsetSubject<CXXRecord, "virtual member function",
-                                     [{S->isVirtual()}]>;
-def NonBitField : SubsetSubject<Field, "non-bit field",
+def NonBitField : SubsetSubject<Field,
                                 [{!S->isBitField()}]>;
 
+def ObjCInstanceMethod : SubsetSubject<ObjCMethod,
+                                       [{S->isInstanceMethod()}]>;
+
+def ObjCInterfaceDeclInitMethod : SubsetSubject<ObjCMethod,
+                               [{S->getMethodFamily() == OMF_init &&
+                                 (isa<ObjCInterfaceDecl>(S->getDeclContext()) ||
+                                  (isa<ObjCCategoryDecl>(S->getDeclContext()) &&
+            cast<ObjCCategoryDecl>(S->getDeclContext())->IsClassExtension()))}]>;
+
+def Struct : SubsetSubject<Record,
+                           [{!S->isUnion()}]>;
+
+def TLSVar : SubsetSubject<Var,
+                           [{S->getTLSKind() != 0}]>;
+
+def SharedVar : SubsetSubject<Var,
+                              [{S->hasGlobalStorage() && !S->getTLSKind()}]>;
+
+def GlobalVar : SubsetSubject<Var,
+                             [{S->hasGlobalStorage()}]>;
+
+// FIXME: this hack is needed because DeclNodes.td defines the base Decl node
+// type to be a class, not a definition. This makes it impossible to create an
+// attribute subject which accepts a Decl. Normally, this is not a problem,
+// because the attribute can have no Subjects clause to accomplish this. But in
+// the case of a SubsetSubject, there's no way to express it without this hack.
+def DeclBase : AttrSubject;
+def FunctionLike : SubsetSubject<DeclBase,
+                                  [{S->getFunctionType(false) != NULL}]>;
+
+// HasFunctionProto is a more strict version of FunctionLike, so it should
+// never be specified in a Subjects list along with FunctionLike (due to the
+// inclusive nature of subject testing).
+def HasFunctionProto : SubsetSubject<DeclBase,
+                                     [{(S->getFunctionType(true) != NULL &&
+                              isa<FunctionProtoType>(S->getFunctionType())) ||
+                                       isa<ObjCMethodDecl>(S) ||
+                                       isa<BlockDecl>(S)}]>;
+
 // A single argument to an attribute
 class Argument<string name, bit optional> {
   string Name = name;
@@ -55,7 +138,6 @@
 class FunctionArgument<string name, bit opt = 0> : Argument<name, opt>;
 class TypeArgument<string name, bit opt = 0> : Argument<name, opt>;
 class UnsignedArgument<string name, bit opt = 0> : Argument<name, opt>;
-class SourceLocArgument<string name, bit opt = 0> : Argument<name, opt>;
 class VariadicUnsignedArgument<string name> : Argument<name, 1>;
 class VariadicExprArgument<string name> : Argument<name, 1>;
 
@@ -67,6 +149,11 @@
 // be dependent.
 class AlignedArgument<string name, bit opt = 0> : Argument<name, opt>;
 
+// A bool argument with a default value
+class DefaultBoolArgument<string name, bit default> : BoolArgument<name, 1> {
+  bit Default = default;
+}
+
 // An integer argument with a default value
 class DefaultIntArgument<string name, int default> : IntArgument<name, 1> {
   int Default = default;
@@ -94,6 +181,7 @@
 class Spelling<string name, string variety> {
   string Name = name;
   string Variety = variety;
+  bit KnownToGCC;
 }
 
 class GNU<string name> : Spelling<name, "GNU">;
@@ -102,17 +190,62 @@
   string Namespace = namespace;
 }
 class Keyword<string name> : Spelling<name, "Keyword">;
+class Pragma<string namespace, string name> : Spelling<name, "Pragma"> {
+  string Namespace = namespace;
+}
+
+// The GCC spelling implies GNU<name, "GNU"> and CXX11<"gnu", name> and also
+// sets KnownToGCC to 1. This spelling should be used for any GCC-compatible
+// attributes.
+class GCC<string name> : Spelling<name, "GCC"> {
+  let KnownToGCC = 1;
+}
 
 class Accessor<string name, list<Spelling> spellings> {
   string Name = name;
   list<Spelling> Spellings = spellings;
 }
 
+class SubjectDiag<bit warn> {
+  bit Warn = warn;
+}
+def WarnDiag : SubjectDiag<1>;
+def ErrorDiag : SubjectDiag<0>;
+
+class SubjectList<list<AttrSubject> subjects, SubjectDiag diag = WarnDiag,
+                  string customDiag = ""> {
+  list<AttrSubject> Subjects = subjects;
+  SubjectDiag Diag = diag;
+  string CustomDiag = customDiag;
+}
+
+class LangOpt<string name> {
+  string Name = name;
+}
+def MicrosoftExt : LangOpt<"MicrosoftExt">;
+def Borland : LangOpt<"Borland">;
+def CUDA : LangOpt<"CUDA">;
+
+// Defines targets for target-specific attributes. The list of strings should
+// specify architectures for which the target applies, based off the ArchType
+// enumeration in Triple.h.
+class TargetArch<list<string> arches> {
+  list<string> Arches = arches;
+  list<string> OSes;
+}
+def TargetARM : TargetArch<["arm", "thumb"]>;
+def TargetMSP430 : TargetArch<["msp430"]>;
+def TargetX86 : TargetArch<["x86"]>;
+def TargetWindows : TargetArch<["x86", "x86_64", "arm", "thumb"]> {
+  let OSes = ["Win32"];
+}
+def TargetMips : TargetArch<["mips", "mipsel"]>;
+
 class Attr {
   // The various ways in which an attribute can be spelled in source
   list<Spelling> Spellings;
   // The things to which an attribute can appertain
-  list<AttrSubject> Subjects;
+  SubjectList Subjects;
   // The arguments allowed on an attribute
   list<Argument> Args = [];
   // Accessors which should be generated for the attribute.
@@ -130,28 +263,55 @@
   bit SemaHandler = 1;
   // Set to true for attributes that are completely ignored.
   bit Ignored = 0;
-  // Set to true if each of the spellings is a distinct attribute.
-  bit DistinctSpellings = 0;
   // Set to true if the attribute's parsing does not match its semantic
   // content. Eg) It parses 3 args, but semantically takes 4 args.  Opts out of
   // common attribute error checking.
   bit HasCustomParsing = 0;
+  // Set to true if all of the attribute's arguments should be parsed in an
+  // unevaluated context.
+  bit ParseArgumentsAsUnevaluated = 0;
+  // Set to true if this attribute can be duplicated on a subject when merging
+  // attributes. By default, attributes are not merged.
+  bit DuplicatesAllowedWhileMerging = 0;
+  // Lists language options, one of which is required to be true for the
+  // attribute to be applicable. If empty, no language options are required.
+  list<LangOpt> LangOpts = [];
   // Any additional text that should be included verbatim in the class.
   code AdditionalMembers = [{}];
+  // Any documentation that should be associated with the attribute. Since an
+  // attribute may be documented under multiple categories, more than one
+  // Documentation entry may be listed.
+  list<Documentation> Documentation;
 }
 
 /// A type attribute is not processed on a declaration or a statement.
 class TypeAttr : Attr {
+  // By default, type attributes do not get an AST node.
   let ASTNode = 0;
 }
 
 /// An inheritable attribute is inherited by later redeclarations.
 class InheritableAttr : Attr;
 
-/// A target-specific attribute that is meant to be processed via
-/// TargetAttributesSema::ProcessDeclAttribute.  This class is meant to be used
-/// as a mixin with InheritableAttr or Attr depending on the attribute's needs.
-class TargetSpecificAttr;
+/// A target-specific attribute.  This class is meant to be used as a mixin
+/// with InheritableAttr or Attr depending on the attribute's needs.
+class TargetSpecificAttr<TargetArch target> {
+  TargetArch Target = target;
+  // Attributes are generally required to have unique spellings for their names
+  // so that the parser can determine what kind of attribute it has parsed.
+  // However, target-specific attributes are special in that the attribute only
+  // "exists" for a given target. So two target-specific attributes can share
+  // the same name when they exist in different targets. To support this, a
+  // Kind can be explicitly specified for a target-specific attribute. This
+  // corresponds to the AttributeList::AT_* enum that is generated and it
+  // 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
+  // subjects differ, should specify HasCustomParsing = 1 and implement their
+  // own parsing and semantic handling requirements as-needed.
+  string ParseKind;
+}
 
 /// An inheritable parameter attribute is inherited by later
 /// redeclarations, even when it's written on a parameter.
@@ -162,6 +322,7 @@
   let Ignored = 1;
   let ASTNode = 0;
   let SemaHandler = 0;
+  let Documentation = [Undocumented];
 }
 
 //
@@ -171,66 +332,77 @@
 def AddressSpace : TypeAttr {
   let Spellings = [GNU<"address_space">];
   let Args = [IntArgument<"AddressSpace">];
+  let Documentation = [Undocumented];
 }
 
 def Alias : Attr {
-  let Spellings = [GNU<"alias">, CXX11<"gnu", "alias">];
+  let Spellings = [GCC<"alias">];
   let Args = [StringArgument<"Aliasee">];
+  let Documentation = [Undocumented];
 }
 
 def Aligned : InheritableAttr {
-  let Spellings = [GNU<"aligned">, Declspec<"align">, CXX11<"gnu", "aligned">,
-                   Keyword<"alignas">, Keyword<"_Alignas">];
-  let Subjects = [NonBitField, NormalVar, Tag];
+  let Spellings = [GCC<"aligned">, Declspec<"align">, Keyword<"alignas">,
+                   Keyword<"_Alignas">];
+//  let Subjects = SubjectList<[NonBitField, NormalVar, Tag]>;
   let Args = [AlignedArgument<"Alignment", 1>];
-  let Accessors = [Accessor<"isGNU", [GNU<"aligned">, CXX11<"gnu","aligned">]>,
+  let Accessors = [Accessor<"isGNU", [GCC<"aligned">]>,
                    Accessor<"isC11", [Keyword<"_Alignas">]>,
                    Accessor<"isAlignas", [Keyword<"alignas">,
                                           Keyword<"_Alignas">]>,
                    Accessor<"isDeclspec",[Declspec<"align">]>];
+  let Documentation = [Undocumented];
 }
 
 def AlignMac68k : InheritableAttr {
+  // This attribute has no spellings as it is only ever created implicitly.
   let Spellings = [];
   let SemaHandler = 0;
-}
-
-def AllocSize : InheritableAttr {
-  let Spellings = [GNU<"alloc_size">, CXX11<"gnu", "alloc_size">];
-  let Args = [VariadicUnsignedArgument<"Args">];
+  let Documentation = [Undocumented];
 }
 
 def AlwaysInline : InheritableAttr {
-  let Spellings = [GNU<"always_inline">, CXX11<"gnu", "always_inline">];
+  let Spellings = [GCC<"always_inline">, Keyword<"__forceinline">];
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [Undocumented];
 }
 
 def TLSModel : InheritableAttr {
-  let Spellings = [GNU<"tls_model">, CXX11<"gnu", "tls_model">];
-  let Subjects = [Var];
+  let Spellings = [GCC<"tls_model">];
+  let Subjects = SubjectList<[TLSVar], ErrorDiag, "ExpectedTLSVar">;
   let Args = [StringArgument<"Model">];
+  let Documentation = [TLSModelDocs];
 }
 
 def AnalyzerNoReturn : InheritableAttr {
   let Spellings = [GNU<"analyzer_noreturn">];
+  let Documentation = [Undocumented];
 }
 
 def Annotate : InheritableParamAttr {
   let Spellings = [GNU<"annotate">];
   let Args = [StringArgument<"Annotation">];
+  let Documentation = [Undocumented];
 }
 
-def ARMInterrupt : InheritableAttr, TargetSpecificAttr {
+def ARMInterrupt : InheritableAttr, TargetSpecificAttr<TargetARM> {
+  // NOTE: If you add any additional spellings, MSP430Interrupt's spellings
+  // must match.
   let Spellings = [GNU<"interrupt">];
   let Args = [EnumArgument<"Interrupt", "InterruptType",
                            ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", ""],
                            ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", "Generic"],
                            1>];
+  let ParseKind = "Interrupt";
+  let HasCustomParsing = 1;
+  let Documentation = [ARMInterruptDocs];
 }
 
 def AsmLabel : InheritableAttr {
-  let Spellings = [];
+  let Spellings = [Keyword<"asm">, Keyword<"__asm__">];
   let Args = [StringArgument<"Label">];
   let SemaHandler = 0;
+  let Documentation = [Undocumented];
 }
 
 def Availability : InheritableAttr {
@@ -246,11 +418,15 @@
              .Default(llvm::StringRef());
 } }];
   let HasCustomParsing = 1;
+  let DuplicatesAllowedWhileMerging = 1;
+//  let Subjects = SubjectList<[Named]>;
+  let Documentation = [AvailabilityDocs];
 }
 
 def Blocks : InheritableAttr {
   let Spellings = [GNU<"blocks">];
   let Args = [EnumArgument<"Type", "BlockType", ["byref"], ["ByRef"]>];
+  let Documentation = [Undocumented];
 }
 
 def Bounded : IgnoredAttr {
@@ -258,14 +434,15 @@
 }
 
 def CarriesDependency : InheritableParamAttr {
-  let Spellings = [GNU<"carries_dependency">, CXX11<"","carries_dependency">,
-                   CXX11<"std","carries_dependency">];
-  let Subjects = [ParmVar, Function];
+  let Spellings = [GNU<"carries_dependency">, CXX11<"","carries_dependency">];
+  let Subjects = SubjectList<[ParmVar, ObjCMethod, Function], ErrorDiag>;
+  let Documentation = [CarriesDependencyDocs];
 }
 
 def CDecl : InheritableAttr {
-  let Spellings = [GNU<"cdecl">, CXX11<"gnu", "cdecl">, Keyword<"__cdecl">,
-                   Keyword<"_cdecl">];
+  let Spellings = [GCC<"cdecl">, Keyword<"__cdecl">, Keyword<"_cdecl">];
+//  let Subjects = [Function, ObjCMethod];
+  let Documentation = [Undocumented];
 }
 
 // cf_audited_transfer indicates that the given function has been
@@ -274,7 +451,8 @@
 // '#pragma clang arc_cf_code_audited' rather than explicitly.
 def CFAuditedTransfer : InheritableAttr {
   let Spellings = [GNU<"cf_audited_transfer">];
-  let Subjects = [Function];
+  let Subjects = SubjectList<[Function], ErrorDiag>;
+  let Documentation = [Undocumented];
 }
 
 // cf_unknown_transfer is an explicit opt-out of cf_audited_transfer.
@@ -282,386 +460,623 @@
 // transfer semantics.
 def CFUnknownTransfer : InheritableAttr {
   let Spellings = [GNU<"cf_unknown_transfer">];
-  let Subjects = [Function];
+  let Subjects = SubjectList<[Function], ErrorDiag>;
+  let Documentation = [Undocumented];
 }
 
 def CFReturnsRetained : InheritableAttr {
   let Spellings = [GNU<"cf_returns_retained">];
-  let Subjects = [ObjCMethod, Function];
+//  let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
+  let Documentation = [Undocumented];
 }
 
 def CFReturnsNotRetained : InheritableAttr {
   let Spellings = [GNU<"cf_returns_not_retained">];
-  let Subjects = [ObjCMethod, Function];
+//  let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
+  let Documentation = [Undocumented];
 }
 
 def CFConsumed : InheritableParamAttr {
   let Spellings = [GNU<"cf_consumed">];
-  let Subjects = [ParmVar];
+  let Subjects = SubjectList<[ParmVar]>;
+  let Documentation = [Undocumented];
 }
 
 def Cleanup : InheritableAttr {
-  let Spellings = [GNU<"cleanup">, CXX11<"gnu", "cleanup">];
+  let Spellings = [GCC<"cleanup">];
   let Args = [FunctionArgument<"FunctionDecl">];
+  let Subjects = SubjectList<[Var]>;
+  let Documentation = [Undocumented];
 }
 
 def Cold : InheritableAttr {
-  let Spellings = [GNU<"cold">, CXX11<"gnu", "cold">];
+  let Spellings = [GCC<"cold">];
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [Undocumented];
 }
 
 def Common : InheritableAttr {
-  let Spellings = [GNU<"common">, CXX11<"gnu", "common">];
+  let Spellings = [GCC<"common">];
+  let Subjects = SubjectList<[Var]>;
+  let Documentation = [Undocumented];
 }
 
 def Const : InheritableAttr {
-  let Spellings = [GNU<"const">, GNU<"__const">,
-                   CXX11<"gnu", "const">, CXX11<"gnu", "__const">];
+  let Spellings = [GCC<"const">, GCC<"__const">];
+  let Documentation = [Undocumented];
 }
 
 def Constructor : InheritableAttr {
-  let Spellings = [GNU<"constructor">, CXX11<"gnu", "constructor">];
-  let Args = [IntArgument<"Priority", 1>];
+  let Spellings = [GCC<"constructor">];
+  let Args = [DefaultIntArgument<"Priority", 65535>];
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [Undocumented];
 }
 
 def CUDAConstant : InheritableAttr {
   let Spellings = [GNU<"constant">];
+  let Subjects = SubjectList<[Var]>;
+  let LangOpts = [CUDA];
+  let Documentation = [Undocumented];
 }
 
 def CUDADevice : InheritableAttr {
   let Spellings = [GNU<"device">];
+  let Subjects = SubjectList<[Function, Var]>;
+  let LangOpts = [CUDA];
+  let Documentation = [Undocumented];
 }
 
 def CUDAGlobal : InheritableAttr {
   let Spellings = [GNU<"global">];
+  let Subjects = SubjectList<[Function]>;
+  let LangOpts = [CUDA];
+  let Documentation = [Undocumented];
 }
 
 def CUDAHost : InheritableAttr {
   let Spellings = [GNU<"host">];
+  let Subjects = SubjectList<[Function]>;
+  let LangOpts = [CUDA];
+  let Documentation = [Undocumented];
 }
 
 def CUDALaunchBounds : InheritableAttr {
   let Spellings = [GNU<"launch_bounds">];
   let Args = [IntArgument<"MaxThreads">, DefaultIntArgument<"MinBlocks", 0>];
+  let LangOpts = [CUDA];
+  let Subjects = SubjectList<[ObjCMethod, FunctionLike], WarnDiag,
+                             "ExpectedFunctionOrMethod">;
+  // An AST node is created for this attribute, but is not used by other parts
+  // of the compiler. However, this node needs to exist in the AST because
+  // non-LLVM backends may be relying on the attribute's presence.
+  let Documentation = [Undocumented];
 }
 
 def CUDAShared : InheritableAttr {
   let Spellings = [GNU<"shared">];
+  let Subjects = SubjectList<[Var]>;
+  let LangOpts = [CUDA];
+  let Documentation = [Undocumented];
 }
 
 def C11NoReturn : InheritableAttr {
   let Spellings = [Keyword<"_Noreturn">];
-  let Subjects = [Function];
+  let Subjects = SubjectList<[Function], ErrorDiag>;
   let SemaHandler = 0;
+  let Documentation = [C11NoReturnDocs];
 }
 
 def CXX11NoReturn : InheritableAttr {
-  let Spellings = [CXX11<"","noreturn">, CXX11<"std","noreturn">];
-  let Subjects = [Function];
+  let Spellings = [CXX11<"","noreturn">];
+  let Subjects = SubjectList<[Function], ErrorDiag>;
+  let Documentation = [CXX11NoReturnDocs];
 }
 
 def OpenCLKernel : InheritableAttr {
   let Spellings = [Keyword<"__kernel">, Keyword<"kernel">];
+  let Subjects = SubjectList<[Function], ErrorDiag>;
+  let Documentation = [Undocumented];
 }
 
+// This attribute is both a type attribute, and a declaration attribute (for
+// parameter variables).
 def OpenCLImageAccess : Attr {
-  let Spellings = [GNU<"opencl_image_access">];
-  let Args = [IntArgument<"Access">];
+  let Spellings = [Keyword<"__read_only">, Keyword<"read_only">,
+                   Keyword<"__write_only">, Keyword<"write_only">,
+                   Keyword<"__read_write">, Keyword<"read_write">];
+  let Subjects = SubjectList<[ParmVar], ErrorDiag>;
+  let Accessors = [Accessor<"isReadOnly", [Keyword<"__read_only">,
+                                           Keyword<"read_only">]>,
+                   Accessor<"isReadWrite", [Keyword<"__read_write">,
+                                            Keyword<"read_write">]>,
+                   Accessor<"isWriteOnly", [Keyword<"__write_only">,
+                                            Keyword<"write_only">]>];
+  let Documentation = [Undocumented];
+}
+
+def OpenCLPrivateAddressSpace : TypeAttr {
+  let Spellings = [Keyword<"__private">, Keyword<"private">];
+  let Documentation = [Undocumented];
+}
+
+def OpenCLGlobalAddressSpace : TypeAttr {
+  let Spellings = [Keyword<"__global">, Keyword<"global">];
+  let Documentation = [Undocumented];
+}
+
+def OpenCLLocalAddressSpace : TypeAttr {
+  let Spellings = [Keyword<"__local">, Keyword<"local">];
+  let Documentation = [Undocumented];
+}
+
+def OpenCLConstantAddressSpace : TypeAttr {
+  let Spellings = [Keyword<"__constant">, Keyword<"constant">];
+  let Documentation = [Undocumented];
 }
 
 def Deprecated : InheritableAttr {
-  let Spellings = [GNU<"deprecated">,
-                   CXX11<"gnu", "deprecated">, CXX11<"","deprecated">];
+  let Spellings = [GCC<"deprecated">, Declspec<"deprecated">,
+                   CXX11<"","deprecated">];
   let Args = [StringArgument<"Message", 1>];
+  let Documentation = [Undocumented];
 }
 
 def Destructor : InheritableAttr {
-  let Spellings = [GNU<"destructor">, CXX11<"gnu", "destructor">];
-  let Args = [IntArgument<"Priority", 1>];
+  let Spellings = [GCC<"destructor">];
+  let Args = [DefaultIntArgument<"Priority", 65535>];
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [Undocumented];
+}
+
+def EnableIf : InheritableAttr {
+  let Spellings = [GNU<"enable_if">];
+  let Subjects = SubjectList<[Function]>;
+  let Args = [ExprArgument<"Cond">, StringArgument<"Message">];
+  let TemplateDependent = 1;
+  let Documentation = [EnableIfDocs];
 }
 
 def ExtVectorType : Attr {
   let Spellings = [GNU<"ext_vector_type">];
+  let Subjects = SubjectList<[TypedefName], ErrorDiag>;
   let Args = [ExprArgument<"NumElements">];
   let ASTNode = 0;
+  let Documentation = [Undocumented];
 }
 
 def FallThrough : Attr {
   let Spellings = [CXX11<"clang", "fallthrough">];
-  let Subjects = [NullStmt];
+//  let Subjects = [NullStmt];
+  let Documentation = [FallthroughDocs];
 }
 
 def FastCall : InheritableAttr {
-  let Spellings = [GNU<"fastcall">, CXX11<"gnu", "fastcall">,
-                   Keyword<"__fastcall">, Keyword<"_fastcall">];
+  let Spellings = [GCC<"fastcall">, Keyword<"__fastcall">,
+                   Keyword<"_fastcall">];
+//  let Subjects = [Function, ObjCMethod];
+  let Documentation = [Undocumented];
 }
 
 def Final : InheritableAttr {
   let Spellings = [Keyword<"final">, Keyword<"sealed">];
   let Accessors = [Accessor<"isSpelledAsSealed", [Keyword<"sealed">]>];
   let SemaHandler = 0;
+  let Documentation = [Undocumented];
 }
 
 def MinSize : InheritableAttr {
   let Spellings = [GNU<"minsize">];
-  let Subjects = [Function];
+  let Subjects = SubjectList<[Function, ObjCMethod], ErrorDiag>;
+  let Documentation = [Undocumented];
+}
+
+def Flatten : InheritableAttr {
+  let Spellings = [GCC<"flatten">];
+  let Subjects = SubjectList<[Function], ErrorDiag>;
+  let Documentation = [FlattenDocs];
 }
 
 def Format : InheritableAttr {
-  let Spellings = [GNU<"format">, CXX11<"gnu", "format">];
+  let Spellings = [GCC<"format">];
   let Args = [IdentifierArgument<"Type">, IntArgument<"FormatIdx">,
               IntArgument<"FirstArg">];
+  let Subjects = SubjectList<[ObjCMethod, Block, HasFunctionProto], WarnDiag,
+                             "ExpectedFunction">;
+  let Documentation = [FormatDocs];
 }
 
 def FormatArg : InheritableAttr {
-  let Spellings = [GNU<"format_arg">, CXX11<"gnu", "format_arg">];
+  let Spellings = [GCC<"format_arg">];
   let Args = [IntArgument<"FormatIdx">];
+  let Subjects = SubjectList<[ObjCMethod, HasFunctionProto], WarnDiag,
+                             "ExpectedFunction">;
+  let Documentation = [Undocumented];
 }
 
 def GNUInline : InheritableAttr {
-  let Spellings = [GNU<"gnu_inline">, CXX11<"gnu", "gnu_inline">];
+  let Spellings = [GCC<"gnu_inline">];
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [Undocumented];
 }
 
 def Hot : InheritableAttr {
-  let Spellings = [GNU<"hot">, CXX11<"gnu", "hot">];
+  let Spellings = [GCC<"hot">];
+  let Subjects = SubjectList<[Function]>;
+  // An AST node is created for this attribute, but not actually used beyond
+  // semantic checking for mutual exclusion with the Cold attribute.
+  let Documentation = [Undocumented];
 }
 
 def IBAction : InheritableAttr {
   let Spellings = [GNU<"ibaction">];
+  let Subjects = SubjectList<[ObjCInstanceMethod], WarnDiag,
+                             "ExpectedObjCInstanceMethod">;
+  // An AST node is created for this attribute, but is not used by other parts
+  // of the compiler. However, this node needs to exist in the AST because
+  // external tools rely on it.
+  let Documentation = [Undocumented];
 }
 
 def IBOutlet : InheritableAttr {
   let Spellings = [GNU<"iboutlet">];
+//  let Subjects = [ObjCIvar, ObjCProperty];
+  let Documentation = [Undocumented];
 }
 
 def IBOutletCollection : InheritableAttr {
   let Spellings = [GNU<"iboutletcollection">];
   let Args = [TypeArgument<"Interface", 1>];
+//  let Subjects = [ObjCIvar, ObjCProperty];
+  let Documentation = [Undocumented];
 }
 
 def Malloc : InheritableAttr {
-  let Spellings = [GNU<"malloc">, CXX11<"gnu", "malloc">];
+  let Spellings = [GCC<"malloc">];
+//  let Subjects = [Function];
+  let Documentation = [Undocumented];
 }
 
 def MaxFieldAlignment : InheritableAttr {
+  // This attribute has no spellings as it is only ever created implicitly.
   let Spellings = [];
   let Args = [UnsignedArgument<"Alignment">];
   let SemaHandler = 0;
+  let Documentation = [Undocumented];
 }
 
 def MayAlias : InheritableAttr {
-  let Spellings = [GNU<"may_alias">, CXX11<"gnu", "may_alias">];
+  // FIXME: this is a type attribute in GCC, but a declaration attribute here.
+  let Spellings = [GCC<"may_alias">];
+  let Documentation = [Undocumented];
 }
 
 def MSABI : InheritableAttr {
-  let Spellings = [GNU<"ms_abi">, CXX11<"gnu", "ms_abi">];
+  let Spellings = [GCC<"ms_abi">];
+//  let Subjects = [Function, ObjCMethod];
+  let Documentation = [Undocumented];
 }
 
-def MSP430Interrupt : InheritableAttr, TargetSpecificAttr {
-  let Spellings = [];
+def MSP430Interrupt : InheritableAttr, TargetSpecificAttr<TargetMSP430> {
+  // NOTE: If you add any additional spellings, ARMInterrupt's spellings must
+  // match.
+  let Spellings = [GNU<"interrupt">];
   let Args = [UnsignedArgument<"Number">];
-  let SemaHandler = 0;
+  let ParseKind = "Interrupt";
+  let HasCustomParsing = 1;
+  let Documentation = [Undocumented];
 }
 
-def Mips16 : InheritableAttr, TargetSpecificAttr {
-  let Spellings = [GNU<"mips16">, CXX11<"gnu", "mips16">];
-  let Subjects = [Function];
+def Mips16 : InheritableAttr, TargetSpecificAttr<TargetMips> {
+  let Spellings = [GCC<"mips16">];
+  let Subjects = SubjectList<[Function], ErrorDiag>;
+  let Documentation = [Undocumented];
 }
 
 def Mode : Attr {
-  let Spellings = [GNU<"mode">, CXX11<"gnu", "mode">];
+  let Spellings = [GCC<"mode">];
   let Args = [IdentifierArgument<"Mode">];
+  let Documentation = [Undocumented];
 }
 
 def Naked : InheritableAttr {
-  let Spellings = [GNU<"naked">, CXX11<"gnu", "naked">];
+  let Spellings = [GCC<"naked">, Declspec<"naked">];
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [Undocumented];
 }
 
 def NeonPolyVectorType : TypeAttr {
   let Spellings = [GNU<"neon_polyvector_type">];
   let Args = [IntArgument<"NumElements">];
+  let Documentation = [Undocumented];
 }
 
 def NeonVectorType : TypeAttr {
   let Spellings = [GNU<"neon_vector_type">];
   let Args = [IntArgument<"NumElements">];
+  let Documentation = [Undocumented];
 }
 
 def ReturnsTwice : InheritableAttr {
-  let Spellings = [GNU<"returns_twice">, CXX11<"gnu", "returns_twice">];
+  let Spellings = [GCC<"returns_twice">];
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [Undocumented];
 }
 
 def NoCommon : InheritableAttr {
-  let Spellings = [GNU<"nocommon">, CXX11<"gnu", "nocommon">];
+  let Spellings = [GCC<"nocommon">];
+  let Subjects = SubjectList<[Var]>;
+  let Documentation = [Undocumented];
 }
 
 def NoDebug : InheritableAttr {
   let Spellings = [GNU<"nodebug">];
+  let Documentation = [Undocumented];
+}
+
+def NoDuplicate : InheritableAttr {
+  let Spellings = [GNU<"noduplicate">, CXX11<"clang", "noduplicate">];
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [NoDuplicateDocs];
 }
 
 def NoInline : InheritableAttr {
-  let Spellings = [GNU<"noinline">, CXX11<"gnu", "noinline">];
+  let Spellings = [GCC<"noinline">, Declspec<"noinline">];
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [Undocumented];
 }
 
-def NoMips16 : InheritableAttr, TargetSpecificAttr {
-  let Spellings = [GNU<"nomips16">, CXX11<"gnu", "nomips16">];
-  let Subjects = [Function];
+def NoMips16 : InheritableAttr, TargetSpecificAttr<TargetMips> {
+  let Spellings = [GCC<"nomips16">];
+  let Subjects = SubjectList<[Function], ErrorDiag>;
+  let Documentation = [Undocumented];
+}
+
+def NoSplitStack : InheritableAttr {
+  let Spellings = [GCC<"no_split_stack">];
+  let Subjects = SubjectList<[Function], ErrorDiag>;
+  let Documentation = [NoSplitStackDocs];
 }
 
 def NonNull : InheritableAttr {
-  let Spellings = [GNU<"nonnull">, CXX11<"gnu", "nonnull">];
+  let Spellings = [GCC<"nonnull">];
+  let Subjects = SubjectList<[ObjCMethod, HasFunctionProto, ParmVar], WarnDiag,
+                             "ExpectedFunctionMethodOrParameter">;
   let Args = [VariadicUnsignedArgument<"Args">];
   let AdditionalMembers =
 [{bool isNonNull(unsigned idx) const {
-    for (args_iterator i = args_begin(), e = args_end();
-         i != e; ++i)
-      if (*i == idx)
+    for (const auto &V : args())
+      if (V == idx)
         return true;
     return false;
   } }];
+  let Documentation = [Undocumented];
+}
+
+def ReturnsNonNull : InheritableAttr {
+  let Spellings = [GCC<"returns_nonnull">];
+  let Subjects = SubjectList<[ObjCMethod, Function], WarnDiag,
+                             "ExpectedFunctionOrMethod">;
+  let Documentation = [Undocumented];
 }
 
 def NoReturn : InheritableAttr {
-  let Spellings = [GNU<"noreturn">, CXX11<"gnu", "noreturn">];
+  let Spellings = [GCC<"noreturn">, Declspec<"noreturn">];
   // FIXME: Does GCC allow this on the function instead?
-  let Subjects = [Function];
+  let Documentation = [Undocumented];
 }
 
 def NoInstrumentFunction : InheritableAttr {
-  let Spellings = [GNU<"no_instrument_function">,
-                   CXX11<"gnu", "no_instrument_function">];
-  let Subjects = [Function];
+  let Spellings = [GCC<"no_instrument_function">];
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [Undocumented];
 }
 
 def NoThrow : InheritableAttr {
-  let Spellings = [GNU<"nothrow">, CXX11<"gnu", "nothrow">];
-}
-
-def NSBridged : InheritableAttr {
-  let Spellings = [GNU<"ns_bridged">];
-  let Subjects = [Record];
-  let Args = [IdentifierArgument<"BridgedType", 1>];
+  let Spellings = [GCC<"nothrow">, Declspec<"nothrow">];
+  let Documentation = [Undocumented];
 }
 
 def ObjCBridge : InheritableAttr {
   let Spellings = [GNU<"objc_bridge">];
-  let Subjects = [Record];
-  let Args = [IdentifierArgument<"BridgedType", 1>];
+  let Subjects = SubjectList<[Record], ErrorDiag>;
+  let Args = [IdentifierArgument<"BridgedType">];
+  let Documentation = [Undocumented];
+}
+
+def ObjCBridgeMutable : InheritableAttr {
+  let Spellings = [GNU<"objc_bridge_mutable">];
+  let Subjects = SubjectList<[Record], ErrorDiag>;
+  let Args = [IdentifierArgument<"BridgedType">];
+  let Documentation = [Undocumented];
+}
+
+def ObjCBridgeRelated : InheritableAttr {
+  let Spellings = [GNU<"objc_bridge_related">];
+  let Subjects = SubjectList<[Record], ErrorDiag>;
+  let Args = [IdentifierArgument<"RelatedClass">,
+          IdentifierArgument<"ClassMethod">,
+          IdentifierArgument<"InstanceMethod">];
+  let HasCustomParsing = 1;
+  let Documentation = [Undocumented];
 }
 
 def NSReturnsRetained : InheritableAttr {
   let Spellings = [GNU<"ns_returns_retained">];
-  let Subjects = [ObjCMethod, Function];
+//  let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
+  let Documentation = [Undocumented];
 }
 
 def NSReturnsNotRetained : InheritableAttr {
   let Spellings = [GNU<"ns_returns_not_retained">];
-  let Subjects = [ObjCMethod, Function];
+//  let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
+  let Documentation = [Undocumented];
 }
 
 def NSReturnsAutoreleased : InheritableAttr {
   let Spellings = [GNU<"ns_returns_autoreleased">];
-  let Subjects = [ObjCMethod, Function];
+//  let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
+  let Documentation = [Undocumented];
 }
 
 def NSConsumesSelf : InheritableAttr {
   let Spellings = [GNU<"ns_consumes_self">];
-  let Subjects = [ObjCMethod];
+  let Subjects = SubjectList<[ObjCMethod]>;
+  let Documentation = [Undocumented];
 }
 
 def NSConsumed : InheritableParamAttr {
   let Spellings = [GNU<"ns_consumed">];
-  let Subjects = [ParmVar];
+  let Subjects = SubjectList<[ParmVar]>;
+  let Documentation = [Undocumented];
 }
 
 def ObjCException : InheritableAttr {
   let Spellings = [GNU<"objc_exception">];
+  let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
+  let Documentation = [Undocumented];
 }
 
 def ObjCMethodFamily : InheritableAttr {
   let Spellings = [GNU<"objc_method_family">];
-  let Subjects = [ObjCMethod];
+  let Subjects = SubjectList<[ObjCMethod], ErrorDiag>;
   let Args = [EnumArgument<"Family", "FamilyKind",
                ["none", "alloc", "copy", "init", "mutableCopy", "new"],
                ["OMF_None", "OMF_alloc", "OMF_copy", "OMF_init",
                 "OMF_mutableCopy", "OMF_new"]>];
+  let Documentation = [ObjCMethodFamilyDocs];
 }
 
 def ObjCNSObject : InheritableAttr {
   let Spellings = [GNU<"NSObject">];
+  let Documentation = [Undocumented];
 }
 
 def ObjCPreciseLifetime : InheritableAttr {
   let Spellings = [GNU<"objc_precise_lifetime">];
-  let Subjects = [Var];
+  let Subjects = SubjectList<[Var], ErrorDiag>;
+  let Documentation = [Undocumented];
 }
 
 def ObjCReturnsInnerPointer : InheritableAttr {
   let Spellings = [GNU<"objc_returns_inner_pointer">];
-  let Subjects = [ObjCMethod, ObjCProperty];
+  let Subjects = SubjectList<[ObjCMethod, ObjCProperty], ErrorDiag>;
+  let Documentation = [Undocumented];
 }
 
 def ObjCRequiresSuper : InheritableAttr {
   let Spellings = [GNU<"objc_requires_super">];
-  let Subjects = [ObjCMethod];
+  let Subjects = SubjectList<[ObjCMethod], ErrorDiag>;
+  let Documentation = [ObjCRequiresSuperDocs];
 }
 
 def ObjCRootClass : InheritableAttr {
   let Spellings = [GNU<"objc_root_class">];
-  let Subjects = [ObjCInterface];
+  let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
+  let Documentation = [Undocumented];
+}
+
+def ObjCExplicitProtocolImpl : InheritableAttr {
+  let Spellings = [GNU<"objc_protocol_requires_explicit_implementation">];
+  let Subjects = SubjectList<[ObjCProtocol], ErrorDiag>;
+  let Documentation = [Undocumented];
+}
+
+def ObjCDesignatedInitializer : Attr {
+  let Spellings = [GNU<"objc_designated_initializer">];
+  let Subjects = SubjectList<[ObjCInterfaceDeclInitMethod], ErrorDiag,
+                             "ExpectedObjCInterfaceDeclInitMethod">;
+  let Documentation = [Undocumented];
+}
+
+def ObjCRuntimeName : Attr {
+  let Spellings = [GNU<"objc_runtime_name">];
+  let Subjects = SubjectList<[ObjCInterface, ObjCProtocol], ErrorDiag>;
+  let Args = [StringArgument<"MetadataName">];
+  let Documentation = [ObjCRuntimeNameDocs];
+}
+
+def OptimizeNone : InheritableAttr {
+  let Spellings = [GNU<"optnone">, CXX11<"clang", "optnone">];
+  let Subjects = SubjectList<[Function, ObjCMethod]>;
+  let Documentation = [OptnoneDocs];
 }
 
 def Overloadable : Attr {
   let Spellings = [GNU<"overloadable">];
+  let Subjects = SubjectList<[Function], ErrorDiag>;
+  let Documentation = [OverloadableDocs];
 }
 
 def Override : InheritableAttr { 
-  let Spellings = [];
+  let Spellings = [Keyword<"override">];
   let SemaHandler = 0;
+  let Documentation = [Undocumented];
 }
 
 def Ownership : InheritableAttr {
   let Spellings = [GNU<"ownership_holds">, GNU<"ownership_returns">,
                    GNU<"ownership_takes">];
-  let DistinctSpellings = 1;
-  let Args = [EnumArgument<"OwnKind", "OwnershipKind",
-                    ["ownership_holds", "ownership_returns", "ownership_takes"],
-                    ["Holds", "Returns", "Takes"]>,
-              StringArgument<"Module">, VariadicUnsignedArgument<"Args">];
-  let HasCustomParsing = 1;
+  let Accessors = [Accessor<"isHolds", [GNU<"ownership_holds">]>,
+                   Accessor<"isReturns", [GNU<"ownership_returns">]>,
+                   Accessor<"isTakes", [GNU<"ownership_takes">]>];
+  let AdditionalMembers = [{
+    enum OwnershipKind { Holds, Returns, Takes };
+    OwnershipKind getOwnKind() const {
+      return isHolds() ? Holds :
+             isTakes() ? Takes :
+             Returns;
+    }
+  }];
+  let Args = [IdentifierArgument<"Module">, VariadicUnsignedArgument<"Args">];
+  let Subjects = SubjectList<[HasFunctionProto], WarnDiag, "ExpectedFunction">;
+  let Documentation = [Undocumented];
 }
 
 def Packed : InheritableAttr {
-  let Spellings = [GNU<"packed">, CXX11<"gnu", "packed">];
+  let Spellings = [GCC<"packed">];
+//  let Subjects = [Tag, Field];
+  let Documentation = [Undocumented];
 }
 
 def PnaclCall : InheritableAttr {
   let Spellings = [GNU<"pnaclcall">];
+//  let Subjects = [Function, ObjCMethod];
+  let Documentation = [Undocumented];
 }
 
 def IntelOclBicc : InheritableAttr {
   let Spellings = [GNU<"intel_ocl_bicc">];
+//  let Subjects = [Function, ObjCMethod];
+  let Documentation = [Undocumented];
 }
 
 def Pcs : InheritableAttr {
-  let Spellings = [GNU<"pcs">, CXX11<"gnu", "pcs">];
+  let Spellings = [GCC<"pcs">];
   let Args = [EnumArgument<"PCS", "PCSType",
                            ["aapcs", "aapcs-vfp"],
                            ["AAPCS", "AAPCS_VFP"]>];
+//  let Subjects = [Function, ObjCMethod];
+  let Documentation = [PcsDocs];
 }
 
 def Pure : InheritableAttr {
-  let Spellings = [GNU<"pure">, CXX11<"gnu", "pure">];
+  let Spellings = [GCC<"pure">];
+  let Documentation = [Undocumented];
 }
 
-def Regparm : InheritableAttr {
-  let Spellings = [GNU<"regparm">, CXX11<"gnu", "regparm">];
+def Regparm : TypeAttr {
+  let Spellings = [GCC<"regparm">];
   let Args = [UnsignedArgument<"NumParams">];
+  let Documentation = [Undocumented];
 }
 
 def ReqdWorkGroupSize : InheritableAttr {
   let Spellings = [GNU<"reqd_work_group_size">];
   let Args = [UnsignedArgument<"XDim">, UnsignedArgument<"YDim">,
               UnsignedArgument<"ZDim">];
+  let Subjects = SubjectList<[Function], ErrorDiag>;
+  let Documentation = [Undocumented];
 }
 
 def WorkGroupSizeHint :  InheritableAttr {
@@ -669,102 +1084,137 @@
   let Args = [UnsignedArgument<"XDim">, 
               UnsignedArgument<"YDim">,
               UnsignedArgument<"ZDim">];
+  let Subjects = SubjectList<[Function], ErrorDiag>;
+  let Documentation = [Undocumented];
 }
 
 def InitPriority : InheritableAttr {
   let Spellings = [GNU<"init_priority">];
   let Args = [UnsignedArgument<"Priority">];
+  let Subjects = SubjectList<[Var], ErrorDiag>;
+  let Documentation = [Undocumented];
 }
 
 def Section : InheritableAttr {
-  let Spellings = [GNU<"section">, CXX11<"gnu", "section">];
+  let Spellings = [GCC<"section">, Declspec<"allocate">];
   let Args = [StringArgument<"Name">];
+  let Subjects = SubjectList<[Function, GlobalVar,
+                              ObjCMethod, ObjCProperty], ErrorDiag,
+                             "ExpectedFunctionGlobalVarMethodOrProperty">;
+  let Documentation = [SectionDocs];
 }
 
 def Sentinel : InheritableAttr {
-  let Spellings = [GNU<"sentinel">, CXX11<"gnu", "sentinel">];
+  let Spellings = [GCC<"sentinel">];
   let Args = [DefaultIntArgument<"Sentinel", 0>,
               DefaultIntArgument<"NullPos", 0>];
+//  let Subjects = SubjectList<[Function, ObjCMethod, Block, Var]>;
+  let Documentation = [Undocumented];
 }
 
 def StdCall : InheritableAttr {
-  let Spellings = [GNU<"stdcall">, CXX11<"gnu", "stdcall">,
-                   Keyword<"__stdcall">, Keyword<"_stdcall">];
+  let Spellings = [GCC<"stdcall">, Keyword<"__stdcall">, Keyword<"_stdcall">];
+//  let Subjects = [Function, ObjCMethod];
+  let Documentation = [Undocumented];
 }
 
 def SysVABI : InheritableAttr {
-  let Spellings = [GNU<"sysv_abi">, CXX11<"gnu", "sysv_abi">];
+  let Spellings = [GCC<"sysv_abi">];
+//  let Subjects = [Function, ObjCMethod];
+  let Documentation = [Undocumented];
 }
 
 def ThisCall : InheritableAttr {
-  let Spellings = [GNU<"thiscall">, CXX11<"gnu", "thiscall">,
-                   Keyword<"__thiscall">, Keyword<"_thiscall">];
+  let Spellings = [GCC<"thiscall">, Keyword<"__thiscall">,
+                   Keyword<"_thiscall">];
+//  let Subjects = [Function, ObjCMethod];
+  let Documentation = [Undocumented];
 }
 
 def Pascal : InheritableAttr {
   let Spellings = [GNU<"pascal">, Keyword<"__pascal">, Keyword<"_pascal">];
+//  let Subjects = [Function, ObjCMethod];
+  let Documentation = [Undocumented];
 }
 
 def TransparentUnion : InheritableAttr {
-  let Spellings = [GNU<"transparent_union">, CXX11<"gnu", "transparent_union">];
+  let Spellings = [GCC<"transparent_union">];
+//  let Subjects = SubjectList<[Record, TypedefName]>;
+  let Documentation = [Undocumented];
 }
 
 def Unavailable : InheritableAttr {
   let Spellings = [GNU<"unavailable">];
   let Args = [StringArgument<"Message", 1>];
+  let Documentation = [Undocumented];
 }
 
 def ArcWeakrefUnavailable : InheritableAttr {
   let Spellings = [GNU<"objc_arc_weak_reference_unavailable">];
-  let Subjects = [ObjCInterface];
+  let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
+  let Documentation = [Undocumented];
 }
 
 def ObjCGC : TypeAttr {
   let Spellings = [GNU<"objc_gc">];
   let Args = [IdentifierArgument<"Kind">];
+  let Documentation = [Undocumented];
 }
 
 def ObjCOwnership : InheritableAttr {
   let Spellings = [GNU<"objc_ownership">];
   let Args = [IdentifierArgument<"Kind">];
   let ASTNode = 0;
+  let Documentation = [Undocumented];
 }
 
 def ObjCRequiresPropertyDefs : InheritableAttr {
   let Spellings = [GNU<"objc_requires_property_definitions">];
-  let Subjects = [ObjCInterface];
+  let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
+  let Documentation = [Undocumented];
 }
 
 def Unused : InheritableAttr {
-  let Spellings = [GNU<"unused">, CXX11<"gnu", "unused">];
+  let Spellings = [GCC<"unused">];
+  let Subjects = SubjectList<[Var, ObjCIvar, Type, Label, Field, ObjCMethod,
+                              FunctionLike], WarnDiag,
+                             "ExpectedVariableFunctionOrLabel">;
+  let Documentation = [Undocumented];
 }
 
 def Used : InheritableAttr {
-  let Spellings = [GNU<"used">, CXX11<"gnu", "used">];
+  let Spellings = [GCC<"used">];
+  let Documentation = [Undocumented];
 }
 
 def Uuid : InheritableAttr {
-  let Spellings = [GNU<"uuid">];
+  let Spellings = [Declspec<"uuid">];
   let Args = [StringArgument<"Guid">];
-  let Subjects = [CXXRecord];
+//  let Subjects = SubjectList<[CXXRecord]>;
+  let LangOpts = [MicrosoftExt, Borland];
+  let Documentation = [Undocumented];
 }
 
 def VectorSize : TypeAttr {
-  let Spellings = [GNU<"vector_size">, CXX11<"gnu", "vector_size">];
+  let Spellings = [GCC<"vector_size">];
   let Args = [ExprArgument<"NumBytes">];
+  let Documentation = [Undocumented];
 }
 
 def VecTypeHint : InheritableAttr {
   let Spellings = [GNU<"vec_type_hint">];
   let Args = [TypeArgument<"TypeHint">];
+  let Subjects = SubjectList<[Function], ErrorDiag>;
+  let Documentation = [Undocumented];
 }
 
 def Visibility : InheritableAttr {
   let Clone = 0;
-  let Spellings = [GNU<"visibility">, CXX11<"gnu", "visibility">];
+  let Spellings = [GCC<"visibility">];
   let Args = [EnumArgument<"Visibility", "VisibilityType",
                            ["default", "hidden", "internal", "protected"],
                            ["Default", "Hidden", "Hidden", "Protected"]>];
+  let Documentation = [Undocumented];
 }
 
 def TypeVisibility : InheritableAttr {
@@ -773,80 +1223,227 @@
   let Args = [EnumArgument<"Visibility", "VisibilityType",
                            ["default", "hidden", "internal", "protected"],
                            ["Default", "Hidden", "Hidden", "Protected"]>];
+//  let Subjects = [Tag, ObjCInterface, Namespace];
+  let Documentation = [Undocumented];
 }
 
 def VecReturn : InheritableAttr {
   let Spellings = [GNU<"vecreturn">];
-  let Subjects = [CXXRecord];
+  let Subjects = SubjectList<[CXXRecord], ErrorDiag>;
+  let Documentation = [Undocumented];
 }
 
 def WarnUnused : InheritableAttr {
   let Spellings = [GNU<"warn_unused">];
-  let Subjects = [Record];
+  let Subjects = SubjectList<[Record]>;
+  let Documentation = [Undocumented];
 }
 
 def WarnUnusedResult : InheritableAttr {
-  let Spellings = [GNU<"warn_unused_result">,
-                   CXX11<"clang", "warn_unused_result">,
-                   CXX11<"gnu", "warn_unused_result">];
+  let Spellings = [GCC<"warn_unused_result">,
+                   CXX11<"clang", "warn_unused_result">];
+  let Subjects = SubjectList<[ObjCMethod, CXXRecord, FunctionLike], WarnDiag,
+                             "ExpectedFunctionMethodOrClass">;
+  let Documentation = [Undocumented];
 }
 
 def Weak : InheritableAttr {
-  let Spellings = [GNU<"weak">, CXX11<"gnu", "weak">];
+  let Spellings = [GCC<"weak">];
+  let Subjects = SubjectList<[Var, Function, CXXRecord]>;
+  let Documentation = [Undocumented];
 }
 
 def WeakImport : InheritableAttr {
   let Spellings = [GNU<"weak_import">];
+  let Documentation = [Undocumented];
 }
 
 def WeakRef : InheritableAttr {
-  let Spellings = [GNU<"weakref">, CXX11<"gnu", "weakref">];
+  let Spellings = [GCC<"weakref">];
   // A WeakRef that has an argument is treated as being an AliasAttr
   let Args = [StringArgument<"Aliasee", 1>];
+  let Subjects = SubjectList<[Var, Function], ErrorDiag>;
+  let Documentation = [Undocumented];
 }
 
-def X86ForceAlignArgPointer : InheritableAttr, TargetSpecificAttr {
-  let Spellings = [];
+def X86ForceAlignArgPointer : InheritableAttr, TargetSpecificAttr<TargetX86> {
+  let Spellings = [GNU<"force_align_arg_pointer">];
+  // Technically, this appertains to a FunctionDecl, but the target-specific
+  // code silently allows anything function-like (such as typedefs or function
+  // pointers), but does not apply the attribute to them.
+  let Documentation = [Undocumented];
 }
 
 // Attribute to disable AddressSanitizer (or equivalent) checks.
 def NoSanitizeAddress : InheritableAttr {
-  let Spellings = [GNU<"no_address_safety_analysis">,
-                   GNU<"no_sanitize_address">,
-                   CXX11<"gnu", "no_address_safety_analysis">,
-                   CXX11<"gnu", "no_sanitize_address">];
+  let Spellings = [GCC<"no_address_safety_analysis">,
+                   GCC<"no_sanitize_address">];
+  let Subjects = SubjectList<[Function], ErrorDiag>;
+  let Documentation = [NoSanitizeAddressDocs];
 }
 
 // Attribute to disable ThreadSanitizer checks.
 def NoSanitizeThread : InheritableAttr {
   let Spellings = [GNU<"no_sanitize_thread">];
+  let Subjects = SubjectList<[Function], ErrorDiag>;
+  let Documentation = [NoSanitizeThreadDocs];
 }
 
 // Attribute to disable MemorySanitizer checks.
 def NoSanitizeMemory : InheritableAttr {
   let Spellings = [GNU<"no_sanitize_memory">];
+  let Subjects = SubjectList<[Function], ErrorDiag>;
+  let Documentation = [NoSanitizeMemoryDocs];
 }
 
 // C/C++ Thread safety attributes (e.g. for deadlock, data race checking)
 
 def GuardedVar : InheritableAttr {
   let Spellings = [GNU<"guarded_var">];
+  let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
+                             "ExpectedFieldOrGlobalVar">;
+  let Documentation = [Undocumented];
 }
 
 def PtGuardedVar : InheritableAttr {
   let Spellings = [GNU<"pt_guarded_var">];
+  let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
+                             "ExpectedFieldOrGlobalVar">;
+  let Documentation = [Undocumented];
 }
 
 def Lockable : InheritableAttr {
   let Spellings = [GNU<"lockable">];
+  let Subjects = SubjectList<[Record]>;
+  let Documentation = [Undocumented];
+  let ASTNode = 0;  // Replaced by Capability
 }
 
 def ScopedLockable : InheritableAttr {
   let Spellings = [GNU<"scoped_lockable">];
+  let Subjects = SubjectList<[Record]>;
+  let Documentation = [Undocumented];
+}
+
+def Capability : InheritableAttr {
+  let Spellings = [GNU<"capability">, CXX11<"clang", "capability">,
+                   GNU<"shared_capability">,
+                   CXX11<"clang", "shared_capability">];
+  let Subjects = SubjectList<[Struct, TypedefName], ErrorDiag,
+                             "ExpectedStructOrTypedef">;
+  let Args = [StringArgument<"Name">];
+  let Accessors = [Accessor<"isShared",
+                    [GNU<"shared_capability">,
+                     CXX11<"clang","shared_capability">]>];
+  let Documentation = [Undocumented];
+  let AdditionalMembers = [{
+    bool isMutex() const { return getName().equals_lower("mutex"); }
+    bool isRole() const { return getName().equals_lower("role"); }
+  }];
+}
+
+def AssertCapability : InheritableAttr {
+  let Spellings = [GNU<"assert_capability">,
+                   CXX11<"clang", "assert_capability">,
+                   GNU<"assert_shared_capability">,
+                   CXX11<"clang", "assert_shared_capability">];
+  let Subjects = SubjectList<[Function]>;
+  let LateParsed = 1;
+  let TemplateDependent = 1;
+  let ParseArgumentsAsUnevaluated = 1;
+  let DuplicatesAllowedWhileMerging = 1;
+  let Args = [ExprArgument<"Expr">];
+  let Accessors = [Accessor<"isShared",
+                    [GNU<"assert_shared_capability">,
+                     CXX11<"clang", "assert_shared_capability">]>];
+  let Documentation = [AssertCapabilityDocs];
+}
+
+def AcquireCapability : InheritableAttr {
+  let Spellings = [GNU<"acquire_capability">,
+                   CXX11<"clang", "acquire_capability">,
+                   GNU<"acquire_shared_capability">,
+                   CXX11<"clang", "acquire_shared_capability">,
+                   GNU<"exclusive_lock_function">,
+                   GNU<"shared_lock_function">];
+  let Subjects = SubjectList<[Function]>;
+  let LateParsed = 1;
+  let TemplateDependent = 1;
+  let ParseArgumentsAsUnevaluated = 1;
+  let DuplicatesAllowedWhileMerging = 1;
+  let Args = [VariadicExprArgument<"Args">];
+  let Accessors = [Accessor<"isShared",
+                    [GNU<"acquire_shared_capability">,
+                     CXX11<"clang", "acquire_shared_capability">,
+                     GNU<"shared_lock_function">]>];
+  let Documentation = [AcquireCapabilityDocs];
+}
+
+def TryAcquireCapability : InheritableAttr {
+  let Spellings = [GNU<"try_acquire_capability">,
+                   CXX11<"clang", "try_acquire_capability">,
+                   GNU<"try_acquire_shared_capability">,
+                   CXX11<"clang", "try_acquire_shared_capability">];
+  let Subjects = SubjectList<[Function],
+                             ErrorDiag>;
+  let LateParsed = 1;
+  let TemplateDependent = 1;
+  let ParseArgumentsAsUnevaluated = 1;
+  let DuplicatesAllowedWhileMerging = 1;
+  let Args = [ExprArgument<"SuccessValue">, VariadicExprArgument<"Args">];
+  let Accessors = [Accessor<"isShared",
+                    [GNU<"try_acquire_shared_capability">,
+                     CXX11<"clang", "try_acquire_shared_capability">]>];
+  let Documentation = [TryAcquireCapabilityDocs];
+}
+
+def ReleaseCapability : InheritableAttr {
+  let Spellings = [GNU<"release_capability">,
+                   CXX11<"clang", "release_capability">,
+                   GNU<"release_shared_capability">,
+                   CXX11<"clang", "release_shared_capability">,
+                   GNU<"release_generic_capability">,
+                   CXX11<"clang", "release_generic_capability">,
+                   GNU<"unlock_function">];
+  let Subjects = SubjectList<[Function]>;
+  let LateParsed = 1;
+  let TemplateDependent = 1;
+  let ParseArgumentsAsUnevaluated = 1;
+  let DuplicatesAllowedWhileMerging = 1;
+  let Args = [VariadicExprArgument<"Args">];
+  let Accessors = [Accessor<"isShared",
+                    [GNU<"release_shared_capability">,
+                     CXX11<"clang", "release_shared_capability">]>,
+                   Accessor<"isGeneric",
+                     [GNU<"release_generic_capability">,
+                      CXX11<"clang", "release_generic_capability">,
+                      GNU<"unlock_function">]>];
+  let Documentation = [ReleaseCapabilityDocs];
+}
+
+def RequiresCapability : InheritableAttr {
+  let Spellings = [GNU<"requires_capability">,
+                   CXX11<"clang", "requires_capability">,
+                   GNU<"exclusive_locks_required">,
+                   GNU<"requires_shared_capability">,
+                   CXX11<"clang", "requires_shared_capability">,
+                   GNU<"shared_locks_required">];
+  let Args = [VariadicExprArgument<"Args">];
+  let LateParsed = 1;
+  let TemplateDependent = 1;
+  let ParseArgumentsAsUnevaluated = 1;
+  let DuplicatesAllowedWhileMerging = 1;
+  let Subjects = SubjectList<[Function]>;
+  let Accessors = [Accessor<"isShared", [GNU<"requires_shared_capability">,
+                                         GNU<"shared_locks_required">,
+                                CXX11<"clang","requires_shared_capability">]>];
+  let Documentation = [Undocumented];
 }
 
 def NoThreadSafetyAnalysis : InheritableAttr {
   let Spellings = [GNU<"no_thread_safety_analysis">];
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [Undocumented];
 }
 
 def GuardedBy : InheritableAttr {
@@ -854,6 +1451,11 @@
   let Args = [ExprArgument<"Arg">];
   let LateParsed = 1;
   let TemplateDependent = 1;
+  let ParseArgumentsAsUnevaluated = 1;
+  let DuplicatesAllowedWhileMerging = 1;
+  let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
+                             "ExpectedFieldOrGlobalVar">;
+  let Documentation = [Undocumented];
 }
 
 def PtGuardedBy : InheritableAttr {
@@ -861,6 +1463,11 @@
   let Args = [ExprArgument<"Arg">];
   let LateParsed = 1;
   let TemplateDependent = 1;
+  let ParseArgumentsAsUnevaluated = 1;
+  let DuplicatesAllowedWhileMerging = 1;
+  let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
+                             "ExpectedFieldOrGlobalVar">;
+  let Documentation = [Undocumented];
 }
 
 def AcquiredAfter : InheritableAttr {
@@ -868,6 +1475,11 @@
   let Args = [VariadicExprArgument<"Args">];
   let LateParsed = 1;
   let TemplateDependent = 1;
+  let ParseArgumentsAsUnevaluated = 1;
+  let DuplicatesAllowedWhileMerging = 1;
+  let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
+                             "ExpectedFieldOrGlobalVar">;
+  let Documentation = [Undocumented];
 }
 
 def AcquiredBefore : InheritableAttr {
@@ -875,20 +1487,11 @@
   let Args = [VariadicExprArgument<"Args">];
   let LateParsed = 1;
   let TemplateDependent = 1;
-}
-
-def ExclusiveLockFunction : InheritableAttr {
-  let Spellings = [GNU<"exclusive_lock_function">];
-  let Args = [VariadicExprArgument<"Args">];
-  let LateParsed = 1;
-  let TemplateDependent = 1;
-}
-
-def SharedLockFunction : InheritableAttr {
-  let Spellings = [GNU<"shared_lock_function">];
-  let Args = [VariadicExprArgument<"Args">];
-  let LateParsed = 1;
-  let TemplateDependent = 1;
+  let ParseArgumentsAsUnevaluated = 1;
+  let DuplicatesAllowedWhileMerging = 1;
+  let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
+                             "ExpectedFieldOrGlobalVar">;
+  let Documentation = [Undocumented];
 }
 
 def AssertExclusiveLock : InheritableAttr {
@@ -896,6 +1499,10 @@
   let Args = [VariadicExprArgument<"Args">];
   let LateParsed = 1;
   let TemplateDependent = 1;
+  let ParseArgumentsAsUnevaluated = 1;
+  let DuplicatesAllowedWhileMerging = 1;
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [Undocumented];
 }
 
 def AssertSharedLock : InheritableAttr {
@@ -903,6 +1510,10 @@
   let Args = [VariadicExprArgument<"Args">];
   let LateParsed = 1;
   let TemplateDependent = 1;
+  let ParseArgumentsAsUnevaluated = 1;
+  let DuplicatesAllowedWhileMerging = 1;
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [Undocumented];
 }
 
 // The first argument is an integer or boolean value specifying the return value
@@ -912,6 +1523,10 @@
   let Args = [ExprArgument<"SuccessValue">, VariadicExprArgument<"Args">];
   let LateParsed = 1;
   let TemplateDependent = 1;
+  let ParseArgumentsAsUnevaluated = 1;
+  let DuplicatesAllowedWhileMerging = 1;
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [Undocumented];
 }
 
 // The first argument is an integer or boolean value specifying the return value
@@ -921,13 +1536,10 @@
   let Args = [ExprArgument<"SuccessValue">, VariadicExprArgument<"Args">];
   let LateParsed = 1;
   let TemplateDependent = 1;
-}
-
-def UnlockFunction : InheritableAttr {
-  let Spellings = [GNU<"unlock_function">];
-  let Args = [VariadicExprArgument<"Args">];
-  let LateParsed = 1;
-  let TemplateDependent = 1;
+  let ParseArgumentsAsUnevaluated = 1;
+  let DuplicatesAllowedWhileMerging = 1;
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [Undocumented];
 }
 
 def LockReturned : InheritableAttr {
@@ -935,6 +1547,9 @@
   let Args = [ExprArgument<"Arg">];
   let LateParsed = 1;
   let TemplateDependent = 1;
+  let ParseArgumentsAsUnevaluated = 1;
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [Undocumented];
 }
 
 def LocksExcluded : InheritableAttr {
@@ -942,70 +1557,78 @@
   let Args = [VariadicExprArgument<"Args">];
   let LateParsed = 1;
   let TemplateDependent = 1;
-}
-
-def ExclusiveLocksRequired : InheritableAttr {
-  let Spellings = [GNU<"exclusive_locks_required">];
-  let Args = [VariadicExprArgument<"Args">];
-  let LateParsed = 1;
-  let TemplateDependent = 1;
-}
-
-def SharedLocksRequired : InheritableAttr {
-  let Spellings = [GNU<"shared_locks_required">];
-  let Args = [VariadicExprArgument<"Args">];
-  let LateParsed = 1;
-  let TemplateDependent = 1;
+  let ParseArgumentsAsUnevaluated = 1;
+  let DuplicatesAllowedWhileMerging = 1;
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [Undocumented];
 }
 
 // C/C++ consumed attributes.
 
 def Consumable : InheritableAttr {
   let Spellings = [GNU<"consumable">];
-  let Subjects = [CXXRecord];
+  let Subjects = SubjectList<[CXXRecord]>;
   let Args = [EnumArgument<"DefaultState", "ConsumedState",
                            ["unknown", "consumed", "unconsumed"],
                            ["Unknown", "Consumed", "Unconsumed"]>];
+  let Documentation = [ConsumableDocs];
+}
+
+def ConsumableAutoCast : InheritableAttr {
+  let Spellings = [GNU<"consumable_auto_cast_state">];
+  let Subjects = SubjectList<[CXXRecord]>;
+  let Documentation = [Undocumented];
+}
+
+def ConsumableSetOnRead : InheritableAttr {
+  let Spellings = [GNU<"consumable_set_state_on_read">];
+  let Subjects = SubjectList<[CXXRecord]>;
+  let Documentation = [Undocumented];
 }
 
 def CallableWhen : InheritableAttr {
   let Spellings = [GNU<"callable_when">];
-  let Subjects = [CXXMethod];
-  let Args = [VariadicEnumArgument<"CallableState", "ConsumedState",
+  let Subjects = SubjectList<[CXXMethod]>;
+  let Args = [VariadicEnumArgument<"CallableStates", "ConsumedState",
                                    ["unknown", "consumed", "unconsumed"],
                                    ["Unknown", "Consumed", "Unconsumed"]>];
+  let Documentation = [CallableWhenDocs];
 }
 
 def ParamTypestate : InheritableAttr {
   let Spellings = [GNU<"param_typestate">];
-  let Subjects = [ParmVar];
+  let Subjects = SubjectList<[ParmVar]>;
   let Args = [EnumArgument<"ParamState", "ConsumedState",
                            ["unknown", "consumed", "unconsumed"],
                            ["Unknown", "Consumed", "Unconsumed"]>];
+  let Documentation = [ParamTypestateDocs];
 }
 
 def ReturnTypestate : InheritableAttr {
   let Spellings = [GNU<"return_typestate">];
-  let Subjects = [Function, ParmVar];
+  let Subjects = SubjectList<[Function, ParmVar]>;
   let Args = [EnumArgument<"State", "ConsumedState",
                            ["unknown", "consumed", "unconsumed"],
                            ["Unknown", "Consumed", "Unconsumed"]>];
+  let Documentation = [ReturnTypestateDocs];
 }
 
 def SetTypestate : InheritableAttr {
   let Spellings = [GNU<"set_typestate">];
-  let Subjects = [CXXMethod];
+  let Subjects = SubjectList<[CXXMethod]>;
   let Args = [EnumArgument<"NewState", "ConsumedState",
                            ["unknown", "consumed", "unconsumed"],
                            ["Unknown", "Consumed", "Unconsumed"]>];
+  let Documentation = [SetTypestateDocs];
 }
 
 def TestTypestate : InheritableAttr {
   let Spellings = [GNU<"test_typestate">];
-  let Subjects = [CXXMethod];
+  let Subjects = SubjectList<[CXXMethod]>;
   let Args = [EnumArgument<"TestState", "ConsumedState",
                            ["consumed", "unconsumed"],
                            ["Consumed", "Unconsumed"]>];
+  let Documentation = [TestTypestateDocs];
 }
 
 // Type safety attributes for `void *' pointers and type tags.
@@ -1017,8 +1640,8 @@
               UnsignedArgument<"ArgumentIdx">,
               UnsignedArgument<"TypeTagIdx">,
               BoolArgument<"IsPointer">];
-  let Subjects = [Function];
   let HasCustomParsing = 1;
+  let Documentation = [ArgumentWithTypeTagDocs, PointerWithTypeTagDocs];
 }
 
 def TypeTagForDatatype : InheritableAttr {
@@ -1027,8 +1650,9 @@
               TypeArgument<"MatchingCType">,
               BoolArgument<"LayoutCompatible">,
               BoolArgument<"MustBeNull">];
-  let Subjects = [Var];
+//  let Subjects = SubjectList<[Var], ErrorDiag>;
   let HasCustomParsing = 1;
+  let Documentation = [TypeTagForDatatypeDocs];
 }
 
 // Microsoft-related attributes
@@ -1038,65 +1662,211 @@
 }
 
 def MsStruct : InheritableAttr {
-  let Spellings = [Declspec<"ms_struct">];
+  let Spellings = [GCC<"ms_struct">];
+  let Subjects = SubjectList<[Record]>;
+  let Documentation = [Undocumented];
 }
 
-def DLLExport : InheritableAttr, TargetSpecificAttr {
-  let Spellings = [Declspec<"dllexport">];
+def DLLExport : InheritableAttr, TargetSpecificAttr<TargetWindows> {
+  let Spellings = [Declspec<"dllexport">, GCC<"dllexport">];
+  let Subjects = SubjectList<[Function, Var, CXXRecord]>;
+  let Documentation = [Undocumented];
 }
 
-def DLLImport : InheritableAttr, TargetSpecificAttr {
-  let Spellings = [Declspec<"dllimport">];
-}
-
-def ForceInline : InheritableAttr {
-  let Spellings = [Keyword<"__forceinline">];
+def DLLImport : InheritableAttr, TargetSpecificAttr<TargetWindows> {
+  let Spellings = [Declspec<"dllimport">, GCC<"dllimport">];
+  let Subjects = SubjectList<[Function, Var, CXXRecord]>;
+  let Documentation = [Undocumented];
 }
 
 def SelectAny : InheritableAttr {
   let Spellings = [Declspec<"selectany">];
+  let LangOpts = [MicrosoftExt];
+  let Documentation = [Undocumented];
 }
 
-def Win64 : InheritableAttr {
+def Thread : Attr {
+  let Spellings = [Declspec<"thread">];
+  let LangOpts = [MicrosoftExt];
+  let Documentation = [ThreadDocs];
+  let Subjects = SubjectList<[Var]>;
+}
+
+def Win64 : IgnoredAttr {
   let Spellings = [Keyword<"__w64">];
+  let LangOpts = [MicrosoftExt];
 }
 
 def Ptr32 : TypeAttr {
   let Spellings = [Keyword<"__ptr32">];
+  let Documentation = [Undocumented];
 }
 
 def Ptr64 : TypeAttr {
   let Spellings = [Keyword<"__ptr64">];
+  let Documentation = [Undocumented];
 }
 
 def SPtr : TypeAttr {
   let Spellings = [Keyword<"__sptr">];
+  let Documentation = [Undocumented];
 }
 
 def UPtr : TypeAttr {
   let Spellings = [Keyword<"__uptr">];
+  let Documentation = [Undocumented];
 }
 
-class MSInheritanceAttr : InheritableAttr;
+def MSInheritance : InheritableAttr {
+  let LangOpts = [MicrosoftExt];
+  let Args = [DefaultBoolArgument<"BestCase", 1>];
+  let Spellings = [Keyword<"__single_inheritance">,
+                   Keyword<"__multiple_inheritance">,
+                   Keyword<"__virtual_inheritance">,
+                   Keyword<"__unspecified_inheritance">];
+  let AdditionalMembers = [{
+  static bool hasVBPtrOffsetField(Spelling Inheritance) {
+    return Inheritance == Keyword_unspecified_inheritance;
+  }
 
-def SingleInheritance : MSInheritanceAttr {
-  let Spellings = [Keyword<"__single_inheritance">];
+  // Only member pointers to functions need a this adjustment, since it can be
+  // combined with the field offset for data pointers.
+  static bool hasNVOffsetField(bool IsMemberFunction, Spelling Inheritance) {
+    return IsMemberFunction && Inheritance >= Keyword_multiple_inheritance;
+  }
+
+  static bool hasVBTableOffsetField(Spelling Inheritance) {
+    return Inheritance >= Keyword_virtual_inheritance;
+  }
+
+  static bool hasOnlyOneField(bool IsMemberFunction,
+                              Spelling Inheritance) {
+    if (IsMemberFunction)
+      return Inheritance <= Keyword_single_inheritance;
+    return Inheritance <= Keyword_multiple_inheritance;
+  }
+  }];
+  let Documentation = [MSInheritanceDocs];
 }
 
-def MultipleInheritance : MSInheritanceAttr {
-  let Spellings = [Keyword<"__multiple_inheritance">];
-}
-
-def VirtualInheritance : MSInheritanceAttr {
-  let Spellings = [Keyword<"__virtual_inheritance">];
-}
-
-// This attribute doesn't have any spellings, but we can apply it implicitly to
-// incomplete types that lack any of the other attributes.
-def UnspecifiedInheritance : MSInheritanceAttr {
+def MSVtorDisp : InheritableAttr {
+  // This attribute has no spellings as it is only ever created implicitly.
   let Spellings = [];
+  let Args = [UnsignedArgument<"vdm">];
+  let SemaHandler = 0;
+
+  let AdditionalMembers = [{
+  enum Mode {
+    Never,
+    ForVBaseOverride,
+    ForVFTable
+  };
+
+  Mode getVtorDispMode() const { return Mode(vdm); }
+  }];
+  let Documentation = [Undocumented];
+}
+
+def InitSeg : Attr {
+  let Spellings = [Pragma<"", "init_seg">];
+  let Args = [StringArgument<"Section">];
+  let SemaHandler = 0;
+  let Documentation = [InitSegDocs];
+  let AdditionalMembers = [{
+  void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const {
+    OS << '(' << getSection() << ')';
+  }
+  }];
 }
 
 def Unaligned : IgnoredAttr {
   let Spellings = [Keyword<"__unaligned">];
 }
+
+def LoopHint : Attr {
+  /// vectorize: vectorizes loop operations if 'value != 0'.
+  /// vectorize_width: vectorize loop operations with width 'value'.
+  /// interleave: interleave multiple loop iterations if 'value != 0'.
+  /// interleave_count: interleaves 'value' loop interations.
+  /// unroll: unroll loop if 'value != 0'.
+  /// unroll_count: unrolls loop 'value' times.
+
+  let Spellings = [Pragma<"clang", "loop">, Pragma<"", "unroll">];
+
+  /// State of the loop optimization specified by the spelling.
+  let Args = [EnumArgument<"Option", "OptionType",
+                          ["vectorize", "vectorize_width", "interleave", "interleave_count",
+                           "unroll", "unroll_count"],
+                          ["Vectorize", "VectorizeWidth", "Interleave", "InterleaveCount",
+                           "Unroll", "UnrollCount"]>,
+              DefaultIntArgument<"Value", 1>];
+
+  let AdditionalMembers = [{
+  static StringRef getOptionName(int Option) {
+    switch(Option) {
+    case Vectorize: return "vectorize";
+    case VectorizeWidth: return "vectorize_width";
+    case Interleave: return "interleave";
+    case InterleaveCount: return "interleave_count";
+    case Unroll: return "unroll";
+    case UnrollCount: return "unroll_count";
+    }
+    llvm_unreachable("Unhandled LoopHint option.");
+  }
+
+  static StringRef getValueName(int Value) {
+    if (Value)
+      return "enable";
+    return "disable";
+  }
+
+  void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const {
+    unsigned SpellingIndex = getSpellingListIndex();
+    if (SpellingIndex == Pragma_unroll) {
+      // String "unroll" of "#pragma unroll" is already emitted as the
+      // pragma name.
+      if (option == UnrollCount)
+        printArgument(OS);
+      OS << "\n";
+      return;
+    }
+    assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling");
+    OS << getOptionName(option);
+    printArgument(OS);
+    OS << "\n";
+  }
+
+  // Prints the loop hint argument including the enclosing parentheses to OS.
+  void printArgument(raw_ostream &OS) const {
+    OS << "(";
+    if (option == VectorizeWidth || option == InterleaveCount ||
+        option == UnrollCount)
+      OS << value;
+    else if (value)
+      OS << "enable";
+    else
+      OS << "disable";
+    OS << ")";
+  }
+
+  // Return a string suitable for identifying this attribute in diagnostics.
+  std::string getDiagnosticName() const {
+    std::string DiagnosticName;
+    llvm::raw_string_ostream OS(DiagnosticName);
+    unsigned SpellingIndex = getSpellingListIndex();
+    if (SpellingIndex == Pragma_unroll && option == Unroll)
+      OS << "#pragma unroll";
+    else if (SpellingIndex == Pragma_unroll && option == UnrollCount) {
+      OS << "#pragma unroll";
+      printArgument(OS);
+    } else {
+      assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling");
+      OS << getOptionName(option);
+      printArgument(OS);
+    }
+    return OS.str();
+  }
+  }];
+
+  let Documentation = [LoopHintDocs, UnrollHintDocs];
+}
diff --git a/include/clang/Basic/AttrDocs.td b/include/clang/Basic/AttrDocs.td
new file mode 100644
index 0000000..e6d6a33
--- /dev/null
+++ b/include/clang/Basic/AttrDocs.td
@@ -0,0 +1,1105 @@
+//==--- AttrDocs.td - Attribute 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-attr-docs. Do not edit this file by hand!!
+  -------------------------------------------------------------------
+
+===================
+Attributes in Clang
+===================
+.. contents::
+   :local:
+
+Introduction
+============
+
+This page lists the attributes currently supported by Clang.
+}];
+}
+
+def SectionDocs : Documentation {
+  let Category = DocCatVariable;
+  let Content = [{
+The ``section`` attribute allows you to specify a specific section a
+global variable or function should be in after translation.
+  }];
+  let Heading = "section (gnu::section, __declspec(allocate))";
+}
+
+def InitSegDocs : Documentation {
+  let Category = DocCatVariable;
+  let Content = [{
+The attribute applied by ``pragma init_seg()`` controls the section into
+which global initialization function pointers are emitted.  It is only
+available with ``-fms-extensions``.  Typically, this function pointer is
+emitted into ``.CRT$XCU`` on Windows.  The user can change the order of
+initialization by using a different section name with the same
+``.CRT$XC`` prefix and a suffix that sorts lexicographically before or
+after the standard ``.CRT$XCU`` sections.  See the init_seg_
+documentation on MSDN for more information.
+
+.. _init_seg: http://msdn.microsoft.com/en-us/library/7977wcck(v=vs.110).aspx
+  }];
+}
+
+def TLSModelDocs : Documentation {
+  let Category = DocCatVariable;
+  let Content = [{
+The ``tls_model`` attribute allows you to specify which thread-local storage
+model to use. It accepts the following strings:
+
+* global-dynamic
+* local-dynamic
+* initial-exec
+* local-exec
+
+TLS models are mutually exclusive.
+  }];
+}
+
+def ThreadDocs : Documentation {
+  let Category = DocCatVariable;
+  let Content = [{
+The ``__declspec(thread)`` attribute declares a variable with thread local
+storage.  It is available under the ``-fms-extensions`` flag for MSVC
+compatibility.  Documentation for the Visual C++ attribute is available on MSDN_.
+
+.. _MSDN: http://msdn.microsoft.com/en-us/library/9w1sdazb.aspx
+
+In Clang, ``__declspec(thread)`` is generally equivalent in functionality to the
+GNU ``__thread`` keyword.  The variable must not have a destructor and must have
+a constant initializer, if any.  The attribute only applies to variables
+declared with static storage duration, such as globals, class static data
+members, and static locals.
+  }];
+}
+
+def CarriesDependencyDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+The ``carries_dependency`` attribute specifies dependency propagation into and
+out of functions.
+
+When specified on a function or Objective-C method, the ``carries_dependency``
+attribute means that the return value carries a dependency out of the function, 
+so that the implementation need not constrain ordering upon return from that
+function. Implementations of the function and its caller may choose to preserve
+dependencies instead of emitting memory ordering instructions such as fences.
+
+Note, this attribute does not change the meaning of the program, but may result
+in generation of more efficient code.
+  }];
+}
+
+def C11NoReturnDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+A function declared as ``_Noreturn`` shall not return to its caller. The
+compiler will generate a diagnostic for a function declared as ``_Noreturn``
+that appears to be capable of returning to its caller.
+  }];
+}
+
+def CXX11NoReturnDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+A function declared as ``[[noreturn]]`` shall not return to its caller. The
+compiler will generate a diagnostic for a function declared as ``[[noreturn]]``
+that appears to be capable of returning to its caller.
+  }];
+}
+
+def AssertCapabilityDocs : Documentation {
+  let Category = DocCatFunction;
+  let Heading = "assert_capability (assert_shared_capability, clang::assert_capability, clang::assert_shared_capability)";
+  let Content = [{
+Marks a function that dynamically tests whether a capability is held, and halts
+the program if it is not held.
+  }];
+}
+
+def AcquireCapabilityDocs : Documentation {
+  let Category = DocCatFunction;
+  let Heading = "acquire_capability (acquire_shared_capability, clang::acquire_capability, clang::acquire_shared_capability)";
+  let Content = [{
+Marks a function as acquiring a capability.
+  }];
+}
+
+def TryAcquireCapabilityDocs : Documentation {
+  let Category = DocCatFunction;
+  let Heading = "try_acquire_capability (try_acquire_shared_capability, clang::try_acquire_capability, clang::try_acquire_shared_capability)";
+  let Content = [{
+Marks a function that attempts to acquire a capability. This function may fail to
+actually acquire the capability; they accept a Boolean value determining
+whether acquiring the capability means success (true), or failing to acquire
+the capability means success (false).
+  }];
+}
+
+def ReleaseCapabilityDocs : Documentation {
+  let Category = DocCatFunction;
+  let Heading = "release_capability (release_shared_capability, clang::release_capability, clang::release_shared_capability)";
+  let Content = [{
+Marks a function as releasing a capability.
+  }];
+}
+def EnableIfDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+The ``enable_if`` attribute can be placed on function declarations to control
+which overload is selected based on the values of the function's arguments.
+When combined with the ``overloadable`` attribute, this feature is also
+available in C.
+
+.. code-block:: c++
+
+  int isdigit(int c);
+  int isdigit(int c) __attribute__((enable_if(c <= -1 || c > 255, "chosen when 'c' is out of range"))) __attribute__((unavailable("'c' must have the value of an unsigned char or EOF")));
+  
+  void foo(char c) {
+    isdigit(c);
+    isdigit(10);
+    isdigit(-10);  // results in a compile-time error.
+  }
+
+The enable_if attribute takes two arguments, the first is an expression written
+in terms of the function parameters, the second is a string explaining why this
+overload candidate could not be selected to be displayed in diagnostics. The
+expression is part of the function signature for the purposes of determining
+whether it is a redeclaration (following the rules used when determining
+whether a C++ template specialization is ODR-equivalent), but is not part of
+the type.
+
+The enable_if expression is evaluated as if it were the body of a
+bool-returning constexpr function declared with the arguments of the function
+it is being applied to, then called with the parameters at the call site. If the
+result is false or could not be determined through constant expression
+evaluation, then this overload will not be chosen and the provided string may
+be used in a diagnostic if the compile fails as a result.
+
+Because the enable_if expression is an unevaluated context, there are no global
+state changes, nor the ability to pass information from the enable_if
+expression to the function body. For example, suppose we want calls to
+strnlen(strbuf, maxlen) to resolve to strnlen_chk(strbuf, maxlen, size of
+strbuf) only if the size of strbuf can be determined:
+
+.. code-block:: c++
+
+  __attribute__((always_inline))
+  static inline size_t strnlen(const char *s, size_t maxlen)
+    __attribute__((overloadable))
+    __attribute__((enable_if(__builtin_object_size(s, 0) != -1))),
+                             "chosen when the buffer size is known but 'maxlen' is not")))
+  {
+    return strnlen_chk(s, maxlen, __builtin_object_size(s, 0));
+  }
+
+Multiple enable_if attributes may be applied to a single declaration. In this
+case, the enable_if expressions are evaluated from left to right in the
+following manner. First, the candidates whose enable_if expressions evaluate to
+false or cannot be evaluated are discarded. If the remaining candidates do not
+share ODR-equivalent enable_if expressions, the overload resolution is
+ambiguous. Otherwise, enable_if overload resolution continues with the next
+enable_if attribute on the candidates that have not been discarded and have
+remaining enable_if attributes. In this way, we pick the most specific
+overload out of a number of viable overloads using enable_if.
+
+.. code-block:: c++
+
+  void f() __attribute__((enable_if(true, "")));  // #1
+  void f() __attribute__((enable_if(true, ""))) __attribute__((enable_if(true, "")));  // #2
+  
+  void g(int i, int j) __attribute__((enable_if(i, "")));  // #1
+  void g(int i, int j) __attribute__((enable_if(j, ""))) __attribute__((enable_if(true)));  // #2
+
+In this example, a call to f() is always resolved to #2, as the first enable_if
+expression is ODR-equivalent for both declarations, but #1 does not have another
+enable_if expression to continue evaluating, so the next round of evaluation has
+only a single candidate. In a call to g(1, 1), the call is ambiguous even though
+#2 has more enable_if attributes, because the first enable_if expressions are
+not ODR-equivalent.
+
+Query for this feature with ``__has_attribute(enable_if)``.
+  }];
+}
+
+def OverloadableDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+Clang provides support for C++ function overloading in C.  Function overloading
+in C is introduced using the ``overloadable`` attribute.  For example, one
+might provide several overloaded versions of a ``tgsin`` function that invokes
+the appropriate standard function computing the sine of a value with ``float``,
+``double``, or ``long double`` precision:
+
+.. code-block:: c
+
+  #include <math.h>
+  float __attribute__((overloadable)) tgsin(float x) { return sinf(x); }
+  double __attribute__((overloadable)) tgsin(double x) { return sin(x); }
+  long double __attribute__((overloadable)) tgsin(long double x) { return sinl(x); }
+
+Given these declarations, one can call ``tgsin`` with a ``float`` value to
+receive a ``float`` result, with a ``double`` to receive a ``double`` result,
+etc.  Function overloading in C follows the rules of C++ function overloading
+to pick the best overload given the call arguments, with a few C-specific
+semantics:
+
+* Conversion from ``float`` or ``double`` to ``long double`` is ranked as a
+  floating-point promotion (per C99) rather than as a floating-point conversion
+  (as in C++).
+
+* A conversion from a pointer of type ``T*`` to a pointer of type ``U*`` is
+  considered a pointer conversion (with conversion rank) if ``T`` and ``U`` are
+  compatible types.
+
+* A conversion from type ``T`` to a value of type ``U`` is permitted if ``T``
+  and ``U`` are compatible types.  This conversion is given "conversion" rank.
+
+The declaration of ``overloadable`` functions is restricted to function
+declarations and definitions.  Most importantly, if any function with a given
+name is given the ``overloadable`` attribute, then all function declarations
+and definitions with that name (and in that scope) must have the
+``overloadable`` attribute.  This rule even applies to redeclarations of
+functions whose original declaration had the ``overloadable`` attribute, e.g.,
+
+.. code-block:: c
+
+  int f(int) __attribute__((overloadable));
+  float f(float); // error: declaration of "f" must have the "overloadable" attribute
+
+  int g(int) __attribute__((overloadable));
+  int g(int) { } // error: redeclaration of "g" must also have the "overloadable" attribute
+
+Functions marked ``overloadable`` must have prototypes.  Therefore, the
+following code is ill-formed:
+
+.. code-block:: c
+
+  int h() __attribute__((overloadable)); // error: h does not have a prototype
+
+However, ``overloadable`` functions are allowed to use a ellipsis even if there
+are no named parameters (as is permitted in C++).  This feature is particularly
+useful when combined with the ``unavailable`` attribute:
+
+.. code-block:: c++
+
+  void honeypot(...) __attribute__((overloadable, unavailable)); // calling me is an error
+
+Functions declared with the ``overloadable`` attribute have their names mangled
+according to the same rules as C++ function names.  For example, the three
+``tgsin`` functions in our motivating example get the mangled names
+``_Z5tgsinf``, ``_Z5tgsind``, and ``_Z5tgsine``, respectively.  There are two
+caveats to this use of name mangling:
+
+* Future versions of Clang may change the name mangling of functions overloaded
+  in C, so you should not depend on an specific mangling.  To be completely
+  safe, we strongly urge the use of ``static inline`` with ``overloadable``
+  functions.
+
+* The ``overloadable`` attribute has almost no meaning when used in C++,
+  because names will already be mangled and functions are already overloadable.
+  However, when an ``overloadable`` function occurs within an ``extern "C"``
+  linkage specification, it's name *will* be mangled in the same way as it
+  would in C.
+
+Query for this feature with ``__has_extension(attribute_overloadable)``.
+  }];
+}
+
+def ObjCMethodFamilyDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+Many methods in Objective-C have conventional meanings determined by their
+selectors. It is sometimes useful to be able to mark a method as having a
+particular conventional meaning despite not having the right selector, or as
+not having the conventional meaning that its selector would suggest. For these
+use cases, we provide an attribute to specifically describe the "method family"
+that a method belongs to.
+
+**Usage**: ``__attribute__((objc_method_family(X)))``, where ``X`` is one of
+``none``, ``alloc``, ``copy``, ``init``, ``mutableCopy``, or ``new``.  This
+attribute can only be placed at the end of a method declaration:
+
+.. code-block:: objc
+
+  - (NSString *)initMyStringValue __attribute__((objc_method_family(none)));
+
+Users who do not wish to change the conventional meaning of a method, and who
+merely want to document its non-standard retain and release semantics, should
+use the retaining behavior attributes (``ns_returns_retained``,
+``ns_returns_not_retained``, etc).
+
+Query for this feature with ``__has_attribute(objc_method_family)``.
+  }];
+}
+
+def NoDuplicateDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+The ``noduplicate`` attribute can be placed on function declarations to control
+whether function calls to this function can be duplicated or not as a result of
+optimizations. This is required for the implementation of functions with
+certain special requirements, like the OpenCL "barrier" function, that might
+need to be run concurrently by all the threads that are executing in lockstep
+on the hardware. For example this attribute applied on the function
+"nodupfunc" in the code below avoids that:
+
+.. code-block:: c
+
+  void nodupfunc() __attribute__((noduplicate));
+  // Setting it as a C++11 attribute is also valid
+  // void nodupfunc() [[clang::noduplicate]];
+  void foo();
+  void bar();
+
+  nodupfunc();
+  if (a > n) {
+    foo();
+  } else {
+    bar();
+  }
+
+gets possibly modified by some optimizations into code similar to this:
+
+.. code-block:: c
+
+  if (a > n) {
+    nodupfunc();
+    foo();
+  } else {
+    nodupfunc();
+    bar();
+  }
+
+where the call to "nodupfunc" is duplicated and sunk into the two branches
+of the condition.
+  }];
+}
+
+def NoSplitStackDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+The ``no_split_stack`` attribute disables the emission of the split stack
+preamble for a particular function. It has no effect if ``-fsplit-stack``
+is not specified.
+  }];
+}
+
+def ObjCRequiresSuperDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+Some Objective-C classes allow a subclass to override a particular method in a
+parent class but expect that the overriding method also calls the overridden
+method in the parent class. For these cases, we provide an attribute to
+designate that a method requires a "call to ``super``" in the overriding
+method in the subclass.
+
+**Usage**: ``__attribute__((objc_requires_super))``.  This attribute can only
+be placed at the end of a method declaration:
+
+.. code-block:: objc
+
+  - (void)foo __attribute__((objc_requires_super));
+
+This attribute can only be applied the method declarations within a class, and
+not a protocol.  Currently this attribute does not enforce any placement of
+where the call occurs in the overriding method (such as in the case of
+``-dealloc`` where the call must appear at the end).  It checks only that it
+exists.
+
+Note that on both OS X and iOS that the Foundation framework provides a
+convenience macro ``NS_REQUIRES_SUPER`` that provides syntactic sugar for this
+attribute:
+
+.. code-block:: objc
+
+  - (void)foo NS_REQUIRES_SUPER;
+
+This macro is conditionally defined depending on the compiler's support for
+this attribute.  If the compiler does not support the attribute the macro
+expands to nothing.
+
+Operationally, when a method has this annotation the compiler will warn if the
+implementation of an override in a subclass does not call super.  For example:
+
+.. code-block:: objc
+
+   warning: method possibly missing a [super AnnotMeth] call
+   - (void) AnnotMeth{};
+                      ^
+  }];
+}
+
+def ObjCRuntimeNameDocs : Documentation {
+    let Category = DocCatFunction;
+    let Content = [{
+By default, the Objective-C interface or protocol identifier is used
+in the metadata name for that object. The `objc_runtime_name`
+attribute allows annotated interfaces or protocols to use the
+specified string argument in the object's metadata name instead of the
+default name.
+        
+**Usage**: ``__attribute__((objc_runtime_name("MyLocalName")))``.  This attribute
+can only be placed before an @protocol or @interface declaration:
+        
+.. code-block:: objc
+        
+  __attribute__((objc_runtime_name("MyLocalName")))
+  @interface Message
+  @end
+        
+    }];
+}
+
+def AvailabilityDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+The ``availability`` attribute can be placed on declarations to describe the
+lifecycle of that declaration relative to operating system versions.  Consider
+the function declaration for a hypothetical function ``f``:
+
+.. code-block:: c++
+
+  void f(void) __attribute__((availability(macosx,introduced=10.4,deprecated=10.6,obsoleted=10.7)));
+
+The availability attribute states that ``f`` was introduced in Mac OS X 10.4,
+deprecated in Mac OS X 10.6, and obsoleted in Mac OS X 10.7.  This information
+is used by Clang to determine when it is safe to use ``f``: for example, if
+Clang is instructed to compile code for Mac OS X 10.5, a call to ``f()``
+succeeds.  If Clang is instructed to compile code for Mac OS X 10.6, the call
+succeeds but Clang emits a warning specifying that the function is deprecated.
+Finally, if Clang is instructed to compile code for Mac OS X 10.7, the call
+fails because ``f()`` is no longer available.
+
+The availability attribute is a comma-separated list starting with the
+platform name and then including clauses specifying important milestones in the
+declaration's lifetime (in any order) along with additional information.  Those
+clauses can be:
+
+introduced=\ *version*
+  The first version in which this declaration was introduced.
+
+deprecated=\ *version*
+  The first version in which this declaration was deprecated, meaning that
+  users should migrate away from this API.
+
+obsoleted=\ *version*
+  The first version in which this declaration was obsoleted, meaning that it
+  was removed completely and can no longer be used.
+
+unavailable
+  This declaration is never available on this platform.
+
+message=\ *string-literal*
+  Additional message text that Clang will provide when emitting a warning or
+  error about use of a deprecated or obsoleted declaration.  Useful to direct
+  users to replacement APIs.
+
+Multiple availability attributes can be placed on a declaration, which may
+correspond to different platforms.  Only the availability attribute with the
+platform corresponding to the target platform will be used; any others will be
+ignored.  If no availability attribute specifies availability for the current
+target platform, the availability attributes are ignored.  Supported platforms
+are:
+
+``ios``
+  Apple's iOS operating system.  The minimum deployment target is specified by
+  the ``-mios-version-min=*version*`` or ``-miphoneos-version-min=*version*``
+  command-line arguments.
+
+``macosx``
+  Apple's Mac OS X operating system.  The minimum deployment target is
+  specified by the ``-mmacosx-version-min=*version*`` command-line argument.
+
+A declaration can be used even when deploying back to a platform version prior
+to when the declaration was introduced.  When this happens, the declaration is
+`weakly linked
+<https://developer.apple.com/library/mac/#documentation/MacOSX/Conceptual/BPFrameworks/Concepts/WeakLinking.html>`_,
+as if the ``weak_import`` attribute were added to the declaration.  A
+weakly-linked declaration may or may not be present a run-time, and a program
+can determine whether the declaration is present by checking whether the
+address of that declaration is non-NULL.
+
+If there are multiple declarations of the same entity, the availability
+attributes must either match on a per-platform basis or later
+declarations must not have availability attributes for that
+platform. For example:
+
+.. code-block:: c
+
+  void g(void) __attribute__((availability(macosx,introduced=10.4)));
+  void g(void) __attribute__((availability(macosx,introduced=10.4))); // okay, matches
+  void g(void) __attribute__((availability(ios,introduced=4.0))); // okay, adds a new platform
+  void g(void); // okay, inherits both macosx and ios availability from above.
+  void g(void) __attribute__((availability(macosx,introduced=10.5))); // error: mismatch
+
+When one method overrides another, the overriding method can be more widely available than the overridden method, e.g.,:
+
+.. code-block:: objc
+
+  @interface A
+  - (id)method __attribute__((availability(macosx,introduced=10.4)));
+  - (id)method2 __attribute__((availability(macosx,introduced=10.4)));
+  @end
+
+  @interface B : A
+  - (id)method __attribute__((availability(macosx,introduced=10.3))); // okay: method moved into base class later
+  - (id)method __attribute__((availability(macosx,introduced=10.5))); // error: this method was available via the base class in 10.4
+  @end
+  }];
+}
+
+def FallthroughDocs : Documentation {
+  let Category = DocCatStmt;
+  let Content = [{
+The ``clang::fallthrough`` attribute is used along with the
+``-Wimplicit-fallthrough`` argument to annotate intentional fall-through
+between switch labels.  It can only be applied to a null statement placed at a
+point of execution between any statement and the next switch label.  It is
+common to mark these places with a specific comment, but this attribute is
+meant to replace comments with a more strict annotation, which can be checked
+by the compiler.  This attribute doesn't change semantics of the code and can
+be used wherever an intended fall-through occurs.  It is designed to mimic
+control-flow statements like ``break;``, so it can be placed in most places
+where ``break;`` can, but only if there are no statements on the execution path
+between it and the next switch label.
+
+Here is an example:
+
+.. code-block:: c++
+
+  // compile with -Wimplicit-fallthrough
+  switch (n) {
+  case 22:
+  case 33:  // no warning: no statements between case labels
+    f();
+  case 44:  // warning: unannotated fall-through
+    g();
+    [[clang::fallthrough]];
+  case 55:  // no warning
+    if (x) {
+      h();
+      break;
+    }
+    else {
+      i();
+      [[clang::fallthrough]];
+    }
+  case 66:  // no warning
+    p();
+    [[clang::fallthrough]]; // warning: fallthrough annotation does not
+                            //          directly precede case label
+    q();
+  case 77:  // warning: unannotated fall-through
+    r();
+  }
+  }];
+}
+
+def ARMInterruptDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+Clang supports the GNU style ``__attribute__((interrupt("TYPE")))`` attribute on
+ARM 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.
+
+The parameter passed to the interrupt attribute is optional, but if
+provided it must be a string literal with one of the following values: "IRQ",
+"FIQ", "SWI", "ABORT", "UNDEF".
+
+The semantics are as follows:
+
+- If the function is AAPCS, Clang instructs the backend to realign the stack to
+  8 bytes on entry. This is a general requirement of the AAPCS at public
+  interfaces, but may not hold when an exception is taken. Doing this allows
+  other AAPCS functions to be called.
+- If the CPU is M-class this is all that needs to be done since the architecture
+  itself is designed in such a way that functions obeying the normal AAPCS ABI
+  constraints are valid exception handlers.
+- If the CPU is not M-class, the prologue and epilogue are modified to save all
+  non-banked registers that are used, so that upon return the user-mode state
+  will not be corrupted. Note that to avoid unnecessary overhead, only
+  general-purpose (integer) registers are saved in this way. If VFP operations
+  are needed, that state must be saved manually.
+
+  Specifically, interrupt kinds other than "FIQ" will save all core registers
+  except "lr" and "sp". "FIQ" interrupts will save r0-r7.
+- If the CPU is not M-class, the return instruction is changed to one of the
+  canonical sequences permitted by the architecture for exception return. Where
+  possible the function itself will make the necessary "lr" adjustments so that
+  the "preferred return address" is selected.
+
+  Unfortunately the compiler is unable to make this guarantee for an "UNDEF"
+  handler, where the offset from "lr" to the preferred return address depends on
+  the execution state of the code which generated the exception. In this case
+  a sequence equivalent to "movs pc, lr" will be used.
+  }];
+}
+
+def PcsDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+On ARM targets, this can attribute can be used to select calling conventions,
+similar to ``stdcall`` on x86. Valid parameter values are "aapcs" and
+"aapcs-vfp".
+  }];
+}
+
+def DocCatConsumed : DocumentationCategory<"Consumed Annotation Checking"> {
+  let Content = [{
+Clang supports additional attributes for checking basic resource management
+properties, specifically for unique objects that have a single owning reference.
+The following attributes are currently supported, although **the implementation
+for these annotations is currently in development and are subject to change.**
+  }];
+}
+
+def SetTypestateDocs : Documentation {
+  let Category = DocCatConsumed;
+  let Content = [{
+Annotate methods that transition an object into a new state with
+``__attribute__((set_typestate(new_state)))``.  The new state must be
+unconsumed, consumed, or unknown.
+  }];
+}
+
+def CallableWhenDocs : Documentation {
+  let Category = DocCatConsumed;
+  let Content = [{
+Use ``__attribute__((callable_when(...)))`` to indicate what states a method
+may be called in.  Valid states are unconsumed, consumed, or unknown.  Each
+argument to this attribute must be a quoted string.  E.g.:
+
+``__attribute__((callable_when("unconsumed", "unknown")))``
+  }];
+}
+
+def TestTypestateDocs : Documentation {
+  let Category = DocCatConsumed;
+  let Content = [{
+Use ``__attribute__((test_typestate(tested_state)))`` to indicate that a method
+returns true if the object is in the specified state..
+  }];
+}
+
+def ParamTypestateDocs : Documentation {
+  let Category = DocCatConsumed;
+  let Content = [{
+This attribute specifies expectations about function parameters.  Calls to an
+function with annotated parameters will issue a warning if the corresponding
+argument isn't in the expected state.  The attribute is also used to set the
+initial state of the parameter when analyzing the function's body.
+  }];
+}
+
+def ReturnTypestateDocs : Documentation {
+  let Category = DocCatConsumed;
+  let Content = [{
+The ``return_typestate`` attribute can be applied to functions or parameters.
+When applied to a function the attribute specifies the state of the returned
+value.  The function's body is checked to ensure that it always returns a value
+in the specified state.  On the caller side, values returned by the annotated
+function are initialized to the given state.
+
+When applied to a function parameter it modifies the state of an argument after
+a call to the function returns.  The function's body is checked to ensure that
+the parameter is in the expected state before returning.
+  }];
+}
+
+def ConsumableDocs : Documentation {
+  let Category = DocCatConsumed;
+  let Content = [{
+Each ``class`` that uses any of the typestate annotations must first be marked
+using the ``consumable`` attribute.  Failure to do so will result in a warning.
+
+This attribute accepts a single parameter that must be one of the following:
+``unknown``, ``consumed``, or ``unconsumed``.
+  }];
+}
+
+def NoSanitizeAddressDocs : Documentation {
+  let Category = DocCatFunction;
+  // This function has multiple distinct spellings, and so it requires a custom
+  // heading to be specified. The most common spelling is sufficient.
+  let Heading = "no_sanitize_address (no_address_safety_analysis, gnu::no_address_safety_analysis, gnu::no_sanitize_address)";
+  let Content = [{
+.. _langext-address_sanitizer:
+
+Use ``__attribute__((no_sanitize_address))`` on a function declaration to
+specify that address safety instrumentation (e.g. AddressSanitizer) should
+not be applied to that function.
+  }];
+}
+
+def NoSanitizeThreadDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+.. _langext-thread_sanitizer:
+
+Use ``__attribute__((no_sanitize_thread))`` on a function declaration to
+specify that checks for data races on plain (non-atomic) memory accesses should
+not be inserted by ThreadSanitizer. The function is still instrumented by the
+tool to avoid false positives and provide meaningful stack traces.
+  }];
+}
+
+def NoSanitizeMemoryDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+.. _langext-memory_sanitizer:
+
+Use ``__attribute__((no_sanitize_memory))`` on a function declaration to
+specify that checks for uninitialized memory should not be inserted 
+(e.g. by MemorySanitizer). The function may still be instrumented by the tool
+to avoid false positives in other places.
+  }];
+}
+
+def DocCatTypeSafety : DocumentationCategory<"Type Safety Checking"> {
+  let Content = [{
+Clang supports additional attributes to enable checking type safety properties
+that can't be enforced by the C type system.  Use cases include:
+
+* MPI library implementations, where these attributes enable checking that
+  the buffer type matches the passed ``MPI_Datatype``;
+* for HDF5 library there is a similar use case to MPI;
+* checking types of variadic functions' arguments for functions like
+  ``fcntl()`` and ``ioctl()``.
+
+You can detect support for these attributes with ``__has_attribute()``.  For
+example:
+
+.. code-block:: c++
+
+  #if defined(__has_attribute)
+  #  if __has_attribute(argument_with_type_tag) && \
+        __has_attribute(pointer_with_type_tag) && \
+        __has_attribute(type_tag_for_datatype)
+  #    define ATTR_MPI_PWT(buffer_idx, type_idx) __attribute__((pointer_with_type_tag(mpi,buffer_idx,type_idx)))
+  /* ... other macros ...  */
+  #  endif
+  #endif
+
+  #if !defined(ATTR_MPI_PWT)
+  # define ATTR_MPI_PWT(buffer_idx, type_idx)
+  #endif
+
+  int MPI_Send(void *buf, int count, MPI_Datatype datatype /*, other args omitted */)
+      ATTR_MPI_PWT(1,3);
+  }];
+}
+
+def ArgumentWithTypeTagDocs : Documentation {
+  let Category = DocCatTypeSafety;
+  let Heading = "argument_with_type_tag";
+  let Content = [{
+Use ``__attribute__((argument_with_type_tag(arg_kind, arg_idx,
+type_tag_idx)))`` on a function declaration to specify that the function
+accepts a type tag that determines the type of some other argument.
+``arg_kind`` is an identifier that should be used when annotating all
+applicable type tags.
+
+This attribute is primarily useful for checking arguments of variadic functions
+(``pointer_with_type_tag`` can be used in most non-variadic cases).
+
+For example:
+
+.. code-block:: c++
+
+  int fcntl(int fd, int cmd, ...)
+      __attribute__(( argument_with_type_tag(fcntl,3,2) ));
+  }];
+}
+
+def PointerWithTypeTagDocs : Documentation {
+  let Category = DocCatTypeSafety;
+  let Heading = "pointer_with_type_tag";
+  let Content = [{
+Use ``__attribute__((pointer_with_type_tag(ptr_kind, ptr_idx, type_tag_idx)))``
+on a function declaration to specify that the function accepts a type tag that
+determines the pointee type of some other pointer argument.
+
+For example:
+
+.. code-block:: c++
+
+  int MPI_Send(void *buf, int count, MPI_Datatype datatype /*, other args omitted */)
+      __attribute__(( pointer_with_type_tag(mpi,1,3) ));
+  }];
+}
+
+def TypeTagForDatatypeDocs : Documentation {
+  let Category = DocCatTypeSafety;
+  let Content = [{
+Clang supports annotating type tags of two forms.
+
+* **Type tag that is an expression containing a reference to some declared
+  identifier.** Use ``__attribute__((type_tag_for_datatype(kind, type)))`` on a
+  declaration with that identifier:
+
+  .. code-block:: c++
+
+    extern struct mpi_datatype mpi_datatype_int
+        __attribute__(( type_tag_for_datatype(mpi,int) ));
+    #define MPI_INT ((MPI_Datatype) &mpi_datatype_int)
+
+* **Type tag that is an integral literal.** Introduce a ``static const``
+  variable with a corresponding initializer value and attach
+  ``__attribute__((type_tag_for_datatype(kind, type)))`` on that declaration,
+  for example:
+
+  .. code-block:: c++
+
+    #define MPI_INT ((MPI_Datatype) 42)
+    static const MPI_Datatype mpi_datatype_int
+        __attribute__(( type_tag_for_datatype(mpi,int) )) = 42
+
+The attribute also accepts an optional third argument that determines how the
+expression is compared to the type tag.  There are two supported flags:
+
+* ``layout_compatible`` will cause types to be compared according to
+  layout-compatibility rules (C++11 [class.mem] p 17, 18).  This is
+  implemented to support annotating types like ``MPI_DOUBLE_INT``.
+
+  For example:
+
+  .. code-block:: c++
+
+    /* In mpi.h */
+    struct internal_mpi_double_int { double d; int i; };
+    extern struct mpi_datatype mpi_datatype_double_int
+        __attribute__(( type_tag_for_datatype(mpi, struct internal_mpi_double_int, layout_compatible) ));
+
+    #define MPI_DOUBLE_INT ((MPI_Datatype) &mpi_datatype_double_int)
+
+    /* In user code */
+    struct my_pair { double a; int b; };
+    struct my_pair *buffer;
+    MPI_Send(buffer, 1, MPI_DOUBLE_INT /*, ...  */); // no warning
+
+    struct my_int_pair { int a; int b; }
+    struct my_int_pair *buffer2;
+    MPI_Send(buffer2, 1, MPI_DOUBLE_INT /*, ...  */); // warning: actual buffer element
+                                                      // type 'struct my_int_pair'
+                                                      // doesn't match specified MPI_Datatype
+
+* ``must_be_null`` specifies that the expression should be a null pointer
+  constant, for example:
+
+  .. code-block:: c++
+
+    /* In mpi.h */
+    extern struct mpi_datatype mpi_datatype_null
+        __attribute__(( type_tag_for_datatype(mpi, void, must_be_null) ));
+
+    #define MPI_DATATYPE_NULL ((MPI_Datatype) &mpi_datatype_null)
+
+    /* In user code */
+    MPI_Send(buffer, 1, MPI_DATATYPE_NULL /*, ...  */); // warning: MPI_DATATYPE_NULL
+                                                        // was specified but buffer
+                                                        // is not a null pointer
+  }];
+}
+
+def FlattenDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+The ``flatten`` attribute causes calls within the attributed function to
+be inlined unless it is impossible to do so, for example if the body of the
+callee is unavailable or if the callee has the ``noinline`` attribute.
+  }];
+}
+
+def FormatDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+
+Clang supports the ``format`` attribute, which indicates that the function
+accepts a ``printf`` or ``scanf``-like format string and corresponding
+arguments or a ``va_list`` that contains these arguments.
+
+Please see `GCC documentation about format attribute
+<http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html>`_ to find details
+about attribute syntax.
+
+Clang implements two kinds of checks with this attribute.
+
+#. Clang checks that the function with the ``format`` attribute is called with
+   a format string that uses format specifiers that are allowed, and that
+   arguments match the format string.  This is the ``-Wformat`` warning, it is
+   on by default.
+
+#. Clang checks that the format string argument is a literal string.  This is
+   the ``-Wformat-nonliteral`` warning, it is off by default.
+
+   Clang implements this mostly the same way as GCC, but there is a difference
+   for functions that accept a ``va_list`` argument (for example, ``vprintf``).
+   GCC does not emit ``-Wformat-nonliteral`` warning for calls to such
+   functions.  Clang does not warn if the format string comes from a function
+   parameter, where the function is annotated with a compatible attribute,
+   otherwise it warns.  For example:
+
+   .. code-block:: c
+
+     __attribute__((__format__ (__scanf__, 1, 3)))
+     void foo(const char* s, char *buf, ...) {
+       va_list ap;
+       va_start(ap, buf);
+
+       vprintf(s, ap); // warning: format string is not a string literal
+     }
+
+   In this case we warn because ``s`` contains a format string for a
+   ``scanf``-like function, but it is passed to a ``printf``-like function.
+
+   If the attribute is removed, clang still warns, because the format string is
+   not a string literal.
+
+   Another example:
+
+   .. code-block:: c
+
+     __attribute__((__format__ (__printf__, 1, 3)))
+     void foo(const char* s, char *buf, ...) {
+       va_list ap;
+       va_start(ap, buf);
+
+       vprintf(s, ap); // warning
+     }
+
+   In this case Clang does not warn because the format string ``s`` and
+   the corresponding arguments are annotated.  If the arguments are
+   incorrect, the caller of ``foo`` will receive a warning.
+  }];
+}
+
+def MSInheritanceDocs : Documentation {
+  let Category = DocCatType;
+  let Heading = "__single_inhertiance, __multiple_inheritance, __virtual_inheritance";
+  let Content = [{
+This collection of keywords is enabled under ``-fms-extensions`` and controls
+the pointer-to-member representation used on ``*-*-win32`` targets.
+
+The ``*-*-win32`` targets utilize a pointer-to-member representation which
+varies in size and alignment depending on the definition of the underlying
+class.
+
+However, this is problematic when a forward declaration is only available and
+no definition has been made yet.  In such cases, Clang is forced to utilize the
+most general representation that is available to it.
+
+These keywords make it possible to use a pointer-to-member representation other
+than the most general one regardless of whether or not the definition will ever
+be present in the current translation unit.
+
+This family of keywords belong between the ``class-key`` and ``class-name``:
+
+.. code-block:: c++
+
+  struct __single_inheritance S;
+  int S::*i;
+  struct S {};
+
+This keyword can be applied to class templates but only has an effect when used
+on full specializations:
+
+.. code-block:: c++
+
+  template <typename T, typename U> struct __single_inheritance A; // warning: inheritance model ignored on primary template
+  template <typename T> struct __multiple_inheritance A<T, T>; // warning: inheritance model ignored on partial specialization
+  template <> struct __single_inheritance A<int, float>;
+
+Note that choosing an inheritance model less general than strictly necessary is
+an error:
+
+.. code-block:: c++
+
+  struct __multiple_inheritance S; // error: inheritance model does not match definition
+  int S::*i;
+  struct S {};
+}];
+}
+
+def OptnoneDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+The ``optnone`` attribute suppresses essentially all optimizations
+on a function or method, regardless of the optimization level applied to
+the compilation unit as a whole.  This is particularly useful when you
+need to debug a particular function, but it is infeasible to build the
+entire application without optimization.  Avoiding optimization on the
+specified function can improve the quality of the debugging information
+for that function.
+
+This attribute is incompatible with the ``always_inline`` attribute.
+  }];
+}
+
+def LoopHintDocs : Documentation {
+  let Category = DocCatStmt;
+  let Content = [{
+The ``#pragma clang loop`` directive allows loop optimization hints to be
+specified for the subsequent loop. The directive allows vectorization,
+interleaving, and unrolling to be enabled or disabled. Vector width as well
+as interleave and unrolling count can be manually specified. See
+`language extensions
+<http://clang.llvm.org/docs/LanguageExtensions.html#extensions-for-loop-hint-optimizations>`_
+for details.
+  }];
+}
+
+def UnrollHintDocs : Documentation {
+  let Category = DocCatStmt;
+  let Content = [{
+Loop unrolling optimization hints can be specified with ``#pragma unroll``. The
+pragma is placed immediately before a for, while, do-while, or c++11 range-based
+for loop.
+
+Specifying ``#pragma unroll`` without a parameter directs the loop unroller to
+attempt to fully unroll the loop if the trip count is known at compile time:
+
+.. code-block:: c++
+
+  #pragma unroll
+  for (...) {
+    ...
+  }
+
+Specifying the optional parameter, ``#pragma unroll _value_``, directs the
+unroller to unroll the loop ``_value_`` times.  The parameter may optionally be
+enclosed in parentheses:
+
+.. code-block:: c++
+
+  #pragma unroll 16
+  for (...) {
+    ...
+  }
+
+  #pragma unroll(16)
+  for (...) {
+    ...
+  }
+
+``#pragma unroll`` and ``#pragma unroll _value_`` have identical semantics to
+``#pragma clang loop unroll(enable)`` and ``#pragma clang loop
+unroll_count(_value_)`` respectively. See `language extensions
+<http://clang.llvm.org/docs/LanguageExtensions.html#extensions-for-loop-hint-optimizations>`_
+for further details including limitations of the unroll hints.
+  }];
+}
+
diff --git a/include/clang/Basic/AttrKinds.h b/include/clang/Basic/AttrKinds.h
index 7c4e2c7..150a30e 100644
--- a/include/clang/Basic/AttrKinds.h
+++ b/include/clang/Basic/AttrKinds.h
@@ -24,7 +24,6 @@
 #define ATTR(X) X,
 #define LAST_INHERITABLE_ATTR(X) X, LAST_INHERITABLE = X,
 #define LAST_INHERITABLE_PARAM_ATTR(X) X, LAST_INHERITABLE_PARAM = X,
-#define LAST_MS_INHERITANCE_ATTR(X) X, LAST_MS_INHERITANCE = X,
 #include "clang/Basic/AttrList.inc"
   NUM_ATTRS
 };
diff --git a/include/clang/Basic/Attributes.h b/include/clang/Basic/Attributes.h
new file mode 100644
index 0000000..5783b3b
--- /dev/null
+++ b/include/clang/Basic/Attributes.h
@@ -0,0 +1,41 @@
+//===--- Attributes.h - Attributes header -----------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_ATTRIBUTES_H
+#define LLVM_CLANG_BASIC_ATTRIBUTES_H
+
+#include "llvm/ADT/Triple.h"
+#include "clang/Basic/LangOptions.h"
+
+namespace clang {
+
+class IdentifierInfo;
+
+enum class AttrSyntax {
+  /// Is the attribute identifier generally known for any syntax?
+  Generic,
+  /// Is the identifier known as a GNU-style attribute?
+  GNU,
+  /// Is the identifier known as a __declspec-style attribute?
+  Declspec,
+  // Is the identifier known as a C++-style attribute?
+  CXX,
+  // Is the identifier known as a pragma attribute?
+  Pragma
+};
+
+/// \brief Return true if we recognize and implement the attribute specified by
+/// the given information.
+bool hasAttribute(AttrSyntax Syntax, const IdentifierInfo *Scope,
+                  const IdentifierInfo *Attr, const llvm::Triple &T,
+                  const LangOptions &LangOpts);
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_BASIC_ATTRIBUTES_H
diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def
index 37b1237..4df191b 100644
--- a/include/clang/Basic/Builtins.def
+++ b/include/clang/Basic/Builtins.def
@@ -50,6 +50,7 @@
 //  L   -> long (e.g. Li for 'long int')
 //  LL  -> long long
 //  LLL -> __int128_t (e.g. LLLi)
+//  W   -> int64_t
 //  S   -> signed
 //  U   -> unsigned
 //  I   -> Required to constant fold to an integer constant expression.
@@ -72,7 +73,7 @@
 //       be followed by ':headername:' to state which header this function
 //       comes from.
 //  i -> this is a runtime library implemented function without the
-//       '__builtin_' prefix. It will be implemented in compiter-rt or libgcc.
+//       '__builtin_' prefix. It will be implemented in compiler-rt or libgcc.
 //  p:N: -> this is a printf-like function whose Nth argument is the format
 //          string.
 //  P:N: -> similar to the p:N: attribute, but the function is like vprintf
@@ -444,6 +445,7 @@
 BUILTIN(__builtin_return_address, "v*IUi", "n")
 BUILTIN(__builtin_extract_return_addr, "v*v*", "n")
 BUILTIN(__builtin_frame_address, "v*IUi", "n")
+BUILTIN(__builtin___clear_cache, "vc*c*", "n")
 BUILTIN(__builtin_flt_rounds, "i", "nc")
 BUILTIN(__builtin_setjmp, "iv**", "j")
 BUILTIN(__builtin_longjmp, "vv**i", "r")
@@ -677,8 +679,16 @@
 // Microsoft builtins.  These are only active with -fms-extensions.
 LANGBUILTIN(_alloca,      "v*z", "n", ALL_MS_LANGUAGES)
 LANGBUILTIN(__assume,     "vb",  "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__noop,       "v.",  "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__noop,       "i.",  "n", ALL_MS_LANGUAGES)
 LANGBUILTIN(__debugbreak, "v",   "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__va_start,   "vc**.", "nt", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedCompareExchange, "LiLiD*LiLi", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedCompareExchangePointer, "v*v*D*v*v*", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedIncrement, "LiLiD*", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedDecrement, "LiLiD*", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedExchangeAdd, "LiLiD*Li", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedExchangePointer, "v*v*D*v*", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(_InterlockedExchange, "LiLiD*Li", "n", ALL_MS_LANGUAGES)
 
 // C99 library functions
 // C99 stdlib.h
@@ -726,11 +736,16 @@
 LIBBUILTIN(vfscanf, "iP*RcC*Ra",  "fS:1:", "stdio.h", ALL_LANGUAGES)
 LIBBUILTIN(vsscanf, "icC*RcC*Ra", "fS:1:", "stdio.h", ALL_LANGUAGES)
 // C99
+// In some systems setjmp is a macro that expands to _setjmp. We undefine
+// it here to avoid having two identical LIBBUILTIN entries.
 #undef setjmp
 LIBBUILTIN(setjmp, "iJ",          "fj",    "setjmp.h", ALL_LANGUAGES)
 LIBBUILTIN(longjmp, "vJi",        "fr",    "setjmp.h", ALL_LANGUAGES)
 
 // Non-C library functions, active in GNU mode only.
+// Functions with (returns_twice) attribute (marked as "j") are still active in
+// all languages, because losing this attribute would result in miscompilation
+// when these functions are used in non-GNU mode. PR16138.
 LIBBUILTIN(alloca, "v*z",         "f",     "stdlib.h", ALL_GNU_LANGUAGES)
 // POSIX string.h
 LIBBUILTIN(stpcpy, "c*c*cC*",     "f",     "string.h", ALL_GNU_LANGUAGES)
@@ -749,18 +764,16 @@
 LIBBUILTIN(strncasecmp, "icC*cC*z", "f",   "strings.h", ALL_GNU_LANGUAGES)
 // POSIX unistd.h
 LIBBUILTIN(_exit, "vi",           "fr",    "unistd.h", ALL_GNU_LANGUAGES)
-LIBBUILTIN(vfork, "p",            "fj",    "unistd.h", ALL_GNU_LANGUAGES)
+LIBBUILTIN(vfork, "p",            "fj",    "unistd.h", ALL_LANGUAGES)
 // POSIX setjmp.h
 
-// In some systems setjmp is a macro that expands to _setjmp. We undefine
-// it here to avoid having two identical LIBBUILTIN entries.
-LIBBUILTIN(_setjmp, "iJ",         "fj",   "setjmp.h", ALL_GNU_LANGUAGES)
-LIBBUILTIN(__sigsetjmp, "iSJi",   "fj",   "setjmp.h", ALL_GNU_LANGUAGES)
-LIBBUILTIN(sigsetjmp, "iSJi",     "fj",   "setjmp.h", ALL_GNU_LANGUAGES)
-LIBBUILTIN(setjmp_syscall, "iJ",  "fj",   "setjmp.h", ALL_GNU_LANGUAGES)
-LIBBUILTIN(savectx, "iJ",         "fj",   "setjmp.h", ALL_GNU_LANGUAGES)
-LIBBUILTIN(qsetjmp, "iJ",         "fj",   "setjmp.h", ALL_GNU_LANGUAGES)
-LIBBUILTIN(getcontext, "iK*",     "fj",   "setjmp.h", ALL_GNU_LANGUAGES)
+LIBBUILTIN(_setjmp, "iJ",         "fj",   "setjmp.h", ALL_LANGUAGES)
+LIBBUILTIN(__sigsetjmp, "iSJi",   "fj",   "setjmp.h", ALL_LANGUAGES)
+LIBBUILTIN(sigsetjmp, "iSJi",     "fj",   "setjmp.h", ALL_LANGUAGES)
+LIBBUILTIN(setjmp_syscall, "iJ",  "fj",   "setjmp.h", ALL_LANGUAGES)
+LIBBUILTIN(savectx, "iJ",         "fj",   "setjmp.h", ALL_LANGUAGES)
+LIBBUILTIN(qsetjmp, "iJ",         "fj",   "setjmp.h", ALL_LANGUAGES)
+LIBBUILTIN(getcontext, "iK*",     "fj",   "setjmp.h", ALL_LANGUAGES)
 
 LIBBUILTIN(_longjmp, "vJi",       "fr",    "setjmp.h", ALL_GNU_LANGUAGES)
 LIBBUILTIN(siglongjmp, "vSJi",    "fr",    "setjmp.h", ALL_GNU_LANGUAGES)
@@ -1137,6 +1150,21 @@
 LIBBUILTIN(ctanhf, "XfXf", "fnc", "complex.h", ALL_LANGUAGES)
 LIBBUILTIN(ctanhl, "XLdXLd", "fnc", "complex.h", ALL_LANGUAGES)
 
+// __sinpi and friends are OS X specific library functions, but otherwise much
+// like the standard (non-complex) sin (etc).
+LIBBUILTIN(__sinpi, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(__sinpif, "ff", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(__cospi, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(__cospif, "ff", "fne", "math.h", ALL_LANGUAGES)
+
+LIBBUILTIN(__tanpi, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(__tanpif, "ff", "fne", "math.h", ALL_LANGUAGES)
+
+// Similarly, __exp10 is OS X only
+LIBBUILTIN(__exp10, "dd", "fne", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(__exp10f, "ff", "fne", "math.h", ALL_LANGUAGES)
+
 // Blocks runtime Builtin math library functions
 LIBBUILTIN(_Block_object_assign, "vv*vC*iC", "f", "Blocks.h", ALL_LANGUAGES)
 LIBBUILTIN(_Block_object_dispose, "vvC*iC", "f", "Blocks.h", ALL_LANGUAGES)
@@ -1179,6 +1207,8 @@
 
 // Clang builtins (not available in GCC).
 BUILTIN(__builtin_addressof, "v*v&", "nct")
+BUILTIN(__builtin_operator_new, "v*z", "c")
+BUILTIN(__builtin_operator_delete, "vv*", "n")
 
 // @LOCALMOD-BEGIN
 // NaCl builtins.
diff --git a/include/clang/Basic/Builtins.h b/include/clang/Basic/Builtins.h
index 9756f21..f9d30e4 100644
--- a/include/clang/Basic/Builtins.h
+++ b/include/clang/Basic/Builtins.h
@@ -94,53 +94,53 @@
   /// \brief Return true if this function has no side effects and doesn't
   /// read memory.
   bool isConst(unsigned ID) const {
-    return strchr(GetRecord(ID).Attributes, 'c') != 0;
+    return strchr(GetRecord(ID).Attributes, 'c') != nullptr;
   }
 
   /// \brief Return true if we know this builtin never throws an exception.
   bool isNoThrow(unsigned ID) const {
-    return strchr(GetRecord(ID).Attributes, 'n') != 0;
+    return strchr(GetRecord(ID).Attributes, 'n') != nullptr;
   }
 
   /// \brief Return true if we know this builtin never returns.
   bool isNoReturn(unsigned ID) const {
-    return strchr(GetRecord(ID).Attributes, 'r') != 0;
+    return strchr(GetRecord(ID).Attributes, 'r') != nullptr;
   }
 
   /// \brief Return true if we know this builtin can return twice.
   bool isReturnsTwice(unsigned ID) const {
-    return strchr(GetRecord(ID).Attributes, 'j') != 0;
+    return strchr(GetRecord(ID).Attributes, 'j') != nullptr;
   }
 
   /// \brief Returns true if this builtin does not perform the side-effects
   /// of its arguments.
   bool isUnevaluated(unsigned ID) const {
-    return strchr(GetRecord(ID).Attributes, 'u') != 0;
+    return strchr(GetRecord(ID).Attributes, 'u') != nullptr;
   }
 
   /// \brief Return true if this is a builtin for a libc/libm function,
   /// with a "__builtin_" prefix (e.g. __builtin_abs).
   bool isLibFunction(unsigned ID) const {
-    return strchr(GetRecord(ID).Attributes, 'F') != 0;
+    return strchr(GetRecord(ID).Attributes, 'F') != nullptr;
   }
 
   /// \brief Determines whether this builtin is a predefined libc/libm
   /// function, such as "malloc", where we know the signature a
   /// priori.
   bool isPredefinedLibFunction(unsigned ID) const {
-    return strchr(GetRecord(ID).Attributes, 'f') != 0;
+    return strchr(GetRecord(ID).Attributes, 'f') != nullptr;
   }
 
   /// \brief Determines whether this builtin is a predefined compiler-rt/libgcc
   /// function, such as "__clear_cache", where we know the signature a
   /// priori.
   bool isPredefinedRuntimeFunction(unsigned ID) const {
-    return strchr(GetRecord(ID).Attributes, 'i') != 0;
+    return strchr(GetRecord(ID).Attributes, 'i') != nullptr;
   }
 
   /// \brief Determines whether this builtin has custom typechecking.
   bool hasCustomTypechecking(unsigned ID) const {
-    return strchr(GetRecord(ID).Attributes, 't') != 0;
+    return strchr(GetRecord(ID).Attributes, 't') != nullptr;
   }
 
   /// \brief Completely forget that the given ID was ever considered a builtin,
@@ -168,7 +168,7 @@
   ///
   /// Such functions can be const when the MathErrno lang option is disabled.
   bool isConstWithoutErrno(unsigned ID) const {
-    return strchr(GetRecord(ID).Attributes, 'e') != 0;
+    return strchr(GetRecord(ID).Attributes, 'e') != nullptr;
   }
 
 private:
@@ -177,6 +177,10 @@
   /// \brief Is this builtin supported according to the given language options?
   bool BuiltinIsSupported(const Builtin::Info &BuiltinInfo,
                           const LangOptions &LangOpts);
+
+  /// \brief Helper function for isPrintfLike and isScanfLike.
+  bool isLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg,
+              const char *Fmt) const;
 };
 
 }
diff --git a/include/clang/Basic/BuiltinsAArch64.def b/include/clang/Basic/BuiltinsAArch64.def
index aafd202..695ecf9 100644
--- a/include/clang/Basic/BuiltinsAArch64.def
+++ b/include/clang/Basic/BuiltinsAArch64.def
@@ -1,4 +1,4 @@
-//===-- BuiltinsAArch64.def - AArch64 Builtin function database -*- C++ -*-===//
+//==- BuiltinsAArch64.def - AArch64 Builtin function database ----*- C++ -*-==//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -16,10 +16,38 @@
 
 // In libgcc
 BUILTIN(__clear_cache, "vv*v*", "i")
-// NEON
-#define GET_NEON_AARCH64_BUILTINS
-#include "clang/Basic/arm_neon.inc"
-#undef GET_NEON_AARCH64_BUILTINS
-#undef GET_NEON_BUILTINS
+
+BUILTIN(__builtin_arm_ldrex, "v.", "t")
+BUILTIN(__builtin_arm_ldaex, "v.", "t")
+BUILTIN(__builtin_arm_strex, "i.", "t")
+BUILTIN(__builtin_arm_stlex, "i.", "t")
+BUILTIN(__builtin_arm_clrex, "v", "")
+
+// Bit manipulation
+BUILTIN(__builtin_arm_rbit, "UiUi", "nc")
+BUILTIN(__builtin_arm_rbit64, "LUiLUi", "nc")
+
+// HINT
+BUILTIN(__builtin_arm_nop, "v", "")
+BUILTIN(__builtin_arm_yield, "v", "")
+BUILTIN(__builtin_arm_wfe, "v", "")
+BUILTIN(__builtin_arm_wfi, "v", "")
+BUILTIN(__builtin_arm_sev, "v", "")
+BUILTIN(__builtin_arm_sevl, "v", "")
+
+// CRC32
+BUILTIN(__builtin_arm_crc32b, "UiUiUc", "nc")
+BUILTIN(__builtin_arm_crc32cb, "UiUiUc", "nc")
+BUILTIN(__builtin_arm_crc32h, "UiUiUs", "nc")
+BUILTIN(__builtin_arm_crc32ch, "UiUiUs", "nc")
+BUILTIN(__builtin_arm_crc32w, "UiUiUi", "nc")
+BUILTIN(__builtin_arm_crc32cw, "UiUiUi", "nc")
+BUILTIN(__builtin_arm_crc32d, "UiUiLUi", "nc")
+BUILTIN(__builtin_arm_crc32cd, "UiUiLUi", "nc")
+
+// Memory barrier
+BUILTIN(__builtin_arm_dmb, "vUi", "nc")
+BUILTIN(__builtin_arm_dsb, "vUi", "nc")
+BUILTIN(__builtin_arm_isb, "vUi", "nc")
 
 #undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsARM.def b/include/clang/Basic/BuiltinsARM.def
index 21bb892..2e5eac6 100644
--- a/include/clang/Basic/BuiltinsARM.def
+++ b/include/clang/Basic/BuiltinsARM.def
@@ -14,6 +14,10 @@
 
 // The format of this database matches clang/Basic/Builtins.def.
 
+#if defined(BUILTIN) && !defined(LANGBUILTIN)
+#   define LANGBUILTIN(ID, TYPE, ATTRS, BUILTIN_LANG) BUILTIN(ID, TYPE, ATTRS)
+#endif
+
 // In libgcc
 BUILTIN(__clear_cache, "vv*v*", "i")
 BUILTIN(__builtin_thread_pointer, "v*", "")
@@ -24,12 +28,17 @@
 BUILTIN(__builtin_arm_ssat, "iiUi", "nc")
 BUILTIN(__builtin_arm_usat, "UiUiUi", "nc")
 
+// Bit manipulation
+BUILTIN(__builtin_arm_rbit, "UiUi", "nc")
+
 // Store and load exclusive
 BUILTIN(__builtin_arm_ldrexd, "LLUiv*", "")
 BUILTIN(__builtin_arm_strexd, "iLLUiv*", "")
 
 BUILTIN(__builtin_arm_ldrex, "v.", "t")
+BUILTIN(__builtin_arm_ldaex, "v.", "t")
 BUILTIN(__builtin_arm_strex, "i.", "t")
+BUILTIN(__builtin_arm_stlex, "i.", "t")
 BUILTIN(__builtin_arm_clrex, "v", "")
 
 // VFP
@@ -59,15 +68,33 @@
 BUILTIN(__builtin_arm_crc32cd, "UiUiLLUi", "nc")
 
 // HINT
+BUILTIN(__builtin_arm_nop, "v", "")
+BUILTIN(__builtin_arm_yield, "v", "")
+BUILTIN(__builtin_arm_wfe, "v", "")
+BUILTIN(__builtin_arm_wfi, "v", "")
+BUILTIN(__builtin_arm_sev, "v", "")
 BUILTIN(__builtin_arm_sevl, "v", "")
 
 // Data barrier
 BUILTIN(__builtin_arm_dmb, "vUi", "nc")
 BUILTIN(__builtin_arm_dsb, "vUi", "nc")
+BUILTIN(__builtin_arm_isb, "vUi", "nc")
 
-// NEON
-#define GET_NEON_BUILTINS
-#include "clang/Basic/arm_neon.inc"
-#undef GET_NEON_BUILTINS
+// MSVC
+LANGBUILTIN(__yield, "v", "", ALL_MS_LANGUAGES)
+LANGBUILTIN(__wfe, "v", "", ALL_MS_LANGUAGES)
+LANGBUILTIN(__wfi, "v", "", ALL_MS_LANGUAGES)
+LANGBUILTIN(__sev, "v", "", ALL_MS_LANGUAGES)
+LANGBUILTIN(__sevl, "v", "", ALL_MS_LANGUAGES)
+
+LANGBUILTIN(__dmb, "vUi", "nc", ALL_MS_LANGUAGES)
+LANGBUILTIN(__dsb, "vUi", "nc", ALL_MS_LANGUAGES)
+LANGBUILTIN(__isb, "vUi", "nc", ALL_MS_LANGUAGES)
+LANGBUILTIN(__ldrexd, "WiCDWi*", "", ALL_MS_LANGUAGES)
+LANGBUILTIN(_MoveFromCoprocessor, "UiUiUiUiUiUi", "", ALL_MS_LANGUAGES)
+LANGBUILTIN(_MoveFromCoprocessor2, "UiUiUiUiUiUi", "", ALL_MS_LANGUAGES)
+LANGBUILTIN(_MoveToCoprocessor, "vUiUiUiUiUiUi", "", ALL_MS_LANGUAGES)
+LANGBUILTIN(_MoveToCoprocessor2, "vUiUiUiUiUiUi", "", ALL_MS_LANGUAGES)
 
 #undef BUILTIN
+#undef LANGBUILTIN
diff --git a/include/clang/Basic/BuiltinsMips.def b/include/clang/Basic/BuiltinsMips.def
index e435d52..2d217f7 100644
--- a/include/clang/Basic/BuiltinsMips.def
+++ b/include/clang/Basic/BuiltinsMips.def
@@ -783,15 +783,15 @@
 BUILTIN(__builtin_msa_shf_h, "V8sV8sIUi", "nc")
 BUILTIN(__builtin_msa_shf_w, "V4iV4iIUi", "nc")
 
-BUILTIN(__builtin_msa_sld_b, "V16cV16cUi", "nc")
-BUILTIN(__builtin_msa_sld_h, "V8sV8sUi", "nc")
-BUILTIN(__builtin_msa_sld_w, "V4iV4iUi", "nc")
-BUILTIN(__builtin_msa_sld_d, "V2LLiV2LLiUi", "nc")
+BUILTIN(__builtin_msa_sld_b, "V16cV16cV16cUi", "nc")
+BUILTIN(__builtin_msa_sld_h, "V8sV8sV8sUi", "nc")
+BUILTIN(__builtin_msa_sld_w, "V4iV4iV4iUi", "nc")
+BUILTIN(__builtin_msa_sld_d, "V2LLiV2LLiV2LLiUi", "nc")
 
-BUILTIN(__builtin_msa_sldi_b, "V16cV16cIUi", "nc")
-BUILTIN(__builtin_msa_sldi_h, "V8sV8sIUi", "nc")
-BUILTIN(__builtin_msa_sldi_w, "V4iV4iIUi", "nc")
-BUILTIN(__builtin_msa_sldi_d, "V2LLiV2LLiIUi", "nc")
+BUILTIN(__builtin_msa_sldi_b, "V16cV16cV16cIUi", "nc")
+BUILTIN(__builtin_msa_sldi_h, "V8sV8sV8sIUi", "nc")
+BUILTIN(__builtin_msa_sldi_w, "V4iV4iV4iIUi", "nc")
+BUILTIN(__builtin_msa_sldi_d, "V2LLiV2LLiV2LLiIUi", "nc")
 
 BUILTIN(__builtin_msa_sll_b, "V16cV16cV16c", "nc")
 BUILTIN(__builtin_msa_sll_h, "V8sV8sV8s", "nc")
diff --git a/include/clang/Basic/BuiltinsNEON.def b/include/clang/Basic/BuiltinsNEON.def
new file mode 100644
index 0000000..7800ae6
--- /dev/null
+++ b/include/clang/Basic/BuiltinsNEON.def
@@ -0,0 +1,21 @@
+//===--- BuiltinsNEON.def - NEON Builtin function database ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the NEON-specific builtin function database.  Users of
+// this file must define the BUILTIN macro to make use of this information.
+//
+//===----------------------------------------------------------------------===//
+
+// The format of this database matches clang/Basic/Builtins.def.
+
+#define GET_NEON_BUILTINS
+#include "clang/Basic/arm_neon.inc"
+#undef GET_NEON_BUILTINS
+
+#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsR600.def b/include/clang/Basic/BuiltinsR600.def
new file mode 100644
index 0000000..49135cc
--- /dev/null
+++ b/include/clang/Basic/BuiltinsR600.def
@@ -0,0 +1,32 @@
+//==- BuiltinsR600.def - R600 Builtin function database ----------*- C++ -*-==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the R600-specific builtin function database. Users of this
+// file must define the BUILTIN macro to make use of this information.
+//
+//===----------------------------------------------------------------------===//
+
+// The format of this database matches clang/Basic/Builtins.def.
+
+BUILTIN(__builtin_amdgpu_div_scale, "dddbb*", "n")
+BUILTIN(__builtin_amdgpu_div_scalef, "fffbb*", "n")
+BUILTIN(__builtin_amdgpu_div_fmas, "dddd", "nc")
+BUILTIN(__builtin_amdgpu_div_fmasf, "ffff", "nc")
+BUILTIN(__builtin_amdgpu_div_fixup, "dddd", "nc")
+BUILTIN(__builtin_amdgpu_div_fixupf, "ffff", "nc")
+BUILTIN(__builtin_amdgpu_trig_preop, "ddi", "nc")
+BUILTIN(__builtin_amdgpu_trig_preopf, "ffi", "nc")
+BUILTIN(__builtin_amdgpu_rcp, "dd", "nc")
+BUILTIN(__builtin_amdgpu_rcpf, "ff", "nc")
+BUILTIN(__builtin_amdgpu_rsq, "dd", "nc")
+BUILTIN(__builtin_amdgpu_rsqf, "ff", "nc")
+BUILTIN(__builtin_amdgpu_rsq_clamped, "dd", "nc")
+BUILTIN(__builtin_amdgpu_rsq_clampedf, "ff", "nc")
+
+#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def
index 51397fa..1f377a8 100644
--- a/include/clang/Basic/BuiltinsX86.def
+++ b/include/clang/Basic/BuiltinsX86.def
@@ -59,6 +59,7 @@
 // All MMX instructions will be generated via builtins. Any MMX vector
 // types (<1 x i64>, <2 x i32>, etc.) that aren't used by these builtins will be
 // expanded by the back-end.
+BUILTIN(_mm_prefetch, "vcC*i", "nc")
 BUILTIN(__builtin_ia32_emms, "v", "")
 BUILTIN(__builtin_ia32_paddb, "V8cV8cV8c", "")
 BUILTIN(__builtin_ia32_paddw, "V4sV4sV4s", "")
@@ -452,9 +453,6 @@
 BUILTIN(__builtin_ia32_movmskps256, "iV8f", "")
 BUILTIN(__builtin_ia32_vzeroall, "v", "")
 BUILTIN(__builtin_ia32_vzeroupper, "v", "")
-BUILTIN(__builtin_ia32_vbroadcastss, "V4ffC*", "")
-BUILTIN(__builtin_ia32_vbroadcastsd256, "V4ddC*", "")
-BUILTIN(__builtin_ia32_vbroadcastss256, "V8ffC*", "")
 BUILTIN(__builtin_ia32_vbroadcastf128_pd256, "V4dV2dC*", "")
 BUILTIN(__builtin_ia32_vbroadcastf128_ps256, "V8fV4fC*", "")
 BUILTIN(__builtin_ia32_storeupd256, "vd*V4d", "")
@@ -759,5 +757,8 @@
 BUILTIN(__builtin_ia32_xend, "v", "")
 BUILTIN(__builtin_ia32_xabort, "vIc", "")
 BUILTIN(__builtin_ia32_xtest, "i", "")
+BUILTIN(__builtin_ia32_rdpmc, "ULLii", "")
+BUILTIN(__builtin_ia32_rdtsc, "ULLi", "")
+BUILTIN(__builtin_ia32_rdtscp, "ULLiUi*", "")
 
 #undef BUILTIN
diff --git a/include/clang/Basic/CMakeLists.txt b/include/clang/Basic/CMakeLists.txt
index 274b94d..e4929b5 100644
--- a/include/clang/Basic/CMakeLists.txt
+++ b/include/clang/Basic/CMakeLists.txt
@@ -28,7 +28,14 @@
   SOURCE Attr.td
   TARGET ClangAttrList)
 
+clang_tablegen(AttrHasAttributeImpl.inc -gen-clang-attr-has-attribute-impl
+  -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
+  SOURCE Attr.td
+  TARGET ClangAttrHasAttributeImpl
+  )
+
 # ARM NEON
 clang_tablegen(arm_neon.inc -gen-arm-neon-sema
+  -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
   SOURCE arm_neon.td
   TARGET ClangARMNeon)
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
index c057bdf..a7b2ba2 100644
--- a/include/clang/Basic/Diagnostic.h
+++ b/include/clang/Basic/Diagnostic.h
@@ -21,20 +21,23 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/Support/type_traits.h"
+#include "llvm/ADT/iterator_range.h"
 #include <list>
 #include <vector>
 
 namespace clang {
-  class DiagnosticConsumer;
+  class DeclContext;
   class DiagnosticBuilder;
+  class DiagnosticConsumer;
+  class DiagnosticErrorTrap;
   class DiagnosticOptions;
   class IdentifierInfo;
-  class DeclContext;
   class LangOptions;
   class Preprocessor;
-  class DiagnosticErrorTrap;
   class StoredDiagnostic;
+  namespace tok {
+  enum TokenKind : unsigned short;
+  }
 
 /// \brief Annotates a diagnostic with some code that should be
 /// inserted, removed, or replaced to fix the problem.
@@ -129,35 +132,34 @@
 /// the user. DiagnosticsEngine is tied to one translation unit and one
 /// SourceManager.
 class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
+  DiagnosticsEngine(const DiagnosticsEngine &) LLVM_DELETED_FUNCTION;
+  void operator=(const DiagnosticsEngine &) LLVM_DELETED_FUNCTION;
+
 public:
   /// \brief The level of the diagnostic, after it has been through mapping.
   enum Level {
     Ignored = DiagnosticIDs::Ignored,
     Note = DiagnosticIDs::Note,
+    Remark = DiagnosticIDs::Remark,
     Warning = DiagnosticIDs::Warning,
     Error = DiagnosticIDs::Error,
     Fatal = DiagnosticIDs::Fatal
   };
 
-  /// \brief How do we handle otherwise-unmapped extension?
-  ///
-  /// This is controlled by -pedantic and -pedantic-errors.
-  enum ExtensionHandling {
-    Ext_Ignore, Ext_Warn, Ext_Error
-  };
-
   enum ArgumentKind {
     ak_std_string,      ///< std::string
     ak_c_string,        ///< const char *
     ak_sint,            ///< int
     ak_uint,            ///< unsigned
+    ak_tokenkind,       ///< enum TokenKind : unsigned
     ak_identifierinfo,  ///< IdentifierInfo
     ak_qualtype,        ///< QualType
     ak_declarationname, ///< DeclarationName
     ak_nameddecl,       ///< NamedDecl *
     ak_nestednamespec,  ///< NestedNameSpecifier *
     ak_declcontext,     ///< DeclContext *
-    ak_qualtype_pair    ///< pair<QualType, QualType>
+    ak_qualtype_pair,   ///< pair<QualType, QualType>
+    ak_attr             ///< Attr *
   };
 
   /// \brief Represents on argument value, which is a union discriminated
@@ -181,7 +183,7 @@
                                    // 0 -> no limit.
   unsigned ConstexprBacktraceLimit; // Cap on depth of constexpr evaluation
                                     // backtrace stack, 0 -> no limit.
-  ExtensionHandling ExtBehavior; // Map extensions onto warnings or errors?
+  diag::Severity ExtBehavior;       // Map extensions to warnings or errors?
   IntrusiveRefCntPtr<DiagnosticIDs> Diags;
   IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
   DiagnosticConsumer *Client;
@@ -191,7 +193,7 @@
   /// \brief Mapping information for diagnostics.
   ///
   /// Mapping info is packed into four bits per diagnostic.  The low three
-  /// bits are the mapping (an instance of diag::Mapping), or zero if unset.
+  /// bits are the mapping (an instance of diag::Severity), or zero if unset.
   /// The high bit is set when the mapping was established as a user mapping.
   /// If the high bit is clear, then the low bits are set to the default
   /// value, and should be mapped with -pedantic, -Werror, etc.
@@ -200,19 +202,18 @@
   /// the state so that we know what is the diagnostic state at any given
   /// source location.
   class DiagState {
-    llvm::DenseMap<unsigned, DiagnosticMappingInfo> DiagMap;
+    llvm::DenseMap<unsigned, DiagnosticMapping> DiagMap;
 
   public:
-    typedef llvm::DenseMap<unsigned, DiagnosticMappingInfo>::iterator
-      iterator;
-    typedef llvm::DenseMap<unsigned, DiagnosticMappingInfo>::const_iterator
-      const_iterator;
+    typedef llvm::DenseMap<unsigned, DiagnosticMapping>::iterator iterator;
+    typedef llvm::DenseMap<unsigned, DiagnosticMapping>::const_iterator
+    const_iterator;
 
-    void setMappingInfo(diag::kind Diag, DiagnosticMappingInfo Info) {
+    void setMapping(diag::kind Diag, DiagnosticMapping Info) {
       DiagMap[Diag] = Info;
     }
 
-    DiagnosticMappingInfo &getOrAddMappingInfo(diag::kind Diag);
+    DiagnosticMapping &getOrAddMapping(diag::kind Diag);
 
     const_iterator begin() const { return DiagMap.begin(); }
     const_iterator end() const { return DiagMap.end(); }
@@ -308,17 +309,15 @@
   ///
   /// This takes the modifiers and argument that was present in the diagnostic.
   ///
-  /// The PrevArgs array (whose length is NumPrevArgs) indicates the previous
-  /// arguments formatted for this diagnostic.  Implementations of this function
-  /// can use this information to avoid redundancy across arguments.
+  /// The PrevArgs array indicates the previous arguments formatted for this
+  /// diagnostic.  Implementations of this function can use this information to
+  /// avoid redundancy across arguments.
   ///
   /// This is a hack to avoid a layering violation between libbasic and libsema.
   typedef void (*ArgToStringFnTy)(
       ArgumentKind Kind, intptr_t Val,
-      const char *Modifier, unsigned ModifierLen,
-      const char *Argument, unsigned ArgumentLen,
-      const ArgumentValue *PrevArgs,
-      unsigned NumPrevArgs,
+      StringRef Modifier, StringRef Argument,
+      ArrayRef<ArgumentValue> PrevArgs,
       SmallVectorImpl<char> &Output,
       void *Cookie,
       ArrayRef<intptr_t> QualTypeVals);
@@ -336,11 +335,18 @@
   /// \brief Second string argument for the delayed diagnostic.
   std::string DelayedDiagArg2;
 
+  /// \brief Optional flag value.
+  ///
+  /// Some flags accept values, for instance: -Wframe-larger-than=<value> and
+  /// -Rpass=<value>. The content of this string is emitted after the flag name
+  /// and '='.
+  std::string FlagValue;
+
 public:
   explicit DiagnosticsEngine(
                       const IntrusiveRefCntPtr<DiagnosticIDs> &Diags,
                       DiagnosticOptions *DiagOpts,
-                      DiagnosticConsumer *client = 0,
+                      DiagnosticConsumer *client = nullptr,
                       bool ShouldOwnClient = true);
   ~DiagnosticsEngine();
 
@@ -351,6 +357,14 @@
   /// \brief Retrieve the diagnostic options.
   DiagnosticOptions &getDiagnosticOptions() const { return *DiagOpts; }
 
+  typedef llvm::iterator_range<DiagState::const_iterator> diag_mapping_range;
+
+  /// \brief Get the current set of diagnostic mappings.
+  diag_mapping_range getDiagnosticMappings() const {
+    const DiagState &DS = *GetCurDiagState();
+    return diag_mapping_range(DS.begin(), DS.end());
+  }
+
   DiagnosticConsumer *getClient() { return Client; }
   const DiagnosticConsumer *getClient() const { return Client; }
 
@@ -364,7 +378,7 @@
     return Client;
   }
 
-  bool hasSourceManager() const { return SourceMgr != 0; }
+  bool hasSourceManager() const { return SourceMgr != nullptr; }
   SourceManager &getSourceManager() const {
     assert(SourceMgr && "SourceManager not set!");
     return *SourceMgr;
@@ -501,10 +515,8 @@
   /// mapped onto ignore/warning/error. 
   ///
   /// This corresponds to the GCC -pedantic and -pedantic-errors option.
-  void setExtensionHandlingBehavior(ExtensionHandling H) {
-    ExtBehavior = H;
-  }
-  ExtensionHandling getExtensionHandlingBehavior() const { return ExtBehavior; }
+  void setExtensionHandlingBehavior(diag::Severity H) { ExtBehavior = H; }
+  diag::Severity getExtensionHandlingBehavior() const { return ExtBehavior; }
 
   /// \brief Counter bumped when an __extension__  block is/ encountered.
   ///
@@ -522,8 +534,7 @@
   ///
   /// \param Loc The source location that this change of diagnostic state should
   /// take affect. It can be null if we are setting the latest state.
-  void setDiagnosticMapping(diag::kind Diag, diag::Mapping Map,
-                            SourceLocation Loc);
+  void setSeverity(diag::kind Diag, diag::Severity Map, SourceLocation Loc);
 
   /// \brief Change an entire diagnostic group (e.g. "unknown-pragmas") to
   /// have the specified mapping.
@@ -531,15 +542,14 @@
   /// \returns true (and ignores the request) if "Group" was unknown, false
   /// otherwise.
   ///
+  /// \param Flavor The flavor of group to affect. -Rfoo does not affect the
+  /// state of the -Wfoo group and vice versa.
+  ///
   /// \param Loc The source location that this change of diagnostic state should
   /// take affect. It can be null if we are setting the state from command-line.
-  bool setDiagnosticGroupMapping(StringRef Group, diag::Mapping Map,
-                                 SourceLocation Loc = SourceLocation());
-
-  /// \brief Set the warning-as-error flag for the given diagnostic.
-  ///
-  /// This function always only operates on the current diagnostic state.
-  void setDiagnosticWarningAsError(diag::kind Diag, bool Enabled);
+  bool setSeverityForGroup(diag::Flavor Flavor, StringRef Group,
+                           diag::Severity Map,
+                           SourceLocation Loc = SourceLocation());
 
   /// \brief Set the warning-as-error flag for the given diagnostic group.
   ///
@@ -548,11 +558,6 @@
   /// \returns True if the given group is unknown, false otherwise.
   bool setDiagnosticGroupWarningAsError(StringRef Group, bool Enabled);
 
-  /// \brief Set the error-as-fatal flag for the given diagnostic.
-  ///
-  /// This function always only operates on the current diagnostic state.
-  void setDiagnosticErrorAsFatal(diag::kind Diag, bool Enabled);
-
   /// \brief Set the error-as-fatal flag for the given diagnostic group.
   ///
   /// This function always only operates on the current diagnostic state.
@@ -560,12 +565,13 @@
   /// \returns True if the given group is unknown, false otherwise.
   bool setDiagnosticGroupErrorAsFatal(StringRef Group, bool Enabled);
 
-  /// \brief Add the specified mapping to all diagnostics.
+  /// \brief Add the specified mapping to all diagnostics of the specified
+  /// flavor.
   ///
   /// Mainly to be used by -Wno-everything to disable all warnings but allow
   /// subsequent -W options to enable specific warnings.
-  void setMappingToAllDiagnostics(diag::Mapping Map,
-                                  SourceLocation Loc = SourceLocation());
+  void setSeverityForAll(diag::Flavor Flavor, diag::Severity Map,
+                         SourceLocation Loc = SourceLocation());
 
   bool hasErrorOccurred() const { return ErrorOccurred; }
 
@@ -587,25 +593,29 @@
     this->NumWarnings = NumWarnings;
   }
 
-  /// \brief Return an ID for a diagnostic with the specified message and level.
+  /// \brief Return an ID for a diagnostic with the specified format string and
+  /// level.
   ///
   /// If this is the first request for this diagnostic, it is registered and
   /// created, otherwise the existing ID is returned.
-  unsigned getCustomDiagID(Level L, StringRef Message) {
-    return Diags->getCustomDiagID((DiagnosticIDs::Level)L, Message);
+  ///
+  /// \param FormatString A fixed diagnostic format string that will be hashed
+  /// and mapped to a unique DiagID.
+  template <unsigned N>
+  unsigned getCustomDiagID(Level L, const char (&FormatString)[N]) {
+    return Diags->getCustomDiagID((DiagnosticIDs::Level)L,
+                                  StringRef(FormatString, N - 1));
   }
 
   /// \brief Converts a diagnostic argument (as an intptr_t) into the string
   /// that represents it.
   void ConvertArgToString(ArgumentKind Kind, intptr_t Val,
-                          const char *Modifier, unsigned ModLen,
-                          const char *Argument, unsigned ArgLen,
-                          const ArgumentValue *PrevArgs, unsigned NumPrevArgs,
+                          StringRef Modifier, StringRef Argument,
+                          ArrayRef<ArgumentValue> PrevArgs,
                           SmallVectorImpl<char> &Output,
                           ArrayRef<intptr_t> QualTypeVals) const {
-    ArgToStringFn(Kind, Val, Modifier, ModLen, Argument, ArgLen,
-                  PrevArgs, NumPrevArgs, Output, ArgToStringCookie,
-                  QualTypeVals);
+    ArgToStringFn(Kind, Val, Modifier, Argument, PrevArgs, Output,
+                  ArgToStringCookie, QualTypeVals);
   }
 
   void SetArgToStringFn(ArgToStringFnTy Fn, void *Cookie) {
@@ -627,10 +637,27 @@
   // DiagnosticsEngine classification and reporting interfaces.
   //
 
+  /// \brief Determine whether the diagnostic is known to be ignored.
+  ///
+  /// This can be used to opportunistically avoid expensive checks when it's
+  /// known for certain that the diagnostic has been suppressed at the
+  /// specified location \p Loc.
+  ///
+  /// \param Loc The source location we are interested in finding out the
+  /// diagnostic state. Can be null in order to query the latest state.
+  bool isIgnored(unsigned DiagID, SourceLocation Loc) const {
+    return Diags->getDiagnosticSeverity(DiagID, Loc, *this) ==
+           diag::Severity::Ignored;
+  }
+
   /// \brief Based on the way the client configured the DiagnosticsEngine
   /// object, classify the specified diagnostic ID into a Level, consumable by
   /// the DiagnosticConsumer.
   ///
+  /// To preserve invariant assumptions, this function should not be used to
+  /// influence parse or semantic analysis actions. Instead consider using
+  /// \c isIgnored().
+  ///
   /// \param Loc The source location we are interested in finding out the
   /// diagnostic state. Can be null in order to query the latest state.
   Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc) const {
@@ -680,6 +707,9 @@
   /// \brief Clear out the current diagnostic.
   void Clear() { CurDiagID = ~0U; }
 
+  /// \brief Return the value associated with this diagnostic flag.
+  StringRef getFlagValue() const { return FlagValue; }
+
 private:
   /// \brief Report the delayed diagnostic.
   void ReportDelayed();
@@ -711,20 +741,10 @@
     /// diagnostic with more than that almost certainly has to be simplified
     /// anyway.
     MaxArguments = 10,
-
-    /// \brief The maximum number of ranges we can hold.
-    MaxRanges = 10,
-
-    /// \brief The maximum number of ranges we can hold.
-    MaxFixItHints = 10
   };
 
   /// \brief The number of entries in Arguments.
   signed char NumDiagArgs;
-  /// \brief The number of ranges in the DiagRanges array.
-  unsigned char NumDiagRanges;
-  /// \brief The number of hints in the DiagFixItHints array.
-  unsigned char NumDiagFixItHints;
 
   /// \brief Specifies whether an argument is in DiagArgumentsStr or
   /// in DiagArguments.
@@ -747,25 +767,25 @@
   intptr_t DiagArgumentsVal[MaxArguments];
 
   /// \brief The list of ranges added to this diagnostic.
-  CharSourceRange DiagRanges[MaxRanges];
+  SmallVector<CharSourceRange, 8> DiagRanges;
 
   /// \brief If valid, provides a hint with some code to insert, remove,
   /// or modify at a particular position.
-  FixItHint DiagFixItHints[MaxFixItHints];
+  SmallVector<FixItHint, 8> DiagFixItHints;
 
-  DiagnosticMappingInfo makeMappingInfo(diag::Mapping Map, SourceLocation L) {
+  DiagnosticMapping makeUserMapping(diag::Severity Map, SourceLocation L) {
     bool isPragma = L.isValid();
-    DiagnosticMappingInfo MappingInfo = DiagnosticMappingInfo::Make(
-      Map, /*IsUser=*/true, isPragma);
+    DiagnosticMapping Mapping =
+        DiagnosticMapping::Make(Map, /*IsUser=*/true, isPragma);
 
     // If this is a pragma mapping, then set the diagnostic mapping flags so
     // that we override command line options.
     if (isPragma) {
-      MappingInfo.setNoWarningAsError(true);
-      MappingInfo.setNoErrorAsFatal(true);
+      Mapping.setNoWarningAsError(true);
+      Mapping.setNoErrorAsFatal(true);
     }
 
-    return MappingInfo;
+    return Mapping;
   }
 
   /// \brief Used to report a diagnostic that is finally fully formed.
@@ -848,7 +868,7 @@
 /// for example.
 class DiagnosticBuilder {
   mutable DiagnosticsEngine *DiagObj;
-  mutable unsigned NumArgs, NumRanges, NumFixits;
+  mutable unsigned NumArgs;
 
   /// \brief Status variable indicating if this diagnostic is still active.
   ///
@@ -863,15 +883,15 @@
 
   void operator=(const DiagnosticBuilder &) LLVM_DELETED_FUNCTION;
   friend class DiagnosticsEngine;
-  
+
   DiagnosticBuilder()
-    : DiagObj(0), NumArgs(0), NumRanges(0), NumFixits(0), IsActive(false),
-      IsForceEmit(false) { }
+      : DiagObj(nullptr), NumArgs(0), IsActive(false), IsForceEmit(false) {}
 
   explicit DiagnosticBuilder(DiagnosticsEngine *diagObj)
-    : DiagObj(diagObj), NumArgs(0), NumRanges(0), NumFixits(0), IsActive(true),
-      IsForceEmit(false) {
+      : DiagObj(diagObj), NumArgs(0), IsActive(true), IsForceEmit(false) {
     assert(diagObj && "DiagnosticBuilder requires a valid DiagnosticsEngine!");
+    diagObj->DiagRanges.clear();
+    diagObj->DiagFixItHints.clear();
   }
 
   friend class PartialDiagnostic;
@@ -879,13 +899,11 @@
 protected:
   void FlushCounts() {
     DiagObj->NumDiagArgs = NumArgs;
-    DiagObj->NumDiagRanges = NumRanges;
-    DiagObj->NumDiagFixItHints = NumFixits;
   }
 
   /// \brief Clear out the current diagnostic.
   void Clear() const {
-    DiagObj = 0;
+    DiagObj = nullptr;
     IsActive = false;
     IsForceEmit = false;
   }
@@ -927,8 +945,6 @@
     IsForceEmit = D.IsForceEmit;
     D.Clear();
     NumArgs = D.NumArgs;
-    NumRanges = D.NumRanges;
-    NumFixits = D.NumFixits;
   }
 
   /// \brief Retrieve an empty diagnostic builder.
@@ -974,27 +990,32 @@
 
   void AddSourceRange(const CharSourceRange &R) const {
     assert(isActive() && "Clients must not add to cleared diagnostic!");
-    assert(NumRanges < DiagnosticsEngine::MaxRanges &&
-           "Too many arguments to diagnostic!");
-    DiagObj->DiagRanges[NumRanges++] = R;
+    DiagObj->DiagRanges.push_back(R);
   }
 
   void AddFixItHint(const FixItHint &Hint) const {
     assert(isActive() && "Clients must not add to cleared diagnostic!");
-    assert(NumFixits < DiagnosticsEngine::MaxFixItHints &&
-           "Too many arguments to diagnostic!");
-    DiagObj->DiagFixItHints[NumFixits++] = Hint;
+    DiagObj->DiagFixItHints.push_back(Hint);
   }
 
-  bool hasMaxRanges() const {
-    return NumRanges == DiagnosticsEngine::MaxRanges;
-  }
-
-  bool hasMaxFixItHints() const {
-    return NumFixits == DiagnosticsEngine::MaxFixItHints;
-  }
+  void addFlagValue(StringRef V) const { DiagObj->FlagValue = V; }
 };
 
+struct AddFlagValue {
+  explicit AddFlagValue(StringRef V) : Val(V) {}
+  StringRef Val;
+};
+
+/// \brief Register a value for the flag in the current diagnostic. This
+/// value will be shown as the suffix "=value" after the flag name. It is
+/// useful in cases where the diagnostic flag accepts values (e.g.,
+/// -Rpass or -Wframe-larger-than).
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                           const AddFlagValue V) {
+  DB.addFlagValue(V.Val);
+  return DB;
+}
+
 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
                                            StringRef S) {
   DB.AddString(S);
@@ -1013,7 +1034,13 @@
   return DB;
 }
 
-inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,bool I) {
+// We use enable_if here to prevent that this overload is selected for
+// pointers or other arguments that are implicitly convertible to bool.
+template <typename T>
+inline
+typename std::enable_if<std::is_same<T, bool>::value,
+                        const DiagnosticBuilder &>::type
+operator<<(const DiagnosticBuilder &DB, T I) {
   DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint);
   return DB;
 }
@@ -1025,6 +1052,12 @@
 }
 
 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                           tok::TokenKind I) {
+  DB.AddTaggedVal(static_cast<unsigned>(I), DiagnosticsEngine::ak_tokenkind);
+  return DB;
+}
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
                                            const IdentifierInfo *II) {
   DB.AddTaggedVal(reinterpret_cast<intptr_t>(II),
                   DiagnosticsEngine::ak_identifierinfo);
@@ -1037,14 +1070,14 @@
 // match.
 template<typename T>
 inline
-typename llvm::enable_if<llvm::is_same<T, DeclContext>, 
-                         const DiagnosticBuilder &>::type
+typename std::enable_if<std::is_same<T, DeclContext>::value,
+                        const DiagnosticBuilder &>::type
 operator<<(const DiagnosticBuilder &DB, T *DC) {
   DB.AddTaggedVal(reinterpret_cast<intptr_t>(DC),
                   DiagnosticsEngine::ak_declcontext);
   return DB;
 }
-  
+
 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
                                            const SourceRange &R) {
   DB.AddSourceRange(CharSourceRange::getTokenRange(R));
@@ -1052,11 +1085,18 @@
 }
 
 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                           ArrayRef<SourceRange> Ranges) {
+  for (const SourceRange &R: Ranges)
+    DB.AddSourceRange(CharSourceRange::getTokenRange(R));
+  return DB;
+}
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
                                            const CharSourceRange &R) {
   DB.AddSourceRange(R);
   return DB;
 }
-  
+
 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
                                            const FixItHint &Hint) {
   if (!Hint.isNull())
@@ -1065,12 +1105,14 @@
 }
 
 inline DiagnosticBuilder DiagnosticsEngine::Report(SourceLocation Loc,
-                                            unsigned DiagID){
+                                                   unsigned DiagID) {
   assert(CurDiagID == ~0U && "Multiple diagnostics in flight at once!");
   CurDiagLoc = Loc;
   CurDiagID = DiagID;
+  FlagValue.clear();
   return DiagnosticBuilder(this);
 }
+
 inline DiagnosticBuilder DiagnosticsEngine::Report(unsigned DiagID) {
   return Report(SourceLocation(), DiagID);
 }
@@ -1159,22 +1201,22 @@
 
   /// \brief Return the number of source ranges associated with this diagnostic.
   unsigned getNumRanges() const {
-    return DiagObj->NumDiagRanges;
+    return DiagObj->DiagRanges.size();
   }
 
   /// \pre Idx < getNumRanges()
   const CharSourceRange &getRange(unsigned Idx) const {
-    assert(Idx < DiagObj->NumDiagRanges && "Invalid diagnostic range index!");
+    assert(Idx < getNumRanges() && "Invalid diagnostic range index!");
     return DiagObj->DiagRanges[Idx];
   }
 
   /// \brief Return an array reference for this diagnostic's ranges.
   ArrayRef<CharSourceRange> getRanges() const {
-    return llvm::makeArrayRef(DiagObj->DiagRanges, DiagObj->NumDiagRanges);
+    return DiagObj->DiagRanges;
   }
 
   unsigned getNumFixItHints() const {
-    return DiagObj->NumDiagFixItHints;
+    return DiagObj->DiagFixItHints.size();
   }
 
   const FixItHint &getFixItHint(unsigned Idx) const {
@@ -1182,8 +1224,8 @@
     return DiagObj->DiagFixItHints[Idx];
   }
 
-  const FixItHint *getFixItHints() const {
-    return getNumFixItHints()? DiagObj->DiagFixItHints : 0;
+  ArrayRef<FixItHint> getFixItHints() const {
+    return DiagObj->DiagFixItHints;
   }
 
   /// \brief Format this diagnostic into a string, substituting the
@@ -1279,7 +1321,7 @@
   /// \param PP The preprocessor object being used for the source; this is 
   /// optional, e.g., it may not be present when processing AST source files.
   virtual void BeginSourceFile(const LangOptions &LangOpts,
-                               const Preprocessor *PP = 0) {}
+                               const Preprocessor *PP = nullptr) {}
 
   /// \brief Callback to inform the diagnostic client that processing
   /// of a source file has ended.
@@ -1312,7 +1354,7 @@
 class IgnoringDiagConsumer : public DiagnosticConsumer {
   virtual void anchor();
   void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
-                        const Diagnostic &Info) {
+                        const Diagnostic &Info) override {
     // Just ignore it.
   }
 };
@@ -1328,11 +1370,11 @@
 
   virtual ~ForwardingDiagnosticConsumer();
 
-  virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
-                                const Diagnostic &Info);
-  virtual void clear();
+  void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+                        const Diagnostic &Info) override;
+  void clear() override;
 
-  virtual bool IncludeInDiagnosticCounts() const;
+  bool IncludeInDiagnosticCounts() const override;
 };
 
 // Struct used for sending info about how a type should be printed.
@@ -1351,6 +1393,13 @@
 /// attribute.  The character itself will be not be printed.
 const char ToggleHighlight = 127;
 
+
+/// ProcessWarningOptions - Initialize the diagnostic client and process the
+/// warning options specified on the command line.
+void ProcessWarningOptions(DiagnosticsEngine &Diags,
+                           const DiagnosticOptions &Opts,
+                           bool ReportDiags = true);
+
 }  // end namespace clang
 
 #endif
diff --git a/include/clang/Basic/Diagnostic.td b/include/clang/Basic/Diagnostic.td
index 2616548..48cbf09 100644
--- a/include/clang/Basic/Diagnostic.td
+++ b/include/clang/Basic/Diagnostic.td
@@ -12,16 +12,20 @@
 //
 //===----------------------------------------------------------------------===//
 
-// Define the diagnostic mappings.
-class DiagMapping;
-def MAP_IGNORE  : DiagMapping;
-def MAP_WARNING : DiagMapping;
-def MAP_ERROR   : DiagMapping;
-def MAP_FATAL   : DiagMapping;
+// Define the diagnostic severities.
+class Severity<string N> {
+  string Name = N;
+}
+def SEV_Ignored : Severity<"Ignored">;
+def SEV_Remark  : Severity<"Remark">;
+def SEV_Warning : Severity<"Warning">;
+def SEV_Error   : Severity<"Error">;
+def SEV_Fatal   : Severity<"Fatal">;
 
 // Define the diagnostic classes.
 class DiagClass;
 def CLASS_NOTE      : DiagClass;
+def CLASS_REMARK    : DiagClass;
 def CLASS_WARNING   : DiagClass;
 def CLASS_EXTENSION : DiagClass;
 def CLASS_ERROR     : DiagClass;
@@ -57,7 +61,7 @@
 
 
 // All diagnostics emitted by the compiler are an indirect subclass of this.
-class Diagnostic<string text, DiagClass DC, DiagMapping defaultmapping> {
+class Diagnostic<string text, DiagClass DC, Severity defaultmapping> {
   /// Component is specified by the file with a big let directive.
   string         Component = ?;
   string         Text = text;
@@ -65,8 +69,8 @@
   SFINAEResponse SFINAE = SFINAE_Suppress;
   bit            AccessControl = 0;
   bit            WarningNoWerror = 0;
-  bit            WarningShowInSystemHeader = 0;
-  DiagMapping    DefaultMapping = defaultmapping;
+  bit            ShowInSystemHeader = 0;
+  Severity       DefaultSeverity = defaultmapping;
   DiagGroup      Group;
   string         CategoryName = "";
 }
@@ -81,24 +85,33 @@
   SFINAEResponse SFINAE = SFINAE_AccessControl;
 }
 
+class ShowInSystemHeader {
+  bit ShowInSystemHeader = 1;
+}
+
+class SuppressInSystemHeader {
+  bit ShowInSystemHeader = 0;
+}
+
 // FIXME: ExtWarn and Extension should also be SFINAEFailure by default.
-class Error<string str>     : Diagnostic<str, CLASS_ERROR, MAP_ERROR>, SFINAEFailure;
-class Warning<string str>   : Diagnostic<str, CLASS_WARNING, MAP_WARNING>;
-class Extension<string str> : Diagnostic<str, CLASS_EXTENSION, MAP_IGNORE>;
-class ExtWarn<string str>   : Diagnostic<str, CLASS_EXTENSION, MAP_WARNING>;
-class Note<string str>      : Diagnostic<str, CLASS_NOTE, MAP_FATAL/*ignored*/>;
+class Error<string str>     : Diagnostic<str, CLASS_ERROR, SEV_Error>, SFINAEFailure {
+  bit ShowInSystemHeader = 1;
+}
+class Warning<string str>   : Diagnostic<str, CLASS_WARNING, SEV_Warning>;
+class Remark<string str>    : Diagnostic<str, CLASS_REMARK, SEV_Ignored>;
+class Extension<string str> : Diagnostic<str, CLASS_EXTENSION, SEV_Ignored>;
+class ExtWarn<string str>   : Diagnostic<str, CLASS_EXTENSION, SEV_Warning>;
+class Note<string str>      : Diagnostic<str, CLASS_NOTE, SEV_Fatal/*ignored*/>;
 
 
-class DefaultIgnore { DiagMapping DefaultMapping = MAP_IGNORE; }
-class DefaultWarn   { DiagMapping DefaultMapping = MAP_WARNING; }
-class DefaultError  { DiagMapping DefaultMapping = MAP_ERROR; }
-class DefaultFatal  { DiagMapping DefaultMapping = MAP_FATAL; }
+class DefaultIgnore { Severity DefaultSeverity = SEV_Ignored; }
+class DefaultWarn   { Severity DefaultSeverity = SEV_Warning; }
+class DefaultError  { Severity DefaultSeverity = SEV_Error; }
+class DefaultFatal  { Severity DefaultSeverity = SEV_Fatal; }
 class DefaultWarnNoWerror {
   bit WarningNoWerror = 1;
 }
-class DefaultWarnShowInSystemHeader {
-  bit WarningShowInSystemHeader = 1;
-}
+class DefaultRemark { Severity DefaultSeverity = SEV_Remark; }
 
 // Definitions for Diagnostics.
 include "DiagnosticASTKinds.td"
diff --git a/include/clang/Basic/DiagnosticASTKinds.td b/include/clang/Basic/DiagnosticASTKinds.td
index 113e564..8d5a1c7 100644
--- a/include/clang/Basic/DiagnosticASTKinds.td
+++ b/include/clang/Basic/DiagnosticASTKinds.td
@@ -89,6 +89,9 @@
   "constexpr evaluation hit maximum call limit">;
 def note_constexpr_step_limit_exceeded : Note<
   "constexpr evaluation hit maximum step limit; possible infinite loop?">;
+def note_constexpr_this : Note<
+  "%select{|implicit }0use of 'this' pointer is only allowed within the "
+  "evaluation of a call to a 'constexpr' member function">;
 def note_constexpr_lifetime_ended : Note<
   "%select{read of|assignment to|increment of|decrement of}0 "
   "%select{temporary|variable}1 whose lifetime has ended">;
@@ -138,6 +141,7 @@
   "(skipping %0 call%s0 in backtrace; use -fconstexpr-backtrace-limit=0 to "
   "see all)">;
 def note_constexpr_call_here : Note<"in call to '%0'">;
+
 def warn_integer_constant_overflow : Warning<
   "overflow in expression; result is %0 with type %1">,
   InGroup<DiagGroup<"integer-overflow">>;
diff --git a/include/clang/Basic/DiagnosticCategories.td b/include/clang/Basic/DiagnosticCategories.td
index a02fbdf..37b8569 100644
--- a/include/clang/Basic/DiagnosticCategories.td
+++ b/include/clang/Basic/DiagnosticCategories.td
@@ -8,3 +8,4 @@
 //===----------------------------------------------------------------------===//
 
 class CatInlineAsm : DiagCategory<"Inline Assembly Issue">;
+class CatBackend : DiagCategory<"Backend Issue">;
diff --git a/include/clang/Basic/DiagnosticCommentKinds.td b/include/clang/Basic/DiagnosticCommentKinds.td
index 49781fe..6dc8b27 100644
--- a/include/clang/Basic/DiagnosticCommentKinds.td
+++ b/include/clang/Basic/DiagnosticCommentKinds.td
@@ -11,7 +11,7 @@
 let CategoryName = "Documentation Issue" in {
 
 // HTML parsing errors.  These are under -Wdocumentation to make sure the user
-// knows that we didn't parse something as he might expect.
+// knows that we didn't parse something as they might expect.
 
 def warn_doc_html_start_tag_expected_quoted_string : Warning<
   "expected quoted string after equals sign">,
@@ -41,6 +41,10 @@
 def note_doc_html_end_tag : Note<
   "end tag">;
 
+def warn_doc_html_missing_end_tag : Warning<
+  "HTML tag '%0' requires an end tag">,
+  InGroup<DocumentationHTML>, DefaultIgnore;
+
 // Commands
 
 def warn_doc_block_command_empty_paragraph : Warning<
diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td
index c54bafc..b3c77b8 100644
--- a/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/include/clang/Basic/DiagnosticCommonKinds.td
@@ -30,7 +30,7 @@
   "definition of %0 is not complete until the closing '}'">;
 /// note_matching - this is used as a continuation of a previous diagnostic,
 /// e.g. to specify the '(' when we expected a ')'.
-def note_matching : Note<"to match this '%0'">;
+def note_matching : Note<"to match this %0">;
 
 def note_using : Note<"using">;
 def note_possibility : Note<"one possibility">;
@@ -40,7 +40,6 @@
 
 let CategoryName = "Lexical or Preprocessor Issue" in {
 
-def err_expected_colon : Error<"expected ':'">;
 def err_expected_colon_after_setter_name : Error<
   "method name referenced in property setter attribute "
   "must end with ':'">;
@@ -60,6 +59,10 @@
 
 let CategoryName = "Parse Issue" in {
 
+def err_expected : Error<"expected %0">;
+def err_expected_either : Error<"expected %0 or %1">;
+def err_expected_after : Error<"expected %1 after %0">;
+
 def err_param_redefinition : Error<"redefinition of parameter %0">;
 def warn_method_param_redefinition : Warning<"redefinition of method parameter %0">;
 def warn_method_param_declaration : Warning<"redeclaration of method parameter %0">,
@@ -101,8 +104,9 @@
   InGroup<CXX98CompatPedantic>, DefaultIgnore;
 def err_integer_too_large : Error<
   "integer constant is larger than the largest unsigned integer type">;
-def warn_integer_too_large_for_signed : Warning<
-  "integer constant is larger than the largest signed integer type">;
+def ext_integer_too_large_for_signed : ExtWarn<
+  "integer constant is larger than the largest signed integer type">,
+  InGroup<DiagGroup<"implicitly-unsigned-literal">>;
 
 // Sema && AST
 def note_invalid_subexpr_in_const_expr : Note<
@@ -114,7 +118,6 @@
   "unknown target triple '%0', please use -triple or -arch">;
 def err_target_unknown_cpu : Error<"unknown target CPU '%0'">;
 def err_target_unknown_abi : Error<"unknown target ABI '%0'">;
-def err_target_unknown_cxxabi : Error<"unknown C++ ABI '%0'">;
 def err_target_unknown_fpmath : Error<"unknown FP unit '%0'">;
 def err_target_unsupported_fpmath : Error<
     "the '%0' unit is not supported with this instruction set">;
@@ -133,4 +136,14 @@
 // Modules
 def err_module_file_conflict : Error<"module '%0' found in both '%1' and '%2'">;
 
+// TransformActions
+// TODO: Use a custom category name to distinguish rewriter errors.
+def err_mt_message : Error<"[rewriter] %0">, SuppressInSystemHeader;
+def warn_mt_message : Warning<"[rewriter] %0">;
+def note_mt_message : Note<"[rewriter] %0">;
+
+// ARCMigrate
+def warn_arcmt_nsalloc_realloc : Warning<"[rewriter] call returns pointer to GC managed memory; it will become unmanaged in ARC">;
+def err_arcmt_nsinvocation_ownership : Error<"NSInvocation's %0 is not safe to be used with an object with ownership other than __unsafe_unretained">;
+
 }
diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td
index 76d8c4a..cd26a6a 100644
--- a/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/include/clang/Basic/DiagnosticDriverKinds.td
@@ -17,9 +17,13 @@
   "unsupported argument '%1' to option '%0'">;
 def err_drv_unknown_stdin_type : Error<
   "-E or -x required when input is from standard input">;
+def err_drv_unknown_stdin_type_clang_cl : Error<
+  "use /Tc or /Tp to set input type for standard input">;
 def err_drv_unknown_language : Error<"language not recognized: '%0'">;
 def err_drv_invalid_arch_name : Error<
   "invalid arch name '%0'">;
+def err_drv_invalid_linker_name : Error<
+  "invalid linker name in argument '%0'">;
 def err_drv_invalid_rtlib_name : Error<
   "invalid runtime library name in argument '%0'">;
 def err_drv_unsupported_rtlib_for_platform : Error<
@@ -35,8 +39,8 @@
   "cannot specify -o when generating multiple output files">;
 def err_drv_out_file_argument_with_multiple_sources : Error<
   "cannot specify '%0%1' when compiling multiple source files">;
-def err_no_external_windows_assembler : Error<
-  "there is no external assembler we can use on windows">;
+def err_no_external_assembler : Error<
+  "there is no external assembler that can be used on this platform">;
 def err_drv_unable_to_remove_file : Error<
   "unable to remove file: %0">;
 def err_drv_command_failure : Error<
@@ -80,6 +84,9 @@
 def err_drv_malformed_sanitizer_blacklist : Error<
   "malformed sanitizer blacklist: '%0'">;
 
+def err_target_unsupported_arch
+  : Error<"the target architecture '%0' is not supported by the target '%1'">;
+
 def err_drv_I_dash_not_supported : Error<
   "'%0' not supported, please use -iquote instead">;
 def err_drv_unknown_argument : Error<"unknown argument: '%0'">;
@@ -109,11 +116,14 @@
   "unknown or ill-formed Objective-C runtime '%0'">;
 def err_drv_emit_llvm_link : Error<
    "-emit-llvm cannot be used when linking">;
-def err_drv_unknown_toolchain : Error<
-  "cannot recognize the type of the toolchain">;
+def err_drv_optimization_remark_pattern : Error<
+  "%0 in '%1'">;
+def err_drv_no_neon_modifier : Error<"[no]neon is not accepted as modifier, please use [no]simd instead">;
 
 def warn_O4_is_O3 : Warning<"-O4 is equivalent to -O3">, InGroup<Deprecated>;
-def warn_drv_optimization_value : Warning<"optimization level '%0' is unsupported; using '%1%2' instead">,
+def warn_drv_optimization_value : Warning<"optimization level '%0' is not supported; using '%1%2' instead">,
+  InGroup<InvalidCommandLineArgument>;
+def warn_ignored_gcc_optimization : Warning<"optimization flag '%0' is not supported">,
   InGroup<InvalidCommandLineArgument>;
 def warn_c_kext : Warning<
   "ignoring -fapple-kext which is valid for C++ and Objective-C++ only">;
@@ -132,12 +142,8 @@
 def warn_drv_empty_joined_argument : Warning<
   "joined argument expects additional value: '%0'">,
   InGroup<UnusedCommandLineArgument>;
-def warn_drv_unused_sanitizer : Warning<"'%0' is ignored in absence of '%1'">,
-  InGroup<UnusedSanitizeArgument>;
 def warn_drv_clang_unsupported : Warning<
   "the clang compiler does not support '%0'">;
-def warn_drv_deprecated_arg : Warning<
-  "argument '%0' is deprecated, use '%1' instead">, InGroup<Deprecated>;
 def warn_drv_assuming_mfloat_abi_is : Warning<
   "unknown platform, assuming -mfloat-abi=%0">;
 def warn_ignoring_ftabstop_value : Warning<
@@ -154,6 +160,8 @@
   "precompiled header '%0' was ignored because '%1' is not first '-include'">;
 def warn_missing_sysroot : Warning<"no such sysroot directory: '%0'">,
   InGroup<DiagGroup<"missing-sysroot">>;
+def warn_debug_compression_unavailable : Warning<"cannot compress debug sections (zlib not installed)">,
+  InGroup<DiagGroup<"debug-compression-unavailable">>;
 
 def note_drv_command_failed_diag_msg : Note<
   "diagnostic msg: %0">;
@@ -164,4 +172,11 @@
   "analyzer-config option '%0' has a key but no value">;
 def err_analyzer_config_multiple_values : Error<
   "analyzer-config option '%0' should contain only one '='">;
+
+def err_drv_modules_validate_once_requires_timestamp : Error<
+  "option '-fmodules-validate-once-per-build-session' requires "
+  "'-fbuild-session-timestamp=<seconds since Epoch>'">;
+
+def warn_drv_invoking_fallback : Warning<"falling back to %0">,
+  InGroup<Fallback>;
 }
diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td
index bcf3c41..ae704c4 100644
--- a/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+class BackendInfo : CatBackend, ShowInSystemHeader;
+
 let Component = "Frontend" in {
 
 def err_fe_error_opening : Error<"error opening '%0': %1">;
@@ -14,13 +16,35 @@
 def err_fe_error_reading_stdin : Error<"error reading stdin: %0">;
 def err_fe_error_backend : Error<"error in backend: %0">, DefaultFatal;
 
-// Error generated by the backend.
 def err_fe_inline_asm : Error<"%0">, CatInlineAsm;
+def warn_fe_inline_asm : Warning<"%0">, CatInlineAsm, InGroup<BackendInlineAsm>;
+def note_fe_inline_asm : Note<"%0">, CatInlineAsm;
 def note_fe_inline_asm_here : Note<"instantiated into assembly here">;
 def err_fe_cannot_link_module : Error<"cannot link module '%0': %1">,
   DefaultFatal;
 
+def warn_fe_frame_larger_than : Warning<"stack frame size of %0 bytes in %q1">,
+    BackendInfo, InGroup<BackendFrameLargerThanEQ>;
+def warn_fe_backend_frame_larger_than: Warning<"%0">,
+    BackendInfo, InGroup<BackendFrameLargerThanEQ>;
+def err_fe_backend_frame_larger_than: Error<"%0">, BackendInfo;
+def note_fe_backend_frame_larger_than: Note<"%0">, BackendInfo;
 
+def warn_fe_backend_plugin: Warning<"%0">, BackendInfo, InGroup<BackendPlugin>;
+def err_fe_backend_plugin: Error<"%0">, BackendInfo;
+def remark_fe_backend_plugin: Remark<"%0">, BackendInfo, InGroup<RemarkBackendPlugin>;
+def note_fe_backend_plugin: Note<"%0">, BackendInfo;
+
+def remark_fe_backend_optimization_remark : Remark<"%0">, BackendInfo,
+    InGroup<BackendOptimizationRemark>;
+def remark_fe_backend_optimization_remark_missed : Remark<"%0">, BackendInfo,
+    InGroup<BackendOptimizationRemarkMissed>;
+def remark_fe_backend_optimization_remark_analysis : Remark<"%0">, BackendInfo,
+    InGroup<BackendOptimizationRemarkAnalysis>;
+def warn_fe_backend_optimization_failure : Warning<"%0">, BackendInfo,
+    InGroup<BackendOptimizationFailure>, DefaultWarn;
+def note_fe_backend_optimization_remark_invalid_loc : Note<"could "
+  "not determine the original source location for %0:%1:%2">;
 
 def err_fe_invalid_code_complete_file : Error<
     "cannot locate code-completion file %0">, DefaultFatal;
@@ -77,6 +101,8 @@
     "cannot find end ('}}') of expected %0">;
 def err_verify_invalid_content : Error<
     "invalid expected %0: %1">;
+def err_verify_missing_regex : Error<
+    "cannot find start of regex ('{{') in %0">;
 def err_verify_inconsistent_diags : Error<
     "'%0' diagnostics %select{expected|seen}1 but not %select{seen|expected}1: "
     "%2">;
@@ -100,17 +126,8 @@
     "must specify system root with -isysroot when building a relocatable "
     "PCH file">;
 
-def warn_unknown_warning_option : Warning<
-    "unknown warning option '%0'">,
-    InGroup<UnknownWarningOption>;
-def warn_unknown_negative_warning_option : Warning<
-    "unknown warning option '%0'">,
-    InGroup<UnknownWarningOption>;
-def warn_unknown_warning_option_suggest : Warning<
-    "unknown warning option '%0'; did you mean '%1'?">,
-    InGroup<UnknownWarningOption>;
-def warn_unknown_negative_warning_option_suggest : Warning<
-    "unknown warning option '%0'; did you mean '%1'?">,
+def warn_unknown_diag_option : Warning<
+    "unknown %select{warning|remark}0 option '%1'%select{|; did you mean '%3'?}2">,
     InGroup<UnknownWarningOption>;
 def warn_unknown_warning_specifier : Warning<
     "unknown %0 warning specifier: '%1'">,
@@ -138,6 +155,10 @@
   InGroup<IncompleteUmbrella>;
 def err_module_unavailable : Error<
   "module '%0' %select{is incompatible with|requires}1 feature '%2'">;
+def err_module_header_missing : Error<
+  "%select{|umbrella }0header '%1' not found">;
+def err_module_cannot_create_includes : Error<
+  "cannot create includes file for module %0: %1">;
 def warn_module_config_macro_undef : Warning<
   "%select{definition|#undef}0 of configuration macro '%1' has no effect on "
   "the import of '%2'; pass '%select{-D%1=...|-U%1}0' on the command line "
@@ -145,4 +166,11 @@
   InGroup<ConfigMacros>;
 def note_module_def_undef_here : Note<
   "macro was %select{defined|#undef'd}0 here">;
+def remark_module_build : Remark<"building module '%0' as '%1'">,
+  InGroup<DiagGroup<"module-build">>;
+
+def err_missing_vfs_overlay_file : Error<
+  "virtual filesystem overlay file '%0' not found">, DefaultFatal;
+def err_invalid_vfs_overlay : Error<
+  "invalid virtual filesystem overlay file '%0'">, DefaultFatal;
 }
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index 38a939f..58dee48 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -18,7 +18,7 @@
 
 // Empty DiagGroups are recognized by clang but ignored.
 def : DiagGroup<"abi">;
-def : DiagGroup<"address">;
+def AbsoluteValue : DiagGroup<"absolute-value">;
 def AddressOfTemporary : DiagGroup<"address-of-temporary">;
 def : DiagGroup<"aggregate-return">;
 def GNUAlignofExpression : DiagGroup<"gnu-alignof-expression">;
@@ -37,19 +37,27 @@
 def LiteralConversion : DiagGroup<"literal-conversion">;
 def StringConversion : DiagGroup<"string-conversion">;
 def SignConversion : DiagGroup<"sign-conversion">;
-def BoolConversion : DiagGroup<"bool-conversion">;
+def PointerBoolConversion : DiagGroup<"pointer-bool-conversion">;
+def UndefinedBoolConversion : DiagGroup<"undefined-bool-conversion">;
+def BoolConversion : DiagGroup<"bool-conversion", [PointerBoolConversion,
+                                                   UndefinedBoolConversion]>;
 def IntConversion : DiagGroup<"int-conversion">;
 def EnumConversion : DiagGroup<"enum-conversion">;
+def FloatConversion : DiagGroup<"float-conversion">;
+def EnumTooLarge : DiagGroup<"enum-too-large">;
 def NonLiteralNullConversion : DiagGroup<"non-literal-null-conversion">;
 def NullConversion : DiagGroup<"null-conversion">;
 def ImplicitConversionFloatingPointToBool :
   DiagGroup<"implicit-conversion-floating-point-to-bool">;
+def ObjCLiteralConversion : DiagGroup<"objc-literal-conversion">;
 def BadArrayNewLength : DiagGroup<"bad-array-new-length">;
+def MacroRedefined : DiagGroup<"macro-redefined">;
 def BuiltinMacroRedefined : DiagGroup<"builtin-macro-redefined">;
 def BuiltinRequiresHeader : DiagGroup<"builtin-requires-header">;
 def C99Compat : DiagGroup<"c99-compat">;
 def CXXCompat: DiagGroup<"c++-compat">;
 def ExternCCompat : DiagGroup<"extern-c-compat">;
+def KeywordCompat : DiagGroup<"keyword-compat">;
 def GNUCaseRange : DiagGroup<"gnu-case-range">;
 def CastAlign : DiagGroup<"cast-align">;
 def : DiagGroup<"cast-qual">;
@@ -70,16 +78,17 @@
   DiagGroup<"c++11-compat-deprecated-writable-strings">;
 
 def DeprecatedDeclarations : DiagGroup<"deprecated-declarations">;
+def UnavailableDeclarations : DiagGroup<"unavailable-declarations">;
 def DeprecatedImplementations :DiagGroup<"deprecated-implementations">;
 def DeprecatedIncrementBool : DiagGroup<"deprecated-increment-bool">;
 def DeprecatedRegister : DiagGroup<"deprecated-register">;
 def DeprecatedWritableStr : DiagGroup<"deprecated-writable-strings",
                                       [CXX11CompatDeprecatedWritableStr]>;
-// FIXME: Why are DeprecatedImplementations and DeprecatedWritableStr
-// not in this group?
+// FIXME: Why is DeprecatedImplementations not in this group?
 def Deprecated : DiagGroup<"deprecated", [DeprecatedDeclarations,
                                           DeprecatedIncrementBool,
-                                          DeprecatedRegister]>,
+                                          DeprecatedRegister,
+                                          DeprecatedWritableStr]>,
                  DiagCategory<"Deprecations">;
 
 def : DiagGroup<"disabled-optimization">;
@@ -112,6 +121,9 @@
 def CXXPre1yCompat : DiagGroup<"c++98-c++11-compat">;
 def CXXPre1yCompatPedantic : DiagGroup<"c++98-c++11-compat-pedantic",
                                        [CXXPre1yCompat]>;
+def CXXPre1zCompat : DiagGroup<"c++98-c++11-c++14-compat">;
+def CXXPre1zCompatPedantic : DiagGroup<"c++98-c++11-c++14-compat-pedantic",
+                                       [CXXPre1zCompat]>;
 
 def CXX98CompatBindToTemporaryCopy :
   DiagGroup<"c++98-compat-bind-to-temporary-copy">;
@@ -124,11 +136,13 @@
                             [CXX98CompatBindToTemporaryCopy,
                              CXX98CompatLocalTypeTemplateArgs,
                              CXX98CompatUnnamedTypeTemplateArgs,
-                             CXXPre1yCompat]>;
+                             CXXPre1yCompat,
+                             CXXPre1zCompat]>;
 // Warnings for C++11 features which are Extensions in C++98 mode.
 def CXX98CompatPedantic : DiagGroup<"c++98-compat-pedantic",
                                     [CXX98Compat,
-                                     CXXPre1yCompatPedantic]>;
+                                     CXXPre1yCompatPedantic,
+                                     CXXPre1zCompatPedantic]>;
 
 def CXX11Narrowing : DiagGroup<"c++11-narrowing">;
 
@@ -148,10 +162,16 @@
                             [CXX11Narrowing,
                              CXX11CompatReservedUserDefinedLiteral,
                              CXX11CompatDeprecatedWritableStr,
-                             CXXPre1yCompat]>;
+                             CXXPre1yCompat,
+                             CXXPre1zCompat]>;
 def : DiagGroup<"c++0x-compat", [CXX11Compat]>;
 def CXX11CompatPedantic : DiagGroup<"c++11-compat-pedantic",
-                                    [CXXPre1yCompatPedantic]>;
+                                    [CXXPre1yCompatPedantic,
+                                     CXXPre1zCompatPedantic]>;
+
+def CXX14Compat : DiagGroup<"c++14-compat", [CXXPre1zCompat]>;
+def CXX14CompatPedantic : DiagGroup<"c++14-compat-pedantic",
+                                    [CXXPre1zCompatPedantic]>;
 
 def : DiagGroup<"effc++">;
 def DivZero : DiagGroup<"division-by-zero">;
@@ -167,9 +187,11 @@
 def DanglingElse: DiagGroup<"dangling-else">;
 def DanglingField : DiagGroup<"dangling-field">;
 def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">;
+def InfiniteRecursion : DiagGroup<"infinite-recursion">;
 def GNUImaginaryConstant : DiagGroup<"gnu-imaginary-constant">;
 def IgnoredQualifiers : DiagGroup<"ignored-qualifiers">;
 def : DiagGroup<"import">;
+def IncompatibleMSStruct : DiagGroup<"incompatible-ms-struct">;
 def IncompatiblePointerTypesDiscardsQualifiers 
   : DiagGroup<"incompatible-pointer-types-discards-qualifiers">;
 def IncompatiblePointerTypes
@@ -177,6 +199,10 @@
     [IncompatiblePointerTypesDiscardsQualifiers]>;
 def IncompleteUmbrella : DiagGroup<"incomplete-umbrella">;
 def IncompleteModule : DiagGroup<"incomplete-module", [IncompleteUmbrella]>;
+def NonModularIncludeInFrameworkModule
+  : DiagGroup<"non-modular-include-in-framework-module">;
+def NonModularIncludeInModule : DiagGroup<"non-modular-include-in-module",
+                                          [NonModularIncludeInFrameworkModule]>;
 def InvalidNoreturn : DiagGroup<"invalid-noreturn">;
 def InvalidSourceEncoding : DiagGroup<"invalid-source-encoding">;
 def KNRPromotedParameter : DiagGroup<"knr-promoted-parameter">;
@@ -213,24 +239,28 @@
 def InitializerOverrides : DiagGroup<"initializer-overrides">;
 def NonNull : DiagGroup<"nonnull">;
 def NonPODVarargs : DiagGroup<"non-pod-varargs">;
+def ClassVarargs : DiagGroup<"class-varargs", [NonPODVarargs]>;
 def : DiagGroup<"nonportable-cfstrings">;
 def NonVirtualDtor : DiagGroup<"non-virtual-dtor">;
 def OveralignedType : DiagGroup<"over-aligned">;
-def : DiagGroup<"old-style-cast">;
+def OldStyleCast : DiagGroup<"old-style-cast">;
 def : DiagGroup<"old-style-definition">;
 def OutOfLineDeclaration : DiagGroup<"out-of-line-declaration">;
 def : DiagGroup<"overflow">;
 def ForwardClassReceiver : DiagGroup<"receiver-forward-class">;
 def MethodAccess : DiagGroup<"objc-method-access">;
 def ObjCReceiver : DiagGroup<"receiver-expr">;
+def OperatorNewReturnsNull : DiagGroup<"new-returns-null">;
 def OverlengthStrings : DiagGroup<"overlength-strings">;
 def OverloadedVirtual : DiagGroup<"overloaded-virtual">;
 def PrivateExtern : DiagGroup<"private-extern">;
 def SelTypeCast : DiagGroup<"cast-of-sel-type">;
+def FunctionDefInObjCContainer : DiagGroup<"function-def-in-objc-container">;
 def BadFunctionCast : DiagGroup<"bad-function-cast">;
 def ObjCPropertyImpl : DiagGroup<"objc-property-implementation">;
 def ObjCPropertyNoAttribute : DiagGroup<"objc-property-no-attribute">;
 def ObjCMissingSuperCalls : DiagGroup<"objc-missing-super-calls">;
+def ObjCDesignatedInit : DiagGroup<"objc-designated-initializers">;
 def ObjCRetainBlockProperty : DiagGroup<"objc-noncopy-retain-block-property">;
 def ObjCReadonlyPropertyHasSetter : DiagGroup<"objc-readonly-with-setter-property">;
 def ObjCInvalidIBOutletProperty : DiagGroup<"invalid-iboutlet">;
@@ -241,8 +271,7 @@
 def Packed : DiagGroup<"packed">;
 def Padded : DiagGroup<"padded">;
 def PointerArith : DiagGroup<"pointer-arith">;
-def PoundWarning : DiagGroup<"#warnings">,
-                   DiagCategory<"#warning Directive">;
+def PoundWarning : DiagGroup<"#warnings">;
 def PoundPragmaMessage : DiagGroup<"#pragma-messages">,
                          DiagCategory<"#pragma message Directive">;
 def : DiagGroup<"pointer-to-int-cast">;
@@ -274,12 +303,19 @@
 def GNUStaticFloatInit : DiagGroup<"gnu-static-float-init">;
 def StaticFloatInit : DiagGroup<"static-float-init", [GNUStaticFloatInit]>;
 def GNUStatementExpression : DiagGroup<"gnu-statement-expression">;
+def StringCompare : DiagGroup<"string-compare">;
 def StringPlusInt : DiagGroup<"string-plus-int">;
 def StringPlusChar : DiagGroup<"string-plus-char">;
 def StrncatSize : DiagGroup<"strncat-size">;
 def TautologicalOutOfRangeCompare : DiagGroup<"tautological-constant-out-of-range-compare">;
+def TautologicalPointerCompare : DiagGroup<"tautological-pointer-compare">;
+def TautologicalOverlapCompare : DiagGroup<"tautological-overlap-compare">;
+def TautologicalUndefinedCompare : DiagGroup<"tautological-undefined-compare">;
 def TautologicalCompare : DiagGroup<"tautological-compare",
-                                    [TautologicalOutOfRangeCompare]>;
+                                    [TautologicalOutOfRangeCompare,
+                                     TautologicalPointerCompare,
+                                     TautologicalOverlapCompare,
+                                     TautologicalUndefinedCompare]>;
 def HeaderHygiene : DiagGroup<"header-hygiene">;
 def DuplicateDeclSpecifier : DiagGroup<"duplicate-decl-specifier">;
 def CompareDistinctPointerType : DiagGroup<"compare-distinct-pointer-types">;
@@ -314,6 +350,7 @@
 def StrictSelector : DiagGroup<"strict-selector-match">;
 def MethodDuplicate : DiagGroup<"duplicate-method-match">;
 def CoveredSwitchDefault : DiagGroup<"covered-switch-default">;
+def SwitchBool     : DiagGroup<"switch-bool">;
 def SwitchEnum     : DiagGroup<"switch-enum">;
 def Switch         : DiagGroup<"switch">;
 def ImplicitFallthroughPerFunction :
@@ -333,17 +370,19 @@
 def Uninitialized  : DiagGroup<"uninitialized", [UninitializedSometimes,
                                                  UninitializedStaticSelfInit]>;
 def UnknownPragmas : DiagGroup<"unknown-pragmas">;
+def IgnoredPragmas : DiagGroup<"ignored-pragmas">;
+def Pragmas : DiagGroup<"pragmas", [UnknownPragmas, IgnoredPragmas]>;
 def UnknownWarningOption : DiagGroup<"unknown-warning-option">;
 def NSobjectAttribute : DiagGroup<"NSObject-attribute">;
-def UnknownAttributes : DiagGroup<"attributes">;
+def UnknownAttributes : DiagGroup<"unknown-attributes">;
 def IgnoredAttributes : DiagGroup<"ignored-attributes">;
+def Attributes : DiagGroup<"attributes", [UnknownAttributes,
+                                          IgnoredAttributes]>;
 def UnnamedTypeTemplateArgs : DiagGroup<"unnamed-type-template-args",
                                         [CXX98CompatUnnamedTypeTemplateArgs]>;
 def UnsupportedFriend : DiagGroup<"unsupported-friend">;
 def UnusedArgument : DiagGroup<"unused-argument">;
-def UnusedSanitizeArgument : DiagGroup<"unused-sanitize-argument">;
-def UnusedCommandLineArgument : DiagGroup<"unused-command-line-argument",
-                                          [UnusedSanitizeArgument]>;
+def UnusedCommandLineArgument : DiagGroup<"unused-command-line-argument">;
 def InvalidCommandLineArgument : DiagGroup<"invalid-command-line-argument">;
 def UnusedComparison : DiagGroup<"unused-comparison">;
 def UnusedExceptionParameter : DiagGroup<"unused-exception-parameter">;
@@ -363,7 +402,6 @@
 def UnusedPropertyIvar :  DiagGroup<"unused-property-ivar">;
 def UsedButMarkedUnused : DiagGroup<"used-but-marked-unused">;
 def UserDefinedLiterals : DiagGroup<"user-defined-literals">;
-def ReadOnlySetterAttrs : DiagGroup<"readonly-setter-attrs">;
 def Reorder : DiagGroup<"reorder">;
 def UndeclaredSelector : DiagGroup<"undeclared-selector">;
 def ImplicitAtomic : DiagGroup<"implicit-atomic-properties">;
@@ -384,6 +422,7 @@
                                      [ARCRepeatedUseOfWeakMaybe]>;
 def ObjCBridge : DiagGroup<"bridge-cast">;
 
+def DeallocInCategory:DiagGroup<"dealloc-in-category">;
 def SelectorTypeMismatch : DiagGroup<"selector-type-mismatch">;
 def Selector : DiagGroup<"selector", [SelectorTypeMismatch]>;
 def Protocol : DiagGroup<"protocol">;
@@ -399,16 +438,48 @@
 def ZeroLengthArray : DiagGroup<"zero-length-array">;
 def GNUZeroLineDirective : DiagGroup<"gnu-zero-line-directive">;
 def GNUZeroVariadicMacroArguments : DiagGroup<"gnu-zero-variadic-macro-arguments">;
+def Fallback : DiagGroup<"fallback">;
+
+// This covers both the deprecated case (in C++98)
+// and the extension case (in C++11 onwards).
+def WritableStrings : DiagGroup<"writable-strings", [DeprecatedWritableStr]>;
 
 // GCC calls -Wdeprecated-writable-strings -Wwrite-strings.
-def GCCWriteStrings : DiagGroup<"write-strings" , [DeprecatedWritableStr]>;
+//
+// Bizarrely, this warning flag enables -fconst-strings in C. This is
+// GCC-compatible, but really weird.
+//
+// FIXME: Should this affect C++11 (where this is an error,
+//        not just deprecated) or not?
+def GCCWriteStrings : DiagGroup<"write-strings" , [WritableStrings]>;
 
 def CharSubscript : DiagGroup<"char-subscripts">;
 def LargeByValueCopy : DiagGroup<"large-by-value-copy">;
 def DuplicateArgDecl : DiagGroup<"duplicate-method-arg">;
 
+// Unreachable code warning groups.
+//
+//  The goal is make -Wunreachable-code on by default, in -Wall, or at
+//  least actively used, with more noisy versions of the warning covered
+//  under separate flags.
+//
+def UnreachableCodeLoopIncrement : DiagGroup<"unreachable-code-loop-increment">;
+def UnreachableCode : DiagGroup<"unreachable-code",
+                                [UnreachableCodeLoopIncrement]>;
+def UnreachableCodeBreak : DiagGroup<"unreachable-code-break">;
+def UnreachableCodeReturn : DiagGroup<"unreachable-code-return">;
+def UnreachableCodeAggressive : DiagGroup<"unreachable-code-aggressive",
+                                    [UnreachableCode,
+                                     UnreachableCodeBreak,
+                                     UnreachableCodeReturn]>;
+
 // Aggregation warning settings.
 
+// Populate -Waddress with warnings from other groups.
+def : DiagGroup<"address", [PointerBoolConversion,
+                            StringCompare,
+                            TautologicalPointerCompare]>;
+
 // -Widiomatic-parentheses contains warnings about 'idiomatic'
 // missing parentheses;  it is off by default.  We do not include it
 // in -Wparentheses because most users who use -Wparentheses explicitly
@@ -434,11 +505,13 @@
                            [BoolConversion,
                             ConstantConversion,
                             EnumConversion,
+                            FloatConversion,
                             Shorten64To32,
                             IntConversion,
                             LiteralConversion,
                             NonLiteralNullConversion, // (1-1)->pointer (etc)
                             NullConversion, // NULL->non-pointer
+                            ObjCLiteralConversion,
                             SignConversion,
                             StringConversion]>,
                  DiagCategory<"Value Conversion Issue">;
@@ -460,7 +533,7 @@
                        [FormatExtraArgs, FormatZeroLength, NonNull,
                         FormatSecurity, FormatY2K, FormatInvalidSpecifier]>,
              DiagCategory<"Format String Issue">;
-def FormatNonLiteral : DiagGroup<"format-nonliteral", [FormatSecurity]>;
+def FormatNonLiteral : DiagGroup<"format-nonliteral">;
 def Format2 : DiagGroup<"format=2",
                         [FormatNonLiteral, FormatSecurity, FormatY2K]>;
 
@@ -501,6 +574,7 @@
     Unused,
     VolatileRegisterVar,
     ObjCMissingSuperCalls,
+    ObjCDesignatedInit,
     OverloadedVirtual,
     PrivateExtern,
     SelTypeCast,
@@ -523,7 +597,7 @@
 // Note that putting warnings in -Wall will not disable them by default. If a
 // warning should be active _only_ when -Wall is passed in, mark it as
 // DefaultIgnore in addition to putting it here.
-def : DiagGroup<"all", [Most, Parentheses, Switch]>;
+def : DiagGroup<"all", [Most, Parentheses, Switch, SwitchBool]>;
 
 // Warnings enabled by -pedantic.  This is magically filled in by TableGen.
 def Pedantic : DiagGroup<"pedantic">;
@@ -554,6 +628,10 @@
 // earlier C++ versions.
 def CXX1y : DiagGroup<"c++1y-extensions">;
 
+// A warning group for warnings about using C++1z features as extensions in
+// earlier C++ versions.
+def CXX1z : DiagGroup<"c++1z-extensions">;
+
 def : DiagGroup<"c++0x-extensions", [CXX11]>;
 def DelegatingCtorCycles :
   DiagGroup<"delegating-ctor-cycles">;
@@ -607,8 +685,6 @@
     ObjCStringComparison
   ]>;
 
-def ObjCLiteralMissingAtSign : DiagGroup<"objc-literal-missing-atsign">;
-
 // Inline ASM warnings.
 def ASMOperandWidths : DiagGroup<"asm-operand-widths">;
 def ASM : DiagGroup<"asm", [
@@ -617,3 +693,23 @@
 
 // OpenMP warnings.
 def SourceUsesOpenMP : DiagGroup<"source-uses-openmp">;
+def OpenMPClauses : DiagGroup<"openmp-clauses">;
+def OpenMPLoopForm : DiagGroup<"openmp-loop-form">;
+
+// Backend warnings.
+def BackendInlineAsm : DiagGroup<"inline-asm">;
+def BackendFrameLargerThanEQ : DiagGroup<"frame-larger-than=">;
+def BackendPlugin : DiagGroup<"backend-plugin">;
+def RemarkBackendPlugin : DiagGroup<"remark-backend-plugin">;
+def BackendOptimizationRemark : DiagGroup<"pass">;
+def BackendOptimizationRemarkMissed : DiagGroup<"pass-missed">;
+def BackendOptimizationRemarkAnalysis : DiagGroup<"pass-analysis">;
+def BackendOptimizationFailure : DiagGroup<"pass-failed">;
+
+// Instrumentation based profiling warnings.
+def ProfileInstrOutOfDate : DiagGroup<"profile-instr-out-of-date">;
+def ProfileInstrUnprofiled : DiagGroup<"profile-instr-unprofiled">;
+
+// A warning group for warnings about code that clang accepts when
+// compiling CUDA C/C++ but which is not compatible with the CUDA spec.
+def CudaCompat : DiagGroup<"cuda-compat">;
diff --git a/include/clang/Basic/DiagnosticIDs.h b/include/clang/Basic/DiagnosticIDs.h
index 56e30fb..bfb0f0d 100644
--- a/include/clang/Basic/DiagnosticIDs.h
+++ b/include/clang/Basic/DiagnosticIDs.h
@@ -56,49 +56,53 @@
     };
 
     /// Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs
-    /// to either MAP_IGNORE (nothing), MAP_WARNING (emit a warning), MAP_ERROR
-    /// (emit as an error).  It allows clients to map errors to
-    /// MAP_ERROR/MAP_DEFAULT or MAP_FATAL (stop emitting diagnostics after this
-    /// one).
-    enum Mapping {
+    /// to either Ignore (nothing), Remark (emit a remark), Warning
+    /// (emit a warning) or Error (emit as an error).  It allows clients to
+    /// map ERRORs to Error or Fatal (stop emitting diagnostics after this one).
+    enum class Severity {
       // NOTE: 0 means "uncomputed".
-      MAP_IGNORE  = 1,     ///< Map this diagnostic to nothing, ignore it.
-      MAP_WARNING = 2,     ///< Map this diagnostic to a warning.
-      MAP_ERROR   = 3,     ///< Map this diagnostic to an error.
-      MAP_FATAL   = 4      ///< Map this diagnostic to a fatal error.
+      Ignored = 1, ///< Do not present this diagnostic, ignore it.
+      Remark = 2,  ///< Present this diagnostic as a remark.
+      Warning = 3, ///< Present this diagnostic as a warning.
+      Error = 4,   ///< Present this diagnostic as an error.
+      Fatal = 5    ///< Present this diagnostic as a fatal error.
+    };
+
+    /// Flavors of diagnostics we can emit. Used to filter for a particular
+    /// kind of diagnostic (for instance, for -W/-R flags).
+    enum class Flavor {
+      WarningOrError, ///< A diagnostic that indicates a problem or potential
+                      ///< problem. Can be made fatal by -Werror.
+      Remark          ///< A diagnostic that indicates normal progress through
+                      ///< compilation.
     };
   }
 
-class DiagnosticMappingInfo {
-  unsigned Mapping : 3;
+class DiagnosticMapping {
+  unsigned Severity : 3;
   unsigned IsUser : 1;
   unsigned IsPragma : 1;
-  unsigned HasShowInSystemHeader : 1;
   unsigned HasNoWarningAsError : 1;
   unsigned HasNoErrorAsFatal : 1;
 
 public:
-  static DiagnosticMappingInfo Make(diag::Mapping Mapping, bool IsUser,
-                                    bool IsPragma) {
-    DiagnosticMappingInfo Result;
-    Result.Mapping = Mapping;
+  static DiagnosticMapping Make(diag::Severity Severity, bool IsUser,
+                                bool IsPragma) {
+    DiagnosticMapping Result;
+    Result.Severity = (unsigned)Severity;
     Result.IsUser = IsUser;
     Result.IsPragma = IsPragma;
-    Result.HasShowInSystemHeader = 0;
     Result.HasNoWarningAsError = 0;
     Result.HasNoErrorAsFatal = 0;
     return Result;
   }
 
-  diag::Mapping getMapping() const { return diag::Mapping(Mapping); }
-  void setMapping(diag::Mapping Value) { Mapping = Value; }
+  diag::Severity getSeverity() const { return (diag::Severity)Severity; }
+  void setSeverity(diag::Severity Value) { Severity = (unsigned)Value; }
 
   bool isUser() const { return IsUser; }
   bool isPragma() const { return IsPragma; }
 
-  bool hasShowInSystemHeader() const { return HasShowInSystemHeader; }
-  void setShowInSystemHeader(bool Value) { HasShowInSystemHeader = Value; }
-
   bool hasNoWarningAsError() const { return HasNoWarningAsError; }
   void setNoWarningAsError(bool Value) { HasNoWarningAsError = Value; }
 
@@ -113,7 +117,7 @@
 public:
   /// \brief The level of the diagnostic, after it has been through mapping.
   enum Level {
-    Ignored, Note, Warning, Error, Fatal
+    Ignored, Note, Remark, Warning, Error, Fatal
   };
 
 private:
@@ -124,11 +128,16 @@
   DiagnosticIDs();
   ~DiagnosticIDs();
 
-  /// \brief Return an ID for a diagnostic with the specified message and level.
+  /// \brief Return an ID for a diagnostic with the specified format string and
+  /// level.
   ///
   /// If this is the first request for this diagnostic, it is registered and
   /// created, otherwise the existing ID is returned.
-  unsigned getCustomDiagID(Level L, StringRef Message);
+
+  // FIXME: Replace this function with a create-only facilty like
+  // createCustomDiagIDFromFormatString() to enforce safe usage. At the time of
+  // writing, nearly all callers of this function were invalid.
+  unsigned getCustomDiagID(Level L, StringRef FormatString);
 
   //===--------------------------------------------------------------------===//
   // Diagnostic classification and reporting interfaces.
@@ -228,15 +237,16 @@
   ///
   /// \param[out] Diags - On return, the diagnostics in the group.
   /// \returns \c true if the given group is unknown, \c false otherwise.
-  bool getDiagnosticsInGroup(StringRef Group,
+  bool getDiagnosticsInGroup(diag::Flavor Flavor, StringRef Group,
                              SmallVectorImpl<diag::kind> &Diags) const;
 
   /// \brief Get the set of all diagnostic IDs.
-  void getAllDiagnostics(SmallVectorImpl<diag::kind> &Diags) const;
+  void getAllDiagnostics(diag::Flavor Flavor,
+                         SmallVectorImpl<diag::kind> &Diags) const;
 
-  /// \brief Get the warning option with the closest edit distance to the given
-  /// group name.
-  static StringRef getNearestWarningOption(StringRef Group);
+  /// \brief Get the diagnostic option with the closest edit distance to the
+  /// given group name.
+  static StringRef getNearestOption(diag::Flavor Flavor, StringRef Group);
 
 private:
   /// \brief Classify the specified diagnostic ID into a Level, consumable by
@@ -247,15 +257,13 @@
   ///
   /// \param Loc The source location for which we are interested in finding out
   /// the diagnostic state. Can be null in order to query the latest state.
-  DiagnosticIDs::Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc,
-                                          const DiagnosticsEngine &Diag) const;
+  DiagnosticIDs::Level
+  getDiagnosticLevel(unsigned DiagID, SourceLocation Loc,
+                     const DiagnosticsEngine &Diag) const LLVM_READONLY;
 
-  /// \brief An internal implementation helper used when \p DiagClass is
-  /// already known.
-  DiagnosticIDs::Level getDiagnosticLevel(unsigned DiagID,
-                                          unsigned DiagClass,
-                                          SourceLocation Loc,
-                                          const DiagnosticsEngine &Diag) const;
+  diag::Severity
+  getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc,
+                        const DiagnosticsEngine &Diag) const LLVM_READONLY;
 
   /// \brief Used to report a diagnostic that is finally fully formed.
   ///
diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td
index 871f5f6..86def87 100644
--- a/include/clang/Basic/DiagnosticLexKinds.td
+++ b/include/clang/Basic/DiagnosticLexKinds.td
@@ -151,7 +151,8 @@
 // Literal
 def ext_nonstandard_escape : Extension<
   "use of non-standard escape character '\\%0'">;
-def ext_unknown_escape : ExtWarn<"unknown escape sequence '\\%0'">;
+def ext_unknown_escape : ExtWarn<"unknown escape sequence '\\%0'">,
+  InGroup<DiagGroup<"unknown-escape-sequence">>;
 def err_invalid_decimal_digit : Error<"invalid digit '%0' in decimal constant">;
 def err_invalid_binary_digit : Error<"invalid digit '%0' in binary constant">;
 def err_invalid_octal_digit : Error<"invalid digit '%0' in octal constant">;
@@ -244,9 +245,9 @@
 // Preprocessor Diagnostics
 //===----------------------------------------------------------------------===//
 
-let CategoryName = "User Defined Issues" in {
+let CategoryName = "User-Defined Issue" in {
 def pp_hash_warning : Warning<"%0">,
-  InGroup<PoundWarning>, DefaultWarnShowInSystemHeader;
+  InGroup<PoundWarning>, ShowInSystemHeader;
 def err_pp_hash_error : Error<"%0">;
 }
 
@@ -300,6 +301,9 @@
   InGroup<DiagGroup<"import-preprocessor-directive-pedantic">>;
 def err_pp_import_directive_ms : Error<
   "#import of type library is an unsupported Microsoft feature">;
+def ext_pp_include_search_ms : ExtWarn<
+  "#include resolved using non-portable MSVC search rules as: %0">,
+  InGroup<DiagGroup<"msvc-include">>;
 
 def ext_pp_ident_directive : Extension<"#ident is a language extension">;
 def ext_pp_include_next_directive : Extension<
@@ -312,7 +316,7 @@
 def ext_pp_comma_expr : Extension<"comma operator in operand of #if">;
 def ext_pp_bad_vaargs_use : Extension<
   "__VA_ARGS__ can only appear in the expansion of a C99 variadic macro">;
-def ext_pp_macro_redef : ExtWarn<"%0 macro redefined">;
+def ext_pp_macro_redef : ExtWarn<"%0 macro redefined">, InGroup<MacroRedefined>;
 def ext_variadic_macro : Extension<"variadic macros are a C99 feature">,
   InGroup<VariadicMacros>;
 def warn_cxx98_compat_variadic_macro : Warning<
@@ -349,7 +353,7 @@
 def err_pp_empty_filename : Error<"empty filename">;
 def err_pp_include_too_deep : Error<"#include nested too deeply">;
 def err_pp_expects_filename : Error<"expected \"FILENAME\" or <FILENAME>">;
-def err_pp_macro_not_identifier : Error<"macro names must be identifiers">;
+def err_pp_macro_not_identifier : Error<"macro name must be an identifier">;
 def err_pp_missing_macro_name : Error<"macro name missing">;
 def err_pp_missing_rparen_in_macro_def : Error<
   "missing ')' in macro parameter list">;
@@ -375,10 +379,7 @@
 def err_pp_expected_rparen : Error<"expected ')' in preprocessor expression">;
 def err_pp_expected_eol : Error<
   "expected end of line in preprocessor expression">;
-def err_pp_defined_requires_identifier : Error<
-  "operator 'defined' requires an identifier">;
-def err_pp_missing_lparen : Error<"missing '(' after '%0'">;
-def err_pp_missing_rparen : Error<"missing ')' after '%0'">;
+def err_pp_expected_after : Error<"missing %1 after %0">;
 def err_pp_colon_without_question : Error<"':' without preceding '?'">;
 def err_pp_division_by_zero : Error<
   "division by zero in preprocessor expression">;
@@ -400,6 +401,9 @@
    ExtWarn<"__has_warning expected option name (e.g. \"-Wundef\")">,
    InGroup<MalformedWarningCheck>;
 
+def err_pp_identifier_arg_not_identifier : Error<
+  "cannot convert %0 token to an identifier">;
+
 def warn_pragma_include_alias_mismatch_angle :
    ExtWarn<"angle-bracketed include <%0> cannot be aliased to double-quoted "
    "include \"%1\"">, InGroup<UnknownPragmas>;
@@ -435,7 +439,8 @@
 def err_pragma_push_pop_macro_malformed : Error<
    "pragma %0 requires a parenthesized string">;
 def warn_pragma_pop_macro_no_push : Warning<
-   "pragma pop_macro could not pop '%0', no matching push_macro">;
+   "pragma pop_macro could not pop '%0', no matching push_macro">,
+  InGroup<IgnoredPragmas>;
 def warn_pragma_message : Warning<"%0">,
    InGroup<PoundPragmaMessage>, DefaultWarnNoWerror;
 def err_pragma_message : Error<"%0">;
@@ -470,7 +475,7 @@
    InGroup<UnknownPragmas>;
 // - #pragma __debug
 def warn_pragma_debug_unexpected_command : Warning<
-  "unexpected debug command '%0'">;
+  "unexpected debug command '%0'">, InGroup<IgnoredPragmas>;
 
 def err_defined_macro_name : Error<"'defined' cannot be used as a macro name">;
 def err_paste_at_start : Error<
@@ -491,11 +496,13 @@
   "too few arguments provided to function-like macro invocation">;
 def err_pp_bad_paste : Error<
   "pasting formed '%0', an invalid preprocessing token">;
-def err_pp_bad_paste_ms : Warning<
+def ext_pp_bad_paste_ms : ExtWarn<
   "pasting formed '%0', an invalid preprocessing token">, DefaultError,
   InGroup<DiagGroup<"invalid-token-paste">>;
 def err_pp_operator_used_as_macro_name : Error<
-  "C++ operator '%0' cannot be used as a macro name">;
+  "C++ operator %0 (aka %1) used as a macro name">;
+def ext_pp_operator_used_as_macro_name : Extension<
+  "C++ operator %0 (aka %1) used as a macro name">, InGroup<Microsoft>;
 def err_pp_illegal_floating_literal : Error<
   "floating point literal in preprocessor expression">;
 def err_pp_line_requires_integer : Error<
@@ -535,6 +542,10 @@
 def err_pp_eof_in_arc_cf_code_audited : Error<
   "'#pragma clang arc_cf_code_audited' was not ended within this file">;
 
+def warn_pp_date_time : Warning<
+  "expansion of date or time macro is not reproducible">,
+  ShowInSystemHeader, DefaultIgnore, InGroup<DiagGroup<"date-time">>;
+
 // Module map parsing
 def err_mmap_unknown_token : Error<"skipping stray token">;
 def err_mmap_expected_module : Error<"expected module declaration">;
@@ -551,8 +562,6 @@
 def err_mmap_module_redefinition : Error<
   "redefinition of module '%0'">;
 def note_mmap_prev_definition : Note<"previously defined here">;
-def err_mmap_header_not_found : Error<
-  "%select{|umbrella }0header '%1' not found">;
 def err_mmap_umbrella_dir_not_found : Error<
   "umbrella directory '%0' not found">;
 def err_mmap_umbrella_clash : Error<
@@ -605,7 +614,7 @@
   "import of module '%1'">, InGroup<AutoImport>, DefaultIgnore;
 def warn_uncovered_module_header : Warning<
   "umbrella header for module '%0' does not include header '%1'">, 
-  InGroup<IncompleteUmbrella>, DefaultIgnore;
+  InGroup<IncompleteUmbrella>;
 def warn_forgotten_module_header : Warning<
   "header '%0' is included in module '%1' but not listed in module map">,
   InGroup<IncompleteModule>, DefaultIgnore;
@@ -614,7 +623,14 @@
 def error_use_of_private_header_outside_module : Error<
   "use of private header from outside its module: '%0'">;
 def error_undeclared_use_of_module : Error<
-  "use of a module not declared used: '%0'">;
+  "module %0 does not depend on a module exporting '%1'">;
+def warn_non_modular_include_in_framework_module : Warning<
+  "include of non-modular header inside framework module '%0'">,
+  InGroup<NonModularIncludeInFrameworkModule>, DefaultIgnore;
+def warn_non_modular_include_in_module : Warning<
+  "include of non-modular header inside module '%0'">,
+  InGroup<NonModularIncludeInModule>, DefaultIgnore;
+
 
 def warn_header_guard : Warning<
   "%0 is used as a header guard here, followed by #define of a different macro">,
diff --git a/include/clang/Basic/DiagnosticOptions.h b/include/clang/Basic/DiagnosticOptions.h
index 2fba384..3e4d0ee 100644
--- a/include/clang/Basic/DiagnosticOptions.h
+++ b/include/clang/Basic/DiagnosticOptions.h
@@ -19,7 +19,7 @@
 
 /// \brief Specifies which overload candidates to display when overload
 /// resolution fails.
-enum OverloadsShown {
+enum OverloadsShown : unsigned {
   Ovl_All,  ///< Show all overloads.
   Ovl_Best  ///< Show just the "best" overload candidates.
 };
@@ -58,6 +58,10 @@
   /// prefixes removed.
   std::vector<std::string> Warnings;
 
+  /// The list of -R... options used to alter the diagnostic mappings, with the
+  /// prefixes removed.
+  std::vector<std::string> Remarks;
+
 public:
   // Define accessors/mutators for diagnostic options of enumeration type.
 #define DIAGOPT(Name, Bits, Default)
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index 4d0641d..b1305e1 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -58,6 +58,10 @@
 def ext_integer_complex : Extension<
   "complex integer types are a GNU extension">, InGroup<GNUComplexInteger>;
 def ext_thread_before : Extension<"'__thread' before '%0'">;
+def ext_keyword_as_ident : ExtWarn<
+  "keyword '%0' will be made available as an identifier "
+  "%select{here|for the remainder of the translation unit}1">,
+  InGroup<KeywordCompat>;
 
 def error_empty_enum : Error<"use of empty enum">;
 def err_invalid_sign_spec : Error<"'%0' cannot be signed or unsigned">;
@@ -65,7 +69,7 @@
 def err_invalid_long_spec : Error<"'long %0' is invalid">;
 def err_invalid_longlong_spec : Error<"'long long %0' is invalid">;
 def err_invalid_complex_spec : Error<"'_Complex %0' is invalid">;
-def err_friend_storage_spec : Error<"'%0' is invalid in friend declarations">;
+def err_friend_decl_spec : Error<"'%0' is invalid in friend declarations">;
 
 def ext_ident_list_in_param : Extension<
   "type-less parameter names in function declaration">;
@@ -145,18 +149,6 @@
 def err_expected_type : Error<"expected a type">;
 def err_expected_external_declaration : Error<"expected external declaration">;
 def err_extraneous_closing_brace : Error<"extraneous closing brace ('}')">;
-def err_expected_ident : Error<"expected identifier">;
-def err_expected_ident_lparen : Error<"expected identifier or '('">;
-def err_expected_ident_lbrace : Error<"expected identifier or '{'">;
-def err_expected_lbrace : Error<"expected '{'">;
-def err_expected_lparen : Error<"expected '('">;
-def err_expected_lparen_or_lbrace : Error<"expected '(' or '{'">;
-def err_expected_rparen : Error<"expected ')'">;
-def err_expected_lsquare : Error<"expected '['">;
-def err_expected_rsquare : Error<"expected ']'">;
-def err_expected_rbrace : Error<"expected '}'">;
-def err_expected_greater : Error<"expected '>'">;
-def err_expected_ggg : Error<"expected '>>>'">;
 def err_expected_semi_declaration : Error<
   "expected ';' at end of declaration">;
 def err_expected_semi_decl_list : Error<
@@ -182,18 +174,16 @@
 def err_invalid_token_after_toplevel_declarator : Error<
   "expected ';' after top level declarator">;
 def err_invalid_token_after_declarator_suggest_equal : Error<
-  "invalid '%0' at end of declaration; did you mean '='?">;
+  "invalid %0 at end of declaration; did you mean '='?">;
 def err_expected_statement : Error<"expected statement">;
 def err_expected_lparen_after : Error<"expected '(' after '%0'">;
-def err_expected_lparen_after_id : Error<"expected '(' after %0">;
+def err_expected_rparen_after : Error<"expected ')' after '%0'">;
+def err_expected_punc : Error<"expected ')' or ',' after '%0'">;
 def err_expected_less_after : Error<"expected '<' after '%0'">;
-def err_expected_equal_after : Error<"expected '=' after %0">;
-def err_expected_comma : Error<"expected ','">;
 def err_expected_lbrace_in_compound_literal : Error<
   "expected '{' in compound literal">;
 def err_expected_while : Error<"expected 'while' in do/while loop">;
 
-def err_expected_semi_after : Error<"expected ';' after %0">;
 def err_expected_semi_after_stmt : Error<"expected ';' after %0 statement">;
 def err_expected_semi_after_expr : Error<"expected ';' after expression">;
 def err_extraneous_token_before_semi : Error<"extraneous '%0' before ';'">;
@@ -203,7 +193,7 @@
 def err_expected_semi_after_namespace_name : Error<
   "expected ';' after namespace name">;
 def err_unexpected_namespace_attributes_alias : Error<
-  "attributes can not be specified on namespace alias">;
+  "attributes cannot be specified on namespace alias">;
 def err_inline_namespace_alias : Error<"namespace alias cannot be inline">;
 def err_namespace_nonnamespace_scope : Error<
   "namespaces can only be defined in global or namespace scope">;
@@ -214,7 +204,8 @@
 def err_expected_semi_after_static_assert : Error<
   "expected ';' after static_assert">;
 def err_expected_semi_for : Error<"expected ';' in 'for' statement specifier">;
-def err_expected_colon_after : Error<"expected ':' after %0">;
+def err_single_decl_assign_in_for_range : Error<
+  "range-based 'for' statement uses ':', not '='">;
 def warn_missing_selector_name : Warning<
   "%0 used as the name of the previous parameter rather than as part "
   "of the selector">,
@@ -235,6 +226,8 @@
 def err_expected_property_name : Error<"expected property name">;
 
 def err_unexpected_at : Error<"unexpected '@' in program">;
+def err_atimport : Error<
+"use of '@import' when modules are disabled">;
 
 def err_invalid_reference_qualifier_application : Error<
   "'%0' qualifier may not be applied to a reference">;
@@ -284,6 +277,13 @@
 def warn_cxx98_compat_for_range : Warning<
   "range-based for loop is incompatible with C++98">,
   InGroup<CXX98Compat>, DefaultIgnore;
+def ext_for_range_identifier : ExtWarn<
+  "range-based for loop with implicit deduced type is a C++1z extension">,
+  InGroup<CXX1z>;
+def warn_cxx1y_compat_for_range_identifier : Warning<
+  "range-based for loop with implicit deduced type is incompatible with "
+  "C++ standards before C++1z">,
+  InGroup<CXXPre1zCompat>, DefaultIgnore;
 def err_for_range_expected_decl : Error<
   "for range declaration must declare a variable">;
 def err_argument_required_after_attribute : Error<
@@ -340,16 +340,16 @@
   "Use of 'long' with '__vector' is deprecated">, InGroup<Deprecated>;
 def err_friend_invalid_in_context : Error<
   "'friend' used outside of class">;
-def err_unknown_typename : Error<
-  "unknown type name %0">;
 def err_use_of_tag_name_without_tag : Error<
   "must use '%1' tag to refer to type %0%select{| in this scope}2">;
 def err_templated_using_directive : Error<
   "cannot template a using directive">;
 def err_templated_using_declaration : Error<
   "cannot template a using declaration">;
-def err_unexected_colon_in_nested_name_spec : Error<
+def err_unexpected_colon_in_nested_name_spec : Error<
   "unexpected ':' in nested name specifier; did you mean '::'?">;
+def err_unexpected_token_in_nested_name_spec : Error<
+  "'%0' cannot be a part of nested name specifier; did you mean ':'?">;
 def err_bool_redeclaration : Error<
   "redeclaration of C++ built-in type 'bool'">;
 def ext_c11_static_assert : Extension<
@@ -361,6 +361,8 @@
   "unexpected parenthesis after '::'">;
 def err_function_definition_not_allowed : Error<
   "function definition is not allowed here">;
+def err_expected_end_of_enumerator : Error<
+  "expected '= constant-expression' or end of enumerator definition">;
 
 /// Objective-C parser diagnostics
 def err_expected_minus_or_plus : Error<
@@ -421,7 +423,7 @@
 def err_expected_objc_container : Error<
   "'@end' must appear in an Objective-C context">;
 def err_unexpected_protocol_qualifier : Error<
-  "@implementation declaration can not be protocol qualified">;
+  "@implementation declaration cannot be protocol qualified">;
 def err_objc_unexpected_atend : Error<
   "'@end' appears where closing brace '}' is expected">;
 def error_property_ivar_decl : Error<
@@ -446,6 +448,8 @@
   "cannot use %select{dot|arrow}0 operator on a type">;
 def err_expected_unqualified_id : Error<
   "expected %select{identifier|unqualified-id}0">;
+def err_brackets_go_after_unqualified_id : Error<
+  "brackets go after the %select{identifier|unqualified-id}0">;
 def err_unexpected_unqualified_id : Error<"type-id cannot have a name">;
 def err_func_def_no_params : Error<
   "function definition does not declare parameters">;
@@ -477,9 +481,6 @@
   "noexcept specifications are incompatible with C++98">,
   InGroup<CXX98Compat>, DefaultIgnore;
 def err_expected_catch : Error<"expected catch">;
-def err_expected_lbrace_or_comma : Error<"expected '{' or ','">;
-def err_expected_rbrace_or_comma : Error<"expected '}' or ','">;
-def err_expected_rsquare_or_comma : Error<"expected ']' or ','">;
 def err_using_namespace_in_class : Error<
   "'using namespace' is not allowed in classes">;
 def err_constructor_bad_name : Error<
@@ -501,8 +502,7 @@
   "ISO C++11 requires a parenthesized pack declaration to have a name">,
   InGroup<DiagGroup<"anonymous-pack-parens">>;
 def err_function_is_not_record : Error<
-  "unexpected '%select{.|->}0' in function call; perhaps remove the "
-  "'%select{.|->}0'?">;
+  "unexpected %0 in function call; perhaps remove the %0?">;
 
 // C++ derived classes
 def err_dup_virtual : Error<"duplicate 'virtual' in base specifier">;
@@ -532,10 +532,12 @@
 def warn_cxx98_compat_alignas : Warning<"'alignas' is incompatible with C++98">,
   InGroup<CXX98Compat>, DefaultIgnore;
 def warn_cxx98_compat_attribute : Warning<
-  "attributes are incompatible with C++98">,
+  "C++11 attribute syntax is incompatible with C++98">,
   InGroup<CXX98Compat>, DefaultIgnore;
 def err_cxx11_attribute_forbids_arguments : Error<
-  "attribute '%0' cannot have an argument list">;
+  "attribute %0 cannot have an argument list">;
+def err_attribute_requires_arguments : Error<
+  "parentheses must be omitted if %0 attribute's argument list is empty">;
 def err_cxx11_attribute_forbids_ellipsis : Error<
   "attribute '%0' cannot be used as an attribute pack">;
 def err_cxx11_attribute_repeated : Error<
@@ -546,8 +548,6 @@
   "introducing an attribute">;
 def err_ms_declspec_type : Error<
   "__declspec attributes must be an identifier or string literal">;
-def warn_ms_declspec_unknown : Warning<
-  "unknown __declspec attribute %0 ignored">, InGroup<UnknownAttributes>;
 def err_ms_property_no_getter_or_putter : Error<
   "property does not specify a getter or a putter">;
 def err_ms_property_unknown_accessor : Error<
@@ -573,10 +573,17 @@
   "expected ',' or '>' in template-parameter-list">;
 def err_class_on_template_template_param : Error<
   "template template parameter requires 'class' after the parameter list">;
+def ext_template_template_param_typename : ExtWarn<
+  "template template parameter using 'typename' is a C++1z extension">,
+  InGroup<CXX1z>;
+def warn_cxx1y_compat_template_template_param_typename : Warning<
+  "template template parameter using 'typename' is "
+  "incompatible with C++ standards before C++1z">,
+  InGroup<CXXPre1zCompat>, DefaultIgnore;
 def err_template_spec_syntax_non_template : Error<
   "identifier followed by '<' indicates a class template specialization but "
-  "%0 %select{does not refer to a template|refers to a function "
-  "template|<unused>|refers to a template template parameter}1">;
+  "%0 %select{does not refer to a template|refers to a function template|"
+  "<unused>|refers to a variable template|<unused>}1">;
 def err_id_after_template_in_nested_name_spec : Error<
   "expected template name after 'template' keyword in nested name specifier">;
 def err_two_right_angle_brackets_need_space : Error<
@@ -636,16 +643,13 @@
   "expected a qualified name after 'typename'">;
 def warn_expected_qualified_after_typename : ExtWarn<
   "expected a qualified name after 'typename'">;
-def err_expected_semi_after_tagdecl : Error<
-  "expected ';' after %0">;
 
 def err_typename_refers_to_non_type_template : Error<
-  "typename specifier refers to a non-template">;
+  "typename specifier refers to a non-type template">;
 def err_expected_type_name_after_typename : Error<
   "expected an identifier or template-id after '::'">;
 def err_explicit_spec_non_template : Error<
-  "explicit %select{specialization|instantiation}0 of non-template "
-  "%select{class|struct|union|interface}1 %2">;
+  "explicit %select{specialization|instantiation}0 of non-template %1 %2">;
   
 def err_default_template_template_parameter_not_template : Error<
   "default template argument for a template template parameter must be a class "
@@ -741,7 +745,8 @@
   "lambda expressions are incompatible with C++98">,
   InGroup<CXX98Compat>, DefaultIgnore;
 def err_lambda_missing_parens : Error<
-  "lambda requires '()' before %select{'mutable'|return type}0">;
+  "lambda requires '()' before %select{'mutable'|return type|"
+  "attribute specifier}0">;
 
 // Availability attribute
 def err_expected_version : Error<
@@ -750,6 +755,13 @@
   "version number must have non-zero major, minor, or sub-minor version">;
 def err_availability_expected_platform : Error<
   "expected a platform name, e.g., 'macosx'">;
+  
+// objc_bridge_related attribute
+def err_objcbridge_related_expected_related_class : Error<
+  "expected a related ObjectiveC class name, e.g., 'NSColor'">;
+def err_objcbridge_related_selector_name : Error<
+  "expected a class method selector with single argument, e.g., 'colorWithCGColor:'">;
+
 def err_availability_expected_change : Error<
   "expected 'introduced', 'deprecated', or 'obsoleted'">;
 def err_availability_unknown_change : Error<
@@ -766,35 +778,82 @@
 def err_type_safety_unknown_flag : Error<
   "invalid comparison flag %0; use 'layout_compatible' or 'must_be_null'">;
 
+// Type traits
+def err_type_trait_arity : Error<
+  "type trait requires %0%select{| or more}1 argument%select{|s}2; have "
+  "%3 argument%s3">;
+
 // Language specific pragmas
 // - Generic warnings
 def warn_pragma_expected_lparen : Warning<
-  "missing '(' after '#pragma %0' - ignoring">;
+  "missing '(' after '#pragma %0' - ignoring">, InGroup<IgnoredPragmas>;
 def warn_pragma_expected_rparen : Warning<
-  "missing ')' after '#pragma %0' - ignoring">;
+  "missing ')' after '#pragma %0' - ignoring">, InGroup<IgnoredPragmas>;
 def warn_pragma_expected_identifier : Warning<
-  "expected identifier in '#pragma %0' - ignored">;  
+  "expected identifier in '#pragma %0' - ignored">, InGroup<IgnoredPragmas>;
+def warn_pragma_expected_section_name : Warning<
+  "expected a string literal for the section name in '#pragma %0' - ignored">,
+  InGroup<IgnoredPragmas>;
+def warn_pragma_expected_section_push_pop_or_name : Warning<
+  "expected push, pop or a string literal for the section name in '#pragma %0' - ignored">,
+  InGroup<IgnoredPragmas>;
+def warn_pragma_expected_section_label_or_name : Warning<
+  "expected a stack label or a string literal for the section name in '#pragma %0' - ignored">,
+  InGroup<IgnoredPragmas>;
+def warn_pragma_expected_init_seg : Warning<
+  "expected 'compiler', 'lib', 'user', or a string literal for the section name in '#pragma %0' - ignored">,
+  InGroup<IgnoredPragmas>;
+def warn_pragma_expected_integer : Warning<
+  "expected integer between %0 and %1 inclusive in '#pragma %2' - ignored">,
+  InGroup<IgnoredPragmas>;
 def warn_pragma_ms_struct : Warning<
-  "incorrect use of '#pragma ms_struct on|off' - ignored">;  
+  "incorrect use of '#pragma ms_struct on|off' - ignored">,
+  InGroup<IgnoredPragmas>;
 def warn_pragma_extra_tokens_at_eol : Warning<
-  "extra tokens at end of '#pragma %0' - ignored">; 
+  "extra tokens at end of '#pragma %0' - ignored">,
+  InGroup<IgnoredPragmas>;
+def warn_pragma_expected_punc : Warning<
+  "expected ')' or ',' in '#pragma %0'">, InGroup<IgnoredPragmas>;
+def warn_pragma_expected_non_wide_string : Warning<
+  "expected non-wide string literal in '#pragma %0'">, InGroup<IgnoredPragmas>;
+// - Generic errors
+def err_pragma_missing_argument : Error<
+  "missing argument to '#pragma %0'; expected %1">;
 // - #pragma options
 def warn_pragma_options_expected_align : Warning<
-  "expected 'align' following '#pragma options' - ignored">;
+  "expected 'align' following '#pragma options' - ignored">,
+  InGroup<IgnoredPragmas>;
 def warn_pragma_align_expected_equal : Warning<
-  "expected '=' following '#pragma %select{align|options align}0' - ignored">;
+  "expected '=' following '#pragma %select{align|options align}0' - ignored">,
+  InGroup<IgnoredPragmas>;
 def warn_pragma_align_invalid_option : Warning<
-  "invalid alignment option in '#pragma %select{align|options align}0' - ignored">;
+  "invalid alignment option in '#pragma %select{align|options align}0' - ignored">,
+  InGroup<IgnoredPragmas>;
 // - #pragma pack
-def warn_pragma_pack_invalid_action : Warning<
-  "unknown action for '#pragma pack' - ignored">;
+def warn_pragma_unsupported_action : Warning<
+  "known but unsupported action '%1' for '#pragma %0' - ignored">,
+  InGroup<IgnoredPragmas>;
+def warn_pragma_invalid_specific_action : Warning<
+  "unknown action '%1' for '#pragma %0' - ignored">,
+  InGroup<IgnoredPragmas>;
+def warn_pragma_expected_action_or_r_paren : Warning<
+  "expected action or ')' in '#pragma %0' - ignored">,
+  InGroup<IgnoredPragmas>;
+def warn_pragma_invalid_action : Warning<
+  "unknown action for '#pragma %0' - ignored">,
+  InGroup<IgnoredPragmas>;
 def warn_pragma_pack_malformed : Warning<
-  "expected integer or identifier in '#pragma pack' - ignored">;
+  "expected integer or identifier in '#pragma pack' - ignored">,
+  InGroup<IgnoredPragmas>;
 // - #pragma unused
 def warn_pragma_unused_expected_var : Warning<
-  "expected '#pragma unused' argument to be a variable name">;
-def warn_pragma_unused_expected_punc : Warning<
-  "expected ')' or ',' in '#pragma unused'">;
+  "expected '#pragma unused' argument to be a variable name">,
+  InGroup<IgnoredPragmas>;
+// - #pragma init_seg
+def warn_pragma_init_seg_unsupported_target : Warning<
+  "'#pragma init_seg' is only supported when targeting a "
+  "Microsoft environment">,
+  InGroup<IgnoredPragmas>;
 // - #pragma fp_contract
 def err_pragma_fp_contract_scope : Error<
   "'#pragma fp_contract' can only appear at file scope or at the start of a "
@@ -807,6 +866,16 @@
 def err_pragma_detect_mismatch_malformed : Error<
   "pragma detect_mismatch is malformed; it requires two comma-separated "
   "string literals">;
+// - #pragma pointers_to_members
+def err_pragma_pointers_to_members_unknown_kind : Error<
+  "unexpected %0, expected to see one of %select{|'best_case', 'full_generality', }1"
+  "'single_inheritance', 'multiple_inheritance', or 'virtual_inheritance'">;
+// - #pragma clang optimize on/off
+def err_pragma_optimize_invalid_argument : Error<
+  "unexpected argument '%0' to '#pragma clang optimize'; "
+  "expected 'on' or 'off'">;
+def err_pragma_optimize_extra_argument : Error<
+  "unexpected extra argument '%0' to '#pragma clang optimize'">;
 
 // OpenCL Section 6.8.g
 def err_not_opencl_storage_class_specifier : Error<
@@ -814,11 +883,11 @@
 
 // OpenCL EXTENSION pragma (OpenCL 1.1 [9.1])
 def warn_pragma_expected_colon : Warning<
-  "missing ':' after %0 - ignoring">;
+  "missing ':' after %0 - ignoring">, InGroup<IgnoredPragmas>;
 def warn_pragma_expected_enable_disable : Warning<
-  "expected 'enable' or 'disable' - ignoring">;
+  "expected 'enable' or 'disable' - ignoring">, InGroup<IgnoredPragmas>;
 def warn_pragma_unknown_extension : Warning<
-  "unknown OpenCL extension %0 - ignoring">;
+  "unknown OpenCL extension %0 - ignoring">, InGroup<IgnoredPragmas>;
 
 def err_seh_expected_handler : Error<
   "expected '__except' or '__finally' block">;
@@ -833,21 +902,35 @@
   "%0 only allowed in __finally block">;
 
 // OpenMP support.
-def warn_pragma_omp_ignored : Warning <
+def warn_pragma_omp_ignored : Warning<
   "unexpected '#pragma omp ...' in program">, InGroup<SourceUsesOpenMP>, DefaultIgnore;
-def warn_omp_extra_tokens_at_eol : Warning <
+def warn_omp_extra_tokens_at_eol : Warning<
   "extra tokens at the end of '#pragma omp %0' are ignored">,
   InGroup<ExtraTokens>;
-def err_omp_unknown_directive : Error <
+def err_omp_unknown_directive : Error<
   "expected an OpenMP directive">;
-def err_omp_unexpected_directive : Error <
+def err_omp_unexpected_directive : Error<
   "unexpected OpenMP directive '#pragma omp %0'">;
-def err_omp_expected_punc : Error <
-  "expected ',' or ')' in %select{'#pragma omp %1'|'%1' clause}0">;
-def err_omp_unexpected_clause : Error <
+def err_omp_expected_punc : Error<
+  "expected ',' or ')' in '%0' %select{clause|directive}1">;
+def err_omp_unexpected_clause : Error<
   "unexpected OpenMP clause '%0' in directive '#pragma omp %1'">;
-def err_omp_more_one_clause : Error <
+def err_omp_more_one_clause : Error<
   "directive '#pragma omp %0' cannot contain more than one '%1' clause">;
+def err_omp_immediate_directive : Error<
+  "'#pragma omp %0' cannot be an immediate substatement">;
+def err_omp_expected_identifier_for_critical : Error<
+  "expected identifier specifying the name of the 'omp critical' directive">;
+
+// Pragma loop support.
+def err_pragma_loop_invalid_option : Error<
+  "%select{invalid|missing}0 option%select{ %1|}0; expected vectorize, "
+  "vectorize_width, interleave, interleave_count, unroll, or unroll_count">;
+
+// Pragma unroll support.
+def warn_pragma_unroll_cuda_value_in_parens : Warning<
+  "argument to '#pragma unroll' should not be in parentheses in CUDA C/C++">,
+  InGroup<CudaCompat>;
 } // end of Parse Issue category.
 
 let CategoryName = "Modules Issue" in {
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 2c89d13..1665a45 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -14,6 +14,11 @@
 let Component = "Sema" in {
 let CategoryName = "Semantic Issue" in {
 
+def note_previous_decl : Note<"%0 declared here">;
+def note_entity_declared_at : Note<"%0 declared here">;
+def note_callee_decl : Note<"%0 declared here">;
+def note_defined_here : Note<"%0 defined here">;
+
 // For loop analysis
 def warn_variables_not_in_loop_body : Warning<
   "variable%select{s| %1|s %1 and %2|s %1, %2, and %3|s %1, %2, %3, and %4}0 "
@@ -30,6 +35,25 @@
   "been assigned">, InGroup<DiagGroup<"duplicate-enum">>, DefaultIgnore;
 def note_duplicate_element : Note<"element %0 also has value %1">;
 
+// Absolute value functions
+def warn_unsigned_abs : Warning<
+  "taking the absolute value of unsigned type %0 has no effect">,
+  InGroup<AbsoluteValue>;
+def note_remove_abs : Note<
+  "remove the call to '%0' since unsigned values cannot be negative">;
+def warn_abs_too_small : Warning<
+  "absolute value function %0 given an argument of type %1 but has parameter "
+  "of type %2 which may cause truncation of value">, InGroup<AbsoluteValue>;
+def warn_wrong_absolute_value_type : Warning<
+  "using %select{integer|floating point|complex}1 absolute value function %0 "
+  "when argument is of %select{integer|floating point|complex}2 type">,
+  InGroup<AbsoluteValue>;
+def note_replace_abs_function : Note<"use function '%0' instead">;
+
+def warn_infinite_recursive_function : Warning<
+  "all paths through this function will call itself">,
+  InGroup<InfiniteRecursion>, DefaultIgnore;
+
 // Constant expressions
 def err_expr_not_ice : Error<
   "expression is not an %select{integer|integral}0 constant expression">;
@@ -87,9 +111,9 @@
 def err_vla_decl_in_file_scope : Error<
   "variable length array declaration not allowed at file scope">;
 def err_vla_decl_has_static_storage : Error<
-  "variable length array declaration can not have 'static' storage duration">;
+  "variable length array declaration cannot have 'static' storage duration">;
 def err_vla_decl_has_extern_linkage : Error<
-  "variable length array declaration can not have 'extern' linkage">;
+  "variable length array declaration cannot have 'extern' linkage">;
 def ext_vla_folded_to_constant : Extension<
   "variable length array folded to constant array as an extension">, InGroup<GNUFoldingConstant>;
 
@@ -142,7 +166,7 @@
 def err_bad_variable_name : Error<
   "%0 cannot be the name of a variable or data member">;
 def err_bad_parameter_name : Error<
-  "'%0' cannot be the name of a parameter">;
+  "%0 cannot be the name of a parameter">;
 def err_parameter_name_omitted : Error<"parameter name omitted">;
 def warn_unused_parameter : Warning<"unused parameter %0">,
   InGroup<UnusedParameter>, DefaultIgnore;
@@ -215,10 +239,13 @@
   InGroup<ImplicitFunctionDeclare>;
 def note_function_suggestion : Note<"did you mean %0?">;
 
-def err_ellipsis_first_arg : Error<
-  "ISO C requires a named argument before '...'">;
+def err_ellipsis_first_param : Error<
+  "ISO C requires a named parameter before '...'">;
 def err_declarator_need_ident : Error<"declarator requires an identifier">;
-def err_bad_language : Error<"unknown linkage language">;
+def err_language_linkage_spec_unknown : Error<"unknown linkage language">;
+def err_language_linkage_spec_not_ascii : Error<
+  "string literal in language linkage specifier cannot have an "
+  "encoding-prefix">;
 def warn_use_out_of_scope_declaration : Warning<
   "use of out-of-scope declaration of %0">;
 def err_inline_non_function : Error<
@@ -251,9 +278,9 @@
 def err_using_decl_nested_name_specifier_is_not_base_class : Error<
   "using declaration refers into '%0', which is not a base class of %1">;
 def err_using_decl_constructor_not_in_direct_base : Error<
-  "%0 is not a direct base of %1, can not inherit constructors">;
+  "%0 is not a direct base of %1, cannot inherit constructors">;
 def err_using_decl_constructor_conflict : Error<
-  "can not inherit constructor, already inherited constructor with "
+  "cannot inherit constructor, already inherited constructor with "
   "the same signature">;
 def note_using_decl_constructor_conflict_current_ctor : Note<
   "conflicting constructor">;
@@ -267,18 +294,21 @@
 def note_using_decl_constructor_ellipsis : Note<
   "constructor declared with ellipsis here">;
 def err_using_decl_can_not_refer_to_class_member : Error<
-  "using declaration can not refer to class member">;
+  "using declaration cannot refer to class member">;
+def note_using_decl_class_member_workaround : Note<
+  "use %select{an alias declaration|a typedef declaration|a reference}0 "
+  "instead">;
 def err_using_decl_can_not_refer_to_namespace : Error<
-  "using declaration can not refer to namespace">;
+  "using declaration cannot refer to namespace">;
 def err_using_decl_constructor : Error<
-  "using declaration can not refer to a constructor">;
+  "using declaration cannot refer to a constructor">;
 def warn_cxx98_compat_using_decl_constructor : Warning<
   "inheriting constructors are incompatible with C++98">,
   InGroup<CXX98Compat>, DefaultIgnore;
 def err_using_decl_destructor : Error<
-  "using declaration can not refer to a destructor">;
+  "using declaration cannot refer to a destructor">;
 def err_using_decl_template_id : Error<
-  "using declaration can not refer to a template specialization">;
+  "using declaration cannot refer to a template specialization">;
 def note_using_decl_target : Note<"target of using declaration">;
 def note_using_decl_conflict : Note<"conflicting declaration">;
 def err_using_decl_redeclaration : Error<"redeclaration of using decl">;
@@ -319,7 +349,7 @@
 def err_thread_non_global : Error<
   "'%0' variables must have global storage">;
 def err_thread_unsupported : Error<
-  "thread-local storage is unsupported for the current target">;
+  "thread-local storage is not supported for the current target">;
 
 def warn_maybe_falloff_nonvoid_function : Warning<
   "control may reach end of non-void function">,
@@ -337,40 +367,42 @@
 def warn_suggest_noreturn_block : Warning<
   "block could be declared with attribute 'noreturn'">,
   InGroup<MissingNoreturn>, DefaultIgnore;
-def warn_unreachable : Warning<"will never be executed">,
-  InGroup<DiagGroup<"unreachable-code">>, DefaultIgnore;
+
+// Unreachable code.
+def warn_unreachable : Warning<
+  "code will never be executed">,
+  InGroup<UnreachableCode>, DefaultIgnore;
+def warn_unreachable_break : Warning<
+  "'break' will never be executed">,
+  InGroup<UnreachableCodeBreak>, DefaultIgnore;
+def warn_unreachable_return : Warning<
+  "'return' will never be executed">,
+  InGroup<UnreachableCodeReturn>, DefaultIgnore;
+def warn_unreachable_loop_increment : Warning<
+  "loop will run at most once (loop increment never executed)">,
+  InGroup<UnreachableCodeLoopIncrement>, DefaultIgnore;
+def note_unreachable_silence : Note<
+  "silence by adding parentheses to mark code as explicitly dead">;
 
 /// Built-in functions.
 def ext_implicit_lib_function_decl : ExtWarn<
   "implicitly declaring library function '%0' with type %1">;
-def note_please_include_header : Note<
-  "please include the header <%0> or explicitly provide a "
-  "declaration for '%1'">;
+def note_include_header_or_declare : Note<
+  "include the header <%0> or explicitly provide a declaration for '%1'">;
 def note_previous_builtin_declaration : Note<"%0 is a builtin with type %1">;
-def warn_implicit_decl_requires_stdio : Warning<
-  "declaration of built-in function '%0' requires inclusion of the header "
-  "<stdio.h>">,
-  InGroup<BuiltinRequiresHeader>;
-def warn_implicit_decl_requires_setjmp : Warning<
-  "declaration of built-in function '%0' requires inclusion of the header "
-  "<setjmp.h>">,
-  InGroup<BuiltinRequiresHeader>;
-def warn_implicit_decl_requires_ucontext : Warning<
-  "declaration of built-in function '%0' requires inclusion of the header "
-  "<ucontext.h>">,
+def warn_implicit_decl_requires_sysheader : Warning<
+  "declaration of built-in function '%1' requires inclusion of the header <%0>">,
   InGroup<BuiltinRequiresHeader>;
 def warn_redecl_library_builtin : Warning<
   "incompatible redeclaration of library function %0">,
   InGroup<DiagGroup<"incompatible-library-redeclaration">>;
 def err_builtin_definition : Error<"definition of builtin function %0">;
-def err_types_compatible_p_in_cplusplus : Error<
-  "__builtin_types_compatible_p is not valid in C++">;
 def warn_builtin_unknown : Warning<"use of unknown builtin %0">,
   InGroup<ImplicitFunctionDeclare>, DefaultError;
 def warn_dyn_class_memaccess : Warning<
   "%select{destination for|source of|first operand of|second operand of}0 this "
-  "%1 call is a pointer to dynamic class %2; vtable pointer will be "
-  "%select{overwritten|copied|moved|compared}3">,
+  "%1 call is a pointer to %select{|class containing a }2dynamic class %3; "
+  "vtable pointer will be %select{overwritten|copied|moved|compared}4">,
   InGroup<DiagGroup<"dynamic-class-memaccess">>;
 def note_bad_memaccess_silence : Note<
   "explicitly cast the pointer to silence this warning">;
@@ -388,11 +420,18 @@
   "%select{destination|source}2; expected %3 or an explicit length">,
   InGroup<SizeofPointerMemaccess>;
 def warn_strlcpycat_wrong_size : Warning<
-  "size argument in %0 call appears to be size of the source; expected the size of "
-  "the destination">,
+  "size argument in %0 call appears to be size of the source; "
+  "expected the size of the destination">,
   InGroup<DiagGroup<"strlcpy-strlcat-size">>;
 def note_strlcpycat_wrong_size : Note<
   "change size argument to be the size of the destination">;
+def warn_memsize_comparison : Warning<
+  "size argument in %0 call is a comparison">,
+  InGroup<DiagGroup<"memsize-comparison">>;
+def note_memsize_comparison_paren : Note<
+  "did you mean to compare the result of %0 instead?">;
+def note_memsize_comparison_cast_silence : Note<
+  "explicitly cast the argument to size_t to silence this warning">;
   
 def warn_strncat_large_size : Warning<
   "the value of the size argument in 'strncat' is too large, might lead to a " 
@@ -405,6 +444,10 @@
   "change the argument to be the free space in the destination buffer minus " 
   "the terminating null byte">;
 
+def warn_assume_side_effects : Warning<
+  "the argument to __assume has side effects that will be discarded">,
+  InGroup<DiagGroup<"assume">>;
+
 /// main()
 // static main() is not an error in C, just in C++.
 def warn_static_main : Warning<"'main' should not be declared static">,
@@ -416,7 +459,8 @@
 def note_main_remove_noreturn : Note<"remove '_Noreturn'">;
 def err_constexpr_main : Error<
   "'main' is not allowed to be declared constexpr">;
-def err_mainlike_template_decl : Error<"'%0' cannot be a template">;
+def err_deleted_main : Error<"'main' is not allowed to be deleted">;
+def err_mainlike_template_decl : Error<"%0 cannot be a template">;
 def err_main_returns_nonint : Error<"'main' must return 'int'">;
 def ext_main_returns_nonint : ExtWarn<"return type of 'main' is not 'int'">,
     InGroup<MainReturnType>;
@@ -428,6 +472,8 @@
 def err_main_arg_wrong : Error<"%select{first|second|third|fourth}0 "
     "parameter of 'main' (%select{argument count|argument array|environment|"
     "platform-specific data}0) must be of type %1">;
+def ext_main_used : Extension<
+  "ISO C++ does not allow 'main' to be used by a program">, InGroup<Main>;
 
 /// parser diagnostics
 def ext_no_declarators : ExtWarn<"declaration does not declare anything">,
@@ -435,6 +481,10 @@
 def ext_typedef_without_a_name : ExtWarn<"typedef requires a name">,
   InGroup<MissingDeclarations>;
 def err_typedef_not_identifier : Error<"typedef name must be an identifier">;
+def err_typedef_changes_linkage : Error<"unsupported: typedef changes linkage"
+  " of anonymous type, but linkage was already computed">;
+def note_typedef_changes_linkage : Note<"use a tag name here to establish "
+  "linkage prior to definition">;
 def err_statically_allocated_object : Error<
   "interface type cannot be statically allocated">;
 def err_object_cannot_be_passed_returned_by_value : Error<
@@ -447,28 +497,37 @@
 def err_opencl_cast_to_half : Error<"casting to type %0 is not allowed">;
 def err_opencl_half_declaration : Error<
   "declaring variable of type %0 is not allowed">;
-def err_opencl_half_argument : Error<
-  "declaring function argument of type %0 is not allowed; did you forget * ?">;
+def err_opencl_half_param : Error<
+  "declaring function parameter of type %0 is not allowed; did you forget * ?">;
 def err_opencl_half_return : Error<
   "declaring function return value of type %0 is not allowed; did you forget * ?">;
 def warn_enum_value_overflow : Warning<"overflow in enumeration value">;
 def warn_pragma_options_align_reset_failed : Warning<
-  "#pragma options align=reset failed: %0">;
+  "#pragma options align=reset failed: %0">,
+  InGroup<IgnoredPragmas>;
 def err_pragma_options_align_mac68k_target_unsupported : Error<
   "mac68k alignment pragma is not supported on this target">;
 def warn_pragma_pack_invalid_alignment : Warning<
-  "expected #pragma pack parameter to be '1', '2', '4', '8', or '16'">;
+  "expected #pragma pack parameter to be '1', '2', '4', '8', or '16'">,
+  InGroup<IgnoredPragmas>;
 // Follow the MSVC implementation.
 def warn_pragma_pack_show : Warning<"value of #pragma pack(show) == %0">;
 def warn_pragma_pack_pop_identifer_and_alignment : Warning<
   "specifying both a name and alignment to 'pop' is undefined">;
-def warn_pragma_pack_pop_failed : Warning<"#pragma pack(pop, ...) failed: %0">;
-def warn_pragma_ms_struct_failed : Warning<"#pramga ms_struct can not be used with dynamic classes or structures">, InGroup<IgnoredAttributes>;
+def warn_pragma_pop_failed : Warning<"#pragma %0(pop, ...) failed: %1">,
+  InGroup<IgnoredPragmas>;
+def warn_cxx_ms_struct :
+  Warning<"ms_struct may not produce MSVC-compatible layouts for classes "
+          "with base classes or virtual functions">,
+  DefaultError, InGroup<IncompatibleMSStruct>;
+def err_section_conflict : Error<"%0 causes a section type conflict with %1">;
 
 def warn_pragma_unused_undeclared_var : Warning<
-  "undeclared variable %0 used as an argument for '#pragma unused'">;
+  "undeclared variable %0 used as an argument for '#pragma unused'">,
+  InGroup<IgnoredPragmas>;
 def warn_pragma_unused_expected_var_arg : Warning<
-  "only variables can be arguments to '#pragma unused'">;
+  "only variables can be arguments to '#pragma unused'">,
+  InGroup<IgnoredPragmas>;
 def err_pragma_push_visibility_mismatch : Error<
   "#pragma visibility push with no matching #pragma visibility pop">;
 def note_surrounding_namespace_ends_here : Note<
@@ -477,6 +536,14 @@
   "#pragma visibility pop with no matching #pragma visibility push">;
 def note_surrounding_namespace_starts_here : Note<
   "surrounding namespace with visibility attribute starts here">;
+def err_pragma_loop_invalid_value : Error<
+  "invalid argument; expected a positive integer value">;
+def err_pragma_loop_invalid_keyword : Error<
+  "invalid argument; expected 'enable' or 'disable'">;
+def err_pragma_loop_compatibility : Error<
+  "%select{incompatible|duplicate}0 directives '%1' and '%2'">;
+def err_pragma_loop_precedes_nonloop : Error<
+  "expected a for, while, or do-while loop to follow '%0'">;
 
 /// Objective-C parser diagnostics
 def err_duplicate_class_def : Error<
@@ -547,12 +614,10 @@
   "instance variable %0 has conflicting bit-field width">;
 def err_conflicting_ivar_name : Error<
   "conflicting instance variable names: %0 vs %1">;
-def err_inconsistant_ivar_count : Error<
+def err_inconsistent_ivar_count : Error<
   "inconsistent number of instance variables specified">;
 def warn_undef_method_impl : Warning<"method definition for %0 not found">,
   InGroup<DiagGroup<"incomplete-implementation">>;
-def note_required_for_protocol_at : 
-  Note<"required for direct or indirect protocol %0">;
 
 def warn_conflicting_overriding_ret_types : Warning<
   "conflicting return type in "
@@ -696,21 +761,21 @@
 def err_atomic_property_nontrivial_assign_op : Error<
   "atomic property of reference type %0 cannot have non-trivial assignment"
   " operator">;
-def warn_owning_getter_rule : Warning<
-  "property's synthesized getter follows Cocoa naming"
+def warn_cocoa_naming_owned_rule : Warning<
+  "property follows Cocoa naming"
   " convention for returning 'owned' objects">,
   InGroup<DiagGroup<"objc-property-matches-cocoa-ownership-rule">>;
 def warn_auto_synthesizing_protocol_property :Warning<
-  "auto property synthesis will not synthesize property"
-  " declared in a protocol">,
+  "auto property synthesis will not synthesize property %0"
+  " declared in protocol %1">,
   InGroup<DiagGroup<"objc-protocol-property-synthesis">>;
 def warn_no_autosynthesis_shared_ivar_property : Warning <
   "auto property synthesis will not synthesize property "
-  "'%0' because it cannot share an ivar with another synthesized property">,
+  "%0 because it cannot share an ivar with another synthesized property">,
   InGroup<ObjCNoPropertyAutoSynthesis>;
 def warn_no_autosynthesis_property : Warning<
   "auto property synthesis will not synthesize property "
-  "'%0' because it is 'readwrite' but it will be synthesized 'readonly' "
+  "%0 because it is 'readwrite' but it will be synthesized 'readonly' "
   "via another property">,
   InGroup<ObjCNoPropertyAutoSynthesis>;
 def warn_autosynthesis_property_ivar_match :Warning<
@@ -724,10 +789,10 @@
   "property declared as returning non-retained objects"
   "; getter returning retained objects">;
 def error_property_setter_ambiguous_use : Error<
-  "synthesized properties '%0' and '%1' both claim setter %2 -"
+  "synthesized properties %0 and %1 both claim setter %2 -"
   " use of this setter will cause unexpected behavior">;
-def err_ownin_getter_rule : Error<
-  "property's synthesized getter follows Cocoa naming"
+def err_cocoa_naming_owned_rule : Error<
+  "property follows Cocoa naming"
   " convention for returning 'owned' objects">;
 def warn_default_atomic_custom_getter_setter : Warning<
   "atomic by default property %0 has a user defined %select{getter|setter}1 "
@@ -778,6 +843,9 @@
 def warn_arc_perform_selector_leaks : Warning<
   "performSelector may cause a leak because its selector is unknown">,
   InGroup<DiagGroup<"arc-performSelector-leaks">>;
+def warn_dealloc_in_category : Warning<
+"-dealloc is being overridden in a category">,
+InGroup<DeallocInCategory>;
 def err_gc_weak_property_strong_type : Error<
   "weak attribute declared on a __strong type property in GC mode">;
 def warn_receiver_is_weak : Warning <
@@ -818,13 +886,10 @@
 def error_strong_property : Error<
   "existing instance variable %1 for strong property %0 may not be __weak">;
 def error_dynamic_property_ivar_decl : Error<
-  "dynamic property can not have instance variable specification">;
+  "dynamic property cannot have instance variable specification">;
 def error_duplicate_ivar_use : Error<
   "synthesized properties %0 and %1 both claim instance variable %2">;
 def error_property_implemented : Error<"property %0 is already implemented">;
-def warn_objc_property_attr_mutually_exclusive : Warning<
-  "property attributes '%0' and '%1' are mutually exclusive">,
-  InGroup<ReadOnlySetterAttrs>, DefaultIgnore;
 def warn_objc_missing_super_call : Warning<
   "method possibly missing a [super %0] call">,
   InGroup<ObjCMissingSuperCalls>;
@@ -841,23 +906,30 @@
 def note_auto_readonly_iboutlet_fixup_suggest : Note<
   "property should be changed to be readwrite">;
 def warn_auto_readonly_iboutlet_property : Warning<
-  "readonly IBOutlet property '%0' when auto-synthesized may "
+  "readonly IBOutlet property %0 when auto-synthesized may "
   "not work correctly with 'nib' loader">,
   InGroup<DiagGroup<"readonly-iboutlet-property">>;
 def warn_auto_implicit_atomic_property : Warning<
   "property is assumed atomic when auto-synthesizing the property">,
   InGroup<ImplicitAtomic>, DefaultIgnore;
 def warn_unimplemented_selector:  Warning<
-  "creating selector for nonexistent method %0">, InGroup<Selector>, DefaultIgnore;
-def warning_multiple_selectors: Warning<
-  "multiple selectors named %0 found">, InGroup<SelectorTypeMismatch>, DefaultIgnore;
+  "no method with selector %0 is implemented in this translation unit">, 
+  InGroup<Selector>, DefaultIgnore;
 def warn_unimplemented_protocol_method : Warning<
-  "method %0 in protocol not implemented">, InGroup<Protocol>;
-
+  "method %0 in protocol %1 not implemented">, InGroup<Protocol>;
+def warning_multiple_selectors: Warning<
+  "several methods with selector %0 of mismatched types are found "
+  "for the @selector expression">,
+  InGroup<SelectorTypeMismatch>, DefaultIgnore;
 // C++ declarations
 def err_static_assert_expression_is_not_constant : Error<
   "static_assert expression is not an integral constant expression">;
-def err_static_assert_failed : Error<"static_assert failed %0">;
+def err_static_assert_failed : Error<"static_assert failed%select{ %1|}0">;
+def ext_static_assert_no_message : ExtWarn<
+  "static_assert with no message is a C++1z extension">, InGroup<CXX1z>;
+def warn_cxx1y_compat_static_assert_no_message : Warning<
+  "static_assert with no message is incompatible with C++ standards before C++1z">,
+  DefaultIgnore, InGroup<CXXPre1zCompat>;
 
 def warn_inline_namespace_reopened_noninline : Warning<
   "inline namespace cannot be reopened as a non-inline namespace">;
@@ -918,7 +990,11 @@
   "dependent nested name specifier '%0' for friend template declaration is "
   "not supported; ignoring this friend declaration">,
   InGroup<UnsupportedFriend>;
-  
+def ext_friend_tag_redecl_outside_namespace : ExtWarn<
+  "unqualified friend declaration referring to type outside of the nearest "
+  "enclosing namespace is a Microsoft extension; add a nested name specifier">,
+  InGroup<Microsoft>;
+
 def err_invalid_member_in_interface : Error<
   "%select{data member |non-public member function |static member function |"
           "user-declared constructor|user-declared destructor|operator |"
@@ -937,19 +1013,23 @@
 def err_array_of_abstract_type : Error<"array of abstract class type %0">;
 def err_capture_of_abstract_type : Error<
   "by-copy capture of value of abstract type %0">;
+def err_capture_of_incomplete_type : Error<
+  "by-copy capture of variable %0 with incomplete type %1">;
+def err_capture_default_non_local : Error<
+  "non-local lambda expression cannot have a capture-default">;
 
 def err_multiple_final_overriders : Error<
   "virtual function %q0 has more than one final overrider in %1">; 
 def note_final_overrider : Note<"final overrider of %q0 in %1">;
 
 def err_type_defined_in_type_specifier : Error<
-  "%0 can not be defined in a type specifier">;
+  "%0 cannot be defined in a type specifier">;
 def err_type_defined_in_result_type : Error<
-  "%0 can not be defined in the result type of a function">;
+  "%0 cannot be defined in the result type of a function">;
 def err_type_defined_in_param_type : Error<
-  "%0 can not be defined in a parameter type">;
+  "%0 cannot be defined in a parameter type">;
 def err_type_defined_in_alias_template : Error<
-  "%0 can not be defined in a type alias template">;
+  "%0 cannot be defined in a type alias template">;
 
 def note_pure_virtual_function : Note<
   "unimplemented pure virtual method %0 in %1">;
@@ -988,12 +1068,13 @@
   "rvalue reference type %0 is not allowed in exception specification">;
 def err_mismatched_exception_spec : Error<
   "exception specification in declaration does not match previous declaration">;
-def warn_mismatched_exception_spec : ExtWarn<
-  "exception specification in declaration does not match previous declaration">;
+def ext_mismatched_exception_spec : ExtWarn<
+  "exception specification in declaration does not match previous declaration">,
+  InGroup<Microsoft>;
 def err_override_exception_spec : Error<
   "exception specification of overriding function is more lax than "
   "base version">;
-def warn_override_exception_spec : ExtWarn<
+def ext_override_exception_spec : ExtWarn<
   "exception specification of overriding function is more lax than "
   "base version">, InGroup<Microsoft>;
 def err_incompatible_exception_specs : Error<
@@ -1105,7 +1186,10 @@
 def warn_cxx98_compat_enum_nested_name_spec : Warning<
   "enumeration type in nested name specifier is incompatible with C++98">,
   InGroup<CXX98Compat>, DefaultIgnore;
-  
+def err_nested_name_spec_is_not_class : Error<
+  "%0 cannot appear before '::' because it is not a class"
+  "%select{ or namespace|, namespace, or scoped enumeration}1; did you mean ':'?">;
+
 // C++ class members
 def err_storageclass_invalid_for_member : Error<
   "storage class specified for a member declaration">;
@@ -1119,7 +1203,7 @@
 def err_virtual_out_of_class : Error<
   "'virtual' can only be specified inside the class definition">;
 def err_virtual_member_function_template : Error<
-  "'virtual' can not be specified on member function templates">;
+  "'virtual' cannot be specified on member function templates">;
 def err_static_overrides_virtual : Error<
   "'static' member function %0 overrides a virtual function in a base class">;
 def err_explicit_non_function : Error<
@@ -1142,7 +1226,7 @@
   "initializer on function does not look like a pure-specifier">;
 def err_non_virtual_pure : Error<
   "%0 is not virtual and cannot be declared pure">;
-def warn_pure_function_definition : ExtWarn<
+def ext_pure_function_definition : ExtWarn<
   "function definition with pure-specifier is a Microsoft extension">,
   InGroup<Microsoft>;
 def err_implicit_object_parameter_init : Error<
@@ -1155,10 +1239,9 @@
   "call to pure virtual member function %0; overrides of %0 in subclasses are "
   "not available in the %select{constructor|destructor}1 of %2">;
 
-def note_field_decl : Note<"member is declared here">;
+def note_member_declared_at : Note<"member is declared here">;
 def note_ivar_decl : Note<"instance variable is declared here">;
 def note_bitfield_decl : Note<"bit-field is declared here">;
-def note_previous_decl : Note<"%0 declared here">;
 def note_implicit_param_decl : Note<"%0 is an implicit parameter">;
 def note_member_synthesized_at : Note<
   "implicit %select{default constructor|copy constructor|move constructor|copy "
@@ -1419,6 +1502,9 @@
   InGroup<Uninitialized>, DefaultIgnore;
 def note_block_var_fixit_add_initialization : Note<
   "maybe you meant to use __block %0">;
+def note_in_omitted_aggregate_initializer : Note<
+  "in implicit initialization of %select{array element %1|field %1}0 "
+  "with omitted initializer">;
 def note_var_fixit_add_initialization : Note<
   "initialize the variable %0 to silence this warning">;
 def note_uninit_fixit_remove_cond : Note<
@@ -1495,16 +1581,22 @@
   "declaration of variable %0 with 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_requires_parens : Error<
+def err_auto_new_list_init : Error<
   "new expression for type %0 cannot use list-initialization">;
 def err_auto_var_init_no_expression : Error<
   "initializer for variable %0 with type %1 is empty">;
 def err_auto_var_init_multiple_expressions : Error<
   "initializer for variable %0 with type %1 contains multiple expressions">;
+def err_auto_var_init_paren_braces : Error<
+  "cannot deduce type for variable %0 with type %1 from "
+  "parenthesized initializer list">;
 def err_auto_new_ctor_multiple_expressions : Error<
   "new expression for type %0 contains multiple constructor arguments">;
 def err_auto_missing_trailing_return : Error<
-  "'auto' return without trailing return type">;
+  "'auto' return without trailing return type; deduced return types are a "
+  "C++1y extension">;
+def err_deduced_return_type : Error<
+  "deduced return types are a C++1y extension">;
 def err_trailing_return_without_auto : Error<
   "function with trailing return type must specify return type 'auto', not %0">;
 def err_trailing_return_in_parens : Error<
@@ -1570,7 +1662,7 @@
   "abstract class is marked '%select{final|sealed}0'">, InGroup<AbstractFinalClass>;
 
 // C++11 attributes
-def err_repeat_attribute : Error<"'%0' attribute cannot be repeated">;
+def err_repeat_attribute : Error<"%0 attribute cannot be repeated">;
 
 // C++11 final
 def err_final_function_overridden : Error<
@@ -1597,6 +1689,8 @@
   "not 'enum class'">;
 def err_only_enums_have_underlying_types : Error<
   "only enumeration types have underlying types">;
+def err_underlying_type_of_incomplete_enum : Error<
+  "cannot determine underlying type of incomplete enumeration type %0">;
 
 // C++11 delegating constructors
 def err_delegating_ctor : Error<
@@ -1730,6 +1824,8 @@
 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_constexpr_body_no_return : Error<
   "no return statement in constexpr function">;
 def warn_cxx11_compat_constexpr_body_no_return : Warning<
@@ -1786,21 +1882,16 @@
 
 // Attributes
 def err_nsobject_attribute : Error<
-  "__attribute ((NSObject)) is for pointer types only">;
-def err_attribute_can_be_applied_only_to_symbol_declaration : Error<
-  "%0 attribute can be applied only to symbol declaration">;
+  "'NSObject' attribute is for pointer types only">;
 def err_attributes_are_not_compatible : Error<
   "%0 and %1 attributes are not compatible">;
 def err_attribute_wrong_number_arguments : Error<
   "%0 attribute %plural{0:takes no arguments|1:takes one argument|"
   ":requires exactly %1 arguments}1">;
 def err_attribute_too_many_arguments : Error<
-  "attribute takes no more than %0 argument%s0">;
-def err_suppress_autosynthesis : Error<
-  "objc_requires_property_definitions attribute may only be specified on a class"
-  "to a class declaration">;
+  "%0 attribute takes no more than %1 argument%s1">;
 def err_attribute_too_few_arguments : Error<
-  "attribute takes at least %0 argument%s0">;
+  "%0 attribute takes at least %1 argument%s1">;
 def err_attribute_invalid_vector_type : Error<"invalid vector element type %0">;
 def err_attribute_bad_neon_vector_size : Error<
   "Neon vector size must be 64 or 128 bits">;
@@ -1809,14 +1900,11 @@
 def err_aligned_attribute_argument_not_int : Error<
   "'aligned' attribute requires integer constant">;
 def err_alignas_attribute_wrong_decl_type : Error<
-  "'%select{alignas|_Alignas}0' attribute cannot be applied to a %select{"
-  "function parameter|variable with 'register' storage class|"
-  "'catch' variable|bit-field}1">;
+  "%0 attribute cannot be applied to a %select{function parameter|"
+  "variable with 'register' storage class|'catch' variable|bit-field}1">;
 def err_alignas_missing_on_definition : Error<
-  "'%select{alignas|_Alignas}0' must be specified on definition if it is "
-  "specified on any declaration">;
-def note_alignas_on_declaration : Note<
-  "declared with '%select{alignas|_Alignas}0' attribute here">;
+  "%0 must be specified on definition if it is specified on any declaration">;
+def note_alignas_on_declaration : Note<"declared with %0 attribute here">;
 def err_alignas_mismatch : Error<
   "redeclaration has different alignment requirement (%1 vs %0)">;
 def err_alignas_underaligned : Error<
@@ -1836,17 +1924,20 @@
 def err_attribute_argument_vec_type_hint : Error<
   "invalid attribute argument %0 - expecting a vector or vectorizable scalar type">;
 def err_attribute_argument_out_of_bounds : Error<
-  "'%0' attribute parameter %1 is out of bounds">;
+  "%0 attribute parameter %1 is out of bounds">;
 def err_attribute_uuid_malformed_guid : Error<
   "uuid attribute contains a malformed GUID">;
-def warn_nonnull_pointers_only : Warning<
-  "nonnull attribute only applies to pointer arguments">;
-def err_attribute_pointers_only : Error<
-  "%0 attribute only applies to pointer arguments">;
+def warn_attribute_pointers_only : Warning<
+  "%0 attribute only applies to pointer arguments">,
+  InGroup<IgnoredAttributes>;
+def err_attribute_pointers_only : Error<warn_attribute_pointers_only.Text>;
+def warn_attribute_return_pointers_only : Warning<
+  "%0 attribute only applies to return values that are pointers">,
+  InGroup<IgnoredAttributes>;
 def err_attribute_no_member_pointers : Error<
   "%0 attribute cannot be used with pointers to members">;
 def err_attribute_invalid_implicit_this_argument : Error<
-  "'%0' attribute is invalid for the implicit this argument">;
+  "%0 attribute is invalid for the implicit this argument">;
 def err_ownership_type : Error<
   "%0 attribute only applies to %select{pointer|integer}1 arguments">;
 def err_format_strftime_third_parameter : Error<
@@ -1858,8 +1949,6 @@
 def err_format_attribute_implicit_this_format_string : Error<
   "format attribute cannot specify the implicit this argument as the format "
   "string">;
-def err_common_not_supported_cplusplus : Error<
-  "common attribute is not supported in C++">;
 def err_init_method_bad_return_type : Error<
   "init methods must return an object pointer type, not %0">;
 def err_attribute_invalid_size : Error<
@@ -1868,8 +1957,8 @@
 def err_attribute_size_too_large : Error<"vector size too large">;
 def err_typecheck_vector_not_convertable : Error<
   "can't convert between vector values of different size (%0 and %1)">;
-def err_typecheck_ext_vector_not_typedef : Error<
-  "ext_vector_type only applies to types, not variables">;
+def err_typecheck_vector_not_convertable_non_scalar : Error<
+  "can't convert between vector and non-scalar values (%0 and %1)">;
 def err_ext_vector_component_exceeds_length : Error<
   "vector component access exceeds type %0">;
 def err_ext_vector_component_name_illegal : Error<
@@ -1923,8 +2012,8 @@
   "direct comparison of %select{an array literal|a dictionary literal|"
   "a numeric literal|a boxed expression|}0 has undefined behavior">,
   InGroup<ObjCLiteralComparison>;
-def warn_missing_atsign_prefix : Warning<
-  "string literal must be prefixed by '@' ">, InGroup<ObjCLiteralMissingAtSign>;
+def err_missing_atsign_prefix : Error<
+  "string literal must be prefixed by '@' ">;
 def warn_objc_string_literal_comparison : Warning<
   "direct comparison of a string literal has undefined behavior">, 
   InGroup<ObjCStringComparison>;
@@ -1934,6 +2023,11 @@
   InGroup<ObjCStringConcatenation>;
 def note_objc_literal_comparison_isequal : Note<
   "use 'isEqual:' instead">;
+def err_attribute_argument_is_zero : Error<
+  "%0 attribute must be greater than 0">;
+def err_property_function_in_objc_container : Error<
+  "use of Objective-C property in function nested in Objective-C "
+  "container not supported, move function outside its container">;
 
 let CategoryName = "Cocoa API Issue" in {
 def warn_objc_redundant_literal_use : Warning<
@@ -1948,30 +2042,24 @@
 
 def err_attribute_section_invalid_for_target : Error<
   "argument to 'section' attribute is not valid for this target: %0">;
-def err_attribute_section_local_variable : Error<
-  "'section' attribute is not valid on local variables">;
 def warn_mismatched_section : Warning<
   "section does not match previous declaration">, InGroup<Section>;
 
 def err_anonymous_property: Error<
   "anonymous property is not supported">;
-def err_property_is_variably_modified: Error<
-  "property '%0' has a variably modified type">;
-def err_no_getter_for_property : Error<
-  "no getter defined for property '%0'">;
-def err_no_setter_for_property : Error<
-  "no setter defined for property '%0'">;
-def error_cannot_find_suitable_getter : Error<
-  "cannot find suitable getter for property '%0'">;
-def error_cannot_find_suitable_setter : Error<
-  "cannot find suitable setter for property '%0'">;
+def err_property_is_variably_modified : Error<
+  "property %0 has a variably modified type">;
+def err_no_accessor_for_property : Error<
+  "no %select{getter|setter}0 defined for property %1">;
+def error_cannot_find_suitable_accessor : Error<
+  "cannot find suitable %select{getter|setter}0 for property %1">;
 
 def err_attribute_aligned_not_power_of_two : Error<
   "requested alignment is not a power of 2">;
-def err_attribute_aligned_greater_than_8192 : Error<
-  "requested alignment must be 8192 bytes or smaller">;
+def err_attribute_aligned_too_great : Error<
+  "requested alignment must be %0 bytes or smaller">;
 def warn_redeclaration_without_attribute_prev_attribute_ignored : Warning<
-  "'%0' redeclared without %1 attribute: previous %1 ignored">;
+  "%q0 redeclared without %1 attribute: previous %1 ignored">;
 def warn_attribute_ignored : Warning<"%0 attribute ignored">,
   InGroup<IgnoredAttributes>;
 def warn_attribute_after_definition_ignored : Warning<
@@ -2005,8 +2093,8 @@
   "Objective-C GC does not allow weak variables on the stack">,
   InGroup<IgnoredAttributes>;
 def warn_nsobject_attribute : Warning<
-  "__attribute ((NSObject)) may be put on a typedef only, "
-  "attribute is ignored">, InGroup<NSobjectAttribute>;
+  "'NSObject' attribute may be put on a typedef only; attribute is ignored">,
+  InGroup<NSobjectAttribute>;
 def warn_attribute_weak_on_local : Warning<
   "__weak attribute cannot be specified on an automatic variable when ARC "
   "is not enabled">,
@@ -2017,19 +2105,59 @@
   "weak declaration cannot have internal linkage">;
 def err_attribute_selectany_non_extern_data : Error<
   "'selectany' can only be applied to data items with external linkage">;
+def err_declspec_thread_on_thread_variable : Error<
+  "'__declspec(thread)' applied to variable that already has a "
+  "thread-local storage specifier">;
+def err_attribute_dll_not_extern : Error<
+  "%q0 must have external linkage when declared %q1">;
 def warn_attribute_invalid_on_definition : Warning<
   "'%0' attribute cannot be specified on a definition">,
   InGroup<IgnoredAttributes>;
+def err_attribute_dll_redeclaration : Error<
+  "redeclaration of %q0 cannot add %q1 attribute">;
+def warn_attribute_dll_redeclaration : Warning<
+  "redeclaration of %q0 should not add %q1 attribute">,
+  InGroup<DiagGroup<"dll-attribute-on-redeclaration">>;
+def err_attribute_dllimport_function_definition : Error<
+  "dllimport cannot be applied to non-inline function definition">;
+def err_attribute_dll_deleted : Error<
+  "attribute %q0 cannot be applied to a deleted function">;
+def err_attribute_dllimport_data_definition : Error<
+  "definition of dllimport data">;
+def err_attribute_dllimport_static_field_definition : Error<
+  "definition of dllimport static field not allowed">;
+def warn_attribute_dllimport_static_field_definition : Warning<
+  "definition of dllimport static field">,
+  InGroup<DiagGroup<"dllimport-static-field-def">>;
+def warn_invalid_initializer_from_system_header : Warning<
+  "invalid constructor form class in system header, should not be explicit">,
+  InGroup<DiagGroup<"invalid-initializer-from-system-header">>;
+def note_used_in_initialization_here : Note<"used in initialization here">;
+def err_attribute_dll_member_of_dll_class : Error<
+  "attribute %q0 cannot be applied to member of %q1 class">;
+def warn_attribute_dll_instantiated_base_class : Warning<
+  "propagating dll attribute to %select{already instantiated|explicitly specialized}0 "
+  "base class template "
+  "%select{without dll attribute|with different dll attribute}1 is not supported">,
+  InGroup<DiagGroup<"unsupported-dll-base-class-template">>;
 def err_attribute_weakref_not_static : Error<
   "weakref declaration must have internal linkage">;
 def err_attribute_weakref_not_global_context : Error<
-  "weakref declaration of '%0' must be in a global context">;
+  "weakref declaration of %0 must be in a global context">;
 def err_attribute_weakref_without_alias : Error<
-  "weakref declaration of '%0' must also have an alias attribute">;
+  "weakref declaration of %0 must also have an alias attribute">;
 def err_alias_not_supported_on_darwin : Error <
   "only weak aliases are supported on darwin">;
 def err_alias_to_undefined : Error<
   "alias must point to a defined variable or function">;
+def warn_alias_to_weak_alias : Warning<
+  "alias will always resolve to %0 even if weak definition of alias %1 is overridden">,
+  InGroup<IgnoredAttributes>;
+def warn_alias_with_section : Warning<
+  "alias will not be in section '%0' but in the same section as the aliasee">,
+  InGroup<IgnoredAttributes>;
+def err_duplicate_mangled_name : Error<
+  "definition with same mangled name as another definition">;
 def err_cyclic_alias : Error<
   "alias definition is part of a cycle">;
 def warn_attribute_wrong_decl_type : Warning<
@@ -2040,18 +2168,14 @@
   "variables, functions and labels|fields and global variables|structs|"
   "variables, functions and tag types|thread-local variables|"
   "variables and fields|variables, data members and tag types|"
-  "types and namespaces|Objective-C interfaces}1">,
+  "types and namespaces|Objective-C interfaces|methods and properties|"
+  "struct or union|struct, union or class|types|"
+  "Objective-C instance methods|init methods of interface or class extension declarations|"
+  "variables, functions and classes|Objective-C protocols|"
+  "functions and global variables|structs or typedefs|"
+  "interface or protocol declarations}1">,
   InGroup<IgnoredAttributes>;
-def err_attribute_wrong_decl_type : Error<
-  "%0 attribute only applies to %select{functions|unions|"
-  "variables and functions|functions and methods|parameters|"
-  "functions, methods and blocks|functions, methods, and classes|"
-  "functions, methods, and parameters|classes|variables|methods|"
-  "variables, functions and labels|fields and global variables|structs|"
-  "variables, functions and tag types|thread-local variables|"
-  "variables and fields|variables, data members and tag types|"
-  "types and namespaces|Objective-C interfaces|"
-  "methods and properties}1">;
+def err_attribute_wrong_decl_type : Error<warn_attribute_wrong_decl_type.Text>;
 def warn_type_attribute_wrong_type : Warning<
   "'%0' only applies to %select{function|pointer|"
   "Objective-C object or block pointer}1 types; type here is %2">,
@@ -2091,8 +2215,6 @@
   "objc_precise_lifetime is not meaningful for "
   "%select{__unsafe_unretained|__autoreleasing}0 objects">;
 def err_invalid_pcs : Error<"invalid PCS type">;
-def err_attribute_can_be_applied_only_to_value_decl : Error<
-  "%0 attribute can only be applied to value declarations">;
 def warn_attribute_not_on_decl : Warning<
   "%0 attribute ignored when parsing type">, InGroup<IgnoredAttributes>;
 def err_base_specifier_attribute : Error<
@@ -2119,29 +2241,23 @@
   "overridden method is here">;
 
 // Thread Safety Attributes
+def warn_invalid_capability_name : Warning<
+  "invalid capability name '%0'; capability name must be 'mutex' or 'role'">,
+  InGroup<ThreadSafetyAttributes>, DefaultIgnore;
 def warn_thread_attribute_ignored : Warning<
   "ignoring %0 attribute because its argument is invalid">,
   InGroup<ThreadSafetyAttributes>, DefaultIgnore;
 def warn_thread_attribute_argument_not_lockable : Warning<
   "%0 attribute requires arguments whose type is annotated "
-  "with 'lockable' attribute; type here is '%1'">,
+  "with 'capability' attribute; type here is %1">,
   InGroup<ThreadSafetyAttributes>, DefaultIgnore;
-def warn_thread_attribute_argument_not_class : Warning<
-  "%0 attribute requires arguments that are class type or point to"
-  " class type; type here is '%1'">,
-  InGroup<ThreadSafetyAttributes>, DefaultIgnore;  
 def warn_thread_attribute_decl_not_lockable : Warning<
   "%0 attribute can only be applied in a context annotated "
-  "with 'lockable' attribute">,
+  "with 'capability(\"mutex\")' attribute">,
   InGroup<ThreadSafetyAttributes>, DefaultIgnore;
 def warn_thread_attribute_decl_not_pointer : Warning<
-  "'%0' only applies to pointer types; type here is %1">,
+  "%0 only applies to pointer types; type here is %1">,
   InGroup<ThreadSafetyAttributes>, DefaultIgnore;
-def warn_thread_attribute_wrong_decl_type : Warning<
-  "%0 attribute only applies to %select{"
-  "fields and global variables|functions and methods|"
-  "classes and structs}1">,
-  InGroup<ThreadSafetyAttributes>, DefaultIgnore;  
 def err_attribute_argument_out_of_range : Error<
   "%0 attribute parameter %1 is out of bounds: "
   "%plural{0:no parameters to index into|"
@@ -2149,41 +2265,43 @@
   ":must be between 1 and %2}2">;
 
 // Thread Safety Analysis   
-def warn_unlock_but_no_lock : Warning<
-  "unlocking '%0' that was not locked">,
+def warn_unlock_but_no_lock : Warning<"releasing %0 '%1' that was not held">,
   InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
-def warn_double_lock : Warning<
-  "locking '%0' that is already locked">,
+def warn_unlock_kind_mismatch : Warning<
+  "releasing %0 '%1' using %select{shared|exclusive}2 access, expected "
+  "%select{shared|exclusive}3 access">,
+  InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
+def warn_double_lock : Warning<"acquiring %0 '%1' that is already held">,
   InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
 def warn_no_unlock : Warning<
-  "mutex '%0' is still locked at the end of function">,
+  "%0 '%1' is still held at the end of function">,
   InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
 def warn_expecting_locked : Warning<
-  "expecting mutex '%0' to be locked at the end of function">,
+  "expecting %0 '%1' to be held at the end of function">,
   InGroup<ThreadSafetyAnalysis>, DefaultIgnore;  
 // FIXME: improve the error message about locks not in scope
 def warn_lock_some_predecessors : Warning<
-  "mutex '%0' is not locked on every path through here">,
+  "%0 '%1' is not held on every path through here">,
   InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
 def warn_expecting_lock_held_on_loop : Warning<
-  "expecting mutex '%0' to be locked at start of each loop">,
+  "expecting %0 '%1' to be held at start of each loop">,
   InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
-def note_locked_here : Note<"mutex acquired here">;
+def note_locked_here : Note<"%0 acquired here">;
 def warn_lock_exclusive_and_shared : Warning<
-  "mutex '%0' is locked exclusively and shared in the same scope">,
+  "%0 '%1' is acquired exclusively and shared in the same scope">,
   InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
 def note_lock_exclusive_and_shared : Note<
-  "the other lock of mutex '%0' is here">;
+  "the other acquisition of %0 '%1' is here">;
 def warn_variable_requires_any_lock : Warning<
-  "%select{reading|writing}1 variable '%0' requires locking "
+  "%select{reading|writing}1 variable '%0' requires holding "
   "%select{any mutex|any mutex exclusively}1">,
   InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
 def warn_var_deref_requires_any_lock : Warning<
-  "%select{reading|writing}1 the value pointed to by '%0' requires locking "
+  "%select{reading|writing}1 the value pointed to by '%0' requires holding "
   "%select{any mutex|any mutex exclusively}1">,
   InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
 def warn_fun_excludes_mutex : Warning<
-  "cannot call function '%0' while mutex '%1' is locked">,
+  "cannot call function '%1' while %0 '%2' is held">,
   InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
 def warn_cannot_resolve_lock : Warning<
   "cannot resolve lock expression">,
@@ -2191,28 +2309,26 @@
 
 // Imprecise thread safety warnings
 def warn_variable_requires_lock : Warning<
-  "%select{reading|writing}2 variable '%0' requires locking "
-  "%select{'%1'|'%1' exclusively}2">,
+  "%select{reading|writing}3 variable '%1' requires holding %0 "
+  "%select{'%2'|'%2' exclusively}3">,
   InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
 def warn_var_deref_requires_lock : Warning<
-  "%select{reading|writing}2 the value pointed to by '%0' requires locking "
-  "%select{'%1'|'%1' exclusively}2">,
+  "%select{reading|writing}3 the value pointed to by '%1' requires "
+  "holding %0 %select{'%2'|'%2' exclusively}3">,
   InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
 def warn_fun_requires_lock : Warning<
-  "calling function '%0' requires %select{shared|exclusive}2 lock on '%1'">,
+  "calling function '%1' requires holding %0 %select{'%2'|'%2' exclusively}3">,
   InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
 
 // Precise thread safety warnings
-def warn_variable_requires_lock_precise : Warning<
-  "%select{reading|writing}2 variable '%0' requires locking "
-  "%select{'%1'|'%1' exclusively}2">,
+def warn_variable_requires_lock_precise :
+  Warning<warn_variable_requires_lock.Text>,
   InGroup<ThreadSafetyPrecise>, DefaultIgnore;
-def warn_var_deref_requires_lock_precise : Warning<
-  "%select{reading|writing}2 the value pointed to by '%0' requires locking "
-  "%select{'%1'|'%1' exclusively}2">,
+def warn_var_deref_requires_lock_precise :
+  Warning<warn_var_deref_requires_lock.Text>,
   InGroup<ThreadSafetyPrecise>, DefaultIgnore;
-def warn_fun_requires_lock_precise : Warning<
-  "calling function '%0' requires %select{shared|exclusive}2 lock on '%1'">,
+def warn_fun_requires_lock_precise :
+  Warning<warn_fun_requires_lock.Text>,
   InGroup<ThreadSafetyPrecise>, DefaultIgnore;
 def note_found_mutex_near_match : Note<"found near match '%0'">;
 
@@ -2257,7 +2373,7 @@
   InGroup<Conversion>, DefaultIgnore;
 def warn_impcast_float_integer : Warning<
   "implicit conversion turns floating-point number into integer: %0 to %1">,
-  InGroup<Conversion>, DefaultIgnore;
+  InGroup<FloatConversion>, DefaultIgnore;
 def warn_impcast_integer_sign : Warning<
   "implicit conversion changes signedness: %0 to %1">,
   InGroup<SignConversion>, DefaultIgnore;
@@ -2297,17 +2413,48 @@
 def warn_impcast_floating_point_to_bool : Warning<
     "implicit conversion turns floating-point number into bool: %0 to %1">,
     InGroup<ImplicitConversionFloatingPointToBool>;
-def warn_impcast_function_to_bool : Warning<
-    "address of function %q0 will always evaluate to 'true'">,
-    InGroup<BoolConversion>;
-def note_function_to_bool_silence : Note<
+
+def warn_impcast_pointer_to_bool : Warning<
+    "address of%select{| function| array}0 '%1' will always evaluate to "
+    "'true'">,
+    InGroup<PointerBoolConversion>;
+def warn_this_bool_conversion : Warning<
+  "'this' pointer cannot be null in well-defined C++ code; pointer may be "
+  "assumed to always convert to true">, InGroup<UndefinedBoolConversion>;
+def warn_address_of_reference_bool_conversion : Warning<
+  "reference cannot be bound to dereferenced null pointer in well-defined C++ "
+  "code; pointer may be assumed to always convert to true">,
+  InGroup<UndefinedBoolConversion>;
+
+def warn_null_pointer_compare : Warning<
+    "comparison of %select{address of|function|array}0 '%1' %select{not |}2"
+    "equal to a null pointer is always %select{true|false}2">,
+    InGroup<TautologicalPointerCompare>;
+def warn_this_null_compare : Warning<
+  "'this' pointer cannot be null in well-defined C++ code; comparison may be "
+  "assumed to always evaluate to %select{true|false}0">,
+  InGroup<TautologicalUndefinedCompare>;
+def warn_address_of_reference_null_compare : Warning<
+  "reference cannot be bound to dereferenced null pointer in well-defined C++ "
+  "code; comparison may be assumed to always evaluate to "
+  "%select{true|false}0">,
+  InGroup<TautologicalUndefinedCompare>;
+def note_reference_is_return_value : Note<"%0 returns a reference">;
+
+def note_function_warning_silence : Note<
     "prefix with the address-of operator to silence this warning">;
-def note_function_to_bool_call : Note<
+def note_function_to_function_call : Note<
     "suffix with parentheses to turn this into a function call">;
+def warn_impcast_objective_c_literal_to_bool : Warning<
+    "implicit boolean conversion of Objective-C object literal always "
+    "evaluates to true">,
+    InGroup<ObjCLiteralConversion>;
 
 def warn_cast_align : Warning<
   "cast from %0 to %1 increases required alignment from %2 to %3">,
   InGroup<CastAlign>, DefaultIgnore;
+def warn_old_style_cast : Warning<
+  "use of old-style cast">, InGroup<OldStyleCast>, DefaultIgnore;
 
 // Separate between casts to void* and non-void* pointers.
 // Some APIs use (abuse) void* for something like a user context,
@@ -2353,17 +2500,27 @@
   InGroup<DiagGroup<"unsupported-visibility">>;
 def err_mismatched_visibility: Error<"visibility does not match previous declaration">;
 def note_previous_attribute : Note<"previous attribute is here">;
-def err_unknown_machine_mode : Error<"unknown machine mode %0">;
-def err_unsupported_machine_mode : Error<"unsupported machine mode %0">;
+def note_attribute : Note<"attribute is here">;
+def err_mismatched_ms_inheritance : Error<
+  "inheritance model does not match %select{definition|previous declaration}0">;
+def warn_ignored_ms_inheritance : Warning<
+  "inheritance model ignored on %select{primary template|partial specialization}0">,
+  InGroup<IgnoredAttributes>;
+def note_previous_ms_inheritance : Note<
+  "previous inheritance model specified here">;
+def err_machine_mode : Error<"%select{unknown|unsupported}0 machine mode %1">;
 def err_mode_not_primitive : Error<
   "mode attribute only supported for integer and floating-point types">;
 def err_mode_wrong_type : Error<
   "type of machine mode does not match type of base type">;
 def err_attr_wrong_decl : Error<
-  "'%0' attribute invalid on this declaration, requires typedef or value">;
+  "%0 attribute invalid on this declaration, requires typedef or value">;
 def warn_attribute_nonnull_no_pointers : Warning<
   "'nonnull' attribute applied to function with no pointer arguments">,
   InGroup<IgnoredAttributes>;
+def warn_attribute_nonnull_parm_no_args : Warning<
+  "'nonnull' attribute when used on parameters takes no arguments">,
+  InGroup<IgnoredAttributes>;
 def warn_attribute_malloc_pointer_only : Warning<
   "'malloc' attribute only applies to functions returning a pointer type">,
   InGroup<IgnoredAttributes>;
@@ -2392,15 +2549,14 @@
   "'regparm' is not valid on this platform">;
 def err_attribute_regparm_invalid_number : Error<
   "'regparm' parameter must be between 0 and %0 inclusive">;
+def err_attribute_not_supported_in_lang : Error<
+  "%0 attribute is not supported in %select{C|C++|Objective-C}1">;
 
 
 // Clang-Specific Attributes
 def warn_attribute_iboutlet : Warning<
   "%0 attribute can only be applied to instance variables or properties">,
   InGroup<IgnoredAttributes>;
-def warn_attribute_ibaction: Warning<
-  "ibaction attribute can only be applied to Objective-C instance methods">,
-  InGroup<IgnoredAttributes>;
 def err_iboutletcollection_type : Error<
   "invalid type %0 as argument of iboutletcollection attribute">;
 def err_iboutletcollection_builtintype : Error<
@@ -2412,8 +2568,6 @@
   "IBOutletCollection properties should be copy/strong and not assign">,
   InGroup<ObjCInvalidIBOutletProperty>;
   
-def err_attribute_overloadable_not_function : Error<
-  "'overloadable' attribute can only be applied to a function">;
 def err_attribute_overloadable_missing : Error<
   "%select{overloaded function|redeclaration of}0 %1 must have the "
   "'overloadable' attribute">;
@@ -2434,17 +2588,36 @@
   InGroup<DiagGroup<"requires-super-attribute">>;
 def note_protocol_decl : Note<
   "protocol is declared here">;
+def note_protocol_decl_undefined : Note<
+  "protocol %0 has no definition">;
 
-def err_ns_bridged_not_interface : Error<
-  "parameter of 'ns_bridged' attribute does not name an Objective-C class">;
-  
+// objc_designated_initializer attribute diagnostics.
+def warn_objc_designated_init_missing_super_call : Warning<
+  "designated initializer missing a 'super' call to a designated initializer of the super class">,
+  InGroup<ObjCDesignatedInit>;
+def note_objc_designated_init_marked_here : Note<
+  "method marked as designated initializer of the class here">;
+def warn_objc_designated_init_non_super_designated_init_call : Warning<
+  "designated initializer should only invoke a designated initializer on 'super'">,
+  InGroup<ObjCDesignatedInit>;
+def warn_objc_designated_init_non_designated_init_call : Warning<
+  "designated initializer invoked a non-designated initializer">,
+  InGroup<ObjCDesignatedInit>;
+def warn_objc_secondary_init_super_init_call : Warning<
+  "convenience initializer should not invoke an initializer on 'super'">,
+  InGroup<ObjCDesignatedInit>;
+def warn_objc_secondary_init_missing_init_call : Warning<
+  "convenience initializer missing a 'self' call to another initializer">,
+  InGroup<ObjCDesignatedInit>;
+def warn_objc_implementation_missing_designated_init_override : Warning<
+  "method override for the designated initializer of the superclass %objcinstance0 not found">,
+  InGroup<ObjCDesignatedInit>;
+
 // objc_bridge attribute diagnostics.
-def err_objc_bridge_not_id : Error<
-  "parameter of 'objc_bridge' attribute must be a single name of an Objective-C class">;
-def err_objc_bridge_attribute : Error<
-  "'objc_bridge' attribute must be applied to a struct%select{|, C++ class}0 or union">;
+def err_objc_attr_not_id : Error<
+  "parameter of %0 attribute must be a single name of an Objective-C %select{class|protocol}1">;
 def err_objc_cf_bridged_not_interface : Error<
-  "CF object of type %0 is bridged to '%1', which is not an Objective-C class">;
+  "CF object of type %0 is bridged to %1, which is not an Objective-C class">;
 def err_objc_ns_bridged_invalid_cfobject : Error<
   "ObjectiveC object of type %0 is bridged to %1, which is not valid CF object">;
 def warn_objc_invalid_bridge : Warning<
@@ -2452,6 +2625,18 @@
 def warn_objc_invalid_bridge_to_cf : Warning<
   "%0 cannot bridge to %1">, InGroup<ObjCBridge>;
 
+// objc_bridge_related attribute diagnostics.
+def err_objc_bridged_related_invalid_class : Error<
+  "could not find Objective-C class %0 to convert %1 to %2">;
+def err_objc_bridged_related_invalid_class_name : Error<
+  "%0 must be name of an Objective-C class to be able to convert %1 to %2">;
+def err_objc_bridged_related_known_method : Error<
+ "%0 must be explicitly converted to %1; use %select{%objcclass2|%objcinstance2}3 "
+ "method for this conversion">;
+
+def err_objc_attr_protocol_requires_definition : Error<
+  "attribute %0 can only be applied to @protocol definitions, not forward declarations">;
+
 // Function Parameter Semantic Analysis.
 def err_param_with_void_type : Error<"argument may not have 'void' type">;
 def err_void_only_param : Error<
@@ -2462,14 +2647,12 @@
   "a parameter list without types is only allowed in a function definition">;
 def ext_param_not_declared : Extension<
   "parameter %0 was not declared, defaulting to type 'int'">;
-def err_param_typedef_of_void : Error<
-  "empty parameter list defined with a %select{typedef|type alias}0 of 'void' not allowed%select{ in C++|}0">;
 def err_param_default_argument : Error<
   "C does not support default arguments">;
 def err_param_default_argument_redefinition : Error<
   "redefinition of default argument">;
-def warn_param_default_argument_redefinition : ExtWarn<
-  "redefinition of default argument">;
+def ext_param_default_argument_redefinition : ExtWarn<
+  "redefinition of default argument">, InGroup<Microsoft>;
 def err_param_default_argument_missing : Error<
   "missing default argument on parameter">;
 def err_param_default_argument_missing_name : Error<
@@ -2579,6 +2762,8 @@
     "candidate template ignored: substitution failure%0%1">;
 def note_ovl_candidate_disabled_by_enable_if : Note<
     "candidate template ignored: disabled by %0%1">;
+def note_ovl_candidate_disabled_by_enable_if_attr : Note<
+    "candidate disabled: %0">;
 def note_ovl_candidate_failed_overload_resolution : Note<
     "candidate template ignored: couldn't resolve reference to overloaded "
     "function %0">;
@@ -2941,11 +3126,14 @@
   "%select{class template|function template|template template parameter"
   "|template}1 %2">;
 def note_template_decl_here : Note<"template is declared here">;
-def note_member_of_template_here : Note<"member is declared here">;
 def err_template_arg_must_be_type : Error<
   "template argument for template type parameter must be a type">;
 def err_template_arg_must_be_type_suggest : Error<
   "template argument for template type parameter must be a type; did you forget 'typename'?">;
+def ext_ms_template_type_arg_missing_typename : ExtWarn<
+  "template argument for template type parameter must be a type; "
+  "omitted 'typename' is a Microsoft extension">,
+  InGroup<Microsoft>;
 def err_template_arg_must_be_expr : Error<
   "template argument for non-type template parameter must be an expression">;
 def err_template_arg_nontype_ambig : Error<
@@ -3059,6 +3247,9 @@
 def ext_ms_deref_template_argument: ExtWarn<
   "non-type template argument containing a dereference operation is a "
   "Microsoft extension">, InGroup<Microsoft>;
+def ext_ms_delayed_template_argument: ExtWarn<
+  "using the undeclared type %0 as a default template argument is a "
+  "Microsoft extension">, InGroup<Microsoft>;
 
 // C++ template specialization
 def err_template_spec_unknown_kind : Error<
@@ -3155,8 +3346,8 @@
   "nested name specifier '%0' for declaration does not refer into a class, "
   "class template or class template partial specialization">;
 def err_specialize_member_of_template : Error<
-  "cannot specialize (with 'template<>') a member of an unspecialized "
-  "template">;
+  "cannot specialize %select{|(with 'template<>') }0a member of an "
+  "unspecialized template">;
 
 // C++ Class Template Partial Specialization
 def err_default_arg_in_partial_spec : Error<
@@ -3164,6 +3355,8 @@
 def err_dependent_non_type_arg_in_partial_spec : Error<
     "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<
     "non-type template argument specializes a template parameter with "
     "dependent type %0">;
@@ -3173,7 +3366,7 @@
     "primary template, remove the template argument list">; 
 def warn_partial_specs_not_deducible : Warning<
     "%select{class|variable}0 template partial specialization contains "
-    "%select{a template parameter|template parameters}1 that can not be "
+    "%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<
     "non-deducible template parameter %0">;
@@ -3194,6 +3387,9 @@
   "previous declaration of variable template partial specialization is here">;
 def err_var_spec_no_template : Error<
   "no variable template matches%select{| partial}0 specialization">;
+def err_var_spec_no_template_but_method : Error<
+  "no variable template matches specialization; "
+  "did you mean to use %0 as function template instead?">;
   
 // C++ Function template specializations
 def err_function_template_spec_no_match : Error<
@@ -3221,6 +3417,10 @@
   "%select{implicit|explicit}0 instantiation of undefined template %1">;
 def err_implicit_instantiate_member_undefined : Error<
   "implicit instantiation of undefined member %0">;
+def note_template_class_instantiation_was_here : Note<
+  "class template %0 was instantiated here">;
+def note_template_class_explicit_specialization_was_here : Note<
+  "class template %0 was explicitly specialized here">;
 def note_template_class_instantiation_here : Note<
   "in instantiation of template class %0 requested here">;
 def note_template_member_class_here : Note<
@@ -3273,6 +3473,9 @@
 // C++ Explicit Instantiation
 def err_explicit_instantiation_duplicate : Error<
     "duplicate explicit instantiation of %0">;
+def ext_explicit_instantiation_duplicate : ExtWarn<
+    "duplicate explicit instantiation of %0 ignored as a Microsoft extension">,
+    InGroup<Microsoft>;
 def note_previous_explicit_instantiation : Note<
     "previous explicit instantiation is here">;
 def ext_explicit_instantiation_after_specialization : Extension<
@@ -3368,7 +3571,7 @@
     "referenced member %0 is declared here">;
 def err_typename_missing : Error<
   "missing 'typename' prior to dependent type name '%0%1'">;
-def warn_typename_missing : ExtWarn<
+def ext_typename_missing : ExtWarn<
   "missing 'typename' prior to dependent type name '%0%1'">,
   InGroup<DiagGroup<"typename-missing">>;
 def ext_typename_outside_of_template : ExtWarn<
@@ -3383,11 +3586,11 @@
   "add 'typename' to treat this using declaration as a type">;
 
 def err_template_kw_refers_to_non_template : Error<
-    "%0 following the 'template' keyword does not refer to a template">;
+  "%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">;
+  "'%0%1' instantiated to a class template, not a function template">;
 def note_referenced_class_template : Error<
-    "class template declared here">;
+  "class template declared here">;
 def err_template_kw_missing : Error<
   "missing 'template' keyword prior to dependent template name '%0%1'">;
 def ext_template_outside_of_template : ExtWarn<
@@ -3397,13 +3600,16 @@
   InGroup<CXX98Compat>, DefaultIgnore;
 
 def err_non_type_template_in_nested_name_specifier : Error<
-  "qualified name refers into a specialization of function template %0">;
+  "qualified name refers into a specialization of %select{function|variable}0 "
+  "template %1">;
 def err_template_id_not_a_type : Error<
   "template name refers to non-type template %0">;
 def note_template_declared_here : Note<
   "%select{function template|class template|variable template"
   "|type alias template|template template parameter}0 "
   "%1 declared here">;
+def err_alias_template_expansion_into_fixed_list : Error<
+  "pack expansion used as argument for non-pack parameter of alias template">;
 def note_parameter_type : Note<
   "parameter of type %0 is declared here">;
 
@@ -3479,9 +3685,13 @@
 def err_unexpected_namespace : Error<
   "unexpected namespace name %0: expected expression">;
 def err_undeclared_var_use : Error<"use of undeclared identifier %0">;
-def warn_found_via_dependent_bases_lookup : ExtWarn<"use of identifier %0 "
-   "found via unqualified lookup into dependent bases of class templates is a "
-   "Microsoft extension">, InGroup<Microsoft>;
+def ext_undeclared_unqual_id_with_dependent_base : ExtWarn<
+  "use of undeclared identifier %0; "
+  "unqualified lookup into dependent bases of class template %1 is a Microsoft extension">,
+  InGroup<Microsoft>;
+def ext_found_via_dependent_bases_lookup : ExtWarn<"use of identifier %0 "
+  "found via unqualified lookup into dependent bases of class templates is a "
+  "Microsoft extension">, InGroup<Microsoft>;
 def note_dependent_var_use : Note<"must qualify identifier to find this "
     "declaration in dependent base class">;
 def err_not_found_by_two_phase_lookup : Error<"call to function %0 that is neither "
@@ -3491,20 +3701,26 @@
 def err_undeclared_use : Error<"use of undeclared %0">;
 def warn_deprecated : Warning<"%0 is deprecated">,
     InGroup<DeprecatedDeclarations>;
+def warn_property_method_deprecated :
+    Warning<"property access is using %0 method which is deprecated">,
+    InGroup<DeprecatedDeclarations>;
 def warn_deprecated_message : Warning<"%0 is deprecated: %1">,
     InGroup<DeprecatedDeclarations>;
 def warn_deprecated_fwdclass_message : Warning<
-    "%0 maybe deprecated because receiver type is unknown">,
+    "%0 may be deprecated because the receiver type is unknown">,
     InGroup<DeprecatedDeclarations>;
 def warn_deprecated_def : Warning<
     "Implementing deprecated %select{method|class|category}0">,
     InGroup<DeprecatedImplementations>, DefaultIgnore;
 def err_unavailable : Error<"%0 is unavailable">;
+def err_property_method_unavailable :
+    Error<"property access is using %0 method which is unavailable">;
 def err_unavailable_message : Error<"%0 is unavailable: %1">;
 def warn_unavailable_fwdclass_message : Warning<
-    "%0 maybe unavailable because receiver type is unknown">;
-def note_unavailable_here : Note<
-  "%select{declaration|function}0 has been explicitly marked "
+    "%0 may be unavailable because the receiver type is unknown">,
+    InGroup<UnavailableDeclarations>;
+def note_availability_specified_here : Note<
+  "%0 has been explicitly marked "
   "%select{unavailable|deleted|deprecated}1 here">;
 def note_implicitly_deleted : Note<
   "explicitly defaulted function was implicitly deleted here">;
@@ -3528,6 +3744,8 @@
 def warn_missing_variable_declarations : Warning<
   "no previous extern declaration for non-static variable %0">,
   InGroup<DiagGroup<"missing-variable-declarations">>, DefaultIgnore;
+def err_static_data_member_reinitialization :
+  Error<"static data member %0 already has an initializer">;
 def err_redefinition : Error<"redefinition of %0">;
 def err_alias_after_tentative :
   Error<"alias definition of %0 after tentative definition">;
@@ -3544,9 +3762,6 @@
 def err_redefinition_extern_inline : Error<
   "redefinition of a 'extern inline' function %0 is not supported in "
   "%select{C99 mode|C++}1">;
-def warn_cxx98_compat_friend_redefinition : Warning<
-  "friend function %0 would be implicitly redefined in C++98">,
-  InGroup<CXX98Compat>, DefaultIgnore;
 
 def note_deleted_dtor_no_operator_delete : Note<
   "virtual destructor requires an unambiguous, accessible 'operator delete'">;
@@ -3584,10 +3799,10 @@
   InGroup<DiagGroup<"undefined-inline">>;
 def note_used_here : Note<"used here">;
 
-def warn_internal_in_extern_inline : ExtWarn<
+def ext_internal_in_extern_inline : ExtWarn<
   "static %select{function|variable}0 %1 is used in an inline function with "
   "external linkage">, InGroup<StaticInInline>;
-def ext_internal_in_extern_inline : Extension<
+def ext_internal_in_extern_inline_quiet : Extension<
   "static %select{function|variable}0 %1 is used in an inline function with "
   "external linkage">, InGroup<StaticInInline>;
 def warn_static_local_in_extern_inline : Warning<
@@ -3595,15 +3810,15 @@
   "in different files">, InGroup<StaticLocalInInline>;
 def note_convert_inline_to_static : Note<
   "use 'static' to give inline function %0 internal linkage">;
-def note_internal_decl_declared_here : Note<
-  "%0 declared here">;
 
-def warn_redefinition_of_typedef : ExtWarn<
+def ext_redefinition_of_typedef : ExtWarn<
   "redefinition of typedef %0 is a C11 feature">,
   InGroup<DiagGroup<"typedef-redefinition"> >;
 def err_redefinition_variably_modified_typedef : Error<
   "redefinition of %select{typedef|type alias}0 for variably-modified type %1">;
 
+def err_inline_decl_follows_def : Error<
+  "inline declaration of %0 follows non-inline definition">;
 def err_inline_declaration_block_scope : Error<
   "inline declaration of %0 not allowed in block scope">;
 def err_static_non_static : Error<
@@ -3620,8 +3835,8 @@
   "declared %select{in global scope|with C language linkage}0 here">;
 def warn_weak_import : Warning <
   "an already-declared variable is made a weak_import declaration %0">;
-def warn_static_non_static : ExtWarn<
-  "static declaration of %0 follows non-static declaration">;
+def ext_static_non_static : Extension<
+  "redeclaring non-static %0 as static is a Microsoft extension">, InGroup<Microsoft>;
 def err_non_static_static : Error<
   "non-static declaration of %0 follows static declaration">;
 def err_extern_non_extern : Error<
@@ -3689,17 +3904,18 @@
 def ext_enum_value_not_int : Extension<
   "ISO C restricts enumerator values to range of 'int' (%0 is too "
   "%select{small|large}1)">;
-def warn_enum_too_large : Warning<
-  "enumeration values exceed range of largest integer">;
-def warn_enumerator_too_large : Warning<
-  "enumerator value %0 is not representable in the largest integer type">;
+def ext_enum_too_large : ExtWarn<
+  "enumeration values exceed range of largest integer">, InGroup<EnumTooLarge>;
+def ext_enumerator_increment_too_large : ExtWarn<
+  "incremented enumerator value %0 is not representable in the "
+  "largest integer type">, InGroup<EnumTooLarge>;
   
 def warn_illegal_constant_array_size : Extension<
   "size of static array must be an integer constant expression">;
 def err_vm_decl_in_file_scope : Error<
   "variably modified type declaration not allowed at file scope">;
 def err_vm_decl_has_extern_linkage : Error<
-  "variably modified type declaration can not have 'extern' linkage">;
+  "variably modified type declaration cannot have 'extern' linkage">;
 def err_typecheck_field_variable_size : Error<
   "fields must have a constant size: 'variable length array in structure' "
   "extension will never be supported">;
@@ -3732,6 +3948,9 @@
   InGroup<BadArrayNewLength>;
 def warn_typecheck_function_qualifiers : Warning<
   "qualifier on function type %0 has unspecified behavior">;
+def warn_typecheck_reference_qualifiers : Warning<
+  "'%0' qualifier on reference type %1 has no effect">,
+  InGroup<IgnoredQualifiers>;
 def err_typecheck_invalid_restrict_not_pointer : Error<
   "restrict requires a pointer or reference (%0 is invalid)">;
 def err_typecheck_invalid_restrict_not_pointer_noarg : Error<
@@ -3760,22 +3979,22 @@
   "variable-sized object may not be initialized">;
 def err_excess_initializers : Error<
   "excess elements in %select{array|vector|scalar|union|struct}0 initializer">;
-def warn_excess_initializers : ExtWarn<
+def ext_excess_initializers : ExtWarn<
   "excess elements in %select{array|vector|scalar|union|struct}0 initializer">;
 def err_excess_initializers_in_char_array_initializer : Error<
   "excess elements in char array initializer">;
-def warn_excess_initializers_in_char_array_initializer : ExtWarn<
+def ext_excess_initializers_in_char_array_initializer : ExtWarn<
   "excess elements in char array initializer">;
 def err_initializer_string_for_char_array_too_long : Error<
   "initializer-string for char array is too long">;
-def warn_initializer_string_for_char_array_too_long : ExtWarn<
+def ext_initializer_string_for_char_array_too_long : ExtWarn<
   "initializer-string for char array is too long">;
 def warn_missing_field_initializers : Warning<
-  "missing field '%0' initializer">,
+  "missing field %0 initializer">,
   InGroup<MissingFieldInitializers>, DefaultIgnore;
 def warn_braces_around_scalar_init : Warning<
   "braces around scalar initializer">;
-def warn_many_braces_around_scalar_init : ExtWarn<
+def ext_many_braces_around_scalar_init : ExtWarn<
   "too many braces around scalar initializer">;
 def ext_complex_component_init : Extension<
   "complex initialization specifying real and imaginary components "
@@ -3816,8 +4035,8 @@
   "constant expression evaluates to %0 which cannot be narrowed to type %1 in "
   "C++11">,
   InGroup<CXX11Narrowing>, DefaultIgnore;
-def note_init_list_narrowing_override : Note<
-  "override this message by inserting an explicit cast">;
+def note_init_list_narrowing_silence : Note<
+  "insert an explicit cast to silence this issue">;
 def err_init_objc_class : Error<
   "cannot initialize Objective-C class type %0">;
 def err_implicit_empty_initializer : Error<
@@ -3852,7 +4071,7 @@
   InGroup<UnusedLabel>, DefaultIgnore;
 
 def err_goto_into_protected_scope : Error<"goto into protected scope">;
-def warn_goto_into_protected_scope : ExtWarn<"goto into protected scope">,
+def ext_goto_into_protected_scope : ExtWarn<"goto into protected scope">,
   InGroup<Microsoft>;
 def warn_cxx98_compat_goto_into_protected_scope : Warning<
   "goto would jump into protected scope in C++98">,
@@ -3913,6 +4132,9 @@
   "jump exits scope of variable with __attribute__((cleanup))">;
 def note_exits_dtor : Note<
   "jump exits scope of variable with non-trivial destructor">;
+def note_exits_temporary_dtor : Note<
+  "jump exits scope of lifetime-extended temporary with non-trivial "
+  "destructor">;
 def note_exits___block : Note<
   "jump exits scope of __block variable">;
 def note_exits_objc_try : Note<
@@ -3954,8 +4176,8 @@
 def err_flexible_array_empty_aggregate : Error<
   "flexible array member %0 not allowed in otherwise empty "
   "%select{struct|interface|union|class|enum}1">;
-def err_flexible_array_has_nonpod_type : Error<
-  "flexible array member %0 of non-POD element type %1">;
+def err_flexible_array_has_nontrivial_dtor : Error<
+  "flexible array member %0 of type %1 with non-trivial destruction">;
 def ext_flexible_array_in_struct : Extension<
   "%0 may not be nested in a struct due to flexible array member">,
   InGroup<FlexibleArrayExtensions>;
@@ -4224,6 +4446,8 @@
 def ext_sizeof_alignof_void_type : Extension<
   "invalid application of '%select{sizeof|alignof|vec_step}0' to a void "
   "type">, InGroup<PointerArith>;
+def err_opencl_sizeof_alignof_type : Error<
+  "invalid application of '%select{sizeof|alignof|vec_step}0' to a void type">;
 def err_sizeof_alignof_incomplete_type : Error<
   "invalid application of '%select{sizeof|alignof|vec_step}0' to an "
   "incomplete type %1">;
@@ -4244,9 +4468,9 @@
 def ext_offsetof_extended_field_designator : Extension<
   "using extended field designator is an extension">,
   InGroup<DiagGroup<"extended-offsetof">>;
-def warn_offsetof_non_pod_type : ExtWarn<"offset of on non-POD type %0">,
+def ext_offsetof_non_pod_type : ExtWarn<"offset of on non-POD type %0">,
   InGroup<InvalidOffsetof>;
-def warn_offsetof_non_standardlayout_type : ExtWarn<
+def ext_offsetof_non_standardlayout_type : ExtWarn<
   "offset of on non-standard-layout type %0">, InGroup<InvalidOffsetof>;
 def err_offsetof_bitfield : Error<"cannot compute offset of bit-field %0">;
 def err_offsetof_field_of_virtual_base : Error<
@@ -4315,7 +4539,7 @@
   "'%1' will be evaluated first">, InGroup<ShiftOpParentheses>;
 
 def warn_self_assignment : Warning<
-  "explicitly assigning a variable of type %0 to itself">,
+  "explicitly assigning value of variable of type %0 to itself">,
   InGroup<SelfAssignment>, DefaultIgnore;
 
 def warn_string_plus_int : Warning<
@@ -4439,6 +4663,9 @@
   "extra qualification on member %0">, InGroup<Microsoft>;
 def err_member_extra_qualification : Error<
   "extra qualification on member %0">;
+def warn_namespace_member_extra_qualification : Warning<
+  "extra qualification on member %0">,
+  InGroup<DiagGroup<"extra-qualification">>;
 def err_member_qualification : Error<
   "non-friend class member %0 cannot have a qualified name">;  
 def note_member_def_close_match : Note<"member declaration nearly matches">;
@@ -4505,13 +4732,12 @@
 def warn_deprecated_string_literal_conversion : Warning<
   "conversion from string literal to %0 is deprecated">,
   InGroup<CXX11CompatDeprecatedWritableStr>;
-def warn_deprecated_string_literal_conversion_c : Warning<
-  "dummy warning to enable -fconst-strings">, InGroup<DeprecatedWritableStr>, DefaultIgnore;
+def ext_deprecated_string_literal_conversion : ExtWarn<
+  "ISO C++11 does not allow conversion from string literal to %0">,
+  InGroup<WritableStrings>, SFINAEFailure;
 def err_realimag_invalid_type : Error<"invalid type %0 to %1 operator">;
 def err_typecheck_sclass_fscope : Error<
   "illegal storage class on file-scoped variable">;
-def err_unsupported_global_register : Error<
-  "global register variables are not supported">;
 def warn_standalone_specifier : Warning<"'%0' ignored on this declaration">,
   InGroup<MissingDeclarations>;
 def ext_standalone_specifier : ExtWarn<"'%0' is not permitted on a declaration "
@@ -4547,6 +4773,9 @@
   "invalid argument type %0 to unary expression">;
 def err_typecheck_indirection_requires_pointer : Error<
   "indirection requires pointer operand (%0 invalid)">;
+def ext_typecheck_indirection_through_void_pointer : Extension<
+  "ISO C++ does not allow indirection on operand of type %0">,
+  InGroup<DiagGroup<"void-ptr-dereference">>;
 def warn_indirection_through_null : Warning<
   "indirection of non-volatile null pointer will be deleted, not trap">, InGroup<NullDereference>;
 def note_indirection_through_null : Note<
@@ -4600,8 +4829,9 @@
   "comparison of unsigned%select{| enum}2 expression %0 is always %1">,
   InGroup<TautologicalCompare>;
 def warn_out_of_range_compare : Warning<
-  "comparison of constant %0 with expression of type %1 is always "
-  "%select{false|true}2">, InGroup<TautologicalOutOfRangeCompare>;
+  "comparison of %select{constant %0|true|false}1 with " 
+  "%select{expression of type %2|boolean expression}3 is always "
+  "%select{false|true}4">, InGroup<TautologicalOutOfRangeCompare>;
 def warn_runsigned_always_true_comparison : Warning<
   "comparison of %0 unsigned%select{| enum}2 expression is always %1">,
   InGroup<TautologicalCompare>;
@@ -4812,7 +5042,7 @@
 def err_qualified_objc_catch_parm : Error<
   "@catch parameter declarator cannot be qualified">;
 def warn_objc_pointer_cxx_catch_fragile : Warning<
-  "can not catch an exception thrown with @throw in C++ in the non-unified "
+  "cannot catch an exception thrown with @throw in C++ in the non-unified "
   "exception model">, InGroup<ObjCNonUnifiedException>;
 def err_objc_object_catch : Error<
   "can't catch an Objective-C object by value">;
@@ -4925,6 +5155,8 @@
   "you need to include <typeinfo> before using the 'typeid' operator">;
 def err_need_header_before_ms_uuidof : Error<
   "you need to include <guiddef.h> before using the '__uuidof' operator">;
+def err_ms___leave_not_in___try : Error<
+  "'__leave' statement not in __try block">;
 def err_uuidof_without_guid : Error<
   "cannot call operator __uuidof on a type with no GUID">;
 def err_uuidof_with_multiple_guids : Error<
@@ -5013,7 +5245,7 @@
   "exception declarator cannot be qualified">;
 def err_early_catch_all : Error<"catch-all handler must come last">;
 def err_bad_memptr_rhs : Error<
-  "right hand operand to %0 has non pointer-to-member type %1">;
+  "right hand operand to %0 has non-pointer-to-member type %1">;
 def err_bad_memptr_lhs : Error<
   "left hand operand to %0 must be a %select{|pointer to }1class "
   "compatible with the right hand operand, but is %2">;
@@ -5139,6 +5371,9 @@
     "initializer missing for lambda capture %0">;
   def err_init_capture_multiple_expressions : Error<
     "initializer for lambda capture %0 contains multiple expressions">;
+  def err_init_capture_paren_braces : Error<
+    "cannot deduce type for lambda capture %0 from "
+    "parenthesized initializer list">;
   def err_init_capture_deduction_failure : Error<
     "cannot deduce type for lambda capture %0 from initializer of type %2">;
   def err_init_capture_deduction_failure_from_init_list : Error<
@@ -5199,9 +5434,8 @@
   "conversion function %diff{from $ to $|between types}0,1 "
   "invokes a deleted function">;
   
-def err_expected_class_or_namespace : Error<"expected a class or namespace">;
-def err_expected_class : Error<"%0 is not a class%select{ or namespace|, "
-  "namespace, or scoped enumeration}1">;
+def err_expected_class_or_namespace : Error<"%0 is not a class"
+  "%select{ or namespace|, namespace, or scoped enumeration}1">;
 def err_invalid_declarator_scope : Error<"cannot define or redeclare %0 here "
   "because namespace %1 does not enclose namespace %2">;
 def err_invalid_declarator_global_scope : Error<
@@ -5280,6 +5514,8 @@
   "return type must match previous return type}0,1 when %select{block "
   "literal|lambda expression}2 has unspecified explicit return type">;
 
+def not_incomplete_class_and_qualified_id : Note<
+  "conformance of forward class %0 to protocol %1 can not be confirmed">;
 def warn_incompatible_qualified_id : Warning<
   "%select{%diff{assigning to $ from incompatible type $|"
   "assigning to type from incompatible type}0,1"
@@ -5496,8 +5732,6 @@
   "calling function with incomplete return type %0">;
 def err_call_function_incomplete_return : Error<
   "calling %0 with incomplete return type %1">;
-def note_function_with_incomplete_return_type_declared_here : Note<
-  "%0 declared here">;
 def err_call_incomplete_argument : Error<
   "argument type %0 is incomplete">;
 def err_typecheck_call_too_few_args : Error<
@@ -5553,10 +5787,6 @@
   "incompatible pointer types passing retainable parameter of type %0"
   "to a CF function expecting %1 type">;
   
-def note_callee_decl : Note<
-  "%0 declared here">;
-def note_defined_here : Note<"%0 defined here">;
-
 def err_builtin_fn_use : Error<"builtin functions must be directly called">;
 
 def warn_call_wrong_number_of_arguments : Warning<
@@ -5590,7 +5820,10 @@
 def err_atomic_op_bitwise_needs_atomic_int : Error<
   "address argument to bitwise atomic operation must be a pointer to "
   "%select{|atomic }0integer (%1 invalid)">;
-  
+def warn_atomic_op_has_invalid_memory_order : Warning<
+  "memory order argument to atomic operation is invalid">,
+  InGroup<DiagGroup<"atomic-memory-ordering">>;
+
 def err_atomic_load_store_uses_lib : Error<
   "atomic %select{load|store}0 requires runtime support that is not "
   "available for this target">;
@@ -5630,6 +5863,11 @@
   "passing object of trivial but non-POD type %0 through variadic"
   " %select{function|block|method|constructor}1 is incompatible with C++98">,
   InGroup<CXX98Compat>, DefaultIgnore;
+def warn_pass_class_arg_to_vararg : Warning<
+  "passing object of class type %0 through variadic "
+  "%select{function|block|method|constructor}1"
+  "%select{|; did you mean to call '%3'?}2">,
+  InGroup<ClassVarargs>, DefaultIgnore;
 def err_cannot_pass_to_vararg : Error<
   "cannot pass %select{expression of type %1|initializer list}0 to variadic "
   "%select{function|block|method|constructor}2">;
@@ -5664,6 +5902,10 @@
 def warn_cast_pointer_from_sel : Warning<
   "cast of type %0 to %1 is deprecated; use sel_getName instead">,
   InGroup<SelTypeCast>;
+def warn_function_def_in_objc_container : Warning<
+  "function definition inside an Objective-C container is deprecated">,
+  InGroup<FunctionDefInObjCContainer>;
+  
 def warn_bad_function_cast : Warning<
   "cast from function call of type %0 to non-matching type %1">,
   InGroup<BadFunctionCast>, DefaultIgnore;
@@ -5678,10 +5920,10 @@
   "pointer type %2">;
 def err_cast_selector_expr : Error<
   "cannot type cast @selector expression">;
-def warn_typecheck_cond_incompatible_pointers : ExtWarn<
+def ext_typecheck_cond_incompatible_pointers : ExtWarn<
   "pointer type mismatch%diff{ ($ and $)|}0,1">,
   InGroup<DiagGroup<"pointer-type-mismatch">>;
-def warn_typecheck_cond_pointer_integer_mismatch : ExtWarn<
+def ext_typecheck_cond_pointer_integer_mismatch : ExtWarn<
   "pointer/integer type mismatch in conditional expression"
   "%diff{ ($ and $)|}0,1">,
   InGroup<DiagGroup<"conditional-type-mismatch">>;
@@ -5709,20 +5951,16 @@
   InGroup<DiagGroup<"unused-volatile-lvalue">>;
 
 def warn_unused_comparison : Warning<
-  "%select{equality|inequality}0 comparison result unused">,
+  "%select{%select{|in}1equality|relational}0 comparison result unused">,
   InGroup<UnusedComparison>;
 def note_inequality_comparison_to_or_assign : Note<
   "use '|=' to turn this inequality comparison into an or-assignment">;
 
 def err_incomplete_type_used_in_type_trait_expr : Error<
   "incomplete type %0 used in type trait expression">;
-def err_type_trait_arity : Error<
-  "type trait requires %0%select{| or more}1 argument%select{|s}2; have "
-  "%3 argument%s3">;
   
 def err_dimension_expr_not_constant_integer : Error<
   "dimension expression does not evaluate to a constant unsigned int">;
-def err_expected_ident_or_lparen : Error<"expected identifier or '('">;
 
 def err_typecheck_cond_incompatible_operands_null : Error<
   "non-pointer operand type %0 incompatible with %select{NULL|nullptr}1">;
@@ -5755,6 +5993,7 @@
     "%diff{$ matching output with type $|}0,1">;
   def err_asm_incomplete_type : Error<"asm operand has incomplete type %0">;
   def err_asm_unknown_register_name : Error<"unknown register name '%0' in asm">;
+  def err_asm_bad_register_type : Error<"bad type for named register variable">;
   def err_asm_invalid_input_size : Error<
     "invalid input size for constraint '%0'">;
   def err_invalid_asm_cast_lvalue : Error<
@@ -5782,6 +6021,12 @@
   "invalid conversion between vector type %0 and integer type %1 "
   "of different size">;
 
+def err_opencl_function_pointer_variable : Error<
+  "pointers to functions are not allowed">;
+
+def err_opencl_taking_function_address : Error<
+  "taking address of function is not allowed">;
+
 def err_invalid_conversion_between_vector_and_scalar : Error<
   "invalid conversion between vector type %0 and scalar type %1">;
 
@@ -5898,8 +6143,6 @@
 def err_reference_to_local_var_in_enclosing_context : Error<
   "reference to local variable %0 declared in enclosing context">;
 
-def note_local_variable_declared_here : Note<
-  "%0 declared here">;
 def err_static_data_member_not_allowed_in_local_class : Error<
   "static data member %0 not allowed in local class %1">; 
   
@@ -5974,6 +6217,9 @@
   "%0 must have at least one parameter">;
 def err_operator_new_delete_template_too_few_parameters : Error<
   "%0 template must have at least two parameters">;
+def warn_operator_new_returns_null : Warning<
+  "%0 should not return a null pointer unless it is declared 'throw()'"
+  "%select{| or 'noexcept'}1">, InGroup<OperatorNewReturnsNull>;
 
 def err_operator_new_dependent_param_type : Error<
   "%0 cannot take a dependent type as first parameter; "
@@ -5990,6 +6236,8 @@
 // C++ literal operators
 def err_literal_operator_outside_namespace : Error<
   "literal operator %0 must be in a namespace or global scope">;
+def err_literal_operator_id_outside_namespace : Error<
+  "non-namespace scope '%0' cannot have a literal operator member">;
 def err_literal_operator_default_argument : Error<
   "literal operator cannot have a default argument">;
 // FIXME: This diagnostic sucks
@@ -6120,12 +6368,13 @@
 def warn_scanf_nonzero_width : Warning<
   "zero field width in scanf format string is unused">,
   InGroup<Format>;
-def warn_printf_conversion_argument_type_mismatch : Warning<
-  "format specifies type %0 but the argument has type %1">,
+def warn_format_conversion_argument_type_mismatch : Warning<
+  "format specifies type %0 but the argument has "
+  "%select{type|underlying type}2 %1">,
   InGroup<Format>;
 def warn_format_argument_needs_cast : Warning<
-  "values of type '%0' should not be used as format arguments; add an explicit "
-  "cast to %1 instead">,
+  "%select{values of type|enum values with underlying type}2 '%0' should not "
+  "be used as format arguments; add an explicit cast to %1 instead">,
   InGroup<Format>;
 def warn_printf_positional_arg_exceeds_data_args : Warning <
   "data argument position '%0' exceeds the number of data arguments (%1)">,
@@ -6150,6 +6399,8 @@
   "format string should not be a wide string">, InGroup<Format>;
 def warn_printf_format_string_contains_null_char : Warning<
   "format string contains '\\0' within the string body">, InGroup<Format>;
+def warn_printf_format_string_not_null_terminated : Warning<
+  "format string is not null-terminated">, InGroup<Format>;
 def warn_printf_asterisk_missing_arg : Warning<
   "'%select{*|.*}0' specified field %select{width|precision}0 is missing a matching 'int' argument">,
   InGroup<Format>;
@@ -6165,12 +6416,12 @@
 def warn_format_nonsensical_length: Warning<
   "length modifier '%0' results in undefined behavior or no effect with '%1' conversion specifier">,
   InGroup<Format>;
-def warn_format_non_standard_positional_arg: ExtWarn<
+def warn_format_non_standard_positional_arg: Warning<
   "positional arguments are not supported by ISO C">, InGroup<FormatNonStandard>, DefaultIgnore;
-def warn_format_non_standard: ExtWarn<
+def warn_format_non_standard: Warning<
   "'%0' %select{length modifier|conversion specifier}1 is not supported by ISO C">,
   InGroup<FormatNonStandard>, DefaultIgnore;
-def warn_format_non_standard_conversion_spec: ExtWarn<
+def warn_format_non_standard_conversion_spec: Warning<
   "using length modifier '%0' with conversion specifier '%1' is not supported by ISO C">,
   InGroup<FormatNonStandard>, DefaultIgnore;
 def warn_printf_ignored_flag: Warning<
@@ -6186,6 +6437,9 @@
 def warn_null_arg : Warning<
   "null passed to a callee which requires a non-null argument">,
   InGroup<NonNull>;
+def warn_null_ret : Warning<
+  "null returned from %select{function|method}0 that requires a non-null return value">,
+  InGroup<NonNull>;
 
 // CHECK: returning address/reference of stack memory
 def warn_ret_stack_addr : Warning<
@@ -6230,11 +6484,17 @@
 def warn_comparison_always : Warning<
   "%select{self-|array }0comparison always evaluates to %select{false|true|a constant}1">,
   InGroup<TautologicalCompare>;
+def warn_comparison_bitwise_always : Warning<
+  "bitwise comparison always evaluates to %select{false|true}0">,
+  InGroup<TautologicalCompare>;
+def warn_tautological_overlap_comparison : Warning<
+  "overlapping comparisons always evaluate to %select{false|true}0">,
+  InGroup<TautologicalOverlapCompare>, DefaultIgnore;
 
 def warn_stringcompare : Warning<
   "result of comparison against %select{a string literal|@encode}0 is "
   "unspecified (use strncmp instead)">,
-  InGroup<DiagGroup<"string-compare">>;
+  InGroup<StringCompare>;
 
 def warn_identity_field_assign : Warning<
   "assigning %select{field|instance variable}0 to itself">,
@@ -6252,7 +6512,7 @@
   "this type tag was not designed to be used with this function">,
   InGroup<TypeSafety>;
 def warn_type_safety_type_mismatch : Warning<
-  "argument type %0 doesn't match specified '%1' type tag "
+  "argument type %0 doesn't match specified %1 type tag "
   "%select{that requires %3|}2">, InGroup<TypeSafety>;
 def warn_type_safety_null_pointer_required : Warning<
   "specified %0 type tag requires a null pointer">, InGroup<TypeSafety>;
@@ -6299,11 +6559,17 @@
   "'continue' statement not in loop statement">;
 def err_break_not_in_loop_or_switch : Error<
   "'break' statement not in loop or switch statement">;
+def warn_loop_ctrl_binds_to_inner : Warning<
+  "'%0' is bound to current loop, GCC binds it to the enclosing loop">,
+  InGroup<GccCompat>;
+def warn_break_binds_to_switch : Warning<
+  "'break' is bound to loop, GCC binds it to switch">,
+  InGroup<GccCompat>;
 def err_default_not_in_switch : Error<
   "'default' statement not in switch statement">;
 def err_case_not_in_switch : Error<"'case' statement not in switch statement">;
 def warn_bool_switch_condition : Warning<
-  "switch condition has boolean value">;
+  "switch condition has boolean value">, InGroup<SwitchBool>;
 def warn_case_value_overflow : Warning<
   "overflow converting case value to switch condition type (%0 to %1)">,
   InGroup<Switch>;
@@ -6434,6 +6700,8 @@
 def err_return_init_list : Error<
   "%select{void function|void method|constructor|destructor}1 %0 "
   "must not return a value">;
+def err_ctor_dtor_returns_void : Error<
+  "%select{constructor|destructor}1 %0 must not return void expression">;
 def warn_noreturn_function_has_return_expr : Warning<
   "function %0 declared 'noreturn' should not return">,
   InGroup<InvalidNoreturn>;
@@ -6484,9 +6752,20 @@
   "incompatible constant for this __builtin_neon function">; 
 def err_argument_invalid_range : Error<
   "argument should be a value from %0 to %1">;
+def warn_neon_vector_initializer_non_portable : Warning<
+  "vector initializers are not compatible with NEON intrinsics in big endian "
+  "mode">, InGroup<DiagGroup<"nonportable-vector-initialization">>;
+def note_neon_vector_initializer_non_portable : Note<
+  "consider using vld1_%0%1() to initialize a vector from memory, or "
+  "vcreate_%0%1() to initialize from an integer constant">;
+def note_neon_vector_initializer_non_portable_q : Note<
+  "consider using vld1q_%0%1() to initialize a vector from memory, or "
+  "vcombine_%0%1(vcreate_%0%1(), vcreate_%0%1()) to initialize from integer "
+  "constants">;
 
 def err_builtin_longjmp_invalid_val : Error<
   "argument to __builtin_longjmp must be a constant 1">;
+def err_builtin_requires_language : Error<"'%0' is only available in %1">;
 
 def err_constant_integer_arg_type : Error<
   "argument to %0 must be a constant integer">;
@@ -6572,9 +6851,6 @@
 def error_protected_ivar_access : Error<"instance variable %0 is protected">,
   AccessControl;
 def warn_maynot_respond : Warning<"%0 may not respond to %1">;
-def warn_attribute_method_def : Warning<
-  "attributes on method implementation and its declaration must match">,
-  InGroup<DiagGroup<"mismatched-method-attributes">>;
 def ext_typecheck_base_super : Warning<
   "method parameter type "
   "%diff{$ does not match super class method parameter type $|"
@@ -6587,6 +6863,8 @@
   "directly accessed">, InGroup<DiagGroup<"direct-ivar-access">>, DefaultIgnore;
 
 // Spell-checking diagnostics
+def err_unknown_typename : Error<
+  "unknown type name %0">;
 def err_unknown_type_or_class_name_suggest : Error<
   "unknown %select{type|class}1 name %0; did you mean %2?">;
 def err_unknown_typename_suggest : Error<
@@ -6644,7 +6922,7 @@
   "no known method %select{%objcinstance1|%objcclass1}0; cast the "
   "message send to the method's return type">;
 def err_unsupported_unknown_any_decl : Error<
-  "%0 has unknown type, which is unsupported for this kind of declaration">;
+  "%0 has unknown type, which is not supported for this kind of declaration">;
 def err_unsupported_unknown_any_expr : Error<
   "unsupported expression with unknown type">;
 def err_unsupported_unknown_any_call : Error<
@@ -6667,6 +6945,8 @@
   "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_static_function_scope : Error<
   "variables in function scope cannot be declared static">;
 def err_opencl_bitfields : Error<
@@ -6696,6 +6976,12 @@
 def err_opencl_global_invalid_addr_space : Error<
   "global variables must have a constant address space qualifier">;
 def err_opencl_no_main : Error<"%select{function|kernel}0 cannot be called 'main'">;
+def err_opencl_kernel_attr :
+  Error<"attribute %0 can only be applied to a kernel function">;
+def err_opencl_return_value_with_address_space : Error<
+  "return value cannot be qualified with address space">;
+def err_opencl_constant_no_init : Error<
+  "variable in constant address space must be initialized">;
 } // end of sema category
 
 let CategoryName = "OpenMP Issue" in {
@@ -6719,24 +7005,147 @@
   "a private variable with incomplete type %0">;
 def err_omp_firstprivate_incomplete_type : Error<
   "a firstprivate variable with incomplete type %0">;
-def err_omp_unexpected_clause_value : Error <
+def err_omp_lastprivate_incomplete_type : Error<
+  "a lastprivate variable with incomplete type %0">;
+def err_omp_reduction_incomplete_type : Error<
+  "a reduction variable with incomplete type %0">;
+def err_omp_unexpected_clause_value : Error<
   "expected %0 in OpenMP clause '%1'">;
-def err_omp_expected_var_name : Error <
+def err_omp_expected_var_name : Error<
   "expected variable name">;
-def err_omp_required_method : Error <
+def err_omp_required_method : Error<
   "%0 variable must have an accessible, unambiguous %select{default constructor|copy constructor|copy assignment operator|'%2'|destructor}1">;
+def err_omp_task_predetermined_firstprivate_required_method : Error<
+  "predetermined as a firstprivate in a task construct variable must have an accessible, unambiguous %select{copy constructor|destructor}0">;
 def err_omp_clause_ref_type_arg : Error<
   "arguments of OpenMP clause '%0' cannot be of reference type %1">;
+def err_omp_task_predetermined_firstprivate_ref_type_arg : Error<
+  "predetermined as a firstprivate in a task construct variable cannot be of reference type %0">;
 def err_omp_threadprivate_incomplete_type : Error<
   "threadprivate variable with incomplete type %0">;
-def err_omp_no_dsa_for_variable : Error <
+def err_omp_no_dsa_for_variable : Error<
   "variable %0 must have explicitly specified data sharing attributes">;
 def err_omp_wrong_dsa : Error<
   "%0 variable cannot be %1">;
-def note_omp_explicit_dsa : Note <
+def note_omp_explicit_dsa : Note<
   "defined as %0">;
-def note_omp_predetermined_dsa : Note <
-  "predetermined as %0">;
+def note_omp_predetermined_dsa : Note<
+  "%select{static data member is predetermined as shared|"
+  "variable with static storage duration is predetermined as shared|"
+  "loop iteration variable is predetermined as private|"
+  "loop iteration variable is predetermined as linear|"
+  "loop iteration variable is predetermined as lastprivate|"
+  "constant variable is predetermined as shared|"
+  "global variable is predetermined as shared|"
+  "non-shared variable in a task construct is predetermined as firstprivate|"
+  "variable with automatic storage duration is predetermined as private}0"
+  "%select{|; perhaps you forget to enclose 'omp %2' directive into a parallel or another task region?}1">;
+def note_omp_implicit_dsa : Note<
+  "implicitly determined as %0">;
+def err_omp_loop_var_dsa : Error<
+  "loop iteration variable in the associated loop of 'omp %1' directive may not be %0, predetermined as %2">;
+def err_omp_not_for : Error<
+  "%select{statement after '#pragma omp %1' must be a for loop|"
+  "expected %2 for loops after '#pragma omp %1'%select{|, but found only %4}3}0">;
+def note_omp_collapse_expr : Note<
+  "as specified in 'collapse' clause">;
+def err_omp_negative_expression_in_clause : Error<
+  "argument to '%0' clause must be a positive integer value">;
+def err_omp_not_integral : Error<
+  "expression must have integral or unscoped enumeration "
+  "type, not %0">;
+def err_omp_incomplete_type : Error<
+  "expression has incomplete class type %0">;
+def err_omp_explicit_conversion : Error<
+  "expression requires explicit conversion from %0 to %1">;
+def note_omp_conversion_here : Note<
+  "conversion to %select{integral|enumeration}0 type %1 declared here">;
+def err_omp_ambiguous_conversion : Error<
+  "ambiguous conversion from type %0 to an integral or unscoped "
+  "enumeration type">;
+def err_omp_required_access : Error<
+  "%0 variable must be %1">;
+def err_omp_const_variable : Error<
+  "const-qualified variable cannot be %0">;
+def err_omp_linear_incomplete_type : Error<
+  "a linear variable with incomplete type %0">;
+def err_omp_linear_expected_int_or_ptr : Error<
+  "argument of a linear clause should be of integral or pointer "
+  "type, not %0">;
+def warn_omp_linear_step_zero : Warning<
+  "zero linear step (%0 %select{|and other variables in clause }1should probably be const)">,
+  InGroup<OpenMPClauses>;
+def err_omp_aligned_expected_array_or_ptr : Error<
+  "argument of aligned clause should be array"
+  "%select{ or pointer|, pointer, reference to array or reference to pointer}1"
+  ", not %0">;
+def err_omp_aligned_twice : Error<
+  "a variable cannot appear in more than one aligned clause">;
+def err_omp_local_var_in_threadprivate_init : Error<
+  "variable with local storage in initial value of threadprivate variable">;
+def err_omp_loop_not_canonical_init : Error<
+  "initialization clause of OpenMP for loop must be of the form "
+  "'var = init' or 'T var = init'">;
+def ext_omp_loop_not_canonical_init : ExtWarn<
+  "initialization clause of OpenMP for loop is not in canonical form "
+  "('var = init' or 'T var = init')">, InGroup<OpenMPLoopForm>;
+def err_omp_loop_not_canonical_cond : Error<
+  "condition of OpenMP for loop must be a relational comparison "
+  "('<', '<=', '>', or '>=') of loop variable %0">;
+def err_omp_loop_not_canonical_incr : Error<
+  "increment clause of OpenMP for loop must perform simple addition "
+  "or subtraction on loop variable %0">;
+def err_omp_loop_variable_type : Error<
+  "variable must be of integer or %select{pointer|random access iterator}0 type">;
+def err_omp_loop_incr_not_compatible : Error<
+  "increment expression must cause %0 to %select{decrease|increase}1 "
+  "on each iteration of OpenMP for loop">;
+def note_omp_loop_cond_requres_compatible_incr : Note<
+  "loop step is expected to be %select{negative|positive}0 due to this condition">;
+def err_omp_loop_cannot_use_stmt : Error<
+  "'%0' statement cannot be used in OpenMP for loop">;
+def err_omp_simd_region_cannot_use_stmt : Error<
+  "'%0' statement cannot be used in OpenMP simd region">;
+def err_omp_unknown_reduction_identifier : Error<
+  "incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'">;
+def err_omp_reduction_type_array : Error<
+  "a reduction variable with array type %0">;
+def err_omp_reduction_ref_type_arg : Error<
+  "argument of OpenMP clause 'reduction' must reference the same object in all threads">;
+def err_omp_clause_not_arithmetic_type_arg : Error<
+  "arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of %select{scalar|arithmetic}0 type">;
+def err_omp_clause_floating_type_arg : Error<
+  "arguments of OpenMP clause 'reduction' with bitwise operators cannot be of floating type">;
+def err_omp_once_referenced : Error<
+  "variable can appear only once in OpenMP '%0' clause">;
+def note_omp_referenced : Note<
+  "previously referenced here">;
+def err_omp_reduction_in_task : Error<
+  "reduction variables may not be accessed in an explicit task">;
+def err_omp_reduction_id_not_compatible : Error<
+  "variable of type %0 is not valid for specified reduction operation">;
+def err_omp_prohibited_region : Error<
+  "region cannot be%select{| closely}0 nested inside '%1' region"
+  "%select{|; perhaps you forget to enclose 'omp %3' directive into a parallel region?}2">;
+def err_omp_prohibited_region_simd : Error<
+  "OpenMP constructs may not be nested inside a simd region">;
+def err_omp_prohibited_region_critical_same_name : Error<
+  "cannot nest 'critical' regions having the same name %0">;
+def note_omp_previous_critical_region : Note<
+  "previous 'critical' region starts here">;
+def err_omp_sections_not_compound_stmt : Error<
+  "the statement for '#pragma omp sections' must be a compound statement">;
+def err_omp_parallel_sections_not_compound_stmt : Error<
+  "the statement for '#pragma omp parallel sections' must be a compound statement">;
+def err_omp_orphaned_section_directive : Error<
+  "%select{orphaned 'omp section' directives are prohibited, it|'omp section' directive}0"
+  " must be closely nested to a sections region%select{|, not a %1 region}0">;
+def err_omp_sections_substmt_not_section : Error<
+  "statement in 'omp sections' directive must be enclosed into a section region">;
+def err_omp_parallel_sections_substmt_not_section : Error<
+  "statement in 'omp parallel sections' directive must be enclosed into a section region">;
+def err_omp_parallel_reduction_in_task_firstprivate : Error<
+  "argument of a reduction clause of a %0 construct must not appear in a firstprivate clause on a task construct">;
 } // end of OpenMP category
 
 let CategoryName = "Related Result Type Issue" in {
@@ -6778,6 +7187,16 @@
   "declaration of %0 must be imported from module '%1' before it is required">;
 def err_module_private_definition : Error<
   "definition of %0 must be imported from module '%1' before it is required">;
+def err_module_import_in_extern_c : Error<
+  "import of C++ module '%0' appears within extern \"C\" language linkage "
+  "specification">;
+def note_module_import_in_extern_c : Note<
+  "extern \"C\" language linkage specification begins here">;
+def err_module_import_not_at_top_level : Error<
+  "import of module '%0' appears within %1">;
+def note_module_import_not_at_top_level : Note<"%0 begins here">;
+def err_module_self_import : Error<
+  "import of module '%0' appears within same top-level module '%1'">;
 }
 
 let CategoryName = "Documentation Issue" in {
@@ -6785,4 +7204,15 @@
   "not a Doxygen trailing comment">, InGroup<Documentation>, DefaultIgnore;
 } // end of documentation issue category
 
+let CategoryName = "Instrumentation Issue" in {
+def warn_profile_data_out_of_date : Warning<
+  "profile data may be out of date: of %0 function%s0, %1 %plural{1:has|:have}1"
+  " no data and %2 %plural{1:has|:have}2 mismatched data that will be ignored">,
+  InGroup<ProfileInstrOutOfDate>;
+def warn_profile_data_unprofiled : Warning<
+  "no profile data available for file \"%0\"">,
+  InGroup<ProfileInstrUnprofiled>;
+
+} // end of instrumentation issue category
+
 } // end of sema component.
diff --git a/include/clang/Basic/DiagnosticSerializationKinds.td b/include/clang/Basic/DiagnosticSerializationKinds.td
index 81509cc..be9d2bd 100644
--- a/include/clang/Basic/DiagnosticSerializationKinds.td
+++ b/include/clang/Basic/DiagnosticSerializationKinds.td
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 let Component = "Serialization" in {
+let CategoryName = "AST Deserialization Issue" in {
 
 def err_fe_unable_to_read_pch_file : Error<
     "unable to read PCH file %0: '%1'">;
@@ -22,6 +23,8 @@
     DefaultFatal;
 def err_fe_pch_file_overridden : Error<
     "file '%0' from the precompiled header has been overridden">;
+def note_pch_required_by : Note<"'%0' required by '%1'">;
+def note_pch_rebuild_required : Note<"please rebuild precompiled header '%0'">;
 def note_module_cache_path : Note<
     "after modifying system headers, please delete the module cache at '%0'">;
 
@@ -36,16 +39,23 @@
     "PCH file but is currently %select{disabled|enabled}2">;
 def err_pch_langopt_value_mismatch : Error<
   "%0 differs in PCH file vs. current file">;
+def err_pch_diagopt_mismatch : Error<"%0 is currently enabled, but was not in "
+  "the PCH file">;
   
-def warn_pch_version_too_old : Error<
+def err_pch_version_too_old : Error<
     "PCH file uses an older PCH format that is no longer supported">;
-def warn_pch_version_too_new : Error<
+def err_pch_version_too_new : Error<
     "PCH file uses a newer PCH format that cannot be read">;
-def warn_pch_different_branch : Error<
+def err_pch_different_branch : Error<
     "PCH file built from a different branch (%0) than the compiler (%1)">;
 def err_pch_with_compiler_errors : Error<
     "PCH file contains compiler errors">;
-    
+
+def err_imported_module_not_found : Error<
+    "module '%0' imported by AST file '%1' not found">, DefaultFatal;
+def err_imported_module_modmap_changed : Error<
+    "module '%0' imported by AST file '%1' found in a different module map file"
+    " (%2) than when the importing AST file was built (%3)">, DefaultFatal;
 def warn_module_conflict : Warning<
     "module '%0' conflicts with already-imported module '%1': %2">, 
     InGroup<ModuleConflict>;
@@ -75,5 +85,14 @@
   "definition has no member %0">;
 def note_module_odr_violation_possible_decl : Note<
   "declaration of %0 does not match">;
+def err_module_odr_violation_different_definitions : Error<
+  "%q0 has different definitions in different modules; "
+  "%select{definition in module '%2' is here|defined here}1">;
+def note_module_odr_violation_different_definitions : Note<
+  "definition in module '%0' is here">;
+def err_module_odr_violation_different_instantiations : Error<
+  "instantiation of %q0 is different in different modules">;
 
-}
+} // let CategoryName
+} // let Component
+
diff --git a/include/clang/Basic/FileManager.h b/include/clang/Basic/FileManager.h
index 255eee3..0ad53c4 100644
--- a/include/clang/Basic/FileManager.h
+++ b/include/clang/Basic/FileManager.h
@@ -17,16 +17,17 @@
 
 #include "clang/Basic/FileSystemOptions.h"
 #include "clang/Basic/LLVM.h"
+#include "clang/Basic/VirtualFileSystem.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Allocator.h"
-#include "llvm/Support/FileSystem.h"
+#include <memory>
 // FIXME: Enhance libsystem to support inode and other fields in stat.
 #include <sys/types.h>
+#include <map>
 
 #ifdef _MSC_VER
 typedef unsigned short mode_t;
@@ -48,17 +49,17 @@
   const char *Name;   // Name of the directory.
   friend class FileManager;
 public:
-  DirectoryEntry() : Name(0) {}
+  DirectoryEntry() : Name(nullptr) {}
   const char *getName() const { return Name; }
 };
 
 /// \brief Cached information about one file (either on disk
 /// or in the virtual file system).
 ///
-/// If the 'FD' member is valid, then this FileEntry has an open file
+/// If the 'File' member is valid, then this FileEntry has an open file
 /// descriptor for the file.
 class FileEntry {
-  const char *Name;           // Name of the file.
+  std::string Name;           // Name of the file.
   off_t Size;                 // File size in bytes.
   time_t ModTime;             // Modification time of file.
   const DirectoryEntry *Dir;  // Directory file lives in.
@@ -66,33 +67,34 @@
   llvm::sys::fs::UniqueID UniqueID;
   bool IsNamedPipe;
   bool InPCH;
+  bool IsValid;               // Is this \c FileEntry initialized and valid?
 
-  /// FD - The file descriptor for the file entry if it is opened and owned
-  /// by the FileEntry.  If not, this is set to -1.
-  mutable int FD;
+  /// \brief The open file, if it is owned by the \p FileEntry.
+  mutable std::unique_ptr<vfs::File> File;
   friend class FileManager;
 
+  void closeFile() const {
+    File.reset(); // rely on destructor to close File
+  }
+
+  void operator=(const FileEntry &) LLVM_DELETED_FUNCTION;
+
 public:
-  FileEntry(llvm::sys::fs::UniqueID UniqueID, bool IsNamedPipe, bool InPCH)
-      : Name(0), UniqueID(UniqueID), IsNamedPipe(IsNamedPipe), InPCH(InPCH),
-        FD(-1) {}
-  // Add a default constructor for use with llvm::StringMap
   FileEntry()
-      : Name(0), UniqueID(0, 0), IsNamedPipe(false), InPCH(false), FD(-1) {}
+      : UniqueID(0, 0), IsNamedPipe(false), InPCH(false), IsValid(false)
+  {}
 
-  FileEntry(const FileEntry &FE) {
-    memcpy(this, &FE, sizeof(FE));
-    assert(FD == -1 && "Cannot copy a file-owning FileEntry");
+  // FIXME: this is here to allow putting FileEntry in std::map.  Once we have
+  // emplace, we shouldn't need a copy constructor anymore.
+  /// Intentionally does not copy fields that are not set in an uninitialized
+  /// \c FileEntry.
+  FileEntry(const FileEntry &FE) : UniqueID(FE.UniqueID),
+      IsNamedPipe(FE.IsNamedPipe), InPCH(FE.InPCH), IsValid(FE.IsValid) {
+    assert(!isValid() && "Cannot copy an initialized FileEntry");
   }
 
-  void operator=(const FileEntry &FE) {
-    memcpy(this, &FE, sizeof(FE));
-    assert(FD == -1 && "Cannot assign a file-owning FileEntry");
-  }
-
-  ~FileEntry();
-
-  const char *getName() const { return Name; }
+  const char *getName() const { return Name.c_str(); }
+  bool isValid() const { return IsValid; }
   off_t getSize() const { return Size; }
   unsigned getUID() const { return UID; }
   const llvm::sys::fs::UniqueID &getUniqueID() const { return UniqueID; }
@@ -119,16 +121,14 @@
 /// as a single file.
 ///
 class FileManager : public RefCountedBase<FileManager> {
+  IntrusiveRefCntPtr<vfs::FileSystem> FS;
   FileSystemOptions FileSystemOpts;
 
-  class UniqueDirContainer;
-  class UniqueFileContainer;
-
   /// \brief Cache for existing real directories.
-  UniqueDirContainer &UniqueRealDirs;
+  std::map<llvm::sys::fs::UniqueID, DirectoryEntry> UniqueRealDirs;
 
   /// \brief Cache for existing real files.
-  UniqueFileContainer &UniqueRealFiles;
+  std::map<llvm::sys::fs::UniqueID, FileEntry> UniqueRealFiles;
 
   /// \brief The virtual directories that we have allocated.
   ///
@@ -169,17 +169,18 @@
   unsigned NumDirCacheMisses, NumFileCacheMisses;
 
   // Caching.
-  OwningPtr<FileSystemStatCache> StatCache;
+  std::unique_ptr<FileSystemStatCache> StatCache;
 
   bool getStatValue(const char *Path, FileData &Data, bool isFile,
-                    int *FileDescriptor);
+                    std::unique_ptr<vfs::File> *F);
 
   /// Add all ancestors of the given path (pointing to either a file
   /// or a directory) as virtual directories.
   void addAncestorsAsVirtualDirs(StringRef Path);
 
 public:
-  FileManager(const FileSystemOptions &FileSystemOpts);
+  FileManager(const FileSystemOptions &FileSystemOpts,
+              IntrusiveRefCntPtr<vfs::FileSystem> FS = nullptr);
   ~FileManager();
 
   /// \brief Installs the provided FileSystemStatCache object within
@@ -226,6 +227,10 @@
   /// \brief Returns the current file system options
   const FileSystemOptions &getFileSystemOptions() { return FileSystemOpts; }
 
+  IntrusiveRefCntPtr<vfs::FileSystem> getVirtualFileSystem() const {
+    return FS;
+  }
+
   /// \brief Retrieve a file entry for a "virtual" file that acts as
   /// if there were a file with the given name on disk.
   ///
@@ -236,17 +241,20 @@
   /// \brief Open the specified file as a MemoryBuffer, returning a new
   /// MemoryBuffer if successful, otherwise returning null.
   llvm::MemoryBuffer *getBufferForFile(const FileEntry *Entry,
-                                       std::string *ErrorStr = 0,
-                                       bool isVolatile = false);
+                                       std::string *ErrorStr = nullptr,
+                                       bool isVolatile = false,
+                                       bool ShouldCloseOpenFile = true);
   llvm::MemoryBuffer *getBufferForFile(StringRef Filename,
-                                       std::string *ErrorStr = 0);
+                                       std::string *ErrorStr = nullptr);
 
   /// \brief Get the 'stat' information for the given \p Path.
   ///
   /// If the path is relative, it will be resolved against the WorkingDir of the
   /// FileManager's FileSystemOptions.
+  ///
+  /// \returns false on success, true on error.
   bool getNoncachedStatValue(StringRef Path,
-                             llvm::sys::fs::file_status &Result);
+                             vfs::Status &Result);
 
   /// \brief Remove the real file \p Entry from the cache.
   void invalidateCache(const FileEntry *Entry);
diff --git a/include/clang/Basic/FileSystemStatCache.h b/include/clang/Basic/FileSystemStatCache.h
index 23d8256..9be8b10 100644
--- a/include/clang/Basic/FileSystemStatCache.h
+++ b/include/clang/Basic/FileSystemStatCache.h
@@ -16,21 +16,30 @@
 #define LLVM_CLANG_FILESYSTEMSTATCACHE_H
 
 #include "clang/Basic/LLVM.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/Support/FileSystem.h"
-#include <sys/stat.h>
-#include <sys/types.h>
+#include <memory>
 
 namespace clang {
 
+namespace vfs {
+class File;
+class FileSystem;
+}
+
+// FIXME: should probably replace this with vfs::Status
 struct FileData {
+  std::string Name;
   uint64_t Size;
   time_t ModTime;
   llvm::sys::fs::UniqueID UniqueID;
   bool IsDirectory;
   bool IsNamedPipe;
   bool InPCH;
+  bool IsVFSMapped; // FIXME: remove this when files support multiple names
+  FileData()
+      : Size(0), ModTime(0), IsDirectory(false), IsNamedPipe(false),
+        InPCH(false), IsVFSMapped(false) {}
 };
 
 /// \brief Abstract interface for introducing a FileManager cache for 'stat'
@@ -39,8 +48,8 @@
 class FileSystemStatCache {
   virtual void anchor();
 protected:
-  OwningPtr<FileSystemStatCache> NextStatCache;
-  
+  std::unique_ptr<FileSystemStatCache> NextStatCache;
+
 public:
   virtual ~FileSystemStatCache() {}
   
@@ -57,10 +66,11 @@
   /// If isFile is true, then this lookup should only return success for files
   /// (not directories).  If it is false this lookup should only return
   /// success for directories (not files).  On a successful file lookup, the
-  /// implementation can optionally fill in FileDescriptor with a valid
-  /// descriptor and the client guarantees that it will close it.
+  /// implementation can optionally fill in \p F with a valid \p File object and
+  /// the client guarantees that it will close it.
   static bool get(const char *Path, FileData &Data, bool isFile,
-                  int *FileDescriptor, FileSystemStatCache *Cache);
+                  std::unique_ptr<vfs::File> *F, FileSystemStatCache *Cache,
+                  vfs::FileSystem &FS);
 
   /// \brief Sets the next stat call cache in the chain of stat caches.
   /// Takes ownership of the given stat cache.
@@ -74,21 +84,24 @@
   /// \brief Retrieve the next stat call cache in the chain, transferring
   /// ownership of this cache (and, transitively, all of the remaining caches)
   /// to the caller.
-  FileSystemStatCache *takeNextStatCache() { return NextStatCache.take(); }
-  
+  FileSystemStatCache *takeNextStatCache() { return NextStatCache.release(); }
+
 protected:
+  // FIXME: The pointer here is a non-owning/optional reference to the
+  // unique_ptr. Optional<unique_ptr<vfs::File>&> might be nicer, but
+  // Optional needs some work to support references so this isn't possible yet.
   virtual LookupResult getStat(const char *Path, FileData &Data, bool isFile,
-                               int *FileDescriptor) = 0;
+                               std::unique_ptr<vfs::File> *F,
+                               vfs::FileSystem &FS) = 0;
 
   LookupResult statChained(const char *Path, FileData &Data, bool isFile,
-                           int *FileDescriptor) {
+                           std::unique_ptr<vfs::File> *F, vfs::FileSystem &FS) {
     if (FileSystemStatCache *Next = getNextStatCache())
-      return Next->getStat(Path, Data, isFile, FileDescriptor);
+      return Next->getStat(Path, Data, isFile, F, FS);
 
     // If we hit the end of the list of stat caches to try, just compute and
     // return it without a cache.
-    return get(Path, Data, isFile, FileDescriptor, 0) ? CacheMissing
-                                                      : CacheExists;
+    return get(Path, Data, isFile, F, nullptr, FS) ? CacheMissing : CacheExists;
   }
 };
 
@@ -106,8 +119,9 @@
   iterator begin() const { return StatCalls.begin(); }
   iterator end() const { return StatCalls.end(); }
 
-  virtual LookupResult getStat(const char *Path, FileData &Data, bool isFile,
-                               int *FileDescriptor);
+  LookupResult getStat(const char *Path, FileData &Data, bool isFile,
+                       std::unique_ptr<vfs::File> *F,
+                       vfs::FileSystem &FS) override;
 };
 
 } // end namespace clang
diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h
index 304ff36..0c278a1 100644
--- a/include/clang/Basic/IdentifierTable.h
+++ b/include/clang/Basic/IdentifierTable.h
@@ -17,12 +17,9 @@
 #define LLVM_CLANG_BASIC_IDENTIFIERTABLE_H
 
 #include "clang/Basic/LLVM.h"
-#include "clang/Basic/OperatorKinds.h"
 #include "clang/Basic/TokenKinds.h"
-#include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
-#include "llvm/Support/PointerLikeTypeTraits.h"
 #include <cassert>
 #include <string>
 
@@ -428,7 +425,7 @@
   /// \brief Create the identifier table, populating it with info about the
   /// language keywords for the language specified by \p LangOpts.
   IdentifierTable(const LangOptions &LangOpts,
-                  IdentifierInfoLookup* externalLookup = 0);
+                  IdentifierInfoLookup* externalLookup = nullptr);
 
   /// \brief Set the external identifier lookup mechanism.
   void setExternalIdentifierLookup(IdentifierInfoLookup *IILookup) {
@@ -625,7 +622,7 @@
   IdentifierInfo *getAsIdentifierInfo() const {
     if (getIdentifierInfoFlag() < MultiArg)
       return reinterpret_cast<IdentifierInfo *>(InfoPtr & ~ArgFlags);
-    return 0;
+    return nullptr;
   }
   MultiKeywordSelector *getMultiKeywordSelector() const {
     return reinterpret_cast<MultiKeywordSelector *>(InfoPtr & ~ArgFlags);
@@ -697,9 +694,11 @@
   
   /// \brief Derive the full selector name (e.g. "foo:bar:") and return
   /// it as an std::string.
-  // FIXME: Add a print method that uses a raw_ostream.
   std::string getAsString() const;
 
+  /// \brief Prints the full selector name (e.g. "foo:bar:").
+  void print(llvm::raw_ostream &OS) const;
+
   /// \brief Derive the conventional family of this method.
   ObjCMethodFamily getMethodFamily() const {
     return getMethodFamilyImpl(*this);
@@ -812,6 +811,8 @@
 template <>
 struct isPodLike<clang::Selector> { static const bool value = true; };
 
+template <typename T> class PointerLikeTypeTraits;
+
 template<>
 class PointerLikeTypeTraits<clang::Selector> {
 public:
diff --git a/include/clang/Basic/LLVM.h b/include/clang/Basic/LLVM.h
index 306c75e..5a71fa8 100644
--- a/include/clang/Basic/LLVM.h
+++ b/include/clang/Basic/LLVM.h
@@ -8,7 +8,7 @@
 //===----------------------------------------------------------------------===//
 //
 /// \file
-/// \brief Forward declares and imports various common LLVM datatypes that
+/// \brief Forward-declares and imports various common LLVM datatypes that
 /// clang wants to use unqualified.
 ///
 //===----------------------------------------------------------------------===//
@@ -29,7 +29,7 @@
   class StringRef;
   class Twine;
   template<typename T> class ArrayRef;
-  template<typename T> class OwningPtr;
+  template<typename T> class MutableArrayRef;
   template<unsigned InternalLen> class SmallString;
   template<typename T, unsigned N> class SmallVector;
   template<typename T> class SmallVectorImpl;
@@ -63,7 +63,7 @@
   using llvm::StringRef;
   using llvm::Twine;
   using llvm::ArrayRef;
-  using llvm::OwningPtr;
+  using llvm::MutableArrayRef;
   using llvm::SmallString;
   using llvm::SmallVector;
   using llvm::SmallVectorImpl;
diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def
index 5a1025c..a297a4c 100644
--- a/include/clang/Basic/LangOptions.def
+++ b/include/clang/Basic/LangOptions.def
@@ -43,13 +43,14 @@
 
 LANGOPT(C99               , 1, 0, "C99")
 LANGOPT(C11               , 1, 0, "C11")
-LANGOPT(MicrosoftExt      , 1, 0, "Microsoft extensions")
-LANGOPT(MicrosoftMode     , 1, 0, "Microsoft compatibility mode")
+LANGOPT(MSVCCompat        , 1, 0, "Microsoft Visual C++ full compatibility mode")
+LANGOPT(MicrosoftExt      , 1, 0, "Microsoft C++ extensions")
 LANGOPT(AsmBlocks         , 1, 0, "Microsoft inline asm blocks")
 LANGOPT(Borland           , 1, 0, "Borland extensions")
 LANGOPT(CPlusPlus         , 1, 0, "C++")
-LANGOPT(CPlusPlus11       , 1, 0, "C++0x")
+LANGOPT(CPlusPlus11       , 1, 0, "C++11")
 LANGOPT(CPlusPlus1y       , 1, 0, "C++1y")
+LANGOPT(CPlusPlus1z       , 1, 0, "C++1z")
 LANGOPT(ObjC1             , 1, 0, "Objective-C 1")
 LANGOPT(ObjC2             , 1, 0, "Objective-C 2")
 BENIGN_LANGOPT(ObjCDefaultSynthProperties , 1, 0,
@@ -61,6 +62,7 @@
 LANGOPT(Trigraphs         , 1, 0,"trigraphs")
 LANGOPT(LineComment       , 1, 0, "'//' comments")
 LANGOPT(Bool              , 1, 0, "bool, true, and false keywords")
+LANGOPT(Half              , 1, 0, "half keyword")
 LANGOPT(WChar             , 1, CPlusPlus, "wchar_t keyword")
 BENIGN_LANGOPT(DollarIdents   , 1, 1, "'$' in identifiers")
 BENIGN_LANGOPT(AsmPreprocessor, 1, 0, "preprocessor in asm mode")
@@ -82,6 +84,7 @@
 LANGOPT(SjLjExceptions    , 1, 0, "setjmp-longjump exception handling")
 LANGOPT(TraditionalCPP    , 1, 0, "traditional CPP emulation")
 LANGOPT(RTTI              , 1, 1, "run-time type information")
+LANGOPT(RTTIData          , 1, 1, "emit run-time type information data")
 LANGOPT(MSBitfields       , 1, 0, "Microsoft-compatible structure layout")
 LANGOPT(Freestanding, 1, 0, "freestanding implementation")
 LANGOPT(NoBuiltin         , 1, 0, "disable builtin functions")
@@ -95,6 +98,9 @@
 BENIGN_LANGOPT(HeinousExtensions , 1, 0, "Extensions that we really don't like and may be ripped out at any time")
 LANGOPT(Modules           , 1, 0, "modules extension to C")
 LANGOPT(ModulesDeclUse    , 1, 0, "require declaration of module uses")
+LANGOPT(ModulesSearchAll  , 1, 1, "search even non-imported modules to find unresolved references")
+LANGOPT(ModulesStrictDeclUse, 1, 0, "require declaration of module uses and all headers to be in modules")
+LANGOPT(ModulesErrorRecovery, 1, 1, "automatically import modules as needed when performing error recovery")
 LANGOPT(Optimize          , 1, 0, "__OPTIMIZE__ predefined macro")
 LANGOPT(OptimizeSize      , 1, 0, "__OPTIMIZE_SIZE__ predefined macro")
 LANGOPT(Static            , 1, 0, "__STATIC__ predefined macro (as opposed to __DYNAMIC__)")
@@ -113,6 +119,7 @@
 BENIGN_LANGOPT(AccessControl     , 1, 1, "C++ access control")
 LANGOPT(CharIsSigned      , 1, 1, "signed char")
 LANGOPT(ShortWChar        , 1, 0, "unsigned short wchar_t")
+ENUM_LANGOPT(MSPointerToMemberRepresentationMethod, PragmaMSPointersToMembersKind, 2, PPTMK_BestCase, "member-pointer representation method")
 
 LANGOPT(ShortEnums        , 1, 0, "short enum types")
 
@@ -173,12 +180,12 @@
                "maximum bracket nesting depth")
 BENIGN_LANGOPT(NumLargeByValueCopy, 32, 0,
         "if non-zero, warn about parameter or return Warn if parameter/return value is larger in bytes than this setting. 0 is no check.")
-VALUE_LANGOPT(MSCVersion, 32, 0,
-              "version of Microsoft Visual C/C++")
+VALUE_LANGOPT(MSCompatibilityVersion, 32, 0, "Microsoft Visual C/C++ Version")
+VALUE_LANGOPT(VtorDispMode, 2, 1, "How many vtordisps to insert")
 
 LANGOPT(ApplePragmaPack, 1, 0, "Apple gcc-compatible #pragma pack handling")
 
-BENIGN_LANGOPT(RetainCommentsFromSystemHeaders, 1, 0, "retain documentation comments from system headers in the AST")
+LANGOPT(RetainCommentsFromSystemHeaders, 1, 0, "retain documentation comments from system headers in the AST")
 
 #undef LANGOPT
 #undef VALUE_LANGOPT
diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h
index d4e8b4e..9bffc7c 100644
--- a/include/clang/Basic/LangOptions.h
+++ b/include/clang/Basic/LangOptions.h
@@ -19,7 +19,6 @@
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/ObjCRuntime.h"
 #include "clang/Basic/Visibility.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
 #include <string>
 
 namespace clang {
@@ -53,12 +52,12 @@
 
 /// \brief Keeps track of the various options that can be
 /// enabled, which controls the dialect of C or C++ that is accepted.
-class LangOptions : public RefCountedBase<LangOptions>, public LangOptionsBase {
+class LangOptions : public LangOptionsBase {
 public:
   typedef clang::Visibility Visibility;
   
   enum GCMode { NonGC, GCOnly, HybridGC };
-  enum StackProtectorMode { SSPOff, SSPOn, SSPReq };
+  enum StackProtectorMode { SSPOff, SSPOn, SSPStrong, SSPReq };
   
   enum SignedOverflowBehaviorTy {
     SOB_Undefined,  // Default C standard behavior.
@@ -66,6 +65,13 @@
     SOB_Trapping    // -ftrapv
   };
 
+  enum PragmaMSPointersToMembersKind {
+    PPTMK_BestCase,
+    PPTMK_FullGeneralitySingleInheritance,
+    PPTMK_FullGeneralityMultipleInheritance,
+    PPTMK_FullGeneralityVirtualInheritance
+  };
+
   enum AddrSpaceMapMangling { ASMM_Target, ASMM_On, ASMM_Off };
 
 public:
diff --git a/include/clang/Basic/Linkage.h b/include/clang/Basic/Linkage.h
index 6996207..f3b4769 100644
--- a/include/clang/Basic/Linkage.h
+++ b/include/clang/Basic/Linkage.h
@@ -18,7 +18,7 @@
 
 /// \brief Describes the different kinds of linkage 
 /// (C++ [basic.link], C99 6.2.2) that an entity may have.
-enum Linkage {
+enum Linkage : unsigned char {
   /// \brief No linkage, which means that the entity is unique and
   /// can only be referred to from within its scope.
   NoLinkage = 0,
@@ -59,11 +59,10 @@
 /// This is relevant to CodeGen and AST file reading.
 enum GVALinkage {
   GVA_Internal,
-  GVA_C99Inline,
-  GVA_CXXInline,
+  GVA_AvailableExternally,
+  GVA_DiscardableODR,
   GVA_StrongExternal,
-  GVA_TemplateInstantiation,
-  GVA_ExplicitTemplateInstantiation
+  GVA_StrongODR
 };
 
 inline bool isExternallyVisible(Linkage L) {
diff --git a/include/clang/Basic/Makefile b/include/clang/Basic/Makefile
index 6a33133..5579a99 100644
--- a/include/clang/Basic/Makefile
+++ b/include/clang/Basic/Makefile
@@ -6,6 +6,7 @@
 	DiagnosticFrontendKinds.inc DiagnosticLexKinds.inc \
 	DiagnosticParseKinds.inc DiagnosticSemaKinds.inc \
 	DiagnosticSerializationKinds.inc \
+	AttrHasAttributeImpl.inc \
 	DiagnosticIndexName.inc DiagnosticGroups.inc AttrList.inc arm_neon.inc \
 	Version.inc
 
@@ -48,9 +49,16 @@
 	$(Verb) $(ClangTableGen) -gen-clang-attr-list -o $(call SYSPATH, $@) \
 	  -I $(PROJ_SRC_DIR)/../.. $<
 
+$(ObjDir)/AttrHasAttributeImpl.inc.tmp : Attr.td $(CLANG_TBLGEN) \
+                                  $(ObjDir)/.dir
+	$(Echo) "Building Clang __has_attribute implementation with tblgen"
+	$(Verb) $(ClangTableGen) -gen-clang-attr-has-attribute-impl -o $(call SYSPATH, $@) \
+		-I $(PROJ_SRC_DIR)/../../ $<
+
 $(ObjDir)/arm_neon.inc.tmp : arm_neon.td $(CLANG_TBLGEN) $(ObjDir)/.dir
 	$(Echo) "Building Clang arm_neon.inc with tblgen"
-	$(Verb) $(ClangTableGen) -gen-arm-neon-sema -o $(call SYSPATH, $@) $<
+	$(Verb) $(ClangTableGen) -gen-arm-neon-sema -o $(call SYSPATH, $@) \
+	  -I $(PROJ_SRC_DIR)/../.. $<
 
 $(ObjDir)/Version.inc.tmp : Version.inc.in Makefile $(LLVM_OBJ_ROOT)/Makefile.config $(ObjDir)/.dir
 	$(Echo) "Updating Clang version info."
diff --git a/include/clang/Basic/Module.h b/include/clang/Basic/Module.h
index e8d774e..9b66840 100644
--- a/include/clang/Basic/Module.h
+++ b/include/clang/Basic/Module.h
@@ -51,10 +51,21 @@
   
   /// \brief The location of the module definition.
   SourceLocation DefinitionLoc;
-  
+
   /// \brief The parent of this module. This will be NULL for the top-level
   /// module.
   Module *Parent;
+
+  /// \brief The module map file that (along with the module name) uniquely
+  /// identifies this module.
+  ///
+  /// The particular module that \c Name refers to may depend on how the module
+  /// was found in header search. However, the combination of \c Name and
+  /// \c ModuleMap will be globally unique for top-level modules. In the case of
+  /// inferred modules, \c ModuleMap will contain the module map that allowed
+  /// the inference (e.g. contained 'Module *') rather than the virtual
+  /// inferred module map file.
+  const FileEntry *ModuleMap;
   
   /// \brief The umbrella header or directory.
   llvm::PointerUnion<const DirectoryEntry *, const FileEntry *> Umbrella;
@@ -88,7 +99,19 @@
   SmallVector<const FileEntry *, 2> ExcludedHeaders;
 
   /// \brief The headers that are private to this module.
-  llvm::SmallVector<const FileEntry *, 2> PrivateHeaders;
+  SmallVector<const FileEntry *, 2> PrivateHeaders;
+
+  /// \brief Information about a header directive as found in the module map
+  /// file.
+  struct HeaderDirective {
+    SourceLocation FileNameLoc;
+    std::string FileName;
+    bool IsUmbrella;
+  };
+
+  /// \brief Headers that are mentioned in the module map file but could not be
+  /// found on the file system.
+  SmallVector<HeaderDirective, 1> MissingHeaders;
 
   /// \brief An individual requirement: a feature name and a flag indicating
   /// the required state of that feature.
@@ -100,8 +123,13 @@
   /// will be false to indicate that this (sub)module is not available.
   SmallVector<Requirement, 2> Requirements;
 
-  /// \brief Whether this module is available in the current
-  /// translation unit.
+  /// \brief Whether this module is missing a feature from \c Requirements.
+  unsigned IsMissingRequirement : 1;
+
+  /// \brief Whether this module is available in the current translation unit.
+  ///
+  /// If the module is missing headers or does not meet all requirements then
+  /// this bit will be 0.
   unsigned IsAvailable : 1;
 
   /// \brief Whether this module was loaded from a module file.
@@ -116,7 +144,15 @@
   /// \brief Whether this is a "system" module (which assumes that all
   /// headers in it are system headers).
   unsigned IsSystem : 1;
-  
+
+  /// \brief Whether this is an 'extern "C"' module (which implicitly puts all
+  /// headers in it within an 'extern "C"' block, and allows the module to be
+  /// imported within such a block).
+  unsigned IsExternC : 1;
+
+  /// \brief Whether this is an inferred submodule (module * { ... }).
+  unsigned IsInferred : 1;
+
   /// \brief Whether we should infer submodules for this module based on 
   /// the headers.
   ///
@@ -148,11 +184,14 @@
     MacrosVisible,
     /// \brief All of the names in this module are visible.
     AllVisible
-  };  
-  
-  ///\ brief The visibility of names within this particular module.
+  };
+
+  /// \brief The visibility of names within this particular module.
   NameVisibilityKind NameVisibility;
 
+  /// \brief The location at which macros within this module became visible.
+  SourceLocation MacroVisibilityLoc;
+
   /// \brief The location of the inferred submodule.
   SourceLocation InferredSubmoduleLoc;
 
@@ -243,19 +282,11 @@
   /// \brief The list of conflicts.
   std::vector<Conflict> Conflicts;
 
-  /// \brief Construct a top-level module.
-  explicit Module(StringRef Name, SourceLocation DefinitionLoc,
-                  bool IsFramework)
-    : Name(Name), DefinitionLoc(DefinitionLoc), Parent(0),Umbrella(),ASTFile(0),
-      IsAvailable(true), IsFromModuleFile(false), IsFramework(IsFramework), 
-      IsExplicit(false), IsSystem(false),
-      InferSubmodules(false), InferExplicitSubmodules(false),
-      InferExportWildcard(false), ConfigMacrosExhaustive(false),
-      NameVisibility(Hidden) { }
-  
   /// \brief Construct a new module or submodule.
-  Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, 
-         bool IsFramework, bool IsExplicit);
+  ///
+  /// For an explanation of \p ModuleMap, see Module::ModuleMap.
+  Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
+         const FileEntry *ModuleMap, bool IsFramework, bool IsExplicit);
   
   ~Module();
   
@@ -276,14 +307,15 @@
   /// this module.
   bool isAvailable(const LangOptions &LangOpts, 
                    const TargetInfo &Target,
-                   Requirement &Req) const;
+                   Requirement &Req,
+                   HeaderDirective &MissingHeader) const;
 
   /// \brief Determine whether this module is a submodule.
-  bool isSubModule() const { return Parent != 0; }
+  bool isSubModule() const { return Parent != nullptr; }
   
   /// \brief Determine whether this module is a submodule of the given other
   /// module.
-  bool isSubModuleOf(Module *Other) const;
+  bool isSubModuleOf(const Module *Other) const;
   
   /// \brief Determine whether this module is a part of a framework,
   /// either because it is a framework module or because it is a submodule
@@ -330,7 +362,8 @@
 
   /// \brief Set the serialized AST file for the top-level module of this module.
   void setASTFile(const FileEntry *File) {
-    assert((getASTFile() == 0 || getASTFile() == File) && "file path changed");
+    assert((File == nullptr || getASTFile() == nullptr ||
+            getASTFile() == File) && "file path changed");
     getTopLevelModule()->ASTFile = File;
   }
 
@@ -382,6 +415,9 @@
                       const LangOptions &LangOpts,
                       const TargetInfo &Target);
 
+  /// \brief Mark this module and all of its submodules as unavailable.
+  void markUnavailable(bool MissingRequirement = false);
+
   /// \brief Find the submodule with the given name.
   ///
   /// \returns The submodule if found, or NULL otherwise.
@@ -389,6 +425,10 @@
 
   /// \brief Determine whether the specified module would be visible to
   /// a lookup at the end of this module.
+  ///
+  /// FIXME: This may return incorrect results for (submodules of) the
+  /// module currently being built, if it's queried before we see all
+  /// of its imports.
   bool isModuleVisible(const Module *M) const {
     if (VisibleModulesCache.empty())
       buildVisibleModulesCache();
diff --git a/include/clang/Basic/ObjCRuntime.h b/include/clang/Basic/ObjCRuntime.h
index 52f35a0..fa375f4 100644
--- a/include/clang/Basic/ObjCRuntime.h
+++ b/include/clang/Basic/ObjCRuntime.h
@@ -79,7 +79,7 @@
     case GCC: return false;
     case MacOSX: return true;
     case GNUstep: return true;
-    case ObjFW: return false;
+    case ObjFW: return true;
     case iOS: return true;
     }
     llvm_unreachable("bad kind");
@@ -99,6 +99,11 @@
           Arch == llvm::Triple::x86_64)
         return false;
     }
+    else if ((getKind() ==  MacOSX) && isNonFragile() &&
+             (getVersion() >= VersionTuple(10, 0)) &&
+             (getVersion() < VersionTuple(10, 6)))
+        return Arch != llvm::Triple::x86_64;
+    // Except for deployment target of 10.5 or less,
     // Mac runtimes use legacy dispatch everywhere now.
     return true;
   }
diff --git a/include/clang/Basic/OnDiskHashTable.h b/include/clang/Basic/OnDiskHashTable.h
deleted file mode 100644
index ee30123..0000000
--- a/include/clang/Basic/OnDiskHashTable.h
+++ /dev/null
@@ -1,485 +0,0 @@
-//===--- OnDiskHashTable.h - On-Disk Hash Table Implementation --*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Defines facilities for reading and writing on-disk hash tables.
-///
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_BASIC_ON_DISK_HASH_TABLE_H
-#define LLVM_CLANG_BASIC_ON_DISK_HASH_TABLE_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/Host.h"
-#include "llvm/Support/MathExtras.h"
-#include "llvm/Support/raw_ostream.h"
-#include <cassert>
-#include <cstdlib>
-
-namespace clang {
-
-namespace io {
-
-typedef uint32_t Offset;
-
-inline void Emit8(raw_ostream& Out, uint32_t V) {
-  Out << (unsigned char)(V);
-}
-
-inline void Emit16(raw_ostream& Out, uint32_t V) {
-  Out << (unsigned char)(V);
-  Out << (unsigned char)(V >>  8);
-  assert((V >> 16) == 0);
-}
-
-inline void Emit24(raw_ostream& Out, uint32_t V) {
-  Out << (unsigned char)(V);
-  Out << (unsigned char)(V >>  8);
-  Out << (unsigned char)(V >> 16);
-  assert((V >> 24) == 0);
-}
-
-inline void Emit32(raw_ostream& Out, uint32_t V) {
-  Out << (unsigned char)(V);
-  Out << (unsigned char)(V >>  8);
-  Out << (unsigned char)(V >> 16);
-  Out << (unsigned char)(V >> 24);
-}
-
-inline void Emit64(raw_ostream& Out, uint64_t V) {
-  Out << (unsigned char)(V);
-  Out << (unsigned char)(V >>  8);
-  Out << (unsigned char)(V >> 16);
-  Out << (unsigned char)(V >> 24);
-  Out << (unsigned char)(V >> 32);
-  Out << (unsigned char)(V >> 40);
-  Out << (unsigned char)(V >> 48);
-  Out << (unsigned char)(V >> 56);
-}
-
-inline void Pad(raw_ostream& Out, unsigned A) {
-  Offset off = (Offset) Out.tell();
-  for (uint32_t n = llvm::OffsetToAlignment(off, A); n; --n)
-    Emit8(Out, 0);
-}
-
-inline uint16_t ReadUnalignedLE16(const unsigned char *&Data) {
-  uint16_t V = ((uint16_t)Data[0]) |
-               ((uint16_t)Data[1] <<  8);
-  Data += 2;
-  return V;
-}
-
-inline uint32_t ReadUnalignedLE32(const unsigned char *&Data) {
-  uint32_t V = ((uint32_t)Data[0])  |
-               ((uint32_t)Data[1] << 8)  |
-               ((uint32_t)Data[2] << 16) |
-               ((uint32_t)Data[3] << 24);
-  Data += 4;
-  return V;
-}
-
-inline uint64_t ReadUnalignedLE64(const unsigned char *&Data) {
-  uint64_t V = ((uint64_t)Data[0])  |
-    ((uint64_t)Data[1] << 8)  |
-    ((uint64_t)Data[2] << 16) |
-    ((uint64_t)Data[3] << 24) |
-    ((uint64_t)Data[4] << 32) |
-    ((uint64_t)Data[5] << 40) |
-    ((uint64_t)Data[6] << 48) |
-    ((uint64_t)Data[7] << 56);
-  Data += 8;
-  return V;
-}
-
-inline uint32_t ReadLE32(const unsigned char *&Data) {
-  // Hosts that directly support little-endian 32-bit loads can just
-  // use them.  Big-endian hosts need a bswap.
-  uint32_t V = *((const uint32_t*)Data);
-  if (llvm::sys::IsBigEndianHost)
-    V = llvm::ByteSwap_32(V);
-  Data += 4;
-  return V;
-}
-
-} // end namespace io
-
-template<typename Info>
-class OnDiskChainedHashTableGenerator {
-  unsigned NumBuckets;
-  unsigned NumEntries;
-  llvm::BumpPtrAllocator BA;
-
-  class Item {
-  public:
-    typename Info::key_type key;
-    typename Info::data_type data;
-    Item *next;
-    const uint32_t hash;
-
-    Item(typename Info::key_type_ref k, typename Info::data_type_ref d,
-         Info &InfoObj)
-    : key(k), data(d), next(0), hash(InfoObj.ComputeHash(k)) {}
-  };
-
-  class Bucket {
-  public:
-    io::Offset off;
-    Item* head;
-    unsigned length;
-
-    Bucket() {}
-  };
-
-  Bucket* Buckets;
-
-private:
-  void insert(Bucket* b, size_t size, Item* E) {
-    unsigned idx = E->hash & (size - 1);
-    Bucket& B = b[idx];
-    E->next = B.head;
-    ++B.length;
-    B.head = E;
-  }
-
-  void resize(size_t newsize) {
-    Bucket* newBuckets = (Bucket*) std::calloc(newsize, sizeof(Bucket));
-    // Populate newBuckets with the old entries.
-    for (unsigned i = 0; i < NumBuckets; ++i)
-      for (Item* E = Buckets[i].head; E ; ) {
-        Item* N = E->next;
-        E->next = 0;
-        insert(newBuckets, newsize, E);
-        E = N;
-      }
-
-    free(Buckets);
-    NumBuckets = newsize;
-    Buckets = newBuckets;
-  }
-
-public:
-
-  void insert(typename Info::key_type_ref key,
-              typename Info::data_type_ref data) {
-    Info InfoObj;
-    insert(key, data, InfoObj);
-  }
-
-  void insert(typename Info::key_type_ref key,
-              typename Info::data_type_ref data, Info &InfoObj) {
-
-    ++NumEntries;
-    if (4*NumEntries >= 3*NumBuckets) resize(NumBuckets*2);
-    insert(Buckets, NumBuckets, new (BA.Allocate<Item>()) Item(key, data,
-                                                               InfoObj));
-  }
-
-  io::Offset Emit(raw_ostream &out) {
-    Info InfoObj;
-    return Emit(out, InfoObj);
-  }
-
-  io::Offset Emit(raw_ostream &out, Info &InfoObj) {
-    using namespace clang::io;
-
-    // Emit the payload of the table.
-    for (unsigned i = 0; i < NumBuckets; ++i) {
-      Bucket& B = Buckets[i];
-      if (!B.head) continue;
-
-      // Store the offset for the data of this bucket.
-      B.off = out.tell();
-      assert(B.off && "Cannot write a bucket at offset 0. Please add padding.");
-
-      // Write out the number of items in the bucket.
-      Emit16(out, B.length);
-      assert(B.length != 0  && "Bucket has a head but zero length?");
-
-      // Write out the entries in the bucket.
-      for (Item *I = B.head; I ; I = I->next) {
-        Emit32(out, I->hash);
-        const std::pair<unsigned, unsigned>& Len =
-          InfoObj.EmitKeyDataLength(out, I->key, I->data);
-        InfoObj.EmitKey(out, I->key, Len.first);
-        InfoObj.EmitData(out, I->key, I->data, Len.second);
-      }
-    }
-
-    // Emit the hashtable itself.
-    Pad(out, 4);
-    io::Offset TableOff = out.tell();
-    Emit32(out, NumBuckets);
-    Emit32(out, NumEntries);
-    for (unsigned i = 0; i < NumBuckets; ++i) Emit32(out, Buckets[i].off);
-
-    return TableOff;
-  }
-
-  OnDiskChainedHashTableGenerator() {
-    NumEntries = 0;
-    NumBuckets = 64;
-    // Note that we do not need to run the constructors of the individual
-    // Bucket objects since 'calloc' returns bytes that are all 0.
-    Buckets = (Bucket*) std::calloc(NumBuckets, sizeof(Bucket));
-  }
-
-  ~OnDiskChainedHashTableGenerator() {
-    std::free(Buckets);
-  }
-};
-
-template<typename Info>
-class OnDiskChainedHashTable {
-  const unsigned NumBuckets;
-  const unsigned NumEntries;
-  const unsigned char* const Buckets;
-  const unsigned char* const Base;
-  Info InfoObj;
-
-public:
-  typedef typename Info::internal_key_type internal_key_type;
-  typedef typename Info::external_key_type external_key_type;
-  typedef typename Info::data_type         data_type;
-
-  OnDiskChainedHashTable(unsigned numBuckets, unsigned numEntries,
-                         const unsigned char* buckets,
-                         const unsigned char* base,
-                         const Info &InfoObj = Info())
-    : NumBuckets(numBuckets), NumEntries(numEntries),
-      Buckets(buckets), Base(base), InfoObj(InfoObj) {
-        assert((reinterpret_cast<uintptr_t>(buckets) & 0x3) == 0 &&
-               "'buckets' must have a 4-byte alignment");
-      }
-
-  unsigned getNumBuckets() const { return NumBuckets; }
-  unsigned getNumEntries() const { return NumEntries; }
-  const unsigned char* getBase() const { return Base; }
-  const unsigned char* getBuckets() const { return Buckets; }
-
-  bool isEmpty() const { return NumEntries == 0; }
-
-  class iterator {
-    internal_key_type key;
-    const unsigned char* const data;
-    const unsigned len;
-    Info *InfoObj;
-  public:
-    iterator() : data(0), len(0) {}
-    iterator(const internal_key_type k, const unsigned char* d, unsigned l,
-             Info *InfoObj)
-      : key(k), data(d), len(l), InfoObj(InfoObj) {}
-
-    data_type operator*() const { return InfoObj->ReadData(key, data, len); }
-    bool operator==(const iterator& X) const { return X.data == data; }
-    bool operator!=(const iterator& X) const { return X.data != data; }
-  };
-
-  iterator find(const external_key_type& eKey, Info *InfoPtr = 0) {
-    if (!InfoPtr)
-      InfoPtr = &InfoObj;
-
-    using namespace io;
-    const internal_key_type& iKey = InfoObj.GetInternalKey(eKey);
-    unsigned key_hash = InfoObj.ComputeHash(iKey);
-
-    // Each bucket is just a 32-bit offset into the hash table file.
-    unsigned idx = key_hash & (NumBuckets - 1);
-    const unsigned char* Bucket = Buckets + sizeof(uint32_t)*idx;
-
-    unsigned offset = ReadLE32(Bucket);
-    if (offset == 0) return iterator(); // Empty bucket.
-    const unsigned char* Items = Base + offset;
-
-    // 'Items' starts with a 16-bit unsigned integer representing the
-    // number of items in this bucket.
-    unsigned len = ReadUnalignedLE16(Items);
-
-    for (unsigned i = 0; i < len; ++i) {
-      // Read the hash.
-      uint32_t item_hash = ReadUnalignedLE32(Items);
-
-      // Determine the length of the key and the data.
-      const std::pair<unsigned, unsigned>& L = Info::ReadKeyDataLength(Items);
-      unsigned item_len = L.first + L.second;
-
-      // Compare the hashes.  If they are not the same, skip the entry entirely.
-      if (item_hash != key_hash) {
-        Items += item_len;
-        continue;
-      }
-
-      // Read the key.
-      const internal_key_type& X =
-        InfoPtr->ReadKey((const unsigned char* const) Items, L.first);
-
-      // If the key doesn't match just skip reading the value.
-      if (!InfoPtr->EqualKey(X, iKey)) {
-        Items += item_len;
-        continue;
-      }
-
-      // The key matches!
-      return iterator(X, Items + L.first, L.second, InfoPtr);
-    }
-
-    return iterator();
-  }
-
-  iterator end() const { return iterator(); }
-
-  /// \brief Iterates over all of the keys in the table.
-  class key_iterator {
-    const unsigned char* Ptr;
-    unsigned NumItemsInBucketLeft;
-    unsigned NumEntriesLeft;
-    Info *InfoObj;
-  public:
-    typedef external_key_type value_type;
-
-    key_iterator(const unsigned char* const Ptr, unsigned NumEntries,
-                  Info *InfoObj)
-      : Ptr(Ptr), NumItemsInBucketLeft(0), NumEntriesLeft(NumEntries),
-        InfoObj(InfoObj) { }
-    key_iterator()
-      : Ptr(0), NumItemsInBucketLeft(0), NumEntriesLeft(0), InfoObj(0) { }
-
-    friend bool operator==(const key_iterator &X, const key_iterator &Y) {
-      return X.NumEntriesLeft == Y.NumEntriesLeft;
-    }
-    friend bool operator!=(const key_iterator& X, const key_iterator &Y) {
-      return X.NumEntriesLeft != Y.NumEntriesLeft;
-    }
-
-    key_iterator& operator++() {  // Preincrement
-      if (!NumItemsInBucketLeft) {
-        // 'Items' starts with a 16-bit unsigned integer representing the
-        // number of items in this bucket.
-        NumItemsInBucketLeft = io::ReadUnalignedLE16(Ptr);
-      }
-      Ptr += 4; // Skip the hash.
-      // Determine the length of the key and the data.
-      const std::pair<unsigned, unsigned>& L = Info::ReadKeyDataLength(Ptr);
-      Ptr += L.first + L.second;
-      assert(NumItemsInBucketLeft);
-      --NumItemsInBucketLeft;
-      assert(NumEntriesLeft);
-      --NumEntriesLeft;
-      return *this;
-    }
-    key_iterator operator++(int) {  // Postincrement
-      key_iterator tmp = *this; ++*this; return tmp;
-    }
-
-    value_type operator*() const {
-      const unsigned char* LocalPtr = Ptr;
-      if (!NumItemsInBucketLeft)
-        LocalPtr += 2; // number of items in bucket
-      LocalPtr += 4; // Skip the hash.
-
-      // Determine the length of the key and the data.
-      const std::pair<unsigned, unsigned>& L
-        = Info::ReadKeyDataLength(LocalPtr);
-
-      // Read the key.
-      const internal_key_type& Key = InfoObj->ReadKey(LocalPtr, L.first);
-      return InfoObj->GetExternalKey(Key);
-    }
-  };
-
-  key_iterator key_begin() {
-    return key_iterator(Base + 4, getNumEntries(), &InfoObj);
-  }
-  key_iterator key_end() { return key_iterator(); }
-
-  /// \brief Iterates over all the entries in the table, returning the data.
-  class data_iterator {
-    const unsigned char* Ptr;
-    unsigned NumItemsInBucketLeft;
-    unsigned NumEntriesLeft;
-    Info *InfoObj;
-  public:
-    typedef data_type value_type;
-
-    data_iterator(const unsigned char* const Ptr, unsigned NumEntries,
-                  Info *InfoObj)
-      : Ptr(Ptr), NumItemsInBucketLeft(0), NumEntriesLeft(NumEntries),
-        InfoObj(InfoObj) { }
-    data_iterator()
-      : Ptr(0), NumItemsInBucketLeft(0), NumEntriesLeft(0), InfoObj(0) { }
-
-    bool operator==(const data_iterator& X) const {
-      return X.NumEntriesLeft == NumEntriesLeft;
-    }
-    bool operator!=(const data_iterator& X) const {
-      return X.NumEntriesLeft != NumEntriesLeft;
-    }
-
-    data_iterator& operator++() {  // Preincrement
-      if (!NumItemsInBucketLeft) {
-        // 'Items' starts with a 16-bit unsigned integer representing the
-        // number of items in this bucket.
-        NumItemsInBucketLeft = io::ReadUnalignedLE16(Ptr);
-      }
-      Ptr += 4; // Skip the hash.
-      // Determine the length of the key and the data.
-      const std::pair<unsigned, unsigned>& L = Info::ReadKeyDataLength(Ptr);
-      Ptr += L.first + L.second;
-      assert(NumItemsInBucketLeft);
-      --NumItemsInBucketLeft;
-      assert(NumEntriesLeft);
-      --NumEntriesLeft;
-      return *this;
-    }
-    data_iterator operator++(int) {  // Postincrement
-      data_iterator tmp = *this; ++*this; return tmp;
-    }
-
-    value_type operator*() const {
-      const unsigned char* LocalPtr = Ptr;
-      if (!NumItemsInBucketLeft)
-        LocalPtr += 2; // number of items in bucket
-      LocalPtr += 4; // Skip the hash.
-
-      // Determine the length of the key and the data.
-      const std::pair<unsigned, unsigned>& L =Info::ReadKeyDataLength(LocalPtr);
-
-      // Read the key.
-      const internal_key_type& Key =
-        InfoObj->ReadKey(LocalPtr, L.first);
-      return InfoObj->ReadData(Key, LocalPtr + L.first, L.second);
-    }
-  };
-
-  data_iterator data_begin() {
-    return data_iterator(Base + 4, getNumEntries(), &InfoObj);
-  }
-  data_iterator data_end() { return data_iterator(); }
-
-  Info &getInfoObj() { return InfoObj; }
-
-  static OnDiskChainedHashTable* Create(const unsigned char* buckets,
-                                        const unsigned char* const base,
-                                        const Info &InfoObj = Info()) {
-    using namespace io;
-    assert(buckets > base);
-    assert((reinterpret_cast<uintptr_t>(buckets) & 0x3) == 0 &&
-           "buckets should be 4-byte aligned.");
-
-    unsigned numBuckets = ReadLE32(buckets);
-    unsigned numEntries = ReadLE32(buckets);
-    return new OnDiskChainedHashTable<Info>(numBuckets, numEntries, buckets,
-                                            base, InfoObj);
-  }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/include/clang/Basic/OpenCL.h b/include/clang/Basic/OpenCL.h
deleted file mode 100644
index 3b3f259..0000000
--- a/include/clang/Basic/OpenCL.h
+++ /dev/null
@@ -1,29 +0,0 @@
-//===--- OpenCL.h - OpenCL enums --------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Defines some OpenCL-specific enums.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_BASIC_OPENCL_H
-#define LLVM_CLANG_BASIC_OPENCL_H
-
-namespace clang {
-
-/// \brief Names for the OpenCL image access qualifiers (OpenCL 1.1 6.6).
-enum OpenCLImageAccess {
-  CLIA_read_only = 1,
-  CLIA_write_only = 2,
-  CLIA_read_write = 3
-};
-
-}
-
-#endif
diff --git a/include/clang/Basic/OpenMPKinds.def b/include/clang/Basic/OpenMPKinds.def
index 6d1a7b2..6cfa5ea 100644
--- a/include/clang/Basic/OpenMPKinds.def
+++ b/include/clang/Basic/OpenMPKinds.def
@@ -15,38 +15,196 @@
 #ifndef OPENMP_DIRECTIVE
 #  define OPENMP_DIRECTIVE(Name)
 #endif
+#ifndef OPENMP_DIRECTIVE_EXT
+#define OPENMP_DIRECTIVE_EXT(Name, Str)
+#endif
 #ifndef OPENMP_CLAUSE
 #  define OPENMP_CLAUSE(Name, Class)
 #endif
 #ifndef OPENMP_PARALLEL_CLAUSE
 #  define OPENMP_PARALLEL_CLAUSE(Name)
 #endif
+#ifndef OPENMP_SIMD_CLAUSE
+#  define OPENMP_SIMD_CLAUSE(Name)
+#endif
+#ifndef OPENMP_FOR_CLAUSE
+#  define OPENMP_FOR_CLAUSE(Name)
+#endif
+#ifndef OPENMP_SECTIONS_CLAUSE
+#  define OPENMP_SECTIONS_CLAUSE(Name)
+#endif
+#ifndef OPENMP_SINGLE_CLAUSE
+#  define OPENMP_SINGLE_CLAUSE(Name)
+#endif
+#ifndef OPENMP_PARALLEL_FOR_CLAUSE
+#  define OPENMP_PARALLEL_FOR_CLAUSE(Name)
+#endif
+#ifndef OPENMP_PARALLEL_SECTIONS_CLAUSE
+#  define OPENMP_PARALLEL_SECTIONS_CLAUSE(Name)
+#endif
+#ifndef OPENMP_TASK_CLAUSE
+#  define OPENMP_TASK_CLAUSE(Name)
+#endif
 #ifndef OPENMP_DEFAULT_KIND
 #  define OPENMP_DEFAULT_KIND(Name)
 #endif
+#ifndef OPENMP_PROC_BIND_KIND
+#  define OPENMP_PROC_BIND_KIND(Name)
+#endif
+#ifndef OPENMP_SCHEDULE_KIND
+#define OPENMP_SCHEDULE_KIND(Name)
+#endif
 
 // OpenMP directives.
 OPENMP_DIRECTIVE(threadprivate)
 OPENMP_DIRECTIVE(parallel)
 OPENMP_DIRECTIVE(task)
+OPENMP_DIRECTIVE(simd)
+OPENMP_DIRECTIVE(for)
+OPENMP_DIRECTIVE(sections)
+OPENMP_DIRECTIVE(section)
+OPENMP_DIRECTIVE(single)
+OPENMP_DIRECTIVE(master)
+OPENMP_DIRECTIVE(critical)
+OPENMP_DIRECTIVE(taskyield)
+OPENMP_DIRECTIVE(barrier)
+OPENMP_DIRECTIVE(taskwait)
+OPENMP_DIRECTIVE(flush)
+OPENMP_DIRECTIVE_EXT(parallel_for, "parallel for")
+OPENMP_DIRECTIVE_EXT(parallel_sections, "parallel sections")
 
 // OpenMP clauses.
+OPENMP_CLAUSE(if, OMPIfClause)
+OPENMP_CLAUSE(final, OMPFinalClause)
+OPENMP_CLAUSE(num_threads, OMPNumThreadsClause)
+OPENMP_CLAUSE(safelen, OMPSafelenClause)
+OPENMP_CLAUSE(collapse, OMPCollapseClause)
 OPENMP_CLAUSE(default, OMPDefaultClause)
 OPENMP_CLAUSE(private, OMPPrivateClause)
 OPENMP_CLAUSE(firstprivate, OMPFirstprivateClause)
+OPENMP_CLAUSE(lastprivate, OMPLastprivateClause)
 OPENMP_CLAUSE(shared,  OMPSharedClause)
+OPENMP_CLAUSE(reduction,  OMPReductionClause)
+OPENMP_CLAUSE(linear,  OMPLinearClause)
+OPENMP_CLAUSE(aligned, OMPAlignedClause)
+OPENMP_CLAUSE(copyin,  OMPCopyinClause)
+OPENMP_CLAUSE(copyprivate,  OMPCopyprivateClause)
+OPENMP_CLAUSE(proc_bind, OMPProcBindClause)
+OPENMP_CLAUSE(schedule, OMPScheduleClause)
+OPENMP_CLAUSE(ordered, OMPOrderedClause)
+OPENMP_CLAUSE(nowait, OMPNowaitClause)
+OPENMP_CLAUSE(untied, OMPUntiedClause)
+OPENMP_CLAUSE(mergeable, OMPMergeableClause)
+OPENMP_CLAUSE(flush, OMPFlushClause)
 
-// Clauses allowed for OpenMP directives.
+// Clauses allowed for OpenMP directive 'parallel'.
+OPENMP_PARALLEL_CLAUSE(if)
+OPENMP_PARALLEL_CLAUSE(num_threads)
 OPENMP_PARALLEL_CLAUSE(default)
+OPENMP_PARALLEL_CLAUSE(proc_bind)
 OPENMP_PARALLEL_CLAUSE(private)
 OPENMP_PARALLEL_CLAUSE(firstprivate)
 OPENMP_PARALLEL_CLAUSE(shared)
+OPENMP_PARALLEL_CLAUSE(reduction)
+OPENMP_PARALLEL_CLAUSE(copyin)
+
+// Clauses allowed for directive 'omp simd'.
+OPENMP_SIMD_CLAUSE(private)
+OPENMP_SIMD_CLAUSE(lastprivate)
+OPENMP_SIMD_CLAUSE(linear)
+OPENMP_SIMD_CLAUSE(aligned)
+OPENMP_SIMD_CLAUSE(safelen)
+OPENMP_SIMD_CLAUSE(collapse)
+OPENMP_SIMD_CLAUSE(reduction)
+
+// Clauses allowed for directive 'omp for'.
+OPENMP_FOR_CLAUSE(private)
+OPENMP_FOR_CLAUSE(lastprivate)
+OPENMP_FOR_CLAUSE(firstprivate)
+OPENMP_FOR_CLAUSE(reduction)
+OPENMP_FOR_CLAUSE(collapse)
+OPENMP_FOR_CLAUSE(schedule)
+OPENMP_FOR_CLAUSE(ordered)
+OPENMP_FOR_CLAUSE(nowait)
+
+// Clauses allowed for OpenMP directive 'omp sections'.
+OPENMP_SECTIONS_CLAUSE(private)
+OPENMP_SECTIONS_CLAUSE(lastprivate)
+OPENMP_SECTIONS_CLAUSE(firstprivate)
+OPENMP_SECTIONS_CLAUSE(reduction)
+OPENMP_SECTIONS_CLAUSE(nowait)
+
+// Clauses allowed for directive 'omp single'.
+OPENMP_SINGLE_CLAUSE(private)
+OPENMP_SINGLE_CLAUSE(firstprivate)
+OPENMP_SINGLE_CLAUSE(copyprivate)
+OPENMP_SINGLE_CLAUSE(nowait)
 
 // Static attributes for 'default' clause.
 OPENMP_DEFAULT_KIND(none)
 OPENMP_DEFAULT_KIND(shared)
 
+// Static attributes for 'proc_bind' clause.
+OPENMP_PROC_BIND_KIND(master)
+OPENMP_PROC_BIND_KIND(close)
+OPENMP_PROC_BIND_KIND(spread)
+
+// Static attributes for 'schedule' clause.
+OPENMP_SCHEDULE_KIND(static)
+OPENMP_SCHEDULE_KIND(dynamic)
+OPENMP_SCHEDULE_KIND(guided)
+OPENMP_SCHEDULE_KIND(auto)
+OPENMP_SCHEDULE_KIND(runtime)
+
+// Clauses allowed for OpenMP directive 'parallel for'.
+OPENMP_PARALLEL_FOR_CLAUSE(if)
+OPENMP_PARALLEL_FOR_CLAUSE(num_threads)
+OPENMP_PARALLEL_FOR_CLAUSE(default)
+OPENMP_PARALLEL_FOR_CLAUSE(proc_bind)
+OPENMP_PARALLEL_FOR_CLAUSE(private)
+OPENMP_PARALLEL_FOR_CLAUSE(firstprivate)
+OPENMP_PARALLEL_FOR_CLAUSE(shared)
+OPENMP_PARALLEL_FOR_CLAUSE(reduction)
+OPENMP_PARALLEL_FOR_CLAUSE(copyin)
+OPENMP_PARALLEL_FOR_CLAUSE(lastprivate)
+OPENMP_PARALLEL_FOR_CLAUSE(collapse)
+OPENMP_PARALLEL_FOR_CLAUSE(schedule)
+OPENMP_PARALLEL_FOR_CLAUSE(ordered)
+
+// Clauses allowed for OpenMP directive 'parallel sections'.
+OPENMP_PARALLEL_SECTIONS_CLAUSE(if)
+OPENMP_PARALLEL_SECTIONS_CLAUSE(num_threads)
+OPENMP_PARALLEL_SECTIONS_CLAUSE(default)
+OPENMP_PARALLEL_SECTIONS_CLAUSE(proc_bind)
+OPENMP_PARALLEL_SECTIONS_CLAUSE(private)
+OPENMP_PARALLEL_SECTIONS_CLAUSE(firstprivate)
+OPENMP_PARALLEL_SECTIONS_CLAUSE(shared)
+OPENMP_PARALLEL_SECTIONS_CLAUSE(reduction)
+OPENMP_PARALLEL_SECTIONS_CLAUSE(copyin)
+OPENMP_PARALLEL_SECTIONS_CLAUSE(lastprivate)
+
+// Clauses allowed for OpenMP directive 'task'.
+OPENMP_TASK_CLAUSE(if)
+OPENMP_TASK_CLAUSE(final)
+OPENMP_TASK_CLAUSE(default)
+OPENMP_TASK_CLAUSE(private)
+OPENMP_TASK_CLAUSE(firstprivate)
+OPENMP_TASK_CLAUSE(shared)
+OPENMP_TASK_CLAUSE(untied)
+OPENMP_TASK_CLAUSE(mergeable)
+
+#undef OPENMP_SCHEDULE_KIND
+#undef OPENMP_PROC_BIND_KIND
 #undef OPENMP_DEFAULT_KIND
 #undef OPENMP_DIRECTIVE
+#undef OPENMP_DIRECTIVE_EXT
 #undef OPENMP_CLAUSE
+#undef OPENMP_SINGLE_CLAUSE
+#undef OPENMP_SECTIONS_CLAUSE
 #undef OPENMP_PARALLEL_CLAUSE
+#undef OPENMP_PARALLEL_FOR_CLAUSE
+#undef OPENMP_PARALLEL_SECTIONS_CLAUSE
+#undef OPENMP_TASK_CLAUSE
+#undef OPENMP_SIMD_CLAUSE
+#undef OPENMP_FOR_CLAUSE
+
diff --git a/include/clang/Basic/OpenMPKinds.h b/include/clang/Basic/OpenMPKinds.h
index 5b45731..526cbb2 100644
--- a/include/clang/Basic/OpenMPKinds.h
+++ b/include/clang/Basic/OpenMPKinds.h
@@ -21,30 +21,45 @@
 
 /// \brief OpenMP directives.
 enum OpenMPDirectiveKind {
-  OMPD_unknown = 0,
 #define OPENMP_DIRECTIVE(Name) \
   OMPD_##Name,
+#define OPENMP_DIRECTIVE_EXT(Name, Str) \
+  OMPD_##Name,
 #include "clang/Basic/OpenMPKinds.def"
-  NUM_OPENMP_DIRECTIVES
+  OMPD_unknown
 };
 
 /// \brief OpenMP clauses.
 enum OpenMPClauseKind {
-  OMPC_unknown = 0,
 #define OPENMP_CLAUSE(Name, Class) \
   OMPC_##Name,
 #include "clang/Basic/OpenMPKinds.def"
   OMPC_threadprivate,
-  NUM_OPENMP_CLAUSES
+  OMPC_unknown
 };
 
 /// \brief OpenMP attributes for 'default' clause.
 enum OpenMPDefaultClauseKind {
-  OMPC_DEFAULT_unknown = 0,
 #define OPENMP_DEFAULT_KIND(Name) \
   OMPC_DEFAULT_##Name,
 #include "clang/Basic/OpenMPKinds.def"
-  NUM_OPENMP_DEFAULT_KINDS
+  OMPC_DEFAULT_unknown
+};
+
+/// \brief OpenMP attributes for 'proc_bind' clause.
+enum OpenMPProcBindClauseKind {
+#define OPENMP_PROC_BIND_KIND(Name) \
+  OMPC_PROC_BIND_##Name,
+#include "clang/Basic/OpenMPKinds.def"
+  OMPC_PROC_BIND_unknown
+};
+
+/// \brief OpenMP attributes for 'schedule' clause.
+enum OpenMPScheduleClauseKind {
+#define OPENMP_SCHEDULE_KIND(Name) \
+  OMPC_SCHEDULE_##Name,
+#include "clang/Basic/OpenMPKinds.def"
+  OMPC_SCHEDULE_unknown
 };
 
 OpenMPDirectiveKind getOpenMPDirectiveKind(llvm::StringRef Str);
@@ -59,6 +74,43 @@
 bool isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
                                  OpenMPClauseKind CKind);
 
+/// \brief Checks if the specified directive is a directive with an associated
+/// loop construct.
+/// \param DKind Specified directive.
+/// \return true - the directive is a loop-associated directive like 'omp simd'
+/// or 'omp for' directive, otherwise - false.
+bool isOpenMPLoopDirective(OpenMPDirectiveKind DKind);
+
+/// \brief Checks if the specified directive is a worksharing directive.
+/// \param DKind Specified directive.
+/// \return true - the directive is a worksharing directive like 'omp for',
+/// otherwise - false.
+bool isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind);
+
+/// \brief Checks if the specified directive is a parallel-kind directive.
+/// \param DKind Specified directive.
+/// \return true - the directive is a parallel-like directive like 'omp
+/// parallel', otherwise - false.
+bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind);
+
+/// \brief Checks if the specified directive is a simd directive.
+/// \param DKind Specified directive.
+/// \return true - the directive is a simd directive like 'omp simd',
+/// otherwise - false.
+bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind);
+
+/// \brief Checks if the specified clause is one of private clauses like
+/// 'private', 'firstprivate', 'reduction' etc..
+/// \param Kind Clause kind.
+/// \return true - the clause is a private clause, otherwise - false.
+bool isOpenMPPrivate(OpenMPClauseKind Kind);
+
+/// \brief Checks if the specified clause is one of threadprivate clauses like
+/// 'threadprivate', 'copyin' or 'copyprivate'.
+/// \param Kind Clause kind.
+/// \return true - the clause is a threadprivate clause, otherwise - false.
+bool isOpenMPThreadPrivate(OpenMPClauseKind Kind);
+
 }
 
 #endif
diff --git a/include/clang/Basic/OperatorKinds.h b/include/clang/Basic/OperatorKinds.h
index 2ceab9c..d3b70c2 100644
--- a/include/clang/Basic/OperatorKinds.h
+++ b/include/clang/Basic/OperatorKinds.h
@@ -19,7 +19,7 @@
 
 /// \brief Enumeration specifying the different kinds of C++ overloaded
 /// operators.
-enum OverloadedOperatorKind {
+enum OverloadedOperatorKind : int {
   OO_None,                ///< Not an overloaded operator
 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
   OO_##Name,
diff --git a/include/clang/Basic/PartialDiagnostic.h b/include/clang/Basic/PartialDiagnostic.h
index dd29926..8ae3b22 100644
--- a/include/clang/Basic/PartialDiagnostic.h
+++ b/include/clang/Basic/PartialDiagnostic.h
@@ -36,7 +36,7 @@
   };
 
   struct Storage {
-    Storage() : NumDiagArgs(0), NumDiagRanges(0) { }
+    Storage() : NumDiagArgs(0) { }
 
     enum {
         /// \brief The maximum number of arguments we can hold. We
@@ -50,9 +50,6 @@
     /// \brief The number of entries in Arguments.
     unsigned char NumDiagArgs;
 
-    /// \brief This is the number of ranges in the DiagRanges array.
-    unsigned char NumDiagRanges;
-
     /// \brief Specifies for each argument whether it is in DiagArgumentsStr
     /// or in DiagArguments.
     unsigned char DiagArgumentsKind[MaxArguments];
@@ -69,9 +66,7 @@
     std::string DiagArgumentsStr[MaxArguments];
 
     /// \brief The list of ranges added to this diagnostic.
-    ///
-    /// It currently only support 10 ranges, could easily be extended if needed.
-    CharSourceRange DiagRanges[10];
+    SmallVector<CharSourceRange, 8> DiagRanges;
 
     /// \brief If valid, provides a hint with some code to insert, remove, or
     /// modify at a particular position.
@@ -97,7 +92,7 @@
 
       Storage *Result = FreeList[--NumFreeListEntries];
       Result->NumDiagArgs = 0;
-      Result->NumDiagRanges = 0;
+      Result->DiagRanges.clear();
       Result->FixItHints.clear();
       return Result;
     }
@@ -159,17 +154,14 @@
       Allocator->Deallocate(DiagStorage);
     else if (Allocator != reinterpret_cast<StorageAllocator *>(~uintptr_t(0)))
       delete DiagStorage;
-    DiagStorage = 0;
+    DiagStorage = nullptr;
   }
 
   void AddSourceRange(const CharSourceRange &R) const {
     if (!DiagStorage)
       DiagStorage = getStorage();
 
-    assert(DiagStorage->NumDiagRanges <
-           llvm::array_lengthof(DiagStorage->DiagRanges) &&
-           "Too many arguments to diagnostic!");
-    DiagStorage->DiagRanges[DiagStorage->NumDiagRanges++] = R;
+    DiagStorage->DiagRanges.push_back(R);
   }
 
   void AddFixItHint(const FixItHint &Hint) const {
@@ -187,13 +179,13 @@
   /// \brief Create a null partial diagnostic, which cannot carry a payload,
   /// and only exists to be swapped with a real partial diagnostic.
   PartialDiagnostic(NullDiagnostic)
-    : DiagID(0), DiagStorage(0), Allocator(0) { }
+    : DiagID(0), DiagStorage(nullptr), Allocator(nullptr) { }
 
   PartialDiagnostic(unsigned DiagID, StorageAllocator &Allocator)
-    : DiagID(DiagID), DiagStorage(0), Allocator(&Allocator) { }
+    : DiagID(DiagID), DiagStorage(nullptr), Allocator(&Allocator) { }
 
   PartialDiagnostic(const PartialDiagnostic &Other)
-    : DiagID(Other.DiagID), DiagStorage(0), Allocator(Other.Allocator)
+    : DiagID(Other.DiagID), DiagStorage(nullptr), Allocator(Other.Allocator)
   {
     if (Other.DiagStorage) {
       DiagStorage = getStorage();
@@ -201,13 +193,11 @@
     }
   }
 
-#if LLVM_HAS_RVALUE_REFERENCES
   PartialDiagnostic(PartialDiagnostic &&Other)
     : DiagID(Other.DiagID), DiagStorage(Other.DiagStorage),
       Allocator(Other.Allocator) {
-    Other.DiagStorage = 0;
+    Other.DiagStorage = nullptr;
   }
-#endif
 
   PartialDiagnostic(const PartialDiagnostic &Other, Storage *DiagStorage)
     : DiagID(Other.DiagID), DiagStorage(DiagStorage),
@@ -218,7 +208,7 @@
   }
 
   PartialDiagnostic(const Diagnostic &Other, StorageAllocator &Allocator)
-    : DiagID(Other.getID()), DiagStorage(0), Allocator(&Allocator)
+    : DiagID(Other.getID()), DiagStorage(nullptr), Allocator(&Allocator)
   {
     // Copy arguments.
     for (unsigned I = 0, N = Other.getNumArgs(); I != N; ++I) {
@@ -251,7 +241,6 @@
     return *this;
   }
 
-#if LLVM_HAS_RVALUE_REFERENCES
   PartialDiagnostic &operator=(PartialDiagnostic &&Other) {
     freeStorage();
 
@@ -259,10 +248,9 @@
     DiagStorage = Other.DiagStorage;
     Allocator = Other.Allocator;
 
-    Other.DiagStorage = 0;
+    Other.DiagStorage = nullptr;
     return *this;
   }
-#endif
 
   ~PartialDiagnostic() {
     freeStorage();
@@ -312,12 +300,12 @@
     }
 
     // Add all ranges.
-    for (unsigned i = 0, e = DiagStorage->NumDiagRanges; i != e; ++i)
-      DB.AddSourceRange(DiagStorage->DiagRanges[i]);
+    for (const CharSourceRange &Range : DiagStorage->DiagRanges)
+      DB.AddSourceRange(Range);
 
     // Add all fix-its.
-    for (unsigned i = 0, e = DiagStorage->FixItHints.size(); i != e; ++i)
-      DB.AddFixItHint(DiagStorage->FixItHints[i]);
+    for (const FixItHint &Fix : DiagStorage->FixItHints)
+      DB.AddFixItHint(Fix);
   }
 
   void EmitToString(DiagnosticsEngine &Diags,
@@ -339,7 +327,7 @@
     freeStorage();
   }
 
-  bool hasStorage() const { return DiagStorage != 0; }
+  bool hasStorage() const { return DiagStorage != nullptr; }
 
   friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
                                              unsigned I) {
@@ -380,8 +368,8 @@
   // match.
   template<typename T>
   friend inline
-  typename llvm::enable_if<llvm::is_same<T, DeclContext>,
-                           const PartialDiagnostic &>::type
+  typename std::enable_if<std::is_same<T, DeclContext>::value,
+                          const PartialDiagnostic &>::type
   operator<<(const PartialDiagnostic &PD, T *DC) {
     PD.AddTaggedVal(reinterpret_cast<intptr_t>(DC),
                     DiagnosticsEngine::ak_declcontext);
diff --git a/include/clang/Basic/PlistSupport.h b/include/clang/Basic/PlistSupport.h
new file mode 100644
index 0000000..b7a9382
--- /dev/null
+++ b/include/clang/Basic/PlistSupport.h
@@ -0,0 +1,122 @@
+//===---------- PlistSupport.h - Plist Output Utilities ---------*- 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_PLISTSUPPORT_H
+#define LLVM_CLANG_PLISTSUPPORT_H
+
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/Lexer.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace clang {
+namespace markup {
+typedef llvm::DenseMap<FileID, unsigned> FIDMap;
+
+inline void AddFID(FIDMap &FIDs, SmallVectorImpl<FileID> &V,
+                   const SourceManager &SM, SourceLocation L) {
+  FileID FID = SM.getFileID(SM.getExpansionLoc(L));
+  FIDMap::iterator I = FIDs.find(FID);
+  if (I != FIDs.end())
+    return;
+  FIDs[FID] = V.size();
+  V.push_back(FID);
+}
+
+inline unsigned GetFID(const FIDMap &FIDs, const SourceManager &SM,
+                       SourceLocation L) {
+  FileID FID = SM.getFileID(SM.getExpansionLoc(L));
+  FIDMap::const_iterator I = FIDs.find(FID);
+  assert(I != FIDs.end());
+  return I->second;
+}
+
+inline raw_ostream &Indent(raw_ostream &o, const unsigned indent) {
+  for (unsigned i = 0; i < indent; ++i)
+    o << ' ';
+  return o;
+}
+
+inline raw_ostream &EmitPlistHeader(raw_ostream &o) {
+  static const char *PlistHeader =
+      "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+      "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" "
+      "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
+      "<plist version=\"1.0\">\n";
+  return o << PlistHeader;
+}
+
+inline raw_ostream &EmitInteger(raw_ostream &o, int64_t value) {
+  o << "<integer>";
+  o << value;
+  o << "</integer>";
+  return o;
+}
+
+inline raw_ostream &EmitString(raw_ostream &o, StringRef s) {
+  o << "<string>";
+  for (StringRef::const_iterator I = s.begin(), E = s.end(); I != E; ++I) {
+    char c = *I;
+    switch (c) {
+    default:
+      o << c;
+      break;
+    case '&':
+      o << "&amp;";
+      break;
+    case '<':
+      o << "&lt;";
+      break;
+    case '>':
+      o << "&gt;";
+      break;
+    case '\'':
+      o << "&apos;";
+      break;
+    case '\"':
+      o << "&quot;";
+      break;
+    }
+  }
+  o << "</string>";
+  return o;
+}
+
+inline void EmitLocation(raw_ostream &o, const SourceManager &SM,
+                         const LangOptions &LangOpts, SourceLocation L,
+                         const FIDMap &FM, unsigned indent,
+                         bool extend = false) {
+  FullSourceLoc Loc(SM.getExpansionLoc(L), const_cast<SourceManager &>(SM));
+
+  // Add in the length of the token, so that we cover multi-char tokens.
+  unsigned offset =
+      extend ? Lexer::MeasureTokenLength(Loc, SM, LangOpts) - 1 : 0;
+
+  Indent(o, indent) << "<dict>\n";
+  Indent(o, indent) << " <key>line</key>";
+  EmitInteger(o, Loc.getExpansionLineNumber()) << '\n';
+  Indent(o, indent) << " <key>col</key>";
+  EmitInteger(o, Loc.getExpansionColumnNumber() + offset) << '\n';
+  Indent(o, indent) << " <key>file</key>";
+  EmitInteger(o, GetFID(FM, SM, Loc)) << '\n';
+  Indent(o, indent) << "</dict>\n";
+}
+
+inline void EmitRange(raw_ostream &o, const SourceManager &SM,
+                      const LangOptions &LangOpts, CharSourceRange R,
+                      const FIDMap &FM, unsigned indent) {
+  Indent(o, indent) << "<array>\n";
+  EmitLocation(o, SM, LangOpts, R.getBegin(), FM, indent + 1);
+  EmitLocation(o, SM, LangOpts, R.getEnd(), FM, indent + 1, R.isTokenRange());
+  Indent(o, indent) << "</array>\n";
+}
+}
+}
+
+#endif
diff --git a/include/clang/Basic/PrettyStackTrace.h b/include/clang/Basic/PrettyStackTrace.h
index 967d0d1..0e49295 100644
--- a/include/clang/Basic/PrettyStackTrace.h
+++ b/include/clang/Basic/PrettyStackTrace.h
@@ -31,7 +31,7 @@
   public:
     PrettyStackTraceLoc(SourceManager &sm, SourceLocation L, const char *Msg)
       : SM(sm), Loc(L), Message(Msg) {}
-    virtual void print(raw_ostream &OS) const;
+    void print(raw_ostream &OS) const override;
   };
 }
 
diff --git a/include/clang/Basic/Sanitizers.def b/include/clang/Basic/Sanitizers.def
index c9b31a3..0ef39bc 100644
--- a/include/clang/Basic/Sanitizers.def
+++ b/include/clang/Basic/Sanitizers.def
@@ -40,13 +40,6 @@
 
 // AddressSanitizer
 SANITIZER("address", Address)
-// More features of AddressSanitizer that should be turned on explicitly.
-SANITIZER("init-order", InitOrder)
-SANITIZER("use-after-return", UseAfterReturn)
-SANITIZER("use-after-scope", UseAfterScope)
-
-SANITIZER_GROUP("address-full", AddressFull,
-                Address | InitOrder | UseAfterReturn | UseAfterScope)
 
 // MemorySanitizer
 SANITIZER("memory", Memory)
@@ -89,7 +82,7 @@
                 ObjectSize | Return | Shift | SignedIntegerOverflow |
                 Unreachable | VLABound | Vptr)
 
-// -fsanitize=undefined-trap (and its alias -fcatch-undefined-behavior) includes
+// -fsanitize=undefined-trap includes
 // all sanitizers included by -fsanitize=undefined, except those that require
 // runtime support.  This group is generally used in conjunction with the
 // -fsanitize-undefined-trap-on-error flag.
@@ -103,7 +96,6 @@
                 SignedIntegerOverflow | UnsignedIntegerOverflow | Shift |
                 IntegerDivideByZero)
 
-// -fbounds-checking
 SANITIZER("local-bounds", LocalBounds)
 SANITIZER_GROUP("bounds", Bounds, ArrayBounds | LocalBounds)
 
diff --git a/include/clang/Basic/SourceLocation.h b/include/clang/Basic/SourceLocation.h
index 10ae07b..7b637d7 100644
--- a/include/clang/Basic/SourceLocation.h
+++ b/include/clang/Basic/SourceLocation.h
@@ -89,7 +89,7 @@
   friend class SourceManager;
   friend class ASTReader;
   friend class ASTWriter;
-  enum LLVM_ENUM_INT_TYPE(unsigned) {
+  enum : unsigned {
     MacroIDBit = 1U << 31
   };
 public:
@@ -172,7 +172,7 @@
   }
 
   void print(raw_ostream &OS, const SourceManager &SM) const;
-  LLVM_ATTRIBUTE_USED std::string printToString(const SourceManager &SM) const;
+  std::string printToString(const SourceManager &SM) const;
   void dump(const SourceManager &SM) const;
 };
 
@@ -188,7 +188,7 @@
   return LHS.getRawEncoding() < RHS.getRawEncoding();
 }
 
-/// \brief A trival tuple used to represent a source range.
+/// \brief A trivial tuple used to represent a source range.
 class SourceRange {
   SourceLocation B;
   SourceLocation E;
@@ -268,7 +268,7 @@
   const SourceManager *SrcMgr;
 public:
   /// \brief Creates a FullSourceLoc where isValid() returns \c false.
-  explicit FullSourceLoc() : SrcMgr(0) {}
+  explicit FullSourceLoc() : SrcMgr(nullptr) {}
 
   explicit FullSourceLoc(SourceLocation Loc, const SourceManager &SM)
     : SourceLocation(Loc), SrcMgr(&SM) {}
@@ -284,19 +284,19 @@
   FullSourceLoc getExpansionLoc() const;
   FullSourceLoc getSpellingLoc() const;
 
-  unsigned getExpansionLineNumber(bool *Invalid = 0) const;
-  unsigned getExpansionColumnNumber(bool *Invalid = 0) const;
+  unsigned getExpansionLineNumber(bool *Invalid = nullptr) const;
+  unsigned getExpansionColumnNumber(bool *Invalid = nullptr) const;
 
-  unsigned getSpellingLineNumber(bool *Invalid = 0) const;
-  unsigned getSpellingColumnNumber(bool *Invalid = 0) const;
+  unsigned getSpellingLineNumber(bool *Invalid = nullptr) const;
+  unsigned getSpellingColumnNumber(bool *Invalid = nullptr) const;
 
-  const char *getCharacterData(bool *Invalid = 0) const;
+  const char *getCharacterData(bool *Invalid = nullptr) const;
 
-  const llvm::MemoryBuffer* getBuffer(bool *Invalid = 0) const;
+  const llvm::MemoryBuffer* getBuffer(bool *Invalid = nullptr) const;
 
   /// \brief Return a StringRef to the source buffer data for the
   /// specified FileID.
-  StringRef getBufferData(bool *Invalid = 0) const;
+  StringRef getBufferData(bool *Invalid = nullptr) const;
 
   /// \brief Decompose the specified location into a raw FileID + Offset pair.
   ///
@@ -331,7 +331,7 @@
   /// \brief Prints information about this FullSourceLoc to stderr.
   ///
   /// This is useful for debugging.
-  LLVM_ATTRIBUTE_USED void dump() const;
+  void dump() const;
 
   friend inline bool
   operator==(const FullSourceLoc &LHS, const FullSourceLoc &RHS) {
@@ -358,7 +358,7 @@
   unsigned Line, Col;
   SourceLocation IncludeLoc;
 public:
-  PresumedLoc() : Filename(0) {}
+  PresumedLoc() : Filename(nullptr) {}
   PresumedLoc(const char *FN, unsigned Ln, unsigned Co, SourceLocation IL)
     : Filename(FN), Line(Ln), Col(Co), IncludeLoc(IL) {
   }
@@ -367,8 +367,8 @@
   ///
   /// This occurs when created with invalid source locations or when walking
   /// off the top of a \#include stack.
-  bool isInvalid() const { return Filename == 0; }
-  bool isValid() const { return Filename != 0; }
+  bool isInvalid() const { return Filename == nullptr; }
+  bool isValid() const { return Filename != nullptr; }
 
   /// \brief Return the presumed filename of this location.
   ///
diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h
index 6aab998..e567a7a 100644
--- a/include/clang/Basic/SourceManager.h
+++ b/include/clang/Basic/SourceManager.h
@@ -42,14 +42,15 @@
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/PointerIntPair.h"
 #include "llvm/ADT/PointerUnion.h"
+#include "llvm/Support/AlignOf.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/DataTypes.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include <cassert>
 #include <map>
+#include <memory>
 #include <vector>
 
 namespace clang {
@@ -89,12 +90,21 @@
       DoNotFreeFlag = 0x02
     };
 
+    // Note that the first member of this class is an aligned character buffer
+    // to ensure that this class has an alignment of 8 bytes. This wastes
+    // 8 bytes for every ContentCache object, but each of these corresponds to
+    // a file loaded into memory, so the 8 bytes doesn't seem terribly
+    // important. It is quite awkward to fit this aligner into any other part
+    // of the class due to the lack of portable ways to combine it with other
+    // members.
+    llvm::AlignedCharArray<8, 1> NonceAligner;
+
     /// \brief The actual buffer containing the characters from the input
     /// file.
     ///
     /// This is owned by the ContentCache object.  The bits indicate
     /// whether the buffer is invalid.
-    mutable llvm::PointerIntPair<const llvm::MemoryBuffer *, 2> Buffer;
+    mutable llvm::PointerIntPair<llvm::MemoryBuffer *, 2> Buffer;
 
   public:
     /// \brief Reference to the file entry representing this ContentCache.
@@ -133,14 +143,16 @@
     /// file considered as a system one.
     unsigned IsSystemFile : 1;
     
-    ContentCache(const FileEntry *Ent = 0)
-      : Buffer(0, false), OrigEntry(Ent), ContentsEntry(Ent),
-        SourceLineCache(0), NumLines(0), BufferOverridden(false),
-        IsSystemFile(false) {}
+    ContentCache(const FileEntry *Ent = nullptr)
+      : Buffer(nullptr, false), OrigEntry(Ent), ContentsEntry(Ent),
+        SourceLineCache(nullptr), NumLines(0), BufferOverridden(false),
+        IsSystemFile(false) {
+      (void)NonceAligner; // Silence warnings about unused member.
+    }
     
     ContentCache(const FileEntry *Ent, const FileEntry *contentEnt)
-      : Buffer(0, false), OrigEntry(Ent), ContentsEntry(contentEnt),
-        SourceLineCache(0), NumLines(0), BufferOverridden(false),
+      : Buffer(nullptr, false), OrigEntry(Ent), ContentsEntry(contentEnt),
+        SourceLineCache(nullptr), NumLines(0), BufferOverridden(false),
         IsSystemFile(false) {}
     
     ~ContentCache();
@@ -149,15 +161,15 @@
     /// a non-NULL Buffer or SourceLineCache.  Ownership of allocated memory
     /// is not transferred, so this is a logical error.
     ContentCache(const ContentCache &RHS)
-      : Buffer(0, false), SourceLineCache(0), BufferOverridden(false),
-        IsSystemFile(false)
-    {
+      : Buffer(nullptr, false), SourceLineCache(nullptr),
+        BufferOverridden(false), IsSystemFile(false) {
       OrigEntry = RHS.OrigEntry;
       ContentsEntry = RHS.ContentsEntry;
-      
-      assert (RHS.Buffer.getPointer() == 0 && RHS.SourceLineCache == 0 &&
-              "Passed ContentCache object cannot own a buffer.");
-      
+
+      assert(RHS.Buffer.getPointer() == nullptr &&
+             RHS.SourceLineCache == nullptr &&
+             "Passed ContentCache object cannot own a buffer.");
+
       NumLines = RHS.NumLines;
     }
 
@@ -170,10 +182,10 @@
     ///   will be emitted at.
     ///
     /// \param Invalid If non-NULL, will be set \c true if an error occurred.
-    const llvm::MemoryBuffer *getBuffer(DiagnosticsEngine &Diag,
-                                        const SourceManager &SM,
-                                        SourceLocation Loc = SourceLocation(),
-                                        bool *Invalid = 0) const;
+    llvm::MemoryBuffer *getBuffer(DiagnosticsEngine &Diag,
+                                  const SourceManager &SM,
+                                  SourceLocation Loc = SourceLocation(),
+                                  bool *Invalid = nullptr) const;
 
     /// \brief Returns the size of the content encapsulated by this
     /// ContentCache.
@@ -193,7 +205,7 @@
     /// this content cache.  This is used for performance analysis.
     llvm::MemoryBuffer::BufferKind getMemoryBufferKind() const;
 
-    void setBuffer(const llvm::MemoryBuffer *B) {
+    void setBuffer(llvm::MemoryBuffer *B) {
       assert(!Buffer.getPointer() && "MemoryBuffer already set.");
       Buffer.setPointer(B);
       Buffer.setInt(false);
@@ -201,13 +213,11 @@
 
     /// \brief Get the underlying buffer, returning NULL if the buffer is not
     /// yet available.
-    const llvm::MemoryBuffer *getRawBuffer() const {
-      return Buffer.getPointer();
-    }
+    llvm::MemoryBuffer *getRawBuffer() const { return Buffer.getPointer(); }
 
     /// \brief Replace the existing buffer (which will be deleted)
     /// with the given buffer.
-    void replaceBuffer(const llvm::MemoryBuffer *B, bool DoNotFree = false);
+    void replaceBuffer(llvm::MemoryBuffer *B, bool DoNotFree = false);
 
     /// \brief Determine whether the buffer itself is invalid.
     bool isBufferInvalid() const {
@@ -224,6 +234,11 @@
     ContentCache &operator=(const ContentCache& RHS) LLVM_DELETED_FUNCTION;
   };
 
+  // Assert that the \c ContentCache objects will always be 8-byte aligned so
+  // that we can pack 3 bits of integer into pointers to such objects.
+  static_assert(llvm::AlignOf<ContentCache>::Alignment >= 8,
+                "ContentCache must be 8-byte aligned.");
+
   /// \brief Information about a FileID, basically just the logical file
   /// that it represents and include stack information.
   ///
@@ -551,7 +566,7 @@
   /// non-null, FileEntry pointers.
   llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*> FileInfos;
 
-  /// \brief True if the ContentCache for files that are overriden by other
+  /// \brief True if the ContentCache for files that are overridden by other
   /// files, should report the original file name. Defaults to true.
   bool OverridenFilesKeepOriginalName;
 
@@ -560,7 +575,7 @@
   bool UserFilesAreVolatile;
 
   struct OverriddenFilesInfoTy {
-    /// \brief Files that have been overriden with the contents from another
+    /// \brief Files that have been overridden with the contents from another
     /// file.
     llvm::DenseMap<const FileEntry *, const FileEntry *> OverriddenFiles;
     /// \brief Files that were overridden with a memory buffer.
@@ -569,7 +584,7 @@
 
   /// \brief Lazily create the object keeping overridden files info, since
   /// it is uncommonly used.
-  OwningPtr<OverriddenFilesInfoTy> OverriddenFilesInfo;
+  std::unique_ptr<OverriddenFilesInfoTy> OverriddenFilesInfo;
 
   OverriddenFilesInfoTy &getOverriddenFilesInfo() {
     if (!OverriddenFilesInfo)
@@ -704,7 +719,8 @@
   FileManager &getFileManager() const { return FileMgr; }
 
   /// \brief Set true if the SourceManager should report the original file name
-  /// for contents of files that were overriden by other files.Defaults to true.
+  /// for contents of files that were overridden by other files. Defaults to
+  /// true.
   void setOverridenFilesKeepOriginalName(bool value) {
     OverridenFilesKeepOriginalName = value;
   }
@@ -729,18 +745,6 @@
     StoredModuleBuildStack.push_back(std::make_pair(moduleName.str(),importLoc));
   }
 
-  /// \brief Create the FileID for a memory buffer that will represent the
-  /// FileID for the main source.
-  ///
-  /// One example of when this would be used is when the main source is read
-  /// from STDIN.
-  FileID createMainFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer,
-                             SrcMgr::CharacteristicKind Kind = SrcMgr::C_User) {
-    assert(MainFileID.isInvalid() && "MainFileID already set!");
-    MainFileID = createFileIDForMemBuffer(Buffer, Kind);
-    return MainFileID;
-  }
-
   //===--------------------------------------------------------------------===//
   // MainFileID creation and querying methods.
   //===--------------------------------------------------------------------===//
@@ -748,14 +752,6 @@
   /// \brief Returns the FileID of the main source file.
   FileID getMainFileID() const { return MainFileID; }
 
-  /// \brief Create the FileID for the main source file.
-  FileID createMainFileID(const FileEntry *SourceFile, 
-                          SrcMgr::CharacteristicKind Kind = SrcMgr::C_User) {
-    assert(MainFileID.isInvalid() && "MainFileID already set!");
-    MainFileID = createFileID(SourceFile, SourceLocation(), Kind);
-    return MainFileID;
-  }
-
   /// \brief Set the file ID for the main source file.
   void setMainFileID(FileID FID) {
     assert(MainFileID.isInvalid() && "MainFileID already set!");
@@ -793,10 +789,10 @@
   ///
   /// This does no caching of the buffer and takes ownership of the
   /// MemoryBuffer, so only pass a MemoryBuffer to this once.
-  FileID createFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer,
+  FileID createFileID(llvm::MemoryBuffer *Buffer,
                       SrcMgr::CharacteristicKind FileCharacter = SrcMgr::C_User,
-                                  int LoadedID = 0, unsigned LoadedOffset = 0,
-                                 SourceLocation IncludeLoc = SourceLocation()) {
+                      int LoadedID = 0, unsigned LoadedOffset = 0,
+                      SourceLocation IncludeLoc = SourceLocation()) {
     return createFileID(createMemBufferContentCache(Buffer), IncludeLoc,
                         FileCharacter, LoadedID, LoadedOffset);
   }
@@ -823,13 +819,13 @@
   ///
   /// \param Invalid If non-NULL, will be set \c true if an error
   /// occurs while retrieving the memory buffer.
-  const llvm::MemoryBuffer *getMemoryBufferForFile(const FileEntry *File,
-                                                   bool *Invalid = 0);
+  llvm::MemoryBuffer *getMemoryBufferForFile(const FileEntry *File,
+                                             bool *Invalid = nullptr);
 
   /// \brief Override the contents of the given source file by providing an
   /// already-allocated buffer.
   ///
-  /// \param SourceFile the source file whose contents will be overriden.
+  /// \param SourceFile the source file whose contents will be overridden.
   ///
   /// \param Buffer the memory buffer whose contents will be used as the
   /// data in the given source file.
@@ -837,12 +833,11 @@
   /// \param DoNotFree If true, then the buffer will not be freed when the
   /// source manager is destroyed.
   void overrideFileContents(const FileEntry *SourceFile,
-                            const llvm::MemoryBuffer *Buffer,
-                            bool DoNotFree = false);
+                            llvm::MemoryBuffer *Buffer, bool DoNotFree = false);
 
   /// \brief Override the given source file with another one.
   ///
-  /// \param SourceFile the source file which will be overriden.
+  /// \param SourceFile the source file which will be overridden.
   ///
   /// \param NewFile the file whose contents will be used as the
   /// data instead of the contents of the given source file.
@@ -875,8 +870,8 @@
   ///
   /// If there is an error opening this buffer the first time, this
   /// manufactures a temporary buffer and returns a non-empty error string.
-  const llvm::MemoryBuffer *getBuffer(FileID FID, SourceLocation Loc,
-                                      bool *Invalid = 0) const {
+  llvm::MemoryBuffer *getBuffer(FileID FID, SourceLocation Loc,
+                                bool *Invalid = nullptr) const {
     bool MyInvalid = false;
     const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &MyInvalid);
     if (MyInvalid || !Entry.isFile()) {
@@ -890,7 +885,7 @@
                                                         Invalid);
   }
 
-  const llvm::MemoryBuffer *getBuffer(FileID FID, bool *Invalid = 0) const {
+  llvm::MemoryBuffer *getBuffer(FileID FID, bool *Invalid = nullptr) const {
     bool MyInvalid = false;
     const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &MyInvalid);
     if (MyInvalid || !Entry.isFile()) {
@@ -910,11 +905,11 @@
     bool MyInvalid = false;
     const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &MyInvalid);
     if (MyInvalid || !Entry.isFile())
-      return 0;
+      return nullptr;
 
     const SrcMgr::ContentCache *Content = Entry.getFile().getContentCache();
     if (!Content)
-      return 0;
+      return nullptr;
     return Content->OrigEntry;
   }
 
@@ -923,7 +918,7 @@
   {
     const SrcMgr::ContentCache *Content = sloc.getFile().getContentCache();
     if (!Content)
-      return 0;
+      return nullptr;
     return Content->OrigEntry;
   }
 
@@ -932,7 +927,7 @@
   ///
   /// \param FID The file ID whose contents will be returned.
   /// \param Invalid If non-NULL, will be set true if an error occurred.
-  StringRef getBufferData(FileID FID, bool *Invalid = 0) const;
+  StringRef getBufferData(FileID FID, bool *Invalid = nullptr) const;
 
   /// \brief Get the number of FileIDs (files and macros) that were created
   /// during preprocessing of \p FID, including it.
@@ -1167,15 +1162,16 @@
   /// \param MacroBegin If non-null and function returns true, it is set to the
   /// begin location of the immediate macro expansion.
   bool isAtStartOfImmediateMacroExpansion(SourceLocation Loc,
-                                          SourceLocation *MacroBegin = 0) const;
+                                    SourceLocation *MacroBegin = nullptr) const;
 
   /// \brief Returns true if the given MacroID location points at the character
   /// end of the immediate macro expansion.
   ///
   /// \param MacroEnd If non-null and function returns true, it is set to the
   /// character end location of the immediate macro expansion.
-  bool isAtEndOfImmediateMacroExpansion(SourceLocation Loc,
-                                        SourceLocation *MacroEnd = 0) const;
+  bool
+  isAtEndOfImmediateMacroExpansion(SourceLocation Loc,
+                                   SourceLocation *MacroEnd = nullptr) const;
 
   /// \brief Returns true if \p Loc is inside the [\p Start, +\p Length)
   /// chunk of the source location address space.
@@ -1184,7 +1180,7 @@
   /// relative offset of \p Loc inside the chunk.
   bool isInSLocAddrSpace(SourceLocation Loc,
                          SourceLocation Start, unsigned Length,
-                         unsigned *RelativeOffset = 0) const {
+                         unsigned *RelativeOffset = nullptr) const {
     assert(((Start.getOffset() < NextLocalOffset &&
                Start.getOffset()+Length <= NextLocalOffset) ||
             (Start.getOffset() >= CurrentLoadedOffset &&
@@ -1230,7 +1226,8 @@
   /// in the appropriate spelling MemoryBuffer.
   ///
   /// \param Invalid If non-NULL, will be set \c true if an error occurs.
-  const char *getCharacterData(SourceLocation SL, bool *Invalid = 0) const;
+  const char *getCharacterData(SourceLocation SL,
+                               bool *Invalid = nullptr) const;
 
   /// \brief Return the column # for the specified file position.
   ///
@@ -1239,12 +1236,13 @@
   /// on a file sloc, so you must choose a spelling or expansion location
   /// before calling this method.
   unsigned getColumnNumber(FileID FID, unsigned FilePos,
-                           bool *Invalid = 0) const;
-  unsigned getSpellingColumnNumber(SourceLocation Loc, bool *Invalid = 0) const;
+                           bool *Invalid = nullptr) const;
+  unsigned getSpellingColumnNumber(SourceLocation Loc,
+                                   bool *Invalid = nullptr) const;
   unsigned getExpansionColumnNumber(SourceLocation Loc,
-                                    bool *Invalid = 0) const;
-  unsigned getPresumedColumnNumber(SourceLocation Loc, bool *Invalid = 0) const;
-
+                                    bool *Invalid = nullptr) const;
+  unsigned getPresumedColumnNumber(SourceLocation Loc,
+                                   bool *Invalid = nullptr) const;
 
   /// \brief Given a SourceLocation, return the spelling line number
   /// for the position indicated.
@@ -1252,17 +1250,17 @@
   /// This requires building and caching a table of line offsets for the
   /// MemoryBuffer, so this is not cheap: use only when about to emit a
   /// diagnostic.
-  unsigned getLineNumber(FileID FID, unsigned FilePos, bool *Invalid = 0) const;
-  unsigned getSpellingLineNumber(SourceLocation Loc, bool *Invalid = 0) const;
-  unsigned getExpansionLineNumber(SourceLocation Loc, bool *Invalid = 0) const;
-  unsigned getPresumedLineNumber(SourceLocation Loc, bool *Invalid = 0) const;
+  unsigned getLineNumber(FileID FID, unsigned FilePos, bool *Invalid = nullptr) const;
+  unsigned getSpellingLineNumber(SourceLocation Loc, bool *Invalid = nullptr) const;
+  unsigned getExpansionLineNumber(SourceLocation Loc, bool *Invalid = nullptr) const;
+  unsigned getPresumedLineNumber(SourceLocation Loc, bool *Invalid = nullptr) const;
 
   /// \brief Return the filename or buffer identifier of the buffer the
   /// location is in.
   ///
   /// Note that this name does not respect \#line directives.  Use
   /// getPresumedLoc for normal clients.
-  const char *getBufferName(SourceLocation Loc, bool *Invalid = 0) const;
+  const char *getBufferName(SourceLocation Loc, bool *Invalid = nullptr) const;
 
   /// \brief Return the file characteristic of the specified source
   /// location, indicating whether this is a normal file, a system
@@ -1286,7 +1284,7 @@
   /// an expansion location, not at the spelling location.
   ///
   /// \returns The presumed location of the specified SourceLocation. If the
-  /// presumed location cannot be calculate (e.g., because \p Loc is invalid
+  /// presumed location cannot be calculated (e.g., because \p Loc is invalid
   /// or the file containing \p Loc has changed on disk), returns an invalid
   /// presumed location.
   PresumedLoc getPresumedLoc(SourceLocation Loc,
@@ -1332,14 +1330,14 @@
     return loc.isMacroID() && isInSystemHeader(getSpellingLoc(loc));
   }
 
-  /// \brief The size of the SLocEnty that \p FID represents.
+  /// \brief The size of the SLocEntry that \p FID represents.
   unsigned getFileIDSize(FileID FID) const;
 
   /// \brief Given a specific FileID, returns true if \p Loc is inside that
   /// FileID chunk and sets relative offset (offset of \p Loc from beginning
   /// of FileID) to \p relativeOffset.
   bool isInFileID(SourceLocation Loc, FileID FID,
-                  unsigned *RelativeOffset = 0) const {
+                  unsigned *RelativeOffset = nullptr) const {
     unsigned Offs = Loc.getOffset();
     if (isOffsetInFileID(FID, Offs)) {
       if (RelativeOffset)
@@ -1368,7 +1366,7 @@
                    bool IsSystemHeader, bool IsExternCHeader);
 
   /// \brief Determine if the source manager has a line table.
-  bool hasLineTable() const { return LineTable != 0; }
+  bool hasLineTable() const { return LineTable != nullptr; }
 
   /// \brief Retrieve the stored line table.
   LineTableInfo &getLineTable();
@@ -1475,7 +1473,7 @@
 
   /// \brief Get a local SLocEntry. This is exposed for indexing.
   const SrcMgr::SLocEntry &getLocalSLocEntry(unsigned Index,
-                                             bool *Invalid = 0) const {
+                                             bool *Invalid = nullptr) const {
     assert(Index < LocalSLocEntryTable.size() && "Invalid index");
     return LocalSLocEntryTable[Index];
   }
@@ -1485,14 +1483,15 @@
 
   /// \brief Get a loaded SLocEntry. This is exposed for indexing.
   const SrcMgr::SLocEntry &getLoadedSLocEntry(unsigned Index,
-                                              bool *Invalid = 0) const {
+                                              bool *Invalid = nullptr) const {
     assert(Index < LoadedSLocEntryTable.size() && "Invalid index");
     if (SLocEntryLoaded[Index])
       return LoadedSLocEntryTable[Index];
     return loadSLocEntry(Index, Invalid);
   }
 
-  const SrcMgr::SLocEntry &getSLocEntry(FileID FID, bool *Invalid = 0) const {
+  const SrcMgr::SLocEntry &getSLocEntry(FileID FID,
+                                        bool *Invalid = nullptr) const {
     if (FID.ID == 0 || FID.ID == -1) {
       if (Invalid) *Invalid = true;
       return LocalSLocEntryTable[0];
@@ -1555,21 +1554,22 @@
   }
 
 private:
-  const llvm::MemoryBuffer *getFakeBufferForRecovery() const;
+  llvm::MemoryBuffer *getFakeBufferForRecovery() const;
   const SrcMgr::ContentCache *getFakeContentCacheForRecovery() const;
 
   const SrcMgr::SLocEntry &loadSLocEntry(unsigned Index, bool *Invalid) const;
 
   /// \brief Get the entry with the given unwrapped FileID.
-  const SrcMgr::SLocEntry &getSLocEntryByID(int ID, bool *Invalid = 0) const {
+  const SrcMgr::SLocEntry &getSLocEntryByID(int ID,
+                                            bool *Invalid = nullptr) const {
     assert(ID != -1 && "Using FileID sentinel value");
     if (ID < 0)
       return getLoadedSLocEntryByID(ID, Invalid);
     return getLocalSLocEntry(static_cast<unsigned>(ID), Invalid);
   }
 
-  const SrcMgr::SLocEntry &getLoadedSLocEntryByID(int ID,
-                                                  bool *Invalid = 0) const {
+  const SrcMgr::SLocEntry &
+  getLoadedSLocEntryByID(int ID, bool *Invalid = nullptr) const {
     return getLoadedSLocEntry(static_cast<unsigned>(-ID - 2), Invalid);
   }
 
@@ -1623,8 +1623,8 @@
                             bool isSystemFile = false);
 
   /// \brief Create a new ContentCache for the specified  memory buffer.
-  const SrcMgr::ContentCache*
-  createMemBufferContentCache(const llvm::MemoryBuffer *Buf);
+  const SrcMgr::ContentCache *
+  createMemBufferContentCache(llvm::MemoryBuffer *Buf);
 
   FileID getFileIDSlow(unsigned SLocOffset) const;
   FileID getFileIDLocal(unsigned SLocOffset) const;
diff --git a/include/clang/Basic/Specifiers.h b/include/clang/Basic/Specifiers.h
index 0b80939..f895673 100644
--- a/include/clang/Basic/Specifiers.h
+++ b/include/clang/Basic/Specifiers.h
@@ -63,21 +63,13 @@
     TST_decltype_auto,    // C++1y decltype(auto)
     TST_unknown_anytype,  // __unknown_anytype extension
     TST_atomic,           // C11 _Atomic
-    TST_image1d_t,        // OpenCL image1d_t
-    TST_image1d_array_t,  // OpenCL image1d_array_t
-    TST_image1d_buffer_t, // OpenCL image1d_buffer_t
-    TST_image2d_t,        // OpenCL image2d_t
-    TST_image2d_array_t,  // OpenCL image2d_array_t
-    TST_image3d_t,        // OpenCL image3d_t
-    TST_sampler_t,        // OpenCL sampler_t
-    TST_event_t,          // OpenCL event_t
     TST_error         // erroneous type
   };
   
   /// \brief Structure that packs information about the type specifiers that
   /// were written in a particular type specifier sequence.
   struct WrittenBuiltinSpecs {
-    /*DeclSpec::TST*/ unsigned Type  : 6;
+    /*DeclSpec::TST*/ unsigned Type  : 5;
     /*DeclSpec::TSS*/ unsigned Sign  : 2;
     /*DeclSpec::TSW*/ unsigned Width : 2;
     bool ModeAttr : 1;
diff --git a/include/clang/Basic/StmtNodes.td b/include/clang/Basic/StmtNodes.td
index 69851a9..d980648 100644
--- a/include/clang/Basic/StmtNodes.td
+++ b/include/clang/Basic/StmtNodes.td
@@ -115,8 +115,6 @@
 def CXXDeleteExpr : DStmt<Expr>;
 def CXXPseudoDestructorExpr : DStmt<Expr>;
 def TypeTraitExpr : DStmt<Expr>;
-def UnaryTypeTraitExpr : DStmt<Expr>;
-def BinaryTypeTraitExpr : DStmt<Expr>;
 def ArrayTypeTraitExpr : DStmt<Expr>;
 def ExpressionTraitExpr : DStmt<Expr>;
 def DependentScopeDeclRefExpr : DStmt<Expr>;
@@ -172,6 +170,7 @@
 def SEHTryStmt : Stmt;
 def SEHExceptStmt : Stmt;
 def SEHFinallyStmt : Stmt;
+def SEHLeaveStmt : Stmt;
 def MSDependentExistsStmt : Stmt;
 
 // OpenCL Extensions.
@@ -180,3 +179,17 @@
 // OpenMP Directives.
 def OMPExecutableDirective : Stmt<1>;
 def OMPParallelDirective : DStmt<OMPExecutableDirective>;
+def OMPSimdDirective : DStmt<OMPExecutableDirective>;
+def OMPForDirective : DStmt<OMPExecutableDirective>;
+def OMPSectionsDirective : DStmt<OMPExecutableDirective>;
+def OMPSectionDirective : DStmt<OMPExecutableDirective>;
+def OMPSingleDirective : DStmt<OMPExecutableDirective>;
+def OMPMasterDirective : DStmt<OMPExecutableDirective>;
+def OMPCriticalDirective : DStmt<OMPExecutableDirective>;
+def OMPParallelForDirective : DStmt<OMPExecutableDirective>;
+def OMPParallelSectionsDirective : DStmt<OMPExecutableDirective>;
+def OMPTaskDirective : DStmt<OMPExecutableDirective>;
+def OMPTaskyieldDirective : DStmt<OMPExecutableDirective>;
+def OMPBarrierDirective : DStmt<OMPExecutableDirective>;
+def OMPTaskwaitDirective : DStmt<OMPExecutableDirective>;
+def OMPFlushDirective : DStmt<OMPExecutableDirective>;
diff --git a/include/clang/Basic/TargetBuiltins.h b/include/clang/Basic/TargetBuiltins.h
index ed3cc49..b1652be 100644
--- a/include/clang/Basic/TargetBuiltins.h
+++ b/include/clang/Basic/TargetBuiltins.h
@@ -1,4 +1,4 @@
-//===--- TargetBuiltins.h - Target specific builtin IDs -------------------===//
+//===--- TargetBuiltins.h - Target specific builtin IDs ---------*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -21,25 +21,37 @@
 
 namespace clang {
 
-  /// \brief AArch64 builtins
-  namespace AArch64 {
-    enum {
-      LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
+  namespace NEON {
+  enum {
+    LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
 #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
-#include "clang/Basic/BuiltinsAArch64.def"
-      LastTSBuiltin
-    };
+#include "clang/Basic/BuiltinsNEON.def"
+    FirstTSBuiltin
+  };
   }
+
   /// \brief ARM builtins
   namespace ARM {
     enum {
-        LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
+      LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
+      LastNEONBuiltin = NEON::FirstTSBuiltin - 1,
 #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
 #include "clang/Basic/BuiltinsARM.def"
-        LastTSBuiltin
+      LastTSBuiltin
     };
   }
 
+  /// \brief AArch64 builtins
+  namespace AArch64 {
+  enum {
+    LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
+    LastNEONBuiltin = NEON::FirstTSBuiltin - 1,
+  #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+  #include "clang/Basic/BuiltinsAArch64.def"
+    LastTSBuiltin
+  };
+  }
+
   /// \brief PPC builtins
   namespace PPC {
     enum {
@@ -60,6 +72,15 @@
     };
   }
 
+  /// \brief R600 builtins
+  namespace R600 {
+  enum {
+    LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
+  #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
+  #include "clang/Basic/BuiltinsR600.def"
+    LastTSBuiltin
+  };
+  }
 
   /// \brief X86 builtins
   namespace X86 {
@@ -91,6 +112,7 @@
       Poly8,
       Poly16,
       Poly64,
+      Poly128,
       Float16,
       Float32,
       Float64
diff --git a/include/clang/Basic/TargetCXXABI.h b/include/clang/Basic/TargetCXXABI.h
index 40aef2c..43978f5 100644
--- a/include/clang/Basic/TargetCXXABI.h
+++ b/include/clang/Basic/TargetCXXABI.h
@@ -63,6 +63,14 @@
     ///   - constructor/destructor signatures.
     iOS,
 
+    /// The iOS 64-bit ABI is follows ARM's published 64-bit ABI more
+    /// closely, but we don't guarantee to follow it perfectly.
+    ///
+    /// It is documented here:
+    ///    http://infocenter.arm.com
+    ///                  /help/topic/com.arm.doc.ihi0059a/IHI0059A_cppabi64.pdf
+    iOS64,
+
     /// The generic AArch64 ABI is also a modified version of the Itanium ABI,
     /// but it has fewer divergences than the 32-bit ARM ABI.
     ///
@@ -110,6 +118,7 @@
     case GenericARM:
     case Emscripten:
     case iOS:
+    case iOS64:
       return true;
 
     case Microsoft:
@@ -126,6 +135,7 @@
     case GenericARM:
     case Emscripten:
     case iOS:
+    case iOS64:
       return false;
 
     case Microsoft:
@@ -146,6 +156,7 @@
       return false;
     case GenericItanium:
     case iOS:
+    case iOS64:
     case Microsoft:
       return true;
     }
@@ -159,14 +170,14 @@
     return !isMicrosoft();
   }
 
-  /// Are temporary objects passed by value to a call destroyed by the callee?
+  /// Are arguments to a call destroyed left to right in the callee?
   /// This is a fundamental language change, since it implies that objects
   /// passed by value do *not* live to the end of the full expression.
   /// Temporaries passed to a function taking a const reference live to the end
   /// of the full expression as usual.  Both the caller and the callee must
   /// have access to the destructor, while only the caller needs the
   /// destructor if this is false.
-  bool isArgumentDestroyedByCallee() const {
+  bool areArgsDestroyedLeftToRightInCallee() const {
     return isMicrosoft();
   }
 
@@ -219,6 +230,7 @@
   bool canKeyFunctionBeInline() const {
     switch (getKind()) {
     case GenericARM:
+    case iOS64:
       return false;
 
     case GenericAArch64:
@@ -255,7 +267,7 @@
 
     /// Only allocate objects in the tail padding of a base class if
     /// the base class is not POD according to the rules of C++ TR1.
-    /// This is non strictly conforming in C++11 mode.
+    /// This is non-strictly conforming in C++11 mode.
     UseTailPaddingUnlessPOD03,
 
     /// Only allocate objects in the tail padding of a base class if
@@ -274,6 +286,11 @@
     case iOS:
       return UseTailPaddingUnlessPOD03;
 
+    // iOS on ARM64 uses the C++11 POD rules.  It does not honor the
+    // Itanium exception about classes with over-large bitfields.
+    case iOS64:
+      return UseTailPaddingUnlessPOD11;
+
     // MSVC always allocates fields in the tail-padding of a base class
     // subobject, even if they're POD.
     case Microsoft:
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
index 047872d..edef7c0 100644
--- a/include/clang/Basic/TargetInfo.h
+++ b/include/clang/Basic/TargetInfo.h
@@ -16,9 +16,9 @@
 #define LLVM_CLANG_BASIC_TARGETINFO_H
 
 #include "clang/Basic/AddressSpaces.h"
-#include "clang/Basic/TargetCXXABI.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/Specifiers.h"
+#include "clang/Basic/TargetCXXABI.h"
 #include "clang/Basic/TargetOptions.h"
 #include "clang/Basic/VersionTuple.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
@@ -47,7 +47,7 @@
 /// \brief Exposes information about the current target.
 ///
 class TargetInfo : public RefCountedBase<TargetInfo> {
-  IntrusiveRefCntPtr<TargetOptions> TargetOpts;
+  std::shared_ptr<TargetOptions> TargetOpts;
   llvm::Triple Triple;
 protected:
   // Target values set by the ctor of the actual target implementation.  Default
@@ -94,8 +94,9 @@
   /// \param Opts - The options to use to initialize the target. The target may
   /// modify the options to canonicalize the target feature information to match
   /// what the backend expects.
-  static TargetInfo* CreateTargetInfo(DiagnosticsEngine &Diags,
-                                      TargetOptions *Opts);
+  static TargetInfo *
+  CreateTargetInfo(DiagnosticsEngine &Diags,
+                   const std::shared_ptr<TargetOptions> &Opts);
 
   virtual ~TargetInfo();
 
@@ -105,10 +106,6 @@
     return *TargetOpts; 
   }
 
-  void setTargetOpts(TargetOptions *TargetOpts) {
-    this->TargetOpts = TargetOpts;
-  }
-
   ///===---- Target Data Type Query Methods -------------------------------===//
   enum IntType {
     NoInt = 0,
@@ -173,7 +170,7 @@
   };
 
 protected:
-  IntType SizeType, IntMaxType, UIntMaxType, PtrDiffType, IntPtrType, WCharType,
+  IntType SizeType, IntMaxType, PtrDiffType, IntPtrType, WCharType,
           WIntType, Char16Type, Char32Type, Int64Type, SigAtomicType,
           ProcessIDType;
 
@@ -209,19 +206,44 @@
 public:
   IntType getSizeType() const { return SizeType; }
   IntType getIntMaxType() const { return IntMaxType; }
-  IntType getUIntMaxType() const { return UIntMaxType; }
+  IntType getUIntMaxType() const {
+    return getCorrespondingUnsignedType(IntMaxType);
+  }
   IntType getPtrDiffType(unsigned AddrSpace) const {
     return AddrSpace == 0 ? PtrDiffType : getPtrDiffTypeV(AddrSpace);
   }
   IntType getIntPtrType() const { return IntPtrType; }
+  IntType getUIntPtrType() const {
+    return getCorrespondingUnsignedType(IntPtrType);
+  }
   IntType getWCharType() const { return WCharType; }
   IntType getWIntType() const { return WIntType; }
   IntType getChar16Type() const { return Char16Type; }
   IntType getChar32Type() const { return Char32Type; }
   IntType getInt64Type() const { return Int64Type; }
+  IntType getUInt64Type() const {
+    return getCorrespondingUnsignedType(Int64Type);
+  }
   IntType getSigAtomicType() const { return SigAtomicType; }
   IntType getProcessIDType() const { return ProcessIDType; }
 
+  static IntType getCorrespondingUnsignedType(IntType T) {
+    switch (T) {
+    case SignedChar:
+      return UnsignedChar;
+    case SignedShort:
+      return UnsignedShort;
+    case SignedInt:
+      return UnsignedInt;
+    case SignedLong:
+      return UnsignedLong;
+    case SignedLongLong:
+      return UnsignedLongLong;
+    default:
+      llvm_unreachable("Unexpected signed integer type");
+    }
+  }
+
   /// \brief Return the width (in bits) of the specified integer type enum.
   ///
   /// For example, SignedInt -> getIntWidth().
@@ -230,6 +252,9 @@
   /// \brief Return integer type with specified width.
   IntType getIntTypeByWidth(unsigned BitWidth, bool IsSigned) const;
 
+  /// \brief Return the smallest integer type with at least the specified width.
+  IntType getLeastIntTypeByWidth(unsigned BitWidth, bool IsSigned) const;
+
   /// \brief Return floating point type with specified width.
   RealType getRealTypeByWidth(unsigned BitWidth) const;
 
@@ -283,7 +308,7 @@
   unsigned getLongLongAlign() const { return LongLongAlign; }
 
   /// \brief Determine whether the __int128 type is supported on this target.
-  bool hasInt128Type() const { return getPointerWidth(0) >= 64; } // FIXME
+  virtual bool hasInt128Type() const { return getPointerWidth(0) >= 64; } // FIXME
 
   /// \brief Return the alignment that is suitable for storing any
   /// object with a fundamental alignment requirement.
@@ -421,7 +446,13 @@
   /// \brief Return the constant suffix for the specified integer type enum.
   ///
   /// For example, SignedLong -> "L".
-  static const char *getTypeConstantSuffix(IntType T);
+  const char *getTypeConstantSuffix(IntType T) const;
+
+  /// \brief Return the printf format modifier for the specified
+  /// integer type enum.
+  ///
+  /// For example, SignedLong -> "l".
+  static const char *getTypeFormatModifier(IntType T);
 
   /// \brief Check whether the given real type should use the "fpret" flavor of
   /// Objective-C message passing on this target.
@@ -579,6 +610,7 @@
   }
 
   const char *getTargetDescription() const {
+    assert(DescriptionString);
     return DescriptionString;
   }
 
@@ -604,24 +636,6 @@
   /// either; the entire thing is pretty badly mangled.
   virtual bool hasProtectedVisibility() const { return true; }
 
-  /// \brief Return the section to use for CFString literals, or 0 if no
-  /// special section is used.
-  virtual const char *getCFStringSection() const {
-    return "__DATA,__cfstring";
-  }
-
-  /// \brief Return the section to use for NSString literals, or 0 if no
-  /// special section is used.
-  virtual const char *getNSStringSection() const {
-    return "__OBJC,__cstring_object,regular,no_dead_strip";
-  }
-
-  /// \brief Return the section to use for NSString literals, or 0 if no
-  /// special section is used (NonFragile ABI).
-  virtual const char *getNSStringNonFragileABISection() const {
-    return "__DATA, __objc_stringobj, regular, no_dead_strip";
-  }
-
   /// \brief An optional hook that targets can implement to perform semantic
   /// checking on attribute((section("foo"))) specifiers.
   ///
@@ -641,7 +655,7 @@
   ///
   /// Apply changes to the target information with respect to certain
   /// language options which change the target configuration.
-  virtual void setForcedLangOptions(LangOptions &Opts);
+  virtual void adjust(const LangOptions &Opts);
 
   /// \brief Get the default set of target features for the CPU;
   /// this should include all legal feature strings on the target.
@@ -649,9 +663,7 @@
   }
 
   /// \brief Get the ABI currently in use.
-  virtual const char *getABI() const {
-    return "";
-  }
+  virtual StringRef getABI() const { return StringRef(); }
 
   /// \brief Get the C++ ABI currently in use.
   TargetCXXABI getCXXABI() const {
@@ -752,7 +764,7 @@
 
   /// \brief Return the section to use for C++ static initialization functions.
   virtual const char *getStaticInitSectionSpecifier() const {
-    return 0;
+    return nullptr;
   }
 
   const LangAS::Map &getAddressSpaceMap() const {
@@ -818,7 +830,7 @@
                                 unsigned &NumAliases) const = 0;
   virtual void getGCCAddlRegNames(const AddlRegName *&Addl,
                                   unsigned &NumAddl) const {
-    Addl = 0;
+    Addl = nullptr;
     NumAddl = 0;
   }
   virtual bool validateAsmConstraint(const char *&Name,
diff --git a/include/clang/Basic/TargetOptions.h b/include/clang/Basic/TargetOptions.h
index 9909182..2c86c31 100644
--- a/include/clang/Basic/TargetOptions.h
+++ b/include/clang/Basic/TargetOptions.h
@@ -15,15 +15,13 @@
 #ifndef LLVM_CLANG_FRONTEND_TARGETOPTIONS_H
 #define LLVM_CLANG_FRONTEND_TARGETOPTIONS_H
 
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
 #include <string>
 #include <vector>
 
 namespace clang {
 
 /// \brief Options for controlling the target.
-class TargetOptions : public RefCountedBase<TargetOptions> {
+class TargetOptions {
 public:
   /// If given, the name of the target triple to compile for. If not given the
   /// target will be selected to match the host.
@@ -38,10 +36,6 @@
   /// If given, the name of the target ABI to use.
   std::string ABI;
 
-  /// If given, the name of the target C++ ABI to use. If not given, defaults
-  /// to "itanium".
-  std::string CXXABI;
-
   /// If given, the version string of the linker in use.
   std::string LinkerVersion;
 
diff --git a/include/clang/Basic/TemplateKinds.h b/include/clang/Basic/TemplateKinds.h
index c521893..b730143 100644
--- a/include/clang/Basic/TemplateKinds.h
+++ b/include/clang/Basic/TemplateKinds.h
@@ -17,6 +17,7 @@
 namespace clang {
 
 /// \brief Specifies the kind of template name that an identifier refers to.
+/// Be careful when changing this: this enumeration is used in diagnostics.
 enum TemplateNameKind {
   /// The name does not refer to a template.
   TNK_Non_template = 0,
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
index 6812cce..5d08833 100644
--- a/include/clang/Basic/TokenKinds.def
+++ b/include/clang/Basic/TokenKinds.def
@@ -23,6 +23,18 @@
 #ifndef KEYWORD
 #define KEYWORD(X,Y) TOK(kw_ ## X)
 #endif
+#ifndef TYPE_TRAIT
+#define TYPE_TRAIT(N,I,K) KEYWORD(I,K)
+#endif
+#ifndef TYPE_TRAIT_1
+#define TYPE_TRAIT_1(I,E,K) TYPE_TRAIT(1,I,K)
+#endif
+#ifndef TYPE_TRAIT_2
+#define TYPE_TRAIT_2(I,E,K) TYPE_TRAIT(2,I,K)
+#endif
+#ifndef TYPE_TRAIT_N
+#define TYPE_TRAIT_N(I,E,K) TYPE_TRAIT(0,I,K)
+#endif
 #ifndef ALIAS
 #define ALIAS(X,Y,Z)
 #endif
@@ -217,6 +229,7 @@
 //   KEYALTIVEC - This is a keyword in AltiVec
 //   KEYBORLAND - This is a keyword if Borland extensions are enabled
 //   BOOLSUPPORT - This is a keyword if 'bool' is a built-in type
+//   HALFSUPPORT - This is a keyword if 'half' is a built-in type
 //   WCHARSUPPORT - This is a keyword if 'wchar_t' is a built-in type
 //
 KEYWORD(auto                        , KEYALL)
@@ -255,7 +268,7 @@
 KEYWORD(while                       , KEYALL)
 KEYWORD(_Alignas                    , KEYALL)
 KEYWORD(_Alignof                    , KEYALL)
-KEYWORD(_Atomic                     , KEYALL)
+KEYWORD(_Atomic                     , KEYALL|KEYNOMS)
 KEYWORD(_Bool                       , KEYNOCXX)
 KEYWORD(_Complex                    , KEYALL)
 KEYWORD(_Generic                    , KEYALL)
@@ -284,7 +297,7 @@
 KEYWORD(namespace                   , KEYCXX)
 KEYWORD(new                         , KEYCXX)
 KEYWORD(operator                    , KEYCXX)
-KEYWORD(private                     , KEYCXX|KEYOPENCL)
+KEYWORD(private                     , KEYCXX)
 KEYWORD(protected                   , KEYCXX)
 KEYWORD(public                      , KEYCXX)
 KEYWORD(reinterpret_cast            , KEYCXX)
@@ -334,7 +347,9 @@
 KEYWORD(__attribute                 , KEYALL)
 KEYWORD(__builtin_choose_expr       , KEYALL)
 KEYWORD(__builtin_offsetof          , KEYALL)
-KEYWORD(__builtin_types_compatible_p, KEYALL)
+// __builtin_types_compatible_p is a GNU C extension that we handle like a C++
+// type trait.
+TYPE_TRAIT_2(__builtin_types_compatible_p, TypeCompatible, KEYNOCXX)
 KEYWORD(__builtin_va_arg            , KEYALL)
 KEYWORD(__extension__               , KEYALL)
 KEYWORD(__imag                      , KEYALL)
@@ -350,43 +365,51 @@
 
 // MS Extensions
 KEYWORD(__FUNCDNAME__               , KEYMS)
+KEYWORD(__FUNCSIG__                 , KEYMS)
 KEYWORD(L__FUNCTION__               , KEYMS)
-KEYWORD(__is_interface_class        , KEYMS)
-KEYWORD(__is_sealed                 , KEYMS)
+TYPE_TRAIT_1(__is_interface_class, IsInterfaceClass, KEYMS)
+TYPE_TRAIT_1(__is_sealed, IsSealed, KEYMS)
+
+// MSVC12.0 / VS2013 Type Traits
+TYPE_TRAIT_1(__is_destructible, IsDestructible, KEYMS)
+TYPE_TRAIT_1(__is_nothrow_destructible, IsNothrowDestructible, KEYMS)
+TYPE_TRAIT_2(__is_nothrow_assignable, IsNothrowAssignable, KEYCXX)
+TYPE_TRAIT_N(__is_constructible, IsConstructible, KEYCXX)
+TYPE_TRAIT_N(__is_nothrow_constructible, IsNothrowConstructible, KEYCXX)
 
 // GNU and MS Type Traits
-KEYWORD(__has_nothrow_assign          , KEYCXX)
-KEYWORD(__has_nothrow_move_assign     , KEYCXX)
-KEYWORD(__has_nothrow_copy            , KEYCXX)
-KEYWORD(__has_nothrow_constructor     , KEYCXX)
-KEYWORD(__has_trivial_assign          , KEYCXX)
-KEYWORD(__has_trivial_move_assign     , KEYCXX)
-KEYWORD(__has_trivial_copy            , KEYCXX)
-KEYWORD(__has_trivial_constructor     , KEYCXX)
-KEYWORD(__has_trivial_move_constructor, KEYCXX)
-KEYWORD(__has_trivial_destructor      , KEYCXX)
-KEYWORD(__has_virtual_destructor      , KEYCXX)
-KEYWORD(__is_abstract                 , KEYCXX)
-KEYWORD(__is_base_of                  , KEYCXX)
-KEYWORD(__is_class                    , KEYCXX)
-KEYWORD(__is_convertible_to           , KEYCXX)
-KEYWORD(__is_empty                    , KEYCXX)
-KEYWORD(__is_enum                     , KEYCXX)
-KEYWORD(__is_final                    , KEYCXX)
+TYPE_TRAIT_1(__has_nothrow_assign, HasNothrowAssign, KEYCXX)
+TYPE_TRAIT_1(__has_nothrow_move_assign, HasNothrowMoveAssign, KEYCXX)
+TYPE_TRAIT_1(__has_nothrow_copy, HasNothrowCopy, KEYCXX)
+TYPE_TRAIT_1(__has_nothrow_constructor, HasNothrowConstructor, KEYCXX)
+TYPE_TRAIT_1(__has_trivial_assign, HasTrivialAssign, KEYCXX)
+TYPE_TRAIT_1(__has_trivial_move_assign, HasTrivialMoveAssign, KEYCXX)
+TYPE_TRAIT_1(__has_trivial_copy, HasTrivialCopy, KEYCXX)
+TYPE_TRAIT_1(__has_trivial_constructor, HasTrivialDefaultConstructor, KEYCXX)
+TYPE_TRAIT_1(__has_trivial_move_constructor, HasTrivialMoveConstructor, KEYCXX)
+TYPE_TRAIT_1(__has_trivial_destructor, HasTrivialDestructor, KEYCXX)
+TYPE_TRAIT_1(__has_virtual_destructor, HasVirtualDestructor, KEYCXX)
+TYPE_TRAIT_1(__is_abstract, IsAbstract, KEYCXX)
+TYPE_TRAIT_2(__is_base_of, IsBaseOf, KEYCXX)
+TYPE_TRAIT_1(__is_class, IsClass, KEYCXX)
+TYPE_TRAIT_2(__is_convertible_to, IsConvertibleTo, KEYCXX)
+TYPE_TRAIT_1(__is_empty, IsEmpty, KEYCXX)
+TYPE_TRAIT_1(__is_enum, IsEnum, KEYCXX)
+TYPE_TRAIT_1(__is_final, IsFinal, KEYCXX)
 // Tentative name - there's no implementation of std::is_literal_type yet.
-KEYWORD(__is_literal                  , KEYCXX)
+TYPE_TRAIT_1(__is_literal, IsLiteral, KEYCXX)
 // Name for GCC 4.6 compatibility - people have already written libraries using
 // this name unfortunately.
-KEYWORD(__is_literal_type             , KEYCXX)
-KEYWORD(__is_pod                      , KEYCXX)
-KEYWORD(__is_polymorphic              , KEYCXX)
-KEYWORD(__is_trivial                  , KEYCXX)
-KEYWORD(__is_union                    , KEYCXX)
+ALIAS("__is_literal_type", __is_literal, KEYCXX)
+TYPE_TRAIT_1(__is_pod, IsPOD, KEYCXX)
+TYPE_TRAIT_1(__is_polymorphic, IsPolymorphic, KEYCXX)
+TYPE_TRAIT_1(__is_trivial, IsTrivial, KEYCXX)
+TYPE_TRAIT_1(__is_union, IsUnion, KEYCXX)
 
 // Clang-only C++ Type Traits
-KEYWORD(__is_trivially_constructible, KEYCXX)
-KEYWORD(__is_trivially_copyable     , KEYCXX)
-KEYWORD(__is_trivially_assignable   , KEYCXX)
+TYPE_TRAIT_N(__is_trivially_constructible, IsTriviallyConstructible, KEYCXX)
+TYPE_TRAIT_1(__is_trivially_copyable, IsTriviallyCopyable, KEYCXX)
+TYPE_TRAIT_2(__is_trivially_assignable, IsTriviallyAssignable, KEYCXX)
 KEYWORD(__underlying_type           , KEYCXX)
 
 // Embarcadero Expression Traits
@@ -394,33 +417,33 @@
 KEYWORD(__is_rvalue_expr            , KEYCXX)
 
 // Embarcadero Unary Type Traits
-KEYWORD(__is_arithmetic             , KEYCXX)
-KEYWORD(__is_floating_point         , KEYCXX)
-KEYWORD(__is_integral               , KEYCXX)
-KEYWORD(__is_complete_type          , KEYCXX)
-KEYWORD(__is_void                   , KEYCXX)
-KEYWORD(__is_array                  , KEYCXX)
-KEYWORD(__is_function               , KEYCXX)
-KEYWORD(__is_reference              , KEYCXX)
-KEYWORD(__is_lvalue_reference       , KEYCXX)
-KEYWORD(__is_rvalue_reference       , KEYCXX)
-KEYWORD(__is_fundamental            , KEYCXX)
-KEYWORD(__is_object                 , KEYCXX)
-KEYWORD(__is_scalar                 , KEYCXX)
-KEYWORD(__is_compound               , KEYCXX)
-KEYWORD(__is_pointer                , KEYCXX)
-KEYWORD(__is_member_object_pointer  , KEYCXX)
-KEYWORD(__is_member_function_pointer, KEYCXX)
-KEYWORD(__is_member_pointer         , KEYCXX)
-KEYWORD(__is_const                  , KEYCXX)
-KEYWORD(__is_volatile               , KEYCXX)
-KEYWORD(__is_standard_layout        , KEYCXX)
-KEYWORD(__is_signed                 , KEYCXX)
-KEYWORD(__is_unsigned               , KEYCXX)
+TYPE_TRAIT_1(__is_arithmetic, IsArithmetic, KEYCXX)
+TYPE_TRAIT_1(__is_floating_point, IsFloatingPoint, KEYCXX)
+TYPE_TRAIT_1(__is_integral, IsIntegral, KEYCXX)
+TYPE_TRAIT_1(__is_complete_type, IsCompleteType, KEYCXX)
+TYPE_TRAIT_1(__is_void, IsVoid, KEYCXX)
+TYPE_TRAIT_1(__is_array, IsArray, KEYCXX)
+TYPE_TRAIT_1(__is_function, IsFunction, KEYCXX)
+TYPE_TRAIT_1(__is_reference, IsReference, KEYCXX)
+TYPE_TRAIT_1(__is_lvalue_reference, IsLvalueReference, KEYCXX)
+TYPE_TRAIT_1(__is_rvalue_reference, IsRvalueReference, KEYCXX)
+TYPE_TRAIT_1(__is_fundamental, IsFundamental, KEYCXX)
+TYPE_TRAIT_1(__is_object, IsObject, KEYCXX)
+TYPE_TRAIT_1(__is_scalar, IsScalar, KEYCXX)
+TYPE_TRAIT_1(__is_compound, IsCompound, KEYCXX)
+TYPE_TRAIT_1(__is_pointer, IsPointer, KEYCXX)
+TYPE_TRAIT_1(__is_member_object_pointer, IsMemberObjectPointer, KEYCXX)
+TYPE_TRAIT_1(__is_member_function_pointer, IsMemberFunctionPointer, KEYCXX)
+TYPE_TRAIT_1(__is_member_pointer, IsMemberPointer, KEYCXX)
+TYPE_TRAIT_1(__is_const, IsConst, KEYCXX)
+TYPE_TRAIT_1(__is_volatile, IsVolatile, KEYCXX)
+TYPE_TRAIT_1(__is_standard_layout, IsStandardLayout, KEYCXX)
+TYPE_TRAIT_1(__is_signed, IsSigned, KEYCXX)
+TYPE_TRAIT_1(__is_unsigned, IsUnsigned, KEYCXX)
 
 // Embarcadero Binary Type Traits
-KEYWORD(__is_same                   , KEYCXX)
-KEYWORD(__is_convertible            , KEYCXX)
+TYPE_TRAIT_2(__is_same, IsSame, KEYCXX)
+TYPE_TRAIT_2(__is_convertible, IsConvertible, KEYCXX)
 KEYWORD(__array_rank                , KEYCXX)
 KEYWORD(__array_extent              , KEYCXX)
 
@@ -434,35 +457,31 @@
 KEYWORD(__stdcall                   , KEYALL)
 KEYWORD(__fastcall                  , KEYALL)
 KEYWORD(__thiscall                  , KEYALL)
-KEYWORD(__forceinline               , KEYALL)
+KEYWORD(__forceinline               , KEYMS)
 KEYWORD(__unaligned                 , KEYMS)
 
-// OpenCL-specific keywords
-KEYWORD(__kernel                    , KEYOPENCL)
-ALIAS("kernel", __kernel            , KEYOPENCL)
-KEYWORD(vec_step                    , KEYOPENCL|KEYALTIVEC)
-KEYWORD(__private                   , KEYOPENCL)
+// OpenCL address space qualifiers
 KEYWORD(__global                    , KEYOPENCL)
 KEYWORD(__local                     , KEYOPENCL)
 KEYWORD(__constant                  , KEYOPENCL)
+KEYWORD(__private                   , KEYOPENCL)
 ALIAS("global", __global            , KEYOPENCL)
 ALIAS("local", __local              , KEYOPENCL)
 ALIAS("constant", __constant        , KEYOPENCL)
+ALIAS("private", __private          , KEYOPENCL)
+// OpenCL function qualifiers
+KEYWORD(__kernel                    , KEYOPENCL)
+ALIAS("kernel", __kernel            , KEYOPENCL)
+// OpenCL access qualifiers
 KEYWORD(__read_only                 , KEYOPENCL)
 KEYWORD(__write_only                , KEYOPENCL)
 KEYWORD(__read_write                , KEYOPENCL)
 ALIAS("read_only", __read_only      , KEYOPENCL)
 ALIAS("write_only", __write_only    , KEYOPENCL)
 ALIAS("read_write", __read_write    , KEYOPENCL)
+// OpenCL builtins
 KEYWORD(__builtin_astype            , KEYOPENCL)
-KEYWORD(image1d_t                   , KEYOPENCL)
-KEYWORD(image1d_array_t             , KEYOPENCL)
-KEYWORD(image1d_buffer_t            , KEYOPENCL)
-KEYWORD(image2d_t                   , KEYOPENCL)
-KEYWORD(image2d_array_t             , KEYOPENCL)
-KEYWORD(image3d_t                   , KEYOPENCL)
-KEYWORD(sampler_t                   , KEYOPENCL)
-KEYWORD(event_t                     , KEYOPENCL)
+KEYWORD(vec_step                    , KEYOPENCL|KEYALTIVEC)
 
 // Borland Extensions.
 KEYWORD(__pascal                    , KEYALL)
@@ -475,7 +494,7 @@
 ALIAS("__fp16", half                , KEYALL)
 
 // OpenCL Extension.
-KEYWORD(half                        , KEYOPENCL)
+KEYWORD(half                        , HALFSUPPORT)
 
 // Objective-C ARC keywords.
 KEYWORD(__bridge                     , KEYARC)
@@ -656,6 +675,21 @@
 // handles them.
 ANNOTATION(pragma_fp_contract)
 
+// Annotation for #pragma pointers_to_members...
+// The lexer produces these so that they only take effect when the parser
+// handles them.
+ANNOTATION(pragma_ms_pointers_to_members)
+
+// Annotation for #pragma vtordisp...
+// The lexer produces these so that they only take effect when the parser
+// handles them.
+ANNOTATION(pragma_ms_vtordisp)
+
+// Annotation for all microsoft #pragmas...
+// The lexer produces these so that they only take effect when the parser
+// handles them.
+ANNOTATION(pragma_ms_pragma)
+
 // Annotation for #pragma OPENCL EXTENSION...
 // The lexer produces these so that they only take effect when the parser
 // handles them.
@@ -667,8 +701,15 @@
 ANNOTATION(pragma_openmp)
 ANNOTATION(pragma_openmp_end)
 
-// Annotation for module import translated from #include etc.
+// Annotations for loop pragma directives #pragma clang loop ...
+// The lexer produces these so that they only take effect when the parser
+// handles #pragma loop ... directives.
+ANNOTATION(pragma_loop_hint)
+
+// Annotations for module import translated from #include etc.
 ANNOTATION(module_include)
+ANNOTATION(module_begin)
+ANNOTATION(module_end)
 
 #undef ANNOTATION
 #undef TESTING_KEYWORD
@@ -677,6 +718,10 @@
 #undef CXX_KEYWORD_OPERATOR
 #undef PPKEYWORD
 #undef ALIAS
+#undef TYPE_TRAIT_N
+#undef TYPE_TRAIT_2
+#undef TYPE_TRAIT_1
+#undef TYPE_TRAIT
 #undef KEYWORD
 #undef PUNCTUATOR
 #undef TOK
diff --git a/include/clang/Basic/TokenKinds.h b/include/clang/Basic/TokenKinds.h
index dcbe1da..794625c 100644
--- a/include/clang/Basic/TokenKinds.h
+++ b/include/clang/Basic/TokenKinds.h
@@ -15,12 +15,14 @@
 #ifndef LLVM_CLANG_TOKENKINDS_H
 #define LLVM_CLANG_TOKENKINDS_H
 
+#include "llvm/Support/Compiler.h"
+
 namespace clang {
 
 namespace tok {
 
 /// \brief Provides a simple uniform namespace for tokens from all C languages.
-enum TokenKind {
+enum TokenKind : unsigned short {
 #define TOK(X) X,
 #include "clang/Basic/TokenKinds.def"
   NUM_TOKENS
@@ -52,7 +54,7 @@
 ///
 /// The name of a token will be an internal name (such as "l_square")
 /// and should not be used as part of diagnostic messages.
-const char *getTokenName(enum TokenKind Kind);
+const char *getTokenName(TokenKind Kind) LLVM_READNONE;
 
 /// \brief Determines the spelling of simple punctuation tokens like
 /// '!' or '%', and returns NULL for literal and annotation tokens.
@@ -61,7 +63,11 @@
 /// and will not produce any alternative spellings (e.g., a
 /// digraph). For the actual spelling of a given Token, use
 /// Preprocessor::getSpelling().
-const char *getTokenSimpleSpelling(enum TokenKind Kind);
+const char *getPunctuatorSpelling(TokenKind Kind) LLVM_READNONE;
+
+/// \brief Determines the spelling of simple keyword and contextual keyword
+/// tokens like 'int' and 'dynamic_cast'. Returns NULL for other token kinds.
+const char *getKeywordSpelling(TokenKind Kind) LLVM_READNONE;
 
 /// \brief Return true if this is a raw identifier or an identifier kind.
 inline bool isAnyIdentifier(TokenKind K) {
diff --git a/include/clang/Basic/TypeTraits.h b/include/clang/Basic/TypeTraits.h
index fc53527..d7d2b18 100644
--- a/include/clang/Basic/TypeTraits.h
+++ b/include/clang/Basic/TypeTraits.h
@@ -17,8 +17,8 @@
 
 namespace clang {
 
-  /// \brief Names for the unary type traits.
-  enum UnaryTypeTrait {
+  /// \brief Names for traits that operate specifically on types.
+  enum TypeTrait {
     UTT_HasNothrowAssign,
     UTT_HasNothrowMoveAssign,
     UTT_HasNothrowCopy,
@@ -37,6 +37,7 @@
     UTT_IsCompleteType,
     UTT_IsCompound,
     UTT_IsConst,
+    UTT_IsDestructible,
     UTT_IsEmpty,
     UTT_IsEnum,
     UTT_IsFinal,
@@ -50,6 +51,7 @@
     UTT_IsMemberFunctionPointer,
     UTT_IsMemberObjectPointer,
     UTT_IsMemberPointer,
+    UTT_IsNothrowDestructible,
     UTT_IsObject,
     UTT_IsPOD,
     UTT_IsPointer,
@@ -65,17 +67,19 @@
     UTT_IsUnion,
     UTT_IsUnsigned,
     UTT_IsVoid,
-    UTT_IsVolatile
-  };
-
-  /// \brief Names for the binary type traits.
-  enum BinaryTypeTrait {
+    UTT_IsVolatile,
+    UTT_Last = UTT_IsVolatile,
     BTT_IsBaseOf,
     BTT_IsConvertible,
     BTT_IsConvertibleTo,
     BTT_IsSame,
     BTT_TypeCompatible,
-    BTT_IsTriviallyAssignable
+    BTT_IsNothrowAssignable,
+    BTT_IsTriviallyAssignable,
+    BTT_Last = BTT_IsTriviallyAssignable,
+    TT_IsConstructible,
+    TT_IsNothrowConstructible,
+    TT_IsTriviallyConstructible
   };
 
   /// \brief Names for the array type traits.
@@ -90,12 +94,6 @@
     UETT_AlignOf,
     UETT_VecStep
   };
-  
-  /// \brief Names for type traits that operate specifically on types.
-  enum TypeTrait {
-    TT_IsTriviallyConstructible
-  };
-  
 }
 
 #endif
diff --git a/include/clang/Basic/Version.h b/include/clang/Basic/Version.h
index 7db8a2e..02da432 100644
--- a/include/clang/Basic/Version.h
+++ b/include/clang/Basic/Version.h
@@ -70,6 +70,9 @@
   /// and the vendor tag.
   std::string getClangFullVersion();
 
+  /// \brief Like getClangFullVersion(), but with a custom tool name.
+  std::string getClangToolFullVersion(llvm::StringRef ToolName);
+
   /// \brief Retrieves a string representing the complete clang version suitable
   /// for use in the CPP __VERSION__ macro, which includes the clang version
   /// number, the repository version, and the vendor tag.
diff --git a/include/clang/Basic/VersionTuple.h b/include/clang/Basic/VersionTuple.h
index ff06a5c..54d06e0 100644
--- a/include/clang/Basic/VersionTuple.h
+++ b/include/clang/Basic/VersionTuple.h
@@ -18,6 +18,7 @@
 #include "clang/Basic/LLVM.h"
 #include "llvm/ADT/Optional.h"
 #include <string>
+#include <tuple>
 
 namespace clang {
 
@@ -87,13 +88,8 @@
   /// If not provided, minor and subminor version numbers are considered to be
   /// zero.
   friend bool operator<(const VersionTuple &X, const VersionTuple &Y) {
-    if (X.Major != Y.Major)
-      return X.Major < Y.Major;
-
-    if (X.Minor != Y.Minor)
-      return X.Minor < Y.Minor;
-
-    return X.Subminor < Y.Subminor;
+    return std::tie(X.Major, X.Minor, X.Subminor) <
+           std::tie(Y.Major, Y.Minor, Y.Subminor);
   }
 
   /// \brief Determine whether one version number follows another.
diff --git a/include/clang/Basic/VirtualFileSystem.h b/include/clang/Basic/VirtualFileSystem.h
new file mode 100644
index 0000000..36f78fd
--- /dev/null
+++ b/include/clang/Basic/VirtualFileSystem.h
@@ -0,0 +1,283 @@
+//===- VirtualFileSystem.h - Virtual File System Layer ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// \brief Defines the virtual file system interface vfs::FileSystem.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_VIRTUAL_FILE_SYSTEM_H
+#define LLVM_CLANG_BASIC_VIRTUAL_FILE_SYSTEM_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/SourceMgr.h"
+
+namespace llvm {
+class MemoryBuffer;
+}
+
+namespace clang {
+namespace vfs {
+
+/// \brief The result of a \p status operation.
+class Status {
+  std::string Name;
+  llvm::sys::fs::UniqueID UID;
+  llvm::sys::TimeValue MTime;
+  uint32_t User;
+  uint32_t Group;
+  uint64_t Size;
+  llvm::sys::fs::file_type Type;
+  llvm::sys::fs::perms Perms;
+
+public:
+  bool IsVFSMapped; // FIXME: remove when files support multiple names
+
+public:
+  Status() : Type(llvm::sys::fs::file_type::status_error) {}
+  Status(const llvm::sys::fs::file_status &Status);
+  Status(StringRef Name, StringRef RealName, llvm::sys::fs::UniqueID UID,
+         llvm::sys::TimeValue MTime, uint32_t User, uint32_t Group,
+         uint64_t Size, llvm::sys::fs::file_type Type,
+         llvm::sys::fs::perms Perms);
+
+  /// \brief Returns the name that should be used for this file or directory.
+  StringRef getName() const { return Name; }
+  void setName(StringRef N) { Name = N; }
+
+  /// @name Status interface from llvm::sys::fs
+  /// @{
+  llvm::sys::fs::file_type getType() const { return Type; }
+  llvm::sys::fs::perms getPermissions() const { return Perms; }
+  llvm::sys::TimeValue getLastModificationTime() const { return MTime; }
+  llvm::sys::fs::UniqueID getUniqueID() const { return UID; }
+  uint32_t getUser() const { return User; }
+  uint32_t getGroup() const { return Group; }
+  uint64_t getSize() const { return Size; }
+  void setType(llvm::sys::fs::file_type v) { Type = v; }
+  void setPermissions(llvm::sys::fs::perms p) { Perms = p; }
+  /// @}
+  /// @name Status queries
+  /// These are static queries in llvm::sys::fs.
+  /// @{
+  bool equivalent(const Status &Other) const;
+  bool isDirectory() const;
+  bool isRegularFile() const;
+  bool isOther() const;
+  bool isSymlink() const;
+  bool isStatusKnown() const;
+  bool exists() const;
+  /// @}
+};
+
+/// \brief Represents an open file.
+class File {
+public:
+  /// \brief Destroy the file after closing it (if open).
+  /// Sub-classes should generally call close() inside their destructors.  We
+  /// cannot do that from the base class, since close is virtual.
+  virtual ~File();
+  /// \brief Get the status of the file.
+  virtual llvm::ErrorOr<Status> status() = 0;
+  /// \brief Get the contents of the file as a \p MemoryBuffer.
+  virtual std::error_code getBuffer(const Twine &Name,
+                                    std::unique_ptr<llvm::MemoryBuffer> &Result,
+                                    int64_t FileSize = -1,
+                                    bool RequiresNullTerminator = true,
+                                    bool IsVolatile = false) = 0;
+  /// \brief Closes the file.
+  virtual std::error_code close() = 0;
+  /// \brief Sets the name to use for this file.
+  virtual void setName(StringRef Name) = 0;
+};
+
+namespace detail {
+/// \brief An interface for virtual file systems to provide an iterator over the
+/// (non-recursive) contents of a directory.
+struct DirIterImpl {
+  virtual ~DirIterImpl();
+  /// \brief Sets \c CurrentEntry to the next entry in the directory on success,
+  /// or returns a system-defined \c error_code.
+  virtual std::error_code increment() = 0;
+  Status CurrentEntry;
+};
+} // end namespace detail
+
+/// \brief An input iterator over the entries in a virtual path, similar to
+/// llvm::sys::fs::directory_iterator.
+class directory_iterator {
+  std::shared_ptr<detail::DirIterImpl> Impl; // Input iterator semantics on copy
+
+public:
+  directory_iterator(std::shared_ptr<detail::DirIterImpl> I) : Impl(I) {
+    assert(Impl.get() != nullptr && "requires non-null implementation");
+    if (!Impl->CurrentEntry.isStatusKnown())
+      Impl.reset(); // Normalize the end iterator to Impl == nullptr.
+  }
+
+  /// \brief Construct an 'end' iterator.
+  directory_iterator() { }
+
+  /// \brief Equivalent to operator++, with an error code.
+  directory_iterator &increment(std::error_code &EC) {
+    assert(Impl && "attempting to increment past end");
+    EC = Impl->increment();
+    if (EC || !Impl->CurrentEntry.isStatusKnown())
+      Impl.reset(); // Normalize the end iterator to Impl == nullptr.
+    return *this;
+  }
+
+  const Status &operator*() const { return Impl->CurrentEntry; }
+  const Status *operator->() const { return &Impl->CurrentEntry; }
+
+  bool operator==(const directory_iterator &RHS) const {
+    if (Impl && RHS.Impl)
+      return Impl->CurrentEntry.equivalent(RHS.Impl->CurrentEntry);
+    return !Impl && !RHS.Impl;
+  }
+  bool operator!=(const directory_iterator &RHS) const {
+    return !(*this == RHS);
+  }
+};
+
+class FileSystem;
+
+/// \brief An input iterator over the recursive contents of a virtual path,
+/// similar to llvm::sys::fs::recursive_directory_iterator.
+class recursive_directory_iterator {
+  typedef std::stack<directory_iterator, std::vector<directory_iterator>>
+      IterState;
+
+  FileSystem *FS;
+  std::shared_ptr<IterState> State; // Input iterator semantics on copy.
+
+public:
+  recursive_directory_iterator(FileSystem &FS, const Twine &Path,
+                               std::error_code &EC);
+  /// \brief Construct an 'end' iterator.
+  recursive_directory_iterator() { }
+
+  /// \brief Equivalent to operator++, with an error code.
+  recursive_directory_iterator &increment(std::error_code &EC);
+
+  const Status &operator*() const { return *State->top(); }
+  const Status *operator->() const { return &*State->top(); }
+
+  bool operator==(const recursive_directory_iterator &Other) const {
+    return State == Other.State; // identity
+  }
+  bool operator!=(const recursive_directory_iterator &RHS) const {
+    return !(*this == RHS);
+  }
+};
+
+/// \brief The virtual file system interface.
+class FileSystem : public llvm::ThreadSafeRefCountedBase<FileSystem> {
+public:
+  virtual ~FileSystem();
+
+  /// \brief Get the status of the entry at \p Path, if one exists.
+  virtual llvm::ErrorOr<Status> status(const Twine &Path) = 0;
+  /// \brief Get a \p File object for the file at \p Path, if one exists.
+  virtual std::error_code openFileForRead(const Twine &Path,
+                                          std::unique_ptr<File> &Result) = 0;
+
+  /// This is a convenience method that opens a file, gets its content and then
+  /// closes the file.
+  std::error_code getBufferForFile(const Twine &Name,
+                                   std::unique_ptr<llvm::MemoryBuffer> &Result,
+                                   int64_t FileSize = -1,
+                                   bool RequiresNullTerminator = true,
+                                   bool IsVolatile = false);
+
+  /// \brief Get a directory_iterator for \p Dir.
+  /// \note The 'end' iterator is directory_iterator().
+  virtual directory_iterator dir_begin(const Twine &Dir,
+                                       std::error_code &EC) = 0;
+};
+
+/// \brief Gets an \p vfs::FileSystem for the 'real' file system, as seen by
+/// the operating system.
+IntrusiveRefCntPtr<FileSystem> getRealFileSystem();
+
+/// \brief A file system that allows overlaying one \p AbstractFileSystem on top
+/// of another.
+///
+/// Consists of a stack of >=1 \p FileSystem objects, which are treated as being
+/// one merged file system. When there is a directory that exists in more than
+/// one file system, the \p OverlayFileSystem contains a directory containing
+/// the union of their contents.  The attributes (permissions, etc.) of the
+/// top-most (most recently added) directory are used.  When there is a file
+/// that exists in more than one file system, the file in the top-most file
+/// system overrides the other(s).
+class OverlayFileSystem : public FileSystem {
+  typedef SmallVector<IntrusiveRefCntPtr<FileSystem>, 1> FileSystemList;
+  /// \brief The stack of file systems, implemented as a list in order of
+  /// their addition.
+  FileSystemList FSList;
+
+public:
+  OverlayFileSystem(IntrusiveRefCntPtr<FileSystem> Base);
+  /// \brief Pushes a file system on top of the stack.
+  void pushOverlay(IntrusiveRefCntPtr<FileSystem> FS);
+
+  llvm::ErrorOr<Status> status(const Twine &Path) override;
+  std::error_code openFileForRead(const Twine &Path,
+                                  std::unique_ptr<File> &Result) override;
+  directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override;
+
+  typedef FileSystemList::reverse_iterator iterator;
+  
+  /// \brief Get an iterator pointing to the most recently added file system.
+  iterator overlays_begin() { return FSList.rbegin(); }
+
+  /// \brief Get an iterator pointing one-past the least recently added file
+  /// system.
+  iterator overlays_end() { return FSList.rend(); }
+};
+
+/// \brief Get a globally unique ID for a virtual file or directory.
+llvm::sys::fs::UniqueID getNextVirtualUniqueID();
+
+/// \brief Gets a \p FileSystem for a virtual file system described in YAML
+/// format.
+///
+/// Takes ownership of \p Buffer.
+IntrusiveRefCntPtr<FileSystem>
+getVFSFromYAML(llvm::MemoryBuffer *Buffer,
+               llvm::SourceMgr::DiagHandlerTy DiagHandler,
+               void *DiagContext = nullptr,
+               IntrusiveRefCntPtr<FileSystem> ExternalFS = getRealFileSystem());
+
+struct YAMLVFSEntry {
+  template <typename T1, typename T2> YAMLVFSEntry(T1 &&VPath, T2 &&RPath)
+      : VPath(std::forward<T1>(VPath)), RPath(std::forward<T2>(RPath)) {}
+  std::string VPath;
+  std::string RPath;
+};
+
+class YAMLVFSWriter {
+  std::vector<YAMLVFSEntry> Mappings;
+  Optional<bool> IsCaseSensitive;
+
+public:
+  YAMLVFSWriter() {}
+  void addFileMapping(StringRef VirtualPath, StringRef RealPath);
+  void setCaseSensitivity(bool CaseSensitive) {
+    IsCaseSensitive = CaseSensitive;
+  }
+  void write(llvm::raw_ostream &OS);
+};
+
+} // end namespace vfs
+} // end namespace clang
+#endif // LLVM_CLANG_BASIC_VIRTUAL_FILE_SYSTEM_H
diff --git a/include/clang/Basic/arm_neon.td b/include/clang/Basic/arm_neon.td
index a099254..0247bb5 100644
--- a/include/clang/Basic/arm_neon.td
+++ b/include/clang/Basic/arm_neon.td
@@ -11,125 +11,265 @@
 //  file will be generated.  See ARM document DUI0348B.
 //
 //===----------------------------------------------------------------------===//
+//
+// Each intrinsic is a subclass of the Inst class. An intrinsic can either
+// generate a __builtin_* call or it can expand to a set of generic operations.
+//
+// The operations are subclasses of Operation providing a list of DAGs, the
+// last of which is the return value. The available DAG nodes are documented
+// below.
+//
+//===----------------------------------------------------------------------===//
 
-class Op;
+// The base Operation class. All operations must subclass this.
+class Operation<list<dag> ops=[]> {
+  list<dag> Ops = ops;
+  bit Unavailable = 0;
+}
+// An operation that only contains a single DAG.
+class Op<dag op> : Operation<[op]>;
+// A shorter version of Operation - takes a list of DAGs. The last of these will
+// be the return value.
+class LOp<list<dag> ops> : Operation<ops>;
 
-def OP_NONE  : Op;
-def OP_UNAVAILABLE : Op;
-def OP_ADD   : Op;
-def OP_ADDL  : Op;
-def OP_ADDLHi : Op;
-def OP_ADDW  : Op;
-def OP_ADDWHi : Op;
-def OP_SUB   : Op;
-def OP_SUBL  : Op;
-def OP_SUBLHi : Op;
-def OP_SUBW  : Op;
-def OP_SUBWHi : Op;
-def OP_MUL   : Op;
-def OP_MLA   : Op;
-def OP_MLAL  : Op;
-def OP_MULLHi : Op;
-def OP_MLALHi : Op;
-def OP_MLS   : Op;
-def OP_MLSL  : Op;
-def OP_MLSLHi : Op;
-def OP_MUL_N : Op;
-def OP_MLA_N : Op;
-def OP_MLS_N : Op;
-def OP_MLAL_N : Op;
-def OP_MLSL_N : Op;
-def OP_MUL_LN: Op;
-def OP_MULX_LN: Op;
-def OP_MULL_LN : Op;
-def OP_MULLHi_LN : Op;
-def OP_MLA_LN: Op;
-def OP_MLS_LN: Op;
-def OP_MLAL_LN : Op;
-def OP_MLALHi_LN : Op;
-def OP_MLSL_LN : Op;
-def OP_MLSLHi_LN : Op;
-def OP_QDMULL_LN : Op;
-def OP_QDMULLHi_LN : Op;
-def OP_QDMLAL_LN : Op;
-def OP_QDMLALHi_LN : Op;
-def OP_QDMLSL_LN : Op;
-def OP_QDMLSLHi_LN : Op;
-def OP_QDMULH_LN : Op;
-def OP_QRDMULH_LN : Op;
-def OP_FMS_LN : Op;
-def OP_FMS_LNQ : Op;
-def OP_TRN1  : Op;
-def OP_ZIP1  : Op;
-def OP_UZP1  : Op;
-def OP_TRN2  : Op;
-def OP_ZIP2  : Op;
-def OP_UZP2  : Op;
-def OP_EQ    : Op;
-def OP_GE    : Op;
-def OP_LE    : Op;
-def OP_GT    : Op;
-def OP_LT    : Op;
-def OP_NEG   : Op;
-def OP_NOT   : Op;
-def OP_AND   : Op;
-def OP_OR    : Op;
-def OP_XOR   : Op;
-def OP_ANDN  : Op;
-def OP_ORN   : Op;
-def OP_CAST  : Op;
-def OP_HI    : Op;
-def OP_LO    : Op;
-def OP_CONC  : Op;
-def OP_DUP   : Op;
-def OP_DUP_LN: Op;
-def OP_SEL   : Op;
-def OP_REV64 : Op;
-def OP_REV32 : Op;
-def OP_REV16 : Op;
-def OP_XTN : Op;
-def OP_SQXTUN : Op;
-def OP_QXTN : Op;
-def OP_VCVT_NA_HI : Op;
-def OP_VCVT_EX_HI : Op;
-def OP_VCVTX_HI : Op;
-def OP_REINT : Op;
-def OP_ADDHNHi : Op;
-def OP_RADDHNHi : Op;
-def OP_SUBHNHi : Op;
-def OP_RSUBHNHi : Op;
-def OP_ABDL  : Op;
-def OP_ABDLHi : Op;
-def OP_ABA   : Op;
-def OP_ABAL  : Op;
-def OP_ABALHi : Op;
-def OP_QDMULLHi : Op;
-def OP_QDMLALHi : Op;
-def OP_QDMLSLHi : Op;
-def OP_DIV  : Op;
-def OP_LONG_HI : Op;
-def OP_NARROW_HI : Op;
-def OP_MOVL_HI : Op;
-def OP_COPY_LN : Op;
-def OP_COPYQ_LN : Op;
-def OP_COPY_LNQ : Op;
-def OP_SCALAR_MUL_LN : Op;
-def OP_SCALAR_MUL_LNQ : Op;
-def OP_SCALAR_MULX_LN : Op;
-def OP_SCALAR_MULX_LNQ : Op;
-def OP_SCALAR_VMULX_LN : Op;
-def OP_SCALAR_VMULX_LNQ : Op;
+// These defs and classes are used internally to implement the SetTheory
+// expansion and should be ignored.
+foreach Index = 0-63 in
+  def sv##Index;
+class MaskExpand;
 
-class Inst <string n, string p, string t, Op o> {
+//===----------------------------------------------------------------------===//
+// Available operations
+//===----------------------------------------------------------------------===//
+
+// DAG arguments can either be operations (documented below) or variables.
+// Variables are prefixed with '$'. There are variables for each input argument,
+// with the name $pN, where N starts at zero. So the zero'th argument will be
+// $p0, the first $p1 etc.
+
+// op - Binary or unary operator, depending on the number of arguments. The
+//      operator itself is just treated as a raw string and is not checked.
+// example: (op "+", $p0, $p1) -> "__p0 + __p1".
+//          (op "-", $p0)      -> "-__p0"
+def op;
+// call - Invoke another intrinsic. The input types are type checked and
+//        disambiguated. If there is no intrinsic defined that takes
+//        the given types (or if there is a type ambiguity) an error is
+//        generated at tblgen time. The name of the intrinsic is the raw
+//        name as given to the Inst class (not mangled).
+// example: (call "vget_high", $p0) -> "vgetq_high_s16(__p0)"
+//            (assuming $p0 has type int16x8_t).
+def call;
+// cast - Perform a cast to a different type. This gets emitted as a static
+//        C-style cast. For a pure reinterpret cast (T x = *(T*)&y), use
+//        "bitcast".
+//
+//        The syntax is (cast MOD* VAL). The last argument is the value to
+//        cast, preceded by a sequence of type modifiers. The target type
+//        starts off as the type of VAL, and is modified by MOD in sequence.
+//        The available modifiers are:
+//          - $X  - Take the type of parameter/variable X. For example:
+//                  (cast $p0, $p1) would cast $p1 to the type of $p0.
+//          - "R" - The type of the return type.
+//          - A typedef string - A NEON or stdint.h type that is then parsed.
+//                               for example: (cast "uint32x4_t", $p0).
+//          - "U" - Make the type unsigned.
+//          - "S" - Make the type signed.
+//          - "H" - Halve the number of lanes in the type.
+//          - "D" - Double the number of lanes in the type.
+//          - "8" - Convert type to an equivalent vector of 8-bit signed
+//                  integers.
+// example: (cast "R", "U", $p0) -> "(uint32x4_t)__p0" (assuming the return
+//           value is of type "int32x4_t".
+//          (cast $p0, "D", "8", $p1) -> "(int8x16_t)__p1" (assuming __p0
+//           has type float64x1_t or any other vector type of 64 bits).
+//          (cast "int32_t", $p2) -> "(int32_t)__p2"
+def cast;
+// bitcast - Same as "cast", except a reinterpret-cast is produced:
+//             (bitcast "T", $p0) -> "*(T*)&__p0".
+//           The VAL argument is saved to a temporary so it can be used
+//           as an l-value.
+def bitcast;
+// dup - Take a scalar argument and create a vector by duplicating it into
+//       all lanes. The type of the vector is the base type of the intrinsic.
+// example: (dup $p1) -> "(uint32x2_t) {__p1, __p1}" (assuming the base type
+//          is uint32x2_t).
+def dup;
+// splat - Take a vector and a lane index, and return a vector of the same type
+//         containing repeated instances of the source vector at the lane index.
+// example: (splat $p0, $p1) ->
+//            "__builtin_shufflevector(__p0, __p0, __p1, __p1, __p1, __p1)"
+//          (assuming __p0 has four elements).
+def splat;
+// save_temp - Create a temporary (local) variable. The variable takes a name
+//             based on the zero'th parameter and can be referenced using
+//             using that name in subsequent DAGs in the same
+//             operation. The scope of a temp is the operation. If a variable
+//             with the given name already exists, an error will be given at
+//             tblgen time.
+// example: [(save_temp $var, (call "foo", $p0)),
+//           (op "+", $var, $p1)] ->
+//              "int32x2_t __var = foo(__p0); return __var + __p1;"
+def save_temp;
+// name_replace - Return the name of the current intrinsic with the first
+//                argument replaced by the second argument. Raises an error if
+//                the first argument does not exist in the intrinsic name.
+// example: (call (name_replace "_high_", "_"), $p0) (to call the non-high
+//            version of this intrinsic).
+def name_replace;
+// literal - Create a literal piece of code. The code is treated as a raw
+//           string, and must be given a type. The type is a stdint.h or
+//           NEON intrinsic type as given to (cast).
+// example: (literal "int32_t", "0")
+def literal;
+// shuffle - Create a vector shuffle. The syntax is (shuffle ARG0, ARG1, MASK).
+//           The MASK argument is a set of elements. The elements are generated
+//           from the two special defs "mask0" and "mask1". "mask0" expands to
+//           the lane indices in sequence for ARG0, and "mask1" expands to
+//           the lane indices in sequence for ARG1. They can be used as-is, e.g.
+//
+//             (shuffle $p0, $p1, mask0) -> $p0
+//             (shuffle $p0, $p1, mask1) -> $p1
+//
+//           or, more usefully, they can be manipulated using the SetTheory
+//           operators plus some extra operators defined in the NEON emitter.
+//           The operators are described below.
+// example: (shuffle $p0, $p1, (add (highhalf mask0), (highhalf mask1))) ->
+//            A concatenation of the high halves of the input vectors.
+def shuffle;
+
+// add, interleave, decimate: These set operators are vanilla SetTheory
+// operators and take their normal definition.
+def add;
+def interleave;
+def decimate;
+// rotl - Rotate set left by a number of elements.
+// example: (rotl mask0, 3) -> [3, 4, 5, 6, 0, 1, 2]
+def rotl;
+// rotl - Rotate set right by a number of elements.
+// example: (rotr mask0, 3) -> [4, 5, 6, 0, 1, 2, 3]
+def rotr;
+// highhalf - Take only the high half of the input.
+// example: (highhalf mask0) -> [4, 5, 6, 7] (assuming mask0 had 8 elements)
+def highhalf;
+// highhalf - Take only the low half of the input.
+// example: (lowhalf mask0) -> [0, 1, 2, 3] (assuming mask0 had 8 elements)
+def lowhalf;
+// rev - Perform a variable-width reversal of the elements. The zero'th argument
+//       is a width in bits to reverse. The lanes this maps to is determined
+//       based on the element width of the underlying type.
+// example: (rev 32, mask0) -> [3, 2, 1, 0, 7, 6, 5, 4] (if 8-bit elements)
+// example: (rev 32, mask0) -> [1, 0, 3, 2]             (if 16-bit elements)
+def rev;
+// mask0 - The initial sequence of lanes for shuffle ARG0
+def mask0 : MaskExpand;
+// mask0 - The initial sequence of lanes for shuffle ARG1
+def mask1 : MaskExpand;
+
+def OP_NONE  : Operation;
+def OP_UNAVAILABLE : Operation {
+  let Unavailable = 1;
+}
+
+//===----------------------------------------------------------------------===//
+// Instruction definitions
+//===----------------------------------------------------------------------===//
+
+// Every intrinsic subclasses "Inst". An intrinsic has a name, a prototype and
+// a sequence of typespecs.
+//
+// The name is the base name of the intrinsic, for example "vget_lane". This is
+// then mangled by the tblgen backend to add type information ("vget_lane_s16").
+//
+// A typespec is a sequence of uppercase characters (modifiers) followed by one
+// lowercase character. A typespec encodes a particular "base type" of the
+// intrinsic.
+//
+// An example typespec is "Qs" - quad-size short - uint16x8_t. The available
+// typespec codes are given below.
+//
+// The string given to an Inst class is a sequence of typespecs. The intrinsic
+// is instantiated for every typespec in the sequence. For example "sdQsQd".
+//
+// The prototype is a string that defines the return type of the intrinsic
+// and the type of each argument. The return type and every argument gets a
+// "modifier" that can change in some way the "base type" of the intrinsic.
+//
+// The modifier 'd' means "default" and does not modify the base type in any
+// way. The available modifiers are given below.
+//
+// Typespecs
+// ---------
+// c: char
+// s: short
+// i: int
+// l: long
+// k: 128-bit long
+// f: float
+// h: half-float
+// d: double
+//
+// Typespec modifiers
+// ------------------
+// S: scalar, only used for function mangling.
+// U: unsigned
+// Q: 128b
+// H: 128b without mangling 'q'
+// P: polynomial
+//
+// Prototype modifiers
+// -------------------
+// prototype: return (arg, arg, ...)
+//
+// v: void
+// t: best-fit integer (int/poly args)
+// x: signed integer   (int/float args)
+// u: unsigned integer (int/float args)
+// f: float (int args)
+// F: double (int args)
+// d: default
+// g: default, ignore 'Q' size modifier.
+// j: default, force 'Q' size modifier.
+// w: double width elements, same num elts
+// n: double width elements, half num elts
+// h: half width elements, double num elts
+// q: half width elements, quad num elts
+// e: half width elements, double num elts, unsigned
+// m: half width elements, same num elts
+// i: constant int
+// l: constant uint64
+// s: scalar of element type
+// z: scalar of half width element type, signed
+// r: scalar of double width element type, signed
+// a: scalar of element type (splat to vector type)
+// b: scalar of unsigned integer/long type (int/float args)
+// $: scalar of signed integer/long type (int/float args)
+// y: scalar of float
+// o: scalar of double
+// k: default elt width, double num elts
+// 2,3,4: array of default vectors
+// B,C,D: array of default elts, force 'Q' size modifier.
+// p: pointer type
+// c: const pointer type
+
+// Every intrinsic subclasses Inst.
+class Inst <string n, string p, string t, Operation o> {
   string Name = n;
   string Prototype = p;
   string Types = t;
-  Op Operand = o;
+  string ArchGuard = "";
+
+  Operation Operation = o;
+  bit CartesianProductOfTypes = 0;
+  bit BigEndianSafe = 0;
   bit isShift = 0;
   bit isScalarShift = 0;
+  bit isScalarNarrowShift = 0;
   bit isVCVT_N = 0;
-  bit isA64 = 0;
-  bit isCrypto = 0;
+  // For immediate checks: the immediate will be assumed to specify the lane of
+  // a Q register. Only used for intrinsics which end up calling polymorphic
+  // builtins.
+  bit isLaneQ = 0;
 
   // Certain intrinsics have different names than their representative
   // instructions. This field allows us to handle this correctly when we
@@ -164,58 +304,193 @@
 // WOpInst:       Instruction with bit size only suffix (e.g., "8").
 // LOpInst:       Logical instruction with no bit size suffix.
 // NoTestOpInst:  Intrinsic that has no corresponding instruction.
-class SOpInst<string n, string p, string t, Op o> : Inst<n, p, t, o> {}
-class IOpInst<string n, string p, string t, Op o> : Inst<n, p, t, o> {}
-class WOpInst<string n, string p, string t, Op o> : Inst<n, p, t, o> {}
-class LOpInst<string n, string p, string t, Op o> : Inst<n, p, t, o> {}
-class NoTestOpInst<string n, string p, string t, Op o> : Inst<n, p, t, o> {}
+class SOpInst<string n, string p, string t, Operation o> : Inst<n, p, t, o> {}
+class IOpInst<string n, string p, string t, Operation o> : Inst<n, p, t, o> {}
+class WOpInst<string n, string p, string t, Operation o> : Inst<n, p, t, o> {}
+class LOpInst<string n, string p, string t, Operation o> : Inst<n, p, t, o> {}
+class NoTestOpInst<string n, string p, string t, Operation o> : Inst<n, p, t, o> {}
 
-// prototype: return (arg, arg, ...)
-// v: void
-// t: best-fit integer (int/poly args)
-// x: signed integer   (int/float args)
-// u: unsigned integer (int/float args)
-// f: float (int args)
-// d: default
-// g: default, ignore 'Q' size modifier.
-// j: default, force 'Q' size modifier.
-// w: double width elements, same num elts
-// n: double width elements, half num elts
-// h: half width elements, double num elts
-// q: half width elements, quad num elts
-// e: half width elements, double num elts, unsigned
-// m: half width elements, same num elts
-// i: constant int
-// l: constant uint64
-// s: scalar of element type
-// z: scalar of half width element type, signed
-// r: scalar of double width element type, signed
-// a: scalar of element type (splat to vector type)
-// b: scalar of unsigned integer/long type (int/float args)
-// $: scalar of signed integer/long type (int/float args)
-// y: scalar of float
-// o: scalar of double
-// k: default elt width, double num elts
-// 2,3,4: array of default vectors
-// B,C,D: array of default elts, force 'Q' size modifier.
-// p: pointer type
-// c: const pointer type
+//===----------------------------------------------------------------------===//
+// Operations
+//===----------------------------------------------------------------------===//
 
-// sizes:
-// c: char
-// s: short
-// i: int
-// l: long
-// f: float
-// h: half-float
-// d: double
+def OP_ADD      : Op<(op "+", $p0, $p1)>;
+def OP_ADDL     : Op<(op "+", (call "vmovl", $p0), (call "vmovl", $p1))>;
+def OP_ADDLHi   : Op<(op "+", (call "vmovl_high", $p0),
+                              (call "vmovl_high", $p1))>;
+def OP_ADDW     : Op<(op "+", $p0, (call "vmovl", $p1))>;
+def OP_ADDWHi   : Op<(op "+", $p0, (call "vmovl_high", $p1))>;
+def OP_SUB      : Op<(op "-", $p0, $p1)>;
+def OP_SUBL     : Op<(op "-", (call "vmovl", $p0), (call "vmovl", $p1))>;
+def OP_SUBLHi   : Op<(op "-", (call "vmovl_high", $p0),
+                              (call "vmovl_high", $p1))>;
+def OP_SUBW     : Op<(op "-", $p0, (call "vmovl", $p1))>;
+def OP_SUBWHi   : Op<(op "-", $p0, (call "vmovl_high", $p1))>;
+def OP_MUL      : Op<(op "*", $p0, $p1)>;
+def OP_MLA      : Op<(op "+", $p0, (op "*", $p1, $p2))>;
+def OP_MLAL     : Op<(op "+", $p0, (call "vmull", $p1, $p2))>;
+def OP_MULLHi   : Op<(call "vmull", (call "vget_high", $p0),
+                                    (call "vget_high", $p1))>;
+def OP_MULLHi_P64 : Op<(call "vmull",
+                         (cast "poly64_t", (call "vget_high", $p0)),
+                         (cast "poly64_t", (call "vget_high", $p1)))>;
+def OP_MULLHi_N : Op<(call "vmull_n", (call "vget_high", $p0), $p1)>;
+def OP_MLALHi   : Op<(call "vmlal", $p0, (call "vget_high", $p1),
+                                         (call "vget_high", $p2))>;
+def OP_MLALHi_N : Op<(call "vmlal_n", $p0, (call "vget_high", $p1), $p2)>;
+def OP_MLS      : Op<(op "-", $p0, (op "*", $p1, $p2))>;
+def OP_MLSL     : Op<(op "-", $p0, (call "vmull", $p1, $p2))>;
+def OP_MLSLHi   : Op<(call "vmlsl", $p0, (call "vget_high", $p1),
+                                         (call "vget_high", $p2))>;
+def OP_MLSLHi_N : Op<(call "vmlsl_n", $p0, (call "vget_high", $p1), $p2)>;
+def OP_MUL_N    : Op<(op "*", $p0, (dup $p1))>;
+def OP_MLA_N    : Op<(op "+", $p0, (op "*", $p1, (dup $p2)))>;
+def OP_MLS_N    : Op<(op "-", $p0, (op "*", $p1, (dup $p2)))>;
+def OP_FMLA_N   : Op<(call "vfma", $p0, $p1, (dup $p2))>;
+def OP_FMLS_N   : Op<(call "vfms", $p0, $p1, (dup $p2))>;
+def OP_MLAL_N   : Op<(op "+", $p0, (call "vmull", $p1, (dup $p2)))>;
+def OP_MLSL_N   : Op<(op "-", $p0, (call "vmull", $p1, (dup $p2)))>;
+def OP_MUL_LN   : Op<(op "*", $p0, (splat $p1, $p2))>;
+def OP_MULX_LN  : Op<(call "vmulx", $p0, (splat $p1, $p2))>;
+def OP_MULL_LN  : Op<(call "vmull", $p0, (splat $p1, $p2))>;
+def OP_MULLHi_LN: Op<(call "vmull", (call "vget_high", $p0), (splat $p1, $p2))>;
+def OP_MLA_LN   : Op<(op "+", $p0, (op "*", $p1, (splat $p2, $p3)))>;
+def OP_MLS_LN   : Op<(op "-", $p0, (op "*", $p1, (splat $p2, $p3)))>;
+def OP_MLAL_LN  : Op<(op "+", $p0, (call "vmull", $p1, (splat $p2, $p3)))>;
+def OP_MLALHi_LN: Op<(op "+", $p0, (call "vmull", (call "vget_high", $p1),
+                                                  (splat $p2, $p3)))>;
+def OP_MLSL_LN  : Op<(op "-", $p0, (call "vmull", $p1, (splat $p2, $p3)))>;
+def OP_MLSLHi_LN : Op<(op "-", $p0, (call "vmull", (call "vget_high", $p1),
+                                                   (splat $p2, $p3)))>;
+def OP_QDMULL_LN : Op<(call "vqdmull", $p0, (splat $p1, $p2))>;
+def OP_QDMULLHi_LN : Op<(call "vqdmull", (call "vget_high", $p0),
+                                         (splat $p1, $p2))>;
+def OP_QDMLAL_LN : Op<(call "vqdmlal", $p0, $p1, (splat $p2, $p3))>;
+def OP_QDMLALHi_LN : Op<(call "vqdmlal", $p0, (call "vget_high", $p1),
+                                              (splat $p2, $p3))>;
+def OP_QDMLSL_LN : Op<(call "vqdmlsl", $p0, $p1, (splat $p2, $p3))>;
+def OP_QDMLSLHi_LN : Op<(call "vqdmlsl", $p0, (call "vget_high", $p1),
+                                              (splat $p2, $p3))>;
+def OP_QDMULH_LN : Op<(call "vqdmulh", $p0, (splat $p1, $p2))>;
+def OP_QRDMULH_LN : Op<(call "vqrdmulh", $p0, (splat $p1, $p2))>;
+def OP_FMS_LN   : Op<(call "vfma_lane", $p0, $p1, (op "-", $p2), $p3)>;
+def OP_FMS_LNQ  : Op<(call "vfma_laneq", $p0, $p1, (op "-", $p2), $p3)>;
+def OP_TRN1     : Op<(shuffle $p0, $p1, (interleave (decimate mask0, 2),
+                                                    (decimate mask1, 2)))>;
+def OP_ZIP1     : Op<(shuffle $p0, $p1, (lowhalf (interleave mask0, mask1)))>;
+def OP_UZP1     : Op<(shuffle $p0, $p1, (add (decimate mask0, 2),
+                                             (decimate mask1, 2)))>;
+def OP_TRN2     : Op<(shuffle $p0, $p1, (interleave
+                                          (decimate (rotl mask0, 1), 2),
+                                          (decimate (rotl mask1, 1), 2)))>;
+def OP_ZIP2     : Op<(shuffle $p0, $p1, (highhalf (interleave mask0, mask1)))>;
+def OP_UZP2     : Op<(shuffle $p0, $p1, (add (decimate (rotl mask0, 1), 2),
+                                             (decimate (rotl mask1, 1), 2)))>;
+def OP_EQ       : Op<(cast "R", (op "==", $p0, $p1))>;
+def OP_GE       : Op<(cast "R", (op ">=", $p0, $p1))>;
+def OP_LE       : Op<(cast "R", (op "<=", $p0, $p1))>;
+def OP_GT       : Op<(cast "R", (op ">", $p0, $p1))>;
+def OP_LT       : Op<(cast "R", (op "<", $p0, $p1))>;
+def OP_NEG      : Op<(op "-", $p0)>;
+def OP_NOT      : Op<(op "~", $p0)>;
+def OP_AND      : Op<(op "&", $p0, $p1)>;
+def OP_OR       : Op<(op "|", $p0, $p1)>;
+def OP_XOR      : Op<(op "^", $p0, $p1)>;
+def OP_ANDN     : Op<(op "&", $p0, (op "~", $p1))>;
+def OP_ORN      : Op<(op "|", $p0, (op "~", $p1))>;
+def OP_CAST     : Op<(cast "R", $p0)>;
+def OP_HI       : Op<(shuffle $p0, $p0, (highhalf mask0))>;
+def OP_LO       : Op<(shuffle $p0, $p0, (lowhalf mask0))>;
+def OP_CONC     : Op<(shuffle $p0, $p1, (add mask0, mask1))>;
+def OP_DUP      : Op<(dup $p0)>;
+def OP_DUP_LN   : Op<(splat $p0, $p1)>;
+def OP_SEL      : Op<(cast "R", (op "|",
+                                    (op "&", $p0, (cast $p0, $p1)),
+                                    (op "&", (op "~", $p0), (cast $p0, $p2))))>;
+def OP_REV16    : Op<(shuffle $p0, $p0, (rev 16, mask0))>;
+def OP_REV32    : Op<(shuffle $p0, $p0, (rev 32, mask0))>;
+def OP_REV64    : Op<(shuffle $p0, $p0, (rev 64, mask0))>;
+def OP_XTN      : Op<(call "vcombine", $p0, (call "vmovn", $p1))>;
+def OP_SQXTUN   : Op<(call "vcombine", (cast $p0, "U", $p0),
+                                       (call "vqmovun", $p1))>;
+def OP_QXTN     : Op<(call "vcombine", $p0, (call "vqmovn", $p1))>;
+def OP_VCVT_NA_HI_F16 : Op<(call "vcombine", $p0, (call "vcvt_f16", $p1))>;
+def OP_VCVT_NA_HI_F32 : Op<(call "vcombine", $p0, (call "vcvt_f32_f64", $p1))>;
+def OP_VCVT_EX_HI_F32 : Op<(call "vcvt_f32_f16", (call "vget_high", $p0))>;
+def OP_VCVT_EX_HI_F64 : Op<(call "vcvt_f64_f32", (call "vget_high", $p0))>;
+def OP_VCVTX_HI : Op<(call "vcombine", $p0, (call "vcvtx_f32", $p1))>;
+def OP_REINT    : Op<(cast "R", $p0)>;
+def OP_ADDHNHi  : Op<(call "vcombine", $p0, (call "vaddhn", $p1, $p2))>;
+def OP_RADDHNHi : Op<(call "vcombine", $p0, (call "vraddhn", $p1, $p2))>;
+def OP_SUBHNHi  : Op<(call "vcombine", $p0, (call "vsubhn", $p1, $p2))>;
+def OP_RSUBHNHi : Op<(call "vcombine", $p0, (call "vrsubhn", $p1, $p2))>;
+def OP_ABDL     : Op<(cast "R", (call "vmovl", (cast $p0, "U",
+                                                     (call "vabd", $p0, $p1))))>;
+def OP_ABDLHi   : Op<(call "vabdl", (call "vget_high", $p0),
+                                    (call "vget_high", $p1))>;
+def OP_ABA      : Op<(op "+", $p0, (call "vabd", $p1, $p2))>;
+def OP_ABAL     : Op<(op "+", $p0, (call "vabdl", $p1, $p2))>;
+def OP_ABALHi   : Op<(call "vabal", $p0, (call "vget_high", $p1),
+                                       (call "vget_high", $p2))>;
+def OP_QDMULLHi : Op<(call "vqdmull", (call "vget_high", $p0),
+                                      (call "vget_high", $p1))>;
+def OP_QDMULLHi_N : Op<(call "vqdmull_n", (call "vget_high", $p0), $p1)>;
+def OP_QDMLALHi : Op<(call "vqdmlal", $p0, (call "vget_high", $p1),
+                                           (call "vget_high", $p2))>;
+def OP_QDMLALHi_N : Op<(call "vqdmlal_n", $p0, (call "vget_high", $p1), $p2)>;
+def OP_QDMLSLHi : Op<(call "vqdmlsl", $p0, (call "vget_high", $p1),
+                                           (call "vget_high", $p2))>;
+def OP_QDMLSLHi_N : Op<(call "vqdmlsl_n", $p0, (call "vget_high", $p1), $p2)>;
+def OP_DIV  : Op<(op "/", $p0, $p1)>;
+def OP_LONG_HI : Op<(cast "R", (call (name_replace "_high_", "_"),
+                                                (call "vget_high", $p0), $p1))>;
+def OP_NARROW_HI : Op<(cast "R", (call "vcombine",
+                                       (cast "R", "H", $p0),
+                                       (cast "R", "H",
+                                           (call (name_replace "_high_", "_"),
+                                                 $p1, $p2))))>;
+def OP_MOVL_HI  : LOp<[(save_temp $a1, (call "vget_high", $p0)),
+                       (cast "R",
+                            (call "vshll_n", $a1, (literal "int32_t", "0")))]>;
+def OP_COPY_LN : Op<(call "vset_lane", (call "vget_lane", $p2, $p3), $p0, $p1)>;
+def OP_SCALAR_MUL_LN : Op<(op "*", $p0, (call "vget_lane", $p1, $p2))>;
+def OP_SCALAR_MULX_LN : Op<(call "vmulx", $p0, (call "vget_lane", $p1, $p2))>;
+def OP_SCALAR_VMULX_LN : LOp<[(save_temp $x, (call "vget_lane", $p0,
+                                                    (literal "int32_t", "0"))),
+                              (save_temp $y, (call "vget_lane", $p1, $p2)),
+                              (save_temp $z, (call "vmulx", $x, $y)),
+                              (call "vset_lane", $z, $p0, $p2)]>;
+def OP_SCALAR_VMULX_LNQ : LOp<[(save_temp $x, (call "vget_lane", $p0,
+                                                     (literal "int32_t", "0"))),
+                               (save_temp $y, (call "vget_lane", $p1, $p2)),
+                               (save_temp $z, (call "vmulx", $x, $y)),
+                               (call "vset_lane", $z, $p0, (literal "int32_t",
+                                                                     "0"))]>;
+class ScalarMulOp<string opname> :
+  Op<(call opname, $p0, (call "vget_lane", $p1, $p2))>;
 
-// size modifiers:
-// S: scalar, only used for function mangling.
-// U: unsigned
-// Q: 128b
-// H: 128b without mangling 'q'
-// P: polynomial
+def OP_SCALAR_QDMULL_LN : ScalarMulOp<"vqdmull">;
+def OP_SCALAR_QDMULH_LN : ScalarMulOp<"vqdmulh">;
+def OP_SCALAR_QRDMULH_LN : ScalarMulOp<"vqrdmulh">;
+
+def OP_SCALAR_HALF_GET_LN : Op<(bitcast "float16_t",
+                                   (call "vget_lane",
+                                         (bitcast "int16x4_t", $p0), $p1))>;
+def OP_SCALAR_HALF_GET_LNQ : Op<(bitcast "float16_t",
+                                    (call "vget_lane",
+                                          (bitcast "int16x8_t", $p0), $p1))>;
+def OP_SCALAR_HALF_SET_LN : Op<(bitcast "float16x4_t",
+                                   (call "vset_lane",
+                                         (bitcast "int16_t", $p0),
+                                         (bitcast "int16x4_t", $p1), $p2))>;
+def OP_SCALAR_HALF_SET_LNQ : Op<(bitcast "float16x8_t",
+                                    (call "vset_lane",
+                                          (bitcast "int16_t", $p0),
+                                          (bitcast "int16x8_t", $p1), $p2))>;
+
+//===----------------------------------------------------------------------===//
+// Instructions
+//===----------------------------------------------------------------------===//
 
 ////////////////////////////////////////////////////////////////////////////////
 // E.3.1 Addition
@@ -380,15 +655,19 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 // E.3.18 Initialize a vector from bit pattern
-def VCREATE : NoTestOpInst<"vcreate", "dl", "csihfUcUsUiUlPcPsl", OP_CAST>;
+def VCREATE : NoTestOpInst<"vcreate", "dl", "csihfUcUsUiUlPcPsl", OP_CAST> {
+  let BigEndianSafe = 1;
+}
 
 ////////////////////////////////////////////////////////////////////////////////
 // E.3.19 Set all lanes to same value
 let InstName = "vmov" in {
 def VDUP_N   : WOpInst<"vdup_n", "ds",
-                       "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl", OP_DUP>;
+                       "UcUsUicsiPcPshfQUcQUsQUiQcQsQiQPcQPsQhQflUlQlQUl",
+                       OP_DUP>;
 def VMOV_N   : WOpInst<"vmov_n", "ds",
-                       "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl", OP_DUP>;
+                       "UcUsUicsiPcPshfQUcQUsQUiQcQsQiQPcQPsQhQflUlQlQUl",
+                       OP_DUP>;
 }
 let InstName = "" in
 def VDUP_LANE: WOpInst<"vdup_lane", "dgi",
@@ -512,7 +791,11 @@
 // E.3.31 Vector reinterpret cast operations
 def VREINTERPRET
   : NoTestOpInst<"vreinterpret", "dd",
-         "csilUcUsUiUlhfPcPsQcQsQiQlQUcQUsQUiQUlQhQfQPcQPs", OP_REINT>;
+         "csilUcUsUiUlhfPcPsQcQsQiQlQUcQUsQUiQUlQhQfQPcQPs", OP_REINT> {
+  let CartesianProductOfTypes = 1;
+  let ArchGuard = "!defined(__aarch64__)";
+  let BigEndianSafe = 1;
+}
 
 ////////////////////////////////////////////////////////////////////////////////
 // Vector fused multiply-add operations
@@ -522,85 +805,66 @@
 ////////////////////////////////////////////////////////////////////////////////
 // AArch64 Intrinsics
 
-let isA64 = 1 in {
+let ArchGuard = "defined(__aarch64__)" in {
 
 ////////////////////////////////////////////////////////////////////////////////
 // Load/Store
-// With additional QUl, Ql, d, Qd, Pl, QPl type.
-def LD1 : WInst<"vld1", "dc",
-                "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsUcUsUiUlcsilhfdPcPsPlQPl">;
-def LD2 : WInst<"vld2", "2c",
-                "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsUcUsUiUlcsilhfdPcPsPlQPl">;
-def LD3 : WInst<"vld3", "3c",
-                "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsUcUsUiUlcsilhfdPcPsPlQPl">;
-def LD4 : WInst<"vld4", "4c",
-                "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsUcUsUiUlcsilhfdPcPsPlQPl">;
-def ST1 : WInst<"vst1", "vpd",
-                "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsUcUsUiUlcsilhfdPcPsPlQPl">;
-def ST2 : WInst<"vst2", "vp2",
-                "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsUcUsUiUlcsilhfdPcPsPlQPl">;
-def ST3 : WInst<"vst3", "vp3",
-                "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsUcUsUiUlcsilhfdPcPsPlQPl">;
-def ST4 : WInst<"vst4", "vp4",
-                "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsUcUsUiUlcsilhfdPcPsPlQPl">;
+def LD1 : WInst<"vld1", "dc", "dQdPlQPl">;
+def LD2 : WInst<"vld2", "2c", "QUlQldQdPlQPl">;
+def LD3 : WInst<"vld3", "3c", "QUlQldQdPlQPl">;
+def LD4 : WInst<"vld4", "4c", "QUlQldQdPlQPl">;
+def ST1 : WInst<"vst1", "vpd", "dQdPlQPl">;
+def ST2 : WInst<"vst2", "vp2", "QUlQldQdPlQPl">;
+def ST3 : WInst<"vst3", "vp3", "QUlQldQdPlQPl">;
+def ST4 : WInst<"vst4", "vp4", "QUlQldQdPlQPl">;
 
 def LD1_X2 : WInst<"vld1_x2", "2c",
-                   "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">;
+                   "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPsQUlQldQdPlQPl">;
 def LD3_x3 : WInst<"vld1_x3", "3c",
-                   "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">;
+                   "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPsQUlQldQdPlQPl">;
 def LD4_x4 : WInst<"vld1_x4", "4c",
-                   "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">;
+                   "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPsQUlQldQdPlQPl">;
 
 def ST1_X2 : WInst<"vst1_x2", "vp2",
-                   "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">;
+                   "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPsQUlQldQdPlQPl">;
 def ST1_X3 : WInst<"vst1_x3", "vp3",
-                   "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">;
+                   "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPsQUlQldQdPlQPl">;
 def ST1_X4 : WInst<"vst1_x4", "vp4",
-                   "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">;
+                   "QUcQUsQUiQcQsQiQhQfQPcQPsUcUsUiUlcsilhfPcPsQUlQldQdPlQPl">;
 
-// With additional QUl, Ql, d, Qd, Pl, QPl type.
-def LD1_LANE : WInst<"vld1_lane", "dcdi",
-                    "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">;
-def LD2_LANE : WInst<"vld2_lane", "2c2i",
-                    "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">;
-def LD3_LANE : WInst<"vld3_lane", "3c3i",
-                    "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">;
-def LD4_LANE : WInst<"vld4_lane", "4c4i",
-                    "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">;
-def ST1_LANE : WInst<"vst1_lane", "vpdi",
-                    "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">;
-def ST2_LANE : WInst<"vst2_lane", "vp2i",
-                    "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">;
-def ST3_LANE : WInst<"vst3_lane", "vp3i",
-                    "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">;
-def ST4_LANE : WInst<"vst4_lane", "vp4i",
-                    "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">;
+def LD1_LANE : WInst<"vld1_lane", "dcdi", "dQdPlQPl">;
+def LD2_LANE : WInst<"vld2_lane", "2c2i", "lUlQcQUcQPcQlQUldQdPlQPl">;
+def LD3_LANE : WInst<"vld3_lane", "3c3i", "lUlQcQUcQPcQlQUldQdPlQPl">;
+def LD4_LANE : WInst<"vld4_lane", "4c4i", "lUlQcQUcQPcQlQUldQdPlQPl">;
+def ST1_LANE : WInst<"vst1_lane", "vpdi", "dQdPlQPl">;
+def ST2_LANE : WInst<"vst2_lane", "vp2i", "lUlQcQUcQPcQlQUldQdPlQPl">;
+def ST3_LANE : WInst<"vst3_lane", "vp3i", "lUlQcQUcQPcQlQUldQdPlQPl">;
+def ST4_LANE : WInst<"vst4_lane", "vp4i", "lUlQcQUcQPcQlQUldQdPlQPl">;
 
-def LD1_DUP  : WInst<"vld1_dup", "dc",
-                    "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">;
+def LD1_DUP  : WInst<"vld1_dup", "dc", "dQdPlQPl">;
 def LD2_DUP  : WInst<"vld2_dup", "2c",
-                    "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">;
+                     "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPldPl">;
 def LD3_DUP  : WInst<"vld3_dup", "3c",
-                    "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">;
+                     "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPldPl">;
 def LD4_DUP  : WInst<"vld4_dup", "4c",
-                    "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPlUcUsUiUlcsilhfdPcPsPl">;
+                     "QUcQUsQUiQUlQcQsQiQlQhQfQdQPcQPsQPldPl">;
+
+def VLDRQ : WInst<"vldrq", "sc", "Pk">;
+def VSTRQ : WInst<"vstrq", "vps", "Pk">;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Addition
-// With additional Qd type.
-def ADD : IOpInst<"vadd", "ddd", "csilfUcUsUiUlQcQsQiQlQfQUcQUsQUiQUlQd", OP_ADD>;
+def ADD : IOpInst<"vadd", "ddd", "dQd", OP_ADD>;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Subtraction
-// With additional Qd type.
-def SUB : IOpInst<"vsub", "ddd", "csilfUcUsUiUlQcQsQiQlQfQUcQUsQUiQUlQd", OP_SUB>;
+def SUB : IOpInst<"vsub", "ddd", "dQd", OP_SUB>;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Multiplication
-// With additional Qd type.
-def MUL     : IOpInst<"vmul", "ddd", "csifUcUsUiQcQsQiQfQUcQUsQUiQd", OP_MUL>;
-def MLA     : IOpInst<"vmla", "dddd", "csifUcUsUiQcQsQiQfQUcQUsQUiQd", OP_MLA>;
-def MLS     : IOpInst<"vmls", "dddd", "csifUcUsUiQcQsQiQfQUcQUsQUiQd", OP_MLS>;
+def MUL     : IOpInst<"vmul", "ddd", "dQd", OP_MUL>;
+def MLA     : IOpInst<"vmla", "dddd", "dQd", OP_MLA>;
+def MLS     : IOpInst<"vmls", "dddd", "dQd", OP_MLS>;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Multiplication Extended
@@ -608,46 +872,50 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 // Division
-def FDIV : IOpInst<"vdiv", "ddd",  "fQfQd", OP_DIV>;
+def FDIV : IOpInst<"vdiv", "ddd",  "fdQfQd", OP_DIV>;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Vector fused multiply-add operations
-// With additional Qd type.
-def FMLA : SInst<"vfma", "dddd", "fQfQd">;
-def FMLS : SInst<"vfms", "dddd", "fQfQd">;
+def FMLA : SInst<"vfma", "dddd", "dQd">;
+def FMLS : SInst<"vfms", "dddd", "fdQfQd">;
+
+////////////////////////////////////////////////////////////////////////////////
+// MUL, MLA, MLS, FMA, FMS definitions with scalar argument
+def VMUL_N_A64 : IOpInst<"vmul_n", "dds", "Qd", OP_MUL_N>;
+
+def FMLA_N : SOpInst<"vfma_n", "ddds", "fQfQd", OP_FMLA_N>;
+def FMLS_N : SOpInst<"vfms_n", "ddds", "fQfQd", OP_FMLS_N>;
+
+def MLA_N : SOpInst<"vmla_n", "ddds", "Qd", OP_MLA_N>;
+def MLS_N : SOpInst<"vmls_n", "ddds", "Qd", OP_MLS_N>;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Logical operations
-// With additional Qd, Ql, QPl type.
-def BSL : SInst<"vbsl", "dudd",
-                "csilUcUsUiUlfPcPsQcQsQiQlQUcQUsQUiQUlQfQPcQPsQdPlQPl">;
+def BSL : SInst<"vbsl", "dudd", "dPlQdQPl">;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Absolute Difference
-// With additional Qd type.
-def ABD  : SInst<"vabd", "ddd",  "csiUcUsUifQcQsQiQUcQUsQUiQfQd">;
+def ABD  : SInst<"vabd", "ddd",  "dQd">;
 
 ////////////////////////////////////////////////////////////////////////////////
 // saturating absolute/negate
-// With additional Qd/Ql type.
-def ABS    : SInst<"vabs", "dd", "csifQcQsQiQfQlQd">;
-def QABS   : SInst<"vqabs", "dd", "csiQcQsQiQl">;
-def NEG    : SOpInst<"vneg", "dd", "csifQcQsQiQfQdQl", OP_NEG>;
-def QNEG   : SInst<"vqneg", "dd", "csiQcQsQiQl">;
+def ABS    : SInst<"vabs", "dd", "dQdlQl">;
+def QABS   : SInst<"vqabs", "dd", "lQl">;
+def NEG    : SOpInst<"vneg", "dd", "dlQdQl", OP_NEG>;
+def QNEG   : SInst<"vqneg", "dd", "lQl">;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Signed Saturating Accumulated of Unsigned Value
-def SUQADD : SInst<"vuqadd", "ddd", "csiQcQsQiQl">;
+def SUQADD : SInst<"vuqadd", "ddd", "csilQcQsQiQl">;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Unsigned Saturating Accumulated of Signed Value
-def USQADD : SInst<"vsqadd", "ddd", "UcUsUiQUcQUsQUiQUl">;
+def USQADD : SInst<"vsqadd", "ddd", "UcUsUiUlQUcQUsQUiQUl">;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Reciprocal/Sqrt
-// With additional Qd type.
-def FRECPS  : IInst<"vrecps", "ddd", "fQfQd">;
-def FRSQRTS : IInst<"vrsqrts", "ddd", "fQfQd">;
+def FRECPS  : IInst<"vrecps", "ddd", "dQd">;
+def FRSQRTS : IInst<"vrsqrts", "ddd", "dQd">;
 
 ////////////////////////////////////////////////////////////////////////////////
 // bitwise reverse
@@ -667,86 +935,62 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 // Converting vectors
-def VCVT_HIGH_F16 : SOpInst<"vcvt_high_f16", "qhj", "f", OP_VCVT_NA_HI>;
-def VCVT_HIGH_F32_F16 : SOpInst<"vcvt_high_f32", "wk", "h", OP_VCVT_EX_HI>;
-def VCVT_F32_F64 : SInst<"vcvt_f32_f64", "fj", "d">;
-def VCVT_HIGH_F32_F64 : SOpInst<"vcvt_high_f32", "qfj", "d", OP_VCVT_NA_HI>;
-def VCVT_F64_F32 : SInst<"vcvt_f64", "wd", "f">;
-def VCVT_F64 : SInst<"vcvt_f64", "fd",  "QlQUl">;
-def VCVT_HIGH_F64_F32 : SOpInst<"vcvt_high_f64", "wj", "f", OP_VCVT_EX_HI>;
+def VCVT_HIGH_F16 : SOpInst<"vcvt_high_f16", "qhj", "f", OP_VCVT_NA_HI_F16>;
+def VCVT_HIGH_F32_F16 : SOpInst<"vcvt_high_f32", "wk", "h", OP_VCVT_EX_HI_F32>;
+def VCVT_F32_F64 : SInst<"vcvt_f32_f64", "md", "Qd">;
+def VCVT_HIGH_F32_F64 : SOpInst<"vcvt_high_f32", "qfj", "d", OP_VCVT_NA_HI_F32>;
+def VCVT_F64_F32 : SInst<"vcvt_f64_f32", "wd", "f">;
+def VCVT_F64 : SInst<"vcvt_f64", "Fd",  "lUlQlQUl">;
+def VCVT_HIGH_F64_F32 : SOpInst<"vcvt_high_f64", "wj", "f", OP_VCVT_EX_HI_F64>;
 def VCVTX_F32_F64 : SInst<"vcvtx_f32", "fj",  "d">;
 def VCVTX_HIGH_F32_F64 : SOpInst<"vcvtx_high_f32", "qfj", "d", OP_VCVTX_HI>;
-def FRINTN : SInst<"vrndn", "dd", "fQfQd">;
-def FRINTA : SInst<"vrnda", "dd", "fQfQd">;
-def FRINTP : SInst<"vrndp", "dd", "fQfQd">;
-def FRINTM : SInst<"vrndm", "dd", "fQfQd">;
-def FRINTX : SInst<"vrndx", "dd", "fQfQd">;
-def FRINTZ : SInst<"vrnd", "dd", "fQfQd">;
-def FRINTI : SInst<"vrndi", "dd", "fQfQd">;
-def VCVT_S64 : SInst<"vcvt_s64", "xd",  "Qd">;
-def VCVT_U64 : SInst<"vcvt_u64", "ud",  "Qd">;
-def FCVTNS_S32 : SInst<"vcvtn_s32", "xd", "fQf">;
-def FCVTNS_S64 : SInst<"vcvtn_s64", "xd", "Qd">;
-def FCVTNU_S32 : SInst<"vcvtn_u32", "ud", "fQf">;
-def FCVTNU_S64 : SInst<"vcvtn_u64", "ud", "Qd">;
-def FCVTPS_S32 : SInst<"vcvtp_s32", "xd", "fQf">;
-def FCVTPS_S64 : SInst<"vcvtp_s64", "xd", "Qd">;
-def FCVTPU_S32 : SInst<"vcvtp_u32", "ud", "fQf">;
-def FCVTPU_S64 : SInst<"vcvtp_u64", "ud", "Qd">;
-def FCVTMS_S32 : SInst<"vcvtm_s32", "xd", "fQf">;
-def FCVTMS_S64 : SInst<"vcvtm_s64", "xd", "Qd">;
-def FCVTMU_S32 : SInst<"vcvtm_u32", "ud", "fQf">;
-def FCVTMU_S64 : SInst<"vcvtm_u64", "ud", "Qd">;
-def FCVTAS_S32 : SInst<"vcvta_s32", "xd", "fQf">;
-def FCVTAS_S64 : SInst<"vcvta_s64", "xd", "Qd">;
-def FCVTAU_S32 : SInst<"vcvta_u32", "ud", "fQf">;
-def FCVTAU_S64 : SInst<"vcvta_u64", "ud", "Qd">;
-def FRECPE  : SInst<"vrecpe", "dd", "fUiQfQUiQd">;
-def FRSQRTE : SInst<"vrsqrte", "dd", "fUiQfQUiQd">;
-def FSQRT   : SInst<"vsqrt", "dd", "fQfQd">;
+def FRINTN : SInst<"vrndn", "dd", "fdQfQd">;
+def FRINTA : SInst<"vrnda", "dd", "fdQfQd">;
+def FRINTP : SInst<"vrndp", "dd", "fdQfQd">;
+def FRINTM : SInst<"vrndm", "dd", "fdQfQd">;
+def FRINTX : SInst<"vrndx", "dd", "fdQfQd">;
+def FRINTZ : SInst<"vrnd", "dd", "fdQfQd">;
+def FRINTI : SInst<"vrndi", "dd", "fdQfQd">;
+def VCVT_S64 : SInst<"vcvt_s64", "xd",  "dQd">;
+def VCVT_U64 : SInst<"vcvt_u64", "ud",  "dQd">;
+def FRECPE  : SInst<"vrecpe", "dd", "dQd">;
+def FRSQRTE : SInst<"vrsqrte", "dd", "dQd">;
+def FSQRT   : SInst<"vsqrt", "dd", "fdQfQd">;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Comparison
-// With additional Qd, Ql, QPl type.
-def VVCEQ  : IOpInst<"vceq", "udd", "csifUcUsUiPcQcQsQiQfQUcQUsQUiQPcPlQPl",
-                     OP_EQ>;
-def FCAGE : IInst<"vcage", "udd", "fQfQd">;
-def FCAGT : IInst<"vcagt", "udd", "fQfQd">;
-def FCALE : IInst<"vcale", "udd", "fQfQd">;
-def FCALT : IInst<"vcalt", "udd", "fQfQd">;
-// With additional Ql, QUl, Qd types.
-def CMTST  : WInst<"vtst", "udd",
-                   "csiUcUsUiPcPsQcQsQiQUcQUsQUiQPcQPslUlQlQUlPlQPl">;
-def CFMEQ  : SOpInst<"vceq", "udd",
-                  "csifUcUsUiPcQcQsQiQlQfQUcQUsQUiQUlQPcQd", OP_EQ>;
-def CFMGE  : SOpInst<"vcge", "udd", "csifUcUsUiQcQsQiQlQfQUcQUsQUiQUlQd", OP_GE>;
-def CFMLE  : SOpInst<"vcle", "udd", "csifUcUsUiQcQsQiQlQfQUcQUsQUiQUlQd", OP_LE>;
-def CFMGT  : SOpInst<"vcgt", "udd", "csifUcUsUiQcQsQiQlQfQUcQUsQUiQUlQd", OP_GT>;
-def CFMLT  : SOpInst<"vclt", "udd", "csifUcUsUiQcQsQiQlQfQUcQUsQUiQUlQd", OP_LT>;
+def FCAGE : IInst<"vcage", "udd", "dQd">;
+def FCAGT : IInst<"vcagt", "udd", "dQd">;
+def FCALE : IInst<"vcale", "udd", "dQd">;
+def FCALT : IInst<"vcalt", "udd", "dQd">;
+def CMTST  : WInst<"vtst", "udd", "lUlPlQlQUlQPl">;
+def CFMEQ  : SOpInst<"vceq", "udd", "lUldQdQlQUlPlQPl", OP_EQ>;
+def CFMGE  : SOpInst<"vcge", "udd", "lUldQdQlQUl", OP_GE>;
+def CFMLE  : SOpInst<"vcle", "udd", "lUldQdQlQUl", OP_LE>;
+def CFMGT  : SOpInst<"vcgt", "udd", "lUldQdQlQUl", OP_GT>;
+def CFMLT  : SOpInst<"vclt", "udd", "lUldQdQlQUl", OP_LT>;
 
 def CMEQ  : SInst<"vceqz", "ud",
-                  "csifUcUsUiPcPsQcQsQiQlQfQUcQUsQUiQUlQPcQPsQd">;
-def CMGE  : SInst<"vcgez", "ud", "csifdQcQsQiQlQfQd">;
-def CMLE  : SInst<"vclez", "ud", "csifdQcQsQiQlQfQd">;
-def CMGT  : SInst<"vcgtz", "ud", "csifdQcQsQiQlQfQd">;
-def CMLT  : SInst<"vcltz", "ud", "csifdQcQsQiQlQfQd">;
+                  "csilfUcUsUiUlPcPsPlQcQsQiQlQfQUcQUsQUiQUlQPcQPsdQdQPl">;
+def CMGE  : SInst<"vcgez", "ud", "csilfdQcQsQiQlQfQd">;
+def CMLE  : SInst<"vclez", "ud", "csilfdQcQsQiQlQfQd">;
+def CMGT  : SInst<"vcgtz", "ud", "csilfdQcQsQiQlQfQd">;
+def CMLT  : SInst<"vcltz", "ud", "csilfdQcQsQiQlQfQd">;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Max/Min Integer
-// With additional Qd type.
-def MAX : SInst<"vmax", "ddd", "csiUcUsUifQcQsQiQUcQUsQUiQfQd">;
-def MIN : SInst<"vmin", "ddd", "csiUcUsUifQcQsQiQUcQUsQUiQfQd">;
+def MAX : SInst<"vmax", "ddd", "dQd">;
+def MIN : SInst<"vmin", "ddd", "dQd">;
 
 ////////////////////////////////////////////////////////////////////////////////
 // MaxNum/MinNum Floating Point
-def FMAXNM : SInst<"vmaxnm", "ddd", "fQfQd">;
-def FMINNM : SInst<"vminnm", "ddd", "fQfQd">;
+def FMAXNM : SInst<"vmaxnm", "ddd", "fdQfQd">;
+def FMINNM : SInst<"vminnm", "ddd", "fdQfQd">;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Pairwise Max/Min
-// With additional Qc Qs Qi QUc QUs QUi Qf Qd types.
-def MAXP : SInst<"vpmax", "ddd", "csiUcUsUifQcQsQiQUcQUsQUiQfQd">;
-def MINP : SInst<"vpmin", "ddd", "csiUcUsUifQcQsQiQUcQUsQUiQfQd">;
+def MAXP : SInst<"vpmax", "ddd", "QcQsQiQUcQUsQUiQfQd">;
+def MINP : SInst<"vpmin", "ddd", "QcQsQiQUcQUsQUiQfQd">;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Pairwise MaxNum/MinNum Floating Point
@@ -755,8 +999,7 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 // Pairwise Addition
-// With additional Qc Qs Qi QUc QUs QUi Qf Qd types.
-def ADDP  : IInst<"vpadd", "ddd", "csiUcUsUifQcQsQiQUcQUsQUiQfQd">;
+def ADDP  : IInst<"vpadd", "ddd", "QcQsQiQlQUcQUsQUiQUlQfQd">;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Shifts by constant
@@ -766,11 +1009,8 @@
                              OP_LONG_HI>;
 
 ////////////////////////////////////////////////////////////////////////////////
-// Shifts with insert, with additional Ql, QPl type.
-def SRI_N : WInst<"vsri_n", "dddi",
-                  "csilUcUsUiUlPcPsQcQsQiQlQUcQUsQUiQUlQPcQPsPlQPl">;
-def SLI_N : WInst<"vsli_n", "dddi",
-                  "csilUcUsUiUlPcPsQcQsQiQlQUcQUsQUiQUlQPcQPsPlQPl">;
+def SRI_N : WInst<"vsri_n", "dddi", "PlQPl">;
+def SLI_N : WInst<"vsli_n", "dddi", "PlQPl">;
 
 // Right shift narrow high
 def SHRN_HIGH_N    : IOpInst<"vshrn_high_n", "hmdi",
@@ -792,9 +1032,9 @@
 def VMOVL_HIGH   : SOpInst<"vmovl_high", "nd", "HcHsHiHUcHUsHUi", OP_MOVL_HI>;
 
 let isVCVT_N = 1 in {
-def CVTF_N_F64   : SInst<"vcvt_n_f64", "fdi", "QlQUl">;
-def FCVTZS_N_S64 : SInst<"vcvt_n_s64", "xdi", "Qd">;
-def FCVTZS_N_U64 : SInst<"vcvt_n_u64", "udi", "Qd">;
+def CVTF_N_F64   : SInst<"vcvt_n_f64", "Fdi", "lUlQlQUl">;
+def FCVTZS_N_S64 : SInst<"vcvt_n_s64", "xdi", "dQd">;
+def FCVTZS_N_U64 : SInst<"vcvt_n_u64", "udi", "dQd">;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -808,8 +1048,11 @@
 def VABAL_HIGH   : SOpInst<"vabal_high", "wwkk", "csiUcUsUi", OP_ABALHi>;
 
 def VMULL_HIGH   : SOpInst<"vmull_high", "wkk", "csiUcUsUiPc", OP_MULLHi>;
+def VMULL_HIGH_N : SOpInst<"vmull_high_n", "wks", "siUsUi", OP_MULLHi_N>;
 def VMLAL_HIGH   : SOpInst<"vmlal_high", "wwkk", "csiUcUsUi", OP_MLALHi>;
+def VMLAL_HIGH_N : SOpInst<"vmlal_high_n", "wwks", "siUsUi", OP_MLALHi_N>;
 def VMLSL_HIGH   : SOpInst<"vmlsl_high", "wwkk", "csiUcUsUi", OP_MLSLHi>;
+def VMLSL_HIGH_N : SOpInst<"vmlsl_high_n", "wwks", "siUsUi", OP_MLSLHi_N>;
 
 def VADDHN_HIGH  : SOpInst<"vaddhn_high", "qhkk", "silUsUiUl", OP_ADDHNHi>;
 def VRADDHN_HIGH : SOpInst<"vraddhn_high", "qhkk", "silUsUiUl", OP_RADDHNHi>;
@@ -817,46 +1060,45 @@
 def VRSUBHN_HIGH : SOpInst<"vrsubhn_high", "qhkk", "silUsUiUl", OP_RSUBHNHi>;
 
 def VQDMULL_HIGH : SOpInst<"vqdmull_high", "wkk", "si", OP_QDMULLHi>;
+def VQDMULL_HIGH_N : SOpInst<"vqdmull_high_n", "wks", "si", OP_QDMULLHi_N>;
 def VQDMLAL_HIGH : SOpInst<"vqdmlal_high", "wwkk", "si", OP_QDMLALHi>;
+def VQDMLAL_HIGH_N : SOpInst<"vqdmlal_high_n", "wwks", "si", OP_QDMLALHi_N>;
 def VQDMLSL_HIGH : SOpInst<"vqdmlsl_high", "wwkk", "si", OP_QDMLSLHi>;
+def VQDMLSL_HIGH_N : SOpInst<"vqdmlsl_high_n", "wwks", "si", OP_QDMLSLHi_N>;
+def VMULL_P64    : SInst<"vmull", "rss", "Pl">;
+def VMULL_HIGH_P64 : SOpInst<"vmull_high", "rdd", "HPl", OP_MULLHi_P64>;
+
 
 ////////////////////////////////////////////////////////////////////////////////
 // Extract or insert element from vector
-def GET_LANE : IInst<"vget_lane", "sdi",
-                     "csilPcPsUcUsUiUlQcQsQiQlQUcQUsQUiQUlPcPsQPcQPsfdQfQdPlQPl">;
-def SET_LANE : IInst<"vset_lane", "dsdi",
-                     "csilPcPsUcUsUiUlQcQsQiQlQUcQUsQUiQUlPcPsQPcQPsfdQfQdPlQPl">;
+def GET_LANE : IInst<"vget_lane", "sdi", "dQdPlQPl">;
+def SET_LANE : IInst<"vset_lane", "dsdi", "dQdPlQPl">;
 def COPY_LANE : IOpInst<"vcopy_lane", "ddidi",
-                        "csiPcPsUcUsUiPcPsfPl", OP_COPY_LN>;
+                        "csilUcUsUiUlPcPsPlfd", OP_COPY_LN>;
 def COPYQ_LANE : IOpInst<"vcopy_lane", "ddigi",
-                        "QcQsQiQlQUcQUsQUiQUlQPcQPsQfQdQPl", OP_COPYQ_LN>;
+                        "QcQsQiQlQUcQUsQUiQUlQPcQPsQfQdQPl", OP_COPY_LN>;
 def COPY_LANEQ : IOpInst<"vcopy_laneq", "ddiki",
-                     "csiPcPsUcUsUif", OP_COPY_LNQ>;
+                     "csilPcPsPlUcUsUiUlfd", OP_COPY_LN>;
 def COPYQ_LANEQ : IOpInst<"vcopy_laneq", "ddidi",
-                     "QcQsQiQlQUcQUsQUiQUlQPcQPsQfdQPl", OP_COPY_LN>;
+                     "QcQsQiQlQUcQUsQUiQUlQPcQPsQfQdQPl", OP_COPY_LN>;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Set all lanes to same value
-def VDUP_LANE1: WOpInst<"vdup_lane", "dgi",
-                  "csilPcPsUcUsUiUlhfdQcQsQiQlQPcQPsQUcQUsQUiQUlQhQfQdPlQPl",
+def VDUP_LANE1: WOpInst<"vdup_lane", "dgi", "hdQhQdPlQPl", OP_DUP_LN>;
+def VDUP_LANE2: WOpInst<"vdup_laneq", "dji",
+                  "csilUcUsUiUlPcPshfdQcQsQiQlQPcQPsQUcQUsQUiQUlQhQfQdPlQPl",
                         OP_DUP_LN>;
-def VDUP_LANE2: WOpInst<"vdup_laneq", "dki",
-                  "csilPcPsUcUsUiUlhfdQcQsQiQlQPcQPsQUcQUsQUiQUlQhQfQdPlQPl",
-                        OP_DUP_LN>;
-def DUP_N   : WOpInst<"vdup_n", "ds",
-                       "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUldQdPlQPl",
-                       OP_DUP>;
-def MOV_N   : WOpInst<"vmov_n", "ds",
-                       "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUldQd",
-                       OP_DUP>;
+def DUP_N   : WOpInst<"vdup_n", "ds", "dQdPlQPl", OP_DUP>;
+def MOV_N   : WOpInst<"vmov_n", "ds", "dQd", OP_DUP>;
 
 ////////////////////////////////////////////////////////////////////////////////
-// Combining vectors, with additional Pl
-def COMBINE : NoTestOpInst<"vcombine", "kdd", "csilhfUcUsUiUlPcPsPl", OP_CONC>;
+def COMBINE : NoTestOpInst<"vcombine", "kdd", "dPl", OP_CONC>;
 
 ////////////////////////////////////////////////////////////////////////////////
-//Initialize a vector from bit pattern, with additional Pl
-def CREATE : NoTestOpInst<"vcreate", "dl", "csihfdUcUsUiUlPcPslPl", OP_CAST>;
+//Initialize a vector from bit pattern
+def CREATE : NoTestOpInst<"vcreate", "dl", "dPl", OP_CAST> {
+  let BigEndianSafe = 1;
+}
 
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -866,7 +1108,9 @@
                            "siUsUifQsQiQUsQUiQf", OP_MLS_LN>;
 
 def VFMA_LANE    : IInst<"vfma_lane", "dddgi", "fdQfQd">;
-def VFMA_LANEQ   : IInst<"vfma_laneq", "dddji", "fdQfQd">;
+def VFMA_LANEQ   : IInst<"vfma_laneq", "dddji", "fdQfQd"> {
+  let isLaneQ = 1;
+}
 def VFMS_LANE    : IOpInst<"vfms_lane", "dddgi", "fdQfQd", OP_FMS_LN>;
 def VFMS_LANEQ   : IOpInst<"vfms_laneq", "dddji", "fdQfQd", OP_FMS_LNQ>;
 
@@ -898,7 +1142,7 @@
 
 // Note: d type is handled by SCALAR_VMUL_LANEQ
 def VMUL_LANEQ   : IOpInst<"vmul_laneq", "ddji",
-                           "sifUsUiQsQiQfQUsQUiQfQd", OP_MUL_LN>;
+                           "sifUsUiQsQiQUsQUiQfQd", OP_MUL_LN>;
 def VMULL_LANEQ  : SOpInst<"vmull_laneq", "wdki", "siUsUi", OP_MULL_LN>;
 def VMULL_HIGH_LANE   : SOpInst<"vmull_high_lane", "wkdi", "siUsUi",
                                 OP_MULLHi_LN>;
@@ -922,20 +1166,19 @@
 ////////////////////////////////////////////////////////////////////////////////
 // Across vectors class
 def VADDLV  : SInst<"vaddlv", "rd", "csiUcUsUiQcQsQiQUcQUsQUi">;
-def VMAXV   : SInst<"vmaxv", "sd", "csiUcUsUiQcQsQiQUcQUsQUiQf">;
-def VMINV   : SInst<"vminv", "sd", "csiUcUsUiQcQsQiQUcQUsQUiQf">;
-def VADDV   : SInst<"vaddv", "sd", "csiUcUsUiQcQsQiQUcQUsQUi">;
-def FMAXNMV : SInst<"vmaxnmv", "sd", "Qf">;
-def FMINNMV : SInst<"vminnmv", "sd", "Qf">;
+def VMAXV   : SInst<"vmaxv", "sd", "csifUcUsUiQcQsQiQUcQUsQUiQfQd">;
+def VMINV   : SInst<"vminv", "sd", "csifUcUsUiQcQsQiQUcQUsQUiQfQd">;
+def VADDV   : SInst<"vaddv", "sd", "csifUcUsUiQcQsQiQUcQUsQUiQfQdQlQUl">;
+def FMAXNMV : SInst<"vmaxnmv", "sd", "fQfQd">;
+def FMINNMV : SInst<"vminnmv", "sd", "fQfQd">;
  
 ////////////////////////////////////////////////////////////////////////////////
 // Newly added Vector Extract for f64
-def VEXT_A64 : WInst<"vext", "dddi",
-                     "cUcPcsUsPsiUilUlfdQcQUcQPcQsQUsQPsQiQUiQlQUlQfQdPlQPl">;
+def VEXT_A64 : WInst<"vext", "dddi", "dQdPlQPl">;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Crypto
-let isCrypto = 1 in {
+let ArchGuard = "__ARM_FEATURE_CRYPTO" in {
 def AESE : SInst<"vaese", "ddd", "QUc">;
 def AESD : SInst<"vaesd", "ddd", "QUc">;
 def AESMC : SInst<"vaesmc", "dd", "QUc">;
@@ -955,6 +1198,31 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
+// Float -> Int conversions with explicit rounding mode
+
+let ArchGuard = "__ARM_ARCH >= 8" in {
+def FCVTNS_S32 : SInst<"vcvtn_s32", "xd", "fQf">;
+def FCVTNU_S32 : SInst<"vcvtn_u32", "ud", "fQf">;
+def FCVTPS_S32 : SInst<"vcvtp_s32", "xd", "fQf">;
+def FCVTPU_S32 : SInst<"vcvtp_u32", "ud", "fQf">;
+def FCVTMS_S32 : SInst<"vcvtm_s32", "xd", "fQf">;
+def FCVTMU_S32 : SInst<"vcvtm_u32", "ud", "fQf">;
+def FCVTAS_S32 : SInst<"vcvta_s32", "xd", "fQf">;
+def FCVTAU_S32 : SInst<"vcvta_u32", "ud", "fQf">;
+}
+
+let ArchGuard = "__ARM_ARCH >= 8 && defined(__aarch64__)" in {
+def FCVTNS_S64 : SInst<"vcvtn_s64", "xd", "dQd">;
+def FCVTNU_S64 : SInst<"vcvtn_u64", "ud", "dQd">;
+def FCVTPS_S64 : SInst<"vcvtp_s64", "xd", "dQd">;
+def FCVTPU_S64 : SInst<"vcvtp_u64", "ud", "dQd">;
+def FCVTMS_S64 : SInst<"vcvtm_s64", "xd", "dQd">;
+def FCVTMU_S64 : SInst<"vcvtm_u64", "ud", "dQd">;
+def FCVTAS_S64 : SInst<"vcvta_s64", "xd", "dQd">;
+def FCVTAU_S64 : SInst<"vcvta_u64", "ud", "dQd">;
+}
+
+////////////////////////////////////////////////////////////////////////////////
 // Permutation
 def VTRN1 : SOpInst<"vtrn1", "ddd",
                     "csiUcUsUifPcPsQcQsQiQlQUcQUsQUiQUlQfQdQPcQPsQPl", OP_TRN1>;
@@ -986,11 +1254,17 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 // Vector reinterpret cast operations
-// With additional d, Qd, pl, Qpl types
-def REINTERPRET
-  : NoTestOpInst<"vreinterpret", "dd",
-         "csilUcUsUiUlhfdPcPsPlQcQsQiQlQUcQUsQUiQUlQhQfQdQPcQPsQPl", OP_REINT>;
 
+// NeonEmitter implicitly takes the cartesian product of the type string with
+// itself during generation so, unlike all other intrinsics, this one should
+// include *all* types, not just additional ones.
+def VVREINTERPRET
+  : NoTestOpInst<"vreinterpret", "dd",
+       "csilUcUsUiUlhfdPcPsPlQcQsQiQlQUcQUsQUiQUlQhQfQdQPcQPsQPlQPk", OP_REINT> {
+  let CartesianProductOfTypes = 1;
+  let BigEndianSafe = 1;
+  let ArchGuard = "__ARM_ARCH >= 8 && defined(__aarch64__)";
+}
 
 ////////////////////////////////////////////////////////////////////////////////
 // Scalar Intrinsics
@@ -1007,10 +1281,8 @@
 def SCALAR_QSUB   : SInst<"vqsub", "sss", "ScSsSiSlSUcSUsSUiSUl">;
 
 let InstName = "vmov" in {
-def VGET_HIGH_A64 : NoTestOpInst<"vget_high", "dk", "csilhfdUcUsUiUlPcPsPl",
-                                 OP_HI>;
-def VGET_LOW_A64  : NoTestOpInst<"vget_low", "dk", "csilhfdUcUsUiUlPcPsPl",
-                                 OP_LO>;
+def VGET_HIGH_A64 : NoTestOpInst<"vget_high", "dk", "dPl", OP_HI>;
+def VGET_LOW_A64  : NoTestOpInst<"vget_low", "dk", "dPl", OP_LO>;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -1049,14 +1321,16 @@
 // Shift Left And Insert (Immediate)
 def SCALAR_SLI_N: SInst<"vsli_n", "sssi", "SlSUl">;
 
-// Signed/Unsigned Saturating Shift Right Narrow (Immediate)
-def SCALAR_SQSHRN_N: SInst<"vqshrn_n", "zsi", "SsSiSlSUsSUiSUl">;
-// Signed/Unsigned Saturating Rounded Shift Right Narrow (Immediate)
-def SCALAR_SQRSHRN_N: SInst<"vqrshrn_n", "zsi", "SsSiSlSUsSUiSUl">;
-// Signed Saturating Shift Right Unsigned Narrow (Immediate)
-def SCALAR_SQSHRUN_N: SInst<"vqshrun_n", "zsi", "SsSiSl">;
-// Signed Saturating Rounded Shift Right Unsigned Narrow (Immediate)
-def SCALAR_SQRSHRUN_N: SInst<"vqrshrun_n", "zsi", "SsSiSl">;
+let isScalarNarrowShift = 1 in {
+  // Signed/Unsigned Saturating Shift Right Narrow (Immediate)
+  def SCALAR_SQSHRN_N: SInst<"vqshrn_n", "zsi", "SsSiSlSUsSUiSUl">;
+  // Signed/Unsigned Saturating Rounded Shift Right Narrow (Immediate)
+  def SCALAR_SQRSHRN_N: SInst<"vqrshrn_n", "zsi", "SsSiSlSUsSUiSUl">;
+  // Signed Saturating Shift Right Unsigned Narrow (Immediate)
+  def SCALAR_SQSHRUN_N: SInst<"vqshrun_n", "zsi", "SsSiSl">;
+  // Signed Saturating Rounded Shift Right Unsigned Narrow (Immediate)
+  def SCALAR_SQRSHRUN_N: SInst<"vqrshrun_n", "zsi", "SsSiSl">;
+}
 
 ////////////////////////////////////////////////////////////////////////////////
 // Scalar Signed/Unsigned Fixed-point Convert To Floating-Point (Immediate)
@@ -1073,7 +1347,7 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 // Scalar Reduce Pairwise Addition (Scalar and Floating Point)
-def SCALAR_ADDP  : SInst<"vpadd", "sd", "SfSHlSHd">;
+def SCALAR_ADDP  : SInst<"vpadd", "sd", "SfSHlSHdSHUl">;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Scalar Reduce Floating Point Pairwise Max/Min
@@ -1117,6 +1391,30 @@
 def SCALAR_UCVTFD : SInst<"vcvt_f64", "os", "SUl">;
 
 ////////////////////////////////////////////////////////////////////////////////
+// Scalar Floating-point Converts
+def SCALAR_FCVTXN  : IInst<"vcvtx_f32", "ys", "Sd">;
+def SCALAR_FCVTNSS : SInst<"vcvtn_s32", "$s", "Sf">;
+def SCALAR_FCVTNUS : SInst<"vcvtn_u32", "bs", "Sf">;
+def SCALAR_FCVTNSD : SInst<"vcvtn_s64", "$s", "Sd">;
+def SCALAR_FCVTNUD : SInst<"vcvtn_u64", "bs", "Sd">;
+def SCALAR_FCVTMSS : SInst<"vcvtm_s32", "$s", "Sf">;
+def SCALAR_FCVTMUS : SInst<"vcvtm_u32", "bs", "Sf">;
+def SCALAR_FCVTMSD : SInst<"vcvtm_s64", "$s", "Sd">;
+def SCALAR_FCVTMUD : SInst<"vcvtm_u64", "bs", "Sd">;
+def SCALAR_FCVTASS : SInst<"vcvta_s32", "$s", "Sf">;
+def SCALAR_FCVTAUS : SInst<"vcvta_u32", "bs", "Sf">;
+def SCALAR_FCVTASD : SInst<"vcvta_s64", "$s", "Sd">;
+def SCALAR_FCVTAUD : SInst<"vcvta_u64", "bs", "Sd">;
+def SCALAR_FCVTPSS : SInst<"vcvtp_s32", "$s", "Sf">;
+def SCALAR_FCVTPUS : SInst<"vcvtp_u32", "bs", "Sf">;
+def SCALAR_FCVTPSD : SInst<"vcvtp_s64", "$s", "Sd">;
+def SCALAR_FCVTPUD : SInst<"vcvtp_u64", "bs", "Sd">;
+def SCALAR_FCVTZSS : SInst<"vcvt_s32", "$s", "Sf">;
+def SCALAR_FCVTZUS : SInst<"vcvt_u32", "bs", "Sf">;
+def SCALAR_FCVTZSD : SInst<"vcvt_s64", "$s", "Sd">;
+def SCALAR_FCVTZUD : SInst<"vcvt_u64", "bs", "Sd">;
+
+////////////////////////////////////////////////////////////////////////////////
 // Scalar Floating-point Reciprocal Estimate
 def SCALAR_FRECPE : IInst<"vrecpe", "ss", "SfSd">;
 
@@ -1172,6 +1470,10 @@
 def SCALAR_ABS : SInst<"vabs", "ss", "Sl">;
 
 ////////////////////////////////////////////////////////////////////////////////
+// Scalar Absolute Difference
+def SCALAR_ABD : IInst<"vabd", "sss", "SfSd">;
+
+////////////////////////////////////////////////////////////////////////////////
 // Scalar Signed Saturating Absolute Value
 def SCALAR_SQABS : SInst<"vqabs", "ss", "ScSsSiSl">;
 
@@ -1217,11 +1519,11 @@
 
 // Scalar Floating Point  multiply (scalar, by element)
 def SCALAR_FMUL_LANE : IOpInst<"vmul_lane", "ssdi", "SfSd", OP_SCALAR_MUL_LN>;
-def SCALAR_FMUL_LANEQ : IOpInst<"vmul_laneq", "ssji", "SfSd", OP_SCALAR_MUL_LNQ>;
+def SCALAR_FMUL_LANEQ : IOpInst<"vmul_laneq", "ssji", "SfSd", OP_SCALAR_MUL_LN>;
 
 // Scalar Floating Point  multiply extended (scalar, by element)
 def SCALAR_FMULX_LANE : IOpInst<"vmulx_lane", "ssdi", "SfSd", OP_SCALAR_MULX_LN>;
-def SCALAR_FMULX_LANEQ : IOpInst<"vmulx_laneq", "ssji", "SfSd", OP_SCALAR_MULX_LNQ>;
+def SCALAR_FMULX_LANEQ : IOpInst<"vmulx_laneq", "ssji", "SfSd", OP_SCALAR_MULX_LN>;
 
 def SCALAR_VMUL_N : IInst<"vmul_n", "dds", "d">;
 
@@ -1229,7 +1531,9 @@
 def SCALAR_VMUL_LANE : IInst<"vmul_lane", "ddgi", "d">;
 
 // VMUL_LANEQ d type implemented using scalar mul lane
-def SCALAR_VMUL_LANEQ   : IInst<"vmul_laneq", "ddji", "d">;
+def SCALAR_VMUL_LANEQ   : IInst<"vmul_laneq", "ddji", "d"> {
+  let isLaneQ = 1;
+}
 
 // VMULX_LANE d type implemented using scalar vmulx_lane
 def SCALAR_VMULX_LANE : IOpInst<"vmulx_lane", "ddgi", "d", OP_SCALAR_VMULX_LN>;
@@ -1244,4 +1548,33 @@
 // Scalar Floating Point fused multiply-subtract (scalar, by element)
 def SCALAR_FMLS_LANE : IOpInst<"vfms_lane", "sssdi", "SfSd", OP_FMS_LN>;
 def SCALAR_FMLS_LANEQ : IOpInst<"vfms_laneq", "sssji", "SfSd", OP_FMS_LNQ>;
+
+// Signed Saturating Doubling Multiply Long (scalar by element)
+def SCALAR_SQDMULL_LANE : SOpInst<"vqdmull_lane", "rsdi", "SsSi", OP_SCALAR_QDMULL_LN>;
+def SCALAR_SQDMULL_LANEQ : SOpInst<"vqdmull_laneq", "rsji", "SsSi", OP_SCALAR_QDMULL_LN>;
+
+// Signed Saturating Doubling Multiply-Add Long (scalar by element)
+def SCALAR_SQDMLAL_LANE : SInst<"vqdmlal_lane", "rrsdi", "SsSi">;
+def SCALAR_SQDMLAL_LANEQ : SInst<"vqdmlal_laneq", "rrsji", "SsSi">;
+
+// Signed Saturating Doubling Multiply-Subtract Long (scalar by element)
+def SCALAR_SQDMLS_LANE : SInst<"vqdmlsl_lane", "rrsdi", "SsSi">;
+def SCALAR_SQDMLS_LANEQ : SInst<"vqdmlsl_laneq", "rrsji", "SsSi">;
+
+// Scalar Integer Saturating Doubling Multiply Half High (scalar by element)
+def SCALAR_SQDMULH_LANE : SOpInst<"vqdmulh_lane", "ssdi", "SsSi", OP_SCALAR_QDMULH_LN>;
+def SCALAR_SQDMULH_LANEQ : SOpInst<"vqdmulh_laneq", "ssji", "SsSi", OP_SCALAR_QDMULH_LN>;
+
+// Scalar Integer Saturating Rounding Doubling Multiply Half High
+def SCALAR_SQRDMULH_LANE : SOpInst<"vqrdmulh_lane", "ssdi", "SsSi", OP_SCALAR_QRDMULH_LN>;
+def SCALAR_SQRDMULH_LANEQ : SOpInst<"vqrdmulh_laneq", "ssji", "SsSi", OP_SCALAR_QRDMULH_LN>;
+
+def SCALAR_VDUP_LANE : IInst<"vdup_lane", "sdi", "ScSsSiSlSfSdSUcSUsSUiSUlSPcSPs">;
+def SCALAR_VDUP_LANEQ : IInst<"vdup_laneq", "sji", "ScSsSiSlSfSdSUcSUsSUiSUlSPcSPs">;
+
+// FIXME: Rename so it is obvious this only applies to halfs.
+def SCALAR_HALF_GET_LANE : IOpInst<"vget_lane", "sdi", "h", OP_SCALAR_HALF_GET_LN>;
+def SCALAR_HALF_SET_LANE : IOpInst<"vset_lane", "dsdi", "h", OP_SCALAR_HALF_SET_LN>;
+def SCALAR_HALF_GET_LANEQ : IOpInst<"vget_lane", "sdi", "Qh", OP_SCALAR_HALF_GET_LNQ>;
+def SCALAR_HALF_SET_LANEQ : IOpInst<"vset_lane", "dsdi", "Qh", OP_SCALAR_HALF_SET_LNQ>;
 }
diff --git a/include/clang/CMakeLists.txt b/include/clang/CMakeLists.txt
index 71c37fd..1d8aecd 100644
--- a/include/clang/CMakeLists.txt
+++ b/include/clang/CMakeLists.txt
@@ -1,7 +1,6 @@
 add_subdirectory(AST)
 add_subdirectory(Basic)
 add_subdirectory(Driver)
-add_subdirectory(Lex)
 add_subdirectory(Parse)
 add_subdirectory(Sema)
 add_subdirectory(Serialization)
diff --git a/include/clang/CodeGen/BackendUtil.h b/include/clang/CodeGen/BackendUtil.h
index 135b6a9..f8b90b3 100644
--- a/include/clang/CodeGen/BackendUtil.h
+++ b/include/clang/CodeGen/BackendUtil.h
@@ -21,7 +21,7 @@
   class CodeGenOptions;
   class TargetOptions;
   class LangOptions;
-  
+
   enum BackendAction {
     Backend_EmitAssembly,  ///< Emit native assembly files
     Backend_EmitBC,        ///< Emit LLVM bitcode files
@@ -30,11 +30,11 @@
     Backend_EmitMCNull,    ///< Run CodeGen, but don't emit anything
     Backend_EmitObj        ///< Emit native object files
   };
-  
+
   void EmitBackendOutput(DiagnosticsEngine &Diags, const CodeGenOptions &CGOpts,
                          const TargetOptions &TOpts, const LangOptions &LOpts,
-                         llvm::Module *M,
-                         BackendAction Action, raw_ostream *OS);
+                         StringRef TDesc, llvm::Module *M, BackendAction Action,
+                         raw_ostream *OS);
 }
 
 #endif
diff --git a/include/clang/CodeGen/CGFunctionInfo.h b/include/clang/CodeGen/CGFunctionInfo.h
index 96da0e9..449827e 100644
--- a/include/clang/CodeGen/CGFunctionInfo.h
+++ b/include/clang/CodeGen/CGFunctionInfo.h
@@ -19,21 +19,23 @@
 #include "clang/AST/CanonicalType.h"
 #include "clang/AST/Type.h"
 #include "llvm/ADT/FoldingSet.h"
-
 #include <cassert>
 
 namespace llvm {
   class Type;
+  class StructType;
 }
 
 namespace clang {
+class Decl;
+
 namespace CodeGen {
 
 /// ABIArgInfo - Helper class to encapsulate information about how a
 /// specific C type should be passed to or returned from a function.
 class ABIArgInfo {
 public:
-  enum Kind {
+  enum Kind : uint8_t {
     /// Direct - Pass the argument directly using the normal converted LLVM
     /// type, or by coercing to another specified type stored in
     /// 'CoerceToType').  If an offset is specified (in UIntData), then the
@@ -60,86 +62,130 @@
     /// are all scalar types or are themselves expandable types.
     Expand,
 
-    KindFirst=Direct, KindLast=Expand
+    /// InAlloca - Pass the argument directly using the LLVM inalloca attribute.
+    /// This is similar to 'direct', except it only applies to arguments stored
+    /// in memory and forbids any implicit copies.  When applied to a return
+    /// type, it means the value is returned indirectly via an implicit sret
+    /// parameter stored in the argument struct.
+    InAlloca,
+    KindFirst = Direct,
+    KindLast = InAlloca
   };
 
 private:
-  Kind TheKind;
-  llvm::Type *TypeData;
+  llvm::Type *TypeData; // isDirect() || isExtend()
   llvm::Type *PaddingType;
-  unsigned UIntData;
-  bool BoolData0;
-  bool BoolData1;
-  bool InReg;
-  bool PaddingInReg;
+  union {
+    unsigned DirectOffset;     // isDirect() || isExtend()
+    unsigned IndirectAlign;    // isIndirect()
+    unsigned AllocaFieldIndex; // isInAlloca()
+  };
+  Kind TheKind;
+  bool PaddingInReg : 1;
+  bool InAllocaSRet : 1;    // isInAlloca()
+  bool IndirectByVal : 1;   // isIndirect()
+  bool IndirectRealign : 1; // isIndirect()
+  bool SRetAfterThis : 1;   // isIndirect()
+  bool InReg : 1;           // isDirect() || isExtend() || isIndirect()
 
-  ABIArgInfo(Kind K, llvm::Type *TD, unsigned UI, bool B0, bool B1, bool IR,
-             bool PIR, llvm::Type* P)
-    : TheKind(K), TypeData(TD), PaddingType(P), UIntData(UI), BoolData0(B0),
-      BoolData1(B1), InReg(IR), PaddingInReg(PIR) {}
+  ABIArgInfo(Kind K)
+      : PaddingType(nullptr), TheKind(K), PaddingInReg(false), InReg(false) {}
 
 public:
-  ABIArgInfo() : TheKind(Direct), TypeData(0), UIntData(0) {}
+  ABIArgInfo()
+      : TypeData(nullptr), PaddingType(nullptr), DirectOffset(0),
+        TheKind(Direct), PaddingInReg(false), InReg(false) {}
 
-  static ABIArgInfo getDirect(llvm::Type *T = 0, unsigned Offset = 0,
-                              llvm::Type *Padding = 0) {
-    return ABIArgInfo(Direct, T, Offset, false, false, false, false, Padding);
+  static ABIArgInfo getDirect(llvm::Type *T = nullptr, unsigned Offset = 0,
+                              llvm::Type *Padding = nullptr) {
+    auto AI = ABIArgInfo(Direct);
+    AI.setCoerceToType(T);
+    AI.setDirectOffset(Offset);
+    AI.setPaddingType(Padding);
+    return AI;
   }
-  static ABIArgInfo getDirectInReg(llvm::Type *T = 0) {
-    return ABIArgInfo(Direct, T, 0, false, false, true, false, 0);
+  static ABIArgInfo getDirectInReg(llvm::Type *T = nullptr) {
+    auto AI = getDirect(T);
+    AI.setInReg(true);
+    return AI;
   }
-  static ABIArgInfo getExtend(llvm::Type *T = 0) {
-    return ABIArgInfo(Extend, T, 0, false, false, false, false, 0);
+  static ABIArgInfo getExtend(llvm::Type *T = nullptr) {
+    auto AI = ABIArgInfo(Extend);
+    AI.setCoerceToType(T);
+    AI.setDirectOffset(0);
+    return AI;
   }
-  static ABIArgInfo getExtendInReg(llvm::Type *T = 0) {
-    return ABIArgInfo(Extend, T, 0, false, false, true, false, 0);
+  static ABIArgInfo getExtendInReg(llvm::Type *T = nullptr) {
+    auto AI = getExtend(T);
+    AI.setInReg(true);
+    return AI;
   }
   static ABIArgInfo getIgnore() {
-    return ABIArgInfo(Ignore, 0, 0, false, false, false, false, 0);
+    return ABIArgInfo(Ignore);
   }
-  static ABIArgInfo getIndirect(unsigned Alignment, bool ByVal = true
-                                , bool Realign = false
-                                , llvm::Type *Padding = 0) {
-    return ABIArgInfo(Indirect, 0, Alignment, ByVal, Realign, false, false,
-                      Padding);
+  static ABIArgInfo getIndirect(unsigned Alignment, bool ByVal = true,
+                                bool Realign = false,
+                                llvm::Type *Padding = nullptr) {
+    auto AI = ABIArgInfo(Indirect);
+    AI.setIndirectAlign(Alignment);
+    AI.setIndirectByVal(ByVal);
+    AI.setIndirectRealign(Realign);
+    AI.setSRetAfterThis(false);
+    AI.setPaddingType(Padding);
+    return AI;
   }
-  static ABIArgInfo getIndirectInReg(unsigned Alignment, bool ByVal = true
-                                , bool Realign = false) {
-    return ABIArgInfo(Indirect, 0, Alignment, ByVal, Realign, true, false, 0);
+  static ABIArgInfo getIndirectInReg(unsigned Alignment, bool ByVal = true,
+                                     bool Realign = false) {
+    auto AI = getIndirect(Alignment, ByVal, Realign);
+    AI.setInReg(true);
+    return AI;
+  }
+  static ABIArgInfo getInAlloca(unsigned FieldIndex) {
+    auto AI = ABIArgInfo(InAlloca);
+    AI.setInAllocaFieldIndex(FieldIndex);
+    return AI;
   }
   static ABIArgInfo getExpand() {
-    return ABIArgInfo(Expand, 0, 0, false, false, false, false, 0);
+    return ABIArgInfo(Expand);
   }
   static ABIArgInfo getExpandWithPadding(bool PaddingInReg,
                                          llvm::Type *Padding) {
-   return ABIArgInfo(Expand, 0, 0, false, false, false, PaddingInReg,
-                     Padding);
+    auto AI = getExpand();
+    AI.setPaddingInReg(PaddingInReg);
+    AI.setPaddingType(Padding);
+    return AI;
   }
 
   Kind getKind() const { return TheKind; }
   bool isDirect() const { return TheKind == Direct; }
+  bool isInAlloca() const { return TheKind == InAlloca; }
   bool isExtend() const { return TheKind == Extend; }
   bool isIgnore() const { return TheKind == Ignore; }
   bool isIndirect() const { return TheKind == Indirect; }
   bool isExpand() const { return TheKind == Expand; }
 
-  bool canHaveCoerceToType() const {
-    return TheKind == Direct || TheKind == Extend;
-  }
+  bool canHaveCoerceToType() const { return isDirect() || isExtend(); }
 
   // Direct/Extend accessors
   unsigned getDirectOffset() const {
     assert((isDirect() || isExtend()) && "Not a direct or extend kind");
-    return UIntData;
+    return DirectOffset;
+  }
+  void setDirectOffset(unsigned Offset) {
+    assert((isDirect() || isExtend()) && "Not a direct or extend kind");
+    DirectOffset = Offset;
   }
 
-  llvm::Type *getPaddingType() const {
-    return PaddingType;
-  }
+  llvm::Type *getPaddingType() const { return PaddingType; }
+
+  void setPaddingType(llvm::Type *T) { PaddingType = T; }
 
   bool getPaddingInReg() const {
     return PaddingInReg;
   }
+  void setPaddingInReg(bool PIR) {
+    PaddingInReg = PIR;
+  }
 
   llvm::Type *getCoerceToType() const {
     assert(canHaveCoerceToType() && "Invalid kind!");
@@ -156,20 +202,67 @@
     return InReg;
   }
 
+  void setInReg(bool IR) {
+    assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!");
+    InReg = IR;
+  }
+
   // Indirect accessors
   unsigned getIndirectAlign() const {
-    assert(TheKind == Indirect && "Invalid kind!");
-    return UIntData;
+    assert(isIndirect() && "Invalid kind!");
+    return IndirectAlign;
+  }
+  void setIndirectAlign(unsigned IA) {
+    assert(isIndirect() && "Invalid kind!");
+    IndirectAlign = IA;
   }
 
   bool getIndirectByVal() const {
-    assert(TheKind == Indirect && "Invalid kind!");
-    return BoolData0;
+    assert(isIndirect() && "Invalid kind!");
+    return IndirectByVal;
+  }
+  void setIndirectByVal(unsigned IBV) {
+    assert(isIndirect() && "Invalid kind!");
+    IndirectByVal = IBV;
   }
 
   bool getIndirectRealign() const {
-    assert(TheKind == Indirect && "Invalid kind!");
-    return BoolData1;
+    assert(isIndirect() && "Invalid kind!");
+    return IndirectRealign;
+  }
+  void setIndirectRealign(bool IR) {
+    assert(isIndirect() && "Invalid kind!");
+    IndirectRealign = IR;
+  }
+
+  bool isSRetAfterThis() const {
+    assert(isIndirect() && "Invalid kind!");
+    return SRetAfterThis;
+  }
+  void setSRetAfterThis(bool AfterThis) {
+    assert(isIndirect() && "Invalid kind!");
+    SRetAfterThis = AfterThis;
+  }
+
+  unsigned getInAllocaFieldIndex() const {
+    assert(isInAlloca() && "Invalid kind!");
+    return AllocaFieldIndex;
+  }
+  void setInAllocaFieldIndex(unsigned FieldIndex) {
+    assert(isInAlloca() && "Invalid kind!");
+    AllocaFieldIndex = FieldIndex;
+  }
+
+  /// \brief Return true if this field of an inalloca struct should be returned
+  /// to implement a struct return calling convention.
+  bool getInAllocaSRet() const {
+    assert(isInAlloca() && "Invalid kind!");
+    return InAllocaSRet;
+  }
+
+  void setInAllocaSRet(bool SRet) {
+    assert(isInAlloca() && "Invalid kind!");
+    InAllocaSRet = SRet;
   }
 
   void dump() const;
@@ -195,7 +288,7 @@
   static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype,
                                        unsigned additional) {
     if (!prototype->isVariadic()) return All;
-    return RequiredArgs(prototype->getNumArgs() + additional);
+    return RequiredArgs(prototype->getNumParams() + additional);
   }
 
   static RequiredArgs forPrototype(const FunctionProtoType *prototype) {
@@ -243,6 +336,9 @@
   /// The clang::CallingConv that this was originally created with.
   unsigned ASTCallingConvention : 8;
 
+  /// Whether this is an instance method.
+  unsigned InstanceMethod : 1;
+
   /// Whether this function is noreturn.
   unsigned NoReturn : 1;
 
@@ -255,6 +351,10 @@
 
   RequiredArgs Required;
 
+  /// The struct representing all arguments passed in memory.  Only used when
+  /// passing non-trivial types with inalloca.  Not part of the profile.
+  llvm::StructType *ArgStruct;
+
   unsigned NumArgs;
   ArgInfo *getArgsBuffer() {
     return reinterpret_cast<ArgInfo*>(this+1);
@@ -267,6 +367,7 @@
 
 public:
   static CGFunctionInfo *create(unsigned llvmCC,
+                                bool InstanceMethod,
                                 const FunctionType::ExtInfo &extInfo,
                                 CanQualType resultType,
                                 ArrayRef<CanQualType> argTypes,
@@ -275,6 +376,14 @@
   typedef const ArgInfo *const_arg_iterator;
   typedef ArgInfo *arg_iterator;
 
+  typedef llvm::iterator_range<arg_iterator> arg_range;
+  typedef llvm::iterator_range<const_arg_iterator> arg_const_range;
+
+  arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
+  arg_const_range arguments() const {
+    return arg_const_range(arg_begin(), arg_end());
+  }
+
   const_arg_iterator arg_begin() const { return getArgsBuffer() + 1; }
   const_arg_iterator arg_end() const { return getArgsBuffer() + 1 + NumArgs; }
   arg_iterator arg_begin() { return getArgsBuffer() + 1; }
@@ -285,6 +394,8 @@
   bool isVariadic() const { return Required.allowsOptionalArgs(); }
   RequiredArgs getRequiredArgs() const { return Required; }
 
+  bool isInstanceMethod() const { return InstanceMethod; }
+
   bool isNoReturn() const { return NoReturn; }
 
   /// In ARC, whether this function retains its return value.  This
@@ -325,23 +436,33 @@
   ABIArgInfo &getReturnInfo() { return getArgsBuffer()[0].info; }
   const ABIArgInfo &getReturnInfo() const { return getArgsBuffer()[0].info; }
 
+  /// \brief Return true if this function uses inalloca arguments.
+  bool usesInAlloca() const { return ArgStruct; }
+
+  /// \brief Get the struct type used to represent all the arguments in memory.
+  llvm::StructType *getArgStruct() const { return ArgStruct; }
+  void setArgStruct(llvm::StructType *Ty) { ArgStruct = Ty; }
+
   void Profile(llvm::FoldingSetNodeID &ID) {
     ID.AddInteger(getASTCallingConvention());
+    ID.AddBoolean(InstanceMethod);
     ID.AddBoolean(NoReturn);
     ID.AddBoolean(ReturnsRetained);
     ID.AddBoolean(HasRegParm);
     ID.AddInteger(RegParm);
     ID.AddInteger(Required.getOpaqueData());
     getReturnType().Profile(ID);
-    for (arg_iterator it = arg_begin(), ie = arg_end(); it != ie; ++it)
-      it->type.Profile(ID);
+    for (const auto &I : arguments())
+      I.type.Profile(ID);
   }
   static void Profile(llvm::FoldingSetNodeID &ID,
+                      bool InstanceMethod,
                       const FunctionType::ExtInfo &info,
                       RequiredArgs required,
                       CanQualType resultType,
                       ArrayRef<CanQualType> argTypes) {
     ID.AddInteger(info.getCC());
+    ID.AddBoolean(InstanceMethod);
     ID.AddBoolean(info.getNoReturn());
     ID.AddBoolean(info.getProducesResult());
     ID.AddBoolean(info.getHasRegParm());
diff --git a/include/clang/CodeGen/CodeGenABITypes.h b/include/clang/CodeGen/CodeGenABITypes.h
index 81e2cdc..2502982 100644
--- a/include/clang/CodeGen/CodeGenABITypes.h
+++ b/include/clang/CodeGen/CodeGenABITypes.h
@@ -47,10 +47,7 @@
 class CodeGenABITypes
 {
 public:
-  CodeGenABITypes(ASTContext &C, const CodeGenOptions &CodeGenOpts,
-                  llvm::Module &M, const llvm::DataLayout &TD,
-                  DiagnosticsEngine &Diags);
-
+  CodeGenABITypes(ASTContext &C, llvm::Module &M, const llvm::DataLayout &TD);
   ~CodeGenABITypes();
 
   /// These methods all forward to methods in the private implementation class
@@ -65,12 +62,18 @@
                                              CanQual<FunctionNoProtoType> Ty);
   const CGFunctionInfo &arrangeCXXMethodType(const CXXRecordDecl *RD,
                                              const FunctionProtoType *FTP);
-  const CGFunctionInfo &arrangeLLVMFunctionInfo(CanQualType returnType,
-                                         llvm::ArrayRef<CanQualType> argTypes,
-                                         FunctionType::ExtInfo info,
-                                         RequiredArgs args);
+  const CGFunctionInfo &arrangeFreeFunctionCall(CanQualType returnType,
+                                                ArrayRef<CanQualType> argTypes,
+                                                FunctionType::ExtInfo info,
+                                                RequiredArgs args);
 
 private:
+  /// Default CodeGenOptions object used to initialize the
+  /// CodeGenModule and otherwise not used. More specifically, it is
+  /// not used in ABI type generation, so none of the options matter.
+  CodeGenOptions *CGO;
+
+  /// The CodeGenModule we use get to the CodeGenTypes object.
   CodeGen::CodeGenModule *CGM;
 };
 
diff --git a/include/clang/CodeGen/CodeGenAction.h b/include/clang/CodeGen/CodeGenAction.h
index 912ef01..37819c7 100644
--- a/include/clang/CodeGen/CodeGenAction.h
+++ b/include/clang/CodeGen/CodeGenAction.h
@@ -11,7 +11,7 @@
 #define LLVM_CLANG_CODEGEN_CODE_GEN_ACTION_H
 
 #include "clang/Frontend/FrontendAction.h"
-#include "llvm/ADT/OwningPtr.h"
+#include <memory>
 
 namespace llvm {
   class LLVMContext;
@@ -24,7 +24,7 @@
 class CodeGenAction : public ASTFrontendAction {
 private:
   unsigned Act;
-  OwningPtr<llvm::Module> TheModule;
+  std::unique_ptr<llvm::Module> TheModule;
   llvm::Module *LinkModule;
   llvm::LLVMContext *VMContext;
   bool OwnsVMContext;
@@ -33,16 +33,16 @@
   /// Create a new code generation action.  If the optional \p _VMContext
   /// parameter is supplied, the action uses it without taking ownership,
   /// otherwise it creates a fresh LLVM context and takes ownership.
-  CodeGenAction(unsigned _Act, llvm::LLVMContext *_VMContext = 0);
+  CodeGenAction(unsigned _Act, llvm::LLVMContext *_VMContext = nullptr);
 
-  virtual bool hasIRSupport() const;
+  bool hasIRSupport() const override;
 
-  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
-                                         StringRef InFile);
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
 
-  virtual void ExecuteAction();
+  void ExecuteAction() override;
 
-  virtual void EndSourceFileAction();
+  void EndSourceFileAction() override;
 
 public:
   ~CodeGenAction();
@@ -65,37 +65,37 @@
 class EmitAssemblyAction : public CodeGenAction {
   virtual void anchor();
 public:
-  EmitAssemblyAction(llvm::LLVMContext *_VMContext = 0);
+  EmitAssemblyAction(llvm::LLVMContext *_VMContext = nullptr);
 };
 
 class EmitBCAction : public CodeGenAction {
   virtual void anchor();
 public:
-  EmitBCAction(llvm::LLVMContext *_VMContext = 0);
+  EmitBCAction(llvm::LLVMContext *_VMContext = nullptr);
 };
 
 class EmitLLVMAction : public CodeGenAction {
   virtual void anchor();
 public:
-  EmitLLVMAction(llvm::LLVMContext *_VMContext = 0);
+  EmitLLVMAction(llvm::LLVMContext *_VMContext = nullptr);
 };
 
 class EmitLLVMOnlyAction : public CodeGenAction {
   virtual void anchor();
 public:
-  EmitLLVMOnlyAction(llvm::LLVMContext *_VMContext = 0);
+  EmitLLVMOnlyAction(llvm::LLVMContext *_VMContext = nullptr);
 };
 
 class EmitCodeGenOnlyAction : public CodeGenAction {
   virtual void anchor();
 public:
-  EmitCodeGenOnlyAction(llvm::LLVMContext *_VMContext = 0);
+  EmitCodeGenOnlyAction(llvm::LLVMContext *_VMContext = nullptr);
 };
 
 class EmitObjAction : public CodeGenAction {
   virtual void anchor();
 public:
-  EmitObjAction(llvm::LLVMContext *_VMContext = 0);
+  EmitObjAction(llvm::LLVMContext *_VMContext = nullptr);
 };
 
 }
diff --git a/include/clang/CodeGen/ModuleBuilder.h b/include/clang/CodeGen/ModuleBuilder.h
index cda7863..4b7236b 100644
--- a/include/clang/CodeGen/ModuleBuilder.h
+++ b/include/clang/CodeGen/ModuleBuilder.h
@@ -27,12 +27,14 @@
   class LangOptions;
   class CodeGenOptions;
   class TargetOptions;
+  class Decl;
 
   class CodeGenerator : public ASTConsumer {
     virtual void anchor();
   public:
     virtual llvm::Module* GetModule() = 0;
     virtual llvm::Module* ReleaseModule() = 0;
+    virtual const Decl *GetDeclForMangledName(llvm::StringRef MangledName) = 0;
   };
 
   /// CreateLLVMCodeGen - Create a CodeGenerator instance.
diff --git a/include/clang/Config/config.h.cmake b/include/clang/Config/config.h.cmake
index c18c4cc..7629ef9 100644
--- a/include/clang/Config/config.h.cmake
+++ b/include/clang/Config/config.h.cmake
@@ -1,3 +1,10 @@
+/* This generated file is for internal use. Do not include it from headers. */
+
+#ifdef CONFIG_H
+#error config.h can only be included once
+#else
+#define CONFIG_H
+
 /* Bug report URL. */
 #define BUG_REPORT_URL "${BUG_REPORT_URL}"
 
@@ -12,3 +19,11 @@
 
 /* Directory where gcc is installed. */
 #define GCC_INSTALL_PREFIX "${GCC_INSTALL_PREFIX}"
+
+/* Define if we have libxml2 */
+#cmakedefine CLANG_HAVE_LIBXML ${CLANG_HAVE_LIBXML}
+
+/* The LLVM product name and version */
+#define BACKEND_PACKAGE_STRING "${BACKEND_PACKAGE_STRING}"
+
+#endif
diff --git a/include/clang/Config/config.h.in b/include/clang/Config/config.h.in
index 8ff9417..1530fef 100644
--- a/include/clang/Config/config.h.in
+++ b/include/clang/Config/config.h.in
@@ -1,6 +1,8 @@
-/* include/clang/Config/config.h.in. */
+/* This generated file is for internal use. Do not include it from headers. */
 
-#ifndef CONFIG_H
+#ifdef CONFIG_H
+#error config.h can only be included once
+#else
 #define CONFIG_H
 
 /* Bug report URL. */
@@ -21,4 +23,12 @@
 /* Directory where gcc is installed. */
 #undef GCC_INSTALL_PREFIX
 
+/* Define if we have libxml2 */
+#undef CLANG_HAVE_LIBXML
+
+#undef PACKAGE_STRING
+
+/* The LLVM product name and version */
+#define BACKEND_PACKAGE_STRING PACKAGE_STRING
+
 #endif
diff --git a/include/clang/Driver/Action.h b/include/clang/Driver/Action.h
index 289dbe3..2cdb581 100644
--- a/include/clang/Driver/Action.h
+++ b/include/clang/Driver/Action.h
@@ -50,10 +50,11 @@
     LinkJobClass,
     LipoJobClass,
     DsymutilJobClass,
-    VerifyJobClass,
+    VerifyDebugInfoJobClass,
+    VerifyPCHJobClass,
 
     JobClassFirst=PreprocessJobClass,
-    JobClassLast=VerifyJobClass
+    JobClassLast=VerifyPCHJobClass
   };
 
   static const char *getClassName(ActionClass AC);
@@ -141,7 +142,7 @@
 };
 
 class PreprocessJobAction : public JobAction {
-  virtual void anchor();
+  void anchor() override;
 public:
   PreprocessJobAction(Action *Input, types::ID OutputType);
 
@@ -151,7 +152,7 @@
 };
 
 class PrecompileJobAction : public JobAction {
-  virtual void anchor();
+  void anchor() override;
 public:
   PrecompileJobAction(Action *Input, types::ID OutputType);
 
@@ -161,7 +162,7 @@
 };
 
 class AnalyzeJobAction : public JobAction {
-  virtual void anchor();
+  void anchor() override;
 public:
   AnalyzeJobAction(Action *Input, types::ID OutputType);
 
@@ -171,7 +172,7 @@
 };
 
 class MigrateJobAction : public JobAction {
-  virtual void anchor();
+  void anchor() override;
 public:
   MigrateJobAction(Action *Input, types::ID OutputType);
 
@@ -181,7 +182,7 @@
 };
 
 class CompileJobAction : public JobAction {
-  virtual void anchor();
+  void anchor() override;
 public:
   CompileJobAction(Action *Input, types::ID OutputType);
 
@@ -191,7 +192,7 @@
 };
 
 class AssembleJobAction : public JobAction {
-  virtual void anchor();
+  void anchor() override;
 public:
   AssembleJobAction(Action *Input, types::ID OutputType);
 
@@ -201,7 +202,7 @@
 };
 
 class LinkJobAction : public JobAction {
-  virtual void anchor();
+  void anchor() override;
 public:
   LinkJobAction(ActionList &Inputs, types::ID Type);
 
@@ -211,7 +212,7 @@
 };
 
 class LipoJobAction : public JobAction {
-  virtual void anchor();
+  void anchor() override;
 public:
   LipoJobAction(ActionList &Inputs, types::ID Type);
 
@@ -221,7 +222,7 @@
 };
 
 class DsymutilJobAction : public JobAction {
-  virtual void anchor();
+  void anchor() override;
 public:
   DsymutilJobAction(ActionList &Inputs, types::ID Type);
 
@@ -231,11 +232,31 @@
 };
 
 class VerifyJobAction : public JobAction {
-  virtual void anchor();
+  void anchor() override;
 public:
-  VerifyJobAction(ActionList &Inputs, types::ID Type);
+  VerifyJobAction(ActionClass Kind, Action *Input, types::ID Type);
+  VerifyJobAction(ActionClass Kind, ActionList &Inputs, types::ID Type);
   static bool classof(const Action *A) {
-    return A->getKind() == VerifyJobClass;
+    return A->getKind() == VerifyDebugInfoJobClass ||
+           A->getKind() == VerifyPCHJobClass;
+  }
+};
+
+class VerifyDebugInfoJobAction : public VerifyJobAction {
+  void anchor() override;
+public:
+  VerifyDebugInfoJobAction(Action *Input, types::ID Type);
+  static bool classof(const Action *A) {
+    return A->getKind() == VerifyDebugInfoJobClass;
+  }
+};
+
+class VerifyPCHJobAction : public VerifyJobAction {
+  void anchor() override;
+public:
+  VerifyPCHJobAction(Action *Input, types::ID Type);
+  static bool classof(const Action *A) {
+    return A->getKind() == VerifyPCHJobClass;
   }
 };
 
diff --git a/include/clang/Driver/CC1AsOptions.h b/include/clang/Driver/CC1AsOptions.h
deleted file mode 100644
index 345f50a..0000000
--- a/include/clang/Driver/CC1AsOptions.h
+++ /dev/null
@@ -1,37 +0,0 @@
-//===--- CC1AsOptions.h - Clang Assembler Options Table ---------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef CLANG_DRIVER_CC1ASOPTIONS_H
-#define CLANG_DRIVER_CC1ASOPTIONS_H
-
-namespace llvm {
-namespace opt {
-  class OptTable;
-}
-}
-
-namespace clang {
-namespace driver {
-
-namespace cc1asoptions {
-  enum ID {
-    OPT_INVALID = 0, // This is not an option ID.
-#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
-               HELPTEXT, METAVAR) OPT_##ID,
-#include "clang/Driver/CC1AsOptions.inc"
-    LastOption
-#undef OPTION
-  };
-}
-
-llvm::opt::OptTable *createCC1AsOptTable();
-}
-}
-
-#endif
diff --git a/include/clang/Driver/CC1AsOptions.td b/include/clang/Driver/CC1AsOptions.td
deleted file mode 100644
index b536724..0000000
--- a/include/clang/Driver/CC1AsOptions.td
+++ /dev/null
@@ -1,95 +0,0 @@
-//===--- CC1AsOptions.td - Options for clang -cc1as -----------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-//  This file defines the options accepted by clang -cc1as.
-//
-//===----------------------------------------------------------------------===//
-
-// Include the common option parsing interfaces.
-include "llvm/Option/OptParser.td"
-
-//===----------------------------------------------------------------------===//
-// Target Options
-//===----------------------------------------------------------------------===//
-
-def triple : Separate<["-"], "triple">,
-  HelpText<"Specify target triple (e.g. x86_64-pc-linux-gnu)">;
-def target_cpu : Separate<["-"], "target-cpu">,
-  HelpText<"Target a specific cpu type">;
-def target_feature : Separate<["-"], "target-feature">,
-  HelpText<"Target specific attributes">;
-
-//===----------------------------------------------------------------------===//
-// Language Options
-//===----------------------------------------------------------------------===//
-
-def I : JoinedOrSeparate<["-"], "I">, MetaVarName<"<directory>">,
-  HelpText<"Add directory to include search path">;
-def n : Flag<["-"], "n">,
-  HelpText<"Don't automatically start assembly file with a text section">;
-def msave_temp_labels : Flag<["-"], "msave-temp-labels">,
-  HelpText<"Save temporary labels in the symbol table. "
-           "Note this may change .s semantics, it should almost never be used "
-           "on compiler generated code!">;
-def main_file_name : Separate<["-"], "main-file-name">,
-  HelpText<"Main file name to use for debug info">;
-
-//===----------------------------------------------------------------------===//
-// Frontend Options
-//===----------------------------------------------------------------------===//
-
-def o : Separate<["-"], "o">, MetaVarName<"<path>">,
-  HelpText<"Specify output file">;
-
-def filetype : Separate<["-"], "filetype">,
-    HelpText<"Specify the output file type ('asm', 'null', or 'obj')">;
-
-def help : Flag<["-", "--"], "help">,
-  HelpText<"Print this help text">;
-
-def version : Flag<["-", "--"], "version">,
-  HelpText<"Print the assembler version">;
-def v : Flag<["-"], "v">, Alias<version>;
-
-// Generic forwarding to LLVM options. This should only be used for debugging
-// and experimental features.
-def mllvm : Separate<["-"], "mllvm">,
-  HelpText<"Additional arguments to forward to LLVM's option processing">;
-
-//===----------------------------------------------------------------------===//
-// Transliterate Options
-//===----------------------------------------------------------------------===//
-
-def output_asm_variant : Separate<["-"], "output-asm-variant">,
-    HelpText<"Select the asm variant index to use for output">;
-def show_encoding : Flag<["-"], "show-encoding">,
-    HelpText<"Show instruction encoding information in transliterate mode">;
-def show_inst : Flag<["-"], "show-inst">,
-    HelpText<"Show internal instruction representation in transliterate mode">;
-
-//===----------------------------------------------------------------------===//
-// Assemble Options
-//===----------------------------------------------------------------------===//
-
-def mrelax_all : Flag<["-"], "mrelax-all">,
-    HelpText<"Relax all fixups (for performance testing)">;
-
-def mno_exec_stack : Flag<["-"], "mnoexecstack">,
-    HelpText<"Mark the file as not needing an executable stack">;
-
-def g : Flag<["-"], "g">, HelpText<"Generate source level debug information">;
-
-def fdebug_compilation_dir : Separate<["-"], "fdebug-compilation-dir">,
-  HelpText<"The compilation directory to embed in the debug info.">;
-
-def dwarf_debug_flags : Separate<["-"], "dwarf-debug-flags">,
-  HelpText<"The string to embed in the Dwarf debug flags record.">;
-
-def dwarf_debug_producer : Separate<["-"], "dwarf-debug-producer">,
-  HelpText<"The string to embed in the Dwarf debug AT_producer record.">;
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index 85cfdcf..d25560c 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -7,7 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
-//  This file defines the options accepted by clang -cc1.
+//  This file defines the options accepted by clang -cc1 and clang -cc1as.
 //
 //===----------------------------------------------------------------------===//
 
@@ -17,21 +17,24 @@
 // Target Options
 //===----------------------------------------------------------------------===//
 
-def cxx_abi : Separate<["-"], "cxx-abi">,
-  HelpText<"Target a particular C++ ABI type">;
-def target_abi : Separate<["-"], "target-abi">,
-  HelpText<"Target a particular ABI type">;
+let Flags = [CC1Option, CC1AsOption, NoDriverOption] in {
+
 def target_cpu : Separate<["-"], "target-cpu">,
   HelpText<"Target a specific cpu type">;
-def mfpmath : Separate<["-"], "mfpmath">,
-  HelpText<"Which unit to use for fp math">;
 def target_feature : Separate<["-"], "target-feature">,
   HelpText<"Target specific attributes">;
-def target_linker_version : Separate<["-"], "target-linker-version">,
-  HelpText<"Target linker version">;
 def triple : Separate<["-"], "triple">,
   HelpText<"Specify target triple (e.g. i686-apple-darwin9)">;
+
+}
+
+def target_abi : Separate<["-"], "target-abi">,
+  HelpText<"Target a particular ABI type">;
+def target_linker_version : Separate<["-"], "target-linker-version">,
+  HelpText<"Target linker version">;
 def triple_EQ : Joined<["-"], "triple=">, Alias<triple>;
+def mfpmath : Separate<["-"], "mfpmath">,
+  HelpText<"Which unit to use for fp math">;
 
 //===----------------------------------------------------------------------===//
 // Analyzer Options
@@ -124,22 +127,37 @@
 // CodeGen Options
 //===----------------------------------------------------------------------===//
 
+let Flags = [CC1Option, CC1AsOption, NoDriverOption] in {
+
+def fdebug_compilation_dir : Separate<["-"], "fdebug-compilation-dir">,
+  HelpText<"The compilation directory to embed in the debug info.">;
+def dwarf_debug_flags : Separate<["-"], "dwarf-debug-flags">,
+  HelpText<"The string to embed in the Dwarf debug flags record.">;
+def mno_exec_stack : Flag<["-"], "mnoexecstack">,
+  HelpText<"Mark the file as not needing an executable stack">;
+def compress_debug_sections : Flag<["-"], "compress-debug-sections">,
+    HelpText<"Compress DWARF debug sections using zlib">;
+def msave_temp_labels : Flag<["-"], "msave-temp-labels">,
+  HelpText<"Save temporary labels in the symbol table. "
+           "Note this may change .s semantics and shouldn't generally be used "
+           "on compiler-generated code.">;
+
+}
+
 def disable_llvm_optzns : Flag<["-"], "disable-llvm-optzns">,
   HelpText<"Don't run LLVM optimization passes">;
 def disable_llvm_verifier : Flag<["-"], "disable-llvm-verifier">,
   HelpText<"Don't run the LLVM IR verifier pass">;
 def disable_red_zone : Flag<["-"], "disable-red-zone">,
   HelpText<"Do not emit code that uses the red zone.">;
-def fdebug_compilation_dir : Separate<["-"], "fdebug-compilation-dir">,
-  HelpText<"The compilation directory to embed in the debug info.">;
-def dwarf_debug_flags : Separate<["-"], "dwarf-debug-flags">,
-  HelpText<"The string to embed in the Dwarf debug flags record.">;
 def dwarf_column_info : Flag<["-"], "dwarf-column-info">,
   HelpText<"Turn on column location information.">;
 def split_dwarf : Flag<["-"], "split-dwarf">,
   HelpText<"Split out the dwarf .dwo sections">;
 def gnu_pubnames : Flag<["-"], "gnu-pubnames">,
   HelpText<"Emit newer GNU style pubnames">;
+def arange_sections : Flag<["-"], "arange_sections">,
+  HelpText<"Emit DWARF .debug_arange sections">;
 def fforbid_guard_variables : Flag<["-"], "fforbid-guard-variables">,
   HelpText<"Emit an error if a C++ static local initializer would need a guard variable">;
 def no_implicit_float : Flag<["-"], "no-implicit-float">,
@@ -188,8 +206,6 @@
   HelpText<"The float ABI to use">;
 def mlimit_float_precision : Separate<["-"], "mlimit-float-precision">,
   HelpText<"Limit float precision to the given value">;
-def mno_exec_stack : Flag<["-"], "mnoexecstack">,
-  HelpText<"Mark the file as not needing an executable stack">;
 def split_stacks : Flag<["-"], "split-stacks">,
   HelpText<"Try to use a split stack if possible.">;
 def mno_zero_initialized_in_bss : Flag<["-"], "mno-zero-initialized-in-bss">,
@@ -198,8 +214,6 @@
   HelpText<"Additional arguments to forward to LLVM backend (during code gen)">;
 def mregparm : Separate<["-"], "mregparm">,
   HelpText<"Limit the number of registers available for integer arguments">;
-def msave_temp_labels : Flag<["-"], "msave-temp-labels">,
-  HelpText<"(integrated-as) Save temporary labels">;
 def mrelocation_model : Separate<["-"], "mrelocation-model">,
   HelpText<"The relocation model to use">;
 def munwind_tables : Flag<["-"], "munwind-tables">,
@@ -223,10 +237,12 @@
 
 def sys_header_deps : Flag<["-"], "sys-header-deps">,
   HelpText<"Include system headers in dependency output">;
+def module_file_deps : Flag<["-"], "module-file-deps">,
+  HelpText<"Include module files in dependency output">;
 def header_include_file : Separate<["-"], "header-include-file">,
   HelpText<"Filename (or -) to write header include output to">;
 def show_includes : Flag<["--"], "show-includes">,
-  HelpText<"Print cl.exe style /showIncludes to stderr">;
+  HelpText<"Print cl.exe style /showIncludes to stdout">;
 
 //===----------------------------------------------------------------------===//
 // Diagnostic Options
@@ -256,6 +272,8 @@
   HelpText<"Set the maximum number of entries to print in a constexpr evaluation backtrace (0 = no limit).">;
 def fmessage_length : Separate<["-"], "fmessage-length">, MetaVarName<"<N>">,
   HelpText<"Format message diagnostics so that they fit within N columns or fewer, when possible.">;
+def verify : Flag<["-"], "verify">,
+  HelpText<"Verify diagnostic output using comment directives">;
 def Wno_rewrite_macros : Flag<["-"], "Wno-rewrite-macros">,
   HelpText<"Silence ObjC rewriting warnings">;
 
@@ -266,6 +284,7 @@
 // This isn't normally used, it is just here so we can parse a
 // CompilerInvocation out of a driver-derived argument vector.
 def cc1 : Flag<["-"], "cc1">;
+def cc1as : Flag<["-"], "cc1as">;
 
 def ast_merge : Separate<["-"], "ast-merge">,
   MetaVarName<"<ast file>">,
@@ -297,8 +316,6 @@
     HelpText<"Pass <arg> to plugin <name>">;
 def add_plugin : Separate<["-"], "add-plugin">, MetaVarName<"<name>">,
   HelpText<"Use the named plugin action in addition to the default action">;
-def version : Flag<["-"], "version">,
-  HelpText<"Print the compiler version">;
 def ast_dump_filter : Separate<["-"], "ast-dump-filter">,
   MetaVarName<"<dump_filter>">,
   HelpText<"Use with -ast-dump or -ast-print to dump/print only AST declaration"
@@ -308,6 +325,8 @@
   HelpText<"Include name lookup table dumps in AST dumps">;
 def fno_modules_global_index : Flag<["-"], "fno-modules-global-index">,
   HelpText<"Do not automatically generate or update the global module index">;
+def fno_modules_error_recovery : Flag<["-"], "fno-modules-error-recovery">,
+  HelpText<"Do not automatically import modules for error recovery">;
 
 let Group = Action_Group in {
 
@@ -393,14 +412,19 @@
 // Language Options
 //===----------------------------------------------------------------------===//
 
+let Flags = [CC1Option, CC1AsOption, NoDriverOption] in {
+
+def version : Flag<["-"], "version">,
+  HelpText<"Print the compiler version">;
+def main_file_name : Separate<["-"], "main-file-name">,
+  HelpText<"Main file name to use for debug info">;
+
+}
+
 def fblocks_runtime_optional : Flag<["-"], "fblocks-runtime-optional">,
   HelpText<"Weakly link in the blocks runtime">;
 def fsjlj_exceptions : Flag<["-"], "fsjlj-exceptions">,
   HelpText<"Use SjLj style exceptions">;
-def fhidden_weak_vtables : Flag<["-"], "fhidden-weak-vtables">,
-  HelpText<"Generate weak vtables and RTTI with hidden visibility">;
-def main_file_name : Separate<["-"], "main-file-name">,
-  HelpText<"Main file name to use for debug info">;
 def split_dwarf_file : Separate<["-"], "split-dwarf-file">,
   HelpText<"File name to use for split dwarf debug info output">;
 def fno_wchar : Flag<["-"], "fno-wchar">,
@@ -476,6 +500,10 @@
   HelpText<"Enable C++1y sized global deallocation functions">;
 def fobjc_subscripting_legacy_runtime : Flag<["-"], "fobjc-subscripting-legacy-runtime">,
   HelpText<"Allow Objective-C array and dictionary subscripting in legacy runtime">;
+def vtordisp_mode_EQ : Joined<["-"], "vtordisp-mode=">,
+  HelpText<"Control vtordisp placement on win32 targets">;
+def fno_rtti_data : Flag<["-"], "fno-rtti-data">,
+  HelpText<"Control emission of RTTI data">;
 
 //===----------------------------------------------------------------------===//
 // Header Search Options
@@ -504,14 +532,6 @@
            "implicit extern \"C\" semantics; these are assumed to not be "
            "user-provided and are used to model system and standard headers' "
            "paths.">;
-def isystem_prefix : JoinedOrSeparate<["-"], "isystem-prefix">,
-  MetaVarName<"<prefix>">,
-  HelpText<"Treat all #include paths starting with <prefix> as including a "
-           "system header.">;
-def ino_system_prefix : JoinedOrSeparate<["-"], "ino-system-prefix">,
-  MetaVarName<"<prefix>">,
-  HelpText<"Treat all #include paths starting with <prefix> as not including a "
-           "system header.">;
 
 //===----------------------------------------------------------------------===//
 // Preprocessor Options
@@ -539,6 +559,8 @@
   HelpText<"OpenCL only. Treat double precision floating-point constant as single precision constant.">;
 def cl_finite_math_only : Flag<["-"], "cl-finite-math-only">,
   HelpText<"OpenCL only. Allow floating-point optimizations that assume arguments and results are not NaNs or +-Inf.">;
+def cl_kernel_arg_info : Flag<["-"], "cl-kernel-arg-info">,
+  HelpText<"OpenCL only. Generate kernel argument metadata.">;
 def cl_unsafe_math_optimizations : Flag<["-"], "cl-unsafe-math-optimizations">,
   HelpText<"OpenCL only. Allow unsafe floating-point optimizations.  Also implies -cl-no-signed-zeros and -cl-mad-enable">;
 def cl_fast_relaxed_math : Flag<["-"], "cl-fast-relaxed-math">,
@@ -556,3 +578,32 @@
   HelpText<"Generate code for CUDA device">;
 
 } // let Flags = [CC1Option]
+
+
+//===----------------------------------------------------------------------===//
+// cc1as-only Options
+//===----------------------------------------------------------------------===//
+
+let Flags = [CC1AsOption, NoDriverOption] in {
+
+// Language Options
+def n : Flag<["-"], "n">,
+  HelpText<"Don't automatically start assembly file with a text section">;
+
+// Frontend Options
+def filetype : Separate<["-"], "filetype">,
+    HelpText<"Specify the output file type ('asm', 'null', or 'obj')">;
+
+// Transliterate Options
+def output_asm_variant : Separate<["-"], "output-asm-variant">,
+    HelpText<"Select the asm variant index to use for output">;
+def show_encoding : Flag<["-"], "show-encoding">,
+    HelpText<"Show instruction encoding information in transliterate mode">;
+def show_inst : Flag<["-"], "show-inst">,
+    HelpText<"Show internal instruction representation in transliterate mode">;
+
+// Assemble Options
+def dwarf_debug_producer : Separate<["-"], "dwarf-debug-producer">,
+  HelpText<"The string to embed in the Dwarf debug AT_producer record.">;
+
+} // let Flags = [CC1AsOption]
diff --git a/include/clang/Driver/CLCompatOptions.td b/include/clang/Driver/CLCompatOptions.td
index d17a63c..7278bf8 100644
--- a/include/clang/Driver/CLCompatOptions.td
+++ b/include/clang/Driver/CLCompatOptions.td
@@ -57,10 +57,19 @@
 def _SLASH_c : CLFlag<"c">, HelpText<"Compile only">, Alias<c>;
 def _SLASH_D : CLJoinedOrSeparate<"D">, HelpText<"Define macro">,
   MetaVarName<"<macro[=value]>">, Alias<D>;
-def _SLASH_GR : CLFlag<"GR">, HelpText<"Enable RTTI">, Alias<frtti>;
-def _SLASH_GR_ : CLFlag<"GR-">, HelpText<"Disable RTTI">, Alias<fno_rtti>;
+def _SLASH_E : CLFlag<"E">, HelpText<"Preprocess to stdout">, Alias<E>;
+def _SLASH_GR : CLFlag<"GR">, HelpText<"Enable emission of RTTI data">;
+def _SLASH_GR_ : CLFlag<"GR-">, HelpText<"Disable emission of RTTI data">;
 def _SLASH_GF_ : CLFlag<"GF-">, HelpText<"Disable string pooling">,
   Alias<fwritable_strings>;
+def _SLASH_Gy : CLFlag<"Gy">, HelpText<"Put each function in its own section">,
+  Alias<ffunction_sections>;
+def _SLASH_Gy_ : CLFlag<"Gy-">, HelpText<"Don't put each function in its own section">,
+  Alias<fno_function_sections>;
+def _SLASH_Gw : CLFlag<"Gw">, HelpText<"Put each data item in its own section">,
+  Alias<fdata_sections>;
+def _SLASH_Gw_ : CLFlag<"Gw-">, HelpText<"Don't put each data item in its own section">,
+  Alias<fno_data_sections>;
 def _SLASH_help : CLFlag<"help">, Alias<help>,
   HelpText<"Display available options">;
 def _SLASH_HELP : CLFlag<"HELP">, Alias<help>;
@@ -88,7 +97,6 @@
   Alias<fomit_frame_pointer>;
 def _SLASH_Oy_ : CLFlag<"Oy-">, HelpText<"Disable frame pointer omission">,
   Alias<fno_omit_frame_pointer>;
-def _SLASH_P : CLFlag<"P">, HelpText<"Only run the preprocessor">, Alias<E>;
 def _SLASH_QUESTION : CLFlag<"?">, Alias<help>,
   HelpText<"Display available options">;
 def _SLASH_showIncludes : CLFlag<"showIncludes">,
@@ -96,6 +104,16 @@
   Alias<show_includes>;
 def _SLASH_U : CLJoinedOrSeparate<"U">, HelpText<"Undefine macro">,
   MetaVarName<"<macro>">, Alias<U>;
+def _SLASH_vmb : CLFlag<"vmb">,
+  HelpText<"Use a best-case representation method for member pointers">;
+def _SLASH_vmg : CLFlag<"vmg">,
+  HelpText<"Use a most-general representation for member pointers">;
+def _SLASH_vms : CLFlag<"vms">,
+  HelpText<"Set the default most-general representation to single inheritance">;
+def _SLASH_vmm : CLFlag<"vmm">,
+  HelpText<"Set the default most-general representation to multiple inheritance">;
+def _SLASH_vmv : CLFlag<"vmv">,
+  HelpText<"Set the default most-general representation to virtual inheritance">;
 def _SLASH_W0 : CLFlag<"W0">, HelpText<"Disable all warnings">, Alias<w>;
 def _SLASH_W1 : CLFlag<"W1">, HelpText<"Enable -Wall">, Alias<Wall>;
 def _SLASH_W2 : CLFlag<"W2">, HelpText<"Enable -Wall">, Alias<Wall>;
@@ -107,14 +125,27 @@
 def _SLASH_WX_ : CLFlag<"WX-">, HelpText<"Do not treat warnings as errors">,
   Alias<W_Joined>, AliasArgs<["no-error"]>;
 def _SLASH_w_flag : CLFlag<"w">, HelpText<"Disable all warnings">, Alias<w>;
+def _SLASH_wd4005 : CLFlag<"wd4005">, Alias<W_Joined>,
+  AliasArgs<["no-macro-redefined"]>;
+def _SLASH_vd : CLJoined<"vd">, HelpText<"Control vtordisp placement">,
+  Alias<vtordisp_mode_EQ>;
+def _SLASH_Z7 : CLFlag<"Z7">, Alias<gline_tables_only>;
+def _SLASH_Zi : CLFlag<"Zi">, HelpText<"Enable debug information">,
+  Alias<gline_tables_only>;
 def _SLASH_Zs : CLFlag<"Zs">, HelpText<"Syntax-check only">,
   Alias<fsyntax_only>;
 
 
 // Non-aliases:
 
+def _SLASH_arch : CLCompileJoined<"arch:">,
+  HelpText<"Set architecture for code generation">;
+
 def _SLASH_M_Group : OptionGroup<"</M group>">, Group<cl_compile_Group>;
 
+def _SLASH_EH : CLJoined<"EH">, HelpText<"Exception handling model">;
+def _SLASH_EP : CLFlag<"EP">,
+  HelpText<"Disable linemarker output and preprocess to stdout">;
 def _SLASH_FA : CLFlag<"FA">,
   HelpText<"Output assembly code file during compilation">;
 def _SLASH_Fa : CLJoined<"Fa">,
@@ -127,6 +158,9 @@
 def _SLASH_Fe : CLJoined<"Fe">,
   HelpText<"Set output executable file or directory (ends in / or \\)">,
   MetaVarName<"<file or directory>">;
+def _SLASH_Fi : CLCompileJoined<"Fi">,
+  HelpText<"Set preprocess output file name">,
+  MetaVarName<"<file>">;
 def _SLASH_Fo : CLCompileJoined<"Fo">,
   HelpText<"Set output object file, or directory (ends in / or \\)">,
   MetaVarName<"<file or directory>">;
@@ -142,6 +176,7 @@
   Flags<[CLOption, DriverOption]>, HelpText<"Use static run-time">;
 def _SLASH_MTd : Option<["/", "-"], "MTd", KIND_FLAG>, Group<_SLASH_M_Group>,
   Flags<[CLOption, DriverOption]>, HelpText<"Use static debug run-time">;
+def _SLASH_P : CLFlag<"P">, HelpText<"Preprocess to file">;
 def _SLASH_Tc : CLCompileJoinedOrSeparate<"Tc">,
   HelpText<"Specify a C source file">, MetaVarName<"<filename>">;
 def _SLASH_TC : CLCompileFlag<"TC">, HelpText<"Treat all source files as C">;
@@ -164,9 +199,10 @@
 def _SLASH_RTC : CLIgnoredJoined<"RTC">;
 def _SLASH_sdl : CLIgnoredFlag<"sdl">;
 def _SLASH_sdl_ : CLIgnoredFlag<"sdl-">;
-def _SLASH_vmg : CLIgnoredFlag<"vmg">;
 def _SLASH_w : CLIgnoredJoined<"w">;
 def _SLASH_Zc_forScope : CLIgnoredFlag<"Zc:forScope">;
+def _SLASH_Zc_inline : CLIgnoredFlag<"Zc:inline">;
+def _SLASH_Zc_rvalueCast : CLIgnoredFlag<"Zc:rvalueCast">;
 def _SLASH_Zc_wchar_t : CLIgnoredFlag<"Zc:wchar_t">;
 def _SLASH_Zm : CLIgnoredJoined<"Zm">;
 
@@ -174,19 +210,15 @@
 // Unsupported:
 
 def _SLASH_AI : CLJoined<"AI">;
-def _SLASH_arch : CLJoined<"arch:">;
 def _SLASH_bigobj : CLFlag<"bigobj">;
 def _SLASH_clr : CLJoined<"clr">;
+def _SLASH_d2Zi_PLUS : CLFlag<"d2Zi+">;
 def _SLASH_doc : CLJoined<"doc">;
-def _SLASH_E : CLFlag<"E">;
-def _SLASH_EH : CLJoined<"EH">;
-def _SLASH_EP : CLFlag<"EP">;
 def _SLASH_FA_joined : CLJoined<"FA">;
 def _SLASH_favor : CLJoined<"favor">;
 def _SLASH_FC : CLFlag<"FC">;
 def _SLASH_F : CLFlag<"F">;
 def _SLASH_Fd : CLJoined<"Fd">;
-def _SLASH_Fi : CLJoined<"Fi">;
 def _SLASH_Fm : CLJoined<"Fm">;
 def _SLASH_fp : CLJoined<"fp">;
 def _SLASH_Fp : CLJoined<"Fp">;
@@ -210,8 +242,6 @@
 def _SLASH_Gs : CLJoined<"Gs">;
 def _SLASH_GT : CLFlag<"GT">;
 def _SLASH_GX : CLFlag<"GX">;
-def _SLASH_Gy : CLFlag<"Gy">;
-def _SLASH_Gy_ : CLFlag<"Gy-">;
 def _SLASH_Gz : CLFlag<"Gz">;
 def _SLASH_GZ : CLFlag<"GZ">;
 def _SLASH_H : CLFlag<"H">;
@@ -229,11 +259,6 @@
 def _SLASH_Qvec_report : CLJoined<"Qvec-report">;
 def _SLASH_u : CLFlag<"u">;
 def _SLASH_V : CLFlag<"V">;
-def _SLASH_vd : CLJoined<"vd">;
-def _SLASH_vmb : CLFlag<"vmb">;
-def _SLASH_vmm : CLFlag<"vmm">;
-def _SLASH_vms : CLFlag<"vms">;
-def _SLASH_vmv : CLFlag<"vmv">;
 def _SLASH_volatile : CLFlag<"volatile">;
 def _SLASH_WL : CLFlag<"WL">;
 def _SLASH_Wp64 : CLFlag<"Wp64">;
@@ -243,13 +268,11 @@
 def _SLASH_Yd : CLFlag<"Yd">;
 def _SLASH_Yl : CLJoined<"Yl">;
 def _SLASH_Yu : CLJoined<"Yu">;
-def _SLASH_Z7 : CLFlag<"Z7">;
 def _SLASH_Za : CLFlag<"Za">;
 def _SLASH_Zc : CLJoined<"Zc:">;
 def _SLASH_Ze : CLFlag<"Ze">;
 def _SLASH_Zg : CLFlag<"Zg">;
-def _SLASH_Zi : CLFlag<"Zi">;
 def _SLASH_ZI : CLFlag<"ZI">;
 def _SLASH_Zl : CLFlag<"Zl">;
-def _SLASH_Zp : CLFlag<"Zp">;
+def _SLASH_Zp : CLJoined<"Zp">;
 def _SLASH_ZW : CLJoined<"ZW">;
diff --git a/include/clang/Driver/CMakeLists.txt b/include/clang/Driver/CMakeLists.txt
index 5961cac..a9d9880 100644
--- a/include/clang/Driver/CMakeLists.txt
+++ b/include/clang/Driver/CMakeLists.txt
@@ -1,7 +1,3 @@
 set(LLVM_TARGET_DEFINITIONS Options.td)
 tablegen(LLVM Options.inc -gen-opt-parser-defs)
 add_public_tablegen_target(ClangDriverOptions)
-
-set(LLVM_TARGET_DEFINITIONS CC1AsOptions.td)
-tablegen(LLVM CC1AsOptions.inc -gen-opt-parser-defs)
-add_public_tablegen_target(ClangCC1AsOptions)
diff --git a/include/clang/Driver/Compilation.h b/include/clang/Driver/Compilation.h
index 3493e4f..c1c0f43 100644
--- a/include/clang/Driver/Compilation.h
+++ b/include/clang/Driver/Compilation.h
@@ -69,6 +69,9 @@
   /// Redirection for stdout, stderr, etc.
   const StringRef **Redirects;
 
+  /// Whether we're compiling for diagnostic purposes.
+  bool ForDiagnostics;
+
 public:
   Compilation(const Driver &D, const ToolChain &DefaultToolChain,
               llvm::opt::InputArgList *Args,
@@ -173,6 +176,9 @@
   /// so compilation can be reexecuted to generate additional diagnostic
   /// information (e.g., preprocessed source(s)).
   void initCompilationForDiagnostics();
+
+  /// Return true if we're compiling for diagnostics.
+  bool isForDiagnostics() { return ForDiagnostics; }
 };
 
 } // end namespace driver
diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h
index 867444e..df974ad 100644
--- a/include/clang/Driver/Driver.h
+++ b/include/clang/Driver/Driver.h
@@ -15,11 +15,11 @@
 #include "clang/Driver/Phases.h"
 #include "clang/Driver/Types.h"
 #include "clang/Driver/Util.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/Support/Path.h" // FIXME: Kill when CompilationInfo
+#include <memory>
                               // lands.
 #include <list>
 #include <set>
@@ -188,12 +188,11 @@
   // getFinalPhase - Determine which compilation mode we are in and record 
   // which option we used to determine the final phase.
   phases::ID getFinalPhase(const llvm::opt::DerivedArgList &DAL,
-                           llvm::opt::Arg **FinalPhaseArg = 0) const;
+                           llvm::opt::Arg **FinalPhaseArg = nullptr) const;
 
 public:
   Driver(StringRef _ClangExecutable,
          StringRef _DefaultTargetTriple,
-         StringRef _DefaultImageName,
          DiagnosticsEngine &_Diags);
   ~Driver();
 
@@ -259,7 +258,7 @@
   /// \param Args - The input arguments.
   /// \param Inputs - The list to store the resulting compilation 
   /// inputs onto.
-  void BuildInputs(const ToolChain &TC, const llvm::opt::DerivedArgList &Args,
+  void BuildInputs(const ToolChain &TC, llvm::opt::DerivedArgList &Args,
                    InputList &Inputs) const;
 
   /// BuildActions - Construct the list of actions to perform for the
@@ -415,6 +414,10 @@
                                 bool &HadExtra);
 };
 
+/// \return True if the last defined optimization level is -Ofast.
+/// And False otherwise.
+bool isOptimizationLevelFast(const llvm::opt::ArgList &Args);
+
 } // end namespace driver
 } // end namespace clang
 
diff --git a/include/clang/Driver/Job.h b/include/clang/Driver/Job.h
index 1dd49a7..5b19efe 100644
--- a/include/clang/Driver/Job.h
+++ b/include/clang/Driver/Job.h
@@ -11,9 +11,9 @@
 #define CLANG_DRIVER_JOB_H_
 
 #include "clang/Basic/LLVM.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Option/Option.h"
+#include <memory>
 
 namespace llvm {
   class raw_ostream;
@@ -76,8 +76,8 @@
   Command(const Action &_Source, const Tool &_Creator, const char *_Executable,
           const llvm::opt::ArgStringList &_Arguments);
 
-  virtual void Print(llvm::raw_ostream &OS, const char *Terminator,
-                     bool Quote, bool CrashReport = false) const;
+  void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
+             bool CrashReport = false) const override;
 
   virtual int Execute(const StringRef **Redirects, std::string *ErrMsg,
                       bool *ExecutionFailed) const;
@@ -88,6 +88,8 @@
   /// getCreator - Return the Tool which caused the creation of this job.
   const Tool &getCreator() const { return Creator; }
 
+  const char *getExecutable() const { return Executable; }
+
   const llvm::opt::ArgStringList &getArguments() const { return Arguments; }
 
   static bool classof(const Job *J) {
@@ -104,18 +106,18 @@
                   const char *Executable_, const ArgStringList &Arguments_,
                   Command *Fallback_);
 
-  virtual void Print(llvm::raw_ostream &OS, const char *Terminator,
-                     bool Quote, bool CrashReport = false) const;
+  void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
+             bool CrashReport = false) const override;
 
-  virtual int Execute(const StringRef **Redirects, std::string *ErrMsg,
-                      bool *ExecutionFailed) const;
+  int Execute(const StringRef **Redirects, std::string *ErrMsg,
+              bool *ExecutionFailed) const override;
 
   static bool classof(const Job *J) {
     return J->getKind() == FallbackCommandClass;
   }
 
 private:
-  OwningPtr<Command> Fallback;
+  std::unique_ptr<Command> Fallback;
 };
 
 /// JobList - A sequence of jobs to perform.
@@ -133,8 +135,8 @@
   JobList();
   virtual ~JobList();
 
-  virtual void Print(llvm::raw_ostream &OS, const char *Terminator,
-                     bool Quote, bool CrashReport = false) const;
+  void Print(llvm::raw_ostream &OS, const char *Terminator,
+             bool Quote, bool CrashReport = false) const override;
 
   /// Add a job to the list (taking ownership).
   void addJob(Job *J) { Jobs.push_back(J); }
diff --git a/include/clang/Driver/Makefile b/include/clang/Driver/Makefile
index 77cf6ff..8309330 100644
--- a/include/clang/Driver/Makefile
+++ b/include/clang/Driver/Makefile
@@ -1,5 +1,5 @@
 CLANG_LEVEL := ../../..
-BUILT_SOURCES = Options.inc CC1AsOptions.inc
+BUILT_SOURCES = Options.inc
 
 TABLEGEN_INC_FILES_COMMON = 1
 
@@ -8,7 +8,3 @@
 $(ObjDir)/Options.inc.tmp : Options.td CC1Options.td CLCompatOptions.td $(LLVM_TBLGEN) $(ObjDir)/.dir
 	$(Echo) "Building Clang Driver Option tables with tblgen"
 	$(Verb) $(LLVMTableGen) -gen-opt-parser-defs -o $(call SYSPATH, $@) $<
-
-$(ObjDir)/CC1AsOptions.inc.tmp : CC1AsOptions.td $(LLVM_TBLGEN) $(ObjDir)/.dir
-	$(Echo) "Building Clang CC1 Assembler Option tables with tblgen"
-	$(Verb) $(LLVMTableGen) -gen-opt-parser-defs -o $(call SYSPATH, $@) $<
diff --git a/include/clang/Driver/Multilib.h b/include/clang/Driver/Multilib.h
new file mode 100644
index 0000000..6c3738a
--- /dev/null
+++ b/include/clang/Driver/Multilib.h
@@ -0,0 +1,167 @@
+//===--- Multilib.h ---------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_LIB_DRIVER_MULTILIB_H_
+#define CLANG_LIB_DRIVER_MULTILIB_H_
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Option/Option.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+namespace driver {
+
+/// This corresponds to a single GCC Multilib, or a segment of one controlled
+/// by a command line flag
+class Multilib {
+public:
+  typedef std::vector<std::string> flags_list;
+
+private:
+  std::string GCCSuffix;
+  std::string OSSuffix;
+  std::string IncludeSuffix;
+  flags_list Flags;
+
+public:
+  Multilib(StringRef GCCSuffix = "", StringRef OSSuffix = "",
+           StringRef IncludeSuffix = "");
+
+  /// \brief Get the detected GCC installation path suffix for the multi-arch
+  /// target variant. Always starts with a '/', unless empty
+  const std::string &gccSuffix() const {
+    assert(GCCSuffix.empty() ||
+           (StringRef(GCCSuffix).front() == '/' && GCCSuffix.size() > 1));
+    return GCCSuffix;
+  }
+  /// Set the GCC installation path suffix.
+  Multilib &gccSuffix(StringRef S);
+
+  /// \brief Get the detected os path suffix for the multi-arch
+  /// target variant. Always starts with a '/', unless empty
+  const std::string &osSuffix() const {
+    assert(OSSuffix.empty() ||
+           (StringRef(OSSuffix).front() == '/' && OSSuffix.size() > 1));
+    return OSSuffix;
+  }
+  /// Set the os path suffix.
+  Multilib &osSuffix(StringRef S);
+
+  /// \brief Get the include directory suffix. Always starts with a '/', unless
+  /// empty
+  const std::string &includeSuffix() const {
+    assert(IncludeSuffix.empty() ||
+           (StringRef(IncludeSuffix).front() == '/' && IncludeSuffix.size() > 1));
+    return IncludeSuffix;
+  }
+  /// Set the include directory suffix
+  Multilib &includeSuffix(StringRef S);
+
+  /// \brief Get the flags that indicate or contraindicate this multilib's use
+  /// All elements begin with either '+' or '-'
+  const flags_list &flags() const { return Flags; }
+  flags_list &flags() { return Flags; }
+  /// Add a flag to the flags list
+  Multilib &flag(StringRef F) {
+    assert(F.front() == '+' || F.front() == '-');
+    Flags.push_back(F);
+    return *this;
+  }
+
+  /// \brief print summary of the Multilib
+  void print(raw_ostream &OS) const;
+
+  /// Check whether any of the 'against' flags contradict the 'for' flags.
+  bool isValid() const;
+
+  /// Check whether the default is selected
+  bool isDefault() const
+  { return GCCSuffix.empty() && OSSuffix.empty() && IncludeSuffix.empty(); }
+
+  bool operator==(const Multilib &Other) const;
+};
+
+raw_ostream &operator<<(raw_ostream &OS, const Multilib &M);
+
+class MultilibSet {
+public:
+  typedef std::vector<Multilib> multilib_list;
+  typedef multilib_list::iterator iterator;
+  typedef multilib_list::const_iterator const_iterator;
+
+  struct FilterCallback {
+    virtual ~FilterCallback() {};
+    /// \return true iff the filter should remove the Multilib from the set
+    virtual bool operator()(const Multilib &M) const = 0;
+  };
+
+private:
+  multilib_list Multilibs;
+
+public:
+  MultilibSet() {}
+
+  /// Add an optional Multilib segment
+  MultilibSet &Maybe(const Multilib &M);
+
+  /// Add a set of mutually incompatible Multilib segments
+  MultilibSet &Either(const Multilib &M1, const Multilib &M2);
+  MultilibSet &Either(const Multilib &M1, const Multilib &M2,
+                      const Multilib &M3);
+  MultilibSet &Either(const Multilib &M1, const Multilib &M2,
+                      const Multilib &M3, const Multilib &M4);
+  MultilibSet &Either(const Multilib &M1, const Multilib &M2,
+                      const Multilib &M3, const Multilib &M4,
+                      const Multilib &M5);
+  MultilibSet &Either(const std::vector<Multilib> &Ms);
+
+  /// Filter out some subset of the Multilibs using a user defined callback
+  MultilibSet &FilterOut(const FilterCallback &F);
+  /// Filter out those Multilibs whose gccSuffix matches the given expression
+  MultilibSet &FilterOut(std::string Regex);
+
+  /// Add a completed Multilib to the set
+  void push_back(const Multilib &M);
+
+  /// Union this set of multilibs with another
+  void combineWith(const MultilibSet &MS);
+
+  /// Remove all of thie multilibs from the set
+  void clear() { Multilibs.clear(); }
+
+  iterator begin() { return Multilibs.begin(); }
+  const_iterator begin() const { return Multilibs.begin(); }
+
+  iterator end() { return Multilibs.end(); }
+  const_iterator end() const { return Multilibs.end(); }
+
+  /// Pick the best multilib in the set, \returns false if none are compatible
+  bool select(const Multilib::flags_list &Flags, Multilib &M) const;
+
+  unsigned size() const { return Multilibs.size(); }
+
+  void print(raw_ostream &OS) const;
+
+private:
+  /// Apply the filter to Multilibs and return the subset that remains
+  static multilib_list filterCopy(const FilterCallback &F,
+                                  const multilib_list &Ms);
+
+  /// Apply the filter to the multilib_list, removing those that don't match
+  static void filterInPlace(const FilterCallback &F, multilib_list &Ms);
+};
+
+raw_ostream &operator<<(raw_ostream &OS, const MultilibSet &MS);
+}
+}
+
+#endif
+
diff --git a/include/clang/Driver/Options.h b/include/clang/Driver/Options.h
index 28948be..cee705d 100644
--- a/include/clang/Driver/Options.h
+++ b/include/clang/Driver/Options.h
@@ -30,7 +30,8 @@
   CoreOption = (1 << 8),
   CLOption = (1 << 9),
   CC1Option = (1 << 10),
-  NoDriverOption = (1 << 11)
+  CC1AsOption = (1 << 11),
+  NoDriverOption = (1 << 12)
 };
 
 enum ID {
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index 9e7dc78..9d4fdad 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -44,6 +44,9 @@
 // CC1Option - This option should be accepted by clang -cc1.
 def CC1Option : OptionFlag;
 
+// CC1AsOption - This option should be accepted by clang -cc1as.
+def CC1AsOption : OptionFlag;
+
 // NoDriverOption - This option should not be accepted by the driver.
 def NoDriverOption : OptionFlag;
 
@@ -60,7 +63,10 @@
 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>;
@@ -69,11 +75,11 @@
 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 m_x86_Features_Group  : OptionGroup<"<m x86 features group>">, Group<m_Group>;
+def m_x86_Features_Group  : OptionGroup<"<m x86 features group>">, Group<m_Group>, Flags<[CoreOption]>;
 def m_hexagon_Features_Group  : OptionGroup<"<m hexagon features group>">, Group<m_Group>;
 def m_arm_Features_Group  : OptionGroup<"<m arm features group>">, Group<m_Group>;
+def m_aarch64_Features_Group  : OptionGroup<"<m aarch64 features group>">, Group<m_Group>;
 def m_ppc_Features_Group  : OptionGroup<"<m ppc features group>">, Group<m_Group>;
-def opencl_Group          : OptionGroup<"<opencl group>">;
 def u_Group               : OptionGroup<"<u group>">;
 
 def pedantic_Group        : OptionGroup<"<pedantic group>">,
@@ -87,6 +93,10 @@
 def clang_ignored_m_Group : OptionGroup<"<clang ignored m group>">,
   Group<m_Group>;
 
+// 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>;
+
 /////////
 // Options
 
@@ -184,8 +194,13 @@
   HelpText<"Enable migration to annotate property with NS_RETURNS_INNER_POINTER">;
 def objcmt_ns_nonatomic_iosonly: Flag<["-"], "objcmt-ns-nonatomic-iosonly">, Flags<[CC1Option]>,
   HelpText<"Enable migration to use NS_NONATOMIC_IOSONLY macro for setting property's 'atomic' attribute">;
-def objcmt_white_list_dir_path: Joined<["-"], "objcmt-white-list-dir-path=">, Flags<[CC1Option]>,
+def objcmt_migrate_designated_init : Flag<["-"], "objcmt-migrate-designated-init">, Flags<[CC1Option]>,
+  HelpText<"Enable migration to infer NS_DESIGNATED_INITIALIZER for initializer methods">;
+def objcmt_whitelist_dir_path: Joined<["-"], "objcmt-whitelist-dir-path=">, Flags<[CC1Option]>,
   HelpText<"Only modify files with a filename contained in the provided directory path">;
+// The misspelt "white-list" [sic] alias is due for removal.
+def : Joined<["-"], "objcmt-white-list-dir-path=">, Flags<[CC1Option]>,
+    Alias<objcmt_whitelist_dir_path>;
 
 // Make sure all other -ccc- options are rejected.
 def ccc_ : Joined<["-"], "ccc-">, Group<internal_Group>, Flags<[Unsupported]>;
@@ -193,7 +208,7 @@
 // Standard Options
 
 def _HASH_HASH_HASH : Flag<["-"], "###">, Flags<[DriverOption, CoreOption]>,
-    HelpText<"Print the commands to run for this compilation">;
+    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]>;
@@ -210,23 +225,29 @@
 def H : Flag<["-"], "H">, Flags<[CC1Option]>,
     HelpText<"Show header includes and nesting depth">;
 def I_ : Flag<["-"], "I-">, Group<I_Group>;
-def I : JoinedOrSeparate<["-"], "I">, Group<I_Group>, Flags<[CC1Option]>,
+def I : JoinedOrSeparate<["-"], "I">, Group<I_Group>, Flags<[CC1Option,CC1AsOption]>,
     HelpText<"Add directory to include search path">;
 def L : JoinedOrSeparate<["-"], "L">, Flags<[RenderJoined]>;
-def MD : Flag<["-"], "MD">, Group<M_Group>;
-def MF : JoinedOrSeparate<["-"], "MF">, Group<M_Group>;
+def MD : Flag<["-"], "MD">, Group<M_Group>,
+    HelpText<"Write a depfile containing user and system headers">;
+def MMD : Flag<["-"], "MMD">, Group<M_Group>,
+    HelpText<"Write a depfile containing user headers">;
+def M : Flag<["-"], "M">, Group<M_Group>,
+    HelpText<"Like -MD, but also implies -E and writes to stdout by default">;
+def MM : Flag<["-"], "MM">, Group<M_Group>,
+    HelpText<"Like -MMD, but also implies -E and writes to stdout by default">;
+def MF : JoinedOrSeparate<["-"], "MF">, Group<M_Group>,
+    HelpText<"Write depfile output from -MMD, -MD, -MM, or -M to <file>">,
+    MetaVarName<"<file>">;
 def MG : Flag<["-"], "MG">, Group<M_Group>, Flags<[CC1Option]>,
-    HelpText<"Add missing headers to dependency list">;
-def MMD : Flag<["-"], "MMD">, Group<M_Group>;
-def MM : Flag<["-"], "MM">, Group<M_Group>;
+    HelpText<"Add missing headers to depfile">;
 def MP : Flag<["-"], "MP">, Group<M_Group>, Flags<[CC1Option]>,
     HelpText<"Create phony target for each dependency (other than main file)">;
 def MQ : JoinedOrSeparate<["-"], "MQ">, Group<M_Group>, Flags<[CC1Option]>,
-    HelpText<"Specify target to quote for dependency">;
+    HelpText<"Specify name of main file output to quote in depfile">;
 def MT : JoinedOrSeparate<["-"], "MT">, Group<M_Group>, Flags<[CC1Option]>,
-    HelpText<"Specify target for dependency">;
+    HelpText<"Specify name of main file output in depfile">;
 def Mach : Flag<["-"], "Mach">;
-def M : Flag<["-"], "M">, Group<M_Group>;
 def O0 : Flag<["-"], "O0">, Group<O_Group>, Flags<[CC1Option]>;
 def O4 : Flag<["-"], "O4">, Group<O_Group>, Flags<[CC1Option]>;
 def ObjCXX : Flag<["-"], "ObjC++">, Flags<[DriverOption]>,
@@ -242,7 +263,19 @@
 def Qunused_arguments : Flag<["-"], "Qunused-arguments">, Flags<[DriverOption, CoreOption]>,
   HelpText<"Don't emit warning for unused driver arguments">;
 def Q : Flag<["-"], "Q">;
-def R : Flag<["-"], "R">;
+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">;
+def Rpass_missed_EQ : Joined<["-"], "Rpass-missed=">, Group<R_value_Group>,
+  Flags<[CC1Option]>,
+  HelpText<"Report missed transformations by optimization passes whose "
+           "name matches the given POSIX regular expression">;
+def Rpass_analysis_EQ : Joined<["-"], "Rpass-analysis=">, Group<R_value_Group>,
+  Flags<[CC1Option]>,
+  HelpText<"Report transformation analysis from optimization passes whose "
+           "name matches the given POSIX regular expression">;
+def R_Joined : Joined<["-"], "R">, Group<R_Group>, Flags<[CC1Option, CoreOption]>,
+  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>;
@@ -261,6 +294,7 @@
 def Wl_COMMA : CommaJoined<["-"], "Wl,">, Flags<[LinkerInput, RenderAsInput]>,
   HelpText<"Pass the comma separated arguments in <arg> to the linker">,
   MetaVarName<"<arg>">;
+// FIXME: This is broken; these should not be Joined arguments.
 def Wno_nonportable_cfstrings : Joined<["-"], "Wno-nonportable-cfstrings">, Group<W_Group>,
   Flags<[CC1Option]>;
 def Wnonportable_cfstrings : Joined<["-"], "Wnonportable-cfstrings">, Group<W_Group>,
@@ -268,6 +302,8 @@
 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]>;
 def W_Joined : Joined<["-"], "W">, Group<W_Group>, Flags<[CC1Option, CoreOption]>,
   MetaVarName<"<warning>">, HelpText<"Enable the specified warning">;
 def Xanalyzer : Separate<["-"], "Xanalyzer">,
@@ -278,6 +314,8 @@
 def Xclang : Separate<["-"], "Xclang">,
   HelpText<"Pass <arg> to the clang compiler">, MetaVarName<"<arg>">,
   Flags<[DriverOption, CoreOption]>;
+def z : Separate<["-"], "z">, Flags<[LinkerInput, RenderAsInput]>,
+  HelpText<"Pass -z <arg> to the linker">, MetaVarName<"<arg>">;
 def Xlinker : Separate<["-"], "Xlinker">, Flags<[LinkerInput, RenderAsInput]>,
   HelpText<"Pass <arg> to the linker">, MetaVarName<"<arg>">;
 def Xpreprocessor : Separate<["-"], "Xpreprocessor">,
@@ -297,8 +335,6 @@
 def bundle__loader : Separate<["-"], "bundle_loader">;
 def bundle : Flag<["-"], "bundle">;
 def b : JoinedOrSeparate<["-"], "b">, Flags<[Unsupported]>;
-def cl_kernel_arg_info : Flag<["-"], "cl-kernel-arg-info">, Flags<[CC1Option]>, Group<opencl_Group>,
-HelpText<"OpenCL only. This option allows the compiler to store information about the arguments of a kernel(s)"> ;
 def client__name : JoinedOrSeparate<["-"], "client_name">;
 def combine : Flag<["-", "--"], "combine">, Flags<[DriverOption, Unsupported]>;
 def compatibility__version : JoinedOrSeparate<["-"], "compatibility_version">;
@@ -320,6 +356,8 @@
   HelpText<"Filename (or -) to write dependency output to">;
 def dependency_dot : Separate<["-"], "dependency-dot">, Flags<[CC1Option]>,
   HelpText<"Filename to write DOT-formatted header dependencies to">;
+def module_dependency_dir : Separate<["-"], "module-dependency-dir">,
+  Flags<[CC1Option]>, HelpText<"Directory to dump module dependencies to">;
 def dumpmachine : Flag<["-"], "dumpmachine">;
 def dumpspecs : Flag<["-"], "dumpspecs">, Flags<[Unsupported]>;
 def dumpversion : Flag<["-"], "dumpversion">;
@@ -346,10 +384,7 @@
   HelpText<"Use Apple's kernel extensions ABI">;
 def fapple_pragma_pack : Flag<["-"], "fapple-pragma-pack">, Group<f_Group>, Flags<[CC1Option]>,
   HelpText<"Enable Apple gcc-compatible #pragma pack handling">;
-def faddress_sanitizer : Flag<["-"], "faddress-sanitizer">, Group<f_Group>;
-def fno_address_sanitizer : Flag<["-"], "fno-address-sanitizer">, Group<f_Group>;
-def fthread_sanitizer : Flag<["-"], "fthread-sanitizer">, Group<f_Group>;
-def fno_thread_sanitizer : Flag<["-"], "fno-thread-sanitizer">, Group<f_Group>;
+def shared_libasan : Flag<["-"], "shared-libasan">;
 def fasm : Flag<["-"], "fasm">, Group<f_Group>;
 
 def fasm_blocks : Flag<["-"], "fasm-blocks">, Group<f_Group>, Flags<[CC1Option]>;
@@ -369,19 +404,23 @@
 def fprofile_sample_use_EQ : Joined<["-"], "fprofile-sample-use=">,
     Group<f_Group>, Flags<[DriverOption, CC1Option]>,
     HelpText<"Enable sample-based profile guided optimizations">;
+def fauto_profile_EQ : Joined<["-"], "fauto-profile=">,
+    Alias<fprofile_sample_use_EQ>;
+def fprofile_instr_generate : Flag<["-"], "fprofile-instr-generate">,
+    Group<f_Group>, Flags<[CC1Option]>,
+    HelpText<"Generate instrumented code to collect execution counts">;
+def fprofile_instr_use : Flag<["-"], "fprofile-instr-use">, Group<f_Group>;
+def fprofile_instr_use_EQ : Joined<["-"], "fprofile-instr-use=">,
+    Group<f_Group>, Flags<[CC1Option]>,
+    HelpText<"Use instrumentation data for profile-guided optimization">;
 
 def fblocks : Flag<["-"], "fblocks">, Group<f_Group>, Flags<[CC1Option]>,
   HelpText<"Enable the 'blocks' language feature">;
 def fbootclasspath_EQ : Joined<["-"], "fbootclasspath=">, Group<f_Group>;
 def fborland_extensions : Flag<["-"], "fborland-extensions">, Group<f_Group>, Flags<[CC1Option]>,
   HelpText<"Accept non-standard constructs supported by the Borland compiler">;
-def fbounds_checking : Flag<["-"], "fbounds-checking">, Group<f_Group>,
-  HelpText<"Enable run-time bounds checks">;
-def fbounds_checking_EQ : Joined<["-"], "fbounds-checking=">, Flags<[CC1Option]>,
-  Group<f_Group>;
 def fbuiltin : Flag<["-"], "fbuiltin">, Group<f_Group>;
 def fcaret_diagnostics : Flag<["-"], "fcaret-diagnostics">, Group<f_Group>;
-def fcatch_undefined_behavior : Flag<["-"], "fcatch-undefined-behavior">, Group<f_Group>;
 def fclasspath_EQ : Joined<["-"], "fclasspath=">, Group<f_Group>;
 def fcolor_diagnostics : Flag<["-"], "fcolor-diagnostics">, Group<f_Group>, Flags<[CC1Option]>,
   HelpText<"Use colors in diagnostics">;
@@ -417,8 +456,6 @@
     HelpText<"Print source range spans in numeric form">;
 def fdiagnostics_show_option : Flag<["-"], "fdiagnostics-show-option">, Group<f_Group>,
     Flags<[CC1Option]>, HelpText<"Print option name with mappable diagnostics">;
-def fdiagnostics_show_name : Flag<["-"], "fdiagnostics-show-name">, Group<f_Group>,
-    Flags<[CC1Option]>, HelpText<"Print diagnostic name">;
 def fdiagnostics_show_note_include_stack : Flag<["-"], "fdiagnostics-show-note-include-stack">,
     Group<f_Group>,  Flags<[CC1Option]>, HelpText<"Display include stacks for diagnostic notes">;
 def fdiagnostics_format_EQ : Joined<["-"], "fdiagnostics-format=">, Group<f_clang_Group>;
@@ -428,8 +465,8 @@
     HelpText<"Print a template comparison tree for differing templates">;
 def fdollars_in_identifiers : Flag<["-"], "fdollars-in-identifiers">, Group<f_Group>,
   HelpText<"Allow '$' in identifiers">, Flags<[CC1Option]>;
-def fdwarf2_cfi_asm : Flag<["-"], "fdwarf2-cfi-asm">, Group<f_Group>;
-def fno_dwarf2_cfi_asm : Flag<["-"], "fno-dwarf2-cfi-asm">, Group<f_Group>,  Flags<[CC1Option]>;
+def fdwarf2_cfi_asm : Flag<["-"], "fdwarf2-cfi-asm">, Group<clang_ignored_f_Group>;
+def fno_dwarf2_cfi_asm : Flag<["-"], "fno-dwarf2-cfi-asm">, Group<clang_ignored_f_Group>;
 def fdwarf_directory_asm : Flag<["-"], "fdwarf-directory-asm">, Group<f_Group>;
 def fno_dwarf_directory_asm : Flag<["-"], "fno-dwarf-directory-asm">, Group<f_Group>, Flags<[CC1Option]>;
 def felide_constructors : Flag<["-"], "felide-constructors">, Group<f_Group>;
@@ -440,18 +477,16 @@
 def femit_all_decls : Flag<["-"], "femit-all-decls">, Group<f_Group>, Flags<[CC1Option]>,
   HelpText<"Emit all declarations, even if unused">;
 def fencoding_EQ : Joined<["-"], "fencoding=">, Group<f_Group>;
-def ferror_limit_EQ : Joined<["-"], "ferror-limit=">, Group<f_Group>;
+def ferror_limit_EQ : Joined<["-"], "ferror-limit=">, Group<f_Group>, Flags<[CoreOption]>;
 def fexceptions : Flag<["-"], "fexceptions">, Group<f_Group>, Flags<[CC1Option]>,
   HelpText<"Enable support for exception handling">;
-def fexpensive_optimizations : Flag<["-"], "fexpensive-optimizations">,
-  Group<clang_ignored_f_Group>;
-def fno_expensive_optimizations : Flag<["-"], "fno-expensive-optimizations">,
-  Group<clang_ignored_f_Group>;
+def : Flag<["-"], "fexpensive-optimizations">, Group<clang_ignored_gcc_optimization_f_Group>;
+def : Flag<["-"], "fno-expensive-optimizations">, Group<clang_ignored_gcc_optimization_f_Group>;
 def fextdirs_EQ : Joined<["-"], "fextdirs=">, Group<f_Group>;
-def fextended_identifiers : Flag<["-"], "fextended-identifiers">,
-    Group<clang_ignored_f_Group>;
-def fno_extended_identifiers : Flag<["-"], "fno-extended-identifiers">,
-    Group<f_Group>, Flags<[Unsupported]>;
+def : Flag<["-"], "fdefer-pop">, Group<clang_ignored_gcc_optimization_f_Group>;
+def : Flag<["-"], "fno-defer-pop">, Group<clang_ignored_gcc_optimization_f_Group>;
+def : Flag<["-"], "fextended-identifiers">, Group<clang_ignored_f_Group>;
+def : Flag<["-"], "fno-extended-identifiers">, Group<f_Group>, Flags<[Unsupported]>;
 def fhosted : Flag<["-"], "fhosted">, Group<f_Group>;
 def ffast_math : Flag<["-"], "ffast-math">, Group<f_Group>, Flags<[CC1Option]>,
   HelpText<"Enable the *frontend*'s 'fast-math' mode. This has no effect on "
@@ -470,23 +505,21 @@
                             "address (memory errors) | thread (race detection) | "
                             "undefined (miscellaneous undefined behavior)">;
 def fno_sanitize_EQ : CommaJoined<["-"], "fno-sanitize=">, Group<f_clang_Group>;
-def fsanitize_address_zero_base_shadow : Flag<["-"], "fsanitize-address-zero-base-shadow">,
-                                         Group<f_clang_Group>, Flags<[CC1Option]>,
-                                         HelpText<"Make AddressSanitizer map shadow memory "
-                                                  "at zero offset">;
-def fno_sanitize_address_zero_base_shadow : Flag<["-"], "fno-sanitize-address-zero-base-shadow">,
-                                            Group<f_clang_Group>;
 def fsanitize_blacklist : Joined<["-"], "fsanitize-blacklist=">,
-                          Group<f_clang_Group>, Flags<[CC1Option]>,
+                          Group<f_clang_Group>, Flags<[CC1Option, CoreOption]>,
                           HelpText<"Path to blacklist file for sanitizers">;
 def fno_sanitize_blacklist : Flag<["-"], "fno-sanitize-blacklist">,
                              Group<f_clang_Group>,
                              HelpText<"Don't use blacklist file for sanitizers">;
+def fsanitize_memory_track_origins_EQ : Joined<["-"], "fsanitize-memory-track-origins=">,
+                                        Group<f_clang_Group>, Flags<[CC1Option]>,
+                                        HelpText<"Enable origins tracking in MemorySanitizer">;
 def fsanitize_memory_track_origins : Flag<["-"], "fsanitize-memory-track-origins">,
                                      Group<f_clang_Group>, Flags<[CC1Option]>,
                                      HelpText<"Enable origins tracking in MemorySanitizer">;
 def fno_sanitize_memory_track_origins : Flag<["-"], "fno-sanitize-memory-track-origins">,
-                                        Group<f_clang_Group>;
+                                        Group<f_clang_Group>, Flags<[CC1Option]>,
+                                        HelpText<"Disable origins tracking in MemorySanitizer">;
 def fsanitize_recover : Flag<["-"], "fsanitize-recover">,
                         Group<f_clang_Group>;
 def fno_sanitize_recover : Flag<["-"], "fno-sanitize-recover">,
@@ -512,9 +545,9 @@
 def fno_honor_nans : Flag<["-"], "fno-honor-nans">, Group<f_Group>;
 def fhonor_infinities : Flag<["-"], "fhonor-infinities">, Group<f_Group>;
 def fno_honor_infinities : Flag<["-"], "fno-honor-infinities">, Group<f_Group>;
-// Sic. This option was misspelled originally.
-def fhonor_infinites : Flag<["-"], "fhonor-infinites">, Alias<fhonor_infinities>;
-def fno_honor_infinites : Flag<["-"], "fno-honor-infinites">, Alias<fno_honor_infinities>;
+// This option was originally misspelt "infinites" [sic].
+def : Flag<["-"], "fhonor-infinites">, Alias<fhonor_infinities>;
+def : Flag<["-"], "fno-honor-infinites">, Alias<fno_honor_infinities>;
 def ftrapping_math : Flag<["-"], "ftrapping-math">, Group<f_Group>;
 def fno_trapping_math : Flag<["-"], "fno-trapping-math">, Group<f_Group>;
 def ffp_contract : Joined<["-"], "ffp-contract=">, Group<f_Group>,
@@ -539,16 +572,14 @@
   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 findirect_virtual_calls : Flag<["-"], "findirect-virtual-calls">, Alias<fapple_kext>;
-def finline_functions : Flag<["-"], "finline-functions">, Group<clang_ignored_f_Group>;
+def : Flag<["-"], "findirect-virtual-calls">, Alias<fapple_kext>;
+def finline_functions : Flag<["-"], "finline-functions">, Group<clang_ignored_gcc_optimization_f_Group>;
 def finline : Flag<["-"], "finline">, Group<clang_ignored_f_Group>;
+def finput_charset_EQ : Joined<["-"], "finput-charset=">, Group<f_Group>;
 def finstrument_functions : Flag<["-"], "finstrument-functions">, Group<f_Group>, Flags<[CC1Option]>,
   HelpText<"Generate calls to instrument function entry and exit">;
-def fkeep_inline_functions : Flag<["-"], "fkeep-inline-functions">, Group<clang_ignored_f_Group>;
 def flat__namespace : Flag<["-"], "flat_namespace">;
 def flax_vector_conversions : Flag<["-"], "flax-vector-conversions">, Group<f_Group>;
-def flimit_debug_info : Flag<["-"], "flimit-debug-info">, Group<f_Group>, Flags<[CC1Option]>,
-  HelpText<"Limit debug information produced to reduce size of debug binary">;
 def flimited_precision_EQ : Joined<["-"], "flimited-precision=">, Group<f_Group>;
 def flto : Flag<["-"], "flto">, Group<f_Group>;
 def fno_lto : Flag<["-"], "fno-lto">, Group<f_Group>;
@@ -559,21 +590,45 @@
 def fms_extensions : Flag<["-"], "fms-extensions">, Group<f_Group>, Flags<[CC1Option]>,
   HelpText<"Accept some non-standard constructs supported by the Microsoft compiler">;
 def fms_compatibility : Flag<["-"], "fms-compatibility">, Group<f_Group>, Flags<[CC1Option]>,
-  HelpText<"Enable Microsoft compatibility mode">;
-def fmsc_version : Joined<["-"], "fmsc-version=">, Group<f_Group>, Flags<[CC1Option, CoreOption]>,
-  HelpText<"Version of the Microsoft C/C++ compiler to report in _MSC_VER (0 = don't define it (default))">;
+  HelpText<"Enable full Microsoft Visual C++ compatibility">;
+def fmsc_version : Joined<["-"], "fmsc-version=">, Group<f_Group>, Flags<[DriverOption, CoreOption]>,
+  HelpText<"Microsoft compiler version number to report in _MSC_VER (0 = don't define it (default))">;
+def fms_compatibility_version
+    : Joined<["-"], "fms-compatibility-version=">,
+      Group<f_Group>,
+      Flags<[ CC1Option, CoreOption ]>,
+      HelpText<"Dot-separated value representing the Microsoft compiler "
+               "version number to report in _MSC_VER (0 = don't define it "
+               "(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]>;
+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>">,
   HelpText<"Specify the module cache path">;
+def fmodules_user_build_path : Separate<["-"], "fmodules-user-build-path">, Group<i_Group>,
+  Flags<[DriverOption, CC1Option]>, MetaVarName<"<directory>">,
+  HelpText<"Specify the module user build path">;
 def fmodules_prune_interval : Joined<["-"], "fmodules-prune-interval=">, Group<i_Group>,
   Flags<[CC1Option]>, MetaVarName<"<seconds>">,
   HelpText<"Specify the interval (in seconds) between attempts to prune the module cache">;
 def fmodules_prune_after : Joined<["-"], "fmodules-prune-after=">, Group<i_Group>,
   Flags<[CC1Option]>, MetaVarName<"<seconds>">,
   HelpText<"Specify the interval (in seconds) after which a module file will be considered unused">;
+def fmodules_search_all : Flag <["-"], "fmodules-search-all">, Group<f_Group>,
+  Flags<[DriverOption, CC1Option]>,
+  HelpText<"Search even non-imported modules to resolve references">;
+def fbuild_session_timestamp : Joined<["-"], "fbuild-session-timestamp=">,
+  Group<i_Group>, Flags<[CC1Option]>, MetaVarName<"<time since Epoch in seconds>">,
+  HelpText<"Time when the current build session started">;
+def fmodules_validate_once_per_build_session : Flag<["-"], "fmodules-validate-once-per-build-session">,
+  Group<i_Group>, Flags<[CC1Option]>,
+  HelpText<"Don't verify input files for the modules if the module has been "
+           "successfully validate or loaded during this build session">;
+def fmodules_validate_system_headers : Flag<["-"], "fmodules-validate-system-headers">,
+  Group<i_Group>, Flags<[CC1Option]>,
+  HelpText<"Validate the system headers that a module depends on when loading the module">;
 def fmodules : Flag <["-"], "fmodules">, Group<f_Group>,
   Flags<[DriverOption, CC1Option]>,
   HelpText<"Enable the 'modules' language feature">;
@@ -591,6 +646,11 @@
 def fmodules_decluse : Flag <["-"], "fmodules-decluse">, Group<f_Group>,
   Flags<[DriverOption,CC1Option]>,
   HelpText<"Require declaration of modules used within a module">;
+def fmodules_strict_decluse : Flag <["-"], "fmodules-strict-decluse">, Group<f_Group>,
+  Flags<[DriverOption,CC1Option]>,
+  HelpText<"Like -fmodules-decluse but requires all headers to be in modules">;
+def fno_modules_search_all : Flag <["-"], "fno-modules-search-all">, Group<f_Group>,
+  Flags<[DriverOption, CC1Option]>;
 def fretain_comments_from_system_headers : Flag<["-"], "fretain-comments-from-system-headers">, Group<f_Group>, Flags<[CC1Option]>;
 
 def fmudflapth : Flag<["-"], "fmudflapth">, Group<f_Group>;
@@ -627,7 +687,6 @@
   Flags<[DriverOption]>;
 def fno_diagnostics_fixit_info : Flag<["-"], "fno-diagnostics-fixit-info">, Group<f_Group>,
   Flags<[CC1Option]>, HelpText<"Do not include fixit information in diagnostics">;
-def fno_diagnostics_show_name : Flag<["-"], "fno-diagnostics-show-name">, Group<f_Group>;
 def fno_diagnostics_show_option : Flag<["-"], "fno-diagnostics-show-option">, Group<f_Group>;
 def fno_diagnostics_show_note_include_stack : Flag<["-"], "fno-diagnostics-show-note-include-stack">,
     Flags<[CC1Option]>, Group<f_Group>;
@@ -640,11 +699,8 @@
 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_keep_inline_functions : Flag<["-"], "fno-keep-inline-functions">, Group<clang_ignored_f_Group>;
 def fno_lax_vector_conversions : Flag<["-"], "fno-lax-vector-conversions">, Group<f_Group>,
   HelpText<"Disallow implicit conversions between vectors with a different number of elements or different element types">, Flags<[CC1Option]>;
-def fno_limit_debug_info : Flag<["-"], "fno-limit-debug-info">, Group<f_Group>, Flags<[CC1Option]>,
-  HelpText<"Do not limit debug information produced to reduce size of debug binary">;
 def fno_merge_all_constants : Flag<["-"], "fno-merge-all-constants">, Group<f_Group>,
     Flags<[CC1Option]>, HelpText<"Disallow merging of constants">;
 def fno_modules : Flag <["-"], "fno-modules">, Group<f_Group>,
@@ -653,6 +709,8 @@
   Flags<[DriverOption]>;
 def fno_modules_decluse : Flag <["-"], "fno-modules-decluse">, Group<f_Group>,
   Flags<[DriverOption]>;
+def fno_modules_strict_decluse : Flag <["-"], "fno-strict-modules-decluse">, Group<f_Group>,
+  Flags<[DriverOption]>;
 def fno_ms_extensions : Flag<["-"], "fno-ms-extensions">, Group<f_Group>;
 def fno_ms_compatibility : Flag<["-"], "fno-ms-compatibility">, Group<f_Group>;
 def fno_delayed_template_parsing : Flag<["-"], "fno-delayed-template-parsing">, Group<f_Group>;
@@ -672,8 +730,10 @@
   Flags<[CC1Option]>, HelpText<"Do not include source location information with diagnostics">;
 def fno_spell_checking : Flag<["-"], "fno-spell-checking">, Group<f_Group>,
   Flags<[CC1Option]>, HelpText<"Disable spell-checking">;
-def fno_stack_protector : Flag<["-"], "fno-stack-protector">, Group<f_Group>;
-def fno_strict_aliasing : Flag<["-"], "fno-strict-aliasing">, Group<f_Group>;
+def fno_stack_protector : Flag<["-"], "fno-stack-protector">, Group<f_Group>,
+  HelpText<"Disable the use of stack protectors">;
+def fno_strict_aliasing : Flag<["-"], "fno-strict-aliasing">, Group<f_Group>,
+  Flags<[DriverOption, CoreOption]>;
 def fstruct_path_tbaa : Flag<["-"], "fstruct-path-tbaa">, Group<f_Group>;
 def fno_struct_path_tbaa : Flag<["-"], "fno-struct-path-tbaa">, Group<f_Group>;
 def fno_strict_enums : Flag<["-"], "fno-strict-enums">, Group<f_Group>;
@@ -726,7 +786,8 @@
 
 def fobjc_sender_dependent_dispatch : Flag<["-"], "fobjc-sender-dependent-dispatch">, Group<f_Group>;
 def fomit_frame_pointer : Flag<["-"], "fomit-frame-pointer">, Group<f_Group>;
-def fopenmp : Flag<["-"], "fopenmp">, Group<f_Group>, Flags<[CC1Option]>;
+def fopenmp : Flag<["-"], "fopenmp">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>;
+def fopenmp_EQ : Joined<["-"], "fopenmp=">, Group<f_Group>, Flags<[CC1Option]>;
 def fno_optimize_sibling_calls : Flag<["-"], "fno-optimize-sibling-calls">, Group<f_Group>;
 def foptimize_sibling_calls : Flag<["-"], "foptimize-sibling-calls">, Group<f_Group>;
 def force__cpusubtype__ALL : Flag<["-"], "force_cpusubtype_ALL">;
@@ -753,12 +814,14 @@
 def freg_struct_return : Flag<["-"], "freg-struct-return">, Group<f_Group>, Flags<[CC1Option]>,
   HelpText<"Override the default ABI to return small structs in registers">;
 def frtti : Flag<["-"], "frtti">, Group<f_Group>;
-def fsched_interblock : Flag<["-"], "fsched-interblock">, Group<clang_ignored_f_Group>;
+def : Flag<["-"], "fsched-interblock">, Group<clang_ignored_f_Group>;
 def fshort_enums : Flag<["-"], "fshort-enums">, Group<f_Group>, Flags<[CC1Option]>,
   HelpText<"Allocate to an enum type only as many bytes as it needs for the declared range of possible values">;
-def freorder_blocks : Flag<["-"], "freorder-blocks">, Group<clang_ignored_f_Group>;
+def : Flag<["-"], "freorder-blocks">, Group<clang_ignored_gcc_optimization_f_Group>;
 def fshort_wchar : Flag<["-"], "fshort-wchar">, Group<f_Group>, Flags<[CC1Option]>,
   HelpText<"Force wchar_t to be a short unsigned int">;
+def fno_short_wchar : Flag<["-"], "fno-short-wchar">, Group<f_Group>, Flags<[CC1Option]>,
+  HelpText<"Force wchar_t to be an unsigned int">;
 def fshow_overloads_EQ : Joined<["-"], "fshow-overloads=">, Group<f_Group>, Flags<[CC1Option]>,
   HelpText<"Which overload candidates to show when overload resolution fails: "
            "best|all; defaults to all">;
@@ -770,9 +833,20 @@
 def fno_signed_char : Flag<["-"], "fno-signed-char">, Flags<[CC1Option]>,
     Group<clang_ignored_f_Group>, HelpText<"Char is unsigned">;
 def fsplit_stack : Flag<["-"], "fsplit-stack">, Group<f_Group>;
-def fstack_protector_all : Flag<["-"], "fstack-protector-all">, Group<f_Group>;
-def fstack_protector : Flag<["-"], "fstack-protector">, Group<f_Group>;
-def fstrict_aliasing : Flag<["-"], "fstrict-aliasing">, Group<f_Group>;
+def fstack_protector_all : Flag<["-"], "fstack-protector-all">, Group<f_Group>,
+  HelpText<"Force the usage of stack protectors for all functions">;
+def fstack_protector_strong : Flag<["-"], "fstack-protector-strong">, Group<f_Group>,
+  HelpText<"Use a strong heuristic to apply stack protectors to functions">;
+def fstack_protector : Flag<["-"], "fstack-protector">, Group<f_Group>,
+  HelpText<"Enable stack protectors for functions potentially vulnerable to stack smashing">;
+def fstandalone_debug : Flag<["-"], "fstandalone-debug">, Group<f_Group>, Flags<[CC1Option]>,
+  HelpText<"Emit full debug info for all types used by the program">;
+def fno_standalone_debug : Flag<["-"], "fno-standalone-debug">, Group<f_Group>, Flags<[CC1Option]>,
+  HelpText<"Limit debug information produced to reduce size of debug binary">;
+def flimit_debug_info : Flag<["-"], "flimit-debug-info">, Alias<fno_standalone_debug>;
+def fno_limit_debug_info : Flag<["-"], "fno-limit-debug-info">, Alias<fstandalone_debug>;
+def fstrict_aliasing : Flag<["-"], "fstrict-aliasing">, Group<f_Group>,
+  Flags<[DriverOption, CoreOption]>;
 def fstrict_enums : Flag<["-"], "fstrict-enums">, Group<f_Group>, Flags<[CC1Option]>,
   HelpText<"Enable optimizations based on the strict definition of an enum's "
            "value range">;
@@ -789,29 +863,28 @@
 def fvectorize : Flag<["-"], "fvectorize">, Group<f_Group>,
   HelpText<"Enable the loop vectorization passes">;
 def fno_vectorize : Flag<["-"], "fno-vectorize">, Group<f_Group>;
-def ftree_vectorize : Flag<["-"], "ftree-vectorize">, Alias<fvectorize>;
-def fno_tree_vectorize : Flag<["-"], "fno-tree-vectorize">, Alias<fno_vectorize>;
+def : Flag<["-"], "ftree-vectorize">, Alias<fvectorize>;
+def : Flag<["-"], "fno-tree-vectorize">, Alias<fno_vectorize>;
 def fslp_vectorize : Flag<["-"], "fslp-vectorize">, Group<f_Group>,
   HelpText<"Enable the superword-level parallelism vectorization passes">;
 def fno_slp_vectorize : Flag<["-"], "fno-slp-vectorize">, Group<f_Group>;
 def fslp_vectorize_aggressive : Flag<["-"], "fslp-vectorize-aggressive">, Group<f_Group>,
   HelpText<"Enable the BB vectorization passes">;
 def fno_slp_vectorize_aggressive : Flag<["-"], "fno-slp-vectorize-aggressive">, Group<f_Group>;
-def ftree_slp_vectorize : Flag<["-"], "ftree-slp-vectorize">, Alias<fslp_vectorize>;
-def fno_tree_slp_vectorize : Flag<["-"], "fno-tree-slp-vectorize">, Alias<fno_slp_vectorize>;
+def : Flag<["-"], "ftree-slp-vectorize">, Alias<fslp_vectorize>;
+def : Flag<["-"], "fno-tree-slp-vectorize">, Alias<fno_slp_vectorize>;
 def Wlarge_by_value_copy_def : Flag<["-"], "Wlarge-by-value-copy">,
   HelpText<"Warn if a function definition returns or accepts an object larger "
            "in bytes than a given value">, Flags<[HelpHidden]>;
 def Wlarge_by_value_copy_EQ : Joined<["-"], "Wlarge-by-value-copy=">, Flags<[CC1Option]>;
 
-// Just silence warnings about -Wlarger-than,  -Wframe-larger-than for now.
-def Wlarger_than : Separate<["-"], "Wlarger-than">, Group<clang_ignored_f_Group>;
-def Wlarger_than_EQ : Joined<["-"], "Wlarger-than=">, Alias<Wlarger_than>;
-def Wlarger_than_ : Joined<["-"], "Wlarger-than-">, Alias<Wlarger_than>;
-def Wframe_larger_than : Separate<["-"], "Wframe-larger-than">, Group<clang_ignored_f_Group>;
-def Wframe_larger_than_EQ : Joined<["-"], "Wframe-larger-than=">, Alias<Wframe_larger_than>;
+// These "special" warning flags are effectively processed as f_Group flags by the driver:
+// Just silence warnings about -Wlarger-than for now.
+def Wlarger_than_EQ : Joined<["-"], "Wlarger-than=">, Group<clang_ignored_f_Group>;
+def Wlarger_than_ : Joined<["-"], "Wlarger-than-">, Alias<Wlarger_than_EQ>;
+def Wframe_larger_than_EQ : Joined<["-"], "Wframe-larger-than=">, Group<f_Group>, Flags<[DriverOption]>;
 
-def fterminated_vtables : Flag<["-"], "fterminated-vtables">, Alias<fapple_kext>;
+def : Flag<["-"], "fterminated-vtables">, Alias<fapple_kext>;
 def fthreadsafe_statics : Flag<["-"], "fthreadsafe-statics">, Group<f_Group>;
 def ftime_report : Flag<["-"], "ftime-report">, Group<f_Group>, Flags<[CC1Option]>;
 def ftlsmodel_EQ : Joined<["-"], "ftls-model=">, Group<f_Group>, Flags<[CC1Option]>;
@@ -866,10 +939,13 @@
   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)">;
+def fno_debug_types_section: Flag<["-"], "fno-debug-types-section">, Group<f_Group>,
+  Flags<[CC1Option]>;
 def g_Flag : Flag<["-"], "g">, Group<g_Group>,
-  HelpText<"Generate source level debug information">, Flags<[CC1Option]>;
+  HelpText<"Generate source-level debug information">, Flags<[CC1Option,CC1AsOption]>;
 def gline_tables_only : Flag<["-"], "gline-tables-only">, Group<g_Group>,
   HelpText<"Emit debug line number tables only">, Flags<[CC1Option]>;
+def gmlt : Flag<["-"], "gmlt">, Alias<gline_tables_only>;
 def g0 : Flag<["-"], "g0">, Group<g_Group>;
 def g1 : Flag<["-"], "g1">, Group<g_Group>;
 def g2 : Flag<["-"], "g2">, Group<g_Group>;
@@ -880,11 +956,11 @@
 def ggdb2 : Flag<["-"], "ggdb2">, Group<g_Group>;
 def ggdb3 : Flag<["-"], "ggdb3">, Group<g_Group>;
 def gdwarf_2 : Flag<["-"], "gdwarf-2">, Group<g_Group>,
-  HelpText<"Generate source level debug information with dwarf version 2">, Flags<[CC1Option]>;
+  HelpText<"Generate source-level debug information with dwarf version 2">, Flags<[CC1Option,CC1AsOption]>;
 def gdwarf_3 : Flag<["-"], "gdwarf-3">, Group<g_Group>,
-  HelpText<"Generate source level debug information with dwarf version 3">, Flags<[CC1Option]>;
+  HelpText<"Generate source-level debug information with dwarf version 3">, Flags<[CC1Option,CC1AsOption]>;
 def gdwarf_4 : Flag<["-"], "gdwarf-4">, Group<g_Group>,
-  HelpText<"Generate source level debug information with dwarf version 4">, Flags<[CC1Option]>;
+  HelpText<"Generate source-level debug information with dwarf version 4">, Flags<[CC1Option,CC1AsOption]>;
 def gfull : Flag<["-"], "gfull">, Group<g_Group>;
 def gused : Flag<["-"], "gused">, Group<g_Group>;
 def gstabs : Joined<["-"], "gstabs">, Group<g_Group>, Flags<[Unsupported]>;
@@ -898,10 +974,12 @@
 def gstrict_dwarf : Flag<["-"], "gstrict-dwarf">, Group<g_flags_Group>;
 def gno_strict_dwarf : Flag<["-"], "gno-strict-dwarf">, Group<g_flags_Group>;
 def gcolumn_info : Flag<["-"], "gcolumn-info">, Group<g_flags_Group>;
+def gno_column_info : Flag<["-"], "gno-column-info">, Group<g_flags_Group>;
 def gsplit_dwarf : Flag<["-"], "gsplit-dwarf">, Group<g_flags_Group>;
 def ggnu_pubnames : Flag<["-"], "ggnu-pubnames">, Group<g_flags_Group>;
+def gdwarf_aranges : Flag<["-"], "gdwarf-aranges">, Group<g_flags_Group>;
 def headerpad__max__install__names : Joined<["-"], "headerpad_max_install_names">;
-def help : Flag<["-", "--"], "help">, Flags<[CC1Option]>,
+def help : Flag<["-", "--"], "help">, Flags<[CC1Option,CC1AsOption]>,
   HelpText<"Display available options">;
 def index_header_map : Flag<["-"], "index-header-map">, Flags<[CC1Option]>,
   HelpText<"Make the next included directory (-I or -F) an indexer header map">;
@@ -918,9 +996,10 @@
   HelpText<"Include precompiled header file">, MetaVarName<"<file>">;
 def relocatable_pch : Flag<["-", "--"], "relocatable-pch">, Flags<[CC1Option]>,
   HelpText<"Whether to build a relocatable precompiled header">;
+def verify_pch : Flag<["-"], "verify-pch">, Group<Action_Group>, Flags<[CC1Option]>,
+  HelpText<"Load and verify that a pre-compiled header file is not stale">;
 def init : Separate<["-"], "init">;
 def install__name : Separate<["-"], "install_name">;
-def integrated_as : Flag<["-"], "integrated-as">, Flags<[DriverOption]>;
 def iprefix : JoinedOrSeparate<["-"], "iprefix">, Group<clang_i_Group>, Flags<[CC1Option]>,
   HelpText<"Set the -iwithprefix/-iwithprefixbefore prefix">, MetaVarName<"<dir>">;
 def iquote : JoinedOrSeparate<["-"], "iquote">, Group<clang_i_Group>, Flags<[CC1Option]>,
@@ -938,21 +1017,28 @@
   HelpText<"Add directory to SYSTEM include search path, "
            "absolute paths are relative to -isysroot">, MetaVarName<"<directory>">,
   Flags<[CC1Option]>;
+def ivfsoverlay : JoinedOrSeparate<["-"], "ivfsoverlay">, Group<clang_i_Group>, Flags<[CC1Option]>,
+  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 lazy__framework : Separate<["-"], "lazy_framework">, Flags<[LinkerInput]>;
 def lazy__library : Separate<["-"], "lazy_library">, Flags<[LinkerInput]>;
-def EL : Flag<["-"], "EL">, Flags<[DriverOption]>;
-def EB : Flag<["-"], "EB">, Flags<[DriverOption]>;
+def mlittle_endian : Flag<["-"], "mlittle-endian">, Flags<[DriverOption]>;
+def EL : Flag<["-"], "EL">, Alias<mlittle_endian>;
+def mbig_endian : Flag<["-"], "mbig-endian">, Flags<[DriverOption]>;
+def EB : Flag<["-"], "EB">, Alias<mbig_endian>;
+def m16 : Flag<["-"], "m16">, Group<m_Group>, Flags<[DriverOption, CoreOption]>;
 def m32 : Flag<["-"], "m32">, Group<m_Group>, Flags<[DriverOption, CoreOption]>;
 def mqdsp6_compat : Flag<["-"], "mqdsp6-compat">, Group<m_Group>, Flags<[DriverOption,CC1Option]>,
   HelpText<"Enable hexagon-qdsp6 backward compatibility">;
 def m3dnowa : Flag<["-"], "m3dnowa">, Group<m_x86_Features_Group>;
 def m3dnow : Flag<["-"], "m3dnow">, Group<m_x86_Features_Group>;
 def m64 : Flag<["-"], "m64">, Group<m_Group>, Flags<[DriverOption, CoreOption]>;
+def mx32 : Flag<["-"], "mx32">, Group<m_Group>, Flags<[DriverOption, CoreOption]>;
 def mabi_EQ : Joined<["-"], "mabi=">, Group<m_Group>;
 def march_EQ : Joined<["-"], "march=">, Group<m_Group>;
+def masm_EQ : Joined<["-"], "masm=">, Group<m_Group>, Flags<[DriverOption]>;
 def mcmodel_EQ : Joined<["-"], "mcmodel=">, Group<m_Group>;
 def mconstant_cfstrings : Flag<["-"], "mconstant-cfstrings">, Group<clang_ignored_m_Group>;
 def mcpu_EQ : Joined<["-"], "mcpu=">, Group<m_Group>;
@@ -973,7 +1059,7 @@
 def mkernel : Flag<["-"], "mkernel">, Group<m_Group>;
 def mlinker_version_EQ : Joined<["-"], "mlinker-version=">,
   Flags<[DriverOption]>;
-def mllvm : Separate<["-"], "mllvm">, Flags<[CC1Option]>,
+def mllvm : Separate<["-"], "mllvm">, Flags<[CC1Option,CC1AsOption,CoreOption]>,
   HelpText<"Additional arguments to forward to LLVM's option processing">;
 def mmacosx_version_min_EQ : Joined<["-"], "mmacosx-version-min=">, Group<m_Group>;
 def mms_bitfields : Flag<["-"], "mms-bitfields">, Group<m_Group>, Flags<[CC1Option]>,
@@ -1028,11 +1114,11 @@
 def mno_sha : Flag<["-"], "mno-sha">, Group<m_x86_Features_Group>;
 
 def munaligned_access : Flag<["-"], "munaligned-access">, Group<m_arm_Features_Group>,
-  HelpText<"Allow memory accesses to be unaligned (ARM only)">;
+  HelpText<"Allow memory accesses to be unaligned (AArch32/AArch64 only)">;
 def mno_unaligned_access : Flag<["-"], "mno-unaligned-access">, Group<m_arm_Features_Group>,
-  HelpText<"Force all memory accesses to be aligned (ARM only)">;
+  HelpText<"Force all memory accesses to be aligned (AArch32/AArch64 only)">;
 def mstrict_align : Flag<["-"], "mstrict-align">, Alias<mno_unaligned_access>, Flags<[CC1Option,HelpHidden]>,
-  HelpText<"Force all memory accesses to be aligned (ARM only, same as mno-unaligned-access)">;
+  HelpText<"Force all memory accesses to be aligned (AArch64 only, same as mno-unaligned-access)">;
 def mno_thumb : Flag<["-"], "mno-thumb">, Group<m_arm_Features_Group>;
 def mrestrict_it: Flag<["-"], "mrestrict-it">, Group<m_arm_Features_Group>,
   HelpText<"Disallow generation of deprecated IT blocks for ARMv8. It is on by default for ARMv8 Thumb mode.">;
@@ -1045,6 +1131,13 @@
   HelpText<"Allow use of CRC instructions (ARM only)">;
 def mnocrc : Flag<["-"], "mnocrc">, Group<m_arm_Features_Group>,
   HelpText<"Disallow use of CRC instructions (ARM only)">;
+def mlong_calls : Flag<["-"], "mlong-calls">, Group<m_arm_Features_Group>,
+  HelpText<"Generate an indirect jump to enable jumps further than 64M">;
+def mno_long_calls : Flag<["-"], "mno-long-calls">, Group<m_arm_Features_Group>,
+  HelpText<"Restore the default behaviour of not generating long calls">;
+
+def mgeneral_regs_only : Flag<["-"], "mgeneral-regs-only">, Group<m_aarch64_Features_Group>,
+  HelpText<"Generate code which only uses the general purpose registers (AArch64 only)">;
 
 def mvsx : Flag<["-"], "mvsx">, Group<m_ppc_Features_Group>;
 def mno_vsx : Flag<["-"], "mno-vsx">, Group<m_ppc_Features_Group>;
@@ -1056,6 +1149,8 @@
 def mno_popcntd : Flag<["-"], "mno-popcntd">, Group<m_ppc_Features_Group>;
 def mqpx : Flag<["-"], "mqpx">, Group<m_ppc_Features_Group>;
 def mno_qpx : Flag<["-"], "mno-qpx">, Group<m_ppc_Features_Group>;
+def mcrbits : Flag<["-"], "mcrbits">, Group<m_ppc_Features_Group>;
+def mno_crbits : Flag<["-"], "mno-crbits">, Group<m_ppc_Features_Group>;
 
 def faltivec : Flag<["-"], "faltivec">, Group<f_Group>, Flags<[CC1Option]>,
   HelpText<"Enable AltiVec vector initializer syntax">;
@@ -1071,7 +1166,7 @@
 def mpascal_strings : Flag<["-"], "mpascal-strings">, Alias<fpascal_strings>;
 def mred_zone : Flag<["-"], "mred-zone">, Group<m_Group>;
 def mregparm_EQ : Joined<["-"], "mregparm=">, Group<m_Group>;
-def mrelax_all : Flag<["-"], "mrelax-all">, Group<m_Group>, Flags<[CC1Option]>,
+def mrelax_all : Flag<["-"], "mrelax-all">, Group<m_Group>, Flags<[CC1Option,CC1AsOption]>,
   HelpText<"(integrated-as) Relax all machine instructions">;
 def mrtd : Flag<["-"], "mrtd">, Group<m_Group>, Flags<[CC1Option]>,
   HelpText<"Make StdCall calling convention the default">;
@@ -1138,18 +1233,48 @@
 def mfp32 : Flag<["-"], "mfp32">, Group<m_Group>,
   HelpText<"Use 32-bit floating point registers (MIPS only)">;
 def mnan_EQ : Joined<["-"], "mnan=">, Group<m_Group>;
+def mips1 : Flag<["-"], "mips1">,
+  Alias<march_EQ>, AliasArgs<["mips1"]>,
+  HelpText<"Equivalent to -march=mips1">, Flags<[HelpHidden]>;
+def mips2 : Flag<["-"], "mips2">,
+  Alias<march_EQ>, AliasArgs<["mips2"]>,
+  HelpText<"Equivalent to -march=mips2">, Flags<[HelpHidden]>;
+def mips3 : Flag<["-"], "mips3">,
+  Alias<march_EQ>, AliasArgs<["mips3"]>,
+  HelpText<"Equivalent to -march=mips3">, Flags<[HelpHidden]>;
+def mips4 : Flag<["-"], "mips4">,
+  Alias<march_EQ>, AliasArgs<["mips4"]>,
+  HelpText<"Equivalent to -march=mips4">, Flags<[HelpHidden]>;
+def mips5 : Flag<["-"], "mips5">,
+  Alias<march_EQ>, AliasArgs<["mips5"]>,
+  HelpText<"Equivalent to -march=mips5">, Flags<[HelpHidden]>;
 def mips32 : Flag<["-"], "mips32">,
   Alias<march_EQ>, AliasArgs<["mips32"]>,
   HelpText<"Equivalent to -march=mips32">, Flags<[HelpHidden]>;
 def mips32r2 : Flag<["-"], "mips32r2">,
   Alias<march_EQ>, AliasArgs<["mips32r2"]>,
   HelpText<"Equivalent to -march=mips32r2">, Flags<[HelpHidden]>;
+def mips32r6 : Flag<["-"], "mips32r6">,
+  Alias<march_EQ>, AliasArgs<["mips32r6"]>,
+  HelpText<"Equivalent to -march=mips32r6">, Flags<[HelpHidden]>;
 def mips64 : Flag<["-"], "mips64">,
   Alias<march_EQ>, AliasArgs<["mips64"]>,
   HelpText<"Equivalent to -march=mips64">, Flags<[HelpHidden]>;
 def mips64r2 : Flag<["-"], "mips64r2">,
   Alias<march_EQ>, AliasArgs<["mips64r2"]>,
   HelpText<"Equivalent to -march=mips64r2">, Flags<[HelpHidden]>;
+def mips64r6 : Flag<["-"], "mips64r6">,
+  Alias<march_EQ>, AliasArgs<["mips64r6"]>,
+  HelpText<"Equivalent to -march=mips64r6">, Flags<[HelpHidden]>;
+def mfpxx : Flag<["-"], "mfpxx">, Group<m_Group>,
+  HelpText<"Avoid FPU mode dependent operations when used with the O32 ABI">,
+  Flags<[HelpHidden]>;
+def modd_spreg : Flag<["-"], "modd-spreg">, Group<m_Group>,
+  HelpText<"Enable odd single-precision floating point registers">,
+  Flags<[HelpHidden]>;
+def mno_odd_spreg : Flag<["-"], "mno-odd-spreg">, Group<m_Group>,
+  HelpText<"Disable odd single-precision floating point registers">,
+  Flags<[HelpHidden]>;
 def module_file_info : Flag<["-"], "module-file-info">, Flags<[DriverOption,CC1Option]>, Group<Action_Group>;
 def mthumb : Flag<["-"], "mthumb">, Group<m_Group>;
 def mtune_EQ : Joined<["-"], "mtune=">, Group<m_Group>;
@@ -1160,7 +1285,6 @@
 def no_canonical_prefixes : Flag<["-"], "no-canonical-prefixes">, Flags<[HelpHidden]>,
   HelpText<"Use relative instead of canonical paths">;
 def no_cpp_precomp : Flag<["-"], "no-cpp-precomp">, Group<clang_ignored_f_Group>;
-def no_integrated_as : Flag<["-"], "no-integrated-as">, Flags<[DriverOption]>;
 def no_integrated_cpp : Flag<["-", "--"], "no-integrated-cpp">, Flags<[DriverOption]>;
 def no_pedantic : Flag<["-", "--"], "no-pedantic">, Group<pedantic_Group>;
 def no__dead__strip__inits__and__terms : Flag<["-"], "no_dead_strip_inits_and_terms">;
@@ -1180,7 +1304,7 @@
   HelpText<"Disable standard #include directories for the C++ standard library">;
 def nostdlib : Flag<["-"], "nostdlib">;
 def object : Flag<["-"], "object">;
-def o : JoinedOrSeparate<["-"], "o">, Flags<[DriverOption, RenderAsInput, CC1Option]>,
+def o : JoinedOrSeparate<["-"], "o">, Flags<[DriverOption, RenderAsInput, CC1Option, CC1AsOption]>,
   HelpText<"Write output to <file>">, MetaVarName<"<file>">;
 def pagezero__size : JoinedOrSeparate<["-"], "pagezero_size">;
 def pass_exit_codes : Flag<["-", "--"], "pass-exit-codes">, Flags<[Unsupported]>;
@@ -1228,6 +1352,8 @@
 def r : Flag<["-"], "r">;
 def save_temps : Flag<["-", "--"], "save-temps">, Flags<[DriverOption]>,
   HelpText<"Save intermediate compilation results">;
+def via_file_asm : Flag<["-", "--"], "via-file-asm">, InternalDebugOpt,
+  HelpText<"Write assembly to file for input to assemble jobs">;
 def sectalign : MultiArg<["-"], "sectalign", 3>;
 def sectcreate : MultiArg<["-"], "sectcreate", 3>;
 def sectobjectsymbols : MultiArg<["-"], "sectobjectsymbols", 2>;
@@ -1257,8 +1383,18 @@
   HelpText<"C++ standard library to use">;
 def sub__library : JoinedOrSeparate<["-"], "sub_library">;
 def sub__umbrella : JoinedOrSeparate<["-"], "sub_umbrella">;
+def system_header_prefix : Joined<["--"], "system-header-prefix=">,
+  Group<clang_i_Group>, Flags<[CC1Option]>, MetaVarName<"<prefix>">,
+  HelpText<"Treat all #include paths starting with <prefix> as including a "
+           "system header.">;
+def : Separate<["--"], "system-header-prefix">, Alias<system_header_prefix>;
+def no_system_header_prefix : Joined<["--"], "no-system-header-prefix=">,
+  Group<clang_i_Group>, Flags<[CC1Option]>, MetaVarName<"<prefix>">,
+  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 target : Joined<["--"], "target=">, Flags<[DriverOption]>,
+def target : Joined<["--"], "target=">, Flags<[DriverOption, CoreOption]>,
   HelpText<"Generate code for the given target">;
 def gcc_toolchain : Joined<["--"], "gcc-toolchain=">, Flags<[DriverOption]>,
   HelpText<"Use the gcc toolchain at the given directory">;
@@ -1278,10 +1414,10 @@
   HelpText<"undef all system defines">;
 def unexported__symbols__list : Separate<["-"], "unexported_symbols_list">;
 def u : JoinedOrSeparate<["-"], "u">, Group<u_Group>;
-def v : Flag<["-"], "v">, Flags<[CC1Option]>,
+def v : Flag<["-"], "v">, Flags<[CC1Option, CoreOption]>,
   HelpText<"Show commands to run and use verbose output">;
-def verify : Flag<["-"], "verify">, Flags<[DriverOption,CC1Option]>,
-  HelpText<"Verify output using a verifier">;
+def verify_debug_info : Flag<["--"], "verify-debug-info">, Flags<[DriverOption]>,
+  HelpText<"Verify the binary representation of debug output">;
 def weak_l : Joined<["-"], "weak-l">, Flags<[LinkerInput]>;
 def weak__framework : Separate<["-"], "weak_framework">, Flags<[LinkerInput]>;
 def weak__library : Separate<["-"], "weak_library">, Flags<[LinkerInput]>;
@@ -1294,6 +1430,15 @@
   MetaVarName<"<language>">;
 def y : Joined<["-"], "y">;
 
+def fintegrated_as : Flag<["-"], "fintegrated-as">, Flags<[DriverOption]>,
+                     Group<f_Group>, HelpText<"Enable the integrated assembler">;
+def fno_integrated_as : Flag<["-"], "fno-integrated-as">,
+                        Flags<[CC1Option, DriverOption]>, Group<f_Group>,
+                        HelpText<"Disable the integrated assembler">;
+def : Flag<["-"], "integrated-as">, Alias<fintegrated_as>, Flags<[DriverOption]>;
+def : Flag<["-"], "no-integrated-as">, Alias<fno_integrated_as>,
+      Flags<[CC1Option, DriverOption]>;
+
 def working_directory : JoinedOrSeparate<["-"], "working-directory">, Flags<[CC1Option]>,
   HelpText<"Resolve file paths relative to the specified directory">;
 def working_directory_EQ : Joined<["-"], "working-directory=">, Flags<[CC1Option]>,
@@ -1302,7 +1447,8 @@
 // Double dash options, which are usually an alias for one of the previous
 // options.
 
-def _mhwdiv_EQ : Separate<["--"], "mhwdiv">, Alias<mhwdiv_EQ>;
+def _mhwdiv_EQ : Joined<["--"], "mhwdiv=">, Alias<mhwdiv_EQ>;
+def _mhwdiv : Separate<["--"], "mhwdiv">, Alias<mhwdiv_EQ>;
 def _CLASSPATH_EQ : Joined<["--"], "CLASSPATH=">, Alias<fclasspath_EQ>;
 def _CLASSPATH : Separate<["--"], "CLASSPATH">, Alias<fclasspath_EQ>;
 def _all_warnings : Flag<["--"], "all-warnings">, Alias<Wall>;
@@ -1445,52 +1591,55 @@
   def _fno : Flag<["-"], "fno-"#name>;
 }
 
-def fprofile_dir : Joined<["-"], "fprofile-dir=">, Group<clang_ignored_f_Group>;
+defm : BooleanFFlag<"no-keep-inline-functions">, Group<clang_ignored_gcc_optimization_f_Group>;
 
-defm profile_use : BooleanFFlag<"profile-use">, Group<clang_ignored_f_Group>;
-def fprofile_use_EQ : Joined<["-"], "fprofile-use=">, Group<clang_ignored_f_Group>;
-def fuse_ld_EQ : Joined<["-"], "fuse-ld=">, Group<clang_ignored_f_Group>;
+def fprofile_dir : Joined<["-"], "fprofile-dir=">, Group<clang_ignored_gcc_optimization_f_Group>;
 
-defm align_functions : BooleanFFlag<"align-functions">, Group<clang_ignored_f_Group>;
-def falign_functions_EQ : Joined<["-"], "falign-functions=">, Group<clang_ignored_f_Group>;
+defm profile_use : BooleanFFlag<"profile-use">, Group<clang_ignored_gcc_optimization_f_Group>;
+def fprofile_use_EQ : Joined<["-"], "fprofile-use=">, Group<clang_ignored_gcc_optimization_f_Group>;
+def fuse_ld_EQ : Joined<["-"], "fuse-ld=">, Group<f_Group>;
+
+defm align_functions : BooleanFFlag<"align-functions">, Group<clang_ignored_gcc_optimization_f_Group>;
+def falign_functions_EQ : Joined<["-"], "falign-functions=">, Group<clang_ignored_gcc_optimization_f_Group>;
 
 // FIXME: This option should be supported and wired up to our diognostics, but
 // ignore it for now to avoid breaking builds that use it.
 def fdiagnostics_show_location_EQ : Joined<["-"], "fdiagnostics-show-location=">, Group<clang_ignored_f_Group>;
 
 defm eliminate_unused_debug_types : BooleanFFlag<"eliminate-unused-debug-types">, Group<clang_ignored_f_Group>;
-defm float_store : BooleanFFlag<"float-store">, Group<clang_ignored_f_Group>;
+defm float_store : BooleanFFlag<"float-store">, Group<clang_ignored_gcc_optimization_f_Group>;
 defm function_attribute_list : BooleanFFlag<"function-attribute-list">, Group<clang_ignored_f_Group>;
-defm gcse : BooleanFFlag<"gcse">, Group<clang_ignored_f_Group>;
+defm gcse : BooleanFFlag<"gcse">, Group<clang_ignored_gcc_optimization_f_Group>;
 defm gnu : BooleanFFlag<"gnu">, Group<clang_ignored_f_Group>;
 defm ident : BooleanFFlag<"ident">, Group<clang_ignored_f_Group>;
 defm implicit_templates : BooleanFFlag<"implicit-templates">, Group<clang_ignored_f_Group>;
-defm inline_limit : BooleanFFlag<"inline-limit">, Group<clang_ignored_f_Group>;
-defm ivopts : BooleanFFlag<"ivopts">, Group<clang_ignored_f_Group>;
+def finline_limit_EQ : Joined<["-"], "finline-limit=">, Group<clang_ignored_gcc_optimization_f_Group>;
+defm finline_limit : BooleanFFlag<"inline-limit">, Group<clang_ignored_gcc_optimization_f_Group>;
+defm ivopts : BooleanFFlag<"ivopts">, Group<clang_ignored_gcc_optimization_f_Group>;
 defm non_call_exceptions : BooleanFFlag<"non-call-exceptions">, Group<clang_ignored_f_Group>;
 defm permissive : BooleanFFlag<"permissive">, Group<clang_ignored_f_Group>;
-defm prefetch_loop_arrays : BooleanFFlag<"prefetch-loop-arrays">, Group<clang_ignored_f_Group>;
+defm prefetch_loop_arrays : BooleanFFlag<"prefetch-loop-arrays">, Group<clang_ignored_gcc_optimization_f_Group>;
 defm printf : BooleanFFlag<"printf">, Group<clang_ignored_f_Group>;
 defm profile : BooleanFFlag<"profile">, Group<clang_ignored_f_Group>;
-defm profile_correction : BooleanFFlag<"profile-correction">, Group<clang_ignored_f_Group>;
+defm profile_correction : BooleanFFlag<"profile-correction">, Group<clang_ignored_gcc_optimization_f_Group>;
 defm profile_generate_sampling : BooleanFFlag<"profile-generate-sampling">, Group<clang_ignored_f_Group>;
 defm profile_reusedist : BooleanFFlag<"profile-reusedist">, Group<clang_ignored_f_Group>;
-defm profile_values : BooleanFFlag<"profile-values">, Group<clang_ignored_f_Group>;
+defm profile_values : BooleanFFlag<"profile-values">, Group<clang_ignored_gcc_optimization_f_Group>;
 defm regs_graph : BooleanFFlag<"regs-graph">, Group<clang_ignored_f_Group>;
 defm ripa : BooleanFFlag<"ripa">, Group<clang_ignored_f_Group>;
-defm rounding_math : BooleanFFlag<"rounding-math">, Group<clang_ignored_f_Group>;
-defm schedule_insns : BooleanFFlag<"schedule-insns">, Group<clang_ignored_f_Group>;
+defm rounding_math : BooleanFFlag<"rounding-math">, Group<clang_ignored_gcc_optimization_f_Group>;
+defm schedule_insns : BooleanFFlag<"schedule-insns">, Group<clang_ignored_gcc_optimization_f_Group>;
 defm see : BooleanFFlag<"see">, Group<clang_ignored_f_Group>;
-defm signaling_nans : BooleanFFlag<"signaling-nans">, Group<clang_ignored_f_Group>;
+defm signaling_nans : BooleanFFlag<"signaling-nans">, Group<clang_ignored_gcc_optimization_f_Group>;
 defm spec_constr_count : BooleanFFlag<"spec-constr-count">, Group<clang_ignored_f_Group>;
 defm strength_reduce :
-    BooleanFFlag<"strength-reduce">, Group<clang_ignored_f_Group>;
+    BooleanFFlag<"strength-reduce">, Group<clang_ignored_gcc_optimization_f_Group>;
 defm tls_model : BooleanFFlag<"tls-model">, Group<clang_ignored_f_Group>;
-defm tracer : BooleanFFlag<"tracer">, Group<clang_ignored_f_Group>;
+defm tracer : BooleanFFlag<"tracer">, Group<clang_ignored_gcc_optimization_f_Group>;
 defm tree_salias : BooleanFFlag<"tree-salias">, Group<clang_ignored_f_Group>;
 defm tree_vectorizer_verbose : BooleanFFlag<"tree-vectorizer-verbose">, Group<clang_ignored_f_Group>;
-defm unroll_all_loops : BooleanFFlag<"unroll-all-loops">, Group<clang_ignored_f_Group>;
-defm unswitch_loops : BooleanFFlag<"unswitch-loops">, Group<clang_ignored_f_Group>;
+defm unroll_all_loops : BooleanFFlag<"unroll-all-loops">, Group<clang_ignored_gcc_optimization_f_Group>;
+defm unswitch_loops : BooleanFFlag<"unswitch-loops">, Group<clang_ignored_gcc_optimization_f_Group>;
 
 
 // gfortran options that we recognize in the driver and pass along when
diff --git a/include/clang/Driver/SanitizerArgs.h b/include/clang/Driver/SanitizerArgs.h
index 35b8f89..c79c471 100644
--- a/include/clang/Driver/SanitizerArgs.h
+++ b/include/clang/Driver/SanitizerArgs.h
@@ -9,10 +9,9 @@
 #ifndef CLANG_LIB_DRIVER_SANITIZERARGS_H_
 #define CLANG_LIB_DRIVER_SANITIZERARGS_H_
 
-#include <string>
-
 #include "llvm/Option/Arg.h"
 #include "llvm/Option/ArgList.h"
+#include <string>
 
 namespace clang {
 namespace driver {
@@ -43,14 +42,16 @@
     NeedsLeakDetection = Leak,
     NeedsUbsanRt = Undefined | Integer,
     NotAllowedWithTrap = Vptr,
-    HasZeroBaseShadow = Thread | Memory | DataFlow
+    HasZeroBaseShadow = Thread | Memory | DataFlow,
+    NeedsUnwindTables = Address | Thread | Memory | DataFlow
   };
   unsigned Kind;
 
   std::string BlacklistFile;
-  bool MsanTrackOrigins;
+  int MsanTrackOrigins;
   bool AsanZeroBaseShadow;
   bool UbsanTrapOnError;
+  bool AsanSharedRuntime;
 
  public:
   SanitizerArgs();
@@ -58,6 +59,7 @@
   SanitizerArgs(const ToolChain &TC, const llvm::opt::ArgList &Args);
 
   bool needsAsanRt() const { return Kind & NeedsAsanRt; }
+  bool needsSharedAsanRt() const { return AsanSharedRuntime; }
   bool needsTsanRt() const { return Kind & NeedsTsanRt; }
   bool needsMsanRt() const { return Kind & NeedsMsanRt; }
   bool needsLeakDetection() const { return Kind & NeedsLeakDetection; }
@@ -74,6 +76,7 @@
   bool hasZeroBaseShadow() const {
     return (Kind & HasZeroBaseShadow) || AsanZeroBaseShadow;
   }
+  bool needsUnwindTables() const { return Kind & NeedsUnwindTables; }
   void addArgs(const llvm::opt::ArgList &Args,
                llvm::opt::ArgStringList &CmdArgs) const;
 
@@ -99,7 +102,7 @@
 
   /// Produce an argument string from ArgList \p Args, which shows how it
   /// provides a sanitizer kind in \p Mask. For example, the argument list
-  /// "-fsanitize=thread,vptr -faddress-sanitizer" with mask \c NeedsUbsanRt
+  /// "-fsanitize=thread,vptr -fsanitize=address" with mask \c NeedsUbsanRt
   /// would produce "-fsanitize=vptr".
   static std::string lastArgumentForKind(const Driver &D,
                                          const llvm::opt::ArgList &Args,
diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h
index 84e0b55..550e4df 100644
--- a/include/clang/Driver/ToolChain.h
+++ b/include/clang/Driver/ToolChain.h
@@ -11,12 +11,13 @@
 #define CLANG_DRIVER_TOOLCHAIN_H_
 
 #include "clang/Driver/Action.h"
+#include "clang/Driver/Multilib.h"
 #include "clang/Driver/Types.h"
 #include "clang/Driver/Util.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/Support/Path.h"
+#include <memory>
 #include <string>
 
 namespace llvm {
@@ -65,17 +66,19 @@
   /// programs.
   path_list ProgramPaths;
 
-  mutable OwningPtr<Tool> Clang;
-  mutable OwningPtr<Tool> Assemble;
-  mutable OwningPtr<Tool> Link;
+  mutable std::unique_ptr<Tool> Clang;
+  mutable std::unique_ptr<Tool> Assemble;
+  mutable std::unique_ptr<Tool> Link;
   Tool *getClang() const;
   Tool *getAssemble() const;
   Tool *getLink() const;
   Tool *getClangAs() const;
 
-  mutable OwningPtr<SanitizerArgs> SanitizerArguments;
+  mutable std::unique_ptr<SanitizerArgs> SanitizerArguments;
 
 protected:
+  MultilibSet Multilibs;
+
   ToolChain(const Driver &D, const llvm::Triple &T,
             const llvm::opt::ArgList &Args);
 
@@ -127,6 +130,8 @@
   path_list &getProgramPaths() { return ProgramPaths; }
   const path_list &getProgramPaths() const { return ProgramPaths; }
 
+  const MultilibSet &getMultilibs() const { return Multilibs; }
+
   const SanitizerArgs& getSanitizerArgs() const;
 
   // Tool access.
@@ -139,7 +144,7 @@
   virtual llvm::opt::DerivedArgList *
   TranslateArgs(const llvm::opt::DerivedArgList &Args,
                 const char *BoundArch) const {
-    return 0;
+    return nullptr;
   }
 
   /// Choose a tool to use to handle the action \p JA.
@@ -150,6 +155,10 @@
   std::string GetFilePath(const char *Name) const;
   std::string GetProgramPath(const char *Name) const;
 
+  /// Returns the linker path, respecting the -fuse-ld= argument to determine
+  /// the linker suffix or name.
+  std::string GetLinkerPath() const;
+
   /// \brief Dispatch to the specific toolchain for verbose printing.
   ///
   /// This is used when handling the verbose option to print detailed,
@@ -159,6 +168,10 @@
 
   // Platform defaults information
 
+  /// \brief Returns true if the toolchain is targeting a non-native
+  /// architecture.
+  virtual bool isCrossCompiling() const;
+
   /// HasNativeLTOLinker - Check whether the linker and related tools have
   /// native LLVM support.
   virtual bool HasNativeLLVMSupport() const;
@@ -193,7 +206,7 @@
   virtual bool UseObjCMixedDispatch() const { return false; }
 
   /// GetDefaultStackProtectorLevel - Get the default stack protector level for
-  /// this tool chain (0=off, 1=on, 2=all).
+  /// this tool chain (0=off, 1=on, 2=strong, 3=all).
   virtual unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const {
     return 0;
   }
@@ -275,6 +288,9 @@
   virtual void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
                                      llvm::opt::ArgStringList &CC1Args) const;
 
+  /// \brief Add warning options that need to be passed to cc1 for this target.
+  virtual void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const;
+
   // GetRuntimeLibType - Determine the runtime library type to use with the
   // given compilation arguments.
   virtual RuntimeLibType
@@ -303,7 +319,7 @@
   /// AddFastMathRuntimeIfAvailable - If a runtime library exists that sets
   /// global flags for unsafe floating point math, add it and return true.
   ///
-  /// This checks for presence of the -ffast-math or -funsafe-math flags.
+  /// This checks for presence of the -Ofast, -ffast-math or -funsafe-math flags.
   virtual bool
   AddFastMathRuntimeIfAvailable(const llvm::opt::ArgList &Args,
                                 llvm::opt::ArgStringList &CmdArgs) const;
diff --git a/include/clang/Driver/Types.def b/include/clang/Driver/Types.def
index d4f52d3..3209679 100644
--- a/include/clang/Driver/Types.def
+++ b/include/clang/Driver/Types.def
@@ -54,22 +54,22 @@
 
 // C family input files to precompile.
 TYPE("c-header-cpp-output",      PP_CHeader,   INVALID,         "i",     "p")
-TYPE("c-header",                 CHeader,      PP_CHeader,      0,       "pu")
-TYPE("cl-header",                CLHeader,     PP_CHeader,      0,       "pu")
+TYPE("c-header",                 CHeader,      PP_CHeader,      nullptr, "pu")
+TYPE("cl-header",                CLHeader,     PP_CHeader,      nullptr, "pu")
 TYPE("objective-c-header-cpp-output", PP_ObjCHeader, INVALID,   "mi",    "p")
-TYPE("objective-c-header",       ObjCHeader,   PP_ObjCHeader,   0,       "pu")
+TYPE("objective-c-header",       ObjCHeader,   PP_ObjCHeader,   nullptr, "pu")
 TYPE("c++-header-cpp-output",    PP_CXXHeader, INVALID,         "ii",    "p")
-TYPE("c++-header",               CXXHeader,    PP_CXXHeader,    0,       "pu")
+TYPE("c++-header",               CXXHeader,    PP_CXXHeader,    nullptr, "pu")
 TYPE("objective-c++-header-cpp-output", PP_ObjCXXHeader, INVALID, "mii", "p")
-TYPE("objective-c++-header",     ObjCXXHeader, PP_ObjCXXHeader, 0,       "pu")
+TYPE("objective-c++-header",     ObjCXXHeader, PP_ObjCXXHeader, nullptr, "pu")
 
 // Other languages.
-TYPE("ada",                      Ada,          INVALID,         0,       "u")
+TYPE("ada",                      Ada,          INVALID,         nullptr, "u")
 TYPE("assembler",                PP_Asm,       INVALID,         "s",     "au")
 TYPE("assembler-with-cpp",       Asm,          PP_Asm,          "S",     "au")
-TYPE("f95",                      PP_Fortran,   INVALID,         0,       "u")
-TYPE("f95-cpp-input",            Fortran,      PP_Fortran,      0,       "u")
-TYPE("java",                     Java,         INVALID,         0,       "u")
+TYPE("f95",                      PP_Fortran,   INVALID,         nullptr, "u")
+TYPE("f95-cpp-input",            Fortran,      PP_Fortran,      nullptr, "u")
+TYPE("java",                     Java,         INVALID,         nullptr, "u")
 
 // LLVM IR/LTO types. We define separate types for IR and LTO because LTO
 // outputs should use the standard suffixes.
@@ -87,8 +87,8 @@
 TYPE("remap",                    Remap,        INVALID,         "remap", "")
 TYPE("precompiled-header",       PCH,          INVALID,         "gch",   "A")
 TYPE("object",                   Object,       INVALID,         "o",     "")
-TYPE("treelang",                 Treelang,     INVALID,         0,       "u")
+TYPE("treelang",                 Treelang,     INVALID,         nullptr, "u")
 TYPE("image",                    Image,        INVALID,         "out",   "")
 TYPE("dSYM",                     dSYM,         INVALID,         "dSYM",  "A")
 TYPE("dependencies",             Dependencies, INVALID,         "d",     "")
-TYPE("none",                     Nothing,      INVALID,         0,       "u")
+TYPE("none",                     Nothing,      INVALID,         nullptr, "u")
diff --git a/include/clang/Edit/Commit.h b/include/clang/Edit/Commit.h
index 626b1dd..5cc5b9c 100644
--- a/include/clang/Edit/Commit.h
+++ b/include/clang/Edit/Commit.h
@@ -49,8 +49,7 @@
   const LangOptions &LangOpts;
   const PPConditionalDirectiveRecord *PPRec;
   EditedSource *Editor;
-  
-  const bool ForceCommitInSystemHeader;
+
   bool IsCommitable;
   SmallVector<Edit, 8> CachedEdits;
   
@@ -59,9 +58,9 @@
 public:
   explicit Commit(EditedSource &Editor);
   Commit(const SourceManager &SM, const LangOptions &LangOpts,
-         const PPConditionalDirectiveRecord *PPRec = 0)
-    : SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec), Editor(0),
-      ForceCommitInSystemHeader(true), IsCommitable(true) { }
+         const PPConditionalDirectiveRecord *PPRec = nullptr)
+    : SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec), Editor(nullptr),
+      IsCommitable(true) { }
 
   bool isCommitable() const { return IsCommitable; }
 
@@ -132,9 +131,9 @@
   void commitRemove(FileOffset offset, unsigned length);
 
   bool isAtStartOfMacroExpansion(SourceLocation loc,
-                                 SourceLocation *MacroBegin = 0) const;
+                                 SourceLocation *MacroBegin = nullptr) const;
   bool isAtEndOfMacroExpansion(SourceLocation loc,
-                               SourceLocation *MacroEnd = 0) const;
+                               SourceLocation *MacroEnd = nullptr) const;
 
   StringRef copyString(StringRef str) {
     char *buf = StrAlloc.Allocate<char>(str.size());
diff --git a/include/clang/Edit/EditedSource.h b/include/clang/Edit/EditedSource.h
index 3ad5a6b..150a5b4 100644
--- a/include/clang/Edit/EditedSource.h
+++ b/include/clang/Edit/EditedSource.h
@@ -28,7 +28,6 @@
   const SourceManager &SourceMgr;
   const LangOptions &LangOpts;
   const PPConditionalDirectiveRecord *PPRec;
-  const bool ForceCommitInSystemHeader;
 
   struct FileEdit {
     StringRef Text;
@@ -46,21 +45,15 @@
 
 public:
   EditedSource(const SourceManager &SM, const LangOptions &LangOpts,
-               const PPConditionalDirectiveRecord *PPRec = 0,
-               const bool FCommitInSystemHeader = true)
+               const PPConditionalDirectiveRecord *PPRec = nullptr)
     : SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec),
-      ForceCommitInSystemHeader(FCommitInSystemHeader),
-      StrAlloc(/*size=*/512) { }
+      StrAlloc() { }
 
   const SourceManager &getSourceManager() const { return SourceMgr; }
   const LangOptions &getLangOpts() const { return LangOpts; }
   const PPConditionalDirectiveRecord *getPPCondDirectiveRecord() const {
     return PPRec;
   }
-  
-  bool getForceCommitInSystemHeader() const {
-    return ForceCommitInSystemHeader;
-  }
 
   bool canInsertInOffset(SourceLocation OrigLoc, FileOffset Offs);
 
diff --git a/include/clang/Edit/FileOffset.h b/include/clang/Edit/FileOffset.h
index 675ad18..0c1e72b 100644
--- a/include/clang/Edit/FileOffset.h
+++ b/include/clang/Edit/FileOffset.h
@@ -41,20 +41,16 @@
     return !(LHS == RHS);
   }
   friend bool operator<(FileOffset LHS, FileOffset RHS) {
-    if (LHS.FID != RHS.FID)
-      return LHS.FID < RHS.FID;
-    return LHS.Offs < RHS.Offs;
+    return std::tie(LHS.FID, LHS.Offs) < std::tie(RHS.FID, RHS.Offs);
   }
   friend bool operator>(FileOffset LHS, FileOffset RHS) {
-    if (LHS.FID != RHS.FID)
-      return LHS.FID > RHS.FID;
-    return LHS.Offs > RHS.Offs;
+    return RHS < LHS;
   }
   friend bool operator>=(FileOffset LHS, FileOffset RHS) {
-    return LHS > RHS || LHS == RHS;
+    return !(LHS < RHS);
   }
   friend bool operator<=(FileOffset LHS, FileOffset RHS) {
-    return LHS < RHS || LHS == RHS;
+    return !(RHS < LHS);
   }
 };
 
diff --git a/include/clang/Format/Format.h b/include/clang/Format/Format.h
index 0f27467..45cccaa 100644
--- a/include/clang/Format/Format.h
+++ b/include/clang/Format/Format.h
@@ -17,7 +17,7 @@
 
 #include "clang/Frontend/FrontendAction.h"
 #include "clang/Tooling/Refactoring.h"
-#include "llvm/Support/system_error.h"
+#include <system_error>
 
 namespace clang {
 
@@ -27,19 +27,49 @@
 
 namespace format {
 
+enum class ParseError { Success = 0, Error, Unsuitable };
+class ParseErrorCategory final : public std::error_category {
+public:
+  const char *name() const LLVM_NOEXCEPT override;
+  std::string message(int EV) const override;
+};
+const std::error_category &getParseCategory();
+std::error_code make_error_code(ParseError e);
+
 /// \brief The \c FormatStyle is used to configure the formatting to follow
 /// specific guidelines.
 struct FormatStyle {
+  /// \brief Supported languages. When stored in a configuration file, specifies
+  /// the language, that the configuration targets. When passed to the
+  /// reformat() function, enables syntax features specific to the language.
+  enum LanguageKind {
+    /// Do not use.
+    LK_None,
+    /// Should be used for C, C++, ObjectiveC, ObjectiveC++.
+    LK_Cpp,
+    /// Should be used for JavaScript.
+    LK_JavaScript,
+    /// Should be used for Protocol Buffers
+    /// (https://developers.google.com/protocol-buffers/).
+    LK_Proto
+  };
+
+  /// \brief Language, this format style is targeted at.
+  LanguageKind Language;
+
   /// \brief The column limit.
   ///
   /// A column limit of \c 0 means that there is no column limit. In this case,
   /// clang-format will respect the input's line breaking decisions within
-  /// statements.
+  /// statements unless they contradict other rules.
   unsigned ColumnLimit;
 
   /// \brief The maximum number of consecutive empty lines to keep.
   unsigned MaxEmptyLinesToKeep;
 
+  /// \brief If true, empty lines at the start of blocks are kept.
+  bool KeepEmptyLinesAtTheStartOfBlocks;
+
   /// \brief The penalty for each line break introduced inside a comment.
   unsigned PenaltyBreakComment;
 
@@ -55,11 +85,22 @@
   /// \brief The penalty for breaking a function call after "call(".
   unsigned PenaltyBreakBeforeFirstCallParameter;
 
-  /// \brief Set whether & and * bind to the type as opposed to the variable.
-  bool PointerBindsToType;
+  /// \brief The & and * alignment style.
+  enum PointerAlignmentStyle {
+    /// Align pointer to the left.
+    PAS_Left,
+    /// Align pointer to the right.
+    PAS_Right,
+    /// Align pointer in the middle.
+    PAS_Middle
+  };
 
-  /// \brief If \c true, analyze the formatted file for the most common binding.
-  bool DerivePointerBinding;
+  /// Pointer and reference alignment style.
+  PointerAlignmentStyle PointerAlignment;
+
+  /// \brief If \c true, analyze the formatted file for the most common
+  /// alignment of & and *. \c PointerAlignment is then used only as fallback.
+  bool DerivePointerAlignment;
 
   /// \brief The extra indent or outdent of access modifiers, e.g. \c public:.
   int AccessModifierOffset;
@@ -85,6 +126,10 @@
   /// Switch statement body is always indented one level more than case labels.
   bool IndentCaseLabels;
 
+  /// \brief Indent if a function definition or declaration is wrapped after the
+  /// type.
+  bool IndentWrappedFunctionNames;
+
   /// \brief Different ways to indent namespace contents.
   enum NamespaceIndentationKind {
     /// Don't indent in namespaces.
@@ -98,7 +143,11 @@
   /// \brief The indentation used for namespaces.
   NamespaceIndentationKind NamespaceIndentation;
 
-  /// \brief The number of spaces to before trailing line comments.
+  /// \brief The number of spaces before trailing line comments
+  /// (\c // - comments).
+  ///
+  /// This does not affect trailing block comments (\c /**/ - comments) as those
+  /// commonly have different usage patterns and a number of special cases.
   unsigned SpacesBeforeTrailingComments;
 
   /// \brief If \c false, a function call's or function definition's parameters
@@ -133,6 +182,11 @@
   /// the commas with the colon.
   bool BreakConstructorInitializersBeforeComma;
 
+  /// \brief Allows contracting simple braced statements to a single line.
+  ///
+  /// E.g., this allows <tt>if (a) { return; }</tt> to be put on a single line.
+  bool AllowShortBlocksOnASingleLine;
+
   /// \brief If \c true, <tt>if (a) return;</tt> can be put on a single
   /// line.
   bool AllowShortIfStatementsOnASingleLine;
@@ -141,6 +195,25 @@
   /// single line.
   bool AllowShortLoopsOnASingleLine;
 
+  /// \brief Different styles for merging short functions containing at most one
+  /// statement.
+  enum ShortFunctionStyle {
+    /// \brief Never merge functions into a single line.
+    SFS_None,
+    /// \brief Only merge functions defined inside a class.
+    SFS_Inline,
+    /// \brief Merge all functions fitting on a single line.
+    SFS_All,
+  };
+
+  /// \brief Dependent on the value, <tt>int f() { return 0; }</tt> can be put
+  /// on a single line.
+  ShortFunctionStyle AllowShortFunctionsOnASingleLine;
+
+  /// \brief Add a space after \c @property in Objective-C, i.e. use
+  /// <tt>\@property (readonly)</tt> instead of <tt>\@property(readonly)</tt>.
+  bool ObjCSpaceAfterProperty;
+
   /// \brief Add a space in front of an Objective-C protocol list, i.e. use
   /// <tt>Foo <Protocol></tt> instead of \c Foo<Protocol>.
   bool ObjCSpaceBeforeProtocolList;
@@ -199,7 +272,11 @@
     /// Like \c Attach, but break before function definitions.
     BS_Stroustrup,
     /// Always break before braces.
-    BS_Allman
+    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.
+    BS_GNU
   };
 
   /// \brief The brace breaking style to use.
@@ -220,10 +297,6 @@
   /// a zero-length name is assumed.
   bool Cpp11BracedListStyle;
 
-  /// \brief If \c true, indent when breaking function declarations which
-  /// are not also definitions after the type.
-  bool IndentFunctionDeclarationAfterType;
-
   /// \brief If \c true, spaces will be inserted after '(' and before ')'.
   bool SpacesInParentheses;
 
@@ -231,15 +304,32 @@
   /// template argument lists
   bool SpacesInAngles;
 
-  /// \brief If \c false, spaces may be inserted into '()'.
+  /// \brief If \c true, spaces may be inserted into '()'.
   bool SpaceInEmptyParentheses;
 
-  /// \brief If \c false, spaces may be inserted into C style casts.
+  /// \brief If \c true, spaces are inserted inside container literals (e.g.
+  /// ObjC and Javascript array and dict literals).
+  bool SpacesInContainerLiterals;
+
+  /// \brief If \c true, spaces may be inserted into C style casts.
   bool SpacesInCStyleCastParentheses;
 
-  /// \brief If \c true, spaces will be inserted between 'for'/'if'/'while'/...
-  /// and '('.
-  bool SpaceAfterControlStatementKeyword;
+  /// \brief Different ways to put a space before opening parentheses.
+  enum SpaceBeforeParensOptions {
+    /// Never put a space before opening parentheses.
+    SBPO_Never,
+    /// Put a space before opening parentheses only after control statement
+    /// keywords (<tt>for/if/while...</tt>).
+    SBPO_ControlStatements,
+    /// Always put a space before opening parentheses, except when it's
+    /// prohibited by the syntax rules (in function-like macro definitions) or
+    /// when determined by other style rules (after unary operators, opening
+    /// parentheses, etc.)
+    SBPO_Always
+  };
+
+  /// \brief Defines in which cases to put a space before opening parentheses.
+  SpaceBeforeParensOptions SpaceBeforeParens;
 
   /// \brief If \c false, spaces will be removed before assignment operators.
   bool SpaceBeforeAssignmentOperators;
@@ -247,6 +337,25 @@
   /// \brief Indent width for line continuations.
   unsigned ContinuationIndentWidth;
 
+  /// \brief A regular expression that describes comments with special meaning,
+  /// which should not be split into lines or otherwise changed.
+  std::string CommentPragmas;
+
+  /// \brief Disables formatting at all.
+  bool DisableFormat;
+
+  /// \brief A vector of macros that should be interpreted as foreach loops
+  /// instead of as function calls.
+  ///
+  /// These are expected to be macros of the form:
+  /// \code
+  /// FOREACH(<variable-declaration>, ...)
+  ///   <loop-body>
+  /// \endcode
+  ///
+  /// For example: BOOST_FOREACH.
+  std::vector<std::string> ForEachMacros;
+
   bool operator==(const FormatStyle &R) const {
     return AccessModifierOffset == R.AccessModifierOffset &&
            ConstructorInitializerIndentWidth ==
@@ -255,6 +364,9 @@
            AlignTrailingComments == R.AlignTrailingComments &&
            AllowAllParametersOfDeclarationOnNextLine ==
                R.AllowAllParametersOfDeclarationOnNextLine &&
+           AllowShortFunctionsOnASingleLine ==
+               R.AllowShortFunctionsOnASingleLine &&
+           AllowShortBlocksOnASingleLine == R.AllowShortBlocksOnASingleLine &&
            AllowShortIfStatementsOnASingleLine ==
                R.AllowShortIfStatementsOnASingleLine &&
            AllowShortLoopsOnASingleLine == R.AllowShortLoopsOnASingleLine &&
@@ -271,33 +383,37 @@
            ColumnLimit == R.ColumnLimit &&
            ConstructorInitializerAllOnOneLineOrOnePerLine ==
                R.ConstructorInitializerAllOnOneLineOrOnePerLine &&
-           DerivePointerBinding == R.DerivePointerBinding &&
+           DerivePointerAlignment == R.DerivePointerAlignment &&
            ExperimentalAutoDetectBinPacking ==
                R.ExperimentalAutoDetectBinPacking &&
            IndentCaseLabels == R.IndentCaseLabels &&
-           IndentFunctionDeclarationAfterType ==
-               R.IndentFunctionDeclarationAfterType &&
-           IndentWidth == R.IndentWidth &&
+           IndentWrappedFunctionNames == R.IndentWrappedFunctionNames &&
+           IndentWidth == R.IndentWidth && Language == R.Language &&
            MaxEmptyLinesToKeep == R.MaxEmptyLinesToKeep &&
+           KeepEmptyLinesAtTheStartOfBlocks ==
+               R.KeepEmptyLinesAtTheStartOfBlocks &&
            NamespaceIndentation == R.NamespaceIndentation &&
+           ObjCSpaceAfterProperty == R.ObjCSpaceAfterProperty &&
            ObjCSpaceBeforeProtocolList == R.ObjCSpaceBeforeProtocolList &&
            PenaltyBreakComment == R.PenaltyBreakComment &&
            PenaltyBreakFirstLessLess == R.PenaltyBreakFirstLessLess &&
            PenaltyBreakString == R.PenaltyBreakString &&
            PenaltyExcessCharacter == R.PenaltyExcessCharacter &&
            PenaltyReturnTypeOnItsOwnLine == R.PenaltyReturnTypeOnItsOwnLine &&
-           PointerBindsToType == R.PointerBindsToType &&
+           PointerAlignment == R.PointerAlignment &&
            SpacesBeforeTrailingComments == R.SpacesBeforeTrailingComments &&
            Cpp11BracedListStyle == R.Cpp11BracedListStyle &&
            Standard == R.Standard && TabWidth == R.TabWidth &&
            UseTab == R.UseTab && SpacesInParentheses == R.SpacesInParentheses &&
            SpacesInAngles == R.SpacesInAngles &&
            SpaceInEmptyParentheses == R.SpaceInEmptyParentheses &&
+           SpacesInContainerLiterals == R.SpacesInContainerLiterals &&
            SpacesInCStyleCastParentheses == R.SpacesInCStyleCastParentheses &&
-           SpaceAfterControlStatementKeyword ==
-               R.SpaceAfterControlStatementKeyword &&
+           SpaceBeforeParens == R.SpaceBeforeParens &&
            SpaceBeforeAssignmentOperators == R.SpaceBeforeAssignmentOperators &&
-           ContinuationIndentWidth == R.ContinuationIndentWidth;
+           ContinuationIndentWidth == R.ContinuationIndentWidth &&
+           CommentPragmas == R.CommentPragmas &&
+           ForEachMacros == R.ForEachMacros;
   }
 };
 
@@ -305,13 +421,15 @@
 /// http://llvm.org/docs/CodingStandards.html.
 FormatStyle getLLVMStyle();
 
-/// \brief Returns a format style complying with Google's C++ style guide:
+/// \brief Returns a format style complying with one of Google's style guides:
 /// http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml.
-FormatStyle getGoogleStyle();
+/// http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml.
+/// https://developers.google.com/protocol-buffers/docs/style.
+FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language);
 
 /// \brief Returns a format style complying with Chromium's style guide:
 /// http://www.chromium.org/developers/coding-style.
-FormatStyle getChromiumStyle();
+FormatStyle getChromiumStyle(FormatStyle::LanguageKind Language);
 
 /// \brief Returns a format style complying with Mozilla's style guide:
 /// https://developer.mozilla.org/en-US/docs/Developer_Guide/Coding_Style.
@@ -321,16 +439,30 @@
 /// http://www.webkit.org/coding/coding-style.html
 FormatStyle getWebKitStyle();
 
-/// \brief Gets a predefined style by name.
+/// \brief Returns a format style complying with GNU Coding Standards:
+/// http://www.gnu.org/prep/standards/standards.html
+FormatStyle getGNUStyle();
+
+/// \brief Returns style indicating formatting should be not applied at all.
+FormatStyle getNoStyle();
+
+/// \brief Gets a predefined style for the specified language by name.
 ///
 /// Currently supported names: LLVM, Google, Chromium, Mozilla. Names are
 /// compared case-insensitively.
 ///
 /// Returns \c true if the Style has been set.
-bool getPredefinedStyle(StringRef Name, FormatStyle *Style);
+bool getPredefinedStyle(StringRef Name, FormatStyle::LanguageKind Language,
+                        FormatStyle *Style);
 
 /// \brief Parse configuration from YAML-formatted text.
-llvm::error_code parseConfiguration(StringRef Text, FormatStyle *Style);
+///
+/// Style->Language is used to get the base style, if the \c BasedOnStyle
+/// option is present.
+///
+/// When \c BasedOnStyle is not present, options not present in the YAML
+/// document, are retained in \p Style.
+std::error_code parseConfiguration(StringRef Text, FormatStyle *Style);
 
 /// \brief Gets configuration in a YAML string.
 std::string configurationAsText(const FormatStyle &Style);
@@ -359,8 +491,8 @@
 ///
 /// \param Standard determines lexing mode: LC_Cpp11 and LS_Auto turn on C++11
 /// lexing mode, LS_Cpp03 - C++03 mode.
-LangOptions getFormattingLangOpts(FormatStyle::LanguageStandard Standard =
-                                      FormatStyle::LS_Cpp11);
+LangOptions getFormattingLangOpts(
+    FormatStyle::LanguageStandard Standard = FormatStyle::LS_Cpp11);
 
 /// \brief Description to be used for help text for a llvm::cl option for
 /// specifying format style. The description is closely related to the operation
@@ -381,12 +513,20 @@
 /// above.
 /// \param[in] FileName Path to start search for .clang-format if \c 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.
 ///
 /// \returns FormatStyle as specified by \c StyleName. If no style could be
 /// determined, the default is LLVM Style (see getLLVMStyle()).
-FormatStyle getStyle(StringRef StyleName, StringRef FileName);
+FormatStyle getStyle(StringRef StyleName, StringRef FileName,
+                     StringRef FallbackStyle);
 
 } // end namespace format
 } // end namespace clang
 
+namespace std {
+template <>
+struct is_error_code_enum<clang::format::ParseError> : std::true_type {};
+}
+
 #endif // LLVM_CLANG_FORMAT_FORMAT_H
diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h
index 43d77f0..42dc69a 100644
--- a/include/clang/Frontend/ASTUnit.h
+++ b/include/clang/Frontend/ASTUnit.h
@@ -27,12 +27,13 @@
 #include "clang/Sema/CodeCompleteConsumer.h"
 #include "clang/Serialization/ASTBitCodes.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringMap.h"
+#include "llvm/Support/MD5.h"
 #include "llvm/Support/Path.h"
 #include <cassert>
 #include <map>
+#include <memory>
 #include <string>
 #include <sys/types.h>
 #include <utility>
@@ -63,33 +64,51 @@
 /// \brief Utility class for loading a ASTContext from an AST file.
 ///
 class ASTUnit : public ModuleLoader {
+public:
+  struct StandaloneFixIt {
+    std::pair<unsigned, unsigned> RemoveRange;
+    std::pair<unsigned, unsigned> InsertFromRange;
+    std::string CodeToInsert;
+    bool BeforePreviousInsertions;
+  };
+
+  struct StandaloneDiagnostic {
+    unsigned ID;
+    DiagnosticsEngine::Level Level;
+    std::string Message;
+    std::string Filename;
+    unsigned LocOffset;
+    std::vector<std::pair<unsigned, unsigned> > Ranges;
+    std::vector<StandaloneFixIt> FixIts;
+  };
+
 private:
-  IntrusiveRefCntPtr<LangOptions>         LangOpts;
+  std::shared_ptr<LangOptions>            LangOpts;
   IntrusiveRefCntPtr<DiagnosticsEngine>   Diagnostics;
   IntrusiveRefCntPtr<FileManager>         FileMgr;
   IntrusiveRefCntPtr<SourceManager>       SourceMgr;
-  OwningPtr<HeaderSearch>                 HeaderInfo;
+  std::unique_ptr<HeaderSearch>           HeaderInfo;
   IntrusiveRefCntPtr<TargetInfo>          Target;
   IntrusiveRefCntPtr<Preprocessor>        PP;
   IntrusiveRefCntPtr<ASTContext>          Ctx;
-  IntrusiveRefCntPtr<TargetOptions>       TargetOpts;
+  std::shared_ptr<TargetOptions>          TargetOpts;
   IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts;
-  ASTReader *Reader;
+  IntrusiveRefCntPtr<ASTReader> Reader;
   bool HadModuleLoaderFatalFailure;
 
   struct ASTWriterData;
-  OwningPtr<ASTWriterData> WriterData;
+  std::unique_ptr<ASTWriterData> WriterData;
 
   FileSystemOptions FileSystemOpts;
 
   /// \brief The AST consumer that received information about the translation
   /// unit as it was parsed or loaded.
-  OwningPtr<ASTConsumer> Consumer;
-  
+  std::unique_ptr<ASTConsumer> Consumer;
+
   /// \brief The semantic analysis object used to type-check the translation
   /// unit.
-  OwningPtr<Sema> TheSema;
-  
+  std::unique_ptr<Sema> TheSema;
+
   /// Optional owned invocation, just used to make the invocation used in
   /// LoadFromCommandLine available.
   IntrusiveRefCntPtr<CompilerInvocation> Invocation;
@@ -135,7 +154,7 @@
   std::string OriginalSourceFile;
 
   /// \brief The set of diagnostics produced when creating the preamble.
-  SmallVector<StoredDiagnostic, 4> PreambleDiagnostics;
+  SmallVector<StandaloneDiagnostic, 4> PreambleDiagnostics;
 
   /// \brief The set of diagnostics produced when creating this
   /// translation unit.
@@ -170,7 +189,7 @@
     mutable unsigned NumLines;
     
   public:
-    PreambleData() : File(0), NumLines(0) { }
+    PreambleData() : File(nullptr), NumLines(0) { }
     
     void assign(const FileEntry *F, const char *begin, const char *end) {
       File = F;
@@ -178,7 +197,7 @@
       NumLines = 0;
     }
 
-    void clear() { Buffer.clear(); File = 0; NumLines = 0; }
+    void clear() { Buffer.clear(); File = nullptr; NumLines = 0; }
 
     size_t size() const { return Buffer.size(); }
     bool empty() const { return Buffer.empty(); }
@@ -205,8 +224,34 @@
     return Preamble;
   }
 
-private:
+  /// Data used to determine if a file used in the preamble has been changed.
+  struct PreambleFileHash {
+    /// All files have size set.
+    off_t Size;
 
+    /// Modification time is set for files that are on disk.  For memory
+    /// buffers it is zero.
+    time_t ModTime;
+
+    /// Memory buffers have MD5 instead of modification time.  We don't
+    /// compute MD5 for on-disk files because we hope that modification time is
+    /// enough to tell if the file was changed.
+    llvm::MD5::MD5Result MD5;
+
+    static PreambleFileHash createForFile(off_t Size, time_t ModTime);
+    static PreambleFileHash
+    createForMemoryBuffer(const llvm::MemoryBuffer *Buffer);
+
+    friend bool operator==(const PreambleFileHash &LHS,
+                           const PreambleFileHash &RHS);
+
+    friend bool operator!=(const PreambleFileHash &LHS,
+                           const PreambleFileHash &RHS) {
+      return !(LHS == RHS);
+    }
+  };
+
+private:
   /// \brief The contents of the preamble that has been precompiled to
   /// \c PreambleFile.
   PreambleData Preamble;
@@ -216,17 +261,13 @@
   /// Used to inform the lexer as to whether it's starting at the beginning of
   /// a line after skipping the preamble.
   bool PreambleEndsAtStartOfLine;
-  
-  /// \brief The size of the source buffer that we've reserved for the main 
-  /// file within the precompiled preamble.
-  unsigned PreambleReservedSize;
 
   /// \brief Keeps track of the files that were used when computing the 
   /// preamble, with both their buffer size and their modification time.
   ///
   /// If any of the files have changed from one compile to the next,
   /// the preamble must be thrown away.
-  llvm::StringMap<std::pair<off_t, time_t> > FilesInPreamble;
+  llvm::StringMap<PreambleFileHash> FilesInPreamble;
 
   /// \brief When non-NULL, this is the buffer used to store the contents of
   /// the main file when it has been padded for use with the precompiled
@@ -268,9 +309,9 @@
                              const char **ArgBegin, const char **ArgEnd,
                              ASTUnit &AST, bool CaptureDiagnostics);
 
-  void TranslateStoredDiagnostics(ASTReader *MMan, StringRef ModName,
+  void TranslateStoredDiagnostics(FileManager &FileMgr,
                                   SourceManager &SrcMan,
-                      const SmallVectorImpl<StoredDiagnostic> &Diags,
+                      const SmallVectorImpl<StandaloneDiagnostic> &Diags,
                             SmallVectorImpl<StoredDiagnostic> &Out);
 
   void clearFileLevelDecls();
@@ -337,8 +378,8 @@
   /// \brief Allocator used to store cached code completions.
   IntrusiveRefCntPtr<GlobalCodeCompletionAllocator>
     CachedCompletionAllocator;
-  
-  OwningPtr<CodeCompletionTUInfo> CCTUInfo;
+
+  std::unique_ptr<CodeCompletionTUInfo> CCTUInfo;
 
   /// \brief The set of cached code-completion results.
   std::vector<CachedCodeCompletionResult> CachedCompletionResults;
@@ -406,9 +447,7 @@
   /// just about any usage.
   /// Becomes a noop in release mode; only useful for debug mode checking.
   class ConcurrencyState {
-#ifndef NDEBUG
     void *Mutex; // a llvm::sys::MutexImpl in debug;
-#endif
 
   public:
     ConcurrencyState();
@@ -457,10 +496,15 @@
   void setASTContext(ASTContext *ctx) { Ctx = ctx; }
   void setPreprocessor(Preprocessor *pp);
 
-  bool hasSema() const { return TheSema.isValid(); }
+  bool hasSema() const { return (bool)TheSema; }
   Sema &getSema() const { 
     assert(TheSema && "ASTUnit does not have a Sema object!");
-    return *TheSema; 
+    return *TheSema;
+  }
+
+  const LangOptions &getLangOpts() const {
+    assert(LangOpts && " ASTUnit does not have language options");
+    return *LangOpts;
   }
   
   const FileManager &getFileManager() const { return *FileMgr; }
@@ -641,16 +685,14 @@
   bool isModuleFile();
 
   llvm::MemoryBuffer *getBufferForFile(StringRef Filename,
-                                       std::string *ErrorStr = 0);
+                                       std::string *ErrorStr = nullptr);
 
   /// \brief Determine what kind of translation unit this AST represents.
   TranslationUnitKind getTranslationUnitKind() const { return TUKind; }
 
-  typedef llvm::PointerUnion<const char *, const llvm::MemoryBuffer *>
-      FilenameOrMemBuf;
   /// \brief A mapping from a file name to the memory buffer that stores the
   /// remapped contents of that file.
-  typedef std::pair<std::string, FilenameOrMemBuf> RemappedFile;
+  typedef std::pair<std::string, llvm::MemoryBuffer *> RemappedFile;
 
   /// \brief Create a ASTUnit. Gets ownership of the passed CompilerInvocation. 
   static ASTUnit *create(CompilerInvocation *CI,
@@ -670,8 +712,7 @@
                               IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
                                   const FileSystemOptions &FileSystemOpts,
                                   bool OnlyLocalDecls = false,
-                                  RemappedFile *RemappedFiles = 0,
-                                  unsigned NumRemappedFiles = 0,
+                                  ArrayRef<RemappedFile> RemappedFiles = None,
                                   bool CaptureDiagnostics = false,
                                   bool AllowPCHWithCompilerErrors = false,
                                   bool UserFilesAreVolatile = false);
@@ -714,19 +755,15 @@
   /// This will only receive an ASTUnit if a new one was created. If an already
   /// created ASTUnit was passed in \p Unit then the caller can check that.
   ///
-  static ASTUnit *LoadFromCompilerInvocationAction(CompilerInvocation *CI,
-                              IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
-                                             ASTFrontendAction *Action = 0,
-                                             ASTUnit *Unit = 0,
-                                             bool Persistent = true,
-                                      StringRef ResourceFilesPath = StringRef(),
-                                             bool OnlyLocalDecls = false,
-                                             bool CaptureDiagnostics = false,
-                                             bool PrecompilePreamble = false,
-                                       bool CacheCodeCompletionResults = false,
-                              bool IncludeBriefCommentsInCodeCompletion = false,
-                                       bool UserFilesAreVolatile = false,
-                                       OwningPtr<ASTUnit> *ErrAST = 0);
+  static ASTUnit *LoadFromCompilerInvocationAction(
+      CompilerInvocation *CI, IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
+      ASTFrontendAction *Action = nullptr, ASTUnit *Unit = nullptr,
+      bool Persistent = true, StringRef ResourceFilesPath = StringRef(),
+      bool OnlyLocalDecls = false, bool CaptureDiagnostics = false,
+      bool PrecompilePreamble = false, bool CacheCodeCompletionResults = false,
+      bool IncludeBriefCommentsInCodeCompletion = false,
+      bool UserFilesAreVolatile = false,
+      std::unique_ptr<ASTUnit> *ErrAST = nullptr);
 
   /// LoadFromCompilerInvocation - Create an ASTUnit from a source file, via a
   /// CompilerInvocation object.
@@ -739,15 +776,13 @@
   //
   // FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we
   // shouldn't need to specify them at construction time.
-  static ASTUnit *LoadFromCompilerInvocation(CompilerInvocation *CI,
-                              IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
-                                             bool OnlyLocalDecls = false,
-                                             bool CaptureDiagnostics = false,
-                                             bool PrecompilePreamble = false,
-                                      TranslationUnitKind TUKind = TU_Complete,
-                                       bool CacheCodeCompletionResults = false,
-                            bool IncludeBriefCommentsInCodeCompletion = false,
-                                             bool UserFilesAreVolatile = false);
+  static std::unique_ptr<ASTUnit> LoadFromCompilerInvocation(
+      CompilerInvocation *CI, IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
+      bool OnlyLocalDecls = false, bool CaptureDiagnostics = false,
+      bool PrecompilePreamble = false, TranslationUnitKind TUKind = TU_Complete,
+      bool CacheCodeCompletionResults = false,
+      bool IncludeBriefCommentsInCodeCompletion = false,
+      bool UserFilesAreVolatile = false);
 
   /// LoadFromCommandLine - Create an ASTUnit from a vector of command line
   /// arguments, which must specify exactly one source file.
@@ -767,32 +802,25 @@
   ///
   // FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we
   // shouldn't need to specify them at construction time.
-  static ASTUnit *LoadFromCommandLine(const char **ArgBegin,
-                                      const char **ArgEnd,
-                              IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
-                                      StringRef ResourceFilesPath,
-                                      bool OnlyLocalDecls = false,
-                                      bool CaptureDiagnostics = false,
-                                      RemappedFile *RemappedFiles = 0,
-                                      unsigned NumRemappedFiles = 0,
-                                      bool RemappedFilesKeepOriginalName = true,
-                                      bool PrecompilePreamble = false,
-                                      TranslationUnitKind TUKind = TU_Complete,
-                                      bool CacheCodeCompletionResults = false,
-                            bool IncludeBriefCommentsInCodeCompletion = false,
-                                      bool AllowPCHWithCompilerErrors = false,
-                                      bool SkipFunctionBodies = false,
-                                      bool UserFilesAreVolatile = false,
-                                      bool ForSerialization = false,
-                                      OwningPtr<ASTUnit> *ErrAST = 0);
-  
+  static ASTUnit *LoadFromCommandLine(
+      const char **ArgBegin, const char **ArgEnd,
+      IntrusiveRefCntPtr<DiagnosticsEngine> Diags, StringRef ResourceFilesPath,
+      bool OnlyLocalDecls = false, bool CaptureDiagnostics = false,
+      ArrayRef<RemappedFile> RemappedFiles = None,
+      bool RemappedFilesKeepOriginalName = true,
+      bool PrecompilePreamble = false, TranslationUnitKind TUKind = TU_Complete,
+      bool CacheCodeCompletionResults = false,
+      bool IncludeBriefCommentsInCodeCompletion = false,
+      bool AllowPCHWithCompilerErrors = false, bool SkipFunctionBodies = false,
+      bool UserFilesAreVolatile = false, bool ForSerialization = false,
+      std::unique_ptr<ASTUnit> *ErrAST = nullptr);
+
   /// \brief Reparse the source files using the same command-line options that
   /// were originally used to produce this translation unit.
   ///
   /// \returns True if a failure occurred that causes the ASTUnit not to
   /// contain any translation-unit information, false otherwise.  
-  bool Reparse(RemappedFile *RemappedFiles = 0,
-               unsigned NumRemappedFiles = 0);
+  bool Reparse(ArrayRef<RemappedFile> RemappedFiles = None);
 
   /// \brief Perform code completion at the given file, line, and
   /// column within this translation unit.
@@ -815,7 +843,7 @@
   /// FIXME: The Diag, LangOpts, SourceMgr, FileMgr, StoredDiagnostics, and
   /// OwnedBuffers parameters are all disgusting hacks. They will go away.
   void CodeComplete(StringRef File, unsigned Line, unsigned Column,
-                    RemappedFile *RemappedFiles, unsigned NumRemappedFiles,
+                    ArrayRef<RemappedFile> RemappedFiles,
                     bool IncludeMacros, bool IncludeCodePatterns,
                     bool IncludeBriefComments,
                     CodeCompleteConsumer &Consumer,
@@ -834,20 +862,21 @@
   ///
   /// \returns True if an error occurred, false otherwise.
   bool serialize(raw_ostream &OS);
-  
-  virtual ModuleLoadResult loadModule(SourceLocation ImportLoc,
-                                      ModuleIdPath Path,
-                                      Module::NameVisibilityKind Visibility,
-                                      bool IsInclusionDirective) {
+
+  ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path,
+                              Module::NameVisibilityKind Visibility,
+                              bool IsInclusionDirective) override {
     // ASTUnit doesn't know how to load modules (not that this matters).
     return ModuleLoadResult();
   }
 
-  virtual void makeModuleVisible(Module *Mod,
-                                 Module::NameVisibilityKind Visibility,
-                                 SourceLocation ImportLoc,
-                                 bool Complain) { }
+  void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility,
+                         SourceLocation ImportLoc, bool Complain) override {}
 
+  GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override
+    { return nullptr; }
+  bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override
+    { return 0; };
 };
 
 } // namespace clang
diff --git a/include/clang/Frontend/ChainedDiagnosticConsumer.h b/include/clang/Frontend/ChainedDiagnosticConsumer.h
index b7dc7c7..11762a9 100644
--- a/include/clang/Frontend/ChainedDiagnosticConsumer.h
+++ b/include/clang/Frontend/ChainedDiagnosticConsumer.h
@@ -11,7 +11,7 @@
 #define LLVM_CLANG_FRONTEND_CHAINEDDIAGNOSTICCONSUMER_H
 
 #include "clang/Basic/Diagnostic.h"
-#include "llvm/ADT/OwningPtr.h"
+#include <memory>
 
 namespace clang {
 class LangOptions;
@@ -22,8 +22,8 @@
 /// diagnostics should be included in counts.
 class ChainedDiagnosticConsumer : public DiagnosticConsumer {
   virtual void anchor();
-  OwningPtr<DiagnosticConsumer> Primary;
-  OwningPtr<DiagnosticConsumer> Secondary;
+  std::unique_ptr<DiagnosticConsumer> Primary;
+  std::unique_ptr<DiagnosticConsumer> Secondary;
 
 public:
   ChainedDiagnosticConsumer(DiagnosticConsumer *_Primary,
@@ -32,28 +32,28 @@
     Secondary.reset(_Secondary);
   }
 
-  virtual void BeginSourceFile(const LangOptions &LO,
-                               const Preprocessor *PP) {
+  void BeginSourceFile(const LangOptions &LO,
+                       const Preprocessor *PP) override {
     Primary->BeginSourceFile(LO, PP);
     Secondary->BeginSourceFile(LO, PP);
   }
 
-  virtual void EndSourceFile() {
+  void EndSourceFile() override {
     Secondary->EndSourceFile();
     Primary->EndSourceFile();
   }
 
-  virtual void finish() {
+  void finish() override {
     Secondary->finish();
     Primary->finish();
   }
 
-  virtual bool IncludeInDiagnosticCounts() const {
+  bool IncludeInDiagnosticCounts() const override {
     return Primary->IncludeInDiagnosticCounts();
   }
 
-  virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
-                                const Diagnostic &Info) {
+  void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+                        const Diagnostic &Info) override {
     // Default implementation (Warnings/errors count).
     DiagnosticConsumer::HandleDiagnostic(DiagLevel, Info);
 
diff --git a/include/clang/Frontend/ChainedIncludesSource.h b/include/clang/Frontend/ChainedIncludesSource.h
deleted file mode 100644
index aa30460..0000000
--- a/include/clang/Frontend/ChainedIncludesSource.h
+++ /dev/null
@@ -1,75 +0,0 @@
-//===- ChainedIncludesSource.h - Chained PCHs in Memory ---------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-//  This file defines the ChainedIncludesSource class, which converts headers
-//  to chained PCHs in memory, mainly used for testing.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SERIALIZATION_CHAINEDINCLUDESSOURCE_H
-#define LLVM_CLANG_SERIALIZATION_CHAINEDINCLUDESSOURCE_H
-
-#include "clang/Sema/ExternalSemaSource.h"
-#include <vector>
-
-namespace clang {
-  class CompilerInstance;
-
-class ChainedIncludesSource : public ExternalSemaSource {
-public:
-  virtual ~ChainedIncludesSource();
-
-  static ChainedIncludesSource *create(CompilerInstance &CI);
-
-  ExternalSemaSource &getFinalReader() const { return *FinalReader; }
-
-private:
-  std::vector<CompilerInstance *> CIs;
-  OwningPtr<ExternalSemaSource> FinalReader;
-
-  
-protected:
-
-//===----------------------------------------------------------------------===//
-// ExternalASTSource interface.
-//===----------------------------------------------------------------------===//
-
-  virtual Decl *GetExternalDecl(uint32_t ID);
-  virtual Selector GetExternalSelector(uint32_t ID);
-  virtual uint32_t GetNumExternalSelectors();
-  virtual Stmt *GetExternalDeclStmt(uint64_t Offset);
-  virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset);
-  virtual bool FindExternalVisibleDeclsByName(const DeclContext *DC,
-                                              DeclarationName Name);
-  virtual ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
-                                        bool (*isKindWeWant)(Decl::Kind),
-                                        SmallVectorImpl<Decl*> &Result);
-  virtual void CompleteType(TagDecl *Tag);
-  virtual void CompleteType(ObjCInterfaceDecl *Class);
-  virtual void StartedDeserializing();
-  virtual void FinishedDeserializing();
-  virtual void StartTranslationUnit(ASTConsumer *Consumer);
-  virtual void PrintStats();
-
-  /// Return the amount of memory used by memory buffers, breaking down
-  /// by heap-backed versus mmap'ed memory.
-  virtual void getMemoryBufferSizes(MemoryBufferSizes &sizes) const;
-
-//===----------------------------------------------------------------------===//
-// ExternalSemaSource interface.
-//===----------------------------------------------------------------------===//
-
-  virtual void InitializeSema(Sema &S);
-  virtual void ForgetSema();
-  virtual void ReadMethodPool(Selector Sel);
-  virtual bool LookupUnqualified(LookupResult &R, Scope *S);
-};
-
-}
-
-#endif
diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def
index 78b825d..1d92efe 100644
--- a/include/clang/Frontend/CodeGenOptions.def
+++ b/include/clang/Frontend/CodeGenOptions.def
@@ -28,6 +28,8 @@
 CODEGENOPT(Name, Bits, Default)
 #endif
 
+CODEGENOPT(DisableIntegratedAS, 1, 0) ///< -no-integrated-as
+CODEGENOPT(CompressDebugSections, 1, 0) ///< -Wa,-compress-debug-sections
 CODEGENOPT(Autolink          , 1, 1) ///< -fno-autolink
 CODEGENOPT(AsmVerbose        , 1, 0) ///< -dA, -fverbose-asm.
 CODEGENOPT(ObjCAutoRefCountExceptions , 1, 0) ///< Whether ARC should be EH-safe.
@@ -59,8 +61,6 @@
 CODEGENOPT(ForbidGuardVariables , 1, 0) ///< Issue errors if C++ guard variables
                                         ///< are required.
 CODEGENOPT(FunctionSections  , 1, 0) ///< Set when -ffunction-sections is enabled.
-CODEGENOPT(HiddenWeakVTables , 1, 0) ///< Emit weak vtables, RTTI, and thunks with
-                                     ///< hidden visibility.
 CODEGENOPT(InstrumentFunctions , 1, 0) ///< Set when -finstrument-functions is
                                        ///< enabled.
 CODEGENOPT(InstrumentForProfiling , 1, 0) ///< Set when -pg is enabled.
@@ -68,7 +68,6 @@
                                      ///< be generated.
 CODEGENOPT(MergeAllConstants , 1, 1) ///< Merge identical constants.
 CODEGENOPT(NoCommon          , 1, 0) ///< Set when -fno-common or C++ is enabled.
-CODEGENOPT(NoDwarf2CFIAsm    , 1, 0) ///< Set when -fno-dwarf2-cfi-asm is enabled.
 CODEGENOPT(NoDwarfDirectoryAsm , 1, 0) ///< Set when -fno-dwarf-directory-asm is
                                        ///< enabled.
 CODEGENOPT(NoExecStack       , 1, 0) ///< Set when -Wa,--noexecstack is enabled.
@@ -87,6 +86,9 @@
 VALUE_CODEGENOPT(OptimizationLevel, 3, 0) ///< The -O[0-4] option specified.
 VALUE_CODEGENOPT(OptimizeSize, 2, 0) ///< If -Os (==1) or -Oz (==2) is specified.
 
+CODEGENOPT(ProfileInstrGenerate , 1, 0) ///< Instrument code to generate
+                                        ///< execution counts to use with PGO.
+
   /// If -fpcc-struct-return or -freg-struct-return is specified.
 ENUM_CODEGENOPT(StructReturnConvention, StructReturnConventionKind, 2, SRCK_Default)
 
@@ -96,7 +98,7 @@
 CODEGENOPT(SaveTempLabels    , 1, 0) ///< Save temporary labels.
 CODEGENOPT(SanitizeAddressZeroBaseShadow , 1, 0) ///< Map shadow memory at zero
                                                  ///< offset in AddressSanitizer.
-CODEGENOPT(SanitizeMemoryTrackOrigins, 1, 0) ///< Enable tracking origins in
+CODEGENOPT(SanitizeMemoryTrackOrigins, 2, 0) ///< Enable tracking origins in
                                              ///< MemorySanitizer
 CODEGENOPT(SanitizeUndefinedTrapOnError, 1, 0) ///< Set on
                                                /// -fsanitize-undefined-trap-on-error
@@ -138,7 +140,7 @@
 VALUE_CODEGENOPT(SSPBufferSize, 32, 0)
 
 /// The kind of generated debug info.
-ENUM_CODEGENOPT(DebugInfo, DebugInfoKind, 2, NoDebugInfo)
+ENUM_CODEGENOPT(DebugInfo, DebugInfoKind, 3, NoDebugInfo)
 
 /// Dwarf version.
 VALUE_CODEGENOPT(DwarfVersion, 3, 0)
diff --git a/include/clang/Frontend/CodeGenOptions.h b/include/clang/Frontend/CodeGenOptions.h
index 86aabf7..3d532ce 100644
--- a/include/clang/Frontend/CodeGenOptions.h
+++ b/include/clang/Frontend/CodeGenOptions.h
@@ -16,6 +16,7 @@
 
 #include <string>
 #include <vector>
+#include "llvm/Support/Regex.h"
 
 namespace clang {
 
@@ -50,12 +51,27 @@
   };
 
   enum DebugInfoKind {
-    NoDebugInfo,          // Don't generate debug info.
-    DebugLineTablesOnly,  // Emit only debug info necessary for generating
-                          // line number tables (-gline-tables-only).
-    LimitedDebugInfo,     // Limit generated debug info to reduce size
-                          // (-flimit-debug-info).
-    FullDebugInfo         // Generate complete debug info.
+    NoDebugInfo,          /// Don't generate debug info.
+
+    LocTrackingOnly,      /// Emit location information but do not generate
+                          /// debug info in the output. This is useful in
+                          /// cases where the backend wants to track source
+                          /// locations for instructions without actually
+                          /// emitting debug info for them (e.g., when -Rpass
+                          /// is used).
+
+    DebugLineTablesOnly,  /// Emit only debug info necessary for generating
+                          /// line number tables (-gline-tables-only).
+
+    LimitedDebugInfo,     /// Limit generated debug info to reduce size
+                          /// (-fno-standalone-debug). This emits
+                          /// forward decls for types that could be
+                          /// replaced with forward decls in the source
+                          /// code. For dynamic C++ classes type info
+                          /// is only emitted int the module that
+                          /// contains the classe's vtable.
+
+    FullDebugInfo         /// Generate complete debug info.
   };
 
   enum TLSModel {
@@ -134,6 +150,31 @@
   /// Name of the profile file to use with -fprofile-sample-use.
   std::string SampleProfileFile;
 
+  /// Name of the profile file to use as input for -fprofile-instr-use
+  std::string InstrProfileInput;
+
+  /// Regular expression to select optimizations for which we should enable
+  /// optimization remarks. Transformation passes whose name matches this
+  /// expression (and support this feature), will emit a diagnostic
+  /// whenever they perform a transformation. This is enabled by the
+  /// -Rpass=regexp flag.
+  std::shared_ptr<llvm::Regex> OptimizationRemarkPattern;
+
+  /// Regular expression to select optimizations for which we should enable
+  /// missed optimization remarks. Transformation passes whose name matches this
+  /// expression (and support this feature), will emit a diagnostic
+  /// whenever they tried but failed to perform a transformation. This is
+  /// enabled by the -Rpass-missed=regexp flag.
+  std::shared_ptr<llvm::Regex> OptimizationRemarkMissedPattern;
+
+  /// Regular expression to select optimizations for which we should enable
+  /// optimization analyses. Transformation passes whose name matches this
+  /// expression (and support this feature), will emit a diagnostic
+  /// whenever they want to explain why they decided to apply or not apply
+  /// a given transformation. This is enabled by the -Rpass-analysis=regexp
+  /// flag.
+  std::shared_ptr<llvm::Regex> OptimizationRemarkAnalysisPattern;
+
 public:
   // Define accessors/mutators for code generation options of enumeration type.
 #define CODEGENOPT(Name, Bits, Default)
diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h
index 5673c59..44e9102 100644
--- a/include/clang/Frontend/CompilerInstance.h
+++ b/include/clang/Frontend/CompilerInstance.h
@@ -13,14 +13,15 @@
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Frontend/CompilerInvocation.h"
+#include "clang/Frontend/Utils.h"
 #include "clang/Lex/ModuleLoader.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/StringRef.h"
 #include <cassert>
 #include <list>
+#include <memory>
 #include <string>
 #include <utility>
 
@@ -74,6 +75,9 @@
   /// The target being compiled for.
   IntrusiveRefCntPtr<TargetInfo> Target;
 
+  /// The virtual file system.
+  IntrusiveRefCntPtr<vfs::FileSystem> VirtualFileSystem;
+
   /// The file manager.
   IntrusiveRefCntPtr<FileManager> FileMgr;
 
@@ -87,19 +91,27 @@
   IntrusiveRefCntPtr<ASTContext> Context;
 
   /// The AST consumer.
-  OwningPtr<ASTConsumer> Consumer;
+  std::unique_ptr<ASTConsumer> Consumer;
 
   /// The code completion consumer.
-  OwningPtr<CodeCompleteConsumer> CompletionConsumer;
+  std::unique_ptr<CodeCompleteConsumer> CompletionConsumer;
 
   /// \brief The semantic analysis object.
-  OwningPtr<Sema> TheSema;
+  std::unique_ptr<Sema> TheSema;
 
   /// \brief The frontend timer
-  OwningPtr<llvm::Timer> FrontendTimer;
+  std::unique_ptr<llvm::Timer> FrontendTimer;
 
-  /// \brief Non-owning reference to the ASTReader, if one exists.
-  ASTReader *ModuleManager;
+  /// \brief The ASTReader, if one exists.
+  IntrusiveRefCntPtr<ASTReader> ModuleManager;
+
+  /// \brief The module dependency collector for crashdumps
+  std::shared_ptr<ModuleDependencyCollector> ModuleDepCollector;
+
+  /// \brief The dependency file generator.
+  std::unique_ptr<DependencyFileGenerator> TheDependencyFileGenerator;
+
+  std::vector<std::shared_ptr<DependencyCollector>> DependencyCollectors;
 
   /// \brief The set of top-level modules that has already been loaded,
   /// along with the module map
@@ -117,13 +129,16 @@
   /// have finished with this translation unit.
   bool BuildGlobalModuleIndex;
 
+  /// \brief We have a full global module index, with all modules.
+  bool HaveFullGlobalModuleIndex;
+
   /// \brief One or more modules failed to build.
   bool ModuleBuildFailed;
 
   /// \brief Holds information about the output file.
   ///
   /// If TempFilename is not empty we must rename it to Filename at the end.
-  /// TempFilename may be empty and Filename non empty if creating the temporary
+  /// TempFilename may be empty and Filename non-empty if creating the temporary
   /// failed.
   struct OutputFile {
     std::string Filename;
@@ -141,7 +156,7 @@
   CompilerInstance(const CompilerInstance &) LLVM_DELETED_FUNCTION;
   void operator=(const CompilerInstance &) LLVM_DELETED_FUNCTION;
 public:
-  CompilerInstance();
+  explicit CompilerInstance(bool BuildingModule = false);
   ~CompilerInstance();
 
   /// @name High-Level Operations
@@ -183,7 +198,7 @@
   /// @name Compiler Invocation and Options
   /// {
 
-  bool hasInvocation() const { return Invocation != 0; }
+  bool hasInvocation() const { return Invocation != nullptr; }
 
   CompilerInvocation &getInvocation() {
     assert(Invocation && "Compiler instance has no invocation!");
@@ -281,7 +296,7 @@
   /// @name Diagnostics Engine
   /// {
 
-  bool hasDiagnostics() const { return Diagnostics != 0; }
+  bool hasDiagnostics() const { return Diagnostics != nullptr; }
 
   /// Get the current diagnostics engine.
   DiagnosticsEngine &getDiagnostics() const {
@@ -302,7 +317,7 @@
   /// @name Target Info
   /// {
 
-  bool hasTarget() const { return Target != 0; }
+  bool hasTarget() const { return Target != nullptr; }
 
   TargetInfo &getTarget() const {
     assert(Target && "Compiler instance has no target!");
@@ -313,10 +328,30 @@
   void setTarget(TargetInfo *Value);
 
   /// }
+  /// @name Virtual File System
+  /// {
+
+  bool hasVirtualFileSystem() const { return VirtualFileSystem != nullptr; }
+
+  vfs::FileSystem &getVirtualFileSystem() const {
+    assert(hasVirtualFileSystem() &&
+           "Compiler instance has no virtual file system");
+    return *VirtualFileSystem;
+  }
+
+  /// \brief Replace the current virtual file system.
+  ///
+  /// \note Most clients should use setFileManager, which will implicitly reset
+  /// the virtual file system to the one contained in the file manager.
+  void setVirtualFileSystem(IntrusiveRefCntPtr<vfs::FileSystem> FS) {
+    VirtualFileSystem = FS;
+  }
+
+  /// }
   /// @name File Manager
   /// {
 
-  bool hasFileManager() const { return FileMgr != 0; }
+  bool hasFileManager() const { return FileMgr != nullptr; }
 
   /// Return the current file manager to the caller.
   FileManager &getFileManager() const {
@@ -325,17 +360,18 @@
   }
   
   void resetAndLeakFileManager() {
+    BuryPointer(FileMgr.get());
     FileMgr.resetWithoutRelease();
   }
 
-  /// setFileManager - Replace the current file manager.
+  /// \brief Replace the current file manager and virtual file system.
   void setFileManager(FileManager *Value);
 
   /// }
   /// @name Source Manager
   /// {
 
-  bool hasSourceManager() const { return SourceMgr != 0; }
+  bool hasSourceManager() const { return SourceMgr != nullptr; }
 
   /// Return the current source manager.
   SourceManager &getSourceManager() const {
@@ -344,6 +380,7 @@
   }
   
   void resetAndLeakSourceManager() {
+    BuryPointer(SourceMgr.get());
     SourceMgr.resetWithoutRelease();
   }
 
@@ -354,7 +391,7 @@
   /// @name Preprocessor
   /// {
 
-  bool hasPreprocessor() const { return PP != 0; }
+  bool hasPreprocessor() const { return PP != nullptr; }
 
   /// Return the current preprocessor.
   Preprocessor &getPreprocessor() const {
@@ -363,6 +400,7 @@
   }
 
   void resetAndLeakPreprocessor() {
+    BuryPointer(PP.get());
     PP.resetWithoutRelease();
   }
 
@@ -373,7 +411,7 @@
   /// @name ASTContext
   /// {
 
-  bool hasASTContext() const { return Context != 0; }
+  bool hasASTContext() const { return Context != nullptr; }
 
   ASTContext &getASTContext() const {
     assert(Context && "Compiler instance has no AST context!");
@@ -381,6 +419,7 @@
   }
   
   void resetAndLeakASTContext() {
+    BuryPointer(Context.get());
     Context.resetWithoutRelease();
   }
 
@@ -395,7 +434,7 @@
   /// @name ASTConsumer
   /// {
 
-  bool hasASTConsumer() const { return Consumer.isValid(); }
+  bool hasASTConsumer() const { return (bool)Consumer; }
 
   ASTConsumer &getASTConsumer() const {
     assert(Consumer && "Compiler instance has no AST consumer!");
@@ -404,7 +443,7 @@
 
   /// takeASTConsumer - Remove the current AST consumer and give ownership to
   /// the caller.
-  ASTConsumer *takeASTConsumer() { return Consumer.take(); }
+  ASTConsumer *takeASTConsumer() { return Consumer.release(); }
 
   /// setASTConsumer - Replace the current AST consumer; the compiler instance
   /// takes ownership of \p Value.
@@ -413,29 +452,32 @@
   /// }
   /// @name Semantic analysis
   /// {
-  bool hasSema() const { return TheSema.isValid(); }
-  
+  bool hasSema() const { return (bool)TheSema; }
+
   Sema &getSema() const { 
     assert(TheSema && "Compiler instance has no Sema object!");
     return *TheSema;
   }
-  
-  Sema *takeSema() { return TheSema.take(); }
-  
+
+  Sema *takeSema() { return TheSema.release(); }
+  void resetAndLeakSema() { BuryPointer(TheSema.release()); }
+
   /// }
   /// @name Module Management
   /// {
 
-  ASTReader *getModuleManager() const { return ModuleManager; }
-  void setModuleManager(ASTReader *Reader) { ModuleManager = Reader; }
+  IntrusiveRefCntPtr<ASTReader> getModuleManager() const;
+  void setModuleManager(IntrusiveRefCntPtr<ASTReader> Reader);
+
+  std::shared_ptr<ModuleDependencyCollector> getModuleDepCollector() const;
+  void setModuleDepCollector(
+      std::shared_ptr<ModuleDependencyCollector> Collector);
 
   /// }
   /// @name Code Completion
   /// {
 
-  bool hasCodeCompletionConsumer() const {
-    return CompletionConsumer.isValid();
-  }
+  bool hasCodeCompletionConsumer() const { return (bool)CompletionConsumer; }
 
   CodeCompleteConsumer &getCodeCompletionConsumer() const {
     assert(CompletionConsumer &&
@@ -446,7 +488,7 @@
   /// takeCodeCompletionConsumer - Remove the current code completion consumer
   /// and give ownership to the caller.
   CodeCompleteConsumer *takeCodeCompletionConsumer() {
-    return CompletionConsumer.take();
+    return CompletionConsumer.release();
   }
 
   /// setCodeCompletionConsumer - Replace the current code completion consumer;
@@ -457,7 +499,7 @@
   /// @name Frontend timer
   /// {
 
-  bool hasFrontendTimer() const { return FrontendTimer.isValid(); }
+  bool hasFrontendTimer() const { return (bool)FrontendTimer; }
 
   llvm::Timer &getFrontendTimer() const {
     assert(FrontendTimer && "Compiler instance has no frontend timer!");
@@ -495,7 +537,7 @@
   ///
   /// \param ShouldOwnClient If Client is non-NULL, specifies whether 
   /// the diagnostic object should take ownership of the client.
-  void createDiagnostics(DiagnosticConsumer *Client = 0,
+  void createDiagnostics(DiagnosticConsumer *Client = nullptr,
                          bool ShouldOwnClient = true);
 
   /// Create a DiagnosticsEngine object with a the TextDiagnosticPrinter.
@@ -518,9 +560,9 @@
   /// \return The new object on success, or null on failure.
   static IntrusiveRefCntPtr<DiagnosticsEngine>
   createDiagnostics(DiagnosticOptions *Opts,
-                    DiagnosticConsumer *Client = 0,
+                    DiagnosticConsumer *Client = nullptr,
                     bool ShouldOwnClient = true,
-                    const CodeGenOptions *CodeGenOpts = 0);
+                    const CodeGenOptions *CodeGenOpts = nullptr);
 
   /// Create the file manager and replace any existing one with it.
   void createFileManager();
@@ -530,28 +572,26 @@
 
   /// Create the preprocessor, using the invocation, file, and source managers,
   /// and replace any existing one with it.
-  void createPreprocessor();
+  void createPreprocessor(TranslationUnitKind TUKind);
 
   /// Create the AST context.
   void createASTContext();
 
   /// Create an external AST source to read a PCH file and attach it to the AST
   /// context.
-  void createPCHExternalASTSource(StringRef Path,
-                                  bool DisablePCHValidation,
+  void createPCHExternalASTSource(StringRef Path, bool DisablePCHValidation,
                                   bool AllowPCHWithCompilerErrors,
-                                  void *DeserializationListener);
+                                  void *DeserializationListener,
+                                  bool OwnDeserializationListener);
 
   /// Create an external AST source to read a PCH file.
   ///
   /// \return - The new object on success, or null on failure.
-  static ExternalASTSource *
-  createPCHExternalASTSource(StringRef Path, const std::string &Sysroot,
-                             bool DisablePCHValidation,
-                             bool AllowPCHWithCompilerErrors,
-                             Preprocessor &PP, ASTContext &Context,
-                             void *DeserializationListener, bool Preamble,
-                             bool UseGlobalModuleIndex);
+  static ExternalASTSource *createPCHExternalASTSource(
+      StringRef Path, const std::string &Sysroot, bool DisablePCHValidation,
+      bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context,
+      void *DeserializationListener, bool OwnDeserializationListener,
+      bool Preamble, bool UseGlobalModuleIndex);
 
   /// Create a code completion consumer using the invocation; note that this
   /// will cause the source manager to truncate the input source file at the
@@ -632,6 +672,8 @@
                    std::string *ResultPathName,
                    std::string *TempPathName);
 
+  llvm::raw_null_ostream *createNullOutputFile();
+
   /// }
   /// @name Initialization Utility Methods
   /// {
@@ -653,21 +695,28 @@
                 const FrontendOptions &Opts);
 
   /// }
-  
-  virtual ModuleLoadResult loadModule(SourceLocation ImportLoc,
-                                      ModuleIdPath Path,
-                                      Module::NameVisibilityKind Visibility,
-                                      bool IsInclusionDirective);
 
-  virtual void makeModuleVisible(Module *Mod,
-                                 Module::NameVisibilityKind Visibility,
-                                 SourceLocation ImportLoc,
-                                 bool Complain);
+  // Create module manager.
+  void createModuleManager();
+
+  ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path,
+                              Module::NameVisibilityKind Visibility,
+                              bool IsInclusionDirective) override;
+
+  void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility,
+                         SourceLocation ImportLoc, bool Complain) override;
 
   bool hadModuleLoaderFatalFailure() const {
     return ModuleLoader::HadFatalFailure;
   }
 
+  GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override;
+
+  bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override;
+
+  void addDependencyCollector(std::shared_ptr<DependencyCollector> Listener) {
+    DependencyCollectors.push_back(std::move(Listener));
+  }
 };
 
 } // end namespace clang
diff --git a/include/clang/Frontend/CompilerInvocation.h b/include/clang/Frontend/CompilerInvocation.h
index f64773c..f05ab80 100644
--- a/include/clang/Frontend/CompilerInvocation.h
+++ b/include/clang/Frontend/CompilerInvocation.h
@@ -47,15 +47,17 @@
 /// When errors are encountered, return false and, if Diags is non-null,
 /// report the error(s).
 bool ParseDiagnosticArgs(DiagnosticOptions &Opts, llvm::opt::ArgList &Args,
-                         DiagnosticsEngine *Diags = 0);
+                         DiagnosticsEngine *Diags = nullptr);
 
 class CompilerInvocationBase : public RefCountedBase<CompilerInvocation> {
-protected:
+  void operator=(const CompilerInvocationBase &) LLVM_DELETED_FUNCTION;
+
+public:
   /// Options controlling the language variant.
-  IntrusiveRefCntPtr<LangOptions> LangOpts;
+  std::shared_ptr<LangOptions> LangOpts;
 
   /// Options controlling the target.
-  IntrusiveRefCntPtr<TargetOptions> TargetOpts;
+  std::shared_ptr<TargetOptions> TargetOpts;
 
   /// Options controlling the diagnostic engine.
   IntrusiveRefCntPtr<DiagnosticOptions> DiagnosticOpts;
@@ -66,17 +68,17 @@
   /// Options controlling the preprocessor (aside from \#include handling).
   IntrusiveRefCntPtr<PreprocessorOptions> PreprocessorOpts;
 
-public:
   CompilerInvocationBase();
+  ~CompilerInvocationBase();
 
   CompilerInvocationBase(const CompilerInvocationBase &X);
   
-  LangOptions *getLangOpts() { return LangOpts.getPtr(); }
-  const LangOptions *getLangOpts() const { return LangOpts.getPtr(); }
+  LangOptions *getLangOpts() { return LangOpts.get(); }
+  const LangOptions *getLangOpts() const { return LangOpts.get(); }
 
-  TargetOptions &getTargetOpts() { return *TargetOpts.getPtr(); }
+  TargetOptions &getTargetOpts() { return *TargetOpts.get(); }
   const TargetOptions &getTargetOpts() const {
-    return *TargetOpts.getPtr();
+    return *TargetOpts.get();
   }
 
   DiagnosticOptions &getDiagnosticOpts() const { return *DiagnosticOpts; }
@@ -204,6 +206,14 @@
   /// @}
 };
 
+namespace vfs {
+  class FileSystem;
+}
+
+IntrusiveRefCntPtr<vfs::FileSystem>
+createVFSFromCompilerInvocation(const CompilerInvocation &CI,
+                                DiagnosticsEngine &Diags);
+
 } // end namespace clang
 
 #endif
diff --git a/include/clang/Frontend/DependencyOutputOptions.h b/include/clang/Frontend/DependencyOutputOptions.h
index fefb6f3..5da1459 100644
--- a/include/clang/Frontend/DependencyOutputOptions.h
+++ b/include/clang/Frontend/DependencyOutputOptions.h
@@ -26,6 +26,7 @@
                                      /// problems.
   unsigned AddMissingHeaderDeps : 1; ///< Add missing headers to dependency list
   unsigned PrintShowIncludes : 1; ///< Print cl.exe style /showIncludes info.
+  unsigned IncludeModuleFiles : 1; ///< Include module file dependencies.
   
   /// The file to write dependency output to.
   std::string OutputFile;
@@ -42,7 +43,10 @@
 
   /// \brief The file to write GraphViz-formatted header dependencies to.
   std::string DOTOutputFile;
-  
+
+  /// \brief The directory to copy module dependencies to when collecting them.
+  std::string ModuleDependencyOutputDir;
+
 public:
   DependencyOutputOptions() {
     IncludeSystemHeaders = 0;
@@ -50,6 +54,7 @@
     UsePhonyTargets = 0;
     AddMissingHeaderDeps = 0;
     PrintShowIncludes = 0;
+    IncludeModuleFiles = 0;
   }
 };
 
diff --git a/include/clang/Frontend/DiagnosticRenderer.h b/include/clang/Frontend/DiagnosticRenderer.h
index f3cd054..ce1dc90 100644
--- a/include/clang/Frontend/DiagnosticRenderer.h
+++ b/include/clang/Frontend/DiagnosticRenderer.h
@@ -83,9 +83,7 @@
                                  DiagnosticsEngine::Level Level,
                                  ArrayRef<CharSourceRange> Ranges,
                                  const SourceManager &SM) = 0;
-  
-  virtual void emitBasicNote(StringRef Message) = 0;
-  
+
   virtual void emitCodeContext(SourceLocation Loc,
                                DiagnosticsEngine::Level Level,
                                SmallVectorImpl<CharSourceRange>& Ranges,
@@ -108,6 +106,7 @@
 
   
 private:
+  void emitBasicNote(StringRef Message);
   void emitIncludeStack(SourceLocation Loc, PresumedLoc PLoc,
                         DiagnosticsEngine::Level Level, const SourceManager &SM);
   void emitIncludeStackRecursively(SourceLocation Loc, const SourceManager &SM);
@@ -144,7 +143,7 @@
                       StringRef Message, ArrayRef<CharSourceRange> Ranges,
                       ArrayRef<FixItHint> FixItHints,
                       const SourceManager *SM,
-                      DiagOrStoredDiag D = (Diagnostic *)0);
+                      DiagOrStoredDiag D = (Diagnostic *)nullptr);
 
   void emitStoredDiagnostic(StoredDiagnostic &Diag);
 };
@@ -158,20 +157,17 @@
     : DiagnosticRenderer(LangOpts, DiagOpts) {}
   
   virtual ~DiagnosticNoteRenderer();
-  
-  virtual void emitBasicNote(StringRef Message);
-    
-  virtual void emitIncludeLocation(SourceLocation Loc,
-                                   PresumedLoc PLoc,
-                                   const SourceManager &SM);
 
-  virtual void emitImportLocation(SourceLocation Loc, PresumedLoc PLoc,
+  void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc,
+                           const SourceManager &SM) override;
+
+  void emitImportLocation(SourceLocation Loc, PresumedLoc PLoc,
+                          StringRef ModuleName,
+                          const SourceManager &SM) override;
+
+  void emitBuildingModuleLocation(SourceLocation Loc, PresumedLoc PLoc,
                                   StringRef ModuleName,
-                                  const SourceManager &SM);
-
-  virtual void emitBuildingModuleLocation(SourceLocation Loc, PresumedLoc PLoc,
-                                          StringRef ModuleName,
-                                          const SourceManager &SM);
+                                  const SourceManager &SM) override;
 
   virtual void emitNote(SourceLocation Loc, StringRef Message,
                         const SourceManager *SM) = 0;
diff --git a/include/clang/Frontend/FrontendAction.h b/include/clang/Frontend/FrontendAction.h
index a568ba0..9ac9d28 100644
--- a/include/clang/Frontend/FrontendAction.h
+++ b/include/clang/Frontend/FrontendAction.h
@@ -21,8 +21,8 @@
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/LangOptions.h"
 #include "clang/Frontend/FrontendOptions.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/StringRef.h"
+#include <memory>
 #include <string>
 #include <vector>
 
@@ -35,7 +35,7 @@
 /// Abstract base class for actions which can be performed by the frontend.
 class FrontendAction {
   FrontendInputFile CurrentInput;
-  OwningPtr<ASTUnit> CurrentASTUnit;
+  std::unique_ptr<ASTUnit> CurrentASTUnit;
   CompilerInstance *Instance;
   friend class ASTMergeAction;
   friend class WrapperFrontendAction;
@@ -124,7 +124,7 @@
 
   bool isCurrentFileAST() const {
     assert(!CurrentInput.isEmpty() && "No current file!");
-    return CurrentASTUnit.isValid();
+    return (bool)CurrentASTUnit;
   }
 
   const FrontendInputFile &getCurrentInput() const {
@@ -146,11 +146,10 @@
     return *CurrentASTUnit;
   }
 
-  ASTUnit *takeCurrentASTUnit() {
-    return CurrentASTUnit.take();
-  }
+  ASTUnit *takeCurrentASTUnit() { return CurrentASTUnit.release(); }
 
-  void setCurrentInput(const FrontendInputFile &CurrentInput, ASTUnit *AST = 0);
+  void setCurrentInput(const FrontendInputFile &CurrentInput,
+                       ASTUnit *AST = nullptr);
 
   /// @}
   /// @name Supported Modes
@@ -220,17 +219,17 @@
   ///
   /// This will also take care of instantiating a code completion consumer if
   /// the user requested it and the action supports it.
-  virtual void ExecuteAction();
+  void ExecuteAction() override;
 
 public:
-  virtual bool usesPreprocessorOnly() const { return false; }
+  bool usesPreprocessorOnly() const override { return false; }
 };
 
 class PluginASTAction : public ASTFrontendAction {
   virtual void anchor();
 protected:
-  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
-                                         StringRef InFile) = 0;
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override = 0;
 
 public:
   /// \brief Parse the given plugin command line arguments.
@@ -248,11 +247,11 @@
 protected:
   /// \brief Provide a default implementation which returns aborts;
   /// this method should never be called by FrontendAction clients.
-  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
-                                         StringRef InFile);
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
 
 public:
-  virtual bool usesPreprocessorOnly() const { return true; }
+  bool usesPreprocessorOnly() const override { return true; }
 };
 
 /// \brief A frontend action which simply wraps some other runtime-specified
@@ -262,28 +261,27 @@
 /// some existing action's behavior. It implements every virtual method in
 /// the FrontendAction interface by forwarding to the wrapped action.
 class WrapperFrontendAction : public FrontendAction {
-  OwningPtr<FrontendAction> WrappedAction;
+  std::unique_ptr<FrontendAction> WrappedAction;
 
 protected:
-  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
-                                         StringRef InFile);
-  virtual bool BeginInvocation(CompilerInstance &CI);
-  virtual bool BeginSourceFileAction(CompilerInstance &CI,
-                                     StringRef Filename);
-  virtual void ExecuteAction();
-  virtual void EndSourceFileAction();
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
+  bool BeginInvocation(CompilerInstance &CI) override;
+  bool BeginSourceFileAction(CompilerInstance &CI, StringRef Filename) override;
+  void ExecuteAction() override;
+  void EndSourceFileAction() override;
 
 public:
   /// Construct a WrapperFrontendAction from an existing action, taking
   /// ownership of it.
   WrapperFrontendAction(FrontendAction *WrappedAction);
 
-  virtual bool usesPreprocessorOnly() const;
-  virtual TranslationUnitKind getTranslationUnitKind();
-  virtual bool hasPCHSupport() const;
-  virtual bool hasASTFileSupport() const;
-  virtual bool hasIRSupport() const;
-  virtual bool hasCodeCompletionSupport() const;
+  bool usesPreprocessorOnly() const override;
+  TranslationUnitKind getTranslationUnitKind() override;
+  bool hasPCHSupport() const override;
+  bool hasASTFileSupport() const override;
+  bool hasIRSupport() const override;
+  bool hasCodeCompletionSupport() const override;
 };
 
 }  // end namespace clang
diff --git a/include/clang/Frontend/FrontendActions.h b/include/clang/Frontend/FrontendActions.h
index f3d1276..84cc82c 100644
--- a/include/clang/Frontend/FrontendActions.h
+++ b/include/clang/Frontend/FrontendActions.h
@@ -17,21 +17,22 @@
 namespace clang {
 
 class Module;
+class FileEntry;
   
 //===----------------------------------------------------------------------===//
 // Custom Consumer Actions
 //===----------------------------------------------------------------------===//
 
 class InitOnlyAction : public FrontendAction {
-  virtual void ExecuteAction();
+  void ExecuteAction() override;
 
-  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
-                                         StringRef InFile);
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
 
 public:
   // Don't claim to only use the preprocessor, we want to follow the AST path,
   // but do nothing.
-  virtual bool usesPreprocessorOnly() const { return false; }
+  bool usesPreprocessorOnly() const override { return false; }
 };
 
 //===----------------------------------------------------------------------===//
@@ -40,44 +41,44 @@
 
 class ASTPrintAction : public ASTFrontendAction {
 protected:
-  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
-                                         StringRef InFile);
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
 };
 
 class ASTDumpAction : public ASTFrontendAction {
 protected:
-  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
-                                         StringRef InFile);
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
 };
 
 class ASTDeclListAction : public ASTFrontendAction {
 protected:
-  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
-                                         StringRef InFile);
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
 };
 
 class ASTViewAction : public ASTFrontendAction {
 protected:
-  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
-                                         StringRef InFile);
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
 };
 
 class DeclContextPrintAction : public ASTFrontendAction {
 protected:
-  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
-                                         StringRef InFile);
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
 };
 
 class GeneratePCHAction : public ASTFrontendAction {
 protected:
-  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
-                                         StringRef InFile);
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
 
-  virtual TranslationUnitKind getTranslationUnitKind() {
+  TranslationUnitKind getTranslationUnitKind() override {
     return TU_Prefix;
   }
 
-  virtual bool hasASTFileSupport() const { return false; }
+  bool hasASTFileSupport() const override { return false; }
 
 public:
   /// \brief Compute the AST consumer arguments that will be used to
@@ -93,57 +94,71 @@
 
 class GenerateModuleAction : public ASTFrontendAction {
   clang::Module *Module;
+  const FileEntry *ModuleMapForUniquing;
   bool IsSystem;
   
 protected:
-  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
-                                         StringRef InFile);
-  
-  virtual TranslationUnitKind getTranslationUnitKind() { 
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
+
+  TranslationUnitKind getTranslationUnitKind() override {
     return TU_Module;
   }
-  
-  virtual bool hasASTFileSupport() const { return false; }
-  
-public:
-  explicit GenerateModuleAction(bool IsSystem = false)
-    : ASTFrontendAction(), IsSystem(IsSystem) { }
 
-  virtual bool BeginSourceFileAction(CompilerInstance &CI, StringRef Filename);
-  
+  bool hasASTFileSupport() const override { return false; }
+
+public:
+  GenerateModuleAction(const FileEntry *ModuleMap = nullptr,
+                       bool IsSystem = false)
+    : ASTFrontendAction(), ModuleMapForUniquing(ModuleMap), IsSystem(IsSystem)
+  { }
+
+  bool BeginSourceFileAction(CompilerInstance &CI, StringRef Filename) override;
+
   /// \brief Compute the AST consumer arguments that will be used to
   /// create the PCHGenerator instance returned by CreateASTConsumer.
   ///
   /// \returns true if an error occurred, false otherwise.
-  static bool ComputeASTConsumerArguments(CompilerInstance &CI,
-                                          StringRef InFile,
-                                          std::string &Sysroot,
-                                          std::string &OutputFile,
-                                          raw_ostream *&OS);
+  bool ComputeASTConsumerArguments(CompilerInstance &CI,
+                                   StringRef InFile,
+                                   std::string &Sysroot,
+                                   std::string &OutputFile,
+                                   raw_ostream *&OS);
 };
 
 class SyntaxOnlyAction : public ASTFrontendAction {
 protected:
-  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
-                                         StringRef InFile);
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                         StringRef InFile) override;
 
 public:
-  virtual bool hasCodeCompletionSupport() const { return true; }
+  bool hasCodeCompletionSupport() const override { return true; }
 };
 
 /// \brief Dump information about the given module file, to be used for
 /// basic debugging and discovery.
 class DumpModuleInfoAction : public ASTFrontendAction {
 protected:
-  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
-                                         StringRef InFile);
-  virtual void ExecuteAction();
-  
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
+  void ExecuteAction() override;
+
 public:
-  virtual bool hasPCHSupport() const { return false; }
-  virtual bool hasASTFileSupport() const { return true; }
-  virtual bool hasIRSupport() const { return false; }
-  virtual bool hasCodeCompletionSupport() const { return false; }
+  bool hasPCHSupport() const override { return false; }
+  bool hasASTFileSupport() const override { return true; }
+  bool hasIRSupport() const override { return false; }
+  bool hasCodeCompletionSupport() const override { return false; }
+};
+
+class VerifyPCHAction : public ASTFrontendAction {
+protected:
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
+
+  void ExecuteAction() override;
+
+public:
+  bool hasCodeCompletionSupport() const override { return false; }
 };
 
 /**
@@ -162,34 +177,34 @@
   std::vector<std::string> ASTFiles;
 
 protected:
-  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
-                                         StringRef InFile);
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
 
-  virtual bool BeginSourceFileAction(CompilerInstance &CI,
-                                     StringRef Filename);
+  bool BeginSourceFileAction(CompilerInstance &CI,
+                             StringRef Filename) override;
 
-  virtual void ExecuteAction();
-  virtual void EndSourceFileAction();
+  void ExecuteAction() override;
+  void EndSourceFileAction() override;
 
 public:
   ASTMergeAction(FrontendAction *AdaptedAction, ArrayRef<std::string> ASTFiles);
   virtual ~ASTMergeAction();
 
-  virtual bool usesPreprocessorOnly() const;
-  virtual TranslationUnitKind getTranslationUnitKind();
-  virtual bool hasPCHSupport() const;
-  virtual bool hasASTFileSupport() const;
-  virtual bool hasCodeCompletionSupport() const;
+  bool usesPreprocessorOnly() const override;
+  TranslationUnitKind getTranslationUnitKind() override;
+  bool hasPCHSupport() const override;
+  bool hasASTFileSupport() const override;
+  bool hasCodeCompletionSupport() const override;
 };
 
 class PrintPreambleAction : public FrontendAction {
 protected:
-  void ExecuteAction();
-  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &, StringRef) { 
-    return 0; 
+  void ExecuteAction() override;
+  ASTConsumer *CreateASTConsumer(CompilerInstance &, StringRef) override {
+    return nullptr;
   }
-  
-  virtual bool usesPreprocessorOnly() const { return true; }
+
+  bool usesPreprocessorOnly() const override { return true; }
 };
   
 //===----------------------------------------------------------------------===//
@@ -198,29 +213,29 @@
 
 class DumpRawTokensAction : public PreprocessorFrontendAction {
 protected:
-  void ExecuteAction();
+  void ExecuteAction() override;
 };
 
 class DumpTokensAction : public PreprocessorFrontendAction {
 protected:
-  void ExecuteAction();
+  void ExecuteAction() override;
 };
 
 class GeneratePTHAction : public PreprocessorFrontendAction {
 protected:
-  void ExecuteAction();
+  void ExecuteAction() override;
 };
 
 class PreprocessOnlyAction : public PreprocessorFrontendAction {
 protected:
-  void ExecuteAction();
+  void ExecuteAction() override;
 };
 
 class PrintPreprocessedAction : public PreprocessorFrontendAction {
 protected:
-  void ExecuteAction();
+  void ExecuteAction() override;
 
-  virtual bool hasPCHSupport() const { return true; }
+  bool hasPCHSupport() const override { return true; }
 };
   
 }  // end namespace clang
diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h
index 4b321e8..e87da8d 100644
--- a/include/clang/Frontend/FrontendOptions.h
+++ b/include/clang/Frontend/FrontendOptions.h
@@ -43,6 +43,7 @@
     GeneratePTH,            ///< Generate pre-tokenized header.
     InitOnly,               ///< Only execute frontend initialization.
     ModuleFileInfo,         ///< Dump information about a module file.
+    VerifyPCH,              ///< Load and verify that a PCH file is usable.
     ParseSyntaxOnly,        ///< Parse and perform semantic analysis.
     PluginAction,           ///< Run a plugin action, \see ActionName.
     PrintDeclContext,       ///< Print DeclContext and their Decls.
@@ -89,9 +90,9 @@
   bool IsSystem;
 
 public:
-  FrontendInputFile() : Buffer(0), Kind(IK_None) { }
+  FrontendInputFile() : Buffer(nullptr), Kind(IK_None) { }
   FrontendInputFile(StringRef File, InputKind Kind, bool IsSystem = false)
-    : File(File.str()), Buffer(0), Kind(Kind), IsSystem(IsSystem) { }
+    : File(File.str()), Buffer(nullptr), Kind(Kind), IsSystem(IsSystem) { }
   FrontendInputFile(llvm::MemoryBuffer *buffer, InputKind Kind,
                     bool IsSystem = false)
     : Buffer(buffer), Kind(Kind), IsSystem(IsSystem) { }
@@ -99,9 +100,9 @@
   InputKind getKind() const { return Kind; }
   bool isSystem() const { return IsSystem; }
 
-  bool isEmpty() const { return File.empty() && Buffer == 0; }
+  bool isEmpty() const { return File.empty() && Buffer == nullptr; }
   bool isFile() const { return !isBuffer(); }
-  bool isBuffer() const { return Buffer != 0; }
+  bool isBuffer() const { return Buffer != nullptr; }
 
   StringRef getFile() const {
     assert(isFile());
@@ -179,10 +180,13 @@
     ObjCMT_ReturnsInnerPointerProperty = 0x200,
     /// \brief use NS_NONATOMIC_IOSONLY for property 'atomic' attribute
     ObjCMT_NsAtomicIOSOnlyProperty = 0x400,
+    /// \brief Enable inferring NS_DESIGNATED_INITIALIZER for ObjC methods.
+    ObjCMT_DesignatedInitializer = 0x800,
     ObjCMT_MigrateDecls = (ObjCMT_ReadonlyProperty | ObjCMT_ReadwriteProperty |
                            ObjCMT_Annotation | ObjCMT_Instancetype |
                            ObjCMT_NsMacros | ObjCMT_ProtocolConformance |
-                           ObjCMT_NsAtomicIOSOnlyProperty),
+                           ObjCMT_NsAtomicIOSOnlyProperty |
+                           ObjCMT_DesignatedInitializer),
     ObjCMT_MigrateAll = (ObjCMT_Literals | ObjCMT_Subscripting | ObjCMT_MigrateDecls)
   };
   unsigned ObjCMTAction;
diff --git a/include/clang/Frontend/FrontendPluginRegistry.h b/include/clang/Frontend/FrontendPluginRegistry.h
index ec925ad..49be495 100644
--- a/include/clang/Frontend/FrontendPluginRegistry.h
+++ b/include/clang/Frontend/FrontendPluginRegistry.h
@@ -13,6 +13,9 @@
 #include "clang/Frontend/FrontendAction.h"
 #include "llvm/Support/Registry.h"
 
+// Instantiated in FrontendAction.cpp.
+extern template class llvm::Registry<clang::PluginASTAction>;
+
 namespace clang {
 
 /// The frontend plugin registry.
diff --git a/include/clang/Frontend/LangStandard.h b/include/clang/Frontend/LangStandard.h
index 1124d53..9680e1f 100644
--- a/include/clang/Frontend/LangStandard.h
+++ b/include/clang/Frontend/LangStandard.h
@@ -25,10 +25,11 @@
   CPlusPlus = (1 << 4),
   CPlusPlus11 = (1 << 5),
   CPlusPlus1y = (1 << 6),
-  Digraphs = (1 << 7),
-  GNUMode = (1 << 8),
-  HexFloat = (1 << 9),
-  ImplicitInt = (1 << 10)
+  CPlusPlus1z = (1 << 7),
+  Digraphs = (1 << 8),
+  GNUMode = (1 << 9),
+  HexFloat = (1 << 10),
+  ImplicitInt = (1 << 11)
 };
 
 }
@@ -69,12 +70,15 @@
   /// isCPlusPlus - Language is a C++ variant.
   bool isCPlusPlus() const { return Flags & frontend::CPlusPlus; }
 
-  /// isCPlusPlus11 - Language is a C++0x variant.
+  /// isCPlusPlus11 - Language is a C++11 variant (or later).
   bool isCPlusPlus11() const { return Flags & frontend::CPlusPlus11; }
 
-  /// isCPlusPlus1y - Language is a C++1y variant.
+  /// isCPlusPlus1y - Language is a C++14 variant (or later).
   bool isCPlusPlus1y() const { return Flags & frontend::CPlusPlus1y; }
 
+  /// isCPlusPlus1z - Language is a C++17 variant (or later).
+  bool isCPlusPlus1z() const { return Flags & frontend::CPlusPlus1z; }
+
   /// hasDigraphs - Language supports digraphs.
   bool hasDigraphs() const { return Flags & frontend::Digraphs; }
 
diff --git a/include/clang/Frontend/LangStandards.def b/include/clang/Frontend/LangStandards.def
index 7b2516b..90a27b5 100644
--- a/include/clang/Frontend/LangStandards.def
+++ b/include/clang/Frontend/LangStandards.def
@@ -108,12 +108,28 @@
              LineComment | CPlusPlus | CPlusPlus11 | Digraphs | GNUMode)
 
 LANGSTANDARD(cxx1y, "c++1y",
-             "Working draft for ISO C++ 2014",
+             "ISO C++ 2014 with amendments",
+             LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus1y | Digraphs)
+LANGSTANDARD(cxx14, "c++14",
+             "ISO C++ 2014 with amendments",
              LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus1y | Digraphs)
 LANGSTANDARD(gnucxx1y, "gnu++1y",
-             "Working draft for ISO C++ 2014 with GNU extensions",
+             "ISO C++ 2014 with amendments and GNU extensions",
              LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus1y | Digraphs |
              GNUMode)
+LANGSTANDARD(gnucxx14, "gnu++14",
+             "ISO C++ 2014 with amendments and GNU extensions",
+             LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus1y | Digraphs |
+             GNUMode)
+
+LANGSTANDARD(cxx1z, "c++1z",
+             "Working draft for ISO C++ 2017",
+             LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus1y | CPlusPlus1z |
+             Digraphs)
+LANGSTANDARD(gnucxx1z, "gnu++1z",
+             "Working draft for ISO C++ 2017 with GNU extensions",
+             LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus1y | CPlusPlus1z |
+             Digraphs | GNUMode)
 
 // OpenCL
 LANGSTANDARD(opencl, "cl",
diff --git a/include/clang/Frontend/LayoutOverrideSource.h b/include/clang/Frontend/LayoutOverrideSource.h
index ec34e14..16d032b 100644
--- a/include/clang/Frontend/LayoutOverrideSource.h
+++ b/include/clang/Frontend/LayoutOverrideSource.h
@@ -47,12 +47,13 @@
     
     /// \brief If this particular record type has an overridden layout,
     /// return that layout.
-    virtual bool 
+    bool
     layoutRecordType(const RecordDecl *Record,
        uint64_t &Size, uint64_t &Alignment,
        llvm::DenseMap<const FieldDecl *, uint64_t> &FieldOffsets,
        llvm::DenseMap<const CXXRecordDecl *, CharUnits> &BaseOffsets,
-       llvm::DenseMap<const CXXRecordDecl *, CharUnits> &VirtualBaseOffsets);
+       llvm::DenseMap<const CXXRecordDecl *,
+                      CharUnits> &VirtualBaseOffsets) override;
     
     /// \brief Dump the overridden layouts.
     void dump();
diff --git a/include/clang/Frontend/LogDiagnosticPrinter.h b/include/clang/Frontend/LogDiagnosticPrinter.h
index e8a6bb3..0130319 100644
--- a/include/clang/Frontend/LogDiagnosticPrinter.h
+++ b/include/clang/Frontend/LogDiagnosticPrinter.h
@@ -39,7 +39,10 @@
     /// The level of the diagnostic.
     DiagnosticsEngine::Level DiagnosticLevel;
   };
-  
+
+  void EmitDiagEntry(llvm::raw_ostream &OS,
+                     const LogDiagnosticPrinter::DiagEntry &DE);
+
   raw_ostream &OS;
   const LangOptions *LangOpts;
   IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
@@ -62,14 +65,14 @@
     DwarfDebugFlags = Value;
   }
 
-  void BeginSourceFile(const LangOptions &LO, const Preprocessor *PP) {
+  void BeginSourceFile(const LangOptions &LO, const Preprocessor *PP) override {
     LangOpts = &LO;
   }
 
-  void EndSourceFile();
+  void EndSourceFile() override;
 
-  virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
-                                const Diagnostic &Info);
+  void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+                        const Diagnostic &Info) override;
 };
 
 } // end namespace clang
diff --git a/include/clang/Frontend/MultiplexConsumer.h b/include/clang/Frontend/MultiplexConsumer.h
index 6ea7547..4d31104 100644
--- a/include/clang/Frontend/MultiplexConsumer.h
+++ b/include/clang/Frontend/MultiplexConsumer.h
@@ -17,7 +17,7 @@
 
 #include "clang/Basic/LLVM.h"
 #include "clang/Sema/SemaConsumer.h"
-#include "llvm/ADT/OwningPtr.h"
+#include <memory>
 #include <vector>
 
 namespace clang {
@@ -33,28 +33,35 @@
   ~MultiplexConsumer();
 
   // ASTConsumer
-  virtual void Initialize(ASTContext &Context);
-  virtual void HandleCXXStaticMemberVarInstantiation(VarDecl *VD);
-  virtual bool HandleTopLevelDecl(DeclGroupRef D);
-  virtual void HandleInterestingDecl(DeclGroupRef D);
-  virtual void HandleTranslationUnit(ASTContext &Ctx);
-  virtual void HandleTagDeclDefinition(TagDecl *D);
-  virtual void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D);
-  virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef D);
-  virtual void CompleteTentativeDefinition(VarDecl *D);
-  virtual void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired);
-  virtual ASTMutationListener *GetASTMutationListener();
-  virtual ASTDeserializationListener *GetASTDeserializationListener();
-  virtual void PrintStats();
+  void Initialize(ASTContext &Context) override;
+  void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override;
+  bool HandleTopLevelDecl(DeclGroupRef D) override;
+  void HandleInlineMethodDefinition(CXXMethodDecl *D) override;
+  void HandleInterestingDecl(DeclGroupRef D) override;
+  void HandleTranslationUnit(ASTContext &Ctx) override;
+  void HandleTagDeclDefinition(TagDecl *D) override;
+  void HandleTagDeclRequiredDefinition(const TagDecl *D) override;
+  void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) override;
+  void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override;
+  void HandleImplicitImportDecl(ImportDecl *D) override;
+  void HandleLinkerOptionPragma(llvm::StringRef Opts) override;
+  void HandleDetectMismatch(llvm::StringRef Name,
+                            llvm::StringRef Value) override;
+  void HandleDependentLibrary(llvm::StringRef Lib) override;
+  void CompleteTentativeDefinition(VarDecl *D) override;
+  void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) override;
+  ASTMutationListener *GetASTMutationListener() override;
+  ASTDeserializationListener *GetASTDeserializationListener() override;
+  void PrintStats() override;
 
   // SemaConsumer
-  virtual void InitializeSema(Sema &S);
-  virtual void ForgetSema();
+  void InitializeSema(Sema &S) override;
+  void ForgetSema() override;
 
 private:
   std::vector<ASTConsumer*> Consumers;  // Owns these.
-  OwningPtr<MultiplexASTMutationListener> MutationListener;
-  OwningPtr<MultiplexASTDeserializationListener> DeserializationListener;
+  std::unique_ptr<MultiplexASTMutationListener> MutationListener;
+  std::unique_ptr<MultiplexASTDeserializationListener> DeserializationListener;
 };
 
 }  // end namespace clang
diff --git a/include/clang/Frontend/SerializedDiagnosticPrinter.h b/include/clang/Frontend/SerializedDiagnosticPrinter.h
index 117771d..4dda1fa 100644
--- a/include/clang/Frontend/SerializedDiagnosticPrinter.h
+++ b/include/clang/Frontend/SerializedDiagnosticPrinter.h
@@ -46,6 +46,19 @@
   RECORD_LAST = RECORD_FIXIT
 };
 
+/// A stable version of DiagnosticIDs::Level.
+///
+/// Do not change the order of values in this enum, and please increment the
+/// serialized diagnostics version number when you add to it.
+enum Level {
+  Ignored = 0,
+  Note,
+  Warning,
+  Error,
+  Fatal,
+  Remark
+};
+
 /// \brief Returns a DiagnosticConsumer that serializes diagnostics to
 ///  a bitcode file.
 ///
diff --git a/include/clang/Frontend/TextDiagnostic.h b/include/clang/Frontend/TextDiagnostic.h
index c8d01b0..acebb90 100644
--- a/include/clang/Frontend/TextDiagnostic.h
+++ b/include/clang/Frontend/TextDiagnostic.h
@@ -63,52 +63,48 @@
   /// formatting of their diagnostic messages.
   ///
   /// \param OS Where the message is printed
-  /// \param Level Used to colorizing the message
+  /// \param IsSupplemental true if this is a continuation note diagnostic
   /// \param Message The text actually printed
   /// \param CurrentColumn The starting column of the first line, accounting
   ///                      for any prefix.
   /// \param Columns The number of columns to use in line-wrapping, 0 disables
   ///                all line-wrapping.
   /// \param ShowColors Enable colorizing of the message.
-  static void printDiagnosticMessage(raw_ostream &OS,
-                                     DiagnosticsEngine::Level Level,
-                                     StringRef Message,
-                                     unsigned CurrentColumn, unsigned Columns,
-                                     bool ShowColors);
+  static void printDiagnosticMessage(raw_ostream &OS, bool IsSupplemental,
+                                     StringRef Message, unsigned CurrentColumn,
+                                     unsigned Columns, bool ShowColors);
 
 protected:
-  virtual void emitDiagnosticMessage(SourceLocation Loc,PresumedLoc PLoc,
-                                     DiagnosticsEngine::Level Level,
-                                     StringRef Message,
-                                     ArrayRef<CharSourceRange> Ranges,
-                                     const SourceManager *SM,
-                                     DiagOrStoredDiag D);
+  void emitDiagnosticMessage(SourceLocation Loc,PresumedLoc PLoc,
+                             DiagnosticsEngine::Level Level,
+                             StringRef Message,
+                             ArrayRef<CharSourceRange> Ranges,
+                             const SourceManager *SM,
+                             DiagOrStoredDiag D) override;
 
-  virtual void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
-                                 DiagnosticsEngine::Level Level,
-                                 ArrayRef<CharSourceRange> Ranges,
-                                 const SourceManager &SM);
-  
-  virtual void emitCodeContext(SourceLocation Loc,
-                               DiagnosticsEngine::Level Level,
-                               SmallVectorImpl<CharSourceRange>& Ranges,
-                               ArrayRef<FixItHint> Hints,
-                               const SourceManager &SM) {
+  void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
+                         DiagnosticsEngine::Level Level,
+                         ArrayRef<CharSourceRange> Ranges,
+                         const SourceManager &SM) override;
+
+  void emitCodeContext(SourceLocation Loc,
+                       DiagnosticsEngine::Level Level,
+                       SmallVectorImpl<CharSourceRange>& Ranges,
+                       ArrayRef<FixItHint> Hints,
+                       const SourceManager &SM) override {
     emitSnippetAndCaret(Loc, Level, Ranges, Hints, SM);
   }
-  
-  virtual void emitBasicNote(StringRef Message);
-  
-  virtual void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc,
-                                   const SourceManager &SM);
 
-  virtual void emitImportLocation(SourceLocation Loc, PresumedLoc PLoc,
+  void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc,
+                           const SourceManager &SM) override;
+
+  void emitImportLocation(SourceLocation Loc, PresumedLoc PLoc,
+                          StringRef ModuleName,
+                          const SourceManager &SM) override;
+
+  void emitBuildingModuleLocation(SourceLocation Loc, PresumedLoc PLoc,
                                   StringRef ModuleName,
-                                  const SourceManager &SM);
-
-  virtual void emitBuildingModuleLocation(SourceLocation Loc, PresumedLoc PLoc,
-                                          StringRef ModuleName,
-                                          const SourceManager &SM);
+                                  const SourceManager &SM) override;
 
 private:
   void emitSnippetAndCaret(SourceLocation Loc, DiagnosticsEngine::Level Level,
diff --git a/include/clang/Frontend/TextDiagnosticBuffer.h b/include/clang/Frontend/TextDiagnosticBuffer.h
index 93ac299..fe5aa3e 100644
--- a/include/clang/Frontend/TextDiagnosticBuffer.h
+++ b/include/clang/Frontend/TextDiagnosticBuffer.h
@@ -28,7 +28,7 @@
   typedef DiagList::iterator iterator;
   typedef DiagList::const_iterator const_iterator;
 private:
-  DiagList Errors, Warnings, Notes;
+  DiagList Errors, Warnings, Remarks, Notes;
 public:
   const_iterator err_begin() const  { return Errors.begin(); }
   const_iterator err_end() const    { return Errors.end(); }
@@ -36,11 +36,14 @@
   const_iterator warn_begin() const { return Warnings.begin(); }
   const_iterator warn_end() const   { return Warnings.end(); }
 
+  const_iterator remark_begin() const { return Remarks.begin(); }
+  const_iterator remark_end() const   { return Remarks.end(); }
+
   const_iterator note_begin() const { return Notes.begin(); }
   const_iterator note_end() const   { return Notes.end(); }
 
-  virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
-                                const Diagnostic &Info);
+  void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+                        const Diagnostic &Info) override;
 
   /// FlushDiagnostics - Flush the buffered diagnostics to an given
   /// diagnostic engine.
diff --git a/include/clang/Frontend/TextDiagnosticPrinter.h b/include/clang/Frontend/TextDiagnosticPrinter.h
index dc80470..9f6d5ff 100644
--- a/include/clang/Frontend/TextDiagnosticPrinter.h
+++ b/include/clang/Frontend/TextDiagnosticPrinter.h
@@ -18,7 +18,7 @@
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/LLVM.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/OwningPtr.h"
+#include <memory>
 
 namespace clang {
 class DiagnosticOptions;
@@ -30,7 +30,7 @@
   IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
 
   /// \brief Handle to the currently active text diagnostic emitter.
-  OwningPtr<TextDiagnostic> TextDiag;
+  std::unique_ptr<TextDiagnostic> TextDiag;
 
   /// A string to prefix to error messages.
   std::string Prefix;
@@ -47,9 +47,10 @@
   /// used.
   void setPrefix(std::string Value) { Prefix = Value; }
 
-  void BeginSourceFile(const LangOptions &LO, const Preprocessor *PP);
-  void EndSourceFile();
-  void HandleDiagnostic(DiagnosticsEngine::Level Level, const Diagnostic &Info);
+  void BeginSourceFile(const LangOptions &LO, const Preprocessor *PP) override;
+  void EndSourceFile() override;
+  void HandleDiagnostic(DiagnosticsEngine::Level Level,
+                        const Diagnostic &Info) override;
 };
 
 } // end namespace clang
diff --git a/include/clang/Frontend/Utils.h b/include/clang/Frontend/Utils.h
index dff56c3..4c0a7b7 100644
--- a/include/clang/Frontend/Utils.h
+++ b/include/clang/Frontend/Utils.h
@@ -15,8 +15,10 @@
 #define LLVM_CLANG_FRONTEND_UTILS_H
 
 #include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/VirtualFileSystem.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSet.h"
 #include "llvm/Option/OptSpecifier.h"
 
 namespace llvm {
@@ -30,12 +32,14 @@
 
 namespace clang {
 class ASTConsumer;
+class ASTReader;
 class CompilerInstance;
 class CompilerInvocation;
 class Decl;
 class DependencyOutputOptions;
 class DiagnosticsEngine;
 class DiagnosticOptions;
+class ExternalSemaSource;
 class FileManager;
 class HeaderSearch;
 class HeaderSearchOptions;
@@ -59,23 +63,81 @@
 /// environment ready to process a single file.
 void InitializePreprocessor(Preprocessor &PP,
                             const PreprocessorOptions &PPOpts,
-                            const HeaderSearchOptions &HSOpts,
                             const FrontendOptions &FEOpts);
 
-/// ProcessWarningOptions - Initialize the diagnostic client and process the
-/// warning options specified on the command line.
-void ProcessWarningOptions(DiagnosticsEngine &Diags,
-                           const DiagnosticOptions &Opts,
-                           bool ReportDiags = true);
-
 /// DoPrintPreprocessedInput - Implement -E mode.
 void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream* OS,
                               const PreprocessorOutputOptions &Opts);
 
-/// AttachDependencyFileGen - Create a dependency file generator, and attach
-/// it to the given preprocessor.  This takes ownership of the output stream.
-void AttachDependencyFileGen(Preprocessor &PP,
-                             const DependencyOutputOptions &Opts);
+/// An interface for collecting the dependencies of a compilation. Users should
+/// use \c attachToPreprocessor and \c attachToASTReader to get all of the
+/// dependencies.
+// FIXME: Migrate DependencyFileGen, DependencyGraphGen, ModuleDepCollectory to
+// use this interface.
+class DependencyCollector {
+public:
+  void attachToPreprocessor(Preprocessor &PP);
+  void attachToASTReader(ASTReader &R);
+  llvm::ArrayRef<std::string> getDependencies() const { return Dependencies; }
+
+  /// Called when a new file is seen. Return true if \p Filename should be added
+  /// to the list of dependencies.
+  ///
+  /// The default implementation ignores <built-in> and system files.
+  virtual bool sawDependency(StringRef Filename, bool FromModule,
+                             bool IsSystem, bool IsModuleFile, bool IsMissing);
+  /// Called when the end of the main file is reached.
+  virtual void finishedMainFile() { }
+  /// Return true if system files should be passed to sawDependency().
+  virtual bool needSystemDependencies() { return false; }
+  virtual ~DependencyCollector();
+
+public: // implementation detail
+  /// Add a dependency \p Filename if it has not been seen before and
+  /// sawDependency() returns true.
+  void maybeAddDependency(StringRef Filename, bool FromModule, bool IsSystem,
+                          bool IsModuleFile, bool IsMissing);
+private:
+  llvm::StringSet<> Seen;
+  std::vector<std::string> Dependencies;
+};
+
+/// Builds a depdenency file when attached to a Preprocessor (for includes) and
+/// ASTReader (for module imports), and writes it out at the end of processing
+/// a source file.  Users should attach to the ast reader whenever a module is
+/// loaded.
+class DependencyFileGenerator {
+  void *Impl; // Opaque implementation
+  DependencyFileGenerator(void *Impl);
+public:
+  static DependencyFileGenerator *CreateAndAttachToPreprocessor(
+    Preprocessor &PP, const DependencyOutputOptions &Opts);
+  void AttachToASTReader(ASTReader &R);
+};
+
+/// Collects the dependencies for imported modules into a directory.  Users
+/// should attach to the AST reader whenever a module is loaded.
+class ModuleDependencyCollector {
+  std::string DestDir;
+  bool HasErrors;
+  llvm::StringSet<> Seen;
+  vfs::YAMLVFSWriter VFSWriter;
+
+public:
+  StringRef getDest() { return DestDir; }
+  bool insertSeen(StringRef Filename) { return Seen.insert(Filename); }
+  void setHasErrors() { HasErrors = true; }
+  void addFileMapping(StringRef VPath, StringRef RPath) {
+    VFSWriter.addFileMapping(VPath, RPath);
+  }
+
+  void attachToASTReader(ASTReader &R);
+  void writeFileMap();
+  bool hasErrors() { return HasErrors; }
+  ModuleDependencyCollector(std::string DestDir)
+      : DestDir(DestDir), HasErrors(false) {}
+  ~ModuleDependencyCollector() { writeFileMap(); }
+};
 
 /// AttachDependencyGraphGen - Create a dependency graph generator, and attach
 /// it to the given preprocessor.
@@ -101,6 +163,12 @@
 /// a seekable stream.
 void CacheTokens(Preprocessor &PP, llvm::raw_fd_ostream* OS);
 
+/// The ChainedIncludesSource class converts headers to chained PCHs in
+/// memory, mainly for testing.
+IntrusiveRefCntPtr<ExternalSemaSource>
+createChainedIncludesSource(CompilerInstance &CI,
+                            IntrusiveRefCntPtr<ExternalSemaSource> &Reader);
+
 /// createInvocationFromCommandLine - Construct a compiler invocation object for
 /// a command line argument vector.
 ///
@@ -115,7 +183,7 @@
 /// is non-null, emits an error if the argument is given, but non-integral.
 int getLastArgIntValue(const llvm::opt::ArgList &Args,
                        llvm::opt::OptSpecifier Id, int Default,
-                       DiagnosticsEngine *Diags = 0);
+                       DiagnosticsEngine *Diags = nullptr);
 
 inline int getLastArgIntValue(const llvm::opt::ArgList &Args,
                               llvm::opt::OptSpecifier Id, int Default,
@@ -123,6 +191,22 @@
   return getLastArgIntValue(Args, Id, Default, &Diags);
 }
 
+uint64_t getLastArgUInt64Value(const llvm::opt::ArgList &Args,
+                               llvm::opt::OptSpecifier Id, uint64_t Default,
+                               DiagnosticsEngine *Diags = nullptr);
+
+inline uint64_t getLastArgUInt64Value(const llvm::opt::ArgList &Args,
+                                      llvm::opt::OptSpecifier Id,
+                                      uint64_t Default,
+                                      DiagnosticsEngine &Diags) {
+  return getLastArgUInt64Value(Args, Id, Default, &Diags);
+}
+
+// When Clang->getFrontendOpts().DisableFree is set we don't delete some of the
+// global objects, but we don't want LeakDetectors to complain, so we bury them
+// in a globally visible array.
+void BuryPointer(const void *Ptr);
+
 } // end namespace clang
 
 #endif
diff --git a/include/clang/Frontend/VerifyDiagnosticConsumer.h b/include/clang/Frontend/VerifyDiagnosticConsumer.h
index 95d7752..9273fac 100644
--- a/include/clang/Frontend/VerifyDiagnosticConsumer.h
+++ b/include/clang/Frontend/VerifyDiagnosticConsumer.h
@@ -13,10 +13,10 @@
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Lex/Preprocessor.h"
 #include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/PointerIntPair.h"
 #include "llvm/ADT/STLExtras.h"
 #include <climits>
+#include <memory>
 
 namespace clang {
 
@@ -34,12 +34,12 @@
 /// comment on the line that has the diagnostic, use:
 ///
 /// \code
-///   expected-{error,warning,note}
+///   expected-{error,warning,remark,note}
 /// \endcode
 ///
-/// to tag if it's an expected error or warning, and place the expected text
-/// between {{ and }} markers. The full text doesn't have to be included, only
-/// enough to ensure that the correct diagnostic was emitted.
+/// to tag if it's an expected error, remark or warning, and place the expected
+/// text between {{ and }} markers. The full text doesn't have to be included,
+/// only enough to ensure that the correct diagnostic was emitted.
 ///
 /// Here's an example:
 ///
@@ -71,7 +71,10 @@
 /// \endcode
 ///
 /// The path can be absolute or relative and the same search paths will be used
-/// as for #include directives.
+/// as for #include directives.  The line number in an external file may be
+/// substituted with '*' meaning that any line number will match (useful where
+/// the included file is, for example, a system header where the actual line
+/// number may change and is not critical).
 ///
 /// The simple syntax above allows each specification to match exactly one
 /// error.  You can use the extended syntax to customize this. The extended
@@ -108,10 +111,11 @@
 ///
 /// In this example, the diagnostic may appear only once, if at all.
 ///
-/// Regex matching mode may be selected by appending '-re' to type, such as:
+/// Regex matching mode may be selected by appending '-re' to type and
+/// including regexes wrapped in double curly braces in the directive, such as:
 ///
 /// \code
-///   expected-error-re
+///   expected-error-re {{format specifies type 'wchar_t **' (aka '{{.+}}')}}
 /// \endcode
 ///
 /// Examples matching error: "variable has incomplete type 'struct s'"
@@ -120,10 +124,10 @@
 ///   // expected-error {{variable has incomplete type 'struct s'}}
 ///   // expected-error {{variable has incomplete type}}
 ///
-///   // expected-error-re {{variable has has type 'struct .'}}
-///   // expected-error-re {{variable has has type 'struct .*'}}
-///   // expected-error-re {{variable has has type 'struct (.*)'}}
-///   // expected-error-re {{variable has has type 'struct[[:space:]](.*)'}}
+///   // expected-error-re {{variable has type 'struct {{.}}'}}
+///   // expected-error-re {{variable has type 'struct {{.*}}'}}
+///   // expected-error-re {{variable has type 'struct {{(.*)}}'}}
+///   // expected-error-re {{variable has type 'struct{{[[:space:]](.*)}}'}}
 /// \endcode
 ///
 /// VerifyDiagnosticConsumer expects at least one expected-* directive to
@@ -142,7 +146,7 @@
   class Directive {
   public:
     static Directive *create(bool RegexKind, SourceLocation DirectiveLoc,
-                             SourceLocation DiagnosticLoc,
+                             SourceLocation DiagnosticLoc, bool MatchAnyLine,
                              StringRef Text, unsigned Min, unsigned Max);
   public:
     /// Constant representing n or more matches.
@@ -152,6 +156,7 @@
     SourceLocation DiagnosticLoc;
     const std::string Text;
     unsigned Min, Max;
+    bool MatchAnyLine;
 
     virtual ~Directive() { }
 
@@ -164,9 +169,9 @@
 
   protected:
     Directive(SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc,
-              StringRef Text, unsigned Min, unsigned Max)
+              bool MatchAnyLine, StringRef Text, unsigned Min, unsigned Max)
       : DirectiveLoc(DirectiveLoc), DiagnosticLoc(DiagnosticLoc),
-        Text(Text), Min(Min), Max(Max) {
+        Text(Text), Min(Min), Max(Max), MatchAnyLine(MatchAnyLine) {
     assert(!DirectiveLoc.isInvalid() && "DirectiveLoc is invalid!");
     assert(!DiagnosticLoc.isInvalid() && "DiagnosticLoc is invalid!");
     }
@@ -183,13 +188,17 @@
   struct ExpectedData {
     DirectiveList Errors;
     DirectiveList Warnings;
+    DirectiveList Remarks;
     DirectiveList Notes;
 
-    ~ExpectedData() {
+    void Reset() {
       llvm::DeleteContainerPointers(Errors);
       llvm::DeleteContainerPointers(Warnings);
+      llvm::DeleteContainerPointers(Remarks);
       llvm::DeleteContainerPointers(Notes);
     }
+
+    ~ExpectedData() { Reset(); }
   };
 
   enum DirectiveStatus {
@@ -203,7 +212,7 @@
   DiagnosticsEngine &Diags;
   DiagnosticConsumer *PrimaryClient;
   bool OwnsPrimaryClient;
-  OwningPtr<TextDiagnosticBuffer> Buffer;
+  std::unique_ptr<TextDiagnosticBuffer> Buffer;
   const Preprocessor *CurrentPreprocessor;
   const LangOptions *LangOpts;
   SourceManager *SrcManager;
@@ -217,24 +226,19 @@
     SrcManager = &SM;
   }
 
-#ifndef NDEBUG
+  // These facilities are used for validation in debug builds.
   class UnparsedFileStatus {
     llvm::PointerIntPair<const FileEntry *, 1, bool> Data;
-
   public:
     UnparsedFileStatus(const FileEntry *File, bool FoundDirectives)
       : Data(File, FoundDirectives) {}
-
     const FileEntry *getFile() const { return Data.getPointer(); }
     bool foundDirectives() const { return Data.getInt(); }
   };
-
   typedef llvm::DenseMap<FileID, const FileEntry *> ParsedFilesMap;
   typedef llvm::DenseMap<FileID, UnparsedFileStatus> UnparsedFilesMap;
-
   ParsedFilesMap ParsedFiles;
   UnparsedFilesMap UnparsedFiles;
-#endif
 
 public:
   /// Create a new verifying diagnostic client, which will issue errors to
@@ -243,10 +247,10 @@
   VerifyDiagnosticConsumer(DiagnosticsEngine &Diags);
   ~VerifyDiagnosticConsumer();
 
-  virtual void BeginSourceFile(const LangOptions &LangOpts,
-                               const Preprocessor *PP);
+  void BeginSourceFile(const LangOptions &LangOpts,
+                       const Preprocessor *PP) override;
 
-  virtual void EndSourceFile();
+  void EndSourceFile() override;
 
   enum ParsedStatus {
     /// File has been processed via HandleComment.
@@ -262,10 +266,10 @@
   /// \brief Update lists of parsed and unparsed files.
   void UpdateParsedFileStatus(SourceManager &SM, FileID FID, ParsedStatus PS);
 
-  virtual bool HandleComment(Preprocessor &PP, SourceRange Comment);
+  bool HandleComment(Preprocessor &PP, SourceRange Comment) override;
 
-  virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
-                                const Diagnostic &Info);
+  void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+                        const Diagnostic &Info) override;
 };
 
 } // end namspace clang
diff --git a/include/clang/Index/CommentToXML.h b/include/clang/Index/CommentToXML.h
index 8444b14..bb7b71a 100644
--- a/include/clang/Index/CommentToXML.h
+++ b/include/clang/Index/CommentToXML.h
@@ -11,6 +11,7 @@
 #define LLVM_CLANG_INDEX_COMMENTTOXML_H
 
 #include "clang/Basic/LLVM.h"
+#include <memory>
 
 namespace clang {
 class ASTContext;
@@ -24,11 +25,12 @@
 class SimpleFormatContext;
 
 class CommentToXMLConverter {
-  SimpleFormatContext *FormatContext;
+  std::unique_ptr<SimpleFormatContext> FormatContext;
   unsigned FormatInMemoryUniqueId;
 
 public:
-  CommentToXMLConverter() : FormatContext(0), FormatInMemoryUniqueId(0) {}
+  CommentToXMLConverter();
+  ~CommentToXMLConverter();
 
   void convertCommentToHTML(const comments::FullComment *FC,
                             SmallVectorImpl<char> &HTML,
diff --git a/include/clang/Index/USRGeneration.h b/include/clang/Index/USRGeneration.h
index 7b0fd50..3195dee 100644
--- a/include/clang/Index/USRGeneration.h
+++ b/include/clang/Index/USRGeneration.h
@@ -14,7 +14,9 @@
 #include "llvm/ADT/StringRef.h"
 
 namespace clang {
-  class Decl;
+class Decl;
+class MacroDefinition;
+class SourceManager;
 
 namespace index {
 
@@ -22,7 +24,7 @@
   return "c:";
 }
 
-/// \brief Generate a USR for a Decl, including the prefix.
+/// \brief Generate a USR for a Decl, including the USR prefix.
 /// \returns true if the results should be ignored, false otherwise.
 bool generateUSRForDecl(const Decl *D, SmallVectorImpl<char> &Buf);
 
@@ -47,6 +49,12 @@
 /// \brief Generate a USR fragment for an Objective-C protocol.
 void generateUSRForObjCProtocol(StringRef Prot, raw_ostream &OS);
 
+/// \brief Generate a USR for a macro, including the USR prefix.
+///
+/// \returns true on error, false on success.
+bool generateUSRForMacro(const MacroDefinition *MD, const SourceManager &SM,
+                         SmallVectorImpl<char> &Buf);
+
 } // namespace index
 } // namespace clang
 
diff --git a/include/clang/Lex/CMakeLists.txt b/include/clang/Lex/CMakeLists.txt
deleted file mode 100644
index 38055eb..0000000
--- a/include/clang/Lex/CMakeLists.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-clang_tablegen(AttrSpellings.inc -gen-clang-attr-spelling-list
-  -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
-  SOURCE ../Basic/Attr.td
-  TARGET ClangAttrSpellings
-  DEPENDS AttrSpellings.inc)
diff --git a/include/clang/Lex/DirectoryLookup.h b/include/clang/Lex/DirectoryLookup.h
index dff3e8c..9edf119 100644
--- a/include/clang/Lex/DirectoryLookup.h
+++ b/include/clang/Lex/DirectoryLookup.h
@@ -92,17 +92,21 @@
 
   /// getDir - Return the directory that this entry refers to.
   ///
-  const DirectoryEntry *getDir() const { return isNormalDir() ? u.Dir : 0; }
+  const DirectoryEntry *getDir() const {
+    return isNormalDir() ? u.Dir : nullptr;
+  }
 
   /// getFrameworkDir - Return the directory that this framework refers to.
   ///
   const DirectoryEntry *getFrameworkDir() const {
-    return isFramework() ? u.Dir : 0;
+    return isFramework() ? u.Dir : nullptr;
   }
 
   /// getHeaderMap - Return the directory that this entry refers to.
   ///
-  const HeaderMap *getHeaderMap() const { return isHeaderMap() ? u.Map : 0; }
+  const HeaderMap *getHeaderMap() const {
+    return isHeaderMap() ? u.Map : nullptr;
+  }
 
   /// isNormalDir - Return true if this is a normal directory, not a header map.
   bool isNormalDir() const { return getLookupType() == LT_NormalDir; }
@@ -161,11 +165,17 @@
   /// \param [out] InUserSpecifiedSystemFramework If the file is found,
   /// set to true if the file is located in a framework that has been
   /// user-specified to be treated as a system framework.
-  const FileEntry *LookupFile(StringRef Filename, HeaderSearch &HS,
+  ///
+  /// \param [out] MappedName if this is a headermap which maps the filename to
+  /// a framework include ("Foo.h" -> "Foo/Foo.h"), set the new name to this
+  /// vector and point Filename to it.
+  const FileEntry *LookupFile(StringRef &Filename, HeaderSearch &HS,
                               SmallVectorImpl<char> *SearchPath,
                               SmallVectorImpl<char> *RelativePath,
                               ModuleMap::KnownHeader *SuggestedModule,
-                              bool &InUserSpecifiedSystemFramework) const;
+                              bool &InUserSpecifiedSystemFramework,
+                              bool &HasBeenMapped,
+                              SmallVectorImpl<char> &MappedName) const;
 
 private:
   const FileEntry *DoFrameworkLookup(
diff --git a/include/clang/Lex/HeaderMap.h b/include/clang/Lex/HeaderMap.h
index 8473a6a..8e78b5a 100644
--- a/include/clang/Lex/HeaderMap.h
+++ b/include/clang/Lex/HeaderMap.h
@@ -55,6 +55,11 @@
   /// "../../file.h".
   const FileEntry *LookupFile(StringRef Filename, FileManager &FM) const;
 
+  /// If the specified relative filename is located in this HeaderMap return
+  /// the filename it is mapped to, otherwise return an empty StringRef.
+  StringRef lookupFilename(StringRef Filename,
+                           SmallVectorImpl<char> &DestPath) const;
+
   /// getFileName - Return the filename of the headermap.
   const char *getFileName() const;
 
diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h
index fb1a862..0342629 100644
--- a/include/clang/Lex/HeaderSearch.h
+++ b/include/clang/Lex/HeaderSearch.h
@@ -18,10 +18,10 @@
 #include "clang/Lex/ModuleMap.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringSet.h"
 #include "llvm/Support/Allocator.h"
+#include <memory>
 #include <vector>
 
 namespace clang {
@@ -73,6 +73,9 @@
   /// provided via a header map. This bit indicates when this is one of
   /// those framework headers.
   unsigned IndexHeaderMapHeader : 1;
+
+  /// \brief Whether this file had been looked up as a header.
+  unsigned IsValid : 1;
   
   /// \brief The number of times the file has been included already.
   unsigned short NumIncludes;
@@ -102,8 +105,8 @@
     : isImport(false), isPragmaOnce(false), DirInfo(SrcMgr::C_User), 
       External(false), isModuleHeader(false), isCompilingModuleHeader(false),
       HeaderRole(ModuleMap::NormalHeader),
-      Resolved(false), IndexHeaderMapHeader(false),
-      NumIncludes(0), ControllingMacroID(0), ControllingMacro(0)  {}
+      Resolved(false), IndexHeaderMapHeader(false), IsValid(0),
+      NumIncludes(0), ControllingMacroID(0), ControllingMacro(nullptr)  {}
 
   /// \brief Retrieve the controlling macro for this header file, if
   /// any.
@@ -158,6 +161,7 @@
   /// \brief Header-search options used to initialize this header search.
   IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts;
 
+  DiagnosticsEngine &Diags;
   FileManager &FileMgr;
   /// \#include search path information.  Requests for \#include "x" search the
   /// directory of the \#including file first, then each directory in SearchDirs
@@ -185,15 +189,27 @@
   /// included, indexed by the FileEntry's UID.
   std::vector<HeaderFileInfo> FileInfo;
 
-  /// \brief Keeps track of each lookup performed by LookupFile.
-  ///
-  /// The first part of the value is the starting index in SearchDirs
-  /// that the cached search was performed from.  If there is a hit and
-  /// this value doesn't match the current query, the cache has to be
-  /// ignored.  The second value is the entry in SearchDirs that satisfied
-  /// the query.
-  llvm::StringMap<std::pair<unsigned, unsigned>, llvm::BumpPtrAllocator>
-    LookupFileCache;
+  /// Keeps track of each lookup performed by LookupFile.
+  struct LookupFileCacheInfo {
+    /// Starting index in SearchDirs that the cached search was performed from.
+    /// If there is a hit and this value doesn't match the current query, the
+    /// cache has to be ignored.
+    unsigned StartIdx;
+    /// The entry in SearchDirs that satisfied the query.
+    unsigned HitIdx;
+    /// This is non-null if the original filename was mapped to a framework
+    /// include via a headermap.
+    const char *MappedName;
+
+    /// Default constructor -- Initialize all members with zero.
+    LookupFileCacheInfo(): StartIdx(0), HitIdx(0), MappedName(nullptr) {}
+
+    void reset(unsigned StartIdx) {
+      this->StartIdx = StartIdx;
+      this->MappedName = nullptr;
+    }
+  };
+  llvm::StringMap<LookupFileCacheInfo, llvm::BumpPtrAllocator> LookupFileCache;
 
   /// \brief Collection mapping a framework or subframework
   /// name like "Carbon" to the Carbon.framework directory.
@@ -204,7 +220,7 @@
   /// include_alias pragma for Microsoft compatibility.
   typedef llvm::StringMap<std::string, llvm::BumpPtrAllocator>
     IncludeAliasMap;
-  OwningPtr<IncludeAliasMap> IncludeAliases;
+  std::unique_ptr<IncludeAliasMap> IncludeAliases;
 
   /// HeaderMaps - This is a mapping from FileEntry -> HeaderMap, uniquing
   /// headermaps.  This vector owns the headermap.
@@ -232,6 +248,8 @@
   unsigned NumMultiIncludeFileOptzn;
   unsigned NumFrameworkLookups, NumSubFrameworkLookups;
 
+  bool EnabledModules;
+
   // HeaderSearch doesn't support default or copy construction.
   HeaderSearch(const HeaderSearch&) LLVM_DELETED_FUNCTION;
   void operator=(const HeaderSearch&) LLVM_DELETED_FUNCTION;
@@ -278,9 +296,7 @@
   }
 
   /// \brief Checks whether the map exists or not.
-  bool HasIncludeAliasMap() const {
-    return IncludeAliases.isValid();
-  }
+  bool HasIncludeAliasMap() const { return (bool)IncludeAliases; }
 
   /// \brief Map the source include name to the dest include name.
   ///
@@ -347,13 +363,15 @@
   /// \returns If successful, this returns 'UsedDir', the DirectoryLookup member
   /// the file was found in, or null if not applicable.
   ///
+  /// \param IncludeLoc Used for diagnostics if valid.
+  ///
   /// \param isAngled indicates whether the file reference is a <> reference.
   ///
   /// \param CurDir If non-null, the file was found in the specified directory
   /// search location.  This is used to implement \#include_next.
   ///
-  /// \param CurFileEnt If non-null, indicates where the \#including file is, in
-  /// case a relative search is needed.
+  /// \param Includers Indicates where the \#including file(s) are, in case
+  /// relative searches are needed. In reverse order of inclusion.
   ///
   /// \param SearchPath If non-null, will be set to the search path relative
   /// to which the file was found. If the include path is absolute, SearchPath
@@ -366,10 +384,10 @@
   /// \param SuggestedModule If non-null, and the file found is semantically
   /// part of a known module, this will be set to the module that should
   /// be imported instead of preprocessing/parsing the file found.
-  const FileEntry *LookupFile(StringRef Filename, bool isAngled,
-                              const DirectoryLookup *FromDir,
+  const FileEntry *LookupFile(StringRef Filename, SourceLocation IncludeLoc,
+                              bool isAngled, const DirectoryLookup *FromDir,
                               const DirectoryLookup *&CurDir,
-                              const FileEntry *CurFileEnt,
+                              ArrayRef<const FileEntry *> Includers,
                               SmallVectorImpl<char> *SearchPath,
                               SmallVectorImpl<char> *RelativePath,
                               ModuleMap::KnownHeader *SuggestedModule,
@@ -458,6 +476,9 @@
   /// FileEntry, uniquing them through the 'HeaderMaps' datastructure.
   const HeaderMap *CreateHeaderMap(const FileEntry *FE);
 
+  /// Returns true if modules are enabled.
+  bool enabledModules() const { return EnabledModules; }
+
   /// \brief Retrieve the name of the module file that should be used to 
   /// load the given module.
   ///
@@ -472,9 +493,12 @@
   ///
   /// \param ModuleName The module whose module file name will be returned.
   ///
+  /// \param ModuleMapPath A path that when combined with \c ModuleName
+  /// uniquely identifies this module. See Module::ModuleMap.
+  ///
   /// \returns The name of the module file that corresponds to this module,
   /// or an empty string if this module does not correspond to any module file.
-  std::string getModuleFileName(StringRef ModuleName);
+  std::string getModuleFileName(StringRef ModuleName, StringRef ModuleMapPath);
 
   /// \brief Lookup a module Search for a module with the given name.
   ///
@@ -486,11 +510,17 @@
   ///
   /// \returns The module with the given name.
   Module *lookupModule(StringRef ModuleName, bool AllowSearch = true);
+
+  /// \brief Try to find a module map file in the given directory, returning
+  /// \c nullptr if none is found.
+  const FileEntry *lookupModuleMapFile(const DirectoryEntry *Dir,
+                                       bool IsFramework);
   
   void IncrementFrameworkLookupCount() { ++NumFrameworkLookups; }
 
   /// \brief Determine whether there is a module map that may map the header
   /// with the given file name to a (sub)module.
+  /// Always returns false if modules are disabled.
   ///
   /// \param Filename The name of the file.
   ///
@@ -543,16 +573,20 @@
   /// of the given search directory.
   void loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir);
 
+  /// \brief Return the HeaderFileInfo structure for the specified FileEntry.
+  const HeaderFileInfo &getFileInfo(const FileEntry *FE) const {
+    return const_cast<HeaderSearch*>(this)->getFileInfo(FE);
+  }
+
 public:
   /// \brief Retrieve the module map.
   ModuleMap &getModuleMap() { return ModMap; }
   
   unsigned header_file_size() const { return FileInfo.size(); }
 
-  /// \brief Return the HeaderFileInfo structure for the specified FileEntry.
-  const HeaderFileInfo &getFileInfo(const FileEntry *FE) const {
-    return const_cast<HeaderSearch*>(this)->getFileInfo(FE);
-  }
+  /// \brief Get a \c HeaderFileInfo structure for the specified \c FileEntry,
+  /// if one exists.
+  bool tryGetFileInfo(const FileEntry *FE, HeaderFileInfo &Result) const;
 
   // Used by external tools
   typedef std::vector<DirectoryLookup>::const_iterator search_dir_iterator;
@@ -602,26 +636,32 @@
     /// invalid.
     LMM_InvalidModuleMap
   };
-  
+
+  LoadModuleMapResult loadModuleMapFileImpl(const FileEntry *File,
+                                            bool IsSystem);
+
   /// \brief Try to load the module map file in the given directory.
   ///
   /// \param DirName The name of the directory where we will look for a module
   /// map file.
   /// \param IsSystem Whether this is a system header directory.
+  /// \param IsFramework Whether this is a framework directory.
   ///
   /// \returns The result of attempting to load the module map file from the
   /// named directory.
-  LoadModuleMapResult loadModuleMapFile(StringRef DirName, bool IsSystem);
+  LoadModuleMapResult loadModuleMapFile(StringRef DirName, bool IsSystem,
+                                        bool IsFramework);
 
   /// \brief Try to load the module map file in the given directory.
   ///
   /// \param Dir The directory where we will look for a module map file.
   /// \param IsSystem Whether this is a system header directory.
+  /// \param IsFramework Whether this is a framework directory.
   ///
   /// \returns The result of attempting to load the module map file from the
   /// named directory.
   LoadModuleMapResult loadModuleMapFile(const DirectoryEntry *Dir,
-                                        bool IsSystem);
+                                        bool IsSystem, bool IsFramework);
 
   /// \brief Return the HeaderFileInfo structure for the specified FileEntry.
   HeaderFileInfo &getFileInfo(const FileEntry *FE);
diff --git a/include/clang/Lex/HeaderSearchOptions.h b/include/clang/Lex/HeaderSearchOptions.h
index 0b21c0d..06024b2 100644
--- a/include/clang/Lex/HeaderSearchOptions.h
+++ b/include/clang/Lex/HeaderSearchOptions.h
@@ -89,6 +89,9 @@
   /// \brief The directory used for the module cache.
   std::string ModuleCachePath;
 
+  /// \brief The directory used for a user build.
+  std::string ModuleUserBuildPath;
+
   /// \brief Whether we should disable the use of the hash string within the
   /// module cache.
   ///
@@ -116,6 +119,12 @@
   /// regenerated often.
   unsigned ModuleCachePruneAfter;
 
+  /// \brief The time in seconds when the build session started.
+  ///
+  /// This time is used by other optimizations in header search and module
+  /// loading.
+  uint64_t BuildSessionTimestamp;
+
   /// \brief The set of macro names that should be ignored for the purposes
   /// of computing the module hash.
   llvm::SetVector<std::string> ModulesIgnoreMacros;
@@ -123,6 +132,9 @@
   /// \brief The set of user-provided module-map-files.
   llvm::SetVector<std::string> ModuleMapFiles;
 
+  /// \brief The set of user-provided virtual filesystem overlay files.
+  std::vector<std::string> VFSOverlayFiles;
+
   /// Include the compiler builtin includes.
   unsigned UseBuiltinIncludes : 1;
 
@@ -138,14 +150,25 @@
   /// Whether header search information should be output as for -v.
   unsigned Verbose : 1;
 
+  /// \brief If true, skip verifying input files used by modules if the
+  /// module was already verified during this build session (see
+  /// \c BuildSessionTimestamp).
+  unsigned ModulesValidateOncePerBuildSession : 1;
+
+  /// \brief Whether to validate system input files when a module is loaded.
+  unsigned ModulesValidateSystemHeaders : 1;
+
 public:
   HeaderSearchOptions(StringRef _Sysroot = "/")
     : Sysroot(_Sysroot), DisableModuleHash(0), ModuleMaps(0),
       ModuleCachePruneInterval(7*24*60*60),
       ModuleCachePruneAfter(31*24*60*60),
+      BuildSessionTimestamp(0),
       UseBuiltinIncludes(true),
       UseStandardSystemIncludes(true), UseStandardCXXIncludes(true),
-      UseLibcxx(false), Verbose(false) {}
+      UseLibcxx(false), Verbose(false),
+      ModulesValidateOncePerBuildSession(false),
+      ModulesValidateSystemHeaders(false) {}
 
   /// AddPath - Add the \p Path path to the specified \p Group list.
   void AddPath(StringRef Path, frontend::IncludeDirGroup Group,
@@ -159,6 +182,10 @@
   void AddSystemHeaderPrefix(StringRef Prefix, bool IsSystemHeader) {
     SystemHeaderPrefixes.push_back(SystemHeaderPrefix(Prefix, IsSystemHeader));
   }
+
+  void AddVFSOverlayFile(StringRef Name) {
+    VFSOverlayFiles.push_back(Name);
+  }
 };
 
 } // end namespace clang
diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h
index f456fa9..edcf883 100644
--- a/include/clang/Lex/Lexer.h
+++ b/include/clang/Lex/Lexer.h
@@ -44,7 +44,7 @@
 /// or buffering/seeking of tokens, only forward lexing is supported.  It relies
 /// on the specified Preprocessor object to handle preprocessor directives, etc.
 class Lexer : public PreprocessorLexer {
-  virtual void anchor();
+  void anchor() override;
 
   //===--------------------------------------------------------------------===//
   // Constant configuration values for this lexer.
@@ -145,7 +145,7 @@
 private:
   /// IndirectLex - An indirect call to 'Lex' that can be invoked via
   ///  the PreprocessorLexer interface.
-  void IndirectLex(Token &Result) { Lex(Result); }
+  void IndirectLex(Token &Result) override { Lex(Result); }
 
 public:
   /// LexFromRawLexer - Lex a token from a designated raw lexer (one with no
@@ -205,7 +205,7 @@
 
   /// ReadToEndOfLine - Read the rest of the current preprocessor line as an
   /// uninterpreted string.  This switches the lexer out of directive mode.
-  void ReadToEndOfLine(SmallVectorImpl<char> *Result = 0);
+  void ReadToEndOfLine(SmallVectorImpl<char> *Result = nullptr);
 
 
   /// Diag - Forwarding function for diagnostics.  This translate a source
@@ -218,7 +218,9 @@
 
   /// getSourceLocation - Return a source location for the next character in
   /// the current file.
-  SourceLocation getSourceLocation() { return getSourceLocation(BufferPtr); }
+  SourceLocation getSourceLocation() override {
+    return getSourceLocation(BufferPtr);
+  }
 
   /// \brief Return the current location in the buffer.
   const char *getBufferLocation() const { return BufferPtr; }
@@ -246,7 +248,7 @@
   static unsigned getSpelling(const Token &Tok, const char *&Buffer, 
                               const SourceManager &SourceMgr,
                               const LangOptions &LangOpts,
-                              bool *Invalid = 0);
+                              bool *Invalid = nullptr);
   
   /// getSpelling() - Return the 'spelling' of the Tok token.  The spelling of a
   /// token is the characters used to represent the token in the source file
@@ -256,7 +258,7 @@
   static std::string getSpelling(const Token &Tok,
                                  const SourceManager &SourceMgr,
                                  const LangOptions &LangOpts, 
-                                 bool *Invalid = 0);
+                                 bool *Invalid = nullptr);
 
   /// getSpelling - This method is used to get the spelling of the
   /// token at the given source location.  If, as is usually true, it
@@ -270,7 +272,7 @@
                                SmallVectorImpl<char> &buffer,
                                const SourceManager &SourceMgr,
                                const LangOptions &LangOpts,
-                               bool *invalid = 0);
+                               bool *invalid = nullptr);
   
   /// MeasureTokenLength - Relex the token at the specified location and return
   /// its length in bytes in the input file.  If the token needs cleaning (e.g.
@@ -329,7 +331,7 @@
   static bool isAtStartOfMacroExpansion(SourceLocation loc,
                                         const SourceManager &SM,
                                         const LangOptions &LangOpts,
-                                        SourceLocation *MacroBegin = 0);
+                                        SourceLocation *MacroBegin = nullptr);
 
   /// \brief Returns true if the given MacroID location points at the last
   /// token of the macro expansion.
@@ -339,7 +341,7 @@
   static bool isAtEndOfMacroExpansion(SourceLocation loc,
                                       const SourceManager &SM,
                                       const LangOptions &LangOpts,
-                                      SourceLocation *MacroEnd = 0);
+                                      SourceLocation *MacroEnd = nullptr);
 
   /// \brief Accepts a range and returns a character range with file locations.
   ///
@@ -375,7 +377,7 @@
   static StringRef getSourceText(CharSourceRange Range,
                                  const SourceManager &SM,
                                  const LangOptions &LangOpts,
-                                 bool *Invalid = 0);
+                                 bool *Invalid = nullptr);
 
   /// \brief Retrieve the name of the immediate macro expansion.
   ///
@@ -546,7 +548,8 @@
 
   /// getCharAndSizeSlow - Handle the slow/uncommon case of the getCharAndSize
   /// method.
-  char getCharAndSizeSlow(const char *Ptr, unsigned &Size, Token *Tok = 0);
+  char getCharAndSizeSlow(const char *Ptr, unsigned &Size,
+                          Token *Tok = nullptr);
 
   /// getEscapedNewLineSize - Return the size of the specified escaped newline,
   /// or 0 if it is not an escaped newline. P[-1] is known to be a "\" on entry
@@ -614,8 +617,28 @@
   /// \return The Unicode codepoint specified by the UCN, or 0 if the UCN is
   ///         invalid.
   uint32_t tryReadUCN(const char *&CurPtr, const char *SlashLoc, Token *Tok);
-};
 
+  /// \brief Try to consume a UCN as part of an identifier at the current
+  /// location.
+  /// \param CurPtr Initially points to the range of characters in the source
+  ///               buffer containing the '\'. Updated to point past the end of
+  ///               the UCN on success.
+  /// \param Size The number of characters occupied by the '\' (including
+  ///             trigraphs and escaped newlines).
+  /// \param Result The token being produced. Marked as containing a UCN on
+  ///               success.
+  /// \return \c true if a UCN was lexed and it produced an acceptable
+  ///         identifier character, \c false otherwise.
+  bool tryConsumeIdentifierUCN(const char *&CurPtr, unsigned Size,
+                               Token &Result);
+
+  /// \brief Try to consume an identifier character encoded in UTF-8.
+  /// \param CurPtr Points to the start of the (potential) UTF-8 code unit
+  ///        sequence. On success, updated to point past the end of it.
+  /// \return \c true if a UTF-8 sequence mapping to an acceptable identifier
+  ///         character was lexed, \c false otherwise.
+  bool tryConsumeIdentifierUTF8Char(const char *&CurPtr);
+};
 
 }  // end namespace clang
 
diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h
index 64d5aa2..b7fcc5d 100644
--- a/include/clang/Lex/LiteralSupport.h
+++ b/include/clang/Lex/LiteralSupport.h
@@ -33,6 +33,9 @@
 class SourceManager;
 class LangOptions;
 
+/// Copy characters from Input to Buf, expanding any UCNs.
+void expandUCNs(SmallVectorImpl<char> &Buf, StringRef Input);
+
 /// NumericLiteralParser - This performs strict semantic analysis of the content
 /// of a ppnumber, classifying it as either integer, floating, or erroneous,
 /// determines the radix of the value and can convert it to a useful value.
@@ -48,6 +51,8 @@
 
   bool saw_exponent, saw_period, saw_ud_suffix;
 
+  SmallString<32> UDSuffixBuf;
+
 public:
   NumericLiteralParser(StringRef TokSpelling,
                        SourceLocation TokLoc,
@@ -58,7 +63,7 @@
   bool isLongLong;
   bool isFloat;       // 1.0f
   bool isImaginary;   // 1.0i
-  bool isMicrosoftInteger;  // Microsoft suffix extension i8, i16, i32, or i64.
+  uint8_t MicrosoftInteger;  // Microsoft suffix extension i8, i16, i32, or i64.
 
   bool isIntegerLiteral() const {
     return !saw_period && !saw_exponent;
@@ -72,7 +77,7 @@
   }
   StringRef getUDSuffix() const {
     assert(saw_ud_suffix);
-    return StringRef(SuffixBegin, ThisTokEnd - SuffixBegin);
+    return UDSuffixBuf;
   }
   unsigned getUDSuffixOffset() const {
     assert(saw_ud_suffix);
@@ -191,15 +196,16 @@
   unsigned UDSuffixToken;
   unsigned UDSuffixOffset;
 public:
-  StringLiteralParser(const Token *StringToks, unsigned NumStringToks,
+  StringLiteralParser(ArrayRef<Token> StringToks,
                       Preprocessor &PP, bool Complain = true);
-  StringLiteralParser(const Token *StringToks, unsigned NumStringToks,
+  StringLiteralParser(ArrayRef<Token> StringToks,
                       const SourceManager &sm, const LangOptions &features,
-                      const TargetInfo &target, DiagnosticsEngine *diags = 0)
+                      const TargetInfo &target,
+                      DiagnosticsEngine *diags = nullptr)
     : SM(sm), Features(features), Target(target), Diags(diags),
       MaxTokenLength(0), SizeBound(0), CharByteWidth(0), Kind(tok::unknown),
       ResultPtr(ResultBuf.data()), hadError(false), Pascal(false) {
-    init(StringToks, NumStringToks);
+    init(StringToks);
   }
     
 
@@ -243,7 +249,7 @@
   }
 
 private:
-  void init(const Token *StringToks, unsigned NumStringToks);
+  void init(ArrayRef<Token> StringToks);
   bool CopyStringFragment(const Token &Tok, const char *TokBegin,
                           StringRef Fragment);
   void DiagnoseLexingError(SourceLocation Loc);
diff --git a/include/clang/Lex/MacroArgs.h b/include/clang/Lex/MacroArgs.h
index 1fd295e..4c0120c 100644
--- a/include/clang/Lex/MacroArgs.h
+++ b/include/clang/Lex/MacroArgs.h
@@ -52,9 +52,10 @@
   /// ArgCache - This is a linked list of MacroArgs objects that the
   /// Preprocessor owns which we use to avoid thrashing malloc/free.
   MacroArgs *ArgCache;
-  
+
   MacroArgs(unsigned NumToks, bool varargsElided)
-    : NumUnexpArgTokens(NumToks), VarargsElided(varargsElided), ArgCache(0) {}
+    : NumUnexpArgTokens(NumToks), VarargsElided(varargsElided),
+      ArgCache(nullptr) {}
   ~MacroArgs() {}
 public:
   /// MacroArgs ctor function - Create a new MacroArgs object with the specified
diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h
index 8cb370e..e9a66e8 100644
--- a/include/clang/Lex/MacroInfo.h
+++ b/include/clang/Lex/MacroInfo.h
@@ -21,7 +21,7 @@
 #include <cassert>
 
 namespace clang {
-  class Preprocessor;
+class Preprocessor;
 
 /// \brief Encapsulates the data about a macro definition (e.g. its tokens).
 ///
@@ -104,8 +104,11 @@
   /// \brief Whether this macro info was loaded from an AST file.
   unsigned FromASTFile : 1;
 
+  /// \brief Whether this macro was used as header guard.
+  bool UsedForHeaderGuard : 1;
+
   ~MacroInfo() {
-    assert(ArgumentList == 0 && "Didn't call destroy before dtor!");
+    assert(!ArgumentList && "Didn't call destroy before dtor!");
   }
 
 public:
@@ -116,7 +119,7 @@
   /// This restores this MacroInfo to a state where it can be reused for other
   /// devious purposes.
   void FreeArgumentList() {
-    ArgumentList = 0;
+    ArgumentList = nullptr;
     NumArguments = 0;
   }
 
@@ -176,7 +179,7 @@
   /// this macro.
   void setArgumentList(IdentifierInfo* const *List, unsigned NumArgs,
                        llvm::BumpPtrAllocator &PPAllocator) {
-    assert(ArgumentList == 0 && NumArguments == 0 &&
+    assert(ArgumentList == nullptr && NumArguments == 0 &&
            "Argument list already set!");
     if (NumArgs == 0) return;
 
@@ -282,6 +285,11 @@
   /// a precompiled header or module) rather than having been parsed.
   bool isFromASTFile() const { return FromASTFile; }
 
+  /// \brief Determine whether this macro was used for a header guard.
+  bool isUsedForHeaderGuard() const { return UsedForHeaderGuard; }
+
+  void setUsedForHeaderGuard(bool Val) { UsedForHeaderGuard = Val; }
+
   /// \brief Retrieve the global ID of the module that owns this particular
   /// macro info.
   unsigned getOwningModuleID() const {
@@ -291,6 +299,8 @@
     return 0;
   }
 
+  void dump() const;
+
 private:
   unsigned getDefinitionLengthSlow(SourceManager &SM) const;
 
@@ -338,12 +348,6 @@
   /// \brief True if the macro directive was loaded from a PCH file.
   bool IsFromPCH : 1;
 
-  /// \brief Whether the macro directive is currently "hidden".
-  ///
-  /// Note that this is transient state that is never serialized to the AST
-  /// file.
-  bool IsHidden : 1;
-
   // Used by DefMacroDirective -----------------------------------------------//
 
   /// \brief True if this macro was imported from a module.
@@ -360,10 +364,10 @@
   bool IsPublic : 1;
 
   MacroDirective(Kind K, SourceLocation Loc)
-    : Previous(0), Loc(Loc), MDKind(K), IsFromPCH(false), IsHidden(false),
+    : Previous(nullptr), Loc(Loc), MDKind(K), IsFromPCH(false),
       IsImported(false), IsAmbiguous(false),
       IsPublic(true) {
-  }
+  } 
 
 public:
   Kind getKind() const { return Kind(MDKind); }
@@ -386,19 +390,13 @@
 
   void setIsFromPCH() { IsFromPCH = true; }
 
-  /// \brief Determine whether this macro directive is hidden.
-  bool isHidden() const { return IsHidden; }
-
-  /// \brief Set whether this macro directive is hidden.
-  void setHidden(bool Val) { IsHidden = Val; }
-
   class DefInfo {
     DefMacroDirective *DefDirective;
     SourceLocation UndefLoc;
     bool IsPublic;
 
   public:
-    DefInfo() : DefDirective(0) { }
+    DefInfo() : DefDirective(nullptr) { }
 
     DefInfo(DefMacroDirective *DefDirective, SourceLocation UndefLoc,
             bool isPublic)
@@ -418,42 +416,44 @@
 
     bool isPublic() const { return IsPublic; }
 
-    bool isValid() const { return DefDirective != 0; }
+    bool isValid() const { return DefDirective != nullptr; }
     bool isInvalid() const { return !isValid(); }
 
     LLVM_EXPLICIT operator bool() const { return isValid(); }
 
-    inline DefInfo getPreviousDefinition(bool AllowHidden = false);
-    const DefInfo getPreviousDefinition(bool AllowHidden = false) const {
-      return const_cast<DefInfo*>(this)->getPreviousDefinition(AllowHidden);
+    inline DefInfo getPreviousDefinition();
+    const DefInfo getPreviousDefinition() const {
+      return const_cast<DefInfo*>(this)->getPreviousDefinition();
     }
   };
 
   /// \brief Traverses the macro directives history and returns the next
   /// macro definition directive along with info about its undefined location
   /// (if there is one) and if it is public or private.
-  DefInfo getDefinition(bool AllowHidden = false);
-  const DefInfo getDefinition(bool AllowHidden = false) const {
-    return const_cast<MacroDirective*>(this)->getDefinition(AllowHidden);
+  DefInfo getDefinition();
+  const DefInfo getDefinition() const {
+    return const_cast<MacroDirective*>(this)->getDefinition();
   }
 
-  bool isDefined(bool AllowHidden = false) const {
-    if (const DefInfo Def = getDefinition(AllowHidden))
+  bool isDefined() const {
+    if (const DefInfo Def = getDefinition())
       return !Def.isUndefined();
     return false;
   }
 
-  const MacroInfo *getMacroInfo(bool AllowHidden = false) const {
-    return getDefinition(AllowHidden).getMacroInfo();
+  const MacroInfo *getMacroInfo() const {
+    return getDefinition().getMacroInfo();
   }
-  MacroInfo *getMacroInfo(bool AllowHidden = false) {
-    return getDefinition(AllowHidden).getMacroInfo();
+  MacroInfo *getMacroInfo() {
+    return getDefinition().getMacroInfo();
   }
 
   /// \brief Find macro definition active in the specified source location. If
   /// this macro was not defined there, return NULL.
   const DefInfo findDirectiveAtLoc(SourceLocation L, SourceManager &SM) const;
 
+  void dump() const;
+
   static bool classof(const MacroDirective *) { return true; }
 };
 
@@ -533,15 +533,15 @@
 
 inline MacroInfo *MacroDirective::DefInfo::getMacroInfo() {
   if (isInvalid())
-    return 0;
+    return nullptr;
   return DefDirective->getInfo();
 }
 
 inline MacroDirective::DefInfo
-MacroDirective::DefInfo::getPreviousDefinition(bool AllowHidden) {
-  if (isInvalid() || DefDirective->getPrevious() == 0)
+MacroDirective::DefInfo::getPreviousDefinition() {
+  if (isInvalid() || DefDirective->getPrevious() == nullptr)
     return DefInfo();
-  return DefDirective->getPrevious()->getDefinition(AllowHidden);
+  return DefDirective->getPrevious()->getDefinition();
 }
 
 }  // end namespace clang
diff --git a/include/clang/Lex/Makefile b/include/clang/Lex/Makefile
deleted file mode 100644
index 762b9a2..0000000
--- a/include/clang/Lex/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-CLANG_LEVEL := ../../..
-TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic
-BUILT_SOURCES = AttrSpellings.inc 
-
-TABLEGEN_INC_FILES_COMMON = 1
-
-include $(CLANG_LEVEL)/Makefile
-
-$(ObjDir)/AttrSpellings.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
-                                  $(ObjDir)/.dir
-	$(Echo) "Building Clang attribute spellings with tblgen"
-	$(Verb) $(ClangTableGen) -gen-clang-attr-spelling-list -o $(call SYSPATH, $@) \
-		-I $(PROJ_SRC_DIR)/../../ $<
diff --git a/include/clang/Lex/ModuleLoader.h b/include/clang/Lex/ModuleLoader.h
index 254ab36..7869799 100644
--- a/include/clang/Lex/ModuleLoader.h
+++ b/include/clang/Lex/ModuleLoader.h
@@ -21,6 +21,7 @@
 
 namespace clang {
 
+class GlobalModuleIndex;
 class IdentifierInfo;
 class Module;
 
@@ -53,11 +54,24 @@
 /// for resolving a module name (e.g., "std") to an actual module file, and
 /// then loading that module.
 class ModuleLoader {
+  // Building a module if true.
+  bool BuildingModule;
 public:
-  ModuleLoader() : HadFatalFailure(false) {}
+  explicit ModuleLoader(bool BuildingModule = false) :
+    BuildingModule(BuildingModule),
+    HadFatalFailure(false) {}
 
   virtual ~ModuleLoader();
   
+  /// \brief Returns true if this instance is building a module.
+  bool buildingModule() const {
+    return BuildingModule;
+  }
+  /// \brief Flag indicating whether this instance is building a module.
+  void setBuildingModule(bool BuildingModuleFlag) {
+    BuildingModule = BuildingModuleFlag;
+  }
+ 
   /// \brief Attempt to load the given module.
   ///
   /// This routine attempts to load the module described by the given 
@@ -88,6 +102,26 @@
                                  SourceLocation ImportLoc,
                                  bool Complain) = 0;
 
+  /// \brief Load, create, or return global module.
+  /// This function returns an existing global module index, if one
+  /// had already been loaded or created, or loads one if it
+  /// exists, or creates one if it doesn't exist.
+  /// Also, importantly, if the index doesn't cover all the modules
+  /// in the module map, it will be update to do so here, because
+  /// of its use in searching for needed module imports and
+  /// associated fixit messages.
+  /// \param TriggerLoc The location for what triggered the load.
+  /// \returns Returns null if load failed.
+  virtual GlobalModuleIndex *loadGlobalModuleIndex(
+                                                SourceLocation TriggerLoc) = 0;
+
+  /// Check global module index for missing imports.
+  /// \param Name The symbol name to look for.
+  /// \param TriggerLoc The location for what triggered the load.
+  /// \returns Returns true if any modules with that symbol found.
+  virtual bool lookupMissingImports(StringRef Name,
+                                    SourceLocation TriggerLoc) = 0;
+
   bool HadFatalFailure;
 };
   
diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h
index 3a17157..a86a927 100644
--- a/include/clang/Lex/ModuleMap.h
+++ b/include/clang/Lex/ModuleMap.h
@@ -38,7 +38,7 @@
   
 class ModuleMap {
   SourceManager &SourceMgr;
-  IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
+  DiagnosticsEngine &Diags;
   const LangOptions &LangOpts;
   const TargetInfo *Target;
   HeaderSearch &HeaderInfo;
@@ -86,7 +86,7 @@
     llvm::PointerIntPair<Module *, 2, ModuleHeaderRole> Storage;
 
   public:
-    KnownHeader() : Storage(0, NormalHeader) { }
+    KnownHeader() : Storage(nullptr, NormalHeader) { }
     KnownHeader(Module *M, ModuleHeaderRole Role) : Storage(M, Role) { }
 
     /// \brief Retrieve the module the header is stored in.
@@ -102,7 +102,9 @@
 
     // \brief Whether this known header is valid (i.e., it has an
     // associated module).
-    LLVM_EXPLICIT operator bool() const { return Storage.getPointer() != 0; }
+    LLVM_EXPLICIT operator bool() const {
+      return Storage.getPointer() != nullptr;
+    }
   };
 
 private:
@@ -131,6 +133,10 @@
     /// \brief Whether the modules we infer are [system] modules.
     unsigned InferSystemModules : 1;
 
+    /// \brief If \c InferModules is non-zero, the module map file that allowed
+    /// inferred modules.  Otherwise, nullptr.
+    const FileEntry *ModuleMapFile;
+
     /// \brief The names of modules that cannot be inferred within this
     /// directory.
     SmallVector<std::string, 2> ExcludedModules;
@@ -175,6 +181,29 @@
   /// resolved.
   Module *resolveModuleId(const ModuleId &Id, Module *Mod, bool Complain) const;
 
+  /// \brief Looks up the modules that \p File corresponds to.
+  ///
+  /// If \p File represents a builtin header within Clang's builtin include
+  /// directory, this also loads all of the module maps to see if it will get
+  /// associated with a specific module (e.g. in /usr/include).
+  HeadersMap::iterator findKnownHeader(const FileEntry *File);
+
+  /// \brief Searches for a module whose umbrella directory contains \p File.
+  ///
+  /// \param File The header to search for.
+  ///
+  /// \param IntermediateDirs On success, contains the set of directories
+  /// searched before finding \p File.
+  KnownHeader findHeaderInUmbrellaDirs(const FileEntry *File,
+                    SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs);
+
+  /// \brief A convenience method to determine if \p File is (possibly nested)
+  /// in an umbrella directory.
+  bool isHeaderInUmbrellaDirs(const FileEntry *File) {
+    SmallVector<const DirectoryEntry *, 2> IntermediateDirs;
+    return static_cast<bool>(findHeaderInUmbrellaDirs(File, IntermediateDirs));
+  }
+
 public:
   /// \brief Construct a new module map.
   ///
@@ -182,13 +211,12 @@
   /// This source manager should be shared with the header-search mechanism,
   /// since they will refer to the same headers.
   ///
-  /// \param DC A diagnostic consumer that will be cloned for use in generating
-  /// diagnostics.
+  /// \param Diags A diagnostic engine used for diagnostics.
   ///
   /// \param LangOpts Language options for this translation unit.
   ///
   /// \param Target The target for this translation unit.
-  ModuleMap(SourceManager &SourceMgr, DiagnosticConsumer &DC,
+  ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags,
             const LangOptions &LangOpts, const TargetInfo *Target,
             HeaderSearch &HeaderInfo);
 
@@ -217,12 +245,30 @@
   /// given header file.  The KnownHeader is default constructed to indicate
   /// that no module owns this header file.
   KnownHeader findModuleForHeader(const FileEntry *File,
-                                  Module *RequestingModule = NULL);
+                                  Module *RequestingModule = nullptr);
+
+  /// \brief Reports errors if a module must not include a specific file.
+  ///
+  /// \param RequestingModule The module including a file.
+  ///
+  /// \param FilenameLoc The location of the inclusion's filename.
+  ///
+  /// \param Filename The included filename as written.
+  ///
+  /// \param File The included file.
+  void diagnoseHeaderInclusion(Module *RequestingModule,
+                               SourceLocation FilenameLoc, StringRef Filename,
+                               const FileEntry *File);
 
   /// \brief Determine whether the given header is part of a module
   /// marked 'unavailable'.
   bool isHeaderInUnavailableModule(const FileEntry *Header) const;
 
+  /// \brief Determine whether the given header is unavailable as part
+  /// of the specified module.
+  bool isHeaderUnavailableInModule(const FileEntry *Header,
+                                   const Module *RequestingModule) const;
+
   /// \brief Retrieve a module with the given name.
   ///
   /// \param Name The name of the module to look up.
@@ -260,13 +306,17 @@
   /// \param Parent The module that will act as the parent of this submodule,
   /// or NULL to indicate that this is a top-level module.
   ///
+  /// \param ModuleMap The module map that defines or allows the inference of
+  /// this module.
+  ///
   /// \param IsFramework Whether this is a framework module.
   ///
   /// \param IsExplicit Whether this is an explicit submodule.
   ///
   /// \returns The found or newly-created module, along with a boolean value
   /// that will be true if the module is newly-created.
-  std::pair<Module *, bool> findOrCreateModule(StringRef Name, Module *Parent, 
+  std::pair<Module *, bool> findOrCreateModule(StringRef Name, Module *Parent,
+                                               const FileEntry *ModuleMap,
                                                bool IsFramework,
                                                bool IsExplicit);
 
diff --git a/include/clang/Lex/MultipleIncludeOpt.h b/include/clang/Lex/MultipleIncludeOpt.h
index b532bf8..e3c6de5 100644
--- a/include/clang/Lex/MultipleIncludeOpt.h
+++ b/include/clang/Lex/MultipleIncludeOpt.h
@@ -60,8 +60,8 @@
     ReadAnyTokens = false;
     ImmediatelyAfterTopLevelIfndef = false;
     DidMacroExpansion = false;
-    TheMacro = 0;
-    DefinedMacro = 0;
+    TheMacro = nullptr;
+    DefinedMacro = nullptr;
   }
 
   SourceLocation GetMacroLocation() const {
@@ -88,8 +88,8 @@
     // below can never "accept".
     ReadAnyTokens = true;
     ImmediatelyAfterTopLevelIfndef = false;
-    DefinedMacro = 0;
-    TheMacro = 0;
+    DefinedMacro = nullptr;
+    TheMacro = nullptr;
   }
 
   /// getHasReadAnyTokensVal - This is used for the \#ifndef hande-shake at the
@@ -166,7 +166,7 @@
     // macro if it's valid (if it isn't, it will be null).
     if (!ReadAnyTokens)
       return TheMacro;
-    return 0;
+    return nullptr;
   }
 
   /// \brief If the ControllingMacro is followed by a macro definition, return
diff --git a/include/clang/Lex/PPCallbacks.h b/include/clang/Lex/PPCallbacks.h
index 0e11218..7f1ea34 100644
--- a/include/clang/Lex/PPCallbacks.h
+++ b/include/clang/Lex/PPCallbacks.h
@@ -214,8 +214,7 @@
 
   /// \brief Callback invoked when a \#pragma gcc dianostic directive is read.
   virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
-                                diag::Mapping mapping, StringRef Str) {
-  }
+                                diag::Severity mapping, StringRef Str) {}
 
   /// \brief Called when an OpenCL extension is either disabled or
   /// enabled with a pragma.
@@ -267,6 +266,10 @@
   virtual void SourceRangeSkipped(SourceRange Range) {
   }
 
+  enum ConditionValueKind {
+    CVK_NotEvaluated, CVK_False, CVK_True
+  };
+
   /// \brief Hook called whenever an \#if is seen.
   /// \param Loc the source location of the directive.
   /// \param ConditionRange The SourceRange of the expression being tested.
@@ -274,7 +277,7 @@
   ///
   // FIXME: better to pass in a list (or tree!) of Tokens.
   virtual void If(SourceLocation Loc, SourceRange ConditionRange,
-                  bool ConditionValue) {
+                  ConditionValueKind ConditionValue) {
   }
 
   /// \brief Hook called whenever an \#elif is seen.
@@ -284,7 +287,7 @@
   /// \param IfLoc the source location of the \#if/\#ifdef/\#ifndef directive.
   // FIXME: better to pass in a list (or tree!) of Tokens.
   virtual void Elif(SourceLocation Loc, SourceRange ConditionRange,
-                    bool ConditionValue, SourceLocation IfLoc) {
+                    ConditionValueKind ConditionValue, SourceLocation IfLoc) {
   }
 
   /// \brief Hook called whenever an \#ifdef is seen.
@@ -329,35 +332,31 @@
     delete First;
   }
 
-  virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
-                           SrcMgr::CharacteristicKind FileType,
-                           FileID PrevFID) {
+  void FileChanged(SourceLocation Loc, FileChangeReason Reason,
+                   SrcMgr::CharacteristicKind FileType,
+                   FileID PrevFID) override {
     First->FileChanged(Loc, Reason, FileType, PrevFID);
     Second->FileChanged(Loc, Reason, FileType, PrevFID);
   }
 
-  virtual void FileSkipped(const FileEntry &ParentFile,
-                           const Token &FilenameTok,
-                           SrcMgr::CharacteristicKind FileType) {
+  void FileSkipped(const FileEntry &ParentFile,
+                   const Token &FilenameTok,
+                   SrcMgr::CharacteristicKind FileType) override {
     First->FileSkipped(ParentFile, FilenameTok, FileType);
     Second->FileSkipped(ParentFile, FilenameTok, FileType);
   }
 
-  virtual bool FileNotFound(StringRef FileName,
-                            SmallVectorImpl<char> &RecoveryPath) {
+  bool FileNotFound(StringRef FileName,
+                    SmallVectorImpl<char> &RecoveryPath) override {
     return First->FileNotFound(FileName, RecoveryPath) ||
            Second->FileNotFound(FileName, RecoveryPath);
   }
 
-  virtual void InclusionDirective(SourceLocation HashLoc,
-                                  const Token &IncludeTok,
-                                  StringRef FileName,
-                                  bool IsAngled,
-                                  CharSourceRange FilenameRange,
-                                  const FileEntry *File,
-                                  StringRef SearchPath,
-                                  StringRef RelativePath,
-                                  const Module *Imported) {
+  void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
+                          StringRef FileName, bool IsAngled,
+                          CharSourceRange FilenameRange, const FileEntry *File,
+                          StringRef SearchPath, StringRef RelativePath,
+                          const Module *Imported) override {
     First->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled,
                               FilenameRange, File, SearchPath, RelativePath,
                               Imported);
@@ -366,147 +365,142 @@
                                Imported);
   }
 
-  virtual void moduleImport(SourceLocation ImportLoc,
-                            ModuleIdPath Path,
-                            const Module *Imported) {
+  void moduleImport(SourceLocation ImportLoc, ModuleIdPath Path,
+                    const Module *Imported) override {
     First->moduleImport(ImportLoc, Path, Imported);
     Second->moduleImport(ImportLoc, Path, Imported);
   }
 
-  virtual void EndOfMainFile() {
+  void EndOfMainFile() override {
     First->EndOfMainFile();
     Second->EndOfMainFile();
   }
 
-  virtual void Ident(SourceLocation Loc, const std::string &str) {
+  void Ident(SourceLocation Loc, const std::string &str) override {
     First->Ident(Loc, str);
     Second->Ident(Loc, str);
   }
 
-  virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
-                             const std::string &Str) {
+  void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
+                     const std::string &Str) override {
     First->PragmaComment(Loc, Kind, Str);
     Second->PragmaComment(Loc, Kind, Str);
   }
 
-  virtual void PragmaDetectMismatch(SourceLocation Loc,
-                                    const std::string &Name,
-                                    const std::string &Value) {
+  void PragmaDetectMismatch(SourceLocation Loc, const std::string &Name,
+                            const std::string &Value) override {
     First->PragmaDetectMismatch(Loc, Name, Value);
     Second->PragmaDetectMismatch(Loc, Name, Value);
   }
 
-  virtual void PragmaMessage(SourceLocation Loc, StringRef Namespace,
-                             PragmaMessageKind Kind, StringRef Str) {
+  void PragmaMessage(SourceLocation Loc, StringRef Namespace,
+                     PragmaMessageKind Kind, StringRef Str) override {
     First->PragmaMessage(Loc, Namespace, Kind, Str);
     Second->PragmaMessage(Loc, Namespace, Kind, Str);
   }
 
-  virtual void PragmaDiagnosticPush(SourceLocation Loc,
-                                    StringRef Namespace) {
+  void PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) override {
     First->PragmaDiagnosticPush(Loc, Namespace);
     Second->PragmaDiagnosticPush(Loc, Namespace);
   }
 
-  virtual void PragmaDiagnosticPop(SourceLocation Loc,
-                                    StringRef Namespace) {
+  void PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace) override {
     First->PragmaDiagnosticPop(Loc, Namespace);
     Second->PragmaDiagnosticPop(Loc, Namespace);
   }
 
-  virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
-                                diag::Mapping mapping, StringRef Str) {
+  void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
+                        diag::Severity mapping, StringRef Str) override {
     First->PragmaDiagnostic(Loc, Namespace, mapping, Str);
     Second->PragmaDiagnostic(Loc, Namespace, mapping, Str);
   }
 
-  virtual void PragmaOpenCLExtension(SourceLocation NameLoc, 
-                                     const IdentifierInfo *Name,
-                                     SourceLocation StateLoc, unsigned State) {
+  void PragmaOpenCLExtension(SourceLocation NameLoc, const IdentifierInfo *Name,
+                             SourceLocation StateLoc, unsigned State) override {
     First->PragmaOpenCLExtension(NameLoc, Name, StateLoc, State);
     Second->PragmaOpenCLExtension(NameLoc, Name, StateLoc, State);
   }
 
-  virtual void PragmaWarning(SourceLocation Loc, StringRef WarningSpec,
-                             ArrayRef<int> Ids) {
+  void PragmaWarning(SourceLocation Loc, StringRef WarningSpec,
+                     ArrayRef<int> Ids) override {
     First->PragmaWarning(Loc, WarningSpec, Ids);
     Second->PragmaWarning(Loc, WarningSpec, Ids);
   }
 
-  virtual void PragmaWarningPush(SourceLocation Loc, int Level) {
+  void PragmaWarningPush(SourceLocation Loc, int Level) override {
     First->PragmaWarningPush(Loc, Level);
     Second->PragmaWarningPush(Loc, Level);
   }
 
-  virtual void PragmaWarningPop(SourceLocation Loc) {
+  void PragmaWarningPop(SourceLocation Loc) override {
     First->PragmaWarningPop(Loc);
     Second->PragmaWarningPop(Loc);
   }
 
-  virtual void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD,
-                            SourceRange Range, const MacroArgs *Args) {
+  void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD,
+                    SourceRange Range, const MacroArgs *Args) override {
     First->MacroExpands(MacroNameTok, MD, Range, Args);
     Second->MacroExpands(MacroNameTok, MD, Range, Args);
   }
 
-  virtual void MacroDefined(const Token &MacroNameTok, const MacroDirective *MD) {
+  void MacroDefined(const Token &MacroNameTok, const MacroDirective *MD) override {
     First->MacroDefined(MacroNameTok, MD);
     Second->MacroDefined(MacroNameTok, MD);
   }
 
-  virtual void MacroUndefined(const Token &MacroNameTok,
-                              const MacroDirective *MD) {
+  void MacroUndefined(const Token &MacroNameTok,
+                      const MacroDirective *MD) override {
     First->MacroUndefined(MacroNameTok, MD);
     Second->MacroUndefined(MacroNameTok, MD);
   }
 
-  virtual void Defined(const Token &MacroNameTok, const MacroDirective *MD,
-                       SourceRange Range) {
+  void Defined(const Token &MacroNameTok, const MacroDirective *MD,
+               SourceRange Range) override {
     First->Defined(MacroNameTok, MD, Range);
     Second->Defined(MacroNameTok, MD, Range);
   }
 
-  virtual void SourceRangeSkipped(SourceRange Range) {
+  void SourceRangeSkipped(SourceRange Range) override {
     First->SourceRangeSkipped(Range);
     Second->SourceRangeSkipped(Range);
   }
 
   /// \brief Hook called whenever an \#if is seen.
-  virtual void If(SourceLocation Loc, SourceRange ConditionRange,
-                  bool ConditionValue) {
+  void If(SourceLocation Loc, SourceRange ConditionRange,
+          ConditionValueKind ConditionValue) override {
     First->If(Loc, ConditionRange, ConditionValue);
     Second->If(Loc, ConditionRange, ConditionValue);
   }
 
   /// \brief Hook called whenever an \#elif is seen.
-  virtual void Elif(SourceLocation Loc, SourceRange ConditionRange,
-                    bool ConditionValue, SourceLocation IfLoc) {
+  void Elif(SourceLocation Loc, SourceRange ConditionRange,
+            ConditionValueKind ConditionValue, SourceLocation IfLoc) override {
     First->Elif(Loc, ConditionRange, ConditionValue, IfLoc);
     Second->Elif(Loc, ConditionRange, ConditionValue, IfLoc);
   }
 
   /// \brief Hook called whenever an \#ifdef is seen.
-  virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
-                     const MacroDirective *MD) {
+  void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
+             const MacroDirective *MD) override {
     First->Ifdef(Loc, MacroNameTok, MD);
     Second->Ifdef(Loc, MacroNameTok, MD);
   }
 
   /// \brief Hook called whenever an \#ifndef is seen.
-  virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
-                      const MacroDirective *MD) {
+  void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
+              const MacroDirective *MD) override {
     First->Ifndef(Loc, MacroNameTok, MD);
     Second->Ifndef(Loc, MacroNameTok, MD);
   }
 
   /// \brief Hook called whenever an \#else is seen.
-  virtual void Else(SourceLocation Loc, SourceLocation IfLoc) {
+  void Else(SourceLocation Loc, SourceLocation IfLoc) override {
     First->Else(Loc, IfLoc);
     Second->Else(Loc, IfLoc);
   }
 
   /// \brief Hook called whenever an \#endif is seen.
-  virtual void Endif(SourceLocation Loc, SourceLocation IfLoc) {
+  void Endif(SourceLocation Loc, SourceLocation IfLoc) override {
     First->Endif(Loc, IfLoc);
     Second->Endif(Loc, IfLoc);
   }
diff --git a/include/clang/Lex/PPConditionalDirectiveRecord.h b/include/clang/Lex/PPConditionalDirectiveRecord.h
index 54a132d..00d2d57 100644
--- a/include/clang/Lex/PPConditionalDirectiveRecord.h
+++ b/include/clang/Lex/PPConditionalDirectiveRecord.h
@@ -86,16 +86,16 @@
   SourceLocation findConditionalDirectiveRegionLoc(SourceLocation Loc) const;
 
 private:
-  virtual void If(SourceLocation Loc, SourceRange ConditionRange,
-                  bool ConditionValue);
-  virtual void Elif(SourceLocation Loc, SourceRange ConditionRange,
-                    bool ConditionValue, SourceLocation IfLoc);
-  virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
-                     const MacroDirective *MD);
-  virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
-                      const MacroDirective *MD);
-  virtual void Else(SourceLocation Loc, SourceLocation IfLoc);
-  virtual void Endif(SourceLocation Loc, SourceLocation IfLoc);
+  void If(SourceLocation Loc, SourceRange ConditionRange,
+          ConditionValueKind ConditionValue) override;
+  void Elif(SourceLocation Loc, SourceRange ConditionRange,
+            ConditionValueKind ConditionValue, SourceLocation IfLoc) override;
+  void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
+             const MacroDirective *MD) override;
+  void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
+              const MacroDirective *MD) override;
+  void Else(SourceLocation Loc, SourceLocation IfLoc) override;
+  void Endif(SourceLocation Loc, SourceLocation IfLoc) override;
 };
 
 } // end namespace clang
diff --git a/include/clang/Lex/PTHLexer.h b/include/clang/Lex/PTHLexer.h
index d748bc1..2352cce 100644
--- a/include/clang/Lex/PTHLexer.h
+++ b/include/clang/Lex/PTHLexer.h
@@ -90,11 +90,11 @@
 
   /// IndirectLex - An indirect call to 'Lex' that can be invoked via
   ///  the PreprocessorLexer interface.
-  void IndirectLex(Token &Result) { Lex(Result); }
+  void IndirectLex(Token &Result) override { Lex(Result); }
 
   /// getSourceLocation - Return a source location for the token in
   /// the current file.
-  SourceLocation getSourceLocation();
+  SourceLocation getSourceLocation() override;
 
   /// SkipBlock - Used by Preprocessor to skip the current conditional block.
   bool SkipBlock();
diff --git a/include/clang/Lex/PTHManager.h b/include/clang/Lex/PTHManager.h
index fad0806..11b5cea 100644
--- a/include/clang/Lex/PTHManager.h
+++ b/include/clang/Lex/PTHManager.h
@@ -114,7 +114,7 @@
   ///  Unlike the version in IdentifierTable, this returns a pointer instead
   ///  of a reference.  If the pointer is NULL then the IdentifierInfo cannot
   ///  be found.
-  IdentifierInfo *get(StringRef Name);
+  IdentifierInfo *get(StringRef Name) override;
 
   /// Create - This method creates PTHManager objects.  The 'file' argument
   ///  is the name of the PTH file.  This method returns NULL upon failure.
diff --git a/include/clang/Lex/Pragma.h b/include/clang/Lex/Pragma.h
index 087448f..4a695a0 100644
--- a/include/clang/Lex/Pragma.h
+++ b/include/clang/Lex/Pragma.h
@@ -69,7 +69,7 @@
 
   /// getIfNamespace - If this is a namespace, return it.  This is equivalent to
   /// using a dynamic_cast, but doesn't require RTTI.
-  virtual PragmaNamespace *getIfNamespace() { return 0; }
+  virtual PragmaNamespace *getIfNamespace() { return nullptr; }
 };
 
 /// EmptyPragmaHandler - A pragma handler which takes no action, which can be
@@ -78,8 +78,8 @@
 public:
   EmptyPragmaHandler();
 
-  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
-                            Token &FirstToken);
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &FirstToken) override;
 };
 
 /// PragmaNamespace - This PragmaHandler subdivides the namespace of pragmas,
@@ -114,10 +114,10 @@
     return Handlers.empty();
   }
 
-  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
-                            Token &FirstToken);
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &FirstToken) override;
 
-  virtual PragmaNamespace *getIfNamespace() { return this; }
+  PragmaNamespace *getIfNamespace() override { return this; }
 };
 
 
diff --git a/include/clang/Lex/PreprocessingRecord.h b/include/clang/Lex/PreprocessingRecord.h
index 2584340..4609fe3 100644
--- a/include/clang/Lex/PreprocessingRecord.h
+++ b/include/clang/Lex/PreprocessingRecord.h
@@ -304,6 +304,9 @@
     /// and are referenced by the iterator using negative indices.
     std::vector<PreprocessedEntity *> LoadedPreprocessedEntities;
 
+    /// \brief The set of ranges that were skipped by the preprocessor,
+    std::vector<SourceRange> SkippedRanges;
+
     /// \brief Global (loaded or local) ID for a preprocessed entity.
     /// Negative values are used to indicate preprocessed entities
     /// loaded from the external source while non-negative values are used to
@@ -400,7 +403,7 @@
       typedef std::random_access_iterator_tag iterator_category;
       typedef int                 difference_type;
       
-      iterator() : Self(0), Position(0) { }
+      iterator() : Self(nullptr), Position(0) { }
       
       iterator(PreprocessingRecord *Self, int Position)
         : Self(Self), Position(Position) { }
@@ -556,28 +559,32 @@
     /// \brief Retrieve the macro definition that corresponds to the given
     /// \c MacroInfo.
     MacroDefinition *findMacroDefinition(const MacroInfo *MI);
+
+    /// \brief Retrieve all ranges that got skipped while preprocessing.
+    const std::vector<SourceRange> &getSkippedRanges() const {
+      return SkippedRanges;
+    }
         
   private:
-    virtual void MacroExpands(const Token &Id, const MacroDirective *MD,
-                              SourceRange Range, const MacroArgs *Args);
-    virtual void MacroDefined(const Token &Id, const MacroDirective *MD);
-    virtual void MacroUndefined(const Token &Id, const MacroDirective *MD);
-    virtual void InclusionDirective(SourceLocation HashLoc,
-                                    const Token &IncludeTok,
-                                    StringRef FileName,
-                                    bool IsAngled,
-                                    CharSourceRange FilenameRange,
-                                    const FileEntry *File,
-                                    StringRef SearchPath,
-                                    StringRef RelativePath,
-                                    const Module *Imported);
-    virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
-                       const MacroDirective *MD);
-    virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
-                        const MacroDirective *MD);
+    void MacroExpands(const Token &Id, const MacroDirective *MD,
+                      SourceRange Range, const MacroArgs *Args) override;
+    void MacroDefined(const Token &Id, const MacroDirective *MD) override;
+    void MacroUndefined(const Token &Id, const MacroDirective *MD) override;
+    void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
+                            StringRef FileName, bool IsAngled,
+                            CharSourceRange FilenameRange,
+                            const FileEntry *File, StringRef SearchPath,
+                            StringRef RelativePath,
+                            const Module *Imported) override;
+    void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
+               const MacroDirective *MD) override;
+    void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
+                const MacroDirective *MD) override;
     /// \brief Hook called whenever the 'defined' operator is seen.
-    virtual void Defined(const Token &MacroNameTok, const MacroDirective *MD,
-                         SourceRange Range);
+    void Defined(const Token &MacroNameTok, const MacroDirective *MD,
+                 SourceRange Range) override;
+
+    void SourceRangeSkipped(SourceRange Range) override;
 
     void addMacroExpansion(const Token &Id, const MacroInfo *MI,
                            SourceRange Range);
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index 223fd47..d4b4ba2 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -6,9 +6,10 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-//
-//  This file defines the Preprocessor interface.
-//
+///
+/// \file
+/// \brief Defines the clang::Preprocessor interface.
+///
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_LEX_PREPROCESSOR_H
@@ -28,10 +29,10 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Allocator.h"
+#include <memory>
 #include <vector>
 
 namespace llvm {
@@ -64,7 +65,7 @@
   IdentifierInfo *II;
 
 public:
-  TokenValue(tok::TokenKind Kind) : Kind(Kind), II(0) {
+  TokenValue(tok::TokenKind Kind) : Kind(Kind), II(nullptr) {
     assert(Kind != tok::raw_identifier && "Raw identifiers are not supported.");
     assert(Kind != tok::identifier &&
            "Identifiers should be created by TokenValue(IdentifierInfo *)");
@@ -78,11 +79,12 @@
   }
 };
 
-/// Preprocessor - This object engages in a tight little dance with the lexer to
-/// efficiently preprocess tokens.  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.
+/// \brief Engages in a tight little dance with the lexer to efficiently
+/// preprocess tokens.
 ///
+/// 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;
   DiagnosticsEngine        *Diags;
@@ -98,12 +100,12 @@
   ExternalPreprocessorSource *ExternalSource;
 
 
-  /// PTH - An optional PTHManager object used for getting tokens from
-  ///  a token cache rather than lexing the original source file.
-  OwningPtr<PTHManager> PTH;
+  /// An optional PTHManager object used for getting tokens from
+  /// a token cache rather than lexing the original source file.
+  std::unique_ptr<PTHManager> PTH;
 
-  /// BP - A BumpPtrAllocator object used to quickly allocate and release
-  ///  objects internal to the Preprocessor.
+  /// A BumpPtrAllocator object used to quickly allocate and release
+  /// objects internal to the Preprocessor.
   llvm::BumpPtrAllocator BP;
 
   /// Identifiers for builtin macros and other builtins.
@@ -114,6 +116,7 @@
   IdentifierInfo *Ident__TIMESTAMP__;              // __TIMESTAMP__
   IdentifierInfo *Ident__COUNTER__;                // __COUNTER__
   IdentifierInfo *Ident_Pragma, *Ident__pragma;    // _Pragma, __pragma
+  IdentifierInfo *Ident__identifier;               // __identifier
   IdentifierInfo *Ident__VA_ARGS__;                // __VA_ARGS__
   IdentifierInfo *Ident__has_feature;              // __has_feature
   IdentifierInfo *Ident__has_extension;            // __has_extension
@@ -122,6 +125,7 @@
   IdentifierInfo *Ident__has_include;              // __has_include
   IdentifierInfo *Ident__has_include_next;         // __has_include_next
   IdentifierInfo *Ident__has_warning;              // __has_warning
+  IdentifierInfo *Ident__is_identifier;            // __is_identifier
   IdentifierInfo *Ident__building_module;          // __building_module
   IdentifierInfo *Ident__MODULE__;                 // __MODULE__
 
@@ -129,7 +133,7 @@
   unsigned CounterValue;  // Next __COUNTER__ value.
 
   enum {
-    /// MaxIncludeStackDepth - Maximum depth of \#includes.
+    /// \brief Maximum depth of \#includes.
     MaxAllowedIncludeStackDepth = 200
   };
 
@@ -144,12 +148,11 @@
   /// Whether the preprocessor owns the header search object.
   bool OwnsHeaderSearch : 1;
 
-  /// DisableMacroExpansion - True if macro expansion is disabled.
+  /// True if macro expansion is disabled.
   bool DisableMacroExpansion : 1;
 
-  /// MacroExpansionInDirectivesOverride - Temporarily disables
-  /// DisableMacroExpansion (i.e. enables expansion) when parsing preprocessor
-  /// directives.
+  /// Temporarily disables DisableMacroExpansion (i.e. enables expansion)
+  /// when parsing preprocessor directives.
   bool MacroExpansionInDirectivesOverride : 1;
 
   class ResetMacroExpansionHelper;
@@ -169,23 +172,25 @@
   /// \brief True if we are pre-expanding macro arguments.
   bool InMacroArgPreExpansion;
 
-  /// Identifiers - This is mapping/lookup information for all identifiers in
+  /// \brief Mapping/lookup information for all identifiers in
   /// the program, including program keywords.
   mutable IdentifierTable Identifiers;
 
-  /// Selectors - This table contains all the selectors in the program. Unlike
-  /// IdentifierTable above, this table *isn't* populated by the preprocessor.
-  /// It is declared/expanded here because it's role/lifetime is
-  /// conceptually similar the IdentifierTable. In addition, the current control
-  /// flow (in clang::ParseAST()), make it convenient to put here.
+  /// \brief This table contains all the selectors in the program.
+  ///
+  /// Unlike IdentifierTable above, this table *isn't* populated by the
+  /// preprocessor. It is declared/expanded here because its role/lifetime is
+  /// conceptually similar to the IdentifierTable. In addition, the current
+  /// control flow (in clang::ParseAST()), make it convenient to put here.
+  ///
   /// FIXME: Make sure the lifetime of Identifiers/Selectors *isn't* tied to
   /// the lifetime of the preprocessor.
   SelectorTable Selectors;
 
-  /// BuiltinInfo - Information about builtins.
+  /// \brief Information about builtins.
   Builtin::Context BuiltinInfo;
 
-  /// PragmaHandlers - This tracks all of the pragmas that the client registered
+  /// \brief Tracks all of the pragmas that the client registered
   /// with this preprocessor.
   PragmaNamespace *PragmaHandlers;
 
@@ -197,6 +202,9 @@
   /// avoid tearing the Lexer and etc. down).
   bool IncrementalProcessing;
 
+  /// The kind of translation unit we are processing.
+  TranslationUnitKind TUKind;
+
   /// \brief The code-completion handler.
   CodeCompletionHandler *CodeComplete;
 
@@ -216,7 +224,7 @@
   /// for preprocessing.
   SourceLocation CodeCompletionFileLoc;
 
-  /// \brief The source location of the 'import' contextual keyword we just 
+  /// \brief The source location of the \c import contextual keyword we just 
   /// lexed, if any.
   SourceLocation ModuleImportLoc;
 
@@ -226,46 +234,53 @@
   /// \brief Whether the last token we lexed was an '@'.
   bool LastTokenWasAt;
 
-  /// \brief Whether the module import expectes an identifier next. Otherwise,
+  /// \brief Whether the module import expects an identifier next. Otherwise,
   /// it expects a '.' or ';'.
   bool ModuleImportExpectsIdentifier;
   
   /// \brief The source location of the currently-active
-  /// #pragma clang arc_cf_code_audited begin.
+  /// \#pragma clang arc_cf_code_audited begin.
   SourceLocation PragmaARCCFCodeAuditedLoc;
 
   /// \brief True if we hit the code-completion point.
   bool CodeCompletionReached;
 
   /// \brief The number of bytes that we will initially skip when entering the
-  /// main file, which is used when loading a precompiled preamble, along
-  /// with a flag that indicates whether skipping this number of bytes will
-  /// place the lexer at the start of a line.
+  /// main file, along with a flag that indicates whether skipping this number
+  /// of bytes will place the lexer at the start of a line.
+  ///
+  /// This is used when loading a precompiled preamble.
   std::pair<unsigned, bool> SkipMainFilePreamble;
 
-  /// CurLexer - This is the current top of the stack that we're lexing from if
+  /// \brief The current top of the stack that we're lexing from if
   /// not expanding a macro and we are lexing directly from source code.
-  ///  Only one of CurLexer, CurPTHLexer, or CurTokenLexer will be non-null.
-  OwningPtr<Lexer> CurLexer;
+  ///
+  /// Only one of CurLexer, CurPTHLexer, or CurTokenLexer will be non-null.
+  std::unique_ptr<Lexer> CurLexer;
 
-  /// CurPTHLexer - This is the current top of stack that we're lexing from if
-  ///  not expanding from a macro and we are lexing from a PTH cache.
-  ///  Only one of CurLexer, CurPTHLexer, or CurTokenLexer will be non-null.
-  OwningPtr<PTHLexer> CurPTHLexer;
+  /// \brief The current top of stack that we're lexing from if
+  /// not expanding from a macro and we are lexing from a PTH cache.
+  ///
+  /// Only one of CurLexer, CurPTHLexer, or CurTokenLexer will be non-null.
+  std::unique_ptr<PTHLexer> CurPTHLexer;
 
-  /// CurPPLexer - This is the current top of the stack what we're lexing from
-  ///  if not expanding a macro.  This is an alias for either CurLexer or
-  ///  CurPTHLexer.
+  /// \brief The current top of the stack what we're lexing from
+  /// if not expanding a macro.
+  ///
+  /// This is an alias for either CurLexer or  CurPTHLexer.
   PreprocessorLexer *CurPPLexer;
 
-  /// CurLookup - The DirectoryLookup structure used to find the current
-  /// FileEntry, if CurLexer is non-null and if applicable.  This allows us to
-  /// implement \#include_next and find directory-specific properties.
+  /// \brief Used to find the current FileEntry, if CurLexer is non-null
+  /// and if applicable.
+  ///
+  /// This allows us to implement \#include_next and find directory-specific
+  /// properties.
   const DirectoryLookup *CurDirLookup;
 
-  /// CurTokenLexer - This is the current macro we are expanding, if we are
-  /// expanding a macro.  One of CurLexer and CurTokenLexer must be null.
-  OwningPtr<TokenLexer> CurTokenLexer;
+  /// \brief The current macro we are expanding, if we are expanding a macro.
+  ///
+  /// One of CurLexer and CurTokenLexer must be null.
+  std::unique_ptr<TokenLexer> CurTokenLexer;
 
   /// \brief The kind of lexer we're currently working with.
   enum CurLexerKind {
@@ -276,26 +291,48 @@
     CLK_LexAfterModuleImport
   } CurLexerKind;
 
-  /// IncludeMacroStack - This keeps track of the stack of files currently
+  /// \brief If the current lexer is for a submodule that is being built, this
+  /// is that submodule.
+  Module *CurSubmodule;
+
+  /// \brief Keeps track of the stack of files currently
   /// \#included, and macros currently being expanded from, not counting
   /// CurLexer/CurTokenLexer.
   struct IncludeStackInfo {
-    enum CurLexerKind     CurLexerKind;
-    Lexer                 *TheLexer;
-    PTHLexer              *ThePTHLexer;
-    PreprocessorLexer     *ThePPLexer;
-    TokenLexer            *TheTokenLexer;
-    const DirectoryLookup *TheDirLookup;
+    enum CurLexerKind           CurLexerKind;
+    Module                     *TheSubmodule;
+    std::unique_ptr<Lexer>      TheLexer;
+    std::unique_ptr<PTHLexer>   ThePTHLexer;
+    PreprocessorLexer          *ThePPLexer;
+    std::unique_ptr<TokenLexer> TheTokenLexer;
+    const DirectoryLookup      *TheDirLookup;
 
-    IncludeStackInfo(enum CurLexerKind K, Lexer *L, PTHLexer* P,
-                     PreprocessorLexer* PPL,
-                     TokenLexer* TL, const DirectoryLookup *D)
-      : CurLexerKind(K), TheLexer(L), ThePTHLexer(P), ThePPLexer(PPL),
-        TheTokenLexer(TL), TheDirLookup(D) {}
+    // The following constructors are completely useless copies of the default
+    // versions, only needed to pacify MSVC.
+    IncludeStackInfo(enum CurLexerKind CurLexerKind, Module *TheSubmodule,
+                     std::unique_ptr<Lexer> &&TheLexer,
+                     std::unique_ptr<PTHLexer> &&ThePTHLexer,
+                     PreprocessorLexer *ThePPLexer,
+                     std::unique_ptr<TokenLexer> &&TheTokenLexer,
+                     const DirectoryLookup *TheDirLookup)
+        : CurLexerKind(std::move(CurLexerKind)),
+          TheSubmodule(std::move(TheSubmodule)), TheLexer(std::move(TheLexer)),
+          ThePTHLexer(std::move(ThePTHLexer)),
+          ThePPLexer(std::move(ThePPLexer)),
+          TheTokenLexer(std::move(TheTokenLexer)),
+          TheDirLookup(std::move(TheDirLookup)) {}
+    IncludeStackInfo(IncludeStackInfo &&RHS)
+        : CurLexerKind(std::move(RHS.CurLexerKind)),
+          TheSubmodule(std::move(RHS.TheSubmodule)),
+          TheLexer(std::move(RHS.TheLexer)),
+          ThePTHLexer(std::move(RHS.ThePTHLexer)),
+          ThePPLexer(std::move(RHS.ThePPLexer)),
+          TheTokenLexer(std::move(RHS.TheTokenLexer)),
+          TheDirLookup(std::move(RHS.TheDirLookup)) {}
   };
   std::vector<IncludeStackInfo> IncludeMacroStack;
 
-  /// Callbacks - These are actions invoked when some preprocessor activity is
+  /// \brief Actions invoked when some preprocessor activity is
   /// encountered (e.g. a file is \#included, etc).
   PPCallbacks *Callbacks;
 
@@ -308,14 +345,16 @@
   };
   SmallVector<MacroExpandsInfo, 2> DelayedMacroExpandsCallbacks;
 
-  /// Macros - For each IdentifierInfo that was associated with a macro, we
+  /// For each IdentifierInfo that was associated with a macro, we
   /// keep a mapping to the history of all macro definitions and #undefs in
   /// the reverse order (the latest one is in the head of the list).
   llvm::DenseMap<const IdentifierInfo*, MacroDirective*> Macros;
   friend class ASTReader;
   
   /// \brief Macros that we want to warn because they are not used at the end
-  /// of the translation unit; we store just their SourceLocations instead
+  /// of the translation unit.
+  ///
+  /// We store just their SourceLocations instead of
   /// something like MacroInfo*. The benefit of this is that when we are
   /// deserializing from PCH, we don't need to deserialize identifier & macros
   /// just so that we can report that they are unused, we just warn using
@@ -324,35 +363,36 @@
   typedef llvm::SmallPtrSet<SourceLocation, 32> WarnUnusedMacroLocsTy;
   WarnUnusedMacroLocsTy WarnUnusedMacroLocs;
 
-  /// MacroArgCache - This is a "freelist" of MacroArg objects that can be
+  /// \brief A "freelist" of MacroArg objects that can be
   /// reused for quick allocation.
   MacroArgs *MacroArgCache;
   friend class MacroArgs;
 
-  /// PragmaPushMacroInfo - For each IdentifierInfo used in a #pragma
-  /// push_macro directive, we keep a MacroInfo stack used to restore
-  /// previous macro value.
+  /// For each IdentifierInfo used in a \#pragma push_macro directive,
+  /// we keep a MacroInfo stack used to restore the previous macro value.
   llvm::DenseMap<IdentifierInfo*, std::vector<MacroInfo*> > PragmaPushMacroInfo;
 
   // Various statistics we track for performance analysis.
-  unsigned NumDirectives, NumIncluded, NumDefined, NumUndefined, NumPragma;
+  unsigned NumDirectives, NumDefined, NumUndefined, NumPragma;
   unsigned NumIf, NumElse, NumEndif;
   unsigned NumEnteredSourceFiles, MaxIncludeStackDepth;
   unsigned NumMacroExpanded, NumFnMacroExpanded, NumBuiltinMacroExpanded;
   unsigned NumFastMacroExpanded, NumTokenPaste, NumFastTokenPaste;
   unsigned NumSkipped;
 
-  /// Predefines - This string is the predefined macros that preprocessor
-  /// should use from the command line etc.
+  /// \brief The predefined macros that preprocessor should use from the
+  /// command line etc.
   std::string Predefines;
 
   /// \brief The file ID for the preprocessor predefines.
   FileID PredefinesFileID;
 
-  /// TokenLexerCache - Cache macro expanders to reduce malloc traffic.
+  /// \{
+  /// \brief Cache of macro expanders to reduce malloc traffic.
   enum { TokenLexerCacheSize = 8 };
   unsigned NumCachedTokenLexers;
   TokenLexer *TokenLexerCache[TokenLexerCacheSize];
+  /// \}
 
   /// \brief Keeps macro expanded tokens for TokenLexers.
   //
@@ -372,17 +412,20 @@
 private:  // Cached tokens state.
   typedef SmallVector<Token, 1> CachedTokensTy;
 
-  /// CachedTokens - Cached tokens are stored here when we do backtracking or
+  /// \brief Cached tokens are stored here when we do backtracking or
   /// lookahead. They are "lexed" by the CachingLex() method.
   CachedTokensTy CachedTokens;
 
-  /// CachedLexPos - The position of the cached token that CachingLex() should
-  /// "lex" next. If it points beyond the CachedTokens vector, it means that
-  /// a normal Lex() should be invoked.
+  /// \brief The position of the cached token that CachingLex() should
+  /// "lex" next.
+  ///
+  /// If it points beyond the CachedTokens vector, it means that a normal
+  /// Lex() should be invoked.
   CachedTokensTy::size_type CachedLexPos;
 
-  /// BacktrackPositions - Stack of backtrack positions, allowing nested
-  /// backtracks. The EnableBacktrackAtThisPos() method pushes a position to
+  /// \brief Stack of backtrack positions, allowing nested backtracks.
+  ///
+  /// The EnableBacktrackAtThisPos() method pushes a position to
   /// indicate where CachedLexPos should be set when the BackTrack() method is
   /// invoked (at which point the last position is popped).
   std::vector<CachedTokensTy::size_type> BacktrackPositions;
@@ -397,7 +440,7 @@
   /// of that list.
   MacroInfoChain *MIChainHead;
 
-  /// MICache - A "freelist" of MacroInfo objects that can be reused for quick
+  /// A "freelist" of MacroInfo objects that can be reused for quick
   /// allocation.
   MacroInfoChain *MICache;
 
@@ -412,20 +455,18 @@
 public:
   Preprocessor(IntrusiveRefCntPtr<PreprocessorOptions> PPOpts,
                DiagnosticsEngine &diags, LangOptions &opts,
-               const TargetInfo *target,
                SourceManager &SM, HeaderSearch &Headers,
                ModuleLoader &TheModuleLoader,
-               IdentifierInfoLookup *IILookup = 0,
+               IdentifierInfoLookup *IILookup = nullptr,
                bool OwnsHeaderSearch = false,
-               bool DelayInitialization = false,
-               bool IncrProcessing = false);
+               TranslationUnitKind TUKind = TU_Complete);
 
   ~Preprocessor();
 
-  /// \brief Initialize the preprocessor, if the constructor did not already
-  /// perform the initialization.
+  /// \brief Initialize the preprocessor using information about the target.
   ///
-  /// \param Target Information about the target.
+  /// \param Target is owned by the caller and must remain valid for the
+  /// lifetime of the preprocessor.
   void Initialize(const TargetInfo &Target);
 
   /// \brief Retrieve the preprocessor options used to initialize this
@@ -470,8 +511,7 @@
     return ParsingIfOrElifDirective;
   }
 
-  /// SetCommentRetentionState - Control whether or not the preprocessor retains
-  /// comments in output.
+  /// \brief Control whether the preprocessor retains comments in output.
   void SetCommentRetentionState(bool KeepComments, bool KeepMacroComments) {
     this->KeepComments = KeepComments | KeepMacroComments;
     this->KeepMacroComments = KeepMacroComments;
@@ -500,26 +540,29 @@
   /// false if it is producing tokens to be consumed by Parse and Sema.
   bool isPreprocessedOutput() const { return PreprocessedOutput; }
 
-  /// isCurrentLexer - Return true if we are lexing directly from the specified
-  /// lexer.
+  /// \brief Return true if we are lexing directly from the specified lexer.
   bool isCurrentLexer(const PreprocessorLexer *L) const {
     return CurPPLexer == L;
   }
 
-  /// getCurrentLexer - Return the current lexer being lexed from.  Note
-  /// that this ignores any potentially active macro expansions and _Pragma
+  /// \brief Return the current lexer being lexed from.
+  ///
+  /// Note that this ignores any potentially active macro expansions and _Pragma
   /// expansions going on at the time.
   PreprocessorLexer *getCurrentLexer() const { return CurPPLexer; }
 
-  /// getCurrentFileLexer - Return the current file lexer being lexed from.
+  /// \brief Return the current file lexer being lexed from.
+  ///
   /// Note that this ignores any potentially active macro expansions and _Pragma
   /// expansions going on at the time.
   PreprocessorLexer *getCurrentFileLexer() const;
 
-  /// \brief Returns the file ID for the preprocessor predefines.
+  /// \brief Returns the FileID for the preprocessor predefines.
   FileID getPredefinesFileID() const { return PredefinesFileID; }
 
-  /// getPPCallbacks/addPPCallbacks - Accessors for preprocessor callbacks.
+  /// \{
+  /// \brief Accessors for preprocessor callbacks.
+  ///
   /// Note that this class takes ownership of any PPCallbacks object given to
   /// it.
   PPCallbacks *getPPCallbacks() const { return Callbacks; }
@@ -528,12 +571,13 @@
       C = new PPChainedCallbacks(C, Callbacks);
     Callbacks = C;
   }
+  /// \}
 
   /// \brief Given an identifier, return its latest MacroDirective if it is
-  // \#defined or null if it isn't \#define'd.
+  /// \#defined or null if it isn't \#define'd.
   MacroDirective *getMacroDirective(IdentifierInfo *II) const {
     if (!II->hasMacroDefinition())
-      return 0;
+      return nullptr;
 
     MacroDirective *MD = getMacroDirectiveHistory(II);
     assert(MD->isDefined() && "Macro is undefined!");
@@ -547,13 +591,14 @@
   MacroInfo *getMacroInfo(IdentifierInfo *II) {
     if (MacroDirective *MD = getMacroDirective(II))
       return MD->getMacroInfo();
-    return 0;
+    return nullptr;
   }
 
   /// \brief Given an identifier, return the (probably #undef'd) MacroInfo
-  /// representing the most recent macro definition. One can iterate over all
-  /// previous macro definitions from it. This method should only be called for
-  /// identifiers that hadMacroDefinition().
+  /// representing the most recent macro definition.
+  ///
+  /// One can iterate over all previous macro definitions from the most recent
+  /// one. This should only be called for identifiers that hadMacroDefinition().
   MacroDirective *getMacroDirectiveHistory(const IdentifierInfo *II) const;
 
   /// \brief Add a directive to the macro directive history for this identifier.
@@ -571,14 +616,15 @@
   /// \brief Set a MacroDirective that was loaded from a PCH file.
   void setLoadedMacroDirective(IdentifierInfo *II, MacroDirective *MD);
 
-  /// macro_iterator/macro_begin/macro_end - This allows you to walk the macro
-  /// history table. Currently defined macros have
+  /// \{
+  /// Iterators for the macro history table. Currently defined macros have
   /// IdentifierInfo::hasMacroDefinition() set and an empty
   /// MacroInfo::getUndefLoc() at the head of the list.
   typedef llvm::DenseMap<const IdentifierInfo *,
                          MacroDirective*>::const_iterator macro_iterator;
   macro_iterator macro_begin(bool IncludeExternalMacros = true) const;
   macro_iterator macro_end(bool IncludeExternalMacros = true) const;
+  /// \}
 
   /// \brief Return the name of the macro defined before \p Loc that has
   /// spelling \p Tokens.  If there are multiple macros with same spelling,
@@ -587,8 +633,9 @@
                                      ArrayRef<TokenValue> Tokens) const;
 
   const std::string &getPredefines() const { return Predefines; }
-  /// setPredefines - Set the predefines for this Preprocessor.  These
-  /// predefines are automatically injected when parsing the main file.
+  /// \brief Set the predefines for this Preprocessor.
+  ///
+  /// These predefines are automatically injected when parsing the main file.
   void setPredefines(const char *P) { Predefines = P; }
   void setPredefines(const std::string &P) { Predefines = P; }
 
@@ -598,23 +645,28 @@
     return &Identifiers.get(Name);
   }
 
-  /// AddPragmaHandler - Add the specified pragma handler to the preprocessor.
-  /// If 'Namespace' is non-null, then it is a token required to exist on the
+  /// \brief Add the specified pragma handler to this preprocessor.
+  ///
+  /// If \p Namespace is non-null, then it is a token required to exist on the
   /// pragma line before the pragma string starts, e.g. "STDC" or "GCC".
   void AddPragmaHandler(StringRef Namespace, PragmaHandler *Handler);
   void AddPragmaHandler(PragmaHandler *Handler) {
     AddPragmaHandler(StringRef(), Handler);
   }
 
-  /// RemovePragmaHandler - Remove the specific pragma handler from
-  /// the preprocessor. If \p Namespace is non-null, then it should
-  /// be the namespace that \p Handler was added to. It is an error
-  /// to remove a handler that has not been registered.
+  /// \brief Remove the specific pragma handler from this preprocessor.
+  ///
+  /// If \p Namespace is non-null, then it should be the namespace that
+  /// \p Handler was added to. It is an error to remove a handler that
+  /// has not been registered.
   void RemovePragmaHandler(StringRef Namespace, PragmaHandler *Handler);
   void RemovePragmaHandler(PragmaHandler *Handler) {
     RemovePragmaHandler(StringRef(), Handler);
   }
 
+  /// Install empty handlers for all pragmas (making them ignored).
+  void IgnorePragmas();
+
   /// \brief Add the specified comment handler to the preprocessor.
   void addCommentHandler(CommentHandler *Handler);
 
@@ -635,7 +687,7 @@
 
   /// \brief Clear out the code completion handler.
   void clearCodeCompletionHandler() {
-    CodeComplete = 0;
+    CodeComplete = nullptr;
   }
 
   /// \brief Hook used by the lexer to invoke the "natural language" code
@@ -650,51 +702,51 @@
   /// all macro expansions, macro definitions, etc.
   void createPreprocessingRecord();
 
-  /// EnterMainSourceFile - Enter the specified FileID as the main source file,
+  /// \brief Enter the specified FileID as the main source file,
   /// which implicitly adds the builtin defines etc.
   void EnterMainSourceFile();
 
-  /// EndSourceFile - Inform the preprocessor callbacks that processing is
-  /// complete.
+  /// \brief Inform the preprocessor callbacks that processing is complete.
   void EndSourceFile();
 
-  /// EnterSourceFile - Add a source file to the top of the include stack and
-  /// start lexing tokens from it instead of the current buffer.  Emit an error
-  /// and don't enter the file on error.
-  void EnterSourceFile(FileID CurFileID, const DirectoryLookup *Dir,
+  /// \brief Add a source file to the top of the include stack and
+  /// start lexing tokens from it instead of the current buffer.
+  ///
+  /// Emits a diagnostic, doesn't enter the file, and returns true on error.
+  bool EnterSourceFile(FileID CurFileID, const DirectoryLookup *Dir,
                        SourceLocation Loc);
 
-  /// EnterMacro - Add a Macro to the top of the include stack and start lexing
-  /// tokens from it instead of the current buffer.  Args specifies the
-  /// tokens input to a function-like macro.
+  /// \brief Add a Macro to the top of the include stack and start lexing
+  /// tokens from it instead of the current buffer.
   ///
-  /// ILEnd specifies the location of the ')' for a function-like macro or the
-  /// identifier for an object-like macro.
+  /// \param Args specifies the tokens input to a function-like macro.
+  /// \param ILEnd specifies the location of the ')' for a function-like macro
+  /// or the identifier for an object-like macro.
   void EnterMacro(Token &Identifier, SourceLocation ILEnd, MacroInfo *Macro,
                   MacroArgs *Args);
 
-  /// EnterTokenStream - Add a "macro" context to the top of the include stack,
+  /// \brief Add a "macro" context to the top of the include stack,
   /// which will cause the lexer to start returning the specified tokens.
   ///
-  /// If DisableMacroExpansion is true, tokens lexed from the token stream will
-  /// not be subject to further macro expansion.  Otherwise, these tokens will
-  /// be re-macro-expanded when/if expansion is enabled.
+  /// If \p DisableMacroExpansion is true, tokens lexed from the token stream
+  /// will not be subject to further macro expansion. Otherwise, these tokens
+  /// will be re-macro-expanded when/if expansion is enabled.
   ///
-  /// If OwnsTokens is false, this method assumes that the specified stream of
-  /// tokens has a permanent owner somewhere, so they do not need to be copied.
-  /// If it is true, it assumes the array of tokens is allocated with new[] and
-  /// must be freed.
-  ///
+  /// If \p OwnsTokens is false, this method assumes that the specified stream
+  /// of tokens has a permanent owner somewhere, so they do not need to be
+  /// copied. If it is true, it assumes the array of tokens is allocated with
+  /// \c new[] and must be freed.
   void EnterTokenStream(const Token *Toks, unsigned NumToks,
                         bool DisableMacroExpansion, bool OwnsTokens);
 
-  /// RemoveTopOfLexerStack - Pop the current lexer/macro exp off the top of the
-  /// lexer stack.  This should only be used in situations where the current
-  /// state of the top-of-stack lexer is known.
+  /// \brief Pop the current lexer/macro exp off the top of the lexer stack.
+  ///
+  /// This should only be used in situations where the current state of the
+  /// top-of-stack lexer is known.
   void RemoveTopOfLexerStack();
 
-  /// EnableBacktrackAtThisPos - From the point that this method is called, and
-  /// until CommitBacktrackedTokens() or Backtrack() is called, the Preprocessor
+  /// From the point that this method is called, and until
+  /// CommitBacktrackedTokens() or Backtrack() is called, the Preprocessor
   /// keeps track of the lexed tokens so that a subsequent Backtrack() call will
   /// make the Preprocessor re-lex the same tokens.
   ///
@@ -708,18 +760,18 @@
   ///
   void EnableBacktrackAtThisPos();
 
-  /// CommitBacktrackedTokens - Disable the last EnableBacktrackAtThisPos call.
+  /// \brief Disable the last EnableBacktrackAtThisPos call.
   void CommitBacktrackedTokens();
 
-  /// Backtrack - Make Preprocessor re-lex the tokens that were lexed since
+  /// \brief Make Preprocessor re-lex the tokens that were lexed since
   /// EnableBacktrackAtThisPos() was previously called.
   void Backtrack();
 
-  /// isBacktrackEnabled - True if EnableBacktrackAtThisPos() was called and
+  /// \brief True if EnableBacktrackAtThisPos() was called and
   /// caching of tokens is on.
   bool isBacktrackEnabled() const { return !BacktrackPositions.empty(); }
 
-  /// Lex - Lex the next token for this preprocessor.
+  /// \brief Lex the next token for this preprocessor.
   void Lex(Token &Result);
 
   void LexAfterModuleImport(Token &Result);
@@ -743,17 +795,18 @@
                               const char *DiagnosticTag,
                               bool AllowMacroExpansion);
 
-  /// LexNonComment - Lex a token.  If it's a comment, keep lexing until we get
-  /// something not a comment.  This is useful in -E -C mode where comments
-  /// would foul up preprocessor directive handling.
+  /// \brief Lex a token.  If it's a comment, keep lexing until we get
+  /// something not a comment.
+  ///
+  /// This is useful in -E -C mode where comments would foul up preprocessor
+  /// directive handling.
   void LexNonComment(Token &Result) {
     do
       Lex(Result);
     while (Result.getKind() == tok::comment);
   }
 
-  /// LexUnexpandedToken - This is just like Lex, but this disables macro
-  /// expansion of identifier tokens.
+  /// \brief Just like Lex, but disables macro expansion of identifier tokens.
   void LexUnexpandedToken(Token &Result) {
     // Disable macro expansion.
     bool OldVal = DisableMacroExpansion;
@@ -765,24 +818,31 @@
     DisableMacroExpansion = OldVal;
   }
 
-  /// LexUnexpandedNonComment - Like LexNonComment, but this disables macro
-  /// expansion of identifier tokens.
+  /// \brief Like LexNonComment, but this disables macro expansion of
+  /// identifier tokens.
   void LexUnexpandedNonComment(Token &Result) {
     do
       LexUnexpandedToken(Result);
     while (Result.getKind() == tok::comment);
   }
 
+  /// \brief Parses a simple integer literal to get its numeric value.  Floating
+  /// point literals and user defined literals are rejected.  Used primarily to
+  /// handle pragmas that accept integer arguments.
+  bool parseSimpleIntegerLiteral(Token &Tok, uint64_t &Value);
+
   /// Disables macro expansion everywhere except for preprocessor directives.
   void SetMacroExpansionOnlyInDirectives() {
     DisableMacroExpansion = true;
     MacroExpansionInDirectivesOverride = true;
   }
 
-  /// LookAhead - This peeks ahead N tokens and returns that token without
-  /// consuming any tokens.  LookAhead(0) returns the next token that would be
-  /// returned by Lex(), LookAhead(1) returns the token after it, etc.  This
-  /// returns normal tokens after phase 5.  As such, it is equivalent to using
+  /// \brief Peeks ahead N tokens and returns that token without consuming any
+  /// tokens.
+  ///
+  /// LookAhead(0) returns the next token that would be returned by Lex(),
+  /// LookAhead(1) returns the token after it, etc.  This returns normal
+  /// tokens after phase 5.  As such, it is equivalent to using
   /// 'Lex', not 'LexUnexpandedToken'.
   const Token &LookAhead(unsigned N) {
     if (CachedLexPos + N < CachedTokens.size())
@@ -791,8 +851,9 @@
       return PeekAhead(N+1);
   }
 
-  /// RevertCachedTokens - When backtracking is enabled and tokens are cached,
+  /// \brief When backtracking is enabled and tokens are cached,
   /// this allows to revert a specific number of tokens.
+  ///
   /// Note that the number of tokens being reverted should be up to the last
   /// backtrack position, not more.
   void RevertCachedTokens(unsigned N) {
@@ -805,20 +866,21 @@
     CachedLexPos -= N;
   }
 
-  /// EnterToken - Enters a token in the token stream to be lexed next. If
-  /// BackTrack() is called afterwards, the token will remain at the insertion
-  /// point.
+  /// \brief Enters a token in the token stream to be lexed next.
+  ///
+  /// If BackTrack() is called afterwards, the token will remain at the
+  /// insertion point.
   void EnterToken(const Token &Tok) {
     EnterCachingLexMode();
     CachedTokens.insert(CachedTokens.begin()+CachedLexPos, Tok);
   }
 
-  /// AnnotateCachedTokens - We notify the Preprocessor that if it is caching
-  /// tokens (because backtrack is enabled) it should replace the most recent
-  /// cached tokens with the given annotation token. This function has no effect
-  /// if backtracking is not enabled.
+  /// We notify the Preprocessor that if it is caching tokens (because
+  /// backtrack is enabled) it should replace the most recent cached tokens
+  /// with the given annotation token. This function has no effect if
+  /// backtracking is not enabled.
   ///
-  /// Note that the use of this function is just for optimization; so that the
+  /// Note that the use of this function is just for optimization, so that the
   /// cached tokens doesn't get re-parsed and re-resolved after a backtrack is
   /// invoked.
   void AnnotateCachedTokens(const Token &Tok) {
@@ -848,7 +910,7 @@
       CachedTokens[CachedLexPos-1] = Tok;
   }
 
-  /// TypoCorrectToken - Update the current token to represent the provided
+  /// Update the current token to represent the provided
   /// identifier, in order to cache an action performed by typo correction.
   void TypoCorrectToken(const Token &Tok) {
     assert(Tok.getIdentifierInfo() && "Expected identifier token");
@@ -886,14 +948,16 @@
                               unsigned Line, unsigned Column);
 
   /// \brief Determine if we are performing code completion.
-  bool isCodeCompletionEnabled() const { return CodeCompletionFile != 0; }
+  bool isCodeCompletionEnabled() const { return CodeCompletionFile != nullptr; }
 
   /// \brief Returns the location of the code-completion point.
+  ///
   /// Returns an invalid location if code-completion is not enabled or the file
   /// containing the code-completion point has not been lexed yet.
   SourceLocation getCodeCompletionLoc() const { return CodeCompletionLoc; }
 
   /// \brief Returns the start location of the file of code-completion point.
+  ///
   /// Returns an invalid location if code-completion is not enabled or the file
   /// containing the code-completion point has not been lexed yet.
   SourceLocation getCodeCompletionFileLoc() const {
@@ -913,8 +977,9 @@
   }
 
   /// \brief The location of the currently-active \#pragma clang
-  /// arc_cf_code_audited begin.  Returns an invalid location if there
-  /// is no such pragma active.
+  /// arc_cf_code_audited begin.
+  ///
+  /// Returns an invalid location if there is no such pragma active.
   SourceLocation getPragmaARCCFCodeAuditedLoc() const {
     return PragmaARCCFCodeAuditedLoc;
   }
@@ -936,7 +1001,7 @@
     SkipMainFilePreamble.second = StartOfLine;
   }
 
-  /// Diag - Forwarding function for diagnostics.  This emits a diagnostic at
+  /// Forwarding function for diagnostics.  This emits a diagnostic at
   /// the specified Token's location, translating the token's start
   /// position in the current buffer into a SourcePosition object for rendering.
   DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const {
@@ -947,7 +1012,7 @@
     return Diags->Report(Tok.getLocation(), DiagID);
   }
 
-  /// getSpelling() - Return the 'spelling' of the token at the given
+  /// Return the 'spelling' of the token at the given
   /// location; does not go up to the spelling location or down to the
   /// expansion location.
   ///
@@ -956,25 +1021,28 @@
   /// \param invalid If non-null, will be set \c true if an error occurs.
   StringRef getSpelling(SourceLocation loc,
                         SmallVectorImpl<char> &buffer,
-                        bool *invalid = 0) const {
+                        bool *invalid = nullptr) const {
     return Lexer::getSpelling(loc, buffer, SourceMgr, LangOpts, invalid);
   }
 
-  /// getSpelling() - Return the 'spelling' of the Tok token.  The spelling of a
-  /// token is the characters used to represent the token in the source file
-  /// after trigraph expansion and escaped-newline folding.  In particular, this
-  /// wants to get the true, uncanonicalized, spelling of things like digraphs
-  /// UCNs, etc.
+  /// \brief Return the 'spelling' of the Tok token.
+  ///
+  /// The spelling of a token is the characters used to represent the token in
+  /// the source file after trigraph expansion and escaped-newline folding.  In
+  /// particular, this wants to get the true, uncanonicalized, spelling of
+  /// things like digraphs, UCNs, etc.
   ///
   /// \param Invalid If non-null, will be set \c true if an error occurs.
-  std::string getSpelling(const Token &Tok, bool *Invalid = 0) const {
+  std::string getSpelling(const Token &Tok, bool *Invalid = nullptr) const {
     return Lexer::getSpelling(Tok, SourceMgr, LangOpts, Invalid);
   }
 
-  /// getSpelling - This method is used to get the spelling of a token into a
-  /// preallocated buffer, instead of as an std::string.  The caller is required
-  /// to allocate enough space for the token, which is guaranteed to be at least
-  /// Tok.getLength() bytes long.  The length of the actual result is returned.
+  /// \brief Get the spelling of a token into a preallocated buffer, instead
+  /// of as an std::string.
+  ///
+  /// The caller is required to allocate enough space for the token, which is
+  /// guaranteed to be at least Tok.getLength() bytes long. The length of the
+  /// actual result is returned.
   ///
   /// Note that this method may do two possible things: it may either fill in
   /// the buffer specified with characters, or it may *change the input pointer*
@@ -982,16 +1050,17 @@
   /// copy).  The caller is not allowed to modify the returned buffer pointer
   /// if an internal buffer is returned.
   unsigned getSpelling(const Token &Tok, const char *&Buffer,
-                       bool *Invalid = 0) const {
+                       bool *Invalid = nullptr) const {
     return Lexer::getSpelling(Tok, Buffer, SourceMgr, LangOpts, Invalid);
   }
 
-  /// getSpelling - This method is used to get the spelling of a token into a
-  /// SmallVector. Note that the returned StringRef may not point to the
+  /// \brief Get the spelling of a token into a SmallVector.
+  ///
+  /// Note that the returned StringRef may not point to the
   /// supplied buffer if a copy can be avoided.
   StringRef getSpelling(const Token &Tok,
                         SmallVectorImpl<char> &Buffer,
-                        bool *Invalid = 0) const;
+                        bool *Invalid = nullptr) const;
 
   /// \brief Relex the token at the specified location.
   /// \returns true if there was a failure, false on success.
@@ -1000,10 +1069,11 @@
     return Lexer::getRawToken(Loc, Result, SourceMgr, LangOpts, IgnoreWhiteSpace);
   }
 
-  /// getSpellingOfSingleCharacterNumericConstant - Tok is a numeric constant
-  /// with length 1, return the character.
-  char getSpellingOfSingleCharacterNumericConstant(const Token &Tok,
-                                                   bool *Invalid = 0) const {
+  /// \brief Given a Token \p Tok that is a numeric constant with length 1,
+  /// return the character.
+  char
+  getSpellingOfSingleCharacterNumericConstant(const Token &Tok,
+                                              bool *Invalid = nullptr) const {
     assert(Tok.is(tok::numeric_constant) &&
            Tok.getLength() == 1 && "Called on unsupported token");
     assert(!Tok.needsCleaning() && "Token can't need cleaning with length 1");
@@ -1019,18 +1089,21 @@
 
   /// \brief Retrieve the name of the immediate macro expansion.
   ///
-  /// This routine starts from a source location, and finds the name of the macro
-  /// responsible for its immediate expansion. It looks through any intervening
-  /// macro argument expansions to compute this. It returns a StringRef which
-  /// refers to the SourceManager-owned buffer of the source where that macro
-  /// name is spelled. Thus, the result shouldn't out-live the SourceManager.
+  /// This routine starts from a source location, and finds the name of the
+  /// macro responsible for its immediate expansion. It looks through any
+  /// intervening macro argument expansions to compute this. It returns a
+  /// StringRef that refers to the SourceManager-owned buffer of the source
+  /// where that macro name is spelled. Thus, the result shouldn't out-live
+  /// the SourceManager.
   StringRef getImmediateMacroName(SourceLocation Loc) {
     return Lexer::getImmediateMacroName(Loc, SourceMgr, getLangOpts());
   }
 
-  /// CreateString - Plop the specified string into a scratch buffer and set the
-  /// specified token's location and length to it.  If specified, the source
-  /// location provides a location of the expansion point of the token.
+  /// \brief Plop the specified string into a scratch buffer and set the
+  /// specified token's location and length to it. 
+  ///
+  /// If specified, the source location provides a location of the expansion
+  /// point of the token.
   void CreateString(StringRef Str, Token &Tok,
                     SourceLocation ExpansionLocStart = SourceLocation(),
                     SourceLocation ExpansionLocEnd = SourceLocation());
@@ -1060,7 +1133,7 @@
   /// \param MacroBegin If non-null and function returns true, it is set to
   /// begin location of the macro.
   bool isAtStartOfMacroExpansion(SourceLocation loc,
-                                 SourceLocation *MacroBegin = 0) const {
+                                 SourceLocation *MacroBegin = nullptr) const {
     return Lexer::isAtStartOfMacroExpansion(loc, SourceMgr, LangOpts,
                                             MacroBegin);
   }
@@ -1071,27 +1144,26 @@
   /// \param MacroEnd If non-null and function returns true, it is set to
   /// end location of the macro.
   bool isAtEndOfMacroExpansion(SourceLocation loc,
-                               SourceLocation *MacroEnd = 0) const {
+                               SourceLocation *MacroEnd = nullptr) const {
     return Lexer::isAtEndOfMacroExpansion(loc, SourceMgr, LangOpts, MacroEnd);
   }
 
-  /// DumpToken - Print the token to stderr, used for debugging.
-  ///
+  /// \brief Print the token to stderr, used for debugging.
   void DumpToken(const Token &Tok, bool DumpFlags = false) const;
   void DumpLocation(SourceLocation Loc) const;
   void DumpMacro(const MacroInfo &MI) const;
 
-  /// AdvanceToTokenCharacter - Given a location that specifies the start of a
+  /// \brief Given a location that specifies the start of a
   /// token, return a new location that specifies a character within the token.
   SourceLocation AdvanceToTokenCharacter(SourceLocation TokStart,
                                          unsigned Char) const {
     return Lexer::AdvanceToTokenCharacter(TokStart, Char, SourceMgr, LangOpts);
   }
 
-  /// IncrementPasteCounter - Increment the counters for the number of token
-  /// paste operations performed.  If fast was specified, this is a 'fast paste'
-  /// case we handled.
+  /// \brief Increment the counters for the number of token paste operations
+  /// performed.
   ///
+  /// If fast was specified, this is a 'fast paste' case we handled.
   void IncrementPasteCounter(bool isFast) {
     if (isFast)
       ++NumFastTokenPaste;
@@ -1103,16 +1175,16 @@
 
   size_t getTotalMemory() const;
 
-  /// HandleMicrosoftCommentPaste - When the macro expander pastes together a
-  /// comment (/##/) in microsoft mode, this method handles updating the current
-  /// state, returning the token on the next source line.
+  /// When the macro expander pastes together a comment (/##/) in Microsoft
+  /// mode, this method handles updating the current state, returning the
+  /// token on the next source line.
   void HandleMicrosoftCommentPaste(Token &Tok);
 
   //===--------------------------------------------------------------------===//
   // Preprocessor callback methods.  These are invoked by a lexer as various
   // directives and events are found.
 
-  /// LookUpIdentifierInfo - Given a tok::raw_identifier token, look up the
+  /// Given a tok::raw_identifier token, look up the
   /// identifier information for the token and install it into the token,
   /// updating the token kind accordingly.
   IdentifierInfo *LookUpIdentifierInfo(Token &Identifier) const;
@@ -1122,14 +1194,13 @@
 
 public:
 
-  // SetPoisonReason - Call this function to indicate the reason for
-  // poisoning an identifier. If that identifier is accessed while
-  // poisoned, then this reason will be used instead of the default
-  // "poisoned" diagnostic.
+  /// \brief Specifies the reason for poisoning an identifier.
+  ///
+  /// If that identifier is accessed while poisoned, then this reason will be
+  /// used instead of the default "poisoned" diagnostic.
   void SetPoisonReason(IdentifierInfo *II, unsigned DiagID);
 
-  // HandlePoisonedIdentifier - Display reason for poisoned
-  // identifier.
+  /// \brief Display reason for poisoned identifier.
   void HandlePoisonedIdentifier(Token & Tok);
 
   void MaybeHandlePoisonedIdentifier(Token & Identifier) {
@@ -1155,45 +1226,53 @@
   IdentifierInfo *Ident__abnormal_termination,
                  *Ident___abnormal_termination,
                  *Ident_AbnormalTermination;
+
+  const char *getCurLexerEndPos();
+
 public:
   void PoisonSEHIdentifiers(bool Poison = true); // Borland
 
-  /// HandleIdentifier - This callback is invoked when the lexer reads an
-  /// identifier and has filled in the tokens IdentifierInfo member.  This
-  /// callback potentially macro expands it or turns it into a named token (like
-  /// 'for').
+  /// \brief Callback invoked when the lexer reads an identifier and has
+  /// filled in the tokens IdentifierInfo member. 
+  ///
+  /// This callback potentially macro expands it or turns it into a named
+  /// token (like 'for').
   ///
   /// \returns true if we actually computed a token, false if we need to
   /// lex again.
   bool HandleIdentifier(Token &Identifier);
 
 
-  /// HandleEndOfFile - This callback is invoked when the lexer hits the end of
-  /// the current file.  This either returns the EOF token and returns true, or
+  /// \brief Callback invoked when the lexer hits the end of the current file.
+  ///
+  /// This either returns the EOF token and returns true, or
   /// pops a level off the include stack and returns false, at which point the
   /// client should call lex again.
   bool HandleEndOfFile(Token &Result, bool isEndOfMacro = false);
 
-  /// HandleEndOfTokenLexer - This callback is invoked when the current
-  /// TokenLexer hits the end of its token stream.
+  /// \brief Callback invoked when the current TokenLexer hits the end of its
+  /// token stream.
   bool HandleEndOfTokenLexer(Token &Result);
 
-  /// HandleDirective - This callback is invoked when the lexer sees a # token
-  /// at the start of a line.  This consumes the directive, modifies the
-  /// lexer/preprocessor state, and advances the lexer(s) so that the next token
-  /// read is the correct one.
+  /// \brief Callback invoked when the lexer sees a # token at the start of a
+  /// line.
+  ///
+  /// This consumes the directive, modifies the lexer/preprocessor state, and
+  /// advances the lexer(s) so that the next token read is the correct one.
   void HandleDirective(Token &Result);
 
-  /// CheckEndOfDirective - Ensure that the next token is a tok::eod token.  If
-  /// not, emit a diagnostic and consume up until the eod.  If EnableMacros is
-  /// true, then we consider macros that expand to zero tokens as being ok.
+  /// \brief Ensure that the next token is a tok::eod token.
+  ///
+  /// If not, emit a diagnostic and consume up until the eod.
+  /// If \p EnableMacros is true, then we consider macros that expand to zero
+  /// tokens as being ok.
   void CheckEndOfDirective(const char *Directive, bool EnableMacros = false);
 
-  /// DiscardUntilEndOfDirective - Read and discard all tokens remaining on the
-  /// current line until the tok::eod token is found.
+  /// \brief Read and discard all tokens remaining on the current line until
+  /// the tok::eod token is found.
   void DiscardUntilEndOfDirective();
 
-  /// SawDateOrTime - This returns true if the preprocessor has seen a use of
+  /// \brief Returns true if the preprocessor has seen a use of
   /// __DATE__ or __TIME__ in the file so far.
   bool SawDateOrTime() const {
     return DATELoc != SourceLocation() || TIMELoc != SourceLocation();
@@ -1234,17 +1313,20 @@
                               ModuleMap::KnownHeader *SuggestedModule,
                               bool SkipCache = false);
 
-  /// GetCurLookup - The DirectoryLookup structure used to find the current
-  /// FileEntry, if CurLexer is non-null and if applicable.  This allows us to
-  /// implement \#include_next and find directory-specific properties.
+  /// \brief Get the DirectoryLookup structure used to find the current
+  /// FileEntry, if CurLexer is non-null and if applicable. 
+  ///
+  /// This allows us to implement \#include_next and find directory-specific
+  /// properties.
   const DirectoryLookup *GetCurDirLookup() { return CurDirLookup; }
 
   /// \brief Return true if we're in the top-level file, not in a \#include.
   bool isInPrimaryFile() const;
 
-  /// ConcatenateIncludeName - Handle cases where the \#include name is expanded
-  /// from a macro as multiple tokens, which need to be glued together.  This
-  /// occurs for code like:
+  /// \brief Handle cases where the \#include name is expanded
+  /// from a macro as multiple tokens, which need to be glued together. 
+  ///
+  /// This occurs for code like:
   /// \code
   ///    \#define FOO <x/y.h>
   ///    \#include FOO
@@ -1257,28 +1339,28 @@
   bool ConcatenateIncludeName(SmallString<128> &FilenameBuffer,
                               SourceLocation &End);
 
-  /// LexOnOffSwitch - Lex an on-off-switch (C99 6.10.6p2) and verify that it is
+  /// \brief Lex an on-off-switch (C99 6.10.6p2) and verify that it is
   /// followed by EOD.  Return true if the token is not a valid on-off-switch.
   bool LexOnOffSwitch(tok::OnOffSwitch &OOS);
 
+  bool CheckMacroName(Token &MacroNameTok, char isDefineUndef);
+
 private:
 
   void PushIncludeMacroStack() {
-    IncludeMacroStack.push_back(IncludeStackInfo(CurLexerKind,
-                                                 CurLexer.take(),
-                                                 CurPTHLexer.take(),
-                                                 CurPPLexer,
-                                                 CurTokenLexer.take(),
-                                                 CurDirLookup));
-    CurPPLexer = 0;
+    IncludeMacroStack.push_back(IncludeStackInfo(
+        CurLexerKind, CurSubmodule, std::move(CurLexer), std::move(CurPTHLexer),
+        CurPPLexer, std::move(CurTokenLexer), CurDirLookup));
+    CurPPLexer = nullptr;
   }
 
   void PopIncludeMacroStack() {
-    CurLexer.reset(IncludeMacroStack.back().TheLexer);
-    CurPTHLexer.reset(IncludeMacroStack.back().ThePTHLexer);
+    CurLexer = std::move(IncludeMacroStack.back().TheLexer);
+    CurPTHLexer = std::move(IncludeMacroStack.back().ThePTHLexer);
     CurPPLexer = IncludeMacroStack.back().ThePPLexer;
-    CurTokenLexer.reset(IncludeMacroStack.back().TheTokenLexer);
+    CurTokenLexer = std::move(IncludeMacroStack.back().TheTokenLexer);
     CurDirLookup  = IncludeMacroStack.back().TheDirLookup;
+    CurSubmodule = IncludeMacroStack.back().TheSubmodule;
     CurLexerKind = IncludeMacroStack.back().CurLexerKind;
     IncludeMacroStack.pop_back();
   }
@@ -1300,15 +1382,16 @@
   /// This memory will  be reused for allocating new MacroInfo objects.
   void ReleaseMacroInfo(MacroInfo* MI);
 
-  /// ReadMacroName - Lex and validate a macro name, which occurs after a
-  /// \#define or \#undef.  This emits a diagnostic, sets the token kind to eod,
+  /// \brief Lex and validate a macro name, which occurs after a
+  /// \#define or \#undef. 
+  ///
+  /// This emits a diagnostic, sets the token kind to eod,
   /// and discards the rest of the macro line if the macro name is invalid.
   void ReadMacroName(Token &MacroNameTok, char isDefineUndef = 0);
 
-  /// ReadMacroDefinitionArgList - The ( starting an argument list of a macro
-  /// definition has just been read.  Lex the rest of the arguments and the
-  /// closing ), updating MI with what we learn and saving in LastTok the
-  /// last token read.
+  /// The ( starting an argument list of a macro definition has just been read.
+  /// Lex the rest of the arguments and the closing ), updating \p MI with
+  /// what we learn and saving in \p LastTok the last token read.
   /// Return true if an error occurs parsing the arg list.
   bool ReadMacroDefinitionArgList(MacroInfo *MI, Token& LastTok);
 
@@ -1327,21 +1410,22 @@
   /// \brief A fast PTH version of SkipExcludedConditionalBlock.
   void PTHSkipExcludedConditionalBlock();
 
-  /// EvaluateDirectiveExpression - Evaluate an integer constant expression that
-  /// may occur after a #if or #elif directive and return it as a bool.  If the
-  /// expression is equivalent to "!defined(X)" return X in IfNDefMacro.
+  /// \brief Evaluate an integer constant expression that may occur after a
+  /// \#if or \#elif directive and return it as a bool.
+  ///
+  /// If the expression is equivalent to "!defined(X)" return X in IfNDefMacro.
   bool EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro);
 
-  /// RegisterBuiltinPragmas - Install the standard preprocessor pragmas:
+  /// \brief Install the standard preprocessor pragmas:
   /// \#pragma GCC poison/system_header/dependency and \#pragma once.
   void RegisterBuiltinPragmas();
 
   /// \brief Register builtin macros such as __LINE__ with the identifier table.
   void RegisterBuiltinMacros();
 
-  /// HandleMacroExpandedIdentifier - If an identifier token is read that is to
-  /// be expanded as a macro, handle it and return the next token as 'Tok'.  If
-  /// we lexed a token, return true; otherwise the caller should lex again.
+  /// If an identifier token is read that is to be expanded as a macro, handle
+  /// it and return the next token as 'Tok'.  If we lexed a token, return true;
+  /// otherwise the caller should lex again.
   bool HandleMacroExpandedIdentifier(Token &Tok, MacroDirective *MD);
 
   /// \brief Cache macro expanded tokens for TokenLexers.
@@ -1354,52 +1438,51 @@
   void removeCachedMacroExpandedTokensOfLastLexer();
   friend void TokenLexer::ExpandFunctionArguments();
 
-  /// isNextPPTokenLParen - Determine whether the next preprocessor token to be
+  /// Determine whether the next preprocessor token to be
   /// lexed is a '('.  If so, consume the token and return true, if not, this
   /// method should have no observable side-effect on the lexed tokens.
   bool isNextPPTokenLParen();
 
-  /// ReadFunctionLikeMacroArgs - After reading "MACRO(", this method is
-  /// invoked to read all of the formal arguments specified for the macro
-  /// invocation.  This returns null on error.
+  /// After reading "MACRO(", this method is invoked to read all of the formal
+  /// arguments specified for the macro invocation.  Returns null on error.
   MacroArgs *ReadFunctionLikeMacroArgs(Token &MacroName, MacroInfo *MI,
                                        SourceLocation &ExpansionEnd);
 
-  /// ExpandBuiltinMacro - If an identifier token is read that is to be expanded
+  /// \brief If an identifier token is read that is to be expanded
   /// as a builtin macro, handle it and return the next token as 'Tok'.
   void ExpandBuiltinMacro(Token &Tok);
 
-  /// Handle_Pragma - Read a _Pragma directive, slice it up, process it, then
-  /// return the first token after the directive.  The _Pragma token has just
-  /// been read into 'Tok'.
+  /// \brief Read a \c _Pragma directive, slice it up, process it, then
+  /// return the first token after the directive.
+  /// This assumes that the \c _Pragma token has just been read into \p Tok.
   void Handle_Pragma(Token &Tok);
 
-  /// HandleMicrosoft__pragma - Like Handle_Pragma except the pragma text
-  /// is not enclosed within a string literal.
+  /// \brief Like Handle_Pragma except the pragma text is not enclosed within
+  /// a string literal.
   void HandleMicrosoft__pragma(Token &Tok);
 
-  /// EnterSourceFileWithLexer - Add a lexer to the top of the include stack and
+  /// \brief Add a lexer to the top of the include stack and
   /// start lexing tokens from it instead of the current buffer.
   void EnterSourceFileWithLexer(Lexer *TheLexer, const DirectoryLookup *Dir);
 
-  /// EnterSourceFileWithPTH - Add a lexer to the top of the include stack and
+  /// \brief Add a lexer to the top of the include stack and
   /// start getting tokens from it using the PTH cache.
   void EnterSourceFileWithPTH(PTHLexer *PL, const DirectoryLookup *Dir);
 
-  /// \brief Set the file ID for the preprocessor predefines.
+  /// \brief Set the FileID for the preprocessor predefines.
   void setPredefinesFileID(FileID FID) {
     assert(PredefinesFileID.isInvalid() && "PredefinesFileID already set!");
     PredefinesFileID = FID;
   }
 
-  /// IsFileLexer - Returns true if we are lexing from a file and not a
-  ///  pragma or a macro.
+  /// \brief Returns true if we are lexing from a file and not a
+  /// pragma or a macro.
   static bool IsFileLexer(const Lexer* L, const PreprocessorLexer* P) {
-    return L ? !L->isPragmaLexer() : P != 0;
+    return L ? !L->isPragmaLexer() : P != nullptr;
   }
 
   static bool IsFileLexer(const IncludeStackInfo& I) {
-    return IsFileLexer(I.TheLexer, I.ThePPLexer);
+    return IsFileLexer(I.TheLexer.get(), I.ThePPLexer);
   }
 
   bool IsFileLexer() const {
@@ -1437,7 +1520,7 @@
   // File inclusion.
   void HandleIncludeDirective(SourceLocation HashLoc,
                               Token &Tok,
-                              const DirectoryLookup *LookupFrom = 0,
+                              const DirectoryLookup *LookupFrom = nullptr,
                               bool isImport = false);
   void HandleIncludeNextDirective(SourceLocation HashLoc, Token &Tok);
   void HandleIncludeMacrosDirective(SourceLocation HashLoc, Token &Tok);
@@ -1449,25 +1532,6 @@
   /// points to.
   Module *getModuleForLocation(SourceLocation FilenameLoc);
 
-  /// \brief Verify that a private header is included only from within its
-  /// module.
-  bool violatesPrivateInclude(Module *RequestingModule,
-                              const FileEntry *IncFileEnt,
-                              ModuleMap::ModuleHeaderRole Role,
-                              Module *RequestedModule);
-
-  /// \brief Verify that a module includes headers only from modules that it
-  /// has declared that it uses.
-  bool violatesUseDeclarations(Module *RequestingModule,
-                               Module *RequestedModule);
-
-  /// \brief Verify that it is legal for the source file that \p FilenameLoc
-  /// points to to include the file \p Filename.
-  ///
-  /// Tries to reuse \p IncFileEnt.
-  void verifyModuleInclude(SourceLocation FilenameLoc, StringRef Filename,
-                           const FileEntry *IncFileEnt);
-
   // Macro handling.
   void HandleDefineDirective(Token &Tok, bool ImmediatelyAfterTopLevelIfndef);
   void HandleUndefDirective(Token &Tok);
diff --git a/include/clang/Lex/PreprocessorLexer.h b/include/clang/Lex/PreprocessorLexer.h
index 27a8df4..ed226ae 100644
--- a/include/clang/Lex/PreprocessorLexer.h
+++ b/include/clang/Lex/PreprocessorLexer.h
@@ -76,7 +76,7 @@
   PreprocessorLexer(Preprocessor *pp, FileID fid);
 
   PreprocessorLexer()
-    : PP(0), InitialNumSLocEntries(0),
+    : PP(nullptr), InitialNumSLocEntries(0),
       ParsingPreprocessorDirective(false),
       ParsingFilename(false),
       LexingRawMode(false) {}
diff --git a/include/clang/Lex/PreprocessorOptions.h b/include/clang/Lex/PreprocessorOptions.h
index eba2a13..135c87f 100644
--- a/include/clang/Lex/PreprocessorOptions.h
+++ b/include/clang/Lex/PreprocessorOptions.h
@@ -97,14 +97,13 @@
   /// the system (the first part of each pair) and gives them the
   /// contents of other files on the system (the second part of each
   /// pair).
-  std::vector<std::pair<std::string, std::string> >  RemappedFiles;
+  std::vector<std::pair<std::string, std::string>> RemappedFiles;
 
   /// \brief The set of file-to-buffer remappings, which take existing files
   /// on the system (the first part of each pair) and gives them the contents
   /// of the specified memory buffer (the second part of each pair).
-  std::vector<std::pair<std::string, const llvm::MemoryBuffer *> > 
-    RemappedFileBuffers;
-  
+  std::vector<std::pair<std::string, llvm::MemoryBuffer *>> RemappedFileBuffers;
+
   /// \brief Whether the compiler instance should retain (i.e., not free)
   /// the buffers associated with remapped files.
   ///
@@ -140,40 +139,6 @@
   /// build it again.
   IntrusiveRefCntPtr<FailedModulesSet> FailedModules;
 
-  typedef std::vector<std::pair<std::string, std::string> >::iterator
-    remapped_file_iterator;
-  typedef std::vector<std::pair<std::string, std::string> >::const_iterator
-    const_remapped_file_iterator;
-  remapped_file_iterator remapped_file_begin() { 
-    return RemappedFiles.begin();
-  }
-  const_remapped_file_iterator remapped_file_begin() const {
-    return RemappedFiles.begin();
-  }
-  remapped_file_iterator remapped_file_end() { 
-    return RemappedFiles.end();
-  }
-  const_remapped_file_iterator remapped_file_end() const { 
-    return RemappedFiles.end();
-  }
-
-  typedef std::vector<std::pair<std::string, const llvm::MemoryBuffer *> >::
-                                  iterator remapped_file_buffer_iterator;
-  typedef std::vector<std::pair<std::string, const llvm::MemoryBuffer *> >::
-                            const_iterator const_remapped_file_buffer_iterator;
-  remapped_file_buffer_iterator remapped_file_buffer_begin() {
-    return RemappedFileBuffers.begin();
-  }
-  const_remapped_file_buffer_iterator remapped_file_buffer_begin() const {
-    return RemappedFileBuffers.begin();
-  }
-  remapped_file_buffer_iterator remapped_file_buffer_end() {
-    return RemappedFileBuffers.end();
-  }
-  const_remapped_file_buffer_iterator remapped_file_buffer_end() const {
-    return RemappedFileBuffers.end();
-  }
-  
 public:
   PreprocessorOptions() : UsePredefines(true), DetailedRecord(false),
                           DisablePCHValidation(false),
@@ -193,20 +158,11 @@
   void addRemappedFile(StringRef From, StringRef To) {
     RemappedFiles.push_back(std::make_pair(From, To));
   }
-  
-  remapped_file_iterator eraseRemappedFile(remapped_file_iterator Remapped) {
-    return RemappedFiles.erase(Remapped);
-  }
-  
-  void addRemappedFile(StringRef From, const llvm::MemoryBuffer * To) {
+
+  void addRemappedFile(StringRef From, llvm::MemoryBuffer *To) {
     RemappedFileBuffers.push_back(std::make_pair(From, To));
   }
-  
-  remapped_file_buffer_iterator
-  eraseRemappedFile(remapped_file_buffer_iterator Remapped) {
-    return RemappedFileBuffers.erase(Remapped);
-  }
-  
+
   void clearRemappedFiles() {
     RemappedFiles.clear();
     RemappedFileBuffers.clear();
diff --git a/include/clang/Lex/Token.h b/include/clang/Lex/Token.h
index 4f6391d..c8b77d1 100644
--- a/include/clang/Lex/Token.h
+++ b/include/clang/Lex/Token.h
@@ -18,6 +18,7 @@
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/TemplateKinds.h"
 #include "clang/Basic/TokenKinds.h"
+#include "llvm/ADT/StringRef.h"
 #include <cstdlib>
 
 namespace clang {
@@ -62,8 +63,7 @@
   void *PtrData;
 
   /// Kind - The actual flavor of token this is.
-  ///
-  unsigned short Kind;
+  tok::TokenKind Kind;
 
   /// Flags - Bits we track about this token, members of the TokenFlags enum.
   unsigned char Flags;
@@ -83,13 +83,13 @@
     IgnoredComma = 0x80    // This comma is not a macro argument separator (MS).
   };
 
-  tok::TokenKind getKind() const { return (tok::TokenKind)Kind; }
+  tok::TokenKind getKind() const { return Kind; }
   void setKind(tok::TokenKind K) { Kind = K; }
 
   /// is/isNot - Predicates to check if this token is a specific kind, as in
   /// "if (Tok.is(tok::l_brace)) {...}".
-  bool is(tok::TokenKind K) const { return Kind == (unsigned) K; }
-  bool isNot(tok::TokenKind K) const { return Kind != (unsigned) K; }
+  bool is(tok::TokenKind K) const { return Kind == K; }
+  bool isNot(tok::TokenKind K) const { return Kind != K; }
 
   /// \brief Return true if this is a raw identifier (when lexing
   /// in raw mode) or a non-keyword identifier (when lexing in non-raw mode).
@@ -145,15 +145,13 @@
     setAnnotationEndLoc(R.getEnd());
   }
 
-  const char *getName() const {
-    return tok::getTokenName( (tok::TokenKind) Kind);
-  }
+  const char *getName() const { return tok::getTokenName(Kind); }
 
   /// \brief Reset all flags to cleared.
   void startToken() {
     Kind = tok::unknown;
     Flags = 0;
-    PtrData = 0;
+    PtrData = nullptr;
     UintData = 0;
     Loc = SourceLocation();
   }
@@ -163,19 +161,19 @@
            "getIdentifierInfo() on a tok::raw_identifier token!");
     assert(!isAnnotation() &&
            "getIdentifierInfo() on an annotation token!");
-    if (isLiteral()) return 0;
+    if (isLiteral()) return nullptr;
     return (IdentifierInfo*) PtrData;
   }
   void setIdentifierInfo(IdentifierInfo *II) {
     PtrData = (void*) II;
   }
 
-  /// getRawIdentifierData - For a raw identifier token (i.e., an identifier
-  /// lexed in raw mode), returns a pointer to the start of it in the text
-  /// buffer if known, null otherwise.
-  const char *getRawIdentifierData() const {
+  /// getRawIdentifier - For a raw identifier token (i.e., an identifier
+  /// lexed in raw mode), returns a reference to the text substring in the
+  /// buffer if known.
+  StringRef getRawIdentifier() const {
     assert(is(tok::raw_identifier));
-    return reinterpret_cast<const char*>(PtrData);
+    return StringRef(reinterpret_cast<const char *>(PtrData), getLength());
   }
   void setRawIdentifierData(const char *Ptr) {
     assert(is(tok::raw_identifier));
diff --git a/include/clang/Lex/TokenLexer.h b/include/clang/Lex/TokenLexer.h
index 7c8cfd0..a873a2e 100644
--- a/include/clang/Lex/TokenLexer.h
+++ b/include/clang/Lex/TokenLexer.h
@@ -81,6 +81,14 @@
   bool AtStartOfLine : 1;
   bool HasLeadingSpace : 1;
 
+  // NextTokGetsSpace - When this is true, the next token appended to the
+  // output list during function argument expansion will get a leading space,
+  // regardless of whether it had one to begin with or not. This is used for
+  // placemarker support. If still true after function argument expansion, the
+  // leading space will be applied to the first token following the macro
+  // expansion.
+  bool NextTokGetsSpace : 1;
+
   /// OwnsTokens - This is true if this TokenLexer allocated the Tokens
   /// array, and thus needs to free it when destroyed.  For simple object-like
   /// macros (for example) we just point into the token buffer of the macro
@@ -100,7 +108,7 @@
   /// identifier for an object-like macro.
   TokenLexer(Token &Tok, SourceLocation ILEnd, MacroInfo *MI,
              MacroArgs *ActualArgs, Preprocessor &pp)
-    : Macro(0), ActualArgs(0), PP(pp), OwnsTokens(false) {
+    : Macro(nullptr), ActualArgs(nullptr), PP(pp), OwnsTokens(false) {
     Init(Tok, ILEnd, MI, ActualArgs);
   }
 
@@ -116,7 +124,7 @@
   /// the token lexer is empty.
   TokenLexer(const Token *TokArray, unsigned NumToks, bool DisableExpansion,
              bool ownsTokens, Preprocessor &pp)
-    : Macro(0), ActualArgs(0), PP(pp), OwnsTokens(false) {
+    : Macro(nullptr), ActualArgs(nullptr), PP(pp), OwnsTokens(false) {
     Init(TokArray, NumToks, DisableExpansion, ownsTokens);
   }
 
@@ -182,6 +190,13 @@
   void updateLocForMacroArgTokens(SourceLocation ArgIdSpellLoc,
                                   Token *begin_tokens, Token *end_tokens);
 
+  /// Remove comma ahead of __VA_ARGS__, if present, according to compiler
+  /// dialect settings.  Returns true if the comma is removed.
+  bool MaybeRemoveCommaBeforeVaArgs(SmallVectorImpl<Token> &ResultToks,
+                                    bool HasPasteOperator,
+                                    MacroInfo *Macro, unsigned MacroArgNo,
+                                    Preprocessor &PP);
+
   void PropagateLineStartLeadingSpaceInfo(Token &Result);
 };
 
diff --git a/include/clang/Makefile b/include/clang/Makefile
index 5f2077d..5ba2dd2 100644
--- a/include/clang/Makefile
+++ b/include/clang/Makefile
@@ -1,5 +1,5 @@
 CLANG_LEVEL := ../..
-DIRS := AST Basic Driver Lex Parse Sema Serialization
+DIRS := AST Basic Driver Parse Sema Serialization
 
 include $(CLANG_LEVEL)/Makefile
 
diff --git a/include/clang/Parse/CMakeLists.txt b/include/clang/Parse/CMakeLists.txt
index ed80c18..ec75f7b 100644
--- a/include/clang/Parse/CMakeLists.txt
+++ b/include/clang/Parse/CMakeLists.txt
@@ -1,14 +1,4 @@
-clang_tablegen(AttrIdentifierArg.inc -gen-clang-attr-identifier-arg-list
+clang_tablegen(AttrParserStringSwitches.inc -gen-clang-attr-parser-string-switches
   -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
   SOURCE ../Basic/Attr.td
-  TARGET ClangAttrIdentifierArg)
-
-clang_tablegen(AttrTypeArg.inc -gen-clang-attr-type-arg-list
-  -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
-  SOURCE ../Basic/Attr.td
-  TARGET ClangAttrTypeArg)
-
-clang_tablegen(AttrLateParsed.inc -gen-clang-attr-late-parsed-list
-  -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
-  SOURCE ../Basic/Attr.td
-  TARGET ClangAttrLateParsed)
+  TARGET ClangAttrParserStringSwitches)
diff --git a/include/clang/Parse/Makefile b/include/clang/Parse/Makefile
index 00d41fa..c477019 100644
--- a/include/clang/Parse/Makefile
+++ b/include/clang/Parse/Makefile
@@ -1,25 +1,13 @@
 CLANG_LEVEL := ../../..
 TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic
-BUILT_SOURCES = AttrIdentifierArg.inc AttrLateParsed.inc AttrTypeArg.inc
+BUILT_SOURCES = AttrParserStringSwitches.inc
 
 TABLEGEN_INC_FILES_COMMON = 1
 
 include $(CLANG_LEVEL)/Makefile
 
-$(ObjDir)/AttrIdentifierArg.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
+$(ObjDir)/AttrParserStringSwitches.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
                                    $(ObjDir)/.dir
-	$(Echo) "Building Clang attribute identifier argument table with tblgen"
-	$(Verb) $(ClangTableGen) -gen-clang-attr-identifier-arg-list -o $(call SYSPATH, $@) \
-		-I $(PROJ_SRC_DIR)/../../ $<
-
-$(ObjDir)/AttrTypeArg.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
-                                   $(ObjDir)/.dir
-	$(Echo) "Building Clang attribute type argument table with tblgen"
-	$(Verb) $(ClangTableGen) -gen-clang-attr-type-arg-list -o $(call SYSPATH, $@) \
-		-I $(PROJ_SRC_DIR)/../../ $<
-
-$(ObjDir)/AttrLateParsed.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
-                                   $(ObjDir)/.dir
-	$(Echo) "Building Clang attribute late-parsed table with tblgen"
-	$(Verb) $(ClangTableGen) -gen-clang-attr-late-parsed-list -o $(call SYSPATH, $@) \
+	$(Echo) "Building Clang parser-related attribute string switches"
+	$(Verb) $(ClangTableGen) -gen-clang-attr-parser-string-switches -o $(call SYSPATH, $@) \
 		-I $(PROJ_SRC_DIR)/../../ $<
diff --git a/include/clang/Parse/ParseAST.h b/include/clang/Parse/ParseAST.h
index 2405a0c..21f9701 100644
--- a/include/clang/Parse/ParseAST.h
+++ b/include/clang/Parse/ParseAST.h
@@ -36,7 +36,7 @@
   void ParseAST(Preprocessor &pp, ASTConsumer *C,
                 ASTContext &Ctx, bool PrintStats = false,
                 TranslationUnitKind TUKind = TU_Complete,
-                CodeCompleteConsumer *CompletionConsumer = 0,
+                CodeCompleteConsumer *CompletionConsumer = nullptr,
                 bool SkipFunctionBodies = false);
 
   /// \brief Parse the main file known to the preprocessor, producing an 
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index 5fb4f7d..c58c41a 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -20,12 +20,13 @@
 #include "clang/Lex/CodeCompletionHandler.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/LoopHint.h"
 #include "clang/Sema/Sema.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/PrettyStackTrace.h"
 #include "llvm/Support/SaveAndRestore.h"
+#include <memory>
 #include <stack>
 
 namespace clang {
@@ -40,7 +41,6 @@
   class ParsingDeclSpec;
   class ParsingDeclarator;
   class ParsingFieldDeclarator;
-  class PragmaUnusedHandler;
   class ColonProtectionRAIIObject;
   class InMessageExpressionRAIIObject;
   class PoisonSEHIdentifiersRAIIObject;
@@ -52,7 +52,6 @@
 /// been read.
 ///
 class Parser : public CodeCompletionHandler {
-  friend class PragmaUnusedHandler;
   friend class ColonProtectionRAIIObject;
   friend class InMessageExpressionRAIIObject;
   friend class PoisonSEHIdentifiersRAIIObject;
@@ -73,7 +72,7 @@
   SourceLocation PrevTokLocation;
 
   unsigned short ParenCount, BracketCount, BraceCount;
-  
+
   /// Actions - These are the callbacks we invoke as we parse various constructs
   /// in the file.
   Sema &Actions;
@@ -136,24 +135,37 @@
   mutable IdentifierInfo *Ident_final;
   mutable IdentifierInfo *Ident_override;
 
-  // C++ type trait keywords that have can be reverted to identifiers and
-  // still used as type traits.
-  llvm::SmallDenseMap<IdentifierInfo *, tok::TokenKind> RevertableTypeTraits;
+  // Some token kinds such as C++ type traits can be reverted to identifiers and
+  // still get used as keywords depending on context.
+  llvm::SmallDenseMap<const IdentifierInfo *, tok::TokenKind>
+  ContextualKeywords;
 
-  OwningPtr<PragmaHandler> AlignHandler;
-  OwningPtr<PragmaHandler> GCCVisibilityHandler;
-  OwningPtr<PragmaHandler> OptionsHandler;
-  OwningPtr<PragmaHandler> PackHandler;
-  OwningPtr<PragmaHandler> MSStructHandler;
-  OwningPtr<PragmaHandler> UnusedHandler;
-  OwningPtr<PragmaHandler> WeakHandler;
-  OwningPtr<PragmaHandler> RedefineExtnameHandler;
-  OwningPtr<PragmaHandler> FPContractHandler;
-  OwningPtr<PragmaHandler> OpenCLExtensionHandler;
-  OwningPtr<CommentHandler> CommentSemaHandler;
-  OwningPtr<PragmaHandler> OpenMPHandler;
-  OwningPtr<PragmaHandler> MSCommentHandler;
-  OwningPtr<PragmaHandler> MSDetectMismatchHandler;
+  std::unique_ptr<PragmaHandler> AlignHandler;
+  std::unique_ptr<PragmaHandler> GCCVisibilityHandler;
+  std::unique_ptr<PragmaHandler> OptionsHandler;
+  std::unique_ptr<PragmaHandler> PackHandler;
+  std::unique_ptr<PragmaHandler> MSStructHandler;
+  std::unique_ptr<PragmaHandler> UnusedHandler;
+  std::unique_ptr<PragmaHandler> WeakHandler;
+  std::unique_ptr<PragmaHandler> RedefineExtnameHandler;
+  std::unique_ptr<PragmaHandler> FPContractHandler;
+  std::unique_ptr<PragmaHandler> OpenCLExtensionHandler;
+  std::unique_ptr<PragmaHandler> OpenMPHandler;
+  std::unique_ptr<PragmaHandler> MSCommentHandler;
+  std::unique_ptr<PragmaHandler> MSDetectMismatchHandler;
+  std::unique_ptr<PragmaHandler> MSPointersToMembers;
+  std::unique_ptr<PragmaHandler> MSVtorDisp;
+  std::unique_ptr<PragmaHandler> MSInitSeg;
+  std::unique_ptr<PragmaHandler> MSDataSeg;
+  std::unique_ptr<PragmaHandler> MSBSSSeg;
+  std::unique_ptr<PragmaHandler> MSConstSeg;
+  std::unique_ptr<PragmaHandler> MSCodeSeg;
+  std::unique_ptr<PragmaHandler> MSSection;
+  std::unique_ptr<PragmaHandler> OptimizeHandler;
+  std::unique_ptr<PragmaHandler> LoopHintHandler;
+  std::unique_ptr<PragmaHandler> UnrollHintHandler;
+
+  std::unique_ptr<CommentHandler> CommentSemaHandler;
 
   /// Whether the '>' token acts as an operator or not. This will be
   /// true except when we are parsing an expression within a C++
@@ -167,7 +179,7 @@
   /// ColonProtectionRAIIObject RAII object.
   bool ColonIsSacred;
 
-  /// \brief When true, we are directly inside an Objective-C messsage
+  /// \brief When true, we are directly inside an Objective-C message
   /// send expression.
   ///
   /// This is managed by the \c InMessageExpressionRAIIObject class, and
@@ -193,6 +205,10 @@
       ++Depth;
       ++AddedLevels;
     }
+    void addDepth(unsigned D) {
+      Depth += D;
+      AddedLevels += D;
+    }
     unsigned getDepth() const { return Depth; }
   };
 
@@ -229,6 +245,9 @@
 
   const Token &getCurToken() const { return Tok; }
   Scope *getCurScope() const { return Actions.getCurScope(); }
+  void incrementMSLocalManglingNumber() const {
+    return Actions.incrementMSLocalManglingNumber();
+  }
 
   Decl  *getObjCDeclContext() const { return Actions.getObjCDeclContext(); }
 
@@ -246,7 +265,7 @@
   typedef clang::TypeResult        TypeResult;
 
   typedef Expr *ExprArg;
-  typedef llvm::MutableArrayRef<Stmt*> MultiStmtArg;
+  typedef MutableArrayRef<Stmt*> MultiStmtArg;
   typedef Sema::FullExprArg FullExprArg;
 
   ExprResult ExprError() { return ExprResult(true); }
@@ -266,24 +285,40 @@
   /// ParseTopLevelDecl - Parse one top-level declaration. Returns true if
   /// the EOF was encountered.
   bool ParseTopLevelDecl(DeclGroupPtrTy &Result);
+  bool ParseTopLevelDecl() {
+    DeclGroupPtrTy Result;
+    return ParseTopLevelDecl(Result);
+  }
 
   /// ConsumeToken - Consume the current 'peek token' and lex the next one.
-  /// This does not work with all kinds of tokens: strings and specific other
-  /// tokens must be consumed with custom methods below.  This returns the
-  /// location of the consumed token.
-  SourceLocation ConsumeToken(bool ConsumeCodeCompletionTok = false) {
-    assert(!isTokenStringLiteral() && !isTokenParen() && !isTokenBracket() &&
-           !isTokenBrace() &&
+  /// This does not work with special tokens: string literals, code completion
+  /// and balanced tokens must be handled using the specific consume methods.
+  /// Returns the location of the consumed token.
+  SourceLocation ConsumeToken() {
+    assert(!isTokenSpecial() &&
            "Should consume special tokens with Consume*Token");
-
-    if (!ConsumeCodeCompletionTok && Tok.is(tok::code_completion))
-      return handleUnexpectedCodeCompletionToken();
-
     PrevTokLocation = Tok.getLocation();
     PP.Lex(Tok);
     return PrevTokLocation;
   }
 
+  bool TryConsumeToken(tok::TokenKind Expected) {
+    if (Tok.isNot(Expected))
+      return false;
+    assert(!isTokenSpecial() &&
+           "Should consume special tokens with Consume*Token");
+    PrevTokLocation = Tok.getLocation();
+    PP.Lex(Tok);
+    return true;
+  }
+
+  bool TryConsumeToken(tok::TokenKind Expected, SourceLocation &Loc) {
+    if (!TryConsumeToken(Expected))
+      return false;
+    Loc = PrevTokLocation;
+    return true;
+  }
+
 private:
   //===--------------------------------------------------------------------===//
   // Low-Level token peeking and consumption methods.
@@ -301,12 +336,15 @@
   bool isTokenBrace() const {
     return Tok.getKind() == tok::l_brace || Tok.getKind() == tok::r_brace;
   }
-
   /// isTokenStringLiteral - True if this token is a string-literal.
-  ///
   bool isTokenStringLiteral() const {
     return tok::isStringLiteral(Tok.getKind());
   }
+  /// isTokenSpecial - True if this token requires special consumption methods.
+  bool isTokenSpecial() const {
+    return isTokenStringLiteral() || isTokenParen() || isTokenBracket() ||
+           isTokenBrace() || Tok.is(tok::code_completion);
+  }
 
   /// \brief Returns true if the current token is '=' or is a type of '='.
   /// For typos, give a fixit to '='
@@ -318,14 +356,16 @@
   SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok = false) {
     if (isTokenParen())
       return ConsumeParen();
-    else if (isTokenBracket())
+    if (isTokenBracket())
       return ConsumeBracket();
-    else if (isTokenBrace())
+    if (isTokenBrace())
       return ConsumeBrace();
-    else if (isTokenStringLiteral())
+    if (isTokenStringLiteral())
       return ConsumeStringToken();
-    else
-      return ConsumeToken(ConsumeCodeCompletionTok);
+    if (Tok.is(tok::code_completion))
+      return ConsumeCodeCompletionTok ? ConsumeCodeCompletionToken()
+                                      : handleUnexpectedCodeCompletionToken();
+    return ConsumeToken();
   }
 
   /// ConsumeParen - This consume method keeps the paren count up-to-date.
@@ -383,8 +423,9 @@
 
   /// \brief Consume the current code-completion token.
   ///
-  /// This routine should be called to consume the code-completion token once
-  /// a code-completion action has already been invoked.
+  /// This routine can be called to consume the code-completion token and
+  /// continue processing in special cases where \c cutOffParsing() isn't
+  /// desired, such as token caching or completion with lookahead.
   SourceLocation ConsumeCodeCompletionToken() {
     assert(Tok.is(tok::code_completion));
     PrevTokLocation = Tok.getLocation();
@@ -408,6 +449,20 @@
     Tok.setKind(tok::eof);
   }
 
+  /// \brief Determine if we're at the end of the file or at a transition
+  /// between modules.
+  bool isEofOrEom() {
+    tok::TokenKind Kind = Tok.getKind();
+    return Kind == tok::eof || Kind == tok::annot_module_begin ||
+           Kind == tok::annot_module_end || Kind == tok::annot_module_include;
+  }
+
+  /// \brief Initialize all pragma handlers.
+  void initializePragmaHandlers();
+
+  /// \brief Destroy and reset all pragma handlers.
+  void resetPragmaHandlers();
+
   /// \brief Handle the annotation token produced for #pragma unused(...)
   void HandlePragmaUnused();
 
@@ -427,6 +482,18 @@
   /// #pragma comment...
   void HandlePragmaMSComment();
 
+  void HandlePragmaMSPointersToMembers();
+
+  void HandlePragmaMSVtorDisp();
+
+  void HandlePragmaMSPragma();
+  bool HandlePragmaMSSection(StringRef PragmaName,
+                             SourceLocation PragmaLocation);
+  bool HandlePragmaMSSegment(StringRef PragmaName,
+                             SourceLocation PragmaLocation);
+  bool HandlePragmaMSInitSeg(StringRef PragmaName,
+                             SourceLocation PragmaLocation);
+
   /// \brief Handle the annotation token produced for
   /// #pragma align...
   void HandlePragmaAlign();
@@ -455,6 +522,10 @@
   /// #pragma clang __debug captured
   StmtResult HandlePragmaCaptured();
 
+  /// \brief Handle the annotation token produced for
+  /// #pragma clang loop and #pragma unroll.
+  LoopHint HandlePragmaLoopHint();
+
   /// GetLookAheadToken - This peeks ahead N tokens and returns that token
   /// without consuming any tokens.  LookAhead(0) returns 'Tok', LookAhead(1)
   /// returns the token after Tok, etc.
@@ -521,7 +592,7 @@
     ANK_Success
   };
   AnnotatedNameKind TryAnnotateName(bool IsAddressOfOperand,
-                                    CorrectionCandidateCallback *CCC = 0);
+                                    CorrectionCandidateCallback *CCC = nullptr);
 
   /// Push a tok::annot_cxxscope token onto the token stream.
   void AnnotateScopeToken(CXXScopeSpec &SS, bool IsNewAnnotation);
@@ -555,6 +626,19 @@
                                 const char *&PrevSpec, unsigned &DiagID,
                                 bool &isInvalid);
 
+  /// TryKeywordIdentFallback - For compatibility with system headers using
+  /// keywords as identifiers, attempt to convert the current token to an
+  /// identifier and optionally disable the keyword for the remainder of the
+  /// translation unit. This returns false if the token was not replaced,
+  /// otherwise emits a diagnostic and returns true.
+  bool TryKeywordIdentFallback(bool DisableKeyword);
+
+  /// TryIdentKeywordUpgrade - Convert the current identifier token back to
+  /// its original kind and return true if it was disabled by
+  /// TryKeywordIdentFallback(), otherwise return false. Use this to
+  /// contextually enable keywords.
+  bool TryIdentKeywordUpgrade();
+
   /// \brief Get the TemplateIdAnnotation from the token.
   TemplateIdAnnotation *takeTemplateIdAnnotation(const Token &tok);
 
@@ -621,7 +705,7 @@
   public:
     explicit ObjCDeclContextSwitch(Parser &p)
       : P(p), DC(p.getObjCDeclContext()),
-        WithinObjCContainer(P.ParsingInObjCContainer, DC != 0) {
+        WithinObjCContainer(P.ParsingInObjCContainer, DC != nullptr) {
       if (DC)
         P.Actions.ActOnObjCTemporaryExitContainerContext(cast<DeclContext>(DC));
     }
@@ -634,12 +718,14 @@
   /// ExpectAndConsume - The parser expects that 'ExpectedTok' is next in the
   /// input.  If so, it is consumed and false is returned.
   ///
-  /// If the input is malformed, this emits the specified diagnostic.  Next, if
-  /// SkipToTok is specified, it calls SkipUntil(SkipToTok).  Finally, true is
+  /// If a trivial punctuator misspelling is encountered, a FixIt error
+  /// diagnostic is issued and false is returned after recovery.
+  ///
+  /// If the input is malformed, this emits the specified diagnostic and true is
   /// returned.
-  bool ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned Diag,
-                        const char *DiagMsg = "",
-                        tok::TokenKind SkipToTok = tok::unknown);
+  bool ExpectAndConsume(tok::TokenKind ExpectedTok,
+                        unsigned Diag = diag::err_expected,
+                        StringRef DiagMsg = "");
 
   /// \brief The parser expects a semicolon and, if present, will consume it.
   ///
@@ -677,14 +763,18 @@
   public:
     // ParseScope - Construct a new object to manage a scope in the
     // parser Self where the new Scope is created with the flags
-    // ScopeFlags, but only when ManageScope is true (the default). If
-    // ManageScope is false, this object does nothing.
-    ParseScope(Parser *Self, unsigned ScopeFlags, bool ManageScope = true)
+    // ScopeFlags, but only when we aren't about to enter a compound statement.
+    ParseScope(Parser *Self, unsigned ScopeFlags, bool EnteredScope = true,
+               bool BeforeCompoundStmt = false)
       : Self(Self) {
-      if (ManageScope)
+      if (EnteredScope && !BeforeCompoundStmt)
         Self->EnterScope(ScopeFlags);
-      else
-        this->Self = 0;
+      else {
+        if (BeforeCompoundStmt)
+          Self->incrementMSLocalManglingNumber();
+
+        this->Self = nullptr;
+      }
     }
 
     // Exit - Exit the scope associated with this object now, rather
@@ -692,7 +782,7 @@
     void Exit() {
       if (Self) {
         Self->ExitScope();
-        Self = 0;
+        Self = nullptr;
       }
     }
 
@@ -811,10 +901,10 @@
     LateParsedClass(Parser *P, ParsingClass *C);
     virtual ~LateParsedClass();
 
-    virtual void ParseLexedMethodDeclarations();
-    virtual void ParseLexedMemberInitializers();
-    virtual void ParseLexedMethodDefs();
-    virtual void ParseLexedAttributes();
+    void ParseLexedMethodDeclarations() override;
+    void ParseLexedMemberInitializers() override;
+    void ParseLexedMethodDefs() override;
+    void ParseLexedAttributes() override;
 
   private:
     Parser *Self;
@@ -838,7 +928,7 @@
                                  SourceLocation Loc)
       : Self(P), AttrName(Name), AttrNameLoc(Loc) {}
 
-    virtual void ParseLexedAttributes();
+    void ParseLexedAttributes() override;
 
     void addDecl(Decl *D) { Decls.push_back(D); }
   };
@@ -870,7 +960,7 @@
     explicit LexedMethod(Parser* P, Decl *MD)
       : Self(P), D(MD), TemplateScope(false) {}
 
-    virtual void ParseLexedMethodDefs();
+    void ParseLexedMethodDefs() override;
   };
 
   /// LateParsedDefaultArgument - Keeps track of a parameter that may
@@ -879,7 +969,7 @@
   /// (C++ [class.mem]p2).
   struct LateParsedDefaultArgument {
     explicit LateParsedDefaultArgument(Decl *P,
-                                       CachedTokens *Toks = 0)
+                                       CachedTokens *Toks = nullptr)
       : Param(P), Toks(Toks) { }
 
     /// Param - The parameter declaration for this parameter.
@@ -898,9 +988,10 @@
   /// argument (C++ [class.mem]p2).
   struct LateParsedMethodDeclaration : public LateParsedDeclaration {
     explicit LateParsedMethodDeclaration(Parser *P, Decl *M)
-      : Self(P), Method(M), TemplateScope(false), ExceptionSpecTokens(0) { }
+      : Self(P), Method(M), TemplateScope(false),
+        ExceptionSpecTokens(nullptr) {}
 
-    virtual void ParseLexedMethodDeclarations();
+    void ParseLexedMethodDeclarations() override;
 
     Parser* Self;
 
@@ -931,7 +1022,7 @@
     LateParsedMemberInitializer(Parser *P, Decl *FD)
       : Self(P), Field(FD) { }
 
-    virtual void ParseLexedMemberInitializers();
+    void ParseLexedMemberInitializers() override;
 
     Parser *Self;
 
@@ -1021,7 +1112,7 @@
   /// specifiers.
   struct ParsedTemplateInfo {
     ParsedTemplateInfo()
-      : Kind(NonTemplate), TemplateParams(0), TemplateLoc() { }
+      : Kind(NonTemplate), TemplateParams(nullptr), TemplateLoc() { }
 
     ParsedTemplateInfo(TemplateParameterLists *TemplateParams,
                        bool isSpecialization,
@@ -1032,7 +1123,7 @@
 
     explicit ParsedTemplateInfo(SourceLocation ExternLoc,
                                 SourceLocation TemplateLoc)
-      : Kind(ExplicitInstantiation), TemplateParams(0),
+      : Kind(ExplicitInstantiation), TemplateParams(nullptr),
         ExternLoc(ExternLoc), TemplateLoc(TemplateLoc),
         LastParameterListWasEmpty(false){ }
 
@@ -1125,12 +1216,12 @@
   };
 
   DeclGroupPtrTy ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
-                                          ParsingDeclSpec *DS = 0);
+                                          ParsingDeclSpec *DS = nullptr);
   bool isDeclarationAfterDeclarator();
   bool isStartOfFunctionDefinition(const ParsingDeclarator &Declarator);
   DeclGroupPtrTy ParseDeclarationOrFunctionDefinition(
                                                   ParsedAttributesWithRange &attrs,
-                                                  ParsingDeclSpec *DS = 0,
+                                                  ParsingDeclSpec *DS = nullptr,
                                                   AccessSpecifier AS = AS_none);
   DeclGroupPtrTy ParseDeclOrFunctionDefInternal(ParsedAttributesWithRange &attrs,
                                                 ParsingDeclSpec &DS,
@@ -1138,11 +1229,11 @@
 
   Decl *ParseFunctionDefinition(ParsingDeclarator &D,
                  const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
-                 LateParsedAttrList *LateParsedAttrs = 0);
+                 LateParsedAttrList *LateParsedAttrs = nullptr);
   void ParseKNRParamDeclarations(Declarator &D);
   // EndLoc, if non-NULL, is filled with the location of the last token of
   // the simple-asm.
-  ExprResult ParseSimpleAsm(SourceLocation *EndLoc = 0);
+  ExprResult ParseSimpleAsm(SourceLocation *EndLoc = nullptr);
   ExprResult ParseAsmStringLiteral();
 
   // Objective-C External Declarations
@@ -1282,12 +1373,12 @@
   typedef SmallVector<SourceLocation, 20> CommaLocsTy;
 
   /// ParseExpressionList - Used for C/C++ (argument-)expression-list.
-  bool ParseExpressionList(SmallVectorImpl<Expr*> &Exprs,
-                           SmallVectorImpl<SourceLocation> &CommaLocs,
-                           void (Sema::*Completer)(Scope *S,
-                                                   Expr *Data,
-                                                   ArrayRef<Expr *> Args) = 0,
-                           Expr *Data = 0);
+  bool
+  ParseExpressionList(SmallVectorImpl<Expr *> &Exprs,
+                      SmallVectorImpl<SourceLocation> &CommaLocs,
+                      void (Sema::*Completer)(Scope *S, Expr *Data,
+                                              ArrayRef<Expr *> Args) = nullptr,
+                      Expr *Data = nullptr);
 
   /// ParseSimpleExpressionList - A simple comma-separated list of expressions,
   /// used for misc language extensions.
@@ -1308,9 +1399,9 @@
                                         ParsedType &CastTy,
                                         SourceLocation &RParenLoc);
 
-  ExprResult ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType,
-                                            ParsedType &CastTy,
-                                            BalancedDelimiterTracker &Tracker);
+  ExprResult ParseCXXAmbiguousParenExpression(
+      ParenParseOption &ExprType, ParsedType &CastTy,
+      BalancedDelimiterTracker &Tracker, ColonProtectionRAIIObject &ColonProt);
   ExprResult ParseCompoundLiteralExpression(ParsedType Ty,
                                                   SourceLocation LParenLoc,
                                                   SourceLocation RParenLoc);
@@ -1334,9 +1425,9 @@
   bool ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS,
                                       ParsedType ObjectType,
                                       bool EnteringContext,
-                                      bool *MayBePseudoDestructor = 0,
+                                      bool *MayBePseudoDestructor = nullptr,
                                       bool IsTypename = false,
-                                      IdentifierInfo **LastII = 0);
+                                      IdentifierInfo **LastII = nullptr);
 
   void CheckForLParenAfterColonColon();
 
@@ -1347,7 +1438,7 @@
   ExprResult ParseLambdaExpression();
   ExprResult TryParseLambdaExpression();
   Optional<unsigned> ParseLambdaIntroducer(LambdaIntroducer &Intro,
-                                           bool *SkippedInits = 0);
+                                           bool *SkippedInits = nullptr);
   bool TryParseLambdaIntroducer(LambdaIntroducer &Intro);
   ExprResult ParseLambdaExpressionAfterIntroducer(
                LambdaIntroducer &Intro);
@@ -1483,10 +1574,10 @@
   /// A SmallVector of types.
   typedef SmallVector<ParsedType, 12> TypeVector;
 
-  StmtResult ParseStatement(SourceLocation *TrailingElseLoc = 0);
-  StmtResult ParseStatementOrDeclaration(StmtVector &Stmts,
-                                         bool OnlyStatement,
-                                         SourceLocation *TrailingElseLoc = 0);
+  StmtResult ParseStatement(SourceLocation *TrailingElseLoc = nullptr);
+  StmtResult
+  ParseStatementOrDeclaration(StmtVector &Stmts, bool OnlyStatement,
+                              SourceLocation *TrailingElseLoc = nullptr);
   StmtResult ParseStatementOrDeclarationAfterAttributes(
                                          StmtVector &Stmts,
                                          bool OnlyStatement,
@@ -1517,6 +1608,9 @@
   StmtResult ParseReturnStatement();
   StmtResult ParseAsmStatement(bool &msAsm);
   StmtResult ParseMicrosoftAsmStatement(SourceLocation AsmLoc);
+  StmtResult ParsePragmaLoopHint(StmtVector &Stmts, bool OnlyStatement,
+                                 SourceLocation *TrailingElseLoc,
+                                 ParsedAttributesWithRange &Attrs);
 
   /// \brief Describes the behavior that should be taken for an __if_exists
   /// block.
@@ -1575,6 +1669,7 @@
   StmtResult ParseSEHTryBlockCommon(SourceLocation Loc);
   StmtResult ParseSEHExceptBlock(SourceLocation Loc);
   StmtResult ParseSEHFinallyBlock(SourceLocation Loc);
+  StmtResult ParseSEHLeaveStatement();
 
   //===--------------------------------------------------------------------===//
   // Objective-C Statements
@@ -1597,9 +1692,29 @@
     DSC_class,  // class context, enables 'friend'
     DSC_type_specifier, // C++ type-specifier-seq or C specifier-qualifier-list
     DSC_trailing, // C++11 trailing-type-specifier in a trailing return type
-    DSC_top_level // top-level/namespace declaration context
+    DSC_alias_declaration, // C++11 type-specifier-seq in an alias-declaration
+    DSC_top_level, // top-level/namespace declaration context
+    DSC_template_type_arg // template type argument context
   };
 
+  /// Is this a context in which we are parsing just a type-specifier (or
+  /// trailing-type-specifier)?
+  static bool isTypeSpecifier(DeclSpecContext DSC) {
+    switch (DSC) {
+    case DSC_normal:
+    case DSC_class:
+    case DSC_top_level:
+      return false;
+
+    case DSC_template_type_arg:
+    case DSC_type_specifier:
+    case DSC_trailing:
+    case DSC_alias_declaration:
+      return true;
+    }
+    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 {
@@ -1617,17 +1732,19 @@
                                         SourceLocation &DeclEnd,
                                         ParsedAttributesWithRange &attrs,
                                         bool RequireSemi,
-                                        ForRangeInit *FRI = 0);
+                                        ForRangeInit *FRI = nullptr);
   bool MightBeDeclarator(unsigned Context);
   DeclGroupPtrTy ParseDeclGroup(ParsingDeclSpec &DS, unsigned Context,
                                 bool AllowFunctionDefinitions,
-                                SourceLocation *DeclEnd = 0,
-                                ForRangeInit *FRI = 0);
+                                SourceLocation *DeclEnd = nullptr,
+                                ForRangeInit *FRI = nullptr);
   Decl *ParseDeclarationAfterDeclarator(Declarator &D,
                const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo());
   bool ParseAsmAttributesAfterDeclarator(Declarator &D);
-  Decl *ParseDeclarationAfterDeclaratorAndAttributes(Declarator &D,
-               const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo());
+  Decl *ParseDeclarationAfterDeclaratorAndAttributes(
+      Declarator &D,
+      const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
+      ForRangeInit *FRI = nullptr);
   Decl *ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope);
   Decl *ParseFunctionTryBlock(Decl *Decl, ParseScope &BodyScope);
 
@@ -1646,7 +1763,10 @@
                 const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
                                   AccessSpecifier AS = AS_none,
                                   DeclSpecContext DSC = DSC_normal,
-                                  LateParsedAttrList *LateAttrs = 0);
+                                  LateParsedAttrList *LateAttrs = nullptr);
+  bool DiagnoseMissingSemiAfterTagDefinition(DeclSpec &DS, AccessSpecifier AS,
+                                       DeclSpecContext DSContext,
+                                       LateParsedAttrList *LateAttrs = nullptr);
 
   void ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS = AS_none,
                                    DeclSpecContext DSC = DSC_normal);
@@ -1686,7 +1806,7 @@
   /// cast. Return false if it's no a decl-specifier, or we're not sure.
   bool isKnownToBeDeclarationSpecifier() {
     if (getLangOpts().CPlusPlus)
-      return isCXXDeclarationSpecifier() == TPResult::True();
+      return isCXXDeclarationSpecifier() == TPResult::True;
     return isDeclarationSpecifier(true);
   }
 
@@ -1709,6 +1829,9 @@
     return isDeclarationSpecifier(true);
   }
 
+  /// \brief Determine whether this is a C++1z for-range-identifier.
+  bool isForRangeIdentifier();
+
   /// \brief Determine whether we are currently at the start of an Objective-C
   /// class message that appears to be missing the open bracket '['.
   bool isStartOfObjCClassMessageMissingOpenBracket();
@@ -1716,12 +1839,13 @@
   /// \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 isConstructorDeclarator(bool Unqualified);
 
   /// \brief Specifies the context in which type-id/expression
   /// disambiguation will occur.
   enum TentativeCXXTypeIdContext {
     TypeIdInParens,
+    TypeIdUnambiguous,
     TypeIdAsTemplateArgument
   };
 
@@ -1740,6 +1864,16 @@
     return isTypeIdInParens(isAmbiguous);
   }
 
+  /// \brief Checks if the current tokens form type-id or expression.
+  /// It is similar to isTypeIdInParens but does not suppose that type-id
+  /// is in parenthesis.
+  bool isTypeIdUnambiguously() {
+    bool IsAmbiguous;
+    if (getLangOpts().CPlusPlus)
+      return isCXXTypeId(TypeIdUnambiguous, IsAmbiguous);
+    return isTypeSpecifierQualifier();
+  }
+
   /// isCXXDeclarationStatement - C++-specialized function that disambiguates
   /// between a declaration or an expression statement, when parsing function
   /// bodies. Returns true for declaration, false for expression.
@@ -1759,7 +1893,7 @@
   /// might be a constructor-style initializer.
   /// If during the disambiguation process a parsing error is encountered,
   /// the function returns true to let the declaration parsing code handle it.
-  bool isCXXFunctionDeclarator(bool *IsAmbiguous = 0);
+  bool isCXXFunctionDeclarator(bool *IsAmbiguous = nullptr);
 
   /// isCXXConditionDeclaration - Disambiguates between a declaration or an
   /// expression for a condition of a if/switch/while/for statement.
@@ -1775,25 +1909,8 @@
 
   /// TPResult - Used as the result value for functions whose purpose is to
   /// disambiguate C++ constructs by "tentatively parsing" them.
-  /// This is a class instead of a simple enum because the implicit enum-to-bool
-  /// conversions may cause subtle bugs.
-  class TPResult {
-    enum Result {
-      TPR_true,
-      TPR_false,
-      TPR_ambiguous,
-      TPR_error
-    };
-    Result Res;
-    TPResult(Result result) : Res(result) {}
-  public:
-    static TPResult True() { return TPR_true; }
-    static TPResult False() { return TPR_false; }
-    static TPResult Ambiguous() { return TPR_ambiguous; }
-    static TPResult Error() { return TPR_error; }
-
-    bool operator==(const TPResult &RHS) const { return Res == RHS.Res; }
-    bool operator!=(const TPResult &RHS) const { return Res != RHS.Res; }
+  enum class TPResult {
+    True, False, Ambiguous, Error
   };
 
   /// \brief Based only on the given token kind, determine whether we know that
@@ -1808,16 +1925,16 @@
   /// tell.
   TPResult isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind);
 
-  /// isCXXDeclarationSpecifier - Returns TPResult::True() if it is a
-  /// declaration specifier, TPResult::False() if it is not,
-  /// TPResult::Ambiguous() if it could be either a decl-specifier or a
-  /// function-style cast, and TPResult::Error() if a parsing error was
+  /// isCXXDeclarationSpecifier - Returns TPResult::True if it is a
+  /// declaration specifier, TPResult::False if it is not,
+  /// TPResult::Ambiguous if it could be either a decl-specifier or a
+  /// function-style cast, and TPResult::Error if a parsing error was
   /// encountered. If it could be a braced C++11 function-style cast, returns
   /// BracedCastResult.
   /// Doesn't consume tokens.
   TPResult
-  isCXXDeclarationSpecifier(TPResult BracedCastResult = TPResult::False(),
-                            bool *HasMissingTypename = 0);
+  isCXXDeclarationSpecifier(TPResult BracedCastResult = TPResult::False,
+                            bool *HasMissingTypename = nullptr);
 
   /// Given that isCXXDeclarationSpecifier returns \c TPResult::True or
   /// \c TPResult::Ambiguous, determine whether the decl-specifier would be
@@ -1830,9 +1947,9 @@
   bool isTentativelyDeclared(IdentifierInfo *II);
 
   // "Tentative parsing" functions, used for disambiguation. If a parsing error
-  // is encountered they will return TPResult::Error().
-  // Returning TPResult::True()/False() indicates that the ambiguity was
-  // resolved and tentative parsing may stop. TPResult::Ambiguous() indicates
+  // is encountered they will return TPResult::Error.
+  // Returning TPResult::True/False indicates that the ambiguity was
+  // resolved and tentative parsing may stop. TPResult::Ambiguous indicates
   // that more tentative parsing is necessary for disambiguation.
   // They all consume tokens, so backtracking should be used after calling them.
 
@@ -1843,19 +1960,20 @@
   TPResult TryParseOperatorId();
   TPResult TryParseInitDeclaratorList();
   TPResult TryParseDeclarator(bool mayBeAbstract, bool mayHaveIdentifier=true);
-  TPResult TryParseParameterDeclarationClause(bool *InvalidAsDeclaration = 0,
-                                              bool VersusTemplateArg = false);
+  TPResult
+  TryParseParameterDeclarationClause(bool *InvalidAsDeclaration = nullptr,
+                                     bool VersusTemplateArg = false);
   TPResult TryParseFunctionDeclarator();
   TPResult TryParseBracketDeclarator();
   TPResult TryConsumeDeclarationSpecifier();
 
 public:
-  TypeResult ParseTypeName(SourceRange *Range = 0,
+  TypeResult ParseTypeName(SourceRange *Range = nullptr,
                            Declarator::TheContext Context
                              = Declarator::TypeNameContext,
                            AccessSpecifier AS = AS_none,
-                           Decl **OwnedType = 0,
-                           ParsedAttributes *Attrs = 0);
+                           Decl **OwnedType = nullptr,
+                           ParsedAttributes *Attrs = nullptr);
 
 private:
   void ParseBlockId(SourceLocation CaretLoc);
@@ -1893,35 +2011,51 @@
   // for example, attributes appertain to decl specifiers.
   void ProhibitCXX11Attributes(ParsedAttributesWithRange &attrs);
 
+  /// \brief Skip C++11 attributes and return the end location of the last one.
+  /// \returns SourceLocation() if there are no attributes.
+  SourceLocation SkipCXX11Attributes();
+
   /// \brief Diagnose and skip C++11 attributes that appear in syntactic
   /// locations where attributes are not allowed.
   void DiagnoseAndSkipCXX11Attributes();
 
+  /// \brief Parses syntax-generic attribute arguments for attributes which are
+  /// known to the implementation, and adds them to the given ParsedAttributes
+  /// list with the given attribute syntax. Returns the number of arguments
+  /// parsed for the attribute.
+  unsigned
+  ParseAttributeArgsCommon(IdentifierInfo *AttrName, SourceLocation AttrNameLoc,
+                           ParsedAttributes &Attrs, SourceLocation *EndLoc,
+                           IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
+                           AttributeList::Syntax Syntax);
+
   void MaybeParseGNUAttributes(Declarator &D,
-                               LateParsedAttrList *LateAttrs = 0) {
+                               LateParsedAttrList *LateAttrs = nullptr) {
     if (Tok.is(tok::kw___attribute)) {
       ParsedAttributes attrs(AttrFactory);
       SourceLocation endLoc;
-      ParseGNUAttributes(attrs, &endLoc, LateAttrs);
+      ParseGNUAttributes(attrs, &endLoc, LateAttrs, &D);
       D.takeAttributes(attrs, endLoc);
     }
   }
   void MaybeParseGNUAttributes(ParsedAttributes &attrs,
-                               SourceLocation *endLoc = 0,
-                               LateParsedAttrList *LateAttrs = 0) {
+                               SourceLocation *endLoc = nullptr,
+                               LateParsedAttrList *LateAttrs = nullptr) {
     if (Tok.is(tok::kw___attribute))
       ParseGNUAttributes(attrs, endLoc, LateAttrs);
   }
   void ParseGNUAttributes(ParsedAttributes &attrs,
-                          SourceLocation *endLoc = 0,
-                          LateParsedAttrList *LateAttrs = 0);
+                          SourceLocation *endLoc = nullptr,
+                          LateParsedAttrList *LateAttrs = nullptr,
+                          Declarator *D = nullptr);
   void ParseGNUAttributeArgs(IdentifierInfo *AttrName,
                              SourceLocation AttrNameLoc,
                              ParsedAttributes &Attrs,
                              SourceLocation *EndLoc,
                              IdentifierInfo *ScopeName,
                              SourceLocation ScopeLoc,
-                             AttributeList::Syntax Syntax);
+                             AttributeList::Syntax Syntax,
+                             Declarator *D);
   IdentifierLoc *ParseIdentifierLoc();
 
   void MaybeParseCXX11Attributes(Declarator &D) {
@@ -1933,7 +2067,7 @@
     }
   }
   void MaybeParseCXX11Attributes(ParsedAttributes &attrs,
-                                 SourceLocation *endLoc = 0) {
+                                 SourceLocation *endLoc = nullptr) {
     if (getLangOpts().CPlusPlus11 && isCXX11AttributeSpecifier()) {
       ParsedAttributesWithRange attrsWithRange(AttrFactory);
       ParseCXX11Attributes(attrsWithRange, endLoc);
@@ -1941,7 +2075,7 @@
     }
   }
   void MaybeParseCXX11Attributes(ParsedAttributesWithRange &attrs,
-                                 SourceLocation *endLoc = 0,
+                                 SourceLocation *endLoc = nullptr,
                                  bool OuterMightBeMessageSend = false) {
     if (getLangOpts().CPlusPlus11 &&
         isCXX11AttributeSpecifier(false, OuterMightBeMessageSend))
@@ -1949,54 +2083,68 @@
   }
 
   void ParseCXX11AttributeSpecifier(ParsedAttributes &attrs,
-                                    SourceLocation *EndLoc = 0);
+                                    SourceLocation *EndLoc = nullptr);
   void ParseCXX11Attributes(ParsedAttributesWithRange &attrs,
-                            SourceLocation *EndLoc = 0);
+                            SourceLocation *EndLoc = nullptr);
+  /// \brief Parses a C++-style attribute argument list. Returns true if this
+  /// results in adding an attribute to the ParsedAttributes list.
+  bool ParseCXX11AttributeArgs(IdentifierInfo *AttrName,
+                               SourceLocation AttrNameLoc,
+                               ParsedAttributes &Attrs, SourceLocation *EndLoc,
+                               IdentifierInfo *ScopeName,
+                               SourceLocation ScopeLoc);
 
   IdentifierInfo *TryParseCXX11AttributeIdentifier(SourceLocation &Loc);
 
   void MaybeParseMicrosoftAttributes(ParsedAttributes &attrs,
-                                     SourceLocation *endLoc = 0) {
+                                     SourceLocation *endLoc = nullptr) {
     if (getLangOpts().MicrosoftExt && Tok.is(tok::l_square))
       ParseMicrosoftAttributes(attrs, endLoc);
   }
   void ParseMicrosoftAttributes(ParsedAttributes &attrs,
-                                SourceLocation *endLoc = 0);
+                                SourceLocation *endLoc = nullptr);
   void ParseMicrosoftDeclSpec(ParsedAttributes &Attrs);
-  bool IsSimpleMicrosoftDeclSpec(IdentifierInfo *Ident);
-  void ParseComplexMicrosoftDeclSpec(IdentifierInfo *Ident, 
-                                     SourceLocation Loc,
-                                     ParsedAttributes &Attrs);
-  void ParseMicrosoftDeclSpecWithSingleArg(IdentifierInfo *AttrName, 
-                                           SourceLocation AttrNameLoc, 
-                                           ParsedAttributes &Attrs);
+  bool ParseMicrosoftDeclSpecArgs(IdentifierInfo *AttrName,
+                                  SourceLocation AttrNameLoc,
+                                  ParsedAttributes &Attrs);
   void ParseMicrosoftTypeAttributes(ParsedAttributes &attrs);
   void ParseMicrosoftInheritanceClassAttributes(ParsedAttributes &attrs);
   void ParseBorlandTypeAttributes(ParsedAttributes &attrs);
   void ParseOpenCLAttributes(ParsedAttributes &attrs);
-  void ParseOpenCLQualifiers(DeclSpec &DS);
+  void ParseOpenCLQualifiers(ParsedAttributes &Attrs);
 
   VersionTuple ParseVersionTuple(SourceRange &Range);
   void ParseAvailabilityAttribute(IdentifierInfo &Availability,
                                   SourceLocation AvailabilityLoc,
                                   ParsedAttributes &attrs,
-                                  SourceLocation *endLoc);
+                                  SourceLocation *endLoc,
+                                  IdentifierInfo *ScopeName,
+                                  SourceLocation ScopeLoc,
+                                  AttributeList::Syntax Syntax);
 
-  bool IsThreadSafetyAttribute(StringRef AttrName);
-  void ParseThreadSafetyAttribute(IdentifierInfo &AttrName,
-                                  SourceLocation AttrNameLoc,
-                                  ParsedAttributes &Attrs,
-                                  SourceLocation *EndLoc);
+  void ParseObjCBridgeRelatedAttribute(IdentifierInfo &ObjCBridgeRelated,
+                                       SourceLocation ObjCBridgeRelatedLoc,
+                                       ParsedAttributes &attrs,
+                                       SourceLocation *endLoc,
+                                       IdentifierInfo *ScopeName,
+                                       SourceLocation ScopeLoc,
+                                       AttributeList::Syntax Syntax);
 
   void ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName,
                                         SourceLocation AttrNameLoc,
                                         ParsedAttributes &Attrs,
-                                        SourceLocation *EndLoc);
+                                        SourceLocation *EndLoc,
+                                        IdentifierInfo *ScopeName,
+                                        SourceLocation ScopeLoc,
+                                        AttributeList::Syntax Syntax);
 
   void ParseAttributeWithTypeArg(IdentifierInfo &AttrName,
                                  SourceLocation AttrNameLoc,
                                  ParsedAttributes &Attrs,
-                                 SourceLocation *EndLoc);
+                                 SourceLocation *EndLoc,
+                                 IdentifierInfo *ScopeName,
+                                 SourceLocation ScopeLoc,
+                                 AttributeList::Syntax Syntax);
 
   void ParseTypeofSpecifier(DeclSpec &DS);
   SourceLocation ParseDecltypeSpecifier(DeclSpec &DS);
@@ -2009,7 +2157,7 @@
   ExprResult ParseAlignArgument(SourceLocation Start,
                                 SourceLocation &EllipsisLoc);
   void ParseAlignmentSpecifier(ParsedAttributes &Attrs,
-                               SourceLocation *endLoc = 0);
+                               SourceLocation *endLoc = nullptr);
 
   VirtSpecifiers::Specifier isCXX11VirtSpecifier(const Token &Tok) const;
   VirtSpecifiers::Specifier isCXX11VirtSpecifier() const {
@@ -2061,7 +2209,8 @@
 
   void ParseTypeQualifierListOpt(DeclSpec &DS, bool GNUAttributesAllowed = true,
                                  bool CXX11AttributesAllowed = true,
-                                 bool AtomicAllowed = true);
+                                 bool AtomicAllowed = true,
+                                 bool IdentifierRequired = false);
   void ParseDirectDeclarator(Declarator &D);
   void ParseParenDeclarator(Declarator &D);
   void ParseFunctionDeclarator(Declarator &D,
@@ -2079,6 +2228,7 @@
          SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo,
          SourceLocation &EllipsisLoc);
   void ParseBracketDeclarator(Declarator &D);
+  void ParseMisplacedBracketDeclarator(Declarator &D);
 
   //===--------------------------------------------------------------------===//
   // C++ 7: Declarations [dcl.dcl]
@@ -2112,7 +2262,7 @@
                                          const ParsedTemplateInfo &TemplateInfo,
                                          SourceLocation &DeclEnd,
                                          ParsedAttributesWithRange &attrs,
-                                         Decl **OwnedType = 0);
+                                         Decl **OwnedType = nullptr);
   Decl *ParseUsingDirective(unsigned Context,
                             SourceLocation UsingLoc,
                             SourceLocation &DeclEnd,
@@ -2122,7 +2272,7 @@
                               SourceLocation UsingLoc,
                               SourceLocation &DeclEnd,
                               AccessSpecifier AS = AS_none,
-                              Decl **OwnedType = 0);
+                              Decl **OwnedType = nullptr);
   Decl *ParseStaticAssertDeclaration(SourceLocation &DeclEnd);
   Decl *ParseNamespaceAlias(SourceLocation NamespaceLoc,
                             SourceLocation AliasLoc, IdentifierInfo *Alias,
@@ -2143,9 +2293,13 @@
                                    Decl *TagDecl);
   ExprResult ParseCXXMemberInitializer(Decl *D, bool IsFunction,
                                        SourceLocation &EqualLoc);
+  void ParseCXXMemberDeclaratorBeforeInitializer(Declarator &DeclaratorInfo,
+                                                 VirtSpecifiers &VS,
+                                                 ExprResult &BitfieldSize,
+                                                 LateParsedAttrList &LateAttrs);
   void ParseCXXClassMemberDeclaration(AccessSpecifier AS, AttributeList *Attr,
-                const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
-                                 ParsingDeclRAIIObject *DiagsFromTParams = 0);
+                  const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
+                  ParsingDeclRAIIObject *DiagsFromTParams = nullptr);
   void ParseConstructorInitializer(Decl *ConstructorDecl);
   MemInitResult ParseMemInitializer(Decl *ConstructorDecl);
   void HandleMemberFunctionDeclDelays(Declarator& DeclaratorInfo,
@@ -2186,7 +2340,12 @@
                                 SmallVectorImpl<Expr *> &VarList,
                                 bool AllowScopeSpecifier);
   /// \brief Parses declarative or executable directive.
-  StmtResult ParseOpenMPDeclarativeOrExecutableDirective();
+  ///
+  /// \param StandAloneAllowed true if allowed stand-alone directives,
+  /// false - otherwise
+  ///
+  StmtResult
+  ParseOpenMPDeclarativeOrExecutableDirective(bool StandAloneAllowed);
   /// \brief Parses clause of kind \a CKind for directive of a kind \a Kind.
   ///
   /// \param DKind Kind of current directive.
@@ -2206,6 +2365,17 @@
   /// \param Kind Kind of current clause.
   ///
   OMPClause *ParseOpenMPSimpleClause(OpenMPClauseKind Kind);
+  /// \brief Parses clause with a single expression and an additional argument
+  /// of a kind \a Kind.
+  ///
+  /// \param Kind Kind of current clause.
+  ///
+  OMPClause *ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind);
+  /// \brief Parses clause without any additional arguments.
+  ///
+  /// \param Kind Kind of current clause.
+  ///
+  OMPClause *ParseOpenMPClause(OpenMPClauseKind Kind);
   /// \brief Parses clause with the list of variables of a kind \a Kind.
   ///
   /// \param Kind Kind of current clause.
@@ -2225,9 +2395,9 @@
 
   // C++ 14.1: Template Parameters [temp.param]
   Decl *ParseDeclarationStartingWithTemplate(unsigned Context,
-                                             SourceLocation &DeclEnd,
-                                             AccessSpecifier AS = AS_none,
-                                             AttributeList *AccessAttrs = 0);
+                                          SourceLocation &DeclEnd,
+                                          AccessSpecifier AS = AS_none,
+                                          AttributeList *AccessAttrs = nullptr);
   Decl *ParseTemplateDeclarationOrSpecialization(unsigned Context,
                                                  SourceLocation &DeclEnd,
                                                  AccessSpecifier AS,
@@ -2238,7 +2408,7 @@
                                        ParsingDeclRAIIObject &DiagsFromParams,
                                        SourceLocation &DeclEnd,
                                        AccessSpecifier AS=AS_none,
-                                       AttributeList *AccessAttrs = 0);
+                                       AttributeList *AccessAttrs = nullptr);
   bool ParseTemplateParameters(unsigned Depth,
                                SmallVectorImpl<Decl*> &TemplateParams,
                                SourceLocation &LAngleLoc,
@@ -2250,6 +2420,12 @@
   Decl *ParseTypeParameter(unsigned Depth, unsigned Position);
   Decl *ParseTemplateTemplateParameter(unsigned Depth, unsigned Position);
   Decl *ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position);
+  void DiagnoseMisplacedEllipsis(SourceLocation EllipsisLoc,
+                                 SourceLocation CorrectLoc,
+                                 bool AlreadyHasEllipsis,
+                                 bool IdentifierHasName);
+  void DiagnoseMisplacedEllipsisInDeclarator(SourceLocation EllipsisLoc,
+                                             Declarator &D);
   // C++ 14.3: Template arguments [temp.arg]
   typedef SmallVector<ParsedTemplateArgument, 16> TemplateArgList;
 
@@ -2284,9 +2460,7 @@
   DeclGroupPtrTy ParseModuleImport(SourceLocation AtLoc);
 
   //===--------------------------------------------------------------------===//
-  // GNU G++: Type Traits [Type-Traits.html in the GCC manual]
-  ExprResult ParseUnaryTypeTrait();
-  ExprResult ParseBinaryTypeTrait();
+  // C++11/G++: Type Traits [Type-Traits.html in the GCC manual]
   ExprResult ParseTypeTrait();
   
   //===--------------------------------------------------------------------===//
@@ -2296,14 +2470,13 @@
 
   //===--------------------------------------------------------------------===//
   // Preprocessor code-completion pass-through
-  virtual void CodeCompleteDirective(bool InConditional);
-  virtual void CodeCompleteInConditionalExclusion();
-  virtual void CodeCompleteMacroName(bool IsDefinition);
-  virtual void CodeCompletePreprocessorExpression();
-  virtual void CodeCompleteMacroArgument(IdentifierInfo *Macro,
-                                         MacroInfo *MacroInfo,
-                                         unsigned ArgumentIndex);
-  virtual void CodeCompleteNaturalLanguage();
+  void CodeCompleteDirective(bool InConditional) override;
+  void CodeCompleteInConditionalExclusion() override;
+  void CodeCompleteMacroName(bool IsDefinition) override;
+  void CodeCompletePreprocessorExpression() override;
+  void CodeCompleteMacroArgument(IdentifierInfo *Macro, MacroInfo *MacroInfo,
+                                 unsigned ArgumentIndex) override;
+  void CodeCompleteNaturalLanguage() override;
 };
 
 }  // end namespace clang
diff --git a/include/clang/Rewrite/Core/HTMLRewrite.h b/include/clang/Rewrite/Core/HTMLRewrite.h
index 3cd0461..ec061dc 100644
--- a/include/clang/Rewrite/Core/HTMLRewrite.h
+++ b/include/clang/Rewrite/Core/HTMLRewrite.h
@@ -63,7 +63,7 @@
   void AddLineNumbers(Rewriter& R, FileID FID);
 
   void AddHeaderFooterInternalBuiltinCSS(Rewriter& R, FileID FID,
-                                         const char *title = NULL);
+                                         const char *title = nullptr);
 
   /// SyntaxHighlight - Relex the specified FileID and annotate the HTML with
   /// information about keywords, comments, etc.
diff --git a/include/clang/Rewrite/Core/RewriteRope.h b/include/clang/Rewrite/Core/RewriteRope.h
index a5192ef..f312aed 100644
--- a/include/clang/Rewrite/Core/RewriteRope.h
+++ b/include/clang/Rewrite/Core/RewriteRope.h
@@ -14,6 +14,7 @@
 #ifndef LLVM_CLANG_REWRITEROPE_H
 #define LLVM_CLANG_REWRITEROPE_H
 
+#include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Compiler.h"
 #include <cassert>
 #include <cstddef>
@@ -60,7 +61,7 @@
     unsigned StartOffs;
     unsigned EndOffs;
 
-    RopePiece() : StrData(0), StartOffs(0), EndOffs(0) {}
+    RopePiece() : StrData(nullptr), StartOffs(0), EndOffs(0) {}
 
     RopePiece(RopeRefCountString *Str, unsigned Start, unsigned End)
       : StrData(Str), StartOffs(Start), EndOffs(End) {
@@ -121,7 +122,8 @@
     // begin iterator.
     RopePieceBTreeIterator(const void /*RopePieceBTreeNode*/ *N);
     // end iterator
-    RopePieceBTreeIterator() : CurNode(0), CurPiece(0), CurChar(0) {}
+    RopePieceBTreeIterator()
+      : CurNode(nullptr), CurPiece(nullptr), CurChar(0) {}
 
     char operator*() const {
       return (*CurPiece)[CurChar];
@@ -144,7 +146,11 @@
     inline RopePieceBTreeIterator operator++(int) { // Postincrement
       RopePieceBTreeIterator tmp = *this; ++*this; return tmp;
     }
-  private:
+
+    llvm::StringRef piece() const {
+      return llvm::StringRef(&(*CurPiece)[0], CurPiece->size());
+    }
+
     void MoveToNextPiece();
   };
 
@@ -190,9 +196,9 @@
   enum { AllocChunkSize = 4080 };
 
 public:
-  RewriteRope() :  AllocBuffer(0), AllocOffs(AllocChunkSize) {}
+  RewriteRope() :  AllocBuffer(nullptr), AllocOffs(AllocChunkSize) {}
   RewriteRope(const RewriteRope &RHS)
-    : Chunks(RHS.Chunks), AllocBuffer(0), AllocOffs(AllocChunkSize) {
+    : Chunks(RHS.Chunks), AllocBuffer(nullptr), AllocOffs(AllocChunkSize) {
   }
 
   ~RewriteRope() {
diff --git a/include/clang/Rewrite/Core/Rewriter.h b/include/clang/Rewrite/Core/Rewriter.h
index 2d2917b..7b22fb4 100644
--- a/include/clang/Rewrite/Core/Rewriter.h
+++ b/include/clang/Rewrite/Core/Rewriter.h
@@ -151,7 +151,7 @@
 
   explicit Rewriter(SourceManager &SM, const LangOptions &LO)
     : SourceMgr(&SM), LangOpts(&LO) {}
-  explicit Rewriter() : SourceMgr(0), LangOpts(0) {}
+  explicit Rewriter() : SourceMgr(nullptr), LangOpts(nullptr) {}
 
   void setSourceMgr(SourceManager &SM, const LangOptions &LO) {
     SourceMgr = &SM;
@@ -275,7 +275,7 @@
   const RewriteBuffer *getRewriteBufferFor(FileID FID) const {
     std::map<FileID, RewriteBuffer>::const_iterator I =
       RewriteBuffers.find(FID);
-    return I == RewriteBuffers.end() ? 0 : &I->second;
+    return I == RewriteBuffers.end() ? nullptr : &I->second;
   }
 
   // Iterators over rewrite buffers.
diff --git a/include/clang/Rewrite/Core/TokenRewriter.h b/include/clang/Rewrite/Core/TokenRewriter.h
index ec0bb5b..c313b45 100644
--- a/include/clang/Rewrite/Core/TokenRewriter.h
+++ b/include/clang/Rewrite/Core/TokenRewriter.h
@@ -17,9 +17,9 @@
 
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Lex/Token.h"
-#include "llvm/ADT/OwningPtr.h"
 #include <list>
 #include <map>
+#include <memory>
 
 namespace clang {
   class LangOptions;
@@ -41,7 +41,7 @@
 
     /// ScratchBuf - This is the buffer that we create scratch tokens from.
     ///
-    OwningPtr<ScratchBuffer> ScratchBuf;
+    std::unique_ptr<ScratchBuffer> ScratchBuf;
 
     TokenRewriter(const TokenRewriter &) LLVM_DELETED_FUNCTION;
     void operator=(const TokenRewriter &) LLVM_DELETED_FUNCTION;
diff --git a/include/clang/Rewrite/Frontend/FixItRewriter.h b/include/clang/Rewrite/Frontend/FixItRewriter.h
index 423f066..3ad8f40 100644
--- a/include/clang/Rewrite/Frontend/FixItRewriter.h
+++ b/include/clang/Rewrite/Frontend/FixItRewriter.h
@@ -90,7 +90,7 @@
 
   /// \brief Check whether there are modifications for a given file.
   bool IsModified(FileID ID) const {
-    return Rewrite.getRewriteBufferFor(ID) != NULL;
+    return Rewrite.getRewriteBufferFor(ID) != nullptr;
   }
 
   // Iteration over files with changes.
@@ -106,18 +106,18 @@
   ///
   /// \returns true if there was an error, false otherwise.
   bool WriteFixedFiles(
-         std::vector<std::pair<std::string, std::string> > *RewrittenFiles = 0);
+     std::vector<std::pair<std::string, std::string> > *RewrittenFiles=nullptr);
 
   /// IncludeInDiagnosticCounts - This method (whose default implementation
   /// returns true) indicates whether the diagnostics handled by this
   /// DiagnosticConsumer should be included in the number of diagnostics
   /// reported by DiagnosticsEngine.
-  virtual bool IncludeInDiagnosticCounts() const;
+  bool IncludeInDiagnosticCounts() const override;
 
   /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or
   /// capturing it to a log as needed.
-  virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
-                                const Diagnostic &Info);
+  void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+                        const Diagnostic &Info) override;
 
   /// \brief Emit a diagnostic via the adapted diagnostic client.
   void Diag(SourceLocation Loc, unsigned DiagID);
diff --git a/include/clang/Rewrite/Frontend/FrontendActions.h b/include/clang/Rewrite/Frontend/FrontendActions.h
index ea876d9..fc79270 100644
--- a/include/clang/Rewrite/Frontend/FrontendActions.h
+++ b/include/clang/Rewrite/Frontend/FrontendActions.h
@@ -22,24 +22,24 @@
 
 class HTMLPrintAction : public ASTFrontendAction {
 protected:
-  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
-                                         StringRef InFile);
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
 };
 
 class FixItAction : public ASTFrontendAction {
 protected:
-  OwningPtr<FixItRewriter> Rewriter;
-  OwningPtr<FixItOptions> FixItOpts;
+  std::unique_ptr<FixItRewriter> Rewriter;
+  std::unique_ptr<FixItOptions> FixItOpts;
 
-  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
-                                         StringRef InFile);
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
 
-  virtual bool BeginSourceFileAction(CompilerInstance &CI,
-                                     StringRef Filename);
+  bool BeginSourceFileAction(CompilerInstance &CI,
+                             StringRef Filename) override;
 
-  virtual void EndSourceFileAction();
+  void EndSourceFileAction() override;
 
-  virtual bool hasASTFileSupport() const { return false; }
+  bool hasASTFileSupport() const override { return false; }
 
 public:
   FixItAction();
@@ -54,28 +54,28 @@
     : WrapperFrontendAction(WrappedAction) {}
 
 protected:
-  virtual bool BeginInvocation(CompilerInstance &CI);
+  bool BeginInvocation(CompilerInstance &CI) override;
 };
 
 class RewriteObjCAction : public ASTFrontendAction {
 protected:
-  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
-                                         StringRef InFile);
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
 };
 
 class RewriteMacrosAction : public PreprocessorFrontendAction {
 protected:
-  void ExecuteAction();
+  void ExecuteAction() override;
 };
 
 class RewriteTestAction : public PreprocessorFrontendAction {
 protected:
-  void ExecuteAction();
+  void ExecuteAction() override;
 };
 
 class RewriteIncludesAction : public PreprocessorFrontendAction {
 protected:
-  void ExecuteAction();
+  void ExecuteAction() override;
 };
 
 }  // end namespace clang
diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h
index 508064d..c21c19f 100644
--- a/include/clang/Sema/AttributeList.h
+++ b/include/clang/Sema/AttributeList.h
@@ -18,8 +18,9 @@
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/VersionTuple.h"
 #include "clang/Sema/Ownership.h"
-#include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Triple.h"
 #include "llvm/Support/Allocator.h"
 #include <cassert>
 
@@ -79,7 +80,9 @@
     /// __declspec(...)
     AS_Declspec,
     /// __ptr16, alignas(...), etc.
-    AS_Keyword
+    AS_Keyword,
+    /// #pragma ...
+    AS_Pragma
   };
 
 private:
@@ -217,7 +220,7 @@
       ScopeLoc(scopeLoc), EllipsisLoc(ellipsisLoc), NumArgs(numArgs),
       SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false),
       IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false),
-      HasParsedType(false), NextInPosition(0), NextInPool(0) {
+      HasParsedType(false), NextInPosition(nullptr), NextInPool(nullptr) {
     if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(ArgsUnion));
     AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
   }
@@ -236,7 +239,7 @@
       Invalid(false), UsedAsTypeAttr(false), IsAvailability(true),
       IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
       UnavailableLoc(unavailable), MessageExpr(messageExpr),
-      NextInPosition(0), NextInPool(0) {
+      NextInPosition(nullptr), NextInPool(nullptr) {
     ArgsUnion PVal(Parm);
     memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
     new (&getAvailabilitySlot(IntroducedSlot)) AvailabilityChange(introduced);
@@ -245,6 +248,26 @@
     AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
   }
 
+  /// Constructor for objc_bridge_related attributes.
+  AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
+                IdentifierInfo *scopeName, SourceLocation scopeLoc,
+                IdentifierLoc *Parm1,
+                IdentifierLoc *Parm2,
+                IdentifierLoc *Parm3,
+                Syntax syntaxUsed)
+  : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
+    ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(3), SyntaxUsed(syntaxUsed),
+    Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
+    IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
+    NextInPosition(nullptr), NextInPool(nullptr) {
+    ArgsVector Args;
+    Args.push_back(Parm1);
+    Args.push_back(Parm2);
+    Args.push_back(Parm3);
+    memcpy(getArgsBuffer(), &Args[0], 3 * sizeof(ArgsUnion));
+    AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
+  }
+  
   /// Constructor for type_tag_for_datatype attribute.
   AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
                 IdentifierInfo *scopeName, SourceLocation scopeLoc,
@@ -254,7 +277,7 @@
       ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed),
       Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
       IsTypeTagForDatatype(true), IsProperty(false), HasParsedType(false),
-      NextInPosition(NULL), NextInPool(NULL) {
+      NextInPosition(nullptr), NextInPool(nullptr) {
     ArgsUnion PVal(ArgKind);
     memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
     TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot();
@@ -272,7 +295,7 @@
         ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed),
         Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
         IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(true),
-        NextInPosition(0), NextInPool(0) {
+        NextInPosition(nullptr), NextInPool(nullptr) {
     new (&getTypeBuffer()) ParsedType(typeArg);
     AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
   }
@@ -286,7 +309,7 @@
       ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed),
       Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
       IsTypeTagForDatatype(false), IsProperty(true), HasParsedType(false),
-      NextInPosition(0), NextInPool(0) {
+      NextInPosition(nullptr), NextInPool(nullptr) {
     new (&getPropertyDataBuffer()) PropertyData(getterId, setterId);
     AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
   }
@@ -368,44 +391,6 @@
     return getArg(Arg).get<IdentifierLoc*>();
   }
 
-  class arg_iterator {
-    ArgsUnion const *X;
-    unsigned Idx;
-  public:
-    arg_iterator(ArgsUnion const *x, unsigned idx) : X(x), Idx(idx) {}
-
-    arg_iterator& operator++() {
-      ++Idx;
-      return *this;
-    }
-
-    bool operator==(const arg_iterator& I) const {
-      assert (X == I.X &&
-              "compared arg_iterators are for different argument lists");
-      return Idx == I.Idx;
-    }
-
-    bool operator!=(const arg_iterator& I) const {
-      return !operator==(I);
-    }
-
-    ArgsUnion operator*() const {
-      return X[Idx];
-    }
-
-    unsigned getArgNum() const {
-      return Idx+1;
-    }
-  };
-
-  arg_iterator arg_begin() const {
-    return arg_iterator(getArgsBuffer(), 0);
-  }
-
-  arg_iterator arg_end() const {
-    return arg_iterator(getArgsBuffer(), NumArgs);
-  }
-
   const AvailabilityChange &getAvailabilityIntroduced() const {
     assert(getKind() == AT_Availability && "Not an availability attribute");
     return getAvailabilitySlot(IntroducedSlot);
@@ -464,9 +449,23 @@
   /// to pretty print itself.
   unsigned getAttributeSpellingListIndex() const;
 
+  bool isTargetSpecificAttr() const;
+  bool isTypeAttr() const;
+
   bool hasCustomParsing() const;
   unsigned getMinArgs() const;
   unsigned getMaxArgs() const;
+  bool diagnoseAppertainsTo(class Sema &S, const Decl *D) const;
+  bool diagnoseLangOpts(class Sema &S) const;
+  bool existsInTarget(const llvm::Triple &T) const;
+  bool isKnownToGCC() const;
+
+  /// \brief If the parsed attribute has a semantic equivalent, and it would
+  /// have a semantic Spelling enumeration (due to having semantically-distinct
+  /// spelling variations), return the value of that semantic spelling. If the
+  /// parsed attribute does not have a semantic equivalent, or would not have
+  /// a Spelling enumeration, the value UINT_MAX is returned.
+  unsigned getSemanticSpelling() const;
 };
 
 /// A factory, from which one makes pools, from which one creates
@@ -549,11 +548,11 @@
 
 public:
   /// Create a new pool for a factory.
-  AttributePool(AttributeFactory &factory) : Factory(factory), Head(0) {}
+  AttributePool(AttributeFactory &factory) : Factory(factory), Head(nullptr) {}
 
   /// Move the given pool's allocations to this pool.
   AttributePool(AttributePool &pool) : Factory(pool.Factory), Head(pool.Head) {
-    pool.Head = 0;
+    pool.Head = nullptr;
   }
 
   AttributeFactory &getFactory() const { return Factory; }
@@ -561,7 +560,7 @@
   void clear() {
     if (Head) {
       Factory.reclaimPool(Head);
-      Head = 0;
+      Head = nullptr;
     }
   }
 
@@ -569,7 +568,7 @@
   void takeAllFrom(AttributePool &pool) {
     if (pool.Head) {
       takePool(pool.Head);
-      pool.Head = 0;
+      pool.Head = nullptr;
     }
   }
 
@@ -607,8 +606,19 @@
                                           syntax));
   }
 
-  AttributeList *createIntegerAttribute(ASTContext &C, IdentifierInfo *Name,
-                                        SourceLocation TokLoc, int Arg);
+  AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
+                        IdentifierInfo *scopeName, SourceLocation scopeLoc,
+                        IdentifierLoc *Param1,
+                        IdentifierLoc *Param2,
+                        IdentifierLoc *Param3,
+                        AttributeList::Syntax syntax) {
+    size_t size = sizeof(AttributeList) + 3 * sizeof(ArgsUnion);
+    void *memory = allocate(size);
+    return add(new (memory) AttributeList(attrName, attrRange,
+                                          scopeName, scopeLoc,
+                                          Param1, Param2, Param3,
+                                          syntax));
+  }
 
   AttributeList *createTypeTagForDatatype(
                     IdentifierInfo *attrName, SourceRange attrRange,
@@ -647,40 +657,6 @@
   }
 };
 
-/// addAttributeLists - Add two AttributeLists together
-/// The right-hand list is appended to the left-hand list, if any
-/// A pointer to the joined list is returned.
-/// Note: the lists are not left unmodified.
-inline AttributeList *addAttributeLists(AttributeList *Left,
-                                        AttributeList *Right) {
-  if (!Left)
-    return Right;
-
-  AttributeList *next = Left, *prev;
-  do {
-    prev = next;
-    next = next->getNext();
-  } while (next);
-  prev->setNext(Right);
-  return Left;
-}
-
-/// CXX11AttributeList - A wrapper around a C++11 attribute list.
-/// Stores, in addition to the list proper, whether or not an actual list was
-/// (as opposed to an empty list, which may be ill-formed in some places) and
-/// the source range of the list.
-struct CXX11AttributeList { 
-  AttributeList *AttrList;
-  SourceRange Range;
-  bool HasAttr;
-  CXX11AttributeList (AttributeList *attrList, SourceRange range, bool hasAttr)
-    : AttrList(attrList), Range(range), HasAttr (hasAttr) {
-  }
-  CXX11AttributeList ()
-    : AttrList(0), Range(), HasAttr(false) {
-  }
-};
-
 /// ParsedAttributes - A collection of parsed attributes.  Currently
 /// we don't differentiate between the various attribute syntaxes,
 /// which is basically silly.
@@ -690,21 +666,18 @@
 class ParsedAttributes {
 public:
   ParsedAttributes(AttributeFactory &factory)
-    : pool(factory), list(0) {
+    : pool(factory), list(nullptr) {
   }
 
-  ParsedAttributes(ParsedAttributes &attrs)
-    : pool(attrs.pool), list(attrs.list) {
-    attrs.list = 0;
-  }
+  ParsedAttributes(const ParsedAttributes &) LLVM_DELETED_FUNCTION;
 
   AttributePool &getPool() const { return pool; }
 
-  bool empty() const { return list == 0; }
+  bool empty() const { return list == nullptr; }
 
   void add(AttributeList *newAttr) {
     assert(newAttr);
-    assert(newAttr->getNext() == 0);
+    assert(newAttr->getNext() == nullptr);
     newAttr->setNext(list);
     list = newAttr;
   }
@@ -726,11 +699,11 @@
 
   void takeAllFrom(ParsedAttributes &attrs) {
     addAll(attrs.list);
-    attrs.list = 0;
+    attrs.list = nullptr;
     pool.takeAllFrom(attrs.pool);
   }
 
-  void clear() { list = 0; pool.clear(); }
+  void clear() { list = nullptr; pool.clear(); }
   AttributeList *getList() const { return list; }
 
   /// Returns a reference to the attribute list.  Try not to introduce
@@ -767,6 +740,20 @@
     return attr;
   }
 
+  /// Add objc_bridge_related attribute.
+  AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
+                        IdentifierInfo *scopeName, SourceLocation scopeLoc,
+                        IdentifierLoc *Param1,
+                        IdentifierLoc *Param2,
+                        IdentifierLoc *Param3,
+                        AttributeList::Syntax syntax) {
+    AttributeList *attr =
+      pool.create(attrName, attrRange, scopeName, scopeLoc,
+                  Param1, Param2, Param3, syntax);
+    add(attr);
+    return attr;
+  }
+
   /// Add type_tag_for_datatype attribute.
   AttributeList *addNewTypeTagForDatatype(
                         IdentifierInfo *attrName, SourceRange attrRange,
@@ -808,15 +795,6 @@
     return attr;
   }
 
-  AttributeList *addNewInteger(ASTContext &C, IdentifierInfo *name,
-                               SourceLocation loc, int arg) {
-    AttributeList *attr =
-      pool.createIntegerAttribute(C, name, loc, arg);
-    add(attr);
-    return attr;
-  }
-
-
 private:
   mutable AttributePool pool;
   AttributeList *list;
@@ -831,6 +809,42 @@
   AANT_ArgumentIdentifier
 };
 
+/// These constants match the enumerated choices of
+/// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type.
+enum AttributeDeclKind {
+  ExpectedFunction,
+  ExpectedUnion,
+  ExpectedVariableOrFunction,
+  ExpectedFunctionOrMethod,
+  ExpectedParameter,
+  ExpectedFunctionMethodOrBlock,
+  ExpectedFunctionMethodOrClass,
+  ExpectedFunctionMethodOrParameter,
+  ExpectedClass,
+  ExpectedVariable,
+  ExpectedMethod,
+  ExpectedVariableFunctionOrLabel,
+  ExpectedFieldOrGlobalVar,
+  ExpectedStruct,
+  ExpectedVariableFunctionOrTag,
+  ExpectedTLSVar,
+  ExpectedVariableOrField,
+  ExpectedVariableFieldOrTag,
+  ExpectedTypeOrNamespace,
+  ExpectedObjectiveCInterface,
+  ExpectedMethodOrProperty,
+  ExpectedStructOrUnion,
+  ExpectedStructOrUnionOrClass,
+  ExpectedType,
+  ExpectedObjCInstanceMethod,
+  ExpectedObjCInterfaceDeclInitMethod,
+  ExpectedFunctionVariableOrClass,
+  ExpectedObjectiveCProtocol,
+  ExpectedFunctionGlobalVarMethodOrProperty,
+  ExpectedStructOrTypedef,
+  ExpectedObjectiveCInterfaceOrProtocol
+};
+
 }  // end namespace clang
 
 #endif
diff --git a/include/clang/Sema/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h
index 64de82c..92a4e9a 100644
--- a/include/clang/Sema/CodeCompleteConsumer.h
+++ b/include/clang/Sema/CodeCompleteConsumer.h
@@ -397,7 +397,7 @@
       CodeCompletionString *Optional;
     };
 
-    Chunk() : Kind(CK_Text), Text(0) { }
+    Chunk() : Kind(CK_Text), Text(nullptr) { }
 
     explicit Chunk(ChunkKind Kind, const char *Text = "");
 
@@ -575,14 +575,14 @@
                         CodeCompletionTUInfo &CCTUInfo)
     : Allocator(Allocator), CCTUInfo(CCTUInfo),
       Priority(0), Availability(CXAvailability_Available),
-      BriefComment(NULL) { }
+      BriefComment(nullptr) { }
 
   CodeCompletionBuilder(CodeCompletionAllocator &Allocator,
                         CodeCompletionTUInfo &CCTUInfo,
                         unsigned Priority, CXAvailabilityKind Availability)
     : Allocator(Allocator), CCTUInfo(CCTUInfo),
       Priority(Priority), Availability(Availability),
-      BriefComment(NULL) { }
+      BriefComment(nullptr) { }
 
   /// \brief Retrieve the allocator into which the code completion
   /// strings should be allocated.
@@ -700,7 +700,7 @@
   /// \brief Build a result that refers to a declaration.
   CodeCompletionResult(const NamedDecl *Declaration,
                        unsigned Priority,
-                       NestedNameSpecifier *Qualifier = 0,
+                       NestedNameSpecifier *Qualifier = nullptr,
                        bool QualifierIsInformative = false,
                        bool Accessible = true)
     : Declaration(Declaration), Priority(Priority),
@@ -714,36 +714,34 @@
 
   /// \brief Build a result that refers to a keyword or symbol.
   CodeCompletionResult(const char *Keyword, unsigned Priority = CCP_Keyword)
-    : Declaration(0), Keyword(Keyword), Priority(Priority), StartParameter(0),
-      Kind(RK_Keyword), CursorKind(CXCursor_NotImplemented),
+    : Declaration(nullptr), Keyword(Keyword), Priority(Priority),
+      StartParameter(0), Kind(RK_Keyword), CursorKind(CXCursor_NotImplemented),
       Availability(CXAvailability_Available), Hidden(false),
       QualifierIsInformative(0), StartsNestedNameSpecifier(false),
-      AllParametersAreInformative(false), DeclaringEntity(false), Qualifier(0)
-  {
-  }
+      AllParametersAreInformative(false), DeclaringEntity(false),
+      Qualifier(nullptr) {}
 
   /// \brief Build a result that refers to a macro.
   CodeCompletionResult(const IdentifierInfo *Macro,
                        unsigned Priority = CCP_Macro)
-    : Declaration(0), Macro(Macro), Priority(Priority), StartParameter(0),
+    : Declaration(nullptr), Macro(Macro), Priority(Priority), StartParameter(0),
       Kind(RK_Macro), CursorKind(CXCursor_MacroDefinition),
       Availability(CXAvailability_Available), Hidden(false),
       QualifierIsInformative(0), StartsNestedNameSpecifier(false),
-      AllParametersAreInformative(false), DeclaringEntity(false), Qualifier(0)
-  {
-  }
+      AllParametersAreInformative(false), DeclaringEntity(false),
+      Qualifier(nullptr) {}
 
   /// \brief Build a result that refers to a pattern.
   CodeCompletionResult(CodeCompletionString *Pattern,
                        unsigned Priority = CCP_CodePattern,
                        CXCursorKind CursorKind = CXCursor_NotImplemented,
                    CXAvailabilityKind Availability = CXAvailability_Available,
-                       const NamedDecl *D = 0)
+                       const NamedDecl *D = nullptr)
     : Declaration(D), Pattern(Pattern), Priority(Priority), StartParameter(0),
       Kind(RK_Pattern), CursorKind(CursorKind), Availability(Availability),
       Hidden(false), QualifierIsInformative(0),
       StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
-      DeclaringEntity(false), Qualifier(0)
+      DeclaringEntity(false), Qualifier(nullptr)
   {
   }
 
@@ -754,7 +752,8 @@
     : Declaration(D), Pattern(Pattern), Priority(Priority), StartParameter(0),
       Kind(RK_Pattern), Availability(CXAvailability_Available), Hidden(false),
       QualifierIsInformative(false), StartsNestedNameSpecifier(false),
-      AllParametersAreInformative(false), DeclaringEntity(false), Qualifier(0) {
+      AllParametersAreInformative(false), DeclaringEntity(false),
+      Qualifier(nullptr) {
     computeCursorKindAndAvailability();
   }  
   
@@ -966,20 +965,19 @@
       CCTUInfo(new GlobalCodeCompletionAllocator) {}
 
   /// \brief Prints the finalized code-completion results.
-  virtual void ProcessCodeCompleteResults(Sema &S,
-                                          CodeCompletionContext Context,
-                                          CodeCompletionResult *Results,
-                                          unsigned NumResults);
+  void ProcessCodeCompleteResults(Sema &S, CodeCompletionContext Context,
+                                  CodeCompletionResult *Results,
+                                  unsigned NumResults) override;
 
-  virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
-                                         OverloadCandidate *Candidates,
-                                         unsigned NumCandidates);
+  void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
+                                 OverloadCandidate *Candidates,
+                                 unsigned NumCandidates) override;
 
-  virtual CodeCompletionAllocator &getAllocator() {
+  CodeCompletionAllocator &getAllocator() override {
     return CCTUInfo.getAllocator();
   }
 
-  virtual CodeCompletionTUInfo &getCodeCompletionTUInfo() { return CCTUInfo; }
+  CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo; }
 };
 
 } // end namespace clang
diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h
index 9e1511d..8364dfc 100644
--- a/include/clang/Sema/DeclSpec.h
+++ b/include/clang/Sema/DeclSpec.h
@@ -178,9 +178,9 @@
   bool isNotEmpty() const { return !isEmpty(); }
 
   /// An error occurred during parsing of the scope specifier.
-  bool isInvalid() const { return isNotEmpty() && getScopeRep() == 0; }
+  bool isInvalid() const { return isNotEmpty() && getScopeRep() == nullptr; }
   /// A scope specifier is present, and it refers to a real scope.
-  bool isValid() const { return isNotEmpty() && getScopeRep() != 0; }
+  bool isValid() const { return isNotEmpty() && getScopeRep() != nullptr; }
 
   /// \brief Indicate that this nested-name-specifier is invalid.
   void SetInvalid(SourceRange R) { 
@@ -193,7 +193,7 @@
   
   /// Deprecated.  Some call sites intend isNotEmpty() while others intend
   /// isValid().
-  bool isSet() const { return getScopeRep() != 0; }
+  bool isSet() const { return getScopeRep() != nullptr; }
 
   void clear() {
     Range = SourceRange();
@@ -285,14 +285,6 @@
   static const TST TST_auto = clang::TST_auto;
   static const TST TST_unknown_anytype = clang::TST_unknown_anytype;
   static const TST TST_atomic = clang::TST_atomic;
-  static const TST TST_image1d_t = clang::TST_image1d_t;
-  static const TST TST_image1d_array_t = clang::TST_image1d_array_t;
-  static const TST TST_image1d_buffer_t = clang::TST_image1d_buffer_t;
-  static const TST TST_image2d_t = clang::TST_image2d_t;
-  static const TST TST_image2d_array_t = clang::TST_image2d_array_t;
-  static const TST TST_image3d_t = clang::TST_image3d_t;
-  static const TST TST_sampler_t = clang::TST_sampler_t;
-  static const TST TST_event_t = clang::TST_event_t;
   static const TST TST_error = clang::TST_error;
 
   // type-qualifiers
@@ -428,11 +420,11 @@
       Friend_specified(false),
       Constexpr_specified(false),
       Attrs(attrFactory),
-      ProtocolQualifiers(0),
+      ProtocolQualifiers(nullptr),
       NumProtocolQualifiers(0),
-      ProtocolLocs(0),
+      ProtocolLocs(nullptr),
       writtenBS(),
-      ObjCQualifiers(0) {
+      ObjCQualifiers(nullptr) {
   }
   ~DeclSpec() {
     delete [] ProtocolQualifiers;
@@ -461,6 +453,12 @@
     ThreadStorageClassSpecLoc  = SourceLocation();
   }
 
+  void ClearTypeSpecType() {
+    TypeSpecType = DeclSpec::TST_unspecified;
+    TypeSpecOwned = false;
+    TSTLoc = SourceLocation();
+  }
+
   // type-specifier
   TSW getTypeSpecWidth() const { return (TSW)TypeSpecWidth; }
   TSC getTypeSpecComplex() const { return (TSC)TypeSpecComplex; }
@@ -507,8 +505,11 @@
     return TypeSpecType == TST_auto || TypeSpecType == TST_decltype_auto;
   }
 
+  bool hasTagDefinition() const;
+
   /// \brief Turn a type-specifier-type into a string like "_Bool" or "union".
-  static const char *getSpecifierName(DeclSpec::TST T);
+  static const char *getSpecifierName(DeclSpec::TST T,
+                                      const PrintingPolicy &Policy);
   static const char *getSpecifierName(DeclSpec::TQ Q);
   static const char *getSpecifierName(DeclSpec::TSS S);
   static const char *getSpecifierName(DeclSpec::TSC C);
@@ -596,36 +597,45 @@
   /// TODO: use a more general approach that still allows these
   /// diagnostics to be ignored when desired.
   bool SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc,
-                           const char *&PrevSpec, unsigned &DiagID);
+                           const char *&PrevSpec, unsigned &DiagID,
+                           const PrintingPolicy &Policy);
   bool SetStorageClassSpecThread(TSCS TSC, SourceLocation Loc,
                                  const char *&PrevSpec, unsigned &DiagID);
   bool SetTypeSpecWidth(TSW W, SourceLocation Loc, const char *&PrevSpec,
-                        unsigned &DiagID);
+                        unsigned &DiagID, const PrintingPolicy &Policy);
   bool SetTypeSpecComplex(TSC C, SourceLocation Loc, const char *&PrevSpec,
                           unsigned &DiagID);
   bool SetTypeSpecSign(TSS S, SourceLocation Loc, const char *&PrevSpec,
                        unsigned &DiagID);
   bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec,
-                       unsigned &DiagID);
+                       unsigned &DiagID, const PrintingPolicy &Policy);
   bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec,
-                       unsigned &DiagID, ParsedType Rep);
+                       unsigned &DiagID, ParsedType Rep,
+                       const PrintingPolicy &Policy);
   bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec,
-                       unsigned &DiagID, Decl *Rep, bool Owned);
+                       unsigned &DiagID, Decl *Rep, bool Owned,
+                       const PrintingPolicy &Policy);
   bool SetTypeSpecType(TST T, SourceLocation TagKwLoc,
                        SourceLocation TagNameLoc, const char *&PrevSpec,
-                       unsigned &DiagID, ParsedType Rep);
+                       unsigned &DiagID, ParsedType Rep,
+                       const PrintingPolicy &Policy);
   bool SetTypeSpecType(TST T, SourceLocation TagKwLoc,
                        SourceLocation TagNameLoc, const char *&PrevSpec,
-                       unsigned &DiagID, Decl *Rep, bool Owned);
+                       unsigned &DiagID, Decl *Rep, bool Owned,
+                       const PrintingPolicy &Policy);
 
   bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec,
-                       unsigned &DiagID, Expr *Rep);
+                       unsigned &DiagID, Expr *Rep,
+                       const PrintingPolicy &policy);
   bool SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc,
-                       const char *&PrevSpec, unsigned &DiagID);
+                       const char *&PrevSpec, unsigned &DiagID,
+                       const PrintingPolicy &Policy);
   bool SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc,
-                       const char *&PrevSpec, unsigned &DiagID);
+                       const char *&PrevSpec, unsigned &DiagID,
+                       const PrintingPolicy &Policy);
   bool SetTypeAltiVecBool(bool isAltiVecBool, SourceLocation Loc,
-                       const char *&PrevSpec, unsigned &DiagID);
+                       const char *&PrevSpec, unsigned &DiagID,
+                       const PrintingPolicy &Policy);
   bool SetTypeSpecError();
   void UpdateDeclRep(Decl *Rep) {
     assert(isDeclRep((TST) TypeSpecType));
@@ -699,22 +709,12 @@
   void addAttributes(AttributeList *AL) {
     Attrs.addAll(AL);
   }
-  void setAttributes(AttributeList *AL) {
-    Attrs.set(AL);
-  }
 
   bool hasAttributes() const { return !Attrs.empty(); }
 
   ParsedAttributes &getAttributes() { return Attrs; }
   const ParsedAttributes &getAttributes() const { return Attrs; }
 
-  /// \brief Return the current attribute list and remove them from
-  /// the DeclSpec so that it doesn't own them.
-  ParsedAttributes takeAttributes() {
-    // The non-const "copy" constructor clears the operand automatically.
-    return Attrs;
-  }
-
   void takeAttributesFrom(ParsedAttributes &attrs) {
     Attrs.takeAllFrom(attrs);
   }
@@ -735,7 +735,8 @@
   /// Finish - This does final analysis of the declspec, issuing diagnostics for
   /// things like "_Imaginary" (lacking an FP type).  After calling this method,
   /// DeclSpec is guaranteed self-consistent, even if an error occurred.
-  void Finish(DiagnosticsEngine &D, Preprocessor &PP);
+  void Finish(DiagnosticsEngine &D, Preprocessor &PP,
+              const PrintingPolicy &Policy);
 
   const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const {
     return writtenBS;
@@ -790,7 +791,7 @@
 
   ObjCDeclSpec()
     : objcDeclQualifier(DQ_None), PropertyAttributes(DQ_PR_noattr),
-      GetterName(0), SetterName(0) { }
+      GetterName(nullptr), SetterName(nullptr) { }
   ObjCDeclQualifier getObjCDeclQualifier() const { return objcDeclQualifier; }
   void setObjCDeclQualifier(ObjCDeclQualifier DQVal) {
     objcDeclQualifier = (ObjCDeclQualifier) (objcDeclQualifier | DQVal);
@@ -813,15 +814,15 @@
   void setSetterName(IdentifierInfo *name) { SetterName = name; }
 
 private:
-  // FIXME: These two are unrelated and mutially exclusive. So perhaps
-  // we can put them in a union to reflect their mutual exclusiveness
+  // FIXME: These two are unrelated and mutually exclusive. So perhaps
+  // we can put them in a union to reflect their mutual exclusivity
   // (space saving is negligible).
   ObjCDeclQualifier objcDeclQualifier : 6;
 
   // NOTE: VC++ treats enums as signed, avoid using ObjCPropertyAttributeKind
   unsigned PropertyAttributes : 12;
-  IdentifierInfo *GetterName;    // getter name of NULL if no getter
-  IdentifierInfo *SetterName;    // setter name of NULL if no setter
+  IdentifierInfo *GetterName;    // getter name or NULL if no getter
+  IdentifierInfo *SetterName;    // setter name or NULL if no setter
 };
 
 /// \brief Represents a C++ unqualified-id that has been parsed. 
@@ -904,13 +905,13 @@
   /// \brief The location of the last token that describes this unqualified-id.
   SourceLocation EndLocation;
   
-  UnqualifiedId() : Kind(IK_Identifier), Identifier(0) { }
+  UnqualifiedId() : Kind(IK_Identifier), Identifier(nullptr) { }
 
   /// \brief Clear out this unqualified-id, setting it to default (invalid) 
   /// state.
   void clear() {
     Kind = IK_Identifier;
-    Identifier = 0;
+    Identifier = nullptr;
     StartLocation = SourceLocation();
     EndLocation = SourceLocation();
   }
@@ -1104,7 +1105,8 @@
   };
 
   /// ParamInfo - An array of paraminfo objects is allocated whenever a function
-  /// declarator is parsed.  There are two interesting styles of arguments here:
+  /// declarator is parsed.  There are two interesting styles of parameters
+  /// here:
   /// K&R-style identifier lists and parameter type lists.  K&R-style identifier
   /// lists will have information about the identifier, but no type information.
   /// Parameter type lists will have type info (if the actions module provides
@@ -1124,7 +1126,7 @@
     ParamInfo() {}
     ParamInfo(IdentifierInfo *ident, SourceLocation iloc,
               Decl *param,
-              CachedTokens *DefArgTokens = 0)
+              CachedTokens *DefArgTokens = nullptr)
       : Ident(ident), IdentLoc(iloc), Param(param),
         DefaultArgTokens(DefArgTokens) {}
   };
@@ -1136,7 +1138,7 @@
 
   struct FunctionTypeInfo : TypeInfoCommon {
     /// hasPrototype - This is true if the function had at least one typed
-    /// argument.  If the function is () or (a,b,c), then it has no prototype,
+    /// parameter.  If the function is () or (a,b,c), then it has no prototype,
     /// and is treated as a K&R-style function.
     unsigned hasPrototype : 1;
 
@@ -1159,8 +1161,8 @@
     /// ExceptionSpecType - An ExceptionSpecificationType value.
     unsigned ExceptionSpecType : 3;
 
-    /// DeleteArgInfo - If this is true, we need to delete[] ArgInfo.
-    unsigned DeleteArgInfo : 1;
+    /// DeleteParams - If this is true, we need to delete[] Params.
+    unsigned DeleteParams : 1;
 
     /// HasTrailingReturnType - If this is true, a trailing return type was
     /// specified.
@@ -1175,9 +1177,9 @@
     /// The location of the right parenthesis in the source.
     unsigned RParenLoc;
 
-    /// NumArgs - This is the number of formal arguments provided for the
+    /// NumParams - This is the number of formal parameters specified by the
     /// declarator.
-    unsigned NumArgs;
+    unsigned NumParams;
 
     /// NumExceptions - This is the number of types in the dynamic-exception-
     /// decl, if the function has one.
@@ -1205,10 +1207,10 @@
     /// \brief The location of the keyword introducing the spec, if any.
     unsigned ExceptionSpecLoc;
 
-    /// ArgInfo - This is a pointer to a new[]'d array of ParamInfo objects that
-    /// describe the arguments for this function declarator.  This is null if
-    /// there are no arguments specified.
-    ParamInfo *ArgInfo;
+    /// Params - This is a pointer to a new[]'d array of ParamInfo objects that
+    /// describe the parameters specified by this function declarator.  null if
+    /// there are no parameters specified.
+    ParamInfo *Params;
 
     union {
       /// \brief Pointer to a new[]'d array of TypeAndRange objects that
@@ -1225,30 +1227,32 @@
     /// type specified.
     UnionParsedType TrailingReturnType;
 
-    /// \brief Reset the argument list to having zero arguments.
+    /// \brief Reset the parameter list to having zero parameters.
     ///
     /// This is used in various places for error recovery.
-    void freeArgs() {
-      if (DeleteArgInfo) {
-        delete[] ArgInfo;
-        DeleteArgInfo = false;
+    void freeParams() {
+      for (unsigned I = 0; I < NumParams; ++I) {
+        delete Params[I].DefaultArgTokens;
+        Params[I].DefaultArgTokens = nullptr;
       }
-      NumArgs = 0;
+      if (DeleteParams) {
+        delete[] Params;
+        DeleteParams = false;
+      }
+      NumParams = 0;
     }
 
     void destroy() {
-      if (DeleteArgInfo)
-        delete[] ArgInfo;
+      if (DeleteParams)
+        delete[] Params;
       if (getExceptionSpecType() == EST_Dynamic)
         delete[] Exceptions;
     }
 
     /// isKNRPrototype - Return true if this is a K&R style identifier list,
     /// like "void foo(a,b,c)".  In a function definition, this will be followed
-    /// by the argument type definitions.
-    bool isKNRPrototype() const {
-      return !hasPrototype && NumArgs != 0;
-    }
+    /// by the parameter type definitions.
+    bool isKNRPrototype() const { return !hasPrototype && NumParams != 0; }
 
     SourceLocation getLParenLoc() const {
       return SourceLocation::getFromRawEncoding(LParenLoc);
@@ -1380,7 +1384,7 @@
     I.Ptr.ConstQualLoc    = ConstQualLoc.getRawEncoding();
     I.Ptr.VolatileQualLoc = VolatileQualLoc.getRawEncoding();
     I.Ptr.RestrictQualLoc = RestrictQualLoc.getRawEncoding();
-    I.Ptr.AttrList        = 0;
+    I.Ptr.AttrList        = nullptr;
     return I;
   }
 
@@ -1392,7 +1396,7 @@
     I.Loc             = Loc;
     I.Ref.HasRestrict = (TypeQuals & DeclSpec::TQ_restrict) != 0;
     I.Ref.LValueRef   = lvalue;
-    I.Ref.AttrList    = 0;
+    I.Ref.AttrList    = nullptr;
     return I;
   }
 
@@ -1404,7 +1408,7 @@
     I.Kind          = Array;
     I.Loc           = LBLoc;
     I.EndLoc        = RBLoc;
-    I.Arr.AttrList  = 0;
+    I.Arr.AttrList  = nullptr;
     I.Arr.TypeQuals = TypeQuals;
     I.Arr.hasStatic = isStatic;
     I.Arr.isStar    = isStar;
@@ -1414,10 +1418,10 @@
 
   /// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
   /// "TheDeclarator" is the declarator that this will be added to.
-  static DeclaratorChunk getFunction(bool hasProto,
-                                     bool isAmbiguous,
+  static DeclaratorChunk getFunction(bool HasProto,
+                                     bool IsAmbiguous,
                                      SourceLocation LParenLoc,
-                                     ParamInfo *ArgInfo, unsigned NumArgs,
+                                     ParamInfo *Params, unsigned NumParams,
                                      SourceLocation EllipsisLoc,
                                      SourceLocation RParenLoc,
                                      unsigned TypeQuals,
@@ -1445,7 +1449,7 @@
     I.Kind          = BlockPointer;
     I.Loc           = Loc;
     I.Cls.TypeQuals = TypeQuals;
-    I.Cls.AttrList  = 0;
+    I.Cls.AttrList  = nullptr;
     return I;
   }
 
@@ -1456,7 +1460,7 @@
     I.Kind          = MemberPointer;
     I.Loc           = Loc;
     I.Mem.TypeQuals = TypeQuals;
-    I.Mem.AttrList  = 0;
+    I.Mem.AttrList  = nullptr;
     new (I.Mem.ScopeMem.Mem) CXXScopeSpec(SS);
     return I;
   }
@@ -1468,7 +1472,7 @@
     I.Kind          = Paren;
     I.Loc           = LParenLoc;
     I.EndLoc        = RParenLoc;
-    I.Common.AttrList = 0;
+    I.Common.AttrList = nullptr;
     return I;
   }
 
@@ -1586,7 +1590,7 @@
       InvalidType(DS.getTypeSpecType() == DeclSpec::TST_error),
       GroupingParens(false), FunctionDefinition(FDK_Declaration), 
       Redeclaration(false),
-      Attrs(ds.getAttributePool().getFactory()), AsmLabel(0),
+      Attrs(ds.getAttributePool().getFactory()), AsmLabel(nullptr),
       InlineParamsUsed(false), Extension(false) {
   }
 
@@ -1663,7 +1667,7 @@
       DeclTypeInfo[i].destroy();
     DeclTypeInfo.clear();
     Attrs.clear();
-    AsmLabel = 0;
+    AsmLabel = nullptr;
     InlineParamsUsed = false;
     CommaLoc = SourceLocation();
     EllipsisLoc = SourceLocation();
@@ -1836,7 +1840,7 @@
     if (Name.getKind() == UnqualifiedId::IK_Identifier)
       return Name.Identifier;
     
-    return 0;
+    return nullptr;
   }
   SourceLocation getIdentifierLoc() const { return Name.StartLocation; }
 
@@ -1891,7 +1895,7 @@
       if (!DeclTypeInfo[i].isParen())
         return &DeclTypeInfo[i];
     }
-    return 0;
+    return nullptr;
   }
 
   /// Return the outermost (furthest from the declarator) chunk of
@@ -1902,7 +1906,7 @@
       if (!DeclTypeInfo[i-1].isParen())
         return &DeclTypeInfo[i-1];
     }
-    return 0;
+    return nullptr;
   }
 
   /// isArrayOfUnknownBound - This method returns true if the declarator
@@ -2113,7 +2117,7 @@
   Declarator D;
   Expr *BitfieldSize;
   explicit FieldDeclarator(const DeclSpec &DS)
-    : D(DS, Declarator::MemberContext), BitfieldSize(0) { }
+    : D(DS, Declarator::MemberContext), BitfieldSize(nullptr) { }
 };
 
 /// \brief Represents a C++11 virt-specifier-seq.
@@ -2131,6 +2135,8 @@
   bool SetSpecifier(Specifier VS, SourceLocation Loc,
                     const char *&PrevSpec);
 
+  bool isUnset() const { return Specifiers == 0; }
+
   bool isOverrideSpecified() const { return Specifiers & VS_Override; }
   SourceLocation getOverrideLoc() const { return VS_overrideLoc; }
 
@@ -2151,24 +2157,23 @@
   SourceLocation LastLocation;
 };
 
-/// \brief An individual capture in a lambda introducer.
-struct LambdaCapture {
-  LambdaCaptureKind Kind;
-  SourceLocation Loc;
-  IdentifierInfo *Id;
-  SourceLocation EllipsisLoc;
-  ExprResult Init;
-
-  LambdaCapture(LambdaCaptureKind Kind, SourceLocation Loc,
-                IdentifierInfo* Id = 0,
-                SourceLocation EllipsisLoc = SourceLocation(),
-                ExprResult Init = ExprResult())
-    : Kind(Kind), Loc(Loc), Id(Id), EllipsisLoc(EllipsisLoc), Init(Init)
-  {}
-};
-
 /// \brief Represents a complete lambda introducer.
 struct LambdaIntroducer {
+  /// \brief An individual capture in a lambda introducer.
+  struct LambdaCapture {
+    LambdaCaptureKind Kind;
+    SourceLocation Loc;
+    IdentifierInfo *Id;
+    SourceLocation EllipsisLoc;
+    ExprResult Init;
+    ParsedType InitCaptureType;
+    LambdaCapture(LambdaCaptureKind Kind, SourceLocation Loc,
+                  IdentifierInfo *Id, SourceLocation EllipsisLoc,
+                  ExprResult Init, ParsedType InitCaptureType)
+        : Kind(Kind), Loc(Loc), Id(Id), EllipsisLoc(EllipsisLoc), Init(Init),
+          InitCaptureType(InitCaptureType) {}
+  };
+
   SourceRange Range;
   SourceLocation DefaultLoc;
   LambdaCaptureDefault Default;
@@ -2180,10 +2185,12 @@
   /// \brief Append a capture in a lambda introducer.
   void addCapture(LambdaCaptureKind Kind,
                   SourceLocation Loc,
-                  IdentifierInfo* Id = 0,
-                  SourceLocation EllipsisLoc = SourceLocation(),
-                  ExprResult Init = ExprResult()) {
-    Captures.push_back(LambdaCapture(Kind, Loc, Id, EllipsisLoc, Init));
+                  IdentifierInfo* Id,
+                  SourceLocation EllipsisLoc,
+                  ExprResult Init, 
+                  ParsedType InitCaptureType) {
+    Captures.push_back(LambdaCapture(Kind, Loc, Id, EllipsisLoc, Init, 
+        InitCaptureType));
   }
 };
 
diff --git a/include/clang/Sema/DelayedDiagnostic.h b/include/clang/Sema/DelayedDiagnostic.h
index 4f4a87f..85551f8 100644
--- a/include/clang/Sema/DelayedDiagnostic.h
+++ b/include/clang/Sema/DelayedDiagnostic.h
@@ -113,7 +113,7 @@
 /// the complete parsing of the current declaration.
 class DelayedDiagnostic {
 public:
-  enum DDKind { Deprecation, Access, ForbiddenType };
+  enum DDKind { Deprecation, Unavailable, Access, ForbiddenType };
 
   unsigned char Kind; // actually a DDKind
   bool Triggered;
@@ -122,11 +122,14 @@
 
   void Destroy();
 
-  static DelayedDiagnostic makeDeprecation(SourceLocation Loc,
-           const NamedDecl *D,
-           const ObjCInterfaceDecl *UnknownObjCClass,
-           const ObjCPropertyDecl  *ObjCProperty,
-           StringRef Msg);
+  static DelayedDiagnostic makeAvailability(Sema::AvailabilityDiagnostic AD,
+                                            SourceLocation Loc,
+                                            const NamedDecl *D,
+                                            const ObjCInterfaceDecl *UnknownObjCClass,
+                                            const ObjCPropertyDecl  *ObjCProperty,
+                                            StringRef Msg,
+                                            bool ObjCPropertyAccess);
+
 
   static DelayedDiagnostic makeAccess(SourceLocation Loc,
                                       const AccessedEntity &Entity) {
@@ -162,12 +165,14 @@
   }
 
   const NamedDecl *getDeprecationDecl() const {
-    assert(Kind == Deprecation && "Not a deprecation diagnostic.");
+    assert((Kind == Deprecation || Kind == Unavailable) &&
+           "Not a deprecation diagnostic.");
     return DeprecationData.Decl;
   }
 
   StringRef getDeprecationMessage() const {
-    assert(Kind == Deprecation && "Not a deprecation diagnostic.");
+    assert((Kind == Deprecation || Kind == Unavailable) &&
+           "Not a deprecation diagnostic.");
     return StringRef(DeprecationData.Message,
                            DeprecationData.MessageLen);
   }
@@ -198,6 +203,10 @@
   const ObjCPropertyDecl *getObjCProperty() const {
     return DeprecationData.ObjCProperty;
   }
+    
+  bool getObjCPropertyAccess() const {
+    return DeprecationData.ObjCPropertyAccess;
+  }
   
 private:
 
@@ -207,6 +216,7 @@
     const ObjCPropertyDecl  *ObjCProperty;
     const char *Message;
     size_t MessageLen;
+    bool ObjCPropertyAccess;
   };
 
   struct FTD {
@@ -244,7 +254,7 @@
 
   /// Does this pool, or any of its ancestors, contain any diagnostics?
   bool empty() const {
-    return (Diagnostics.empty() && (Parent == NULL || Parent->empty()));
+    return (Diagnostics.empty() && (!Parent || Parent->empty()));
   }
 
   /// Add a diagnostic to this pool.
@@ -257,7 +267,7 @@
     if (pool.Diagnostics.empty()) return;
 
     if (Diagnostics.empty()) {
-      Diagnostics = llvm_move(pool.Diagnostics);
+      Diagnostics = std::move(pool.Diagnostics);
     } else {
       Diagnostics.append(pool.pool_begin(), pool.pool_end());
     }
diff --git a/include/clang/Sema/IdentifierResolver.h b/include/clang/Sema/IdentifierResolver.h
index 99d94a1..b2404bc 100644
--- a/include/clang/Sema/IdentifierResolver.h
+++ b/include/clang/Sema/IdentifierResolver.h
@@ -150,11 +150,14 @@
   /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
   /// true if 'D' belongs to the given declaration context.
   ///
-  /// \param ExplicitInstantiationOrSpecialization When true, we are checking
-  /// whether the declaration is in scope for the purposes of explicit template
-  /// instantiation or specialization. The default is false.
-  bool isDeclInScope(Decl *D, DeclContext *Ctx, Scope *S = 0,
-                     bool ExplicitInstantiationOrSpecialization = false) const;
+  /// \param AllowInlineNamespace If \c true, we are checking whether a prior
+  ///        declaration is in scope in a declaration that requires a prior
+  ///        declaration (because it is either explicitly qualified or is a
+  ///        template instantiation or specialization). In this case, a
+  ///        declaration is in scope if it's in the inline namespace set of the
+  ///        context.
+  bool isDeclInScope(Decl *D, DeclContext *Ctx, Scope *S = nullptr,
+                     bool AllowInlineNamespace = false) const;
 
   /// AddDecl - Link the decl to its shadowed decl chain.
   void AddDecl(NamedDecl *D);
diff --git a/include/clang/Sema/Initialization.h b/include/clang/Sema/Initialization.h
index 3a1e78d..9f342b2 100644
--- a/include/clang/Sema/Initialization.h
+++ b/include/clang/Sema/Initialization.h
@@ -103,6 +103,9 @@
   /// \brief The type of the object or reference being initialized.
   QualType Type;
 
+  /// \brief The mangling number for the next reference temporary to be created.
+  mutable unsigned ManglingNumber;
+
   struct LN {
     /// \brief When Kind == EK_Result, EK_Exception, EK_New, the
     /// location of the 'return', 'throw', or 'new' keyword,
@@ -116,8 +119,8 @@
   };
 
   struct C {
-    /// \brief The variable being captured by an EK_LambdaCapture.
-    VarDecl *Var;
+    /// \brief The name of the variable being captured by an EK_LambdaCapture.
+    IdentifierInfo *VarID;
 
     /// \brief The source location at which the capture occurs.
     unsigned Location;
@@ -155,19 +158,19 @@
     struct C Capture;
   };
 
-  InitializedEntity() { }
+  InitializedEntity() : ManglingNumber(0) {}
 
   /// \brief Create the initialization entity for a variable.
   InitializedEntity(VarDecl *Var)
-    : Kind(EK_Variable), Parent(0), Type(Var->getType()),
-      VariableOrMember(Var) { }
+    : Kind(EK_Variable), Parent(nullptr), Type(Var->getType()),
+      ManglingNumber(0), VariableOrMember(Var) { }
   
   /// \brief Create the initialization entity for the result of a
   /// function, throwing an object, performing an explicit cast, or
   /// initializing a parameter for which there is no declaration.
   InitializedEntity(EntityKind Kind, SourceLocation Loc, QualType Type,
                     bool NRVO = false)
-    : Kind(Kind), Parent(0), Type(Type)
+    : Kind(Kind), Parent(nullptr), Type(Type), ManglingNumber(0)
   {
     LocAndNRVO.Location = Loc.getRawEncoding();
     LocAndNRVO.NRVO = NRVO;
@@ -176,17 +179,18 @@
   /// \brief Create the initialization entity for a member subobject.
   InitializedEntity(FieldDecl *Member, const InitializedEntity *Parent) 
     : Kind(EK_Member), Parent(Parent), Type(Member->getType()),
-      VariableOrMember(Member) { }
+      ManglingNumber(0), VariableOrMember(Member) { }
   
   /// \brief Create the initialization entity for an array element.
   InitializedEntity(ASTContext &Context, unsigned Index, 
                     const InitializedEntity &Parent);
 
   /// \brief Create the initialization entity for a lambda capture.
-  InitializedEntity(VarDecl *Var, FieldDecl *Field, SourceLocation Loc)
-    : Kind(EK_LambdaCapture), Parent(0), Type(Field->getType()) 
+  InitializedEntity(IdentifierInfo *VarID, QualType FieldType, SourceLocation Loc)
+    : Kind(EK_LambdaCapture), Parent(nullptr), Type(FieldType),
+      ManglingNumber(0)
   {
-    Capture.Var = Var;
+    Capture.VarID = VarID;
     Capture.Location = Loc.getRawEncoding();
   }
   
@@ -214,7 +218,7 @@
     Entity.Kind = EK_Parameter;
     Entity.Type =
       Context.getVariableArrayDecayedType(Type.getUnqualifiedType());
-    Entity.Parent = 0;
+    Entity.Parent = nullptr;
     Entity.Parameter
       = (static_cast<uintptr_t>(Consumed) | reinterpret_cast<uintptr_t>(Parm));
     return Entity;
@@ -228,7 +232,7 @@
     InitializedEntity Entity;
     Entity.Kind = EK_Parameter;
     Entity.Type = Context.getVariableArrayDecayedType(Type);
-    Entity.Parent = 0;
+    Entity.Parent = nullptr;
     Entity.Parameter = (Consumed);
     return Entity;
   }
@@ -258,7 +262,7 @@
   /// \brief Create the initialization entity for a temporary.
   static InitializedEntity InitializeTemporary(QualType Type) {
     InitializedEntity Result(EK_Temporary, SourceLocation(), Type);
-    Result.TypeInfo = 0;
+    Result.TypeInfo = nullptr;
     return Result;
   }
 
@@ -290,14 +294,16 @@
   }
   
   /// \brief Create the initialization entity for a member subobject.
-  static InitializedEntity InitializeMember(FieldDecl *Member,
-                                          const InitializedEntity *Parent = 0) {
+  static InitializedEntity
+  InitializeMember(FieldDecl *Member,
+                   const InitializedEntity *Parent = nullptr) {
     return InitializedEntity(Member, Parent);
   }
   
   /// \brief Create the initialization entity for a member subobject.
-  static InitializedEntity InitializeMember(IndirectFieldDecl *Member,
-                                      const InitializedEntity *Parent = 0) {
+  static InitializedEntity
+  InitializeMember(IndirectFieldDecl *Member,
+                   const InitializedEntity *Parent = nullptr) {
     return InitializedEntity(Member->getAnonField(), Parent);
   }
 
@@ -309,10 +315,10 @@
   }
 
   /// \brief Create the initialization entity for a lambda capture.
-  static InitializedEntity InitializeLambdaCapture(VarDecl *Var,
-                                                   FieldDecl *Field,
+  static InitializedEntity InitializeLambdaCapture(IdentifierInfo *VarID,
+                                                   QualType FieldType,
                                                    SourceLocation Loc) {
-    return InitializedEntity(Var, Field, Loc);
+    return InitializedEntity(VarID, FieldType, Loc);
   }
 
   /// \brief Create the entity for a compound literal initializer.
@@ -341,7 +347,7 @@
     if (Kind == EK_Temporary || Kind == EK_CompoundLiteralInit)
       return TypeInfo;
     
-    return 0;
+    return nullptr;
   }
   
   /// \brief Retrieve the name of the entity being initialized.
@@ -395,6 +401,13 @@
     return SourceLocation::getFromRawEncoding(LocAndNRVO.Location);
   }
 
+  /// \brief If this is an array, vector, or complex number element, get the
+  /// element's index.
+  unsigned getElementIndex() const {
+    assert(getKind() == EK_ArrayElement || getKind() == EK_VectorElement ||
+           getKind() == EK_ComplexElement);
+    return Index;
+  }
   /// \brief If this is already the initializer for an array or vector
   /// element, sets the element index.
   void setElementIndex(unsigned Index) {
@@ -402,13 +415,11 @@
            getKind() == EK_ComplexElement);
     this->Index = Index;
   }
-
-  /// \brief Retrieve the variable for a captured variable in a lambda.
-  VarDecl *getCapturedVar() const {
+  /// \brief For a lambda capture, return the capture's name.
+  StringRef getCapturedVarName() const {
     assert(getKind() == EK_LambdaCapture && "Not a lambda capture!");
-    return Capture.Var;
+    return Capture.VarID->getName();
   }
-  
   /// \brief Determine the location of the capture when initializing
   /// field from a captured variable in a lambda.
   SourceLocation getCaptureLoc() const {
@@ -420,6 +431,8 @@
     Kind = EK_Parameter_CF_Audited;
   }
 
+  unsigned allocateManglingNumber() const { return ++ManglingNumber; }
+
   /// Dump a representation of the initialized entity to standard error,
   /// for debugging purposes.
   void dump() const;
@@ -650,22 +663,25 @@
     SK_QualificationConversionXValue,
     /// \brief Perform a qualification conversion, producing an lvalue.
     SK_QualificationConversionLValue,
+    /// \brief Perform a conversion adding _Atomic to a type.
+    SK_AtomicConversion,
     /// \brief Perform a load from a glvalue, producing an rvalue.
     SK_LValueToRValue,
     /// \brief Perform an implicit conversion sequence.
     SK_ConversionSequence,
     /// \brief Perform an implicit conversion sequence without narrowing.
     SK_ConversionSequenceNoNarrowing,
-    /// \brief Perform list-initialization without a constructor
+    /// \brief Perform list-initialization without a constructor.
     SK_ListInitialization,
-    /// \brief Perform list-initialization with a constructor.
-    SK_ListConstructorCall,
     /// \brief Unwrap the single-element initializer list for a reference.
     SK_UnwrapInitList,
     /// \brief Rewrap the single-element initializer list for a reference.
     SK_RewrapInitList,
     /// \brief Perform initialization via a constructor.
     SK_ConstructorInitialization,
+    /// \brief Perform initialization via a constructor, taking arguments from
+    /// a single InitListExpr.
+    SK_ConstructorInitializationFromList,
     /// \brief Zero-initialize the object
     SK_ZeroInitialization,
     /// \brief C assignment
@@ -689,6 +705,9 @@
     SK_ProduceObjCObject,
     /// \brief Construct a std::initializer_list from an initializer list.
     SK_StdInitializerList,
+    /// \brief Perform initialization via a constructor taking a single
+    /// std::initializer_list argument.
+    SK_StdInitializerListConstructorCall,
     /// \brief Initialize an OpenCL sampler from an integer.
     SK_OCLSamplerInit,
     /// \brief Passing zero to a function where OpenCL event_t is expected.
@@ -845,17 +864,17 @@
   ///
   /// \param Args the argument(s) provided for initialization.
   ///
-  /// \param InInitList true if we are initializing from an expression within
-  ///        an initializer list. This disallows narrowing conversions in C++11
-  ///        onwards.
+  /// \param TopLevelOfInitList true if we are initializing from an expression
+  ///        at the top level inside an initializer list. This disallows
+  ///        narrowing conversions in C++11 onwards.
   InitializationSequence(Sema &S, 
                          const InitializedEntity &Entity,
                          const InitializationKind &Kind,
                          MultiExprArg Args,
-                         bool InInitList = false);
+                         bool TopLevelOfInitList = false);
   void InitializeFrom(Sema &S, const InitializedEntity &Entity,
                       const InitializationKind &Kind, MultiExprArg Args,
-                      bool InInitList);
+                      bool TopLevelOfInitList);
 
   ~InitializationSequence();
   
@@ -884,7 +903,7 @@
                      const InitializedEntity &Entity,
                      const InitializationKind &Kind,
                      MultiExprArg Args,
-                     QualType *ResultType = 0);
+                     QualType *ResultType = nullptr);
   
   /// \brief Diagnose an potentially-invalid initialization sequence.
   ///
@@ -982,7 +1001,11 @@
   /// given type.
   void AddQualificationConversionStep(QualType Ty,
                                      ExprValueKind Category);
-  
+
+  /// \brief Add a new step that performs conversion from non-atomic to atomic
+  /// type.
+  void AddAtomicConversionStep(QualType Ty);
+
   /// \brief Add a new step that performs a load of the given type.
   ///
   /// Although the term "LValueToRValue" is conventional, this applies to both
diff --git a/include/clang/Sema/Lookup.h b/include/clang/Sema/Lookup.h
index 105c879..00cc164 100644
--- a/include/clang/Sema/Lookup.h
+++ b/include/clang/Sema/Lookup.h
@@ -130,8 +130,8 @@
                Sema::LookupNameKind LookupKind,
                Sema::RedeclarationKind Redecl = Sema::NotForRedeclaration)
     : ResultKind(NotFound),
-      Paths(0),
-      NamingClass(0),
+      Paths(nullptr),
+      NamingClass(nullptr),
       SemaRef(SemaRef),
       NameInfo(NameInfo),
       LookupKind(LookupKind),
@@ -152,8 +152,8 @@
                SourceLocation NameLoc, Sema::LookupNameKind LookupKind,
                Sema::RedeclarationKind Redecl = Sema::NotForRedeclaration)
     : ResultKind(NotFound),
-      Paths(0),
-      NamingClass(0),
+      Paths(nullptr),
+      NamingClass(nullptr),
       SemaRef(SemaRef),
       NameInfo(Name, NameLoc),
       LookupKind(LookupKind),
@@ -172,8 +172,8 @@
   /// disabled.
   LookupResult(TemporaryToken _, const LookupResult &Other)
     : ResultKind(NotFound),
-      Paths(0),
-      NamingClass(0),
+      Paths(nullptr),
+      NamingClass(nullptr),
       SemaRef(Other.SemaRef),
       NameInfo(Other.NameInfo),
       LookupKind(Other.LookupKind),
@@ -259,7 +259,7 @@
   }
 
   LookupResultKind getResultKind() const {
-    sanity();
+    assert(sanity());
     return ResultKind;
   }
 
@@ -303,7 +303,7 @@
   /// if there is one.
   NamedDecl *getAcceptableDecl(NamedDecl *D) const {
     if (!D->isInIdentifierNamespace(IDNS))
-      return 0;
+      return nullptr;
 
     if (isHiddenDeclarationVisible() || isVisible(SemaRef, D))
       return D;
@@ -324,7 +324,7 @@
   /// \brief Returns whether these results arose from performing a
   /// lookup into a class.
   bool isClassLookup() const {
-    return NamingClass != 0;
+    return NamingClass != nullptr;
   }
 
   /// \brief Returns the 'naming class' for this lookup, i.e. the
@@ -421,7 +421,7 @@
 
       if (Paths) {
         deletePaths(Paths);
-        Paths = 0;
+        Paths = nullptr;
       }
     } else {
       AmbiguityKind SavedAK = Ambiguity;
@@ -434,14 +434,14 @@
         Ambiguity = SavedAK;
       } else if (Paths) {
         deletePaths(Paths);
-        Paths = 0;
+        Paths = nullptr;
       }
     }
   }
 
   template <class DeclClass>
   DeclClass *getAsSingle() const {
-    if (getResultKind() != Found) return 0;
+    if (getResultKind() != Found) return nullptr;
     return dyn_cast<DeclClass>(getFoundDecl());
   }
 
@@ -491,8 +491,8 @@
     ResultKind = NotFound;
     Decls.clear();
     if (Paths) deletePaths(Paths);
-    Paths = NULL;
-    NamingClass = 0;
+    Paths = nullptr;
+    NamingClass = nullptr;
     Shadowed = false;
   }
 
@@ -637,13 +637,7 @@
   void configure();
 
   // Sanity checks.
-  void sanityImpl() const;
-
-  void sanity() const {
-#ifndef NDEBUG
-    sanityImpl();
-#endif
-  }
+  bool sanity() const;
 
   bool sanityCheckUnresolved() const {
     for (iterator I = begin(), E = end(); I != E; ++I)
diff --git a/include/clang/Sema/LoopHint.h b/include/clang/Sema/LoopHint.h
new file mode 100644
index 0000000..d4b985d
--- /dev/null
+++ b/include/clang/Sema/LoopHint.h
@@ -0,0 +1,40 @@
+//===--- LoopHint.h - Types for LoopHint ------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_LOOPHINT_H
+#define LLVM_CLANG_SEMA_LOOPHINT_H
+
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Sema/AttributeList.h"
+#include "clang/Sema/Ownership.h"
+
+namespace clang {
+
+/// \brief Loop optimization hint for loop and unroll pragmas.
+struct LoopHint {
+  // Source range of the directive.
+  SourceRange Range;
+  // Identifier corresponding to the name of the pragma.  "loop" for
+  // "#pragma clang loop" directives and "unroll" for "#pragma unroll"
+  // hints.
+  IdentifierLoc *PragmaNameLoc;
+  // Name of the loop hint.  Examples: "unroll", "vectorize".  In the
+  // "#pragma unroll" case, this is identical to PragmaNameLoc.
+  IdentifierLoc *OptionLoc;
+  // Identifier for the hint argument.  If null, then the hint has no argument
+  // such as for "#pragma unroll".
+  IdentifierLoc *ValueLoc;
+  // Expression for the hint argument if it exists, null otherwise.
+  Expr *ValueExpr;
+};
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_SEMA_LOOPHINT_H
diff --git a/include/clang/Sema/MultiplexExternalSemaSource.h b/include/clang/Sema/MultiplexExternalSemaSource.h
index e9ba479..7860b6d 100644
--- a/include/clang/Sema/MultiplexExternalSemaSource.h
+++ b/include/clang/Sema/MultiplexExternalSemaSource.h
@@ -65,31 +65,35 @@
 
   /// \brief Resolve a declaration ID into a declaration, potentially
   /// building a new declaration.
-  virtual Decl *GetExternalDecl(uint32_t ID);
+  Decl *GetExternalDecl(uint32_t ID) override;
+
+  /// \brief Complete the redeclaration chain if it's been extended since the
+  /// previous generation of the AST source.
+  void CompleteRedeclChain(const Decl *D) override;
 
   /// \brief Resolve a selector ID into a selector.
-  virtual Selector GetExternalSelector(uint32_t ID);
+  Selector GetExternalSelector(uint32_t ID) override;
 
   /// \brief Returns the number of selectors known to the external AST
   /// source.
-  virtual uint32_t GetNumExternalSelectors();
+  uint32_t GetNumExternalSelectors() override;
 
   /// \brief Resolve the offset of a statement in the decl stream into
   /// a statement.
-  virtual Stmt *GetExternalDeclStmt(uint64_t Offset);
+  Stmt *GetExternalDeclStmt(uint64_t Offset) override;
 
   /// \brief Resolve the offset of a set of C++ base specifiers in the decl
   /// stream into an array of specifiers.
-  virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset);
+  CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset) override;
 
   /// \brief Find all declarations with the given name in the
   /// given context.
-  virtual bool
-  FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name);
+  bool
+  FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name) override;
 
   /// \brief Ensures that the table of all visible declarations inside this
   /// context is up to date.
-  virtual void completeVisibleDeclsMap(const DeclContext *DC);
+  void completeVisibleDeclsMap(const DeclContext *DC) override;
 
   /// \brief Finds all declarations lexically contained within the given
   /// DeclContext, after applying an optional filter predicate.
@@ -99,9 +103,9 @@
   /// are returned.
   ///
   /// \return an indication of whether the load succeeded or failed.
-  virtual ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
-                                        bool (*isKindWeWant)(Decl::Kind),
-                                        SmallVectorImpl<Decl*> &Result);
+  ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
+                                bool (*isKindWeWant)(Decl::Kind),
+                                SmallVectorImpl<Decl*> &Result) override;
 
   /// \brief Finds all declarations lexically contained within the given
   /// DeclContext.
@@ -109,7 +113,7 @@
   /// \return true if an error occurred
   ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
                                 SmallVectorImpl<Decl*> &Result) {
-    return FindExternalLexicalDecls(DC, 0, Result);
+    return FindExternalLexicalDecls(DC, nullptr, Result);
   }
 
   template <typename DeclTy>
@@ -121,12 +125,12 @@
   /// \brief Get the decls that are contained in a file in the Offset/Length
   /// range. \p Length can be 0 to indicate a point at \p Offset instead of
   /// a range. 
-  virtual void FindFileRegionDecls(FileID File, unsigned Offset,unsigned Length,
-                                   SmallVectorImpl<Decl *> &Decls);
+  void FindFileRegionDecls(FileID File, unsigned Offset,unsigned Length,
+                           SmallVectorImpl<Decl *> &Decls) override;
 
   /// \brief Gives the external AST source an opportunity to complete
   /// an incomplete type.
-  virtual void CompleteType(TagDecl *Tag);
+  void CompleteType(TagDecl *Tag) override;
 
   /// \brief Gives the external AST source an opportunity to complete an
   /// incomplete Objective-C class.
@@ -134,27 +138,27 @@
   /// This routine will only be invoked if the "externally completed" bit is
   /// set on the ObjCInterfaceDecl via the function 
   /// \c ObjCInterfaceDecl::setExternallyCompleted().
-  virtual void CompleteType(ObjCInterfaceDecl *Class);
+  void CompleteType(ObjCInterfaceDecl *Class) override;
 
   /// \brief Loads comment ranges.
-  virtual void ReadComments();
+  void ReadComments() override;
 
   /// \brief Notify ExternalASTSource that we started deserialization of
   /// a decl or type so until FinishedDeserializing is called there may be
   /// decls that are initializing. Must be paired with FinishedDeserializing.
-  virtual void StartedDeserializing();
+  void StartedDeserializing() override;
 
   /// \brief Notify ExternalASTSource that we finished the deserialization of
   /// a decl or type. Must be paired with StartedDeserializing.
-  virtual void FinishedDeserializing();
+  void FinishedDeserializing() override;
 
   /// \brief Function that will be invoked when we begin parsing a new
   /// translation unit involving this external AST source.
-  virtual void StartTranslationUnit(ASTConsumer *Consumer);
+  void StartTranslationUnit(ASTConsumer *Consumer) override;
 
   /// \brief Print any statistics that have been gathered regarding
   /// the external AST source.
-  virtual void PrintStats();
+  void PrintStats() override;
   
   
   /// \brief Perform layout on the given record.
@@ -184,16 +188,17 @@
   /// be laid out according to the ABI.
   /// 
   /// \returns true if the record layout was provided, false otherwise.
-  virtual bool 
+  bool
   layoutRecordType(const RecordDecl *Record,
                    uint64_t &Size, uint64_t &Alignment,
                    llvm::DenseMap<const FieldDecl *, uint64_t> &FieldOffsets,
                  llvm::DenseMap<const CXXRecordDecl *, CharUnits> &BaseOffsets,
-          llvm::DenseMap<const CXXRecordDecl *, CharUnits> &VirtualBaseOffsets);
+                 llvm::DenseMap<const CXXRecordDecl *,
+                                CharUnits> &VirtualBaseOffsets) override;
 
   /// Return the amount of memory used by memory buffers, breaking down
   /// by heap-backed versus mmap'ed memory.
-  virtual void getMemoryBufferSizes(MemoryBufferSizes &sizes) const;
+  void getMemoryBufferSizes(MemoryBufferSizes &sizes) const override;
 
   //===--------------------------------------------------------------------===//
   // ExternalSemaSource.
@@ -202,24 +207,25 @@
   /// \brief Initialize the semantic source with the Sema instance
   /// being used to perform semantic analysis on the abstract syntax
   /// tree.
-  virtual void InitializeSema(Sema &S);
+  void InitializeSema(Sema &S) override;
 
   /// \brief Inform the semantic consumer that Sema is no longer available.
-  virtual void ForgetSema();
+  void ForgetSema() override;
 
   /// \brief Load the contents of the global method pool for a given
   /// selector.
-  virtual void ReadMethodPool(Selector Sel);
+  void ReadMethodPool(Selector Sel) override;
 
   /// \brief Load the set of namespaces that are known to the external source,
   /// which will be used during typo correction.
-  virtual void ReadKnownNamespaces(SmallVectorImpl<NamespaceDecl*> &Namespaces);
+  void
+  ReadKnownNamespaces(SmallVectorImpl<NamespaceDecl*> &Namespaces) override;
 
   /// \brief Load the set of used but not defined functions or variables with
   /// internal linkage, or used but not defined inline functions.
-  virtual void ReadUndefinedButUsed(
-                         llvm::DenseMap<NamedDecl*, SourceLocation> &Undefined);
-  
+  void ReadUndefinedButUsed(
+                llvm::DenseMap<NamedDecl*, SourceLocation> &Undefined) override;
+
   /// \brief Do last resort, unqualified lookup on a LookupResult that
   /// Sema cannot find.
   ///
@@ -228,7 +234,7 @@
   /// \param S the Scope of the identifier occurrence.
   ///
   /// \return true to tell Sema to recover using the LookupResult.
-  virtual bool LookupUnqualified(LookupResult &R, Scope *S);
+  bool LookupUnqualified(LookupResult &R, Scope *S) override;
 
   /// \brief Read the set of tentative definitions known to the external Sema
   /// source.
@@ -237,8 +243,8 @@
   /// given vector of tentative definitions. Note that this routine may be
   /// invoked multiple times; the external source should take care not to
   /// introduce the same declarations repeatedly.
-  virtual void ReadTentativeDefinitions(SmallVectorImpl<VarDecl*> &Defs);
-  
+  void ReadTentativeDefinitions(SmallVectorImpl<VarDecl*> &Defs) override;
+
   /// \brief Read the set of unused file-scope declarations known to the
   /// external Sema source.
   ///
@@ -246,9 +252,9 @@
   /// given vector of declarations. Note that this routine may be
   /// invoked multiple times; the external source should take care not to
   /// introduce the same declarations repeatedly.
-  virtual void ReadUnusedFileScopedDecls(
-                                 SmallVectorImpl<const DeclaratorDecl*> &Decls);
-  
+  void ReadUnusedFileScopedDecls(
+                        SmallVectorImpl<const DeclaratorDecl*> &Decls) override;
+
   /// \brief Read the set of delegating constructors known to the
   /// external Sema source.
   ///
@@ -256,8 +262,8 @@
   /// given vector of declarations. Note that this routine may be
   /// invoked multiple times; the external source should take care not to
   /// introduce the same declarations repeatedly.
-  virtual void ReadDelegatingConstructors(
-                                   SmallVectorImpl<CXXConstructorDecl*> &Decls);
+  void ReadDelegatingConstructors(
+                          SmallVectorImpl<CXXConstructorDecl*> &Decls) override;
 
   /// \brief Read the set of ext_vector type declarations known to the
   /// external Sema source.
@@ -266,7 +272,7 @@
   /// the given vector of declarations. Note that this routine may be
   /// invoked multiple times; the external source should take care not to
   /// introduce the same declarations repeatedly.
-  virtual void ReadExtVectorDecls(SmallVectorImpl<TypedefNameDecl*> &Decls);
+  void ReadExtVectorDecls(SmallVectorImpl<TypedefNameDecl*> &Decls) override;
 
   /// \brief Read the set of dynamic classes known to the external Sema source.
   ///
@@ -274,7 +280,7 @@
   /// the given vector of declarations. Note that this routine may be
   /// invoked multiple times; the external source should take care not to
   /// introduce the same declarations repeatedly.
-  virtual void ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl*> &Decls);
+  void ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl*> &Decls) override;
 
   /// \brief Read the set of locally-scoped extern "C" declarations known to the
   /// external Sema source.
@@ -283,7 +289,8 @@
   /// declarations to the given vector of declarations. Note that this routine
   /// may be invoked multiple times; the external source should take care not
   /// to introduce the same declarations repeatedly.
-  virtual void ReadLocallyScopedExternCDecls(SmallVectorImpl<NamedDecl*>&Decls);
+  void ReadLocallyScopedExternCDecls(
+                                   SmallVectorImpl<NamedDecl*> &Decls) override;
 
   /// \brief Read the set of referenced selectors known to the
   /// external Sema source.
@@ -292,8 +299,8 @@
   /// given vector of selectors. Note that this routine 
   /// may be invoked multiple times; the external source should take care not 
   /// to introduce the same selectors repeatedly.
-  virtual void ReadReferencedSelectors(SmallVectorImpl<std::pair<Selector, 
-                                                       SourceLocation> > &Sels);
+  void ReadReferencedSelectors(SmallVectorImpl<std::pair<Selector,
+                                              SourceLocation> > &Sels) override;
 
   /// \brief Read the set of weak, undeclared identifiers known to the
   /// external Sema source.
@@ -302,15 +309,15 @@
   /// the given vector. Note that this routine may be invoked multiple times; 
   /// the external source should take care not to introduce the same identifiers
   /// repeatedly.
-  virtual void ReadWeakUndeclaredIdentifiers(
-                    SmallVectorImpl<std::pair<IdentifierInfo*, WeakInfo> > &WI);
+  void ReadWeakUndeclaredIdentifiers(
+           SmallVectorImpl<std::pair<IdentifierInfo*, WeakInfo> > &WI) override;
 
   /// \brief Read the set of used vtables known to the external Sema source.
   ///
   /// The external source should append its own used vtables to the given
   /// vector. Note that this routine may be invoked multiple times; the external
   /// source should take care not to introduce the same vtables repeatedly.
-  virtual void ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables);
+  void ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables) override;
 
   /// \brief Read the set of pending instantiations known to the external
   /// Sema source.
@@ -319,8 +326,8 @@
   /// given vector. Note that this routine may be invoked multiple times; the
   /// external source should take care not to introduce the same instantiations
   /// repeatedly.
-  virtual void ReadPendingInstantiations(
-              SmallVectorImpl<std::pair<ValueDecl*, SourceLocation> >& Pending);
+  void ReadPendingInstantiations(
+     SmallVectorImpl<std::pair<ValueDecl*, SourceLocation> >& Pending) override;
 
   /// \brief Read the set of late parsed template functions for this source.
   ///
@@ -328,17 +335,18 @@
   /// into the map. Note that this routine may be invoked multiple times; the
   /// external source should take care not to introduce the same map entries
   /// repeatedly.
-  virtual void ReadLateParsedTemplates(
-      llvm::DenseMap<const FunctionDecl *, LateParsedTemplate *> &LPTMap);
+  void ReadLateParsedTemplates(
+                         llvm::DenseMap<const FunctionDecl *,
+                                        LateParsedTemplate *> &LPTMap) override;
 
   /// \copydoc ExternalSemaSource::CorrectTypo
   /// \note Returns the first nonempty correction.
-  virtual TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo,
-                                     int LookupKind, Scope *S, CXXScopeSpec *SS,
-                                     CorrectionCandidateCallback &CCC,
-                                     DeclContext *MemberContext,
-                                     bool EnteringContext,
-                                     const ObjCObjectPointerType *OPT);
+  TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo,
+                             int LookupKind, Scope *S, CXXScopeSpec *SS,
+                             CorrectionCandidateCallback &CCC,
+                             DeclContext *MemberContext,
+                             bool EnteringContext,
+                             const ObjCObjectPointerType *OPT) override;
 
   /// \brief Produces a diagnostic note if one of the attached sources
   /// contains a complete definition for \p T. Queries the sources in list
@@ -350,7 +358,8 @@
   /// \param T the \c QualType that should have been complete at \p Loc
   ///
   /// \return true if a diagnostic was produced, false otherwise.
-  virtual bool MaybeDiagnoseMissingCompleteType(SourceLocation Loc, QualType T);
+  bool MaybeDiagnoseMissingCompleteType(SourceLocation Loc,
+                                        QualType T) override;
 
   // isa/cast/dyn_cast support
   static bool classof(const MultiplexExternalSemaSource*) { return true; }
diff --git a/include/clang/Sema/ObjCMethodList.h b/include/clang/Sema/ObjCMethodList.h
index 94e3807..2003356 100644
--- a/include/clang/Sema/ObjCMethodList.h
+++ b/include/clang/Sema/ObjCMethodList.h
@@ -26,7 +26,7 @@
   /// \brief The next list object and 2 bits for extra info.
   llvm::PointerIntPair<ObjCMethodList *, 2> NextAndExtraBits;
 
-  ObjCMethodList() : Method(0) { }
+  ObjCMethodList() : Method(nullptr) { }
   ObjCMethodList(ObjCMethodDecl *M, ObjCMethodList *C)
     : Method(M), NextAndExtraBits(C, 0) { }
 
diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h
index b8bd14a..7c221a2 100644
--- a/include/clang/Sema/Overload.h
+++ b/include/clang/Sema/Overload.h
@@ -262,7 +262,7 @@
     StandardConversionSequence Before;
 
     /// EllipsisConversion - When this is true, it means user-defined
-    /// conversion sequence starts with a ... (elipsis) conversion, instead of 
+    /// conversion sequence starts with a ... (ellipsis) conversion, instead of
     /// a standard conversion. In this case, 'Before' field must be ignored.
     // FIXME. I much rather put this as the first field. But there seems to be
     // a gcc code gen. bug which causes a crash in a test. Putting it here seems
@@ -339,7 +339,6 @@
     enum FailureKind {
       no_conversion,
       unrelated_class,
-      suppressed_user,
       bad_qualifiers,
       lvalue_ref_to_rvalue,
       rvalue_ref_to_lvalue
@@ -364,7 +363,7 @@
     }
     void init(FailureKind K, QualType From, QualType To) {
       Kind = K;
-      FromExpr = 0;
+      FromExpr = nullptr;
       setFromType(From);
       setToType(To);
     }
@@ -579,7 +578,11 @@
     /// (CUDA) This candidate was not viable because the callee
     /// was not accessible from the caller's target (i.e. host->device,
     /// global->host, device->host).
-    ovl_fail_bad_target
+    ovl_fail_bad_target,
+
+    /// This candidate function was not viable because an enable_if
+    /// attribute disabled it.
+    ovl_fail_enable_if
   };
 
   /// OverloadCandidate - A single candidate in an overload set (C++ 13.3).
@@ -675,11 +678,35 @@
 
       return CanFix;
     }
+
+    unsigned getNumParams() const {
+      if (IsSurrogate) {
+        auto STy = Surrogate->getConversionType();
+        while (STy->isPointerType() || STy->isReferenceType())
+          STy = STy->getPointeeType();
+        return STy->getAs<FunctionProtoType>()->getNumParams();
+      }
+      if (Function)
+        return Function->getNumParams();
+      return ExplicitCallArguments;
+    }
   };
 
   /// OverloadCandidateSet - A set of overload candidates, used in C++
   /// overload resolution (C++ 13.3).
   class OverloadCandidateSet {
+  public:
+    enum CandidateSetKind {
+      /// Normal lookup.
+      CSK_Normal,
+      /// Lookup for candidates for a call using operator syntax. Candidates
+      /// that have no parameters of class type will be skipped unless there
+      /// is a parameter of (reference to) enum type and the corresponding
+      /// argument is of the same enum type.
+      CSK_Operator
+    };
+
+  private:
     SmallVector<OverloadCandidate, 16> Candidates;
     llvm::SmallPtrSet<Decl *, 16> Functions;
 
@@ -688,6 +715,7 @@
     llvm::BumpPtrAllocator ConversionSequenceAllocator;
 
     SourceLocation Loc;
+    CandidateSetKind Kind;
 
     unsigned NumInlineSequences;
     char InlineSpace[16 * sizeof(ImplicitConversionSequence)];
@@ -698,10 +726,12 @@
     void destroyCandidates();
 
   public:
-    OverloadCandidateSet(SourceLocation Loc) : Loc(Loc), NumInlineSequences(0){}
+    OverloadCandidateSet(SourceLocation Loc, CandidateSetKind CSK)
+        : Loc(Loc), Kind(CSK), NumInlineSequences(0) {}
     ~OverloadCandidateSet() { destroyCandidates(); }
 
     SourceLocation getLocation() const { return Loc; }
+    CandidateSetKind getKind() const { return Kind; }
 
     /// \brief Determine when this overload candidate will be new to the
     /// overload set.
diff --git a/include/clang/Sema/Ownership.h b/include/clang/Sema/Ownership.h
index b7d7710..8031562 100644
--- a/include/clang/Sema/Ownership.h
+++ b/include/clang/Sema/Ownership.h
@@ -49,7 +49,7 @@
     typedef llvm::PointerLikeTypeTraits<PtrTy> Traits;
 
   public:
-    OpaquePtr() : Ptr(0) {}
+    OpaquePtr() : Ptr(nullptr) {}
 
     static OpaquePtr make(PtrTy P) { OpaquePtr OP; OP.set(P); return OP; }
 
@@ -79,7 +79,7 @@
       Ptr = Traits::getAsVoidPointer(P);
     }
 
-    LLVM_EXPLICIT operator bool() const { return Ptr != 0; }
+    LLVM_EXPLICIT operator bool() const { return Ptr != nullptr; }
 
     void *getAsOpaquePtr() const { return Ptr; }
     static OpaquePtr getFromOpaquePtr(void *P) { return OpaquePtr(P); }
@@ -158,12 +158,10 @@
 
     bool isInvalid() const { return Invalid; }
     bool isUsable() const { return !Invalid && Val; }
+    bool isUnset() const { return !Invalid && !Val; }
 
     PtrTy get() const { return Val; }
-    // FIXME: Replace with get.
-    PtrTy release() const { return Val; }
-    PtrTy take() const { return Val; }
-    template <typename T> T *takeAs() { return static_cast<T*>(get()); }
+    template <typename T> T *getAs() { return static_cast<T*>(get()); }
 
     void set(PtrTy V) { Val = V; }
 
@@ -199,15 +197,13 @@
 
     bool isInvalid() const { return PtrWithInvalid & 0x01; }
     bool isUsable() const { return PtrWithInvalid > 0x01; }
+    bool isUnset() const { return PtrWithInvalid == 0; }
 
     PtrTy get() const {
       void *VP = reinterpret_cast<void *>(PtrWithInvalid & ~0x01);
       return PtrTraits::getFromVoidPointer(VP);
     }
-    // FIXME: Replace with get.
-    PtrTy take() const { return get(); }
-    PtrTy release() const { return get(); }
-    template <typename T> T *takeAs() { return static_cast<T*>(get()); }
+    template <typename T> T *getAs() { return static_cast<T*>(get()); }
 
     void set(PtrTy V) {
       void *VP = PtrTraits::getAsVoidPointer(V);
@@ -262,11 +258,11 @@
   typedef ActionResult<Decl*> DeclResult;
   typedef OpaquePtr<TemplateName> ParsedTemplateTy;
 
-  typedef llvm::MutableArrayRef<Expr*> MultiExprArg;
-  typedef llvm::MutableArrayRef<Stmt*> MultiStmtArg;
-  typedef llvm::MutableArrayRef<ParsedTemplateArgument> ASTTemplateArgsPtr;
-  typedef llvm::MutableArrayRef<ParsedType> MultiTypeArg;
-  typedef llvm::MutableArrayRef<TemplateParameterList*> MultiTemplateParamsArg;
+  typedef MutableArrayRef<Expr*> MultiExprArg;
+  typedef MutableArrayRef<Stmt*> MultiStmtArg;
+  typedef MutableArrayRef<ParsedTemplateArgument> ASTTemplateArgsPtr;
+  typedef MutableArrayRef<ParsedType> MultiTypeArg;
+  typedef MutableArrayRef<TemplateParameterList*> MultiTemplateParamsArg;
 
   inline ExprResult ExprError() { return ExprResult(true); }
   inline StmtResult StmtError() { return StmtResult(true); }
diff --git a/include/clang/Sema/ParsedTemplate.h b/include/clang/Sema/ParsedTemplate.h
index 94db454..b36425f 100644
--- a/include/clang/Sema/ParsedTemplate.h
+++ b/include/clang/Sema/ParsedTemplate.h
@@ -35,7 +35,7 @@
     /// \brief Build an empty template argument. 
     ///
     /// This template argument is invalid.
-    ParsedTemplateArgument() : Kind(Type), Arg(0) { }
+    ParsedTemplateArgument() : Kind(Type), Arg(nullptr) { }
     
     /// \brief Create a template type argument or non-type template argument.
     ///
@@ -61,7 +61,7 @@
         SS(SS), Loc(TemplateLoc), EllipsisLoc() { }
     
     /// \brief Determine whether the given template argument is invalid.
-    bool isInvalid() const { return Arg == 0; }
+    bool isInvalid() const { return Arg == nullptr; }
     
     /// \brief Determine what kind of template argument we have.
     KindType getKind() const { return Kind; }
diff --git a/include/clang/Sema/PrettyDeclStackTrace.h b/include/clang/Sema/PrettyDeclStackTrace.h
index aa55705..c0c772d 100644
--- a/include/clang/Sema/PrettyDeclStackTrace.h
+++ b/include/clang/Sema/PrettyDeclStackTrace.h
@@ -39,7 +39,7 @@
                             const char *Msg)
     : S(S), TheDecl(D), Loc(Loc), Message(Msg) {}
 
-  virtual void print(raw_ostream &OS) const;
+  void print(raw_ostream &OS) const override;
 };
 
 }
diff --git a/include/clang/Sema/Scope.h b/include/clang/Sema/Scope.h
index 249a4c7..8e4e2ef 100644
--- a/include/clang/Sema/Scope.h
+++ b/include/clang/Sema/Scope.h
@@ -15,13 +15,21 @@
 #define LLVM_CLANG_SEMA_SCOPE_H
 
 #include "clang/Basic/Diagnostic.h"
+#include "llvm/ADT/PointerIntPair.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallVector.h"
 
+namespace llvm {
+
+class raw_ostream;
+
+}
+
 namespace clang {
 
 class Decl;
 class UsingDirectiveDecl;
+class VarDecl;
 
 /// Scope - A scope is a transient data structure that is used while parsing the
 /// program.  It assists with resolving identifiers to the appropriate
@@ -93,21 +101,47 @@
     /// \brief This is the scope for a function-level C++ try or catch scope.
     FnTryCatchScope = 0x4000,
 
-    /// \brief This is the scope of OpenMP executable directive
-    OpenMPDirectiveScope = 0x8000
+    /// \brief This is the scope of OpenMP executable directive.
+    OpenMPDirectiveScope = 0x8000,
+
+    /// \brief This is the scope of some OpenMP loop directive.
+    OpenMPLoopDirectiveScope = 0x10000,
+
+    /// \brief This is the scope of some OpenMP simd directive.
+    /// For example, it is used for 'omp simd', 'omp for simd'.
+    /// This flag is propagated to children scopes.
+    OpenMPSimdDirectiveScope = 0x20000,
+
+    /// This scope corresponds to an enum.
+    EnumScope = 0x40000,
+
+    /// This scope corresponds to a SEH try.
+    SEHTryScope = 0x80000,
   };
 private:
   /// The parent scope for this scope.  This is null for the translation-unit
   /// scope.
   Scope *AnyParent;
 
+  /// Flags - This contains a set of ScopeFlags, which indicates how the scope
+  /// interrelates with other control flow statements.
+  unsigned Flags;
+
   /// Depth - This is the depth of this scope.  The translation-unit scope has
   /// depth 0.
   unsigned short Depth;
 
-  /// Flags - This contains a set of ScopeFlags, which indicates how the scope
-  /// interrelates with other control flow statements.
-  unsigned short Flags;
+  /// \brief Declarations with static linkage are mangled with the number of
+  /// scopes seen as a component.
+  unsigned short MSLocalManglingNumber;
+
+  /// \brief SEH __try blocks get uniquely numbered within a function.  This
+  /// variable holds the index for an SEH try block.
+  short SEHTryIndex;
+
+  /// \brief SEH __try blocks get uniquely numbered within a function.  This
+  /// variable holds the next free index at a function's scope.
+  short SEHTryIndexPool;
 
   /// PrototypeDepth - This is the number of function prototype scopes
   /// enclosing this scope, including this scope.
@@ -120,6 +154,8 @@
   /// FnParent - If this scope has a parent scope that is a function body, this
   /// pointer is non-null and points to it.  This is used for label processing.
   Scope *FnParent;
+  Scope *MSLocalManglingParent;
+  Scope *SEHTryParent;
 
   /// BreakParent/ContinueParent - This is a direct link to the innermost
   /// BreakScope/ContinueScope which contains the contents of this scope
@@ -156,7 +192,11 @@
 
   /// \brief Used to determine if errors occurred in this scope.
   DiagnosticErrorTrap ErrorTrap;
-  
+
+  /// A lattice consisting of undefined, a single NRVO candidate variable in
+  /// this scope, or over-defined. The bit is true when over-defined.
+  llvm::PointerIntPair<VarDecl *, 1, bool> NRVO;
+
 public:
   Scope(Scope *Parent, unsigned ScopeFlags, DiagnosticsEngine &Diag)
     : ErrorTrap(Diag) {
@@ -181,6 +221,11 @@
   const Scope *getFnParent() const { return FnParent; }
   Scope *getFnParent() { return FnParent; }
 
+  const Scope *getMSLocalManglingParent() const {
+    return MSLocalManglingParent;
+  }
+  Scope *getMSLocalManglingParent() { return MSLocalManglingParent; }
+
   /// getContinueParent - Return the closest scope that a continue statement
   /// would be affected by.
   Scope *getContinueParent() {
@@ -219,10 +264,11 @@
     return PrototypeIndex++;
   }
 
-  typedef DeclSetTy::iterator decl_iterator;
-  decl_iterator decl_begin() const { return DeclsInScope.begin(); }
-  decl_iterator decl_end()   const { return DeclsInScope.end(); }
-  bool decl_empty()          const { return DeclsInScope.empty(); }
+  typedef llvm::iterator_range<DeclSetTy::iterator> decl_range;
+  decl_range decls() const {
+    return decl_range(DeclsInScope.begin(), DeclsInScope.end());
+  }
+  bool decl_empty() const { return DeclsInScope.empty(); }
 
   void AddDecl(Decl *D) {
     DeclsInScope.insert(D);
@@ -232,6 +278,30 @@
     DeclsInScope.erase(D);
   }
 
+  void incrementMSLocalManglingNumber() {
+    if (Scope *MSLMP = getMSLocalManglingParent())
+      MSLMP->MSLocalManglingNumber += 1;
+  }
+
+  void decrementMSLocalManglingNumber() {
+    if (Scope *MSLMP = getMSLocalManglingParent())
+      MSLMP->MSLocalManglingNumber -= 1;
+  }
+
+  unsigned getMSLocalManglingNumber() const {
+    if (const Scope *MSLMP = getMSLocalManglingParent())
+      return MSLMP->MSLocalManglingNumber;
+    return 1;
+  }
+
+  int getSEHTryIndex() {
+    return SEHTryIndex;
+  }
+
+  int getSEHTryParentIndex() const {
+    return SEHTryParent ? SEHTryParent->SEHTryIndex : -1;
+  }
+
   /// isDeclScope - Return true if this is the scope that the specified decl is
   /// declared in.
   bool isDeclScope(Decl *D) {
@@ -273,6 +343,18 @@
     return false;
   }
 
+  /// isInObjcMethodOuterScope - Return true if this scope is an
+  /// Objective-C method outer most body.
+  bool isInObjcMethodOuterScope() const {
+    if (const Scope *S = this) {
+      // If this scope is an objc method scope, then we succeed.
+      if (S->getFlags() & ObjCMethodScope)
+        return true;
+    }
+    return false;
+  }
+
+  
   /// isTemplateParamScope - Return true if this scope is a C++
   /// template parameter scope.
   bool isTemplateParamScope() const {
@@ -309,39 +391,81 @@
     return (getFlags() & Scope::OpenMPDirectiveScope);
   }
 
+  /// \brief Determine whether this scope is some OpenMP loop directive scope
+  /// (for example, 'omp for', 'omp simd').
+  bool isOpenMPLoopDirectiveScope() const {
+    if (getFlags() & Scope::OpenMPLoopDirectiveScope) {
+      assert(isOpenMPDirectiveScope() &&
+             "OpenMP loop directive scope is not a directive scope");
+      return true;
+    }
+    return false;
+  }
+
+  /// \brief Determine whether this scope is (or is nested into) some OpenMP
+  /// loop simd directive scope (for example, 'omp simd', 'omp for simd').
+  bool isOpenMPSimdDirectiveScope() const {
+    return getFlags() & Scope::OpenMPSimdDirectiveScope;
+  }
+
+  /// \brief Determine whether this scope is a loop having OpenMP loop
+  /// directive attached.
+  bool isOpenMPLoopScope() const {
+    const Scope *P = getParent();
+    return P && P->isOpenMPLoopDirectiveScope();
+  }
+
   /// \brief Determine whether this scope is a C++ 'try' block.
   bool isTryScope() const { return getFlags() & Scope::TryScope; }
 
+  /// \brief Determine whether this scope is a SEH '__try' block.
+  bool isSEHTryScope() const { return getFlags() & Scope::SEHTryScope; }
+
   /// containedInPrototypeScope - Return true if this or a parent scope
   /// is a FunctionPrototypeScope.
   bool containedInPrototypeScope() const;
 
-  typedef UsingDirectivesTy::iterator udir_iterator;
-  typedef UsingDirectivesTy::const_iterator const_udir_iterator;
-
   void PushUsingDirective(UsingDirectiveDecl *UDir) {
     UsingDirectives.push_back(UDir);
   }
 
-  udir_iterator using_directives_begin() {
-    return UsingDirectives.begin();
+  typedef llvm::iterator_range<UsingDirectivesTy::iterator>
+    using_directives_range;
+
+  using_directives_range using_directives() {
+    return using_directives_range(UsingDirectives.begin(),
+                                  UsingDirectives.end());
   }
 
-  udir_iterator using_directives_end() {
-    return UsingDirectives.end();
+  void addNRVOCandidate(VarDecl *VD) {
+    if (NRVO.getInt())
+      return;
+    if (NRVO.getPointer() == nullptr) {
+      NRVO.setPointer(VD);
+      return;
+    }
+    if (NRVO.getPointer() != VD)
+      setNoNRVO();
   }
 
-  const_udir_iterator using_directives_begin() const {
-    return UsingDirectives.begin();
+  void setNoNRVO() {
+    NRVO.setInt(1);
+    NRVO.setPointer(nullptr);
   }
 
-  const_udir_iterator using_directives_end() const {
-    return UsingDirectives.end();
-  }
+  void mergeNRVOIntoParent();
 
   /// Init - This is used by the parser to implement scope caching.
   ///
   void Init(Scope *parent, unsigned flags);
+
+  /// \brief Sets up the specified scope flags and adjusts the scope state
+  /// variables accordingly.
+  ///
+  void AddFlags(unsigned Flags);
+
+  void dumpImpl(raw_ostream &OS) const;
+  void dump() const;
 };
 
 }  // end namespace clang
diff --git a/include/clang/Sema/ScopeInfo.h b/include/clang/Sema/ScopeInfo.h
index 06afe1a..63427aa 100644
--- a/include/clang/Sema/ScopeInfo.h
+++ b/include/clang/Sema/ScopeInfo.h
@@ -110,6 +110,21 @@
   /// with \c __attribute__((objc_requires_super)).
   bool ObjCShouldCallSuper;
 
+  /// True when this is a method marked as a designated initializer.
+  bool ObjCIsDesignatedInit;
+  /// This starts true for a method marked as designated initializer and will
+  /// be set to false if there is an invocation to a designated initializer of
+  /// the super class.
+  bool ObjCWarnForNoDesignatedInitChain;
+
+  /// True when this is an initializer method not marked as a designated
+  /// initializer within a class that has at least one initializer marked as a
+  /// designated initializer.
+  bool ObjCIsSecondaryInit;
+  /// This starts true for a secondary initializer method and will be set to
+  /// false if there is an invocation of an initializer on 'self'.
+  bool ObjCWarnForNoInitDelegation;
+
   /// \brief Used to determine if errors occurred in this function or block.
   DiagnosticErrorTrap ErrorTrap;
 
@@ -318,6 +333,10 @@
       HasIndirectGoto(false),
       HasDroppedStmt(false),
       ObjCShouldCallSuper(false),
+      ObjCIsDesignatedInit(false),
+      ObjCWarnForNoDesignatedInitChain(false),
+      ObjCIsSecondaryInit(false),
+      ObjCWarnForNoInitDelegation(false),
       ErrorTrap(Diag) { }
 
   virtual ~FunctionScopeInfo();
@@ -386,7 +405,7 @@
     enum IsThisCapture { ThisCapture };
     Capture(IsThisCapture, bool IsNested, SourceLocation Loc,
             QualType CaptureType, Expr *Cpy)
-        : VarAndNested(0, IsNested),
+        : VarAndNested(nullptr, IsNested),
           InitExprAndCaptureKind(Cpy, Cap_This),
           Loc(Loc), EllipsisLoc(), CaptureType(CaptureType) {}
 
@@ -644,10 +663,10 @@
   SourceLocation PotentialThisCaptureLocation;
 
   LambdaScopeInfo(DiagnosticsEngine &Diag)
-    : CapturingScopeInfo(Diag, ImpCap_None), Lambda(0),
-      CallOperator(0), NumExplicitCaptures(0), Mutable(false),
+    : CapturingScopeInfo(Diag, ImpCap_None), Lambda(nullptr),
+      CallOperator(nullptr), NumExplicitCaptures(0), Mutable(false),
       ExprNeedsCleanups(false), ContainsUnexpandedParameterPack(false),
-      AutoTemplateParameterDepth(0), GLTemplateParameterList(0)
+      AutoTemplateParameterDepth(0), GLTemplateParameterList(nullptr)
   {
     Kind = SK_Lambda;
   }
@@ -708,10 +727,10 @@
   /// act of analyzing the enclosing full expression (ActOnFinishFullExpr)
   /// if we can determine that the full expression is not instantiation-
   /// dependent, then we can entirely avoid its capture. 
-  ///

-  ///   const int n = 0;

-  ///   [&] (auto x) {

-  ///     (void)+n + x;

+  ///
+  ///   const int n = 0;
+  ///   [&] (auto x) {
+  ///     (void)+n + x;
   ///   };
   /// Interestingly, this strategy would involve a capture of n, even though 
   /// it's obviously not odr-used here, because the full-expression is 
@@ -725,12 +744,12 @@
   /// Before anyone is tempted to implement a strategy for not-capturing 'n',
   /// consider the insightful warning in: 
   ///    /cfe-commits/Week-of-Mon-20131104/092596.html
-  /// "The problem is that the set of captures for a lambda is part of the ABI

-  ///  (since lambda layout can be made visible through inline functions and the

-  ///  like), and there are no guarantees as to which cases we'll manage to build

-  ///  an lvalue-to-rvalue conversion in, when parsing a template -- some

-  ///  seemingly harmless change elsewhere in Sema could cause us to start or stop

-  ///  building such a node. So we need a rule that anyone can implement and get

+  /// "The problem is that the set of captures for a lambda is part of the ABI
+  ///  (since lambda layout can be made visible through inline functions and the
+  ///  like), and there are no guarantees as to which cases we'll manage to build
+  ///  an lvalue-to-rvalue conversion in, when parsing a template -- some
+  ///  seemingly harmless change elsewhere in Sema could cause us to start or stop
+  ///  building such a node. So we need a rule that anyone can implement and get
   ///  exactly the same result".
   ///    
   void markVariableExprAsNonODRUsed(Expr *CapturingVarExpr) {
@@ -738,7 +757,7 @@
         || isa<MemberExpr>(CapturingVarExpr));
     NonODRUsedCapturingExprs.insert(CapturingVarExpr);
   }
-  bool isVariableExprMarkedAsNonODRUsed(Expr *CapturingVarExpr) {
+  bool isVariableExprMarkedAsNonODRUsed(Expr *CapturingVarExpr) const {
     assert(isa<DeclRefExpr>(CapturingVarExpr) 
       || isa<MemberExpr>(CapturingVarExpr));
     return NonODRUsedCapturingExprs.count(CapturingVarExpr);
@@ -761,16 +780,14 @@
     return getNumPotentialVariableCaptures() || 
                                   PotentialThisCaptureLocation.isValid(); 
   }
-  
-  // When passed the index, returns the VarDecl and Expr associated 
+
+  // When passed the index, returns the VarDecl and Expr associated
   // with the index.
-  void getPotentialVariableCapture(unsigned Idx, VarDecl *&VD, Expr *&E);
- 
+  void getPotentialVariableCapture(unsigned Idx, VarDecl *&VD, Expr *&E) const;
 };
 
-
 FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy()
-  : Base(0, false), Property(0) {}
+  : Base(nullptr, false), Property(nullptr) {}
 
 FunctionScopeInfo::WeakObjectProfileTy
 FunctionScopeInfo::WeakObjectProfileTy::getSentinel() {
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index ed28583..e254afd 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -26,11 +26,11 @@
 #include "clang/AST/TypeLoc.h"
 #include "clang/Basic/ExpressionTraits.h"
 #include "clang/Basic/LangOptions.h"
+#include "clang/Basic/Module.h"
 #include "clang/Basic/OpenMPKinds.h"
 #include "clang/Basic/Specifiers.h"
 #include "clang/Basic/TemplateKinds.h"
 #include "clang/Basic/TypeTraits.h"
-#include "clang/Lex/ModuleLoader.h"
 #include "clang/Sema/AnalysisBasedWarnings.h"
 #include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/ExternalSemaSource.h"
@@ -38,17 +38,18 @@
 #include "clang/Sema/LocInfoType.h"
 #include "clang/Sema/ObjCMethodList.h"
 #include "clang/Sema/Ownership.h"
+#include "clang/Sema/Scope.h"
 #include "clang/Sema/ScopeInfo.h"
 #include "clang/Sema/TypoCorrection.h"
 #include "clang/Sema/Weak.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/Optional.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallVector.h"
-#include "llvm/MC/MCParser/MCAsmParser.h"
+#include "llvm/ADT/TinyPtrVector.h"
 #include <deque>
+#include <memory>
 #include <string>
 #include <vector>
 
@@ -57,6 +58,7 @@
   template <typename ValueT> struct DenseMapInfo;
   template <typename ValueT, typename ValueInfoT> class DenseSet;
   class SmallBitVector;
+  class InlineAsmIdentifierInfo;
 }
 
 namespace clang {
@@ -101,6 +103,7 @@
   class DependentDiagnostic;
   class DesignatedInitExpr;
   class Designation;
+  class EnableIfAttr;
   class EnumConstantDecl;
   class Expr;
   class ExtVectorType;
@@ -122,6 +125,8 @@
   class LocalInstantiationScope;
   class LookupResult;
   class MacroInfo;
+  typedef ArrayRef<std::pair<IdentifierInfo *, SourceLocation>> ModuleIdPath;
+  class ModuleLoader;
   class MultiLevelTemplateArgumentList;
   class NamedDecl;
   class NonNullAttr;
@@ -152,7 +157,6 @@
   class Stmt;
   class StringLiteral;
   class SwitchStmt;
-  class TargetAttributesSema;
   class TemplateArgument;
   class TemplateArgumentList;
   class TemplateArgumentLoc;
@@ -204,7 +208,6 @@
 class Sema {
   Sema(const Sema &) LLVM_DELETED_FUNCTION;
   void operator=(const Sema &) LLVM_DELETED_FUNCTION;
-  mutable const TargetAttributesSema* TheTargetAttributesSema;
 
   ///\brief Source of additional semantic information.
   ExternalSemaSource *ExternalSource;
@@ -263,9 +266,82 @@
 
   bool MSStructPragmaOn; // True when \#pragma ms_struct on
 
+  /// \brief Controls member pointer representation format under the MS ABI.
+  LangOptions::PragmaMSPointersToMembersKind
+      MSPointerToMemberRepresentationMethod;
+
+  enum PragmaVtorDispKind {
+    PVDK_Push,          ///< #pragma vtordisp(push, mode)
+    PVDK_Set,           ///< #pragma vtordisp(mode)
+    PVDK_Pop,           ///< #pragma vtordisp(pop)
+    PVDK_Reset          ///< #pragma vtordisp()
+  };
+
+  enum PragmaMsStackAction {
+    PSK_Reset,    // #pragma ()
+    PSK_Set,      // #pragma ("name")
+    PSK_Push,     // #pragma (push[, id])
+    PSK_Push_Set, // #pragma (push[, id], "name")
+    PSK_Pop,      // #pragma (pop[, id])
+    PSK_Pop_Set,  // #pragma (pop[, id], "name")
+  };
+
+  /// \brief Whether to insert vtordisps prior to virtual bases in the Microsoft
+  /// C++ ABI.  Possible values are 0, 1, and 2, which mean:
+  ///
+  /// 0: Suppress all vtordisps
+  /// 1: Insert vtordisps in the presence of vbase overrides and non-trivial
+  ///    structors
+  /// 2: Always insert vtordisps to support RTTI on partially constructed
+  ///    objects
+  ///
+  /// The stack always has at least one element in it.
+  SmallVector<MSVtorDispAttr::Mode, 2> VtorDispModeStack;
+
+  /// \brief Source location for newly created implicit MSInheritanceAttrs
+  SourceLocation ImplicitMSInheritanceAttrLoc;
+
+  template<typename ValueType>
+  struct PragmaStack {
+    struct Slot {
+      llvm::StringRef StackSlotLabel;
+      ValueType Value;
+      SourceLocation PragmaLocation;
+      Slot(llvm::StringRef StackSlotLabel,
+           ValueType Value,
+           SourceLocation PragmaLocation)
+        : StackSlotLabel(StackSlotLabel), Value(Value),
+          PragmaLocation(PragmaLocation) {}
+    };
+    void Act(SourceLocation PragmaLocation,
+             PragmaMsStackAction Action,
+             llvm::StringRef StackSlotLabel,
+             ValueType Value);
+    explicit PragmaStack(const ValueType &Value)
+      : CurrentValue(Value) {}
+    SmallVector<Slot, 2> Stack;
+    ValueType CurrentValue;
+    SourceLocation CurrentPragmaLocation;
+  };
+  // FIXME: We should serialize / deserialize these if they occur in a PCH (but
+  // we shouldn't do so if they're in a module).
+  PragmaStack<StringLiteral *> DataSegStack;
+  PragmaStack<StringLiteral *> BSSSegStack;
+  PragmaStack<StringLiteral *> ConstSegStack;
+  PragmaStack<StringLiteral *> CodeSegStack;
+
+  /// Last section used with #pragma init_seg.
+  StringLiteral *CurInitSeg;
+  SourceLocation CurInitSegLoc;
+
   /// VisContext - Manages the stack for \#pragma GCC visibility.
   void *VisContext; // Really a "PragmaVisStack*"
 
+  /// \brief This represents the last location of a "#pragma clang optimize off"
+  /// directive if such a directive has not been closed by an "on" yet. If
+  /// optimizations are currently "on", this is set to an invalid location.
+  SourceLocation OptimizeOffPragmaLocation;
+
   /// \brief Flag indicating if Sema is building a recovery call expression.
   ///
   /// This flag is used to avoid building recovery call expressions
@@ -281,6 +357,12 @@
   /// element type here is ExprWithCleanups::Object.
   SmallVector<BlockDecl*, 8> ExprCleanupObjects;
 
+  /// \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. 
   llvm::SmallPtrSet<Expr*, 2> MaybeODRUseExprs;
 
   /// \brief Stack containing information about each of the nested
@@ -301,7 +383,7 @@
   ExtVectorDeclsType ExtVectorDecls;
 
   /// FieldCollector - Collects CXXFieldDecls during parsing of C++ classes.
-  OwningPtr<CXXFieldCollector> FieldCollector;
+  std::unique_ptr<CXXFieldCollector> FieldCollector;
 
   typedef llvm::SmallSetVector<const NamedDecl*, 16> NamedDeclSetType;
 
@@ -313,7 +395,7 @@
   /// PureVirtualClassDiagSet - a set of class declarations which we have
   /// emitted a list of pure virtual functions. Used to prevent emitting the
   /// same list more than once.
-  OwningPtr<RecordDeclSetTy> PureVirtualClassDiagSet;
+  std::unique_ptr<RecordDeclSetTy> PureVirtualClassDiagSet;
 
   /// ParsingInitForAutoVars - a set of declarations with auto types for which
   /// we are currently parsing the initializer.
@@ -420,13 +502,13 @@
     sema::DelayedDiagnosticPool *CurPool;
 
   public:
-    DelayedDiagnostics() : CurPool(0) {}
+    DelayedDiagnostics() : CurPool(nullptr) {}
 
     /// Adds a delayed diagnostic.
     void add(const sema::DelayedDiagnostic &diag); // in DelayedDiagnostic.h
 
     /// Determines whether diagnostics should be delayed.
-    bool shouldDelayDiagnostics() { return CurPool != 0; }
+    bool shouldDelayDiagnostics() { return CurPool != nullptr; }
 
     /// Returns the current delayed-diagnostics pool.
     sema::DelayedDiagnosticPool *getCurrentPool() const {
@@ -454,13 +536,13 @@
     DelayedDiagnosticsState pushUndelayed() {
       DelayedDiagnosticsState state;
       state.SavedPool = CurPool;
-      CurPool = 0;
+      CurPool = nullptr;
       return state;
     }
 
     /// Undo a previous pushUndelayed().
     void popUndelayed(DelayedDiagnosticsState state) {
-      assert(CurPool == NULL);
+      assert(CurPool == nullptr);
       CurPool = state.SavedPool;
     }
   } DelayedDiagnostics;
@@ -474,13 +556,15 @@
     QualType SavedCXXThisTypeOverride;
 
   public:
-    ContextRAII(Sema &S, DeclContext *ContextToPush)
+    ContextRAII(Sema &S, DeclContext *ContextToPush, bool NewThisContext = true)
       : S(S), SavedContext(S.CurContext),
         SavedContextState(S.DelayedDiagnostics.pushUndelayed()),
         SavedCXXThisTypeOverride(S.CXXThisTypeOverride)
     {
       assert(ContextToPush && "pushing null context");
       S.CurContext = ContextToPush;
+      if (NewThisContext)
+        S.CXXThisTypeOverride = QualType();
     }
 
     void pop() {
@@ -488,7 +572,7 @@
       S.CurContext = SavedContext;
       S.DelayedDiagnostics.popUndelayed(SavedContextState);
       S.CXXThisTypeOverride = SavedCXXThisTypeOverride;
-      SavedContext = 0;
+      SavedContext = nullptr;
     }
 
     ~ContextRAII() {
@@ -563,7 +647,7 @@
   RecordDecl *MSVCGuidDecl;
 
   /// \brief Caches identifiers/selectors for NSFoundation APIs.
-  OwningPtr<NSAPI> NSAPIObj;
+  std::unique_ptr<NSAPI> NSAPIObj;
 
   /// \brief The declaration of the Objective-C NSNumber class.
   ObjCInterfaceDecl *NSNumberDecl;
@@ -766,7 +850,7 @@
   /// \brief The number of SFINAE diagnostics that have been trapped.
   unsigned NumSFINAEErrors;
 
-  typedef llvm::DenseMap<ParmVarDecl *, SmallVector<ParmVarDecl *, 1> >
+  typedef llvm::DenseMap<ParmVarDecl *, llvm::TinyPtrVector<ParmVarDecl *>>
     UnparsedDefaultArgInstantiationsMap;
 
   /// \brief A mapping from parameters with unparsed default arguments to the
@@ -827,6 +911,7 @@
 
   /// Private Helper predicate to check for 'self'.
   bool isSelfExpr(Expr *RExpr);
+  bool isSelfExpr(Expr *RExpr, const ObjCMethodDecl *Method);
 
   /// \brief Cause the active diagnostic on the DiagosticsEngine to be
   /// emitted. This is closely coupled to the SemaDiagnosticBuilder class and
@@ -847,13 +932,12 @@
     bool OldFPContractState : 1;
   };
 
-  typedef llvm::MCAsmParserSemaCallback::InlineAsmIdentifierInfo
-    InlineAsmIdentifierInfo;
+  void addImplicitTypedef(StringRef Name, QualType T);
 
 public:
   Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
        TranslationUnitKind TUKind = TU_Complete,
-       CodeCompleteConsumer *CompletionConsumer = 0);
+       CodeCompleteConsumer *CompletionConsumer = nullptr);
   ~Sema();
 
   /// \brief Perform initialization that occurs after the parser has been
@@ -866,7 +950,6 @@
 
   DiagnosticsEngine &getDiagnostics() const { return Diags; }
   SourceManager &getSourceManager() const { return SourceMgr; }
-  const TargetAttributesSema &getTargetAttributesSema() const;
   Preprocessor &getPreprocessor() const { return PP; }
   ASTContext &getASTContext() const { return Context; }
   ASTConsumer &getASTConsumer() const { return Consumer; }
@@ -948,9 +1031,11 @@
   getFixItZeroInitializerForType(QualType T, SourceLocation Loc) const;
   std::string getFixItZeroLiteralForType(QualType T, SourceLocation Loc) const;
 
-  ExprResult Owned(Expr* E) { return E; }
-  ExprResult Owned(ExprResult R) { return R; }
-  StmtResult Owned(Stmt* S) { return S; }
+  /// \brief Calls \c Lexer::getLocForEndOfToken()
+  SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset = 0);
+
+  /// \brief Retrieve the module loader associated with the preprocessor.
+  ModuleLoader &getModuleLoader() const;
 
   void ActOnEndOfTranslationUnit();
 
@@ -961,7 +1046,7 @@
   void PushFunctionScope();
   void PushBlockScope(Scope *BlockScope, BlockDecl *Block);
   sema::LambdaScopeInfo *PushLambdaScope();
-  
+
   /// \brief This is used to inform Sema what the current TemplateParameterDepth
   /// is during Parsing.  Currently it is used to pass on the depth
   /// when parsing generic lambda 'auto' parameters.
@@ -970,13 +1055,27 @@
   void PushCapturedRegionScope(Scope *RegionScope, CapturedDecl *CD,
                                RecordDecl *RD,
                                CapturedRegionKind K);
-  void PopFunctionScopeInfo(const sema::AnalysisBasedWarnings::Policy *WP =0,
-                            const Decl *D = 0, const BlockExpr *blkExpr = 0);
+  void
+  PopFunctionScopeInfo(const sema::AnalysisBasedWarnings::Policy *WP = nullptr,
+                       const Decl *D = nullptr,
+                       const BlockExpr *blkExpr = nullptr);
 
   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;
+      return FunctionScopes[e];
+    }
+    return nullptr;
+  }
+  
   template <typename ExprT>
   void recordUseOfEvaluatedWeak(const ExprT *E, bool IsRead=true) {
     if (!isUnevaluatedContext())
@@ -1012,9 +1111,9 @@
   //
 
   QualType BuildQualifiedType(QualType T, SourceLocation Loc, Qualifiers Qs,
-                              const DeclSpec *DS = 0);
+                              const DeclSpec *DS = nullptr);
   QualType BuildQualifiedType(QualType T, SourceLocation Loc, unsigned CVRA,
-                              const DeclSpec *DS = 0);
+                              const DeclSpec *DS = nullptr);
   QualType BuildPointerType(QualType T,
                             SourceLocation Loc, DeclarationName Entity);
   QualType BuildReferenceType(QualType T, bool LValueRef,
@@ -1055,7 +1154,7 @@
   /// unqualified type will always be a FunctionProtoType.
   /// Otherwise, returns a NULL type.
   QualType BuildFunctionType(QualType T,
-                             llvm::MutableArrayRef<QualType> ParamTypes,
+                             MutableArrayRef<QualType> ParamTypes,
                              SourceLocation Loc, DeclarationName Entity,
                              const FunctionProtoType::ExtProtoInfo &EPI);
 
@@ -1076,10 +1175,13 @@
   ParsedType CreateParsedType(QualType T, TypeSourceInfo *TInfo);
   DeclarationNameInfo GetNameForDeclarator(Declarator &D);
   DeclarationNameInfo GetNameFromUnqualifiedId(const UnqualifiedId &Name);
-  static QualType GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo = 0);
+  static QualType GetTypeFromParser(ParsedType Ty,
+                                    TypeSourceInfo **TInfo = nullptr);
   CanThrowResult canThrow(const Expr *E);
   const FunctionProtoType *ResolveExceptionSpec(SourceLocation Loc,
                                                 const FunctionProtoType *FPT);
+  void UpdateExceptionSpec(FunctionDecl *FD,
+                           const FunctionProtoType::ExtProtoInfo &EPI);
   bool CheckSpecifiedExceptionType(QualType &T, const SourceRange &Range);
   bool CheckDistantExceptionSpec(QualType T);
   bool CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New);
@@ -1090,8 +1192,8 @@
       const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID,
       const FunctionProtoType *Old, SourceLocation OldLoc,
       const FunctionProtoType *New, SourceLocation NewLoc,
-      bool *MissingExceptionSpecification = 0,
-      bool *MissingEmptyExceptionSpecification = 0,
+      bool *MissingExceptionSpecification = nullptr,
+      bool *MissingEmptyExceptionSpecification = nullptr,
       bool AllowNoexceptAllMatchWithNoSpec = false,
       bool IsOperatorNew = false);
   bool CheckExceptionSpecSubset(
@@ -1142,7 +1244,7 @@
   public:
     BoundTypeDiagnoser1(unsigned DiagID, const T1 &Arg1)
       : TypeDiagnoser(DiagID == 0), DiagID(DiagID), Arg1(Arg1) { }
-    virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) {
+    void diagnose(Sema &S, SourceLocation Loc, QualType T) override {
       if (Suppressed) return;
       S.Diag(Loc, DiagID) << getPrintable(Arg1) << T;
     }
@@ -1162,7 +1264,7 @@
       : TypeDiagnoser(DiagID == 0), DiagID(DiagID), Arg1(Arg1),
         Arg2(Arg2) { }
 
-    virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) {
+    void diagnose(Sema &S, SourceLocation Loc, QualType T) override {
       if (Suppressed) return;
       S.Diag(Loc, DiagID) << getPrintable(Arg1) << getPrintable(Arg2) << T;
     }
@@ -1183,7 +1285,7 @@
     : TypeDiagnoser(DiagID == 0), DiagID(DiagID), Arg1(Arg1),
       Arg2(Arg2), Arg3(Arg3) { }
 
-    virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) {
+    void diagnose(Sema &S, SourceLocation Loc, QualType T) override {
       if (Suppressed) return;
       S.Diag(Loc, DiagID)
         << getPrintable(Arg1) << getPrintable(Arg2) << getPrintable(Arg3) << T;
@@ -1293,33 +1395,36 @@
   /// function to pin them on. ActOnFunctionDeclarator reads this list and patches
   /// them into the FunctionDecl.
   std::vector<NamedDecl*> DeclsInPrototypeScope;
-  /// Nonzero if we are currently parsing a function declarator. This is a counter
-  /// as opposed to a boolean so we can deal with nested function declarators
-  /// such as:
-  ///     void f(void (*g)(), ...)
-  unsigned InFunctionDeclarator;
 
-  DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType = 0);
+  DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType = nullptr);
 
   void DiagnoseUseOfUnimplementedSelectors();
 
   bool isSimpleTypeSpecifier(tok::TokenKind Kind) const;
 
   ParsedType getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
-                         Scope *S, CXXScopeSpec *SS = 0,
+                         Scope *S, CXXScopeSpec *SS = nullptr,
                          bool isClassName = false,
                          bool HasTrailingDot = false,
                          ParsedType ObjectType = ParsedType(),
                          bool IsCtorOrDtorName = false,
                          bool WantNontrivialTypeSourceInfo = false,
-                         IdentifierInfo **CorrectedII = 0);
+                         IdentifierInfo **CorrectedII = nullptr);
   TypeSpecifierType isTagName(IdentifierInfo &II, Scope *S);
   bool isMicrosoftMissingTypename(const CXXScopeSpec *SS, Scope *S);
-  bool DiagnoseUnknownTypeName(IdentifierInfo *&II,
+  void DiagnoseUnknownTypeName(IdentifierInfo *&II,
                                SourceLocation IILoc,
                                Scope *S,
                                CXXScopeSpec *SS,
-                               ParsedType &SuggestedType);
+                               ParsedType &SuggestedType,
+                               bool AllowClassTemplates = false);
+
+  /// \brief For compatibility with MSVC, we delay parsing of some default
+  /// template type arguments until instantiation time.  Emits a warning and
+  /// returns a synthesized DependentNameType that isn't really dependent on any
+  /// other template arguments.
+  ParsedType ActOnDelayedDefaultTemplateArg(const IdentifierInfo &II,
+                                            SourceLocation NameLoc);
 
   /// \brief Describes the result of the name lookup and resolution performed
   /// by \c ClassifyName().
@@ -1444,7 +1549,7 @@
                                   SourceLocation NameLoc,
                                   const Token &NextToken,
                                   bool IsAddressOfOperand,
-                                  CorrectionCandidateCallback *CCC = 0);
+                                  CorrectionCandidateCallback *CCC = nullptr);
 
   Decl *ActOnDeclarator(Scope *S, Declarator &D);
 
@@ -1455,6 +1560,14 @@
   bool diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC,
                                     DeclarationName Name,
                                     SourceLocation Loc);
+  void
+  diagnoseIgnoredQualifiers(unsigned DiagID, unsigned Quals,
+                            SourceLocation FallbackLoc,
+                            SourceLocation ConstQualLoc = SourceLocation(),
+                            SourceLocation VolatileQualLoc = SourceLocation(),
+                            SourceLocation RestrictQualLoc = SourceLocation(),
+                            SourceLocation AtomicQualLoc = SourceLocation());
+
   static bool adjustContextForLocalExternDecl(DeclContext *&DC);
   void DiagnoseFunctionSpecifiers(const DeclSpec &DS);
   void CheckShadow(Scope *S, VarDecl *D, const LookupResult& R);
@@ -1476,8 +1589,6 @@
   void CheckVariableDeclarationType(VarDecl *NewVD);
   void CheckCompleteVariableDeclaration(VarDecl *var);
   void MaybeSuggestAddingStaticToDecl(const FunctionDecl *D);
-  void ActOnStartFunctionDeclarator();
-  void ActOnEndFunctionDeclarator();
 
   NamedDecl* ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
                                      TypeSourceInfo *TInfo,
@@ -1485,7 +1596,6 @@
                                      MultiTemplateParamsArg TemplateParamLists,
                                      bool &AddToScope);
   bool AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD);
-  void checkVoidParamDecl(ParmVarDecl *Param);
 
   bool CheckConstexprFunctionDecl(const FunctionDecl *FD);
   bool CheckConstexprFunctionBody(const FunctionDecl *FD, Stmt *Body);
@@ -1515,7 +1625,7 @@
   void ActOnParamUnparsedDefaultArgument(Decl *param,
                                          SourceLocation EqualLoc,
                                          SourceLocation ArgLoc);
-  void ActOnParamDefaultArgumentError(Decl *param);
+  void ActOnParamDefaultArgumentError(Decl *param, SourceLocation EqualLoc);
   bool SetParamDefaultArgument(ParmVarDecl *Param, Expr *DefaultArg,
                                SourceLocation EqualLoc);
 
@@ -1524,12 +1634,16 @@
   void ActOnUninitializedDecl(Decl *dcl, bool TypeMayContainAuto);
   void ActOnInitializerError(Decl *Dcl);
   void ActOnCXXForRangeDecl(Decl *D);
+  StmtResult ActOnCXXForRangeIdentifier(Scope *S, SourceLocation IdentLoc,
+                                        IdentifierInfo *Ident,
+                                        ParsedAttributes &Attrs,
+                                        SourceLocation AttrEnd);
   void SetDeclDeleted(Decl *dcl, SourceLocation DelLoc);
   void SetDeclDefaulted(Decl *dcl, SourceLocation DefaultLoc);
   void FinalizeDeclaration(Decl *D);
   DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
                                          ArrayRef<Decl *> Group);
-  DeclGroupPtrTy BuildDeclaratorGroup(llvm::MutableArrayRef<Decl *> Group,
+  DeclGroupPtrTy BuildDeclaratorGroup(MutableArrayRef<Decl *> Group,
                                       bool TypeMayContainAuto = true);
 
   /// Should be called on all declarations that might have attached
@@ -1541,7 +1655,7 @@
                                        SourceLocation LocAfterDecls);
   void CheckForFunctionRedefinition(FunctionDecl *FD,
                                     const FunctionDecl *EffectiveDefinition =
-                                        0);
+                                        nullptr);
   Decl *ActOnStartOfFunctionDef(Scope *S, Declarator &D);
   Decl *ActOnStartOfFunctionDef(Scope *S, Decl *D);
   void ActOnStartOfObjCMethodDef(Scope *S, Decl *D);
@@ -1549,6 +1663,16 @@
     return D && isa<ObjCMethodDecl>(D);
   }
 
+  /// \brief Determine whether we can delay parsing the body of a function or
+  /// function template until it is used, assuming we don't care about emitting
+  /// code for that function.
+  ///
+  /// This will be \c false if we may need the body of the function in the
+  /// middle of parsing an expression (where it's impractical to switch to
+  /// parsing a different function), for instance, if it's constexpr in C++11
+  /// or has an 'auto' return type in C++14. These cases are essentially bugs.
+  bool canDelayFunctionBody(const Declarator &D);
+
   /// \brief Determine whether we can skip parsing the body of a function
   /// definition, assuming we don't care about analyzing its body or emitting
   /// code for that function.
@@ -1562,6 +1686,7 @@
   Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body);
   Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body, bool IsInstantiation);
   Decl *ActOnSkippedFunctionBody(Decl *Decl);
+  void ActOnFinishInlineMethodDef(CXXMethodDecl *D);
 
   /// ActOnFinishDelayedAttribute - Invoked when we have finished parsing an
   /// attribute for which parsing is delayed.
@@ -1605,12 +1730,13 @@
   void ActOnModuleInclude(SourceLocation DirectiveLoc, Module *Mod);
 
   /// \brief Create an implicit import of the given module at the given
-  /// source location.
+  /// source location, for error recovery, if possible.
   ///
-  /// This routine is typically used for error recovery, when the entity found
-  /// by name lookup is actually hidden within a module that we know about but
-  /// the user has forgotten to import.
-  void createImplicitModuleImport(SourceLocation Loc, Module *Mod);
+  /// This routine is typically used when an entity found by name lookup
+  /// is actually hidden within a module that we know about but the user
+  /// has forgotten to import.
+  void createImplicitModuleImportForErrorRecovery(SourceLocation Loc,
+                                                  Module *Mod);
 
   /// \brief Retrieve a suitable printing policy.
   PrintingPolicy getPrintingPolicy() const {
@@ -1634,7 +1760,8 @@
 
   Decl *BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
                                     AccessSpecifier AS,
-                                    RecordDecl *Record);
+                                    RecordDecl *Record,
+                                    const PrintingPolicy &Policy);
 
   Decl *BuildMicrosoftCAnonymousStruct(Scope *S, DeclSpec &DS,
                                        RecordDecl *Record);
@@ -1659,7 +1786,8 @@
                  MultiTemplateParamsArg TemplateParameterLists,
                  bool &OwnedDecl, bool &IsDependent,
                  SourceLocation ScopedEnumKWLoc,
-                 bool ScopedEnumUsesClassTag, TypeResult UnderlyingType);
+                 bool ScopedEnumUsesClassTag, TypeResult UnderlyingType,
+                 bool IsTypeSpecifier);
 
   Decl *ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc,
                                 unsigned TagSpec, SourceLocation TagLoc,
@@ -1700,7 +1828,7 @@
                             InClassInitStyle InitStyle,
                             SourceLocation TSSL,
                             AccessSpecifier AS, NamedDecl *PrevDecl,
-                            Declarator *D = 0);
+                            Declarator *D = nullptr);
 
   bool CheckNontrivialField(FieldDecl *FD);
   void DiagnoseNontrivial(const CXXRecordDecl *Record, CXXSpecialMember CSM);
@@ -1817,11 +1945,11 @@
   /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
   /// true if 'D' belongs to the given declaration context.
   ///
-  /// \param ExplicitInstantiationOrSpecialization When true, we are checking
-  /// whether the declaration is in scope for the purposes of explicit template
-  /// instantiation or specialization. The default is false.
-  bool isDeclInScope(NamedDecl *D, DeclContext *Ctx, Scope *S = 0,
-                     bool ExplicitInstantiationOrSpecialization = false);
+  /// \param AllowInlineNamespace If \c true, allow the declaration to be in the
+  ///        enclosing namespace set of the context, rather than contained
+  ///        directly within it.
+  bool isDeclInScope(NamedDecl *D, DeclContext *Ctx, Scope *S = nullptr,
+                     bool AllowInlineNamespace = false);
 
   /// Finds the scope corresponding to the given decl context, if it
   /// happens to be an enclosing scope.  Otherwise return NULL.
@@ -1852,6 +1980,10 @@
                                     unsigned AttrSpellingListIndex);
   DLLExportAttr *mergeDLLExportAttr(Decl *D, SourceRange Range,
                                     unsigned AttrSpellingListIndex);
+  MSInheritanceAttr *
+  mergeMSInheritanceAttr(Decl *D, SourceRange Range, bool BestCase,
+                         unsigned AttrSpellingListIndex,
+                         MSInheritanceAttr::Spelling SemanticSpelling);
   FormatAttr *mergeFormatAttr(Decl *D, SourceRange Range,
                               IdentifierInfo *Format, int FormatIdx,
                               int FirstArg, unsigned AttrSpellingListIndex);
@@ -1874,7 +2006,7 @@
   void mergeDeclAttributes(NamedDecl *New, Decl *Old,
                            AvailabilityMergeKind AMK = AMK_Redeclaration);
   void MergeTypedefNameDecl(TypedefNameDecl *New, LookupResult &OldDecls);
-  bool MergeFunctionDecl(FunctionDecl *New, Decl *Old, Scope *S,
+  bool MergeFunctionDecl(FunctionDecl *New, NamedDecl *&Old, Scope *S,
                          bool MergeTypeWithOld);
   bool MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old,
                                     Scope *S, bool MergeTypeWithOld);
@@ -1945,9 +2077,9 @@
                                  QualType &ConvertedType);
   bool IsBlockPointerConversion(QualType FromType, QualType ToType,
                                 QualType& ConvertedType);
-  bool FunctionArgTypesAreEqual(const FunctionProtoType *OldType,
-                                const FunctionProtoType *NewType,
-                                unsigned *ArgPos = 0);
+  bool FunctionParamTypesAreEqual(const FunctionProtoType *OldType,
+                                  const FunctionProtoType *NewType,
+                                  unsigned *ArgPos = nullptr);
   void HandleFunctionTypeMismatch(PartialDiagnostic &PDiag,
                                   QualType FromType, QualType ToType);
 
@@ -2061,10 +2193,10 @@
           AllowScopedEnumerations(AllowScopedEnumerations) {}
 
     /// Match an integral or (possibly scoped) enumeration type.
-    bool match(QualType T);
+    bool match(QualType T) override;
 
     SemaDiagnosticBuilder
-    diagnoseNoMatch(Sema &S, SourceLocation Loc, QualType T) {
+    diagnoseNoMatch(Sema &S, SourceLocation Loc, QualType T) override {
       return diagnoseNotInt(S, Loc, T);
     }
 
@@ -2117,10 +2249,10 @@
                             bool PartialOverloading = false,
                             bool AllowExplicit = false);
   void AddFunctionCandidates(const UnresolvedSetImpl &Functions,
-                             ArrayRef<Expr *> Args,
-                             OverloadCandidateSet& CandidateSet,
-                             bool SuppressUserConversions = false,
-                            TemplateArgumentListInfo *ExplicitTemplateArgs = 0);
+                      ArrayRef<Expr *> Args,
+                      OverloadCandidateSet &CandidateSet,
+                      bool SuppressUserConversions = false,
+                      TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr);
   void AddMethodCandidate(DeclAccessPair FoundDecl,
                           QualType ObjectType,
                           Expr::Classification ObjectClassification,
@@ -2154,13 +2286,13 @@
                               CXXRecordDecl *ActingContext,
                               Expr *From, QualType ToType,
                               OverloadCandidateSet& CandidateSet,
-                              bool AllowObjCConversionOnExplicit = false);
+                              bool AllowObjCConversionOnExplicit);
   void AddTemplateConversionCandidate(FunctionTemplateDecl *FunctionTemplate,
                                       DeclAccessPair FoundDecl,
                                       CXXRecordDecl *ActingContext,
                                       Expr *From, QualType ToType,
                                       OverloadCandidateSet &CandidateSet,
-                                    bool AllowObjCConversionOnExplicit = false);
+                                      bool AllowObjCConversionOnExplicit);
   void AddSurrogateCandidate(CXXConversionDecl *Conversion,
                              DeclAccessPair FoundDecl,
                              CXXRecordDecl *ActingContext,
@@ -2180,7 +2312,7 @@
                                     SourceLocation OpLoc, ArrayRef<Expr *> Args,
                                     OverloadCandidateSet& CandidateSet);
   void AddArgumentDependentLookupCandidates(DeclarationName Name,
-                                            bool Operator, SourceLocation Loc,
+                                            SourceLocation Loc,
                                             ArrayRef<Expr *> Args,
                                 TemplateArgumentListInfo *ExplicitTemplateArgs,
                                             OverloadCandidateSet& CandidateSet,
@@ -2193,6 +2325,11 @@
   // identified by the expression Expr
   void NoteAllOverloadCandidates(Expr* E, QualType DestType = QualType());
 
+  /// Check the enable_if expressions on the given function. Returns the first
+  /// failing attribute, or NULL if they were all successful.
+  EnableIfAttr *CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args,
+                              bool MissingImplicitThis = false);
+
   // [PossiblyAFunctionType]  -->   [Return]
   // NonFunctionType --> NonFunctionType
   // R (A) --> R(A)
@@ -2206,11 +2343,12 @@
                                      QualType TargetType,
                                      bool Complain,
                                      DeclAccessPair &Found,
-                                     bool *pHadMultipleCandidates = 0);
+                                     bool *pHadMultipleCandidates = nullptr);
 
-  FunctionDecl *ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl,
-                                                   bool Complain = false,
-                                                   DeclAccessPair* Found = 0);
+  FunctionDecl *
+  ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl,
+                                              bool Complain = false,
+                                              DeclAccessPair *Found = nullptr);
 
   bool ResolveAndFixSingleFunctionTemplateSpecialization(
                       ExprResult &SrcExpr,
@@ -2296,7 +2434,7 @@
 
   ExprResult BuildOverloadedArrowExpr(Scope *S, Expr *Base,
                                       SourceLocation OpLoc,
-                                      bool *NoArrowOperatorFound = 0);
+                                      bool *NoArrowOperatorFound = nullptr);
 
   /// CheckCallReturnType - Checks that a call expression's return type is
   /// complete. Returns true on failure. The location passed in is the location
@@ -2462,6 +2600,9 @@
   void LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S,
                                     QualType T1, QualType T2,
                                     UnresolvedSetImpl &Functions);
+  void addOverloadedOperatorToUnresolvedSet(UnresolvedSetImpl &Functions,
+                                            DeclAccessPair Operator,
+                                            QualType T1, QualType T2);
 
   LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc,
                                  SourceLocation GnuLabelLoc = SourceLocation());
@@ -2478,6 +2619,7 @@
                                         bool RValueThis, unsigned ThisQuals);
   CXXDestructorDecl *LookupDestructor(CXXRecordDecl *Class);
 
+  bool checkLiteralOperatorId(const CXXScopeSpec &SS, const UnqualifiedId &Id);
   LiteralOperatorLookupResult LookupLiteralOperator(Scope *S, LookupResult &R,
                                                     ArrayRef<QualType> ArgTys,
                                                     bool AllowRaw,
@@ -2485,10 +2627,8 @@
                                                     bool AllowStringTemplate);
   bool isKnownName(StringRef name);
 
-  void ArgumentDependentLookup(DeclarationName Name, bool Operator,
-                               SourceLocation Loc,
-                               ArrayRef<Expr *> Args,
-                               ADLResult &Functions);
+  void ArgumentDependentLookup(DeclarationName Name, SourceLocation Loc,
+                               ArrayRef<Expr *> Args, ADLResult &Functions);
 
   void LookupVisibleDecls(Scope *S, LookupNameKind Kind,
                           VisibleDeclConsumer &Consumer,
@@ -2497,13 +2637,19 @@
                           VisibleDeclConsumer &Consumer,
                           bool IncludeGlobalScope = true);
 
+  enum CorrectTypoKind {
+    CTK_NonError,     // CorrectTypo used in a non error recovery situation.
+    CTK_ErrorRecovery // CorrectTypo used in normal error recovery.
+  };
+
   TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo,
                              Sema::LookupNameKind LookupKind,
                              Scope *S, CXXScopeSpec *SS,
                              CorrectionCandidateCallback &CCC,
-                             DeclContext *MemberContext = 0,
+                             CorrectTypoKind Mode,
+                             DeclContext *MemberContext = nullptr,
                              bool EnteringContext = false,
-                             const ObjCObjectPointerType *OPT = 0,
+                             const ObjCObjectPointerType *OPT = nullptr,
                              bool RecordFailure = true);
 
   void diagnoseTypo(const TypoCorrection &Correction,
@@ -2521,8 +2667,7 @@
                                    AssociatedClassSet &AssociatedClasses);
 
   void FilterLookupForScope(LookupResult &R, DeclContext *Ctx, Scope *S,
-                            bool ConsiderLinkage,
-                            bool ExplicitInstantiationOrSpecialization);
+                            bool ConsiderLinkage, bool AllowInlineNamespace);
 
   void DiagnoseAmbiguousLookup(LookupResult &Result);
   //@}
@@ -2551,11 +2696,14 @@
 
   bool CheckRegparmAttr(const AttributeList &attr, unsigned &value);
   bool CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC, 
-                            const FunctionDecl *FD = 0);
+                            const FunctionDecl *FD = nullptr);
   bool CheckNoReturnAttr(const AttributeList &attr);
   bool checkStringLiteralArgumentAttr(const AttributeList &Attr,
                                       unsigned ArgNum, StringRef &Str,
-                                      SourceLocation *ArgLocation = 0);
+                                      SourceLocation *ArgLocation = nullptr);
+  bool checkMSInheritanceAttrOnDefinition(
+      CXXRecordDecl *RD, SourceRange Range, bool BestCase,
+      MSInheritanceAttr::Spelling SemanticSpelling);
 
   void CheckAlignasUnderalignment(Decl *D);
 
@@ -2564,6 +2712,11 @@
   /// function type typedefs and typename template arguments.
   void adjustMemberFunctionCC(QualType &T, bool IsStatic);
 
+  // Check if there is an explicit attribute, but only look through parens.
+  // The intent is to look for an attribute on the current declarator, but not
+  // one that came from a typedef.
+  bool hasExplicitCallingConv(QualType &T);
+
   /// Get the outermost AttributedType node that sets a calling convention.
   /// Valid types should not have multiple attributes with different CCs.
   const AttributedType *getCallingConvAttributedType(QualType T) const;
@@ -2572,8 +2725,6 @@
   StmtResult ProcessStmtAttributes(Stmt *Stmt, AttributeList *Attrs,
                                    SourceRange Range);
 
-  void WarnUndefinedMethod(SourceLocation ImpLoc, ObjCMethodDecl *method,
-                           bool &IncompleteImpl, unsigned DiagID);
   void WarnConflictingTypedMethods(ObjCMethodDecl *Method,
                                    ObjCMethodDecl *MethodDecl,
                                    bool IsProtocolMethodDecl);
@@ -2591,15 +2742,6 @@
   typedef llvm::SmallPtrSet<Selector, 8> SelectorSet;
   typedef llvm::DenseMap<Selector, ObjCMethodDecl*> ProtocolsMethodsMap;
 
-  /// CheckProtocolMethodDefs - This routine checks unimplemented
-  /// methods declared in protocol, and those referenced by it.
-  void CheckProtocolMethodDefs(SourceLocation ImpLoc,
-                               ObjCProtocolDecl *PDecl,
-                               bool& IncompleteImpl,
-                               const SelectorSet &InsMap,
-                               const SelectorSet &ClsMap,
-                               ObjCContainerDecl *CDecl);
-
   /// CheckImplementationIvars - This routine checks if the instance variables
   /// listed in the implelementation match those listed in the interface.
   void CheckImplementationIvars(ObjCImplementationDecl *ImpDecl,
@@ -2615,7 +2757,8 @@
   /// DiagnoseUnimplementedProperties - This routine warns on those properties
   /// which must be implemented by this implementation.
   void DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl,
-                                       ObjCContainerDecl *CDecl);
+                                       ObjCContainerDecl *CDecl,
+                                       bool SynthesizeProperties);
 
   /// DefaultSynthesizeProperties - This routine default synthesizes all
   /// properties which must be synthesized in the class's \@implementation.
@@ -2623,12 +2766,6 @@
                                     ObjCInterfaceDecl *IDecl);
   void DefaultSynthesizeProperties(Scope *S, Decl *D);
 
-  /// CollectImmediateProperties - This routine collects all properties in
-  /// the class and its conforming protocols; but not those it its super class.
-  void CollectImmediateProperties(ObjCContainerDecl *CDecl,
-            llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap,
-            llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& SuperPropMap);
-  
   /// IvarBacksCurrentMethodAccessor - This routine returns 'true' if 'IV' is
   /// an ivar synthesized for 'Method' and 'Method' is a property accessor
   /// declared in class 'IFace'.
@@ -2637,7 +2774,8 @@
   
   /// DiagnoseUnusedBackingIvarInAccessor - Issue an 'unused' warning if ivar which
   /// backs the property is not used in the property's accessor.
-  void DiagnoseUnusedBackingIvarInAccessor(Scope *S);
+  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.
@@ -2676,7 +2814,7 @@
                                        const unsigned AttributesAsWritten,
                                        TypeSourceInfo *T,
                                        tok::ObjCKeywordKind MethodImplKind,
-                                       DeclContext *lexicalDC = 0);
+                                       DeclContext *lexicalDC = nullptr);
 
   /// AtomicPropertySetterGetterRules - This routine enforces the rule (via
   /// warning) when atomic property has one but not the other user-declared
@@ -2686,6 +2824,10 @@
 
   void DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D);
 
+  void DiagnoseMissingDesignatedInitOverrides(
+                                          const ObjCImplementationDecl *ImplD,
+                                          const ObjCInterfaceDecl *IFD);
+
   void DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID, ObjCInterfaceDecl *SID);
 
   enum MethodMatchStrategy {
@@ -2779,12 +2921,6 @@
 
   const ObjCMethodDecl *SelectorsForTypoCorrection(Selector Sel,
                               QualType ObjectType=QualType());
-  
-  /// DiagnoseMismatchedMethodsInGlobalPool - This routine goes through list of
-  /// methods in global pool and issues diagnostic on identical selectors which
-  /// have mismathched types.
-  void DiagnoseMismatchedMethodsInGlobalPool();
-  
   /// LookupImplementedMethodInGlobalPool - Returns the method which has an
   /// implementation.
   ObjCMethodDecl *LookupImplementedMethodInGlobalPool(Selector Sel);
@@ -2799,7 +2935,7 @@
 public:
   class FullExprArg {
   public:
-    FullExprArg(Sema &actions) : E(0) { }
+    FullExprArg(Sema &actions) : E(nullptr) { }
 
     // FIXME: The const_cast here is ugly. RValue references would make this
     // much nicer (or we could duplicate a bunch of the move semantics
@@ -2830,13 +2966,13 @@
     return MakeFullExpr(Arg, Arg ? Arg->getExprLoc() : SourceLocation());
   }
   FullExprArg MakeFullExpr(Expr *Arg, SourceLocation CC) {
-    return FullExprArg(ActOnFinishFullExpr(Arg, CC).release());
+    return FullExprArg(ActOnFinishFullExpr(Arg, CC).get());
   }
   FullExprArg MakeFullDiscardedValueExpr(Expr *Arg) {
     ExprResult FE =
       ActOnFinishFullExpr(Arg, Arg ? Arg->getExprLoc() : SourceLocation(),
                           /*DiscardedValue*/ true);
-    return FullExprArg(FE.release());
+    return FullExprArg(FE.get());
   }
 
   StmtResult ActOnExprStmt(ExprResult Arg);
@@ -2951,15 +3087,23 @@
 
   void ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope,
                                 CapturedRegionKind Kind, unsigned NumParams);
+  typedef std::pair<StringRef, QualType> CapturedParamNameType;
+  void ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope,
+                                CapturedRegionKind Kind,
+                                ArrayRef<CapturedParamNameType> Params);
   StmtResult ActOnCapturedRegionEnd(Stmt *S);
   void ActOnCapturedRegionError();
   RecordDecl *CreateCapturedStmtRecordDecl(CapturedDecl *&CD,
                                            SourceLocation Loc,
                                            unsigned NumParams);
-  const VarDecl *getCopyElisionCandidate(QualType ReturnType, Expr *E,
-                                         bool AllowFunctionParameters);
+  VarDecl *getCopyElisionCandidate(QualType ReturnType, Expr *E,
+                                   bool AllowFunctionParameters);
+  bool isCopyElisionCandidate(QualType ReturnType, const VarDecl *VD,
+                              bool AllowFunctionParameters);
 
-  StmtResult ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp);
+  StmtResult ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp,
+                             Scope *CurScope);
+  StmtResult BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp);
   StmtResult ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp);
 
   StmtResult ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
@@ -2972,7 +3116,7 @@
   ExprResult LookupInlineAsmIdentifier(CXXScopeSpec &SS,
                                        SourceLocation TemplateKWLoc,
                                        UnqualifiedId &Id,
-                                       InlineAsmIdentifierInfo &Info,
+                                       llvm::InlineAsmIdentifierInfo &Info,
                                        bool IsUnevaluatedContext);
   bool LookupInlineAsmField(StringRef Base, StringRef Member,
                             unsigned &Offset, SourceLocation AsmLoc);
@@ -3025,14 +3169,12 @@
 
   StmtResult ActOnSEHTryBlock(bool IsCXXTry, // try (true) or __try (false) ?
                               SourceLocation TryLoc, Stmt *TryBlock,
-                              Stmt *Handler);
-
-  StmtResult ActOnSEHExceptBlock(SourceLocation Loc,
-                                 Expr *FilterExpr,
+                              Stmt *Handler, int HandlerIndex,
+                              int HandlerParentIndex);
+  StmtResult ActOnSEHExceptBlock(SourceLocation Loc, Expr *FilterExpr,
                                  Stmt *Block);
-
-  StmtResult ActOnSEHFinallyBlock(SourceLocation Loc,
-                                  Stmt *Block);
+  StmtResult ActOnSEHFinallyBlock(SourceLocation Loc, Stmt *Block);
+  StmtResult ActOnSEHLeaveStmt(SourceLocation Loc, Scope *CurScope);
 
   void DiagnoseReturnInConstructorExceptionHandler(CXXTryStmt *TryBlock);
 
@@ -3077,12 +3219,16 @@
 
   void redelayDiagnostics(sema::DelayedDiagnosticPool &pool);
 
-  void EmitDeprecationWarning(NamedDecl *D, StringRef Message,
-                              SourceLocation Loc,
-                              const ObjCInterfaceDecl *UnknownObjCClass,
-                              const ObjCPropertyDecl  *ObjCProperty);
+  enum AvailabilityDiagnostic { AD_Deprecation, AD_Unavailable };
 
-  void HandleDelayedDeprecationCheck(sema::DelayedDiagnostic &DD, Decl *Ctx);
+  void EmitAvailabilityWarning(AvailabilityDiagnostic AD,
+                               NamedDecl *D, StringRef Message,
+                               SourceLocation Loc,
+                               const ObjCInterfaceDecl *UnknownObjCClass,
+                               const ObjCPropertyDecl  *ObjCProperty,
+                               bool ObjCPropertyAccess);
+
+  void HandleDelayedAvailabilityCheck(sema::DelayedDiagnostic &DD, Decl *Ctx);
 
   bool makeUnavailableInSystemHeader(SourceLocation loc,
                                      StringRef message);
@@ -3092,7 +3238,8 @@
 
   bool CanUseDecl(NamedDecl *D);
   bool DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc,
-                         const ObjCInterfaceDecl *UnknownObjCClass=0);
+                         const ObjCInterfaceDecl *UnknownObjCClass=nullptr,
+                         bool ObjCPropertyAccess=false);
   void NoteDeletedFunction(FunctionDecl *FD);
   std::string getDeletedOrUnavailableSuffix(const FunctionDecl *FD);
   bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD,
@@ -3102,7 +3249,7 @@
                              ArrayRef<Expr *> Args);
 
   void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext,
-                                       Decl *LambdaContextDecl = 0,
+                                       Decl *LambdaContextDecl = nullptr,
                                        bool IsDecltype = false);
   enum ReuseLambdaContextDecl_t { ReuseLambdaContextDecl };
   void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext,
@@ -3193,7 +3340,7 @@
   /// emitted; this may also leave the ExprResult invalid.
   bool tryToRecoverWithCall(ExprResult &E, const PartialDiagnostic &PD,
                             bool ForceComplain = false,
-                            bool (*IsPlausibleResult)(QualType) = 0);
+                            bool (*IsPlausibleResult)(QualType) = nullptr);
 
   /// \brief Figure out if an expression could be turned into a call.
   bool tryExprAsCall(Expr &E, QualType &ZeroArgCallReturnTy,
@@ -3216,7 +3363,7 @@
                                SourceLocation TemplateKWLoc,
                                UnqualifiedId &Id,
                                bool HasTrailingLParen, bool IsAddressOfOperand,
-                               CorrectionCandidateCallback *CCC = 0,
+                               CorrectionCandidateCallback *CCC = nullptr,
                                bool IsInlineAsmIdentifier = false);
 
   void DecomposeUnqualifiedId(const UnqualifiedId &Id,
@@ -3224,10 +3371,11 @@
                               DeclarationNameInfo &NameInfo,
                               const TemplateArgumentListInfo *&TemplateArgs);
 
-  bool DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
-                           CorrectionCandidateCallback &CCC,
-                           TemplateArgumentListInfo *ExplicitTemplateArgs = 0,
-                           ArrayRef<Expr *> Args = None);
+  bool
+  DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
+                      CorrectionCandidateCallback &CCC,
+                      TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr,
+                      ArrayRef<Expr *> Args = None);
 
   ExprResult LookupInObjCMethod(LookupResult &LookUp, Scope *S,
                                 IdentifierInfo *II,
@@ -3242,18 +3390,20 @@
   ExprResult BuildDeclRefExpr(ValueDecl *D, QualType Ty,
                               ExprValueKind VK,
                               SourceLocation Loc,
-                              const CXXScopeSpec *SS = 0);
-  ExprResult BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK,
-                              const DeclarationNameInfo &NameInfo,
-                              const CXXScopeSpec *SS = 0, NamedDecl *FoundD = 0,
-                              const TemplateArgumentListInfo *TemplateArgs = 0);
+                              const CXXScopeSpec *SS = nullptr);
+  ExprResult
+  BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK,
+                   const DeclarationNameInfo &NameInfo,
+                   const CXXScopeSpec *SS = nullptr,
+                   NamedDecl *FoundD = nullptr,
+                   const TemplateArgumentListInfo *TemplateArgs = nullptr);
   ExprResult
   BuildAnonymousStructUnionMemberReference(
       const CXXScopeSpec &SS,
       SourceLocation nameLoc,
       IndirectFieldDecl *indirectField,
-      DeclAccessPair FoundDecl = DeclAccessPair::make(0, AS_none),
-      Expr *baseObjectExpr = 0,
+      DeclAccessPair FoundDecl = DeclAccessPair::make(nullptr, AS_none),
+      Expr *baseObjectExpr = nullptr,
       SourceLocation opLoc = SourceLocation());
 
   ExprResult BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS,
@@ -3269,9 +3419,10 @@
                                   const LookupResult &R,
                                   bool HasTrailingLParen);
 
-  ExprResult BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS,
-                                         const DeclarationNameInfo &NameInfo,
-                                               bool IsAddressOfOperand);
+  ExprResult BuildQualifiedDeclarationNameExpr(
+      CXXScopeSpec &SS, const DeclarationNameInfo &NameInfo,
+      bool IsAddressOfOperand, TypeSourceInfo **RecoveryTSI = nullptr);
+
   ExprResult BuildDependentDeclRefExpr(const CXXScopeSpec &SS,
                                        SourceLocation TemplateKWLoc,
                                 const DeclarationNameInfo &NameInfo,
@@ -3282,20 +3433,22 @@
                                       bool NeedsADL);
   ExprResult BuildDeclarationNameExpr(
       const CXXScopeSpec &SS, const DeclarationNameInfo &NameInfo, NamedDecl *D,
-      NamedDecl *FoundD = 0, const TemplateArgumentListInfo *TemplateArgs = 0);
+      NamedDecl *FoundD = nullptr,
+      const TemplateArgumentListInfo *TemplateArgs = nullptr);
 
   ExprResult BuildLiteralOperatorCall(LookupResult &R,
-                                      DeclarationNameInfo &SuffixInfo,
-                                      ArrayRef<Expr*> Args,
-                                      SourceLocation LitEndLoc,
-                            TemplateArgumentListInfo *ExplicitTemplateArgs = 0);
+                      DeclarationNameInfo &SuffixInfo,
+                      ArrayRef<Expr *> Args,
+                      SourceLocation LitEndLoc,
+                      TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr);
 
   ExprResult BuildPredefinedExpr(SourceLocation Loc,
                                  PredefinedExpr::IdentType IT);
   ExprResult ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind);
   ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val);
-  ExprResult ActOnNumericConstant(const Token &Tok, Scope *UDLScope = 0);
-  ExprResult ActOnCharacterConstant(const Token &Tok, Scope *UDLScope = 0);
+  ExprResult ActOnNumericConstant(const Token &Tok, Scope *UDLScope = nullptr);
+  ExprResult ActOnCharacterConstant(const Token &Tok,
+                                    Scope *UDLScope = nullptr);
   ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E);
   ExprResult ActOnParenListExpr(SourceLocation L,
                                 SourceLocation R,
@@ -3303,8 +3456,8 @@
 
   /// ActOnStringLiteral - The specified tokens were lexed as pasted string
   /// fragments (e.g. "foo" "bar" L"baz").
-  ExprResult ActOnStringLiteral(const Token *StringToks, unsigned NumStringToks,
-                                Scope *UDLScope = 0);
+  ExprResult ActOnStringLiteral(ArrayRef<Token> StringToks,
+                                Scope *UDLScope = nullptr);
 
   ExprResult ActOnGenericSelectionExpr(SourceLocation KeyLoc,
                                        SourceLocation DefaultLoc,
@@ -3361,14 +3514,6 @@
   ExprResult CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc,
                                              Expr *Idx, SourceLocation RLoc);
 
-  ExprResult BuildMemberReferenceExpr(Expr *Base, QualType BaseType,
-                                      SourceLocation OpLoc, bool IsArrow,
-                                      CXXScopeSpec &SS,
-                                      SourceLocation TemplateKWLoc,
-                                      NamedDecl *FirstQualifierInScope,
-                                const DeclarationNameInfo &NameInfo,
-                                const TemplateArgumentListInfo *TemplateArgs);
-
   // This struct is for use by ActOnMemberAccess to allow
   // BuildMemberReferenceExpr to be able to reinvoke ActOnMemberAccess after
   // changing the access operator from a '.' to a '->' (to see if that is the
@@ -3381,22 +3526,23 @@
     bool HasTrailingLParen;
   };
 
-  ExprResult BuildMemberReferenceExpr(Expr *Base, QualType BaseType,
-                                      SourceLocation OpLoc, bool IsArrow,
-                                      const CXXScopeSpec &SS,
-                                      SourceLocation TemplateKWLoc,
-                                      NamedDecl *FirstQualifierInScope,
-                                      LookupResult &R,
-                                 const TemplateArgumentListInfo *TemplateArgs,
-                                      bool SuppressQualifierCheck = false,
-                                     ActOnMemberAccessExtraArgs *ExtraArgs = 0);
+  ExprResult BuildMemberReferenceExpr(
+      Expr *Base, QualType BaseType, SourceLocation OpLoc, bool IsArrow,
+      CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
+      NamedDecl *FirstQualifierInScope, const DeclarationNameInfo &NameInfo,
+      const TemplateArgumentListInfo *TemplateArgs,
+      ActOnMemberAccessExtraArgs *ExtraArgs = nullptr);
+
+  ExprResult
+  BuildMemberReferenceExpr(Expr *Base, QualType BaseType, SourceLocation OpLoc,
+                           bool IsArrow, const CXXScopeSpec &SS,
+                           SourceLocation TemplateKWLoc,
+                           NamedDecl *FirstQualifierInScope, LookupResult &R,
+                           const TemplateArgumentListInfo *TemplateArgs,
+                           bool SuppressQualifierCheck = false,
+                           ActOnMemberAccessExtraArgs *ExtraArgs = nullptr);
 
   ExprResult PerformMemberExprBaseConversion(Expr *Base, bool IsArrow);
-  ExprResult LookupMemberExpr(LookupResult &R, ExprResult &Base,
-                              bool &IsArrow, SourceLocation OpLoc,
-                              CXXScopeSpec &SS,
-                              Decl *ObjCImpDecl,
-                              bool HasTemplateArgs);
 
   bool CheckQualifiedMemberReference(Expr *BaseExpr, QualType BaseType,
                                      const CXXScopeSpec &SS,
@@ -3435,12 +3581,13 @@
   /// locations.
   ExprResult ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc,
                            MultiExprArg ArgExprs, SourceLocation RParenLoc,
-                           Expr *ExecConfig = 0, bool IsExecConfig = false);
+                           Expr *ExecConfig = nullptr,
+                           bool IsExecConfig = false);
   ExprResult BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
                                    SourceLocation LParenLoc,
                                    ArrayRef<Expr *> Arg,
                                    SourceLocation RParenLoc,
-                                   Expr *Config = 0,
+                                   Expr *Config = nullptr,
                                    bool IsExecConfig = false);
 
   ExprResult ActOnCUDAExecConfigExpr(Scope *S, SourceLocation LLLLoc,
@@ -3676,12 +3823,13 @@
                                    const LookupResult &Previous);
   bool CheckUsingDeclQualifier(SourceLocation UsingLoc,
                                const CXXScopeSpec &SS,
+                               const DeclarationNameInfo &NameInfo,
                                SourceLocation NameLoc);
 
   NamedDecl *BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
                                    SourceLocation UsingLoc,
                                    CXXScopeSpec &SS,
-                                   const DeclarationNameInfo &NameInfo,
+                                   DeclarationNameInfo NameInfo,
                                    AttributeList *AttrList,
                                    bool IsInstantiation,
                                    bool HasTypenameKeyword,
@@ -3714,16 +3862,18 @@
   BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
                         CXXConstructorDecl *Constructor, MultiExprArg Exprs,
                         bool HadMultipleCandidates, bool IsListInitialization,
+                        bool IsStdInitListInitialization,
                         bool RequiresZeroInit, unsigned ConstructKind,
                         SourceRange ParenRange);
 
-  // FIXME: Can re remove this and have the above BuildCXXConstructExpr check if
+  // FIXME: Can we remove this and have the above BuildCXXConstructExpr check if
   // the constructor can be elidable?
   ExprResult
   BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
                         CXXConstructorDecl *Constructor, bool Elidable,
                         MultiExprArg Exprs, bool HadMultipleCandidates,
-                        bool IsListInitialization, bool RequiresZeroInit,
+                        bool IsListInitialization,
+                        bool IsStdInitListInitialization, bool RequiresZeroInit,
                         unsigned ConstructKind, SourceRange ParenRange);
 
   /// BuildCXXDefaultArgExpr - Creates a CXXDefaultArgExpr, instantiating
@@ -3795,7 +3945,7 @@
         ///   potential exceptions of the special member function contains "any"
         EPI.ExceptionSpecType = EST_ComputedNoexcept;
         EPI.NoexceptExpr = Self->ActOnCXXBoolLiteral(SourceLocation(),
-                                                     tok::kw_false).take();
+                                                     tok::kw_false).get();
       }
     }
     FunctionProtoType::ExtProtoInfo getEPI() const {
@@ -4105,7 +4255,7 @@
   /// \return returns 'true' if failed, 'false' if success.
   bool CheckCXXThisCapture(SourceLocation Loc, bool Explicit = false, 
       bool BuildAndDiagnose = true,
-      const unsigned *const FunctionScopeIndexToStopAt = 0);
+      const unsigned *const FunctionScopeIndexToStopAt = nullptr);
 
   /// \brief Determine whether the given type is the type of *this that is used
   /// outside of the body of a member function for a type that is currently
@@ -4202,32 +4352,6 @@
   ExprResult BuildCXXNoexceptExpr(SourceLocation KeyLoc, Expr *Operand,
                                   SourceLocation RParen);
 
-  /// ActOnUnaryTypeTrait - Parsed one of the unary type trait support
-  /// pseudo-functions.
-  ExprResult ActOnUnaryTypeTrait(UnaryTypeTrait OTT,
-                                 SourceLocation KWLoc,
-                                 ParsedType Ty,
-                                 SourceLocation RParen);
-
-  ExprResult BuildUnaryTypeTrait(UnaryTypeTrait OTT,
-                                 SourceLocation KWLoc,
-                                 TypeSourceInfo *T,
-                                 SourceLocation RParen);
-
-  /// ActOnBinaryTypeTrait - Parsed one of the bianry type trait support
-  /// pseudo-functions.
-  ExprResult ActOnBinaryTypeTrait(BinaryTypeTrait OTT,
-                                  SourceLocation KWLoc,
-                                  ParsedType LhsTy,
-                                  ParsedType RhsTy,
-                                  SourceLocation RParen);
-
-  ExprResult BuildBinaryTypeTrait(BinaryTypeTrait BTT,
-                                  SourceLocation KWLoc,
-                                  TypeSourceInfo *LhsT,
-                                  TypeSourceInfo *RhsT,
-                                  SourceLocation RParen);
-
   /// \brief Parsed one of the type trait support pseudo-functions.
   ExprResult ActOnTypeTrait(TypeTrait Kind, SourceLocation KWLoc,
                             ArrayRef<ParsedType> Args,
@@ -4311,7 +4435,8 @@
   }
   ExprResult ActOnFinishFullExpr(Expr *Expr, SourceLocation CC,
                                  bool DiscardedValue = false,
-                                 bool IsConstexpr = false);
+                                 bool IsConstexpr = false,
+                                 bool IsLambdaInitCaptureInitializer = false);
   StmtResult ActOnFinishFullStmt(Stmt *Stmt);
 
   // Marks SS invalid if it represents an incomplete type.
@@ -4352,7 +4477,8 @@
                                    bool EnteringContext,
                                    CXXScopeSpec &SS,
                                    NamedDecl *ScopeLookupResult,
-                                   bool ErrorRecoveryLookup);
+                                   bool ErrorRecoveryLookup,
+                                   bool *IsCorrectedToColon = nullptr);
 
   /// \brief The parser has parsed a nested-name-specifier 'identifier::'.
   ///
@@ -4375,6 +4501,13 @@
   /// output parameter (containing the full nested-name-specifier,
   /// including this new type).
   ///
+  /// \param ErrorRecoveryLookup If true, then this method is called to improve
+  /// error recovery. In this case do not emit error message.
+  ///
+  /// \param IsCorrectedToColon If not null, suggestions to replace '::' -> ':'
+  /// are allowed.  The bool value pointed by this parameter is set to 'true'
+  /// if the identifier is treated as if it was followed by ':', not '::'.
+  ///
   /// \returns true if an error occurred, false otherwise.
   bool ActOnCXXNestedNameSpecifier(Scope *S,
                                    IdentifierInfo &Identifier,
@@ -4382,7 +4515,9 @@
                                    SourceLocation CCLoc,
                                    ParsedType ObjectType,
                                    bool EnteringContext,
-                                   CXXScopeSpec &SS);
+                                   CXXScopeSpec &SS,
+                                   bool ErrorRecoveryLookup = false,
+                                   bool *IsCorrectedToColon = nullptr);
 
   ExprResult ActOnDecltypeExpression(Expr *E);
 
@@ -4506,10 +4641,18 @@
                         bool ExplicitResultType,
                         bool Mutable);
 
-  /// \brief Check an init-capture and build the implied variable declaration
-  /// with the specified name and initializer.
-  VarDecl *checkInitCapture(SourceLocation Loc, bool ByRef,
-                            IdentifierInfo *Id, Expr *Init);
+  /// \brief Perform initialization analysis of the init-capture and perform
+  /// any implicit conversions such as an lvalue-to-rvalue conversion if
+  /// not being used to initialize a reference.
+  QualType performLambdaInitCaptureInitialization(SourceLocation Loc, 
+      bool ByRef, IdentifierInfo *Id, Expr *&Init);
+  /// \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, 
+    QualType InitCaptureType, IdentifierInfo *Id, Expr *Init);
 
   /// \brief Build the implicit field for an init-capture.
   FieldDecl *buildInitCaptureField(sema::LambdaScopeInfo *LSI, VarDecl *Var);
@@ -4617,7 +4760,8 @@
                                          SourceLocation AtLoc,
                                          SourceLocation SelLoc,
                                          SourceLocation LParenLoc,
-                                         SourceLocation RParenLoc);
+                                         SourceLocation RParenLoc,
+                                         bool WarnMultipleSelectors);
 
   /// ParseObjCProtocolExpression - Build protocol expression for \@protocol
   ExprResult ParseObjCProtocolExpression(IdentifierInfo * ProtocolName,
@@ -4632,8 +4776,7 @@
   //
   Decl *ActOnStartLinkageSpecification(Scope *S,
                                        SourceLocation ExternLoc,
-                                       SourceLocation LangLoc,
-                                       StringRef Lang,
+                                       Expr *LangStr,
                                        SourceLocation LBraceLoc);
   Decl *ActOnFinishLinkageSpecification(Scope *S,
                                         Decl *LinkageSpec,
@@ -4644,21 +4787,24 @@
   // C++ Classes
   //
   bool isCurrentClassName(const IdentifierInfo &II, Scope *S,
-                          const CXXScopeSpec *SS = 0);
+                          const CXXScopeSpec *SS = nullptr);
   bool isCurrentClassNameTypo(IdentifierInfo *&II, const CXXScopeSpec *SS);
 
   bool ActOnAccessSpecifier(AccessSpecifier Access,
                             SourceLocation ASLoc,
                             SourceLocation ColonLoc,
-                            AttributeList *Attrs = 0);
+                            AttributeList *Attrs = nullptr);
 
   NamedDecl *ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS,
                                  Declarator &D,
                                  MultiTemplateParamsArg TemplateParameterLists,
                                  Expr *BitfieldWidth, const VirtSpecifiers &VS,
                                  InClassInitStyle InitStyle);
-  void ActOnCXXInClassMemberInitializer(Decl *VarDecl, SourceLocation EqualLoc,
-                                        Expr *Init);
+
+  void ActOnStartCXXInClassMemberInitializer();
+  void ActOnFinishCXXInClassMemberInitializer(Decl *VarDecl,
+                                              SourceLocation EqualLoc,
+                                              Expr *Init);
 
   MemInitResult ActOnMemInitializer(Decl *ConstructorD,
                                     Scope *S,
@@ -4784,8 +4930,8 @@
                                          AttributeList *AttrList);
   void ActOnFinishCXXMemberDecls();
 
-  void ActOnReenterTemplateScope(Scope *S, Decl *Template);
-  void ActOnReenterDeclaratorTemplateScope(Scope *S, DeclaratorDecl *D);
+  void ActOnReenterCXXMethodParameter(Scope *S, ParmVarDecl *Param);
+  unsigned ActOnReenterTemplateScope(Scope *S, Decl *Template);
   void ActOnStartDelayedMemberDeclarations(Scope *S, Decl *Record);
   void ActOnStartDelayedCXXMethodDeclaration(Scope *S, Decl *Method);
   void ActOnDelayedCXXMethodParameter(Scope *S, Decl *Param);
@@ -4864,7 +5010,7 @@
 
   bool CheckDerivedToBaseConversion(QualType Derived, QualType Base,
                                     SourceLocation Loc, SourceRange Range,
-                                    CXXCastPath *BasePath = 0,
+                                    CXXCastPath *BasePath = nullptr,
                                     bool IgnoreAccess = false);
   bool CheckDerivedToBaseConversion(QualType Derived, QualType Base,
                                     unsigned InaccessibleBaseID,
@@ -5052,7 +5198,7 @@
   void DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl);
   TemplateDecl *AdjustDeclIfTemplate(Decl *&Decl);
 
-  Decl *ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis,
+  Decl *ActOnTypeParameter(Scope *S, bool Typename,
                            SourceLocation EllipsisLoc,
                            SourceLocation KeyLoc,
                            IdentifierInfo *ParamName,
@@ -5103,7 +5249,8 @@
                                   TemplateParamListContext TPC);
   TemplateParameterList *MatchTemplateParametersToScopeSpecifier(
       SourceLocation DeclStartLoc, SourceLocation DeclLoc,
-      const CXXScopeSpec &SS, ArrayRef<TemplateParameterList *> ParamLists,
+      const CXXScopeSpec &SS, TemplateIdAnnotation *TemplateId,
+      ArrayRef<TemplateParameterList *> ParamLists,
       bool IsFriend, bool &IsExplicitSpecialization, bool &Invalid);
 
   DeclResult CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
@@ -5113,6 +5260,7 @@
                                 TemplateParameterList *TemplateParams,
                                 AccessSpecifier AS,
                                 SourceLocation ModulePrivateLoc,
+                                SourceLocation FriendLoc,
                                 unsigned NumOuterTemplateParamLists,
                             TemplateParameterList **OuterTemplateParamLists);
 
@@ -5147,7 +5295,7 @@
                                     SourceLocation RAngleLoc);
 
   DeclResult ActOnVarTemplateSpecialization(
-      Scope *S, VarTemplateDecl *VarTemplate, Declarator &D, TypeSourceInfo *DI,
+      Scope *S, Declarator &D, TypeSourceInfo *DI,
       SourceLocation TemplateKWLoc, TemplateParameterList *TemplateParams,
       StorageClass SC, bool IsPartialSpecialization);
 
@@ -5185,12 +5333,7 @@
   ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagUseKind TUK,
                                    SourceLocation KWLoc,
                                    SourceLocation ModulePrivateLoc,
-                                   CXXScopeSpec &SS,
-                                   TemplateTy Template,
-                                   SourceLocation TemplateNameLoc,
-                                   SourceLocation LAngleLoc,
-                                   ASTTemplateArgsPtr TemplateArgs,
-                                   SourceLocation RAngleLoc,
+                                   TemplateIdAnnotation &TemplateId,
                                    AttributeList *Attr,
                                  MultiTemplateParamsArg TemplateParameterLists);
 
@@ -5275,7 +5418,7 @@
   };
 
   bool CheckTemplateArgument(NamedDecl *Param,
-                             const TemplateArgumentLoc &Arg,
+                             TemplateArgumentLoc &Arg,
                              NamedDecl *Template,
                              SourceLocation TemplateLoc,
                              SourceLocation RAngleLoc,
@@ -5303,21 +5446,15 @@
   /// \param Converted Will receive the converted, canonicalized template
   /// arguments.
   ///
-  ///
-  /// \param ExpansionIntoFixedList If non-NULL, will be set true to indicate
-  /// when the template arguments contain a pack expansion that is being
-  /// expanded into a fixed parameter list.
-  ///
-  /// \returns True if an error occurred, false otherwise.
+  /// \returns true if an error occurred, false otherwise.
   bool CheckTemplateArgumentList(TemplateDecl *Template,
                                  SourceLocation TemplateLoc,
                                  TemplateArgumentListInfo &TemplateArgs,
                                  bool PartialTemplateArgs,
-                           SmallVectorImpl<TemplateArgument> &Converted,
-                                 bool *ExpansionIntoFixedList = 0);
+                           SmallVectorImpl<TemplateArgument> &Converted);
 
   bool CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
-                                 const TemplateArgumentLoc &Arg,
+                                 TemplateArgumentLoc &Arg,
                            SmallVectorImpl<TemplateArgument> &Converted);
 
   bool CheckTemplateArgument(TemplateTypeParmDecl *Param,
@@ -5327,7 +5464,7 @@
                                    TemplateArgument &Converted,
                                CheckTemplateArgumentKind CTAK = CTAK_Specified);
   bool CheckTemplateArgument(TemplateTemplateParmDecl *Param,
-                             const TemplateArgumentLoc &Arg,
+                             TemplateArgumentLoc &Arg,
                              unsigned ArgumentPackIndex);
 
   ExprResult
@@ -5776,6 +5913,8 @@
   // C++ Template Argument Deduction (C++ [temp.deduct])
   //===--------------------------------------------------------------------===//
 
+  QualType adjustCCAndNoReturn(QualType ArgFunctionType, QualType FunctionType);
+
   /// \brief Describes the result of template argument deduction.
   ///
   /// The TemplateDeductionResult enumeration describes the result of
@@ -5863,7 +6002,7 @@
                                   unsigned NumExplicitlySpecified,
                                   FunctionDecl *&Specialization,
                                   sema::TemplateDeductionInfo &Info,
-           SmallVectorImpl<OriginalCallArg> const *OriginalCallArgs = 0);
+           SmallVectorImpl<OriginalCallArg> const *OriginalCallArgs = nullptr);
 
   TemplateDeductionResult
   DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
@@ -5960,10 +6099,11 @@
   // C++ Template Instantiation
   //
 
-  MultiLevelTemplateArgumentList getTemplateInstantiationArgs(NamedDecl *D,
-                                     const TemplateArgumentList *Innermost = 0,
-                                                bool RelativeToPrimary = false,
-                                               const FunctionDecl *Pattern = 0);
+  MultiLevelTemplateArgumentList
+  getTemplateInstantiationArgs(NamedDecl *D,
+                               const TemplateArgumentList *Innermost = nullptr,
+                               bool RelativeToPrimary = false,
+                               const FunctionDecl *Pattern = nullptr);
 
   /// \brief A template instantiation that is currently in progress.
   struct ActiveTemplateInstantiation {
@@ -6038,8 +6178,8 @@
     SourceRange InstantiationRange;
 
     ActiveTemplateInstantiation()
-      : Kind(TemplateInstantiation), Template(0), Entity(0), TemplateArgs(0),
-        NumTemplateArgs(0), DeductionInfo(0) {}
+      : Kind(TemplateInstantiation), Template(nullptr), Entity(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.
@@ -6232,13 +6372,15 @@
                           SourceRange InstantiationRange = SourceRange());
 
     /// \brief Note that we are substituting prior template arguments into a
-    /// non-type or template template parameter.
+    /// non-type parameter.
     InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
                           NamedDecl *Template,
                           NonTypeTemplateParmDecl *Param,
                           ArrayRef<TemplateArgument> TemplateArgs,
                           SourceRange InstantiationRange);
 
+    /// \brief Note that we are substituting prior template arguments into a
+    /// template template parameter.
     InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
                           NamedDecl *Template,
                           TemplateTemplateParmDecl *Param,
@@ -6270,6 +6412,15 @@
     bool CheckInstantiationDepth(SourceLocation PointOfInstantiation,
                                  SourceRange InstantiationRange);
 
+    // FIXME: Replace this with a constructor once we can use delegating
+    // constructors in llvm.
+    void Initialize(
+        ActiveTemplateInstantiation::InstantiationKind Kind,
+        SourceLocation PointOfInstantiation, SourceRange InstantiationRange,
+        Decl *Entity, NamedDecl *Template = nullptr,
+        ArrayRef<TemplateArgument> TemplateArgs = ArrayRef<TemplateArgument>(),
+        sema::TemplateDeductionInfo *DeductionInfo = nullptr);
+
     InstantiatingTemplate(const InstantiatingTemplate&) LLVM_DELETED_FUNCTION;
 
     InstantiatingTemplate&
@@ -6406,6 +6557,26 @@
   /// types, static variables, enumerators, etc.
   std::deque<PendingImplicitInstantiation> PendingLocalImplicitInstantiations;
 
+  class SavePendingLocalImplicitInstantiationsRAII {
+  public:
+    SavePendingLocalImplicitInstantiationsRAII(Sema &S): S(S) {
+      SavedPendingLocalImplicitInstantiations.swap(
+          S.PendingLocalImplicitInstantiations);
+    }
+
+    ~SavePendingLocalImplicitInstantiationsRAII() {
+      assert(S.PendingLocalImplicitInstantiations.empty() &&
+             "there shouldn't be any pending local implicit instantiations");
+      SavedPendingLocalImplicitInstantiations.swap(
+          S.PendingLocalImplicitInstantiations);
+    }
+
+  private:
+    Sema &S;
+    std::deque<PendingImplicitInstantiation>
+    SavedPendingLocalImplicitInstantiations;
+  };
+
   void PerformPendingInstantiations(bool LocalOnly = false);
 
   TypeSourceInfo *SubstType(TypeSourceInfo *T,
@@ -6435,7 +6606,7 @@
                       ParmVarDecl **Params, unsigned NumParams,
                       const MultiLevelTemplateArgumentList &TemplateArgs,
                       SmallVectorImpl<QualType> &ParamTypes,
-                      SmallVectorImpl<ParmVarDecl *> *OutParams = 0);
+                      SmallVectorImpl<ParmVarDecl *> *OutParams = nullptr);
   ExprResult SubstExpr(Expr *E,
                        const MultiLevelTemplateArgumentList &TemplateArgs);
 
@@ -6499,8 +6670,8 @@
 
   void InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
                         const Decl *Pattern, Decl *Inst,
-                        LateInstantiatedAttrVec *LateAttrs = 0,
-                        LocalInstantiationScope *OuterMostScope = 0);
+                        LateInstantiatedAttrVec *LateAttrs = nullptr,
+                        LocalInstantiationScope *OuterMostScope = nullptr);
 
   bool
   InstantiateClassTemplateSpecialization(SourceLocation PointOfInstantiation,
@@ -6545,8 +6716,8 @@
       const TemplateArgumentListInfo &TemplateArgsInfo,
       SmallVectorImpl<TemplateArgument> &Converted,
       SourceLocation PointOfInstantiation, void *InsertPos,
-      LateInstantiatedAttrVec *LateAttrs = 0,
-      LocalInstantiationScope *StartingScope = 0);
+      LateInstantiatedAttrVec *LateAttrs = nullptr,
+      LocalInstantiationScope *StartingScope = nullptr);
   VarTemplateSpecializationDecl *CompleteVarTemplateSpecializationDecl(
       VarTemplateSpecializationDecl *VarSpec, VarDecl *PatternDecl,
       const MultiLevelTemplateArgumentList &TemplateArgs);
@@ -6680,8 +6851,8 @@
   /// \param lexicalDC Container for redeclaredProperty.
   void ProcessPropertyDecl(ObjCPropertyDecl *property,
                            ObjCContainerDecl *CD,
-                           ObjCPropertyDecl *redeclaredProperty = 0,
-                           ObjCContainerDecl *lexicalDC = 0);
+                           ObjCPropertyDecl *redeclaredProperty = nullptr,
+                           ObjCContainerDecl *lexicalDC = nullptr);
 
 
   void DiagnosePropertyMismatch(ObjCPropertyDecl *Property,
@@ -6702,7 +6873,7 @@
                       Selector GetterSel, Selector SetterSel,
                       bool *OverridingProperty,
                       tok::ObjCKeywordKind MethodImplKind,
-                      DeclContext *lexicalDC = 0);
+                      DeclContext *lexicalDC = nullptr);
 
   Decl *ActOnPropertyImplDecl(Scope *S,
                               SourceLocation AtLoc,
@@ -6865,6 +7036,27 @@
                                   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,
+                                        ObjCMethodDecl *&ClassMethod,
+                                        ObjCMethodDecl *&InstanceMethod,
+                                        TypedefNameDecl *&TDNDecl,
+                                        bool CfToNs);
+  
+  bool CheckObjCBridgeRelatedConversions(SourceLocation Loc,
+                                         QualType DestType, QualType SrcType,
+                                         Expr *&SrcExpr);
+  
+  bool ConversionToObjCStringLiteralCheck(QualType DstType, Expr *&SrcExpr);
+  
   bool checkInitMethod(ObjCMethodDecl *method, QualType receiverTypeIfCall);
 
   /// \brief Check whether the given new method is a valid override of the
@@ -6932,6 +7124,69 @@
   /// \#pragma comment(kind, "arg").
   void ActOnPragmaMSComment(PragmaMSCommentKind Kind, StringRef Arg);
 
+  /// ActOnPragmaMSPointersToMembers - called on well formed \#pragma
+  /// pointers_to_members(representation method[, general purpose
+  /// representation]).
+  void ActOnPragmaMSPointersToMembers(
+      LangOptions::PragmaMSPointersToMembersKind Kind,
+      SourceLocation PragmaLoc);
+
+  /// \brief Called on well formed \#pragma vtordisp().
+  void ActOnPragmaMSVtorDisp(PragmaVtorDispKind Kind, SourceLocation PragmaLoc,
+                             MSVtorDispAttr::Mode Value);
+
+  enum PragmaSectionKind {
+    PSK_DataSeg,
+    PSK_BSSSeg,
+    PSK_ConstSeg,
+    PSK_CodeSeg,
+  };
+
+  enum PragmaSectionFlag : unsigned {
+    PSF_None = 0,
+    PSF_Read = 0x1,
+    PSF_Write = 0x2,
+    PSF_Execute = 0x4,
+    PSF_Implicit = 0x8,
+    PSF_Invalid = 0x80000000U,
+  };
+
+  struct SectionInfo {
+    DeclaratorDecl *Decl;
+    SourceLocation PragmaSectionLocation;
+    int SectionFlags;
+    SectionInfo() {}
+    SectionInfo(DeclaratorDecl *Decl,
+                SourceLocation PragmaSectionLocation,
+                int SectionFlags)
+      : Decl(Decl),
+        PragmaSectionLocation(PragmaSectionLocation),
+        SectionFlags(SectionFlags) {}
+  };
+
+  llvm::StringMap<SectionInfo> SectionInfos;
+  bool UnifySection(const StringRef &SectionName, 
+                    int SectionFlags,
+                    DeclaratorDecl *TheDecl);
+  bool UnifySection(const StringRef &SectionName,
+                    int SectionFlags,
+                    SourceLocation PragmaSectionLocation);
+
+  /// \brief Called on well formed \#pragma bss_seg/data_seg/const_seg/code_seg.
+  void ActOnPragmaMSSeg(SourceLocation PragmaLocation,
+                        PragmaMsStackAction Action,
+                        llvm::StringRef StackSlotLabel,
+                        StringLiteral *SegmentName,
+                        llvm::StringRef PragmaName);
+
+  /// \brief Called on well formed \#pragma section().
+  void ActOnPragmaMSSection(SourceLocation PragmaLocation,
+                            int SectionFlags, StringLiteral *SegmentName);
+
+  /// \brief Called on well-formed \#pragma init_seg().
+  void ActOnPragmaMSInitSeg(SourceLocation PragmaLocation,
+                            StringLiteral *SegmentName);
+
   /// ActOnPragmaDetectMismatch - Call on well-formed \#pragma detect_mismatch
   void ActOnPragmaDetectMismatch(StringRef Name, StringRef Value);
 
@@ -7003,6 +7258,25 @@
   /// the appropriate attribute.
   void AddCFAuditedAttribute(Decl *D);
 
+  /// \brief Called on well formed \#pragma clang optimize.
+  void ActOnPragmaOptimize(bool On, SourceLocation PragmaLoc);
+
+  /// \brief Get the location for the currently active "\#pragma clang optimize
+  /// off". If this location is invalid, then the state of the pragma is "on".
+  SourceLocation getOptimizeOffPragmaLocation() const {
+    return OptimizeOffPragmaLocation;
+  }
+
+  /// \brief Only called on function definitions; if there is a pragma in scope
+  /// with the effect of a range-based optnone, consider marking the function
+  /// with attribute optnone.
+  void AddRangeBasedOptnone(FunctionDecl *FD);
+
+  /// \brief Adds the 'optnone' attribute to the function declaration if there
+  /// are no conflicts; Loc represents the location causing the 'optnone'
+  /// attribute to be added (usually because of a pragma).
+  void AddOptnoneAttributeIfNoConflicts(FunctionDecl *FD, SourceLocation Loc);
+
   /// AddAlignedAttr - Adds an aligned attribute to a particular declaration.
   void AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E,
                       unsigned SpellingListIndex, bool IsPackExpansion);
@@ -7015,11 +7289,15 @@
   /// \brief Initialization of data-sharing attributes stack.
   void InitDataSharingAttributesStack();
   void DestroyDataSharingAttributesStack();
+  ExprResult VerifyPositiveIntegerConstantInClause(Expr *Op,
+                                                   OpenMPClauseKind CKind);
 public:
+  ExprResult PerformOpenMPImplicitIntegerConversion(SourceLocation OpLoc,
+                                                    Expr *Op);
   /// \brief Called on start of new data sharing attribute block.
   void StartOpenMPDSABlock(OpenMPDirectiveKind K,
-                           const DeclarationNameInfo &DirName,
-                           Scope *CurScope);
+                           const DeclarationNameInfo &DirName, Scope *CurScope,
+                           SourceLocation Loc);
   /// \brief Called on end of data sharing attribute block.
   void EndOpenMPDSABlock(Stmt *CurDirective);
 
@@ -7033,12 +7311,15 @@
   DeclGroupPtrTy ActOnOpenMPThreadprivateDirective(
                                      SourceLocation Loc,
                                      ArrayRef<Expr *> VarList);
-  // \brief Builds a new OpenMPThreadPrivateDecl and checks its correctness.
+  /// \brief Builds a new OpenMPThreadPrivateDecl and checks its correctness.
   OMPThreadPrivateDecl *CheckOMPThreadPrivateDecl(
                                      SourceLocation Loc,
                                      ArrayRef<Expr *> VarList);
 
+  /// \brief Initialization of captured region for OpenMP region.
+  void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope);
   StmtResult ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,
+                                            const DeclarationNameInfo &DirName,
                                             ArrayRef<OMPClause *> Clauses,
                                             Stmt *AStmt,
                                             SourceLocation StartLoc,
@@ -7049,6 +7330,100 @@
                                           Stmt *AStmt,
                                           SourceLocation StartLoc,
                                           SourceLocation EndLoc);
+  /// \brief Called on well-formed '\#pragma omp simd' after parsing
+  /// of the associated statement.
+  StmtResult ActOnOpenMPSimdDirective(
+      ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+      SourceLocation EndLoc,
+      llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA);
+  /// \brief Called on well-formed '\#pragma omp for' after parsing
+  /// of the associated statement.
+  StmtResult ActOnOpenMPForDirective(
+      ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+      SourceLocation EndLoc,
+      llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA);
+  /// \brief Called on well-formed '\#pragma omp sections' after parsing
+  /// of the associated statement.
+  StmtResult ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
+                                          Stmt *AStmt, SourceLocation StartLoc,
+                                          SourceLocation EndLoc);
+  /// \brief Called on well-formed '\#pragma omp section' after parsing of the
+  /// associated statement.
+  StmtResult ActOnOpenMPSectionDirective(Stmt *AStmt, SourceLocation StartLoc,
+                                         SourceLocation EndLoc);
+  /// \brief Called on well-formed '\#pragma omp single' after parsing of the
+  /// associated statement.
+  StmtResult ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
+                                        Stmt *AStmt, SourceLocation StartLoc,
+                                        SourceLocation EndLoc);
+  /// \brief Called on well-formed '\#pragma omp master' after parsing of the
+  /// associated statement.
+  StmtResult ActOnOpenMPMasterDirective(Stmt *AStmt, SourceLocation StartLoc,
+                                        SourceLocation EndLoc);
+  /// \brief Called on well-formed '\#pragma omp critical' after parsing of the
+  /// associated statement.
+  StmtResult ActOnOpenMPCriticalDirective(const DeclarationNameInfo &DirName,
+                                          Stmt *AStmt, SourceLocation StartLoc,
+                                          SourceLocation EndLoc);
+  /// \brief Called on well-formed '\#pragma omp parallel for' after parsing
+  /// of the  associated statement.
+  StmtResult ActOnOpenMPParallelForDirective(
+      ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+      SourceLocation EndLoc,
+      llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA);
+  /// \brief Called on well-formed '\#pragma omp parallel sections' after
+  /// parsing of the  associated statement.
+  StmtResult ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
+                                                  Stmt *AStmt,
+                                                  SourceLocation StartLoc,
+                                                  SourceLocation EndLoc);
+  /// \brief Called on well-formed '\#pragma omp task' after parsing of the
+  /// associated statement.
+  StmtResult ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
+                                      Stmt *AStmt, SourceLocation StartLoc,
+                                      SourceLocation EndLoc);
+  /// \brief Called on well-formed '\#pragma omp taskyield'.
+  StmtResult ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
+                                           SourceLocation EndLoc);
+  /// \brief Called on well-formed '\#pragma omp barrier'.
+  StmtResult ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
+                                         SourceLocation EndLoc);
+  /// \brief Called on well-formed '\#pragma omp taskwait'.
+  StmtResult ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
+                                          SourceLocation EndLoc);
+  /// \brief Called on well-formed '\#pragma omp flush'.
+  StmtResult ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
+                                       SourceLocation StartLoc,
+                                       SourceLocation EndLoc);
+
+  OMPClause *ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,
+                                         Expr *Expr,
+                                         SourceLocation StartLoc,
+                                         SourceLocation LParenLoc,
+                                         SourceLocation EndLoc);
+  /// \brief Called on well-formed 'if' clause.
+  OMPClause *ActOnOpenMPIfClause(Expr *Condition, SourceLocation StartLoc,
+                                 SourceLocation LParenLoc,
+                                 SourceLocation EndLoc);
+  /// \brief Called on well-formed 'final' clause.
+  OMPClause *ActOnOpenMPFinalClause(Expr *Condition, SourceLocation StartLoc,
+                                    SourceLocation LParenLoc,
+                                    SourceLocation EndLoc);
+  /// \brief Called on well-formed 'num_threads' clause.
+  OMPClause *ActOnOpenMPNumThreadsClause(Expr *NumThreads,
+                                         SourceLocation StartLoc,
+                                         SourceLocation LParenLoc,
+                                         SourceLocation EndLoc);
+  /// \brief Called on well-formed 'safelen' clause.
+  OMPClause *ActOnOpenMPSafelenClause(Expr *Length,
+                                      SourceLocation StartLoc,
+                                      SourceLocation LParenLoc,
+                                      SourceLocation EndLoc);
+  /// \brief Called on well-formed 'collapse' clause.
+  OMPClause *ActOnOpenMPCollapseClause(Expr *NumForLoops,
+                                       SourceLocation StartLoc,
+                                       SourceLocation LParenLoc,
+                                       SourceLocation EndLoc);
 
   OMPClause *ActOnOpenMPSimpleClause(OpenMPClauseKind Kind,
                                      unsigned Argument,
@@ -7062,12 +7437,50 @@
                                       SourceLocation StartLoc,
                                       SourceLocation LParenLoc,
                                       SourceLocation EndLoc);
+  /// \brief Called on well-formed 'proc_bind' clause.
+  OMPClause *ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind,
+                                       SourceLocation KindLoc,
+                                       SourceLocation StartLoc,
+                                       SourceLocation LParenLoc,
+                                       SourceLocation EndLoc);
 
-  OMPClause *ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
-                                      ArrayRef<Expr *> Vars,
-                                      SourceLocation StartLoc,
-                                      SourceLocation LParenLoc,
+  OMPClause *ActOnOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind,
+                                                unsigned Argument, Expr *Expr,
+                                                SourceLocation StartLoc,
+                                                SourceLocation LParenLoc,
+                                                SourceLocation ArgumentLoc,
+                                                SourceLocation CommaLoc,
+                                                SourceLocation EndLoc);
+  /// \brief Called on well-formed 'schedule' clause.
+  OMPClause *ActOnOpenMPScheduleClause(OpenMPScheduleClauseKind Kind,
+                                       Expr *ChunkSize, SourceLocation StartLoc,
+                                       SourceLocation LParenLoc,
+                                       SourceLocation KindLoc,
+                                       SourceLocation CommaLoc,
+                                       SourceLocation EndLoc);
+
+  OMPClause *ActOnOpenMPClause(OpenMPClauseKind Kind, SourceLocation StartLoc,
+                               SourceLocation EndLoc);
+  /// \brief Called on well-formed 'ordered' clause.
+  OMPClause *ActOnOpenMPOrderedClause(SourceLocation StartLoc,
                                       SourceLocation EndLoc);
+  /// \brief Called on well-formed 'nowait' clause.
+  OMPClause *ActOnOpenMPNowaitClause(SourceLocation StartLoc,
+                                     SourceLocation EndLoc);
+  /// \brief Called on well-formed 'untied' clause.
+  OMPClause *ActOnOpenMPUntiedClause(SourceLocation StartLoc,
+                                     SourceLocation EndLoc);
+  /// \brief Called on well-formed 'mergeable' clause.
+  OMPClause *ActOnOpenMPMergeableClause(SourceLocation StartLoc,
+                                        SourceLocation EndLoc);
+
+  OMPClause *
+  ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef<Expr *> Vars,
+                           Expr *TailExpr, SourceLocation StartLoc,
+                           SourceLocation LParenLoc, SourceLocation ColonLoc,
+                           SourceLocation EndLoc,
+                           CXXScopeSpec &ReductionIdScopeSpec,
+                           const DeclarationNameInfo &ReductionId);
   /// \brief Called on well-formed 'private' clause.
   OMPClause *ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
                                       SourceLocation StartLoc,
@@ -7078,11 +7491,52 @@
                                            SourceLocation StartLoc,
                                            SourceLocation LParenLoc,
                                            SourceLocation EndLoc);
+  /// \brief Called on well-formed 'lastprivate' clause.
+  OMPClause *ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList,
+                                          SourceLocation StartLoc,
+                                          SourceLocation LParenLoc,
+                                          SourceLocation EndLoc);
   /// \brief Called on well-formed 'shared' clause.
   OMPClause *ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
                                      SourceLocation StartLoc,
                                      SourceLocation LParenLoc,
                                      SourceLocation EndLoc);
+  /// \brief Called on well-formed 'reduction' clause.
+  OMPClause *
+  ActOnOpenMPReductionClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc,
+                             SourceLocation LParenLoc, SourceLocation ColonLoc,
+                             SourceLocation EndLoc,
+                             CXXScopeSpec &ReductionIdScopeSpec,
+                             const DeclarationNameInfo &ReductionId);
+  /// \brief Called on well-formed 'linear' clause.
+  OMPClause *ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList,
+                                     Expr *Step,
+                                     SourceLocation StartLoc,
+                                     SourceLocation LParenLoc,
+                                     SourceLocation ColonLoc,
+                                     SourceLocation EndLoc);
+  /// \brief Called on well-formed 'aligned' clause.
+  OMPClause *ActOnOpenMPAlignedClause(ArrayRef<Expr *> VarList,
+                                      Expr *Alignment,
+                                      SourceLocation StartLoc,
+                                      SourceLocation LParenLoc,
+                                      SourceLocation ColonLoc,
+                                      SourceLocation EndLoc);
+  /// \brief Called on well-formed 'copyin' clause.
+  OMPClause *ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
+                                     SourceLocation StartLoc,
+                                     SourceLocation LParenLoc,
+                                     SourceLocation EndLoc);
+  /// \brief Called on well-formed 'copyprivate' clause.
+  OMPClause *ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
+                                          SourceLocation StartLoc,
+                                          SourceLocation LParenLoc,
+                                          SourceLocation EndLoc);
+  /// \brief Called on well-formed 'flush' pseudo clause.
+  OMPClause *ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
+                                    SourceLocation StartLoc,
+                                    SourceLocation LParenLoc,
+                                    SourceLocation EndLoc);
 
   /// \brief The kind of conversion being performed.
   enum CheckedConversionKind {
@@ -7101,7 +7555,7 @@
   /// If isLvalue, the result of the cast is an lvalue.
   ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK,
                                ExprValueKind VK = VK_RValue,
-                               const CXXCastPath *BasePath = 0,
+                               const CXXCastPath *BasePath = nullptr,
                                CheckedConversionKind CCK
                                   = CCK_ImplicitConversion);
 
@@ -7118,6 +7572,10 @@
   // functions and arrays to their respective pointers (C99 6.3.2.1).
   ExprResult UsualUnaryConversions(Expr *E);
 
+  /// CallExprUnaryConversions - a special case of an unary conversion
+  /// performed on a function designator of a call expression.
+  ExprResult CallExprUnaryConversions(Expr *E);
+
   // DefaultFunctionArrayConversion - converts functions and arrays
   // to their respective pointers (C99 6.3.2.1).
   ExprResult DefaultFunctionArrayConversion(Expr *E);
@@ -7167,13 +7625,14 @@
   /// function, issuing a diagnostic if not.
   void checkVariadicArgument(const Expr *E, VariadicCallType CT);
 
+  /// Check to see if a given expression could have '.c_str()' called on it.
+  bool hasCStrMethod(const Expr *E);
+
   /// GatherArgumentsForCall - Collector argument expressions for various
   /// form of call prototypes.
-  bool GatherArgumentsForCall(SourceLocation CallLoc,
-                              FunctionDecl *FDecl,
+  bool GatherArgumentsForCall(SourceLocation CallLoc, FunctionDecl *FDecl,
                               const FunctionProtoType *Proto,
-                              unsigned FirstProtoArg,
-                              ArrayRef<Expr *> Args,
+                              unsigned FirstParam, ArrayRef<Expr *> Args,
                               SmallVectorImpl<Expr *> &AllArgs,
                               VariadicCallType CallType = VariadicDoesNotApply,
                               bool AllowExplicit = false,
@@ -7271,7 +7730,7 @@
                                 SourceLocation Loc,
                                 QualType DstType, QualType SrcType,
                                 Expr *SrcExpr, AssignmentAction Action,
-                                bool *Complained = 0);
+                                bool *Complained = nullptr);
 
   /// DiagnoseAssignmentEnum - Warn if assignment to enum is a constant
   /// integer not in the range of enum values.
@@ -7342,10 +7801,10 @@
     bool IsCompAssign = false);
   QualType CheckAdditionOperands( // C99 6.5.6
     ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, unsigned Opc,
-    QualType* CompLHSTy = 0);
+    QualType* CompLHSTy = nullptr);
   QualType CheckSubtractionOperands( // C99 6.5.6
     ExprResult &LHS, ExprResult &RHS, SourceLocation Loc,
-    QualType* CompLHSTy = 0);
+    QualType* CompLHSTy = nullptr);
   QualType CheckShiftOperands( // C99 6.5.7
     ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, unsigned Opc,
     bool IsCompAssign = false);
@@ -7378,15 +7837,15 @@
     ExprResult &cond, ExprResult &lhs, ExprResult &rhs,
     ExprValueKind &VK, ExprObjectKind &OK, SourceLocation questionLoc);
   QualType FindCompositePointerType(SourceLocation Loc, Expr *&E1, Expr *&E2,
-                                    bool *NonStandardCompositeType = 0);
+                                    bool *NonStandardCompositeType = nullptr);
   QualType FindCompositePointerType(SourceLocation Loc,
                                     ExprResult &E1, ExprResult &E2,
-                                    bool *NonStandardCompositeType = 0) {
-    Expr *E1Tmp = E1.take(), *E2Tmp = E2.take();
+                                    bool *NonStandardCompositeType = nullptr) {
+    Expr *E1Tmp = E1.get(), *E2Tmp = E2.get();
     QualType Composite = FindCompositePointerType(Loc, E1Tmp, E2Tmp,
                                                   NonStandardCompositeType);
-    E1 = Owned(E1Tmp);
-    E2 = Owned(E2Tmp);
+    E1 = E1Tmp;
+    E2 = E2Tmp;
     return Composite;
   }
 
@@ -7396,6 +7855,10 @@
   bool DiagnoseConditionalForNull(Expr *LHSExpr, Expr *RHSExpr,
                                   SourceLocation QuestionLoc);
 
+  void DiagnoseAlwaysNonNullPointer(Expr *E,
+                                    Expr::NullPointerConstantKind NullType,
+                                    bool IsEqual, SourceRange Range);
+
   /// type checking for vector binary operators.
   QualType CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
                                SourceLocation Loc, bool IsCompAssign);
@@ -7405,6 +7868,8 @@
   QualType CheckVectorLogicalOperands(ExprResult &LHS, ExprResult &RHS,
                                       SourceLocation Loc);
 
+  bool isLaxVectorConversion(QualType srcType, QualType destType);
+
   /// type checking declaration initializers (C99 6.7.8)
   bool CheckForConstantInitializer(Expr *e, QualType t);
 
@@ -7477,7 +7942,9 @@
   ARCConversionResult CheckObjCARCConversion(SourceRange castRange,
                                              QualType castType, Expr *&op,
                                              CheckedConversionKind CCK,
-                                             bool DiagnoseCFAudited = false);
+                                             bool DiagnoseCFAudited = false,
+                                             BinaryOperatorKind Opc = BO_PtrMemD
+                                             );
 
   Expr *stripARCUnbridgedCast(Expr *e);
   void diagnoseARCUnbridgedCast(Expr *e);
@@ -7585,7 +8052,8 @@
   ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
                                              unsigned DiagID,
                                              bool AllowFold = true);
-  ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result=0);
+  ExprResult VerifyIntegerConstantExpression(Expr *E,
+                                             llvm::APSInt *Result = nullptr);
 
   /// VerifyBitField - verifies that a bit field expression is an ICE and has
   /// the correct width, and that the field type is valid.
@@ -7593,7 +8061,7 @@
   /// Can optionally return whether the bit-field is of width 0
   ExprResult VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName,
                             QualType FieldTy, bool IsMsStruct,
-                            Expr *BitWidth, bool *ZeroWidth = 0);
+                            Expr *BitWidth, bool *ZeroWidth = nullptr);
 
   enum CUDAFunctionTarget {
     CFT_Device,
@@ -7717,7 +8185,7 @@
   void CodeCompleteObjCInstanceMessage(Scope *S, Expr *Receiver,
                                        ArrayRef<IdentifierInfo *> SelIdents,
                                        bool AtArgumentExpression,
-                                       ObjCInterfaceDecl *Super = 0);
+                                       ObjCInterfaceDecl *Super = nullptr);
   void CodeCompleteObjCForCollection(Scope *S,
                                      DeclGroupPtrTy IterationVar);
   void CodeCompleteObjCSelector(Scope *S,
@@ -7770,7 +8238,7 @@
 
 private:
   void CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,
-                        const ArraySubscriptExpr *ASE=0,
+                        const ArraySubscriptExpr *ASE=nullptr,
                         bool AllowOnePastEnd=true, bool IndexNegated=false);
   void CheckArrayAccess(const Expr *E);
   // Used to grab the relevant information from a FormatAttr and a
@@ -7796,21 +8264,24 @@
                             SourceLocation Loc);
 
   void checkCall(NamedDecl *FDecl, ArrayRef<const Expr *> Args,
-                 unsigned NumProtoArgs, bool IsMemberFunction,
-                 SourceLocation Loc, SourceRange Range,
-                 VariadicCallType CallType);
-
+                 unsigned NumParams, bool IsMemberFunction, SourceLocation Loc,
+                 SourceRange Range, VariadicCallType CallType);
 
   bool CheckObjCString(Expr *Arg);
 
   ExprResult CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
 
-  bool CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall);
+  bool CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall,
+                                    unsigned MaxWidth);
+  bool CheckNeonBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
   bool CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+
   bool CheckAArch64BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
   bool CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+  bool CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
 
   bool SemaBuiltinVAStart(CallExpr *TheCall);
+  bool SemaBuiltinVAStartARM(CallExpr *Call);
   bool SemaBuiltinUnorderedCompare(CallExpr *TheCall);
   bool SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs);
 
@@ -7823,13 +8294,15 @@
 
 private:
   bool SemaBuiltinPrefetch(CallExpr *TheCall);
-  bool SemaBuiltinObjectSize(CallExpr *TheCall);
+  bool SemaBuiltinAssume(CallExpr *TheCall);
   bool SemaBuiltinLongjmp(CallExpr *TheCall);
   ExprResult SemaBuiltinAtomicOverloaded(ExprResult TheCallResult);
   ExprResult SemaAtomicOpsOverloaded(ExprResult TheCallResult,
                                      AtomicExpr::AtomicOp Op);
   bool SemaBuiltinConstantArg(CallExpr *TheCall, int ArgNum,
                               llvm::APSInt &Result);
+  bool SemaBuiltinConstantArgRange(CallExpr *TheCall, int ArgNum,
+                                   int Low, int High);
 
 public:
   enum FormatStringType {
@@ -7864,9 +8337,9 @@
                             SourceLocation Loc, SourceRange range,
                             llvm::SmallBitVector &CheckedVarArgs);
 
-  void CheckNonNullArguments(const NonNullAttr *NonNull,
-                             const Expr * const *ExprArgs,
-                             SourceLocation CallSiteLoc);
+  void CheckAbsoluteValueFunction(const CallExpr *Call,
+                                  const FunctionDecl *FDecl,
+                                  IdentifierInfo *FnInfo);
 
   void CheckMemaccessArguments(const CallExpr *Call,
                                unsigned BId,
@@ -7878,8 +8351,12 @@
   void CheckStrncatArguments(const CallExpr *Call,
                              IdentifierInfo *FnName);
 
-  void CheckReturnStackAddr(Expr *RetValExp, QualType lhsType,
-                            SourceLocation ReturnLoc);
+  void CheckReturnValExpr(Expr *RetValExp, QualType lhsType,
+                          SourceLocation ReturnLoc,
+                          bool isObjCMethod = false,
+                          const AttrVec *Attrs = nullptr,
+                          const FunctionDecl *FD = nullptr);
+
   void CheckFloatComparison(SourceLocation Loc, Expr* LHS, Expr* RHS);
   void CheckImplicitConversions(Expr *E, SourceLocation CC = SourceLocation());
   void CheckForIntOverflow(Expr *E);
@@ -7893,6 +8370,10 @@
   void CheckBitFieldInitialization(SourceLocation InitLoc, FieldDecl *Field,
                                    Expr *Init);
 
+  /// \brief Check if the given expression contains 'break' or 'continue'
+  /// statement that produces control flow different from GCC.
+  void CheckBreakContinueBinding(Expr *E);
+
 public:
   /// \brief Register a magic integral constant to be used as a type tag.
   void RegisterTypeTagForDatatype(const IdentifierInfo *ArgumentKind,
@@ -7921,7 +8402,7 @@
 
 private:
   /// \brief A map from magic value to type information.
-  OwningPtr<llvm::DenseMap<TypeTagMagicValue, TypeTagData> >
+  std::unique_ptr<llvm::DenseMap<TypeTagMagicValue, TypeTagData>>
       TypeTagForDatatypeMagicValues;
 
   /// \brief Peform checks on a call of a function with argument_with_type_tag
@@ -7954,6 +8435,10 @@
   /// template substitution or instantiation.
   Scope *getCurScope() const { return CurScope; }
 
+  void incrementMSLocalManglingNumber() const {
+    return CurScope->incrementMSLocalManglingNumber();
+  }
+
   IdentifierInfo *getSuperIdentifier() const;
   IdentifierInfo *getFloat128Identifier() const;
 
@@ -7981,7 +8466,7 @@
 public:
   EnterExpressionEvaluationContext(Sema &Actions,
                                    Sema::ExpressionEvaluationContext NewContext,
-                                   Decl *LambdaContextDecl = 0,
+                                   Decl *LambdaContextDecl = nullptr,
                                    bool IsDecltype = false)
     : Actions(Actions) {
     Actions.PushExpressionEvaluationContext(NewContext, LambdaContextDecl,
diff --git a/include/clang/Sema/SemaInternal.h b/include/clang/Sema/SemaInternal.h
index 01d4cc9..9199b0f 100644
--- a/include/clang/Sema/SemaInternal.h
+++ b/include/clang/Sema/SemaInternal.h
@@ -24,44 +24,68 @@
 inline PartialDiagnostic Sema::PDiag(unsigned DiagID) {
   return PartialDiagnostic(DiagID, Context.getDiagAllocator());
 }
-

-

-// This requires the variable to be non-dependent and the initializer

-// to not be value dependent.

-inline bool IsVariableAConstantExpression(VarDecl *Var, ASTContext &Context) {

-  const VarDecl *DefVD = 0;

-  return !isa<ParmVarDecl>(Var) &&

-    Var->isUsableInConstantExpressions(Context) &&

-    Var->getAnyInitializer(DefVD) && DefVD->checkInitIsICE(); 

-}

-

-// Directly mark a variable odr-used. Given a choice, prefer to use 

-// MarkVariableReferenced since it does additional checks and then 

-// calls MarkVarDeclODRUsed.

-// If the variable must be captured:

-//  - if FunctionScopeIndexToStopAt is null, capture it in the CurContext

-//  - else capture it in the DeclContext that maps to the 

-//    *FunctionScopeIndexToStopAt on the FunctionScopeInfo stack.  

-inline void MarkVarDeclODRUsed(VarDecl *Var,

-    SourceLocation Loc, Sema &SemaRef,

-    const unsigned *const FunctionScopeIndexToStopAt) {

-  // Keep track of used but undefined variables.

-  // FIXME: We shouldn't suppress this warning for static data members.

-  if (Var->hasDefinition(SemaRef.Context) == VarDecl::DeclarationOnly &&

-    !Var->isExternallyVisible() &&

-    !(Var->isStaticDataMember() && Var->hasInit())) {

-      SourceLocation &old = SemaRef.UndefinedButUsed[Var->getCanonicalDecl()];

-      if (old.isInvalid()) old = Loc;

-  }

-  QualType CaptureType, DeclRefType;

-  SemaRef.tryCaptureVariable(Var, Loc, Sema::TryCapture_Implicit, 

-    /*EllipsisLoc*/ SourceLocation(),

-    /*BuildAndDiagnose*/ true, 

-    CaptureType, DeclRefType, 

-    FunctionScopeIndexToStopAt);

-

-  Var->markUsed(SemaRef.Context);

+
+inline bool
+FTIHasSingleVoidParameter(const DeclaratorChunk::FunctionTypeInfo &FTI) {
+  return FTI.NumParams == 1 && !FTI.isVariadic &&
+         FTI.Params[0].Ident == nullptr && FTI.Params[0].Param &&
+         cast<ParmVarDecl>(FTI.Params[0].Param)->getType()->isVoidType();
 }
+
+inline bool
+FTIHasNonVoidParameters(const DeclaratorChunk::FunctionTypeInfo &FTI) {
+  // Assume FTI is well-formed.
+  return FTI.NumParams && !FTIHasSingleVoidParameter(FTI);
+}
+
+// This requires the variable to be non-dependent and the initializer
+// to not be value dependent.
+inline bool IsVariableAConstantExpression(VarDecl *Var, ASTContext &Context) {
+  const VarDecl *DefVD = nullptr;
+  return !isa<ParmVarDecl>(Var) &&
+    Var->isUsableInConstantExpressions(Context) &&
+    Var->getAnyInitializer(DefVD) && DefVD->checkInitIsICE(); 
+}
+
+// Directly mark a variable odr-used. Given a choice, prefer to use 
+// MarkVariableReferenced since it does additional checks and then 
+// calls MarkVarDeclODRUsed.
+// If the variable must be captured:
+//  - if FunctionScopeIndexToStopAt is null, capture it in the CurContext
+//  - else capture it in the DeclContext that maps to the 
+//    *FunctionScopeIndexToStopAt on the FunctionScopeInfo stack.  
+inline void MarkVarDeclODRUsed(VarDecl *Var,
+    SourceLocation Loc, Sema &SemaRef,
+    const unsigned *const FunctionScopeIndexToStopAt) {
+  // Keep track of used but undefined variables.
+  // FIXME: We shouldn't suppress this warning for static data members.
+  if (Var->hasDefinition(SemaRef.Context) == VarDecl::DeclarationOnly &&
+    !Var->isExternallyVisible() &&
+    !(Var->isStaticDataMember() && Var->hasInit())) {
+      SourceLocation &old = SemaRef.UndefinedButUsed[Var->getCanonicalDecl()];
+      if (old.isInvalid()) old = Loc;
+  }
+  QualType CaptureType, DeclRefType;
+  SemaRef.tryCaptureVariable(Var, Loc, Sema::TryCapture_Implicit, 
+    /*EllipsisLoc*/ SourceLocation(),
+    /*BuildAndDiagnose*/ true, 
+    CaptureType, DeclRefType, 
+    FunctionScopeIndexToStopAt);
+
+  Var->markUsed(SemaRef.Context);
+}
+
+/// Return a DLL attribute from the declaration.
+inline InheritableAttr *getDLLAttr(Decl *D) {
+  assert(!(D->hasAttr<DLLImportAttr>() && D->hasAttr<DLLExportAttr>()) &&
+         "A declaration cannot be both dllimport and dllexport.");
+  if (auto *Import = D->getAttr<DLLImportAttr>())
+    return Import;
+  if (auto *Export = D->getAttr<DLLExportAttr>())
+    return Export;
+  return nullptr;
+}
+
 }
 
 #endif
diff --git a/include/clang/Sema/SemaLambda.h b/include/clang/Sema/SemaLambda.h
index cf9fff1..f636750 100644
--- a/include/clang/Sema/SemaLambda.h
+++ b/include/clang/Sema/SemaLambda.h
@@ -1,39 +1,36 @@
-//===--- SemaLambda.h - Lambda Helper Functions --------------*- 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 provides some common utility functions for processing

-/// Lambdas.

-///

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

-

-#ifndef LLVM_CLANG_SEMA_LAMBDA_H

-#define LLVM_CLANG_SEMA_LAMBDA_H

-#include "clang/AST/ASTLambda.h"

-#include "clang/Sema/ScopeInfo.h"

-namespace clang {

- 

-// Given a lambda's call operator and a variable (or null for 'this'), 

-// compute the nearest enclosing lambda that is capture-ready (i.e 

-// the enclosing context is not dependent, and all intervening lambdas can 

-// either implicitly or explicitly capture Var)

-// 

-// Return the CallOperator of the capturable lambda and set function scope 

-// index to the correct index within the function scope stack to correspond 

-// to the capturable lambda.

-// If VarDecl *VD is null, we check for 'this' capture.

-CXXMethodDecl* 

-GetInnermostEnclosingCapturableLambda( 

-    ArrayRef<sema::FunctionScopeInfo*> FunctionScopes,

-    unsigned &FunctionScopeIndex,

-    DeclContext *const CurContext, VarDecl *VD, Sema &S);

-

-} // clang

-

-#endif // LLVM_CLANG_SEMA_LAMBDA_H

+//===--- SemaLambda.h - Lambda Helper Functions --------------*- 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 provides some common utility functions for processing
+/// Lambdas.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SEMA_LAMBDA_H
+#define LLVM_CLANG_SEMA_LAMBDA_H
+#include "clang/AST/ASTLambda.h"
+#include "clang/Sema/ScopeInfo.h"
+namespace clang {
+ 
+
+/// \brief Examines the FunctionScopeInfo stack to determine the nearest
+/// enclosing lambda (to the current lambda) that is 'capture-capable' for 
+/// the variable referenced in the current lambda (i.e. \p VarToCapture).
+/// If successful, returns the index into Sema's FunctionScopeInfo stack
+/// of the capture-capable lambda's LambdaScopeInfo. 
+/// See Implementation for more detailed comments. 
+
+Optional<unsigned> getStackIndexOfNearestEnclosingCaptureCapableLambda(
+    ArrayRef<const sema::FunctionScopeInfo *> FunctionScopes,
+    VarDecl *VarToCapture, Sema &S);
+
+} // clang
+
+#endif // LLVM_CLANG_SEMA_LAMBDA_H
diff --git a/include/clang/Sema/Template.h b/include/clang/Sema/Template.h
index 1af61d5..c08a5df 100644
--- a/include/clang/Sema/Template.h
+++ b/include/clang/Sema/Template.h
@@ -246,7 +246,7 @@
     LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope = false)
       : SemaRef(SemaRef), Outer(SemaRef.CurrentInstantiationScope),
         Exited(false), CombineWithOuterScope(CombineWithOuterScope),
-        PartiallySubstitutedPack(0)
+        PartiallySubstitutedPack(nullptr)
     {
       SemaRef.CurrentInstantiationScope = this;
     }
@@ -276,7 +276,7 @@
       LocalInstantiationScope *newScope =
         new LocalInstantiationScope(SemaRef, CombineWithOuterScope);
 
-      newScope->Outer = 0;
+      newScope->Outer = nullptr;
       if (Outer)
         newScope->Outer = Outer->cloneScopes(Outermost);
 
@@ -319,7 +319,7 @@
     /// \param D The declaration whose instantiation we are searching for.
     ///
     /// \returns A pointer to the declaration or argument pack of declarations
-    /// to which the declaration \c D is instantiataed, if found. Otherwise,
+    /// to which the declaration \c D is instantiated, if found. Otherwise,
     /// returns NULL.
     llvm::PointerUnion<Decl *, DeclArgumentPack *> *
     findInstantiationOf(const Decl *D);
@@ -348,17 +348,17 @@
     /// interest.
     void ResetPartiallySubstitutedPack() {
       assert(PartiallySubstitutedPack && "No partially-substituted pack");
-      PartiallySubstitutedPack = 0;
-      ArgsInPartiallySubstitutedPack = 0;
+      PartiallySubstitutedPack = nullptr;
+      ArgsInPartiallySubstitutedPack = nullptr;
       NumArgsInPartiallySubstitutedPack = 0;
     }
 
     /// \brief Retrieve the partially-substitued template parameter pack.
     ///
     /// If there is no partially-substituted parameter pack, returns NULL.
-    NamedDecl *getPartiallySubstitutedPack(
-                                      const TemplateArgument **ExplicitArgs = 0,
-                                           unsigned *NumExplicitArgs = 0) const;
+    NamedDecl *
+    getPartiallySubstitutedPack(const TemplateArgument **ExplicitArgs = nullptr,
+                                unsigned *NumExplicitArgs = nullptr) const;
   };
 
   class TemplateDeclInstantiator
@@ -391,8 +391,8 @@
                              const MultiLevelTemplateArgumentList &TemplateArgs)
       : SemaRef(SemaRef),
         SubstIndex(SemaRef, SemaRef.ArgumentPackSubstitutionIndex),
-        Owner(Owner), TemplateArgs(TemplateArgs), LateAttrs(0), StartingScope(0)
-    { }
+        Owner(Owner), TemplateArgs(TemplateArgs), LateAttrs(nullptr),
+        StartingScope(nullptr) {}
 
 // Define all the decl visitors using DeclNodes.inc
 #define DECL(DERIVED, BASE) \
@@ -436,8 +436,8 @@
 
     // Disable late instantiation of attributes.
     void disableLateAttributeInstantiation() {
-      LateAttrs = 0;
-      StartingScope = 0;
+      LateAttrs = nullptr;
+      StartingScope = nullptr;
     }
 
     LocalInstantiationScope *getStartingScope() const { return StartingScope; }
@@ -493,7 +493,7 @@
     Decl *VisitVarTemplateSpecializationDecl(
         VarTemplateDecl *VarTemplate, VarDecl *FromVar, void *InsertPos,
         const TemplateArgumentListInfo &TemplateArgsInfo,
-        llvm::ArrayRef<TemplateArgument> Converted);
+        ArrayRef<TemplateArgument> Converted);
 
     Decl *InstantiateTypedefNameDecl(TypedefNameDecl *D, bool IsTypeAlias);
     ClassTemplatePartialSpecializationDecl *
diff --git a/include/clang/Sema/TemplateDeduction.h b/include/clang/Sema/TemplateDeduction.h
index 1daa689..2c2c36d 100644
--- a/include/clang/Sema/TemplateDeduction.h
+++ b/include/clang/Sema/TemplateDeduction.h
@@ -19,6 +19,7 @@
 
 namespace clang {
 
+struct DeducedPack;
 class TemplateArgumentList;
 class Sema;
 
@@ -48,7 +49,8 @@
 
 public:
   TemplateDeductionInfo(SourceLocation Loc)
-    : Deduced(0), Loc(Loc), HasSFINAEDiagnostic(false), Expression(0) { }
+    : Deduced(nullptr), Loc(Loc), HasSFINAEDiagnostic(false),
+      Expression(nullptr) {}
 
   /// \brief Returns the location at which template argument is
   /// occurring.
@@ -59,7 +61,7 @@
   /// \brief Take ownership of the deduced template argument list.
   TemplateArgumentList *take() {
     TemplateArgumentList *Result = Deduced;
-    Deduced = 0;
+    Deduced = nullptr;
     return Result;
   }
 
@@ -161,6 +163,11 @@
   ///   an overloaded function which could not be resolved to a specific
   ///   function.
   Expr *Expression;
+
+  /// \brief Information on packs that we're currently expanding.
+  ///
+  /// FIXME: This should be kept internal to SemaTemplateDeduction.
+  SmallVector<DeducedPack *, 8> PendingDeducedPacks;
 };
 
 } // end namespace sema
diff --git a/include/clang/Sema/TypoCorrection.h b/include/clang/Sema/TypoCorrection.h
index f0b7726..6cab59c 100644
--- a/include/clang/Sema/TypoCorrection.h
+++ b/include/clang/Sema/TypoCorrection.h
@@ -39,7 +39,7 @@
   static const unsigned CallbackDistanceWeight = 150U;
 
   TypoCorrection(const DeclarationName &Name, NamedDecl *NameDecl,
-                 NestedNameSpecifier *NNS = 0, unsigned CharDistance = 0,
+                 NestedNameSpecifier *NNS = nullptr, unsigned CharDistance = 0,
                  unsigned QualifierDistance = 0)
       : CorrectionName(Name), CorrectionNameSpec(NNS),
         CharDistance(CharDistance), QualifierDistance(QualifierDistance),
@@ -49,7 +49,7 @@
       CorrectionDecls.push_back(NameDecl);
   }
 
-  TypoCorrection(NamedDecl *Name, NestedNameSpecifier *NNS = 0,
+  TypoCorrection(NamedDecl *Name, NestedNameSpecifier *NNS = nullptr,
                  unsigned CharDistance = 0)
       : CorrectionName(Name->getDeclName()), CorrectionNameSpec(NNS),
         CharDistance(CharDistance), QualifierDistance(0), CallbackDistance(0),
@@ -58,14 +58,14 @@
       CorrectionDecls.push_back(Name);
   }
 
-  TypoCorrection(DeclarationName Name, NestedNameSpecifier *NNS = 0,
+  TypoCorrection(DeclarationName Name, NestedNameSpecifier *NNS = nullptr,
                  unsigned CharDistance = 0)
       : CorrectionName(Name), CorrectionNameSpec(NNS),
         CharDistance(CharDistance), QualifierDistance(0), CallbackDistance(0),
         ForceSpecifierReplacement(false), RequiresImport(false) {}
 
   TypoCorrection()
-      : CorrectionNameSpec(0), CharDistance(0), QualifierDistance(0),
+      : CorrectionNameSpec(nullptr), CharDistance(0), QualifierDistance(0),
         CallbackDistance(0), ForceSpecifierReplacement(false),
         RequiresImport(false) {}
 
@@ -81,7 +81,7 @@
   }
   void setCorrectionSpecifier(NestedNameSpecifier* NNS) {
     CorrectionNameSpec = NNS;
-    ForceSpecifierReplacement = (NNS != 0);
+    ForceSpecifierReplacement = (NNS != nullptr);
   }
 
   void WillReplaceSpecifier(bool ForceReplacement) {
@@ -130,7 +130,7 @@
 
   /// \brief Gets the pointer to the declaration of the typo correction
   NamedDecl *getCorrectionDecl() const {
-    return hasCorrectionDecl() ? *(CorrectionDecls.begin()) : 0;
+    return hasCorrectionDecl() ? *(CorrectionDecls.begin()) : nullptr;
   }
   template <class DeclClass>
   DeclClass *getCorrectionDeclAs() const {
@@ -172,7 +172,7 @@
   /// as the only element in the list to mark this TypoCorrection as a keyword.
   void makeKeyword() {
     CorrectionDecls.clear();
-    CorrectionDecls.push_back(0);
+    CorrectionDecls.push_back(nullptr);
     ForceSpecifierReplacement = true;
   }
 
@@ -180,7 +180,7 @@
   // item in CorrectionDecls is NULL.
   bool isKeyword() const {
     return !CorrectionDecls.empty() &&
-        CorrectionDecls.front() == 0;
+        CorrectionDecls.front() == nullptr;
   }
 
   // Check if this TypoCorrection is the given keyword.
@@ -250,8 +250,8 @@
   CorrectionCandidateCallback()
       : WantTypeSpecifiers(true), WantExpressionKeywords(true),
         WantCXXNamedCasts(true), WantRemainingKeywords(true),
-        WantObjCSuper(false),
-        IsObjCIvarLookup(false) {}
+        WantObjCSuper(false), IsObjCIvarLookup(false),
+        IsAddressOfOperand(false) {}
 
   virtual ~CorrectionCandidateCallback() {}
 
@@ -287,6 +287,7 @@
   // Temporary hack for the one case where a CorrectTypoContext enum is used
   // when looking up results.
   bool IsObjCIvarLookup;
+  bool IsAddressOfOperand;
 };
 
 /// @brief Simple template class for restricting typo correction candidates
@@ -294,7 +295,7 @@
 template <class C>
 class DeclFilterCCC : public CorrectionCandidateCallback {
 public:
-  virtual bool ValidateCandidate(const TypoCorrection &candidate) {
+  bool ValidateCandidate(const TypoCorrection &candidate) override {
     return candidate.getCorrectionDeclAs<C>();
   }
 };
@@ -305,13 +306,16 @@
 class FunctionCallFilterCCC : public CorrectionCandidateCallback {
 public:
   FunctionCallFilterCCC(Sema &SemaRef, unsigned NumArgs,
-                        bool HasExplicitTemplateArgs);
+                        bool HasExplicitTemplateArgs,
+                        MemberExpr *ME = nullptr);
 
-  virtual bool ValidateCandidate(const TypoCorrection &candidate);
+  bool ValidateCandidate(const TypoCorrection &candidate) override;
 
  private:
   unsigned NumArgs;
   bool HasExplicitTemplateArgs;
+  DeclContext *CurContext;
+  MemberExpr *MemberFn;
 };
 
 // @brief Callback class that effectively disabled typo correction
@@ -324,7 +328,7 @@
     WantRemainingKeywords = false;
   }
 
-  virtual bool ValidateCandidate(const TypoCorrection &candidate) {
+  bool ValidateCandidate(const TypoCorrection &candidate) override {
     return false;
   }
 };
diff --git a/include/clang/Sema/Weak.h b/include/clang/Sema/Weak.h
index 6d1b64b..9c7212e 100644
--- a/include/clang/Sema/Weak.h
+++ b/include/clang/Sema/Weak.h
@@ -28,7 +28,7 @@
   bool used;              // identifier later declared?
 public:
   WeakInfo()
-    : alias(0), loc(SourceLocation()), used(false) {}
+    : alias(nullptr), loc(SourceLocation()), used(false) {}
   WeakInfo(IdentifierInfo *Alias, SourceLocation Loc)
     : alias(Alias), loc(Loc), used(false) {}
   inline IdentifierInfo * getAlias() const { return alias; }
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h
index 03d9050..7ae1977 100644
--- a/include/clang/Serialization/ASTBitCodes.h
+++ b/include/clang/Serialization/ASTBitCodes.h
@@ -213,9 +213,6 @@
       /// types and decls used within the AST file.
       DECLTYPES_BLOCK_ID,
 
-      /// \brief The block containing DECL_UPDATES records.
-      DECL_UPDATES_BLOCK_ID,
-      
       /// \brief The block containing the detailed preprocessing record.
       PREPROCESSOR_DETAIL_BLOCK_ID,
       
@@ -284,7 +281,14 @@
       HEADER_SEARCH_OPTIONS = 11,
 
       /// \brief Record code for the preprocessor options table.
-      PREPROCESSOR_OPTIONS = 12
+      PREPROCESSOR_OPTIONS = 12,
+
+      /// \brief Record code for the module name.
+      MODULE_NAME = 13,
+
+      /// \brief Record code for the module map file that was used to build this
+      /// AST file.
+      MODULE_MAP_FILE = 14
     };
 
     /// \brief Record types that occur within the input-files block
@@ -349,15 +353,15 @@
       /// IDs).
       IDENTIFIER_TABLE = 5,
 
-      /// \brief Record code for the array of external definitions.
+      /// \brief Record code for the array of eagerly deserialized decls.
       ///
-      /// The AST file contains a list of all of the unnamed external
-      /// definitions present within the parsed headers, stored as an
-      /// array of declaration IDs. These external definitions will be
+      /// The AST file contains a list of all of the declarations that should be
+      /// eagerly deserialized present within the parsed headers, stored as an
+      /// array of declaration IDs. These declarations will be
       /// reported to the AST consumer after the AST file has been
       /// read, since their presence can affect the semantics of the
       /// program (e.g., for code generation).
-      EXTERNAL_DEFINITIONS = 6,
+      EAGERLY_DESERIALIZED_DECLS = 6,
 
       /// \brief Record code for the set of non-builtin, special
       /// types.
@@ -538,7 +542,10 @@
       UNDEFINED_BUT_USED = 49,
 
       /// \brief Record code for late parsed template functions.
-      LATE_PARSED_TEMPLATE = 50
+      LATE_PARSED_TEMPLATE = 50,
+
+      /// \brief Record code for \#pragma optimize options.
+      OPTIMIZE_PRAGMA_OPTIONS = 51
     };
 
     /// \brief Record types used within a source manager block.
@@ -841,7 +848,9 @@
       /// \brief An AtomicType record.
       TYPE_ATOMIC                = 40,
       /// \brief A DecayedType record.
-      TYPE_DECAYED               = 41
+      TYPE_DECAYED               = 41,
+      /// \brief An AdjustedType record.
+      TYPE_ADJUSTED              = 42
     };
 
     /// \brief The type IDs for special types constructed by semantic
@@ -1300,13 +1309,11 @@
       EXPR_CXX_UNRESOLVED_MEMBER,        // UnresolvedMemberExpr
       EXPR_CXX_UNRESOLVED_LOOKUP,        // UnresolvedLookupExpr
 
-      EXPR_CXX_UNARY_TYPE_TRAIT,  // UnaryTypeTraitExpr
       EXPR_CXX_EXPRESSION_TRAIT,  // ExpressionTraitExpr
       EXPR_CXX_NOEXCEPT,          // CXXNoexceptExpr
 
       EXPR_OPAQUE_VALUE,          // OpaqueValueExpr
       EXPR_BINARY_CONDITIONAL_OPERATOR,  // BinaryConditionalOperator
-      EXPR_BINARY_TYPE_TRAIT,     // BinaryTypeTraitExpr
       EXPR_TYPE_TRAIT,            // TypeTraitExpr
       EXPR_ARRAY_TYPE_TRAIT,      // ArrayTypeTraitIntExpr
       
@@ -1327,12 +1334,27 @@
       EXPR_CXX_PROPERTY_REF_EXPR, // MSPropertyRefExpr
       EXPR_CXX_UUIDOF_EXPR,       // CXXUuidofExpr (of expr).
       EXPR_CXX_UUIDOF_TYPE,       // CXXUuidofExpr (of type).
+      STMT_SEH_LEAVE,             // SEHLeaveStmt
       STMT_SEH_EXCEPT,            // SEHExceptStmt
       STMT_SEH_FINALLY,           // SEHFinallyStmt
       STMT_SEH_TRY,               // SEHTryStmt
 
       // OpenMP drectives
       STMT_OMP_PARALLEL_DIRECTIVE,
+      STMT_OMP_SIMD_DIRECTIVE,
+      STMT_OMP_FOR_DIRECTIVE,
+      STMT_OMP_SECTIONS_DIRECTIVE,
+      STMT_OMP_SECTION_DIRECTIVE,
+      STMT_OMP_SINGLE_DIRECTIVE,
+      STMT_OMP_MASTER_DIRECTIVE,
+      STMT_OMP_CRITICAL_DIRECTIVE,
+      STMT_OMP_PARALLEL_FOR_DIRECTIVE,
+      STMT_OMP_PARALLEL_SECTIONS_DIRECTIVE,
+      STMT_OMP_TASK_DIRECTIVE,
+      STMT_OMP_TASKYIELD_DIRECTIVE,
+      STMT_OMP_BARRIER_DIRECTIVE,
+      STMT_OMP_TASKWAIT_DIRECTIVE,
+      STMT_OMP_FLUSH_DIRECTIVE,
 
       // ARC
       EXPR_OBJC_BRIDGED_CAST,     // ObjCBridgedCastExpr
diff --git a/include/clang/Serialization/ASTDeserializationListener.h b/include/clang/Serialization/ASTDeserializationListener.h
index 0218129..180f554 100644
--- a/include/clang/Serialization/ASTDeserializationListener.h
+++ b/include/clang/Serialization/ASTDeserializationListener.h
@@ -15,6 +15,7 @@
 #ifndef LLVM_CLANG_FRONTEND_AST_DESERIALIZATION_LISTENER_H
 #define LLVM_CLANG_FRONTEND_AST_DESERIALIZATION_LISTENER_H
 
+#include "clang/Basic/IdentifierTable.h"
 #include "clang/Serialization/ASTBitCodes.h"
 
 namespace clang {
@@ -27,10 +28,8 @@
 class Module;
   
 class ASTDeserializationListener {
-protected:
-  virtual ~ASTDeserializationListener();
-
 public:
+  virtual ~ASTDeserializationListener();
 
   /// \brief The ASTReader was initialized.
   virtual void ReaderInitialized(ASTReader *Reader) { }
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
index d3cca1a..3f44440 100644
--- a/include/clang/Serialization/ASTReader.h
+++ b/include/clang/Serialization/ASTReader.h
@@ -34,21 +34,20 @@
 #include "llvm/ADT/APFloat.h"
 #include "llvm/ADT/APInt.h"
 #include "llvm/ADT/APSInt.h"
-#include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/MapVector.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/TinyPtrVector.h"
 #include "llvm/Bitcode/BitstreamReader.h"
 #include "llvm/Support/DataTypes.h"
 #include <deque>
 #include <map>
+#include <memory>
 #include <string>
 #include <utility>
 #include <vector>
-#include <sys/stat.h>
 
 namespace llvm {
   class MemoryBuffer;
@@ -64,6 +63,7 @@
 class Attr;
 class Decl;
 class DeclContext;
+class DefMacroDirective;
 class DiagnosticOptions;
 class NestedNameSpecifier;
 class CXXBaseSpecifier;
@@ -108,6 +108,9 @@
     return FullVersion != getClangFullRepositoryVersion();
   }
 
+  virtual void ReadModuleName(StringRef ModuleName) {}
+  virtual void ReadModuleMapFile(StringRef ModuleMapPath) {}
+
   /// \brief Receives the language options.
   ///
   /// \returns true to indicate the options are invalid or false otherwise.
@@ -129,8 +132,9 @@
   ///
   /// \returns true to indicate the diagnostic options are invalid, or false
   /// otherwise.
-  virtual bool ReadDiagnosticOptions(const DiagnosticOptions &DiagOpts,
-                                     bool Complain) {
+  virtual bool
+  ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
+                        bool Complain) {
     return false;
   }
 
@@ -170,15 +174,60 @@
   virtual void ReadCounter(const serialization::ModuleFile &M,
                            unsigned Value) {}
 
+  /// This is called for each AST file loaded.
+  virtual void visitModuleFile(StringRef Filename) {}
+
   /// \brief Returns true if this \c ASTReaderListener wants to receive the
   /// input files of the AST file via \c visitInputFile, false otherwise.
   virtual bool needsInputFileVisitation() { return false; }
-
-  /// \brief if \c needsInputFileVisitation returns true, this is called for each
-  /// input file of the AST file.
+  /// \brief Returns true if this \c ASTReaderListener wants to receive the
+  /// system input files of the AST file via \c visitInputFile, false otherwise.
+  virtual bool needsSystemInputFileVisitation() { return false; }
+  /// \brief if \c needsInputFileVisitation returns true, this is called for
+  /// each non-system input file of the AST File. If
+  /// \c needsSystemInputFileVisitation is true, then it is called for all
+  /// system input files as well.
   ///
   /// \returns true to continue receiving the next input file, false to stop.
-  virtual bool visitInputFile(StringRef Filename, bool isSystem) { return true;}
+  virtual bool visitInputFile(StringRef Filename, bool isSystem,
+                              bool isOverridden) {
+    return true;
+  }
+};
+
+/// \brief Simple wrapper class for chaining listeners.
+class ChainedASTReaderListener : public ASTReaderListener {
+  std::unique_ptr<ASTReaderListener> First;
+  std::unique_ptr<ASTReaderListener> Second;
+
+public:
+  /// Takes ownership of \p First and \p Second.
+  ChainedASTReaderListener(ASTReaderListener *First, ASTReaderListener *Second)
+      : First(First), Second(Second) { }
+
+  bool ReadFullVersionInformation(StringRef FullVersion) override;
+  void ReadModuleName(StringRef ModuleName) override;
+  void ReadModuleMapFile(StringRef ModuleMapPath) override;
+  bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain) override;
+  bool ReadTargetOptions(const TargetOptions &TargetOpts,
+                         bool Complain) override;
+  bool ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
+                             bool Complain) override;
+  bool ReadFileSystemOptions(const FileSystemOptions &FSOpts,
+                             bool Complain) override;
+
+  bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
+                               bool Complain) override;
+  bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
+                               bool Complain,
+                               std::string &SuggestedPredefines) override;
+
+  void ReadCounter(const serialization::ModuleFile &M, unsigned Value) override;
+  bool needsInputFileVisitation() override;
+  bool needsSystemInputFileVisitation() override;
+  void visitModuleFile(StringRef Filename) override;
+  bool visitInputFile(StringRef Filename, bool isSystem,
+                      bool isOverridden) override;
 };
 
 /// \brief ASTReaderListener implementation to validate the information of
@@ -191,14 +240,15 @@
   PCHValidator(Preprocessor &PP, ASTReader &Reader)
     : PP(PP), Reader(Reader) {}
 
-  virtual bool ReadLanguageOptions(const LangOptions &LangOpts,
-                                   bool Complain);
-  virtual bool ReadTargetOptions(const TargetOptions &TargetOpts,
-                                 bool Complain);
-  virtual bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
-                                       bool Complain,
-                                       std::string &SuggestedPredefines);
-  virtual void ReadCounter(const serialization::ModuleFile &M, unsigned Value);
+  bool ReadLanguageOptions(const LangOptions &LangOpts,
+                           bool Complain) override;
+  bool ReadTargetOptions(const TargetOptions &TargetOpts,
+                         bool Complain) override;
+  bool ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
+                             bool Complain) override;
+  bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, bool Complain,
+                               std::string &SuggestedPredefines) override;
+  void ReadCounter(const serialization::ModuleFile &M, unsigned Value) override;
 
 private:
   void Error(const char *Msg);
@@ -211,7 +261,7 @@
 namespace reader {
   class ASTIdentifierLookupTrait;
   /// \brief The on-disk hash table used for the DeclContext's Name lookup table.
-  typedef OnDiskChainedHashTable<ASTDeclContextNameLookupTrait>
+  typedef llvm::OnDiskIterableChainedHashTable<ASTDeclContextNameLookupTrait>
     ASTDeclContextNameLookupTable;
 }
 
@@ -285,10 +335,11 @@
 
 private:
   /// \brief The receiver of some callbacks invoked by ASTReader.
-  OwningPtr<ASTReaderListener> Listener;
+  std::unique_ptr<ASTReaderListener> Listener;
 
   /// \brief The receiver of deserialization events.
   ASTDeserializationListener *DeserializationListener;
+  bool OwnsDeserializationListener;
 
   SourceManager &SourceMgr;
   FileManager &FileMgr;
@@ -315,7 +366,7 @@
   SourceLocation CurrentImportLoc;
 
   /// \brief The global module index, if loaded.
-  llvm::OwningPtr<GlobalModuleIndex> GlobalIndex;
+  std::unique_ptr<GlobalModuleIndex> GlobalIndex;
 
   /// \brief A map of global bit offsets to the module that stores entities
   /// at those bit offsets.
@@ -366,12 +417,17 @@
   /// in the chain.
   DeclUpdateOffsetsMap DeclUpdateOffsets;
 
+  /// \brief Declaration updates for already-loaded declarations that we need
+  /// to apply once we finish processing an import.
+  llvm::SmallVector<std::pair<serialization::GlobalDeclID, Decl*>, 16>
+      PendingUpdateRecords;
+
   struct ReplacedDeclInfo {
     ModuleFile *Mod;
     uint64_t Offset;
     unsigned RawLoc;
 
-    ReplacedDeclInfo() : Mod(0), Offset(0), RawLoc(0) {}
+    ReplacedDeclInfo() : Mod(nullptr), Offset(0), RawLoc(0) {}
     ReplacedDeclInfo(ModuleFile *Mod, uint64_t Offset, unsigned RawLoc)
       : Mod(Mod), Offset(Offset), RawLoc(RawLoc) {}
   };
@@ -385,7 +441,7 @@
     ModuleFile *Mod;
     ArrayRef<serialization::LocalDeclID> Decls;
 
-    FileDeclsInfo() : Mod(0) {}
+    FileDeclsInfo() : Mod(nullptr) {}
     FileDeclsInfo(ModuleFile *Mod, ArrayRef<serialization::LocalDeclID> Decls)
       : Mod(Mod), Decls(Decls) {}
   };
@@ -471,18 +527,22 @@
   /// global submodule ID to produce a local ID.
   GlobalSubmoduleMapType GlobalSubmoduleMap;
 
+  /// \brief Information on a macro definition or undefinition that is visible
+  /// at the end of a submodule.
+  struct ModuleMacroInfo;
+
   /// \brief An entity that has been hidden.
   class HiddenName {
   public:
     enum NameKind {
       Declaration,
-      MacroVisibility
+      Macro
     } Kind;
 
   private:
     union {
       Decl *D;
-      MacroDirective *MD;
+      ModuleMacroInfo *MMI;
     };
 
     IdentifierInfo *Id;
@@ -490,8 +550,8 @@
   public:
     HiddenName(Decl *D) : Kind(Declaration), D(D), Id() { }
 
-    HiddenName(IdentifierInfo *II, MacroDirective *MD)
-      : Kind(MacroVisibility), MD(MD), Id(II) { }
+    HiddenName(IdentifierInfo *II, ModuleMacroInfo *MMI)
+      : Kind(Macro), MMI(MMI), Id(II) { }
 
     NameKind getKind() const { return Kind; }
 
@@ -500,15 +560,21 @@
       return D;
     }
 
-    std::pair<IdentifierInfo *, MacroDirective *> getMacro() const {
-      assert(getKind() == MacroVisibility && "Hidden name is not a macro!");
-      return std::make_pair(Id, MD);
+    std::pair<IdentifierInfo *, ModuleMacroInfo *> getMacro() const {
+      assert(getKind() == Macro && "Hidden name is not a macro!");
+      return std::make_pair(Id, MMI);
     }
-};
+  };
+
+  typedef llvm::SmallDenseMap<IdentifierInfo*,
+                              ModuleMacroInfo*> HiddenMacrosMap;
 
   /// \brief A set of hidden declarations.
-  typedef SmallVector<HiddenName, 2> HiddenNames;
-  
+  struct HiddenNames {
+    SmallVector<Decl*, 2> HiddenDecls;
+    HiddenMacrosMap HiddenMacros;
+  };
+
   typedef llvm::DenseMap<Module *, HiddenNames> HiddenNamesMapType;
 
   /// \brief A mapping from each of the hidden submodules to the deserialized
@@ -564,8 +630,8 @@
     ModuleFile *M;
 
     struct ModuleMacroDataTy {
-      serialization::GlobalMacroID GMacID;
-      unsigned ImportLoc;
+      uint32_t MacID;
+      serialization::SubmoduleID *Overrides;
     };
     struct PCHMacroDataTy {
       uint64_t MacroDirectivesOffset;
@@ -577,10 +643,10 @@
     };
 
     PendingMacroInfo(ModuleFile *M,
-                     serialization::GlobalMacroID GMacID,
-                     SourceLocation ImportLoc) : M(M) {
-      ModuleMacroData.GMacID = GMacID;
-      ModuleMacroData.ImportLoc = ImportLoc.getRawEncoding();
+                     uint32_t MacID,
+                     serialization::SubmoduleID *Overrides) : M(M) {
+      ModuleMacroData.MacID = MacID;
+      ModuleMacroData.Overrides = Overrides;
     }
 
     PendingMacroInfo(ModuleFile *M, uint64_t MacroDirectivesOffset) : M(M) {
@@ -610,10 +676,10 @@
   /// \brief The IDs of all declarations that fulfill the criteria of
   /// "interesting" decls.
   ///
-  /// This contains the data loaded from all EXTERNAL_DEFINITIONS blocks in the
-  /// chain. The referenced declarations are deserialized and passed to the
-  /// consumer eagerly.
-  SmallVector<uint64_t, 16> ExternalDefinitions;
+  /// This contains the data loaded from all EAGERLY_DESERIALIZED_DECLS blocks
+  /// in the chain. The referenced declarations are deserialized and passed to
+  /// the consumer eagerly.
+  SmallVector<uint64_t, 16> EagerlyDeserializedDecls;
 
   /// \brief The IDs of all tentative definitions stored in the chain.
   ///
@@ -701,6 +767,9 @@
   /// \brief The floating point pragma option settings.
   SmallVector<uint64_t, 1> FPPragmaOptions;
 
+  /// \brief The pragma clang optimize location (if the pragma state is "off").
+  SourceLocation OptimizeOffPragmaLocation;
+
   /// \brief The OpenCL extension settings.
   SmallVector<uint64_t, 1> OpenCLExtensions;
 
@@ -714,9 +783,17 @@
   // \brief A list of late parsed template function data.
   SmallVector<uint64_t, 1> LateParsedTemplates;
 
+  struct ImportedSubmodule {
+    serialization::SubmoduleID ID;
+    SourceLocation ImportLoc;
+
+    ImportedSubmodule(serialization::SubmoduleID ID, SourceLocation ImportLoc)
+      : ID(ID), ImportLoc(ImportLoc) {}
+  };
+
   /// \brief A list of modules that were imported by precompiled headers or
   /// any other non-module AST file.
-  SmallVector<serialization::SubmoduleID, 2> ImportedModules;
+  SmallVector<ImportedSubmodule, 2> ImportedModules;
   //@}
 
   /// \brief The directory that the PCH we are reading is stored in.
@@ -733,16 +810,19 @@
   /// \brief Whether to accept an AST file with compiler errors.
   bool AllowASTWithCompilerErrors;
 
+  /// \brief Whether to accept an AST file that has a different configuration
+  /// from the current compiler instance.
+  bool AllowConfigurationMismatch;
+
+  /// \brief Whether validate system input files.
+  bool ValidateSystemInputs;
+
   /// \brief Whether we are allowed to use the global module index.
   bool UseGlobalIndex;
 
   /// \brief Whether we have tried loading the global module index yet.
   bool TriedLoadingGlobalIndex;
 
-  /// \brief The current "generation" of the module file import stack, which 
-  /// indicates how many separate module file load operations have occurred.
-  unsigned CurrentGeneration;
-
   typedef llvm::DenseMap<unsigned, SwitchCase *> SwitchCaseMapTy;
   /// \brief Mapping from switch-case IDs in the chain to switch-case statements
   ///
@@ -860,6 +940,10 @@
   /// \brief Keeps track of the elements added to PendingDeclChains.
   llvm::SmallSet<serialization::DeclID, 16> PendingDeclChainsKnown;
 
+  /// \brief The list of canonical declarations whose redeclaration chains
+  /// need to be marked as incomplete once we're done deserializing things.
+  SmallVector<Decl *, 16> PendingIncompleteDeclChains;
+
   /// \brief The Decl IDs for the Sema/Lexical DeclContext of a Decl that has
   /// been loaded but its DeclContext was not set yet.
   struct PendingDeclContextInfo {
@@ -883,6 +967,13 @@
   /// once recursing loading has been completed.
   llvm::SmallVector<NamedDecl *, 16> PendingOdrMergeChecks;
 
+  /// \brief Record definitions in which we found an ODR violation.
+  llvm::SmallDenseMap<CXXRecordDecl *, llvm::TinyPtrVector<CXXRecordDecl *>, 2>
+      PendingOdrMergeFailures;
+
+  /// \brief DeclContexts in which we have diagnosed an ODR violation.
+  llvm::SmallPtrSet<DeclContext*, 2> DiagnosedOdrMergeFailures;
+
   /// \brief The set of Objective-C categories that have been deserialized
   /// since the last time the declaration chains were linked.
   llvm::SmallPtrSet<ObjCCategoryDecl *, 16> CategoriesDeserialized;
@@ -891,7 +982,14 @@
   /// loaded, for which we will need to check for categories whenever a new
   /// module is loaded.
   SmallVector<ObjCInterfaceDecl *, 16> ObjCClassesLoaded;
-  
+
+  /// \brief A mapping from a primary context for a declaration chain to the
+  /// other declarations of that entity that also have name lookup tables.
+  /// Used when we merge together two class definitions that have different
+  /// sets of declared special member functions.
+  llvm::DenseMap<const DeclContext*, SmallVector<const DeclContext*, 2>>
+      MergedLookups;
+
   typedef llvm::DenseMap<Decl *, SmallVector<serialization::DeclID, 2> >
     MergedDeclsMap;
     
@@ -970,6 +1068,18 @@
   /// \brief Reads a statement from the specified cursor.
   Stmt *ReadStmtFromStream(ModuleFile &F);
 
+  struct InputFileInfo {
+    std::string Filename;
+    off_t StoredSize;
+    time_t StoredTime;
+    bool Overridden;
+  };
+
+  /// \brief Reads the stored information about an input file.
+  InputFileInfo readInputFileInfo(ModuleFile &F, unsigned ID);
+  /// \brief A convenience method to read the filename from an input file.
+  std::string getInputFileName(ModuleFile &F, unsigned ID);
+
   /// \brief Retrieve the file entry and 'overridden' bit for an input
   /// file in the given module file.
   serialization::InputFile getInputFile(ModuleFile &F, unsigned ID,
@@ -999,13 +1109,15 @@
                             unsigned ClientLoadCapabilities);
   ASTReadResult ReadControlBlock(ModuleFile &F,
                                  SmallVectorImpl<ImportedModule> &Loaded,
+                                 const ModuleFile *ImportedBy,
                                  unsigned ClientLoadCapabilities);
-  bool ReadASTBlock(ModuleFile &F);
+  ASTReadResult ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities);
   bool ParseLineTable(ModuleFile &F, SmallVectorImpl<uint64_t> &Record);
   bool ReadSourceManagerBlock(ModuleFile &F);
   llvm::BitstreamCursor &SLocCursorForID(int ID);
   SourceLocation getImportLocation(ModuleFile *F);
-  bool ReadSubmoduleBlock(ModuleFile &F);
+  ASTReadResult ReadSubmoduleBlock(ModuleFile &F,
+                                   unsigned ClientLoadCapabilities);
   static bool ParseLanguageOptions(const RecordData &Record, bool Complain,
                                    ASTReaderListener &Listener);
   static bool ParseTargetOptions(const RecordData &Record, bool Complain,
@@ -1028,9 +1140,14 @@
   };
 
   QualType readTypeRecord(unsigned Index);
+  void readExceptionSpec(ModuleFile &ModuleFile,
+                         SmallVectorImpl<QualType> &ExceptionStorage,
+                         FunctionProtoType::ExtProtoInfo &EPI,
+                         const RecordData &Record, unsigned &Index);
   RecordLocation TypeCursorForIndex(unsigned Index);
   void LoadedDecl(unsigned Index, Decl *D);
   Decl *ReadDeclRecord(serialization::DeclID ID);
+  void markIncompleteDeclChain(Decl *Canon);
   RecordLocation DeclCursorForID(serialization::DeclID ID,
                                  unsigned &RawLocation);
   void loadDeclUpdateRecords(serialization::DeclID ID, Decl *D);
@@ -1041,13 +1158,10 @@
   RecordLocation getLocalBitOffset(uint64_t GlobalOffset);
   uint64_t getGlobalBitOffset(ModuleFile &M, uint32_t LocalOffset);
 
-  /// \brief Returns the first preprocessed entity ID that ends after BLoc.
+  /// \brief Returns the first preprocessed entity ID that begins or ends after
+  /// \arg Loc.
   serialization::PreprocessedEntityID
-    findBeginPreprocessedEntity(SourceLocation BLoc) const;
-
-  /// \brief Returns the first preprocessed entity ID that begins after ELoc.
-  serialization::PreprocessedEntityID
-    findEndPreprocessedEntity(SourceLocation ELoc) const;
+  findPreprocessedEntity(SourceLocation Loc, bool EndsAfter) const;
 
   /// \brief Find the next module that contains entities and return the ID
   /// of the first entry.
@@ -1079,7 +1193,7 @@
     typedef value_type&         reference;
     typedef value_type*         pointer;
 
-    ModuleDeclIterator() : Reader(0), Mod(0), Pos(0) { }
+    ModuleDeclIterator() : Reader(nullptr), Mod(nullptr), Pos(nullptr) { }
 
     ModuleDeclIterator(ASTReader *Reader, ModuleFile *Mod,
                        const serialization::LocalDeclID *Pos)
@@ -1174,11 +1288,20 @@
   /// AST file the was created out of an AST with compiler errors,
   /// otherwise it will reject it.
   ///
+  /// \param AllowConfigurationMismatch If true, the AST reader will not check
+  /// for configuration differences between the AST file and the invocation.
+  ///
+  /// \param ValidateSystemInputs If true, the AST reader will validate
+  /// system input files in addition to user input files. This is only
+  /// meaningful if \p DisableValidation is false.
+  ///
   /// \param UseGlobalIndex If true, the AST reader will try to load and use
   /// the global module index.
   ASTReader(Preprocessor &PP, ASTContext &Context, StringRef isysroot = "",
             bool DisableValidation = false,
             bool AllowASTWithCompilerErrors = false,
+            bool AllowConfigurationMismatch = false,
+            bool ValidateSystemInputs = false,
             bool UseGlobalIndex = true);
 
   ~ASTReader();
@@ -1237,24 +1360,41 @@
   /// \param ImportLoc The location at which the import occurs.
   ///
   /// \param Complain Whether to complain about conflicting module imports.
-  void makeModuleVisible(Module *Mod, 
+  void makeModuleVisible(Module *Mod,
                          Module::NameVisibilityKind NameVisibility,
                          SourceLocation ImportLoc,
                          bool Complain);
-  
+
   /// \brief Make the names within this set of hidden names visible.
-  void makeNamesVisible(const HiddenNames &Names, Module *Owner);
-  
+  void makeNamesVisible(const HiddenNames &Names, Module *Owner,
+                        bool FromFinalization);
+
   /// \brief Set the AST callbacks listener.
   void setListener(ASTReaderListener *listener) {
     Listener.reset(listener);
   }
 
+  /// \brief Add an AST callbak listener.
+  ///
+  /// Takes ownership of \p L.
+  void addListener(ASTReaderListener *L) {
+    if (Listener)
+      L = new ChainedASTReaderListener(L, Listener.release());
+    Listener.reset(L);
+  }
+
   /// \brief Set the AST deserialization listener.
-  void setDeserializationListener(ASTDeserializationListener *Listener);
+  void setDeserializationListener(ASTDeserializationListener *Listener,
+                                  bool TakeOwnership = false);
 
   /// \brief Determine whether this AST reader has a global index.
-  bool hasGlobalIndex() const { return GlobalIndex.isValid(); }
+  bool hasGlobalIndex() const { return (bool)GlobalIndex; }
+
+  /// \brief Return global module index.
+  GlobalModuleIndex *getGlobalIndex() { return GlobalIndex.get(); }
+
+  /// \brief Reset reader for a reload try.
+  void resetForReload() { TriedLoadingGlobalIndex = false; }
 
   /// \brief Attempts to load the global index.
   ///
@@ -1325,20 +1465,20 @@
   ///
   /// \returns null if an error occurred that prevented the preprocessed
   /// entity from being loaded.
-  virtual PreprocessedEntity *ReadPreprocessedEntity(unsigned Index);
+  PreprocessedEntity *ReadPreprocessedEntity(unsigned Index) override;
 
   /// \brief Returns a pair of [Begin, End) indices of preallocated
   /// preprocessed entities that \p Range encompasses.
-  virtual std::pair<unsigned, unsigned>
-      findPreprocessedEntitiesInRange(SourceRange Range);
+  std::pair<unsigned, unsigned>
+      findPreprocessedEntitiesInRange(SourceRange Range) override;
 
   /// \brief Optionally returns true or false if the preallocated preprocessed
   /// entity with index \p Index came from file \p FID.
-  virtual Optional<bool> isPreprocessedEntityInFileID(unsigned Index,
-                                                      FileID FID);
+  Optional<bool> isPreprocessedEntityInFileID(unsigned Index,
+                                              FileID FID) override;
 
   /// \brief Read the header file information for the given file entry.
-  virtual HeaderFileInfo GetHeaderFileInfo(const FileEntry *FE);
+  HeaderFileInfo GetHeaderFileInfo(const FileEntry *FE) override;
 
   void ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag);
 
@@ -1443,14 +1583,22 @@
   /// \brief Retrieve the module file that owns the given declaration, or NULL
   /// if the declaration is not from a module file.
   ModuleFile *getOwningModuleFile(const Decl *D);
-  
+
+  /// \brief Get the best name we know for the module that owns the given
+  /// declaration, or an empty string if the declaration is not from a module.
+  std::string getOwningModuleNameForDiagnostic(const Decl *D);
+
   /// \brief Returns the source location for the decl \p ID.
   SourceLocation getSourceLocationForDeclID(serialization::GlobalDeclID ID);
 
   /// \brief Resolve a declaration ID into a declaration, potentially
   /// building a new declaration.
   Decl *GetDecl(serialization::DeclID ID);
-  virtual Decl *GetExternalDecl(uint32_t ID);
+  Decl *GetExternalDecl(uint32_t ID) override;
+
+  /// \brief Resolve a declaration ID into a declaration. Return 0 if it's not
+  /// been loaded yet.
+  Decl *GetExistingDecl(serialization::DeclID ID);
 
   /// \brief Reads a declaration with the given local ID in the given module.
   Decl *GetLocalDecl(ModuleFile &F, uint32_t LocalID) {
@@ -1497,19 +1645,24 @@
     return cast_or_null<T>(GetDecl(ReadDeclID(F, R, I)));
   }
 
+  /// \brief If any redeclarations of \p D have been imported since it was
+  /// last checked, this digs out those redeclarations and adds them to the
+  /// redeclaration chain for \p D.
+  void CompleteRedeclChain(const Decl *D) override;
+
   /// \brief Read a CXXBaseSpecifiers ID form the given record and
   /// return its global bit offset.
   uint64_t readCXXBaseSpecifiers(ModuleFile &M, const RecordData &Record,
                                  unsigned &Idx);
 
-  virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset);
+  CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset) override;
 
   /// \brief Resolve the offset of a statement into a statement.
   ///
   /// This operation will read a new statement from the external
   /// source each time it is called, and is meant to be used via a
   /// LazyOffsetPtr (which is used by Decls for the body of functions, etc).
-  virtual Stmt *GetExternalDeclStmt(uint64_t Offset);
+  Stmt *GetExternalDeclStmt(uint64_t Offset) override;
 
   /// ReadBlockAbbrevs - Enter a subblock of the specified BlockID with the
   /// specified cursor.  Read the abbreviations that are at the top of the block
@@ -1519,9 +1672,8 @@
   /// \brief Finds all the visible declarations with a given name.
   /// The current implementation of this method just loads the entire
   /// lookup table as unmaterialized references.
-  virtual bool
-  FindExternalVisibleDeclsByName(const DeclContext *DC,
-                                 DeclarationName Name);
+  bool FindExternalVisibleDeclsByName(const DeclContext *DC,
+                                      DeclarationName Name) override;
 
   /// \brief Read all of the declarations lexically stored in a
   /// declaration context.
@@ -1536,49 +1688,49 @@
   ///
   /// \returns true if there was an error while reading the
   /// declarations for this declaration context.
-  virtual ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
-                                        bool (*isKindWeWant)(Decl::Kind),
-                                        SmallVectorImpl<Decl*> &Decls);
+  ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
+                                bool (*isKindWeWant)(Decl::Kind),
+                                SmallVectorImpl<Decl*> &Decls) override;
 
   /// \brief Get the decls that are contained in a file in the Offset/Length
   /// range. \p Length can be 0 to indicate a point at \p Offset instead of
   /// a range.
-  virtual void FindFileRegionDecls(FileID File, unsigned Offset,unsigned Length,
-                                   SmallVectorImpl<Decl *> &Decls);
+  void FindFileRegionDecls(FileID File, unsigned Offset, unsigned Length,
+                           SmallVectorImpl<Decl *> &Decls) override;
 
   /// \brief Notify ASTReader that we started deserialization of
   /// a decl or type so until FinishedDeserializing is called there may be
   /// decls that are initializing. Must be paired with FinishedDeserializing.
-  virtual void StartedDeserializing() { ++NumCurrentElementsDeserializing; }
+  void StartedDeserializing() override { ++NumCurrentElementsDeserializing; }
 
   /// \brief Notify ASTReader that we finished the deserialization of
   /// a decl or type. Must be paired with StartedDeserializing.
-  virtual void FinishedDeserializing();
+  void FinishedDeserializing() override;
 
   /// \brief Function that will be invoked when we begin parsing a new
   /// translation unit involving this external AST source.
   ///
   /// This function will provide all of the external definitions to
   /// the ASTConsumer.
-  virtual void StartTranslationUnit(ASTConsumer *Consumer);
+  void StartTranslationUnit(ASTConsumer *Consumer) override;
 
   /// \brief Print some statistics about AST usage.
-  virtual void PrintStats();
+  void PrintStats() override;
 
   /// \brief Dump information about the AST reader to standard error.
   void dump();
 
   /// Return the amount of memory used by memory buffers, breaking down
   /// by heap-backed versus mmap'ed memory.
-  virtual void getMemoryBufferSizes(MemoryBufferSizes &sizes) const;
+  void getMemoryBufferSizes(MemoryBufferSizes &sizes) const override;
 
   /// \brief Initialize the semantic source with the Sema instance
   /// being used to perform semantic analysis on the abstract syntax
   /// tree.
-  virtual void InitializeSema(Sema &S);
+  void InitializeSema(Sema &S) override;
 
   /// \brief Inform the semantic consumer that Sema is no longer available.
-  virtual void ForgetSema() { SemaObj = 0; }
+  void ForgetSema() override { SemaObj = nullptr; }
 
   /// \brief Retrieve the IdentifierInfo for the named identifier.
   ///
@@ -1587,56 +1739,57 @@
   /// declarations will be deserialized and introduced into the declaration
   /// chain of the identifier.
   virtual IdentifierInfo *get(const char *NameStart, const char *NameEnd);
-  IdentifierInfo *get(StringRef Name) {
+  IdentifierInfo *get(StringRef Name) override {
     return get(Name.begin(), Name.end());
   }
 
   /// \brief Retrieve an iterator into the set of all identifiers
   /// in all loaded AST files.
-  virtual IdentifierIterator *getIdentifiers();
+  IdentifierIterator *getIdentifiers() override;
 
   /// \brief Load the contents of the global method pool for a given
   /// selector.
-  virtual void ReadMethodPool(Selector Sel);
+  void ReadMethodPool(Selector Sel) override;
 
   /// \brief Load the set of namespaces that are known to the external source,
   /// which will be used during typo correction.
-  virtual void ReadKnownNamespaces(
-                           SmallVectorImpl<NamespaceDecl *> &Namespaces);
+  void ReadKnownNamespaces(
+                         SmallVectorImpl<NamespaceDecl *> &Namespaces) override;
 
-  virtual void ReadUndefinedButUsed(
-                        llvm::DenseMap<NamedDecl *, SourceLocation> &Undefined);
+  void ReadUndefinedButUsed(
+               llvm::DenseMap<NamedDecl *, SourceLocation> &Undefined) override;
 
-  virtual void ReadTentativeDefinitions(
-                 SmallVectorImpl<VarDecl *> &TentativeDefs);
+  void ReadTentativeDefinitions(
+                            SmallVectorImpl<VarDecl *> &TentativeDefs) override;
 
-  virtual void ReadUnusedFileScopedDecls(
-                 SmallVectorImpl<const DeclaratorDecl *> &Decls);
+  void ReadUnusedFileScopedDecls(
+                       SmallVectorImpl<const DeclaratorDecl *> &Decls) override;
 
-  virtual void ReadDelegatingConstructors(
-                 SmallVectorImpl<CXXConstructorDecl *> &Decls);
+  void ReadDelegatingConstructors(
+                         SmallVectorImpl<CXXConstructorDecl *> &Decls) override;
 
-  virtual void ReadExtVectorDecls(SmallVectorImpl<TypedefNameDecl *> &Decls);
+  void ReadExtVectorDecls(SmallVectorImpl<TypedefNameDecl *> &Decls) override;
 
-  virtual void ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl *> &Decls);
+  void ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl *> &Decls) override;
 
-  virtual void ReadLocallyScopedExternCDecls(
-                 SmallVectorImpl<NamedDecl *> &Decls);
+  void ReadLocallyScopedExternCDecls(
+                                  SmallVectorImpl<NamedDecl *> &Decls) override;
 
-  virtual void ReadReferencedSelectors(
-                 SmallVectorImpl<std::pair<Selector, SourceLocation> > &Sels);
+  void ReadReferencedSelectors(
+          SmallVectorImpl<std::pair<Selector, SourceLocation> > &Sels) override;
 
-  virtual void ReadWeakUndeclaredIdentifiers(
-                 SmallVectorImpl<std::pair<IdentifierInfo *, WeakInfo> > &WI);
+  void ReadWeakUndeclaredIdentifiers(
+          SmallVectorImpl<std::pair<IdentifierInfo *, WeakInfo> > &WI) override;
 
-  virtual void ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables);
+  void ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables) override;
 
-  virtual void ReadPendingInstantiations(
+  void ReadPendingInstantiations(
                  SmallVectorImpl<std::pair<ValueDecl *,
-                                           SourceLocation> > &Pending);
+                                           SourceLocation> > &Pending) override;
 
-  virtual void ReadLateParsedTemplates(
-      llvm::DenseMap<const FunctionDecl *, LateParsedTemplate *> &LPTMap);
+  void ReadLateParsedTemplates(
+                         llvm::DenseMap<const FunctionDecl *,
+                                        LateParsedTemplate *> &LPTMap) override;
 
   /// \brief Load a selector from disk, registering its ID if it exists.
   void LoadSelector(Selector Sel);
@@ -1644,7 +1797,7 @@
   void SetIdentifierInfo(unsigned ID, IdentifierInfo *II);
   void SetGloballyVisibleDecls(IdentifierInfo *II,
                                const SmallVectorImpl<uint32_t> &DeclIDs,
-                               SmallVectorImpl<Decl *> *Decls = 0);
+                               SmallVectorImpl<Decl *> *Decls = nullptr);
 
   /// \brief Report a diagnostic.
   DiagnosticBuilder Diag(unsigned DiagID);
@@ -1659,7 +1812,7 @@
     return DecodeIdentifierInfo(getGlobalIdentifierID(M, Record[Idx++]));
   }
 
-  virtual IdentifierInfo *GetIdentifier(serialization::IdentifierID ID) {
+  IdentifierInfo *GetIdentifier(serialization::IdentifierID ID) override {
     // Note that we are loading an identifier.
     Deserializing AnIdentifier(this);
 
@@ -1671,13 +1824,26 @@
   serialization::IdentifierID getGlobalIdentifierID(ModuleFile &M,
                                                     unsigned LocalID);
 
+  ModuleMacroInfo *getModuleMacro(const PendingMacroInfo &PMInfo);
+
   void resolvePendingMacro(IdentifierInfo *II, const PendingMacroInfo &PMInfo);
 
   void installPCHMacroDirectives(IdentifierInfo *II,
                                  ModuleFile &M, uint64_t Offset);
 
-  void installImportedMacro(IdentifierInfo *II, MacroDirective *MD,
-                            Module *Owner);
+  void installImportedMacro(IdentifierInfo *II, ModuleMacroInfo *MMI,
+                            Module *Owner, bool FromFinalization);
+
+  typedef llvm::TinyPtrVector<DefMacroDirective *> AmbiguousMacros;
+  llvm::DenseMap<IdentifierInfo*, AmbiguousMacros> AmbiguousMacroDefs;
+
+  void
+  removeOverriddenMacros(IdentifierInfo *II, AmbiguousMacros &Ambig,
+                         ArrayRef<serialization::SubmoduleID> Overrides);
+
+  AmbiguousMacros *
+  removeOverriddenMacros(IdentifierInfo *II,
+                         ArrayRef<serialization::SubmoduleID> Overrides);
 
   /// \brief Retrieve the macro with the given ID.
   MacroInfo *getMacro(serialization::MacroID ID);
@@ -1687,11 +1853,11 @@
   serialization::MacroID getGlobalMacroID(ModuleFile &M, unsigned LocalID);
 
   /// \brief Read the source location entry with index ID.
-  virtual bool ReadSLocEntry(int ID);
+  bool ReadSLocEntry(int ID) override;
 
   /// \brief Retrieve the module import location and module name for the
   /// given source manager entry ID.
-  virtual std::pair<SourceLocation, StringRef> getModuleImportLoc(int ID);
+  std::pair<SourceLocation, StringRef> getModuleImportLoc(int ID) override;
 
   /// \brief Retrieve the global submodule ID given a module and its local ID
   /// number.
@@ -1705,7 +1871,7 @@
   /// \brief Retrieve the module that corresponds to the given module ID.
   ///
   /// Note: overrides method in ExternalASTSource
-  virtual Module *getModule(unsigned ID);
+  Module *getModule(unsigned ID) override;
 
   /// \brief Retrieve a selector from the given module with its local ID
   /// number.
@@ -1713,8 +1879,8 @@
 
   Selector DecodeSelector(serialization::SelectorID Idx);
 
-  virtual Selector GetExternalSelector(serialization::SelectorID ID);
-  uint32_t GetNumExternalSelectors();
+  Selector GetExternalSelector(serialization::SelectorID ID) override;
+  uint32_t GetNumExternalSelectors() override;
 
   Selector ReadSelector(ModuleFile &M, const RecordData &Record, unsigned &Idx) {
     return getLocalSelector(M, Record[Idx++]);
@@ -1832,7 +1998,7 @@
            "Should be called only during statement reading!");
     // Subexpressions are stored from last to first, so the next Stmt we need
     // is at the back of the stack.
-    assert(!StmtStack.empty() && "Read too many sub statements!");
+    assert(!StmtStack.empty() && "Read too many sub-statements!");
     return StmtStack.pop_back_val();
   }
 
@@ -1855,11 +2021,10 @@
   /// \param II The name of the macro.
   /// \param M The module file.
   /// \param GMacID The global macro ID that is associated with this identifier.
-  /// \param ImportLoc The location where the module is imported.
   void addPendingMacroFromModule(IdentifierInfo *II,
                                  ModuleFile *M,
                                  serialization::GlobalMacroID GMacID,
-                                 SourceLocation ImportLoc);
+                                 ArrayRef<serialization::SubmoduleID>);
 
   /// \brief Add a macro to deserialize its macro directive history from a PCH.
   ///
@@ -1871,16 +2036,16 @@
                               ModuleFile *M, uint64_t MacroDirectivesOffset);
 
   /// \brief Read the set of macros defined by this external macro source.
-  virtual void ReadDefinedMacros();
+  void ReadDefinedMacros() override;
 
   /// \brief Update an out-of-date identifier.
-  virtual void updateOutOfDateIdentifier(IdentifierInfo &II);
+  void updateOutOfDateIdentifier(IdentifierInfo &II) override;
 
   /// \brief Note that this identifier is up-to-date.
   void markIdentifierUpToDate(IdentifierInfo *II);
 
   /// \brief Load all external visible decls in the given DeclContext.
-  void completeVisibleDeclsMap(const DeclContext *DC);
+  void completeVisibleDeclsMap(const DeclContext *DC) override;
 
   /// \brief Retrieve the AST context that this AST reader supplements.
   ASTContext &getContext() { return Context; }
@@ -1911,8 +2076,8 @@
   SmallVector<std::pair<llvm::BitstreamCursor,
                         serialization::ModuleFile *>, 8> CommentsCursors;
 
-  /// \brief Loads comments ranges.
-  void ReadComments();
+  //RIDErief Loads comments ranges.
+  void ReadComments() override;
 };
 
 /// \brief Helper class that saves the current stream position and
diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h
index 07fdd06..ad6ecdd 100644
--- a/include/clang/Serialization/ASTWriter.h
+++ b/include/clang/Serialization/ASTWriter.h
@@ -246,10 +246,10 @@
   /// @name FlushStmt Caches
   /// @{
 
-  /// \brief Set of parent Stmts for the currently serializing sub stmt.
+  /// \brief Set of parent Stmts for the currently serializing sub-stmt.
   llvm::DenseSet<Stmt *> ParentStmts;
 
-  /// \brief Offsets of sub stmts already serialized. The offset points
+  /// \brief Offsets of sub-stmts already serialized. The offset points
   /// just after the stmt record.
   llvm::DenseMap<Stmt *, uint64_t> SubStmtEntries;
 
@@ -283,7 +283,37 @@
   llvm::DenseMap<const MacroDefinition *, serialization::PreprocessedEntityID>
       MacroDefinitions;
 
-  typedef SmallVector<uint64_t, 2> UpdateRecord;
+  /// An update to a Decl.
+  class DeclUpdate {
+    /// A DeclUpdateKind.
+    unsigned Kind;
+    union {
+      const Decl *Dcl;
+      void *Type;
+      unsigned Loc;
+      unsigned Val;
+    };
+
+  public:
+    DeclUpdate(unsigned Kind) : Kind(Kind), Dcl(nullptr) {}
+    DeclUpdate(unsigned Kind, const Decl *Dcl) : Kind(Kind), Dcl(Dcl) {}
+    DeclUpdate(unsigned Kind, QualType Type)
+        : Kind(Kind), Type(Type.getAsOpaquePtr()) {}
+    DeclUpdate(unsigned Kind, SourceLocation Loc)
+        : Kind(Kind), Loc(Loc.getRawEncoding()) {}
+    DeclUpdate(unsigned Kind, unsigned Val)
+        : Kind(Kind), Val(Val) {}
+
+    unsigned getKind() const { return Kind; }
+    const Decl *getDecl() const { return Dcl; }
+    QualType getType() const { return QualType::getFromOpaquePtr(Type); }
+    SourceLocation getLoc() const {
+      return SourceLocation::getFromRawEncoding(Loc);
+    }
+    unsigned getNumber() const { return Val; }
+  };
+
+  typedef SmallVector<DeclUpdate, 1> UpdateRecord;
   typedef llvm::DenseMap<const Decl *, UpdateRecord> DeclUpdateMap;
   /// \brief Mapping from declarations that came from a chained PCH to the
   /// record containing modifications to them.
@@ -297,16 +327,15 @@
   /// \brief Declarations encountered that might be external
   /// definitions.
   ///
-  /// We keep track of external definitions (as well as tentative
-  /// definitions) as we are emitting declarations to the AST
-  /// file. The AST file contains a separate record for these external
-  /// definitions, which are provided to the AST consumer by the AST
-  /// reader. This is behavior is required to properly cope with,
+  /// We keep track of external definitions and other 'interesting' declarations
+  /// as we are emitting declarations to the AST file. The AST file contains a
+  /// separate record for these declarations, which are provided to the AST
+  /// consumer by the AST reader. This is behavior is required to properly cope with,
   /// e.g., tentative variable definitions that occur within
   /// headers. The declarations themselves are stored as declaration
-  /// IDs, since they will be written out to an EXTERNAL_DEFINITIONS
+  /// IDs, since they will be written out to an EAGERLY_DESERIALIZED_DECLS
   /// record.
-  SmallVector<uint64_t, 16> ExternalDefinitions;
+  SmallVector<uint64_t, 16> EagerlyDeserializedDecls;
 
   /// \brief DeclContexts that have received extensions since their serialized
   /// form.
@@ -438,6 +467,8 @@
                                      bool isModule);
   void WriteCXXBaseSpecifiersOffsets();
   void WriteType(QualType T);
+  uint32_t GenerateNameLookupTable(const DeclContext *DC,
+                                   llvm::SmallVectorImpl<char> &LookupTable);
   uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC);
   uint64_t WriteDeclContextVisibleBlock(ASTContext &Context, DeclContext *DC);
   void WriteTypeDeclOffsets();
@@ -448,8 +479,7 @@
   void WriteIdentifierTable(Preprocessor &PP, IdentifierResolver &IdResolver,
                             bool IsModule);
   void WriteAttributes(ArrayRef<const Attr*> Attrs, RecordDataImpl &Record);
-  void ResolveDeclUpdatesBlocks();
-  void WriteDeclUpdatesBlocks();
+  void WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord);
   void WriteDeclReplacementsBlock();
   void WriteDeclContextVisibleUpdate(const DeclContext *DC);
   void WriteFPPragmaOptions(const FPOptions &Opts);
@@ -458,6 +488,7 @@
   void WriteRedeclarations();
   void WriteMergedDecls();
   void WriteLateParsedTemplates(Sema &SemaRef);
+  void WriteOptimizePragmaOptions(Sema &SemaRef);
 
   unsigned DeclParmVarAbbrev;
   unsigned DeclContextLexicalAbbrev;
@@ -475,6 +506,7 @@
 
   void WriteDeclsBlockAbbrevs();
   void WriteDecl(ASTContext &Context, Decl *D);
+  void AddFunctionDefinition(const FunctionDecl *FD, RecordData &Record);
 
   void WriteASTCore(Sema &SemaRef,
                     StringRef isysroot, const std::string &OutputFile,
@@ -645,9 +677,7 @@
   void AddVersionTuple(const VersionTuple &Version, RecordDataImpl &Record);
 
   /// \brief Mark a declaration context as needing an update.
-  void AddUpdatedDeclContext(const DeclContext *DC) {
-    UpdatedDeclContexts.insert(DC);
-  }
+  void AddUpdatedDeclContext(const DeclContext *DC);
 
   void RewriteDecl(const Decl *D) {
     DeclsToRewrite.insert(D);
@@ -715,35 +745,36 @@
   bool hasChain() const { return Chain; }
 
   // ASTDeserializationListener implementation
-  void ReaderInitialized(ASTReader *Reader);
-  void IdentifierRead(serialization::IdentID ID, IdentifierInfo *II);
-  void MacroRead(serialization::MacroID ID, MacroInfo *MI);
-  void TypeRead(serialization::TypeIdx Idx, QualType T);
-  void SelectorRead(serialization::SelectorID ID, Selector Sel);
+  void ReaderInitialized(ASTReader *Reader) override;
+  void IdentifierRead(serialization::IdentID ID, IdentifierInfo *II) override;
+  void MacroRead(serialization::MacroID ID, MacroInfo *MI) override;
+  void TypeRead(serialization::TypeIdx Idx, QualType T) override;
+  void SelectorRead(serialization::SelectorID ID, Selector Sel) override;
   void MacroDefinitionRead(serialization::PreprocessedEntityID ID,
-                           MacroDefinition *MD);
-  void ModuleRead(serialization::SubmoduleID ID, Module *Mod);
+                           MacroDefinition *MD) override;
+  void ModuleRead(serialization::SubmoduleID ID, Module *Mod) override;
 
   // ASTMutationListener implementation.
-  virtual void CompletedTagDefinition(const TagDecl *D);
-  virtual void AddedVisibleDecl(const DeclContext *DC, const Decl *D);
-  virtual void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D);
-  virtual void AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD,
-                                    const ClassTemplateSpecializationDecl *D);
-  virtual void
-  AddedCXXTemplateSpecialization(const VarTemplateDecl *TD,
-                                 const VarTemplateSpecializationDecl *D);
-  virtual void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD,
-                                              const FunctionDecl *D);
-  virtual void DeducedReturnType(const FunctionDecl *FD, QualType ReturnType);
-  virtual void CompletedImplicitDefinition(const FunctionDecl *D);
-  virtual void StaticDataMemberInstantiated(const VarDecl *D);
-  virtual void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
-                                            const ObjCInterfaceDecl *IFD);
-  virtual void AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop,
-                                            const ObjCPropertyDecl *OrigProp,
-                                            const ObjCCategoryDecl *ClassExt);
-  void DeclarationMarkedUsed(const Decl *D) LLVM_OVERRIDE;
+  void CompletedTagDefinition(const TagDecl *D) override;
+  void AddedVisibleDecl(const DeclContext *DC, const Decl *D) override;
+  void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) override;
+  void AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD,
+                             const ClassTemplateSpecializationDecl *D) override;
+  void AddedCXXTemplateSpecialization(const VarTemplateDecl *TD,
+                               const VarTemplateSpecializationDecl *D) override;
+  void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD,
+                                      const FunctionDecl *D) override;
+  void ResolvedExceptionSpec(const FunctionDecl *FD) override;
+  void DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) override;
+  void CompletedImplicitDefinition(const FunctionDecl *D) override;
+  void StaticDataMemberInstantiated(const VarDecl *D) override;
+  void FunctionDefinitionInstantiated(const FunctionDecl *D) override;
+  void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
+                                    const ObjCInterfaceDecl *IFD) override;
+  void AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop,
+                                    const ObjCPropertyDecl *OrigProp,
+                                    const ObjCCategoryDecl *ClassExt) override;
+  void DeclarationMarkedUsed(const Decl *D) override;
 };
 
 /// \brief AST and semantic-analysis consumer that generates a
@@ -771,10 +802,10 @@
                StringRef isysroot, raw_ostream *Out,
                bool AllowASTWithErrors = false);
   ~PCHGenerator();
-  virtual void InitializeSema(Sema &S) { SemaPtr = &S; }
-  virtual void HandleTranslationUnit(ASTContext &Ctx);
-  virtual ASTMutationListener *GetASTMutationListener();
-  virtual ASTDeserializationListener *GetASTDeserializationListener();
+  void InitializeSema(Sema &S) override { SemaPtr = &S; }
+  void HandleTranslationUnit(ASTContext &Ctx) override;
+  ASTMutationListener *GetASTMutationListener() override;
+  ASTDeserializationListener *GetASTDeserializationListener() override;
 
   bool hasEmittedPCH() const { return HasEmittedPCH; }
 };
diff --git a/include/clang/Serialization/GlobalModuleIndex.h b/include/clang/Serialization/GlobalModuleIndex.h
index 76414ba..1f0d752 100644
--- a/include/clang/Serialization/GlobalModuleIndex.h
+++ b/include/clang/Serialization/GlobalModuleIndex.h
@@ -17,11 +17,11 @@
 #define LLVM_CLANG_SERIALIZATION_GLOBAL_MODULE_INDEX_H
 
 #include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
+#include <memory>
 #include <utility>
 
 namespace llvm {
@@ -59,7 +59,7 @@
 class GlobalModuleIndex {
   /// \brief Buffer containing the index file, which is lazily accessed so long
   /// as the global module index is live.
-  llvm::OwningPtr<llvm::MemoryBuffer> Buffer;
+  std::unique_ptr<llvm::MemoryBuffer> Buffer;
 
   /// \brief The hash table.
   ///
@@ -186,6 +186,9 @@
   /// \brief Print statistics to standard error.
   void printStats();
 
+  /// \brief Print debugging view to standard error.
+  void dump();
+
   /// \brief Write a global index into the given
   ///
   /// \param FileMgr The file manager to use to load module files.
diff --git a/include/clang/Serialization/Module.h b/include/clang/Serialization/Module.h
index 89c604f..4952039 100644
--- a/include/clang/Serialization/Module.h
+++ b/include/clang/Serialization/Module.h
@@ -18,17 +18,21 @@
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Serialization/ASTBitCodes.h"
 #include "clang/Serialization/ContinuousRangeMap.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/SetVector.h"
 #include "llvm/Bitcode/BitstreamReader.h"
+#include <memory>
 #include <string>
 
+namespace llvm {
+template <typename Info> class OnDiskChainedHashTable;
+template <typename Info> class OnDiskIterableChainedHashTable;
+}
+
 namespace clang {
 
 class FileEntry;
 class DeclContext;
 class Module;
-template<typename Info> class OnDiskChainedHashTable;
 
 namespace serialization {
 
@@ -49,7 +53,7 @@
   DeclContextInfo()
     : NameLookupTableData(), LexicalDecls(), NumLexicalDecls() {}
 
-  OnDiskChainedHashTable<reader::ASTDeclContextNameLookupTrait>
+  llvm::OnDiskIterableChainedHashTable<reader::ASTDeclContextNameLookupTrait>
     *NameLookupTableData; // an ASTDeclContextNameLookupTable.
   const KindDeclIDPair *LexicalDecls;
   unsigned NumLexicalDecls;
@@ -57,11 +61,12 @@
 
 /// \brief The input file that has been loaded from this AST file, along with
 /// bools indicating whether this was an overridden buffer or if it was
-/// out-of-date.
+/// out-of-date or not-found.
 class InputFile {
   enum {
     Overridden = 1,
-    OutOfDate = 2
+    OutOfDate = 2,
+    NotFound = 3
   };
   llvm::PointerIntPair<const FileEntry *, 2, unsigned> Val;
 
@@ -79,9 +84,16 @@
     Val.setPointerAndInt(File, intVal);
   }
 
+  static InputFile getNotFound() {
+    InputFile File;
+    File.Val.setInt(NotFound);
+    return File;
+  }
+
   const FileEntry *getFile() const { return Val.getPointer(); }
   bool isOverridden() const { return Val.getInt() == Overridden; }
   bool isOutOfDate() const { return Val.getInt() == OutOfDate; }
+  bool isNotFound() const { return Val.getInt() == NotFound; }
 };
 
 /// \brief Information about a module that has been loaded by the ASTReader.
@@ -107,6 +119,13 @@
   /// \brief The file name of the module file.
   std::string FileName;
 
+  /// \brief The name of the module.
+  std::string ModuleName;
+
+  std::string getTimestampFilename() const {
+    return FileName + ".timestamp";
+  }
+
   /// \brief The original source file name that was used to build the
   /// primary AST file, which may have been modified for
   /// relocatable-pch support.
@@ -124,6 +143,8 @@
   /// allow resolving headers even after headers+PCH was moved to a new path.
   std::string OriginalDir;
 
+  std::string ModuleMapPath;
+
   /// \brief Whether this precompiled header is a relocatable PCH file.
   bool RelocatablePCH;
 
@@ -139,7 +160,7 @@
   
   /// \brief The memory buffer that stores the data associated with
   /// this AST file.
-  OwningPtr<llvm::MemoryBuffer> Buffer;
+  std::unique_ptr<llvm::MemoryBuffer> Buffer;
 
   /// \brief The size of this file, in bits.
   uint64_t SizeInBits;
@@ -159,6 +180,9 @@
   /// If module A depends on and imports module B, both modules will have the
   /// same DirectImportLoc, but different ImportLoc (B's ImportLoc will be a
   /// source location inside module A).
+  ///
+  /// WARNING: This is largely useless. It doesn't tell you when a module was
+  /// made visible, just when the first submodule of that module was imported.
   SourceLocation DirectImportLoc;
 
   /// \brief The source location where this module was first imported.
@@ -177,6 +201,12 @@
   /// \brief The input files that have been loaded from this AST file.
   std::vector<InputFile> InputFilesLoaded;
 
+  /// \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;
+
   // === Source Locations ===
 
   /// \brief Cursor used to read source location entries.
diff --git a/include/clang/Serialization/ModuleManager.h b/include/clang/Serialization/ModuleManager.h
index ca643ba..3259902 100644
--- a/include/clang/Serialization/ModuleManager.h
+++ b/include/clang/Serialization/ModuleManager.h
@@ -18,6 +18,7 @@
 #include "clang/Basic/FileManager.h"
 #include "clang/Serialization/Module.h"
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
 
 namespace clang { 
 
@@ -65,7 +66,7 @@
   /// calls to visit().
   struct VisitState {
     explicit VisitState(unsigned N)
-      : VisitNumber(N, 0), NextVisitNumber(1), NextState(0)
+      : VisitNumber(N, 0), NextVisitNumber(1), NextState(nullptr)
     {
       Stack.reserve(N);
     }
@@ -194,6 +195,7 @@
 
   /// \brief Remove the given set of modules.
   void removeModules(ModuleIterator first, ModuleIterator last,
+                     llvm::SmallPtrSetImpl<ModuleFile *> &LoadedSuccessfully,
                      ModuleMap *modMap);
 
   /// \brief Add an in-memory buffer the list of known buffers
@@ -230,7 +232,7 @@
   /// Any module that is known to both the global module index and the module
   /// manager that is *not* in this set can be skipped.
   void visit(bool (*Visitor)(ModuleFile &M, void *UserData), void *UserData,
-             llvm::SmallPtrSet<ModuleFile *, 4> *ModuleFilesHit = 0);
+             llvm::SmallPtrSet<ModuleFile *, 4> *ModuleFilesHit = nullptr);
   
   /// \brief Visit each of the modules with a depth-first traversal.
   ///
diff --git a/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h b/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h
index 5978299..26335bf 100644
--- a/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h
+++ b/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h
@@ -114,8 +114,6 @@
     /// Indicates that the object is not owned and controlled by the
     /// Garbage collector.
     GCNotOwnedSymbol,
-    /// Indicates that the object is not owned and controlled by ARC.
-    ARCNotOwnedSymbol,
     /// Indicates that the return value is an owned object when the
     /// receiver is also a tracked object.
     OwnedWhenTrackedReceiver,
@@ -154,7 +152,7 @@
   }
   
   bool notOwned() const {
-    return K == NotOwnedSymbol || K == ARCNotOwnedSymbol;
+    return K == NotOwnedSymbol;
   }
   
   bool operator==(const RetEffect &Other) const {
@@ -174,9 +172,6 @@
   static RetEffect MakeGCNotOwned() {
     return RetEffect(GCNotOwnedSymbol, ObjC);
   }
-  static RetEffect MakeARCNotOwned() {
-    return RetEffect(ARCNotOwnedSymbol, ObjC);
-  }
   static RetEffect MakeNoRet() {
     return RetEffect(NoRet);
   }
@@ -202,7 +197,7 @@
 
 public:
   /// Returns the argument effects for a call.
-  llvm::ArrayRef<ArgEffect> getArgs() const { return Args; }
+  ArrayRef<ArgEffect> getArgs() const { return Args; }
 
   /// Returns the effects on the receiver.
   ArgEffect getReceiver() const { return Receiver; }
diff --git a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
index 618782e..978c3e2 100644
--- a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
+++ b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
@@ -54,6 +54,7 @@
 enum AnalysisDiagClients {
 #define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN) PD_##NAME,
 #include "clang/StaticAnalyzer/Core/Analyses.def"
+PD_NONE,
 NUM_ANALYSIS_DIAG_CLIENTS
 };
 
@@ -140,7 +141,7 @@
   unsigned AnalyzeAll : 1;
   unsigned AnalyzerDisplayProgress : 1;
   unsigned AnalyzeNestedBlocks : 1;
-  
+
   /// \brief The flag regulates if we should eagerly assume evaluations of
   /// conditionals, thus, bifurcating the path.
   ///
@@ -198,8 +199,11 @@
   /// \sa mayInlineTemplateFunctions
   Optional<bool> InlineTemplateFunctions;
 
-  /// \sa mayInlineCXXContainerCtorsAndDtors
-  Optional<bool> InlineCXXContainerCtorsAndDtors;
+  /// \sa mayInlineCXXAllocator
+  Optional<bool> InlineCXXAllocator;
+
+  /// \sa mayInlineCXXContainerMethods
+  Optional<bool> InlineCXXContainerMethods;
 
   /// \sa mayInlineCXXSharedPtrDtor
   Optional<bool> InlineCXXSharedPtrDtor;
@@ -229,6 +233,9 @@
   /// \sa reportIssuesInMainSourceFile
   Optional<bool> ReportIssuesInMainSourceFile;
 
+  /// \sa StableReportFilename
+  Optional<bool> StableReportFilename;
+
   /// \sa getGraphTrimInterval
   Optional<unsigned> GraphTrimInterval;
 
@@ -290,12 +297,18 @@
   /// accepts the values "true" and "false".
   bool mayInlineTemplateFunctions();
 
-  /// Returns whether or not constructors and destructors of C++ container
-  /// objects may be considered for inlining.
+  /// Returns whether or not allocator call may be considered for inlining.
+  ///
+  /// This is controlled by the 'c++-allocator-inlining' config option, which
+  /// accepts the values "true" and "false".
+  bool mayInlineCXXAllocator();
+
+  /// Returns whether or not methods of C++ container objects may be considered
+  /// for inlining.
   ///
   /// This is controlled by the 'c++-container-inlining' config option, which
   /// accepts the values "true" and "false".
-  bool mayInlineCXXContainerCtorsAndDtors();
+  bool mayInlineCXXContainerMethods();
 
   /// Returns whether or not the destructor of C++ 'shared_ptr' may be
   /// considered for inlining.
@@ -349,6 +362,12 @@
   /// which accepts the values "true" and "false".
   bool shouldReportIssuesInMainSourceFile();
 
+  /// Returns whether or not the report filename should be random or not.
+  ///
+  /// This is controlled by the 'stable-report-filename' config option,
+  /// which accepts the values "true" and "false". Default = false
+  bool shouldWriteStableReportFilename();
+
   /// Returns whether irrelevant parts of a bug report path should be pruned
   /// out of the final output.
   ///
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
index 9584b8b..5371231 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
@@ -19,6 +19,7 @@
 #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
 #include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/FoldingSet.h"
@@ -143,19 +144,18 @@
 
 public:
   BugReport(BugType& bt, StringRef desc, const ExplodedNode *errornode)
-    : BT(bt), DeclWithIssue(0), Description(desc), ErrorNode(errornode),
+    : BT(bt), DeclWithIssue(nullptr), Description(desc), ErrorNode(errornode),
       ConfigurationChangeToken(0), DoNotPrunePath(false) {}
 
   BugReport(BugType& bt, StringRef shortDesc, StringRef desc,
             const ExplodedNode *errornode)
-    : BT(bt), DeclWithIssue(0), ShortDescription(shortDesc), Description(desc),
-      ErrorNode(errornode), ConfigurationChangeToken(0),
+    : BT(bt), DeclWithIssue(nullptr), ShortDescription(shortDesc),
+      Description(desc), ErrorNode(errornode), ConfigurationChangeToken(0),
       DoNotPrunePath(false) {}
 
-  BugReport(BugType& bt, StringRef desc, PathDiagnosticLocation l)
-    : BT(bt), DeclWithIssue(0), Description(desc), Location(l), ErrorNode(0),
-      ConfigurationChangeToken(0),
-      DoNotPrunePath(false) {}
+  BugReport(BugType &bt, StringRef desc, PathDiagnosticLocation l)
+    : BT(bt), DeclWithIssue(nullptr), Description(desc), Location(l),
+      ErrorNode(nullptr), ConfigurationChangeToken(0), DoNotPrunePath(false) {}
 
   /// \brief Create a BugReport with a custom uniqueing location.
   ///
@@ -166,7 +166,7 @@
   /// the allocation site, rather then the location where the bug is reported.
   BugReport(BugType& bt, StringRef desc, const ExplodedNode *errornode,
             PathDiagnosticLocation LocationToUnique, const Decl *DeclToUnique)
-    : BT(bt), DeclWithIssue(0), Description(desc),
+    : BT(bt), DeclWithIssue(nullptr), Description(desc),
       UniqueingLocation(LocationToUnique),
       UniqueingDecl(DeclToUnique),
       ErrorNode(errornode), ConfigurationChangeToken(0),
@@ -463,7 +463,12 @@
   /// reports.
   void emitReport(BugReport *R);
 
-  void EmitBasicReport(const Decl *DeclWithIssue,
+  void EmitBasicReport(const Decl *DeclWithIssue, const CheckerBase *Checker,
+                       StringRef BugName, StringRef BugCategory,
+                       StringRef BugStr, PathDiagnosticLocation Loc,
+                       ArrayRef<SourceRange> Ranges = None);
+
+  void EmitBasicReport(const Decl *DeclWithIssue, CheckName CheckName,
                        StringRef BugName, StringRef BugCategory,
                        StringRef BugStr, PathDiagnosticLocation Loc,
                        ArrayRef<SourceRange> Ranges = None);
@@ -473,7 +478,8 @@
 
   /// \brief Returns a BugType that is associated with the given name and
   /// category.
-  BugType *getBugTypeForName(StringRef name, StringRef category);
+  BugType *getBugTypeForName(CheckName CheckName, StringRef name,
+                             StringRef category);
 };
 
 // FIXME: Get rid of GRBugReporter.  It's the wrong abstraction.
@@ -505,9 +511,8 @@
   ///
   /// \return True if the report was valid and a path was generated,
   ///         false if the reports should be considered invalid.
-  virtual bool generatePathDiagnostic(PathDiagnostic &PD,
-                                      PathDiagnosticConsumer &PC,
-                                      ArrayRef<BugReport*> &bugReports);
+  bool generatePathDiagnostic(PathDiagnostic &PD, PathDiagnosticConsumer &PC,
+                              ArrayRef<BugReport*> &bugReports) override;
 
   /// classof - Used by isa<>, cast<>, and dyn_cast<>.
   static bool classof(const BugReporter* R) {
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
index 2e67180..f352f80 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
@@ -89,7 +89,7 @@
 /// will have to provide your own implementation.)
 template <class DERIVED>
 class BugReporterVisitorImpl : public BugReporterVisitor {
-  virtual BugReporterVisitor *clone() const {
+  BugReporterVisitor *clone() const override {
     return new DERIVED(*static_cast<const DERIVED *>(this));
   }
 };
@@ -118,12 +118,12 @@
     Satisfied(false),
     EnableNullFPSuppression(InEnableNullFPSuppression) {}
 
-  void Profile(llvm::FoldingSetNodeID &ID) const;
+  void Profile(llvm::FoldingSetNodeID &ID) const override;
 
   PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
                                  const ExplodedNode *PrevN,
                                  BugReporterContext &BRC,
-                                 BugReport &BR);
+                                 BugReport &BR) override;
 };
 
 class TrackConstraintBRVisitor
@@ -144,7 +144,7 @@
     IsZeroCheck(!Assumption && Constraint.getAs<Loc>()),
     IsTrackingTurnedOn(false) {}
 
-  void Profile(llvm::FoldingSetNodeID &ID) const;
+  void Profile(llvm::FoldingSetNodeID &ID) const override;
 
   /// Return the tag associated with this visitor.  This tag will be used
   /// to make all PathDiagnosticPieces created by this visitor.
@@ -153,7 +153,7 @@
   PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
                                  const ExplodedNode *PrevN,
                                  BugReporterContext &BRC,
-                                 BugReport &BR);
+                                 BugReport &BR) override;
 
 private:
   /// Checks if the constraint is valid in the current state.
@@ -166,8 +166,8 @@
 class NilReceiverBRVisitor
   : public BugReporterVisitorImpl<NilReceiverBRVisitor> {
 public:
-  
-  void Profile(llvm::FoldingSetNodeID &ID) const {
+
+  void Profile(llvm::FoldingSetNodeID &ID) const override {
     static int x = 0;
     ID.AddPointer(&x);
   }
@@ -175,7 +175,7 @@
   PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
                                  const ExplodedNode *PrevN,
                                  BugReporterContext &BRC,
-                                 BugReport &BR);
+                                 BugReport &BR) override;
 
   /// If the statement is a message send expression with nil receiver, returns
   /// the receiver expression. Returns NULL otherwise.
@@ -185,7 +185,7 @@
 /// Visitor that tries to report interesting diagnostics from conditions.
 class ConditionBRVisitor : public BugReporterVisitorImpl<ConditionBRVisitor> {
 public:
-  void Profile(llvm::FoldingSetNodeID &ID) const {
+  void Profile(llvm::FoldingSetNodeID &ID) const override {
     static int x = 0;
     ID.AddPointer(&x);
   }
@@ -193,11 +193,11 @@
   /// Return the tag associated with this visitor.  This tag will be used
   /// to make all PathDiagnosticPieces created by this visitor.
   static const char *getTag();
-  
-  virtual PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
-                                         const ExplodedNode *Prev,
-                                         BugReporterContext &BRC,
-                                         BugReport &BR);
+
+  PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
+                                 const ExplodedNode *Prev,
+                                 BugReporterContext &BRC,
+                                 BugReport &BR) override;
 
   PathDiagnosticPiece *VisitNodeImpl(const ExplodedNode *N,
                                      const ExplodedNode *Prev,
@@ -257,20 +257,20 @@
     return static_cast<void *>(&Tag);
   }
 
-  void Profile(llvm::FoldingSetNodeID &ID) const {
+  void Profile(llvm::FoldingSetNodeID &ID) const override {
     ID.AddPointer(getTag());
   }
 
-  virtual PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
-                                         const ExplodedNode *Prev,
-                                         BugReporterContext &BRC,
-                                         BugReport &BR) {
-    return 0;
+  PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
+                                 const ExplodedNode *Prev,
+                                 BugReporterContext &BRC,
+                                 BugReport &BR) override {
+    return nullptr;
   }
 
-  virtual PathDiagnosticPiece *getEndPath(BugReporterContext &BRC,
-                                          const ExplodedNode *N,
-                                          BugReport &BR);
+  PathDiagnosticPiece *getEndPath(BugReporterContext &BRC,
+                                  const ExplodedNode *N,
+                                  BugReport &BR) override;
 };
 
 /// \brief When a region containing undefined value or '0' value is passed 
@@ -287,7 +287,7 @@
 public:
   UndefOrNullArgVisitor(const MemRegion *InR) : R(InR) {}
 
-  virtual void Profile(llvm::FoldingSetNodeID &ID) const {
+  void Profile(llvm::FoldingSetNodeID &ID) const override {
     static int Tag = 0;
     ID.AddPointer(&Tag);
     ID.AddPointer(R);
@@ -296,7 +296,7 @@
   PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
                                  const ExplodedNode *PrevN,
                                  BugReporterContext &BRC,
-                                 BugReport &BR);
+                                 BugReport &BR) override;
 };
 
 class SuppressInlineDefensiveChecksVisitor
@@ -319,7 +319,7 @@
 public:
   SuppressInlineDefensiveChecksVisitor(DefinedSVal Val, const ExplodedNode *N);
 
-  void Profile(llvm::FoldingSetNodeID &ID) const;
+  void Profile(llvm::FoldingSetNodeID &ID) const override;
 
   /// Return the tag associated with this visitor.  This tag will be used
   /// to make all PathDiagnosticPieces created by this visitor.
@@ -328,7 +328,7 @@
   PathDiagnosticPiece *VisitNode(const ExplodedNode *Succ,
                                  const ExplodedNode *Pred,
                                  BugReporterContext &BRC,
-                                 BugReport &BR);
+                                 BugReport &BR) override;
 };
 
 namespace bugreporter {
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
index 49f9c83..24c7785 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
@@ -14,8 +14,9 @@
 #ifndef LLVM_CLANG_ANALYSIS_BUGTYPE
 #define LLVM_CLANG_ANALYSIS_BUGTYPE
 
-#include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h"
 #include "clang/Basic/LLVM.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
 #include "llvm/ADT/FoldingSet.h"
 #include <string>
 
@@ -29,20 +30,25 @@
 
 class BugType {
 private:
+  const CheckName Check;
   const std::string Name;
   const std::string Category;
   bool SuppressonSink;
 
   virtual void anchor();
 public:
-  BugType(StringRef name, StringRef cat)
-    : Name(name), Category(cat), SuppressonSink(false) {}
+  BugType(class CheckName check, StringRef name, StringRef cat)
+      : Check(check), Name(name), Category(cat), SuppressonSink(false) {}
+  BugType(const CheckerBase *checker, StringRef name, StringRef cat)
+      : Check(checker->getCheckName()), Name(name), Category(cat),
+        SuppressonSink(false) {}
   virtual ~BugType() {}
 
   // FIXME: Should these be made strings as well?
   StringRef getName() const { return Name; }
   StringRef getCategory() const { return Category; }
-  
+  StringRef getCheckName() const { return Check.getName(); }
+
   /// isSuppressOnSink - Returns true if bug reports associated with this bug
   ///  type should be suppressed if the end node of the report is post-dominated
   ///  by a sink node.
@@ -54,14 +60,18 @@
 
 class BuiltinBug : public BugType {
   const std::string desc;
-  virtual void anchor();
+  void anchor() override;
 public:
-  BuiltinBug(const char *name, const char *description)
-    : BugType(name, categories::LogicError), desc(description) {}
-  
-  BuiltinBug(const char *name)
-    : BugType(name, categories::LogicError), desc(name) {}
-  
+  BuiltinBug(class CheckName check, const char *name, const char *description)
+      : BugType(check, name, categories::LogicError), desc(description) {}
+
+  BuiltinBug(const CheckerBase *checker, const char *name,
+             const char *description)
+      : BugType(checker, name, categories::LogicError), desc(description) {}
+
+  BuiltinBug(const CheckerBase *checker, const char *name)
+      : BugType(checker, name, categories::LogicError), desc(name) {}
+
   StringRef getDescription() const { return desc; }
 };
 
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
index b0670da..5a578d0 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
@@ -21,13 +21,13 @@
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/PointerUnion.h"
 #include <deque>
-#include <list>
 #include <iterator>
+#include <list>
 #include <string>
 #include <vector>
 
 namespace clang {
-
+class ConditionalOperator;
 class AnalysisDeclContext;
 class BinaryOperator;
 class CompoundStmt;
@@ -72,7 +72,9 @@
   
   struct FilesMade : public llvm::FoldingSet<PDFileEntry> {
     llvm::BumpPtrAllocator Alloc;
-    
+
+    ~FilesMade();
+
     void addDiagnostic(const PathDiagnostic &PD,
                        StringRef ConsumerName,
                        StringRef fileName);
@@ -136,29 +138,29 @@
 
   PathDiagnosticLocation(SourceLocation L, const SourceManager &sm,
                          Kind kind)
-    : K(kind), S(0), D(0), SM(&sm),
+    : K(kind), S(nullptr), D(nullptr), SM(&sm),
       Loc(genLocation(L)), Range(genRange()) {
   }
 
-  FullSourceLoc
-    genLocation(SourceLocation L = SourceLocation(),
-                LocationOrAnalysisDeclContext LAC = (AnalysisDeclContext*)0) const;
+  FullSourceLoc genLocation(
+      SourceLocation L = SourceLocation(),
+      LocationOrAnalysisDeclContext LAC = (AnalysisDeclContext *)nullptr) const;
 
-  PathDiagnosticRange
-    genRange(LocationOrAnalysisDeclContext LAC = (AnalysisDeclContext*)0) const;
+  PathDiagnosticRange genRange(
+      LocationOrAnalysisDeclContext LAC = (AnalysisDeclContext *)nullptr) const;
 
 public:
   /// Create an invalid location.
   PathDiagnosticLocation()
-    : K(SingleLocK), S(0), D(0), SM(0) {}
+    : K(SingleLocK), S(nullptr), D(nullptr), SM(nullptr) {}
 
   /// Create a location corresponding to the given statement.
   PathDiagnosticLocation(const Stmt *s,
                          const SourceManager &sm,
                          LocationOrAnalysisDeclContext lac)
     : K(s->getLocStart().isValid() ? StmtK : SingleLocK),
-      S(K == StmtK ? s : 0),
-      D(0), SM(&sm),
+      S(K == StmtK ? s : nullptr),
+      D(nullptr), SM(&sm),
       Loc(genLocation(SourceLocation(), lac)),
       Range(genRange(lac)) {
     assert(K == SingleLocK || S);
@@ -168,7 +170,7 @@
 
   /// Create a location corresponding to the given declaration.
   PathDiagnosticLocation(const Decl *d, const SourceManager &sm)
-    : K(DeclK), S(0), D(d), SM(&sm),
+    : K(DeclK), S(nullptr), D(d), SM(&sm),
       Loc(genLocation()), Range(genRange()) {
     assert(D);
     assert(Loc.isValid());
@@ -179,7 +181,8 @@
   ///
   /// This should only be used if there are no more appropriate constructors.
   PathDiagnosticLocation(SourceLocation loc, const SourceManager &sm)
-    : K(SingleLocK), S(0), D(0), SM(&sm), Loc(loc, sm), Range(genRange()) {
+    : K(SingleLocK), S(nullptr), D(nullptr), SM(&sm), Loc(loc, sm),
+      Range(genRange()) {
     assert(Loc.isValid());
     assert(Range.isValid());
   }
@@ -211,6 +214,9 @@
   /// Assumes the statement has a valid location.
   static PathDiagnosticLocation createOperatorLoc(const BinaryOperator *BO,
                                                   const SourceManager &SM);
+  static PathDiagnosticLocation createConditionalColonLoc(
+                                                  const ConditionalOperator *CO,
+                                                  const SourceManager &SM);
 
   /// For member expressions, return the location of the '.' or '->'.
   /// Assumes the statement has a valid location.
@@ -259,7 +265,7 @@
   }
 
   bool isValid() const {
-    return SM != 0;
+    return SM != nullptr;
   }
 
   FullSourceLoc asLocation() const {
@@ -420,7 +426,7 @@
     return Result;
   }
 
-  LLVM_ATTRIBUTE_USED void dump() const;
+  void dump() const;
 };
 
 class PathDiagnosticSpotPiece : public PathDiagnosticPiece {
@@ -437,10 +443,10 @@
     if (addPosRange && Pos.hasRange()) addRange(Pos.asRange());
   }
 
-  PathDiagnosticLocation getLocation() const { return Pos; }
-  virtual void flattenLocations() { Pos.flatten(); }
+  PathDiagnosticLocation getLocation() const override { return Pos; }
+  void flattenLocations() override { Pos.flatten(); }
 
-  virtual void Profile(llvm::FoldingSetNodeID &ID) const;
+  void Profile(llvm::FoldingSetNodeID &ID) const override;
 
   static bool classof(const PathDiagnosticPiece *P) {
     return P->getKind() == Event || P->getKind() == Macro;
@@ -476,7 +482,7 @@
 
   /// \brief Search the call expression for the symbol Sym and dispatch the
   /// 'getMessageForX()' methods to construct a specific message.
-  virtual std::string getMessage(const ExplodedNode *N);
+  std::string getMessage(const ExplodedNode *N) override;
 
   /// Produces the message of the following form:
   ///   'Msg via Nth parameter'
@@ -496,12 +502,12 @@
   /// supply a message that will be used to construct an extra hint on the
   /// returns from all the calls on the stack from this event to the final
   /// diagnostic.
-  OwningPtr<StackHintGenerator> CallStackHint;
+  std::unique_ptr<StackHintGenerator> CallStackHint;
 
 public:
   PathDiagnosticEventPiece(const PathDiagnosticLocation &pos,
                            StringRef s, bool addPosRange = true,
-                           StackHintGenerator *stackHint = 0)
+                           StackHintGenerator *stackHint = nullptr)
     : PathDiagnosticSpotPiece(pos, s, Event, addPosRange),
       CallStackHint(stackHint) {}
 
@@ -520,10 +526,8 @@
   bool isPrunable() const {
     return IsPrunable.hasValue() ? IsPrunable.getValue() : false;
   }
-  
-  bool hasCallStackHint() {
-    return CallStackHint.isValid();
-  }
+
+  bool hasCallStackHint() { return (bool)CallStackHint; }
 
   /// Produce the hint for the given node. The node contains 
   /// information about the call for which the diagnostic can be generated.
@@ -533,7 +537,7 @@
     return "";  
   }
 
-  virtual void dump() const;
+  void dump() const override;
 
   static inline bool classof(const PathDiagnosticPiece *P) {
     return P->getKind() == Event;
@@ -543,11 +547,11 @@
 class PathDiagnosticCallPiece : public PathDiagnosticPiece {
   PathDiagnosticCallPiece(const Decl *callerD,
                           const PathDiagnosticLocation &callReturnPos)
-    : PathDiagnosticPiece(Call), Caller(callerD), Callee(0),
+    : PathDiagnosticPiece(Call), Caller(callerD), Callee(nullptr),
       NoExit(false), callReturn(callReturnPos) {}
 
   PathDiagnosticCallPiece(PathPieces &oldPath, const Decl *caller)
-    : PathDiagnosticPiece(Call), Caller(caller), Callee(0),
+    : PathDiagnosticPiece(Call), Caller(caller), Callee(nullptr),
       NoExit(true), path(oldPath) {}
   
   const Decl *Caller;
@@ -579,7 +583,7 @@
     CallStackMessage = st;
   }
 
-  virtual PathDiagnosticLocation getLocation() const {
+  PathDiagnosticLocation getLocation() const override {
     return callEnter;
   }
   
@@ -588,7 +592,7 @@
     getCallEnterWithinCallerEvent() const;
   IntrusiveRefCntPtr<PathDiagnosticEventPiece> getCallExitEvent() const;
 
-  virtual void flattenLocations() {
+  void flattenLocations() override {
     callEnter.flatten();
     callReturn.flatten();
     for (PathPieces::iterator I = path.begin(), 
@@ -601,10 +605,10 @@
   
   static PathDiagnosticCallPiece *construct(PathPieces &pieces,
                                             const Decl *caller);
-  
-  virtual void dump() const;
 
-  virtual void Profile(llvm::FoldingSetNodeID &ID) const;
+  void dump() const override;
+
+  void Profile(llvm::FoldingSetNodeID &ID) const override;
 
   static inline bool classof(const PathDiagnosticPiece *P) {
     return P->getKind() == Call;
@@ -651,7 +655,7 @@
 
   void push_back(const PathDiagnosticLocationPair &X) { LPairs.push_back(X); }
 
-  virtual PathDiagnosticLocation getLocation() const {
+  PathDiagnosticLocation getLocation() const override {
     return getStartLocation();
   }
 
@@ -659,7 +663,7 @@
   iterator begin() { return LPairs.begin(); }
   iterator end()   { return LPairs.end(); }
 
-  virtual void flattenLocations() {
+  void flattenLocations() override {
     for (iterator I=begin(), E=end(); I!=E; ++I) I->flatten();
   }
 
@@ -672,9 +676,9 @@
     return P->getKind() == ControlFlow;
   }
 
-  virtual void dump() const;
+  void dump() const override;
 
-  virtual void Profile(llvm::FoldingSetNodeID &ID) const;
+  void Profile(llvm::FoldingSetNodeID &ID) const override;
 };
 
 class PathDiagnosticMacroPiece : public PathDiagnosticSpotPiece {
@@ -688,7 +692,7 @@
   
   bool containsEvent() const;
 
-  virtual void flattenLocations() {
+  void flattenLocations() override {
     PathDiagnosticSpotPiece::flattenLocations();
     for (PathPieces::iterator I = subPieces.begin(), 
          E = subPieces.end(); I != E; ++I) (*I)->flattenLocations();
@@ -698,15 +702,16 @@
     return P->getKind() == Macro;
   }
 
-  virtual void dump() const;
+  void dump() const override;
 
-  virtual void Profile(llvm::FoldingSetNodeID &ID) const;
+  void Profile(llvm::FoldingSetNodeID &ID) const override;
 };
 
 /// PathDiagnostic - PathDiagnostic objects represent a single path-sensitive
 ///  diagnostic.  It represents an ordered-collection of PathDiagnosticPieces,
 ///  each which represent the pieces of the path.
 class PathDiagnostic : public llvm::FoldingSetNode {
+  std::string CheckName;
   const Decl *DeclWithIssue;
   std::string BugType;
   std::string VerboseDesc;
@@ -727,8 +732,8 @@
 
   PathDiagnostic() LLVM_DELETED_FUNCTION;
 public:
-  PathDiagnostic(const Decl *DeclWithIssue, StringRef bugtype,
-                 StringRef verboseDesc, StringRef shortDesc,
+  PathDiagnostic(StringRef CheckName, const Decl *DeclWithIssue,
+                 StringRef bugtype, StringRef verboseDesc, StringRef shortDesc,
                  StringRef category, PathDiagnosticLocation LocationToUnique,
                  const Decl *DeclToUnique);
 
@@ -785,6 +790,7 @@
   StringRef getShortDescription() const {
     return ShortDesc.empty() ? VerboseDesc : ShortDesc;
   }
+  StringRef getCheckName() const { return CheckName; }
   StringRef getBugType() const { return BugType; }
   StringRef getCategory() const { return Category; }
 
diff --git a/include/clang/StaticAnalyzer/Core/Checker.h b/include/clang/StaticAnalyzer/Core/Checker.h
index cf7cf05..b9a5b8a 100644
--- a/include/clang/StaticAnalyzer/Core/Checker.h
+++ b/include/clang/StaticAnalyzer/Core/Checker.h
@@ -453,14 +453,29 @@
 } // end eval namespace
 
 class CheckerBase : public ProgramPointTag {
+  CheckName Name;
+  friend class ::clang::ento::CheckerManager;
+
 public:
-  StringRef getTagDescription() const;
+  StringRef getTagDescription() const override;
+  CheckName getCheckName() const;
 
   /// See CheckerManager::runCheckersForPrintState.
   virtual void printState(raw_ostream &Out, ProgramStateRef State,
                           const char *NL, const char *Sep) const { }
 };
-  
+
+/// Dump checker name to stream.
+raw_ostream& operator<<(raw_ostream &Out, const CheckerBase &Checker);
+
+/// Tag that can use a checker name as a message provider 
+/// (see SimpleProgramPointTag).
+class CheckerProgramPointTag : public SimpleProgramPointTag {
+public:
+  CheckerProgramPointTag(StringRef CheckerName, StringRef Msg);
+  CheckerProgramPointTag(const CheckerBase *Checker, StringRef Msg);
+};
+
 template <typename CHECK1, typename CHECK2=check::_VoidCheck,
           typename CHECK3=check::_VoidCheck, typename CHECK4=check::_VoidCheck,
           typename CHECK5=check::_VoidCheck, typename CHECK6=check::_VoidCheck,
@@ -511,7 +526,7 @@
 class EventDispatcher {
   CheckerManager *Mgr;
 public:
-  EventDispatcher() : Mgr(0) { }
+  EventDispatcher() : Mgr(nullptr) { }
 
   template <typename CHECKER>
   static void _register(CHECKER *checker, CheckerManager &mgr) {
diff --git a/include/clang/StaticAnalyzer/Core/CheckerManager.h b/include/clang/StaticAnalyzer/Core/CheckerManager.h
index 8ad67c1..b364115 100644
--- a/include/clang/StaticAnalyzer/Core/CheckerManager.h
+++ b/include/clang/StaticAnalyzer/Core/CheckerManager.h
@@ -16,8 +16,8 @@
 
 #include "clang/Analysis/ProgramPoint.h"
 #include "clang/Basic/LangOptions.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
 #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallVector.h"
 #include <vector>
@@ -29,11 +29,11 @@
 
 namespace ento {
   class CheckerBase;
+  class CheckerRegistry;
   class ExprEngine;
   class AnalysisManager;
   class BugReporter;
   class CheckerContext;
-  class SimpleCall;
   class ObjCMethodCall;
   class SVal;
   class ExplodedNode;
@@ -132,9 +132,26 @@
   PSK_EscapeOther
 };
 
+// This wrapper is used to ensure that only StringRefs originating from the
+// CheckerRegistry are used as check names. We want to make sure all check
+// name strings have a lifetime that keeps them alive at least until the path
+// diagnostics have been processed.
+class CheckName {
+  StringRef Name;
+  friend class ::clang::ento::CheckerRegistry;
+  explicit CheckName(StringRef Name) : Name(Name) {}
+
+public:
+  CheckName() {}
+  CheckName(const CheckName &Other) : Name(Other.Name) {}
+  StringRef getName() const { return Name; }
+};
+
 class CheckerManager {
   const LangOptions LangOpts;
   AnalyzerOptionsRef AOptions;
+  CheckName CurrentCheckName;
+
 public:
   CheckerManager(const LangOptions &langOpts,
                  AnalyzerOptionsRef AOptions)
@@ -143,6 +160,9 @@
 
   ~CheckerManager();
 
+  void setCurrentCheckName(CheckName name) { CurrentCheckName = name; }
+  CheckName getCurrentCheckName() const { return CurrentCheckName; }
+
   bool hasPathSensitiveCheckers() const;
 
   void finishedCheckerRegistration();
@@ -169,6 +189,7 @@
       return static_cast<CHECKER *>(ref); // already registered.
 
     CHECKER *checker = new CHECKER();
+    checker->Name = CurrentCheckName;
     CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
     CHECKER::_register(checker, *this);
     ref = checker;
@@ -183,6 +204,7 @@
       return static_cast<CHECKER *>(ref); // already registered.
 
     CHECKER *checker = new CHECKER(AOpts);
+    checker->Name = CurrentCheckName;
     CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>));
     CHECKER::_register(checker, *this);
     ref = checker;
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h b/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h
index 9502900..37be69a 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h
@@ -11,6 +11,7 @@
 #define LLVM_CLANG_SA_CORE_APSINTTYPE_H
 
 #include "llvm/ADT/APSInt.h"
+#include <tuple>
 
 namespace clang {
 namespace ento {
@@ -97,13 +98,8 @@
   /// Unsigned integers are considered to be better conversion types than
   /// signed integers of the same width.
   bool operator<(const APSIntType &Other) const {
-    if (BitWidth < Other.BitWidth)
-      return true;
-    if (BitWidth > Other.BitWidth)
-      return false;
-    if (!IsUnsigned && Other.IsUnsigned)
-      return true;
-    return false;
+    return std::tie(BitWidth, IsUnsigned) <
+           std::tie(Other.BitWidth, Other.IsUnsigned);
   }
 };
     
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
index d7d83ce..1a398b8 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
@@ -65,8 +65,8 @@
   StoreManagerCreator getStoreManagerCreator() {
     return CreateStoreMgr;
   }
-  
-  AnalyzerOptions& getAnalyzerOptions() {
+
+  AnalyzerOptions& getAnalyzerOptions() override {
     return options;
   }
 
@@ -76,15 +76,15 @@
 
   CheckerManager *getCheckerManager() const { return CheckerMgr; }
 
-  virtual ASTContext &getASTContext() {
+  ASTContext &getASTContext() override {
     return Ctx;
   }
 
-  virtual SourceManager &getSourceManager() {
+  SourceManager &getSourceManager() override {
     return getASTContext().getSourceManager();
   }
 
-  virtual DiagnosticsEngine &getDiagnostic() {
+  DiagnosticsEngine &getDiagnostic() override {
     return Diags;
   }
 
@@ -92,7 +92,7 @@
     return LangOpts;
   }
 
-  ArrayRef<PathDiagnosticConsumer*> getPathDiagnosticConsumers()  {
+  ArrayRef<PathDiagnosticConsumer*> getPathDiagnosticConsumers() override {
     return PathConsumers;
   }
 
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
index 2c799c0..08905fd 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
@@ -79,9 +79,9 @@
   const llvm::APSInt& getValue(uint64_t X, unsigned BitWidth, bool isUnsigned);
 
 public:
-  BasicValueFactory(ASTContext &ctx, llvm::BumpPtrAllocator& Alloc)
-  : Ctx(ctx), BPAlloc(Alloc), PersistentSVals(0), PersistentSValPairs(0),
-    SValListFactory(Alloc) {}
+  BasicValueFactory(ASTContext &ctx, llvm::BumpPtrAllocator &Alloc)
+    : Ctx(ctx), BPAlloc(Alloc), PersistentSVals(nullptr),
+      PersistentSValPairs(nullptr), SValListFactory(Alloc) {}
 
   ~BasicValueFactory();
 
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h b/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h
index 2483a79..0408070 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h
@@ -16,9 +16,7 @@
 #ifndef LLVM_CLANG_GR_BLOCKCOUNTER
 #define LLVM_CLANG_GR_BLOCKCOUNTER
 
-namespace llvm {
-  class BumpPtrAllocator;
-}
+#include "llvm/Support/Allocator.h"
 
 namespace clang {
 
@@ -35,7 +33,7 @@
   BlockCounter(void *D) : Data(D) {}
 
 public:
-  BlockCounter() : Data(0) {}
+  BlockCounter() : Data(nullptr) {}
 
   unsigned getNumVisited(const StackFrameContext *CallSite, 
                          unsigned BlockID) const;
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
index cfaf085..4a5426b 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
@@ -33,9 +33,6 @@
 
 enum CallEventKind {
   CE_Function,
-  CE_Block,
-  CE_BEG_SIMPLE_CALLS = CE_Function,
-  CE_END_SIMPLE_CALLS = CE_Block,
   CE_CXXMember,
   CE_CXXMemberOperator,
   CE_CXXDestructor,
@@ -45,6 +42,7 @@
   CE_CXXAllocator,
   CE_BEG_FUNCTION_CALLS = CE_Function,
   CE_END_FUNCTION_CALLS = CE_CXXAllocator,
+  CE_Block,
   CE_ObjCMessage
 };
 
@@ -58,14 +56,14 @@
   CallEventRef(const CallEventRef &Orig) : IntrusiveRefCntPtr<const T>(Orig) {}
 
   CallEventRef<T> cloneWithState(ProgramStateRef State) const {
-    return this->getPtr()->template cloneWithState<T>(State);
+    return this->get()->template cloneWithState<T>(State);
   }
 
   // Allow implicit conversions to a superclass type, since CallEventRef
   // behaves like a pointer-to-const.
   template <typename SuperT>
   operator CallEventRef<SuperT> () const {
-    return this->getPtr();
+    return this->get();
   }
 };
 
@@ -88,15 +86,15 @@
   const MemRegion *R;
 
 public:
-  RuntimeDefinition(): D(0), R(0) {}
-  RuntimeDefinition(const Decl *InD): D(InD), R(0) {}
+  RuntimeDefinition(): D(nullptr), R(nullptr) {}
+  RuntimeDefinition(const Decl *InD): D(InD), R(nullptr) {}
   RuntimeDefinition(const Decl *InD, const MemRegion *InR): D(InD), R(InR) {}
   const Decl *getDecl() { return D; }
     
   /// \brief Check if the definition we have is precise. 
   /// If not, it is possible that the call dispatches to another definition at 
   /// execution time.
-  bool mayHaveOtherDefinitions() { return R != 0; }
+  bool mayHaveOtherDefinitions() { return R != nullptr; }
   
   /// When other definitions are possible, returns the region whose runtime type 
   /// determines the method definition.
@@ -239,7 +237,7 @@
 
   /// \brief Returns the expression associated with a given argument.
   /// May be null if this expression does not appear in the source.
-  virtual const Expr *getArgExpr(unsigned Index) const { return 0; }
+  virtual const Expr *getArgExpr(unsigned Index) const { return nullptr; }
 
   /// \brief Returns the source range for errors associated with this argument.
   ///
@@ -295,20 +293,20 @@
   const IdentifierInfo *getCalleeIdentifier() const {
     const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(getDecl());
     if (!ND)
-      return 0;
+      return nullptr;
     return ND->getIdentifier();
   }
 
   /// \brief Returns an appropriate ProgramPoint for this call.
   ProgramPoint getProgramPoint(bool IsPreVisit = false,
-                               const ProgramPointTag *Tag = 0) const;
+                               const ProgramPointTag *Tag = nullptr) const;
 
   /// \brief Returns a new state with all argument regions invalidated.
   ///
   /// This accepts an alternate state in case some processing has already
   /// occurred.
   ProgramStateRef invalidateRegions(unsigned BlockCount,
-                                    ProgramStateRef Orig = 0) const;
+                                    ProgramStateRef Orig = nullptr) const;
 
   typedef std::pair<Loc, SVal> FrameBindingTy;
   typedef SmallVectorImpl<FrameBindingTy> BindingsTy;
@@ -344,23 +342,16 @@
   // Iterator access to formal parameters and their types.
 private:
   typedef std::const_mem_fun_t<QualType, ParmVarDecl> get_type_fun;
-  
-public:
-  typedef const ParmVarDecl * const *param_iterator;
 
-  /// Returns an iterator over the call's formal parameters.
+public:
+  /// Return call's formal parameters.
   ///
   /// Remember that the number of formal parameters may not match the number
   /// of arguments for all calls. However, the first parameter will always
   /// correspond with the argument value returned by \c getArgSVal(0).
-  ///
-  /// If the call has no accessible declaration, \c param_begin() will be equal
-  /// to \c param_end().
-  virtual param_iterator param_begin() const = 0;
-  /// \sa param_begin()
-  virtual param_iterator param_end() const = 0;
+  virtual ArrayRef<ParmVarDecl*> parameters() const = 0;
 
-  typedef llvm::mapped_iterator<param_iterator, get_type_fun>
+  typedef llvm::mapped_iterator<ArrayRef<ParmVarDecl*>::iterator, get_type_fun>
     param_type_iterator;
 
   /// Returns an iterator over the types of the call's formal parameters.
@@ -369,17 +360,18 @@
   /// definition because it represents a public interface, and probably has
   /// more annotations.
   param_type_iterator param_type_begin() const {
-    return llvm::map_iterator(param_begin(),
+    return llvm::map_iterator(parameters().begin(),
                               get_type_fun(&ParmVarDecl::getType));
   }
   /// \sa param_type_begin()
   param_type_iterator param_type_end() const {
-    return llvm::map_iterator(param_end(), get_type_fun(&ParmVarDecl::getType));
+    return llvm::map_iterator(parameters().end(),
+                              get_type_fun(&ParmVarDecl::getType));
   }
 
   // For debugging purposes only
   void dump(raw_ostream &Out) const;
-  LLVM_ATTRIBUTE_USED void dump() const;
+  void dump() const;
 };
 
 
@@ -398,11 +390,11 @@
 public:
   // This function is overridden by subclasses, but they must return
   // a FunctionDecl.
-  virtual const FunctionDecl *getDecl() const {
+  const FunctionDecl *getDecl() const override {
     return cast<FunctionDecl>(CallEvent::getDecl());
   }
 
-  virtual RuntimeDefinition getRuntimeDefinition() const {
+  RuntimeDefinition getRuntimeDefinition() const override {
     const FunctionDecl *FD = getDecl();
     // Note that the AnalysisDeclContext will have the FunctionDecl with
     // the definition (if one exists).
@@ -417,13 +409,12 @@
     return RuntimeDefinition();
   }
 
-  virtual bool argumentsMayEscape() const;
+  bool argumentsMayEscape() const override;
 
-  virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
-                                            BindingsTy &Bindings) const;
+  void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
+                                    BindingsTy &Bindings) const override;
 
-  virtual param_iterator param_begin() const;
-  virtual param_iterator param_end() const;
+  ArrayRef<ParmVarDecl *> parameters() const override;
 
   static bool classof(const CallEvent *CA) {
     return CA->getKind() >= CE_BEG_FUNCTION_CALLS &&
@@ -431,49 +422,36 @@
   }
 };
 
-/// \brief Represents a call to a non-C++ function, written as a CallExpr.
-class SimpleCall : public AnyFunctionCall {
+/// \brief Represents a C function or static C++ member function call.
+///
+/// Example: \c fun()
+class SimpleFunctionCall : public AnyFunctionCall {
+  friend class CallEventManager;
+
 protected:
-  SimpleCall(const CallExpr *CE, ProgramStateRef St,
-             const LocationContext *LCtx)
+  SimpleFunctionCall(const CallExpr *CE, ProgramStateRef St,
+                     const LocationContext *LCtx)
     : AnyFunctionCall(CE, St, LCtx) {}
-  SimpleCall(const SimpleCall &Other) : AnyFunctionCall(Other) {}
+  SimpleFunctionCall(const SimpleFunctionCall &Other)
+    : AnyFunctionCall(Other) {}
+  void cloneTo(void *Dest) const override {
+    new (Dest) SimpleFunctionCall(*this);
+  }
 
 public:
   virtual const CallExpr *getOriginExpr() const {
     return cast<CallExpr>(AnyFunctionCall::getOriginExpr());
   }
 
-  virtual const FunctionDecl *getDecl() const;
+  const FunctionDecl *getDecl() const override;
 
-  virtual unsigned getNumArgs() const { return getOriginExpr()->getNumArgs(); }
+  unsigned getNumArgs() const override { return getOriginExpr()->getNumArgs(); }
 
-  virtual const Expr *getArgExpr(unsigned Index) const {
+  const Expr *getArgExpr(unsigned Index) const override {
     return getOriginExpr()->getArg(Index);
   }
 
-  static bool classof(const CallEvent *CA) {
-    return CA->getKind() >= CE_BEG_SIMPLE_CALLS &&
-           CA->getKind() <= CE_END_SIMPLE_CALLS;
-  }
-};
-
-/// \brief Represents a C function or static C++ member function call.
-///
-/// Example: \c fun()
-class FunctionCall : public SimpleCall {
-  friend class CallEventManager;
-
-protected:
-  FunctionCall(const CallExpr *CE, ProgramStateRef St,
-               const LocationContext *LCtx)
-    : SimpleCall(CE, St, LCtx) {}
-
-  FunctionCall(const FunctionCall &Other) : SimpleCall(Other) {}
-  virtual void cloneTo(void *Dest) const { new (Dest) FunctionCall(*this); }
-
-public:
-  virtual Kind getKind() const { return CE_Function; }
+  Kind getKind() const override { return CE_Function; }
 
   static bool classof(const CallEvent *CA) {
     return CA->getKind() == CE_Function;
@@ -483,47 +461,56 @@
 /// \brief Represents a call to a block.
 ///
 /// Example: <tt>^{ /* ... */ }()</tt>
-class BlockCall : public SimpleCall {
+class BlockCall : public CallEvent {
   friend class CallEventManager;
 
 protected:
   BlockCall(const CallExpr *CE, ProgramStateRef St,
             const LocationContext *LCtx)
-    : SimpleCall(CE, St, LCtx) {}
+    : CallEvent(CE, St, LCtx) {}
 
-  BlockCall(const BlockCall &Other) : SimpleCall(Other) {}
-  virtual void cloneTo(void *Dest) const { new (Dest) BlockCall(*this); }
+  BlockCall(const BlockCall &Other) : CallEvent(Other) {}
+  void cloneTo(void *Dest) const override { new (Dest) BlockCall(*this); }
 
-  virtual void getExtraInvalidatedValues(ValueList &Values) const;
+  void getExtraInvalidatedValues(ValueList &Values) const override;
 
 public:
+  virtual const CallExpr *getOriginExpr() const {
+    return cast<CallExpr>(CallEvent::getOriginExpr());
+  }
+
+  unsigned getNumArgs() const override { return getOriginExpr()->getNumArgs(); }
+
+  const Expr *getArgExpr(unsigned Index) const override {
+    return getOriginExpr()->getArg(Index);
+  }
+
   /// \brief Returns the region associated with this instance of the block.
   ///
   /// This may be NULL if the block's origin is unknown.
   const BlockDataRegion *getBlockRegion() const;
 
-  /// \brief Gets the declaration of the block.
-  ///
-  /// This is not an override of getDecl() because AnyFunctionCall has already
-  /// assumed that it's a FunctionDecl.
-  const BlockDecl *getBlockDecl() const {
+  const BlockDecl *getDecl() const override {
     const BlockDataRegion *BR = getBlockRegion();
     if (!BR)
-      return 0;
+      return nullptr;
     return BR->getDecl();
   }
 
-  virtual RuntimeDefinition getRuntimeDefinition() const {
-    return RuntimeDefinition(getBlockDecl());
+  RuntimeDefinition getRuntimeDefinition() const override {
+    return RuntimeDefinition(getDecl());
   }
 
-  virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
-                                            BindingsTy &Bindings) const;
+  bool argumentsMayEscape() const override {
+    return true;
+  }
 
-  virtual param_iterator param_begin() const;
-  virtual param_iterator param_end() const;
+  void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
+                                    BindingsTy &Bindings) const override;
 
-  virtual Kind getKind() const { return CE_Block; }
+  ArrayRef<ParmVarDecl*> parameters() const override;
+
+  Kind getKind() const override { return CE_Block; }
 
   static bool classof(const CallEvent *CA) {
     return CA->getKind() == CE_Block;
@@ -534,7 +521,7 @@
 /// it is written.
 class CXXInstanceCall : public AnyFunctionCall {
 protected:
-  virtual void getExtraInvalidatedValues(ValueList &Values) const;
+  void getExtraInvalidatedValues(ValueList &Values) const override;
 
   CXXInstanceCall(const CallExpr *CE, ProgramStateRef St,
                   const LocationContext *LCtx)
@@ -548,17 +535,17 @@
 
 public:
   /// \brief Returns the expression representing the implicit 'this' object.
-  virtual const Expr *getCXXThisExpr() const { return 0; }
+  virtual const Expr *getCXXThisExpr() const { return nullptr; }
 
   /// \brief Returns the value of the implicit 'this' object.
   virtual SVal getCXXThisVal() const;
 
-  virtual const FunctionDecl *getDecl() const;
+  const FunctionDecl *getDecl() const override;
 
-  virtual RuntimeDefinition getRuntimeDefinition() const;
+  RuntimeDefinition getRuntimeDefinition() const override;
 
-  virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
-                                            BindingsTy &Bindings) const;
+  void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
+                                    BindingsTy &Bindings) const override;
 
   static bool classof(const CallEvent *CA) {
     return CA->getKind() >= CE_BEG_CXX_INSTANCE_CALLS &&
@@ -578,28 +565,28 @@
     : CXXInstanceCall(CE, St, LCtx) {}
 
   CXXMemberCall(const CXXMemberCall &Other) : CXXInstanceCall(Other) {}
-  virtual void cloneTo(void *Dest) const { new (Dest) CXXMemberCall(*this); }
+  void cloneTo(void *Dest) const override { new (Dest) CXXMemberCall(*this); }
 
 public:
   virtual const CXXMemberCallExpr *getOriginExpr() const {
     return cast<CXXMemberCallExpr>(CXXInstanceCall::getOriginExpr());
   }
 
-  virtual unsigned getNumArgs() const {
+  unsigned getNumArgs() const override {
     if (const CallExpr *CE = getOriginExpr())
       return CE->getNumArgs();
     return 0;
   }
 
-  virtual const Expr *getArgExpr(unsigned Index) const {
+  const Expr *getArgExpr(unsigned Index) const override {
     return getOriginExpr()->getArg(Index);
   }
 
-  virtual const Expr *getCXXThisExpr() const;
-  
-  virtual RuntimeDefinition getRuntimeDefinition() const;
+  const Expr *getCXXThisExpr() const override;
 
-  virtual Kind getKind() const { return CE_CXXMember; }
+  RuntimeDefinition getRuntimeDefinition() const override;
+
+  Kind getKind() const override { return CE_CXXMember; }
 
   static bool classof(const CallEvent *CA) {
     return CA->getKind() == CE_CXXMember;
@@ -620,7 +607,7 @@
 
   CXXMemberOperatorCall(const CXXMemberOperatorCall &Other)
     : CXXInstanceCall(Other) {}
-  virtual void cloneTo(void *Dest) const {
+  void cloneTo(void *Dest) const override {
     new (Dest) CXXMemberOperatorCall(*this);
   }
 
@@ -629,16 +616,16 @@
     return cast<CXXOperatorCallExpr>(CXXInstanceCall::getOriginExpr());
   }
 
-  virtual unsigned getNumArgs() const {
+  unsigned getNumArgs() const override {
     return getOriginExpr()->getNumArgs() - 1;
   }
-  virtual const Expr *getArgExpr(unsigned Index) const {
+  const Expr *getArgExpr(unsigned Index) const override {
     return getOriginExpr()->getArg(Index + 1);
   }
 
-  virtual const Expr *getCXXThisExpr() const;
+  const Expr *getCXXThisExpr() const override;
 
-  virtual Kind getKind() const { return CE_CXXMemberOperator; }
+  Kind getKind() const override { return CE_CXXMemberOperator; }
 
   static bool classof(const CallEvent *CA) {
     return CA->getKind() == CE_CXXMemberOperator;
@@ -671,23 +658,23 @@
   }
 
   CXXDestructorCall(const CXXDestructorCall &Other) : CXXInstanceCall(Other) {}
-  virtual void cloneTo(void *Dest) const { new (Dest) CXXDestructorCall(*this); }
+  void cloneTo(void *Dest) const override {new (Dest) CXXDestructorCall(*this);}
 
 public:
-  virtual SourceRange getSourceRange() const { return Location; }
-  virtual unsigned getNumArgs() const { return 0; }
+  SourceRange getSourceRange() const override { return Location; }
+  unsigned getNumArgs() const override { return 0; }
 
-  virtual RuntimeDefinition getRuntimeDefinition() const;
+  RuntimeDefinition getRuntimeDefinition() const override;
 
   /// \brief Returns the value of the implicit 'this' object.
-  virtual SVal getCXXThisVal() const;
+  SVal getCXXThisVal() const override;
 
   /// Returns true if this is a call to a base class destructor.
   bool isBaseDestructor() const {
     return DtorDataTy::getFromOpaqueValue(Data).getInt();
   }
 
-  virtual Kind getKind() const { return CE_CXXDestructor; }
+  Kind getKind() const override { return CE_CXXDestructor; }
 
   static bool classof(const CallEvent *CA) {
     return CA->getKind() == CE_CXXDestructor;
@@ -715,32 +702,32 @@
   }
 
   CXXConstructorCall(const CXXConstructorCall &Other) : AnyFunctionCall(Other){}
-  virtual void cloneTo(void *Dest) const { new (Dest) CXXConstructorCall(*this); }
+  void cloneTo(void *Dest) const override { new (Dest) CXXConstructorCall(*this); }
 
-  virtual void getExtraInvalidatedValues(ValueList &Values) const;
+  void getExtraInvalidatedValues(ValueList &Values) const override;
 
 public:
   virtual const CXXConstructExpr *getOriginExpr() const {
     return cast<CXXConstructExpr>(AnyFunctionCall::getOriginExpr());
   }
 
-  virtual const CXXConstructorDecl *getDecl() const {
+  const CXXConstructorDecl *getDecl() const override {
     return getOriginExpr()->getConstructor();
   }
 
-  virtual unsigned getNumArgs() const { return getOriginExpr()->getNumArgs(); }
+  unsigned getNumArgs() const override { return getOriginExpr()->getNumArgs(); }
 
-  virtual const Expr *getArgExpr(unsigned Index) const {
+  const Expr *getArgExpr(unsigned Index) const override {
     return getOriginExpr()->getArg(Index);
   }
 
   /// \brief Returns the value of the implicit 'this' object.
   SVal getCXXThisVal() const;
 
-  virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
-                                            BindingsTy &Bindings) const;
+  void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
+                                    BindingsTy &Bindings) const override;
 
-  virtual Kind getKind() const { return CE_CXXConstructor; }
+  Kind getKind() const override { return CE_CXXConstructor; }
 
   static bool classof(const CallEvent *CA) {
     return CA->getKind() == CE_CXXConstructor;
@@ -759,29 +746,29 @@
     : AnyFunctionCall(E, St, LCtx) {}
 
   CXXAllocatorCall(const CXXAllocatorCall &Other) : AnyFunctionCall(Other) {}
-  virtual void cloneTo(void *Dest) const { new (Dest) CXXAllocatorCall(*this); }
+  void cloneTo(void *Dest) const override { new (Dest) CXXAllocatorCall(*this); }
 
 public:
   virtual const CXXNewExpr *getOriginExpr() const {
     return cast<CXXNewExpr>(AnyFunctionCall::getOriginExpr());
   }
 
-  virtual const FunctionDecl *getDecl() const {
+  const FunctionDecl *getDecl() const override {
     return getOriginExpr()->getOperatorNew();
   }
 
-  virtual unsigned getNumArgs() const {
+  unsigned getNumArgs() const override {
     return getOriginExpr()->getNumPlacementArgs() + 1;
   }
 
-  virtual const Expr *getArgExpr(unsigned Index) const {
+  const Expr *getArgExpr(unsigned Index) const override {
     // The first argument of an allocator call is the size of the allocation.
     if (Index == 0)
-      return 0;
+      return nullptr;
     return getOriginExpr()->getPlacementArg(Index - 1);
   }
 
-  virtual Kind getKind() const { return CE_CXXAllocator; }
+  Kind getKind() const override { return CE_CXXAllocator; }
 
   static bool classof(const CallEvent *CE) {
     return CE->getKind() == CE_CXXAllocator;
@@ -810,13 +797,13 @@
   ObjCMethodCall(const ObjCMessageExpr *Msg, ProgramStateRef St,
                  const LocationContext *LCtx)
     : CallEvent(Msg, St, LCtx) {
-    Data = 0;
+    Data = nullptr;
   }
 
   ObjCMethodCall(const ObjCMethodCall &Other) : CallEvent(Other) {}
-  virtual void cloneTo(void *Dest) const { new (Dest) ObjCMethodCall(*this); }
+  void cloneTo(void *Dest) const override { new (Dest) ObjCMethodCall(*this); }
 
-  virtual void getExtraInvalidatedValues(ValueList &Values) const;
+  void getExtraInvalidatedValues(ValueList &Values) const override;
 
   /// Check if the selector may have multiple definitions (may have overrides).
   virtual bool canBeOverridenInSubclass(ObjCInterfaceDecl *IDecl,
@@ -826,13 +813,13 @@
   virtual const ObjCMessageExpr *getOriginExpr() const {
     return cast<ObjCMessageExpr>(CallEvent::getOriginExpr());
   }
-  virtual const ObjCMethodDecl *getDecl() const {
+  const ObjCMethodDecl *getDecl() const override {
     return getOriginExpr()->getMethodDecl();
   }
-  virtual unsigned getNumArgs() const {
+  unsigned getNumArgs() const override {
     return getOriginExpr()->getNumArgs();
   }
-  virtual const Expr *getArgExpr(unsigned Index) const {
+  const Expr *getArgExpr(unsigned Index) const override {
     return getOriginExpr()->getArg(Index);
   }
 
@@ -846,7 +833,7 @@
     return getOriginExpr()->getSelector();
   }
 
-  virtual SourceRange getSourceRange() const;
+  SourceRange getSourceRange() const override;
 
   /// \brief Returns the value of the receiver at the time of this call.
   SVal getReceiverSVal() const;
@@ -883,15 +870,16 @@
     llvm_unreachable("Unknown message kind");
   }
 
-  virtual RuntimeDefinition getRuntimeDefinition() const;
+  RuntimeDefinition getRuntimeDefinition() const override;
 
-  virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
-                                            BindingsTy &Bindings) const;
+  bool argumentsMayEscape() const override;
 
-  virtual param_iterator param_begin() const;
-  virtual param_iterator param_end() const;
+  void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
+                                    BindingsTy &Bindings) const override;
 
-  virtual Kind getKind() const { return CE_ObjCMessage; }
+  ArrayRef<ParmVarDecl*> parameters() const override;
+
+  Kind getKind() const override { return CE_ObjCMessage; }
 
   static bool classof(const CallEvent *CA) {
     return CA->getKind() == CE_ObjCMessage;
@@ -911,6 +899,7 @@
 
   llvm::BumpPtrAllocator &Alloc;
   SmallVector<void *, 8> Cache;
+  typedef SimpleFunctionCall CallEventTemplateTy;
 
   void reclaim(const void *Memory) {
     Cache.push_back(const_cast<void *>(Memory));
@@ -919,24 +908,30 @@
   /// Returns memory that can be initialized as a CallEvent.
   void *allocate() {
     if (Cache.empty())
-      return Alloc.Allocate<FunctionCall>();
+      return Alloc.Allocate<CallEventTemplateTy>();
     else
       return Cache.pop_back_val();
   }
 
   template <typename T, typename Arg>
   T *create(Arg A, ProgramStateRef St, const LocationContext *LCtx) {
+    static_assert(sizeof(T) == sizeof(CallEventTemplateTy),
+                  "CallEvent subclasses are not all the same size");
     return new (allocate()) T(A, St, LCtx);
   }
 
   template <typename T, typename Arg1, typename Arg2>
   T *create(Arg1 A1, Arg2 A2, ProgramStateRef St, const LocationContext *LCtx) {
+    static_assert(sizeof(T) == sizeof(CallEventTemplateTy),
+                  "CallEvent subclasses are not all the same size");
     return new (allocate()) T(A1, A2, St, LCtx);
   }
 
   template <typename T, typename Arg1, typename Arg2, typename Arg3>
   T *create(Arg1 A1, Arg2 A2, Arg3 A3, ProgramStateRef St,
             const LocationContext *LCtx) {
+    static_assert(sizeof(T) == sizeof(CallEventTemplateTy),
+                  "CallEvent subclasses are not all the same size");
     return new (allocate()) T(A1, A2, A3, St, LCtx);
   }
 
@@ -944,6 +939,8 @@
             typename Arg4>
   T *create(Arg1 A1, Arg2 A2, Arg3 A3, Arg4 A4, ProgramStateRef St,
             const LocationContext *LCtx) {
+    static_assert(sizeof(T) == sizeof(CallEventTemplateTy),
+                  "CallEvent subclasses are not all the same size");
     return new (allocate()) T(A1, A2, A3, A4, St, LCtx);
   }
 
@@ -989,7 +986,8 @@
 template <typename T>
 CallEventRef<T> CallEvent::cloneWithState(ProgramStateRef NewState) const {
   assert(isa<T>(*this) && "Cloning to unrelated type");
-  assert(sizeof(T) == sizeof(CallEvent) && "Subclasses may not add fields");
+  static_assert(sizeof(T) == sizeof(CallEvent),
+                "Subclasses may not add fields");
 
   if (NewState == State)
     return cast<T>(this);
@@ -1026,7 +1024,7 @@
 
     static SimpleType
     getSimplifiedValue(clang::ento::CallEventRef<T> Val) {
-      return Val.getPtr();
+      return Val.get();
     }
   };
 }
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
index 0b9762a..5a33bdf 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
@@ -174,8 +174,13 @@
     return Pred->getLocationContext()->getAnalysisDeclContext();
   }
 
-  /// \brief If the given node corresponds to a PostStore program point, retrieve
-  /// the location region as it was uttered in the code.
+  /// \brief Get the blockID.
+  unsigned getBlockID() const {
+    return NB.getContext().getBlock()->getBlockID();
+  }
+
+  /// \brief If the given node corresponds to a PostStore program point,
+  /// retrieve the location region as it was uttered in the code.
   ///
   /// This utility can be useful for generating extensive diagnostics, for
   /// example, for finding variables that the given symbol was assigned to.
@@ -183,7 +188,7 @@
     ProgramPoint L = N->getLocation();
     if (Optional<PostStore> PSL = L.getAs<PostStore>())
       return reinterpret_cast<const MemRegion*>(PSL->getLocationValue());
-    return 0;
+    return nullptr;
   }
 
   /// \brief Get the value of arbitrary expressions at this point in the path.
@@ -200,9 +205,9 @@
   ///        tag is specified, a default tag, unique to the given checker,
   ///        will be used. Tags are used to prevent states generated at
   ///        different sites from caching out.
-  ExplodedNode *addTransition(ProgramStateRef State = 0,
-                              const ProgramPointTag *Tag = 0) {
-    return addTransitionImpl(State ? State : getState(), false, 0, Tag);
+  ExplodedNode *addTransition(ProgramStateRef State = nullptr,
+                              const ProgramPointTag *Tag = nullptr) {
+    return addTransitionImpl(State ? State : getState(), false, nullptr, Tag);
   }
 
   /// \brief Generates a new transition with the given predecessor.
@@ -214,15 +219,15 @@
   /// @param Tag The tag to uniquely identify the creation site.
   ExplodedNode *addTransition(ProgramStateRef State,
                               ExplodedNode *Pred,
-                              const ProgramPointTag *Tag = 0) {
+                              const ProgramPointTag *Tag = nullptr) {
     return addTransitionImpl(State, false, Pred, Tag);
   }
 
   /// \brief Generate a sink node. Generating a sink stops exploration of the
   /// given path.
-  ExplodedNode *generateSink(ProgramStateRef State = 0,
-                             ExplodedNode *Pred = 0,
-                             const ProgramPointTag *Tag = 0) {
+  ExplodedNode *generateSink(ProgramStateRef State = nullptr,
+                             ExplodedNode *Pred = nullptr,
+                             const ProgramPointTag *Tag = nullptr) {
     return addTransitionImpl(State ? State : getState(), true, Pred, Tag);
   }
 
@@ -244,7 +249,7 @@
     if (FunDecl)
       return FunDecl->getIdentifier();
     else
-      return 0;
+      return nullptr;
   }
 
   /// \brief Get the name of the called function (path-sensitive).
@@ -280,8 +285,8 @@
 private:
   ExplodedNode *addTransitionImpl(ProgramStateRef State,
                                  bool MarkAsSink,
-                                 ExplodedNode *P = 0,
-                                 const ProgramPointTag *Tag = 0) {
+                                 ExplodedNode *P = nullptr,
+                                 const ProgramPointTag *Tag = nullptr) {
     if (!State || (State == Pred->getState() && !Tag && !MarkAsSink))
       return Pred;
 
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
index 1e76ea6..51bb89b 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
@@ -85,7 +85,7 @@
       // does not. Is there a good equivalent there?
       assert(assume(State, Cond, false) && "System is over constrained.");
 #endif
-      return ProgramStatePair((ProgramStateRef)NULL, State);
+      return ProgramStatePair((ProgramStateRef)nullptr, State);
     }
 
     ProgramStateRef StFalse = assume(State, Cond, false);
@@ -93,7 +93,7 @@
       // We are careful to return the original state, /not/ StTrue,
       // because we want to avoid having callers generate a new node
       // in the ExplodedGraph.
-      return ProgramStatePair(State, (ProgramStateRef)NULL);
+      return ProgramStatePair(State, (ProgramStateRef)nullptr);
     }
 
     return ProgramStatePair(StTrue, StFalse);
@@ -106,7 +106,7 @@
   /// value for a symbol, even if it is perfectly constrained.
   virtual const llvm::APSInt* getSymVal(ProgramStateRef state,
                                         SymbolRef sym) const {
-    return 0;
+    return nullptr;
   }
 
   virtual ProgramStateRef removeDeadBindings(ProgramStateRef state,
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
index a2e211e..76ace6d 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
@@ -21,7 +21,7 @@
 #include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/WorkList.h"
-#include "llvm/ADT/OwningPtr.h"
+#include <memory>
 
 namespace clang {
 
@@ -60,12 +60,12 @@
   SubEngine& SubEng;
 
   /// G - The simulation graph.  Each node is a (location,state) pair.
-  OwningPtr<ExplodedGraph> G;
+  std::unique_ptr<ExplodedGraph> G;
 
   /// WList - A set of queued nodes that need to be processed by the
   ///  worklist algorithm.  It is up to the implementation of WList to decide
   ///  the order that nodes are processed.
-  OwningPtr<WorkList> WList;
+  std::unique_ptr<WorkList> WList;
 
   /// BCounterFactory - A factory object for created BlockCounter objects.
   ///   These are used to record for key nodes in the ExplodedGraph the
@@ -120,7 +120,7 @@
 
   /// takeGraph - Returns the exploded graph.  Ownership of the graph is
   ///  transferred to the caller.
-  ExplodedGraph* takeGraph() { return G.take(); }
+  ExplodedGraph *takeGraph() { return G.release(); }
 
   /// ExecuteWorkList - Run the worklist algorithm for a maximum number of
   ///  steps.  Returns true if there is still simulation state on the worklist.
@@ -312,7 +312,7 @@
 /// \class NodeBuilderWithSinks
 /// \brief This node builder keeps track of the generated sink nodes.
 class NodeBuilderWithSinks: public NodeBuilder {
-  virtual void anchor();
+  void anchor() override;
 protected:
   SmallVector<ExplodedNode*, 2> sinksGenerated;
   ProgramPoint &Location;
@@ -324,13 +324,13 @@
 
   ExplodedNode *generateNode(ProgramStateRef State,
                              ExplodedNode *Pred,
-                             const ProgramPointTag *Tag = 0) {
+                             const ProgramPointTag *Tag = nullptr) {
     const ProgramPoint &LocalLoc = (Tag ? Location.withTag(Tag) : Location);
     return NodeBuilder::generateNode(LocalLoc, State, Pred);
   }
 
   ExplodedNode *generateSink(ProgramStateRef State, ExplodedNode *Pred,
-                             const ProgramPointTag *Tag = 0) {
+                             const ProgramPointTag *Tag = nullptr) {
     const ProgramPoint &LocalLoc = (Tag ? Location.withTag(Tag) : Location);
     ExplodedNode *N = NodeBuilder::generateSink(LocalLoc, State, Pred);
     if (N && N->isSink())
@@ -355,14 +355,16 @@
   /// nodes currently owned by another builder(with larger scope), use
   /// Enclosing builder to transfer ownership.
   StmtNodeBuilder(ExplodedNode *SrcNode, ExplodedNodeSet &DstSet,
-                      const NodeBuilderContext &Ctx, NodeBuilder *Enclosing = 0)
+                  const NodeBuilderContext &Ctx,
+                  NodeBuilder *Enclosing = nullptr)
     : NodeBuilder(SrcNode, DstSet, Ctx), EnclosingBldr(Enclosing) {
     if (EnclosingBldr)
       EnclosingBldr->takeNodes(SrcNode);
   }
 
   StmtNodeBuilder(ExplodedNodeSet &SrcSet, ExplodedNodeSet &DstSet,
-                      const NodeBuilderContext &Ctx, NodeBuilder *Enclosing = 0)
+                  const NodeBuilderContext &Ctx,
+                  NodeBuilder *Enclosing = nullptr)
     : NodeBuilder(SrcSet, DstSet, Ctx), EnclosingBldr(Enclosing) {
     if (EnclosingBldr)
       for (ExplodedNodeSet::iterator I = SrcSet.begin(),
@@ -378,7 +380,7 @@
   ExplodedNode *generateNode(const Stmt *S,
                              ExplodedNode *Pred,
                              ProgramStateRef St,
-                             const ProgramPointTag *tag = 0,
+                             const ProgramPointTag *tag = nullptr,
                              ProgramPoint::Kind K = ProgramPoint::PostStmtKind){
     const ProgramPoint &L = ProgramPoint::getProgramPoint(S, K,
                                   Pred->getLocationContext(), tag);
@@ -388,7 +390,7 @@
   ExplodedNode *generateSink(const Stmt *S,
                              ExplodedNode *Pred,
                              ProgramStateRef St,
-                             const ProgramPointTag *tag = 0,
+                             const ProgramPointTag *tag = nullptr,
                              ProgramPoint::Kind K = ProgramPoint::PostStmtKind){
     const ProgramPoint &L = ProgramPoint::getProgramPoint(S, K,
                                   Pred->getLocationContext(), tag);
@@ -399,7 +401,7 @@
 /// \brief BranchNodeBuilder is responsible for constructing the nodes
 /// corresponding to the two branches of the if statement - true and false.
 class BranchNodeBuilder: public NodeBuilder {
-  virtual void anchor();
+  void anchor() override;
   const CFGBlock *DstT;
   const CFGBlock *DstF;
 
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
index bf17cd8..98092ef 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
@@ -27,11 +27,11 @@
 #include "llvm/ADT/DepthFirstIterator.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/GraphTraits.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/Casting.h"
+#include <memory>
 #include <vector>
 
 namespace clang {
@@ -164,7 +164,7 @@
                       const ProgramStateRef &state,
                       bool IsSink) {
     ID.Add(Loc);
-    ID.AddPointer(state.getPtr());
+    ID.AddPointer(state.get());
     ID.AddBoolean(IsSink);
   }
 
@@ -189,7 +189,7 @@
   }
 
   ExplodedNode *getFirstPred() {
-    return pred_empty() ? NULL : *(pred_begin());
+    return pred_empty() ? nullptr : *(pred_begin());
   }
 
   const ExplodedNode *getFirstPred() const {
@@ -197,7 +197,7 @@
   }
 
   const ExplodedNode *getFirstSucc() const {
-    return succ_empty() ? NULL : *(succ_begin());
+    return succ_empty() ? nullptr : *(succ_begin());
   }
 
   // Iterators over successor and predecessor vertices.
@@ -295,7 +295,7 @@
   ///  the node was freshly created.
   ExplodedNode *getNode(const ProgramPoint &L, ProgramStateRef State,
                         bool IsSink = false,
-                        bool* IsNew = 0);
+                        bool* IsNew = nullptr);
 
   ExplodedGraph* MakeEmptyGraph() const {
     return new ExplodedGraph();
@@ -373,8 +373,8 @@
   ///                        nodes in this graph.
   /// \returns The trimmed graph
   ExplodedGraph *trim(ArrayRef<const NodeTy *> Nodes,
-                      InterExplodedGraphMap *ForwardMap = 0,
-                      InterExplodedGraphMap *InverseMap = 0) const;
+                      InterExplodedGraphMap *ForwardMap = nullptr,
+                      InterExplodedGraphMap *InverseMap = nullptr) const;
 
   /// Enable tracking of recently allocated nodes for potential reclamation
   /// when calling reclaimRecentlyAllocatedNodes().
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
index d89dffe..0fb4a24 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -43,7 +43,6 @@
 
 class AnalysisManager;
 class CallEvent;
-class SimpleCall;
 class CXXConstructorCall;
 
 class ExprEngine : public SubEngine {
@@ -107,7 +106,7 @@
 
   /// Returns true if there is still simulation state on the worklist.
   bool ExecuteWorkList(const LocationContext *L, unsigned Steps = 150000) {
-    return Engine.ExecuteWorkList(L, Steps, 0);
+    return Engine.ExecuteWorkList(L, Steps, nullptr);
   }
 
   /// Execute the work list with an initial state. Nodes that reaches the exit
@@ -123,7 +122,7 @@
   /// getContext - Return the ASTContext associated with this analysis.
   ASTContext &getContext() const { return AMgr.getASTContext(); }
 
-  virtual AnalysisManager &getAnalysisManager() { return AMgr; }
+  AnalysisManager &getAnalysisManager() override { return AMgr; }
 
   CheckerManager &getCheckerManager() const {
     return *AMgr.getCheckerManager();
@@ -155,7 +154,7 @@
 
   /// getInitialState - Return the initial state used for the root vertex
   ///  in the ExplodedGraph.
-  ProgramStateRef getInitialState(const LocationContext *InitLoc);
+  ProgramStateRef getInitialState(const LocationContext *InitLoc) override;
 
   ExplodedGraph& getGraph() { return G; }
   const ExplodedGraph& getGraph() const { return G; }
@@ -187,13 +186,13 @@
   ///        and \p ReferenceStmt must be valid (non-null).
   void removeDead(ExplodedNode *Node, ExplodedNodeSet &Out,
             const Stmt *ReferenceStmt, const LocationContext *LC,
-            const Stmt *DiagnosticStmt = 0,
+            const Stmt *DiagnosticStmt = nullptr,
             ProgramPoint::Kind K = ProgramPoint::PreStmtPurgeDeadSymbolsKind);
 
   /// processCFGElement - Called by CoreEngine. Used to generate new successor
   ///  nodes by processing the 'effects' of a CFG element.
   void processCFGElement(const CFGElement E, ExplodedNode *Pred,
-                         unsigned StmtIdx, NodeBuilderContext *Ctx);
+                         unsigned StmtIdx, NodeBuilderContext *Ctx) override;
 
   void ProcessStmt(const CFGStmt S, ExplodedNode *Pred);
 
@@ -201,7 +200,9 @@
 
   void ProcessImplicitDtor(const CFGImplicitDtor D, ExplodedNode *Pred);
 
-  void ProcessAutomaticObjDtor(const CFGAutomaticObjDtor D, 
+  void ProcessNewAllocator(const CXXNewExpr *NE, ExplodedNode *Pred);
+
+  void ProcessAutomaticObjDtor(const CFGAutomaticObjDtor D,
                                ExplodedNode *Pred, ExplodedNodeSet &Dst);
   void ProcessDeleteDtor(const CFGDeleteDtor D,
                          ExplodedNode *Pred, ExplodedNodeSet &Dst);
@@ -213,10 +214,10 @@
                             ExplodedNode *Pred, ExplodedNodeSet &Dst);
 
   /// Called by CoreEngine when processing the entrance of a CFGBlock.
-  virtual void processCFGBlockEntrance(const BlockEdge &L,
-                                       NodeBuilderWithSinks &nodeBuilder,
-                                       ExplodedNode *Pred);
-  
+  void processCFGBlockEntrance(const BlockEdge &L,
+                               NodeBuilderWithSinks &nodeBuilder,
+                               ExplodedNode *Pred) override;
+ 
   /// ProcessBranch - Called by CoreEngine.  Used to generate successor
   ///  nodes by processing the 'effects' of a branch condition.
   void processBranch(const Stmt *Condition, const Stmt *Term, 
@@ -224,7 +225,7 @@
                      ExplodedNode *Pred,
                      ExplodedNodeSet &Dst,
                      const CFGBlock *DstT,
-                     const CFGBlock *DstF);
+                     const CFGBlock *DstF) override;
 
   /// Called by CoreEngine.  Used to processing branching behavior
   /// at static initalizers.
@@ -233,20 +234,20 @@
                                 ExplodedNode *Pred,
                                 ExplodedNodeSet &Dst,
                                 const CFGBlock *DstT,
-                                const CFGBlock *DstF);
+                                const CFGBlock *DstF) override;
 
   /// processIndirectGoto - Called by CoreEngine.  Used to generate successor
   ///  nodes by processing the 'effects' of a computed goto jump.
-  void processIndirectGoto(IndirectGotoNodeBuilder& builder);
+  void processIndirectGoto(IndirectGotoNodeBuilder& builder) override;
 
   /// ProcessSwitch - Called by CoreEngine.  Used to generate successor
   ///  nodes by processing the 'effects' of a switch statement.
-  void processSwitch(SwitchNodeBuilder& builder);
+  void processSwitch(SwitchNodeBuilder& builder) override;
 
   /// Called by CoreEngine.  Used to generate end-of-path
   /// nodes when the control reaches the end of a function.
   void processEndOfFunction(NodeBuilderContext& BC,
-                            ExplodedNode *Pred);
+                            ExplodedNode *Pred) override;
 
   /// Remove dead bindings/symbols before exiting a function.
   void removeDeadOnEndOfFunction(NodeBuilderContext& BC,
@@ -254,22 +255,23 @@
                                  ExplodedNodeSet &Dst);
 
   /// Generate the entry node of the callee.
-  void processCallEnter(CallEnter CE, ExplodedNode *Pred);
+  void processCallEnter(CallEnter CE, ExplodedNode *Pred) override;
 
   /// Generate the sequence of nodes that simulate the call exit and the post
   /// visit for CallExpr.
-  void processCallExit(ExplodedNode *Pred);
+  void processCallExit(ExplodedNode *Pred) override;
 
   /// Called by CoreEngine when the analysis worklist has terminated.
-  void processEndWorklist(bool hasWorkRemaining);
+  void processEndWorklist(bool hasWorkRemaining) override;
 
   /// evalAssume - Callback function invoked by the ConstraintManager when
   ///  making assumptions about state values.
-  ProgramStateRef processAssume(ProgramStateRef state, SVal cond,bool assumption);
+  ProgramStateRef processAssume(ProgramStateRef state, SVal cond,
+                                bool assumption) override;
 
   /// wantsRegionChangeUpdate - Called by ProgramStateManager to determine if a
   ///  region change should trigger a processRegionChanges update.
-  bool wantsRegionChangeUpdate(ProgramStateRef state);
+  bool wantsRegionChangeUpdate(ProgramStateRef state) override;
 
   /// processRegionChanges - Called by ProgramStateManager whenever a change is made
   ///  to the store. Used to update checkers that track region values.
@@ -278,13 +280,13 @@
                        const InvalidatedSymbols *invalidated,
                        ArrayRef<const MemRegion *> ExplicitRegions,
                        ArrayRef<const MemRegion *> Regions,
-                       const CallEvent *Call);
+                       const CallEvent *Call) override;
 
   /// printState - Called by ProgramStateManager to print checker-specific data.
   void printState(raw_ostream &Out, ProgramStateRef State,
-                  const char *NL, const char *Sep);
+                  const char *NL, const char *Sep) override;
 
-  virtual ProgramStateManager& getStateManager() { return StateMgr; }
+  ProgramStateManager& getStateManager() override { return StateMgr; }
 
   StoreManager& getStoreManager() { return StateMgr.getStoreManager(); }
 
@@ -420,6 +422,10 @@
                           const Stmt *S, bool IsBaseDtor,
                           ExplodedNode *Pred, ExplodedNodeSet &Dst);
 
+  void VisitCXXNewAllocatorCall(const CXXNewExpr *CNE,
+                                ExplodedNode *Pred,
+                                ExplodedNodeSet &Dst);
+
   void VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
                        ExplodedNodeSet &Dst);
 
@@ -471,21 +477,21 @@
   ///  This method is used by evalStore, VisitDeclStmt, and others.
   void evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE, ExplodedNode *Pred,
                 SVal location, SVal Val, bool atDeclInit = false,
-                const ProgramPoint *PP = 0);
+                const ProgramPoint *PP = nullptr);
 
   /// Call PointerEscape callback when a value escapes as a result of bind.
   ProgramStateRef processPointerEscapedOnBind(ProgramStateRef State,
-                                              SVal Loc, SVal Val);
+                                              SVal Loc, SVal Val) override;
   /// Call PointerEscape callback when a value escapes as a result of
   /// region invalidation.
   /// \param[in] ITraits Specifies invalidation traits for regions/symbols.
   ProgramStateRef notifyCheckersOfPointerEscape(
-                            ProgramStateRef State,
-                            const InvalidatedSymbols *Invalidated,
-                            ArrayRef<const MemRegion *> ExplicitRegions,
-                            ArrayRef<const MemRegion *> Regions,
-                            const CallEvent *Call,
-                            RegionAndSymbolInvalidationTraits &ITraits);
+                           ProgramStateRef State,
+                           const InvalidatedSymbols *Invalidated,
+                           ArrayRef<const MemRegion *> ExplicitRegions,
+                           ArrayRef<const MemRegion *> Regions,
+                           const CallEvent *Call,
+                           RegionAndSymbolInvalidationTraits &ITraits) override;
 
 public:
   // FIXME: 'tag' should be removed, and a LocationContext should be used
@@ -500,14 +506,14 @@
                 ExplodedNode *Pred,
                 ProgramStateRef St,
                 SVal location,
-                const ProgramPointTag *tag = 0,
+                const ProgramPointTag *tag = nullptr,
                 QualType LoadTy = QualType());
 
   // FIXME: 'tag' should be removed, and a LocationContext should be used
   // instead.
   void evalStore(ExplodedNodeSet &Dst, const Expr *AssignE, const Expr *StoreE,
                  ExplodedNode *Pred, ProgramStateRef St, SVal TargetLV, SVal Val,
-                 const ProgramPointTag *tag = 0);
+                 const ProgramPointTag *tag = nullptr);
 
   /// \brief Create a new state in which the call return value is binded to the
   /// call origin expression.
@@ -580,7 +586,7 @@
   ProgramStateRef createTemporaryRegionIfNeeded(ProgramStateRef State,
                                                 const LocationContext *LC,
                                                 const Expr *E,
-                                                const Expr *ResultE = 0);
+                                                const Expr *ResultE = nullptr);
 };
 
 /// Traits for storing the call processing policy inside GDM.
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
index a84dcb0..92b082d 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
@@ -23,13 +23,10 @@
 #include "clang/Basic/LLVM.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
 #include "llvm/ADT/FoldingSet.h"
+#include "llvm/Support/Allocator.h"
 #include "llvm/Support/ErrorHandling.h"
 #include <string>
 
-namespace llvm {
-class BumpPtrAllocator;
-}
-
 namespace clang {
 
 class LocationContext;
@@ -57,7 +54,7 @@
   // Visual Studio will only create enumerations of size int, not long long.
   static const int64_t Symbolic = INT64_MAX;
 
-  RegionOffset() : R(0) {}
+  RegionOffset() : R(nullptr) {}
   RegionOffset(const MemRegion *r, int64_t off) : R(r), Offset(off) {}
 
   const MemRegion *getRegion() const { return R; }
@@ -204,12 +201,12 @@
     assert(classof(this));
   }
 
-  MemRegionManager* getMemRegionManager() const { return Mgr; }
+  MemRegionManager* getMemRegionManager() const override { return Mgr; }
 
 public:
-  bool isBoundable() const { return false; }
-  
-  void Profile(llvm::FoldingSetNodeID &ID) const;
+  bool isBoundable() const override { return false; }
+
+  void Profile(llvm::FoldingSetNodeID &ID) const override;
 
   static bool classof(const MemRegion *R) {
     Kind k = R->getKind();
@@ -243,9 +240,9 @@
     : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) {}
 
 public:
-  void Profile(llvm::FoldingSetNodeID &ID) const;
-  
-  void dumpToStream(raw_ostream &os) const;
+  void Profile(llvm::FoldingSetNodeID &ID) const override;
+
+  void dumpToStream(raw_ostream &os) const override;
 
   const CodeTextRegion *getCodeRegion() const { return CR; }
 
@@ -286,7 +283,7 @@
 
 public:
 
-  void dumpToStream(raw_ostream &os) const;
+  void dumpToStream(raw_ostream &os) const override;
 
   static bool classof(const MemRegion *R) {
     return R->getKind() == GlobalSystemSpaceRegionKind;
@@ -306,7 +303,7 @@
 
 public:
 
-  void dumpToStream(raw_ostream &os) const;
+  void dumpToStream(raw_ostream &os) const override;
 
   static bool classof(const MemRegion *R) {
     return R->getKind() == GlobalImmutableSpaceRegionKind;
@@ -324,7 +321,7 @@
 
 public:
 
-  void dumpToStream(raw_ostream &os) const;
+  void dumpToStream(raw_ostream &os) const override;
 
   static bool classof(const MemRegion *R) {
     return R->getKind() == GlobalInternalSpaceRegionKind;
@@ -339,7 +336,7 @@
     : MemSpaceRegion(mgr, HeapSpaceRegionKind) {}
 public:
 
-  void dumpToStream(raw_ostream &os) const;
+  void dumpToStream(raw_ostream &os) const override;
 
   static bool classof(const MemRegion *R) {
     return R->getKind() == HeapSpaceRegionKind;
@@ -353,7 +350,7 @@
     : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {}
 public:
 
-  void dumpToStream(raw_ostream &os) const;
+  void dumpToStream(raw_ostream &os) const override;
 
   static bool classof(const MemRegion *R) {
     return R->getKind() == UnknownSpaceRegionKind;
@@ -373,7 +370,7 @@
 public:  
   const StackFrameContext *getStackFrame() const { return SFC; }
   
-  void Profile(llvm::FoldingSetNodeID &ID) const;
+  void Profile(llvm::FoldingSetNodeID &ID) const override;
 
   static bool classof(const MemRegion *R) {
     Kind k = R->getKind();
@@ -389,7 +386,7 @@
     : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {}
 public:
 
-  void dumpToStream(raw_ostream &os) const;
+  void dumpToStream(raw_ostream &os) const override;
 
   static bool classof(const MemRegion *R) {
     return R->getKind() == StackLocalsSpaceRegionKind;
@@ -404,7 +401,7 @@
     : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {}
 public:
 
-  void dumpToStream(raw_ostream &os) const;
+  void dumpToStream(raw_ostream &os) const override;
 
   static bool classof(const MemRegion *R) {
     return R->getKind() == StackArgumentsSpaceRegionKind;
@@ -430,9 +427,9 @@
     return UnknownVal();
   }
 
-  MemRegionManager* getMemRegionManager() const;
+  MemRegionManager* getMemRegionManager() const override;
 
-  virtual bool isSubRegionOf(const MemRegion* R) const;
+  bool isSubRegionOf(const MemRegion* R) const override;
 
   static bool classof(const MemRegion* R) {
     return R->getKind() > END_MEMSPACES;
@@ -459,16 +456,16 @@
 
   const Expr *getExpr() const { return Ex; }
 
-  bool isBoundable() const { return true; }
+  bool isBoundable() const override { return true; }
 
-  DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
+  DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
 
-  void Profile(llvm::FoldingSetNodeID& ID) const;
+  void Profile(llvm::FoldingSetNodeID& ID) const override;
 
   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr *Ex,
                             unsigned Cnt, const MemRegion *superRegion);
 
-  void dumpToStream(raw_ostream &os) const;
+  void dumpToStream(raw_ostream &os) const override;
 
   static bool classof(const MemRegion* R) {
     return R->getKind() == AllocaRegionKind;
@@ -478,7 +475,7 @@
 /// TypedRegion - An abstract class representing regions that are typed.
 class TypedRegion : public SubRegion {
 public:
-  virtual void anchor();
+  void anchor() override;
 protected:
   TypedRegion(const MemRegion* sReg, Kind k) : SubRegion(sReg, k) {}
 
@@ -489,7 +486,7 @@
     return getLocationType().getDesugaredType(Context);
   }
 
-  bool isBoundable() const { return true; }
+  bool isBoundable() const override { return true; }
 
   static bool classof(const MemRegion* R) {
     unsigned k = R->getKind();
@@ -500,14 +497,14 @@
 /// TypedValueRegion - An abstract class representing regions having a typed value.
 class TypedValueRegion : public TypedRegion {
 public:
-  virtual void anchor();
+  void anchor() override;
 protected:
   TypedValueRegion(const MemRegion* sReg, Kind k) : TypedRegion(sReg, k) {}
 
 public:
   virtual QualType getValueType() const = 0;
 
-  virtual QualType getLocationType() const {
+  QualType getLocationType() const override {
     // FIXME: We can possibly optimize this later to cache this value.
     QualType T = getValueType();
     ASTContext &ctx = getContext();
@@ -521,7 +518,7 @@
     return T.getTypePtrOrNull() ? T.getDesugaredType(Context) : T;
   }
 
-  DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
+  DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
 
   static bool classof(const MemRegion* R) {
     unsigned k = R->getKind();
@@ -532,12 +529,12 @@
 
 class CodeTextRegion : public TypedRegion {
 public:
-  virtual void anchor();
+  void anchor() override;
 protected:
   CodeTextRegion(const MemRegion *sreg, Kind k) : TypedRegion(sreg, k) {}
 public:
-  bool isBoundable() const { return false; }
-    
+  bool isBoundable() const override { return false; }
+
   static bool classof(const MemRegion* R) {
     Kind k = R->getKind();
     return k >= FunctionTextRegionKind && k <= BlockTextRegionKind;
@@ -552,8 +549,8 @@
     : CodeTextRegion(sreg, FunctionTextRegionKind), FD(fd) {
     assert(isa<ObjCMethodDecl>(fd) || isa<FunctionDecl>(fd));
   }
-  
-  QualType getLocationType() const {
+
+  QualType getLocationType() const override {
     const ASTContext &Ctx = getContext();
     if (const FunctionDecl *D = dyn_cast<FunctionDecl>(FD)) {
       return Ctx.getPointerType(D->getType());
@@ -570,11 +567,11 @@
   const NamedDecl *getDecl() const {
     return FD;
   }
-    
-  virtual void dumpToStream(raw_ostream &os) const;
-  
-  void Profile(llvm::FoldingSetNodeID& ID) const;
-  
+
+  void dumpToStream(raw_ostream &os) const override;
+
+  void Profile(llvm::FoldingSetNodeID& ID) const override;
+
   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const NamedDecl *FD,
                             const MemRegion*);
   
@@ -602,7 +599,7 @@
     : CodeTextRegion(sreg, BlockTextRegionKind), BD(bd), AC(ac), locTy(lTy) {}
 
 public:
-  QualType getLocationType() const {
+  QualType getLocationType() const override {
     return locTy;
   }
   
@@ -611,11 +608,11 @@
   }
 
   AnalysisDeclContext *getAnalysisDeclContext() const { return AC; }
-    
-  virtual void dumpToStream(raw_ostream &os) const;
-  
-  void Profile(llvm::FoldingSetNodeID& ID) const;
-  
+
+  virtual void dumpToStream(raw_ostream &os) const override;
+
+  void Profile(llvm::FoldingSetNodeID& ID) const override;
+
   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD,
                             CanQualType, const AnalysisDeclContext*,
                             const MemRegion*);
@@ -635,21 +632,23 @@
   friend class MemRegionManager;
   const BlockTextRegion *BC;
   const LocationContext *LC; // Can be null */
+  unsigned BlockCount;
   void *ReferencedVars;
   void *OriginalVars;
 
   BlockDataRegion(const BlockTextRegion *bc, const LocationContext *lc,
-                  const MemRegion *sreg)
+                  unsigned count, const MemRegion *sreg)
   : TypedRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc),
-    ReferencedVars(0), OriginalVars(0) {}
+     BlockCount(count),
+    ReferencedVars(nullptr), OriginalVars(nullptr) {}
 
 public:
   const BlockTextRegion *getCodeRegion() const { return BC; }
   
   const BlockDecl *getDecl() const { return BC->getDecl(); }
 
-  QualType getLocationType() const { return BC->getLocationType(); }
-  
+  QualType getLocationType() const override { return BC->getLocationType(); }
+
   class referenced_vars_iterator {
     const MemRegion * const *R;
     const MemRegion * const *OriginalR;
@@ -666,11 +665,11 @@
     }
 
     bool operator==(const referenced_vars_iterator &I) const {
-      assert((R == 0) == (I.R == 0));
+      assert((R == nullptr) == (I.R == nullptr));
       return I.R == R;
     }
     bool operator!=(const referenced_vars_iterator &I) const {
-      assert((R == 0) == (I.R == 0));
+      assert((R == nullptr) == (I.R == nullptr));
       return I.R != R;
     }
     referenced_vars_iterator &operator++() {
@@ -686,13 +685,14 @@
       
   referenced_vars_iterator referenced_vars_begin() const;
   referenced_vars_iterator referenced_vars_end() const;  
-    
-  virtual void dumpToStream(raw_ostream &os) const;
-    
-  void Profile(llvm::FoldingSetNodeID& ID) const;
-    
+
+  void dumpToStream(raw_ostream &os) const override;
+
+  void Profile(llvm::FoldingSetNodeID& ID) const override;
+
   static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockTextRegion *,
-                            const LocationContext *, const MemRegion *);
+                            const LocationContext *, unsigned,
+                            const MemRegion *);
     
   static bool classof(const MemRegion* R) {
     return R->getKind() == BlockDataRegionKind;
@@ -720,17 +720,17 @@
     return sym;
   }
 
-  bool isBoundable() const { return true; }
+  bool isBoundable() const override { return true; }
 
-  DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
+  DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
 
-  void Profile(llvm::FoldingSetNodeID& ID) const;
+  void Profile(llvm::FoldingSetNodeID& ID) const override;
 
   static void ProfileRegion(llvm::FoldingSetNodeID& ID,
                             SymbolRef sym,
                             const MemRegion* superRegion);
 
-  void dumpToStream(raw_ostream &os) const;
+  void dumpToStream(raw_ostream &os) const override;
 
   static bool classof(const MemRegion* R) {
     return R->getKind() == SymbolicRegionKind;
@@ -754,19 +754,19 @@
 
   const StringLiteral* getStringLiteral() const { return Str; }
 
-  QualType getValueType() const {
+  QualType getValueType() const override {
     return Str->getType();
   }
 
-  DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
+  DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
 
-  bool isBoundable() const { return false; }
+  bool isBoundable() const override { return false; }
 
-  void Profile(llvm::FoldingSetNodeID& ID) const {
+  void Profile(llvm::FoldingSetNodeID& ID) const override {
     ProfileRegion(ID, Str, superRegion);
   }
 
-  void dumpToStream(raw_ostream &os) const;
+  void dumpToStream(raw_ostream &os) const override;
 
   static bool classof(const MemRegion* R) {
     return R->getKind() == StringRegionKind;
@@ -789,19 +789,19 @@
 public:
   
   const ObjCStringLiteral* getObjCStringLiteral() const { return Str; }
-  
-  QualType getValueType() const {
+
+  QualType getValueType() const override {
     return Str->getType();
   }
-  
-  bool isBoundable() const { return false; }
-  
-  void Profile(llvm::FoldingSetNodeID& ID) const {
+
+  bool isBoundable() const override { return false; }
+
+  void Profile(llvm::FoldingSetNodeID& ID) const override {
     ProfileRegion(ID, Str, superRegion);
   }
-  
-  void dumpToStream(raw_ostream &os) const;
-  
+
+  void dumpToStream(raw_ostream &os) const override;
+
   static bool classof(const MemRegion* R) {
     return R->getKind() == ObjCStringRegionKind;
   }
@@ -822,15 +822,15 @@
                             const CompoundLiteralExpr *CL,
                             const MemRegion* superRegion);
 public:
-  QualType getValueType() const {
+  QualType getValueType() const override {
     return CL->getType();
   }
 
-  bool isBoundable() const { return !CL->isFileScope(); }
+  bool isBoundable() const override { return !CL->isFileScope(); }
 
-  void Profile(llvm::FoldingSetNodeID& ID) const;
+  void Profile(llvm::FoldingSetNodeID& ID) const override;
 
-  void dumpToStream(raw_ostream &os) const;
+  void dumpToStream(raw_ostream &os) const override;
 
   const CompoundLiteralExpr *getLiteralExpr() const { return CL; }
 
@@ -851,7 +851,7 @@
 
 public:
   const Decl *getDecl() const { return D; }
-  void Profile(llvm::FoldingSetNodeID& ID) const;
+  void Profile(llvm::FoldingSetNodeID& ID) const override;
 
   static bool classof(const MemRegion* R) {
     unsigned k = R->getKind();
@@ -871,27 +871,27 @@
     DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind);
   }
 
-  void Profile(llvm::FoldingSetNodeID& ID) const;
+  void Profile(llvm::FoldingSetNodeID& ID) const override;
 
 public:
   const VarDecl *getDecl() const { return cast<VarDecl>(D); }
 
   const StackFrameContext *getStackFrame() const;
-  
-  QualType getValueType() const {
+
+  QualType getValueType() const override {
     // FIXME: We can cache this if needed.
     return getDecl()->getType();
   }
 
-  void dumpToStream(raw_ostream &os) const;
+  void dumpToStream(raw_ostream &os) const override;
 
   static bool classof(const MemRegion* R) {
     return R->getKind() == VarRegionKind;
   }
 
-  bool canPrintPrettyAsExpr() const;
+  bool canPrintPrettyAsExpr() const override;
 
-  void printPrettyAsExpr(raw_ostream &os) const;
+  void printPrettyAsExpr(raw_ostream &os) const override;
 };
   
 /// CXXThisRegion - Represents the region for the implicit 'this' parameter
@@ -907,15 +907,15 @@
                             const PointerType *PT,
                             const MemRegion *sReg);
 
-  void Profile(llvm::FoldingSetNodeID &ID) const;
+  void Profile(llvm::FoldingSetNodeID &ID) const override;
 
-public:  
-  QualType getValueType() const {
+public:
+  QualType getValueType() const override {
     return QualType(ThisPointerTy, 0);
   }
 
-  void dumpToStream(raw_ostream &os) const;
-  
+  void dumpToStream(raw_ostream &os) const override;
+
   static bool classof(const MemRegion* R) {
     return R->getKind() == CXXThisRegionKind;
   }
@@ -933,12 +933,12 @@
 public:
   const FieldDecl *getDecl() const { return cast<FieldDecl>(D); }
 
-  QualType getValueType() const {
+  QualType getValueType() const override {
     // FIXME: We can cache this if needed.
     return getDecl()->getType();
   }
 
-  DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
+  DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
 
   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl *FD,
                             const MemRegion* superRegion) {
@@ -949,12 +949,12 @@
     return R->getKind() == FieldRegionKind;
   }
 
-  void dumpToStream(raw_ostream &os) const;
+  void dumpToStream(raw_ostream &os) const override;
 
-  bool canPrintPretty() const;
-  void printPretty(raw_ostream &os) const;
-  bool canPrintPrettyAsExpr() const;
-  void printPrettyAsExpr(raw_ostream &os) const;
+  bool canPrintPretty() const override;
+  void printPretty(raw_ostream &os) const override;
+  bool canPrintPrettyAsExpr() const override;
+  void printPrettyAsExpr(raw_ostream &os) const override;
 };
 
 class ObjCIvarRegion : public DeclRegion {
@@ -968,12 +968,12 @@
 
 public:
   const ObjCIvarDecl *getDecl() const;
-  QualType getValueType() const;
+  QualType getValueType() const override;
 
-  bool canPrintPrettyAsExpr() const;
-  void printPrettyAsExpr(raw_ostream &os) const;
+  bool canPrintPrettyAsExpr() const override;
+  void printPrettyAsExpr(raw_ostream &os) const override;
 
-  void dumpToStream(raw_ostream &os) const;
+  void dumpToStream(raw_ostream &os) const override;
 
   static bool classof(const MemRegion* R) {
     return R->getKind() == ObjCIvarRegionKind;
@@ -1026,7 +1026,7 @@
 
   NonLoc getIndex() const { return Index; }
 
-  QualType getValueType() const {
+  QualType getValueType() const override {
     return ElementType;
   }
 
@@ -1036,9 +1036,9 @@
   /// Compute the offset within the array. The array might also be a subobject.
   RegionRawOffset getAsArrayOffset() const;
 
-  void dumpToStream(raw_ostream &os) const;
+  void dumpToStream(raw_ostream &os) const override;
 
-  void Profile(llvm::FoldingSetNodeID& ID) const;
+  void Profile(llvm::FoldingSetNodeID& ID) const override;
 
   static bool classof(const MemRegion* R) {
     return R->getKind() == ElementRegionKind;
@@ -1060,13 +1060,13 @@
 public:
   const Expr *getExpr() const { return Ex; }
 
-  QualType getValueType() const {
+  QualType getValueType() const override {
     return Ex->getType();
   }
 
-  void dumpToStream(raw_ostream &os) const;
+  void dumpToStream(raw_ostream &os) const override;
 
-  void Profile(llvm::FoldingSetNodeID &ID) const;
+  void Profile(llvm::FoldingSetNodeID &ID) const override;
 
   static bool classof(const MemRegion* R) {
     return R->getKind() == CXXTempObjectRegionKind;
@@ -1091,19 +1091,19 @@
   const CXXRecordDecl *getDecl() const { return Data.getPointer(); }
   bool isVirtual() const { return Data.getInt(); }
 
-  QualType getValueType() const;
+  QualType getValueType() const override;
 
-  void dumpToStream(raw_ostream &os) const;
+  void dumpToStream(raw_ostream &os) const override;
 
-  void Profile(llvm::FoldingSetNodeID &ID) const;
+  void Profile(llvm::FoldingSetNodeID &ID) const override;
 
   static bool classof(const MemRegion *region) {
     return region->getKind() == CXXBaseObjectRegionKind;
   }
 
-  bool canPrintPrettyAsExpr() const;
-  
-  void printPrettyAsExpr(raw_ostream &os) const;
+  bool canPrintPrettyAsExpr() const override;
+
+  void printPrettyAsExpr(raw_ostream &os) const override;
 };
 
 template<typename RegionTy>
@@ -1111,7 +1111,7 @@
   if (const RegionTy* RT = dyn_cast<RegionTy>(this))
     return RT;
 
-  return NULL;
+  return nullptr;
 }
 
 //===----------------------------------------------------------------------===//
@@ -1140,9 +1140,10 @@
   MemSpaceRegion *code;
 
 public:
-  MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator& a)
-    : C(c), A(a), InternalGlobals(0), SystemGlobals(0), ImmutableGlobals(0),
-      heap(0), unknown(0), code(0) {}
+  MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator &a)
+    : C(c), A(a), InternalGlobals(nullptr), SystemGlobals(nullptr),
+      ImmutableGlobals(nullptr), heap(nullptr), unknown(nullptr),
+      code(nullptr) {}
 
   ~MemRegionManager();
 
@@ -1164,7 +1165,7 @@
   ///  global variables.
   const GlobalsSpaceRegion *getGlobalsRegion(
       MemRegion::Kind K = MemRegion::GlobalInternalSpaceRegionKind,
-      const CodeTextRegion *R = 0);
+      const CodeTextRegion *R = nullptr);
 
   /// getHeapRegion - Retrieve the memory region associated with the
   ///  generic "heap".
@@ -1270,7 +1271,8 @@
   ///  argument is allowed to be NULL for cases where we have no known
   ///  context.
   const BlockDataRegion *getBlockDataRegion(const BlockTextRegion *bc,
-                                            const LocationContext *lc = NULL);
+                                            const LocationContext *lc,
+                                            unsigned blockCount);
 
   /// Create a CXXTempObjectRegion for temporaries which are lifetime-extended
   /// by static references. This differs from getCXXTempObjectRegion in the
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
index 03739ed..4902ef5 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
@@ -25,10 +25,10 @@
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/ImmutableMap.h"
 #include "llvm/ADT/PointerIntPair.h"
+#include "llvm/Support/Allocator.h"
 
 namespace llvm {
 class APSInt;
-class BumpPtrAllocator;
 }
 
 namespace clang {
@@ -237,16 +237,16 @@
   ProgramStateRef
   invalidateRegions(ArrayRef<const MemRegion *> Regions, const Expr *E,
                     unsigned BlockCount, const LocationContext *LCtx,
-                    bool CausesPointerEscape, InvalidatedSymbols *IS = 0,
-                    const CallEvent *Call = 0,
-                    RegionAndSymbolInvalidationTraits *ITraits = 0) const;
+                    bool CausesPointerEscape, InvalidatedSymbols *IS = nullptr,
+                    const CallEvent *Call = nullptr,
+                    RegionAndSymbolInvalidationTraits *ITraits = nullptr) const;
 
   ProgramStateRef
   invalidateRegions(ArrayRef<SVal> Regions, const Expr *E,
                     unsigned BlockCount, const LocationContext *LCtx,
-                    bool CausesPointerEscape, InvalidatedSymbols *IS = 0,
-                    const CallEvent *Call = 0,
-                    RegionAndSymbolInvalidationTraits *ITraits = 0) const;
+                    bool CausesPointerEscape, InvalidatedSymbols *IS = nullptr,
+                    const CallEvent *Call = nullptr,
+                    RegionAndSymbolInvalidationTraits *ITraits = nullptr) const;
 
   /// enterStackFrame - Returns the state for entry to the given stack frame,
   ///  preserving the current state.
@@ -441,8 +441,8 @@
   SubEngine *Eng; /* Can be null. */
 
   EnvironmentManager                   EnvMgr;
-  OwningPtr<StoreManager>              StoreMgr;
-  OwningPtr<ConstraintManager>         ConstraintMgr;
+  std::unique_ptr<StoreManager>        StoreMgr;
+  std::unique_ptr<ConstraintManager>   ConstraintMgr;
 
   ProgramState::GenericDataMap::Factory     GDMFactory;
 
@@ -454,10 +454,10 @@
   llvm::FoldingSet<ProgramState> StateSet;
 
   /// Object that manages the data for all created SVals.
-  OwningPtr<SValBuilder> svalBuilder;
+  std::unique_ptr<SValBuilder> svalBuilder;
 
   /// Manages memory for created CallEvents.
-  OwningPtr<CallEventManager> CallEventMgr;
+  std::unique_ptr<CallEventManager> CallEventMgr;
 
   /// A BumpPtrAllocator to allocate states.
   llvm::BumpPtrAllocator &Alloc;
@@ -676,10 +676,8 @@
 inline SVal ProgramState::getLValue(const IndirectFieldDecl *D,
                                     SVal Base) const {
   StoreManager &SM = *getStateManager().StoreMgr;
-  for (IndirectFieldDecl::chain_iterator I = D->chain_begin(),
-                                         E = D->chain_end();
-       I != E; ++I) {
-    Base = SM.getLValueField(cast<FieldDecl>(*I), Base);
+  for (const auto *I : D->chain()) {
+    Base = SM.getLValueField(cast<FieldDecl>(I), Base);
   }
 
   return Base;
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h
index eb52ae4..823bde7 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h
@@ -18,10 +18,10 @@
 #ifndef LLVM_CLANG_GR_PROGRAMSTATETRAIT_H
 #define LLVM_CLANG_GR_PROGRAMSTATETRAIT_H
 
+#include "llvm/Support/Allocator.h"
 #include "llvm/Support/DataTypes.h"
 
 namespace llvm {
-  class BumpPtrAllocator;
   template <typename K, typename D, typename I> class ImmutableMap;
   template <typename K, typename I> class ImmutableSet;
   template <typename T> class ImmutableList;
@@ -64,7 +64,8 @@
     typedef const value_type*                 lookup_type;
 
     static inline data_type MakeData(void *const* p) {
-      return p ? data_type((typename data_type::TreeTy*) *p) : data_type(0);
+      return p ? data_type((typename data_type::TreeTy*) *p)
+               : data_type(nullptr);
     }
     static inline void *MakeVoidPtr(data_type B) {
       return B.getRoot();
@@ -112,7 +113,8 @@
     typedef Key                               key_type;
 
     static inline data_type MakeData(void *const* p) {
-      return p ? data_type((typename data_type::TreeTy*) *p) : data_type(0);
+      return p ? data_type((typename data_type::TreeTy*) *p)
+               : data_type(nullptr);
     }
 
     static inline void *MakeVoidPtr(data_type B) {
@@ -163,7 +165,7 @@
 
     static inline data_type MakeData(void *const* p) {
       return p ? data_type((const llvm::ImmutableListImpl<T>*) *p)
-               : data_type(0);
+               : data_type(nullptr);
     }
 
     static inline void *MakeVoidPtr(data_type D) {
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
index bbb5688..29fb413 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
@@ -88,7 +88,7 @@
 
   virtual SVal evalComplement(NonLoc val) = 0;
 
-  /// Create a new value which represents a binary expression with two non
+  /// Create a new value which represents a binary expression with two non-
   /// location operands.
   virtual SVal evalBinOpNN(ProgramStateRef state, BinaryOperator::Opcode op,
                            NonLoc lhs, NonLoc rhs, QualType resultTy) = 0;
@@ -99,7 +99,7 @@
                            Loc lhs, Loc rhs, QualType resultTy) = 0;
 
   /// Create a new value which represents a binary expression with a memory
-  /// location and non location operands. For example, this would be used to
+  /// location and non-location operands. For example, this would be used to
   /// evaluate a pointer arithmetic operation.
   virtual SVal evalBinOpLN(ProgramStateRef state, BinaryOperator::Opcode op,
                            Loc lhs, NonLoc rhs, QualType resultTy) = 0;
@@ -146,14 +146,14 @@
                                       const LocationContext *LCtx,
                                       QualType type,
                                       unsigned visitCount,
-                                      const void *symbolTag = 0) {
+                                      const void *symbolTag = nullptr) {
     return SymMgr.conjureSymbol(stmt, LCtx, type, visitCount, symbolTag);
   }
 
   const SymbolConjured* conjureSymbol(const Expr *expr,
                                       const LocationContext *LCtx,
                                       unsigned visitCount,
-                                      const void *symbolTag = 0) {
+                                      const void *symbolTag = nullptr) {
     return SymMgr.conjureSymbol(expr, LCtx, visitCount, symbolTag);
   }
 
@@ -200,7 +200,8 @@
   DefinedSVal getFunctionPointer(const FunctionDecl *func);
   
   DefinedSVal getBlockPointer(const BlockDecl *block, CanQualType locTy,
-                              const LocationContext *locContext);
+                              const LocationContext *locContext,
+                              unsigned blockCount);
 
   /// Returns the value of \p E, if it can be determined in a non-path-sensitive
   /// manner.
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
index 5a426ef..d50c3be 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
@@ -63,11 +63,11 @@
   explicit SVal(const void *d, bool isLoc, unsigned ValKind)
   : Data(d), Kind((isLoc ? LocKind : NonLocKind) | (ValKind << BaseBits)) {}
 
-  explicit SVal(BaseKind k, const void *D = NULL)
+  explicit SVal(BaseKind k, const void *D = nullptr)
     : Data(D), Kind(k) {}
 
 public:
-  explicit SVal() : Data(0), Kind(0) {}
+  explicit SVal() : Data(nullptr), Kind(0) {}
 
   /// \brief Convert to the specified SVal type, asserting that this SVal is of
   /// the desired type.
@@ -211,7 +211,7 @@
   explicit DefinedOrUnknownSVal(const void *d, bool isLoc, unsigned ValKind)
     : SVal(d, isLoc, ValKind) {}
   
-  explicit DefinedOrUnknownSVal(BaseKind k, void *D = NULL)
+  explicit DefinedOrUnknownSVal(BaseKind k, void *D = nullptr)
     : SVal(k, D) {}
   
 private:
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
index 530dae5..84c3166 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
@@ -220,10 +220,11 @@
     bool First;
 
   public:
-    FindUniqueBinding(SymbolRef sym) : Sym(sym), Binding(0), First(true) {}
+    FindUniqueBinding(SymbolRef sym)
+      : Sym(sym), Binding(nullptr), First(true) {}
 
     bool HandleBinding(StoreManager& SMgr, Store store, const MemRegion* R,
-                       SVal val);
+                       SVal val) override;
     LLVM_EXPLICIT operator bool() { return First && Binding; }
     const MemRegion *getRegion() { return Binding; }
   };
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
index f653c70..3482e8d 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
@@ -122,7 +122,7 @@
   inline ProgramStateRef 
   processRegionChange(ProgramStateRef state,
                       const MemRegion* MR) {
-    return processRegionChanges(state, 0, MR, MR, 0);
+    return processRegionChanges(state, nullptr, MR, MR, nullptr);
   }
 
   virtual ProgramStateRef
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
index 914b2be..2b5cc18 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
@@ -23,12 +23,9 @@
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/FoldingSet.h"
+#include "llvm/Support/Allocator.h"
 #include "llvm/Support/DataTypes.h"
 
-namespace llvm {
-class BumpPtrAllocator;
-}
-
 namespace clang {
   class ASTContext;
   class StackFrameContext;
@@ -105,7 +102,7 @@
 /// \brief A symbol representing data which can be stored in a memory location
 /// (region).
 class SymbolData : public SymExpr {
-  virtual void anchor();
+  void anchor() override;
   const SymbolID Sym;
 
 protected:
@@ -138,13 +135,13 @@
     profile.AddPointer(R);
   }
 
-  virtual void Profile(llvm::FoldingSetNodeID& profile) {
+  void Profile(llvm::FoldingSetNodeID& profile) override {
     Profile(profile, R);
   }
 
-  virtual void dumpToStream(raw_ostream &os) const;
+  void dumpToStream(raw_ostream &os) const override;
 
-  QualType getType() const;
+  QualType getType() const override;
 
   // Implement isa<T> support.
   static inline bool classof(const SymExpr *SE) {
@@ -173,9 +170,9 @@
   unsigned getCount() const { return Count; }
   const void *getTag() const { return SymbolTag; }
 
-  QualType getType() const;
+  QualType getType() const override;
 
-  virtual void dumpToStream(raw_ostream &os) const;
+  void dumpToStream(raw_ostream &os) const override;
 
   static void Profile(llvm::FoldingSetNodeID& profile, const Stmt *S,
                       QualType T, unsigned Count, const LocationContext *LCtx,
@@ -188,7 +185,7 @@
     profile.AddPointer(SymbolTag);
   }
 
-  virtual void Profile(llvm::FoldingSetNodeID& profile) {
+  void Profile(llvm::FoldingSetNodeID& profile) override {
     Profile(profile, S, T, Count, LCtx, SymbolTag);
   }
 
@@ -211,9 +208,9 @@
   SymbolRef getParentSymbol() const { return parentSymbol; }
   const TypedValueRegion *getRegion() const { return R; }
 
-  QualType getType() const;
+  QualType getType() const override;
 
-  virtual void dumpToStream(raw_ostream &os) const;
+  void dumpToStream(raw_ostream &os) const override;
 
   static void Profile(llvm::FoldingSetNodeID& profile, SymbolRef parent,
                       const TypedValueRegion *r) {
@@ -222,7 +219,7 @@
     profile.AddPointer(parent);
   }
 
-  virtual void Profile(llvm::FoldingSetNodeID& profile) {
+  void Profile(llvm::FoldingSetNodeID& profile) override {
     Profile(profile, parentSymbol, R);
   }
 
@@ -244,16 +241,16 @@
 
   const SubRegion *getRegion() const { return R; }
 
-  QualType getType() const;
+  QualType getType() const override;
 
-  virtual void dumpToStream(raw_ostream &os) const;
+  void dumpToStream(raw_ostream &os) const override;
 
   static void Profile(llvm::FoldingSetNodeID& profile, const SubRegion *R) {
     profile.AddInteger((unsigned) ExtentKind);
     profile.AddPointer(R);
   }
 
-  virtual void Profile(llvm::FoldingSetNodeID& profile) {
+  void Profile(llvm::FoldingSetNodeID& profile) override {
     Profile(profile, R);
   }
 
@@ -283,9 +280,9 @@
   unsigned getCount() const { return Count; }
   const void *getTag() const { return Tag; }
 
-  QualType getType() const;
+  QualType getType() const override;
 
-  virtual void dumpToStream(raw_ostream &os) const;
+  void dumpToStream(raw_ostream &os) const override;
 
   static void Profile(llvm::FoldingSetNodeID& profile, const MemRegion *R,
                       const Stmt *S, QualType T, unsigned Count,
@@ -298,7 +295,7 @@
     profile.AddPointer(Tag);
   }
 
-  virtual void Profile(llvm::FoldingSetNodeID& profile) {
+  void Profile(llvm::FoldingSetNodeID& profile) override {
     Profile(profile, R, S, T, Count, Tag);
   }
 
@@ -320,11 +317,11 @@
   SymbolCast(const SymExpr *In, QualType From, QualType To) :
     SymExpr(CastSymbolKind), Operand(In), FromTy(From), ToTy(To) { }
 
-  QualType getType() const { return ToTy; }
+  QualType getType() const override { return ToTy; }
 
   const SymExpr *getOperand() const { return Operand; }
 
-  virtual void dumpToStream(raw_ostream &os) const;
+  void dumpToStream(raw_ostream &os) const override;
 
   static void Profile(llvm::FoldingSetNodeID& ID,
                       const SymExpr *In, QualType From, QualType To) {
@@ -334,7 +331,7 @@
     ID.Add(To);
   }
 
-  void Profile(llvm::FoldingSetNodeID& ID) {
+  void Profile(llvm::FoldingSetNodeID& ID) override {
     Profile(ID, Operand, FromTy, ToTy);
   }
 
@@ -356,7 +353,7 @@
 public:
   // FIXME: We probably need to make this out-of-line to avoid redundant
   // generation of virtual functions.
-  QualType getType() const { return T; }
+  QualType getType() const override { return T; }
 
   BinaryOperator::Opcode getOpcode() const { return Op; }
 
@@ -377,7 +374,7 @@
              const llvm::APSInt& rhs, QualType t)
     : BinarySymExpr(SymIntKind, op, t), LHS(lhs), RHS(rhs) {}
 
-  virtual void dumpToStream(raw_ostream &os) const;
+  void dumpToStream(raw_ostream &os) const override;
 
   const SymExpr *getLHS() const { return LHS; }
   const llvm::APSInt &getRHS() const { return RHS; }
@@ -392,7 +389,7 @@
     ID.Add(t);
   }
 
-  void Profile(llvm::FoldingSetNodeID& ID) {
+  void Profile(llvm::FoldingSetNodeID& ID) override {
     Profile(ID, LHS, getOpcode(), RHS, getType());
   }
 
@@ -412,7 +409,7 @@
              const SymExpr *rhs, QualType t)
     : BinarySymExpr(IntSymKind, op, t), LHS(lhs), RHS(rhs) {}
 
-  virtual void dumpToStream(raw_ostream &os) const;
+  void dumpToStream(raw_ostream &os) const override;
 
   const SymExpr *getRHS() const { return RHS; }
   const llvm::APSInt &getLHS() const { return LHS; }
@@ -427,7 +424,7 @@
     ID.Add(t);
   }
 
-  void Profile(llvm::FoldingSetNodeID& ID) {
+  void Profile(llvm::FoldingSetNodeID& ID) override {
     Profile(ID, LHS, getOpcode(), RHS, getType());
   }
 
@@ -450,7 +447,7 @@
   const SymExpr *getLHS() const { return LHS; }
   const SymExpr *getRHS() const { return RHS; }
 
-  virtual void dumpToStream(raw_ostream &os) const;
+  void dumpToStream(raw_ostream &os) const override;
 
   static void Profile(llvm::FoldingSetNodeID& ID, const SymExpr *lhs,
                     BinaryOperator::Opcode op, const SymExpr *rhs, QualType t) {
@@ -461,7 +458,7 @@
     ID.Add(t);
   }
 
-  void Profile(llvm::FoldingSetNodeID& ID) {
+  void Profile(llvm::FoldingSetNodeID& ID) override {
     Profile(ID, LHS, getOpcode(), RHS, getType());
   }
 
@@ -501,12 +498,12 @@
                                       const LocationContext *LCtx,
                                       QualType T,
                                       unsigned VisitCount,
-                                      const void *SymbolTag = 0);
+                                      const void *SymbolTag = nullptr);
 
   const SymbolConjured* conjureSymbol(const Expr *E,
                                       const LocationContext *LCtx,
                                       unsigned VisitCount,
-                                      const void *SymbolTag = 0) {
+                                      const void *SymbolTag = nullptr) {
     return conjureSymbol(E, LCtx, E->getType(), VisitCount, SymbolTag);
   }
 
@@ -519,9 +516,9 @@
   ///
   /// VisitCount can be used to differentiate regions corresponding to
   /// different loop iterations, thus, making the symbol path-dependent.
-  const SymbolMetadata* getMetadataSymbol(const MemRegion* R, const Stmt *S,
+  const SymbolMetadata *getMetadataSymbol(const MemRegion *R, const Stmt *S,
                                           QualType T, unsigned VisitCount,
-                                          const void *SymbolTag = 0);
+                                          const void *SymbolTag = nullptr);
 
   const SymbolCast* getCastSymbol(const SymExpr *Operand,
                                   QualType From, QualType To);
@@ -590,7 +587,7 @@
   SymbolReaper(const StackFrameContext *Ctx, const Stmt *s, SymbolManager& symmgr,
                StoreManager &storeMgr)
    : LCtx(Ctx), Loc(s), SymMgr(symmgr),
-     reapedStore(0, storeMgr) {}
+     reapedStore(nullptr, storeMgr) {}
 
   ~SymbolReaper() {}
 
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h b/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h
index d12a151..3ed145d 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h
@@ -42,7 +42,7 @@
   explicit WorkListUnit(ExplodedNode *N, BlockCounter C)
   : node(N),
     counter(C),
-    block(NULL),
+    block(nullptr),
     blockIdx(0) {}
 
   /// Returns the node associated with the worklist unit.
diff --git a/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h b/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h
new file mode 100644
index 0000000..30e5d3d
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h
@@ -0,0 +1,49 @@
+//===--- AnalysisConsumer.h - Front-end Analysis Engine Hooks ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header contains the functions necessary for a front-end to run various
+// analyses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_GR_ANALYSISCONSUMER_H
+#define LLVM_CLANG_GR_ANALYSISCONSUMER_H
+
+#include "clang/AST/ASTConsumer.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
+#include <string>
+
+namespace clang {
+
+class Preprocessor;
+class DiagnosticsEngine;
+
+namespace ento {
+class CheckerManager;
+
+class AnalysisASTConsumer : public ASTConsumer {
+public:
+  virtual void AddDiagnosticConsumer(PathDiagnosticConsumer *Consumer) = 0;
+};
+
+/// CreateAnalysisConsumer - Creates an ASTConsumer to run various code
+/// analysis passes.  (The set of analyses run is controlled by command-line
+/// options.)
+AnalysisASTConsumer *CreateAnalysisConsumer(const Preprocessor &pp,
+                                            const std::string &output,
+                                            AnalyzerOptionsRef opts,
+                                            ArrayRef<std::string> plugins);
+
+} // end GR namespace
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Frontend/FrontendActions.h b/include/clang/StaticAnalyzer/Frontend/FrontendActions.h
index 838ac92..21ecfc2 100644
--- a/include/clang/StaticAnalyzer/Frontend/FrontendActions.h
+++ b/include/clang/StaticAnalyzer/Frontend/FrontendActions.h
@@ -22,8 +22,8 @@
 
 class AnalysisAction : public ASTFrontendAction {
 protected:
-  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
-                                         StringRef InFile);
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
 };
 
 void printCheckerHelp(raw_ostream &OS, ArrayRef<std::string> plugins);
diff --git a/include/clang/Tooling/ArgumentsAdjusters.h b/include/clang/Tooling/ArgumentsAdjusters.h
index 71acef8..765e7d2 100644
--- a/include/clang/Tooling/ArgumentsAdjusters.h
+++ b/include/clang/Tooling/ArgumentsAdjusters.h
@@ -49,13 +49,13 @@
 /// This class implements ArgumentsAdjuster interface and converts input
 /// command line arguments to the "syntax check only" variant.
 class ClangSyntaxOnlyAdjuster : public ArgumentsAdjuster {
-  virtual CommandLineArguments Adjust(const CommandLineArguments &Args);
+  CommandLineArguments Adjust(const CommandLineArguments &Args) override;
 };
 
 /// \brief An argument adjuster which removes output-related command line
 /// arguments.
 class ClangStripOutputAdjuster : public ArgumentsAdjuster {
-  virtual CommandLineArguments Adjust(const CommandLineArguments &Args);
+  CommandLineArguments Adjust(const CommandLineArguments &Args) override;
 };
 
 } // end namespace tooling
diff --git a/include/clang/Tooling/CommonOptionsParser.h b/include/clang/Tooling/CommonOptionsParser.h
index eaffe43..815ede8 100644
--- a/include/clang/Tooling/CommonOptionsParser.h
+++ b/include/clang/Tooling/CommonOptionsParser.h
@@ -28,6 +28,7 @@
 #define LLVM_TOOLS_CLANG_INCLUDE_CLANG_TOOLING_COMMONOPTIONSPARSER_H
 
 #include "clang/Tooling/CompilationDatabase.h"
+#include "llvm/Support/CommandLine.h"
 
 namespace clang {
 namespace tooling {
@@ -46,13 +47,14 @@
 /// using namespace clang::tooling;
 /// using namespace llvm;
 ///
+/// static cl::OptionCategory MyToolCategory("My tool options");
 /// static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
 /// static cl::extrahelp MoreHelp("\nMore help text...");
-/// static cl:opt<bool> YourOwnOption(...);
+/// static cl::opt<bool> YourOwnOption(...);
 /// ...
 ///
 /// int main(int argc, const char **argv) {
-///   CommonOptionsParser OptionsParser(argc, argv);
+///   CommonOptionsParser OptionsParser(argc, argv, MyToolCategory);
 ///   ClangTool Tool(OptionsParser.getCompilations(),
 ///                  OptionsParser.getSourcePathListi());
 ///   return Tool.run(newFrontendActionFactory<clang::SyntaxOnlyAction>());
@@ -61,10 +63,16 @@
 class CommonOptionsParser {
 public:
   /// \brief Parses command-line, initializes a compilation database.
+  ///
   /// This constructor can change argc and argv contents, e.g. consume
   /// command-line options used for creating FixedCompilationDatabase.
+  ///
+  /// All options not belonging to \p Category become hidden.
+  ///
   /// This constructor exits program in case of error.
-  CommonOptionsParser(int &argc, const char **argv, const char *Overview = 0);
+  CommonOptionsParser(int &argc, const char **argv,
+                      llvm::cl::OptionCategory &Category,
+                      const char *Overview = nullptr);
 
   /// Returns a reference to the loaded compilations database.
   CompilationDatabase &getCompilations() {
@@ -79,7 +87,7 @@
   static const char *const HelpMessage;
 
 private:
-  OwningPtr<CompilationDatabase> Compilations;
+  std::unique_ptr<CompilationDatabase> Compilations;
   std::vector<std::string> SourcePathList;
 };
 
diff --git a/include/clang/Tooling/CompilationDatabase.h b/include/clang/Tooling/CompilationDatabase.h
index 8cca329..d1e729a 100644
--- a/include/clang/Tooling/CompilationDatabase.h
+++ b/include/clang/Tooling/CompilationDatabase.h
@@ -30,9 +30,9 @@
 
 #include "clang/Basic/LLVM.h"
 #include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/Twine.h"
+#include <memory>
 #include <string>
 #include <vector>
 
@@ -42,8 +42,8 @@
 /// \brief Specifies the working directory and command of a compilation.
 struct CompileCommand {
   CompileCommand() {}
-  CompileCommand(Twine Directory, ArrayRef<std::string> CommandLine)
-    : Directory(Directory.str()), CommandLine(CommandLine) {}
+  CompileCommand(Twine Directory, std::vector<std::string> CommandLine)
+      : Directory(Directory.str()), CommandLine(std::move(CommandLine)) {}
 
   /// \brief The working directory the command was executed from.
   std::string Directory;
@@ -166,7 +166,7 @@
   /// The argument list is meant to be compatible with normal llvm command line
   /// parsing in main methods.
   /// int main(int argc, char **argv) {
-  ///   OwningPtr<FixedCompilationDatabase> Compilations(
+  ///   std::unique_ptr<FixedCompilationDatabase> Compilations(
   ///     FixedCompilationDatabase::loadFromCommandLine(argc, argv));
   ///   cl::ParseCommandLineOptions(argc, argv);
   ///   ...
@@ -190,19 +190,19 @@
   /// Will always return a vector with one entry that contains the directory
   /// and command line specified at construction with "clang-tool" as argv[0]
   /// and 'FilePath' as positional argument.
-  virtual std::vector<CompileCommand> getCompileCommands(
-    StringRef FilePath) const;
+  std::vector<CompileCommand>
+  getCompileCommands(StringRef FilePath) const override;
 
   /// \brief Returns the list of all files available in the compilation database.
   ///
   /// Note: This is always an empty list for the fixed compilation database.
-  virtual std::vector<std::string> getAllFiles() const;
+  std::vector<std::string> getAllFiles() const override;
 
   /// \brief Returns all compile commands for all the files in the compilation
   /// database.
   ///
   /// Note: This is always an empty list for the fixed compilation database.
-  virtual std::vector<CompileCommand> getAllCompileCommands() const;
+  std::vector<CompileCommand> getAllCompileCommands() const override;
 
 private:
   /// This is built up to contain a single entry vector to be returned from
diff --git a/include/clang/Tooling/FileMatchTrie.h b/include/clang/Tooling/FileMatchTrie.h
index e531854..be37baf 100644
--- a/include/clang/Tooling/FileMatchTrie.h
+++ b/include/clang/Tooling/FileMatchTrie.h
@@ -16,8 +16,8 @@
 #define LLVM_CLANG_TOOLING_FILE_MATCH_TRIE_H
 
 #include "clang/Basic/LLVM.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/StringRef.h"
+#include <memory>
 #include <string>
 #include <vector>
 
@@ -79,7 +79,7 @@
                            raw_ostream &Error) const;
 private:
   FileMatchTrieNode *Root;
-  OwningPtr<PathComparator> Comparator;
+  std::unique_ptr<PathComparator> Comparator;
 };
 
 
diff --git a/include/clang/Tooling/JSONCompilationDatabase.h b/include/clang/Tooling/JSONCompilationDatabase.h
index e3f149b..1b33359 100644
--- a/include/clang/Tooling/JSONCompilationDatabase.h
+++ b/include/clang/Tooling/JSONCompilationDatabase.h
@@ -18,12 +18,12 @@
 #include "clang/Basic/LLVM.h"
 #include "clang/Tooling/CompilationDatabase.h"
 #include "clang/Tooling/FileMatchTrie.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/SourceMgr.h"
 #include "llvm/Support/YAMLParser.h"
+#include <memory>
 #include <string>
 #include <vector>
 
@@ -67,17 +67,17 @@
   ///
   /// FIXME: Currently FilePath must be an absolute path inside the
   /// source directory which does not have symlinks resolved.
-  virtual std::vector<CompileCommand> getCompileCommands(
-    StringRef FilePath) const;
+  std::vector<CompileCommand>
+  getCompileCommands(StringRef FilePath) const override;
 
   /// \brief Returns the list of all files available in the compilation database.
   ///
   /// These are the 'file' entries of the JSON objects.
-  virtual std::vector<std::string> getAllFiles() const;
+  std::vector<std::string> getAllFiles() const override;
 
   /// \brief Returns all compile commands for all the files in the compilation
   /// database.
-  virtual std::vector<CompileCommand> getAllCompileCommands() const;
+  std::vector<CompileCommand> getAllCompileCommands() const override;
 
 private:
   /// \brief Constructs a JSON compilation database on a memory buffer.
@@ -104,7 +104,7 @@
 
   FileMatchTrie MatchTrie;
 
-  OwningPtr<llvm::MemoryBuffer> Database;
+  std::unique_ptr<llvm::MemoryBuffer> Database;
   llvm::SourceMgr SM;
   llvm::yaml::Stream YAMLStream;
 };
diff --git a/include/clang/Tooling/Refactoring.h b/include/clang/Tooling/Refactoring.h
index 43ec9ac..cd2fb9f 100644
--- a/include/clang/Tooling/Refactoring.h
+++ b/include/clang/Tooling/Refactoring.h
@@ -83,16 +83,16 @@
 
   /// \brief Creates a Replacement of the range [Start, Start+Length) with
   /// ReplacementText.
-  Replacement(SourceManager &Sources, SourceLocation Start, unsigned Length,
+  Replacement(const SourceManager &Sources, SourceLocation Start, unsigned Length,
               StringRef ReplacementText);
 
   /// \brief Creates a Replacement of the given range with ReplacementText.
-  Replacement(SourceManager &Sources, const CharSourceRange &Range,
+  Replacement(const SourceManager &Sources, const CharSourceRange &Range,
               StringRef ReplacementText);
 
   /// \brief Creates a Replacement of the node with ReplacementText.
   template <typename Node>
-  Replacement(SourceManager &Sources, const Node &NodeToReplace,
+  Replacement(const SourceManager &Sources, const Node &NodeToReplace,
               StringRef ReplacementText);
 
   /// \brief Returns whether this replacement can be applied to a file.
@@ -115,9 +115,10 @@
   std::string toString() const;
 
  private:
-  void setFromSourceLocation(SourceManager &Sources, SourceLocation Start,
+  void setFromSourceLocation(const SourceManager &Sources, SourceLocation Start,
                              unsigned Length, StringRef ReplacementText);
-  void setFromSourceRange(SourceManager &Sources, const CharSourceRange &Range,
+  void setFromSourceRange(const SourceManager &Sources,
+                          const CharSourceRange &Range,
                           StringRef ReplacementText);
 
   std::string FilePath;
@@ -230,8 +231,8 @@
 };
 
 template <typename Node>
-Replacement::Replacement(SourceManager &Sources, const Node &NodeToReplace,
-                         StringRef ReplacementText) {
+Replacement::Replacement(const SourceManager &Sources,
+                         const Node &NodeToReplace, StringRef ReplacementText) {
   const CharSourceRange Range =
       CharSourceRange::getTokenRange(NodeToReplace->getSourceRange());
   setFromSourceRange(Sources, Range, ReplacementText);
diff --git a/include/clang/Tooling/RefactoringCallbacks.h b/include/clang/Tooling/RefactoringCallbacks.h
index c500f35..19f2774 100644
--- a/include/clang/Tooling/RefactoringCallbacks.h
+++ b/include/clang/Tooling/RefactoringCallbacks.h
@@ -52,7 +52,7 @@
 class ReplaceStmtWithText : public RefactoringCallback {
 public:
   ReplaceStmtWithText(StringRef FromId, StringRef ToText);
-  virtual void run(const ast_matchers::MatchFinder::MatchResult &Result);
+  void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
 
 private:
   std::string FromId;
@@ -64,7 +64,7 @@
 class ReplaceStmtWithStmt : public RefactoringCallback {
 public:
   ReplaceStmtWithStmt(StringRef FromId, StringRef ToId);
-  virtual void run(const ast_matchers::MatchFinder::MatchResult &Result);
+  void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
 
 private:
   std::string FromId;
@@ -77,7 +77,7 @@
 class ReplaceIfStmtWithItsBody : public RefactoringCallback {
 public:
   ReplaceIfStmtWithItsBody(StringRef Id, bool PickTrueBranch);
-  virtual void run(const ast_matchers::MatchFinder::MatchResult &Result);
+  void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
 
 private:
   std::string Id;
diff --git a/include/clang/Tooling/ReplacementsYaml.h b/include/clang/Tooling/ReplacementsYaml.h
index 18d3259..ac9f469 100644
--- a/include/clang/Tooling/ReplacementsYaml.h
+++ b/include/clang/Tooling/ReplacementsYaml.h
@@ -18,26 +18,14 @@
 
 #include "clang/Tooling/Refactoring.h"
 #include "llvm/Support/YAMLTraits.h"
-#include <vector>
 #include <string>
+#include <vector>
 
 LLVM_YAML_IS_SEQUENCE_VECTOR(clang::tooling::Replacement)
 
 namespace llvm {
 namespace yaml {
 
-/// \brief ScalarTraits to read/write std::string objects.
-template <> struct ScalarTraits<std::string> {
-  static void output(const std::string &Val, void *, llvm::raw_ostream &Out) {
-    Out << Val;
-  }
-
-  static StringRef input(StringRef Scalar, void *, std::string &Val) {
-    Val = Scalar;
-    return StringRef();
-  }
-};
-
 /// \brief Specialized MappingTraits to describe how a Replacement is
 /// (de)serialized.
 template <> struct MappingTraits<clang::tooling::Replacement> {
diff --git a/include/clang/Tooling/Tooling.h b/include/clang/Tooling/Tooling.h
index de507a7..769acd3 100644
--- a/include/clang/Tooling/Tooling.h
+++ b/include/clang/Tooling/Tooling.h
@@ -39,6 +39,7 @@
 #include "clang/Tooling/CompilationDatabase.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/Twine.h"
+#include <memory>
 #include <string>
 #include <vector>
 
@@ -80,7 +81,7 @@
 
   /// \brief Invokes the compiler with a FrontendAction created by create().
   bool runInvocation(clang::CompilerInvocation *Invocation, FileManager *Files,
-                     DiagnosticConsumer *DiagConsumer);
+                     DiagnosticConsumer *DiagConsumer) override;
 
   /// \brief Returns a new clang::FrontendAction.
   ///
@@ -96,7 +97,7 @@
 /// FrontendActionFactory *Factory =
 ///   newFrontendActionFactory<clang::SyntaxOnlyAction>();
 template <typename T>
-FrontendActionFactory *newFrontendActionFactory();
+std::unique_ptr<FrontendActionFactory> newFrontendActionFactory();
 
 /// \brief Callbacks called before and after each source file processed by a
 /// FrontendAction created by the FrontedActionFactory returned by \c
@@ -125,11 +126,11 @@
 /// struct ProvidesASTConsumers {
 ///   clang::ASTConsumer *newASTConsumer();
 /// } Factory;
-/// FrontendActionFactory *FactoryAdapter =
-///   newFrontendActionFactory(&Factory);
+/// std::unique_ptr<FrontendActionFactory> FactoryAdapter(
+///   newFrontendActionFactory(&Factory));
 template <typename FactoryT>
-inline FrontendActionFactory *newFrontendActionFactory(
-    FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks = NULL);
+inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory(
+    FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks = nullptr);
 
 /// \brief Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag.
 ///
@@ -160,8 +161,8 @@
 /// \param FileName The file name which 'Code' will be mapped as.
 ///
 /// \return The resulting AST or null if an error occurred.
-ASTUnit *buildASTFromCode(const Twine &Code,
-                          const Twine &FileName = "input.cc");
+std::unique_ptr<ASTUnit> buildASTFromCode(const Twine &Code,
+                                          const Twine &FileName = "input.cc");
 
 /// \brief Builds an AST for 'Code' with additional flags.
 ///
@@ -170,9 +171,10 @@
 /// \param FileName The file name which 'Code' will be mapped as.
 ///
 /// \return The resulting AST or null if an error occurred.
-ASTUnit *buildASTFromCodeWithArgs(const Twine &Code,
-                                  const std::vector<std::string> &Args,
-                                  const Twine &FileName = "input.cc");
+std::unique_ptr<ASTUnit>
+buildASTFromCodeWithArgs(const Twine &Code,
+                         const std::vector<std::string> &Args,
+                         const Twine &FileName = "input.cc");
 
 /// \brief Utility to run a FrontendAction in a single clang invocation.
 class ToolInvocation {
@@ -186,7 +188,7 @@
   /// \param FAction The action to be executed. Class takes ownership.
   /// \param Files The FileManager used for the execution. Class does not take
   /// ownership.
-  ToolInvocation(ArrayRef<std::string> CommandLine, FrontendAction *FAction,
+  ToolInvocation(std::vector<std::string> CommandLine, FrontendAction *FAction,
                  FileManager *Files);
 
   /// \brief Create a tool invocation.
@@ -194,7 +196,7 @@
   /// \param CommandLine The command line arguments to clang.
   /// \param Action The action to be executed.
   /// \param Files The FileManager used for the execution.
-  ToolInvocation(ArrayRef<std::string> CommandLine, ToolAction *Action,
+  ToolInvocation(std::vector<std::string> CommandLine, ToolAction *Action,
                  FileManager *Files);
 
   ~ToolInvocation();
@@ -282,7 +284,7 @@
 
   /// \brief Create an AST for each file specified in the command line and
   /// append them to ASTs.
-  int buildASTs(std::vector<ASTUnit *> &ASTs);
+  int buildASTs(std::vector<std::unique_ptr<ASTUnit>> &ASTs);
 
   /// \brief Returns the file manager used in the tool.
   ///
@@ -303,17 +305,18 @@
 };
 
 template <typename T>
-FrontendActionFactory *newFrontendActionFactory() {
+std::unique_ptr<FrontendActionFactory> newFrontendActionFactory() {
   class SimpleFrontendActionFactory : public FrontendActionFactory {
   public:
-    virtual clang::FrontendAction *create() { return new T; }
+    clang::FrontendAction *create() override { return new T; }
   };
 
-  return new SimpleFrontendActionFactory;
+  return std::unique_ptr<FrontendActionFactory>(
+      new SimpleFrontendActionFactory);
 }
 
 template <typename FactoryT>
-inline FrontendActionFactory *newFrontendActionFactory(
+inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory(
     FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks) {
   class FrontendActionFactoryAdapter : public FrontendActionFactory {
   public:
@@ -321,7 +324,7 @@
                                           SourceFileCallbacks *Callbacks)
       : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
 
-    virtual clang::FrontendAction *create() {
+    clang::FrontendAction *create() override {
       return new ConsumerFactoryAdaptor(ConsumerFactory, Callbacks);
     }
 
@@ -333,21 +336,21 @@
         : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
 
       clang::ASTConsumer *CreateASTConsumer(clang::CompilerInstance &,
-                                            StringRef) {
+                                            StringRef) override {
         return ConsumerFactory->newASTConsumer();
       }
 
     protected:
-      virtual bool BeginSourceFileAction(CompilerInstance &CI,
-                                         StringRef Filename) LLVM_OVERRIDE {
+      bool BeginSourceFileAction(CompilerInstance &CI,
+                                 StringRef Filename) override {
         if (!clang::ASTFrontendAction::BeginSourceFileAction(CI, Filename))
           return false;
-        if (Callbacks != NULL)
+        if (Callbacks)
           return Callbacks->handleBeginSource(CI, Filename);
         return true;
       }
-      virtual void EndSourceFileAction() LLVM_OVERRIDE {
-        if (Callbacks != NULL)
+      void EndSourceFileAction() override {
+        if (Callbacks)
           Callbacks->handleEndSource();
         clang::ASTFrontendAction::EndSourceFileAction();
       }
@@ -360,7 +363,8 @@
     SourceFileCallbacks *Callbacks;
   };
 
-  return new FrontendActionFactoryAdapter(ConsumerFactory, Callbacks);
+  return std::unique_ptr<FrontendActionFactory>(
+      new FrontendActionFactoryAdapter(ConsumerFactory, Callbacks));
 }
 
 /// \brief Returns the absolute path of \c File, by prepending it with
diff --git a/include/clang/module.modulemap b/include/clang/module.modulemap
new file mode 100644
index 0000000..0380601
--- /dev/null
+++ b/include/clang/module.modulemap
@@ -0,0 +1,110 @@
+module Clang_Analysis {
+  requires cplusplus
+  umbrella "Analysis"
+
+  // This file is intended for repeated textual inclusion.
+  exclude header "Analysis/Analyses/ThreadSafetyOps.def"
+
+  module * { export * }
+}
+
+module Clang_AST {
+  requires cplusplus
+  umbrella "AST"
+
+  // These files are intended for repeated textual inclusion.
+  exclude header "AST/BuiltinTypes.def"
+  exclude header "AST/TypeLocNodes.def"
+  exclude header "AST/TypeNodes.def"
+
+  module * { export * }
+}
+
+module Clang_ASTMatchers { requires cplusplus umbrella "ASTMatchers" module * { export * } }
+
+module Clang_Basic {
+  requires cplusplus
+  umbrella "Basic"
+
+  // These files are intended for repeated textual inclusion.
+  exclude header "Basic/BuiltinsAArch64.def"
+  exclude header "Basic/BuiltinsARM64.def"
+  exclude header "Basic/BuiltinsARM.def"
+  exclude header "Basic/Builtins.def"
+  exclude header "Basic/BuiltinsHexagon.def"
+  exclude header "Basic/BuiltinsMips.def"
+  exclude header "Basic/BuiltinsNEON.def"
+  exclude header "Basic/BuiltinsNVPTX.def"
+  exclude header "Basic/BuiltinsPPC.def"
+  exclude header "Basic/BuiltinsR600.def"
+  exclude header "Basic/BuiltinsX86.def"
+  exclude header "Basic/BuiltinsXCore.def"
+  exclude header "Basic/DiagnosticOptions.def"
+  exclude header "Basic/LangOptions.def"
+  exclude header "Basic/OpenCLExtensions.def"
+  exclude header "Basic/OpenMPKinds.def"
+  exclude header "Basic/OperatorKinds.def"
+  exclude header "Basic/Sanitizers.def"
+  exclude header "Basic/TokenKinds.def"
+
+  // This file is one big layering violation.
+  exclude header "Basic/AllDiagnostics.h"
+
+  // This file includes a header from Lex.
+  exclude header "Basic/PlistSupport.h"
+
+  // FIXME: This is logically a part of Basic, but has been put in the wrong place.
+  header "StaticAnalyzer/Core/AnalyzerOptions.h"
+
+  module * { export * }
+}
+
+module Clang_CodeGen { requires cplusplus umbrella "CodeGen" module * { export * } }
+module Clang_Config { requires cplusplus umbrella "Config" module * { export * } }
+
+module Clang_Driver {
+  requires cplusplus
+  umbrella "Driver"
+
+  // This file is intended for repeated textual inclusion.
+  exclude header "Driver/Types.def"
+
+  module * { export * }
+}
+
+module Clang_Edit { requires cplusplus umbrella "Edit" module * { export * } }
+module Clang_Format { requires cplusplus umbrella "Format" module * { export * } }
+
+module Clang_Frontend {
+  requires cplusplus
+  umbrella "Frontend"
+
+  // These files are intended for repeated textual inclusion.
+  exclude header "Frontend/CodeGenOptions.def"
+  exclude header "Frontend/LangStandards.def"
+
+  module * { export * }
+}
+
+module Clang_FrontendTool { requires cplusplus umbrella "FrontendTool" module * { export * } }
+module Clang_Index { requires cplusplus umbrella "Index" module * { export * } }
+module Clang_Lex { requires cplusplus umbrella "Lex" module * { export * } }
+module Clang_Parse { requires cplusplus umbrella "Parse" module * { export * } }
+module Clang_Rewrite { requires cplusplus umbrella "Rewrite" module * { export * } }
+module Clang_Sema { requires cplusplus umbrella "Sema" module * { export * } }
+module Clang_Serialization { requires cplusplus umbrella "Serialization" module * { export * } }
+
+module Clang_StaticAnalyzer {
+  requires cplusplus
+  umbrella "StaticAnalyzer"
+
+  // This file is intended for repeated textual inclusion.
+  exclude header "StaticAnalyzer/Core/Analyses.def"
+
+  // FIXME: This is logically a part of Basic, but has been put in the wrong place.
+  exclude header "StaticAnalyzer/Core/AnalyzerOptions.h"
+
+  module * { export * }
+}
+
+module Clang_Tooling { requires cplusplus umbrella "Tooling" module * { export * } }
diff --git a/lib/ARCMigrate/ARCMT.cpp b/lib/ARCMigrate/ARCMT.cpp
index 3e429be..8a13b2e 100644
--- a/lib/ARCMigrate/ARCMT.cpp
+++ b/lib/ARCMigrate/ARCMT.cpp
@@ -103,8 +103,8 @@
     : Diags(diags), DiagClient(client), CapturedDiags(capturedDiags),
       HasBegunSourceFile(false) { }
 
-  virtual void BeginSourceFile(const LangOptions &Opts,
-                               const Preprocessor *PP) {
+  void BeginSourceFile(const LangOptions &Opts,
+                       const Preprocessor *PP) override {
     // Pass BeginSourceFile message onto DiagClient on first call.
     // The corresponding EndSourceFile call will be made from an
     // explicit call to FinishCapture.
@@ -128,8 +128,8 @@
     assert(!HasBegunSourceFile && "FinishCapture not called!");
   }
 
-  virtual void HandleDiagnostic(DiagnosticsEngine::Level level,
-                                const Diagnostic &Info) {
+  void HandleDiagnostic(DiagnosticsEngine::Level level,
+                        const Diagnostic &Info) override {
     if (DiagnosticIDs::isARCDiagnostic(Info.getID()) ||
         level >= DiagnosticsEngine::Error || level == DiagnosticsEngine::Note) {
       if (Info.getLocation().isValid())
@@ -167,7 +167,7 @@
 
 static CompilerInvocation *
 createInvocationForMigration(CompilerInvocation &origCI) {
-  OwningPtr<CompilerInvocation> CInvok;
+  std::unique_ptr<CompilerInvocation> CInvok;
   CInvok.reset(new CompilerInvocation(origCI));
   PreprocessorOptions &PPOpts = CInvok->getPreprocessorOpts();
   if (!PPOpts.ImplicitPCHInclude.empty()) {
@@ -204,11 +204,11 @@
       WarnOpts.push_back(*I);
   }
   WarnOpts.push_back("error=arc-unsafe-retained-assign");
-  CInvok->getDiagnosticOpts().Warnings = llvm_move(WarnOpts);
+  CInvok->getDiagnosticOpts().Warnings = std::move(WarnOpts);
 
   CInvok->getLangOpts()->ObjCARCWeak = HasARCRuntime(origCI);
 
-  return CInvok.take();
+  return CInvok.release();
 }
 
 static void emitPremigrationErrors(const CapturedDiagList &arcDiags,
@@ -246,7 +246,7 @@
                                                                      NoFinalizeRemoval);
   assert(!transforms.empty());
 
-  OwningPtr<CompilerInvocation> CInvok;
+  std::unique_ptr<CompilerInvocation> CInvok;
   CInvok.reset(createInvocationForMigration(origCI));
   CInvok->getFrontendOpts().Inputs.clear();
   CInvok->getFrontendOpts().Inputs.push_back(Input);
@@ -263,8 +263,8 @@
   CaptureDiagnosticConsumer errRec(*Diags, *DiagClient, capturedDiags);
   Diags->setClient(&errRec, /*ShouldOwnClient=*/false);
 
-  OwningPtr<ASTUnit> Unit(
-      ASTUnit::LoadFromCompilerInvocationAction(CInvok.take(), Diags));
+  std::unique_ptr<ASTUnit> Unit(
+      ASTUnit::LoadFromCompilerInvocationAction(CInvok.release(), Diags));
   if (!Unit) {
     errRec.FinishCapture();
     return true;
@@ -310,8 +310,10 @@
   TransformActions testAct(*Diags, capturedDiags, Ctx, Unit->getPreprocessor());
   MigrationPass pass(Ctx, OrigGCMode, Unit->getSema(), testAct, capturedDiags,
                      ARCMTMacroLocs);
-  pass.setNSAllocReallocError(NoNSAllocReallocError);
   pass.setNoFinalizeRemoval(NoFinalizeRemoval);
+  if (!NoNSAllocReallocError)
+    Diags->setSeverity(diag::warn_arcmt_nsalloc_realloc, diag::Severity::Error,
+                       SourceLocation());
 
   for (unsigned i=0, e = transforms.size(); i != e; ++i)
     transforms[i](pass);
@@ -416,44 +418,6 @@
   return false;
 }
 
-bool arcmt::getFileRemappingsFromFileList(
-                        std::vector<std::pair<std::string,std::string> > &remap,
-                        ArrayRef<StringRef> remapFiles,
-                        DiagnosticConsumer *DiagClient) {
-  bool hasErrorOccurred = false;
-  llvm::StringMap<bool> Uniquer;
-
-  IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
-  IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
-      new DiagnosticsEngine(DiagID, new DiagnosticOptions,
-                            DiagClient, /*ShouldOwnClient=*/false));
-
-  for (ArrayRef<StringRef>::iterator
-         I = remapFiles.begin(), E = remapFiles.end(); I != E; ++I) {
-    StringRef file = *I;
-
-    FileRemapper remapper;
-    bool err = remapper.initFromFile(file, *Diags,
-                                     /*ignoreIfFilesChanged=*/true);
-    hasErrorOccurred = hasErrorOccurred || err;
-    if (err)
-      continue;
-
-    PreprocessorOptions PPOpts;
-    remapper.applyMappings(PPOpts);
-    for (PreprocessorOptions::remapped_file_iterator
-           RI = PPOpts.remapped_file_begin(), RE = PPOpts.remapped_file_end();
-           RI != RE; ++RI) {
-      bool &inserted = Uniquer[RI->first];
-      if (inserted)
-        continue;
-      inserted = true;
-      remap.push_back(*RI);
-    }
-  }
-
-  return hasErrorOccurred;
-}
 
 //===----------------------------------------------------------------------===//
 // CollectTransformActions.
@@ -468,8 +432,8 @@
   ARCMTMacroTrackerPPCallbacks(std::vector<SourceLocation> &ARCMTMacroLocs)
     : ARCMTMacroLocs(ARCMTMacroLocs) { }
 
-  virtual void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD,
-                            SourceRange Range, const MacroArgs *Args) {
+  void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD,
+                    SourceRange Range, const MacroArgs *Args) override {
     if (MacroNameTok.getIdentifierInfo()->getName() == getARCMTMacroName())
       ARCMTMacroLocs.push_back(MacroNameTok.getLocation());
   }
@@ -482,8 +446,8 @@
   ARCMTMacroTrackerAction(std::vector<SourceLocation> &ARCMTMacroLocs)
     : ARCMTMacroLocs(ARCMTMacroLocs) { }
 
-  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
-                                         StringRef InFile) {
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override {
     CI.getPreprocessor().addPPCallbacks(
                               new ARCMTMacroTrackerPPCallbacks(ARCMTMacroLocs));
     return new ASTConsumer();
@@ -506,14 +470,14 @@
       Listener->finish();
   }
 
-  virtual void insert(SourceLocation loc, StringRef text) {
+  void insert(SourceLocation loc, StringRef text) override {
     bool err = rewriter.InsertText(loc, text, /*InsertAfter=*/true,
                                    /*indentNewLines=*/true);
     if (!err && Listener)
       Listener->insert(loc, text);
   }
 
-  virtual void remove(CharSourceRange range) {
+  void remove(CharSourceRange range) override {
     Rewriter::RewriteOptions removeOpts;
     removeOpts.IncludeInsertsAtBeginOfRange = false;
     removeOpts.IncludeInsertsAtEndOfRange = false;
@@ -524,8 +488,8 @@
       Listener->remove(range);
   }
 
-  virtual void increaseIndentation(CharSourceRange range,
-                                    SourceLocation parentIndent) {
+  void increaseIndentation(CharSourceRange range,
+                            SourceLocation parentIndent) override {
     rewriter.IncreaseIndentation(range, parentIndent);
   }
 };
@@ -550,7 +514,7 @@
 
 bool MigrationProcess::applyTransform(TransformFn trans,
                                       RewriteListener *listener) {
-  OwningPtr<CompilerInvocation> CInvok;
+  std::unique_ptr<CompilerInvocation> CInvok;
   CInvok.reset(createInvocationForMigration(OrigCI));
   CInvok->getDiagnosticOpts().IgnoreWarnings = true;
 
@@ -569,12 +533,11 @@
   CaptureDiagnosticConsumer errRec(*Diags, *DiagClient, capturedDiags);
   Diags->setClient(&errRec, /*ShouldOwnClient=*/false);
 
-  OwningPtr<ARCMTMacroTrackerAction> ASTAction;
+  std::unique_ptr<ARCMTMacroTrackerAction> ASTAction;
   ASTAction.reset(new ARCMTMacroTrackerAction(ARCMTMacroLocs));
 
-  OwningPtr<ASTUnit> Unit(
-      ASTUnit::LoadFromCompilerInvocationAction(CInvok.take(), Diags,
-                                                ASTAction.get()));
+  std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCompilerInvocationAction(
+      CInvok.release(), Diags, ASTAction.get()));
   if (!Unit) {
     errRec.FinishCapture();
     return true;
diff --git a/lib/ARCMigrate/CMakeLists.txt b/lib/ARCMigrate/CMakeLists.txt
index c552612..b716a20 100644
--- a/lib/ARCMigrate/CMakeLists.txt
+++ b/lib/ARCMigrate/CMakeLists.txt
@@ -1,3 +1,7 @@
+set(LLVM_LINK_COMPONENTS
+  Support
+  )
+
 add_clang_library(clangARCMigrate
   ARCMT.cpp
   ARCMTActions.cpp
@@ -19,26 +23,16 @@
   TransZeroOutPropsInDealloc.cpp
   TransformActions.cpp
   Transforms.cpp
-  )
 
-add_dependencies(clangARCMigrate
-  ClangAttrClasses
-  ClangAttrList
-  ClangAttrParsedAttrList
-  ClangCommentNodes
-  ClangDeclNodes
-  ClangDiagnosticCommon
-  ClangDiagnosticGroups
-  ClangDiagnosticSema
-  ClangStmtNodes
-  )
-
-target_link_libraries(clangARCMigrate
-  clangBasic
+  LINK_LIBS
   clangAST
-  clangParse
+  clangAnalysis
+  clangBasic
+  clangEdit
   clangFrontend
-  clangRewriteCore
-  clangRewriteFrontend
+  clangLex
+  clangRewrite
+  clangSema
+  clangSerialization
   clangStaticAnalyzerCheckers
   )
diff --git a/lib/ARCMigrate/FileRemapper.cpp b/lib/ARCMigrate/FileRemapper.cpp
index a14226e..40e6060 100644
--- a/lib/ARCMigrate/FileRemapper.cpp
+++ b/lib/ARCMigrate/FileRemapper.cpp
@@ -36,8 +36,7 @@
   assert(ToFromMappings.empty());
   if (!outputDir.empty()) {
     std::string infoFile = getRemapInfoFile(outputDir);
-    bool existed;
-    llvm::sys::fs::remove(infoFile, existed);
+    llvm::sys::fs::remove(infoFile);
   }
 }
 
@@ -65,13 +64,14 @@
     return false;
 
   std::vector<std::pair<const FileEntry *, const FileEntry *> > pairs;
-  
-  OwningPtr<llvm::MemoryBuffer> fileBuf;
-  if (llvm::MemoryBuffer::getFile(infoFile.c_str(), fileBuf))
+
+  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> fileBuf =
+      llvm::MemoryBuffer::getFile(infoFile.c_str());
+  if (!fileBuf)
     return report("Error opening file: " + infoFile, Diag);
   
   SmallVector<StringRef, 64> lines;
-  fileBuf->getBuffer().split(lines, "\n");
+  fileBuf.get()->getBuffer().split(lines, "\n");
 
   for (unsigned idx = 0; idx+3 <= lines.size(); idx += 3) {
     StringRef fromFilename = lines[idx];
@@ -112,8 +112,7 @@
 bool FileRemapper::flushToDisk(StringRef outputDir, DiagnosticsEngine &Diag) {
   using namespace llvm::sys;
 
-  bool existed;
-  if (fs::create_directory(outputDir, existed) != llvm::errc::success)
+  if (fs::create_directory(outputDir))
     return report("Could not create directory: " + outputDir, Diag);
 
   std::string infoFile = getRemapInfoFile(outputDir);
@@ -125,8 +124,7 @@
 
   std::string errMsg;
   std::string infoFile = outputPath;
-  llvm::raw_fd_ostream infoOut(infoFile.c_str(), errMsg,
-                               llvm::sys::fs::F_Binary);
+  llvm::raw_fd_ostream infoOut(infoFile.c_str(), errMsg, llvm::sys::fs::F_None);
   if (!errMsg.empty())
     return report(errMsg, Diag);
 
@@ -182,8 +180,7 @@
                     Diag);
 
     std::string errMsg;
-    llvm::raw_fd_ostream Out(origFE->getName(), errMsg,
-                             llvm::sys::fs::F_Binary);
+    llvm::raw_fd_ostream Out(origFE->getName(), errMsg, llvm::sys::fs::F_None);
     if (!errMsg.empty())
       return report(errMsg, Diag);
 
@@ -210,22 +207,6 @@
   PPOpts.RetainRemappedFileBuffers = true;
 }
 
-void FileRemapper::transferMappingsAndClear(PreprocessorOptions &PPOpts) {
-  for (MappingsTy::iterator
-         I = FromToMappings.begin(), E = FromToMappings.end(); I != E; ++I) {
-    if (const FileEntry *FE = I->second.dyn_cast<const FileEntry *>()) {
-      PPOpts.addRemappedFile(I->first->getName(), FE->getName());
-    } else {
-      llvm::MemoryBuffer *mem = I->second.get<llvm::MemoryBuffer *>();
-      PPOpts.addRemappedFile(I->first->getName(), mem);
-    }
-    I->second = Target();
-  }
-
-  PPOpts.RetainRemappedFileBuffers = false;
-  clear();
-}
-
 void FileRemapper::remap(StringRef filePath, llvm::MemoryBuffer *memBuf) {
   remap(getOriginalFile(filePath), memBuf);
 }
@@ -272,9 +253,7 @@
 }
 
 bool FileRemapper::report(const Twine &err, DiagnosticsEngine &Diag) {
-  SmallString<128> buf;
-  unsigned ID = Diag.getDiagnosticIDs()->getCustomDiagID(DiagnosticIDs::Error,
-                                                         err.toStringRef(buf));
-  Diag.Report(ID);
+  Diag.Report(Diag.getCustomDiagID(DiagnosticsEngine::Error, "%0"))
+      << err.str();
   return true;
 }
diff --git a/lib/ARCMigrate/Internals.h b/lib/ARCMigrate/Internals.h
index 3690c83..a65b329 100644
--- a/lib/ARCMigrate/Internals.h
+++ b/lib/ARCMigrate/Internals.h
@@ -48,7 +48,6 @@
 class TransformActions {
   DiagnosticsEngine &Diags;
   CapturedDiagList &CapturedDiags;
-  bool ReportedErrors;
   void *Impl; // TransformActionsImpl.
 
 public:
@@ -95,6 +94,8 @@
     return CapturedDiags.hasDiagnostic(IDs, range);
   }
 
+  DiagnosticBuilder report(SourceLocation loc, unsigned diagId,
+                           SourceRange range = SourceRange());
   void reportError(StringRef error, SourceLocation loc,
                    SourceRange range = SourceRange());
   void reportWarning(StringRef warning, SourceLocation loc,
@@ -102,7 +103,9 @@
   void reportNote(StringRef note, SourceLocation loc,
                   SourceRange range = SourceRange());
 
-  bool hasReportedErrors() const { return ReportedErrors; }
+  bool hasReportedErrors() const {
+    return Diags.hasUnrecoverableErrorOccurred();
+  }
 
   class RewriteReceiver {
   public:
@@ -161,8 +164,6 @@
   const CapturedDiagList &getDiags() const { return CapturedDiags; }
 
   bool isGCMigration() const { return OrigGCMode != LangOptions::NonGC; }
-  bool noNSAllocReallocError() const { return MigOptions.NoNSAllocReallocError; }
-  void setNSAllocReallocError(bool val) { MigOptions.NoNSAllocReallocError = val; }
   bool noFinalizeRemoval() const { return MigOptions.NoFinalizeRemoval; }
   void setNoFinalizeRemoval(bool val) {MigOptions.NoFinalizeRemoval = val; }
 
diff --git a/lib/ARCMigrate/ObjCMT.cpp b/lib/ARCMigrate/ObjCMT.cpp
index cac0fb0..1a2055e 100644
--- a/lib/ARCMigrate/ObjCMT.cpp
+++ b/lib/ARCMigrate/ObjCMT.cpp
@@ -8,12 +8,15 @@
 //===----------------------------------------------------------------------===//
 
 #include "Transforms.h"
+#include "clang/ARCMigrate/ARCMT.h"
 #include "clang/ARCMigrate/ARCMTActions.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/Attr.h"
 #include "clang/AST/NSAPI.h"
 #include "clang/AST/ParentMap.h"
 #include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/Analysis/DomainSpecific/CocoaConventions.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Edit/Commit.h"
 #include "clang/Edit/EditedSource.h"
@@ -24,11 +27,11 @@
 #include "clang/Lex/PPConditionalDirectiveRecord.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Rewrite/Core/Rewriter.h"
-#include "clang/Analysis/DomainSpecific/CocoaConventions.h"
 #include "clang/StaticAnalyzer/Checkers/ObjCRetainCount.h"
-#include "clang/AST/Attr.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/YAMLParser.h"
 
 using namespace clang;
 using namespace arcmt;
@@ -45,7 +48,6 @@
   
   void migrateDecl(Decl *D);
   void migrateObjCInterfaceDecl(ASTContext &Ctx, ObjCContainerDecl *D);
-  void migrateDeprecatedAnnotation(ASTContext &Ctx, ObjCCategoryDecl *CatDecl);
   void migrateProtocolConformance(ASTContext &Ctx,
                                   const ObjCImplementationDecl *ImpDecl);
   void CacheObjCNSIntegerTypedefed(const TypedefDecl *TypedefDcl);
@@ -76,14 +78,18 @@
   
   void migrateAddMethodAnnotation(ASTContext &Ctx,
                                   const ObjCMethodDecl *MethodDecl);
+
+  void inferDesignatedInitializers(ASTContext &Ctx,
+                                   const ObjCImplementationDecl *ImplD);
+
 public:
   std::string MigrateDir;
   unsigned ASTMigrateActions;
   FileID FileId;
   const TypedefDecl *NSIntegerTypedefed;
   const TypedefDecl *NSUIntegerTypedefed;
-  OwningPtr<NSAPI> NSAPIObj;
-  OwningPtr<edit::EditedSource> Editor;
+  std::unique_ptr<NSAPI> NSAPIObj;
+  std::unique_ptr<edit::EditedSource> Editor;
   FileRemapper &Remapper;
   FileManager &FileMgr;
   const PPConditionalDirectiveRecord *PPRec;
@@ -103,7 +109,7 @@
                          ArrayRef<std::string> WhiteList)
   : MigrateDir(migrateDir),
     ASTMigrateActions(astMigrateActions),
-    NSIntegerTypedefed(0), NSUIntegerTypedefed(0),
+    NSIntegerTypedefed(nullptr), NSUIntegerTypedefed(nullptr),
     Remapper(remapper), FileMgr(fileMgr), PPRec(PPRec), PP(PP),
     IsOutputFile(isOutputFile) {
 
@@ -114,26 +120,26 @@
   }
 
 protected:
-  virtual void Initialize(ASTContext &Context) {
+  void Initialize(ASTContext &Context) override {
     NSAPIObj.reset(new NSAPI(Context));
     Editor.reset(new edit::EditedSource(Context.getSourceManager(),
                                         Context.getLangOpts(),
-                                        PPRec, false));
+                                        PPRec));
   }
 
-  virtual bool HandleTopLevelDecl(DeclGroupRef DG) {
+  bool HandleTopLevelDecl(DeclGroupRef DG) override {
     for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
       migrateDecl(*I);
     return true;
   }
-  virtual void HandleInterestingDecl(DeclGroupRef DG) {
+  void HandleInterestingDecl(DeclGroupRef DG) override {
     // Ignore decls from the PCH.
   }
-  virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef DG) {
+  void HandleTopLevelDeclInObjCContainer(DeclGroupRef DG) override {
     ObjCMigrateASTConsumer::HandleTopLevelDecl(DG);
   }
 
-  virtual void HandleTranslationUnit(ASTContext &Ctx);
+  void HandleTranslationUnit(ASTContext &Ctx) override;
 
   bool canModifyFile(StringRef Path) {
     if (WhiteListFilenames.empty())
@@ -141,6 +147,30 @@
     return WhiteListFilenames.find(llvm::sys::path::filename(Path))
         != WhiteListFilenames.end();
   }
+  bool canModifyFile(const FileEntry *FE) {
+    if (!FE)
+      return false;
+    return canModifyFile(FE->getName());
+  }
+  bool canModifyFile(FileID FID) {
+    if (FID.isInvalid())
+      return false;
+    return canModifyFile(PP.getSourceManager().getFileEntryForID(FID));
+  }
+
+  bool canModify(const Decl *D) {
+    if (!D)
+      return false;
+    if (const ObjCCategoryImplDecl *CatImpl = dyn_cast<ObjCCategoryImplDecl>(D))
+      return canModify(CatImpl->getCategoryDecl());
+    if (const ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D))
+      return canModify(Impl->getClassInterface());
+    if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
+      return canModify(cast<Decl>(MD->getDeclContext()));
+
+    FileID FID = PP.getSourceManager().getFileID(D->getLocation());
+    return canModifyFile(FID);
+  }
 };
 
 }
@@ -150,7 +180,7 @@
                                      unsigned migrateAction)
   : WrapperFrontendAction(WrappedAction), MigrateDir(migrateDir),
     ObjCMigAction(migrateAction),
-    CompInst(0) {
+    CompInst(nullptr) {
   if (MigrateDir.empty())
     MigrateDir = "."; // user current directory if none is given.
 }
@@ -223,7 +253,7 @@
 
 class BodyMigrator : public RecursiveASTVisitor<BodyMigrator> {
   ObjCMigrateASTConsumer &Consumer;
-  OwningPtr<ParentMap> PMap;
+  std::unique_ptr<ParentMap> PMap;
 
 public:
   BodyMigrator(ObjCMigrateASTConsumer &consumer) : Consumer(consumer) { }
@@ -294,7 +324,9 @@
 static const char *PropertyMemoryAttribute(ASTContext &Context, QualType ArgType) {
   Qualifiers::ObjCLifetime propertyLifetime = ArgType.getObjCLifetime();
   bool RetainableObject = ArgType->isObjCRetainableType();
-  if (RetainableObject && propertyLifetime == Qualifiers::OCL_Strong) {
+  if (RetainableObject &&
+      (propertyLifetime == Qualifiers::OCL_Strong
+       || propertyLifetime == Qualifiers::OCL_None)) {
     if (const ObjCObjectPointerType *ObjPtrTy =
         ArgType->getAs<ObjCObjectPointerType>()) {
       ObjCInterfaceDecl *IDecl = ObjPtrTy->getObjectType()->getInterface();
@@ -302,7 +334,7 @@
           IDecl->lookupNestedProtocol(&Context.Idents.get("NSCopying")))
         return "copy";
       else
-        return "retain";
+        return "strong";
     }
     else if (ArgType->isBlockPointerType())
       return "copy";
@@ -311,8 +343,8 @@
     // looking into setter's implementation for backing weak ivar.
     return "weak";
   else if (RetainableObject)
-    return ArgType->isBlockPointerType() ? "copy" : "retain";
-  return 0;
+    return ArgType->isBlockPointerType() ? "copy" : "strong";
+  return nullptr;
 }
 
 static void rewriteToObjCProperty(const ObjCMethodDecl *Getter,
@@ -344,23 +376,23 @@
     PropertyString += PropertyNameString;
   }
   // Property with no setter may be suggested as a 'readonly' property.
-  if (!Setter) {
+  if (!Setter)
     append_attr(PropertyString, "readonly", LParenAdded);
-    QualType ResType = Context.getCanonicalType(Getter->getResultType());
-    if (const char *MemoryManagementAttr = PropertyMemoryAttribute(Context, ResType))
-      append_attr(PropertyString, MemoryManagementAttr, LParenAdded);
-  }
+  
   
   // Short circuit 'delegate' properties that contain the name "delegate" or
   // "dataSource", or have exact name "target" to have 'assign' attribute.
   if (PropertyName.equals("target") ||
       (PropertyName.find("delegate") != StringRef::npos) ||
       (PropertyName.find("dataSource") != StringRef::npos)) {
-    QualType QT = Getter->getResultType();
+    QualType QT = Getter->getReturnType();
     if (!QT->isRealType())
       append_attr(PropertyString, "assign", LParenAdded);
-  }
-  else if (Setter) {
+  } else if (!Setter) {
+    QualType ResType = Context.getCanonicalType(Getter->getReturnType());
+    if (const char *MemoryManagementAttr = PropertyMemoryAttribute(Context, ResType))
+      append_attr(PropertyString, MemoryManagementAttr, LParenAdded);
+  } else {
     const ParmVarDecl *argDecl = *Setter->param_begin();
     QualType ArgType = Context.getCanonicalType(argDecl->getType());
     if (const char *MemoryManagementAttr = PropertyMemoryAttribute(Context, ArgType))
@@ -368,7 +400,7 @@
   }
   if (LParenAdded)
     PropertyString += ')';
-  QualType RT = Getter->getResultType();
+  QualType RT = Getter->getReturnType();
   if (!isa<TypedefType>(RT)) {
     // strip off any ARC lifetime qualifier.
     QualType CanResultTy = Context.getCanonicalType(RT);
@@ -419,21 +451,27 @@
     // Get location past ';'
     EndLoc = EndLoc.getLocWithOffset(1);
     SourceLocation BeginOfSetterDclLoc = Setter->getLocStart();
-    // FIXME. This assumes that setter decl; is immediately preceeded by eoln.
+    // FIXME. This assumes that setter decl; is immediately preceded by eoln.
     // It is trying to remove the setter method decl. line entirely.
     BeginOfSetterDclLoc = BeginOfSetterDclLoc.getLocWithOffset(-1);
     commit.remove(SourceRange(BeginOfSetterDclLoc, EndLoc));
   }
 }
 
+static bool IsCategoryNameWithDeprecatedSuffix(ObjCContainerDecl *D) {
+  if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(D)) {
+    StringRef Name = CatDecl->getName();
+    return Name.endswith("Deprecated");
+  }
+  return false;
+}
+
 void ObjCMigrateASTConsumer::migrateObjCInterfaceDecl(ASTContext &Ctx,
                                                       ObjCContainerDecl *D) {
-  if (D->isDeprecated())
+  if (D->isDeprecated() || IsCategoryNameWithDeprecatedSuffix(D))
     return;
-  
-  for (ObjCContainerDecl::method_iterator M = D->meth_begin(), MEnd = D->meth_end();
-       M != MEnd; ++M) {
-    ObjCMethodDecl *Method = (*M);
+    
+  for (auto *Method : D->methods()) {
     if (Method->isDeprecated())
       continue;
     bool PropertyInferred = migrateProperty(Ctx, D, Method);
@@ -448,48 +486,13 @@
   if (!(ASTMigrateActions & FrontendOptions::ObjCMT_ReturnsInnerPointerProperty))
     return;
   
-  for (ObjCContainerDecl::prop_iterator P = D->prop_begin(),
-       E = D->prop_end(); P != E; ++P) {
-    ObjCPropertyDecl *Prop = *P;
+  for (auto *Prop : D->properties()) {
     if ((ASTMigrateActions & FrontendOptions::ObjCMT_Annotation) &&
         !Prop->isDeprecated())
       migratePropertyNsReturnsInnerPointer(Ctx, Prop);
   }
 }
 
-void ObjCMigrateASTConsumer::migrateDeprecatedAnnotation(ASTContext &Ctx,
-                                                           ObjCCategoryDecl *CatDecl) {
-  StringRef Name = CatDecl->getName();
-  if (!Name.endswith("Deprecated"))
-    return;
-  
-  if (!Ctx.Idents.get("DEPRECATED").hasMacroDefinition())
-    return;
-  
-  ObjCContainerDecl *D = cast<ObjCContainerDecl>(CatDecl);
-  
-  for (ObjCContainerDecl::method_iterator M = D->meth_begin(), MEnd = D->meth_end();
-       M != MEnd; ++M) {
-    ObjCMethodDecl *Method = (*M);
-    if (Method->isDeprecated() || Method->isImplicit())
-      continue;
-    // Annotate with DEPRECATED
-    edit::Commit commit(*Editor);
-    commit.insertBefore(Method->getLocEnd(), " DEPRECATED");
-    Editor->commit(commit);
-  }
-  for (ObjCContainerDecl::prop_iterator P = D->prop_begin(),
-       E = D->prop_end(); P != E; ++P) {
-    ObjCPropertyDecl *Prop = *P;
-    if (Prop->isDeprecated())
-      continue;
-    // Annotate with DEPRECATED
-    edit::Commit commit(*Editor);
-    commit.insertAfterToken(Prop->getLocEnd(), " DEPRECATED");
-    Editor->commit(commit);
-  }
-}
-
 static bool
 ClassImplementsAllMethodsAndProperties(ASTContext &Ctx,
                                       const ObjCImplementationDecl *ImpDecl,
@@ -500,9 +503,7 @@
   // in class interface.
   bool HasAtleastOneRequiredProperty = false;
   if (const ObjCProtocolDecl *PDecl = Protocol->getDefinition())
-    for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(),
-         E = PDecl->prop_end(); P != E; ++P) {
-      ObjCPropertyDecl *Property = *P;
+    for (const auto *Property : PDecl->properties()) {
       if (Property->getPropertyImplementation() == ObjCPropertyDecl::Optional)
         continue;
       HasAtleastOneRequiredProperty = true;
@@ -532,9 +533,7 @@
   if (const ObjCProtocolDecl *PDecl = Protocol->getDefinition()) {
     if (PDecl->meth_begin() == PDecl->meth_end())
       return HasAtleastOneRequiredProperty;
-    for (ObjCContainerDecl::method_iterator M = PDecl->meth_begin(),
-         MEnd = PDecl->meth_end(); M != MEnd; ++M) {
-      ObjCMethodDecl *MD = (*M);
+    for (const auto *MD : PDecl->methods()) {
       if (MD->isImplicit())
         continue;
       if (MD->getImplementationControl() == ObjCMethodDecl::Optional)
@@ -632,7 +631,7 @@
                                                  /*IsDecl*/true);
   if (!EndOfEnumDclLoc.isInvalid()) {
     SourceLocation BeginOfEnumDclLoc = EnumDcl->getLocStart();
-    // FIXME. This assumes that enum decl; is immediately preceeded by eoln.
+    // FIXME. This assumes that enum decl; is immediately preceded by eoln.
     // It is trying to remove the enum decl. lines entirely.
     BeginOfEnumDclLoc = BeginOfEnumDclLoc.getLocWithOffset(-1);
     commit.remove(SourceRange(BeginOfEnumDclLoc, EndOfEnumDclLoc));
@@ -660,9 +659,7 @@
   bool PowerOfTwo = true;
   bool AllHexdecimalEnumerator = true;
   uint64_t MaxPowerOfTwoVal = 0;
-  for (EnumDecl::enumerator_iterator EI = EnumDcl->enumerator_begin(),
-       EE = EnumDcl->enumerator_end(); EI != EE; ++EI) {
-    EnumConstantDecl *Enumerator = (*EI);
+  for (auto Enumerator : EnumDcl->enumerators()) {
     const Expr *InitExpr = Enumerator->getInitExpr();
     if (!InitExpr) {
       PowerOfTwo = false;
@@ -749,6 +746,8 @@
     if (!DropIt)
       MinimalConformingProtocols.push_back(TargetPDecl);
   }
+  if (MinimalConformingProtocols.empty())
+    return;
   edit::Commit commit(*Editor);
   rewriteToObjCInterfaceDecl(IDecl, MinimalConformingProtocols,
                              *NSAPIObj, commit);
@@ -774,11 +773,11 @@
   if (!TypedefDcl) {
     if (NSIntegerTypedefed) {
       TypedefDcl = NSIntegerTypedefed;
-      NSIntegerTypedefed = 0;
+      NSIntegerTypedefed = nullptr;
     }
     else if (NSUIntegerTypedefed) {
       TypedefDcl = NSUIntegerTypedefed;
-      NSUIntegerTypedefed = 0;
+      NSUIntegerTypedefed = nullptr;
     }
     else
       return false;
@@ -831,11 +830,15 @@
   return Res;
 }
 
-static void ReplaceWithInstancetype(const ObjCMigrateASTConsumer &ASTC,
+static void ReplaceWithInstancetype(ASTContext &Ctx,
+                                    const ObjCMigrateASTConsumer &ASTC,
                                     ObjCMethodDecl *OM) {
+  if (OM->getReturnType() == Ctx.getObjCInstanceType())
+    return; // already has instancetype.
+
   SourceRange R;
   std::string ClassString;
-  if (TypeSourceInfo *TSInfo =  OM->getResultTypeSourceInfo()) {
+  if (TypeSourceInfo *TSInfo = OM->getReturnTypeSourceInfo()) {
     TypeLoc TL = TSInfo->getTypeLoc();
     R = SourceRange(TL.getBeginLoc(), TL.getEndLoc());
     ClassString = "instancetype";
@@ -855,7 +858,7 @@
   ObjCInterfaceDecl *IDecl = OM->getClassInterface();
   SourceRange R;
   std::string ClassString;
-  if (TypeSourceInfo *TSInfo =  OM->getResultTypeSourceInfo()) {
+  if (TypeSourceInfo *TSInfo = OM->getReturnTypeSourceInfo()) {
     TypeLoc TL = TSInfo->getTypeLoc();
     R = SourceRange(TL.getBeginLoc(), TL.getEndLoc()); {
       ClassString  = IDecl->getName();
@@ -893,14 +896,14 @@
       migrateFactoryMethod(Ctx, CDecl, OM, OIT_Singleton);
       return;
     case OIT_Init:
-      if (OM->getResultType()->isObjCIdType())
-        ReplaceWithInstancetype(*this, OM);
+      if (OM->getReturnType()->isObjCIdType())
+        ReplaceWithInstancetype(Ctx, *this, OM);
       return;
     case OIT_ReturnsSelf:
       migrateFactoryMethod(Ctx, CDecl, OM, OIT_ReturnsSelf);
       return;
   }
-  if (!OM->getResultType()->isObjCIdType())
+  if (!OM->getReturnType()->isObjCIdType())
     return;
   
   ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl);
@@ -915,7 +918,7 @@
     migrateFactoryMethod(Ctx, CDecl, OM);
     return;
   }
-  ReplaceWithInstancetype(*this, OM);
+  ReplaceWithInstancetype(Ctx, *this, OM);
 }
 
 static bool TypeIsInnerPointer(QualType T) {
@@ -1034,7 +1037,7 @@
       Method->param_size() != 0)
     return false;
   // Is this method candidate to be a getter?
-  QualType GRT = Method->getResultType();
+  QualType GRT = Method->getReturnType();
   if (GRT->isVoidType())
     return false;
   
@@ -1087,7 +1090,7 @@
       return false;
     
     // Is this a valid setter, matching the target getter?
-    QualType SRT = SetterMethod->getResultType();
+    QualType SRT = SetterMethod->getReturnType();
     if (!SRT->isVoidType())
       return false;
     const ParmVarDecl *argDecl = *SetterMethod->param_begin();
@@ -1109,7 +1112,7 @@
     // Try a non-void method with no argument (and no setter or property of same name
     // as a 'readonly' property.
     edit::Commit commit(*Editor);
-    rewriteToObjCProperty(Method, 0 /*SetterMethod*/, *NSAPIObj, commit,
+    rewriteToObjCProperty(Method, nullptr /*SetterMethod*/, *NSAPIObj, commit,
                           LengthOfPrefix,
                           (ASTMigrateActions &
                            FrontendOptions::ObjCMT_AtomicProperty) != 0,
@@ -1128,8 +1131,8 @@
       !OM->isInstanceMethod() ||
       OM->hasAttr<ObjCReturnsInnerPointerAttr>())
     return;
-  
-  QualType RT = OM->getResultType();
+
+  QualType RT = OM->getReturnType();
   if (!TypeIsInnerPointer(RT) ||
       !Ctx.Idents.get("NS_RETURNS_INNER_POINTER").hasMacroDefinition())
     return;
@@ -1153,14 +1156,11 @@
 
 void ObjCMigrateASTConsumer::migrateAllMethodInstaceType(ASTContext &Ctx,
                                                  ObjCContainerDecl *CDecl) {
-  if (CDecl->isDeprecated())
+  if (CDecl->isDeprecated() || IsCategoryNameWithDeprecatedSuffix(CDecl))
     return;
   
   // migrate methods which can have instancetype as their result type.
-  for (ObjCContainerDecl::method_iterator M = CDecl->meth_begin(),
-       MEnd = CDecl->meth_end();
-       M != MEnd; ++M) {
-    ObjCMethodDecl *Method = (*M);
+  for (auto *Method : CDecl->methods()) {
     if (Method->isDeprecated())
       continue;
     migrateMethodInstanceType(Ctx, CDecl, Method);
@@ -1172,8 +1172,8 @@
                                                   ObjCMethodDecl *OM,
                                                   ObjCInstanceTypeFamily OIT_Family) {
   if (OM->isInstanceMethod() ||
-      OM->getResultType() == Ctx.getObjCInstanceType() ||
-      !OM->getResultType()->isObjCIdType())
+      OM->getReturnType() == Ctx.getObjCInstanceType() ||
+      !OM->getReturnType()->isObjCIdType())
     return;
   
   // Candidate factory methods are + (id) NaMeXXX : ... which belong to a class
@@ -1228,7 +1228,7 @@
   if (OIT_Family == OIT_ReturnsSelf)
     ReplaceWithClasstype(*this, OM);
   else
-    ReplaceWithInstancetype(*this, OM);
+    ReplaceWithInstancetype(Ctx, *this, OM);
 }
 
 static bool IsVoidStarType(QualType Ty) {
@@ -1338,7 +1338,7 @@
   // Annotate function.
   if (!ResultAnnotated) {
     RetEffect Ret = CE.getReturnValue();
-    const char *AnnotationString = 0;
+    const char *AnnotationString = nullptr;
     if (Ret.getObjKind() == RetEffect::CF) {
       if (Ret.isOwned() &&
           Ctx.Idents.get("CF_RETURNS_RETAINED").hasMacroDefinition())
@@ -1359,19 +1359,19 @@
       Editor->commit(commit);
     }
   }
-  llvm::ArrayRef<ArgEffect> AEArgs = CE.getArgs();
+  ArrayRef<ArgEffect> AEArgs = CE.getArgs();
   unsigned i = 0;
   for (FunctionDecl::param_const_iterator pi = FuncDecl->param_begin(),
        pe = FuncDecl->param_end(); pi != pe; ++pi, ++i) {
     const ParmVarDecl *pd = *pi;
     ArgEffect AE = AEArgs[i];
-    if (AE == DecRef && !pd->getAttr<CFConsumedAttr>() &&
+    if (AE == DecRef && !pd->hasAttr<CFConsumedAttr>() &&
         Ctx.Idents.get("CF_CONSUMED").hasMacroDefinition()) {
       edit::Commit commit(*Editor);
       commit.insertBefore(pd->getLocation(), "CF_CONSUMED ");
       Editor->commit(commit);
     }
-    else if (AE == DecRefMsg && !pd->getAttr<NSConsumedAttr>() &&
+    else if (AE == DecRefMsg && !pd->hasAttr<NSConsumedAttr>() &&
              Ctx.Idents.get("NS_CONSUMED").hasMacroDefinition()) {
       edit::Commit commit(*Editor);
       commit.insertBefore(pd->getLocation(), "NS_CONSUMED ");
@@ -1389,11 +1389,11 @@
     return CF_BRIDGING_NONE;
     
   CallEffects CE  = CallEffects::getEffect(FuncDecl);
-  bool FuncIsReturnAnnotated = (FuncDecl->getAttr<CFReturnsRetainedAttr>() ||
-                                FuncDecl->getAttr<CFReturnsNotRetainedAttr>() ||
-                                FuncDecl->getAttr<NSReturnsRetainedAttr>() ||
-                                FuncDecl->getAttr<NSReturnsNotRetainedAttr>() ||
-                                FuncDecl->getAttr<NSReturnsAutoreleasedAttr>());
+  bool FuncIsReturnAnnotated = (FuncDecl->hasAttr<CFReturnsRetainedAttr>() ||
+                                FuncDecl->hasAttr<CFReturnsNotRetainedAttr>() ||
+                                FuncDecl->hasAttr<NSReturnsRetainedAttr>() ||
+                                FuncDecl->hasAttr<NSReturnsNotRetainedAttr>() ||
+                                FuncDecl->hasAttr<NSReturnsAutoreleasedAttr>());
   
   // Trivial case of when funciton is annotated and has no argument.
   if (FuncIsReturnAnnotated && FuncDecl->getNumParams() == 0)
@@ -1405,13 +1405,13 @@
     if (Ret.getObjKind() == RetEffect::CF &&
         (Ret.isOwned() || Ret.notOwned()))
       ReturnCFAudited = true;
-    else if (!AuditedType(FuncDecl->getResultType()))
+    else if (!AuditedType(FuncDecl->getReturnType()))
       return CF_BRIDGING_NONE;
   }
   
   // At this point result type is audited for potential inclusion.
   // Now, how about argument types.
-  llvm::ArrayRef<ArgEffect> AEArgs = CE.getArgs();
+  ArrayRef<ArgEffect> AEArgs = CE.getArgs();
   unsigned i = 0;
   bool ArgCFAudited = false;
   for (FunctionDecl::param_const_iterator pi = FuncDecl->param_begin(),
@@ -1419,7 +1419,7 @@
     const ParmVarDecl *pd = *pi;
     ArgEffect AE = AEArgs[i];
     if (AE == DecRef /*CFConsumed annotated*/ || AE == IncRef) {
-      if (AE == DecRef && !pd->getAttr<CFConsumedAttr>())
+      if (AE == DecRef && !pd->hasAttr<CFConsumedAttr>())
         ArgCFAudited = true;
       else if (AE == IncRef)
         ArgCFAudited = true;
@@ -1444,12 +1444,8 @@
     return;
   
   // migrate methods which can have instancetype as their result type.
-  for (ObjCContainerDecl::method_iterator M = CDecl->meth_begin(),
-       MEnd = CDecl->meth_end();
-       M != MEnd; ++M) {
-    ObjCMethodDecl *Method = (*M);
+  for (const auto *Method : CDecl->methods())
     migrateCFAnnotation(Ctx, Method);
-  }
 }
 
 void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
@@ -1459,7 +1455,7 @@
   // Annotate function.
   if (!ResultAnnotated) {
     RetEffect Ret = CE.getReturnValue();
-    const char *AnnotationString = 0;
+    const char *AnnotationString = nullptr;
     if (Ret.getObjKind() == RetEffect::CF) {
       if (Ret.isOwned() &&
           Ctx.Idents.get("CF_RETURNS_RETAINED").hasMacroDefinition())
@@ -1492,13 +1488,13 @@
       Editor->commit(commit);
     }
   }
-  llvm::ArrayRef<ArgEffect> AEArgs = CE.getArgs();
+  ArrayRef<ArgEffect> AEArgs = CE.getArgs();
   unsigned i = 0;
   for (ObjCMethodDecl::param_const_iterator pi = MethodDecl->param_begin(),
        pe = MethodDecl->param_end(); pi != pe; ++pi, ++i) {
     const ParmVarDecl *pd = *pi;
     ArgEffect AE = AEArgs[i];
-    if (AE == DecRef && !pd->getAttr<CFConsumedAttr>() &&
+    if (AE == DecRef && !pd->hasAttr<CFConsumedAttr>() &&
         Ctx.Idents.get("CF_CONSUMED").hasMacroDefinition()) {
       edit::Commit commit(*Editor);
       commit.insertBefore(pd->getLocation(), "CF_CONSUMED ");
@@ -1514,14 +1510,14 @@
     return;
   
   CallEffects CE  = CallEffects::getEffect(MethodDecl);
-  bool MethodIsReturnAnnotated = (MethodDecl->getAttr<CFReturnsRetainedAttr>() ||
-                                  MethodDecl->getAttr<CFReturnsNotRetainedAttr>() ||
-                                  MethodDecl->getAttr<NSReturnsRetainedAttr>() ||
-                                  MethodDecl->getAttr<NSReturnsNotRetainedAttr>() ||
-                                  MethodDecl->getAttr<NSReturnsAutoreleasedAttr>());
+  bool MethodIsReturnAnnotated = (MethodDecl->hasAttr<CFReturnsRetainedAttr>() ||
+                                  MethodDecl->hasAttr<CFReturnsNotRetainedAttr>() ||
+                                  MethodDecl->hasAttr<NSReturnsRetainedAttr>() ||
+                                  MethodDecl->hasAttr<NSReturnsNotRetainedAttr>() ||
+                                  MethodDecl->hasAttr<NSReturnsAutoreleasedAttr>());
   
   if (CE.getReceiver() ==  DecRefMsg &&
-      !MethodDecl->getAttr<NSConsumesSelfAttr>() &&
+      !MethodDecl->hasAttr<NSConsumesSelfAttr>() &&
       MethodDecl->getMethodFamily() != OMF_init &&
       MethodDecl->getMethodFamily() != OMF_release &&
       Ctx.Idents.get("NS_CONSUMES_SELF").hasMacroDefinition()) {
@@ -1542,20 +1538,19 @@
         (Ret.isOwned() || Ret.notOwned())) {
       AddCFAnnotations(Ctx, CE, MethodDecl, false);
       return;
-    }
-    else if (!AuditedType(MethodDecl->getResultType()))
+    } else if (!AuditedType(MethodDecl->getReturnType()))
       return;
   }
   
   // At this point result type is either annotated or audited.
   // Now, how about argument types.
-  llvm::ArrayRef<ArgEffect> AEArgs = CE.getArgs();
+  ArrayRef<ArgEffect> AEArgs = CE.getArgs();
   unsigned i = 0;
   for (ObjCMethodDecl::param_const_iterator pi = MethodDecl->param_begin(),
        pe = MethodDecl->param_end(); pi != pe; ++pi, ++i) {
     const ParmVarDecl *pd = *pi;
     ArgEffect AE = AEArgs[i];
-    if ((AE == DecRef && !pd->getAttr<CFConsumedAttr>()) || AE == IncRef ||
+    if ((AE == DecRef && !pd->hasAttr<CFConsumedAttr>()) || AE == IncRef ||
         !AuditedType(pd->getType())) {
       AddCFAnnotations(Ctx, CE, MethodDecl, MethodIsReturnAnnotated);
       return;
@@ -1565,6 +1560,53 @@
 }
 
 namespace {
+class SuperInitChecker : public RecursiveASTVisitor<SuperInitChecker> {
+public:
+  bool shouldVisitTemplateInstantiations() const { return false; }
+  bool shouldWalkTypesOfTypeLocs() const { return false; }
+
+  bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
+    if (E->getReceiverKind() == ObjCMessageExpr::SuperInstance) {
+      if (E->getMethodFamily() == OMF_init)
+        return false;
+    }
+    return true;
+  }
+};
+} // anonymous namespace
+
+static bool hasSuperInitCall(const ObjCMethodDecl *MD) {
+  return !SuperInitChecker().TraverseStmt(MD->getBody());
+}
+
+void ObjCMigrateASTConsumer::inferDesignatedInitializers(
+    ASTContext &Ctx,
+    const ObjCImplementationDecl *ImplD) {
+
+  const ObjCInterfaceDecl *IFace = ImplD->getClassInterface();
+  if (!IFace || IFace->hasDesignatedInitializers())
+    return;
+  if (!Ctx.Idents.get("NS_DESIGNATED_INITIALIZER").hasMacroDefinition())
+    return;
+
+  for (const auto *MD : ImplD->instance_methods()) {
+    if (MD->isDeprecated() ||
+        MD->getMethodFamily() != OMF_init ||
+        MD->isDesignatedInitializerForTheInterface())
+      continue;
+    const ObjCMethodDecl *IFaceM = IFace->getMethod(MD->getSelector(),
+                                                    /*isInstance=*/true);
+    if (!IFaceM)
+      continue;
+    if (hasSuperInitCall(MD)) {
+      edit::Commit commit(*Editor);
+      commit.insert(IFaceM->getLocEnd(), " NS_DESIGNATED_INITIALIZER");
+      Editor->commit(commit);
+    }
+  }
+}
+
+namespace {
 
 class RewritesReceiver : public edit::EditsReceiver {
   Rewriter &Rewrite;
@@ -1572,42 +1614,92 @@
 public:
   RewritesReceiver(Rewriter &Rewrite) : Rewrite(Rewrite) { }
 
-  virtual void insert(SourceLocation loc, StringRef text) {
+  void insert(SourceLocation loc, StringRef text) override {
     Rewrite.InsertText(loc, text);
   }
-  virtual void replace(CharSourceRange range, StringRef text) {
+  void replace(CharSourceRange range, StringRef text) override {
     Rewrite.ReplaceText(range.getBegin(), Rewrite.getRangeSize(range), text);
   }
 };
 
-}
+class JSONEditWriter : public edit::EditsReceiver {
+  SourceManager &SourceMgr;
+  llvm::raw_ostream &OS;
 
-static bool
-IsReallyASystemHeader(ASTContext &Ctx, const FileEntry *file, FileID FID) {
-  bool Invalid = false;
-  const SrcMgr::SLocEntry &SEntry =
-  Ctx.getSourceManager().getSLocEntry(FID, &Invalid);
-  if (!Invalid && SEntry.isFile()) {
-    const SrcMgr::FileInfo &FI = SEntry.getFile();
-    if (!FI.hasLineDirectives()) {
-      if (FI.getFileCharacteristic() == SrcMgr::C_ExternCSystem)
-        return true;
-      if (FI.getFileCharacteristic() == SrcMgr::C_System) {
-        // This file is in a system header directory. Continue with commiting change
-        // only if it is a user specified system directory because user put a
-        // .system_framework file in the framework directory.
-        StringRef Directory(file->getDir()->getName());
-        size_t Ix = Directory.rfind(".framework");
-        if (Ix == StringRef::npos)
-          return true;
-        std::string PatchToSystemFramework = Directory.slice(0, Ix+sizeof(".framework"));
-        PatchToSystemFramework += ".system_framework";
-        if (!llvm::sys::fs::exists(PatchToSystemFramework.data()))
-          return true;
-      }
-    }
+public:
+  JSONEditWriter(SourceManager &SM, llvm::raw_ostream &OS)
+    : SourceMgr(SM), OS(OS) {
+    OS << "[\n";
   }
-  return false;
+  ~JSONEditWriter() {
+    OS << "]\n";
+  }
+
+private:
+  struct EntryWriter {
+    SourceManager &SourceMgr;
+    llvm::raw_ostream &OS;
+
+    EntryWriter(SourceManager &SM, llvm::raw_ostream &OS)
+      : SourceMgr(SM), OS(OS) {
+      OS << " {\n";
+    }
+    ~EntryWriter() {
+      OS << " },\n";
+    }
+
+    void writeLoc(SourceLocation Loc) {
+      FileID FID;
+      unsigned Offset;
+      std::tie(FID, Offset) = SourceMgr.getDecomposedLoc(Loc);
+      assert(!FID.isInvalid());
+      SmallString<200> Path =
+          StringRef(SourceMgr.getFileEntryForID(FID)->getName());
+      llvm::sys::fs::make_absolute(Path);
+      OS << "  \"file\": \"";
+      OS.write_escaped(Path.str()) << "\",\n";
+      OS << "  \"offset\": " << Offset << ",\n";
+    }
+
+    void writeRemove(CharSourceRange Range) {
+      assert(Range.isCharRange());
+      std::pair<FileID, unsigned> Begin =
+          SourceMgr.getDecomposedLoc(Range.getBegin());
+      std::pair<FileID, unsigned> End =
+          SourceMgr.getDecomposedLoc(Range.getEnd());
+      assert(Begin.first == End.first);
+      assert(Begin.second <= End.second);
+      unsigned Length = End.second - Begin.second;
+
+      OS << "  \"remove\": " << Length << ",\n";
+    }
+
+    void writeText(StringRef Text) {
+      OS << "  \"text\": \"";
+      OS.write_escaped(Text) << "\",\n";
+    }
+  };
+ 
+  void insert(SourceLocation Loc, StringRef Text) override {
+    EntryWriter Writer(SourceMgr, OS);
+    Writer.writeLoc(Loc);
+    Writer.writeText(Text);
+  }
+
+  void replace(CharSourceRange Range, StringRef Text) override {
+    EntryWriter Writer(SourceMgr, OS);
+    Writer.writeLoc(Range.getBegin());
+    Writer.writeRemove(Range);
+    Writer.writeText(Text);
+  }
+
+  void remove(CharSourceRange Range) override {
+    EntryWriter Writer(SourceMgr, OS);
+    Writer.writeLoc(Range.getBegin());
+    Writer.writeRemove(Range);
+  }
+};
+
 }
 
 void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) {
@@ -1624,22 +1716,25 @@
         }
       
       if (ObjCInterfaceDecl *CDecl = dyn_cast<ObjCInterfaceDecl>(*D))
-        migrateObjCInterfaceDecl(Ctx, CDecl);
+        if (canModify(CDecl))
+          migrateObjCInterfaceDecl(Ctx, CDecl);
       if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(*D)) {
-        migrateObjCInterfaceDecl(Ctx, CatDecl);
-        if (ASTMigrateActions & FrontendOptions::ObjCMT_Annotation)
-          migrateDeprecatedAnnotation(Ctx, CatDecl);
+        if (canModify(CatDecl))
+          migrateObjCInterfaceDecl(Ctx, CatDecl);
       }
       else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(*D))
-        ObjCProtocolDecls.insert(PDecl);
+        ObjCProtocolDecls.insert(PDecl->getCanonicalDecl());
       else if (const ObjCImplementationDecl *ImpDecl =
                dyn_cast<ObjCImplementationDecl>(*D)) {
-        if (ASTMigrateActions & FrontendOptions::ObjCMT_ProtocolConformance)
+        if ((ASTMigrateActions & FrontendOptions::ObjCMT_ProtocolConformance) &&
+            canModify(ImpDecl))
           migrateProtocolConformance(Ctx, ImpDecl);
       }
       else if (const EnumDecl *ED = dyn_cast<EnumDecl>(*D)) {
         if (!(ASTMigrateActions & FrontendOptions::ObjCMT_NsMacros))
           continue;
+        if (!canModify(ED))
+          continue;
         DeclContext::decl_iterator N = D;
         if (++N != DEnd) {
           const TypedefDecl *TD = dyn_cast<TypedefDecl>(*N);
@@ -1647,11 +1742,13 @@
             D++;
         }
         else
-          migrateNSEnumDecl(Ctx, ED, /*TypedefDecl */0);
+          migrateNSEnumDecl(Ctx, ED, /*TypedefDecl */nullptr);
       }
       else if (const TypedefDecl *TD = dyn_cast<TypedefDecl>(*D)) {
         if (!(ASTMigrateActions & FrontendOptions::ObjCMT_NsMacros))
           continue;
+        if (!canModify(TD))
+          continue;
         DeclContext::decl_iterator N = D;
         if (++N == DEnd)
           continue;
@@ -1673,23 +1770,49 @@
         CacheObjCNSIntegerTypedefed(TD);
       }
       else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*D)) {
-        if (ASTMigrateActions & FrontendOptions::ObjCMT_Annotation)
+        if ((ASTMigrateActions & FrontendOptions::ObjCMT_Annotation) &&
+            canModify(FD))
           migrateCFAnnotation(Ctx, FD);
       }
       
       if (ObjCContainerDecl *CDecl = dyn_cast<ObjCContainerDecl>(*D)) {
+        bool CanModify = canModify(CDecl);
         // migrate methods which can have instancetype as their result type.
-        if (ASTMigrateActions & FrontendOptions::ObjCMT_Instancetype)
+        if ((ASTMigrateActions & FrontendOptions::ObjCMT_Instancetype) &&
+            CanModify)
           migrateAllMethodInstaceType(Ctx, CDecl);
         // annotate methods with CF annotations.
-        if (ASTMigrateActions & FrontendOptions::ObjCMT_Annotation)
+        if ((ASTMigrateActions & FrontendOptions::ObjCMT_Annotation) &&
+            CanModify)
           migrateARCSafeAnnotation(Ctx, CDecl);
       }
+
+      if (const ObjCImplementationDecl *
+            ImplD = dyn_cast<ObjCImplementationDecl>(*D)) {
+        if ((ASTMigrateActions & FrontendOptions::ObjCMT_DesignatedInitializer) &&
+            canModify(ImplD))
+          inferDesignatedInitializers(Ctx, ImplD);
+      }
     }
     if (ASTMigrateActions & FrontendOptions::ObjCMT_Annotation)
       AnnotateImplicitBridging(Ctx);
   }
   
+ if (IsOutputFile) {
+   std::string Error;
+   llvm::raw_fd_ostream OS(MigrateDir.c_str(), Error, llvm::sys::fs::F_None);
+    if (!Error.empty()) {
+      DiagnosticsEngine &Diags = Ctx.getDiagnostics();
+      Diags.Report(Diags.getCustomDiagID(DiagnosticsEngine::Error, "%0"))
+          << Error;
+      return;
+    }
+
+   JSONEditWriter Writer(Ctx.getSourceManager(), OS);
+   Editor->applyRewrites(Writer);
+   return;
+ }
+
   Rewriter rewriter(Ctx.getSourceManager(), Ctx.getLangOpts());
   RewritesReceiver Rec(rewriter);
   Editor->applyRewrites(Rec);
@@ -1700,10 +1823,6 @@
     RewriteBuffer &buf = I->second;
     const FileEntry *file = Ctx.getSourceManager().getFileEntryForID(FID);
     assert(file);
-    if (IsReallyASystemHeader(Ctx, file, FID))
-      continue;
-    if (!canModifyFile(file->getName()))
-      continue;
     SmallString<512> newText;
     llvm::raw_svector_ostream vecOS(newText);
     buf.write(vecOS);
@@ -1734,8 +1853,8 @@
   std::vector<std::string> Filenames;
   if (DirPath.empty() || !is_directory(DirPath))
     return Filenames;
-  
-  llvm::error_code EC;
+
+  std::error_code EC;
   directory_iterator DI = directory_iterator(DirPath, EC);
   directory_iterator DE;
   for (; !EC && DI != DE; DI = DI.increment(EC)) {
@@ -1773,3 +1892,246 @@
                                     /*isOutputFile=*/true,
                                     WhiteList);
 }
+
+namespace {
+struct EditEntry {
+  const FileEntry *File;
+  unsigned Offset;
+  unsigned RemoveLen;
+  std::string Text;
+
+  EditEntry() : File(), Offset(), RemoveLen() {}
+};
+}
+
+namespace llvm {
+template<> struct DenseMapInfo<EditEntry> {
+  static inline EditEntry getEmptyKey() {
+    EditEntry Entry;
+    Entry.Offset = unsigned(-1);
+    return Entry;
+  }
+  static inline EditEntry getTombstoneKey() {
+    EditEntry Entry;
+    Entry.Offset = unsigned(-2);
+    return Entry;
+  }
+  static unsigned getHashValue(const EditEntry& Val) {
+    llvm::FoldingSetNodeID ID;
+    ID.AddPointer(Val.File);
+    ID.AddInteger(Val.Offset);
+    ID.AddInteger(Val.RemoveLen);
+    ID.AddString(Val.Text);
+    return ID.ComputeHash();
+  }
+  static bool isEqual(const EditEntry &LHS, const EditEntry &RHS) {
+    return LHS.File == RHS.File &&
+        LHS.Offset == RHS.Offset &&
+        LHS.RemoveLen == RHS.RemoveLen &&
+        LHS.Text == RHS.Text;
+  }
+};
+}
+
+namespace {
+class RemapFileParser {
+  FileManager &FileMgr;
+
+public:
+  RemapFileParser(FileManager &FileMgr) : FileMgr(FileMgr) { }
+
+  bool parse(StringRef File, SmallVectorImpl<EditEntry> &Entries) {
+    using namespace llvm::yaml;
+
+    llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr =
+        llvm::MemoryBuffer::getFile(File);
+    if (!FileBufOrErr)
+      return true;
+
+    llvm::SourceMgr SM;
+    Stream YAMLStream(FileBufOrErr.get().release(), SM);
+    document_iterator I = YAMLStream.begin();
+    if (I == YAMLStream.end())
+      return true;
+    Node *Root = I->getRoot();
+    if (!Root)
+      return true;
+
+    SequenceNode *SeqNode = dyn_cast<SequenceNode>(Root);
+    if (!SeqNode)
+      return true;
+
+    for (SequenceNode::iterator
+           AI = SeqNode->begin(), AE = SeqNode->end(); AI != AE; ++AI) {
+      MappingNode *MapNode = dyn_cast<MappingNode>(&*AI);
+      if (!MapNode)
+        continue;
+      parseEdit(MapNode, Entries);
+    }
+
+    return false;
+  }
+
+private:
+  void parseEdit(llvm::yaml::MappingNode *Node,
+                 SmallVectorImpl<EditEntry> &Entries) {
+    using namespace llvm::yaml;
+    EditEntry Entry;
+    bool Ignore = false;
+
+    for (MappingNode::iterator
+           KVI = Node->begin(), KVE = Node->end(); KVI != KVE; ++KVI) {
+      ScalarNode *KeyString = dyn_cast<ScalarNode>((*KVI).getKey());
+      if (!KeyString)
+        continue;
+      SmallString<10> KeyStorage;
+      StringRef Key = KeyString->getValue(KeyStorage);
+
+      ScalarNode *ValueString = dyn_cast<ScalarNode>((*KVI).getValue());
+      if (!ValueString)
+        continue;
+      SmallString<64> ValueStorage;
+      StringRef Val = ValueString->getValue(ValueStorage);
+
+      if (Key == "file") {
+        const FileEntry *FE = FileMgr.getFile(Val);
+        if (!FE)
+          Ignore = true;
+        Entry.File = FE;
+      } else if (Key == "offset") {
+        if (Val.getAsInteger(10, Entry.Offset))
+          Ignore = true;
+      } else if (Key == "remove") {
+        if (Val.getAsInteger(10, Entry.RemoveLen))
+          Ignore = true;
+      } else if (Key == "text") {
+        Entry.Text = Val;
+      }
+    }
+
+    if (!Ignore)
+      Entries.push_back(Entry);
+  }
+};
+}
+
+static bool reportDiag(const Twine &Err, DiagnosticsEngine &Diag) {
+  Diag.Report(Diag.getCustomDiagID(DiagnosticsEngine::Error, "%0"))
+      << Err.str();
+  return true;
+}
+
+static std::string applyEditsToTemp(const FileEntry *FE,
+                                    ArrayRef<EditEntry> Edits,
+                                    FileManager &FileMgr,
+                                    DiagnosticsEngine &Diag) {
+  using namespace llvm::sys;
+
+  SourceManager SM(Diag, FileMgr);
+  FileID FID = SM.createFileID(FE, SourceLocation(), SrcMgr::C_User);
+  LangOptions LangOpts;
+  edit::EditedSource Editor(SM, LangOpts);
+  for (ArrayRef<EditEntry>::iterator
+        I = Edits.begin(), E = Edits.end(); I != E; ++I) {
+    const EditEntry &Entry = *I;
+    assert(Entry.File == FE);
+    SourceLocation Loc =
+        SM.getLocForStartOfFile(FID).getLocWithOffset(Entry.Offset);
+    CharSourceRange Range;
+    if (Entry.RemoveLen != 0) {
+      Range = CharSourceRange::getCharRange(Loc,
+                                         Loc.getLocWithOffset(Entry.RemoveLen));
+    }
+
+    edit::Commit commit(Editor);
+    if (Range.isInvalid()) {
+      commit.insert(Loc, Entry.Text);
+    } else if (Entry.Text.empty()) {
+      commit.remove(Range);
+    } else {
+      commit.replace(Range, Entry.Text);
+    }
+    Editor.commit(commit);
+  }
+
+  Rewriter rewriter(SM, LangOpts);
+  RewritesReceiver Rec(rewriter);
+  Editor.applyRewrites(Rec);
+
+  const RewriteBuffer *Buf = rewriter.getRewriteBufferFor(FID);
+  SmallString<512> NewText;
+  llvm::raw_svector_ostream OS(NewText);
+  Buf->write(OS);
+  OS.flush();
+
+  SmallString<64> TempPath;
+  int FD;
+  if (fs::createTemporaryFile(path::filename(FE->getName()),
+                              path::extension(FE->getName()), FD,
+                              TempPath)) {
+    reportDiag("Could not create file: " + TempPath.str(), Diag);
+    return std::string();
+  }
+
+  llvm::raw_fd_ostream TmpOut(FD, /*shouldClose=*/true);
+  TmpOut.write(NewText.data(), NewText.size());
+  TmpOut.close();
+
+  return TempPath.str();
+}
+
+bool arcmt::getFileRemappingsFromFileList(
+                        std::vector<std::pair<std::string,std::string> > &remap,
+                        ArrayRef<StringRef> remapFiles,
+                        DiagnosticConsumer *DiagClient) {
+  bool hasErrorOccurred = false;
+
+  FileSystemOptions FSOpts;
+  FileManager FileMgr(FSOpts);
+  RemapFileParser Parser(FileMgr);
+
+  IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
+  IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
+      new DiagnosticsEngine(DiagID, new DiagnosticOptions,
+                            DiagClient, /*ShouldOwnClient=*/false));
+
+  typedef llvm::DenseMap<const FileEntry *, std::vector<EditEntry> >
+      FileEditEntriesTy;
+  FileEditEntriesTy FileEditEntries;
+
+  llvm::DenseSet<EditEntry> EntriesSet;
+
+  for (ArrayRef<StringRef>::iterator
+         I = remapFiles.begin(), E = remapFiles.end(); I != E; ++I) {
+    SmallVector<EditEntry, 16> Entries;
+    if (Parser.parse(*I, Entries))
+      continue;
+
+    for (SmallVectorImpl<EditEntry>::iterator
+           EI = Entries.begin(), EE = Entries.end(); EI != EE; ++EI) {
+      EditEntry &Entry = *EI;
+      if (!Entry.File)
+        continue;
+      std::pair<llvm::DenseSet<EditEntry>::iterator, bool>
+        Insert = EntriesSet.insert(Entry);
+      if (!Insert.second)
+        continue;
+
+      FileEditEntries[Entry.File].push_back(Entry);
+    }
+  }
+
+  for (FileEditEntriesTy::iterator
+         I = FileEditEntries.begin(), E = FileEditEntries.end(); I != E; ++I) {
+    std::string TempFile = applyEditsToTemp(I->first, I->second,
+                                            FileMgr, *Diags);
+    if (TempFile.empty()) {
+      hasErrorOccurred = true;
+      continue;
+    }
+
+    remap.push_back(std::make_pair(I->first->getName(), TempFile));
+  }
+
+  return hasErrorOccurred;
+}
diff --git a/lib/ARCMigrate/PlistReporter.cpp b/lib/ARCMigrate/PlistReporter.cpp
index 144ba2e..6b34ef0 100644
--- a/lib/ARCMigrate/PlistReporter.cpp
+++ b/lib/ARCMigrate/PlistReporter.cpp
@@ -9,86 +9,27 @@
 
 #include "Internals.h"
 #include "clang/Basic/FileManager.h"
+#include "clang/Basic/PlistSupport.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Lex/Lexer.h"
 using namespace clang;
 using namespace arcmt;
+using namespace markup;
 
-// FIXME: This duplicates significant functionality from PlistDiagnostics.cpp,
-// it would be jolly good if there was a reusable PlistWriter or something.
-
-typedef llvm::DenseMap<FileID, unsigned> FIDMap;
-
-static void AddFID(FIDMap &FIDs, SmallVectorImpl<FileID> &V,
-                   const SourceManager &SM, SourceLocation L) {
-
-  FileID FID = SM.getFileID(SM.getExpansionLoc(L));
-  FIDMap::iterator I = FIDs.find(FID);
-  if (I != FIDs.end()) return;
-  FIDs[FID] = V.size();
-  V.push_back(FID);
-}
-
-static unsigned GetFID(const FIDMap& FIDs, const SourceManager &SM,
-                       SourceLocation L) {
-  FileID FID = SM.getFileID(SM.getExpansionLoc(L));
-  FIDMap::const_iterator I = FIDs.find(FID);
-  assert(I != FIDs.end());
-  return I->second;
-}
-
-static raw_ostream& Indent(raw_ostream& o, const unsigned indent) {
-  for (unsigned i = 0; i < indent; ++i) o << ' ';
-  return o;
-}
-
-static void EmitLocation(raw_ostream& o, const SourceManager &SM,
-                         const LangOptions &LangOpts,
-                         SourceLocation L, const FIDMap &FM,
-                         unsigned indent, bool extend = false) {
-
-  FullSourceLoc Loc(SM.getExpansionLoc(L), const_cast<SourceManager&>(SM));
-
-  // Add in the length of the token, so that we cover multi-char tokens.
-  unsigned offset =
-    extend ? Lexer::MeasureTokenLength(Loc, SM, LangOpts) - 1 : 0;
-
-  Indent(o, indent) << "<dict>\n";
-  Indent(o, indent) << " <key>line</key><integer>"
-                    << Loc.getExpansionLineNumber() << "</integer>\n";
-  Indent(o, indent) << " <key>col</key><integer>"
-                    << Loc.getExpansionColumnNumber() + offset << "</integer>\n";
-  Indent(o, indent) << " <key>file</key><integer>"
-                    << GetFID(FM, SM, Loc) << "</integer>\n";
-  Indent(o, indent) << "</dict>\n";
-}
-
-static void EmitRange(raw_ostream& o, const SourceManager &SM,
-                      const LangOptions &LangOpts,
-                      CharSourceRange R, const FIDMap &FM,
-                      unsigned indent) {
-  Indent(o, indent) << "<array>\n";
-  EmitLocation(o, SM, LangOpts, R.getBegin(), FM, indent+1);
-  EmitLocation(o, SM, LangOpts, R.getEnd(), FM, indent+1, R.isTokenRange());
-  Indent(o, indent) << "</array>\n";
-}
-
-static raw_ostream& EmitString(raw_ostream& o,
-                                     StringRef s) {
-  o << "<string>";
-  for (StringRef::const_iterator I=s.begin(), E=s.end(); I!=E; ++I) {
-    char c = *I;
-    switch (c) {
-    default:   o << c; break;
-    case '&':  o << "&amp;"; break;
-    case '<':  o << "&lt;"; break;
-    case '>':  o << "&gt;"; break;
-    case '\'': o << "&apos;"; break;
-    case '\"': o << "&quot;"; break;
-    }
+static StringRef getLevelName(DiagnosticsEngine::Level Level) {
+  switch (Level) {
+  case DiagnosticsEngine::Ignored:
+    llvm_unreachable("ignored");
+  case DiagnosticsEngine::Note:
+    return "note";
+  case DiagnosticsEngine::Remark:
+  case DiagnosticsEngine::Warning:
+    return "warning";
+  case DiagnosticsEngine::Fatal:
+  case DiagnosticsEngine::Error:
+    return "error";
   }
-  o << "</string>";
-  return o;
+  llvm_unreachable("Invalid DiagnosticsEngine level!");
 }
 
 void arcmt::writeARCDiagsToPlist(const std::string &outPath,
@@ -116,17 +57,13 @@
   }
 
   std::string errMsg;
-  llvm::raw_fd_ostream o(outPath.c_str(), errMsg);
+  llvm::raw_fd_ostream o(outPath.c_str(), errMsg, llvm::sys::fs::F_Text);
   if (!errMsg.empty()) {
     llvm::errs() << "error: could not create file: " << outPath << '\n';
     return;
   }
 
-  // Write the plist header.
-  o << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
-  "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" "
-  "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
-  "<plist version=\"1.0\">\n";
+  EmitPlistHeader(o);
 
   // Write the root object: a <dict> containing...
   //  - "files", an <array> mapping from FIDs to file names
@@ -135,11 +72,8 @@
        " <key>files</key>\n"
        " <array>\n";
 
-  for (SmallVectorImpl<FileID>::iterator I=Fids.begin(), E=Fids.end();
-       I!=E; ++I) {
-    o << "  ";
-    EmitString(o, SM.getFileEntryForID(*I)->getName()) << '\n';
-  }
+  for (FileID FID : Fids)
+    EmitString(o << "  ", SM.getFileEntryForID(FID)->getName()) << '\n';
 
   o << " </array>\n"
        " <key>diagnostics</key>\n"
@@ -162,12 +96,7 @@
     EmitString(o, DiagIDs.getCategoryNameFromID(
                           DiagIDs.getCategoryNumberForDiag(D.getID()))) << '\n';
     o << "   <key>type</key>";
-    if (D.getLevel() >= DiagnosticsEngine::Error)
-      EmitString(o, "error") << '\n';
-    else if (D.getLevel() == DiagnosticsEngine::Warning)
-      EmitString(o, "warning") << '\n';
-    else
-      EmitString(o, "note") << '\n';
+    EmitString(o, getLevelName(D.getLevel())) << '\n';
 
     // Output the location of the bug.
     o << "  <key>location</key>\n";
diff --git a/lib/ARCMigrate/TransAPIUses.cpp b/lib/ARCMigrate/TransAPIUses.cpp
index a0994a6..544cb0a 100644
--- a/lib/ARCMigrate/TransAPIUses.cpp
+++ b/lib/ARCMigrate/TransAPIUses.cpp
@@ -66,8 +66,7 @@
         selName = "getArgument";
       else if (E->getSelector() == setArgumentSel)
         selName = "setArgument";
-
-      if (selName.empty())
+      else
         return true;
 
       Expr *parm = E->getArg(0)->IgnoreParenCasts();
@@ -75,13 +74,12 @@
       if (pointee.isNull())
         return true;
 
-      if (pointee.getObjCLifetime() > Qualifiers::OCL_ExplicitNone) {
-        std::string err = "NSInvocation's ";
-        err += selName;
-        err += " is not safe to be used with an object with ownership other "
-            "than __unsafe_unretained";
-        Pass.TA.reportError(err, parm->getLocStart(), parm->getSourceRange());
-      }
+      if (pointee.getObjCLifetime() > Qualifiers::OCL_ExplicitNone)
+        Pass.TA.report(parm->getLocStart(),
+                       diag::err_arcmt_nsinvocation_ownership,
+                       parm->getSourceRange())
+            << selName;
+
       return true;
     }
 
diff --git a/lib/ARCMigrate/TransAutoreleasePool.cpp b/lib/ARCMigrate/TransAutoreleasePool.cpp
index a2990e7..a8a99fa 100644
--- a/lib/ARCMigrate/TransAutoreleasePool.cpp
+++ b/lib/ARCMigrate/TransAutoreleasePool.cpp
@@ -70,7 +70,7 @@
                          : public RecursiveASTVisitor<AutoreleasePoolRewriter> {
 public:
   AutoreleasePoolRewriter(MigrationPass &pass)
-    : Body(0), Pass(pass) {
+    : Body(nullptr), Pass(pass) {
     PoolII = &pass.Ctx.Idents.get("NSAutoreleasePool");
     DrainSel = pass.Ctx.Selectors.getNullarySelector(
                                                  &pass.Ctx.Idents.get("drain"));
@@ -230,7 +230,7 @@
     bool IsFollowedBySimpleReturnStmt;
     SmallVector<ObjCMessageExpr *, 4> Releases;
 
-    PoolScope() : PoolVar(0), CompoundParent(0), Begin(), End(),
+    PoolScope() : PoolVar(nullptr), CompoundParent(nullptr), Begin(), End(),
                   IsFollowedBySimpleReturnStmt(false) { }
 
     SourceRange getIndentedRange() const {
@@ -305,7 +305,7 @@
       // statement, in which case we will include the return in the scope.
       if (SI != SE)
         if (ReturnStmt *retS = dyn_cast<ReturnStmt>(*SI))
-          if ((retS->getRetValue() == 0 ||
+          if ((retS->getRetValue() == nullptr ||
                isa<DeclRefExpr>(retS->getRetValue()->IgnoreParenCasts())) &&
               findLocationAfterSemi(retS->getLocEnd(), Pass.Ctx).isValid()) {
             scope.IsFollowedBySimpleReturnStmt = true;
@@ -421,7 +421,7 @@
     ExprSet Refs;
     SmallVector<PoolScope, 2> Scopes;
 
-    PoolVarInfo() : Dcl(0) { }
+    PoolVarInfo() : Dcl(nullptr) { }
   };
 
   std::map<VarDecl *, PoolVarInfo> PoolVars;
diff --git a/lib/ARCMigrate/TransBlockObjCVariable.cpp b/lib/ARCMigrate/TransBlockObjCVariable.cpp
index 97c4e34..fac6a84 100644
--- a/lib/ARCMigrate/TransBlockObjCVariable.cpp
+++ b/lib/ARCMigrate/TransBlockObjCVariable.cpp
@@ -78,10 +78,9 @@
   bool VisitBlockDecl(BlockDecl *block) {
     SmallVector<VarDecl *, 4> BlockVars;
     
-    for (BlockDecl::capture_iterator
-           I = block->capture_begin(), E = block->capture_end(); I != E; ++I) {
-      VarDecl *var = I->getVariable();
-      if (I->isByRef() &&
+    for (const auto &I : block->captures()) {
+      VarDecl *var = I.getVariable();
+      if (I.isByRef() &&
           var->getType()->isObjCObjectPointerType() &&
           isImplicitStrong(var->getType())) {
         BlockVars.push_back(var);
diff --git a/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp b/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp
index ffb638f..9689f40 100644
--- a/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp
+++ b/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp
@@ -89,9 +89,8 @@
   bool VisitCompoundStmt(CompoundStmt *S) {
     if (S->body_empty())
       return false; // was already empty, not because of transformations.
-    for (CompoundStmt::body_iterator
-           I = S->body_begin(), E = S->body_end(); I != E; ++I)
-      if (!Visit(*I))
+    for (auto *I : S->body())
+      if (!Visit(I))
         return false;
     return true;
   }
@@ -167,9 +166,8 @@
   }
 
   bool VisitCompoundStmt(CompoundStmt *S) {
-    for (CompoundStmt::body_iterator
-           I = S->body_begin(), E = S->body_end(); I != E; ++I)
-      check(*I);
+    for (auto *I : S->body())
+      check(I);
     return true;
   }
 
@@ -189,9 +187,8 @@
 
 static bool isBodyEmpty(CompoundStmt *body, ASTContext &Ctx,
                         std::vector<SourceLocation> &MacroLocs) {
-  for (CompoundStmt::body_iterator
-         I = body->body_begin(), E = body->body_end(); I != E; ++I)
-    if (!EmptyChecker(Ctx, MacroLocs).Visit(*I))
+  for (auto *I : body->body())
+    if (!EmptyChecker(Ctx, MacroLocs).Visit(I))
       return false;
 
   return true;
@@ -208,12 +205,9 @@
     impl_iterator;
   for (impl_iterator I = impl_iterator(DC->decls_begin()),
                      E = impl_iterator(DC->decls_end()); I != E; ++I) {
-    ObjCMethodDecl *DeallocM = 0;
-    ObjCMethodDecl *FinalizeM = 0;
-    for (ObjCImplementationDecl::instmeth_iterator
-           MI = I->instmeth_begin(),
-           ME = I->instmeth_end(); MI != ME; ++MI) {
-      ObjCMethodDecl *MD = *MI;
+    ObjCMethodDecl *DeallocM = nullptr;
+    ObjCMethodDecl *FinalizeM = nullptr;
+    for (auto *MD : I->instance_methods()) {
       if (!MD->hasBody())
         continue;
   
diff --git a/lib/ARCMigrate/TransGCAttrs.cpp b/lib/ARCMigrate/TransGCAttrs.cpp
index d8be1ae..10fce19 100644
--- a/lib/ARCMigrate/TransGCAttrs.cpp
+++ b/lib/ARCMigrate/TransGCAttrs.cpp
@@ -80,7 +80,7 @@
     }
   }
 
-  bool handleAttr(AttributedTypeLoc TL, Decl *D = 0) {
+  bool handleAttr(AttributedTypeLoc TL, Decl *D = nullptr) {
     if (TL.getAttrKind() != AttributedType::attr_objc_ownership)
       return false;
 
@@ -134,8 +134,7 @@
       return hasObjCImpl(ContD);
 
     if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
-      for (CXXRecordDecl::method_iterator
-             MI = RD->method_begin(), ME = RD->method_end(); MI != ME; ++MI) {
+      for (const auto *MI : RD->methods()) {
         if (MI->isOutOfLine())
           return true;
       }
@@ -150,9 +149,9 @@
       return false;
     if (ObjCContainerDecl *ContD = dyn_cast<ObjCContainerDecl>(D)) {
       if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(ContD))
-        return ID->getImplementation() != 0;
+        return ID->getImplementation() != nullptr;
       if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(ContD))
-        return CD->getImplementation() != 0;
+        return CD->getImplementation() != nullptr;
       if (isa<ObjCImplDecl>(ContD))
         return true;
       return false;
@@ -164,8 +163,7 @@
     if (!D)
       return false;
 
-    for (Decl::redecl_iterator
-           I = D->redecls_begin(), E = D->redecls_end(); I != E; ++I)
+    for (auto I : D->redecls())
       if (!isInMainFile(I->getLocation()))
         return false;
     
diff --git a/lib/ARCMigrate/TransGCCalls.cpp b/lib/ARCMigrate/TransGCCalls.cpp
index 249f20f..3a236d3 100644
--- a/lib/ARCMigrate/TransGCCalls.cpp
+++ b/lib/ARCMigrate/TransGCCalls.cpp
@@ -38,14 +38,8 @@
     TransformActions &TA = MigrateCtx.Pass.TA;
 
     if (MigrateCtx.isGCOwnedNonObjC(E->getType())) {
-      if (MigrateCtx.Pass.noNSAllocReallocError())
-        TA.reportWarning("call returns pointer to GC managed memory; "
-                       "it will become unmanaged in ARC",
-                       E->getLocStart(), E->getSourceRange());
-      else 
-        TA.reportError("call returns pointer to GC managed memory; "
-                       "it will become unmanaged in ARC",
-                       E->getLocStart(), E->getSourceRange());
+      TA.report(E->getLocStart(), diag::warn_arcmt_nsalloc_realloc,
+                E->getSourceRange());
       return true;
     }
 
diff --git a/lib/ARCMigrate/TransProperties.cpp b/lib/ARCMigrate/TransProperties.cpp
index b6ddc43..ab12884 100644
--- a/lib/ARCMigrate/TransProperties.cpp
+++ b/lib/ARCMigrate/TransProperties.cpp
@@ -61,7 +61,8 @@
     ObjCIvarDecl *IvarD;
     ObjCPropertyImplDecl *ImplD;
 
-    PropData(ObjCPropertyDecl *propD) : PropD(propD), IvarD(0), ImplD(0) { }
+    PropData(ObjCPropertyDecl *propD)
+      : PropD(propD), IvarD(nullptr), ImplD(nullptr) {}
   };
 
   typedef SmallVector<PropData, 2> PropsTy;
@@ -74,18 +75,16 @@
     : MigrateCtx(MigrateCtx), Pass(MigrateCtx.Pass) { }
 
   static void collectProperties(ObjCContainerDecl *D, AtPropDeclsTy &AtProps,
-                                AtPropDeclsTy *PrevAtProps = 0) {
-    for (ObjCInterfaceDecl::prop_iterator
-           propI = D->prop_begin(),
-           propE = D->prop_end(); propI != propE; ++propI) {
-      if (propI->getAtLoc().isInvalid())
+                                AtPropDeclsTy *PrevAtProps = nullptr) {
+    for (auto *Prop : D->properties()) {
+      if (Prop->getAtLoc().isInvalid())
         continue;
-      unsigned RawLoc = propI->getAtLoc().getRawEncoding();
+      unsigned RawLoc = Prop->getAtLoc().getRawEncoding();
       if (PrevAtProps)
         if (PrevAtProps->find(RawLoc) != PrevAtProps->end())
           continue;
       PropsTy &props = AtProps[RawLoc];
-      props.push_back(*propI);
+      props.push_back(Prop);
     }
   }
 
@@ -141,12 +140,8 @@
 
     AtPropDeclsTy AtExtProps;
     // Look through extensions.
-    for (ObjCInterfaceDecl::visible_extensions_iterator
-           ext = iface->visible_extensions_begin(),
-           extEnd = iface->visible_extensions_end();
-         ext != extEnd; ++ext) {
-      collectProperties(*ext, AtExtProps, &AtProps);
-    }
+    for (auto *Ext : iface->visible_extensions())
+      collectProperties(Ext, AtExtProps, &AtProps);
 
     for (AtPropDeclsTy::iterator
            I = AtExtProps.begin(), E = AtExtProps.end(); I != E; ++I) {
@@ -353,14 +348,6 @@
     return false;    
   }
 
-  bool hasAllIvarsBacked(PropsTy &props) const {
-    for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I)
-      if (!isUserDeclared(I->IvarD))
-        return false;
-
-    return true;
-  }
-
   // \brief Returns true if all declarations in the @property have GC __weak.
   bool hasGCWeak(PropsTy &props, SourceLocation atLoc) const {
     if (!Pass.isGCMigration())
diff --git a/lib/ARCMigrate/TransProtectedScope.cpp b/lib/ARCMigrate/TransProtectedScope.cpp
index 237aa42..0fcbcbe 100644
--- a/lib/ARCMigrate/TransProtectedScope.cpp
+++ b/lib/ARCMigrate/TransProtectedScope.cpp
@@ -47,7 +47,7 @@
     St_Fixed
   } State;
   
-  CaseInfo() : SC(0), State(St_Unchecked) {}
+  CaseInfo() : SC(nullptr), State(St_Unchecked) {}
   CaseInfo(SwitchCase *S, SourceRange Range)
     : SC(S), Range(Range), State(St_Unchecked) {}
 };
diff --git a/lib/ARCMigrate/TransRetainReleaseDealloc.cpp b/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
index 446a284..bcbc9e9 100644
--- a/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
+++ b/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
@@ -38,13 +38,13 @@
   MigrationPass &Pass;
 
   ExprSet Removables;
-  OwningPtr<ParentMap> StmtMap;
+  std::unique_ptr<ParentMap> StmtMap;
 
   Selector DelegateSel, FinalizeSel;
 
 public:
   RetainReleaseDeallocRemover(MigrationPass &pass)
-    : Body(0), Pass(pass) {
+    : Body(nullptr), Pass(pass) {
     DelegateSel =
         Pass.Ctx.Selectors.getNullarySelector(&Pass.Ctx.Idents.get("delegate"));
     FinalizeSel =
@@ -70,7 +70,7 @@
           // An unused autorelease is badness. If we remove it the receiver
           // will likely die immediately while previously it was kept alive
           // by the autorelease pool. This is bad practice in general, leave it
-          // and emit an error to force the user to restructure his code.
+          // and emit an error to force the user to restructure their code.
           Pass.TA.reportError("it is not safe to remove an unused 'autorelease' "
               "message; its receiver may be destroyed immediately",
               E->getLocStart(), E->getSourceRange());
@@ -212,7 +212,7 @@
       return false;
 
     Stmt *prevStmt, *nextStmt;
-    llvm::tie(prevStmt, nextStmt) = getPreviousAndNextStmt(E);
+    std::tie(prevStmt, nextStmt) = getPreviousAndNextStmt(E);
 
     return isPlusOneAssignToVar(prevStmt, RefD) ||
            isPlusOneAssignToVar(nextStmt, RefD);
@@ -248,7 +248,7 @@
   }
 
   std::pair<Stmt *, Stmt *> getPreviousAndNextStmt(Expr *E) {
-    Stmt *prevStmt = 0, *nextStmt = 0;
+    Stmt *prevStmt = nullptr, *nextStmt = nullptr;
     if (!E)
       return std::make_pair(prevStmt, nextStmt);
 
@@ -294,7 +294,7 @@
 
   Decl *getReferencedDecl(Expr *E) {
     if (!E)
-      return 0;
+      return nullptr;
 
     E = E->IgnoreParenCasts();
     if (ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E)) {
@@ -305,7 +305,7 @@
       case OMF_retain:
         return getReferencedDecl(ME->getInstanceReceiver());
       default:
-        return 0;
+        return nullptr;
       }
     }
     if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
@@ -315,7 +315,7 @@
     if (ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(E))
       return IRE->getDecl();
 
-    return 0;
+    return nullptr;
   }
 
   /// \brief Check if the retain/release is due to a GCD/XPC macro that are
@@ -345,7 +345,7 @@
     if (!isGCDOrXPC)
       return;
 
-    StmtExpr *StmtE = 0;
+    StmtExpr *StmtE = nullptr;
     Stmt *S = Msg;
     while (S) {
       if (StmtExpr *SE = dyn_cast<StmtExpr>(S)) {
diff --git a/lib/ARCMigrate/TransUnbridgedCasts.cpp b/lib/ARCMigrate/TransUnbridgedCasts.cpp
index 7b360c6..7ca4955 100644
--- a/lib/ARCMigrate/TransUnbridgedCasts.cpp
+++ b/lib/ARCMigrate/TransUnbridgedCasts.cpp
@@ -60,13 +60,14 @@
 class UnbridgedCastRewriter : public RecursiveASTVisitor<UnbridgedCastRewriter>{
   MigrationPass &Pass;
   IdentifierInfo *SelfII;
-  OwningPtr<ParentMap> StmtMap;
+  std::unique_ptr<ParentMap> StmtMap;
   Decl *ParentD;
   Stmt *Body;
-  mutable OwningPtr<ExprSet> Removables;
+  mutable std::unique_ptr<ExprSet> Removables;
 
 public:
-  UnbridgedCastRewriter(MigrationPass &pass) : Pass(pass), ParentD(0), Body(0) {
+  UnbridgedCastRewriter(MigrationPass &pass)
+    : Pass(pass), ParentD(nullptr), Body(nullptr) {
     SelfII = &Pass.Ctx.Idents.get("self");
   }
 
@@ -133,11 +134,11 @@
     Expr *inner = E->IgnoreParenCasts();
     if (CallExpr *callE = dyn_cast<CallExpr>(inner)) {
       if (FunctionDecl *FD = callE->getDirectCallee()) {
-        if (FD->getAttr<CFReturnsRetainedAttr>()) {
+        if (FD->hasAttr<CFReturnsRetainedAttr>()) {
           castToObjCObject(E, /*retained=*/true);
           return;
         }
-        if (FD->getAttr<CFReturnsNotRetainedAttr>()) {
+        if (FD->hasAttr<CFReturnsNotRetainedAttr>()) {
           castToObjCObject(E, /*retained=*/false);
           return;
         }
@@ -283,7 +284,7 @@
     SourceLocation Loc = E->getExprLoc();
     assert(Loc.isMacroID());
     SourceLocation MacroBegin, MacroEnd;
-    llvm::tie(MacroBegin, MacroEnd) = SM.getImmediateExpansionRange(Loc);
+    std::tie(MacroBegin, MacroEnd) = SM.getImmediateExpansionRange(Loc);
     SourceRange SubRange = E->getSubExpr()->IgnoreParenImpCasts()->getSourceRange();
     SourceLocation InnerBegin = SM.getImmediateMacroCallerLoc(SubRange.getBegin());
     SourceLocation InnerEnd = SM.getImmediateMacroCallerLoc(SubRange.getEnd());
@@ -439,7 +440,7 @@
         }
         if (i < callE->getNumArgs() && i < FD->getNumParams()) {
           ParmVarDecl *PD = FD->getParamDecl(i);
-          if (PD->getAttr<CFConsumedAttr>()) {
+          if (PD->hasAttr<CFConsumedAttr>()) {
             isConsumed = true;
             return true;
           }
diff --git a/lib/ARCMigrate/TransUnusedInitDelegate.cpp b/lib/ARCMigrate/TransUnusedInitDelegate.cpp
index e316c73..98571c0 100644
--- a/lib/ARCMigrate/TransUnusedInitDelegate.cpp
+++ b/lib/ARCMigrate/TransUnusedInitDelegate.cpp
@@ -39,7 +39,7 @@
 
 public:
   UnusedInitRewriter(MigrationPass &pass)
-    : Body(0), Pass(pass) { }
+    : Body(nullptr), Pass(pass) { }
 
   void transformBody(Stmt *body, Decl *ParentD) {
     Body = body;
diff --git a/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp b/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp
index 4d088e0..76ce0ec 100644
--- a/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp
+++ b/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp
@@ -35,7 +35,7 @@
   Selector FinalizeSel;
 
 public:
-  ZeroOutInDeallocRemover(MigrationPass &pass) : Pass(pass), SelfD(0) {
+  ZeroOutInDeallocRemover(MigrationPass &pass) : Pass(pass), SelfD(nullptr) {
     FinalizeSel =
         Pass.Ctx.Selectors.getNullarySelector(&Pass.Ctx.Idents.get("finalize"));
   }
@@ -113,23 +113,21 @@
 
     // For a 'dealloc' method use, find all property implementations in
     // this class implementation.
-    for (ObjCImplDecl::propimpl_iterator
-           I = IMD->propimpl_begin(), EI = IMD->propimpl_end(); I != EI; ++I) {
-        ObjCPropertyImplDecl *PID = *I;
-        if (PID->getPropertyImplementation() ==
-            ObjCPropertyImplDecl::Synthesize) {
-          ObjCPropertyDecl *PD = PID->getPropertyDecl();
-          ObjCMethodDecl *setterM = PD->getSetterMethodDecl();
-          if (!(setterM && setterM->isDefined())) {
-            ObjCPropertyDecl::PropertyAttributeKind AttrKind = 
-              PD->getPropertyAttributes();
-              if (AttrKind & 
-                  (ObjCPropertyDecl::OBJC_PR_retain | 
-                   ObjCPropertyDecl::OBJC_PR_copy   |
-                   ObjCPropertyDecl::OBJC_PR_strong))
-                SynthesizedProperties[PD] = PID;
-          }
+    for (auto *PID : IMD->property_impls()) {
+      if (PID->getPropertyImplementation() ==
+          ObjCPropertyImplDecl::Synthesize) {
+        ObjCPropertyDecl *PD = PID->getPropertyDecl();
+        ObjCMethodDecl *setterM = PD->getSetterMethodDecl();
+        if (!(setterM && setterM->isDefined())) {
+          ObjCPropertyDecl::PropertyAttributeKind AttrKind = 
+            PD->getPropertyAttributes();
+            if (AttrKind & 
+                (ObjCPropertyDecl::OBJC_PR_retain | 
+                  ObjCPropertyDecl::OBJC_PR_copy   |
+                  ObjCPropertyDecl::OBJC_PR_strong))
+              SynthesizedProperties[PD] = PID;
         }
+      }
     }
 
     // Now, remove all zeroing of ivars etc.
@@ -137,7 +135,7 @@
 
     // clear out for next method.
     SynthesizedProperties.clear();
-    SelfD = 0;
+    SelfD = nullptr;
     Removables.clear();
     return true;
   }
diff --git a/lib/ARCMigrate/TransformActions.cpp b/lib/ARCMigrate/TransformActions.cpp
index 2fd0619..6d178be 100644
--- a/lib/ARCMigrate/TransformActions.cpp
+++ b/lib/ARCMigrate/TransformActions.cpp
@@ -601,7 +601,7 @@
 TransformActions::TransformActions(DiagnosticsEngine &diag,
                                    CapturedDiagList &capturedDiags,
                                    ASTContext &ctx, Preprocessor &PP)
-  : Diags(diag), CapturedDiags(capturedDiags), ReportedErrors(false) {
+    : Diags(diag), CapturedDiags(capturedDiags) {
   Impl = new TransformActionsImpl(capturedDiags, ctx, PP);
 }
 
@@ -673,60 +673,24 @@
   static_cast<TransformActionsImpl*>(Impl)->applyRewrites(receiver);
 }
 
-void TransformActions::reportError(StringRef error, SourceLocation loc,
-                                   SourceRange range) {
-  assert(!static_cast<TransformActionsImpl*>(Impl)->isInTransaction() &&
+DiagnosticBuilder TransformActions::report(SourceLocation loc, unsigned diagId,
+                                           SourceRange range) {
+  assert(!static_cast<TransformActionsImpl *>(Impl)->isInTransaction() &&
          "Errors should be emitted out of a transaction");
-
-  SourceManager &SM = static_cast<TransformActionsImpl*>(Impl)->
-                                             getASTContext().getSourceManager();
-  if (SM.isInSystemHeader(SM.getExpansionLoc(loc)))
-    return;
-
-  // FIXME: Use a custom category name to distinguish rewriter errors.
-  std::string rewriteErr = "[rewriter] ";
-  rewriteErr += error;
-  unsigned diagID
-     = Diags.getDiagnosticIDs()->getCustomDiagID(DiagnosticIDs::Error,
-                                                 rewriteErr);
-  Diags.Report(loc, diagID) << range;
-  ReportedErrors = true;
+  return Diags.Report(loc, diagId) << range;
 }
 
-void TransformActions::reportWarning(StringRef warning, SourceLocation loc,
+void TransformActions::reportError(StringRef message, SourceLocation loc,
                                    SourceRange range) {
-  assert(!static_cast<TransformActionsImpl*>(Impl)->isInTransaction() &&
-         "Warning should be emitted out of a transaction");
-  
-  SourceManager &SM = static_cast<TransformActionsImpl*>(Impl)->
-    getASTContext().getSourceManager();
-  if (SM.isInSystemHeader(SM.getExpansionLoc(loc)))
-    return;
-  
-  // FIXME: Use a custom category name to distinguish rewriter errors.
-  std::string rewriterWarn = "[rewriter] ";
-  rewriterWarn += warning;
-  unsigned diagID
-  = Diags.getDiagnosticIDs()->getCustomDiagID(DiagnosticIDs::Warning,
-                                              rewriterWarn);
-  Diags.Report(loc, diagID) << range;
+  report(loc, diag::err_mt_message, range) << message;
 }
 
-void TransformActions::reportNote(StringRef note, SourceLocation loc,
+void TransformActions::reportWarning(StringRef message, SourceLocation loc,
+                                     SourceRange range) {
+  report(loc, diag::warn_mt_message, range) << message;
+}
+
+void TransformActions::reportNote(StringRef message, SourceLocation loc,
                                   SourceRange range) {
-  assert(!static_cast<TransformActionsImpl*>(Impl)->isInTransaction() &&
-         "Errors should be emitted out of a transaction");
-
-  SourceManager &SM = static_cast<TransformActionsImpl*>(Impl)->
-                                             getASTContext().getSourceManager();
-  if (SM.isInSystemHeader(SM.getExpansionLoc(loc)))
-    return;
-
-  // FIXME: Use a custom category name to distinguish rewriter errors.
-  std::string rewriteNote = "[rewriter] ";
-  rewriteNote += note;
-  unsigned diagID
-     = Diags.getDiagnosticIDs()->getCustomDiagID(DiagnosticIDs::Note,
-                                                 rewriteNote);
-  Diags.Report(loc, diagID) << range;
+  report(loc, diag::note_mt_message, range) << message;
 }
diff --git a/lib/ARCMigrate/Transforms.cpp b/lib/ARCMigrate/Transforms.cpp
index 679b924..6ff7b6b 100644
--- a/lib/ARCMigrate/Transforms.cpp
+++ b/lib/ARCMigrate/Transforms.cpp
@@ -88,7 +88,7 @@
   if (const CallExpr *
         callE = dyn_cast<CallExpr>(E->IgnoreParenCasts())) {
     if (const FunctionDecl *FD = callE->getDirectCallee()) {
-      if (FD->getAttr<CFReturnsRetainedAttr>())
+      if (FD->hasAttr<CFReturnsRetainedAttr>())
         return true;
 
       if (FD->isGlobal() &&
@@ -264,9 +264,8 @@
   }
   
   bool VisitCompoundStmt(CompoundStmt *S) {
-    for (CompoundStmt::body_iterator
-        I = S->body_begin(), E = S->body_end(); I != E; ++I)
-      mark(*I);
+    for (auto *I : S->body())
+      mark(I);
     return true;
   }
   
@@ -414,8 +413,7 @@
   if (tok.isNot(tok::at)) return false;
   lexer.LexFromRawLexer(tok);
   if (tok.isNot(tok::raw_identifier)) return false;
-  if (StringRef(tok.getRawIdentifierData(), tok.getLength())
-        != "property")
+  if (tok.getRawIdentifier() != "property")
     return false;
   lexer.LexFromRawLexer(tok);
   if (tok.isNot(tok::l_paren)) return false;
@@ -431,8 +429,7 @@
 
   while (1) {
     if (tok.isNot(tok::raw_identifier)) return false;
-    StringRef ident(tok.getRawIdentifierData(), tok.getLength());
-    if (ident == fromAttr) {
+    if (tok.getRawIdentifier() == fromAttr) {
       if (!toAttr.empty()) {
         Pass.TA.replaceText(tok.getLocation(), fromAttr, toAttr);
         return true;
@@ -497,8 +494,7 @@
   if (tok.isNot(tok::at)) return false;
   lexer.LexFromRawLexer(tok);
   if (tok.isNot(tok::raw_identifier)) return false;
-  if (StringRef(tok.getRawIdentifierData(), tok.getLength())
-        != "property")
+  if (tok.getRawIdentifier() != "property")
     return false;
   lexer.LexFromRawLexer(tok);
 
@@ -538,15 +534,12 @@
   impl_iterator;
   for (impl_iterator I = impl_iterator(DC->decls_begin()),
        E = impl_iterator(DC->decls_end()); I != E; ++I) {
-    for (ObjCImplementationDecl::instmeth_iterator
-         MI = I->instmeth_begin(),
-         ME = I->instmeth_end(); MI != ME; ++MI) {
-      ObjCMethodDecl *MD = *MI;
+    for (const auto *MD : I->instance_methods()) {
       if (!MD->hasBody())
         continue;
       
       if (MD->isInstanceMethod() && MD->getSelector() == FinalizeSel) {
-        ObjCMethodDecl *FinalizeM = MD;
+        const ObjCMethodDecl *FinalizeM = MD;
         Transaction Trans(TA);
         TA.insert(FinalizeM->getSourceRange().getBegin(), 
                   "#if !__has_feature(objc_arc)\n");
diff --git a/lib/ARCMigrate/Transforms.h b/lib/ARCMigrate/Transforms.h
index eab5e85..12551d2 100644
--- a/lib/ARCMigrate/Transforms.h
+++ b/lib/ARCMigrate/Transforms.h
@@ -127,29 +127,29 @@
 
 class PropertyRewriteTraverser : public ASTTraverser {
 public:
-  virtual void traverseObjCImplementation(ObjCImplementationContext &ImplCtx);
+  void traverseObjCImplementation(ObjCImplementationContext &ImplCtx) override;
 };
 
 class BlockObjCVariableTraverser : public ASTTraverser {
 public:
-  virtual void traverseBody(BodyContext &BodyCtx);
+  void traverseBody(BodyContext &BodyCtx) override;
 };
 
 class ProtectedScopeTraverser : public ASTTraverser {
 public:
-  virtual void traverseBody(BodyContext &BodyCtx);
+  void traverseBody(BodyContext &BodyCtx) override;
 };
 
 // GC transformations
 
 class GCAttrsTraverser : public ASTTraverser {
 public:
-  virtual void traverseTU(MigrationContext &MigrateCtx);
+  void traverseTU(MigrationContext &MigrateCtx) override;
 };
 
 class GCCollectableCallsTraverser : public ASTTraverser {
 public:
-  virtual void traverseBody(BodyContext &BodyCtx);
+  void traverseBody(BodyContext &BodyCtx) override;
 };
 
 //===----------------------------------------------------------------------===//
@@ -189,7 +189,7 @@
 
   typedef RecursiveASTVisitor<BodyTransform<BODY_TRANS> > base;
 public:
-  BodyTransform(MigrationPass &pass) : Pass(pass), ParentD(0) { }
+  BodyTransform(MigrationPass &pass) : Pass(pass), ParentD(nullptr) { }
 
   bool TraverseStmt(Stmt *rootS) {
     if (rootS)
diff --git a/lib/AST/APValue.cpp b/lib/AST/APValue.cpp
index 541836b..0fa0216 100644
--- a/lib/AST/APValue.cpp
+++ b/lib/AST/APValue.cpp
@@ -34,7 +34,7 @@
 
 struct APValue::LV : LVBase {
   static const unsigned InlinePathSpace =
-      (MaxSize - sizeof(LVBase)) / sizeof(LValuePathEntry);
+      (DataSize - sizeof(LVBase)) / sizeof(LValuePathEntry);
 
   /// Path - The sequence of base classes, fields and array indices to follow to
   /// walk from Base to the subobject. When performing GCC-style folding, there
@@ -75,7 +75,7 @@
 
 struct APValue::MemberPointerData : MemberPointerBase {
   static const unsigned InlinePathSpace =
-      (MaxSize - sizeof(MemberPointerBase)) / sizeof(const CXXRecordDecl*);
+      (DataSize - sizeof(MemberPointerBase)) / sizeof(const CXXRecordDecl*);
   typedef const CXXRecordDecl *PathElem;
   union {
     PathElem Path[InlinePathSpace];
@@ -117,7 +117,7 @@
   delete [] Elts;
 }
 
-APValue::UnionData::UnionData() : Field(0), Value(new APValue) {}
+APValue::UnionData::UnionData() : Field(nullptr), Value(new APValue) {}
 APValue::UnionData::~UnionData () {
   delete Value;
 }
@@ -136,7 +136,7 @@
     break;
   case Vector:
     MakeVector();
-    setVector(((const Vec *)(const char *)RHS.Data)->Elts,
+    setVector(((const Vec *)(const char *)RHS.Data.buffer)->Elts,
               RHS.getVectorLength());
     break;
   case ComplexInt:
@@ -188,27 +188,27 @@
 
 void APValue::DestroyDataAndMakeUninit() {
   if (Kind == Int)
-    ((APSInt*)(char*)Data)->~APSInt();
+    ((APSInt*)(char*)Data.buffer)->~APSInt();
   else if (Kind == Float)
-    ((APFloat*)(char*)Data)->~APFloat();
+    ((APFloat*)(char*)Data.buffer)->~APFloat();
   else if (Kind == Vector)
-    ((Vec*)(char*)Data)->~Vec();
+    ((Vec*)(char*)Data.buffer)->~Vec();
   else if (Kind == ComplexInt)
-    ((ComplexAPSInt*)(char*)Data)->~ComplexAPSInt();
+    ((ComplexAPSInt*)(char*)Data.buffer)->~ComplexAPSInt();
   else if (Kind == ComplexFloat)
-    ((ComplexAPFloat*)(char*)Data)->~ComplexAPFloat();
+    ((ComplexAPFloat*)(char*)Data.buffer)->~ComplexAPFloat();
   else if (Kind == LValue)
-    ((LV*)(char*)Data)->~LV();
+    ((LV*)(char*)Data.buffer)->~LV();
   else if (Kind == Array)
-    ((Arr*)(char*)Data)->~Arr();
+    ((Arr*)(char*)Data.buffer)->~Arr();
   else if (Kind == Struct)
-    ((StructData*)(char*)Data)->~StructData();
+    ((StructData*)(char*)Data.buffer)->~StructData();
   else if (Kind == Union)
-    ((UnionData*)(char*)Data)->~UnionData();
+    ((UnionData*)(char*)Data.buffer)->~UnionData();
   else if (Kind == MemberPointer)
-    ((MemberPointerData*)(char*)Data)->~MemberPointerData();
+    ((MemberPointerData*)(char*)Data.buffer)->~MemberPointerData();
   else if (Kind == AddrLabelDiff)
-    ((AddrLabelDiffData*)(char*)Data)->~AddrLabelDiffData();
+    ((AddrLabelDiffData*)(char*)Data.buffer)->~AddrLabelDiffData();
   Kind = Uninitialized;
 }
 
@@ -239,19 +239,20 @@
            "same size.");
     return getComplexIntReal().needsCleanup();
   case LValue:
-    return reinterpret_cast<const LV *>(Data)->hasPathPtr();
+    return reinterpret_cast<const LV *>(Data.buffer)->hasPathPtr();
   case MemberPointer:
-    return reinterpret_cast<const MemberPointerData *>(Data)->hasPathPtr();
+    return reinterpret_cast<const MemberPointerData *>(Data.buffer)
+        ->hasPathPtr();
   }
   llvm_unreachable("Unknown APValue kind!");
 }
 
 void APValue::swap(APValue &RHS) {
   std::swap(Kind, RHS.Kind);
-  char TmpData[MaxSize];
-  memcpy(TmpData, Data, MaxSize);
-  memcpy(Data, RHS.Data, MaxSize);
-  memcpy(RHS.Data, TmpData, MaxSize);
+  char TmpData[DataSize];
+  memcpy(TmpData, Data.buffer, DataSize);
+  memcpy(Data.buffer, RHS.Data.buffer, DataSize);
+  memcpy(RHS.Data.buffer, TmpData, DataSize);
 }
 
 void APValue::dump() const {
@@ -402,8 +403,13 @@
 
       if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>())
         Out << *VD;
-      else
-        Base.get<const Expr*>()->printPretty(Out, 0, Ctx.getPrintingPolicy());
+      else {
+        assert(Base.get<const Expr *>() != nullptr &&
+               "Expecting non-null Expr");
+        Base.get<const Expr*>()->printPretty(Out, nullptr,
+                                             Ctx.getPrintingPolicy());
+      }
+
       if (!O.isZero()) {
         Out << " + " << (O / S);
         if (IsReference)
@@ -424,12 +430,13 @@
       ElemTy = VD->getType();
     } else {
       const Expr *E = Base.get<const Expr*>();
-      E->printPretty(Out, 0, Ctx.getPrintingPolicy());
+      assert(E != nullptr && "Expecting non-null Expr");
+      E->printPretty(Out, nullptr, Ctx.getPrintingPolicy());
       ElemTy = E->getType();
     }
 
     ArrayRef<LValuePathEntry> Path = getLValuePath();
-    const CXXRecordDecl *CastToBase = 0;
+    const CXXRecordDecl *CastToBase = nullptr;
     for (unsigned I = 0, N = Path.size(); I != N; ++I) {
       if (ElemTy->getAs<RecordType>()) {
         // The lvalue refers to a class type, so the next path entry is a base
@@ -498,8 +505,7 @@
         First = false;
       }
     }
-    for (RecordDecl::field_iterator FI = RD->field_begin();
-         FI != RD->field_end(); ++FI) {
+    for (const auto *FI : RD->fields()) {
       if (!First)
         Out << ", ";
       if (FI->isUnnamedBitfield()) continue;
@@ -546,39 +552,39 @@
 
 const APValue::LValueBase APValue::getLValueBase() const {
   assert(isLValue() && "Invalid accessor");
-  return ((const LV*)(const void*)Data)->BaseAndIsOnePastTheEnd.getPointer();
+  return ((const LV*)(const void*)Data.buffer)->BaseAndIsOnePastTheEnd.getPointer();
 }
 
 bool APValue::isLValueOnePastTheEnd() const {
   assert(isLValue() && "Invalid accessor");
-  return ((const LV*)(const void*)Data)->BaseAndIsOnePastTheEnd.getInt();
+  return ((const LV*)(const void*)Data.buffer)->BaseAndIsOnePastTheEnd.getInt();
 }
 
 CharUnits &APValue::getLValueOffset() {
   assert(isLValue() && "Invalid accessor");
-  return ((LV*)(void*)Data)->Offset;
+  return ((LV*)(void*)Data.buffer)->Offset;
 }
 
 bool APValue::hasLValuePath() const {
   assert(isLValue() && "Invalid accessor");
-  return ((const LV*)(const char*)Data)->hasPath();
+  return ((const LV*)(const char*)Data.buffer)->hasPath();
 }
 
 ArrayRef<APValue::LValuePathEntry> APValue::getLValuePath() const {
   assert(isLValue() && hasLValuePath() && "Invalid accessor");
-  const LV &LVal = *((const LV*)(const char*)Data);
+  const LV &LVal = *((const LV*)(const char*)Data.buffer);
   return ArrayRef<LValuePathEntry>(LVal.getPath(), LVal.PathLength);
 }
 
 unsigned APValue::getLValueCallIndex() const {
   assert(isLValue() && "Invalid accessor");
-  return ((const LV*)(const char*)Data)->CallIndex;
+  return ((const LV*)(const char*)Data.buffer)->CallIndex;
 }
 
 void APValue::setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
                         unsigned CallIndex) {
   assert(isLValue() && "Invalid accessor");
-  LV &LVal = *((LV*)(char*)Data);
+  LV &LVal = *((LV*)(char*)Data.buffer);
   LVal.BaseAndIsOnePastTheEnd.setPointer(B);
   LVal.BaseAndIsOnePastTheEnd.setInt(false);
   LVal.Offset = O;
@@ -590,7 +596,7 @@
                         ArrayRef<LValuePathEntry> Path, bool IsOnePastTheEnd,
                         unsigned CallIndex) {
   assert(isLValue() && "Invalid accessor");
-  LV &LVal = *((LV*)(char*)Data);
+  LV &LVal = *((LV*)(char*)Data.buffer);
   LVal.BaseAndIsOnePastTheEnd.setPointer(B);
   LVal.BaseAndIsOnePastTheEnd.setInt(IsOnePastTheEnd);
   LVal.Offset = O;
@@ -601,39 +607,42 @@
 
 const ValueDecl *APValue::getMemberPointerDecl() const {
   assert(isMemberPointer() && "Invalid accessor");
-  const MemberPointerData &MPD = *((const MemberPointerData*)(const char*)Data);
+  const MemberPointerData &MPD =
+      *((const MemberPointerData *)(const char *)Data.buffer);
   return MPD.MemberAndIsDerivedMember.getPointer();
 }
 
 bool APValue::isMemberPointerToDerivedMember() const {
   assert(isMemberPointer() && "Invalid accessor");
-  const MemberPointerData &MPD = *((const MemberPointerData*)(const char*)Data);
+  const MemberPointerData &MPD =
+      *((const MemberPointerData *)(const char *)Data.buffer);
   return MPD.MemberAndIsDerivedMember.getInt();
 }
 
 ArrayRef<const CXXRecordDecl*> APValue::getMemberPointerPath() const {
   assert(isMemberPointer() && "Invalid accessor");
-  const MemberPointerData &MPD = *((const MemberPointerData*)(const char*)Data);
+  const MemberPointerData &MPD =
+      *((const MemberPointerData *)(const char *)Data.buffer);
   return ArrayRef<const CXXRecordDecl*>(MPD.getPath(), MPD.PathLength);
 }
 
 void APValue::MakeLValue() {
   assert(isUninit() && "Bad state change");
-  assert(sizeof(LV) <= MaxSize && "LV too big");
-  new ((void*)(char*)Data) LV();
+  static_assert(sizeof(LV) <= DataSize, "LV too big");
+  new ((void*)(char*)Data.buffer) LV();
   Kind = LValue;
 }
 
 void APValue::MakeArray(unsigned InitElts, unsigned Size) {
   assert(isUninit() && "Bad state change");
-  new ((void*)(char*)Data) Arr(InitElts, Size);
+  new ((void*)(char*)Data.buffer) Arr(InitElts, Size);
   Kind = Array;
 }
 
 void APValue::MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
                                 ArrayRef<const CXXRecordDecl*> Path) {
   assert(isUninit() && "Bad state change");
-  MemberPointerData *MPD = new ((void*)(char*)Data) MemberPointerData;
+  MemberPointerData *MPD = new ((void*)(char*)Data.buffer) MemberPointerData;
   Kind = MemberPointer;
   MPD->MemberAndIsDerivedMember.setPointer(Member);
   MPD->MemberAndIsDerivedMember.setInt(IsDerivedMember);
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 4cca0c4..c139d0b 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -29,6 +29,7 @@
 #include "clang/AST/RecordLayout.h"
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/TypeLoc.h"
+#include "clang/AST/VTableBuilder.h"
 #include "clang/Basic/Builtins.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
@@ -62,6 +63,13 @@
 RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
   if (!CommentsLoaded && ExternalSource) {
     ExternalSource->ReadComments();
+
+#ifndef NDEBUG
+    ArrayRef<RawComment *> RawComments = Comments.getComments();
+    assert(std::is_sorted(RawComments.begin(), RawComments.end(),
+                          BeforeThanCompare<RawComment>(SourceMgr)));
+#endif
+
     CommentsLoaded = true;
   }
 
@@ -69,23 +77,23 @@
 
   // User can not attach documentation to implicit declarations.
   if (D->isImplicit())
-    return NULL;
+    return nullptr;
 
   // User can not attach documentation to implicit instantiations.
   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
     if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
-      return NULL;
+      return nullptr;
   }
 
   if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
     if (VD->isStaticDataMember() &&
         VD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
-      return NULL;
+      return nullptr;
   }
 
   if (const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(D)) {
     if (CRD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
-      return NULL;
+      return nullptr;
   }
 
   if (const ClassTemplateSpecializationDecl *CTSD =
@@ -93,35 +101,35 @@
     TemplateSpecializationKind TSK = CTSD->getSpecializationKind();
     if (TSK == TSK_ImplicitInstantiation ||
         TSK == TSK_Undeclared)
-      return NULL;
+      return nullptr;
   }
 
   if (const EnumDecl *ED = dyn_cast<EnumDecl>(D)) {
     if (ED->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
-      return NULL;
+      return nullptr;
   }
   if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
     // When tag declaration (but not definition!) is part of the
     // decl-specifier-seq of some other declaration, it doesn't get comment
     if (TD->isEmbeddedInDeclarator() && !TD->isCompleteDefinition())
-      return NULL;
+      return nullptr;
   }
   // TODO: handle comments for function parameters properly.
   if (isa<ParmVarDecl>(D))
-    return NULL;
+    return nullptr;
 
   // TODO: we could look up template parameter documentation in the template
   // documentation.
   if (isa<TemplateTypeParmDecl>(D) ||
       isa<NonTypeTemplateParmDecl>(D) ||
       isa<TemplateTemplateParmDecl>(D))
-    return NULL;
+    return nullptr;
 
   ArrayRef<RawComment *> RawComments = Comments.getComments();
 
   // If there are no comments anywhere, we won't find anything.
   if (RawComments.empty())
-    return NULL;
+    return nullptr;
 
   // Find declaration location.
   // For Objective-C declarations we generally don't expect to have multiple
@@ -137,17 +145,29 @@
     DeclLoc = D->getLocStart();
   else {
     DeclLoc = D->getLocation();
-    // If location of the typedef name is in a macro, it is because being
-    // declared via a macro. Try using declaration's starting location
-    // as the "declaration location".
-    if (DeclLoc.isMacroID() && isa<TypedefDecl>(D))
-      DeclLoc = D->getLocStart();
+    if (DeclLoc.isMacroID()) {
+      if (isa<TypedefDecl>(D)) {
+        // If location of the typedef name is in a macro, it is because being
+        // declared via a macro. Try using declaration's starting location as
+        // the "declaration location".
+        DeclLoc = D->getLocStart();
+      } else if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
+        // If location of the tag decl is inside a macro, but the spelling of
+        // the tag name comes from a macro argument, it looks like a special
+        // macro like NS_ENUM is being used to define the tag decl.  In that
+        // case, adjust the source location to the expansion loc so that we can
+        // attach the comment to the tag decl.
+        if (SourceMgr.isMacroArgExpansion(DeclLoc) &&
+            TD->isCompleteDefinition())
+          DeclLoc = SourceMgr.getExpansionLoc(DeclLoc);
+      }
+    }
   }
 
   // If the declaration doesn't map directly to a location in a file, we
   // can't find the comment.
   if (DeclLoc.isInvalid() || !DeclLoc.isFileID())
-    return NULL;
+    return nullptr;
 
   // Find the comment that occurs just after this declaration.
   ArrayRef<RawComment *>::iterator Comment;
@@ -201,12 +221,12 @@
   // The comment just after the declaration was not a trailing comment.
   // Let's look at the previous comment.
   if (Comment == RawComments.begin())
-    return NULL;
+    return nullptr;
   --Comment;
 
   // Check that we actually have a non-member Doxygen comment.
   if (!(*Comment)->isDocumentation() || (*Comment)->isTrailingComment())
-    return NULL;
+    return nullptr;
 
   // Decompose the end of the comment.
   std::pair<FileID, unsigned> CommentEndDecomp
@@ -215,14 +235,14 @@
   // If the comment and the declaration aren't in the same file, then they
   // aren't related.
   if (DeclLocDecomp.first != CommentEndDecomp.first)
-    return NULL;
+    return nullptr;
 
   // Get the corresponding buffer.
   bool Invalid = false;
   const char *Buffer = SourceMgr.getBufferData(DeclLocDecomp.first,
                                                &Invalid).data();
   if (Invalid)
-    return NULL;
+    return nullptr;
 
   // Extract text between the comment and declaration.
   StringRef Text(Buffer + CommentEndDecomp.second,
@@ -231,7 +251,7 @@
   // There should be no other declarations or preprocessor directives between
   // comment and declaration.
   if (Text.find_first_of(";{}#@") != StringRef::npos)
-    return NULL;
+    return nullptr;
 
   return *Comment;
 }
@@ -329,13 +349,11 @@
   }
 
   // Search for comments attached to declarations in the redeclaration chain.
-  const RawComment *RC = NULL;
-  const Decl *OriginalDeclForRC = NULL;
-  for (Decl::redecl_iterator I = D->redecls_begin(),
-                             E = D->redecls_end();
-       I != E; ++I) {
+  const RawComment *RC = nullptr;
+  const Decl *OriginalDeclForRC = nullptr;
+  for (auto I : D->redecls()) {
     llvm::DenseMap<const Decl *, RawCommentAndCacheFlags>::iterator Pos =
-        RedeclComments.find(*I);
+        RedeclComments.find(I);
     if (Pos != RedeclComments.end()) {
       const RawCommentAndCacheFlags &Raw = Pos->second;
       if (Raw.getKind() != RawCommentAndCacheFlags::NoCommentInDecl) {
@@ -344,16 +362,16 @@
         break;
       }
     } else {
-      RC = getRawCommentForDeclNoCache(*I);
-      OriginalDeclForRC = *I;
+      RC = getRawCommentForDeclNoCache(I);
+      OriginalDeclForRC = I;
       RawCommentAndCacheFlags Raw;
       if (RC) {
         Raw.setRaw(RC);
         Raw.setKind(RawCommentAndCacheFlags::FromDecl);
       } else
         Raw.setKind(RawCommentAndCacheFlags::NoCommentInDecl);
-      Raw.setOriginalDecl(*I);
-      RedeclComments[*I] = Raw;
+      Raw.setOriginalDecl(I);
+      RedeclComments[I] = Raw;
       if (RC)
         break;
     }
@@ -371,10 +389,8 @@
   Raw.setKind(RawCommentAndCacheFlags::FromRedecl);
   Raw.setOriginalDecl(OriginalDeclForRC);
 
-  for (Decl::redecl_iterator I = D->redecls_begin(),
-                             E = D->redecls_end();
-       I != E; ++I) {
-    RawCommentAndCacheFlags &R = RedeclComments[*I];
+  for (auto I : D->redecls()) {
+    RawCommentAndCacheFlags &R = RedeclComments[I];
     if (R.getKind() == RawCommentAndCacheFlags::NoCommentInDecl)
       R = Raw;
   }
@@ -390,10 +406,7 @@
     if (!ID)
       return;
     // Add redeclared method here.
-    for (ObjCInterfaceDecl::known_extensions_iterator
-           Ext = ID->known_extensions_begin(),
-           ExtEnd = ID->known_extensions_end();
-         Ext != ExtEnd; ++Ext) {
+    for (const auto *Ext : ID->known_extensions()) {
       if (ObjCMethodDecl *RedeclaredMethod =
             Ext->getMethod(ObjCMethod->getSelector(),
                                   ObjCMethod->isInstanceMethod()))
@@ -409,6 +422,8 @@
   ThisDeclInfo->IsFilled = false;
   ThisDeclInfo->fill();
   ThisDeclInfo->CommentDecl = FC->getDecl();
+  if (!ThisDeclInfo->TemplateParameters)
+    ThisDeclInfo->TemplateParameters = FC->getDeclInfo()->TemplateParameters;
   comments::FullComment *CFC =
     new (*this) comments::FullComment(FC->getBlocks(),
                                       ThisDeclInfo);
@@ -418,14 +433,14 @@
 
 comments::FullComment *ASTContext::getLocalCommentForDeclUncached(const Decl *D) const {
   const RawComment *RC = getRawCommentForDeclNoCache(D);
-  return RC ? RC->parse(*this, 0, D) : 0;
+  return RC ? RC->parse(*this, nullptr, D) : nullptr;
 }
 
 comments::FullComment *ASTContext::getCommentForDecl(
                                               const Decl *D,
                                               const Preprocessor *PP) const {
   if (D->isInvalidDecl())
-    return NULL;
+    return nullptr;
   D = adjustDeclToTemplate(D);
   
   const Decl *Canonical = D->getCanonicalDecl();
@@ -482,13 +497,12 @@
     }
     else if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
       if (!(RD = RD->getDefinition()))
-        return NULL;
+        return nullptr;
       // Check non-virtual bases.
-      for (CXXRecordDecl::base_class_const_iterator I =
-           RD->bases_begin(), E = RD->bases_end(); I != E; ++I) {
-        if (I->isVirtual() || (I->getAccessSpecifier() != AS_public))
+      for (const auto &I : RD->bases()) {
+        if (I.isVirtual() || (I.getAccessSpecifier() != AS_public))
           continue;
-        QualType Ty = I->getType();
+        QualType Ty = I.getType();
         if (Ty.isNull())
           continue;
         if (const CXXRecordDecl *NonVirtualBase = Ty->getAsCXXRecordDecl()) {
@@ -500,11 +514,10 @@
         }
       }
       // Check virtual bases.
-      for (CXXRecordDecl::base_class_const_iterator I =
-           RD->vbases_begin(), E = RD->vbases_end(); I != E; ++I) {
-        if (I->getAccessSpecifier() != AS_public)
+      for (const auto &I : RD->vbases()) {
+        if (I.getAccessSpecifier() != AS_public)
           continue;
-        QualType Ty = I->getType();
+        QualType Ty = I.getType();
         if (Ty.isNull())
           continue;
         if (const CXXRecordDecl *VirtualBase = Ty->getAsCXXRecordDecl()) {
@@ -515,7 +528,7 @@
         }
       }
     }
-    return NULL;
+    return nullptr;
   }
   
   // If the RawComment was attached to other redeclaration of this Decl, we
@@ -576,7 +589,7 @@
   // Check if we already have a canonical template template parameter.
   llvm::FoldingSetNodeID ID;
   CanonicalTemplateTemplateParm::Profile(ID, TTP);
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
   CanonicalTemplateTemplateParm *Canonical
     = CanonTemplateTemplateParms.FindNodeOrInsertPos(ID, InsertPos);
   if (Canonical)
@@ -595,7 +608,7 @@
                                                SourceLocation(),
                                                SourceLocation(),
                                                TTP->getDepth(),
-                                               TTP->getIndex(), 0, false,
+                                               TTP->getIndex(), nullptr, false,
                                                TTP->isParameterPack()));
     else if (NonTypeTemplateParmDecl *NTTP
              = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
@@ -615,7 +628,7 @@
                                                 SourceLocation(),
                                                 SourceLocation(),
                                                 NTTP->getDepth(),
-                                                NTTP->getPosition(), 0, 
+                                                NTTP->getPosition(), nullptr,
                                                 T,
                                                 TInfo,
                                                 ExpandedTypes.data(),
@@ -626,7 +639,7 @@
                                                 SourceLocation(),
                                                 SourceLocation(),
                                                 NTTP->getDepth(),
-                                                NTTP->getPosition(), 0, 
+                                                NTTP->getPosition(), nullptr,
                                                 T,
                                                 NTTP->isParameterPack(),
                                                 TInfo);
@@ -643,7 +656,7 @@
                                        SourceLocation(), TTP->getDepth(),
                                        TTP->getPosition(), 
                                        TTP->isParameterPack(),
-                                       0,
+                                       nullptr,
                          TemplateParameterList::Create(*this, SourceLocation(),
                                                        SourceLocation(),
                                                        CanonParams.data(),
@@ -652,7 +665,7 @@
 
   // Get the new insert position for the node we care about.
   Canonical = CanonTemplateTemplateParms.FindNodeOrInsertPos(ID, InsertPos);
-  assert(Canonical == 0 && "Shouldn't be in the map!");
+  assert(!Canonical && "Shouldn't be in the map!");
   (void)Canonical;
 
   // Create the canonical template template parameter entry.
@@ -662,14 +675,14 @@
 }
 
 CXXABI *ASTContext::createCXXABI(const TargetInfo &T) {
-  if (!LangOpts.CPlusPlus) return 0;
+  if (!LangOpts.CPlusPlus) return nullptr;
 
   switch (T.getCXXABI().getKind()) {
-  case TargetCXXABI::GenericARM:
+  case TargetCXXABI::GenericARM: // Same as Itanium at this level
   case TargetCXXABI::iOS:
-    return CreateARMCXXABI(*this);
+  case TargetCXXABI::iOS64:
   case TargetCXXABI::Emscripten:     // Same as Itanium at this level
-  case TargetCXXABI::GenericAArch64: // Same as Itanium at this level
+  case TargetCXXABI::GenericAArch64:
   case TargetCXXABI::GenericItanium:
     return CreateItaniumCXXABI(*this);
   case TargetCXXABI::Microsoft:
@@ -711,47 +724,40 @@
 }
 
 ASTContext::ASTContext(LangOptions& LOpts, SourceManager &SM,
-                       const TargetInfo *t,
                        IdentifierTable &idents, SelectorTable &sels,
-                       Builtin::Context &builtins,
-                       unsigned size_reserve,
-                       bool DelayInitialization) 
+                       Builtin::Context &builtins)
   : FunctionProtoTypes(this_()),
     TemplateSpecializationTypes(this_()),
     DependentTemplateSpecializationTypes(this_()),
     SubstTemplateTemplateParmPacks(this_()),
-    GlobalNestedNameSpecifier(0), 
-    Int128Decl(0), UInt128Decl(0), Float128StubDecl(0),
-    BuiltinVaListDecl(0),
-    ObjCIdDecl(0), ObjCSelDecl(0), ObjCClassDecl(0), ObjCProtocolClassDecl(0),
-    BOOLDecl(0),
-    CFConstantStringTypeDecl(0), ObjCInstanceTypeDecl(0),
-    FILEDecl(0), 
-    jmp_bufDecl(0), sigjmp_bufDecl(0), ucontext_tDecl(0),
-    BlockDescriptorType(0), BlockDescriptorExtendedType(0),
-    cudaConfigureCallDecl(0),
+    GlobalNestedNameSpecifier(nullptr),
+    Int128Decl(nullptr), UInt128Decl(nullptr), Float128StubDecl(nullptr),
+    BuiltinVaListDecl(nullptr),
+    ObjCIdDecl(nullptr), ObjCSelDecl(nullptr), ObjCClassDecl(nullptr),
+    ObjCProtocolClassDecl(nullptr), BOOLDecl(nullptr),
+    CFConstantStringTypeDecl(nullptr), ObjCInstanceTypeDecl(nullptr),
+    FILEDecl(nullptr),
+    jmp_bufDecl(nullptr), sigjmp_bufDecl(nullptr), ucontext_tDecl(nullptr),
+    BlockDescriptorType(nullptr), BlockDescriptorExtendedType(nullptr),
+    cudaConfigureCallDecl(nullptr),
     NullTypeSourceInfo(QualType()), 
     FirstLocalImport(), LastLocalImport(),
     SourceMgr(SM), LangOpts(LOpts), 
-    AddrSpaceMap(0), Target(t), PrintingPolicy(LOpts),
+    AddrSpaceMap(nullptr), Target(nullptr), PrintingPolicy(LOpts),
     Idents(idents), Selectors(sels),
     BuiltinInfo(builtins),
     DeclarationNames(*this),
-    ExternalSource(0), Listener(0),
+    ExternalSource(nullptr), Listener(nullptr),
     Comments(SM), CommentsLoaded(false),
     CommentCommandTraits(BumpAlloc, LOpts.CommentOpts),
-    LastSDM(0, 0)
+    LastSDM(nullptr, 0)
 {
-  if (size_reserve > 0) Types.reserve(size_reserve);
   TUDecl = TranslationUnitDecl::Create(*this);
-  
-  if (!DelayInitialization) {
-    assert(t && "No target supplied for ASTContext initialization");
-    InitBuiltinTypes(*t);
-  }
 }
 
 ASTContext::~ASTContext() {
+  ReleaseParentMapEntries();
+
   // Release the DenseMaps associated with DeclContext objects.
   // FIXME: Is this the ideal solution?
   ReleaseDeclContextMaps();
@@ -783,11 +789,19 @@
        A != AEnd; ++A)
     A->second->~AttrVec();
 
-  for (llvm::DenseMap<const DeclContext *, MangleNumberingContext *>::iterator
-           I = MangleNumberingContexts.begin(),
-           E = MangleNumberingContexts.end();
-       I != E; ++I)
-    delete I->second;
+  llvm::DeleteContainerSeconds(MangleNumberingContexts);
+}
+
+void ASTContext::ReleaseParentMapEntries() {
+  if (!AllParents) return;
+  for (const auto &Entry : *AllParents) {
+    if (Entry.second.is<ast_type_traits::DynTypedNode *>()) {
+      delete Entry.second.get<ast_type_traits::DynTypedNode *>();
+    } else {
+      assert(Entry.second.is<ParentVector *>());
+      delete Entry.second.get<ParentVector *>();
+    }
+  }
 }
 
 void ASTContext::AddDeallocation(void (*Callback)(void*), void *Data) {
@@ -795,8 +809,8 @@
 }
 
 void
-ASTContext::setExternalSource(OwningPtr<ExternalASTSource> &Source) {
-  ExternalSource.reset(Source.take());
+ASTContext::setExternalSource(IntrusiveRefCntPtr<ExternalASTSource> Source) {
+  ExternalSource = Source;
 }
 
 void ASTContext::PrintStats() const {
@@ -850,7 +864,7 @@
                << NumImplicitDestructors
                << " implicit destructors created\n";
 
-  if (ExternalSource.get()) {
+  if (ExternalSource) {
     llvm::errs() << "\n";
     ExternalSource->PrintStats();
   }
@@ -858,45 +872,47 @@
   BumpAlloc.PrintStats();
 }
 
+RecordDecl *ASTContext::buildImplicitRecord(StringRef Name,
+                                            RecordDecl::TagKind TK) const {
+  SourceLocation Loc;
+  RecordDecl *NewDecl;
+  if (getLangOpts().CPlusPlus)
+    NewDecl = CXXRecordDecl::Create(*this, TK, getTranslationUnitDecl(), Loc,
+                                    Loc, &Idents.get(Name));
+  else
+    NewDecl = RecordDecl::Create(*this, TK, getTranslationUnitDecl(), Loc, Loc,
+                                 &Idents.get(Name));
+  NewDecl->setImplicit();
+  return NewDecl;
+}
+
+TypedefDecl *ASTContext::buildImplicitTypedef(QualType T,
+                                              StringRef Name) const {
+  TypeSourceInfo *TInfo = getTrivialTypeSourceInfo(T);
+  TypedefDecl *NewDecl = TypedefDecl::Create(
+      const_cast<ASTContext &>(*this), getTranslationUnitDecl(),
+      SourceLocation(), SourceLocation(), &Idents.get(Name), TInfo);
+  NewDecl->setImplicit();
+  return NewDecl;
+}
+
 TypedefDecl *ASTContext::getInt128Decl() const {
-  if (!Int128Decl) {
-    TypeSourceInfo *TInfo = getTrivialTypeSourceInfo(Int128Ty);
-    Int128Decl = TypedefDecl::Create(const_cast<ASTContext &>(*this), 
-                                     getTranslationUnitDecl(),
-                                     SourceLocation(),
-                                     SourceLocation(),
-                                     &Idents.get("__int128_t"),
-                                     TInfo);
-  }
-  
+  if (!Int128Decl)
+    Int128Decl = buildImplicitTypedef(Int128Ty, "__int128_t");
   return Int128Decl;
 }
 
 TypedefDecl *ASTContext::getUInt128Decl() const {
-  if (!UInt128Decl) {
-    TypeSourceInfo *TInfo = getTrivialTypeSourceInfo(UnsignedInt128Ty);
-    UInt128Decl = TypedefDecl::Create(const_cast<ASTContext &>(*this), 
-                                     getTranslationUnitDecl(),
-                                     SourceLocation(),
-                                     SourceLocation(),
-                                     &Idents.get("__uint128_t"),
-                                     TInfo);
-  }
-  
+  if (!UInt128Decl)
+    UInt128Decl = buildImplicitTypedef(UnsignedInt128Ty, "__uint128_t");
   return UInt128Decl;
 }
 
 TypeDecl *ASTContext::getFloat128StubType() const {
   assert(LangOpts.CPlusPlus && "should only be called for c++");
-  if (!Float128StubDecl) {
-    Float128StubDecl = CXXRecordDecl::Create(const_cast<ASTContext &>(*this), 
-                                             TTK_Struct,
-                                             getTranslationUnitDecl(),
-                                             SourceLocation(),
-                                             SourceLocation(),
-                                             &Idents.get("__float128"));
-  }
-  
+  if (!Float128StubDecl)
+    Float128StubDecl = buildImplicitRecord("__float128");
+
   return Float128StubDecl;
 }
 
@@ -1107,7 +1123,7 @@
   llvm::DenseMap<const FunctionDecl*, FunctionDecl *>::const_iterator Pos
     = ClassScopeSpecializationPattern.find(FD);
   if (Pos == ClassScopeSpecializationPattern.end())
-    return 0;
+    return nullptr;
 
   return Pos->second;
 }
@@ -1124,7 +1140,7 @@
   llvm::DenseMap<UsingDecl *, NamedDecl *>::const_iterator Pos
     = InstantiatedFromUsingDecl.find(UUD);
   if (Pos == InstantiatedFromUsingDecl.end())
-    return 0;
+    return nullptr;
 
   return Pos->second;
 }
@@ -1144,7 +1160,7 @@
   llvm::DenseMap<UsingShadowDecl*, UsingShadowDecl*>::const_iterator Pos
     = InstantiatedFromUsingShadowDecl.find(Inst);
   if (Pos == InstantiatedFromUsingShadowDecl.end())
-    return 0;
+    return nullptr;
 
   return Pos->second;
 }
@@ -1160,7 +1176,7 @@
   llvm::DenseMap<FieldDecl *, FieldDecl *>::iterator Pos
     = InstantiatedFromUnnamedFieldDecl.find(Field);
   if (Pos == InstantiatedFromUnnamedFieldDecl.end())
-    return 0;
+    return nullptr;
 
   return Pos->second;
 }
@@ -1180,7 +1196,7 @@
   llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos
     = OverriddenMethods.find(Method->getCanonicalDecl());
   if (Pos == OverriddenMethods.end())
-    return 0;
+    return nullptr;
 
   return Pos->second.begin();
 }
@@ -1190,7 +1206,7 @@
   llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos
     = OverriddenMethods.find(Method->getCanonicalDecl());
   if (Pos == OverriddenMethods.end())
-    return 0;
+    return nullptr;
 
   return Pos->second.end();
 }
@@ -1294,13 +1310,14 @@
 
   } else if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
     QualType T = VD->getType();
-    if (const ReferenceType* RT = T->getAs<ReferenceType>()) {
+    if (const ReferenceType *RT = T->getAs<ReferenceType>()) {
       if (ForAlignof)
         T = RT->getPointeeType();
       else
         T = getPointerType(RT->getPointeeType());
     }
-    if (!T->isIncompleteType() && !T->isFunctionType()) {
+    QualType BaseT = getBaseElementType(T);
+    if (!BaseT->isIncompleteType() && !T->isFunctionType()) {
       // Adjust alignments of declarations with array type by the
       // large-array alignment on the target.
       if (const ArrayType *arrayType = getAsArrayType(T)) {
@@ -1312,9 +1329,6 @@
                    MinWidth <= getTypeSize(cast<ConstantArrayType>(arrayType)))
             Align = std::max(Align, Target->getLargeArrayAlign());
         }
-
-        // Walk through any array types while we're at it.
-        T = getBaseElementType(arrayType);
       }
       Align = std::max(Align, getPreferredTypeAlign(T.getTypePtr()));
       if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
@@ -1619,7 +1633,7 @@
   }
   case Type::MemberPointer: {
     const MemberPointerType *MPT = cast<MemberPointerType>(T);
-    llvm::tie(Width, Align) = ABI->getMemberPointerWidthAndAlign(MPT);
+    std::tie(Width, Align) = ABI->getMemberPointerWidthAndAlign(MPT);
     break;
   }
   case Type::Complex: {
@@ -1633,8 +1647,9 @@
   }
   case Type::ObjCObject:
     return getTypeInfo(cast<ObjCObjectType>(T)->getBaseType().getTypePtr());
+  case Type::Adjusted:
   case Type::Decayed:
-    return getTypeInfo(cast<DecayedType>(T)->getDecayedType().getTypePtr());
+    return getTypeInfo(cast<AdjustedType>(T)->getAdjustedType().getTypePtr());
   case Type::ObjCInterface: {
     const ObjCInterfaceType *ObjCI = cast<ObjCInterfaceType>(T);
     const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl());
@@ -1762,13 +1777,19 @@
   if (Target->getTriple().getArch() == llvm::Triple::xcore)
     return ABIAlign;  // Never overalign on XCore.
 
+  const TypedefType *TT = T->getAs<TypedefType>();
+
   // Double and long long should be naturally aligned if possible.
-  if (const ComplexType* CT = T->getAs<ComplexType>())
+  T = T->getBaseElementTypeUnsafe();
+  if (const ComplexType *CT = T->getAs<ComplexType>())
     T = CT->getElementType().getTypePtr();
   if (T->isSpecificBuiltinType(BuiltinType::Double) ||
       T->isSpecificBuiltinType(BuiltinType::LongLong) ||
       T->isSpecificBuiltinType(BuiltinType::ULongLong))
-    return std::max(ABIAlign, (unsigned)getTypeSize(T));
+    // Don't increase the alignment if an alignment attribute was specified on a
+    // typedef declaration.
+    if (!TT || !TT->getDecl()->getMaxAlignment())
+      return std::max(ABIAlign, (unsigned)getTypeSize(T));
 
   return ABIAlign;
 }
@@ -1797,9 +1818,8 @@
   if (const ObjCInterfaceDecl *SuperClass = OI->getSuperClass())
     DeepCollectObjCIvars(SuperClass, false, Ivars);
   if (!leafClass) {
-    for (ObjCInterfaceDecl::ivar_iterator I = OI->ivar_begin(),
-         E = OI->ivar_end(); I != E; ++I)
-      Ivars.push_back(*I);
+    for (const auto *I : OI->ivars())
+      Ivars.push_back(I);
   } else {
     ObjCInterfaceDecl *IDecl = const_cast<ObjCInterfaceDecl *>(OI);
     for (const ObjCIvarDecl *Iv = IDecl->all_declared_ivar_begin(); Iv; 
@@ -1815,24 +1835,17 @@
   if (const ObjCInterfaceDecl *OI = dyn_cast<ObjCInterfaceDecl>(CDecl)) {
     // We can use protocol_iterator here instead of
     // all_referenced_protocol_iterator since we are walking all categories.    
-    for (ObjCInterfaceDecl::all_protocol_iterator P = OI->all_referenced_protocol_begin(),
-         PE = OI->all_referenced_protocol_end(); P != PE; ++P) {
-      ObjCProtocolDecl *Proto = (*P);
+    for (auto *Proto : OI->all_referenced_protocols()) {
       Protocols.insert(Proto->getCanonicalDecl());
-      for (ObjCProtocolDecl::protocol_iterator P = Proto->protocol_begin(),
-           PE = Proto->protocol_end(); P != PE; ++P) {
-        Protocols.insert((*P)->getCanonicalDecl());
-        CollectInheritedProtocols(*P, Protocols);
+      for (auto *P : Proto->protocols()) {
+        Protocols.insert(P->getCanonicalDecl());
+        CollectInheritedProtocols(P, Protocols);
       }
     }
     
     // Categories of this Interface.
-    for (ObjCInterfaceDecl::visible_categories_iterator
-           Cat = OI->visible_categories_begin(),
-           CatEnd = OI->visible_categories_end();
-         Cat != CatEnd; ++Cat) {
-      CollectInheritedProtocols(*Cat, Protocols);
-    }
+    for (const auto *Cat : OI->visible_categories())
+      CollectInheritedProtocols(Cat, Protocols);
 
     if (ObjCInterfaceDecl *SD = OI->getSuperClass())
       while (SD) {
@@ -1840,22 +1853,16 @@
         SD = SD->getSuperClass();
       }
   } else if (const ObjCCategoryDecl *OC = dyn_cast<ObjCCategoryDecl>(CDecl)) {
-    for (ObjCCategoryDecl::protocol_iterator P = OC->protocol_begin(),
-         PE = OC->protocol_end(); P != PE; ++P) {
-      ObjCProtocolDecl *Proto = (*P);
+    for (auto *Proto : OC->protocols()) {
       Protocols.insert(Proto->getCanonicalDecl());
-      for (ObjCProtocolDecl::protocol_iterator P = Proto->protocol_begin(),
-           PE = Proto->protocol_end(); P != PE; ++P)
-        CollectInheritedProtocols(*P, Protocols);
+      for (const auto *P : Proto->protocols())
+        CollectInheritedProtocols(P, Protocols);
     }
   } else if (const ObjCProtocolDecl *OP = dyn_cast<ObjCProtocolDecl>(CDecl)) {
-    for (ObjCProtocolDecl::protocol_iterator P = OP->protocol_begin(),
-         PE = OP->protocol_end(); P != PE; ++P) {
-      ObjCProtocolDecl *Proto = (*P);
+    for (auto *Proto : OP->protocols()) {
       Protocols.insert(Proto->getCanonicalDecl());
-      for (ObjCProtocolDecl::protocol_iterator P = Proto->protocol_begin(),
-           PE = Proto->protocol_end(); P != PE; ++P)
-        CollectInheritedProtocols(*P, Protocols);
+      for (const auto *P : Proto->protocols())
+        CollectInheritedProtocols(P, Protocols);
     }
   }
 }
@@ -1863,12 +1870,8 @@
 unsigned ASTContext::CountNonClassIvars(const ObjCInterfaceDecl *OI) const {
   unsigned count = 0;  
   // Count ivars declared in class extension.
-  for (ObjCInterfaceDecl::known_extensions_iterator
-         Ext = OI->known_extensions_begin(),
-         ExtEnd = OI->known_extensions_end();
-       Ext != ExtEnd; ++Ext) {
+  for (const auto *Ext : OI->known_extensions())
     count += Ext->ivar_size();
-  }
   
   // Count ivar defined in this class's implementation.  This
   // includes synthesized ivars.
@@ -1902,7 +1905,7 @@
     I = ObjCImpls.find(D);
   if (I != ObjCImpls.end())
     return cast<ObjCImplementationDecl>(I->second);
-  return 0;
+  return nullptr;
 }
 /// \brief Get the implementation of ObjCCategoryDecl, or NULL if none exists.
 ObjCCategoryImplDecl *ASTContext::getObjCImplementation(ObjCCategoryDecl *D) {
@@ -1910,7 +1913,7 @@
     I = ObjCImpls.find(D);
   if (I != ObjCImpls.end())
     return cast<ObjCCategoryImplDecl>(I->second);
-  return 0;
+  return nullptr;
 }
 
 /// \brief Set the implementation of ObjCInterfaceDecl.
@@ -1938,7 +1941,7 @@
           dyn_cast<ObjCImplDecl>(ND->getDeclContext()))
     return IMD->getClassInterface();
 
-  return 0;
+  return nullptr;
 }
 
 /// \brief Get the copy initialization expression of VarDecl,or NULL if 
@@ -1949,7 +1952,7 @@
          "getBlockVarCopyInits - not __block var");
   llvm::DenseMap<const VarDecl*, Expr*>::iterator
     I = BlockVarCopyInits.find(VD);
-  return (I != BlockVarCopyInits.end()) ? cast<Expr>(I->second) : 0;
+  return (I != BlockVarCopyInits.end()) ? cast<Expr>(I->second) : nullptr;
 }
 
 /// \brief Set the copy inialization expression of a block var decl.
@@ -1983,7 +1986,7 @@
 
 const ASTRecordLayout &
 ASTContext::getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const {
-  return getObjCLayout(D, 0);
+  return getObjCLayout(D, nullptr);
 }
 
 const ASTRecordLayout &
@@ -2004,7 +2007,7 @@
   // Check if we've already instantiated this type.
   llvm::FoldingSetNodeID ID;
   ExtQuals::Profile(ID, baseType, quals);
-  void *insertPos = 0;
+  void *insertPos = nullptr;
   if (ExtQuals *eq = ExtQualNodes.FindNodeOrInsertPos(ID, insertPos)) {
     assert(eq->getQualifiers() == quals);
     return QualType(eq, fastQuals);
@@ -2081,12 +2084,12 @@
 
   QualType Result;
   if (const FunctionNoProtoType *FNPT = dyn_cast<FunctionNoProtoType>(T)) {
-    Result = getFunctionNoProtoType(FNPT->getResultType(), Info);
+    Result = getFunctionNoProtoType(FNPT->getReturnType(), Info);
   } else {
     const FunctionProtoType *FPT = cast<FunctionProtoType>(T);
     FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
     EPI.ExtInfo = Info;
-    Result = getFunctionType(FPT->getResultType(), FPT->getArgTypes(), EPI);
+    Result = getFunctionType(FPT->getReturnType(), FPT->getParamTypes(), EPI);
   }
 
   return cast<FunctionType>(Result.getTypePtr());
@@ -2098,7 +2101,7 @@
   while (true) {
     const FunctionProtoType *FPT = FD->getType()->castAs<FunctionProtoType>();
     FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
-    FD->setType(getFunctionType(ResultType, FPT->getArgTypes(), EPI));
+    FD->setType(getFunctionType(ResultType, FPT->getParamTypes(), EPI));
     if (FunctionDecl *Next = FD->getPreviousDecl())
       FD = Next;
     else
@@ -2116,7 +2119,7 @@
   llvm::FoldingSetNodeID ID;
   ComplexType::Profile(ID, T);
 
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
   if (ComplexType *CT = ComplexTypes.FindNodeOrInsertPos(ID, InsertPos))
     return QualType(CT, 0);
 
@@ -2128,7 +2131,7 @@
 
     // Get the new insert position for the node we care about.
     ComplexType *NewIP = ComplexTypes.FindNodeOrInsertPos(ID, InsertPos);
-    assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+    assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
   }
   ComplexType *New = new (*this, TypeAlignment) ComplexType(T, Canonical);
   Types.push_back(New);
@@ -2144,7 +2147,7 @@
   llvm::FoldingSetNodeID ID;
   PointerType::Profile(ID, T);
 
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
   if (PointerType *PT = PointerTypes.FindNodeOrInsertPos(ID, InsertPos))
     return QualType(PT, 0);
 
@@ -2156,7 +2159,7 @@
 
     // Get the new insert position for the node we care about.
     PointerType *NewIP = PointerTypes.FindNodeOrInsertPos(ID, InsertPos);
-    assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+    assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
   }
   PointerType *New = new (*this, TypeAlignment) PointerType(T, Canonical);
   Types.push_back(New);
@@ -2164,15 +2167,30 @@
   return QualType(New, 0);
 }
 
+QualType ASTContext::getAdjustedType(QualType Orig, QualType New) const {
+  llvm::FoldingSetNodeID ID;
+  AdjustedType::Profile(ID, Orig, New);
+  void *InsertPos = nullptr;
+  AdjustedType *AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos);
+  if (AT)
+    return QualType(AT, 0);
+
+  QualType Canonical = getCanonicalType(New);
+
+  // Get the new insert position for the node we care about.
+  AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos);
+  assert(!AT && "Shouldn't be in the map!");
+
+  AT = new (*this, TypeAlignment)
+      AdjustedType(Type::Adjusted, Orig, New, Canonical);
+  Types.push_back(AT);
+  AdjustedTypes.InsertNode(AT, InsertPos);
+  return QualType(AT, 0);
+}
+
 QualType ASTContext::getDecayedType(QualType T) const {
   assert((T->isArrayType() || T->isFunctionType()) && "T does not decay");
 
-  llvm::FoldingSetNodeID ID;
-  DecayedType::Profile(ID, T);
-  void *InsertPos = 0;
-  if (DecayedType *DT = DecayedTypes.FindNodeOrInsertPos(ID, InsertPos))
-    return QualType(DT, 0);
-
   QualType Decayed;
 
   // C99 6.7.5.3p7:
@@ -2190,17 +2208,23 @@
   if (T->isFunctionType())
     Decayed = getPointerType(T);
 
+  llvm::FoldingSetNodeID ID;
+  AdjustedType::Profile(ID, T, Decayed);
+  void *InsertPos = nullptr;
+  AdjustedType *AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos);
+  if (AT)
+    return QualType(AT, 0);
+
   QualType Canonical = getCanonicalType(Decayed);
 
   // Get the new insert position for the node we care about.
-  DecayedType *NewIP = DecayedTypes.FindNodeOrInsertPos(ID, InsertPos);
-  assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+  AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos);
+  assert(!AT && "Shouldn't be in the map!");
 
-  DecayedType *New =
-      new (*this, TypeAlignment) DecayedType(T, Decayed, Canonical);
-  Types.push_back(New);
-  DecayedTypes.InsertNode(New, InsertPos);
-  return QualType(New, 0);
+  AT = new (*this, TypeAlignment) DecayedType(T, Decayed, Canonical);
+  Types.push_back(AT);
+  AdjustedTypes.InsertNode(AT, InsertPos);
+  return QualType(AT, 0);
 }
 
 /// getBlockPointerType - Return the uniqued reference to the type for
@@ -2212,7 +2236,7 @@
   llvm::FoldingSetNodeID ID;
   BlockPointerType::Profile(ID, T);
 
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
   if (BlockPointerType *PT =
         BlockPointerTypes.FindNodeOrInsertPos(ID, InsertPos))
     return QualType(PT, 0);
@@ -2226,7 +2250,7 @@
     // Get the new insert position for the node we care about.
     BlockPointerType *NewIP =
       BlockPointerTypes.FindNodeOrInsertPos(ID, InsertPos);
-    assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+    assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
   }
   BlockPointerType *New
     = new (*this, TypeAlignment) BlockPointerType(T, Canonical);
@@ -2247,7 +2271,7 @@
   llvm::FoldingSetNodeID ID;
   ReferenceType::Profile(ID, T, SpelledAsLValue);
 
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
   if (LValueReferenceType *RT =
         LValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos))
     return QualType(RT, 0);
@@ -2264,7 +2288,7 @@
     // Get the new insert position for the node we care about.
     LValueReferenceType *NewIP =
       LValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos);
-    assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+    assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
   }
 
   LValueReferenceType *New
@@ -2284,7 +2308,7 @@
   llvm::FoldingSetNodeID ID;
   ReferenceType::Profile(ID, T, false);
 
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
   if (RValueReferenceType *RT =
         RValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos))
     return QualType(RT, 0);
@@ -2301,7 +2325,7 @@
     // Get the new insert position for the node we care about.
     RValueReferenceType *NewIP =
       RValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos);
-    assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+    assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
   }
 
   RValueReferenceType *New
@@ -2319,7 +2343,7 @@
   llvm::FoldingSetNodeID ID;
   MemberPointerType::Profile(ID, T, Cls);
 
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
   if (MemberPointerType *PT =
       MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos))
     return QualType(PT, 0);
@@ -2333,7 +2357,7 @@
     // Get the new insert position for the node we care about.
     MemberPointerType *NewIP =
       MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos);
-    assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+    assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
   }
   MemberPointerType *New
     = new (*this, TypeAlignment) MemberPointerType(T, Cls, Canonical);
@@ -2361,7 +2385,7 @@
   llvm::FoldingSetNodeID ID;
   ConstantArrayType::Profile(ID, EltTy, ArySize, ASM, IndexTypeQuals);
 
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
   if (ConstantArrayType *ATP =
       ConstantArrayTypes.FindNodeOrInsertPos(ID, InsertPos))
     return QualType(ATP, 0);
@@ -2378,7 +2402,7 @@
     // Get the new insert position for the node we care about.
     ConstantArrayType *NewIP =
       ConstantArrayTypes.FindNodeOrInsertPos(ID, InsertPos);
-    assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+    assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
   }
 
   ConstantArrayType *New = new(*this,TypeAlignment)
@@ -2496,7 +2520,7 @@
     const IncompleteArrayType *iat = cast<IncompleteArrayType>(ty);
     result = getVariableArrayType(
                  getVariableArrayDecayedType(iat->getElementType()),
-                                  /*size*/ 0,
+                                  /*size*/ nullptr,
                                   ArrayType::Normal,
                                   iat->getIndexTypeCVRQualifiers(),
                                   SourceRange());
@@ -2508,7 +2532,7 @@
     const VariableArrayType *vat = cast<VariableArrayType>(ty);
     result = getVariableArrayType(
                  getVariableArrayDecayedType(vat->getElementType()),
-                                  /*size*/ 0,
+                                  /*size*/ nullptr,
                                   ArrayType::Star,
                                   vat->getIndexTypeCVRQualifiers(),
                                   vat->getBracketsRange());
@@ -2578,7 +2602,7 @@
 
   SplitQualType canonElementType = getCanonicalType(elementType).split();
 
-  void *insertPos = 0;
+  void *insertPos = nullptr;
   llvm::FoldingSetNodeID ID;
   DependentSizedArrayType::Profile(ID, *this,
                                    QualType(canonElementType.Ty, 0),
@@ -2623,7 +2647,7 @@
   llvm::FoldingSetNodeID ID;
   IncompleteArrayType::Profile(ID, elementType, ASM, elementTypeQuals);
 
-  void *insertPos = 0;
+  void *insertPos = nullptr;
   if (IncompleteArrayType *iat =
        IncompleteArrayTypes.FindNodeOrInsertPos(ID, insertPos))
     return QualType(iat, 0);
@@ -2663,7 +2687,7 @@
   llvm::FoldingSetNodeID ID;
   VectorType::Profile(ID, vecType, NumElts, Type::Vector, VecKind);
 
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
   if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos))
     return QualType(VTP, 0);
 
@@ -2675,7 +2699,7 @@
 
     // Get the new insert position for the node we care about.
     VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos);
-    assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+    assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
   }
   VectorType *New = new (*this, TypeAlignment)
     VectorType(vecType, NumElts, Canonical, VecKind);
@@ -2694,7 +2718,7 @@
   llvm::FoldingSetNodeID ID;
   VectorType::Profile(ID, vecType, NumElts, Type::ExtVector,
                       VectorType::GenericVector);
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
   if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos))
     return QualType(VTP, 0);
 
@@ -2706,7 +2730,7 @@
 
     // Get the new insert position for the node we care about.
     VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos);
-    assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+    assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
   }
   ExtVectorType *New = new (*this, TypeAlignment)
     ExtVectorType(vecType, NumElts, Canonical);
@@ -2723,7 +2747,7 @@
   DependentSizedExtVectorType::Profile(ID, *this, getCanonicalType(vecType),
                                        SizeExpr);
 
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
   DependentSizedExtVectorType *Canon
     = DependentSizedExtVectorTypes.FindNodeOrInsertPos(ID, InsertPos);
   DependentSizedExtVectorType *New;
@@ -2769,7 +2793,7 @@
   llvm::FoldingSetNodeID ID;
   FunctionNoProtoType::Profile(ID, ResultTy, Info);
 
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
   if (FunctionNoProtoType *FT =
         FunctionNoProtoTypes.FindNodeOrInsertPos(ID, InsertPos))
     return QualType(FT, 0);
@@ -2781,7 +2805,7 @@
     // Get the new insert position for the node we care about.
     FunctionNoProtoType *NewIP =
       FunctionNoProtoTypes.FindNodeOrInsertPos(ID, InsertPos);
-    assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+    assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
   }
 
   FunctionProtoType::ExtInfo newInfo = Info.withCallingConv(CallConv);
@@ -2799,8 +2823,6 @@
           T.getObjCLifetime() == Qualifiers::OCL_ExplicitNone);
 }
 
-/// getFunctionType - Return a normal function type with a typed argument
-/// list.  isVariadic indicates whether the argument list includes '...'.
 QualType
 ASTContext::getFunctionType(QualType ResultTy, ArrayRef<QualType> ArgArray,
                             const FunctionProtoType::ExtProtoInfo &EPI) const {
@@ -2812,7 +2834,7 @@
   FunctionProtoType::Profile(ID, ResultTy, ArgArray.begin(), NumArgs, EPI,
                              *this);
 
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
   if (FunctionProtoType *FTP =
         FunctionProtoTypes.FindNodeOrInsertPos(ID, InsertPos))
     return QualType(FTP, 0);
@@ -2852,7 +2874,7 @@
     // Get the new insert position for the node we care about.
     FunctionProtoType *NewIP =
       FunctionProtoTypes.FindNodeOrInsertPos(ID, InsertPos);
-    assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+    assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
   }
 
   // FunctionProtoType objects are allocated with extra bytes after
@@ -2874,7 +2896,7 @@
   } else if (EPI.ExceptionSpecType == EST_Unevaluated) {
     Size += sizeof(FunctionDecl*);
   }
-  if (EPI.ConsumedArguments)
+  if (EPI.ConsumedParameters)
     Size += NumArgs * sizeof(bool);
 
   FunctionProtoType *FTP = (FunctionProtoType*) Allocate(Size, TypeAlignment);
@@ -2996,7 +3018,7 @@
   llvm::FoldingSetNodeID id;
   AttributedType::Profile(id, attrKind, modifiedType, equivalentType);
 
-  void *insertPos = 0;
+  void *insertPos = nullptr;
   AttributedType *type = AttributedTypes.FindNodeOrInsertPos(id, insertPos);
   if (type) return QualType(type, 0);
 
@@ -3020,7 +3042,7 @@
 
   llvm::FoldingSetNodeID ID;
   SubstTemplateTypeParmType::Profile(ID, Parm, Replacement);
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
   SubstTemplateTypeParmType *SubstParm
     = SubstTemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos);
 
@@ -3039,17 +3061,15 @@
                                           const TemplateTypeParmType *Parm,
                                               const TemplateArgument &ArgPack) {
 #ifndef NDEBUG
-  for (TemplateArgument::pack_iterator P = ArgPack.pack_begin(), 
-                                    PEnd = ArgPack.pack_end();
-       P != PEnd; ++P) {
-    assert(P->getKind() == TemplateArgument::Type &&"Pack contains a non-type");
-    assert(P->getAsType().isCanonical() && "Pack contains non-canonical type");
+  for (const auto &P : ArgPack.pack_elements()) {
+    assert(P.getKind() == TemplateArgument::Type &&"Pack contains a non-type");
+    assert(P.getAsType().isCanonical() && "Pack contains non-canonical type");
   }
 #endif
   
   llvm::FoldingSetNodeID ID;
   SubstTemplateTypeParmPackType::Profile(ID, Parm, ArgPack);
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
   if (SubstTemplateTypeParmPackType *SubstParm
         = SubstTemplateTypeParmPackTypes.FindNodeOrInsertPos(ID, InsertPos))
     return QualType(SubstParm, 0);
@@ -3078,7 +3098,7 @@
                                              TemplateTypeParmDecl *TTPDecl) const {
   llvm::FoldingSetNodeID ID;
   TemplateTypeParmType::Profile(ID, Depth, Index, ParameterPack, TTPDecl);
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
   TemplateTypeParmType *TypeParm
     = TemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos);
 
@@ -3219,7 +3239,7 @@
   TemplateSpecializationType::Profile(ID, CanonTemplate,
                                       CanonArgs.data(), NumArgs, *this);
 
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
   TemplateSpecializationType *Spec
     = TemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos);
 
@@ -3247,7 +3267,7 @@
   llvm::FoldingSetNodeID ID;
   ElaboratedType::Profile(ID, Keyword, NNS, NamedType);
 
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
   ElaboratedType *T = ElaboratedTypes.FindNodeOrInsertPos(ID, InsertPos);
   if (T)
     return QualType(T, 0);
@@ -3271,7 +3291,7 @@
   llvm::FoldingSetNodeID ID;
   ParenType::Profile(ID, InnerType);
 
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
   ParenType *T = ParenTypes.FindNodeOrInsertPos(ID, InsertPos);
   if (T)
     return QualType(T, 0);
@@ -3294,8 +3314,6 @@
                                           NestedNameSpecifier *NNS,
                                           const IdentifierInfo *Name,
                                           QualType Canon) const {
-  assert(NNS->isDependent() && "nested-name-specifier must be dependent");
-
   if (Canon.isNull()) {
     NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS);
     ElaboratedTypeKeyword CanonKeyword = Keyword;
@@ -3309,7 +3327,7 @@
   llvm::FoldingSetNodeID ID;
   DependentNameType::Profile(ID, Keyword, NNS, Name);
 
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
   DependentNameType *T
     = DependentNameTypes.FindNodeOrInsertPos(ID, InsertPos);
   if (T)
@@ -3350,7 +3368,7 @@
   DependentTemplateSpecializationType::Profile(ID, *this, Keyword, NNS,
                                                Name, NumArgs, Args);
 
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
   DependentTemplateSpecializationType *T
     = DependentTemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos);
   if (T)
@@ -3396,7 +3414,7 @@
 
   assert(Pattern->containsUnexpandedParameterPack() &&
          "Pack expansions must expand one or more parameter packs");
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
   PackExpansionType *T
     = PackExpansionTypes.FindNodeOrInsertPos(ID, InsertPos);
   if (T)
@@ -3409,7 +3427,7 @@
     // contains an alias template specialization which ignores one of its
     // parameters.
     if (Canon->containsUnexpandedParameterPack()) {
-      Canon = getPackExpansionType(getCanonicalType(Pattern), NumExpansions);
+      Canon = getPackExpansionType(Canon, NumExpansions);
 
       // Find the insert position again, in case we inserted an element into
       // PackExpansionTypes and invalidated our insert position.
@@ -3420,7 +3438,7 @@
   T = new (*this) PackExpansionType(Pattern, Canon, NumExpansions);
   Types.push_back(T);
   PackExpansionTypes.InsertNode(T, InsertPos);
-  return QualType(T, 0);  
+  return QualType(T, 0);
 }
 
 /// CmpProtocolNames - Comparison predicate for sorting protocols
@@ -3471,7 +3489,7 @@
   // Look in the folding set for an existing type.
   llvm::FoldingSetNodeID ID;
   ObjCObjectTypeImpl::Profile(ID, BaseType, Protocols, NumProtocols);
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
   if (ObjCObjectType *QT = ObjCObjectTypes.FindNodeOrInsertPos(ID, InsertPos))
     return QualType(QT, 0);
 
@@ -3508,13 +3526,79 @@
   return QualType(T, 0);
 }
 
+/// ObjCObjectAdoptsQTypeProtocols - Checks that protocols in IC's
+/// protocol list adopt all protocols in QT's qualified-id protocol
+/// list.
+bool ASTContext::ObjCObjectAdoptsQTypeProtocols(QualType QT,
+                                                ObjCInterfaceDecl *IC) {
+  if (!QT->isObjCQualifiedIdType())
+    return false;
+  
+  if (const ObjCObjectPointerType *OPT = QT->getAs<ObjCObjectPointerType>()) {
+    // If both the right and left sides have qualifiers.
+    for (auto *Proto : OPT->quals()) {
+      if (!IC->ClassImplementsProtocol(Proto, false))
+        return false;
+    }
+    return true;
+  }
+  return false;
+}
+
+/// QIdProtocolsAdoptObjCObjectProtocols - Checks that protocols in
+/// QT's qualified-id protocol list adopt all protocols in IDecl's list
+/// of protocols.
+bool ASTContext::QIdProtocolsAdoptObjCObjectProtocols(QualType QT,
+                                                ObjCInterfaceDecl *IDecl) {
+  if (!QT->isObjCQualifiedIdType())
+    return false;
+  const ObjCObjectPointerType *OPT = QT->getAs<ObjCObjectPointerType>();
+  if (!OPT)
+    return false;
+  if (!IDecl->hasDefinition())
+    return false;
+  llvm::SmallPtrSet<ObjCProtocolDecl *, 8> InheritedProtocols;
+  CollectInheritedProtocols(IDecl, InheritedProtocols);
+  if (InheritedProtocols.empty())
+    return false;
+  // Check that if every protocol in list of id<plist> conforms to a protcol
+  // of IDecl's, then bridge casting is ok.
+  bool Conforms = false;
+  for (auto *Proto : OPT->quals()) {
+    Conforms = false;
+    for (auto *PI : InheritedProtocols) {
+      if (ProtocolCompatibleWithProtocol(Proto, PI)) {
+        Conforms = true;
+        break;
+      }
+    }
+    if (!Conforms)
+      break;
+  }
+  if (Conforms)
+    return true;
+  
+  for (auto *PI : InheritedProtocols) {
+    // If both the right and left sides have qualifiers.
+    bool Adopts = false;
+    for (auto *Proto : OPT->quals()) {
+      // return 'true' if 'PI' is in the inheritance hierarchy of Proto
+      if ((Adopts = ProtocolCompatibleWithProtocol(PI, Proto)))
+        break;
+    }
+    if (!Adopts)
+      return false;
+  }
+  return true;
+}
+
 /// getObjCObjectPointerType - Return a ObjCObjectPointerType type for
 /// the given object type.
 QualType ASTContext::getObjCObjectPointerType(QualType ObjectT) const {
   llvm::FoldingSetNodeID ID;
   ObjCObjectPointerType::Profile(ID, ObjectT);
 
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
   if (ObjCObjectPointerType *QT =
               ObjCObjectPointerTypes.FindNodeOrInsertPos(ID, InsertPos))
     return QualType(QT, 0);
@@ -3573,7 +3657,7 @@
     llvm::FoldingSetNodeID ID;
     DependentTypeOfExprType::Profile(ID, *this, tofExpr);
 
-    void *InsertPos = 0;
+    void *InsertPos = nullptr;
     DependentTypeOfExprType *Canon
       = DependentTypeOfExprTypes.FindNodeOrInsertPos(ID, InsertPos);
     if (Canon) {
@@ -3597,10 +3681,10 @@
 }
 
 /// getTypeOfType -  Unlike many "get<Type>" functions, we don't unique
-/// TypeOfType AST's. The only motivation to unique these nodes would be
+/// TypeOfType nodes. The only motivation to unique these nodes would be
 /// memory savings. Since typeof(t) is fairly uncommon, space shouldn't be
-/// an issue. This doesn't effect the type checker, since it operates
-/// on canonical type's (which are always unique).
+/// an issue. This doesn't affect the type checker, since it operates
+/// on canonical types (which are always unique).
 QualType ASTContext::getTypeOfType(QualType tofType) const {
   QualType Canonical = getCanonicalType(tofType);
   TypeOfType *tot = new (*this, TypeAlignment) TypeOfType(tofType, Canonical);
@@ -3609,39 +3693,34 @@
 }
 
 
-/// getDecltypeType -  Unlike many "get<Type>" functions, we don't unique
-/// DecltypeType AST's. The only motivation to unique these nodes would be
-/// memory savings. Since decltype(t) is fairly uncommon, space shouldn't be
-/// an issue. This doesn't effect the type checker, since it operates
-/// on canonical types (which are always unique).
+/// \brief Unlike many "get<Type>" functions, we don't unique DecltypeType
+/// nodes. This would never be helpful, since each such type has its own
+/// expression, and would not give a significant memory saving, since there
+/// is an Expr tree under each such type.
 QualType ASTContext::getDecltypeType(Expr *e, QualType UnderlyingType) const {
   DecltypeType *dt;
-  
-  // C++0x [temp.type]p2:
+
+  // C++11 [temp.type]p2:
   //   If an expression e involves a template parameter, decltype(e) denotes a
-  //   unique dependent type. Two such decltype-specifiers refer to the same 
-  //   type only if their expressions are equivalent (14.5.6.1). 
+  //   unique dependent type. Two such decltype-specifiers refer to the same
+  //   type only if their expressions are equivalent (14.5.6.1).
   if (e->isInstantiationDependent()) {
     llvm::FoldingSetNodeID ID;
     DependentDecltypeType::Profile(ID, *this, e);
 
-    void *InsertPos = 0;
+    void *InsertPos = nullptr;
     DependentDecltypeType *Canon
       = DependentDecltypeTypes.FindNodeOrInsertPos(ID, InsertPos);
-    if (Canon) {
-      // We already have a "canonical" version of an equivalent, dependent
-      // decltype type. Use that as our canonical type.
-      dt = new (*this, TypeAlignment) DecltypeType(e, UnderlyingType,
-                                       QualType((DecltypeType*)Canon, 0));
-    } else {
+    if (!Canon) {
       // Build a new, canonical typeof(expr) type.
       Canon = new (*this, TypeAlignment) DependentDecltypeType(*this, e);
       DependentDecltypeTypes.InsertNode(Canon, InsertPos);
-      dt = Canon;
     }
+    dt = new (*this, TypeAlignment)
+        DecltypeType(e, UnderlyingType, QualType((DecltypeType *)Canon, 0));
   } else {
-    dt = new (*this, TypeAlignment) DecltypeType(e, UnderlyingType, 
-                                      getCanonicalType(UnderlyingType));
+    dt = new (*this, TypeAlignment)
+        DecltypeType(e, UnderlyingType, getCanonicalType(UnderlyingType));
   }
   Types.push_back(dt);
   return QualType(dt, 0);
@@ -3671,7 +3750,7 @@
     return getAutoDeductType();
 
   // Look in the folding set for an existing type.
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
   llvm::FoldingSetNodeID ID;
   AutoType::Profile(ID, DeducedType, IsDecltypeAuto, IsDependent);
   if (AutoType *AT = AutoTypes.FindNodeOrInsertPos(ID, InsertPos))
@@ -3694,7 +3773,7 @@
   llvm::FoldingSetNodeID ID;
   AtomicType::Profile(ID, T);
 
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
   if (AtomicType *AT = AtomicTypes.FindNodeOrInsertPos(ID, InsertPos))
     return QualType(AT, 0);
 
@@ -3706,7 +3785,7 @@
 
     // Get the new insert position for the node we care about.
     AtomicType *NewIP = AtomicTypes.FindNodeOrInsertPos(ID, InsertPos);
-    assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+    assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
   }
   AtomicType *New = new (*this, TypeAlignment) AtomicType(T, Canonical);
   Types.push_back(New);
@@ -4065,7 +4144,7 @@
 NestedNameSpecifier *
 ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const {
   if (!NNS)
-    return 0;
+    return nullptr;
 
   switch (NNS->getKind()) {
   case NestedNameSpecifier::Identifier:
@@ -4077,13 +4156,13 @@
   case NestedNameSpecifier::Namespace:
     // A namespace is canonical; build a nested-name-specifier with
     // this namespace and no prefix.
-    return NestedNameSpecifier::Create(*this, 0, 
+    return NestedNameSpecifier::Create(*this, nullptr,
                                  NNS->getAsNamespace()->getOriginalNamespace());
 
   case NestedNameSpecifier::NamespaceAlias:
     // A namespace is canonical; build a nested-name-specifier with
     // this namespace and no prefix.
-    return NestedNameSpecifier::Create(*this, 0, 
+    return NestedNameSpecifier::Create(*this, nullptr,
                                     NNS->getAsNamespaceAlias()->getNamespace()
                                                       ->getOriginalNamespace());
 
@@ -4105,8 +4184,8 @@
     // Otherwise, just canonicalize the type, and force it to be a TypeSpec.
     // FIXME: Why are TypeSpec and TypeSpecWithTemplate distinct in the
     // first place?
-    return NestedNameSpecifier::Create(*this, 0, false,
-                                       const_cast<Type*>(T.getTypePtr()));
+    return NestedNameSpecifier::Create(*this, nullptr, false,
+                                       const_cast<Type *>(T.getTypePtr()));
   }
 
   case NestedNameSpecifier::Global:
@@ -4128,7 +4207,7 @@
 
   // Handle the common negative case fast.
   if (!isa<ArrayType>(T.getCanonicalType()))
-    return 0;
+    return nullptr;
 
   // Apply any qualifiers from the array type to the element type.  This
   // implements C99 6.7.3p8: "If the specification of an array type includes
@@ -4143,7 +4222,7 @@
 
   // If we have a simple case, just return now.
   const ArrayType *ATy = dyn_cast<ArrayType>(split.Ty);
-  if (ATy == 0 || qs.empty())
+  if (!ATy || qs.empty())
     return ATy;
 
   // Otherwise, we have an array and we have qualifiers on it.  Push the
@@ -4429,7 +4508,7 @@
   // FIXME: In C++, enum types are never integer types.
   if (ET->getDecl()->isComplete() && !ET->getDecl()->isScoped())
     return ET->getDecl()->getIntegerType().getTypePtr();
-  return NULL;
+  return nullptr;
 }
 
 /// getIntegerTypeOrder - Returns the highest ranked integer type:
@@ -4480,22 +4559,10 @@
   return 1;
 }
 
-static RecordDecl *
-CreateRecordDecl(const ASTContext &Ctx, RecordDecl::TagKind TK,
-                 DeclContext *DC, IdentifierInfo *Id) {
-  SourceLocation Loc;
-  if (Ctx.getLangOpts().CPlusPlus)
-    return CXXRecordDecl::Create(Ctx, TK, DC, Loc, Loc, Id);
-  else
-    return RecordDecl::Create(Ctx, TK, DC, Loc, Loc, Id);
-}
-
 // getCFConstantStringType - Return the type used for constant CFStrings.
 QualType ASTContext::getCFConstantStringType() const {
   if (!CFConstantStringTypeDecl) {
-    CFConstantStringTypeDecl =
-      CreateRecordDecl(*this, TTK_Struct, TUDecl,
-                       &Idents.get("NSConstantString"));
+    CFConstantStringTypeDecl = buildImplicitRecord("NSConstantString");
     CFConstantStringTypeDecl->startDefinition();
 
     QualType FieldTypes[4];
@@ -4513,9 +4580,9 @@
     for (unsigned i = 0; i < 4; ++i) {
       FieldDecl *Field = FieldDecl::Create(*this, CFConstantStringTypeDecl,
                                            SourceLocation(),
-                                           SourceLocation(), 0,
-                                           FieldTypes[i], /*TInfo=*/0,
-                                           /*BitWidth=*/0,
+                                           SourceLocation(), nullptr,
+                                           FieldTypes[i], /*TInfo=*/nullptr,
+                                           /*BitWidth=*/nullptr,
                                            /*Mutable=*/false,
                                            ICIS_NoInit);
       Field->setAccess(AS_public);
@@ -4530,8 +4597,7 @@
 
 QualType ASTContext::getObjCSuperType() const {
   if (ObjCSuperType.isNull()) {
-    RecordDecl *ObjCSuperTypeDecl  =
-      CreateRecordDecl(*this, TTK_Struct, TUDecl, &Idents.get("objc_super"));
+    RecordDecl *ObjCSuperTypeDecl = buildImplicitRecord("objc_super");
     TUDecl->addDecl(ObjCSuperTypeDecl);
     ObjCSuperType = getTagDeclType(ObjCSuperTypeDecl);
   }
@@ -4548,12 +4614,11 @@
   if (BlockDescriptorType)
     return getTagDeclType(BlockDescriptorType);
 
-  RecordDecl *T;
+  RecordDecl *RD;
   // FIXME: Needs the FlagAppleBlock bit.
-  T = CreateRecordDecl(*this, TTK_Struct, TUDecl,
-                       &Idents.get("__block_descriptor"));
-  T->startDefinition();
-  
+  RD = buildImplicitRecord("__block_descriptor");
+  RD->startDefinition();
+
   QualType FieldTypes[] = {
     UnsignedLongTy,
     UnsignedLongTy,
@@ -4565,20 +4630,17 @@
   };
 
   for (size_t i = 0; i < 2; ++i) {
-    FieldDecl *Field = FieldDecl::Create(*this, T, SourceLocation(),
-                                         SourceLocation(),
-                                         &Idents.get(FieldNames[i]),
-                                         FieldTypes[i], /*TInfo=*/0,
-                                         /*BitWidth=*/0,
-                                         /*Mutable=*/false,
-                                         ICIS_NoInit);
+    FieldDecl *Field = FieldDecl::Create(
+        *this, RD, SourceLocation(), SourceLocation(),
+        &Idents.get(FieldNames[i]), FieldTypes[i], /*TInfo=*/nullptr,
+        /*BitWidth=*/nullptr, /*Mutable=*/false, ICIS_NoInit);
     Field->setAccess(AS_public);
-    T->addDecl(Field);
+    RD->addDecl(Field);
   }
 
-  T->completeDefinition();
+  RD->completeDefinition();
 
-  BlockDescriptorType = T;
+  BlockDescriptorType = RD;
 
   return getTagDeclType(BlockDescriptorType);
 }
@@ -4587,12 +4649,11 @@
   if (BlockDescriptorExtendedType)
     return getTagDeclType(BlockDescriptorExtendedType);
 
-  RecordDecl *T;
+  RecordDecl *RD;
   // FIXME: Needs the FlagAppleBlock bit.
-  T = CreateRecordDecl(*this, TTK_Struct, TUDecl,
-                       &Idents.get("__block_descriptor_withcopydispose"));
-  T->startDefinition();
-  
+  RD = buildImplicitRecord("__block_descriptor_withcopydispose");
+  RD->startDefinition();
+
   QualType FieldTypes[] = {
     UnsignedLongTy,
     UnsignedLongTy,
@@ -4608,21 +4669,18 @@
   };
 
   for (size_t i = 0; i < 4; ++i) {
-    FieldDecl *Field = FieldDecl::Create(*this, T, SourceLocation(),
-                                         SourceLocation(),
-                                         &Idents.get(FieldNames[i]),
-                                         FieldTypes[i], /*TInfo=*/0,
-                                         /*BitWidth=*/0,
-                                         /*Mutable=*/false,
-                                         ICIS_NoInit);
+    FieldDecl *Field = FieldDecl::Create(
+        *this, RD, SourceLocation(), SourceLocation(),
+        &Idents.get(FieldNames[i]), FieldTypes[i], /*TInfo=*/nullptr,
+        /*BitWidth=*/nullptr,
+        /*Mutable=*/false, ICIS_NoInit);
     Field->setAccess(AS_public);
-    T->addDecl(Field);
+    RD->addDecl(Field);
   }
 
-  T->completeDefinition();
+  RD->completeDefinition();
 
-  BlockDescriptorExtendedType = T;
-
+  BlockDescriptorExtendedType = RD;
   return getTagDeclType(BlockDescriptorExtendedType);
 }
 
@@ -4692,12 +4750,8 @@
 
 TypedefDecl *ASTContext::getObjCInstanceTypeDecl() {
   if (!ObjCInstanceTypeDecl)
-    ObjCInstanceTypeDecl = TypedefDecl::Create(*this, 
-                                               getTranslationUnitDecl(),
-                                               SourceLocation(), 
-                                               SourceLocation(),
-                                               &Idents.get("instancetype"), 
-                                     getTrivialTypeSourceInfo(getObjCIdType()));
+    ObjCInstanceTypeDecl =
+        buildImplicitTypedef(getObjCIdType(), "instancetype");
   return ObjCInstanceTypeDecl;
 }
 
@@ -4728,6 +4782,12 @@
   return sz;
 }
 
+bool ASTContext::isMSStaticDataMemberInlineDefinition(const VarDecl *VD) const {
+  return getLangOpts().MSVCCompat && VD->isStaticDataMember() &&
+         VD->getType()->isIntegralOrEnumerationType() &&
+         !VD->getFirstDecl()->isOutOfLine() && VD->getFirstDecl()->hasInit();
+}
+
 static inline 
 std::string charUnitsToString(const CharUnits &CU) {
   return llvm::itostr(CU.getQuantity());
@@ -4743,21 +4803,19 @@
       Expr->getType()->getAs<BlockPointerType>()->getPointeeType();
   // Encode result type.
   if (getLangOpts().EncodeExtendedBlockSig)
-    getObjCEncodingForMethodParameter(Decl::OBJC_TQ_None,
-                            BlockTy->getAs<FunctionType>()->getResultType(),
-                            S, true /*Extended*/);
+    getObjCEncodingForMethodParameter(
+        Decl::OBJC_TQ_None, BlockTy->getAs<FunctionType>()->getReturnType(), S,
+        true /*Extended*/);
   else
-    getObjCEncodingForType(BlockTy->getAs<FunctionType>()->getResultType(),
-                           S);
+    getObjCEncodingForType(BlockTy->getAs<FunctionType>()->getReturnType(), S);
   // Compute size of all parameters.
   // Start with computing size of a pointer in number of bytes.
   // FIXME: There might(should) be a better way of doing this computation!
   SourceLocation Loc;
   CharUnits PtrSize = getTypeSizeInChars(VoidPtrTy);
   CharUnits ParmOffset = PtrSize;
-  for (BlockDecl::param_const_iterator PI = Decl->param_begin(),
-       E = Decl->param_end(); PI != E; ++PI) {
-    QualType PType = (*PI)->getType();
+  for (auto PI : Decl->params()) {
+    QualType PType = PI->getType();
     CharUnits sz = getObjCEncodingTypeSize(PType);
     if (sz.isZero())
       continue;
@@ -4771,9 +4829,7 @@
   
   // Argument types.
   ParmOffset = PtrSize;
-  for (BlockDecl::param_const_iterator PI = Decl->param_begin(), E =
-       Decl->param_end(); PI != E; ++PI) {
-    ParmVarDecl *PVDecl = *PI;
+  for (auto PVDecl : Decl->params()) {
     QualType PType = PVDecl->getOriginalType(); 
     if (const ArrayType *AT =
           dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) {
@@ -4798,12 +4854,11 @@
 bool ASTContext::getObjCEncodingForFunctionDecl(const FunctionDecl *Decl,
                                                 std::string& S) {
   // Encode result type.
-  getObjCEncodingForType(Decl->getResultType(), S);
+  getObjCEncodingForType(Decl->getReturnType(), S);
   CharUnits ParmOffset;
   // Compute size of all parameters.
-  for (FunctionDecl::param_const_iterator PI = Decl->param_begin(),
-       E = Decl->param_end(); PI != E; ++PI) {
-    QualType PType = (*PI)->getType();
+  for (auto PI : Decl->params()) {
+    QualType PType = PI->getType();
     CharUnits sz = getObjCEncodingTypeSize(PType);
     if (sz.isZero())
       continue;
@@ -4816,9 +4871,7 @@
   ParmOffset = CharUnits::Zero();
 
   // Argument types.
-  for (FunctionDecl::param_const_iterator PI = Decl->param_begin(),
-       E = Decl->param_end(); PI != E; ++PI) {
-    ParmVarDecl *PVDecl = *PI;
+  for (auto PVDecl : Decl->params()) {
     QualType PType = PVDecl->getOriginalType();
     if (const ArrayType *AT =
           dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) {
@@ -4845,7 +4898,7 @@
   // Encode type qualifer, 'in', 'inout', etc. for the parameter.
   getObjCEncodingForTypeQualifier(QT, S);
   // Encode parameter type.
-  getObjCEncodingForTypeImpl(T, S, true, true, 0,
+  getObjCEncodingForTypeImpl(T, S, true, true, nullptr,
                              true     /*OutermostType*/,
                              false    /*EncodingProperty*/, 
                              false    /*StructField*/, 
@@ -4860,8 +4913,8 @@
                                               bool Extended) const {
   // FIXME: This is not very efficient.
   // Encode return type.
-  getObjCEncodingForMethodParameter(Decl->getObjCDeclQualifier(), 
-                                    Decl->getResultType(), S, Extended);
+  getObjCEncodingForMethodParameter(Decl->getObjCDeclQualifier(),
+                                    Decl->getReturnType(), S, Extended);
   // Compute size of all parameters.
   // Start with computing size of a pointer in number of bytes.
   // FIXME: There might(should) be a better way of doing this computation!
@@ -4908,6 +4961,26 @@
   return false;
 }
 
+ObjCPropertyImplDecl *
+ASTContext::getObjCPropertyImplDeclForPropertyDecl(
+                                      const ObjCPropertyDecl *PD,
+                                      const Decl *Container) const {
+  if (!Container)
+    return nullptr;
+  if (const ObjCCategoryImplDecl *CID =
+      dyn_cast<ObjCCategoryImplDecl>(Container)) {
+    for (auto *PID : CID->property_impls())
+      if (PID->getPropertyDecl() == PD)
+        return PID;
+  } else {
+    const ObjCImplementationDecl *OID=cast<ObjCImplementationDecl>(Container);
+    for (auto *PID : OID->property_impls())
+      if (PID->getPropertyDecl() == PD)
+        return PID;
+  }
+  return nullptr;
+}
+
 /// getObjCEncodingForPropertyDecl - Return the encoded type for this
 /// property declaration. If non-NULL, Container must be either an
 /// ObjCCategoryImplDecl or ObjCImplementationDecl; it should only be
@@ -4938,39 +5011,14 @@
                                                 std::string& S) const {
   // Collect information from the property implementation decl(s).
   bool Dynamic = false;
-  ObjCPropertyImplDecl *SynthesizePID = 0;
+  ObjCPropertyImplDecl *SynthesizePID = nullptr;
 
-  // FIXME: Duplicated code due to poor abstraction.
-  if (Container) {
-    if (const ObjCCategoryImplDecl *CID =
-        dyn_cast<ObjCCategoryImplDecl>(Container)) {
-      for (ObjCCategoryImplDecl::propimpl_iterator
-             i = CID->propimpl_begin(), e = CID->propimpl_end();
-           i != e; ++i) {
-        ObjCPropertyImplDecl *PID = *i;
-        if (PID->getPropertyDecl() == PD) {
-          if (PID->getPropertyImplementation()==ObjCPropertyImplDecl::Dynamic) {
-            Dynamic = true;
-          } else {
-            SynthesizePID = PID;
-          }
-        }
-      }
-    } else {
-      const ObjCImplementationDecl *OID=cast<ObjCImplementationDecl>(Container);
-      for (ObjCCategoryImplDecl::propimpl_iterator
-             i = OID->propimpl_begin(), e = OID->propimpl_end();
-           i != e; ++i) {
-        ObjCPropertyImplDecl *PID = *i;
-        if (PID->getPropertyDecl() == PD) {
-          if (PID->getPropertyImplementation()==ObjCPropertyImplDecl::Dynamic) {
-            Dynamic = true;
-          } else {
-            SynthesizePID = PID;
-          }
-        }
-      }
-    }
+  if (ObjCPropertyImplDecl *PropertyImpDecl =
+      getObjCPropertyImplDeclForPropertyDecl(PD, Container)) {
+    if (PropertyImpDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
+      Dynamic = true;
+    else
+      SynthesizePID = PropertyImpDecl;
   }
 
   // FIXME: This is not very efficient.
@@ -4979,9 +5027,7 @@
   // Encode result type.
   // GCC has some special rules regarding encoding of properties which
   // closely resembles encoding of ivars.
-  getObjCEncodingForTypeImpl(PD->getType(), S, true, true, 0,
-                             true /* outermost type */,
-                             true /* encoding for property */);
+  getObjCEncodingForPropertyType(PD->getType(), S);
 
   if (PD->isReadOnly()) {
     S += ",R";
@@ -4989,6 +5035,8 @@
       S += ",C";
     if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_retain)
       S += ",&";
+    if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_weak)
+      S += ",W";
   } else {
     switch (PD->getSetterKind()) {
     case ObjCPropertyDecl::Assign: break;
@@ -5052,6 +5100,16 @@
                              true /* outermost type */);
 }
 
+void ASTContext::getObjCEncodingForPropertyType(QualType T,
+                                                std::string& S) const {
+  // Encode result type.
+  // GCC has some special rules regarding encoding of properties which
+  // closely resembles encoding of ivars.
+  getObjCEncodingForTypeImpl(T, S, true, true, nullptr,
+                             true /* outermost type */,
+                             true /* encoding property */);
+}
+
 static char getObjCEncodingForPrimitiveKind(const ASTContext *C,
                                             BuiltinType::Kind kind) {
     switch (kind) {
@@ -5181,15 +5239,15 @@
   case Type::Complex: {
     const ComplexType *CT = T->castAs<ComplexType>();
     S += 'j';
-    getObjCEncodingForTypeImpl(CT->getElementType(), S, false, false, 0, false,
-                               false);
+    getObjCEncodingForTypeImpl(CT->getElementType(), S, false, false, nullptr,
+                               false, false);
     return;
   }
 
   case Type::Atomic: {
     const AtomicType *AT = T->castAs<AtomicType>();
     S += 'A';
-    getObjCEncodingForTypeImpl(AT->getValueType(), S, false, false, 0,
+    getObjCEncodingForTypeImpl(AT->getValueType(), S, false, false, nullptr,
                                false, false);
     return;
   }
@@ -5261,7 +5319,7 @@
     getLegacyIntegralTypeEncoding(PointeeTy);
 
     getObjCEncodingForTypeImpl(PointeeTy, S, false, ExpandPointedToStructures,
-                               NULL);
+                               nullptr);
     return;
   }
 
@@ -5323,9 +5381,7 @@
       if (!RDecl->isUnion()) {
         getObjCEncodingForStructureImpl(RDecl, S, FD);
       } else {
-        for (RecordDecl::field_iterator Field = RDecl->field_begin(),
-                                     FieldEnd = RDecl->field_end();
-             Field != FieldEnd; ++Field) {
+        for (const auto *Field : RDecl->fields()) {
           if (FD) {
             S += '"';
             S += Field->getNameAsString();
@@ -5335,7 +5391,7 @@
           // Special case bit-fields.
           if (Field->isBitField()) {
             getObjCEncodingForTypeImpl(Field->getType(), S, false, true,
-                                       *Field);
+                                       Field);
           } else {
             QualType qt = Field->getType();
             getLegacyIntegralTypeEncoding(qt);
@@ -5359,37 +5415,38 @@
       
       S += '<';
       // Block return type
-      getObjCEncodingForTypeImpl(FT->getResultType(), S, 
-                                 ExpandPointedToStructures, ExpandStructures, 
-                                 FD, 
-                                 false /* OutermostType */, 
-                                 EncodingProperty, 
-                                 false /* StructField */, 
-                                 EncodeBlockParameters, 
-                                 EncodeClassNames);
+      getObjCEncodingForTypeImpl(
+          FT->getReturnType(), S, ExpandPointedToStructures, ExpandStructures,
+          FD, false /* OutermostType */, EncodingProperty,
+          false /* StructField */, EncodeBlockParameters, EncodeClassNames);
       // Block self
       S += "@?";
       // Block parameters
       if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT)) {
-        for (FunctionProtoType::arg_type_iterator I = FPT->arg_type_begin(),
-               E = FPT->arg_type_end(); I && (I != E); ++I) {
-          getObjCEncodingForTypeImpl(*I, S, 
-                                     ExpandPointedToStructures, 
-                                     ExpandStructures, 
-                                     FD, 
-                                     false /* OutermostType */, 
-                                     EncodingProperty, 
-                                     false /* StructField */, 
-                                     EncodeBlockParameters, 
-                                     EncodeClassNames);
-        }
+        for (const auto &I : FPT->param_types())
+          getObjCEncodingForTypeImpl(
+              I, S, ExpandPointedToStructures, ExpandStructures, FD,
+              false /* OutermostType */, EncodingProperty,
+              false /* StructField */, EncodeBlockParameters, EncodeClassNames);
       }
       S += '>';
     }
     return;
   }
 
-  case Type::ObjCObject:
+  case Type::ObjCObject: {
+    // hack to match legacy encoding of *id and *Class
+    QualType Ty = getObjCObjectPointerType(CT);
+    if (Ty->isObjCIdType()) {
+      S += "{objc_object=}";
+      return;
+    }
+    else if (Ty->isObjCClassType()) {
+      S += "{objc_class=}";
+      return;
+    }
+  }
+  
   case Type::ObjCInterface: {
     // Ignore protocol qualifiers when mangling at this level.
     T = T->castAs<ObjCObjectType>()->getBaseType();
@@ -5441,10 +5498,9 @@
         // Note that we do extended encoding of protocol qualifer list
         // Only when doing ivar or property encoding.
         S += '"';
-        for (ObjCObjectPointerType::qual_iterator I = OPT->qual_begin(),
-             E = OPT->qual_end(); I != E; ++I) {
+        for (const auto *I : OPT->quals()) {
           S += '<';
-          S += (*I)->getNameAsString();
+          S += I->getNameAsString();
           S += '>';
         }
         S += '"';
@@ -5476,7 +5532,7 @@
       }
       getObjCEncodingForTypeImpl(PointeeTy, S,
                                  false, ExpandPointedToStructures,
-                                 NULL,
+                                 nullptr,
                                  false, false, false, false, false,
                                  /*EncodePointerToObjCTypedef*/true);
       return;
@@ -5487,10 +5543,9 @@
         (FD || EncodingProperty || EncodeClassNames)) {
       S += '"';
       S += OPT->getInterfaceDecl()->getIdentifier()->getName();
-      for (ObjCObjectPointerType::qual_iterator I = OPT->qual_begin(),
-           E = OPT->qual_end(); I != E; ++I) {
+      for (const auto *I : OPT->quals()) {
         S += '<';
-        S += (*I)->getNameAsString();
+        S += I->getNameAsString();
         S += '>';
       }
       S += '"';
@@ -5543,11 +5598,9 @@
   const ASTRecordLayout &layout = getASTRecordLayout(RDecl);
 
   if (CXXRec) {
-    for (CXXRecordDecl::base_class_iterator
-           BI = CXXRec->bases_begin(),
-           BE = CXXRec->bases_end(); BI != BE; ++BI) {
-      if (!BI->isVirtual()) {
-        CXXRecordDecl *base = BI->getType()->getAsCXXRecordDecl();
+    for (const auto &BI : CXXRec->bases()) {
+      if (!BI.isVirtual()) {
+        CXXRecordDecl *base = BI.getType()->getAsCXXRecordDecl();
         if (base->isEmpty())
           continue;
         uint64_t offs = toBits(layout.getBaseClassOffset(base));
@@ -5567,10 +5620,8 @@
   }
 
   if (CXXRec && includeVBases) {
-    for (CXXRecordDecl::base_class_iterator
-           BI = CXXRec->vbases_begin(),
-           BE = CXXRec->vbases_end(); BI != BE; ++BI) {
-      CXXRecordDecl *base = BI->getType()->getAsCXXRecordDecl();
+    for (const auto &BI : CXXRec->vbases()) {
+      CXXRecordDecl *base = BI.getType()->getAsCXXRecordDecl();
       if (base->isEmpty())
         continue;
       uint64_t offs = toBits(layout.getVBaseClassOffset(base));
@@ -5588,7 +5639,9 @@
     size = layout.getSize();
   }
 
+#ifndef NDEBUG
   uint64_t CurOffs = 0;
+#endif
   std::multimap<uint64_t, NamedDecl *>::iterator
     CurLayObj = FieldOrBaseOffsets.begin();
 
@@ -5602,19 +5655,21 @@
       S += '"';
     }
     S += "^^?";
+#ifndef NDEBUG
     CurOffs += getTypeSize(VoidPtrTy);
+#endif
   }
 
   if (!RDecl->hasFlexibleArrayMember()) {
     // Mark the end of the structure.
     uint64_t offs = toBits(size);
     FieldOrBaseOffsets.insert(FieldOrBaseOffsets.upper_bound(offs),
-                              std::make_pair(offs, (NamedDecl*)0));
+                              std::make_pair(offs, nullptr));
   }
 
   for (; CurLayObj != FieldOrBaseOffsets.end(); ++CurLayObj) {
+#ifndef NDEBUG
     assert(CurOffs <= CurLayObj->first);
-
     if (CurOffs < CurLayObj->first) {
       uint64_t padding = CurLayObj->first - CurOffs; 
       // FIXME: There doesn't seem to be a way to indicate in the encoding that
@@ -5626,9 +5681,10 @@
       // longer then though.
       CurOffs += padding;
     }
+#endif
 
     NamedDecl *dcl = CurLayObj->second;
-    if (dcl == 0)
+    if (!dcl)
       break; // reached end of structure.
 
     if (CXXRecordDecl *base = dyn_cast<CXXRecordDecl>(dcl)) {
@@ -5638,7 +5694,9 @@
       // making the encoding type bigger than it really is.
       getObjCEncodingForStructureImpl(base, S, FD, /*includeVBases*/false);
       assert(!base->isEmpty());
+#ifndef NDEBUG
       CurOffs += toBits(getASTRecordLayout(base).getNonVirtualSize());
+#endif
     } else {
       FieldDecl *field = cast<FieldDecl>(dcl);
       if (FD) {
@@ -5649,7 +5707,9 @@
 
       if (field->isBitField()) {
         EncodeBitField(this, S, field->getType(), field);
+#ifndef NDEBUG
         CurOffs += field->getBitWidthValue(*this);
+#endif
       } else {
         QualType qt = field->getType();
         getLegacyIntegralTypeEncoding(qt);
@@ -5657,7 +5717,9 @@
                                    /*OutermostType*/false,
                                    /*EncodingProperty*/false,
                                    /*StructField*/true);
+#ifndef NDEBUG
         CurOffs += getTypeSize(field->getType());
+#endif
       }
     }
   }
@@ -5681,41 +5743,27 @@
 
 TypedefDecl *ASTContext::getObjCIdDecl() const {
   if (!ObjCIdDecl) {
-    QualType T = getObjCObjectType(ObjCBuiltinIdTy, 0, 0);
+    QualType T = getObjCObjectType(ObjCBuiltinIdTy, nullptr, 0);
     T = getObjCObjectPointerType(T);
-    TypeSourceInfo *IdInfo = getTrivialTypeSourceInfo(T);
-    ObjCIdDecl = TypedefDecl::Create(const_cast<ASTContext &>(*this),
-                                     getTranslationUnitDecl(),
-                                     SourceLocation(), SourceLocation(),
-                                     &Idents.get("id"), IdInfo);
+    ObjCIdDecl = buildImplicitTypedef(T, "id");
   }
-  
   return ObjCIdDecl;
 }
 
 TypedefDecl *ASTContext::getObjCSelDecl() const {
   if (!ObjCSelDecl) {
-    QualType SelT = getPointerType(ObjCBuiltinSelTy);
-    TypeSourceInfo *SelInfo = getTrivialTypeSourceInfo(SelT);
-    ObjCSelDecl = TypedefDecl::Create(const_cast<ASTContext &>(*this),
-                                      getTranslationUnitDecl(),
-                                      SourceLocation(), SourceLocation(),
-                                      &Idents.get("SEL"), SelInfo);
+    QualType T = getPointerType(ObjCBuiltinSelTy);
+    ObjCSelDecl = buildImplicitTypedef(T, "SEL");
   }
   return ObjCSelDecl;
 }
 
 TypedefDecl *ASTContext::getObjCClassDecl() const {
   if (!ObjCClassDecl) {
-    QualType T = getObjCObjectType(ObjCBuiltinClassTy, 0, 0);
+    QualType T = getObjCObjectType(ObjCBuiltinClassTy, nullptr, 0);
     T = getObjCObjectPointerType(T);
-    TypeSourceInfo *ClassInfo = getTrivialTypeSourceInfo(T);
-    ObjCClassDecl = TypedefDecl::Create(const_cast<ASTContext &>(*this),
-                                        getTranslationUnitDecl(),
-                                        SourceLocation(), SourceLocation(),
-                                        &Idents.get("Class"), ClassInfo);
+    ObjCClassDecl = buildImplicitTypedef(T, "Class");
   }
-  
   return ObjCClassDecl;
 }
 
@@ -5725,7 +5773,7 @@
       = ObjCInterfaceDecl::Create(*this, getTranslationUnitDecl(), 
                                   SourceLocation(),
                                   &Idents.get("Protocol"),
-                                  /*PrevDecl=*/0,
+                                  /*PrevDecl=*/nullptr,
                                   SourceLocation(), true);    
   }
   
@@ -5738,56 +5786,30 @@
 
 static TypedefDecl *CreateCharPtrBuiltinVaListDecl(const ASTContext *Context) {
   // typedef char* __builtin_va_list;
-  QualType CharPtrType = Context->getPointerType(Context->CharTy);
-  TypeSourceInfo *TInfo
-    = Context->getTrivialTypeSourceInfo(CharPtrType);
-
-  TypedefDecl *VaListTypeDecl
-    = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
-                          Context->getTranslationUnitDecl(),
-                          SourceLocation(), SourceLocation(),
-                          &Context->Idents.get("__builtin_va_list"),
-                          TInfo);
-  return VaListTypeDecl;
+  QualType T = Context->getPointerType(Context->CharTy);
+  return Context->buildImplicitTypedef(T, "__builtin_va_list");
 }
 
 static TypedefDecl *CreateVoidPtrBuiltinVaListDecl(const ASTContext *Context) {
   // typedef void* __builtin_va_list;
-  QualType VoidPtrType = Context->getPointerType(Context->VoidTy);
-  TypeSourceInfo *TInfo
-    = Context->getTrivialTypeSourceInfo(VoidPtrType);
-
-  TypedefDecl *VaListTypeDecl
-    = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
-                          Context->getTranslationUnitDecl(),
-                          SourceLocation(), SourceLocation(),
-                          &Context->Idents.get("__builtin_va_list"),
-                          TInfo);
-  return VaListTypeDecl;
+  QualType T = Context->getPointerType(Context->VoidTy);
+  return Context->buildImplicitTypedef(T, "__builtin_va_list");
 }
 
 static TypedefDecl *
 CreateAArch64ABIBuiltinVaListDecl(const ASTContext *Context) {
-  RecordDecl *VaListTagDecl;
+  // struct __va_list
+  RecordDecl *VaListTagDecl = Context->buildImplicitRecord("__va_list");
   if (Context->getLangOpts().CPlusPlus) {
     // namespace std { struct __va_list {
     NamespaceDecl *NS;
     NS = NamespaceDecl::Create(const_cast<ASTContext &>(*Context),
                                Context->getTranslationUnitDecl(),
-                               /*Inline*/false, SourceLocation(),
+                               /*Inline*/ false, SourceLocation(),
                                SourceLocation(), &Context->Idents.get("std"),
-                               /*PrevDecl*/0);
-
-    VaListTagDecl = CXXRecordDecl::Create(*Context, TTK_Struct,
-                                          Context->getTranslationUnitDecl(),
-                                          SourceLocation(), SourceLocation(),
-                                          &Context->Idents.get("__va_list"));
+                               /*PrevDecl*/ nullptr);
+    NS->setImplicit();
     VaListTagDecl->setDeclContext(NS);
-  } else {
-    // struct __va_list
-    VaListTagDecl = CreateRecordDecl(*Context, TTK_Struct,
-                                   Context->getTranslationUnitDecl(),
-                                   &Context->Idents.get("__va_list"));
   }
 
   VaListTagDecl->startDefinition();
@@ -5823,8 +5845,8 @@
                                          SourceLocation(),
                                          SourceLocation(),
                                          &Context->Idents.get(FieldNames[i]),
-                                         FieldTypes[i], /*TInfo=*/0,
-                                         /*BitWidth=*/0,
+                                         FieldTypes[i], /*TInfo=*/nullptr,
+                                         /*BitWidth=*/nullptr,
                                          /*Mutable=*/false,
                                          ICIS_NoInit);
     Field->setAccess(AS_public);
@@ -5835,23 +5857,14 @@
   Context->VaListTagTy = VaListTagType;
 
   // } __builtin_va_list;
-  TypedefDecl *VaListTypedefDecl
-    = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
-                          Context->getTranslationUnitDecl(),
-                          SourceLocation(), SourceLocation(),
-                          &Context->Idents.get("__builtin_va_list"),
-                          Context->getTrivialTypeSourceInfo(VaListTagType));
-
-  return VaListTypedefDecl;
+  return Context->buildImplicitTypedef(VaListTagType, "__builtin_va_list");
 }
 
 static TypedefDecl *CreatePowerABIBuiltinVaListDecl(const ASTContext *Context) {
   // typedef struct __va_list_tag {
   RecordDecl *VaListTagDecl;
 
-  VaListTagDecl = CreateRecordDecl(*Context, TTK_Struct,
-                                   Context->getTranslationUnitDecl(),
-                                   &Context->Idents.get("__va_list_tag"));
+  VaListTagDecl = Context->buildImplicitRecord("__va_list_tag");
   VaListTagDecl->startDefinition();
 
   const size_t NumFields = 5;
@@ -5884,8 +5897,8 @@
                                          SourceLocation(),
                                          SourceLocation(),
                                          &Context->Idents.get(FieldNames[i]),
-                                         FieldTypes[i], /*TInfo=*/0,
-                                         /*BitWidth=*/0,
+                                         FieldTypes[i], /*TInfo=*/nullptr,
+                                         /*BitWidth=*/nullptr,
                                          /*Mutable=*/false,
                                          ICIS_NoInit);
     Field->setAccess(AS_public);
@@ -5896,12 +5909,9 @@
   Context->VaListTagTy = VaListTagType;
 
   // } __va_list_tag;
-  TypedefDecl *VaListTagTypedefDecl
-    = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
-                          Context->getTranslationUnitDecl(),
-                          SourceLocation(), SourceLocation(),
-                          &Context->Idents.get("__va_list_tag"),
-                          Context->getTrivialTypeSourceInfo(VaListTagType));
+  TypedefDecl *VaListTagTypedefDecl =
+      Context->buildImplicitTypedef(VaListTagType, "__va_list_tag");
+
   QualType VaListTagTypedefType =
     Context->getTypedefType(VaListTagTypedefDecl);
 
@@ -5910,25 +5920,14 @@
   QualType VaListTagArrayType
     = Context->getConstantArrayType(VaListTagTypedefType,
                                     Size, ArrayType::Normal, 0);
-  TypeSourceInfo *TInfo
-    = Context->getTrivialTypeSourceInfo(VaListTagArrayType);
-  TypedefDecl *VaListTypedefDecl
-    = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
-                          Context->getTranslationUnitDecl(),
-                          SourceLocation(), SourceLocation(),
-                          &Context->Idents.get("__builtin_va_list"),
-                          TInfo);
-
-  return VaListTypedefDecl;
+  return Context->buildImplicitTypedef(VaListTagArrayType, "__builtin_va_list");
 }
 
 static TypedefDecl *
 CreateX86_64ABIBuiltinVaListDecl(const ASTContext *Context) {
   // typedef struct __va_list_tag {
   RecordDecl *VaListTagDecl;
-  VaListTagDecl = CreateRecordDecl(*Context, TTK_Struct,
-                                   Context->getTranslationUnitDecl(),
-                                   &Context->Idents.get("__va_list_tag"));
+  VaListTagDecl = Context->buildImplicitRecord("__va_list_tag");
   VaListTagDecl->startDefinition();
 
   const size_t NumFields = 4;
@@ -5958,8 +5957,8 @@
                                          SourceLocation(),
                                          SourceLocation(),
                                          &Context->Idents.get(FieldNames[i]),
-                                         FieldTypes[i], /*TInfo=*/0,
-                                         /*BitWidth=*/0,
+                                         FieldTypes[i], /*TInfo=*/nullptr,
+                                         /*BitWidth=*/nullptr,
                                          /*Mutable=*/false,
                                          ICIS_NoInit);
     Field->setAccess(AS_public);
@@ -5970,12 +5969,9 @@
   Context->VaListTagTy = VaListTagType;
 
   // } __va_list_tag;
-  TypedefDecl *VaListTagTypedefDecl
-    = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
-                          Context->getTranslationUnitDecl(),
-                          SourceLocation(), SourceLocation(),
-                          &Context->Idents.get("__va_list_tag"),
-                          Context->getTrivialTypeSourceInfo(VaListTagType));
+  TypedefDecl *VaListTagTypedefDecl =
+      Context->buildImplicitTypedef(VaListTagType, "__va_list_tag");
+
   QualType VaListTagTypedefType =
     Context->getTypedefType(VaListTagTypedefDecl);
 
@@ -5984,16 +5980,7 @@
   QualType VaListTagArrayType
     = Context->getConstantArrayType(VaListTagTypedefType,
                                       Size, ArrayType::Normal,0);
-  TypeSourceInfo *TInfo
-    = Context->getTrivialTypeSourceInfo(VaListTagArrayType);
-  TypedefDecl *VaListTypedefDecl
-    = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
-                          Context->getTranslationUnitDecl(),
-                          SourceLocation(), SourceLocation(),
-                          &Context->Idents.get("__builtin_va_list"),
-                          TInfo);
-
-  return VaListTypedefDecl;
+  return Context->buildImplicitTypedef(VaListTagArrayType, "__builtin_va_list");
 }
 
 static TypedefDecl *CreatePNaClABIBuiltinVaListDecl(const ASTContext *Context) {
@@ -6002,19 +5989,13 @@
   QualType IntArrayType
     = Context->getConstantArrayType(Context->IntTy,
 				    Size, ArrayType::Normal, 0);
-  TypedefDecl *VaListTypedefDecl
-    = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
-                          Context->getTranslationUnitDecl(),
-                          SourceLocation(), SourceLocation(),
-                          &Context->Idents.get("__builtin_va_list"),
-                          Context->getTrivialTypeSourceInfo(IntArrayType));
-
-  return VaListTypedefDecl;
+  return Context->buildImplicitTypedef(IntArrayType, "__builtin_va_list");
 }
 
 static TypedefDecl *
 CreateAAPCSABIBuiltinVaListDecl(const ASTContext *Context) {
-  RecordDecl *VaListDecl;
+  // struct __va_list
+  RecordDecl *VaListDecl = Context->buildImplicitRecord("__va_list");
   if (Context->getLangOpts().CPlusPlus) {
     // namespace std { struct __va_list {
     NamespaceDecl *NS;
@@ -6022,20 +6003,9 @@
                                Context->getTranslationUnitDecl(),
                                /*Inline*/false, SourceLocation(),
                                SourceLocation(), &Context->Idents.get("std"),
-                               /*PrevDecl*/0);
-
-    VaListDecl = CXXRecordDecl::Create(*Context, TTK_Struct,
-                                       Context->getTranslationUnitDecl(),
-                                       SourceLocation(), SourceLocation(),
-                                       &Context->Idents.get("__va_list"));
-
+                               /*PrevDecl*/ nullptr);
+    NS->setImplicit();
     VaListDecl->setDeclContext(NS);
-
-  } else {
-    // struct __va_list {
-    VaListDecl = CreateRecordDecl(*Context, TTK_Struct,
-                                  Context->getTranslationUnitDecl(),
-                                  &Context->Idents.get("__va_list"));
   }
 
   VaListDecl->startDefinition();
@@ -6047,8 +6017,8 @@
                                        SourceLocation(),
                                        &Context->Idents.get("__ap"),
                                        Context->getPointerType(Context->VoidTy),
-                                       /*TInfo=*/0,
-                                       /*BitWidth=*/0,
+                                       /*TInfo=*/nullptr,
+                                       /*BitWidth=*/nullptr,
                                        /*Mutable=*/false,
                                        ICIS_NoInit);
   Field->setAccess(AS_public);
@@ -6058,26 +6028,15 @@
   VaListDecl->completeDefinition();
 
   // typedef struct __va_list __builtin_va_list;
-  TypeSourceInfo *TInfo
-    = Context->getTrivialTypeSourceInfo(Context->getRecordType(VaListDecl));
-
-  TypedefDecl *VaListTypeDecl
-    = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
-                          Context->getTranslationUnitDecl(),
-                          SourceLocation(), SourceLocation(),
-                          &Context->Idents.get("__builtin_va_list"),
-                          TInfo);
-
-  return VaListTypeDecl;
+  QualType T = Context->getRecordType(VaListDecl);
+  return Context->buildImplicitTypedef(T, "__builtin_va_list");
 }
 
 static TypedefDecl *
 CreateSystemZBuiltinVaListDecl(const ASTContext *Context) {
   // typedef struct __va_list_tag {
   RecordDecl *VaListTagDecl;
-  VaListTagDecl = CreateRecordDecl(*Context, TTK_Struct,
-                                   Context->getTranslationUnitDecl(),
-                                   &Context->Idents.get("__va_list_tag"));
+  VaListTagDecl = Context->buildImplicitRecord("__va_list_tag");
   VaListTagDecl->startDefinition();
 
   const size_t NumFields = 4;
@@ -6107,8 +6066,8 @@
                                          SourceLocation(),
                                          SourceLocation(),
                                          &Context->Idents.get(FieldNames[i]),
-                                         FieldTypes[i], /*TInfo=*/0,
-                                         /*BitWidth=*/0,
+                                         FieldTypes[i], /*TInfo=*/nullptr,
+                                         /*BitWidth=*/nullptr,
                                          /*Mutable=*/false,
                                          ICIS_NoInit);
     Field->setAccess(AS_public);
@@ -6119,12 +6078,8 @@
   Context->VaListTagTy = VaListTagType;
 
   // } __va_list_tag;
-  TypedefDecl *VaListTagTypedefDecl
-    = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
-                          Context->getTranslationUnitDecl(),
-                          SourceLocation(), SourceLocation(),
-                          &Context->Idents.get("__va_list_tag"),
-                          Context->getTrivialTypeSourceInfo(VaListTagType));
+  TypedefDecl *VaListTagTypedefDecl =
+      Context->buildImplicitTypedef(VaListTagType, "__va_list_tag");
   QualType VaListTagTypedefType =
     Context->getTypedefType(VaListTagTypedefDecl);
 
@@ -6133,16 +6088,8 @@
   QualType VaListTagArrayType
     = Context->getConstantArrayType(VaListTagTypedefType,
                                       Size, ArrayType::Normal,0);
-  TypeSourceInfo *TInfo
-    = Context->getTrivialTypeSourceInfo(VaListTagArrayType);
-  TypedefDecl *VaListTypedefDecl
-    = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
-                          Context->getTranslationUnitDecl(),
-                          SourceLocation(), SourceLocation(),
-                          &Context->Idents.get("__builtin_va_list"),
-                          TInfo);
 
-  return VaListTypedefDecl;
+  return Context->buildImplicitTypedef(VaListTagArrayType, "__builtin_va_list");
 }
 
 static TypedefDecl *CreateVaListDecl(const ASTContext *Context,
@@ -6170,8 +6117,10 @@
 }
 
 TypedefDecl *ASTContext::getBuiltinVaListDecl() const {
-  if (!BuiltinVaListDecl)
+  if (!BuiltinVaListDecl) {
     BuiltinVaListDecl = CreateVaListDecl(this, Target->getBuiltinVaListKind());
+    assert(BuiltinVaListDecl->isImplicit());
+  }
 
   return BuiltinVaListDecl;
 }
@@ -6228,7 +6177,7 @@
   llvm::FoldingSetNodeID ID;
   QualifiedTemplateName::Profile(ID, NNS, TemplateKeyword, Template);
 
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
   QualifiedTemplateName *QTN =
     QualifiedTemplateNames.FindNodeOrInsertPos(ID, InsertPos);
   if (!QTN) {
@@ -6251,7 +6200,7 @@
   llvm::FoldingSetNodeID ID;
   DependentTemplateName::Profile(ID, NNS, Name);
 
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
   DependentTemplateName *QTN =
     DependentTemplateNames.FindNodeOrInsertPos(ID, InsertPos);
 
@@ -6286,8 +6235,8 @@
   
   llvm::FoldingSetNodeID ID;
   DependentTemplateName::Profile(ID, NNS, Operator);
-  
-  void *InsertPos = 0;
+
+  void *InsertPos = nullptr;
   DependentTemplateName *QTN
     = DependentTemplateNames.FindNodeOrInsertPos(ID, InsertPos);
   
@@ -6318,8 +6267,8 @@
                                          TemplateName replacement) const {
   llvm::FoldingSetNodeID ID;
   SubstTemplateTemplateParmStorage::Profile(ID, param, replacement);
-  
-  void *insertPos = 0;
+
+  void *insertPos = nullptr;
   SubstTemplateTemplateParmStorage *subst
     = SubstTemplateTemplateParms.FindNodeOrInsertPos(ID, insertPos);
   
@@ -6337,8 +6286,8 @@
   ASTContext &Self = const_cast<ASTContext &>(*this);
   llvm::FoldingSetNodeID ID;
   SubstTemplateTemplateParmPackStorage::Profile(ID, Self, Param, ArgPack);
-  
-  void *InsertPos = 0;
+
+  void *InsertPos = nullptr;
   SubstTemplateTemplateParmPackStorage *Subst
     = SubstTemplateTemplateParmPacks.FindNodeOrInsertPos(ID, InsertPos);
   
@@ -6455,9 +6404,8 @@
                                            ObjCProtocolDecl *rProto) const {
   if (declaresSameEntity(lProto, rProto))
     return true;
-  for (ObjCProtocolDecl::protocol_iterator PI = rProto->protocol_begin(),
-       E = rProto->protocol_end(); PI != E; ++PI)
-    if (ProtocolCompatibleWithProtocol(lProto, *PI))
+  for (auto *PI : rProto->protocols())
+    if (ProtocolCompatibleWithProtocol(lProto, PI))
       return true;
   return false;
 }
@@ -6470,13 +6418,9 @@
   const ObjCObjectPointerType *rhsOPT = rhs->getAs<ObjCObjectPointerType>();
   assert ((lhsQID && rhsOPT) && "ObjCQualifiedClassTypesAreCompatible");
   
-  for (ObjCObjectPointerType::qual_iterator I = lhsQID->qual_begin(),
-       E = lhsQID->qual_end(); I != E; ++I) {
+  for (auto *lhsProto : lhsQID->quals()) {
     bool match = false;
-    ObjCProtocolDecl *lhsProto = *I;
-    for (ObjCObjectPointerType::qual_iterator J = rhsOPT->qual_begin(),
-         E = rhsOPT->qual_end(); J != E; ++J) {
-      ObjCProtocolDecl *rhsProto = *J;
+    for (auto *rhsProto : rhsOPT->quals()) {
       if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto)) {
         match = true;
         break;
@@ -6509,12 +6453,11 @@
       // If the RHS is a unqualified interface pointer "NSString*",
       // make sure we check the class hierarchy.
       if (ObjCInterfaceDecl *rhsID = rhsOPT->getInterfaceDecl()) {
-        for (ObjCObjectPointerType::qual_iterator I = lhsQID->qual_begin(),
-             E = lhsQID->qual_end(); I != E; ++I) {
+        for (auto *I : lhsQID->quals()) {
           // when comparing an id<P> on lhs with a static type on rhs,
           // see if static class implements all of id's protocols, directly or
           // through its super class and categories.
-          if (!rhsID->ClassImplementsProtocol(*I, true))
+          if (!rhsID->ClassImplementsProtocol(I, true))
             return false;
         }
       }
@@ -6522,17 +6465,13 @@
       return true;
     }
     // Both the right and left sides have qualifiers.
-    for (ObjCObjectPointerType::qual_iterator I = lhsQID->qual_begin(),
-         E = lhsQID->qual_end(); I != E; ++I) {
-      ObjCProtocolDecl *lhsProto = *I;
+    for (auto *lhsProto : lhsQID->quals()) {
       bool match = false;
 
       // when comparing an id<P> on lhs with a static type on rhs,
       // see if static class implements all of id's protocols, directly or
       // through its super class and categories.
-      for (ObjCObjectPointerType::qual_iterator J = rhsOPT->qual_begin(),
-           E = rhsOPT->qual_end(); J != E; ++J) {
-        ObjCProtocolDecl *rhsProto = *J;
+      for (auto *rhsProto : rhsOPT->quals()) {
         if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) ||
             (compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) {
           match = true;
@@ -6542,12 +6481,11 @@
       // If the RHS is a qualified interface pointer "NSString<P>*",
       // make sure we check the class hierarchy.
       if (ObjCInterfaceDecl *rhsID = rhsOPT->getInterfaceDecl()) {
-        for (ObjCObjectPointerType::qual_iterator I = lhsQID->qual_begin(),
-             E = lhsQID->qual_end(); I != E; ++I) {
+        for (auto *I : lhsQID->quals()) {
           // when comparing an id<P> on lhs with a static type on rhs,
           // see if static class implements all of id's protocols, directly or
           // through its super class and categories.
-          if (rhsID->ClassImplementsProtocol(*I, true)) {
+          if (rhsID->ClassImplementsProtocol(I, true)) {
             match = true;
             break;
           }
@@ -6566,9 +6504,7 @@
   if (const ObjCObjectPointerType *lhsOPT =
         lhs->getAsObjCInterfacePointerType()) {
     // If both the right and left sides have qualifiers.
-    for (ObjCObjectPointerType::qual_iterator I = lhsOPT->qual_begin(),
-         E = lhsOPT->qual_end(); I != E; ++I) {
-      ObjCProtocolDecl *lhsProto = *I;
+    for (auto *lhsProto : lhsOPT->quals()) {
       bool match = false;
 
       // when comparing an id<P> on rhs with a static type on lhs,
@@ -6576,9 +6512,7 @@
       // through its super class and categories.
       // First, lhs protocols in the qualifier list must be found, direct
       // or indirect in rhs's qualifier list or it is a mismatch.
-      for (ObjCObjectPointerType::qual_iterator J = rhsQID->qual_begin(),
-           E = rhsQID->qual_end(); J != E; ++J) {
-        ObjCProtocolDecl *rhsProto = *J;
+      for (auto *rhsProto : rhsQID->quals()) {
         if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) ||
             (compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) {
           match = true;
@@ -6599,14 +6533,9 @@
       // assume that it is mismatch.
       if (LHSInheritedProtocols.empty() && lhsOPT->qual_empty())
         return false;
-      for (llvm::SmallPtrSet<ObjCProtocolDecl*,8>::iterator I =
-           LHSInheritedProtocols.begin(),
-           E = LHSInheritedProtocols.end(); I != E; ++I) {
+      for (auto *lhsProto : LHSInheritedProtocols) {
         bool match = false;
-        ObjCProtocolDecl *lhsProto = (*I);
-        for (ObjCObjectPointerType::qual_iterator J = rhsQID->qual_begin(),
-             E = rhsQID->qual_end(); J != E; ++J) {
-          ObjCProtocolDecl *rhsProto = *J;
+        for (auto *rhsProto : rhsQID->quals()) {
           if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) ||
               (compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) {
             match = true;
@@ -6799,16 +6728,9 @@
       if (SuperClassInheritedProtocols.empty())
         return false;
       
-      for (ObjCObjectType::qual_iterator LHSPI = LHS->qual_begin(),
-           LHSPE = LHS->qual_end();
-           LHSPI != LHSPE; LHSPI++) {
-        bool SuperImplementsProtocol = false;
-        ObjCProtocolDecl *LHSProto = (*LHSPI);
-        
-        for (llvm::SmallPtrSet<ObjCProtocolDecl*,8>::iterator I =
-             SuperClassInheritedProtocols.begin(),
-             E = SuperClassInheritedProtocols.end(); I != E; ++I) {
-          ObjCProtocolDecl *SuperClassProto = (*I);
+      for (const auto *LHSProto : LHS->quals()) {
+        bool SuperImplementsProtocol = false;        
+        for (auto *SuperClassProto : SuperClassInheritedProtocols) {
           if (SuperClassProto->lookupProtocolNamed(LHSProto->getIdentifier())) {
             SuperImplementsProtocol = true;
             break;
@@ -6822,17 +6744,13 @@
     return false;
   }
 
-  for (ObjCObjectType::qual_iterator LHSPI = LHS->qual_begin(),
-                                     LHSPE = LHS->qual_end();
-       LHSPI != LHSPE; LHSPI++) {
+  for (const auto *LHSPI : LHS->quals()) {
     bool RHSImplementsProtocol = false;
 
     // If the RHS doesn't implement the protocol on the left, the types
     // are incompatible.
-    for (ObjCObjectType::qual_iterator RHSPI = RHS->qual_begin(),
-                                       RHSPE = RHS->qual_end();
-         RHSPI != RHSPE; RHSPI++) {
-      if ((*RHSPI)->lookupProtocolNamed((*LHSPI)->getIdentifier())) {
+    for (auto *RHSPI : RHS->quals()) {
+      if (RHSPI->lookupProtocolNamed(LHSPI->getIdentifier())) {
         RHSImplementsProtocol = true;
         break;
       }
@@ -6892,9 +6810,8 @@
   if (const RecordType *UT = T->getAsUnionType()) {
     RecordDecl *UD = UT->getDecl();
     if (UD->hasAttr<TransparentUnionAttr>()) {
-      for (RecordDecl::field_iterator it = UD->field_begin(),
-           itend = UD->field_end(); it != itend; ++it) {
-        QualType ET = it->getType().getUnqualifiedType();
+      for (const auto *I : UD->fields()) {
+        QualType ET = I->getType().getUnqualifiedType();
         QualType MT = mergeTypes(ET, SubType, OfBlockPointer, Unqualified);
         if (!MT.isNull())
           return MT;
@@ -6905,11 +6822,11 @@
   return QualType();
 }
 
-/// mergeFunctionArgumentTypes - merge two types which appear as function
-/// argument types
-QualType ASTContext::mergeFunctionArgumentTypes(QualType lhs, QualType rhs, 
-                                                bool OfBlockPointer,
-                                                bool Unqualified) {
+/// mergeFunctionParameterTypes - merge two types which appear as function
+/// parameter types
+QualType ASTContext::mergeFunctionParameterTypes(QualType lhs, QualType rhs,
+                                                 bool OfBlockPointer,
+                                                 bool Unqualified) {
   // GNU extension: two types are compatible if they appear as a function
   // argument, one of the types is a transparent union type and the other
   // type is compatible with a union member
@@ -6939,23 +6856,23 @@
   // Check return type
   QualType retType;
   if (OfBlockPointer) {
-    QualType RHS = rbase->getResultType();
-    QualType LHS = lbase->getResultType();
+    QualType RHS = rbase->getReturnType();
+    QualType LHS = lbase->getReturnType();
     bool UnqualifiedResult = Unqualified;
     if (!UnqualifiedResult)
       UnqualifiedResult = (!RHS.hasQualifiers() && LHS.hasQualifiers());
     retType = mergeTypes(LHS, RHS, true, UnqualifiedResult, true);
   }
   else
-    retType = mergeTypes(lbase->getResultType(), rbase->getResultType(), false,
+    retType = mergeTypes(lbase->getReturnType(), rbase->getReturnType(), false,
                          Unqualified);
   if (retType.isNull()) return QualType();
   
   if (Unqualified)
     retType = retType.getUnqualifiedType();
 
-  CanQualType LRetType = getCanonicalType(lbase->getResultType());
-  CanQualType RRetType = getCanonicalType(rbase->getResultType());
+  CanQualType LRetType = getCanonicalType(lbase->getReturnType());
+  CanQualType RRetType = getCanonicalType(rbase->getReturnType());
   if (Unqualified) {
     LRetType = LRetType.getUnqualifiedType();
     RRetType = RRetType.getUnqualifiedType();
@@ -6999,11 +6916,8 @@
   if (lproto && rproto) { // two C99 style function prototypes
     assert(!lproto->hasExceptionSpec() && !rproto->hasExceptionSpec() &&
            "C++ shouldn't be here");
-    unsigned lproto_nargs = lproto->getNumArgs();
-    unsigned rproto_nargs = rproto->getNumArgs();
-
-    // Compatible functions must have the same number of arguments
-    if (lproto_nargs != rproto_nargs)
+    // Compatible functions must have the same number of parameters
+    if (lproto->getNumParams() != rproto->getNumParams())
       return QualType();
 
     // Variadic and non-variadic functions aren't compatible
@@ -7016,29 +6930,29 @@
     if (LangOpts.ObjCAutoRefCount &&
         !FunctionTypesMatchOnNSConsumedAttrs(rproto, lproto))
       return QualType();
-      
-    // Check argument compatibility
+
+    // Check parameter type compatibility
     SmallVector<QualType, 10> types;
-    for (unsigned i = 0; i < lproto_nargs; i++) {
-      QualType largtype = lproto->getArgType(i).getUnqualifiedType();
-      QualType rargtype = rproto->getArgType(i).getUnqualifiedType();
-      QualType argtype = mergeFunctionArgumentTypes(largtype, rargtype,
-                                                    OfBlockPointer,
-                                                    Unqualified);
-      if (argtype.isNull()) return QualType();
-      
+    for (unsigned i = 0, n = lproto->getNumParams(); i < n; i++) {
+      QualType lParamType = lproto->getParamType(i).getUnqualifiedType();
+      QualType rParamType = rproto->getParamType(i).getUnqualifiedType();
+      QualType paramType = mergeFunctionParameterTypes(
+          lParamType, rParamType, OfBlockPointer, Unqualified);
+      if (paramType.isNull())
+        return QualType();
+
       if (Unqualified)
-        argtype = argtype.getUnqualifiedType();
-      
-      types.push_back(argtype);
+        paramType = paramType.getUnqualifiedType();
+
+      types.push_back(paramType);
       if (Unqualified) {
-        largtype = largtype.getUnqualifiedType();
-        rargtype = rargtype.getUnqualifiedType();
+        lParamType = lParamType.getUnqualifiedType();
+        rParamType = rParamType.getUnqualifiedType();
       }
-      
-      if (getCanonicalType(argtype) != getCanonicalType(largtype))
+
+      if (getCanonicalType(paramType) != getCanonicalType(lParamType))
         allLTypes = false;
-      if (getCanonicalType(argtype) != getCanonicalType(rargtype))
+      if (getCanonicalType(paramType) != getCanonicalType(rParamType))
         allRTypes = false;
     }
       
@@ -7062,20 +6976,19 @@
     // The only types actually affected are promotable integer
     // types and floats, which would be passed as a different
     // type depending on whether the prototype is visible.
-    unsigned proto_nargs = proto->getNumArgs();
-    for (unsigned i = 0; i < proto_nargs; ++i) {
-      QualType argTy = proto->getArgType(i);
-      
+    for (unsigned i = 0, n = proto->getNumParams(); i < n; ++i) {
+      QualType paramTy = proto->getParamType(i);
+
       // Look at the converted type of enum types, since that is the type used
       // to pass enum values.
-      if (const EnumType *Enum = argTy->getAs<EnumType>()) {
-        argTy = Enum->getDecl()->getIntegerType();
-        if (argTy.isNull())
+      if (const EnumType *Enum = paramTy->getAs<EnumType>()) {
+        paramTy = Enum->getDecl()->getIntegerType();
+        if (paramTy.isNull())
           return QualType();
       }
-      
-      if (argTy->isPromotableIntegerType() ||
-          getCanonicalType(argTy).getUnqualifiedType() == FloatTy)
+
+      if (paramTy->isPromotableIntegerType() ||
+          getCanonicalType(paramTy).getUnqualifiedType() == FloatTy)
         return QualType();
     }
 
@@ -7084,7 +6997,7 @@
 
     FunctionProtoType::ExtProtoInfo EPI = proto->getExtProtoInfo();
     EPI.ExtInfo = einfo;
-    return getFunctionType(retType, proto->getArgTypes(), EPI);
+    return getFunctionType(retType, proto->getParamTypes(), EPI);
   }
 
   if (allLTypes) return lhs;
@@ -7388,18 +7301,16 @@
 bool ASTContext::FunctionTypesMatchOnNSConsumedAttrs(
                    const FunctionProtoType *FromFunctionType,
                    const FunctionProtoType *ToFunctionType) {
-  if (FromFunctionType->hasAnyConsumedArgs() != 
-      ToFunctionType->hasAnyConsumedArgs())
+  if (FromFunctionType->hasAnyConsumedParams() !=
+      ToFunctionType->hasAnyConsumedParams())
     return false;
   FunctionProtoType::ExtProtoInfo FromEPI = 
     FromFunctionType->getExtProtoInfo();
   FunctionProtoType::ExtProtoInfo ToEPI = 
     ToFunctionType->getExtProtoInfo();
-  if (FromEPI.ConsumedArguments && ToEPI.ConsumedArguments)
-    for (unsigned ArgIdx = 0, NumArgs = FromFunctionType->getNumArgs();
-         ArgIdx != NumArgs; ++ArgIdx)  {
-      if (FromEPI.ConsumedArguments[ArgIdx] != 
-          ToEPI.ConsumedArguments[ArgIdx])
+  if (FromEPI.ConsumedParameters && ToEPI.ConsumedParameters)
+    for (unsigned i = 0, n = FromFunctionType->getNumParams(); i != n; ++i) {
+      if (FromEPI.ConsumedParameters[i] != ToEPI.ConsumedParameters[i])
         return false;
     }
   return true;
@@ -7417,10 +7328,10 @@
   if (RHSCan->isFunctionType()) {
     if (!LHSCan->isFunctionType())
       return QualType();
-    QualType OldReturnType = 
-      cast<FunctionType>(RHSCan.getTypePtr())->getResultType();
+    QualType OldReturnType =
+        cast<FunctionType>(RHSCan.getTypePtr())->getReturnType();
     QualType NewReturnType =
-      cast<FunctionType>(LHSCan.getTypePtr())->getResultType();
+        cast<FunctionType>(LHSCan.getTypePtr())->getReturnType();
     QualType ResReturnType = 
       mergeObjCGCQualifiers(NewReturnType, OldReturnType);
     if (ResReturnType.isNull())
@@ -7433,7 +7344,7 @@
         FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
         EPI.ExtInfo = getFunctionExtInfo(LHS);
         QualType ResultType =
-            getFunctionType(OldReturnType, FPT->getArgTypes(), EPI);
+            getFunctionType(OldReturnType, FPT->getParamTypes(), EPI);
         return ResultType;
       }
     }
@@ -7574,6 +7485,19 @@
       assert(HowLong <= 2 && "Can't have LLLL modifier");
       ++HowLong;
       break;
+    case 'W':
+      // This modifier represents int64 type.
+      assert(HowLong == 0 && "Can't use both 'L' and 'W' modifiers!");
+      switch (Context.getTargetInfo().getInt64Type()) {
+      default:
+        llvm_unreachable("Unexpected integer type");
+      case TargetInfo::SignedLong:
+        HowLong = 1;
+        break;
+      case TargetInfo::SignedLongLong:
+        HowLong = 2;
+        break;
+      }
     }
   }
 
@@ -7835,7 +7759,8 @@
   return getFunctionType(ResType, ArgTypes, EPI);
 }
 
-GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) {
+static GVALinkage basicGVALinkageForFunction(const ASTContext &Context,
+                                             const FunctionDecl *FD) {
   if (!FD->isExternallyVisible())
     return GVA_Internal;
 
@@ -7847,68 +7772,126 @@
     break;
 
   case TSK_ExplicitInstantiationDefinition:
-    return GVA_ExplicitTemplateInstantiation;
+    return GVA_StrongODR;
 
+  // C++11 [temp.explicit]p10:
+  //   [ Note: The intent is that an inline function that is the subject of
+  //   an explicit instantiation declaration will still be implicitly
+  //   instantiated when used so that the body can be considered for
+  //   inlining, but that no out-of-line copy of the inline function would be
+  //   generated in the translation unit. -- end note ]
   case TSK_ExplicitInstantiationDeclaration:
+    return GVA_AvailableExternally;
+
   case TSK_ImplicitInstantiation:
-    External = GVA_TemplateInstantiation;
+    External = GVA_DiscardableODR;
     break;
   }
 
   if (!FD->isInlined())
     return External;
 
-  if ((!getLangOpts().CPlusPlus && !getLangOpts().MicrosoftMode) ||
+  if ((!Context.getLangOpts().CPlusPlus && !Context.getLangOpts().MSVCCompat &&
+       !FD->hasAttr<DLLExportAttr>()) ||
       FD->hasAttr<GNUInlineAttr>()) {
+    // FIXME: This doesn't match gcc's behavior for dllexport inline functions.
+
     // GNU or C99 inline semantics. Determine whether this symbol should be
     // externally visible.
     if (FD->isInlineDefinitionExternallyVisible())
       return External;
 
     // C99 inline semantics, where the symbol is not externally visible.
-    return GVA_C99Inline;
+    return GVA_AvailableExternally;
   }
 
-  // C++0x [temp.explicit]p9:
-  //   [ Note: The intent is that an inline function that is the subject of 
-  //   an explicit instantiation declaration will still be implicitly 
-  //   instantiated when used so that the body can be considered for 
-  //   inlining, but that no out-of-line copy of the inline function would be
-  //   generated in the translation unit. -- end note ]
-  if (FD->getTemplateSpecializationKind() 
-                                       == TSK_ExplicitInstantiationDeclaration)
-    return GVA_C99Inline;
+  // Functions specified with extern and inline in -fms-compatibility mode
+  // forcibly get emitted.  While the body of the function cannot be later
+  // replaced, the function definition cannot be discarded.
+  if (FD->getMostRecentDecl()->isMSExternInline())
+    return GVA_StrongODR;
 
-  return GVA_CXXInline;
+  return GVA_DiscardableODR;
 }
 
-GVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) {
+static GVALinkage adjustGVALinkageForDLLAttribute(GVALinkage L, const Decl *D) {
+  // See http://msdn.microsoft.com/en-us/library/xa0d9ste.aspx
+  // dllexport/dllimport on inline functions.
+  if (D->hasAttr<DLLImportAttr>()) {
+    if (L == GVA_DiscardableODR || L == GVA_StrongODR)
+      return GVA_AvailableExternally;
+  } else if (D->hasAttr<DLLExportAttr>()) {
+    if (L == GVA_DiscardableODR)
+      return GVA_StrongODR;
+  }
+  return L;
+}
+
+GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) const {
+  return adjustGVALinkageForDLLAttribute(basicGVALinkageForFunction(*this, FD),
+                                         FD);
+}
+
+static GVALinkage basicGVALinkageForVariable(const ASTContext &Context,
+                                             const VarDecl *VD) {
   if (!VD->isExternallyVisible())
     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 it's linkage from the nearest
+    // enclosing function.
+    if (LexicalContext)
+      StaticLocalLinkage =
+          Context.GetGVALinkageForFunction(cast<FunctionDecl>(LexicalContext));
+
+    // 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;
+  }
+
+  // MSVC treats in-class initialized static data members as definitions.
+  // By giving them non-strong linkage, out-of-line definitions won't
+  // cause link errors.
+  if (Context.isMSStaticDataMemberInlineDefinition(VD))
+    return GVA_DiscardableODR;
+
   switch (VD->getTemplateSpecializationKind()) {
   case TSK_Undeclared:
   case TSK_ExplicitSpecialization:
     return GVA_StrongExternal;
 
-  case TSK_ExplicitInstantiationDeclaration:
-    llvm_unreachable("Variable should not be instantiated");
-  // Fall through to treat this like any other instantiation.
-
   case TSK_ExplicitInstantiationDefinition:
-    return GVA_ExplicitTemplateInstantiation;
+    return GVA_StrongODR;
+
+  case TSK_ExplicitInstantiationDeclaration:
+    return GVA_AvailableExternally;
 
   case TSK_ImplicitInstantiation:
-    return GVA_TemplateInstantiation;
+    return GVA_DiscardableODR;
   }
 
   llvm_unreachable("Invalid Linkage!");
 }
 
+GVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) {
+  return adjustGVALinkageForDLLAttribute(basicGVALinkageForVariable(*this, VD),
+                                         VD);
+}
+
 bool ASTContext::DeclMustBeEmitted(const Decl *D) {
   if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
     if (!VD->isFileVarDecl())
       return false;
+    // Global named register variables (GNU extension) are never emitted.
+    if (VD->getStorageClass() == SC_Register)
+      return false;
   } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
     // We never need to emit an uninstantiated function template.
     if (FD->getTemplatedKind() == FunctionDecl::TK_FunctionTemplate)
@@ -7955,8 +7938,8 @@
     // 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++.
-    if (Linkage == GVA_Internal  || Linkage == GVA_C99Inline ||
-        Linkage == GVA_CXXInline || Linkage == GVA_TemplateInstantiation)
+    if (Linkage == GVA_Internal || Linkage == GVA_AvailableExternally ||
+        Linkage == GVA_DiscardableODR)
       return false;
     return true;
   }
@@ -7964,12 +7947,14 @@
   const VarDecl *VD = cast<VarDecl>(D);
   assert(VD->isFileVarDecl() && "Expected file scoped var");
 
-  if (VD->isThisDeclarationADefinition() == VarDecl::DeclarationOnly)
+  if (VD->isThisDeclarationADefinition() == VarDecl::DeclarationOnly &&
+      !isMSStaticDataMemberInlineDefinition(VD))
     return false;
 
   // Variables that can be needed in other TUs are required.
   GVALinkage L = GetGVALinkageForVariable(VD);
-  if (L != GVA_Internal && L != GVA_TemplateInstantiation)
+  if (L != GVA_Internal && L != GVA_AvailableExternally &&
+      L != GVA_DiscardableODR)
     return true;
 
   // Variables that have destruction with side-effects are required.
@@ -7997,6 +7982,16 @@
   return ABI->isNearlyEmpty(RD);
 }
 
+VTableContextBase *ASTContext::getVTableContext() {
+  if (!VTContext.get()) {
+    if (Target->getCXXABI().isMicrosoft())
+      VTContext.reset(new MicrosoftVTableContext(*this));
+    else
+      VTContext.reset(new ItaniumVTableContext(*this));
+  }
+  return VTContext.get();
+}
+
 MangleContext *ASTContext::createMangleContext() {
   switch (Target->getCXXABI().getKind()) {
   case TargetCXXABI::GenericAArch64:
@@ -8004,6 +7999,7 @@
   case TargetCXXABI::GenericARM:
   case TargetCXXABI::Emscripten:
   case TargetCXXABI::iOS:
+  case TargetCXXABI::iOS64:
     return ItaniumMangleContext::create(*this, getDiagnostics());
   case TargetCXXABI::Microsoft:
     return MicrosoftMangleContext::create(*this, getDiagnostics());
@@ -8073,6 +8069,17 @@
   return I != MangleNumbers.end() ? I->second : 1;
 }
 
+void ASTContext::setStaticLocalNumber(const VarDecl *VD, unsigned Number) {
+  if (Number > 1)
+    StaticLocalNumbers[VD] = Number;
+}
+
+unsigned ASTContext::getStaticLocalNumber(const VarDecl *VD) const {
+  llvm::DenseMap<const VarDecl *, unsigned>::const_iterator I =
+      StaticLocalNumbers.find(VD);
+  return I != StaticLocalNumbers.end() ? I->second : 1;
+}
+
 MangleNumberingContext &
 ASTContext::getManglingNumberContext(const DeclContext *DC) {
   assert(LangOpts.CPlusPlus);  // We don't need mangling numbers for plain C.
@@ -8107,7 +8114,7 @@
 
   llvm::DenseMap<const MaterializeTemporaryExpr *, APValue>::iterator I =
       MaterializedTemporaryValues.find(E);
-  return I == MaterializedTemporaryValues.end() ? 0 : &I->second;
+  return I == MaterializedTemporaryValues.end() ? nullptr : &I->second;
 }
 
 bool ASTContext::AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const {
@@ -8170,18 +8177,45 @@
 
     template <typename T>
     bool TraverseNode(T *Node, bool(VisitorBase:: *traverse) (T *)) {
-      if (Node == NULL)
+      if (!Node)
         return true;
-      if (ParentStack.size() > 0)
-        // FIXME: Currently we add the same parent multiple times, for example
-        // when we visit all subexpressions of template instantiations; this is
-        // suboptimal, bug benign: the only way to visit those is with
-        // hasAncestor / hasParent, and those do not create new matches.
+      if (ParentStack.size() > 0) {
+        // FIXME: Currently we add the same parent multiple times, but only
+        // when no memoization data is available for the type.
+        // For example when we visit all subexpressions of template
+        // instantiations; this is suboptimal, but benign: the only way to
+        // visit those is with hasAncestor / hasParent, and those do not create
+        // new matches.
         // The plan is to enable DynTypedNode to be storable in a map or hash
         // map. The main problem there is to implement hash functions /
         // comparison operators for all types that DynTypedNode supports that
         // do not have pointer identity.
-        (*Parents)[Node].push_back(ParentStack.back());
+        auto &NodeOrVector = (*Parents)[Node];
+        if (NodeOrVector.isNull()) {
+          NodeOrVector = new ast_type_traits::DynTypedNode(ParentStack.back());
+        } else {
+          if (NodeOrVector.template is<ast_type_traits::DynTypedNode *>()) {
+            auto *Node =
+                NodeOrVector.template get<ast_type_traits::DynTypedNode *>();
+            auto *Vector = new ASTContext::ParentVector(1, *Node);
+            NodeOrVector = Vector;
+            delete Node;
+          }
+          assert(NodeOrVector.template is<ASTContext::ParentVector *>());
+
+          auto *Vector =
+              NodeOrVector.template get<ASTContext::ParentVector *>();
+          // Skip duplicates for types that have memoization data.
+          // We must check that the type has memoization data before calling
+          // std::find() because DynTypedNode::operator== can't compare all
+          // types.
+          bool Found = ParentStack.back().getMemoizationData() &&
+                       std::find(Vector->begin(), Vector->end(),
+                                 ParentStack.back()) != Vector->end();
+          if (!Found)
+            Vector->push_back(ParentStack.back());
+        }
+      }
       ParentStack.push_back(ast_type_traits::DynTypedNode::create(*Node));
       bool Result = (this ->* traverse) (Node);
       ParentStack.pop_back();
@@ -8219,7 +8253,11 @@
   if (I == AllParents->end()) {
     return ParentVector();
   }
-  return I->second;
+  if (I->second.is<ast_type_traits::DynTypedNode *>()) {
+    return ParentVector(1, *I->second.get<ast_type_traits::DynTypedNode *>());
+  }
+  const auto &Parents = *I->second.get<ParentVector *>();
+  return ParentVector(Parents.begin(), Parents.end());
 }
 
 bool
@@ -8232,8 +8270,7 @@
   if (MethodDecl->getObjCDeclQualifier() !=
       MethodImpl->getObjCDeclQualifier())
     return false;
-  if (!hasSameType(MethodDecl->getResultType(),
-                   MethodImpl->getResultType()))
+  if (!hasSameType(MethodDecl->getReturnType(), MethodImpl->getReturnType()))
     return false;
   
   if (MethodDecl->param_size() != MethodImpl->param_size())
@@ -8253,3 +8290,12 @@
   return (MethodDecl->isVariadic() == MethodImpl->isVariadic());
   
 }
+
+// Explicitly instantiate this in case a Redeclarable<T> is used from a TU that
+// doesn't include ASTContext.h
+template
+clang::LazyGenerationalUpdatePtr<
+    const Decl *, Decl *, &ExternalASTSource::CompleteRedeclChain>::ValueType
+clang::LazyGenerationalUpdatePtr<
+    const Decl *, Decl *, &ExternalASTSource::CompleteRedeclChain>::makeValue(
+        const clang::ASTContext &Ctx, Decl *Value);
diff --git a/lib/AST/ASTDiagnostic.cpp b/lib/AST/ASTDiagnostic.cpp
index fce8f64..8c8b1df 100644
--- a/lib/AST/ASTDiagnostic.cpp
+++ b/lib/AST/ASTDiagnostic.cpp
@@ -12,6 +12,8 @@
 //===----------------------------------------------------------------------===//
 #include "clang/AST/ASTDiagnostic.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTLambda.h"
+#include "clang/AST/Attr.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/ExprCXX.h"
@@ -51,6 +53,11 @@
       QT = AT->desugar();
       continue;
     }
+    // ...or an adjusted type...
+    if (const AdjustedType *AT = dyn_cast<AdjustedType>(Ty)) {
+      QT = AT->desugar();
+      continue;
+    }
     // ... or an auto type.
     if (const AutoType *AT = dyn_cast<AutoType>(Ty)) {
       if (!AT->isSugared())
@@ -155,9 +162,8 @@
 /// diagnostic message
 static std::string
 ConvertTypeToDiagnosticString(ASTContext &Context, QualType Ty,
-                              const DiagnosticsEngine::ArgumentValue *PrevArgs,
-                              unsigned NumPrevArgs,
-                              ArrayRef<intptr_t> QualTypeVals) {
+                            ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs,
+                            ArrayRef<intptr_t> QualTypeVals) {
   // FIXME: Playing with std::string is really slow.
   bool ForceAKA = false;
   QualType CanTy = Ty.getCanonicalType();
@@ -195,7 +201,7 @@
   // Check to see if we already desugared this type in this
   // diagnostic.  If so, don't do it again.
   bool Repeated = false;
-  for (unsigned i = 0; i != NumPrevArgs; ++i) {
+  for (unsigned i = 0, e = PrevArgs.size(); i != e; ++i) {
     // TODO: Handle ak_declcontext case.
     if (PrevArgs[i].first == DiagnosticsEngine::ak_qualtype) {
       void *Ptr = (void*)PrevArgs[i].second;
@@ -222,6 +228,20 @@
         return S;
       }
     }
+
+    // Give some additional info on vector types. These are either not desugared
+    // or displaying complex __attribute__ expressions so add details of the
+    // type and element count.
+    if (Ty->isVectorType()) {
+      const VectorType *VTy = Ty->getAs<VectorType>();
+      std::string DecoratedString;
+      llvm::raw_string_ostream OS(DecoratedString);
+      const char *Values = VTy->getNumElements() > 1 ? "values" : "value";
+      OS << "'" << S << "' (vector of " << VTy->getNumElements() << " '"
+         << VTy->getElementType().getAsString(Context.getPrintingPolicy())
+         << "' " << Values << ")";
+      return OS.str();
+    }
   }
 
   S = "'" + S + "'";
@@ -236,12 +256,9 @@
 void clang::FormatASTNodeDiagnosticArgument(
     DiagnosticsEngine::ArgumentKind Kind,
     intptr_t Val,
-    const char *Modifier,
-    unsigned ModLen,
-    const char *Argument,
-    unsigned ArgLen,
-    const DiagnosticsEngine::ArgumentValue *PrevArgs,
-    unsigned NumPrevArgs,
+    StringRef Modifier,
+    StringRef Argument,
+    ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs,
     SmallVectorImpl<char> &Output,
     void *Cookie,
     ArrayRef<intptr_t> QualTypeVals) {
@@ -276,28 +293,26 @@
       // Attempting to do a template diff on non-templates.  Set the variables
       // and continue with regular type printing of the appropriate type.
       Val = TDT.PrintFromType ? TDT.FromType : TDT.ToType;
-      ModLen = 0;
-      ArgLen = 0;
+      Modifier = StringRef();
+      Argument = StringRef();
       // Fall through
     }
     case DiagnosticsEngine::ak_qualtype: {
-      assert(ModLen == 0 && ArgLen == 0 &&
+      assert(Modifier.empty() && Argument.empty() &&
              "Invalid modifier for QualType argument");
       
       QualType Ty(QualType::getFromOpaquePtr(reinterpret_cast<void*>(Val)));
-      OS << ConvertTypeToDiagnosticString(Context, Ty, PrevArgs, NumPrevArgs,
-                                          QualTypeVals);
+      OS << ConvertTypeToDiagnosticString(Context, Ty, PrevArgs, QualTypeVals);
       NeedQuotes = false;
       break;
     }
     case DiagnosticsEngine::ak_declarationname: {
-      if (ModLen == 9 && !memcmp(Modifier, "objcclass", 9) && ArgLen == 0)
+      if (Modifier == "objcclass" && Argument.empty())
         OS << '+';
-      else if (ModLen == 12 && !memcmp(Modifier, "objcinstance", 12)
-                && ArgLen==0)
+      else if (Modifier == "objcinstance" && Argument.empty())
         OS << '-';
       else
-        assert(ModLen == 0 && ArgLen == 0 &&
+        assert(Modifier.empty() && Argument.empty() &&
                "Invalid modifier for DeclarationName argument");
 
       OS << DeclarationName::getFromOpaqueInteger(Val);
@@ -305,10 +320,10 @@
     }
     case DiagnosticsEngine::ak_nameddecl: {
       bool Qualified;
-      if (ModLen == 1 && Modifier[0] == 'q' && ArgLen == 0)
+      if (Modifier == "q" && Argument.empty())
         Qualified = true;
       else {
-        assert(ModLen == 0 && ArgLen == 0 &&
+        assert(Modifier.empty() && Argument.empty() &&
                "Invalid modifier for NamedDecl* argument");
         Qualified = false;
       }
@@ -325,7 +340,8 @@
     case DiagnosticsEngine::ak_declcontext: {
       DeclContext *DC = reinterpret_cast<DeclContext *> (Val);
       assert(DC && "Should never have a null declaration context");
-      
+      NeedQuotes = false;
+
       if (DC->isTranslationUnit()) {
         // FIXME: Get these strings from some localized place
         if (Context.getLangOpts().CPlusPlus)
@@ -335,10 +351,17 @@
       } else if (TypeDecl *Type = dyn_cast<TypeDecl>(DC)) {
         OS << ConvertTypeToDiagnosticString(Context,
                                             Context.getTypeDeclType(Type),
-                                            PrevArgs, NumPrevArgs,
-                                            QualTypeVals);
+                                            PrevArgs, QualTypeVals);
       } else {
         // FIXME: Get these strings from some localized place
+        if (isa<BlockDecl>(DC)) {
+          OS << "block literal";
+          break;
+        }
+        if (isLambdaCallOperator(DC)) {
+          OS << "lambda expression";
+          break;
+        }
         NamedDecl *ND = cast<NamedDecl>(DC);
         if (isa<NamespaceDecl>(ND))
           OS << "namespace ";
@@ -351,9 +374,16 @@
         ND->getNameForDiagnostic(OS, Context.getPrintingPolicy(), true);
         OS << '\'';
       }
+      break;
+    }
+    case DiagnosticsEngine::ak_attr: {
+      const Attr *At = reinterpret_cast<Attr *>(Val);
+      assert(At && "Received null Attr object!");
+      OS << '\'' << At->getSpelling() << '\'';
       NeedQuotes = false;
       break;
     }
+
   }
 
   OS.flush();
@@ -442,6 +472,9 @@
       /// FromExpr, ToExpr - The expression arguments.
       Expr *FromExpr, *ToExpr;
 
+      /// FromNullPtr, ToNullPtr - If the template argument is a nullptr
+      bool FromNullPtr, ToNullPtr;
+
       /// FromTD, ToTD - The template decl for template template
       /// arguments or the type arguments that are templates.
       TemplateDecl *FromTD, *ToTD;
@@ -470,10 +503,12 @@
 
       DiffNode(unsigned ParentNode = 0)
         : Kind(Invalid), NextNode(0), ChildNode(0), ParentNode(ParentNode),
-          FromType(), ToType(), FromExpr(0), ToExpr(0), FromTD(0), ToTD(0),
-          IsValidFromInt(false), IsValidToInt(false), FromValueDecl(0),
-          ToValueDecl(0), FromAddressOf(false), ToAddressOf(false),
-          FromDefault(false), ToDefault(false), Same(false) { }
+          FromType(), ToType(), FromExpr(nullptr), ToExpr(nullptr),
+          FromNullPtr(false), ToNullPtr(false),
+          FromTD(nullptr), ToTD(nullptr), IsValidFromInt(false),
+          IsValidToInt(false), FromValueDecl(nullptr), ToValueDecl(nullptr),
+          FromAddressOf(false), ToAddressOf(false), FromDefault(false),
+          ToDefault(false), Same(false) {}
     };
 
     /// FlatTree - A flattened tree used to store the DiffNodes.
@@ -543,6 +578,12 @@
       FlatTree[CurrentNode].Same = Same;
     }
 
+    /// SetNullPtr - Sets the NullPtr flags of the current node.
+    void SetNullPtr(bool FromNullPtr, bool ToNullPtr) {
+      FlatTree[CurrentNode].FromNullPtr = FromNullPtr;
+      FlatTree[CurrentNode].ToNullPtr = ToNullPtr;
+    }
+
     /// SetDefault - Sets FromDefault and ToDefault flags of the current node.
     void SetDefault(bool FromDefault, bool ToDefault) {
       FlatTree[CurrentNode].FromDefault = FromDefault;
@@ -665,6 +706,16 @@
       return FlatTree[ReadNode].NextNode != 0;
     }
 
+    /// FromNullPtr - Returns true if the from argument is null.
+    bool FromNullPtr() {
+      return FlatTree[ReadNode].FromNullPtr;
+    }
+
+    /// ToNullPtr - Returns true if the to argument is null.
+    bool ToNullPtr() {
+      return FlatTree[ReadNode].ToNullPtr;
+    }
+
     /// FromDefault - Return true if the from argument is the default.
     bool FromDefault() {
       return FlatTree[ReadNode].FromDefault;
@@ -718,7 +769,7 @@
     TSTiterator(ASTContext &Context, const TemplateSpecializationType *TST)
         : TST(TST),
           DesugarTST(GetTemplateSpecializationType(Context, TST->desugar())),
-          Index(0), CurrentTA(0), EndTA(0) {
+          Index(0), CurrentTA(nullptr), EndTA(nullptr) {
       if (isEnd()) return;
 
       // Set to first template argument.  If not a parameter pack, done.
@@ -809,13 +860,13 @@
     const RecordType *RT = Ty->getAs<RecordType>();
 
     if (!RT)
-      return 0;
+      return nullptr;
 
     const ClassTemplateSpecializationDecl *CTSD =
         dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl());
 
     if (!CTSD)
-      return 0;
+      return nullptr;
 
     Ty = Context.getTemplateSpecializationType(
              TemplateName(CTSD->getSpecializedTemplate()),
@@ -887,9 +938,9 @@
       // Handle Expressions
       if (NonTypeTemplateParmDecl *DefaultNTTPD =
               dyn_cast<NonTypeTemplateParmDecl>(ParamND)) {
-        Expr *FromExpr = 0, *ToExpr = 0;
+        Expr *FromExpr = nullptr, *ToExpr = nullptr;
         llvm::APSInt FromInt, ToInt;
-        ValueDecl *FromValueDecl = 0, *ToValueDecl = 0;
+        ValueDecl *FromValueDecl = nullptr, *ToValueDecl = nullptr;
         unsigned ParamWidth = 128; // Safe default
         if (DefaultNTTPD->getType()->isIntegralOrEnumerationType())
           ParamWidth = Context.getIntWidth(DefaultNTTPD->getType());
@@ -903,6 +954,10 @@
         bool HasToValueDecl =
             !ToIter.isEnd() &&
             ToIter->getKind() == TemplateArgument::Declaration;
+        bool FromNullPtr = !FromIter.isEnd() &&
+                           FromIter->getKind() == TemplateArgument::NullPtr;
+        bool ToNullPtr =
+            !ToIter.isEnd() && ToIter->getKind() == TemplateArgument::NullPtr;
 
         assert(((!HasFromInt && !HasToInt) ||
                 (!HasFromValueDecl && !HasToValueDecl)) &&
@@ -912,41 +967,54 @@
           FromInt = FromIter->getAsIntegral();
         else if (HasFromValueDecl)
           FromValueDecl = FromIter->getAsDecl();
-        else
+        else if (!FromNullPtr)
           FromExpr = GetExpr(FromIter, DefaultNTTPD);
 
         if (HasToInt)
           ToInt = ToIter->getAsIntegral();
         else if (HasToValueDecl)
           ToValueDecl = ToIter->getAsDecl();
-        else
+        else if (!ToNullPtr)
           ToExpr = GetExpr(ToIter, DefaultNTTPD);
 
+        bool TemplateArgumentIsPointerType =
+            DefaultNTTPD->getType()->isPointerType();
+        if (FromExpr && TemplateArgumentIsPointerType) {
+          FromNullPtr = CheckForNullPtr(FromExpr);
+        }
+        if (ToExpr && TemplateArgumentIsPointerType) {
+          ToNullPtr = CheckForNullPtr(ToExpr);
+        }
+
         if (!HasFromInt && !HasToInt && !HasFromValueDecl && !HasToValueDecl) {
           Tree.SetNode(FromExpr, ToExpr);
           Tree.SetDefault(FromIter.isEnd() && FromExpr,
                           ToIter.isEnd() && ToExpr);
           if (DefaultNTTPD->getType()->isIntegralOrEnumerationType()) {
             if (FromExpr)
-              FromInt = GetInt(FromIter, FromExpr);
+              HasFromInt = GetInt(FromIter, FromExpr, FromInt);
             if (ToExpr)
-              ToInt = GetInt(ToIter, ToExpr);
-            Tree.SetNode(FromInt, ToInt, FromExpr, ToExpr);
+              HasToInt = GetInt(ToIter, ToExpr, ToInt);
+          }
+          if (HasFromInt && HasToInt) {
+            Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt);
             Tree.SetSame(IsSameConvertedInt(ParamWidth, FromInt, ToInt));
             Tree.SetKind(DiffTree::Integer);
+          } else if (HasFromInt || HasToInt) {
+            Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt);
+            Tree.SetSame(false);
+            Tree.SetKind(DiffTree::Integer);
           } else {
-            Tree.SetSame(IsEqualExpr(Context, ParamWidth, FromExpr, ToExpr));
+            Tree.SetSame(IsEqualExpr(Context, ParamWidth, FromExpr, ToExpr) ||
+                         (FromNullPtr && ToNullPtr));
+            Tree.SetNullPtr(FromNullPtr, ToNullPtr);
             Tree.SetKind(DiffTree::Expression);
           }
         } else if (HasFromInt || HasToInt) {
-          if (!HasFromInt && FromExpr) {
-            FromInt = GetInt(FromIter, FromExpr);
-            HasFromInt = true;
-          }
-          if (!HasToInt && ToExpr) {
-            ToInt = GetInt(ToIter, ToExpr);
-            HasToInt = true;
-          }
+          if (!HasFromInt && FromExpr)
+            HasFromInt = GetInt(FromIter, FromExpr, FromInt);
+          if (!HasToInt && ToExpr)
+            HasToInt = GetInt(ToIter, ToExpr, ToInt);
           Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt);
           Tree.SetSame(IsSameConvertedInt(ParamWidth, FromInt, ToInt));
           Tree.SetDefault(FromIter.isEnd() && HasFromInt,
@@ -958,12 +1026,36 @@
           if (!HasToValueDecl && ToExpr)
             ToValueDecl = GetValueDecl(ToIter, ToExpr);
           QualType ArgumentType = DefaultNTTPD->getType();
-          bool FromAddressOf = FromValueDecl &&
-                               !ArgumentType->isReferenceType() &&
-                               !FromValueDecl->getType()->isArrayType();
-          bool ToAddressOf = ToValueDecl &&
-                             !ArgumentType->isReferenceType() &&
-                             !ToValueDecl->getType()->isArrayType();
+          bool FromAddressOf = false;
+          if (FromValueDecl) {
+            if (FromExpr) {
+              if (UnaryOperator *UO =
+                      dyn_cast<UnaryOperator>(FromExpr->IgnoreParens())) {
+                if (UO->getOpcode() == UO_AddrOf)
+                  FromAddressOf = true;
+              }
+            } else {
+              if (!ArgumentType->isReferenceType()) {
+                FromAddressOf = true;
+              }
+            }
+          }
+          bool ToAddressOf = false;
+          if (ToValueDecl) {
+            if (ToExpr) {
+              if (UnaryOperator *UO =
+                      dyn_cast<UnaryOperator>(ToExpr->IgnoreParens())) {
+                if (UO->getOpcode() == UO_AddrOf) {
+                  ToAddressOf = true;
+                }
+              }
+            } else {
+              if (!ArgumentType->isReferenceType()) {
+                ToAddressOf = true;
+              }
+            }
+          }
+          Tree.SetNullPtr(FromNullPtr, ToNullPtr);
           Tree.SetNode(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf);
           Tree.SetSame(FromValueDecl && ToValueDecl &&
                        FromValueDecl->getCanonicalDecl() ==
@@ -984,6 +1076,7 @@
         Tree.SetSame(
             FromDecl && ToDecl &&
             FromDecl->getCanonicalDecl() == ToDecl->getCanonicalDecl());
+        Tree.SetDefault(FromIter.isEnd() && FromDecl, ToIter.isEnd() && ToDecl);
         Tree.SetKind(DiffTree::TemplateTemplate);
       }
 
@@ -1072,7 +1165,7 @@
   /// GetExpr - Retrieves the template expression argument, including default
   /// arguments.
   Expr *GetExpr(const TSTiterator &Iter, NonTypeTemplateParmDecl *DefaultNTTPD) {
-    Expr *ArgExpr = 0;
+    Expr *ArgExpr = nullptr;
     bool isVariadic = DefaultNTTPD->isParameterPack();
 
     if (!Iter.isEnd())
@@ -1090,20 +1183,28 @@
 
   /// GetInt - Retrieves the template integer argument, including evaluating
   /// default arguments.
-  llvm::APInt GetInt(const TSTiterator &Iter, Expr *ArgExpr) {
+  bool GetInt(const TSTiterator &Iter, Expr *ArgExpr, llvm::APInt &Int) {
     // Default, value-depenedent expressions require fetching
-    // from the desugared TemplateArgument
-    if (Iter.isEnd() && ArgExpr->isValueDependent())
+    // from the desugared TemplateArgument, otherwise expression needs to
+    // be evaluatable.
+    if (Iter.isEnd() && ArgExpr->isValueDependent()) {
       switch (Iter.getDesugar().getKind()) {
         case TemplateArgument::Integral:
-          return Iter.getDesugar().getAsIntegral();
+          Int = Iter.getDesugar().getAsIntegral();
+          return true;
         case TemplateArgument::Expression:
           ArgExpr = Iter.getDesugar().getAsExpr();
-          return ArgExpr->EvaluateKnownConstInt(Context);
+          Int = ArgExpr->EvaluateKnownConstInt(Context);
+          return true;
         default:
-          assert(0 && "Unexpected template argument kind");
+          llvm_unreachable("Unexpected template argument kind");
       }
-    return ArgExpr->EvaluateKnownConstInt(Context);
+    } else if (ArgExpr->isEvaluatable(Context)) {
+      Int = ArgExpr->EvaluateKnownConstInt(Context);
+      return true;
+    }
+
+    return false;
   }
 
   /// GetValueDecl - Retrieves the template Decl argument, including
@@ -1119,16 +1220,40 @@
           ArgExpr = Iter.getDesugar().getAsExpr();
           return cast<DeclRefExpr>(ArgExpr)->getDecl();
         default:
-          assert(0 && "Unexpected template argument kind");
+          llvm_unreachable("Unexpected template argument kind");
       }
     DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ArgExpr);
     if (!DRE) {
-      DRE = cast<DeclRefExpr>(cast<UnaryOperator>(ArgExpr)->getSubExpr());
+      UnaryOperator *UO = dyn_cast<UnaryOperator>(ArgExpr->IgnoreParens());
+      if (!UO)
+        return nullptr;
+      DRE = cast<DeclRefExpr>(UO->getSubExpr());
     }
 
     return DRE->getDecl();
   }
 
+  /// CheckForNullPtr - returns true if the expression can be evaluated as
+  /// a null pointer
+  bool CheckForNullPtr(Expr *E) {
+    assert(E && "Expected expression");
+
+    E = E->IgnoreParenCasts();
+    if (E->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull))
+      return true;
+
+    DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E);
+    if (!DRE)
+      return false;
+
+    VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl());
+    if (!VD || !VD->hasInit())
+      return false;
+
+    return VD->getInit()->IgnoreParenCasts()->isNullPointerConstant(
+        Context, Expr::NPC_ValueDependentIsNull);
+  }
+
   /// GetTemplateDecl - Retrieves the template template arguments, including
   /// default arguments.
   TemplateDecl *GetTemplateDecl(const TSTiterator &Iter,
@@ -1136,7 +1261,7 @@
     bool isVariadic = DefaultTTPD->isParameterPack();
 
     TemplateArgument TA = DefaultTTPD->getDefaultArgument().getArgument();
-    TemplateDecl *DefaultTD = 0;
+    TemplateDecl *DefaultTD = nullptr;
     if (TA.getKind() != TemplateArgument::Null)
       DefaultTD = TA.getAsTemplate().getAsTemplateDecl();
 
@@ -1145,7 +1270,7 @@
     if (!isVariadic)
       return DefaultTD;
 
-    return 0;
+    return nullptr;
   }
 
   /// IsSameConvertedInt - Returns true if both integers are equal when
@@ -1166,11 +1291,8 @@
     if (!FromExpr || !ToExpr)
       return false;
 
-    FromExpr = FromExpr->IgnoreParens();
-    ToExpr = ToExpr->IgnoreParens();
-
-    DeclRefExpr *FromDRE = dyn_cast<DeclRefExpr>(FromExpr),
-                *ToDRE = dyn_cast<DeclRefExpr>(ToExpr);
+    DeclRefExpr *FromDRE = dyn_cast<DeclRefExpr>(FromExpr->IgnoreParens()),
+                *ToDRE = dyn_cast<DeclRefExpr>(ToExpr->IgnoreParens());
 
     if (FromDRE || ToDRE) {
       if (!FromDRE || !ToDRE)
@@ -1180,8 +1302,12 @@
 
     Expr::EvalResult FromResult, ToResult;
     if (!FromExpr->EvaluateAsRValue(FromResult, Context) ||
-        !ToExpr->EvaluateAsRValue(ToResult, Context))
-      return false;
+        !ToExpr->EvaluateAsRValue(ToResult, Context)) {
+      llvm::FoldingSetNodeID FromID, ToID;
+      FromExpr->Profile(FromID, Context, true);
+      ToExpr->Profile(ToID, Context, true);
+      return FromID == ToID;
+    }
 
     APValue &FromVal = FromResult.Val;
     APValue &ToVal = ToResult.Val;
@@ -1235,8 +1361,8 @@
       case DiffTree::Expression: {
         Expr *FromExpr, *ToExpr;
         Tree.GetNode(FromExpr, ToExpr);
-        PrintExpr(FromExpr, ToExpr, Tree.FromDefault(), Tree.ToDefault(),
-                  Tree.NodeIsSame());
+        PrintExpr(FromExpr, ToExpr, Tree.FromNullPtr(), Tree.ToNullPtr(),
+                  Tree.FromDefault(), Tree.ToDefault(), Tree.NodeIsSame());
         return;
       }
       case DiffTree::TemplateTemplate: {
@@ -1262,7 +1388,8 @@
         bool FromAddressOf, ToAddressOf;
         Tree.GetNode(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf);
         PrintValueDecl(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf,
-                       Tree.FromDefault(), Tree.ToDefault(), Tree.NodeIsSame());
+                       Tree.FromNullPtr(), Tree.ToNullPtr(), Tree.FromDefault(),
+                       Tree.ToDefault(), Tree.NodeIsSame());
         return;
       }
       case DiffTree::Template: {
@@ -1341,7 +1468,7 @@
            "Only one template argument may be missing.");
 
     if (Same) {
-      OS << FromType.getAsString();
+      OS << FromType.getAsString(Policy);
       return;
     }
 
@@ -1349,22 +1476,22 @@
         FromType.getLocalUnqualifiedType() ==
         ToType.getLocalUnqualifiedType()) {
       Qualifiers FromQual = FromType.getLocalQualifiers(),
-                 ToQual = ToType.getLocalQualifiers(),
-                 CommonQual;
+                 ToQual = ToType.getLocalQualifiers();
       PrintQualifiers(FromQual, ToQual);
       FromType.getLocalUnqualifiedType().print(OS, Policy);
       return;
     }
 
     std::string FromTypeStr = FromType.isNull() ? "(no argument)"
-                                                : FromType.getAsString();
+                                                : FromType.getAsString(Policy);
     std::string ToTypeStr = ToType.isNull() ? "(no argument)"
-                                            : ToType.getAsString();
+                                            : ToType.getAsString(Policy);
     // Switch to canonical typename if it is better.
     // TODO: merge this with other aka printing above.
     if (FromTypeStr == ToTypeStr) {
-      std::string FromCanTypeStr = FromType.getCanonicalType().getAsString();
-      std::string ToCanTypeStr = ToType.getCanonicalType().getAsString();
+      std::string FromCanTypeStr =
+          FromType.getCanonicalType().getAsString(Policy);
+      std::string ToCanTypeStr = ToType.getCanonicalType().getAsString(Policy);
       if (FromCanTypeStr != ToCanTypeStr) {
         FromTypeStr = FromCanTypeStr;
         ToTypeStr = ToCanTypeStr;
@@ -1388,36 +1515,41 @@
 
   /// PrintExpr - Prints out the expr template arguments, highlighting argument
   /// differences.
-  void PrintExpr(const Expr *FromExpr, const Expr *ToExpr,
-                 bool FromDefault, bool ToDefault, bool Same) {
+  void PrintExpr(const Expr *FromExpr, const Expr *ToExpr, bool FromNullPtr,
+                 bool ToNullPtr, bool FromDefault, bool ToDefault, bool Same) {
     assert((FromExpr || ToExpr) &&
             "Only one template argument may be missing.");
     if (Same) {
-      PrintExpr(FromExpr);
+      PrintExpr(FromExpr, FromNullPtr);
     } else if (!PrintTree) {
       OS << (FromDefault ? "(default) " : "");
       Bold();
-      PrintExpr(FromExpr);
+      PrintExpr(FromExpr, FromNullPtr);
       Unbold();
     } else {
       OS << (FromDefault ? "[(default) " : "[");
       Bold();
-      PrintExpr(FromExpr);
+      PrintExpr(FromExpr, FromNullPtr);
       Unbold();
       OS << " != " << (ToDefault ? "(default) " : "");
       Bold();
-      PrintExpr(ToExpr);
+      PrintExpr(ToExpr, ToNullPtr);
       Unbold();
       OS << ']';
     }
   }
 
   /// PrintExpr - Actual formatting and printing of expressions.
-  void PrintExpr(const Expr *E) {
-    if (!E)
-      OS << "(no argument)";
-    else
-      E->printPretty(OS, 0, Policy); return;
+  void PrintExpr(const Expr *E, bool NullPtr = false) {
+    if (E) {
+      E->printPretty(OS, nullptr, Policy);
+      return;
+    }
+    if (NullPtr) {
+      OS << "nullptr";
+      return;
+    }
+    OS << "(no argument)";
   }
 
   /// PrintTemplateTemplate - Handles printing of template template arguments,
@@ -1487,6 +1619,8 @@
         Bold();
       }
       OS << Val.toString(10);
+    } else if (E) {
+      PrintExpr(E);
     } else {
       OS << "(no argument)";
     }
@@ -1507,35 +1641,46 @@
     return true;
   }
 
+  void PrintValueDecl(ValueDecl *VD, bool AddressOf, bool NullPtr) {
+    if (VD) {
+      if (AddressOf)
+        OS << "&";
+      OS << VD->getName();
+      return;
+    }
+
+    if (NullPtr) {
+      OS << "nullptr";
+      return;
+    }
+
+    OS << "(no argument)";
+  }
+
   /// PrintDecl - Handles printing of Decl arguments, highlighting
   /// argument differences.
   void PrintValueDecl(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl,
-                      bool FromAddressOf, bool ToAddressOf, bool FromDefault,
-                      bool ToDefault, bool Same) {
-    assert((FromValueDecl || ToValueDecl) &&
+                      bool FromAddressOf, bool ToAddressOf, bool FromNullPtr,
+                      bool ToNullPtr, bool FromDefault, bool ToDefault,
+                      bool Same) {
+    assert((FromValueDecl || FromNullPtr || ToValueDecl || ToNullPtr) &&
            "Only one Decl argument may be NULL");
 
     if (Same) {
-      OS << FromValueDecl->getName();
+      PrintValueDecl(FromValueDecl, FromAddressOf, FromNullPtr);
     } else if (!PrintTree) {
       OS << (FromDefault ? "(default) " : "");
       Bold();
-      if (FromAddressOf)
-        OS << "&";
-      OS << (FromValueDecl ? FromValueDecl->getName() : "(no argument)");
+      PrintValueDecl(FromValueDecl, FromAddressOf, FromNullPtr);
       Unbold();
     } else {
       OS << (FromDefault ? "[(default) " : "[");
       Bold();
-      if (FromAddressOf)
-        OS << "&";
-      OS << (FromValueDecl ? FromValueDecl->getName() : "(no argument)");
+      PrintValueDecl(FromValueDecl, FromAddressOf, FromNullPtr);
       Unbold();
       OS << " != " << (ToDefault ? "(default) " : "");
       Bold();
-      if (ToAddressOf)
-        OS << "&";
-      OS << (ToValueDecl ? ToValueDecl->getName() : "(no argument)");
+      PrintValueDecl(ToValueDecl, ToAddressOf, ToNullPtr);
       Unbold();
       OS << ']';
     }
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index 2f40255..df7a2cb 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -32,12 +32,23 @@
 
 namespace  {
   // Colors used for various parts of the AST dump
+  // Do not use bold yellow for any text.  It is hard to read on white screens.
 
   struct TerminalColor {
     raw_ostream::Colors Color;
     bool Bold;
   };
 
+  // Red           - CastColor
+  // Green         - TypeColor
+  // Bold Green    - DeclKindNameColor, UndeserializedColor
+  // Yellow        - AddressColor, LocationColor
+  // Blue          - CommentColor, NullColor, IndentColor
+  // Bold Blue     - AttrColor
+  // Bold Magenta  - StmtColor
+  // Cyan          - ValueKindColor, ObjectKindColor
+  // Bold Cyan     - ValueColor, DeclNameColor
+
   // Decl kind names (VarDecl, FunctionDecl, etc)
   static const TerminalColor DeclKindNameColor = { raw_ostream::GREEN, true };
   // Attr names (CleanupAttr, GuardedByAttr, etc)
@@ -45,7 +56,7 @@
   // Statement names (DeclStmt, ImplicitCastExpr, etc)
   static const TerminalColor StmtColor = { raw_ostream::MAGENTA, true };
   // Comment names (FullComment, ParagraphComment, TextComment, etc)
-  static const TerminalColor CommentColor = { raw_ostream::YELLOW, true };
+  static const TerminalColor CommentColor = { raw_ostream::BLUE, false };
 
   // Type names (int, float, etc, plus user defined types)
   static const TerminalColor TypeColor = { raw_ostream::GREEN, false };
@@ -138,11 +149,43 @@
       }
     };
 
+    class ChildDumper {
+      ASTDumper &Dumper;
+
+      const Decl *Prev;
+      bool PrevRef;
+    public:
+      ChildDumper(ASTDumper &Dumper) : Dumper(Dumper), Prev(nullptr) {}
+      ~ChildDumper() {
+        if (Prev) {
+          Dumper.lastChild();
+          dump(nullptr);
+        }
+      }
+
+      // FIXME: This should take an arbitrary callable as the dumping action.
+      void dump(const Decl *D, bool Ref = false) {
+        if (Prev) {
+          if (PrevRef)
+            Dumper.dumpDeclRef(Prev);
+          else
+            Dumper.dumpDecl(Prev);
+        }
+        Prev = D;
+        PrevRef = Ref;
+      }
+      void dumpRef(const Decl *D) { dump(D, true); }
+
+      // Give up ownership of the children of the node. By calling this,
+      // the caller takes back responsibility for calling lastChild().
+      void release() { dump(nullptr); }
+    };
+
   public:
     ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
               const SourceManager *SM)
       : OS(OS), Traits(Traits), SM(SM), IsFirstLine(true), MoreChildren(false),
-        LastLocFilename(""), LastLocLine(~0U), FC(0),
+        LastLocFilename(""), LastLocLine(~0U), FC(nullptr),
         ShowColors(SM && SM->getDiagnostics().getShowColors()) { }
 
     ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
@@ -173,7 +216,7 @@
     void dumpBareType(QualType T);
     void dumpType(QualType T);
     void dumpBareDeclRef(const Decl *Node);
-    void dumpDeclRef(const Decl *Node, const char *Label = 0);
+    void dumpDeclRef(const Decl *Node, const char *Label = nullptr);
     void dumpName(const NamedDecl *D);
     bool hasNodes(const DeclContext *DC);
     void dumpDeclContext(const DeclContext *DC);
@@ -211,6 +254,13 @@
     void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D);
     void VisitCXXRecordDecl(const CXXRecordDecl *D);
     void VisitStaticAssertDecl(const StaticAssertDecl *D);
+    template<typename SpecializationDecl>
+    void VisitTemplateDeclSpecialization(ChildDumper &Children,
+                                         const SpecializationDecl *D,
+                                         bool DumpExplicitInst,
+                                         bool DumpRefOnly);
+    template<typename TemplateDecl>
+    void VisitTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst);
     void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D);
     void VisitClassTemplateDecl(const ClassTemplateDecl *D);
     void VisitClassTemplateSpecializationDecl(
@@ -265,6 +315,7 @@
     void VisitIntegerLiteral(const IntegerLiteral *Node);
     void VisitFloatingLiteral(const FloatingLiteral *Node);
     void VisitStringLiteral(const StringLiteral *Str);
+    void VisitInitListExpr(const InitListExpr *ILE);
     void VisitUnaryOperator(const UnaryOperator *Node);
     void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Node);
     void VisitMemberExpr(const MemberExpr *Node);
@@ -394,6 +445,9 @@
 }
 
 void ASTDumper::dumpLocation(SourceLocation Loc) {
+  if (!SM)
+    return;
+
   ColorScope Color(*this, LocationColor);
   SourceLocation SpellingLoc = SM->getSpellingLoc(Loc);
 
@@ -500,17 +554,14 @@
 void ASTDumper::dumpDeclContext(const DeclContext *DC) {
   if (!DC)
     return;
-  bool HasUndeserializedDecls = DC->hasExternalLexicalStorage();
-  for (DeclContext::decl_iterator I = DC->noload_decls_begin(),
-                                  E = DC->noload_decls_end();
-       I != E; ++I) {
-    DeclContext::decl_iterator Next = I;
-    ++Next;
-    if (Next == E && !HasUndeserializedDecls)
-      lastChild();
-    dumpDecl(*I);
-  }
-  if (HasUndeserializedDecls) {
+
+  ChildDumper Children(*this);
+  for (auto *D : DC->noload_decls())
+    Children.dump(D);
+
+  if (DC->hasExternalLexicalStorage()) {
+    Children.release();
+
     lastChild();
     IndentScope Indent(*this);
     ColorScope Color(*this, UndeserializedColor);
@@ -569,6 +620,7 @@
   IndentScope Indent(*this);
   {
     ColorScope Color(*this, AttrColor);
+
     switch (A->getKind()) {
 #define ATTR(X) case attr::X: OS << #X; break;
 #include "clang/Basic/AttrList.inc"
@@ -578,6 +630,10 @@
   }
   dumpPointer(A);
   dumpSourceRange(A->getRange());
+  if (A->isInherited())
+    OS << " Inherited";
+  if (A->isImplicit())
+    OS << " Implicit";
 #include "clang/AST/AttrDump.inc"
 }
 
@@ -742,13 +798,23 @@
     OS << " parent " << cast<Decl>(D->getDeclContext());
   dumpPreviousDecl(OS, D);
   dumpSourceRange(D->getSourceRange());
+  OS << ' ';
+  dumpLocation(D->getLocation());
   if (Module *M = D->getOwningModule())
     OS << " in " << M->getFullModuleName();
   if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
     if (ND->isHidden())
       OS << " hidden";
+  if (D->isImplicit())
+    OS << " implicit";
+  if (D->isUsed())
+    OS << " used";
+  else if (D->isReferenced())
+    OS << " referenced";
+  if (D->isInvalidDecl())
+    OS << " invalid";
 
-  bool HasAttrs = D->attr_begin() != D->attr_end();
+  bool HasAttrs = D->hasAttrs();
   const FullComment *Comment =
       D->getASTContext().getLocalCommentForDeclUncached(D);
   // Decls within functions are visited by the body
@@ -770,9 +836,6 @@
   lastChild();
   dumpFullComment(Comment);
 
-  if (D->isInvalidDecl())
-    OS << " invalid";
-
   setMoreChildren(false);
   if (HasDeclContext)
     dumpDeclContext(cast<DeclContext>(D));
@@ -824,13 +887,10 @@
 void ASTDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) {
   dumpName(D);
   dumpType(D->getType());
-  for (IndirectFieldDecl::chain_iterator I = D->chain_begin(),
-                                         E = D->chain_end();
-       I != E; ++I) {
-    if (I + 1 == E)
-      lastChild();
-    dumpDeclRef(*I);
-  }
+
+  ChildDumper Children(*this);
+  for (auto *Child : D->chain())
+    Children.dumpRef(Child);
 }
 
 void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) {
@@ -964,6 +1024,11 @@
   if (D->isNRVOVariable())
     OS << " nrvo";
   if (D->hasInit()) {
+    switch (D->getInitStyle()) {
+    case VarDecl::CInit: OS << " cinit"; break;
+    case VarDecl::CallInit: OS << " callinit"; break;
+    case VarDecl::ListInit: OS << " listinit"; break;
+    }
     lastChild();
     dumpStmt(D->getInit());
   }
@@ -1016,15 +1081,13 @@
   if (!D->isCompleteDefinition())
     return;
 
-  for (CXXRecordDecl::base_class_const_iterator I = D->bases_begin(),
-                                                E = D->bases_end();
-       I != E; ++I) {
+  for (const auto &I : D->bases()) {
     IndentScope Indent(*this);
-    if (I->isVirtual())
+    if (I.isVirtual())
       OS << "virtual ";
-    dumpAccessSpecifier(I->getAccessSpecifier());
-    dumpType(I->getType());
-    if (I->isPackExpansion())
+    dumpAccessSpecifier(I.getAccessSpecifier());
+    dumpType(I.getType());
+    if (I.isPackExpansion())
       OS << "...";
   }
 }
@@ -1035,63 +1098,69 @@
   dumpStmt(D->getMessage());
 }
 
-void ASTDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
-  dumpName(D);
-  dumpTemplateParameters(D->getTemplateParameters());
-  dumpDecl(D->getTemplatedDecl());
-  for (FunctionTemplateDecl::spec_iterator I = D->spec_begin(),
-                                           E = D->spec_end();
-       I != E; ++I) {
-    FunctionTemplateDecl::spec_iterator Next = I;
-    ++Next;
-    if (Next == E)
-      lastChild();
-    switch (I->getTemplateSpecializationKind()) {
-    case TSK_Undeclared:
-    case TSK_ImplicitInstantiation:
+template<typename SpecializationDecl>
+void ASTDumper::VisitTemplateDeclSpecialization(ChildDumper &Children,
+                                                const SpecializationDecl *D,
+                                                bool DumpExplicitInst,
+                                                bool DumpRefOnly) {
+  bool DumpedAny = false;
+  for (auto *RedeclWithBadType : D->redecls()) {
+    // FIXME: The redecls() range sometimes has elements of a less-specific
+    // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives
+    // us TagDecls, and should give CXXRecordDecls).
+    auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType);
+    if (!Redecl) {
+      // Found the injected-class-name for a class template. This will be dumped
+      // as part of its surrounding class so we don't need to dump it here.
+      assert(isa<CXXRecordDecl>(RedeclWithBadType) &&
+             "expected an injected-class-name");
+      continue;
+    }
+
+    switch (Redecl->getTemplateSpecializationKind()) {
     case TSK_ExplicitInstantiationDeclaration:
     case TSK_ExplicitInstantiationDefinition:
-      if (D == D->getCanonicalDecl())
-        dumpDecl(*I);
-      else
-        dumpDeclRef(*I);
+      if (!DumpExplicitInst)
+        break;
+      // Fall through.
+    case TSK_Undeclared:
+    case TSK_ImplicitInstantiation:
+      Children.dump(Redecl, DumpRefOnly);
+      DumpedAny = true;
       break;
     case TSK_ExplicitSpecialization:
-      dumpDeclRef(*I);
       break;
     }
   }
+
+  // Ensure we dump at least one decl for each specialization.
+  if (!DumpedAny)
+    Children.dumpRef(D);
+}
+
+template<typename TemplateDecl>
+void ASTDumper::VisitTemplateDecl(const TemplateDecl *D,
+                                  bool DumpExplicitInst) {
+  dumpName(D);
+  dumpTemplateParameters(D->getTemplateParameters());
+
+  ChildDumper Children(*this);
+  Children.dump(D->getTemplatedDecl());
+
+  for (auto *Child : D->specializations())
+    VisitTemplateDeclSpecialization(Children, Child, DumpExplicitInst,
+                                    !D->isCanonicalDecl());
+}
+
+void ASTDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
+  // FIXME: We don't add a declaration of a function template specialization
+  // to its context when it's explicitly instantiated, so dump explicit
+  // instantiations when we dump the template itself.
+  VisitTemplateDecl(D, true);
 }
 
 void ASTDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
-  dumpName(D);
-  dumpTemplateParameters(D->getTemplateParameters());
-
-  ClassTemplateDecl::spec_iterator I = D->spec_begin();
-  ClassTemplateDecl::spec_iterator E = D->spec_end();
-  if (I == E)
-    lastChild();
-  dumpDecl(D->getTemplatedDecl());
-  for (; I != E; ++I) {
-    ClassTemplateDecl::spec_iterator Next = I;
-    ++Next;
-    if (Next == E)
-      lastChild();
-    switch (I->getTemplateSpecializationKind()) {
-    case TSK_Undeclared:
-    case TSK_ImplicitInstantiation:
-      if (D == D->getCanonicalDecl())
-        dumpDecl(*I);
-      else
-        dumpDeclRef(*I);
-      break;
-    case TSK_ExplicitSpecialization:
-    case TSK_ExplicitInstantiationDeclaration:
-    case TSK_ExplicitInstantiationDefinition:
-      dumpDeclRef(*I);
-      break;
-    }
-  }
+  VisitTemplateDecl(D, false);
 }
 
 void ASTDumper::VisitClassTemplateSpecializationDecl(
@@ -1114,34 +1183,7 @@
 }
 
 void ASTDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) {
-  dumpName(D);
-  dumpTemplateParameters(D->getTemplateParameters());
-
-  VarTemplateDecl::spec_iterator I = D->spec_begin();
-  VarTemplateDecl::spec_iterator E = D->spec_end();
-  if (I == E)
-    lastChild();
-  dumpDecl(D->getTemplatedDecl());
-  for (; I != E; ++I) {
-    VarTemplateDecl::spec_iterator Next = I;
-    ++Next;
-    if (Next == E)
-      lastChild();
-    switch (I->getTemplateSpecializationKind()) {
-    case TSK_Undeclared:
-    case TSK_ImplicitInstantiation:
-      if (D == D->getCanonicalDecl())
-        dumpDecl(*I);
-      else
-        dumpDeclRef(*I);
-      break;
-    case TSK_ExplicitSpecialization:
-    case TSK_ExplicitInstantiationDeclaration:
-    case TSK_ExplicitInstantiationDefinition:
-      dumpDeclRef(*I);
-      break;
-    }
-  }
+  VisitTemplateDecl(D, false);
 }
 
 void ASTDumper::VisitVarTemplateSpecializationDecl(
@@ -1164,8 +1206,10 @@
   if (D->isParameterPack())
     OS << " ...";
   dumpName(D);
-  if (D->hasDefaultArgument())
-    dumpType(D->getDefaultArgument());
+  if (D->hasDefaultArgument()) {
+    lastChild();
+    dumpTemplateArgument(D->getDefaultArgument());
+  }
 }
 
 void ASTDumper::VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
@@ -1173,8 +1217,10 @@
   if (D->isParameterPack())
     OS << " ...";
   dumpName(D);
-  if (D->hasDefaultArgument())
-    dumpStmt(D->getDefaultArgument());
+  if (D->hasDefaultArgument()) {
+    lastChild();
+    dumpTemplateArgument(D->getDefaultArgument());
+  }
 }
 
 void ASTDumper::VisitTemplateTemplateParmDecl(
@@ -1183,8 +1229,10 @@
     OS << " ...";
   dumpName(D);
   dumpTemplateParameters(D->getTemplateParameters());
-  if (D->hasDefaultArgument())
+  if (D->hasDefaultArgument()) {
+    lastChild();
     dumpTemplateArgumentLoc(D->getDefaultArgument());
+  }
 }
 
 void ASTDumper::VisitUsingDecl(const UsingDecl *D) {
@@ -1241,8 +1289,6 @@
   dumpType(D->getType());
   if (D->getSynthesize())
     OS << " synthesize";
-  if (D->getBackingIvarReferencedInAccessor())
-    OS << " BackingIvarReferencedInAccessor";
 
   switch (D->getAccessControl()) {
   case ObjCIvarDecl::None:
@@ -1269,7 +1315,7 @@
   else
     OS << " +";
   dumpName(D);
-  dumpType(D->getResultType());
+  dumpType(D->getReturnType());
 
   bool OldMoreChildren = hasMoreChildren();
   bool IsVariadic = D->isVariadic();
@@ -1327,28 +1373,20 @@
 
 void ASTDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
   dumpName(D);
-  for (ObjCProtocolDecl::protocol_iterator I = D->protocol_begin(),
-                                           E = D->protocol_end();
-       I != E; ++I) {
-    if (I + 1 == E)
-      lastChild();
-    dumpDeclRef(*I);
-  }
+
+  ChildDumper Children(*this);
+  for (auto *Child : D->protocols())
+    Children.dumpRef(Child);
 }
 
 void ASTDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
   dumpName(D);
   dumpDeclRef(D->getSuperClass(), "super");
-  if (D->protocol_begin() == D->protocol_end())
-    lastChild();
-  dumpDeclRef(D->getImplementation());
-  for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
-                                            E = D->protocol_end();
-       I != E; ++I) {
-    if (I + 1 == E)
-      lastChild();
-    dumpDeclRef(*I);
-  }
+
+  ChildDumper Children(*this);
+  Children.dumpRef(D->getImplementation());
+  for (auto *Child : D->protocols())
+    Children.dumpRef(Child);
 }
 
 void ASTDumper::VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
@@ -1427,9 +1465,8 @@
 }
 
 void ASTDumper::VisitBlockDecl(const BlockDecl *D) {
-  for (BlockDecl::param_const_iterator I = D->param_begin(), E = D->param_end();
-       I != E; ++I)
-    dumpDecl(*I);
+  for (auto I : D->params())
+    dumpDecl(I);
 
   if (D->isVariadic()) {
     IndentScope Indent(*this);
@@ -1440,20 +1477,19 @@
     IndentScope Indent(*this);
     OS << "capture this";
   }
-  for (BlockDecl::capture_iterator I = D->capture_begin(), E = D->capture_end();
-       I != E; ++I) {
+  for (const auto &I : D->captures()) {
     IndentScope Indent(*this);
     OS << "capture";
-    if (I->isByRef())
+    if (I.isByRef())
       OS << " byref";
-    if (I->isNested())
+    if (I.isNested())
       OS << " nested";
-    if (I->getVariable()) {
+    if (I.getVariable()) {
       OS << ' ';
-      dumpBareDeclRef(I->getVariable());
+      dumpBareDeclRef(I.getVariable());
     }
-    if (I->hasCopyExpr())
-      dumpStmt(I->getCopyExpr());
+    if (I.hasCopyExpr())
+      dumpStmt(I.getCopyExpr());
   }
   lastChild();
   dumpStmt(D->getBody());
@@ -1664,6 +1700,7 @@
   case PredefinedExpr::FuncDName:      OS <<  " __FUNCDNAME__"; break;
   case PredefinedExpr::LFunction:      OS <<  " L__FUNCTION__"; break;
   case PredefinedExpr::PrettyFunction: OS <<  " __PRETTY_FUNCTION__";break;
+  case PredefinedExpr::FuncSig:        OS <<  " __FUNCSIG__"; break;
   }
 }
 
@@ -1694,6 +1731,22 @@
   Str->outputString(OS);
 }
 
+void ASTDumper::VisitInitListExpr(const InitListExpr *ILE) {
+  VisitExpr(ILE);
+  if (auto *Filler = ILE->getArrayFiller()) {
+    if (!ILE->getNumInits())
+      lastChild();
+    IndentScope Indent(*this);
+    OS << "array filler";
+    lastChild();
+    dumpStmt(Filler);
+  }
+  if (auto *Field = ILE->getInitializedFieldInUnion()) {
+    OS << " field ";
+    dumpBareDeclRef(Field);
+  }
+}
+
 void ASTDumper::VisitUnaryOperator(const UnaryOperator *Node) {
   VisitExpr(Node);
   OS << " " << (Node->isPostfix() ? "postfix" : "prefix")
@@ -1838,7 +1891,8 @@
 
 void ASTDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) {
   VisitExpr(Node);
-  OS << " selector=" << Node->getSelector().getAsString();
+  OS << " selector=";
+  Node->getSelector().print(OS);
   switch (Node->getReceiverKind()) {
   case ObjCMessageExpr::Instance:
     break;
@@ -1860,7 +1914,8 @@
 
 void ASTDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) {
   VisitExpr(Node);
-  OS << " selector=" << Node->getBoxingMethod()->getSelector().getAsString();
+  OS << " selector=";
+  Node->getBoxingMethod()->getSelector().print(OS);
 }
 
 void ASTDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
@@ -1879,7 +1934,8 @@
 void ASTDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) {
   VisitExpr(Node);
 
-  OS << " " << Node->getSelector().getAsString();
+  OS << " ";
+  Node->getSelector().print(OS);
 }
 
 void ASTDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) {
@@ -1893,13 +1949,13 @@
   if (Node->isImplicitProperty()) {
     OS << " Kind=MethodRef Getter=\"";
     if (Node->getImplicitPropertyGetter())
-      OS << Node->getImplicitPropertyGetter()->getSelector().getAsString();
+      Node->getImplicitPropertyGetter()->getSelector().print(OS);
     else
       OS << "(null)";
 
     OS << "\" Setter=\"";
     if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter())
-      OS << Setter->getSelector().getAsString();
+      Setter->getSelector().print(OS);
     else
       OS << "(null)";
     OS << "\"";
@@ -1926,7 +1982,7 @@
   else
     OS << " Kind=DictionarySubscript GetterForDictionary=\"";
   if (Node->getAtIndexMethodDecl())
-    OS << Node->getAtIndexMethodDecl()->getSelector().getAsString();
+    Node->getAtIndexMethodDecl()->getSelector().print(OS);
   else
     OS << "(null)";
 
@@ -1935,7 +1991,7 @@
   else
     OS << "\" SetterForDictionary=\"";
   if (Node->setAtIndexMethodDecl())
-    OS << Node->setAtIndexMethodDecl()->getSelector().getAsString();
+    Node->setAtIndexMethodDecl()->getSelector().print(OS);
   else
     OS << "(null)";
 }
@@ -1964,7 +2020,7 @@
 
   FC = C;
   dumpComment(C);
-  FC = 0;
+  FC = nullptr;
 }
 
 void ASTDumper::dumpComment(const Comment *C) {
@@ -2054,7 +2110,7 @@
       OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
   }
 
-  if (C->isParamIndexValid())
+  if (C->isParamIndexValid() && !C->isVarArgParam())
     OS << " ParamIndex=" << C->getParamIndex();
 }
 
@@ -2095,27 +2151,25 @@
 // Decl method implementations
 //===----------------------------------------------------------------------===//
 
-void Decl::dump() const {
-  dump(llvm::errs());
-}
+LLVM_DUMP_METHOD void Decl::dump() const { dump(llvm::errs()); }
 
-void Decl::dump(raw_ostream &OS) const {
+LLVM_DUMP_METHOD void Decl::dump(raw_ostream &OS) const {
   ASTDumper P(OS, &getASTContext().getCommentCommandTraits(),
               &getASTContext().getSourceManager());
   P.dumpDecl(this);
 }
 
-void Decl::dumpColor() const {
+LLVM_DUMP_METHOD void Decl::dumpColor() const {
   ASTDumper P(llvm::errs(), &getASTContext().getCommentCommandTraits(),
               &getASTContext().getSourceManager(), /*ShowColors*/true);
   P.dumpDecl(this);
 }
 
-void DeclContext::dumpLookups() const {
+LLVM_DUMP_METHOD void DeclContext::dumpLookups() const {
   dumpLookups(llvm::errs());
 }
 
-void DeclContext::dumpLookups(raw_ostream &OS) const {
+LLVM_DUMP_METHOD void DeclContext::dumpLookups(raw_ostream &OS) const {
   const DeclContext *DC = this;
   while (!DC->isTranslationUnit())
     DC = DC->getParent();
@@ -2128,22 +2182,22 @@
 // Stmt method implementations
 //===----------------------------------------------------------------------===//
 
-void Stmt::dump(SourceManager &SM) const {
+LLVM_DUMP_METHOD void Stmt::dump(SourceManager &SM) const {
   dump(llvm::errs(), SM);
 }
 
-void Stmt::dump(raw_ostream &OS, SourceManager &SM) const {
-  ASTDumper P(OS, 0, &SM);
+LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS, SourceManager &SM) const {
+  ASTDumper P(OS, nullptr, &SM);
   P.dumpStmt(this);
 }
 
-void Stmt::dump() const {
-  ASTDumper P(llvm::errs(), 0, 0);
+LLVM_DUMP_METHOD void Stmt::dump() const {
+  ASTDumper P(llvm::errs(), nullptr, nullptr);
   P.dumpStmt(this);
 }
 
-void Stmt::dumpColor() const {
-  ASTDumper P(llvm::errs(), 0, 0, /*ShowColors*/true);
+LLVM_DUMP_METHOD void Stmt::dumpColor() const {
+  ASTDumper P(llvm::errs(), nullptr, nullptr, /*ShowColors*/true);
   P.dumpStmt(this);
 }
 
@@ -2151,11 +2205,11 @@
 // Comment method implementations
 //===----------------------------------------------------------------------===//
 
-void Comment::dump() const {
-  dump(llvm::errs(), 0, 0);
+LLVM_DUMP_METHOD void Comment::dump() const {
+  dump(llvm::errs(), nullptr, nullptr);
 }
 
-void Comment::dump(const ASTContext &Context) const {
+LLVM_DUMP_METHOD void Comment::dump(const ASTContext &Context) const {
   dump(llvm::errs(), &Context.getCommentCommandTraits(),
        &Context.getSourceManager());
 }
@@ -2167,8 +2221,8 @@
   D.dumpFullComment(FC);
 }
 
-void Comment::dumpColor() const {
+LLVM_DUMP_METHOD void Comment::dumpColor() const {
   const FullComment *FC = dyn_cast<FullComment>(this);
-  ASTDumper D(llvm::errs(), 0, 0, /*ShowColors*/true);
+  ASTDumper D(llvm::errs(), nullptr, nullptr, /*ShowColors*/true);
   D.dumpFullComment(FC);
 }
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index e16015b..b0e0b1d 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -81,7 +81,7 @@
     bool ImportDeclParts(NamedDecl *D, DeclContext *&DC, 
                          DeclContext *&LexicalDC, DeclarationName &Name, 
                          SourceLocation &Loc);
-    void ImportDefinitionIfNeeded(Decl *FromD, Decl *ToD = 0);
+    void ImportDefinitionIfNeeded(Decl *FromD, Decl *ToD = nullptr);
     void ImportDeclarationNameLoc(const DeclarationNameInfo &From,
                                   DeclarationNameInfo& To);
     void ImportDeclContext(DeclContext *FromDC, bool ForceImport = false);
@@ -407,10 +407,11 @@
       return false;
     break;
   
+  case Type::Adjusted:
   case Type::Decayed:
     if (!IsStructurallyEquivalent(Context,
-                                  cast<DecayedType>(T1)->getPointeeType(),
-                                  cast<DecayedType>(T2)->getPointeeType()))
+                                  cast<AdjustedType>(T1)->getOriginalType(),
+                                  cast<AdjustedType>(T2)->getOriginalType()))
       return false;
     break;
 
@@ -534,12 +535,11 @@
   case Type::FunctionProto: {
     const FunctionProtoType *Proto1 = cast<FunctionProtoType>(T1);
     const FunctionProtoType *Proto2 = cast<FunctionProtoType>(T2);
-    if (Proto1->getNumArgs() != Proto2->getNumArgs())
+    if (Proto1->getNumParams() != Proto2->getNumParams())
       return false;
-    for (unsigned I = 0, N = Proto1->getNumArgs(); I != N; ++I) {
-      if (!IsStructurallyEquivalent(Context, 
-                                    Proto1->getArgType(I),
-                                    Proto2->getArgType(I)))
+    for (unsigned I = 0, N = Proto1->getNumParams(); I != N; ++I) {
+      if (!IsStructurallyEquivalent(Context, Proto1->getParamType(I),
+                                    Proto2->getParamType(I)))
         return false;
     }
     if (Proto1->isVariadic() != Proto2->isVariadic())
@@ -570,9 +570,8 @@
   case Type::FunctionNoProto: {
     const FunctionType *Function1 = cast<FunctionType>(T1);
     const FunctionType *Function2 = cast<FunctionType>(T2);
-    if (!IsStructurallyEquivalent(Context, 
-                                  Function1->getResultType(),
-                                  Function2->getResultType()))
+    if (!IsStructurallyEquivalent(Context, Function1->getReturnType(),
+                                  Function2->getReturnType()))
       return false;
       if (Function1->getExtInfo() != Function2->getExtInfo())
         return false;
@@ -931,10 +930,8 @@
     return None;
 
   unsigned Index = 0;
-  for (DeclContext::decl_iterator D = Owner->noload_decls_begin(),
-                               DEnd = Owner->noload_decls_end();
-       D != DEnd; ++D) {
-    FieldDecl *F = dyn_cast<FieldDecl>(*D);
+  for (const auto *D : Owner->noload_decls()) {
+    const auto *F = dyn_cast<FieldDecl>(D);
     if (!F || !F->isAnonymousStructOrUnion())
       continue;
 
@@ -1586,7 +1583,7 @@
 ASTNodeImporter::VisitFunctionNoProtoType(const FunctionNoProtoType *T) {
   // FIXME: What happens if we're importing a function without a prototype 
   // into C++? Should we make it variadic?
-  QualType ToResultType = Importer.Import(T->getResultType());
+  QualType ToResultType = Importer.Import(T->getReturnType());
   if (ToResultType.isNull())
     return QualType();
 
@@ -1595,16 +1592,14 @@
 }
 
 QualType ASTNodeImporter::VisitFunctionProtoType(const FunctionProtoType *T) {
-  QualType ToResultType = Importer.Import(T->getResultType());
+  QualType ToResultType = Importer.Import(T->getReturnType());
   if (ToResultType.isNull())
     return QualType();
   
   // Import argument types
   SmallVector<QualType, 4> ArgTypes;
-  for (FunctionProtoType::arg_type_iterator A = T->arg_type_begin(),
-                                         AEnd = T->arg_type_end();
-       A != AEnd; ++A) {
-    QualType ArgType = Importer.Import(*A);
+  for (const auto &A : T->param_types()) {
+    QualType ArgType = Importer.Import(A);
     if (ArgType.isNull())
       return QualType();
     ArgTypes.push_back(ArgType);
@@ -1612,10 +1607,8 @@
   
   // Import exception types
   SmallVector<QualType, 4> ExceptionTypes;
-  for (FunctionProtoType::exception_iterator E = T->exception_begin(),
-                                          EEnd = T->exception_end();
-       E != EEnd; ++E) {
-    QualType ExceptionType = Importer.Import(*E);
+  for (const auto &E : T->exceptions()) {
+    QualType ExceptionType = Importer.Import(E);
     if (ExceptionType.isNull())
       return QualType();
     ExceptionTypes.push_back(ExceptionType);
@@ -1631,7 +1624,7 @@
   ToEPI.RefQualifier = FromEPI.RefQualifier;
   ToEPI.NumExceptions = ExceptionTypes.size();
   ToEPI.Exceptions = ExceptionTypes.data();
-  ToEPI.ConsumedArguments = FromEPI.ConsumedArguments;
+  ToEPI.ConsumedParameters = FromEPI.ConsumedParameters;
   ToEPI.ExceptionSpecType = FromEPI.ExceptionSpecType;
   ToEPI.NoexceptExpr = Importer.Import(FromEPI.NoexceptExpr);
   ToEPI.ExceptionSpecDecl = cast_or_null<FunctionDecl>(
@@ -1756,7 +1749,7 @@
 }
 
 QualType ASTNodeImporter::VisitElaboratedType(const ElaboratedType *T) {
-  NestedNameSpecifier *ToQualifier = 0;
+  NestedNameSpecifier *ToQualifier = nullptr;
   // Note: the qualifier in an ElaboratedType is optional.
   if (T->getQualifier()) {
     ToQualifier = Importer.Import(T->getQualifier());
@@ -1787,11 +1780,9 @@
     return QualType();
 
   SmallVector<ObjCProtocolDecl *, 4> Protocols;
-  for (ObjCObjectType::qual_iterator P = T->qual_begin(), 
-                                     PEnd = T->qual_end();
-       P != PEnd; ++P) {
+  for (auto *P : T->quals()) {
     ObjCProtocolDecl *Protocol
-      = dyn_cast_or_null<ObjCProtocolDecl>(Importer.Import(*P));
+      = dyn_cast_or_null<ObjCProtocolDecl>(Importer.Import(P));
     if (!Protocol)
       return QualType();
     Protocols.push_back(Protocol);
@@ -1909,11 +1900,8 @@
     return;
   }
   
-  for (DeclContext::decl_iterator From = FromDC->decls_begin(),
-                               FromEnd = FromDC->decls_end();
-       From != FromEnd;
-       ++From)
-    Importer.Import(*From);
+  for (auto *From : FromDC->decls())
+    Importer.Import(From);
 }
 
 bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To, 
@@ -1946,6 +1934,7 @@
     ToData.HasProtectedFields = FromData.HasProtectedFields;
     ToData.HasPublicFields = FromData.HasPublicFields;
     ToData.HasMutableFields = FromData.HasMutableFields;
+    ToData.HasVariantMembers = FromData.HasVariantMembers;
     ToData.HasOnlyCMembers = FromData.HasOnlyCMembers;
     ToData.HasInClassInitializer = FromData.HasInClassInitializer;
     ToData.HasUninitializedReferenceMember
@@ -1986,29 +1975,25 @@
     ToData.IsLambda = FromData.IsLambda;
 
     SmallVector<CXXBaseSpecifier *, 4> Bases;
-    for (CXXRecordDecl::base_class_iterator 
-                  Base1 = FromCXX->bases_begin(),
-            FromBaseEnd = FromCXX->bases_end();
-         Base1 != FromBaseEnd;
-         ++Base1) {
-      QualType T = Importer.Import(Base1->getType());
+    for (const auto &Base1 : FromCXX->bases()) {
+      QualType T = Importer.Import(Base1.getType());
       if (T.isNull())
         return true;
 
       SourceLocation EllipsisLoc;
-      if (Base1->isPackExpansion())
-        EllipsisLoc = Importer.Import(Base1->getEllipsisLoc());
+      if (Base1.isPackExpansion())
+        EllipsisLoc = Importer.Import(Base1.getEllipsisLoc());
 
       // Ensure that we have a definition for the base.
-      ImportDefinitionIfNeeded(Base1->getType()->getAsCXXRecordDecl());
+      ImportDefinitionIfNeeded(Base1.getType()->getAsCXXRecordDecl());
         
       Bases.push_back(
                     new (Importer.getToContext()) 
-                      CXXBaseSpecifier(Importer.Import(Base1->getSourceRange()),
-                                       Base1->isVirtual(),
-                                       Base1->isBaseOfClass(),
-                                       Base1->getAccessSpecifierAsWritten(),
-                                   Importer.Import(Base1->getTypeSourceInfo()),
+                      CXXBaseSpecifier(Importer.Import(Base1.getSourceRange()),
+                                       Base1.isVirtual(),
+                                       Base1.isBaseOfClass(),
+                                       Base1.getAccessSpecifierAsWritten(),
+                                   Importer.Import(Base1.getTypeSourceInfo()),
                                        EllipsisLoc));
     }
     if (!Bases.empty())
@@ -2075,8 +2060,8 @@
        P != PEnd; ++P) {
     Decl *To = Importer.Import(*P);
     if (!To)
-      return 0;
-    
+      return nullptr;
+
     ToParams.push_back(cast<NamedDecl>(To));
   }
   
@@ -2236,7 +2221,7 @@
 Decl *ASTNodeImporter::VisitDecl(Decl *D) {
   Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node)
     << D->getDeclKindName();
-  return 0;
+  return nullptr;
 }
 
 Decl *ASTNodeImporter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
@@ -2254,9 +2239,9 @@
   DeclarationName Name;
   SourceLocation Loc;
   if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
-    return 0;
-  
-  NamespaceDecl *MergeWithNamespace = 0;
+    return nullptr;
+
+  NamespaceDecl *MergeWithNamespace = nullptr;
   if (!Name) {
     // This is an anonymous namespace. Adopt an existing anonymous
     // namespace if we can.
@@ -2296,7 +2281,7 @@
                                         D->isInline(),
                                         Importer.Import(D->getLocStart()),
                                         Loc, Name.getAsIdentifierInfo(),
-                                        /*PrevDecl=*/0);
+                                        /*PrevDecl=*/nullptr);
     ToNamespace->setLexicalDeclContext(LexicalDC);
     LexicalDC->addDeclInternal(ToNamespace);
     
@@ -2322,8 +2307,8 @@
   DeclarationName Name;
   SourceLocation Loc;
   if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
-    return 0;
-  
+    return nullptr;
+
   // If this typedef is not in block scope, determine whether we've
   // seen a typedef with the same name (that we can merge with) or any
   // other entity by that name (which name lookup could conflict with).
@@ -2350,15 +2335,15 @@
                                          ConflictingDecls.data(), 
                                          ConflictingDecls.size());
       if (!Name)
-        return 0;
+        return nullptr;
     }
   }
   
   // Import the underlying type of this typedef;
   QualType T = Importer.Import(D->getUnderlyingType());
   if (T.isNull())
-    return 0;
-  
+    return nullptr;
+
   // Create the new typedef node.
   TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
   SourceLocation StartL = Importer.Import(D->getLocStart());
@@ -2396,8 +2381,8 @@
   DeclarationName Name;
   SourceLocation Loc;
   if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
-    return 0;
-  
+    return nullptr;
+
   // Figure out what enum name we're looking for.
   unsigned IDNS = Decl::IDNS_Tag;
   DeclarationName SearchName = Name;
@@ -2440,7 +2425,7 @@
   // Create the enum declaration.
   EnumDecl *D2 = EnumDecl::Create(Importer.getToContext(), DC,
                                   Importer.Import(D->getLocStart()),
-                                  Loc, Name.getAsIdentifierInfo(), 0,
+                                  Loc, Name.getAsIdentifierInfo(), nullptr,
                                   D->isScoped(), D->isScopedUsingClassTag(),
                                   D->isFixed());
   // Import the qualifier, if any.
@@ -2453,12 +2438,12 @@
   // Import the integer type.
   QualType ToIntegerType = Importer.Import(D->getIntegerType());
   if (ToIntegerType.isNull())
-    return 0;
+    return nullptr;
   D2->setIntegerType(ToIntegerType);
   
   // Import the definition
   if (D->isCompleteDefinition() && ImportDefinition(D, D2))
-    return 0;
+    return nullptr;
 
   return D2;
 }
@@ -2471,8 +2456,8 @@
   if (Definition && Definition != D) {
     Decl *ImportedDef = Importer.Import(Definition);
     if (!ImportedDef)
-      return 0;
-    
+      return nullptr;
+
     return Importer.Imported(D, ImportedDef);
   }
   
@@ -2481,8 +2466,8 @@
   DeclarationName Name;
   SourceLocation Loc;
   if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
-    return 0;
-      
+    return nullptr;
+
   // Figure out what structure name we're looking for.
   unsigned IDNS = Decl::IDNS_Tag;
   DeclarationName SearchName = Name;
@@ -2493,7 +2478,7 @@
     IDNS |= Decl::IDNS_Ordinary;
 
   // We may already have a record of the same name; try to find and match it.
-  RecordDecl *AdoptDecl = 0;
+  RecordDecl *AdoptDecl = nullptr;
   if (!DC->isFunctionOrMethod()) {
     SmallVector<NamedDecl *, 4> ConflictingDecls;
     SmallVector<NamedDecl *, 2> FoundDecls;
@@ -2538,6 +2523,21 @@
         } else if (!D->isCompleteDefinition()) {
           // We have a forward declaration of this type, so adopt that forward
           // declaration rather than building a new one.
+            
+          // If one or both can be completed from external storage then try one
+          // last time to complete and compare them before doing this.
+            
+          if (FoundRecord->hasExternalLexicalStorage() &&
+              !FoundRecord->isCompleteDefinition())
+            FoundRecord->getASTContext().getExternalSource()->CompleteType(FoundRecord);
+          if (D->hasExternalLexicalStorage())
+            D->getASTContext().getExternalSource()->CompleteType(D);
+            
+          if (FoundRecord->isCompleteDefinition() &&
+              D->isCompleteDefinition() &&
+              !IsStructuralMatch(D, FoundRecord))
+            continue;
+              
           AdoptDecl = FoundRecord;
           continue;
         } else if (!SearchName) {
@@ -2581,8 +2581,8 @@
   Importer.Imported(D, D2);
 
   if (D->isCompleteDefinition() && ImportDefinition(D, D2, IDK_Default))
-    return 0;
-  
+    return nullptr;
+
   return D2;
 }
 
@@ -2592,11 +2592,11 @@
   DeclarationName Name;
   SourceLocation Loc;
   if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
-    return 0;
+    return nullptr;
 
   QualType T = Importer.Import(D->getType());
   if (T.isNull())
-    return 0;
+    return nullptr;
 
   // Determine whether there are any other declarations with the same name and 
   // in the same context.
@@ -2623,14 +2623,14 @@
                                          ConflictingDecls.data(), 
                                          ConflictingDecls.size());
       if (!Name)
-        return 0;
+        return nullptr;
     }
   }
   
   Expr *Init = Importer.Import(D->getInitExpr());
   if (D->getInitExpr() && !Init)
-    return 0;
-  
+    return nullptr;
+
   EnumConstantDecl *ToEnumerator
     = EnumConstantDecl::Create(Importer.getToContext(), cast<EnumDecl>(DC), Loc, 
                                Name.getAsIdentifierInfo(), T, 
@@ -2648,7 +2648,7 @@
   DeclarationName Name;
   SourceLocation Loc;
   if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
-    return 0;
+    return nullptr;
 
   // Try to find a function in our own ("to") context with the same name, same
   // type, and in the same context as the function we're importing.
@@ -2694,7 +2694,7 @@
                                          ConflictingDecls.data(), 
                                          ConflictingDecls.size());
       if (!Name)
-        return 0;
+        return nullptr;
     }    
   }
 
@@ -2716,7 +2716,7 @@
         FromEPI.NoexceptExpr) {
       FunctionProtoType::ExtProtoInfo DefaultEPI;
       FromTy = Importer.getFromContext().getFunctionType(
-          FromFPT->getResultType(), FromFPT->getArgTypes(), DefaultEPI);
+          FromFPT->getReturnType(), FromFPT->getParamTypes(), DefaultEPI);
       usedDifferentExceptionSpec = true;
     }
   }
@@ -2724,22 +2724,21 @@
   // Import the type.
   QualType T = Importer.Import(FromTy);
   if (T.isNull())
-    return 0;
-  
+    return nullptr;
+
   // Import the function parameters.
   SmallVector<ParmVarDecl *, 8> Parameters;
-  for (FunctionDecl::param_iterator P = D->param_begin(), PEnd = D->param_end();
-       P != PEnd; ++P) {
-    ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(*P));
+  for (auto P : D->params()) {
+    ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(P));
     if (!ToP)
-      return 0;
-    
+      return nullptr;
+
     Parameters.push_back(ToP);
   }
   
   // Create the imported function.
   TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
-  FunctionDecl *ToFunction = 0;
+  FunctionDecl *ToFunction = nullptr;
   if (CXXConstructorDecl *FromConstructor = dyn_cast<CXXConstructorDecl>(D)) {
     ToFunction = CXXConstructorDecl::Create(Importer.getToContext(),
                                             cast<CXXRecordDecl>(DC),
@@ -2804,7 +2803,7 @@
     // Update FunctionProtoType::ExtProtoInfo.
     QualType T = Importer.Import(D->getType());
     if (T.isNull())
-      return 0;
+      return nullptr;
     ToFunction->setType(T);
   }
 
@@ -2838,10 +2837,8 @@
     return 0;
 
   unsigned Index = 1;
-  for (DeclContext::decl_iterator D = Owner->noload_decls_begin(),
-                               DEnd = Owner->noload_decls_end();
-       D != DEnd; ++D) {
-    if (*D == F)
+  for (const auto *D : Owner->noload_decls()) {
+    if (D == F)
       return Index;
 
     if (isa<FieldDecl>(*D) || isa<IndirectFieldDecl>(*D))
@@ -2857,8 +2854,8 @@
   DeclarationName Name;
   SourceLocation Loc;
   if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
-    return 0;
-  
+    return nullptr;
+
   // Determine whether we've already imported this field. 
   SmallVector<NamedDecl *, 2> FoundDecls;
   DC->localUncachedLookup(Name, FoundDecls);
@@ -2878,20 +2875,20 @@
         << Name << D->getType() << FoundField->getType();
       Importer.ToDiag(FoundField->getLocation(), diag::note_odr_value_here)
         << FoundField->getType();
-      return 0;
+      return nullptr;
     }
   }
 
   // Import the type.
   QualType T = Importer.Import(D->getType());
   if (T.isNull())
-    return 0;
-  
+    return nullptr;
+
   TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
   Expr *BitWidth = Importer.Import(D->getBitWidth());
   if (!BitWidth && D->getBitWidth())
-    return 0;
-  
+    return nullptr;
+
   FieldDecl *ToField = FieldDecl::Create(Importer.getToContext(), DC,
                                          Importer.Import(D->getInnerLocStart()),
                                          Loc, Name.getAsIdentifierInfo(),
@@ -2913,7 +2910,7 @@
   DeclarationName Name;
   SourceLocation Loc;
   if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
-    return 0;
+    return nullptr;
 
   // Determine whether we've already imported this field. 
   SmallVector<NamedDecl *, 2> FoundDecls;
@@ -2940,24 +2937,23 @@
         << Name << D->getType() << FoundField->getType();
       Importer.ToDiag(FoundField->getLocation(), diag::note_odr_value_here)
         << FoundField->getType();
-      return 0;
+      return nullptr;
     }
   }
 
   // Import the type.
   QualType T = Importer.Import(D->getType());
   if (T.isNull())
-    return 0;
+    return nullptr;
 
   NamedDecl **NamedChain =
     new (Importer.getToContext())NamedDecl*[D->getChainingSize()];
 
   unsigned i = 0;
-  for (IndirectFieldDecl::chain_iterator PI = D->chain_begin(),
-       PE = D->chain_end(); PI != PE; ++PI) {
-    Decl* D = Importer.Import(*PI);
+  for (auto *PI : D->chain()) {
+    Decl *D = Importer.Import(PI);
     if (!D)
-      return 0;
+      return nullptr;
     NamedChain[i++] = cast<NamedDecl>(D);
   }
 
@@ -2978,8 +2974,8 @@
   DeclarationName Name;
   SourceLocation Loc;
   if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
-    return 0;
-  
+    return nullptr;
+
   // Determine whether we've already imported this ivar 
   SmallVector<NamedDecl *, 2> FoundDecls;
   DC->localUncachedLookup(Name, FoundDecls);
@@ -2995,27 +2991,26 @@
         << Name << D->getType() << FoundIvar->getType();
       Importer.ToDiag(FoundIvar->getLocation(), diag::note_odr_value_here)
         << FoundIvar->getType();
-      return 0;
+      return nullptr;
     }
   }
 
   // Import the type.
   QualType T = Importer.Import(D->getType());
   if (T.isNull())
-    return 0;
-  
+    return nullptr;
+
   TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
   Expr *BitWidth = Importer.Import(D->getBitWidth());
   if (!BitWidth && D->getBitWidth())
-    return 0;
-  
+    return nullptr;
+
   ObjCIvarDecl *ToIvar = ObjCIvarDecl::Create(Importer.getToContext(),
                                               cast<ObjCContainerDecl>(DC),
                                        Importer.Import(D->getInnerLocStart()),
                                               Loc, Name.getAsIdentifierInfo(),
                                               T, TInfo, D->getAccessControl(),
-                                              BitWidth, D->getSynthesize(),
-                                              D->getBackingIvarReferencedInAccessor());
+                                              BitWidth, D->getSynthesize());
   ToIvar->setLexicalDeclContext(LexicalDC);
   Importer.Imported(D, ToIvar);
   LexicalDC->addDeclInternal(ToIvar);
@@ -3029,12 +3024,12 @@
   DeclarationName Name;
   SourceLocation Loc;
   if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
-    return 0;
-  
+    return nullptr;
+
   // Try to find a variable in our own ("to") context with the same name and
   // in the same context as the variable we're importing.
   if (D->isFileVarDecl()) {
-    VarDecl *MergeWithVar = 0;
+    VarDecl *MergeWithVar = nullptr;
     SmallVector<NamedDecl *, 4> ConflictingDecls;
     unsigned IDNS = Decl::IDNS_Ordinary;
     SmallVector<NamedDecl *, 2> FoundDecls;
@@ -3063,8 +3058,8 @@
               // Import the type.
               QualType T = Importer.Import(D->getType());
               if (T.isNull())
-                return 0;
-              
+                return nullptr;
+
               FoundVar->setType(T);
               MergeWithVar = FoundVar;
               break;
@@ -3115,15 +3110,15 @@
                                          ConflictingDecls.data(), 
                                          ConflictingDecls.size());
       if (!Name)
-        return 0;
+        return nullptr;
     }
   }
     
   // Import the type.
   QualType T = Importer.Import(D->getType());
   if (T.isNull())
-    return 0;
-  
+    return nullptr;
+
   // Create the imported variable.
   TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
   VarDecl *ToVar = VarDecl::Create(Importer.getToContext(), DC,
@@ -3139,7 +3134,7 @@
 
   // Merge the initializer.
   if (ImportDefinition(D, ToVar))
-    return 0;
+    return nullptr;
 
   return ToVar;
 }
@@ -3152,16 +3147,16 @@
   // Import the name of this declaration.
   DeclarationName Name = Importer.Import(D->getDeclName());
   if (D->getDeclName() && !Name)
-    return 0;
-  
+    return nullptr;
+
   // Import the location of this declaration.
   SourceLocation Loc = Importer.Import(D->getLocation());
   
   // Import the parameter's type.
   QualType T = Importer.Import(D->getType());
   if (T.isNull())
-    return 0;
-  
+    return nullptr;
+
   // Create the imported parameter.
   ImplicitParamDecl *ToParm
     = ImplicitParamDecl::Create(Importer.getToContext(), DC,
@@ -3178,23 +3173,23 @@
   // Import the name of this declaration.
   DeclarationName Name = Importer.Import(D->getDeclName());
   if (D->getDeclName() && !Name)
-    return 0;
-  
+    return nullptr;
+
   // Import the location of this declaration.
   SourceLocation Loc = Importer.Import(D->getLocation());
   
   // Import the parameter's type.
   QualType T = Importer.Import(D->getType());
   if (T.isNull())
-    return 0;
-  
+    return nullptr;
+
   // Create the imported parameter.
   TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
   ParmVarDecl *ToParm = ParmVarDecl::Create(Importer.getToContext(), DC,
                                      Importer.Import(D->getInnerLocStart()),
                                             Loc, Name.getAsIdentifierInfo(),
                                             T, TInfo, D->getStorageClass(),
-                                            /*FIXME: Default argument*/ 0);
+                                            /*FIXME: Default argument*/nullptr);
   ToParm->setHasInheritedDefaultArg(D->hasInheritedDefaultArg());
   return Importer.Imported(D, ToParm);
 }
@@ -3205,8 +3200,8 @@
   DeclarationName Name;
   SourceLocation Loc;
   if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
-    return 0;
-  
+    return nullptr;
+
   SmallVector<NamedDecl *, 2> FoundDecls;
   DC->localUncachedLookup(Name, FoundDecls);
   for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
@@ -3215,15 +3210,15 @@
         continue;
 
       // Check return types.
-      if (!Importer.IsStructurallyEquivalent(D->getResultType(),
-                                             FoundMethod->getResultType())) {
+      if (!Importer.IsStructurallyEquivalent(D->getReturnType(),
+                                             FoundMethod->getReturnType())) {
         Importer.ToDiag(Loc, diag::err_odr_objc_method_result_type_inconsistent)
-          << D->isInstanceMethod() << Name
-          << D->getResultType() << FoundMethod->getResultType();
+            << D->isInstanceMethod() << Name << D->getReturnType()
+            << FoundMethod->getReturnType();
         Importer.ToDiag(FoundMethod->getLocation(), 
                         diag::note_odr_objc_method_here)
           << D->isInstanceMethod() << Name;
-        return 0;
+        return nullptr;
       }
 
       // Check the number of parameters.
@@ -3234,7 +3229,7 @@
         Importer.ToDiag(FoundMethod->getLocation(), 
                         diag::note_odr_objc_method_here)
           << D->isInstanceMethod() << Name;
-        return 0;
+        return nullptr;
       }
 
       // Check parameter types.
@@ -3249,7 +3244,7 @@
             << (*P)->getType() << (*FoundP)->getType();
           Importer.ToDiag((*FoundP)->getLocation(), diag::note_odr_value_here)
             << (*FoundP)->getType();
-          return 0;
+          return nullptr;
         }
       }
 
@@ -3261,7 +3256,7 @@
         Importer.ToDiag(FoundMethod->getLocation(), 
                         diag::note_odr_objc_method_here)
           << D->isInstanceMethod() << Name;
-        return 0;
+        return nullptr;
       }
 
       // FIXME: Any other bits we need to merge?
@@ -3270,39 +3265,28 @@
   }
 
   // Import the result type.
-  QualType ResultTy = Importer.Import(D->getResultType());
+  QualType ResultTy = Importer.Import(D->getReturnType());
   if (ResultTy.isNull())
-    return 0;
+    return nullptr;
 
-  TypeSourceInfo *ResultTInfo = Importer.Import(D->getResultTypeSourceInfo());
+  TypeSourceInfo *ReturnTInfo = Importer.Import(D->getReturnTypeSourceInfo());
 
-  ObjCMethodDecl *ToMethod
-    = ObjCMethodDecl::Create(Importer.getToContext(),
-                             Loc,
-                             Importer.Import(D->getLocEnd()),
-                             Name.getObjCSelector(),
-                             ResultTy, ResultTInfo, DC,
-                             D->isInstanceMethod(),
-                             D->isVariadic(),
-                             D->isPropertyAccessor(),
-                             D->isImplicit(),
-                             D->isDefined(),
-                             D->getImplementationControl(),
-                             D->hasRelatedResultType());
+  ObjCMethodDecl *ToMethod = ObjCMethodDecl::Create(
+      Importer.getToContext(), Loc, Importer.Import(D->getLocEnd()),
+      Name.getObjCSelector(), ResultTy, ReturnTInfo, DC, D->isInstanceMethod(),
+      D->isVariadic(), D->isPropertyAccessor(), D->isImplicit(), D->isDefined(),
+      D->getImplementationControl(), D->hasRelatedResultType());
 
   // FIXME: When we decide to merge method definitions, we'll need to
   // deal with implicit parameters.
 
   // Import the parameters
   SmallVector<ParmVarDecl *, 5> ToParams;
-  for (ObjCMethodDecl::param_iterator FromP = D->param_begin(),
-                                   FromPEnd = D->param_end();
-       FromP != FromPEnd; 
-       ++FromP) {
-    ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(*FromP));
+  for (auto *FromP : D->params()) {
+    ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(FromP));
     if (!ToP)
-      return 0;
-    
+      return nullptr;
+
     ToParams.push_back(ToP);
   }
   
@@ -3327,13 +3311,13 @@
   DeclarationName Name;
   SourceLocation Loc;
   if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
-    return 0;
-  
+    return nullptr;
+
   ObjCInterfaceDecl *ToInterface
     = cast_or_null<ObjCInterfaceDecl>(Importer.Import(D->getClassInterface()));
   if (!ToInterface)
-    return 0;
-  
+    return nullptr;
+
   // Determine if we've already encountered this category.
   ObjCCategoryDecl *MergeWithCategory
     = ToInterface->FindCategoryDeclaration(Name.getAsIdentifierInfo());
@@ -3363,7 +3347,7 @@
       ObjCProtocolDecl *ToProto
         = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
       if (!ToProto)
-        return 0;
+        return nullptr;
       Protocols.push_back(ToProto);
       ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
     }
@@ -3385,8 +3369,8 @@
       = cast_or_null<ObjCCategoryImplDecl>(
                                        Importer.Import(D->getImplementation()));
     if (!Impl)
-      return 0;
-    
+      return nullptr;
+
     ToCategory->setImplementation(Impl);
   }
   
@@ -3441,8 +3425,8 @@
   if (Definition && Definition != D) {
     Decl *ImportedDef = Importer.Import(Definition);
     if (!ImportedDef)
-      return 0;
-    
+      return nullptr;
+
     return Importer.Imported(D, ImportedDef);
   }
 
@@ -3451,9 +3435,9 @@
   DeclarationName Name;
   SourceLocation Loc;
   if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
-    return 0;
+    return nullptr;
 
-  ObjCProtocolDecl *MergeWithProtocol = 0;
+  ObjCProtocolDecl *MergeWithProtocol = nullptr;
   SmallVector<NamedDecl *, 2> FoundDecls;
   DC->localUncachedLookup(Name, FoundDecls);
   for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
@@ -3469,7 +3453,7 @@
     ToProto = ObjCProtocolDecl::Create(Importer.getToContext(), DC,
                                        Name.getAsIdentifierInfo(), Loc,
                                        Importer.Import(D->getAtStartLoc()),
-                                       /*PrevDecl=*/0);
+                                       /*PrevDecl=*/nullptr);
     ToProto->setLexicalDeclContext(LexicalDC);
     LexicalDC->addDeclInternal(ToProto);
   }
@@ -3477,8 +3461,8 @@
   Importer.Imported(D, ToProto);
 
   if (D->isThisDeclarationADefinition() && ImportDefinition(D, ToProto))
-    return 0;
-  
+    return nullptr;
+
   return ToProto;
 }
 
@@ -3558,12 +3542,8 @@
   
   // Import categories. When the categories themselves are imported, they'll
   // hook themselves into this interface.
-  for (ObjCInterfaceDecl::known_categories_iterator
-         Cat = From->known_categories_begin(),
-         CatEnd = From->known_categories_end();
-       Cat != CatEnd; ++Cat) {
-    Importer.Import(*Cat);
-  }
+  for (auto *Cat : From->known_categories())
+    Importer.Import(Cat);
   
   // If we have an @implementation, import it as well.
   if (From->getImplementation()) {
@@ -3590,8 +3570,8 @@
   if (Definition && Definition != D) {
     Decl *ImportedDef = Importer.Import(Definition);
     if (!ImportedDef)
-      return 0;
-    
+      return nullptr;
+
     return Importer.Imported(D, ImportedDef);
   }
 
@@ -3600,10 +3580,10 @@
   DeclarationName Name;
   SourceLocation Loc;
   if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
-    return 0;
+    return nullptr;
 
   // Look for an existing interface with the same name.
-  ObjCInterfaceDecl *MergeWithIface = 0;
+  ObjCInterfaceDecl *MergeWithIface = nullptr;
   SmallVector<NamedDecl *, 2> FoundDecls;
   DC->localUncachedLookup(Name, FoundDecls);
   for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
@@ -3620,7 +3600,7 @@
     ToIface = ObjCInterfaceDecl::Create(Importer.getToContext(), DC,
                                         Importer.Import(D->getAtStartLoc()),
                                         Name.getAsIdentifierInfo(), 
-                                        /*PrevDecl=*/0,Loc,
+                                        /*PrevDecl=*/nullptr, Loc,
                                         D->isImplicitInterfaceDecl());
     ToIface->setLexicalDeclContext(LexicalDC);
     LexicalDC->addDeclInternal(ToIface);
@@ -3628,8 +3608,8 @@
   Importer.Imported(D, ToIface);
   
   if (D->isThisDeclarationADefinition() && ImportDefinition(D, ToIface))
-    return 0;
-    
+    return nullptr;
+
   return ToIface;
 }
 
@@ -3637,14 +3617,14 @@
   ObjCCategoryDecl *Category = cast_or_null<ObjCCategoryDecl>(
                                         Importer.Import(D->getCategoryDecl()));
   if (!Category)
-    return 0;
-  
+    return nullptr;
+
   ObjCCategoryImplDecl *ToImpl = Category->getImplementation();
   if (!ToImpl) {
     DeclContext *DC = Importer.ImportContext(D->getDeclContext());
     if (!DC)
-      return 0;
-    
+      return nullptr;
+
     SourceLocation CategoryNameLoc = Importer.Import(D->getCategoryNameLoc());
     ToImpl = ObjCCategoryImplDecl::Create(Importer.getToContext(), DC,
                                           Importer.Import(D->getIdentifier()),
@@ -3657,8 +3637,8 @@
     if (D->getDeclContext() != D->getLexicalDeclContext()) {
       LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
       if (!LexicalDC)
-        return 0;
-      
+        return nullptr;
+
       ToImpl->setLexicalDeclContext(LexicalDC);
     }
     
@@ -3676,15 +3656,15 @@
   ObjCInterfaceDecl *Iface = cast_or_null<ObjCInterfaceDecl>(
                                        Importer.Import(D->getClassInterface()));
   if (!Iface)
-    return 0;
+    return nullptr;
 
   // Import the superclass, if any.
-  ObjCInterfaceDecl *Super = 0;
+  ObjCInterfaceDecl *Super = nullptr;
   if (D->getSuperClass()) {
     Super = cast_or_null<ObjCInterfaceDecl>(
                                           Importer.Import(D->getSuperClass()));
     if (!Super)
-      return 0;
+      return nullptr;
   }
 
   ObjCImplementationDecl *Impl = Iface->getImplementation();
@@ -3704,7 +3684,7 @@
       DeclContext *LexicalDC
         = Importer.ImportContext(D->getLexicalDeclContext());
       if (!LexicalDC)
-        return 0;
+        return nullptr;
       Impl->setLexicalDeclContext(LexicalDC);
     }
     
@@ -3717,28 +3697,29 @@
     // Verify that the existing @implementation has the same superclass.
     if ((Super && !Impl->getSuperClass()) ||
         (!Super && Impl->getSuperClass()) ||
-        (Super && Impl->getSuperClass() && 
-         !declaresSameEntity(Super->getCanonicalDecl(), Impl->getSuperClass()))) {
-        Importer.ToDiag(Impl->getLocation(), 
-                        diag::err_odr_objc_superclass_inconsistent)
-          << Iface->getDeclName();
-        // FIXME: It would be nice to have the location of the superclass
-        // below.
-        if (Impl->getSuperClass())
-          Importer.ToDiag(Impl->getLocation(), 
+        (Super && Impl->getSuperClass() &&
+         !declaresSameEntity(Super->getCanonicalDecl(),
+                             Impl->getSuperClass()))) {
+      Importer.ToDiag(Impl->getLocation(),
+                      diag::err_odr_objc_superclass_inconsistent)
+        << Iface->getDeclName();
+      // FIXME: It would be nice to have the location of the superclass
+      // below.
+      if (Impl->getSuperClass())
+        Importer.ToDiag(Impl->getLocation(),
+                        diag::note_odr_objc_superclass)
+        << Impl->getSuperClass()->getDeclName();
+      else
+        Importer.ToDiag(Impl->getLocation(),
+                        diag::note_odr_objc_missing_superclass);
+      if (D->getSuperClass())
+        Importer.FromDiag(D->getLocation(),
                           diag::note_odr_objc_superclass)
-          << Impl->getSuperClass()->getDeclName();
-        else
-          Importer.ToDiag(Impl->getLocation(), 
+        << D->getSuperClass()->getDeclName();
+      else
+        Importer.FromDiag(D->getLocation(),
                           diag::note_odr_objc_missing_superclass);
-        if (D->getSuperClass())
-          Importer.FromDiag(D->getLocation(), 
-                            diag::note_odr_objc_superclass)
-          << D->getSuperClass()->getDeclName();
-        else
-          Importer.FromDiag(D->getLocation(), 
-                            diag::note_odr_objc_missing_superclass);
-      return 0;
+      return nullptr;
     }
   }
     
@@ -3754,7 +3735,7 @@
   DeclarationName Name;
   SourceLocation Loc;
   if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
-    return 0;
+    return nullptr;
 
   // Check whether we have already imported this property.
   SmallVector<NamedDecl *, 2> FoundDecls;
@@ -3769,7 +3750,7 @@
           << Name << D->getType() << FoundProp->getType();
         Importer.ToDiag(FoundProp->getLocation(), diag::note_odr_value_here)
           << FoundProp->getType();
-        return 0;
+        return nullptr;
       }
 
       // FIXME: Check property attributes, getters, setters, etc.?
@@ -3783,7 +3764,7 @@
   // Import the type.
   TypeSourceInfo *T = Importer.Import(D->getTypeSourceInfo());
   if (!T)
-    return 0;
+    return nullptr;
 
   // Create the new property.
   ObjCPropertyDecl *ToProperty
@@ -3815,31 +3796,31 @@
   ObjCPropertyDecl *Property = cast_or_null<ObjCPropertyDecl>(
                                         Importer.Import(D->getPropertyDecl()));
   if (!Property)
-    return 0;
+    return nullptr;
 
   DeclContext *DC = Importer.ImportContext(D->getDeclContext());
   if (!DC)
-    return 0;
-  
+    return nullptr;
+
   // Import the lexical declaration context.
   DeclContext *LexicalDC = DC;
   if (D->getDeclContext() != D->getLexicalDeclContext()) {
     LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
     if (!LexicalDC)
-      return 0;
+      return nullptr;
   }
 
   ObjCImplDecl *InImpl = dyn_cast<ObjCImplDecl>(LexicalDC);
   if (!InImpl)
-    return 0;
+    return nullptr;
 
   // Import the ivar (for an @synthesize).
-  ObjCIvarDecl *Ivar = 0;
+  ObjCIvarDecl *Ivar = nullptr;
   if (D->getPropertyIvarDecl()) {
     Ivar = cast_or_null<ObjCIvarDecl>(
                                     Importer.Import(D->getPropertyIvarDecl()));
     if (!Ivar)
-      return 0;
+      return nullptr;
   }
 
   ObjCPropertyImplDecl *ToImpl
@@ -3868,7 +3849,7 @@
                         diag::note_odr_objc_property_impl_kind)
         << D->getPropertyDecl()->getDeclName()
         << (D->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic);
-      return 0;
+      return nullptr;
     }
     
     // For @synthesize, check that we have the same 
@@ -3882,7 +3863,7 @@
       Importer.FromDiag(D->getPropertyIvarDeclLoc(), 
                         diag::note_odr_objc_synthesize_ivar_here)
         << D->getPropertyIvarDecl()->getDeclName();
-      return 0;
+      return nullptr;
     }
     
     // Merge the existing implementation with the new implementation.
@@ -3914,21 +3895,21 @@
   // Import the name of this declaration.
   DeclarationName Name = Importer.Import(D->getDeclName());
   if (D->getDeclName() && !Name)
-    return 0;
-  
+    return nullptr;
+
   // Import the location of this declaration.
   SourceLocation Loc = Importer.Import(D->getLocation());
 
   // Import the type of this declaration.
   QualType T = Importer.Import(D->getType());
   if (T.isNull())
-    return 0;
-  
+    return nullptr;
+
   // Import type-source information.
   TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
   if (D->getTypeSourceInfo() && !TInfo)
-    return 0;
-  
+    return nullptr;
+
   // FIXME: Import default argument.
   
   return NonTypeTemplateParmDecl::Create(Importer.getToContext(),
@@ -3944,8 +3925,8 @@
   // Import the name of this declaration.
   DeclarationName Name = Importer.Import(D->getDeclName());
   if (D->getDeclName() && !Name)
-    return 0;
-  
+    return nullptr;
+
   // Import the location of this declaration.
   SourceLocation Loc = Importer.Import(D->getLocation());
   
@@ -3953,8 +3934,8 @@
   TemplateParameterList *TemplateParams
     = ImportTemplateParameterList(D->getTemplateParameters());
   if (!TemplateParams)
-    return 0;
-  
+    return nullptr;
+
   // FIXME: Import default argument.
   
   return TemplateTemplateParmDecl::Create(Importer.getToContext(), 
@@ -3975,8 +3956,8 @@
     Decl *ImportedDef
       = Importer.Import(Definition->getDescribedClassTemplate());
     if (!ImportedDef)
-      return 0;
-    
+      return nullptr;
+
     return Importer.Imported(D, ImportedDef);
   }
   
@@ -3985,8 +3966,8 @@
   DeclarationName Name;
   SourceLocation Loc;
   if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
-    return 0;
-  
+    return nullptr;
+
   // We may already have a template of the same name; try to find and match it.
   if (!DC->isFunctionOrMethod()) {
     SmallVector<NamedDecl *, 4> ConflictingDecls;
@@ -4019,7 +4000,7 @@
     }
     
     if (!Name)
-      return 0;
+      return nullptr;
   }
 
   CXXRecordDecl *DTemplated = D->getTemplatedDecl();
@@ -4039,12 +4020,12 @@
   TemplateParameterList *TemplateParams
     = ImportTemplateParameterList(D->getTemplateParameters());
   if (!TemplateParams)
-    return 0;
-  
+    return nullptr;
+
   ClassTemplateDecl *D2 = ClassTemplateDecl::Create(Importer.getToContext(), DC, 
                                                     Loc, Name, TemplateParams, 
                                                     D2Templated, 
-  /*PrevDecl=*/0);
+                                                    /*PrevDecl=*/nullptr);
   D2Templated->setDescribedClassTemplate(D2);    
   
   D2->setAccess(D->getAccess());
@@ -4072,8 +4053,8 @@
   if (Definition && Definition != D) {
     Decl *ImportedDef = Importer.Import(Definition);
     if (!ImportedDef)
-      return 0;
-    
+      return nullptr;
+
     return Importer.Imported(D, ImportedDef);
   }
 
@@ -4081,18 +4062,18 @@
     = cast_or_null<ClassTemplateDecl>(Importer.Import(
                                                  D->getSpecializedTemplate()));
   if (!ClassTemplate)
-    return 0;
-  
+    return nullptr;
+
   // Import the context of this declaration.
   DeclContext *DC = ClassTemplate->getDeclContext();
   if (!DC)
-    return 0;
-  
+    return nullptr;
+
   DeclContext *LexicalDC = DC;
   if (D->getDeclContext() != D->getLexicalDeclContext()) {
     LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
     if (!LexicalDC)
-      return 0;
+      return nullptr;
   }
   
   // Import the location of this declaration.
@@ -4104,13 +4085,12 @@
   if (ImportTemplateArguments(D->getTemplateArgs().data(), 
                               D->getTemplateArgs().size(),
                               TemplateArgs))
-    return 0;
-  
+    return nullptr;
+
   // Try to find an existing specialization with these template arguments.
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
   ClassTemplateSpecializationDecl *D2
-    = ClassTemplate->findSpecialization(TemplateArgs.data(), 
-                                        TemplateArgs.size(), InsertPos);
+    = ClassTemplate->findSpecialization(TemplateArgs, InsertPos);
   if (D2) {
     // We already have a class template specialization with these template
     // arguments.
@@ -4133,7 +4113,7 @@
                                                  ClassTemplate,
                                                  TemplateArgs.data(), 
                                                  TemplateArgs.size(), 
-                                                 /*PrevDecl=*/0);
+                                                 /*PrevDecl=*/nullptr);
     D2->setSpecializationKind(D->getSpecializationKind());
 
     // Add this specialization to the class template.
@@ -4149,8 +4129,8 @@
   Importer.Imported(D, D2);
   
   if (D->isCompleteDefinition() && ImportDefinition(D, D2))
-    return 0;
-  
+    return nullptr;
+
   return D2;
 }
 
@@ -4164,7 +4144,7 @@
   if (Definition && Definition != D->getTemplatedDecl()) {
     Decl *ImportedDef = Importer.Import(Definition->getDescribedVarTemplate());
     if (!ImportedDef)
-      return 0;
+      return nullptr;
 
     return Importer.Imported(D, ImportedDef);
   }
@@ -4174,7 +4154,7 @@
   DeclarationName Name;
   SourceLocation Loc;
   if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
-    return 0;
+    return nullptr;
 
   // We may already have a template of the same name; try to find and match it.
   assert(!DC->isFunctionOrMethod() &&
@@ -4206,14 +4186,14 @@
   }
 
   if (!Name)
-    return 0;
+    return nullptr;
 
   VarDecl *DTemplated = D->getTemplatedDecl();
 
   // Import the type.
   QualType T = Importer.Import(DTemplated->getType());
   if (T.isNull())
-    return 0;
+    return nullptr;
 
   // Create the declaration that is being templated.
   SourceLocation StartLoc = Importer.Import(DTemplated->getLocStart());
@@ -4231,17 +4211,16 @@
 
   // Merge the initializer.
   if (ImportDefinition(DTemplated, D2Templated))
-    return 0;
+    return nullptr;
 
   // Create the variable template declaration itself.
   TemplateParameterList *TemplateParams =
       ImportTemplateParameterList(D->getTemplateParameters());
   if (!TemplateParams)
-    return 0;
+    return nullptr;
 
   VarTemplateDecl *D2 = VarTemplateDecl::Create(
-      Importer.getToContext(), DC, Loc, Name, TemplateParams, D2Templated,
-      /*PrevDecl=*/0);
+      Importer.getToContext(), DC, Loc, Name, TemplateParams, D2Templated);
   D2Templated->setDescribedVarTemplate(D2);
 
   D2->setAccess(D->getAccess());
@@ -4269,7 +4248,7 @@
   if (Definition && Definition != D) {
     Decl *ImportedDef = Importer.Import(Definition);
     if (!ImportedDef)
-      return 0;
+      return nullptr;
 
     return Importer.Imported(D, ImportedDef);
   }
@@ -4277,18 +4256,18 @@
   VarTemplateDecl *VarTemplate = cast_or_null<VarTemplateDecl>(
       Importer.Import(D->getSpecializedTemplate()));
   if (!VarTemplate)
-    return 0;
+    return nullptr;
 
   // Import the context of this declaration.
   DeclContext *DC = VarTemplate->getDeclContext();
   if (!DC)
-    return 0;
+    return nullptr;
 
   DeclContext *LexicalDC = DC;
   if (D->getDeclContext() != D->getLexicalDeclContext()) {
     LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
     if (!LexicalDC)
-      return 0;
+      return nullptr;
   }
 
   // Import the location of this declaration.
@@ -4299,12 +4278,12 @@
   SmallVector<TemplateArgument, 2> TemplateArgs;
   if (ImportTemplateArguments(D->getTemplateArgs().data(),
                               D->getTemplateArgs().size(), TemplateArgs))
-    return 0;
+    return nullptr;
 
   // Try to find an existing specialization with these template arguments.
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
   VarTemplateSpecializationDecl *D2 = VarTemplate->findSpecialization(
-      TemplateArgs.data(), TemplateArgs.size(), InsertPos);
+      TemplateArgs, InsertPos);
   if (D2) {
     // We already have a variable template specialization with these template
     // arguments.
@@ -4325,7 +4304,7 @@
     // Import the type.
     QualType T = Importer.Import(D->getType());
     if (T.isNull())
-      return 0;
+      return nullptr;
     TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
 
     // Create a new specialization.
@@ -4348,7 +4327,7 @@
   Importer.Imported(D, D2);
 
   if (D->isThisDeclarationADefinition() && ImportDefinition(D, D2))
-    return 0;
+    return nullptr;
 
   return D2;
 }
@@ -4360,7 +4339,7 @@
 Stmt *ASTNodeImporter::VisitStmt(Stmt *S) {
   Importer.FromDiag(S->getLocStart(), diag::err_unsupported_ast_node)
     << S->getStmtClassName();
-  return 0;
+  return nullptr;
 }
 
 //----------------------------------------------------------------------------
@@ -4369,24 +4348,24 @@
 Expr *ASTNodeImporter::VisitExpr(Expr *E) {
   Importer.FromDiag(E->getLocStart(), diag::err_unsupported_ast_node)
     << E->getStmtClassName();
-  return 0;
+  return nullptr;
 }
 
 Expr *ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) {
   ValueDecl *ToD = cast_or_null<ValueDecl>(Importer.Import(E->getDecl()));
   if (!ToD)
-    return 0;
+    return nullptr;
 
-  NamedDecl *FoundD = 0;
+  NamedDecl *FoundD = nullptr;
   if (E->getDecl() != E->getFoundDecl()) {
     FoundD = cast_or_null<NamedDecl>(Importer.Import(E->getFoundDecl()));
     if (!FoundD)
-      return 0;
+      return nullptr;
   }
   
   QualType T = Importer.Import(E->getType());
   if (T.isNull())
-    return 0;
+    return nullptr;
 
   DeclRefExpr *DRE = DeclRefExpr::Create(Importer.getToContext(), 
                                          Importer.Import(E->getQualifierLoc()),
@@ -4396,7 +4375,7 @@
                                          Importer.Import(E->getLocation()),
                                          T, E->getValueKind(),
                                          FoundD,
-                                         /*FIXME:TemplateArgs=*/0);
+                                         /*FIXME:TemplateArgs=*/nullptr);
   if (E->hadMultipleCandidates())
     DRE->setHadMultipleCandidates(true);
   return DRE;
@@ -4405,7 +4384,7 @@
 Expr *ASTNodeImporter::VisitIntegerLiteral(IntegerLiteral *E) {
   QualType T = Importer.Import(E->getType());
   if (T.isNull())
-    return 0;
+    return nullptr;
 
   return IntegerLiteral::Create(Importer.getToContext(), 
                                 E->getValue(), T,
@@ -4415,8 +4394,8 @@
 Expr *ASTNodeImporter::VisitCharacterLiteral(CharacterLiteral *E) {
   QualType T = Importer.Import(E->getType());
   if (T.isNull())
-    return 0;
-  
+    return nullptr;
+
   return new (Importer.getToContext()) CharacterLiteral(E->getValue(),
                                                         E->getKind(), T,
                                           Importer.Import(E->getLocation()));
@@ -4425,8 +4404,8 @@
 Expr *ASTNodeImporter::VisitParenExpr(ParenExpr *E) {
   Expr *SubExpr = Importer.Import(E->getSubExpr());
   if (!SubExpr)
-    return 0;
-  
+    return nullptr;
+
   return new (Importer.getToContext()) 
                                   ParenExpr(Importer.Import(E->getLParen()),
                                             Importer.Import(E->getRParen()),
@@ -4436,12 +4415,12 @@
 Expr *ASTNodeImporter::VisitUnaryOperator(UnaryOperator *E) {
   QualType T = Importer.Import(E->getType());
   if (T.isNull())
-    return 0;
+    return nullptr;
 
   Expr *SubExpr = Importer.Import(E->getSubExpr());
   if (!SubExpr)
-    return 0;
-  
+    return nullptr;
+
   return new (Importer.getToContext()) UnaryOperator(SubExpr, E->getOpcode(),
                                                      T, E->getValueKind(),
                                                      E->getObjectKind(),
@@ -4455,8 +4434,8 @@
   if (E->isArgumentType()) {
     TypeSourceInfo *TInfo = Importer.Import(E->getArgumentTypeInfo());
     if (!TInfo)
-      return 0;
-    
+      return nullptr;
+
     return new (Importer.getToContext()) UnaryExprOrTypeTraitExpr(E->getKind(),
                                            TInfo, ResultType,
                                            Importer.Import(E->getOperatorLoc()),
@@ -4465,8 +4444,8 @@
   
   Expr *SubExpr = Importer.Import(E->getArgumentExpr());
   if (!SubExpr)
-    return 0;
-  
+    return nullptr;
+
   return new (Importer.getToContext()) UnaryExprOrTypeTraitExpr(E->getKind(),
                                           SubExpr, ResultType,
                                           Importer.Import(E->getOperatorLoc()),
@@ -4476,16 +4455,16 @@
 Expr *ASTNodeImporter::VisitBinaryOperator(BinaryOperator *E) {
   QualType T = Importer.Import(E->getType());
   if (T.isNull())
-    return 0;
+    return nullptr;
 
   Expr *LHS = Importer.Import(E->getLHS());
   if (!LHS)
-    return 0;
-  
+    return nullptr;
+
   Expr *RHS = Importer.Import(E->getRHS());
   if (!RHS)
-    return 0;
-  
+    return nullptr;
+
   return new (Importer.getToContext()) BinaryOperator(LHS, RHS, E->getOpcode(),
                                                       T, E->getValueKind(),
                                                       E->getObjectKind(),
@@ -4496,24 +4475,24 @@
 Expr *ASTNodeImporter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
   QualType T = Importer.Import(E->getType());
   if (T.isNull())
-    return 0;
-  
+    return nullptr;
+
   QualType CompLHSType = Importer.Import(E->getComputationLHSType());
   if (CompLHSType.isNull())
-    return 0;
-  
+    return nullptr;
+
   QualType CompResultType = Importer.Import(E->getComputationResultType());
   if (CompResultType.isNull())
-    return 0;
-  
+    return nullptr;
+
   Expr *LHS = Importer.Import(E->getLHS());
   if (!LHS)
-    return 0;
-  
+    return nullptr;
+
   Expr *RHS = Importer.Import(E->getRHS());
   if (!RHS)
-    return 0;
-  
+    return nullptr;
+
   return new (Importer.getToContext()) 
                         CompoundAssignOperator(LHS, RHS, E->getOpcode(),
                                                T, E->getValueKind(),
@@ -4533,15 +4512,15 @@
 Expr *ASTNodeImporter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
   QualType T = Importer.Import(E->getType());
   if (T.isNull())
-    return 0;
+    return nullptr;
 
   Expr *SubExpr = Importer.Import(E->getSubExpr());
   if (!SubExpr)
-    return 0;
+    return nullptr;
 
   CXXCastPath BasePath;
   if (ImportCastPath(E, BasePath))
-    return 0;
+    return nullptr;
 
   return ImplicitCastExpr::Create(Importer.getToContext(), T, E->getCastKind(),
                                   SubExpr, &BasePath, E->getValueKind());
@@ -4550,19 +4529,19 @@
 Expr *ASTNodeImporter::VisitCStyleCastExpr(CStyleCastExpr *E) {
   QualType T = Importer.Import(E->getType());
   if (T.isNull())
-    return 0;
-  
+    return nullptr;
+
   Expr *SubExpr = Importer.Import(E->getSubExpr());
   if (!SubExpr)
-    return 0;
+    return nullptr;
 
   TypeSourceInfo *TInfo = Importer.Import(E->getTypeInfoAsWritten());
   if (!TInfo && E->getTypeInfoAsWritten())
-    return 0;
-  
+    return nullptr;
+
   CXXCastPath BasePath;
   if (ImportCastPath(E, BasePath))
-    return 0;
+    return nullptr;
 
   return CStyleCastExpr::Create(Importer.getToContext(), T,
                                 E->getValueKind(), E->getCastKind(),
@@ -4616,7 +4595,7 @@
   // on the type and a single location. Implement a real version of this.
   QualType T = Import(FromTSI->getType());
   if (T.isNull())
-    return 0;
+    return nullptr;
 
   return ToContext.getTrivialTypeSourceInfo(T, 
                         FromTSI->getTypeLoc().getLocStart());
@@ -4624,7 +4603,7 @@
 
 Decl *ASTImporter::Import(Decl *FromD) {
   if (!FromD)
-    return 0;
+    return nullptr;
 
   ASTNodeImporter Importer(*this);
 
@@ -4639,8 +4618,8 @@
   // Import the type
   Decl *ToD = Importer.Visit(FromD);
   if (!ToD)
-    return 0;
-  
+    return nullptr;
+
   // Record the imported declaration.
   ImportedDecls[FromD] = ToD;
   
@@ -4675,8 +4654,8 @@
 
   DeclContext *ToDC = cast_or_null<DeclContext>(Import(cast<Decl>(FromDC)));
   if (!ToDC)
-    return 0;
-  
+    return nullptr;
+
   // When we're using a record/enum/Objective-C class/protocol as a context, we 
   // need it to have a definition.
   if (RecordDecl *ToRecord = dyn_cast<RecordDecl>(ToDC)) {
@@ -4726,14 +4705,14 @@
 
 Expr *ASTImporter::Import(Expr *FromE) {
   if (!FromE)
-    return 0;
+    return nullptr;
 
   return cast_or_null<Expr>(Import(cast<Stmt>(FromE)));
 }
 
 Stmt *ASTImporter::Import(Stmt *FromS) {
   if (!FromS)
-    return 0;
+    return nullptr;
 
   // Check whether we've already imported this declaration.  
   llvm::DenseMap<Stmt *, Stmt *>::iterator Pos = ImportedStmts.find(FromS);
@@ -4744,8 +4723,8 @@
   ASTNodeImporter Importer(*this);
   Stmt *ToS = Importer.Visit(FromS);
   if (!ToS)
-    return 0;
-  
+    return nullptr;
+
   // Record the imported declaration.
   ImportedStmts[FromS] = ToS;
   return ToS;
@@ -4753,7 +4732,7 @@
 
 NestedNameSpecifier *ASTImporter::Import(NestedNameSpecifier *FromNNS) {
   if (!FromNNS)
-    return 0;
+    return nullptr;
 
   NestedNameSpecifier *prefix = Import(FromNNS->getPrefix());
 
@@ -4762,21 +4741,21 @@
     if (IdentifierInfo *II = Import(FromNNS->getAsIdentifier())) {
       return NestedNameSpecifier::Create(ToContext, prefix, II);
     }
-    return 0;
+    return nullptr;
 
   case NestedNameSpecifier::Namespace:
     if (NamespaceDecl *NS = 
           cast<NamespaceDecl>(Import(FromNNS->getAsNamespace()))) {
       return NestedNameSpecifier::Create(ToContext, prefix, NS);
     }
-    return 0;
+    return nullptr;
 
   case NestedNameSpecifier::NamespaceAlias:
     if (NamespaceAliasDecl *NSAD = 
           cast<NamespaceAliasDecl>(Import(FromNNS->getAsNamespaceAlias()))) {
       return NestedNameSpecifier::Create(ToContext, prefix, NSAD);
     }
-    return 0;
+    return nullptr;
 
   case NestedNameSpecifier::Global:
     return NestedNameSpecifier::GlobalSpecifier(ToContext);
@@ -4791,7 +4770,7 @@
                                            bTemplate, T.getTypePtr());
       }
     }
-    return 0;
+      return nullptr;
   }
 
   llvm_unreachable("Invalid nested name specifier kind");
@@ -4943,8 +4922,7 @@
     llvm::MemoryBuffer *ToBuf
       = llvm::MemoryBuffer::getMemBufferCopy(FromBuf->getBuffer(),
                                              FromBuf->getBufferIdentifier());
-    ToID = ToSM.createFileIDForMemBuffer(ToBuf,
-                                    FromSLoc.getFile().getFileCharacteristic());
+    ToID = ToSM.createFileID(ToBuf, FromSLoc.getFile().getFileCharacteristic());
   }
   
   
@@ -5054,7 +5032,7 @@
 
 IdentifierInfo *ASTImporter::Import(const IdentifierInfo *FromId) {
   if (!FromId)
-    return 0;
+    return nullptr;
 
   return &ToContext.Idents.get(FromId->getName());
 }
diff --git a/lib/AST/ASTTypeTraits.cpp b/lib/AST/ASTTypeTraits.cpp
index ae47ea9..baa8e48 100644
--- a/lib/AST/ASTTypeTraits.cpp
+++ b/lib/AST/ASTTypeTraits.cpp
@@ -39,18 +39,24 @@
 #include "clang/AST/TypeNodes.def"
 };
 
-bool ASTNodeKind::isBaseOf(ASTNodeKind Other) const {
-  return isBaseOf(KindId, Other.KindId);
+bool ASTNodeKind::isBaseOf(ASTNodeKind Other, unsigned *Distance) const {
+  return isBaseOf(KindId, Other.KindId, Distance);
 }
 
 bool ASTNodeKind::isSame(ASTNodeKind Other) const {
   return KindId != NKI_None && KindId == Other.KindId;
 }
 
-bool ASTNodeKind::isBaseOf(NodeKindId Base, NodeKindId Derived) {
+bool ASTNodeKind::isBaseOf(NodeKindId Base, NodeKindId Derived,
+                           unsigned *Distance) {
   if (Base == NKI_None || Derived == NKI_None) return false;
-  while (Derived != Base && Derived != NKI_None)
+  unsigned Dist = 0;
+  while (Derived != Base && Derived != NKI_None) {
     Derived = AllKindInfo[Derived].ParentId;
+    ++Dist;
+  }
+  if (Distance)
+    *Distance = Dist;
   return Derived == Base;
 }
 
@@ -71,7 +77,7 @@
   else if (const Decl *D = get<Decl>())
     D->print(OS, PP);
   else if (const Stmt *S = get<Stmt>())
-    S->printPretty(OS, 0, PP);
+    S->printPretty(OS, nullptr, PP);
   else if (const Type *T = get<Type>())
     QualType(T, 0).print(OS, PP);
   else
diff --git a/lib/AST/AttrImpl.cpp b/lib/AST/AttrImpl.cpp
index 7af3c8b..0bf6bcd 100644
--- a/lib/AST/AttrImpl.cpp
+++ b/lib/AST/AttrImpl.cpp
@@ -24,6 +24,4 @@
 
 void InheritableParamAttr::anchor() { }
 
-void MSInheritanceAttr::anchor() { }
-
 #include "clang/AST/AttrImpl.inc"
diff --git a/lib/AST/CMakeLists.txt b/lib/AST/CMakeLists.txt
index 461e8b3..9006be6 100644
--- a/lib/AST/CMakeLists.txt
+++ b/lib/AST/CMakeLists.txt
@@ -57,29 +57,8 @@
   TypePrinter.cpp
   VTableBuilder.cpp
   VTTBuilder.cpp
-  )
 
-add_dependencies(clangAST
-  ClangARMNeon
-  ClangAttrClasses
-  ClangAttrList
-  ClangAttrImpl
-  ClangAttrDump
-  ClangCommentCommandInfo
-  ClangCommentCommandList
-  ClangCommentNodes
-  ClangCommentHTMLTags
-  ClangCommentHTMLTagsProperties
-  ClangCommentHTMLNamedCharacterReferences
-  ClangDeclNodes
-  ClangDiagnosticAST
-  ClangDiagnosticComment
-  ClangDiagnosticCommon
-  ClangDiagnosticSema
-  ClangStmtNodes
-  )
-
-target_link_libraries(clangAST
+  LINK_LIBS
   clangBasic
   clangLex
   )
diff --git a/lib/AST/CXXABI.h b/lib/AST/CXXABI.h
index 89203f1..12b929b 100644
--- a/lib/AST/CXXABI.h
+++ b/lib/AST/CXXABI.h
@@ -44,7 +44,6 @@
 };
 
 /// Creates an instance of a C++ ABI class.
-CXXABI *CreateARMCXXABI(ASTContext &Ctx);
 CXXABI *CreateItaniumCXXABI(ASTContext &Ctx);
 CXXABI *CreateMicrosoftCXXABI(ASTContext &Ctx);
 }
diff --git a/lib/AST/CXXInheritance.cpp b/lib/AST/CXXInheritance.cpp
index b51014b..6e80ee7 100644
--- a/lib/AST/CXXInheritance.cpp
+++ b/lib/AST/CXXInheritance.cpp
@@ -35,16 +35,12 @@
   std::copy(Decls.begin(), Decls.end(), DeclsFound);
 }
 
-CXXBasePaths::decl_iterator CXXBasePaths::found_decls_begin() {
+CXXBasePaths::decl_range CXXBasePaths::found_decls() {
   if (NumDeclsFound == 0)
     ComputeDeclsFound();
-  return DeclsFound;
-}
 
-CXXBasePaths::decl_iterator CXXBasePaths::found_decls_end() {
-  if (NumDeclsFound == 0)
-    ComputeDeclsFound();
-  return DeclsFound + NumDeclsFound;
+  return decl_range(decl_iterator(DeclsFound),
+                    decl_iterator(DeclsFound + NumDeclsFound));
 }
 
 /// isAmbiguous - Determines whether the set of paths provided is
@@ -62,7 +58,7 @@
   Paths.clear();
   ClassSubobjects.clear();
   ScratchPath.clear();
-  DetectedVirtual = 0;
+  DetectedVirtual = nullptr;
 }
 
 /// @brief Swaps the contents of this CXXBasePaths structure with the
@@ -141,9 +137,8 @@
   const CXXRecordDecl *Record = this;
   bool AllMatches = true;
   while (true) {
-    for (CXXRecordDecl::base_class_const_iterator
-           I = Record->bases_begin(), E = Record->bases_end(); I != E; ++I) {
-      const RecordType *Ty = I->getType()->getAs<RecordType>();
+    for (const auto &I : Record->bases()) {
+      const RecordType *Ty = I.getType()->getAs<RecordType>();
       if (!Ty) {
         if (AllowShortCircuit) return false;
         AllMatches = false;
@@ -186,14 +181,11 @@
   AccessSpecifier AccessToHere = ScratchPath.Access;
   bool IsFirstStep = ScratchPath.empty();
 
-  for (CXXRecordDecl::base_class_const_iterator BaseSpec = Record->bases_begin(),
-         BaseSpecEnd = Record->bases_end(); 
-       BaseSpec != BaseSpecEnd; 
-       ++BaseSpec) {
+  for (const auto &BaseSpec : Record->bases()) {
     // Find the record of the base class subobjects for this type.
-    QualType BaseType = Context.getCanonicalType(BaseSpec->getType())
-                                                          .getUnqualifiedType();
-    
+    QualType BaseType =
+        Context.getCanonicalType(BaseSpec.getType()).getUnqualifiedType();
+
     // C++ [temp.dep]p3:
     //   In the definition of a class template or a member of a class template,
     //   if a base class of the class template depends on a template-parameter,
@@ -208,10 +200,10 @@
     std::pair<bool, unsigned>& Subobjects = ClassSubobjects[BaseType];
     bool VisitBase = true;
     bool SetVirtual = false;
-    if (BaseSpec->isVirtual()) {
+    if (BaseSpec.isVirtual()) {
       VisitBase = !Subobjects.first;
       Subobjects.first = true;
-      if (isDetectingVirtual() && DetectedVirtual == 0) {
+      if (isDetectingVirtual() && DetectedVirtual == nullptr) {
         // If this is the first virtual we find, remember it. If it turns out
         // there is no base path here, we'll reset it later.
         DetectedVirtual = BaseType->getAs<RecordType>();
@@ -223,9 +215,9 @@
     if (isRecordingPaths()) {
       // Add this base specifier to the current path.
       CXXBasePathElement Element;
-      Element.Base = &*BaseSpec;
+      Element.Base = &BaseSpec;
       Element.Class = Record;
-      if (BaseSpec->isVirtual())
+      if (BaseSpec.isVirtual())
         Element.SubobjectNumber = 0;
       else
         Element.SubobjectNumber = Subobjects.second;
@@ -247,16 +239,16 @@
       // 3. Otherwise, overall access is determined by the most restrictive
       //    access in the sequence.
       if (IsFirstStep)
-        ScratchPath.Access = BaseSpec->getAccessSpecifier();
+        ScratchPath.Access = BaseSpec.getAccessSpecifier();
       else
         ScratchPath.Access = CXXRecordDecl::MergeAccess(AccessToHere, 
-                                                 BaseSpec->getAccessSpecifier());
+                                                 BaseSpec.getAccessSpecifier());
     }
     
     // Track whether there's a path involving this specific base.
     bool FoundPathThroughBase = false;
     
-    if (BaseMatches(BaseSpec, ScratchPath, UserData)) {
+    if (BaseMatches(&BaseSpec, ScratchPath, UserData)) {
       // We've found a path that terminates at this base.
       FoundPath = FoundPathThroughBase = true;
       if (isRecordingPaths()) {
@@ -269,7 +261,7 @@
       }
     } else if (VisitBase) {
       CXXRecordDecl *BaseRecord
-        = cast<CXXRecordDecl>(BaseSpec->getType()->castAs<RecordType>()
+        = cast<CXXRecordDecl>(BaseSpec.getType()->castAs<RecordType>()
                                 ->getDecl());
       if (lookupInBases(Context, BaseRecord, BaseMatches, UserData)) {
         // C++ [class.member.lookup]p2:
@@ -294,7 +286,7 @@
 
     // If we set a virtual earlier, and this isn't a path, forget it again.
     if (SetVirtual && !FoundPathThroughBase) {
-      DetectedVirtual = 0;
+      DetectedVirtual = nullptr;
     }
   }
 
@@ -333,7 +325,7 @@
     for (CXXBasePath::iterator PE = P->begin(), PEEnd = P->end();
          PE != PEEnd && !Hidden; ++PE) {
       if (PE->Base->isVirtual()) {
-        CXXRecordDecl *VBase = 0;
+        CXXRecordDecl *VBase = nullptr;
         if (const RecordType *Record = PE->Base->getType()->getAs<RecordType>())
           VBase = cast<CXXRecordDecl>(Record->getDecl());
         if (!VBase)
@@ -347,7 +339,7 @@
                                        HidingPEnd = Paths.end();
              HidingP != HidingPEnd;
              ++HidingP) {
-          CXXRecordDecl *HidingClass = 0;
+          CXXRecordDecl *HidingClass = nullptr;
           if (const RecordType *Record
                        = HidingP->back().Base->getType()->getAs<RecordType>())
             HidingClass = cast<CXXRecordDecl>(Record->getDecl());
@@ -501,14 +493,13 @@
     SubobjectNumber
       = ++SubobjectCount[cast<CXXRecordDecl>(RD->getCanonicalDecl())];
 
-  for (CXXRecordDecl::base_class_const_iterator Base = RD->bases_begin(),
-         BaseEnd = RD->bases_end(); Base != BaseEnd; ++Base) {
-    if (const RecordType *RT = Base->getType()->getAs<RecordType>()) {
+  for (const auto &Base : RD->bases()) {
+    if (const RecordType *RT = Base.getType()->getAs<RecordType>()) {
       const CXXRecordDecl *BaseDecl = cast<CXXRecordDecl>(RT->getDecl());
       if (!BaseDecl->isPolymorphic())
         continue;
 
-      if (Overriders.empty() && !Base->isVirtual()) {
+      if (Overriders.empty() && !Base.isVirtual()) {
         // There are no other overriders of virtual member functions,
         // so let the base class fill in our overriders for us.
         Collect(BaseDecl, false, InVirtualSubobject, Overriders);
@@ -522,7 +513,7 @@
       // its base classes) more than once.
       CXXFinalOverriderMap ComputedBaseOverriders;
       CXXFinalOverriderMap *BaseOverriders = &ComputedBaseOverriders;
-      if (Base->isVirtual()) {
+      if (Base.isVirtual()) {
         CXXFinalOverriderMap *&MyVirtualOverriders = VirtualOverriders[BaseDecl];
         BaseOverriders = MyVirtualOverriders;
         if (!MyVirtualOverriders) {
@@ -551,10 +542,7 @@
     }
   }
 
-  for (CXXRecordDecl::method_iterator M = RD->method_begin(), 
-                                   MEnd = RD->method_end();
-       M != MEnd;
-       ++M) {
+  for (auto *M : RD->methods()) {
     // We only care about virtual methods.
     if (!M->isVirtual())
       continue;
@@ -637,7 +625,7 @@
 void 
 CXXRecordDecl::getFinalOverriders(CXXFinalOverriderMap &FinalOverriders) const {
   FinalOverriderCollector Collector;
-  Collector.Collect(this, false, 0, FinalOverriders);
+  Collector.Collect(this, false, nullptr, FinalOverriders);
 
   // Weed out any final overriders that come from virtual base class
   // subobjects that were hidden by other subobjects along any path.
@@ -702,13 +690,12 @@
   if (Layout.isPrimaryBaseVirtual())
     Bases.insert(Layout.getPrimaryBase());
 
-  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
-       E = RD->bases_end(); I != E; ++I) {
-    assert(!I->getType()->isDependentType() &&
+  for (const auto &I : RD->bases()) {
+    assert(!I.getType()->isDependentType() &&
            "Cannot get indirect primary bases for class with dependent bases.");
 
     const CXXRecordDecl *BaseDecl =
-      cast<CXXRecordDecl>(I->getType()->castAs<RecordType>()->getDecl());
+      cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
 
     // Only bases with virtual bases participate in computing the
     // indirect primary virtual base classes.
@@ -725,13 +712,12 @@
   if (!getNumVBases())
     return;
 
-  for (CXXRecordDecl::base_class_const_iterator I = bases_begin(),
-       E = bases_end(); I != E; ++I) {
-    assert(!I->getType()->isDependentType() &&
+  for (const auto &I : bases()) {
+    assert(!I.getType()->isDependentType() &&
            "Cannot get indirect primary bases for class with dependent bases.");
 
     const CXXRecordDecl *BaseDecl =
-      cast<CXXRecordDecl>(I->getType()->castAs<RecordType>()->getDecl());
+      cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
 
     // Only bases with virtual bases participate in computing the
     // indirect primary virtual base classes.
diff --git a/lib/AST/Comment.cpp b/lib/AST/Comment.cpp
index f24a23d..4f43346 100644
--- a/lib/AST/Comment.cpp
+++ b/lib/AST/Comment.cpp
@@ -136,7 +136,7 @@
   IsInstanceMethod = false;
   IsClassMethod = false;
   ParamVars = None;
-  TemplateParameters = NULL;
+  TemplateParameters = nullptr;
 
   if (!CommentDecl) {
     // If there is no declaration, the defaults is our only guess.
@@ -159,7 +159,7 @@
     Kind = FunctionKind;
     ParamVars = ArrayRef<const ParmVarDecl *>(FD->param_begin(),
                                               FD->getNumParams());
-    ResultType = FD->getResultType();
+    ReturnType = FD->getReturnType();
     unsigned NumLists = FD->getNumTemplateParameterLists();
     if (NumLists != 0) {
       TemplateKind = TemplateSpecialization;
@@ -180,7 +180,7 @@
     Kind = FunctionKind;
     ParamVars = ArrayRef<const ParmVarDecl *>(MD->param_begin(),
                                               MD->param_size());
-    ResultType = MD->getResultType();
+    ReturnType = MD->getReturnType();
     IsObjCMethod = true;
     IsInstanceMethod = MD->isInstanceMethod();
     IsClassMethod = !IsInstanceMethod;
@@ -193,7 +193,7 @@
     const FunctionDecl *FD = FTD->getTemplatedDecl();
     ParamVars = ArrayRef<const ParmVarDecl *>(FD->param_begin(),
                                               FD->getNumParams());
-    ResultType = FD->getResultType();
+    ReturnType = FD->getReturnType();
     TemplateParameters = FTD->getTemplateParameters();
     break;
   }
@@ -251,6 +251,16 @@
         TL = PointerTL.getPointeeLoc().getUnqualifiedLoc();
         continue;
       }
+      // Look through reference types.
+      if (ReferenceTypeLoc ReferenceTL = TL.getAs<ReferenceTypeLoc>()) {
+        TL = ReferenceTL.getPointeeLoc().getUnqualifiedLoc();
+        continue;
+      }
+      // Look through adjusted types.
+      if (AdjustedTypeLoc ATL = TL.getAs<AdjustedTypeLoc>()) {
+        TL = ATL.getOriginalLoc();
+        continue;
+      }
       if (BlockPointerTypeLoc BlockPointerTL =
               TL.getAs<BlockPointerTypeLoc>()) {
         TL = BlockPointerTL.getPointeeLoc().getUnqualifiedLoc();
@@ -261,13 +271,39 @@
         TL = MemberPointerTL.getPointeeLoc().getUnqualifiedLoc();
         continue;
       }
+      if (ElaboratedTypeLoc ETL = TL.getAs<ElaboratedTypeLoc>()) {
+        TL = ETL.getNamedTypeLoc();
+        continue;
+      }
       // Is this a typedef for a function type?
       if (FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>()) {
         Kind = FunctionKind;
         ArrayRef<ParmVarDecl *> Params = FTL.getParams();
         ParamVars = ArrayRef<const ParmVarDecl *>(Params.data(),
                                                   Params.size());
-        ResultType = FTL.getResultLoc().getType();
+        ReturnType = FTL.getReturnLoc().getType();
+        break;
+      }
+      if (TemplateSpecializationTypeLoc STL =
+              TL.getAs<TemplateSpecializationTypeLoc>()) {
+        // If we have a typedef to a template specialization with exactly one
+        // template argument of a function type, this looks like std::function,
+        // boost::function, or other function wrapper.  Treat these typedefs as
+        // functions.
+        if (STL.getNumArgs() != 1)
+          break;
+        TemplateArgumentLoc MaybeFunction = STL.getArgLoc(0);
+        if (MaybeFunction.getArgument().getKind() != TemplateArgument::Type)
+          break;
+        TypeSourceInfo *MaybeFunctionTSI = MaybeFunction.getTypeSourceInfo();
+        TypeLoc TL = MaybeFunctionTSI->getTypeLoc().getUnqualifiedLoc();
+        if (FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>()) {
+          Kind = FunctionKind;
+          ArrayRef<ParmVarDecl *> Params = FTL.getParams();
+          ParamVars = ArrayRef<const ParmVarDecl *>(Params.data(),
+                                                    Params.size());
+          ReturnType = FTL.getReturnLoc().getType();
+        }
         break;
       }
       break;
diff --git a/lib/AST/CommentCommandTraits.cpp b/lib/AST/CommentCommandTraits.cpp
index 01bd12e..a7b07a4 100644
--- a/lib/AST/CommentCommandTraits.cpp
+++ b/lib/AST/CommentCommandTraits.cpp
@@ -43,47 +43,42 @@
   return getRegisteredCommandInfo(CommandID);
 }
 
-static void
-HelperTypoCorrectCommandInfo(SmallVectorImpl<const CommandInfo *> &BestCommand,
-                             StringRef Typo, const CommandInfo *Command) {
-  const unsigned MaxEditDistance = 1;
-  unsigned BestEditDistance = MaxEditDistance + 1;
-  StringRef Name = Command->Name;
-  
-  unsigned MinPossibleEditDistance = abs((int)Name.size() - (int)Typo.size());
-  if (MinPossibleEditDistance > 0 &&
-      Typo.size() / MinPossibleEditDistance < 1)
-    return;
-  unsigned EditDistance = Typo.edit_distance(Name, true, MaxEditDistance);
-  if (EditDistance > MaxEditDistance)
-    return;
-  if (EditDistance == BestEditDistance)
-    BestCommand.push_back(Command);
-  else if (EditDistance < BestEditDistance) {
-    BestCommand.clear();
-    BestCommand.push_back(Command);
-    BestEditDistance = EditDistance;
-  }
-}
-
 const CommandInfo *
 CommandTraits::getTypoCorrectCommandInfo(StringRef Typo) const {
-  // single character command impostures, such as \t or \n must not go
+  // Single-character command impostures, such as \t or \n, should not go
   // through the fixit logic.
   if (Typo.size() <= 1)
-    return NULL;
-  
+    return nullptr;
+
+  // The maximum edit distance we're prepared to accept.
+  const unsigned MaxEditDistance = 1;
+
+  unsigned BestEditDistance = MaxEditDistance;
   SmallVector<const CommandInfo *, 2> BestCommand;
-  
-  const int NumOfCommands = llvm::array_lengthof(Commands);
-  for (int i = 0; i < NumOfCommands; i++)
-    HelperTypoCorrectCommandInfo(BestCommand, Typo, &Commands[i]);
-  
-  for (unsigned i = 0, e = RegisteredCommands.size(); i != e; ++i)
-    if (!RegisteredCommands[i]->IsUnknownCommand)
-      HelperTypoCorrectCommandInfo(BestCommand, Typo, RegisteredCommands[i]);
-  
-  return (BestCommand.size() != 1) ? NULL : BestCommand[0];
+
+  auto ConsiderCorrection = [&](const CommandInfo *Command) {
+    StringRef Name = Command->Name;
+
+    unsigned MinPossibleEditDistance = abs((int)Name.size() - (int)Typo.size());
+    if (MinPossibleEditDistance <= BestEditDistance) {
+      unsigned EditDistance = Typo.edit_distance(Name, true, BestEditDistance);
+      if (EditDistance < BestEditDistance) {
+        BestEditDistance = EditDistance;
+        BestCommand.clear();
+      }
+      if (EditDistance == BestEditDistance)
+        BestCommand.push_back(Command);
+    }
+  };
+
+  for (const auto &Command : Commands)
+    ConsiderCorrection(&Command);
+
+  for (const auto *Command : RegisteredCommands)
+    if (!Command->IsUnknownCommand)
+      ConsiderCorrection(Command);
+
+  return BestCommand.size() == 1 ? BestCommand[0] : nullptr;
 }
 
 CommandInfo *CommandTraits::createCommandInfoWithName(StringRef CommandName) {
@@ -118,7 +113,7 @@
                                                   unsigned CommandID) {
   if (CommandID < llvm::array_lengthof(Commands))
     return &Commands[CommandID];
-  return NULL;
+  return nullptr;
 }
 
 const CommandInfo *CommandTraits::getRegisteredCommandInfo(
@@ -127,7 +122,7 @@
     if (RegisteredCommands[i]->Name == Name)
       return RegisteredCommands[i];
   }
-  return NULL;
+  return nullptr;
 }
 
 const CommandInfo *CommandTraits::getRegisteredCommandInfo(
diff --git a/lib/AST/CommentLexer.cpp b/lib/AST/CommentLexer.cpp
index 475532d..792a832 100644
--- a/lib/AST/CommentLexer.cpp
+++ b/lib/AST/CommentLexer.cpp
@@ -268,6 +268,19 @@
     
 } // unnamed namespace
 
+void Lexer::formTokenWithChars(Token &Result, const char *TokEnd,
+                               tok::TokenKind Kind) {
+  const unsigned TokLen = TokEnd - BufferPtr;
+  Result.setLocation(getSourceLocation(BufferPtr));
+  Result.setKind(Kind);
+  Result.setLength(TokLen);
+#ifndef NDEBUG
+  Result.TextPtr = "<UNSET>";
+  Result.IntVal = 7;
+#endif
+  BufferPtr = TokEnd;
+}
+
 void Lexer::lexCommentText(Token &T) {
   assert(CommentState == LCS_InsideBCPLComment ||
          CommentState == LCS_InsideCComment);
@@ -353,16 +366,17 @@
 
         const CommandInfo *Info = Traits.getCommandInfoOrNULL(CommandName);
         if (!Info) {
-          formTokenWithChars(T, TokenPtr, tok::unknown_command);
-          T.setUnknownCommandName(CommandName);
           if ((Info = Traits.getTypoCorrectCommandInfo(CommandName))) {
             StringRef CorrectedName = Info->Name;
-            SourceRange CommandRange(T.getLocation().getLocWithOffset(1),
-                                     T.getEndLocation());
-            Diag(T.getLocation(), diag::warn_correct_comment_command_name)
+            SourceLocation Loc = getSourceLocation(BufferPtr);
+            SourceRange CommandRange(Loc.getLocWithOffset(1),
+                                     getSourceLocation(TokenPtr));
+            Diag(Loc, diag::warn_correct_comment_command_name)
               << CommandName << CorrectedName
               << FixItHint::CreateReplacement(CommandRange, CorrectedName);
           } else {
+            formTokenWithChars(T, TokenPtr, tok::unknown_command);
+            T.setUnknownCommandName(CommandName);
             Diag(T.getLocation(), diag::warn_unknown_comment_command_name);
             return;
           }
diff --git a/lib/AST/CommentParser.cpp b/lib/AST/CommentParser.cpp
index 03e0101..cb37ec3 100644
--- a/lib/AST/CommentParser.cpp
+++ b/lib/AST/CommentParser.cpp
@@ -311,9 +311,9 @@
 BlockCommandComment *Parser::parseBlockCommand() {
   assert(Tok.is(tok::backslash_command) || Tok.is(tok::at_command));
 
-  ParamCommandComment *PC = 0;
-  TParamCommandComment *TPC = 0;
-  BlockCommandComment *BC = 0;
+  ParamCommandComment *PC = nullptr;
+  TParamCommandComment *TPC = nullptr;
+  BlockCommandComment *BC = nullptr;
   const CommandInfo *Info = Traits.getCommandInfo(Tok.getCommandID());
   CommandMarkerKind CommandMarker =
       Tok.is(tok::backslash_command) ? CMK_Backslash : CMK_At;
diff --git a/lib/AST/CommentSema.cpp b/lib/AST/CommentSema.cpp
index 1c6222f..12823c3 100644
--- a/lib/AST/CommentSema.cpp
+++ b/lib/AST/CommentSema.cpp
@@ -29,7 +29,8 @@
            DiagnosticsEngine &Diags, CommandTraits &Traits,
            const Preprocessor *PP) :
     Allocator(Allocator), SourceMgr(SourceMgr), Diags(Diags), Traits(Traits),
-    PP(PP), ThisDeclInfo(NULL), BriefCommand(NULL), HeaderfileCommand(NULL) {
+    PP(PP), ThisDeclInfo(nullptr), BriefCommand(nullptr),
+    HeaderfileCommand(nullptr) {
 }
 
 void Sema::setDecl(const Decl *D) {
@@ -68,8 +69,12 @@
   Command->setParagraph(Paragraph);
   checkBlockCommandEmptyParagraph(Command);
   checkBlockCommandDuplicate(Command);
-  checkReturnsCommand(Command);
-  checkDeprecatedCommand(Command);
+  if (ThisDeclInfo) {
+    // These checks only make sense if the comment is attached to a
+    // declaration.
+    checkReturnsCommand(Command);
+    checkDeprecatedCommand(Command);
+  }
 }
 
 ParamCommandComment *Sema::actOnParamCommandStart(
@@ -122,7 +127,7 @@
     << (DiagSelect-1) << (DiagSelect-1)
     << Comment->getSourceRange();
 }
-  
+
 void Sema::checkContainerDeclVerbatimLine(const BlockCommandComment *Comment) {
   const CommandInfo *Info = Traits.getCommandInfo(Comment->getCommandID());
   if (!Info->IsRecordLikeDeclarationCommand)
@@ -478,6 +483,7 @@
   if (isHTMLEndTagForbidden(TagName)) {
     Diag(HET->getLocation(), diag::warn_doc_html_end_forbidden)
       << TagName << HET->getSourceRange();
+    HET->setIsMalformed();
     return HET;
   }
 
@@ -493,14 +499,19 @@
   if (!FoundOpen) {
     Diag(HET->getLocation(), diag::warn_doc_html_end_unbalanced)
       << HET->getSourceRange();
+    HET->setIsMalformed();
     return HET;
   }
 
   while (!HTMLOpenTags.empty()) {
-    const HTMLStartTagComment *HST = HTMLOpenTags.pop_back_val();
+    HTMLStartTagComment *HST = HTMLOpenTags.pop_back_val();
     StringRef LastNotClosedTagName = HST->getTagName();
-    if (LastNotClosedTagName == TagName)
+    if (LastNotClosedTagName == TagName) {
+      // If the start tag is malformed, end tag is malformed as well.
+      if (HST->isMalformed())
+        HET->setIsMalformed();
       break;
+    }
 
     if (isHTMLEndTagOptional(LastNotClosedTagName))
       continue;
@@ -514,16 +525,18 @@
                                                 HET->getLocation(),
                                                 &CloseLineInvalid);
 
-    if (OpenLineInvalid || CloseLineInvalid || OpenLine == CloseLine)
+    if (OpenLineInvalid || CloseLineInvalid || OpenLine == CloseLine) {
       Diag(HST->getLocation(), diag::warn_doc_html_start_end_mismatch)
         << HST->getTagName() << HET->getTagName()
         << HST->getSourceRange() << HET->getSourceRange();
-    else {
+      HST->setIsMalformed();
+    } else {
       Diag(HST->getLocation(), diag::warn_doc_html_start_end_mismatch)
         << HST->getTagName() << HET->getTagName()
         << HST->getSourceRange();
       Diag(HET->getLocation(), diag::note_doc_html_end_tag)
         << HET->getSourceRange();
+      HST->setIsMalformed();
     }
   }
 
@@ -534,6 +547,18 @@
                               ArrayRef<BlockContentComment *> Blocks) {
   FullComment *FC = new (Allocator) FullComment(Blocks, ThisDeclInfo);
   resolveParamCommandIndexes(FC);
+
+  // Complain about HTML tags that are not closed.
+  while (!HTMLOpenTags.empty()) {
+    HTMLStartTagComment *HST = HTMLOpenTags.pop_back_val();
+    if (isHTMLEndTagOptional(HST->getTagName()))
+      continue;
+
+    Diag(HST->getLocation(), diag::warn_doc_html_missing_end_tag)
+      << HST->getTagName() << HST->getSourceRange();
+    HST->setIsMalformed();
+  }
+
   return FC;
 }
 
@@ -558,8 +583,11 @@
 void Sema::checkReturnsCommand(const BlockCommandComment *Command) {
   if (!Traits.getCommandInfo(Command->getCommandID())->IsReturnsCommand)
     return;
+
+  assert(ThisDeclInfo && "should not call this check on a bare comment");
+
   if (isFunctionDecl()) {
-    if (ThisDeclInfo->ResultType->isVoidType()) {
+    if (ThisDeclInfo->ReturnType->isVoidType()) {
       unsigned DiagKind;
       switch (ThisDeclInfo->CommentDecl->getKind()) {
       default:
@@ -586,7 +614,7 @@
   }
   else if (isObjCPropertyDecl())
     return;
-  
+
   Diag(Command->getLocation(),
        diag::warn_doc_returns_not_attached_to_a_function_decl)
     << Command->getCommandMarker()
@@ -596,7 +624,7 @@
 
 void Sema::checkBlockCommandDuplicate(const BlockCommandComment *Command) {
   const CommandInfo *Info = Traits.getCommandInfo(Command->getCommandID());
-  const BlockCommandComment *PrevCommand = NULL;
+  const BlockCommandComment *PrevCommand = nullptr;
   if (Info->IsBriefCommand) {
     if (!BriefCommand) {
       BriefCommand = Command;
@@ -636,6 +664,8 @@
   if (!Traits.getCommandInfo(Command->getCommandID())->IsDeprecatedCommand)
     return;
 
+  assert(ThisDeclInfo && "should not call this check on a bare comment");
+
   const Decl *D = ThisDeclInfo->CommentDecl;
   if (!D)
     return;
@@ -694,7 +724,7 @@
   SmallVector<ParamCommandComment *, 8> ParamVarDocs;
 
   ArrayRef<const ParmVarDecl *> ParamVars = getParamVars();
-  ParamVarDocs.resize(ParamVars.size(), NULL);
+  ParamVarDocs.resize(ParamVars.size(), nullptr);
 
   // First pass over all \\param commands: resolve all parameter names.
   for (Comment::child_iterator I = FC->child_begin(), E = FC->child_end();
@@ -783,11 +813,14 @@
 }
 
 bool Sema::isFunctionOrMethodVariadic() {
-  if (!isAnyFunctionDecl() && !isObjCMethodDecl())
+  if (!isAnyFunctionDecl() && !isObjCMethodDecl() && !isFunctionTemplateDecl())
     return false;
   if (const FunctionDecl *FD =
         dyn_cast<FunctionDecl>(ThisDeclInfo->CurrentDecl))
     return FD->isVariadic();
+  if (const FunctionTemplateDecl *FTD =
+        dyn_cast<FunctionTemplateDecl>(ThisDeclInfo->CurrentDecl))
+    return FTD->getTemplatedDecl()->isVariadic();
   if (const ObjCMethodDecl *MD =
         dyn_cast<ObjCMethodDecl>(ThisDeclInfo->CurrentDecl))
     return MD->isVariadic();
@@ -812,7 +845,7 @@
   }
   return false;
 }
-  
+
 bool Sema::isObjCPropertyDecl() {
   if (!ThisDeclInfo)
     return false;
@@ -834,8 +867,8 @@
     return false;
   if (!ThisDeclInfo->IsFilled)
     inspectThisDecl();
-  return isUnionDecl() || isClassOrStructDecl() 
-         || isObjCInterfaceDecl() || isObjCProtocolDecl();
+  return isUnionDecl() || isClassOrStructDecl() || isObjCInterfaceDecl() ||
+         isObjCProtocolDecl();
 }
 
 bool Sema::isUnionDecl() {
@@ -848,7 +881,7 @@
     return RD->isUnion();
   return false;
 }
-  
+
 bool Sema::isClassOrStructDecl() {
   if (!ThisDeclInfo)
     return false;
@@ -858,7 +891,7 @@
          isa<RecordDecl>(ThisDeclInfo->CurrentDecl) &&
          !isUnionDecl();
 }
-  
+
 bool Sema::isClassTemplateDecl() {
   if (!ThisDeclInfo)
     return false;
@@ -874,7 +907,7 @@
   if (!ThisDeclInfo->IsFilled)
     inspectThisDecl();
   return ThisDeclInfo->CurrentDecl &&
-  (isa<FunctionTemplateDecl>(ThisDeclInfo->CurrentDecl));
+         (isa<FunctionTemplateDecl>(ThisDeclInfo->CurrentDecl));
 }
 
 bool Sema::isObjCInterfaceDecl() {
@@ -885,7 +918,7 @@
   return ThisDeclInfo->CurrentDecl &&
          isa<ObjCInterfaceDecl>(ThisDeclInfo->CurrentDecl);
 }
-  
+
 bool Sema::isObjCProtocolDecl() {
   if (!ThisDeclInfo)
     return false;
@@ -894,7 +927,7 @@
   return ThisDeclInfo->CurrentDecl &&
          isa<ObjCProtocolDecl>(ThisDeclInfo->CurrentDecl);
 }
-  
+
 ArrayRef<const ParmVarDecl *> Sema::getParamVars() {
   if (!ThisDeclInfo->IsFilled)
     inspectThisDecl();
@@ -930,7 +963,7 @@
 public:
   SimpleTypoCorrector(StringRef Typo) :
       Typo(Typo), MaxEditDistance((Typo.size() + 2) / 3),
-      BestDecl(NULL), BestEditDistance(MaxEditDistance + 1),
+      BestDecl(nullptr), BestEditDistance(MaxEditDistance + 1),
       BestIndex(0), NextIndex(0)
   { }
 
@@ -938,7 +971,7 @@
 
   const NamedDecl *getBestDecl() const {
     if (BestEditDistance > MaxEditDistance)
-      return NULL;
+      return nullptr;
 
     return BestDecl;
   }
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index fe6f5fa..7448de2 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -13,6 +13,7 @@
 
 #include "clang/AST/Decl.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTLambda.h"
 #include "clang/AST/ASTMutationListener.h"
 #include "clang/AST/Attr.h"
 #include "clang/AST/DeclCXX.h"
@@ -29,7 +30,6 @@
 #include "clang/Basic/Specifiers.h"
 #include "clang/Basic/TargetInfo.h"
 #include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/type_traits.h"
 #include <algorithm>
 
 using namespace clang;
@@ -158,8 +158,7 @@
 /// Does the given declaration have member specialization information,
 /// and if so, is it an explicit specialization?
 template <class T> static typename
-llvm::enable_if_c<!llvm::is_base_of<RedeclarableTemplateDecl, T>::value,
-                  bool>::type
+std::enable_if<!std::is_base_of<RedeclarableTemplateDecl, T>::value, bool>::type
 isExplicitMemberSpecialization(const T *D) {
   if (const MemberSpecializationInfo *member =
         D->getMemberSpecializationInfo()) {
@@ -209,11 +208,8 @@
   // If we're on Mac OS X, an 'availability' for Mac OS X attribute
   // implies visibility(default).
   if (D->getASTContext().getTargetInfo().getTriple().isOSDarwin()) {
-    for (specific_attr_iterator<AvailabilityAttr> 
-              A = D->specific_attr_begin<AvailabilityAttr>(),
-           AEnd = D->specific_attr_end<AvailabilityAttr>();
-         A != AEnd; ++A)
-      if ((*A)->getPlatform()->getName().equals("macosx"))
+    for (const auto *A : D->specific_attrs<AvailabilityAttr>())
+      if (A->getPlatform()->getName().equals("macosx"))
         return DefaultVisibility;
   }
 
@@ -231,23 +227,21 @@
 /// template parameter list.  For visibility purposes, template
 /// parameters are part of the signature of a template.
 static LinkageInfo
-getLVForTemplateParameterList(const TemplateParameterList *params,
+getLVForTemplateParameterList(const TemplateParameterList *Params,
                               LVComputationKind computation) {
   LinkageInfo LV;
-  for (TemplateParameterList::const_iterator P = params->begin(),
-                                          PEnd = params->end();
-       P != PEnd; ++P) {
-
+  for (const NamedDecl *P : *Params) {
     // Template type parameters are the most common and never
     // contribute to visibility, pack or not.
-    if (isa<TemplateTypeParmDecl>(*P))
+    if (isa<TemplateTypeParmDecl>(P))
       continue;
 
     // Non-type template parameters can be restricted by the value type, e.g.
     //   template <enum X> class A { ... };
     // We have to be careful here, though, because we can be dealing with
     // dependent types.
-    if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
+    if (const NonTypeTemplateParmDecl *NTTP =
+            dyn_cast<NonTypeTemplateParmDecl>(P)) {
       // Handle the non-pack case first.
       if (!NTTP->isExpandedParameterPack()) {
         if (!NTTP->getType()->isDependentType()) {
@@ -267,7 +261,7 @@
 
     // Template template parameters can be restricted by their
     // template parameters, recursively.
-    TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
+    const TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(P);
 
     // Handle the non-pack case first.
     if (!TTP->isExpandedParameterPack()) {
@@ -292,7 +286,7 @@
                                 LVComputationKind computation);
 
 static const Decl *getOutermostFuncOrBlockContext(const Decl *D) {
-  const Decl *Ret = NULL;
+  const Decl *Ret = nullptr;
   const DeclContext *DC = D->getDeclContext();
   while (DC->getDeclKind() != Decl::TranslationUnit) {
     if (isa<FunctionDecl>(DC) || isa<BlockDecl>(DC))
@@ -307,43 +301,41 @@
 ///
 /// Note that we don't take an LVComputationKind because we always
 /// want to honor the visibility of template arguments in the same way.
-static LinkageInfo
-getLVForTemplateArgumentList(ArrayRef<TemplateArgument> args,
-                             LVComputationKind computation) {
+static LinkageInfo getLVForTemplateArgumentList(ArrayRef<TemplateArgument> Args,
+                                                LVComputationKind computation) {
   LinkageInfo LV;
 
-  for (unsigned i = 0, e = args.size(); i != e; ++i) {
-    const TemplateArgument &arg = args[i];
-    switch (arg.getKind()) {
+  for (const TemplateArgument &Arg : Args) {
+    switch (Arg.getKind()) {
     case TemplateArgument::Null:
     case TemplateArgument::Integral:
     case TemplateArgument::Expression:
       continue;
 
     case TemplateArgument::Type:
-      LV.merge(getLVForType(*arg.getAsType(), computation));
+      LV.merge(getLVForType(*Arg.getAsType(), computation));
       continue;
 
     case TemplateArgument::Declaration:
-      if (NamedDecl *ND = dyn_cast<NamedDecl>(arg.getAsDecl())) {
+      if (NamedDecl *ND = dyn_cast<NamedDecl>(Arg.getAsDecl())) {
         assert(!usesTypeVisibility(ND));
         LV.merge(getLVForDecl(ND, computation));
       }
       continue;
 
     case TemplateArgument::NullPtr:
-      LV.merge(arg.getNullPtrType()->getLinkageAndVisibility());
+      LV.merge(Arg.getNullPtrType()->getLinkageAndVisibility());
       continue;
 
     case TemplateArgument::Template:
     case TemplateArgument::TemplateExpansion:
-      if (TemplateDecl *Template
-                = arg.getAsTemplateOrTemplatePattern().getAsTemplateDecl())
+      if (TemplateDecl *Template =
+              Arg.getAsTemplateOrTemplatePattern().getAsTemplateDecl())
         LV.merge(getLVForDecl(Template, computation));
       continue;
 
     case TemplateArgument::Pack:
-      LV.merge(getLVForTemplateArgumentList(arg.getPackAsArray(), computation));
+      LV.merge(getLVForTemplateArgumentList(Arg.getPackAsArray(), computation));
       continue;
     }
     llvm_unreachable("bad template argument kind");
@@ -479,6 +471,58 @@
   LV.mergeExternalVisibility(argsLV);
 }
 
+/// Should we consider visibility associated with the template
+/// arguments and parameters of the given variable template
+/// specialization? As usual, follow class template specialization
+/// logic up to initialization.
+static bool shouldConsiderTemplateVisibility(
+                                 const VarTemplateSpecializationDecl *spec,
+                                 LVComputationKind computation) {
+  // Include visibility from the template parameters and arguments
+  // only if this is not an explicit instantiation or specialization
+  // with direct explicit visibility (and note that implicit
+  // instantiations won't have a direct attribute).
+  if (!spec->isExplicitInstantiationOrSpecialization())
+    return true;
+
+  // An explicit variable specialization is an independent, top-level
+  // declaration.  As such, if it has an explicit visibility attribute,
+  // that must directly express the user's intent, and we should honor
+  // it.
+  if (spec->isExplicitSpecialization() &&
+      hasExplicitVisibilityAlready(computation))
+    return false;
+
+  return !hasDirectVisibilityAttribute(spec, computation);
+}
+
+/// Merge in template-related linkage and visibility for the given
+/// variable template specialization. As usual, follow class template
+/// specialization logic up to initialization.
+static void mergeTemplateLV(LinkageInfo &LV,
+                            const VarTemplateSpecializationDecl *spec,
+                            LVComputationKind computation) {
+  bool considerVisibility = shouldConsiderTemplateVisibility(spec, computation);
+
+  // Merge information from the template parameters, but ignore
+  // visibility if we're only considering template arguments.
+
+  VarTemplateDecl *temp = spec->getSpecializedTemplate();
+  LinkageInfo tempLV =
+    getLVForTemplateParameterList(temp->getTemplateParameters(), computation);
+  LV.mergeMaybeWithVisibility(tempLV,
+           considerVisibility && !hasExplicitVisibilityAlready(computation));
+
+  // Merge information from the template arguments.  We ignore
+  // template-argument visibility if we've got an explicit
+  // instantiation with a visibility attribute.
+  const TemplateArgumentList &templateArgs = spec->getTemplateArgs();
+  LinkageInfo argsLV = getLVForTemplateArgumentList(templateArgs, computation);
+  if (considerVisibility)
+    LV.mergeVisibility(argsLV);
+  LV.mergeExternalVisibility(argsLV);
+}
+
 static bool useInlineVisibilityHidden(const NamedDecl *D) {
   // FIXME: we should warn if -fvisibility-inlines-hidden is used with c.
   const LangOptions &Opts = D->getASTContext().getLangOpts();
@@ -498,7 +542,7 @@
     TSK = MSI->getTemplateSpecializationKind();
   }
 
-  const FunctionDecl *Def = 0;
+  const FunctionDecl *Def = nullptr;
   // InlineVisibilityHidden only applies to definitions, and
   // isInlined() only gives meaningful answers on definitions
   // anyway.
@@ -512,9 +556,9 @@
   return First->isInExternCContext();
 }
 
-static bool isSingleLineExternC(const Decl &D) {
+static bool isSingleLineLanguageLinkage(const Decl &D) {
   if (const LinkageSpecDecl *SD = dyn_cast<LinkageSpecDecl>(D.getDeclContext()))
-    if (SD->getLanguage() == LinkageSpecDecl::lang_c && !SD->hasBraces())
+    if (!SD->hasBraces())
       return true;
   return false;
 }
@@ -548,7 +592,7 @@
 
       if (Var->getStorageClass() != SC_Extern &&
           Var->getStorageClass() != SC_PrivateExtern &&
-          !isSingleLineExternC(*Var))
+          !isSingleLineLanguageLinkage(*Var))
         return LinkageInfo::internal();
     }
 
@@ -561,16 +605,10 @@
       if (PrevVar->getStorageClass() == SC_Static)
         return LinkageInfo::internal();
     }
-  } else if (isa<FunctionDecl>(D) || isa<FunctionTemplateDecl>(D)) {
+  } else if (const FunctionDecl *Function = D->getAsFunction()) {
     // C++ [temp]p4:
     //   A non-member function template can have internal linkage; any
     //   other template name shall have external linkage.
-    const FunctionDecl *Function = 0;
-    if (const FunctionTemplateDecl *FunTmpl
-                                        = dyn_cast<FunctionTemplateDecl>(D))
-      Function = FunTmpl->getTemplatedDecl();
-    else
-      Function = cast<FunctionDecl>(D);
 
     // Explicitly declared static.
     if (Function->getCanonicalDecl()->getStorageClass() == SC_Static)
@@ -676,6 +714,14 @@
     // C99 6.2.2p4 and propagating the visibility attribute, so we don't have
     // to do it here.
 
+    // As per function and class template specializations (below),
+    // consider LV for the template and template arguments.  We're at file
+    // scope, so we do not need to worry about nested specializations.
+    if (const VarTemplateSpecializationDecl *spec
+              = dyn_cast<VarTemplateSpecializationDecl>(Var)) {
+      mergeTemplateLV(LV, spec, computation);
+    }
+
   //     - a function, unless it has internal linkage; or
   } else if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
     // In theory, we can modify the function's LV by the LV of its
@@ -782,11 +828,18 @@
   // really have linkage, but it's convenient to say they do for the
   // purposes of calculating linkage of pointer-to-data-member
   // template arguments.
+  //
+  // Templates also don't officially have linkage, but since we ignore
+  // the C++ standard and look at template arguments when determining
+  // linkage and visibility of a template specialization, we might hit
+  // a template template argument that way. If we do, we need to
+  // consider its linkage.
   if (!(isa<CXXMethodDecl>(D) ||
         isa<VarDecl>(D) ||
         isa<FieldDecl>(D) ||
         isa<IndirectFieldDecl>(D) ||
-        isa<TagDecl>(D)))
+        isa<TagDecl>(D) ||
+        isa<TemplateDecl>(D)))
     return LinkageInfo::none();
 
   LinkageInfo LV;
@@ -825,7 +878,7 @@
   // we need to completely ignore the visibility from it.
 
   // Specifically, if this decl exists and has an explicit attribute.
-  const NamedDecl *explicitSpecSuppressor = 0;
+  const NamedDecl *explicitSpecSuppressor = nullptr;
 
   if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
     // If the type of the function uses a type with unique-external
@@ -876,6 +929,10 @@
 
   // Static data members.
   } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+    if (const VarTemplateSpecializationDecl *spec
+        = dyn_cast<VarTemplateSpecializationDecl>(VD))
+      mergeTemplateLV(LV, spec, computation);
+
     // Modify the variable's linkage by its type, but ignore the
     // type's visibility unless it's a definition.
     LinkageInfo typeLV = getLVForType(*VD->getType(), computation);
@@ -949,15 +1006,19 @@
   return getLVForDecl(this, computation);
 }
 
-Optional<Visibility>
-NamedDecl::getExplicitVisibility(ExplicitVisibilityKind kind) const {
+static Optional<Visibility>
+getExplicitVisibilityAux(const NamedDecl *ND,
+                         NamedDecl::ExplicitVisibilityKind kind,
+                         bool IsMostRecent) {
+  assert(!IsMostRecent || ND == ND->getMostRecentDecl());
+
   // Check the declaration itself first.
-  if (Optional<Visibility> V = getVisibilityOf(this, kind))
+  if (Optional<Visibility> V = getVisibilityOf(ND, kind))
     return V;
 
   // If this is a member class of a specialization of a class template
   // and the corresponding decl has explicit visibility, use that.
-  if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(this)) {
+  if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(ND)) {
     CXXRecordDecl *InstantiatedFrom = RD->getInstantiatedFromMemberClass();
     if (InstantiatedFrom)
       return getVisibilityOf(InstantiatedFrom, kind);
@@ -967,26 +1028,32 @@
   // specialization of a class template, check for visibility
   // on the pattern.
   if (const ClassTemplateSpecializationDecl *spec
-        = dyn_cast<ClassTemplateSpecializationDecl>(this))
+        = dyn_cast<ClassTemplateSpecializationDecl>(ND))
     return getVisibilityOf(spec->getSpecializedTemplate()->getTemplatedDecl(),
                            kind);
 
   // Use the most recent declaration.
-  const NamedDecl *MostRecent = getMostRecentDecl();
-  if (MostRecent != this)
-    return MostRecent->getExplicitVisibility(kind);
+  if (!IsMostRecent && !isa<NamespaceDecl>(ND)) {
+    const NamedDecl *MostRecent = ND->getMostRecentDecl();
+    if (MostRecent != ND)
+      return getExplicitVisibilityAux(MostRecent, kind, true);
+  }
 
-  if (const VarDecl *Var = dyn_cast<VarDecl>(this)) {
+  if (const VarDecl *Var = dyn_cast<VarDecl>(ND)) {
     if (Var->isStaticDataMember()) {
       VarDecl *InstantiatedFrom = Var->getInstantiatedFromStaticDataMember();
       if (InstantiatedFrom)
         return getVisibilityOf(InstantiatedFrom, kind);
     }
 
+    if (const auto *VTSD = dyn_cast<VarTemplateSpecializationDecl>(Var))
+      return getVisibilityOf(VTSD->getSpecializedTemplate()->getTemplatedDecl(),
+                             kind);
+
     return None;
   }
   // Also handle function template specializations.
-  if (const FunctionDecl *fn = dyn_cast<FunctionDecl>(this)) {
+  if (const FunctionDecl *fn = dyn_cast<FunctionDecl>(ND)) {
     // If the function is a specialization of a template with an
     // explicit visibility attribute, use that.
     if (FunctionTemplateSpecializationInfo *templateInfo
@@ -1004,12 +1071,17 @@
   }
 
   // The visibility of a template is stored in the templated decl.
-  if (const TemplateDecl *TD = dyn_cast<TemplateDecl>(this))
+  if (const TemplateDecl *TD = dyn_cast<TemplateDecl>(ND))
     return getVisibilityOf(TD->getTemplatedDecl(), kind);
 
   return None;
 }
 
+Optional<Visibility>
+NamedDecl::getExplicitVisibility(ExplicitVisibilityKind kind) const {
+  return getExplicitVisibilityAux(this, kind, false);
+}
+
 static LinkageInfo getLVForClosure(const DeclContext *DC, Decl *ContextDecl,
                                    LVComputationKind computation) {
   // This lambda has its linkage/visibility determined by its owner.
@@ -1231,16 +1303,13 @@
 
     // We have just computed the linkage for this decl. By induction we know
     // that all other computed linkages match, check that the one we just
-    // computed
-    // also does.
-    NamedDecl *Old = NULL;
-    for (NamedDecl::redecl_iterator I = D->redecls_begin(),
-                                    E = D->redecls_end();
-         I != E; ++I) {
-      NamedDecl *T = cast<NamedDecl>(*I);
+    // computed also does.
+    NamedDecl *Old = nullptr;
+    for (auto I : D->redecls()) {
+      NamedDecl *T = cast<NamedDecl>(I);
       if (T == D)
         continue;
-      if (T->hasCachedLinkage()) {
+      if (!T->isInvalidDecl() && T->hasCachedLinkage()) {
         Old = T;
         break;
       }
@@ -1259,13 +1328,9 @@
 }
 
 std::string NamedDecl::getQualifiedNameAsString() const {
-  return getQualifiedNameAsString(getASTContext().getPrintingPolicy());
-}
-
-std::string NamedDecl::getQualifiedNameAsString(const PrintingPolicy &P) const {
   std::string QualName;
   llvm::raw_string_ostream OS(QualName);
-  printQualifiedName(OS, P);
+  printQualifiedName(OS, getASTContext().getPrintingPolicy());
   return OS.str();
 }
 
@@ -1302,17 +1367,20 @@
                                                             TemplateArgs.size(),
                                                             P);
     } else if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(*I)) {
+      if (P.SuppressUnwrittenScope &&
+          (ND->isAnonymousNamespace() || ND->isInline()))
+        continue;
       if (ND->isAnonymousNamespace())
-        OS << "<anonymous namespace>";
+        OS << "(anonymous namespace)";
       else
         OS << *ND;
     } else if (const RecordDecl *RD = dyn_cast<RecordDecl>(*I)) {
       if (!RD->getIdentifier())
-        OS << "<anonymous " << RD->getKindName() << '>';
+        OS << "(anonymous " << RD->getKindName() << ')';
       else
         OS << *RD;
     } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) {
-      const FunctionProtoType *FT = 0;
+      const FunctionProtoType *FT = nullptr;
       if (FD->hasWrittenPrototype())
         FT = dyn_cast<FunctionProtoType>(FD->getType()->castAs<FunctionType>());
 
@@ -1341,7 +1409,7 @@
   if (getDeclName())
     OS << *this;
   else
-    OS << "<anonymous>";
+    OS << "(anonymous)";
 }
 
 void NamedDecl::getNameForDiagnostic(raw_ostream &OS,
@@ -1381,6 +1449,7 @@
   if (isa<ObjCMethodDecl>(this))
     return false;
 
+  // FIXME: Is this correct if one of the decls comes from an inline namespace?
   if (isa<ObjCInterfaceDecl>(this) && isa<ObjCCompatibleAliasDecl>(OldD))
     return true;
 
@@ -1407,14 +1476,19 @@
 
   // A typedef of an Objective-C class type can replace an Objective-C class
   // declaration or definition, and vice versa.
+  // FIXME: Is this correct if one of the decls comes from an inline namespace?
   if ((isa<TypedefNameDecl>(this) && isa<ObjCInterfaceDecl>(OldD)) ||
       (isa<ObjCInterfaceDecl>(this) && isa<TypedefNameDecl>(OldD)))
     return true;
-  
+
   // For non-function declarations, if the declarations are of the
-  // same kind then this must be a redeclaration, or semantic analysis
-  // would not have given us the new declaration.
-  return this->getKind() == OldD->getKind();
+  // same kind and have the same parent then this must be a redeclaration,
+  // or semantic analysis would not have given us the new declaration.
+  // Note that inline namespaces can give us two declarations with the same
+  // name and kind in the same scope but different contexts.
+  return this->getKind() == OldD->getKind() &&
+         this->getDeclContext()->getRedeclContext()->Equals(
+             OldD->getDeclContext()->getRedeclContext());
 }
 
 bool NamedDecl::hasLinkage() const {
@@ -1442,11 +1516,9 @@
 
   if (isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D) || isa<MSPropertyDecl>(D))
     return true;
-  if (isa<CXXMethodDecl>(D))
-    return cast<CXXMethodDecl>(D)->isInstance();
-  if (isa<FunctionTemplateDecl>(D))
-    return cast<CXXMethodDecl>(cast<FunctionTemplateDecl>(D)
-                                 ->getTemplatedDecl())->isInstance();
+  if (const CXXMethodDecl *MD =
+          dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()))
+    return MD->isInstance();
   return false;
 }
 
@@ -1563,7 +1635,9 @@
 SourceRange DeclaratorDecl::getSourceRange() const {
   SourceLocation RangeEnd = getLocation();
   if (TypeSourceInfo *TInfo = getTypeSourceInfo()) {
-    if (typeIsPostfix(TInfo->getType()))
+    // If the declaration has no name or the type extends past the name take the
+    // end location of the type.
+    if (!getDeclName() || typeIsPostfix(TInfo->getType()))
       RangeEnd = TInfo->getTypeLoc().getSourceRange().getEnd();
   }
   return SourceRange(getOuterLocStart(), RangeEnd);
@@ -1573,13 +1647,13 @@
 QualifierInfo::setTemplateParameterListsInfo(ASTContext &Context,
                                              unsigned NumTPLists,
                                              TemplateParameterList **TPLists) {
-  assert((NumTPLists == 0 || TPLists != 0) &&
+  assert((NumTPLists == 0 || TPLists != nullptr) &&
          "Empty array of template parameters with positive size!");
 
   // Free previous template parameters (if any).
   if (NumTemplParamLists > 0) {
     Context.Deallocate(TemplParamLists);
-    TemplParamLists = 0;
+    TemplParamLists = nullptr;
     NumTemplParamLists = 0;
   }
   // Set info on matched template parameter lists (if any).
@@ -1609,12 +1683,16 @@
   llvm_unreachable("Invalid storage class");
 }
 
-VarDecl::VarDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
-                 SourceLocation IdLoc, IdentifierInfo *Id, QualType T,
-                 TypeSourceInfo *TInfo, StorageClass SC)
-    : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc), Init() {
-  assert(sizeof(VarDeclBitfields) <= sizeof(unsigned));
-  assert(sizeof(ParmVarDeclBitfields) <= sizeof(unsigned));
+VarDecl::VarDecl(Kind DK, ASTContext &C, DeclContext *DC,
+                 SourceLocation StartLoc, SourceLocation IdLoc,
+                 IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
+                 StorageClass SC)
+    : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc),
+      redeclarable_base(C), Init() {
+  static_assert(sizeof(VarDeclBitfields) <= sizeof(unsigned),
+                "VarDeclBitfields too large!");
+  static_assert(sizeof(ParmVarDeclBitfields) <= sizeof(unsigned),
+                "ParmVarDeclBitfields too large!");
   AllBits = 0;
   VarDeclBits.SClass = SC;
   // Everything else is implicitly initialized to false.
@@ -1624,13 +1702,13 @@
                          SourceLocation StartL, SourceLocation IdL,
                          IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
                          StorageClass S) {
-  return new (C) VarDecl(Var, DC, StartL, IdL, Id, T, TInfo, S);
+  return new (C, DC) VarDecl(Var, C, DC, StartL, IdL, Id, T, TInfo, S);
 }
 
 VarDecl *VarDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(VarDecl));
-  return new (Mem) VarDecl(Var, 0, SourceLocation(), SourceLocation(), 0, 
-                           QualType(), 0, SC_None);
+  return new (C, ID)
+      VarDecl(Var, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
+              QualType(), nullptr, SC_None);
 }
 
 void VarDecl::setStorageClass(StorageClass SC) {
@@ -1638,6 +1716,21 @@
   VarDeclBits.SClass = SC;
 }
 
+VarDecl::TLSKind VarDecl::getTLSKind() const {
+  switch (VarDeclBits.TSCSpec) {
+  case TSCS_unspecified:
+    if (hasAttr<ThreadAttr>())
+      return TLS_Static;
+    return TLS_None;
+  case TSCS___thread: // Fall through.
+  case TSCS__Thread_local:
+      return TLS_Static;
+  case TSCS_thread_local:
+    return TLS_Dynamic;
+  }
+  llvm_unreachable("Unknown thread storage class specifier!");
+}
+
 SourceRange VarDecl::getSourceRange() const {
   if (const Expr *Init = getInit()) {
     SourceLocation InitEnd = Init->getLocEnd();
@@ -1650,7 +1743,7 @@
 }
 
 template<typename T>
-static LanguageLinkage getLanguageLinkageTemplate(const T &D) {
+static LanguageLinkage getDeclLanguageLinkage(const T &D) {
   // C++ [dcl.link]p1: All function types, function names with external linkage,
   // and variable names with external linkage have a language linkage.
   if (!D.hasExternalFormalLinkage())
@@ -1678,7 +1771,7 @@
 }
 
 template<typename T>
-static bool isExternCTemplate(const T &D) {
+static bool isDeclExternC(const T &D) {
   // Since the context is ignored for class members, they can only have C++
   // language linkage or no language linkage.
   const DeclContext *DC = D.getDeclContext();
@@ -1691,11 +1784,11 @@
 }
 
 LanguageLinkage VarDecl::getLanguageLinkage() const {
-  return getLanguageLinkageTemplate(*this);
+  return getDeclLanguageLinkage(*this);
 }
 
 bool VarDecl::isExternC() const {
-  return isExternCTemplate(*this);
+  return isDeclExternC(*this);
 }
 
 bool VarDecl::isInExternCContext() const {
@@ -1764,7 +1857,7 @@
   //   A declaration directly contained in a linkage-specification is treated
   //   as if it contains the extern specifier for the purpose of determining
   //   the linkage of the declared name and whether it is a definition.
-  if (isSingleLineExternC(*this))
+  if (isSingleLineLanguageLinkage(*this))
     return DeclarationOnly;
 
   // C99 6.9.2p2:
@@ -1783,38 +1876,35 @@
 VarDecl *VarDecl::getActingDefinition() {
   DefinitionKind Kind = isThisDeclarationADefinition();
   if (Kind != TentativeDefinition)
-    return 0;
+    return nullptr;
 
-  VarDecl *LastTentative = 0;
+  VarDecl *LastTentative = nullptr;
   VarDecl *First = getFirstDecl();
-  for (redecl_iterator I = First->redecls_begin(), E = First->redecls_end();
-       I != E; ++I) {
-    Kind = (*I)->isThisDeclarationADefinition();
+  for (auto I : First->redecls()) {
+    Kind = I->isThisDeclarationADefinition();
     if (Kind == Definition)
-      return 0;
+      return nullptr;
     else if (Kind == TentativeDefinition)
-      LastTentative = *I;
+      LastTentative = I;
   }
   return LastTentative;
 }
 
 VarDecl *VarDecl::getDefinition(ASTContext &C) {
   VarDecl *First = getFirstDecl();
-  for (redecl_iterator I = First->redecls_begin(), E = First->redecls_end();
-       I != E; ++I) {
-    if ((*I)->isThisDeclarationADefinition(C) == Definition)
-      return *I;
+  for (auto I : First->redecls()) {
+    if (I->isThisDeclarationADefinition(C) == Definition)
+      return I;
   }
-  return 0;
+  return nullptr;
 }
 
 VarDecl::DefinitionKind VarDecl::hasDefinition(ASTContext &C) const {
   DefinitionKind Kind = DeclarationOnly;
   
   const VarDecl *First = getFirstDecl();
-  for (redecl_iterator I = First->redecls_begin(), E = First->redecls_end();
-       I != E; ++I) {
-    Kind = std::max(Kind, (*I)->isThisDeclarationADefinition(C));
+  for (auto I : First->redecls()) {
+    Kind = std::max(Kind, I->isThisDeclarationADefinition(C));
     if (Kind == Definition)
       break;
   }
@@ -1823,15 +1913,13 @@
 }
 
 const Expr *VarDecl::getAnyInitializer(const VarDecl *&D) const {
-  redecl_iterator I = redecls_begin(), E = redecls_end();
-  while (I != E && !I->getInit())
-    ++I;
-
-  if (I != E) {
-    D = *I;
-    return I->getInit();
+  for (auto I : redecls()) {
+    if (auto Expr = I->getInit()) {
+      D = I;
+      return Expr;
+    }
   }
-  return 0;
+  return nullptr;
 }
 
 bool VarDecl::isOutOfLine() const {
@@ -1852,15 +1940,14 @@
 
 VarDecl *VarDecl::getOutOfLineDefinition() {
   if (!isStaticDataMember())
-    return 0;
-  
-  for (VarDecl::redecl_iterator RD = redecls_begin(), RDEnd = redecls_end();
-       RD != RDEnd; ++RD) {
+    return nullptr;
+
+  for (auto RD : redecls()) {
     if (RD->getLexicalDeclContext()->isFileContext())
-      return *RD;
+      return RD;
   }
-  
-  return 0;
+
+  return nullptr;
 }
 
 void VarDecl::setInit(Expr *I) {
@@ -1937,7 +2024,7 @@
   // first time it is evaluated. FIXME: The notes won't always be emitted the
   // first time we try evaluation, so might not be produced at all.
   if (Eval->WasEvaluated)
-    return Eval->Evaluated.isUninit() ? 0 : &Eval->Evaluated;
+    return Eval->Evaluated.isUninit() ? nullptr : &Eval->Evaluated;
 
   const Expr *Init = cast<Expr>(Eval->Value);
   assert(!Init->isValueDependent());
@@ -1946,7 +2033,7 @@
     // FIXME: Produce a diagnostic for self-initialization.
     Eval->CheckedICE = true;
     Eval->IsICE = false;
-    return 0;
+    return nullptr;
   }
 
   Eval->IsEvaluating = true;
@@ -1972,7 +2059,7 @@
     Eval->IsICE = Result && Notes.empty();
   }
 
-  return Result ? &Eval->Evaluated : 0;
+  return Result ? &Eval->Evaluated : nullptr;
 }
 
 bool VarDecl::checkInitIsICE() const {
@@ -2014,8 +2101,8 @@
 VarDecl *VarDecl::getInstantiatedFromStaticDataMember() const {
   if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo())
     return cast<VarDecl>(MSI->getInstantiatedFrom());
-  
-  return 0;
+
+  return nullptr;
 }
 
 TemplateSpecializationKind VarDecl::getTemplateSpecializationKind() const {
@@ -2055,7 +2142,7 @@
     // return getASTContext().getInstantiatedFromStaticDataMember(this);
     return getASTContext().getTemplateOrSpecializationInfo(this)
         .dyn_cast<MemberSpecializationInfo *>();
-  return 0;
+  return nullptr;
 }
 
 void VarDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK,
@@ -2097,8 +2184,8 @@
                                  SourceLocation IdLoc, IdentifierInfo *Id,
                                  QualType T, TypeSourceInfo *TInfo,
                                  StorageClass S, Expr *DefArg) {
-  return new (C) ParmVarDecl(ParmVar, DC, StartLoc, IdLoc, Id, T, TInfo,
-                             S, DefArg);
+  return new (C, DC) ParmVarDecl(ParmVar, C, DC, StartLoc, IdLoc, Id, T, TInfo,
+                                 S, DefArg);
 }
 
 QualType ParmVarDecl::getOriginalType() const {
@@ -2110,9 +2197,9 @@
 }
 
 ParmVarDecl *ParmVarDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ParmVarDecl));
-  return new (Mem) ParmVarDecl(ParmVar, 0, SourceLocation(), SourceLocation(),
-                               0, QualType(), 0, SC_None, 0);
+  return new (C, ID)
+      ParmVarDecl(ParmVar, C, nullptr, SourceLocation(), SourceLocation(),
+                  nullptr, QualType(), nullptr, SC_None, nullptr);
 }
 
 SourceRange ParmVarDecl::getSourceRange() const {
@@ -2185,9 +2272,9 @@
 }
 
 bool FunctionDecl::hasBody(const FunctionDecl *&Definition) const {
-  for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) {
+  for (auto I : redecls()) {
     if (I->Body || I->IsLateTemplateParsed) {
-      Definition = *I;
+      Definition = I;
       return true;
     }
   }
@@ -2210,10 +2297,10 @@
 }
 
 bool FunctionDecl::isDefined(const FunctionDecl *&Definition) const {
-  for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) {
+  for (auto I : redecls()) {
     if (I->IsDeleted || I->IsDefaulted || I->Body || I->IsLateTemplateParsed ||
         I->hasAttr<AliasAttr>()) {
-      Definition = I->IsDeleted ? I->getCanonicalDecl() : *I;
+      Definition = I->IsDeleted ? I->getCanonicalDecl() : I;
       return true;
     }
   }
@@ -2223,12 +2310,12 @@
 
 Stmt *FunctionDecl::getBody(const FunctionDecl *&Definition) const {
   if (!hasBody(Definition))
-    return 0;
+    return nullptr;
 
   if (Definition->Body)
     return Definition->Body.get(getASTContext().getExternalSource());
 
-  return 0;
+  return nullptr;
 }
 
 void FunctionDecl::setBody(Stmt *B) {
@@ -2292,11 +2379,12 @@
          getDeclName().getCXXOverloadedOperator() == OO_Array_New ||
          getDeclName().getCXXOverloadedOperator() == OO_Array_Delete);
 
-  if (isa<CXXRecordDecl>(getDeclContext())) return false;
-  assert(getDeclContext()->getRedeclContext()->isTranslationUnit());
+  if (!getDeclContext()->getRedeclContext()->isTranslationUnit())
+    return false;
 
   const FunctionProtoType *proto = getType()->castAs<FunctionProtoType>();
-  if (proto->getNumArgs() != 2 || proto->isVariadic()) return false;
+  if (proto->getNumParams() != 2 || proto->isVariadic())
+    return false;
 
   ASTContext &Context =
     cast<TranslationUnitDecl>(getDeclContext()->getRedeclContext())
@@ -2304,13 +2392,7 @@
 
   // The result type and first argument type are constant across all
   // these operators.  The second argument must be exactly void*.
-  return (proto->getArgType(1).getCanonicalType() == Context.VoidPtrTy);
-}
-
-static bool isNamespaceStd(const DeclContext *DC) {
-  const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC->getRedeclContext());
-  return ND && isNamed(ND, "std") &&
-         ND->getParent()->getRedeclContext()->isTranslationUnit();
+  return (proto->getParamType(1).getCanonicalType() == Context.VoidPtrTy);
 }
 
 bool FunctionDecl::isReplaceableGlobalAllocationFunction() const {
@@ -2324,20 +2406,23 @@
 
   if (isa<CXXRecordDecl>(getDeclContext()))
     return false;
-  assert(getDeclContext()->getRedeclContext()->isTranslationUnit());
+
+  // This can only fail for an invalid 'operator new' declaration.
+  if (!getDeclContext()->getRedeclContext()->isTranslationUnit())
+    return false;
 
   const FunctionProtoType *FPT = getType()->castAs<FunctionProtoType>();
-  if (FPT->getNumArgs() > 2 || FPT->isVariadic())
+  if (FPT->getNumParams() == 0 || FPT->getNumParams() > 2 || FPT->isVariadic())
     return false;
 
   // If this is a single-parameter function, it must be a replaceable global
   // allocation or deallocation function.
-  if (FPT->getNumArgs() == 1)
+  if (FPT->getNumParams() == 1)
     return true;
 
   // Otherwise, we're looking for a second parameter whose type is
   // 'const std::nothrow_t &', or, in C++1y, 'std::size_t'.
-  QualType Ty = FPT->getArgType(1);
+  QualType Ty = FPT->getParamType(1);
   ASTContext &Ctx = getASTContext();
   if (Ctx.getLangOpts().SizedDeallocation &&
       Ctx.hasSameType(Ty, Ctx.getSizeType()))
@@ -2347,30 +2432,31 @@
   Ty = Ty->getPointeeType();
   if (Ty.getCVRQualifiers() != Qualifiers::Const)
     return false;
-  // FIXME: Recognise nothrow_t in an inline namespace inside std?
   const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();
-  return RD && isNamed(RD, "nothrow_t") && isNamespaceStd(RD->getDeclContext());
+  return RD && isNamed(RD, "nothrow_t") && RD->isInStdNamespace();
 }
 
 FunctionDecl *
 FunctionDecl::getCorrespondingUnsizedGlobalDeallocationFunction() const {
   ASTContext &Ctx = getASTContext();
   if (!Ctx.getLangOpts().SizedDeallocation)
-    return 0;
+    return nullptr;
 
   if (getDeclName().getNameKind() != DeclarationName::CXXOperatorName)
-    return 0;
+    return nullptr;
   if (getDeclName().getCXXOverloadedOperator() != OO_Delete &&
       getDeclName().getCXXOverloadedOperator() != OO_Array_Delete)
-    return 0;
+    return nullptr;
   if (isa<CXXRecordDecl>(getDeclContext()))
-    return 0;
-  assert(getDeclContext()->getRedeclContext()->isTranslationUnit());
+    return nullptr;
+
+  if (!getDeclContext()->getRedeclContext()->isTranslationUnit())
+    return nullptr;
 
   if (getNumParams() != 2 || isVariadic() ||
-      !Ctx.hasSameType(getType()->castAs<FunctionProtoType>()->getArgType(1),
+      !Ctx.hasSameType(getType()->castAs<FunctionProtoType>()->getParamType(1),
                        Ctx.getSizeType()))
-    return 0;
+    return nullptr;
 
   // This is a sized deallocation function. Find the corresponding unsized
   // deallocation function.
@@ -2380,15 +2466,15 @@
     if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*RI))
       if (FD->getNumParams() == 1 && !FD->isVariadic())
         return FD;
-  return 0;
+  return nullptr;
 }
 
 LanguageLinkage FunctionDecl::getLanguageLinkage() const {
-  return getLanguageLinkageTemplate(*this);
+  return getDeclLanguageLinkage(*this);
 }
 
 bool FunctionDecl::isExternC() const {
-  return isExternCTemplate(*this);
+  return isDeclExternC(*this);
 }
 
 bool FunctionDecl::isInExternCContext() const {
@@ -2431,7 +2517,7 @@
 
   if (FunctionTemplateDecl *FunTmpl = getDescribedFunctionTemplate()) {
     FunctionTemplateDecl *PrevFunTmpl
-      = PrevDecl? PrevDecl->getDescribedFunctionTemplate() : 0;
+      = PrevDecl? PrevDecl->getDescribedFunctionTemplate() : nullptr;
     assert((!PrevDecl || PrevFunTmpl) && "Function/function template mismatch");
     FunTmpl->setPreviousDecl(PrevFunTmpl);
   }
@@ -2477,7 +2563,7 @@
 
   // If the function is marked "overloadable", it has a different mangled name
   // and is not the C library function.
-  if (getAttr<OverloadableAttr>())
+  if (hasAttr<OverloadableAttr>())
     return 0;
 
   if (!Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID))
@@ -2499,16 +2585,13 @@
 /// based on its FunctionType.  This is the length of the ParamInfo array
 /// after it has been created.
 unsigned FunctionDecl::getNumParams() const {
-  const FunctionType *FT = getType()->castAs<FunctionType>();
-  if (isa<FunctionNoProtoType>(FT))
-    return 0;
-  return cast<FunctionProtoType>(FT)->getNumArgs();
-
+  const FunctionProtoType *FPT = getType()->getAs<FunctionProtoType>();
+  return FPT ? FPT->getNumParams() : 0;
 }
 
 void FunctionDecl::setParams(ASTContext &C,
                              ArrayRef<ParmVarDecl *> NewParamInfo) {
-  assert(ParamInfo == 0 && "Already has param info!");
+  assert(!ParamInfo && "Already has param info!");
   assert(NewParamInfo.size() == getNumParams() && "Parameter count mismatch!");
 
   // Zero params -> null pointer.
@@ -2525,44 +2608,67 @@
     NamedDecl **A = new (getASTContext()) NamedDecl*[NewDecls.size()];
     std::copy(NewDecls.begin(), NewDecls.end(), A);
     DeclsInPrototypeScope = ArrayRef<NamedDecl *>(A, NewDecls.size());
+    // Move declarations introduced in prototype to the function context.
+    for (auto I : NewDecls) {
+      DeclContext *DC = I->getDeclContext();
+      // Forward-declared reference to an enumeration is not added to
+      // declaration scope, so skip declaration that is absent from its
+      // declaration contexts.
+      if (DC->containsDecl(I)) {
+          DC->removeDecl(I);
+          I->setDeclContext(this);
+          addDecl(I);
+      }
+    }
   }
 }
 
 /// 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
-/// arguments (in C++) or the last parameter is a parameter pack.
+/// arguments (in C++) or are parameter packs (C++11).
 unsigned FunctionDecl::getMinRequiredArguments() const {
   if (!getASTContext().getLangOpts().CPlusPlus)
     return getNumParams();
-  
-  unsigned NumRequiredArgs = getNumParams();  
-  
-  // If the last parameter is a parameter pack, we don't need an argument for 
-  // it.
-  if (NumRequiredArgs > 0 &&
-      getParamDecl(NumRequiredArgs - 1)->isParameterPack())
-    --NumRequiredArgs;
-      
-  // If this parameter has a default argument, we don't need an argument for
-  // it.
-  while (NumRequiredArgs > 0 &&
-         getParamDecl(NumRequiredArgs-1)->hasDefaultArg())
-    --NumRequiredArgs;
 
-  // We might have parameter packs before the end. These can't be deduced,
-  // but they can still handle multiple arguments.
-  unsigned ArgIdx = NumRequiredArgs;
-  while (ArgIdx > 0) {
-    if (getParamDecl(ArgIdx - 1)->isParameterPack())
-      NumRequiredArgs = ArgIdx;
-    
-    --ArgIdx;
-  }
-  
+  unsigned NumRequiredArgs = 0;
+  for (auto *Param : params())
+    if (!Param->isParameterPack() && !Param->hasDefaultArg())
+      ++NumRequiredArgs;
   return NumRequiredArgs;
 }
 
+/// \brief The combination of the extern and inline keywords under MSVC forces
+/// the function to be required.
+///
+/// Note: This function assumes that we will only get called when isInlined()
+/// would return true for this FunctionDecl.
+bool FunctionDecl::isMSExternInline() const {
+  assert(isInlined() && "expected to get called on an inlined function!");
+
+  const ASTContext &Context = getASTContext();
+  if (!Context.getLangOpts().MSVCCompat && !hasAttr<DLLExportAttr>())
+    return false;
+
+  for (const FunctionDecl *FD = this; FD; FD = FD->getPreviousDecl())
+    if (FD->getStorageClass() == SC_Extern)
+      return true;
+
+  return false;
+}
+
+static bool redeclForcesDefMSVC(const FunctionDecl *Redecl) {
+  if (Redecl->getStorageClass() != SC_Extern)
+    return false;
+
+  for (const FunctionDecl *FD = Redecl->getPreviousDecl(); FD;
+       FD = FD->getPreviousDecl())
+    if (FD->getStorageClass() == SC_Extern)
+      return false;
+
+  return true;
+}
+
 static bool RedeclForcesDefC99(const FunctionDecl *Redecl) {
   // Only consider file-scope declarations in this test.
   if (!Redecl->getLexicalDeclContext()->isTranslationUnit())
@@ -2582,7 +2688,7 @@
 /// \brief For a function declaration in C or C++, determine whether this
 /// declaration causes the definition to be externally visible.
 ///
-/// Specifically, this determines if adding the current declaration to the set
+/// For instance, this determines if adding the current declaration to the set
 /// of redeclarations of the given functions causes
 /// isInlineDefinitionExternallyVisible to change from false to true.
 bool FunctionDecl::doesDeclarationForceExternallyVisibleDefinition() const {
@@ -2591,6 +2697,13 @@
 
   ASTContext &Context = getASTContext();
 
+  if (Context.getLangOpts().MSVCCompat) {
+    const FunctionDecl *Definition;
+    if (hasBody(Definition) && Definition->isInlined() &&
+        redeclForcesDefMSVC(this))
+      return true;
+  }
+
   if (Context.getLangOpts().GNUInline || hasAttr<GNUInlineAttr>()) {
     // With GNU inlining, a declaration with 'inline' but not 'extern', forces
     // an externally visible definition.
@@ -2638,6 +2751,26 @@
   return FoundBody;
 }
 
+SourceRange FunctionDecl::getReturnTypeSourceRange() const {
+  const TypeSourceInfo *TSI = getTypeSourceInfo();
+  if (!TSI)
+    return SourceRange();
+  FunctionTypeLoc FTL =
+      TSI->getTypeLoc().IgnoreParens().getAs<FunctionTypeLoc>();
+  if (!FTL)
+    return SourceRange();
+
+  // Skip self-referential return types.
+  const SourceManager &SM = getASTContext().getSourceManager();
+  SourceRange RTRange = FTL.getReturnLoc().getSourceRange();
+  SourceLocation Boundary = getNameInfo().getLocStart();
+  if (RTRange.isInvalid() || Boundary.isInvalid() ||
+      !SM.isBeforeInTranslationUnit(RTRange.getEnd(), Boundary))
+    return SourceRange();
+
+  return RTRange;
+}
+
 /// \brief For an inline function definition in C, or for a gnu_inline function
 /// in C++, determine whether the definition will be externally visible.
 ///
@@ -2672,9 +2805,7 @@
     
     // If any declaration is 'inline' but not 'extern', then this definition
     // is externally visible.
-    for (redecl_iterator Redecl = redecls_begin(), RedeclEnd = redecls_end();
-         Redecl != RedeclEnd;
-         ++Redecl) {
+    for (auto Redecl : redecls()) {
       if (Redecl->isInlineSpecified() && 
           Redecl->getStorageClass() != SC_Extern)
         return true;
@@ -2691,10 +2822,8 @@
   //   [...] If all of the file scope declarations for a function in a 
   //   translation unit include the inline function specifier without extern, 
   //   then the definition in that translation unit is an inline definition.
-  for (redecl_iterator Redecl = redecls_begin(), RedeclEnd = redecls_end();
-       Redecl != RedeclEnd;
-       ++Redecl) {
-    if (RedeclForcesDefC99(*Redecl))
+  for (auto Redecl : redecls()) {
+    if (RedeclForcesDefC99(Redecl))
       return true;
   }
   
@@ -2720,7 +2849,7 @@
   if (getDeclName().getNameKind() == DeclarationName::CXXLiteralOperatorName)
     return getDeclName().getCXXLiteralIdentifier();
   else
-    return 0;
+    return nullptr;
 }
 
 FunctionDecl::TemplatedKind FunctionDecl::getTemplatedKind() const {
@@ -2742,8 +2871,8 @@
 FunctionDecl *FunctionDecl::getInstantiatedFromMemberFunction() const {
   if (MemberSpecializationInfo *Info = getMemberSpecializationInfo())
     return cast<FunctionDecl>(Info->getInstantiatedFrom());
-  
-  return 0;
+
+  return nullptr;
 }
 
 void 
@@ -2773,7 +2902,7 @@
   // It is possible to instantiate TSK_ExplicitSpecialization kind
   // if the FunctionDecl has a class scope specialization pattern.
   case TSK_ExplicitSpecialization:
-    return getClassScopeSpecializationPattern() != 0;
+    return getClassScopeSpecializationPattern() != nullptr;
 
   case TSK_ExplicitInstantiationDeclaration:
     // Handled below.
@@ -2813,14 +2942,34 @@
   // Handle class scope explicit specialization special case.
   if (getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
     return getClassScopeSpecializationPattern();
+  
+  // If this is a generic lambda call operator specialization, its 
+  // instantiation pattern is always its primary template's pattern
+  // even if its primary template was instantiated from another 
+  // member template (which happens with nested generic lambdas).
+  // Since a lambda's call operator's body is transformed eagerly, 
+  // we don't have to go hunting for a prototype definition template 
+  // (i.e. instantiated-from-member-template) to use as an instantiation 
+  // pattern.
 
+  if (isGenericLambdaCallOperatorSpecialization(
+          dyn_cast<CXXMethodDecl>(this))) {
+    assert(getPrimaryTemplate() && "A generic lambda specialization must be "
+                                   "generated from a primary call operator "
+                                   "template");
+    assert(getPrimaryTemplate()->getTemplatedDecl()->getBody() &&
+           "A generic lambda call operator template must always have a body - "
+           "even if instantiated from a prototype (i.e. as written) member "
+           "template");
+    return getPrimaryTemplate()->getTemplatedDecl();
+  }
+  
   if (FunctionTemplateDecl *Primary = getPrimaryTemplate()) {
     while (Primary->getInstantiatedFromMemberTemplate()) {
       // If we have hit a point where the user provided a specialization of
       // this template, we're done looking.
       if (Primary->isMemberSpecialization())
         break;
-      
       Primary = Primary->getInstantiatedFromMemberTemplate();
     }
     
@@ -2836,7 +2985,7 @@
             .dyn_cast<FunctionTemplateSpecializationInfo*>()) {
     return Info->Template.getPointer();
   }
-  return 0;
+  return nullptr;
 }
 
 FunctionDecl *FunctionDecl::getClassScopeSpecializationPattern() const {
@@ -2850,7 +2999,7 @@
             .dyn_cast<FunctionTemplateSpecializationInfo*>()) {
     return Info->TemplateArguments;
   }
-  return 0;
+  return nullptr;
 }
 
 const ASTTemplateArgumentListInfo *
@@ -2860,7 +3009,7 @@
             .dyn_cast<FunctionTemplateSpecializationInfo*>()) {
     return Info->TemplateArgumentsAsWritten;
   }
-  return 0;
+  return nullptr;
 }
 
 void
@@ -3090,14 +3239,14 @@
                              IdentifierInfo *Id, QualType T,
                              TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
                              InClassInitStyle InitStyle) {
-  return new (C) FieldDecl(Decl::Field, DC, StartLoc, IdLoc, Id, T, TInfo,
-                           BW, Mutable, InitStyle);
+  return new (C, DC) FieldDecl(Decl::Field, DC, StartLoc, IdLoc, Id, T, TInfo,
+                               BW, Mutable, InitStyle);
 }
 
 FieldDecl *FieldDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FieldDecl));
-  return new (Mem) FieldDecl(Field, 0, SourceLocation(), SourceLocation(),
-                             0, QualType(), 0, 0, false, ICIS_NoInit);
+  return new (C, ID) FieldDecl(Field, nullptr, SourceLocation(),
+                               SourceLocation(), nullptr, QualType(), nullptr,
+                               nullptr, false, ICIS_NoInit);
 }
 
 bool FieldDecl::isAnonymousStructOrUnion() const {
@@ -3169,8 +3318,10 @@
 
 void TagDecl::setTypedefNameForAnonDecl(TypedefNameDecl *TDD) {
   NamedDeclOrQualifier = TDD;
-  if (TypeForDecl)
-    assert(TypeForDecl->isLinkageValid());
+  if (const Type *T = getTypeForDecl()) {
+    (void)T;
+    assert(T->isLinkageValid());
+  }
   assert(isLinkageValid());
 }
 
@@ -3178,10 +3329,10 @@
   IsBeingDefined = true;
 
   if (CXXRecordDecl *D = dyn_cast<CXXRecordDecl>(this)) {
-    struct CXXRecordDecl::DefinitionData *Data = 
+    struct CXXRecordDecl::DefinitionData *Data =
       new (getASTContext()) struct CXXRecordDecl::DefinitionData(D);
-    for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I)
-      cast<CXXRecordDecl>(*I)->DefinitionData = Data;
+    for (auto I : redecls())
+      cast<CXXRecordDecl>(I)->DefinitionData = Data;
   }
 }
 
@@ -3213,12 +3364,11 @@
   if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(this))
     return CXXRD->getDefinition();
 
-  for (redecl_iterator R = redecls_begin(), REnd = redecls_end();
-       R != REnd; ++R)
+  for (auto R : redecls())
     if (R->isCompleteDefinition())
-      return *R;
+      return R;
 
-  return 0;
+  return nullptr;
 }
 
 void TagDecl::setQualifierInfo(NestedNameSpecifierLoc QualifierLoc) {
@@ -3233,7 +3383,7 @@
     if (hasExtInfo()) {
       if (getExtInfo()->NumTemplParamLists == 0) {
         getASTContext().Deallocate(getExtInfo());
-        NamedDeclOrQualifier = (TypedefNameDecl*) 0;
+        NamedDeclOrQualifier = (TypedefNameDecl*)nullptr;
       }
       else
         getExtInfo()->QualifierLoc = QualifierLoc;
@@ -3264,21 +3414,28 @@
                            IdentifierInfo *Id,
                            EnumDecl *PrevDecl, bool IsScoped,
                            bool IsScopedUsingClassTag, bool IsFixed) {
-  EnumDecl *Enum = new (C) EnumDecl(DC, StartLoc, IdLoc, Id, PrevDecl,
-                                    IsScoped, IsScopedUsingClassTag, IsFixed);
+  EnumDecl *Enum = new (C, DC) EnumDecl(C, DC, StartLoc, IdLoc, Id, PrevDecl,
+                                        IsScoped, IsScopedUsingClassTag,
+                                        IsFixed);
   Enum->MayHaveOutOfDateDef = C.getLangOpts().Modules;
   C.getTypeDeclType(Enum, PrevDecl);
   return Enum;
 }
 
 EnumDecl *EnumDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(EnumDecl));
-  EnumDecl *Enum = new (Mem) EnumDecl(0, SourceLocation(), SourceLocation(),
-                                      0, 0, false, false, false);
+  EnumDecl *Enum =
+      new (C, ID) EnumDecl(C, nullptr, SourceLocation(), SourceLocation(),
+                           nullptr, nullptr, false, false, false);
   Enum->MayHaveOutOfDateDef = C.getLangOpts().Modules;
   return Enum;
 }
 
+SourceRange EnumDecl::getIntegerTypeRange() const {
+  if (const TypeSourceInfo *TI = getIntegerTypeSourceInfo())
+    return TI->getTypeLoc().getSourceRange();
+  return SourceRange();
+}
+
 void EnumDecl::completeDefinition(QualType NewType,
                                   QualType NewPromotionType,
                                   unsigned NumPositiveBits,
@@ -3314,7 +3471,7 @@
   if (SpecializationInfo)
     return cast<EnumDecl>(SpecializationInfo->getInstantiatedFrom());
 
-  return 0;
+  return nullptr;
 }
 
 void EnumDecl::setInstantiationOfMemberEnum(ASTContext &C, EnumDecl *ED,
@@ -3327,10 +3484,11 @@
 // RecordDecl Implementation
 //===----------------------------------------------------------------------===//
 
-RecordDecl::RecordDecl(Kind DK, TagKind TK, DeclContext *DC,
-                       SourceLocation StartLoc, SourceLocation IdLoc,
-                       IdentifierInfo *Id, RecordDecl *PrevDecl)
-  : TagDecl(DK, TK, DC, IdLoc, Id, PrevDecl, StartLoc) {
+RecordDecl::RecordDecl(Kind DK, TagKind TK, const ASTContext &C,
+                       DeclContext *DC, SourceLocation StartLoc,
+                       SourceLocation IdLoc, IdentifierInfo *Id,
+                       RecordDecl *PrevDecl)
+    : TagDecl(DK, TK, C, DC, IdLoc, Id, PrevDecl, StartLoc) {
   HasFlexibleArrayMember = false;
   AnonymousStructOrUnion = false;
   HasObjectMember = false;
@@ -3342,8 +3500,8 @@
 RecordDecl *RecordDecl::Create(const ASTContext &C, TagKind TK, DeclContext *DC,
                                SourceLocation StartLoc, SourceLocation IdLoc,
                                IdentifierInfo *Id, RecordDecl* PrevDecl) {
-  RecordDecl* R = new (C) RecordDecl(Record, TK, DC, StartLoc, IdLoc, Id,
-                                     PrevDecl);
+  RecordDecl *R = new (C, DC) RecordDecl(Record, TK, C, DC,
+                                         StartLoc, IdLoc, Id, PrevDecl);
   R->MayHaveOutOfDateDef = C.getLangOpts().Modules;
 
   C.getTypeDeclType(R, PrevDecl);
@@ -3351,9 +3509,9 @@
 }
 
 RecordDecl *RecordDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(RecordDecl));
-  RecordDecl *R = new (Mem) RecordDecl(Record, TTK_Struct, 0, SourceLocation(),
-                                       SourceLocation(), 0, 0);
+  RecordDecl *R =
+      new (C, ID) RecordDecl(Record, TTK_Struct, C, nullptr, SourceLocation(),
+                             SourceLocation(), nullptr, nullptr);
   R->MayHaveOutOfDateDef = C.getLangOpts().Modules;
   return R;
 }
@@ -3416,7 +3574,7 @@
   if (Decls.empty())
     return;
 
-  llvm::tie(FirstDecl, LastDecl) = BuildDeclChain(Decls,
+  std::tie(FirstDecl, LastDecl) = BuildDeclChain(Decls,
                                                  /*FieldsAlreadyLoaded=*/false);
 }
 
@@ -3425,7 +3583,7 @@
 //===----------------------------------------------------------------------===//
 
 void BlockDecl::setParams(ArrayRef<ParmVarDecl *> NewParamInfo) {
-  assert(ParamInfo == 0 && "Already has param info!");
+  assert(!ParamInfo && "Already has param info!");
 
   // Zero params -> null pointer.
   if (!NewParamInfo.empty()) {
@@ -3443,7 +3601,7 @@
 
   if (begin == end) {
     NumCaptures = 0;
-    Captures = 0;
+    Captures = nullptr;
     return;
   }
 
@@ -3458,10 +3616,9 @@
 }
 
 bool BlockDecl::capturesVariable(const VarDecl *variable) const {
-  for (capture_const_iterator
-         i = capture_begin(), e = capture_end(); i != e; ++i)
+  for (const auto &I : captures())
     // Only auto vars can be captured, so no redeclaration worries.
-    if (i->getVariable() == variable)
+    if (I.getVariable() == variable)
       return true;
 
   return false;
@@ -3478,33 +3635,33 @@
 void TranslationUnitDecl::anchor() { }
 
 TranslationUnitDecl *TranslationUnitDecl::Create(ASTContext &C) {
-  return new (C) TranslationUnitDecl(C);
+  return new (C, (DeclContext *)nullptr) TranslationUnitDecl(C);
 }
 
 void LabelDecl::anchor() { }
 
 LabelDecl *LabelDecl::Create(ASTContext &C, DeclContext *DC,
                              SourceLocation IdentL, IdentifierInfo *II) {
-  return new (C) LabelDecl(DC, IdentL, II, 0, IdentL);
+  return new (C, DC) LabelDecl(DC, IdentL, II, nullptr, IdentL);
 }
 
 LabelDecl *LabelDecl::Create(ASTContext &C, DeclContext *DC,
                              SourceLocation IdentL, IdentifierInfo *II,
                              SourceLocation GnuLabelL) {
   assert(GnuLabelL != IdentL && "Use this only for GNU local labels");
-  return new (C) LabelDecl(DC, IdentL, II, 0, GnuLabelL);
+  return new (C, DC) LabelDecl(DC, IdentL, II, nullptr, GnuLabelL);
 }
 
 LabelDecl *LabelDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(LabelDecl));
-  return new (Mem) LabelDecl(0, SourceLocation(), 0, 0, SourceLocation());
+  return new (C, ID) LabelDecl(nullptr, SourceLocation(), nullptr, nullptr,
+                               SourceLocation());
 }
 
 void ValueDecl::anchor() { }
 
 bool ValueDecl::isWeak() const {
-  for (attr_iterator I = attr_begin(), E = attr_end(); I != E; ++I)
-    if (isa<WeakAttr>(*I) || isa<WeakRefAttr>(*I))
+  for (const auto *I : attrs())
+    if (isa<WeakAttr>(I) || isa<WeakRefAttr>(I))
       return true;
 
   return isWeakImported();
@@ -3516,13 +3673,13 @@
                                              SourceLocation IdLoc,
                                              IdentifierInfo *Id,
                                              QualType Type) {
-  return new (C) ImplicitParamDecl(DC, IdLoc, Id, Type);
+  return new (C, DC) ImplicitParamDecl(C, DC, IdLoc, Id, Type);
 }
 
-ImplicitParamDecl *ImplicitParamDecl::CreateDeserialized(ASTContext &C, 
+ImplicitParamDecl *ImplicitParamDecl::CreateDeserialized(ASTContext &C,
                                                          unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ImplicitParamDecl));
-  return new (Mem) ImplicitParamDecl(0, SourceLocation(), 0, QualType());
+  return new (C, ID) ImplicitParamDecl(C, nullptr, SourceLocation(), nullptr,
+                                       QualType());
 }
 
 FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC,
@@ -3530,66 +3687,53 @@
                                    const DeclarationNameInfo &NameInfo,
                                    QualType T, TypeSourceInfo *TInfo,
                                    StorageClass SC,
-                                   bool isInlineSpecified, 
+                                   bool isInlineSpecified,
                                    bool hasWrittenPrototype,
                                    bool isConstexprSpecified) {
-  FunctionDecl *New = new (C) FunctionDecl(Function, DC, StartLoc, NameInfo,
-                                           T, TInfo, SC,
-                                           isInlineSpecified,
-                                           isConstexprSpecified);
+  FunctionDecl *New =
+      new (C, DC) FunctionDecl(Function, C, DC, StartLoc, NameInfo, T, TInfo,
+                               SC, isInlineSpecified, isConstexprSpecified);
   New->HasWrittenPrototype = hasWrittenPrototype;
   return New;
 }
 
 FunctionDecl *FunctionDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FunctionDecl));
-  return new (Mem) FunctionDecl(Function, 0, SourceLocation(), 
-                                DeclarationNameInfo(), QualType(), 0,
-                                SC_None, false, false);
+  return new (C, ID) FunctionDecl(Function, C, nullptr, SourceLocation(),
+                                  DeclarationNameInfo(), QualType(), nullptr,
+                                  SC_None, false, false);
 }
 
 BlockDecl *BlockDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) {
-  return new (C) BlockDecl(DC, L);
+  return new (C, DC) BlockDecl(DC, L);
 }
 
 BlockDecl *BlockDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(BlockDecl));
-  return new (Mem) BlockDecl(0, SourceLocation());
-}
-
-MSPropertyDecl *MSPropertyDecl::CreateDeserialized(ASTContext &C,
-                                                   unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(MSPropertyDecl));
-  return new (Mem) MSPropertyDecl(0, SourceLocation(), DeclarationName(),
-                                  QualType(), 0, SourceLocation(),
-                                  0, 0);
+  return new (C, ID) BlockDecl(nullptr, SourceLocation());
 }
 
 CapturedDecl *CapturedDecl::Create(ASTContext &C, DeclContext *DC,
                                    unsigned NumParams) {
-  unsigned Size = sizeof(CapturedDecl) + NumParams * sizeof(ImplicitParamDecl*);
-  return new (C.Allocate(Size)) CapturedDecl(DC, NumParams);
+  return new (C, DC, NumParams * sizeof(ImplicitParamDecl *))
+      CapturedDecl(DC, NumParams);
 }
 
 CapturedDecl *CapturedDecl::CreateDeserialized(ASTContext &C, unsigned ID,
-                                   unsigned NumParams) {
-  unsigned Size = sizeof(CapturedDecl) + NumParams * sizeof(ImplicitParamDecl*);
-  void *Mem = AllocateDeserializedDecl(C, ID, Size);
-  return new (Mem) CapturedDecl(0, NumParams);
+                                               unsigned NumParams) {
+  return new (C, ID, NumParams * sizeof(ImplicitParamDecl *))
+      CapturedDecl(nullptr, NumParams);
 }
 
 EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD,
                                            SourceLocation L,
                                            IdentifierInfo *Id, QualType T,
                                            Expr *E, const llvm::APSInt &V) {
-  return new (C) EnumConstantDecl(CD, L, Id, T, E, V);
+  return new (C, CD) EnumConstantDecl(CD, L, Id, T, E, V);
 }
 
 EnumConstantDecl *
 EnumConstantDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(EnumConstantDecl));
-  return new (Mem) EnumConstantDecl(0, SourceLocation(), 0, QualType(), 0, 
-                                    llvm::APSInt());
+  return new (C, ID) EnumConstantDecl(nullptr, SourceLocation(), nullptr,
+                                      QualType(), nullptr, llvm::APSInt());
 }
 
 void IndirectFieldDecl::anchor() { }
@@ -3598,14 +3742,14 @@
 IndirectFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
                           IdentifierInfo *Id, QualType T, NamedDecl **CH,
                           unsigned CHS) {
-  return new (C) IndirectFieldDecl(DC, L, Id, T, CH, CHS);
+  return new (C, DC) IndirectFieldDecl(DC, L, Id, T, CH, CHS);
 }
 
 IndirectFieldDecl *IndirectFieldDecl::CreateDeserialized(ASTContext &C,
                                                          unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(IndirectFieldDecl));
-  return new (Mem) IndirectFieldDecl(0, SourceLocation(), DeclarationName(),
-                                     QualType(), 0, 0);
+  return new (C, ID) IndirectFieldDecl(nullptr, SourceLocation(),
+                                       DeclarationName(), QualType(), nullptr,
+                                       0);
 }
 
 SourceRange EnumConstantDecl::getSourceRange() const {
@@ -3620,26 +3764,26 @@
 TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *DC,
                                  SourceLocation StartLoc, SourceLocation IdLoc,
                                  IdentifierInfo *Id, TypeSourceInfo *TInfo) {
-  return new (C) TypedefDecl(DC, StartLoc, IdLoc, Id, TInfo);
+  return new (C, DC) TypedefDecl(C, DC, StartLoc, IdLoc, Id, TInfo);
 }
 
 void TypedefNameDecl::anchor() { }
 
 TypedefDecl *TypedefDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TypedefDecl));
-  return new (Mem) TypedefDecl(0, SourceLocation(), SourceLocation(), 0, 0);
+  return new (C, ID) TypedefDecl(C, nullptr, SourceLocation(), SourceLocation(),
+                                 nullptr, nullptr);
 }
 
 TypeAliasDecl *TypeAliasDecl::Create(ASTContext &C, DeclContext *DC,
                                      SourceLocation StartLoc,
                                      SourceLocation IdLoc, IdentifierInfo *Id,
                                      TypeSourceInfo *TInfo) {
-  return new (C) TypeAliasDecl(DC, StartLoc, IdLoc, Id, TInfo);
+  return new (C, DC) TypeAliasDecl(C, DC, StartLoc, IdLoc, Id, TInfo);
 }
 
 TypeAliasDecl *TypeAliasDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TypeAliasDecl));
-  return new (Mem) TypeAliasDecl(0, SourceLocation(), SourceLocation(), 0, 0);
+  return new (C, ID) TypeAliasDecl(C, nullptr, SourceLocation(),
+                                   SourceLocation(), nullptr, nullptr);
 }
 
 SourceRange TypedefDecl::getSourceRange() const {
@@ -3664,24 +3808,23 @@
                                            StringLiteral *Str,
                                            SourceLocation AsmLoc,
                                            SourceLocation RParenLoc) {
-  return new (C) FileScopeAsmDecl(DC, Str, AsmLoc, RParenLoc);
+  return new (C, DC) FileScopeAsmDecl(DC, Str, AsmLoc, RParenLoc);
 }
 
-FileScopeAsmDecl *FileScopeAsmDecl::CreateDeserialized(ASTContext &C, 
+FileScopeAsmDecl *FileScopeAsmDecl::CreateDeserialized(ASTContext &C,
                                                        unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FileScopeAsmDecl));
-  return new (Mem) FileScopeAsmDecl(0, 0, SourceLocation(), SourceLocation());
+  return new (C, ID) FileScopeAsmDecl(nullptr, nullptr, SourceLocation(),
+                                      SourceLocation());
 }
 
 void EmptyDecl::anchor() {}
 
 EmptyDecl *EmptyDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) {
-  return new (C) EmptyDecl(DC, L);
+  return new (C, DC) EmptyDecl(DC, L);
 }
 
 EmptyDecl *EmptyDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(EmptyDecl));
-  return new (Mem) EmptyDecl(0, SourceLocation());
+  return new (C, ID) EmptyDecl(nullptr, SourceLocation());
 }
 
 //===----------------------------------------------------------------------===//
@@ -3719,30 +3862,28 @@
   *reinterpret_cast<SourceLocation *>(this + 1) = EndLoc;
 }
 
-ImportDecl *ImportDecl::Create(ASTContext &C, DeclContext *DC, 
+ImportDecl *ImportDecl::Create(ASTContext &C, DeclContext *DC,
                                SourceLocation StartLoc, Module *Imported,
                                ArrayRef<SourceLocation> IdentifierLocs) {
-  void *Mem = C.Allocate(sizeof(ImportDecl) + 
-                         IdentifierLocs.size() * sizeof(SourceLocation));
-  return new (Mem) ImportDecl(DC, StartLoc, Imported, IdentifierLocs);
+  return new (C, DC, IdentifierLocs.size() * sizeof(SourceLocation))
+      ImportDecl(DC, StartLoc, Imported, IdentifierLocs);
 }
 
-ImportDecl *ImportDecl::CreateImplicit(ASTContext &C, DeclContext *DC, 
+ImportDecl *ImportDecl::CreateImplicit(ASTContext &C, DeclContext *DC,
                                        SourceLocation StartLoc,
-                                       Module *Imported, 
+                                       Module *Imported,
                                        SourceLocation EndLoc) {
-  void *Mem = C.Allocate(sizeof(ImportDecl) + sizeof(SourceLocation));
-  ImportDecl *Import = new (Mem) ImportDecl(DC, StartLoc, Imported, EndLoc);
+  ImportDecl *Import =
+      new (C, DC, sizeof(SourceLocation)) ImportDecl(DC, StartLoc,
+                                                     Imported, EndLoc);
   Import->setImplicit();
   return Import;
 }
 
 ImportDecl *ImportDecl::CreateDeserialized(ASTContext &C, unsigned ID,
                                            unsigned NumLocations) {
-  void *Mem = AllocateDeserializedDecl(C, ID, 
-                                       (sizeof(ImportDecl) + 
-                                        NumLocations * sizeof(SourceLocation)));
-  return new (Mem) ImportDecl(EmptyShell());  
+  return new (C, ID, NumLocations * sizeof(SourceLocation))
+      ImportDecl(EmptyShell());
 }
 
 ArrayRef<SourceLocation> ImportDecl::getIdentifierLocs() const {
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index 121c5a6..2b1506d 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -45,25 +45,30 @@
   getASTContext().getExternalSource()->updateOutOfDateIdentifier(II);
 }
 
-void *Decl::AllocateDeserializedDecl(const ASTContext &Context, 
-                                     unsigned ID,
-                                     unsigned Size) {
+void *Decl::operator new(std::size_t Size, const ASTContext &Context,
+                         unsigned ID, std::size_t Extra) {
   // Allocate an extra 8 bytes worth of storage, which ensures that the
   // resulting pointer will still be 8-byte aligned. 
-  void *Start = Context.Allocate(Size + 8);
+  void *Start = Context.Allocate(Size + Extra + 8);
   void *Result = (char*)Start + 8;
-  
+
   unsigned *PrefixPtr = (unsigned *)Result - 2;
-  
+
   // Zero out the first 4 bytes; this is used to store the owning module ID.
   PrefixPtr[0] = 0;
-  
+
   // Store the global declaration ID in the second 4 bytes.
   PrefixPtr[1] = ID;
-  
+
   return Result;
 }
 
+void *Decl::operator new(std::size_t Size, const ASTContext &Ctx,
+                         DeclContext *Parent, std::size_t Extra) {
+  assert(!Parent || &Parent->getParentASTContext() == &Ctx);
+  return ::operator new(Size + Extra, Ctx);
+}
+
 Module *Decl::getOwningModuleSlow() const {
   assert(isFromASTFile() && "Not from AST file?");
   return getASTContext().getExternalSource()->getModule(getOwningModuleID());
@@ -80,6 +85,7 @@
 
 void Decl::setInvalidDecl(bool Invalid) {
   InvalidDecl = Invalid;
+  assert(!isa<TagDecl>(this) || !cast<TagDecl>(this)->isCompleteDefinition());
   if (Invalid && !isa<ParmVarDecl>(this)) {
     // Defensive maneuver for ill-formed code: we're likely not to make it to
     // a point where we set the access specifier, so default it to "public"
@@ -153,11 +159,12 @@
   return isTemplateParameterPack();
 }
 
-bool Decl::isFunctionOrFunctionTemplate() const {
-  if (const UsingShadowDecl *UD = dyn_cast<UsingShadowDecl>(this))
-    return UD->getTargetDecl()->isFunctionOrFunctionTemplate();
-
-  return isa<FunctionDecl>(this) || isa<FunctionTemplateDecl>(this);
+FunctionDecl *Decl::getAsFunction() {
+  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(this))
+    return FD;
+  if (const FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(this))
+    return FTD->getTemplatedDecl();
+  return nullptr;
 }
 
 bool Decl::isTemplateDecl() const {
@@ -171,7 +178,7 @@
     if (DC->isFunctionOrMethod())
       return DC;
 
-  return 0;
+  return nullptr;
 }
 
 
@@ -244,6 +251,10 @@
   return false;
 }
 
+bool Decl::isInStdNamespace() const {
+  return getDeclContext()->isStdNamespace();
+}
+
 TranslationUnitDecl *Decl::getTranslationUnitDecl() {
   if (TranslationUnitDecl *TUD = dyn_cast<TranslationUnitDecl>(this))
     return TUD;
@@ -306,7 +317,7 @@
     return true;
 
   // Check redeclarations.
-  for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I)
+  for (auto I : redecls())
     if (I->Referenced)
       return true;
 
@@ -401,8 +412,8 @@
   AvailabilityResult Result = AR_Available;
   std::string ResultMessage;
 
-  for (attr_iterator A = attr_begin(), AEnd = attr_end(); A != AEnd; ++A) {
-    if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
+  for (const auto *A : attrs()) {
+    if (const auto *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
       if (Result >= AR_Deprecated)
         continue;
 
@@ -413,13 +424,13 @@
       continue;
     }
 
-    if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
+    if (const auto *Unavailable = dyn_cast<UnavailableAttr>(A)) {
       if (Message)
         *Message = Unavailable->getMessage();
       return AR_Unavailable;
     }
 
-    if (AvailabilityAttr *Availability = dyn_cast<AvailabilityAttr>(*A)) {
+    if (const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
       AvailabilityResult AR = CheckAvailability(getASTContext(), Availability,
                                                 Message);
 
@@ -475,13 +486,13 @@
   if (!canBeWeakImported(IsDefinition))
     return false;
 
-  for (attr_iterator A = attr_begin(), AEnd = attr_end(); A != AEnd; ++A) {
-    if (isa<WeakImportAttr>(*A))
+  for (const auto *A : attrs()) {
+    if (isa<WeakImportAttr>(A))
       return true;
 
-    if (AvailabilityAttr *Availability = dyn_cast<AvailabilityAttr>(*A)) {
-      if (CheckAvailability(getASTContext(), Availability, 0) 
-                                                         == AR_NotYetIntroduced)
+    if (const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
+      if (CheckAvailability(getASTContext(), Availability,
+                            nullptr) == AR_NotYetIntroduced)
         return true;
     }
   }
@@ -662,7 +673,7 @@
   return SourceLocation();
 }
 
-void Decl::CheckAccessDeclContext() const {
+bool Decl::AccessDeclContextSanity() const {
 #ifndef NDEBUG
   // Suppress this check if any of the following hold:
   // 1. this is the translation unit (and thus has no parent)
@@ -684,16 +695,35 @@
       // AS_none as access specifier.
       isa<CXXRecordDecl>(this) ||
       isa<ClassScopeFunctionSpecializationDecl>(this))
-    return;
+    return true;
 
   assert(Access != AS_none &&
          "Access specifier is AS_none inside a record decl");
 #endif
+  return true;
 }
 
 static Decl::Kind getKind(const Decl *D) { return D->getKind(); }
 static Decl::Kind getKind(const DeclContext *DC) { return DC->getDeclKind(); }
 
+const FunctionType *Decl::getFunctionType(bool BlocksToo) const {
+  QualType Ty;
+  if (const ValueDecl *D = dyn_cast<ValueDecl>(this))
+    Ty = D->getType();
+  else if (const TypedefNameDecl *D = dyn_cast<TypedefNameDecl>(this))
+    Ty = D->getUnderlyingType();
+  else
+    return nullptr;
+
+  if (Ty->isFunctionPointerType())
+    Ty = Ty->getAs<PointerType>()->getPointeeType();
+  else if (BlocksToo && Ty->isBlockPointerType())
+    Ty = Ty->getAs<BlockPointerType>()->getPointeeType();
+
+  return Ty->getAs<FunctionType>();
+}
+
+
 /// Starting at a given context (a Decl or DeclContext), look for a
 /// code context that is not a closure (a lambda, block, etc.).
 template <class T> static Decl *getNonClosureContext(T *D) {
@@ -712,7 +742,7 @@
   } else if (CapturedDecl *CD = dyn_cast<CapturedDecl>(D)) {
     return getNonClosureContext(CD->getParent());
   } else {
-    return 0;
+    return nullptr;
   }
 }
 
@@ -769,6 +799,22 @@
          cast<NamespaceDecl>(this)->isInline();
 }
 
+bool DeclContext::isStdNamespace() const {
+  if (!isNamespace())
+    return false;
+
+  const NamespaceDecl *ND = cast<NamespaceDecl>(this);
+  if (ND->isInline()) {
+    return ND->getParent()->isStdNamespace();
+  }
+
+  if (!getParent()->getRedeclContext()->isTranslationUnit())
+    return false;
+
+  const IdentifierInfo *II = ND->getIdentifier();
+  return II && II->isStr("std");
+}
+
 bool DeclContext::isDependentContext() const {
   if (isFileContext())
     return false;
@@ -811,7 +857,7 @@
   while (DC->getDeclKind() != Decl::TranslationUnit) {
     if (DC->getDeclKind() == Decl::LinkageSpec)
       return cast<LinkageSpecDecl>(DC)->getLanguage() == ID;
-    DC = DC->getParent();
+    DC = DC->getLexicalParent();
   }
   return false;
 }
@@ -874,18 +920,17 @@
       // If this is a tag type that has a definition or is currently
       // being defined, that definition is our primary context.
       TagDecl *Tag = cast<TagDecl>(this);
-      assert(isa<TagType>(Tag->TypeForDecl) ||
-             isa<InjectedClassNameType>(Tag->TypeForDecl));
 
       if (TagDecl *Def = Tag->getDefinition())
         return Def;
 
-      if (!isa<InjectedClassNameType>(Tag->TypeForDecl)) {
-        const TagType *TagTy = cast<TagType>(Tag->TypeForDecl);
-        if (TagTy->isBeingDefined())
-          // FIXME: is it necessarily being defined in the decl
-          // that owns the type?
-          return TagTy->getDecl();
+      if (const TagType *TagTy = dyn_cast<TagType>(Tag->getTypeForDecl())) {
+        // Note, TagType::getDecl returns the (partial) definition one exists.
+        TagDecl *PossiblePartialDef = TagTy->getDecl();
+        if (PossiblePartialDef->isBeingDefined())
+          return PossiblePartialDef;
+      } else {
+        assert(isa<InjectedClassNameType>(Tag->getTypeForDecl()));
       }
 
       return Tag;
@@ -918,8 +963,8 @@
 DeclContext::BuildDeclChain(ArrayRef<Decl*> Decls,
                             bool FieldsAlreadyLoaded) {
   // Build up a chain of declarations via the Decl::NextInContextAndBits field.
-  Decl *FirstNewDecl = 0;
-  Decl *PrevDecl = 0;
+  Decl *FirstNewDecl = nullptr;
+  Decl *PrevDecl = nullptr;
   for (unsigned I = 0, N = Decls.size(); I != N; ++I) {
     if (FieldsAlreadyLoaded && isa<FieldDecl>(Decls[I]))
       continue;
@@ -939,13 +984,12 @@
 /// \brief We have just acquired external visible storage, and we already have
 /// built a lookup map. For every name in the map, pull in the new names from
 /// the external storage.
-void DeclContext::reconcileExternalVisibleStorage() {
+void DeclContext::reconcileExternalVisibleStorage() const {
   assert(NeedToReconcileExternalVisibleStorage && LookupPtr.getPointer());
   NeedToReconcileExternalVisibleStorage = false;
 
-  StoredDeclsMap &Map = *LookupPtr.getPointer();
-  for (StoredDeclsMap::iterator I = Map.begin(); I != Map.end(); ++I)
-    I->second.setHasExternalDecls();
+  for (auto &Lookup : *LookupPtr.getPointer())
+    Lookup.second.setHasExternalDecls();
 }
 
 /// \brief Load the declarations within this lexical storage from an
@@ -982,8 +1026,8 @@
   // Splice the newly-read declarations into the beginning of the list
   // of declarations.
   Decl *ExternalFirst, *ExternalLast;
-  llvm::tie(ExternalFirst, ExternalLast) = BuildDeclChain(Decls,
-                                                          FieldsAlreadyLoaded);
+  std::tie(ExternalFirst, ExternalLast) =
+      BuildDeclChain(Decls, FieldsAlreadyLoaded);
   ExternalLast->NextInContextAndBits.setPointer(FirstDecl);
   FirstDecl = ExternalFirst;
   if (!LastDecl)
@@ -997,6 +1041,8 @@
   StoredDeclsMap *Map;
   if (!(Map = DC->LookupPtr.getPointer()))
     Map = DC->CreateStoredDeclsMap(Context);
+  if (DC->NeedToReconcileExternalVisibleStorage)
+    DC->reconcileExternalVisibleStorage();
 
   (*Map)[Name].removeExternalDecls();
 
@@ -1011,6 +1057,8 @@
   StoredDeclsMap *Map;
   if (!(Map = DC->LookupPtr.getPointer()))
     Map = DC->CreateStoredDeclsMap(Context);
+  if (DC->NeedToReconcileExternalVisibleStorage)
+    DC->reconcileExternalVisibleStorage();
 
   StoredDeclsList &List = (*Map)[Name];
 
@@ -1050,14 +1098,9 @@
   return List.getLookupResult();
 }
 
-DeclContext::decl_iterator DeclContext::noload_decls_begin() const {
-  return decl_iterator(FirstDecl);
-}
-
 DeclContext::decl_iterator DeclContext::decls_begin() const {
   if (hasExternalLexicalStorage())
     LoadLexicalDeclsFromExternalStorage();
-
   return decl_iterator(FirstDecl);
 }
 
@@ -1082,7 +1125,7 @@
   // Remove D from the decl chain.  This is O(n) but hopefully rare.
   if (D == FirstDecl) {
     if (D == LastDecl)
-      FirstDecl = LastDecl = 0;
+      FirstDecl = LastDecl = nullptr;
     else
       FirstDecl = D->NextInContextAndBits.getPointer();
   } else {
@@ -1097,7 +1140,7 @@
   }
   
   // Mark that D is no longer in the decl chain.
-  D->NextInContextAndBits.setPointer(0);
+  D->NextInContextAndBits.setPointer(nullptr);
 
   // Remove D from the lookup table if necessary.
   if (isa<NamedDecl>(D)) {
@@ -1187,6 +1230,10 @@
 /// buildLookup - Build the lookup data structure with all of the
 /// declarations in this DeclContext (and any other contexts linked
 /// to it or transparent contexts nested within it) and return it.
+///
+/// Note that the produced map may miss out declarations from an
+/// external source. If it does, those entries will be marked with
+/// the 'hasExternalDecls' flag.
 StoredDeclsMap *DeclContext::buildLookup() {
   assert(this == getPrimaryContext() && "buildLookup called on non-primary DC");
 
@@ -1202,7 +1249,6 @@
 
   // We no longer have any lazy decls.
   LookupPtr.setInt(false);
-  NeedToReconcileExternalVisibleStorage = false;
   return LookupPtr.getPointer();
 }
 
@@ -1251,11 +1297,13 @@
     return PrimaryContext->lookup(Name);
 
   if (hasExternalVisibleStorage()) {
+    if (NeedToReconcileExternalVisibleStorage)
+      reconcileExternalVisibleStorage();
+
     StoredDeclsMap *Map = LookupPtr.getPointer();
+
     if (LookupPtr.getInt())
       Map = buildLookup();
-    else if (NeedToReconcileExternalVisibleStorage)
-      reconcileExternalVisibleStorage();
 
     if (!Map)
       Map = CreateStoredDeclsMap(getParentASTContext());
@@ -1267,7 +1315,7 @@
       return R.first->second.getLookupResult();
 
     ExternalASTSource *Source = getParentASTContext().getExternalSource();
-    if (Source->FindExternalVisibleDeclsByName(this, Name) || R.second) {
+    if (Source->FindExternalVisibleDeclsByName(this, Name) || !R.second) {
       if (StoredDeclsMap *Map = LookupPtr.getPointer()) {
         StoredDeclsMap::iterator I = Map->find(Name);
         if (I != Map->end())
@@ -1275,7 +1323,7 @@
       }
     }
 
-    return lookup_result(lookup_iterator(0), lookup_iterator(0));
+    return lookup_result(lookup_iterator(nullptr), lookup_iterator(nullptr));
   }
 
   StoredDeclsMap *Map = LookupPtr.getPointer();
@@ -1283,11 +1331,11 @@
     Map = buildLookup();
 
   if (!Map)
-    return lookup_result(lookup_iterator(0), lookup_iterator(0));
+    return lookup_result(lookup_iterator(nullptr), lookup_iterator(nullptr));
 
   StoredDeclsMap::iterator I = Map->find(Name);
   if (I == Map->end())
-    return lookup_result(lookup_iterator(0), lookup_iterator(0));
+    return lookup_result(lookup_iterator(nullptr), lookup_iterator(nullptr));
 
   return I->second.getLookupResult();
 }
@@ -1324,12 +1372,12 @@
   }
 
   if (!Map)
-    return lookup_result(lookup_iterator(0), lookup_iterator(0));
+    return lookup_result(lookup_iterator(nullptr), lookup_iterator(nullptr));
 
   StoredDeclsMap::iterator I = Map->find(Name);
-  return I != Map->end()
-             ? I->second.getLookupResult()
-             : lookup_result(lookup_iterator(0), lookup_iterator(0));
+  return I != Map->end() ? I->second.getLookupResult()
+                         : lookup_result(lookup_iterator(nullptr),
+                                         lookup_iterator(nullptr));
 }
 
 void DeclContext::localUncachedLookup(DeclarationName Name,
@@ -1502,13 +1550,13 @@
 
 /// Returns iterator range [First, Last) of UsingDirectiveDecls stored within
 /// this context.
-DeclContext::udir_iterator_range
-DeclContext::getUsingDirectives() const {
+DeclContext::udir_range DeclContext::using_directives() const {
   // FIXME: Use something more efficient than normal lookup for using
   // directives. In C++, using directives are looked up more than anything else.
   lookup_const_result Result = lookup(UsingDirectiveDecl::getName());
-  return udir_iterator_range(reinterpret_cast<udir_iterator>(Result.begin()),
-                             reinterpret_cast<udir_iterator>(Result.end()));
+  return udir_range(
+      reinterpret_cast<UsingDirectiveDecl *const *>(Result.begin()),
+      reinterpret_cast<UsingDirectiveDecl *const *>(Result.end()));
 }
 
 //===----------------------------------------------------------------------===//
@@ -1568,7 +1616,7 @@
 
   // Allocate the copy of the PartialDiagnostic via the ASTContext's
   // BumpPtrAllocator, rather than the ASTContext itself.
-  PartialDiagnostic::Storage *DiagStorage = 0;
+  PartialDiagnostic::Storage *DiagStorage = nullptr;
   if (PDiag.hasStorage())
     DiagStorage = new (C) PartialDiagnostic::Storage;
   
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index b7f0fab..ed26c52 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -31,8 +31,7 @@
 void AccessSpecDecl::anchor() { }
 
 AccessSpecDecl *AccessSpecDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(AccessSpecDecl));
-  return new (Mem) AccessSpecDecl(EmptyShell());
+  return new (C, ID) AccessSpecDecl(EmptyShell());
 }
 
 void LazyASTUnresolvedSet::getFromExternalSource(ASTContext &C) const {
@@ -51,7 +50,7 @@
     Aggregate(true), PlainOldData(true), Empty(true), Polymorphic(false),
     Abstract(false), IsStandardLayout(true), HasNoNonEmptyBases(true),
     HasPrivateFields(false), HasProtectedFields(false), HasPublicFields(false),
-    HasMutableFields(false), HasOnlyCMembers(true),
+    HasMutableFields(false), HasVariantMembers(false), HasOnlyCMembers(true),
     HasInClassInitializer(false), HasUninitializedReferenceMember(false),
     NeedOverloadResolutionForMoveConstructor(false),
     NeedOverloadResolutionForMoveAssignment(false),
@@ -71,7 +70,8 @@
     ImplicitCopyAssignmentHasConstParam(true),
     HasDeclaredCopyConstructorWithConstParam(false),
     HasDeclaredCopyAssignmentWithConstParam(false),
-    IsLambda(false), NumBases(0), NumVBases(0), Bases(), VBases(),
+    IsLambda(false), IsParsingBaseSpecifiers(false), NumBases(0), NumVBases(0),
+    Bases(), VBases(),
     Definition(D), FirstFriend() {
 }
 
@@ -83,20 +83,22 @@
   return VBases.get(Definition->getASTContext().getExternalSource());
 }
 
-CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
-                             SourceLocation StartLoc, SourceLocation IdLoc,
-                             IdentifierInfo *Id, CXXRecordDecl *PrevDecl)
-  : RecordDecl(K, TK, DC, StartLoc, IdLoc, Id, PrevDecl),
-    DefinitionData(PrevDecl ? PrevDecl->DefinitionData : 0),
-    TemplateOrInstantiation() { }
+CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, const ASTContext &C,
+                             DeclContext *DC, SourceLocation StartLoc,
+                             SourceLocation IdLoc, IdentifierInfo *Id,
+                             CXXRecordDecl *PrevDecl)
+    : RecordDecl(K, TK, C, DC, StartLoc, IdLoc, Id, PrevDecl),
+      DefinitionData(PrevDecl ? PrevDecl->DefinitionData
+                              : DefinitionDataPtr(this)),
+      TemplateOrInstantiation() {}
 
 CXXRecordDecl *CXXRecordDecl::Create(const ASTContext &C, TagKind TK,
                                      DeclContext *DC, SourceLocation StartLoc,
                                      SourceLocation IdLoc, IdentifierInfo *Id,
                                      CXXRecordDecl* PrevDecl,
                                      bool DelayTypeCreation) {
-  CXXRecordDecl* R = new (C) CXXRecordDecl(CXXRecord, TK, DC, StartLoc, IdLoc,
-                                           Id, PrevDecl);
+  CXXRecordDecl *R = new (C, DC) CXXRecordDecl(CXXRecord, TK, C, DC, StartLoc,
+                                               IdLoc, Id, PrevDecl);
   R->MayHaveOutOfDateDef = C.getLangOpts().Modules;
 
   // FIXME: DelayTypeCreation seems like such a hack
@@ -105,29 +107,29 @@
   return R;
 }
 
-CXXRecordDecl *CXXRecordDecl::CreateLambda(const ASTContext &C, DeclContext *DC,
-                                           TypeSourceInfo *Info, SourceLocation Loc,
-                                           bool Dependent, bool IsGeneric, 
-                                           LambdaCaptureDefault CaptureDefault) {
-  CXXRecordDecl* R = new (C) CXXRecordDecl(CXXRecord, TTK_Class, DC, Loc, Loc,
-                                           0, 0);
+CXXRecordDecl *
+CXXRecordDecl::CreateLambda(const ASTContext &C, DeclContext *DC,
+                            TypeSourceInfo *Info, SourceLocation Loc,
+                            bool Dependent, bool IsGeneric,
+                            LambdaCaptureDefault CaptureDefault) {
+  CXXRecordDecl *R =
+      new (C, DC) CXXRecordDecl(CXXRecord, TTK_Class, C, DC, Loc, Loc,
+                                nullptr, nullptr);
   R->IsBeingDefined = true;
-  R->DefinitionData = new (C) struct LambdaDefinitionData(R, Info, 
-                                                          Dependent, 
-                                                          IsGeneric, 
-                                                          CaptureDefault);
+  R->DefinitionData =
+      new (C) struct LambdaDefinitionData(R, Info, Dependent, IsGeneric,
+                                          CaptureDefault);
   R->MayHaveOutOfDateDef = false;
   R->setImplicit(true);
-  C.getTypeDeclType(R, /*PrevDecl=*/0);
+  C.getTypeDeclType(R, /*PrevDecl=*/nullptr);
   return R;
 }
 
 CXXRecordDecl *
 CXXRecordDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(CXXRecordDecl));
-  CXXRecordDecl *R = new (Mem) CXXRecordDecl(CXXRecord, TTK_Struct, 0,
-                                             SourceLocation(), SourceLocation(),
-                                             0, 0);
+  CXXRecordDecl *R = new (C, ID) CXXRecordDecl(
+      CXXRecord, TTK_Struct, C, nullptr, SourceLocation(), SourceLocation(),
+      nullptr, nullptr);
   R->MayHaveOutOfDateDef = false;
   return R;
 }
@@ -205,19 +207,17 @@
       data().HasNonLiteralTypeFieldsOrBases = true;
     
     // Now go through all virtual bases of this base and add them.
-    for (CXXRecordDecl::base_class_iterator VBase =
-          BaseClassDecl->vbases_begin(),
-         E = BaseClassDecl->vbases_end(); VBase != E; ++VBase) {
+    for (const auto &VBase : BaseClassDecl->vbases()) {
       // Add this base if it's not already in the list.
-      if (SeenVBaseTypes.insert(C.getCanonicalType(VBase->getType()))) {
-        VBases.push_back(VBase);
+      if (SeenVBaseTypes.insert(C.getCanonicalType(VBase.getType()))) {
+        VBases.push_back(&VBase);
 
         // C++11 [class.copy]p8:
         //   The implicitly-declared copy constructor for a class X will have
         //   the form 'X::X(const X&)' if each [...] virtual base class B of X
         //   has a copy constructor whose first parameter is of type
         //   'const B&' or 'const volatile B&' [...]
-        if (CXXRecordDecl *VBaseDecl = VBase->getType()->getAsCXXRecordDecl())
+        if (CXXRecordDecl *VBaseDecl = VBase.getType()->getAsCXXRecordDecl())
           if (!VBaseDecl->hasCopyConstructorWithConstParam())
             data().ImplicitCopyConstructorHasConstParam = false;
       }
@@ -335,8 +335,10 @@
     addedClassSubobject(BaseClassDecl);
   }
   
-  if (VBases.empty())
+  if (VBases.empty()) {
+    data().IsParsingBaseSpecifiers = false;
     return;
+  }
 
   // Create base specifier for any direct or indirect virtual bases.
   data().VBases = new (C) CXXBaseSpecifier[VBases.size()];
@@ -347,6 +349,8 @@
       addedClassSubobject(Type->getAsCXXRecordDecl());
     data().getVBases()[I] = *VBases[I];
   }
+
+  data().IsParsingBaseSpecifiers = false;
 }
 
 void CXXRecordDecl::addedClassSubobject(CXXRecordDecl *Subobj) {
@@ -391,7 +395,7 @@
   if (!isDependentContext())
     return false;
 
-  return !forallBases(SawBase, 0);
+  return !forallBases(SawBase, nullptr);
 }
 
 bool CXXRecordDecl::isTriviallyCopyable() const {
@@ -532,8 +536,11 @@
   if (CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(D)) {
     SMKind |= SMF_Destructor;
 
-    if (!DD->isImplicit())
+    if (DD->isUserProvided())
       data().HasIrrelevantDestructor = false;
+    // If the destructor is explicitly defaulted and not trivial or not public
+    // or if the destructor is deleted, we clear HasIrrelevantDestructor in
+    // finishedDefaultedOrDeletedMember.
 
     // C++11 [class.dtor]p5:
     //   A destructor is trivial if [...] the destructor is not virtual.
@@ -656,7 +663,13 @@
     // Keep track of the presence of mutable fields.
     if (Field->isMutable())
       data().HasMutableFields = true;
-    
+
+    // C++11 [class.union]p8, DR1460:
+    //   If X is a union, a non-static data member of X that is not an anonymous
+    //   union is a variant member of X.
+    if (isUnion() && !Field->isAnonymousStructOrUnion())
+      data().HasVariantMembers = true;
+
     // C++0x [class]p9:
     //   A POD struct is a class that is both a trivial class and a 
     //   standard-layout class, and has no non-static data members of type 
@@ -692,7 +705,9 @@
     if (!T->isLiteralType(Context) || T.isVolatileQualified())
       data().HasNonLiteralTypeFieldsOrBases = true;
 
-    if (Field->hasInClassInitializer()) {
+    if (Field->hasInClassInitializer() ||
+        (Field->isAnonymousStructOrUnion() &&
+         Field->getType()->getAsCXXRecordDecl()->hasInClassInitializer())) {
       data().HasInClassInitializer = true;
 
       // C++11 [class]p5:
@@ -725,6 +740,13 @@
       if (FieldRec->getDefinition()) {
         addedClassSubobject(FieldRec);
 
+        // We may need to perform overload resolution to determine whether a
+        // field can be moved if it's const or volatile qualified.
+        if (T.getCVRQualifiers() & (Qualifiers::Const | Qualifiers::Volatile)) {
+          data().NeedOverloadResolutionForMoveConstructor = true;
+          data().NeedOverloadResolutionForMoveAssignment = true;
+        }
+
         // C++11 [class.ctor]p5, C++11 [class.copy]p11:
         //   A defaulted [special member] for a class X is defined as
         //   deleted if:
@@ -802,15 +824,13 @@
         // Virtual bases and virtual methods make a class non-empty, but they
         // also make it non-standard-layout so we needn't check here.
         // A non-empty base class may leave the class standard-layout, but not
-        // if we have arrived here, and have at least on non-static data
+        // if we have arrived here, and have at least one non-static data
         // member. If IsStandardLayout remains true, then the first non-static
         // data member must come through here with Empty still true, and Empty
         // will subsequently be set to false below.
         if (data().IsStandardLayout && data().Empty) {
-          for (CXXRecordDecl::base_class_const_iterator BI = bases_begin(),
-                                                        BE = bases_end();
-               BI != BE; ++BI) {
-            if (Context.hasSameUnqualifiedType(BI->getType(), T)) {
+          for (const auto &BI : bases()) {
+            if (Context.hasSameUnqualifiedType(BI.getType(), T)) {
               data().IsStandardLayout = false;
               break;
             }
@@ -855,6 +875,13 @@
         if (FieldRec->hasUninitializedReferenceMember() &&
             !Field->hasInClassInitializer())
           data().HasUninitializedReferenceMember = true;
+
+        // C++11 [class.union]p8, DR1460:
+        //   a non-static data member of an anonymous union that is a member of
+        //   X is also a variant member of X.
+        if (FieldRec->hasVariantMembers() &&
+            Field->isAnonymousStructOrUnion())
+          data().HasVariantMembers = true;
       }
     } else {
       // Base element type of field is a non-class type.
@@ -921,9 +948,11 @@
     else if (Constructor->isConstexpr())
       // We may now know that the constructor is constexpr.
       data().HasConstexprNonCopyMoveConstructor = true;
-  } else if (isa<CXXDestructorDecl>(D))
+  } else if (isa<CXXDestructorDecl>(D)) {
     SMKind |= SMF_Destructor;
-  else if (D->isCopyAssignmentOperator())
+    if (!D->isTrivial() || D->getAccess() != AS_public || D->isDeleted())
+      data().HasIrrelevantDestructor = false;
+  } else if (D->isCopyAssignmentOperator())
     SMKind |= SMF_CopyAssignment;
   else if (D->isMoveAssignmentOperator())
     SMKind |= SMF_MoveAssignment;
@@ -952,7 +981,7 @@
 }
 
 CXXMethodDecl* CXXRecordDecl::getLambdaCallOperator() const {
-  if (!isLambda()) return 0;
+  if (!isLambda()) return nullptr;
   DeclarationName Name = 
     getASTContext().DeclarationNames.getCXXOperatorName(OO_Call);
   DeclContext::lookup_const_result Calls = lookup(Name);
@@ -969,11 +998,11 @@
 }
 
 CXXMethodDecl* CXXRecordDecl::getLambdaStaticInvoker() const {
-  if (!isLambda()) return 0;
+  if (!isLambda()) return nullptr;
   DeclarationName Name = 
     &getASTContext().Idents.get(getLambdaStaticInvokerName());
   DeclContext::lookup_const_result Invoker = lookup(Name);
-  if (Invoker.empty()) return 0;
+  if (Invoker.empty()) return nullptr;
   assert(Invoker.size() == 1 && "More than one static invoker operator!");  
   NamedDecl *InvokerFun = Invoker.front();
   if (FunctionTemplateDecl *InvokerTemplate =
@@ -987,11 +1016,11 @@
        llvm::DenseMap<const VarDecl *, FieldDecl *> &Captures,
        FieldDecl *&ThisCapture) const {
   Captures.clear();
-  ThisCapture = 0;
+  ThisCapture = nullptr;
 
   LambdaDefinitionData &Lambda = getLambdaData();
   RecordDecl::field_iterator Field = field_begin();
-  for (LambdaExpr::Capture *C = Lambda.Captures, *CEnd = C + Lambda.NumCaptures;
+  for (const LambdaCapture *C = Lambda.Captures, *CEnd = C + Lambda.NumCaptures;
        C != CEnd; ++C, ++Field) {
     if (C->capturesThis())
       ThisCapture = *Field;
@@ -1003,21 +1032,17 @@
 
 TemplateParameterList * 
 CXXRecordDecl::getGenericLambdaTemplateParameterList() const {
-  if (!isLambda()) return 0;
+  if (!isLambda()) return nullptr;
   CXXMethodDecl *CallOp = getLambdaCallOperator();     
   if (FunctionTemplateDecl *Tmpl = CallOp->getDescribedFunctionTemplate())
     return Tmpl->getTemplateParameters();
-  return 0;
+  return nullptr;
 }
 
 static CanQualType GetConversionType(ASTContext &Context, NamedDecl *Conv) {
-  QualType T;
-  if (isa<UsingShadowDecl>(Conv))
-    Conv = cast<UsingShadowDecl>(Conv)->getTargetDecl();
-  if (FunctionTemplateDecl *ConvTemp = dyn_cast<FunctionTemplateDecl>(Conv))
-    T = ConvTemp->getTemplatedDecl()->getResultType();
-  else 
-    T = cast<CXXConversionDecl>(Conv)->getConversionType();
+  QualType T =
+      cast<CXXConversionDecl>(Conv->getUnderlyingDecl()->getAsFunction())
+          ->getConversionType();
   return Context.getCanonicalType(T);
 }
 
@@ -1080,14 +1105,13 @@
   }
 
   // Collect information recursively from any base classes.
-  for (CXXRecordDecl::base_class_iterator
-         I = Record->bases_begin(), E = Record->bases_end(); I != E; ++I) {
-    const RecordType *RT = I->getType()->getAs<RecordType>();
+  for (const auto &I : Record->bases()) {
+    const RecordType *RT = I.getType()->getAs<RecordType>();
     if (!RT) continue;
 
     AccessSpecifier BaseAccess
-      = CXXRecordDecl::MergeAccess(Access, I->getAccessSpecifier());
-    bool BaseInVirtual = InVirtual || I->isVirtual();
+      = CXXRecordDecl::MergeAccess(Access, I.getAccessSpecifier());
+    bool BaseInVirtual = InVirtual || I.isVirtual();
 
     CXXRecordDecl *Base = cast<CXXRecordDecl>(RT->getDecl());
     CollectVisibleConversions(Context, Base, BaseInVirtual, BaseAccess,
@@ -1123,13 +1147,12 @@
     HiddenTypes.insert(GetConversionType(Context, ConvI.getDecl()));
 
   // Recursively collect conversions from base classes.
-  for (CXXRecordDecl::base_class_iterator
-         I = Record->bases_begin(), E = Record->bases_end(); I != E; ++I) {
-    const RecordType *RT = I->getType()->getAs<RecordType>();
+  for (const auto &I : Record->bases()) {
+    const RecordType *RT = I.getType()->getAs<RecordType>();
     if (!RT) continue;
 
     CollectVisibleConversions(Context, cast<CXXRecordDecl>(RT->getDecl()),
-                              I->isVirtual(), I->getAccessSpecifier(),
+                              I.isVirtual(), I.getAccessSpecifier(),
                               HiddenTypes, Output, VBaseCs, HiddenVBaseCs);
   }
 
@@ -1190,8 +1213,8 @@
 CXXRecordDecl *CXXRecordDecl::getInstantiatedFromMemberClass() const {
   if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo())
     return cast<CXXRecordDecl>(MSInfo->getInstantiatedFrom());
-  
-  return 0;
+
+  return nullptr;
 }
 
 void 
@@ -1199,7 +1222,7 @@
                                              TemplateSpecializationKind TSK) {
   assert(TemplateOrInstantiation.isNull() && 
          "Previous template or instantiation?");
-  assert(!isa<ClassTemplateSpecializationDecl>(this));
+  assert(!isa<ClassTemplatePartialSpecializationDecl>(this));
   TemplateOrInstantiation 
     = new (getASTContext()) MemberSpecializationInfo(RD, TSK);
 }
@@ -1241,14 +1264,14 @@
 
   DeclContext::lookup_const_result R = lookup(Name);
   if (R.empty())
-    return 0;
+    return nullptr;
 
   CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(R.front());
   return Dtor;
 }
 
 void CXXRecordDecl::completeDefinition() {
-  completeDefinition(0);
+  completeDefinition(nullptr);
 }
 
 void CXXRecordDecl::completeDefinition(CXXFinalOverriderMap *FinalOverriders) {
@@ -1310,11 +1333,9 @@
       isDependentContext())
     return false;
   
-  for (CXXRecordDecl::base_class_const_iterator B = bases_begin(),
-                                             BEnd = bases_end();
-       B != BEnd; ++B) {
+  for (const auto &B : bases()) {
     CXXRecordDecl *BaseDecl 
-      = cast<CXXRecordDecl>(B->getType()->getAs<RecordType>()->getDecl());
+      = cast<CXXRecordDecl>(B.getType()->getAs<RecordType>()->getDecl());
     if (BaseDecl->isAbstract())
       return true;
   }
@@ -1362,7 +1383,7 @@
       if (MayBeBase && recursivelyOverrides(this, MD))
         return MD;
     }
-    return NULL;
+    return nullptr;
   }
 
   lookup_const_result Candidates = RD->lookup(getDeclName());
@@ -1376,9 +1397,8 @@
       return MD;
   }
 
-  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
-         E = RD->bases_end(); I != E; ++I) {
-    const RecordType *RT = I->getType()->getAs<RecordType>();
+  for (const auto &I : RD->bases()) {
+    const RecordType *RT = I.getType()->getAs<RecordType>();
     if (!RT)
       continue;
     const CXXRecordDecl *Base = cast<CXXRecordDecl>(RT->getDecl());
@@ -1387,7 +1407,7 @@
       return T;
   }
 
-  return NULL;
+  return nullptr;
 }
 
 CXXMethodDecl *
@@ -1397,17 +1417,15 @@
                       QualType T, TypeSourceInfo *TInfo,
                       StorageClass SC, bool isInline,
                       bool isConstexpr, SourceLocation EndLocation) {
-  return new (C) CXXMethodDecl(CXXMethod, RD, StartLoc, NameInfo, T, TInfo,
-                               SC, isInline, isConstexpr,
-                               EndLocation);
+  return new (C, RD) CXXMethodDecl(CXXMethod, C, RD, StartLoc, NameInfo,
+                                   T, TInfo, SC, isInline, isConstexpr,
+                                   EndLocation);
 }
 
 CXXMethodDecl *CXXMethodDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(CXXMethodDecl));
-  return new (Mem) CXXMethodDecl(CXXMethod, 0, SourceLocation(), 
-                                 DeclarationNameInfo(), QualType(),
-                                 0, SC_None, false, false,
-                                 SourceLocation());
+  return new (C, ID) CXXMethodDecl(CXXMethod, C, nullptr, SourceLocation(),
+                                   DeclarationNameInfo(), QualType(), nullptr,
+                                   SC_None, false, false, SourceLocation());
 }
 
 bool CXXMethodDecl::isUsualDeallocationFunction() const {
@@ -1504,12 +1522,12 @@
 }
 
 CXXMethodDecl::method_iterator CXXMethodDecl::begin_overridden_methods() const {
-  if (isa<CXXConstructorDecl>(this)) return 0;
+  if (isa<CXXConstructorDecl>(this)) return nullptr;
   return getASTContext().overridden_methods_begin(this);
 }
 
 CXXMethodDecl::method_iterator CXXMethodDecl::end_overridden_methods() const {
-  if (isa<CXXConstructorDecl>(this)) return 0;
+  if (isa<CXXConstructorDecl>(this)) return nullptr;
   return getASTContext().overridden_methods_end(this);
 }
 
@@ -1607,7 +1625,7 @@
                                        VarDecl **Indices,
                                        unsigned NumIndices)
   : Initializee(Member), MemberOrEllipsisLocation(MemberLoc), Init(Init), 
-    LParenLoc(L), RParenLoc(R), IsVirtual(false),
+    LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(false),
     IsWritten(false), SourceOrderOrNumArrayIndices(NumIndices)
 {
   VarDecl **MyIndices = reinterpret_cast<VarDecl **> (this + 1);
@@ -1639,7 +1657,7 @@
   if (isBaseInitializer())
     return Initializee.get<TypeSourceInfo*>()->getType().getTypePtr();
   else
-    return 0;
+    return nullptr;
 }
 
 SourceLocation CXXCtorInitializer::getSourceLocation() const {
@@ -1670,9 +1688,9 @@
 
 CXXConstructorDecl *
 CXXConstructorDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(CXXConstructorDecl));
-  return new (Mem) CXXConstructorDecl(0, SourceLocation(),DeclarationNameInfo(),
-                                      QualType(), 0, false, false, false,false);
+  return new (C, ID) CXXConstructorDecl(C, nullptr, SourceLocation(),
+                                        DeclarationNameInfo(), QualType(),
+                                        nullptr, false, false, false, false);
 }
 
 CXXConstructorDecl *
@@ -1685,9 +1703,9 @@
   assert(NameInfo.getName().getNameKind()
          == DeclarationName::CXXConstructorName &&
          "Name must refer to a constructor");
-  return new (C) CXXConstructorDecl(RD, StartLoc, NameInfo, T, TInfo,
-                                    isExplicit, isInline, isImplicitlyDeclared,
-                                    isConstexpr);
+  return new (C, RD) CXXConstructorDecl(C, RD, StartLoc, NameInfo, T, TInfo,
+                                        isExplicit, isInline,
+                                        isImplicitlyDeclared, isConstexpr);
 }
 
 CXXConstructorDecl *CXXConstructorDecl::getTargetConstructor() const {
@@ -1695,8 +1713,8 @@
   Expr *E = (*init_begin())->getInit()->IgnoreImplicit();
   if (CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(E))
     return Construct->getConstructor();
-  
-  return 0;
+
+  return nullptr;
 }
 
 bool CXXConstructorDecl::isDefaultConstructor() const {
@@ -1732,8 +1750,8 @@
   //   all other parameters have default arguments.
   if ((getNumParams() < 1) ||
       (getNumParams() > 1 && !getParamDecl(1)->hasDefaultArg()) ||
-      (getPrimaryTemplate() != 0) ||
-      (getDescribedFunctionTemplate() != 0))
+      (getPrimaryTemplate() != nullptr) ||
+      (getDescribedFunctionTemplate() != nullptr))
     return false;
   
   const ParmVarDecl *Param = getParamDecl(0);
@@ -1781,8 +1799,8 @@
 bool CXXConstructorDecl::isSpecializationCopyingObject() const {
   if ((getNumParams() < 1) ||
       (getNumParams() > 1 && !getParamDecl(1)->hasDefaultArg()) ||
-      (getPrimaryTemplate() == 0) ||
-      (getDescribedFunctionTemplate() != 0))
+      (getPrimaryTemplate() == nullptr) ||
+      (getDescribedFunctionTemplate() != nullptr))
     return false;
 
   const ParmVarDecl *Param = getParamDecl(0);
@@ -1803,7 +1821,7 @@
   // Hack: we store the inherited constructor in the overridden method table
   method_iterator It = getASTContext().overridden_methods_begin(this);
   if (It == getASTContext().overridden_methods_end(this))
-    return 0;
+    return nullptr;
 
   return cast<CXXConstructorDecl>(*It);
 }
@@ -1820,9 +1838,9 @@
 
 CXXDestructorDecl *
 CXXDestructorDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(CXXDestructorDecl));
-  return new (Mem) CXXDestructorDecl(0, SourceLocation(), DeclarationNameInfo(),
-                                   QualType(), 0, false, false);
+  return new (C, ID)
+      CXXDestructorDecl(C, nullptr, SourceLocation(), DeclarationNameInfo(),
+                        QualType(), nullptr, false, false);
 }
 
 CXXDestructorDecl *
@@ -1834,18 +1852,18 @@
   assert(NameInfo.getName().getNameKind()
          == DeclarationName::CXXDestructorName &&
          "Name must refer to a destructor");
-  return new (C) CXXDestructorDecl(RD, StartLoc, NameInfo, T, TInfo, isInline,
-                                   isImplicitlyDeclared);
+  return new (C, RD) CXXDestructorDecl(C, RD, StartLoc, NameInfo, T, TInfo,
+                                       isInline, isImplicitlyDeclared);
 }
 
 void CXXConversionDecl::anchor() { }
 
 CXXConversionDecl *
 CXXConversionDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(CXXConversionDecl));
-  return new (Mem) CXXConversionDecl(0, SourceLocation(), DeclarationNameInfo(),
-                                     QualType(), 0, false, false, false,
-                                     SourceLocation());
+  return new (C, ID) CXXConversionDecl(C, nullptr, SourceLocation(),
+                                       DeclarationNameInfo(), QualType(),
+                                       nullptr, false, false, false,
+                                       SourceLocation());
 }
 
 CXXConversionDecl *
@@ -1858,9 +1876,9 @@
   assert(NameInfo.getName().getNameKind()
          == DeclarationName::CXXConversionFunctionName &&
          "Name must refer to a conversion function");
-  return new (C) CXXConversionDecl(RD, StartLoc, NameInfo, T, TInfo,
-                                   isInline, isExplicit, isConstexpr,
-                                   EndLocation);
+  return new (C, RD) CXXConversionDecl(C, RD, StartLoc, NameInfo, T, TInfo,
+                                       isInline, isExplicit, isConstexpr,
+                                       EndLocation);
 }
 
 bool CXXConversionDecl::isLambdaToBlockPointerConversion() const {
@@ -1876,13 +1894,13 @@
                                          SourceLocation LangLoc,
                                          LanguageIDs Lang,
                                          bool HasBraces) {
-  return new (C) LinkageSpecDecl(DC, ExternLoc, LangLoc, Lang, HasBraces);
+  return new (C, DC) LinkageSpecDecl(DC, ExternLoc, LangLoc, Lang, HasBraces);
 }
 
-LinkageSpecDecl *LinkageSpecDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(LinkageSpecDecl));
-  return new (Mem) LinkageSpecDecl(0, SourceLocation(), SourceLocation(),
-                                   lang_c, false);
+LinkageSpecDecl *LinkageSpecDecl::CreateDeserialized(ASTContext &C,
+                                                     unsigned ID) {
+  return new (C, ID) LinkageSpecDecl(nullptr, SourceLocation(),
+                                     SourceLocation(), lang_c, false);
 }
 
 void UsingDirectiveDecl::anchor() { }
@@ -1896,16 +1914,16 @@
                                                DeclContext *CommonAncestor) {
   if (NamespaceDecl *NS = dyn_cast_or_null<NamespaceDecl>(Used))
     Used = NS->getOriginalNamespace();
-  return new (C) UsingDirectiveDecl(DC, L, NamespaceLoc, QualifierLoc,
-                                    IdentLoc, Used, CommonAncestor);
+  return new (C, DC) UsingDirectiveDecl(DC, L, NamespaceLoc, QualifierLoc,
+                                        IdentLoc, Used, CommonAncestor);
 }
 
-UsingDirectiveDecl *
-UsingDirectiveDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(UsingDirectiveDecl));
-  return new (Mem) UsingDirectiveDecl(0, SourceLocation(), SourceLocation(),
-                                      NestedNameSpecifierLoc(),
-                                      SourceLocation(), 0, 0);
+UsingDirectiveDecl *UsingDirectiveDecl::CreateDeserialized(ASTContext &C,
+                                                           unsigned ID) {
+  return new (C, ID) UsingDirectiveDecl(nullptr, SourceLocation(),
+                                        SourceLocation(),
+                                        NestedNameSpecifierLoc(),
+                                        SourceLocation(), nullptr, nullptr);
 }
 
 NamespaceDecl *UsingDirectiveDecl::getNominatedNamespace() {
@@ -1915,17 +1933,14 @@
   return cast_or_null<NamespaceDecl>(NominatedNamespace);
 }
 
-void NamespaceDecl::anchor() { }
-
-NamespaceDecl::NamespaceDecl(DeclContext *DC, bool Inline, 
-                             SourceLocation StartLoc,
-                             SourceLocation IdLoc, IdentifierInfo *Id,
-                             NamespaceDecl *PrevDecl)
-  : NamedDecl(Namespace, DC, IdLoc, Id), DeclContext(Namespace),
-    LocStart(StartLoc), RBraceLoc(), AnonOrFirstNamespaceAndInline(0, Inline) 
-{
+NamespaceDecl::NamespaceDecl(ASTContext &C, DeclContext *DC, bool Inline,
+                             SourceLocation StartLoc, SourceLocation IdLoc,
+                             IdentifierInfo *Id, NamespaceDecl *PrevDecl)
+    : NamedDecl(Namespace, DC, IdLoc, Id), DeclContext(Namespace),
+      redeclarable_base(C), LocStart(StartLoc), RBraceLoc(),
+      AnonOrFirstNamespaceAndInline(nullptr, Inline) {
   setPreviousDecl(PrevDecl);
-  
+
   if (PrevDecl)
     AnonOrFirstNamespaceAndInline.setPointer(PrevDecl->getOriginalNamespace());
 }
@@ -1934,13 +1949,23 @@
                                      bool Inline, SourceLocation StartLoc,
                                      SourceLocation IdLoc, IdentifierInfo *Id,
                                      NamespaceDecl *PrevDecl) {
-  return new (C) NamespaceDecl(DC, Inline, StartLoc, IdLoc, Id, PrevDecl);
+  return new (C, DC) NamespaceDecl(C, DC, Inline, StartLoc, IdLoc, Id,
+                                   PrevDecl);
 }
 
 NamespaceDecl *NamespaceDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(NamespaceDecl));
-  return new (Mem) NamespaceDecl(0, false, SourceLocation(), SourceLocation(), 
-                                 0, 0);
+  return new (C, ID) NamespaceDecl(C, nullptr, false, SourceLocation(),
+                                   SourceLocation(), nullptr, nullptr);
+}
+
+NamespaceDecl *NamespaceDecl::getNextRedeclarationImpl() {
+  return getNextRedeclaration();
+}
+NamespaceDecl *NamespaceDecl::getPreviousDeclImpl() {
+  return getPreviousDecl();
+}
+NamespaceDecl *NamespaceDecl::getMostRecentDeclImpl() {
+  return getMostRecentDecl();
 }
 
 void NamespaceAliasDecl::anchor() { }
@@ -1954,24 +1979,24 @@
                                                NamedDecl *Namespace) {
   if (NamespaceDecl *NS = dyn_cast_or_null<NamespaceDecl>(Namespace))
     Namespace = NS->getOriginalNamespace();
-  return new (C) NamespaceAliasDecl(DC, UsingLoc, AliasLoc, Alias, 
-                                    QualifierLoc, IdentLoc, Namespace);
+  return new (C, DC) NamespaceAliasDecl(DC, UsingLoc, AliasLoc, Alias,
+                                        QualifierLoc, IdentLoc, Namespace);
 }
 
 NamespaceAliasDecl *
 NamespaceAliasDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(NamespaceAliasDecl));
-  return new (Mem) NamespaceAliasDecl(0, SourceLocation(), SourceLocation(), 0,
-                                      NestedNameSpecifierLoc(), 
-                                      SourceLocation(), 0);
+  return new (C, ID) NamespaceAliasDecl(nullptr, SourceLocation(),
+                                        SourceLocation(), nullptr,
+                                        NestedNameSpecifierLoc(),
+                                        SourceLocation(), nullptr);
 }
 
 void UsingShadowDecl::anchor() { }
 
 UsingShadowDecl *
 UsingShadowDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(UsingShadowDecl));
-  return new (Mem) UsingShadowDecl(0, SourceLocation(), 0, 0);
+  return new (C, ID) UsingShadowDecl(C, nullptr, SourceLocation(),
+                                     nullptr, nullptr);
 }
 
 UsingDecl *UsingShadowDecl::getUsingDecl() const {
@@ -2019,13 +2044,13 @@
                              NestedNameSpecifierLoc QualifierLoc,
                              const DeclarationNameInfo &NameInfo,
                              bool HasTypename) {
-  return new (C) UsingDecl(DC, UL, QualifierLoc, NameInfo, HasTypename);
+  return new (C, DC) UsingDecl(DC, UL, QualifierLoc, NameInfo, HasTypename);
 }
 
 UsingDecl *UsingDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(UsingDecl));
-  return new (Mem) UsingDecl(0, SourceLocation(), NestedNameSpecifierLoc(),
-                             DeclarationNameInfo(), false);
+  return new (C, ID) UsingDecl(nullptr, SourceLocation(),
+                               NestedNameSpecifierLoc(), DeclarationNameInfo(),
+                               false);
 }
 
 SourceRange UsingDecl::getSourceRange() const {
@@ -2041,16 +2066,16 @@
                                  SourceLocation UsingLoc,
                                  NestedNameSpecifierLoc QualifierLoc,
                                  const DeclarationNameInfo &NameInfo) {
-  return new (C) UnresolvedUsingValueDecl(DC, C.DependentTy, UsingLoc,
-                                          QualifierLoc, NameInfo);
+  return new (C, DC) UnresolvedUsingValueDecl(DC, C.DependentTy, UsingLoc,
+                                              QualifierLoc, NameInfo);
 }
 
 UnresolvedUsingValueDecl *
 UnresolvedUsingValueDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(UnresolvedUsingValueDecl));
-  return new (Mem) UnresolvedUsingValueDecl(0, QualType(), SourceLocation(),
-                                            NestedNameSpecifierLoc(),
-                                            DeclarationNameInfo());
+  return new (C, ID) UnresolvedUsingValueDecl(nullptr, QualType(),
+                                              SourceLocation(),
+                                              NestedNameSpecifierLoc(),
+                                              DeclarationNameInfo());
 }
 
 SourceRange UnresolvedUsingValueDecl::getSourceRange() const {
@@ -2068,20 +2093,16 @@
                                     NestedNameSpecifierLoc QualifierLoc,
                                     SourceLocation TargetNameLoc,
                                     DeclarationName TargetName) {
-  return new (C) UnresolvedUsingTypenameDecl(DC, UsingLoc, TypenameLoc,
-                                             QualifierLoc, TargetNameLoc,
-                                             TargetName.getAsIdentifierInfo());
+  return new (C, DC) UnresolvedUsingTypenameDecl(
+      DC, UsingLoc, TypenameLoc, QualifierLoc, TargetNameLoc,
+      TargetName.getAsIdentifierInfo());
 }
 
 UnresolvedUsingTypenameDecl *
 UnresolvedUsingTypenameDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, 
-                                       sizeof(UnresolvedUsingTypenameDecl));
-  return new (Mem) UnresolvedUsingTypenameDecl(0, SourceLocation(),
-                                               SourceLocation(),
-                                               NestedNameSpecifierLoc(),
-                                               SourceLocation(),
-                                               0);
+  return new (C, ID) UnresolvedUsingTypenameDecl(
+      nullptr, SourceLocation(), SourceLocation(), NestedNameSpecifierLoc(),
+      SourceLocation(), nullptr);
 }
 
 void StaticAssertDecl::anchor() { }
@@ -2092,15 +2113,30 @@
                                            StringLiteral *Message,
                                            SourceLocation RParenLoc,
                                            bool Failed) {
-  return new (C) StaticAssertDecl(DC, StaticAssertLoc, AssertExpr, Message,
-                                  RParenLoc, Failed);
+  return new (C, DC) StaticAssertDecl(DC, StaticAssertLoc, AssertExpr, Message,
+                                      RParenLoc, Failed);
 }
 
-StaticAssertDecl *StaticAssertDecl::CreateDeserialized(ASTContext &C, 
+StaticAssertDecl *StaticAssertDecl::CreateDeserialized(ASTContext &C,
                                                        unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(StaticAssertDecl));
-  return new (Mem) StaticAssertDecl(0, SourceLocation(), 0, 0,
-                                    SourceLocation(), false);
+  return new (C, ID) StaticAssertDecl(nullptr, SourceLocation(), nullptr,
+                                      nullptr, SourceLocation(), false);
+}
+
+MSPropertyDecl *MSPropertyDecl::Create(ASTContext &C, DeclContext *DC,
+                                       SourceLocation L, DeclarationName N,
+                                       QualType T, TypeSourceInfo *TInfo,
+                                       SourceLocation StartL,
+                                       IdentifierInfo *Getter,
+                                       IdentifierInfo *Setter) {
+  return new (C, DC) MSPropertyDecl(DC, L, N, T, TInfo, StartL, Getter, Setter);
+}
+
+MSPropertyDecl *MSPropertyDecl::CreateDeserialized(ASTContext &C,
+                                                   unsigned ID) {
+  return new (C, ID) MSPropertyDecl(nullptr, SourceLocation(),
+                                    DeclarationName(), QualType(), nullptr,
+                                    SourceLocation(), nullptr, nullptr);
 }
 
 static const char *getAccessName(AccessSpecifier AS) {
diff --git a/lib/AST/DeclFriend.cpp b/lib/AST/DeclFriend.cpp
index 1c639d6..a996cab 100644
--- a/lib/AST/DeclFriend.cpp
+++ b/lib/AST/DeclFriend.cpp
@@ -46,25 +46,21 @@
   }
 #endif
 
-  std::size_t Size = sizeof(FriendDecl)
-    + FriendTypeTPLists.size() * sizeof(TemplateParameterList*);
-  void *Mem = C.Allocate(Size);
-  FriendDecl *FD = new (Mem) FriendDecl(DC, L, Friend, FriendL,
-                                        FriendTypeTPLists);
+  std::size_t Extra = FriendTypeTPLists.size() * sizeof(TemplateParameterList*);
+  FriendDecl *FD = new (C, DC, Extra) FriendDecl(DC, L, Friend, FriendL,
+                                                 FriendTypeTPLists);
   cast<CXXRecordDecl>(DC)->pushFriendDecl(FD);
   return FD;
 }
 
 FriendDecl *FriendDecl::CreateDeserialized(ASTContext &C, unsigned ID,
                                            unsigned FriendTypeNumTPLists) {
-  std::size_t Size = sizeof(FriendDecl)
-    + FriendTypeNumTPLists * sizeof(TemplateParameterList*);
-  void *Mem = AllocateDeserializedDecl(C, ID, Size);
-  return new (Mem) FriendDecl(EmptyShell(), FriendTypeNumTPLists);
+  std::size_t Extra = FriendTypeNumTPLists * sizeof(TemplateParameterList*);
+  return new (C, ID, Extra) FriendDecl(EmptyShell(), FriendTypeNumTPLists);
 }
 
 FriendDecl *CXXRecordDecl::getFirstFriend() const {
   ExternalASTSource *Source = getParentASTContext().getExternalSource();
   Decl *First = data().FirstFriend.get(Source);
-  return First ? cast<FriendDecl>(First) : 0;
+  return First ? cast<FriendDecl>(First) : nullptr;
 }
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index b2b5b70..2204dff 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -25,7 +25,7 @@
 //===----------------------------------------------------------------------===//
 
 void ObjCListBase::set(void *const* InList, unsigned Elts, ASTContext &Ctx) {
-  List = 0;
+  List = nullptr;
   if (Elts == 0) return;  // Setting to an empty list is a noop.
 
 
@@ -60,7 +60,7 @@
     if (ObjCIvarDecl *ivar = dyn_cast<ObjCIvarDecl>(*Ivar))
       return ivar;
   }
-  return 0;
+  return nullptr;
 }
 
 // Get the local instance/class method declared in this interface.
@@ -72,7 +72,7 @@
   if (const ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(this)) {
     if (const ObjCProtocolDecl *Def = Proto->getDefinition())
       if (Def->isHidden() && !AllowHidden)
-        return 0;
+        return nullptr;
   }
 
   // Since instance & class methods can have the same name, the loop below
@@ -90,7 +90,7 @@
     if (MD && MD->isInstanceMethod() == isInstance)
       return MD;
   }
-  return 0;
+  return nullptr;
 }
 
 /// HasUserDeclaredSetterMethod - This routine returns 'true' if a user declared setter
@@ -112,11 +112,7 @@
   if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(this)) {
     // Also look into categories, including class extensions, looking
     // for a user declared instance method.
-    for (ObjCInterfaceDecl::visible_categories_iterator
-         Cat = ID->visible_categories_begin(),
-         CatEnd = ID->visible_categories_end();
-         Cat != CatEnd;
-         ++Cat) {
+    for (const auto *Cat : ID->visible_categories()) {
       if (ObjCMethodDecl *MD = Cat->getInstanceMethod(Sel))
         if (!MD->isImplicit())
           return true;
@@ -125,8 +121,7 @@
       // Also search through the categories looking for a 'readwrite' declaration
       // of this property. If one found, presumably a setter will be provided
       // (properties declared in categories will not get auto-synthesized).
-      for (ObjCContainerDecl::prop_iterator P = Cat->prop_begin(),
-           E = Cat->prop_end(); P != E; ++P)
+      for (const auto *P : Cat->properties())
         if (P->getIdentifier() == Property->getIdentifier()) {
           if (P->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_readwrite)
             return true;
@@ -135,13 +130,10 @@
     }
     
     // Also look into protocols, for a user declared instance method.
-    for (ObjCInterfaceDecl::all_protocol_iterator P =
-         ID->all_referenced_protocol_begin(),
-         PE = ID->all_referenced_protocol_end(); P != PE; ++P) {
-      ObjCProtocolDecl *Proto = (*P);
+    for (const auto *Proto : ID->all_referenced_protocols())
       if (Proto->HasUserDeclaredSetterMethod(Property))
         return true;
-    }
+
     // And in its super class.
     ObjCInterfaceDecl *OSC = ID->getSuperClass();
     while (OSC) {
@@ -151,11 +143,9 @@
     }
   }
   if (const ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(this))
-    for (ObjCProtocolDecl::protocol_iterator PI = PD->protocol_begin(),
-         E = PD->protocol_end(); PI != E; ++PI) {
-      if ((*PI)->HasUserDeclaredSetterMethod(Property))
+    for (const auto *PI : PD->protocols())
+      if (PI->HasUserDeclaredSetterMethod(Property))
         return true;
-    }
   return false;
 }
 
@@ -167,7 +157,7 @@
   if (const ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(DC)) {
     if (const ObjCProtocolDecl *Def = Proto->getDefinition())
       if (Def->isHidden())
-        return 0;
+        return nullptr;
   }
 
   DeclContext::lookup_const_result R = DC->lookup(propertyID);
@@ -176,7 +166,7 @@
     if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(*I))
       return PD;
 
-  return 0;
+  return nullptr;
 }
 
 IdentifierInfo *
@@ -197,7 +187,7 @@
   if (const ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(this)) {
     if (const ObjCProtocolDecl *Def = Proto->getDefinition())
       if (Def->isHidden())
-        return 0;
+        return nullptr;
   }
 
   if (ObjCPropertyDecl *PD =
@@ -209,29 +199,23 @@
       break;
     case Decl::ObjCProtocol: {
       const ObjCProtocolDecl *PID = cast<ObjCProtocolDecl>(this);
-      for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
-           E = PID->protocol_end(); I != E; ++I)
-        if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
+      for (const auto *I : PID->protocols())
+        if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId))
           return P;
       break;
     }
     case Decl::ObjCInterface: {
       const ObjCInterfaceDecl *OID = cast<ObjCInterfaceDecl>(this);
       // Look through categories (but not extensions).
-      for (ObjCInterfaceDecl::visible_categories_iterator
-             Cat = OID->visible_categories_begin(),
-             CatEnd = OID->visible_categories_end();
-           Cat != CatEnd; ++Cat) {
+      for (const auto *Cat : OID->visible_categories()) {
         if (!Cat->IsClassExtension())
           if (ObjCPropertyDecl *P = Cat->FindPropertyDeclaration(PropertyId))
             return P;
       }
 
       // Look through protocols.
-      for (ObjCInterfaceDecl::all_protocol_iterator
-            I = OID->all_referenced_protocol_begin(),
-            E = OID->all_referenced_protocol_end(); I != E; ++I)
-        if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
+      for (const auto *I : OID->all_referenced_protocols())
+        if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId))
           return P;
 
       // Finally, check the super class.
@@ -243,15 +227,13 @@
       const ObjCCategoryDecl *OCD = cast<ObjCCategoryDecl>(this);
       // Look through protocols.
       if (!OCD->IsClassExtension())
-        for (ObjCCategoryDecl::protocol_iterator
-              I = OCD->protocol_begin(), E = OCD->protocol_end(); I != E; ++I)
-        if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
-          return P;
-
+        for (const auto *I : OCD->protocols())
+          if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId))
+            return P;
       break;
     }
   }
-  return 0;
+  return nullptr;
 }
 
 void ObjCInterfaceDecl::anchor() { }
@@ -265,8 +247,8 @@
                                             IdentifierInfo *PropertyId) const {
   // FIXME: Should make sure no callers ever do this.
   if (!hasDefinition())
-    return 0;
-  
+    return nullptr;
+
   if (data().ExternallyCompleted)
     LoadExternalDefinition();
 
@@ -275,27 +257,21 @@
     return PD;
 
   // Look through protocols.
-  for (ObjCInterfaceDecl::all_protocol_iterator
-        I = all_referenced_protocol_begin(),
-        E = all_referenced_protocol_end(); I != E; ++I)
-    if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
+  for (const auto *I : all_referenced_protocols())
+    if (ObjCPropertyDecl *P = I->FindPropertyDeclaration(PropertyId))
       return P;
 
-  return 0;
+  return nullptr;
 }
 
 void ObjCInterfaceDecl::collectPropertiesToImplement(PropertyMap &PM,
                                                      PropertyDeclOrder &PO) const {
-  for (ObjCContainerDecl::prop_iterator P = prop_begin(),
-      E = prop_end(); P != E; ++P) {
-    ObjCPropertyDecl *Prop = *P;
+  for (auto *Prop : properties()) {
     PM[Prop->getIdentifier()] = Prop;
     PO.push_back(Prop);
   }
-  for (ObjCInterfaceDecl::all_protocol_iterator
-      PI = all_referenced_protocol_begin(),
-      E = all_referenced_protocol_end(); PI != E; ++PI)
-    (*PI)->collectPropertiesToImplement(PM, PO);
+  for (const auto *PI : all_referenced_protocols())
+    PI->collectPropertiesToImplement(PM, PO);
   // Note, the properties declared only in class extensions are still copied
   // into the main @interface's property list, and therefore we don't
   // explicitly, have to search class extension properties.
@@ -318,7 +294,7 @@
       return Class;
     Class = Class->getSuperClass();
   }
-  return 0;
+  return nullptr;
 }
 
 void ObjCInterfaceDecl::mergeClassExtensionProtocolList(
@@ -341,10 +317,7 @@
   for (unsigned i = 0; i < ExtNum; i++) {
     bool protocolExists = false;
     ObjCProtocolDecl *ProtoInExtension = ExtList[i];
-    for (all_protocol_iterator
-          p = all_referenced_protocol_begin(),
-          e = all_referenced_protocol_end(); p != e; ++p) {
-      ObjCProtocolDecl *Proto = (*p);
+    for (auto *Proto : all_referenced_protocols()) {
       if (C.ProtocolCompatibleWithProtocol(ProtoInExtension, Proto)) {
         protocolExists = true;
         break;
@@ -360,14 +333,132 @@
     return;
 
   // Merge ProtocolRefs into class's protocol list;
-  for (all_protocol_iterator p = all_referenced_protocol_begin(), 
-        e = all_referenced_protocol_end(); p != e; ++p) {
-    ProtocolRefs.push_back(*p);
+  for (auto *P : all_referenced_protocols()) {
+    ProtocolRefs.push_back(P);
   }
 
   data().AllReferencedProtocols.set(ProtocolRefs.data(), ProtocolRefs.size(),C);
 }
 
+const ObjCInterfaceDecl *
+ObjCInterfaceDecl::findInterfaceWithDesignatedInitializers() const {
+  const ObjCInterfaceDecl *IFace = this;
+  while (IFace) {
+    if (IFace->hasDesignatedInitializers())
+      return IFace;
+    if (!IFace->inheritsDesignatedInitializers())
+      break;
+    IFace = IFace->getSuperClass();
+  }
+  return nullptr;
+}
+
+static bool isIntroducingInitializers(const ObjCInterfaceDecl *D) {
+  for (const auto *MD : D->instance_methods()) {
+    if (MD->getMethodFamily() == OMF_init && !MD->isOverriding())
+      return true;
+  }
+  for (const auto *Ext : D->visible_extensions()) {
+    for (const auto *MD : Ext->instance_methods()) {
+      if (MD->getMethodFamily() == OMF_init && !MD->isOverriding())
+        return true;
+    }
+  }
+  if (const auto *ImplD = D->getImplementation()) {
+    for (const auto *MD : ImplD->instance_methods()) {
+      if (MD->getMethodFamily() == OMF_init && !MD->isOverriding())
+        return true;
+    }
+  }
+  return false;
+}
+
+bool ObjCInterfaceDecl::inheritsDesignatedInitializers() const {
+  switch (data().InheritedDesignatedInitializers) {
+  case DefinitionData::IDI_Inherited:
+    return true;
+  case DefinitionData::IDI_NotInherited:
+    return false;
+  case DefinitionData::IDI_Unknown: {
+    // If the class introduced initializers we conservatively assume that we
+    // don't know if any of them is a designated initializer to avoid possible
+    // misleading warnings.
+    if (isIntroducingInitializers(this)) {
+      data().InheritedDesignatedInitializers = DefinitionData::IDI_NotInherited;
+    } else {
+      if (auto SuperD = getSuperClass()) {
+        data().InheritedDesignatedInitializers =
+          SuperD->declaresOrInheritsDesignatedInitializers() ?
+            DefinitionData::IDI_Inherited :
+            DefinitionData::IDI_NotInherited;
+      } else {
+        data().InheritedDesignatedInitializers =
+          DefinitionData::IDI_NotInherited;
+      }
+    }
+    assert(data().InheritedDesignatedInitializers
+             != DefinitionData::IDI_Unknown);
+    return data().InheritedDesignatedInitializers ==
+        DefinitionData::IDI_Inherited;
+  }
+  }
+
+  llvm_unreachable("unexpected InheritedDesignatedInitializers value");
+}
+
+void ObjCInterfaceDecl::getDesignatedInitializers(
+    llvm::SmallVectorImpl<const ObjCMethodDecl *> &Methods) const {
+  // Check for a complete definition and recover if not so.
+  if (!isThisDeclarationADefinition())
+    return;
+  if (data().ExternallyCompleted)
+    LoadExternalDefinition();
+
+  const ObjCInterfaceDecl *IFace= findInterfaceWithDesignatedInitializers();
+  if (!IFace)
+    return;
+
+  for (const auto *MD : IFace->instance_methods())
+    if (MD->isThisDeclarationADesignatedInitializer())
+      Methods.push_back(MD);
+  for (const auto *Ext : IFace->visible_extensions()) {
+    for (const auto *MD : Ext->instance_methods())
+      if (MD->isThisDeclarationADesignatedInitializer())
+        Methods.push_back(MD);
+  }
+}
+
+bool ObjCInterfaceDecl::isDesignatedInitializer(Selector Sel,
+                                      const ObjCMethodDecl **InitMethod) const {
+  // Check for a complete definition and recover if not so.
+  if (!isThisDeclarationADefinition())
+    return false;
+  if (data().ExternallyCompleted)
+    LoadExternalDefinition();
+
+  const ObjCInterfaceDecl *IFace= findInterfaceWithDesignatedInitializers();
+  if (!IFace)
+    return false;
+
+  if (const ObjCMethodDecl *MD = IFace->getInstanceMethod(Sel)) {
+    if (MD->isThisDeclarationADesignatedInitializer()) {
+      if (InitMethod)
+        *InitMethod = MD;
+      return true;
+    }
+  }
+  for (const auto *Ext : IFace->visible_extensions()) {
+    if (const ObjCMethodDecl *MD = Ext->getInstanceMethod(Sel)) {
+      if (MD->isThisDeclarationADesignatedInitializer()) {
+        if (InitMethod)
+          *InitMethod = MD;
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
 void ObjCInterfaceDecl::allocateDefinitionData() {
   assert(!hasDefinition() && "ObjC class already has a definition");
   Data.setPointer(new (getASTContext()) DefinitionData());
@@ -382,9 +473,8 @@
   allocateDefinitionData();
 
   // Update all of the declarations with a pointer to the definition.
-  for (redecl_iterator RD = redecls_begin(), RDEnd = redecls_end();
-       RD != RDEnd; ++RD) {
-    if (*RD != this)
+  for (auto RD : redecls()) {
+    if (RD != this)
       RD->Data = Data;
   }
 }
@@ -393,22 +483,19 @@
                                               ObjCInterfaceDecl *&clsDeclared) {
   // FIXME: Should make sure no callers ever do this.
   if (!hasDefinition())
-    return 0;  
+    return nullptr;
 
   if (data().ExternallyCompleted)
     LoadExternalDefinition();
 
   ObjCInterfaceDecl* ClassDecl = this;
-  while (ClassDecl != NULL) {
+  while (ClassDecl != nullptr) {
     if (ObjCIvarDecl *I = ClassDecl->getIvarDecl(ID)) {
       clsDeclared = ClassDecl;
       return I;
     }
 
-    for (ObjCInterfaceDecl::visible_extensions_iterator
-           Ext = ClassDecl->visible_extensions_begin(),
-           ExtEnd = ClassDecl->visible_extensions_end();
-         Ext != ExtEnd; ++Ext) {
+    for (const auto *Ext : ClassDecl->visible_extensions()) {
       if (ObjCIvarDecl *I = Ext->getIvarDecl(ID)) {
         clsDeclared = ClassDecl;
         return I;
@@ -417,7 +504,7 @@
       
     ClassDecl = ClassDecl->getSuperClass();
   }
-  return NULL;
+  return nullptr;
 }
 
 /// lookupInheritedClass - This method returns ObjCInterfaceDecl * of the super
@@ -427,29 +514,27 @@
                                         const IdentifierInfo*ICName) {
   // FIXME: Should make sure no callers ever do this.
   if (!hasDefinition())
-    return 0;
+    return nullptr;
 
   if (data().ExternallyCompleted)
     LoadExternalDefinition();
 
   ObjCInterfaceDecl* ClassDecl = this;
-  while (ClassDecl != NULL) {
+  while (ClassDecl != nullptr) {
     if (ClassDecl->getIdentifier() == ICName)
       return ClassDecl;
     ClassDecl = ClassDecl->getSuperClass();
   }
-  return NULL;
+  return nullptr;
 }
 
 ObjCProtocolDecl *
 ObjCInterfaceDecl::lookupNestedProtocol(IdentifierInfo *Name) {
-  for (ObjCInterfaceDecl::all_protocol_iterator P =
-       all_referenced_protocol_begin(), PE = all_referenced_protocol_end();
-       P != PE; ++P)
-    if ((*P)->lookupProtocolNamed(Name))
-      return (*P);
+  for (auto *P : all_referenced_protocols())
+    if (P->lookupProtocolNamed(Name))
+      return P;
   ObjCInterfaceDecl *SuperClass = getSuperClass();
-  return SuperClass ? SuperClass->lookupNestedProtocol(Name) : NULL;
+  return SuperClass ? SuperClass->lookupNestedProtocol(Name) : nullptr;
 }
 
 /// lookupMethod - This method returns an instance/class method by looking in
@@ -457,37 +542,34 @@
 /// When argument category "C" is specified, any implicit method found
 /// in this category is ignored.
 ObjCMethodDecl *ObjCInterfaceDecl::lookupMethod(Selector Sel, 
-                                     bool isInstance,
-                                     bool shallowCategoryLookup,
-                                     const ObjCCategoryDecl *C) const {
+                                                bool isInstance,
+                                                bool shallowCategoryLookup,
+                                                bool followSuper,
+                                                const ObjCCategoryDecl *C) const
+{
   // FIXME: Should make sure no callers ever do this.
   if (!hasDefinition())
-    return 0;
+    return nullptr;
 
   const ObjCInterfaceDecl* ClassDecl = this;
-  ObjCMethodDecl *MethodDecl = 0;
+  ObjCMethodDecl *MethodDecl = nullptr;
 
   if (data().ExternallyCompleted)
     LoadExternalDefinition();
 
-  while (ClassDecl != NULL) {
+  while (ClassDecl) {
     if ((MethodDecl = ClassDecl->getMethod(Sel, isInstance)))
       return MethodDecl;
 
     // Didn't find one yet - look through protocols.
-    for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(),
-                                              E = ClassDecl->protocol_end();
-           I != E; ++I)
-      if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
+    for (const auto *I : ClassDecl->protocols())
+      if ((MethodDecl = I->lookupMethod(Sel, isInstance)))
         return MethodDecl;
     
     // Didn't find one yet - now look through categories.
-    for (ObjCInterfaceDecl::visible_categories_iterator
-         Cat = ClassDecl->visible_categories_begin(),
-         CatEnd = ClassDecl->visible_categories_end();
-         Cat != CatEnd; ++Cat) {
+    for (const auto *Cat : ClassDecl->visible_categories()) {
       if ((MethodDecl = Cat->getMethod(Sel, isInstance)))
-        if (C != (*Cat) || !MethodDecl->isImplicit())
+        if (C != Cat || !MethodDecl->isImplicit())
           return MethodDecl;
 
       if (!shallowCategoryLookup) {
@@ -497,14 +579,18 @@
         for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
              E = Protocols.end(); I != E; ++I)
           if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
-            if (C != (*Cat) || !MethodDecl->isImplicit())
+            if (C != Cat || !MethodDecl->isImplicit())
               return MethodDecl;
       }
     }
-  
+
+    if (!followSuper)
+      return nullptr;
+
+    // Get the super class (if any).
     ClassDecl = ClassDecl->getSuperClass();
   }
-  return NULL;
+  return nullptr;
 }
 
 // Will search "local" class/category implementations for a method decl.
@@ -515,12 +601,12 @@
                                    bool Instance) const {
   // FIXME: Should make sure no callers ever do this.
   if (!hasDefinition())
-    return 0;
+    return nullptr;
 
   if (data().ExternallyCompleted)
     LoadExternalDefinition();
 
-  ObjCMethodDecl *Method = 0;
+  ObjCMethodDecl *Method = nullptr;
   if (ObjCImplementationDecl *ImpDecl = getImplementation())
     Method = Instance ? ImpDecl->getInstanceMethod(Sel) 
                       : ImpDecl->getClassMethod(Sel);
@@ -550,31 +636,38 @@
 // ObjCMethodDecl
 //===----------------------------------------------------------------------===//
 
-ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
-                                       SourceLocation beginLoc,
-                                       SourceLocation endLoc,
-                                       Selector SelInfo, QualType T,
-                                       TypeSourceInfo *ResultTInfo,
-                                       DeclContext *contextDecl,
-                                       bool isInstance,
-                                       bool isVariadic,
-                                       bool isPropertyAccessor,
-                                       bool isImplicitlyDeclared,
-                                       bool isDefined,
-                                       ImplementationControl impControl,
-                                       bool HasRelatedResultType) {
-  return new (C) ObjCMethodDecl(beginLoc, endLoc,
-                                SelInfo, T, ResultTInfo, contextDecl,
-                                isInstance, isVariadic, isPropertyAccessor,
-                                isImplicitlyDeclared, isDefined,
-                                impControl,
-                                HasRelatedResultType);
+ObjCMethodDecl *ObjCMethodDecl::Create(
+    ASTContext &C, SourceLocation beginLoc, SourceLocation endLoc,
+    Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo,
+    DeclContext *contextDecl, bool isInstance, bool isVariadic,
+    bool isPropertyAccessor, bool isImplicitlyDeclared, bool isDefined,
+    ImplementationControl impControl, bool HasRelatedResultType) {
+  return new (C, contextDecl) ObjCMethodDecl(
+      beginLoc, endLoc, SelInfo, T, ReturnTInfo, contextDecl, isInstance,
+      isVariadic, isPropertyAccessor, isImplicitlyDeclared, isDefined,
+      impControl, HasRelatedResultType);
 }
 
 ObjCMethodDecl *ObjCMethodDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCMethodDecl));
-  return new (Mem) ObjCMethodDecl(SourceLocation(), SourceLocation(), 
-                                  Selector(), QualType(), 0, 0);
+  return new (C, ID) ObjCMethodDecl(SourceLocation(), SourceLocation(),
+                                    Selector(), QualType(), nullptr, nullptr);
+}
+
+bool ObjCMethodDecl::isThisDeclarationADesignatedInitializer() const {
+  return getMethodFamily() == OMF_init &&
+      hasAttr<ObjCDesignatedInitializerAttr>();
+}
+
+bool ObjCMethodDecl::isDesignatedInitializerForTheInterface(
+    const ObjCMethodDecl **InitMethod) const {
+  if (getMethodFamily() != OMF_init)
+    return false;
+  const DeclContext *DC = getDeclContext();
+  if (isa<ObjCProtocolDecl>(DC))
+    return false;
+  if (const ObjCInterfaceDecl *ID = getClassInterface())
+    return ID->isDesignatedInitializer(getSelector(), InitMethod);
+  return false;
 }
 
 Stmt *ObjCMethodDecl::getBody() const {
@@ -591,7 +684,7 @@
 void ObjCMethodDecl::setParamsAndSelLocs(ASTContext &C,
                                          ArrayRef<ParmVarDecl*> Params,
                                          ArrayRef<SourceLocation> SelLocs) {
-  ParamsAndSelLocs = 0;
+  ParamsAndSelLocs = nullptr;
   NumParams = Params.size();
   if (Params.empty() && SelLocs.empty())
     return;
@@ -628,9 +721,9 @@
 /// \brief A definition will return its interface declaration.
 /// An interface declaration will return its definition.
 /// Otherwise it will return itself.
-ObjCMethodDecl *ObjCMethodDecl::getNextRedeclaration() {
+ObjCMethodDecl *ObjCMethodDecl::getNextRedeclarationImpl() {
   ASTContext &Ctx = getASTContext();
-  ObjCMethodDecl *Redecl = 0;
+  ObjCMethodDecl *Redecl = nullptr;
   if (HasRedeclaration)
     Redecl = const_cast<ObjCMethodDecl*>(Ctx.getObjCMethodRedeclaration(this));
   if (Redecl)
@@ -730,7 +823,7 @@
   // init only has a conventional meaning for an instance method, and
   // it has to return an object.
   case OMF_init:
-    if (!isInstanceMethod() || !getResultType()->isObjCObjectPointerType())
+    if (!isInstanceMethod() || !getReturnType()->isObjCObjectPointerType())
       family = OMF_None;
     break;
 
@@ -740,7 +833,7 @@
   case OMF_copy:
   case OMF_mutableCopy:
   case OMF_new:
-    if (!getResultType()->isObjCObjectPointerType())
+    if (!getReturnType()->isObjCObjectPointerType())
       family = OMF_None;
     break;
 
@@ -757,15 +850,14 @@
     break;
       
   case OMF_performSelector:
-    if (!isInstanceMethod() ||
-        !getResultType()->isObjCIdType())
+    if (!isInstanceMethod() || !getReturnType()->isObjCIdType())
       family = OMF_None;
     else {
       unsigned noParams = param_size();
       if (noParams < 1 || noParams > 3)
         family = OMF_None;
       else {
-        ObjCMethodDecl::arg_type_iterator it = arg_type_begin();
+        ObjCMethodDecl::param_type_iterator it = param_type_begin();
         QualType ArgT = (*it);
         if (!ArgT->isObjCSelType()) {
           family = OMF_None;
@@ -838,7 +930,7 @@
   setSelfDecl(self);
 
   if (selfIsConsumed)
-    self->addAttr(new (Context) NSConsumedAttr(SourceLocation(), Context));
+    self->addAttr(NSConsumedAttr::CreateImplicit(Context));
 
   if (selfIsPseudoStrong)
     self->setARCPseudoStrong(true);
@@ -855,8 +947,8 @@
     return CD->getClassInterface();
   if (ObjCImplDecl *IMD = dyn_cast<ObjCImplDecl>(getDeclContext()))
     return IMD->getClassInterface();
-
-  assert(!isa<ObjCProtocolDecl>(getDeclContext()) && "It's a protocol method");
+  if (isa<ObjCProtocolDecl>(getDeclContext()))
+    return nullptr;
   llvm_unreachable("unknown method context");
 }
 
@@ -886,10 +978,8 @@
           return;
         }
 
-    for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
-                                          PEnd = Category->protocol_end();
-         P != PEnd; ++P)
-      CollectOverriddenMethodsRecurse(*P, Method, Methods, MovedToSuper);
+    for (const auto *P : Category->protocols())
+      CollectOverriddenMethodsRecurse(P, Method, Methods, MovedToSuper);
     return;
   }
 
@@ -906,26 +996,17 @@
     }
 
   if (const ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)){
-    for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
-                                          PEnd = Protocol->protocol_end();
-         P != PEnd; ++P)
-      CollectOverriddenMethodsRecurse(*P, Method, Methods, MovedToSuper);
+    for (const auto *P : Protocol->protocols())
+      CollectOverriddenMethodsRecurse(P, Method, Methods, MovedToSuper);
   }
 
   if (const ObjCInterfaceDecl *
         Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
-    for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(),
-                                           PEnd = Interface->protocol_end();
-         P != PEnd; ++P)
-      CollectOverriddenMethodsRecurse(*P, Method, Methods, MovedToSuper);
+    for (const auto *P : Interface->protocols())
+      CollectOverriddenMethodsRecurse(P, Method, Methods, MovedToSuper);
 
-    for (ObjCInterfaceDecl::known_categories_iterator
-           Cat = Interface->known_categories_begin(),
-           CatEnd = Interface->known_categories_end();
-         Cat != CatEnd; ++Cat) {
-      CollectOverriddenMethodsRecurse(*Cat, Method, Methods,
-                                      MovedToSuper);
-    }
+    for (const auto *Cat : Interface->known_categories())
+      CollectOverriddenMethodsRecurse(Cat, Method, Methods, MovedToSuper);
 
     if (const ObjCInterfaceDecl *Super = Interface->getSuperClass())
       return CollectOverriddenMethodsRecurse(Super, Method, Methods,
@@ -1002,11 +1083,11 @@
   Selector Sel = getSelector();
   unsigned NumArgs = Sel.getNumArgs();
   if (NumArgs > 1)
-    return 0;
+    return nullptr;
 
   if (!isInstanceMethod() || getMethodFamily() != OMF_None)
-    return 0;
-  
+    return nullptr;
+
   if (isPropertyAccessor()) {
     const ObjCContainerDecl *Container = cast<ObjCContainerDecl>(getParent());
     // If container is class extension, find its primary class.
@@ -1016,20 +1097,18 @@
     
     bool IsGetter = (NumArgs == 0);
 
-    for (ObjCContainerDecl::prop_iterator I = Container->prop_begin(),
-                                          E = Container->prop_end();
-         I != E; ++I) {
-      Selector NextSel = IsGetter ? (*I)->getGetterName()
-                                  : (*I)->getSetterName();
+    for (const auto *I : Container->properties()) {
+      Selector NextSel = IsGetter ? I->getGetterName()
+                                  : I->getSetterName();
       if (NextSel == Sel)
-        return *I;
+        return I;
     }
 
     llvm_unreachable("Marked as a property accessor but no property found!");
   }
 
   if (!CheckOverrides)
-    return 0;
+    return nullptr;
 
   typedef SmallVector<const ObjCMethodDecl *, 8> OverridesTy;
   OverridesTy Overrides;
@@ -1040,8 +1119,7 @@
       return Prop;
   }
 
-  return 0;
-
+  return nullptr;
 }
 
 //===----------------------------------------------------------------------===//
@@ -1055,37 +1133,38 @@
                                              ObjCInterfaceDecl *PrevDecl,
                                              SourceLocation ClassLoc,
                                              bool isInternal){
-  ObjCInterfaceDecl *Result = new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, 
-                                                        PrevDecl, isInternal);
+  ObjCInterfaceDecl *Result = new (C, DC)
+      ObjCInterfaceDecl(C, DC, atLoc, Id, ClassLoc, PrevDecl, isInternal);
   Result->Data.setInt(!C.getLangOpts().Modules);
   C.getObjCInterfaceType(Result, PrevDecl);
   return Result;
 }
 
-ObjCInterfaceDecl *ObjCInterfaceDecl::CreateDeserialized(ASTContext &C, 
+ObjCInterfaceDecl *ObjCInterfaceDecl::CreateDeserialized(const ASTContext &C,
                                                          unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCInterfaceDecl));
-  ObjCInterfaceDecl *Result = new (Mem) ObjCInterfaceDecl(0, SourceLocation(),
-                                                          0, SourceLocation(),
-                                                          0, false);
+  ObjCInterfaceDecl *Result = new (C, ID) ObjCInterfaceDecl(C, nullptr,
+                                                            SourceLocation(),
+                                                            nullptr,
+                                                            SourceLocation(),
+                                                            nullptr, false);
   Result->Data.setInt(!C.getLangOpts().Modules);
   return Result;
 }
 
-ObjCInterfaceDecl::
-ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
-                  SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl,
-                  bool isInternal)
-  : ObjCContainerDecl(ObjCInterface, DC, Id, CLoc, atLoc),
-    TypeForDecl(0), Data()
-{
+ObjCInterfaceDecl::ObjCInterfaceDecl(const ASTContext &C, DeclContext *DC,
+                                     SourceLocation AtLoc, IdentifierInfo *Id,
+                                     SourceLocation CLoc,
+                                     ObjCInterfaceDecl *PrevDecl,
+                                     bool IsInternal)
+    : ObjCContainerDecl(ObjCInterface, DC, Id, CLoc, AtLoc),
+      redeclarable_base(C), TypeForDecl(nullptr), Data() {
   setPreviousDecl(PrevDecl);
   
   // Copy the 'data' pointer over.
   if (PrevDecl)
     Data = PrevDecl->Data;
   
-  setImplicit(isInternal);
+  setImplicit(IsInternal);
 }
 
 void ObjCInterfaceDecl::LoadExternalDefinition() const {
@@ -1103,6 +1182,40 @@
   data().ExternallyCompleted = true;
 }
 
+void ObjCInterfaceDecl::setHasDesignatedInitializers() {
+  // Check for a complete definition and recover if not so.
+  if (!isThisDeclarationADefinition())
+    return;
+  data().HasDesignatedInitializers = true;
+}
+
+bool ObjCInterfaceDecl::hasDesignatedInitializers() const {
+  // Check for a complete definition and recover if not so.
+  if (!isThisDeclarationADefinition())
+    return false;
+  if (data().ExternallyCompleted)
+    LoadExternalDefinition();
+
+  return data().HasDesignatedInitializers;
+}
+
+StringRef
+ObjCInterfaceDecl::getObjCRuntimeNameAsString() const {
+  if (ObjCRuntimeNameAttr *ObjCRTName = getAttr<ObjCRuntimeNameAttr>())
+    return ObjCRTName->getMetadataName();
+
+  return getName();
+}
+
+StringRef
+ObjCImplementationDecl::getObjCRuntimeNameAsString() const {
+  if (ObjCInterfaceDecl *ID =
+      const_cast<ObjCImplementationDecl*>(this)->getClassInterface())
+    return ID->getObjCRuntimeNameAsString();
+    
+  return getName();
+}
+
 ObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const {
   if (const ObjCInterfaceDecl *Def = getDefinition()) {
     if (data().ExternallyCompleted)
@@ -1113,7 +1226,7 @@
   }
   
   // FIXME: Should make sure no callers ever do this.
-  return 0;
+  return nullptr;
 }
 
 void ObjCInterfaceDecl::setImplementation(ObjCImplementationDecl *ImplD) {
@@ -1146,9 +1259,9 @@
 ObjCIvarDecl *ObjCInterfaceDecl::all_declared_ivar_begin() {
   // FIXME: Should make sure no callers ever do this.
   if (!hasDefinition())
-    return 0;
-  
-  ObjCIvarDecl *curIvar = 0;
+    return nullptr;
+
+  ObjCIvarDecl *curIvar = nullptr;
   if (!data().IvarList) {
     if (!ivar_empty()) {
       ObjCInterfaceDecl::ivar_iterator I = ivar_begin(), E = ivar_end();
@@ -1157,10 +1270,7 @@
         curIvar->setNextIvar(*I);
     }
 
-    for (ObjCInterfaceDecl::known_extensions_iterator
-           Ext = known_extensions_begin(),
-           ExtEnd = known_extensions_end();
-         Ext != ExtEnd; ++Ext) {
+    for (const auto *Ext : known_extensions()) {
       if (!Ext->ivar_empty()) {
         ObjCCategoryDecl::ivar_iterator
           I = Ext->ivar_begin(),
@@ -1184,19 +1294,17 @@
     data().IvarListMissingImplementation = false;
     if (!ImplDecl->ivar_empty()) {
       SmallVector<SynthesizeIvarChunk, 16> layout;
-      for (ObjCImplementationDecl::ivar_iterator I = ImplDecl->ivar_begin(),
-           E = ImplDecl->ivar_end(); I != E; ++I) {
-        ObjCIvarDecl *IV = *I;
+      for (auto *IV : ImplDecl->ivars()) {
         if (IV->getSynthesize() && !IV->isInvalidDecl()) {
           layout.push_back(SynthesizeIvarChunk(
                              IV->getASTContext().getTypeSize(IV->getType()), IV));
           continue;
         }
         if (!data().IvarList)
-          data().IvarList = *I;
+          data().IvarList = IV;
         else
-          curIvar->setNextIvar(*I);
-        curIvar = *I;
+          curIvar->setNextIvar(IV);
+        curIvar = IV;
       }
       
       if (!layout.empty()) {
@@ -1223,47 +1331,37 @@
 ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const {
   // FIXME: Should make sure no callers ever do this.
   if (!hasDefinition())
-    return 0;
+    return nullptr;
 
   if (data().ExternallyCompleted)
     LoadExternalDefinition();
 
-  for (visible_categories_iterator Cat = visible_categories_begin(),
-                                   CatEnd = visible_categories_end();
-       Cat != CatEnd;
-       ++Cat) {
+  for (auto *Cat : visible_categories())
     if (Cat->getIdentifier() == CategoryId)
-      return *Cat;
-  }
-  
-  return 0;
+      return Cat;
+
+  return nullptr;
 }
 
 ObjCMethodDecl *
 ObjCInterfaceDecl::getCategoryInstanceMethod(Selector Sel) const {
-  for (visible_categories_iterator Cat = visible_categories_begin(),
-                                   CatEnd = visible_categories_end();
-       Cat != CatEnd;
-       ++Cat) {
+  for (const auto *Cat : visible_categories()) {
     if (ObjCCategoryImplDecl *Impl = Cat->getImplementation())
       if (ObjCMethodDecl *MD = Impl->getInstanceMethod(Sel))
         return MD;
   }
 
-  return 0;
+  return nullptr;
 }
 
 ObjCMethodDecl *ObjCInterfaceDecl::getCategoryClassMethod(Selector Sel) const {
-  for (visible_categories_iterator Cat = visible_categories_begin(),
-                                   CatEnd = visible_categories_end();
-       Cat != CatEnd;
-       ++Cat) {
+  for (const auto *Cat : visible_categories()) {
     if (ObjCCategoryImplDecl *Impl = Cat->getImplementation())
       if (ObjCMethodDecl *MD = Impl->getClassMethod(Sel))
         return MD;
   }
-  
-  return 0;
+
+  return nullptr;
 }
 
 /// ClassImplementsProtocol - Checks that 'lProto' protocol
@@ -1277,9 +1375,8 @@
   
   ObjCInterfaceDecl *IDecl = this;
   // 1st, look up the class.
-  for (ObjCInterfaceDecl::protocol_iterator
-        PI = IDecl->protocol_begin(), E = IDecl->protocol_end(); PI != E; ++PI){
-    if (getASTContext().ProtocolCompatibleWithProtocol(lProto, *PI))
+  for (auto *PI : IDecl->protocols()){
+    if (getASTContext().ProtocolCompatibleWithProtocol(lProto, PI))
       return true;
     // This is dubious and is added to be compatible with gcc.  In gcc, it is
     // also allowed assigning a protocol-qualified 'id' type to a LHS object
@@ -1288,20 +1385,15 @@
     // FIXME: Treat this as an extension, and flag this as an error when GCC
     // extensions are not enabled.
     if (RHSIsQualifiedID &&
-        getASTContext().ProtocolCompatibleWithProtocol(*PI, lProto))
+        getASTContext().ProtocolCompatibleWithProtocol(PI, lProto))
       return true;
   }
 
   // 2nd, look up the category.
   if (lookupCategory)
-    for (visible_categories_iterator Cat = visible_categories_begin(),
-                                     CatEnd = visible_categories_end();
-         Cat != CatEnd;
-         ++Cat) {
-      for (ObjCCategoryDecl::protocol_iterator PI = Cat->protocol_begin(),
-                                               E = Cat->protocol_end();
-           PI != E; ++PI)
-        if (getASTContext().ProtocolCompatibleWithProtocol(lProto, *PI))
+    for (const auto *Cat : visible_categories()) {
+      for (auto *PI : Cat->protocols())
+        if (getASTContext().ProtocolCompatibleWithProtocol(lProto, PI))
           return true;
     }
 
@@ -1325,8 +1417,7 @@
                                    SourceLocation IdLoc, IdentifierInfo *Id,
                                    QualType T, TypeSourceInfo *TInfo,
                                    AccessControl ac, Expr *BW,
-                                   bool synthesized,
-                                   bool backingIvarReferencedInAccessor) {
+                                   bool synthesized) {
   if (DC) {
     // Ivar's can only appear in interfaces, implementations (via synthesized
     // properties), and class extensions (via direct declaration, or synthesized
@@ -1350,17 +1441,17 @@
       else
         ID = cast<ObjCCategoryDecl>(DC)->getClassInterface();
     }
-    ID->setIvarList(0);
+    ID->setIvarList(nullptr);
   }
 
-  return new (C) ObjCIvarDecl(DC, StartLoc, IdLoc, Id, T, TInfo,
-                              ac, BW, synthesized, backingIvarReferencedInAccessor);
+  return new (C, DC) ObjCIvarDecl(DC, StartLoc, IdLoc, Id, T, TInfo, ac, BW,
+                                  synthesized);
 }
 
 ObjCIvarDecl *ObjCIvarDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCIvarDecl));
-  return new (Mem) ObjCIvarDecl(0, SourceLocation(), SourceLocation(), 0,
-                                QualType(), 0, ObjCIvarDecl::None, 0, false, false);
+  return new (C, ID) ObjCIvarDecl(nullptr, SourceLocation(), SourceLocation(),
+                                  nullptr, QualType(), nullptr,
+                                  ObjCIvarDecl::None, nullptr, false);
 }
 
 const ObjCInterfaceDecl *ObjCIvarDecl::getContainingInterface() const {
@@ -1397,14 +1488,14 @@
 *ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC,
                              SourceLocation StartLoc,  SourceLocation IdLoc,
                              IdentifierInfo *Id, QualType T, Expr *BW) {
-  return new (C) ObjCAtDefsFieldDecl(DC, StartLoc, IdLoc, Id, T, BW);
+  return new (C, DC) ObjCAtDefsFieldDecl(DC, StartLoc, IdLoc, Id, T, BW);
 }
 
-ObjCAtDefsFieldDecl *ObjCAtDefsFieldDecl::CreateDeserialized(ASTContext &C, 
+ObjCAtDefsFieldDecl *ObjCAtDefsFieldDecl::CreateDeserialized(ASTContext &C,
                                                              unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCAtDefsFieldDecl));
-  return new (Mem) ObjCAtDefsFieldDecl(0, SourceLocation(), SourceLocation(),
-                                       0, QualType(), 0);
+  return new (C, ID) ObjCAtDefsFieldDecl(nullptr, SourceLocation(),
+                                         SourceLocation(), nullptr, QualType(),
+                                         nullptr);
 }
 
 //===----------------------------------------------------------------------===//
@@ -1413,12 +1504,12 @@
 
 void ObjCProtocolDecl::anchor() { }
 
-ObjCProtocolDecl::ObjCProtocolDecl(DeclContext *DC, IdentifierInfo *Id,
-                                   SourceLocation nameLoc, 
+ObjCProtocolDecl::ObjCProtocolDecl(ASTContext &C, DeclContext *DC,
+                                   IdentifierInfo *Id, SourceLocation nameLoc,
                                    SourceLocation atStartLoc,
                                    ObjCProtocolDecl *PrevDecl)
-  : ObjCContainerDecl(ObjCProtocol, DC, Id, nameLoc, atStartLoc), Data()
-{
+    : ObjCContainerDecl(ObjCProtocol, DC, Id, nameLoc, atStartLoc),
+      redeclarable_base(C), Data() {
   setPreviousDecl(PrevDecl);
   if (PrevDecl)
     Data = PrevDecl->Data;
@@ -1429,17 +1520,17 @@
                                            SourceLocation nameLoc,
                                            SourceLocation atStartLoc,
                                            ObjCProtocolDecl *PrevDecl) {
-  ObjCProtocolDecl *Result 
-    = new (C) ObjCProtocolDecl(DC, Id, nameLoc, atStartLoc, PrevDecl);
+  ObjCProtocolDecl *Result =
+      new (C, DC) ObjCProtocolDecl(C, DC, Id, nameLoc, atStartLoc, PrevDecl);
   Result->Data.setInt(!C.getLangOpts().Modules);
   return Result;
 }
 
-ObjCProtocolDecl *ObjCProtocolDecl::CreateDeserialized(ASTContext &C, 
+ObjCProtocolDecl *ObjCProtocolDecl::CreateDeserialized(ASTContext &C,
                                                        unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCProtocolDecl));
-  ObjCProtocolDecl *Result = new (Mem) ObjCProtocolDecl(0, 0, SourceLocation(),
-                                                        SourceLocation(), 0);
+  ObjCProtocolDecl *Result =
+      new (C, ID) ObjCProtocolDecl(C, nullptr, nullptr, SourceLocation(),
+                                   SourceLocation(), nullptr);
   Result->Data.setInt(!C.getLangOpts().Modules);
   return Result;
 }
@@ -1450,32 +1541,32 @@
   if (Name == getIdentifier())
     return PDecl;
 
-  for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
-    if ((PDecl = (*I)->lookupProtocolNamed(Name)))
+  for (auto *I : protocols())
+    if ((PDecl = I->lookupProtocolNamed(Name)))
       return PDecl;
 
-  return NULL;
+  return nullptr;
 }
 
 // lookupMethod - Lookup a instance/class method in the protocol and protocols
 // it inherited.
 ObjCMethodDecl *ObjCProtocolDecl::lookupMethod(Selector Sel,
                                                bool isInstance) const {
-  ObjCMethodDecl *MethodDecl = NULL;
+  ObjCMethodDecl *MethodDecl = nullptr;
 
   // If there is no definition or the definition is hidden, we don't find
   // anything.
   const ObjCProtocolDecl *Def = getDefinition();
   if (!Def || Def->isHidden())
-    return NULL;
+    return nullptr;
 
   if ((MethodDecl = getMethod(Sel, isInstance)))
     return MethodDecl;
 
-  for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
-    if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
+  for (const auto *I : protocols())
+    if ((MethodDecl = I->lookupMethod(Sel, isInstance)))
       return MethodDecl;
-  return NULL;
+  return nullptr;
 }
 
 void ObjCProtocolDecl::allocateDefinitionData() {
@@ -1488,8 +1579,7 @@
   allocateDefinitionData();
   
   // Update all of the declarations with a pointer to the definition.
-  for (redecl_iterator RD = redecls_begin(), RDEnd = redecls_end();
-       RD != RDEnd; ++RD)
+  for (auto RD : redecls())
     RD->Data = this->Data;
 }
 
@@ -1497,17 +1587,14 @@
                                                     PropertyDeclOrder &PO) const {
   
   if (const ObjCProtocolDecl *PDecl = getDefinition()) {
-    for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(),
-         E = PDecl->prop_end(); P != E; ++P) {
-      ObjCPropertyDecl *Prop = *P;
+    for (auto *Prop : PDecl->properties()) {
       // Insert into PM if not there already.
       PM.insert(std::make_pair(Prop->getIdentifier(), Prop));
       PO.push_back(Prop);
     }
     // Scan through protocol's protocols.
-    for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
-         E = PDecl->protocol_end(); PI != E; ++PI)
-      (*PI)->collectPropertiesToImplement(PM, PO);
+    for (const auto *PI : PDecl->protocols())
+      PI->collectPropertiesToImplement(PM, PO);
   }
 }
 
@@ -1517,9 +1604,7 @@
                                                 ProtocolPropertyMap &PM) const {
   if (const ObjCProtocolDecl *PDecl = getDefinition()) {
     bool MatchFound = false;
-    for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(),
-         E = PDecl->prop_end(); P != E; ++P) {
-      ObjCPropertyDecl *Prop = *P;
+    for (auto *Prop : PDecl->properties()) {
       if (Prop == Property)
         continue;
       if (Prop->getIdentifier() == Property->getIdentifier()) {
@@ -1530,12 +1615,19 @@
     }
     // Scan through protocol's protocols which did not have a matching property.
     if (!MatchFound)
-      for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
-           E = PDecl->protocol_end(); PI != E; ++PI)
-        (*PI)->collectInheritedProtocolProperties(Property, PM);
+      for (const auto *PI : PDecl->protocols())
+        PI->collectInheritedProtocolProperties(Property, PM);
   }
 }
 
+StringRef
+ObjCProtocolDecl::getObjCRuntimeNameAsString() const {
+  if (ObjCRuntimeNameAttr *ObjCRTName = getAttr<ObjCRuntimeNameAttr>())
+    return ObjCRTName->getMetadataName();
+
+  return getName();
+}
+
 //===----------------------------------------------------------------------===//
 // ObjCCategoryDecl
 //===----------------------------------------------------------------------===//
@@ -1543,17 +1635,16 @@
 void ObjCCategoryDecl::anchor() { }
 
 ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
-                                           SourceLocation AtLoc, 
+                                           SourceLocation AtLoc,
                                            SourceLocation ClassNameLoc,
                                            SourceLocation CategoryNameLoc,
                                            IdentifierInfo *Id,
                                            ObjCInterfaceDecl *IDecl,
                                            SourceLocation IvarLBraceLoc,
                                            SourceLocation IvarRBraceLoc) {
-  ObjCCategoryDecl *CatDecl = new (C) ObjCCategoryDecl(DC, AtLoc, ClassNameLoc,
-                                                       CategoryNameLoc, Id,
-                                                       IDecl,
-                                                       IvarLBraceLoc, IvarRBraceLoc);
+  ObjCCategoryDecl *CatDecl =
+      new (C, DC) ObjCCategoryDecl(DC, AtLoc, ClassNameLoc, CategoryNameLoc, Id,
+                                   IDecl, IvarLBraceLoc, IvarRBraceLoc);
   if (IDecl) {
     // Link this category into its class's category list.
     CatDecl->NextClassCategory = IDecl->getCategoryListRaw();
@@ -1567,11 +1658,11 @@
   return CatDecl;
 }
 
-ObjCCategoryDecl *ObjCCategoryDecl::CreateDeserialized(ASTContext &C, 
+ObjCCategoryDecl *ObjCCategoryDecl::CreateDeserialized(ASTContext &C,
                                                        unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCCategoryDecl));
-  return new (Mem) ObjCCategoryDecl(0, SourceLocation(), SourceLocation(),
-                                    SourceLocation(), 0, 0);
+  return new (C, ID) ObjCCategoryDecl(nullptr, SourceLocation(),
+                                      SourceLocation(), SourceLocation(),
+                                      nullptr, nullptr);
 }
 
 ObjCCategoryImplDecl *ObjCCategoryDecl::getImplementation() const {
@@ -1599,22 +1690,22 @@
                              SourceLocation CategoryNameLoc) {
   if (ClassInterface && ClassInterface->hasDefinition())
     ClassInterface = ClassInterface->getDefinition();
-  return new (C) ObjCCategoryImplDecl(DC, Id, ClassInterface,
-                                      nameLoc, atStartLoc, CategoryNameLoc);
+  return new (C, DC) ObjCCategoryImplDecl(DC, Id, ClassInterface, nameLoc,
+                                          atStartLoc, CategoryNameLoc);
 }
 
 ObjCCategoryImplDecl *ObjCCategoryImplDecl::CreateDeserialized(ASTContext &C, 
                                                                unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCCategoryImplDecl));
-  return new (Mem) ObjCCategoryImplDecl(0, 0, 0, SourceLocation(), 
-                                        SourceLocation(), SourceLocation());
+  return new (C, ID) ObjCCategoryImplDecl(nullptr, nullptr, nullptr,
+                                          SourceLocation(), SourceLocation(),
+                                          SourceLocation());
 }
 
 ObjCCategoryDecl *ObjCCategoryImplDecl::getCategoryDecl() const {
   // The class interface might be NULL if we are working with invalid code.
   if (const ObjCInterfaceDecl *ID = getClassInterface())
     return ID->FindCategoryDeclaration(getIdentifier());
-  return 0;
+  return nullptr;
 }
 
 
@@ -1649,13 +1740,11 @@
 ///
 ObjCPropertyImplDecl *ObjCImplDecl::
 FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
-  for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
-    ObjCPropertyImplDecl *PID = *i;
+  for (auto *PID : property_impls())
     if (PID->getPropertyIvarDecl() &&
         PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
       return PID;
-  }
-  return 0;
+  return nullptr;
 }
 
 /// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
@@ -1664,12 +1753,10 @@
 ///
 ObjCPropertyImplDecl *ObjCImplDecl::
 FindPropertyImplDecl(IdentifierInfo *Id) const {
-  for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
-    ObjCPropertyImplDecl *PID = *i;
+  for (auto *PID : property_impls())
     if (PID->getPropertyDecl()->getIdentifier() == Id)
       return PID;
-  }
-  return 0;
+  return nullptr;
 }
 
 raw_ostream &clang::operator<<(raw_ostream &OS,
@@ -1695,16 +1782,15 @@
                                SourceLocation IvarRBraceLoc) {
   if (ClassInterface && ClassInterface->hasDefinition())
     ClassInterface = ClassInterface->getDefinition();
-  return new (C) ObjCImplementationDecl(DC, ClassInterface, SuperDecl,
-                                        nameLoc, atStartLoc, superLoc,
-                                        IvarLBraceLoc, IvarRBraceLoc);
+  return new (C, DC) ObjCImplementationDecl(DC, ClassInterface, SuperDecl,
+                                            nameLoc, atStartLoc, superLoc,
+                                            IvarLBraceLoc, IvarRBraceLoc);
 }
 
 ObjCImplementationDecl *
 ObjCImplementationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCImplementationDecl));
-  return new (Mem) ObjCImplementationDecl(0, 0, 0, SourceLocation(), 
-                                          SourceLocation());
+  return new (C, ID) ObjCImplementationDecl(nullptr, nullptr, nullptr,
+                                            SourceLocation(), SourceLocation());
 }
 
 void ObjCImplementationDecl::setIvarInitializers(ASTContext &C,
@@ -1737,13 +1823,13 @@
                                 SourceLocation L,
                                 IdentifierInfo *Id,
                                 ObjCInterfaceDecl* AliasedClass) {
-  return new (C) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
+  return new (C, DC) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
 }
 
 ObjCCompatibleAliasDecl *
 ObjCCompatibleAliasDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCCompatibleAliasDecl));
-  return new (Mem) ObjCCompatibleAliasDecl(0, SourceLocation(), 0, 0);
+  return new (C, ID) ObjCCompatibleAliasDecl(nullptr, SourceLocation(),
+                                             nullptr, nullptr);
 }
 
 //===----------------------------------------------------------------------===//
@@ -1759,15 +1845,14 @@
                                            SourceLocation LParenLoc,
                                            TypeSourceInfo *T,
                                            PropertyControl propControl) {
-  return new (C) ObjCPropertyDecl(DC, L, Id, AtLoc, LParenLoc, T);
+  return new (C, DC) ObjCPropertyDecl(DC, L, Id, AtLoc, LParenLoc, T);
 }
 
-ObjCPropertyDecl *ObjCPropertyDecl::CreateDeserialized(ASTContext &C, 
+ObjCPropertyDecl *ObjCPropertyDecl::CreateDeserialized(ASTContext &C,
                                                        unsigned ID) {
-  void * Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCPropertyDecl));
-  return new (Mem) ObjCPropertyDecl(0, SourceLocation(), 0, SourceLocation(),
-                                    SourceLocation(),
-                                    0);
+  return new (C, ID) ObjCPropertyDecl(nullptr, SourceLocation(), nullptr,
+                                      SourceLocation(), SourceLocation(),
+                                      nullptr);
 }
 
 //===----------------------------------------------------------------------===//
@@ -1782,15 +1867,15 @@
                                                    Kind PK,
                                                    ObjCIvarDecl *ivar,
                                                    SourceLocation ivarLoc) {
-  return new (C) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar,
-                                      ivarLoc);
+  return new (C, DC) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar,
+                                          ivarLoc);
 }
 
-ObjCPropertyImplDecl *ObjCPropertyImplDecl::CreateDeserialized(ASTContext &C, 
+ObjCPropertyImplDecl *ObjCPropertyImplDecl::CreateDeserialized(ASTContext &C,
                                                                unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ObjCPropertyImplDecl));
-  return new (Mem) ObjCPropertyImplDecl(0, SourceLocation(), SourceLocation(),
-                                        0, Dynamic, 0, SourceLocation());
+  return new (C, ID) ObjCPropertyImplDecl(nullptr, SourceLocation(),
+                                          SourceLocation(), nullptr, Dynamic,
+                                          nullptr, SourceLocation());
 }
 
 SourceRange ObjCPropertyImplDecl::getSourceRange() const {
diff --git a/lib/AST/DeclOpenMP.cpp b/lib/AST/DeclOpenMP.cpp
index 0d195f7..5f8b42b 100644
--- a/lib/AST/DeclOpenMP.cpp
+++ b/lib/AST/DeclOpenMP.cpp
@@ -12,8 +12,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/AST/ASTContext.h"
-#include "clang/AST/DeclBase.h"
 #include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
 #include "clang/AST/DeclOpenMP.h"
 #include "clang/AST/Expr.h"
 
@@ -29,12 +29,8 @@
                                                    DeclContext *DC,
                                                    SourceLocation L,
                                                    ArrayRef<Expr *> VL) {
-  unsigned Size = sizeof(OMPThreadPrivateDecl) +
-                  (VL.size() * sizeof(Expr *));
-
-  void *Mem = C.Allocate(Size, llvm::alignOf<OMPThreadPrivateDecl>());
-  OMPThreadPrivateDecl *D = new (Mem) OMPThreadPrivateDecl(OMPThreadPrivate,
-                                                           DC, L);
+  OMPThreadPrivateDecl *D = new (C, DC, VL.size() * sizeof(Expr *))
+      OMPThreadPrivateDecl(OMPThreadPrivate, DC, L);
   D->NumVars = VL.size();
   D->setVars(VL);
   return D;
@@ -43,11 +39,8 @@
 OMPThreadPrivateDecl *OMPThreadPrivateDecl::CreateDeserialized(ASTContext &C,
                                                                unsigned ID,
                                                                unsigned N) {
-  unsigned Size = sizeof(OMPThreadPrivateDecl) + (N * sizeof(Expr *));
-
-  void *Mem = AllocateDeserializedDecl(C, ID, Size);
-  OMPThreadPrivateDecl *D = new (Mem) OMPThreadPrivateDecl(OMPThreadPrivate,
-                                                           0, SourceLocation());
+  OMPThreadPrivateDecl *D = new (C, ID, N * sizeof(Expr *))
+      OMPThreadPrivateDecl(OMPThreadPrivate, nullptr, SourceLocation());
   D->NumVars = N;
   return D;
 }
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index 767f662..e5e5130 100644
--- a/lib/AST/DeclPrinter.cpp
+++ b/lib/AST/DeclPrinter.cpp
@@ -85,7 +85,7 @@
     void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D);
 
     void PrintTemplateParameters(const TemplateParameterList *Params,
-                                 const TemplateArgumentList *Args = 0);
+                                 const TemplateArgumentList *Args = nullptr);
     void prettyPrintAttributes(Decl *D);
   };
 }
@@ -114,7 +114,7 @@
     else if (const ArrayType* ATy = dyn_cast<ArrayType>(BaseType))
       BaseType = ATy->getElementType();
     else if (const FunctionType* FTy = BaseType->getAs<FunctionType>())
-      BaseType = FTy->getResultType();
+      BaseType = FTy->getReturnType();
     else if (const VectorType *VTy = BaseType->getAs<VectorType>())
       BaseType = VTy->getElementType();
     else if (const ReferenceType *RTy = BaseType->getAs<ReferenceType>())
@@ -167,7 +167,7 @@
   }
 }
 
-void DeclContext::dumpDeclContext() const {
+LLVM_DUMP_METHOD void DeclContext::dumpDeclContext() const {
   // Get the translation unit
   const DeclContext *DC = this;
   while (!DC->isTranslationUnit())
@@ -238,17 +238,6 @@
     if (D->isImplicit())
       continue;
 
-    // FIXME: Ugly hack so we don't pretty-print the builtin declaration
-    // of __builtin_va_list or __[u]int128_t.  There should be some other way
-    // to check that.
-    if (NamedDecl *ND = dyn_cast<NamedDecl>(*D)) {
-      if (IdentifierInfo *II = ND->getIdentifier()) {
-        if (II->isStr("__builtin_va_list") ||
-            II->isStr("__int128_t") || II->isStr("__uint128_t"))
-          continue;
-      }
-    }
-
     // The next bits of code handles stuff like "struct {int x;} a,b"; we're
     // forced to merge the declarations because there's no other way to
     // refer to the struct in question.  This limited merging is safe without
@@ -293,21 +282,21 @@
     Visit(*D);
 
     // FIXME: Need to be able to tell the DeclPrinter when
-    const char *Terminator = 0;
+    const char *Terminator = nullptr;
     if (isa<OMPThreadPrivateDecl>(*D))
-      Terminator = 0;
+      Terminator = nullptr;
     else if (isa<FunctionDecl>(*D) &&
              cast<FunctionDecl>(*D)->isThisDeclarationADefinition())
-      Terminator = 0;
+      Terminator = nullptr;
     else if (isa<ObjCMethodDecl>(*D) && cast<ObjCMethodDecl>(*D)->getBody())
-      Terminator = 0;
+      Terminator = nullptr;
     else if (isa<NamespaceDecl>(*D) || isa<LinkageSpecDecl>(*D) ||
              isa<ObjCImplementationDecl>(*D) ||
              isa<ObjCInterfaceDecl>(*D) ||
              isa<ObjCProtocolDecl>(*D) ||
              isa<ObjCCategoryImplDecl>(*D) ||
              isa<ObjCCategoryDecl>(*D))
-      Terminator = 0;
+      Terminator = nullptr;
     else if (isa<EnumConstantDecl>(*D)) {
       DeclContext::decl_iterator Next = D;
       ++Next;
@@ -390,12 +379,13 @@
   Out << *D;
   if (Expr *Init = D->getInitExpr()) {
     Out << " = ";
-    Init->printPretty(Out, 0, Policy, Indentation);
+    Init->printPretty(Out, nullptr, Policy, Indentation);
   }
 }
 
 void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
   CXXConstructorDecl *CDecl = dyn_cast<CXXConstructorDecl>(D);
+  CXXConversionDecl *ConversionDecl = dyn_cast<CXXConversionDecl>(D);
   if (!Policy.SuppressSpecifiers) {
     switch (D->getStorageClass()) {
     case SC_None: break;
@@ -409,7 +399,9 @@
     if (D->isInlineSpecified())  Out << "inline ";
     if (D->isVirtualAsWritten()) Out << "virtual ";
     if (D->isModulePrivate())    Out << "__module_private__ ";
-    if (CDecl && CDecl->isExplicitSpecified())
+    if (D->isConstexpr() && !D->isExplicitlyDefaulted()) Out << "constexpr ";
+    if ((CDecl && CDecl->isExplicitSpecified()) ||
+        (ConversionDecl && ConversionDecl->isExplicit()))
       Out << "explicit ";
   }
 
@@ -423,9 +415,8 @@
     Ty = PT->getInnerType();
   }
 
-  if (isa<FunctionType>(Ty)) {
-    const FunctionType *AFT = Ty->getAs<FunctionType>();
-    const FunctionProtoType *FT = 0;
+  if (const FunctionType *AFT = Ty->getAs<FunctionType>()) {
+    const FunctionProtoType *FT = nullptr;
     if (D->hasWrittenPrototype())
       FT = dyn_cast<FunctionProtoType>(AFT);
 
@@ -459,6 +450,17 @@
         Proto += " volatile";
       if (FT->isRestrict())
         Proto += " restrict";
+
+      switch (FT->getRefQualifier()) {
+      case RQ_None:
+        break;
+      case RQ_LValue:
+        Proto += " &";
+        break;
+      case RQ_RValue:
+        Proto += " &&";
+        break;
+      }
     }
 
     if (FT && FT->hasDynamicExceptionSpec()) {
@@ -478,7 +480,7 @@
       if (FT->getExceptionSpecType() == EST_ComputedNoexcept) {
         Proto += "(";
         llvm::raw_string_ostream EOut(Proto);
-        FT->getNoexceptExpr()->printPretty(EOut, 0, SubPolicy,
+        FT->getNoexceptExpr()->printPretty(EOut, nullptr, SubPolicy,
                                            Indentation);
         EOut.flush();
         Proto += EOut.str();
@@ -488,10 +490,7 @@
 
     if (CDecl) {
       bool HasInitializerList = false;
-      for (CXXConstructorDecl::init_const_iterator B = CDecl->init_begin(),
-           E = CDecl->init_end();
-           B != E; ++B) {
-        CXXCtorInitializer *BMInitializer = (*B);
+      for (const auto *BMInitializer : CDecl->inits()) {
         if (BMInitializer->isInClassMemberInitializer())
           continue;
 
@@ -519,9 +518,9 @@
             Init = Tmp->getSubExpr();
           
           Init = Init->IgnoreParens();
-          
-          Expr *SimpleInit = 0;
-          Expr **Args = 0;
+
+          Expr *SimpleInit = nullptr;
+          Expr **Args = nullptr;
           unsigned NumArgs = 0;
           if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) {
             Args = ParenList->getExprs();
@@ -534,29 +533,32 @@
             SimpleInit = Init;
           
           if (SimpleInit)
-            SimpleInit->printPretty(Out, 0, Policy, Indentation);
+            SimpleInit->printPretty(Out, nullptr, Policy, Indentation);
           else {
             for (unsigned I = 0; I != NumArgs; ++I) {
+              assert(Args[I] != nullptr && "Expected non-null Expr");
               if (isa<CXXDefaultArgExpr>(Args[I]))
                 break;
               
               if (I)
                 Out << ", ";
-              Args[I]->printPretty(Out, 0, Policy, Indentation);
+              Args[I]->printPretty(Out, nullptr, Policy, Indentation);
             }
           }
         }
         Out << ")";
+        if (BMInitializer->isPackExpansion())
+          Out << "...";
       }
-      if (!Proto.empty())
-        Out << Proto;
-    } else {
+    } else if (!ConversionDecl && !isa<CXXDestructorDecl>(D)) {
       if (FT && FT->hasTrailingReturn()) {
         Out << "auto " << Proto << " -> ";
         Proto.clear();
       }
-      AFT->getResultType().print(Out, Policy, Proto);
+      AFT->getReturnType().print(Out, Policy, Proto);
+      Proto.clear();
     }
+    Out << Proto;
   } else {
     Ty.print(Out, Policy, Proto);
   }
@@ -585,7 +587,8 @@
     } else
       Out << ' ';
 
-    D->getBody()->printPretty(Out, 0, SubPolicy, Indentation);
+    if (D->getBody())
+      D->getBody()->printPretty(Out, nullptr, SubPolicy, Indentation);
     Out << '\n';
   }
 }
@@ -626,7 +629,7 @@
 
   if (D->isBitField()) {
     Out << " : ";
-    D->getBitWidth()->printPretty(Out, 0, Policy, Indentation);
+    D->getBitWidth()->printPretty(Out, nullptr, Policy, Indentation);
   }
 
   Expr *Init = D->getInClassInitializer();
@@ -635,7 +638,7 @@
       Out << " ";
     else
       Out << " = ";
-    Init->printPretty(Out, 0, Policy, Indentation);
+    Init->printPretty(Out, nullptr, Policy, Indentation);
   }
   prettyPrintAttributes(D);
 }
@@ -690,7 +693,7 @@
       else if (D->getInitStyle() == VarDecl::CInit) {
         Out << " = ";
       }
-      Init->printPretty(Out, 0, Policy, Indentation);
+      Init->printPretty(Out, nullptr, Policy, Indentation);
       if ((D->getInitStyle() == VarDecl::CallInit) && !isa<ParenListExpr>(Init))
         Out << ")";
     }
@@ -704,7 +707,7 @@
 
 void DeclPrinter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) {
   Out << "__asm (";
-  D->getAsmString()->printPretty(Out, 0, Policy, Indentation);
+  D->getAsmString()->printPretty(Out, nullptr, Policy, Indentation);
   Out << ")";
 }
 
@@ -715,9 +718,9 @@
 
 void DeclPrinter::VisitStaticAssertDecl(StaticAssertDecl *D) {
   Out << "static_assert(";
-  D->getAssertExpr()->printPretty(Out, 0, Policy, Indentation);
+  D->getAssertExpr()->printPretty(Out, nullptr, Policy, Indentation);
   Out << ", ";
-  D->getMessage()->printPretty(Out, 0, Policy, Indentation);
+  D->getMessage()->printPretty(Out, nullptr, Policy, Indentation);
   Out << ")";
 }
 
@@ -855,7 +858,8 @@
         Args->get(i).print(Policy, Out);
       } else if (NTTP->hasDefaultArgument()) {
         Out << " = ";
-        NTTP->getDefaultArgument()->printPretty(Out, 0, Policy, Indentation);
+        NTTP->getDefaultArgument()->printPretty(Out, nullptr, Policy,
+                                                Indentation);
       }
     } else if (const TemplateTemplateParmDecl *TTPD =
                  dyn_cast<TemplateTemplateParmDecl>(Param)) {
@@ -884,10 +888,9 @@
 void DeclPrinter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
   if (PrintInstantiation) {
     TemplateParameterList *Params = D->getTemplateParameters();
-    for (FunctionTemplateDecl::spec_iterator I = D->spec_begin(), E = D->spec_end();
-         I != E; ++I) {
-      PrintTemplateParameters(Params, (*I)->getTemplateSpecializationArgs());
-      Visit(*I);
+    for (auto *I : D->specializations()) {
+      PrintTemplateParameters(Params, I->getTemplateSpecializationArgs());
+      Visit(I);
     }
   }
 
@@ -897,10 +900,9 @@
 void DeclPrinter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
   if (PrintInstantiation) {
     TemplateParameterList *Params = D->getTemplateParameters();
-    for (ClassTemplateDecl::spec_iterator I = D->spec_begin(), E = D->spec_end();
-         I != E; ++I) {
-      PrintTemplateParameters(Params, &(*I)->getTemplateArgs());
-      Visit(*I);
+    for (auto *I : D->specializations()) {
+      PrintTemplateParameters(Params, &I->getTemplateArgs());
+      Visit(I);
       Out << '\n';
     }
   }
@@ -917,19 +919,19 @@
     Out << "- ";
   else
     Out << "+ ";
-  if (!OMD->getResultType().isNull())
-    Out << '(' << OMD->getASTContext().getUnqualifiedObjCPointerType(OMD->getResultType()).
-                    getAsString(Policy) << ")";
+  if (!OMD->getReturnType().isNull())
+    Out << '(' << OMD->getASTContext()
+                      .getUnqualifiedObjCPointerType(OMD->getReturnType())
+                      .getAsString(Policy) << ")";
 
   std::string name = OMD->getSelector().getAsString();
   std::string::size_type pos, lastPos = 0;
-  for (ObjCMethodDecl::param_iterator PI = OMD->param_begin(),
-       E = OMD->param_end(); PI != E; ++PI) {
+  for (const auto *PI : OMD->params()) {
     // FIXME: selector is missing here!
     pos = name.find_first_of(':', lastPos);
     Out << " " << name.substr(lastPos, pos - lastPos);
-    Out << ":(" << (*PI)->getASTContext().getUnqualifiedObjCPointerType((*PI)->getType()).
-                      getAsString(Policy) << ')' << **PI;
+    Out << ":(" << PI->getASTContext().getUnqualifiedObjCPointerType(PI->getType()).
+                      getAsString(Policy) << ')' << *PI;
     lastPos = pos + 1;
   }
 
@@ -941,7 +943,7 @@
 
   if (OMD->getBody() && !Policy.TerseOutput) {
     Out << ' ';
-    OMD->getBody()->printPretty(Out, 0, Policy);
+    OMD->getBody()->printPretty(Out, nullptr, Policy);
     Out << '\n';
   }
   else if (Policy.PolishForDeclaration)
@@ -960,10 +962,9 @@
   if (OID->ivar_size() > 0) {
     Out << "{\n";
     Indentation += Policy.Indentation;
-    for (ObjCImplementationDecl::ivar_iterator I = OID->ivar_begin(),
-         E = OID->ivar_end(); I != E; ++I) {
+    for (const auto *I : OID->ivars()) {
       Indent() << I->getASTContext().getUnqualifiedObjCPointerType(I->getType()).
-                    getAsString(Policy) << ' ' << **I << ";\n";
+                    getAsString(Policy) << ' ' << *I << ";\n";
     }
     Indentation -= Policy.Indentation;
     Out << "}\n";
@@ -999,10 +1000,10 @@
     Out << "{\n";
     eolnOut = true;
     Indentation += Policy.Indentation;
-    for (ObjCInterfaceDecl::ivar_iterator I = OID->ivar_begin(),
-         E = OID->ivar_end(); I != E; ++I) {
-      Indent() << I->getASTContext().getUnqualifiedObjCPointerType(I->getType()).
-                    getAsString(Policy) << ' ' << **I << ";\n";
+    for (const auto *I : OID->ivars()) {
+      Indent() << I->getASTContext()
+                      .getUnqualifiedObjCPointerType(I->getType())
+                      .getAsString(Policy) << ' ' << *I << ";\n";
     }
     Indentation -= Policy.Indentation;
     Out << "}\n";
@@ -1051,11 +1052,9 @@
   if (PID->ivar_size() > 0) {
     Out << "{\n";
     Indentation += Policy.Indentation;
-    for (ObjCCategoryDecl::ivar_iterator I = PID->ivar_begin(),
-         E = PID->ivar_end(); I != E; ++I) {
+    for (const auto *I : PID->ivars())
       Indent() << I->getASTContext().getUnqualifiedObjCPointerType(I->getType()).
-                    getAsString(Policy) << ' ' << **I << ";\n";
-    }
+                    getAsString(Policy) << ' ' << *I << ";\n";
     Indentation -= Policy.Indentation;
     Out << "}\n";
   }
@@ -1090,13 +1089,13 @@
     }
 
     if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_getter) {
-      Out << (first ? ' ' : ',') << "getter = "
-          << PDecl->getGetterName().getAsString();
+      Out << (first ? ' ' : ',') << "getter = ";
+      PDecl->getGetterName().print(Out);
       first = false;
     }
     if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_setter) {
-      Out << (first ? ' ' : ',') << "setter = "
-          << PDecl->getSetterName().getAsString();
+      Out << (first ? ' ' : ',') << "setter = ";
+      PDecl->getSetterName().print(Out);
       first = false;
     }
 
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index 7172fb7..0d1d2a4 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -164,13 +164,13 @@
 typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType*
 RedeclarableTemplateDecl::findSpecializationImpl(
                                  llvm::FoldingSetVector<EntryType> &Specs,
-                                 const TemplateArgument *Args, unsigned NumArgs,
+                                 ArrayRef<TemplateArgument> Args,
                                  void *&InsertPos) {
   typedef SpecEntryTraits<EntryType> SETraits;
   llvm::FoldingSetNodeID ID;
-  EntryType::Profile(ID,Args,NumArgs, getASTContext());
+  EntryType::Profile(ID,Args, getASTContext());
   EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
-  return Entry ? SETraits::getMostRecentDecl(Entry) : 0;
+  return Entry ? SETraits::getMostRecentDecl(Entry) : nullptr;
 }
 
 /// \brief Generate the injected template arguments for the given template
@@ -229,14 +229,13 @@
                                                TemplateParameterList *Params,
                                                    NamedDecl *Decl) {
   AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
-  return new (C) FunctionTemplateDecl(DC, L, Name, Params, Decl);
+  return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
 }
 
 FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
                                                                unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FunctionTemplateDecl));
-  return new (Mem) FunctionTemplateDecl(0, SourceLocation(), DeclarationName(),
-                                        0, 0);
+  return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
+                                          DeclarationName(), nullptr, nullptr);
 }
 
 RedeclarableTemplateDecl::CommonBase *
@@ -251,7 +250,7 @@
   if (CommonPtr->LazySpecializations) {
     ASTContext &Context = getASTContext();
     uint32_t *Specs = CommonPtr->LazySpecializations;
-    CommonPtr->LazySpecializations = 0;
+    CommonPtr->LazySpecializations = nullptr;
     for (uint32_t I = 0, N = *Specs++; I != N; ++I)
       (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
   }
@@ -264,9 +263,9 @@
 }
 
 FunctionDecl *
-FunctionTemplateDecl::findSpecialization(const TemplateArgument *Args,
-                                         unsigned NumArgs, void *&InsertPos) {
-  return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
+FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
+                                         void *&InsertPos) {
+  return findSpecializationImpl(getSpecializations(), Args, InsertPos);
 }
 
 void FunctionTemplateDecl::addSpecialization(
@@ -308,15 +307,16 @@
                                              NamedDecl *Decl,
                                              ClassTemplateDecl *PrevDecl) {
   AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
-  ClassTemplateDecl *New = new (C) ClassTemplateDecl(DC, L, Name, Params, Decl);
+  ClassTemplateDecl *New = new (C, DC) ClassTemplateDecl(C, DC, L, Name,
+                                                         Params, Decl);
   New->setPreviousDecl(PrevDecl);
   return New;
 }
 
-ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C, 
+ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
                                                          unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ClassTemplateDecl));
-  return new (Mem) ClassTemplateDecl(EmptyShell());
+  return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
+                                       DeclarationName(), nullptr, nullptr);
 }
 
 void ClassTemplateDecl::LoadLazySpecializations() const {
@@ -324,7 +324,7 @@
   if (CommonPtr->LazySpecializations) {
     ASTContext &Context = getASTContext();
     uint32_t *Specs = CommonPtr->LazySpecializations;
-    CommonPtr->LazySpecializations = 0;
+    CommonPtr->LazySpecializations = nullptr;
     for (uint32_t I = 0, N = *Specs++; I != N; ++I)
       (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
   }
@@ -350,9 +350,9 @@
 }
 
 ClassTemplateSpecializationDecl *
-ClassTemplateDecl::findSpecialization(const TemplateArgument *Args,
-                                      unsigned NumArgs, void *&InsertPos) {
-  return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
+ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
+                                      void *&InsertPos) {
+  return findSpecializationImpl(getSpecializations(), Args, InsertPos);
 }
 
 void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
@@ -370,11 +370,9 @@
 }
 
 ClassTemplatePartialSpecializationDecl *
-ClassTemplateDecl::findPartialSpecialization(const TemplateArgument *Args,
-                                             unsigned NumArgs,
+ClassTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
                                              void *&InsertPos) {
-  return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs,
-                                InsertPos);
+  return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
 }
 
 void ClassTemplateDecl::AddPartialSpecialization(
@@ -418,7 +416,7 @@
       return P->getMostRecentDecl();
   }
 
-  return 0;
+  return nullptr;
 }
 
 ClassTemplatePartialSpecializationDecl *
@@ -433,7 +431,7 @@
       return P->getMostRecentDecl();
   }
 
-  return 0;
+  return nullptr;
 }
 
 QualType
@@ -471,17 +469,16 @@
                              unsigned D, unsigned P, IdentifierInfo *Id,
                              bool Typename, bool ParameterPack) {
   TemplateTypeParmDecl *TTPDecl =
-    new (C) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
+    new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
   QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
-  TTPDecl->TypeForDecl = TTPType.getTypePtr();
+  TTPDecl->setTypeForDecl(TTPType.getTypePtr());
   return TTPDecl;
 }
 
 TemplateTypeParmDecl *
 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TemplateTypeParmDecl));
-  return new (Mem) TemplateTypeParmDecl(0, SourceLocation(), SourceLocation(),
-                                        0, false);
+  return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(),
+                                          SourceLocation(), nullptr, false);
 }
 
 SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
@@ -499,15 +496,15 @@
 }
 
 unsigned TemplateTypeParmDecl::getDepth() const {
-  return TypeForDecl->getAs<TemplateTypeParmType>()->getDepth();
+  return getTypeForDecl()->getAs<TemplateTypeParmType>()->getDepth();
 }
 
 unsigned TemplateTypeParmDecl::getIndex() const {
-  return TypeForDecl->getAs<TemplateTypeParmType>()->getIndex();
+  return getTypeForDecl()->getAs<TemplateTypeParmType>()->getIndex();
 }
 
 bool TemplateTypeParmDecl::isParameterPack() const {
-  return TypeForDecl->getAs<TemplateTypeParmType>()->isParameterPack();
+  return getTypeForDecl()->getAs<TemplateTypeParmType>()->isParameterPack();
 }
 
 //===----------------------------------------------------------------------===//
@@ -525,7 +522,7 @@
                                                  unsigned NumExpandedTypes,
                                                 TypeSourceInfo **ExpandedTInfos)
   : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
-    TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false),
+    TemplateParmPosition(D, P), DefaultArgumentAndInherited(nullptr, false),
     ParameterPack(true), ExpandedParameterPack(true),
     NumExpandedTypes(NumExpandedTypes)
 {
@@ -544,8 +541,8 @@
                                 unsigned D, unsigned P, IdentifierInfo *Id,
                                 QualType T, bool ParameterPack,
                                 TypeSourceInfo *TInfo) {
-  return new (C) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
-                                         T, ParameterPack, TInfo);
+  return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
+                                             T, ParameterPack, TInfo);
 }
 
 NonTypeTemplateParmDecl *
@@ -557,34 +554,26 @@
                                 const QualType *ExpandedTypes, 
                                 unsigned NumExpandedTypes,
                                 TypeSourceInfo **ExpandedTInfos) {
-  unsigned Size = sizeof(NonTypeTemplateParmDecl) 
-                + NumExpandedTypes * 2 * sizeof(void*);
-  void *Mem = C.Allocate(Size);
-  return new (Mem) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc,
-                                           D, P, Id, T, TInfo,
-                                           ExpandedTypes, NumExpandedTypes, 
-                                           ExpandedTInfos);
+  unsigned Extra = NumExpandedTypes * 2 * sizeof(void*);
+  return new (C, DC, Extra) NonTypeTemplateParmDecl(
+      DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
+      ExpandedTypes, NumExpandedTypes, ExpandedTInfos);
 }
 
 NonTypeTemplateParmDecl *
 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(NonTypeTemplateParmDecl));
-  return new (Mem) NonTypeTemplateParmDecl(0, SourceLocation(), 
-                                           SourceLocation(), 0, 0, 0, 
-                                           QualType(), false, 0);
+  return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(),
+                                             SourceLocation(), 0, 0, nullptr,
+                                             QualType(), false, nullptr);
 }
 
 NonTypeTemplateParmDecl *
 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
                                             unsigned NumExpandedTypes) {
-  unsigned Size = sizeof(NonTypeTemplateParmDecl) 
-                + NumExpandedTypes * 2 * sizeof(void*);
-  
-  void *Mem = AllocateDeserializedDecl(C, ID, Size);
-  return new (Mem) NonTypeTemplateParmDecl(0, SourceLocation(), 
-                                           SourceLocation(), 0, 0, 0,
-                                           QualType(), 0, 0, NumExpandedTypes,
-                                           0);
+  unsigned Extra = NumExpandedTypes * 2 * sizeof(void*);
+  return new (C, ID, Extra) NonTypeTemplateParmDecl(
+      nullptr, SourceLocation(), SourceLocation(), 0, 0, nullptr, QualType(),
+      nullptr, nullptr, NumExpandedTypes, nullptr);
 }
 
 SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
@@ -624,8 +613,8 @@
                                  SourceLocation L, unsigned D, unsigned P,
                                  bool ParameterPack, IdentifierInfo *Id,
                                  TemplateParameterList *Params) {
-  return new (C) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id, 
-                                          Params);
+  return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
+                                              Params);
 }
 
 TemplateTemplateParmDecl *
@@ -634,28 +623,23 @@
                                  IdentifierInfo *Id,
                                  TemplateParameterList *Params,
                                  ArrayRef<TemplateParameterList *> Expansions) {
-  void *Mem = C.Allocate(sizeof(TemplateTemplateParmDecl) +
-                         sizeof(TemplateParameterList*) * Expansions.size());
-  return new (Mem) TemplateTemplateParmDecl(DC, L, D, P, Id, Params,
-                                            Expansions.size(),
-                                            Expansions.data());
+  return new (C, DC, sizeof(TemplateParameterList*) * Expansions.size())
+      TemplateTemplateParmDecl(DC, L, D, P, Id, Params,
+                               Expansions.size(), Expansions.data());
 }
 
 TemplateTemplateParmDecl *
 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TemplateTemplateParmDecl));
-  return new (Mem) TemplateTemplateParmDecl(0, SourceLocation(), 0, 0, false,
-                                            0, 0);
+  return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
+                                              false, nullptr, nullptr);
 }
 
 TemplateTemplateParmDecl *
 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
                                              unsigned NumExpansions) {
-  unsigned Size = sizeof(TemplateTemplateParmDecl) +
-                  sizeof(TemplateParameterList*) * NumExpansions;
-  void *Mem = AllocateDeserializedDecl(C, ID, Size);
-  return new (Mem) TemplateTemplateParmDecl(0, SourceLocation(), 0, 0, 0, 0,
-                                            NumExpansions, 0);
+  return new (C, ID, sizeof(TemplateParameterList*) * NumExpansions)
+      TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
+                               nullptr, NumExpansions, nullptr);
 }
 
 //===----------------------------------------------------------------------===//
@@ -682,7 +666,7 @@
                                        const TemplateArgumentList *TemplateArgs,
                           const TemplateArgumentListInfo *TemplateArgsAsWritten,
                                            SourceLocation POI) {
-  const ASTTemplateArgumentListInfo *ArgsAsWritten = 0;
+  const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
   if (TemplateArgsAsWritten)
     ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
                                                         *TemplateArgsAsWritten);
@@ -710,20 +694,20 @@
                                 const TemplateArgument *Args,
                                 unsigned NumArgs,
                                 ClassTemplateSpecializationDecl *PrevDecl)
-  : CXXRecordDecl(DK, TK, DC, StartLoc, IdLoc,
+  : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
                   SpecializedTemplate->getIdentifier(),
                   PrevDecl),
     SpecializedTemplate(SpecializedTemplate),
-    ExplicitInfo(0),
+    ExplicitInfo(nullptr),
     TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
     SpecializationKind(TSK_Undeclared) {
 }
 
-ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(Kind DK)
-  : CXXRecordDecl(DK, TTK_Struct, 0, SourceLocation(), SourceLocation(), 0, 0),
-    ExplicitInfo(0),
-    SpecializationKind(TSK_Undeclared) {
-}
+ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
+                                                                 Kind DK)
+    : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
+                    SourceLocation(), nullptr, nullptr),
+      ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
 
 ClassTemplateSpecializationDecl *
 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
@@ -734,13 +718,10 @@
                                         const TemplateArgument *Args,
                                         unsigned NumArgs,
                                    ClassTemplateSpecializationDecl *PrevDecl) {
-  ClassTemplateSpecializationDecl *Result
-    = new (Context)ClassTemplateSpecializationDecl(Context,
-                                                   ClassTemplateSpecialization,
-                                                   TK, DC, StartLoc, IdLoc,
-                                                   SpecializedTemplate,
-                                                   Args, NumArgs,
-                                                   PrevDecl);
+  ClassTemplateSpecializationDecl *Result =
+      new (Context, DC) ClassTemplateSpecializationDecl(
+          Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
+          SpecializedTemplate, Args, NumArgs, PrevDecl);
   Result->MayHaveOutOfDateDef = false;
 
   Context.getTypeDeclType(Result, PrevDecl);
@@ -748,12 +729,10 @@
 }
 
 ClassTemplateSpecializationDecl *
-ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, 
+ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
                                                     unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, 
-                                       sizeof(ClassTemplateSpecializationDecl));
   ClassTemplateSpecializationDecl *Result =
-    new (Mem) ClassTemplateSpecializationDecl(ClassTemplateSpecialization);
+    new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
   Result->MayHaveOutOfDateDef = false;
   return Result;
 }
@@ -797,7 +776,7 @@
     typedef ClassTemplatePartialSpecializationDecl CTPSDecl;
     CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this));
     CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
-    assert(inst_from != 0);
+    assert(inst_from != nullptr);
     return inst_from->getSourceRange();
   }
   else {
@@ -836,7 +815,7 @@
                                     SpecializedTemplate,
                                     Args, NumArgs, PrevDecl),
     TemplateParams(Params), ArgsAsWritten(ArgInfos),
-    InstantiatedFromMember(0, false)
+    InstantiatedFromMember(nullptr, false)
 {
   AdoptTemplateParameterList(Params, this);
 }
@@ -855,14 +834,10 @@
   const ASTTemplateArgumentListInfo *ASTArgInfos =
     ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
 
-  ClassTemplatePartialSpecializationDecl *Result
-    = new (Context)ClassTemplatePartialSpecializationDecl(Context, TK, DC,
-                                                          StartLoc, IdLoc,
-                                                          Params,
-                                                          SpecializedTemplate,
-                                                          Args, NumArgs,
-                                                          ASTArgInfos,
-                                                          PrevDecl);
+  ClassTemplatePartialSpecializationDecl *Result = new (Context, DC)
+      ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
+                                             Params, SpecializedTemplate, Args,
+                                             NumArgs, ASTArgInfos, PrevDecl);
   Result->setSpecializationKind(TSK_ExplicitSpecialization);
   Result->MayHaveOutOfDateDef = false;
 
@@ -873,10 +848,8 @@
 ClassTemplatePartialSpecializationDecl *
 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
                                                            unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, 
-                sizeof(ClassTemplatePartialSpecializationDecl));
-  ClassTemplatePartialSpecializationDecl *Result
-    = new (Mem) ClassTemplatePartialSpecializationDecl();
+  ClassTemplatePartialSpecializationDecl *Result =
+      new (C, ID) ClassTemplatePartialSpecializationDecl(C);
   Result->MayHaveOutOfDateDef = false;
   return Result;
 }
@@ -894,15 +867,13 @@
                                                TemplateParameterList **Params,
                                                FriendUnion Friend,
                                                SourceLocation FLoc) {
-  FriendTemplateDecl *Result
-    = new (Context) FriendTemplateDecl(DC, L, NParams, Params, Friend, FLoc);
-  return Result;
+  return new (Context, DC) FriendTemplateDecl(DC, L, NParams, Params,
+                                              Friend, FLoc);
 }
 
 FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
                                                            unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FriendTemplateDecl));
-  return new (Mem) FriendTemplateDecl(EmptyShell());
+  return new (C, ID) FriendTemplateDecl(EmptyShell());
 }
 
 //===----------------------------------------------------------------------===//
@@ -916,14 +887,13 @@
                                                   TemplateParameterList *Params,
                                                      NamedDecl *Decl) {
   AdoptTemplateParameterList(Params, DC);
-  return new (C) TypeAliasTemplateDecl(DC, L, Name, Params, Decl);
+  return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
 }
 
 TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
                                                                  unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TypeAliasTemplateDecl));
-  return new (Mem) TypeAliasTemplateDecl(0, SourceLocation(), DeclarationName(),
-                                         0, 0);
+  return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
+                                           DeclarationName(), nullptr, nullptr);
 }
 
 void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
@@ -945,10 +915,8 @@
 ClassScopeFunctionSpecializationDecl *
 ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
                                                          unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, 
-                sizeof(ClassScopeFunctionSpecializationDecl));
-  return new (Mem) ClassScopeFunctionSpecializationDecl(0, SourceLocation(), 0,
-                                             false, TemplateArgumentListInfo());
+  return new (C, ID) ClassScopeFunctionSpecializationDecl(
+      nullptr, SourceLocation(), nullptr, false, TemplateArgumentListInfo());
 }
 
 //===----------------------------------------------------------------------===//
@@ -966,33 +934,30 @@
       return CurD;
     CurD = CurD->getPreviousDecl();
   }
-  return 0;
+  return nullptr;
 }
 
 VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
                                          SourceLocation L, DeclarationName Name,
                                          TemplateParameterList *Params,
-                                         NamedDecl *Decl,
-                                         VarTemplateDecl *PrevDecl) {
-  VarTemplateDecl *New = new (C) VarTemplateDecl(DC, L, Name, Params, Decl);
-  New->setPreviousDecl(PrevDecl);
-  return New;
+                                         VarDecl *Decl) {
+  return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
 }
 
 VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
                                                      unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(VarTemplateDecl));
-  return new (Mem) VarTemplateDecl(EmptyShell());
+  return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
+                                     DeclarationName(), nullptr, nullptr);
 }
 
-// TODO: Unify accross class, function and variable templates?
+// TODO: Unify across class, function and variable templates?
 //       May require moving this and Common to RedeclarableTemplateDecl.
 void VarTemplateDecl::LoadLazySpecializations() const {
   Common *CommonPtr = getCommonPtr();
   if (CommonPtr->LazySpecializations) {
     ASTContext &Context = getASTContext();
     uint32_t *Specs = CommonPtr->LazySpecializations;
-    CommonPtr->LazySpecializations = 0;
+    CommonPtr->LazySpecializations = nullptr;
     for (uint32_t I = 0, N = *Specs++; I != N; ++I)
       (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
   }
@@ -1018,9 +983,9 @@
 }
 
 VarTemplateSpecializationDecl *
-VarTemplateDecl::findSpecialization(const TemplateArgument *Args,
-                                    unsigned NumArgs, void *&InsertPos) {
-  return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
+VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
+                                    void *&InsertPos) {
+  return findSpecializationImpl(getSpecializations(), Args, InsertPos);
 }
 
 void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
@@ -1038,10 +1003,9 @@
 }
 
 VarTemplatePartialSpecializationDecl *
-VarTemplateDecl::findPartialSpecialization(const TemplateArgument *Args,
-                                           unsigned NumArgs, void *&InsertPos) {
-  return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs,
-                                InsertPos);
+VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
+                                           void *&InsertPos) {
+  return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
 }
 
 void VarTemplateDecl::AddPartialSpecialization(
@@ -1084,47 +1048,43 @@
       return P->getMostRecentDecl();
   }
 
-  return 0;
+  return nullptr;
 }
 
 //===----------------------------------------------------------------------===//
 // VarTemplateSpecializationDecl Implementation
 //===----------------------------------------------------------------------===//
 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
-    ASTContext &Context, Kind DK, DeclContext *DC, SourceLocation StartLoc,
+    Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
     SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
     TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
     unsigned NumArgs)
-    : VarDecl(DK, DC, StartLoc, IdLoc, SpecializedTemplate->getIdentifier(), T,
-              TInfo, S),
-      SpecializedTemplate(SpecializedTemplate), ExplicitInfo(0),
+    : VarDecl(DK, Context, DC, StartLoc, IdLoc,
+              SpecializedTemplate->getIdentifier(), T, TInfo, S),
+      SpecializedTemplate(SpecializedTemplate), ExplicitInfo(nullptr),
       TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
       SpecializationKind(TSK_Undeclared) {}
 
-VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK)
-    : VarDecl(DK, 0, SourceLocation(), SourceLocation(), 0, QualType(), 0,
-              SC_None),
-      ExplicitInfo(0), SpecializationKind(TSK_Undeclared) {}
+VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
+                                                             ASTContext &C)
+    : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
+              QualType(), nullptr, SC_None),
+      ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
 
 VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
     ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
     SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
     TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
     unsigned NumArgs) {
-  VarTemplateSpecializationDecl *Result = new (Context)
-      VarTemplateSpecializationDecl(Context, VarTemplateSpecialization, DC,
-                                    StartLoc, IdLoc, SpecializedTemplate, T,
-                                    TInfo, S, Args, NumArgs);
-  return Result;
+  return new (Context, DC) VarTemplateSpecializationDecl(
+      VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
+      SpecializedTemplate, T, TInfo, S, Args, NumArgs);
 }
 
 VarTemplateSpecializationDecl *
 VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  void *Mem =
-      AllocateDeserializedDecl(C, ID, sizeof(VarTemplateSpecializationDecl));
-  VarTemplateSpecializationDecl *Result =
-      new (Mem) VarTemplateSpecializationDecl(VarTemplateSpecialization);
-  return Result;
+  return new (C, ID)
+      VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
 }
 
 void VarTemplateSpecializationDecl::getNameForDiagnostic(
@@ -1163,11 +1123,11 @@
     VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
     StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
     const ASTTemplateArgumentListInfo *ArgInfos)
-    : VarTemplateSpecializationDecl(Context, VarTemplatePartialSpecialization,
+    : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
                                     DC, StartLoc, IdLoc, SpecializedTemplate, T,
                                     TInfo, S, Args, NumArgs),
       TemplateParams(Params), ArgsAsWritten(ArgInfos),
-      InstantiatedFromMember(0, false) {
+      InstantiatedFromMember(nullptr, false) {
   // TODO: The template parameters should be in DC by now. Verify.
   // AdoptTemplateParameterList(Params, DC);
 }
@@ -1183,7 +1143,7 @@
     = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
 
   VarTemplatePartialSpecializationDecl *Result =
-      new (Context) VarTemplatePartialSpecializationDecl(
+      new (Context, DC) VarTemplatePartialSpecializationDecl(
           Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
           S, Args, NumArgs, ASTArgInfos);
   Result->setSpecializationKind(TSK_ExplicitSpecialization);
@@ -1193,9 +1153,5 @@
 VarTemplatePartialSpecializationDecl *
 VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
                                                          unsigned ID) {
-  void *Mem = AllocateDeserializedDecl(
-      C, ID, sizeof(VarTemplatePartialSpecializationDecl));
-  VarTemplatePartialSpecializationDecl *Result =
-      new (Mem) VarTemplatePartialSpecializationDecl();
-  return Result;
+  return new (C, ID) VarTemplatePartialSpecializationDecl(C);
 }
diff --git a/lib/AST/DeclarationName.cpp b/lib/AST/DeclarationName.cpp
index e064e23..b7c2877 100644
--- a/lib/AST/DeclarationName.cpp
+++ b/lib/AST/DeclarationName.cpp
@@ -143,13 +143,16 @@
   case DeclarationName::ObjCZeroArgSelector:
   case DeclarationName::ObjCOneArgSelector:
   case DeclarationName::ObjCMultiArgSelector:
-    return OS << N.getObjCSelector().getAsString();
+    N.getObjCSelector().print(OS);
+    return OS;
 
   case DeclarationName::CXXConstructorName: {
     QualType ClassType = N.getCXXNameType();
     if (const RecordType *ClassRec = ClassType->getAs<RecordType>())
       return OS << *ClassRec->getDecl();
-    return OS << ClassType.getAsString();
+    LangOptions LO;
+    LO.CPlusPlus = true;
+    return OS << ClassType.getAsString(PrintingPolicy(LO));
   }
 
   case DeclarationName::CXXDestructorName: {
@@ -157,12 +160,14 @@
     QualType Type = N.getCXXNameType();
     if (const RecordType *Rec = Type->getAs<RecordType>())
       return OS << *Rec->getDecl();
-    return OS << Type.getAsString();
+    LangOptions LO;
+    LO.CPlusPlus = true;
+    return OS << Type.getAsString(PrintingPolicy(LO));
   }
 
   case DeclarationName::CXXOperatorName: {
     static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
-      0,
+      nullptr,
 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
       Spelling,
 #include "clang/Basic/OperatorKinds.def"
@@ -184,7 +189,10 @@
     QualType Type = N.getCXXNameType();
     if (const RecordType *Rec = Type->getAs<RecordType>())
       return OS << *Rec->getDecl();
-    return OS << Type.getAsString();
+    LangOptions LO;
+    LO.CPlusPlus = true;
+    LO.Bool = true;
+    return OS << Type.getAsString(PrintingPolicy(LO));
   }
   case DeclarationName::CXXUsingDirective:
     return OS << "<using-directive>";
@@ -265,7 +273,7 @@
   if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
     return CXXLit->ID;
   else
-    return 0;
+    return nullptr;
 }
 
 void *DeclarationName::getFETokenInfoAsVoidSlow() const {
@@ -338,7 +346,7 @@
   for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
     CXXOperatorNames[Op].ExtraKindOrNumArgs
       = Op + DeclarationNameExtra::CXXConversionFunction;
-    CXXOperatorNames[Op].FETokenInfo = 0;
+    CXXOperatorNames[Op].FETokenInfo = nullptr;
   }
 }
 
@@ -399,14 +407,14 @@
   ID.AddInteger(EKind);
   ID.AddPointer(Ty.getAsOpaquePtr());
 
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
   if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
     return DeclarationName(Name);
 
   CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName;
   SpecialName->ExtraKindOrNumArgs = EKind;
   SpecialName->Type = Ty;
-  SpecialName->FETokenInfo = 0;
+  SpecialName->FETokenInfo = nullptr;
 
   SpecialNames->InsertNode(SpecialName, InsertPos);
   return DeclarationName(SpecialName);
@@ -426,7 +434,7 @@
   llvm::FoldingSetNodeID ID;
   ID.AddPointer(II);
 
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
   if (CXXLiteralOperatorIdName *Name =
                                LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
     return DeclarationName (Name);
@@ -434,7 +442,7 @@
   CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName;
   LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
   LiteralName->ID = II;
-  LiteralName->FETokenInfo = 0;
+  LiteralName->FETokenInfo = nullptr;
 
   LiteralNames->InsertNode(LiteralName, InsertPos);
   return DeclarationName(LiteralName);
@@ -447,7 +455,7 @@
   case DeclarationName::CXXConstructorName:
   case DeclarationName::CXXDestructorName:
   case DeclarationName::CXXConversionFunctionName:
-    NamedType.TInfo = 0;
+    NamedType.TInfo = nullptr;
     break;
   case DeclarationName::CXXOperatorName:
     CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
@@ -537,7 +545,10 @@
         OS << '~';
       else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
         OS << "operator ";
-      OS << TInfo->getType().getAsString();
+      LangOptions LO;
+      LO.CPlusPlus = true;
+      LO.Bool = true;
+      OS << TInfo->getType().getAsString(PrintingPolicy(LO));
     } else
       OS << Name;
     return;
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 9055dda..5f559b7 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -44,7 +44,7 @@
     DerivedType = PTy->getPointeeType();
 
   if (DerivedType->isDependentType())
-    return NULL;
+    return nullptr;
 
   const RecordType *Ty = DerivedType->castAs<RecordType>();
   Decl *D = Ty->getDecl();
@@ -105,37 +105,6 @@
   return E;
 }
 
-const Expr *
-Expr::findMaterializedTemporary(const MaterializeTemporaryExpr *&MTE) const {
-  const Expr *E = this;
-
-  // This might be a default initializer for a reference member. Walk over the
-  // wrapper node for that.
-  if (const CXXDefaultInitExpr *DAE = dyn_cast<CXXDefaultInitExpr>(E))
-    E = DAE->getExpr();
-
-  // Look through single-element init lists that claim to be lvalues. They're
-  // just syntactic wrappers in this case.
-  if (const InitListExpr *ILE = dyn_cast<InitListExpr>(E)) {
-    if (ILE->getNumInits() == 1 && ILE->isGLValue()) {
-      E = ILE->getInit(0);
-      if (const CXXDefaultInitExpr *DAE = dyn_cast<CXXDefaultInitExpr>(E))
-        E = DAE->getExpr();
-    }
-  }
-
-  // Look through expressions for materialized temporaries (for now).
-  if (const MaterializeTemporaryExpr *M
-      = dyn_cast<MaterializeTemporaryExpr>(E)) {
-    MTE = M;
-    E = M->GetTemporaryExpr();
-  }
-
-  if (const CXXDefaultArgExpr *DAE = dyn_cast<CXXDefaultArgExpr>(E))
-    E = DAE->getExpr();
-  return E;
-}
-
 /// isKnownToHaveBooleanValue - Return true if this is an integer expression
 /// that is known to return 0 or 1.  This happens for _Bool/bool expressions
 /// but also int expressions which are produced by things like comparisons in
@@ -152,6 +121,8 @@
     switch (UO->getOpcode()) {
     case UO_Plus:
       return UO->getSubExpr()->isKnownToHaveBooleanValue();
+    case UO_LNot:
+      return true;
     default:
       return false;
     }
@@ -431,7 +402,7 @@
                                  const TemplateArgumentListInfo *TemplateArgs) {
   // Filter out cases where the found Decl is the same as the value refenenced.
   if (D == FoundD)
-    FoundD = 0;
+    FoundD = nullptr;
 
   std::size_t Size = sizeof(DeclRefExpr);
   if (QualifierLoc)
@@ -484,7 +455,7 @@
 
   if (IT == PredefinedExpr::FuncDName) {
     if (const NamedDecl *ND = dyn_cast<NamedDecl>(CurrentDecl)) {
-      OwningPtr<MangleContext> MC;
+      std::unique_ptr<MangleContext> MC;
       MC.reset(Context.createMangleContext());
 
       if (MC->shouldMangleDeclName(ND)) {
@@ -507,7 +478,7 @@
     return "";
   }
   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CurrentDecl)) {
-    if (IT != PrettyFunction && IT != PrettyFunctionNoVirtual)
+    if (IT != PrettyFunction && IT != PrettyFunctionNoVirtual && IT != FuncSig)
       return FD->getNameAsString();
 
     SmallString<256> Name;
@@ -523,16 +494,28 @@
     PrintingPolicy Policy(Context.getLangOpts());
     std::string Proto;
     llvm::raw_string_ostream POut(Proto);
-    FD->printQualifiedName(POut, Policy);
 
     const FunctionDecl *Decl = FD;
     if (const FunctionDecl* Pattern = FD->getTemplateInstantiationPattern())
       Decl = Pattern;
     const FunctionType *AFT = Decl->getType()->getAs<FunctionType>();
-    const FunctionProtoType *FT = 0;
+    const FunctionProtoType *FT = nullptr;
     if (FD->hasWrittenPrototype())
       FT = dyn_cast<FunctionProtoType>(AFT);
 
+    if (IT == FuncSig) {
+      switch (FT->getCallConv()) {
+      case CC_C: POut << "__cdecl "; break;
+      case CC_X86StdCall: POut << "__stdcall "; break;
+      case CC_X86FastCall: POut << "__fastcall "; break;
+      case CC_X86ThisCall: POut << "__thiscall "; break;
+      // Only bother printing the conventions that MSVC knows about.
+      default: break;
+      }
+    }
+
+    FD->printQualifiedName(POut, Policy);
+
     POut << "(";
     if (FT) {
       for (unsigned i = 0, e = Decl->getNumParams(); i != e; ++i) {
@@ -619,13 +602,15 @@
     // not a constructor or destructor.
     if ((isa<CXXMethodDecl>(FD) &&
          cast<CXXMethodDecl>(FD)->getParent()->isLambda()) ||
-        (FT && FT->getResultType()->getAs<AutoType>()))
+        (FT && FT->getReturnType()->getAs<AutoType>()))
       Proto = "auto " + Proto;
-    else if (FT && FT->getResultType()->getAs<DecltypeType>())
-      FT->getResultType()->getAs<DecltypeType>()->getUnderlyingType()
+    else if (FT && FT->getReturnType()->getAs<DecltypeType>())
+      FT->getReturnType()
+          ->getAs<DecltypeType>()
+          ->getUnderlyingType()
           .getAsStringInternal(Proto, Policy);
     else if (!isa<CXXConstructorDecl>(FD) && !isa<CXXDestructorDecl>(FD))
-      AFT->getResultType().getAsStringInternal(Proto, Policy);
+      AFT->getReturnType().getAsStringInternal(Proto, Policy);
 
     Out << Proto;
 
@@ -658,7 +643,7 @@
       Out << '(' << *CID << ')';
 
     Out <<  ' ';
-    Out << MD->getSelector().getAsString();
+    MD->getSelector().print(Out);
     Out <<  ']';
 
     Out.flush();
@@ -810,6 +795,9 @@
                                      StringKind Kind, bool Pascal, QualType Ty,
                                      const SourceLocation *Loc,
                                      unsigned NumStrs) {
+  assert(C.getAsConstantArrayType(Ty) &&
+         "StringLiteral must be of constant array type!");
+
   // Allocate enough space for the StringLiteral plus an array of locations for
   // any concatenated string tokens.
   void *Mem = C.Allocate(sizeof(StringLiteral)+
@@ -1010,7 +998,7 @@
     TheLexer.LexFromRawLexer(TheTok);
     
     // Use the StringLiteralParser to compute the length of the string in bytes.
-    StringLiteralParser SLP(&TheTok, 1, SM, Features, Target);
+    StringLiteralParser SLP(TheTok, SM, Features, Target);
     unsigned TokNumBytes = SLP.GetStringLength();
     
     // If the byte is in this token, return the location of the byte.
@@ -1144,7 +1132,7 @@
 }
 
 CallExpr::CallExpr(const ASTContext &C, StmtClass SC, EmptyShell Empty)
-  : Expr(SC, Empty), SubExprs(0), NumArgs(0) {
+  : Expr(SC, Empty), SubExprs(nullptr), NumArgs(0) {
   // FIXME: Why do we allocate this?
   SubExprs = new (C) Stmt*[PREARGS_START];
   CallExprBits.NumPreArgs = 0;
@@ -1152,7 +1140,7 @@
 
 CallExpr::CallExpr(const ASTContext &C, StmtClass SC, unsigned NumPreArgs,
                    EmptyShell Empty)
-  : Expr(SC, Empty), SubExprs(0), NumArgs(0) {
+  : Expr(SC, Empty), SubExprs(nullptr), NumArgs(0) {
   // FIXME: Why do we allocate this?
   SubExprs = new (C) Stmt*[PREARGS_START+NumPreArgs];
   CallExprBits.NumPreArgs = NumPreArgs;
@@ -1179,7 +1167,7 @@
   if (MemberExpr *ME = dyn_cast<MemberExpr>(CEE))
     return ME->getMemberDecl();
 
-  return 0;
+  return nullptr;
 }
 
 FunctionDecl *CallExpr::getDirectCallee() {
@@ -1208,16 +1196,16 @@
   // Null out new args.
   for (unsigned i = getNumArgs()+PREARGS_START+NumPreArgs;
        i != NumArgs+PREARGS_START+NumPreArgs; ++i)
-    NewSubExprs[i] = 0;
+    NewSubExprs[i] = nullptr;
 
   if (SubExprs) C.Deallocate(SubExprs);
   SubExprs = NewSubExprs;
   this->NumArgs = NumArgs;
 }
 
-/// isBuiltinCall - If this is a call to a builtin, return the builtin ID.  If
+/// getBuiltinCallee - If this is a call to a builtin, return the builtin ID. If
 /// not, return 0.
-unsigned CallExpr::isBuiltinCall() const {
+unsigned CallExpr::getBuiltinCallee() const {
   // All simple function calls (e.g. func()) are implicitly cast to pointer to
   // function. As a result, we try and obtain the DeclRefExpr from the
   // ImplicitCastExpr.
@@ -1240,7 +1228,7 @@
 }
 
 bool CallExpr::isUnevaluatedBuiltinCall(ASTContext &Ctx) const {
-  if (unsigned BI = isBuiltinCall())
+  if (unsigned BI = getBuiltinCallee())
     return Ctx.BuiltinInfo.isUnevaluated(BI);
   return false;
 }
@@ -1256,7 +1244,7 @@
     CalleeType = Expr::findBoundMemberType(getCallee());
     
   const FunctionType *FnType = CalleeType->castAs<FunctionType>();
-  return FnType->getResultType();
+  return FnType->getReturnType();
 }
 
 SourceLocation CallExpr::getLocStart() const {
@@ -1421,7 +1409,7 @@
   return EndLoc;
 }
 
-void CastExpr::CheckCastConsistency() const {
+bool CastExpr::CastConsistency() const {
   switch (getCastKind()) {
   case CK_DerivedToBase:
   case CK_UncheckedDerivedToBase:
@@ -1474,6 +1462,11 @@
     assert(getSubExpr()->getType()->isFunctionType());
     goto CheckNoBasePath;
 
+  case CK_AddressSpaceConversion:
+    assert(getType()->isPointerType());
+    assert(getSubExpr()->getType()->isPointerType());
+    assert(getType()->getPointeeType().getAddressSpace() !=
+           getSubExpr()->getType()->getPointeeType().getAddressSpace());
   // These should not have an inheritance path.
   case CK_Dynamic:
   case CK_ToUnion:
@@ -1524,6 +1517,7 @@
     assert(path_empty() && "Cast kind should not have a base path!");
     break;
   }
+  return true;
 }
 
 const char *CastExpr::getCastKindName() const {
@@ -1625,7 +1619,7 @@
   case CK_ARCReclaimReturnedObject:
     return "ARCReclaimReturnedObject";
   case CK_ARCExtendBlockObject:
-    return "ARCCExtendBlockObject";
+    return "ARCExtendBlockObject";
   case CK_AtomicToNonAtomic:
     return "AtomicToNonAtomic";
   case CK_NonAtomicToAtomic:
@@ -1636,13 +1630,15 @@
     return "BuiltinFnToFnPtr";
   case CK_ZeroToOCLEvent:
     return "ZeroToOCLEvent";
+  case CK_AddressSpaceConversion:
+    return "AddressSpaceConversion";
   }
 
   llvm_unreachable("Unhandled cast kind!");
 }
 
 Expr *CastExpr::getSubExprAsWritten() {
-  Expr *SubExpr = 0;
+  Expr *SubExpr = nullptr;
   CastExpr *E = this;
   do {
     SubExpr = E->getSubExpr();
@@ -1838,7 +1834,7 @@
   : Expr(InitListExprClass, QualType(), VK_RValue, OK_Ordinary, false, false,
          false, false),
     InitExprs(C, initExprs.size()),
-    LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), AltForm(0, true)
+    LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), AltForm(nullptr, true)
 {
   sawArrayRangeDesignator(false);
   for (unsigned I = 0; I != initExprs.size(); ++I) {
@@ -1861,18 +1857,18 @@
 }
 
 void InitListExpr::resizeInits(const ASTContext &C, unsigned NumInits) {
-  InitExprs.resize(C, NumInits, 0);
+  InitExprs.resize(C, NumInits, nullptr);
 }
 
 Expr *InitListExpr::updateInit(const ASTContext &C, unsigned Init, Expr *expr) {
   if (Init >= InitExprs.size()) {
-    InitExprs.insert(C, InitExprs.end(), Init - InitExprs.size() + 1, 0);
-    InitExprs.back() = expr;
-    return 0;
+    InitExprs.insert(C, InitExprs.end(), Init - InitExprs.size() + 1, nullptr);
+    setInit(Init, expr);
+    return nullptr;
   }
 
   Expr *Result = cast_or_null<Expr>(InitExprs[Init]);
-  InitExprs[Init] = expr;
+  setInit(Init, expr);
   return Result;
 }
 
@@ -1882,7 +1878,7 @@
   // Fill out any "holes" in the array due to designated initializers.
   Expr **inits = getInits();
   for (unsigned i = 0, e = getNumInits(); i != e; ++i)
-    if (inits[i] == 0)
+    if (inits[i] == nullptr)
       inits[i] = filler;
 }
 
@@ -1892,7 +1888,11 @@
   const ArrayType *AT = getType()->getAsArrayTypeUnsafe();
   if (!AT || !AT->getElementType()->isIntegerType())
     return false;
-  const Expr *Init = getInit(0)->IgnoreParens();
+  // It is possible for getInit() to return null.
+  const Expr *Init = getInit(0);
+  if (!Init)
+    return false;
+  Init = Init->IgnoreParens();
   return isa<StringLiteral>(Init) || isa<ObjCEncodeExpr>(Init);
 }
 
@@ -2078,15 +2078,25 @@
     return true;
 
   case CXXOperatorCallExprClass: {
-    // We warn about operator== and operator!= even when user-defined operator
+    // Warn about operator ==,!=,<,>,<=, and >= even when user-defined operator
     // overloads as there is no reasonable way to define these such that they
     // have non-trivial, desirable side-effects. See the -Wunused-comparison
-    // warning: these operators are commonly typo'ed, and so warning on them
+    // warning: operators == and != are commonly typo'ed, and so warning on them
     // provides additional value as well. If this list is updated,
     // DiagnoseUnusedComparison should be as well.
     const CXXOperatorCallExpr *Op = cast<CXXOperatorCallExpr>(this);
-    if (Op->getOperator() == OO_EqualEqual ||
-        Op->getOperator() == OO_ExclaimEqual) {
+    switch (Op->getOperator()) {
+    default:
+      break;
+    case OO_EqualEqual:
+    case OO_ExclaimEqual:
+    case OO_Less:
+    case OO_Greater:
+    case OO_GreaterEqual:
+    case OO_LessEqual:
+      if (Op->getCallReturnType()->isReferenceType() ||
+          Op->getCallReturnType()->isVoidType())
+        break;
       WarnE = this;
       Loc = Op->getOperatorLoc();
       R1 = Op->getSourceRange();
@@ -2106,8 +2116,8 @@
       //
       // Note: If new cases are added here, DiagnoseUnusedExprResult should be
       // updated to match for QoI.
-      if (FD->getAttr<WarnUnusedResultAttr>() ||
-          FD->getAttr<PureAttr>() || FD->getAttr<ConstAttr>()) {
+      if (FD->hasAttr<WarnUnusedResultAttr>() ||
+          FD->hasAttr<PureAttr>() || FD->hasAttr<ConstAttr>()) {
         WarnE = this;
         Loc = CE->getCallee()->getLocStart();
         R1 = CE->getCallee()->getSourceRange();
@@ -2151,12 +2161,15 @@
       return true;
     }
 
-    const ObjCMethodDecl *MD = ME->getMethodDecl();
-    if (MD && MD->getAttr<WarnUnusedResultAttr>()) {
-      WarnE = this;
-      Loc = getExprLoc();
-      return true;
-    }
+    if (const ObjCMethodDecl *MD = ME->getMethodDecl())
+      if (MD->hasAttr<WarnUnusedResultAttr>() ||
+          (MD->isPropertyAccessor() && !MD->getReturnType()->isVoidType() &&
+           !ME->getReceiverType()->isObjCIdType())) {
+        WarnE = this;
+        Loc = getExprLoc();
+        return true;
+      }
+
     return false;
   }
 
@@ -2393,6 +2406,27 @@
   }
 }
 
+Expr *Expr::IgnoreCasts() {
+  Expr *E = this;
+  while (true) {
+    if (CastExpr *P = dyn_cast<CastExpr>(E)) {
+      E = P->getSubExpr();
+      continue;
+    }
+    if (MaterializeTemporaryExpr *Materialize
+        = dyn_cast<MaterializeTemporaryExpr>(E)) {
+      E = Materialize->GetTemporaryExpr();
+      continue;
+    }
+    if (SubstNonTypeTemplateParmExpr *NTTP
+        = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
+      E = NTTP->getReplacement();
+      continue;
+    }
+    return E;
+  }
+}
+
 /// IgnoreParenLValueCasts - Ignore parentheses and lvalue-to-rvalue
 /// casts.  This is intended purely as a temporary workaround for code
 /// that hasn't yet been rewritten to do the right thing about those
@@ -2638,7 +2672,8 @@
   return false;
 }
 
-bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef) const {
+bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef,
+                                 const Expr **Culprit) const {
   // This function is attempting whether an expression is an initializer
   // which can be evaluated at compile-time. It very closely parallels
   // ConstExprEmitter in CGExprConstant.cpp; if they don't match, it
@@ -2650,7 +2685,11 @@
 
   if (IsForRef) {
     EvalResult Result;
-    return EvaluateAsLValue(Result, Ctx) && !Result.HasSideEffects;
+    if (EvaluateAsLValue(Result, Ctx) && !Result.HasSideEffects)
+      return true;
+    if (Culprit)
+      *Culprit = this;
+    return false;
   }
 
   switch (getStmtClass()) {
@@ -2669,7 +2708,7 @@
 
       // Trivial copy constructor
       assert(CE->getNumArgs() == 1 && "trivial ctor with > 1 argument");
-      return CE->getArg(0)->isConstantInitializer(Ctx, false);
+      return CE->getArg(0)->isConstantInitializer(Ctx, false, Culprit);
     }
 
     break;
@@ -2679,14 +2718,14 @@
     // "struct x {int x;} x = (struct x) {};".
     // FIXME: This accepts other cases it shouldn't!
     const Expr *Exp = cast<CompoundLiteralExpr>(this)->getInitializer();
-    return Exp->isConstantInitializer(Ctx, false);
+    return Exp->isConstantInitializer(Ctx, false, Culprit);
   }
   case InitListExprClass: {
     const InitListExpr *ILE = cast<InitListExpr>(this);
     if (ILE->getType()->isArrayType()) {
       unsigned numInits = ILE->getNumInits();
       for (unsigned i = 0; i < numInits; i++) {
-        if (!ILE->getInit(i)->isConstantInitializer(Ctx, false))
+        if (!ILE->getInit(i)->isConstantInitializer(Ctx, false, Culprit))
           return false;
       }
       return true;
@@ -2710,11 +2749,14 @@
           if (Field->isBitField()) {
             // Bitfields have to evaluate to an integer.
             llvm::APSInt ResultTmp;
-            if (!Elt->EvaluateAsInt(ResultTmp, Ctx))
+            if (!Elt->EvaluateAsInt(ResultTmp, Ctx)) {
+              if (Culprit)
+                *Culprit = Elt;
               return false;
+            }
           } else {
             bool RefType = Field->getType()->isReferenceType();
-            if (!Elt->isConstantInitializer(Ctx, RefType))
+            if (!Elt->isConstantInitializer(Ctx, RefType, Culprit))
               return false;
           }
         }
@@ -2728,19 +2770,22 @@
     return true;
   case ParenExprClass:
     return cast<ParenExpr>(this)->getSubExpr()
-      ->isConstantInitializer(Ctx, IsForRef);
+      ->isConstantInitializer(Ctx, IsForRef, Culprit);
   case GenericSelectionExprClass:
     return cast<GenericSelectionExpr>(this)->getResultExpr()
-      ->isConstantInitializer(Ctx, IsForRef);
+      ->isConstantInitializer(Ctx, IsForRef, Culprit);
   case ChooseExprClass:
-    if (cast<ChooseExpr>(this)->isConditionDependent())
+    if (cast<ChooseExpr>(this)->isConditionDependent()) {
+      if (Culprit)
+        *Culprit = this;
       return false;
+    }
     return cast<ChooseExpr>(this)->getChosenSubExpr()
-      ->isConstantInitializer(Ctx, IsForRef);
+      ->isConstantInitializer(Ctx, IsForRef, Culprit);
   case UnaryOperatorClass: {
     const UnaryOperator* Exp = cast<UnaryOperator>(this);
     if (Exp->getOpcode() == UO_Extension)
-      return Exp->getSubExpr()->isConstantInitializer(Ctx, false);
+      return Exp->getSubExpr()->isConstantInitializer(Ctx, false, Culprit);
     break;
   }
   case CXXFunctionalCastExprClass:
@@ -2760,25 +2805,29 @@
         CE->getCastKind() == CK_ConstructorConversion ||
         CE->getCastKind() == CK_NonAtomicToAtomic ||
         CE->getCastKind() == CK_AtomicToNonAtomic)
-      return CE->getSubExpr()->isConstantInitializer(Ctx, false);
+      return CE->getSubExpr()->isConstantInitializer(Ctx, false, Culprit);
 
     break;
   }
   case MaterializeTemporaryExprClass:
     return cast<MaterializeTemporaryExpr>(this)->GetTemporaryExpr()
-                                            ->isConstantInitializer(Ctx, false);
+      ->isConstantInitializer(Ctx, false, Culprit);
 
   case SubstNonTypeTemplateParmExprClass:
     return cast<SubstNonTypeTemplateParmExpr>(this)->getReplacement()
-                                            ->isConstantInitializer(Ctx, false);
+      ->isConstantInitializer(Ctx, false, Culprit);
   case CXXDefaultArgExprClass:
     return cast<CXXDefaultArgExpr>(this)->getExpr()
-                                            ->isConstantInitializer(Ctx, false);
+      ->isConstantInitializer(Ctx, false, Culprit);
   case CXXDefaultInitExprClass:
     return cast<CXXDefaultInitExpr>(this)->getExpr()
-                                            ->isConstantInitializer(Ctx, false);
+      ->isConstantInitializer(Ctx, false, Culprit);
   }
-  return isEvaluatable(Ctx);
+  if (isEvaluatable(Ctx))
+    return true;
+  if (Culprit)
+    *Culprit = this;
+  return false;
 }
 
 bool Expr::HasSideEffects(const ASTContext &Ctx) const {
@@ -2821,8 +2870,6 @@
   case CXXThisExprClass:
   case CXXScalarValueInitExprClass:
   case TypeTraitExprClass:
-  case UnaryTypeTraitExprClass:
-  case BinaryTypeTraitExprClass:
   case ArrayTypeTraitExprClass:
   case ExpressionTraitExprClass:
   case CXXNoexceptExprClass:
@@ -3055,7 +3102,7 @@
 Expr::isNullPointerConstant(ASTContext &Ctx,
                             NullPointerConstantValueDependence NPC) const {
   if (isValueDependent() &&
-      (!Ctx.getLangOpts().CPlusPlus11 || Ctx.getLangOpts().MicrosoftMode)) {
+      (!Ctx.getLangOpts().CPlusPlus11 || Ctx.getLangOpts().MSVCCompat)) {
     switch (NPC) {
     case NPC_NeverValueDependent:
       llvm_unreachable("Unexpected value dependent expression!");
@@ -3141,8 +3188,7 @@
     const IntegerLiteral *Lit = dyn_cast<IntegerLiteral>(this);
     if (Lit && !Lit->getValue())
       return NPCK_ZeroLiteral;
-    else if (!Ctx.getLangOpts().MicrosoftMode ||
-             !isCXX98IntegralConstantExpr(Ctx))
+    else if (!Ctx.getLangOpts().MSVCCompat || !isCXX98IntegralConstantExpr(Ctx))
       return NPCK_NotNull;
   } else {
     // If we have an integer constant expression, we need to *evaluate* it and
@@ -3233,7 +3279,7 @@
       return BinOp->getRHS()->getSourceBitField();
   }
 
-  return 0;
+  return nullptr;
 }
 
 bool Expr::refersToVectorElement() const {
@@ -3339,8 +3385,9 @@
     SelectorOrMethod(reinterpret_cast<uintptr_t>(Method? Method
                                                        : Sel.getAsOpaquePtr())),
     Kind(IsInstanceSuper? SuperInstance : SuperClass),
-    HasMethod(Method != 0), IsDelegateInitCall(false), IsImplicit(isImplicit),
-    SuperLoc(SuperLoc), LBracLoc(LBracLoc), RBracLoc(RBracLoc) 
+    HasMethod(Method != nullptr), IsDelegateInitCall(false),
+    IsImplicit(isImplicit), SuperLoc(SuperLoc), LBracLoc(LBracLoc),
+    RBracLoc(RBracLoc)
 {
   initArgsAndSelLocs(Args, SelLocs, SelLocsK);
   setReceiverPointer(SuperType.getAsOpaquePtr());
@@ -3363,8 +3410,8 @@
     SelectorOrMethod(reinterpret_cast<uintptr_t>(Method? Method
                                                        : Sel.getAsOpaquePtr())),
     Kind(Class),
-    HasMethod(Method != 0), IsDelegateInitCall(false), IsImplicit(isImplicit),
-    LBracLoc(LBracLoc), RBracLoc(RBracLoc) 
+    HasMethod(Method != nullptr), IsDelegateInitCall(false),
+    IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc)
 {
   initArgsAndSelLocs(Args, SelLocs, SelLocsK);
   setReceiverPointer(Receiver);
@@ -3388,8 +3435,8 @@
     SelectorOrMethod(reinterpret_cast<uintptr_t>(Method? Method
                                                        : Sel.getAsOpaquePtr())),
     Kind(Instance),
-    HasMethod(Method != 0), IsDelegateInitCall(false), IsImplicit(isImplicit),
-    LBracLoc(LBracLoc), RBracLoc(RBracLoc) 
+    HasMethod(Method != nullptr), IsDelegateInitCall(false),
+    IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc)
 {
   initArgsAndSelLocs(Args, SelLocs, SelLocsK);
   setReceiverPointer(Receiver);
@@ -3571,7 +3618,7 @@
   if (const ObjCObjectType *Ty = T->getAs<ObjCObjectType>())
     return Ty->getInterface();
 
-  return 0;
+  return nullptr;
 }
 
 StringRef ObjCBridgedCastExpr::getBridgeKindName() const {
@@ -3806,30 +3853,21 @@
 
 Expr *DesignatedInitExpr::getArrayIndex(const Designator& D) const {
   assert(D.Kind == Designator::ArrayDesignator && "Requires array designator");
-  char *Ptr = static_cast<char *>(
-                  const_cast<void *>(static_cast<const void *>(this)));
-  Ptr += sizeof(DesignatedInitExpr);
-  Stmt **SubExprs = reinterpret_cast<Stmt**>(reinterpret_cast<void**>(Ptr));
+  Stmt *const *SubExprs = reinterpret_cast<Stmt *const *>(this + 1);
   return cast<Expr>(*(SubExprs + D.ArrayOrRange.Index + 1));
 }
 
 Expr *DesignatedInitExpr::getArrayRangeStart(const Designator &D) const {
   assert(D.Kind == Designator::ArrayRangeDesignator &&
          "Requires array range designator");
-  char *Ptr = static_cast<char *>(
-                  const_cast<void *>(static_cast<const void *>(this)));
-  Ptr += sizeof(DesignatedInitExpr);
-  Stmt **SubExprs = reinterpret_cast<Stmt**>(reinterpret_cast<void**>(Ptr));
+  Stmt *const *SubExprs = reinterpret_cast<Stmt *const *>(this + 1);
   return cast<Expr>(*(SubExprs + D.ArrayOrRange.Index + 1));
 }
 
 Expr *DesignatedInitExpr::getArrayRangeEnd(const Designator &D) const {
   assert(D.Kind == Designator::ArrayRangeDesignator &&
          "Requires array range designator");
-  char *Ptr = static_cast<char *>(
-                  const_cast<void *>(static_cast<const void *>(this)));
-  Ptr += sizeof(DesignatedInitExpr);
-  Stmt **SubExprs = reinterpret_cast<Stmt**>(reinterpret_cast<void**>(Ptr));
+  Stmt *const *SubExprs = reinterpret_cast<Stmt *const *>(this + 1);
   return cast<Expr>(*(SubExprs + D.ArrayOrRange.Index + 2));
 }
 
@@ -3953,7 +3991,7 @@
       ExprBits.ContainsUnexpandedParameterPack = true;
 
     if (isa<OpaqueValueExpr>(E))
-      assert(cast<OpaqueValueExpr>(E)->getSourceExpr() != 0 &&
+      assert(cast<OpaqueValueExpr>(E)->getSourceExpr() != nullptr &&
              "opaque-value semantic expressions for pseudo-object "
              "operations must have sources");
   }
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index 3738c0e..64c21dd 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -55,8 +55,8 @@
 }
 
 // static
-UuidAttr *CXXUuidofExpr::GetUuidAttrOfType(QualType QT,
-                                           bool *RDHasMultipleGUIDsPtr) {
+const UuidAttr *CXXUuidofExpr::GetUuidAttrOfType(QualType QT,
+                                                 bool *RDHasMultipleGUIDsPtr) {
   // Optionally remove one level of pointer, reference or array indirection.
   const Type *Ty = QT.getTypePtr();
   if (QT->isPointerType() || QT->isReferenceType())
@@ -64,22 +64,23 @@
   else if (QT->isArrayType())
     Ty = Ty->getBaseElementTypeUnsafe();
 
-  // Loop all record redeclaration looking for an uuid attribute.
-  CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();
+  const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();
   if (!RD)
-    return 0;
+    return nullptr;
+
+  if (const UuidAttr *Uuid = RD->getMostRecentDecl()->getAttr<UuidAttr>())
+    return Uuid;
 
   // __uuidof can grab UUIDs from template arguments.
-  if (ClassTemplateSpecializationDecl *CTSD =
+  if (const ClassTemplateSpecializationDecl *CTSD =
           dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
     const TemplateArgumentList &TAL = CTSD->getTemplateArgs();
-    UuidAttr *UuidForRD = 0;
+    const UuidAttr *UuidForRD = nullptr;
 
-    for (unsigned I = 0, N = TAL.size(); I != N; ++I) {
-      const TemplateArgument &TA = TAL[I];
+    for (const TemplateArgument &TA : TAL.asArray()) {
       bool SeenMultipleGUIDs = false;
 
-      UuidAttr *UuidForTA = 0;
+      const UuidAttr *UuidForTA = nullptr;
       if (TA.getKind() == TemplateArgument::Type)
         UuidForTA = GetUuidAttrOfType(TA.getAsType(), &SeenMultipleGUIDs);
       else if (TA.getKind() == TemplateArgument::Declaration)
@@ -101,20 +102,14 @@
       if (SeenMultipleGUIDs) {
         if (RDHasMultipleGUIDsPtr)
           *RDHasMultipleGUIDsPtr = true;
-        return 0;
+        return nullptr;
       }
     }
 
     return UuidForRD;
   }
 
-  for (CXXRecordDecl::redecl_iterator I = RD->redecls_begin(),
-                                      E = RD->redecls_end();
-       I != E; ++I)
-    if (UuidAttr *Uuid = I->getAttr<UuidAttr>())
-      return Uuid;
-
-  return 0;
+  return nullptr;
 }
 
 StringRef CXXUuidofExpr::getUuidAsStringRef(ASTContext &Context) const {
@@ -151,14 +146,15 @@
          ty->isDependentType(), ty->isDependentType(),
          ty->isInstantiationDependentType(),
          ty->containsUnexpandedParameterPack()),
-    SubExprs(0), OperatorNew(operatorNew), OperatorDelete(operatorDelete),
+    SubExprs(nullptr), OperatorNew(operatorNew), OperatorDelete(operatorDelete),
     AllocatedTypeInfo(allocatedTypeInfo), TypeIdParens(typeIdParens),
     Range(Range), DirectInitRange(directInitRange),
     GlobalNew(globalNew), UsualArrayDeleteWantsSize(usualArrayDeleteWantsSize) {
-  assert((initializer != 0 || initializationStyle == NoInit) &&
+  assert((initializer != nullptr || initializationStyle == NoInit) &&
          "Only NoInit can have no initializer.");
   StoredInitializationStyle = initializer ? initializationStyle + 1 : 0;
-  AllocateArgsArray(C, arraySize != 0, placementArgs.size(), initializer != 0);
+  AllocateArgsArray(C, arraySize != nullptr, placementArgs.size(),
+                    initializer != nullptr);
   unsigned i = 0;
   if (Array) {
     if (arraySize->isInstantiationDependent())
@@ -203,7 +199,7 @@
 
 void CXXNewExpr::AllocateArgsArray(const ASTContext &C, bool isArray,
                                    unsigned numPlaceArgs, bool hasInitializer){
-  assert(SubExprs == 0 && "SubExprs already allocated");
+  assert(SubExprs == nullptr && "SubExprs already allocated");
   Array = isArray;
   NumPlacementArgs = numPlaceArgs;
 
@@ -345,9 +341,9 @@
            QualifierLoc.getNestedNameSpecifier()
                                       ->containsUnexpandedParameterPack()))),
     NameInfo(NameInfo), QualifierLoc(QualifierLoc),
-    Results(0), NumResults(End - Begin),
-    HasTemplateKWAndArgsInfo(TemplateArgs != 0 || TemplateKWLoc.isValid())
-{
+    Results(nullptr), NumResults(End - Begin),
+    HasTemplateKWAndArgsInfo(TemplateArgs != nullptr ||
+                             TemplateKWLoc.isValid()) {
   NumResults = End - Begin;
   if (NumResults) {
     // Determine whether this expression is type-dependent.
@@ -398,7 +394,7 @@
 void OverloadExpr::initializeResults(const ASTContext &C,
                                      UnresolvedSetIterator Begin,
                                      UnresolvedSetIterator End) {
-  assert(Results == 0 && "Results already initialized!");
+  assert(!Results && "Results already initialized!");
   NumResults = End - Begin;
   if (NumResults) {
      Results = static_cast<DeclAccessPair *>(
@@ -433,7 +429,7 @@
            QualifierLoc.getNestedNameSpecifier()
                             ->containsUnexpandedParameterPack()))),
     QualifierLoc(QualifierLoc), NameInfo(NameInfo), 
-    HasTemplateKWAndArgsInfo(Args != 0 || TemplateKWLoc.isValid())
+    HasTemplateKWAndArgsInfo(Args != nullptr || TemplateKWLoc.isValid())
 {
   if (Args) {
     bool Dependent = true;
@@ -478,7 +474,7 @@
   DependentScopeDeclRefExpr *E
     = new (Mem) DependentScopeDeclRefExpr(QualType(), NestedNameSpecifierLoc(),
                                           SourceLocation(),
-                                          DeclarationNameInfo(), 0);
+                                          DeclarationNameInfo(), nullptr);
   E->HasTemplateKWAndArgsInfo = HasTemplateKWAndArgsInfo;
   return E;
 }
@@ -544,7 +540,7 @@
       return BO->getLHS();
 
   // FIXME: Will eventually need to cope with member pointers.
-  return 0;
+  return nullptr;
 }
 
 CXXMethodDecl *CXXMemberCallExpr::getMethodDecl() const {
@@ -553,14 +549,14 @@
     return cast<CXXMethodDecl>(MemExpr->getMemberDecl());
 
   // FIXME: Will eventually need to cope with member pointers.
-  return 0;
+  return nullptr;
 }
 
 
 CXXRecordDecl *CXXMemberCallExpr::getRecordDecl() const {
   Expr* ThisArg = getImplicitObjectArgument();
   if (!ThisArg)
-    return 0;
+    return nullptr;
 
   if (ThisArg->getType()->isAnyPointerType())
     return ThisArg->getType()->getPointeeType()->getAsCXXRecordDecl();
@@ -810,13 +806,16 @@
                                                SourceRange ParenOrBraceRange,
                                                bool HadMultipleCandidates,
                                                bool ListInitialization,
+                                               bool StdInitListInitialization,
                                                bool ZeroInitialization)
   : CXXConstructExpr(C, CXXTemporaryObjectExprClass, 
                      Type->getType().getNonReferenceType(), 
                      Type->getTypeLoc().getBeginLoc(),
                      Cons, false, Args,
                      HadMultipleCandidates,
-                     ListInitialization, ZeroInitialization,
+                     ListInitialization,
+                     StdInitListInitialization,
+                     ZeroInitialization,
                      CXXConstructExpr::CK_Complete, ParenOrBraceRange),
     Type(Type) {
 }
@@ -838,12 +837,14 @@
                                            ArrayRef<Expr*> Args,
                                            bool HadMultipleCandidates,
                                            bool ListInitialization,
+                                           bool StdInitListInitialization,
                                            bool ZeroInitialization,
                                            ConstructionKind ConstructKind,
                                            SourceRange ParenOrBraceRange) {
   return new (C) CXXConstructExpr(C, CXXConstructExprClass, T, Loc, D, 
                                   Elidable, Args,
                                   HadMultipleCandidates, ListInitialization,
+                                  StdInitListInitialization,
                                   ZeroInitialization, ConstructKind,
                                   ParenOrBraceRange);
 }
@@ -854,6 +855,7 @@
                                    ArrayRef<Expr*> args,
                                    bool HadMultipleCandidates,
                                    bool ListInitialization,
+                                   bool StdInitListInitialization,
                                    bool ZeroInitialization,
                                    ConstructionKind ConstructKind,
                                    SourceRange ParenOrBraceRange)
@@ -865,8 +867,9 @@
     NumArgs(args.size()),
     Elidable(elidable), HadMultipleCandidates(HadMultipleCandidates),
     ListInitialization(ListInitialization),
+    StdInitListInitialization(StdInitListInitialization),
     ZeroInitialization(ZeroInitialization),
-    ConstructKind(ConstructKind), Args(0)
+    ConstructKind(ConstructKind), Args(nullptr)
 {
   if (NumArgs) {
     Args = new (C) Stmt*[args.size()];
@@ -886,7 +889,7 @@
   }
 }
 
-LambdaExpr::Capture::Capture(SourceLocation Loc, bool Implicit,
+LambdaCapture::LambdaCapture(SourceLocation Loc, bool Implicit,
                              LambdaCaptureKind Kind, VarDecl *Var,
                              SourceLocation EllipsisLoc)
   : DeclAndBits(Var, 0), Loc(Loc), EllipsisLoc(EllipsisLoc)
@@ -896,8 +899,8 @@
     Bits |= Capture_Implicit;
   
   switch (Kind) {
-  case LCK_This: 
-    assert(Var == 0 && "'this' capture cannot have a variable!");
+  case LCK_This:
+    assert(!Var && "'this' capture cannot have a variable!");
     break;
 
   case LCK_ByCopy:
@@ -910,7 +913,7 @@
   DeclAndBits.setInt(Bits);
 }
 
-LambdaCaptureKind LambdaExpr::Capture::getCaptureKind() const {
+LambdaCaptureKind LambdaCapture::getCaptureKind() const {
   Decl *D = DeclAndBits.getPointer();
   if (!D)
     return LCK_This;
@@ -1031,6 +1034,10 @@
   return capture_begin() + NumCaptures;
 }
 
+LambdaExpr::capture_range LambdaExpr::captures() const {
+  return capture_range(capture_begin(), capture_end());
+}
+
 LambdaExpr::capture_iterator LambdaExpr::explicit_capture_begin() const {
   return capture_begin();
 }
@@ -1041,6 +1048,10 @@
   return Data.Captures + Data.NumExplicitCaptures;
 }
 
+LambdaExpr::capture_range LambdaExpr::explicit_captures() const {
+  return capture_range(explicit_capture_begin(), explicit_capture_end());
+}
+
 LambdaExpr::capture_iterator LambdaExpr::implicit_capture_begin() const {
   return explicit_capture_end();
 }
@@ -1049,6 +1060,10 @@
   return capture_end();
 }
 
+LambdaExpr::capture_range LambdaExpr::implicit_captures() const {
+  return capture_range(implicit_capture_begin(), implicit_capture_end());
+}
+
 ArrayRef<VarDecl *> 
 LambdaExpr::getCaptureInitIndexVars(capture_init_iterator Iter) const {
   assert(HasArrayIndexVars && "No array index-var data?");
@@ -1187,7 +1202,8 @@
                                        ->containsUnexpandedParameterPack()) ||
           MemberNameInfo.containsUnexpandedParameterPack())),
     Base(Base), BaseType(BaseType), IsArrow(IsArrow),
-    HasTemplateKWAndArgsInfo(TemplateArgs != 0 || TemplateKWLoc.isValid()),
+    HasTemplateKWAndArgsInfo(TemplateArgs != nullptr ||
+                             TemplateKWLoc.isValid()),
     OperatorLoc(OperatorLoc), QualifierLoc(QualifierLoc), 
     FirstQualifierFoundInScope(FirstQualifierFoundInScope),
     MemberNameInfo(MemberNameInfo) {
@@ -1260,26 +1276,26 @@
                                          bool HasTemplateKWAndArgsInfo,
                                          unsigned NumTemplateArgs) {
   if (!HasTemplateKWAndArgsInfo)
-    return new (C) CXXDependentScopeMemberExpr(C, 0, QualType(),
+    return new (C) CXXDependentScopeMemberExpr(C, nullptr, QualType(),
                                                0, SourceLocation(),
-                                               NestedNameSpecifierLoc(), 0,
-                                               DeclarationNameInfo());
+                                               NestedNameSpecifierLoc(),
+                                               nullptr, DeclarationNameInfo());
 
   std::size_t size = sizeof(CXXDependentScopeMemberExpr) +
                      ASTTemplateKWAndArgsInfo::sizeFor(NumTemplateArgs);
   void *Mem = C.Allocate(size, llvm::alignOf<CXXDependentScopeMemberExpr>());
   CXXDependentScopeMemberExpr *E
-    =  new (Mem) CXXDependentScopeMemberExpr(C, 0, QualType(),
+    =  new (Mem) CXXDependentScopeMemberExpr(C, nullptr, QualType(),
                                              0, SourceLocation(),
                                              NestedNameSpecifierLoc(),
-                                             SourceLocation(), 0,
-                                             DeclarationNameInfo(), 0);
+                                             SourceLocation(), nullptr,
+                                             DeclarationNameInfo(), nullptr);
   E->HasTemplateKWAndArgsInfo = true;
   return E;
 }
 
 bool CXXDependentScopeMemberExpr::isImplicitAccess() const {
-  if (Base == 0)
+  if (!Base)
     return true;
   
   return cast<Expr>(Base)->isImplicitCXXThis();
@@ -1291,16 +1307,11 @@
     NamedDecl *decl = *begin;
     if (isa<UnresolvedUsingValueDecl>(decl))
       return false;
-    if (isa<UsingShadowDecl>(decl))
-      decl = cast<UsingShadowDecl>(decl)->getUnderlyingDecl();
 
     // Unresolved member expressions should only contain methods and
     // method templates.
-    assert(isa<CXXMethodDecl>(decl) || isa<FunctionTemplateDecl>(decl));
-
-    if (isa<FunctionTemplateDecl>(decl))
-      decl = cast<FunctionTemplateDecl>(decl)->getTemplatedDecl();
-    if (cast<CXXMethodDecl>(decl)->isStatic())
+    if (cast<CXXMethodDecl>(decl->getUnderlyingDecl()->getAsFunction())
+            ->isStatic())
       return false;
   } while (++begin != end);
 
@@ -1338,7 +1349,7 @@
 }
 
 bool UnresolvedMemberExpr::isImplicitAccess() const {
-  if (Base == 0)
+  if (!Base)
     return true;
   
   return cast<Expr>(Base)->isImplicitCXXThis();
@@ -1387,7 +1398,7 @@
   // If there was a nested name specifier, it names the naming class.
   // It can't be dependent: after all, we were actually able to do the
   // lookup.
-  CXXRecordDecl *Record = 0;
+  CXXRecordDecl *Record = nullptr;
   if (getQualifier()) {
     const Type *T = getQualifier()->getAsType();
     assert(T && "qualifier in member expression does not name type");
@@ -1450,7 +1461,26 @@
                                   unsigned NumParams) {
   return new (Context.Allocate(sizeof(FunctionParmPackExpr) +
                                sizeof(ParmVarDecl*) * NumParams))
-    FunctionParmPackExpr(QualType(), 0, SourceLocation(), 0, 0);
+    FunctionParmPackExpr(QualType(), nullptr, SourceLocation(), 0, nullptr);
+}
+
+void MaterializeTemporaryExpr::setExtendingDecl(const ValueDecl *ExtendedBy,
+                                                unsigned ManglingNumber) {
+  // We only need extra state if we have to remember more than just the Stmt.
+  if (!ExtendedBy)
+    return;
+
+  // We may need to allocate extra storage for the mangling number and the
+  // extended-by ValueDecl.
+  if (!State.is<ExtraState *>()) {
+    auto ES = new (ExtendedBy->getASTContext()) ExtraState;
+    ES->Temporary = State.get<Stmt *>();
+    State = ES;
+  }
+
+  auto ES = State.get<ExtraState *>();
+  ES->ExtendingDecl = ExtendedBy;
+  ES->ManglingNumber = ManglingNumber;
 }
 
 TypeTraitExpr::TypeTraitExpr(QualType T, SourceLocation Loc, TypeTrait Kind,
diff --git a/lib/AST/ExprClassification.cpp b/lib/AST/ExprClassification.cpp
index 54f77ef..d3d2530 100644
--- a/lib/AST/ExprClassification.cpp
+++ b/lib/AST/ExprClassification.cpp
@@ -165,8 +165,6 @@
   case Expr::FloatingLiteralClass:
   case Expr::CXXNoexceptExprClass:
   case Expr::CXXScalarValueInitExprClass:
-  case Expr::UnaryTypeTraitExprClass:
-  case Expr::BinaryTypeTraitExprClass:
   case Expr::TypeTraitExprClass:
   case Expr::ArrayTypeTraitExprClass:
   case Expr::ExpressionTraitExprClass:
@@ -348,7 +346,7 @@
   case Expr::ObjCMessageExprClass:
     if (const ObjCMethodDecl *Method =
           cast<ObjCMessageExpr>(E)->getMethodDecl()) {
-      Cl::Kinds kind = ClassifyUnnamed(Ctx, Method->getResultType());
+      Cl::Kinds kind = ClassifyUnnamed(Ctx, Method->getReturnType());
       return (kind == Cl::CL_PRValue) ? Cl::CL_ObjCMessageRValue : kind;
     }
     return Cl::CL_PRValue;
@@ -543,10 +541,21 @@
          "This is only relevant for C++.");
 
   // C++ [expr.cond]p2
-  //   If either the second or the third operand has type (cv) void, [...]
-  //   the result [...] is a prvalue.
-  if (True->getType()->isVoidType() || False->getType()->isVoidType())
+  //   If either the second or the third operand has type (cv) void,
+  //   one of the following shall hold:
+  if (True->getType()->isVoidType() || False->getType()->isVoidType()) {
+    // The second or the third operand (but not both) is a (possibly
+    // parenthesized) throw-expression; the result is of the [...] value
+    // category of the other.
+    bool TrueIsThrow = isa<CXXThrowExpr>(True->IgnoreParenImpCasts());
+    bool FalseIsThrow = isa<CXXThrowExpr>(False->IgnoreParenImpCasts());
+    if (const Expr *NonThrow = TrueIsThrow ? (FalseIsThrow ? nullptr : False)
+                                           : (FalseIsThrow ? True : nullptr))
+      return ClassifyInternal(Ctx, NonThrow);
+
+    //   [Otherwise] the result [...] is a prvalue.
     return Cl::CL_PRValue;
+  }
 
   // Note that at this point, we have already performed all conversions
   // according to [expr.cond]p3.
@@ -584,7 +593,8 @@
   // Assignment to a property in ObjC is an implicit setter access. But a
   // setter might not exist.
   if (const ObjCPropertyRefExpr *Expr = dyn_cast<ObjCPropertyRefExpr>(E)) {
-    if (Expr->isImplicitProperty() && Expr->getImplicitPropertySetter() == 0)
+    if (Expr->isImplicitProperty() &&
+        Expr->getImplicitPropertySetter() == nullptr)
       return Cl::CM_NoSetterProperty;
   }
 
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 390cfe9..7d7ca99 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -320,7 +320,7 @@
 
     APValue *getTemporary(const void *Key) {
       MapTy::iterator I = Temporaries.find(Key);
-      return I == Temporaries.end() ? 0 : &I->second;
+      return I == Temporaries.end() ? nullptr : &I->second;
     }
     APValue &createTemporary(const void *Key, bool IsLifetimeExtended);
   };
@@ -347,7 +347,8 @@
     PartialDiagnostic *Diag;
 
   public:
-    explicit OptionalDiagnostic(PartialDiagnostic *Diag = 0) : Diag(Diag) {}
+    explicit OptionalDiagnostic(PartialDiagnostic *Diag = nullptr)
+      : Diag(Diag) {}
 
     template<typename T>
     OptionalDiagnostic &operator<<(const T &v) {
@@ -474,13 +475,30 @@
 
       /// Evaluate in any way we know how. Don't worry about side-effects that
       /// can't be modeled.
-      EM_IgnoreSideEffects
+      EM_IgnoreSideEffects,
+
+      /// Evaluate as a constant expression. Stop if we find that the expression
+      /// is not a constant expression. Some expressions can be retried in the
+      /// optimizer if we don't constant fold them here, but in an unevaluated
+      /// context we try to fold them immediately since the optimizer never
+      /// gets a chance to look at it.
+      EM_ConstantExpressionUnevaluated,
+
+      /// Evaluate as a potential constant expression. Keep going if we hit a
+      /// construct that we can't evaluate yet (because we don't yet know the
+      /// value of something) but stop if we hit something that could never be
+      /// a constant expression. Some expressions can be retried in the
+      /// optimizer if we don't constant fold them here, but in an unevaluated
+      /// context we try to fold them immediately since the optimizer never
+      /// gets a chance to look at it.
+      EM_PotentialConstantExpressionUnevaluated
     } EvalMode;
 
     /// Are we checking whether the expression is a potential constant
     /// expression?
     bool checkingPotentialConstantExpression() const {
-      return EvalMode == EM_PotentialConstantExpression;
+      return EvalMode == EM_PotentialConstantExpression ||
+             EvalMode == EM_PotentialConstantExpressionUnevaluated;
     }
 
     /// Are we checking an expression for overflow?
@@ -489,12 +507,13 @@
     bool checkingForOverflow() { return EvalMode == EM_EvaluateForOverflow; }
 
     EvalInfo(const ASTContext &C, Expr::EvalStatus &S, EvaluationMode Mode)
-      : Ctx(const_cast<ASTContext&>(C)), EvalStatus(S), CurrentCall(0),
+      : Ctx(const_cast<ASTContext &>(C)), EvalStatus(S), CurrentCall(nullptr),
         CallStackDepth(0), NextCallIndex(1),
         StepsLeft(getLangOpts().ConstexprStepLimit),
-        BottomFrame(*this, SourceLocation(), 0, 0, 0),
-        EvaluatingDecl((const ValueDecl*)0), EvaluatingDeclValue(0),
-        HasActiveDiagnostic(false), EvalMode(Mode) {}
+        BottomFrame(*this, SourceLocation(), nullptr, nullptr, nullptr),
+        EvaluatingDecl((const ValueDecl *)nullptr),
+        EvaluatingDeclValue(nullptr), HasActiveDiagnostic(false),
+        EvalMode(Mode) {}
 
     void setEvaluatingDecl(APValue::LValueBase Base, APValue &Value) {
       EvaluatingDecl = Base;
@@ -527,7 +546,7 @@
       CallStackFrame *Frame = CurrentCall;
       while (Frame->Index > CallIndex)
         Frame = Frame->Caller;
-      return (Frame->Index == CallIndex) ? Frame : 0;
+      return (Frame->Index == CallIndex) ? Frame : nullptr;
     }
 
     bool nextStep(const Stmt *S) {
@@ -573,6 +592,8 @@
             // some later problem.
           case EM_ConstantExpression:
           case EM_PotentialConstantExpression:
+          case EM_ConstantExpressionUnevaluated:
+          case EM_PotentialConstantExpressionUnevaluated:
             HasActiveDiagnostic = false;
             return OptionalDiagnostic();
           }
@@ -644,11 +665,13 @@
     bool keepEvaluatingAfterSideEffect() {
       switch (EvalMode) {
       case EM_PotentialConstantExpression:
+      case EM_PotentialConstantExpressionUnevaluated:
       case EM_EvaluateForOverflow:
       case EM_IgnoreSideEffects:
         return true;
 
       case EM_ConstantExpression:
+      case EM_ConstantExpressionUnevaluated:
       case EM_ConstantFold:
         return false;
       }
@@ -670,10 +693,12 @@
 
       switch (EvalMode) {
       case EM_PotentialConstantExpression:
+      case EM_PotentialConstantExpressionUnevaluated:
       case EM_EvaluateForOverflow:
         return true;
 
       case EM_ConstantExpression:
+      case EM_ConstantExpressionUnevaluated:
       case EM_ConstantFold:
       case EM_IgnoreSideEffects:
         return false;
@@ -696,7 +721,9 @@
                         Info.EvalStatus.Diag->empty() &&
                         !Info.EvalStatus.HasSideEffects),
         OldMode(Info.EvalMode) {
-      if (Enabled && Info.EvalMode == EvalInfo::EM_ConstantExpression)
+      if (Enabled &&
+          (Info.EvalMode == EvalInfo::EM_ConstantExpression ||
+           Info.EvalMode == EvalInfo::EM_ConstantExpressionUnevaluated))
         Info.EvalMode = EvalInfo::EM_ConstantFold;
     }
     void keepDiagnostics() { Enabled = false; }
@@ -716,7 +743,7 @@
 
   public:
     SpeculativeEvaluationRAII(EvalInfo &Info,
-                              SmallVectorImpl<PartialDiagnosticAt> *NewDiag = 0)
+                        SmallVectorImpl<PartialDiagnosticAt> *NewDiag = nullptr)
       : Info(Info), Old(Info.EvalStatus) {
       Info.EvalStatus.Diag = NewDiag;
       // If we're speculatively evaluating, we may have skipped over some
@@ -943,7 +970,7 @@
       // any object: we won't use such a designator for anything.
       if (!Info.getLangOpts().CPlusPlus11)
         Designator.setInvalid();
-      return checkNullPointer(Info, E, CSK) &&
+      return (CSK == CSK_ArrayToPointer || checkNullPointer(Info, E, CSK)) &&
              Designator.checkSubobject(Info, E, CSK);
     }
 
@@ -961,7 +988,7 @@
         Designator.addComplexUnchecked(EltTy, Imag);
     }
     void adjustIndex(EvalInfo &Info, const Expr *E, uint64_t N) {
-      if (checkNullPointer(Info, E, CSK_ArrayIndex))
+      if (N && checkNullPointer(Info, E, CSK_ArrayIndex))
         Designator.adjustIndex(Info, E, N);
     }
   };
@@ -1141,7 +1168,7 @@
 
 /// Should this call expression be treated as a string literal?
 static bool IsStringLiteralCall(const CallExpr *E) {
-  unsigned Builtin = E->isBuiltinCall();
+  unsigned Builtin = E->getBuiltinCallee();
   return (Builtin == Builtin::BI__builtin___CFStringMakeConstantString ||
           Builtin == Builtin::BI__builtin___NSStringMakeConstantString);
 }
@@ -1242,11 +1269,29 @@
           LVal.getLValueCallIndex() == 0) &&
          "have call index for global lvalue");
 
-  // Check if this is a thread-local variable.
   if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) {
     if (const VarDecl *Var = dyn_cast<const VarDecl>(VD)) {
+      // Check if this is a thread-local variable.
       if (Var->getTLSKind())
         return false;
+
+      // A dllimport variable never acts like a constant.
+      if (Var->hasAttr<DLLImportAttr>())
+        return false;
+    }
+    if (const auto *FD = dyn_cast<const FunctionDecl>(VD)) {
+      // __declspec(dllimport) must be handled very carefully:
+      // We must never initialize an expression with the thunk in C++.
+      // Doing otherwise would allow the same id-expression to yield
+      // different addresses for the same function in different translation
+      // units.  However, this means that we must dynamically initialize the
+      // expression with the contents of the import address table at runtime.
+      //
+      // The C language has no notion of ODR; furthermore, it has no notion of
+      // dynamic initialization.  This means that we are permitted to
+      // perform initialization with the address of the thunk.
+      if (Info.getLangOpts().CPlusPlus && FD->hasAttr<DLLImportAttr>())
+        return false;
     }
   }
 
@@ -1276,7 +1321,7 @@
 /// Check that this core constant expression is of literal type, and if not,
 /// produce an appropriate diagnostic.
 static bool CheckLiteralType(EvalInfo &Info, const Expr *E,
-                             const LValue *This = 0) {
+                             const LValue *This = nullptr) {
   if (!E->isRValue() || E->getType()->isLiteralType(Info.Ctx))
     return true;
 
@@ -1307,6 +1352,11 @@
     return false;
   }
 
+  // We allow _Atomic(T) to be initialized from anything that T can be
+  // initialized from.
+  if (const AtomicType *AT = Type->getAs<AtomicType>())
+    Type = AT->getValueType();
+
   // Core issue 1454: For a literal constant expression of array or class type,
   // each subobject of its value shall have been initialized by a constant
   // expression.
@@ -1338,8 +1388,7 @@
           return false;
       }
     }
-    for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
-         I != E; ++I) {
+    for (const auto *I : RD->fields()) {
       if (!CheckConstantExpression(Info, DiagLoc, I->getType(),
                                    Value.getStructField(I->getFieldIndex())))
         return false;
@@ -1738,7 +1787,7 @@
 static bool HandleLValueDirectBase(EvalInfo &Info, const Expr *E, LValue &Obj,
                                    const CXXRecordDecl *Derived,
                                    const CXXRecordDecl *Base,
-                                   const ASTRecordLayout *RL = 0) {
+                                   const ASTRecordLayout *RL = nullptr) {
   if (!RL) {
     if (Derived->isInvalidDecl()) return false;
     RL = &Info.Ctx.getASTRecordLayout(Derived);
@@ -1791,7 +1840,7 @@
 /// currently described by LVal.
 static bool HandleLValueMember(EvalInfo &Info, const Expr *E, LValue &LVal,
                                const FieldDecl *FD,
-                               const ASTRecordLayout *RL = 0) {
+                               const ASTRecordLayout *RL = nullptr) {
   if (!RL) {
     if (FD->getParent()->isInvalidDecl()) return false;
     RL = &Info.Ctx.getASTRecordLayout(FD->getParent());
@@ -1807,9 +1856,8 @@
 static bool HandleLValueIndirectMember(EvalInfo &Info, const Expr *E,
                                        LValue &LVal,
                                        const IndirectFieldDecl *IFD) {
-  for (IndirectFieldDecl::chain_iterator C = IFD->chain_begin(),
-                                         CE = IFD->chain_end(); C != CE; ++C)
-    if (!HandleLValueMember(Info, E, LVal, cast<FieldDecl>(*C)))
+  for (const auto *C : IFD->chain())
+    if (!HandleLValueMember(Info, E, LVal, cast<FieldDecl>(C)))
       return false;
   return true;
 }
@@ -2047,7 +2095,7 @@
   /// The type of the complete object.
   QualType Type;
 
-  CompleteObject() : Value(0) {}
+  CompleteObject() : Value(nullptr) {}
   CompleteObject(APValue *Value, QualType Type)
       : Value(Value), Type(Type) {
     assert(Value && "missing value for complete object");
@@ -2075,7 +2123,7 @@
 
   APValue *O = Obj.Value;
   QualType ObjType = Obj.Type;
-  const FieldDecl *LastField = 0;
+  const FieldDecl *LastField = nullptr;
 
   // Walk the designator's path to find the subobject.
   for (unsigned I = 0, N = Sub.Entries.size(); /**/; ++I) {
@@ -2098,7 +2146,7 @@
       return true;
     }
 
-    LastField = 0;
+    LastField = nullptr;
     if (ObjType->isArrayType()) {
       // Next subobject is an array element.
       const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(ObjType);
@@ -2381,7 +2429,7 @@
     return CompleteObject();
   }
 
-  CallStackFrame *Frame = 0;
+  CallStackFrame *Frame = nullptr;
   if (LVal.CallIndex) {
     Frame = Info.getCallFrame(LVal.CallIndex);
     if (!Frame) {
@@ -2406,7 +2454,7 @@
   }
 
   // Compute value storage location and type of base object.
-  APValue *BaseVal = 0;
+  APValue *BaseVal = nullptr;
   QualType BaseType = getType(LVal.Base);
 
   if (const ValueDecl *D = LVal.Base.dyn_cast<const ValueDecl*>()) {
@@ -2776,7 +2824,7 @@
     // if we're post-incrementing a complex.
     if (Old) {
       *Old = Subobj;
-      Old = 0;
+      Old = nullptr;
     }
 
     switch (Subobj.getKind()) {
@@ -2913,6 +2961,7 @@
   if (Object->getType()->isLiteralType(Info.Ctx))
     return EvaluateTemporary(Object, This, Info);
 
+  Info.Diag(Object, diag::note_constexpr_nonliteral) << Object->getType();
   return false;
 }
 
@@ -2934,14 +2983,14 @@
                                                   bool IncludeMember = true) {
   MemberPtr MemPtr;
   if (!EvaluateMemberPointer(RHS, MemPtr, Info))
-    return 0;
+    return nullptr;
 
   // C++11 [expr.mptr.oper]p6: If the second operand is the null pointer to
   // member value, the behavior is undefined.
   if (!MemPtr.getDecl()) {
     // FIXME: Specific diagnostic.
     Info.Diag(RHS);
-    return 0;
+    return nullptr;
   }
 
   if (MemPtr.isDerivedMember()) {
@@ -2951,7 +3000,7 @@
     if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() >
         LV.Designator.Entries.size()) {
       Info.Diag(RHS);
-      return 0;
+      return nullptr;
     }
     unsigned PathLengthToMember =
         LV.Designator.Entries.size() - MemPtr.Path.size();
@@ -2961,14 +3010,14 @@
       const CXXRecordDecl *MPDecl = MemPtr.Path[I];
       if (LVDecl->getCanonicalDecl() != MPDecl->getCanonicalDecl()) {
         Info.Diag(RHS);
-        return 0;
+        return nullptr;
       }
     }
 
     // Truncate the lvalue to the appropriate derived class.
     if (!CastToDerivedClass(Info, RHS, LV, MemPtr.getContainingRecord(),
                             PathLengthToMember))
-      return 0;
+      return nullptr;
   } else if (!MemPtr.Path.empty()) {
     // Extend the LValue path with the member pointer's path.
     LV.Designator.Entries.reserve(LV.Designator.Entries.size() +
@@ -2983,24 +3032,24 @@
     for (unsigned I = 1, N = MemPtr.Path.size(); I != N; ++I) {
       const CXXRecordDecl *Base = MemPtr.Path[N - I - 1];
       if (!HandleLValueDirectBase(Info, RHS, LV, RD, Base))
-        return 0;
+        return nullptr;
       RD = Base;
     }
     // Finally cast to the class containing the member.
     if (!HandleLValueDirectBase(Info, RHS, LV, RD,
                                 MemPtr.getContainingRecord()))
-      return 0;
+      return nullptr;
   }
 
   // Add the member. Note that we cannot build bound member functions here.
   if (IncludeMember) {
     if (const FieldDecl *FD = dyn_cast<FieldDecl>(MemPtr.getDecl())) {
       if (!HandleLValueMember(Info, RHS, LV, FD))
-        return 0;
+        return nullptr;
     } else if (const IndirectFieldDecl *IFD =
                  dyn_cast<IndirectFieldDecl>(MemPtr.getDecl())) {
       if (!HandleLValueIndirectMember(Info, RHS, LV, IFD))
-        return 0;
+        return nullptr;
     } else {
       llvm_unreachable("can't construct reference to bound member function");
     }
@@ -3020,7 +3069,7 @@
       MemberPtr MemPtr;
       EvaluateMemberPointer(BO->getRHS(), MemPtr, Info);
     }
-    return 0;
+    return nullptr;
   }
 
   return HandleMemberPointerAccess(Info, BO->getLHS()->getType(), LV,
@@ -3092,14 +3141,18 @@
     Result.set(VD, Info.CurrentCall->Index);
     APValue &Val = Info.CurrentCall->createTemporary(VD, true);
 
-    if (!VD->getInit()) {
+    const Expr *InitE = VD->getInit();
+    if (!InitE) {
       Info.Diag(D->getLocStart(), diag::note_constexpr_uninitialized)
         << false << VD->getType();
       Val = APValue();
       return false;
     }
 
-    if (!EvaluateInPlace(Val, Info, Result, VD->getInit())) {
+    if (InitE->isValueDependent())
+      return false;
+
+    if (!EvaluateInPlace(Val, Info, Result, InitE)) {
       // Wipe out any partially-computed value, to allow tracking that this
       // evaluation failed.
       Val = APValue();
@@ -3120,12 +3173,13 @@
 }
 
 static EvalStmtResult EvaluateStmt(APValue &Result, EvalInfo &Info,
-                                   const Stmt *S, const SwitchCase *SC = 0);
+                                   const Stmt *S,
+                                   const SwitchCase *SC = nullptr);
 
 /// Evaluate the body of a loop, and translate the result as appropriate.
 static EvalStmtResult EvaluateLoopBody(APValue &Result, EvalInfo &Info,
                                        const Stmt *Body,
-                                       const SwitchCase *Case = 0) {
+                                       const SwitchCase *Case = nullptr) {
   BlockScopeRAII Scope(Info);
   switch (EvalStmtResult ESR = EvaluateStmt(Result, Info, Body, Case)) {
   case ESR_Break:
@@ -3159,7 +3213,7 @@
 
   // Find the switch case corresponding to the value of the condition.
   // FIXME: Cache this lookup.
-  const SwitchCase *Found = 0;
+  const SwitchCase *Found = nullptr;
   for (const SwitchCase *SC = SS->getSwitchCaseList(); SC;
        SC = SC->getNextSwitchCase()) {
     if (isa<DefaultStmt>(SC)) {
@@ -3224,7 +3278,7 @@
     case Stmt::CaseStmtClass:
     case Stmt::DefaultStmtClass:
       if (Case == S)
-        Case = 0;
+        Case = nullptr;
       break;
 
     case Stmt::IfStmtClass: {
@@ -3291,13 +3345,12 @@
 
   case Stmt::DeclStmtClass: {
     const DeclStmt *DS = cast<DeclStmt>(S);
-    for (DeclStmt::const_decl_iterator DclIt = DS->decl_begin(),
-           DclEnd = DS->decl_end(); DclIt != DclEnd; ++DclIt) {
+    for (const auto *DclIt : DS->decls()) {
       // Each declaration initialization is its own full-expression.
       // FIXME: This isn't quite right; if we're performing aggregate
       // initialization, each braced subexpression is its own full-expression.
       FullExpressionRAII Scope(Info);
-      if (!EvaluateDecl(Info, *DclIt) && !Info.keepEvaluatingAfterFailure())
+      if (!EvaluateDecl(Info, DclIt) && !Info.keepEvaluatingAfterFailure())
         return ESR_Failed;
     }
     return ESR_Succeeded;
@@ -3315,11 +3368,10 @@
     BlockScopeRAII Scope(Info);
 
     const CompoundStmt *CS = cast<CompoundStmt>(S);
-    for (CompoundStmt::const_body_iterator BI = CS->body_begin(),
-           BE = CS->body_end(); BI != BE; ++BI) {
-      EvalStmtResult ESR = EvaluateStmt(Result, Info, *BI, Case);
+    for (const auto *BI : CS->body()) {
+      EvalStmtResult ESR = EvaluateStmt(Result, Info, BI, Case);
       if (ESR == ESR_Succeeded)
-        Case = 0;
+        Case = nullptr;
       else if (ESR != ESR_CaseNotFound)
         return ESR;
     }
@@ -3368,7 +3420,7 @@
       EvalStmtResult ESR = EvaluateLoopBody(Result, Info, DS->getBody(), Case);
       if (ESR != ESR_Continue)
         return ESR;
-      Case = 0;
+      Case = nullptr;
 
       FullExpressionRAII CondScope(Info);
       if (!EvaluateAsBooleanCondition(DS->getCond(), Continue, Info))
@@ -3593,7 +3645,7 @@
 
   EvalStmtResult ESR = EvaluateStmt(Result, Info, Body);
   if (ESR == ESR_Succeeded) {
-    if (Callee->getResultType()->isVoidType())
+    if (Callee->getReturnType()->isVoidType())
       return true;
     Info.Diag(Callee->getLocEnd(), diag::note_constexpr_no_return);
   }
@@ -3659,15 +3711,14 @@
 #ifndef NDEBUG
   CXXRecordDecl::base_class_const_iterator BaseIt = RD->bases_begin();
 #endif
-  for (CXXConstructorDecl::init_const_iterator I = Definition->init_begin(),
-       E = Definition->init_end(); I != E; ++I) {
+  for (const auto *I : Definition->inits()) {
     LValue Subobject = This;
     APValue *Value = &Result;
 
     // Determine the subobject to initialize.
-    FieldDecl *FD = 0;
-    if ((*I)->isBaseInitializer()) {
-      QualType BaseType((*I)->getBaseClass(), 0);
+    FieldDecl *FD = nullptr;
+    if (I->isBaseInitializer()) {
+      QualType BaseType(I->getBaseClass(), 0);
 #ifndef NDEBUG
       // Non-virtual base classes are initialized in the order in the class
       // definition. We have already checked for virtual base classes.
@@ -3676,12 +3727,12 @@
              "base class initializers not in expected order");
       ++BaseIt;
 #endif
-      if (!HandleLValueDirectBase(Info, (*I)->getInit(), Subobject, RD,
+      if (!HandleLValueDirectBase(Info, I->getInit(), Subobject, RD,
                                   BaseType->getAsCXXRecordDecl(), &Layout))
         return false;
       Value = &Result.getStructBase(BasesSeen++);
-    } else if ((FD = (*I)->getMember())) {
-      if (!HandleLValueMember(Info, (*I)->getInit(), Subobject, FD, &Layout))
+    } else if ((FD = I->getMember())) {
+      if (!HandleLValueMember(Info, I->getInit(), Subobject, FD, &Layout))
         return false;
       if (RD->isUnion()) {
         Result = APValue(FD);
@@ -3689,13 +3740,11 @@
       } else {
         Value = &Result.getStructField(FD->getFieldIndex());
       }
-    } else if (IndirectFieldDecl *IFD = (*I)->getIndirectMember()) {
+    } else if (IndirectFieldDecl *IFD = I->getIndirectMember()) {
       // Walk the indirect field decl's chain to find the object to initialize,
       // and make sure we've initialized every step along it.
-      for (IndirectFieldDecl::chain_iterator C = IFD->chain_begin(),
-                                             CE = IFD->chain_end();
-           C != CE; ++C) {
-        FD = cast<FieldDecl>(*C);
+      for (auto *C : IFD->chain()) {
+        FD = cast<FieldDecl>(C);
         CXXRecordDecl *CD = cast<CXXRecordDecl>(FD->getParent());
         // Switch the union field if it differs. This happens if we had
         // preceding zero-initialization, and we're now initializing a union
@@ -3710,7 +3759,7 @@
             *Value = APValue(APValue::UninitStruct(), CD->getNumBases(),
                              std::distance(CD->field_begin(), CD->field_end()));
         }
-        if (!HandleLValueMember(Info, (*I)->getInit(), Subobject, FD))
+        if (!HandleLValueMember(Info, I->getInit(), Subobject, FD))
           return false;
         if (CD->isUnion())
           Value = &Value->getUnionValue();
@@ -3722,8 +3771,8 @@
     }
 
     FullExpressionRAII InitScope(Info);
-    if (!EvaluateInPlace(*Value, Info, Subobject, (*I)->getInit()) ||
-        (FD && FD->isBitField() && !truncateBitfieldValue(Info, (*I)->getInit(),
+    if (!EvaluateInPlace(*Value, Info, Subobject, I->getInit()) ||
+        (FD && FD->isBitField() && !truncateBitfieldValue(Info, I->getInit(),
                                                           *Value, FD))) {
       // If we're checking for a potential constant expression, evaluate all
       // initializers even if some of them fail.
@@ -3742,15 +3791,14 @@
 //===----------------------------------------------------------------------===//
 namespace {
 
-// FIXME: RetTy is always bool. Remove it.
-template <class Derived, typename RetTy=bool>
+template <class Derived>
 class ExprEvaluatorBase
-  : public ConstStmtVisitor<Derived, RetTy> {
+  : public ConstStmtVisitor<Derived, bool> {
 private:
-  RetTy DerivedSuccess(const APValue &V, const Expr *E) {
+  bool DerivedSuccess(const APValue &V, const Expr *E) {
     return static_cast<Derived*>(this)->Success(V, E);
   }
-  RetTy DerivedZeroInitialization(const Expr *E) {
+  bool DerivedZeroInitialization(const Expr *E) {
     return static_cast<Derived*>(this)->ZeroInitialization(E);
   }
 
@@ -3795,14 +3843,14 @@
 
 protected:
   EvalInfo &Info;
-  typedef ConstStmtVisitor<Derived, RetTy> StmtVisitorTy;
+  typedef ConstStmtVisitor<Derived, bool> StmtVisitorTy;
   typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
 
   OptionalDiagnostic CCEDiag(const Expr *E, diag::kind D) {
     return Info.CCEDiag(E, D);
   }
 
-  RetTy ZeroInitialization(const Expr *E) { return Error(E); }
+  bool ZeroInitialization(const Expr *E) { return Error(E); }
 
 public:
   ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
@@ -3819,28 +3867,28 @@
     return Error(E, diag::note_invalid_subexpr_in_const_expr);
   }
 
-  RetTy VisitStmt(const Stmt *) {
+  bool VisitStmt(const Stmt *) {
     llvm_unreachable("Expression evaluator should not be called on stmts");
   }
-  RetTy VisitExpr(const Expr *E) {
+  bool VisitExpr(const Expr *E) {
     return Error(E);
   }
 
-  RetTy VisitParenExpr(const ParenExpr *E)
+  bool VisitParenExpr(const ParenExpr *E)
     { return StmtVisitorTy::Visit(E->getSubExpr()); }
-  RetTy VisitUnaryExtension(const UnaryOperator *E)
+  bool VisitUnaryExtension(const UnaryOperator *E)
     { return StmtVisitorTy::Visit(E->getSubExpr()); }
-  RetTy VisitUnaryPlus(const UnaryOperator *E)
+  bool VisitUnaryPlus(const UnaryOperator *E)
     { return StmtVisitorTy::Visit(E->getSubExpr()); }
-  RetTy VisitChooseExpr(const ChooseExpr *E)
+  bool VisitChooseExpr(const ChooseExpr *E)
     { return StmtVisitorTy::Visit(E->getChosenSubExpr()); }
-  RetTy VisitGenericSelectionExpr(const GenericSelectionExpr *E)
+  bool VisitGenericSelectionExpr(const GenericSelectionExpr *E)
     { return StmtVisitorTy::Visit(E->getResultExpr()); }
-  RetTy VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E)
+  bool VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E)
     { return StmtVisitorTy::Visit(E->getReplacement()); }
-  RetTy VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E)
+  bool VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E)
     { return StmtVisitorTy::Visit(E->getExpr()); }
-  RetTy VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E) {
+  bool VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E) {
     // The initializer may not have been parsed yet, or might be erroneous.
     if (!E->getExpr())
       return Error(E);
@@ -3848,19 +3896,19 @@
   }
   // We cannot create any objects for which cleanups are required, so there is
   // nothing to do here; all cleanups must come from unevaluated subexpressions.
-  RetTy VisitExprWithCleanups(const ExprWithCleanups *E)
+  bool VisitExprWithCleanups(const ExprWithCleanups *E)
     { return StmtVisitorTy::Visit(E->getSubExpr()); }
 
-  RetTy VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *E) {
+  bool VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *E) {
     CCEDiag(E, diag::note_constexpr_invalid_cast) << 0;
     return static_cast<Derived*>(this)->VisitCastExpr(E);
   }
-  RetTy VisitCXXDynamicCastExpr(const CXXDynamicCastExpr *E) {
+  bool VisitCXXDynamicCastExpr(const CXXDynamicCastExpr *E) {
     CCEDiag(E, diag::note_constexpr_invalid_cast) << 1;
     return static_cast<Derived*>(this)->VisitCastExpr(E);
   }
 
-  RetTy VisitBinaryOperator(const BinaryOperator *E) {
+  bool VisitBinaryOperator(const BinaryOperator *E) {
     switch (E->getOpcode()) {
     default:
       return Error(E);
@@ -3882,7 +3930,7 @@
     }
   }
 
-  RetTy VisitBinaryConditionalOperator(const BinaryConditionalOperator *E) {
+  bool VisitBinaryConditionalOperator(const BinaryConditionalOperator *E) {
     // Evaluate and cache the common expression. We treat it as a temporary,
     // even though it's not quite the same thing.
     if (!Evaluate(Info.CurrentCall->createTemporary(E->getOpaqueValue(), false),
@@ -3892,7 +3940,7 @@
     return HandleConditionalOperator(E);
   }
 
-  RetTy VisitConditionalOperator(const ConditionalOperator *E) {
+  bool VisitConditionalOperator(const ConditionalOperator *E) {
     bool IsBcpCall = false;
     // If the condition (ignoring parens) is a __builtin_constant_p call,
     // the result is a constant expression if it can be folded without
@@ -3900,7 +3948,7 @@
     // for discussion.
     if (const CallExpr *CallCE =
           dyn_cast<CallExpr>(E->getCond()->IgnoreParenCasts()))
-      if (CallCE->isBuiltinCall() == Builtin::BI__builtin_constant_p)
+      if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
         IsBcpCall = true;
 
     // Always assume __builtin_constant_p(...) ? ... : ... is a potential
@@ -3917,7 +3965,7 @@
     return true;
   }
 
-  RetTy VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
+  bool VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
     if (APValue *Value = Info.CurrentCall->getTemporary(E))
       return DerivedSuccess(*Value, E);
 
@@ -3931,18 +3979,18 @@
     return StmtVisitorTy::Visit(Source);
   }
 
-  RetTy VisitCallExpr(const CallExpr *E) {
+  bool VisitCallExpr(const CallExpr *E) {
     const Expr *Callee = E->getCallee()->IgnoreParens();
     QualType CalleeType = Callee->getType();
 
-    const FunctionDecl *FD = 0;
-    LValue *This = 0, ThisVal;
+    const FunctionDecl *FD = nullptr;
+    LValue *This = nullptr, ThisVal;
     ArrayRef<const Expr *> Args(E->getArgs(), E->getNumArgs());
     bool HasQualifier = false;
 
     // Extract function decl and 'this' pointer from the callee.
     if (CalleeType->isSpecificBuiltinType(BuiltinType::BoundMember)) {
-      const ValueDecl *Member = 0;
+      const ValueDecl *Member = nullptr;
       if (const MemberExpr *ME = dyn_cast<MemberExpr>(Callee)) {
         // Explicit bound member calls, such as x.f() or p->g();
         if (!EvaluateObjectArgument(Info, ME->getBase(), ThisVal))
@@ -4004,7 +4052,7 @@
         isa<CXXMethodDecl>(FD) && cast<CXXMethodDecl>(FD)->isVirtual())
       return Error(E, diag::note_constexpr_virtual_call);
 
-    const FunctionDecl *Definition = 0;
+    const FunctionDecl *Definition = nullptr;
     Stmt *Body = FD->getBody(Definition);
     APValue Result;
 
@@ -4016,28 +4064,28 @@
     return DerivedSuccess(Result, E);
   }
 
-  RetTy VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
+  bool VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
     return StmtVisitorTy::Visit(E->getInitializer());
   }
-  RetTy VisitInitListExpr(const InitListExpr *E) {
+  bool VisitInitListExpr(const InitListExpr *E) {
     if (E->getNumInits() == 0)
       return DerivedZeroInitialization(E);
     if (E->getNumInits() == 1)
       return StmtVisitorTy::Visit(E->getInit(0));
     return Error(E);
   }
-  RetTy VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) {
+  bool VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) {
     return DerivedZeroInitialization(E);
   }
-  RetTy VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E) {
+  bool VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E) {
     return DerivedZeroInitialization(E);
   }
-  RetTy VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E) {
+  bool VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E) {
     return DerivedZeroInitialization(E);
   }
 
   /// A member expression where the object is a prvalue is itself a prvalue.
-  RetTy VisitMemberExpr(const MemberExpr *E) {
+  bool VisitMemberExpr(const MemberExpr *E) {
     assert(!E->isArrow() && "missing call to bound member function?");
 
     APValue Val;
@@ -4061,7 +4109,7 @@
            DerivedSuccess(Result, E);
   }
 
-  RetTy VisitCastExpr(const CastExpr *E) {
+  bool VisitCastExpr(const CastExpr *E) {
     switch (E->getCastKind()) {
     default:
       break;
@@ -4093,13 +4141,13 @@
     return Error(E);
   }
 
-  RetTy VisitUnaryPostInc(const UnaryOperator *UO) {
+  bool VisitUnaryPostInc(const UnaryOperator *UO) {
     return VisitUnaryPostIncDec(UO);
   }
-  RetTy VisitUnaryPostDec(const UnaryOperator *UO) {
+  bool VisitUnaryPostDec(const UnaryOperator *UO) {
     return VisitUnaryPostIncDec(UO);
   }
-  RetTy VisitUnaryPostIncDec(const UnaryOperator *UO) {
+  bool VisitUnaryPostIncDec(const UnaryOperator *UO) {
     if (!Info.getLangOpts().CPlusPlus1y && !Info.keepEvaluatingAfterFailure())
       return Error(UO);
 
@@ -4113,7 +4161,7 @@
     return DerivedSuccess(RVal, UO);
   }
 
-  RetTy VisitStmtExpr(const StmtExpr *E) {
+  bool VisitStmtExpr(const StmtExpr *E) {
     // We will have checked the full-expressions inside the statement expression
     // when they were completed, and don't need to check them again now.
     if (Info.checkingForOverflow())
@@ -4162,11 +4210,11 @@
 namespace {
 template<class Derived>
 class LValueExprEvaluatorBase
-  : public ExprEvaluatorBase<Derived, bool> {
+  : public ExprEvaluatorBase<Derived> {
 protected:
   LValue &Result;
   typedef LValueExprEvaluatorBase LValueExprEvaluatorBaseTy;
-  typedef ExprEvaluatorBase<Derived, bool> ExprEvaluatorBaseTy;
+  typedef ExprEvaluatorBase<Derived> ExprEvaluatorBaseTy;
 
   bool Success(APValue::LValueBase B) {
     Result.set(B);
@@ -4356,7 +4404,7 @@
 }
 
 bool LValueExprEvaluator::VisitVarDecl(const Expr *E, const VarDecl *VD) {
-  CallStackFrame *Frame = 0;
+  CallStackFrame *Frame = nullptr;
   if (VD->hasLocalStorage() && Info.CurrentCall->Index > 1)
     Frame = Info.CurrentCall;
 
@@ -4533,7 +4581,7 @@
 
   return handleIncDec(
       this->Info, UO, Result, UO->getSubExpr()->getType(),
-      UO->isIncrementOp(), 0);
+      UO->isIncrementOp(), nullptr);
 }
 
 bool LValueExprEvaluator::VisitCompoundAssignOperator(
@@ -4584,7 +4632,7 @@
 
 namespace {
 class PointerExprEvaluator
-  : public ExprEvaluatorBase<PointerExprEvaluator, bool> {
+  : public ExprEvaluatorBase<PointerExprEvaluator> {
   LValue &Result;
 
   bool Success(const Expr *E) {
@@ -4601,7 +4649,7 @@
     return true;
   }
   bool ZeroInitialization(const Expr *E) {
-    return Success((Expr*)0);
+    return Success((Expr*)nullptr);
   }
 
   bool VisitBinaryOperator(const BinaryOperator *E);
@@ -4623,8 +4671,13 @@
     // Can't look at 'this' when checking a potential constant expression.
     if (Info.checkingPotentialConstantExpression())
       return false;
-    if (!Info.CurrentCall->This)
-      return Error(E);
+    if (!Info.CurrentCall->This) {
+      if (Info.getLangOpts().CPlusPlus11)
+        Info.Diag(E, diag::note_constexpr_this) << E->isImplicit();
+      else
+        Info.Diag(E);
+      return false;
+    }
     Result = *Info.CurrentCall->This;
     return true;
   }
@@ -4729,7 +4782,7 @@
     if (Value.isInt()) {
       unsigned Size = Info.Ctx.getTypeSize(E->getType());
       uint64_t N = Value.getInt().extOrTrunc(Size).getZExtValue();
-      Result.Base = (Expr*)0;
+      Result.Base = (Expr*)nullptr;
       Result.Offset = CharUnits::fromQuantity(N);
       Result.CallIndex = 0;
       Result.Designator.setInvalid();
@@ -4769,7 +4822,7 @@
   if (IsStringLiteralCall(E))
     return Success(E);
 
-  switch (E->isBuiltinCall()) {
+  switch (E->getBuiltinCallee()) {
   case Builtin::BI__builtin_addressof:
     return EvaluateLValue(E->getArg(0), Result, Info);
 
@@ -4784,7 +4837,7 @@
 
 namespace {
 class MemberPointerExprEvaluator
-  : public ExprEvaluatorBase<MemberPointerExprEvaluator, bool> {
+  : public ExprEvaluatorBase<MemberPointerExprEvaluator> {
   MemberPtr &Result;
 
   bool Success(const ValueDecl *D) {
@@ -4801,7 +4854,7 @@
     return true;
   }
   bool ZeroInitialization(const Expr *E) {
-    return Success((const ValueDecl*)0);
+    return Success((const ValueDecl*)nullptr);
   }
 
   bool VisitCastExpr(const CastExpr *E);
@@ -4872,7 +4925,7 @@
 
 namespace {
   class RecordExprEvaluator
-  : public ExprEvaluatorBase<RecordExprEvaluator, bool> {
+  : public ExprEvaluatorBase<RecordExprEvaluator> {
     const LValue &This;
     APValue &Result;
   public:
@@ -4925,14 +4978,13 @@
     }
   }
 
-  for (RecordDecl::field_iterator I = RD->field_begin(), End = RD->field_end();
-       I != End; ++I) {
+  for (const auto *I : RD->fields()) {
     // -- if T is a reference type, no initialization is performed.
     if (I->getType()->isReferenceType())
       continue;
 
     LValue Subobject = This;
-    if (!HandleLValueMember(Info, E, Subobject, *I, &Layout))
+    if (!HandleLValueMember(Info, E, Subobject, I, &Layout))
       return false;
 
     ImplicitValueInitExpr VIE(I->getType());
@@ -4952,7 +5004,7 @@
     // object's first non-static named data member is zero-initialized
     RecordDecl::field_iterator I = RD->field_begin();
     if (I == RD->field_end()) {
-      Result = APValue((const FieldDecl*)0);
+      Result = APValue((const FieldDecl*)nullptr);
       return true;
     }
 
@@ -5040,8 +5092,7 @@
                    std::distance(RD->field_begin(), RD->field_end()));
   unsigned ElementNo = 0;
   bool Success = true;
-  for (RecordDecl::field_iterator Field = RD->field_begin(),
-       FieldEnd = RD->field_end(); Field != FieldEnd; ++Field) {
+  for (const auto *Field : RD->fields()) {
     // Anonymous bit-fields are not considered members of the class for
     // purposes of aggregate initialization.
     if (Field->isUnnamedBitfield())
@@ -5054,7 +5105,7 @@
     // FIXME: Diagnostics here should point to the end of the initializer
     // list, not the start.
     if (!HandleLValueMember(Info, HaveInit ? E->getInit(ElementNo) : E,
-                            Subobject, *Field, &Layout))
+                            Subobject, Field, &Layout))
       return false;
 
     // Perform an implicit value-initialization for members beyond the end of
@@ -5069,7 +5120,7 @@
     APValue &FieldVal = Result.getStructField(Field->getFieldIndex());
     if (!EvaluateInPlace(FieldVal, Info, Subobject, Init) ||
         (Field->isBitField() && !truncateBitfieldValue(Info, Init,
-                                                       FieldVal, *Field))) {
+                                                       FieldVal, Field))) {
       if (!Info.keepEvaluatingAfterFailure())
         return false;
       Success = false;
@@ -5089,19 +5140,18 @@
     if (!Result.isUninit())
       return true;
 
-    if (ZeroInit)
-      return ZeroInitialization(E);
-
-    const CXXRecordDecl *RD = FD->getParent();
-    if (RD->isUnion())
-      Result = APValue((FieldDecl*)0);
-    else
-      Result = APValue(APValue::UninitStruct(), RD->getNumBases(),
-                       std::distance(RD->field_begin(), RD->field_end()));
-    return true;
+    // We can get here in two different ways:
+    //  1) We're performing value-initialization, and should zero-initialize
+    //     the object, or
+    //  2) We're performing default-initialization of an object with a trivial
+    //     constexpr default constructor, in which case we should start the
+    //     lifetimes of all the base subobjects (there can be no data member
+    //     subobjects in this case) per [basic.life]p1.
+    // Either way, ZeroInitialization is appropriate.
+    return ZeroInitialization(E);
   }
 
-  const FunctionDecl *Definition = 0;
+  const FunctionDecl *Definition = nullptr;
   FD->getBody(Definition);
 
   if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition))
@@ -5235,7 +5285,7 @@
 
 namespace {
   class VectorExprEvaluator
-  : public ExprEvaluatorBase<VectorExprEvaluator, bool> {
+  : public ExprEvaluatorBase<VectorExprEvaluator> {
     APValue &Result;
   public:
 
@@ -5416,7 +5466,7 @@
 
 namespace {
   class ArrayExprEvaluator
-  : public ExprEvaluatorBase<ArrayExprEvaluator, bool> {
+  : public ExprEvaluatorBase<ArrayExprEvaluator> {
     const LValue &This;
     APValue &Result;
   public:
@@ -5488,7 +5538,7 @@
 
   unsigned NumEltsToInit = E->getNumInits();
   unsigned NumElts = CAT->getSize().getZExtValue();
-  const Expr *FillerExpr = E->hasArrayFiller() ? E->getArrayFiller() : 0;
+  const Expr *FillerExpr = E->hasArrayFiller() ? E->getArrayFiller() : nullptr;
 
   // If the initializer might depend on the array index, run it for each
   // array element. For now, just whitelist non-class value-initialization.
@@ -5578,22 +5628,12 @@
     if (HadZeroInit)
       return true;
 
-    if (ZeroInit) {
-      ImplicitValueInitExpr VIE(Type);
-      return EvaluateInPlace(*Value, Info, Subobject, &VIE);
-    }
-
-    const CXXRecordDecl *RD = FD->getParent();
-    if (RD->isUnion())
-      *Value = APValue((FieldDecl*)0);
-    else
-      *Value =
-          APValue(APValue::UninitStruct(), RD->getNumBases(),
-                  std::distance(RD->field_begin(), RD->field_end()));
-    return true;
+    // See RecordExprEvaluator::VisitCXXConstructExpr for explanation.
+    ImplicitValueInitExpr VIE(Type);
+    return EvaluateInPlace(*Value, Info, Subobject, &VIE);
   }
 
-  const FunctionDecl *Definition = 0;
+  const FunctionDecl *Definition = nullptr;
   FD->getBody(Definition);
 
   if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition))
@@ -5621,7 +5661,7 @@
 
 namespace {
 class IntExprEvaluator
-  : public ExprEvaluatorBase<IntExprEvaluator, bool> {
+  : public ExprEvaluatorBase<IntExprEvaluator> {
   APValue &Result;
 public:
   IntExprEvaluator(EvalInfo &info, APValue &result)
@@ -5727,14 +5767,6 @@
     return ZeroInitialization(E);
   }
 
-  bool VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) {
-    return Success(E->getValue(), E);
-  }
-
-  bool VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E) {
-    return Success(E->getValue(), E);
-  }
-
   bool VisitTypeTraitExpr(const TypeTraitExpr *E) {
     return Success(E->getValue(), E);
   }
@@ -5975,7 +6007,7 @@
 }
 
 bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) {
-  switch (unsigned BuiltinOp = E->isBuiltinCall()) {
+  switch (unsigned BuiltinOp = E->getBuiltinCallee()) {
   default:
     return ExprEvaluatorBaseTy::VisitCallExpr(E);
 
@@ -5994,7 +6026,17 @@
 
     // Expression had no side effects, but we couldn't statically determine the
     // size of the referenced object.
-    return Error(E);
+    switch (Info.EvalMode) {
+    case EvalInfo::EM_ConstantExpression:
+    case EvalInfo::EM_PotentialConstantExpression:
+    case EvalInfo::EM_ConstantFold:
+    case EvalInfo::EM_EvaluateForOverflow:
+    case EvalInfo::EM_IgnoreSideEffects:
+      return Error(E);
+    case EvalInfo::EM_ConstantExpressionUnevaluated:
+    case EvalInfo::EM_PotentialConstantExpressionUnevaluated:
+      return Success(-1ULL, E);
+    }
   }
 
   case Builtin::BI__builtin_bswap16:
@@ -6016,7 +6058,8 @@
 
   case Builtin::BI__builtin_clz:
   case Builtin::BI__builtin_clzl:
-  case Builtin::BI__builtin_clzll: {
+  case Builtin::BI__builtin_clzll:
+  case Builtin::BI__builtin_clzs: {
     APSInt Val;
     if (!EvaluateInteger(E->getArg(0), Val, Info))
       return false;
@@ -6031,7 +6074,8 @@
 
   case Builtin::BI__builtin_ctz:
   case Builtin::BI__builtin_ctzl:
-  case Builtin::BI__builtin_ctzll: {
+  case Builtin::BI__builtin_ctzll:
+  case Builtin::BI__builtin_ctzs: {
     APSInt Val;
     if (!EvaluateInteger(E->getArg(0), Val, Info))
       return false;
@@ -6267,11 +6311,11 @@
     const Expr *E;
     EvalResult LHSResult; // meaningful only for binary operator expression.
     enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind } Kind;
-    
-    Job() : StoredInfo(0) { }
+
+    Job() : StoredInfo(nullptr) {}
     void startSpeculativeEval(EvalInfo &Info) {
       OldEvalStatus = Info.EvalStatus;
-      Info.EvalStatus.Diag = 0;
+      Info.EvalStatus.Diag = nullptr;
       StoredInfo = &Info;
     }
     ~Job() {
@@ -6897,8 +6941,9 @@
 }
 
 CharUnits IntExprEvaluator::GetAlignOfType(QualType T) {
-  // C++ [expr.alignof]p3: "When alignof is applied to a reference type, the
-  //   result shall be the alignment of the referenced type."
+  // C++ [expr.alignof]p3:
+  //     When alignof is applied to a reference type, the result is the
+  //     alignment of the referenced type.
   if (const ReferenceType *Ref = T->getAs<ReferenceType>())
     T = Ref->getPointeeType();
 
@@ -6917,7 +6962,7 @@
   // alignof decl is always accepted, even if it doesn't make sense: we default
   // to 1 in those cases.
   if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
-    return Info.Ctx.getDeclAlign(DRE->getDecl(), 
+    return Info.Ctx.getDeclAlign(DRE->getDecl(),
                                  /*RefAsPointee*/true);
 
   if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
@@ -7120,6 +7165,7 @@
   case CK_BuiltinFnToFnPtr:
   case CK_ZeroToOCLEvent:
   case CK_NonAtomicToAtomic:
+  case CK_AddressSpaceConversion:
     llvm_unreachable("invalid cast kind for integral value");
 
   case CK_BitCast:
@@ -7258,7 +7304,7 @@
 
 namespace {
 class FloatExprEvaluator
-  : public ExprEvaluatorBase<FloatExprEvaluator, bool> {
+  : public ExprEvaluatorBase<FloatExprEvaluator> {
   APFloat &Result;
 public:
   FloatExprEvaluator(EvalInfo &info, APFloat &result)
@@ -7319,7 +7365,7 @@
 }
 
 bool FloatExprEvaluator::VisitCallExpr(const CallExpr *E) {
-  switch (E->isBuiltinCall()) {
+  switch (E->getBuiltinCallee()) {
   default:
     return ExprEvaluatorBaseTy::VisitCallExpr(E);
 
@@ -7474,7 +7520,7 @@
 
 namespace {
 class ComplexExprEvaluator
-  : public ExprEvaluatorBase<ComplexExprEvaluator, bool> {
+  : public ExprEvaluatorBase<ComplexExprEvaluator> {
   ComplexValue &Result;
 
 public:
@@ -7592,6 +7638,7 @@
   case CK_BuiltinFnToFnPtr:
   case CK_ZeroToOCLEvent:
   case CK_NonAtomicToAtomic:
+  case CK_AddressSpaceConversion:
     llvm_unreachable("invalid cast kind for complex value");
 
   case CK_LValueToRValue:
@@ -7858,7 +7905,7 @@
 
 namespace {
 class AtomicExprEvaluator :
-    public ExprEvaluatorBase<AtomicExprEvaluator, bool> {
+    public ExprEvaluatorBase<AtomicExprEvaluator> {
   APValue &Result;
 public:
   AtomicExprEvaluator(EvalInfo &Info, APValue &Result)
@@ -7898,7 +7945,7 @@
 
 namespace {
 class VoidExprEvaluator
-  : public ExprEvaluatorBase<VoidExprEvaluator, bool> {
+  : public ExprEvaluatorBase<VoidExprEvaluator> {
 public:
   VoidExprEvaluator(EvalInfo &Info) : ExprEvaluatorBaseTy(Info) {}
 
@@ -7913,6 +7960,16 @@
       return true;
     }
   }
+
+  bool VisitCallExpr(const CallExpr *E) {
+    switch (E->getBuiltinCallee()) {
+    default:
+      return ExprEvaluatorBaseTy::VisitCallExpr(E);
+    case Builtin::BI__assume:
+      // The argument is not evaluated!
+      return true;
+    }
+  }
 };
 } // end anonymous namespace
 
@@ -8000,6 +8057,8 @@
 /// an object can indirectly refer to subobjects which were initialized earlier.
 static bool EvaluateInPlace(APValue &Result, EvalInfo &Info, const LValue &This,
                             const Expr *E, bool AllowNonLiteralTypes) {
+  assert(!E->isValueDependent());
+
   if (!AllowNonLiteralTypes && !CheckLiteralType(Info, E, &This))
     return false;
 
@@ -8019,6 +8078,9 @@
 /// EvaluateAsRValue - Try to evaluate this expression, performing an implicit
 /// lvalue-to-rvalue cast if it is an lvalue.
 static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result) {
+  if (E->getType().isNull())
+    return false;
+
   if (!CheckLiteralType(Info, E))
     return false;
 
@@ -8046,6 +8108,13 @@
     IsConst = true;
     return true;
   }
+
+  // This case should be rare, but we need to check it before we check on
+  // the type below.
+  if (Exp->getType().isNull()) {
+    IsConst = false;
+    return true;
+  }
   
   // FIXME: Evaluating values of large array and record types can cause
   // performance problems. Only do so in C++11 for now.
@@ -8303,10 +8372,20 @@
   case Expr::MaterializeTemporaryExprClass:
   case Expr::PseudoObjectExprClass:
   case Expr::AtomicExprClass:
-  case Expr::InitListExprClass:
   case Expr::LambdaExprClass:
     return ICEDiag(IK_NotICE, E->getLocStart());
 
+  case Expr::InitListExprClass: {
+    // C++03 [dcl.init]p13: If T is a scalar type, then a declaration of the
+    // form "T x = { a };" is equivalent to "T x = a;".
+    // Unless we're initializing a reference, T is a scalar as it is known to be
+    // of integral or enumeration type.
+    if (E->isRValue())
+      if (cast<InitListExpr>(E)->getNumInits() == 1)
+        return CheckICE(cast<InitListExpr>(E)->getInit(0), Ctx);
+    return ICEDiag(IK_NotICE, E->getLocStart());
+  }
+
   case Expr::SizeOfPackExprClass:
   case Expr::GNUNullExprClass:
     // GCC considers the GNU __null value to be an integral constant expression.
@@ -8325,8 +8404,6 @@
   case Expr::ObjCBoolLiteralExprClass:
   case Expr::CXXBoolLiteralExprClass:
   case Expr::CXXScalarValueInitExprClass:
-  case Expr::UnaryTypeTraitExprClass:
-  case Expr::BinaryTypeTraitExprClass:
   case Expr::TypeTraitExprClass:
   case Expr::ArrayTypeTraitExprClass:
   case Expr::ExpressionTraitExprClass:
@@ -8338,7 +8415,7 @@
     // constant expressions, but they can never be ICEs because an ICE cannot
     // contain an operand of (pointer to) function type.
     const CallExpr *CE = cast<CallExpr>(E);
-    if (CE->isBuiltinCall())
+    if (CE->getBuiltinCallee())
       return CheckEvalInICE(E, Ctx);
     return ICEDiag(IK_NotICE, E->getLocStart());
   }
@@ -8555,7 +8632,7 @@
     // extension.  See GCC PR38377 for discussion.
     if (const CallExpr *CallCE
         = dyn_cast<CallExpr>(Exp->getCond()->IgnoreParenCasts()))
-      if (CallCE->isBuiltinCall() == Builtin::BI__builtin_constant_p)
+      if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p)
         return CheckEvalInICE(E, Ctx);
     ICEDiag CondResult = CheckICE(Exp->getCond(), Ctx);
     if (CondResult.Kind == IK_NotICE)
@@ -8613,7 +8690,7 @@
 bool Expr::isIntegerConstantExpr(const ASTContext &Ctx,
                                  SourceLocation *Loc) const {
   if (Ctx.getLangOpts().CPlusPlus11)
-    return EvaluateCPlusPlus11IntegralConstantExpr(Ctx, this, 0, Loc);
+    return EvaluateCPlusPlus11IntegralConstantExpr(Ctx, this, nullptr, Loc);
 
   ICEDiag D = CheckICE(this, Ctx);
   if (D.Kind != IK_ICE) {
@@ -8665,6 +8742,28 @@
   return IsConstExpr;
 }
 
+bool Expr::EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx,
+                                    const FunctionDecl *Callee,
+                                    ArrayRef<const Expr*> Args) const {
+  Expr::EvalStatus Status;
+  EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpressionUnevaluated);
+
+  ArgVector ArgValues(Args.size());
+  for (ArrayRef<const Expr*>::iterator I = Args.begin(), E = Args.end();
+       I != E; ++I) {
+    if (!Evaluate(ArgValues[I - Args.begin()], Info, *I))
+      // If evaluation fails, throw away the argument entirely.
+      ArgValues[I - Args.begin()] = APValue();
+    if (Info.EvalStatus.HasSideEffects)
+      return false;
+  }
+
+  // Build fake call to Callee.
+  CallStackFrame Frame(Info, Callee->getLocation(), Callee, /*This*/nullptr,
+                       ArgValues.data());
+  return Evaluate(Value, Info, this) && !Info.EvalStatus.HasSideEffects;
+}
+
 bool Expr::isPotentialConstantExpr(const FunctionDecl *FD,
                                    SmallVectorImpl<
                                      PartialDiagnosticAt> &Diags) {
@@ -8681,7 +8780,7 @@
                 EvalInfo::EM_PotentialConstantExpression);
 
   const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
-  const CXXRecordDecl *RD = MD ? MD->getParent()->getCanonicalDecl() : 0;
+  const CXXRecordDecl *RD = MD ? MD->getParent()->getCanonicalDecl() : nullptr;
 
   // Fabricate an arbitrary expression on the stack and pretend that it
   // is a temporary being used as the 'this' pointer.
@@ -8700,8 +8799,32 @@
     Info.setEvaluatingDecl(This.getLValueBase(), Scratch);
     HandleConstructorCall(Loc, This, Args, CD, Info, Scratch);
   } else
-    HandleFunctionCall(Loc, FD, (MD && MD->isInstance()) ? &This : 0,
+    HandleFunctionCall(Loc, FD, (MD && MD->isInstance()) ? &This : nullptr,
                        Args, FD->getBody(), Info, Scratch);
 
   return Diags.empty();
 }
+
+bool Expr::isPotentialConstantExprUnevaluated(Expr *E,
+                                              const FunctionDecl *FD,
+                                              SmallVectorImpl<
+                                                PartialDiagnosticAt> &Diags) {
+  Expr::EvalStatus Status;
+  Status.Diag = &Diags;
+
+  EvalInfo Info(FD->getASTContext(), Status,
+                EvalInfo::EM_PotentialConstantExpressionUnevaluated);
+
+  // Fabricate a call stack frame to give the arguments a plausible cover story.
+  ArrayRef<const Expr*> Args;
+  ArgVector ArgValues(0);
+  bool Success = EvaluateArgs(Args, ArgValues, Info);
+  (void)Success;
+  assert(Success &&
+         "Failed to set up arguments for potential constant evaluation");
+  CallStackFrame Frame(Info, SourceLocation(), FD, nullptr, ArgValues.data());
+
+  APValue ResultScratch;
+  Evaluate(ResultScratch, Info, E);
+  return Diags.empty();
+}
diff --git a/lib/AST/ExternalASTSource.cpp b/lib/AST/ExternalASTSource.cpp
index 96ebe92..8894107 100644
--- a/lib/AST/ExternalASTSource.cpp
+++ b/lib/AST/ExternalASTSource.cpp
@@ -14,16 +14,44 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/AST/ExternalASTSource.h"
+#include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclarationName.h"
+#include "llvm/Support/ErrorHandling.h"
 
 using namespace clang;
 
 ExternalASTSource::~ExternalASTSource() { }
 
+void ExternalASTSource::FindFileRegionDecls(FileID File, unsigned Offset,
+                                            unsigned Length,
+                                            SmallVectorImpl<Decl *> &Decls) {}
+
+void ExternalASTSource::CompleteRedeclChain(const Decl *D) {}
+
+void ExternalASTSource::CompleteType(TagDecl *Tag) {}
+
+void ExternalASTSource::CompleteType(ObjCInterfaceDecl *Class) {}
+
+void ExternalASTSource::ReadComments() {}
+
+void ExternalASTSource::StartedDeserializing() {}
+
+void ExternalASTSource::FinishedDeserializing() {}
+
+void ExternalASTSource::StartTranslationUnit(ASTConsumer *Consumer) {}
+
 void ExternalASTSource::PrintStats() { }
 
+bool ExternalASTSource::layoutRecordType(
+    const RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
+    llvm::DenseMap<const FieldDecl *, uint64_t> &FieldOffsets,
+    llvm::DenseMap<const CXXRecordDecl *, CharUnits> &BaseOffsets,
+    llvm::DenseMap<const CXXRecordDecl *, CharUnits> &VirtualBaseOffsets) {
+  return false;
+}
+
 Decl *ExternalASTSource::GetExternalDecl(uint32_t ID) {
-  return 0;
+  return nullptr;
 }
 
 Selector ExternalASTSource::GetExternalSelector(uint32_t ID) {
@@ -35,12 +63,12 @@
 }
 
 Stmt *ExternalASTSource::GetExternalDeclStmt(uint64_t Offset) {
-  return 0;
+  return nullptr;
 }
 
 CXXBaseSpecifier *
 ExternalASTSource::GetExternalCXXBaseSpecifiers(uint64_t Offset) {
-  return 0;
+  return nullptr;
 }
 
 bool
@@ -60,3 +88,21 @@
 }
 
 void ExternalASTSource::getMemoryBufferSizes(MemoryBufferSizes &sizes) const { }
+
+uint32_t ExternalASTSource::incrementGeneration(ASTContext &C) {
+  uint32_t OldGeneration = CurrentGeneration;
+
+  // Make sure the generation of the topmost external source for the context is
+  // incremented. That might not be us.
+  auto *P = C.getExternalSource();
+  if (P && P != this)
+    CurrentGeneration = P->incrementGeneration(C);
+  else {
+    // FIXME: Only bump the generation counter if the current generation number
+    // has been observed?
+    if (!++CurrentGeneration)
+      llvm::report_fatal_error("generation counter overflowed", false);
+  }
+
+  return OldGeneration;
+}
diff --git a/lib/AST/InheritViz.cpp b/lib/AST/InheritViz.cpp
index 3d64310..eb3020c 100644
--- a/lib/AST/InheritViz.cpp
+++ b/lib/AST/InheritViz.cpp
@@ -93,26 +93,25 @@
   // Display the base classes.
   const CXXRecordDecl *Decl
     = static_cast<const CXXRecordDecl *>(Type->getAs<RecordType>()->getDecl());
-  for (CXXRecordDecl::base_class_const_iterator Base = Decl->bases_begin();
-       Base != Decl->bases_end(); ++Base) {
-    QualType CanonBaseType = Context.getCanonicalType(Base->getType());
+  for (const auto &Base : Decl->bases()) {
+    QualType CanonBaseType = Context.getCanonicalType(Base.getType());
 
     // If this is not virtual inheritance, bump the direct base
     // count for the type.
-    if (!Base->isVirtual())
+    if (!Base.isVirtual())
       ++DirectBaseCount[CanonBaseType];
 
     // Write out the node (if we need to).
-    WriteNode(Base->getType(), Base->isVirtual());
+    WriteNode(Base.getType(), Base.isVirtual());
 
     // Write out the edge.
     Out << "  ";
     WriteNodeReference(Type, FromVirtual);
     Out << " -> ";
-    WriteNodeReference(Base->getType(), Base->isVirtual());
+    WriteNodeReference(Base.getType(), Base.isVirtual());
 
     // Write out edge attributes to show the kind of inheritance.
-    if (Base->isVirtual()) {
+    if (Base.isVirtual()) {
       Out << " [ style=\"dashed\" ]";
     }
     Out << ";";
@@ -140,7 +139,7 @@
 
   int FD;
   SmallString<128> Filename;
-  error_code EC =
+  std::error_code EC =
       sys::fs::createTemporaryFile(Self.getAsString(), "dot", FD, Filename);
   if (EC) {
     llvm::errs() << "Error: " << EC.message() << "\n";
diff --git a/lib/AST/ItaniumCXXABI.cpp b/lib/AST/ItaniumCXXABI.cpp
index 5784660..b5f8c0f 100644
--- a/lib/AST/ItaniumCXXABI.cpp
+++ b/lib/AST/ItaniumCXXABI.cpp
@@ -33,12 +33,17 @@
 /// literals within a particular context.
 class ItaniumNumberingContext : public MangleNumberingContext {
   llvm::DenseMap<IdentifierInfo*, unsigned> VarManglingNumbers;
+  llvm::DenseMap<IdentifierInfo*, unsigned> TagManglingNumbers;
 
 public:
   /// Variable decls are numbered by identifier.
-  virtual unsigned getManglingNumber(const VarDecl *VD) {
+  unsigned getManglingNumber(const VarDecl *VD, unsigned) override {
     return ++VarManglingNumbers[VD->getIdentifier()];
   }
+
+  unsigned getManglingNumber(const TagDecl *TD, unsigned) override {
+    return ++TagManglingNumbers[TD->getIdentifier()];
+  }
 };
 
 class ItaniumCXXABI : public CXXABI {
@@ -48,7 +53,7 @@
   ItaniumCXXABI(ASTContext &Ctx) : Context(Ctx) { }
 
   std::pair<uint64_t, unsigned>
-  getMemberPointerWidthAndAlign(const MemberPointerType *MPT) const {
+  getMemberPointerWidthAndAlign(const MemberPointerType *MPT) const override {
     const TargetInfo &Target = Context.getTargetInfo();
     TargetInfo::IntType PtrDiff = Target.getPtrDiffType(0);
     uint64_t Width = Target.getTypeWidth(PtrDiff);
@@ -58,13 +63,17 @@
     return std::make_pair(Width, Align);
   }
 
-  CallingConv getDefaultMethodCallConv(bool isVariadic) const {
+  CallingConv getDefaultMethodCallConv(bool isVariadic) const override {
+    const llvm::Triple &T = Context.getTargetInfo().getTriple();
+    if (!isVariadic && T.isWindowsGNUEnvironment() &&
+        T.getArch() == llvm::Triple::x86)
+      return CC_X86ThisCall;
     return CC_C;
   }
 
   // We cheat and just check that the class has a vtable pointer, and that it's
   // only big enough to have a vtable pointer and nothing more (or less).
-  bool isNearlyEmpty(const CXXRecordDecl *RD) const {
+  bool isNearlyEmpty(const CXXRecordDecl *RD) const override {
 
     // Check that the class has a vtable pointer.
     if (!RD->isDynamicClass())
@@ -76,21 +85,12 @@
     return Layout.getNonVirtualSize() == PointerSize;
   }
 
-  virtual MangleNumberingContext *createMangleNumberingContext() const {
+  MangleNumberingContext *createMangleNumberingContext() const override {
     return new ItaniumNumberingContext();
   }
 };
-
-class ARMCXXABI : public ItaniumCXXABI {
-public:
-  ARMCXXABI(ASTContext &Ctx) : ItaniumCXXABI(Ctx) { }
-};
 }
 
 CXXABI *clang::CreateItaniumCXXABI(ASTContext &Ctx) {
   return new ItaniumCXXABI(Ctx);
 }
-
-CXXABI *clang::CreateARMCXXABI(ASTContext &Ctx) {
-  return new ARMCXXABI(Ctx);
-}
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index e94b4cf..977d6fc 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -11,7 +11,7 @@
 // which is used in GCC 3.2 and newer (and many compilers that are
 // ABI-compatible with GCC):
 //
-//   http://www.codesourcery.com/public/cxx-abi/abi.html
+//   http://mentorembedded.github.io/cxx-abi/abi.html#mangling
 //
 //===----------------------------------------------------------------------===//
 #include "clang/AST/Mangle.h"
@@ -21,6 +21,7 @@
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/TypeLoc.h"
@@ -87,7 +88,7 @@
     D = cast<Decl>(DC);
     DC = getEffectiveDeclContext(D);
   }
-  return 0;
+  return nullptr;
 }
 
 static const FunctionDecl *getStructor(const FunctionDecl *fn) {
@@ -101,11 +102,18 @@
   const FunctionDecl *fn = dyn_cast_or_null<FunctionDecl>(decl);
   return (fn ? getStructor(fn) : decl);
 }
-                                                    
+
+static bool isLambda(const NamedDecl *ND) {
+  const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(ND);
+  if (!Record)
+    return false;
+
+  return Record->isLambda();
+}
+
 static const unsigned UnknownArity = ~0U;
 
 class ItaniumMangleContextImpl : public ItaniumMangleContext {
-  llvm::DenseMap<const TagDecl *, uint64_t> AnonStructIds;
   typedef std::pair<const DeclContext*, IdentifierInfo*> DiscriminatorKeyTy;
   llvm::DenseMap<DiscriminatorKeyTy, unsigned> Discriminator;
   llvm::DenseMap<const NamedDecl*, unsigned> Uniquifier;
@@ -115,51 +123,47 @@
                                     DiagnosticsEngine &Diags)
       : ItaniumMangleContext(Context, Diags) {}
 
-  uint64_t getAnonymousStructId(const TagDecl *TD) {
-    std::pair<llvm::DenseMap<const TagDecl *,
-      uint64_t>::iterator, bool> Result =
-      AnonStructIds.insert(std::make_pair(TD, AnonStructIds.size()));
-    return Result.first->second;
-  }
-
   /// @name Mangler Entry Points
   /// @{
 
-  bool shouldMangleCXXName(const NamedDecl *D);
-  void mangleCXXName(const NamedDecl *D, raw_ostream &);
-  void mangleThunk(const CXXMethodDecl *MD,
-                   const ThunkInfo &Thunk,
-                   raw_ostream &);
+  bool shouldMangleCXXName(const NamedDecl *D) override;
+  bool shouldMangleStringLiteral(const StringLiteral *) override {
+    return false;
+  }
+  void mangleCXXName(const NamedDecl *D, raw_ostream &) override;
+  void mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk,
+                   raw_ostream &) override;
   void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
                           const ThisAdjustment &ThisAdjustment,
-                          raw_ostream &);
-  void mangleReferenceTemporary(const VarDecl *D,
-                                raw_ostream &);
-  void mangleCXXVTable(const CXXRecordDecl *RD,
-                       raw_ostream &);
-  void mangleCXXVTT(const CXXRecordDecl *RD,
-                    raw_ostream &);
+                          raw_ostream &) override;
+  void mangleReferenceTemporary(const VarDecl *D, unsigned ManglingNumber,
+                                raw_ostream &) override;
+  void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) override;
+  void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) override;
   void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
-                           const CXXRecordDecl *Type,
-                           raw_ostream &);
-  void mangleCXXRTTI(QualType T, raw_ostream &);
-  void mangleCXXRTTIName(QualType T, raw_ostream &);
+                           const CXXRecordDecl *Type, raw_ostream &) override;
+  void mangleCXXRTTI(QualType T, raw_ostream &) override;
+  void mangleCXXRTTIName(QualType T, raw_ostream &) override;
+  void mangleTypeName(QualType T, raw_ostream &) override;
   void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
-                     raw_ostream &);
+                     raw_ostream &) override;
   void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
-                     raw_ostream &);
+                     raw_ostream &) override;
 
-  void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &);
-  void mangleDynamicInitializer(const VarDecl *D, raw_ostream &Out);
-  void mangleDynamicAtExitDestructor(const VarDecl *D, raw_ostream &Out);
-  void mangleItaniumThreadLocalInit(const VarDecl *D, raw_ostream &);
-  void mangleItaniumThreadLocalWrapper(const VarDecl *D, raw_ostream &);
+  void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) override;
+  void mangleDynamicInitializer(const VarDecl *D, raw_ostream &Out) override;
+  void mangleDynamicAtExitDestructor(const VarDecl *D,
+                                     raw_ostream &Out) override;
+  void mangleItaniumThreadLocalInit(const VarDecl *D, raw_ostream &) override;
+  void mangleItaniumThreadLocalWrapper(const VarDecl *D,
+                                       raw_ostream &) override;
+
+  void mangleStringLiteral(const StringLiteral *, raw_ostream &) override;
 
   bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc) {
     // Lambda closure types are already numbered.
-    if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(ND))
-      if (RD->isLambda())
-        return false;
+    if (isLambda(ND))
+      return false;
 
     // Anonymous tags are already numbered.
     if (const TagDecl *Tag = dyn_cast<TagDecl>(ND)) {
@@ -249,7 +253,7 @@
 
 public:
   CXXNameMangler(ItaniumMangleContextImpl &C, raw_ostream &Out_,
-                 const NamedDecl *D = 0)
+                 const NamedDecl *D = nullptr)
     : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(0),
       SeqID(0) {
     // These can't be mangled without a ctor type or dtor type.
@@ -284,11 +288,13 @@
   void mangleNumber(int64_t Number);
   void mangleFloat(const llvm::APFloat &F);
   void mangleFunctionEncoding(const FunctionDecl *FD);
+  void mangleSeqID(unsigned SeqID);
   void mangleName(const NamedDecl *ND);
   void mangleType(QualType T);
   void mangleNameOrStandardSubstitution(const NamedDecl *ND);
   
 private:
+
   bool mangleSubstitution(const NamedDecl *ND);
   bool mangleSubstitution(QualType T);
   bool mangleSubstitution(TemplateName Template);
@@ -453,6 +459,25 @@
   if (!Context.shouldMangleDeclName(FD))
     return;
 
+  if (FD->hasAttr<EnableIfAttr>()) {
+    FunctionTypeDepthState Saved = FunctionTypeDepth.push();
+    Out << "Ua9enable_ifI";
+    // FIXME: specific_attr_iterator iterates in reverse order. Fix that and use
+    // it here.
+    for (AttrVec::const_reverse_iterator I = FD->getAttrs().rbegin(),
+                                         E = FD->getAttrs().rend();
+         I != E; ++I) {
+      EnableIfAttr *EIA = dyn_cast<EnableIfAttr>(*I);
+      if (!EIA)
+        continue;
+      Out << 'X';
+      mangleExpression(EIA->getCond());
+      Out << 'E';
+    }
+    Out << 'E';
+    FunctionTypeDepth.pop(Saved);
+  }
+
   // Whether the mangling of a function type includes the return type depends on
   // the context and the nature of the function. The rules for deciding whether
   // the return type is included are:
@@ -534,15 +559,7 @@
     return Spec->getSpecializedTemplate();
   }
 
-  return 0;
-}
-
-static bool isLambda(const NamedDecl *ND) {
-  const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(ND);
-  if (!Record)
-    return false;
-  
-  return Record->isLambda();
+  return nullptr;
 }
 
 void CXXNameMangler::mangleName(const NamedDecl *ND) {
@@ -569,7 +586,7 @@
 
   if (DC->isTranslationUnit() || isStdNamespace(DC)) {
     // Check if we have a template.
-    const TemplateArgumentList *TemplateArgs = 0;
+    const TemplateArgumentList *TemplateArgs = nullptr;
     if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) {
       mangleUnscopedTemplateName(TD);
       mangleTemplateArgs(*TemplateArgs);
@@ -832,6 +849,7 @@
     switch (type->getTypeClass()) {
     case Type::Builtin:
     case Type::Complex:
+    case Type::Adjusted:
     case Type::Decayed:
     case Type::Pointer:
     case Type::BlockPointer:
@@ -982,26 +1000,27 @@
 
         // Pretend we had a different nested name specifier.
         newQualifier = NestedNameSpecifier::Create(getASTContext(),
-                                                   /*prefix*/ 0,
+                                                   /*prefix*/ nullptr,
                                                    /*template*/ false,
                                                    type.getTypePtr());
       } else if (NamespaceDecl *nspace =
                    dyn_cast<NamespaceDecl>(firstQualifierLookup)) {
         newQualifier = NestedNameSpecifier::Create(getASTContext(),
-                                                   /*prefix*/ 0,
+                                                   /*prefix*/ nullptr,
                                                    nspace);
       } else if (NamespaceAliasDecl *alias =
                    dyn_cast<NamespaceAliasDecl>(firstQualifierLookup)) {
         newQualifier = NestedNameSpecifier::Create(getASTContext(),
-                                                   /*prefix*/ 0,
+                                                   /*prefix*/ nullptr,
                                                    alias);
       } else {
         // No sensible mangling to do here.
-        newQualifier = 0;
+        newQualifier = nullptr;
       }
 
       if (newQualifier)
-        return mangleUnresolvedPrefix(newQualifier, /*lookup*/ 0, recursive);
+        return mangleUnresolvedPrefix(newQualifier, /*lookup*/ nullptr,
+                                      recursive);
 
     } else {
       Out << "sr";
@@ -1024,26 +1043,25 @@
                                           DeclarationName name,
                                           unsigned knownArity) {
   if (qualifier) mangleUnresolvedPrefix(qualifier, firstQualifierLookup);
-  mangleUnqualifiedName(0, name, knownArity);
+  mangleUnqualifiedName(nullptr, name, knownArity);
 }
 
 static const FieldDecl *FindFirstNamedDataMember(const RecordDecl *RD) {
   assert(RD->isAnonymousStructOrUnion() &&
          "Expected anonymous struct or union!");
   
-  for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
-       I != E; ++I) {
+  for (const auto *I : RD->fields()) {
     if (I->getIdentifier())
-      return *I;
+      return I;
     
     if (const RecordType *RT = I->getType()->getAs<RecordType>())
       if (const FieldDecl *NamedDataMember = 
           FindFirstNamedDataMember(RT->getDecl()))
         return NamedDataMember;
-    }
+  }
 
   // We didn't find a named data member.
-  return 0;
+  return nullptr;
 }
 
 void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
@@ -1147,7 +1165,7 @@
     }
 
     // Get a unique id for the anonymous struct.
-    uint64_t AnonStructId = Context.getAnonymousStructId(TD);
+    unsigned AnonStructId = Context.getAnonymousStructId(TD);
 
     // Mangle it as a source name in the form
     // [n] $_<id>
@@ -1249,7 +1267,7 @@
   }
   
   // Check if we have a template.
-  const TemplateArgumentList *TemplateArgs = 0;
+  const TemplateArgumentList *TemplateArgs = nullptr;
   if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) {
     mangleTemplatePrefix(TD, NoFunction);
     mangleTemplateArgs(*TemplateArgs);
@@ -1489,7 +1507,7 @@
     return;
   
   // Check if we have a template.
-  const TemplateArgumentList *TemplateArgs = 0;
+  const TemplateArgumentList *TemplateArgs = nullptr;
   if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) {
     mangleTemplatePrefix(TD);
     mangleTemplateArgs(*TemplateArgs);
@@ -1513,7 +1531,7 @@
   
   if (OverloadedTemplateStorage *Overloaded
                                       = Template.getAsOverloadedTemplate()) {
-    mangleUnqualifiedName(0, (*Overloaded->begin())->getDeclName(), 
+    mangleUnqualifiedName(nullptr, (*Overloaded->begin())->getDeclName(),
                           UnknownArity);
     return;
   }
@@ -1555,8 +1573,8 @@
 void CXXNameMangler::mangleType(TemplateName TN) {
   if (mangleSubstitution(TN))
     return;
-      
-  TemplateDecl *TD = 0;
+
+  TemplateDecl *TD = nullptr;
 
   switch (TN.getKind()) {
   case TemplateName::QualifiedTemplate:
@@ -1583,7 +1601,7 @@
 
     // <class-enum-type> ::= <name>
     // <name> ::= <nested-name>
-    mangleUnresolvedPrefix(Dependent->getQualifier(), 0);
+    mangleUnresolvedPrefix(Dependent->getQualifier(), nullptr);
     mangleSourceName(Dependent->getIdentifier());
     break;
   }
@@ -1918,7 +1936,7 @@
   //                 ::= x  # long long, __int64
   //                 ::= y  # unsigned long long, __int64
   //                 ::= n  # __int128
-  // UNSUPPORTED:    ::= o  # unsigned __int128
+  //                 ::= o  # unsigned __int128
   //                 ::= f  # float
   //                 ::= d  # double
   //                 ::= e  # long double, __float80
@@ -2011,11 +2029,11 @@
   // <bare-function-type> ::= <signature type>+
   if (MangleReturnType) {
     FunctionTypeDepth.enterResultType();
-    mangleType(Proto->getResultType());
+    mangleType(Proto->getReturnType());
     FunctionTypeDepth.leaveResultType();
   }
 
-  if (Proto->getNumArgs() == 0 && !Proto->isVariadic()) {
+  if (Proto->getNumParams() == 0 && !Proto->isVariadic()) {
     //   <builtin-type> ::= v   # void
     Out << 'v';
 
@@ -2023,10 +2041,8 @@
     return;
   }
 
-  for (FunctionProtoType::arg_type_iterator Arg = Proto->arg_type_begin(),
-                                         ArgEnd = Proto->arg_type_end();
-       Arg != ArgEnd; ++Arg)
-    mangleType(Context.getASTContext().getSignatureParameterType(*Arg));
+  for (const auto &Arg : Proto->param_types())
+    mangleType(Context.getASTContext().getSignatureParameterType(Arg));
 
   FunctionTypeDepth.pop(saved);
 
@@ -2157,11 +2173,20 @@
 void CXXNameMangler::mangleNeonVectorType(const VectorType *T) {
   QualType EltType = T->getElementType();
   assert(EltType->isBuiltinType() && "Neon vector element not a BuiltinType");
-  const char *EltName = 0;
+  const char *EltName = nullptr;
   if (T->getVectorKind() == VectorType::NeonPolyVector) {
     switch (cast<BuiltinType>(EltType)->getKind()) {
-    case BuiltinType::SChar:     EltName = "poly8_t"; break;
-    case BuiltinType::Short:     EltName = "poly16_t"; break;
+    case BuiltinType::SChar:
+    case BuiltinType::UChar:
+      EltName = "poly8_t";
+      break;
+    case BuiltinType::Short:
+    case BuiltinType::UShort:
+      EltName = "poly16_t";
+      break;
+    case BuiltinType::ULongLong:
+      EltName = "poly64_t";
+      break;
     default: llvm_unreachable("unexpected Neon polynomial vector element type");
     }
   } else {
@@ -2174,13 +2199,14 @@
     case BuiltinType::UInt:      EltName = "uint32_t"; break;
     case BuiltinType::LongLong:  EltName = "int64_t"; break;
     case BuiltinType::ULongLong: EltName = "uint64_t"; break;
+    case BuiltinType::Double:    EltName = "float64_t"; break;
     case BuiltinType::Float:     EltName = "float32_t"; break;
     case BuiltinType::Half:      EltName = "float16_t";break;
     default:
       llvm_unreachable("unexpected Neon vector element type");
     }
   }
-  const char *BaseName = 0;
+  const char *BaseName = nullptr;
   unsigned BitSize = (T->getNumElements() *
                       getASTContext().getTypeSize(EltType));
   if (BitSize == 64)
@@ -2201,6 +2227,7 @@
     return "Int16";
   case BuiltinType::Int:
     return "Int32";
+  case BuiltinType::Long:
   case BuiltinType::LongLong:
     return "Int64";
   case BuiltinType::UChar:
@@ -2209,6 +2236,7 @@
     return "Uint16";
   case BuiltinType::UInt:
     return "Uint32";
+  case BuiltinType::ULong:
   case BuiltinType::ULongLong:
     return "Uint64";
   case BuiltinType::Half:
@@ -2244,7 +2272,7 @@
     case BuiltinType::UShort:
       EltName = "Poly16";
       break;
-    case BuiltinType::ULongLong:
+    case BuiltinType::ULong:
       EltName = "Poly64";
       break;
     default:
@@ -2269,8 +2297,13 @@
 void CXXNameMangler::mangleType(const VectorType *T) {
   if ((T->getVectorKind() == VectorType::NeonVector ||
        T->getVectorKind() == VectorType::NeonPolyVector)) {
-    if (getASTContext().getTargetInfo().getTriple().getArch() ==
-        llvm::Triple::aarch64)
+    llvm::Triple Target = getASTContext().getTargetInfo().getTriple();
+    llvm::Triple::ArchType Arch =
+        getASTContext().getTargetInfo().getTriple().getArch();
+    if ((Arch == llvm::Triple::aarch64 ||
+         Arch == llvm::Triple::aarch64_be ||
+         Arch == llvm::Triple::arm64_be ||
+         Arch == llvm::Triple::arm64) && !Target.isOSDarwin())
       mangleAArch64NeonVectorType(T);
     else
       mangleNeonVectorType(T);
@@ -2310,9 +2343,8 @@
     SmallString<64> QualStr;
     llvm::raw_svector_ostream QualOS(QualStr);
     QualOS << "objcproto";
-    ObjCObjectType::qual_iterator i = T->qual_begin(), e = T->qual_end();
-    for ( ; i != e; ++i) {
-      StringRef name = (*i)->getName();
+    for (const auto *I : T->quals()) {
+      StringRef name = I->getName();
       QualOS << name.size() << name;
     }
     QualOS.flush();
@@ -2351,10 +2383,37 @@
 }
 
 void CXXNameMangler::mangleType(const DependentNameType *T) {
+  // Proposal by cxx-abi-dev, 2014-03-26
+  // <class-enum-type> ::= <name>    # non-dependent or dependent type name or
+  //                                 # dependent elaborated type specifier using
+  //                                 # 'typename'
+  //                   ::= Ts <name> # dependent elaborated type specifier using
+  //                                 # 'struct' or 'class'
+  //                   ::= Tu <name> # dependent elaborated type specifier using
+  //                                 # 'union'
+  //                   ::= Te <name> # dependent elaborated type specifier using
+  //                                 # 'enum'
+  switch (T->getKeyword()) {
+    case ETK_Typename:
+      break;
+    case ETK_Struct:
+    case ETK_Class:
+    case ETK_Interface:
+      Out << "Ts";
+      break;
+    case ETK_Union:
+      Out << "Tu";
+      break;
+    case ETK_Enum:
+      Out << "Te";
+      break;
+    default:
+      llvm_unreachable("unexpected keyword for dependent type name");
+  }
   // Typename types are always nested
   Out << 'N';
   manglePrefix(T->getQualifier());
-  mangleSourceName(T->getIdentifier());    
+  mangleSourceName(T->getIdentifier());
   Out << 'E';
 }
 
@@ -2437,7 +2496,7 @@
 }
 
 void CXXNameMangler::mangleType(const AtomicType *T) {
-  // <type> ::= U <source-name> <type>	# vendor extended type qualifier
+  // <type> ::= U <source-name> <type>  # vendor extended type qualifier
   // (Until there's a standardized mangling...)
   Out << "U7_Atomic";
   mangleType(T->getValueType());
@@ -2580,8 +2639,6 @@
   case Expr::ShuffleVectorExprClass:
   case Expr::ConvertVectorExprClass:
   case Expr::StmtExprClass:
-  case Expr::UnaryTypeTraitExprClass:
-  case Expr::BinaryTypeTraitExprClass:
   case Expr::TypeTraitExprClass:
   case Expr::ArrayTypeTraitExprClass:
   case Expr::ExpressionTraitExprClass:
@@ -2617,7 +2674,6 @@
     llvm_unreachable("cannot mangle opaque value; mangling wrong thing?");
 
   case Expr::InitListExprClass: {
-    // Proposal by Jason Merrill, 2012-01-03
     Out << "il";
     const InitListExpr *InitList = cast<InitListExpr>(E);
     for (unsigned i = 0, e = InitList->getNumInits(); i != e; ++i)
@@ -2682,7 +2738,6 @@
     Out << '_';
     mangleType(New->getAllocatedType());
     if (New->hasInitializer()) {
-      // Proposal by Jason Merrill, 2012-01-03
       if (New->getInitializationStyle() == CXXNewExpr::ListInit)
         Out << "il";
       else
@@ -2713,15 +2768,15 @@
   case Expr::MemberExprClass: {
     const MemberExpr *ME = cast<MemberExpr>(E);
     mangleMemberExpr(ME->getBase(), ME->isArrow(),
-                     ME->getQualifier(), 0, ME->getMemberDecl()->getDeclName(),
-                     Arity);
+                     ME->getQualifier(), nullptr,
+                     ME->getMemberDecl()->getDeclName(), Arity);
     break;
   }
 
   case Expr::UnresolvedMemberExprClass: {
     const UnresolvedMemberExpr *ME = cast<UnresolvedMemberExpr>(E);
     mangleMemberExpr(ME->getBase(), ME->isArrow(),
-                     ME->getQualifier(), 0, ME->getMemberName(),
+                     ME->getQualifier(), nullptr, ME->getMemberName(),
                      Arity);
     if (ME->hasExplicitTemplateArgs())
       mangleTemplateArgs(ME->getExplicitTemplateArgs());
@@ -2741,7 +2796,7 @@
 
   case Expr::UnresolvedLookupExprClass: {
     const UnresolvedLookupExpr *ULE = cast<UnresolvedLookupExpr>(E);
-    mangleUnresolvedName(ULE->getQualifier(), 0, ULE->getName(), Arity);
+    mangleUnresolvedName(ULE->getQualifier(), nullptr, ULE->getName(), Arity);
 
     // All the <unresolved-name> productions end in a
     // base-unresolved-name, where <template-args> are just tacked
@@ -2768,7 +2823,6 @@
     const CXXConstructExpr *CE = cast<CXXConstructExpr>(E);
     unsigned N = CE->getNumArgs();
 
-    // Proposal by Jason Merrill, 2012-01-03
     if (CE->isListInitialization())
       Out << "tl";
     else
@@ -3004,7 +3058,8 @@
 
   case Expr::DependentScopeDeclRefExprClass: {
     const DependentScopeDeclRefExpr *DRE = cast<DependentScopeDeclRefExpr>(E);
-    mangleUnresolvedName(DRE->getQualifier(), 0, DRE->getDeclName(), Arity);
+    mangleUnresolvedName(DRE->getQualifier(), nullptr, DRE->getDeclName(),
+                         Arity);
 
     // All the <unresolved-name> productions end in a
     // base-unresolved-name, where <template-args> are just tacked
@@ -3341,10 +3396,8 @@
   case TemplateArgument::Pack: {
     //  <template-arg> ::= J <template-arg>* E
     Out << 'J';
-    for (TemplateArgument::pack_iterator PA = A.pack_begin(),
-                                      PAEnd = A.pack_end();
-         PA != PAEnd; ++PA)
-      mangleTemplateArg(*PA);
+    for (const auto &P : A.pack_elements())
+      mangleTemplateArg(P);
     Out << 'E';
   }
   }
@@ -3359,6 +3412,27 @@
     Out << 'T' << (Index - 1) << '_';
 }
 
+void CXXNameMangler::mangleSeqID(unsigned SeqID) {
+  if (SeqID == 1)
+    Out << '0';
+  else if (SeqID > 1) {
+    SeqID--;
+
+    // <seq-id> is encoded in base-36, using digits and upper case letters.
+    char Buffer[7]; // log(2**32) / log(36) ~= 7
+    MutableArrayRef<char> BufferRef(Buffer);
+    MutableArrayRef<char>::reverse_iterator I = BufferRef.rbegin();
+
+    for (; SeqID != 0; SeqID /= 36) {
+      unsigned C = SeqID % 36;
+      *I++ = (C < 10 ? '0' + C : 'A' + C - 10);
+    }
+
+    Out.write(I.base(), I - BufferRef.rbegin());
+  }
+  Out << '_';
+}
+
 void CXXNameMangler::mangleExistingSubstitution(QualType type) {
   bool result = mangleSubstitution(type);
   assert(result && "no existing substitution for type");
@@ -3415,30 +3489,8 @@
     return false;
 
   unsigned SeqID = I->second;
-  if (SeqID == 0)
-    Out << "S_";
-  else {
-    SeqID--;
-
-    // <seq-id> is encoded in base-36, using digits and upper case letters.
-    char Buffer[10];
-    char *BufferPtr = llvm::array_endof(Buffer);
-
-    if (SeqID == 0) *--BufferPtr = '0';
-
-    while (SeqID) {
-      assert(BufferPtr > Buffer && "Buffer overflow!");
-
-      char c = static_cast<char>(SeqID % 36);
-
-      *--BufferPtr =  (c < 10 ? '0' + c : 'A' + c - 10);
-      SeqID /= 36;
-    }
-
-    Out << 'S'
-        << StringRef(BufferPtr, llvm::array_endof(Buffer)-BufferPtr)
-        << '_';
-  }
+  Out << 'S';
+  mangleSeqID(SeqID);
 
   return true;
 }
@@ -3731,12 +3783,15 @@
 }
 
 void ItaniumMangleContextImpl::mangleReferenceTemporary(const VarDecl *D,
+                                                        unsigned ManglingNumber,
                                                         raw_ostream &Out) {
   // We match the GCC mangling here.
   //  <special-name> ::= GR <object name>
   CXXNameMangler Mangler(*this, Out);
   Mangler.getStream() << "_ZGR";
   Mangler.mangleName(D);
+  assert(ManglingNumber > 0 && "Reference temporary mangling number is zero!");
+  Mangler.mangleSeqID(ManglingNumber - 1);
 }
 
 void ItaniumMangleContextImpl::mangleCXXVTable(const CXXRecordDecl *RD,
@@ -3784,6 +3839,14 @@
   Mangler.mangleType(Ty);
 }
 
+void ItaniumMangleContextImpl::mangleTypeName(QualType Ty, raw_ostream &Out) {
+  mangleCXXRTTIName(Ty, Out);
+}
+
+void ItaniumMangleContextImpl::mangleStringLiteral(const StringLiteral *, raw_ostream &) {
+  llvm_unreachable("Can't mangle string literals");
+}
+
 ItaniumMangleContext *
 ItaniumMangleContext::create(ASTContext &Context, DiagnosticsEngine &Diags) {
   return new ItaniumMangleContextImpl(Context, Diags);
diff --git a/lib/AST/Mangle.cpp b/lib/AST/Mangle.cpp
index 231ef03..fdc00e3 100644
--- a/lib/AST/Mangle.cpp
+++ b/lib/AST/Mangle.cpp
@@ -11,13 +11,13 @@
 //
 //===----------------------------------------------------------------------===//
 #include "clang/AST/Attr.h"
-#include "clang/AST/Mangle.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/ExprCXX.h"
+#include "clang/AST/Mangle.h"
 #include "clang/Basic/ABI.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
@@ -64,7 +64,7 @@
 static StdOrFastCC getStdOrFastCallMangling(const ASTContext &Context,
                                             const NamedDecl *ND) {
   const TargetInfo &TI = Context.getTargetInfo();
-  llvm::Triple Triple = TI.getTriple();
+  const llvm::Triple &Triple = TI.getTriple();
   if (!Triple.isOSWindows() || Triple.getArch() != llvm::Triple::x86)
     return SOF_OTHER;
 
@@ -163,13 +163,9 @@
   if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD))
     if (!MD->isStatic())
       ++ArgWords;
-  for (FunctionProtoType::arg_type_iterator Arg = Proto->arg_type_begin(),
-         ArgEnd = Proto->arg_type_end();
-       Arg != ArgEnd; ++Arg) {
-    QualType AT = *Arg;
+  for (const auto &AT : Proto->param_types())
     // Size should be aligned to DWORD boundary
     ArgWords += llvm::RoundUpToAlignment(ASTContext.getTypeSize(AT), 32) / 32;
-  }
   Out << 4 * ArgWords;
 }
 
@@ -246,7 +242,9 @@
   OS << (MD->isInstanceMethod() ? '-' : '+') << '[' << CD->getName();
   if (const ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(CD))
     OS << '(' << *CID << ')';
-  OS << ' ' << MD->getSelector().getAsString() << ']';
+  OS << ' ';
+  MD->getSelector().print(OS);
+  OS << ']';
   
   Out << OS.str().size() << OS.str();
 }
diff --git a/lib/AST/MangleNumberingContext.cpp b/lib/AST/MangleNumberingContext.cpp
index 91ef0e2..5f40f03 100644
--- a/lib/AST/MangleNumberingContext.cpp
+++ b/lib/AST/MangleNumberingContext.cpp
@@ -24,7 +24,7 @@
     = CallOperator->getType()->getAs<FunctionProtoType>();
   ASTContext &Context = CallOperator->getASTContext();
 
-  QualType Key = Context.getFunctionType(Context.VoidTy, Proto->getArgTypes(),
+  QualType Key = Context.getFunctionType(Context.VoidTy, Proto->getParamTypes(),
                                          FunctionProtoType::ExtProtoInfo());
   Key = Context.getCanonicalType(Key);
   return ++ManglingNumbers[Key->castAs<FunctionProtoType>()];
@@ -33,11 +33,13 @@
 unsigned
 MangleNumberingContext::getManglingNumber(const BlockDecl *BD) {
   // FIXME: Compute a BlockPointerType?  Not obvious how.
-  const Type *Ty = 0;
+  const Type *Ty = nullptr;
   return ++ManglingNumbers[Ty];
 }
 
 unsigned
-MangleNumberingContext::getManglingNumber(const TagDecl *TD) {
-  return ++TagManglingNumbers[TD->getIdentifier()];
+MangleNumberingContext::getStaticLocalNumber(const VarDecl *VD) {
+  // FIXME: Compute a BlockPointerType?  Not obvious how.
+  const Type *Ty = nullptr;
+  return ++ManglingNumbers[Ty];
 }
diff --git a/lib/AST/MicrosoftCXXABI.cpp b/lib/AST/MicrosoftCXXABI.cpp
index 4a93ea1..6870315 100644
--- a/lib/AST/MicrosoftCXXABI.cpp
+++ b/lib/AST/MicrosoftCXXABI.cpp
@@ -13,8 +13,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "CXXABI.h"
-#include "clang/AST/Attr.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/Attr.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/MangleNumberingContext.h"
 #include "clang/AST/RecordLayout.h"
@@ -28,15 +28,15 @@
 /// \brief Numbers things which need to correspond across multiple TUs.
 /// Typically these are things like static locals, lambdas, or blocks.
 class MicrosoftNumberingContext : public MangleNumberingContext {
-  unsigned NumStaticLocals;
-
 public:
-  MicrosoftNumberingContext() : NumStaticLocals(0) { }
+  unsigned getManglingNumber(const VarDecl *VD,
+                             unsigned MSLocalManglingNumber) override {
+    return MSLocalManglingNumber;
+  }
 
-  /// Static locals are numbered by source order.
-  virtual unsigned getManglingNumber(const VarDecl *VD) {
-    assert(VD->isStaticLocal());
-    return ++NumStaticLocals;
+  unsigned getManglingNumber(const TagDecl *TD,
+                             unsigned MSLocalManglingNumber) override {
+    return MSLocalManglingNumber;
   }
 };
 
@@ -46,16 +46,16 @@
   MicrosoftCXXABI(ASTContext &Ctx) : Context(Ctx) { }
 
   std::pair<uint64_t, unsigned>
-  getMemberPointerWidthAndAlign(const MemberPointerType *MPT) const;
+  getMemberPointerWidthAndAlign(const MemberPointerType *MPT) const override;
 
-  CallingConv getDefaultMethodCallConv(bool isVariadic) const {
+  CallingConv getDefaultMethodCallConv(bool isVariadic) const override {
     if (!isVariadic &&
         Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86)
       return CC_X86ThisCall;
     return CC_C;
   }
 
-  bool isNearlyEmpty(const CXXRecordDecl *RD) const {
+  bool isNearlyEmpty(const CXXRecordDecl *RD) const override {
     // FIXME: Audit the corners
     if (!RD->isDynamicClass())
       return false;
@@ -69,7 +69,7 @@
       Layout.getNonVirtualSize() == PointerSize * 2;
   }    
 
-  MangleNumberingContext *createMangleNumberingContext() const {
+  MangleNumberingContext *createMangleNumberingContext() const override {
     return new MicrosoftNumberingContext();
   }
 };
@@ -92,26 +92,27 @@
   return false;
 }
 
-static MSInheritanceModel MSInheritanceAttrToModel(attr::Kind Kind) {
-  switch (Kind) {
-  default: llvm_unreachable("expected MS inheritance attribute");
-  case attr::SingleInheritance:      return MSIM_Single;
-  case attr::MultipleInheritance:    return MSIM_Multiple;
-  case attr::VirtualInheritance:     return MSIM_Virtual;
-  case attr::UnspecifiedInheritance: return MSIM_Unspecified;
-  }
+MSInheritanceAttr::Spelling CXXRecordDecl::calculateInheritanceModel() const {
+  if (!hasDefinition() || isParsingBaseSpecifiers())
+    return MSInheritanceAttr::Keyword_unspecified_inheritance;
+  if (getNumVBases() > 0)
+    return MSInheritanceAttr::Keyword_virtual_inheritance;
+  if (usesMultipleInheritanceModel(this))
+    return MSInheritanceAttr::Keyword_multiple_inheritance;
+  return MSInheritanceAttr::Keyword_single_inheritance;
 }
 
-MSInheritanceModel CXXRecordDecl::getMSInheritanceModel() const {
-  if (Attr *IA = this->getAttr<MSInheritanceAttr>())
-    return MSInheritanceAttrToModel(IA->getKind());
-  // If there was no explicit attribute, the record must be defined already, and
-  // we can figure out the inheritance model from its other properties.
-  if (this->getNumVBases() > 0)
-    return MSIM_Virtual;
-  if (usesMultipleInheritanceModel(this))
-    return this->isPolymorphic() ? MSIM_MultiplePolymorphic : MSIM_Multiple;
-  return this->isPolymorphic() ? MSIM_SinglePolymorphic : MSIM_Single;
+MSInheritanceAttr::Spelling
+CXXRecordDecl::getMSInheritanceModel() const {
+  MSInheritanceAttr *IA = getAttr<MSInheritanceAttr>();
+  assert(IA && "Expected MSInheritanceAttr on the CXXRecordDecl!");
+  return IA->getSemanticSpelling();
+}
+
+MSVtorDispAttr::Mode CXXRecordDecl::getMSVtorDispMode() const {
+  if (MSVtorDispAttr *VDA = getAttr<MSVtorDispAttr>())
+    return VDA->getVtorDispMode();
+  return MSVtorDispAttr::Mode(getASTContext().getLangOpts().VtorDispMode);
 }
 
 // Returns the number of pointer and integer slots used to represent a member
@@ -133,49 +134,32 @@
 //     // offset.
 //     int NonVirtualBaseAdjustment;
 //
+//     // The offset of the vb-table pointer within the object.  Only needed for
+//     // incomplete types.
+//     int VBPtrOffset;
+//
 //     // An offset within the vb-table that selects the virtual base containing
 //     // the member.  Loading from this offset produces a new offset that is
 //     // added to the address of the vb-table pointer to produce the base.
 //     int VirtualBaseAdjustmentOffset;
-//
-//     // The offset of the vb-table pointer within the object.  Only needed for
-//     // incomplete types.
-//     int VBPtrOffset;
 //   };
 static std::pair<unsigned, unsigned>
 getMSMemberPointerSlots(const MemberPointerType *MPT) {
-  const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
-  MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
-  unsigned Ptrs;
+  const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
+  MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
+  unsigned Ptrs = 0;
   unsigned Ints = 0;
-  if (MPT->isMemberFunctionPointer()) {
-    // Member function pointers are a struct of a function pointer followed by a
-    // variable number of ints depending on the inheritance model used.  The
-    // function pointer is a real function if it is non-virtual and a vftable
-    // slot thunk if it is virtual.  The ints select the object base passed for
-    // the 'this' pointer.
-    Ptrs = 1;  // First slot is always a function pointer.
-    switch (Inheritance) {
-    case MSIM_Unspecified: ++Ints;  // VBTableOffset
-    case MSIM_Virtual:     ++Ints;  // VirtualBaseAdjustmentOffset
-    case MSIM_MultiplePolymorphic:
-    case MSIM_Multiple:    ++Ints;  // NonVirtualBaseAdjustment
-    case MSIM_SinglePolymorphic:
-    case MSIM_Single:      break;   // Nothing
-    }
-  } else {
-    // Data pointers are an aggregate of ints.  The first int is an offset
-    // followed by vbtable-related offsets.
-    Ptrs = 0;
-    switch (Inheritance) {
-    case MSIM_Unspecified: ++Ints;  // VBTableOffset
-    case MSIM_Virtual:     ++Ints;  // VirtualBaseAdjustmentOffset
-    case MSIM_MultiplePolymorphic:
-    case MSIM_Multiple:             // Nothing
-    case MSIM_SinglePolymorphic:
-    case MSIM_Single:      ++Ints;  // Field offset
-    }
-  }
+  if (MPT->isMemberFunctionPointer())
+    Ptrs = 1;
+  else
+    Ints = 1;
+  if (MSInheritanceAttr::hasNVOffsetField(MPT->isMemberFunctionPointer(),
+                                          Inheritance))
+    Ints++;
+  if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
+    Ints++;
+  if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
+    Ints++;
   return std::make_pair(Ptrs, Ints);
 }
 
@@ -185,14 +169,26 @@
   assert(Target.getTriple().getArch() == llvm::Triple::x86 ||
          Target.getTriple().getArch() == llvm::Triple::x86_64);
   unsigned Ptrs, Ints;
-  llvm::tie(Ptrs, Ints) = getMSMemberPointerSlots(MPT);
+  std::tie(Ptrs, Ints) = getMSMemberPointerSlots(MPT);
   // The nominal struct is laid out with pointers followed by ints and aligned
   // to a pointer width if any are present and an int width otherwise.
   unsigned PtrSize = Target.getPointerWidth(0);
   unsigned IntSize = Target.getIntWidth();
   uint64_t Width = Ptrs * PtrSize + Ints * IntSize;
-  unsigned Align = Ptrs > 0 ? Target.getPointerAlign(0) : Target.getIntAlign();
-  Width = llvm::RoundUpToAlignment(Width, Align);
+  unsigned Align;
+
+  // When MSVC does x86_32 record layout, it aligns aggregate member pointers to
+  // 8 bytes.  However, __alignof usually returns 4 for data memptrs and 8 for
+  // function memptrs.
+  if (Ptrs + Ints > 1 && Target.getTriple().getArch() == llvm::Triple::x86)
+    Align = 8 * 8;
+  else if (Ptrs)
+    Align = Target.getPointerAlign(0);
+  else
+    Align = Target.getIntAlign();
+
+  if (Target.getTriple().getArch() == llvm::Triple::x86_64)
+    Width = llvm::RoundUpToAlignment(Width, Align);
   return std::make_pair(Width, Align);
 }
 
diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp
index ff1b015..e6a6d09 100644
--- a/lib/AST/MicrosoftMangle.cpp
+++ b/lib/AST/MicrosoftMangle.cpp
@@ -14,17 +14,21 @@
 #include "clang/AST/Mangle.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Attr.h"
-#include "clang/AST/CharUnits.h"
 #include "clang/AST/CXXInheritance.h"
+#include "clang/AST/CharUnits.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
+#include "clang/AST/VTableBuilder.h"
 #include "clang/Basic/ABI.h"
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringMap.h"
+#include "llvm/Support/MathExtras.h"
 
 using namespace clang;
 
@@ -71,10 +75,114 @@
   return fn;
 }
 
+static bool isLambda(const NamedDecl *ND) {
+  const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(ND);
+  if (!Record)
+    return false;
+
+  return Record->isLambda();
+}
+
+/// MicrosoftMangleContextImpl - Overrides the default MangleContext for the
+/// Microsoft Visual C++ ABI.
+class MicrosoftMangleContextImpl : public MicrosoftMangleContext {
+  typedef std::pair<const DeclContext *, IdentifierInfo *> DiscriminatorKeyTy;
+  llvm::DenseMap<DiscriminatorKeyTy, unsigned> Discriminator;
+  llvm::DenseMap<const NamedDecl *, unsigned> Uniquifier;
+  llvm::DenseMap<const CXXRecordDecl *, unsigned> LambdaIds;
+
+public:
+  MicrosoftMangleContextImpl(ASTContext &Context, DiagnosticsEngine &Diags)
+      : MicrosoftMangleContext(Context, Diags) {}
+  bool shouldMangleCXXName(const NamedDecl *D) override;
+  bool shouldMangleStringLiteral(const StringLiteral *SL) override;
+  void mangleCXXName(const NamedDecl *D, raw_ostream &Out) override;
+  void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
+                                raw_ostream &) override;
+  void mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk,
+                   raw_ostream &) override;
+  void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
+                          const ThisAdjustment &ThisAdjustment,
+                          raw_ostream &) override;
+  void mangleCXXVFTable(const CXXRecordDecl *Derived,
+                        ArrayRef<const CXXRecordDecl *> BasePath,
+                        raw_ostream &Out) override;
+  void mangleCXXVBTable(const CXXRecordDecl *Derived,
+                        ArrayRef<const CXXRecordDecl *> BasePath,
+                        raw_ostream &Out) override;
+  void mangleCXXRTTI(QualType T, raw_ostream &Out) override;
+  void mangleCXXRTTIName(QualType T, raw_ostream &Out) override;
+  void mangleCXXRTTIBaseClassDescriptor(const CXXRecordDecl *Derived,
+                                        uint32_t NVOffset, int32_t VBPtrOffset,
+                                        uint32_t VBTableOffset, uint32_t Flags,
+                                        raw_ostream &Out) override;
+  void mangleCXXRTTIBaseClassArray(const CXXRecordDecl *Derived,
+                                   raw_ostream &Out) override;
+  void mangleCXXRTTIClassHierarchyDescriptor(const CXXRecordDecl *Derived,
+                                             raw_ostream &Out) override;
+  void
+  mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *Derived,
+                                     ArrayRef<const CXXRecordDecl *> BasePath,
+                                     raw_ostream &Out) override;
+  void mangleTypeName(QualType T, raw_ostream &) override;
+  void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
+                     raw_ostream &) override;
+  void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
+                     raw_ostream &) override;
+  void mangleReferenceTemporary(const VarDecl *, unsigned ManglingNumber,
+                                raw_ostream &) override;
+  void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &Out) override;
+  void mangleDynamicInitializer(const VarDecl *D, raw_ostream &Out) override;
+  void mangleDynamicAtExitDestructor(const VarDecl *D,
+                                     raw_ostream &Out) override;
+  void mangleStringLiteral(const StringLiteral *SL, raw_ostream &Out) override;
+  bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc) {
+    // Lambda closure types are already numbered.
+    if (isLambda(ND))
+      return false;
+
+    const DeclContext *DC = getEffectiveDeclContext(ND);
+    if (!DC->isFunctionOrMethod())
+      return false;
+
+    // Use the canonical number for externally visible decls.
+    if (ND->isExternallyVisible()) {
+      disc = getASTContext().getManglingNumber(ND);
+      return true;
+    }
+
+    // Anonymous tags are already numbered.
+    if (const TagDecl *Tag = dyn_cast<TagDecl>(ND)) {
+      if (Tag->getName().empty() && !Tag->getTypedefNameForAnonDecl())
+        return false;
+    }
+
+    // Make up a reasonable number for internal decls.
+    unsigned &discriminator = Uniquifier[ND];
+    if (!discriminator)
+      discriminator = ++Discriminator[std::make_pair(DC, ND->getIdentifier())];
+    disc = discriminator;
+    return true;
+  }
+
+  unsigned getLambdaId(const CXXRecordDecl *RD) {
+    assert(RD->isLambda() && "RD must be a lambda!");
+    assert(!RD->isExternallyVisible() && "RD must not be visible!");
+    assert(RD->getLambdaManglingNumber() == 0 &&
+           "RD must not have a mangling number!");
+    std::pair<llvm::DenseMap<const CXXRecordDecl *, unsigned>::iterator, bool>
+        Result = LambdaIds.insert(std::make_pair(RD, LambdaIds.size()));
+    return Result.first->second;
+  }
+
+private:
+  void mangleInitFiniStub(const VarDecl *D, raw_ostream &Out, char CharCode);
+};
+
 /// MicrosoftCXXNameMangler - Manage the mangling of a single name for the
 /// Microsoft Visual C++ ABI.
 class MicrosoftCXXNameMangler {
-  MangleContext &Context;
+  MicrosoftMangleContextImpl &Context;
   raw_ostream &Out;
 
   /// The "structor" is the top-level declaration being mangled, if
@@ -85,9 +193,8 @@
 
   typedef llvm::StringMap<unsigned> BackRefMap;
   BackRefMap NameBackReferences;
-  bool UseNameBackReferences;
 
-  typedef llvm::DenseMap<void*, unsigned> ArgBackRefMap;
+  typedef llvm::DenseMap<void *, unsigned> ArgBackRefMap;
   ArgBackRefMap TypeBackReferences;
 
   ASTContext &getASTContext() const { return Context.getASTContext(); }
@@ -99,53 +206,55 @@
 public:
   enum QualifierMangleMode { QMM_Drop, QMM_Mangle, QMM_Escape, QMM_Result };
 
-  MicrosoftCXXNameMangler(MangleContext &C, raw_ostream &Out_)
-    : Context(C), Out(Out_),
-      Structor(0), StructorType(-1),
-      UseNameBackReferences(true),
-      PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(0) ==
-                       64) { }
+  MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_)
+      : Context(C), Out(Out_), Structor(nullptr), StructorType(-1),
+        PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(0) ==
+                         64) {}
 
-  MicrosoftCXXNameMangler(MangleContext &C, raw_ostream &Out_,
+  MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_,
                           const CXXDestructorDecl *D, CXXDtorType Type)
-    : Context(C), Out(Out_),
-      Structor(getStructor(D)), StructorType(Type),
-      UseNameBackReferences(true),
-      PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(0) ==
-                       64) { }
+      : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type),
+        PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(0) ==
+                         64) {}
 
   raw_ostream &getStream() const { return Out; }
 
   void mangle(const NamedDecl *D, StringRef Prefix = "\01?");
   void mangleName(const NamedDecl *ND);
-  void mangleDeclaration(const NamedDecl *ND);
   void mangleFunctionEncoding(const FunctionDecl *FD);
   void mangleVariableEncoding(const VarDecl *VD);
-  void mangleNumber(uint32_t Number);
-  void mangleNumber(const llvm::APSInt &Value);
+  void mangleMemberDataPointer(const CXXRecordDecl *RD, const ValueDecl *VD);
+  void mangleMemberFunctionPointer(const CXXRecordDecl *RD,
+                                   const CXXMethodDecl *MD);
+  void mangleVirtualMemPtrThunk(
+      const CXXMethodDecl *MD,
+      const MicrosoftVTableContext::MethodVFTableLocation &ML);
+  void mangleNumber(int64_t Number);
   void mangleType(QualType T, SourceRange Range,
                   QualifierMangleMode QMM = QMM_Mangle);
-  void mangleFunctionType(const FunctionType *T, const FunctionDecl *D = 0,
+  void mangleFunctionType(const FunctionType *T,
+                          const FunctionDecl *D = nullptr,
                           bool ForceInstMethod = false);
-  void manglePostfix(const DeclContext *DC, bool NoFunction = false);
+  void mangleNestedName(const NamedDecl *ND);
 
 private:
-  void disableBackReferences() { UseNameBackReferences = false; }
   void mangleUnqualifiedName(const NamedDecl *ND) {
     mangleUnqualifiedName(ND, ND->getDeclName());
   }
   void mangleUnqualifiedName(const NamedDecl *ND, DeclarationName Name);
-  void mangleSourceName(const IdentifierInfo *II);
+  void mangleSourceName(StringRef Name);
   void mangleOperatorName(OverloadedOperatorKind OO, SourceLocation Loc);
   void mangleCXXDtorType(CXXDtorType T);
   void mangleQualifiers(Qualifiers Quals, bool IsMember);
-  void manglePointerQualifiers(Qualifiers Quals);
+  void mangleRefQualifier(RefQualifierKind RefQualifier);
+  void manglePointerCVQualifiers(Qualifiers Quals);
+  void manglePointerExtQualifiers(Qualifiers Quals, const Type *PointeeType);
 
   void mangleUnscopedTemplateName(const TemplateDecl *ND);
-  void mangleTemplateInstantiationName(const TemplateDecl *TD,
-                                      const TemplateArgumentList &TemplateArgs);
+  void
+  mangleTemplateInstantiationName(const TemplateDecl *TD,
+                                  const TemplateArgumentList &TemplateArgs);
   void mangleObjCMethodName(const ObjCMethodDecl *MD);
-  void mangleLocalName(const FunctionDecl *FD);
 
   void mangleArgumentType(QualType T, SourceRange Range);
 
@@ -158,7 +267,7 @@
 #undef ABSTRACT_TYPE
 #undef NON_CANONICAL_TYPE
 #undef TYPE
-  
+
   void mangleType(const TagDecl *TD);
   void mangleDecayedArrayType(const ArrayType *T);
   void mangleArrayType(const ArrayType *T);
@@ -172,45 +281,6 @@
                           const TemplateArgumentList &TemplateArgs);
   void mangleTemplateArg(const TemplateDecl *TD, const TemplateArgument &TA);
 };
-
-/// MicrosoftMangleContextImpl - Overrides the default MangleContext for the
-/// Microsoft Visual C++ ABI.
-class MicrosoftMangleContextImpl : public MicrosoftMangleContext {
-public:
-  MicrosoftMangleContextImpl(ASTContext &Context, DiagnosticsEngine &Diags)
-      : MicrosoftMangleContext(Context, Diags) {}
-  virtual bool shouldMangleCXXName(const NamedDecl *D);
-  virtual void mangleCXXName(const NamedDecl *D, raw_ostream &Out);
-  virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
-                                        int OffsetInVFTable, raw_ostream &);
-  virtual void mangleThunk(const CXXMethodDecl *MD,
-                           const ThunkInfo &Thunk,
-                           raw_ostream &);
-  virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
-                                  const ThisAdjustment &ThisAdjustment,
-                                  raw_ostream &);
-  virtual void mangleCXXVFTable(const CXXRecordDecl *Derived,
-                                ArrayRef<const CXXRecordDecl *> BasePath,
-                                raw_ostream &Out);
-  virtual void mangleCXXVBTable(const CXXRecordDecl *Derived,
-                                ArrayRef<const CXXRecordDecl *> BasePath,
-                                raw_ostream &Out);
-  virtual void mangleCXXRTTI(QualType T, raw_ostream &);
-  virtual void mangleCXXRTTIName(QualType T, raw_ostream &);
-  virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
-                             raw_ostream &);
-  virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
-                             raw_ostream &);
-  virtual void mangleReferenceTemporary(const VarDecl *, raw_ostream &);
-  virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &Out);
-  virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &Out);
-  virtual void mangleDynamicAtExitDestructor(const VarDecl *D,
-                                             raw_ostream &Out);
-
-private:
-  void mangleInitFiniStub(const VarDecl *D, raw_ostream &Out, char CharCode);
-};
-
 }
 
 bool MicrosoftMangleContextImpl::shouldMangleCXXName(const NamedDecl *D) {
@@ -266,8 +336,14 @@
   return true;
 }
 
-void MicrosoftCXXNameMangler::mangle(const NamedDecl *D,
-                                     StringRef Prefix) {
+bool
+MicrosoftMangleContextImpl::shouldMangleStringLiteral(const StringLiteral *SL) {
+  return SL->isAscii() || SL->isWide();
+  // TODO: This needs to be updated when MSVC gains support for Unicode
+  // literals.
+}
+
+void MicrosoftCXXNameMangler::mangle(const NamedDecl *D, StringRef Prefix) {
   // MSVC doesn't mangle C++ names the same way it mangles extern "C" names.
   // Therefore it's really important that we don't decorate the
   // name with leading underscores or leading/trailing at signs. So, by
@@ -285,10 +361,9 @@
     // TODO: Fields? Can MSVC even mangle them?
     // Issue a diagnostic for now.
     DiagnosticsEngine &Diags = Context.getDiags();
-    unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
-      "cannot mangle this declaration yet");
-    Diags.Report(D->getLocation(), DiagID)
-      << D->getSourceRange();
+    unsigned DiagID = Diags.getCustomDiagID(
+        DiagnosticsEngine::Error, "cannot mangle this declaration yet");
+    Diags.Report(D->getLocation(), DiagID) << D->getSourceRange();
   }
 }
 
@@ -323,7 +398,7 @@
   //                 ::= 2  # public static member
   //                 ::= 3  # global
   //                 ::= 4  # static local
-  
+
   // The first character in the encoding (after the name) is the storage class.
   if (VD->isStaticDataMember()) {
     // If it's a static member, it also encodes the access level.
@@ -343,13 +418,13 @@
   //                 ::= <type> <pointee-cvr-qualifiers> # pointers, references
   // Pointers and references are odd. The type of 'int * const foo;' gets
   // mangled as 'QAHA' instead of 'PAHB', for example.
-  TypeLoc TL = VD->getTypeSourceInfo()->getTypeLoc();
-  QualType Ty = TL.getType();
+  SourceRange SR = VD->getSourceRange();
+  QualType Ty = VD->getType();
   if (Ty->isPointerType() || Ty->isReferenceType() ||
       Ty->isMemberPointerType()) {
-    mangleType(Ty, TL.getSourceRange(), QMM_Drop);
-    if (PointersAre64Bit)
-      Out << 'E';
+    mangleType(Ty, SR, QMM_Drop);
+    manglePointerExtQualifiers(
+        Ty.getDesugaredType(getASTContext()).getLocalQualifiers(), nullptr);
     if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>()) {
       mangleQualifiers(MPT->getPointeeType().getQualifiers(), true);
       // Member pointers are suffixed with a back reference to the member
@@ -365,64 +440,169 @@
     else
       mangleQualifiers(Ty.getQualifiers(), false);
   } else {
-    mangleType(Ty, TL.getSourceRange(), QMM_Drop);
+    mangleType(Ty, SR, QMM_Drop);
     mangleQualifiers(Ty.getLocalQualifiers(), false);
   }
 }
 
+void MicrosoftCXXNameMangler::mangleMemberDataPointer(const CXXRecordDecl *RD,
+                                                      const ValueDecl *VD) {
+  // <member-data-pointer> ::= <integer-literal>
+  //                       ::= $F <number> <number>
+  //                       ::= $G <number> <number> <number>
+
+  int64_t FieldOffset;
+  int64_t VBTableOffset;
+  MSInheritanceAttr::Spelling IM = RD->getMSInheritanceModel();
+  if (VD) {
+    FieldOffset = getASTContext().getFieldOffset(VD);
+    assert(FieldOffset % getASTContext().getCharWidth() == 0 &&
+           "cannot take address of bitfield");
+    FieldOffset /= getASTContext().getCharWidth();
+
+    VBTableOffset = 0;
+  } else {
+    FieldOffset = RD->nullFieldOffsetIsZero() ? 0 : -1;
+
+    VBTableOffset = -1;
+  }
+
+  char Code = '\0';
+  switch (IM) {
+  case MSInheritanceAttr::Keyword_single_inheritance:      Code = '0'; break;
+  case MSInheritanceAttr::Keyword_multiple_inheritance:    Code = '0'; break;
+  case MSInheritanceAttr::Keyword_virtual_inheritance:     Code = 'F'; break;
+  case MSInheritanceAttr::Keyword_unspecified_inheritance: Code = 'G'; break;
+  }
+
+  Out << '$' << Code;
+
+  mangleNumber(FieldOffset);
+
+  // The C++ standard doesn't allow base-to-derived member pointer conversions
+  // in template parameter contexts, so the vbptr offset of data member pointers
+  // is always zero.
+  if (MSInheritanceAttr::hasVBPtrOffsetField(IM))
+    mangleNumber(0);
+  if (MSInheritanceAttr::hasVBTableOffsetField(IM))
+    mangleNumber(VBTableOffset);
+}
+
+void
+MicrosoftCXXNameMangler::mangleMemberFunctionPointer(const CXXRecordDecl *RD,
+                                                     const CXXMethodDecl *MD) {
+  // <member-function-pointer> ::= $1? <name>
+  //                           ::= $H? <name> <number>
+  //                           ::= $I? <name> <number> <number>
+  //                           ::= $J? <name> <number> <number> <number>
+
+  MSInheritanceAttr::Spelling IM = RD->getMSInheritanceModel();
+
+  char Code = '\0';
+  switch (IM) {
+  case MSInheritanceAttr::Keyword_single_inheritance:      Code = '1'; break;
+  case MSInheritanceAttr::Keyword_multiple_inheritance:    Code = 'H'; break;
+  case MSInheritanceAttr::Keyword_virtual_inheritance:     Code = 'I'; break;
+  case MSInheritanceAttr::Keyword_unspecified_inheritance: Code = 'J'; break;
+  }
+
+  // If non-virtual, mangle the name.  If virtual, mangle as a virtual memptr
+  // thunk.
+  uint64_t NVOffset = 0;
+  uint64_t VBTableOffset = 0;
+  uint64_t VBPtrOffset = 0;
+  if (MD) {
+    Out << '$' << Code << '?';
+    if (MD->isVirtual()) {
+      MicrosoftVTableContext *VTContext =
+          cast<MicrosoftVTableContext>(getASTContext().getVTableContext());
+      const MicrosoftVTableContext::MethodVFTableLocation &ML =
+          VTContext->getMethodVFTableLocation(GlobalDecl(MD));
+      mangleVirtualMemPtrThunk(MD, ML);
+      NVOffset = ML.VFPtrOffset.getQuantity();
+      VBTableOffset = ML.VBTableIndex * 4;
+      if (ML.VBase) {
+        const ASTRecordLayout &Layout = getASTContext().getASTRecordLayout(RD);
+        VBPtrOffset = Layout.getVBPtrOffset().getQuantity();
+      }
+    } else {
+      mangleName(MD);
+      mangleFunctionEncoding(MD);
+    }
+  } else {
+    // Null single inheritance member functions are encoded as a simple nullptr.
+    if (IM == MSInheritanceAttr::Keyword_single_inheritance) {
+      Out << "$0A@";
+      return;
+    }
+    if (IM == MSInheritanceAttr::Keyword_unspecified_inheritance)
+      VBTableOffset = -1;
+    Out << '$' << Code;
+  }
+
+  if (MSInheritanceAttr::hasNVOffsetField(/*IsMemberFunction=*/true, IM))
+    mangleNumber(NVOffset);
+  if (MSInheritanceAttr::hasVBPtrOffsetField(IM))
+    mangleNumber(VBPtrOffset);
+  if (MSInheritanceAttr::hasVBTableOffsetField(IM))
+    mangleNumber(VBTableOffset);
+}
+
+void MicrosoftCXXNameMangler::mangleVirtualMemPtrThunk(
+    const CXXMethodDecl *MD,
+    const MicrosoftVTableContext::MethodVFTableLocation &ML) {
+  // Get the vftable offset.
+  CharUnits PointerWidth = getASTContext().toCharUnitsFromBits(
+      getASTContext().getTargetInfo().getPointerWidth(0));
+  uint64_t OffsetInVFTable = ML.Index * PointerWidth.getQuantity();
+
+  Out << "?_9";
+  mangleName(MD->getParent());
+  Out << "$B";
+  mangleNumber(OffsetInVFTable);
+  Out << 'A';
+  Out << (PointersAre64Bit ? 'A' : 'E');
+}
+
 void MicrosoftCXXNameMangler::mangleName(const NamedDecl *ND) {
   // <name> ::= <unscoped-name> {[<named-scope>]+ | [<nested-name>]}? @
-  const DeclContext *DC = ND->getDeclContext();
 
   // Always start with the unqualified name.
-  mangleUnqualifiedName(ND);    
+  mangleUnqualifiedName(ND);
 
-  // If this is an extern variable declared locally, the relevant DeclContext
-  // is that of the containing namespace, or the translation unit.
-  if (isa<FunctionDecl>(DC) && ND->hasLinkage())
-    while (!DC->isNamespace() && !DC->isTranslationUnit())
-      DC = DC->getParent();
-
-  manglePostfix(DC);
+  mangleNestedName(ND);
 
   // Terminate the whole name with an '@'.
   Out << '@';
 }
 
-void MicrosoftCXXNameMangler::mangleNumber(uint32_t Number) {
-  llvm::APSInt APSNumber(/*BitWidth=*/32, /*isUnsigned=*/true);
-  APSNumber = Number;
-  mangleNumber(APSNumber);
-}
+void MicrosoftCXXNameMangler::mangleNumber(int64_t Number) {
+  // <non-negative integer> ::= A@              # when Number == 0
+  //                        ::= <decimal digit> # when 1 <= Number <= 10
+  //                        ::= <hex digit>+ @  # when Number >= 10
+  //
+  // <number>               ::= [?] <non-negative integer>
 
-void MicrosoftCXXNameMangler::mangleNumber(const llvm::APSInt &Value) {
-  // <number> ::= [?] <decimal digit> # 1 <= Number <= 10
-  //          ::= [?] <hex digit>+ @ # 0 or > 9; A = 0, B = 1, etc...
-  //          ::= [?] @ # 0 (alternate mangling, not emitted by VC)
-  if (Value.isSigned() && Value.isNegative()) {
+  uint64_t Value = static_cast<uint64_t>(Number);
+  if (Number < 0) {
+    Value = -Value;
     Out << '?';
-    mangleNumber(llvm::APSInt(Value.abs()));
-    return;
   }
-  llvm::APSInt Temp(Value);
-  // There's a special shorter mangling for 0, but Microsoft
-  // chose not to use it. Instead, 0 gets mangled as "A@". Oh well...
-  if (Value.uge(1) && Value.ule(10)) {
-    --Temp;
-    Temp.print(Out, false);
-  } else {
-    // We have to build up the encoding in reverse order, so it will come
-    // out right when we write it out.
-    char Encoding[64];
-    char *EndPtr = Encoding+sizeof(Encoding);
-    char *CurPtr = EndPtr;
-    llvm::APSInt NibbleMask(Value.getBitWidth(), Value.isUnsigned());
-    NibbleMask = 0xf;
-    do {
-      *--CurPtr = 'A' + Temp.And(NibbleMask).getLimitedValue(0xf);
-      Temp = Temp.lshr(4);
-    } while (Temp != 0);
-    Out.write(CurPtr, EndPtr-CurPtr);
+
+  if (Value == 0)
+    Out << "A@";
+  else if (Value >= 1 && Value <= 10)
+    Out << (Value - 1);
+  else {
+    // Numbers that are not encoded as decimal digits are represented as nibbles
+    // in the range of ASCII characters 'A' to 'P'.
+    // The number 0x123450 would be encoded as 'BCDEFA'
+    char EncodedNumberBuffer[sizeof(uint64_t) * 2];
+    MutableArrayRef<char> BufferRef(EncodedNumberBuffer);
+    MutableArrayRef<char>::reverse_iterator I = BufferRef.rbegin();
+    for (; Value != 0; Value >>= 4)
+      *I++ = 'A' + (Value & 0xf);
+    Out.write(I.base(), I - BufferRef.rbegin());
     Out << '@';
   }
 }
@@ -430,7 +610,7 @@
 static const TemplateDecl *
 isTemplate(const NamedDecl *ND, const TemplateArgumentList *&TemplateArgs) {
   // Check if we have a function template.
-  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)){
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
     if (const TemplateDecl *TD = FD->getPrimaryTemplate()) {
       TemplateArgs = FD->getTemplateSpecializationArgs();
       return TD;
@@ -439,24 +619,30 @@
 
   // Check if we have a class template.
   if (const ClassTemplateSpecializationDecl *Spec =
-        dyn_cast<ClassTemplateSpecializationDecl>(ND)) {
+          dyn_cast<ClassTemplateSpecializationDecl>(ND)) {
     TemplateArgs = &Spec->getTemplateArgs();
     return Spec->getSpecializedTemplate();
   }
 
-  return 0;
+  // Check if we have a variable template.
+  if (const VarTemplateSpecializationDecl *Spec =
+          dyn_cast<VarTemplateSpecializationDecl>(ND)) {
+    TemplateArgs = &Spec->getTemplateArgs();
+    return Spec->getSpecializedTemplate();
+  }
+
+  return nullptr;
 }
 
-void
-MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
-                                               DeclarationName Name) {
+void MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
+                                                    DeclarationName Name) {
   //  <unqualified-name> ::= <operator-name>
   //                     ::= <ctor-dtor-name>
   //                     ::= <source-name>
   //                     ::= <template-name>
 
   // Check if we have a template.
-  const TemplateArgumentList *TemplateArgs = 0;
+  const TemplateArgumentList *TemplateArgs = nullptr;
   if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) {
     // Function templates aren't considered for name back referencing.  This
     // makes sense since function templates aren't likely to occur multiple
@@ -464,10 +650,10 @@
     // FIXME: Test alias template mangling with MSVC 2013.
     if (!isa<ClassTemplateDecl>(TD)) {
       mangleTemplateInstantiationName(TD, *TemplateArgs);
+      Out << '@';
       return;
     }
 
-    // We have a class template.
     // Here comes the tricky thing: if we need to mangle something like
     //   void foo(A::X<Y>, B::X<Y>),
     // the X<Y> part is aliased. However, if you need to mangle
@@ -479,50 +665,51 @@
     //   type [ -> template-parameters]
     //      \-> namespace[s]
     // What we do is we create a new mangler, mangle the same type (without
-    // a namespace suffix) using the extra mangler with back references
-    // disabled (to avoid infinite recursion) and then use the mangled type
-    // name as a key to check the mangling of different types for aliasing.
+    // a namespace suffix) to a string using the extra mangler and then use 
+    // the mangled type name as a key to check the mangling of different types
+    // for aliasing.
 
-    std::string BackReferenceKey;
-    BackRefMap::iterator Found;
-    if (UseNameBackReferences) {
-      llvm::raw_string_ostream Stream(BackReferenceKey);
-      MicrosoftCXXNameMangler Extra(Context, Stream);
-      Extra.disableBackReferences();
-      Extra.mangleUnqualifiedName(ND, Name);
-      Stream.flush();
+    llvm::SmallString<64> TemplateMangling;
+    llvm::raw_svector_ostream Stream(TemplateMangling);
+    MicrosoftCXXNameMangler Extra(Context, Stream);
+    Extra.mangleTemplateInstantiationName(TD, *TemplateArgs);
+    Stream.flush();
 
-      Found = NameBackReferences.find(BackReferenceKey);
-    }
-    if (!UseNameBackReferences || Found == NameBackReferences.end()) {
-      mangleTemplateInstantiationName(TD, *TemplateArgs);
-      if (UseNameBackReferences && NameBackReferences.size() < 10) {
-        size_t Size = NameBackReferences.size();
-        NameBackReferences[BackReferenceKey] = Size;
-      }
-    } else {
-      Out << Found->second;
-    }
+    mangleSourceName(TemplateMangling);
     return;
   }
 
   switch (Name.getNameKind()) {
     case DeclarationName::Identifier: {
       if (const IdentifierInfo *II = Name.getAsIdentifierInfo()) {
-        mangleSourceName(II);
+        mangleSourceName(II->getName());
         break;
       }
-      
+
       // Otherwise, an anonymous entity.  We must have a declaration.
       assert(ND && "mangling empty name without declaration");
-      
+
       if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) {
         if (NS->isAnonymousNamespace()) {
           Out << "?A@";
           break;
         }
       }
-      
+
+      if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
+        // We must have an anonymous union or struct declaration.
+        const CXXRecordDecl *RD = VD->getType()->getAsCXXRecordDecl();
+        assert(RD && "expected variable decl to have a record type");
+        // Anonymous types with no tag or typedef get the name of their
+        // declarator mangled in.  If they have no declarator, number them with
+        // a $S prefix.
+        llvm::SmallString<64> Name("$S");
+        // Get a unique id for the anonymous struct.
+        Name += llvm::utostr(Context.getAnonymousStructId(RD) + 1);
+        mangleSourceName(Name.str());
+        break;
+      }
+
       // We must have an anonymous struct.
       const TagDecl *TD = cast<TagDecl>(ND);
       if (const TypedefNameDecl *D = TD->getTypedefNameForAnonDecl()) {
@@ -530,27 +717,47 @@
                "Typedef should not be in another decl context!");
         assert(D->getDeclName().getAsIdentifierInfo() &&
                "Typedef was not named!");
-        mangleSourceName(D->getDeclName().getAsIdentifierInfo());
+        mangleSourceName(D->getDeclName().getAsIdentifierInfo()->getName());
         break;
       }
 
-      if (TD->hasDeclaratorForAnonDecl())
+      if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(TD)) {
+        if (Record->isLambda()) {
+          llvm::SmallString<10> Name("<lambda_");
+          unsigned LambdaId;
+          if (Record->getLambdaManglingNumber())
+            LambdaId = Record->getLambdaManglingNumber();
+          else
+            LambdaId = Context.getLambdaId(Record);
+
+          Name += llvm::utostr(LambdaId);
+          Name += ">";
+
+          mangleSourceName(Name);
+          break;
+        }
+      }
+
+      llvm::SmallString<64> Name("<unnamed-type-");
+      if (TD->hasDeclaratorForAnonDecl()) {
         // Anonymous types with no tag or typedef get the name of their
-        // declarator mangled in.
-        Out << "<unnamed-type-" << TD->getDeclaratorForAnonDecl()->getName()
-            << ">@";
-      else
-        // Anonymous types with no tag, no typedef, or declarator get
-        // '<unnamed-tag>@'.
-        Out << "<unnamed-tag>@";
+        // declarator mangled in if they have one.
+        Name += TD->getDeclaratorForAnonDecl()->getName();
+      } else {
+        // Otherwise, number the types using a $S prefix.
+        Name += "$S";
+        Name += llvm::utostr(Context.getAnonymousStructId(TD));
+      }
+      Name += ">";
+      mangleSourceName(Name.str());
       break;
     }
-      
+
     case DeclarationName::ObjCZeroArgSelector:
     case DeclarationName::ObjCOneArgSelector:
     case DeclarationName::ObjCMultiArgSelector:
       llvm_unreachable("Can't mangle Objective-C selector names here!");
-      
+
     case DeclarationName::CXXConstructorName:
       if (ND == Structor) {
         assert(StructorType == Ctor_Complete &&
@@ -558,7 +765,7 @@
       }
       Out << "?0";
       break;
-      
+
     case DeclarationName::CXXDestructorName:
       if (ND == Structor)
         // If the named decl is the C++ destructor we're mangling,
@@ -569,70 +776,69 @@
         // class with a destructor is declared within a destructor.
         mangleCXXDtorType(Dtor_Base);
       break;
-      
+
     case DeclarationName::CXXConversionFunctionName:
       // <operator-name> ::= ?B # (cast)
       // The target type is encoded as the return type.
       Out << "?B";
       break;
-      
+
     case DeclarationName::CXXOperatorName:
       mangleOperatorName(Name.getCXXOverloadedOperator(), ND->getLocation());
       break;
-      
+
     case DeclarationName::CXXLiteralOperatorName: {
-      // FIXME: Was this added in VS2010? Does MS even know how to mangle this?
-      DiagnosticsEngine Diags = Context.getDiags();
-      unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
-        "cannot mangle this literal operator yet");
-      Diags.Report(ND->getLocation(), DiagID);
+      Out << "?__K";
+      mangleSourceName(Name.getCXXLiteralIdentifier()->getName());
       break;
     }
-      
+
     case DeclarationName::CXXUsingDirective:
       llvm_unreachable("Can't mangle a using directive name!");
   }
 }
 
-void MicrosoftCXXNameMangler::manglePostfix(const DeclContext *DC,
-                                            bool NoFunction) {
+void MicrosoftCXXNameMangler::mangleNestedName(const NamedDecl *ND) {
   // <postfix> ::= <unqualified-name> [<postfix>]
   //           ::= <substitution> [<postfix>]
+  if (isLambda(ND))
+    return;
 
-  if (!DC) return;
+  const DeclContext *DC = ND->getDeclContext();
 
-  while (isa<LinkageSpecDecl>(DC))
+  while (!DC->isTranslationUnit()) {
+    if (isa<TagDecl>(ND) || isa<VarDecl>(ND)) {
+      unsigned Disc;
+      if (Context.getNextDiscriminator(ND, Disc)) {
+        Out << '?';
+        mangleNumber(Disc);
+        Out << '?';
+      }
+    }
+
+    if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {
+      DiagnosticsEngine &Diags = Context.getDiags();
+      unsigned DiagID =
+          Diags.getCustomDiagID(DiagnosticsEngine::Error,
+                                "cannot mangle a local inside this block yet");
+      Diags.Report(BD->getLocation(), DiagID);
+
+      // FIXME: This is completely, utterly, wrong; see ItaniumMangle
+      // for how this should be done.
+      Out << "__block_invoke" << Context.getBlockId(BD, false);
+      Out << '@';
+      continue;
+    } else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC)) {
+      mangleObjCMethodName(Method);
+    } else if (isa<NamedDecl>(DC)) {
+      ND = cast<NamedDecl>(DC);
+      if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
+        mangle(FD, "?");
+        break;
+      } else
+        mangleUnqualifiedName(ND);
+    }
     DC = DC->getParent();
-
-  if (DC->isTranslationUnit())
-    return;
-
-  if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {
-    DiagnosticsEngine Diags = Context.getDiags();
-    unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
-      "cannot mangle a local inside this block yet");
-    Diags.Report(BD->getLocation(), DiagID);
-
-    // FIXME: This is completely, utterly, wrong; see ItaniumMangle
-    // for how this should be done.
-    Out << "__block_invoke" << Context.getBlockId(BD, false);
-    Out << '@';
-    return manglePostfix(DC->getParent(), NoFunction);
-  } else if (isa<CapturedDecl>(DC)) {
-    // Skip CapturedDecl context.
-    manglePostfix(DC->getParent(), NoFunction);
-    return;
-  }
-
-  if (NoFunction && (isa<FunctionDecl>(DC) || isa<ObjCMethodDecl>(DC)))
-    return;
-  else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC))
-    mangleObjCMethodName(Method);
-  else if (const FunctionDecl *Func = dyn_cast<FunctionDecl>(DC))
-    mangleLocalName(Func);
-  else {
-    mangleUnqualifiedName(cast<NamedDecl>(DC));
-    manglePostfix(DC->getParent(), NoFunction);
   }
 }
 
@@ -771,7 +977,7 @@
   case OO_Array_New: Out << "?_U"; break;
   // <operator-name> ::= ?_V # delete[]
   case OO_Array_Delete: Out << "?_V"; break;
-    
+
   case OO_Conditional: {
     DiagnosticsEngine &Diags = Context.getDiags();
     unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
@@ -779,25 +985,29 @@
     Diags.Report(Loc, DiagID);
     break;
   }
-    
+
   case OO_None:
   case NUM_OVERLOADED_OPERATORS:
     llvm_unreachable("Not an overloaded operator");
   }
 }
 
-void MicrosoftCXXNameMangler::mangleSourceName(const IdentifierInfo *II) {
+void MicrosoftCXXNameMangler::mangleSourceName(StringRef Name) {
   // <source name> ::= <identifier> @
-  std::string key = II->getNameStart();
   BackRefMap::iterator Found;
-  if (UseNameBackReferences)
-    Found = NameBackReferences.find(key);
-  if (!UseNameBackReferences || Found == NameBackReferences.end()) {
-    Out << II->getName() << '@';
-    if (UseNameBackReferences && NameBackReferences.size() < 10) {
-      size_t Size = NameBackReferences.size();
-      NameBackReferences[key] = Size;
-    }
+  if (NameBackReferences.size() < 10) {
+    size_t Size = NameBackReferences.size();
+    bool Inserted;
+    std::tie(Found, Inserted) =
+        NameBackReferences.insert(std::make_pair(Name, Size));
+    if (Inserted)
+      Found = NameBackReferences.end();
+  } else {
+    Found = NameBackReferences.find(Name);
+  }
+
+  if (Found == NameBackReferences.end()) {
+    Out << Name << '@';
   } else {
     Out << Found->second;
   }
@@ -807,47 +1017,8 @@
   Context.mangleObjCMethodName(MD, Out);
 }
 
-// Find out how many function decls live above this one and return an integer
-// suitable for use as the number in a numbered anonymous scope.
-// TODO: Memoize.
-static unsigned getLocalNestingLevel(const FunctionDecl *FD) {
-  const DeclContext *DC = FD->getParent();
-  int level = 1;
-
-  while (DC && !DC->isTranslationUnit()) {
-    if (isa<FunctionDecl>(DC) || isa<ObjCMethodDecl>(DC)) level++;
-    DC = DC->getParent();
-  }
-
-  return 2*level;
-}
-
-void MicrosoftCXXNameMangler::mangleLocalName(const FunctionDecl *FD) {
-  // <nested-name> ::= <numbered-anonymous-scope> ? <mangled-name>
-  // <numbered-anonymous-scope> ::= ? <number>
-  // Even though the name is rendered in reverse order (e.g.
-  // A::B::C is rendered as C@B@A), VC numbers the scopes from outermost to
-  // innermost. So a method bar in class C local to function foo gets mangled
-  // as something like:
-  // ?bar@C@?1??foo@@YAXXZ@QAEXXZ
-  // This is more apparent when you have a type nested inside a method of a
-  // type nested inside a function. A method baz in class D local to method
-  // bar of class C local to function foo gets mangled as:
-  // ?baz@D@?3??bar@C@?1??foo@@YAXXZ@QAEXXZ@QAEXXZ
-  // This scheme is general enough to support GCC-style nested
-  // functions. You could have a method baz of class C inside a function bar
-  // inside a function foo, like so:
-  // ?baz@C@?3??bar@?1??foo@@YAXXZ@YAXXZ@QAEXXZ
-  unsigned NestLevel = getLocalNestingLevel(FD);
-  Out << '?';
-  mangleNumber(NestLevel);
-  Out << '?';
-  mangle(FD, "?");
-}
-
 void MicrosoftCXXNameMangler::mangleTemplateInstantiationName(
-                                                         const TemplateDecl *TD,
-                     const TemplateArgumentList &TemplateArgs) {
+    const TemplateDecl *TD, const TemplateArgumentList &TemplateArgs) {
   // <template-name> ::= <unscoped-template-name> <template-args>
   //                 ::= <substitution>
   // Always start with the unqualified name.
@@ -873,20 +1044,18 @@
   mangleUnqualifiedName(TD);
 }
 
-void
-MicrosoftCXXNameMangler::mangleIntegerLiteral(const llvm::APSInt &Value,
-                                              bool IsBoolean) {
+void MicrosoftCXXNameMangler::mangleIntegerLiteral(const llvm::APSInt &Value,
+                                                   bool IsBoolean) {
   // <integer-literal> ::= $0 <number>
   Out << "$0";
   // Make sure booleans are encoded as 0/1.
   if (IsBoolean && Value.getBoolValue())
     mangleNumber(1);
   else
-    mangleNumber(Value);
+    mangleNumber(Value.getSExtValue());
 }
 
-void
-MicrosoftCXXNameMangler::mangleExpression(const Expr *E) {
+void MicrosoftCXXNameMangler::mangleExpression(const Expr *E) {
   // See if this is a constant expression.
   llvm::APSInt Value;
   if (E->isIntegerConstantExpr(Value, Context.getASTContext())) {
@@ -894,7 +1063,10 @@
     return;
   }
 
-  const CXXUuidofExpr *UE = 0;
+  // Look through no-op casts like template parameter substitutions.
+  E = E->IgnoreParenNoopCasts(Context.getASTContext());
+
+  const CXXUuidofExpr *UE = nullptr;
   if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
     if (UO->getOpcode() == UO_AddrOf)
       UE = dyn_cast<CXXUuidofExpr>(UO->getSubExpr());
@@ -923,26 +1095,30 @@
 
   // As bad as this diagnostic is, it's better than crashing.
   DiagnosticsEngine &Diags = Context.getDiags();
-  unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
-                                   "cannot yet mangle expression type %0");
-  Diags.Report(E->getExprLoc(), DiagID)
-    << E->getStmtClassName() << E->getSourceRange();
+  unsigned DiagID = Diags.getCustomDiagID(
+      DiagnosticsEngine::Error, "cannot yet mangle expression type %0");
+  Diags.Report(E->getExprLoc(), DiagID) << E->getStmtClassName()
+                                        << E->getSourceRange();
 }
 
-void
-MicrosoftCXXNameMangler::mangleTemplateArgs(const TemplateDecl *TD,
-                                     const TemplateArgumentList &TemplateArgs) {
-  // <template-args> ::= {<type> | <integer-literal>}+ @
-  unsigned NumTemplateArgs = TemplateArgs.size();
-  for (unsigned i = 0; i < NumTemplateArgs; ++i) {
-    const TemplateArgument &TA = TemplateArgs[i];
+void MicrosoftCXXNameMangler::mangleTemplateArgs(
+    const TemplateDecl *TD, const TemplateArgumentList &TemplateArgs) {
+  // <template-args> ::= <template-arg>+
+  for (const TemplateArgument &TA : TemplateArgs.asArray())
     mangleTemplateArg(TD, TA);
-  }
-  Out << '@';
 }
 
 void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
                                                 const TemplateArgument &TA) {
+  // <template-arg> ::= <type>
+  //                ::= <integer-literal>
+  //                ::= <member-data-pointer>
+  //                ::= <member-function-pointer>
+  //                ::= $E? <name> <type-encoding>
+  //                ::= $1? <name> <type-encoding>
+  //                ::= $0A@
+  //                ::= <template-args>
+
   switch (TA.getKind()) {
   case TemplateArgument::Null:
     llvm_unreachable("Can't mangle null template arguments!");
@@ -955,25 +1131,54 @@
   }
   case TemplateArgument::Declaration: {
     const NamedDecl *ND = cast<NamedDecl>(TA.getAsDecl());
-    mangle(ND, TA.isDeclForReferenceParam() ? "$E?" : "$1?");
+    if (isa<FieldDecl>(ND) || isa<IndirectFieldDecl>(ND)) {
+      mangleMemberDataPointer(
+          cast<CXXRecordDecl>(ND->getDeclContext())->getMostRecentDecl(),
+          cast<ValueDecl>(ND));
+    } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
+      const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
+      if (MD && MD->isInstance())
+        mangleMemberFunctionPointer(MD->getParent()->getMostRecentDecl(), MD);
+      else
+        mangle(FD, "$1?");
+    } else {
+      mangle(ND, TA.isDeclForReferenceParam() ? "$E?" : "$1?");
+    }
     break;
   }
   case TemplateArgument::Integral:
     mangleIntegerLiteral(TA.getAsIntegral(),
                          TA.getIntegralType()->isBooleanType());
     break;
-  case TemplateArgument::NullPtr:
+  case TemplateArgument::NullPtr: {
+    QualType T = TA.getNullPtrType();
+    if (const MemberPointerType *MPT = T->getAs<MemberPointerType>()) {
+      const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
+      if (MPT->isMemberFunctionPointerType() && isa<ClassTemplateDecl>(TD)) {
+        mangleMemberFunctionPointer(RD, nullptr);
+        return;
+      }
+      if (MPT->isMemberDataPointer()) {
+        mangleMemberDataPointer(RD, nullptr);
+        return;
+      }
+    }
     Out << "$0A@";
     break;
+  }
   case TemplateArgument::Expression:
     mangleExpression(TA.getAsExpr());
     break;
-  case TemplateArgument::Pack:
-    // Unlike Itanium, there is no character code to indicate an argument pack.
-    for (TemplateArgument::pack_iterator I = TA.pack_begin(), E = TA.pack_end();
-         I != E; ++I)
-      mangleTemplateArg(TD, *I);
+  case TemplateArgument::Pack: {
+    ArrayRef<TemplateArgument> TemplateArgs = TA.getPackAsArray();
+    if (TemplateArgs.empty()) {
+      Out << "$S";
+    } else {
+      for (const TemplateArgument &PA : TemplateArgs)
+        mangleTemplateArg(TD, PA);
+    }
     break;
+  }
   case TemplateArgument::Template:
     mangleType(cast<TagDecl>(
         TA.getAsTemplate().getAsTemplateDecl()->getTemplatedDecl()));
@@ -1063,13 +1268,43 @@
   // FIXME: For now, just drop all extension qualifiers on the floor.
 }
 
-void MicrosoftCXXNameMangler::manglePointerQualifiers(Qualifiers Quals) {
-  // <pointer-cvr-qualifiers> ::= P  # no qualifiers
-  //                          ::= Q  # const
-  //                          ::= R  # volatile
-  //                          ::= S  # const volatile
+void
+MicrosoftCXXNameMangler::mangleRefQualifier(RefQualifierKind RefQualifier) {
+  // <ref-qualifier> ::= G                # lvalue reference
+  //                 ::= H                # rvalue-reference
+  switch (RefQualifier) {
+  case RQ_None:
+    break;
+
+  case RQ_LValue:
+    Out << 'G';
+    break;
+
+  case RQ_RValue:
+    Out << 'H';
+    break;
+  }
+}
+
+void
+MicrosoftCXXNameMangler::manglePointerExtQualifiers(Qualifiers Quals,
+                                                    const Type *PointeeType) {
+  bool HasRestrict = Quals.hasRestrict();
+  if (PointersAre64Bit && (!PointeeType || !PointeeType->isFunctionType()))
+    Out << 'E';
+
+  if (HasRestrict)
+    Out << 'I';
+}
+
+void MicrosoftCXXNameMangler::manglePointerCVQualifiers(Qualifiers Quals) {
+  // <pointer-cv-qualifiers> ::= P  # no qualifiers
+  //                         ::= Q  # const
+  //                         ::= R  # volatile
+  //                         ::= S  # const volatile
   bool HasConst = Quals.hasConst(),
        HasVolatile = Quals.hasVolatile();
+
   if (HasConst && HasVolatile) {
     Out << 'S';
   } else if (HasVolatile) {
@@ -1169,8 +1404,10 @@
   }
 
   // We have to mangle these now, while we still have enough information.
-  if (IsPointer)
-    manglePointerQualifiers(Quals);
+  if (IsPointer) {
+    manglePointerCVQualifiers(Quals);
+    manglePointerExtQualifiers(Quals, T->getPointeeType().getTypePtr());
+  }
   const Type *ty = T.getTypePtr();
 
   switch (ty->getTypeClass()) {
@@ -1258,7 +1495,7 @@
   case BuiltinType::OCLImage3d: Out << "PAUocl_image3d@@"; break;
   case BuiltinType::OCLSampler: Out << "PAUocl_sampler@@"; break;
   case BuiltinType::OCLEvent: Out << "PAUocl_event@@"; break;
- 
+
   case BuiltinType::NullPtr: Out << "$$T"; break;
 
   case BuiltinType::Char16:
@@ -1310,9 +1547,10 @@
   // If this is a C++ instance method, mangle the CVR qualifiers for the
   // this pointer.
   if (IsInstMethod) {
-    if (PointersAre64Bit)
-      Out << 'E';
-    mangleQualifiers(Qualifiers::fromCVRMask(Proto->getTypeQuals()), false);
+    Qualifiers Quals = Qualifiers::fromCVRMask(Proto->getTypeQuals());
+    manglePointerExtQualifiers(Quals, nullptr);
+    mangleRefQualifier(Proto->getRefQualifier());
+    mangleQualifiers(Quals, false);
   }
 
   mangleCallingConvention(T);
@@ -1331,23 +1569,30 @@
     }
     Out << '@';
   } else {
-    QualType ResultType = Proto->getResultType();
-    if (ResultType->isVoidType())
-      ResultType = ResultType.getUnqualifiedType();
-    mangleType(ResultType, Range, QMM_Result);
+    QualType ResultType = Proto->getReturnType();
+    if (const auto *AT =
+            dyn_cast_or_null<AutoType>(ResultType->getContainedAutoType())) {
+      Out << '?';
+      mangleQualifiers(ResultType.getLocalQualifiers(), /*IsMember=*/false);
+      Out << '?';
+      mangleSourceName(AT->isDecltypeAuto() ? "<decltype-auto>" : "<auto>");
+      Out << '@';
+    } else {
+      if (ResultType->isVoidType())
+        ResultType = ResultType.getUnqualifiedType();
+      mangleType(ResultType, Range, QMM_Result);
+    }
   }
 
   // <argument-list> ::= X # void
   //                 ::= <type>+ @
   //                 ::= <type>* Z # varargs
-  if (Proto->getNumArgs() == 0 && !Proto->isVariadic()) {
+  if (Proto->getNumParams() == 0 && !Proto->isVariadic()) {
     Out << 'X';
   } else {
     // Happens for function pointer type arguments for example.
-    for (FunctionProtoType::arg_type_iterator Arg = Proto->arg_type_begin(),
-         ArgEnd = Proto->arg_type_end();
-         Arg != ArgEnd; ++Arg)
-      mangleArgumentType(*Arg, Range);
+    for (const QualType Arg : Proto->param_types())
+      mangleArgumentType(Arg, Range);
     // <builtin-type>      ::= Z  # ellipsis
     if (Proto->isVariadic())
       Out << 'Z';
@@ -1469,7 +1714,7 @@
 // <union-type>  ::= T <name>
 // <struct-type> ::= U <name>
 // <class-type>  ::= V <name>
-// <enum-type>   ::= W <size> <name>
+// <enum-type>   ::= W4 <name>
 void MicrosoftCXXNameMangler::mangleType(const EnumType *T, SourceRange) {
   mangleType(cast<TagType>(T)->getDecl());
 }
@@ -1489,9 +1734,7 @@
       Out << 'V';
       break;
     case TTK_Enum:
-      Out << 'W';
-      Out << getASTContext().getTypeSizeInChars(
-                cast<EnumDecl>(TD)->getIntegerType()).getQuantity();
+      Out << "W4";
       break;
   }
   mangleName(TD);
@@ -1507,7 +1750,7 @@
 void MicrosoftCXXNameMangler::mangleDecayedArrayType(const ArrayType *T) {
   // This isn't a recursive mangling, so now we have to do it all in this
   // one call.
-  manglePointerQualifiers(T->getElementType().getQualifiers());
+  manglePointerCVQualifiers(T->getElementType().getQualifiers());
   mangleType(T->getElementType(), SourceRange());
 }
 void MicrosoftCXXNameMangler::mangleType(const ConstantArrayType *T,
@@ -1531,7 +1774,7 @@
   SmallVector<llvm::APInt, 3> Dimensions;
   for (;;) {
     if (const ConstantArrayType *CAT =
-          getASTContext().getAsConstantArrayType(ElementTy)) {
+            getASTContext().getAsConstantArrayType(ElementTy)) {
       Dimensions.push_back(CAT->getSize());
       ElementTy = CAT->getElementType();
     } else if (ElementTy->isVariableArrayType()) {
@@ -1554,7 +1797,7 @@
         << DSAT->getBracketsRange();
       return;
     } else if (const IncompleteArrayType *IAT =
-          getASTContext().getAsIncompleteArrayType(ElementTy)) {
+                   getASTContext().getAsIncompleteArrayType(ElementTy)) {
       Dimensions.push_back(llvm::APInt(32, 0));
       ElementTy = IAT->getElementType();
     }
@@ -1563,8 +1806,8 @@
   Out << 'Y';
   // <dimension-count> ::= <number> # number of extra dimensions
   mangleNumber(Dimensions.size());
-  for (unsigned Dim = 0; Dim < Dimensions.size(); ++Dim)
-    mangleNumber(Dimensions[Dim].getLimitedValue());
+  for (const llvm::APInt &Dimension : Dimensions)
+    mangleNumber(Dimension.getLimitedValue());
   mangleType(ElementTy, SourceRange(), QMM_Escape);
 }
 
@@ -1577,10 +1820,8 @@
   if (const FunctionProtoType *FPT = PointeeType->getAs<FunctionProtoType>()) {
     Out << '8';
     mangleName(T->getClass()->castAs<RecordType>()->getDecl());
-    mangleFunctionType(FPT, 0, true);
+    mangleFunctionType(FPT, nullptr, true);
   } else {
-    if (PointersAre64Bit && !T->getPointeeType()->isFunctionType())
-      Out << 'E';
     mangleQualifiers(PointeeType.getQualifiers(), true);
     mangleName(T->getClass()->castAs<RecordType>()->getDecl());
     mangleType(PointeeType, Range, QMM_Drop);
@@ -1608,42 +1849,37 @@
 
 // <type> ::= <pointer-type>
 // <pointer-type> ::= E? <pointer-cvr-qualifiers> <cvr-qualifiers> <type>
-//                       # the E is required for 64-bit non static pointers
+//                       # the E is required for 64-bit non-static pointers
 void MicrosoftCXXNameMangler::mangleType(const PointerType *T,
                                          SourceRange Range) {
   QualType PointeeTy = T->getPointeeType();
-  if (PointersAre64Bit && !T->getPointeeType()->isFunctionType())
-    Out << 'E';
   mangleType(PointeeTy, Range);
 }
 void MicrosoftCXXNameMangler::mangleType(const ObjCObjectPointerType *T,
                                          SourceRange Range) {
   // Object pointers never have qualifiers.
   Out << 'A';
-  if (PointersAre64Bit && !T->getPointeeType()->isFunctionType())
-    Out << 'E';
+  manglePointerExtQualifiers(Qualifiers(), T->getPointeeType().getTypePtr());
   mangleType(T->getPointeeType(), Range);
 }
 
 // <type> ::= <reference-type>
 // <reference-type> ::= A E? <cvr-qualifiers> <type>
-//                 # the E is required for 64-bit non static lvalue references
+//                 # the E is required for 64-bit non-static lvalue references
 void MicrosoftCXXNameMangler::mangleType(const LValueReferenceType *T,
                                          SourceRange Range) {
   Out << 'A';
-  if (PointersAre64Bit && !T->getPointeeType()->isFunctionType())
-    Out << 'E';
+  manglePointerExtQualifiers(Qualifiers(), T->getPointeeType().getTypePtr());
   mangleType(T->getPointeeType(), Range);
 }
 
 // <type> ::= <r-value-reference-type>
 // <r-value-reference-type> ::= $$Q E? <cvr-qualifiers> <type>
-//                 # the E is required for 64-bit non static rvalue references
+//                 # the E is required for 64-bit non-static rvalue references
 void MicrosoftCXXNameMangler::mangleType(const RValueReferenceType *T,
                                          SourceRange Range) {
   Out << "$$Q";
-  if (PointersAre64Bit && !T->getPointeeType()->isFunctionType())
-    Out << 'E';
+  manglePointerExtQualifiers(Qualifiers(), T->getPointeeType().getTypePtr());
   mangleType(T->getPointeeType(), Range);
 }
 
@@ -1808,6 +2044,8 @@
 }
 
 void MicrosoftCXXNameMangler::mangleType(const AutoType *T, SourceRange Range) {
+  assert(T->getDeducedType().isNull() && "expecting a dependent type!");
+
   DiagnosticsEngine &Diags = Context.getDiags();
   unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
     "cannot mangle this 'auto' type yet");
@@ -1884,14 +2122,18 @@
     }
     if (Adjustment.Virtual.Microsoft.VBPtrOffset) {
       Out << 'R' << AccessSpec;
-      Mangler.mangleNumber(Adjustment.Virtual.Microsoft.VBPtrOffset);
-      Mangler.mangleNumber(Adjustment.Virtual.Microsoft.VBOffsetOffset);
-      Mangler.mangleNumber(Adjustment.Virtual.Microsoft.VtordispOffset);
-      Mangler.mangleNumber(Adjustment.NonVirtual);
+      Mangler.mangleNumber(
+          static_cast<uint32_t>(Adjustment.Virtual.Microsoft.VBPtrOffset));
+      Mangler.mangleNumber(
+          static_cast<uint32_t>(Adjustment.Virtual.Microsoft.VBOffsetOffset));
+      Mangler.mangleNumber(
+          static_cast<uint32_t>(Adjustment.Virtual.Microsoft.VtordispOffset));
+      Mangler.mangleNumber(static_cast<uint32_t>(Adjustment.NonVirtual));
     } else {
       Out << AccessSpec;
-      Mangler.mangleNumber(Adjustment.Virtual.Microsoft.VtordispOffset);
-      Mangler.mangleNumber(-Adjustment.NonVirtual);
+      Mangler.mangleNumber(
+          static_cast<uint32_t>(Adjustment.Virtual.Microsoft.VtordispOffset));
+      Mangler.mangleNumber(-static_cast<uint32_t>(Adjustment.NonVirtual));
     }
   } else if (Adjustment.NonVirtual != 0) {
     switch (MD->getAccess()) {
@@ -1906,7 +2148,7 @@
     case AS_public:
       Out << 'W';
     }
-    Mangler.mangleNumber(-Adjustment.NonVirtual);
+    Mangler.mangleNumber(-static_cast<uint32_t>(Adjustment.NonVirtual));
   } else {
     switch (MD->getAccess()) {
     case AS_none:
@@ -1923,17 +2165,17 @@
   }
 }
 
-void MicrosoftMangleContextImpl::mangleVirtualMemPtrThunk(
-    const CXXMethodDecl *MD, int OffsetInVFTable, raw_ostream &Out) {
-  bool Is64Bit = getASTContext().getTargetInfo().getPointerWidth(0) == 64;
+void
+MicrosoftMangleContextImpl::mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
+                                                     raw_ostream &Out) {
+  MicrosoftVTableContext *VTContext =
+      cast<MicrosoftVTableContext>(getASTContext().getVTableContext());
+  const MicrosoftVTableContext::MethodVFTableLocation &ML =
+      VTContext->getMethodVFTableLocation(GlobalDecl(MD));
 
   MicrosoftCXXNameMangler Mangler(*this, Out);
-  Mangler.getStream() << "\01??_9";
-  Mangler.mangleName(MD->getParent());
-  Mangler.getStream() << "$B";
-  Mangler.mangleNumber(OffsetInVFTable);
-  Mangler.getStream() << "A";
-  Mangler.getStream() << (Is64Bit ? "A" : "E");
+  Mangler.getStream() << "\01?";
+  Mangler.mangleVirtualMemPtrThunk(MD, ML);
 }
 
 void MicrosoftMangleContextImpl::mangleThunk(const CXXMethodDecl *MD,
@@ -1944,7 +2186,8 @@
   Mangler.mangleName(MD);
   mangleThunkThisAdjustment(MD, Thunk.This, Mangler, Out);
   if (!Thunk.Return.isEmpty())
-    assert(Thunk.Method != 0 && "Thunk info should hold the overridee decl");
+    assert(Thunk.Method != nullptr &&
+           "Thunk info should hold the overridee decl");
 
   const CXXMethodDecl *DeclForFPT = Thunk.Method ? Thunk.Method : MD;
   Mangler.mangleFunctionType(
@@ -1976,11 +2219,8 @@
   Mangler.getStream() << "\01??_7";
   Mangler.mangleName(Derived);
   Mangler.getStream() << "6B"; // '6' for vftable, 'B' for const.
-  for (ArrayRef<const CXXRecordDecl *>::iterator I = BasePath.begin(),
-                                                 E = BasePath.end();
-       I != E; ++I) {
-    Mangler.mangleName(*I);
-  }
+  for (const CXXRecordDecl *RD : BasePath)
+    Mangler.mangleName(RD);
   Mangler.getStream() << '@';
 }
 
@@ -1995,28 +2235,76 @@
   Mangler.getStream() << "\01??_8";
   Mangler.mangleName(Derived);
   Mangler.getStream() << "7B";  // '7' for vbtable, 'B' for const.
-  for (ArrayRef<const CXXRecordDecl *>::iterator I = BasePath.begin(),
-                                                 E = BasePath.end();
-       I != E; ++I) {
-    Mangler.mangleName(*I);
-  }
+  for (const CXXRecordDecl *RD : BasePath)
+    Mangler.mangleName(RD);
   Mangler.getStream() << '@';
 }
 
-void MicrosoftMangleContextImpl::mangleCXXRTTI(QualType T, raw_ostream &) {
-  // FIXME: Give a location...
-  unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error,
-    "cannot mangle RTTI descriptors for type %0 yet");
-  getDiags().Report(DiagID)
-    << T.getBaseTypeIdentifier();
+void MicrosoftMangleContextImpl::mangleCXXRTTI(QualType T, raw_ostream &Out) {
+  MicrosoftCXXNameMangler Mangler(*this, Out);
+  Mangler.getStream() << "\01??_R0";
+  Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
+  Mangler.getStream() << "@8";
 }
 
-void MicrosoftMangleContextImpl::mangleCXXRTTIName(QualType T, raw_ostream &) {
-  // FIXME: Give a location...
-  unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error,
-    "cannot mangle the name of type %0 into RTTI descriptors yet");
-  getDiags().Report(DiagID)
-    << T.getBaseTypeIdentifier();
+void MicrosoftMangleContextImpl::mangleCXXRTTIName(QualType T,
+                                                   raw_ostream &Out) {
+  MicrosoftCXXNameMangler Mangler(*this, Out);
+  Mangler.getStream() << '.';
+  Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
+}
+
+void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassDescriptor(
+    const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
+    uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) {
+  MicrosoftCXXNameMangler Mangler(*this, Out);
+  Mangler.getStream() << "\01??_R1";
+  Mangler.mangleNumber(NVOffset);
+  Mangler.mangleNumber(VBPtrOffset);
+  Mangler.mangleNumber(VBTableOffset);
+  Mangler.mangleNumber(Flags);
+  Mangler.mangleName(Derived);
+  Mangler.getStream() << "8";
+}
+
+void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassArray(
+    const CXXRecordDecl *Derived, raw_ostream &Out) {
+  MicrosoftCXXNameMangler Mangler(*this, Out);
+  Mangler.getStream() << "\01??_R2";
+  Mangler.mangleName(Derived);
+  Mangler.getStream() << "8";
+}
+
+void MicrosoftMangleContextImpl::mangleCXXRTTIClassHierarchyDescriptor(
+    const CXXRecordDecl *Derived, raw_ostream &Out) {
+  MicrosoftCXXNameMangler Mangler(*this, Out);
+  Mangler.getStream() << "\01??_R3";
+  Mangler.mangleName(Derived);
+  Mangler.getStream() << "8";
+}
+
+void MicrosoftMangleContextImpl::mangleCXXRTTICompleteObjectLocator(
+    const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,
+    raw_ostream &Out) {
+  // <mangled-name> ::= ?_R4 <class-name> <storage-class>
+  //                    <cvr-qualifiers> [<name>] @
+  // NOTE: <cvr-qualifiers> here is always 'B' (const). <storage-class>
+  // is always '6' for vftables.
+  MicrosoftCXXNameMangler Mangler(*this, Out);
+  Mangler.getStream() << "\01??_R4";
+  Mangler.mangleName(Derived);
+  Mangler.getStream() << "6B"; // '6' for vftable, 'B' for const.
+  for (const CXXRecordDecl *RD : BasePath)
+    Mangler.mangleName(RD);
+  Mangler.getStream() << '@';
+}
+
+void MicrosoftMangleContextImpl::mangleTypeName(QualType T, raw_ostream &Out) {
+  // This is just a made up unique string for the purposes of tbaa.  undname
+  // does *not* know how to demangle it.
+  MicrosoftCXXNameMangler Mangler(*this, Out);
+  Mangler.getStream() << '?';
+  Mangler.mangleType(T, SourceRange());
 }
 
 void MicrosoftMangleContextImpl::mangleCXXCtor(const CXXConstructorDecl *D,
@@ -2034,6 +2322,7 @@
 }
 
 void MicrosoftMangleContextImpl::mangleReferenceTemporary(const VarDecl *VD,
+                                                          unsigned,
                                                           raw_ostream &) {
   unsigned DiagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error,
     "cannot mangle this reference temporary yet");
@@ -2042,7 +2331,16 @@
 
 void MicrosoftMangleContextImpl::mangleStaticGuardVariable(const VarDecl *VD,
                                                            raw_ostream &Out) {
-  // <guard-name> ::= ?_B <postfix> @51
+  // TODO: This is not correct, especially with respect to MSVC2013.  MSVC2013
+  // utilizes thread local variables to implement thread safe, re-entrant
+  // initialization for statics.  They no longer differentiate between an
+  // externally visible and non-externally visible static with respect to
+  // mangling, they all get $TSS <number>.
+  //
+  // N.B. This means that they can get more than 32 static variable guards in a
+  // scope.  It also means that they broke compatibility with their own ABI.
+
+  // <guard-name> ::= ?_B <postfix> @5 <scope-depth>
   //              ::= ?$S <guard-num> @ <postfix> @4IA
 
   // The first mangling is what MSVC uses to guard static locals in inline
@@ -2056,8 +2354,17 @@
   bool Visible = VD->isExternallyVisible();
   // <operator-name> ::= ?_B # local static guard
   Mangler.getStream() << (Visible ? "\01??_B" : "\01?$S1@");
-  Mangler.manglePostfix(VD->getDeclContext());
-  Mangler.getStream() << (Visible ? "@51" : "@4IA");
+  unsigned ScopeDepth = 0;
+  if (Visible && !getNextDiscriminator(VD, ScopeDepth))
+    // If we do not have a discriminator and are emitting a guard variable for
+    // use at global scope, then mangling the nested name will not be enough to
+    // remove ambiguities.
+    Mangler.mangle(VD, "");
+  else
+    Mangler.mangleNestedName(VD);
+  Mangler.getStream() << (Visible ? "@5" : "@4IA");
+  if (ScopeDepth)
+    Mangler.mangleNumber(ScopeDepth);
 }
 
 void MicrosoftMangleContextImpl::mangleInitFiniStub(const VarDecl *D,
@@ -2066,6 +2373,10 @@
   MicrosoftCXXNameMangler Mangler(*this, Out);
   Mangler.getStream() << "\01??__" << CharCode;
   Mangler.mangleName(D);
+  if (D->isStaticDataMember()) {
+    Mangler.mangleVariableEncoding(D);
+    Mangler.getStream() << '@';
+  }
   // This is the function class mangling.  These stubs are global, non-variadic,
   // cdecl functions that return void and take no args.
   Mangler.getStream() << "YAXXZ";
@@ -2084,6 +2395,172 @@
   mangleInitFiniStub(D, Out, 'F');
 }
 
+void MicrosoftMangleContextImpl::mangleStringLiteral(const StringLiteral *SL,
+                                                     raw_ostream &Out) {
+  // <char-type> ::= 0   # char
+  //             ::= 1   # wchar_t
+  //             ::= ??? # char16_t/char32_t will need a mangling too...
+  //
+  // <literal-length> ::= <non-negative integer>  # the length of the literal
+  //
+  // <encoded-crc>    ::= <hex digit>+ @          # crc of the literal including
+  //                                              # null-terminator
+  //
+  // <encoded-string> ::= <simple character>           # uninteresting character
+  //                  ::= '?$' <hex digit> <hex digit> # these two nibbles
+  //                                                   # encode the byte for the
+  //                                                   # character
+  //                  ::= '?' [a-z]                    # \xe1 - \xfa
+  //                  ::= '?' [A-Z]                    # \xc1 - \xda
+  //                  ::= '?' [0-9]                    # [,/\:. \n\t'-]
+  //
+  // <literal> ::= '??_C@_' <char-type> <literal-length> <encoded-crc>
+  //               <encoded-string> '@'
+  MicrosoftCXXNameMangler Mangler(*this, Out);
+  Mangler.getStream() << "\01??_C@_";
+
+  // <char-type>: The "kind" of string literal is encoded into the mangled name.
+  // TODO: This needs to be updated when MSVC gains support for unicode
+  // literals.
+  if (SL->isAscii())
+    Mangler.getStream() << '0';
+  else if (SL->isWide())
+    Mangler.getStream() << '1';
+  else
+    llvm_unreachable("unexpected string literal kind!");
+
+  // <literal-length>: The next part of the mangled name consists of the length
+  // of the string.
+  // The StringLiteral does not consider the NUL terminator byte(s) but the
+  // mangling does.
+  // N.B. The length is in terms of bytes, not characters.
+  Mangler.mangleNumber(SL->getByteLength() + SL->getCharByteWidth());
+
+  // We will use the "Rocksoft^tm Model CRC Algorithm" to describe the
+  // properties of our CRC:
+  //   Width  : 32
+  //   Poly   : 04C11DB7
+  //   Init   : FFFFFFFF
+  //   RefIn  : True
+  //   RefOut : True
+  //   XorOut : 00000000
+  //   Check  : 340BC6D9
+  uint32_t CRC = 0xFFFFFFFFU;
+
+  auto UpdateCRC = [&CRC](char Byte) {
+    for (unsigned i = 0; i < 8; ++i) {
+      bool Bit = CRC & 0x80000000U;
+      if (Byte & (1U << i))
+        Bit = !Bit;
+      CRC <<= 1;
+      if (Bit)
+        CRC ^= 0x04C11DB7U;
+    }
+  };
+
+  auto GetLittleEndianByte = [&Mangler, &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) {
+    unsigned CharByteWidth = SL->getCharByteWidth();
+    uint32_t CodeUnit = SL->getCodeUnit(Index / CharByteWidth);
+    unsigned OffsetInCodeUnit = (CharByteWidth - 1) - (Index % CharByteWidth);
+    return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
+  };
+
+  // CRC all the bytes of the StringLiteral.
+  for (unsigned I = 0, E = SL->getByteLength(); I != E; ++I)
+    UpdateCRC(GetLittleEndianByte(I));
+
+  // The NUL terminator byte(s) were not present earlier,
+  // we need to manually process those bytes into the CRC.
+  for (unsigned NullTerminator = 0; NullTerminator < SL->getCharByteWidth();
+       ++NullTerminator)
+    UpdateCRC('\x00');
+
+  // The literature refers to the process of reversing the bits in the final CRC
+  // output as "reflection".
+  CRC = llvm::reverseBits(CRC);
+
+  // <encoded-crc>: The CRC is encoded utilizing the standard number mangling
+  // scheme.
+  Mangler.mangleNumber(CRC);
+
+  // <encoded-string>: The mangled name also contains the first 32 _characters_
+  // (including null-terminator bytes) of the StringLiteral.
+  // Each character is encoded by splitting them into bytes and then encoding
+  // the constituent bytes.
+  auto MangleByte = [&Mangler](char Byte) {
+    // There are five different manglings for characters:
+    // - [a-zA-Z0-9_$]: A one-to-one mapping.
+    // - ?[a-z]: The range from \xe1 to \xfa.
+    // - ?[A-Z]: The range from \xc1 to \xda.
+    // - ?[0-9]: The set of [,/\:. \n\t'-].
+    // - ?$XX: A fallback which maps nibbles.
+    if (isIdentifierBody(Byte, /*AllowDollar=*/true)) {
+      Mangler.getStream() << Byte;
+    } else if (isLetter(Byte & 0x7f)) {
+      Mangler.getStream() << '?' << static_cast<char>(Byte & 0x7f);
+    } else {
+      switch (Byte) {
+        case ',':
+          Mangler.getStream() << "?0";
+          break;
+        case '/':
+          Mangler.getStream() << "?1";
+          break;
+        case '\\':
+          Mangler.getStream() << "?2";
+          break;
+        case ':':
+          Mangler.getStream() << "?3";
+          break;
+        case '.':
+          Mangler.getStream() << "?4";
+          break;
+        case ' ':
+          Mangler.getStream() << "?5";
+          break;
+        case '\n':
+          Mangler.getStream() << "?6";
+          break;
+        case '\t':
+          Mangler.getStream() << "?7";
+          break;
+        case '\'':
+          Mangler.getStream() << "?8";
+          break;
+        case '-':
+          Mangler.getStream() << "?9";
+          break;
+        default:
+          Mangler.getStream() << "?$";
+          Mangler.getStream() << static_cast<char>('A' + ((Byte >> 4) & 0xf));
+          Mangler.getStream() << static_cast<char>('A' + (Byte & 0xf));
+          break;
+      }
+    }
+  };
+
+  // Enforce our 32 character max.
+  unsigned NumCharsToMangle = std::min(32U, SL->getLength());
+  for (unsigned I = 0, E = NumCharsToMangle * SL->getCharByteWidth(); I != E;
+       ++I)
+    MangleByte(GetBigEndianByte(I));
+
+  // Encode the NUL terminator if there is room.
+  if (NumCharsToMangle < 32)
+    for (unsigned NullTerminator = 0; NullTerminator < SL->getCharByteWidth();
+         ++NullTerminator)
+      MangleByte(0);
+
+  Mangler.getStream() << '@';
+}
+
 MicrosoftMangleContext *
 MicrosoftMangleContext::create(ASTContext &Context, DiagnosticsEngine &Diags) {
   return new MicrosoftMangleContextImpl(Context, Diags);
diff --git a/lib/AST/NSAPI.cpp b/lib/AST/NSAPI.cpp
index a862630..986b3b5 100644
--- a/lib/AST/NSAPI.cpp
+++ b/lib/AST/NSAPI.cpp
@@ -14,9 +14,9 @@
 using namespace clang;
 
 NSAPI::NSAPI(ASTContext &ctx)
-  : Ctx(ctx), ClassIds(), BOOLId(0), NSIntegerId(0), NSUIntegerId(0),
-    NSASCIIStringEncodingId(0), NSUTF8StringEncodingId(0) {
-}
+  : Ctx(ctx), ClassIds(), BOOLId(nullptr), NSIntegerId(nullptr),
+    NSUIntegerId(nullptr), NSASCIIStringEncodingId(nullptr),
+    NSUTF8StringEncodingId(nullptr) {}
 
 IdentifierInfo *NSAPI::getNSClassId(NSClassIdKindKind K) const {
   static const char *ClassName[NumClassIds] = {
diff --git a/lib/AST/NestedNameSpecifier.cpp b/lib/AST/NestedNameSpecifier.cpp
index b03c4e0..1f041aa 100644
--- a/lib/AST/NestedNameSpecifier.cpp
+++ b/lib/AST/NestedNameSpecifier.cpp
@@ -30,7 +30,7 @@
   llvm::FoldingSetNodeID ID;
   Mockup.Profile(ID);
 
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
   NestedNameSpecifier *NNS
     = Context.NestedNameSpecifiers.FindNodeOrInsertPos(ID, InsertPos);
   if (!NNS) {
@@ -61,7 +61,8 @@
                             const NamespaceDecl *NS) {
   assert(NS && "Namespace cannot be NULL");
   assert((!Prefix ||
-          (Prefix->getAsType() == 0 && Prefix->getAsIdentifier() == 0)) &&
+          (Prefix->getAsType() == nullptr &&
+           Prefix->getAsIdentifier() == nullptr)) &&
          "Broken nested name specifier");
   NestedNameSpecifier Mockup;
   Mockup.Prefix.setPointer(Prefix);
@@ -76,7 +77,8 @@
                             NamespaceAliasDecl *Alias) {
   assert(Alias && "Namespace alias cannot be NULL");
   assert((!Prefix ||
-          (Prefix->getAsType() == 0 && Prefix->getAsIdentifier() == 0)) &&
+          (Prefix->getAsType() == nullptr &&
+           Prefix->getAsIdentifier() == nullptr)) &&
          "Broken nested name specifier");
   NestedNameSpecifier Mockup;
   Mockup.Prefix.setPointer(Prefix);
@@ -101,7 +103,7 @@
 NestedNameSpecifier::Create(const ASTContext &Context, IdentifierInfo *II) {
   assert(II && "Identifier cannot be NULL");
   NestedNameSpecifier Mockup;
-  Mockup.Prefix.setPointer(0);
+  Mockup.Prefix.setPointer(nullptr);
   Mockup.Prefix.setInt(StoredIdentifier);
   Mockup.Specifier = II;
   return FindOrInsert(Context, Mockup);
@@ -117,7 +119,7 @@
 }
 
 NestedNameSpecifier::SpecifierKind NestedNameSpecifier::getKind() const {
-  if (Specifier == 0)
+  if (!Specifier)
     return Global;
 
   switch (Prefix.getInt()) {
@@ -144,7 +146,7 @@
   if (Prefix.getInt() == StoredNamespaceOrAlias)
     return dyn_cast<NamespaceDecl>(static_cast<NamedDecl *>(Specifier));
 
-  return 0;
+  return nullptr;
 }
 
 /// \brief Retrieve the namespace alias stored in this nested name
@@ -153,7 +155,7 @@
   if (Prefix.getInt() == StoredNamespaceOrAlias)
     return dyn_cast<NamespaceAliasDecl>(static_cast<NamedDecl *>(Specifier));
 
-  return 0;
+  return nullptr;
 }
 
 
@@ -437,7 +439,7 @@
 
 NestedNameSpecifierLocBuilder::
 NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other) 
-  : Representation(Other.Representation), Buffer(0),
+  : Representation(Other.Representation), Buffer(nullptr),
     BufferSize(0), BufferCapacity(0)
 {
   if (!Other.Buffer)
@@ -451,10 +453,8 @@
   }
   
   // Deep copy
-  BufferSize = Other.BufferSize;
-  BufferCapacity = Other.BufferSize;
-  Buffer = static_cast<char *>(malloc(BufferCapacity));
-  memcpy(Buffer, Other.Buffer, BufferSize);
+  Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize,
+         BufferCapacity);
 }
 
 NestedNameSpecifierLocBuilder &
@@ -477,7 +477,7 @@
   
   if (!Other.Buffer) {
     // Empty.
-    Buffer = 0;
+    Buffer = nullptr;
     BufferSize = 0;
     return *this;
   }
@@ -490,10 +490,8 @@
   }
   
   // Deep copy.
-  BufferSize = Other.BufferSize;
-  BufferCapacity = BufferSize;
-  Buffer = static_cast<char *>(malloc(BufferSize));
-  memcpy(Buffer, Other.Buffer, BufferSize);
+  Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize,
+         BufferCapacity);
   return *this;
 }
 
@@ -599,7 +597,7 @@
     free(Buffer);
 
   if (!Other) {
-    Representation = 0;
+    Representation = nullptr;
     BufferSize = 0;
     return;
   }
diff --git a/lib/AST/ParentMap.cpp b/lib/AST/ParentMap.cpp
index ff44d93..a991302 100644
--- a/lib/AST/ParentMap.cpp
+++ b/lib/AST/ParentMap.cpp
@@ -37,7 +37,7 @@
     // If we are rebuilding the map, clear out any existing state.
     if (M[POE->getSyntacticForm()])
       for (Stmt::child_range I = S->children(); I; ++I)
-        M[*I] = 0;
+        M[*I] = nullptr;
 
     M[POE->getSyntacticForm()] = S;
     BuildParentMap(M, POE->getSyntacticForm(), OV_Transparent);
@@ -92,7 +92,7 @@
   }
 }
 
-ParentMap::ParentMap(Stmt* S) : Impl(0) {
+ParentMap::ParentMap(Stmt *S) : Impl(nullptr) {
   if (S) {
     MapTy *M = new MapTy();
     BuildParentMap(*M, S);
@@ -120,7 +120,7 @@
 Stmt* ParentMap::getParent(Stmt* S) const {
   MapTy* M = (MapTy*) Impl;
   MapTy::iterator I = M->find(S);
-  return I == M->end() ? 0 : I->second;
+  return I == M->end() ? nullptr : I->second;
 }
 
 Stmt *ParentMap::getParentIgnoreParens(Stmt *S) const {
@@ -146,7 +146,7 @@
 }
 
 Stmt *ParentMap::getOuterParenParent(Stmt *S) const {
-  Stmt *Paren = 0;
+  Stmt *Paren = nullptr;
   while (isa<ParenExpr>(S)) {
     Paren = S;
     S = getParent(S);
diff --git a/lib/AST/RawCommentList.cpp b/lib/AST/RawCommentList.cpp
index 1fa7cea..24b129a 100644
--- a/lib/AST/RawCommentList.cpp
+++ b/lib/AST/RawCommentList.cpp
@@ -95,10 +95,9 @@
   unsigned BeginOffset;
   unsigned EndOffset;
 
-  llvm::tie(BeginFileID, BeginOffset) =
+  std::tie(BeginFileID, BeginOffset) =
       SourceMgr.getDecomposedLoc(Range.getBegin());
-  llvm::tie(EndFileID, EndOffset) =
-      SourceMgr.getDecomposedLoc(Range.getEnd());
+  std::tie(EndFileID, EndOffset) = SourceMgr.getDecomposedLoc(Range.getEnd());
 
   const unsigned Length = EndOffset - BeginOffset;
   if (Length < 2)
@@ -252,3 +251,15 @@
     Comments.push_back(new (Allocator) RawComment(RC));
   }
 }
+
+void RawCommentList::addDeserializedComments(ArrayRef<RawComment *> DeserializedComments) {
+  std::vector<RawComment *> MergedComments;
+  MergedComments.reserve(Comments.size() + DeserializedComments.size());
+
+  std::merge(Comments.begin(), Comments.end(),
+             DeserializedComments.begin(), DeserializedComments.end(),
+             std::back_inserter(MergedComments),
+             BeforeThanCompare<RawComment>(SourceMgr));
+  std::swap(Comments, MergedComments);
+}
+
diff --git a/lib/AST/RecordLayout.cpp b/lib/AST/RecordLayout.cpp
index 71e44ec..b2c244e 100644
--- a/lib/AST/RecordLayout.cpp
+++ b/lib/AST/RecordLayout.cpp
@@ -21,19 +21,22 @@
   if (FieldOffsets)
     Ctx.Deallocate(FieldOffsets);
   if (CXXInfo) {
-    Ctx.Deallocate(CXXInfo);
     CXXInfo->~CXXRecordLayoutInfo();
+    Ctx.Deallocate(CXXInfo);
   }
   this->~ASTRecordLayout();
   Ctx.Deallocate(this);
 }
 
 ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, CharUnits size,
-                                 CharUnits alignment, CharUnits datasize,
+                                 CharUnits alignment, 
+                                 CharUnits requiredAlignment,
+                                 CharUnits datasize,
                                  const uint64_t *fieldoffsets,
                                  unsigned fieldcount)
-  : Size(size), DataSize(datasize), Alignment(alignment), FieldOffsets(0),
-    FieldCount(fieldcount), CXXInfo(0) {
+  : Size(size), DataSize(datasize), Alignment(alignment),
+    RequiredAlignment(requiredAlignment), FieldOffsets(nullptr),
+    FieldCount(fieldcount), CXXInfo(nullptr) {
   if (FieldCount > 0)  {
     FieldOffsets = new (Ctx) uint64_t[FieldCount];
     memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets));
@@ -43,21 +46,24 @@
 // Constructor for C++ records.
 ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx,
                                  CharUnits size, CharUnits alignment,
+                                 CharUnits requiredAlignment,
                                  bool hasOwnVFPtr, bool hasExtendableVFPtr,
                                  CharUnits vbptroffset,
                                  CharUnits datasize,
                                  const uint64_t *fieldoffsets,
                                  unsigned fieldcount,
                                  CharUnits nonvirtualsize,
-                                 CharUnits nonvirtualalign,
+                                 CharUnits nonvirtualalignment,
                                  CharUnits SizeOfLargestEmptySubobject,
                                  const CXXRecordDecl *PrimaryBase,
                                  bool IsPrimaryBaseVirtual,
                                  const CXXRecordDecl *BaseSharingVBPtr,
-                                 bool AlignAfterVBases,
+                                 bool HasZeroSizedSubObject,
+                                 bool LeadsWithZeroSizedBase,
                                  const BaseOffsetsMapTy& BaseOffsets,
                                  const VBaseOffsetsMapTy& VBaseOffsets)
-  : Size(size), DataSize(datasize), Alignment(alignment), FieldOffsets(0),
+  : Size(size), DataSize(datasize), Alignment(alignment),
+    RequiredAlignment(requiredAlignment), FieldOffsets(nullptr),
     FieldCount(fieldcount), CXXInfo(new (Ctx) CXXRecordLayoutInfo)
 {
   if (FieldCount > 0)  {
@@ -68,7 +74,7 @@
   CXXInfo->PrimaryBase.setPointer(PrimaryBase);
   CXXInfo->PrimaryBase.setInt(IsPrimaryBaseVirtual);
   CXXInfo->NonVirtualSize = nonvirtualsize;
-  CXXInfo->NonVirtualAlign = nonvirtualalign;
+  CXXInfo->NonVirtualAlignment = nonvirtualalignment;
   CXXInfo->SizeOfLargestEmptySubobject = SizeOfLargestEmptySubobject;
   CXXInfo->BaseOffsets = BaseOffsets;
   CXXInfo->VBaseOffsets = VBaseOffsets;
@@ -76,7 +82,8 @@
   CXXInfo->VBPtrOffset = vbptroffset;
   CXXInfo->HasExtendableVFPtr = hasExtendableVFPtr;
   CXXInfo->BaseSharingVBPtr = BaseSharingVBPtr;
-  CXXInfo->AlignAfterVBases = AlignAfterVBases;
+  CXXInfo->HasZeroSizedSubObject = HasZeroSizedSubObject;
+  CXXInfo->LeadsWithZeroSizedBase = LeadsWithZeroSizedBase;
 
 
 #ifndef NDEBUG
diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp
index 524c3ba..b3deeba 100644
--- a/lib/AST/RecordLayoutBuilder.cpp
+++ b/lib/AST/RecordLayoutBuilder.cpp
@@ -65,7 +65,7 @@
   const CXXRecordDecl *Class;
 
   /// EmptyClassOffsets - A map from offsets to empty record decls.
-  typedef SmallVector<const CXXRecordDecl *, 1> ClassVectorTy;
+  typedef llvm::TinyPtrVector<const CXXRecordDecl *> ClassVectorTy;
   typedef llvm::DenseMap<CharUnits, ClassVectorTy> EmptyClassOffsetsMapTy;
   EmptyClassOffsetsMapTy EmptyClassOffsets;
   
@@ -140,10 +140,8 @@
 
 void EmptySubobjectMap::ComputeEmptySubobjectSizes() {
   // Check the bases.
-  for (CXXRecordDecl::base_class_const_iterator I = Class->bases_begin(),
-       E = Class->bases_end(); I != E; ++I) {
-    const CXXRecordDecl *BaseDecl =
-      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+  for (const CXXBaseSpecifier &Base : Class->bases()) {
+    const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
 
     CharUnits EmptySize;
     const ASTRecordLayout &Layout = Context.getASTRecordLayout(BaseDecl);
@@ -160,18 +158,16 @@
   }
 
   // Check the fields.
-  for (CXXRecordDecl::field_iterator I = Class->field_begin(),
-       E = Class->field_end(); I != E; ++I) {
-
+  for (const FieldDecl *FD : Class->fields()) {
     const RecordType *RT =
-      Context.getBaseElementType(I->getType())->getAs<RecordType>();
+        Context.getBaseElementType(FD->getType())->getAs<RecordType>();
 
     // We only care about record types.
     if (!RT)
       continue;
 
     CharUnits EmptySize;
-    const CXXRecordDecl *MemberDecl = cast<CXXRecordDecl>(RT->getDecl());
+    const CXXRecordDecl *MemberDecl = RT->getAsCXXRecordDecl();
     const ASTRecordLayout &Layout = Context.getASTRecordLayout(MemberDecl);
     if (MemberDecl->isEmpty()) {
       // If the class decl is empty, get its size.
@@ -196,8 +192,8 @@
   EmptyClassOffsetsMapTy::const_iterator I = EmptyClassOffsets.find(Offset);
   if (I == EmptyClassOffsets.end())
     return true;
-  
-  const ClassVectorTy& Classes = I->second;
+
+  const ClassVectorTy &Classes = I->second;
   if (std::find(Classes.begin(), Classes.end(), RD) == Classes.end())
     return true;
 
@@ -213,7 +209,7 @@
 
   // If we have empty structures inside a union, we can assign both
   // the same offset. Just avoid pushing them twice in the list.
-  ClassVectorTy& Classes = EmptyClassOffsets[Offset];
+  ClassVectorTy &Classes = EmptyClassOffsets[Offset];
   if (std::find(Classes.begin(), Classes.end(), RD) != Classes.end())
     return;
   
@@ -237,8 +233,7 @@
 
   // Traverse all non-virtual bases.
   const ASTRecordLayout &Layout = Context.getASTRecordLayout(Info->Class);
-  for (unsigned I = 0, E = Info->Bases.size(); I != E; ++I) {
-    BaseSubobjectInfo* Base = Info->Bases[I];
+  for (const BaseSubobjectInfo *Base : Info->Bases) {
     if (Base->IsVirtual)
       continue;
 
@@ -263,12 +258,12 @@
        E = Info->Class->field_end(); I != E; ++I, ++FieldNo) {
     if (I->isBitField())
       continue;
-  
+
     CharUnits FieldOffset = Offset + getFieldOffset(Layout, FieldNo);
     if (!CanPlaceFieldSubobjectAtOffset(*I, FieldOffset))
       return false;
   }
-  
+
   return true;
 }
 
@@ -288,8 +283,7 @@
 
   // Traverse all non-virtual bases.
   const ASTRecordLayout &Layout = Context.getASTRecordLayout(Info->Class);
-  for (unsigned I = 0, E = Info->Bases.size(); I != E; ++I) {
-    BaseSubobjectInfo* Base = Info->Bases[I];
+  for (const BaseSubobjectInfo *Base : Info->Bases) {
     if (Base->IsVirtual)
       continue;
 
@@ -348,13 +342,11 @@
   const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
 
   // Traverse all non-virtual bases.
-  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
-       E = RD->bases_end(); I != E; ++I) {
-    if (I->isVirtual())
+  for (const CXXBaseSpecifier &Base : RD->bases()) {
+    if (Base.isVirtual())
       continue;
 
-    const CXXRecordDecl *BaseDecl =
-      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+    const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
 
     CharUnits BaseOffset = Offset + Layout.getBaseClassOffset(BaseDecl);
     if (!CanPlaceFieldSubobjectAtOffset(BaseDecl, Class, BaseOffset))
@@ -363,11 +355,9 @@
 
   if (RD == Class) {
     // This is the most derived class, traverse virtual bases as well.
-    for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(),
-         E = RD->vbases_end(); I != E; ++I) {
-      const CXXRecordDecl *VBaseDecl =
-        cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
-      
+    for (const CXXBaseSpecifier &Base : RD->vbases()) {
+      const CXXRecordDecl *VBaseDecl = Base.getType()->getAsCXXRecordDecl();
+
       CharUnits VBaseOffset = Offset + Layout.getVBaseClassOffset(VBaseDecl);
       if (!CanPlaceFieldSubobjectAtOffset(VBaseDecl, Class, VBaseOffset))
         return false;
@@ -399,10 +389,8 @@
     return true;
   
   QualType T = FD->getType();
-  if (const RecordType *RT = T->getAs<RecordType>()) {
-    const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+  if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
     return CanPlaceFieldSubobjectAtOffset(RD, RD, Offset);
-  }
 
   // If we have an array type we need to look at every element.
   if (const ConstantArrayType *AT = Context.getAsConstantArrayType(T)) {
@@ -410,8 +398,8 @@
     const RecordType *RT = ElemTy->getAs<RecordType>();
     if (!RT)
       return true;
-  
-    const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+
+    const CXXRecordDecl *RD = RT->getAsCXXRecordDecl();
     const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
 
     uint64_t NumElements = Context.getConstantArrayElementCount(AT);
@@ -460,13 +448,11 @@
   const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
 
   // Traverse all non-virtual bases.
-  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
-       E = RD->bases_end(); I != E; ++I) {
-    if (I->isVirtual())
+  for (const CXXBaseSpecifier &Base : RD->bases()) {
+    if (Base.isVirtual())
       continue;
 
-    const CXXRecordDecl *BaseDecl =
-      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+    const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
 
     CharUnits BaseOffset = Offset + Layout.getBaseClassOffset(BaseDecl);
     UpdateEmptyFieldSubobjects(BaseDecl, Class, BaseOffset);
@@ -474,11 +460,9 @@
 
   if (RD == Class) {
     // This is the most derived class, traverse virtual bases as well.
-    for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(),
-         E = RD->vbases_end(); I != E; ++I) {
-      const CXXRecordDecl *VBaseDecl =
-      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
-      
+    for (const CXXBaseSpecifier &Base : RD->vbases()) {
+      const CXXRecordDecl *VBaseDecl = Base.getType()->getAsCXXRecordDecl();
+
       CharUnits VBaseOffset = Offset + Layout.getVBaseClassOffset(VBaseDecl);
       UpdateEmptyFieldSubobjects(VBaseDecl, Class, VBaseOffset);
     }
@@ -500,8 +484,7 @@
 void EmptySubobjectMap::UpdateEmptyFieldSubobjects(const FieldDecl *FD,
                                                    CharUnits Offset) {
   QualType T = FD->getType();
-  if (const RecordType *RT = T->getAs<RecordType>()) {
-    const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+  if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl()) {
     UpdateEmptyFieldSubobjects(RD, RD, Offset);
     return;
   }
@@ -512,8 +495,8 @@
     const RecordType *RT = ElemTy->getAs<RecordType>();
     if (!RT)
       return;
-    
-    const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+
+    const CXXRecordDecl *RD = RT->getAsCXXRecordDecl();
     const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
     
     uint64_t NumElements = Context.getConstantArrayElementCount(AT);
@@ -649,9 +632,9 @@
       MaxFieldAlignment(CharUnits::Zero()), 
       DataSize(0), NonVirtualSize(CharUnits::Zero()), 
       NonVirtualAlignment(CharUnits::One()), 
-      PrimaryBase(0), PrimaryBaseIsVirtual(false),
+      PrimaryBase(nullptr), PrimaryBaseIsVirtual(false),
       HasOwnVFPtr(false),
-      FirstNearlyEmptyVBase(0) { }
+      FirstNearlyEmptyVBase(nullptr) {}
 
   /// Reset this RecordLayoutBuilder to a fresh state, using the given
   /// alignment as the initial alignment.  This is used for the
@@ -783,16 +766,14 @@
 
 void
 RecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD) {
-  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
-         E = RD->bases_end(); I != E; ++I) {
-    assert(!I->getType()->isDependentType() &&
+  for (const auto &I : RD->bases()) {
+    assert(!I.getType()->isDependentType() &&
            "Cannot layout class with dependent bases.");
 
-    const CXXRecordDecl *Base =
-      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+    const CXXRecordDecl *Base = I.getType()->getAsCXXRecordDecl();
 
     // Check if this is a nearly empty virtual base.
-    if (I->isVirtual() && Context.isNearlyEmpty(Base)) {
+    if (I.isVirtual() && Context.isNearlyEmpty(Base)) {
       // If it's not an indirect primary base, then we've found our primary
       // base.
       if (!IndirectPrimaryBases.count(Base)) {
@@ -825,14 +806,12 @@
   // If the record has a dynamic base class, attempt to choose a primary base
   // class. It is the first (in direct base class order) non-virtual dynamic
   // base class, if one exists.
-  for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
-         e = RD->bases_end(); i != e; ++i) {
+  for (const auto &I : RD->bases()) {
     // Ignore virtual bases.
-    if (i->isVirtual())
+    if (I.isVirtual())
       continue;
 
-    const CXXRecordDecl *Base =
-      cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
+    const CXXRecordDecl *Base = I.getType()->getAsCXXRecordDecl();
 
     if (Base->isDynamicClass()) {
       // We found it.
@@ -885,11 +864,11 @@
   
   Info->Class = RD;
   Info->IsVirtual = IsVirtual;
-  Info->Derived = 0;
-  Info->PrimaryVirtualBaseInfo = 0;
-  
-  const CXXRecordDecl *PrimaryVirtualBase = 0;
-  BaseSubobjectInfo *PrimaryVirtualBaseInfo = 0;
+  Info->Derived = nullptr;
+  Info->PrimaryVirtualBaseInfo = nullptr;
+
+  const CXXRecordDecl *PrimaryVirtualBase = nullptr;
+  BaseSubobjectInfo *PrimaryVirtualBaseInfo = nullptr;
 
   // Check if this base has a primary virtual base.
   if (RD->getNumVBases()) {
@@ -906,8 +885,8 @@
         if (PrimaryVirtualBaseInfo->Derived) {
           // We did have info about this primary base, and it turns out that it
           // has already been claimed as a primary virtual base for another
-          // base. 
-          PrimaryVirtualBase = 0;        
+          // base.
+          PrimaryVirtualBase = nullptr;
         } else {
           // We can claim this base as our primary base.
           Info->PrimaryVirtualBaseInfo = PrimaryVirtualBaseInfo;
@@ -918,13 +897,11 @@
   }
 
   // Now go through all direct bases.
-  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
-       E = RD->bases_end(); I != E; ++I) {
-    bool IsVirtual = I->isVirtual();
-    
-    const CXXRecordDecl *BaseDecl =
-      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
-    
+  for (const auto &I : RD->bases()) {
+    bool IsVirtual = I.isVirtual();
+
+    const CXXRecordDecl *BaseDecl = I.getType()->getAsCXXRecordDecl();
+
     Info->Bases.push_back(ComputeBaseSubobjectInfo(BaseDecl, IsVirtual, Info));
   }
   
@@ -944,15 +921,14 @@
 }
 
 void RecordLayoutBuilder::ComputeBaseSubobjectInfo(const CXXRecordDecl *RD) {
-  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
-       E = RD->bases_end(); I != E; ++I) {
-    bool IsVirtual = I->isVirtual();
+  for (const auto &I : RD->bases()) {
+    bool IsVirtual = I.isVirtual();
 
-    const CXXRecordDecl *BaseDecl =
-      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
-    
+    const CXXRecordDecl *BaseDecl = I.getType()->getAsCXXRecordDecl();
+
     // Compute the base subobject info for this base.
-    BaseSubobjectInfo *Info = ComputeBaseSubobjectInfo(BaseDecl, IsVirtual, 0);
+    BaseSubobjectInfo *Info = ComputeBaseSubobjectInfo(BaseDecl, IsVirtual,
+                                                       nullptr);
 
     if (IsVirtual) {
       // ComputeBaseInfo has already added this base for us.
@@ -999,8 +975,8 @@
       // If the primary virtual base was a primary virtual base of some other
       // base class we'll have to steal it.
       BaseSubobjectInfo *PrimaryBaseInfo = VirtualBaseInfo.lookup(PrimaryBase);
-      PrimaryBaseInfo->Derived = 0;
-      
+      PrimaryBaseInfo->Derived = nullptr;
+
       // We have a virtual primary base, insert it as an indirect primary base.
       IndirectPrimaryBases.insert(PrimaryBase);
 
@@ -1033,15 +1009,13 @@
   }
 
   // Now lay out the non-virtual bases.
-  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
-         E = RD->bases_end(); I != E; ++I) {
+  for (const auto &I : RD->bases()) {
 
     // Ignore virtual bases.
-    if (I->isVirtual())
+    if (I.isVirtual())
       continue;
 
-    const CXXRecordDecl *BaseDecl =
-      cast<CXXRecordDecl>(I->getType()->castAs<RecordType>()->getDecl());
+    const CXXRecordDecl *BaseDecl = I.getType()->getAsCXXRecordDecl();
 
     // Skip the primary base, because we've already laid it out.  The
     // !PrimaryBaseIsVirtual check is required because we might have a
@@ -1093,8 +1067,7 @@
 
   // Now go through all direct non-virtual bases.
   const ASTRecordLayout &Layout = Context.getASTRecordLayout(Info->Class);
-  for (unsigned I = 0, E = Info->Bases.size(); I != E; ++I) {
-    const BaseSubobjectInfo *Base = Info->Bases[I];
+  for (const BaseSubobjectInfo *Base : Info->Bases) {
     if (Base->IsVirtual)
       continue;
 
@@ -1118,15 +1091,13 @@
     PrimaryBaseIsVirtual = Layout.isPrimaryBaseVirtual();
   }
 
-  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
-         E = RD->bases_end(); I != E; ++I) {
-    assert(!I->getType()->isDependentType() &&
+  for (const CXXBaseSpecifier &Base : RD->bases()) {
+    assert(!Base.getType()->isDependentType() &&
            "Cannot layout class with dependent bases.");
 
-    const CXXRecordDecl *BaseDecl =
-      cast<CXXRecordDecl>(I->getType()->castAs<RecordType>()->getDecl());
+    const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
 
-    if (I->isVirtual()) {
+    if (Base.isVirtual()) {
       if (PrimaryBase != BaseDecl || !PrimaryBaseIsVirtual) {
         bool IndirectPrimaryBase = IndirectPrimaryBases.count(BaseDecl);
 
@@ -1191,7 +1162,7 @@
     }
   }
   
-  CharUnits UnpackedBaseAlign = Layout.getNonVirtualAlign();
+  CharUnits UnpackedBaseAlign = Layout.getNonVirtualAlignment();
   CharUnits BaseAlign = (Packed) ? CharUnits::One() : UnpackedBaseAlign;
  
   // If we have an empty base class, try to place it at offset 0.
@@ -1326,22 +1297,18 @@
 
 #ifndef NDEBUG
   // Check that we have base offsets for all bases.
-  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
-       E = RD->bases_end(); I != E; ++I) {
-    if (I->isVirtual())
+  for (const CXXBaseSpecifier &Base : RD->bases()) {
+    if (Base.isVirtual())
       continue;
 
-    const CXXRecordDecl *BaseDecl =
-      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+    const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
 
     assert(Bases.count(BaseDecl) && "Did not find base offset!");
   }
 
   // And all virtual bases.
-  for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(),
-       E = RD->vbases_end(); I != E; ++I) {
-    const CXXRecordDecl *BaseDecl =
-      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+  for (const CXXBaseSpecifier &Base : RD->vbases()) {
+    const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
 
     assert(VBases.count(BaseDecl) && "Did not find base offset!");
   }
@@ -1374,9 +1341,8 @@
 void RecordLayoutBuilder::LayoutFields(const RecordDecl *D) {
   // Layout each field, for now, just sequentially, respecting alignment.  In
   // the future, this will need to be tweakable by targets.
-  for (RecordDecl::field_iterator Field = D->field_begin(),
-       FieldEnd = D->field_end(); Field != FieldEnd; ++Field)
-    LayoutField(*Field);
+  for (const auto *Field : D->fields())
+    LayoutField(Field);
 }
 
 void RecordLayoutBuilder::LayoutWideBitField(uint64_t FieldSize,
@@ -1396,14 +1362,13 @@
   };
 
   QualType Type;
-  for (unsigned I = 0, E = llvm::array_lengthof(IntegralPODTypes);
-       I != E; ++I) {
-    uint64_t Size = Context.getTypeSize(IntegralPODTypes[I]);
+  for (const QualType &QT : IntegralPODTypes) {
+    uint64_t Size = Context.getTypeSize(QT);
 
     if (Size > FieldSize)
       break;
 
-    Type = IntegralPODTypes[I];
+    Type = QT;
   }
   assert(!Type.isNull() && "Did not find a type!");
 
@@ -1452,127 +1417,224 @@
   uint64_t TypeSize = FieldInfo.first;
   unsigned FieldAlign = FieldInfo.second;
 
+  // UnfilledBitsInLastUnit is the difference between the end of the
+  // last allocated bitfield (i.e. the first bit offset available for
+  // bitfields) and the end of the current data size in bits (i.e. the
+  // first bit offset available for non-bitfields).  The current data
+  // size in bits is always a multiple of the char size; additionally,
+  // for ms_struct records it's also a multiple of the
+  // LastBitfieldTypeSize (if set).
+
+  // The struct-layout algorithm is dictated by the platform ABI,
+  // which in principle could use almost any rules it likes.  In
+  // practice, UNIXy targets tend to inherit the algorithm described
+  // in the System V generic ABI.  The basic bitfield layout rule in
+  // System V is to place bitfields at the next available bit offset
+  // where the entire bitfield would fit in an aligned storage unit of
+  // the declared type; it's okay if an earlier or later non-bitfield
+  // is allocated in the same storage unit.  However, some targets
+  // (those that !useBitFieldTypeAlignment(), e.g. ARM APCS) don't
+  // require this storage unit to be aligned, and therefore always put
+  // the bitfield at the next available bit offset.
+
+  // ms_struct basically requests a complete replacement of the
+  // platform ABI's struct-layout algorithm, with the high-level goal
+  // of duplicating MSVC's layout.  For non-bitfields, this follows
+  // the the standard algorithm.  The basic bitfield layout rule is to
+  // allocate an entire unit of the bitfield's declared type
+  // (e.g. 'unsigned long'), then parcel it up among successive
+  // bitfields whose declared types have the same size, making a new
+  // unit as soon as the last can no longer store the whole value.
+  // Since it completely replaces the platform ABI's algorithm,
+  // settings like !useBitFieldTypeAlignment() do not apply.
+
+  // A zero-width bitfield forces the use of a new storage unit for
+  // later bitfields.  In general, this occurs by rounding up the
+  // current size of the struct as if the algorithm were about to
+  // place a non-bitfield of the field's formal type.  Usually this
+  // does not change the alignment of the struct itself, but it does
+  // on some targets (those that useZeroLengthBitfieldAlignment(),
+  // e.g. ARM).  In ms_struct layout, zero-width bitfields are
+  // ignored unless they follow a non-zero-width bitfield.
+
+  // A field alignment restriction (e.g. from #pragma pack) or
+  // specification (e.g. from __attribute__((aligned))) changes the
+  // formal alignment of the field.  For System V, this alters the
+  // required alignment of the notional storage unit that must contain
+  // the bitfield.  For ms_struct, this only affects the placement of
+  // new storage units.  In both cases, the effect of #pragma pack is
+  // ignored on zero-width bitfields.
+
+  // On System V, a packed field (e.g. from #pragma pack or
+  // __attribute__((packed))) always uses the next available bit
+  // offset.
+
+  // In an ms_struct struct, the alignment of a fundamental type is
+  // always equal to its size.  This is necessary in order to mimic
+  // the i386 alignment rules on targets which might not fully align
+  // all types (e.g. Darwin PPC32, where alignof(long long) == 4).
+
+  // First, some simple bookkeeping to perform for ms_struct structs.
   if (IsMsStruct) {
-    // The field alignment for integer types in ms_struct structs is
-    // always the size.
+    // The field alignment for integer types is always the size.
     FieldAlign = TypeSize;
-    // Ignore zero-length bitfields after non-bitfields in ms_struct structs.
-    if (!FieldSize && !LastBitfieldTypeSize)
-      FieldAlign = 1;
-    // If a bitfield is followed by a bitfield of a different size, don't
-    // pack the bits together in ms_struct structs.
+
+    // If the previous field was not a bitfield, or was a bitfield
+    // with a different storage unit size, we're done with that
+    // storage unit.
     if (LastBitfieldTypeSize != TypeSize) {
+      // Also, ignore zero-length bitfields after non-bitfields.
+      if (!LastBitfieldTypeSize && !FieldSize)
+        FieldAlign = 1;
+
       UnfilledBitsInLastUnit = 0;
       LastBitfieldTypeSize = 0;
     }
   }
 
-  uint64_t UnpaddedFieldOffset = getDataSizeInBits() - UnfilledBitsInLastUnit;
-  uint64_t FieldOffset = IsUnion ? 0 : UnpaddedFieldOffset;
-
-  bool ZeroLengthBitfield = false;
-  if (!Context.getTargetInfo().useBitFieldTypeAlignment() &&
-      Context.getTargetInfo().useZeroLengthBitfieldAlignment() &&
-      FieldSize == 0) {
-    // The alignment of a zero-length bitfield affects the alignment
-    // of the next member.  The alignment is the max of the zero 
-    // length bitfield's alignment and a target specific fixed value.
-    ZeroLengthBitfield = true;
-    unsigned ZeroLengthBitfieldBoundary =
-      Context.getTargetInfo().getZeroLengthBitfieldBoundary();
-    if (ZeroLengthBitfieldBoundary > FieldAlign)
-      FieldAlign = ZeroLengthBitfieldBoundary;
-  }
-
+  // If the field is wider than its declared type, it follows
+  // different rules in all cases.
   if (FieldSize > TypeSize) {
     LayoutWideBitField(FieldSize, TypeSize, FieldPacked, D);
     return;
   }
 
-  // The align if the field is not packed. This is to check if the attribute
-  // was unnecessary (-Wpacked).
+  // Compute the next available bit offset.
+  uint64_t FieldOffset =
+    IsUnion ? 0 : (getDataSizeInBits() - UnfilledBitsInLastUnit);
+
+  // Handle targets that don't honor bitfield type alignment.
+  if (!IsMsStruct && !Context.getTargetInfo().useBitFieldTypeAlignment()) {
+    // Some such targets do honor it on zero-width bitfields.
+    if (FieldSize == 0 &&
+        Context.getTargetInfo().useZeroLengthBitfieldAlignment()) {
+      // The alignment to round up to is the max of the field's natural
+      // alignment and a target-specific fixed value (sometimes zero).
+      unsigned ZeroLengthBitfieldBoundary =
+        Context.getTargetInfo().getZeroLengthBitfieldBoundary();
+      FieldAlign = std::max(FieldAlign, ZeroLengthBitfieldBoundary);
+
+    // If that doesn't apply, just ignore the field alignment.
+    } else {
+      FieldAlign = 1;
+    }
+  }
+
+  // Remember the alignment we would have used if the field were not packed.
   unsigned UnpackedFieldAlign = FieldAlign;
-  uint64_t UnpackedFieldOffset = FieldOffset;
-  if (!Context.getTargetInfo().useBitFieldTypeAlignment() && !ZeroLengthBitfield)
-    UnpackedFieldAlign = 1;
 
-  if (FieldPacked || 
-      (!Context.getTargetInfo().useBitFieldTypeAlignment() && !ZeroLengthBitfield))
+  // Ignore the field alignment if the field is packed unless it has zero-size.
+  if (!IsMsStruct && FieldPacked && FieldSize != 0)
     FieldAlign = 1;
-  FieldAlign = std::max(FieldAlign, D->getMaxAlignment());
-  UnpackedFieldAlign = std::max(UnpackedFieldAlign, D->getMaxAlignment());
 
-  // The maximum field alignment overrides the aligned attribute.
-  if (!MaxFieldAlignment.isZero() && FieldSize != 0) {
+  // But, if there's an 'aligned' attribute on the field, honor that.
+  if (unsigned ExplicitFieldAlign = D->getMaxAlignment()) {
+    FieldAlign = std::max(FieldAlign, ExplicitFieldAlign);
+    UnpackedFieldAlign = std::max(UnpackedFieldAlign, ExplicitFieldAlign);
+  }
+
+  // But, if there's a #pragma pack in play, that takes precedent over
+  // even the 'aligned' attribute, for non-zero-width bitfields.
+  if (!MaxFieldAlignment.isZero() && FieldSize) {
     unsigned MaxFieldAlignmentInBits = Context.toBits(MaxFieldAlignment);
     FieldAlign = std::min(FieldAlign, MaxFieldAlignmentInBits);
     UnpackedFieldAlign = std::min(UnpackedFieldAlign, MaxFieldAlignmentInBits);
   }
 
-  // ms_struct bitfields always have to start at a round alignment.
-  if (IsMsStruct && !LastBitfieldTypeSize) {
-    FieldOffset = llvm::RoundUpToAlignment(FieldOffset, FieldAlign);
-    UnpackedFieldOffset = llvm::RoundUpToAlignment(UnpackedFieldOffset,
-                                                   UnpackedFieldAlign);
+  // For purposes of diagnostics, we're going to simultaneously
+  // compute the field offsets that we would have used if we weren't
+  // adding any alignment padding or if the field weren't packed.
+  uint64_t UnpaddedFieldOffset = FieldOffset;
+  uint64_t UnpackedFieldOffset = FieldOffset;
+
+  // Check if we need to add padding to fit the bitfield within an
+  // allocation unit with the right size and alignment.  The rules are
+  // somewhat different here for ms_struct structs.
+  if (IsMsStruct) {
+    // If it's not a zero-width bitfield, and we can fit the bitfield
+    // into the active storage unit (and we haven't already decided to
+    // start a new storage unit), just do so, regardless of any other
+    // other consideration.  Otherwise, round up to the right alignment.
+    if (FieldSize == 0 || FieldSize > UnfilledBitsInLastUnit) {
+      FieldOffset = llvm::RoundUpToAlignment(FieldOffset, FieldAlign);
+      UnpackedFieldOffset = llvm::RoundUpToAlignment(UnpackedFieldOffset,
+                                                     UnpackedFieldAlign);
+      UnfilledBitsInLastUnit = 0;
+    }
+
+  } else {
+    // #pragma pack, with any value, suppresses the insertion of padding.
+    bool AllowPadding = MaxFieldAlignment.isZero();
+
+    // Compute the real offset.
+    if (FieldSize == 0 || 
+        (AllowPadding &&
+         (FieldOffset & (FieldAlign-1)) + FieldSize > TypeSize)) {
+      FieldOffset = llvm::RoundUpToAlignment(FieldOffset, FieldAlign);
+    }
+
+    // Repeat the computation for diagnostic purposes.
+    if (FieldSize == 0 ||
+        (AllowPadding &&
+         (UnpackedFieldOffset & (UnpackedFieldAlign-1)) + FieldSize > TypeSize))
+      UnpackedFieldOffset = llvm::RoundUpToAlignment(UnpackedFieldOffset,
+                                                     UnpackedFieldAlign);
   }
 
-  // Check if we need to add padding to give the field the correct alignment.
-  if (FieldSize == 0 || 
-      (MaxFieldAlignment.isZero() &&
-       (FieldOffset & (FieldAlign-1)) + FieldSize > TypeSize))
-    FieldOffset = llvm::RoundUpToAlignment(FieldOffset, FieldAlign);
-
-  if (FieldSize == 0 ||
-      (MaxFieldAlignment.isZero() &&
-       (UnpackedFieldOffset & (UnpackedFieldAlign-1)) + FieldSize > TypeSize))
-    UnpackedFieldOffset = llvm::RoundUpToAlignment(UnpackedFieldOffset,
-                                                   UnpackedFieldAlign);
-
-  // Padding members don't affect overall alignment, unless zero length bitfield
-  // alignment is enabled.
-  if (!D->getIdentifier() &&
-      !Context.getTargetInfo().useZeroLengthBitfieldAlignment() &&
-      !IsMsStruct)
-    FieldAlign = UnpackedFieldAlign = 1;
-
+  // If we're using external layout, give the external layout a chance
+  // to override this information.
   if (ExternalLayout)
     FieldOffset = updateExternalFieldOffset(D, FieldOffset);
 
-  // Place this field at the current location.
+  // Okay, place the bitfield at the calculated offset.
   FieldOffsets.push_back(FieldOffset);
 
+  // Bookkeeping:
+
+  // Anonymous members don't affect the overall record alignment,
+  // except on targets where they do.
+  if (!IsMsStruct &&
+      !Context.getTargetInfo().useZeroLengthBitfieldAlignment() &&
+      !D->getIdentifier())
+    FieldAlign = UnpackedFieldAlign = 1;
+
+  // Diagnose differences in layout due to padding or packing.
   if (!ExternalLayout)
     CheckFieldPadding(FieldOffset, UnpaddedFieldOffset, UnpackedFieldOffset,
                       UnpackedFieldAlign, FieldPacked, D);
 
   // Update DataSize to include the last byte containing (part of) the bitfield.
+
+  // For unions, this is just a max operation, as usual.
   if (IsUnion) {
     // FIXME: I think FieldSize should be TypeSize here.
     setDataSize(std::max(getDataSizeInBits(), FieldSize));
-  } else {
-    if (IsMsStruct && FieldSize) {
-      // Under ms_struct, a bitfield always takes up space equal to the size
-      // of the type.  We can't just change the alignment computation on the
-      // other codepath because of the way this interacts with #pragma pack:
-      // in a packed struct, we need to allocate misaligned space in the
-      // struct to hold the bitfield.
-      if (!UnfilledBitsInLastUnit) {
-        setDataSize(FieldOffset + TypeSize);
-        UnfilledBitsInLastUnit = TypeSize - FieldSize;
-      } else if (UnfilledBitsInLastUnit < FieldSize) {
-        setDataSize(getDataSizeInBits() + TypeSize);
-        UnfilledBitsInLastUnit = TypeSize - FieldSize;
-      } else {
-        UnfilledBitsInLastUnit -= FieldSize;
-      }
-      LastBitfieldTypeSize = TypeSize;
-    } else {
-      uint64_t NewSizeInBits = FieldOffset + FieldSize;
-      uint64_t BitfieldAlignment = Context.getTargetInfo().getCharAlign();
-      setDataSize(llvm::RoundUpToAlignment(NewSizeInBits, BitfieldAlignment));
-      UnfilledBitsInLastUnit = getDataSizeInBits() - NewSizeInBits;
-      LastBitfieldTypeSize = 0;
+
+  // For non-zero-width bitfields in ms_struct structs, allocate a new
+  // storage unit if necessary.
+  } else if (IsMsStruct && FieldSize) {
+    // We should have cleared UnfilledBitsInLastUnit in every case
+    // where we changed storage units.
+    if (!UnfilledBitsInLastUnit) {
+      setDataSize(FieldOffset + TypeSize);
+      UnfilledBitsInLastUnit = TypeSize;
     }
+    UnfilledBitsInLastUnit -= FieldSize;
+    LastBitfieldTypeSize = TypeSize;
+
+  // Otherwise, bump the data size up to include the bitfield,
+  // including padding up to char alignment, and then remember how
+  // bits we didn't use.
+  } else {
+    uint64_t NewSizeInBits = FieldOffset + FieldSize;
+    uint64_t CharAlignment = Context.getTargetInfo().getCharAlign();
+    setDataSize(llvm::RoundUpToAlignment(NewSizeInBits, CharAlignment));
+    UnfilledBitsInLastUnit = getDataSizeInBits() - NewSizeInBits;
+
+    // The only time we can get here for an ms_struct is if this is a
+    // zero-width bitfield, which doesn't count as anything for the
+    // purposes of unfilled bits.
+    LastBitfieldTypeSize = 0;
   }
 
   // Update the size.
@@ -1870,28 +1932,26 @@
                                                const CXXRecordDecl *RD) {
   // If a class isn't polymorphic it doesn't have a key function.
   if (!RD->isPolymorphic())
-    return 0;
+    return nullptr;
 
   // A class that is not externally visible doesn't have a key function. (Or
   // at least, there's no point to assigning a key function to such a class;
   // this doesn't affect the ABI.)
   if (!RD->isExternallyVisible())
-    return 0;
+    return nullptr;
 
-  // Template instantiations don't have key functions,see Itanium C++ ABI 5.2.6.
+  // Template instantiations don't have key functions per Itanium C++ ABI 5.2.6.
   // Same behavior as GCC.
   TemplateSpecializationKind TSK = RD->getTemplateSpecializationKind();
   if (TSK == TSK_ImplicitInstantiation ||
+      TSK == TSK_ExplicitInstantiationDeclaration ||
       TSK == TSK_ExplicitInstantiationDefinition)
-    return 0;
+    return nullptr;
 
   bool allowInlineFunctions =
     Context.getTargetInfo().getCXXABI().canKeyFunctionBeInline();
 
-  for (CXXRecordDecl::method_iterator I = RD->method_begin(),
-         E = RD->method_end(); I != E; ++I) {
-    const CXXMethodDecl *MD = *I;
-
+  for (const CXXMethodDecl *MD : RD->methods()) {
     if (!MD->isVirtual())
       continue;
 
@@ -1924,7 +1984,7 @@
     return MD;
   }
 
-  return 0;
+  return nullptr;
 }
 
 DiagnosticBuilder
@@ -1979,48 +2039,101 @@
 }
 
 // This section contains an implementation of struct layout that is, up to the
-// included tests, compatible with cl.exe (2012).  The layout produced is
+// included tests, compatible with cl.exe (2013).  The layout produced is
 // significantly different than those produced by the Itanium ABI.  Here we note
 // the most important differences.
 //
 // * The alignment of bitfields in unions is ignored when computing the
 //   alignment of the union.
-// * The existance of zero-width bitfield that occurs after anything other than
+// * The existence of zero-width bitfield that occurs after anything other than
 //   a non-zero length bitfield is ignored.
+// * There is no explicit primary base for the purposes of layout.  All bases
+//   with vfptrs are laid out first, followed by all bases without vfptrs.
 // * The Itanium equivalent vtable pointers are split into a vfptr (virtual
 //   function pointer) and a vbptr (virtual base pointer).  They can each be
 //   shared with a, non-virtual bases. These bases need not be the same.  vfptrs
-//   always occur at offset 0.  vbptrs can occur at an
-//   arbitrary offset and are placed after non-virtual bases but before fields.
+//   always occur at offset 0.  vbptrs can occur at an arbitrary offset and are
+//   placed after the lexiographically last non-virtual base.  This placement
+//   is always before fields but can be in the middle of the non-virtual bases
+//   due to the two-pass layout scheme for non-virtual-bases.
 // * Virtual bases sometimes require a 'vtordisp' field that is laid out before
 //   the virtual base and is used in conjunction with virtual overrides during
-//   construction and destruction.
-// * vfptrs are allocated in a block of memory equal to the alignment of the
-//   fields and non-virtual bases at offset 0 in 32 bit mode and in a pointer
-//   sized block of memory in 64 bit mode.
-// * vbptrs are allocated in a block of memory equal to the alignment of the
-//   fields and non-virtual bases.  This block is at a potentially unaligned
-//   offset.  If the allocation slot is unaligned and the alignment is less than
-//   or equal to the pointer size, additional space is allocated so that the
-//   pointer can be aligned properly.  This causes very strange effects on the
-//   placement of objects after the allocated block. (see the code).
+//   construction and destruction.  This is always a 4 byte value and is used as
+//   an alternative to constructor vtables.
 // * vtordisps are allocated in a block of memory with size and alignment equal
 //   to the alignment of the completed structure (before applying __declspec(
 //   align())).  The vtordisp always occur at the end of the allocation block,
 //   immediately prior to the virtual base.
-// * The last zero sized non-virtual base is allocated after the placement of
-//   vbptr if one exists and can be placed at the end of the struct, potentially
-//   aliasing either the first member or another struct allocated after this
-//   one.
-// * The last zero size virtual base may be placed at the end of the struct.
-//   and can potentially alias a zero sized type in the next struct.
-// * If the last field is a non-zero length bitfield and we have any virtual
-//   bases then some extra padding is added before the virtual bases for no
-//   obvious reason.
-
+// * vfptrs are injected after all bases and fields have been laid out.  In
+//   order to guarantee proper alignment of all fields, the vfptr injection
+//   pushes all bases and fields back by the alignment imposed by those bases
+//   and fields.  This can potentially add a significant amount of padding.
+//   vfptrs are always injected at offset 0.
+// * vbptrs are injected after all bases and fields have been laid out.  In
+//   order to guarantee proper alignment of all fields, the vfptr injection
+//   pushes all bases and fields back by the alignment imposed by those bases
+//   and fields.  This can potentially add a significant amount of padding.
+//   vbptrs are injected immediately after the last non-virtual base as
+//   lexiographically ordered in the code.  If this site isn't pointer aligned
+//   the vbptr is placed at the next properly aligned location.  Enough padding
+//   is added to guarantee a fit.
+// * The last zero sized non-virtual base can be placed at the end of the
+//   struct (potentially aliasing another object), or may alias with the first
+//   field, even if they are of the same type.
+// * The last zero size virtual base may be placed at the end of the struct
+//   potentially aliasing another object.
+// * The ABI attempts to avoid aliasing of zero sized bases by adding padding
+//   between bases or vbases with specific properties.  The criteria for
+//   additional padding between two bases is that the first base is zero sized
+//   or ends with a zero sized subobject and the second base is zero sized or
+//   trails with a zero sized base or field (sharing of vfptrs can reorder the
+//   layout of the so the leading base is not always the first one declared).
+//   This rule does take into account fields that are not records, so padding
+//   will occur even if the last field is, e.g. an int. The padding added for
+//   bases is 1 byte.  The padding added between vbases depends on the alignment
+//   of the object but is at least 4 bytes (in both 32 and 64 bit modes).
+// * There is no concept of non-virtual alignment, non-virtual alignment and
+//   alignment are always identical.
+// * There is a distinction between alignment and required alignment.
+//   __declspec(align) changes the required alignment of a struct.  This
+//   alignment is _always_ obeyed, even in the presence of #pragma pack. A
+//   record inherites required alignment from all of its fields an bases.
+// * __declspec(align) on bitfields has the effect of changing the bitfield's
+//   alignment instead of its required alignment.  This is the only known way
+//   to make the alignment of a struct bigger than 8.  Interestingly enough
+//   this alignment is also immune to the effects of #pragma pack and can be
+//   used to create structures with large alignment under #pragma pack.
+//   However, because it does not impact required alignment, such a structure,
+//   when used as a field or base, will not be aligned if #pragma pack is
+//   still active at the time of use.
+//
+// Known incompatibilities:
+// * all: #pragma pack between fields in a record
+// * 2010 and back: If the last field in a record is a bitfield, every object
+//   laid out after the record will have extra padding inserted before it.  The
+//   extra padding will have size equal to the size of the storage class of the
+//   bitfield.  0 sized bitfields don't exhibit this behavior and the extra
+//   padding can be avoided by adding a 0 sized bitfield after the non-zero-
+//   sized bitfield.
+// * 2012 and back: In 64-bit mode, if the alignment of a record is 16 or
+//   greater due to __declspec(align()) then a second layout phase occurs after
+//   The locations of the vf and vb pointers are known.  This layout phase
+//   suffers from the "last field is a bitfield" bug in 2010 and results in
+//   _every_ field getting padding put in front of it, potentially including the
+//   vfptr, leaving the vfprt at a non-zero location which results in a fault if
+//   anything tries to read the vftbl.  The second layout phase also treats
+//   bitfields as separate entities and gives them each storage rather than
+//   packing them.  Additionally, because this phase appears to perform a
+//   (an unstable) sort on the members before laying them out and because merged
+//   bitfields have the same address, the bitfields end up in whatever order
+//   the sort left them in, a behavior we could never hope to replicate.
 
 namespace {
 struct MicrosoftRecordLayoutBuilder {
+  struct ElementInfo {
+    CharUnits Size;
+    CharUnits Alignment;
+  };
   typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetsMapTy;
   MicrosoftRecordLayoutBuilder(const ASTContext &Context) : Context(Context) {}
 private:
@@ -2028,19 +2141,20 @@
   LLVM_DELETED_FUNCTION;
   void operator=(const MicrosoftRecordLayoutBuilder &) LLVM_DELETED_FUNCTION;
 public:
-
   void layout(const RecordDecl *RD);
   void cxxLayout(const CXXRecordDecl *RD);
   /// \brief Initializes size and alignment and honors some flags.
   void initializeLayout(const RecordDecl *RD);
   /// \brief Initialized C++ layout, compute alignment and virtual alignment and
-  /// existance of vfptrs and vbptrs.  Alignment is needed before the vfptr is
+  /// existence of vfptrs and vbptrs.  Alignment is needed before the vfptr is
   /// laid out.
   void initializeCXXLayout(const CXXRecordDecl *RD);
-  void layoutVFPtr(const CXXRecordDecl *RD);
   void layoutNonVirtualBases(const CXXRecordDecl *RD);
-  void layoutNonVirtualBase(const CXXRecordDecl *RD);
-  void layoutVBPtr(const CXXRecordDecl *RD);
+  void layoutNonVirtualBase(const CXXRecordDecl *BaseDecl,
+                            const ASTRecordLayout &BaseLayout,
+                            const ASTRecordLayout *&PreviousBaseLayout);
+  void injectVFPtr(const CXXRecordDecl *RD);
+  void injectVBPtr(const CXXRecordDecl *RD);
   /// \brief Lays out the fields of the record.  Also rounds size up to
   /// alignment.
   void layoutFields(const RecordDecl *RD);
@@ -2050,22 +2164,14 @@
   /// special cases associated with zero-width bit-fields.
   void layoutZeroWidthBitField(const FieldDecl *FD);
   void layoutVirtualBases(const CXXRecordDecl *RD);
-  void layoutVirtualBase(const CXXRecordDecl *RD, bool HasVtordisp);
-  /// \brief Flushes the lazy virtual base and conditionally rounds up to
-  /// alignment.
-  void finalizeCXXLayout(const CXXRecordDecl *RD);
-  void honorDeclspecAlign(const RecordDecl *RD);
-
-  /// \brief Updates the alignment of the type.  This function doesn't take any
-  /// properties (such as packedness) into account.  getAdjustedFieldInfo()
-  /// adjustes for packedness.
-  void updateAlignment(CharUnits NewAlignment) {
-    Alignment = std::max(Alignment, NewAlignment);
-  }
-  /// \brief Gets the size and alignment taking attributes into account.
-  std::pair<CharUnits, CharUnits> getAdjustedFieldInfo(const FieldDecl *FD);
-  /// \brief Places a field at offset 0.
-  void placeFieldAtZero() { FieldOffsets.push_back(0); }
+  void finalizeLayout(const RecordDecl *RD);
+  /// \brief Gets the size and alignment of a base taking pragma pack and
+  /// __declspec(align) into account.
+  ElementInfo getAdjustedElementInfo(const ASTRecordLayout &Layout);
+  /// \brief Gets the size and alignment of a field taking pragma  pack and
+  /// __declspec(align) into account.  It also updates RequiredAlignment as a
+  /// side effect because it is most convenient to do so here.
+  ElementInfo getAdjustedElementInfo(const FieldDecl *FD);
   /// \brief Places a field at an offset in CharUnits.
   void placeFieldAtOffset(CharUnits FieldOffset) {
     FieldOffsets.push_back(Context.toBits(FieldOffset));
@@ -2077,325 +2183,280 @@
   /// \brief Compute the set of virtual bases for which vtordisps are required.
   llvm::SmallPtrSet<const CXXRecordDecl *, 2>
   computeVtorDispSet(const CXXRecordDecl *RD);
-
   const ASTContext &Context;
   /// \brief The size of the record being laid out.
   CharUnits Size;
+  /// \brief The non-virtual size of the record layout.
+  CharUnits NonVirtualSize;
+  /// \brief The data size of the record layout.
+  CharUnits DataSize;
   /// \brief The current alignment of the record layout.
   CharUnits Alignment;
-  /// \brief The collection of field offsets.
-  SmallVector<uint64_t, 16> FieldOffsets;
   /// \brief The maximum allowed field alignment. This is set by #pragma pack.
   CharUnits MaxFieldAlignment;
-  /// \brief Alignment does not occur for virtual bases unless something
-  /// forces it to by explicitly using __declspec(align())
-  bool AlignAfterVBases : 1;
-  bool IsUnion : 1;
-  /// \brief True if the last field laid out was a bitfield and was not 0
-  /// width.
-  bool LastFieldIsNonZeroWidthBitfield : 1;
+  /// \brief The alignment that this record must obey.  This is imposed by
+  /// __declspec(align()) on the record itself or one of its fields or bases.
+  CharUnits RequiredAlignment;
   /// \brief The size of the allocation of the currently active bitfield.
   /// This value isn't meaningful unless LastFieldIsNonZeroWidthBitfield
   /// is true.
   CharUnits CurrentBitfieldSize;
-  /// \brief The number of remaining bits in our last bitfield allocation.
-  /// This value isn't meaningful unless LastFieldIsNonZeroWidthBitfield is
-  /// true.
-  unsigned RemainingBitsInField;
-
-  /// \brief The data alignment of the record layout.
-  CharUnits DataSize;
-  /// \brief The alignment of the non-virtual portion of the record layout
-  /// without the impact of the virtual pointers.
-  /// Only used for C++ layouts.
-  CharUnits BasesAndFieldsAlignment;
-  /// \brief The alignment of the non-virtual portion of the record layout
-  /// Only used for C++ layouts.
-  CharUnits NonVirtualAlignment;
-  /// \brief The additional alignment imposed by the virtual bases.
-  CharUnits VirtualAlignment;
+  /// \brief Offset to the virtual base table pointer (if one exists).
+  CharUnits VBPtrOffset;
+  /// \brief The size and alignment info of a pointer.
+  ElementInfo PointerInfo;
   /// \brief The primary base class (if one exists).
   const CXXRecordDecl *PrimaryBase;
   /// \brief The class we share our vb-pointer with.
   const CXXRecordDecl *SharedVBPtrBase;
-  /// \brief True if the class has a vftable pointer that can be extended
-  /// by this class or classes derived from it.  Such a vfptr will always occur
-  /// at offset 0.
-  bool HasExtendableVFPtr : 1;
-  /// \brief True if the class has a (not necessarily its own) vbtable pointer.
-  bool HasVBPtr : 1;
-  /// \brief Offset to the virtual base table pointer (if one exists).
-  CharUnits VBPtrOffset;
+  /// \brief The collection of field offsets.
+  SmallVector<uint64_t, 16> FieldOffsets;
   /// \brief Base classes and their offsets in the record.
   BaseOffsetsMapTy Bases;
   /// \brief virtual base classes and their offsets in the record.
   ASTRecordLayout::VBaseOffsetsMapTy VBases;
-  /// \brief The size of a pointer.
-  CharUnits PointerSize;
-  /// \brief The alignment of a pointer.
-  CharUnits PointerAlignment;
-  /// \brief Holds an empty base we haven't yet laid out.
-  const CXXRecordDecl *LazyEmptyBase;
-  /// \brief Lets us know if the last base we laid out was empty.  Only used
-  /// when adjusting the placement of a last zero-sized base in 64 bit mode.
-  bool LastBaseWasEmpty;
-  /// \brief Lets us know if we're in 64-bit mode
-  bool Is64BitMode;
+  /// \brief The number of remaining bits in our last bitfield allocation.
+  /// This value isn't meaningful unless LastFieldIsNonZeroWidthBitfield is
+  /// true.
+  unsigned RemainingBitsInField;
+  bool IsUnion : 1;
+  /// \brief True if the last field laid out was a bitfield and was not 0
+  /// width.
+  bool LastFieldIsNonZeroWidthBitfield : 1;
+  /// \brief True if the class has its own vftable pointer.
+  bool HasOwnVFPtr : 1;
+  /// \brief True if the class has a vbtable pointer.
+  bool HasVBPtr : 1;
+  /// \brief True if the last sub-object within the type is zero sized or the
+  /// object itself is zero sized.  This *does not* count members that are not
+  /// records.  Only used for MS-ABI.
+  bool EndsWithZeroSizedObject : 1;
+  /// \brief True if this class is zero sized or first base is zero sized or
+  /// has this property.  Only used for MS-ABI.
+  bool LeadsWithZeroSizedBase : 1;
 };
 } // namespace
 
-std::pair<CharUnits, CharUnits>
-MicrosoftRecordLayoutBuilder::getAdjustedFieldInfo(const FieldDecl *FD) {
-  std::pair<CharUnits, CharUnits> FieldInfo =
-      Context.getTypeInfoInChars(FD->getType());
-
-  // If we're not on win32 and using ms_struct the field alignment will be wrong
-  // for 64 bit types, so we fix that here.
-  if (FD->getASTContext().getTargetInfo().getTriple().getOS() !=
-      llvm::Triple::Win32) {
-    QualType T = Context.getBaseElementType(FD->getType());
-    if (const BuiltinType *BTy = T->getAs<BuiltinType>()) {
-      CharUnits TypeSize = Context.getTypeSizeInChars(BTy);
-      if (TypeSize > FieldInfo.second)
-        FieldInfo.second = TypeSize;
-    }
-  }
-
-  // Respect packed attribute.
-  if (FD->hasAttr<PackedAttr>())
-    FieldInfo.second = CharUnits::One();
-  // Respect pack pragma.
-  else if (!MaxFieldAlignment.isZero())
-    FieldInfo.second = std::min(FieldInfo.second, MaxFieldAlignment);
-  // Respect alignment attributes.
-  if (unsigned fieldAlign = FD->getMaxAlignment()) {
-    CharUnits FieldAlign = Context.toCharUnitsFromBits(fieldAlign);
-    AlignAfterVBases = true;
-    FieldInfo.second = std::max(FieldInfo.second, FieldAlign);
-  }
-  return FieldInfo;
+MicrosoftRecordLayoutBuilder::ElementInfo
+MicrosoftRecordLayoutBuilder::getAdjustedElementInfo(
+    const ASTRecordLayout &Layout) {
+  ElementInfo Info;
+  Info.Alignment = Layout.getAlignment();
+  // Respect pragma pack.
+  if (!MaxFieldAlignment.isZero())
+    Info.Alignment = std::min(Info.Alignment, MaxFieldAlignment);
+  // Track zero-sized subobjects here where it's already available.
+  EndsWithZeroSizedObject = Layout.hasZeroSizedSubObject();
+  // Respect required alignment, this is necessary because we may have adjusted
+  // the alignment in the case of pragam pack.  Note that the required alignment
+  // doesn't actually apply to the struct alignment at this point.
+  Alignment = std::max(Alignment, Info.Alignment);
+  RequiredAlignment = std::max(RequiredAlignment, Layout.getRequiredAlignment());
+  Info.Alignment = std::max(Info.Alignment, Layout.getRequiredAlignment());
+  Info.Size = Layout.getNonVirtualSize();
+  return Info;
 }
 
-void MicrosoftRecordLayoutBuilder::initializeLayout(const RecordDecl *RD) {
-  IsUnion = RD->isUnion();
-  Is64BitMode = Context.getTargetInfo().getPointerWidth(0) == 64;
-
-  Size = CharUnits::Zero();
-  Alignment = CharUnits::One();
-  AlignAfterVBases = false;
-
-  // Compute the maximum field alignment.
-  MaxFieldAlignment = CharUnits::Zero();
-  // Honor the default struct packing maximum alignment flag.
-  if (unsigned DefaultMaxFieldAlignment = Context.getLangOpts().PackStruct)
-    MaxFieldAlignment = CharUnits::fromQuantity(DefaultMaxFieldAlignment);
-  // Honor the packing attribute.
-  if (const MaxFieldAlignmentAttr *MFAA = RD->getAttr<MaxFieldAlignmentAttr>())
-    MaxFieldAlignment = Context.toCharUnitsFromBits(MFAA->getAlignment());
-  // Packed attribute forces max field alignment to be 1.
-  if (RD->hasAttr<PackedAttr>())
-    MaxFieldAlignment = CharUnits::One();
+MicrosoftRecordLayoutBuilder::ElementInfo
+MicrosoftRecordLayoutBuilder::getAdjustedElementInfo(
+    const FieldDecl *FD) {
+  ElementInfo Info;
+  std::tie(Info.Size, Info.Alignment) =
+      Context.getTypeInfoInChars(FD->getType());
+  // Respect align attributes.
+  CharUnits FieldRequiredAlignment = 
+      Context.toCharUnitsFromBits(FD->getMaxAlignment());
+  // Respect attributes applied to subobjects of the field.
+  if (FD->isBitField())
+    // For some reason __declspec align impacts alignment rather than required
+    // alignment when it is applied to bitfields.
+    Info.Alignment = std::max(Info.Alignment, FieldRequiredAlignment);
+  else {
+    if (auto RT =
+            FD->getType()->getBaseElementTypeUnsafe()->getAs<RecordType>()) {
+      auto const &Layout = Context.getASTRecordLayout(RT->getDecl());
+      EndsWithZeroSizedObject = Layout.hasZeroSizedSubObject();
+      FieldRequiredAlignment = std::max(FieldRequiredAlignment,
+                                        Layout.getRequiredAlignment());
+    }
+    // Capture required alignment as a side-effect.
+    RequiredAlignment = std::max(RequiredAlignment, FieldRequiredAlignment);
+  }
+  // Respect pragma pack, attribute pack and declspec align
+  if (!MaxFieldAlignment.isZero())
+    Info.Alignment = std::min(Info.Alignment, MaxFieldAlignment);
+  if (FD->hasAttr<PackedAttr>())
+    Info.Alignment = CharUnits::One();
+  Info.Alignment = std::max(Info.Alignment, FieldRequiredAlignment);
+  return Info;
 }
 
 void MicrosoftRecordLayoutBuilder::layout(const RecordDecl *RD) {
   initializeLayout(RD);
   layoutFields(RD);
-  honorDeclspecAlign(RD);
+  DataSize = Size = Size.RoundUpToAlignment(Alignment);
+  RequiredAlignment = std::max(
+      RequiredAlignment, Context.toCharUnitsFromBits(RD->getMaxAlignment()));
+  finalizeLayout(RD);
 }
 
 void MicrosoftRecordLayoutBuilder::cxxLayout(const CXXRecordDecl *RD) {
   initializeLayout(RD);
   initializeCXXLayout(RD);
-  layoutVFPtr(RD);
   layoutNonVirtualBases(RD);
-  layoutVBPtr(RD);
   layoutFields(RD);
-  DataSize = Size;
-  NonVirtualAlignment = Alignment;
+  injectVBPtr(RD);
+  injectVFPtr(RD);
+  if (HasOwnVFPtr || (HasVBPtr && !SharedVBPtrBase))
+    Alignment = std::max(Alignment, PointerInfo.Alignment);
+  auto RoundingAlignment = Alignment;
+  if (!MaxFieldAlignment.isZero())
+    RoundingAlignment = std::min(RoundingAlignment, MaxFieldAlignment);
+  NonVirtualSize = Size = Size.RoundUpToAlignment(RoundingAlignment);
+  RequiredAlignment = std::max(
+      RequiredAlignment, Context.toCharUnitsFromBits(RD->getMaxAlignment()));
   layoutVirtualBases(RD);
-  finalizeCXXLayout(RD);
-  honorDeclspecAlign(RD);
+  finalizeLayout(RD);
+}
+
+void MicrosoftRecordLayoutBuilder::initializeLayout(const RecordDecl *RD) {
+  IsUnion = RD->isUnion();
+  Size = CharUnits::Zero();
+  Alignment = CharUnits::One();
+  // In 64-bit mode we always perform an alignment step after laying out vbases.
+  // In 32-bit mode we do not.  The check to see if we need to perform alignment
+  // checks the RequiredAlignment field and performs alignment if it isn't 0.
+  RequiredAlignment = Context.getTargetInfo().getPointerWidth(0) == 64 ?
+                      CharUnits::One() : CharUnits::Zero();
+  // Compute the maximum field alignment.
+  MaxFieldAlignment = CharUnits::Zero();
+  // Honor the default struct packing maximum alignment flag.
+  if (unsigned DefaultMaxFieldAlignment = Context.getLangOpts().PackStruct)
+      MaxFieldAlignment = CharUnits::fromQuantity(DefaultMaxFieldAlignment);
+  // Honor the packing attribute.  The MS-ABI ignores pragma pack if its larger
+  // than the pointer size.
+  if (const MaxFieldAlignmentAttr *MFAA = RD->getAttr<MaxFieldAlignmentAttr>()){
+    unsigned PackedAlignment = MFAA->getAlignment();
+    if (PackedAlignment <= Context.getTargetInfo().getPointerWidth(0))
+      MaxFieldAlignment = Context.toCharUnitsFromBits(PackedAlignment);
+  }
+  // Packed attribute forces max field alignment to be 1.
+  if (RD->hasAttr<PackedAttr>())
+    MaxFieldAlignment = CharUnits::One();
 }
 
 void
 MicrosoftRecordLayoutBuilder::initializeCXXLayout(const CXXRecordDecl *RD) {
-  // Calculate pointer size and alignment.
-  PointerSize =
-      Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0));
-  PointerAlignment = PointerSize;
-  if (!MaxFieldAlignment.isZero())
-    PointerAlignment = std::min(PointerAlignment, MaxFieldAlignment);
-
-  // Initialize information about the bases.
+  EndsWithZeroSizedObject = false;
+  LeadsWithZeroSizedBase = false;
+  HasOwnVFPtr = false;
   HasVBPtr = false;
-  HasExtendableVFPtr = false;
-  SharedVBPtrBase = 0;
-  PrimaryBase = 0;
-  VirtualAlignment = CharUnits::One();
-  AlignAfterVBases = Is64BitMode;
-
-  // If the record has a dynamic base class, attempt to choose a primary base
-  // class. It is the first (in direct base class order) non-virtual dynamic
-  // base class, if one exists.
-  for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
-                                                e = RD->bases_end();
-       i != e; ++i) {
-    const CXXRecordDecl *BaseDecl =
-        cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
-    const ASTRecordLayout &Layout = Context.getASTRecordLayout(BaseDecl);
-    // Handle forced alignment.
-    if (Layout.getAlignAfterVBases())
-      AlignAfterVBases = true;
-    // Handle virtual bases.
-    if (i->isVirtual()) {
-      VirtualAlignment = std::max(VirtualAlignment, Layout.getAlignment());
-      HasVBPtr = true;
-      continue;
-    }
-    // We located a primary base class!
-    if (!PrimaryBase && Layout.hasExtendableVFPtr()) {
-      PrimaryBase = BaseDecl;
-      HasExtendableVFPtr = true;
-    }
-    // We located a base to share a VBPtr with!
-    if (!SharedVBPtrBase && Layout.hasVBPtr()) {
-      SharedVBPtrBase = BaseDecl;
-      HasVBPtr = true;
-    }
-    updateAlignment(Layout.getAlignment());
-  }
-
-  // Use LayoutFields to compute the alignment of the fields.  The layout
-  // is discarded.  This is the simplest way to get all of the bit-field
-  // behavior correct and is not actually very expensive.
-  layoutFields(RD);
-  Size = CharUnits::Zero();
-  BasesAndFieldsAlignment = Alignment;
-  FieldOffsets.clear();
-}
-
-void MicrosoftRecordLayoutBuilder::layoutVFPtr(const CXXRecordDecl *RD) {
-  // If we have a primary base then our VFPtr was already laid out
-  if (PrimaryBase)
-    return;
-
-  // Look at all of our methods to determine if we need a VFPtr.  We need a
-  // vfptr if we define a new virtual function.
-  if (!HasExtendableVFPtr && RD->isDynamicClass())
-    for (CXXRecordDecl::method_iterator i = RD->method_begin(),
-                                        e = RD->method_end();
-         !HasExtendableVFPtr && i != e; ++i)
-      HasExtendableVFPtr = i->isVirtual() && i->size_overridden_methods() == 0;
-  if (!HasExtendableVFPtr)
-    return;
-
-  // MSVC 32 (but not 64) potentially over-aligns the vf-table pointer by giving
-  // it the max alignment of all the non-virtual data in the class.  The
-  // resulting layout is essentially { vftbl, { nvdata } }.  This is completely
-  // unnecessary, but we're not here to pass judgment.
-  updateAlignment(PointerAlignment);
-  if (Is64BitMode)
-    Size = Size.RoundUpToAlignment(PointerAlignment) + PointerSize;
-  else
-    Size = Size.RoundUpToAlignment(PointerAlignment) + Alignment;
+  PrimaryBase = nullptr;
+  SharedVBPtrBase = nullptr;
+  // Calculate pointer size and alignment.  These are used for vfptr and vbprt
+  // injection.
+  PointerInfo.Size =
+      Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0));
+  PointerInfo.Alignment = PointerInfo.Size;
+  // Respect pragma pack.
+  if (!MaxFieldAlignment.isZero())
+    PointerInfo.Alignment = std::min(PointerInfo.Alignment, MaxFieldAlignment);
 }
 
 void
 MicrosoftRecordLayoutBuilder::layoutNonVirtualBases(const CXXRecordDecl *RD) {
-  LazyEmptyBase = 0;
-  LastBaseWasEmpty = false;
-
-  // Lay out the primary base first.
-  if (PrimaryBase)
-    layoutNonVirtualBase(PrimaryBase);
-
+  // The MS-ABI lays out all bases that contain leading vfptrs before it lays
+  // out any bases that do not contain vfptrs.  We implement this as two passes
+  // over the bases.  This approach guarantees that the primary base is laid out
+  // first.  We use these passes to calculate some additional aggregated
+  // information about the bases, such as reqruied alignment and the presence of
+  // zero sized members.
+  const ASTRecordLayout *PreviousBaseLayout = nullptr;
   // Iterate through the bases and lay out the non-virtual ones.
-  for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
-                                                e = RD->bases_end();
-       i != e; ++i) {
-    if (i->isVirtual())
+  for (const CXXBaseSpecifier &Base : RD->bases()) {
+    const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
+    const ASTRecordLayout &BaseLayout = Context.getASTRecordLayout(BaseDecl);
+    // Mark and skip virtual bases.
+    if (Base.isVirtual()) {
+      HasVBPtr = true;
       continue;
-    const CXXRecordDecl *BaseDecl =
-        cast<CXXRecordDecl>(i->getType()->castAs<RecordType>()->getDecl());
-    if (BaseDecl != PrimaryBase)
-      layoutNonVirtualBase(BaseDecl);
-  }
-}
-
-void
-MicrosoftRecordLayoutBuilder::layoutNonVirtualBase(const CXXRecordDecl *RD) {
-  const ASTRecordLayout *Layout = RD ? &Context.getASTRecordLayout(RD) : 0;
-
-  // If we have a lazy empty base we haven't laid out yet, do that now.
-  if (LazyEmptyBase) {
-    const ASTRecordLayout &LazyLayout =
-        Context.getASTRecordLayout(LazyEmptyBase);
-    Size = Size.RoundUpToAlignment(LazyLayout.getAlignment());
-    Bases.insert(std::make_pair(LazyEmptyBase, Size));
-    // Empty bases only consume space when followed by another empty base.
-    if (RD && Layout->getNonVirtualSize().isZero()) {
-      LastBaseWasEmpty = true;
-      Size++;
     }
-    LazyEmptyBase = 0;
+    // Check fo a base to share a VBPtr with.
+    if (!SharedVBPtrBase && BaseLayout.hasVBPtr()) {
+      SharedVBPtrBase = BaseDecl;
+      HasVBPtr = true;
+    }
+    // Only lay out bases with extendable VFPtrs on the first pass.
+    if (!BaseLayout.hasExtendableVFPtr())
+      continue;
+    // If we don't have a primary base, this one qualifies.
+    if (!PrimaryBase) {
+      PrimaryBase = BaseDecl;
+      LeadsWithZeroSizedBase = BaseLayout.leadsWithZeroSizedBase();
+    }
+    // Lay out the base.
+    layoutNonVirtualBase(BaseDecl, BaseLayout, PreviousBaseLayout);
   }
-
-  // RD is null when flushing the final lazy base.
-  if (!RD)
-    return;
-
-  if (Layout->getNonVirtualSize().isZero()) {
-    LazyEmptyBase = RD;
-    return;
+  // Figure out if we need a fresh VFPtr for this class.
+  if (!PrimaryBase && RD->isDynamicClass())
+    for (CXXRecordDecl::method_iterator i = RD->method_begin(),
+                                        e = RD->method_end();
+         !HasOwnVFPtr && i != e; ++i)
+      HasOwnVFPtr = i->isVirtual() && i->size_overridden_methods() == 0;
+  // If we don't have a primary base then we have a leading object that could
+  // itself lead with a zero-sized object, something we track.
+  bool CheckLeadingLayout = !PrimaryBase;
+  // Iterate through the bases and lay out the non-virtual ones.
+  for (const CXXBaseSpecifier &Base : RD->bases()) {
+    if (Base.isVirtual())
+      continue;
+    const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
+    const ASTRecordLayout &BaseLayout = Context.getASTRecordLayout(BaseDecl);
+    // Only lay out bases without extendable VFPtrs on the second pass.
+    if (BaseLayout.hasExtendableVFPtr()) {
+      VBPtrOffset = Bases[BaseDecl] + BaseLayout.getNonVirtualSize();
+      continue;
+    }
+    // If this is the first layout, check to see if it leads with a zero sized
+    // object.  If it does, so do we.
+    if (CheckLeadingLayout) {
+      CheckLeadingLayout = false;
+      LeadsWithZeroSizedBase = BaseLayout.leadsWithZeroSizedBase();
+    }
+    // Lay out the base.
+    layoutNonVirtualBase(BaseDecl, BaseLayout, PreviousBaseLayout);
+    VBPtrOffset = Bases[BaseDecl] + BaseLayout.getNonVirtualSize();
   }
-
-  // Insert the base here.
-  CharUnits BaseOffset = Size.RoundUpToAlignment(Layout->getAlignment());
-  Bases.insert(std::make_pair(RD, BaseOffset));
-  Size = BaseOffset + Layout->getDataSize();
-  // Note: we don't update alignment here because it was accounted
-  // for during initalization.
-  LastBaseWasEmpty = false;
-}
-
-void MicrosoftRecordLayoutBuilder::layoutVBPtr(const CXXRecordDecl *RD) {
+  // Set our VBPtroffset if we know it at this point.
   if (!HasVBPtr)
     VBPtrOffset = CharUnits::fromQuantity(-1);
   else if (SharedVBPtrBase) {
     const ASTRecordLayout &Layout = Context.getASTRecordLayout(SharedVBPtrBase);
     VBPtrOffset = Bases[SharedVBPtrBase] + Layout.getVBPtrOffset();
-  } else {
-    VBPtrOffset = Size.RoundUpToAlignment(PointerAlignment);
-    CharUnits OldSize = Size;
-    Size = VBPtrOffset + PointerSize;
-    if (BasesAndFieldsAlignment <= PointerAlignment) {
-      // Handle strange padding rules for the lazily placed base.  I have no
-      // explanation for why the last virtual base is padded in such an odd way.
-      // Two things to note about this padding are that the rules are different
-      // if the alignment of the bases+fields is <= to the alignemnt of a
-      // pointer and that the rule in 64-bit mode behaves differently depending
-      // on if the second to last base was also zero sized.
-      Size += OldSize % BasesAndFieldsAlignment.getQuantity();
-    } else {
-      if (Is64BitMode)
-        Size += LastBaseWasEmpty ? CharUnits::One() : CharUnits::Zero();
-      else
-        Size = OldSize + BasesAndFieldsAlignment;
-    }
-    updateAlignment(PointerAlignment);
   }
+}
 
-  // Flush the lazy empty base.
-  layoutNonVirtualBase(0);
+void MicrosoftRecordLayoutBuilder::layoutNonVirtualBase(
+    const CXXRecordDecl *BaseDecl,
+    const ASTRecordLayout &BaseLayout,
+    const ASTRecordLayout *&PreviousBaseLayout) {
+  // Insert padding between two bases if the left first one is zero sized or
+  // contains a zero sized subobject and the right is zero sized or one leads
+  // with a zero sized base.
+  if (PreviousBaseLayout && PreviousBaseLayout->hasZeroSizedSubObject() &&
+      BaseLayout.leadsWithZeroSizedBase())
+    Size++;
+  ElementInfo Info = getAdjustedElementInfo(BaseLayout);
+  CharUnits BaseOffset = Size.RoundUpToAlignment(Info.Alignment);
+  Bases.insert(std::make_pair(BaseDecl, BaseOffset));
+  Size = BaseOffset + BaseLayout.getNonVirtualSize();
+  PreviousBaseLayout = &BaseLayout;
 }
 
 void MicrosoftRecordLayoutBuilder::layoutFields(const RecordDecl *RD) {
   LastFieldIsNonZeroWidthBitfield = false;
-  for (RecordDecl::field_iterator Field = RD->field_begin(),
-                                  FieldEnd = RD->field_end();
-       Field != FieldEnd; ++Field)
-    layoutField(*Field);
-  Size = Size.RoundUpToAlignment(Alignment);
+  for (const FieldDecl *Field : RD->fields())
+    layoutField(Field);
 }
 
 void MicrosoftRecordLayoutBuilder::layoutField(const FieldDecl *FD) {
@@ -2404,20 +2465,15 @@
     return;
   }
   LastFieldIsNonZeroWidthBitfield = false;
-
-  std::pair<CharUnits, CharUnits> FieldInfo = getAdjustedFieldInfo(FD);
-  CharUnits FieldSize = FieldInfo.first;
-  CharUnits FieldAlign = FieldInfo.second;
-
-  updateAlignment(FieldAlign);
+  ElementInfo Info = getAdjustedElementInfo(FD);
+  Alignment = std::max(Alignment, Info.Alignment);
   if (IsUnion) {
-    placeFieldAtZero();
-    Size = std::max(Size, FieldSize);
+    placeFieldAtOffset(CharUnits::Zero());
+    Size = std::max(Size, Info.Size);
   } else {
-    // Round up the current record size to the field's alignment boundary.
-    CharUnits FieldOffset = Size.RoundUpToAlignment(FieldAlign);
+    CharUnits FieldOffset = Size.RoundUpToAlignment(Info.Alignment);
     placeFieldAtOffset(FieldOffset);
-    Size = FieldOffset + FieldSize;
+    Size = FieldOffset + Info.Size;
   }
 }
 
@@ -2427,39 +2483,33 @@
     layoutZeroWidthBitField(FD);
     return;
   }
-
-  std::pair<CharUnits, CharUnits> FieldInfo = getAdjustedFieldInfo(FD);
-  CharUnits FieldSize = FieldInfo.first;
-  CharUnits FieldAlign = FieldInfo.second;
-
+  ElementInfo Info = getAdjustedElementInfo(FD);
   // Clamp the bitfield to a containable size for the sake of being able
   // to lay them out.  Sema will throw an error.
-  if (Width > Context.toBits(FieldSize))
-    Width = Context.toBits(FieldSize);
-
+  if (Width > Context.toBits(Info.Size))
+    Width = Context.toBits(Info.Size);
   // Check to see if this bitfield fits into an existing allocation.  Note:
   // MSVC refuses to pack bitfields of formal types with different sizes
   // into the same allocation.
   if (!IsUnion && LastFieldIsNonZeroWidthBitfield &&
-      CurrentBitfieldSize == FieldSize && Width <= RemainingBitsInField) {
+      CurrentBitfieldSize == Info.Size && Width <= RemainingBitsInField) {
     placeFieldAtBitOffset(Context.toBits(Size) - RemainingBitsInField);
     RemainingBitsInField -= Width;
     return;
   }
-
   LastFieldIsNonZeroWidthBitfield = true;
-  CurrentBitfieldSize = FieldSize;
+  CurrentBitfieldSize = Info.Size;
   if (IsUnion) {
-    placeFieldAtZero();
-    Size = std::max(Size, FieldSize);
+    placeFieldAtOffset(CharUnits::Zero());
+    Size = std::max(Size, Info.Size);
     // TODO: Add a Sema warning that MS ignores bitfield alignment in unions.
   } else {
     // Allocate a new block of memory and place the bitfield in it.
-    CharUnits FieldOffset = Size.RoundUpToAlignment(FieldAlign);
+    CharUnits FieldOffset = Size.RoundUpToAlignment(Info.Alignment);
     placeFieldAtOffset(FieldOffset);
-    Size = FieldOffset + FieldSize;
-    updateAlignment(FieldAlign);
-    RemainingBitsInField = Context.toBits(FieldSize) - Width;
+    Size = FieldOffset + Info.Size;
+    Alignment = std::max(Alignment, Info.Alignment);
+    RemainingBitsInField = Context.toBits(Info.Size) - Width;
   }
 }
 
@@ -2467,201 +2517,220 @@
 MicrosoftRecordLayoutBuilder::layoutZeroWidthBitField(const FieldDecl *FD) {
   // Zero-width bitfields are ignored unless they follow a non-zero-width
   // bitfield.
-  std::pair<CharUnits, CharUnits> FieldInfo = getAdjustedFieldInfo(FD);
-  CharUnits FieldSize = FieldInfo.first;
-  CharUnits FieldAlign = FieldInfo.second;
-
   if (!LastFieldIsNonZeroWidthBitfield) {
     placeFieldAtOffset(IsUnion ? CharUnits::Zero() : Size);
     // TODO: Add a Sema warning that MS ignores alignment for zero
-    // sized bitfields that occur after zero-size bitfields or non bitfields.
+    // sized bitfields that occur after zero-size bitfields or non-bitfields.
     return;
   }
-
   LastFieldIsNonZeroWidthBitfield = false;
+  ElementInfo Info = getAdjustedElementInfo(FD);
   if (IsUnion) {
-    placeFieldAtZero();
-    Size = std::max(Size, FieldSize);
+    placeFieldAtOffset(CharUnits::Zero());
+    Size = std::max(Size, Info.Size);
+    // TODO: Add a Sema warning that MS ignores bitfield alignment in unions.
   } else {
     // Round up the current record size to the field's alignment boundary.
-    CharUnits FieldOffset = Size.RoundUpToAlignment(FieldAlign);
+    CharUnits FieldOffset = Size.RoundUpToAlignment(Info.Alignment);
     placeFieldAtOffset(FieldOffset);
     Size = FieldOffset;
-    updateAlignment(FieldAlign);
+    Alignment = std::max(Alignment, Info.Alignment);
   }
 }
 
+void MicrosoftRecordLayoutBuilder::injectVBPtr(const CXXRecordDecl *RD) {
+  if (!HasVBPtr || SharedVBPtrBase)
+    return;
+  // Inject the VBPointer at the injection site.
+  CharUnits InjectionSite = VBPtrOffset;
+  // But before we do, make sure it's properly aligned.
+  VBPtrOffset = VBPtrOffset.RoundUpToAlignment(PointerInfo.Alignment);
+  // Determine where the first field should be laid out after the vbptr.
+  CharUnits FieldStart = VBPtrOffset + PointerInfo.Size;
+  // Make sure that the amount we push the fields back by is a multiple of the
+  // alignment.
+  CharUnits Offset = (FieldStart - InjectionSite).RoundUpToAlignment(
+      std::max(RequiredAlignment, Alignment));
+  // Increase the size of the object and push back all fields by the offset
+  // amount.
+  Size += Offset;
+  for (uint64_t &FieldOffset : FieldOffsets)
+    FieldOffset += Context.toBits(Offset);
+  for (BaseOffsetsMapTy::value_type &Base : Bases)
+    if (Base.second >= InjectionSite)
+      Base.second += Offset;
+}
+
+void MicrosoftRecordLayoutBuilder::injectVFPtr(const CXXRecordDecl *RD) {
+  if (!HasOwnVFPtr)
+    return;
+  // Make sure that the amount we push the struct back by is a multiple of the
+  // alignment.
+  CharUnits Offset = PointerInfo.Size.RoundUpToAlignment(
+      std::max(RequiredAlignment, Alignment));
+  // Increase the size of the object and push back all fields, the vbptr and all
+  // bases by the offset amount.
+  Size += Offset;
+  for (uint64_t &FieldOffset : FieldOffsets)
+    FieldOffset += Context.toBits(Offset);
+  if (HasVBPtr)
+    VBPtrOffset += Offset;
+  for (BaseOffsetsMapTy::value_type &Base : Bases)
+    Base.second += Offset;
+}
+
 void MicrosoftRecordLayoutBuilder::layoutVirtualBases(const CXXRecordDecl *RD) {
   if (!HasVBPtr)
     return;
-
-  updateAlignment(VirtualAlignment);
-
-  // Zero-sized v-bases obey the alignment attribute so apply it here.  The
-  // alignment attribute is normally accounted for in FinalizeLayout.
-  if (unsigned MaxAlign = RD->getMaxAlignment())
-    updateAlignment(Context.toCharUnitsFromBits(MaxAlign));
-
-  llvm::SmallPtrSet<const CXXRecordDecl *, 2> HasVtordisp =
+  // Vtordisps are always 4 bytes (even in 64-bit mode)
+  CharUnits VtorDispSize = CharUnits::fromQuantity(4);
+  CharUnits VtorDispAlignment = VtorDispSize;
+  // vtordisps respect pragma pack.
+  if (!MaxFieldAlignment.isZero())
+    VtorDispAlignment = std::min(VtorDispAlignment, MaxFieldAlignment);
+  // The alignment of the vtordisp is at least the required alignment of the
+  // entire record.  This requirement may be present to support vtordisp
+  // injection.
+  for (const CXXBaseSpecifier &VBase : RD->vbases()) {
+    const CXXRecordDecl *BaseDecl = VBase.getType()->getAsCXXRecordDecl();
+    const ASTRecordLayout &BaseLayout = Context.getASTRecordLayout(BaseDecl);
+    RequiredAlignment =
+        std::max(RequiredAlignment, BaseLayout.getRequiredAlignment());
+  }
+  VtorDispAlignment = std::max(VtorDispAlignment, RequiredAlignment);
+  // Compute the vtordisp set.
+  llvm::SmallPtrSet<const CXXRecordDecl *, 2> HasVtordispSet =
       computeVtorDispSet(RD);
-
-  // If the last field we laid out was a non-zero length bitfield then add some
-  // extra padding for no obvious reason.
-  if (LastFieldIsNonZeroWidthBitfield)
-    Size += CurrentBitfieldSize;
-
   // Iterate through the virtual bases and lay them out.
-  for (CXXRecordDecl::base_class_const_iterator i = RD->vbases_begin(),
-                                                e = RD->vbases_end();
-       i != e; ++i) {
-    const CXXRecordDecl *BaseDecl =
-        cast<CXXRecordDecl>(i->getType()->castAs<RecordType>()->getDecl());
-    layoutVirtualBase(BaseDecl, HasVtordisp.count(BaseDecl));
+  const ASTRecordLayout *PreviousBaseLayout = nullptr;
+  for (const CXXBaseSpecifier &VBase : RD->vbases()) {
+    const CXXRecordDecl *BaseDecl = VBase.getType()->getAsCXXRecordDecl();
+    const ASTRecordLayout &BaseLayout = Context.getASTRecordLayout(BaseDecl);
+    bool HasVtordisp = HasVtordispSet.count(BaseDecl);
+    // Insert padding between two bases if the left first one is zero sized or
+    // contains a zero sized subobject and the right is zero sized or one leads
+    // with a zero sized base.  The padding between virtual bases is 4
+    // bytes (in both 32 and 64 bits modes) and always involves rounding up to
+    // the required alignment, we don't know why.
+    if ((PreviousBaseLayout && PreviousBaseLayout->hasZeroSizedSubObject() &&
+        BaseLayout.leadsWithZeroSizedBase()) || HasVtordisp) {
+      Size = Size.RoundUpToAlignment(VtorDispAlignment) + VtorDispSize;
+      Alignment = std::max(VtorDispAlignment, Alignment);
+    }
+    // Insert the virtual base.
+    ElementInfo Info = getAdjustedElementInfo(BaseLayout);
+    CharUnits BaseOffset = Size.RoundUpToAlignment(Info.Alignment);
+    VBases.insert(std::make_pair(BaseDecl,
+        ASTRecordLayout::VBaseInfo(BaseOffset, HasVtordisp)));
+    Size = BaseOffset + BaseLayout.getNonVirtualSize();
+    PreviousBaseLayout = &BaseLayout;
   }
 }
 
-void MicrosoftRecordLayoutBuilder::layoutVirtualBase(const CXXRecordDecl *RD,
-                                                     bool HasVtordisp) {
-  if (LazyEmptyBase) {
-    const ASTRecordLayout &LazyLayout =
-        Context.getASTRecordLayout(LazyEmptyBase);
-    Size = Size.RoundUpToAlignment(LazyLayout.getAlignment());
-    VBases.insert(
-        std::make_pair(LazyEmptyBase, ASTRecordLayout::VBaseInfo(Size, false)));
-    // Empty bases only consume space when followed by another empty base.
-    // The space consumed is in an Alignment sized/aligned block and the v-base
-    // is placed at its alignment offset into the chunk, unless its alignment
-    // is less than 4 bytes, at which it is placed at 4 byte offset in the
-    // chunk.  We have no idea why.
-    if (RD && Context.getASTRecordLayout(RD).getNonVirtualSize().isZero())
-      Size = Size.RoundUpToAlignment(Alignment) + CharUnits::fromQuantity(4);
-    LazyEmptyBase = 0;
+void MicrosoftRecordLayoutBuilder::finalizeLayout(const RecordDecl *RD) {
+  // Respect required alignment.  Note that in 32-bit mode Required alignment
+  // may be 0 nad cause size not to be updated.
+  DataSize = Size;
+  if (!RequiredAlignment.isZero()) {
+    Alignment = std::max(Alignment, RequiredAlignment);
+    auto RoundingAlignment = Alignment;
+    if (!MaxFieldAlignment.isZero())
+      RoundingAlignment = std::min(RoundingAlignment, MaxFieldAlignment);
+    RoundingAlignment = std::max(RoundingAlignment, RequiredAlignment);
+    Size = Size.RoundUpToAlignment(RoundingAlignment);
   }
-
-  // RD is null when flushing the final lazy virtual base.
-  if (!RD)
-    return;
-
-  const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
-  if (Layout.getNonVirtualSize().isZero() && !HasVtordisp) {
-    LazyEmptyBase = RD;
-    return;
-  }
-
-  CharUnits BaseNVSize = Layout.getNonVirtualSize();
-  CharUnits BaseAlign = Layout.getAlignment();
-
-  // vtordisps are always 4 bytes (even in 64-bit mode)
-  if (HasVtordisp)
-    Size = Size.RoundUpToAlignment(Alignment) + CharUnits::fromQuantity(4);
-  Size = Size.RoundUpToAlignment(BaseAlign);
-
-  // Insert the base here.
-  CharUnits BaseOffset = Size.RoundUpToAlignment(BaseAlign);
-  VBases.insert(
-      std::make_pair(RD, ASTRecordLayout::VBaseInfo(BaseOffset, HasVtordisp)));
-  Size = BaseOffset + BaseNVSize;
-  // Note: we don't update alignment here because it was accounted for in
-  // InitializeLayout.
-}
-
-void MicrosoftRecordLayoutBuilder::finalizeCXXLayout(const CXXRecordDecl *RD) {
-  // Flush the lazy virtual base.
-  layoutVirtualBase(0, false);
-
-  if (RD->vbases_begin() == RD->vbases_end() || AlignAfterVBases)
-    Size = Size.RoundUpToAlignment(Alignment);
-
-  if (Size.isZero())
+  // Zero-sized structures have size equal to their alignment.
+  if (Size.isZero()) {
+    EndsWithZeroSizedObject = true;
+    LeadsWithZeroSizedBase = true;
     Size = Alignment;
-}
-
-void MicrosoftRecordLayoutBuilder::honorDeclspecAlign(const RecordDecl *RD) {
-  if (unsigned MaxAlign = RD->getMaxAlignment()) {
-    AlignAfterVBases = true;
-    updateAlignment(Context.toCharUnitsFromBits(MaxAlign));
-    Size = Size.RoundUpToAlignment(Alignment);
   }
 }
 
+// Recursively walks the non-virtual bases of a class and determines if any of
+// them are in the bases with overridden methods set.
 static bool
-RequiresVtordisp(const llvm::SmallPtrSet<const CXXRecordDecl *, 2> &HasVtordisp,
+RequiresVtordisp(const llvm::SmallPtrSetImpl<const CXXRecordDecl *> &
+                     BasesWithOverriddenMethods,
                  const CXXRecordDecl *RD) {
-  if (HasVtordisp.count(RD))
+  if (BasesWithOverriddenMethods.count(RD))
     return true;
   // If any of a virtual bases non-virtual bases (recursively) requires a
   // vtordisp than so does this virtual base.
-  for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
-                                                e = RD->bases_end();
-       i != e; ++i)
-    if (!i->isVirtual() &&
-        RequiresVtordisp(
-            HasVtordisp,
-            cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl())))
+  for (const CXXBaseSpecifier &Base : RD->bases())
+    if (!Base.isVirtual() &&
+        RequiresVtordisp(BasesWithOverriddenMethods,
+                         Base.getType()->getAsCXXRecordDecl()))
       return true;
   return false;
 }
 
 llvm::SmallPtrSet<const CXXRecordDecl *, 2>
 MicrosoftRecordLayoutBuilder::computeVtorDispSet(const CXXRecordDecl *RD) {
-  llvm::SmallPtrSet<const CXXRecordDecl *, 2> HasVtordisp;
+  llvm::SmallPtrSet<const CXXRecordDecl *, 2> HasVtordispSet;
+
+  // /vd2 or #pragma vtordisp(2): Always use vtordisps for virtual bases with
+  // vftables.
+  if (RD->getMSVtorDispMode() == MSVtorDispAttr::ForVFTable) {
+    for (const CXXBaseSpecifier &Base : RD->vbases()) {
+      const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
+      const ASTRecordLayout &Layout = Context.getASTRecordLayout(BaseDecl);
+      if (Layout.hasExtendableVFPtr())
+        HasVtordispSet.insert(BaseDecl);
+    }
+    return HasVtordispSet;
+  }
 
   // If any of our bases need a vtordisp for this type, so do we.  Check our
   // direct bases for vtordisp requirements.
-  for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
-                                                e = RD->bases_end();
-       i != e; ++i) {
-    const CXXRecordDecl *BaseDecl =
-        cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
+  for (const CXXBaseSpecifier &Base : RD->bases()) {
+    const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
     const ASTRecordLayout &Layout = Context.getASTRecordLayout(BaseDecl);
-    for (ASTRecordLayout::VBaseOffsetsMapTy::const_iterator
-             bi = Layout.getVBaseOffsetsMap().begin(),
-             be = Layout.getVBaseOffsetsMap().end();
-         bi != be; ++bi)
-      if (bi->second.hasVtorDisp())
-        HasVtordisp.insert(bi->first);
+    for (const auto &bi : Layout.getVBaseOffsetsMap())
+      if (bi.second.hasVtorDisp())
+        HasVtordispSet.insert(bi.first);
   }
-
-  // If we define a constructor or destructor and override a function that is
-  // defined in a virtual base's vtable, that virtual bases need a vtordisp.
-  // Here we collect a list of classes with vtables for which our virtual bases
-  // actually live.  The virtual bases with this property will require
-  // vtordisps.  In addition, virtual bases that contain non-virtual bases that
-  // define functions we override also require vtordisps, this case is checked
-  // explicitly below.
-  if (RD->hasUserDeclaredConstructor() || RD->hasUserDeclaredDestructor()) {
-    llvm::SmallPtrSet<const CXXMethodDecl *, 8> Work;
-    // Seed the working set with our non-destructor virtual methods.
-    for (CXXRecordDecl::method_iterator i = RD->method_begin(),
-                                        e = RD->method_end();
-         i != e; ++i)
-      if ((*i)->isVirtual() && !isa<CXXDestructorDecl>(*i))
-        Work.insert(*i);
-    while (!Work.empty()) {
-      const CXXMethodDecl *MD = *Work.begin();
-      CXXMethodDecl::method_iterator i = MD->begin_overridden_methods(),
-                                     e = MD->end_overridden_methods();
-      if (i == e)
-        // If a virtual method has no-overrides it lives in its parent's vtable.
-        HasVtordisp.insert(MD->getParent());
-      else
-        Work.insert(i, e);
-      // We've finished processing this element, remove it from the working set.
-      Work.erase(MD);
-    }
+  // We don't introduce any additional vtordisps if either:
+  // * A user declared constructor or destructor aren't declared.
+  // * #pragma vtordisp(0) or the /vd0 flag are in use.
+  if ((!RD->hasUserDeclaredConstructor() && !RD->hasUserDeclaredDestructor()) ||
+      RD->getMSVtorDispMode() == MSVtorDispAttr::Never)
+    return HasVtordispSet;
+  // /vd1 or #pragma vtordisp(1): Try to guess based on whether we think it's
+  // possible for a partially constructed object with virtual base overrides to
+  // escape a non-trivial constructor.
+  assert(RD->getMSVtorDispMode() == MSVtorDispAttr::ForVBaseOverride);
+  // Compute a set of base classes which define methods we override.  A virtual
+  // base in this set will require a vtordisp.  A virtual base that transitively
+  // contains one of these bases as a non-virtual base will also require a
+  // vtordisp.
+  llvm::SmallPtrSet<const CXXMethodDecl *, 8> Work;
+  llvm::SmallPtrSet<const CXXRecordDecl *, 2> BasesWithOverriddenMethods;
+  // Seed the working set with our non-destructor virtual methods.
+  for (const CXXMethodDecl *MD : RD->methods())
+    if (MD->isVirtual() && !isa<CXXDestructorDecl>(MD))
+      Work.insert(MD);
+  while (!Work.empty()) {
+    const CXXMethodDecl *MD = *Work.begin();
+    CXXMethodDecl::method_iterator i = MD->begin_overridden_methods(),
+                                   e = MD->end_overridden_methods();
+    // If a virtual method has no-overrides it lives in its parent's vtable.
+    if (i == e)
+      BasesWithOverriddenMethods.insert(MD->getParent());
+    else
+      Work.insert(i, e);
+    // We've finished processing this element, remove it from the working set.
+    Work.erase(MD);
   }
-
-  // Re-check all of our vbases for vtordisp requirements (in case their
-  // non-virtual bases have vtordisp requirements).
-  for (CXXRecordDecl::base_class_const_iterator i = RD->vbases_begin(),
-                                                e = RD->vbases_end();
-       i != e; ++i) {
-    const CXXRecordDecl *BaseDecl =  i->getType()->getAsCXXRecordDecl();
-    if (!HasVtordisp.count(BaseDecl) && RequiresVtordisp(HasVtordisp, BaseDecl))
-      HasVtordisp.insert(BaseDecl);
+  // For each of our virtual bases, check if it is in the set of overridden
+  // bases or if it transitively contains a non-virtual base that is.
+  for (const CXXBaseSpecifier &Base : RD->vbases()) {
+    const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
+    if (!HasVtordispSet.count(BaseDecl) &&
+        RequiresVtordisp(BasesWithOverriddenMethods, BaseDecl))
+      HasVtordispSet.insert(BaseDecl);
   }
-
-  return HasVtordisp;
+  return HasVtordispSet;
 }
 
 /// \brief Get or compute information about the layout of the specified record
@@ -2673,19 +2742,20 @@
   if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
     Builder.cxxLayout(RD);
     return new (*this) ASTRecordLayout(
-        *this, Builder.Size, Builder.Alignment,
-        Builder.HasExtendableVFPtr && !Builder.PrimaryBase,
-        Builder.HasExtendableVFPtr,
-        Builder.VBPtrOffset, Builder.DataSize, Builder.FieldOffsets.data(),
-        Builder.FieldOffsets.size(), Builder.DataSize,
-        Builder.NonVirtualAlignment, CharUnits::Zero(), Builder.PrimaryBase,
-        false, Builder.SharedVBPtrBase, Builder.AlignAfterVBases, Builder.Bases,
-        Builder.VBases);
+        *this, Builder.Size, Builder.Alignment, Builder.RequiredAlignment,
+        Builder.HasOwnVFPtr,
+        Builder.HasOwnVFPtr || Builder.PrimaryBase,
+        Builder.VBPtrOffset, Builder.NonVirtualSize, Builder.FieldOffsets.data(),
+        Builder.FieldOffsets.size(), Builder.NonVirtualSize,
+        Builder.Alignment, CharUnits::Zero(), Builder.PrimaryBase,
+        false, Builder.SharedVBPtrBase,
+        Builder.EndsWithZeroSizedObject, Builder.LeadsWithZeroSizedBase,
+        Builder.Bases, Builder.VBases);
   } else {
     Builder.layout(D);
     return new (*this) ASTRecordLayout(
-        *this, Builder.Size, Builder.Alignment, Builder.Size,
-        Builder.FieldOffsets.data(), Builder.FieldOffsets.size());
+        *this, Builder.Size, Builder.Alignment, Builder.RequiredAlignment,
+        Builder.Size, Builder.FieldOffsets.data(), Builder.FieldOffsets.size());
   }
 }
 
@@ -2713,7 +2783,7 @@
   const ASTRecordLayout *Entry = ASTRecordLayouts[D];
   if (Entry) return *Entry;
 
-  const ASTRecordLayout *NewEntry = 0;
+  const ASTRecordLayout *NewEntry = nullptr;
 
   if (isMsLayout(D) && !D->getASTContext().getExternalSource()) {
     NewEntry = BuildMicrosoftASTRecordLayout(D);
@@ -2736,6 +2806,8 @@
     NewEntry =
       new (*this) ASTRecordLayout(*this, Builder.getSize(), 
                                   Builder.Alignment,
+                                  /*RequiredAlignment : used by MS-ABI)*/
+                                  Builder.Alignment,
                                   Builder.HasOwnVFPtr,
                                   RD->isDynamicClass(),
                                   CharUnits::fromQuantity(-1),
@@ -2747,15 +2819,17 @@
                                   EmptySubobjects.SizeOfLargestEmptySubobject,
                                   Builder.PrimaryBase,
                                   Builder.PrimaryBaseIsVirtual,
-                                  0, true,
+                                  nullptr, false, false,
                                   Builder.Bases, Builder.VBases);
   } else {
-    RecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/0);
+    RecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/nullptr);
     Builder.Layout(D);
 
     NewEntry =
       new (*this) ASTRecordLayout(*this, Builder.getSize(), 
                                   Builder.Alignment,
+                                  /*RequiredAlignment : used by MS-ABI)*/
+                                  Builder.Alignment,
                                   Builder.getSize(),
                                   Builder.FieldOffsets.data(),
                                   Builder.FieldOffsets.size());
@@ -2773,16 +2847,25 @@
 
 const CXXMethodDecl *ASTContext::getCurrentKeyFunction(const CXXRecordDecl *RD) {
   if (!getTargetInfo().getCXXABI().hasKeyFunctions())
-    return 0;
+    return nullptr;
 
   assert(RD->getDefinition() && "Cannot get key function for forward decl!");
   RD = cast<CXXRecordDecl>(RD->getDefinition());
 
-  LazyDeclPtr &Entry = KeyFunctions[RD];
-  if (!Entry)
-    Entry = const_cast<CXXMethodDecl*>(computeKeyFunction(*this, RD));
+  // Beware:
+  //  1) computing the key function might trigger deserialization, which might
+  //     invalidate iterators into KeyFunctions
+  //  2) 'get' on the LazyDeclPtr might also trigger deserialization and
+  //     invalidate the LazyDeclPtr within the map itself
+  LazyDeclPtr Entry = KeyFunctions[RD];
+  const Decl *Result =
+      Entry ? Entry.get(getExternalSource()) : computeKeyFunction(*this, RD);
 
-  return cast_or_null<CXXMethodDecl>(Entry.get(getExternalSource()));
+  // Store it back if it changed.
+  if (Entry.isOffset() || Entry.isValid() != bool(Result))
+    KeyFunctions[RD] = const_cast<Decl*>(Result);
+
+  return cast_or_null<CXXMethodDecl>(Result);
 }
 
 void ASTContext::setNonKeyFunction(const CXXMethodDecl *Method) {
@@ -2799,10 +2882,12 @@
   if (I == KeyFunctions.end()) return;
 
   // If it is cached, check whether it's the target method, and if so,
-  // remove it from the cache.
-  if (I->second.get(getExternalSource()) == Method) {
+  // remove it from the cache. Note, the call to 'get' might invalidate
+  // the iterator and the LazyDeclPtr object within the map.
+  LazyDeclPtr Ptr = I->second;
+  if (Ptr.get(getExternalSource()) == Method) {
     // FIXME: remember that we did this for module / chained PCH state?
-    KeyFunctions.erase(I);
+    KeyFunctions.erase(Method->getParent());
   }
 }
 
@@ -2819,10 +2904,8 @@
     const IndirectFieldDecl *IFD = cast<IndirectFieldDecl>(VD);
 
     OffsetInBits = 0;
-    for (IndirectFieldDecl::chain_iterator CI = IFD->chain_begin(),
-                                           CE = IFD->chain_end();
-         CI != CE; ++CI)
-      OffsetInBits += ::getFieldOffset(*this, cast<FieldDecl>(*CI));
+    for (const NamedDecl *ND : IFD->chain())
+      OffsetInBits += ::getFieldOffset(*this, cast<FieldDecl>(ND));
   }
 
   return OffsetInBits;
@@ -2856,15 +2939,17 @@
     // entries later; however we shouldn't look up implementations
     // frequently.
     if (SynthCount == 0)
-      return getObjCLayout(D, 0);
+      return getObjCLayout(D, nullptr);
   }
 
-  RecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/0);
+  RecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/nullptr);
   Builder.Layout(D);
 
   const ASTRecordLayout *NewEntry =
     new (*this) ASTRecordLayout(*this, Builder.getSize(), 
                                 Builder.Alignment,
+                                /*RequiredAlignment : used by MS-ABI)*/
+                                Builder.Alignment,
                                 Builder.getDataSize(),
                                 Builder.FieldOffsets.data(),
                                 Builder.FieldOffsets.size());
@@ -2917,19 +3002,24 @@
     OS << '(' << *RD << " vftable pointer)\n";
   }
 
-  // Dump (non-virtual) bases
-  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
-         E = RD->bases_end(); I != E; ++I) {
-    assert(!I->getType()->isDependentType() &&
+  // Collect nvbases.
+  SmallVector<const CXXRecordDecl *, 4> Bases;
+  for (const CXXBaseSpecifier &Base : RD->bases()) {
+    assert(!Base.getType()->isDependentType() &&
            "Cannot layout class with dependent bases.");
-    if (I->isVirtual())
-      continue;
+    if (!Base.isVirtual())
+      Bases.push_back(Base.getType()->getAsCXXRecordDecl());
+  }
 
-    const CXXRecordDecl *Base =
-      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+  // Sort nvbases by offset.
+  std::stable_sort(Bases.begin(), Bases.end(),
+                   [&](const CXXRecordDecl *L, const CXXRecordDecl *R) {
+    return Layout.getBaseClassOffset(L) < Layout.getBaseClassOffset(R);
+  });
 
+  // Dump (non-virtual) bases
+  for (const CXXRecordDecl *Base : Bases) {
     CharUnits BaseOffset = Offset + Layout.getBaseClassOffset(Base);
-
     DumpCXXRecordLayout(OS, Base, C, BaseOffset, IndentLevel,
                         Base == PrimaryBase ? "(primary base)" : "(base)",
                         /*IncludeVirtualBases=*/false);
@@ -2949,13 +3039,11 @@
     CharUnits FieldOffset = Offset + 
       C.toCharUnitsFromBits(Layout.getFieldOffset(FieldNo));
 
-    if (const RecordType *RT = Field.getType()->getAs<RecordType>()) {
-      if (const CXXRecordDecl *D = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
-        DumpCXXRecordLayout(OS, D, C, FieldOffset, IndentLevel,
-                            Field.getName().data(),
-                            /*IncludeVirtualBases=*/true);
-        continue;
-      }
+    if (const CXXRecordDecl *D = Field.getType()->getAsCXXRecordDecl()) {
+      DumpCXXRecordLayout(OS, D, C, FieldOffset, IndentLevel,
+                          Field.getName().data(),
+                          /*IncludeVirtualBases=*/true);
+      continue;
     }
 
     PrintOffset(OS, FieldOffset, IndentLevel);
@@ -2968,11 +3056,9 @@
   // Dump virtual bases.
   const ASTRecordLayout::VBaseOffsetsMapTy &vtordisps = 
     Layout.getVBaseOffsetsMap();
-  for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(),
-         E = RD->vbases_end(); I != E; ++I) {
-    assert(I->isVirtual() && "Found non-virtual class!");
-    const CXXRecordDecl *VBase =
-      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+  for (const CXXBaseSpecifier &Base : RD->vbases()) {
+    assert(Base.isVirtual() && "Found non-virtual class!");
+    const CXXRecordDecl *VBase = Base.getType()->getAsCXXRecordDecl();
 
     CharUnits VBaseOffset = Offset + Layout.getVBaseClassOffset(VBase);
 
@@ -2995,8 +3081,7 @@
 
   PrintIndentNoOffset(OS, IndentLevel - 1);
   OS << " nvsize=" << Layout.getNonVirtualSize().getQuantity();
-  OS << ", nvalign=" << Layout.getNonVirtualAlign().getQuantity() << "]\n";
-  OS << '\n';
+  OS << ", nvalign=" << Layout.getNonVirtualAlignment().getQuantity() << "]\n";
 }
 
 void ASTContext::DumpRecordLayout(const RecordDecl *RD,
@@ -3006,7 +3091,7 @@
 
   if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
     if (!Simple)
-      return DumpCXXRecordLayout(OS, CXXRD, *this, CharUnits(), 0, 0,
+      return DumpCXXRecordLayout(OS, CXXRD, *this, CharUnits(), 0, nullptr,
                                  /*IncludeVirtualBases=*/true);
 
   OS << "Type: " << getTypeDeclType(RD).getAsString() << "\n";
diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp
index de85161..a8483dc 100644
--- a/lib/AST/Stmt.cpp
+++ b/lib/AST/Stmt.cpp
@@ -65,13 +65,13 @@
   unsigned sum = 0;
   llvm::errs() << "\n*** Stmt/Expr Stats:\n";
   for (int i = 0; i != Stmt::lastStmtConstant+1; i++) {
-    if (StmtClassInfo[i].Name == 0) continue;
+    if (StmtClassInfo[i].Name == nullptr) continue;
     sum += StmtClassInfo[i].Counter;
   }
   llvm::errs() << "  " << sum << " stmts/exprs total.\n";
   sum = 0;
   for (int i = 0; i != Stmt::lastStmtConstant+1; i++) {
-    if (StmtClassInfo[i].Name == 0) continue;
+    if (StmtClassInfo[i].Name == nullptr) continue;
     if (StmtClassInfo[i].Counter == 0) continue;
     llvm::errs() << "    " << StmtClassInfo[i].Counter << " "
                  << StmtClassInfo[i].Name << ", " << StmtClassInfo[i].Size
@@ -260,7 +260,7 @@
          "NumStmts doesn't fit in bits of CompoundStmtBits.NumStmts!");
 
   if (Stmts.size() == 0) {
-    Body = 0;
+    Body = nullptr;
     return;
   }
 
@@ -285,8 +285,8 @@
 AttributedStmt *AttributedStmt::Create(const ASTContext &C, SourceLocation Loc,
                                        ArrayRef<const Attr*> Attrs,
                                        Stmt *SubStmt) {
-  void *Mem = C.Allocate(sizeof(AttributedStmt) +
-                         sizeof(Attr*) * (Attrs.size() - 1),
+  assert(!Attrs.empty() && "Attrs should not be empty");
+  void *Mem = C.Allocate(sizeof(AttributedStmt) + sizeof(Attr *) * Attrs.size(),
                          llvm::alignOf<AttributedStmt>());
   return new (Mem) AttributedStmt(Loc, Attrs, SubStmt);
 }
@@ -294,8 +294,7 @@
 AttributedStmt *AttributedStmt::CreateEmpty(const ASTContext &C,
                                             unsigned NumAttrs) {
   assert(NumAttrs > 0 && "NumAttrs should be greater than zero");
-  void *Mem = C.Allocate(sizeof(AttributedStmt) +
-                         sizeof(Attr*) * (NumAttrs - 1),
+  void *Mem = C.Allocate(sizeof(AttributedStmt) + sizeof(Attr *) * NumAttrs,
                          llvm::alignOf<AttributedStmt>());
   return new (Mem) AttributedStmt(EmptyShell(), NumAttrs);
 }
@@ -554,7 +553,7 @@
 
       // Find the ']'.
       const char *NameEnd = (const char*)memchr(CurPtr, ']', StrEnd-CurPtr);
-      if (NameEnd == 0)
+      if (NameEnd == nullptr)
         return diag::err_asm_unterminated_symbolic_operand_name;
       if (NameEnd == CurPtr)
         return diag::err_asm_empty_symbolic_operand_name;
@@ -720,8 +719,7 @@
                              Stmt **CatchStmts, unsigned NumCatchStmts,
                              Stmt *atFinallyStmt)
   : Stmt(ObjCAtTryStmtClass), AtTryLoc(atTryLoc),
-    NumCatchStmts(NumCatchStmts), HasFinally(atFinallyStmt != 0)
-{
+    NumCatchStmts(NumCatchStmts), HasFinally(atFinallyStmt != nullptr) {
   Stmt **Stmts = getStmts();
   Stmts[0] = atTryStmt;
   for (unsigned I = 0; I != NumCatchStmts; ++I)
@@ -738,7 +736,7 @@
                                      unsigned NumCatchStmts,
                                      Stmt *atFinallyStmt) {
   unsigned Size = sizeof(ObjCAtTryStmt) +
-    (1 + NumCatchStmts + (atFinallyStmt != 0)) * sizeof(Stmt *);
+    (1 + NumCatchStmts + (atFinallyStmt != nullptr)) * sizeof(Stmt *);
   void *Mem = Context.Allocate(Size, llvm::alignOf<ObjCAtTryStmt>());
   return new (Mem) ObjCAtTryStmt(atTryLoc, atTryStmt, CatchStmts, NumCatchStmts,
                                  atFinallyStmt);
@@ -803,7 +801,7 @@
 Expr *CXXForRangeStmt::getRangeInit() {
   DeclStmt *RangeStmt = getRangeStmt();
   VarDecl *RangeDecl = dyn_cast_or_null<VarDecl>(RangeStmt->getSingleDecl());
-  assert(RangeDecl &&& "for-range should have a single var decl");
+  assert(RangeDecl && "for-range should have a single var decl");
   return RangeDecl->getInit();
 }
 
@@ -833,7 +831,7 @@
 
 VarDecl *IfStmt::getConditionVariable() const {
   if (!SubExprs[VAR])
-    return 0;
+    return nullptr;
 
   DeclStmt *DS = cast<DeclStmt>(SubExprs[VAR]);
   return cast<VarDecl>(DS->getSingleDecl());
@@ -841,7 +839,7 @@
 
 void IfStmt::setConditionVariable(const ASTContext &C, VarDecl *V) {
   if (!V) {
-    SubExprs[VAR] = 0;
+    SubExprs[VAR] = nullptr;
     return;
   }
 
@@ -864,7 +862,7 @@
 
 VarDecl *ForStmt::getConditionVariable() const {
   if (!SubExprs[CONDVAR])
-    return 0;
+    return nullptr;
 
   DeclStmt *DS = cast<DeclStmt>(SubExprs[CONDVAR]);
   return cast<VarDecl>(DS->getSingleDecl());
@@ -872,7 +870,7 @@
 
 void ForStmt::setConditionVariable(const ASTContext &C, VarDecl *V) {
   if (!V) {
-    SubExprs[CONDVAR] = 0;
+    SubExprs[CONDVAR] = nullptr;
     return;
   }
 
@@ -882,16 +880,16 @@
 }
 
 SwitchStmt::SwitchStmt(const ASTContext &C, VarDecl *Var, Expr *cond)
-  : Stmt(SwitchStmtClass), FirstCase(0), AllEnumCasesCovered(0)
+  : Stmt(SwitchStmtClass), FirstCase(nullptr), AllEnumCasesCovered(0)
 {
   setConditionVariable(C, Var);
   SubExprs[COND] = cond;
-  SubExprs[BODY] = NULL;
+  SubExprs[BODY] = nullptr;
 }
 
 VarDecl *SwitchStmt::getConditionVariable() const {
   if (!SubExprs[VAR])
-    return 0;
+    return nullptr;
 
   DeclStmt *DS = cast<DeclStmt>(SubExprs[VAR]);
   return cast<VarDecl>(DS->getSingleDecl());
@@ -899,7 +897,7 @@
 
 void SwitchStmt::setConditionVariable(const ASTContext &C, VarDecl *V) {
   if (!V) {
-    SubExprs[VAR] = 0;
+    SubExprs[VAR] = nullptr;
     return;
   }
 
@@ -925,7 +923,7 @@
 
 VarDecl *WhileStmt::getConditionVariable() const {
   if (!SubExprs[VAR])
-    return 0;
+    return nullptr;
 
   DeclStmt *DS = cast<DeclStmt>(SubExprs[VAR]);
   return cast<VarDecl>(DS->getSingleDecl());
@@ -933,7 +931,7 @@
 
 void WhileStmt::setConditionVariable(const ASTContext &C, VarDecl *V) {
   if (!V) {
-    SubExprs[VAR] = 0;
+    SubExprs[VAR] = nullptr;
     return;
   }
 
@@ -947,7 +945,7 @@
   if (AddrLabelExpr *E =
         dyn_cast<AddrLabelExpr>(getTarget()->IgnoreParenImpCasts()))
     return E->getLabel();
-  return 0;
+  return nullptr;
 }
 
 // ReturnStmt
@@ -958,22 +956,20 @@
   return cast_or_null<Expr>(RetExpr);
 }
 
-SEHTryStmt::SEHTryStmt(bool IsCXXTry,
-                       SourceLocation TryLoc,
-                       Stmt *TryBlock,
-                       Stmt *Handler)
-  : Stmt(SEHTryStmtClass),
-    IsCXXTry(IsCXXTry),
-    TryLoc(TryLoc)
-{
-  Children[TRY]     = TryBlock;
+SEHTryStmt::SEHTryStmt(bool IsCXXTry, SourceLocation TryLoc, Stmt *TryBlock,
+                       Stmt *Handler, int HandlerIndex, int HandlerParentIndex)
+    : Stmt(SEHTryStmtClass), IsCXXTry(IsCXXTry), TryLoc(TryLoc),
+      HandlerIndex(HandlerIndex), HandlerParentIndex(HandlerParentIndex) {
+  Children[TRY] = TryBlock;
   Children[HANDLER] = Handler;
 }
 
-SEHTryStmt* SEHTryStmt::Create(const ASTContext &C, bool IsCXXTry,
+SEHTryStmt *SEHTryStmt::Create(const ASTContext &C, bool IsCXXTry,
                                SourceLocation TryLoc, Stmt *TryBlock,
-                               Stmt *Handler) {
-  return new(C) SEHTryStmt(IsCXXTry,TryLoc,TryBlock,Handler);
+                               Stmt *Handler, int HandlerIndex,
+                               int HandlerParentIndex) {
+  return new (C) SEHTryStmt(IsCXXTry, TryLoc, TryBlock, Handler, HandlerIndex,
+                            HandlerParentIndex);
 }
 
 SEHExceptStmt* SEHTryStmt::getExceptHandler() const {
@@ -1049,8 +1045,8 @@
 
 CapturedStmt::CapturedStmt(EmptyShell Empty, unsigned NumCaptures)
   : Stmt(CapturedStmtClass, Empty), NumCaptures(NumCaptures),
-    CapDeclAndKind(0, CR_Default), TheRecordDecl(0) {
-  getStoredStmts()[NumCaptures] = 0;
+    CapDeclAndKind(nullptr, CR_Default), TheRecordDecl(nullptr) {
+  getStoredStmts()[NumCaptures] = nullptr;
 }
 
 CapturedStmt *CapturedStmt::Create(const ASTContext &Context, Stmt *S,
@@ -1100,15 +1096,14 @@
 }
 
 bool CapturedStmt::capturesVariable(const VarDecl *Var) const {
-  for (const_capture_iterator I = capture_begin(),
-                              E = capture_end(); I != E; ++I) {
-    if (!I->capturesVariable())
+  for (const auto &I : captures()) {
+    if (!I.capturesVariable())
       continue;
 
     // This does not handle variable redeclarations. This should be
     // extended to capture variables with redeclarations, for example
     // a thread-private variable in OpenMP.
-    if (I->getCapturedVar() == Var)
+    if (I.getCapturedVar() == Var)
       return true;
   }
 
@@ -1130,8 +1125,9 @@
                                            SourceLocation LParenLoc,
                                            SourceLocation EndLoc,
                                            ArrayRef<Expr *> VL) {
-  void *Mem = C.Allocate(sizeof(OMPPrivateClause) + sizeof(Expr *) * VL.size(),
-                         llvm::alignOf<OMPPrivateClause>());
+  void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPPrivateClause),
+                                                  llvm::alignOf<Expr *>()) +
+                         sizeof(Expr *) * VL.size());
   OMPPrivateClause *Clause = new (Mem) OMPPrivateClause(StartLoc, LParenLoc,
                                                         EndLoc, VL.size());
   Clause->setVarRefs(VL);
@@ -1140,8 +1136,9 @@
 
 OMPPrivateClause *OMPPrivateClause::CreateEmpty(const ASTContext &C,
                                                 unsigned N) {
-  void *Mem = C.Allocate(sizeof(OMPPrivateClause) + sizeof(Expr *) * N,
-                         llvm::alignOf<OMPPrivateClause>());
+  void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPPrivateClause),
+                                                  llvm::alignOf<Expr *>()) +
+                         sizeof(Expr *) * N);
   return new (Mem) OMPPrivateClause(N);
 }
 
@@ -1150,9 +1147,9 @@
                                                      SourceLocation LParenLoc,
                                                      SourceLocation EndLoc,
                                                      ArrayRef<Expr *> VL) {
-  void *Mem = C.Allocate(sizeof(OMPFirstprivateClause) +
-                         sizeof(Expr *) * VL.size(),
-                         llvm::alignOf<OMPFirstprivateClause>());
+  void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPFirstprivateClause),
+                                                  llvm::alignOf<Expr *>()) +
+                         sizeof(Expr *) * VL.size());
   OMPFirstprivateClause *Clause = new (Mem) OMPFirstprivateClause(StartLoc,
                                                                   LParenLoc,
                                                                   EndLoc,
@@ -1163,18 +1160,42 @@
 
 OMPFirstprivateClause *OMPFirstprivateClause::CreateEmpty(const ASTContext &C,
                                                           unsigned N) {
-  void *Mem = C.Allocate(sizeof(OMPFirstprivateClause) + sizeof(Expr *) * N,
-                         llvm::alignOf<OMPFirstprivateClause>());
+  void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPFirstprivateClause),
+                                                  llvm::alignOf<Expr *>()) +
+                         sizeof(Expr *) * N);
   return new (Mem) OMPFirstprivateClause(N);
 }
 
+OMPLastprivateClause *OMPLastprivateClause::Create(const ASTContext &C,
+                                                   SourceLocation StartLoc,
+                                                   SourceLocation LParenLoc,
+                                                   SourceLocation EndLoc,
+                                                   ArrayRef<Expr *> VL) {
+  void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPLastprivateClause),
+                                                  llvm::alignOf<Expr *>()) +
+                         sizeof(Expr *) * VL.size());
+  OMPLastprivateClause *Clause =
+      new (Mem) OMPLastprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
+  Clause->setVarRefs(VL);
+  return Clause;
+}
+
+OMPLastprivateClause *OMPLastprivateClause::CreateEmpty(const ASTContext &C,
+                                                        unsigned N) {
+  void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPLastprivateClause),
+                                                  llvm::alignOf<Expr *>()) +
+                         sizeof(Expr *) * N);
+  return new (Mem) OMPLastprivateClause(N);
+}
+
 OMPSharedClause *OMPSharedClause::Create(const ASTContext &C,
                                          SourceLocation StartLoc,
                                          SourceLocation LParenLoc,
                                          SourceLocation EndLoc,
                                          ArrayRef<Expr *> VL) {
-  void *Mem = C.Allocate(sizeof(OMPSharedClause) + sizeof(Expr *) * VL.size(),
-                         llvm::alignOf<OMPSharedClause>());
+  void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPSharedClause),
+                                                  llvm::alignOf<Expr *>()) +
+                         sizeof(Expr *) * VL.size());
   OMPSharedClause *Clause = new (Mem) OMPSharedClause(StartLoc, LParenLoc,
                                                       EndLoc, VL.size());
   Clause->setVarRefs(VL);
@@ -1183,15 +1204,148 @@
 
 OMPSharedClause *OMPSharedClause::CreateEmpty(const ASTContext &C,
                                               unsigned N) {
-  void *Mem = C.Allocate(sizeof(OMPSharedClause) + sizeof(Expr *) * N,
-                         llvm::alignOf<OMPSharedClause>());
+  void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPSharedClause),
+                                                  llvm::alignOf<Expr *>()) +
+                         sizeof(Expr *) * N);
   return new (Mem) OMPSharedClause(N);
 }
 
+OMPLinearClause *OMPLinearClause::Create(const ASTContext &C,
+                                         SourceLocation StartLoc,
+                                         SourceLocation LParenLoc,
+                                         SourceLocation ColonLoc,
+                                         SourceLocation EndLoc,
+                                         ArrayRef<Expr *> VL, Expr *Step) {
+  void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPLinearClause),
+                                                  llvm::alignOf<Expr *>()) +
+                         sizeof(Expr *) * (VL.size() + 1));
+  OMPLinearClause *Clause = new (Mem)
+      OMPLinearClause(StartLoc, LParenLoc, ColonLoc, EndLoc, VL.size());
+  Clause->setVarRefs(VL);
+  Clause->setStep(Step);
+  return Clause;
+}
+
+OMPLinearClause *OMPLinearClause::CreateEmpty(const ASTContext &C,
+                                              unsigned NumVars) {
+  void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPLinearClause),
+                                                  llvm::alignOf<Expr *>()) +
+                         sizeof(Expr *) * (NumVars + 1));
+  return new (Mem) OMPLinearClause(NumVars);
+}
+
+OMPAlignedClause *
+OMPAlignedClause::Create(const ASTContext &C, SourceLocation StartLoc,
+                         SourceLocation LParenLoc, SourceLocation ColonLoc,
+                         SourceLocation EndLoc, ArrayRef<Expr *> VL, Expr *A) {
+  void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPAlignedClause),
+                                                  llvm::alignOf<Expr *>()) +
+                         sizeof(Expr *) * (VL.size() + 1));
+  OMPAlignedClause *Clause = new (Mem)
+      OMPAlignedClause(StartLoc, LParenLoc, ColonLoc, EndLoc, VL.size());
+  Clause->setVarRefs(VL);
+  Clause->setAlignment(A);
+  return Clause;
+}
+
+OMPAlignedClause *OMPAlignedClause::CreateEmpty(const ASTContext &C,
+                                                unsigned NumVars) {
+  void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPAlignedClause),
+                                                  llvm::alignOf<Expr *>()) +
+                         sizeof(Expr *) * (NumVars + 1));
+  return new (Mem) OMPAlignedClause(NumVars);
+}
+
+OMPCopyinClause *OMPCopyinClause::Create(const ASTContext &C,
+                                         SourceLocation StartLoc,
+                                         SourceLocation LParenLoc,
+                                         SourceLocation EndLoc,
+                                         ArrayRef<Expr *> VL) {
+  void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPCopyinClause),
+                                                  llvm::alignOf<Expr *>()) +
+                         sizeof(Expr *) * VL.size());
+  OMPCopyinClause *Clause = new (Mem) OMPCopyinClause(StartLoc, LParenLoc,
+                                                      EndLoc, VL.size());
+  Clause->setVarRefs(VL);
+  return Clause;
+}
+
+OMPCopyinClause *OMPCopyinClause::CreateEmpty(const ASTContext &C,
+                                              unsigned N) {
+  void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPCopyinClause),
+                                                  llvm::alignOf<Expr *>()) +
+                         sizeof(Expr *) * N);
+  return new (Mem) OMPCopyinClause(N);
+}
+
+OMPCopyprivateClause *OMPCopyprivateClause::Create(const ASTContext &C,
+                                                   SourceLocation StartLoc,
+                                                   SourceLocation LParenLoc,
+                                                   SourceLocation EndLoc,
+                                                   ArrayRef<Expr *> VL) {
+  void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPCopyprivateClause),
+                                                  llvm::alignOf<Expr *>()) +
+                         sizeof(Expr *) * VL.size());
+  OMPCopyprivateClause *Clause =
+      new (Mem) OMPCopyprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
+  Clause->setVarRefs(VL);
+  return Clause;
+}
+
+OMPCopyprivateClause *OMPCopyprivateClause::CreateEmpty(const ASTContext &C,
+                                                        unsigned N) {
+  void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPCopyprivateClause),
+                                                  llvm::alignOf<Expr *>()) +
+                         sizeof(Expr *) * N);
+  return new (Mem) OMPCopyprivateClause(N);
+}
+
 void OMPExecutableDirective::setClauses(ArrayRef<OMPClause *> Clauses) {
-  assert(Clauses.size() == this->Clauses.size() &&
+  assert(Clauses.size() == getNumClauses() &&
          "Number of clauses is not the same as the preallocated buffer");
-  std::copy(Clauses.begin(), Clauses.end(), this->Clauses.begin());
+  std::copy(Clauses.begin(), Clauses.end(), getClauses().begin());
+}
+
+OMPReductionClause *OMPReductionClause::Create(
+    const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
+    SourceLocation EndLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL,
+    NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo) {
+  void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPReductionClause),
+                                                  llvm::alignOf<Expr *>()) +
+                         sizeof(Expr *) * VL.size());
+  OMPReductionClause *Clause = new (Mem) OMPReductionClause(
+      StartLoc, LParenLoc, EndLoc, ColonLoc, VL.size(), QualifierLoc, NameInfo);
+  Clause->setVarRefs(VL);
+  return Clause;
+}
+
+OMPReductionClause *OMPReductionClause::CreateEmpty(const ASTContext &C,
+                                                    unsigned N) {
+  void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPReductionClause),
+                                                  llvm::alignOf<Expr *>()) +
+                         sizeof(Expr *) * N);
+  return new (Mem) OMPReductionClause(N);
+}
+
+OMPFlushClause *OMPFlushClause::Create(const ASTContext &C,
+                                       SourceLocation StartLoc,
+                                       SourceLocation LParenLoc,
+                                       SourceLocation EndLoc,
+                                       ArrayRef<Expr *> VL) {
+  void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPFlushClause),
+                                                  llvm::alignOf<Expr *>()) +
+                         sizeof(Expr *) * VL.size());
+  OMPFlushClause *Clause =
+      new (Mem) OMPFlushClause(StartLoc, LParenLoc, EndLoc, VL.size());
+  Clause->setVarRefs(VL);
+  return Clause;
+}
+
+OMPFlushClause *OMPFlushClause::CreateEmpty(const ASTContext &C, unsigned N) {
+  void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPFlushClause),
+                                                  llvm::alignOf<Expr *>()) +
+                         sizeof(Expr *) * N);
+  return new (Mem) OMPFlushClause(N);
 }
 
 OMPParallelDirective *OMPParallelDirective::Create(
@@ -1200,9 +1354,10 @@
                                               SourceLocation EndLoc,
                                               ArrayRef<OMPClause *> Clauses,
                                               Stmt *AssociatedStmt) {
-  void *Mem = C.Allocate(sizeof(OMPParallelDirective) +
-                         sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *),
-                         llvm::alignOf<OMPParallelDirective>());
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelDirective),
+                                           llvm::alignOf<OMPClause *>());
+  void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() +
+                         sizeof(Stmt *));
   OMPParallelDirective *Dir = new (Mem) OMPParallelDirective(StartLoc, EndLoc,
                                                              Clauses.size());
   Dir->setClauses(Clauses);
@@ -1211,10 +1366,315 @@
 }
 
 OMPParallelDirective *OMPParallelDirective::CreateEmpty(const ASTContext &C,
-                                                        unsigned N,
+                                                        unsigned NumClauses,
                                                         EmptyShell) {
-  void *Mem = C.Allocate(sizeof(OMPParallelDirective) +
-                         sizeof(OMPClause *) * N + sizeof(Stmt *),
-                         llvm::alignOf<OMPParallelDirective>());
-  return new (Mem) OMPParallelDirective(N);
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelDirective),
+                                           llvm::alignOf<OMPClause *>());
+  void *Mem = C.Allocate(Size + sizeof(OMPClause *) * NumClauses +
+                         sizeof(Stmt *));
+  return new (Mem) OMPParallelDirective(NumClauses);
 }
+
+OMPSimdDirective *
+OMPSimdDirective::Create(const ASTContext &C, SourceLocation StartLoc,
+                         SourceLocation EndLoc, unsigned CollapsedNum,
+                         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSimdDirective),
+                                           llvm::alignOf<OMPClause *>());
+  void *Mem =
+      C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
+  OMPSimdDirective *Dir = new (Mem)
+      OMPSimdDirective(StartLoc, EndLoc, CollapsedNum, Clauses.size());
+  Dir->setClauses(Clauses);
+  Dir->setAssociatedStmt(AssociatedStmt);
+  return Dir;
+}
+
+OMPSimdDirective *OMPSimdDirective::CreateEmpty(const ASTContext &C,
+                                                unsigned NumClauses,
+                                                unsigned CollapsedNum,
+                                                EmptyShell) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSimdDirective),
+                                           llvm::alignOf<OMPClause *>());
+  void *Mem =
+      C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
+  return new (Mem) OMPSimdDirective(CollapsedNum, NumClauses);
+}
+
+OMPForDirective *
+OMPForDirective::Create(const ASTContext &C, SourceLocation StartLoc,
+                        SourceLocation EndLoc, unsigned CollapsedNum,
+                        ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPForDirective),
+                                           llvm::alignOf<OMPClause *>());
+  void *Mem =
+      C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
+  OMPForDirective *Dir =
+      new (Mem) OMPForDirective(StartLoc, EndLoc, CollapsedNum, Clauses.size());
+  Dir->setClauses(Clauses);
+  Dir->setAssociatedStmt(AssociatedStmt);
+  return Dir;
+}
+
+OMPForDirective *OMPForDirective::CreateEmpty(const ASTContext &C,
+                                              unsigned NumClauses,
+                                              unsigned CollapsedNum,
+                                              EmptyShell) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPForDirective),
+                                           llvm::alignOf<OMPClause *>());
+  void *Mem =
+      C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
+  return new (Mem) OMPForDirective(CollapsedNum, NumClauses);
+}
+
+OMPSectionsDirective *OMPSectionsDirective::Create(
+    const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+    ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSectionsDirective),
+                                           llvm::alignOf<OMPClause *>());
+  void *Mem =
+      C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
+  OMPSectionsDirective *Dir =
+      new (Mem) OMPSectionsDirective(StartLoc, EndLoc, Clauses.size());
+  Dir->setClauses(Clauses);
+  Dir->setAssociatedStmt(AssociatedStmt);
+  return Dir;
+}
+
+OMPSectionsDirective *OMPSectionsDirective::CreateEmpty(const ASTContext &C,
+                                                        unsigned NumClauses,
+                                                        EmptyShell) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSectionsDirective),
+                                           llvm::alignOf<OMPClause *>());
+  void *Mem =
+      C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
+  return new (Mem) OMPSectionsDirective(NumClauses);
+}
+
+OMPSectionDirective *OMPSectionDirective::Create(const ASTContext &C,
+                                                 SourceLocation StartLoc,
+                                                 SourceLocation EndLoc,
+                                                 Stmt *AssociatedStmt) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSectionsDirective),
+                                           llvm::alignOf<Stmt *>());
+  void *Mem = C.Allocate(Size + sizeof(Stmt *));
+  OMPSectionDirective *Dir = new (Mem) OMPSectionDirective(StartLoc, EndLoc);
+  Dir->setAssociatedStmt(AssociatedStmt);
+  return Dir;
+}
+
+OMPSectionDirective *OMPSectionDirective::CreateEmpty(const ASTContext &C,
+                                                      EmptyShell) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSectionDirective),
+                                           llvm::alignOf<Stmt *>());
+  void *Mem = C.Allocate(Size + sizeof(Stmt *));
+  return new (Mem) OMPSectionDirective();
+}
+
+OMPSingleDirective *OMPSingleDirective::Create(const ASTContext &C,
+                                               SourceLocation StartLoc,
+                                               SourceLocation EndLoc,
+                                               ArrayRef<OMPClause *> Clauses,
+                                               Stmt *AssociatedStmt) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSingleDirective),
+                                           llvm::alignOf<OMPClause *>());
+  void *Mem =
+      C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
+  OMPSingleDirective *Dir =
+      new (Mem) OMPSingleDirective(StartLoc, EndLoc, Clauses.size());
+  Dir->setClauses(Clauses);
+  Dir->setAssociatedStmt(AssociatedStmt);
+  return Dir;
+}
+
+OMPSingleDirective *OMPSingleDirective::CreateEmpty(const ASTContext &C,
+                                                    unsigned NumClauses,
+                                                    EmptyShell) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSingleDirective),
+                                           llvm::alignOf<OMPClause *>());
+  void *Mem =
+      C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
+  return new (Mem) OMPSingleDirective(NumClauses);
+}
+
+OMPMasterDirective *OMPMasterDirective::Create(const ASTContext &C,
+                                               SourceLocation StartLoc,
+                                               SourceLocation EndLoc,
+                                               Stmt *AssociatedStmt) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPMasterDirective),
+                                           llvm::alignOf<Stmt *>());
+  void *Mem = C.Allocate(Size + sizeof(Stmt *));
+  OMPMasterDirective *Dir = new (Mem) OMPMasterDirective(StartLoc, EndLoc);
+  Dir->setAssociatedStmt(AssociatedStmt);
+  return Dir;
+}
+
+OMPMasterDirective *OMPMasterDirective::CreateEmpty(const ASTContext &C,
+                                                    EmptyShell) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPMasterDirective),
+                                           llvm::alignOf<Stmt *>());
+  void *Mem = C.Allocate(Size + sizeof(Stmt *));
+  return new (Mem) OMPMasterDirective();
+}
+
+OMPCriticalDirective *OMPCriticalDirective::Create(
+    const ASTContext &C, const DeclarationNameInfo &Name,
+    SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPCriticalDirective),
+                                           llvm::alignOf<Stmt *>());
+  void *Mem = C.Allocate(Size + sizeof(Stmt *));
+  OMPCriticalDirective *Dir =
+      new (Mem) OMPCriticalDirective(Name, StartLoc, EndLoc);
+  Dir->setAssociatedStmt(AssociatedStmt);
+  return Dir;
+}
+
+OMPCriticalDirective *OMPCriticalDirective::CreateEmpty(const ASTContext &C,
+                                                        EmptyShell) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPCriticalDirective),
+                                           llvm::alignOf<Stmt *>());
+  void *Mem = C.Allocate(Size + sizeof(Stmt *));
+  return new (Mem) OMPCriticalDirective();
+}
+
+OMPParallelForDirective *
+OMPParallelForDirective::Create(const ASTContext &C, SourceLocation StartLoc,
+                                SourceLocation EndLoc, unsigned CollapsedNum,
+                                ArrayRef<OMPClause *> Clauses,
+                                Stmt *AssociatedStmt) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelForDirective),
+                                           llvm::alignOf<OMPClause *>());
+  void *Mem =
+      C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
+  OMPParallelForDirective *Dir = new (Mem)
+      OMPParallelForDirective(StartLoc, EndLoc, CollapsedNum, Clauses.size());
+  Dir->setClauses(Clauses);
+  Dir->setAssociatedStmt(AssociatedStmt);
+  return Dir;
+}
+
+OMPParallelForDirective *
+OMPParallelForDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses,
+                                     unsigned CollapsedNum, EmptyShell) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelForDirective),
+                                           llvm::alignOf<OMPClause *>());
+  void *Mem =
+      C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
+  return new (Mem) OMPParallelForDirective(CollapsedNum, NumClauses);
+}
+
+OMPParallelSectionsDirective *OMPParallelSectionsDirective::Create(
+    const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+    ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelSectionsDirective),
+                                           llvm::alignOf<OMPClause *>());
+  void *Mem =
+      C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
+  OMPParallelSectionsDirective *Dir =
+      new (Mem) OMPParallelSectionsDirective(StartLoc, EndLoc, Clauses.size());
+  Dir->setClauses(Clauses);
+  Dir->setAssociatedStmt(AssociatedStmt);
+  return Dir;
+}
+
+OMPParallelSectionsDirective *
+OMPParallelSectionsDirective::CreateEmpty(const ASTContext &C,
+                                          unsigned NumClauses, EmptyShell) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelSectionsDirective),
+                                           llvm::alignOf<OMPClause *>());
+  void *Mem =
+      C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
+  return new (Mem) OMPParallelSectionsDirective(NumClauses);
+}
+
+OMPTaskDirective *OMPTaskDirective::Create(const ASTContext &C,
+                                           SourceLocation StartLoc,
+                                           SourceLocation EndLoc,
+                                           ArrayRef<OMPClause *> Clauses,
+                                           Stmt *AssociatedStmt) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPTaskDirective),
+                                           llvm::alignOf<OMPClause *>());
+  void *Mem =
+      C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
+  OMPTaskDirective *Dir =
+      new (Mem) OMPTaskDirective(StartLoc, EndLoc, Clauses.size());
+  Dir->setClauses(Clauses);
+  Dir->setAssociatedStmt(AssociatedStmt);
+  return Dir;
+}
+
+OMPTaskDirective *OMPTaskDirective::CreateEmpty(const ASTContext &C,
+                                                unsigned NumClauses,
+                                                EmptyShell) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPTaskDirective),
+                                           llvm::alignOf<OMPClause *>());
+  void *Mem =
+      C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
+  return new (Mem) OMPTaskDirective(NumClauses);
+}
+
+OMPTaskyieldDirective *OMPTaskyieldDirective::Create(const ASTContext &C,
+                                                     SourceLocation StartLoc,
+                                                     SourceLocation EndLoc) {
+  void *Mem = C.Allocate(sizeof(OMPTaskyieldDirective));
+  OMPTaskyieldDirective *Dir =
+      new (Mem) OMPTaskyieldDirective(StartLoc, EndLoc);
+  return Dir;
+}
+
+OMPTaskyieldDirective *OMPTaskyieldDirective::CreateEmpty(const ASTContext &C,
+                                                          EmptyShell) {
+  void *Mem = C.Allocate(sizeof(OMPTaskyieldDirective));
+  return new (Mem) OMPTaskyieldDirective();
+}
+
+OMPBarrierDirective *OMPBarrierDirective::Create(const ASTContext &C,
+                                                 SourceLocation StartLoc,
+                                                 SourceLocation EndLoc) {
+  void *Mem = C.Allocate(sizeof(OMPBarrierDirective));
+  OMPBarrierDirective *Dir = new (Mem) OMPBarrierDirective(StartLoc, EndLoc);
+  return Dir;
+}
+
+OMPBarrierDirective *OMPBarrierDirective::CreateEmpty(const ASTContext &C,
+                                                      EmptyShell) {
+  void *Mem = C.Allocate(sizeof(OMPBarrierDirective));
+  return new (Mem) OMPBarrierDirective();
+}
+
+OMPTaskwaitDirective *OMPTaskwaitDirective::Create(const ASTContext &C,
+                                                   SourceLocation StartLoc,
+                                                   SourceLocation EndLoc) {
+  void *Mem = C.Allocate(sizeof(OMPTaskwaitDirective));
+  OMPTaskwaitDirective *Dir = new (Mem) OMPTaskwaitDirective(StartLoc, EndLoc);
+  return Dir;
+}
+
+OMPTaskwaitDirective *OMPTaskwaitDirective::CreateEmpty(const ASTContext &C,
+                                                        EmptyShell) {
+  void *Mem = C.Allocate(sizeof(OMPTaskwaitDirective));
+  return new (Mem) OMPTaskwaitDirective();
+}
+
+OMPFlushDirective *OMPFlushDirective::Create(const ASTContext &C,
+                                             SourceLocation StartLoc,
+                                             SourceLocation EndLoc,
+                                             ArrayRef<OMPClause *> Clauses) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPFlushDirective),
+                                           llvm::alignOf<OMPClause *>());
+  void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size());
+  OMPFlushDirective *Dir =
+      new (Mem) OMPFlushDirective(StartLoc, EndLoc, Clauses.size());
+  Dir->setClauses(Clauses);
+  return Dir;
+}
+
+OMPFlushDirective *OMPFlushDirective::CreateEmpty(const ASTContext &C,
+                                                  unsigned NumClauses,
+                                                  EmptyShell) {
+  unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPFlushDirective),
+                                           llvm::alignOf<OMPClause *>());
+  void *Mem = C.Allocate(Size + sizeof(OMPClause *) * NumClauses);
+  return new (Mem) OMPFlushDirective(NumClauses);
+}
+
diff --git a/lib/AST/StmtIterator.cpp b/lib/AST/StmtIterator.cpp
index 6e85375..1ccba04 100644
--- a/lib/AST/StmtIterator.cpp
+++ b/lib/AST/StmtIterator.cpp
@@ -27,7 +27,7 @@
     t = vt->getElementType().getTypePtr();
   }
 
-  return NULL;
+  return nullptr;
 }
 
 void StmtIteratorBase::NextVA() {
@@ -54,7 +54,7 @@
 }
 
 void StmtIteratorBase::NextDecl(bool ImmediateAdvance) {
-  assert (getVAPtr() == NULL);
+  assert(getVAPtr() == nullptr);
   assert(inDeclGroup());
 
   if (ImmediateAdvance)
@@ -93,12 +93,12 @@
 }
 
 StmtIteratorBase::StmtIteratorBase(Decl** dgi, Decl** dge)
-  : stmt(0), DGI(dgi), RawVAPtr(DeclGroupMode), DGE(dge) {
+  : stmt(nullptr), DGI(dgi), RawVAPtr(DeclGroupMode), DGE(dge) {
   NextDecl(false);
 }
 
 StmtIteratorBase::StmtIteratorBase(const VariableArrayType* t)
-  : stmt(0), DGI(0), RawVAPtr(SizeOfTypeVAMode) {
+  : stmt(nullptr), DGI(nullptr), RawVAPtr(SizeOfTypeVAMode) {
   RawVAPtr |= reinterpret_cast<uintptr_t>(t);
 }
 
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index 0ecb5b5..1fdad9f 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -70,6 +70,7 @@
     void PrintCallArgs(CallExpr *E);
     void PrintRawSEHExceptHandler(SEHExceptStmt *S);
     void PrintRawSEHFinallyStmt(SEHFinallyStmt *S);
+    void PrintOMPExecutableDirective(OMPExecutableDirective *S);
 
     void PrintExpr(Expr *E) {
       if (E)
@@ -89,7 +90,7 @@
           return;
       else StmtVisitor<StmtPrinter>::Visit(S);
     }
-    
+
     void VisitStmt(Stmt *Node) LLVM_ATTRIBUTE_UNUSED {
       Indent() << "<<unknown stmt type>>\n";
     }
@@ -113,9 +114,8 @@
 /// with no newline after the }.
 void StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) {
   OS << "{\n";
-  for (CompoundStmt::body_iterator I = Node->body_begin(), E = Node->body_end();
-       I != E; ++I)
-    PrintStmt(*I);
+  for (auto *I : Node->body())
+    PrintStmt(I);
 
   Indent() << "}";
 }
@@ -125,11 +125,7 @@
 }
 
 void StmtPrinter::PrintRawDeclStmt(const DeclStmt *S) {
-  DeclStmt::const_decl_iterator Begin = S->decl_begin(), End = S->decl_end();
-  SmallVector<Decl*, 2> Decls;
-  for ( ; Begin != End; ++Begin)
-    Decls.push_back(*Begin);
-
+  SmallVector<Decl*, 2> Decls(S->decls());
   Decl::printGroup(Decls.data(), Decls.size(), OS, Policy, IndentLevel);
 }
 
@@ -172,19 +168,10 @@
 }
 
 void StmtPrinter::VisitAttributedStmt(AttributedStmt *Node) {
-  OS << "[[";
-  bool first = true;
-  for (ArrayRef<const Attr*>::iterator it = Node->getAttrs().begin(),
-                                       end = Node->getAttrs().end();
-                                       it != end; ++it) {
-    if (!first) {
-      OS << ", ";
-      first = false;
-    }
-    // TODO: check this
-    (*it)->printPretty(OS, Policy);
+  for (const auto *Attr : Node->getAttrs()) {
+    Attr->printPretty(OS, Policy);
   }
-  OS << "]] ";
+
   PrintStmt(Node->getSubStmt(), 0);
 }
 
@@ -330,7 +317,8 @@
   PrintExpr(Node->getRangeInit());
   OS << ") {\n";
   PrintStmt(Node->getBody());
-  Indent() << "}\n";
+  Indent() << "}";
+  if (Policy.IncludeNewlines) OS << "\n";
 }
 
 void StmtPrinter::VisitMSDependentExistsStmt(MSDependentExistsStmt *Node) {
@@ -350,21 +338,25 @@
 }
 
 void StmtPrinter::VisitGotoStmt(GotoStmt *Node) {
-  Indent() << "goto " << Node->getLabel()->getName() << ";\n";
+  Indent() << "goto " << Node->getLabel()->getName() << ";";
+  if (Policy.IncludeNewlines) OS << "\n";
 }
 
 void StmtPrinter::VisitIndirectGotoStmt(IndirectGotoStmt *Node) {
   Indent() << "goto *";
   PrintExpr(Node->getTarget());
-  OS << ";\n";
+  OS << ";";
+  if (Policy.IncludeNewlines) OS << "\n";
 }
 
 void StmtPrinter::VisitContinueStmt(ContinueStmt *Node) {
-  Indent() << "continue;\n";
+  Indent() << "continue;";
+  if (Policy.IncludeNewlines) OS << "\n";
 }
 
 void StmtPrinter::VisitBreakStmt(BreakStmt *Node) {
-  Indent() << "break;\n";
+  Indent() << "break;";
+  if (Policy.IncludeNewlines) OS << "\n";
 }
 
 
@@ -374,7 +366,8 @@
     OS << " ";
     PrintExpr(Node->getRetValue());
   }
-  OS << ";\n";
+  OS << ";";
+  if (Policy.IncludeNewlines) OS << "\n";
 }
 
 
@@ -437,7 +430,8 @@
     VisitStringLiteral(Node->getClobberStringLiteral(i));
   }
 
-  OS << ");\n";
+  OS << ");";
+  if (Policy.IncludeNewlines) OS << "\n";
 }
 
 void StmtPrinter::VisitMSAsmStmt(MSAsmStmt *Node) {
@@ -579,6 +573,11 @@
   OS << "\n";
 }
 
+void StmtPrinter::VisitSEHLeaveStmt(SEHLeaveStmt *Node) {
+  Indent() << "__leave;";
+  if (Policy.IncludeNewlines) OS << "\n";
+}
+
 //===----------------------------------------------------------------------===//
 //  OpenMP clauses printing methods
 //===----------------------------------------------------------------------===//
@@ -586,29 +585,100 @@
 namespace {
 class OMPClausePrinter : public OMPClauseVisitor<OMPClausePrinter> {
   raw_ostream &OS;
+  const PrintingPolicy &Policy;
   /// \brief Process clauses with list of variables.
   template <typename T>
   void VisitOMPClauseList(T *Node, char StartSym);
 public:
-  OMPClausePrinter(raw_ostream &OS) : OS(OS) { }
+  OMPClausePrinter(raw_ostream &OS, const PrintingPolicy &Policy)
+    : OS(OS), Policy(Policy) { }
 #define OPENMP_CLAUSE(Name, Class)                              \
   void Visit##Class(Class *S);
 #include "clang/Basic/OpenMPKinds.def"
 };
 
+void OMPClausePrinter::VisitOMPIfClause(OMPIfClause *Node) {
+  OS << "if(";
+  Node->getCondition()->printPretty(OS, nullptr, Policy, 0);
+  OS << ")";
+}
+
+void OMPClausePrinter::VisitOMPFinalClause(OMPFinalClause *Node) {
+  OS << "final(";
+  Node->getCondition()->printPretty(OS, nullptr, Policy, 0);
+  OS << ")";
+}
+
+void OMPClausePrinter::VisitOMPNumThreadsClause(OMPNumThreadsClause *Node) {
+  OS << "num_threads(";
+  Node->getNumThreads()->printPretty(OS, nullptr, Policy, 0);
+  OS << ")";
+}
+
+void OMPClausePrinter::VisitOMPSafelenClause(OMPSafelenClause *Node) {
+  OS << "safelen(";
+  Node->getSafelen()->printPretty(OS, nullptr, Policy, 0);
+  OS << ")";
+}
+
+void OMPClausePrinter::VisitOMPCollapseClause(OMPCollapseClause *Node) {
+  OS << "collapse(";
+  Node->getNumForLoops()->printPretty(OS, nullptr, Policy, 0);
+  OS << ")";
+}
+
 void OMPClausePrinter::VisitOMPDefaultClause(OMPDefaultClause *Node) {
   OS << "default("
      << getOpenMPSimpleClauseTypeName(OMPC_default, Node->getDefaultKind())
      << ")";
 }
 
+void OMPClausePrinter::VisitOMPProcBindClause(OMPProcBindClause *Node) {
+  OS << "proc_bind("
+     << getOpenMPSimpleClauseTypeName(OMPC_proc_bind, Node->getProcBindKind())
+     << ")";
+}
+
+void OMPClausePrinter::VisitOMPScheduleClause(OMPScheduleClause *Node) {
+  OS << "schedule("
+     << getOpenMPSimpleClauseTypeName(OMPC_schedule, Node->getScheduleKind());
+  if (Node->getChunkSize()) {
+    OS << ", ";
+    Node->getChunkSize()->printPretty(OS, nullptr, Policy);
+  }
+  OS << ")";
+}
+
+void OMPClausePrinter::VisitOMPOrderedClause(OMPOrderedClause *) {
+  OS << "ordered";
+}
+
+void OMPClausePrinter::VisitOMPNowaitClause(OMPNowaitClause *) {
+  OS << "nowait";
+}
+
+void OMPClausePrinter::VisitOMPUntiedClause(OMPUntiedClause *) {
+  OS << "untied";
+}
+
+void OMPClausePrinter::VisitOMPMergeableClause(OMPMergeableClause *) {
+  OS << "mergeable";
+}
+
 template<typename T>
 void OMPClausePrinter::VisitOMPClauseList(T *Node, char StartSym) {
   for (typename T::varlist_iterator I = Node->varlist_begin(),
                                     E = Node->varlist_end();
-         I != E; ++I)
-    OS << (I == Node->varlist_begin() ? StartSym : ',')
-       << *cast<NamedDecl>(cast<DeclRefExpr>(*I)->getDecl());
+         I != E; ++I) {
+    assert(*I && "Expected non-null Stmt");
+    if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(*I)) {
+      OS << (I == Node->varlist_begin() ? StartSym : ',');
+      cast<NamedDecl>(DRE->getDecl())->printQualifiedName(OS);
+    } else {
+      OS << (I == Node->varlist_begin() ? StartSym : ',');
+      (*I)->printPretty(OS, nullptr, Policy, 0);
+    }
+  }
 }
 
 void OMPClausePrinter::VisitOMPPrivateClause(OMPPrivateClause *Node) {
@@ -627,6 +697,14 @@
   }
 }
 
+void OMPClausePrinter::VisitOMPLastprivateClause(OMPLastprivateClause *Node) {
+  if (!Node->varlist_empty()) {
+    OS << "lastprivate";
+    VisitOMPClauseList(Node, '(');
+    OS << ")";
+  }
+}
+
 void OMPClausePrinter::VisitOMPSharedClause(OMPSharedClause *Node) {
   if (!Node->varlist_empty()) {
     OS << "shared";
@@ -635,17 +713,83 @@
   }
 }
 
+void OMPClausePrinter::VisitOMPReductionClause(OMPReductionClause *Node) {
+  if (!Node->varlist_empty()) {
+    OS << "reduction(";
+    NestedNameSpecifier *QualifierLoc =
+        Node->getQualifierLoc().getNestedNameSpecifier();
+    OverloadedOperatorKind OOK =
+        Node->getNameInfo().getName().getCXXOverloadedOperator();
+    if (QualifierLoc == nullptr && OOK != OO_None) {
+      // Print reduction identifier in C format
+      OS << getOperatorSpelling(OOK);
+    } else {
+      // Use C++ format
+      if (QualifierLoc != nullptr)
+        QualifierLoc->print(OS, Policy);
+      OS << Node->getNameInfo();
+    }
+    OS << ":";
+    VisitOMPClauseList(Node, ' ');
+    OS << ")";
+  }
+}
+
+void OMPClausePrinter::VisitOMPLinearClause(OMPLinearClause *Node) {
+  if (!Node->varlist_empty()) {
+    OS << "linear";
+    VisitOMPClauseList(Node, '(');
+    if (Node->getStep() != nullptr) {
+      OS << ": ";
+      Node->getStep()->printPretty(OS, nullptr, Policy, 0);
+    }
+    OS << ")";
+  }
+}
+
+void OMPClausePrinter::VisitOMPAlignedClause(OMPAlignedClause *Node) {
+  if (!Node->varlist_empty()) {
+    OS << "aligned";
+    VisitOMPClauseList(Node, '(');
+    if (Node->getAlignment() != nullptr) {
+      OS << ": ";
+      Node->getAlignment()->printPretty(OS, nullptr, Policy, 0);
+    }
+    OS << ")";
+  }
+}
+
+void OMPClausePrinter::VisitOMPCopyinClause(OMPCopyinClause *Node) {
+  if (!Node->varlist_empty()) {
+    OS << "copyin";
+    VisitOMPClauseList(Node, '(');
+    OS << ")";
+  }
+}
+
+void OMPClausePrinter::VisitOMPCopyprivateClause(OMPCopyprivateClause *Node) {
+  if (!Node->varlist_empty()) {
+    OS << "copyprivate";
+    VisitOMPClauseList(Node, '(');
+    OS << ")";
+  }
+}
+
+void OMPClausePrinter::VisitOMPFlushClause(OMPFlushClause *Node) {
+  if (!Node->varlist_empty()) {
+    VisitOMPClauseList(Node, '(');
+    OS << ")";
+  }
+}
 }
 
 //===----------------------------------------------------------------------===//
 //  OpenMP directives printing methods
 //===----------------------------------------------------------------------===//
 
-void StmtPrinter::VisitOMPParallelDirective(OMPParallelDirective *Node) {
-  Indent() << "#pragma omp parallel ";
-
-  OMPClausePrinter Printer(OS);
-  ArrayRef<OMPClause *> Clauses = Node->clauses();
+void StmtPrinter::PrintOMPExecutableDirective(OMPExecutableDirective *S) {
+  OMPClausePrinter Printer(OS, Policy);
+  ArrayRef<OMPClause *> Clauses = S->clauses();
   for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
        I != E; ++I)
     if (*I && !(*I)->isImplicit()) {
@@ -653,13 +797,95 @@
       OS << ' ';
     }
   OS << "\n";
-  if (Node->getAssociatedStmt()) {
-    assert(isa<CapturedStmt>(Node->getAssociatedStmt()) &&
+  if (S->hasAssociatedStmt() && S->getAssociatedStmt()) {
+    assert(isa<CapturedStmt>(S->getAssociatedStmt()) &&
            "Expected captured statement!");
-    Stmt *CS = cast<CapturedStmt>(Node->getAssociatedStmt())->getCapturedStmt();
+    Stmt *CS = cast<CapturedStmt>(S->getAssociatedStmt())->getCapturedStmt();
     PrintStmt(CS);
   }
 }
+
+void StmtPrinter::VisitOMPParallelDirective(OMPParallelDirective *Node) {
+  Indent() << "#pragma omp parallel ";
+  PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPSimdDirective(OMPSimdDirective *Node) {
+  Indent() << "#pragma omp simd ";
+  PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPForDirective(OMPForDirective *Node) {
+  Indent() << "#pragma omp for ";
+  PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPSectionsDirective(OMPSectionsDirective *Node) {
+  Indent() << "#pragma omp sections ";
+  PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPSectionDirective(OMPSectionDirective *Node) {
+  Indent() << "#pragma omp section";
+  PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPSingleDirective(OMPSingleDirective *Node) {
+  Indent() << "#pragma omp single ";
+  PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPMasterDirective(OMPMasterDirective *Node) {
+  Indent() << "#pragma omp master";
+  PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPCriticalDirective(OMPCriticalDirective *Node) {
+  Indent() << "#pragma omp critical";
+  if (Node->getDirectiveName().getName()) {
+    OS << " (";
+    Node->getDirectiveName().printName(OS);
+    OS << ")";
+  }
+  PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPParallelForDirective(OMPParallelForDirective *Node) {
+  Indent() << "#pragma omp parallel for ";
+  PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPParallelSectionsDirective(
+    OMPParallelSectionsDirective *Node) {
+  Indent() << "#pragma omp parallel sections ";
+  PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPTaskDirective(OMPTaskDirective *Node) {
+  Indent() << "#pragma omp task ";
+  PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *Node) {
+  Indent() << "#pragma omp taskyield";
+  PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPBarrierDirective(OMPBarrierDirective *Node) {
+  Indent() << "#pragma omp barrier";
+  PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *Node) {
+  Indent() << "#pragma omp taskwait";
+  PrintOMPExecutableDirective(Node);
+}
+
+void StmtPrinter::VisitOMPFlushDirective(OMPFlushDirective *Node) {
+  Indent() << "#pragma omp flush ";
+  PrintOMPExecutableDirective(Node);
+}
+
 //===----------------------------------------------------------------------===//
 //  Expr printing methods.
 //===----------------------------------------------------------------------===//
@@ -709,13 +935,15 @@
 void StmtPrinter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
   if (Node->isSuperReceiver())
     OS << "super.";
-  else if (Node->getBase()) {
+  else if (Node->isObjectReceiver() && Node->getBase()) {
     PrintExpr(Node->getBase());
     OS << ".";
+  } else if (Node->isClassReceiver() && Node->getClassReceiver()) {
+    OS << Node->getClassReceiver()->getName() << ".";
   }
 
   if (Node->isImplicitProperty())
-    OS << Node->getImplicitPropertyGetter()->getSelector().getAsString();
+    Node->getImplicitPropertyGetter()->getSelector().print(OS);
   else
     OS << Node->getExplicitProperty()->getName();
 }
@@ -741,6 +969,9 @@
     case PredefinedExpr::FuncDName:
       OS << "__FUNCDNAME__";
       break;
+    case PredefinedExpr::FuncSig:
+      OS << "__FUNCSIG__";
+      break;
     case PredefinedExpr::LFunction:
       OS << "L__FUNCTION__";
       break;
@@ -812,11 +1043,10 @@
   // Emit suffixes.  Integer literals are always a builtin integer type.
   switch (Node->getType()->getAs<BuiltinType>()->getKind()) {
   default: llvm_unreachable("Unexpected type for integer literal!");
-  // FIXME: The Short and UShort cases are to handle cases where a short
-  // integeral literal is formed during template instantiation.  They should
-  // be removed when template instantiation no longer needs integer literals.
-  case BuiltinType::Short:
-  case BuiltinType::UShort:
+  case BuiltinType::SChar:     OS << "i8"; break;
+  case BuiltinType::UChar:     OS << "Ui8"; break;
+  case BuiltinType::Short:     OS << "i16"; break;
+  case BuiltinType::UShort:    OS << "Ui16"; break;
   case BuiltinType::Int:       break; // no suffix.
   case BuiltinType::UInt:      OS << 'U'; break;
   case BuiltinType::Long:      OS << 'L'; break;
@@ -1000,7 +1230,7 @@
 
   MemberExpr *ParentMember = dyn_cast<MemberExpr>(Node->getBase());
   FieldDecl  *ParentDecl   = ParentMember
-    ? dyn_cast<FieldDecl>(ParentMember->getMemberDecl()) : NULL;
+    ? dyn_cast<FieldDecl>(ParentMember->getMemberDecl()) : nullptr;
 
   if (!ParentDecl || !ParentDecl->isAnonymousStructOrUnion())
     OS << (Node->isArrow() ? "->" : ".");
@@ -1041,7 +1271,7 @@
   PrintExpr(Node->getInitializer());
 }
 void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
-  // No need to print anything, simply forward to the sub expression.
+  // No need to print anything, simply forward to the subexpression.
   PrintExpr(Node->getSubExpr());
 }
 void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) {
@@ -1142,10 +1372,12 @@
                       DEnd = Node->designators_end();
        D != DEnd; ++D) {
     if (D->isFieldDesignator()) {
-      if (D->getDotLoc().isInvalid())
-        OS << D->getFieldName()->getName() << ":";
-      else
+      if (D->getDotLoc().isInvalid()) {
+        if (IdentifierInfo *II = D->getFieldName())
+          OS << II->getName() << ":";
+      } else {
         OS << "." << D->getFieldName()->getName();
+      }
     } else {
       OS << "[";
       if (D->isArrayDesignator()) {
@@ -1192,7 +1424,7 @@
 }
 
 void StmtPrinter::VisitAtomicExpr(AtomicExpr *Node) {
-  const char *Name = 0;
+  const char *Name = nullptr;
   switch (Node->getOp()) {
 #define BUILTIN(ID, TYPE, ATTRS)
 #define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
@@ -1279,6 +1511,12 @@
 }
 
 void StmtPrinter::VisitCXXMemberCallExpr(CXXMemberCallExpr *Node) {
+  // If we have a conversion operator call only print the argument.
+  CXXMethodDecl *MD = Node->getMethodDecl();
+  if (MD && isa<CXXConversionDecl>(MD)) {
+    PrintExpr(Node->getImplicitObjectArgument());
+    return;
+  }
   VisitCallExpr(cast<CallExpr>(Node));
 }
 
@@ -1358,9 +1596,8 @@
       cast<FunctionDecl>(DRE->getDecl())->getTemplateSpecializationArgs();
     assert(Args);
     const TemplateArgument &Pack = Args->get(0);
-    for (TemplateArgument::pack_iterator I = Pack.pack_begin(),
-                                         E = Pack.pack_end(); I != E; ++I) {
-      char C = (char)I->getAsIntegral().getZExtValue();
+    for (const auto &P : Pack.pack_elements()) {
+      char C = (char)P.getAsIntegral().getZExtValue();
       OS << C;
     }
     break;
@@ -1398,7 +1635,7 @@
 }
 
 void StmtPrinter::VisitCXXThrowExpr(CXXThrowExpr *Node) {
-  if (Node->getSubExpr() == 0)
+  if (!Node->getSubExpr())
     OS << "throw";
   else {
     OS << "throw ";
@@ -1490,16 +1727,14 @@
     OS << " (";
     CXXMethodDecl *Method = Node->getCallOperator();
     NeedComma = false;
-    for (CXXMethodDecl::param_iterator P = Method->param_begin(),
-                                    PEnd = Method->param_end();
-         P != PEnd; ++P) {
+    for (auto P : Method->params()) {
       if (NeedComma) {
         OS << ", ";
       } else {
         NeedComma = true;
       }
-      std::string ParamStr = (*P)->getNameAsString();
-      (*P)->getOriginalType().print(OS, Policy, ParamStr);
+      std::string ParamStr = P->getNameAsString();
+      P->getOriginalType().print(OS, Policy, ParamStr);
     }
     if (Method->isVariadic()) {
       if (NeedComma)
@@ -1520,7 +1755,7 @@
     // Print the trailing return type if it was specified in the source.
     if (Node->hasExplicitResultType()) {
       OS << " -> ";
-      Proto->getResultType().print(OS, Policy);
+      Proto->getReturnType().print(OS, Policy);
     }
   }
 
@@ -1625,7 +1860,7 @@
 }
 
 void StmtPrinter::VisitExprWithCleanups(ExprWithCleanups *E) {
-  // Just forward to the sub expression.
+  // Just forward to the subexpression.
   PrintExpr(E->getSubExpr());
 }
 
@@ -1675,74 +1910,15 @@
         OS, Node->getTemplateArgs(), Node->getNumTemplateArgs(), Policy);
 }
 
-static const char *getTypeTraitName(UnaryTypeTrait UTT) {
-  switch (UTT) {
-  case UTT_HasNothrowAssign:      return "__has_nothrow_assign";
-  case UTT_HasNothrowMoveAssign:  return "__has_nothrow_move_assign";
-  case UTT_HasNothrowConstructor: return "__has_nothrow_constructor";
-  case UTT_HasNothrowCopy:          return "__has_nothrow_copy";
-  case UTT_HasTrivialAssign:      return "__has_trivial_assign";
-  case UTT_HasTrivialMoveAssign:      return "__has_trivial_move_assign";
-  case UTT_HasTrivialMoveConstructor: return "__has_trivial_move_constructor";
-  case UTT_HasTrivialDefaultConstructor: return "__has_trivial_constructor";
-  case UTT_HasTrivialCopy:          return "__has_trivial_copy";
-  case UTT_HasTrivialDestructor:  return "__has_trivial_destructor";
-  case UTT_HasVirtualDestructor:  return "__has_virtual_destructor";
-  case UTT_IsAbstract:            return "__is_abstract";
-  case UTT_IsArithmetic:            return "__is_arithmetic";
-  case UTT_IsArray:                 return "__is_array";
-  case UTT_IsClass:               return "__is_class";
-  case UTT_IsCompleteType:          return "__is_complete_type";
-  case UTT_IsCompound:              return "__is_compound";
-  case UTT_IsConst:                 return "__is_const";
-  case UTT_IsEmpty:               return "__is_empty";
-  case UTT_IsEnum:                return "__is_enum";
-  case UTT_IsFinal:                 return "__is_final";
-  case UTT_IsFloatingPoint:         return "__is_floating_point";
-  case UTT_IsFunction:              return "__is_function";
-  case UTT_IsFundamental:           return "__is_fundamental";
-  case UTT_IsIntegral:              return "__is_integral";
-  case UTT_IsInterfaceClass:        return "__is_interface_class";
-  case UTT_IsLiteral:               return "__is_literal";
-  case UTT_IsLvalueReference:       return "__is_lvalue_reference";
-  case UTT_IsMemberFunctionPointer: return "__is_member_function_pointer";
-  case UTT_IsMemberObjectPointer:   return "__is_member_object_pointer";
-  case UTT_IsMemberPointer:         return "__is_member_pointer";
-  case UTT_IsObject:                return "__is_object";
-  case UTT_IsPOD:                 return "__is_pod";
-  case UTT_IsPointer:               return "__is_pointer";
-  case UTT_IsPolymorphic:         return "__is_polymorphic";
-  case UTT_IsReference:             return "__is_reference";
-  case UTT_IsRvalueReference:       return "__is_rvalue_reference";
-  case UTT_IsScalar:                return "__is_scalar";
-  case UTT_IsSealed:                return "__is_sealed";
-  case UTT_IsSigned:                return "__is_signed";
-  case UTT_IsStandardLayout:        return "__is_standard_layout";
-  case UTT_IsTrivial:               return "__is_trivial";
-  case UTT_IsTriviallyCopyable:     return "__is_trivially_copyable";
-  case UTT_IsUnion:               return "__is_union";
-  case UTT_IsUnsigned:              return "__is_unsigned";
-  case UTT_IsVoid:                  return "__is_void";
-  case UTT_IsVolatile:              return "__is_volatile";
-  }
-  llvm_unreachable("Type trait not covered by switch statement");
-}
-
-static const char *getTypeTraitName(BinaryTypeTrait BTT) {
-  switch (BTT) {
-  case BTT_IsBaseOf:              return "__is_base_of";
-  case BTT_IsConvertible:         return "__is_convertible";
-  case BTT_IsSame:                return "__is_same";
-  case BTT_TypeCompatible:        return "__builtin_types_compatible_p";
-  case BTT_IsConvertibleTo:       return "__is_convertible_to";
-  case BTT_IsTriviallyAssignable: return "__is_trivially_assignable";
-  }
-  llvm_unreachable("Binary type trait not covered by switch");
-}
-
 static const char *getTypeTraitName(TypeTrait TT) {
   switch (TT) {
-  case clang::TT_IsTriviallyConstructible:return "__is_trivially_constructible";
+#define TYPE_TRAIT_1(Spelling, Name, Key) \
+case clang::UTT_##Name: return #Spelling;
+#define TYPE_TRAIT_2(Spelling, Name, Key) \
+case clang::BTT_##Name: return #Spelling;
+#define TYPE_TRAIT_N(Spelling, Name, Key) \
+  case clang::TT_##Name: return #Spelling;
+#include "clang/Basic/TokenKinds.def"
   }
   llvm_unreachable("Type trait not covered by switch");
 }
@@ -1763,20 +1939,6 @@
   llvm_unreachable("Expression type trait not covered by switch");
 }
 
-void StmtPrinter::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
-  OS << getTypeTraitName(E->getTrait()) << '(';
-  E->getQueriedType().print(OS, Policy);
-  OS << ')';
-}
-
-void StmtPrinter::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
-  OS << getTypeTraitName(E->getTrait()) << '(';
-  E->getLhsType().print(OS, Policy);
-  OS << ',';
-  E->getRhsType().print(OS, Policy);
-  OS << ')';
-}
-
 void StmtPrinter::VisitTypeTraitExpr(TypeTraitExpr *E) {
   OS << getTypeTraitName(E->getTrait()) << "(";
   for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
@@ -1881,7 +2043,9 @@
 }
 
 void StmtPrinter::VisitObjCSelectorExpr(ObjCSelectorExpr *Node) {
-  OS << "@selector(" << Node->getSelector().getAsString() << ')';
+  OS << "@selector(";
+  Node->getSelector().print(OS);
+  OS << ')';
 }
 
 void StmtPrinter::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
@@ -1987,18 +2151,13 @@
 //===----------------------------------------------------------------------===//
 
 void Stmt::dumpPretty(const ASTContext &Context) const {
-  printPretty(llvm::errs(), 0, PrintingPolicy(Context.getLangOpts()));
+  printPretty(llvm::errs(), nullptr, PrintingPolicy(Context.getLangOpts()));
 }
 
 void Stmt::printPretty(raw_ostream &OS,
                        PrinterHelper *Helper,
                        const PrintingPolicy &Policy,
                        unsigned Indentation) const {
-  if (this == 0) {
-    OS << "<NULL>";
-    return;
-  }
-
   StmtPrinter P(OS, Helper, Policy, Indentation);
   P.Visit(const_cast<Stmt*>(this));
 }
diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp
index 6805e62..f44f25c 100644
--- a/lib/AST/StmtProfile.cpp
+++ b/lib/AST/StmtProfile.cpp
@@ -79,9 +79,8 @@
 
 void StmtProfiler::VisitDeclStmt(const DeclStmt *S) {
   VisitStmt(S);
-  for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
-       D != DEnd; ++D)
-    VisitDecl(*D);
+  for (const auto *D : S->decls())
+    VisitDecl(D);
 }
 
 void StmtProfiler::VisitNullStmt(const NullStmt *S) {
@@ -215,6 +214,10 @@
   VisitStmt(S);
 }
 
+void StmtProfiler::VisitSEHLeaveStmt(const SEHLeaveStmt *S) {
+  VisitStmt(S);
+}
+
 void StmtProfiler::VisitCapturedStmt(const CapturedStmt *S) {
   VisitStmt(S);
 }
@@ -265,14 +268,52 @@
 #include "clang/Basic/OpenMPKinds.def"
 };
 
+void OMPClauseProfiler::VisitOMPIfClause(const OMPIfClause *C) {
+  if (C->getCondition())
+    Profiler->VisitStmt(C->getCondition());
+}
+
+void OMPClauseProfiler::VisitOMPFinalClause(const OMPFinalClause *C) {
+  if (C->getCondition())
+    Profiler->VisitStmt(C->getCondition());
+}
+
+void OMPClauseProfiler::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
+  if (C->getNumThreads())
+    Profiler->VisitStmt(C->getNumThreads());
+}
+
+void OMPClauseProfiler::VisitOMPSafelenClause(const OMPSafelenClause *C) {
+  if (C->getSafelen())
+    Profiler->VisitStmt(C->getSafelen());
+}
+
+void OMPClauseProfiler::VisitOMPCollapseClause(const OMPCollapseClause *C) {
+  if (C->getNumForLoops())
+    Profiler->VisitStmt(C->getNumForLoops());
+}
+
 void OMPClauseProfiler::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
 
+void OMPClauseProfiler::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
+
+void OMPClauseProfiler::VisitOMPScheduleClause(const OMPScheduleClause *C) {
+  if (C->getChunkSize())
+    Profiler->VisitStmt(C->getChunkSize());
+}
+
+void OMPClauseProfiler::VisitOMPOrderedClause(const OMPOrderedClause *) {}
+
+void OMPClauseProfiler::VisitOMPNowaitClause(const OMPNowaitClause *) {}
+
+void OMPClauseProfiler::VisitOMPUntiedClause(const OMPUntiedClause *) {}
+
+void OMPClauseProfiler::VisitOMPMergeableClause(const OMPMergeableClause *) {}
+
 template<typename T>
 void OMPClauseProfiler::VisitOMPClauseList(T *Node) {
-  for (typename T::varlist_const_iterator I = Node->varlist_begin(),
-                                          E = Node->varlist_end();
-         I != E; ++I)
-    Profiler->VisitStmt(*I);
+  for (auto *I : Node->varlists())
+    Profiler->VisitStmt(I);
 }
 
 void OMPClauseProfiler::VisitOMPPrivateClause(const OMPPrivateClause *C) {
@@ -282,13 +323,42 @@
                                          const OMPFirstprivateClause *C) {
   VisitOMPClauseList(C);
 }
+void
+OMPClauseProfiler::VisitOMPLastprivateClause(const OMPLastprivateClause *C) {
+  VisitOMPClauseList(C);
+}
 void OMPClauseProfiler::VisitOMPSharedClause(const OMPSharedClause *C) {
   VisitOMPClauseList(C);
 }
+void OMPClauseProfiler::VisitOMPReductionClause(
+                                         const OMPReductionClause *C) {
+  Profiler->VisitNestedNameSpecifier(
+      C->getQualifierLoc().getNestedNameSpecifier());
+  Profiler->VisitName(C->getNameInfo().getName());
+  VisitOMPClauseList(C);
+}
+void OMPClauseProfiler::VisitOMPLinearClause(const OMPLinearClause *C) {
+  VisitOMPClauseList(C);
+  Profiler->VisitStmt(C->getStep());
+}
+void OMPClauseProfiler::VisitOMPAlignedClause(const OMPAlignedClause *C) {
+  VisitOMPClauseList(C);
+  Profiler->VisitStmt(C->getAlignment());
+}
+void OMPClauseProfiler::VisitOMPCopyinClause(const OMPCopyinClause *C) {
+  VisitOMPClauseList(C);
+}
+void
+OMPClauseProfiler::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
+  VisitOMPClauseList(C);
+}
+void OMPClauseProfiler::VisitOMPFlushClause(const OMPFlushClause *C) {
+  VisitOMPClauseList(C);
+}
 }
 
 void
-StmtProfiler::VisitOMPParallelDirective(const OMPParallelDirective *S) {
+StmtProfiler::VisitOMPExecutableDirective(const OMPExecutableDirective *S) {
   VisitStmt(S);
   OMPClauseProfiler P(this);
   ArrayRef<OMPClause *> Clauses = S->clauses();
@@ -298,6 +368,69 @@
       P.Visit(*I);
 }
 
+void StmtProfiler::VisitOMPParallelDirective(const OMPParallelDirective *S) {
+  VisitOMPExecutableDirective(S);
+}
+
+void StmtProfiler::VisitOMPSimdDirective(const OMPSimdDirective *S) {
+  VisitOMPExecutableDirective(S);
+}
+
+void StmtProfiler::VisitOMPForDirective(const OMPForDirective *S) {
+  VisitOMPExecutableDirective(S);
+}
+
+void StmtProfiler::VisitOMPSectionsDirective(const OMPSectionsDirective *S) {
+  VisitOMPExecutableDirective(S);
+}
+
+void StmtProfiler::VisitOMPSectionDirective(const OMPSectionDirective *S) {
+  VisitOMPExecutableDirective(S);
+}
+
+void StmtProfiler::VisitOMPSingleDirective(const OMPSingleDirective *S) {
+  VisitOMPExecutableDirective(S);
+}
+
+void StmtProfiler::VisitOMPMasterDirective(const OMPMasterDirective *S) {
+  VisitOMPExecutableDirective(S);
+}
+
+void StmtProfiler::VisitOMPCriticalDirective(const OMPCriticalDirective *S) {
+  VisitOMPExecutableDirective(S);
+  VisitName(S->getDirectiveName().getName());
+}
+
+void
+StmtProfiler::VisitOMPParallelForDirective(const OMPParallelForDirective *S) {
+  VisitOMPExecutableDirective(S);
+}
+
+void StmtProfiler::VisitOMPParallelSectionsDirective(
+    const OMPParallelSectionsDirective *S) {
+  VisitOMPExecutableDirective(S);
+}
+
+void StmtProfiler::VisitOMPTaskDirective(const OMPTaskDirective *S) {
+  VisitOMPExecutableDirective(S);
+}
+
+void StmtProfiler::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *S) {
+  VisitOMPExecutableDirective(S);
+}
+
+void StmtProfiler::VisitOMPBarrierDirective(const OMPBarrierDirective *S) {
+  VisitOMPExecutableDirective(S);
+}
+
+void StmtProfiler::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *S) {
+  VisitOMPExecutableDirective(S);
+}
+
+void StmtProfiler::VisitOMPFlushDirective(const OMPFlushDirective *S) {
+  VisitOMPExecutableDirective(S);
+}
+
 void StmtProfiler::VisitExpr(const Expr *S) {
   VisitStmt(S);
 }
@@ -529,7 +662,7 @@
   for (unsigned i = 0; i != S->getNumAssocs(); ++i) {
     QualType T = S->getAssocType(i);
     if (T.isNull())
-      ID.AddPointer(0);
+      ID.AddPointer(nullptr);
     else
       VisitType(T);
     VisitExpr(S->getAssocExpr(i));
@@ -585,11 +718,11 @@
 
   case OO_Star:
     if (S->getNumArgs() == 1) {
-      UnaryOp = UO_Minus;
+      UnaryOp = UO_Deref;
       return Stmt::UnaryOperatorClass;
     }
     
-    BinaryOp = BO_Sub;
+    BinaryOp = BO_Mul;
     return Stmt::BinaryOperatorClass;
 
   case OO_Slash:
@@ -734,7 +867,7 @@
   
   llvm_unreachable("Invalid overloaded operator expression");
 }
-                               
+
 
 void StmtProfiler::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *S) {
   if (S->isTypeDependent()) {
@@ -743,7 +876,7 @@
     UnaryOperatorKind UnaryOp = UO_Extension;
     BinaryOperatorKind BinaryOp = BO_Comma;
     Stmt::StmtClass SC = DecodeOperatorCall(S, UnaryOp, BinaryOp);
-    
+
     ID.AddInteger(SC);
     for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
       Visit(S->getArg(I));
@@ -754,10 +887,10 @@
       ID.AddInteger(BinaryOp);
     else
       assert(SC == Stmt::ArraySubscriptExprClass);
-                    
+
     return;
   }
-  
+
   VisitCallExpr(S);
   ID.AddInteger(S->getOperator());
 }
@@ -923,10 +1056,10 @@
   VisitExpr(S);
   ID.AddBoolean(S->isArrow());
   VisitNestedNameSpecifier(S->getQualifier());
-  ID.AddBoolean(S->getScopeTypeInfo() != 0);
+  ID.AddBoolean(S->getScopeTypeInfo() != nullptr);
   if (S->getScopeTypeInfo())
     VisitType(S->getScopeTypeInfo()->getType());
-  ID.AddBoolean(S->getDestroyedTypeInfo() != 0);
+  ID.AddBoolean(S->getDestroyedTypeInfo() != nullptr);
   if (S->getDestroyedTypeInfo())
     VisitType(S->getDestroyedType());
   else
@@ -948,19 +1081,6 @@
   VisitOverloadExpr(S);
 }
 
-void StmtProfiler::VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *S) {
-  VisitExpr(S);
-  ID.AddInteger(S->getTrait());
-  VisitType(S->getQueriedType());
-}
-
-void StmtProfiler::VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *S) {
-  VisitExpr(S);
-  ID.AddInteger(S->getTrait());
-  VisitType(S->getLhsType());
-  VisitType(S->getRhsType());
-}
-
 void StmtProfiler::VisitTypeTraitExpr(const TypeTraitExpr *S) {
   VisitExpr(S);
   ID.AddInteger(S->getTrait());
@@ -1200,7 +1320,7 @@
     }
   }
 
-  ID.AddPointer(D? D->getCanonicalDecl() : 0);
+  ID.AddPointer(D? D->getCanonicalDecl() : nullptr);
 }
 
 void StmtProfiler::VisitType(QualType T) {
@@ -1268,9 +1388,8 @@
     break;
 
   case TemplateArgument::Pack:
-    const TemplateArgument *Pack = Arg.pack_begin();
-    for (unsigned i = 0, e = Arg.pack_size(); i != e; ++i)
-      VisitTemplateArgument(Pack[i]);
+    for (const auto &P : Arg.pack_elements())
+      VisitTemplateArgument(P);
     break;
   }
 }
diff --git a/lib/AST/TemplateBase.cpp b/lib/AST/TemplateBase.cpp
index 16efb79..ac6a754 100644
--- a/lib/AST/TemplateBase.cpp
+++ b/lib/AST/TemplateBase.cpp
@@ -114,11 +114,9 @@
     return (getAsExpr()->isTypeDependent() || getAsExpr()->isValueDependent());
 
   case Pack:
-    for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P) {
-      if (P->isDependent())
+    for (const auto &P : pack_elements())
+      if (P.isDependent())
         return true;
-    }
-
     return false;
   }
 
@@ -155,11 +153,9 @@
     return getAsExpr()->isInstantiationDependent();
     
   case Pack:
-    for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P) {
-      if (P->isInstantiationDependent())
+    for (const auto &P : pack_elements())
+      if (P.isInstantiationDependent())
         return true;
-    }
-    
     return false;
   }
 
@@ -214,8 +210,8 @@
     break;
 
   case Pack:
-    for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P)
-      if (P->containsUnexpandedParameterPack())
+    for (const auto &P : pack_elements())
+      if (P.containsUnexpandedParameterPack())
         return true;
 
     break;
@@ -248,7 +244,7 @@
     break;
 
   case Declaration:
-    ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : 0);
+    ID.AddPointer(getAsDecl()? getAsDecl()->getCanonicalDecl() : nullptr);
     break;
 
   case Template:
@@ -345,7 +341,7 @@
                              raw_ostream &Out) const {
   switch (getKind()) {
   case Null:
-    Out << "<no value>";
+    Out << "(no value)";
     break;
     
   case Type: {
@@ -362,7 +358,7 @@
       // FIXME: distinguish between pointer and reference args?
       ND->printQualifiedName(Out);
     } else {
-      Out << "<anonymous>";
+      Out << "(anonymous)";
     }
     break;
   }
@@ -386,20 +382,19 @@
   }
     
   case Expression:
-    getAsExpr()->printPretty(Out, 0, Policy);
+    getAsExpr()->printPretty(Out, nullptr, Policy);
     break;
     
   case Pack:
     Out << "<";
     bool First = true;
-    for (TemplateArgument::pack_iterator P = pack_begin(), PEnd = pack_end();
-         P != PEnd; ++P) {
+    for (const auto &P : pack_elements()) {
       if (First)
         First = false;
       else
         Out << ", ";
       
-      P->print(Policy, Out);
+      P.print(Policy, Out);
     }
     Out << ">";
     break;        
@@ -489,7 +484,7 @@
     LangOptions LangOpts;
     LangOpts.CPlusPlus = true;
     PrintingPolicy Policy(LangOpts);
-    Arg.getAsExpr()->printPretty(OS, 0, Policy);
+    Arg.getAsExpr()->printPretty(OS, nullptr, Policy);
     return DB << OS.str();
   }
       
@@ -511,6 +506,8 @@
 const ASTTemplateArgumentListInfo *
 ASTTemplateArgumentListInfo::Create(ASTContext &C,
                                     const TemplateArgumentListInfo &List) {
+  assert(llvm::alignOf<ASTTemplateArgumentListInfo>() >=
+         llvm::alignOf<TemplateArgumentLoc>());
   std::size_t size = ASTTemplateArgumentListInfo::sizeFor(List.size());
   void *Mem = C.Allocate(size, llvm::alignOf<ASTTemplateArgumentListInfo>());
   ASTTemplateArgumentListInfo *TAI = new (Mem) ASTTemplateArgumentListInfo();
diff --git a/lib/AST/TemplateName.cpp b/lib/AST/TemplateName.cpp
index 8767c63..77c8fd5 100644
--- a/lib/AST/TemplateName.cpp
+++ b/lib/AST/TemplateName.cpp
@@ -78,7 +78,7 @@
   if (SubstTemplateTemplateParmStorage *sub = getAsSubstTemplateTemplateParm())
     return sub->getReplacement().getAsTemplateDecl();
 
-  return 0;
+  return nullptr;
 }
 
 bool TemplateName::isDependent() const {
@@ -121,7 +121,7 @@
     return DTN->getQualifier() && 
       DTN->getQualifier()->containsUnexpandedParameterPack();
 
-  return getAsSubstTemplateTemplateParmPack() != 0;
+  return getAsSubstTemplateTemplateParmPack() != nullptr;
 }
 
 void
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 7421bae..1677874 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -45,7 +45,7 @@
 
 const IdentifierInfo* QualType::getBaseTypeIdentifier() const {
   const Type* ty = getTypePtr();
-  NamedDecl *ND = NULL;
+  NamedDecl *ND = nullptr;
   if (ty->isPointerType() || ty->isReferenceType())
     return ty->getPointeeType().getBaseTypeIdentifier();
   else if (ty->isRecordType())
@@ -60,7 +60,7 @@
 
   if (ND)
     return ND->getIdentifier();
-  return NULL;
+  return nullptr;
 }
 
 bool QualType::isConstant(QualType T, ASTContext &Ctx) {
@@ -202,7 +202,7 @@
 
   // If the canonical form of this type isn't the right kind, reject it.
   if (!isa<ArrayType>(CanonicalType))
-    return 0;
+    return nullptr;
 
   // If this is a typedef for an array type, strip the typedef off without
   // losing all typedef information.
@@ -410,7 +410,7 @@
   if (const ComplexType *Complex = getAs<ComplexType>())
     if (Complex->getElementType()->isIntegerType())
       return Complex;
-  return 0;
+  return nullptr;
 }
 
 QualType Type::getPointeeType() const {
@@ -422,6 +422,10 @@
     return BPT->getPointeeType();
   if (const ReferenceType *RT = getAs<ReferenceType>())
     return RT->getPointeeType();
+  if (const MemberPointerType *MPT = getAs<MemberPointerType>())
+    return MPT->getPointeeType();
+  if (const DecayedType *DT = getAs<DecayedType>())
+    return DT->getPointeeType();
   return QualType();
 }
 
@@ -435,13 +439,13 @@
   // If the canonical form of this type isn't the right kind, reject it.
   if (const RecordType *RT = dyn_cast<RecordType>(CanonicalType)) {
     if (!RT->getDecl()->isStruct())
-      return 0;
+      return nullptr;
 
     // If this is a typedef for a structure type, strip the typedef off without
     // losing all typedef information.
     return cast<RecordType>(getUnqualifiedDesugaredType());
   }
-  return 0;
+  return nullptr;
 }
 
 const RecordType *Type::getAsUnionType() const {
@@ -454,14 +458,14 @@
   // If the canonical form of this type isn't the right kind, reject it.
   if (const RecordType *RT = dyn_cast<RecordType>(CanonicalType)) {
     if (!RT->getDecl()->isUnion())
-      return 0;
+      return nullptr;
 
     // If this is a typedef for a union type, strip the typedef off without
     // losing all typedef information.
     return cast<RecordType>(getUnqualifiedDesugaredType());
   }
 
-  return 0;
+  return nullptr;
 }
 
 ObjCObjectType::ObjCObjectType(QualType Canonical, QualType Base,
@@ -485,11 +489,11 @@
   if (const ObjCObjectType *T = getAs<ObjCObjectType>())
     if (T->getNumProtocols() && T->getInterface())
       return T;
-  return 0;
+  return nullptr;
 }
 
 bool Type::isObjCQualifiedInterfaceType() const {
-  return getAsObjCQualifiedInterfaceType() != 0;
+  return getAsObjCQualifiedInterfaceType() != nullptr;
 }
 
 const ObjCObjectPointerType *Type::getAsObjCQualifiedIdType() const {
@@ -499,7 +503,7 @@
     if (OPT->isObjCQualifiedIdType())
       return OPT;
   }
-  return 0;
+  return nullptr;
 }
 
 const ObjCObjectPointerType *Type::getAsObjCQualifiedClassType() const {
@@ -509,7 +513,7 @@
     if (OPT->isObjCQualifiedClassType())
       return OPT;
   }
-  return 0;
+  return nullptr;
 }
 
 const ObjCObjectPointerType *Type::getAsObjCInterfacePointerType() const {
@@ -517,7 +521,7 @@
     if (OPT->getInterfaceType())
       return OPT;
   }
-  return 0;
+  return nullptr;
 }
 
 const CXXRecordDecl *Type::getPointeeCXXRecordDecl() const {
@@ -527,12 +531,12 @@
   else if (const ReferenceType *RT = getAs<ReferenceType>())
     PointeeType = RT->getPointeeType();
   else
-    return 0;
+    return nullptr;
 
   if (const RecordType *RT = PointeeType->getAs<RecordType>())
     return dyn_cast<CXXRecordDecl>(RT->getDecl());
 
-  return 0;
+  return nullptr;
 }
 
 CXXRecordDecl *Type::getAsCXXRecordDecl() const {
@@ -541,8 +545,8 @@
   else if (const InjectedClassNameType *Injected
                                   = getAs<InjectedClassNameType>())
     return Injected->getDecl();
-  
-  return 0;
+
+  return nullptr;
 }
 
 namespace {
@@ -552,7 +556,7 @@
     using TypeVisitor<GetContainedAutoVisitor, AutoType*>::Visit;
     AutoType *Visit(QualType T) {
       if (T.isNull())
-        return 0;
+        return nullptr;
       return Visit(T.getTypePtr());
     }
 
@@ -585,7 +589,7 @@
       return Visit(T->getElementType());
     }
     AutoType *VisitFunctionType(const FunctionType *T) {
-      return Visit(T->getResultType());
+      return Visit(T->getReturnType());
     }
     AutoType *VisitParenType(const ParenType *T) {
       return Visit(T->getInnerType());
@@ -593,6 +597,9 @@
     AutoType *VisitAttributedType(const AttributedType *T) {
       return Visit(T->getModifiedType());
     }
+    AutoType *VisitAdjustedType(const AdjustedType *T) {
+      return Visit(T->getOriginalType());
+    }
   };
 }
 
@@ -688,7 +695,7 @@
 /// types.
 bool Type::isAnyCharacterType() const {
   const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType);
-  if (BT == 0) return false;
+  if (!BT) return false;
   switch (BT->getKind()) {
   default: return false;
   case BuiltinType::Char_U:
@@ -894,8 +901,8 @@
 /// determine its size.
 bool Type::isIncompleteType(NamedDecl **Def) const {
   if (Def)
-    *Def = 0;
-  
+    *Def = nullptr;
+
   switch (CanonicalType->getTypeClass()) {
   default: return false;
   case Builtin:
@@ -1424,8 +1431,7 @@
   llvm_unreachable("Unknown elaborated type keyword.");
 }
 
-const char*
-TypeWithKeyword::getKeywordName(ElaboratedTypeKeyword Keyword) {
+StringRef TypeWithKeyword::getKeywordName(ElaboratedTypeKeyword Keyword) {
   switch (Keyword) {
   case ETK_None: return "";
   case ETK_Typename: return "typename";
@@ -1516,7 +1522,7 @@
   case ULong:             return "unsigned long";
   case ULongLong:         return "unsigned long long";
   case UInt128:           return "unsigned __int128";
-  case Half:              return "half";
+  case Half:              return Policy.Half ? "half" : "__fp16";
   case Float:             return "float";
   case Double:            return "double";
   case LongDouble:        return "long double";
@@ -1582,41 +1588,38 @@
   llvm_unreachable("Invalid calling convention.");
 }
 
-FunctionProtoType::FunctionProtoType(QualType result, ArrayRef<QualType> args,
+FunctionProtoType::FunctionProtoType(QualType result, ArrayRef<QualType> params,
                                      QualType canonical,
                                      const ExtProtoInfo &epi)
-  : FunctionType(FunctionProto, result, epi.TypeQuals,
-                 canonical,
-                 result->isDependentType(),
-                 result->isInstantiationDependentType(),
-                 result->isVariablyModifiedType(),
-                 result->containsUnexpandedParameterPack(),
-                 epi.ExtInfo),
-    NumArgs(args.size()), NumExceptions(epi.NumExceptions),
-    ExceptionSpecType(epi.ExceptionSpecType),
-    HasAnyConsumedArgs(epi.ConsumedArguments != 0),
-    Variadic(epi.Variadic), HasTrailingReturn(epi.HasTrailingReturn),
-    RefQualifier(epi.RefQualifier)
-{
-  assert(NumArgs == args.size() && "function has too many parameters");
+    : FunctionType(FunctionProto, result, epi.TypeQuals, canonical,
+                   result->isDependentType(),
+                   result->isInstantiationDependentType(),
+                   result->isVariablyModifiedType(),
+                   result->containsUnexpandedParameterPack(), epi.ExtInfo),
+      NumParams(params.size()), NumExceptions(epi.NumExceptions),
+      ExceptionSpecType(epi.ExceptionSpecType),
+      HasAnyConsumedParams(epi.ConsumedParameters != nullptr),
+      Variadic(epi.Variadic), HasTrailingReturn(epi.HasTrailingReturn),
+      RefQualifier(epi.RefQualifier) {
+  assert(NumParams == params.size() && "function has too many parameters");
 
   // Fill in the trailing argument array.
   QualType *argSlot = reinterpret_cast<QualType*>(this+1);
-  for (unsigned i = 0; i != NumArgs; ++i) {
-    if (args[i]->isDependentType())
+  for (unsigned i = 0; i != NumParams; ++i) {
+    if (params[i]->isDependentType())
       setDependent();
-    else if (args[i]->isInstantiationDependentType())
+    else if (params[i]->isInstantiationDependentType())
       setInstantiationDependent();
-    
-    if (args[i]->containsUnexpandedParameterPack())
+
+    if (params[i]->containsUnexpandedParameterPack())
       setContainsUnexpandedParameterPack();
 
-    argSlot[i] = args[i];
+    argSlot[i] = params[i];
   }
 
   if (getExceptionSpecType() == EST_Dynamic) {
     // Fill in the exception array.
-    QualType *exnSlot = argSlot + NumArgs;
+    QualType *exnSlot = argSlot + NumParams;
     for (unsigned i = 0, e = epi.NumExceptions; i != e; ++i) {
       if (epi.Exceptions[i]->isDependentType())
         setDependent();
@@ -1630,7 +1633,7 @@
     }
   } else if (getExceptionSpecType() == EST_ComputedNoexcept) {
     // Store the noexcept expression and context.
-    Expr **noexSlot = reinterpret_cast<Expr**>(argSlot + NumArgs);
+    Expr **noexSlot = reinterpret_cast<Expr **>(argSlot + NumParams);
     *noexSlot = epi.NoexceptExpr;
     
     if (epi.NoexceptExpr) {
@@ -1643,7 +1646,8 @@
   } else if (getExceptionSpecType() == EST_Uninstantiated) {
     // Store the function decl from which we will resolve our
     // exception specification.
-    FunctionDecl **slot = reinterpret_cast<FunctionDecl**>(argSlot + NumArgs);
+    FunctionDecl **slot =
+        reinterpret_cast<FunctionDecl **>(argSlot + NumParams);
     slot[0] = epi.ExceptionSpecDecl;
     slot[1] = epi.ExceptionSpecTemplate;
     // This exception specification doesn't make the type dependent, because
@@ -1651,14 +1655,15 @@
   } else if (getExceptionSpecType() == EST_Unevaluated) {
     // Store the function decl from which we will resolve our
     // exception specification.
-    FunctionDecl **slot = reinterpret_cast<FunctionDecl**>(argSlot + NumArgs);
+    FunctionDecl **slot =
+        reinterpret_cast<FunctionDecl **>(argSlot + NumParams);
     slot[0] = epi.ExceptionSpecDecl;
   }
 
-  if (epi.ConsumedArguments) {
-    bool *consumedArgs = const_cast<bool*>(getConsumedArgsBuffer());
-    for (unsigned i = 0; i != NumArgs; ++i)
-      consumedArgs[i] = epi.ConsumedArguments[i];
+  if (epi.ConsumedParameters) {
+    bool *consumedParams = const_cast<bool *>(getConsumedParamsBuffer());
+    for (unsigned i = 0; i != NumParams; ++i)
+      consumedParams[i] = epi.ConsumedParameters[i];
   }
 }
 
@@ -1678,7 +1683,7 @@
     return NR_Dependent;
 
   llvm::APSInt value;
-  bool isICE = noexceptExpr->isIntegerConstantExpr(value, ctx, 0,
+  bool isICE = noexceptExpr->isIntegerConstantExpr(value, ctx, nullptr,
                                                    /*evaluated*/false);
   (void)isICE;
   assert(isICE && "AST should not contain bad noexcept expressions.");
@@ -1686,16 +1691,41 @@
   return value.getBoolValue() ? NR_Nothrow : NR_Throw;
 }
 
+bool FunctionProtoType::isNothrow(const ASTContext &Ctx,
+                                  bool ResultIfDependent) const {
+  ExceptionSpecificationType EST = getExceptionSpecType();
+  assert(EST != EST_Unevaluated && EST != EST_Uninstantiated);
+  if (EST == EST_DynamicNone || EST == EST_BasicNoexcept)
+    return true;
+
+  if (EST == EST_Dynamic && ResultIfDependent == true) {
+    // A dynamic exception specification is throwing unless every exception
+    // type is an (unexpanded) pack expansion type.
+    for (unsigned I = 0, N = NumExceptions; I != N; ++I)
+      if (!getExceptionType(I)->getAs<PackExpansionType>())
+        return false;
+    return ResultIfDependent;
+  }
+
+  if (EST != EST_ComputedNoexcept)
+    return false;
+
+  NoexceptResult NR = getNoexceptSpec(Ctx);
+  if (NR == NR_Dependent)
+    return ResultIfDependent;
+  return NR == NR_Nothrow;
+}
+
 bool FunctionProtoType::isTemplateVariadic() const {
-  for (unsigned ArgIdx = getNumArgs(); ArgIdx; --ArgIdx)
-    if (isa<PackExpansionType>(getArgType(ArgIdx - 1)))
+  for (unsigned ArgIdx = getNumParams(); ArgIdx; --ArgIdx)
+    if (isa<PackExpansionType>(getParamType(ArgIdx - 1)))
       return true;
   
   return false;
 }
 
 void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, QualType Result,
-                                const QualType *ArgTys, unsigned NumArgs,
+                                const QualType *ArgTys, unsigned NumParams,
                                 const ExtProtoInfo &epi,
                                 const ASTContext &Context) {
 
@@ -1717,7 +1747,7 @@
   // whether the following bool is the EH spec or part of the arguments.
 
   ID.AddPointer(Result.getAsOpaquePtr());
-  for (unsigned i = 0; i != NumArgs; ++i)
+  for (unsigned i = 0; i != NumParams; ++i)
     ID.AddPointer(ArgTys[i].getAsOpaquePtr());
   // This method is relatively performance sensitive, so as a performance
   // shortcut, use one AddInteger call instead of four for the next four
@@ -1740,9 +1770,9 @@
              epi.ExceptionSpecType == EST_Unevaluated) {
     ID.AddPointer(epi.ExceptionSpecDecl->getCanonicalDecl());
   }
-  if (epi.ConsumedArguments) {
-    for (unsigned i = 0; i != NumArgs; ++i)
-      ID.AddBoolean(epi.ConsumedArguments[i]);
+  if (epi.ConsumedParameters) {
+    for (unsigned i = 0; i != NumParams; ++i)
+      ID.AddBoolean(epi.ConsumedParameters[i]);
   }
   epi.ExtInfo.Profile(ID);
   ID.AddBoolean(epi.HasTrailingReturn);
@@ -1750,7 +1780,7 @@
 
 void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID,
                                 const ASTContext &Ctx) {
-  Profile(ID, getResultType(), arg_type_begin(), NumArgs, getExtProtoInfo(),
+  Profile(ID, getReturnType(), param_type_begin(), NumParams, getExtProtoInfo(),
           Ctx);
 }
 
@@ -1819,11 +1849,9 @@
     decl(const_cast<TagDecl*>(D)) {}
 
 static TagDecl *getInterestingTagDecl(TagDecl *decl) {
-  for (TagDecl::redecl_iterator I = decl->redecls_begin(),
-                                E = decl->redecls_end();
-       I != E; ++I) {
+  for (auto I : decl->redecls()) {
     if (I->isCompleteDefinition() || I->isBeingDefined())
-      return *I;
+      return I;
   }
   // If there's no definition (not even in progress), return what we have.
   return decl;
@@ -1896,7 +1924,7 @@
 }
 
 IdentifierInfo *TemplateTypeParmType::getIdentifier() const {
-  return isCanonicalUnqualified() ? 0 : getDecl()->getIdentifier();
+  return isCanonicalUnqualified() ? nullptr : getDecl()->getIdentifier();
 }
 
 SubstTemplateTypeParmPackType::
@@ -1922,10 +1950,8 @@
                                             const TemplateArgument &ArgPack) {
   ID.AddPointer(Replaced);
   ID.AddInteger(ArgPack.pack_size());
-  for (TemplateArgument::pack_iterator P = ArgPack.pack_begin(), 
-                                    PEnd = ArgPack.pack_end();
-       P != PEnd; ++P)
-    ID.AddPointer(P->getAsType().getAsOpaquePtr());
+  for (const auto &P : ArgPack.pack_elements())
+    ID.AddPointer(P.getAsType().getAsOpaquePtr());
 }
 
 bool TemplateSpecializationType::
@@ -2200,13 +2226,12 @@
   case Type::ExtVector:
     return Cache::get(cast<VectorType>(T)->getElementType());
   case Type::FunctionNoProto:
-    return Cache::get(cast<FunctionType>(T)->getResultType());
+    return Cache::get(cast<FunctionType>(T)->getReturnType());
   case Type::FunctionProto: {
     const FunctionProtoType *FPT = cast<FunctionProtoType>(T);
-    CachedProperties result = Cache::get(FPT->getResultType());
-    for (FunctionProtoType::arg_type_iterator ai = FPT->arg_type_begin(),
-           ae = FPT->arg_type_end(); ai != ae; ++ai)
-      result = merge(result, Cache::get(*ai));
+    CachedProperties result = Cache::get(FPT->getReturnType());
+    for (const auto &ai : FPT->param_types())
+      result = merge(result, Cache::get(ai));
     return result;
   }
   case Type::ObjCInterface: {
@@ -2285,13 +2310,12 @@
   case Type::ExtVector:
     return computeLinkageInfo(cast<VectorType>(T)->getElementType());
   case Type::FunctionNoProto:
-    return computeLinkageInfo(cast<FunctionType>(T)->getResultType());
+    return computeLinkageInfo(cast<FunctionType>(T)->getReturnType());
   case Type::FunctionProto: {
     const FunctionProtoType *FPT = cast<FunctionProtoType>(T);
-    LinkageInfo LV = computeLinkageInfo(FPT->getResultType());
-    for (FunctionProtoType::arg_type_iterator ai = FPT->arg_type_begin(),
-           ae = FPT->arg_type_end(); ai != ae; ++ai)
-      LV.merge(computeLinkageInfo(*ai));
+    LinkageInfo LV = computeLinkageInfo(FPT->getReturnType());
+    for (const auto &ai : FPT->param_types())
+      LV.merge(computeLinkageInfo(ai));
     return LV;
   }
   case Type::ObjCInterface:
@@ -2441,3 +2465,7 @@
 
   return DK_none;
 }
+
+CXXRecordDecl *MemberPointerType::getMostRecentCXXRecordDecl() const {
+  return getClass()->getAsCXXRecordDecl()->getMostRecentDecl();
+}
diff --git a/lib/AST/TypeLoc.cpp b/lib/AST/TypeLoc.cpp
index 22a51bc..208d695 100644
--- a/lib/AST/TypeLoc.cpp
+++ b/lib/AST/TypeLoc.cpp
@@ -55,7 +55,7 @@
 /// \brief Returns the alignment of the type source info data block.
 unsigned TypeLoc::getLocalAlignmentForType(QualType Ty) {
   if (Ty.isNull()) return 1;
-  return TypeAligner().Visit(TypeLoc(Ty, 0));
+  return TypeAligner().Visit(TypeLoc(Ty, nullptr));
 }
 
 namespace {
@@ -73,7 +73,7 @@
 /// \brief Returns the size of the type source info data block.
 unsigned TypeLoc::getFullDataSizeForType(QualType Ty) {
   unsigned Total = 0;
-  TypeLoc TyLoc(Ty, 0);
+  TypeLoc TyLoc(Ty, nullptr);
   unsigned MaxAlign = 1;
   while (!TyLoc.isNull()) {
     unsigned Align = getLocalAlignmentForType(TyLoc.getType());
diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp
index 571e3db..061473e 100644
--- a/lib/AST/TypePrinter.cpp
+++ b/lib/AST/TypePrinter.cpp
@@ -204,6 +204,7 @@
       NeedARCStrongQualifier = true;
       // Fall through
       
+    case Type::Adjusted:
     case Type::Decayed:
     case Type::Pointer:
     case Type::BlockPointer:
@@ -429,7 +430,16 @@
 }
 void TypePrinter::printConstantArrayAfter(const ConstantArrayType *T, 
                                           raw_ostream &OS) {
-  OS << '[' << T->getSize().getZExtValue() << ']';
+  OS << '[';
+  if (T->getIndexTypeQualifiers().hasQualifiers()) {
+    AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers());
+    OS << ' ';
+  }
+
+  if (T->getSizeModifier() == ArrayType::Static)
+    OS << "static ";
+
+  OS << T->getSize().getZExtValue() << ']';
   printAfter(T->getElementType(), OS);
 }
 
@@ -460,23 +470,32 @@
   }
 
   if (T->getSizeModifier() == VariableArrayType::Static)
-    OS << "static";
+    OS << "static ";
   else if (T->getSizeModifier() == VariableArrayType::Star)
     OS << '*';
 
   if (T->getSizeExpr())
-    T->getSizeExpr()->printPretty(OS, 0, Policy);
+    T->getSizeExpr()->printPretty(OS, nullptr, Policy);
   OS << ']';
 
   printAfter(T->getElementType(), OS);
 }
 
+void TypePrinter::printAdjustedBefore(const AdjustedType *T, raw_ostream &OS) {
+  // Print the adjusted representation, otherwise the adjustment will be
+  // invisible.
+  printBefore(T->getAdjustedType(), OS);
+}
+void TypePrinter::printAdjustedAfter(const AdjustedType *T, raw_ostream &OS) {
+  printAfter(T->getAdjustedType(), OS);
+}
+
 void TypePrinter::printDecayedBefore(const DecayedType *T, raw_ostream &OS) {
   // Print as though it's a pointer.
-  printBefore(T->getDecayedType(), OS);
+  printAdjustedBefore(T, OS);
 }
 void TypePrinter::printDecayedAfter(const DecayedType *T, raw_ostream &OS) {
-  printAfter(T->getDecayedType(), OS);
+  printAdjustedAfter(T, OS);
 }
 
 void TypePrinter::printDependentSizedArrayBefore(
@@ -491,7 +510,7 @@
                                                raw_ostream &OS) {
   OS << '[';
   if (T->getSizeExpr())
-    T->getSizeExpr()->printPretty(OS, 0, Policy);
+    T->getSizeExpr()->printPretty(OS, nullptr, Policy);
   OS << ']';
   printAfter(T->getElementType(), OS);
 }
@@ -506,7 +525,7 @@
                                           raw_ostream &OS) { 
   OS << " __attribute__((ext_vector_type(";
   if (T->getSizeExpr())
-    T->getSizeExpr()->printPretty(OS, 0, Policy);
+    T->getSizeExpr()->printPretty(OS, nullptr, Policy);
   OS << ")))";  
   printAfter(T->getElementType(), OS);
 }
@@ -583,7 +602,8 @@
     OS << " noexcept";
     if (getExceptionSpecType() == EST_ComputedNoexcept) {
       OS << '(';
-      getNoexceptExpr()->printPretty(OS, 0, Policy);
+      if (getNoexceptExpr())
+        getNoexceptExpr()->printPretty(OS, nullptr, Policy);
       OS << ')';
     }
   }
@@ -598,7 +618,7 @@
   } else {
     // If needed for precedence reasons, wrap the inner part in grouping parens.
     SaveAndRestore<bool> PrevPHIsEmpty(HasEmptyPlaceHolder, false);
-    printBefore(T->getResultType(), OS);
+    printBefore(T->getReturnType(), OS);
     if (!PrevPHIsEmpty.get())
       OS << '(';
   }
@@ -614,17 +634,17 @@
   OS << '(';
   {
     ParamPolicyRAII ParamPolicy(Policy);
-    for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i) {
+    for (unsigned i = 0, e = T->getNumParams(); i != e; ++i) {
       if (i) OS << ", ";
-      print(T->getArgType(i), OS, StringRef());
+      print(T->getParamType(i), OS, StringRef());
     }
   }
   
   if (T->isVariadic()) {
-    if (T->getNumArgs())
+    if (T->getNumParams())
       OS << ", ";
     OS << "...";
-  } else if (T->getNumArgs() == 0 && !Policy.LangOpts.CPlusPlus) {
+  } else if (T->getNumParams() == 0 && !Policy.LangOpts.CPlusPlus) {
     // Do not emit int() if we have a proto, emit 'int(void)'.
     OS << "void";
   }
@@ -703,17 +723,17 @@
   T->printExceptionSpecification(OS, Policy);
 
   if (T->hasTrailingReturn()) {
-    OS << " -> "; 
-    print(T->getResultType(), OS, StringRef());
+    OS << " -> ";
+    print(T->getReturnType(), OS, StringRef());
   } else
-    printAfter(T->getResultType(), OS);
+    printAfter(T->getReturnType(), OS);
 }
 
 void TypePrinter::printFunctionNoProtoBefore(const FunctionNoProtoType *T, 
                                              raw_ostream &OS) { 
   // If needed for precedence reasons, wrap the inner part in grouping parens.
   SaveAndRestore<bool> PrevPHIsEmpty(HasEmptyPlaceHolder, false);
-  printBefore(T->getResultType(), OS);
+  printBefore(T->getReturnType(), OS);
   if (!PrevPHIsEmpty.get())
     OS << '(';
 }
@@ -727,7 +747,7 @@
   OS << "()";
   if (T->getNoReturnAttr())
     OS << " __attribute__((noreturn))";
-  printAfter(T->getResultType(), OS);
+  printAfter(T->getReturnType(), OS);
 }
 
 void TypePrinter::printTypeSpec(const NamedDecl *D, raw_ostream &OS) {
@@ -751,7 +771,8 @@
 void TypePrinter::printTypeOfExprBefore(const TypeOfExprType *T,
                                         raw_ostream &OS) {
   OS << "typeof ";
-  T->getUnderlyingExpr()->printPretty(OS, 0, Policy);
+  if (T->getUnderlyingExpr())
+    T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
   spaceBeforePlaceHolder(OS);
 }
 void TypePrinter::printTypeOfExprAfter(const TypeOfExprType *T,
@@ -767,7 +788,8 @@
 
 void TypePrinter::printDecltypeBefore(const DecltypeType *T, raw_ostream &OS) { 
   OS << "decltype(";
-  T->getUnderlyingExpr()->printPretty(OS, 0, Policy);
+  if (T->getUnderlyingExpr())
+    T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);
   OS << ')';
   spaceBeforePlaceHolder(OS);
 }
@@ -838,7 +860,7 @@
     if (NS->getIdentifier())
       OS << NS->getName() << "::";
     else
-      OS << "<anonymous>::";
+      OS << "(anonymous namespace)::";
   } else if (ClassTemplateSpecializationDecl *Spec
                = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
     IncludeStrongLifetimeRAII Strong(Policy);
@@ -890,13 +912,13 @@
     OS << Typedef->getIdentifier()->getName();
   } else {
     // Make an unambiguous representation for anonymous types, e.g.
-    //   <anonymous enum at /usr/include/string.h:120:9>
+    //   (anonymous enum at /usr/include/string.h:120:9)
     
     if (isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda()) {
-      OS << "<lambda";
+      OS << "(lambda";
       HasKindDecoration = true;
     } else {
-      OS << "<anonymous";
+      OS << "(anonymous";
     }
     
     if (Policy.AnonymousTagLocations) {
@@ -915,7 +937,7 @@
       }
     }
     
-    OS << '>';
+    OS << ')';
   }
 
   // If this is a class template specialization, print the template
@@ -1249,13 +1271,12 @@
   print(T->getBaseType(), OS, StringRef());
   OS << '<';
   bool isFirst = true;
-  for (ObjCObjectType::qual_iterator
-         I = T->qual_begin(), E = T->qual_end(); I != E; ++I) {
+  for (const auto *I : T->quals()) {
     if (isFirst)
       isFirst = false;
     else
       OS << ',';
-    OS << (*I)->getName();
+    OS << I->getName();
   }
   OS << '>';
   spaceBeforePlaceHolder(OS);
@@ -1271,12 +1292,12 @@
   T->getPointeeType().getLocalQualifiers().print(OS, Policy,
                                                 /*appendSpaceIfNonEmpty=*/true);
 
+  assert(!T->isObjCSelType());
+
   if (T->isObjCIdType() || T->isObjCQualifiedIdType())
     OS << "id";
   else if (T->isObjCClassType() || T->isObjCQualifiedClassType())
     OS << "Class";
-  else if (T->isObjCSelType())
-    OS << "SEL";
   else
     OS << T->getInterfaceDecl()->getName();
   
@@ -1292,7 +1313,8 @@
     OS << '>';
   }
   
-  if (!T->isObjCIdType() && !T->isObjCQualifiedIdType()) {
+  if (!T->isObjCIdType() && !T->isObjCQualifiedIdType() &&
+      !T->isObjCClassType() && !T->isObjCQualifiedClassType()) {
     OS << " *"; // Don't forget the implicit pointer.
   } else {
     spaceBeforePlaceHolder(OS);
@@ -1413,13 +1435,10 @@
   print(llvm::errs(), PrintingPolicy(LO), "identifier");
   llvm::errs() << '\n';
 }
-void QualType::dump() const {
-  dump(0);
-}
 
-void Type::dump() const {
-  QualType(this, 0).dump();
-}
+LLVM_DUMP_METHOD void QualType::dump() const { dump(nullptr); }
+
+LLVM_DUMP_METHOD void Type::dump() const { QualType(this, 0).dump(); }
 
 std::string Qualifiers::getAsString() const {
   LangOptions LO;
diff --git a/lib/AST/VTTBuilder.cpp b/lib/AST/VTTBuilder.cpp
index 5ca4e86..c213d1c 100644
--- a/lib/AST/VTTBuilder.cpp
+++ b/lib/AST/VTTBuilder.cpp
@@ -56,15 +56,13 @@
 void VTTBuilder::LayoutSecondaryVTTs(BaseSubobject Base) {
   const CXXRecordDecl *RD = Base.getBase();
 
-  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
-       E = RD->bases_end(); I != E; ++I) {
-    
+  for (const auto &I : RD->bases()) {    
     // Don't layout virtual bases.
-    if (I->isVirtual())
+    if (I.isVirtual())
         continue;
 
     const CXXRecordDecl *BaseDecl =
-      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+      cast<CXXRecordDecl>(I.getType()->getAs<RecordType>()->getDecl());
 
     const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD);
     CharUnits BaseOffset = Base.getBaseOffset() + 
@@ -88,10 +86,9 @@
   if (!RD->getNumVBases() && !BaseIsMorallyVirtual)
     return;
 
-  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
-       E = RD->bases_end(); I != E; ++I) {
+  for (const auto &I : RD->bases()) {
     const CXXRecordDecl *BaseDecl =
-      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+      cast<CXXRecordDecl>(I.getType()->getAs<RecordType>()->getDecl());
 
     // Itanium C++ ABI 2.6.2:
     //   Secondary virtual pointers are present for all bases with either
@@ -106,7 +103,7 @@
     bool BaseDeclIsMorallyVirtual = BaseIsMorallyVirtual;
     bool BaseDeclIsNonVirtualPrimaryBase = false;
     CharUnits BaseOffset;
-    if (I->isVirtual()) {
+    if (I.isVirtual()) {
       // Ignore virtual bases that we've already visited.
       if (!VBases.insert(BaseDecl))
         continue;
@@ -153,13 +150,12 @@
 
 void VTTBuilder::LayoutVirtualVTTs(const CXXRecordDecl *RD,
                                    VisitedVirtualBasesSetTy &VBases) {
-  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
-       E = RD->bases_end(); I != E; ++I) {
+  for (const auto &I : RD->bases()) {
     const CXXRecordDecl *BaseDecl = 
-      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+      cast<CXXRecordDecl>(I.getType()->getAs<RecordType>()->getDecl());
     
     // Check if this is a virtual base.
-    if (I->isVirtual()) {
+    if (I.isVirtual()) {
       // Check if we've seen this base before.
       if (!VBases.insert(BaseDecl))
         continue;
diff --git a/lib/AST/VTableBuilder.cpp b/lib/AST/VTableBuilder.cpp
index 5f7ae0f..fa1127f 100644
--- a/lib/AST/VTableBuilder.cpp
+++ b/lib/AST/VTableBuilder.cpp
@@ -16,6 +16,7 @@
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/RecordLayout.h"
 #include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/Support/Format.h"
 #include "llvm/Support/raw_ostream.h"
 #include <algorithm>
@@ -43,9 +44,9 @@
   /// path from the derived class to the base class involves a virtual base
   /// class.
   CharUnits NonVirtualOffset;
-  
-  BaseOffset() : DerivedClass(0), VirtualBase(0), 
-    NonVirtualOffset(CharUnits::Zero()) { }
+
+  BaseOffset() : DerivedClass(nullptr), VirtualBase(nullptr),
+                 NonVirtualOffset(CharUnits::Zero()) { }
   BaseOffset(const CXXRecordDecl *DerivedClass,
              const CXXRecordDecl *VirtualBase, CharUnits NonVirtualOffset)
     : DerivedClass(DerivedClass), VirtualBase(VirtualBase), 
@@ -63,10 +64,15 @@
     /// Method - The method decl of the overrider.
     const CXXMethodDecl *Method;
 
+    /// VirtualBase - The virtual base class subobject of this overridder.
+    /// Note that this records the closest derived virtual base class subobject.
+    const CXXRecordDecl *VirtualBase;
+
     /// Offset - the base offset of the overrider's parent in the layout class.
     CharUnits Offset;
-    
-    OverriderInfo() : Method(0), Offset(CharUnits::Zero()) { }
+
+    OverriderInfo() : Method(nullptr), VirtualBase(nullptr),
+                      Offset(CharUnits::Zero()) { }
   };
 
 private:
@@ -200,6 +206,7 @@
       
       Overrider.Offset = OverriderOffset;
       Overrider.Method = Method.Method;
+      Overrider.VirtualBase = Method.InVirtualSubobject;
     }
   }
 
@@ -215,8 +222,8 @@
   CharUnits NonVirtualOffset = CharUnits::Zero();
 
   unsigned NonVirtualStart = 0;
-  const CXXRecordDecl *VirtualBase = 0;
-  
+  const CXXRecordDecl *VirtualBase = nullptr;
+
   // First, look for the virtual base class.
   for (int I = Path.size(), E = 0; I != E; --I) {
     const CXXBasePathElement &Element = Path[I - 1];
@@ -268,11 +275,11 @@
   const FunctionType *DerivedFT = DerivedMD->getType()->getAs<FunctionType>();
   
   // Canonicalize the return types.
-  CanQualType CanDerivedReturnType = 
-    Context.getCanonicalType(DerivedFT->getResultType());
-  CanQualType CanBaseReturnType = 
-    Context.getCanonicalType(BaseFT->getResultType());
-  
+  CanQualType CanDerivedReturnType =
+      Context.getCanonicalType(DerivedFT->getReturnType());
+  CanQualType CanBaseReturnType =
+      Context.getCanonicalType(BaseFT->getReturnType());
+
   assert(CanDerivedReturnType->getTypeClass() == 
          CanBaseReturnType->getTypeClass() && 
          "Types must have same type class!");
@@ -337,13 +344,12 @@
     OffsetInLayoutClass;
   
   // Traverse our bases.
-  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
-       E = RD->bases_end(); I != E; ++I) {
-    const CXXRecordDecl *BaseDecl = I->getType()->getAsCXXRecordDecl();
+  for (const auto &B : RD->bases()) {
+    const CXXRecordDecl *BaseDecl = B.getType()->getAsCXXRecordDecl();
 
     CharUnits BaseOffset;
     CharUnits BaseOffsetInLayoutClass;
-    if (I->isVirtual()) {
+    if (B.isVirtual()) {
       // Check if we've visited this virtual base before.
       if (SubobjectOffsets.count(std::make_pair(BaseDecl, 0)))
         continue;
@@ -363,7 +369,7 @@
     }
 
     ComputeBaseOffsets(BaseSubobject(BaseDecl, BaseOffset), 
-                       I->isVirtual(), BaseOffsetInLayoutClass, 
+                       B.isVirtual(), BaseOffsetInLayoutClass, 
                        SubobjectOffsets, SubobjectLayoutClassOffsets, 
                        SubobjectCounts);
   }
@@ -374,16 +380,15 @@
   const CXXRecordDecl *RD = Base.getBase();
   const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
 
-  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
-       E = RD->bases_end(); I != E; ++I) {
-    const CXXRecordDecl *BaseDecl = I->getType()->getAsCXXRecordDecl();
+  for (const auto &B : RD->bases()) {
+    const CXXRecordDecl *BaseDecl = B.getType()->getAsCXXRecordDecl();
     
     // Ignore bases that don't have any virtual member functions.
     if (!BaseDecl->isPolymorphic())
       continue;
 
     CharUnits BaseOffset;
-    if (I->isVirtual()) {
+    if (B.isVirtual()) {
       if (!VisitedVirtualBases.insert(BaseDecl)) {
         // We've visited this base before.
         continue;
@@ -397,21 +402,22 @@
     dump(Out, BaseSubobject(BaseDecl, BaseOffset), VisitedVirtualBases);
   }
 
-  Out << "Final overriders for (" << RD->getQualifiedNameAsString() << ", ";
+  Out << "Final overriders for (";
+  RD->printQualifiedName(Out);
+  Out << ", ";
   Out << Base.getBaseOffset().getQuantity() << ")\n";
 
   // Now dump the overriders for this base subobject.
-  for (CXXRecordDecl::method_iterator I = RD->method_begin(), 
-       E = RD->method_end(); I != E; ++I) {
-    const CXXMethodDecl *MD = *I;
-
+  for (const auto *MD : RD->methods()) {
     if (!MD->isVirtual())
       continue;
   
     OverriderInfo Overrider = getOverrider(MD, Base.getBaseOffset());
 
-    Out << "  " << MD->getQualifiedNameAsString() << " - (";
-    Out << Overrider.Method->getQualifiedNameAsString();
+    Out << "  ";
+    MD->printQualifiedName(Out);
+    Out << " - (";
+    Overrider.Method->printQualifiedName(Out);
     Out << ", " << Overrider.Offset.getQuantity() << ')';
 
     BaseOffset Offset;
@@ -420,8 +426,10 @@
 
     if (!Offset.isEmpty()) {
       Out << " [ret-adj: ";
-      if (Offset.VirtualBase)
-        Out << Offset.VirtualBase->getQualifiedNameAsString() << " vbase, ";
+      if (Offset.VirtualBase) {
+        Offset.VirtualBase->printQualifiedName(Out);
+        Out << " vbase, ";
+      }
              
       Out << Offset.NonVirtualOffset.getQuantity() << " nv]";
     }
@@ -472,10 +480,10 @@
   // list here because there isn't necessarily an inheritance
   // relationship between the two methods.
   if (LT->getTypeQuals() != RT->getTypeQuals() ||
-      LT->getNumArgs() != RT->getNumArgs())
+      LT->getNumParams() != RT->getNumParams())
     return false;
-  for (unsigned I = 0, E = LT->getNumArgs(); I != E; ++I)
-    if (LT->getArgType(I) != RT->getArgType(I))
+  for (unsigned I = 0, E = LT->getNumParams(); I != E; ++I)
+    if (LT->getParamType(I) != RT->getParamType(I))
       return false;
   return true;
 }
@@ -684,10 +692,7 @@
   }
   
   // Add the vcall offsets.
-  for (CXXRecordDecl::method_iterator I = RD->method_begin(),
-       E = RD->method_end(); I != E; ++I) {
-    const CXXMethodDecl *MD = *I;
-    
+  for (const auto *MD : RD->methods()) {
     if (!MD->isVirtual())
       continue;
 
@@ -715,13 +720,11 @@
   }
 
   // And iterate over all non-virtual bases (ignoring the primary base).
-  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
-       E = RD->bases_end(); I != E; ++I) {
-  
-    if (I->isVirtual())
+  for (const auto &B : RD->bases()) {  
+    if (B.isVirtual())
       continue;
 
-    const CXXRecordDecl *BaseDecl = I->getType()->getAsCXXRecordDecl();
+    const CXXRecordDecl *BaseDecl = B.getType()->getAsCXXRecordDecl();
     if (BaseDecl == PrimaryBase)
       continue;
 
@@ -741,12 +744,11 @@
     Context.getASTRecordLayout(LayoutClass);
 
   // Add vbase offsets.
-  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
-       E = RD->bases_end(); I != E; ++I) {
-    const CXXRecordDecl *BaseDecl = I->getType()->getAsCXXRecordDecl();
+  for (const auto &B : RD->bases()) {
+    const CXXRecordDecl *BaseDecl = B.getType()->getAsCXXRecordDecl();
 
     // Check if this is a virtual base that we haven't visited before.
-    if (I->isVirtual() && VisitedVirtualBases.insert(BaseDecl)) {
+    if (B.isVirtual() && VisitedVirtualBases.insert(BaseDecl)) {
       CharUnits Offset = 
         LayoutClassLayout.getVBaseClassOffset(BaseDecl) - OffsetInLayoutClass;
 
@@ -1294,7 +1296,7 @@
       // We don't have vcall offsets for this virtual base, go ahead and
       // build them.
       VCallAndVBaseOffsetBuilder Builder(MostDerivedClass, MostDerivedClass,
-                                         /*FinalOverriders=*/0,
+                                         /*FinalOverriders=*/nullptr,
                                          BaseSubobject(Offset.VirtualBase,
                                                        CharUnits::Zero()),
                                          /*BaseIsVirtual=*/true,
@@ -1448,8 +1450,8 @@
         return OverriddenMD;
     }
   }
-  
-  return 0;
+
+  return nullptr;
 }
 
 void ItaniumVTableBuilder::AddMethods(
@@ -1503,16 +1505,13 @@
       llvm_unreachable("Found a duplicate primary base!");
   }
 
-  const CXXDestructorDecl *ImplicitVirtualDtor = 0;
+  const CXXDestructorDecl *ImplicitVirtualDtor = nullptr;
 
   typedef llvm::SmallVector<const CXXMethodDecl *, 8> NewVirtualFunctionsTy;
   NewVirtualFunctionsTy NewVirtualFunctions;
 
   // Now go through all virtual member functions and add them.
-  for (CXXRecordDecl::method_iterator I = RD->method_begin(),
-       E = RD->method_end(); I != E; ++I) {
-    const CXXMethodDecl *MD = *I;
-  
+  for (const auto *MD : RD->methods()) {
     if (!MD->isVirtual())
       continue;
 
@@ -1759,13 +1758,12 @@
   const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
   const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
   
-  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
-       E = RD->bases_end(); I != E; ++I) {
+  for (const auto &B : RD->bases()) {
     // Ignore virtual bases, we'll emit them later.
-    if (I->isVirtual())
+    if (B.isVirtual())
       continue;
     
-    const CXXRecordDecl *BaseDecl = I->getType()->getAsCXXRecordDecl();
+    const CXXRecordDecl *BaseDecl = B.getType()->getAsCXXRecordDecl();
 
     // Ignore bases that don't have a vtable.
     if (!BaseDecl->isDynamicClass())
@@ -1838,13 +1836,12 @@
   }
 
   // Traverse bases, looking for more primary virtual bases.
-  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
-       E = RD->bases_end(); I != E; ++I) {
-    const CXXRecordDecl *BaseDecl = I->getType()->getAsCXXRecordDecl();
+  for (const auto &B : RD->bases()) {
+    const CXXRecordDecl *BaseDecl = B.getType()->getAsCXXRecordDecl();
 
     CharUnits BaseOffsetInLayoutClass;
     
-    if (I->isVirtual()) {
+    if (B.isVirtual()) {
       if (!VBases.insert(BaseDecl))
         continue;
       
@@ -1868,13 +1865,12 @@
   //   Then come the virtual base virtual tables, also in inheritance graph
   //   order, and again excluding primary bases (which share virtual tables with
   //   the classes for which they are primary).
-  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
-       E = RD->bases_end(); I != E; ++I) {
-    const CXXRecordDecl *BaseDecl = I->getType()->getAsCXXRecordDecl();
+  for (const auto &B : RD->bases()) {
+    const CXXRecordDecl *BaseDecl = B.getType()->getAsCXXRecordDecl();
 
     // Check if this base needs a vtable. (If it's virtual, not a primary base
     // of some other class, and we haven't visited it before).
-    if (I->isVirtual() && BaseDecl->isDynamicClass() && 
+    if (B.isVirtual() && BaseDecl->isDynamicClass() && 
         !PrimaryVirtualBases.count(BaseDecl) && VBases.insert(BaseDecl)) {
       const ASTRecordLayout &MostDerivedClassLayout =
         Context.getASTRecordLayout(MostDerivedClass);
@@ -1900,21 +1896,6 @@
   }
 }
 
-struct ItaniumThunkInfoComparator {
-  bool operator() (const ThunkInfo &LHS, const ThunkInfo &RHS) {
-    assert(LHS.Method == 0);
-    assert(RHS.Method == 0);
-
-    if (LHS.This != RHS.This)
-      return LHS.This < RHS.This;
-
-    if (LHS.Return != RHS.Return)
-      return LHS.Return < RHS.Return;
-
-    return false;
-  }
-};
-
 /// dumpLayout - Dump the vtable layout.
 void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) {
   // FIXME: write more tests that actually use the dumpLayout output to prevent
@@ -1922,12 +1903,13 @@
 
   if (isBuildingConstructorVTable()) {
     Out << "Construction vtable for ('";
-    Out << MostDerivedClass->getQualifiedNameAsString() << "', ";
+    MostDerivedClass->printQualifiedName(Out);
+    Out << "', ";
     Out << MostDerivedClassOffset.getQuantity() << ") in '";
-    Out << LayoutClass->getQualifiedNameAsString();
+    LayoutClass->printQualifiedName(Out);
   } else {
     Out << "Vtable for '";
-    Out << MostDerivedClass->getQualifiedNameAsString();
+    MostDerivedClass->printQualifiedName(Out);
   }
   Out << "' (" << Components.size() << " entries).\n";
 
@@ -1973,7 +1955,8 @@
       break;
     
     case VTableComponent::CK_RTTI:
-      Out << Component.getRTTIDecl()->getQualifiedNameAsString() << " RTTI";
+      Component.getRTTIDecl()->printQualifiedName(Out);
+      Out << " RTTI";
       break;
     
     case VTableComponent::CK_FunctionPointer: {
@@ -2028,7 +2011,7 @@
       
       const CXXDestructorDecl *DD = Component.getDestructorDecl();
       
-      Out << DD->getQualifiedNameAsString();
+      DD->printQualifiedName(Out);
       if (IsComplete)
         Out << "() [complete]";
       else
@@ -2078,7 +2061,8 @@
         const BaseSubobject &Base = 
           AddressPointsByIndex.find(NextIndex)->second;
         
-        Out << "       -- (" << Base.getBase()->getQualifiedNameAsString();
+        Out << "       -- (";
+        Base.getBase()->printQualifiedName(Out);
         Out << ", " << Base.getBaseOffset().getQuantity();
         Out << ") vtable address --\n";
       } else {
@@ -2124,7 +2108,8 @@
     }
     
     Out << "Virtual base offset offsets for '";
-    Out << MostDerivedClass->getQualifiedNameAsString() << "' (";
+    MostDerivedClass->printQualifiedName(Out);
+    Out << "' (";
     Out << ClassNamesAndOffsets.size();
     Out << (ClassNamesAndOffsets.size() == 1 ? " entry" : " entries") << ").\n";
 
@@ -2158,7 +2143,10 @@
 
       ThunkInfoVectorTy ThunksVector = Thunks[MD];
       std::sort(ThunksVector.begin(), ThunksVector.end(),
-                ItaniumThunkInfoComparator());
+                [](const ThunkInfo &LHS, const ThunkInfo &RHS) {
+        assert(LHS.Method == nullptr && RHS.Method == nullptr);
+        return std::tie(LHS.This, LHS.Return) < std::tie(RHS.This, RHS.Return);
+      });
 
       Out << "Thunks for '" << MethodName << "' (" << ThunksVector.size();
       Out << (ThunksVector.size() == 1 ? " entry" : " entries") << ").\n";
@@ -2203,10 +2191,7 @@
   // Store them in a map keyed by the index so we'll get a sorted table.
   std::map<uint64_t, std::string> IndicesMap;
 
-  for (CXXRecordDecl::method_iterator i = MostDerivedClass->method_begin(),
-       e = MostDerivedClass->method_end(); i != e; ++i) {
-    const CXXMethodDecl *MD = *i;
-    
+  for (const auto *MD : MostDerivedClass->methods()) {
     // We only want virtual member functions.
     if (!MD->isVirtual())
       continue;
@@ -2230,7 +2215,7 @@
   // Print the vtable indices for all the member functions.
   if (!IndicesMap.empty()) {
     Out << "VTable indices for '";
-    Out << MostDerivedClass->getQualifiedNameAsString();
+    MostDerivedClass->printQualifiedName(Out);
     Out << "' (" << IndicesMap.size() << " entries).\n";
 
     for (std::map<uint64_t, std::string>::const_iterator I = IndicesMap.begin(),
@@ -2245,17 +2230,6 @@
 
   Out << '\n';
 }
-
-struct VTableThunksComparator {
-  bool operator()(const VTableLayout::VTableThunkTy &LHS,
-                  const VTableLayout::VTableThunkTy &RHS) {
-    if (LHS.first == RHS.first) {
-      assert(LHS.second == RHS.second &&
-             "Different thunks should have unique indices!");
-    }
-    return LHS.first < RHS.first;
-  }
-};
 }
 
 VTableLayout::VTableLayout(uint64_t NumVTableComponents,
@@ -2276,14 +2250,18 @@
             this->VTableThunks.get());
   std::sort(this->VTableThunks.get(),
             this->VTableThunks.get() + NumVTableThunks,
-            VTableThunksComparator());
+            [](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;
+  });
 }
 
 VTableLayout::~VTableLayout() { }
 
 ItaniumVTableContext::ItaniumVTableContext(ASTContext &Context)
-  : IsMicrosoftABI(Context.getTargetInfo().getCXXABI().isMicrosoft()) {
-}
+    : VTableContextBase(/*MS=*/false) {}
 
 ItaniumVTableContext::~ItaniumVTableContext() {
   llvm::DeleteContainerSeconds(VTableLayouts);
@@ -2312,8 +2290,8 @@
     VirtualBaseClassOffsetOffsets.find(ClassPair);
   if (I != VirtualBaseClassOffsetOffsets.end())
     return I->second;
-  
-  VCallAndVBaseOffsetBuilder Builder(RD, RD, /*FinalOverriders=*/0,
+
+  VCallAndVBaseOffsetBuilder Builder(RD, RD, /*FinalOverriders=*/nullptr,
                                      BaseSubobject(RD, CharUnits::Zero()),
                                      /*BaseIsVirtual=*/false,
                                      /*OffsetInLayoutClass=*/CharUnits::Zero());
@@ -2348,8 +2326,6 @@
 
 void
 ItaniumVTableContext::computeVTableRelatedInformation(const CXXRecordDecl *RD) {
-  assert(!IsMicrosoftABI && "Shouldn't be called in this ABI!");
-
   const VTableLayout *&Entry = VTableLayouts[RD];
 
   // Check if we've computed this information before.
@@ -2444,6 +2420,9 @@
   typedef llvm::DenseMap<GlobalDecl, MethodVFTableLocation>
     MethodVFTableLocationsTy;
 
+  typedef llvm::iterator_range<MethodVFTableLocationsTy::const_iterator>
+    method_locations_range;
+
 private:
   /// VTables - Global vtable information.
   MicrosoftVTableContext &VTables;
@@ -2457,7 +2436,7 @@
 
   const ASTRecordLayout &MostDerivedClassLayout;
 
-  VFPtrInfo WhichVFPtr;
+  const VPtrInfo &WhichVFPtr;
 
   /// FinalOverriders - The final overriders of the most derived class.
   const FinalOverriders Overriders;
@@ -2467,6 +2446,9 @@
 
   MethodVFTableLocationsTy MethodVFTableLocations;
 
+  /// \brief Does this class have an RTTI component?
+  bool HasRTTIComponent;
+
   /// MethodInfo - Contains information about a method in a vtable.
   /// (Used for computing 'this' pointer adjustment thunks.
   struct MethodInfo {
@@ -2521,11 +2503,8 @@
   }
 
   /// ComputeThisOffset - Returns the 'this' argument offset for the given
-  /// method in the given subobject, relative to the beginning of the
-  /// MostDerivedClass.
-  CharUnits ComputeThisOffset(const CXXMethodDecl *MD,
-                              BaseSubobject Base,
-                              FinalOverriders::OverriderInfo Overrider);
+  /// method, relative to the beginning of the MostDerivedClass.
+  CharUnits ComputeThisOffset(FinalOverriders::OverriderInfo Overrider);
 
   void CalculateVtordispAdjustment(FinalOverriders::OverriderInfo Overrider,
                                    CharUnits ThisOffset, ThisAdjustment &TA);
@@ -2533,17 +2512,21 @@
   /// AddMethod - Add a single virtual member function to the vftable
   /// components vector.
   void AddMethod(const CXXMethodDecl *MD, ThunkInfo TI) {
+    if (!TI.isEmpty()) {
+      VTableThunks[Components.size()] = TI;
+      AddThunk(MD, TI);
+    }
     if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
       assert(TI.Return.isEmpty() &&
              "Destructor can't have return adjustment!");
       Components.push_back(VTableComponent::MakeDeletingDtor(DD));
     } else {
-      if (!TI.isEmpty())
-        VTableThunks[Components.size()] = TI;
       Components.push_back(VTableComponent::MakeFunction(MD));
     }
   }
 
+  bool NeedsReturnAdjustingThunk(const CXXMethodDecl *MD);
+
   /// AddMethods - Add the methods of this base subobject and the relevant
   /// subbases to the vftable we're currently laying out.
   void AddMethods(BaseSubobject Base, unsigned BaseDepth,
@@ -2555,8 +2538,9 @@
     // pointing to the middle of a section.
 
     BasesSetVectorTy VisitedBases;
-    AddMethods(BaseSubobject(MostDerivedClass, CharUnits::Zero()), 0, 0,
+    AddMethods(BaseSubobject(MostDerivedClass, CharUnits::Zero()), 0, nullptr,
                VisitedBases);
+    assert(Components.size() && "vftable can't be empty");
 
     assert(MethodVFTableLocations.empty());
     for (MethodInfoMapTy::const_iterator I = MethodInfoMap.begin(),
@@ -2567,8 +2551,8 @@
       // and the entries shadowed by return adjusting thunks.
       if (MD->getParent() != MostDerivedClass || MI.Shadowed)
         continue;
-      MethodVFTableLocation Loc(MI.VBTableIndex, WhichVFPtr.LastVBase,
-                                WhichVFPtr.VFPtrOffset, MI.VFTableIndex);
+      MethodVFTableLocation Loc(MI.VBTableIndex, WhichVFPtr.getVBaseWithVPtr(),
+                                WhichVFPtr.NonVirtualOffset, MI.VFTableIndex);
       if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
         MethodVFTableLocations[GlobalDecl(DD, Dtor_Deleting)] = Loc;
       } else {
@@ -2586,13 +2570,20 @@
 
 public:
   VFTableBuilder(MicrosoftVTableContext &VTables,
-                 const CXXRecordDecl *MostDerivedClass, VFPtrInfo Which)
+                 const CXXRecordDecl *MostDerivedClass, const VPtrInfo *Which)
       : VTables(VTables),
         Context(MostDerivedClass->getASTContext()),
         MostDerivedClass(MostDerivedClass),
         MostDerivedClassLayout(Context.getASTRecordLayout(MostDerivedClass)),
-        WhichVFPtr(Which),
+        WhichVFPtr(*Which),
         Overriders(MostDerivedClass, CharUnits(), MostDerivedClass) {
+    // Only include the RTTI component if we know that we will provide a
+    // definition of the vftable.
+    HasRTTIComponent = Context.getLangOpts().RTTIData &&
+                       !MostDerivedClass->hasAttr<DLLImportAttr>();
+    if (HasRTTIComponent)
+      Components.push_back(VTableComponent::MakeRTTI(MostDerivedClass));
+
     LayoutVFTable();
 
     if (Context.getLangOpts().DumpVTableLayouts)
@@ -2605,12 +2596,9 @@
 
   ThunksMapTy::const_iterator thunks_end() const { return Thunks.end(); }
 
-  MethodVFTableLocationsTy::const_iterator vtable_indices_begin() const {
-    return MethodVFTableLocations.begin();
-  }
-
-  MethodVFTableLocationsTy::const_iterator vtable_indices_end() const {
-    return MethodVFTableLocations.end();
+  method_locations_range vtable_locations() const {
+    return method_locations_range(MethodVFTableLocations.begin(),
+                                  MethodVFTableLocations.end());
   }
 
   uint64_t getNumVTableComponents() const { return Components.size(); }
@@ -2634,6 +2622,8 @@
   void dumpLayout(raw_ostream &);
 };
 
+} // end namespace
+
 /// InitialOverriddenDefinitionCollector - Finds the set of least derived bases
 /// that define the given method.
 struct InitialOverriddenDefinitionCollector {
@@ -2655,14 +2645,18 @@
 }
 
 CharUnits
-VFTableBuilder::ComputeThisOffset(const CXXMethodDecl *MD,
-                                  BaseSubobject Base,
-                                  FinalOverriders::OverriderInfo Overrider) {
+VFTableBuilder::ComputeThisOffset(FinalOverriders::OverriderInfo Overrider) {
   InitialOverriddenDefinitionCollector Collector;
-  visitAllOverriddenMethods(MD, Collector);
+  visitAllOverriddenMethods(Overrider.Method, Collector);
+
+  // If there are no overrides then 'this' is located
+  // in the base that defines the method.
+  if (Collector.Bases.size() == 0)
+    return Overrider.Offset;
 
   CXXBasePaths Paths;
-  Base.getBase()->lookupInBases(BaseInSet, &Collector.Bases, Paths);
+  Overrider.Method->getParent()->lookupInBases(BaseInSet, &Collector.Bases,
+                                               Paths);
 
   // This will hold the smallest this offset among overridees of MD.
   // This implies that an offset of a non-virtual base will dominate an offset
@@ -2671,10 +2665,12 @@
   CharUnits Ret;
   bool First = true;
 
+  const ASTRecordLayout &OverriderRDLayout =
+      Context.getASTRecordLayout(Overrider.Method->getParent());
   for (CXXBasePaths::paths_iterator I = Paths.begin(), E = Paths.end();
        I != E; ++I) {
     const CXXBasePath &Path = (*I);
-    CharUnits ThisOffset = Base.getBaseOffset();
+    CharUnits ThisOffset = Overrider.Offset;
     CharUnits LastVBaseOffset;
 
     // For each path from the overrider to the parents of the overridden methods,
@@ -2687,34 +2683,33 @@
       const ASTRecordLayout &Layout = Context.getASTRecordLayout(PrevRD);
 
       if (Element.Base->isVirtual()) {
-        LastVBaseOffset = MostDerivedClassLayout.getVBaseClassOffset(CurRD);
-        if (Overrider.Method->getParent() == PrevRD) {
-          // This one's interesting. If the final overrider is in a vbase B of the
-          // most derived class and it overrides a method of the B's own vbase A,
-          // it uses A* as "this". In its prologue, it can cast A* to B* with
-          // a static offset. This offset is used regardless of the actual
-          // offset of A from B in the most derived class, requiring an
-          // this-adjusting thunk in the vftable if A and B are laid out
-          // differently in the most derived class.
-          ThisOffset += Layout.getVBaseClassOffset(CurRD);
-        } else {
-          ThisOffset = LastVBaseOffset;
-        }
+        // The interesting things begin when you have virtual inheritance.
+        // The final overrider will use a static adjustment equal to the offset
+        // of the vbase in the final overrider class.
+        // For example, if the final overrider is in a vbase B of the most
+        // derived class and it overrides a method of the B's own vbase A,
+        // it uses A* as "this".  In its prologue, it can cast A* to B* with
+        // a static offset.  This offset is used regardless of the actual
+        // offset of A from B in the most derived class, requiring an
+        // this-adjusting thunk in the vftable if A and B are laid out
+        // differently in the most derived class.
+        LastVBaseOffset = ThisOffset =
+            Overrider.Offset + OverriderRDLayout.getVBaseClassOffset(CurRD);
       } else {
         ThisOffset += Layout.getBaseClassOffset(CurRD);
       }
     }
 
-    if (isa<CXXDestructorDecl>(MD)) {
+    if (isa<CXXDestructorDecl>(Overrider.Method)) {
       if (LastVBaseOffset.isZero()) {
         // If a "Base" class has at least one non-virtual base with a virtual
         // destructor, the "Base" virtual destructor will take the address
         // of the "Base" subobject as the "this" argument.
-        return Base.getBaseOffset();
+        ThisOffset = Overrider.Offset;
       } else {
         // A virtual destructor of a virtual base takes the address of the
         // virtual base subobject as the "this" argument.
-        return LastVBaseOffset;
+        ThisOffset = LastVBaseOffset;
       }
     }
 
@@ -2734,39 +2729,35 @@
   const ASTRecordLayout::VBaseOffsetsMapTy &VBaseMap =
       MostDerivedClassLayout.getVBaseOffsetsMap();
   const ASTRecordLayout::VBaseOffsetsMapTy::const_iterator &VBaseMapEntry =
-      VBaseMap.find(WhichVFPtr.LastVBase);
+      VBaseMap.find(WhichVFPtr.getVBaseWithVPtr());
   assert(VBaseMapEntry != VBaseMap.end());
 
-  // Check if we need a vtordisp adjustment at all.
-  if (!VBaseMapEntry->second.hasVtorDisp())
+  // If there's no vtordisp or the final overrider is defined in the same vbase
+  // as the initial declaration, we don't need any vtordisp adjustment.
+  if (!VBaseMapEntry->second.hasVtorDisp() ||
+      Overrider.VirtualBase == WhichVFPtr.getVBaseWithVPtr())
     return;
 
-  CharUnits VFPtrVBaseOffset = VBaseMapEntry->second.VBaseOffset;
+  // OK, now we know we need to use a vtordisp thunk.
   // The implicit vtordisp field is located right before the vbase.
+  CharUnits VFPtrVBaseOffset = VBaseMapEntry->second.VBaseOffset;
   TA.Virtual.Microsoft.VtordispOffset =
-      (VFPtrVBaseOffset - WhichVFPtr.VFPtrFullOffset).getQuantity() - 4;
+      (VFPtrVBaseOffset - WhichVFPtr.FullOffsetInMDC).getQuantity() - 4;
 
-  // If the final overrider is defined in either:
-  // - the most derived class or its non-virtual base or
-  // - the same vbase as the initial declaration,
-  // a simple vtordisp thunk will suffice.
-  const CXXRecordDecl *OverriderRD = Overrider.Method->getParent();
-  if (OverriderRD == MostDerivedClass)
-    return;
-
-  const CXXRecordDecl *OverriderVBase =
-      ComputeBaseOffset(Context, OverriderRD, MostDerivedClass).VirtualBase;
-  if (!OverriderVBase || OverriderVBase == WhichVFPtr.LastVBase)
+  // A simple vtordisp thunk will suffice if the final overrider is defined
+  // in either the most derived class or its non-virtual base.
+  if (Overrider.Method->getParent() == MostDerivedClass ||
+      !Overrider.VirtualBase)
     return;
 
   // Otherwise, we need to do use the dynamic offset of the final overrider
   // in order to get "this" adjustment right.
   TA.Virtual.Microsoft.VBPtrOffset =
-      (VFPtrVBaseOffset + WhichVFPtr.VFPtrOffset -
+      (VFPtrVBaseOffset + WhichVFPtr.NonVirtualOffset -
        MostDerivedClassLayout.getVBPtrOffset()).getQuantity();
   TA.Virtual.Microsoft.VBOffsetOffset =
       Context.getTypeSizeInChars(Context.IntTy).getQuantity() *
-      VTables.getVBTableIndex(MostDerivedClass, OverriderVBase);
+      VTables.getVBTableIndex(MostDerivedClass, Overrider.VirtualBase);
 
   TA.NonVirtual = (ThisOffset - Overrider.Offset).getQuantity();
 }
@@ -2777,25 +2768,20 @@
   // Put the virtual methods into VirtualMethods in the proper order:
   // 1) Group overloads by declaration name. New groups are added to the
   //    vftable in the order of their first declarations in this class
-  //    (including overrides).
+  //    (including overrides and non-virtual methods).
   // 2) In each group, new overloads appear in the reverse order of declaration.
   typedef SmallVector<const CXXMethodDecl *, 1> MethodGroup;
   SmallVector<MethodGroup, 10> Groups;
   typedef llvm::DenseMap<DeclarationName, unsigned> VisitedGroupIndicesTy;
   VisitedGroupIndicesTy VisitedGroupIndices;
-  for (CXXRecordDecl::method_iterator I = RD->method_begin(),
-       E = RD->method_end(); I != E; ++I) {
-    const CXXMethodDecl *MD = *I;
-    if (!MD->isVirtual())
-      continue;
-
+  for (const auto *MD : RD->methods()) {
     VisitedGroupIndicesTy::iterator J;
     bool Inserted;
-    llvm::tie(J, Inserted) = VisitedGroupIndices.insert(
+    std::tie(J, Inserted) = VisitedGroupIndices.insert(
         std::make_pair(MD->getDeclName(), Groups.size()));
     if (Inserted)
-      Groups.push_back(MethodGroup(1, MD));
-    else
+      Groups.push_back(MethodGroup());
+    if (MD->isVirtual())
       Groups[J->second].push_back(MD);
   }
 
@@ -2803,6 +2789,32 @@
     VirtualMethods.append(Groups[I].rbegin(), Groups[I].rend());
 }
 
+/// We need a return adjusting thunk for this method if its return type is
+/// not trivially convertible to the return type of any of its overridden
+/// methods.
+bool VFTableBuilder::NeedsReturnAdjustingThunk(const CXXMethodDecl *MD) {
+  OverriddenMethodsSetTy OverriddenMethods;
+  ComputeAllOverriddenMethods(MD, OverriddenMethods);
+  for (OverriddenMethodsSetTy::iterator I = OverriddenMethods.begin(),
+                                        E = OverriddenMethods.end();
+       I != E; ++I) {
+    const CXXMethodDecl *OverriddenMD = *I;
+    BaseOffset Adjustment =
+        ComputeReturnAdjustmentBaseOffset(Context, MD, OverriddenMD);
+    if (!Adjustment.isEmpty())
+      return true;
+  }
+  return false;
+}
+
+static bool isDirectVBase(const CXXRecordDecl *Base, const CXXRecordDecl *RD) {
+  for (const auto &B : RD->bases()) {
+    if (B.isVirtual() && B.getType()->getAsCXXRecordDecl() == Base)
+      return true;
+  }
+  return false;
+}
+
 void VFTableBuilder::AddMethods(BaseSubobject Base, unsigned BaseDepth,
                                 const CXXRecordDecl *LastVBase,
                                 BasesSetVectorTy &VisitedBases) {
@@ -2814,11 +2826,11 @@
 
   // See if this class expands a vftable of the base we look at, which is either
   // the one defined by the vfptr base path or the primary base of the current class.
-  const CXXRecordDecl *NextBase = 0, *NextLastVBase = LastVBase;
+  const CXXRecordDecl *NextBase = nullptr, *NextLastVBase = LastVBase;
   CharUnits NextBaseOffset;
-  if (BaseDepth < WhichVFPtr.PathToBaseWithVFPtr.size()) {
-    NextBase = WhichVFPtr.PathToBaseWithVFPtr[BaseDepth];
-    if (Layout.getVBaseOffsetsMap().count(NextBase)) {
+  if (BaseDepth < WhichVFPtr.PathToBaseWithVPtr.size()) {
+    NextBase = WhichVFPtr.PathToBaseWithVPtr[BaseDepth];
+    if (isDirectVBase(NextBase, RD)) {
       NextLastVBase = NextBase;
       NextBaseOffset = MostDerivedClassLayout.getVBaseClassOffset(NextBase);
     } else {
@@ -2856,13 +2868,21 @@
 
     FinalOverriders::OverriderInfo Overrider =
         Overriders.getOverrider(MD, Base.getBaseOffset());
-    ThisAdjustment ThisAdjustmentOffset;
-    bool ForceThunk = false;
+    const CXXMethodDecl *OverriderMD = Overrider.Method;
+    const CXXMethodDecl *OverriddenMD =
+        FindNearestOverriddenMethod(MD, VisitedBases);
 
-    // Check if this virtual member function overrides
-    // a method in one of the visited bases.
-    if (const CXXMethodDecl *OverriddenMD =
-            FindNearestOverriddenMethod(MD, VisitedBases)) {
+    ThisAdjustment ThisAdjustmentOffset;
+    bool ReturnAdjustingThunk = false;
+    CharUnits ThisOffset = ComputeThisOffset(Overrider);
+    ThisAdjustmentOffset.NonVirtual =
+        (ThisOffset - WhichVFPtr.FullOffsetInMDC).getQuantity();
+    if ((OverriddenMD || OverriderMD != MD) &&
+        WhichVFPtr.getVBaseWithVPtr())
+      CalculateVtordispAdjustment(Overrider, ThisOffset, ThisAdjustmentOffset);
+
+    if (OverriddenMD) {
+      // If MD overrides anything in this vftable, we need to update the entries.
       MethodInfoMapTy::iterator OverriddenMDIterator =
           MethodInfoMap.find(OverriddenMD);
 
@@ -2872,23 +2892,7 @@
 
       MethodInfo &OverriddenMethodInfo = OverriddenMDIterator->second;
 
-      // Create a this-adjusting thunk if needed.
-      CharUnits TI = ComputeThisOffset(MD, Base, Overrider);
-      if (TI != WhichVFPtr.VFPtrFullOffset) {
-        ThisAdjustmentOffset.NonVirtual =
-            (TI - WhichVFPtr.VFPtrFullOffset).getQuantity();
-      }
-
-      if (WhichVFPtr.LastVBase)
-        CalculateVtordispAdjustment(Overrider, TI, ThisAdjustmentOffset);
-
-      if (!ThisAdjustmentOffset.isEmpty()) {
-        VTableThunks[OverriddenMethodInfo.VFTableIndex].This =
-            ThisAdjustmentOffset;
-        AddThunk(MD, VTableThunks[OverriddenMethodInfo.VFTableIndex]);
-      }
-
-      if (MD->getResultType() == OverriddenMD->getResultType()) {
+      if (!NeedsReturnAdjustingThunk(MD)) {
         // No return adjustment needed - just replace the overridden method info
         // with the current info.
         MethodInfo MI(OverriddenMethodInfo.VBTableIndex,
@@ -2899,33 +2903,17 @@
                "Should not have method info for this method yet!");
         MethodInfoMap.insert(std::make_pair(MD, MI));
         continue;
-      } else {
-        // In case we need a return adjustment, we'll add a new slot for
-        // the overrider and put a return-adjusting thunk where the overridden
-        // method was in the vftable.
-        // For now, just mark the overriden method as shadowed by a new slot.
-        OverriddenMethodInfo.Shadowed = true;
-        ForceThunk = true;
-
-        // Also apply this adjustment to the shadowed slots.
-        if (!ThisAdjustmentOffset.isEmpty()) {
-          // FIXME: this is O(N^2), can be O(N).
-          const CXXMethodDecl *SubOverride = OverriddenMD;
-          while ((SubOverride =
-                      FindNearestOverriddenMethod(SubOverride, VisitedBases))) {
-            MethodInfoMapTy::iterator SubOverrideIterator =
-                MethodInfoMap.find(SubOverride);
-            if (SubOverrideIterator == MethodInfoMap.end())
-              break;
-            MethodInfo &SubOverrideMI = SubOverrideIterator->second;
-            assert(SubOverrideMI.Shadowed);
-            VTableThunks[SubOverrideMI.VFTableIndex].This =
-                ThisAdjustmentOffset;
-            AddThunk(MD, VTableThunks[SubOverrideMI.VFTableIndex]);
-          }
-        }
       }
-    } else if (Base.getBaseOffset() != WhichVFPtr.VFPtrFullOffset ||
+
+      // In case we need a return adjustment, we'll add a new slot for
+      // the overrider. Mark the overriden method as shadowed by the new slot.
+      OverriddenMethodInfo.Shadowed = true;
+
+      // Force a special name mangling for a return-adjusting thunk
+      // unless the method is the final overrider without this adjustment.
+      ReturnAdjustingThunk =
+          !(MD == OverriderMD && ThisAdjustmentOffset.isEmpty());
+    } else if (Base.getBaseOffset() != WhichVFPtr.FullOffsetInMDC ||
                MD->size_overridden_methods()) {
       // Skip methods that don't belong to the vftable of the current class,
       // e.g. each method that wasn't seen in any of the visited sub-bases
@@ -2937,14 +2925,13 @@
     // it requires return adjustment. Insert the method info for this method.
     unsigned VBIndex =
         LastVBase ? VTables.getVBTableIndex(MostDerivedClass, LastVBase) : 0;
-    MethodInfo MI(VBIndex, Components.size());
+    MethodInfo MI(VBIndex,
+                  HasRTTIComponent ? Components.size() - 1 : Components.size());
 
     assert(!MethodInfoMap.count(MD) &&
            "Should not have method info for this method yet!");
     MethodInfoMap.insert(std::make_pair(MD, MI));
 
-    const CXXMethodDecl *OverriderMD = Overrider.Method;
-
     // Check if this overrider needs a return adjustment.
     // We don't want to do this for pure virtual member functions.
     BaseOffset ReturnAdjustmentOffset;
@@ -2954,7 +2941,7 @@
           ComputeReturnAdjustmentBaseOffset(Context, OverriderMD, MD);
     }
     if (!ReturnAdjustmentOffset.isEmpty()) {
-      ForceThunk = true;
+      ReturnAdjustingThunk = true;
       ReturnAdjustment.NonVirtual =
           ReturnAdjustmentOffset.NonVirtualOffset.getQuantity();
       if (ReturnAdjustmentOffset.VirtualBase) {
@@ -2969,40 +2956,30 @@
     }
 
     AddMethod(OverriderMD, ThunkInfo(ThisAdjustmentOffset, ReturnAdjustment,
-                                     ForceThunk ? MD : 0));
+                                     ReturnAdjustingThunk ? MD : nullptr));
   }
 }
 
-void PrintBasePath(const VFPtrInfo::BasePath &Path, raw_ostream &Out) {
-  for (VFPtrInfo::BasePath::const_reverse_iterator I = Path.rbegin(),
+static void PrintBasePath(const VPtrInfo::BasePath &Path, raw_ostream &Out) {
+  for (VPtrInfo::BasePath::const_reverse_iterator I = Path.rbegin(),
        E = Path.rend(); I != E; ++I) {
-    Out << "'" << (*I)->getQualifiedNameAsString() << "' in ";
+    Out << "'";
+    (*I)->printQualifiedName(Out);
+    Out << "' in ";
   }
 }
 
-struct MicrosoftThunkInfoStableSortComparator {
-  bool operator() (const ThunkInfo &LHS, const ThunkInfo &RHS) {
-    if (LHS.This != RHS.This)
-      return LHS.This < RHS.This;
-
-    if (LHS.Return != RHS.Return)
-      return LHS.Return < RHS.Return;
-
-    // Keep different thunks with the same adjustments in the order they
-    // were put into the vector.
-    return false;
-  }
-};
-
 static void dumpMicrosoftThunkAdjustment(const ThunkInfo &TI, raw_ostream &Out,
                                          bool ContinueFirstLine) {
   const ReturnAdjustment &R = TI.Return;
   bool Multiline = false;
-  const char *LinePrefix = "\n        ";
-  if (!R.isEmpty()) {
+  const char *LinePrefix = "\n       ";
+  if (!R.isEmpty() || TI.Method) {
     if (!ContinueFirstLine)
       Out << LinePrefix;
-    Out << "[return adjustment: ";
+    Out << "[return adjustment (to type '"
+        << TI.Method->getReturnType().getCanonicalType().getAsString()
+        << "'): ";
     if (R.Virtual.Microsoft.VBPtrOffset)
       Out << "vbptr at offset " << R.Virtual.Microsoft.VBPtrOffset << ", ";
     if (R.Virtual.Microsoft.VBIndex)
@@ -3021,7 +2998,7 @@
       Out << "vtordisp at " << T.Virtual.Microsoft.VtordispOffset << ", ";
       if (T.Virtual.Microsoft.VBPtrOffset) {
         Out << "vbptr at " << T.Virtual.Microsoft.VBPtrOffset
-            << " to the left, ";
+            << " to the left,";
         assert(T.Virtual.Microsoft.VBOffsetOffset > 0);
         Out << LinePrefix << " vboffset at "
             << T.Virtual.Microsoft.VBOffsetOffset << " in the vbtable, ";
@@ -3033,9 +3010,11 @@
 
 void VFTableBuilder::dumpLayout(raw_ostream &Out) {
   Out << "VFTable for ";
-  PrintBasePath(WhichVFPtr.PathToBaseWithVFPtr, Out);
-  Out << "'" << MostDerivedClass->getQualifiedNameAsString();
-  Out << "' (" << Components.size() << " entries).\n";
+  PrintBasePath(WhichVFPtr.PathToBaseWithVPtr, Out);
+  Out << "'";
+  MostDerivedClass->printQualifiedName(Out);
+  Out << "' (" << Components.size()
+      << (Components.size() == 1 ? " entry" : " entries") << ").\n";
 
   for (unsigned I = 0, E = Components.size(); I != E; ++I) {
     Out << llvm::format("%4d | ", I);
@@ -3045,12 +3024,15 @@
     // Dump the component.
     switch (Component.getKind()) {
     case VTableComponent::CK_RTTI:
-      Out << Component.getRTTIDecl()->getQualifiedNameAsString() << " RTTI";
+      Component.getRTTIDecl()->printQualifiedName(Out);
+      Out << " RTTI";
       break;
 
     case VTableComponent::CK_FunctionPointer: {
       const CXXMethodDecl *MD = Component.getFunctionDecl();
 
+      // FIXME: Figure out how to print the real thunk type, since they can
+      // differ in the return type.
       std::string Str = PredefinedExpr::ComputeName(
           PredefinedExpr::PrettyFunctionNoVirtual, MD);
       Out << Str;
@@ -3072,7 +3054,7 @@
     case VTableComponent::CK_DeletingDtorPointer: {
       const CXXDestructorDecl *DD = Component.getDestructorDecl();
 
-      Out << DD->getQualifiedNameAsString();
+      DD->printQualifiedName(Out);
       Out << "() [scalar deleting]";
 
       if (DD->isPure())
@@ -3124,7 +3106,11 @@
 
       ThunkInfoVectorTy ThunksVector = Thunks[MD];
       std::stable_sort(ThunksVector.begin(), ThunksVector.end(),
-                       MicrosoftThunkInfoStableSortComparator());
+                       [](const ThunkInfo &LHS, const ThunkInfo &RHS) {
+        // Keep different thunks with the same adjustments in the order they
+        // were put into the vector.
+        return std::tie(LHS.This, LHS.Return) < std::tie(RHS.This, RHS.Return);
+      });
 
       Out << "Thunks for '" << MethodName << "' (" << ThunksVector.size();
       Out << (ThunksVector.size() == 1 ? " entry" : " entries") << ").\n";
@@ -3140,123 +3126,170 @@
       Out << '\n';
     }
   }
-}
+
+  Out.flush();
 }
 
-void MicrosoftVTableContext::enumerateVFPtrs(
-    const CXXRecordDecl *MostDerivedClass,
-    const ASTRecordLayout &MostDerivedClassLayout, BaseSubobject Base,
-    const CXXRecordDecl *LastVBase,
-    const VFPtrInfo::BasePath &PathFromCompleteClass,
-    BasesSetVectorTy &VisitedVBases,
-    VFPtrListTy &Result) {
-  const CXXRecordDecl *CurrentClass = Base.getBase();
-  CharUnits OffsetInCompleteClass = Base.getBaseOffset();
-  const ASTRecordLayout &CurrentClassLayout =
-      Context.getASTRecordLayout(CurrentClass);
-
-  if (CurrentClassLayout.hasOwnVFPtr()) {
-    if (LastVBase) {
-      uint64_t VBIndex = getVBTableIndex(MostDerivedClass, LastVBase);
-      assert(VBIndex > 0 && "vbases must have vbindex!");
-      CharUnits VFPtrOffset =
-          OffsetInCompleteClass -
-          MostDerivedClassLayout.getVBaseClassOffset(LastVBase);
-      Result.push_back(VFPtrInfo(VBIndex, LastVBase, VFPtrOffset,
-                                 PathFromCompleteClass, OffsetInCompleteClass));
-    } else {
-      Result.push_back(VFPtrInfo(OffsetInCompleteClass, PathFromCompleteClass));
-    }
+static bool setsIntersect(const llvm::SmallPtrSet<const CXXRecordDecl *, 4> &A,
+                          const ArrayRef<const CXXRecordDecl *> &B) {
+  for (ArrayRef<const CXXRecordDecl *>::iterator I = B.begin(), E = B.end();
+       I != E; ++I) {
+    if (A.count(*I))
+      return true;
   }
+  return false;
+}
 
-  for (CXXRecordDecl::base_class_const_iterator I = CurrentClass->bases_begin(),
-       E = CurrentClass->bases_end(); I != E; ++I) {
-    const CXXRecordDecl *BaseDecl = I->getType()->getAsCXXRecordDecl();
+static bool rebucketPaths(VPtrInfoVector &Paths);
 
-    CharUnits NextBaseOffset;
-    const CXXRecordDecl *NextLastVBase;
-    if (I->isVirtual()) {
-      if (!VisitedVBases.insert(BaseDecl))
+/// Produces MSVC-compatible vbtable data.  The symbols produced by this
+/// algorithm match those produced by MSVC 2012 and newer, which is different
+/// from MSVC 2010.
+///
+/// MSVC 2012 appears to minimize the vbtable names using the following
+/// algorithm.  First, walk the class hierarchy in the usual order, depth first,
+/// left to right, to find all of the subobjects which contain a vbptr field.
+/// Visiting each class node yields a list of inheritance paths to vbptrs.  Each
+/// record with a vbptr creates an initially empty path.
+///
+/// To combine paths from child nodes, the paths are compared to check for
+/// ambiguity.  Paths are "ambiguous" if multiple paths have the same set of
+/// components in the same order.  Each group of ambiguous paths is extended by
+/// appending the class of the base from which it came.  If the current class
+/// node produced an ambiguous path, its path is extended with the current class.
+/// After extending paths, MSVC again checks for ambiguity, and extends any
+/// ambiguous path which wasn't already extended.  Because each node yields an
+/// unambiguous set of paths, MSVC doesn't need to extend any path more than once
+/// to produce an unambiguous set of paths.
+///
+/// TODO: Presumably vftables use the same algorithm.
+void MicrosoftVTableContext::computeVTablePaths(bool ForVBTables,
+                                                const CXXRecordDecl *RD,
+                                                VPtrInfoVector &Paths) {
+  assert(Paths.empty());
+  const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
+
+  // Base case: this subobject has its own vptr.
+  if (ForVBTables ? Layout.hasOwnVBPtr() : Layout.hasOwnVFPtr())
+    Paths.push_back(new VPtrInfo(RD));
+
+  // Recursive case: get all the vbtables from our bases and remove anything
+  // that shares a virtual base.
+  llvm::SmallPtrSet<const CXXRecordDecl*, 4> VBasesSeen;
+  for (const auto &B : RD->bases()) {
+    const CXXRecordDecl *Base = B.getType()->getAsCXXRecordDecl();
+    if (B.isVirtual() && VBasesSeen.count(Base))
+      continue;
+
+    if (!Base->isDynamicClass())
+      continue;
+
+    const VPtrInfoVector &BasePaths =
+        ForVBTables ? enumerateVBTables(Base) : getVFPtrOffsets(Base);
+
+    for (VPtrInfo *BaseInfo : BasePaths) {
+      // Don't include the path if it goes through a virtual base that we've
+      // already included.
+      if (setsIntersect(VBasesSeen, BaseInfo->ContainingVBases))
         continue;
-      NextBaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl);
-      NextLastVBase = BaseDecl;
-    } else {
-      NextBaseOffset = OffsetInCompleteClass +
-                       CurrentClassLayout.getBaseClassOffset(BaseDecl);
-      NextLastVBase = LastVBase;
+
+      // Copy the path and adjust it as necessary.
+      VPtrInfo *P = new VPtrInfo(*BaseInfo);
+
+      // We mangle Base into the path if the path would've been ambiguous and it
+      // wasn't already extended with Base.
+      if (P->MangledPath.empty() || P->MangledPath.back() != Base)
+        P->NextBaseToMangle = Base;
+
+      // Keep track of the full path.
+      // FIXME: Why do we need this?
+      P->PathToBaseWithVPtr.insert(P->PathToBaseWithVPtr.begin(), Base);
+
+      // Keep track of which vtable the derived class is going to extend with
+      // new methods or bases.  We append to either the vftable of our primary
+      // base, or the first non-virtual base that has a vbtable.
+      if (P->ReusingBase == Base &&
+          Base == (ForVBTables ? Layout.getBaseSharingVBPtr()
+                               : Layout.getPrimaryBase()))
+        P->ReusingBase = RD;
+
+      // Keep track of the full adjustment from the MDC to this vtable.  The
+      // adjustment is captured by an optional vbase and a non-virtual offset.
+      if (B.isVirtual())
+        P->ContainingVBases.push_back(Base);
+      else if (P->ContainingVBases.empty())
+        P->NonVirtualOffset += Layout.getBaseClassOffset(Base);
+
+      // Update the full offset in the MDC.
+      P->FullOffsetInMDC = P->NonVirtualOffset;
+      if (const CXXRecordDecl *VB = P->getVBaseWithVPtr())
+        P->FullOffsetInMDC += Layout.getVBaseClassOffset(VB);
+
+      Paths.push_back(P);
     }
 
-    VFPtrInfo::BasePath NewPath = PathFromCompleteClass;
-    NewPath.push_back(BaseDecl);
-    BaseSubobject NextBase(BaseDecl, NextBaseOffset);
+    if (B.isVirtual())
+      VBasesSeen.insert(Base);
 
-    enumerateVFPtrs(MostDerivedClass, MostDerivedClassLayout, NextBase,
-                    NextLastVBase, NewPath, VisitedVBases, Result);
+    // After visiting any direct base, we've transitively visited all of its
+    // morally virtual bases.
+    for (const auto &VB : Base->vbases())
+      VBasesSeen.insert(VB.getType()->getAsCXXRecordDecl());
   }
+
+  // Sort the paths into buckets, and if any of them are ambiguous, extend all
+  // paths in ambiguous buckets.
+  bool Changed = true;
+  while (Changed)
+    Changed = rebucketPaths(Paths);
 }
 
-/// CalculatePathToMangle - Calculate the subset of records that should be used
-/// to mangle the vftable for the given vfptr.
-/// Should only be called if a class has multiple vftables.
-static void
-CalculatePathToMangle(const CXXRecordDecl *RD, VFPtrInfo &VFPtr) {
-  // FIXME: In some rare cases this code produces a slightly incorrect mangling.
-  // It's very likely that the vbtable mangling code can be adjusted to mangle
-  // both vftables and vbtables correctly.
-
-  VFPtrInfo::BasePath &FullPath = VFPtr.PathToBaseWithVFPtr;
-  if (FullPath.empty()) {
-    // Mangle the class's own vftable.
-    assert(RD->getNumVBases() &&
-           "Something's wrong: if the most derived "
-           "class has more than one vftable, it can only have its own "
-           "vftable if it has vbases");
-    VFPtr.PathToMangle.push_back(RD);
-    return;
+static bool extendPath(VPtrInfo *P) {
+  if (P->NextBaseToMangle) {
+    P->MangledPath.push_back(P->NextBaseToMangle);
+    P->NextBaseToMangle = nullptr;// Prevent the path from being extended twice.
+    return true;
   }
-
-  unsigned Begin = 0;
-
-  // First, skip all the bases before the vbase.
-  if (VFPtr.LastVBase) {
-    while (FullPath[Begin] != VFPtr.LastVBase) {
-      Begin++;
-      assert(Begin < FullPath.size());
-    }
-  }
-
-  // Then, put the rest of the base path in the reverse order.
-  for (unsigned I = FullPath.size(); I != Begin; --I) {
-    const CXXRecordDecl *CurBase = FullPath[I - 1],
-                        *ItsBase = (I == 1) ? RD : FullPath[I - 2];
-    bool BaseIsVirtual = false;
-    for (CXXRecordDecl::base_class_const_iterator J = ItsBase->bases_begin(),
-         F = ItsBase->bases_end(); J != F; ++J) {
-      if (J->getType()->getAsCXXRecordDecl() == CurBase) {
-        BaseIsVirtual = J->isVirtual();
-        break;
-      }
-    }
-
-    // Should skip the current base if it is a non-virtual base with no siblings.
-    if (BaseIsVirtual || ItsBase->getNumBases() != 1)
-      VFPtr.PathToMangle.push_back(CurBase);
-  }
+  return false;
 }
 
-void MicrosoftVTableContext::enumerateVFPtrs(
-    const CXXRecordDecl *ForClass,
-    MicrosoftVTableContext::VFPtrListTy &Result) {
-  Result.clear();
-  const ASTRecordLayout &ClassLayout = Context.getASTRecordLayout(ForClass);
-  BasesSetVectorTy VisitedVBases;
-  enumerateVFPtrs(ForClass, ClassLayout,
-                  BaseSubobject(ForClass, CharUnits::Zero()), 0,
-                  VFPtrInfo::BasePath(), VisitedVBases, Result);
-  if (Result.size() > 1) {
-    for (unsigned I = 0, E = Result.size(); I != E; ++I)
-      CalculatePathToMangle(ForClass, Result[I]);
+static bool rebucketPaths(VPtrInfoVector &Paths) {
+  // What we're essentially doing here is bucketing together ambiguous paths.
+  // Any bucket with more than one path in it gets extended by NextBase, which
+  // is usually the direct base of the inherited the vbptr.  This code uses a
+  // sorted vector to implement a multiset to form the buckets.  Note that the
+  // ordering is based on pointers, but it doesn't change our output order.  The
+  // current algorithm is designed to match MSVC 2012's names.
+  VPtrInfoVector PathsSorted(Paths);
+  std::sort(PathsSorted.begin(), PathsSorted.end(),
+            [](const VPtrInfo *LHS, const VPtrInfo *RHS) {
+    return LHS->MangledPath < RHS->MangledPath;
+  });
+  bool Changed = false;
+  for (size_t I = 0, E = PathsSorted.size(); I != E;) {
+    // Scan forward to find the end of the bucket.
+    size_t BucketStart = I;
+    do {
+      ++I;
+    } while (I != E && PathsSorted[BucketStart]->MangledPath ==
+                           PathsSorted[I]->MangledPath);
+
+    // If this bucket has multiple paths, extend them all.
+    if (I - BucketStart > 1) {
+      for (size_t II = BucketStart; II != I; ++II)
+        Changed |= extendPath(PathsSorted[II]);
+      assert(Changed && "no paths were extended to fix ambiguity");
+    }
   }
+  return Changed;
+}
+
+MicrosoftVTableContext::~MicrosoftVTableContext() {
+  for (auto &P : VFPtrLocations) 
+    llvm::DeleteContainerPointers(*P.second);
+  llvm::DeleteContainerSeconds(VFPtrLocations);
+  llvm::DeleteContainerSeconds(VFTableLayouts);
+  llvm::DeleteContainerSeconds(VBaseInfo);
 }
 
 void MicrosoftVTableContext::computeVTableRelatedInformation(
@@ -3269,24 +3302,31 @@
 
   const VTableLayout::AddressPointsMapTy EmptyAddressPointsMap;
 
-  VFPtrListTy &VFPtrs = VFPtrLocations[RD];
-  enumerateVFPtrs(RD, VFPtrs);
+  VPtrInfoVector *VFPtrs = new VPtrInfoVector();
+  computeVTablePaths(/*ForVBTables=*/false, RD, *VFPtrs);
+  VFPtrLocations[RD] = VFPtrs;
 
   MethodVFTableLocationsTy NewMethodLocations;
-  for (VFPtrListTy::iterator I = VFPtrs.begin(), E = VFPtrs.end();
+  for (VPtrInfoVector::iterator I = VFPtrs->begin(), E = VFPtrs->end();
        I != E; ++I) {
     VFTableBuilder Builder(*this, RD, *I);
 
-    VFTableIdTy id(RD, I->VFPtrFullOffset);
+    VFTableIdTy id(RD, (*I)->FullOffsetInMDC);
     assert(VFTableLayouts.count(id) == 0);
     SmallVector<VTableLayout::VTableThunkTy, 1> VTableThunks(
         Builder.vtable_thunks_begin(), Builder.vtable_thunks_end());
     VFTableLayouts[id] = new VTableLayout(
         Builder.getNumVTableComponents(), Builder.vtable_component_begin(),
         VTableThunks.size(), VTableThunks.data(), EmptyAddressPointsMap, true);
-    NewMethodLocations.insert(Builder.vtable_indices_begin(),
-                              Builder.vtable_indices_end());
     Thunks.insert(Builder.thunks_begin(), Builder.thunks_end());
+
+    for (const auto &Loc : Builder.vtable_locations()) {
+      GlobalDecl GD = Loc.first;
+      MethodVFTableLocation NewLoc = Loc.second;
+      auto M = NewMethodLocations.find(GD);
+      if (M == NewMethodLocations.end() || NewLoc < M->second)
+        NewMethodLocations[GD] = NewLoc;
+    }
   }
 
   MethodVFTableLocations.insert(NewMethodLocations.begin(),
@@ -3324,8 +3364,10 @@
   // Print the vtable indices for all the member functions.
   if (!IndicesMap.empty()) {
     Out << "VFTable indices for ";
-    Out << "'" << RD->getQualifiedNameAsString();
-    Out << "' (" << IndicesMap.size() << " entries).\n";
+    Out << "'";
+    RD->printQualifiedName(Out);
+    Out << "' (" << IndicesMap.size()
+        << (IndicesMap.size() == 1 ? " entry" : " entries") << ").\n";
 
     CharUnits LastVFPtrOffset = CharUnits::fromQuantity(-1);
     uint64_t LastVBIndex = 0;
@@ -3352,49 +3394,66 @@
     }
     Out << '\n';
   }
+
+  Out.flush();
 }
 
-void MicrosoftVTableContext::computeVBTableRelatedInformation(
+const VirtualBaseInfo *MicrosoftVTableContext::computeVBTableRelatedInformation(
     const CXXRecordDecl *RD) {
-  if (ComputedVBTableIndices.count(RD))
-    return;
-  ComputedVBTableIndices.insert(RD);
+  VirtualBaseInfo *VBI;
 
-  const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
-  BasesSetVectorTy VisitedBases;
+  {
+    // Get or create a VBI for RD.  Don't hold a reference to the DenseMap cell,
+    // as it may be modified and rehashed under us.
+    VirtualBaseInfo *&Entry = VBaseInfo[RD];
+    if (Entry)
+      return Entry;
+    Entry = VBI = new VirtualBaseInfo();
+  }
+
+  computeVTablePaths(/*ForVBTables=*/true, RD, VBI->VBPtrPaths);
 
   // First, see if the Derived class shared the vbptr with a non-virtual base.
+  const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
   if (const CXXRecordDecl *VBPtrBase = Layout.getBaseSharingVBPtr()) {
-    // If the Derived class shares the vbptr with a non-virtual base,
-    // it inherits its vbase indices.
-    computeVBTableRelatedInformation(VBPtrBase);
-    for (CXXRecordDecl::base_class_const_iterator I = VBPtrBase->vbases_begin(),
-         E = VBPtrBase->vbases_end(); I != E; ++I) {
-      const CXXRecordDecl *SubVBase = I->getType()->getAsCXXRecordDecl();
-      assert(VBTableIndices.count(ClassPairTy(VBPtrBase, SubVBase)));
-      VBTableIndices[ClassPairTy(RD, SubVBase)] =
-          VBTableIndices[ClassPairTy(VBPtrBase, SubVBase)];
-      VisitedBases.insert(SubVBase);
-    }
+    // If the Derived class shares the vbptr with a non-virtual base, the shared
+    // virtual bases come first so that the layout is the same.
+    const VirtualBaseInfo *BaseInfo =
+        computeVBTableRelatedInformation(VBPtrBase);
+    VBI->VBTableIndices.insert(BaseInfo->VBTableIndices.begin(),
+                               BaseInfo->VBTableIndices.end());
   }
 
   // New vbases are added to the end of the vbtable.
   // Skip the self entry and vbases visited in the non-virtual base, if any.
-  unsigned VBTableIndex = 1 + VisitedBases.size();
-  for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(),
-       E = RD->vbases_end(); I != E; ++I) {
-    const CXXRecordDecl *CurVBase = I->getType()->getAsCXXRecordDecl();
-    if (VisitedBases.insert(CurVBase))
-      VBTableIndices[ClassPairTy(RD, CurVBase)] = VBTableIndex++;
+  unsigned VBTableIndex = 1 + VBI->VBTableIndices.size();
+  for (const auto &VB : RD->vbases()) {
+    const CXXRecordDecl *CurVBase = VB.getType()->getAsCXXRecordDecl();
+    if (!VBI->VBTableIndices.count(CurVBase))
+      VBI->VBTableIndices[CurVBase] = VBTableIndex++;
   }
+
+  return VBI;
 }
 
-const MicrosoftVTableContext::VFPtrListTy &
+unsigned MicrosoftVTableContext::getVBTableIndex(const CXXRecordDecl *Derived,
+                                                 const CXXRecordDecl *VBase) {
+  const VirtualBaseInfo *VBInfo = computeVBTableRelatedInformation(Derived);
+  assert(VBInfo->VBTableIndices.count(VBase));
+  return VBInfo->VBTableIndices.find(VBase)->second;
+}
+
+const VPtrInfoVector &
+MicrosoftVTableContext::enumerateVBTables(const CXXRecordDecl *RD) {
+  return computeVBTableRelatedInformation(RD)->VBPtrPaths;
+}
+
+const VPtrInfoVector &
 MicrosoftVTableContext::getVFPtrOffsets(const CXXRecordDecl *RD) {
   computeVTableRelatedInformation(RD);
 
   assert(VFPtrLocations.count(RD) && "Couldn't find vfptr locations");
-  return VFPtrLocations[RD];
+  return *VFPtrLocations[RD];
 }
 
 const VTableLayout &
diff --git a/lib/ASTMatchers/ASTMatchFinder.cpp b/lib/ASTMatchers/ASTMatchFinder.cpp
index f6dcb97..23708e2 100644
--- a/lib/ASTMatchers/ASTMatchFinder.cpp
+++ b/lib/ASTMatchers/ASTMatchFinder.cpp
@@ -58,11 +58,8 @@
   BoundNodesTreeBuilder BoundNodes;
 
   bool operator<(const MatchKey &Other) const {
-    if (MatcherID != Other.MatcherID)
-      return MatcherID < Other.MatcherID;
-    if (Node != Other.Node)
-      return Node < Other.Node;
-    return BoundNodes < Other.BoundNodes;
+    return std::tie(MatcherID, Node, BoundNodes) <
+           std::tie(Other.MatcherID, Other.Node, Other.BoundNodes);
   }
 };
 
@@ -140,7 +137,7 @@
   // of the public API of this class.
   bool TraverseDecl(Decl *DeclNode) {
     ScopedIncrement ScopedDepth(&CurrentDepth);
-    return (DeclNode == NULL) || traverse(*DeclNode);
+    return (DeclNode == nullptr) || traverse(*DeclNode);
   }
   bool TraverseStmt(Stmt *StmtNode) {
     ScopedIncrement ScopedDepth(&CurrentDepth);
@@ -148,11 +145,11 @@
     if (Traversal ==
         ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses) {
       const Expr *ExprNode = dyn_cast_or_null<Expr>(StmtNode);
-      if (ExprNode != NULL) {
+      if (ExprNode) {
         StmtToTraverse = ExprNode->IgnoreParenImpCasts();
       }
     }
-    return (StmtToTraverse == NULL) || traverse(*StmtToTraverse);
+    return (StmtToTraverse == nullptr) || traverse(*StmtToTraverse);
   }
   // We assume that the QualType and the contained type are on the same
   // hierarchy level. Thus, we try to match either of them.
@@ -183,7 +180,7 @@
   }
   bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS) {
     ScopedIncrement ScopedDepth(&CurrentDepth);
-    return (NNS == NULL) || traverse(*NNS);
+    return (NNS == nullptr) || traverse(*NNS);
   }
   bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
     if (!NNS)
@@ -272,8 +269,8 @@
   // traversal should continue after this function returns.
   template <typename T>
   bool traverse(const T &Node) {
-    TOOLING_COMPILE_ASSERT(IsBaseType<T>::value,
-                           traverse_can_only_be_instantiated_with_base_type);
+    static_assert(IsBaseType<T>::value,
+                  "traverse can only be instantiated with base type");
     if (!match(Node))
       return false;
     return baseTraverse(Node);
@@ -298,7 +295,7 @@
   MatchASTVisitor(
       std::vector<std::pair<internal::DynTypedMatcher, MatchCallback *> > *
           MatcherCallbackPairs)
-      : MatcherCallbackPairs(MatcherCallbackPairs), ActiveASTContext(NULL) {}
+      : MatcherCallbackPairs(MatcherCallbackPairs), ActiveASTContext(nullptr) {}
 
   void onStartOfTranslationUnit() {
     for (std::vector<std::pair<internal::DynTypedMatcher,
@@ -410,36 +407,36 @@
     return Visitor.findMatch(Node);
   }
 
-  virtual bool classIsDerivedFrom(const CXXRecordDecl *Declaration,
-                                  const Matcher<NamedDecl> &Base,
-                                  BoundNodesTreeBuilder *Builder);
+  bool classIsDerivedFrom(const CXXRecordDecl *Declaration,
+                          const Matcher<NamedDecl> &Base,
+                          BoundNodesTreeBuilder *Builder) override;
 
   // Implements ASTMatchFinder::matchesChildOf.
-  virtual bool matchesChildOf(const ast_type_traits::DynTypedNode &Node,
-                              const DynTypedMatcher &Matcher,
-                              BoundNodesTreeBuilder *Builder,
-                              TraversalKind Traversal,
-                              BindKind Bind) {
+  bool matchesChildOf(const ast_type_traits::DynTypedNode &Node,
+                      const DynTypedMatcher &Matcher,
+                      BoundNodesTreeBuilder *Builder,
+                      TraversalKind Traversal,
+                      BindKind Bind) override {
     if (ResultCache.size() > MaxMemoizationEntries)
       ResultCache.clear();
     return memoizedMatchesRecursively(Node, Matcher, Builder, 1, Traversal,
                                       Bind);
   }
   // Implements ASTMatchFinder::matchesDescendantOf.
-  virtual bool matchesDescendantOf(const ast_type_traits::DynTypedNode &Node,
-                                   const DynTypedMatcher &Matcher,
-                                   BoundNodesTreeBuilder *Builder,
-                                   BindKind Bind) {
+  bool matchesDescendantOf(const ast_type_traits::DynTypedNode &Node,
+                           const DynTypedMatcher &Matcher,
+                           BoundNodesTreeBuilder *Builder,
+                           BindKind Bind) override {
     if (ResultCache.size() > MaxMemoizationEntries)
       ResultCache.clear();
     return memoizedMatchesRecursively(Node, Matcher, Builder, INT_MAX,
                                       TK_AsIs, Bind);
   }
   // Implements ASTMatchFinder::matchesAncestorOf.
-  virtual bool matchesAncestorOf(const ast_type_traits::DynTypedNode &Node,
-                                 const DynTypedMatcher &Matcher,
-                                 BoundNodesTreeBuilder *Builder,
-                                 AncestorMatchMode MatchMode) {
+  bool matchesAncestorOf(const ast_type_traits::DynTypedNode &Node,
+                         const DynTypedMatcher &Matcher,
+                         BoundNodesTreeBuilder *Builder,
+                         AncestorMatchMode MatchMode) override {
     // Reset the cache outside of the recursive call to make sure we
     // don't invalidate any iterators.
     if (ResultCache.size() > MaxMemoizationEntries)
@@ -469,7 +466,7 @@
   }
 
   // Implements ASTMatchFinder::getASTContext.
-  virtual ASTContext &getASTContext() const { return *ActiveASTContext; }
+  ASTContext &getASTContext() const override { return *ActiveASTContext; }
 
   bool shouldVisitTemplateInstantiations() const { return true; }
   bool shouldVisitImplicitCode() const { return true; }
@@ -576,7 +573,7 @@
       : Context(Context),
         Callback(Callback) {}
 
-    virtual void visitMatch(const BoundNodes& BoundNodesView) {
+    void visitMatch(const BoundNodes& BoundNodesView) override {
       Callback->run(MatchFinder::MatchResult(BoundNodesView, Context));
     }
 
@@ -619,21 +616,21 @@
 
 static CXXRecordDecl *getAsCXXRecordDecl(const Type *TypeNode) {
   // Type::getAs<...>() drills through typedefs.
-  if (TypeNode->getAs<DependentNameType>() != NULL ||
-      TypeNode->getAs<DependentTemplateSpecializationType>() != NULL ||
-      TypeNode->getAs<TemplateTypeParmType>() != NULL)
+  if (TypeNode->getAs<DependentNameType>() != nullptr ||
+      TypeNode->getAs<DependentTemplateSpecializationType>() != nullptr ||
+      TypeNode->getAs<TemplateTypeParmType>() != nullptr)
     // Dependent names and template TypeNode parameters will be matched when
     // the template is instantiated.
-    return NULL;
+    return nullptr;
   TemplateSpecializationType const *TemplateType =
       TypeNode->getAs<TemplateSpecializationType>();
-  if (TemplateType == NULL) {
+  if (!TemplateType) {
     return TypeNode->getAsCXXRecordDecl();
   }
   if (TemplateType->getTemplateName().isDependent())
     // Dependent template specializations will be matched when the
     // template is instantiated.
-    return NULL;
+    return nullptr;
 
   // For template specialization types which are specializing a template
   // declaration which is an explicit or partial specialization of another
@@ -645,7 +642,7 @@
   // another template declaration, getAsCXXRecordDecl() returns NULL and
   // we get the CXXRecordDecl of the templated declaration.
   CXXRecordDecl *SpecializationDecl = TemplateType->getAsCXXRecordDecl();
-  if (SpecializationDecl != NULL) {
+  if (SpecializationDecl) {
     return SpecializationDecl;
   }
   NamedDecl *Templated =
@@ -667,17 +664,14 @@
                                          BoundNodesTreeBuilder *Builder) {
   if (!Declaration->hasDefinition())
     return false;
-  typedef CXXRecordDecl::base_class_const_iterator BaseIterator;
-  for (BaseIterator It = Declaration->bases_begin(),
-                    End = Declaration->bases_end();
-       It != End; ++It) {
-    const Type *TypeNode = It->getType().getTypePtr();
+  for (const auto &It : Declaration->bases()) {
+    const Type *TypeNode = It.getType().getTypePtr();
 
     if (typeHasMatchingAlias(TypeNode, Base, Builder))
       return true;
 
     CXXRecordDecl *ClassDecl = getAsCXXRecordDecl(TypeNode);
-    if (ClassDecl == NULL)
+    if (!ClassDecl)
       continue;
     if (ClassDecl == Declaration) {
       // This can happen for recursive template definitions; if the
@@ -696,7 +690,7 @@
 }
 
 bool MatchASTVisitor::TraverseDecl(Decl *DeclNode) {
-  if (DeclNode == NULL) {
+  if (!DeclNode) {
     return true;
   }
   match(*DeclNode);
@@ -704,7 +698,7 @@
 }
 
 bool MatchASTVisitor::TraverseStmt(Stmt *StmtNode) {
-  if (StmtNode == NULL) {
+  if (!StmtNode) {
     return true;
   }
   match(*StmtNode);
@@ -749,8 +743,8 @@
       : Finder(Finder), ParsingDone(ParsingDone) {}
 
 private:
-  virtual void HandleTranslationUnit(ASTContext &Context) {
-    if (ParsingDone != NULL) {
+  void HandleTranslationUnit(ASTContext &Context) override {
+    if (ParsingDone != nullptr) {
       ParsingDone->run();
     }
     Finder->matchAST(Context);
@@ -771,7 +765,7 @@
 MatchFinder::MatchCallback::~MatchCallback() {}
 MatchFinder::ParsingDoneTestCallback::~ParsingDoneTestCallback() {}
 
-MatchFinder::MatchFinder() : ParsingDone(NULL) {}
+MatchFinder::MatchFinder() : ParsingDone(nullptr) {}
 
 MatchFinder::~MatchFinder() {}
 
diff --git a/lib/ASTMatchers/ASTMatchersInternal.cpp b/lib/ASTMatchers/ASTMatchersInternal.cpp
index d15eb54..47b8b6d 100644
--- a/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ b/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -34,6 +34,26 @@
   }
 }
 
+bool NotUnaryOperator(const ast_type_traits::DynTypedNode DynNode,
+                      ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
+                      ArrayRef<DynTypedMatcher> InnerMatchers) {
+  if (InnerMatchers.size() != 1)
+    return false;
+
+  // The 'unless' matcher will always discard the result:
+  // If the inner matcher doesn't match, unless returns true,
+  // but the inner matcher cannot have bound anything.
+  // If the inner matcher matches, the result is false, and
+  // any possible binding will be discarded.
+  // We still need to hand in all the bound nodes up to this
+  // point so the inner matcher can depend on bound nodes,
+  // and we need to actively discard the bound nodes, otherwise
+  // the inner matcher will reset the bound nodes if it doesn't
+  // match, but this would be inversed by 'unless'.
+  BoundNodesTreeBuilder Discard(*Builder);
+  return !InnerMatchers[0].matches(DynNode, Finder, &Discard);
+}
+
 bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
                            ASTMatchFinder *Finder,
                            BoundNodesTreeBuilder *Builder,
diff --git a/lib/ASTMatchers/CMakeLists.txt b/lib/ASTMatchers/CMakeLists.txt
index 4a390a8..8a8e8c3 100644
--- a/lib/ASTMatchers/CMakeLists.txt
+++ b/lib/ASTMatchers/CMakeLists.txt
@@ -5,19 +5,7 @@
 add_clang_library(clangASTMatchers
   ASTMatchFinder.cpp
   ASTMatchersInternal.cpp
-  )
 
-add_dependencies(clangASTMatchers
-  ClangAttrClasses
-  ClangAttrImpl
-  ClangAttrList
-  ClangCommentNodes
-  ClangDeclNodes
-  ClangDiagnosticCommon
-  ClangStmtNodes
-  )
-
-target_link_libraries(clangASTMatchers
-  clangBasic
+  LINK_LIBS
   clangAST
   )
diff --git a/lib/ASTMatchers/Dynamic/CMakeLists.txt b/lib/ASTMatchers/Dynamic/CMakeLists.txt
index 843341b..c0d80ad 100644
--- a/lib/ASTMatchers/Dynamic/CMakeLists.txt
+++ b/lib/ASTMatchers/Dynamic/CMakeLists.txt
@@ -5,12 +5,9 @@
   VariantValue.cpp
   Parser.cpp
   Registry.cpp
-  )
 
-add_dependencies(clangDynamicASTMatchers
+  LINK_LIBS
+  clangAST
   clangASTMatchers
-  )
-
-target_link_libraries(clangDynamicASTMatchers
-  clangASTMatchers
+  clangBasic
   )
diff --git a/lib/ASTMatchers/Dynamic/Diagnostics.cpp b/lib/ASTMatchers/Dynamic/Diagnostics.cpp
index da2ed9a..b0abdc7 100644
--- a/lib/ASTMatchers/Dynamic/Diagnostics.cpp
+++ b/lib/ASTMatchers/Dynamic/Diagnostics.cpp
@@ -87,7 +87,7 @@
 
 StringRef errorTypeToFormatString(Diagnostics::ErrorType Type) {
   switch (Type) {
-  case Diagnostics::ET_RegistryNotFound:
+  case Diagnostics::ET_RegistryMatcherNotFound:
     return "Matcher not found: $0";
   case Diagnostics::ET_RegistryWrongArgCount:
     return "Incorrect argument count. (Expected = $0) != (Actual = $1)";
@@ -98,6 +98,8 @@
   case Diagnostics::ET_RegistryAmbiguousOverload:
     // TODO: Add type info about the overload error.
     return "Ambiguous matcher overload.";
+  case Diagnostics::ET_RegistryValueNotFound:
+    return "Value not found: $0";
 
   case Diagnostics::ET_ParserStringError:
     return "Error parsing string token: <$0>";
diff --git a/lib/ASTMatchers/Dynamic/Marshallers.h b/lib/ASTMatchers/Dynamic/Marshallers.h
index ae0c300..6e144cd 100644
--- a/lib/ASTMatchers/Dynamic/Marshallers.h
+++ b/lib/ASTMatchers/Dynamic/Marshallers.h
@@ -20,14 +20,12 @@
 #ifndef LLVM_CLANG_AST_MATCHERS_DYNAMIC_MARSHALLERS_H
 #define LLVM_CLANG_AST_MATCHERS_DYNAMIC_MARSHALLERS_H
 
-#include <string>
-
 #include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/ASTMatchers/Dynamic/Diagnostics.h"
 #include "clang/ASTMatchers/Dynamic/VariantValue.h"
 #include "clang/Basic/LLVM.h"
 #include "llvm/ADT/STLExtras.h"
-#include "llvm/Support/type_traits.h"
+#include <string>
 
 namespace clang {
 namespace ast_matchers {
@@ -35,6 +33,46 @@
 
 namespace internal {
 
+struct ArgKind {
+  enum Kind {
+    AK_Matcher,
+    AK_Unsigned,
+    AK_String
+  };
+  ArgKind(Kind K)
+      : K(K) {}
+  ArgKind(ast_type_traits::ASTNodeKind MatcherKind)
+      : K(AK_Matcher), MatcherKind(MatcherKind) {}
+
+  std::string asString() const {
+    switch (getArgKind()) {
+    case AK_Matcher:
+      return (Twine("Matcher<") + MatcherKind.asStringRef() + ">").str();
+    case AK_Unsigned:
+      return "unsigned";
+    case AK_String:
+      return "string";
+    }
+    llvm_unreachable("unhandled ArgKind");
+  }
+
+  Kind getArgKind() const { return K; }
+  ast_type_traits::ASTNodeKind getMatcherKind() const {
+    assert(K == AK_Matcher);
+    return MatcherKind;
+  }
+
+  bool operator<(const ArgKind &Other) const {
+    if (K == AK_Matcher && Other.K == AK_Matcher)
+      return MatcherKind < Other.MatcherKind;
+    return K < Other.K;
+  }
+
+private:
+  Kind K;
+  ast_type_traits::ASTNodeKind MatcherKind;
+};
+
 /// \brief Helper template class to just from argument type to the right is/get
 ///   functions in VariantValue.
 /// Used to verify and extract the matcher arguments below.
@@ -43,11 +81,13 @@
 };
 
 template <> struct ArgTypeTraits<std::string> {
-  static StringRef asString() { return "String"; }
   static bool is(const VariantValue &Value) { return Value.isString(); }
   static const std::string &get(const VariantValue &Value) {
     return Value.getString();
   }
+  static ArgKind getKind() {
+    return ArgKind(ArgKind::AK_String);
+  }
 };
 
 template <>
@@ -55,46 +95,95 @@
 };
 
 template <class T> struct ArgTypeTraits<ast_matchers::internal::Matcher<T> > {
-  static std::string asString() {
-    return (Twine("Matcher<") +
-            ast_type_traits::ASTNodeKind::getFromNodeKind<T>().asStringRef() +
-            ">").str();
-  }
   static bool is(const VariantValue &Value) {
     return Value.isMatcher() && Value.getMatcher().hasTypedMatcher<T>();
   }
   static ast_matchers::internal::Matcher<T> get(const VariantValue &Value) {
     return Value.getMatcher().getTypedMatcher<T>();
   }
+  static ArgKind getKind() {
+    return ArgKind(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
+  }
 };
 
 template <> struct ArgTypeTraits<unsigned> {
-  static std::string asString() { return "Unsigned"; }
   static bool is(const VariantValue &Value) { return Value.isUnsigned(); }
   static unsigned get(const VariantValue &Value) {
     return Value.getUnsigned();
   }
+  static ArgKind getKind() {
+    return ArgKind(ArgKind::AK_Unsigned);
+  }
 };
 
-/// \brief Generic MatcherCreate interface.
+/// \brief Matcher descriptor interface.
 ///
-/// Provides a \c run() method that constructs the matcher from the provided
-/// arguments.
-class MatcherCreateCallback {
+/// Provides a \c create() method that constructs the matcher from the provided
+/// arguments, and various other methods for type introspection.
+class MatcherDescriptor {
 public:
-  virtual ~MatcherCreateCallback() {}
-  virtual VariantMatcher run(const SourceRange &NameRange,
-                             ArrayRef<ParserValue> Args,
-                             Diagnostics *Error) const = 0;
+  virtual ~MatcherDescriptor() {}
+  virtual VariantMatcher create(const SourceRange &NameRange,
+                                ArrayRef<ParserValue> Args,
+                                Diagnostics *Error) const = 0;
+
+  /// Returns whether the matcher is variadic. Variadic matchers can take any
+  /// number of arguments, but they must be of the same type.
+  virtual bool isVariadic() const = 0;
+
+  /// Returns the number of arguments accepted by the matcher if not variadic.
+  virtual unsigned getNumArgs() const = 0;
+
+  /// Given that the matcher is being converted to type \p ThisKind, append the
+  /// set of argument types accepted for argument \p ArgNo to \p ArgKinds.
+  // FIXME: We should provide the ability to constrain the output of this
+  // function based on the types of other matcher arguments.
+  virtual void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
+                           std::vector<ArgKind> &ArgKinds) const = 0;
+
+  /// Returns whether this matcher is convertible to the given type.  If it is
+  /// so convertible, store in *Specificity a value corresponding to the
+  /// "specificity" of the converted matcher to the given context, and in
+  /// *LeastDerivedKind the least derived matcher kind which would result in the
+  /// same matcher overload.  Zero specificity indicates that this conversion
+  /// would produce a trivial matcher that will either always or never match.
+  /// Such matchers are excluded from code completion results.
+  virtual bool isConvertibleTo(
+      ast_type_traits::ASTNodeKind Kind, unsigned *Specificity = nullptr,
+      ast_type_traits::ASTNodeKind *LeastDerivedKind = nullptr) const = 0;
+
+  /// Returns whether the matcher will, given a matcher of any type T, yield a
+  /// matcher of type T.
+  virtual bool isPolymorphic() const { return false; }
 };
 
+inline bool isRetKindConvertibleTo(
+    ArrayRef<ast_type_traits::ASTNodeKind> RetKinds,
+    ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
+    ast_type_traits::ASTNodeKind *LeastDerivedKind) {
+  for (ArrayRef<ast_type_traits::ASTNodeKind>::const_iterator
+           i = RetKinds.begin(),
+           e = RetKinds.end();
+       i != e; ++i) {
+    unsigned Distance;
+    if (i->isBaseOf(Kind, &Distance)) {
+      if (Specificity)
+        *Specificity = 100 - Distance;
+      if (LeastDerivedKind)
+        *LeastDerivedKind = *i;
+      return true;
+    }
+  }
+  return false;
+}
+
 /// \brief Simple callback implementation. Marshaller and function are provided.
 ///
 /// This class wraps a function of arbitrary signature and a marshaller
-/// function into a MatcherCreateCallback.
+/// function into a MatcherDescriptor.
 /// The marshaller is in charge of taking the VariantValue arguments, checking
 /// their types, unpacking them and calling the underlying function.
-class FixedArgCountMatcherCreateCallback : public MatcherCreateCallback {
+class FixedArgCountMatcherDescriptor : public MatcherDescriptor {
 public:
   typedef VariantMatcher (*MarshallerType)(void (*Func)(),
                                            StringRef MatcherName,
@@ -105,64 +194,42 @@
   /// \param Marshaller Function to unpack the arguments and call \c Func
   /// \param Func Matcher construct function. This is the function that
   ///   compile-time matcher expressions would use to create the matcher.
-  FixedArgCountMatcherCreateCallback(MarshallerType Marshaller, void (*Func)(),
-                                     StringRef MatcherName)
-      : Marshaller(Marshaller), Func(Func), MatcherName(MatcherName) {}
+  /// \param RetKinds The list of matcher types to which the matcher is
+  ///   convertible.
+  /// \param ArgKinds The types of the arguments this matcher takes.
+  FixedArgCountMatcherDescriptor(
+      MarshallerType Marshaller, void (*Func)(), StringRef MatcherName,
+      ArrayRef<ast_type_traits::ASTNodeKind> RetKinds,
+      ArrayRef<ArgKind> ArgKinds)
+      : Marshaller(Marshaller), Func(Func), MatcherName(MatcherName),
+        RetKinds(RetKinds.begin(), RetKinds.end()),
+        ArgKinds(ArgKinds.begin(), ArgKinds.end()) {}
 
-  VariantMatcher run(const SourceRange &NameRange, ArrayRef<ParserValue> Args,
-                     Diagnostics *Error) const {
+  VariantMatcher create(const SourceRange &NameRange,
+                        ArrayRef<ParserValue> Args, Diagnostics *Error) const {
     return Marshaller(Func, MatcherName, NameRange, Args, Error);
   }
 
+  bool isVariadic() const { return false; }
+  unsigned getNumArgs() const { return ArgKinds.size(); }
+  void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
+                   std::vector<ArgKind> &Kinds) const {
+    Kinds.push_back(ArgKinds[ArgNo]);
+  }
+  bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
+                       ast_type_traits::ASTNodeKind *LeastDerivedKind) const {
+    return isRetKindConvertibleTo(RetKinds, Kind, Specificity,
+                                  LeastDerivedKind);
+  }
+
 private:
   const MarshallerType Marshaller;
   void (* const Func)();
   const std::string MatcherName;
+  const std::vector<ast_type_traits::ASTNodeKind> RetKinds;
+  const std::vector<ArgKind> ArgKinds;
 };
 
-/// \brief Simple callback implementation. Free function is wrapped.
-///
-/// This class simply wraps a free function with the right signature to export
-/// it as a MatcherCreateCallback.
-/// This allows us to have one implementation of the interface for as many free
-/// functions as we want, reducing the number of symbols and size of the
-/// object file.
-class FreeFuncMatcherCreateCallback : public MatcherCreateCallback {
-public:
-  typedef VariantMatcher (*RunFunc)(StringRef MatcherName,
-                                    const SourceRange &NameRange,
-                                    ArrayRef<ParserValue> Args,
-                                    Diagnostics *Error);
-
-  FreeFuncMatcherCreateCallback(RunFunc Func, StringRef MatcherName)
-      : Func(Func), MatcherName(MatcherName.str()) {}
-
-  VariantMatcher run(const SourceRange &NameRange, ArrayRef<ParserValue> Args,
-                     Diagnostics *Error) const {
-    return Func(MatcherName, NameRange, Args, Error);
-  }
-
-private:
-  const RunFunc Func;
-  const std::string MatcherName;
-};
-
-/// \brief Helper macros to check the arguments on all marshaller functions.
-#define CHECK_ARG_COUNT(count)                                                 \
-  if (Args.size() != count) {                                                  \
-    Error->addError(NameRange, Error->ET_RegistryWrongArgCount)                \
-        << count << Args.size();                                               \
-    return VariantMatcher();                                                   \
-  }
-
-#define CHECK_ARG_TYPE(index, type)                                            \
-  if (!ArgTypeTraits<type>::is(Args[index].Value)) {                           \
-    Error->addError(Args[index].Range, Error->ET_RegistryWrongArgType)         \
-        << (index + 1) << ArgTypeTraits<type>::asString()                      \
-        << Args[index].Value.getTypeAsString();                                \
-    return VariantMatcher();                                                   \
-  }
-
 /// \brief Helper methods to extract and merge all possible typed matchers
 /// out of the polymorphic object.
 template <class PolyMatcher>
@@ -193,10 +260,178 @@
                                                    NULL) {
   std::vector<DynTypedMatcher> Matchers;
   mergePolyMatchers(PolyMatcher, Matchers, typename T::ReturnTypes());
-  VariantMatcher Out = VariantMatcher::PolymorphicMatcher(Matchers);
+  VariantMatcher Out = VariantMatcher::PolymorphicMatcher(std::move(Matchers));
   return Out;
 }
 
+template <typename T>
+inline void buildReturnTypeVectorFromTypeList(
+    std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
+  RetTypes.push_back(
+      ast_type_traits::ASTNodeKind::getFromNodeKind<typename T::head>());
+  buildReturnTypeVectorFromTypeList<typename T::tail>(RetTypes);
+}
+
+template <>
+inline void
+buildReturnTypeVectorFromTypeList<ast_matchers::internal::EmptyTypeList>(
+    std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {}
+
+template <typename T>
+struct BuildReturnTypeVector {
+  static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
+    buildReturnTypeVectorFromTypeList<typename T::ReturnTypes>(RetTypes);
+  }
+};
+
+template <typename T>
+struct BuildReturnTypeVector<ast_matchers::internal::Matcher<T> > {
+  static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
+    RetTypes.push_back(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
+  }
+};
+
+template <typename T>
+struct BuildReturnTypeVector<ast_matchers::internal::BindableMatcher<T> > {
+  static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
+    RetTypes.push_back(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
+  }
+};
+
+/// \brief Variadic marshaller function.
+template <typename ResultT, typename ArgT,
+          ResultT (*Func)(ArrayRef<const ArgT *>)>
+VariantMatcher
+variadicMatcherDescriptor(StringRef MatcherName, const SourceRange &NameRange,
+                          ArrayRef<ParserValue> Args, Diagnostics *Error) {
+  ArgT **InnerArgs = new ArgT *[Args.size()]();
+
+  bool HasError = false;
+  for (size_t i = 0, e = Args.size(); i != e; ++i) {
+    typedef ArgTypeTraits<ArgT> ArgTraits;
+    const ParserValue &Arg = Args[i];
+    const VariantValue &Value = Arg.Value;
+    if (!ArgTraits::is(Value)) {
+      Error->addError(Arg.Range, Error->ET_RegistryWrongArgType)
+          << (i + 1) << ArgTraits::getKind().asString() << Value.getTypeAsString();
+      HasError = true;
+      break;
+    }
+    InnerArgs[i] = new ArgT(ArgTraits::get(Value));
+  }
+
+  VariantMatcher Out;
+  if (!HasError) {
+    Out = outvalueToVariantMatcher(
+        Func(ArrayRef<const ArgT *>(InnerArgs, Args.size())));
+  }
+
+  for (size_t i = 0, e = Args.size(); i != e; ++i) {
+    delete InnerArgs[i];
+  }
+  delete[] InnerArgs;
+  return Out;
+}
+
+/// \brief Matcher descriptor for variadic functions.
+///
+/// This class simply wraps a VariadicFunction with the right signature to export
+/// it as a MatcherDescriptor.
+/// This allows us to have one implementation of the interface for as many free
+/// functions as we want, reducing the number of symbols and size of the
+/// object file.
+class VariadicFuncMatcherDescriptor : public MatcherDescriptor {
+public:
+  typedef VariantMatcher (*RunFunc)(StringRef MatcherName,
+                                    const SourceRange &NameRange,
+                                    ArrayRef<ParserValue> Args,
+                                    Diagnostics *Error);
+
+  template <typename ResultT, typename ArgT,
+            ResultT (*F)(ArrayRef<const ArgT *>)>
+  VariadicFuncMatcherDescriptor(llvm::VariadicFunction<ResultT, ArgT, F> Func,
+                          StringRef MatcherName)
+      : Func(&variadicMatcherDescriptor<ResultT, ArgT, F>),
+        MatcherName(MatcherName.str()),
+        ArgsKind(ArgTypeTraits<ArgT>::getKind()) {
+    BuildReturnTypeVector<ResultT>::build(RetKinds);
+  }
+
+  VariantMatcher create(const SourceRange &NameRange,
+                        ArrayRef<ParserValue> Args, Diagnostics *Error) const {
+    return Func(MatcherName, NameRange, Args, Error);
+  }
+
+  bool isVariadic() const { return true; }
+  unsigned getNumArgs() const { return 0; }
+  void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
+                   std::vector<ArgKind> &Kinds) const {
+    Kinds.push_back(ArgsKind);
+  }
+  bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
+                       ast_type_traits::ASTNodeKind *LeastDerivedKind) const {
+    return isRetKindConvertibleTo(RetKinds, Kind, Specificity,
+                                  LeastDerivedKind);
+  }
+
+private:
+  const RunFunc Func;
+  const std::string MatcherName;
+  std::vector<ast_type_traits::ASTNodeKind> RetKinds;
+  const ArgKind ArgsKind;
+};
+
+/// \brief Return CK_Trivial when appropriate for VariadicDynCastAllOfMatchers.
+class DynCastAllOfMatcherDescriptor : public VariadicFuncMatcherDescriptor {
+public:
+  template <typename BaseT, typename DerivedT>
+  DynCastAllOfMatcherDescriptor(
+      ast_matchers::internal::VariadicDynCastAllOfMatcher<BaseT, DerivedT> Func,
+      StringRef MatcherName)
+      : VariadicFuncMatcherDescriptor(Func, MatcherName),
+        DerivedKind(ast_type_traits::ASTNodeKind::getFromNodeKind<DerivedT>()) {
+  }
+
+  bool
+  isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
+                ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
+    // If Kind is not a base of DerivedKind, either DerivedKind is a base of
+    // Kind (in which case the match will always succeed) or Kind and
+    // DerivedKind are unrelated (in which case it will always fail), so set
+    // Specificity to 0.
+    if (VariadicFuncMatcherDescriptor::isConvertibleTo(Kind, Specificity,
+                                                 LeastDerivedKind)) {
+      if (Kind.isSame(DerivedKind) || !Kind.isBaseOf(DerivedKind)) {
+        if (Specificity)
+          *Specificity = 0;
+      }
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+private:
+  const ast_type_traits::ASTNodeKind DerivedKind;
+};
+
+/// \brief Helper macros to check the arguments on all marshaller functions.
+#define CHECK_ARG_COUNT(count)                                                 \
+  if (Args.size() != count) {                                                  \
+    Error->addError(NameRange, Error->ET_RegistryWrongArgCount)                \
+        << count << Args.size();                                               \
+    return VariantMatcher();                                                   \
+  }
+
+#define CHECK_ARG_TYPE(index, type)                                            \
+  if (!ArgTypeTraits<type>::is(Args[index].Value)) {                           \
+    Error->addError(Args[index].Range, Error->ET_RegistryWrongArgType)         \
+        << (index + 1) << ArgTypeTraits<type>::getKind().asString()            \
+        << Args[index].Value.getTypeAsString();                                \
+    return VariantMatcher();                                                   \
+  }
+
+
 /// \brief 0-arg marshaller function.
 template <typename ReturnType>
 static VariantMatcher matcherMarshall0(void (*Func)(), StringRef MatcherName,
@@ -239,42 +474,6 @@
 #undef CHECK_ARG_COUNT
 #undef CHECK_ARG_TYPE
 
-/// \brief Variadic marshaller function.
-template <typename ResultT, typename ArgT,
-          ResultT (*Func)(ArrayRef<const ArgT *>)>
-VariantMatcher
-variadicMatcherCreateCallback(StringRef MatcherName,
-                              const SourceRange &NameRange,
-                              ArrayRef<ParserValue> Args, Diagnostics *Error) {
-  ArgT **InnerArgs = new ArgT *[Args.size()]();
-
-  bool HasError = false;
-  for (size_t i = 0, e = Args.size(); i != e; ++i) {
-    typedef ArgTypeTraits<ArgT> ArgTraits;
-    const ParserValue &Arg = Args[i];
-    const VariantValue &Value = Arg.Value;
-    if (!ArgTraits::is(Value)) {
-      Error->addError(Arg.Range, Error->ET_RegistryWrongArgType)
-          << (i + 1) << ArgTraits::asString() << Value.getTypeAsString();
-      HasError = true;
-      break;
-    }
-    InnerArgs[i] = new ArgT(ArgTraits::get(Value));
-  }
-
-  VariantMatcher Out;
-  if (!HasError) {
-    Out = outvalueToVariantMatcher(
-        Func(ArrayRef<const ArgT *>(InnerArgs, Args.size())));
-  }
-
-  for (size_t i = 0, e = Args.size(); i != e; ++i) {
-    delete InnerArgs[i];
-  }
-  delete[] InnerArgs;
-  return Out;
-}
-
 /// \brief Helper class used to collect all the possible overloads of an
 ///   argument adaptative matcher function.
 template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
@@ -282,7 +481,7 @@
 class AdaptativeOverloadCollector {
 public:
   AdaptativeOverloadCollector(StringRef Name,
-                              std::vector<MatcherCreateCallback *> &Out)
+                              std::vector<MatcherDescriptor *> &Out)
       : Name(Name), Out(Out) {
     collect(FromTypes());
   }
@@ -296,33 +495,32 @@
 
   /// \brief Recursive case. Get the overload for the head of the list, and
   ///   recurse to the tail.
-  template <typename FromTypeList> inline void collect(FromTypeList);
+  template <typename FromTypeList>
+  inline void collect(FromTypeList);
 
   const StringRef Name;
-  std::vector<MatcherCreateCallback *> &Out;
+  std::vector<MatcherDescriptor *> &Out;
 };
 
-/// \brief MatcherCreateCallback that wraps multiple "overloads" of the same
+/// \brief MatcherDescriptor that wraps multiple "overloads" of the same
 ///   matcher.
 ///
 /// It will try every overload and generate appropriate errors for when none or
 /// more than one overloads match the arguments.
-class OverloadedMatcherCreateCallback : public MatcherCreateCallback {
+class OverloadedMatcherDescriptor : public MatcherDescriptor {
 public:
-  OverloadedMatcherCreateCallback(ArrayRef<MatcherCreateCallback *> Callbacks)
-      : Overloads(Callbacks) {}
+  OverloadedMatcherDescriptor(ArrayRef<MatcherDescriptor *> Callbacks)
+      : Overloads(Callbacks.begin(), Callbacks.end()) {}
 
-  virtual ~OverloadedMatcherCreateCallback() {
-    llvm::DeleteContainerPointers(Overloads);
-  }
+  virtual ~OverloadedMatcherDescriptor() {}
 
-  virtual VariantMatcher run(const SourceRange &NameRange,
-                             ArrayRef<ParserValue> Args,
-                             Diagnostics *Error) const {
+  virtual VariantMatcher create(const SourceRange &NameRange,
+                                ArrayRef<ParserValue> Args,
+                                Diagnostics *Error) const {
     std::vector<VariantMatcher> Constructed;
     Diagnostics::OverloadContext Ctx(Error);
-    for (size_t i = 0, e = Overloads.size(); i != e; ++i) {
-      VariantMatcher SubMatcher = Overloads[i]->run(NameRange, Args, Error);
+    for (const auto &O : Overloads) {
+      VariantMatcher SubMatcher = O->create(NameRange, Args, Error);
       if (!SubMatcher.isNull()) {
         Constructed.push_back(SubMatcher);
       }
@@ -339,20 +537,67 @@
     return Constructed[0];
   }
 
+  bool isVariadic() const {
+    bool Overload0Variadic = Overloads[0]->isVariadic();
+#ifndef NDEBUG
+    for (const auto &O : Overloads) {
+      assert(Overload0Variadic == O->isVariadic());
+    }
+#endif
+    return Overload0Variadic;
+  }
+
+  unsigned getNumArgs() const {
+    unsigned Overload0NumArgs = Overloads[0]->getNumArgs();
+#ifndef NDEBUG
+    for (const auto &O : Overloads) {
+      assert(Overload0NumArgs == O->getNumArgs());
+    }
+#endif
+    return Overload0NumArgs;
+  }
+
+  void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
+                   std::vector<ArgKind> &Kinds) const {
+    for (const auto &O : Overloads) {
+      if (O->isConvertibleTo(ThisKind))
+        O->getArgKinds(ThisKind, ArgNo, Kinds);
+    }
+  }
+
+  bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
+                       ast_type_traits::ASTNodeKind *LeastDerivedKind) const {
+    for (const auto &O : Overloads) {
+      if (O->isConvertibleTo(Kind, Specificity, LeastDerivedKind))
+        return true;
+    }
+    return false;
+  }
+
 private:
-  std::vector<MatcherCreateCallback *> Overloads;
+  std::vector<std::unique_ptr<MatcherDescriptor>> Overloads;
 };
 
 /// \brief Variadic operator marshaller function.
-class VariadicOperatorMatcherCreateCallback : public MatcherCreateCallback {
+class VariadicOperatorMatcherDescriptor : public MatcherDescriptor {
 public:
   typedef ast_matchers::internal::VariadicOperatorFunction VarFunc;
-  VariadicOperatorMatcherCreateCallback(VarFunc Func, StringRef MatcherName)
-      : Func(Func), MatcherName(MatcherName) {}
+  VariadicOperatorMatcherDescriptor(unsigned MinCount, unsigned MaxCount,
+                                    VarFunc Func, StringRef MatcherName)
+      : MinCount(MinCount), MaxCount(MaxCount), Func(Func),
+        MatcherName(MatcherName) {}
 
-  virtual VariantMatcher run(const SourceRange &NameRange,
-                             ArrayRef<ParserValue> Args,
-                             Diagnostics *Error) const {
+  virtual VariantMatcher create(const SourceRange &NameRange,
+                                ArrayRef<ParserValue> Args,
+                                Diagnostics *Error) const {
+    if (Args.size() < MinCount || MaxCount < Args.size()) {
+      const std::string MaxStr =
+          (MaxCount == UINT_MAX ? "" : Twine(MaxCount)).str();
+      Error->addError(NameRange, Error->ET_RegistryWrongArgCount)
+          << ("(" + Twine(MinCount) + ", " + MaxStr + ")") << Args.size();
+      return VariantMatcher();
+    }
+
     std::vector<VariantMatcher> InnerArgs;
     for (size_t i = 0, e = Args.size(); i != e; ++i) {
       const ParserValue &Arg = Args[i];
@@ -364,85 +609,123 @@
       }
       InnerArgs.push_back(Value.getMatcher());
     }
-    return VariantMatcher::VariadicOperatorMatcher(Func, InnerArgs);
+    return VariantMatcher::VariadicOperatorMatcher(Func, std::move(InnerArgs));
   }
 
+  bool isVariadic() const { return true; }
+  unsigned getNumArgs() const { return 0; }
+  void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
+                   std::vector<ArgKind> &Kinds) const {
+    Kinds.push_back(ThisKind);
+  }
+  bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
+                       ast_type_traits::ASTNodeKind *LeastDerivedKind) const {
+    if (Specificity)
+      *Specificity = 1;
+    if (LeastDerivedKind)
+      *LeastDerivedKind = Kind;
+    return true;
+  }
+  bool isPolymorphic() const override { return true; }
+
 private:
+  const unsigned MinCount;
+  const unsigned MaxCount;
   const VarFunc Func;
   const StringRef MatcherName;
 };
 
-
 /// Helper functions to select the appropriate marshaller functions.
 /// They detect the number of arguments, arguments types and return type.
 
 /// \brief 0-arg overload
 template <typename ReturnType>
-MatcherCreateCallback *makeMatcherAutoMarshall(ReturnType (*Func)(),
-                                               StringRef MatcherName) {
-  return new FixedArgCountMatcherCreateCallback(
+MatcherDescriptor *makeMatcherAutoMarshall(ReturnType (*Func)(),
+                                     StringRef MatcherName) {
+  std::vector<ast_type_traits::ASTNodeKind> RetTypes;
+  BuildReturnTypeVector<ReturnType>::build(RetTypes);
+  return new FixedArgCountMatcherDescriptor(
       matcherMarshall0<ReturnType>, reinterpret_cast<void (*)()>(Func),
-      MatcherName);
+      MatcherName, RetTypes, None);
 }
 
 /// \brief 1-arg overload
 template <typename ReturnType, typename ArgType1>
-MatcherCreateCallback *makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1),
-                                               StringRef MatcherName) {
-  return new FixedArgCountMatcherCreateCallback(
+MatcherDescriptor *makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1),
+                                     StringRef MatcherName) {
+  std::vector<ast_type_traits::ASTNodeKind> RetTypes;
+  BuildReturnTypeVector<ReturnType>::build(RetTypes);
+  ArgKind AK = ArgTypeTraits<ArgType1>::getKind();
+  return new FixedArgCountMatcherDescriptor(
       matcherMarshall1<ReturnType, ArgType1>,
-      reinterpret_cast<void (*)()>(Func), MatcherName);
+      reinterpret_cast<void (*)()>(Func), MatcherName, RetTypes, AK);
 }
 
 /// \brief 2-arg overload
 template <typename ReturnType, typename ArgType1, typename ArgType2>
-MatcherCreateCallback *makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1,
-                                                                  ArgType2),
-                                               StringRef MatcherName) {
-  return new FixedArgCountMatcherCreateCallback(
+MatcherDescriptor *makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1, ArgType2),
+                                     StringRef MatcherName) {
+  std::vector<ast_type_traits::ASTNodeKind> RetTypes;
+  BuildReturnTypeVector<ReturnType>::build(RetTypes);
+  ArgKind AKs[] = { ArgTypeTraits<ArgType1>::getKind(),
+                    ArgTypeTraits<ArgType2>::getKind() };
+  return new FixedArgCountMatcherDescriptor(
       matcherMarshall2<ReturnType, ArgType1, ArgType2>,
-      reinterpret_cast<void (*)()>(Func), MatcherName);
+      reinterpret_cast<void (*)()>(Func), MatcherName, RetTypes, AKs);
 }
 
 /// \brief Variadic overload.
 template <typename ResultT, typename ArgT,
           ResultT (*Func)(ArrayRef<const ArgT *>)>
-MatcherCreateCallback *
+MatcherDescriptor *
 makeMatcherAutoMarshall(llvm::VariadicFunction<ResultT, ArgT, Func> VarFunc,
                         StringRef MatcherName) {
-  return new FreeFuncMatcherCreateCallback(
-      &variadicMatcherCreateCallback<ResultT, ArgT, Func>, MatcherName);
+  return new VariadicFuncMatcherDescriptor(VarFunc, MatcherName);
+}
+
+/// \brief Overload for VariadicDynCastAllOfMatchers.
+///
+/// Not strictly necessary, but DynCastAllOfMatcherDescriptor gives us better
+/// completion results for that type of matcher.
+template <typename BaseT, typename DerivedT>
+MatcherDescriptor *
+makeMatcherAutoMarshall(ast_matchers::internal::VariadicDynCastAllOfMatcher<
+                            BaseT, DerivedT> VarFunc,
+                        StringRef MatcherName) {
+  return new DynCastAllOfMatcherDescriptor(VarFunc, MatcherName);
 }
 
 /// \brief Argument adaptative overload.
 template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
           typename FromTypes, typename ToTypes>
-MatcherCreateCallback *
+MatcherDescriptor *
 makeMatcherAutoMarshall(ast_matchers::internal::ArgumentAdaptingMatcherFunc<
                             ArgumentAdapterT, FromTypes, ToTypes>,
                         StringRef MatcherName) {
-  std::vector<MatcherCreateCallback *> Overloads;
+  std::vector<MatcherDescriptor *> Overloads;
   AdaptativeOverloadCollector<ArgumentAdapterT, FromTypes, ToTypes>(MatcherName,
                                                                     Overloads);
-  return new OverloadedMatcherCreateCallback(Overloads);
+  return new OverloadedMatcherDescriptor(Overloads);
 }
 
 template <template <typename ToArg, typename FromArg> class ArgumentAdapterT,
           typename FromTypes, typename ToTypes>
 template <typename FromTypeList>
-inline void
-AdaptativeOverloadCollector<ArgumentAdapterT, FromTypes, ToTypes>::collect(
-    FromTypeList) {
+inline void AdaptativeOverloadCollector<ArgumentAdapterT, FromTypes,
+                                        ToTypes>::collect(FromTypeList) {
   Out.push_back(makeMatcherAutoMarshall(
       &AdaptativeFunc::template create<typename FromTypeList::head>, Name));
   collect(typename FromTypeList::tail());
 }
 
 /// \brief Variadic operator overload.
-MatcherCreateCallback *makeMatcherAutoMarshall(
-    ast_matchers::internal::VariadicOperatorMatcherFunc Func,
-    StringRef MatcherName) {
-  return new VariadicOperatorMatcherCreateCallback(Func.Func, MatcherName);
+template <unsigned MinCount, unsigned MaxCount>
+MatcherDescriptor *
+makeMatcherAutoMarshall(ast_matchers::internal::VariadicOperatorMatcherFunc<
+                            MinCount, MaxCount> Func,
+                        StringRef MatcherName) {
+  return new VariadicOperatorMatcherDescriptor(MinCount, MaxCount, Func.Func,
+                                               MatcherName);
 }
 
 }  // namespace internal
diff --git a/lib/ASTMatchers/Dynamic/Parser.cpp b/lib/ASTMatchers/Dynamic/Parser.cpp
index df9596e..25629d9 100644
--- a/lib/ASTMatchers/Dynamic/Parser.cpp
+++ b/lib/ASTMatchers/Dynamic/Parser.cpp
@@ -12,13 +12,13 @@
 ///
 //===----------------------------------------------------------------------===//
 
-#include <string>
-#include <vector>
-
 #include "clang/ASTMatchers/Dynamic/Parser.h"
 #include "clang/ASTMatchers/Dynamic/Registry.h"
 #include "clang/Basic/CharInfo.h"
+#include "llvm/ADT/Optional.h"
 #include "llvm/ADT/Twine.h"
+#include <string>
+#include <vector>
 
 namespace clang {
 namespace ast_matchers {
@@ -28,15 +28,16 @@
 struct Parser::TokenInfo {
   /// \brief Different possible tokens.
   enum TokenKind {
-    TK_Eof = 0,
-    TK_OpenParen = 1,
-    TK_CloseParen = 2,
-    TK_Comma = 3,
-    TK_Period = 4,
-    TK_Literal = 5,
-    TK_Ident = 6,
-    TK_InvalidChar = 7,
-    TK_Error = 8
+    TK_Eof,
+    TK_OpenParen,
+    TK_CloseParen,
+    TK_Comma,
+    TK_Period,
+    TK_Literal,
+    TK_Ident,
+    TK_InvalidChar,
+    TK_Error,
+    TK_CodeCompletion
   };
 
   /// \brief Some known identifiers.
@@ -56,7 +57,15 @@
 class Parser::CodeTokenizer {
 public:
   explicit CodeTokenizer(StringRef MatcherCode, Diagnostics *Error)
-      : Code(MatcherCode), StartOfLine(MatcherCode), Line(1), Error(Error) {
+      : Code(MatcherCode), StartOfLine(MatcherCode), Line(1), Error(Error),
+        CodeCompletionLocation(nullptr) {
+    NextToken = getNextToken();
+  }
+
+  CodeTokenizer(StringRef MatcherCode, Diagnostics *Error,
+                unsigned CodeCompletionOffset)
+      : Code(MatcherCode), StartOfLine(MatcherCode), Line(1), Error(Error),
+        CodeCompletionLocation(MatcherCode.data() + CodeCompletionOffset) {
     NextToken = getNextToken();
   }
 
@@ -78,6 +87,13 @@
     TokenInfo Result;
     Result.Range.Start = currentLocation();
 
+    if (CodeCompletionLocation && CodeCompletionLocation <= Code.data()) {
+      Result.Kind = TokenInfo::TK_CodeCompletion;
+      Result.Text = StringRef(CodeCompletionLocation, 0);
+      CodeCompletionLocation = nullptr;
+      return Result;
+    }
+
     if (Code.empty()) {
       Result.Kind = TokenInfo::TK_Eof;
       Result.Text = "";
@@ -122,8 +138,21 @@
       if (isAlphanumeric(Code[0])) {
         // Parse an identifier
         size_t TokenLength = 1;
-        while (TokenLength < Code.size() && isAlphanumeric(Code[TokenLength]))
+        while (1) {
+          // A code completion location in/immediately after an identifier will
+          // cause the portion of the identifier before the code completion
+          // location to become a code completion token.
+          if (CodeCompletionLocation == Code.data() + TokenLength) {
+            CodeCompletionLocation = nullptr;
+            Result.Kind = TokenInfo::TK_CodeCompletion;
+            Result.Text = Code.substr(0, TokenLength);
+            Code = Code.drop_front(TokenLength);
+            return Result;
+          }
+          if (TokenLength == Code.size() || !isAlphanumeric(Code[TokenLength]))
+            break;
           ++TokenLength;
+        }
         Result.Kind = TokenInfo::TK_Ident;
         Result.Text = Code.substr(0, TokenLength);
         Code = Code.drop_front(TokenLength);
@@ -224,16 +253,68 @@
   unsigned Line;
   Diagnostics *Error;
   TokenInfo NextToken;
+  const char *CodeCompletionLocation;
 };
 
 Parser::Sema::~Sema() {}
 
+VariantValue Parser::Sema::getNamedValue(StringRef Name) {
+  return VariantValue();
+}
+
+struct Parser::ScopedContextEntry {
+  Parser *P;
+
+  ScopedContextEntry(Parser *P, MatcherCtor C) : P(P) {
+    P->ContextStack.push_back(std::make_pair(C, 0u));
+  }
+
+  ~ScopedContextEntry() {
+    P->ContextStack.pop_back();
+  }
+
+  void nextArg() {
+    ++P->ContextStack.back().second;
+  }
+};
+
+/// \brief Parse expressions that start with an identifier.
+///
+/// This function can parse named values and matchers.
+/// In case of failure it will try to determine the user's intent to give
+/// an appropriate error message.
+bool Parser::parseIdentifierPrefixImpl(VariantValue *Value) {
+  const TokenInfo NameToken = Tokenizer->consumeNextToken();
+
+  if (Tokenizer->nextTokenKind() != TokenInfo::TK_OpenParen) {
+    // Parse as a named value.
+    if (const VariantValue NamedValue = S->getNamedValue(NameToken.Text)) {
+      *Value = NamedValue;
+      return true;
+    }
+    // If the syntax is correct and the name is not a matcher either, report
+    // unknown named value.
+    if ((Tokenizer->nextTokenKind() == TokenInfo::TK_Comma ||
+         Tokenizer->nextTokenKind() == TokenInfo::TK_CloseParen ||
+         Tokenizer->nextTokenKind() == TokenInfo::TK_Eof) &&
+        !S->lookupMatcherCtor(NameToken.Text)) {
+      Error->addError(NameToken.Range, Error->ET_RegistryValueNotFound)
+          << NameToken.Text;
+      return false;
+    }
+    // Otherwise, fallback to the matcher parser.
+  }
+
+  // Parse as a matcher expression.
+  return parseMatcherExpressionImpl(NameToken, Value);
+}
+
 /// \brief Parse and validate a matcher expression.
 /// \return \c true on success, in which case \c Value has the matcher parsed.
 ///   If the input is malformed, or some argument has an error, it
 ///   returns \c false.
-bool Parser::parseMatcherExpressionImpl(VariantValue *Value) {
-  const TokenInfo NameToken = Tokenizer->consumeNextToken();
+bool Parser::parseMatcherExpressionImpl(const TokenInfo &NameToken,
+                                        VariantValue *Value) {
   assert(NameToken.Kind == TokenInfo::TK_Ident);
   const TokenInfo OpenToken = Tokenizer->consumeNextToken();
   if (OpenToken.Kind != TokenInfo::TK_OpenParen) {
@@ -242,32 +323,49 @@
     return false;
   }
 
+  llvm::Optional<MatcherCtor> Ctor = S->lookupMatcherCtor(NameToken.Text);
+
+  if (!Ctor) {
+    Error->addError(NameToken.Range, Error->ET_RegistryMatcherNotFound)
+        << NameToken.Text;
+    // Do not return here. We need to continue to give completion suggestions.
+  }
+
   std::vector<ParserValue> Args;
   TokenInfo EndToken;
-  while (Tokenizer->nextTokenKind() != TokenInfo::TK_Eof) {
-    if (Tokenizer->nextTokenKind() == TokenInfo::TK_CloseParen) {
-      // End of args.
-      EndToken = Tokenizer->consumeNextToken();
-      break;
-    }
-    if (Args.size() > 0) {
-      // We must find a , token to continue.
-      const TokenInfo CommaToken = Tokenizer->consumeNextToken();
-      if (CommaToken.Kind != TokenInfo::TK_Comma) {
-        Error->addError(CommaToken.Range, Error->ET_ParserNoComma)
-            << CommaToken.Text;
+
+  {
+    ScopedContextEntry SCE(this, Ctor ? *Ctor : nullptr);
+
+    while (Tokenizer->nextTokenKind() != TokenInfo::TK_Eof) {
+      if (Tokenizer->nextTokenKind() == TokenInfo::TK_CloseParen) {
+        // End of args.
+        EndToken = Tokenizer->consumeNextToken();
+        break;
+      }
+      if (Args.size() > 0) {
+        // We must find a , token to continue.
+        const TokenInfo CommaToken = Tokenizer->consumeNextToken();
+        if (CommaToken.Kind != TokenInfo::TK_Comma) {
+          Error->addError(CommaToken.Range, Error->ET_ParserNoComma)
+              << CommaToken.Text;
+          return false;
+        }
+      }
+
+      Diagnostics::Context Ctx(Diagnostics::Context::MatcherArg, Error,
+                               NameToken.Text, NameToken.Range,
+                               Args.size() + 1);
+      ParserValue ArgValue;
+      ArgValue.Text = Tokenizer->peekNextToken().Text;
+      ArgValue.Range = Tokenizer->peekNextToken().Range;
+      if (!parseExpressionImpl(&ArgValue.Value)) {
         return false;
       }
+
+      Args.push_back(ArgValue);
+      SCE.nextArg();
     }
-
-    Diagnostics::Context Ctx(Diagnostics::Context::MatcherArg, Error,
-                             NameToken.Text, NameToken.Range, Args.size() + 1);
-    ParserValue ArgValue;
-    ArgValue.Text = Tokenizer->peekNextToken().Text;
-    ArgValue.Range = Tokenizer->peekNextToken().Range;
-    if (!parseExpressionImpl(&ArgValue.Value)) return false;
-
-    Args.push_back(ArgValue);
   }
 
   if (EndToken.Kind == TokenInfo::TK_Eof) {
@@ -280,6 +378,11 @@
     // Parse .bind("foo")
     Tokenizer->consumeNextToken();  // consume the period.
     const TokenInfo BindToken = Tokenizer->consumeNextToken();
+    if (BindToken.Kind == TokenInfo::TK_CodeCompletion) {
+      addCompletion(BindToken, "bind(\"", "bind");
+      return false;
+    }
+
     const TokenInfo OpenToken = Tokenizer->consumeNextToken();
     const TokenInfo IDToken = Tokenizer->consumeNextToken();
     const TokenInfo CloseToken = Tokenizer->consumeNextToken();
@@ -306,19 +409,55 @@
     BindID = IDToken.Value.getString();
   }
 
+  if (!Ctor)
+    return false;
+
   // Merge the start and end infos.
   Diagnostics::Context Ctx(Diagnostics::Context::ConstructMatcher, Error,
                            NameToken.Text, NameToken.Range);
   SourceRange MatcherRange = NameToken.Range;
   MatcherRange.End = EndToken.Range.End;
   VariantMatcher Result = S->actOnMatcherExpression(
-      NameToken.Text, MatcherRange, BindID, Args, Error);
+      *Ctor, MatcherRange, BindID, Args, Error);
   if (Result.isNull()) return false;
 
   *Value = Result;
   return true;
 }
 
+// If the prefix of this completion matches the completion token, add it to
+// Completions minus the prefix.
+void Parser::addCompletion(const TokenInfo &CompToken, StringRef TypedText,
+                           StringRef Decl) {
+  if (TypedText.size() >= CompToken.Text.size() &&
+      TypedText.substr(0, CompToken.Text.size()) == CompToken.Text) {
+    Completions.push_back(
+        MatcherCompletion(TypedText.substr(CompToken.Text.size()), Decl));
+  }
+}
+
+void Parser::addExpressionCompletions() {
+  const TokenInfo CompToken = Tokenizer->consumeNextToken();
+  assert(CompToken.Kind == TokenInfo::TK_CodeCompletion);
+
+  // We cannot complete code if there is an invalid element on the context
+  // stack.
+  for (ContextStackTy::iterator I = ContextStack.begin(),
+                                E = ContextStack.end();
+       I != E; ++I) {
+    if (!I->first)
+      return;
+  }
+
+  std::vector<MatcherCompletion> RegCompletions =
+      Registry::getCompletions(ContextStack);
+  for (std::vector<MatcherCompletion>::iterator I = RegCompletions.begin(),
+                                                E = RegCompletions.end();
+       I != E; ++I) {
+    addCompletion(CompToken, I->TypedText, I->MatcherDecl);
+  }
+}
+
 /// \brief Parse an <Expresssion>
 bool Parser::parseExpressionImpl(VariantValue *Value) {
   switch (Tokenizer->nextTokenKind()) {
@@ -327,7 +466,11 @@
     return true;
 
   case TokenInfo::TK_Ident:
-    return parseMatcherExpressionImpl(Value);
+    return parseIdentifierPrefixImpl(Value);
+
+  case TokenInfo::TK_CodeCompletion:
+    addExpressionCompletions();
+    return false;
 
   case TokenInfo::TK_Eof:
     Error->addError(Tokenizer->consumeNextToken().Range,
@@ -355,22 +498,23 @@
                Diagnostics *Error)
     : Tokenizer(Tokenizer), S(S), Error(Error) {}
 
-class RegistrySema : public Parser::Sema {
-public:
-  virtual ~RegistrySema() {}
-  VariantMatcher actOnMatcherExpression(StringRef MatcherName,
-                                        const SourceRange &NameRange,
-                                        StringRef BindID,
-                                        ArrayRef<ParserValue> Args,
-                                        Diagnostics *Error) {
-    if (BindID.empty()) {
-      return Registry::constructMatcher(MatcherName, NameRange, Args, Error);
-    } else {
-      return Registry::constructBoundMatcher(MatcherName, NameRange, BindID,
-                                             Args, Error);
-    }
+Parser::RegistrySema::~RegistrySema() {}
+
+llvm::Optional<MatcherCtor>
+Parser::RegistrySema::lookupMatcherCtor(StringRef MatcherName) {
+  return Registry::lookupMatcherCtor(MatcherName);
+}
+
+VariantMatcher Parser::RegistrySema::actOnMatcherExpression(
+    MatcherCtor Ctor, const SourceRange &NameRange, StringRef BindID,
+    ArrayRef<ParserValue> Args, Diagnostics *Error) {
+  if (BindID.empty()) {
+    return Registry::constructMatcher(Ctor, NameRange, Args, Error);
+  } else {
+    return Registry::constructBoundMatcher(Ctor, NameRange, BindID, Args,
+                                           Error);
   }
-};
+}
 
 bool Parser::parseExpression(StringRef Code, VariantValue *Value,
                              Diagnostics *Error) {
@@ -390,6 +534,18 @@
   return true;
 }
 
+std::vector<MatcherCompletion>
+Parser::completeExpression(StringRef Code, unsigned CompletionOffset) {
+  Diagnostics Error;
+  CodeTokenizer Tokenizer(Code, &Error, CompletionOffset);
+  RegistrySema S;
+  Parser P(&Tokenizer, &S, &Error);
+  VariantValue Dummy;
+  P.parseExpressionImpl(&Dummy);
+
+  return P.Completions;
+}
+
 llvm::Optional<DynTypedMatcher>
 Parser::parseMatcherExpression(StringRef Code, Diagnostics *Error) {
   RegistrySema S;
diff --git a/lib/ASTMatchers/Dynamic/Registry.cpp b/lib/ASTMatchers/Dynamic/Registry.cpp
index 70e956e..4bc50a0 100644
--- a/lib/ASTMatchers/Dynamic/Registry.cpp
+++ b/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -13,23 +13,24 @@
 //===------------------------------------------------------------===//
 
 #include "clang/ASTMatchers/Dynamic/Registry.h"
-
-#include <utility>
-
 #include "Marshallers.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/ManagedStatic.h"
+#include <set>
+#include <utility>
+
+using namespace clang::ast_type_traits;
 
 namespace clang {
 namespace ast_matchers {
 namespace dynamic {
 namespace {
 
-using internal::MatcherCreateCallback;
+using internal::MatcherDescriptor;
 
-typedef llvm::StringMap<const MatcherCreateCallback *> ConstructorMap;
+typedef llvm::StringMap<const MatcherDescriptor *> ConstructorMap;
 class RegistryMaps {
 public:
   RegistryMaps();
@@ -38,12 +39,12 @@
   const ConstructorMap &constructors() const { return Constructors; }
 
 private:
-  void registerMatcher(StringRef MatcherName, MatcherCreateCallback *Callback);
+  void registerMatcher(StringRef MatcherName, MatcherDescriptor *Callback);
   ConstructorMap Constructors;
 };
 
 void RegistryMaps::registerMatcher(StringRef MatcherName,
-                                   MatcherCreateCallback *Callback) {
+                                   MatcherDescriptor *Callback) {
   assert(Constructors.find(MatcherName) == Constructors.end());
   Constructors[MatcherName] = Callback;
 }
@@ -58,14 +59,14 @@
 
 #define REGISTER_OVERLOADED_2(name)                                            \
   do {                                                                         \
-    MatcherCreateCallback *Callbacks[] = {                                     \
+    MatcherDescriptor *Callbacks[] = {                                         \
       internal::makeMatcherAutoMarshall(SPECIFIC_MATCHER_OVERLOAD(name, 0),    \
                                         #name),                                \
       internal::makeMatcherAutoMarshall(SPECIFIC_MATCHER_OVERLOAD(name, 1),    \
                                         #name)                                 \
     };                                                                         \
     registerMatcher(#name,                                                     \
-                    new internal::OverloadedMatcherCreateCallback(Callbacks)); \
+                    new internal::OverloadedMatcherDescriptor(Callbacks));     \
   } while (0)
 
 /// \brief Generate a registry map with all the known matchers.
@@ -76,11 +77,9 @@
   // ofKind
   //
   // Polymorphic + argument overload:
-  // unless
   // findAll
   //
   // Other:
-  // loc
   // equals
   // equalsNode
 
@@ -89,6 +88,7 @@
   REGISTER_OVERLOADED_2(hasType);
   REGISTER_OVERLOADED_2(isDerivedFrom);
   REGISTER_OVERLOADED_2(isSameOrDerivedFrom);
+  REGISTER_OVERLOADED_2(loc);
   REGISTER_OVERLOADED_2(pointsTo);
   REGISTER_OVERLOADED_2(references);
   REGISTER_OVERLOADED_2(thisPointerType);
@@ -113,6 +113,7 @@
   REGISTER_MATCHER(builtinType);
   REGISTER_MATCHER(cStyleCastExpr);
   REGISTER_MATCHER(callExpr);
+  REGISTER_MATCHER(caseStmt);
   REGISTER_MATCHER(castExpr);
   REGISTER_MATCHER(catchStmt);
   REGISTER_MATCHER(characterLiteral);
@@ -133,7 +134,9 @@
   REGISTER_MATCHER(declCountIs);
   REGISTER_MATCHER(declRefExpr);
   REGISTER_MATCHER(declStmt);
+  REGISTER_MATCHER(declaratorDecl);
   REGISTER_MATCHER(defaultArgExpr);
+  REGISTER_MATCHER(defaultStmt);
   REGISTER_MATCHER(deleteExpr);
   REGISTER_MATCHER(dependentSizedArrayType);
   REGISTER_MATCHER(destructorDecl);
@@ -143,15 +146,20 @@
   REGISTER_MATCHER(elaboratedType);
   REGISTER_MATCHER(enumConstantDecl);
   REGISTER_MATCHER(enumDecl);
+  REGISTER_MATCHER(equalsBoundNode);
   REGISTER_MATCHER(explicitCastExpr);
   REGISTER_MATCHER(expr);
+  REGISTER_MATCHER(exprWithCleanups);
   REGISTER_MATCHER(fieldDecl);
   REGISTER_MATCHER(floatLiteral);
   REGISTER_MATCHER(forEach);
+  REGISTER_MATCHER(forEachConstructorInitializer);
   REGISTER_MATCHER(forEachDescendant);
+  REGISTER_MATCHER(forEachSwitchCase);
   REGISTER_MATCHER(forField);
   REGISTER_MATCHER(forRangeStmt);
   REGISTER_MATCHER(forStmt);
+  REGISTER_MATCHER(friendDecl);
   REGISTER_MATCHER(functionDecl);
   REGISTER_MATCHER(functionTemplateDecl);
   REGISTER_MATCHER(functionType);
@@ -170,6 +178,7 @@
   REGISTER_MATCHER(hasBase);
   REGISTER_MATCHER(hasBody);
   REGISTER_MATCHER(hasCanonicalType);
+  REGISTER_MATCHER(hasCaseConstant);
   REGISTER_MATCHER(hasCondition);
   REGISTER_MATCHER(hasConditionVariableStatement);
   REGISTER_MATCHER(hasDeclContext);
@@ -180,12 +189,14 @@
   REGISTER_MATCHER(hasEitherOperand);
   REGISTER_MATCHER(hasElementType);
   REGISTER_MATCHER(hasFalseExpression);
+  REGISTER_MATCHER(hasGlobalStorage);
   REGISTER_MATCHER(hasImplicitDestinationType);
   REGISTER_MATCHER(hasIncrement);
   REGISTER_MATCHER(hasIndex);
   REGISTER_MATCHER(hasInitializer);
   REGISTER_MATCHER(hasLHS);
   REGISTER_MATCHER(hasLocalQualifiers);
+  REGISTER_MATCHER(hasLocalStorage);
   REGISTER_MATCHER(hasLoopInit);
   REGISTER_MATCHER(hasMethod);
   REGISTER_MATCHER(hasName);
@@ -203,6 +214,7 @@
   REGISTER_MATCHER(hasTargetDecl);
   REGISTER_MATCHER(hasTemplateArgument);
   REGISTER_MATCHER(hasTrueExpression);
+  REGISTER_MATCHER(hasTypeLoc);
   REGISTER_MATCHER(hasUnaryOperand);
   REGISTER_MATCHER(hasValueType);
   REGISTER_MATCHER(ifStmt);
@@ -215,12 +227,15 @@
   REGISTER_MATCHER(innerType);
   REGISTER_MATCHER(integerLiteral);
   REGISTER_MATCHER(isArrow);
+  REGISTER_MATCHER(isConst);
   REGISTER_MATCHER(isConstQualified);
   REGISTER_MATCHER(isDefinition);
   REGISTER_MATCHER(isExplicitTemplateSpecialization);
+  REGISTER_MATCHER(isExpr);
   REGISTER_MATCHER(isExternC);
   REGISTER_MATCHER(isImplicit);
   REGISTER_MATCHER(isInteger);
+  REGISTER_MATCHER(isListInitialization);
   REGISTER_MATCHER(isOverride);
   REGISTER_MATCHER(isPrivate);
   REGISTER_MATCHER(isProtected);
@@ -252,6 +267,7 @@
   REGISTER_MATCHER(operatorCallExpr);
   REGISTER_MATCHER(parameterCountIs);
   REGISTER_MATCHER(parenType);
+  REGISTER_MATCHER(parmVarDecl);
   REGISTER_MATCHER(pointee);
   REGISTER_MATCHER(pointerType);
   REGISTER_MATCHER(qualType);
@@ -275,6 +291,7 @@
   REGISTER_MATCHER(switchCase);
   REGISTER_MATCHER(switchStmt);
   REGISTER_MATCHER(templateSpecializationType);
+  REGISTER_MATCHER(temporaryObjectExpr);
   REGISTER_MATCHER(thisExpr);
   REGISTER_MATCHER(throughUsingDecl);
   REGISTER_MATCHER(throwExpr);
@@ -285,6 +302,10 @@
   REGISTER_MATCHER(typedefType);
   REGISTER_MATCHER(unaryExprOrTypeTraitExpr);
   REGISTER_MATCHER(unaryOperator);
+  REGISTER_MATCHER(unaryTransformType);
+  REGISTER_MATCHER(unless);
+  REGISTER_MATCHER(unresolvedConstructExpr);
+  REGISTER_MATCHER(unresolvedUsingValueDecl);
   REGISTER_MATCHER(userDefinedLiteral);
   REGISTER_MATCHER(usingDecl);
   REGISTER_MATCHER(varDecl);
@@ -306,27 +327,175 @@
 } // anonymous namespace
 
 // static
-VariantMatcher Registry::constructMatcher(StringRef MatcherName,
-                                          const SourceRange &NameRange,
-                                          ArrayRef<ParserValue> Args,
-                                          Diagnostics *Error) {
+llvm::Optional<MatcherCtor> Registry::lookupMatcherCtor(StringRef MatcherName) {
   ConstructorMap::const_iterator it =
       RegistryData->constructors().find(MatcherName);
-  if (it == RegistryData->constructors().end()) {
-    Error->addError(NameRange, Error->ET_RegistryNotFound) << MatcherName;
-    return VariantMatcher();
+  return it == RegistryData->constructors().end()
+             ? llvm::Optional<MatcherCtor>()
+             : it->second;
+}
+
+namespace {
+
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+                              const std::set<ASTNodeKind> &KS) {
+  unsigned Count = 0;
+  for (std::set<ASTNodeKind>::const_iterator I = KS.begin(), E = KS.end();
+       I != E; ++I) {
+    if (I != KS.begin())
+      OS << "|";
+    if (Count++ == 3) {
+      OS << "...";
+      break;
+    }
+    OS << *I;
+  }
+  return OS;
+}
+
+struct ReverseSpecificityThenName {
+  bool operator()(const std::pair<unsigned, std::string> &A,
+                  const std::pair<unsigned, std::string> &B) const {
+    return A.first > B.first || (A.first == B.first && A.second < B.second);
+  }
+};
+
+}
+
+std::vector<MatcherCompletion> Registry::getCompletions(
+    ArrayRef<std::pair<MatcherCtor, unsigned> > Context) {
+  ASTNodeKind InitialTypes[] = {
+    ASTNodeKind::getFromNodeKind<Decl>(),
+    ASTNodeKind::getFromNodeKind<QualType>(),
+    ASTNodeKind::getFromNodeKind<Type>(),
+    ASTNodeKind::getFromNodeKind<Stmt>(),
+    ASTNodeKind::getFromNodeKind<NestedNameSpecifier>(),
+    ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>(),
+    ASTNodeKind::getFromNodeKind<TypeLoc>()
+  };
+  ArrayRef<ASTNodeKind> InitialTypesRef(InitialTypes);
+
+  // Starting with the above seed of acceptable top-level matcher types, compute
+  // the acceptable type set for the argument indicated by each context element.
+  std::set<ASTNodeKind> TypeSet(InitialTypesRef.begin(), InitialTypesRef.end());
+  for (ArrayRef<std::pair<MatcherCtor, unsigned> >::iterator
+           CtxI = Context.begin(),
+           CtxE = Context.end();
+       CtxI != CtxE; ++CtxI) {
+    std::vector<internal::ArgKind> NextTypeSet;
+    for (std::set<ASTNodeKind>::iterator I = TypeSet.begin(), E = TypeSet.end();
+         I != E; ++I) {
+      if (CtxI->first->isConvertibleTo(*I) &&
+          (CtxI->first->isVariadic() ||
+           CtxI->second < CtxI->first->getNumArgs()))
+        CtxI->first->getArgKinds(*I, CtxI->second, NextTypeSet);
+    }
+    TypeSet.clear();
+    for (std::vector<internal::ArgKind>::iterator I = NextTypeSet.begin(),
+                                                  E = NextTypeSet.end();
+         I != E; ++I) {
+      if (I->getArgKind() == internal::ArgKind::AK_Matcher)
+        TypeSet.insert(I->getMatcherKind());
+    }
   }
 
-  return it->second->run(NameRange, Args, Error);
+  typedef std::map<std::pair<unsigned, std::string>, MatcherCompletion,
+                   ReverseSpecificityThenName> CompletionsTy;
+  CompletionsTy Completions;
+
+  // TypeSet now contains the list of acceptable types for the argument we are
+  // completing.  Search the registry for acceptable matchers.
+  for (ConstructorMap::const_iterator I = RegistryData->constructors().begin(),
+                                      E = RegistryData->constructors().end();
+       I != E; ++I) {
+    std::set<ASTNodeKind> RetKinds;
+    unsigned NumArgs = I->second->isVariadic() ? 1 : I->second->getNumArgs();
+    bool IsPolymorphic = I->second->isPolymorphic();
+    std::vector<std::vector<internal::ArgKind> > ArgsKinds(NumArgs);
+    unsigned MaxSpecificity = 0;
+    for (std::set<ASTNodeKind>::iterator TI = TypeSet.begin(),
+                                         TE = TypeSet.end();
+         TI != TE; ++TI) {
+      unsigned Specificity;
+      ASTNodeKind LeastDerivedKind;
+      if (I->second->isConvertibleTo(*TI, &Specificity, &LeastDerivedKind)) {
+        if (MaxSpecificity < Specificity)
+          MaxSpecificity = Specificity;
+        RetKinds.insert(LeastDerivedKind);
+        for (unsigned Arg = 0; Arg != NumArgs; ++Arg)
+          I->second->getArgKinds(*TI, Arg, ArgsKinds[Arg]);
+        if (IsPolymorphic)
+          break;
+      }
+    }
+
+    if (!RetKinds.empty() && MaxSpecificity > 0) {
+      std::string Decl;
+      llvm::raw_string_ostream OS(Decl);
+
+      if (IsPolymorphic) {
+        OS << "Matcher<T> " << I->first() << "(Matcher<T>";
+      } else {
+        OS << "Matcher<" << RetKinds << "> " << I->first() << "(";
+        for (std::vector<std::vector<internal::ArgKind> >::iterator
+                 KI = ArgsKinds.begin(),
+                 KE = ArgsKinds.end();
+             KI != KE; ++KI) {
+          if (KI != ArgsKinds.begin())
+            OS << ", ";
+          // This currently assumes that a matcher may not overload a
+          // non-matcher, and all non-matcher overloads have identical
+          // arguments.
+          if ((*KI)[0].getArgKind() == internal::ArgKind::AK_Matcher) {
+            std::set<ASTNodeKind> MatcherKinds;
+            std::transform(
+                KI->begin(), KI->end(),
+                std::inserter(MatcherKinds, MatcherKinds.end()),
+                std::mem_fun_ref(&internal::ArgKind::getMatcherKind));
+            OS << "Matcher<" << MatcherKinds << ">";
+          } else {
+            OS << (*KI)[0].asString();
+          }
+        }
+      }
+      if (I->second->isVariadic())
+        OS << "...";
+      OS << ")";
+
+      std::string TypedText = I->first();
+      TypedText += "(";
+      if (ArgsKinds.empty())
+        TypedText += ")";
+      else if (ArgsKinds[0][0].getArgKind() == internal::ArgKind::AK_String)
+        TypedText += "\"";
+
+      Completions[std::make_pair(MaxSpecificity, I->first())] =
+          MatcherCompletion(TypedText, OS.str());
+    }
+  }
+
+  std::vector<MatcherCompletion> RetVal;
+  for (CompletionsTy::iterator I = Completions.begin(), E = Completions.end();
+       I != E; ++I)
+    RetVal.push_back(I->second);
+  return RetVal;
 }
 
 // static
-VariantMatcher Registry::constructBoundMatcher(StringRef MatcherName,
+VariantMatcher Registry::constructMatcher(MatcherCtor Ctor,
+                                          const SourceRange &NameRange,
+                                          ArrayRef<ParserValue> Args,
+                                          Diagnostics *Error) {
+  return Ctor->create(NameRange, Args, Error);
+}
+
+// static
+VariantMatcher Registry::constructBoundMatcher(MatcherCtor Ctor,
                                                const SourceRange &NameRange,
                                                StringRef BindID,
                                                ArrayRef<ParserValue> Args,
                                                Diagnostics *Error) {
-  VariantMatcher Out = constructMatcher(MatcherName, NameRange, Args, Error);
+  VariantMatcher Out = constructMatcher(Ctor, NameRange, Args, Error);
   if (Out.isNull()) return Out;
 
   llvm::Optional<DynTypedMatcher> Result = Out.getSingleMatcher();
diff --git a/lib/ASTMatchers/Dynamic/VariantValue.cpp b/lib/ASTMatchers/Dynamic/VariantValue.cpp
index 3e49e1b..18c9894 100644
--- a/lib/ASTMatchers/Dynamic/VariantValue.cpp
+++ b/lib/ASTMatchers/Dynamic/VariantValue.cpp
@@ -13,7 +13,6 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/ASTMatchers/Dynamic/VariantValue.h"
-
 #include "clang/Basic/LLVM.h"
 #include "llvm/ADT/STLExtras.h"
 
@@ -38,7 +37,8 @@
   }
 
   virtual void makeTypedMatcher(MatcherOps &Ops) const {
-    if (Ops.canConstructFrom(Matcher))
+    bool Ignore;
+    if (Ops.canConstructFrom(Matcher, Ignore))
       Ops.constructFrom(Matcher);
   }
 
@@ -48,8 +48,8 @@
 
 class VariantMatcher::PolymorphicPayload : public VariantMatcher::Payload {
 public:
-  PolymorphicPayload(ArrayRef<DynTypedMatcher> MatchersIn)
-      : Matchers(MatchersIn) {}
+  PolymorphicPayload(std::vector<DynTypedMatcher> MatchersIn)
+      : Matchers(std::move(MatchersIn)) {}
 
   virtual ~PolymorphicPayload() {}
 
@@ -70,15 +70,25 @@
   }
 
   virtual void makeTypedMatcher(MatcherOps &Ops) const {
-    const DynTypedMatcher *Found = NULL;
+    bool FoundIsExact = false;
+    const DynTypedMatcher *Found = nullptr;
+    int NumFound = 0;
     for (size_t i = 0, e = Matchers.size(); i != e; ++i) {
-      if (Ops.canConstructFrom(Matchers[i])) {
-        if (Found)
-          return;
+      bool IsExactMatch;
+      if (Ops.canConstructFrom(Matchers[i], IsExactMatch)) {
+        if (Found) {
+          if (FoundIsExact) {
+            assert(!IsExactMatch && "We should not have two exact matches.");
+            continue;
+          }
+        }
         Found = &Matchers[i];
+        FoundIsExact = IsExactMatch;
+        ++NumFound;
       }
     }
-    if (Found)
+    // We only succeed if we found exactly one, or if we found an exact match.
+    if (Found && (FoundIsExact || NumFound == 1))
       Ops.constructFrom(*Found);
   }
 
@@ -88,8 +98,8 @@
 class VariantMatcher::VariadicOpPayload : public VariantMatcher::Payload {
 public:
   VariadicOpPayload(ast_matchers::internal::VariadicOperatorFunction Func,
-                    ArrayRef<VariantMatcher> Args)
-      : Func(Func), Args(Args) {}
+                    std::vector<VariantMatcher> Args)
+      : Func(Func), Args(std::move(Args)) {}
 
   virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const {
     return llvm::Optional<DynTypedMatcher>();
@@ -121,14 +131,14 @@
 }
 
 VariantMatcher
-VariantMatcher::PolymorphicMatcher(ArrayRef<DynTypedMatcher> Matchers) {
-  return VariantMatcher(new PolymorphicPayload(Matchers));
+VariantMatcher::PolymorphicMatcher(std::vector<DynTypedMatcher> Matchers) {
+  return VariantMatcher(new PolymorphicPayload(std::move(Matchers)));
 }
 
 VariantMatcher VariantMatcher::VariadicOperatorMatcher(
     ast_matchers::internal::VariadicOperatorFunction Func,
-    ArrayRef<VariantMatcher> Args) {
-  return VariantMatcher(new VariadicOpPayload(Func, Args));
+    std::vector<VariantMatcher> Args) {
+  return VariantMatcher(new VariadicOpPayload(Func, std::move(Args)));
 }
 
 llvm::Optional<DynTypedMatcher> VariantMatcher::getSingleMatcher() const {
diff --git a/lib/Analysis/AnalysisDeclContext.cpp b/lib/Analysis/AnalysisDeclContext.cpp
index 465f0c3..90d4b13 100644
--- a/lib/Analysis/AnalysisDeclContext.cpp
+++ b/lib/Analysis/AnalysisDeclContext.cpp
@@ -28,8 +28,8 @@
 #include "clang/Analysis/Support/BumpVector.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/SaveAndRestore.h"
+#include "llvm/Support/raw_ostream.h"
 
 using namespace clang;
 
@@ -41,11 +41,11 @@
   : Manager(Mgr),
     D(d),
     cfgBuildOptions(buildOptions),
-    forcedBlkExprs(0),
+    forcedBlkExprs(nullptr),
     builtCFG(false),
     builtCompleteCFG(false),
-    ReferencedBlockVars(0),
-    ManagedAnalyses(0)
+    ReferencedBlockVars(nullptr),
+    ManagedAnalyses(nullptr)
 {  
   cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
 }
@@ -54,11 +54,11 @@
                                          const Decl *d)
 : Manager(Mgr),
   D(d),
-  forcedBlkExprs(0),
+  forcedBlkExprs(nullptr),
   builtCFG(false),
   builtCompleteCFG(false),
-  ReferencedBlockVars(0),
-  ManagedAnalyses(0)
+  ReferencedBlockVars(nullptr),
+  ManagedAnalyses(nullptr)
 {  
   cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
 }
@@ -68,7 +68,8 @@
                                                        bool addInitializers,
                                                        bool addTemporaryDtors,
                                                        bool synthesizeBodies,
-                                                       bool addStaticInitBranch)
+                                                       bool addStaticInitBranch,
+                                                       bool addCXXNewAllocator)
   : SynthesizeBodies(synthesizeBodies)
 {
   cfgBuildOptions.PruneTriviallyFalseEdges = !useUnoptimizedCFG;
@@ -76,12 +77,11 @@
   cfgBuildOptions.AddInitializers = addInitializers;
   cfgBuildOptions.AddTemporaryDtors = addTemporaryDtors;
   cfgBuildOptions.AddStaticInitBranches = addStaticInitBranch;
+  cfgBuildOptions.AddCXXNewAllocator = addCXXNewAllocator;
 }
 
 void AnalysisDeclContextManager::clear() {
-  for (ContextMap::iterator I = Contexts.begin(), E = Contexts.end(); I!=E; ++I)
-    delete I->second;
-  Contexts.clear();
+  llvm::DeleteContainerSeconds(Contexts);
 }
 
 static BodyFarm &getBodyFarm(ASTContext &C) {
@@ -94,14 +94,21 @@
   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
     Stmt *Body = FD->getBody();
     if (!Body && Manager && Manager->synthesizeBodies()) {
-      IsAutosynthesized = true;
-      return getBodyFarm(getASTContext()).getBody(FD);
+      Body = getBodyFarm(getASTContext()).getBody(FD);
+      if (Body)
+        IsAutosynthesized = true;
     }
     return Body;
   }
-  else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
-    return MD->getBody();
-  else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
+  else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
+    Stmt *Body = MD->getBody();
+    if (!Body && Manager && Manager->synthesizeBodies()) {
+      Body = getBodyFarm(getASTContext()).getBody(MD);
+      if (Body)
+        IsAutosynthesized = true;
+    }
+    return Body;
+  } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
     return BD->getBody();
   else if (const FunctionTemplateDecl *FunTmpl
            = dyn_cast_or_null<FunctionTemplateDecl>(D))
@@ -126,15 +133,14 @@
     return MD->getSelfDecl();
   if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
     // See if 'self' was captured by the block.
-    for (BlockDecl::capture_const_iterator it = BD->capture_begin(),
-         et = BD->capture_end(); it != et; ++it) {
-      const VarDecl *VD = it->getVariable();
+    for (const auto &I : BD->captures()) {
+      const VarDecl *VD = I.getVariable();
       if (VD->getName() == "self")
         return dyn_cast<ImplicitParamDecl>(VD);
     }    
   }
 
-  return NULL;
+  return nullptr;
 }
 
 void AnalysisDeclContext::registerForcedBlockExpression(const Stmt *stmt) {
@@ -183,6 +189,9 @@
 
     if (PM)
       addParentsForSyntheticStmts(cfg.get(), *PM);
+
+    // The Observer should only observe one build of the CFG.
+    getCFGBuildOptions().Observer = nullptr;
   }
   return cfg.get();
 }
@@ -199,6 +208,9 @@
 
     if (PM)
       addParentsForSyntheticStmts(completeCFG.get(), *PM);
+
+    // The Observer should only observe one build of the CFG.
+    getCFGBuildOptions().Observer = nullptr;
   }
   return completeCFG.get();
 }
@@ -211,8 +223,8 @@
     cfgStmtMap.reset(CFGStmtMap::Build(c, &getParentMap()));
     return cfgStmtMap.get();
   }
-    
-  return 0;
+
+  return nullptr;
 }
 
 CFGReverseBlockReachabilityAnalysis *AnalysisDeclContext::getCFGReachablityAnalysis() {
@@ -223,8 +235,8 @@
     CFA.reset(new CFGReverseBlockReachabilityAnalysis(*c));
     return CFA.get();
   }
-  
-  return 0;
+
+  return nullptr;
 }
 
 void AnalysisDeclContext::dumpCFG(bool ShowColors) {
@@ -235,10 +247,8 @@
   if (!PM) {
     PM.reset(new ParentMap(getBody()));
     if (const CXXConstructorDecl *C = dyn_cast<CXXConstructorDecl>(getDecl())) {
-      for (CXXConstructorDecl::init_const_iterator I = C->init_begin(),
-                                                   E = C->init_end();
-           I != E; ++I) {
-        PM->addStmt((*I)->getInit());
+      for (const auto *I : C->inits()) {
+        PM->addStmt(I->getInit());
       }
     }
     if (builtCFG)
@@ -391,7 +401,7 @@
       return SFC;
     LC = LC->getParent();
   }
-  return NULL;
+  return nullptr;
 }
 
 bool LocationContext::inTopFrame() const {
@@ -435,7 +445,7 @@
   }
 }
 
-void LocationContext::dumpStack() const {
+LLVM_DUMP_METHOD void LocationContext::dumpStack() const {
   dumpStack(llvm::errs());
 }
 
@@ -454,11 +464,6 @@
                             BumpVectorContext &bc)
   : BEVals(bevals), BC(bc) {}
 
-  bool IsTrackedDecl(const VarDecl *VD) {
-    const DeclContext *DC = VD->getDeclContext();
-    return IgnoredContexts.count(DC) == 0;
-  }
-
   void VisitStmt(Stmt *S) {
     for (Stmt::child_range I = S->children(); I; ++I)
       if (Stmt *child = *I)
@@ -506,9 +511,8 @@
   new (BV) DeclVec(BC, 10);
 
   // Go through the capture list.
-  for (BlockDecl::capture_const_iterator CI = BD->capture_begin(),
-       CE = BD->capture_end(); CI != CE; ++CI) {
-    BV->push_back(CI->getVariable(), BC);
+  for (const auto &CI : BD->captures()) {
+    BV->push_back(CI.getVariable(), BC);
   }
 
   // Find the referenced global/static variables.
@@ -548,15 +552,13 @@
   // Release the managed analyses.
   if (ManagedAnalyses) {
     ManagedAnalysisMap *M = (ManagedAnalysisMap*) ManagedAnalyses;
-    for (ManagedAnalysisMap::iterator I = M->begin(), E = M->end(); I!=E; ++I)
-      delete I->second;  
+    llvm::DeleteContainerSeconds(*M);
     delete M;
   }
 }
 
 AnalysisDeclContextManager::~AnalysisDeclContextManager() {
-  for (ContextMap::iterator I = Contexts.begin(), E = Contexts.end(); I!=E; ++I)
-    delete I->second;
+  llvm::DeleteContainerSeconds(Contexts);
 }
 
 LocationContext::~LocationContext() {}
diff --git a/lib/Analysis/BodyFarm.cpp b/lib/Analysis/BodyFarm.cpp
index 4d5c2ee..316a18b 100644
--- a/lib/Analysis/BodyFarm.cpp
+++ b/lib/Analysis/BodyFarm.cpp
@@ -35,8 +35,7 @@
   // returns void.
   const FunctionProtoType *FT =
   BPT->getPointeeType()->getAs<FunctionProtoType>();
-  if (!FT || !FT->getResultType()->isVoidType()  ||
-      FT->getNumArgs() != 0)
+  if (!FT || !FT->getReturnType()->isVoidType() || FT->getNumParams() != 0)
     return false;
 
   return true;
@@ -74,6 +73,9 @@
   
   /// Create an Objective-C bool literal.
   ObjCBoolLiteralExpr *makeObjCBool(bool Val);
+
+  /// Create an Objective-C ivar reference.
+  ObjCIvarRefExpr *makeObjCIvarRef(const Expr *Base, const ObjCIvarDecl *IVar);
   
   /// Create a Return statement.
   ReturnStmt *makeReturn(const Expr *RetVal);
@@ -126,20 +128,20 @@
 
 ImplicitCastExpr *ASTMaker::makeLvalueToRvalue(const Expr *Arg, QualType Ty) {
   return ImplicitCastExpr::Create(C, Ty, CK_LValueToRValue,
-                                  const_cast<Expr*>(Arg), 0, VK_RValue);
+                                  const_cast<Expr*>(Arg), nullptr, VK_RValue);
 }
 
 Expr *ASTMaker::makeIntegralCast(const Expr *Arg, QualType Ty) {
   if (Arg->getType() == Ty)
     return const_cast<Expr*>(Arg);
-  
+
   return ImplicitCastExpr::Create(C, Ty, CK_IntegralCast,
-                                  const_cast<Expr*>(Arg), 0, VK_RValue);
+                                  const_cast<Expr*>(Arg), nullptr, VK_RValue);
 }
 
 ImplicitCastExpr *ASTMaker::makeIntegralCastToBoolean(const Expr *Arg) {
   return ImplicitCastExpr::Create(C, C.BoolTy, CK_IntegralToBoolean,
-                                  const_cast<Expr*>(Arg), 0, VK_RValue);
+                                  const_cast<Expr*>(Arg), nullptr, VK_RValue);
 }
 
 ObjCBoolLiteralExpr *ASTMaker::makeObjCBool(bool Val) {
@@ -147,8 +149,18 @@
   return new (C) ObjCBoolLiteralExpr(Val, Ty, SourceLocation());
 }
 
+ObjCIvarRefExpr *ASTMaker::makeObjCIvarRef(const Expr *Base,
+                                           const ObjCIvarDecl *IVar) {
+  return new (C) ObjCIvarRefExpr(const_cast<ObjCIvarDecl*>(IVar),
+                                 IVar->getType(), SourceLocation(),
+                                 SourceLocation(), const_cast<Expr*>(Base),
+                                 /*arrow=*/true, /*free=*/false);
+}
+
+
 ReturnStmt *ASTMaker::makeReturn(const Expr *RetVal) {
-  return new (C) ReturnStmt(SourceLocation(), const_cast<Expr*>(RetVal), 0);
+  return new (C) ReturnStmt(SourceLocation(), const_cast<Expr*>(RetVal),
+                            nullptr);
 }
 
 //===----------------------------------------------------------------------===//
@@ -161,24 +173,24 @@
 static Stmt *create_dispatch_once(ASTContext &C, const FunctionDecl *D) {
   // Check if we have at least two parameters.
   if (D->param_size() != 2)
-    return 0;
+    return nullptr;
 
   // Check if the first parameter is a pointer to integer type.
   const ParmVarDecl *Predicate = D->getParamDecl(0);
   QualType PredicateQPtrTy = Predicate->getType();
   const PointerType *PredicatePtrTy = PredicateQPtrTy->getAs<PointerType>();
   if (!PredicatePtrTy)
-    return 0;
+    return nullptr;
   QualType PredicateTy = PredicatePtrTy->getPointeeType();
   if (!PredicateTy->isIntegerType())
-    return 0;
-  
+    return nullptr;
+
   // Check if the second parameter is the proper block type.
   const ParmVarDecl *Block = D->getParamDecl(1);
   QualType Ty = Block->getType();
   if (!isDispatchBlock(Ty))
-    return 0;
-  
+    return nullptr;
+
   // Everything checks out.  Create a fakse body that checks the predicate,
   // sets it, and calls the block.  Basically, an AST dump of:
   //
@@ -231,7 +243,7 @@
                                            SourceLocation());
   
   // (5) Create the 'if' statement.
-  IfStmt *If = new (C) IfStmt(C, SourceLocation(), 0, UO, CS);
+  IfStmt *If = new (C) IfStmt(C, SourceLocation(), nullptr, UO, CS);
   return If;
 }
 
@@ -239,14 +251,14 @@
 static Stmt *create_dispatch_sync(ASTContext &C, const FunctionDecl *D) {
   // Check if we have at least two parameters.
   if (D->param_size() != 2)
-    return 0;
-  
+    return nullptr;
+
   // Check if the second parameter is a block.
   const ParmVarDecl *PV = D->getParamDecl(1);
   QualType Ty = PV->getType();
   if (!isDispatchBlock(Ty))
-    return 0;
-  
+    return nullptr;
+
   // Everything checks out.  Create a fake body that just calls the block.
   // This is basically just an AST dump of:
   //
@@ -266,8 +278,8 @@
 {
   // There are exactly 3 arguments.
   if (D->param_size() != 3)
-    return 0;
-  
+    return nullptr;
+
   // Signature:
   // _Bool OSAtomicCompareAndSwapPtr(void *__oldValue,
   //                                 void *__newValue,
@@ -278,12 +290,12 @@
   //    return YES;
   //   }
   //   else return NO;
-  
-  QualType ResultTy = D->getResultType();
+
+  QualType ResultTy = D->getReturnType();
   bool isBoolean = ResultTy->isBooleanType();
   if (!isBoolean && !ResultTy->isIntegralType(C))
-    return 0;
-  
+    return nullptr;
+
   const ParmVarDecl *OldValue = D->getParamDecl(0);
   QualType OldValueTy = OldValue->getType();
 
@@ -296,7 +308,7 @@
   QualType TheValueTy = TheValue->getType();
   const PointerType *PT = TheValueTy->getAs<PointerType>();
   if (!PT)
-    return 0;
+    return nullptr;
   QualType PointeeTy = PT->getPointeeType();
   
   ASTMaker M(C);
@@ -335,9 +347,9 @@
   
   /// Construct the If.
   Stmt *If =
-    new (C) IfStmt(C, SourceLocation(), 0, Comparison, Body,
+    new (C) IfStmt(C, SourceLocation(), nullptr, Comparison, Body,
                    SourceLocation(), Else);
-  
+
   return If;  
 }
 
@@ -347,15 +359,15 @@
   Optional<Stmt *> &Val = Bodies[D];
   if (Val.hasValue())
     return Val.getValue();
-  
-  Val = 0;
-  
-  if (D->getIdentifier() == 0)
-    return 0;
+
+  Val = nullptr;
+
+  if (D->getIdentifier() == nullptr)
+    return nullptr;
 
   StringRef Name = D->getName();
   if (Name.empty())
-    return 0;
+    return nullptr;
 
   FunctionFarmer FF;
 
@@ -367,10 +379,94 @@
     FF = llvm::StringSwitch<FunctionFarmer>(Name)
           .Case("dispatch_sync", create_dispatch_sync)
           .Case("dispatch_once", create_dispatch_once)
-        .Default(NULL);
+          .Default(nullptr);
   }
   
   if (FF) { Val = FF(C, D); }
   return Val.getValue();
 }
 
+static Stmt *createObjCPropertyGetter(ASTContext &Ctx,
+                                      const ObjCPropertyDecl *Prop) {
+  // First, find the backing ivar.
+  const ObjCIvarDecl *IVar = Prop->getPropertyIvarDecl();
+  if (!IVar)
+    return nullptr;
+
+  // Ignore weak variables, which have special behavior.
+  if (Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_weak)
+    return nullptr;
+
+  // Look to see if Sema has synthesized a body for us. This happens in
+  // Objective-C++ because the return value may be a C++ class type with a
+  // non-trivial copy constructor. We can only do this if we can find the
+  // @synthesize for this property, though (or if we know it's been auto-
+  // synthesized).
+  const ObjCImplementationDecl *ImplDecl =
+    IVar->getContainingInterface()->getImplementation();
+  if (ImplDecl) {
+    for (const auto *I : ImplDecl->property_impls()) {
+      if (I->getPropertyDecl() != Prop)
+        continue;
+
+      if (I->getGetterCXXConstructor()) {
+        ASTMaker M(Ctx);
+        return M.makeReturn(I->getGetterCXXConstructor());
+      }
+    }
+  }
+
+  // Sanity check that the property is the same type as the ivar, or a
+  // reference to it, and that it is either an object pointer or trivially
+  // copyable.
+  if (!Ctx.hasSameUnqualifiedType(IVar->getType(),
+                                  Prop->getType().getNonReferenceType()))
+    return nullptr;
+  if (!IVar->getType()->isObjCLifetimeType() &&
+      !IVar->getType().isTriviallyCopyableType(Ctx))
+    return nullptr;
+
+  // Generate our body:
+  //   return self->_ivar;
+  ASTMaker M(Ctx);
+
+  const VarDecl *selfVar = Prop->getGetterMethodDecl()->getSelfDecl();
+
+  Expr *loadedIVar =
+    M.makeObjCIvarRef(
+      M.makeLvalueToRvalue(
+        M.makeDeclRefExpr(selfVar),
+        selfVar->getType()),
+      IVar);
+
+  if (!Prop->getType()->isReferenceType())
+    loadedIVar = M.makeLvalueToRvalue(loadedIVar, IVar->getType());
+
+  return M.makeReturn(loadedIVar);
+}
+
+Stmt *BodyFarm::getBody(const ObjCMethodDecl *D) {
+  // We currently only know how to synthesize property accessors.
+  if (!D->isPropertyAccessor())
+    return nullptr;
+
+  D = D->getCanonicalDecl();
+
+  Optional<Stmt *> &Val = Bodies[D];
+  if (Val.hasValue())
+    return Val.getValue();
+  Val = nullptr;
+
+  const ObjCPropertyDecl *Prop = D->findPropertyDecl();
+  if (!Prop)
+    return nullptr;
+
+  // For now, we only synthesize getters.
+  if (D->param_size() != 0)
+    return nullptr;
+
+  Val = createObjCPropertyGetter(C, Prop);
+
+  return Val.getValue();
+}
+
diff --git a/lib/Analysis/BodyFarm.h b/lib/Analysis/BodyFarm.h
index 96f61df..2d200fb 100644
--- a/lib/Analysis/BodyFarm.h
+++ b/lib/Analysis/BodyFarm.h
@@ -24,6 +24,8 @@
 class ASTContext;
 class Decl;
 class FunctionDecl;
+class ObjCMethodDecl;
+class ObjCPropertyDecl;
 class Stmt;
   
 class BodyFarm {
@@ -32,7 +34,10 @@
   
   /// Factory method for creating bodies for ordinary functions.
   Stmt *getBody(const FunctionDecl *D);
-  
+
+  /// Factory method for creating bodies for Objective-C properties.
+  Stmt *getBody(const ObjCMethodDecl *D);
+
 private:
   typedef llvm::DenseMap<const Decl *, Optional<Stmt *> > BodyMap;
 
diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp
index 8b8c573..842a385 100644
--- a/lib/Analysis/CFG.cpp
+++ b/lib/Analysis/CFG.cpp
@@ -21,7 +21,7 @@
 #include "clang/AST/StmtVisitor.h"
 #include "clang/Basic/Builtins.h"
 #include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/OwningPtr.h"
+#include <memory>
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/Format.h"
@@ -112,7 +112,7 @@
     /// Incrementing invalid iterator is allowed and will result in invalid
     /// iterator.
     const_iterator()
-        : Scope(NULL), VarIter(0) {}
+        : Scope(nullptr), VarIter(0) {}
 
     /// Create valid iterator. In case when S.Prev is an invalid iterator and
     /// I is equal to 0, this will create invalid iterator.
@@ -207,7 +207,7 @@
 /// build process. It consists of CFGBlock that specifies position in CFG graph
 /// and  LocalScope::const_iterator that specifies position in LocalScope graph.
 struct BlockScopePosPair {
-  BlockScopePosPair() : block(0) {}
+  BlockScopePosPair() : block(nullptr) {}
   BlockScopePosPair(CFGBlock *b, LocalScope::const_iterator scopePos)
       : block(b), scopePosition(scopePos) {}
 
@@ -291,7 +291,7 @@
   typedef BlockScopePosPair JumpSource;
 
   ASTContext *Context;
-  OwningPtr<CFG> cfg;
+  std::unique_ptr<CFG> cfg;
 
   CFGBlock *Block;
   CFGBlock *Succ;
@@ -336,11 +336,11 @@
   explicit CFGBuilder(ASTContext *astContext,
                       const CFG::BuildOptions &buildOpts) 
     : Context(astContext), cfg(new CFG()), // crew a new CFG
-      Block(NULL), Succ(NULL),
-      SwitchTerminatedBlock(NULL), DefaultCaseBlock(NULL),
-      TryTerminatedBlock(NULL), badCFG(false), BuildOpts(buildOpts), 
-      switchExclusivelyCovered(false), switchCond(0),
-      cachedEntry(0), lastLookup(0) {}
+      Block(nullptr), Succ(nullptr),
+      SwitchTerminatedBlock(nullptr), DefaultCaseBlock(nullptr),
+      TryTerminatedBlock(nullptr), badCFG(false), BuildOpts(buildOpts),
+      switchExclusivelyCovered(false), switchCond(nullptr),
+      cachedEntry(nullptr), lastLookup(nullptr) {}
 
   // buildCFG - Used by external clients to construct the CFG.
   CFG* buildCFG(const Decl *D, Stmt *Statement);
@@ -363,6 +363,7 @@
                                       AddStmtChoice asc);
   CFGBlock *VisitCXXCatchStmt(CXXCatchStmt *S);
   CFGBlock *VisitCXXConstructExpr(CXXConstructExpr *C, AddStmtChoice asc);
+  CFGBlock *VisitCXXNewExpr(CXXNewExpr *DE, AddStmtChoice asc);
   CFGBlock *VisitCXXDeleteExpr(CXXDeleteExpr *DE, AddStmtChoice asc);
   CFGBlock *VisitCXXForRangeStmt(CXXForRangeStmt *S);
   CFGBlock *VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E,
@@ -442,8 +443,9 @@
   LocalScope* createOrReuseLocalScope(LocalScope* Scope);
 
   void addLocalScopeForStmt(Stmt *S);
-  LocalScope* addLocalScopeForDeclStmt(DeclStmt *DS, LocalScope* Scope = NULL);
-  LocalScope* addLocalScopeForVarDecl(VarDecl *VD, LocalScope* Scope = NULL);
+  LocalScope* addLocalScopeForDeclStmt(DeclStmt *DS,
+                                       LocalScope* Scope = nullptr);
+  LocalScope* addLocalScopeForVarDecl(VarDecl *VD, LocalScope* Scope = nullptr);
 
   void addLocalScopeAndDtors(Stmt *S);
 
@@ -459,6 +461,9 @@
   void appendInitializer(CFGBlock *B, CXXCtorInitializer *I) {
     B->appendInitializer(I, cfg->getBumpVectorContext());
   }
+  void appendNewAllocator(CFGBlock *B, CXXNewExpr *NE) {
+    B->appendNewAllocator(NE, cfg->getBumpVectorContext());
+  }
   void appendBaseDtor(CFGBlock *B, const CXXBaseSpecifier *BS) {
     B->appendBaseDtor(BS, cfg->getBumpVectorContext());
   }
@@ -479,8 +484,252 @@
   void prependAutomaticObjDtorsWithTerminator(CFGBlock *Blk,
       LocalScope::const_iterator B, LocalScope::const_iterator E);
 
-  void addSuccessor(CFGBlock *B, CFGBlock *S) {
-    B->addSuccessor(S, cfg->getBumpVectorContext());
+  void addSuccessor(CFGBlock *B, CFGBlock *S, bool IsReachable = true) {
+    B->addSuccessor(CFGBlock::AdjacentBlock(S, IsReachable),
+                    cfg->getBumpVectorContext());
+  }
+
+  /// Add a reachable successor to a block, with the alternate variant that is
+  /// unreachable.
+  void addSuccessor(CFGBlock *B, CFGBlock *ReachableBlock, CFGBlock *AltBlock) {
+    B->addSuccessor(CFGBlock::AdjacentBlock(ReachableBlock, AltBlock),
+                    cfg->getBumpVectorContext());
+  }
+
+  /// \brief Find a relational comparison with an expression evaluating to a
+  /// boolean and a constant other than 0 and 1.
+  /// e.g. if ((x < y) == 10)
+  TryResult checkIncorrectRelationalOperator(const BinaryOperator *B) {
+    const Expr *LHSExpr = B->getLHS()->IgnoreParens();
+    const Expr *RHSExpr = B->getRHS()->IgnoreParens();
+
+    const IntegerLiteral *IntLiteral = dyn_cast<IntegerLiteral>(LHSExpr);
+    const Expr *BoolExpr = RHSExpr;
+    bool IntFirst = true;
+    if (!IntLiteral) {
+      IntLiteral = dyn_cast<IntegerLiteral>(RHSExpr);
+      BoolExpr = LHSExpr;
+      IntFirst = false;
+    }
+
+    if (!IntLiteral || !BoolExpr->isKnownToHaveBooleanValue())
+      return TryResult();
+
+    llvm::APInt IntValue = IntLiteral->getValue();
+    if ((IntValue == 1) || (IntValue == 0))
+      return TryResult();
+
+    bool IntLarger = IntLiteral->getType()->isUnsignedIntegerType() ||
+                     !IntValue.isNegative();
+
+    BinaryOperatorKind Bok = B->getOpcode();
+    if (Bok == BO_GT || Bok == BO_GE) {
+      // Always true for 10 > bool and bool > -1
+      // Always false for -1 > bool and bool > 10
+      return TryResult(IntFirst == IntLarger);
+    } else {
+      // Always true for -1 < bool and bool < 10
+      // Always false for 10 < bool and bool < -1
+      return TryResult(IntFirst != IntLarger);
+    }
+  }
+
+  /// Find an incorrect equality comparison. Either with an expression
+  /// evaluating to a boolean and a constant other than 0 and 1.
+  /// e.g. if (!x == 10) or a bitwise and/or operation that always evaluates to
+  /// true/false e.q. (x & 8) == 4.
+  TryResult checkIncorrectEqualityOperator(const BinaryOperator *B) {
+    const Expr *LHSExpr = B->getLHS()->IgnoreParens();
+    const Expr *RHSExpr = B->getRHS()->IgnoreParens();
+
+    const IntegerLiteral *IntLiteral = dyn_cast<IntegerLiteral>(LHSExpr);
+    const Expr *BoolExpr = RHSExpr;
+
+    if (!IntLiteral) {
+      IntLiteral = dyn_cast<IntegerLiteral>(RHSExpr);
+      BoolExpr = LHSExpr;
+    }
+
+    if (!IntLiteral)
+      return TryResult();
+
+    const BinaryOperator *BitOp = dyn_cast<BinaryOperator>(BoolExpr);
+    if (BitOp && (BitOp->getOpcode() == BO_And ||
+                  BitOp->getOpcode() == BO_Or)) {
+      const Expr *LHSExpr2 = BitOp->getLHS()->IgnoreParens();
+      const Expr *RHSExpr2 = BitOp->getRHS()->IgnoreParens();
+
+      const IntegerLiteral *IntLiteral2 = dyn_cast<IntegerLiteral>(LHSExpr2);
+
+      if (!IntLiteral2)
+        IntLiteral2 = dyn_cast<IntegerLiteral>(RHSExpr2);
+
+      if (!IntLiteral2)
+        return TryResult();
+
+      llvm::APInt L1 = IntLiteral->getValue();
+      llvm::APInt L2 = IntLiteral2->getValue();
+      if ((BitOp->getOpcode() == BO_And && (L2 & L1) != L1) ||
+          (BitOp->getOpcode() == BO_Or  && (L2 | L1) != L1)) {
+        if (BuildOpts.Observer)
+          BuildOpts.Observer->compareBitwiseEquality(B,
+                                                     B->getOpcode() != BO_EQ);
+        TryResult(B->getOpcode() != BO_EQ);
+      }
+    } else if (BoolExpr->isKnownToHaveBooleanValue()) {
+      llvm::APInt IntValue = IntLiteral->getValue();
+      if ((IntValue == 1) || (IntValue == 0)) {
+        return TryResult();
+      }
+      return TryResult(B->getOpcode() != BO_EQ);
+    }
+
+    return TryResult();
+  }
+
+  TryResult analyzeLogicOperatorCondition(BinaryOperatorKind Relation,
+                                          const llvm::APSInt &Value1,
+                                          const llvm::APSInt &Value2) {
+    assert(Value1.isSigned() == Value2.isSigned());
+    switch (Relation) {
+      default:
+        return TryResult();
+      case BO_EQ:
+        return TryResult(Value1 == Value2);
+      case BO_NE:
+        return TryResult(Value1 != Value2);
+      case BO_LT:
+        return TryResult(Value1 <  Value2);
+      case BO_LE:
+        return TryResult(Value1 <= Value2);
+      case BO_GT:
+        return TryResult(Value1 >  Value2);
+      case BO_GE:
+        return TryResult(Value1 >= Value2);
+    }
+  }
+
+  /// \brief Find a pair of comparison expressions with or without parentheses
+  /// with a shared variable and constants and a logical operator between them
+  /// that always evaluates to either true or false.
+  /// e.g. if (x != 3 || x != 4)
+  TryResult checkIncorrectLogicOperator(const BinaryOperator *B) {
+    assert(B->isLogicalOp());
+    const BinaryOperator *LHS =
+        dyn_cast<BinaryOperator>(B->getLHS()->IgnoreParens());
+    const BinaryOperator *RHS =
+        dyn_cast<BinaryOperator>(B->getRHS()->IgnoreParens());
+    if (!LHS || !RHS)
+      return TryResult();
+
+    if (!LHS->isComparisonOp() || !RHS->isComparisonOp())
+      return TryResult();
+
+    BinaryOperatorKind BO1 = LHS->getOpcode();
+    const DeclRefExpr *Decl1 =
+        dyn_cast<DeclRefExpr>(LHS->getLHS()->IgnoreParenImpCasts());
+    const IntegerLiteral *Literal1 =
+        dyn_cast<IntegerLiteral>(LHS->getRHS()->IgnoreParens());
+    if (!Decl1 && !Literal1) {
+      if (BO1 == BO_GT)
+        BO1 = BO_LT;
+      else if (BO1 == BO_GE)
+        BO1 = BO_LE;
+      else if (BO1 == BO_LT)
+        BO1 = BO_GT;
+      else if (BO1 == BO_LE)
+        BO1 = BO_GE;
+      Decl1 = dyn_cast<DeclRefExpr>(LHS->getRHS()->IgnoreParenImpCasts());
+      Literal1 = dyn_cast<IntegerLiteral>(LHS->getLHS()->IgnoreParens());
+    }
+
+    if (!Decl1 || !Literal1)
+      return TryResult();
+
+    BinaryOperatorKind BO2 = RHS->getOpcode();
+    const DeclRefExpr *Decl2 =
+        dyn_cast<DeclRefExpr>(RHS->getLHS()->IgnoreParenImpCasts());
+    const IntegerLiteral *Literal2 =
+        dyn_cast<IntegerLiteral>(RHS->getRHS()->IgnoreParens());
+    if (!Decl2 && !Literal2) {
+      if (BO2 == BO_GT)
+        BO2 = BO_LT;
+      else if (BO2 == BO_GE)
+        BO2 = BO_LE;
+      else if (BO2 == BO_LT)
+        BO2 = BO_GT;
+      else if (BO2 == BO_LE)
+        BO2 = BO_GE;
+      Decl2 = dyn_cast<DeclRefExpr>(RHS->getRHS()->IgnoreParenImpCasts());
+      Literal2 = dyn_cast<IntegerLiteral>(RHS->getLHS()->IgnoreParens());
+    }
+
+    if (!Decl2 || !Literal2)
+      return TryResult();
+
+    // Check that it is the same variable on both sides.
+    if (Decl1->getDecl() != Decl2->getDecl())
+      return TryResult();
+
+    llvm::APSInt L1, L2;
+
+    if (!Literal1->EvaluateAsInt(L1, *Context) ||
+        !Literal2->EvaluateAsInt(L2, *Context))
+      return TryResult();
+
+    // Can't compare signed with unsigned or with different bit width.
+    if (L1.isSigned() != L2.isSigned() || L1.getBitWidth() != L2.getBitWidth())
+      return TryResult();
+
+    // Values that will be used to determine if result of logical
+    // operator is always true/false
+    const llvm::APSInt Values[] = {
+      // Value less than both Value1 and Value2
+      llvm::APSInt::getMinValue(L1.getBitWidth(), L1.isUnsigned()),
+      // L1
+      L1,
+      // Value between Value1 and Value2
+      ((L1 < L2) ? L1 : L2) + llvm::APSInt(llvm::APInt(L1.getBitWidth(), 1),
+                              L1.isUnsigned()),
+      // L2
+      L2,
+      // Value greater than both Value1 and Value2
+      llvm::APSInt::getMaxValue(L1.getBitWidth(), L1.isUnsigned()),
+    };
+
+    // Check whether expression is always true/false by evaluating the following
+    // * variable x is less than the smallest literal.
+    // * variable x is equal to the smallest literal.
+    // * Variable x is between smallest and largest literal.
+    // * Variable x is equal to the largest literal.
+    // * Variable x is greater than largest literal.
+    bool AlwaysTrue = true, AlwaysFalse = true;
+    for (unsigned int ValueIndex = 0;
+         ValueIndex < sizeof(Values) / sizeof(Values[0]);
+         ++ValueIndex) {
+      llvm::APSInt Value = Values[ValueIndex];
+      TryResult Res1, Res2;
+      Res1 = analyzeLogicOperatorCondition(BO1, Value, L1);
+      Res2 = analyzeLogicOperatorCondition(BO2, Value, L2);
+
+      if (!Res1.isKnown() || !Res2.isKnown())
+        return TryResult();
+
+      if (B->getOpcode() == BO_LAnd) {
+        AlwaysTrue &= (Res1.isTrue() && Res2.isTrue());
+        AlwaysFalse &= !(Res1.isTrue() && Res2.isTrue());
+      } else {
+        AlwaysTrue &= (Res1.isTrue() || Res2.isTrue());
+        AlwaysFalse &= !(Res1.isTrue() || Res2.isTrue());
+      }
+    }
+
+    if (AlwaysTrue || AlwaysFalse) {
+      if (BuildOpts.Observer)
+        BuildOpts.Observer->compareAlwaysTrue(B, AlwaysTrue);
+      return TryResult(AlwaysTrue);
+    }
+    return TryResult();
   }
 
   /// Try and evaluate an expression to an integer constant.
@@ -565,10 +814,22 @@
             // is determined by the RHS: X && 0 -> 0, X || 1 -> 1.
             if (RHS.isTrue() == (Bop->getOpcode() == BO_LOr))
               return RHS.isTrue();
+          } else {
+            TryResult BopRes = checkIncorrectLogicOperator(Bop);
+            if (BopRes.isKnown())
+              return BopRes.isTrue();
           }
         }
 
         return TryResult();
+      } else if (Bop->isEqualityOp()) {
+          TryResult BopRes = checkIncorrectEqualityOperator(Bop);
+          if (BopRes.isKnown())
+            return BopRes.isTrue();
+      } else if (Bop->isRelationalOp()) {
+        TryResult BopRes = checkIncorrectRelationalOperator(Bop);
+        if (BopRes.isKnown())
+          return BopRes.isTrue();
       }
     }
 
@@ -607,13 +868,13 @@
 
   if (!fb) {
     // No need to update 'cachedEntry', since it will always be null.
-    assert(cachedEntry == 0);
+    assert(!cachedEntry);
     return shouldAdd;
   }
 
   CFG::BuildOptions::ForcedBlkExprs::iterator itr = fb->find(stmt);
   if (itr == fb->end()) {
-    cachedEntry = 0;
+    cachedEntry = nullptr;
     return shouldAdd;
   }
 
@@ -632,7 +893,7 @@
     t = vt->getElementType().getTypePtr();
   }
 
-  return 0;
+  return nullptr;
 }
 
 /// BuildCFG - Constructs a CFG from an AST (a Stmt*).  The AST can represent an
@@ -643,14 +904,14 @@
 CFG* CFGBuilder::buildCFG(const Decl *D, Stmt *Statement) {
   assert(cfg.get());
   if (!Statement)
-    return NULL;
+    return nullptr;
 
   // Create an empty block that will serve as the exit block for the CFG.  Since
   // this is the first block added to the CFG, it will be implicitly registered
   // as the exit block.
   Succ = createBlock();
   assert(Succ == &cfg->getExit());
-  Block = NULL;  // the EXIT block is empty.  Create all other blocks lazily.
+  Block = nullptr;  // the EXIT block is empty.  Create all other blocks lazily.
 
   if (BuildOpts.AddImplicitDtors)
     if (const CXXDestructorDecl *DD = dyn_cast_or_null<CXXDestructorDecl>(D))
@@ -660,7 +921,7 @@
   CFGBlock *B = addStmt(Statement);
 
   if (badCFG)
-    return NULL;
+    return nullptr;
 
   // For C++ constructor add initializers to CFG.
   if (const CXXConstructorDecl *CD = dyn_cast_or_null<CXXConstructorDecl>(D)) {
@@ -668,7 +929,7 @@
         E = CD->init_rend(); I != E; ++I) {
       B = addInitializer(*I);
       if (badCFG)
-        return NULL;
+        return nullptr;
     }
   }
 
@@ -712,7 +973,7 @@
   // Create an empty entry block that has no predecessors.
   cfg->setEntry(createBlock());
 
-  return cfg.take();
+  return cfg.release();
 }
 
 /// createBlock - Used to lazily create blocks that are connected
@@ -730,7 +991,7 @@
 CFGBlock *CFGBuilder::createNoReturnBlock() {
   CFGBlock *B = createBlock(false);
   B->setHasNoReturnElement();
-  addSuccessor(B, &cfg->getExit());
+  addSuccessor(B, &cfg->getExit(), Succ);
   return B;
 }
 
@@ -868,30 +1129,27 @@
   const CXXRecordDecl *RD = DD->getParent();
 
   // At the end destroy virtual base objects.
-  for (CXXRecordDecl::base_class_const_iterator VI = RD->vbases_begin(),
-      VE = RD->vbases_end(); VI != VE; ++VI) {
-    const CXXRecordDecl *CD = VI->getType()->getAsCXXRecordDecl();
+  for (const auto &VI : RD->vbases()) {
+    const CXXRecordDecl *CD = VI.getType()->getAsCXXRecordDecl();
     if (!CD->hasTrivialDestructor()) {
       autoCreateBlock();
-      appendBaseDtor(Block, VI);
+      appendBaseDtor(Block, &VI);
     }
   }
 
   // Before virtual bases destroy direct base objects.
-  for (CXXRecordDecl::base_class_const_iterator BI = RD->bases_begin(),
-      BE = RD->bases_end(); BI != BE; ++BI) {
-    if (!BI->isVirtual()) {
-      const CXXRecordDecl *CD = BI->getType()->getAsCXXRecordDecl();
+  for (const auto &BI : RD->bases()) {
+    if (!BI.isVirtual()) {
+      const CXXRecordDecl *CD = BI.getType()->getAsCXXRecordDecl();
       if (!CD->hasTrivialDestructor()) {
         autoCreateBlock();
-        appendBaseDtor(Block, BI);
+        appendBaseDtor(Block, &BI);
       }
     }
   }
 
   // First destroy member objects.
-  for (CXXRecordDecl::field_iterator FI = RD->field_begin(),
-      FE = RD->field_end(); FI != FE; ++FI) {
+  for (auto *FI : RD->fields()) {
     // Check for constant size array. Set type to array element type.
     QualType QT = FI->getType();
     if (const ConstantArrayType *AT = Context->getAsConstantArrayType(QT)) {
@@ -903,7 +1161,7 @@
     if (const CXXRecordDecl *CD = QT->getAsCXXRecordDecl())
       if (!CD->hasTrivialDestructor()) {
         autoCreateBlock();
-        appendMemberDtor(Block, *FI);
+        appendMemberDtor(Block, FI);
       }
   }
 }
@@ -926,13 +1184,12 @@
   if (!BuildOpts.AddImplicitDtors)
     return;
 
-  LocalScope *Scope = 0;
+  LocalScope *Scope = nullptr;
 
   // For compound statement we will be creating explicit scope.
   if (CompoundStmt *CS = dyn_cast<CompoundStmt>(S)) {
-    for (CompoundStmt::body_iterator BI = CS->body_begin(), BE = CS->body_end()
-        ; BI != BE; ++BI) {
-      Stmt *SI = (*BI)->stripLabelLikeStatements();
+    for (auto *BI : CS->body()) {
+      Stmt *SI = BI->stripLabelLikeStatements();
       if (DeclStmt *DS = dyn_cast<DeclStmt>(SI))
         Scope = addLocalScopeForDeclStmt(DS, Scope);
     }
@@ -952,11 +1209,9 @@
   if (!BuildOpts.AddImplicitDtors)
     return Scope;
 
-  for (DeclStmt::decl_iterator DI = DS->decl_begin(), DE = DS->decl_end()
-      ; DI != DE; ++DI) {
-    if (VarDecl *VD = dyn_cast<VarDecl>(*DI))
+  for (auto *DI : DS->decls())
+    if (VarDecl *VD = dyn_cast<VarDecl>(DI))
       Scope = addLocalScopeForVarDecl(VD, Scope);
-  }
   return Scope;
 }
 
@@ -1051,7 +1306,7 @@
 CFGBlock *CFGBuilder::Visit(Stmt * S, AddStmtChoice asc) {
   if (!S) {
     badCFG = true;
-    return 0;
+    return nullptr;
   }
 
   if (Expr *E = dyn_cast<Expr>(S))
@@ -1122,6 +1377,9 @@
     case Stmt::CXXConstructExprClass:
       return VisitCXXConstructExpr(cast<CXXConstructExpr>(S), asc);
 
+    case Stmt::CXXNewExprClass:
+      return VisitCXXNewExpr(cast<CXXNewExpr>(S), asc);
+
     case Stmt::CXXDeleteExprClass:
       return VisitCXXDeleteExpr(cast<CXXDeleteExpr>(S), asc);
 
@@ -1273,9 +1531,10 @@
   appendStmt(ConfluenceBlock, B);
 
   if (badCFG)
-    return 0;
+    return nullptr;
 
-  return VisitLogicalOperator(B, 0, ConfluenceBlock, ConfluenceBlock).first;
+  return VisitLogicalOperator(B, nullptr, ConfluenceBlock,
+                              ConfluenceBlock).first;
 }
 
 std::pair<CFGBlock*, CFGBlock*>
@@ -1293,7 +1552,7 @@
   do {
     if (BinaryOperator *B_RHS = dyn_cast<BinaryOperator>(RHS))
       if (B_RHS->isLogicalOp()) {
-        llvm::tie(RHSBlock, ExitBlock) =
+        std::tie(RHSBlock, ExitBlock) =
           VisitLogicalOperator(B_RHS, Term, TrueBlock, FalseBlock);
         break;
       }
@@ -1311,8 +1570,10 @@
     else {
       RHSBlock->setTerminator(Term);
       TryResult KnownVal = tryEvaluateBool(RHS);
-      addSuccessor(RHSBlock, KnownVal.isFalse() ? NULL : TrueBlock);
-      addSuccessor(RHSBlock, KnownVal.isTrue() ? NULL : FalseBlock);
+      if (!KnownVal.isKnown())
+        KnownVal = tryEvaluateBool(B);
+      addSuccessor(RHSBlock, TrueBlock, !KnownVal.isFalse());
+      addSuccessor(RHSBlock, FalseBlock, !KnownVal.isTrue());
     }
 
     Block = RHSBlock;
@@ -1321,7 +1582,7 @@
   while (false);
 
   if (badCFG)
-    return std::make_pair((CFGBlock*)0, (CFGBlock*)0);
+    return std::make_pair(nullptr, nullptr);
 
   // Generate the blocks for evaluating the LHS.
   Expr *LHS = B->getLHS()->IgnoreParens();
@@ -1348,19 +1609,19 @@
   CFGBlock *EntryLHSBlock = addStmt(LHS);
 
   if (badCFG)
-    return std::make_pair((CFGBlock*)0, (CFGBlock*)0);
+    return std::make_pair(nullptr, nullptr);
 
   // See if this is a known constant.
   TryResult KnownVal = tryEvaluateBool(LHS);
 
   // Now link the LHSBlock with RHSBlock.
   if (B->getOpcode() == BO_LOr) {
-    addSuccessor(LHSBlock, KnownVal.isFalse() ? NULL : TrueBlock);
-    addSuccessor(LHSBlock, KnownVal.isTrue() ? NULL : RHSBlock);
+    addSuccessor(LHSBlock, TrueBlock, !KnownVal.isFalse());
+    addSuccessor(LHSBlock, RHSBlock, !KnownVal.isTrue());
   } else {
     assert(B->getOpcode() == BO_LAnd);
-    addSuccessor(LHSBlock, KnownVal.isFalse() ? NULL : RHSBlock);
-    addSuccessor(LHSBlock, KnownVal.isTrue() ? NULL : FalseBlock);
+    addSuccessor(LHSBlock, RHSBlock, !KnownVal.isFalse());
+    addSuccessor(LHSBlock, FalseBlock, !KnownVal.isTrue());
   }
 
   return std::make_pair(EntryLHSBlock, ExitBlock);
@@ -1414,7 +1675,7 @@
   // "break" is a control-flow statement.  Thus we stop processing the current
   // block.
   if (badCFG)
-    return 0;
+    return nullptr;
 
   // Now create a new block that ends with the break statement.
   Block = createBlock(false);
@@ -1502,7 +1763,7 @@
   if (Block) {
     Succ = Block;
     if (badCFG)
-      return 0;
+      return nullptr;
   }
 
   if (NoReturn)
@@ -1528,26 +1789,26 @@
   CFGBlock *ConfluenceBlock = Block ? Block : createBlock();
   appendStmt(ConfluenceBlock, C);
   if (badCFG)
-    return 0;
+    return nullptr;
 
   AddStmtChoice alwaysAdd = asc.withAlwaysAdd(true);
   Succ = ConfluenceBlock;
-  Block = NULL;
+  Block = nullptr;
   CFGBlock *LHSBlock = Visit(C->getLHS(), alwaysAdd);
   if (badCFG)
-    return 0;
+    return nullptr;
 
   Succ = ConfluenceBlock;
-  Block = NULL;
+  Block = nullptr;
   CFGBlock *RHSBlock = Visit(C->getRHS(), alwaysAdd);
   if (badCFG)
-    return 0;
+    return nullptr;
 
   Block = createBlock(false);
   // See if this is a known constant.
   const TryResult& KnownVal = tryEvaluateBool(C->getCond());
-  addSuccessor(Block, KnownVal.isFalse() ? NULL : LHSBlock);
-  addSuccessor(Block, KnownVal.isTrue() ? NULL : RHSBlock);
+  addSuccessor(Block, KnownVal.isFalse() ? nullptr : LHSBlock);
+  addSuccessor(Block, KnownVal.isTrue() ? nullptr : RHSBlock);
   Block->setTerminator(C);
   return addStmt(C->getCond());
 }
@@ -1565,7 +1826,7 @@
       LastBlock = newBlock;
 
     if (badCFG)
-      return NULL;
+      return nullptr;
   }
 
   return LastBlock;
@@ -1574,14 +1835,14 @@
 CFGBlock *CFGBuilder::VisitConditionalOperator(AbstractConditionalOperator *C,
                                                AddStmtChoice asc) {
   const BinaryConditionalOperator *BCO = dyn_cast<BinaryConditionalOperator>(C);
-  const OpaqueValueExpr *opaqueValue = (BCO ? BCO->getOpaqueValue() : NULL);
+  const OpaqueValueExpr *opaqueValue = (BCO ? BCO->getOpaqueValue() : nullptr);
 
   // Create the confluence block that will "merge" the results of the ternary
   // expression.
   CFGBlock *ConfluenceBlock = Block ? Block : createBlock();
   appendStmt(ConfluenceBlock, C);
   if (badCFG)
-    return 0;
+    return nullptr;
 
   AddStmtChoice alwaysAdd = asc.withAlwaysAdd(true);
 
@@ -1590,14 +1851,14 @@
   // value that is returned instead.
   //  e.g: x ?: y is shorthand for: x ? x : y;
   Succ = ConfluenceBlock;
-  Block = NULL;
-  CFGBlock *LHSBlock = 0;
+  Block = nullptr;
+  CFGBlock *LHSBlock = nullptr;
   const Expr *trueExpr = C->getTrueExpr();
   if (trueExpr != opaqueValue) {
     LHSBlock = Visit(C->getTrueExpr(), alwaysAdd);
     if (badCFG)
-      return 0;
-    Block = NULL;
+      return nullptr;
+    Block = nullptr;
   }
   else
     LHSBlock = ConfluenceBlock;
@@ -1606,7 +1867,7 @@
   Succ = ConfluenceBlock;
   CFGBlock *RHSBlock = Visit(C->getFalseExpr(), alwaysAdd);
   if (badCFG)
-    return 0;
+    return nullptr;
 
   // If the condition is a logical '&&' or '||', build a more accurate CFG.
   if (BinaryOperator *Cond =
@@ -1619,8 +1880,8 @@
 
   // See if this is a known constant.
   const TryResult& KnownVal = tryEvaluateBool(C->getCond());
-  addSuccessor(Block, KnownVal.isFalse() ? NULL : LHSBlock);
-  addSuccessor(Block, KnownVal.isTrue() ? NULL : RHSBlock);
+  addSuccessor(Block, LHSBlock, !KnownVal.isFalse());
+  addSuccessor(Block, RHSBlock, !KnownVal.isTrue());
   Block->setTerminator(C);
   Expr *condExpr = C->getCond();
 
@@ -1648,7 +1909,7 @@
   if (DS->isSingleDecl())
     return VisitDeclSubExpr(DS);
 
-  CFGBlock *B = 0;
+  CFGBlock *B = nullptr;
 
   // Build an individual DeclStmt for each decl.
   for (DeclStmt::reverse_decl_iterator I = DS->decl_rbegin(),
@@ -1689,16 +1950,16 @@
   bool HasTemporaries = false;
 
   // Guard static initializers under a branch.
-  CFGBlock *blockAfterStaticInit = 0;
+  CFGBlock *blockAfterStaticInit = nullptr;
 
   if (BuildOpts.AddStaticInitBranches && VD->isStaticLocal()) {
     // For static variables, we need to create a branch to track
     // whether or not they are initialized.
     if (Block) {
       Succ = Block;
-      Block = 0;
+      Block = nullptr;
       if (badCFG)
-        return 0;
+        return nullptr;
     }
     blockAfterStaticInit = Succ;
   }
@@ -1741,7 +2002,7 @@
 
   // If the type of VD is a VLA, then we must process its size expressions.
   for (const VariableArrayType* VA = FindVA(VD->getType().getTypePtr());
-       VA != 0; VA = FindVA(VA->getElementType().getTypePtr())) {
+       VA != nullptr; VA = FindVA(VA->getElementType().getTypePtr())) {
     if (CFGBlock *newBlock = addStmt(VA->getSizeExpr()))
       LastBlock = newBlock;
   }
@@ -1788,7 +2049,7 @@
   if (Block) {
     Succ = Block;
     if (badCFG)
-      return 0;
+      return nullptr;
   }
 
   // Process the false branch.
@@ -1799,7 +2060,7 @@
 
     // NULL out Block so that the recursive call to Visit will
     // create a new basic block.
-    Block = NULL;
+    Block = nullptr;
 
     // If branch is not a compound statement create implicit scope
     // and add destructors.
@@ -1812,7 +2073,7 @@
       ElseBlock = sv.get();
     else if (Block) {
       if (badCFG)
-        return 0;
+        return nullptr;
     }
   }
 
@@ -1822,7 +2083,7 @@
     Stmt *Then = I->getThen();
     assert(Then);
     SaveAndRestore<CFGBlock*> sv(Succ);
-    Block = NULL;
+    Block = nullptr;
 
     // If branch is not a compound statement create implicit scope
     // and add destructors.
@@ -1839,7 +2100,7 @@
       addSuccessor(ThenBlock, sv.get());
     } else if (Block) {
       if (badCFG)
-        return 0;
+        return nullptr;
     }
   }
 
@@ -1865,23 +2126,21 @@
   // See if this is a known constant.
   const TryResult &KnownVal = tryEvaluateBool(I->getCond());
 
-  // Now add the successors.
-  addSuccessor(Block, KnownVal.isFalse() ? NULL : ThenBlock);
-  addSuccessor(Block, KnownVal.isTrue()? NULL : ElseBlock);
+  // 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".
   CFGBlock *LastBlock = addStmt(I->getCond());
 
-  // Finally, if the IfStmt contains a condition variable, add both the IfStmt
-  // and the condition variable initialization to the CFG.
-  if (VarDecl *VD = I->getConditionVariable()) {
-    if (Expr *Init = VD->getInit()) {
-      autoCreateBlock();
-      appendStmt(Block, I->getConditionVariableDeclStmt());
-      LastBlock = addStmt(Init);
-    }
+  // Finally, 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));
   }
 
   return LastBlock;
@@ -1929,10 +2188,10 @@
   // about.
   LabelBlock->setLabel(L);
   if (badCFG)
-    return 0;
+    return nullptr;
 
   // We set Block to NULL to allow lazy creation of a new block (if necessary);
-  Block = NULL;
+  Block = nullptr;
 
   // This block is now the implicit successor of other blocks.
   Succ = LabelBlock;
@@ -1946,7 +2205,7 @@
        et = E->capture_init_end(); it != et; ++it) {
     if (Expr *Init = *it) {
       CFGBlock *Tmp = Visit(Init);
-      if (Tmp != 0)
+      if (Tmp)
         LastBlock = Tmp;
     }
   }
@@ -1976,7 +2235,7 @@
 }
 
 CFGBlock *CFGBuilder::VisitForStmt(ForStmt *F) {
-  CFGBlock *LoopSuccessor = NULL;
+  CFGBlock *LoopSuccessor = nullptr;
 
   // Save local scope position because in case of condition variable ScopePos
   // won't be restored when traversing AST.
@@ -1999,7 +2258,7 @@
   // block.
   if (Block) {
     if (badCFG)
-      return 0;
+      return nullptr;
     LoopSuccessor = Block;
   } else
     LoopSuccessor = Succ;
@@ -2009,7 +2268,7 @@
   SaveAndRestore<JumpTarget> save_break(BreakJumpTarget);
   BreakJumpTarget = JumpTarget(LoopSuccessor, ScopePos);
 
-  CFGBlock *BodyBlock = 0, *TransitionBlock = 0;
+  CFGBlock *BodyBlock = nullptr, *TransitionBlock = nullptr;
 
   // Now create the loop body.
   {
@@ -2035,8 +2294,8 @@
     if (Block) {
       assert(Block == Succ);
       if (badCFG)
-        return 0;
-      Block = 0;
+        return nullptr;
+      Block = nullptr;
     }
 
    // The starting block for the loop increment is the block that should
@@ -2062,13 +2321,13 @@
       BodyBlock = ContinueJumpTarget.block;
     }
     else if (badCFG)
-      return 0;
+      return nullptr;
   }
   
   // Because of short-circuit evaluation, the condition of the loop can span
   // multiple basic blocks.  Thus we need the "Entry" and "Exit" blocks that
   // evaluate the condition.
-  CFGBlock *EntryConditionBlock = 0, *ExitConditionBlock = 0;
+  CFGBlock *EntryConditionBlock = nullptr, *ExitConditionBlock = nullptr;
 
   do {
     Expr *C = F->getCond();
@@ -2076,9 +2335,9 @@
     // Specially handle logical operators, which have a slightly
     // more optimal CFG representation.
     if (BinaryOperator *Cond =
-            dyn_cast_or_null<BinaryOperator>(C ? C->IgnoreParens() : 0))
+            dyn_cast_or_null<BinaryOperator>(C ? C->IgnoreParens() : nullptr))
       if (Cond->isLogicalOp()) {
-        llvm::tie(EntryConditionBlock, ExitConditionBlock) =
+        std::tie(EntryConditionBlock, ExitConditionBlock) =
           VisitLogicalOperator(Cond, F, BodyBlock, LoopSuccessor);
         break;
       }
@@ -2109,16 +2368,17 @@
       }
 
       if (Block && badCFG)
-        return 0;
+        return nullptr;
 
       KnownVal = tryEvaluateBool(C);
     }
 
     // Add the loop body entry as a successor to the condition.
-    addSuccessor(ExitConditionBlock, KnownVal.isFalse() ? NULL : BodyBlock);
+    addSuccessor(ExitConditionBlock, KnownVal.isFalse() ? nullptr : BodyBlock);
     // Link up the condition block with the code that follows the loop.  (the
     // false branch).
-    addSuccessor(ExitConditionBlock, KnownVal.isTrue() ? NULL : LoopSuccessor);
+    addSuccessor(ExitConditionBlock,
+                 KnownVal.isTrue() ? nullptr : LoopSuccessor);
 
   } while (false);
 
@@ -2137,7 +2397,7 @@
 
   // There is no loop initialization.  We are thus basically a while loop.
   // NULL out Block to force lazy block construction.
-  Block = NULL;
+  Block = nullptr;
   Succ = EntryConditionBlock;
   return EntryConditionBlock;
 }
@@ -2183,13 +2443,13 @@
   //   a DeclStmt and the other returns a DeclRefExpr.
   //
 
-  CFGBlock *LoopSuccessor = 0;
+  CFGBlock *LoopSuccessor = nullptr;
 
   if (Block) {
     if (badCFG)
-      return 0;
+      return nullptr;
     LoopSuccessor = Block;
-    Block = 0;
+    Block = nullptr;
   } else
     LoopSuccessor = Succ;
 
@@ -2212,8 +2472,8 @@
                                         AddStmtChoice::NotAlwaysAdd);
   if (Block) {
     if (badCFG)
-      return 0;
-    Block = 0;
+      return nullptr;
+    Block = nullptr;
   }
 
   // The condition block is the implicit successor for the loop body as well as
@@ -2230,7 +2490,7 @@
     // Add an intermediate block between the BodyBlock and the
     // EntryConditionBlock to represent the "loop back" transition, for looping
     // back to the head of the loop.
-    CFGBlock *LoopBackBlock = 0;
+    CFGBlock *LoopBackBlock = nullptr;
     Succ = LoopBackBlock = createBlock();
     LoopBackBlock->setLoopTarget(S);
     
@@ -2243,7 +2503,7 @@
       BodyBlock = ContinueJumpTarget.block; // can happen for "for (X in Y) ;"
     else if (Block) {
       if (badCFG)
-        return 0;
+        return nullptr;
     }
 
     // This new body block is a successor to our "exit" condition block.
@@ -2275,9 +2535,9 @@
   // for diagnostic clients.
   if (SyncBlock) {
     if (badCFG)
-      return 0;
+      return nullptr;
 
-    Block = 0;
+    Block = nullptr;
     Succ = SyncBlock;
   }
 
@@ -2320,7 +2580,7 @@
 }
 
 CFGBlock *CFGBuilder::VisitWhileStmt(WhileStmt *W) {
-  CFGBlock *LoopSuccessor = NULL;
+  CFGBlock *LoopSuccessor = nullptr;
 
   // Save local scope position because in case of condition variable ScopePos
   // won't be restored when traversing AST.
@@ -2338,14 +2598,14 @@
   // block.
   if (Block) {
     if (badCFG)
-      return 0;
+      return nullptr;
     LoopSuccessor = Block;
-    Block = 0;
+    Block = nullptr;
   } else {
     LoopSuccessor = Succ;
   }
 
-  CFGBlock *BodyBlock = 0, *TransitionBlock = 0;
+  CFGBlock *BodyBlock = nullptr, *TransitionBlock = nullptr;
 
   // Process the loop body.
   {
@@ -2379,13 +2639,13 @@
     if (!BodyBlock)
       BodyBlock = ContinueJumpTarget.block; // can happen for "while(...) ;"
     else if (Block && badCFG)
-      return 0;
+      return nullptr;
   }
 
   // Because of short-circuit evaluation, the condition of the loop can span
   // multiple basic blocks.  Thus we need the "Entry" and "Exit" blocks that
   // evaluate the condition.
-  CFGBlock *EntryConditionBlock = 0, *ExitConditionBlock = 0;
+  CFGBlock *EntryConditionBlock = nullptr, *ExitConditionBlock = nullptr;
 
   do {
     Expr *C = W->getCond();
@@ -2394,9 +2654,8 @@
     // more optimal CFG representation.
     if (BinaryOperator *Cond = dyn_cast<BinaryOperator>(C->IgnoreParens()))
       if (Cond->isLogicalOp()) {
-        llvm::tie(EntryConditionBlock, ExitConditionBlock) =
-          VisitLogicalOperator(Cond, W, BodyBlock,
-                               LoopSuccessor);
+        std::tie(EntryConditionBlock, ExitConditionBlock) =
+            VisitLogicalOperator(Cond, W, BodyBlock, LoopSuccessor);
         break;
       }
 
@@ -2422,16 +2681,17 @@
     }
 
     if (Block && badCFG)
-      return 0;
+      return nullptr;
 
     // See if this is a known constant.
     const TryResult& KnownVal = tryEvaluateBool(C);
 
     // Add the loop body entry as a successor to the condition.
-    addSuccessor(ExitConditionBlock, KnownVal.isFalse() ? NULL : BodyBlock);
+    addSuccessor(ExitConditionBlock, KnownVal.isFalse() ? nullptr : BodyBlock);
     // Link up the condition block with the code that follows the loop.  (the
     // false branch).
-    addSuccessor(ExitConditionBlock, KnownVal.isTrue() ? NULL : LoopSuccessor);
+    addSuccessor(ExitConditionBlock,
+                 KnownVal.isTrue() ? nullptr : LoopSuccessor);
 
   } while(false);
 
@@ -2440,7 +2700,7 @@
 
   // There can be no more statements in the condition block since we loop back
   // to this block.  NULL out Block to force lazy creation of another block.
-  Block = NULL;
+  Block = nullptr;
 
   // Return the condition block, which is the dominating block for the loop.
   Succ = EntryConditionBlock;
@@ -2460,7 +2720,7 @@
 
   // If we were in the middle of a block we stop processing that block.
   if (badCFG)
-    return 0;
+    return nullptr;
 
   // Create the new block.
   Block = createBlock(false);
@@ -2476,7 +2736,7 @@
 CFGBlock *CFGBuilder::VisitCXXThrowExpr(CXXThrowExpr *T) {
   // If we were in the middle of a block we stop processing that block.
   if (badCFG)
-    return 0;
+    return nullptr;
 
   // Create the new block.
   Block = createBlock(false);
@@ -2494,13 +2754,13 @@
 }
 
 CFGBlock *CFGBuilder::VisitDoStmt(DoStmt *D) {
-  CFGBlock *LoopSuccessor = NULL;
+  CFGBlock *LoopSuccessor = nullptr;
 
   // "do...while" is a control-flow statement.  Thus we stop processing the
   // current block.
   if (Block) {
     if (badCFG)
-      return 0;
+      return nullptr;
     LoopSuccessor = Block;
   } else
     LoopSuccessor = Succ;
@@ -2521,7 +2781,7 @@
     EntryConditionBlock = addStmt(C);
     if (Block) {
       if (badCFG)
-        return 0;
+        return nullptr;
     }
   }
 
@@ -2532,7 +2792,7 @@
   const TryResult &KnownVal = tryEvaluateBool(D->getCond());
 
   // Process the loop body.
-  CFGBlock *BodyBlock = NULL;
+  CFGBlock *BodyBlock = nullptr;
   {
     assert(D->getBody());
 
@@ -2548,7 +2808,7 @@
     BreakJumpTarget = JumpTarget(LoopSuccessor, ScopePos);
 
     // NULL out Block to force lazy instantiation of blocks for the body.
-    Block = NULL;
+    Block = nullptr;
 
     // If body is not a compound statement create implicit scope
     // and add destructors.
@@ -2562,7 +2822,7 @@
       BodyBlock = EntryConditionBlock; // can happen for "do ; while(...)"
     else if (Block) {
       if (badCFG)
-        return 0;
+        return nullptr;
     }
 
     if (!KnownVal.isFalse()) {
@@ -2571,7 +2831,7 @@
       // empty block to represent the transition block for looping back to the
       // head of the loop.
       // FIXME: Can we do this more efficiently without adding another block?
-      Block = NULL;
+      Block = nullptr;
       Succ = BodyBlock;
       CFGBlock *LoopBackBlock = createBlock();
       LoopBackBlock->setLoopTarget(D);
@@ -2580,16 +2840,16 @@
       addSuccessor(ExitConditionBlock, LoopBackBlock);
     }
     else
-      addSuccessor(ExitConditionBlock, NULL);
+      addSuccessor(ExitConditionBlock, nullptr);
   }
 
   // Link up the condition block with the code that follows the loop.
   // (the false branch).
-  addSuccessor(ExitConditionBlock, KnownVal.isTrue() ? NULL : LoopSuccessor);
+  addSuccessor(ExitConditionBlock, KnownVal.isTrue() ? nullptr : LoopSuccessor);
 
   // There can be no more statements in the body block(s) since we loop back to
   // the body.  NULL out Block to force lazy creation of another block.
-  Block = NULL;
+  Block = nullptr;
 
   // Return the loop body, which is the dominating block for the loop.
   Succ = BodyBlock;
@@ -2600,7 +2860,7 @@
   // "continue" is a control-flow statement.  Thus we stop processing the
   // current block.
   if (badCFG)
-    return 0;
+    return nullptr;
 
   // Now create a new block that ends with the continue statement.
   Block = createBlock(false);
@@ -2630,7 +2890,7 @@
   
   if (E->isArgumentType()) {
     for (const VariableArrayType *VA =FindVA(E->getArgumentType().getTypePtr());
-         VA != 0; VA = FindVA(VA->getElementType().getTypePtr()))
+         VA != nullptr; VA = FindVA(VA->getElementType().getTypePtr()))
       lastBlock = addStmt(VA->getSizeExpr());
   }
   return lastBlock;
@@ -2649,7 +2909,7 @@
 CFGBlock *CFGBuilder::VisitSwitchStmt(SwitchStmt *Terminator) {
   // "switch" is a control-flow statement.  Thus we stop processing the current
   // block.
-  CFGBlock *SwitchSuccessor = NULL;
+  CFGBlock *SwitchSuccessor = nullptr;
 
   // Save local scope position because in case of condition variable ScopePos
   // won't be restored when traversing AST.
@@ -2665,7 +2925,7 @@
 
   if (Block) {
     if (badCFG)
-      return 0;
+      return nullptr;
     SwitchSuccessor = Block;
   } else SwitchSuccessor = Succ;
 
@@ -2691,7 +2951,7 @@
   // up to the switch.  We also don't keep a pointer to the body, since all
   // control-flow from the switch goes to case/default statements.
   assert(Terminator->getBody() && "switch must contain a non-NULL body");
-  Block = NULL;
+  Block = nullptr;
 
   // For pruning unreachable case statements, save the current state
   // for tracking the condition value.
@@ -2703,7 +2963,7 @@
   Expr::EvalResult result;
   bool b = tryEvaluate(Terminator->getCond(), result);
   SaveAndRestore<Expr::EvalResult*> save_switchCond(switchCond,
-                                                    b ? &result : 0);
+                                                    b ? &result : nullptr);
 
   // If body is not a compound statement create implicit scope
   // and add destructors.
@@ -2713,7 +2973,7 @@
   addStmt(Terminator->getBody());
   if (Block) {
     if (badCFG)
-      return 0;
+      return nullptr;
   }
 
   // If we have no "default:" case, the default transition is to the code
@@ -2726,8 +2986,8 @@
   SwitchAlwaysHasSuccessor |= switchExclusivelyCovered;
   SwitchAlwaysHasSuccessor |= Terminator->isAllEnumCasesCovered() &&
                               Terminator->getSwitchCaseList();
-  addSuccessor(SwitchTerminatedBlock,
-               SwitchAlwaysHasSuccessor ? 0 : DefaultCaseBlock);
+  addSuccessor(SwitchTerminatedBlock, DefaultCaseBlock,
+               !SwitchAlwaysHasSuccessor);
 
   // Add the terminator and condition in the switch block.
   SwitchTerminatedBlock->setTerminator(Terminator);
@@ -2786,7 +3046,7 @@
 CFGBlock *CFGBuilder::VisitCaseStmt(CaseStmt *CS) {
   // CaseStmts are essentially labels, so they are the first statement in a
   // block.
-  CFGBlock *TopBlock = 0, *LastBlock = 0;
+  CFGBlock *TopBlock = nullptr, *LastBlock = nullptr;
 
   if (Stmt *Sub = CS->getSubStmt()) {
     // For deeply nested chains of CaseStmts, instead of doing a recursion
@@ -2804,7 +3064,7 @@
       addSuccessor(SwitchTerminatedBlock,
                    shouldAddCase(switchExclusivelyCovered, switchCond,
                                  CS, *Context)
-                   ? currentBlock : 0);
+                   ? currentBlock : nullptr);
 
       LastBlock = currentBlock;
       CS = cast<CaseStmt>(Sub);
@@ -2823,18 +3083,17 @@
   CaseBlock->setLabel(CS);
 
   if (badCFG)
-    return 0;
+    return nullptr;
 
   // Add this block to the list of successors for the block with the switch
   // statement.
   assert(SwitchTerminatedBlock);
-  addSuccessor(SwitchTerminatedBlock,
+  addSuccessor(SwitchTerminatedBlock, CaseBlock,
                shouldAddCase(switchExclusivelyCovered, switchCond,
-                             CS, *Context)
-               ? CaseBlock : 0);
+                             CS, *Context));
 
   // We set Block to NULL to allow lazy creation of a new block (if necessary)
-  Block = NULL;
+  Block = nullptr;
 
   if (TopBlock) {
     addSuccessor(LastBlock, CaseBlock);
@@ -2861,7 +3120,7 @@
   DefaultCaseBlock->setLabel(Terminator);
 
   if (badCFG)
-    return 0;
+    return nullptr;
 
   // Unlike case statements, we don't add the default block to the successors
   // for the switch statement immediately.  This is done when we finish
@@ -2870,7 +3129,7 @@
   // be the last successor of a switch-terminated block.
 
   // We set Block to NULL to allow lazy creation of a new block (if necessary)
-  Block = NULL;
+  Block = nullptr;
 
   // This block is now the implicit successor of other blocks.
   Succ = DefaultCaseBlock;
@@ -2881,11 +3140,11 @@
 CFGBlock *CFGBuilder::VisitCXXTryStmt(CXXTryStmt *Terminator) {
   // "try"/"catch" is a control-flow statement.  Thus we stop processing the
   // current block.
-  CFGBlock *TrySuccessor = NULL;
+  CFGBlock *TrySuccessor = nullptr;
 
   if (Block) {
     if (badCFG)
-      return 0;
+      return nullptr;
     TrySuccessor = Block;
   } else TrySuccessor = Succ;
 
@@ -2901,13 +3160,13 @@
     // The code after the try is the implicit successor.
     Succ = TrySuccessor;
     CXXCatchStmt *CS = Terminator->getHandler(h);
-    if (CS->getExceptionDecl() == 0) {
+    if (CS->getExceptionDecl() == nullptr) {
       HasCatchAll = true;
     }
-    Block = NULL;
+    Block = nullptr;
     CFGBlock *CatchBlock = VisitCXXCatchStmt(CS);
-    if (CatchBlock == 0)
-      return 0;
+    if (!CatchBlock)
+      return nullptr;
     // Add this block to the list of successors for the block with the try
     // statement.
     addSuccessor(NewTryTerminatedBlock, CatchBlock);
@@ -2927,7 +3186,7 @@
   cfg->addTryDispatchBlock(TryTerminatedBlock);
 
   assert(Terminator->getTryBlock() && "try must contain a non-NULL body");
-  Block = NULL;
+  Block = nullptr;
   return addStmt(Terminator->getTryBlock());
 }
 
@@ -2966,10 +3225,10 @@
 
   // Bail out if the CFG is bad.
   if (badCFG)
-    return 0;
+    return nullptr;
 
   // We set Block to NULL to allow lazy creation of a new block (if necessary)
-  Block = NULL;
+  Block = nullptr;
 
   return CatchBlock;
 }
@@ -3002,10 +3261,10 @@
 
   // "for" is a control-flow statement.  Thus we stop processing the current
   // block.
-  CFGBlock *LoopSuccessor = NULL;
+  CFGBlock *LoopSuccessor = nullptr;
   if (Block) {
     if (badCFG)
-      return 0;
+      return nullptr;
     LoopSuccessor = Block;
   } else
     LoopSuccessor = Succ;
@@ -3024,7 +3283,7 @@
     Block = ConditionBlock;
     CFGBlock *BeginConditionBlock = addStmt(C);
     if (badCFG)
-      return 0;
+      return nullptr;
     assert(BeginConditionBlock == ConditionBlock &&
            "condition block in for-range was unexpectedly complex");
     (void)BeginConditionBlock;
@@ -3050,7 +3309,7 @@
 
     // Generate increment code in its own basic block.  This is the target of
     // continue statements.
-    Block = 0;
+    Block = nullptr;
     Succ = addStmt(S->getInc());
     ContinueJumpTarget = JumpTarget(Succ, ContinueScopePos);
 
@@ -3061,9 +3320,8 @@
     // Finish up the increment block and prepare to start the loop body.
     assert(Block);
     if (badCFG)
-      return 0;
-    Block = 0;
-
+      return nullptr;
+    Block = nullptr;
 
     // Add implicit scope and dtors for loop variable.
     addLocalScopeAndDtors(S->getLoopVarStmt());
@@ -3071,18 +3329,19 @@
     // Populate a new block to contain the loop body and loop variable.
     addStmt(S->getBody());
     if (badCFG)
-      return 0;
+      return nullptr;
     CFGBlock *LoopVarStmtBlock = addStmt(S->getLoopVarStmt());
     if (badCFG)
-      return 0;
-    
+      return nullptr;
+
     // This new body block is a successor to our condition block.
-    addSuccessor(ConditionBlock, KnownVal.isFalse() ? 0 : LoopVarStmtBlock);
+    addSuccessor(ConditionBlock,
+                 KnownVal.isFalse() ? nullptr : LoopVarStmtBlock);
   }
 
   // Link up the condition block with the code that follows the loop (the
   // false branch).
-  addSuccessor(ConditionBlock, KnownVal.isTrue() ? 0 : LoopSuccessor);
+  addSuccessor(ConditionBlock, KnownVal.isTrue() ? nullptr : LoopSuccessor);
 
   // Add the initialization statements.
   Block = createBlock();
@@ -3124,6 +3383,23 @@
   return VisitChildren(C);
 }
 
+CFGBlock *CFGBuilder::VisitCXXNewExpr(CXXNewExpr *NE,
+                                      AddStmtChoice asc) {
+
+  autoCreateBlock();
+  appendStmt(Block, NE);
+
+  if (NE->getInitializer())
+    Block = Visit(NE->getInitializer());
+  if (BuildOpts.AddCXXNewAllocator)
+    appendNewAllocator(Block, NE);
+  if (NE->isArray())
+    Block = Visit(NE->getArraySize());
+  for (CXXNewExpr::arg_iterator I = NE->placement_arg_begin(),
+       E = NE->placement_arg_end(); I != E; ++I)
+    Block = Visit(*I);
+  return Block;
+}
 
 CFGBlock *CFGBuilder::VisitCXXDeleteExpr(CXXDeleteExpr *DE,
                                          AddStmtChoice asc) {
@@ -3179,7 +3455,7 @@
   // IndirectGoto is a control-flow statement.  Thus we stop processing the
   // current block and create a new one.
   if (badCFG)
-    return 0;
+    return nullptr;
 
   Block = createBlock(false);
   Block->setTerminator(I);
@@ -3193,7 +3469,7 @@
 tryAgain:
   if (!E) {
     badCFG = true;
-    return NULL;
+    return nullptr;
   }
   switch (E->getStmtClass()) {
     default:
@@ -3219,10 +3495,35 @@
     case Stmt::ParenExprClass:
       E = cast<ParenExpr>(E)->getSubExpr();
       goto tryAgain;
-      
+
     case Stmt::MaterializeTemporaryExprClass:
       E = cast<MaterializeTemporaryExpr>(E)->GetTemporaryExpr();
       goto tryAgain;
+
+    case Stmt::BlockExprClass:
+      // Don't recurse into blocks; their subexpressions don't get evaluated
+      // here.
+      return Block;
+
+    case Stmt::LambdaExprClass: {
+      // For lambda expressions, only recurse into the capture initializers,
+      // and not the body.
+      auto *LE = cast<LambdaExpr>(E);
+      CFGBlock *B = Block;
+      for (Expr *Init : LE->capture_inits()) {
+        if (CFGBlock *R = VisitForTemporaryDtors(Init))
+          B = R;
+      }
+      return B;
+    }
+
+    case Stmt::CXXDefaultArgExprClass:
+      E = cast<CXXDefaultArgExpr>(E)->getExpr();
+      goto tryAgain;
+
+    case Stmt::CXXDefaultInitExprClass:
+      E = cast<CXXDefaultInitExpr>(E)->getExpr();
+      goto tryAgain;
   }
 }
 
@@ -3248,15 +3549,15 @@
     autoCreateBlock();
     CFGBlock *ConfluenceBlock = VisitForTemporaryDtors(E->getLHS());
     if (badCFG)
-      return NULL;
+      return nullptr;
 
     Succ = ConfluenceBlock;
-    Block = NULL;
+    Block = nullptr;
     CFGBlock *RHSBlock = VisitForTemporaryDtors(E->getRHS());
 
     if (RHSBlock) {
       if (badCFG)
-        return NULL;
+        return nullptr;
 
       // If RHS expression did produce destructors we need to connect created
       // blocks to CFG in same manner as for binary operator itself.
@@ -3276,12 +3577,12 @@
       // Link LHSBlock with RHSBlock exactly the same way as for binary operator
       // itself.
       if (E->getOpcode() == BO_LOr) {
-        addSuccessor(LHSBlock, KnownVal.isTrue() ? NULL : ConfluenceBlock);
-        addSuccessor(LHSBlock, KnownVal.isFalse() ? NULL : RHSBlock);
+        addSuccessor(LHSBlock, KnownVal.isTrue() ? nullptr : ConfluenceBlock);
+        addSuccessor(LHSBlock, KnownVal.isFalse() ? nullptr : RHSBlock);
       } else {
         assert (E->getOpcode() == BO_LAnd);
-        addSuccessor(LHSBlock, KnownVal.isFalse() ? NULL : RHSBlock);
-        addSuccessor(LHSBlock, KnownVal.isTrue() ? NULL : ConfluenceBlock);
+        addSuccessor(LHSBlock, KnownVal.isFalse() ? nullptr : RHSBlock);
+        addSuccessor(LHSBlock, KnownVal.isTrue() ? nullptr : ConfluenceBlock);
       }
 
       Block = LHSBlock;
@@ -3320,10 +3621,12 @@
     // a new block for the destructor which does not have as a successor
     // anything built thus far. Control won't flow out of this block.
     const CXXDestructorDecl *Dtor = E->getTemporary()->getDestructor();
-    if (Dtor->isNoReturn())
+    if (Dtor->isNoReturn()) {
+      Succ = B;
       Block = createNoReturnBlock();
-    else
+    } else {
       autoCreateBlock();
+    }
 
     appendTemporaryDtor(Block, E);
     B = Block;
@@ -3339,29 +3642,29 @@
   autoCreateBlock();
   CFGBlock *ConfluenceBlock = VisitForTemporaryDtors(E->getCond());
   if (badCFG)
-    return NULL;
+    return nullptr;
   if (BinaryConditionalOperator *BCO
         = dyn_cast<BinaryConditionalOperator>(E)) {
     ConfluenceBlock = VisitForTemporaryDtors(BCO->getCommon());
     if (badCFG)
-      return NULL;
+      return nullptr;
   }
 
   // Try to add block with destructors for LHS expression.
-  CFGBlock *LHSBlock = NULL;
+  CFGBlock *LHSBlock = nullptr;
   Succ = ConfluenceBlock;
-  Block = NULL;
+  Block = nullptr;
   LHSBlock = VisitForTemporaryDtors(E->getTrueExpr(), BindToTemporary);
   if (badCFG)
-    return NULL;
+    return nullptr;
 
   // Try to add block with destructors for RHS expression;
   Succ = ConfluenceBlock;
-  Block = NULL;
+  Block = nullptr;
   CFGBlock *RHSBlock = VisitForTemporaryDtors(E->getFalseExpr(),
                                               BindToTemporary);
   if (badCFG)
-    return NULL;
+    return nullptr;
 
   if (!RHSBlock && !LHSBlock) {
     // If neither LHS nor RHS expression had temporaries to destroy don't create
@@ -3372,14 +3675,15 @@
 
   Block = createBlock(false);
   Block->setTerminator(CFGTerminator(E, true));
+  assert(Block->getTerminator().isTemporaryDtorsBranch());
 
   // See if this is a known constant.
   const TryResult &KnownVal = tryEvaluateBool(E->getCond());
 
   if (LHSBlock) {
-    addSuccessor(Block, KnownVal.isFalse() ? NULL : LHSBlock);
+    addSuccessor(Block, LHSBlock, !KnownVal.isFalse());
   } else if (KnownVal.isFalse()) {
-    addSuccessor(Block, NULL);
+    addSuccessor(Block, nullptr);
   } else {
     addSuccessor(Block, ConfluenceBlock);
     std::reverse(ConfluenceBlock->pred_begin(), ConfluenceBlock->pred_end());
@@ -3387,7 +3691,8 @@
 
   if (!RHSBlock)
     RHSBlock = ConfluenceBlock;
-  addSuccessor(Block, KnownVal.isTrue() ? NULL : RHSBlock);
+
+  addSuccessor(Block, RHSBlock, !KnownVal.isTrue());
 
   return Block;
 }
@@ -3426,6 +3731,7 @@
   switch (getKind()) {
     case CFGElement::Statement:
     case CFGElement::Initializer:
+    case CFGElement::NewAllocator:
       llvm_unreachable("getDestructorDecl should only be used with "
                        "ImplicitDtors");
     case CFGElement::AutomaticObjectDtor: {
@@ -3458,7 +3764,7 @@
     case CFGElement::MemberDtor:
 
       // Not yet supported.
-      return 0;
+      return nullptr;
   }
   llvm_unreachable("getKind() returned bogus value");
 }
@@ -3470,13 +3776,37 @@
 }
 
 //===----------------------------------------------------------------------===//
-// Filtered walking of the CFG.
+// CFGBlock operations.
 //===----------------------------------------------------------------------===//
 
+CFGBlock::AdjacentBlock::AdjacentBlock(CFGBlock *B, bool IsReachable)
+  : ReachableBlock(IsReachable ? B : nullptr),
+    UnreachableBlock(!IsReachable ? B : nullptr,
+                     B && IsReachable ? AB_Normal : AB_Unreachable) {}
+
+CFGBlock::AdjacentBlock::AdjacentBlock(CFGBlock *B, CFGBlock *AlternateBlock)
+  : ReachableBlock(B),
+    UnreachableBlock(B == AlternateBlock ? nullptr : AlternateBlock,
+                     B == AlternateBlock ? AB_Alternate : AB_Normal) {}
+
+void CFGBlock::addSuccessor(AdjacentBlock Succ,
+                            BumpVectorContext &C) {
+  if (CFGBlock *B = Succ.getReachableBlock())
+    B->Preds.push_back(AdjacentBlock(this, Succ.isReachable()), C);
+
+  if (CFGBlock *UnreachableB = Succ.getPossiblyUnreachableBlock())
+    UnreachableB->Preds.push_back(AdjacentBlock(this, false), C);
+
+  Succs.push_back(Succ, C);
+}
+
 bool CFGBlock::FilterEdge(const CFGBlock::FilterOptions &F,
         const CFGBlock *From, const CFGBlock *To) {
 
-  if (To && F.IgnoreDefaultsWithCoveredEnums) {
+  if (F.IgnoreNullPredecessors && !From)
+    return true;
+
+  if (To && From && F.IgnoreDefaultsWithCoveredEnums) {
     // If the 'To' has no label or is labeled but the label isn't a
     // CaseStmt then filter this edge.
     if (const SwitchStmt *S =
@@ -3572,7 +3902,7 @@
   void setBlockID(signed i) { currentBlock = i; }
   void setStmtID(unsigned i) { currStmt = i; }
 
-  virtual bool handledStmt(Stmt *S, raw_ostream &OS) {
+  bool handledStmt(Stmt *S, raw_ostream &OS) override {
     StmtMapTy::iterator I = StmtMap.find(S);
 
     if (I == StmtMap.end())
@@ -3615,11 +3945,14 @@
 public:
   CFGBlockTerminatorPrint(raw_ostream &os, StmtPrinterHelper* helper,
                           const PrintingPolicy &Policy)
-    : OS(os), Helper(helper), Policy(Policy) {}
+    : OS(os), Helper(helper), Policy(Policy) {
+    this->Policy.IncludeNewlines = false;
+  }
 
   void VisitIfStmt(IfStmt *I) {
     OS << "if ";
-    I->getCond()->printPretty(OS,Helper,Policy);
+    if (Stmt *C = I->getCond())
+      C->printPretty(OS, Helper, Policy);
   }
 
   // Default case.
@@ -3667,19 +4000,22 @@
   }
 
   void VisitAbstractConditionalOperator(AbstractConditionalOperator* C) {
-    C->getCond()->printPretty(OS, Helper, Policy);
+    if (Stmt *Cond = C->getCond())
+      Cond->printPretty(OS, Helper, Policy);
     OS << " ? ... : ...";
   }
 
   void VisitChooseExpr(ChooseExpr *C) {
     OS << "__builtin_choose_expr( ";
-    C->getCond()->printPretty(OS, Helper, Policy);
+    if (Stmt *Cond = C->getCond())
+      Cond->printPretty(OS, Helper, Policy);
     OS << " )";
   }
 
   void VisitIndirectGotoStmt(IndirectGotoStmt *I) {
     OS << "goto *";
-    I->getTarget()->printPretty(OS, Helper, Policy);
+    if (Stmt *T = I->getTarget())
+      T->printPretty(OS, Helper, Policy);
   }
 
   void VisitBinaryOperator(BinaryOperator* B) {
@@ -3688,7 +4024,8 @@
       return;
     }
 
-    B->getLHS()->printPretty(OS, Helper, Policy);
+    if (B->getLHS())
+      B->getLHS()->printPretty(OS, Helper, Policy);
 
     switch (B->getOpcode()) {
       case BO_LOr:
@@ -3705,6 +4042,13 @@
   void VisitExpr(Expr *E) {
     E->printPretty(OS, Helper, Policy);
   }
+
+public:
+  void print(CFGTerminator T) {
+    if (T.isTemporaryDtorsBranch())
+      OS << "(Temp Dtor) ";
+    Visit(T.getStmt());
+  }
 };
 } // end anonymous namespace
 
@@ -3712,7 +4056,8 @@
                        const CFGElement &E) {
   if (Optional<CFGStmt> CS = E.getAs<CFGStmt>()) {
     const Stmt *S = CS->getStmt();
-    
+    assert(S != nullptr && "Expecting non-null Stmt");
+
     // special printing for statement-expressions.
     if (const StmtExpr *SE = dyn_cast<StmtExpr>(S)) {
       const CompoundStmt *Sub = SE->getSubStmt();
@@ -3787,6 +4132,11 @@
     OS << ".~" << T->getAsCXXRecordDecl()->getName().str() << "()";
     OS << " (Implicit destructor)\n";
 
+  } else if (Optional<CFGNewAllocator> NE = E.getAs<CFGNewAllocator>()) {
+    OS << "CFGNewAllocator(";
+    if (const CXXNewExpr *AllocExpr = NE->getAllocatorExpr())
+      AllocExpr->getType().print(OS, PrintingPolicy(Helper.getLangOpts()));
+    OS << ")\n";
   } else if (Optional<CFGDeleteDtor> DE = E.getAs<CFGDeleteDtor>()) {
     const CXXRecordDecl *RD = DE->getCXXRecordDecl();
     if (!RD)
@@ -3835,6 +4185,8 @@
     OS << " (EXIT)]\n";
   else if (&B == cfg->getIndirectGotoBlock())
     OS << " (INDIRECT GOTO DISPATCH)]\n";
+  else if (B.hasNoReturnElement())
+    OS << " (NORETURN)]\n";
   else
     OS << "]\n";
   
@@ -3851,8 +4203,9 @@
       OS << L->getName();
     else if (CaseStmt *C = dyn_cast<CaseStmt>(Label)) {
       OS << "case ";
-      C->getLHS()->printPretty(OS, &Helper,
-                               PrintingPolicy(Helper.getLangOpts()));
+      if (C->getLHS())
+        C->getLHS()->printPretty(OS, &Helper,
+                                 PrintingPolicy(Helper.getLangOpts()));
       if (C->getRHS()) {
         OS << " ... ";
         C->getRHS()->printPretty(OS, &Helper,
@@ -3903,7 +4256,7 @@
 
     PrintingPolicy PP(Helper.getLangOpts());
     CFGBlockTerminatorPrint TPrinter(OS, &Helper, PP);
-    TPrinter.Visit(const_cast<Stmt*>(B.getTerminator().getStmt()));
+    TPrinter.print(B.getTerminator());
     OS << '\n';
     
     if (ShowColors)
@@ -3931,7 +4284,16 @@
         if (i % 10 == 8)
           OS << "\n     ";
 
-        OS << " B" << (*I)->getBlockID();
+        CFGBlock *B = *I;
+        bool Reachable = true;
+        if (!B) {
+          Reachable = false;
+          B = I->getPossiblyUnreachableBlock();
+        }
+
+        OS << " B" << B->getBlockID();
+        if (!Reachable)
+          OS << "(Unreachable)";
       }
       
       if (ShowColors)
@@ -3960,12 +4322,24 @@
         if (i % 10 == 8)
           OS << "\n    ";
 
-        if (*I)
-          OS << " B" << (*I)->getBlockID();
-        else
-          OS  << " NULL";
+        CFGBlock *B = *I;
+
+        bool Reachable = true;
+        if (!B) {
+          Reachable = false;
+          B = I->getPossiblyUnreachableBlock();
+        }
+
+        if (B) {
+          OS << " B" << B->getBlockID();
+          if (!Reachable)
+            OS << "(Unreachable)";
+        }
+        else {
+          OS << " NULL";
+        }
       }
-      
+
       if (ShowColors)
         OS.resetColor();
       OS << '\n';
@@ -4007,6 +4381,10 @@
   print(llvm::errs(), cfg, LO, ShowColors);
 }
 
+void CFGBlock::dump() const {
+  dump(getParent(), LangOptions(), false);
+}
+
 /// print - A simple pretty printer of a CFGBlock that outputs to an ostream.
 ///   Generally this will only be called from CFG::print.
 void CFGBlock::print(raw_ostream &OS, const CFG* cfg,
@@ -4019,16 +4397,16 @@
 /// printTerminator - A simple pretty printer of the terminator of a CFGBlock.
 void CFGBlock::printTerminator(raw_ostream &OS,
                                const LangOptions &LO) const {
-  CFGBlockTerminatorPrint TPrinter(OS, NULL, PrintingPolicy(LO));
-  TPrinter.Visit(const_cast<Stmt*>(getTerminator().getStmt()));
+  CFGBlockTerminatorPrint TPrinter(OS, nullptr, PrintingPolicy(LO));
+  TPrinter.print(getTerminator());
 }
 
-Stmt *CFGBlock::getTerminatorCondition() {
+Stmt *CFGBlock::getTerminatorCondition(bool StripParens) {
   Stmt *Terminator = this->Terminator;
   if (!Terminator)
-    return NULL;
+    return nullptr;
 
-  Expr *E = NULL;
+  Expr *E = nullptr;
 
   switch (Terminator->getStmtClass()) {
     default:
@@ -4082,7 +4460,10 @@
       return Terminator;
   }
 
-  return E ? E->IgnoreParens() : NULL;
+  if (!StripParens)
+    return E;
+
+  return E ? E->IgnoreParens() : nullptr;
 }
 
 //===----------------------------------------------------------------------===//
@@ -4099,7 +4480,7 @@
   StmtPrinterHelper H(this, LO);
   GraphHelper = &H;
   llvm::ViewGraph(this,"CFG");
-  GraphHelper = NULL;
+  GraphHelper = nullptr;
 #endif
 }
 
diff --git a/lib/Analysis/CFGReachabilityAnalysis.cpp b/lib/Analysis/CFGReachabilityAnalysis.cpp
index 492e66f..4ae135f 100644
--- a/lib/Analysis/CFGReachabilityAnalysis.cpp
+++ b/lib/Analysis/CFGReachabilityAnalysis.cpp
@@ -69,7 +69,8 @@
     // Add the predecessors to the worklist.
     for (CFGBlock::const_pred_iterator i = block->pred_begin(), 
          e = block->pred_end(); i != e; ++i) {
-      worklist.push_back(*i);
+      if (*i)
+        worklist.push_back(*i);
     }
   }
 }
diff --git a/lib/Analysis/CFGStmtMap.cpp b/lib/Analysis/CFGStmtMap.cpp
index 87c2f5b..19b8019 100644
--- a/lib/Analysis/CFGStmtMap.cpp
+++ b/lib/Analysis/CFGStmtMap.cpp
@@ -42,8 +42,8 @@
 
     X = PM->getParentIgnoreParens(X);
   }
-  
-  return 0;
+
+  return nullptr;
 }
 
 static void Accumulate(SMap &SM, CFGBlock *B) {
@@ -77,7 +77,7 @@
 
 CFGStmtMap *CFGStmtMap::Build(CFG *C, ParentMap *PM) {
   if (!C || !PM)
-    return 0;
+    return nullptr;
 
   SMap *SM = new SMap();
 
diff --git a/lib/Analysis/CMakeLists.txt b/lib/Analysis/CMakeLists.txt
index deab8f1..461ffb0 100644
--- a/lib/Analysis/CMakeLists.txt
+++ b/lib/Analysis/CMakeLists.txt
@@ -1,3 +1,7 @@
+set(LLVM_LINK_COMPONENTS
+  Support
+  )
+
 add_clang_library(clangAnalysis
   AnalysisDeclContext.cpp
   BodyFarm.cpp
@@ -18,20 +22,13 @@
   ReachableCode.cpp
   ScanfFormatString.cpp
   ThreadSafety.cpp
+  ThreadSafetyCommon.cpp
+  ThreadSafetyLogical.cpp
+  ThreadSafetyTIL.cpp
   UninitializedValues.cpp
-  )
 
-add_dependencies(clangAnalysis
-  ClangAttrClasses
-  ClangAttrList
-  ClangCommentNodes
-  ClangDiagnosticCommon
-  ClangDeclNodes
-  ClangDiagnosticAnalysis
-  ClangStmtNodes
-  )
-
-target_link_libraries(clangAnalysis
-  clangBasic
+  LINK_LIBS
   clangAST
+  clangBasic
+  clangLex
   )
diff --git a/lib/Analysis/CallGraph.cpp b/lib/Analysis/CallGraph.cpp
index 3387015..f41a96d 100644
--- a/lib/Analysis/CallGraph.cpp
+++ b/lib/Analysis/CallGraph.cpp
@@ -10,8 +10,6 @@
 //  This file defines the AST-based CallGraph.
 //
 //===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "CallGraph"
-
 #include "clang/Analysis/CallGraph.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
@@ -22,6 +20,8 @@
 
 using namespace clang;
 
+#define DEBUG_TYPE "CallGraph"
+
 STATISTIC(NumObjCCallEdges, "Number of Objective-C method call edges");
 STATISTIC(NumBlockCallEdges, "Number of block call edges");
 
@@ -49,7 +49,7 @@
       return Block->getBlockDecl();
     }
 
-    return 0;
+    return nullptr;
   }
 
   void addCalledDecl(Decl *D) {
@@ -70,7 +70,7 @@
       Selector Sel = ME->getSelector();
       
       // Find the callee definition within the same translation unit.
-      Decl *D = 0;
+      Decl *D = nullptr;
       if (ME->isInstanceMessage())
         D = IDecl->lookupPrivateMethod(Sel);
       else
@@ -95,23 +95,17 @@
   if (BlockDecl *BD = dyn_cast<BlockDecl>(D))
     addNodeForDecl(BD, true);
 
-  for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
-       I!=E; ++I)
-    if (DeclContext *DC = dyn_cast<DeclContext>(*I))
+  for (auto *I : D->decls())
+    if (auto *DC = dyn_cast<DeclContext>(I))
       addNodesForBlocks(DC);
 }
 
 CallGraph::CallGraph() {
-  Root = getOrInsertNode(0);
+  Root = getOrInsertNode(nullptr);
 }
 
 CallGraph::~CallGraph() {
-  if (!FunctionMap.empty()) {
-    for (FunctionMapTy::iterator I = FunctionMap.begin(), E = FunctionMap.end();
-        I != E; ++I)
-      delete I->second;
-    FunctionMap.clear();
-  }
+  llvm::DeleteContainerSeconds(FunctionMap);
 }
 
 bool CallGraph::includeInGraph(const Decl *D) {
@@ -153,7 +147,7 @@
 
 CallGraphNode *CallGraph::getNode(const Decl *F) const {
   FunctionMapTy::const_iterator I = FunctionMap.find(F);
-  if (I == FunctionMap.end()) return 0;
+  if (I == FunctionMap.end()) return nullptr;
   return I->second;
 }
 
@@ -164,7 +158,7 @@
 
   Node = new CallGraphNode(F);
   // Make Root node a parent of all functions to make sure all are reachable.
-  if (F != 0)
+  if (F)
     Root->addCallee(Node, this);
   return Node;
 }
diff --git a/lib/Analysis/Consumed.cpp b/lib/Analysis/Consumed.cpp
index b33c8d8..2b2da2c 100644
--- a/lib/Analysis/Consumed.cpp
+++ b/lib/Analysis/Consumed.cpp
@@ -17,20 +17,20 @@
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/RecursiveASTVisitor.h"
-#include "clang/AST/StmtVisitor.h"
 #include "clang/AST/StmtCXX.h"
+#include "clang/AST/StmtVisitor.h"
 #include "clang/AST/Type.h"
+#include "clang/Analysis/Analyses/Consumed.h"
 #include "clang/Analysis/Analyses/PostOrderCFGView.h"
 #include "clang/Analysis/AnalysisContext.h"
 #include "clang/Analysis/CFG.h"
-#include "clang/Analysis/Analyses/Consumed.h"
 #include "clang/Basic/OperatorKinds.h"
 #include "clang/Basic/SourceLocation.h"
 #include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/raw_ostream.h"
+#include <memory>
 
 // TODO: Adjust states of args to constructors in the same way that arguments to
 //       function calls are handled.
@@ -57,11 +57,9 @@
 static SourceLocation getFirstStmtLoc(const CFGBlock *Block) {
   // Find the source location of the first statement in the block, if the block
   // is not empty.
-  for (CFGBlock::const_iterator BI = Block->begin(), BE = Block->end();
-       BI != BE; ++BI) {
-    if (Optional<CFGStmt> CS = BI->getAs<CFGStmt>())
+  for (const auto &B : *Block)
+    if (Optional<CFGStmt> CS = B.getAs<CFGStmt>())
       return CS->getStmt()->getLocStart();
-  }
 
   // Block is empty.
   // If we have one successor, return the first statement in that block
@@ -115,14 +113,10 @@
 static bool isCallableInState(const CallableWhenAttr *CWAttr,
                               ConsumedState State) {
   
-  CallableWhenAttr::callableState_iterator I = CWAttr->callableState_begin(),
-                                           E = CWAttr->callableState_end();
-  
-  for (; I != E; ++I) {
-    
+  for (const auto &S : CWAttr->callableStates()) {
     ConsumedState MappedAttrState = CS_None;
-    
-    switch (*I) {
+
+    switch (S) {
     case CallableWhenAttr::Unknown:
       MappedAttrState = CS_Unknown;
       break;
@@ -143,6 +137,7 @@
   return false;
 }
 
+
 static bool isConsumableType(const QualType &QT) {
   if (QT->isPointerType() || QT->isReferenceType())
     return false;
@@ -153,6 +148,23 @@
   return false;
 }
 
+static bool isAutoCastType(const QualType &QT) {
+  if (QT->isPointerType() || QT->isReferenceType())
+    return false;
+
+  if (const CXXRecordDecl *RD = QT->getAsCXXRecordDecl())
+    return RD->hasAttr<ConsumableAutoCastAttr>();
+
+  return false;
+}
+
+static bool isSetOnReadPtrType(const QualType &QT) {
+  if (const CXXRecordDecl *RD = QT->getPointeeCXXRecordDecl())
+    return RD->hasAttr<ConsumableSetOnReadAttr>();
+  return false;
+}
+
+
 static bool isKnownState(ConsumedState State) {
   switch (State) {
   case CS_Unconsumed:
@@ -165,19 +177,16 @@
   llvm_unreachable("invalid enum");
 }
 
-static bool isRValueRefish(QualType ParamType) {
-  return ParamType->isRValueReferenceType() ||
-        (ParamType->isLValueReferenceType() &&
-         !cast<LValueReferenceType>(
-           ParamType.getCanonicalType())->isSpelledAsLValue());
+static bool isRValueRef(QualType ParamType) {
+  return ParamType->isRValueReferenceType();
 }
 
 static bool isTestingFunction(const FunctionDecl *FunDecl) {
   return FunDecl->hasAttr<TestTypestateAttr>();
 }
 
-static bool isValueType(QualType ParamType) {
-  return !(ParamType->isPointerType() || ParamType->isReferenceType());
+static bool isPointerOrRef(QualType ParamType) {
+  return ParamType->isPointerType() || ParamType->isReferenceType();
 }
 
 static ConsumedState mapConsumableAttrState(const QualType QT) {
@@ -455,15 +464,29 @@
   ConsumedAnalyzer &Analyzer;
   ConsumedStateMap *StateMap;
   MapType PropagationMap;
-  void forwardInfo(const Stmt *From, const Stmt *To);
-  bool isLikeMoveAssignment(const CXXMethodDecl *MethodDecl);
-  void propagateReturnType(const Stmt *Call, const FunctionDecl *Fun,
-                           QualType ReturnType);
+
+  InfoEntry findInfo(const Expr *E) {
+    return PropagationMap.find(E->IgnoreParens());
+  }
+  ConstInfoEntry findInfo(const Expr *E) const {
+    return PropagationMap.find(E->IgnoreParens());
+  }
+  void insertInfo(const Expr *E, const PropagationInfo &PI) {
+    PropagationMap.insert(PairType(E->IgnoreParens(), PI));
+  }
+
+  void forwardInfo(const Expr *From, const Expr *To);
+  void copyInfo(const Expr *From, const Expr *To, ConsumedState CS);
+  ConsumedState getInfo(const Expr *From);
+  void setInfo(const Expr *To, ConsumedState NS);
+  void propagateReturnType(const Expr *Call, const FunctionDecl *Fun);
 
 public:
   void checkCallability(const PropagationInfo &PInfo,
                         const FunctionDecl *FunDecl,
                         SourceLocation BlameLoc);
+  bool handleCall(const CallExpr *Call, const Expr *ObjArg,
+                  const FunctionDecl *FunD);
   
   void VisitBinaryOperator(const BinaryOperator *BinOp);
   void VisitCallExpr(const CallExpr *Call);
@@ -485,8 +508,8 @@
                       ConsumedStateMap *StateMap)
       : AC(AC), Analyzer(Analyzer), StateMap(StateMap) {}
   
-  PropagationInfo getInfo(const Stmt *StmtNode) const {
-    ConstInfoEntry Entry = PropagationMap.find(StmtNode);
+  PropagationInfo getInfo(const Expr *StmtNode) const {
+    ConstInfoEntry Entry = findInfo(StmtNode);
     
     if (Entry != PropagationMap.end())
       return Entry->second;
@@ -499,76 +522,187 @@
   }
 };
 
+
+void ConsumedStmtVisitor::forwardInfo(const Expr *From, const Expr *To) {
+  InfoEntry Entry = findInfo(From);
+  if (Entry != PropagationMap.end())
+    insertInfo(To, Entry->second);
+}
+
+
+// Create a new state for To, which is initialized to the state of From.
+// If NS is not CS_None, sets the state of From to NS.
+void ConsumedStmtVisitor::copyInfo(const Expr *From, const Expr *To,
+                                   ConsumedState NS) {
+  InfoEntry Entry = findInfo(From);
+  if (Entry != PropagationMap.end()) {
+    PropagationInfo& PInfo = Entry->second;
+    ConsumedState CS = PInfo.getAsState(StateMap);
+    if (CS != CS_None)
+      insertInfo(To, PropagationInfo(CS));
+    if (NS != CS_None && PInfo.isPointerToValue())
+      setStateForVarOrTmp(StateMap, PInfo, NS);
+  }
+}
+
+
+// Get the ConsumedState for From
+ConsumedState ConsumedStmtVisitor::getInfo(const Expr *From) {
+  InfoEntry Entry = findInfo(From);
+  if (Entry != PropagationMap.end()) {
+    PropagationInfo& PInfo = Entry->second;
+    return PInfo.getAsState(StateMap);
+  }
+  return CS_None;
+}
+
+
+// If we already have info for To then update it, otherwise create a new entry.
+void ConsumedStmtVisitor::setInfo(const Expr *To, ConsumedState NS) {
+  InfoEntry Entry = findInfo(To);
+  if (Entry != PropagationMap.end()) {
+    PropagationInfo& PInfo = Entry->second;
+    if (PInfo.isPointerToValue())
+      setStateForVarOrTmp(StateMap, PInfo, NS);
+  } else if (NS != CS_None) {
+     insertInfo(To, PropagationInfo(NS));
+  }
+}
+
+
+
 void ConsumedStmtVisitor::checkCallability(const PropagationInfo &PInfo,
                                            const FunctionDecl *FunDecl,
                                            SourceLocation BlameLoc) {
   assert(!PInfo.isTest());
-  
-  if (!FunDecl->hasAttr<CallableWhenAttr>())
-    return;
-  
+
   const CallableWhenAttr *CWAttr = FunDecl->getAttr<CallableWhenAttr>();
-  
+  if (!CWAttr)
+    return;
+
   if (PInfo.isVar()) {
     ConsumedState VarState = StateMap->getState(PInfo.getVar());
-    
+
     if (VarState == CS_None || isCallableInState(CWAttr, VarState))
       return;
-    
+
     Analyzer.WarningsHandler.warnUseInInvalidState(
       FunDecl->getNameAsString(), PInfo.getVar()->getNameAsString(),
       stateToString(VarState), BlameLoc);
-    
+
   } else {
     ConsumedState TmpState = PInfo.getAsState(StateMap);
-    
+
     if (TmpState == CS_None || isCallableInState(CWAttr, TmpState))
       return;
-    
+
     Analyzer.WarningsHandler.warnUseOfTempInInvalidState(
       FunDecl->getNameAsString(), stateToString(TmpState), BlameLoc);
   }
 }
 
-void ConsumedStmtVisitor::forwardInfo(const Stmt *From, const Stmt *To) {
-  InfoEntry Entry = PropagationMap.find(From);
-  
-  if (Entry != PropagationMap.end())
-    PropagationMap.insert(PairType(To, Entry->second));
+
+// Factors out common behavior for function, method, and operator calls.
+// Check parameters and set parameter state if necessary.
+// Returns true if the state of ObjArg is set, or false otherwise.
+bool ConsumedStmtVisitor::handleCall(const CallExpr *Call, const Expr *ObjArg,
+                                     const FunctionDecl *FunD) {
+  unsigned Offset = 0;
+  if (isa<CXXOperatorCallExpr>(Call) && isa<CXXMethodDecl>(FunD))
+    Offset = 1;  // first argument is 'this'
+
+  // check explicit parameters
+  for (unsigned Index = Offset; Index < Call->getNumArgs(); ++Index) {
+    // Skip variable argument lists.
+    if (Index - Offset >= FunD->getNumParams())
+      break;
+
+    const ParmVarDecl *Param = FunD->getParamDecl(Index - Offset);
+    QualType ParamType = Param->getType();
+
+    InfoEntry Entry = findInfo(Call->getArg(Index));
+
+    if (Entry == PropagationMap.end() || Entry->second.isTest())
+      continue;
+    PropagationInfo PInfo = Entry->second;
+
+    // Check that the parameter is in the correct state.
+    if (ParamTypestateAttr *PTA = Param->getAttr<ParamTypestateAttr>()) {
+      ConsumedState ParamState = PInfo.getAsState(StateMap);
+      ConsumedState ExpectedState = mapParamTypestateAttrState(PTA);
+
+      if (ParamState != ExpectedState)
+        Analyzer.WarningsHandler.warnParamTypestateMismatch(
+          Call->getArg(Index)->getExprLoc(),
+          stateToString(ExpectedState), stateToString(ParamState));
+    }
+
+    if (!(Entry->second.isVar() || Entry->second.isTmp()))
+      continue;
+
+    // Adjust state on the caller side.
+    if (isRValueRef(ParamType))
+      setStateForVarOrTmp(StateMap, PInfo, consumed::CS_Consumed);
+    else if (ReturnTypestateAttr *RT = Param->getAttr<ReturnTypestateAttr>())
+      setStateForVarOrTmp(StateMap, PInfo, mapReturnTypestateAttrState(RT));
+    else if (isPointerOrRef(ParamType) &&
+             (!ParamType->getPointeeType().isConstQualified() ||
+              isSetOnReadPtrType(ParamType)))
+      setStateForVarOrTmp(StateMap, PInfo, consumed::CS_Unknown);
+  }
+
+  if (!ObjArg)
+    return false;
+
+  // check implicit 'self' parameter, if present
+  InfoEntry Entry = findInfo(ObjArg);
+  if (Entry != PropagationMap.end()) {
+    PropagationInfo PInfo = Entry->second;
+    checkCallability(PInfo, FunD, Call->getExprLoc());
+
+    if (SetTypestateAttr *STA = FunD->getAttr<SetTypestateAttr>()) {
+      if (PInfo.isVar()) {
+        StateMap->setState(PInfo.getVar(), mapSetTypestateAttrState(STA));
+        return true;
+      }
+      else if (PInfo.isTmp()) {
+        StateMap->setState(PInfo.getTmp(), mapSetTypestateAttrState(STA));
+        return true;
+      }
+    }
+    else if (isTestingFunction(FunD) && PInfo.isVar()) {
+      PropagationMap.insert(PairType(Call,
+        PropagationInfo(PInfo.getVar(), testsFor(FunD))));
+    }
+  }
+  return false;
 }
 
-bool ConsumedStmtVisitor::isLikeMoveAssignment(
-  const CXXMethodDecl *MethodDecl) {
-  
-  return MethodDecl->isMoveAssignmentOperator() ||
-         (MethodDecl->getOverloadedOperator() == OO_Equal &&
-          MethodDecl->getNumParams() == 1 &&
-          MethodDecl->getParamDecl(0)->getType()->isRValueReferenceType());
-}
 
-void ConsumedStmtVisitor::propagateReturnType(const Stmt *Call,
-                                              const FunctionDecl *Fun,
-                                              QualType ReturnType) {
-  if (isConsumableType(ReturnType)) {
-    
+void ConsumedStmtVisitor::propagateReturnType(const Expr *Call,
+                                              const FunctionDecl *Fun) {
+  QualType RetType = Fun->getCallResultType();
+  if (RetType->isReferenceType())
+    RetType = RetType->getPointeeType();
+
+  if (isConsumableType(RetType)) {
     ConsumedState ReturnState;
-    
-    if (Fun->hasAttr<ReturnTypestateAttr>())
-      ReturnState = mapReturnTypestateAttrState(
-        Fun->getAttr<ReturnTypestateAttr>());
+    if (ReturnTypestateAttr *RTA = Fun->getAttr<ReturnTypestateAttr>())
+      ReturnState = mapReturnTypestateAttrState(RTA);
     else
-      ReturnState = mapConsumableAttrState(ReturnType);
+      ReturnState = mapConsumableAttrState(RetType);
     
     PropagationMap.insert(PairType(Call, PropagationInfo(ReturnState)));
   }
 }
 
+
 void ConsumedStmtVisitor::VisitBinaryOperator(const BinaryOperator *BinOp) {
   switch (BinOp->getOpcode()) {
   case BO_LAnd:
   case BO_LOr : {
-    InfoEntry LEntry = PropagationMap.find(BinOp->getLHS()),
-              REntry = PropagationMap.find(BinOp->getRHS());
+    InfoEntry LEntry = findInfo(BinOp->getLHS()),
+              REntry = findInfo(BinOp->getRHS());
     
     VarTestResult LTest, RTest;
     
@@ -576,7 +710,7 @@
       LTest = LEntry->second.getVarTest();
       
     } else {
-      LTest.Var      = NULL;
+      LTest.Var      = nullptr;
       LTest.TestsFor = CS_None;
     }
     
@@ -584,11 +718,11 @@
       RTest = REntry->second.getVarTest();
       
     } else {
-      RTest.Var      = NULL;
+      RTest.Var      = nullptr;
       RTest.TestsFor = CS_None;
     }
-    
-    if (!(LTest.Var == NULL && RTest.Var == NULL))
+
+    if (!(LTest.Var == nullptr && RTest.Var == nullptr))
       PropagationMap.insert(PairType(BinOp, PropagationInfo(BinOp,
         static_cast<EffectiveOp>(BinOp->getOpcode() == BO_LOr), LTest, RTest)));
     
@@ -606,68 +740,20 @@
 }
 
 void ConsumedStmtVisitor::VisitCallExpr(const CallExpr *Call) {
-  if (const FunctionDecl *FunDecl =
-    dyn_cast_or_null<FunctionDecl>(Call->getDirectCallee())) {
-    
-    // Special case for the std::move function.
-    // TODO: Make this more specific. (Deferred)
-    if (FunDecl->getNameAsString() == "move") {
-      forwardInfo(Call->getArg(0), Call);
-      return;
-    }
-    
-    unsigned Offset = Call->getNumArgs() - FunDecl->getNumParams();
-    
-    for (unsigned Index = Offset; Index < Call->getNumArgs(); ++Index) {
-      const ParmVarDecl *Param = FunDecl->getParamDecl(Index - Offset);
-      QualType ParamType = Param->getType();
-      
-      InfoEntry Entry = PropagationMap.find(Call->getArg(Index));
-      
-      if (Entry == PropagationMap.end() || Entry->second.isTest())
-        continue;
-      
-      PropagationInfo PInfo = Entry->second;
-      
-      // Check that the parameter is in the correct state.
-      
-      if (Param->hasAttr<ParamTypestateAttr>()) {
-        ConsumedState ParamState = PInfo.getAsState(StateMap);
-        
-        ConsumedState ExpectedState =
-          mapParamTypestateAttrState(Param->getAttr<ParamTypestateAttr>());
-        
-        if (ParamState != ExpectedState)
-          Analyzer.WarningsHandler.warnParamTypestateMismatch(
-            Call->getArg(Index - Offset)->getExprLoc(),
-            stateToString(ExpectedState), stateToString(ParamState));
-      }
-      
-      if (!(Entry->second.isVar() || Entry->second.isTmp()))
-        continue;
-      
-      // Adjust state on the caller side.
-      
-      if (isRValueRefish(ParamType)) {
-        setStateForVarOrTmp(StateMap, PInfo, consumed::CS_Consumed);
-        
-      } else if (Param->hasAttr<ReturnTypestateAttr>()) {
-        setStateForVarOrTmp(StateMap, PInfo,
-          mapReturnTypestateAttrState(Param->getAttr<ReturnTypestateAttr>()));
-        
-      } else if (!isValueType(ParamType) &&
-                 !ParamType->getPointeeType().isConstQualified()) {
-        
-        setStateForVarOrTmp(StateMap, PInfo, consumed::CS_Unknown);
-      }
-    }
-    
-    QualType RetType = FunDecl->getCallResultType();
-    if (RetType->isReferenceType())
-      RetType = RetType->getPointeeType();
-    
-    propagateReturnType(Call, FunDecl, RetType);
+  const FunctionDecl *FunDecl = Call->getDirectCallee();
+  if (!FunDecl)
+    return;
+
+  // Special case for the std::move function.
+  // TODO: Make this more specific. (Deferred)
+  if (Call->getNumArgs() == 1 && FunDecl->getNameAsString() == "move" &&
+      FunDecl->isInStdNamespace()) {
+    copyInfo(Call->getArg(0), Call, CS_Consumed);
+    return;
   }
+
+  handleCall(Call, nullptr, FunDecl);
+  propagateReturnType(Call, FunDecl);
 }
 
 void ConsumedStmtVisitor::VisitCastExpr(const CastExpr *Cast) {
@@ -677,7 +763,7 @@
 void ConsumedStmtVisitor::VisitCXXBindTemporaryExpr(
   const CXXBindTemporaryExpr *Temp) {
   
-  InfoEntry Entry = PropagationMap.find(Temp->getSubExpr());
+  InfoEntry Entry = findInfo(Temp->getSubExpr());
   
   if (Entry != PropagationMap.end() && !Entry->second.isTest()) {
     StateMap->setState(Temp, Entry->second.getAsState(StateMap));
@@ -695,168 +781,60 @@
     return;
   
   // FIXME: What should happen if someone annotates the move constructor?
-  if (Constructor->hasAttr<ReturnTypestateAttr>()) {
-    // TODO: Adjust state of args appropriately.
-    
-    ReturnTypestateAttr *RTAttr = Constructor->getAttr<ReturnTypestateAttr>();
-    ConsumedState RetState = mapReturnTypestateAttrState(RTAttr);
+  if (ReturnTypestateAttr *RTA = Constructor->getAttr<ReturnTypestateAttr>()) {
+    // TODO: Adjust state of args appropriately.    
+    ConsumedState RetState = mapReturnTypestateAttrState(RTA);
     PropagationMap.insert(PairType(Call, PropagationInfo(RetState)));
-    
   } else if (Constructor->isDefaultConstructor()) {
-    
     PropagationMap.insert(PairType(Call,
       PropagationInfo(consumed::CS_Consumed)));
-    
   } else if (Constructor->isMoveConstructor()) {
-    
-    InfoEntry Entry = PropagationMap.find(Call->getArg(0));
-    
-    if (Entry != PropagationMap.end()) {
-      PropagationInfo PInfo = Entry->second;
-      
-      if (PInfo.isVar()) {
-        const VarDecl* Var = PInfo.getVar();
-        
-        PropagationMap.insert(PairType(Call,
-          PropagationInfo(StateMap->getState(Var))));
-        
-        StateMap->setState(Var, consumed::CS_Consumed);
-        
-      } else if (PInfo.isTmp()) {
-        const CXXBindTemporaryExpr *Tmp = PInfo.getTmp();
-        
-        PropagationMap.insert(PairType(Call,
-          PropagationInfo(StateMap->getState(Tmp))));
-        
-        StateMap->setState(Tmp, consumed::CS_Consumed);
-        
-      } else {
-        PropagationMap.insert(PairType(Call, PInfo));
-      }
-    }
+    copyInfo(Call->getArg(0), Call, CS_Consumed);
   } else if (Constructor->isCopyConstructor()) {
-    forwardInfo(Call->getArg(0), Call);
-    
+    // Copy state from arg.  If setStateOnRead then set arg to CS_Unknown.
+    ConsumedState NS =
+      isSetOnReadPtrType(Constructor->getThisType(CurrContext)) ?
+      CS_Unknown : CS_None;
+    copyInfo(Call->getArg(0), Call, NS);
   } else {
     // TODO: Adjust state of args appropriately.
-    
     ConsumedState RetState = mapConsumableAttrState(ThisType);
     PropagationMap.insert(PairType(Call, PropagationInfo(RetState)));
   }
 }
 
+
 void ConsumedStmtVisitor::VisitCXXMemberCallExpr(
-  const CXXMemberCallExpr *Call) {
-  
-  VisitCallExpr(Call);
-  
-  InfoEntry Entry = PropagationMap.find(Call->getCallee()->IgnoreParens());
-  
-  if (Entry != PropagationMap.end()) {
-    PropagationInfo PInfo = Entry->second;
-    const CXXMethodDecl *MethodDecl = Call->getMethodDecl();
-    
-    checkCallability(PInfo, MethodDecl, Call->getExprLoc());
-    
-    if (PInfo.isVar()) {
-      if (isTestingFunction(MethodDecl))
-        PropagationMap.insert(PairType(Call,
-          PropagationInfo(PInfo.getVar(), testsFor(MethodDecl))));
-      else if (MethodDecl->hasAttr<SetTypestateAttr>())
-        StateMap->setState(PInfo.getVar(),
-          mapSetTypestateAttrState(MethodDecl->getAttr<SetTypestateAttr>()));
-    } else if (PInfo.isTmp() && MethodDecl->hasAttr<SetTypestateAttr>()) {
-      StateMap->setState(PInfo.getTmp(),
-        mapSetTypestateAttrState(MethodDecl->getAttr<SetTypestateAttr>()));
-    }
-  }
+    const CXXMemberCallExpr *Call) {
+  CXXMethodDecl* MD = Call->getMethodDecl();
+  if (!MD)
+    return;
+
+  handleCall(Call, Call->getImplicitObjectArgument(), MD);
+  propagateReturnType(Call, MD);
 }
 
+
 void ConsumedStmtVisitor::VisitCXXOperatorCallExpr(
-  const CXXOperatorCallExpr *Call) {
-  
+    const CXXOperatorCallExpr *Call) {
+
   const FunctionDecl *FunDecl =
     dyn_cast_or_null<FunctionDecl>(Call->getDirectCallee());
-  
   if (!FunDecl) return;
-    
-  if (isa<CXXMethodDecl>(FunDecl) &&
-      isLikeMoveAssignment(cast<CXXMethodDecl>(FunDecl))) {
-    
-    InfoEntry LEntry = PropagationMap.find(Call->getArg(0));
-    InfoEntry REntry = PropagationMap.find(Call->getArg(1));
-    
-    PropagationInfo LPInfo, RPInfo;
-    
-    if (LEntry != PropagationMap.end() &&
-        REntry != PropagationMap.end()) {
-      
-      LPInfo = LEntry->second;
-      RPInfo = REntry->second;
-      
-      if (LPInfo.isPointerToValue() && RPInfo.isPointerToValue()) {
-        setStateForVarOrTmp(StateMap, LPInfo, RPInfo.getAsState(StateMap));
-        PropagationMap.insert(PairType(Call, LPInfo));
-        setStateForVarOrTmp(StateMap, RPInfo, consumed::CS_Consumed);
-        
-      } else if (RPInfo.isState()) {
-        setStateForVarOrTmp(StateMap, LPInfo, RPInfo.getState());
-        PropagationMap.insert(PairType(Call, LPInfo));
-        
-      } else {
-        setStateForVarOrTmp(StateMap, RPInfo, consumed::CS_Consumed);
-      }
-      
-    } else if (LEntry != PropagationMap.end() &&
-               REntry == PropagationMap.end()) {
-      
-      LPInfo = LEntry->second;
-      
-      assert(!LPInfo.isTest());
-      
-      if (LPInfo.isPointerToValue()) {
-        setStateForVarOrTmp(StateMap, LPInfo, consumed::CS_Unknown);
-        PropagationMap.insert(PairType(Call, LPInfo));
-        
-      } else {
-        PropagationMap.insert(PairType(Call,
-          PropagationInfo(consumed::CS_Unknown)));
-      }
-      
-    } else if (LEntry == PropagationMap.end() &&
-               REntry != PropagationMap.end()) {
-      
-      RPInfo = REntry->second;
-      
-      if (RPInfo.isPointerToValue())
-        setStateForVarOrTmp(StateMap, RPInfo, consumed::CS_Consumed);
-    }
-    
-  } else {
-    
-    VisitCallExpr(Call);
-    
-    InfoEntry Entry = PropagationMap.find(Call->getArg(0));
-    
-    if (Entry != PropagationMap.end()) {
-      PropagationInfo PInfo = Entry->second;
-      
-      checkCallability(PInfo, FunDecl, Call->getExprLoc());
-      
-      if (PInfo.isVar()) {
-        if (isTestingFunction(FunDecl))
-          PropagationMap.insert(PairType(Call,
-            PropagationInfo(PInfo.getVar(), testsFor(FunDecl))));
-        else if (FunDecl->hasAttr<SetTypestateAttr>())
-          StateMap->setState(PInfo.getVar(),
-            mapSetTypestateAttrState(FunDecl->getAttr<SetTypestateAttr>()));
-        
-      } else if (PInfo.isTmp() && FunDecl->hasAttr<SetTypestateAttr>()) {
-        StateMap->setState(PInfo.getTmp(),
-          mapSetTypestateAttrState(FunDecl->getAttr<SetTypestateAttr>()));
-    }
-    }
+
+  if (Call->getOperator() == OO_Equal) {
+    ConsumedState CS = getInfo(Call->getArg(1));
+    if (!handleCall(Call, Call->getArg(0), FunDecl))
+      setInfo(Call->getArg(0), CS);
+    return;
   }
+
+  if (const CXXMemberCallExpr *MCall = dyn_cast<CXXMemberCallExpr>(Call))
+    handleCall(MCall, MCall->getImplicitObjectArgument(), FunDecl);
+  else
+    handleCall(Call, Call->getArg(0), FunDecl);
+
+  propagateReturnType(Call, FunDecl);
 }
 
 void ConsumedStmtVisitor::VisitDeclRefExpr(const DeclRefExpr *DeclRef) {
@@ -866,11 +844,9 @@
 }
 
 void ConsumedStmtVisitor::VisitDeclStmt(const DeclStmt *DeclS) {
-  for (DeclStmt::const_decl_iterator DI = DeclS->decl_begin(),
-       DE = DeclS->decl_end(); DI != DE; ++DI) {
-    
-    if (isa<VarDecl>(*DI)) VisitVarDecl(cast<VarDecl>(*DI));
-  }
+  for (const auto *DI : DeclS->decls())    
+    if (isa<VarDecl>(DI))
+      VisitVarDecl(cast<VarDecl>(DI));
   
   if (DeclS->isSingleDecl())
     if (const VarDecl *Var = dyn_cast_or_null<VarDecl>(DeclS->getSingleDecl()))
@@ -892,22 +868,16 @@
   QualType ParamType = Param->getType();
   ConsumedState ParamState = consumed::CS_None;
   
-  if (Param->hasAttr<ParamTypestateAttr>()) {
-    const ParamTypestateAttr *PTAttr = Param->getAttr<ParamTypestateAttr>();
-    ParamState = mapParamTypestateAttrState(PTAttr);
-    
-  } else if (isConsumableType(ParamType)) {
-    ParamState = mapConsumableAttrState(ParamType);
-    
-  } else if (isRValueRefish(ParamType) &&
-             isConsumableType(ParamType->getPointeeType())) {
-    
-    ParamState = mapConsumableAttrState(ParamType->getPointeeType());
-    
-  } else if (ParamType->isReferenceType() &&
-             isConsumableType(ParamType->getPointeeType())) {
+  if (const ParamTypestateAttr *PTA = Param->getAttr<ParamTypestateAttr>())
+    ParamState = mapParamTypestateAttrState(PTA);    
+  else if (isConsumableType(ParamType))
+    ParamState = mapConsumableAttrState(ParamType);    
+  else if (isRValueRef(ParamType) &&
+           isConsumableType(ParamType->getPointeeType()))
+    ParamState = mapConsumableAttrState(ParamType->getPointeeType());    
+  else if (ParamType->isReferenceType() &&
+           isConsumableType(ParamType->getPointeeType()))
     ParamState = consumed::CS_Unknown;
-  }
   
   if (ParamState != CS_None)
     StateMap->setState(Param, ParamState);
@@ -917,7 +887,7 @@
   ConsumedState ExpectedState = Analyzer.getExpectedReturnState();
   
   if (ExpectedState != CS_None) {
-    InfoEntry Entry = PropagationMap.find(Ret->getRetValue());
+    InfoEntry Entry = findInfo(Ret->getRetValue());
     
     if (Entry != PropagationMap.end()) {
       ConsumedState RetState = Entry->second.getAsState(StateMap);
@@ -934,7 +904,7 @@
 }
 
 void ConsumedStmtVisitor::VisitUnaryOperator(const UnaryOperator *UOp) {
-  InfoEntry Entry = PropagationMap.find(UOp->getSubExpr()->IgnoreParens());
+  InfoEntry Entry = findInfo(UOp->getSubExpr());
   if (Entry == PropagationMap.end()) return;
   
   switch (UOp->getOpcode()) {
@@ -956,8 +926,7 @@
 void ConsumedStmtVisitor::VisitVarDecl(const VarDecl *Var) {
   if (isConsumableType(Var->getType())) {
     if (Var->hasInit()) {
-      MapType::iterator VIT = PropagationMap.find(
-        Var->getInit()->IgnoreImplicit());
+      MapType::iterator VIT = findInfo(Var->getInit()->IgnoreImplicit());
       if (VIT != PropagationMap.end()) {
         PropagationInfo PInfo = VIT->second;
         ConsumedState St = PInfo.getAsState(StateMap);
@@ -1092,9 +1061,9 @@
 
 void ConsumedBlockInfo::addInfo(const CFGBlock *Block,
                                 ConsumedStateMap *StateMap) {
-  
-  assert(Block != NULL && "Block pointer must not be NULL");
-  
+
+  assert(Block && "Block pointer must not be NULL");
+
   ConsumedStateMap *Entry = StateMapsArray[Block->getBlockID()];
     
   if (Entry) {
@@ -1116,7 +1085,7 @@
 void ConsumedBlockInfo::discardInfo(const CFGBlock *Block) {
   unsigned int BlockID = Block->getBlockID();
   delete StateMapsArray[BlockID];
-  StateMapsArray[BlockID] = NULL;
+  StateMapsArray[BlockID] = nullptr;
 }
 
 ConsumedStateMap* ConsumedBlockInfo::getInfo(const CFGBlock *Block) {
@@ -1126,7 +1095,7 @@
   if (isBackEdgeTarget(Block)) {
     return new ConsumedStateMap(*StateMap);
   } else {
-    StateMapsArray[Block->getBlockID()] = NULL;
+    StateMapsArray[Block->getBlockID()] = nullptr;
     return StateMap;
   }
 }
@@ -1139,8 +1108,8 @@
 }
 
 bool ConsumedBlockInfo::isBackEdgeTarget(const CFGBlock *Block) {
-  assert(Block != NULL && "Block pointer must not be NULL");
-  
+  assert(Block && "Block pointer must not be NULL");
+
   // Anything with less than two predecessors can't be the target of a back
   // edge.
   if (Block->pred_size() < 2)
@@ -1158,24 +1127,19 @@
 void ConsumedStateMap::checkParamsForReturnTypestate(SourceLocation BlameLoc,
   ConsumedWarningsHandlerBase &WarningsHandler) const {
   
-  ConsumedState ExpectedState;
-  
-  for (VarMapType::const_iterator DMI = VarMap.begin(), DME = VarMap.end();
-       DMI != DME; ++DMI) {
-    
-    if (isa<ParmVarDecl>(DMI->first)) {
-      const ParmVarDecl *Param = cast<ParmVarDecl>(DMI->first);
+  for (const auto &DM : VarMap) {
+    if (isa<ParmVarDecl>(DM.first)) {
+      const ParmVarDecl *Param = cast<ParmVarDecl>(DM.first);
+      const ReturnTypestateAttr *RTA = Param->getAttr<ReturnTypestateAttr>();
       
-      if (!Param->hasAttr<ReturnTypestateAttr>()) continue;
+      if (!RTA)
+        continue;
       
-      ExpectedState =
-        mapReturnTypestateAttrState(Param->getAttr<ReturnTypestateAttr>());
-      
-      if (DMI->second != ExpectedState) {
+      ConsumedState ExpectedState = mapReturnTypestateAttrState(RTA);      
+      if (DM.second != ExpectedState)
         WarningsHandler.warnParamReturnTypestateMismatch(BlameLoc,
           Param->getNameAsString(), stateToString(ExpectedState),
-          stateToString(DMI->second));
-      }
+          stateToString(DM.second));
     }
   }
 }
@@ -1211,16 +1175,14 @@
     return;
   }
   
-  for (VarMapType::const_iterator DMI = Other->VarMap.begin(),
-       DME = Other->VarMap.end(); DMI != DME; ++DMI) {
-    
-    LocalState = this->getState(DMI->first);
+  for (const auto &DM : Other->VarMap) {
+    LocalState = this->getState(DM.first);
     
     if (LocalState == CS_None)
       continue;
     
-    if (LocalState != DMI->second)
-       VarMap[DMI->first] = CS_Unknown;
+    if (LocalState != DM.second)
+     VarMap[DM.first] = CS_Unknown;
   }
 }
 
@@ -1231,18 +1193,16 @@
   ConsumedState LocalState;
   SourceLocation BlameLoc = getLastStmtLoc(LoopBack);
   
-  for (VarMapType::const_iterator DMI = LoopBackStates->VarMap.begin(),
-       DME = LoopBackStates->VarMap.end(); DMI != DME; ++DMI) {
-    
-    LocalState = this->getState(DMI->first);
+  for (const auto &DM : LoopBackStates->VarMap) {    
+    LocalState = this->getState(DM.first);
     
     if (LocalState == CS_None)
       continue;
     
-    if (LocalState != DMI->second) {
-      VarMap[DMI->first] = CS_Unknown;
-      WarningsHandler.warnLoopStateMismatch(
-        BlameLoc, DMI->first->getNameAsString());
+    if (LocalState != DM.second) {
+      VarMap[DM.first] = CS_Unknown;
+      WarningsHandler.warnLoopStateMismatch(BlameLoc,
+                                            DM.first->getNameAsString());
     }
   }
 }
@@ -1262,18 +1222,14 @@
   TmpMap[Tmp] = State;
 }
 
-void ConsumedStateMap::remove(const VarDecl *Var) {
-  VarMap.erase(Var);
+void ConsumedStateMap::remove(const CXXBindTemporaryExpr *Tmp) {
+  TmpMap.erase(Tmp);
 }
 
 bool ConsumedStateMap::operator!=(const ConsumedStateMap *Other) const {
-  for (VarMapType::const_iterator DMI = Other->VarMap.begin(),
-       DME = Other->VarMap.end(); DMI != DME; ++DMI) {
-    
-    if (this->getState(DMI->first) != DMI->second)
-      return true;
-  }
-  
+  for (const auto &DM : Other->VarMap)
+    if (this->getState(DM.first) != DM.second)
+      return true;  
   return false;
 }
 
@@ -1286,9 +1242,7 @@
   } else
     ReturnType = D->getCallResultType();
 
-  if (D->hasAttr<ReturnTypestateAttr>()) {
-    const ReturnTypestateAttr *RTSAttr = D->getAttr<ReturnTypestateAttr>();
-
+  if (const ReturnTypestateAttr *RTSAttr = D->getAttr<ReturnTypestateAttr>()) {
     const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl();
     if (!RD || !RD->hasAttr<ConsumableAttr>()) {
       // FIXME: This should be removed when template instantiation propagates
@@ -1300,22 +1254,27 @@
       ExpectedReturnState = CS_None;
     } else
       ExpectedReturnState = mapReturnTypestateAttrState(RTSAttr);
-  } else if (isConsumableType(ReturnType))
-    ExpectedReturnState = mapConsumableAttrState(ReturnType);
+  } else if (isConsumableType(ReturnType)) {
+    if (isAutoCastType(ReturnType))   // We can auto-cast the state to the
+      ExpectedReturnState = CS_None;  // expected state.
+    else
+      ExpectedReturnState = mapConsumableAttrState(ReturnType);
+  }
   else
     ExpectedReturnState = CS_None;
 }
 
 bool ConsumedAnalyzer::splitState(const CFGBlock *CurrBlock,
                                   const ConsumedStmtVisitor &Visitor) {
-  
-  OwningPtr<ConsumedStateMap> FalseStates(new ConsumedStateMap(*CurrStates));
+
+  std::unique_ptr<ConsumedStateMap> FalseStates(
+      new ConsumedStateMap(*CurrStates));
   PropagationInfo PInfo;
   
   if (const IfStmt *IfNode =
     dyn_cast_or_null<IfStmt>(CurrBlock->getTerminator().getStmt())) {
     
-    const Stmt *Cond = IfNode->getCond();
+    const Expr *Cond = IfNode->getCond();
     
     PInfo = Visitor.getInfo(Cond);
     if (!PInfo.isValid() && isa<BinaryOperator>(Cond))
@@ -1384,9 +1343,9 @@
     delete CurrStates;
     
   if (*++SI)
-    BlockInfo.addInfo(*SI, FalseStates.take());
-  
-  CurrStates = NULL;
+    BlockInfo.addInfo(*SI, FalseStates.release());
+
+  CurrStates = nullptr;
   return true;
 }
 
@@ -1410,18 +1369,12 @@
   ConsumedStmtVisitor Visitor(AC, *this, CurrStates);
   
   // Add all trackable parameters to the state map.
-  for (FunctionDecl::param_const_iterator PI = D->param_begin(),
-       PE = D->param_end(); PI != PE; ++PI) {
-    Visitor.VisitParmVarDecl(*PI);
-  }
+  for (const auto *PI : D->params())
+    Visitor.VisitParmVarDecl(PI);
   
   // Visit all of the function's basic blocks.
-  for (PostOrderCFGView::iterator I = SortedGraph->begin(),
-       E = SortedGraph->end(); I != E; ++I) {
-    
-    const CFGBlock *CurrBlock = *I;
-    
-    if (CurrStates == NULL)
+  for (const auto *CurrBlock : *SortedGraph) {
+    if (!CurrStates)
       CurrStates = BlockInfo.getInfo(CurrBlock);
     
     if (!CurrStates) {
@@ -1429,33 +1382,32 @@
       
     } else if (!CurrStates->isReachable()) {
       delete CurrStates;
-      CurrStates = NULL;
+      CurrStates = nullptr;
       continue;
     }
     
     Visitor.reset(CurrStates);
     
     // Visit all of the basic block's statements.
-    for (CFGBlock::const_iterator BI = CurrBlock->begin(),
-         BE = CurrBlock->end(); BI != BE; ++BI) {
-      
-      switch (BI->getKind()) {
+    for (const auto &B : *CurrBlock) {
+      switch (B.getKind()) {
       case CFGElement::Statement:
-        Visitor.Visit(BI->castAs<CFGStmt>().getStmt());
+        Visitor.Visit(B.castAs<CFGStmt>().getStmt());
         break;
         
       case CFGElement::TemporaryDtor: {
-        const CFGTemporaryDtor DTor = BI->castAs<CFGTemporaryDtor>();
+        const CFGTemporaryDtor &DTor = B.castAs<CFGTemporaryDtor>();
         const CXXBindTemporaryExpr *BTE = DTor.getBindTemporaryExpr();
         
         Visitor.checkCallability(PropagationInfo(BTE),
                                  DTor.getDestructorDecl(AC.getASTContext()),
                                  BTE->getExprLoc());
+        CurrStates->remove(BTE);
         break;
       }
       
       case CFGElement::AutomaticObjectDtor: {
-        const CFGAutomaticObjDtor DTor = BI->castAs<CFGAutomaticObjDtor>();
+        const CFGAutomaticObjDtor &DTor = B.castAs<CFGAutomaticObjDtor>();
         SourceLocation Loc = DTor.getTriggerStmt()->getLocEnd();
         const VarDecl *Var = DTor.getVarDecl();
         
@@ -1470,13 +1422,11 @@
       }
     }
     
-    CurrStates->clearTemporaries();
-    
     // TODO: Handle other forms of branching with precision, including while-
     //       and for-loops. (Deferred)
     if (!splitState(CurrBlock, Visitor)) {
-      CurrStates->setSource(NULL);
-      
+      CurrStates->setSource(nullptr);
+
       if (CurrBlock->succ_size() > 1 ||
           (CurrBlock->succ_size() == 1 &&
            (*CurrBlock->succ_begin())->pred_size() > 1)) {
@@ -1485,9 +1435,9 @@
         
         for (CFGBlock::const_succ_iterator SI = CurrBlock->succ_begin(),
              SE = CurrBlock->succ_end(); SI != SE; ++SI) {
-          
-          if (*SI == NULL) continue;
-          
+
+          if (*SI == nullptr) continue;
+
           if (BlockInfo.isBackEdge(CurrBlock, *SI)) {
             BlockInfo.borrowInfo(*SI)->intersectAtLoopHead(*SI, CurrBlock,
                                                            CurrStates,
@@ -1502,8 +1452,8 @@
         
         if (!OwnershipTaken)
           delete CurrStates;
-        
-        CurrStates = NULL;
+
+        CurrStates = nullptr;
       }
     }
     
diff --git a/lib/Analysis/FormatString.cpp b/lib/Analysis/FormatString.cpp
index 43ecc66..851b97e 100644
--- a/lib/Analysis/FormatString.cpp
+++ b/lib/Analysis/FormatString.cpp
@@ -507,7 +507,7 @@
   case None:
     return "";
   }
-  return NULL;
+  return nullptr;
 }
 
 //===----------------------------------------------------------------------===//
@@ -539,7 +539,7 @@
   case nArg: return "n";
   case PercentArg:  return "%";
   case ScanListArg: return "[";
-  case InvalidSpecifier: return NULL;
+  case InvalidSpecifier: return nullptr;
 
   // POSIX unicode extensions.
   case CArg: return "C";
@@ -551,7 +551,7 @@
   // GlibC specific specifiers.
   case PrintErrno: return "m";
   }
-  return NULL;
+  return nullptr;
 }
 
 Optional<ConversionSpecifier>
diff --git a/lib/Analysis/FormatStringParsing.h b/lib/Analysis/FormatStringParsing.h
index 6b25123..fba3180 100644
--- a/lib/Analysis/FormatStringParsing.h
+++ b/lib/Analysis/FormatStringParsing.h
@@ -53,14 +53,14 @@
   bool Stop;
 public:
   SpecifierResult(bool stop = false)
-  : Start(0), Stop(stop) {}
+  : Start(nullptr), Stop(stop) {}
   SpecifierResult(const char *start,
                   const T &fs)
   : FS(fs), Start(start), Stop(false) {}
   
   const char *getStart() const { return Start; }
   bool shouldStop() const { return Stop; }
-  bool hasValue() const { return Start != 0; }
+  bool hasValue() const { return Start != nullptr; }
   const T &getValue() const {
     assert(hasValue());
     return FS;
diff --git a/lib/Analysis/LiveVariables.cpp b/lib/Analysis/LiveVariables.cpp
index 38db72a..3d6fc03 100644
--- a/lib/Analysis/LiveVariables.cpp
+++ b/lib/Analysis/LiveVariables.cpp
@@ -37,7 +37,6 @@
       POV(Ctx.getAnalysis<PostOrderCFGView>()) {}
   
   void enqueueBlock(const CFGBlock *block);
-  void enqueueSuccessors(const CFGBlock *block);
   void enqueuePredecessors(const CFGBlock *block);
 
   const CFGBlock *dequeue();
@@ -53,19 +52,6 @@
     worklist.push_back(block);
   }
 }
-  
-void DataflowWorklist::enqueueSuccessors(const clang::CFGBlock *block) {
-  const unsigned OldWorklistSize = worklist.size();
-  for (CFGBlock::const_succ_iterator I = block->succ_begin(),
-       E = block->succ_end(); I != E; ++I) {
-    enqueueBlock(*I);
-  }
-
-  if (OldWorklistSize == 0 || OldWorklistSize == worklist.size())
-    return;
-
-  sortWorklist();
-}
 
 void DataflowWorklist::enqueuePredecessors(const clang::CFGBlock *block) {
   const unsigned OldWorklistSize = worklist.size();
@@ -86,7 +72,7 @@
 
 const CFGBlock *DataflowWorklist::dequeue() {
   if (worklist.empty())
-    return 0;
+    return nullptr;
   const CFGBlock *b = worklist.pop_back_val();
   enqueuedBlocks[b->getBlockID()] = false;
   return b;
@@ -108,10 +94,10 @@
   LiveVariables::LivenessValues
   merge(LiveVariables::LivenessValues valsA,
         LiveVariables::LivenessValues valsB);
-      
-  LiveVariables::LivenessValues runOnBlock(const CFGBlock *block,
-                                           LiveVariables::LivenessValues val,
-                                           LiveVariables::Observer *obs = 0);
+
+  LiveVariables::LivenessValues
+  runOnBlock(const CFGBlock *block, LiveVariables::LivenessValues val,
+             LiveVariables::Observer *obs = nullptr);
 
   void dumpBlockLiveness(const SourceManager& M);
 
@@ -211,8 +197,6 @@
   LiveVariables::LivenessValues &val;
   LiveVariables::Observer *observer;
   const CFGBlock *currentBlock;
-
-  void markLogicalExprLeaves(const Expr *E);
 public:
   TransferFunctions(LiveVariablesImpl &im,
                     LiveVariables::LivenessValues &Val,
@@ -240,8 +224,8 @@
     
     ty = VT->getElementType().getTypePtr();
   }
-  
-  return 0;
+
+  return nullptr;
 }
 
 static const Stmt *LookThroughStmt(const Stmt *S) {
@@ -307,7 +291,7 @@
       const DeclStmt *DS = cast<DeclStmt>(S);
       if (const VarDecl *VD = dyn_cast<VarDecl>(DS->getSingleDecl())) {
         for (const VariableArrayType* VA = FindVA(VD->getType());
-             VA != 0; VA = FindVA(VA->getElementType())) {
+             VA != nullptr; VA = FindVA(VA->getElementType())) {
           AddLiveStmt(val.liveStmts, LV.SSetFact, VA->getSizeExpr());
         }
       }
@@ -369,28 +353,12 @@
         if (observer)
           observer->observerKill(DR);
       }
-  } else if (B->isLogicalOp()) {
-    // Leaf expressions in the logical operator tree are live until we reach the
-    // outermost logical operator. Static analyzer relies on this behaviour.
-    markLogicalExprLeaves(B->getLHS()->IgnoreParens());
-    markLogicalExprLeaves(B->getRHS()->IgnoreParens());
   }
 }
 
-void TransferFunctions::markLogicalExprLeaves(const Expr *E) {
-  const BinaryOperator *B = dyn_cast<BinaryOperator>(E);
-  if (!B || !B->isLogicalOp()) {
-    val.liveStmts = LV.SSetFact.add(val.liveStmts, E);
-    return;
-  }
-
-  markLogicalExprLeaves(B->getLHS()->IgnoreParens());
-  markLogicalExprLeaves(B->getRHS()->IgnoreParens());
-}
-
 void TransferFunctions::VisitBlockExpr(BlockExpr *BE) {
   AnalysisDeclContext::referenced_decls_iterator I, E;
-  llvm::tie(I, E) =
+  std::tie(I, E) =
     LV.analysisContext.getReferencedBlockVars(BE->getBlockDecl());
   for ( ; I != E ; ++I) {
     const VarDecl *VD = *I;
@@ -407,9 +375,8 @@
 }
 
 void TransferFunctions::VisitDeclStmt(DeclStmt *DS) {
-  for (DeclStmt::decl_iterator DI=DS->decl_begin(), DE = DS->decl_end();
-       DI != DE; ++DI)
-    if (VarDecl *VD = dyn_cast<VarDecl>(*DI)) {
+  for (const auto *DI : DS->decls())
+    if (const auto *VD = dyn_cast<VarDecl>(DI)) {
       if (!isAlwaysAlive(VD))
         val.liveDecls = LV.DSetFact.remove(val.liveDecls, VD);
     }
@@ -417,8 +384,8 @@
 
 void TransferFunctions::VisitObjCForCollectionStmt(ObjCForCollectionStmt *OS) {
   // Kill the iteration variable.
-  DeclRefExpr *DR = 0;
-  const VarDecl *VD = 0;
+  DeclRefExpr *DR = nullptr;
+  const VarDecl *VD = nullptr;
 
   Stmt *element = OS->getElement();
   if (DeclStmt *DS = dyn_cast<DeclStmt>(element)) {
@@ -526,12 +493,12 @@
   // No CFG?  Bail out.
   CFG *cfg = AC.getCFG();
   if (!cfg)
-    return 0;
+    return nullptr;
 
   // The analysis currently has scalability issues for very large CFGs.
   // Bail out if it looks too large.
   if (cfg->getNumBlockIDs() > 300000)
-    return 0;
+    return nullptr;
 
   LiveVariablesImpl *LV = new LiveVariablesImpl(AC, killAtAssign);
 
@@ -599,16 +566,6 @@
   return new LiveVariables(LV);
 }
 
-static bool compare_entries(const CFGBlock *A, const CFGBlock *B) {
-  return A->getBlockID() < B->getBlockID();
-}
-
-static bool compare_vd_entries(const Decl *A, const Decl *B) {
-  SourceLocation ALoc = A->getLocStart();
-  SourceLocation BLoc = B->getLocStart();
-  return ALoc.getRawEncoding() < BLoc.getRawEncoding();
-}
-
 void LiveVariables::dumpBlockLiveness(const SourceManager &M) {
   getImpl(impl).dumpBlockLiveness(M);
 }
@@ -620,7 +577,9 @@
        it != ei; ++it) {
     vec.push_back(it->first);    
   }
-  std::sort(vec.begin(), vec.end(), compare_entries);
+  std::sort(vec.begin(), vec.end(), [](const CFGBlock *A, const CFGBlock *B) {
+    return A->getBlockID() < B->getBlockID();
+  });
 
   std::vector<const VarDecl*> declVec;
 
@@ -637,9 +596,11 @@
           se = vals.liveDecls.end(); si != se; ++si) {
       declVec.push_back(*si);      
     }
-    
-    std::sort(declVec.begin(), declVec.end(), compare_vd_entries);
-    
+
+    std::sort(declVec.begin(), declVec.end(), [](const Decl *A, const Decl *B) {
+      return A->getLocStart() < B->getLocStart();
+    });
+
     for (std::vector<const VarDecl*>::iterator di = declVec.begin(),
          de = declVec.end(); di != de; ++di) {
       llvm::errs() << " " << (*di)->getDeclName().getAsString()
diff --git a/lib/Analysis/PostOrderCFGView.cpp b/lib/Analysis/PostOrderCFGView.cpp
index cfd66f7..5a3c8182 100644
--- a/lib/Analysis/PostOrderCFGView.cpp
+++ b/lib/Analysis/PostOrderCFGView.cpp
@@ -31,7 +31,7 @@
 PostOrderCFGView *PostOrderCFGView::create(AnalysisDeclContext &ctx) {
   const CFG *cfg = ctx.getCFG();
   if (!cfg)
-    return 0;
+    return nullptr;
   return new PostOrderCFGView(cfg);
 }
 
diff --git a/lib/Analysis/PrintfFormatString.cpp b/lib/Analysis/PrintfFormatString.cpp
index f21b407..082a832 100644
--- a/lib/Analysis/PrintfFormatString.cpp
+++ b/lib/Analysis/PrintfFormatString.cpp
@@ -60,7 +60,7 @@
   using namespace clang::analyze_printf;
 
   const char *I = Beg;
-  const char *Start = 0;
+  const char *Start = nullptr;
   UpdateOnReturn <const char*> UpdateBeg(Beg, I);
 
   // Look for a '%' character that indicates the start of a format specifier.
@@ -124,7 +124,7 @@
 
   // Look for the field width (if any).
   if (ParseFieldWidth(H, FS, Start, I, E,
-                      FS.usesPositionalArg() ? 0 : &argIndex))
+                      FS.usesPositionalArg() ? nullptr : &argIndex))
     return true;
 
   if (I == E) {
@@ -142,7 +142,7 @@
     }
 
     if (ParsePrecision(H, FS, Start, I, E,
-                       FS.usesPositionalArg() ? 0 : &argIndex))
+                       FS.usesPositionalArg() ? nullptr : &argIndex))
       return true;
 
     if (I == E) {
diff --git a/lib/Analysis/ProgramPoint.cpp b/lib/Analysis/ProgramPoint.cpp
index 7d67e8a..26b59bb 100644
--- a/lib/Analysis/ProgramPoint.cpp
+++ b/lib/Analysis/ProgramPoint.cpp
@@ -43,9 +43,10 @@
   }
 }
 
-SimpleProgramPointTag::SimpleProgramPointTag(StringRef description)
-  : desc(description) {}
+SimpleProgramPointTag::SimpleProgramPointTag(StringRef MsgProvider, 
+                                             StringRef Msg)
+  : Desc((MsgProvider + " : " + Msg).str()) {}
 
 StringRef SimpleProgramPointTag::getTagDescription() const {
-  return desc;
+  return Desc;
 }
diff --git a/lib/Analysis/PseudoConstantAnalysis.cpp b/lib/Analysis/PseudoConstantAnalysis.cpp
index 5d659ce..3f96ca8 100644
--- a/lib/Analysis/PseudoConstantAnalysis.cpp
+++ b/lib/Analysis/PseudoConstantAnalysis.cpp
@@ -70,7 +70,7 @@
   if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(E))
     return DR->getDecl();
   else
-    return 0;
+    return nullptr;
 }
 
 void PseudoConstantAnalysis::RunAnalysis() {
@@ -171,10 +171,9 @@
     case Stmt::DeclStmtClass: {
       const DeclStmt *DS = cast<DeclStmt>(Head);
       // Iterate over each decl and see if any of them contain reference decls
-      for (DeclStmt::const_decl_iterator I = DS->decl_begin(),
-          E = DS->decl_end(); I != E; ++I) {
+      for (const auto *I : DS->decls()) {
         // We only care about VarDecls
-        const VarDecl *VD = dyn_cast<VarDecl>(*I);
+        const VarDecl *VD = dyn_cast<VarDecl>(I);
         if (!VD)
           continue;
 
diff --git a/lib/Analysis/ReachableCode.cpp b/lib/Analysis/ReachableCode.cpp
index a2d19c0..b4a72a7 100644
--- a/lib/Analysis/ReachableCode.cpp
+++ b/lib/Analysis/ReachableCode.cpp
@@ -13,10 +13,12 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Analysis/Analyses/ReachableCode.h"
+#include "clang/Lex/Preprocessor.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/StmtCXX.h"
+#include "clang/AST/ParentMap.h"
 #include "clang/Analysis/AnalysisContext.h"
 #include "clang/Analysis/CFG.h"
 #include "clang/Basic/SourceManager.h"
@@ -25,36 +27,352 @@
 
 using namespace clang;
 
-namespace {
-class DeadCodeScan {
-  llvm::BitVector Visited;
-  llvm::BitVector &Reachable;
-  SmallVector<const CFGBlock *, 10> WorkList;
-  
-  typedef SmallVector<std::pair<const CFGBlock *, const Stmt *>, 12>
-      DeferredLocsTy;
-  
-  DeferredLocsTy DeferredLocs;
-  
-public:
-  DeadCodeScan(llvm::BitVector &reachable)
-    : Visited(reachable.size()),
-      Reachable(reachable) {}
-  
-  void enqueue(const CFGBlock *block);  
-  unsigned scanBackwards(const CFGBlock *Start,
-                         clang::reachable_code::Callback &CB);
-  
-  bool isDeadCodeRoot(const CFGBlock *Block);
-  
-  const Stmt *findDeadCode(const CFGBlock *Block);
-  
-  void reportDeadCode(const Stmt *S,
-                      clang::reachable_code::Callback &CB);
-};
+//===----------------------------------------------------------------------===//
+// Core Reachability Analysis routines.
+//===----------------------------------------------------------------------===//
+
+static bool isEnumConstant(const Expr *Ex) {
+  const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Ex);
+  if (!DR)
+    return false;
+  return isa<EnumConstantDecl>(DR->getDecl());
 }
 
-void DeadCodeScan::enqueue(const CFGBlock *block) {  
+static bool isTrivialExpression(const Expr *Ex) {
+  Ex = Ex->IgnoreParenCasts();
+  return isa<IntegerLiteral>(Ex) || isa<StringLiteral>(Ex) ||
+         isa<CXXBoolLiteralExpr>(Ex) || isa<ObjCBoolLiteralExpr>(Ex) ||
+         isa<CharacterLiteral>(Ex) ||
+         isEnumConstant(Ex);
+}
+
+static bool isTrivialDoWhile(const CFGBlock *B, const Stmt *S) {
+  // Check if the block ends with a do...while() and see if 'S' is the
+  // condition.
+  if (const Stmt *Term = B->getTerminator()) {
+    if (const DoStmt *DS = dyn_cast<DoStmt>(Term)) {
+      const Expr *Cond = DS->getCond()->IgnoreParenCasts();
+      return Cond == S && isTrivialExpression(Cond);
+    }
+  }
+  return false;
+}
+
+static bool isDeadReturn(const CFGBlock *B, const Stmt *S) {
+  // Look to see if the current control flow ends with a 'return', and see if
+  // 'S' is a substatement. The 'return' may not be the last element in the
+  // block, or may be in a subsequent block because of destructors.
+  const CFGBlock *Current = B;
+  while (true) {
+    for (CFGBlock::const_reverse_iterator I = Current->rbegin(),
+                                          E = Current->rend();
+         I != E; ++I) {
+      if (Optional<CFGStmt> CS = I->getAs<CFGStmt>()) {
+        if (const ReturnStmt *RS = dyn_cast<ReturnStmt>(CS->getStmt())) {
+          if (RS == S)
+            return true;
+          if (const Expr *RE = RS->getRetValue()) {
+            RE = RE->IgnoreParenCasts();
+            if (RE == S)
+              return true;
+            ParentMap PM(const_cast<Expr *>(RE));
+            // If 'S' is in the ParentMap, it is a subexpression of
+            // the return statement.
+            return PM.getParent(S);
+          }
+        }
+        break;
+      }
+    }
+    // Note also that we are restricting the search for the return statement
+    // to stop at control-flow; only part of a return statement may be dead,
+    // without the whole return statement being dead.
+    if (Current->getTerminator().isTemporaryDtorsBranch()) {
+      // Temporary destructors have a predictable control flow, thus we want to
+      // look into the next block for the return statement.
+      // We look into the false branch, as we know the true branch only contains
+      // the call to the destructor.
+      assert(Current->succ_size() == 2);
+      Current = *(Current->succ_begin() + 1);
+    } else if (!Current->getTerminator() && Current->succ_size() == 1) {
+      // If there is only one successor, we're not dealing with outgoing control
+      // flow. Thus, look into the next block.
+      Current = *Current->succ_begin();
+      if (Current->pred_size() > 1) {
+        // If there is more than one predecessor, we're dealing with incoming
+        // control flow - if the return statement is in that block, it might
+        // well be reachable via a different control flow, thus it's not dead.
+        return false;
+      }
+    } else {
+      // We hit control flow or a dead end. Stop searching.
+      return false;
+    }
+  }
+  llvm_unreachable("Broke out of infinite loop.");
+}
+
+static SourceLocation getTopMostMacro(SourceLocation Loc, SourceManager &SM) {
+  assert(Loc.isMacroID());
+  SourceLocation Last;
+  while (Loc.isMacroID()) {
+    Last = Loc;
+    Loc = SM.getImmediateMacroCallerLoc(Loc);
+  }
+  return Last;
+}
+
+/// Returns true if the statement is expanded from a configuration macro.
+static bool isExpandedFromConfigurationMacro(const Stmt *S,
+                                             Preprocessor &PP,
+                                             bool IgnoreYES_NO = false) {
+  // FIXME: This is not very precise.  Here we just check to see if the
+  // value comes from a macro, but we can do much better.  This is likely
+  // to be over conservative.  This logic is factored into a separate function
+  // so that we can refine it later.
+  SourceLocation L = S->getLocStart();
+  if (L.isMacroID()) {
+    if (IgnoreYES_NO) {
+      // The Objective-C constant 'YES' and 'NO'
+      // are defined as macros.  Do not treat them
+      // as configuration values.
+      SourceManager &SM = PP.getSourceManager();
+      SourceLocation TopL = getTopMostMacro(L, SM);
+      StringRef MacroName = PP.getImmediateMacroName(TopL);
+      if (MacroName == "YES" || MacroName == "NO")
+        return false;
+    }
+    return true;
+  }
+  return false;
+}
+
+static bool isConfigurationValue(const ValueDecl *D, Preprocessor &PP);
+
+/// Returns true if the statement represents a configuration value.
+///
+/// A configuration value is something usually determined at compile-time
+/// to conditionally always execute some branch.  Such guards are for
+/// "sometimes unreachable" code.  Such code is usually not interesting
+/// to report as unreachable, and may mask truly unreachable code within
+/// those blocks.
+static bool isConfigurationValue(const Stmt *S,
+                                 Preprocessor &PP,
+                                 SourceRange *SilenceableCondVal = nullptr,
+                                 bool IncludeIntegers = true,
+                                 bool WrappedInParens = false) {
+  if (!S)
+    return false;
+
+  if (const Expr *Ex = dyn_cast<Expr>(S))
+    S = Ex->IgnoreCasts();
+
+  // Special case looking for the sigil '()' around an integer literal.
+  if (const ParenExpr *PE = dyn_cast<ParenExpr>(S))
+    if (!PE->getLocStart().isMacroID())
+      return isConfigurationValue(PE->getSubExpr(), PP, SilenceableCondVal, 
+                                  IncludeIntegers, true);
+
+  if (const Expr *Ex = dyn_cast<Expr>(S))
+    S = Ex->IgnoreCasts();
+
+  bool IgnoreYES_NO = false;
+
+  switch (S->getStmtClass()) {
+    case Stmt::CallExprClass: {
+      const FunctionDecl *Callee =
+        dyn_cast_or_null<FunctionDecl>(cast<CallExpr>(S)->getCalleeDecl());
+      return Callee ? Callee->isConstexpr() : false;
+    }
+    case Stmt::DeclRefExprClass:
+      return isConfigurationValue(cast<DeclRefExpr>(S)->getDecl(), PP);
+    case Stmt::ObjCBoolLiteralExprClass:
+      IgnoreYES_NO = true;
+      // Fallthrough.
+    case Stmt::CXXBoolLiteralExprClass:
+    case Stmt::IntegerLiteralClass: {
+      const Expr *E = cast<Expr>(S);
+      if (IncludeIntegers) {
+        if (SilenceableCondVal && !SilenceableCondVal->getBegin().isValid())
+          *SilenceableCondVal = E->getSourceRange();
+        return WrappedInParens || isExpandedFromConfigurationMacro(E, PP, IgnoreYES_NO);
+      }
+      return false;
+    }
+    case Stmt::MemberExprClass:
+      return isConfigurationValue(cast<MemberExpr>(S)->getMemberDecl(), PP);
+    case Stmt::UnaryExprOrTypeTraitExprClass:
+      return true;
+    case Stmt::BinaryOperatorClass: {
+      const BinaryOperator *B = cast<BinaryOperator>(S);
+      // Only include raw integers (not enums) as configuration
+      // values if they are used in a logical or comparison operator
+      // (not arithmetic).
+      IncludeIntegers &= (B->isLogicalOp() || B->isComparisonOp());
+      return isConfigurationValue(B->getLHS(), PP, SilenceableCondVal,
+                                  IncludeIntegers) ||
+             isConfigurationValue(B->getRHS(), PP, SilenceableCondVal,
+                                  IncludeIntegers);
+    }
+    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);
+    }
+    default:
+      return false;
+  }
+}
+
+static bool isConfigurationValue(const ValueDecl *D, Preprocessor &PP) {
+  if (const EnumConstantDecl *ED = dyn_cast<EnumConstantDecl>(D))
+    return isConfigurationValue(ED->getInitExpr(), PP);
+  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+    // As a heuristic, treat globals as configuration values.  Note
+    // that we only will get here if Sema evaluated this
+    // condition to a constant expression, which means the global
+    // had to be declared in a way to be a truly constant value.
+    // We could generalize this to local variables, but it isn't
+    // clear if those truly represent configuration values that
+    // gate unreachable code.
+    if (!VD->hasLocalStorage())
+      return true;
+
+    // As a heuristic, locals that have been marked 'const' explicitly
+    // can be treated as configuration values as well.
+    return VD->getType().isLocalConstQualified();
+  }
+  return false;
+}
+
+/// Returns true if we should always explore all successors of a block.
+static bool shouldTreatSuccessorsAsReachable(const CFGBlock *B,
+                                             Preprocessor &PP) {
+  if (const Stmt *Term = B->getTerminator()) {
+    if (isa<SwitchStmt>(Term))
+      return true;
+    // Specially handle '||' and '&&'.
+    if (isa<BinaryOperator>(Term)) {
+      return isConfigurationValue(Term, PP);
+    }
+  }
+
+  const Stmt *Cond = B->getTerminatorCondition(/* stripParens */ false);
+  return isConfigurationValue(Cond, PP);
+}
+
+static unsigned scanFromBlock(const CFGBlock *Start,
+                              llvm::BitVector &Reachable,
+                              Preprocessor *PP,
+                              bool IncludeSometimesUnreachableEdges) {
+  unsigned count = 0;
+  
+  // Prep work queue
+  SmallVector<const CFGBlock*, 32> WL;
+  
+  // The entry block may have already been marked reachable
+  // by the caller.
+  if (!Reachable[Start->getBlockID()]) {
+    ++count;
+    Reachable[Start->getBlockID()] = true;
+  }
+  
+  WL.push_back(Start);
+  
+  // Find the reachable blocks from 'Start'.
+  while (!WL.empty()) {
+    const CFGBlock *item = WL.pop_back_val();
+
+    // There are cases where we want to treat all successors as reachable.
+    // The idea is that some "sometimes unreachable" code is not interesting,
+    // and that we should forge ahead and explore those branches anyway.
+    // This allows us to potentially uncover some "always unreachable" code
+    // within the "sometimes unreachable" code.
+    // Look at the successors and mark then reachable.
+    Optional<bool> TreatAllSuccessorsAsReachable;
+    if (!IncludeSometimesUnreachableEdges)
+      TreatAllSuccessorsAsReachable = false;
+
+    for (CFGBlock::const_succ_iterator I = item->succ_begin(), 
+         E = item->succ_end(); I != E; ++I) {
+      const CFGBlock *B = *I;
+      if (!B) do {
+        const CFGBlock *UB = I->getPossiblyUnreachableBlock();
+        if (!UB)
+          break;
+
+        if (!TreatAllSuccessorsAsReachable.hasValue()) {
+          assert(PP);
+          TreatAllSuccessorsAsReachable =
+            shouldTreatSuccessorsAsReachable(item, *PP);
+        }
+
+        if (TreatAllSuccessorsAsReachable.getValue()) {
+          B = UB;
+          break;
+        }
+      }
+      while (false);
+
+      if (B) {
+        unsigned blockID = B->getBlockID();
+        if (!Reachable[blockID]) {
+          Reachable.set(blockID);
+          WL.push_back(B);
+          ++count;
+        }
+      }
+    }
+  }
+  return count;
+}
+
+static unsigned scanMaybeReachableFromBlock(const CFGBlock *Start,
+                                            Preprocessor &PP,
+                                            llvm::BitVector &Reachable) {
+  return scanFromBlock(Start, Reachable, &PP, true);
+}
+
+//===----------------------------------------------------------------------===//
+// Dead Code Scanner.
+//===----------------------------------------------------------------------===//
+
+namespace {
+  class DeadCodeScan {
+    llvm::BitVector Visited;
+    llvm::BitVector &Reachable;
+    SmallVector<const CFGBlock *, 10> WorkList;
+    Preprocessor &PP;
+
+    typedef SmallVector<std::pair<const CFGBlock *, const Stmt *>, 12>
+    DeferredLocsTy;
+
+    DeferredLocsTy DeferredLocs;
+
+  public:
+    DeadCodeScan(llvm::BitVector &reachable, Preprocessor &PP)
+    : Visited(reachable.size()),
+      Reachable(reachable),
+      PP(PP) {}
+
+    void enqueue(const CFGBlock *block);
+    unsigned scanBackwards(const CFGBlock *Start,
+    clang::reachable_code::Callback &CB);
+
+    bool isDeadCodeRoot(const CFGBlock *Block);
+
+    const Stmt *findDeadCode(const CFGBlock *Block);
+
+    void reportDeadCode(const CFGBlock *B,
+                        const Stmt *S,
+                        clang::reachable_code::Callback &CB);
+  };
+}
+
+void DeadCodeScan::enqueue(const CFGBlock *block) {
   unsigned blockID = block->getBlockID();
   if (Reachable[blockID] || Visited[blockID])
     return;
@@ -64,9 +382,9 @@
 
 bool DeadCodeScan::isDeadCodeRoot(const clang::CFGBlock *Block) {
   bool isDeadRoot = true;
-  
+
   for (CFGBlock::const_pred_iterator I = Block->pred_begin(),
-        E = Block->pred_end(); I != E; ++I) {
+       E = Block->pred_end(); I != E; ++I) {
     if (const CFGBlock *PredBlock = *I) {
       unsigned blockID = PredBlock->getBlockID();
       if (Visited[blockID]) {
@@ -81,7 +399,7 @@
       }
     }
   }
-  
+
   return isDeadRoot;
 }
 
@@ -100,14 +418,16 @@
       if (isValidDeadStmt(S))
         return S;
     }
-  
+
   if (CFGTerminator T = Block->getTerminator()) {
-    const Stmt *S = T.getStmt();
-    if (isValidDeadStmt(S))
-      return S;    
+    if (!T.isTemporaryDtorsBranch()) {
+      const Stmt *S = T.getStmt();
+      if (isValidDeadStmt(S))
+        return S;
+    }
   }
 
-  return 0;
+  return nullptr;
 }
 
 static int SrcCmp(const std::pair<const CFGBlock *, const Stmt *> *p1,
@@ -124,7 +444,7 @@
 
   unsigned count = 0;
   enqueue(Start);
-  
+
   while (!WorkList.empty()) {
     const CFGBlock *Block = WorkList.pop_back_val();
 
@@ -135,7 +455,7 @@
 
     // Look for any dead code within the block.
     const Stmt *S = findDeadCode(Block);
-    
+
     if (!S) {
       // No dead code.  Possibly an empty block.  Look at dead predecessors.
       for (CFGBlock::const_pred_iterator I = Block->pred_begin(),
@@ -145,16 +465,16 @@
       }
       continue;
     }
-    
+
     // Specially handle macro-expanded code.
     if (S->getLocStart().isMacroID()) {
-      count += clang::reachable_code::ScanReachableFromBlock(Block, Reachable);
+      count += scanMaybeReachableFromBlock(Block, PP, Reachable);
       continue;
     }
 
     if (isDeadCodeRoot(Block)) {
-      reportDeadCode(S, CB);
-      count += clang::reachable_code::ScanReachableFromBlock(Block, Reachable);
+      reportDeadCode(Block, S, CB);
+      count += scanMaybeReachableFromBlock(Block, PP, Reachable);
     }
     else {
       // Record this statement as the possibly best location in a
@@ -169,15 +489,15 @@
   if (!DeferredLocs.empty()) {
     llvm::array_pod_sort(DeferredLocs.begin(), DeferredLocs.end(), SrcCmp);
     for (DeferredLocsTy::iterator I = DeferredLocs.begin(),
-          E = DeferredLocs.end(); I != E; ++I) {
-      const CFGBlock *block = I->first;
-      if (Reachable[block->getBlockID()])
+         E = DeferredLocs.end(); I != E; ++I) {
+      const CFGBlock *Block = I->first;
+      if (Reachable[Block->getBlockID()])
         continue;
-      reportDeadCode(I->second, CB);
-      count += clang::reachable_code::ScanReachableFromBlock(block, Reachable);
+      reportDeadCode(Block, I->second, CB);
+      count += scanMaybeReachableFromBlock(Block, PP, Reachable);
     }
   }
-    
+
   return count;
 }
 
@@ -208,7 +528,7 @@
     case Expr::BinaryConditionalOperatorClass:
     case Expr::ConditionalOperatorClass: {
       const AbstractConditionalOperator *CO =
-        cast<AbstractConditionalOperator>(S);
+      cast<AbstractConditionalOperator>(S);
       return CO->getQuestionLoc();
     }
     case Expr::MemberExprClass: {
@@ -246,61 +566,86 @@
   return S->getLocStart();
 }
 
-void DeadCodeScan::reportDeadCode(const Stmt *S,
+void DeadCodeScan::reportDeadCode(const CFGBlock *B,
+                                  const Stmt *S,
                                   clang::reachable_code::Callback &CB) {
+  // Classify the unreachable code found, or suppress it in some cases.
+  reachable_code::UnreachableKind UK = reachable_code::UK_Other;
+
+  if (isa<BreakStmt>(S)) {
+    UK = reachable_code::UK_Break;
+  }
+  else if (isTrivialDoWhile(B, S)) {
+    return;
+  }
+  else if (isDeadReturn(B, S)) {
+    UK = reachable_code::UK_Return;
+  }
+
+  SourceRange SilenceableCondVal;
+
+  if (UK == reachable_code::UK_Other) {
+    // Check if the dead code is part of the "loop target" of
+    // a for/for-range loop.  This is the block that contains
+    // the increment code.
+    if (const Stmt *LoopTarget = B->getLoopTarget()) {
+      SourceLocation Loc = LoopTarget->getLocStart();
+      SourceRange R1(Loc, Loc), R2;
+
+      if (const ForStmt *FS = dyn_cast<ForStmt>(LoopTarget)) {
+        const Expr *Inc = FS->getInc();
+        Loc = Inc->getLocStart();
+        R2 = Inc->getSourceRange();
+      }
+
+      CB.HandleUnreachable(reachable_code::UK_Loop_Increment,
+                           Loc, SourceRange(), SourceRange(Loc, Loc), R2);
+      return;
+    }
+    
+    // Check if the dead block has a predecessor whose branch has
+    // a configuration value that *could* be modified to
+    // silence the warning.
+    CFGBlock::const_pred_iterator PI = B->pred_begin();
+    if (PI != B->pred_end()) {
+      if (const CFGBlock *PredBlock = PI->getPossiblyUnreachableBlock()) {
+        const Stmt *TermCond =
+            PredBlock->getTerminatorCondition(/* strip parens */ false);
+        isConfigurationValue(TermCond, PP, &SilenceableCondVal);
+      }
+    }
+  }
+
   SourceRange R1, R2;
   SourceLocation Loc = GetUnreachableLoc(S, R1, R2);
-  CB.HandleUnreachable(Loc, R1, R2);
+  CB.HandleUnreachable(UK, Loc, SilenceableCondVal, R1, R2);
 }
 
+//===----------------------------------------------------------------------===//
+// Reachability APIs.
+//===----------------------------------------------------------------------===//
+
 namespace clang { namespace reachable_code {
 
-void Callback::anchor() { }  
+void Callback::anchor() { }
 
 unsigned ScanReachableFromBlock(const CFGBlock *Start,
                                 llvm::BitVector &Reachable) {
-  unsigned count = 0;
-  
-  // Prep work queue
-  SmallVector<const CFGBlock*, 32> WL;
-  
-  // The entry block may have already been marked reachable
-  // by the caller.
-  if (!Reachable[Start->getBlockID()]) {
-    ++count;
-    Reachable[Start->getBlockID()] = true;
-  }
-  
-  WL.push_back(Start);
-  
-  // Find the reachable blocks from 'Start'.
-  while (!WL.empty()) {
-    const CFGBlock *item = WL.pop_back_val();
-    
-    // Look at the successors and mark then reachable.
-    for (CFGBlock::const_succ_iterator I = item->succ_begin(), 
-         E = item->succ_end(); I != E; ++I)
-      if (const CFGBlock *B = *I) {
-        unsigned blockID = B->getBlockID();
-        if (!Reachable[blockID]) {
-          Reachable.set(blockID);
-          WL.push_back(B);
-          ++count;
-        }
-      }
-  }
-  return count;
+  return scanFromBlock(Start, Reachable, /* SourceManager* */ nullptr, false);
 }
-  
-void FindUnreachableCode(AnalysisDeclContext &AC, Callback &CB) {
+
+void FindUnreachableCode(AnalysisDeclContext &AC, Preprocessor &PP,
+                         Callback &CB) {
+
   CFG *cfg = AC.getCFG();
   if (!cfg)
     return;
 
-  // Scan for reachable blocks from the entrance of the CFG.  
+  // Scan for reachable blocks from the entrance of the CFG.
   // If there are no unreachable blocks, we're done.
   llvm::BitVector reachable(cfg->getNumBlockIDs());
-  unsigned numReachable = ScanReachableFromBlock(&cfg->getEntry(), reachable);
+  unsigned numReachable =
+    scanMaybeReachableFromBlock(&cfg->getEntry(), PP, reachable);
   if (numReachable == cfg->getNumBlockIDs())
     return;
   
@@ -309,7 +654,7 @@
   if (!AC.getCFGBuildOptions().AddEHEdges) {
     for (CFG::try_block_iterator I = cfg->try_blocks_begin(),
          E = cfg->try_blocks_end() ; I != E; ++I) {
-      numReachable += ScanReachableFromBlock(*I, reachable);
+      numReachable += scanMaybeReachableFromBlock(*I, PP, reachable);
     }
     if (numReachable == cfg->getNumBlockIDs())
       return;
@@ -323,7 +668,7 @@
     if (reachable[block->getBlockID()])
       continue;
     
-    DeadCodeScan DS(reachable);
+    DeadCodeScan DS(reachable, PP);
     numReachable += DS.scanBackwards(block, CB);
     
     if (numReachable == cfg->getNumBlockIDs())
diff --git a/lib/Analysis/ScanfFormatString.cpp b/lib/Analysis/ScanfFormatString.cpp
index f5ce84f..ed28627 100644
--- a/lib/Analysis/ScanfFormatString.cpp
+++ b/lib/Analysis/ScanfFormatString.cpp
@@ -50,6 +50,15 @@
     }
   }
 
+  // Special case: "^]" are the first characters.
+  if (I + 1 != E && I[0] == '^' && I[1] == ']') {
+    I += 2;
+    if (I == E) {
+      H.HandleIncompleteScanList(start, I - 1);
+      return true;
+    }
+  }
+
   // Look for a ']' character which denotes the end of the scan list.
   while (*I != ']') {
     if (++I == E) {
@@ -73,7 +82,7 @@
   
   using namespace clang::analyze_scanf;
   const char *I = Beg;
-  const char *Start = 0;
+  const char *Start = nullptr;
   UpdateOnReturn <const char*> UpdateBeg(Beg, I);
 
     // Look for a '%' character that indicates the start of a format specifier.
@@ -379,21 +388,23 @@
   return ArgType();
 }
 
-bool ScanfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
+bool ScanfSpecifier::fixType(QualType QT, QualType RawQT,
+                             const LangOptions &LangOpt,
                              ASTContext &Ctx) {
-  if (!QT->isPointerType())
-    return false;
 
   // %n is different from other conversion specifiers; don't try to fix it.
   if (CS.getKind() == ConversionSpecifier::nArg)
     return false;
 
+  if (!QT->isPointerType())
+    return false;
+
   QualType PT = QT->getPointeeType();
 
   // If it's an enum, get its underlying type.
-  if (const EnumType *ETy = QT->getAs<EnumType>())
-    QT = ETy->getDecl()->getIntegerType();
-  
+  if (const EnumType *ETy = PT->getAs<EnumType>())
+    PT = ETy->getDecl()->getIntegerType();
+
   const BuiltinType *BT = PT->getAs<BuiltinType>();
   if (!BT)
     return false;
@@ -405,6 +416,15 @@
       LM.setKind(LengthModifier::AsWideChar);
     else
       LM.setKind(LengthModifier::None);
+
+    // If we know the target array length, we can use it as a field width.
+    if (const ConstantArrayType *CAT = Ctx.getAsConstantArrayType(RawQT)) {
+      if (CAT->getSizeModifier() == ArrayType::Normal)
+        FieldWidth = OptionalAmount(OptionalAmount::Constant,
+                                    CAT->getSize().getZExtValue() - 1,
+                                    "", 0, false);
+
+    }
     return true;
   }
 
diff --git a/lib/Analysis/ThreadSafety.cpp b/lib/Analysis/ThreadSafety.cpp
index 0a40b57..11df61f 100644
--- a/lib/Analysis/ThreadSafety.cpp
+++ b/lib/Analysis/ThreadSafety.cpp
@@ -10,18 +10,22 @@
 // A intra-procedural analysis for thread safety (e.g. deadlocks and race
 // conditions), based off of an annotation system.
 //
-// See http://clang.llvm.org/docs/LanguageExtensions.html#thread-safety-annotation-checking
+// See http://clang.llvm.org/docs/ThreadSafetyAnalysis.html
 // for more information.
 //
 //===----------------------------------------------------------------------===//
 
-#include "clang/Analysis/Analyses/ThreadSafety.h"
 #include "clang/AST/Attr.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/StmtCXX.h"
 #include "clang/AST/StmtVisitor.h"
 #include "clang/Analysis/Analyses/PostOrderCFGView.h"
+#include "clang/Analysis/Analyses/ThreadSafety.h"
+#include "clang/Analysis/Analyses/ThreadSafetyLogical.h"
+#include "clang/Analysis/Analyses/ThreadSafetyTIL.h"
+#include "clang/Analysis/Analyses/ThreadSafetyTraverse.h"
+#include "clang/Analysis/Analyses/ThreadSafetyCommon.h"
 #include "clang/Analysis/AnalysisContext.h"
 #include "clang/Analysis/CFG.h"
 #include "clang/Analysis/CFGStmtMap.h"
@@ -172,12 +176,9 @@
     const Expr* const* FunArgs;    // Function arguments
     CallingContext*    PrevCtx;    // The previous context; or 0 if none.
 
-    CallingContext(const NamedDecl *D = 0, const Expr *S = 0,
-                   unsigned N = 0, const Expr* const *A = 0,
-                   CallingContext *P = 0)
-      : AttrDecl(D), SelfArg(S), SelfArrow(false),
-        NumArgs(N), FunArgs(A), PrevCtx(P)
-    { }
+    CallingContext(const NamedDecl *D)
+        : AttrDecl(D), SelfArg(nullptr), SelfArrow(false), NumArgs(0),
+          FunArgs(nullptr), PrevCtx(nullptr) {}
   };
 
   typedef SmallVector<SExprNode, 4> NodeVector;
@@ -188,44 +189,41 @@
   NodeVector NodeVec;
 
 private:
+  unsigned make(ExprOp O, unsigned F = 0, const void *D = nullptr) {
+    NodeVec.push_back(SExprNode(O, F, D));
+    return NodeVec.size() - 1;
+  }
+
   unsigned makeNop() {
-    NodeVec.push_back(SExprNode(EOP_Nop, 0, 0));
-    return NodeVec.size()-1;
+    return make(EOP_Nop);
   }
 
   unsigned makeWildcard() {
-    NodeVec.push_back(SExprNode(EOP_Wildcard, 0, 0));
-    return NodeVec.size()-1;
+    return make(EOP_Wildcard);
   }
 
   unsigned makeUniversal() {
-    NodeVec.push_back(SExprNode(EOP_Universal, 0, 0));
-    return NodeVec.size()-1;
+    return make(EOP_Universal);
   }
 
   unsigned makeNamedVar(const NamedDecl *D) {
-    NodeVec.push_back(SExprNode(EOP_NVar, 0, D));
-    return NodeVec.size()-1;
+    return make(EOP_NVar, 0, D);
   }
 
   unsigned makeLocalVar(const NamedDecl *D) {
-    NodeVec.push_back(SExprNode(EOP_LVar, 0, D));
-    return NodeVec.size()-1;
+    return make(EOP_LVar, 0, D);
   }
 
   unsigned makeThis() {
-    NodeVec.push_back(SExprNode(EOP_This, 0, 0));
-    return NodeVec.size()-1;
+    return make(EOP_This);
   }
 
   unsigned makeDot(const NamedDecl *D, bool Arrow) {
-    NodeVec.push_back(SExprNode(EOP_Dot, Arrow ? 1 : 0, D));
-    return NodeVec.size()-1;
+    return make(EOP_Dot, Arrow ? 1 : 0, D);
   }
 
   unsigned makeCall(unsigned NumArgs, const NamedDecl *D) {
-    NodeVec.push_back(SExprNode(EOP_Call, NumArgs, D));
-    return NodeVec.size()-1;
+    return make(EOP_Call, NumArgs, D);
   }
 
   // Grab the very first declaration of virtual method D
@@ -238,32 +236,32 @@
         return D;  // Method does not override anything
       D = *I;      // FIXME: this does not work with multiple inheritance.
     }
-    return 0;
+    return nullptr;
   }
 
   unsigned makeMCall(unsigned NumArgs, const CXXMethodDecl *D) {
-    NodeVec.push_back(SExprNode(EOP_MCall, NumArgs, getFirstVirtualDecl(D)));
-    return NodeVec.size()-1;
+    return make(EOP_MCall, NumArgs, getFirstVirtualDecl(D));
   }
 
   unsigned makeIndex() {
-    NodeVec.push_back(SExprNode(EOP_Index, 0, 0));
-    return NodeVec.size()-1;
+    return make(EOP_Index);
   }
 
   unsigned makeUnary() {
-    NodeVec.push_back(SExprNode(EOP_Unary, 0, 0));
-    return NodeVec.size()-1;
+    return make(EOP_Unary);
   }
 
   unsigned makeBinary() {
-    NodeVec.push_back(SExprNode(EOP_Binary, 0, 0));
-    return NodeVec.size()-1;
+    return make(EOP_Binary);
   }
 
   unsigned makeUnknown(unsigned Arity) {
-    NodeVec.push_back(SExprNode(EOP_Unknown, Arity, 0));
-    return NodeVec.size()-1;
+    return make(EOP_Unknown, Arity);
+  }
+
+  inline bool isCalleeArrow(const Expr *E) {
+    const MemberExpr *ME = dyn_cast<MemberExpr>(E->IgnoreParenCasts());
+    return ME ? ME->isArrow() : false;
   }
 
   /// Build an SExpr from the given C++ expression.
@@ -272,10 +270,10 @@
   /// ensure that the original expression is a valid mutex expression.
   ///
   /// NDeref returns the number of Derefence and AddressOf operations
-  /// preceeding the Expr; this is used to decide whether to pretty-print
+  /// preceding the Expr; this is used to decide whether to pretty-print
   /// SExprs with . or ->.
-  unsigned buildSExpr(const Expr *Exp, CallingContext* CallCtx,
-                      int* NDeref = 0) {
+  unsigned buildSExpr(const Expr *Exp, CallingContext *CallCtx,
+                      int *NDeref = nullptr) {
     if (!Exp)
       return 0;
 
@@ -327,8 +325,7 @@
       if (LockReturnedAttr* At = MD->getAttr<LockReturnedAttr>()) {
         CallingContext LRCallCtx(CMCE->getMethodDecl());
         LRCallCtx.SelfArg = CMCE->getImplicitObjectArgument();
-        LRCallCtx.SelfArrow =
-          dyn_cast<MemberExpr>(CMCE->getCallee())->isArrow();
+        LRCallCtx.SelfArrow = isCalleeArrow(CMCE->getCallee());
         LRCallCtx.NumArgs = CMCE->getNumArgs();
         LRCallCtx.FunArgs = CMCE->getArgs();
         LRCallCtx.PrevCtx = CallCtx;
@@ -338,7 +335,7 @@
       // ignore any method named get().
       if (CMCE->getMethodDecl()->getNameAsString() == "get" &&
           CMCE->getNumArgs() == 0) {
-        if (NDeref && dyn_cast<MemberExpr>(CMCE->getCallee())->isArrow())
+        if (NDeref && isCalleeArrow(CMCE->getCallee()))
           ++(*NDeref);
         return buildSExpr(CMCE->getImplicitObjectArgument(), CallCtx, NDeref);
       }
@@ -373,7 +370,7 @@
         }
       }
       unsigned NumCallArgs = CE->getNumArgs();
-      unsigned Root = makeCall(NumCallArgs, 0);
+      unsigned Root = makeCall(NumCallArgs, nullptr);
       unsigned Sz = buildSExpr(CE->getCallee(), CallCtx);
       const Expr* const* CallArgs = CE->getArgs();
       for (unsigned i = 0; i < NumCallArgs; ++i) {
@@ -466,7 +463,7 @@
   ///        occurs.
   /// \param D  The declaration to which the lock/unlock attribute is attached.
   void buildSExprFromExpr(const Expr *MutexExp, const Expr *DeclExp,
-                          const NamedDecl *D, VarDecl *SelfDecl = 0) {
+                          const NamedDecl *D, VarDecl *SelfDecl = nullptr) {
     CallingContext CallCtx(D);
 
     if (MutexExp) {
@@ -483,8 +480,8 @@
     }
 
     // If we are processing a raw attribute expression, with no substitutions.
-    if (DeclExp == 0) {
-      buildSExpr(MutexExp, 0);
+    if (!DeclExp) {
+      buildSExpr(MutexExp, nullptr);
       return;
     }
 
@@ -496,16 +493,15 @@
     } else if (const CXXMemberCallExpr *CE =
                dyn_cast<CXXMemberCallExpr>(DeclExp)) {
       CallCtx.SelfArg   = CE->getImplicitObjectArgument();
-      CallCtx.SelfArrow = dyn_cast<MemberExpr>(CE->getCallee())->isArrow();
+      CallCtx.SelfArrow = isCalleeArrow(CE->getCallee());
       CallCtx.NumArgs   = CE->getNumArgs();
       CallCtx.FunArgs   = CE->getArgs();
-    } else if (const CallExpr *CE =
-               dyn_cast<CallExpr>(DeclExp)) {
+    } else if (const CallExpr *CE = dyn_cast<CallExpr>(DeclExp)) {
       CallCtx.NumArgs = CE->getNumArgs();
       CallCtx.FunArgs = CE->getArgs();
     } else if (const CXXConstructExpr *CE =
                dyn_cast<CXXConstructExpr>(DeclExp)) {
-      CallCtx.SelfArg = 0;  // Will be set below
+      CallCtx.SelfArg = nullptr;  // Will be set below
       CallCtx.NumArgs = CE->getNumArgs();
       CallCtx.FunArgs = CE->getArgs();
     } else if (D && isa<CXXDestructorDecl>(D)) {
@@ -521,16 +517,16 @@
       CallCtx.SelfArg = &SelfDRE;
 
       // If the attribute has no arguments, then assume the argument is "this".
-      if (MutexExp == 0)
-        buildSExpr(CallCtx.SelfArg, 0);
+      if (!MutexExp)
+        buildSExpr(CallCtx.SelfArg, nullptr);
       else  // For most attributes.
         buildSExpr(MutexExp, &CallCtx);
       return;
     }
 
     // If the attribute has no arguments, then assume the argument is "this".
-    if (MutexExp == 0)
-      buildSExpr(CallCtx.SelfArg, 0);
+    if (!MutexExp)
+      buildSExpr(CallCtx.SelfArg, nullptr);
     else  // For most attributes.
       buildSExpr(MutexExp, &CallCtx);
   }
@@ -548,8 +544,8 @@
   ///        occurs.
   /// \param D  The declaration to which the lock/unlock attribute is attached.
   /// Caller must check isValid() after construction.
-  SExpr(const Expr* MutexExp, const Expr *DeclExp, const NamedDecl* D,
-        VarDecl *SelfDecl=0) {
+  SExpr(const Expr *MutexExp, const Expr *DeclExp, const NamedDecl *D,
+        VarDecl *SelfDecl = nullptr) {
     buildSExprFromExpr(MutexExp, DeclExp, D, SelfDecl);
   }
 
@@ -572,15 +568,15 @@
 
   /// Issue a warning about an invalid lock expression
   static void warnInvalidLock(ThreadSafetyHandler &Handler,
-                              const Expr *MutexExp,
-                              const Expr *DeclExp, const NamedDecl* D) {
+                              const Expr *MutexExp, const Expr *DeclExp,
+                              const NamedDecl *D, StringRef Kind) {
     SourceLocation Loc;
     if (DeclExp)
       Loc = DeclExp->getExprLoc();
 
     // FIXME: add a note about the attribute location in MutexExp or D
     if (Loc.isValid())
-      Handler.handleInvalidLockExp(Loc);
+      Handler.handleInvalidLockExp(Kind, Loc);
   }
 
   bool operator==(const SExpr &other) const {
@@ -713,27 +709,16 @@
   }
 };
 
-
-
 /// \brief A short list of SExprs
 class MutexIDList : public SmallVector<SExpr, 3> {
 public:
-  /// \brief Return true if the list contains the specified SExpr
-  /// Performs a linear search, because these lists are almost always very small.
-  bool contains(const SExpr& M) {
-    for (iterator I=begin(),E=end(); I != E; ++I)
-      if ((*I) == M) return true;
-    return false;
-  }
-
-  /// \brief Push M onto list, bud discard duplicates
+  /// \brief Push M onto list, but discard duplicates.
   void push_back_nodup(const SExpr& M) {
-    if (!contains(M)) push_back(M);
+    if (end() == std::find(begin(), end(), M))
+      push_back(M);
   }
 };
 
-
-
 /// \brief This is a helper class that stores info about the most recent
 /// accquire of a Lock.
 ///
@@ -864,45 +849,38 @@
     return false;
   }
 
-  // Returns an iterator
   iterator findLockIter(FactManager &FM, const SExpr &M) {
-    for (iterator I = begin(), E = end(); I != E; ++I) {
-      const SExpr &Exp = FM[*I].MutID;
-      if (Exp.matches(M))
-        return I;
-    }
-    return end();
+    return std::find_if(begin(), end(), [&](FactID ID) {
+      return FM[ID].MutID.matches(M);
+    });
   }
 
-  LockData* findLock(FactManager &FM, const SExpr &M) const {
-    for (const_iterator I = begin(), E = end(); I != E; ++I) {
-      const SExpr &Exp = FM[*I].MutID;
-      if (Exp.matches(M))
-        return &FM[*I].LDat;
-    }
-    return 0;
+  LockData *findLock(FactManager &FM, const SExpr &M) const {
+    auto I = std::find_if(begin(), end(), [&](FactID ID) {
+      return FM[ID].MutID.matches(M);
+    });
+
+    return I != end() ? &FM[*I].LDat : nullptr;
   }
 
-  LockData* findLockUniv(FactManager &FM, const SExpr &M) const {
-    for (const_iterator I = begin(), E = end(); I != E; ++I) {
-      const SExpr &Exp = FM[*I].MutID;
-      if (Exp.matches(M) || Exp.isUniversal())
-        return &FM[*I].LDat;
-    }
-    return 0;
+  LockData *findLockUniv(FactManager &FM, const SExpr &M) const {
+    auto I = std::find_if(begin(), end(), [&](FactID ID) -> bool {
+      const SExpr &Expr = FM[ID].MutID;
+      return Expr.isUniversal() || Expr.matches(M);
+    });
+
+    return I != end() ? &FM[*I].LDat : nullptr;
   }
 
-  FactEntry* findPartialMatch(FactManager &FM, const SExpr &M) const {
-    for (const_iterator I=begin(), E=end(); I != E; ++I) {
-      const SExpr& Exp = FM[*I].MutID;
-      if (Exp.partiallyMatches(M)) return &FM[*I];
-    }
-    return 0;
+  FactEntry *findPartialMatch(FactManager &FM, const SExpr &M) const {
+    auto I = std::find_if(begin(), end(), [&](FactID ID) {
+      return FM[ID].MutID.partiallyMatches(M);
+    });
+
+    return I != end() ? &FM[*I] : nullptr;
   }
 };
 
-
-
 /// A Lockset maps each SExpr (defined above) to information about how it has
 /// been locked.
 typedef llvm::ImmutableMap<SExpr, LockData> Lockset;
@@ -984,7 +962,7 @@
 
     // Create reference to previous definition
     VarDefinition(const NamedDecl *D, unsigned R, Context C)
-      : Dec(D), Exp(0), Ref(R), Ctx(C)
+      : Dec(D), Exp(nullptr), Ref(R), Ctx(C)
     { }
   };
 
@@ -997,14 +975,14 @@
 public:
   LocalVariableMap() {
     // index 0 is a placeholder for undefined variables (aka phi-nodes).
-    VarDefinitions.push_back(VarDefinition(0, 0u, getEmptyContext()));
+    VarDefinitions.push_back(VarDefinition(nullptr, 0u, getEmptyContext()));
   }
 
   /// Look up a definition, within the given context.
   const VarDefinition* lookup(const NamedDecl *D, Context Ctx) {
     const unsigned *i = Ctx.lookup(D);
     if (!i)
-      return 0;
+      return nullptr;
     assert(*i < VarDefinitions.size());
     return &VarDefinitions[*i];
   }
@@ -1015,7 +993,7 @@
   const Expr* lookupExpr(const NamedDecl *D, Context &Ctx) {
     const unsigned *P = Ctx.lookup(D);
     if (!P)
-      return 0;
+      return nullptr;
 
     unsigned i = *P;
     while (i > 0) {
@@ -1025,7 +1003,7 @@
       }
       i = VarDefinitions[i].Ref;
     }
-    return 0;
+    return nullptr;
   }
 
   Context getEmptyContext() { return ContextFactory.getEmptyMap(); }
@@ -1085,8 +1063,8 @@
   }
 
   /// Builds the variable map.
-  void traverseCFG(CFG *CFGraph, PostOrderCFGView *SortedGraph,
-                     std::vector<CFGBlockInfo> &BlockInfo);
+  void traverseCFG(CFG *CFGraph, const PostOrderCFGView *SortedGraph,
+                   std::vector<CFGBlockInfo> &BlockInfo);
 
 protected:
   // Get the current context index
@@ -1099,7 +1077,7 @@
 
   // Adds a new definition to the given context, and returns a new context.
   // This method should be called when declaring a new variable.
-  Context addDefinition(const NamedDecl *D, Expr *Exp, Context Ctx) {
+  Context addDefinition(const NamedDecl *D, const Expr *Exp, Context Ctx) {
     assert(!Ctx.contains(D));
     unsigned newID = VarDefinitions.size();
     Context NewCtx = ContextFactory.add(Ctx, D, newID);
@@ -1180,9 +1158,9 @@
 void VarMapBuilder::VisitDeclStmt(DeclStmt *S) {
   bool modifiedCtx = false;
   DeclGroupRef DGrp = S->getDeclGroup();
-  for (DeclGroupRef::iterator I = DGrp.begin(), E = DGrp.end(); I != E; ++I) {
-    if (VarDecl *VD = dyn_cast_or_null<VarDecl>(*I)) {
-      Expr *E = VD->getInit();
+  for (const auto *D : DGrp) {
+    if (const auto *VD = dyn_cast_or_null<VarDecl>(D)) {
+      const Expr *E = VD->getInit();
 
       // Add local variables with trivial type to the variable map
       QualType T = VD->getType();
@@ -1224,13 +1202,12 @@
 LocalVariableMap::Context
 LocalVariableMap::intersectContexts(Context C1, Context C2) {
   Context Result = C1;
-  for (Context::iterator I = C1.begin(), E = C1.end(); I != E; ++I) {
-    const NamedDecl *Dec = I.getKey();
-    unsigned i1 = I.getData();
+  for (const auto &P : C1) {
+    const NamedDecl *Dec = P.first;
     const unsigned *i2 = C2.lookup(Dec);
     if (!i2)             // variable doesn't exist on second path
       Result = removeDefinition(Dec, Result);
-    else if (*i2 != i1)  // variable exists, but has different definition
+    else if (*i2 != P.second)  // variable exists, but has different definition
       Result = clearDefinition(Dec, Result);
   }
   return Result;
@@ -1241,11 +1218,8 @@
 // (We use this for a naive implementation of SSA on loop back-edges.)
 LocalVariableMap::Context LocalVariableMap::createReferenceContext(Context C) {
   Context Result = getEmptyContext();
-  for (Context::iterator I = C.begin(), E = C.end(); I != E; ++I) {
-    const NamedDecl *Dec = I.getKey();
-    unsigned i = I.getData();
-    Result = addReference(Dec, i, Result);
-  }
+  for (const auto &P : C)
+    Result = addReference(P.first, P.second, Result);
   return Result;
 }
 
@@ -1253,13 +1227,12 @@
 // altering the VarDefinitions.  C1 must be the result of an earlier call to
 // createReferenceContext.
 void LocalVariableMap::intersectBackEdge(Context C1, Context C2) {
-  for (Context::iterator I = C1.begin(), E = C1.end(); I != E; ++I) {
-    const NamedDecl *Dec = I.getKey();
-    unsigned i1 = I.getData();
+  for (const auto &P : C1) {
+    unsigned i1 = P.second;
     VarDefinition *VDef = &VarDefinitions[i1];
     assert(VDef->isReference());
 
-    const unsigned *i2 = C2.lookup(Dec);
+    const unsigned *i2 = C2.lookup(P.first);
     if (!i2 || (*i2 != i1))
       VDef->Ref = 0;    // Mark this variable as undefined
   }
@@ -1305,15 +1278,13 @@
 //   ...                 { y -> y1           | x3 = 2, x2 = 1, ... }
 //
 void LocalVariableMap::traverseCFG(CFG *CFGraph,
-                                   PostOrderCFGView *SortedGraph,
+                                   const PostOrderCFGView *SortedGraph,
                                    std::vector<CFGBlockInfo> &BlockInfo) {
   PostOrderCFGView::CFGBlockSet VisitedBlocks(CFGraph);
 
   CtxIndices.resize(CFGraph->getNumBlockIDs());
 
-  for (PostOrderCFGView::iterator I = SortedGraph->begin(),
-       E = SortedGraph->end(); I!= E; ++I) {
-    const CFGBlock *CurrBlock = *I;
+  for (const auto *CurrBlock : *SortedGraph) {
     int CurrBlockID = CurrBlock->getBlockID();
     CFGBlockInfo *CurrBlockInfo = &BlockInfo[CurrBlockID];
 
@@ -1325,7 +1296,7 @@
     for (CFGBlock::const_pred_iterator PI = CurrBlock->pred_begin(),
          PE  = CurrBlock->pred_end(); PI != PE; ++PI) {
       // if *PI -> CurrBlock is a back edge, so skip it
-      if (*PI == 0 || !VisitedBlocks.alreadySet(*PI)) {
+      if (*PI == nullptr || !VisitedBlocks.alreadySet(*PI)) {
         HasBackEdges = true;
         continue;
       }
@@ -1351,7 +1322,7 @@
         createReferenceContext(CurrBlockInfo->EntryContext);
 
     // Create a starting context index for the current block
-    saveContext(0, CurrBlockInfo->EntryContext);
+    saveContext(nullptr, CurrBlockInfo->EntryContext);
     CurrBlockInfo->EntryIndex = getContextIndex();
 
     // Visit all the statements in the basic block.
@@ -1374,7 +1345,7 @@
     for (CFGBlock::const_succ_iterator SI = CurrBlock->succ_begin(),
          SE  = CurrBlock->succ_end(); SI != SE; ++SI) {
       // if CurrBlock -> *SI is *not* a back edge
-      if (*SI == 0 || !VisitedBlocks.alreadySet(*SI))
+      if (*SI == nullptr || !VisitedBlocks.alreadySet(*SI))
         continue;
 
       CFGBlock *FirstLoopBlock = *SI;
@@ -1386,17 +1357,15 @@
 
   // Put an extra entry at the end of the indexed context array
   unsigned exitID = CFGraph->getExit().getBlockID();
-  saveContext(0, BlockInfo[exitID].ExitContext);
+  saveContext(nullptr, BlockInfo[exitID].ExitContext);
 }
 
 /// Find the appropriate source locations to use when producing diagnostics for
 /// each block in the CFG.
 static void findBlockLocations(CFG *CFGraph,
-                               PostOrderCFGView *SortedGraph,
+                               const PostOrderCFGView *SortedGraph,
                                std::vector<CFGBlockInfo> &BlockInfo) {
-  for (PostOrderCFGView::iterator I = SortedGraph->begin(),
-       E = SortedGraph->end(); I!= E; ++I) {
-    const CFGBlock *CurrBlock = *I;
+  for (const auto *CurrBlock : *SortedGraph) {
     CFGBlockInfo *CurrBlockInfo = &BlockInfo[CurrBlock->getBlockID()];
 
     // Find the source location of the last statement in the block, if the
@@ -1447,13 +1416,14 @@
 public:
   ThreadSafetyAnalyzer(ThreadSafetyHandler &H) : Handler(H) {}
 
-  void addLock(FactSet &FSet, const SExpr &Mutex, const LockData &LDat);
-  void removeLock(FactSet &FSet, const SExpr &Mutex,
-                  SourceLocation UnlockLoc, bool FullyRemove=false);
+  void addLock(FactSet &FSet, const SExpr &Mutex, const LockData &LDat,
+               StringRef DiagKind);
+  void removeLock(FactSet &FSet, const SExpr &Mutex, SourceLocation UnlockLoc,
+                  bool FullyRemove, LockKind Kind, StringRef DiagKind);
 
   template <typename AttrType>
   void getMutexIDs(MutexIDList &Mtxs, AttrType *Attr, Expr *Exp,
-                   const NamedDecl *D, VarDecl *SelfDecl=0);
+                   const NamedDecl *D, VarDecl *SelfDecl = nullptr);
 
   template <class AttrType>
   void getMutexIDs(MutexIDList &Mtxs, AttrType *Attr, Expr *Exp,
@@ -1482,12 +1452,89 @@
   void runAnalysis(AnalysisDeclContext &AC);
 };
 
+/// \brief Gets the value decl pointer from DeclRefExprs or MemberExprs.
+static const ValueDecl *getValueDecl(const Expr *Exp) {
+  if (const auto *CE = dyn_cast<ImplicitCastExpr>(Exp))
+    return getValueDecl(CE->getSubExpr());
+
+  if (const auto *DR = dyn_cast<DeclRefExpr>(Exp))
+    return DR->getDecl();
+
+  if (const auto *ME = dyn_cast<MemberExpr>(Exp))
+    return ME->getMemberDecl();
+
+  return nullptr;
+}
+
+template <typename Ty>
+class has_arg_iterator_range {
+  typedef char yes[1];
+  typedef char no[2];
+
+  template <typename Inner>
+  static yes& test(Inner *I, decltype(I->args()) * = nullptr);
+
+  template <typename>
+  static no& test(...);
+
+public:
+  static const bool value = sizeof(test<Ty>(nullptr)) == sizeof(yes);
+};
+
+static StringRef ClassifyDiagnostic(const CapabilityAttr *A) {
+  return A->getName();
+}
+
+static StringRef ClassifyDiagnostic(QualType VDT) {
+  // We need to look at the declaration of the type of the value to determine
+  // which it is. The type should either be a record or a typedef, or a pointer
+  // or reference thereof.
+  if (const auto *RT = VDT->getAs<RecordType>()) {
+    if (const auto *RD = RT->getDecl())
+      if (const auto *CA = RD->getAttr<CapabilityAttr>())
+        return ClassifyDiagnostic(CA);
+  } else if (const auto *TT = VDT->getAs<TypedefType>()) {
+    if (const auto *TD = TT->getDecl())
+      if (const auto *CA = TD->getAttr<CapabilityAttr>())
+        return ClassifyDiagnostic(CA);
+  } else if (VDT->isPointerType() || VDT->isReferenceType())
+    return ClassifyDiagnostic(VDT->getPointeeType());
+
+  return "mutex";
+}
+
+static StringRef ClassifyDiagnostic(const ValueDecl *VD) {
+  assert(VD && "No ValueDecl passed");
+
+  // The ValueDecl is the declaration of a mutex or role (hopefully).
+  return ClassifyDiagnostic(VD->getType());
+}
+
+template <typename AttrTy>
+static typename std::enable_if<!has_arg_iterator_range<AttrTy>::value,
+                               StringRef>::type
+ClassifyDiagnostic(const AttrTy *A) {
+  if (const ValueDecl *VD = getValueDecl(A->getArg()))
+    return ClassifyDiagnostic(VD);
+  return "mutex";
+}
+
+template <typename AttrTy>
+static typename std::enable_if<has_arg_iterator_range<AttrTy>::value,
+                               StringRef>::type
+ClassifyDiagnostic(const AttrTy *A) {
+  for (const auto *Arg : A->args()) {
+    if (const ValueDecl *VD = getValueDecl(Arg))
+      return ClassifyDiagnostic(VD);
+  }
+  return "mutex";
+}
 
 /// \brief Add a new lock to the lockset, warning if the lock is already there.
 /// \param Mutex -- the Mutex expression for the lock
 /// \param LDat  -- the LockData for the lock
 void ThreadSafetyAnalyzer::addLock(FactSet &FSet, const SExpr &Mutex,
-                                   const LockData &LDat) {
+                                   const LockData &LDat, StringRef DiagKind) {
   // FIXME: deal with acquired before/after annotations.
   // FIXME: Don't always warn when we have support for reentrant locks.
   if (Mutex.shouldIgnore())
@@ -1495,7 +1542,7 @@
 
   if (FSet.findLock(FactMan, Mutex)) {
     if (!LDat.Asserted)
-      Handler.handleDoubleLock(Mutex.toString(), LDat.AcquireLoc);
+      Handler.handleDoubleLock(DiagKind, Mutex.toString(), LDat.AcquireLoc);
   } else {
     FSet.addLock(FactMan, Mutex, LDat);
   }
@@ -1505,16 +1552,24 @@
 /// \brief Remove a lock from the lockset, warning if the lock is not there.
 /// \param Mutex The lock expression corresponding to the lock to be removed
 /// \param UnlockLoc The source location of the unlock (only used in error msg)
-void ThreadSafetyAnalyzer::removeLock(FactSet &FSet,
-                                      const SExpr &Mutex,
+void ThreadSafetyAnalyzer::removeLock(FactSet &FSet, const SExpr &Mutex,
                                       SourceLocation UnlockLoc,
-                                      bool FullyRemove) {
+                                      bool FullyRemove, LockKind ReceivedKind,
+                                      StringRef DiagKind) {
   if (Mutex.shouldIgnore())
     return;
 
   const LockData *LDat = FSet.findLock(FactMan, Mutex);
   if (!LDat) {
-    Handler.handleUnmatchedUnlock(Mutex.toString(), UnlockLoc);
+    Handler.handleUnmatchedUnlock(DiagKind, Mutex.toString(), UnlockLoc);
+    return;
+  }
+
+  // Generic lock removal doesn't care about lock kind mismatches, but
+  // otherwise diagnose when the lock kinds are mismatched.
+  if (ReceivedKind != LK_Generic && LDat->LKind != ReceivedKind) {
+    Handler.handleIncorrectUnlockKind(DiagKind, Mutex.toString(), LDat->LKind,
+                                      ReceivedKind, UnlockLoc);
     return;
   }
 
@@ -1529,8 +1584,8 @@
       // We're releasing the underlying mutex, but not destroying the
       // managing object.  Warn on dual release.
       if (!FSet.findLock(FactMan, LDat->UnderlyingMutex)) {
-        Handler.handleUnmatchedUnlock(LDat->UnderlyingMutex.toString(),
-                                      UnlockLoc);
+        Handler.handleUnmatchedUnlock(
+            DiagKind, LDat->UnderlyingMutex.toString(), UnlockLoc);
       }
       FSet.removeLock(FactMan, LDat->UnderlyingMutex);
       return;
@@ -1546,22 +1601,21 @@
 void ThreadSafetyAnalyzer::getMutexIDs(MutexIDList &Mtxs, AttrType *Attr,
                                        Expr *Exp, const NamedDecl *D,
                                        VarDecl *SelfDecl) {
-  typedef typename AttrType::args_iterator iterator_type;
-
   if (Attr->args_size() == 0) {
     // The mutex held is the "this" object.
-    SExpr Mu(0, Exp, D, SelfDecl);
+    SExpr Mu(nullptr, Exp, D, SelfDecl);
     if (!Mu.isValid())
-      SExpr::warnInvalidLock(Handler, 0, Exp, D);
+      SExpr::warnInvalidLock(Handler, nullptr, Exp, D,
+                             ClassifyDiagnostic(Attr));
     else
       Mtxs.push_back_nodup(Mu);
     return;
   }
 
-  for (iterator_type I=Attr->args_begin(), E=Attr->args_end(); I != E; ++I) {
-    SExpr Mu(*I, Exp, D, SelfDecl);
+  for (const auto *Arg : Attr->args()) {
+    SExpr Mu(Arg, Exp, D, SelfDecl);
     if (!Mu.isValid())
-      SExpr::warnInvalidLock(Handler, *I, Exp, D);
+      SExpr::warnInvalidLock(Handler, Arg, Exp, D, ClassifyDiagnostic(Attr));
     else
       Mtxs.push_back_nodup(Mu);
   }
@@ -1578,23 +1632,22 @@
                                        const CFGBlock *CurrBlock,
                                        Expr *BrE, bool Neg) {
   // Find out which branch has the lock
-  bool branch = 0;
-  if (CXXBoolLiteralExpr *BLE = dyn_cast_or_null<CXXBoolLiteralExpr>(BrE)) {
+  bool branch = false;
+  if (CXXBoolLiteralExpr *BLE = dyn_cast_or_null<CXXBoolLiteralExpr>(BrE))
     branch = BLE->getValue();
-  }
-  else if (IntegerLiteral *ILE = dyn_cast_or_null<IntegerLiteral>(BrE)) {
+  else if (IntegerLiteral *ILE = dyn_cast_or_null<IntegerLiteral>(BrE))
     branch = ILE->getValue().getBoolValue();
-  }
+
   int branchnum = branch ? 0 : 1;
-  if (Neg) branchnum = !branchnum;
+  if (Neg)
+    branchnum = !branchnum;
 
   // If we've taken the trylock branch, then add the lock
   int i = 0;
   for (CFGBlock::const_succ_iterator SI = PredBlock->succ_begin(),
        SE = PredBlock->succ_end(); SI != SE && i < 2; ++SI, ++i) {
-    if (*SI == CurrBlock && i == branchnum) {
+    if (*SI == CurrBlock && i == branchnum)
       getMutexIDs(Mtxs, Attr, Exp, D);
-    }
   }
 }
 
@@ -1623,7 +1676,7 @@
                                                          LocalVarContext C,
                                                          bool &Negate) {
   if (!Cond)
-    return 0;
+    return nullptr;
 
   if (const CallExpr *CallExp = dyn_cast<CallExpr>(Cond)) {
     return CallExp;
@@ -1646,7 +1699,7 @@
       Negate = !Negate;
       return getTrylockCallExpr(UOP->getSubExpr(), C, Negate);
     }
-    return 0;
+    return nullptr;
   }
   else if (const BinaryOperator *BOP = dyn_cast<BinaryOperator>(Cond)) {
     if (BOP->getOpcode() == BO_EQ || BOP->getOpcode() == BO_NE) {
@@ -1663,7 +1716,7 @@
         if (!TCond) Negate = !Negate;
         return getTrylockCallExpr(BOP->getRHS(), C, Negate);
       }
-      return 0;
+      return nullptr;
     }
     if (BOP->getOpcode() == BO_LAnd) {
       // LHS must have been evaluated in a different block.
@@ -1672,9 +1725,9 @@
     if (BOP->getOpcode() == BO_LOr) {
       return getTrylockCallExpr(BOP->getRHS(), C, Negate);
     }
-    return 0;
+    return nullptr;
   }
-  return 0;
+  return nullptr;
 }
 
 
@@ -1694,6 +1747,7 @@
   bool Negate = false;
   const CFGBlockInfo *PredBlockInfo = &BlockInfo[PredBlock->getBlockID()];
   const LocalVarContext &LVarCtx = PredBlockInfo->ExitContext;
+  StringRef CapDiagKind = "mutex";
 
   CallExpr *Exp =
     const_cast<CallExpr*>(getTrylockCallExpr(Cond, LVarCtx, Negate));
@@ -1708,15 +1762,14 @@
   MutexIDList SharedLocksToAdd;
 
   // If the condition is a call to a Trylock function, then grab the attributes
-  AttrVec &ArgAttrs = FunDecl->getAttrs();
-  for (unsigned i = 0; i < ArgAttrs.size(); ++i) {
-    Attr *Attr = ArgAttrs[i];
+  for (auto *Attr : FunDecl->getAttrs()) {
     switch (Attr->getKind()) {
       case attr::ExclusiveTrylockFunction: {
         ExclusiveTrylockFunctionAttr *A =
           cast<ExclusiveTrylockFunctionAttr>(Attr);
         getMutexIDs(ExclusiveLocksToAdd, A, Exp, FunDecl,
                     PredBlock, CurrBlock, A->getSuccessValue(), Negate);
+        CapDiagKind = ClassifyDiagnostic(A);
         break;
       }
       case attr::SharedTrylockFunction: {
@@ -1724,6 +1777,7 @@
           cast<SharedTrylockFunctionAttr>(Attr);
         getMutexIDs(SharedLocksToAdd, A, Exp, FunDecl,
                     PredBlock, CurrBlock, A->getSuccessValue(), Negate);
+        CapDiagKind = ClassifyDiagnostic(A);
         break;
       }
       default:
@@ -1733,17 +1787,13 @@
 
   // Add and remove locks.
   SourceLocation Loc = Exp->getExprLoc();
-  for (unsigned i=0,n=ExclusiveLocksToAdd.size(); i<n; ++i) {
-    addLock(Result, ExclusiveLocksToAdd[i],
-            LockData(Loc, LK_Exclusive));
-  }
-  for (unsigned i=0,n=SharedLocksToAdd.size(); i<n; ++i) {
-    addLock(Result, SharedLocksToAdd[i],
-            LockData(Loc, LK_Shared));
-  }
+  for (const auto &ExclusiveLockToAdd : ExclusiveLocksToAdd)
+    addLock(Result, ExclusiveLockToAdd, LockData(Loc, LK_Exclusive),
+            CapDiagKind);
+  for (const auto &SharedLockToAdd : SharedLocksToAdd)
+    addLock(Result, SharedLockToAdd, LockData(Loc, LK_Shared), CapDiagKind);
 }
 
-
 /// \brief We use this class to visit different types of expressions in
 /// CFGBlocks, and build up the lockset.
 /// An expression may cause us to add or remove locks from the lockset, or else
@@ -1758,16 +1808,17 @@
   unsigned CtxIndex;
 
   // Helper functions
-  const ValueDecl *getValueDecl(const Expr *Exp);
 
   void warnIfMutexNotHeld(const NamedDecl *D, const Expr *Exp, AccessKind AK,
-                          Expr *MutexExp, ProtectedOperationKind POK);
-  void warnIfMutexHeld(const NamedDecl *D, const Expr *Exp, Expr *MutexExp);
+                          Expr *MutexExp, ProtectedOperationKind POK,
+                          StringRef DiagKind);
+  void warnIfMutexHeld(const NamedDecl *D, const Expr *Exp, Expr *MutexExp,
+                       StringRef DiagKind);
 
   void checkAccess(const Expr *Exp, AccessKind AK);
   void checkPtAccess(const Expr *Exp, AccessKind AK);
 
-  void handleCall(Expr *Exp, const NamedDecl *D, VarDecl *VD = 0);
+  void handleCall(Expr *Exp, const NamedDecl *D, VarDecl *VD = nullptr);
 
 public:
   BuildLockset(ThreadSafetyAnalyzer *Anlzr, CFGBlockInfo &Info)
@@ -1786,31 +1837,17 @@
   void VisitDeclStmt(DeclStmt *S);
 };
 
-
-/// \brief Gets the value decl pointer from DeclRefExprs or MemberExprs
-const ValueDecl *BuildLockset::getValueDecl(const Expr *Exp) {
-  if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(Exp))
-    return getValueDecl(CE->getSubExpr());
-
-  if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Exp))
-    return DR->getDecl();
-
-  if (const MemberExpr *ME = dyn_cast<MemberExpr>(Exp))
-    return ME->getMemberDecl();
-
-  return 0;
-}
-
 /// \brief Warn if the LSet does not contain a lock sufficient to protect access
 /// of at least the passed in AccessKind.
 void BuildLockset::warnIfMutexNotHeld(const NamedDecl *D, const Expr *Exp,
                                       AccessKind AK, Expr *MutexExp,
-                                      ProtectedOperationKind POK) {
+                                      ProtectedOperationKind POK,
+                                      StringRef DiagKind) {
   LockKind LK = getLockKindFromAccessKind(AK);
 
   SExpr Mutex(MutexExp, Exp, D);
   if (!Mutex.isValid()) {
-    SExpr::warnInvalidLock(Analyzer->Handler, MutexExp, Exp, D);
+    SExpr::warnInvalidLock(Analyzer->Handler, MutexExp, Exp, D, DiagKind);
     return;
   } else if (Mutex.shouldIgnore()) {
     return;
@@ -1826,40 +1863,38 @@
       LDat = &FEntry->LDat;
       std::string PartMatchStr = FEntry->MutID.toString();
       StringRef   PartMatchName(PartMatchStr);
-      Analyzer->Handler.handleMutexNotHeld(D, POK, Mutex.toString(), LK,
-                                           Exp->getExprLoc(), &PartMatchName);
+      Analyzer->Handler.handleMutexNotHeld(DiagKind, D, POK, Mutex.toString(),
+                                           LK, Exp->getExprLoc(),
+                                           &PartMatchName);
     } else {
       // Warn that there's no match at all.
-      Analyzer->Handler.handleMutexNotHeld(D, POK, Mutex.toString(), LK,
-                                           Exp->getExprLoc());
+      Analyzer->Handler.handleMutexNotHeld(DiagKind, D, POK, Mutex.toString(),
+                                           LK, Exp->getExprLoc());
     }
     NoError = false;
   }
   // Make sure the mutex we found is the right kind.
   if (NoError && LDat && !LDat->isAtLeast(LK))
-    Analyzer->Handler.handleMutexNotHeld(D, POK, Mutex.toString(), LK,
+    Analyzer->Handler.handleMutexNotHeld(DiagKind, D, POK, Mutex.toString(), LK,
                                          Exp->getExprLoc());
 }
 
 /// \brief Warn if the LSet contains the given lock.
-void BuildLockset::warnIfMutexHeld(const NamedDecl *D, const Expr* Exp,
-                                   Expr *MutexExp) {
+void BuildLockset::warnIfMutexHeld(const NamedDecl *D, const Expr *Exp,
+                                   Expr *MutexExp,
+                                   StringRef DiagKind) {
   SExpr Mutex(MutexExp, Exp, D);
   if (!Mutex.isValid()) {
-    SExpr::warnInvalidLock(Analyzer->Handler, MutexExp, Exp, D);
+    SExpr::warnInvalidLock(Analyzer->Handler, MutexExp, Exp, D, DiagKind);
     return;
   }
 
   LockData* LDat = FSet.findLock(Analyzer->FactMan, Mutex);
-  if (LDat) {
-    std::string DeclName = D->getNameAsString();
-    StringRef   DeclNameSR (DeclName);
-    Analyzer->Handler.handleFunExcludesLock(DeclNameSR, Mutex.toString(),
-                                            Exp->getExprLoc());
-  }
+  if (LDat)
+    Analyzer->Handler.handleFunExcludesLock(
+        DiagKind, D->getNameAsString(), Mutex.toString(), Exp->getExprLoc());
 }
 
-
 /// \brief Checks guarded_by and pt_guarded_by attributes.
 /// Whenever we identify an access (read or write) to a DeclRefExpr that is
 /// marked with guarded_by, we must ensure the appropriate mutexes are held.
@@ -1876,10 +1911,8 @@
   }
 
   if (const ArraySubscriptExpr *AE = dyn_cast<ArraySubscriptExpr>(Exp)) {
-    if (Analyzer->Handler.issueBetaWarnings()) {
-      checkPtAccess(AE->getLHS(), AK);
-      return;
-    }
+    checkPtAccess(AE->getLHS(), AK);
+    return;
   }
 
   if (const MemberExpr *ME = dyn_cast<MemberExpr>(Exp)) {
@@ -1893,55 +1926,48 @@
   if (!D || !D->hasAttrs())
     return;
 
-  if (D->getAttr<GuardedVarAttr>() && FSet.isEmpty())
-    Analyzer->Handler.handleNoMutexHeld(D, POK_VarAccess, AK,
+  if (D->hasAttr<GuardedVarAttr>() && FSet.isEmpty())
+    Analyzer->Handler.handleNoMutexHeld("mutex", D, POK_VarAccess, AK,
                                         Exp->getExprLoc());
 
-  const AttrVec &ArgAttrs = D->getAttrs();
-  for (unsigned i = 0, Size = ArgAttrs.size(); i < Size; ++i)
-    if (GuardedByAttr *GBAttr = dyn_cast<GuardedByAttr>(ArgAttrs[i]))
-      warnIfMutexNotHeld(D, Exp, AK, GBAttr->getArg(), POK_VarAccess);
+  for (const auto *I : D->specific_attrs<GuardedByAttr>())
+    warnIfMutexNotHeld(D, Exp, AK, I->getArg(), POK_VarAccess,
+                       ClassifyDiagnostic(I));
 }
 
 /// \brief Checks pt_guarded_by and pt_guarded_var attributes.
 void BuildLockset::checkPtAccess(const Expr *Exp, AccessKind AK) {
-  if (Analyzer->Handler.issueBetaWarnings()) {
-    while (true) {
-      if (const ParenExpr *PE = dyn_cast<ParenExpr>(Exp)) {
-        Exp = PE->getSubExpr();
-        continue;
-      }
-      if (const CastExpr *CE = dyn_cast<CastExpr>(Exp)) {
-        if (CE->getCastKind() == CK_ArrayToPointerDecay) {
-          // If it's an actual array, and not a pointer, then it's elements
-          // are protected by GUARDED_BY, not PT_GUARDED_BY;
-          checkAccess(CE->getSubExpr(), AK);
-          return;
-        }
-        Exp = CE->getSubExpr();
-        continue;
-      }
-      break;
+  while (true) {
+    if (const ParenExpr *PE = dyn_cast<ParenExpr>(Exp)) {
+      Exp = PE->getSubExpr();
+      continue;
     }
+    if (const CastExpr *CE = dyn_cast<CastExpr>(Exp)) {
+      if (CE->getCastKind() == CK_ArrayToPointerDecay) {
+        // If it's an actual array, and not a pointer, then it's elements
+        // are protected by GUARDED_BY, not PT_GUARDED_BY;
+        checkAccess(CE->getSubExpr(), AK);
+        return;
+      }
+      Exp = CE->getSubExpr();
+      continue;
+    }
+    break;
   }
-  else
-    Exp = Exp->IgnoreParenCasts();
 
   const ValueDecl *D = getValueDecl(Exp);
   if (!D || !D->hasAttrs())
     return;
 
-  if (D->getAttr<PtGuardedVarAttr>() && FSet.isEmpty())
-    Analyzer->Handler.handleNoMutexHeld(D, POK_VarDereference, AK,
+  if (D->hasAttr<PtGuardedVarAttr>() && FSet.isEmpty())
+    Analyzer->Handler.handleNoMutexHeld("mutex", D, POK_VarDereference, AK,
                                         Exp->getExprLoc());
 
-  const AttrVec &ArgAttrs = D->getAttrs();
-  for (unsigned i = 0, Size = ArgAttrs.size(); i < Size; ++i)
-    if (PtGuardedByAttr *GBAttr = dyn_cast<PtGuardedByAttr>(ArgAttrs[i]))
-      warnIfMutexNotHeld(D, Exp, AK, GBAttr->getArg(), POK_VarDereference);
+  for (auto const *I : D->specific_attrs<PtGuardedByAttr>())
+    warnIfMutexNotHeld(D, Exp, AK, I->getArg(), POK_VarDereference,
+                       ClassifyDiagnostic(I));
 }
 
-
 /// \brief Process a function call, method call, constructor call,
 /// or destructor call.  This involves looking at the attributes on the
 /// corresponding function/method/constructor/destructor, issuing warnings,
@@ -1955,26 +1981,22 @@
 void BuildLockset::handleCall(Expr *Exp, const NamedDecl *D, VarDecl *VD) {
   SourceLocation Loc = Exp->getExprLoc();
   const AttrVec &ArgAttrs = D->getAttrs();
-  MutexIDList ExclusiveLocksToAdd;
-  MutexIDList SharedLocksToAdd;
-  MutexIDList LocksToRemove;
+  MutexIDList ExclusiveLocksToAdd, SharedLocksToAdd;
+  MutexIDList ExclusiveLocksToRemove, SharedLocksToRemove, GenericLocksToRemove;
+  StringRef CapDiagKind = "mutex";
 
   for(unsigned i = 0; i < ArgAttrs.size(); ++i) {
     Attr *At = const_cast<Attr*>(ArgAttrs[i]);
     switch (At->getKind()) {
-      // When we encounter an exclusive lock function, we need to add the lock
-      // to our lockset with kind exclusive.
-      case attr::ExclusiveLockFunction: {
-        ExclusiveLockFunctionAttr *A = cast<ExclusiveLockFunctionAttr>(At);
-        Analyzer->getMutexIDs(ExclusiveLocksToAdd, A, Exp, D, VD);
-        break;
-      }
+      // When we encounter a lock function, we need to add the lock to our
+      // lockset.
+      case attr::AcquireCapability: {
+        auto *A = cast<AcquireCapabilityAttr>(At);
+        Analyzer->getMutexIDs(A->isShared() ? SharedLocksToAdd
+                                            : ExclusiveLocksToAdd,
+                              A, Exp, D, VD);
 
-      // When we encounter a shared lock function, we need to add the lock
-      // to our lockset with kind shared.
-      case attr::SharedLockFunction: {
-        SharedLockFunctionAttr *A = cast<SharedLockFunctionAttr>(At);
-        Analyzer->getMutexIDs(SharedLocksToAdd, A, Exp, D, VD);
+        CapDiagKind = ClassifyDiagnostic(A);
         break;
       }
 
@@ -1986,10 +2008,10 @@
 
         MutexIDList AssertLocks;
         Analyzer->getMutexIDs(AssertLocks, A, Exp, D, VD);
-        for (unsigned i=0,n=AssertLocks.size(); i<n; ++i) {
-          Analyzer->addLock(FSet, AssertLocks[i],
-                            LockData(Loc, LK_Exclusive, false, true));
-        }
+        for (const auto &AssertLock : AssertLocks)
+          Analyzer->addLock(FSet, AssertLock,
+                            LockData(Loc, LK_Exclusive, false, true),
+                            ClassifyDiagnostic(A));
         break;
       }
       case attr::AssertSharedLock: {
@@ -1997,50 +2019,44 @@
 
         MutexIDList AssertLocks;
         Analyzer->getMutexIDs(AssertLocks, A, Exp, D, VD);
-        for (unsigned i=0,n=AssertLocks.size(); i<n; ++i) {
-          Analyzer->addLock(FSet, AssertLocks[i],
-                            LockData(Loc, LK_Shared, false, true));
-        }
+        for (const auto &AssertLock : AssertLocks)
+          Analyzer->addLock(FSet, AssertLock,
+                            LockData(Loc, LK_Shared, false, true),
+                            ClassifyDiagnostic(A));
         break;
       }
 
       // When we encounter an unlock function, we need to remove unlocked
       // mutexes from the lockset, and flag a warning if they are not there.
-      case attr::UnlockFunction: {
-        UnlockFunctionAttr *A = cast<UnlockFunctionAttr>(At);
-        Analyzer->getMutexIDs(LocksToRemove, A, Exp, D, VD);
+      case attr::ReleaseCapability: {
+        auto *A = cast<ReleaseCapabilityAttr>(At);
+        if (A->isGeneric())
+          Analyzer->getMutexIDs(GenericLocksToRemove, A, Exp, D, VD);
+        else if (A->isShared())
+          Analyzer->getMutexIDs(SharedLocksToRemove, A, Exp, D, VD);
+        else
+          Analyzer->getMutexIDs(ExclusiveLocksToRemove, A, Exp, D, VD);
+
+        CapDiagKind = ClassifyDiagnostic(A);
         break;
       }
 
-      case attr::ExclusiveLocksRequired: {
-        ExclusiveLocksRequiredAttr *A = cast<ExclusiveLocksRequiredAttr>(At);
-
-        for (ExclusiveLocksRequiredAttr::args_iterator
-             I = A->args_begin(), E = A->args_end(); I != E; ++I)
-          warnIfMutexNotHeld(D, Exp, AK_Written, *I, POK_FunctionCall);
-        break;
-      }
-
-      case attr::SharedLocksRequired: {
-        SharedLocksRequiredAttr *A = cast<SharedLocksRequiredAttr>(At);
-
-        for (SharedLocksRequiredAttr::args_iterator I = A->args_begin(),
-             E = A->args_end(); I != E; ++I)
-          warnIfMutexNotHeld(D, Exp, AK_Read, *I, POK_FunctionCall);
+      case attr::RequiresCapability: {
+        RequiresCapabilityAttr *A = cast<RequiresCapabilityAttr>(At);
+        for (auto *Arg : A->args())
+          warnIfMutexNotHeld(D, Exp, A->isShared() ? AK_Read : AK_Written, Arg,
+                             POK_FunctionCall, ClassifyDiagnostic(A));
         break;
       }
 
       case attr::LocksExcluded: {
         LocksExcludedAttr *A = cast<LocksExcludedAttr>(At);
-
-        for (LocksExcludedAttr::args_iterator I = A->args_begin(),
-            E = A->args_end(); I != E; ++I) {
-          warnIfMutexHeld(D, Exp, *I);
-        }
+        for (auto *Arg : A->args())
+          warnIfMutexHeld(D, Exp, Arg, ClassifyDiagnostic(A));
         break;
       }
 
-      // Ignore other (non thread-safety) attributes
+      // Ignore attributes unrelated to thread-safety
       default:
         break;
     }
@@ -2051,44 +2067,43 @@
   if (VD) {
     if (const CXXConstructorDecl *CD = dyn_cast<const CXXConstructorDecl>(D)) {
       const CXXRecordDecl* PD = CD->getParent();
-      if (PD && PD->getAttr<ScopedLockableAttr>())
+      if (PD && PD->hasAttr<ScopedLockableAttr>())
         isScopedVar = true;
     }
   }
 
   // Add locks.
-  for (unsigned i=0,n=ExclusiveLocksToAdd.size(); i<n; ++i) {
-    Analyzer->addLock(FSet, ExclusiveLocksToAdd[i],
-                            LockData(Loc, LK_Exclusive, isScopedVar));
-  }
-  for (unsigned i=0,n=SharedLocksToAdd.size(); i<n; ++i) {
-    Analyzer->addLock(FSet, SharedLocksToAdd[i],
-                            LockData(Loc, LK_Shared, isScopedVar));
-  }
+  for (const auto &M : ExclusiveLocksToAdd)
+    Analyzer->addLock(FSet, M, LockData(Loc, LK_Exclusive, isScopedVar),
+                      CapDiagKind);
+  for (const auto &M : SharedLocksToAdd)
+    Analyzer->addLock(FSet, M, LockData(Loc, LK_Shared, isScopedVar),
+                      CapDiagKind);
 
   // Add the managing object as a dummy mutex, mapped to the underlying mutex.
   // FIXME -- this doesn't work if we acquire multiple locks.
   if (isScopedVar) {
     SourceLocation MLoc = VD->getLocation();
     DeclRefExpr DRE(VD, false, VD->getType(), VK_LValue, VD->getLocation());
-    SExpr SMutex(&DRE, 0, 0);
+    SExpr SMutex(&DRE, nullptr, nullptr);
 
-    for (unsigned i=0,n=ExclusiveLocksToAdd.size(); i<n; ++i) {
-      Analyzer->addLock(FSet, SMutex, LockData(MLoc, LK_Exclusive,
-                                               ExclusiveLocksToAdd[i]));
-    }
-    for (unsigned i=0,n=SharedLocksToAdd.size(); i<n; ++i) {
-      Analyzer->addLock(FSet, SMutex, LockData(MLoc, LK_Shared,
-                                               SharedLocksToAdd[i]));
-    }
+    for (const auto &M : ExclusiveLocksToAdd)
+      Analyzer->addLock(FSet, SMutex, LockData(MLoc, LK_Exclusive, M),
+                        CapDiagKind);
+    for (const auto &M : SharedLocksToAdd)
+      Analyzer->addLock(FSet, SMutex, LockData(MLoc, LK_Shared, M),
+                        CapDiagKind);
   }
 
   // Remove locks.
   // FIXME -- should only fully remove if the attribute refers to 'this'.
   bool Dtor = isa<CXXDestructorDecl>(D);
-  for (unsigned i=0,n=LocksToRemove.size(); i<n; ++i) {
-    Analyzer->removeLock(FSet, LocksToRemove[i], Loc, Dtor);
-  }
+  for (const auto &M : ExclusiveLocksToRemove)
+    Analyzer->removeLock(FSet, M, Loc, Dtor, LK_Exclusive, CapDiagKind);
+  for (const auto &M : SharedLocksToRemove)
+    Analyzer->removeLock(FSet, M, Loc, Dtor, LK_Shared, CapDiagKind);
+  for (const auto &M : GenericLocksToRemove)
+    Analyzer->removeLock(FSet, M, Loc, Dtor, LK_Generic, CapDiagKind);
 }
 
 
@@ -2165,11 +2180,9 @@
       case OO_Star:
       case OO_Arrow:
       case OO_Subscript: {
-        if (Analyzer->Handler.issueBetaWarnings()) {
-          const Expr *Obj = OE->getArg(0);
-          checkAccess(Obj, AK_Read);
-          checkPtAccess(Obj, AK_Read);
-        }
+        const Expr *Obj = OE->getArg(0);
+        checkAccess(Obj, AK_Read);
+        checkPtAccess(Obj, AK_Read);
         break;
       }
       default: {
@@ -2198,9 +2211,7 @@
   // adjust the context
   LVarCtx = Analyzer->LocalVarMap.getNextContext(CtxIndex, S, LVarCtx);
 
-  DeclGroupRef DGrp = S->getDeclGroup();
-  for (DeclGroupRef::iterator I = DGrp.begin(), E = DGrp.end(); I != E; ++I) {
-    Decl *D = *I;
+  for (auto *D : S->getDeclGroup()) {
     if (VarDecl *VD = dyn_cast_or_null<VarDecl>(D)) {
       Expr *E = VD->getInit();
       // handle constructors that involve temporaries
@@ -2242,26 +2253,24 @@
   FactSet FSet1Orig = FSet1;
 
   // Find locks in FSet2 that conflict or are not in FSet1, and warn.
-  for (FactSet::const_iterator I = FSet2.begin(), E = FSet2.end();
-       I != E; ++I) {
-    const SExpr &FSet2Mutex = FactMan[*I].MutID;
-    const LockData &LDat2 = FactMan[*I].LDat;
+  for (const auto &Fact : FSet2) {
+    const SExpr &FSet2Mutex = FactMan[Fact].MutID;
+    const LockData &LDat2 = FactMan[Fact].LDat;
     FactSet::iterator I1 = FSet1.findLockIter(FactMan, FSet2Mutex);
 
     if (I1 != FSet1.end()) {
       const LockData* LDat1 = &FactMan[*I1].LDat;
       if (LDat1->LKind != LDat2.LKind) {
-        Handler.handleExclusiveAndShared(FSet2Mutex.toString(),
-                                         LDat2.AcquireLoc,
-                                         LDat1->AcquireLoc);
+        Handler.handleExclusiveAndShared("mutex", FSet2Mutex.toString(),
+                                         LDat2.AcquireLoc, LDat1->AcquireLoc);
         if (Modify && LDat1->LKind != LK_Exclusive) {
           // Take the exclusive lock, which is the one in FSet2.
-          *I1 = *I;
+          *I1 = Fact;
         }
       }
       else if (LDat1->Asserted && !LDat2.Asserted) {
         // The non-asserted lock in FSet2 is the one we want to track.
-        *I1 = *I;
+        *I1 = Fact;
       }
     } else {
       if (LDat2.UnderlyingMutex.isValid()) {
@@ -2269,23 +2278,21 @@
           // If this is a scoped lock that manages another mutex, and if the
           // underlying mutex is still held, then warn about the underlying
           // mutex.
-          Handler.handleMutexHeldEndOfScope(LDat2.UnderlyingMutex.toString(),
-                                            LDat2.AcquireLoc,
-                                            JoinLoc, LEK1);
+          Handler.handleMutexHeldEndOfScope("mutex",
+                                            LDat2.UnderlyingMutex.toString(),
+                                            LDat2.AcquireLoc, JoinLoc, LEK1);
         }
       }
       else if (!LDat2.Managed && !FSet2Mutex.isUniversal() && !LDat2.Asserted)
-        Handler.handleMutexHeldEndOfScope(FSet2Mutex.toString(),
-                                          LDat2.AcquireLoc,
-                                          JoinLoc, LEK1);
+        Handler.handleMutexHeldEndOfScope("mutex", FSet2Mutex.toString(),
+                                          LDat2.AcquireLoc, JoinLoc, LEK1);
     }
   }
 
   // Find locks in FSet1 that are not in FSet2, and remove them.
-  for (FactSet::const_iterator I = FSet1Orig.begin(), E = FSet1Orig.end();
-       I != E; ++I) {
-    const SExpr &FSet1Mutex = FactMan[*I].MutID;
-    const LockData &LDat1 = FactMan[*I].LDat;
+  for (const auto &Fact : FSet1Orig) {
+    const SExpr &FSet1Mutex = FactMan[Fact].MutID;
+    const LockData &LDat1 = FactMan[Fact].LDat;
 
     if (!FSet2.findLock(FactMan, FSet1Mutex)) {
       if (LDat1.UnderlyingMutex.isValid()) {
@@ -2293,15 +2300,14 @@
           // If this is a scoped lock that manages another mutex, and if the
           // underlying mutex is still held, then warn about the underlying
           // mutex.
-          Handler.handleMutexHeldEndOfScope(LDat1.UnderlyingMutex.toString(),
-                                            LDat1.AcquireLoc,
-                                            JoinLoc, LEK1);
+          Handler.handleMutexHeldEndOfScope("mutex",
+                                            LDat1.UnderlyingMutex.toString(),
+                                            LDat1.AcquireLoc, JoinLoc, LEK1);
         }
       }
       else if (!LDat1.Managed && !FSet1Mutex.isUniversal() && !LDat1.Asserted)
-        Handler.handleMutexHeldEndOfScope(FSet1Mutex.toString(),
-                                          LDat1.AcquireLoc,
-                                          JoinLoc, LEK2);
+        Handler.handleMutexHeldEndOfScope("mutex", FSet1Mutex.toString(),
+                                          LDat1.AcquireLoc, JoinLoc, LEK2);
       if (Modify)
         FSet1.removeLock(FactMan, FSet1Mutex);
     }
@@ -2331,16 +2337,21 @@
 /// at the end of each block, and issue warnings for thread safety violations.
 /// Each block in the CFG is traversed exactly once.
 void ThreadSafetyAnalyzer::runAnalysis(AnalysisDeclContext &AC) {
-  CFG *CFGraph = AC.getCFG();
-  if (!CFGraph) return;
-  const NamedDecl *D = dyn_cast_or_null<NamedDecl>(AC.getDecl());
+  // TODO: this whole function needs be rewritten as a visitor for CFGWalker.
+  // For now, we just use the walker to set things up.
+  threadSafety::CFGWalker walker;
+  if (!walker.init(AC))
+    return;
 
   // AC.dumpCFG(true);
+  // threadSafety::printSCFG(walker);
 
-  if (!D)
-    return;  // Ignore anonymous functions for now.
-  if (D->getAttr<NoThreadSafetyAnalysisAttr>())
+  CFG *CFGraph = walker.getGraph();
+  const NamedDecl *D = walker.getDecl();
+
+  if (D->hasAttr<NoThreadSafetyAnalysisAttr>())
     return;
+
   // FIXME: Do something a bit more intelligent inside constructor and
   // destructor code.  Constructors and destructors must assume unique access
   // to 'this', so checks on member variable access is disabled, but we should
@@ -2356,7 +2367,7 @@
   // We need to explore the CFG via a "topological" ordering.
   // That way, we will be guaranteed to have information about required
   // predecessor locksets when exploring a new block.
-  PostOrderCFGView *SortedGraph = AC.getAnalysis<PostOrderCFGView>();
+  const PostOrderCFGView *SortedGraph = walker.getSortedGraph();
   PostOrderCFGView::CFGBlockSet VisitedBlocks(CFGraph);
 
   // Mark entry block as reachable
@@ -2382,35 +2393,31 @@
 
     MutexIDList ExclusiveLocksToAdd;
     MutexIDList SharedLocksToAdd;
+    StringRef CapDiagKind = "mutex";
 
     SourceLocation Loc = D->getLocation();
-    for (unsigned i = 0; i < ArgAttrs.size(); ++i) {
-      Attr *Attr = ArgAttrs[i];
+    for (const auto *Attr : ArgAttrs) {
       Loc = Attr->getLocation();
-      if (ExclusiveLocksRequiredAttr *A
-            = dyn_cast<ExclusiveLocksRequiredAttr>(Attr)) {
-        getMutexIDs(ExclusiveLocksToAdd, A, (Expr*) 0, D);
-      } else if (SharedLocksRequiredAttr *A
-                   = dyn_cast<SharedLocksRequiredAttr>(Attr)) {
-        getMutexIDs(SharedLocksToAdd, A, (Expr*) 0, D);
-      } else if (UnlockFunctionAttr *A = dyn_cast<UnlockFunctionAttr>(Attr)) {
+      if (const auto *A = dyn_cast<RequiresCapabilityAttr>(Attr)) {
+        getMutexIDs(A->isShared() ? SharedLocksToAdd : ExclusiveLocksToAdd, A,
+                    nullptr, D);
+        CapDiagKind = ClassifyDiagnostic(A);
+      } else if (const auto *A = dyn_cast<ReleaseCapabilityAttr>(Attr)) {
         // UNLOCK_FUNCTION() is used to hide the underlying lock implementation.
         // We must ignore such methods.
         if (A->args_size() == 0)
           return;
         // FIXME -- deal with exclusive vs. shared unlock functions?
-        getMutexIDs(ExclusiveLocksToAdd, A, (Expr*) 0, D);
-        getMutexIDs(LocksReleased, A, (Expr*) 0, D);
-      } else if (ExclusiveLockFunctionAttr *A
-                   = dyn_cast<ExclusiveLockFunctionAttr>(Attr)) {
+        getMutexIDs(ExclusiveLocksToAdd, A, nullptr, D);
+        getMutexIDs(LocksReleased, A, nullptr, D);
+        CapDiagKind = ClassifyDiagnostic(A);
+      } else if (const auto *A = dyn_cast<AcquireCapabilityAttr>(Attr)) {
         if (A->args_size() == 0)
           return;
-        getMutexIDs(ExclusiveLocksAcquired, A, (Expr*) 0, D);
-      } else if (SharedLockFunctionAttr *A
-                   = dyn_cast<SharedLockFunctionAttr>(Attr)) {
-        if (A->args_size() == 0)
-          return;
-        getMutexIDs(SharedLocksAcquired, A, (Expr*) 0, D);
+        getMutexIDs(A->isShared() ? SharedLocksAcquired
+                                  : ExclusiveLocksAcquired,
+                    A, nullptr, D);
+        CapDiagKind = ClassifyDiagnostic(A);
       } else if (isa<ExclusiveTrylockFunctionAttr>(Attr)) {
         // Don't try to check trylock functions for now
         return;
@@ -2421,19 +2428,15 @@
     }
 
     // FIXME -- Loc can be wrong here.
-    for (unsigned i=0,n=ExclusiveLocksToAdd.size(); i<n; ++i) {
-      addLock(InitialLockset, ExclusiveLocksToAdd[i],
-              LockData(Loc, LK_Exclusive));
-    }
-    for (unsigned i=0,n=SharedLocksToAdd.size(); i<n; ++i) {
-      addLock(InitialLockset, SharedLocksToAdd[i],
-              LockData(Loc, LK_Shared));
-    }
+    for (const auto &ExclusiveLockToAdd : ExclusiveLocksToAdd)
+      addLock(InitialLockset, ExclusiveLockToAdd, LockData(Loc, LK_Exclusive),
+              CapDiagKind);
+    for (const auto &SharedLockToAdd : SharedLocksToAdd)
+      addLock(InitialLockset, SharedLockToAdd, LockData(Loc, LK_Shared),
+              CapDiagKind);
   }
 
-  for (PostOrderCFGView::iterator I = SortedGraph->begin(),
-       E = SortedGraph->end(); I!= E; ++I) {
-    const CFGBlock *CurrBlock = *I;
+  for (const auto *CurrBlock : *SortedGraph) {
     int CurrBlockID = CurrBlock->getBlockID();
     CFGBlockInfo *CurrBlockInfo = &BlockInfo[CurrBlockID];
 
@@ -2459,7 +2462,7 @@
          PE  = CurrBlock->pred_end(); PI != PE; ++PI) {
 
       // if *PI -> CurrBlock is a back edge
-      if (*PI == 0 || !VisitedBlocks.alreadySet(*PI))
+      if (*PI == nullptr || !VisitedBlocks.alreadySet(*PI))
         continue;
 
       int PrevBlockID = (*PI)->getBlockID();
@@ -2502,9 +2505,7 @@
 
     // Process continue and break blocks. Assume that the lockset for the
     // resulting block is unaffected by any discrepancies in them.
-    for (unsigned SpecialI = 0, SpecialN = SpecialBlocks.size();
-         SpecialI < SpecialN; ++SpecialI) {
-      CFGBlock *PrevBlock = SpecialBlocks[SpecialI];
+    for (const auto *PrevBlock : SpecialBlocks) {
       int PrevBlockID = PrevBlock->getBlockID();
       CFGBlockInfo *PrevBlockInfo = &BlockInfo[PrevBlockID];
 
@@ -2573,7 +2574,7 @@
          SE  = CurrBlock->succ_end(); SI != SE; ++SI) {
 
       // if CurrBlock -> *SI is *not* a back edge
-      if (*SI == 0 || !VisitedBlocks.alreadySet(*SI))
+      if (*SI == nullptr || !VisitedBlocks.alreadySet(*SI))
         continue;
 
       CFGBlock *FirstLoopBlock = *SI;
@@ -2600,17 +2601,14 @@
   // by *-LOCK_FUNCTION and UNLOCK_FUNCTION.  The intersect below will then
   // issue the appropriate warning.
   // FIXME: the location here is not quite right.
-  for (unsigned i=0,n=ExclusiveLocksAcquired.size(); i<n; ++i) {
-    ExpectedExitSet.addLock(FactMan, ExclusiveLocksAcquired[i],
+  for (const auto &Lock : ExclusiveLocksAcquired)
+    ExpectedExitSet.addLock(FactMan, Lock,
                             LockData(D->getLocation(), LK_Exclusive));
-  }
-  for (unsigned i=0,n=SharedLocksAcquired.size(); i<n; ++i) {
-    ExpectedExitSet.addLock(FactMan, SharedLocksAcquired[i],
+  for (const auto &Lock : SharedLocksAcquired)
+    ExpectedExitSet.addLock(FactMan, Lock,
                             LockData(D->getLocation(), LK_Shared));
-  }
-  for (unsigned i=0,n=LocksReleased.size(); i<n; ++i) {
-    ExpectedExitSet.removeLock(FactMan, LocksReleased[i]);
-  }
+  for (const auto &Lock : LocksReleased)
+    ExpectedExitSet.removeLock(FactMan, Lock);
 
   // FIXME: Should we call this function for all blocks which exit the function?
   intersectAndWarn(ExpectedExitSet, Final->ExitSet,
diff --git a/lib/Analysis/ThreadSafetyCommon.cpp b/lib/Analysis/ThreadSafetyCommon.cpp
new file mode 100644
index 0000000..da88b78
--- /dev/null
+++ b/lib/Analysis/ThreadSafetyCommon.cpp
@@ -0,0 +1,794 @@
+//===- ThreadSafetyCommon.cpp ----------------------------------*- C++ --*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Implementation of the interfaces declared in ThreadSafetyCommon.h
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Analysis/Analyses/ThreadSafetyCommon.h"
+#include "clang/AST/Attr.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/StmtCXX.h"
+#include "clang/Analysis/Analyses/PostOrderCFGView.h"
+#include "clang/Analysis/Analyses/ThreadSafetyTIL.h"
+#include "clang/Analysis/Analyses/ThreadSafetyTraverse.h"
+#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Basic/OperatorKinds.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+
+#include <algorithm>
+#include <climits>
+#include <vector>
+
+
+namespace clang {
+namespace threadSafety {
+
+// From ThreadSafetyUtil.h
+std::string getSourceLiteralString(const clang::Expr *CE) {
+  switch (CE->getStmtClass()) {
+    case Stmt::IntegerLiteralClass:
+      return cast<IntegerLiteral>(CE)->getValue().toString(10, true);
+    case Stmt::StringLiteralClass: {
+      std::string ret("\"");
+      ret += cast<StringLiteral>(CE)->getString();
+      ret += "\"";
+      return ret;
+    }
+    case Stmt::CharacterLiteralClass:
+    case Stmt::CXXNullPtrLiteralExprClass:
+    case Stmt::GNUNullExprClass:
+    case Stmt::CXXBoolLiteralExprClass:
+    case Stmt::FloatingLiteralClass:
+    case Stmt::ImaginaryLiteralClass:
+    case Stmt::ObjCStringLiteralClass:
+    default:
+      return "#lit";
+  }
+}
+
+namespace til {
+
+// Return true if E is a variable that points to an incomplete Phi node.
+static bool isIncompleteVar(const SExpr *E) {
+  if (const auto *V = dyn_cast<Variable>(E)) {
+    if (const auto *Ph = dyn_cast<Phi>(V->definition()))
+      return Ph->status() == Phi::PH_Incomplete;
+  }
+  return false;
+}
+
+}  // end namespace til
+
+
+typedef SExprBuilder::CallingContext CallingContext;
+
+
+til::SExpr *SExprBuilder::lookupStmt(const Stmt *S) {
+  auto It = SMap.find(S);
+  if (It != SMap.end())
+    return It->second;
+  return nullptr;
+}
+
+
+til::SCFG *SExprBuilder::buildCFG(CFGWalker &Walker) {
+  Walker.walk(*this);
+  return Scfg;
+}
+
+
+// Translate a clang statement or expression to a TIL expression.
+// Also performs substitution of variables; Ctx provides the context.
+// Dispatches on the type of S.
+til::SExpr *SExprBuilder::translate(const Stmt *S, CallingContext *Ctx) {
+  if (!S)
+    return nullptr;
+
+  // Check if S has already been translated and cached.
+  // This handles the lookup of SSA names for DeclRefExprs here.
+  if (til::SExpr *E = lookupStmt(S))
+    return E;
+
+  switch (S->getStmtClass()) {
+  case Stmt::DeclRefExprClass:
+    return translateDeclRefExpr(cast<DeclRefExpr>(S), Ctx);
+  case Stmt::CXXThisExprClass:
+    return translateCXXThisExpr(cast<CXXThisExpr>(S), Ctx);
+  case Stmt::MemberExprClass:
+    return translateMemberExpr(cast<MemberExpr>(S), Ctx);
+  case Stmt::CallExprClass:
+    return translateCallExpr(cast<CallExpr>(S), Ctx);
+  case Stmt::CXXMemberCallExprClass:
+    return translateCXXMemberCallExpr(cast<CXXMemberCallExpr>(S), Ctx);
+  case Stmt::CXXOperatorCallExprClass:
+    return translateCXXOperatorCallExpr(cast<CXXOperatorCallExpr>(S), Ctx);
+  case Stmt::UnaryOperatorClass:
+    return translateUnaryOperator(cast<UnaryOperator>(S), Ctx);
+  case Stmt::BinaryOperatorClass:
+  case Stmt::CompoundAssignOperatorClass:
+    return translateBinaryOperator(cast<BinaryOperator>(S), Ctx);
+
+  case Stmt::ArraySubscriptExprClass:
+    return translateArraySubscriptExpr(cast<ArraySubscriptExpr>(S), Ctx);
+  case Stmt::ConditionalOperatorClass:
+    return translateConditionalOperator(cast<ConditionalOperator>(S), Ctx);
+  case Stmt::BinaryConditionalOperatorClass:
+    return translateBinaryConditionalOperator(
+             cast<BinaryConditionalOperator>(S), Ctx);
+
+  // We treat these as no-ops
+  case Stmt::ParenExprClass:
+    return translate(cast<ParenExpr>(S)->getSubExpr(), Ctx);
+  case Stmt::ExprWithCleanupsClass:
+    return translate(cast<ExprWithCleanups>(S)->getSubExpr(), Ctx);
+  case Stmt::CXXBindTemporaryExprClass:
+    return translate(cast<CXXBindTemporaryExpr>(S)->getSubExpr(), Ctx);
+
+  // Collect all literals
+  case Stmt::CharacterLiteralClass:
+  case Stmt::CXXNullPtrLiteralExprClass:
+  case Stmt::GNUNullExprClass:
+  case Stmt::CXXBoolLiteralExprClass:
+  case Stmt::FloatingLiteralClass:
+  case Stmt::ImaginaryLiteralClass:
+  case Stmt::IntegerLiteralClass:
+  case Stmt::StringLiteralClass:
+  case Stmt::ObjCStringLiteralClass:
+    return new (Arena) til::Literal(cast<Expr>(S));
+
+  case Stmt::DeclStmtClass:
+    return translateDeclStmt(cast<DeclStmt>(S), Ctx);
+  default:
+    break;
+  }
+  if (const CastExpr *CE = dyn_cast<CastExpr>(S))
+    return translateCastExpr(CE, Ctx);
+
+  return new (Arena) til::Undefined(S);
+}
+
+
+til::SExpr *SExprBuilder::translateDeclRefExpr(const DeclRefExpr *DRE,
+                                               CallingContext *Ctx) {
+  const ValueDecl *VD = cast<ValueDecl>(DRE->getDecl()->getCanonicalDecl());
+
+  // Function parameters require substitution and/or renaming.
+  if (const ParmVarDecl *PV = dyn_cast_or_null<ParmVarDecl>(VD)) {
+    const FunctionDecl *FD =
+        cast<FunctionDecl>(PV->getDeclContext())->getCanonicalDecl();
+    unsigned I = PV->getFunctionScopeIndex();
+
+    if (Ctx && Ctx->FunArgs && FD == Ctx->AttrDecl->getCanonicalDecl()) {
+      // Substitute call arguments for references to function parameters
+      assert(I < Ctx->NumArgs);
+      return translate(Ctx->FunArgs[I], Ctx->Prev);
+    }
+    // Map the param back to the param of the original function declaration
+    // for consistent comparisons.
+    VD = FD->getParamDecl(I);
+  }
+
+  // For non-local variables, treat it as a referenced to a named object.
+  return new (Arena) til::LiteralPtr(VD);
+}
+
+
+til::SExpr *SExprBuilder::translateCXXThisExpr(const CXXThisExpr *TE,
+                                               CallingContext *Ctx) {
+  // Substitute for 'this'
+  if (Ctx && Ctx->SelfArg)
+    return translate(Ctx->SelfArg, Ctx->Prev);
+  assert(SelfVar && "We have no variable for 'this'!");
+  return SelfVar;
+}
+
+
+til::SExpr *SExprBuilder::translateMemberExpr(const MemberExpr *ME,
+                                              CallingContext *Ctx) {
+  til::SExpr *E = translate(ME->getBase(), Ctx);
+  E = new (Arena) til::SApply(E);
+  return new (Arena) til::Project(E, ME->getMemberDecl());
+}
+
+
+til::SExpr *SExprBuilder::translateCallExpr(const CallExpr *CE,
+                                            CallingContext *Ctx) {
+  // TODO -- Lock returned
+  til::SExpr *E = translate(CE->getCallee(), Ctx);
+  for (const auto *Arg : CE->arguments()) {
+    til::SExpr *A = translate(Arg, Ctx);
+    E = new (Arena) til::Apply(E, A);
+  }
+  return new (Arena) til::Call(E, CE);
+}
+
+
+til::SExpr *SExprBuilder::translateCXXMemberCallExpr(
+    const CXXMemberCallExpr *ME, CallingContext *Ctx) {
+  return translateCallExpr(cast<CallExpr>(ME), Ctx);
+}
+
+
+til::SExpr *SExprBuilder::translateCXXOperatorCallExpr(
+    const CXXOperatorCallExpr *OCE, CallingContext *Ctx) {
+  return translateCallExpr(cast<CallExpr>(OCE), Ctx);
+}
+
+
+til::SExpr *SExprBuilder::translateUnaryOperator(const UnaryOperator *UO,
+                                                 CallingContext *Ctx) {
+  switch (UO->getOpcode()) {
+  case UO_PostInc:
+  case UO_PostDec:
+  case UO_PreInc:
+  case UO_PreDec:
+    return new (Arena) til::Undefined(UO);
+
+  // We treat these as no-ops
+  case UO_AddrOf:
+  case UO_Deref:
+  case UO_Plus:
+    return translate(UO->getSubExpr(), Ctx);
+
+  case UO_Minus:
+    return new (Arena)
+      til::UnaryOp(til::UOP_Minus, translate(UO->getSubExpr(), Ctx));
+  case UO_Not:
+    return new (Arena)
+      til::UnaryOp(til::UOP_BitNot, translate(UO->getSubExpr(), Ctx));
+  case UO_LNot:
+    return new (Arena)
+      til::UnaryOp(til::UOP_LogicNot, translate(UO->getSubExpr(), Ctx));
+
+  // Currently unsupported
+  case UO_Real:
+  case UO_Imag:
+  case UO_Extension:
+    return new (Arena) til::Undefined(UO);
+  }
+  return new (Arena) til::Undefined(UO);
+}
+
+
+til::SExpr *SExprBuilder::translateBinOp(til::TIL_BinaryOpcode Op,
+                                         const BinaryOperator *BO,
+                                         CallingContext *Ctx, bool Reverse) {
+   til::SExpr *E0 = translate(BO->getLHS(), Ctx);
+   til::SExpr *E1 = translate(BO->getRHS(), Ctx);
+   if (Reverse)
+     return new (Arena) til::BinaryOp(Op, E1, E0);
+   else
+     return new (Arena) til::BinaryOp(Op, E0, E1);
+}
+
+
+til::SExpr *SExprBuilder::translateBinAssign(til::TIL_BinaryOpcode Op,
+                                             const BinaryOperator *BO,
+                                             CallingContext *Ctx,
+                                             bool Assign) {
+  const Expr *LHS = BO->getLHS();
+  const Expr *RHS = BO->getRHS();
+  til::SExpr *E0 = translate(LHS, Ctx);
+  til::SExpr *E1 = translate(RHS, Ctx);
+
+  const ValueDecl *VD = nullptr;
+  til::SExpr *CV = nullptr;
+  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(LHS)) {
+    VD = DRE->getDecl();
+    CV = lookupVarDecl(VD);
+  }
+
+  if (!Assign) {
+    til::SExpr *Arg = CV ? CV : new (Arena) til::Load(E0);
+    E1 = new (Arena) til::BinaryOp(Op, Arg, E1);
+    E1 = addStatement(E1, nullptr, VD);
+  }
+  if (VD && CV)
+    return updateVarDecl(VD, E1);
+  return new (Arena) til::Store(E0, E1);
+}
+
+
+til::SExpr *SExprBuilder::translateBinaryOperator(const BinaryOperator *BO,
+                                                  CallingContext *Ctx) {
+  switch (BO->getOpcode()) {
+  case BO_PtrMemD:
+  case BO_PtrMemI:
+    return new (Arena) til::Undefined(BO);
+
+  case BO_Mul:  return translateBinOp(til::BOP_Mul, BO, Ctx);
+  case BO_Div:  return translateBinOp(til::BOP_Div, BO, Ctx);
+  case BO_Rem:  return translateBinOp(til::BOP_Rem, BO, Ctx);
+  case BO_Add:  return translateBinOp(til::BOP_Add, BO, Ctx);
+  case BO_Sub:  return translateBinOp(til::BOP_Sub, BO, Ctx);
+  case BO_Shl:  return translateBinOp(til::BOP_Shl, BO, Ctx);
+  case BO_Shr:  return translateBinOp(til::BOP_Shr, BO, Ctx);
+  case BO_LT:   return translateBinOp(til::BOP_Lt,  BO, Ctx);
+  case BO_GT:   return translateBinOp(til::BOP_Lt,  BO, Ctx, true);
+  case BO_LE:   return translateBinOp(til::BOP_Leq, BO, Ctx);
+  case BO_GE:   return translateBinOp(til::BOP_Leq, BO, Ctx, true);
+  case BO_EQ:   return translateBinOp(til::BOP_Eq,  BO, Ctx);
+  case BO_NE:   return translateBinOp(til::BOP_Neq, BO, Ctx);
+  case BO_And:  return translateBinOp(til::BOP_BitAnd,   BO, Ctx);
+  case BO_Xor:  return translateBinOp(til::BOP_BitXor,   BO, Ctx);
+  case BO_Or:   return translateBinOp(til::BOP_BitOr,    BO, Ctx);
+  case BO_LAnd: return translateBinOp(til::BOP_LogicAnd, BO, Ctx);
+  case BO_LOr:  return translateBinOp(til::BOP_LogicOr,  BO, Ctx);
+
+  case BO_Assign:    return translateBinAssign(til::BOP_Eq,  BO, Ctx, true);
+  case BO_MulAssign: return translateBinAssign(til::BOP_Mul, BO, Ctx);
+  case BO_DivAssign: return translateBinAssign(til::BOP_Div, BO, Ctx);
+  case BO_RemAssign: return translateBinAssign(til::BOP_Rem, BO, Ctx);
+  case BO_AddAssign: return translateBinAssign(til::BOP_Add, BO, Ctx);
+  case BO_SubAssign: return translateBinAssign(til::BOP_Sub, BO, Ctx);
+  case BO_ShlAssign: return translateBinAssign(til::BOP_Shl, BO, Ctx);
+  case BO_ShrAssign: return translateBinAssign(til::BOP_Shr, BO, Ctx);
+  case BO_AndAssign: return translateBinAssign(til::BOP_BitAnd, BO, Ctx);
+  case BO_XorAssign: return translateBinAssign(til::BOP_BitXor, BO, Ctx);
+  case BO_OrAssign:  return translateBinAssign(til::BOP_BitOr,  BO, Ctx);
+
+  case BO_Comma:
+    // The clang CFG should have already processed both sides.
+    return translate(BO->getRHS(), Ctx);
+  }
+  return new (Arena) til::Undefined(BO);
+}
+
+
+til::SExpr *SExprBuilder::translateCastExpr(const CastExpr *CE,
+                                            CallingContext *Ctx) {
+  clang::CastKind K = CE->getCastKind();
+  switch (K) {
+  case CK_LValueToRValue: {
+    if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CE->getSubExpr())) {
+      til::SExpr *E0 = lookupVarDecl(DRE->getDecl());
+      if (E0)
+        return E0;
+    }
+    til::SExpr *E0 = translate(CE->getSubExpr(), Ctx);
+    return new (Arena) til::Load(E0);
+  }
+  case CK_NoOp:
+  case CK_DerivedToBase:
+  case CK_UncheckedDerivedToBase:
+  case CK_ArrayToPointerDecay:
+  case CK_FunctionToPointerDecay: {
+    til::SExpr *E0 = translate(CE->getSubExpr(), Ctx);
+    return E0;
+  }
+  default: {
+    // FIXME: handle different kinds of casts.
+    til::SExpr *E0 = translate(CE->getSubExpr(), Ctx);
+    return new (Arena) til::Cast(til::CAST_none, E0);
+  }
+  }
+}
+
+
+til::SExpr *
+SExprBuilder::translateArraySubscriptExpr(const ArraySubscriptExpr *E,
+                                          CallingContext *Ctx) {
+  til::SExpr *E0 = translate(E->getBase(), Ctx);
+  til::SExpr *E1 = translate(E->getIdx(), Ctx);
+  return new (Arena) til::ArrayIndex(E0, E1);
+}
+
+
+til::SExpr *
+SExprBuilder::translateConditionalOperator(const ConditionalOperator *C,
+                                           CallingContext *Ctx) {
+  return new (Arena) til::Undefined(C);
+}
+
+
+til::SExpr *SExprBuilder::translateBinaryConditionalOperator(
+    const BinaryConditionalOperator *C, CallingContext *Ctx) {
+  return new (Arena) til::Undefined(C);
+}
+
+
+til::SExpr *
+SExprBuilder::translateDeclStmt(const DeclStmt *S, CallingContext *Ctx) {
+  DeclGroupRef DGrp = S->getDeclGroup();
+  for (DeclGroupRef::iterator I = DGrp.begin(), E = DGrp.end(); I != E; ++I) {
+    if (VarDecl *VD = dyn_cast_or_null<VarDecl>(*I)) {
+      Expr *E = VD->getInit();
+      til::SExpr* SE = translate(E, Ctx);
+
+      // Add local variables with trivial type to the variable map
+      QualType T = VD->getType();
+      if (T.isTrivialType(VD->getASTContext())) {
+        return addVarDecl(VD, SE);
+      }
+      else {
+        // TODO: add alloca
+      }
+    }
+  }
+  return nullptr;
+}
+
+
+
+// If (E) is non-trivial, then add it to the current basic block, and
+// update the statement map so that S refers to E.  Returns a new variable
+// that refers to E.
+// If E is trivial returns E.
+til::SExpr *SExprBuilder::addStatement(til::SExpr* E, const Stmt *S,
+                                       const ValueDecl *VD) {
+  if (!E)
+    return nullptr;
+  if (til::ThreadSafetyTIL::isTrivial(E))
+    return E;
+
+  til::Variable *V = new (Arena) til::Variable(E, VD);
+  CurrentInstructions.push_back(V);
+  if (S)
+    insertStmt(S, V);
+  return V;
+}
+
+
+// Returns the current value of VD, if known, and nullptr otherwise.
+til::SExpr *SExprBuilder::lookupVarDecl(const ValueDecl *VD) {
+  auto It = LVarIdxMap.find(VD);
+  if (It != LVarIdxMap.end()) {
+    assert(CurrentLVarMap[It->second].first == VD);
+    return CurrentLVarMap[It->second].second;
+  }
+  return nullptr;
+}
+
+
+// if E is a til::Variable, update its clangDecl.
+inline void maybeUpdateVD(til::SExpr *E, const ValueDecl *VD) {
+  if (!E)
+    return;
+  if (til::Variable *V = dyn_cast<til::Variable>(E)) {
+    if (!V->clangDecl())
+      V->setClangDecl(VD);
+  }
+}
+
+// Adds a new variable declaration.
+til::SExpr *SExprBuilder::addVarDecl(const ValueDecl *VD, til::SExpr *E) {
+  maybeUpdateVD(E, VD);
+  LVarIdxMap.insert(std::make_pair(VD, CurrentLVarMap.size()));
+  CurrentLVarMap.makeWritable();
+  CurrentLVarMap.push_back(std::make_pair(VD, E));
+  return E;
+}
+
+
+// Updates a current variable declaration.  (E.g. by assignment)
+til::SExpr *SExprBuilder::updateVarDecl(const ValueDecl *VD, til::SExpr *E) {
+  maybeUpdateVD(E, VD);
+  auto It = LVarIdxMap.find(VD);
+  if (It == LVarIdxMap.end()) {
+    til::SExpr *Ptr = new (Arena) til::LiteralPtr(VD);
+    til::SExpr *St  = new (Arena) til::Store(Ptr, E);
+    return St;
+  }
+  CurrentLVarMap.makeWritable();
+  CurrentLVarMap.elem(It->second).second = E;
+  return E;
+}
+
+
+// Make a Phi node in the current block for the i^th variable in CurrentVarMap.
+// If E != null, sets Phi[CurrentBlockInfo->ArgIndex] = E.
+// If E == null, this is a backedge and will be set later.
+void SExprBuilder::makePhiNodeVar(unsigned i, unsigned NPreds, til::SExpr *E) {
+  unsigned ArgIndex = CurrentBlockInfo->ProcessedPredecessors;
+  assert(ArgIndex > 0 && ArgIndex < NPreds);
+
+  til::Variable *V = dyn_cast<til::Variable>(CurrentLVarMap[i].second);
+  if (V && V->getBlockID() == CurrentBB->blockID()) {
+    // We already have a Phi node in the current block,
+    // so just add the new variable to the Phi node.
+    til::Phi *Ph = dyn_cast<til::Phi>(V->definition());
+    assert(Ph && "Expecting Phi node.");
+    if (E)
+      Ph->values()[ArgIndex] = E;
+    return;
+  }
+
+  // Make a new phi node: phi(..., E)
+  // All phi args up to the current index are set to the current value.
+  til::SExpr *CurrE = CurrentLVarMap[i].second;
+  til::Phi *Ph = new (Arena) til::Phi(Arena, NPreds);
+  Ph->values().setValues(NPreds, nullptr);
+  for (unsigned PIdx = 0; PIdx < ArgIndex; ++PIdx)
+    Ph->values()[PIdx] = CurrE;
+  if (E)
+    Ph->values()[ArgIndex] = E;
+  // If E is from a back-edge, or either E or CurrE are incomplete, then
+  // mark this node as incomplete; we may need to remove it later.
+  if (!E || isIncompleteVar(E) || isIncompleteVar(CurrE)) {
+    Ph->setStatus(til::Phi::PH_Incomplete);
+  }
+
+  // Add Phi node to current block, and update CurrentLVarMap[i]
+  auto *Var = new (Arena) til::Variable(Ph, CurrentLVarMap[i].first);
+  CurrentArguments.push_back(Var);
+  if (Ph->status() == til::Phi::PH_Incomplete)
+    IncompleteArgs.push_back(Var);
+
+  CurrentLVarMap.makeWritable();
+  CurrentLVarMap.elem(i).second = Var;
+}
+
+
+// Merge values from Map into the current variable map.
+// This will construct Phi nodes in the current basic block as necessary.
+void SExprBuilder::mergeEntryMap(LVarDefinitionMap Map) {
+  assert(CurrentBlockInfo && "Not processing a block!");
+
+  if (!CurrentLVarMap.valid()) {
+    // Steal Map, using copy-on-write.
+    CurrentLVarMap = std::move(Map);
+    return;
+  }
+  if (CurrentLVarMap.sameAs(Map))
+    return;  // Easy merge: maps from different predecessors are unchanged.
+
+  unsigned NPreds = CurrentBB->numPredecessors();
+  unsigned ESz = CurrentLVarMap.size();
+  unsigned MSz = Map.size();
+  unsigned Sz  = std::min(ESz, MSz);
+
+  for (unsigned i=0; i<Sz; ++i) {
+    if (CurrentLVarMap[i].first != Map[i].first) {
+      // We've reached the end of variables in common.
+      CurrentLVarMap.makeWritable();
+      CurrentLVarMap.downsize(i);
+      break;
+    }
+    if (CurrentLVarMap[i].second != Map[i].second)
+      makePhiNodeVar(i, NPreds, Map[i].second);
+  }
+  if (ESz > MSz) {
+    CurrentLVarMap.makeWritable();
+    CurrentLVarMap.downsize(Map.size());
+  }
+}
+
+
+// Merge a back edge into the current variable map.
+// This will create phi nodes for all variables in the variable map.
+void SExprBuilder::mergeEntryMapBackEdge() {
+  // We don't have definitions for variables on the backedge, because we
+  // haven't gotten that far in the CFG.  Thus, when encountering a back edge,
+  // we conservatively create Phi nodes for all variables.  Unnecessary Phi
+  // nodes will be marked as incomplete, and stripped out at the end.
+  //
+  // An Phi node is unnecessary if it only refers to itself and one other
+  // variable, e.g. x = Phi(y, y, x)  can be reduced to x = y.
+
+  assert(CurrentBlockInfo && "Not processing a block!");
+
+  if (CurrentBlockInfo->HasBackEdges)
+    return;
+  CurrentBlockInfo->HasBackEdges = true;
+
+  CurrentLVarMap.makeWritable();
+  unsigned Sz = CurrentLVarMap.size();
+  unsigned NPreds = CurrentBB->numPredecessors();
+
+  for (unsigned i=0; i < Sz; ++i) {
+    makePhiNodeVar(i, NPreds, nullptr);
+  }
+}
+
+
+// Update the phi nodes that were initially created for a back edge
+// once the variable definitions have been computed.
+// I.e., merge the current variable map into the phi nodes for Blk.
+void SExprBuilder::mergePhiNodesBackEdge(const CFGBlock *Blk) {
+  til::BasicBlock *BB = lookupBlock(Blk);
+  unsigned ArgIndex = BBInfo[Blk->getBlockID()].ProcessedPredecessors;
+  assert(ArgIndex > 0 && ArgIndex < BB->numPredecessors());
+
+  for (til::Variable *V : BB->arguments()) {
+    til::Phi *Ph = dyn_cast_or_null<til::Phi>(V->definition());
+    assert(Ph && "Expecting Phi Node.");
+    assert(Ph->values()[ArgIndex] == nullptr && "Wrong index for back edge.");
+    assert(V->clangDecl() && "No local variable for Phi node.");
+
+    til::SExpr *E = lookupVarDecl(V->clangDecl());
+    assert(E && "Couldn't find local variable for Phi node.");
+
+    Ph->values()[ArgIndex] = E;
+  }
+}
+
+void SExprBuilder::enterCFG(CFG *Cfg, const NamedDecl *D,
+                            const CFGBlock *First) {
+  // Perform initial setup operations.
+  unsigned NBlocks = Cfg->getNumBlockIDs();
+  Scfg = new (Arena) til::SCFG(Arena, NBlocks);
+
+  // allocate all basic blocks immediately, to handle forward references.
+  BBInfo.resize(NBlocks);
+  BlockMap.resize(NBlocks, nullptr);
+  // create map from clang blockID to til::BasicBlocks
+  for (auto *B : *Cfg) {
+    auto *BB = new (Arena) til::BasicBlock(Arena);
+    BB->reserveInstructions(B->size());
+    BlockMap[B->getBlockID()] = BB;
+  }
+  CallCtx.reset(new SExprBuilder::CallingContext(D));
+
+  CurrentBB = lookupBlock(&Cfg->getEntry());
+  auto Parms = isa<ObjCMethodDecl>(D) ? cast<ObjCMethodDecl>(D)->parameters()
+                                      : cast<FunctionDecl>(D)->parameters();
+  for (auto *Pm : Parms) {
+    QualType T = Pm->getType();
+    if (!T.isTrivialType(Pm->getASTContext()))
+      continue;
+
+    // Add parameters to local variable map.
+    // FIXME: right now we emulate params with loads; that should be fixed.
+    til::SExpr *Lp = new (Arena) til::LiteralPtr(Pm);
+    til::SExpr *Ld = new (Arena) til::Load(Lp);
+    til::SExpr *V  = addStatement(Ld, nullptr, Pm);
+    addVarDecl(Pm, V);
+  }
+}
+
+
+void SExprBuilder::enterCFGBlock(const CFGBlock *B) {
+  // Intialize TIL basic block and add it to the CFG.
+  CurrentBB = lookupBlock(B);
+  CurrentBB->reservePredecessors(B->pred_size());
+  Scfg->add(CurrentBB);
+
+  CurrentBlockInfo = &BBInfo[B->getBlockID()];
+
+  // CurrentLVarMap is moved to ExitMap on block exit.
+  // FIXME: the entry block will hold function parameters.
+  // assert(!CurrentLVarMap.valid() && "CurrentLVarMap already initialized.");
+}
+
+
+void SExprBuilder::handlePredecessor(const CFGBlock *Pred) {
+  // Compute CurrentLVarMap on entry from ExitMaps of predecessors
+
+  CurrentBB->addPredecessor(BlockMap[Pred->getBlockID()]);
+  BlockInfo *PredInfo = &BBInfo[Pred->getBlockID()];
+  assert(PredInfo->UnprocessedSuccessors > 0);
+
+  if (--PredInfo->UnprocessedSuccessors == 0)
+    mergeEntryMap(std::move(PredInfo->ExitMap));
+  else
+    mergeEntryMap(PredInfo->ExitMap.clone());
+
+  ++CurrentBlockInfo->ProcessedPredecessors;
+}
+
+
+void SExprBuilder::handlePredecessorBackEdge(const CFGBlock *Pred) {
+  mergeEntryMapBackEdge();
+}
+
+
+void SExprBuilder::enterCFGBlockBody(const CFGBlock *B) {
+  // The merge*() methods have created arguments.
+  // Push those arguments onto the basic block.
+  CurrentBB->arguments().reserve(
+    static_cast<unsigned>(CurrentArguments.size()), Arena);
+  for (auto *V : CurrentArguments)
+    CurrentBB->addArgument(V);
+}
+
+
+void SExprBuilder::handleStatement(const Stmt *S) {
+  til::SExpr *E = translate(S, CallCtx.get());
+  addStatement(E, S);
+}
+
+
+void SExprBuilder::handleDestructorCall(const VarDecl *VD,
+                                        const CXXDestructorDecl *DD) {
+  til::SExpr *Sf = new (Arena) til::LiteralPtr(VD);
+  til::SExpr *Dr = new (Arena) til::LiteralPtr(DD);
+  til::SExpr *Ap = new (Arena) til::Apply(Dr, Sf);
+  til::SExpr *E = new (Arena) til::Call(Ap);
+  addStatement(E, nullptr);
+}
+
+
+
+void SExprBuilder::exitCFGBlockBody(const CFGBlock *B) {
+  CurrentBB->instructions().reserve(
+    static_cast<unsigned>(CurrentInstructions.size()), Arena);
+  for (auto *V : CurrentInstructions)
+    CurrentBB->addInstruction(V);
+
+  // Create an appropriate terminator
+  unsigned N = B->succ_size();
+  auto It = B->succ_begin();
+  if (N == 1) {
+    til::BasicBlock *BB = *It ? lookupBlock(*It) : nullptr;
+    // TODO: set index
+    unsigned Idx = BB ? BB->findPredecessorIndex(CurrentBB) : 0;
+    til::SExpr *Tm = new (Arena) til::Goto(BB, Idx);
+    CurrentBB->setTerminator(Tm);
+  }
+  else if (N == 2) {
+    til::SExpr *C = translate(B->getTerminatorCondition(true), CallCtx.get());
+    til::BasicBlock *BB1 = *It ? lookupBlock(*It) : nullptr;
+    ++It;
+    til::BasicBlock *BB2 = *It ? lookupBlock(*It) : nullptr;
+    unsigned Idx1 = BB1 ? BB1->findPredecessorIndex(CurrentBB) : 0;
+    unsigned Idx2 = BB2 ? BB2->findPredecessorIndex(CurrentBB) : 0;
+    til::SExpr *Tm = new (Arena) til::Branch(C, BB1, BB2, Idx1, Idx2);
+    CurrentBB->setTerminator(Tm);
+  }
+}
+
+
+void SExprBuilder::handleSuccessor(const CFGBlock *Succ) {
+  ++CurrentBlockInfo->UnprocessedSuccessors;
+}
+
+
+void SExprBuilder::handleSuccessorBackEdge(const CFGBlock *Succ) {
+  mergePhiNodesBackEdge(Succ);
+  ++BBInfo[Succ->getBlockID()].ProcessedPredecessors;
+}
+
+
+void SExprBuilder::exitCFGBlock(const CFGBlock *B) {
+  CurrentArguments.clear();
+  CurrentInstructions.clear();
+  CurrentBlockInfo->ExitMap = std::move(CurrentLVarMap);
+  CurrentBB = nullptr;
+  CurrentBlockInfo = nullptr;
+}
+
+
+void SExprBuilder::exitCFG(const CFGBlock *Last) {
+  for (auto *V : IncompleteArgs) {
+    til::Phi *Ph = dyn_cast<til::Phi>(V->definition());
+    if (Ph && Ph->status() == til::Phi::PH_Incomplete)
+      simplifyIncompleteArg(V, Ph);
+  }
+
+  CurrentArguments.clear();
+  CurrentInstructions.clear();
+  IncompleteArgs.clear();
+}
+
+
+
+class TILPrinter : public til::PrettyPrinter<TILPrinter, llvm::raw_ostream> {};
+
+
+void printSCFG(CFGWalker &Walker) {
+  llvm::BumpPtrAllocator Bpa;
+  til::MemRegionRef Arena(&Bpa);
+  SExprBuilder builder(Arena);
+  til::SCFG *Cfg = builder.buildCFG(Walker);
+  TILPrinter::print(Cfg, llvm::errs());
+}
+
+
+
+} // end namespace threadSafety
+
+} // end namespace clang
diff --git a/lib/Analysis/ThreadSafetyLogical.cpp b/lib/Analysis/ThreadSafetyLogical.cpp
new file mode 100644
index 0000000..facfa11
--- /dev/null
+++ b/lib/Analysis/ThreadSafetyLogical.cpp
@@ -0,0 +1,112 @@
+//===- ThreadSafetyLogical.cpp ---------------------------------*- C++ --*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// This file defines a representation for logical expressions with SExpr leaves
+// that are used as part of fact-checking capability expressions.
+//===----------------------------------------------------------------------===//
+
+#include "clang/Analysis/Analyses/ThreadSafetyLogical.h"
+
+using namespace llvm;
+using namespace clang::threadSafety::lexpr;
+
+// Implication.  We implement De Morgan's Laws by maintaining LNeg and RNeg
+// to keep track of whether LHS and RHS are negated.
+static bool implies(const LExpr *LHS, bool LNeg, const LExpr *RHS, bool RNeg) {
+  // In comments below, we write => for implication.
+
+  // Calculates the logical AND implication operator.
+  const auto LeftAndOperator = [=](const BinOp *A) {
+    return implies(A->left(), LNeg, RHS, RNeg) &&
+           implies(A->right(), LNeg, RHS, RNeg);
+  };
+  const auto RightAndOperator = [=](const BinOp *A) {
+    return implies(LHS, LNeg, A->left(), RNeg) &&
+           implies(LHS, LNeg, A->right(), RNeg);
+  };
+
+  // Calculates the logical OR implication operator.
+  const auto LeftOrOperator = [=](const BinOp *A) {
+    return implies(A->left(), LNeg, RHS, RNeg) ||
+           implies(A->right(), LNeg, RHS, RNeg);
+  };
+  const auto RightOrOperator = [=](const BinOp *A) {
+    return implies(LHS, LNeg, A->left(), RNeg) ||
+           implies(LHS, LNeg, A->right(), RNeg);
+  };
+
+  // Recurse on right.
+  switch (RHS->kind()) {
+  case LExpr::And:
+    // When performing right recursion:
+    //   C => A & B  [if]  C => A and C => B
+    // When performing right recursion (negated):
+    //   C => !(A & B)  [if]  C => !A | !B  [===]  C => !A or C => !B
+    return RNeg ? RightOrOperator(cast<And>(RHS))
+                : RightAndOperator(cast<And>(RHS));
+  case LExpr::Or:
+    // When performing right recursion:
+    //   C => (A | B)  [if]  C => A or C => B
+    // When performing right recursion (negated):
+    //   C => !(A | B)  [if]  C => !A & !B  [===]  C => !A and C => !B
+    return RNeg ? RightAndOperator(cast<Or>(RHS))
+                : RightOrOperator(cast<Or>(RHS));
+  case LExpr::Not:
+    // Note that C => !A is very different from !(C => A). It would be incorrect
+    // to return !implies(LHS, RHS).
+    return implies(LHS, LNeg, cast<Not>(RHS)->exp(), !RNeg);
+  case LExpr::Terminal:
+    // After reaching the terminal, it's time to recurse on the left.
+    break;
+  }
+
+  // RHS is now a terminal.  Recurse on Left.
+  switch (LHS->kind()) {
+  case LExpr::And:
+    // When performing left recursion:
+    //   A & B => C  [if]  A => C or B => C
+    // When performing left recursion (negated):
+    //   !(A & B) => C  [if]  !A | !B => C  [===]  !A => C and !B => C
+    return LNeg ? LeftAndOperator(cast<And>(LHS))
+                : LeftOrOperator(cast<And>(LHS));
+  case LExpr::Or:
+    // When performing left recursion:
+    //   A | B => C  [if]  A => C and B => C
+    // When performing left recursion (negated):
+    //   !(A | B) => C  [if]  !A & !B => C  [===]  !A => C or !B => C
+    return LNeg ? LeftOrOperator(cast<Or>(LHS))
+                : LeftAndOperator(cast<Or>(LHS));
+  case LExpr::Not:
+    // Note that A => !C is very different from !(A => C). It would be incorrect
+    // to return !implies(LHS, RHS).
+    return implies(cast<Not>(LHS)->exp(), !LNeg, RHS, RNeg);
+  case LExpr::Terminal:
+    // After reaching the terminal, it's time to perform identity comparisons.
+    break;
+  }
+
+  // A => A
+  // !A => !A
+  if (LNeg != RNeg)
+    return false;
+
+  // FIXME -- this should compare SExprs for equality, not pointer equality.
+  return cast<Terminal>(LHS)->expr() == cast<Terminal>(RHS)->expr();
+}
+
+namespace clang {
+namespace threadSafety {
+namespace lexpr {
+
+bool implies(const LExpr *LHS, const LExpr *RHS) {
+  // Start out by assuming that LHS and RHS are not negated.
+  return ::implies(LHS, false, RHS, false);
+}
+}
+}
+}
diff --git a/lib/Analysis/ThreadSafetyTIL.cpp b/lib/Analysis/ThreadSafetyTIL.cpp
new file mode 100644
index 0000000..f67cbb9
--- /dev/null
+++ b/lib/Analysis/ThreadSafetyTIL.cpp
@@ -0,0 +1,153 @@
+//===- ThreadSafetyTIL.cpp -------------------------------------*- C++ --*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT in the llvm repository for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Analysis/Analyses/ThreadSafetyTIL.h"
+#include "clang/Analysis/Analyses/ThreadSafetyTraverse.h"
+
+namespace clang {
+namespace threadSafety {
+namespace til {
+
+
+StringRef getUnaryOpcodeString(TIL_UnaryOpcode Op) {
+  switch (Op) {
+    case UOP_Minus:    return "-";
+    case UOP_BitNot:   return "~";
+    case UOP_LogicNot: return "!";
+  }
+  return "";
+}
+
+
+StringRef getBinaryOpcodeString(TIL_BinaryOpcode Op) {
+  switch (Op) {
+    case BOP_Mul:      return "*";
+    case BOP_Div:      return "/";
+    case BOP_Rem:      return "%";
+    case BOP_Add:      return "+";
+    case BOP_Sub:      return "-";
+    case BOP_Shl:      return "<<";
+    case BOP_Shr:      return ">>";
+    case BOP_BitAnd:   return "&";
+    case BOP_BitXor:   return "^";
+    case BOP_BitOr:    return "|";
+    case BOP_Eq:       return "==";
+    case BOP_Neq:      return "!=";
+    case BOP_Lt:       return "<";
+    case BOP_Leq:      return "<=";
+    case BOP_LogicAnd: return "&&";
+    case BOP_LogicOr:  return "||";
+  }
+  return "";
+}
+
+
+unsigned BasicBlock::addPredecessor(BasicBlock *Pred) {
+  unsigned Idx = Predecessors.size();
+  Predecessors.reserveCheck(1, Arena);
+  Predecessors.push_back(Pred);
+  for (Variable *V : Args) {
+    if (Phi* Ph = dyn_cast<Phi>(V->definition())) {
+      Ph->values().reserveCheck(1, Arena);
+      Ph->values().push_back(nullptr);
+    }
+  }
+  return Idx;
+}
+
+void BasicBlock::reservePredecessors(unsigned NumPreds) {
+  Predecessors.reserve(NumPreds, Arena);
+  for (Variable *V : Args) {
+    if (Phi* Ph = dyn_cast<Phi>(V->definition())) {
+      Ph->values().reserve(NumPreds, Arena);
+    }
+  }
+}
+
+void BasicBlock::renumberVars() {
+  unsigned VID = 0;
+  for (Variable *V : Args) {
+    V->setID(BlockID, VID++);
+  }
+  for (Variable *V : Instrs) {
+    V->setID(BlockID, VID++);
+  }
+}
+
+void SCFG::renumberVars() {
+  for (BasicBlock *B : Blocks) {
+    B->renumberVars();
+  }
+}
+
+
+
+
+// If E is a variable, then trace back through any aliases or redundant
+// Phi nodes to find the canonical definition.
+SExpr *getCanonicalVal(SExpr *E) {
+  while (auto *V = dyn_cast<Variable>(E)) {
+    SExpr *D;
+    do {
+      if (V->kind() != Variable::VK_Let)
+        return V;
+      D = V->definition();
+      auto *V2 = dyn_cast<Variable>(D);
+      if (V2)
+        V = V2;
+      else
+        break;
+    } while (true);
+
+    if (ThreadSafetyTIL::isTrivial(D))
+      return D;
+
+    if (Phi *Ph = dyn_cast<Phi>(D)) {
+      if (Ph->status() == Phi::PH_Incomplete)
+        simplifyIncompleteArg(V, Ph);
+
+      if (Ph->status() == Phi::PH_SingleVal) {
+        E = Ph->values()[0];
+        continue;
+      }
+    }
+    return V;
+  }
+  return E;
+}
+
+
+// Trace the arguments of an incomplete Phi node to see if they have the same
+// canonical definition.  If so, mark the Phi node as redundant.
+// getCanonicalVal() will recursively call simplifyIncompletePhi().
+void simplifyIncompleteArg(Variable *V, til::Phi *Ph) {
+  assert(Ph && Ph->status() == Phi::PH_Incomplete);
+
+  // eliminate infinite recursion -- assume that this node is not redundant.
+  Ph->setStatus(Phi::PH_MultiVal);
+
+  SExpr *E0 = getCanonicalVal(Ph->values()[0]);
+  for (unsigned i=1, n=Ph->values().size(); i<n; ++i) {
+    SExpr *Ei = getCanonicalVal(Ph->values()[i]);
+    if (Ei == V)
+      continue;  // Recursive reference to itself.  Don't count.
+    if (Ei != E0) {
+      return;    // Status is already set to MultiVal.
+    }
+  }
+  Ph->setStatus(Phi::PH_SingleVal);
+  // Eliminate Redundant Phi node.
+  V->setDefinition(Ph->values()[0]);
+}
+
+
+}  // end namespace til
+}  // end namespace threadSafety
+}  // end namespace clang
+
diff --git a/lib/Analysis/UninitializedValues.cpp b/lib/Analysis/UninitializedValues.cpp
index 332c02c..f5c786a 100644
--- a/lib/Analysis/UninitializedValues.cpp
+++ b/lib/Analysis/UninitializedValues.cpp
@@ -34,7 +34,7 @@
 
 static bool isTrackedVar(const VarDecl *vd, const DeclContext *dc) {
   if (vd->isLocalVarDecl() && !vd->hasGlobalStorage() &&
-      !vd->isExceptionVariable() &&
+      !vd->isExceptionVariable() && !vd->isInitCapture() &&
       vd->getDeclContext() == dc) {
     QualType ty = vd->getType();
     return ty->isScalarType() || ty->isVectorType();
@@ -236,7 +236,7 @@
 }
 
 const CFGBlock *DataflowWorklist::dequeue() {
-  const CFGBlock *B = 0;
+  const CFGBlock *B = nullptr;
 
   // First dequeue from the worklist.  This can represent
   // updates along backedges that we want propagated as quickly as possible.
@@ -250,7 +250,7 @@
     ++PO_I;
   }
   else {
-    return 0;
+    return nullptr;
   }
 
   assert(enqueuedBlocks[B->getBlockID()] == true);
@@ -295,7 +295,7 @@
     if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl()))
       if (isTrackedVar(VD, DC))
         return FindVarResult(VD, DRE);
-  return FindVarResult(0, 0);
+  return FindVarResult(nullptr, nullptr);
 }
 
 /// \brief Classify each DeclRefExpr as an initialization or a use. Any
@@ -353,7 +353,7 @@
     if (DRE && DRE->getDecl() == VD)
       return DRE;
   }
-  return 0;
+  return nullptr;
 }
 
 void ClassifyRefs::classify(const Expr *E, Class C) {
@@ -373,9 +373,8 @@
 }
 
 void ClassifyRefs::VisitDeclStmt(DeclStmt *DS) {
-  for (DeclStmt::decl_iterator DI = DS->decl_begin(), DE = DS->decl_end();
-       DI != DE; ++DI) {
-    VarDecl *VD = dyn_cast<VarDecl>(*DI);
+  for (auto *DI : DS->decls()) {
+    VarDecl *VD = dyn_cast<VarDecl>(DI);
     if (VD && isTrackedVar(VD))
       if (const DeclRefExpr *DRE = getSelfInitExpr(VD))
         Classification[DRE] = SelfInit;
@@ -535,12 +534,15 @@
       for (CFGBlock::const_pred_iterator I = B->pred_begin(), E = B->pred_end();
            I != E; ++I) {
         const CFGBlock *Pred = *I;
+        if (!Pred)
+          continue;
+        
         Value AtPredExit = vals.getValue(Pred, B, vd);
         if (AtPredExit == Initialized)
           // This block initializes the variable.
           continue;
         if (AtPredExit == MayUninitialized &&
-            vals.getValue(B, 0, vd) == Uninitialized) {
+            vals.getValue(B, nullptr, vd) == Uninitialized) {
           // This block declares the variable (uninitialized), and is reachable
           // from a block that initializes the variable. We can't guarantee to
           // give an earlier location for the diagnostic (and it appears that
@@ -630,12 +632,11 @@
 
 void TransferFunctions::VisitBlockExpr(BlockExpr *be) {
   const BlockDecl *bd = be->getBlockDecl();
-  for (BlockDecl::capture_const_iterator i = bd->capture_begin(),
-        e = bd->capture_end() ; i != e; ++i) {
-    const VarDecl *vd = i->getVariable();
+  for (const auto &I : bd->captures()) {
+    const VarDecl *vd = I.getVariable();
     if (!isTrackedVar(vd))
       continue;
-    if (i->isByRef()) {
+    if (I.isByRef()) {
       vals[vd] = Initialized;
       continue;
     }
@@ -691,9 +692,8 @@
 }
 
 void TransferFunctions::VisitDeclStmt(DeclStmt *DS) {
-  for (DeclStmt::decl_iterator DI = DS->decl_begin(), DE = DS->decl_end();
-       DI != DE; ++DI) {
-    VarDecl *VD = dyn_cast<VarDecl>(*DI);
+  for (auto *DI : DS->decls()) {
+    VarDecl *VD = dyn_cast<VarDecl>(DI);
     if (VD && isTrackedVar(VD)) {
       if (getSelfInitExpr(VD)) {
         // If the initializer consists solely of a reference to itself, we
@@ -751,6 +751,8 @@
   for (CFGBlock::const_pred_iterator I = block->pred_begin(),
        E = block->pred_end(); I != E; ++I) {
     const CFGBlock *pred = *I;
+    if (!pred)
+      continue;
     if (wasAnalyzed[pred->getBlockID()]) {
       vals.mergeIntoScratch(vals.getValueVector(pred), isFirst);
       isFirst = false;
@@ -787,8 +789,8 @@
   /// The current block to scribble use information.
   unsigned currentBlock;
 
-  virtual void handleUseOfUninitVariable(const VarDecl *vd,
-                                         const UninitUse &use) {
+  void handleUseOfUninitVariable(const VarDecl *vd,
+                                 const UninitUse &use) override {
     hadUse[currentBlock] = true;
     hadAnyUse = true;
   }
@@ -796,7 +798,7 @@
   /// Called when the uninitialized variable analysis detects the
   /// idiom 'int x = x'.  All other uses of 'x' within the initializer
   /// are handled by handleUseOfUninitVariable.
-  virtual void handleSelfInit(const VarDecl *vd) {
+  void handleSelfInit(const VarDecl *vd) override {
     hadUse[currentBlock] = true;
     hadAnyUse = true;
   }
diff --git a/lib/Basic/Attributes.cpp b/lib/Basic/Attributes.cpp
new file mode 100644
index 0000000..a05ad05
--- /dev/null
+++ b/lib/Basic/Attributes.cpp
@@ -0,0 +1,17 @@
+#include "clang/Basic/Attributes.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "llvm/ADT/StringSwitch.h"
+using namespace clang;
+
+bool clang::hasAttribute(AttrSyntax Syntax, const IdentifierInfo *Scope,
+                         const IdentifierInfo *Attr, const llvm::Triple &T,
+                         const LangOptions &LangOpts) {
+  StringRef Name = Attr->getName();
+  // Normalize the attribute name, __foo__ becomes foo.
+  if (Name.size() >= 4 && Name.startswith("__") && Name.endswith("__"))
+    Name = Name.substr(2, Name.size() - 4);
+
+#include "clang/Basic/AttrHasAttributeImpl.inc"
+
+  return false;
+}
diff --git a/lib/Basic/Builtins.cpp b/lib/Basic/Builtins.cpp
index c84dd6d..8efcac6 100644
--- a/lib/Basic/Builtins.cpp
+++ b/lib/Basic/Builtins.cpp
@@ -20,7 +20,7 @@
 using namespace clang;
 
 static const Builtin::Info BuiltinInfo[] = {
-  { "not a builtin function", 0, 0, 0, ALL_LANGUAGES },
+  { "not a builtin function", nullptr, nullptr, nullptr, ALL_LANGUAGES},
 #define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
 #define LANGBUILTIN(ID, TYPE, ATTRS, BUILTIN_LANG) { #ID, TYPE, ATTRS, 0, BUILTIN_LANG },
 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER, BUILTIN_LANG) { #ID, TYPE, ATTRS, HEADER,\
@@ -37,7 +37,7 @@
 
 Builtin::Context::Context() {
   // Get the target specific builtins from the target.
-  TSRecords = 0;
+  TSRecords = nullptr;
   NumTSRecords = 0;
 }
 
@@ -76,7 +76,7 @@
 
   // Step #2: Register target-specific builtins.
   for (unsigned i = 0, e = NumTSRecords; i != e; ++i)
-    if (!LangOpts.NoBuiltin || !strchr(TSRecords[i].Attributes, 'f'))
+    if (BuiltinIsSupported(TSRecords[i], LangOpts))
       Table.get(TSRecords[i].Name).setBuiltinID(i+Builtin::FirstTSBuiltin);
 }
 
@@ -97,40 +97,35 @@
   Table.get(GetRecord(ID).Name).setBuiltinID(0);
 }
 
-bool
-Builtin::Context::isPrintfLike(unsigned ID, unsigned &FormatIdx,
-                               bool &HasVAListArg) {
-  const char *Printf = strpbrk(GetRecord(ID).Attributes, "pP");
-  if (!Printf)
+bool Builtin::Context::isLike(unsigned ID, unsigned &FormatIdx,
+                              bool &HasVAListArg, const char *Fmt) const {
+  assert(Fmt && "Not passed a format string");
+  assert(::strlen(Fmt) == 2 &&
+         "Format string needs to be two characters long");
+  assert(::toupper(Fmt[0]) == Fmt[1] &&
+         "Format string is not in the form \"xX\"");
+
+  const char *Like = ::strpbrk(GetRecord(ID).Attributes, Fmt);
+  if (!Like)
     return false;
 
-  HasVAListArg = (*Printf == 'P');
+  HasVAListArg = (*Like == Fmt[1]);
 
-  ++Printf;
-  assert(*Printf == ':' && "p or P specifier must have be followed by a ':'");
-  ++Printf;
+  ++Like;
+  assert(*Like == ':' && "Format specifier must be followed by a ':'");
+  ++Like;
 
-  assert(strchr(Printf, ':') && "printf specifier must end with a ':'");
-  FormatIdx = strtol(Printf, 0, 10);
+  assert(::strchr(Like, ':') && "Format specifier must end with a ':'");
+  FormatIdx = ::strtol(Like, nullptr, 10);
   return true;
 }
 
-// FIXME: Refactor with isPrintfLike.
-bool
-Builtin::Context::isScanfLike(unsigned ID, unsigned &FormatIdx,
-                              bool &HasVAListArg) {
-  const char *Scanf = strpbrk(GetRecord(ID).Attributes, "sS");
-  if (!Scanf)
-    return false;
-
-  HasVAListArg = (*Scanf == 'S');
-
-  ++Scanf;
-  assert(*Scanf == ':' && "s or S specifier must have be followed by a ':'");
-  ++Scanf;
-
-  assert(strchr(Scanf, ':') && "printf specifier must end with a ':'");
-  FormatIdx = strtol(Scanf, 0, 10);
-  return true;
+bool Builtin::Context::isPrintfLike(unsigned ID, unsigned &FormatIdx,
+                                    bool &HasVAListArg) {
+  return isLike(ID, FormatIdx, HasVAListArg, "pP");
 }
 
+bool Builtin::Context::isScanfLike(unsigned ID, unsigned &FormatIdx,
+                                   bool &HasVAListArg) {
+  return isLike(ID, FormatIdx, HasVAListArg, "sS");
+}
diff --git a/lib/Basic/CMakeLists.txt b/lib/Basic/CMakeLists.txt
index 3411169..0df82b3 100644
--- a/lib/Basic/CMakeLists.txt
+++ b/lib/Basic/CMakeLists.txt
@@ -1,6 +1,10 @@
-set(LLVM_LINK_COMPONENTS mc)
+set(LLVM_LINK_COMPONENTS
+  MC
+  Support
+  )
 
 add_clang_library(clangBasic
+  Attributes.cpp
   Builtins.cpp
   CharInfo.cpp
   Diagnostic.cpp
@@ -20,6 +24,8 @@
   TokenKinds.cpp
   Version.cpp
   VersionTuple.cpp
+  VirtualFileSystem.cpp
+  Warnings.cpp
   )
 
 # Determine Subversion revision.
@@ -29,17 +35,15 @@
   find_package(Subversion)
 endif()
 if (Subversion_FOUND AND EXISTS "${CLANG_SOURCE_DIR}/.svn")
-  # Create custom target to generate the Subversion version include.
-  add_custom_target(clang_revision_tag  ALL
-    COMMAND ${CMAKE_COMMAND} -DFIRST_SOURCE_DIR=${LLVM_MAIN_SRC_DIR}
-                             -DFIRST_REPOSITORY=LLVM_REPOSITORY
-                             -DSECOND_SOURCE_DIR=${CLANG_SOURCE_DIR}
-                             -DSECOND_REPOSITORY=SVN_REPOSITORY
-                             -DHEADER_FILE=${CMAKE_CURRENT_BINARY_DIR}/SVNVersion.inc
-   -P ${LLVM_MAIN_SRC_DIR}/cmake/modules/GetSVN.cmake)
+  set(FIRST_SOURCE_DIR ${LLVM_MAIN_SRC_DIR})
+  set(FIRST_REPOSITORY LLVM_REPOSITORY)
+  set(SECOND_SOURCE_DIR ${CLANG_SOURCE_DIR})
+  set(SECOND_REPOSITORY SVN_REPOSITORY)
+  set(HEADER_FILE ${CMAKE_CURRENT_BINARY_DIR}/SVNVersion.inc)
+  include(GetSVN)
 
   # Mark the generated header as being generated.
-message(STATUS "Expecting header to go in ${CMAKE_CURRENT_BINARY_DIR}/SVNVersion.inc")
+  message(STATUS "Expecting header to go in ${CMAKE_CURRENT_BINARY_DIR}/SVNVersion.inc")
   set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/SVNVersion.inc
     PROPERTIES GENERATED TRUE
                HEADER_FILE_ONLY TRUE)
@@ -49,25 +53,3 @@
     PROPERTIES COMPILE_DEFINITIONS "HAVE_SVN_VERSION_INC")
 
 endif()
-
-add_dependencies(clangBasic
-  ClangARMNeon
-  ClangAttrList
-  ClangDiagnosticAnalysis
-  ClangDiagnosticAST
-  ClangDiagnosticComment
-  ClangDiagnosticCommon
-  ClangDiagnosticDriver
-  ClangDiagnosticFrontend
-  ClangDiagnosticGroups
-  ClangDiagnosticIndexName
-  ClangDiagnosticLex
-  ClangDiagnosticParse
-  ClangDiagnosticSema
-  ClangDiagnosticSerialization
-  )
-
-# clangBasic depends on the version.
-if (Subversion_FOUND AND EXISTS "${CLANG_SOURCE_DIR}/.svn")
-  add_dependencies(clangBasic clang_revision_tag)
-endif()
\ No newline at end of file
diff --git a/lib/Basic/Diagnostic.cpp b/lib/Basic/Diagnostic.cpp
index 45d4b53..4567e32 100644
--- a/lib/Basic/Diagnostic.cpp
+++ b/lib/Basic/Diagnostic.cpp
@@ -24,15 +24,13 @@
 using namespace clang;
 
 static void DummyArgToStringFn(DiagnosticsEngine::ArgumentKind AK, intptr_t QT,
-                               const char *Modifier, unsigned ML,
-                               const char *Argument, unsigned ArgLen,
-                               const DiagnosticsEngine::ArgumentValue *PrevArgs,
-                               unsigned NumPrevArgs,
-                               SmallVectorImpl<char> &Output,
-                               void *Cookie,
-                               ArrayRef<intptr_t> QualTypeVals) {
-  const char *Str = "<can't format argument>";
-  Output.append(Str, Str+strlen(Str));
+                            StringRef Modifier, StringRef Argument,
+                            ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs,
+                            SmallVectorImpl<char> &Output,
+                            void *Cookie,
+                            ArrayRef<intptr_t> QualTypeVals) {
+  StringRef Str = "<can't format argument>";
+  Output.append(Str.begin(), Str.end());
 }
 
 
@@ -41,9 +39,9 @@
                        DiagnosticOptions *DiagOpts,       
                        DiagnosticConsumer *client, bool ShouldOwnClient)
   : Diags(diags), DiagOpts(DiagOpts), Client(client),
-    OwnsDiagClient(ShouldOwnClient), SourceMgr(0) {
+    OwnsDiagClient(ShouldOwnClient), SourceMgr(nullptr) {
   ArgToStringFn = DummyArgToStringFn;
-  ArgToStringCookie = 0;
+  ArgToStringCookie = nullptr;
 
   AllExtensionsSilenced = 0;
   IgnoreAllWarnings = false;
@@ -56,7 +54,7 @@
   PrintTemplateTree = false;
   ShowColors = false;
   ShowOverloads = Ovl_All;
-  ExtBehavior = Ext_Ignore;
+  ExtBehavior = diag::Severity::Ignored;
 
   ErrorLimit = 0;
   TemplateBacktraceLimit = 0;
@@ -157,17 +155,17 @@
   if (LastStateChangePos.isValid() &&
       Loc.isBeforeInTranslationUnitThan(LastStateChangePos))
     Pos = std::upper_bound(DiagStatePoints.begin(), DiagStatePoints.end(),
-                           DiagStatePoint(0, Loc));
+                           DiagStatePoint(nullptr, Loc));
   --Pos;
   return Pos;
 }
 
-void DiagnosticsEngine::setDiagnosticMapping(diag::kind Diag, diag::Mapping Map,
-                                             SourceLocation L) {
+void DiagnosticsEngine::setSeverity(diag::kind Diag, diag::Severity Map,
+                                    SourceLocation L) {
   assert(Diag < diag::DIAG_UPPER_LIMIT &&
          "Can only map builtin diagnostics");
   assert((Diags->isBuiltinWarningOrExtension(Diag) ||
-          (Map == diag::MAP_FATAL || Map == diag::MAP_ERROR)) &&
+          (Map == diag::Severity::Fatal || Map == diag::Severity::Error)) &&
          "Cannot map errors into warnings!");
   assert(!DiagStatePoints.empty());
   assert((L.isInvalid() || SourceMgr) && "No SourceMgr for valid location");
@@ -175,17 +173,17 @@
   FullSourceLoc Loc = SourceMgr? FullSourceLoc(L, *SourceMgr) : FullSourceLoc();
   FullSourceLoc LastStateChangePos = DiagStatePoints.back().Loc;
   // Don't allow a mapping to a warning override an error/fatal mapping.
-  if (Map == diag::MAP_WARNING) {
-    DiagnosticMappingInfo &Info = GetCurDiagState()->getOrAddMappingInfo(Diag);
-    if (Info.getMapping() == diag::MAP_ERROR ||
-        Info.getMapping() == diag::MAP_FATAL)
-      Map = Info.getMapping();
+  if (Map == diag::Severity::Warning) {
+    DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(Diag);
+    if (Info.getSeverity() == diag::Severity::Error ||
+        Info.getSeverity() == diag::Severity::Fatal)
+      Map = Info.getSeverity();
   }
-  DiagnosticMappingInfo MappingInfo = makeMappingInfo(Map, L);
+  DiagnosticMapping Mapping = makeUserMapping(Map, L);
 
   // Common case; setting all the diagnostics of a group in one place.
   if (Loc.isInvalid() || Loc == LastStateChangePos) {
-    GetCurDiagState()->setMappingInfo(Diag, MappingInfo);
+    GetCurDiagState()->setMapping(Diag, Mapping);
     return;
   }
 
@@ -198,7 +196,7 @@
     // the new state became active.
     DiagStates.push_back(*GetCurDiagState());
     PushDiagStatePoint(&DiagStates.back(), Loc);
-    GetCurDiagState()->setMappingInfo(Diag, MappingInfo);
+    GetCurDiagState()->setMapping(Diag, Mapping);
     return;
   }
 
@@ -211,81 +209,64 @@
   // Update all diagnostic states that are active after the given location.
   for (DiagStatePointsTy::iterator
          I = Pos+1, E = DiagStatePoints.end(); I != E; ++I) {
-    GetCurDiagState()->setMappingInfo(Diag, MappingInfo);
+    GetCurDiagState()->setMapping(Diag, Mapping);
   }
 
   // If the location corresponds to an existing point, just update its state.
   if (Pos->Loc == Loc) {
-    GetCurDiagState()->setMappingInfo(Diag, MappingInfo);
+    GetCurDiagState()->setMapping(Diag, Mapping);
     return;
   }
 
   // Create a new state/point and fit it into the vector of DiagStatePoints
   // so that the vector is always ordered according to location.
-  Pos->Loc.isBeforeInTranslationUnitThan(Loc);
+  assert(Pos->Loc.isBeforeInTranslationUnitThan(Loc));
   DiagStates.push_back(*Pos->State);
   DiagState *NewState = &DiagStates.back();
-  GetCurDiagState()->setMappingInfo(Diag, MappingInfo);
+  GetCurDiagState()->setMapping(Diag, Mapping);
   DiagStatePoints.insert(Pos+1, DiagStatePoint(NewState,
                                                FullSourceLoc(Loc, *SourceMgr)));
 }
 
-bool DiagnosticsEngine::setDiagnosticGroupMapping(
-  StringRef Group, diag::Mapping Map, SourceLocation Loc)
-{
+bool DiagnosticsEngine::setSeverityForGroup(diag::Flavor Flavor,
+                                            StringRef Group, diag::Severity Map,
+                                            SourceLocation Loc) {
   // Get the diagnostics in this group.
   SmallVector<diag::kind, 8> GroupDiags;
-  if (Diags->getDiagnosticsInGroup(Group, GroupDiags))
+  if (Diags->getDiagnosticsInGroup(Flavor, Group, GroupDiags))
     return true;
 
   // Set the mapping.
   for (unsigned i = 0, e = GroupDiags.size(); i != e; ++i)
-    setDiagnosticMapping(GroupDiags[i], Map, Loc);
+    setSeverity(GroupDiags[i], Map, Loc);
 
   return false;
 }
 
-void DiagnosticsEngine::setDiagnosticWarningAsError(diag::kind Diag,
-                                                    bool Enabled) {
-  // If we are enabling this feature, just set the diagnostic mappings to map to
-  // errors.
-  if (Enabled) 
-    setDiagnosticMapping(Diag, diag::MAP_ERROR, SourceLocation());
-
-  // Otherwise, we want to set the diagnostic mapping's "no Werror" bit, and
-  // potentially downgrade anything already mapped to be a warning.
-  DiagnosticMappingInfo &Info = GetCurDiagState()->getOrAddMappingInfo(Diag);
-
-  if (Info.getMapping() == diag::MAP_ERROR ||
-      Info.getMapping() == diag::MAP_FATAL)
-    Info.setMapping(diag::MAP_WARNING);
-
-  Info.setNoWarningAsError(true);
-}
-
 bool DiagnosticsEngine::setDiagnosticGroupWarningAsError(StringRef Group,
                                                          bool Enabled) {
   // If we are enabling this feature, just set the diagnostic mappings to map to
   // errors.
   if (Enabled)
-    return setDiagnosticGroupMapping(Group, diag::MAP_ERROR);
+    return setSeverityForGroup(diag::Flavor::WarningOrError, Group,
+                               diag::Severity::Error);
 
   // Otherwise, we want to set the diagnostic mapping's "no Werror" bit, and
   // potentially downgrade anything already mapped to be a warning.
 
   // Get the diagnostics in this group.
   SmallVector<diag::kind, 8> GroupDiags;
-  if (Diags->getDiagnosticsInGroup(Group, GroupDiags))
+  if (Diags->getDiagnosticsInGroup(diag::Flavor::WarningOrError, Group,
+                                   GroupDiags))
     return true;
 
   // Perform the mapping change.
   for (unsigned i = 0, e = GroupDiags.size(); i != e; ++i) {
-    DiagnosticMappingInfo &Info = GetCurDiagState()->getOrAddMappingInfo(
-      GroupDiags[i]);
+    DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(GroupDiags[i]);
 
-    if (Info.getMapping() == diag::MAP_ERROR ||
-        Info.getMapping() == diag::MAP_FATAL)
-      Info.setMapping(diag::MAP_WARNING);
+    if (Info.getSeverity() == diag::Severity::Error ||
+        Info.getSeverity() == diag::Severity::Fatal)
+      Info.setSeverity(diag::Severity::Warning);
 
     Info.setNoWarningAsError(true);
   }
@@ -293,45 +274,29 @@
   return false;
 }
 
-void DiagnosticsEngine::setDiagnosticErrorAsFatal(diag::kind Diag,
-                                                  bool Enabled) {
-  // If we are enabling this feature, just set the diagnostic mappings to map to
-  // errors.
-  if (Enabled)
-    setDiagnosticMapping(Diag, diag::MAP_FATAL, SourceLocation());
-  
-  // Otherwise, we want to set the diagnostic mapping's "no Werror" bit, and
-  // potentially downgrade anything already mapped to be a warning.
-  DiagnosticMappingInfo &Info = GetCurDiagState()->getOrAddMappingInfo(Diag);
-  
-  if (Info.getMapping() == diag::MAP_FATAL)
-    Info.setMapping(diag::MAP_ERROR);
-  
-  Info.setNoErrorAsFatal(true);
-}
-
 bool DiagnosticsEngine::setDiagnosticGroupErrorAsFatal(StringRef Group,
                                                        bool Enabled) {
   // If we are enabling this feature, just set the diagnostic mappings to map to
   // fatal errors.
   if (Enabled)
-    return setDiagnosticGroupMapping(Group, diag::MAP_FATAL);
+    return setSeverityForGroup(diag::Flavor::WarningOrError, Group,
+                               diag::Severity::Fatal);
 
   // Otherwise, we want to set the diagnostic mapping's "no Werror" bit, and
   // potentially downgrade anything already mapped to be an error.
 
   // Get the diagnostics in this group.
   SmallVector<diag::kind, 8> GroupDiags;
-  if (Diags->getDiagnosticsInGroup(Group, GroupDiags))
+  if (Diags->getDiagnosticsInGroup(diag::Flavor::WarningOrError, Group,
+                                   GroupDiags))
     return true;
 
   // Perform the mapping change.
   for (unsigned i = 0, e = GroupDiags.size(); i != e; ++i) {
-    DiagnosticMappingInfo &Info = GetCurDiagState()->getOrAddMappingInfo(
-      GroupDiags[i]);
+    DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(GroupDiags[i]);
 
-    if (Info.getMapping() == diag::MAP_FATAL)
-      Info.setMapping(diag::MAP_ERROR);
+    if (Info.getSeverity() == diag::Severity::Fatal)
+      Info.setSeverity(diag::Severity::Error);
 
     Info.setNoErrorAsFatal(true);
   }
@@ -339,16 +304,17 @@
   return false;
 }
 
-void DiagnosticsEngine::setMappingToAllDiagnostics(diag::Mapping Map,
-                                                   SourceLocation Loc) {
+void DiagnosticsEngine::setSeverityForAll(diag::Flavor Flavor,
+                                          diag::Severity Map,
+                                          SourceLocation Loc) {
   // Get all the diagnostics.
   SmallVector<diag::kind, 64> AllDiags;
-  Diags->getAllDiagnostics(AllDiags);
+  Diags->getAllDiagnostics(Flavor, AllDiags);
 
   // Set the mapping.
   for (unsigned i = 0, e = AllDiags.size(); i != e; ++i)
     if (Diags->isBuiltinWarningOrExtension(AllDiags[i]))
-      setDiagnosticMapping(AllDiags[i], Map, Loc);
+      setSeverity(AllDiags[i], Map, Loc);
 }
 
 void DiagnosticsEngine::Report(const StoredDiagnostic &storedDiag) {
@@ -358,22 +324,19 @@
   CurDiagID = storedDiag.getID();
   NumDiagArgs = 0;
 
-  NumDiagRanges = storedDiag.range_size();
-  assert(NumDiagRanges < DiagnosticsEngine::MaxRanges &&
-         "Too many arguments to diagnostic!");
-  unsigned i = 0;
+  DiagRanges.clear();
+  DiagRanges.reserve(storedDiag.range_size());
   for (StoredDiagnostic::range_iterator
          RI = storedDiag.range_begin(),
          RE = storedDiag.range_end(); RI != RE; ++RI)
-    DiagRanges[i++] = *RI;
+    DiagRanges.push_back(*RI);
 
-  assert(NumDiagRanges < DiagnosticsEngine::MaxFixItHints &&
-         "Too many arguments to diagnostic!");
-  NumDiagFixItHints = 0;
+  DiagFixItHints.clear();
+  DiagFixItHints.reserve(storedDiag.fixit_size());
   for (StoredDiagnostic::fixit_iterator
          FI = storedDiag.fixit_begin(),
          FE = storedDiag.fixit_end(); FI != FE; ++FI)
-    DiagFixItHints[NumDiagFixItHints++] = *FI;
+    DiagFixItHints.push_back(*FI);
 
   assert(Client && "DiagnosticConsumer not set!");
   Level DiagLevel = storedDiag.getLevel();
@@ -639,6 +602,17 @@
   }
 }
 
+/// \brief Returns the friendly description for a token kind that will appear
+/// without quotes in diagnostic messages. These strings may be translatable in
+/// future.
+static const char *getTokenDescForDiagnostic(tok::TokenKind Kind) {
+  switch (Kind) {
+  case tok::identifier:
+    return "identifier";
+  default:
+    return nullptr;
+  }
+}
 
 /// FormatDiagnostic - Format this diagnostic into a string, substituting the
 /// formal arguments into the %0 slots.  The result is appended onto the Str
@@ -696,7 +670,7 @@
     // The digit is a number from 0-9 indicating which argument this comes from.
     // The modifier is a string of digits from the set [-a-z]+, arguments is a
     // brace enclosed string.
-    const char *Modifier = 0, *Argument = 0;
+    const char *Modifier = nullptr, *Argument = nullptr;
     unsigned ModifierLen = 0, ArgumentLen = 0;
 
     // Check to see if we have a modifier.  If so eat it.
@@ -812,6 +786,28 @@
       }
       break;
     }
+    // ---- TOKEN SPELLINGS ----
+    case DiagnosticsEngine::ak_tokenkind: {
+      tok::TokenKind Kind = static_cast<tok::TokenKind>(getRawArg(ArgNo));
+      assert(ModifierLen == 0 && "No modifiers for token kinds yet");
+
+      llvm::raw_svector_ostream Out(OutStr);
+      if (const char *S = tok::getPunctuatorSpelling(Kind))
+        // Quoted token spelling for punctuators.
+        Out << '\'' << S << '\'';
+      else if (const char *S = tok::getKeywordSpelling(Kind))
+        // Unquoted token spelling for keywords.
+        Out << S;
+      else if (const char *S = getTokenDescForDiagnostic(Kind))
+        // Unquoted translatable token name.
+        Out << S;
+      else if (const char *S = tok::getTokenName(Kind))
+        // Debug name, shouldn't appear in user-facing diagnostics.
+        Out << '<' << S << '>';
+      else
+        Out << "(null)";
+      break;
+    }
     // ---- NAMES and TYPES ----
     case DiagnosticsEngine::ak_identifierinfo: {
       const IdentifierInfo *II = getArgIdentifier(ArgNo);
@@ -832,10 +828,11 @@
     case DiagnosticsEngine::ak_nameddecl:
     case DiagnosticsEngine::ak_nestednamespec:
     case DiagnosticsEngine::ak_declcontext:
+    case DiagnosticsEngine::ak_attr:
       getDiags()->ConvertArgToString(Kind, getRawArg(ArgNo),
-                                     Modifier, ModifierLen,
-                                     Argument, ArgumentLen,
-                                     FormattedArgs.data(), FormattedArgs.size(),
+                                     StringRef(Modifier, ModifierLen),
+                                     StringRef(Argument, ArgumentLen),
+                                     FormattedArgs,
                                      OutStr, QualTypeVals);
       break;
     case DiagnosticsEngine::ak_qualtype_pair:
@@ -857,10 +854,9 @@
         TDT.PrintFromType = true;
         TDT.PrintTree = true;
         getDiags()->ConvertArgToString(Kind, val,
-                                       Modifier, ModifierLen,
-                                       Argument, ArgumentLen,
-                                       FormattedArgs.data(),
-                                       FormattedArgs.size(),
+                                       StringRef(Modifier, ModifierLen),
+                                       StringRef(Argument, ArgumentLen),
+                                       FormattedArgs,
                                        Tree, QualTypeVals);
         // If there is no tree information, fall back to regular printing.
         if (!Tree.empty()) {
@@ -881,9 +877,9 @@
       TDT.PrintTree = false;
       TDT.PrintFromType = true;
       getDiags()->ConvertArgToString(Kind, val,
-                                     Modifier, ModifierLen,
-                                     Argument, ArgumentLen,
-                                     FormattedArgs.data(), FormattedArgs.size(),
+                                     StringRef(Modifier, ModifierLen),
+                                     StringRef(Argument, ArgumentLen),
+                                     FormattedArgs,
                                      OutStr, QualTypeVals);
       if (!TDT.TemplateDiffUsed)
         FormattedArgs.push_back(std::make_pair(DiagnosticsEngine::ak_qualtype,
@@ -895,9 +891,9 @@
       // Append second type
       TDT.PrintFromType = false;
       getDiags()->ConvertArgToString(Kind, val,
-                                     Modifier, ModifierLen,
-                                     Argument, ArgumentLen,
-                                     FormattedArgs.data(), FormattedArgs.size(),
+                                     StringRef(Modifier, ModifierLen),
+                                     StringRef(Argument, ArgumentLen),
+                                     FormattedArgs,
                                      OutStr, QualTypeVals);
       if (!TDT.TemplateDiffUsed)
         FormattedArgs.push_back(std::make_pair(DiagnosticsEngine::ak_qualtype,
diff --git a/lib/Basic/DiagnosticIDs.cpp b/lib/Basic/DiagnosticIDs.cpp
index 9d99fbe..ec244cc 100644
--- a/lib/Basic/DiagnosticIDs.cpp
+++ b/lib/Basic/DiagnosticIDs.cpp
@@ -15,8 +15,8 @@
 #include "clang/Basic/AllDiagnostics.h"
 #include "clang/Basic/DiagnosticCategories.h"
 #include "clang/Basic/SourceManager.h"
-#include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/ErrorHandling.h"
 #include <map>
 using namespace clang;
@@ -30,14 +30,15 @@
 // Diagnostic classes.
 enum {
   CLASS_NOTE       = 0x01,
-  CLASS_WARNING    = 0x02,
-  CLASS_EXTENSION  = 0x03,
-  CLASS_ERROR      = 0x04
+  CLASS_REMARK     = 0x02,
+  CLASS_WARNING    = 0x03,
+  CLASS_EXTENSION  = 0x04,
+  CLASS_ERROR      = 0x05
 };
 
 struct StaticDiagInfoRec {
   uint16_t DiagID;
-  unsigned Mapping : 3;
+  unsigned DefaultSeverity : 3;
   unsigned Class : 3;
   unsigned SFINAE : 2;
   unsigned WarnNoWerror : 1;
@@ -57,6 +58,11 @@
     return StringRef(DescriptionStr, DescriptionLen);
   }
 
+  diag::Flavor getFlavor() const {
+    return Class == CLASS_REMARK ? diag::Flavor::Remark
+                                 : diag::Flavor::WarningOrError;
+  }
+
   bool operator<(const StaticDiagInfoRec &RHS) const {
     return DiagID < RHS.DiagID;
   }
@@ -65,12 +71,13 @@
 } // namespace anonymous
 
 static const StaticDiagInfoRec StaticDiagInfo[] = {
-#define DIAG(ENUM,CLASS,DEFAULT_MAPPING,DESC,GROUP,               \
-             SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY)            \
-  { diag::ENUM, DEFAULT_MAPPING, CLASS,                           \
-    DiagnosticIDs::SFINAE,                                        \
-    NOWERROR, SHOWINSYSHEADER, CATEGORY, GROUP,                   \
-    STR_SIZE(DESC, uint16_t), DESC },
+#define DIAG(ENUM, CLASS, DEFAULT_SEVERITY, DESC, GROUP, SFINAE, NOWERROR,     \
+             SHOWINSYSHEADER, CATEGORY)                                        \
+  {                                                                            \
+    diag::ENUM, DEFAULT_SEVERITY, CLASS, DiagnosticIDs::SFINAE, NOWERROR,      \
+        SHOWINSYSHEADER, CATEGORY, GROUP, STR_SIZE(DESC, uint16_t), DESC       \
+  }                                                                            \
+  ,
 #include "clang/Basic/DiagnosticCommonKinds.inc"
 #include "clang/Basic/DiagnosticDriverKinds.inc"
 #include "clang/Basic/DiagnosticFrontendKinds.inc"
@@ -108,10 +115,10 @@
   // Out of bounds diag. Can't be in the table.
   using namespace diag;
   if (DiagID >= DIAG_UPPER_LIMIT || DiagID <= DIAG_START_COMMON)
-    return 0;
+    return nullptr;
 
   // Compute the index of the requested diagnostic in the static table.
-  // 1. Add the number of diagnostics in each category preceeding the
+  // 1. Add the number of diagnostics in each category preceding the
   //    diagnostic and of the category the diagnostic is in. This gives us
   //    the offset of the category in the table.
   // 2. Subtract the number of IDs in each category from our ID. This gives us
@@ -138,7 +145,7 @@
 
   // Avoid out of bounds reads.
   if (ID + Offset >= StaticDiagInfoSize)
-    return 0;
+    return nullptr;
 
   assert(ID < StaticDiagInfoSize && Offset < StaticDiagInfoSize);
 
@@ -147,28 +154,22 @@
   // happen when this function is called with an ID that points into a hole in
   // the diagID space.
   if (Found->DiagID != DiagID)
-    return 0;
+    return nullptr;
   return Found;
 }
 
-static DiagnosticMappingInfo GetDefaultDiagMappingInfo(unsigned DiagID) {
-  DiagnosticMappingInfo Info = DiagnosticMappingInfo::Make(
-    diag::MAP_FATAL, /*IsUser=*/false, /*IsPragma=*/false);
+static DiagnosticMapping GetDefaultDiagMapping(unsigned DiagID) {
+  DiagnosticMapping Info = DiagnosticMapping::Make(
+      diag::Severity::Fatal, /*IsUser=*/false, /*IsPragma=*/false);
 
   if (const StaticDiagInfoRec *StaticInfo = GetDiagInfo(DiagID)) {
-    Info.setMapping((diag::Mapping) StaticInfo->Mapping);
+    Info.setSeverity((diag::Severity)StaticInfo->DefaultSeverity);
 
     if (StaticInfo->WarnNoWerror) {
-      assert(Info.getMapping() == diag::MAP_WARNING &&
+      assert(Info.getSeverity() == diag::Severity::Warning &&
              "Unexpected mapping with no-Werror bit!");
       Info.setNoWarningAsError(true);
     }
-
-    if (StaticInfo->WarnShowInSystemHeader) {
-      assert(Info.getMapping() == diag::MAP_WARNING &&
-             "Unexpected mapping with show-in-system-header bit!");
-      Info.setShowInSystemHeader(true);
-    }
   }
 
   return Info;
@@ -197,15 +198,14 @@
 // Unfortunately, the split between DiagnosticIDs and Diagnostic is not
 // particularly clean, but for now we just implement this method here so we can
 // access GetDefaultDiagMapping.
-DiagnosticMappingInfo &DiagnosticsEngine::DiagState::getOrAddMappingInfo(
-  diag::kind Diag)
-{
-  std::pair<iterator, bool> Result = DiagMap.insert(
-    std::make_pair(Diag, DiagnosticMappingInfo()));
+DiagnosticMapping &
+DiagnosticsEngine::DiagState::getOrAddMapping(diag::kind Diag) {
+  std::pair<iterator, bool> Result =
+      DiagMap.insert(std::make_pair(Diag, DiagnosticMapping()));
 
   // Initialize the entry if we added it.
   if (Result.second)
-    Result.first->second = GetDefaultDiagMappingInfo(Diag);
+    Result.first->second = GetDefaultDiagMapping(Diag);
 
   return Result.first->second;
 }
@@ -215,7 +215,7 @@
 #define CATEGORY(X, ENUM) { X, STR_SIZE(X, uint8_t) },
 #include "clang/Basic/DiagnosticGroups.inc"
 #undef GET_CATEGORY_TABLE
-  { 0, 0 }
+  { nullptr, 0 }
 };
 
 /// getNumberOfCategories - Return the number of categories
@@ -264,14 +264,14 @@
       /// getDescription - Return the description of the specified custom
       /// diagnostic.
       StringRef getDescription(unsigned DiagID) const {
-        assert(this && DiagID-DIAG_UPPER_LIMIT < DiagInfo.size() &&
+        assert(DiagID - DIAG_UPPER_LIMIT < DiagInfo.size() &&
                "Invalid diagnostic ID");
         return DiagInfo[DiagID-DIAG_UPPER_LIMIT].second;
       }
 
       /// getLevel - Return the level of the specified custom diagnostic.
       DiagnosticIDs::Level getLevel(unsigned DiagID) const {
-        assert(this && DiagID-DIAG_UPPER_LIMIT < DiagInfo.size() &&
+        assert(DiagID - DIAG_UPPER_LIMIT < DiagInfo.size() &&
                "Invalid diagnostic ID");
         return DiagInfo[DiagID-DIAG_UPPER_LIMIT].first;
       }
@@ -300,9 +300,7 @@
 // Common Diagnostic implementation
 //===----------------------------------------------------------------------===//
 
-DiagnosticIDs::DiagnosticIDs() {
-  CustomDiagInfo = 0;
-}
+DiagnosticIDs::DiagnosticIDs() { CustomDiagInfo = nullptr; }
 
 DiagnosticIDs::~DiagnosticIDs() {
   delete CustomDiagInfo;
@@ -311,10 +309,13 @@
 /// getCustomDiagID - Return an ID for a diagnostic with the specified message
 /// and level.  If this is the first request for this diagnostic, it is
 /// registered and created, otherwise the existing ID is returned.
-unsigned DiagnosticIDs::getCustomDiagID(Level L, StringRef Message) {
-  if (CustomDiagInfo == 0)
+///
+/// \param FormatString A fixed diagnostic format string that will be hashed and
+/// mapped to a unique DiagID.
+unsigned DiagnosticIDs::getCustomDiagID(Level L, StringRef FormatString) {
+  if (!CustomDiagInfo)
     CustomDiagInfo = new diag::CustomDiagInfo();
-  return CustomDiagInfo->getOrCreateDiagID(L, Message, *this);
+  return CustomDiagInfo->getOrCreateDiagID(L, FormatString, *this);
 }
 
 
@@ -344,9 +345,9 @@
   if (DiagID >= diag::DIAG_UPPER_LIMIT ||
       getBuiltinDiagClass(DiagID) != CLASS_EXTENSION)
     return false;
-  
+
   EnabledByDefault =
-    GetDefaultDiagMappingInfo(DiagID).getMapping() != diag::MAP_IGNORE;
+      GetDefaultDiagMapping(DiagID).getSeverity() != diag::Severity::Ignored;
   return true;
 }
 
@@ -354,7 +355,7 @@
   if (DiagID >= diag::DIAG_UPPER_LIMIT)
     return false;
 
-  return GetDefaultDiagMappingInfo(DiagID).getMapping() == diag::MAP_ERROR;
+  return GetDefaultDiagMapping(DiagID).getSeverity() == diag::Severity::Error;
 }
 
 /// getDescription - Given a diagnostic ID, return a description of the
@@ -362,9 +363,26 @@
 StringRef DiagnosticIDs::getDescription(unsigned DiagID) const {
   if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
     return Info->getDescription();
+  assert(CustomDiagInfo && "Invalid CustomDiagInfo");
   return CustomDiagInfo->getDescription(DiagID);
 }
 
+static DiagnosticIDs::Level toLevel(diag::Severity SV) {
+  switch (SV) {
+  case diag::Severity::Ignored:
+    return DiagnosticIDs::Ignored;
+  case diag::Severity::Remark:
+    return DiagnosticIDs::Remark;
+  case diag::Severity::Warning:
+    return DiagnosticIDs::Warning;
+  case diag::Severity::Error:
+    return DiagnosticIDs::Error;
+  case diag::Severity::Fatal:
+    return DiagnosticIDs::Fatal;
+  }
+  llvm_unreachable("unexpected severity");
+}
+
 /// getDiagnosticLevel - Based on the way the client configured the
 /// DiagnosticsEngine object, classify the specified diagnostic ID into a Level,
 /// by consumable the DiagnosticClient.
@@ -372,12 +390,14 @@
 DiagnosticIDs::getDiagnosticLevel(unsigned DiagID, SourceLocation Loc,
                                   const DiagnosticsEngine &Diag) const {
   // Handle custom diagnostics, which cannot be mapped.
-  if (DiagID >= diag::DIAG_UPPER_LIMIT)
+  if (DiagID >= diag::DIAG_UPPER_LIMIT) {
+    assert(CustomDiagInfo && "Invalid CustomDiagInfo");
     return CustomDiagInfo->getLevel(DiagID);
+  }
 
   unsigned DiagClass = getBuiltinDiagClass(DiagID);
   if (DiagClass == CLASS_NOTE) return DiagnosticIDs::Note;
-  return getDiagnosticLevel(DiagID, DiagClass, Loc, Diag);
+  return toLevel(getDiagnosticSeverity(DiagID, Loc, Diag));
 }
 
 /// \brief Based on the way the client configured the Diagnostic
@@ -386,41 +406,37 @@
 ///
 /// \param Loc The source location we are interested in finding out the
 /// diagnostic state. Can be null in order to query the latest state.
-DiagnosticIDs::Level
-DiagnosticIDs::getDiagnosticLevel(unsigned DiagID, unsigned DiagClass,
-                                  SourceLocation Loc,
-                                  const DiagnosticsEngine &Diag) const {
+diag::Severity
+DiagnosticIDs::getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc,
+                                     const DiagnosticsEngine &Diag) const {
+  assert(getBuiltinDiagClass(DiagID) != CLASS_NOTE);
+
   // Specific non-error diagnostics may be mapped to various levels from ignored
   // to error.  Errors can only be mapped to fatal.
-  DiagnosticIDs::Level Result = DiagnosticIDs::Fatal;
+  diag::Severity Result = diag::Severity::Fatal;
 
   DiagnosticsEngine::DiagStatePointsTy::iterator
     Pos = Diag.GetDiagStatePointForLoc(Loc);
   DiagnosticsEngine::DiagState *State = Pos->State;
 
   // Get the mapping information, or compute it lazily.
-  DiagnosticMappingInfo &MappingInfo = State->getOrAddMappingInfo(
-    (diag::kind)DiagID);
+  DiagnosticMapping &Mapping = State->getOrAddMapping((diag::kind)DiagID);
 
-  switch (MappingInfo.getMapping()) {
-  case diag::MAP_IGNORE:
-    Result = DiagnosticIDs::Ignored;
-    break;
-  case diag::MAP_WARNING:
-    Result = DiagnosticIDs::Warning;
-    break;
-  case diag::MAP_ERROR:
-    Result = DiagnosticIDs::Error;
-    break;
-  case diag::MAP_FATAL:
-    Result = DiagnosticIDs::Fatal;
-    break;
-  }
+  // TODO: Can a null severity really get here?
+  if (Mapping.getSeverity() != diag::Severity())
+    Result = Mapping.getSeverity();
 
   // Upgrade ignored diagnostics if -Weverything is enabled.
-  if (Diag.EnableAllWarnings && Result == DiagnosticIDs::Ignored &&
-      !MappingInfo.isUser())
-    Result = DiagnosticIDs::Warning;
+  if (Diag.EnableAllWarnings && Result == diag::Severity::Ignored &&
+      !Mapping.isUser())
+    Result = diag::Severity::Warning;
+
+  // Diagnostics of class REMARK are either printed as remarks or in case they
+  // have been added to -Werror they are printed as errors.
+  // FIXME: Disregarding user-requested remark mappings like this is bogus.
+  if (Result == diag::Severity::Warning &&
+      getBuiltinDiagClass(DiagID) == CLASS_REMARK)
+    Result = diag::Severity::Remark;
 
   // Ignore -pedantic diagnostics inside __extension__ blocks.
   // (The diagnostics controlled by -pedantic are the extension diagnostics
@@ -428,62 +444,46 @@
   bool EnabledByDefault = false;
   bool IsExtensionDiag = isBuiltinExtensionDiag(DiagID, EnabledByDefault);
   if (Diag.AllExtensionsSilenced && IsExtensionDiag && !EnabledByDefault)
-    return DiagnosticIDs::Ignored;
+    return diag::Severity::Ignored;
 
   // For extension diagnostics that haven't been explicitly mapped, check if we
   // should upgrade the diagnostic.
-  if (IsExtensionDiag && !MappingInfo.isUser()) {
-    switch (Diag.ExtBehavior) {
-    case DiagnosticsEngine::Ext_Ignore:
-      break; 
-    case DiagnosticsEngine::Ext_Warn:
-      // Upgrade ignored diagnostics to warnings.
-      if (Result == DiagnosticIDs::Ignored)
-        Result = DiagnosticIDs::Warning;
-      break;
-    case DiagnosticsEngine::Ext_Error:
-      // Upgrade ignored or warning diagnostics to errors.
-      if (Result == DiagnosticIDs::Ignored || Result == DiagnosticIDs::Warning)
-        Result = DiagnosticIDs::Error;
-      break;
-    }
-  }
+  if (IsExtensionDiag && !Mapping.isUser())
+    Result = std::max(Result, Diag.ExtBehavior);
 
   // At this point, ignored errors can no longer be upgraded.
-  if (Result == DiagnosticIDs::Ignored)
+  if (Result == diag::Severity::Ignored)
     return Result;
 
   // Honor -w, which is lower in priority than pedantic-errors, but higher than
   // -Werror.
-  if (Result == DiagnosticIDs::Warning && Diag.IgnoreAllWarnings)
-    return DiagnosticIDs::Ignored;
+  if (Result == diag::Severity::Warning && Diag.IgnoreAllWarnings)
+    return diag::Severity::Ignored;
 
   // If -Werror is enabled, map warnings to errors unless explicitly disabled.
-  if (Result == DiagnosticIDs::Warning) {
-    if (Diag.WarningsAsErrors && !MappingInfo.hasNoWarningAsError())
-      Result = DiagnosticIDs::Error;
+  if (Result == diag::Severity::Warning) {
+    if (Diag.WarningsAsErrors && !Mapping.hasNoWarningAsError())
+      Result = diag::Severity::Error;
   }
 
   // If -Wfatal-errors is enabled, map errors to fatal unless explicity
   // disabled.
-  if (Result == DiagnosticIDs::Error) {
-    if (Diag.ErrorsAsFatal && !MappingInfo.hasNoErrorAsFatal())
-      Result = DiagnosticIDs::Fatal;
+  if (Result == diag::Severity::Error) {
+    if (Diag.ErrorsAsFatal && !Mapping.hasNoErrorAsFatal())
+      Result = diag::Severity::Fatal;
   }
 
+  // Custom diagnostics always are emitted in system headers.
+  bool ShowInSystemHeader =
+      !GetDiagInfo(DiagID) || GetDiagInfo(DiagID)->WarnShowInSystemHeader;
+
   // If we are in a system header, we ignore it. We look at the diagnostic class
   // because we also want to ignore extensions and warnings in -Werror and
   // -pedantic-errors modes, which *map* warnings/extensions to errors.
-  if (Result >= DiagnosticIDs::Warning &&
-      DiagClass != CLASS_ERROR &&
-      // Custom diagnostics always are emitted in system headers.
-      DiagID < diag::DIAG_UPPER_LIMIT &&
-      !MappingInfo.hasShowInSystemHeader() &&
-      Diag.SuppressSystemWarnings &&
-      Loc.isValid() &&
+  if (Diag.SuppressSystemWarnings && !ShowInSystemHeader && Loc.isValid() &&
       Diag.getSourceManager().isInSystemHeader(
           Diag.getSourceManager().getExpansionLoc(Loc)))
-    return DiagnosticIDs::Ignored;
+    return diag::Severity::Ignored;
 
   return Result;
 }
@@ -527,40 +527,57 @@
   return StringRef();
 }
 
-static void getDiagnosticsInGroup(const WarningOption *Group,
+/// Return \c true if any diagnostics were found in this group, even if they
+/// were filtered out due to having the wrong flavor.
+static bool getDiagnosticsInGroup(diag::Flavor Flavor,
+                                  const WarningOption *Group,
                                   SmallVectorImpl<diag::kind> &Diags) {
+  // An empty group is considered to be a warning group: we have empty groups
+  // for GCC compatibility, and GCC does not have remarks.
+  if (!Group->Members && !Group->SubGroups)
+    return Flavor == diag::Flavor::Remark ? true : false;
+
+  bool NotFound = true;
+
   // Add the members of the option diagnostic set.
   const int16_t *Member = DiagArrays + Group->Members;
-  for (; *Member != -1; ++Member)
-    Diags.push_back(*Member);
+  for (; *Member != -1; ++Member) {
+    if (GetDiagInfo(*Member)->getFlavor() == Flavor) {
+      NotFound = false;
+      Diags.push_back(*Member);
+    }
+  }
 
   // Add the members of the subgroups.
   const int16_t *SubGroups = DiagSubGroups + Group->SubGroups;
   for (; *SubGroups != (int16_t)-1; ++SubGroups)
-    getDiagnosticsInGroup(&OptionTable[(short)*SubGroups], Diags);
+    NotFound &= getDiagnosticsInGroup(Flavor, &OptionTable[(short)*SubGroups],
+                                      Diags);
+
+  return NotFound;
 }
 
-bool DiagnosticIDs::getDiagnosticsInGroup(
-    StringRef Group,
-    SmallVectorImpl<diag::kind> &Diags) const {
-  const WarningOption *Found =
-  std::lower_bound(OptionTable, OptionTable + OptionTableSize, Group,
-                   WarningOptionCompare);
+bool
+DiagnosticIDs::getDiagnosticsInGroup(diag::Flavor Flavor, StringRef Group,
+                                     SmallVectorImpl<diag::kind> &Diags) const {
+  const WarningOption *Found = std::lower_bound(
+      OptionTable, OptionTable + OptionTableSize, Group, WarningOptionCompare);
   if (Found == OptionTable + OptionTableSize ||
       Found->getName() != Group)
     return true; // Option not found.
 
-  ::getDiagnosticsInGroup(Found, Diags);
-  return false;
+  return ::getDiagnosticsInGroup(Flavor, Found, Diags);
 }
 
-void DiagnosticIDs::getAllDiagnostics(
-                               SmallVectorImpl<diag::kind> &Diags) const {
+void DiagnosticIDs::getAllDiagnostics(diag::Flavor Flavor,
+                                     SmallVectorImpl<diag::kind> &Diags) const {
   for (unsigned i = 0; i != StaticDiagInfoSize; ++i)
-    Diags.push_back(StaticDiagInfo[i].DiagID);
+    if (StaticDiagInfo[i].getFlavor() == Flavor)
+      Diags.push_back(StaticDiagInfo[i].DiagID);
 }
 
-StringRef DiagnosticIDs::getNearestWarningOption(StringRef Group) {
+StringRef DiagnosticIDs::getNearestOption(diag::Flavor Flavor,
+                                          StringRef Group) {
   StringRef Best;
   unsigned BestDistance = Group.size() + 1; // Sanity threshold.
   for (const WarningOption *i = OptionTable, *e = OptionTable + OptionTableSize;
@@ -570,6 +587,14 @@
       continue;
 
     unsigned Distance = i->getName().edit_distance(Group, true, BestDistance);
+    if (Distance > BestDistance)
+      continue;
+
+    // Don't suggest groups that are not of this kind.
+    llvm::SmallVector<diag::kind, 8> Diags;
+    if (::getDiagnosticsInGroup(Flavor, i, Diags) || Diags.empty())
+      continue;
+
     if (Distance == BestDistance) {
       // Two matches with the same distance, don't prefer one over the other.
       Best = "";
@@ -677,6 +702,7 @@
 
 bool DiagnosticIDs::isUnrecoverable(unsigned DiagID) const {
   if (DiagID >= diag::DIAG_UPPER_LIMIT) {
+    assert(CustomDiagInfo && "Invalid CustomDiagInfo");
     // Custom diagnostics.
     return CustomDiagInfo->getLevel(DiagID) >= DiagnosticIDs::Error;
   }
diff --git a/lib/Basic/FileManager.cpp b/lib/Basic/FileManager.cpp
index af9b266..9421032 100644
--- a/lib/Basic/FileManager.cpp
+++ b/lib/Basic/FileManager.cpp
@@ -25,29 +25,13 @@
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/system_error.h"
 #include <map>
 #include <set>
 #include <string>
+#include <system_error>
 
-// FIXME: This is terrible, we need this for ::close.
-#if !defined(_MSC_VER) && !defined(__MINGW32__)
-#include <unistd.h>
-#include <sys/uio.h>
-#else
-#include <io.h>
-#ifndef S_ISFIFO
-#define S_ISFIFO(x) (0)
-#endif
-#endif
-#if defined(LLVM_ON_UNIX)
-#include <limits.h>
-#endif
 using namespace clang;
 
-// FIXME: Enhance libsystem to support inode and other fields.
-#include <sys/stat.h>
-
 /// NON_EXISTENT_DIR - A special value distinct from null that is used to
 /// represent a dir name that doesn't exist on the disk.
 #define NON_EXISTENT_DIR reinterpret_cast<DirectoryEntry*>((intptr_t)-1)
@@ -56,63 +40,24 @@
 /// represent a filename that doesn't exist on the disk.
 #define NON_EXISTENT_FILE reinterpret_cast<FileEntry*>((intptr_t)-1)
 
-
-FileEntry::~FileEntry() {
-  // If this FileEntry owns an open file descriptor that never got used, close
-  // it.
-  if (FD != -1) ::close(FD);
-}
-
-class FileManager::UniqueDirContainer {
-  /// UniqueDirs - Cache from ID's to existing directories/files.
-  std::map<llvm::sys::fs::UniqueID, DirectoryEntry> UniqueDirs;
-
-public:
-  /// getDirectory - Return an existing DirectoryEntry with the given
-  /// ID's if there is already one; otherwise create and return a
-  /// default-constructed DirectoryEntry.
-  DirectoryEntry &getDirectory(const llvm::sys::fs::UniqueID &UniqueID) {
-    return UniqueDirs[UniqueID];
-  }
-
-  size_t size() const { return UniqueDirs.size(); }
-};
-
-class FileManager::UniqueFileContainer {
-  /// UniqueFiles - Cache from ID's to existing directories/files.
-  std::set<FileEntry> UniqueFiles;
-
-public:
-  /// getFile - Return an existing FileEntry with the given ID's if
-  /// there is already one; otherwise create and return a
-  /// default-constructed FileEntry.
-  FileEntry &getFile(llvm::sys::fs::UniqueID UniqueID, bool IsNamedPipe,
-                     bool InPCH) {
-    return const_cast<FileEntry &>(
-        *UniqueFiles.insert(FileEntry(UniqueID, IsNamedPipe, InPCH)).first);
-  }
-
-  size_t size() const { return UniqueFiles.size(); }
-
-  void erase(const FileEntry *Entry) { UniqueFiles.erase(*Entry); }
-};
-
 //===----------------------------------------------------------------------===//
 // Common logic.
 //===----------------------------------------------------------------------===//
 
-FileManager::FileManager(const FileSystemOptions &FSO)
-  : FileSystemOpts(FSO),
-    UniqueRealDirs(*new UniqueDirContainer()),
-    UniqueRealFiles(*new UniqueFileContainer()),
+FileManager::FileManager(const FileSystemOptions &FSO,
+                         IntrusiveRefCntPtr<vfs::FileSystem> FS)
+  : FS(FS), FileSystemOpts(FSO),
     SeenDirEntries(64), SeenFileEntries(64), NextFileUID(0) {
   NumDirLookups = NumFileLookups = 0;
   NumDirCacheMisses = NumFileCacheMisses = 0;
+
+  // If the caller doesn't provide a virtual file system, just grab the real
+  // file system.
+  if (!FS)
+    this->FS = vfs::getRealFileSystem();
 }
 
 FileManager::~FileManager() {
-  delete &UniqueRealDirs;
-  delete &UniqueRealFiles;
   for (unsigned i = 0, e = VirtualFileEntries.size(); i != e; ++i)
     delete VirtualFileEntries[i];
   for (unsigned i = 0, e = VirtualDirectoryEntries.size(); i != e; ++i)
@@ -122,8 +67,8 @@
 void FileManager::addStatCache(FileSystemStatCache *statCache,
                                bool AtBeginning) {
   assert(statCache && "No stat cache provided?");
-  if (AtBeginning || StatCache.get() == 0) {
-    statCache->setNextStatCache(StatCache.take());
+  if (AtBeginning || !StatCache.get()) {
+    statCache->setNextStatCache(StatCache.release());
     StatCache.reset(statCache);
     return;
   }
@@ -155,7 +100,7 @@
 }
 
 void FileManager::clearStatCaches() {
-  StatCache.reset(0);
+  StatCache.reset();
 }
 
 /// \brief Retrieve the directory that the given file name resides in.
@@ -164,10 +109,10 @@
                                                   StringRef Filename,
                                                   bool CacheFailure) {
   if (Filename.empty())
-    return NULL;
+    return nullptr;
 
   if (llvm::sys::path::is_separator(Filename[Filename.size() - 1]))
-    return NULL;  // If Filename is a directory.
+    return nullptr; // If Filename is a directory.
 
   StringRef DirName = llvm::sys::path::parent_path(Filename);
   // Use the current directory if file has no path component.
@@ -231,8 +176,8 @@
   // See if there was already an entry in the map.  Note that the map
   // contains both virtual and real directories.
   if (NamedDirEnt.getValue())
-    return NamedDirEnt.getValue() == NON_EXISTENT_DIR
-              ? 0 : NamedDirEnt.getValue();
+    return NamedDirEnt.getValue() == NON_EXISTENT_DIR ? nullptr
+                                                      : NamedDirEnt.getValue();
 
   ++NumDirCacheMisses;
 
@@ -245,19 +190,18 @@
 
   // Check to see if the directory exists.
   FileData Data;
-  if (getStatValue(InterndDirName, Data, false, 0 /*directory lookup*/)) {
+  if (getStatValue(InterndDirName, Data, false, nullptr /*directory lookup*/)) {
     // There's no real directory at the given path.
     if (!CacheFailure)
       SeenDirEntries.erase(DirName);
-    return 0;
+    return nullptr;
   }
 
   // It exists.  See if we have already opened a directory with the
   // same inode (this occurs on Unix-like systems when one dir is
   // symlinked to another, for example) or the same path (on
   // Windows).
-  DirectoryEntry &UDE =
-      UniqueRealDirs.getDirectory(Data.UniqueID);
+  DirectoryEntry &UDE = UniqueRealDirs[Data.UniqueID];
 
   NamedDirEnt.setValue(&UDE);
   if (!UDE.getName()) {
@@ -280,7 +224,7 @@
   // See if there is already an entry in the map.
   if (NamedFileEnt.getValue())
     return NamedFileEnt.getValue() == NON_EXISTENT_FILE
-                 ? 0 : NamedFileEnt.getValue();
+                 ? nullptr : NamedFileEnt.getValue();
 
   ++NumFileCacheMisses;
 
@@ -298,56 +242,59 @@
   // without a 'sys' subdir will get a cached failure result.
   const DirectoryEntry *DirInfo = getDirectoryFromFile(*this, Filename,
                                                        CacheFailure);
-  if (DirInfo == 0) {  // Directory doesn't exist, file can't exist.
+  if (DirInfo == nullptr) { // Directory doesn't exist, file can't exist.
     if (!CacheFailure)
       SeenFileEntries.erase(Filename);
-    
-    return 0;
+
+    return nullptr;
   }
   
   // FIXME: Use the directory info to prune this, before doing the stat syscall.
   // FIXME: This will reduce the # syscalls.
 
   // Nope, there isn't.  Check to see if the file exists.
-  int FileDescriptor = -1;
+  std::unique_ptr<vfs::File> F;
   FileData Data;
-  if (getStatValue(InterndFileName, Data, true,
-                   openFile ? &FileDescriptor : 0)) {
+  if (getStatValue(InterndFileName, Data, true, openFile ? &F : nullptr)) {
     // There's no real file at the given path.
     if (!CacheFailure)
       SeenFileEntries.erase(Filename);
-    
-    return 0;
+
+    return nullptr;
   }
 
-  if (FileDescriptor != -1 && !openFile) {
-    close(FileDescriptor);
-    FileDescriptor = -1;
-  }
+  assert((openFile || !F) && "undesired open file");
 
   // It exists.  See if we have already opened a file with the same inode.
   // This occurs when one dir is symlinked to another, for example.
-  FileEntry &UFE =
-      UniqueRealFiles.getFile(Data.UniqueID, Data.IsNamedPipe, Data.InPCH);
+  FileEntry &UFE = UniqueRealFiles[Data.UniqueID];
 
   NamedFileEnt.setValue(&UFE);
-  if (UFE.getName()) { // Already have an entry with this inode, return it.
-    // If the stat process opened the file, close it to avoid a FD leak.
-    if (FileDescriptor != -1)
-      close(FileDescriptor);
+  if (UFE.isValid()) { // Already have an entry with this inode, return it.
+
+    // FIXME: this hack ensures that if we look up a file by a virtual path in
+    // the VFS that the getDir() will have the virtual path, even if we found
+    // the file by a 'real' path first. This is required in order to find a
+    // module's structure when its headers/module map are mapped in the VFS.
+    // We should remove this as soon as we can properly support a file having
+    // multiple names.
+    if (DirInfo != UFE.Dir && Data.IsVFSMapped)
+      UFE.Dir = DirInfo;
 
     return &UFE;
   }
 
-  // Otherwise, we don't have this directory yet, add it.
-  // FIXME: Change the name to be a char* that points back to the
-  // 'SeenFileEntries' key.
-  UFE.Name    = InterndFileName;
+  // Otherwise, we don't have this file yet, add it.
+  UFE.Name    = Data.Name;
   UFE.Size = Data.Size;
   UFE.ModTime = Data.ModTime;
   UFE.Dir     = DirInfo;
   UFE.UID     = NextFileUID++;
-  UFE.FD      = FileDescriptor;
+  UFE.UniqueID = Data.UniqueID;
+  UFE.IsNamedPipe = Data.IsNamedPipe;
+  UFE.InPCH = Data.InPCH;
+  UFE.File = std::move(F);
+  UFE.IsValid = true;
   return &UFE;
 }
 
@@ -370,7 +317,7 @@
   NamedFileEnt.setValue(NON_EXISTENT_FILE);
 
   addAncestorsAsVirtualDirs(Filename);
-  FileEntry *UFE = 0;
+  FileEntry *UFE = nullptr;
 
   // Now that all ancestors of Filename are in the cache, the
   // following call is guaranteed to find the DirectoryEntry from the
@@ -383,24 +330,26 @@
   // Check to see if the file exists. If so, drop the virtual file
   FileData Data;
   const char *InterndFileName = NamedFileEnt.getKeyData();
-  if (getStatValue(InterndFileName, Data, true, 0) == 0) {
+  if (getStatValue(InterndFileName, Data, true, nullptr) == 0) {
     Data.Size = Size;
     Data.ModTime = ModificationTime;
-    UFE = &UniqueRealFiles.getFile(Data.UniqueID, Data.IsNamedPipe, Data.InPCH);
+    UFE = &UniqueRealFiles[Data.UniqueID];
 
     NamedFileEnt.setValue(UFE);
 
     // If we had already opened this file, close it now so we don't
     // leak the descriptor. We're not going to use the file
     // descriptor anyway, since this is a virtual file.
-    if (UFE->FD != -1) {
-      close(UFE->FD);
-      UFE->FD = -1;
-    }
+    if (UFE->File)
+      UFE->closeFile();
 
     // If we already have an entry with this inode, return it.
-    if (UFE->getName())
+    if (UFE->isValid())
       return UFE;
+
+    UFE->UniqueID = Data.UniqueID;
+    UFE->IsNamedPipe = Data.IsNamedPipe;
+    UFE->InPCH = Data.InPCH;
   }
 
   if (!UFE) {
@@ -414,7 +363,7 @@
   UFE->ModTime = ModificationTime;
   UFE->Dir     = DirInfo;
   UFE->UID     = NextFileUID++;
-  UFE->FD      = -1;
+  UFE->File.reset();
   return UFE;
 }
 
@@ -432,9 +381,9 @@
 
 llvm::MemoryBuffer *FileManager::
 getBufferForFile(const FileEntry *Entry, std::string *ErrorStr,
-                 bool isVolatile) {
-  OwningPtr<llvm::MemoryBuffer> Result;
-  llvm::error_code ec;
+                 bool isVolatile, bool ShouldCloseOpenFile) {
+  std::unique_ptr<llvm::MemoryBuffer> Result;
+  std::error_code ec;
 
   uint64_t FileSize = Entry->getSize();
   // If there's a high enough chance that the file have changed since we
@@ -444,50 +393,54 @@
 
   const char *Filename = Entry->getName();
   // If the file is already open, use the open file descriptor.
-  if (Entry->FD != -1) {
-    ec = llvm::MemoryBuffer::getOpenFile(Entry->FD, Filename, Result, FileSize);
+  if (Entry->File) {
+    ec = Entry->File->getBuffer(Filename, Result, FileSize,
+                                /*RequiresNullTerminator=*/true, isVolatile);
     if (ErrorStr)
       *ErrorStr = ec.message();
-
-    close(Entry->FD);
-    Entry->FD = -1;
-    return Result.take();
+    // FIXME: we need a set of APIs that can make guarantees about whether a
+    // FileEntry is open or not.
+    if (ShouldCloseOpenFile)
+      Entry->closeFile();
+    return Result.release();
   }
 
   // Otherwise, open the file.
 
   if (FileSystemOpts.WorkingDir.empty()) {
-    ec = llvm::MemoryBuffer::getFile(Filename, Result, FileSize);
+    ec = FS->getBufferForFile(Filename, Result, FileSize,
+                              /*RequiresNullTerminator=*/true, isVolatile);
     if (ec && ErrorStr)
       *ErrorStr = ec.message();
-    return Result.take();
+    return Result.release();
   }
 
   SmallString<128> FilePath(Entry->getName());
   FixupRelativePath(FilePath);
-  ec = llvm::MemoryBuffer::getFile(FilePath.str(), Result, FileSize);
+  ec = FS->getBufferForFile(FilePath.str(), Result, FileSize,
+                            /*RequiresNullTerminator=*/true, isVolatile);
   if (ec && ErrorStr)
     *ErrorStr = ec.message();
-  return Result.take();
+  return Result.release();
 }
 
 llvm::MemoryBuffer *FileManager::
 getBufferForFile(StringRef Filename, std::string *ErrorStr) {
-  OwningPtr<llvm::MemoryBuffer> Result;
-  llvm::error_code ec;
+  std::unique_ptr<llvm::MemoryBuffer> Result;
+  std::error_code ec;
   if (FileSystemOpts.WorkingDir.empty()) {
-    ec = llvm::MemoryBuffer::getFile(Filename, Result);
+    ec = FS->getBufferForFile(Filename, Result);
     if (ec && ErrorStr)
       *ErrorStr = ec.message();
-    return Result.take();
+    return Result.release();
   }
 
   SmallString<128> FilePath(Filename);
   FixupRelativePath(FilePath);
-  ec = llvm::MemoryBuffer::getFile(FilePath.c_str(), Result);
+  ec = FS->getBufferForFile(FilePath.c_str(), Result);
   if (ec && ErrorStr)
     *ErrorStr = ec.message();
-  return Result.take();
+  return Result.release();
 }
 
 /// getStatValue - Get the 'stat' information for the specified path,
@@ -496,26 +449,29 @@
 /// false if it's an existent real file.  If FileDescriptor is NULL,
 /// do directory look-up instead of file look-up.
 bool FileManager::getStatValue(const char *Path, FileData &Data, bool isFile,
-                               int *FileDescriptor) {
+                               std::unique_ptr<vfs::File> *F) {
   // FIXME: FileSystemOpts shouldn't be passed in here, all paths should be
   // absolute!
   if (FileSystemOpts.WorkingDir.empty())
-    return FileSystemStatCache::get(Path, Data, isFile, FileDescriptor,
-                                    StatCache.get());
+    return FileSystemStatCache::get(Path, Data, isFile, F,StatCache.get(), *FS);
 
   SmallString<128> FilePath(Path);
   FixupRelativePath(FilePath);
 
-  return FileSystemStatCache::get(FilePath.c_str(), Data, isFile,
-                                  FileDescriptor, StatCache.get());
+  return FileSystemStatCache::get(FilePath.c_str(), Data, isFile, F,
+                                  StatCache.get(), *FS);
 }
 
 bool FileManager::getNoncachedStatValue(StringRef Path,
-                                        llvm::sys::fs::file_status &Result) {
+                                        vfs::Status &Result) {
   SmallString<128> FilePath(Path);
   FixupRelativePath(FilePath);
 
-  return llvm::sys::fs::status(FilePath.c_str(), Result);
+  llvm::ErrorOr<vfs::Status> S = FS->status(FilePath.c_str());
+  if (!S)
+    return true;
+  Result = *S;
+  return false;
 }
 
 void FileManager::invalidateCache(const FileEntry *Entry) {
@@ -526,7 +482,7 @@
   // FileEntry invalidation should not block future optimizations in the file
   // caches. Possible alternatives are cache truncation (invalidate last N) or
   // invalidation of the whole cache.
-  UniqueRealFiles.erase(Entry);
+  UniqueRealFiles.erase(Entry->getUniqueID());
 }
 
 
diff --git a/lib/Basic/FileSystemStatCache.cpp b/lib/Basic/FileSystemStatCache.cpp
index 7a01bff..7515cfb 100644
--- a/lib/Basic/FileSystemStatCache.cpp
+++ b/lib/Basic/FileSystemStatCache.cpp
@@ -12,7 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Basic/FileSystemStatCache.h"
-#include "llvm/Support/FileSystem.h"
+#include "clang/Basic/VirtualFileSystem.h"
 #include "llvm/Support/Path.h"
 
 // FIXME: This is terrible, we need this for ::close.
@@ -30,14 +30,16 @@
 
 void FileSystemStatCache::anchor() { }
 
-static void copyStatusToFileData(const llvm::sys::fs::file_status &Status,
+static void copyStatusToFileData(const vfs::Status &Status,
                                  FileData &Data) {
+  Data.Name = Status.getName();
   Data.Size = Status.getSize();
   Data.ModTime = Status.getLastModificationTime().toEpochTime();
   Data.UniqueID = Status.getUniqueID();
-  Data.IsDirectory = is_directory(Status);
-  Data.IsNamedPipe = Status.type() == llvm::sys::fs::file_type::fifo_file;
+  Data.IsDirectory = Status.isDirectory();
+  Data.IsNamedPipe = Status.getType() == llvm::sys::fs::file_type::fifo_file;
   Data.InPCH = false;
+  Data.IsVFSMapped = Status.IsVFSMapped;
 }
 
 /// FileSystemStatCache::get - Get the 'stat' information for the specified
@@ -50,22 +52,23 @@
 /// implementation can optionally fill in FileDescriptor with a valid
 /// descriptor and the client guarantees that it will close it.
 bool FileSystemStatCache::get(const char *Path, FileData &Data, bool isFile,
-                              int *FileDescriptor, FileSystemStatCache *Cache) {
+                              std::unique_ptr<vfs::File> *F,
+                              FileSystemStatCache *Cache, vfs::FileSystem &FS) {
   LookupResult R;
   bool isForDir = !isFile;
 
   // If we have a cache, use it to resolve the stat query.
   if (Cache)
-    R = Cache->getStat(Path, Data, isFile, FileDescriptor);
-  else if (isForDir || !FileDescriptor) {
+    R = Cache->getStat(Path, Data, isFile, F, FS);
+  else if (isForDir || !F) {
     // If this is a directory or a file descriptor is not needed and we have
     // no cache, just go to the file system.
-    llvm::sys::fs::file_status Status;
-    if (llvm::sys::fs::status(Path, Status)) {
+    llvm::ErrorOr<vfs::Status> Status = FS.status(Path);
+    if (!Status) {
       R = CacheMissing;
     } else {
       R = CacheExists;
-      copyStatusToFileData(Status, Data);
+      copyStatusToFileData(*Status, Data);
     }
   } else {
     // Otherwise, we have to go to the filesystem.  We can always just use
@@ -75,7 +78,8 @@
     //
     // Because of this, check to see if the file exists with 'open'.  If the
     // open succeeds, use fstat to get the stat info.
-    llvm::error_code EC = llvm::sys::fs::openFileForRead(Path, *FileDescriptor);
+    std::unique_ptr<vfs::File> OwnedFile;
+    std::error_code EC = FS.openFileForRead(Path, OwnedFile);
 
     if (EC) {
       // If the open fails, our "stat" fails.
@@ -84,16 +88,16 @@
       // Otherwise, the open succeeded.  Do an fstat to get the information
       // about the file.  We'll end up returning the open file descriptor to the
       // client to do what they please with it.
-      llvm::sys::fs::file_status Status;
-      if (!llvm::sys::fs::status(*FileDescriptor, Status)) {
+      llvm::ErrorOr<vfs::Status> Status = OwnedFile->status();
+      if (Status) {
         R = CacheExists;
-        copyStatusToFileData(Status, Data);
+        copyStatusToFileData(*Status, Data);
+        *F = std::move(OwnedFile);
       } else {
         // fstat rarely fails.  If it does, claim the initial open didn't
         // succeed.
         R = CacheMissing;
-        ::close(*FileDescriptor);
-        *FileDescriptor = -1;
+        *F = nullptr;
       }
     }
   }
@@ -105,10 +109,8 @@
   // demands.
   if (Data.IsDirectory != isForDir) {
     // If not, close the file if opened.
-    if (FileDescriptor && *FileDescriptor != -1) {
-      ::close(*FileDescriptor);
-      *FileDescriptor = -1;
-    }
+    if (F)
+      *F = nullptr;
     
     return true;
   }
@@ -118,8 +120,8 @@
 
 MemorizeStatCalls::LookupResult
 MemorizeStatCalls::getStat(const char *Path, FileData &Data, bool isFile,
-                           int *FileDescriptor) {
-  LookupResult Result = statChained(Path, Data, isFile, FileDescriptor);
+                           std::unique_ptr<vfs::File> *F, vfs::FileSystem &FS) {
+  LookupResult Result = statChained(Path, Data, isFile, F, FS);
 
   // Do not cache failed stats, it is easy to construct common inconsistent
   // situations if we do, and they are not important for PCH performance (which
diff --git a/lib/Basic/IdentifierTable.cpp b/lib/Basic/IdentifierTable.cpp
index 500e732..2198459 100644
--- a/lib/Basic/IdentifierTable.cpp
+++ b/lib/Basic/IdentifierTable.cpp
@@ -12,11 +12,13 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "clang/Basic/CharInfo.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/LangOptions.h"
-#include "clang/Basic/CharInfo.h"
+#include "clang/Basic/OperatorKinds.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/SmallString.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/raw_ostream.h"
 #include <cstdio>
@@ -42,8 +44,8 @@
   RevertedTokenID = false;
   OutOfDate = false;
   IsModulesImport = false;
-  FETokenInfo = 0;
-  Entry = 0;
+  FETokenInfo = nullptr;
+  Entry = nullptr;
 }
 
 //===----------------------------------------------------------------------===//
@@ -60,7 +62,7 @@
   class EmptyLookupIterator : public IdentifierIterator
   {
   public:
-    virtual StringRef Next() { return StringRef(); }
+    StringRef Next() override { return StringRef(); }
   };
 }
 
@@ -105,6 +107,7 @@
     KEYARC = 0x800,
     KEYNOMS = 0x01000,
     WCHARSUPPORT = 0x02000,
+    HALFSUPPORT = 0x04000,
     KEYALL = (0xffff & ~KEYNOMS) // Because KEYNOMS is used to exclude.
   };
 }
@@ -129,6 +132,7 @@
   else if (LangOpts.MicrosoftExt && (Flags & KEYMS)) AddResult = 1;
   else if (LangOpts.Borland && (Flags & KEYBORLAND)) AddResult = 1;
   else if (LangOpts.Bool && (Flags & BOOLSUPPORT)) AddResult = 2;
+  else if (LangOpts.Half && (Flags & HALFSUPPORT)) AddResult = 2;
   else if (LangOpts.WChar && (Flags & WCHARSUPPORT)) AddResult = 2;
   else if (LangOpts.AltiVec && (Flags & KEYALTIVEC)) AddResult = 2;
   else if (LangOpts.OpenCL && (Flags & KEYOPENCL)) AddResult = 2;
@@ -139,8 +143,8 @@
   else if (LangOpts.ObjC2 && (Flags & KEYARC)) AddResult = 2;
   else if (LangOpts.CPlusPlus && (Flags & KEYCXX11)) AddResult = 3;
 
-  // Don't add this keyword under MicrosoftMode.
-  if (LangOpts.MicrosoftMode && (Flags & KEYNOMS))
+  // Don't add this keyword under MSVCCompat.
+  if (LangOpts.MSVCCompat && (Flags & KEYNOMS))
      return;
   // Don't add this keyword if disabled in this language.
   if (AddResult == 0) return;
@@ -398,6 +402,10 @@
   return getMultiKeywordSelector()->getName();
 }
 
+void Selector::print(llvm::raw_ostream &OS) const {
+  OS << getAsString();
+}
+
 /// Interpreting the given string using the normal CamelCase
 /// conventions, determine whether the given string starts with the
 /// given "word", which is assumed to end in a lowercase letter.
@@ -521,7 +529,7 @@
   llvm::FoldingSetNodeID ID;
   MultiKeywordSelector::Profile(ID, IIV, nKeys);
 
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
   if (MultiKeywordSelector *SI =
         SelTabImpl.Table.FindNodeOrInsertPos(ID, InsertPos))
     return Selector(SI);
@@ -549,7 +557,7 @@
   switch (Operator) {
   case OO_None:
   case NUM_OVERLOADED_OPERATORS:
-    return 0;
+    return nullptr;
 
 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
   case OO_##Name: return Spelling;
diff --git a/lib/Basic/Module.cpp b/lib/Basic/Module.cpp
index d08cef1..f689c73 100644
--- a/lib/Basic/Module.cpp
+++ b/lib/Basic/Module.cpp
@@ -24,20 +24,23 @@
 
 using namespace clang;
 
-Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, 
-               bool IsFramework, bool IsExplicit)
-  : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent),
-    Umbrella(), ASTFile(0), IsAvailable(true), IsFromModuleFile(false),
-    IsFramework(IsFramework), IsExplicit(IsExplicit), IsSystem(false),
-    InferSubmodules(false), InferExplicitSubmodules(false), 
-    InferExportWildcard(false), ConfigMacrosExhaustive(false),
-    NameVisibility(Hidden)
-{ 
+Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
+               const FileEntry *File, bool IsFramework, bool IsExplicit)
+    : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), ModuleMap(File),
+      Umbrella(), ASTFile(nullptr), IsMissingRequirement(false),
+      IsAvailable(true), IsFromModuleFile(false), IsFramework(IsFramework),
+      IsExplicit(IsExplicit), IsSystem(false), IsExternC(false),
+      IsInferred(false), InferSubmodules(false), InferExplicitSubmodules(false),
+      InferExportWildcard(false), ConfigMacrosExhaustive(false),
+      NameVisibility(Hidden) {
   if (Parent) {
     if (!Parent->isAvailable())
       IsAvailable = false;
     if (Parent->IsSystem)
       IsSystem = true;
+    if (Parent->IsExternC)
+      IsExternC = true;
+    IsMissingRequirement = Parent->IsMissingRequirement;
     
     Parent->SubModuleIndex[Name] = Parent->SubModules.size();
     Parent->SubModules.push_back(this);
@@ -69,11 +72,15 @@
 
 bool
 Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
-                    Requirement &Req) const {
+                    Requirement &Req, HeaderDirective &MissingHeader) const {
   if (IsAvailable)
     return true;
 
   for (const Module *Current = this; Current; Current = Current->Parent) {
+    if (!Current->MissingHeaders.empty()) {
+      MissingHeader = Current->MissingHeaders.front();
+      return false;
+    }
     for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) {
       if (hasFeature(Current->Requirements[I].first, LangOpts, Target) !=
               Current->Requirements[I].second) {
@@ -86,7 +93,7 @@
   llvm_unreachable("could not find a reason why module is unavailable");
 }
 
-bool Module::isSubModuleOf(Module *Other) const {
+bool Module::isSubModuleOf(const Module *Other) const {
   const Module *This = this;
   do {
     if (This == Other)
@@ -155,6 +162,10 @@
   if (hasFeature(Feature, LangOpts, Target) == RequiredState)
     return;
 
+  markUnavailable(/*MissingRequirement*/true);
+}
+
+void Module::markUnavailable(bool MissingRequirement) {
   if (!IsAvailable)
     return;
 
@@ -168,6 +179,7 @@
       continue;
 
     Current->IsAvailable = false;
+    Current->IsMissingRequirement |= MissingRequirement;
     for (submodule_iterator Sub = Current->submodule_begin(),
                          SubEnd = Current->submodule_end();
          Sub != SubEnd; ++Sub) {
@@ -180,8 +192,8 @@
 Module *Module::findSubmodule(StringRef Name) const {
   llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
   if (Pos == SubModuleIndex.end())
-    return 0;
-  
+    return nullptr;
+
   return SubModules[Pos->getValue()];
 }
 
@@ -349,7 +361,8 @@
   
   for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end();
        MI != MIEnd; ++MI)
-    (*MI)->print(OS, Indent + 2);
+    if (!(*MI)->IsInferred)
+      (*MI)->print(OS, Indent + 2);
   
   for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
     OS.indent(Indent + 2);
diff --git a/lib/Basic/OpenMPKinds.cpp b/lib/Basic/OpenMPKinds.cpp
index 1350934..06f010f 100644
--- a/lib/Basic/OpenMPKinds.cpp
+++ b/lib/Basic/OpenMPKinds.cpp
@@ -22,46 +22,49 @@
 
 OpenMPDirectiveKind clang::getOpenMPDirectiveKind(StringRef Str) {
   return llvm::StringSwitch<OpenMPDirectiveKind>(Str)
-#define OPENMP_DIRECTIVE(Name) \
-           .Case(#Name, OMPD_##Name)
+#define OPENMP_DIRECTIVE(Name) .Case(#Name, OMPD_##Name)
+#define OPENMP_DIRECTIVE_EXT(Name, Str) .Case(Str, OMPD_##Name)
 #include "clang/Basic/OpenMPKinds.def"
-           .Default(OMPD_unknown);
+      .Default(OMPD_unknown);
 }
 
 const char *clang::getOpenMPDirectiveName(OpenMPDirectiveKind Kind) {
-  assert(Kind < NUM_OPENMP_DIRECTIVES);
+  assert(Kind <= OMPD_unknown);
   switch (Kind) {
   case OMPD_unknown:
     return "unknown";
-#define OPENMP_DIRECTIVE(Name) \
-  case OMPD_##Name : return #Name;
+#define OPENMP_DIRECTIVE(Name)                                                 \
+  case OMPD_##Name:                                                            \
+    return #Name;
+#define OPENMP_DIRECTIVE_EXT(Name, Str)                                        \
+  case OMPD_##Name:                                                            \
+    return Str;
 #include "clang/Basic/OpenMPKinds.def"
-  case NUM_OPENMP_DIRECTIVES:
     break;
   }
   llvm_unreachable("Invalid OpenMP directive kind");
 }
 
 OpenMPClauseKind clang::getOpenMPClauseKind(StringRef Str) {
+  if (Str == "flush")
+    return OMPC_unknown;
   return llvm::StringSwitch<OpenMPClauseKind>(Str)
-#define OPENMP_CLAUSE(Name, Class) \
-           .Case(#Name, OMPC_##Name)
+#define OPENMP_CLAUSE(Name, Class) .Case(#Name, OMPC_##Name)
 #include "clang/Basic/OpenMPKinds.def"
-           .Default(OMPC_unknown);
+      .Default(OMPC_unknown);
 }
 
 const char *clang::getOpenMPClauseName(OpenMPClauseKind Kind) {
-  assert(Kind < NUM_OPENMP_CLAUSES);
+  assert(Kind <= OMPC_unknown);
   switch (Kind) {
   case OMPC_unknown:
     return "unknown";
-#define OPENMP_CLAUSE(Name, Class) \
-  case OMPC_##Name : return #Name;
+#define OPENMP_CLAUSE(Name, Class)                                             \
+  case OMPC_##Name:                                                            \
+    return #Name;
 #include "clang/Basic/OpenMPKinds.def"
   case OMPC_threadprivate:
     return "threadprivate or thread local";
-  case NUM_OPENMP_CLAUSES:
-    break;
   }
   llvm_unreachable("Invalid OpenMP clause kind");
 }
@@ -71,16 +74,40 @@
   switch (Kind) {
   case OMPC_default:
     return llvm::StringSwitch<OpenMPDefaultClauseKind>(Str)
-#define OPENMP_DEFAULT_KIND(Name) \
-             .Case(#Name, OMPC_DEFAULT_##Name)
+#define OPENMP_DEFAULT_KIND(Name) .Case(#Name, OMPC_DEFAULT_##Name)
 #include "clang/Basic/OpenMPKinds.def"
-             .Default(OMPC_DEFAULT_unknown);
+        .Default(OMPC_DEFAULT_unknown);
+  case OMPC_proc_bind:
+    return llvm::StringSwitch<OpenMPProcBindClauseKind>(Str)
+#define OPENMP_PROC_BIND_KIND(Name) .Case(#Name, OMPC_PROC_BIND_##Name)
+#include "clang/Basic/OpenMPKinds.def"
+        .Default(OMPC_PROC_BIND_unknown);
+  case OMPC_schedule:
+    return llvm::StringSwitch<OpenMPScheduleClauseKind>(Str)
+#define OPENMP_SCHEDULE_KIND(Name) .Case(#Name, OMPC_SCHEDULE_##Name)
+#include "clang/Basic/OpenMPKinds.def"
+        .Default(OMPC_SCHEDULE_unknown);
   case OMPC_unknown:
   case OMPC_threadprivate:
+  case OMPC_if:
+  case OMPC_final:
+  case OMPC_num_threads:
+  case OMPC_safelen:
+  case OMPC_collapse:
   case OMPC_private:
   case OMPC_firstprivate:
+  case OMPC_lastprivate:
   case OMPC_shared:
-  case NUM_OPENMP_CLAUSES:
+  case OMPC_reduction:
+  case OMPC_linear:
+  case OMPC_aligned:
+  case OMPC_copyin:
+  case OMPC_copyprivate:
+  case OMPC_ordered:
+  case OMPC_nowait:
+  case OMPC_untied:
+  case OMPC_mergeable:
+  case OMPC_flush:
     break;
   }
   llvm_unreachable("Invalid OpenMP simple clause kind");
@@ -93,17 +120,53 @@
     switch (Type) {
     case OMPC_DEFAULT_unknown:
       return "unknown";
-#define OPENMP_DEFAULT_KIND(Name) \
-    case OMPC_DEFAULT_##Name : return #Name;
+#define OPENMP_DEFAULT_KIND(Name)                                              \
+  case OMPC_DEFAULT_##Name:                                                    \
+    return #Name;
 #include "clang/Basic/OpenMPKinds.def"
     }
     llvm_unreachable("Invalid OpenMP 'default' clause type");
+  case OMPC_proc_bind:
+    switch (Type) {
+    case OMPC_PROC_BIND_unknown:
+      return "unknown";
+#define OPENMP_PROC_BIND_KIND(Name)                                            \
+  case OMPC_PROC_BIND_##Name:                                                  \
+    return #Name;
+#include "clang/Basic/OpenMPKinds.def"
+    }
+    llvm_unreachable("Invalid OpenMP 'proc_bind' clause type");
+  case OMPC_schedule:
+    switch (Type) {
+    case OMPC_SCHEDULE_unknown:
+      return "unknown";
+#define OPENMP_SCHEDULE_KIND(Name)                                             \
+  case OMPC_SCHEDULE_##Name:                                                   \
+    return #Name;
+#include "clang/Basic/OpenMPKinds.def"
+    }
+    llvm_unreachable("Invalid OpenMP 'schedule' clause type");
   case OMPC_unknown:
   case OMPC_threadprivate:
+  case OMPC_if:
+  case OMPC_final:
+  case OMPC_num_threads:
+  case OMPC_safelen:
+  case OMPC_collapse:
   case OMPC_private:
   case OMPC_firstprivate:
+  case OMPC_lastprivate:
   case OMPC_shared:
-  case NUM_OPENMP_CLAUSES:
+  case OMPC_reduction:
+  case OMPC_linear:
+  case OMPC_aligned:
+  case OMPC_copyin:
+  case OMPC_copyprivate:
+  case OMPC_ordered:
+  case OMPC_nowait:
+  case OMPC_untied:
+  case OMPC_mergeable:
+  case OMPC_flush:
     break;
   }
   llvm_unreachable("Invalid OpenMP simple clause kind");
@@ -111,23 +174,133 @@
 
 bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
                                         OpenMPClauseKind CKind) {
-  assert(DKind < NUM_OPENMP_DIRECTIVES);
-  assert(CKind < NUM_OPENMP_CLAUSES);
+  assert(DKind <= OMPD_unknown);
+  assert(CKind <= OMPC_unknown);
   switch (DKind) {
   case OMPD_parallel:
     switch (CKind) {
-#define OPENMP_PARALLEL_CLAUSE(Name) \
-    case OMPC_##Name: return true;
+#define OPENMP_PARALLEL_CLAUSE(Name)                                           \
+  case OMPC_##Name:                                                            \
+    return true;
 #include "clang/Basic/OpenMPKinds.def"
     default:
       break;
     }
     break;
+  case OMPD_simd:
+    switch (CKind) {
+#define OPENMP_SIMD_CLAUSE(Name)                                               \
+  case OMPC_##Name:                                                            \
+    return true;
+#include "clang/Basic/OpenMPKinds.def"
+    default:
+      break;
+    }
+    break;
+  case OMPD_for:
+    switch (CKind) {
+#define OPENMP_FOR_CLAUSE(Name)                                                \
+  case OMPC_##Name:                                                            \
+    return true;
+#include "clang/Basic/OpenMPKinds.def"
+    default:
+      break;
+    }
+    break;
+  case OMPD_sections:
+    switch (CKind) {
+#define OPENMP_SECTIONS_CLAUSE(Name)                                           \
+  case OMPC_##Name:                                                            \
+    return true;
+#include "clang/Basic/OpenMPKinds.def"
+    default:
+      break;
+    }
+    break;
+  case OMPD_single:
+    switch (CKind) {
+#define OPENMP_SINGLE_CLAUSE(Name)                                             \
+  case OMPC_##Name:                                                            \
+    return true;
+#include "clang/Basic/OpenMPKinds.def"
+    default:
+      break;
+    }
+    break;
+  case OMPD_parallel_for:
+    switch (CKind) {
+#define OPENMP_PARALLEL_FOR_CLAUSE(Name)                                       \
+  case OMPC_##Name:                                                            \
+    return true;
+#include "clang/Basic/OpenMPKinds.def"
+    default:
+      break;
+    }
+    break;
+  case OMPD_parallel_sections:
+    switch (CKind) {
+#define OPENMP_PARALLEL_SECTIONS_CLAUSE(Name)                                  \
+  case OMPC_##Name:                                                            \
+    return true;
+#include "clang/Basic/OpenMPKinds.def"
+    default:
+      break;
+    }
+    break;
+  case OMPD_task:
+    switch (CKind) {
+#define OPENMP_TASK_CLAUSE(Name)                                               \
+  case OMPC_##Name:                                                            \
+    return true;
+#include "clang/Basic/OpenMPKinds.def"
+    default:
+      break;
+    }
+    break;
+  case OMPD_flush:
+    return CKind == OMPC_flush;
+    break;
   case OMPD_unknown:
   case OMPD_threadprivate:
-  case OMPD_task:
-  case NUM_OPENMP_DIRECTIVES:
+  case OMPD_section:
+  case OMPD_master:
+  case OMPD_critical:
+  case OMPD_taskyield:
+  case OMPD_barrier:
+  case OMPD_taskwait:
     break;
   }
   return false;
 }
+
+bool clang::isOpenMPLoopDirective(OpenMPDirectiveKind DKind) {
+  return DKind == OMPD_simd || DKind == OMPD_for ||
+         DKind == OMPD_parallel_for; // TODO add next directives.
+}
+
+bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind) {
+  return DKind == OMPD_for || DKind == OMPD_sections || DKind == OMPD_section ||
+         DKind == OMPD_single || DKind == OMPD_parallel_for ||
+         DKind == OMPD_parallel_sections; // TODO add next directives.
+}
+
+bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind DKind) {
+  return DKind == OMPD_parallel || DKind == OMPD_parallel_for ||
+         DKind == OMPD_parallel_sections; // TODO add next directives.
+}
+
+bool clang::isOpenMPSimdDirective(OpenMPDirectiveKind DKind) {
+  return DKind == OMPD_simd; // TODO || DKind == OMPD_for_simd || ...
+}
+
+bool clang::isOpenMPPrivate(OpenMPClauseKind Kind) {
+  return Kind == OMPC_private || Kind == OMPC_firstprivate ||
+         Kind == OMPC_lastprivate || Kind == OMPC_linear ||
+         Kind == OMPC_reduction; // TODO add next clauses like 'reduction'.
+}
+
+bool clang::isOpenMPThreadPrivate(OpenMPClauseKind Kind) {
+  return Kind == OMPC_threadprivate ||
+         Kind == OMPC_copyin; // TODO add next clauses like 'copyprivate'.
+}
+
diff --git a/lib/Basic/SourceLocation.cpp b/lib/Basic/SourceLocation.cpp
index 1822091..0c06a48 100644
--- a/lib/Basic/SourceLocation.cpp
+++ b/lib/Basic/SourceLocation.cpp
@@ -61,14 +61,15 @@
   OS << '>';
 }
 
-std::string SourceLocation::printToString(const SourceManager &SM) const {
+LLVM_DUMP_METHOD std::string
+SourceLocation::printToString(const SourceManager &SM) const {
   std::string S;
   llvm::raw_string_ostream OS(S);
   print(OS, SM);
   return OS.str();
 }
 
-void SourceLocation::dump(const SourceManager &SM) const {
+LLVM_DUMP_METHOD void SourceLocation::dump(const SourceManager &SM) const {
   print(llvm::errs(), SM);
 }
 
@@ -122,7 +123,7 @@
   return SrcMgr->isBeforeInTranslationUnit(*this, Loc);
 }
 
-void FullSourceLoc::dump() const {
+LLVM_DUMP_METHOD void FullSourceLoc::dump() const {
   SourceLocation::dump(*SrcMgr);
 }
 
diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp
index 9d79551..61dfe35 100644
--- a/lib/Basic/SourceManager.cpp
+++ b/lib/Basic/SourceManager.cpp
@@ -26,7 +26,6 @@
 #include <algorithm>
 #include <cstring>
 #include <string>
-#include <sys/stat.h>
 
 using namespace clang;
 using namespace SrcMgr;
@@ -55,8 +54,8 @@
   // Should be unreachable, but keep for sanity.
   if (!Buffer.getPointer())
     return llvm::MemoryBuffer::MemoryBuffer_Malloc;
-  
-  const llvm::MemoryBuffer *buf = Buffer.getPointer();
+
+  llvm::MemoryBuffer *buf = Buffer.getPointer();
   return buf->getBufferKind();
 }
 
@@ -69,8 +68,7 @@
                              : (unsigned) ContentsEntry->getSize();
 }
 
-void ContentCache::replaceBuffer(const llvm::MemoryBuffer *B,
-                                 bool DoNotFree) {
+void ContentCache::replaceBuffer(llvm::MemoryBuffer *B, bool DoNotFree) {
   if (B && B == Buffer.getPointer()) {
     assert(0 && "Replacing with the same buffer");
     Buffer.setInt(DoNotFree? DoNotFreeFlag : 0);
@@ -83,13 +81,13 @@
   Buffer.setInt(DoNotFree? DoNotFreeFlag : 0);
 }
 
-const llvm::MemoryBuffer *ContentCache::getBuffer(DiagnosticsEngine &Diag,
-                                                  const SourceManager &SM,
-                                                  SourceLocation Loc,
-                                                  bool *Invalid) const {
+llvm::MemoryBuffer *ContentCache::getBuffer(DiagnosticsEngine &Diag,
+                                            const SourceManager &SM,
+                                            SourceLocation Loc,
+                                            bool *Invalid) const {
   // Lazily create the Buffer for ContentCaches that wrap files.  If we already
   // computed it, just return what we have.
-  if (Buffer.getPointer() || ContentsEntry == 0) {
+  if (Buffer.getPointer() || !ContentsEntry) {
     if (Invalid)
       *Invalid = isBufferInvalid();
     
@@ -163,7 +161,7 @@
     .StartsWith("\x0E\xFE\xFF", "SDSU")
     .StartsWith("\xFB\xEE\x28", "BOCU-1")
     .StartsWith("\x84\x31\x95\x33", "GB-18030")
-    .Default(0);
+    .Default(nullptr);
 
   if (InvalidBOM) {
     Diag.Report(Loc, diag::err_unsupported_bom)
@@ -272,7 +270,7 @@
   // Do a binary search to find the maximal element that is still before Offset.
   std::vector<LineEntry>::const_iterator I =
     std::upper_bound(Entries.begin(), Entries.end(), Offset);
-  if (I == Entries.begin()) return 0;
+  if (I == Entries.begin()) return nullptr;
   return &*--I;
 }
 
@@ -286,7 +284,7 @@
 /// getLineTableFilenameID - Return the uniqued ID for the specified filename.
 ///
 unsigned SourceManager::getLineTableFilenameID(StringRef Name) {
-  if (LineTable == 0)
+  if (!LineTable)
     LineTable = new LineTableInfo();
   return LineTable->getLineTableFilenameID(Name);
 }
@@ -309,7 +307,7 @@
   // Remember that this file has #line directives now if it doesn't already.
   const_cast<SrcMgr::FileInfo&>(FileInfo).setHasLineDirectives();
 
-  if (LineTable == 0)
+  if (!LineTable)
     LineTable = new LineTableInfo();
   LineTable->AddLineNote(LocInfo.first, LocInfo.second, LineNo, FilenameID);
 }
@@ -339,7 +337,7 @@
   // Remember that this file has #line directives now if it doesn't already.
   const_cast<SrcMgr::FileInfo&>(FileInfo).setHasLineDirectives();
 
-  if (LineTable == 0)
+  if (!LineTable)
     LineTable = new LineTableInfo();
 
   SrcMgr::CharacteristicKind FileKind;
@@ -361,7 +359,7 @@
 }
 
 LineTableInfo &SourceManager::getLineTable() {
-  if (LineTable == 0)
+  if (!LineTable)
     LineTable = new LineTableInfo();
   return *LineTable;
 }
@@ -374,9 +372,9 @@
                              bool UserFilesAreVolatile)
   : Diag(Diag), FileMgr(FileMgr), OverridenFilesKeepOriginalName(true),
     UserFilesAreVolatile(UserFilesAreVolatile),
-    ExternalSLocEntries(0), LineTable(0), NumLinearScans(0),
-    NumBinaryProbes(0), FakeBufferForRecovery(0),
-    FakeContentCacheForRecovery(0) {
+    ExternalSLocEntries(nullptr), LineTable(nullptr), NumLinearScans(0),
+    NumBinaryProbes(0), FakeBufferForRecovery(nullptr),
+    FakeContentCacheForRecovery(nullptr) {
   clearIDTables();
   Diag.setSourceManager(this);
 }
@@ -404,10 +402,7 @@
   delete FakeBufferForRecovery;
   delete FakeContentCacheForRecovery;
 
-  for (llvm::DenseMap<FileID, MacroArgsMap *>::iterator
-         I = MacroArgsCacheMap.begin(),E = MacroArgsCacheMap.end(); I!=E; ++I) {
-    delete I->second;
-  }
+  llvm::DeleteContainerSeconds(MacroArgsCacheMap);
 }
 
 void SourceManager::clearIDTables() {
@@ -416,7 +411,7 @@
   LoadedSLocEntryTable.clear();
   SLocEntryLoaded.clear();
   LastLineNoFileIDQuery = FileID();
-  LastLineNoContentCache = 0;
+  LastLineNoContentCache = nullptr;
   LastFileIDLookup = FileID();
 
   if (LineTable)
@@ -439,12 +434,8 @@
   ContentCache *&Entry = FileInfos[FileEnt];
   if (Entry) return Entry;
 
-  // Nope, create a new Cache entry.  Make sure it is at least 8-byte aligned
-  // so that FileInfo can use the low 3 bits of the pointer for its own
-  // nefarious purposes.
-  unsigned EntryAlign = llvm::AlignOf<ContentCache>::Alignment;
-  EntryAlign = std::max(8U, EntryAlign);
-  Entry = ContentCacheAlloc.Allocate<ContentCache>(1, EntryAlign);
+  // Nope, create a new Cache entry.
+  Entry = ContentCacheAlloc.Allocate<ContentCache>();
 
   if (OverriddenFilesInfo) {
     // If the file contents are overridden with contents from another file,
@@ -469,14 +460,10 @@
 
 /// createMemBufferContentCache - Create a new ContentCache for the specified
 ///  memory buffer.  This does no caching.
-const ContentCache*
-SourceManager::createMemBufferContentCache(const MemoryBuffer *Buffer) {
-  // Add a new ContentCache to the MemBufferInfos list and return it.  Make sure
-  // it is at least 8-byte aligned so that FileInfo can use the low 3 bits of
-  // the pointer for its own nefarious purposes.
-  unsigned EntryAlign = llvm::AlignOf<ContentCache>::Alignment;
-  EntryAlign = std::max(8U, EntryAlign);
-  ContentCache *Entry = ContentCacheAlloc.Allocate<ContentCache>(1, EntryAlign);
+const ContentCache *
+SourceManager::createMemBufferContentCache(llvm::MemoryBuffer *Buffer) {
+  // Add a new ContentCache to the MemBufferInfos list and return it.
+  ContentCache *Entry = ContentCacheAlloc.Allocate<ContentCache>();
   new (Entry) ContentCache();
   MemBufferInfos.push_back(Entry);
   Entry->setBuffer(Buffer);
@@ -516,7 +503,7 @@
 
 /// \brief As part of recovering from missing or changed content, produce a
 /// fake, non-empty buffer.
-const llvm::MemoryBuffer *SourceManager::getFakeBufferForRecovery() const {
+llvm::MemoryBuffer *SourceManager::getFakeBufferForRecovery() const {
   if (!FakeBufferForRecovery)
     FakeBufferForRecovery
       = llvm::MemoryBuffer::getMemBuffer("<<<INVALID BUFFER>>");
@@ -655,16 +642,15 @@
   return SourceLocation::getMacroLoc(NextLocalOffset - (TokLength + 1));
 }
 
-const llvm::MemoryBuffer *
-SourceManager::getMemoryBufferForFile(const FileEntry *File,
-                                      bool *Invalid) {
+llvm::MemoryBuffer *SourceManager::getMemoryBufferForFile(const FileEntry *File,
+                                                          bool *Invalid) {
   const SrcMgr::ContentCache *IR = getOrCreateContentCache(File);
   assert(IR && "getOrCreateContentCache() cannot return NULL");
   return IR->getBuffer(Diag, *this, SourceLocation(), Invalid);
 }
 
 void SourceManager::overrideFileContents(const FileEntry *SourceFile,
-                                         const llvm::MemoryBuffer *Buffer,
+                                         llvm::MemoryBuffer *Buffer,
                                          bool DoNotFree) {
   const SrcMgr::ContentCache *IR = getOrCreateContentCache(SourceFile);
   assert(IR && "getOrCreateContentCache() cannot return NULL");
@@ -691,7 +677,7 @@
     return;
 
   const SrcMgr::ContentCache *IR = getOrCreateContentCache(File);
-  const_cast<SrcMgr::ContentCache *>(IR)->replaceBuffer(0);
+  const_cast<SrcMgr::ContentCache *>(IR)->replaceBuffer(nullptr);
   const_cast<SrcMgr::ContentCache *>(IR)->ContentsEntry = IR->OrigEntry;
 
   assert(OverriddenFilesInfo);
@@ -707,10 +693,9 @@
       *Invalid = true;
     return "<<<<<INVALID SOURCE LOCATION>>>>>";
   }
-  
-  const llvm::MemoryBuffer *Buf
-    = SLoc.getFile().getContentCache()->getBuffer(Diag, *this, SourceLocation(), 
-                                                  &MyInvalid);
+
+  llvm::MemoryBuffer *Buf = SLoc.getFile().getContentCache()->getBuffer(
+      Diag, *this, SourceLocation(), &MyInvalid);
   if (Invalid)
     *Invalid = MyInvalid;
 
@@ -1128,9 +1113,8 @@
     
     return "<<<<INVALID BUFFER>>>>";
   }
-  const llvm::MemoryBuffer *Buffer
-    = Entry.getFile().getContentCache()
-                  ->getBuffer(Diag, *this, SourceLocation(), &CharDataInvalid);
+  llvm::MemoryBuffer *Buffer = Entry.getFile().getContentCache()->getBuffer(
+      Diag, *this, SourceLocation(), &CharDataInvalid);
   if (Invalid)
     *Invalid = CharDataInvalid;
   return Buffer->getBufferStart() + (CharDataInvalid? 0 : LocInfo.second);
@@ -1142,7 +1126,7 @@
 unsigned SourceManager::getColumnNumber(FileID FID, unsigned FilePos,
                                         bool *Invalid) const {
   bool MyInvalid = false;
-  const llvm::MemoryBuffer *MemBuf = getBuffer(FID, &MyInvalid);
+  llvm::MemoryBuffer *MemBuf = getBuffer(FID, &MyInvalid);
   if (Invalid)
     *Invalid = MyInvalid;
 
@@ -1159,7 +1143,7 @@
   // See if we just calculated the line number for this FilePos and can use
   // that to lookup the start of the line instead of searching for it.
   if (LastLineNoFileIDQuery == FID &&
-      LastLineNoContentCache->SourceLineCache != 0 &&
+      LastLineNoContentCache->SourceLineCache != nullptr &&
       LastLineNoResult < LastLineNoContentCache->NumLines) {
     unsigned *SourceLineCache = LastLineNoContentCache->SourceLineCache;
     unsigned LineStart = SourceLineCache[LastLineNoResult - 1];
@@ -1216,8 +1200,7 @@
                                llvm::BumpPtrAllocator &Alloc,
                                const SourceManager &SM, bool &Invalid) {
   // Note that calling 'getBuffer()' may lazily page in the file.
-  const MemoryBuffer *Buffer = FI->getBuffer(Diag, SM, SourceLocation(),
-                                             &Invalid);
+  MemoryBuffer *Buffer = FI->getBuffer(Diag, SM, SourceLocation(), &Invalid);
   if (Invalid)
     return;
 
@@ -1323,7 +1306,7 @@
   
   // If this is the first use of line information for this buffer, compute the
   /// SourceLineCache for it on demand.
-  if (Content->SourceLineCache == 0) {
+  if (!Content->SourceLineCache) {
     bool MyInvalid = false;
     ComputeLineNumbers(Diag, Content, ContentCacheAlloc, *this, MyInvalid);
     if (Invalid)
@@ -1381,31 +1364,6 @@
     }
   }
 
-  // If the spread is large, do a "radix" test as our initial guess, based on
-  // the assumption that lines average to approximately the same length.
-  // NOTE: This is currently disabled, as it does not appear to be profitable in
-  // initial measurements.
-  if (0 && SourceLineCacheEnd-SourceLineCache > 20) {
-    unsigned FileLen = Content->SourceLineCache[Content->NumLines-1];
-
-    // Take a stab at guessing where it is.
-    unsigned ApproxPos = Content->NumLines*QueriedFilePos / FileLen;
-
-    // Check for -10 and +10 lines.
-    unsigned LowerBound = std::max(int(ApproxPos-10), 0);
-    unsigned UpperBound = std::min(ApproxPos+10, FileLen);
-
-    // If the computed lower bound is less than the query location, move it in.
-    if (SourceLineCache < SourceLineCacheStart+LowerBound &&
-        SourceLineCacheStart[LowerBound] < QueriedFilePos)
-      SourceLineCache = SourceLineCacheStart+LowerBound;
-
-    // If the computed upper bound is greater than the query location, move it.
-    if (SourceLineCacheEnd > SourceLineCacheStart+UpperBound &&
-        SourceLineCacheStart[UpperBound] >= QueriedFilePos)
-      SourceLineCacheEnd = SourceLineCacheStart+UpperBound;
-  }
-
   unsigned *Pos
     = std::lower_bound(SourceLineCache, SourceLineCacheEnd, QueriedFilePos);
   unsigned LineNo = Pos-SourceLineCacheStart;
@@ -1583,7 +1541,7 @@
   return FI.getIncludeLoc().isInvalid();
 }
 
-/// \brief The size of the SLocEnty that \arg FID represents.
+/// \brief The size of the SLocEntry that \p FID represents.
 unsigned SourceManager::getFileIDSize(FileID FID) const {
   bool Invalid = false;
   const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid);
@@ -1732,7 +1690,8 @@
       if (SLoc.isFile()) { 
         const ContentCache *FileContentCache 
           = SLoc.getFile().getContentCache();
-      const FileEntry *Entry =FileContentCache? FileContentCache->OrigEntry : 0;
+        const FileEntry *Entry = FileContentCache ? FileContentCache->OrigEntry
+                                                  : nullptr;
         if (Entry && 
             *SourceFileName == llvm::sys::path::filename(Entry->getName())) {
           if (Optional<llvm::sys::fs::UniqueID> EntryUID =
@@ -1784,7 +1743,7 @@
 
   // If this is the first use of line information for this buffer, compute the
   // SourceLineCache for it on demand.
-  if (Content->SourceLineCache == 0) {
+  if (!Content->SourceLineCache) {
     bool MyInvalid = false;
     ComputeLineNumbers(Diag, Content, ContentCacheAlloc, *this, MyInvalid);
     if (MyInvalid)
@@ -1798,7 +1757,7 @@
     return FileLoc.getLocWithOffset(Size);
   }
 
-  const llvm::MemoryBuffer *Buffer = Content->getBuffer(Diag, *this);
+  llvm::MemoryBuffer *Buffer = Content->getBuffer(Diag, *this);
   unsigned FilePos = Content->SourceLineCache[Line - 1];
   const char *Buf = Buffer->getBufferStart() + FilePos;
   unsigned BufLength = Buffer->getBufferSize() - FilePos;
@@ -1893,7 +1852,7 @@
 
     FileID SpellFID; // Current FileID in the spelling range.
     unsigned SpellRelativeOffs;
-    llvm::tie(SpellFID, SpellRelativeOffs) = getDecomposedLoc(SpellLoc);
+    std::tie(SpellFID, SpellRelativeOffs) = getDecomposedLoc(SpellLoc);
     while (1) {
       const SLocEntry &Entry = getSLocEntry(SpellFID);
       unsigned SpellFIDBeginOffs = Entry.getOffset();
@@ -1972,7 +1931,7 @@
 
   FileID FID;
   unsigned Offset;
-  llvm::tie(FID, Offset) = getDecomposedLoc(Loc);
+  std::tie(FID, Offset) = getDecomposedLoc(Loc);
   if (FID.isInvalid())
     return Loc;
 
@@ -2160,7 +2119,7 @@
   unsigned NumLineNumsComputed = 0;
   unsigned NumFileBytesMapped = 0;
   for (fileinfo_iterator I = fileinfo_begin(), E = fileinfo_end(); I != E; ++I){
-    NumLineNumsComputed += I->second->SourceLineCache != 0;
+    NumLineNumsComputed += I->second->SourceLineCache != nullptr;
     NumFileBytesMapped  += I->second->getSizeBytesMapped();
   }
   unsigned NumMacroArgsComputed = MacroArgsCacheMap.size();
diff --git a/lib/Basic/TargetInfo.cpp b/lib/Basic/TargetInfo.cpp
index e993055..aecf13b 100644
--- a/lib/Basic/TargetInfo.cpp
+++ b/lib/Basic/TargetInfo.cpp
@@ -52,7 +52,6 @@
   SizeType = UnsignedLong;
   PtrDiffType = SignedLong;
   IntMaxType = SignedLongLong;
-  UIntMaxType = UnsignedLongLong;
   IntPtrType = SignedLong;
   WCharType = SignedInt;
   WIntType = SignedInt;
@@ -69,8 +68,7 @@
   FloatFormat = &llvm::APFloat::IEEEsingle;
   DoubleFormat = &llvm::APFloat::IEEEdouble;
   LongDoubleFormat = &llvm::APFloat::IEEEdouble;
-  DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
-                      "i64:64:64-f32:32:32-f64:64:64-n32";
+  DescriptionString = nullptr;
   UserLabelPrefix = "_";
   MCountName = "mcount";
   RegParmMax = 0;
@@ -83,8 +81,10 @@
   // Default to not using fp2ret for __Complex long double
   ComplexLongDoubleUsesFP2Ret = false;
 
-  // Default to using the Itanium ABI.
-  TheCXXABI.set(TargetCXXABI::GenericItanium);
+  // Set the C++ ABI based on the triple.
+  TheCXXABI.set(Triple.isKnownWindowsMSVCEnvironment()
+                    ? TargetCXXABI::Microsoft
+                    : TargetCXXABI::GenericItanium);
 
   // Default to an empty address space map.
   AddrSpaceMap = &DefaultAddrSpaceMap;
@@ -103,7 +103,7 @@
 const char *TargetInfo::getTypeName(IntType T) {
   switch (T) {
   default: llvm_unreachable("not an integer!");
-  case SignedChar:       return "char";
+  case SignedChar:       return "signed char";
   case UnsignedChar:     return "unsigned char";
   case SignedShort:      return "short";
   case UnsignedShort:    return "unsigned short";
@@ -118,7 +118,7 @@
 
 /// getTypeConstantSuffix - Return the constant suffix for the specified
 /// integer type enum. For example, SignedLong -> "L".
-const char *TargetInfo::getTypeConstantSuffix(IntType T) {
+const char *TargetInfo::getTypeConstantSuffix(IntType T) const {
   switch (T) {
   default: llvm_unreachable("not an integer!");
   case SignedChar:
@@ -127,13 +127,36 @@
   case SignedLong:       return "L";
   case SignedLongLong:   return "LL";
   case UnsignedChar:
+    if (getCharWidth() < getIntWidth())
+      return "";
   case UnsignedShort:
+    if (getShortWidth() < getIntWidth())
+      return "";
   case UnsignedInt:      return "U";
   case UnsignedLong:     return "UL";
   case UnsignedLongLong: return "ULL";
   }
 }
 
+/// getTypeFormatModifier - Return the printf format modifier for the
+/// specified integer type enum. For example, SignedLong -> "l".
+
+const char *TargetInfo::getTypeFormatModifier(IntType T) {
+  switch (T) {
+  default: llvm_unreachable("not an integer!");
+  case SignedChar:
+  case UnsignedChar:     return "hh";
+  case SignedShort:
+  case UnsignedShort:    return "h";
+  case SignedInt:
+  case UnsignedInt:      return "";
+  case SignedLong:
+  case UnsignedLong:     return "l";
+  case SignedLongLong:
+  case UnsignedLongLong: return "ll";
+  }
+}
+
 /// getTypeWidth - Return the width (in bits) of the specified integer type
 /// enum. For example, SignedInt -> getIntWidth().
 unsigned TargetInfo::getTypeWidth(IntType T) const {
@@ -167,6 +190,21 @@
   return NoInt;
 }
 
+TargetInfo::IntType TargetInfo::getLeastIntTypeByWidth(unsigned BitWidth,
+                                                       bool IsSigned) const {
+  if (getCharWidth() >= BitWidth)
+    return IsSigned ? SignedChar : UnsignedChar;
+  if (getShortWidth() >= BitWidth)
+    return IsSigned ? SignedShort : UnsignedShort;
+  if (getIntWidth() >= BitWidth)
+    return IsSigned ? SignedInt : UnsignedInt;
+  if (getLongWidth() >= BitWidth)
+    return IsSigned ? SignedLong : UnsignedLong;
+  if (getLongLongWidth() >= BitWidth)
+    return IsSigned ? SignedLongLong : UnsignedLongLong;
+  return NoInt;
+}
+
 TargetInfo::RealType TargetInfo::getRealTypeByWidth(unsigned BitWidth) const {
   if (getFloatWidth() == BitWidth)
     return Float;
@@ -226,10 +264,10 @@
   };
 }
 
-/// setForcedLangOptions - Set forced language options.
+/// adjust - Set forced language options.
 /// Apply changes to the target information with respect to certain
 /// language options which change the target configuration.
-void TargetInfo::setForcedLangOptions(LangOptions &Opts) {
+void TargetInfo::adjust(const LangOptions &Opts) {
   if (Opts.NoBitFieldTypeAlign)
     UseBitFieldTypeAlignment = false;
   if (Opts.ShortWChar)
@@ -245,7 +283,14 @@
     LongLongWidth = LongLongAlign = 128;
     HalfWidth = HalfAlign = 16;
     FloatWidth = FloatAlign = 32;
-    DoubleWidth = DoubleAlign = 64;
+    
+    // Embedded 32-bit targets (OpenCL EP) might have double C type 
+    // defined as float. Let's not override this as it might lead 
+    // to generating illegal code that uses 64bit doubles.
+    if (DoubleWidth != FloatWidth) {
+      DoubleWidth = DoubleAlign = 64;
+      DoubleFormat = &llvm::APFloat::IEEEdouble;
+    }
     LongDoubleWidth = LongDoubleAlign = 128;
 
     assert(PointerWidth == 32 || PointerWidth == 64);
@@ -255,12 +300,10 @@
     IntPtrType = Is32BitArch ? SignedInt : SignedLong;
 
     IntMaxType = SignedLongLong;
-    UIntMaxType = UnsignedLongLong;
     Int64Type = SignedLong;
 
     HalfFormat = &llvm::APFloat::IEEEhalf;
     FloatFormat = &llvm::APFloat::IEEEsingle;
-    DoubleFormat = &llvm::APFloat::IEEEdouble;
     LongDoubleFormat = &llvm::APFloat::IEEEquad;
   }
 }
@@ -483,6 +526,9 @@
                                          ConstraintInfo &Info) const {
   const char *Name = Info.ConstraintStr.c_str();
 
+  if (!*Name)
+    return false;
+
   while (*Name) {
     switch (*Name) {
     default:
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index 49a77d3..ef5c2e8 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -20,7 +20,6 @@
 #include "clang/Basic/TargetBuiltins.h"
 #include "clang/Basic/TargetOptions.h"
 #include "llvm/ADT/APFloat.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/StringSwitch.h"
@@ -29,6 +28,7 @@
 #include "llvm/MC/MCSectionMachO.h"
 #include "llvm/Support/ErrorHandling.h"
 #include <algorithm>
+#include <memory>
 using namespace clang;
 
 //===----------------------------------------------------------------------===//
@@ -74,8 +74,8 @@
                             MacroBuilder &Builder) const=0;
 public:
   OSTargetInfo(const llvm::Triple &Triple) : TgtInfo(Triple) {}
-  virtual void getTargetDefines(const LangOptions &Opts,
-                                MacroBuilder &Builder) const {
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override {
     TgtInfo::getTargetDefines(Opts, Builder);
     getOSDefines(Opts, TgtInfo::getTriple(), Builder);
   }
@@ -90,7 +90,6 @@
                              VersionTuple &PlatformMinVersion) {
   Builder.defineMacro("__APPLE_CC__", "6000");
   Builder.defineMacro("__APPLE__");
-  Builder.defineMacro("__MACH__");
   Builder.defineMacro("OBJC_NEW_PROPERTIES");
   // AddressSanitizer doesn't play well with source fortification, which is on
   // by default on Darwin.
@@ -148,25 +147,38 @@
     Str[3] = '0' + (Rev / 10);
     Str[4] = '0' + (Rev % 10);
     Str[5] = '\0';
-    Builder.defineMacro("__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__", Str);
-  } else if (Triple.getArchName() != "thumbv6m" &&
-             Triple.getArchName() != "thumbv7m" &&
-             Triple.getArchName() != "thumbv7em") {
+    Builder.defineMacro("__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__",
+                        Str);
+  } else if (Triple.isMacOSX()) {
     // Note that the Driver allows versions which aren't representable in the
     // define (because we only get a single digit for the minor and micro
     // revision numbers). So, we limit them to the maximum representable
     // version.
-    assert(Triple.getEnvironmentName().empty() && "Invalid environment!");
     assert(Maj < 100 && Min < 100 && Rev < 100 && "Invalid version!");
-    char Str[5];
-    Str[0] = '0' + (Maj / 10);
-    Str[1] = '0' + (Maj % 10);
-    Str[2] = '0' + std::min(Min, 9U);
-    Str[3] = '0' + std::min(Rev, 9U);
-    Str[4] = '\0';
+    char Str[7];
+    if (Maj < 10 || (Maj == 10 && Min < 10)) {
+      Str[0] = '0' + (Maj / 10);
+      Str[1] = '0' + (Maj % 10);
+      Str[2] = '0' + std::min(Min, 9U);
+      Str[3] = '0' + std::min(Rev, 9U);
+      Str[4] = '\0';
+    } else {
+      // Handle versions > 10.9.
+      Str[0] = '0' + (Maj / 10);
+      Str[1] = '0' + (Maj % 10);
+      Str[2] = '0' + (Min / 10);
+      Str[3] = '0' + (Min % 10);
+      Str[4] = '0' + (Rev / 10);
+      Str[5] = '0' + (Rev % 10);
+      Str[6] = '\0';
+    }
     Builder.defineMacro("__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__", Str);
   }
 
+  // Tell users about the kernel if there is one.
+  if (Triple.isOSDarwin())
+    Builder.defineMacro("__MACH__");
+
   PlatformMinVersion = VersionTuple(Maj, Min, Rev);
 }
 
@@ -174,8 +186,8 @@
 template<typename Target>
 class DarwinTargetInfo : public OSTargetInfo<Target> {
 protected:
-  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
-                            MacroBuilder &Builder) const {
+  void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+                    MacroBuilder &Builder) const override {
     getDarwinDefines(Builder, Opts, Triple, this->PlatformName,
                      this->PlatformMinVersion);
   }
@@ -186,7 +198,7 @@
     this->MCountName = "\01mcount";
   }
 
-  virtual std::string isValidSectionSpecifier(StringRef SR) const {
+  std::string isValidSectionSpecifier(StringRef SR) const override {
     // Let MCSectionMachO validate this.
     StringRef Segment, Section;
     unsigned TAA, StubSize;
@@ -195,7 +207,7 @@
                                                        TAA, HasTAA, StubSize);
   }
 
-  virtual const char *getStaticInitSectionSpecifier() const {
+  const char *getStaticInitSectionSpecifier() const override {
     // FIXME: We should return 0 when building kexts.
     return "__TEXT,__StaticInit,regular,pure_instructions";
   }
@@ -203,7 +215,7 @@
   /// Darwin does not support protected visibility.  Darwin's "default"
   /// is very similar to ELF's "protected";  Darwin requires a "weak"
   /// attribute on declarations that can be dynamically replaced.
-  virtual bool hasProtectedVisibility() const {
+  bool hasProtectedVisibility() const override {
     return false;
   }
 };
@@ -213,8 +225,8 @@
 template<typename Target>
 class DragonFlyBSDTargetInfo : public OSTargetInfo<Target> {
 protected:
-  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
-                            MacroBuilder &Builder) const {
+  void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+                    MacroBuilder &Builder) const override {
     // DragonFly defines; list based off of gcc output
     Builder.defineMacro("__DragonFly__");
     Builder.defineMacro("__DragonFly_cc_version", "100001");
@@ -281,8 +293,8 @@
 template<typename Target>
 class FreeBSDTargetInfo : public OSTargetInfo<Target> {
 protected:
-  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
-                            MacroBuilder &Builder) const {
+  void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+                    MacroBuilder &Builder) const override {
     // FreeBSD defines; list based off of gcc output
 
     unsigned Release = Triple.getOSMajorVersion();
@@ -328,8 +340,8 @@
 template<typename Target>
 class KFreeBSDTargetInfo : public OSTargetInfo<Target> {
 protected:
-  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
-                            MacroBuilder &Builder) const {
+  void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+                    MacroBuilder &Builder) const override {
     // GNU/kFreeBSD defines; list based off of gcc output
 
     DefineStd(Builder, "unix", Opts);
@@ -351,8 +363,8 @@
 template<typename Target>
 class MinixTargetInfo : public OSTargetInfo<Target> {
 protected:
-  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
-                            MacroBuilder &Builder) const {
+  void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+                    MacroBuilder &Builder) const override {
     // Minix defines
 
     Builder.defineMacro("__minix", "3");
@@ -375,8 +387,8 @@
 template<typename Target>
 class LinuxTargetInfo : public OSTargetInfo<Target> {
 protected:
-  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
-                            MacroBuilder &Builder) const {
+  void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+                    MacroBuilder &Builder) const override {
     // Linux defines; list based off of gcc output
     DefineStd(Builder, "unix", Opts);
     DefineStd(Builder, "linux", Opts);
@@ -393,9 +405,19 @@
   LinuxTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
     this->UserLabelPrefix = "";
     this->WIntType = TargetInfo::UnsignedInt;
+
+    switch (Triple.getArch()) {
+    default:
+      break;
+    case llvm::Triple::ppc:
+    case llvm::Triple::ppc64:
+    case llvm::Triple::ppc64le:
+      this->MCountName = "_mcount";
+      break;
+    }
   }
 
-  virtual const char *getStaticInitSectionSpecifier() const {
+  const char *getStaticInitSectionSpecifier() const override {
     return ".text.startup";
   }
 };
@@ -404,14 +426,25 @@
 template<typename Target>
 class NetBSDTargetInfo : public OSTargetInfo<Target> {
 protected:
-  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
-                            MacroBuilder &Builder) const {
+  void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+                    MacroBuilder &Builder) const override {
     // NetBSD defines; list based off of gcc output
     Builder.defineMacro("__NetBSD__");
     Builder.defineMacro("__unix__");
     Builder.defineMacro("__ELF__");
     if (Opts.POSIXThreads)
       Builder.defineMacro("_POSIX_THREADS");
+
+    switch (Triple.getArch()) {
+    default:
+      break;
+    case llvm::Triple::arm:
+    case llvm::Triple::armeb:
+    case llvm::Triple::thumb:
+    case llvm::Triple::thumbeb:
+      Builder.defineMacro("__ARM_DWARF_EH__");
+      break;
+    }
   }
 public:
   NetBSDTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
@@ -423,8 +456,8 @@
 template<typename Target>
 class OpenBSDTargetInfo : public OSTargetInfo<Target> {
 protected:
-  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
-                            MacroBuilder &Builder) const {
+  void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+                    MacroBuilder &Builder) const override {
     // OpenBSD defines; list based off of gcc output
 
     Builder.defineMacro("__OpenBSD__");
@@ -460,8 +493,8 @@
 template<typename Target>
 class BitrigTargetInfo : public OSTargetInfo<Target> {
 protected:
-  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
-                            MacroBuilder &Builder) const {
+  void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+                    MacroBuilder &Builder) const override {
     // Bitrig defines; list based off of gcc output
 
     Builder.defineMacro("__Bitrig__");
@@ -473,7 +506,6 @@
 public:
   BitrigTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
     this->UserLabelPrefix = "";
-    this->TLSSupported = false;
     this->MCountName = "__mcount";
   }
 };
@@ -482,8 +514,8 @@
 template<typename Target>
 class PSPTargetInfo : public OSTargetInfo<Target> {
 protected:
-  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
-                            MacroBuilder &Builder) const {
+  void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+                    MacroBuilder &Builder) const override {
     // PSP defines; list based on the output of the pspdev gcc toolchain.
     Builder.defineMacro("PSP");
     Builder.defineMacro("_PSP");
@@ -500,8 +532,8 @@
 template<typename Target>
 class PS3PPUTargetInfo : public OSTargetInfo<Target> {
 protected:
-  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
-                            MacroBuilder &Builder) const {
+  void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+                    MacroBuilder &Builder) const override {
     // PS3 PPU defines.
     Builder.defineMacro("__PPC__");
     Builder.defineMacro("__PPU__");
@@ -517,28 +549,9 @@
     this->LongWidth = this->LongAlign = 32;
     this->PointerWidth = this->PointerAlign = 32;
     this->IntMaxType = TargetInfo::SignedLongLong;
-    this->UIntMaxType = TargetInfo::UnsignedLongLong;
     this->Int64Type = TargetInfo::SignedLongLong;
     this->SizeType = TargetInfo::UnsignedInt;
-    this->DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
-                              "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32";
-  }
-};
-
-// FIXME: Need a real SPU target.
-// PS3 SPU Target
-template<typename Target>
-class PS3SPUTargetInfo : public OSTargetInfo<Target> {
-protected:
-  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
-                            MacroBuilder &Builder) const {
-    // PS3 PPU defines.
-    Builder.defineMacro("__SPU__");
-    Builder.defineMacro("__ELF__");
-  }
-public:
-  PS3SPUTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {
-    this->UserLabelPrefix = "";
+    this->DescriptionString = "E-m:e-p:32:32-i64:64-n32:64";
   }
 };
 
@@ -546,8 +559,8 @@
 template<typename Target>
 class AuroraUXTargetInfo : public OSTargetInfo<Target> {
 protected:
-  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
-                            MacroBuilder &Builder) const {
+  void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+                    MacroBuilder &Builder) const override {
     DefineStd(Builder, "sun", Opts);
     DefineStd(Builder, "unix", Opts);
     Builder.defineMacro("__ELF__");
@@ -567,8 +580,8 @@
 template<typename Target>
 class SolarisTargetInfo : public OSTargetInfo<Target> {
 protected:
-  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
-                            MacroBuilder &Builder) const {
+  void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+                    MacroBuilder &Builder) const override {
     DefineStd(Builder, "sun", Opts);
     DefineStd(Builder, "unix", Opts);
     Builder.defineMacro("__ELF__");
@@ -601,14 +614,14 @@
 template<typename Target>
 class WindowsTargetInfo : public OSTargetInfo<Target> {
 protected:
-  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
-                            MacroBuilder &Builder) const {
+  void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+                    MacroBuilder &Builder) const override {
     Builder.defineMacro("_WIN32");
   }
   void getVisualStudioDefines(const LangOptions &Opts,
                               MacroBuilder &Builder) const {
     if (Opts.CPlusPlus) {
-      if (Opts.RTTI)
+      if (Opts.RTTIData)
         Builder.defineMacro("_CPPRTTI");
 
       if (Opts.Exceptions)
@@ -623,8 +636,13 @@
     if (Opts.POSIXThreads)
       Builder.defineMacro("_MT");
 
-    if (Opts.MSCVersion != 0)
-      Builder.defineMacro("_MSC_VER", Twine(Opts.MSCVersion));
+    if (Opts.MSCompatibilityVersion) {
+      Builder.defineMacro("_MSC_VER",
+                          Twine(Opts.MSCompatibilityVersion / 100000));
+      Builder.defineMacro("_MSC_FULL_VER", Twine(Opts.MSCompatibilityVersion));
+      // FIXME We cannot encode the revision information into 32-bits
+      Builder.defineMacro("_MSC_BUILD", Twine(1));
+    }
 
     if (Opts.MicrosoftExt) {
       Builder.defineMacro("_MSC_EXTENSIONS");
@@ -647,8 +665,8 @@
 template <typename Target>
 class NaClTargetInfo : public OSTargetInfo<Target> {
 protected:
-  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
-                            MacroBuilder &Builder) const {
+  void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+                    MacroBuilder &Builder) const override {
     if (Opts.POSIXThreads)
       Builder.defineMacro("_REENTRANT");
     if (Opts.CPlusPlus)
@@ -667,7 +685,6 @@
     this->PointerAlign = 32;
     this->PointerWidth = 32;
     this->IntMaxType = TargetInfo::SignedLongLong;
-    this->UIntMaxType = TargetInfo::UnsignedLongLong;
     this->Int64Type = TargetInfo::SignedLongLong;
     this->DoubleAlign = 64;
     this->LongDoubleWidth = 64;
@@ -679,11 +696,22 @@
     this->IntPtrType = TargetInfo::SignedInt;
     // RegParmMax is inherited from the underlying architecture
     this->LongDoubleFormat = &llvm::APFloat::IEEEdouble;
-    this->DescriptionString = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-"
-                              "f32:32:32-f64:64:64-p:32:32:32-v128:32:32";
+    if (Triple.getArch() == llvm::Triple::arm) {
+      // @LOCALMOD
+      // Handled in ARM's setABI().
+    } else if (Triple.getArch() == llvm::Triple::x86) {
+      this->DescriptionString = "e-m:e-p:32:32-i64:64-f80:32-n8:16:32-S128";
+    } else if (Triple.getArch() == llvm::Triple::x86_64) {
+      this->DescriptionString = "e-m:e-p:32:32-i64:64-f80:128-n8:16:32:64-S128";
+    } else if (Triple.getArch() == llvm::Triple::mipsel) {
+      // Handled on mips' setDescriptionString.
+    } else {
+      assert(Triple.getArch() == llvm::Triple::le32);
+      this->DescriptionString = "e-p:32:32-i64:64";
+    }
   }
-  virtual typename Target::CallingConvCheckResult checkCallingConvention(
-      CallingConv CC) const {
+  typename Target::CallingConvCheckResult checkCallingConvention(
+      CallingConv CC) const override {
     return CC == CC_PnaclCall ? Target::CCCR_OK :
         Target::checkCallingConvention(CC);
   }
@@ -728,15 +756,16 @@
     ArchDefinePwr6  = 1 << 9,
     ArchDefinePwr6x = 1 << 10,
     ArchDefinePwr7  = 1 << 11,
-    ArchDefineA2    = 1 << 12,
-    ArchDefineA2q   = 1 << 13
+    ArchDefinePwr8  = 1 << 12,
+    ArchDefineA2    = 1 << 13,
+    ArchDefineA2q   = 1 << 14
   } ArchDefineTypes;
 
   // Note: GCC recognizes the following additional cpus:
   //  401, 403, 405, 405fp, 440fp, 464, 464fp, 476, 476fp, 505, 740, 801,
   //  821, 823, 8540, 8548, e300c2, e300c3, e500mc64, e6500, 860, cell,
   //  titan, rs64.
-  virtual bool setCPU(const std::string &Name) {
+  bool setCPU(const std::string &Name) override {
     bool CPUKnown = llvm::StringSwitch<bool>(Name)
       .Case("generic", true)
       .Case("440", true)
@@ -776,6 +805,8 @@
       .Case("pwr6x", true)
       .Case("power7", true)
       .Case("pwr7", true)
+      .Case("power8", true)
+      .Case("pwr8", true)
       .Case("powerpc", true)
       .Case("ppc", true)
       .Case("powerpc64", true)
@@ -790,29 +821,29 @@
     return CPUKnown;
   }
 
-  virtual void getTargetBuiltins(const Builtin::Info *&Records,
-                                 unsigned &NumRecords) const {
+  void getTargetBuiltins(const Builtin::Info *&Records,
+                         unsigned &NumRecords) const override {
     Records = BuiltinInfo;
     NumRecords = clang::PPC::LastTSBuiltin-Builtin::FirstTSBuiltin;
   }
 
-  virtual bool isCLZForZeroUndef() const { return false; }
+  bool isCLZForZeroUndef() const override { return false; }
 
-  virtual void getTargetDefines(const LangOptions &Opts,
-                                MacroBuilder &Builder) const;
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override;
 
-  virtual void getDefaultFeatures(llvm::StringMap<bool> &Features) const;
+  void getDefaultFeatures(llvm::StringMap<bool> &Features) const override;
 
-  virtual bool handleTargetFeatures(std::vector<std::string> &Features,
-                                    DiagnosticsEngine &Diags);
-  virtual bool hasFeature(StringRef Feature) const;
-  
-  virtual void getGCCRegNames(const char * const *&Names,
-                              unsigned &NumNames) const;
-  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
-                                unsigned &NumAliases) const;
-  virtual bool validateAsmConstraint(const char *&Name,
-                                     TargetInfo::ConstraintInfo &Info) const {
+  bool handleTargetFeatures(std::vector<std::string> &Features,
+                            DiagnosticsEngine &Diags) override;
+  bool hasFeature(StringRef Feature) const override;
+
+  void getGCCRegNames(const char * const *&Names,
+                      unsigned &NumNames) const override;
+  void getGCCRegAliases(const GCCRegAlias *&Aliases,
+                        unsigned &NumAliases) const override;
+  bool validateAsmConstraint(const char *&Name,
+                             TargetInfo::ConstraintInfo &Info) const override {
     switch (*Name) {
     default: return false;
     case 'O': // Zero
@@ -834,6 +865,7 @@
         case 'f':// VSX vector register to hold vector float data
         case 's':// VSX vector register to hold scalar float data
         case 'a':// Any VSX register
+        case 'c':// An individual CR bit
           break;
         default:
           return false;
@@ -909,10 +941,24 @@
     }
     return true;
   }
-  virtual const char *getClobbers() const {
+  std::string convertConstraint(const char *&Constraint) const override {
+    std::string R;
+    switch (*Constraint) {
+    case 'e':
+    case 'w':
+      // Two-character constraint; add "^" hint for later parsing.
+      R = std::string("^") + std::string(Constraint, 2);
+      Constraint++;
+      break;
+    default:
+      return TargetInfo::convertConstraint(Constraint);
+    }
+    return R;
+  }
+  const char *getClobbers() const override {
     return "";
   }
-  int getEHDataRegisterNumber(unsigned RegNo) const {
+  int getEHDataRegisterNumber(unsigned RegNo) const override {
     if (RegNo == 0) return 3;
     if (RegNo == 1) return 4;
     return -1;
@@ -970,12 +1016,11 @@
   // Target properties.
   if (getTriple().getArch() == llvm::Triple::ppc64le) {
     Builder.defineMacro("_LITTLE_ENDIAN");
-    Builder.defineMacro("__LITTLE_ENDIAN__");
+    Builder.defineMacro("_CALL_ELF","2");
   } else {
     if (getTriple().getOS() != llvm::Triple::NetBSD &&
         getTriple().getOS() != llvm::Triple::OpenBSD)
       Builder.defineMacro("_BIG_ENDIAN");
-    Builder.defineMacro("__BIG_ENDIAN__");
   }
 
   // Subtarget options.
@@ -1024,7 +1069,10 @@
                      | ArchDefinePpcsq)
     .Case("pwr7",  ArchDefineName | ArchDefinePwr6x | ArchDefinePwr6
                      | ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4
-                     | ArchDefinePwr6 | ArchDefinePpcgr | ArchDefinePpcsq)
+                     | ArchDefinePpcgr | ArchDefinePpcsq)
+    .Case("pwr8",  ArchDefineName | ArchDefinePwr7 | ArchDefinePwr6x
+                     | ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5
+                     | ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
     .Case("power3",  ArchDefinePpcgr)
     .Case("power4",  ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
     .Case("power5",  ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr
@@ -1038,7 +1086,10 @@
                        | ArchDefinePpcsq)
     .Case("power7",  ArchDefinePwr7 | ArchDefinePwr6x | ArchDefinePwr6
                        | ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4
-                       | ArchDefinePwr6 | ArchDefinePpcgr | ArchDefinePpcsq)
+                       | ArchDefinePpcgr | ArchDefinePpcsq)
+    .Case("power8",  ArchDefinePwr8 | ArchDefinePwr7 | ArchDefinePwr6x
+                       | ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5
+                       | ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
     .Default(ArchDefineNone);
 
   if (defs & ArchDefineName)
@@ -1065,6 +1116,8 @@
     Builder.defineMacro("_ARCH_PWR6X");
   if (defs & ArchDefinePwr7)
     Builder.defineMacro("_ARCH_PWR7");
+  if (defs & ArchDefinePwr8)
+    Builder.defineMacro("_ARCH_PWR8");
   if (defs & ArchDefineA2)
     Builder.defineMacro("_ARCH_A2");
   if (defs & ArchDefineA2q) {
@@ -1113,6 +1166,7 @@
     .Case("g5", true)
     .Case("pwr6", true)
     .Case("pwr7", true)
+    .Case("pwr8", true)
     .Case("ppc64", true)
     .Case("ppc64le", true)
     .Default(false);
@@ -1233,8 +1287,7 @@
 class PPC32TargetInfo : public PPCTargetInfo {
 public:
   PPC32TargetInfo(const llvm::Triple &Triple) : PPCTargetInfo(Triple) {
-    DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
-                        "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32";
+    DescriptionString = "E-m:e-p:32:32-i64:64-n32";
 
     switch (getTriple().getOS()) {
     case llvm::Triple::Linux:
@@ -1257,7 +1310,7 @@
     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32;
   }
 
-  virtual BuiltinVaListKind getBuiltinVaListKind() const {
+  BuiltinVaListKind getBuiltinVaListKind() const override {
     // This is the ELF definition, and is overridden by the Darwin sub-target
     return TargetInfo::PowerABIBuiltinVaList;
   }
@@ -1272,24 +1325,24 @@
   PPC64TargetInfo(const llvm::Triple &Triple) : PPCTargetInfo(Triple) {
     LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
     IntMaxType = SignedLong;
-    UIntMaxType = UnsignedLong;
     Int64Type = SignedLong;
 
     if (getTriple().getOS() == llvm::Triple::FreeBSD) {
       LongDoubleWidth = LongDoubleAlign = 64;
       LongDoubleFormat = &llvm::APFloat::IEEEdouble;
-      DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
-                          "i64:64:64-f32:32:32-f64:64:64-"
-                          "v128:128:128-n32:64";
-    } else
-      DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
-                          "i64:64:64-f32:32:32-f64:64:64-f128:128:128-"
-                          "v128:128:128-n32:64";
+      DescriptionString = "E-m:e-i64:64-n32:64";
+    } else {
+      if ((Triple.getArch() == llvm::Triple::ppc64le)) {
+        DescriptionString = "e-m:e-i64:64-n32:64";
+      } else {
+        DescriptionString = "E-m:e-i64:64-n32:64";
+      }
+}
 
     // PPC64 supports atomics up to 8 bytes.
     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
   }
-  virtual BuiltinVaListKind getBuiltinVaListKind() const {
+  BuiltinVaListKind getBuiltinVaListKind() const override {
     return TargetInfo::CharPtrBuiltinVaList;
   }
 };
@@ -1307,10 +1360,9 @@
     PtrDiffType = SignedInt;    // for http://llvm.org/bugs/show_bug.cgi?id=15726
     LongLongAlign = 32;
     SuitableAlign = 128;
-    DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
-                        "i64:32:64-f32:32:32-f64:64:64-v128:128:128-n32";
+    DescriptionString = "E-m:o-p:32:32-f64:32:64-n32";
   }
-  virtual BuiltinVaListKind getBuiltinVaListKind() const {
+  BuiltinVaListKind getBuiltinVaListKind() const override {
     return TargetInfo::CharPtrBuiltinVaList;
   }
 };
@@ -1322,8 +1374,7 @@
       : DarwinTargetInfo<PPC64TargetInfo>(Triple) {
     HasAlignMac68kSupport = true;
     SuitableAlign = 128;
-    DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
-                        "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64";
+    DescriptionString = "E-m:o-i64:64-n32:64";
   }
 };
 } // end anonymous namespace.
@@ -1351,30 +1402,30 @@
       // These must be defined in sorted order!
       NoAsmVariants = true;
     }
-    virtual void getTargetDefines(const LangOptions &Opts,
-                                  MacroBuilder &Builder) const {
+    void getTargetDefines(const LangOptions &Opts,
+                          MacroBuilder &Builder) const override {
       Builder.defineMacro("__PTX__");
       Builder.defineMacro("__NVPTX__");
     }
-    virtual void getTargetBuiltins(const Builtin::Info *&Records,
-                                   unsigned &NumRecords) const {
+    void getTargetBuiltins(const Builtin::Info *&Records,
+                           unsigned &NumRecords) const override {
       Records = BuiltinInfo;
       NumRecords = clang::NVPTX::LastTSBuiltin-Builtin::FirstTSBuiltin;
     }
-    virtual bool hasFeature(StringRef Feature) const {
+    bool hasFeature(StringRef Feature) const override {
       return Feature == "ptx" || Feature == "nvptx";
     }
-    
-    virtual void getGCCRegNames(const char * const *&Names,
-                                unsigned &NumNames) const;
-    virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
-                                  unsigned &NumAliases) const {
+
+    void getGCCRegNames(const char * const *&Names,
+                        unsigned &NumNames) const override;
+    void getGCCRegAliases(const GCCRegAlias *&Aliases,
+                                  unsigned &NumAliases) const override {
       // No aliases.
-      Aliases = 0;
+      Aliases = nullptr;
       NumAliases = 0;
     }
-    virtual bool validateAsmConstraint(const char *&Name,
-                                       TargetInfo::ConstraintInfo &Info) const {
+    bool validateAsmConstraint(const char *&Name,
+                               TargetInfo::ConstraintInfo &Info) const override {
       switch (*Name) {
       default: return false;
       case 'c':
@@ -1387,15 +1438,15 @@
         return true;
       }
     }
-    virtual const char *getClobbers() const {
+    const char *getClobbers() const override {
       // FIXME: Is this really right?
       return "";
     }
-    virtual BuiltinVaListKind getBuiltinVaListKind() const {
+    BuiltinVaListKind getBuiltinVaListKind() const override {
       // FIXME: implement
       return TargetInfo::CharPtrBuiltinVaList;
     }
-    virtual bool setCPU(const std::string &Name) {
+    bool setCPU(const std::string &Name) override {
       bool Valid = llvm::StringSwitch<bool>(Name)
         .Case("sm_20", true)
         .Case("sm_21", true)
@@ -1428,11 +1479,9 @@
   public:
     NVPTX32TargetInfo(const llvm::Triple &Triple) : NVPTXTargetInfo(Triple) {
       PointerWidth = PointerAlign = 32;
-      SizeType     = PtrDiffType = IntPtrType = TargetInfo::UnsignedInt;
-      DescriptionString
-        = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-"
-          "f32:32:32-f64:64:64-v16:16:16-v32:32:32-v64:64:64-v128:128:128-"
-          "n16:32:64";
+      SizeType     = PtrDiffType = TargetInfo::UnsignedInt;
+      IntPtrType = TargetInfo::SignedInt;
+      DescriptionString = "e-p:32:32-i64:64-v16:16-v32:32-n16:32:64";
   }
   };
 
@@ -1440,11 +1489,9 @@
   public:
     NVPTX64TargetInfo(const llvm::Triple &Triple) : NVPTXTargetInfo(Triple) {
       PointerWidth = PointerAlign = 64;
-      SizeType     = PtrDiffType = IntPtrType = TargetInfo::UnsignedLongLong;
-      DescriptionString
-        = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-"
-          "f32:32:32-f64:64:64-v16:16:16-v32:32:32-v64:64:64-v128:128:128-"
-          "n16:32:64";
+      SizeType     = PtrDiffType = TargetInfo::UnsignedLongLong;
+      IntPtrType = TargetInfo::SignedLongLong;
+      DescriptionString = "e-i64:64-v16:16-v32:32-n16:32:64";
   }
   };
 }
@@ -1461,31 +1508,21 @@
 };
 
 static const char *DescriptionStringR600 =
-  "e"
-  "-p:32:32:32"
-  "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32"
-  "-v16:16:16-v24:32:32-v32:32:32-v48:64:64-v64:64:64-v96:128:128-v128:128:128"
-  "-v192:256:256-v256:256:256-v512:512:512-v1024:1024:1024-v2048:2048:2048"
-  "-n32:64";
+  "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128"
+  "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64";
 
 static const char *DescriptionStringR600DoubleOps =
-  "e"
-  "-p:32:32:32"
-  "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64"
-  "-v16:16:16-v24:32:32-v32:32:32-v48:64:64-v64:64:64-v96:128:128-v128:128:128"
-  "-v192:256:256-v256:256:256-v512:512:512-v1024:1024:1024-v2048:2048:2048"
-  "-n32:64";
+  "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128"
+  "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64";
 
 static const char *DescriptionStringSI =
-  "e"
-  "-p:64:64:64"
-  "-p3:32:32:32"
-  "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64"
-  "-v16:16:16-v24:32:32-v32:32:32-v48:64:64-v64:64:64-v96:128:128-v128:128:128"
-  "-v192:256:256-v256:256:256-v512:512:512-v1024:1024:1024-v2048:2048:2048"
-  "-n32:64";
+  "e-p:32:32-p1:64:64-p2:64:64-p3:32:32-p4:64:64-p5:32:32-p24:64:64"
+  "-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128"
+  "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64";
 
 class R600TargetInfo : public TargetInfo {
+  static const Builtin::Info BuiltinInfo[];
+
   /// \brief The GPU profiles supported by the R600 target.
   enum GPUKind {
     GK_NONE,
@@ -1509,44 +1546,43 @@
     UseAddrSpaceMapMangling = true;
   }
 
-  virtual const char * getClobbers() const {
+  const char * getClobbers() const override {
     return "";
   }
 
-  virtual void getGCCRegNames(const char * const *&Names,
-                              unsigned &numNames) const  {
-    Names = NULL;
+  void getGCCRegNames(const char * const *&Names,
+                      unsigned &numNames) const override {
+    Names = nullptr;
     numNames = 0;
   }
 
-  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
-                                unsigned &NumAliases) const {
-    Aliases = NULL;
+  void getGCCRegAliases(const GCCRegAlias *&Aliases,
+                        unsigned &NumAliases) const override {
+    Aliases = nullptr;
     NumAliases = 0;
   }
 
-  virtual bool validateAsmConstraint(const char *&Name,
-                                     TargetInfo::ConstraintInfo &info) const {
+  bool validateAsmConstraint(const char *&Name,
+                             TargetInfo::ConstraintInfo &info) const override {
     return true;
   }
 
-  virtual void getTargetBuiltins(const Builtin::Info *&Records,
-                                 unsigned &NumRecords) const {
-    Records = NULL;
-    NumRecords = 0;
+  void getTargetBuiltins(const Builtin::Info *&Records,
+                         unsigned &NumRecords) const override {
+    Records = BuiltinInfo;
+    NumRecords = clang::R600::LastTSBuiltin - Builtin::FirstTSBuiltin;
   }
 
-
-  virtual void getTargetDefines(const LangOptions &Opts,
-                                MacroBuilder &Builder) const {
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override {
     Builder.defineMacro("__R600__");
   }
 
-  virtual BuiltinVaListKind getBuiltinVaListKind() const {
+  BuiltinVaListKind getBuiltinVaListKind() const override {
     return TargetInfo::CharPtrBuiltinVaList;
   }
 
-  virtual bool setCPU(const std::string &Name) {
+  bool setCPU(const std::string &Name) override {
     GPU = llvm::StringSwitch<GPUKind>(Name)
       .Case("r600" ,    GK_R600)
       .Case("rv610",    GK_R600)
@@ -1581,6 +1617,7 @@
       .Case("kabini",   GK_SEA_ISLANDS)
       .Case("kaveri",   GK_SEA_ISLANDS)
       .Case("hawaii",   GK_SEA_ISLANDS)
+      .Case("mullins",  GK_SEA_ISLANDS)
       .Default(GK_NONE);
 
     if (GPU == GK_NONE) {
@@ -1612,6 +1649,12 @@
   }
 };
 
+const Builtin::Info R600TargetInfo::BuiltinInfo[] = {
+#define BUILTIN(ID, TYPE, ATTRS)                \
+  { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
+#include "clang/Basic/BuiltinsR600.def"
+};
+
 } // end anonymous namespace
 
 namespace {
@@ -1811,6 +1854,7 @@
     CK_BDVER1,
     CK_BDVER2,
     CK_BDVER3,
+    CK_BDVER4,
     //@}
 
     /// This specification is deprecated and will be removed in the future.
@@ -1844,57 +1888,57 @@
     BigEndian = false;
     LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
   }
-  virtual unsigned getFloatEvalMethod() const {
+  unsigned getFloatEvalMethod() const override {
     // X87 evaluates with 80 bits "long double" precision.
     return SSELevel == NoSSE ? 2 : 0;
   }
-  virtual void getTargetBuiltins(const Builtin::Info *&Records,
-                                 unsigned &NumRecords) const {
+  void getTargetBuiltins(const Builtin::Info *&Records,
+                                 unsigned &NumRecords) const override {
     Records = BuiltinInfo;
     NumRecords = clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin;
   }
-  virtual void getGCCRegNames(const char * const *&Names,
-                              unsigned &NumNames) const {
+  void getGCCRegNames(const char * const *&Names,
+                      unsigned &NumNames) const override {
     Names = GCCRegNames;
     NumNames = llvm::array_lengthof(GCCRegNames);
   }
-  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
-                                unsigned &NumAliases) const {
-    Aliases = 0;
+  void getGCCRegAliases(const GCCRegAlias *&Aliases,
+                        unsigned &NumAliases) const override {
+    Aliases = nullptr;
     NumAliases = 0;
   }
-  virtual void getGCCAddlRegNames(const AddlRegName *&Names,
-                                  unsigned &NumNames) const {
+  void getGCCAddlRegNames(const AddlRegName *&Names,
+                          unsigned &NumNames) const override {
     Names = AddlRegNames;
     NumNames = llvm::array_lengthof(AddlRegNames);
   }
-  virtual bool validateAsmConstraint(const char *&Name,
-                                     TargetInfo::ConstraintInfo &info) const;
-  virtual std::string convertConstraint(const char *&Constraint) const;
-  virtual const char *getClobbers() const {
+  bool validateAsmConstraint(const char *&Name,
+                                     TargetInfo::ConstraintInfo &info) const override;
+  std::string convertConstraint(const char *&Constraint) const override;
+  const char *getClobbers() const override {
     return "~{dirflag},~{fpsr},~{flags}";
   }
-  virtual void getTargetDefines(const LangOptions &Opts,
-                                MacroBuilder &Builder) const;
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override;
   static void setSSELevel(llvm::StringMap<bool> &Features, X86SSEEnum Level,
                           bool Enabled);
   static void setMMXLevel(llvm::StringMap<bool> &Features, MMX3DNowEnum Level,
                           bool Enabled);
   static void setXOPLevel(llvm::StringMap<bool> &Features, XOPEnum Level,
                           bool Enabled);
-  virtual void setFeatureEnabled(llvm::StringMap<bool> &Features,
-                                 StringRef Name, bool Enabled) const {
+  void setFeatureEnabled(llvm::StringMap<bool> &Features,
+                         StringRef Name, bool Enabled) const override {
     setFeatureEnabledImpl(Features, Name, Enabled);
   }
   // This exists purely to cut down on the number of virtual calls in
   // getDefaultFeatures which calls this repeatedly.
   static void setFeatureEnabledImpl(llvm::StringMap<bool> &Features,
                                     StringRef Name, bool Enabled);
-  virtual void getDefaultFeatures(llvm::StringMap<bool> &Features) const;
-  virtual bool hasFeature(StringRef Feature) const;
-  virtual bool handleTargetFeatures(std::vector<std::string> &Features,
-                                    DiagnosticsEngine &Diags);
-  virtual const char* getABI() const {
+  void getDefaultFeatures(llvm::StringMap<bool> &Features) const override;
+  bool hasFeature(StringRef Feature) const override;
+  bool handleTargetFeatures(std::vector<std::string> &Features,
+                            DiagnosticsEngine &Diags) override;
+  StringRef getABI() const override {
     if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX)
       return "avx";
     else if (getTriple().getArch() == llvm::Triple::x86 &&
@@ -1902,7 +1946,7 @@
       return "no-mmx";
     return "";
   }
-  virtual bool setCPU(const std::string &Name) {
+  bool setCPU(const std::string &Name) override {
     CPU = llvm::StringSwitch<CPUKind>(Name)
       .Case("i386", CK_i386)
       .Case("i486", CK_i486)
@@ -1954,6 +1998,7 @@
       .Case("bdver1", CK_BDVER1)
       .Case("bdver2", CK_BDVER2)
       .Case("bdver3", CK_BDVER3)
+      .Case("bdver4", CK_BDVER4)
       .Case("x86-64", CK_x86_64)
       .Case("geode", CK_Geode)
       .Default(CK_Generic);
@@ -2023,15 +2068,16 @@
     case CK_BDVER1:
     case CK_BDVER2:
     case CK_BDVER3:
+    case CK_BDVER4:
     case CK_x86_64:
       return true;
     }
     llvm_unreachable("Unhandled CPU kind");
   }
 
-  virtual bool setFPMath(StringRef Name);
+  bool setFPMath(StringRef Name) override;
 
-  virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const {
+  CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
     // We accept all non-ARM calling conventions
     return (CC == CC_X86ThisCall ||
             CC == CC_X86FastCall ||
@@ -2041,7 +2087,7 @@
             CC == CC_IntelOclBicc) ? CCCR_OK : CCCR_Warning;
   }
 
-  virtual CallingConv getDefaultCallingConv(CallingConvMethodType MT) const {
+  CallingConv getDefaultCallingConv(CallingConvMethodType MT) const override {
     return MT == CCMT_Member ? CC_X86ThisCall : CC_C;
   }
 };
@@ -2225,6 +2271,10 @@
     setFeatureEnabledImpl(Features, "prfchw", true);
     setFeatureEnabledImpl(Features, "cx16", true);
     break;
+  case CK_BDVER4:
+    setFeatureEnabledImpl(Features, "avx2", true);
+    setFeatureEnabledImpl(Features, "bmi2", true);
+    // FALLTHROUGH
   case CK_BDVER2:
   case CK_BDVER3:
     setFeatureEnabledImpl(Features, "xop", true);
@@ -2728,13 +2778,15 @@
   case CK_BDVER3:
     defineCPUMacros(Builder, "bdver3");
     break;
+  case CK_BDVER4:
+    defineCPUMacros(Builder, "bdver4");
+    break;
   case CK_Geode:
     defineCPUMacros(Builder, "geode");
     break;
   }
 
   // Target properties.
-  Builder.defineMacro("__LITTLE_ENDIAN__");
   Builder.defineMacro("__REGISTER_PREFIX__", "");
 
   // Define __NO_MATH_INLINES on linux/x86 so that we don't get inline
@@ -2927,6 +2979,13 @@
     case 'm':  // any MMX register, when inter-unit moves enabled.
       break;   // falls through to setAllowsRegister.
   }
+  case 'f': // any x87 floating point stack register.
+    // Constraint 'f' cannot be used for output operands.
+    if (Info.ConstraintStr[0] == '=')
+      return false;
+
+    Info.setAllowsRegister();
+    return true;
   case 'a': // eax.
   case 'b': // ebx.
   case 'c': // ecx.
@@ -2934,7 +2993,6 @@
   case 'S': // esi.
   case 'D': // edi.
   case 'A': // edx:eax.
-  case 'f': // any x87 floating point stack register.
   case 't': // top of floating point stack.
   case 'u': // second from top of floating point stack.
   case 'q': // Any register accessible as [r]l: a, b, c, and d.
@@ -2987,9 +3045,7 @@
     LongDoubleWidth = 96;
     LongDoubleAlign = 32;
     SuitableAlign = 128;
-    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
-                        "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
-                        "a0:0:64-f80:32:32-n8:16:32-S128";
+    DescriptionString = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128";
     SizeType = UnsignedInt;
     PtrDiffType = SignedInt;
     IntPtrType = SignedInt;
@@ -3005,17 +3061,17 @@
     // MaxAtomicInlineWidth. (cmpxchg8b is an i586 instruction.)
     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
   }
-  virtual BuiltinVaListKind getBuiltinVaListKind() const {
+  BuiltinVaListKind getBuiltinVaListKind() const override {
     return TargetInfo::CharPtrBuiltinVaList;
   }
 
-  int getEHDataRegisterNumber(unsigned RegNo) const {
+  int getEHDataRegisterNumber(unsigned RegNo) const override {
     if (RegNo == 0) return 0;
     if (RegNo == 1) return 2;
     return -1;
   }
-  virtual bool validateInputSize(StringRef Constraint,
-                                 unsigned Size) const {
+  bool validateInputSize(StringRef Constraint,
+                         unsigned Size) const override {
     switch (Constraint[0]) {
     default: break;
     case 'a':
@@ -3036,7 +3092,7 @@
   NetBSDI386TargetInfo(const llvm::Triple &Triple)
       : NetBSDTargetInfo<X86_32TargetInfo>(Triple) {}
 
-  virtual unsigned getFloatEvalMethod() const {
+  unsigned getFloatEvalMethod() const override {
     unsigned Major, Minor, Micro;
     getTriple().getOSVersion(Major, Minor, Micro);
     // New NetBSD uses the default rounding mode.
@@ -3083,9 +3139,7 @@
     MaxVectorAlign = 256;
     SizeType = UnsignedLong;
     IntPtrType = SignedLong;
-    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
-                        "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
-                        "a0:0:64-f80:128:128-n8:16:32-S128";
+    DescriptionString = "e-m:o-p:32:32-f64:32:64-f80:128-n8:16:32-S128";
     HasAlignMac68kSupport = true;
   }
 
@@ -3098,32 +3152,26 @@
 public:
   WindowsX86_32TargetInfo(const llvm::Triple &Triple)
       : WindowsTargetInfo<X86_32TargetInfo>(Triple) {
-    TLSSupported = false;
     WCharType = UnsignedShort;
     DoubleAlign = LongLongAlign = 64;
-    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
-                        "i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-"
-                        "v128:128:128-a0:0:64-f80:32:32-n8:16:32-S32";
+    DescriptionString = "e-m:w-p:32:32-i64:64-f80:32-n8:16:32-S32";
   }
-  virtual void getTargetDefines(const LangOptions &Opts,
-                                MacroBuilder &Builder) const {
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override {
     WindowsTargetInfo<X86_32TargetInfo>::getTargetDefines(Opts, Builder);
   }
 };
-} // end anonymous namespace
-
-namespace {
 
 // x86-32 Windows Visual Studio target
-class VisualStudioWindowsX86_32TargetInfo : public WindowsX86_32TargetInfo {
+class MicrosoftX86_32TargetInfo : public WindowsX86_32TargetInfo {
 public:
-  VisualStudioWindowsX86_32TargetInfo(const llvm::Triple &Triple)
+  MicrosoftX86_32TargetInfo(const llvm::Triple &Triple)
       : WindowsX86_32TargetInfo(Triple) {
     LongDoubleWidth = LongDoubleAlign = 64;
     LongDoubleFormat = &llvm::APFloat::IEEEdouble;
   }
-  virtual void getTargetDefines(const LangOptions &Opts,
-                                MacroBuilder &Builder) const {
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override {
     WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
     WindowsX86_32TargetInfo::getVisualStudioDefines(Opts, Builder);
     // The value of the following reflects processor type.
@@ -3134,29 +3182,46 @@
 };
 } // end anonymous namespace
 
+static void addMinGWDefines(const LangOptions &Opts, MacroBuilder &Builder) {
+  Builder.defineMacro("__MSVCRT__");
+  Builder.defineMacro("__MINGW32__");
+
+  // Mingw defines __declspec(a) to __attribute__((a)).  Clang supports
+  // __declspec natively under -fms-extensions, but we define a no-op __declspec
+  // macro anyway for pre-processor compatibility.
+  if (Opts.MicrosoftExt)
+    Builder.defineMacro("__declspec", "__declspec");
+  else
+    Builder.defineMacro("__declspec(a)", "__attribute__((a))");
+
+  if (!Opts.MicrosoftExt) {
+    // Provide macros for all the calling convention keywords.  Provide both
+    // single and double underscore prefixed variants.  These are available on
+    // x64 as well as x86, even though they have no effect.
+    const char *CCs[] = {"cdecl", "stdcall", "fastcall", "thiscall", "pascal"};
+    for (const char *CC : CCs) {
+      std::string GCCSpelling = "__attribute__((__";
+      GCCSpelling += CC;
+      GCCSpelling += "__))";
+      Builder.defineMacro(Twine("_") + CC, GCCSpelling);
+      Builder.defineMacro(Twine("__") + CC, GCCSpelling);
+    }
+  }
+}
+
 namespace {
 // x86-32 MinGW target
 class MinGWX86_32TargetInfo : public WindowsX86_32TargetInfo {
 public:
   MinGWX86_32TargetInfo(const llvm::Triple &Triple)
       : WindowsX86_32TargetInfo(Triple) {}
-  virtual void getTargetDefines(const LangOptions &Opts,
-                                MacroBuilder &Builder) const {
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override {
     WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder);
     DefineStd(Builder, "WIN32", Opts);
     DefineStd(Builder, "WINNT", Opts);
     Builder.defineMacro("_X86_");
-    Builder.defineMacro("__MSVCRT__");
-    Builder.defineMacro("__MINGW32__");
-
-    // mingw32-gcc provides __declspec(a) as alias of __attribute__((a)).
-    // In contrast, clang-cc1 provides __declspec(a) with -fms-extensions.
-    if (Opts.MicrosoftExt)
-      // Provide "as-is" __declspec.
-      Builder.defineMacro("__declspec", "__declspec");
-    else
-      // Provide alias of __attribute__ like mingw32-gcc.
-      Builder.defineMacro("__declspec(a)", "__attribute__((a))");
+    addMinGWDefines(Opts, Builder);
   }
 };
 } // end anonymous namespace
@@ -3170,12 +3235,10 @@
     TLSSupported = false;
     WCharType = UnsignedShort;
     DoubleAlign = LongLongAlign = 64;
-    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
-                        "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
-                        "a0:0:64-f80:32:32-n8:16:32-S32";
+    DescriptionString = "e-m:w-p:32:32-i64:64-f80:32-n8:16:32-S32";
   }
-  virtual void getTargetDefines(const LangOptions &Opts,
-                                MacroBuilder &Builder) const {
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override {
     X86_32TargetInfo::getTargetDefines(Opts, Builder);
     Builder.defineMacro("_X86_");
     Builder.defineMacro("__CYGWIN__");
@@ -3199,8 +3262,8 @@
     this->UserLabelPrefix = "";
     this->TLSSupported = false;
   }
-  virtual void getTargetDefines(const LangOptions &Opts,
-                                MacroBuilder &Builder) const {
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override {
     X86_32TargetInfo::getTargetDefines(Opts, Builder);
     Builder.defineMacro("__INTEL__");
     Builder.defineMacro("__HAIKU__");
@@ -3212,8 +3275,8 @@
 template<typename Target>
 class RTEMSTargetInfo : public OSTargetInfo<Target> {
 protected:
-  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
-                            MacroBuilder &Builder) const {
+  void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+                    MacroBuilder &Builder) const override {
     // RTEMS defines; list based off of gcc output
 
     Builder.defineMacro("__rtems__");
@@ -3253,8 +3316,8 @@
     PtrDiffType = SignedLong;
     this->UserLabelPrefix = "";
   }
-  virtual void getTargetDefines(const LangOptions &Opts,
-                                MacroBuilder &Builder) const {
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override {
     X86_32TargetInfo::getTargetDefines(Opts, Builder);
     Builder.defineMacro("__INTEL__");
     Builder.defineMacro("__rtems__");
@@ -3267,20 +3330,23 @@
 class X86_64TargetInfo : public X86TargetInfo {
 public:
   X86_64TargetInfo(const llvm::Triple &Triple) : X86TargetInfo(Triple) {
-    LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
+    const bool IsX32 = getTriple().getEnvironment() == llvm::Triple::GNUX32;
+    LongWidth = LongAlign = PointerWidth = PointerAlign = IsX32 ? 32 : 64;
     LongDoubleWidth = 128;
     LongDoubleAlign = 128;
     LargeArrayMinWidth = 128;
     LargeArrayAlign = 128;
     SuitableAlign = 128;
-    IntMaxType = SignedLong;
-    UIntMaxType = UnsignedLong;
-    Int64Type = SignedLong;
+    SizeType    = IsX32 ? UnsignedInt      : UnsignedLong;
+    PtrDiffType = IsX32 ? SignedInt        : SignedLong;
+    IntPtrType  = IsX32 ? SignedInt        : SignedLong;
+    IntMaxType  = IsX32 ? SignedLongLong   : SignedLong;
+    Int64Type   = IsX32 ? SignedLongLong   : SignedLong;
     RegParmMax = 6;
 
-    DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
-                        "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
-                        "a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128";
+    DescriptionString = (IsX32)
+                            ? "e-m:e-" "p:32:32-" "i64:64-f80:128-n8:16:32:64-S128"
+                            : "e-m:e-"            "i64:64-f80:128-n8:16:32:64-S128";
 
     // Use fpret only for long double.
     RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble);
@@ -3289,28 +3355,26 @@
     ComplexLongDoubleUsesFP2Ret = true;
 
     // x86-64 has atomics up to 16 bytes.
-    // FIXME: Once the backend is fixed, increase MaxAtomicInlineWidth to 128
-    // on CPUs with cmpxchg16b
     MaxAtomicPromoteWidth = 128;
-    MaxAtomicInlineWidth = 64;
+    MaxAtomicInlineWidth = 128;
   }
-  virtual BuiltinVaListKind getBuiltinVaListKind() const {
+  BuiltinVaListKind getBuiltinVaListKind() const override {
     return TargetInfo::X86_64ABIBuiltinVaList;
   }
 
-  int getEHDataRegisterNumber(unsigned RegNo) const {
+  int getEHDataRegisterNumber(unsigned RegNo) const override {
     if (RegNo == 0) return 0;
     if (RegNo == 1) return 1;
     return -1;
   }
 
-  virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const {
+  CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
     return (CC == CC_C ||
             CC == CC_IntelOclBicc ||
             CC == CC_X86_64Win64) ? CCCR_OK : CCCR_Warning;
   }
 
-  virtual CallingConv getDefaultCallingConv(CallingConvMethodType MT) const {
+  CallingConv getDefaultCallingConv(CallingConvMethodType MT) const override {
     return CC_C;
   }
 
@@ -3323,27 +3387,25 @@
 public:
   WindowsX86_64TargetInfo(const llvm::Triple &Triple)
       : WindowsTargetInfo<X86_64TargetInfo>(Triple) {
-    TLSSupported = false;
     WCharType = UnsignedShort;
     LongWidth = LongAlign = 32;
     DoubleAlign = LongLongAlign = 64;
     IntMaxType = SignedLongLong;
-    UIntMaxType = UnsignedLongLong;
     Int64Type = SignedLongLong;
     SizeType = UnsignedLongLong;
     PtrDiffType = SignedLongLong;
     IntPtrType = SignedLongLong;
     this->UserLabelPrefix = "";
   }
-  virtual void getTargetDefines(const LangOptions &Opts,
-                                MacroBuilder &Builder) const {
+  void getTargetDefines(const LangOptions &Opts,
+                                MacroBuilder &Builder) const override {
     WindowsTargetInfo<X86_64TargetInfo>::getTargetDefines(Opts, Builder);
     Builder.defineMacro("_WIN64");
   }
-  virtual BuiltinVaListKind getBuiltinVaListKind() const {
+  BuiltinVaListKind getBuiltinVaListKind() const override {
     return TargetInfo::CharPtrBuiltinVaList;
   }
-  virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const {
+  CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
     return (CC == CC_C ||
             CC == CC_IntelOclBicc ||
             CC == CC_X86_64SysV) ? CCCR_OK : CCCR_Warning;
@@ -3353,15 +3415,15 @@
 
 namespace {
 // x86-64 Windows Visual Studio target
-class VisualStudioWindowsX86_64TargetInfo : public WindowsX86_64TargetInfo {
+class MicrosoftX86_64TargetInfo : public WindowsX86_64TargetInfo {
 public:
-  VisualStudioWindowsX86_64TargetInfo(const llvm::Triple &Triple)
+  MicrosoftX86_64TargetInfo(const llvm::Triple &Triple)
       : WindowsX86_64TargetInfo(Triple) {
     LongDoubleWidth = LongDoubleAlign = 64;
     LongDoubleFormat = &llvm::APFloat::IEEEdouble;
   }
-  virtual void getTargetDefines(const LangOptions &Opts,
-                                MacroBuilder &Builder) const {
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override {
     WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
     WindowsX86_64TargetInfo::getVisualStudioDefines(Opts, Builder);
     Builder.defineMacro("_M_X64");
@@ -3376,22 +3438,12 @@
 public:
   MinGWX86_64TargetInfo(const llvm::Triple &Triple)
       : WindowsX86_64TargetInfo(Triple) {}
-  virtual void getTargetDefines(const LangOptions &Opts,
-                                MacroBuilder &Builder) const {
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override {
     WindowsX86_64TargetInfo::getTargetDefines(Opts, Builder);
     DefineStd(Builder, "WIN64", Opts);
-    Builder.defineMacro("__MSVCRT__");
-    Builder.defineMacro("__MINGW32__");
     Builder.defineMacro("__MINGW64__");
-
-    // mingw32-gcc provides __declspec(a) as alias of __attribute__((a)).
-    // In contrast, clang-cc1 provides __declspec(a) with -fms-extensions.
-    if (Opts.MicrosoftExt)
-      // Provide "as-is" __declspec.
-      Builder.defineMacro("__declspec", "__declspec");
-    else
-      // Provide alias of __attribute__ like mingw32-gcc.
-      Builder.defineMacro("__declspec(a)", "__attribute__((a))");
+    addMinGWDefines(Opts, Builder);
   }
 };
 } // end anonymous namespace
@@ -3403,6 +3455,11 @@
       : DarwinTargetInfo<X86_64TargetInfo>(Triple) {
     Int64Type = SignedLongLong;
     MaxVectorAlign = 256;
+    // The 64-bit iOS simulator uses the builtin bool type for Objective-C.
+    llvm::Triple T = llvm::Triple(Triple);
+    if (T.getOS() == llvm::Triple::IOS)
+      UseSignedCharForObjCBool = false;
+    DescriptionString = "e-m:o-i64:64-f80:128-n8:16:32:64-S128";
   }
 };
 } // end anonymous namespace
@@ -3413,7 +3470,6 @@
   OpenBSDX86_64TargetInfo(const llvm::Triple &Triple)
       : OpenBSDTargetInfo<X86_64TargetInfo>(Triple) {
     IntMaxType = SignedLongLong;
-    UIntMaxType = UnsignedLongLong;
     Int64Type = SignedLongLong;
   }
 };
@@ -3425,242 +3481,11 @@
   BitrigX86_64TargetInfo(const llvm::Triple &Triple)
       : BitrigTargetInfo<X86_64TargetInfo>(Triple) {
     IntMaxType = SignedLongLong;
-    UIntMaxType = UnsignedLongLong;
     Int64Type = SignedLongLong;
   }
 };
 }
 
-namespace {
-class AArch64TargetInfo : public TargetInfo {
-  static const char * const GCCRegNames[];
-  static const TargetInfo::GCCRegAlias GCCRegAliases[];
-
-  enum FPUModeEnum {
-    FPUMode,
-    NeonMode
-  };
-
-  unsigned FPU;
-  unsigned Crypto;
-  static const Builtin::Info BuiltinInfo[];
-
-public:
-  AArch64TargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
-    BigEndian = false;
-    LongWidth = LongAlign = 64;
-    LongDoubleWidth = LongDoubleAlign = 128;
-    PointerWidth = PointerAlign = 64;
-    SuitableAlign = 128;
-    DescriptionString = "e-p:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
-                        "i64:64:64-i128:128:128-f32:32:32-f64:64:64-"
-                        "f128:128:128-n32:64-S128";
-
-    WCharType = UnsignedInt;
-    LongDoubleFormat = &llvm::APFloat::IEEEquad;
-
-    // AArch64 backend supports 64-bit operations at the moment. In principle
-    // 128-bit is possible if register-pairs are used.
-    MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
-
-    TheCXXABI.set(TargetCXXABI::GenericAArch64);
-  }
-  virtual void getTargetDefines(const LangOptions &Opts,
-                                MacroBuilder &Builder) const {
-    // GCC defines theses currently
-    Builder.defineMacro("__aarch64__");
-    Builder.defineMacro("__AARCH64EL__");
-
-    // ACLE predefines. Many can only have one possible value on v8 AArch64.
-    Builder.defineMacro("__ARM_ACLE",         "200");
-    Builder.defineMacro("__ARM_ARCH",         "8");
-    Builder.defineMacro("__ARM_ARCH_PROFILE", "'A'");
-
-    Builder.defineMacro("__ARM_64BIT_STATE");
-    Builder.defineMacro("__ARM_PCS_AAPCS64");
-    Builder.defineMacro("__ARM_ARCH_ISA_A64");
-
-    Builder.defineMacro("__ARM_FEATURE_UNALIGNED");
-    Builder.defineMacro("__ARM_FEATURE_CLZ");
-    Builder.defineMacro("__ARM_FEATURE_FMA");
-    Builder.defineMacro("__ARM_FEATURE_DIV");
-
-    Builder.defineMacro("__ARM_ALIGN_MAX_STACK_PWR", "4");
-
-    // 0xe implies support for half, single and double precision operations.
-    Builder.defineMacro("__ARM_FP", "0xe");
-
-    // PCS specifies this for SysV variants, which is all we support. Other ABIs
-    // may choose __ARM_FP16_FORMAT_ALTERNATIVE.
-    Builder.defineMacro("__ARM_FP16_FORMAT_IEEE");
-
-    if (Opts.FastMath || Opts.FiniteMathOnly)
-      Builder.defineMacro("__ARM_FP_FAST");
-
-    if ((Opts.C99 || Opts.C11) && !Opts.Freestanding)
-      Builder.defineMacro("__ARM_FP_FENV_ROUNDING");
-
-    Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
-                        Opts.ShortWChar ? "2" : "4");
-
-    Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM",
-                        Opts.ShortEnums ? "1" : "4");
-
-    if (BigEndian)
-      Builder.defineMacro("__AARCH_BIG_ENDIAN");
-
-    if (FPU == NeonMode) {
-      Builder.defineMacro("__ARM_NEON");
-      // 64-bit NEON supports half, single and double precision operations.
-      Builder.defineMacro("__ARM_NEON_FP", "7");
-    }
-
-    if (Crypto) {
-      Builder.defineMacro("__ARM_FEATURE_CRYPTO");
-    }
-  }
-  virtual void getTargetBuiltins(const Builtin::Info *&Records,
-                                 unsigned &NumRecords) const {
-    Records = BuiltinInfo;
-    NumRecords = clang::AArch64::LastTSBuiltin-Builtin::FirstTSBuiltin;
-  }
-  virtual bool hasFeature(StringRef Feature) const {
-    return Feature == "aarch64" || (Feature == "neon" && FPU == NeonMode);
-  }
-
-  virtual bool setCPU(const std::string &Name) {
-    return llvm::StringSwitch<bool>(Name)
-             .Case("generic", true)
-             .Cases("cortex-a53", "cortex-a57", true)
-             .Default(false);
-  }
-
-  virtual bool handleTargetFeatures(std::vector<std::string> &Features,
-                                    DiagnosticsEngine &Diags) {
-    FPU = FPUMode;
-    Crypto = 0;
-    for (unsigned i = 0, e = Features.size(); i != e; ++i) {
-      if (Features[i] == "+neon")
-        FPU = NeonMode;
-      if (Features[i] == "+crypto")
-        Crypto = 1;
-    }
-    return true;
-  }
-
-  virtual void getGCCRegNames(const char *const *&Names,
-                              unsigned &NumNames) const;
-  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
-                                unsigned &NumAliases) const;
-
-  virtual bool isCLZForZeroUndef() const { return false; }
-
-  virtual bool validateAsmConstraint(const char *&Name,
-                                     TargetInfo::ConstraintInfo &Info) const {
-    switch (*Name) {
-    default: return false;
-    case 'w': // An FP/SIMD vector register
-      Info.setAllowsRegister();
-      return true;
-    case 'I': // Constant that can be used with an ADD instruction
-    case 'J': // Constant that can be used with a SUB instruction
-    case 'K': // Constant that can be used with a 32-bit logical instruction
-    case 'L': // Constant that can be used with a 64-bit logical instruction
-    case 'M': // Constant that can be used as a 32-bit MOV immediate
-    case 'N': // Constant that can be used as a 64-bit MOV immediate
-    case 'Y': // Floating point constant zero
-    case 'Z': // Integer constant zero
-      return true;
-    case 'Q': // A memory reference with base register and no offset
-      Info.setAllowsMemory();
-      return true;
-    case 'S': // A symbolic address
-      Info.setAllowsRegister();
-      return true;
-    case 'U':
-      // Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes, whatever they may be
-      // Utf: A memory address suitable for ldp/stp in TF mode, whatever it may be
-      // Usa: An absolute symbolic address
-      // Ush: The high part (bits 32:12) of a pc-relative symbolic address
-      llvm_unreachable("FIXME: Unimplemented support for bizarre constraints");
-    }
-  }
-
-  virtual const char *getClobbers() const {
-    // There are no AArch64 clobbers shared by all asm statements.
-    return "";
-  }
-
-  virtual BuiltinVaListKind getBuiltinVaListKind() const {
-    return TargetInfo::AArch64ABIBuiltinVaList;
-  }
-};
-
-const char * const AArch64TargetInfo::GCCRegNames[] = {
-  "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7",
-  "w8", "w9", "w10", "w11", "w12", "w13", "w14", "w15",
-  "w16", "w17", "w18", "w19", "w20", "w21", "w22", "w23",
-  "w24", "w25", "w26", "w27", "w28", "w29", "w30", "wsp", "wzr",
-
-  "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", "x29", "x30", "sp", "xzr",
-
-  "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7",
-  "b8", "b9", "b10", "b11", "b12", "b13", "b14", "b15",
-  "b16", "b17", "b18", "b19", "b20", "b21", "b22", "b23",
-  "b24", "b25", "b26", "b27", "b28", "b29", "b30", "b31",
-
-  "h0", "h1", "h2", "h3", "h4", "h5", "h6", "h7",
-  "h8", "h9", "h10", "h11", "h12", "h13", "h14", "h15",
-  "h16", "h17", "h18", "h19", "h20", "h21", "h22", "h23",
-  "h24", "h25", "h26", "h27", "h28", "h29", "h30", "h31",
-
-  "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
-  "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15",
-  "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23",
-  "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
-
-  "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",
-
-  "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7",
-  "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15",
-  "q16", "q17", "q18", "q19", "q20", "q21", "q22", "q23",
-  "q24", "q25", "q26", "q27", "q28", "q29", "q30", "q31"
-};
-
-void AArch64TargetInfo::getGCCRegNames(const char * const *&Names,
-                                       unsigned &NumNames) const {
-  Names = GCCRegNames;
-  NumNames = llvm::array_lengthof(GCCRegNames);
-}
-
-const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = {
-  { { "x16" }, "ip0"},
-  { { "x17" }, "ip1"},
-  { { "x29" }, "fp" },
-  { { "x30" }, "lr" }
-};
-
-void AArch64TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
-                                         unsigned &NumAliases) const {
-  Aliases = GCCRegAliases;
-  NumAliases = llvm::array_lengthof(GCCRegAliases);
-
-}
-
-const Builtin::Info AArch64TargetInfo::BuiltinInfo[] = {
-#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
-#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
-                                              ALL_LANGUAGES },
-#include "clang/Basic/BuiltinsAArch64.def"
-};
-
-} // end anonymous namespace
 
 namespace {
 class ARMTargetInfo : public TargetInfo {
@@ -3705,48 +3530,185 @@
   unsigned SoftFloatABI : 1;
 
   unsigned CRC : 1;
+  unsigned Crypto : 1;
 
   static const Builtin::Info BuiltinInfo[];
 
   static bool shouldUseInlineAtomic(const llvm::Triple &T) {
-    // On linux, binaries targeting old cpus call functions in libgcc to
-    // perform atomic operations. The implementation in libgcc then calls into
-    // the kernel which on armv6 and newer uses ldrex and strex. The net result
-    // is that if we assume the kernel is at least as recent as the hardware,
-    // it is safe to use atomic instructions on armv6 and newer.
-    if (!T.isOSLinux() &&
-        T.getOS() != llvm::Triple::FreeBSD &&
-        T.getOS() != llvm::Triple::Bitrig)
-      return false;
     StringRef ArchName = T.getArchName();
-    if (T.getArch() == llvm::Triple::arm) {
-      if (!ArchName.startswith("armv"))
+    if (T.getArch() == llvm::Triple::arm ||
+        T.getArch() == llvm::Triple::armeb) {
+      StringRef VersionStr;
+      if (ArchName.startswith("armv"))
+        VersionStr = ArchName.substr(4, 1);
+      else if (ArchName.startswith("armebv"))
+        VersionStr = ArchName.substr(6, 1);
+      else
         return false;
-      StringRef VersionStr = ArchName.substr(4);
       unsigned Version;
       if (VersionStr.getAsInteger(10, Version))
         return false;
       return Version >= 6;
     }
-    assert(T.getArch() == llvm::Triple::thumb);
-    if (!ArchName.startswith("thumbv"))
+    assert(T.getArch() == llvm::Triple::thumb ||
+           T.getArch() == llvm::Triple::thumbeb);
+    StringRef VersionStr;
+    if (ArchName.startswith("thumbv"))
+      VersionStr = ArchName.substr(6, 1);
+    else if (ArchName.startswith("thumbebv"))
+      VersionStr = ArchName.substr(8, 1);
+    else
       return false;
-    StringRef VersionStr = ArchName.substr(6);
     unsigned Version;
     if (VersionStr.getAsInteger(10, Version))
       return false;
     return Version >= 7;
   }
 
+  void setABIAAPCS() {
+    IsAAPCS = true;
+
+    DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;
+    const llvm::Triple &T = getTriple();
+
+    // size_t is unsigned long on Darwin and NetBSD.
+    if (T.isOSDarwin() || T.getOS() == llvm::Triple::NetBSD)
+      SizeType = UnsignedLong;
+    else
+      SizeType = UnsignedInt;
+
+    switch (T.getOS()) {
+    case llvm::Triple::NetBSD:
+      WCharType = SignedInt;
+      break;
+    case llvm::Triple::Win32:
+      WCharType = UnsignedShort;
+      break;
+    case llvm::Triple::Linux:
+    default:
+      // AAPCS 7.1.1, ARM-Linux ABI 2.4: type of wchar_t is unsigned int.
+      WCharType = UnsignedInt;
+      break;
+    }
+
+    UseBitFieldTypeAlignment = true;
+
+    ZeroLengthBitfieldBoundary = 0;
+
+    if (IsThumb) {
+      // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
+      // so set preferred for small types to 32.
+      if (T.isOSBinFormatMachO()) {
+        DescriptionString = BigEndian ?
+                              "E-m:o-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:64-"
+                              "v128:64:128-a:0:32-n32-S64" :
+                              "e-m:o-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:64-"
+                              "v128:64:128-a:0:32-n32-S64";
+      } else if (T.isOSWindows()) {
+        // FIXME: this is invalid for WindowsCE
+        assert(!BigEndian && "Windows on ARM does not support big endian");
+        DescriptionString = "e"
+                            "-m:e"
+                            "-p:32:32"
+                            "-i1:8:32-i8:8:32-i16:16:32-i64:64"
+                            "-v128:64:128"
+                            "-a:0:32"
+                            "-n32"
+                            "-S64";
+      } else {
+        DescriptionString = BigEndian ?
+                              "E-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:64-"
+                              "v128:64:128-a:0:32-n32-S64" :
+                              "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:64-"
+                              "v128:64:128-a:0:32-n32-S64";
+      }
+    } else {
+      if (T.isOSBinFormatMachO())
+        DescriptionString = BigEndian ?
+                              "E-m:o-p:32:32-i64:64-v128:64:128-n32-S64" :
+                              "e-m:o-p:32:32-i64:64-v128:64:128-n32-S64";
+      // @LOCALMOD-BEGIN
+      else if (T.isOSNaCl()) {
+        assert(!BigEndian && "NaCl on ARM does not support big endian");
+        DescriptionString = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S128";
+      } else
+      // @LOCALMOD-END
+        DescriptionString = BigEndian ?
+                              "E-m:e-p:32:32-i64:64-v128:64:128-n32-S64" :
+                              "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64";
+    }
+
+    // FIXME: Enumerated types are variable width in straight AAPCS.
+  }
+
+  void setABIAPCS() {
+    const llvm::Triple &T = getTriple();
+
+    IsAAPCS = false;
+
+    DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 32;
+
+    // size_t is unsigned int on FreeBSD.
+    if (T.getOS() == llvm::Triple::FreeBSD)
+      SizeType = UnsignedInt;
+    else
+      SizeType = UnsignedLong;
+
+    // Revert to using SignedInt on apcs-gnu to comply with existing behaviour.
+    WCharType = SignedInt;
+
+    // Do not respect the alignment of bit-field types when laying out
+    // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
+    UseBitFieldTypeAlignment = false;
+
+    /// gcc forces the alignment to 4 bytes, regardless of the type of the
+    /// zero length bitfield.  This corresponds to EMPTY_FIELD_BOUNDARY in
+    /// gcc.
+    ZeroLengthBitfieldBoundary = 32;
+
+    if (IsThumb) {
+      // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
+      // so set preferred for small types to 32.
+      if (T.isOSBinFormatMachO())
+        DescriptionString = BigEndian ?
+            "E-m:o-p:32:32-i1:8:32-i8:8:32-i16:16:32-f64:32:64"
+            "-v64:32:64-v128:32:128-a:0:32-n32-S32" :
+            "e-m:o-p:32:32-i1:8:32-i8:8:32-i16:16:32-f64:32:64"
+            "-v64:32:64-v128:32:128-a:0:32-n32-S32";
+      else
+        DescriptionString = BigEndian ?
+            "E-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-f64:32:64"
+            "-v64:32:64-v128:32:128-a:0:32-n32-S32" :
+            "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-f64:32:64"
+            "-v64:32:64-v128:32:128-a:0:32-n32-S32";
+    } else {
+      if (T.isOSBinFormatMachO())
+        DescriptionString = BigEndian ?
+            "E-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32" :
+            "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32";
+      else
+        DescriptionString = BigEndian ?
+            "E-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32" :
+            "e-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32";
+    }
+
+    // FIXME: Override "preferred align" for double and long long.
+  }
+
 public:
-  ARMTargetInfo(const llvm::Triple &Triple)
-      : TargetInfo(Triple), ABI("aapcs-linux"), CPU("arm1136j-s"),
-        FPMath(FP_Default), IsAAPCS(true) {
-    BigEndian = false;
-    SizeType = UnsignedInt;
-    PtrDiffType = SignedInt;
-    // AAPCS 7.1.1, ARM-Linux ABI 2.4: type of wchar_t is unsigned int.
-    WCharType = UnsignedInt;
+  ARMTargetInfo(const llvm::Triple &Triple, bool IsBigEndian)
+      : TargetInfo(Triple), CPU("arm1136j-s"), FPMath(FP_Default),
+        IsAAPCS(true) {
+    BigEndian = IsBigEndian;
+
+    switch (getTriple().getOS()) {
+    case llvm::Triple::NetBSD:
+      PtrDiffType = SignedLong;
+      break;
+    default:
+      PtrDiffType = SignedInt;
+      break;
+    }
 
     // {} in inline assembly are neon specifiers, not assembly variant
     // specifiers.
@@ -3754,17 +3716,8 @@
 
     // FIXME: Should we just treat this as a feature?
     IsThumb = getTriple().getArchName().startswith("thumb");
-    if (IsThumb) {
-      // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
-      // so set preferred for small types to 32.
-      DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
-                           "i64:64:64-f32:32:32-f64:64:64-"
-                           "v64:64:64-v128:64:128-a0:0:32-n32-S64");
-    } else {
-      DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
-                           "i64:64:64-f32:32:32-f64:64:64-"
-                           "v64:64:64-v128:64:128-a0:0:64-n32-S64");
-    }
+
+    setABI("aapcs-linux");
 
     // ARM targets default to using the ARM C++ ABI.
     TheCXXABI.set(TargetCXXABI::GenericARM);
@@ -3780,8 +3733,8 @@
     // zero length bitfield.
     UseZeroLengthBitfieldAlignment = true;
   }
-  virtual const char *getABI() const { return ABI.c_str(); }
-  virtual bool setABI(const std::string &Name) {
+  StringRef getABI() const override { return ABI; }
+  bool setABI(const std::string &Name) override {
     ABI = Name;
 
     // The defaults (above) are for AAPCS, check if we need to change them.
@@ -3789,53 +3742,22 @@
     // FIXME: We need support for -meabi... we could just mangle it into the
     // name.
     if (Name == "apcs-gnu") {
-      DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 32;
-      // size_t is unsigned int on FreeBSD.
-      if (getTriple().getOS() != llvm::Triple::FreeBSD)
-        SizeType = UnsignedLong;
-
-      // Revert to using SignedInt on apcs-gnu to comply with existing behaviour.
-      WCharType = SignedInt;
-
-      // Do not respect the alignment of bit-field types when laying out
-      // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
-      UseBitFieldTypeAlignment = false;
-
-      /// gcc forces the alignment to 4 bytes, regardless of the type of the
-      /// zero length bitfield.  This corresponds to EMPTY_FIELD_BOUNDARY in
-      /// gcc.
-      ZeroLengthBitfieldBoundary = 32;
-
-      IsAAPCS = false;
-
-      if (IsThumb) {
-        // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
-        // so set preferred for small types to 32.
-        DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
-                             "i64:32:64-f32:32:32-f64:32:64-"
-                             "v64:32:64-v128:32:128-a0:0:32-n32-S32");
-      } else {
-        DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
-                             "i64:32:64-f32:32:32-f64:32:64-"
-                             "v64:32:64-v128:32:128-a0:0:32-n32-S32");
-      }
-
-      // FIXME: Override "preferred align" for double and long long.
-    } else if (Name == "aapcs" || Name == "aapcs-vfp") {
-      // size_t is unsigned long on Darwin.
-      if (getTriple().isOSDarwin())
-        SizeType = UnsignedLong;
-      IsAAPCS = true;
-      // FIXME: Enumerated types are variable width in straight AAPCS.
-    } else if (Name == "aapcs-linux") {
-      IsAAPCS = true;
-    } else
-      return false;
-
-    return true;
+      setABIAPCS();
+      return true;
+    }
+    if (Name == "aapcs" || Name == "aapcs-vfp" || Name == "aapcs-linux") {
+      setABIAAPCS();
+      return true;
+    }
+    return false;
   }
 
-  void getDefaultFeatures(llvm::StringMap<bool> &Features) const {
+  void getDefaultFeatures(llvm::StringMap<bool> &Features) const override {
+    if (IsAAPCS)
+      Features["aapcs"] = true;
+    else
+      Features["apcs"] = true;
+
     StringRef ArchName = getTriple().getArchName();
     if (CPU == "arm1136jf-s" || CPU == "arm1176jzf-s" || CPU == "mpcore")
       Features["vfp2"] = true;
@@ -3847,32 +3769,44 @@
     else if (CPU == "cortex-a5") {
       Features["vfp4"] = true;
       Features["neon"] = true;
-    } else if (CPU == "swift" || CPU == "cortex-a7" || CPU == "cortex-a15") {
+    } else if (CPU == "swift" || CPU == "cortex-a7" ||
+               CPU == "cortex-a12" || CPU == "cortex-a15" ||
+               CPU == "krait") {
       Features["vfp4"] = true;
       Features["neon"] = true;
       Features["hwdiv"] = true;
       Features["hwdiv-arm"] = true;
+    } else if (CPU == "cyclone") {
+      Features["v8fp"] = true;
+      Features["neon"] = true;
+      Features["hwdiv"] = true;
+      Features["hwdiv-arm"] = true;
     } else if (CPU == "cortex-a53" || CPU == "cortex-a57") {
       Features["fp-armv8"] = true;
       Features["neon"] = true;
       Features["hwdiv"] = true;
       Features["hwdiv-arm"] = true;
       Features["crc"] = true;
-    } else if (CPU == "cortex-r5" || CPU == "cortex-m3" ||
-               CPU == "cortex-m4" ||
+      Features["crypto"] = true;
+    } else if (CPU == "cortex-r5" ||
                // Enable the hwdiv extension for all v8a AArch32 cores by
                // default.
                ArchName == "armv8a" || ArchName == "armv8" ||
-               ArchName == "thumbv8a" || ArchName == "thumbv8") {
+               ArchName == "armebv8a" || ArchName == "armebv8" ||
+               ArchName == "thumbv8a" || ArchName == "thumbv8" ||
+               ArchName == "thumbebv8a" || ArchName == "thumbebv8") {
       Features["hwdiv"] = true;
       Features["hwdiv-arm"] = true;
+    } else if (CPU == "cortex-m3" || CPU == "cortex-m4") {
+      Features["hwdiv"] = true;
     }
   }
 
-  virtual bool handleTargetFeatures(std::vector<std::string> &Features,
-                                    DiagnosticsEngine &Diags) {
+  bool handleTargetFeatures(std::vector<std::string> &Features,
+                            DiagnosticsEngine &Diags) override {
     FPU = 0;
     CRC = 0;
+    Crypto = 0;
     SoftFloat = SoftFloatABI = false;
     HWDiv = 0;
     for (unsigned i = 0, e = Features.size(); i != e; ++i) {
@@ -3896,6 +3830,8 @@
         HWDiv |= HWDivARM;
       else if (Features[i] == "+crc")
         CRC = 1;
+      else if (Features[i] == "+crypto")
+        Crypto = 1;
     }
 
     if (!(FPU & NeonFPU) && FPMath == FP_Neon) {
@@ -3919,7 +3855,7 @@
     return true;
   }
 
-  virtual bool hasFeature(StringRef Feature) const {
+  bool hasFeature(StringRef Feature) const override {
     return llvm::StringSwitch<bool>(Feature)
         .Case("arm", true)
         .Case("softfloat", SoftFloat)
@@ -3946,42 +3882,60 @@
       .Cases("arm1176jz-s", "arm1176jzf-s", "6ZK")
       .Cases("arm1136jf-s", "mpcorenovfp", "mpcore", "6K")
       .Cases("arm1156t2-s", "arm1156t2f-s", "6T2")
-      .Cases("cortex-a5", "cortex-a7", "cortex-a8", "7A")
-      .Cases("cortex-a9", "cortex-a12", "cortex-a15", "7A")
+      .Cases("cortex-a5", "cortex-a7", "cortex-a8", "cortex-a9-mp", "7A")
+      .Cases("cortex-a9", "cortex-a12", "cortex-a15", "krait", "7A")
       .Cases("cortex-r4", "cortex-r5", "7R")
-      .Case("cortex-a9-mp", "7F")
       .Case("swift", "7S")
-      .Cases("cortex-m3", "cortex-m4", "7M")
+      .Case("cyclone", "8A")
+      .Case("cortex-m3", "7M")
+      .Case("cortex-m4", "7EM")
       .Case("cortex-m0", "6M")
       .Cases("cortex-a53", "cortex-a57", "8A")
-      .Default(0);
+      .Default(nullptr);
   }
   static const char *getCPUProfile(StringRef Name) {
     return llvm::StringSwitch<const char*>(Name)
       .Cases("cortex-a5", "cortex-a7", "cortex-a8", "A")
-      .Cases("cortex-a9", "cortex-a12", "cortex-a15", "A")
+      .Cases("cortex-a9", "cortex-a12", "cortex-a15", "krait", "A")
       .Cases("cortex-a53", "cortex-a57", "A")
       .Cases("cortex-m3", "cortex-m4", "cortex-m0", "M")
       .Cases("cortex-r4", "cortex-r5", "R")
       .Default("");
   }
-  virtual bool setCPU(const std::string &Name) {
+  bool setCPU(const std::string &Name) override {
     if (!getCPUDefineSuffix(Name))
       return false;
 
+    // Cortex M does not support 8 byte atomics, while general Thumb2 does.
+    StringRef Profile = getCPUProfile(Name);
+    if (Profile == "M" && MaxAtomicInlineWidth) {
+      MaxAtomicPromoteWidth = 32;
+      MaxAtomicInlineWidth = 32;
+    }
+
     CPU = Name;
     return true;
   }
-  virtual bool setFPMath(StringRef Name);
-  virtual void getTargetDefines(const LangOptions &Opts,
-                                MacroBuilder &Builder) const {
+  bool setFPMath(StringRef Name) override;
+  bool supportsThumb(StringRef ArchName, StringRef CPUArch,
+                     unsigned CPUArchVer) const {
+    return CPUArchVer >= 7 || (CPUArch.find('T') != StringRef::npos) ||
+           (CPUArch.find('M') != StringRef::npos);
+  }
+  bool supportsThumb2(StringRef ArchName, StringRef CPUArch,
+                      unsigned CPUArchVer) const {
+    // We check both CPUArchVer and ArchName because when only triple is
+    // specified, the default CPU is arm1136j-s.
+    return ArchName.endswith("v6t2") || ArchName.endswith("v7") ||
+           ArchName.endswith("v8") || CPUArch == "6T2" || CPUArchVer >= 7;
+  }
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override {
     // Target identification.
     Builder.defineMacro("__arm");
     Builder.defineMacro("__arm__");
 
     // Target properties.
-    Builder.defineMacro("__ARMEL__");
-    Builder.defineMacro("__LITTLE_ENDIAN__");
     Builder.defineMacro("__REGISTER_PREFIX__", "");
 
     StringRef CPUArch = getCPUDefineSuffix(CPU);
@@ -3990,21 +3944,53 @@
       llvm_unreachable("Invalid char for architecture version number");
     }
     Builder.defineMacro("__ARM_ARCH_" + CPUArch + "__");
-    Builder.defineMacro("__ARM_ARCH", CPUArch.substr(0, 1));
+
+    // ACLE 6.4.1 ARM/Thumb instruction set architecture
     StringRef CPUProfile = getCPUProfile(CPU);
+    StringRef ArchName = getTriple().getArchName();
+
+    // __ARM_ARCH is defined as an integer value indicating the current ARM ISA
+    Builder.defineMacro("__ARM_ARCH", CPUArch.substr(0, 1));
+
+    // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA.  It
+    // is not defined for the M-profile.
+    // NOTE that the deffault profile is assumed to be 'A'
+    if (CPUProfile.empty() || CPUProfile != "M")
+      Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1");
+
+    // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supporst the original
+    // Thumb ISA (including v6-M).  It is set to 2 if the core supports the
+    // Thumb-2 ISA as found in the v6T2 architecture and all v7 architecture.
+    if (supportsThumb2(ArchName, CPUArch, CPUArchVer))
+      Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
+    else if (supportsThumb(ArchName, CPUArch, CPUArchVer))
+      Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
+
+    // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
+    // instruction set such as ARM or Thumb.
+    Builder.defineMacro("__ARM_32BIT_STATE", "1");
+
+    // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)
+
+    // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.
     if (!CPUProfile.empty())
-      Builder.defineMacro("__ARM_ARCH_PROFILE", CPUProfile);
-    
+      Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'");
+
+    // ACLE predefines.
+    Builder.defineMacro("__ARM_ACLE", "200");
+
     // Subtarget options.
 
     // FIXME: It's more complicated than this and we don't really support
     // interworking.
-    if (5 <= CPUArchVer && CPUArchVer <= 7)
+    // Windows on ARM does not "support" interworking
+    if (5 <= CPUArchVer && CPUArchVer <= 8 && !getTriple().isOSWindows())
       Builder.defineMacro("__THUMB_INTERWORK__");
 
     if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {
       // Embedded targets on Darwin follow AAPCS, but not EABI.
-      if (!getTriple().isOSDarwin())
+      // Windows on ARM follows AAPCS VFP, but does not conform to EABI.
+      if (!getTriple().isOSDarwin() && !getTriple().isOSWindows())
         Builder.defineMacro("__ARM_EABI__");
       Builder.defineMacro("__ARM_PCS", "1");
 
@@ -4021,7 +4007,7 @@
     if (IsThumb) {
       Builder.defineMacro("__THUMBEL__");
       Builder.defineMacro("__thumb__");
-      if (CPUArch == "6T2" || CPUArchVer == 7)
+      if (supportsThumb2(ArchName, CPUArch, CPUArchVer))
         Builder.defineMacro("__thumb2__");
     }
     if (((HWDiv & HWDivThumb) && IsThumb) || ((HWDiv & HWDivARM) && !IsThumb))
@@ -4039,17 +4025,28 @@
       if (FPU & VFP4FPU)
         Builder.defineMacro("__ARM_VFPV4__");
     }
-    
+
     // This only gets set when Neon instructions are actually available, unlike
     // the VFP define, hence the soft float and arch check. This is subtly
     // different from gcc, we follow the intent which was that it should be set
     // when Neon instructions are actually available.
-    if ((FPU & NeonFPU) && !SoftFloat && CPUArchVer >= 7)
+    if ((FPU & NeonFPU) && !SoftFloat && CPUArchVer >= 7) {
+      Builder.defineMacro("__ARM_NEON");
       Builder.defineMacro("__ARM_NEON__");
+    }
+
+    Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
+                        Opts.ShortWChar ? "2" : "4");
+
+    Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM",
+                        Opts.ShortEnums ? "1" : "4");
 
     if (CRC)
       Builder.defineMacro("__ARM_FEATURE_CRC32");
 
+    if (Crypto)
+      Builder.defineMacro("__ARM_FEATURE_CRYPTO");
+
     if (CPUArchVer >= 6 && CPUArch != "6M") {
       Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
       Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
@@ -4057,21 +4054,21 @@
       Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
     }
   }
-  virtual void getTargetBuiltins(const Builtin::Info *&Records,
-                                 unsigned &NumRecords) const {
+  void getTargetBuiltins(const Builtin::Info *&Records,
+                         unsigned &NumRecords) const override {
     Records = BuiltinInfo;
     NumRecords = clang::ARM::LastTSBuiltin-Builtin::FirstTSBuiltin;
   }
-  virtual bool isCLZForZeroUndef() const { return false; }
-  virtual BuiltinVaListKind getBuiltinVaListKind() const {
+  bool isCLZForZeroUndef() const override { return false; }
+  BuiltinVaListKind getBuiltinVaListKind() const override {
     return IsAAPCS ? AAPCSABIBuiltinVaList : TargetInfo::VoidPtrBuiltinVaList;
   }
-  virtual void getGCCRegNames(const char * const *&Names,
-                              unsigned &NumNames) const;
-  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
-                                unsigned &NumAliases) const;
-  virtual bool validateAsmConstraint(const char *&Name,
-                                     TargetInfo::ConstraintInfo &Info) const {
+  void getGCCRegNames(const char * const *&Names,
+                      unsigned &NumNames) const override;
+  void getGCCRegAliases(const GCCRegAlias *&Aliases,
+                        unsigned &NumAliases) const override;
+  bool validateAsmConstraint(const char *&Name,
+                             TargetInfo::ConstraintInfo &Info) const override {
     switch (*Name) {
     default: break;
     case 'l': // r0-r7
@@ -4101,7 +4098,7 @@
     }
     return false;
   }
-  virtual std::string convertConstraint(const char *&Constraint) const {
+  std::string convertConstraint(const char *&Constraint) const override {
     std::string R;
     switch (*Constraint) {
     case 'U':   // Two-character constraint; add "^" hint for later parsing.
@@ -4116,9 +4113,8 @@
     }
     return R;
   }
-  virtual bool validateConstraintModifier(StringRef Constraint,
-                                          const char Modifier,
-                                          unsigned Size) const {
+  bool validateConstraintModifier(StringRef Constraint, const char Modifier,
+                                  unsigned Size) const override {
     bool isOutput = (Constraint[0] == '=');
     bool isInOut = (Constraint[0] == '+');
 
@@ -4133,7 +4129,7 @@
     case 'r': {
       switch (Modifier) {
       default:
-        return (isInOut || isOutput || Size <= 32);
+        return (isInOut || isOutput || Size <= 64);
       case 'q':
         // A register of size 32 cannot fit a vector type.
         return false;
@@ -4143,16 +4139,16 @@
 
     return true;
   }
-  virtual const char *getClobbers() const {
+  const char *getClobbers() const override {
     // FIXME: Is this really right?
     return "";
   }
 
-  virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const {
+  CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
     return (CC == CC_AAPCS || CC == CC_AAPCS_VFP) ? CCCR_OK : CCCR_Warning;
   }
 
-  virtual int getEHDataRegisterNumber(unsigned RegNo) const {
+  int getEHDataRegisterNumber(unsigned RegNo) const override {
     if (RegNo == 0) return 0;
     if (RegNo == 1) return 1;
     return -1;
@@ -4230,25 +4226,123 @@
 #define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
                                               ALL_LANGUAGES },
+#include "clang/Basic/BuiltinsNEON.def"
+
+#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
+#define LANGBUILTIN(ID, TYPE, ATTRS, LANG) { #ID, TYPE, ATTRS, 0, LANG },
+#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
+                                              ALL_LANGUAGES },
 #include "clang/Basic/BuiltinsARM.def"
 };
+
+class ARMleTargetInfo : public ARMTargetInfo {
+public:
+  ARMleTargetInfo(const llvm::Triple &Triple)
+    : ARMTargetInfo(Triple, false) { }
+  virtual void getTargetDefines(const LangOptions &Opts,
+                                MacroBuilder &Builder) const {
+    Builder.defineMacro("__ARMEL__");
+    ARMTargetInfo::getTargetDefines(Opts, Builder);
+  }
+};
+
+class ARMbeTargetInfo : public ARMTargetInfo {
+public:
+  ARMbeTargetInfo(const llvm::Triple &Triple)
+    : ARMTargetInfo(Triple, true) { }
+  virtual void getTargetDefines(const LangOptions &Opts,
+                                MacroBuilder &Builder) const {
+    Builder.defineMacro("__ARMEB__");
+    Builder.defineMacro("__ARM_BIG_ENDIAN");
+    ARMTargetInfo::getTargetDefines(Opts, Builder);
+  }
+};
 } // end anonymous namespace.
 
 namespace {
+class WindowsARMTargetInfo : public WindowsTargetInfo<ARMleTargetInfo> {
+  const llvm::Triple Triple;
+public:
+  WindowsARMTargetInfo(const llvm::Triple &Triple)
+    : WindowsTargetInfo<ARMleTargetInfo>(Triple), Triple(Triple) {
+    TLSSupported = false;
+    WCharType = UnsignedShort;
+    SizeType = UnsignedInt;
+    UserLabelPrefix = "";
+  }
+  void getVisualStudioDefines(const LangOptions &Opts,
+                              MacroBuilder &Builder) const {
+    WindowsTargetInfo<ARMleTargetInfo>::getVisualStudioDefines(Opts, Builder);
+
+    // FIXME: this is invalid for WindowsCE
+    Builder.defineMacro("_M_ARM_NT", "1");
+    Builder.defineMacro("_M_ARMT", "_M_ARM");
+    Builder.defineMacro("_M_THUMB", "_M_ARM");
+
+    assert((Triple.getArch() == llvm::Triple::arm ||
+            Triple.getArch() == llvm::Triple::thumb) &&
+           "invalid architecture for Windows ARM target info");
+    unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
+    Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset));
+
+    // TODO map the complete set of values
+    // 31: VFPv3 40: VFPv4
+    Builder.defineMacro("_M_ARM_FP", "31");
+  }
+  BuiltinVaListKind getBuiltinVaListKind() const override {
+    return TargetInfo::CharPtrBuiltinVaList;
+  }
+};
+
+// Windows ARM + Itanium C++ ABI Target
+class ItaniumWindowsARMleTargetInfo : public WindowsARMTargetInfo {
+public:
+  ItaniumWindowsARMleTargetInfo(const llvm::Triple &Triple)
+    : WindowsARMTargetInfo(Triple) {
+    TheCXXABI.set(TargetCXXABI::GenericARM);
+  }
+
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override {
+    WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
+
+    if (Opts.MSVCCompat)
+      WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
+  }
+};
+
+// Windows ARM, MS (C++) ABI
+class MicrosoftARMleTargetInfo : public WindowsARMTargetInfo {
+public:
+  MicrosoftARMleTargetInfo(const llvm::Triple &Triple)
+    : WindowsARMTargetInfo(Triple) {
+    TheCXXABI.set(TargetCXXABI::Microsoft);
+  }
+
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override {
+    WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
+    WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
+  }
+};
+}
+
+
+namespace {
 class DarwinARMTargetInfo :
-  public DarwinTargetInfo<ARMTargetInfo> {
+  public DarwinTargetInfo<ARMleTargetInfo> {
 protected:
-  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
-                            MacroBuilder &Builder) const {
+  void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+                    MacroBuilder &Builder) const override {
     getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
   }
 
 public:
   DarwinARMTargetInfo(const llvm::Triple &Triple)
-      : DarwinTargetInfo<ARMTargetInfo>(Triple) {
+      : DarwinTargetInfo<ARMleTargetInfo>(Triple) {
     HasAlignMac68kSupport = true;
     // iOS always has 64-bit atomic instructions.
-    // FIXME: This should be based off of the target features in ARMTargetInfo.
+    // FIXME: This should be based off of the target features in ARMleTargetInfo.
     MaxAtomicInlineWidth = 64;
 
     // Darwin on iOS uses a variant of the ARM C++ ABI.
@@ -4259,6 +4353,357 @@
 
 
 namespace {
+class AArch64TargetInfo : public TargetInfo {
+  virtual void setDescriptionString() = 0;
+  static const TargetInfo::GCCRegAlias GCCRegAliases[];
+  static const char *const GCCRegNames[];
+
+  enum FPUModeEnum {
+    FPUMode,
+    NeonMode
+  };
+
+  unsigned FPU;
+  unsigned CRC;
+  unsigned Crypto;
+
+  static const Builtin::Info BuiltinInfo[];
+
+  std::string ABI;
+
+public:
+  AArch64TargetInfo(const llvm::Triple &Triple)
+      : TargetInfo(Triple), ABI("aapcs") {
+
+    if (getTriple().getOS() == llvm::Triple::NetBSD) {
+      WCharType = SignedInt;
+
+      // NetBSD apparently prefers consistency across ARM targets to consistency
+      // across 64-bit targets.
+      Int64Type = SignedLongLong;
+      IntMaxType = SignedLongLong;
+    } else {
+      WCharType = UnsignedInt;
+      Int64Type = SignedLong;
+      IntMaxType = SignedLong;
+    }
+
+    LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
+    MaxVectorAlign = 128;
+    RegParmMax = 8;
+    MaxAtomicInlineWidth = 128;
+    MaxAtomicPromoteWidth = 128;
+
+    LongDoubleWidth = LongDoubleAlign = 128;
+    LongDoubleFormat = &llvm::APFloat::IEEEquad;
+
+    // {} in inline assembly are neon specifiers, not assembly variant
+    // specifiers.
+    NoAsmVariants = true;
+
+    // AArch64 targets default to using the ARM C++ ABI.
+    TheCXXABI.set(TargetCXXABI::GenericAArch64);
+  }
+
+  StringRef getABI() const override { return ABI; }
+  virtual bool setABI(const std::string &Name) {
+    if (Name != "aapcs" && Name != "darwinpcs")
+      return false;
+
+    ABI = Name;
+    return true;
+  }
+
+  virtual bool setCPU(const std::string &Name) {
+    bool CPUKnown = llvm::StringSwitch<bool>(Name)
+                        .Case("generic", true)
+                        .Cases("cortex-a53", "cortex-a57", true)
+                        .Case("cyclone", true)
+                        .Default(false);
+    return CPUKnown;
+  }
+
+  virtual void getTargetDefines(const LangOptions &Opts,
+                                MacroBuilder &Builder) const {
+    // Target identification.
+    Builder.defineMacro("__aarch64__");
+
+    // Target properties.
+    Builder.defineMacro("_LP64");
+    Builder.defineMacro("__LP64__");
+
+    // ACLE predefines. Many can only have one possible value on v8 AArch64.
+    Builder.defineMacro("__ARM_ACLE", "200");
+    Builder.defineMacro("__ARM_ARCH", "8");
+    Builder.defineMacro("__ARM_ARCH_PROFILE", "'A'");
+
+    Builder.defineMacro("__ARM_64BIT_STATE");
+    Builder.defineMacro("__ARM_PCS_AAPCS64");
+    Builder.defineMacro("__ARM_ARCH_ISA_A64");
+
+    Builder.defineMacro("__ARM_FEATURE_UNALIGNED");
+    Builder.defineMacro("__ARM_FEATURE_CLZ");
+    Builder.defineMacro("__ARM_FEATURE_FMA");
+    Builder.defineMacro("__ARM_FEATURE_DIV");
+
+    Builder.defineMacro("__ARM_ALIGN_MAX_STACK_PWR", "4");
+
+    // 0xe implies support for half, single and double precision operations.
+    Builder.defineMacro("__ARM_FP", "0xe");
+
+    // PCS specifies this for SysV variants, which is all we support. Other ABIs
+    // may choose __ARM_FP16_FORMAT_ALTERNATIVE.
+    Builder.defineMacro("__ARM_FP16_FORMAT_IEEE");
+
+    if (Opts.FastMath || Opts.FiniteMathOnly)
+      Builder.defineMacro("__ARM_FP_FAST");
+
+    if ((Opts.C99 || Opts.C11) && !Opts.Freestanding)
+      Builder.defineMacro("__ARM_FP_FENV_ROUNDING");
+
+    Builder.defineMacro("__ARM_SIZEOF_WCHAR_T", Opts.ShortWChar ? "2" : "4");
+
+    Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM",
+                        Opts.ShortEnums ? "1" : "4");
+
+    if (FPU == NeonMode) {
+      Builder.defineMacro("__ARM_NEON");
+      // 64-bit NEON supports half, single and double precision operations.
+      Builder.defineMacro("__ARM_NEON_FP", "0xe");
+    }
+
+    if (CRC)
+      Builder.defineMacro("__ARM_FEATURE_CRC32");
+
+    if (Crypto)
+      Builder.defineMacro("__ARM_FEATURE_CRYPTO");
+  }
+
+  virtual void getTargetBuiltins(const Builtin::Info *&Records,
+                                 unsigned &NumRecords) const {
+    Records = BuiltinInfo;
+    NumRecords = clang::AArch64::LastTSBuiltin - Builtin::FirstTSBuiltin;
+  }
+
+  virtual bool hasFeature(StringRef Feature) const {
+    return Feature == "aarch64" ||
+      Feature == "arm64" ||
+      (Feature == "neon" && FPU == NeonMode);
+  }
+
+  bool handleTargetFeatures(std::vector<std::string> &Features,
+                            DiagnosticsEngine &Diags) override {
+    FPU = FPUMode;
+    CRC = 0;
+    Crypto = 0;
+    for (unsigned i = 0, e = Features.size(); i != e; ++i) {
+      if (Features[i] == "+neon")
+        FPU = NeonMode;
+      if (Features[i] == "+crc")
+        CRC = 1;
+      if (Features[i] == "+crypto")
+        Crypto = 1;
+    }
+
+    setDescriptionString();
+
+    return true;
+  }
+
+  virtual bool isCLZForZeroUndef() const { return false; }
+
+  virtual BuiltinVaListKind getBuiltinVaListKind() const {
+    return TargetInfo::AArch64ABIBuiltinVaList;
+  }
+
+  virtual void getGCCRegNames(const char *const *&Names,
+                              unsigned &NumNames) const;
+  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
+                                unsigned &NumAliases) const;
+
+  virtual bool validateAsmConstraint(const char *&Name,
+                                     TargetInfo::ConstraintInfo &Info) const {
+    switch (*Name) {
+    default:
+      return false;
+    case 'w': // Floating point and SIMD registers (V0-V31)
+      Info.setAllowsRegister();
+      return true;
+    case 'I': // Constant that can be used with an ADD instruction
+    case 'J': // Constant that can be used with a SUB instruction
+    case 'K': // Constant that can be used with a 32-bit logical instruction
+    case 'L': // Constant that can be used with a 64-bit logical instruction
+    case 'M': // Constant that can be used as a 32-bit MOV immediate
+    case 'N': // Constant that can be used as a 64-bit MOV immediate
+    case 'Y': // Floating point constant zero
+    case 'Z': // Integer constant zero
+      return true;
+    case 'Q': // A memory reference with base register and no offset
+      Info.setAllowsMemory();
+      return true;
+    case 'S': // A symbolic address
+      Info.setAllowsRegister();
+      return true;
+    case 'U':
+      // Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes, whatever they may be
+      // Utf: A memory address suitable for ldp/stp in TF mode, whatever it may be
+      // Usa: An absolute symbolic address
+      // Ush: The high part (bits 32:12) of a pc-relative symbolic address
+      llvm_unreachable("FIXME: Unimplemented support for bizarre constraints");
+    case 'z': // Zero register, wzr or xzr
+      Info.setAllowsRegister();
+      return true;
+    case 'x': // Floating point and SIMD registers (V0-V15)
+      Info.setAllowsRegister();
+      return true;
+    }
+    return false;
+  }
+
+  virtual const char *getClobbers() const { return ""; }
+
+  int getEHDataRegisterNumber(unsigned RegNo) const {
+    if (RegNo == 0)
+      return 0;
+    if (RegNo == 1)
+      return 1;
+    return -1;
+  }
+};
+
+const char *const AArch64TargetInfo::GCCRegNames[] = {
+  // 32-bit Integer registers
+  "w0",  "w1",  "w2",  "w3",  "w4",  "w5",  "w6",  "w7",  "w8",  "w9",  "w10",
+  "w11", "w12", "w13", "w14", "w15", "w16", "w17", "w18", "w19", "w20", "w21",
+  "w22", "w23", "w24", "w25", "w26", "w27", "w28", "w29", "w30", "wsp",
+
+  // 64-bit Integer registers
+  "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",
+
+  // 32-bit floating point regsisters
+  "s0",  "s1",  "s2",  "s3",  "s4",  "s5",  "s6",  "s7",  "s8",  "s9",  "s10",
+  "s11", "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21",
+  "s22", "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
+
+  // 64-bit floating point regsisters
+  "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",
+
+  // Vector registers
+  "v0",  "v1",  "v2",  "v3",  "v4",  "v5",  "v6",  "v7",  "v8",  "v9",  "v10",
+  "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21",
+  "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"
+};
+
+void AArch64TargetInfo::getGCCRegNames(const char *const *&Names,
+                                     unsigned &NumNames) const {
+  Names = GCCRegNames;
+  NumNames = llvm::array_lengthof(GCCRegNames);
+}
+
+const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = {
+  { { "w31" }, "wsp" },
+  { { "x29" }, "fp" },
+  { { "x30" }, "lr" },
+  { { "x31" }, "sp" },
+  // The S/D/Q and W/X registers overlap, but aren't really aliases; we
+  // don't want to substitute one of these for a different-sized one.
+};
+
+void AArch64TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
+                                       unsigned &NumAliases) const {
+  Aliases = GCCRegAliases;
+  NumAliases = llvm::array_lengthof(GCCRegAliases);
+}
+
+const Builtin::Info AArch64TargetInfo::BuiltinInfo[] = {
+#define BUILTIN(ID, TYPE, ATTRS)                                               \
+  { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
+#include "clang/Basic/BuiltinsNEON.def"
+
+#define BUILTIN(ID, TYPE, ATTRS)                                               \
+  { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
+#include "clang/Basic/BuiltinsAArch64.def"
+};
+
+class AArch64leTargetInfo : public AArch64TargetInfo {
+  void setDescriptionString() override {
+    if (getTriple().isOSBinFormatMachO())
+      DescriptionString = "e-m:o-i64:64-i128:128-n32:64-S128";
+    else
+      DescriptionString = "e-m:e-i64:64-i128:128-n32:64-S128";
+  }
+
+public:
+  AArch64leTargetInfo(const llvm::Triple &Triple)
+    : AArch64TargetInfo(Triple) {
+    BigEndian = false;
+    }
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override {
+    Builder.defineMacro("__AARCH64EL__");
+    AArch64TargetInfo::getTargetDefines(Opts, Builder);
+  }
+};
+
+class AArch64beTargetInfo : public AArch64TargetInfo {
+  void setDescriptionString() override {
+    assert(!getTriple().isOSBinFormatMachO());
+    DescriptionString = "E-m:e-i64:64-i128:128-n32:64-S128";
+  }
+
+public:
+  AArch64beTargetInfo(const llvm::Triple &Triple)
+    : AArch64TargetInfo(Triple) { }
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override {
+    Builder.defineMacro("__AARCH64EB__");
+    Builder.defineMacro("__AARCH_BIG_ENDIAN");
+    Builder.defineMacro("__ARM_BIG_ENDIAN");
+    AArch64TargetInfo::getTargetDefines(Opts, Builder);
+  }
+};
+} // end anonymous namespace.
+
+namespace {
+class DarwinAArch64TargetInfo : public DarwinTargetInfo<AArch64leTargetInfo> {
+protected:
+  void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+                    MacroBuilder &Builder) const override {
+    Builder.defineMacro("__AARCH64_SIMD__");
+    Builder.defineMacro("__ARM64_ARCH_8__");
+    Builder.defineMacro("__ARM_NEON__");
+    Builder.defineMacro("__LITTLE_ENDIAN__");
+    Builder.defineMacro("__REGISTER_PREFIX__", "");
+    Builder.defineMacro("__arm64", "1");
+    Builder.defineMacro("__arm64__", "1");
+
+    getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
+  }
+
+public:
+  DarwinAArch64TargetInfo(const llvm::Triple &Triple)
+      : DarwinTargetInfo<AArch64leTargetInfo>(Triple) {
+    Int64Type = SignedLongLong;
+    WCharType = SignedInt;
+    UseSignedCharForObjCBool = false;
+
+    LongDoubleWidth = LongDoubleAlign = 64;
+    LongDoubleFormat = &llvm::APFloat::IEEEdouble;
+
+    TheCXXABI.set(TargetCXXABI::iOS64);
+  }
+
+  virtual BuiltinVaListKind getBuiltinVaListKind() const {
+    return TargetInfo::CharPtrBuiltinVaList;
+  }
+};
+} // end anonymous namespace
+
+namespace {
 // Hexagon abstract base class
 class HexagonTargetInfo : public TargetInfo {
   static const Builtin::Info BuiltinInfo[];
@@ -4268,41 +4713,39 @@
 public:
   HexagonTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
     BigEndian = false;
-    DescriptionString = ("e-p:32:32:32-"
-                         "i64:64:64-i32:32:32-i16:16:16-i1:32:32-"
-                         "f64:64:64-f32:32:32-a0:0-n32");
+    DescriptionString = "e-m:e-p:32:32-i1:32-i64:64-a:0-n32";
 
     // {} in inline assembly are packet specifiers, not assembly variant
     // specifiers.
     NoAsmVariants = true;
   }
 
-  virtual void getTargetBuiltins(const Builtin::Info *&Records,
-                                 unsigned &NumRecords) const {
+  void getTargetBuiltins(const Builtin::Info *&Records,
+                         unsigned &NumRecords) const override {
     Records = BuiltinInfo;
     NumRecords = clang::Hexagon::LastTSBuiltin-Builtin::FirstTSBuiltin;
   }
 
-  virtual bool validateAsmConstraint(const char *&Name,
-                                     TargetInfo::ConstraintInfo &Info) const {
+  bool validateAsmConstraint(const char *&Name,
+                             TargetInfo::ConstraintInfo &Info) const override {
     return true;
   }
 
-  virtual void getTargetDefines(const LangOptions &Opts,
-                                MacroBuilder &Builder) const;
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override;
 
-  virtual bool hasFeature(StringRef Feature) const {
+  bool hasFeature(StringRef Feature) const override {
     return Feature == "hexagon";
   }
-  
-  virtual BuiltinVaListKind getBuiltinVaListKind() const {
+
+  BuiltinVaListKind getBuiltinVaListKind() const override {
     return TargetInfo::CharPtrBuiltinVaList;
   }
-  virtual void getGCCRegNames(const char * const *&Names,
-                              unsigned &NumNames) const;
-  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
-                                unsigned &NumAliases) const;
-  virtual const char *getClobbers() const {
+  void getGCCRegNames(const char * const *&Names,
+                      unsigned &NumNames) const override;
+  void getGCCRegAliases(const GCCRegAlias *&Aliases,
+                        unsigned &NumAliases) const override;
+  const char *getClobbers() const override {
     return "";
   }
 
@@ -4310,10 +4753,10 @@
     return llvm::StringSwitch<const char*>(Name)
       .Case("hexagonv4", "4")
       .Case("hexagonv5", "5")
-      .Default(0);
+      .Default(nullptr);
   }
 
-  virtual bool setCPU(const std::string &Name) {
+  bool setCPU(const std::string &Name) override {
     if (!getHexagonCPUSuffix(Name))
       return false;
 
@@ -4421,47 +4864,47 @@
 public:
   SparcTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {}
 
-  virtual bool handleTargetFeatures(std::vector<std::string> &Features,
-                                    DiagnosticsEngine &Diags) {
+  bool handleTargetFeatures(std::vector<std::string> &Features,
+                            DiagnosticsEngine &Diags) override {
     SoftFloat = false;
     for (unsigned i = 0, e = Features.size(); i != e; ++i)
       if (Features[i] == "+soft-float")
         SoftFloat = true;
     return true;
   }
-  virtual void getTargetDefines(const LangOptions &Opts,
-                                MacroBuilder &Builder) const {
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override {
     DefineStd(Builder, "sparc", Opts);
     Builder.defineMacro("__REGISTER_PREFIX__", "");
 
     if (SoftFloat)
       Builder.defineMacro("SOFT_FLOAT", "1");
   }
-  
-  virtual bool hasFeature(StringRef Feature) const {
+
+  bool hasFeature(StringRef Feature) const override {
     return llvm::StringSwitch<bool>(Feature)
              .Case("softfloat", SoftFloat)
              .Case("sparc", true)
              .Default(false);
   }
-  
-  virtual void getTargetBuiltins(const Builtin::Info *&Records,
-                                 unsigned &NumRecords) const {
+
+  void getTargetBuiltins(const Builtin::Info *&Records,
+                         unsigned &NumRecords) const override {
     // FIXME: Implement!
   }
-  virtual BuiltinVaListKind getBuiltinVaListKind() const {
+  BuiltinVaListKind getBuiltinVaListKind() const override {
     return TargetInfo::VoidPtrBuiltinVaList;
   }
-  virtual void getGCCRegNames(const char * const *&Names,
-                              unsigned &NumNames) const;
-  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
-                                unsigned &NumAliases) const;
-  virtual bool validateAsmConstraint(const char *&Name,
-                                     TargetInfo::ConstraintInfo &info) const {
+  void getGCCRegNames(const char * const *&Names,
+                      unsigned &NumNames) const override;
+  void getGCCRegAliases(const GCCRegAlias *&Aliases,
+                        unsigned &NumAliases) const override;
+  bool validateAsmConstraint(const char *&Name,
+                             TargetInfo::ConstraintInfo &info) const override {
     // FIXME: Implement!
     return false;
   }
-  virtual const char *getClobbers() const {
+  const char *getClobbers() const override {
     // FIXME: Implement!
     return "";
   }
@@ -4525,13 +4968,11 @@
 class SparcV8TargetInfo : public SparcTargetInfo {
 public:
   SparcV8TargetInfo(const llvm::Triple &Triple) : SparcTargetInfo(Triple) {
-    // FIXME: Support Sparc quad-precision long double?
-    DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
-                        "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32-S64";
+    DescriptionString = "E-m:e-p:32:32-i64:64-f128:64-n32-S64";
   }
 
-  virtual void getTargetDefines(const LangOptions &Opts,
-                                MacroBuilder &Builder) const {
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override {
     SparcTargetInfo::getTargetDefines(Opts, Builder);
     Builder.defineMacro("__sparcv8");
   }
@@ -4542,24 +4983,27 @@
 public:
   SparcV9TargetInfo(const llvm::Triple &Triple) : SparcTargetInfo(Triple) {
     // FIXME: Support Sparc quad-precision long double?
-    DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
-                        "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32:64-S128";
+    DescriptionString = "E-m:e-i64:64-n32:64-S128";
     // This is an LP64 platform.
     LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
 
     // OpenBSD uses long long for int64_t and intmax_t.
-    if (getTriple().getOS() == llvm::Triple::OpenBSD) {
+    if (getTriple().getOS() == llvm::Triple::OpenBSD)
       IntMaxType = SignedLongLong;
-      UIntMaxType = UnsignedLongLong;
-    } else {
+    else
       IntMaxType = SignedLong;
-      UIntMaxType = UnsignedLong;
-    }
     Int64Type = IntMaxType;
+
+    // The SPARCv8 System V ABI has long double 128-bits in size, but 64-bit
+    // aligned. The SPARCv9 SCD 2.4.1 says 16-byte aligned.
+    LongDoubleWidth = 128;
+    LongDoubleAlign = 128;
+    LongDoubleFormat = &llvm::APFloat::IEEEquad;
+    MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
   }
 
-  virtual void getTargetDefines(const LangOptions &Opts,
-                                MacroBuilder &Builder) const {
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override {
     SparcTargetInfo::getTargetDefines(Opts, Builder);
     Builder.defineMacro("__sparcv9");
     Builder.defineMacro("__arch64__");
@@ -4572,6 +5016,22 @@
       Builder.defineMacro("__sparcv9__");
     }
   }
+
+  bool setCPU(const std::string &Name) override {
+    bool CPUKnown = llvm::StringSwitch<bool>(Name)
+      .Case("v9", true)
+      .Case("ultrasparc", true)
+      .Case("ultrasparc3", true)
+      .Case("niagara", true)
+      .Case("niagara2", true)
+      .Case("niagara3", true)
+      .Case("niagara4", true)
+      .Default(false);
+
+    // No need to store the CPU yet.  There aren't any CPU-specific
+    // macros to define.
+    return CPUKnown;
+  }
 };
 
 } // end anonymous namespace.
@@ -4596,108 +5056,107 @@
 } // end anonymous namespace.
 
 namespace {
-  class SystemZTargetInfo : public TargetInfo {
-    static const char *const GCCRegNames[];
+class SystemZTargetInfo : public TargetInfo {
+  static const char *const GCCRegNames[];
 
-  public:
-    SystemZTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
-      TLSSupported = true;
-      IntWidth = IntAlign = 32;
-      LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64;
-      PointerWidth = PointerAlign = 64;
-      LongDoubleWidth = 128;
-      LongDoubleAlign = 64;
-      LongDoubleFormat = &llvm::APFloat::IEEEquad;
-      MinGlobalAlign = 16;
-      DescriptionString = "E-p:64:64:64-i1:8:16-i8:8:16-i16:16-i32:32-i64:64"
-       "-f32:32-f64:64-f128:64-a0:8:16-n32:64";
-      MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
-    }
-    virtual void getTargetDefines(const LangOptions &Opts,
-                                  MacroBuilder &Builder) const {
-      Builder.defineMacro("__s390__");
-      Builder.defineMacro("__s390x__");
-      Builder.defineMacro("__zarch__");
-      Builder.defineMacro("__LONG_DOUBLE_128__");
-    }
-    virtual void getTargetBuiltins(const Builtin::Info *&Records,
-                                   unsigned &NumRecords) const {
-      // FIXME: Implement.
-      Records = 0;
-      NumRecords = 0;
-    }
-
-    virtual void getGCCRegNames(const char *const *&Names,
-                                unsigned &NumNames) const;
-    virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
-                                  unsigned &NumAliases) const {
-      // No aliases.
-      Aliases = 0;
-      NumAliases = 0;
-    }
-    virtual bool validateAsmConstraint(const char *&Name,
-                                       TargetInfo::ConstraintInfo &info) const;
-    virtual const char *getClobbers() const {
-      // FIXME: Is this really right?
-      return "";
-    }
-    virtual BuiltinVaListKind getBuiltinVaListKind() const {
-      return TargetInfo::SystemZBuiltinVaList;
-    }
-    virtual bool setCPU(const std::string &Name) {
-      bool CPUKnown = llvm::StringSwitch<bool>(Name)
-        .Case("z10", true)
-        .Case("z196", true)
-        .Case("zEC12", true)
-        .Default(false);
-
-      // No need to store the CPU yet.  There aren't any CPU-specific
-      // macros to define.
-      return CPUKnown;
-    }
-  };
-
-  const char *const SystemZTargetInfo::GCCRegNames[] = {
-    "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",
-    "r8",  "r9",  "r10", "r11", "r12", "r13", "r14", "r15",
-    "f0",  "f2",  "f4",  "f6",  "f1",  "f3",  "f5",  "f7",
-    "f8",  "f10", "f12", "f14", "f9",  "f11", "f13", "f15"
-  };
-
-  void SystemZTargetInfo::getGCCRegNames(const char *const *&Names,
-                                         unsigned &NumNames) const {
-    Names = GCCRegNames;
-    NumNames = llvm::array_lengthof(GCCRegNames);
+public:
+  SystemZTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) {
+    TLSSupported = true;
+    IntWidth = IntAlign = 32;
+    LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64;
+    PointerWidth = PointerAlign = 64;
+    LongDoubleWidth = 128;
+    LongDoubleAlign = 64;
+    LongDoubleFormat = &llvm::APFloat::IEEEquad;
+    MinGlobalAlign = 16;
+    DescriptionString = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64";
+    MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
+  }
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override {
+    Builder.defineMacro("__s390__");
+    Builder.defineMacro("__s390x__");
+    Builder.defineMacro("__zarch__");
+    Builder.defineMacro("__LONG_DOUBLE_128__");
+  }
+  void getTargetBuiltins(const Builtin::Info *&Records,
+                         unsigned &NumRecords) const override {
+    // FIXME: Implement.
+    Records = nullptr;
+    NumRecords = 0;
   }
 
-  bool SystemZTargetInfo::
-  validateAsmConstraint(const char *&Name,
-                        TargetInfo::ConstraintInfo &Info) const {
-    switch (*Name) {
-    default:
-      return false;
-
-    case 'a': // Address register
-    case 'd': // Data register (equivalent to 'r')
-    case 'f': // Floating-point register
-      Info.setAllowsRegister();
-      return true;
-
-    case 'I': // Unsigned 8-bit constant
-    case 'J': // Unsigned 12-bit constant
-    case 'K': // Signed 16-bit constant
-    case 'L': // Signed 20-bit displacement (on all targets we support)
-    case 'M': // 0x7fffffff
-      return true;
-
-    case 'Q': // Memory with base and unsigned 12-bit displacement
-    case 'R': // Likewise, plus an index
-    case 'S': // Memory with base and signed 20-bit displacement
-    case 'T': // Likewise, plus an index
-      Info.setAllowsMemory();
-      return true;
-    }
+  void getGCCRegNames(const char *const *&Names,
+                      unsigned &NumNames) const override;
+  void getGCCRegAliases(const GCCRegAlias *&Aliases,
+                        unsigned &NumAliases) const override {
+    // No aliases.
+    Aliases = nullptr;
+    NumAliases = 0;
   }
+  bool validateAsmConstraint(const char *&Name,
+                             TargetInfo::ConstraintInfo &info) const override;
+  const char *getClobbers() const override {
+    // FIXME: Is this really right?
+    return "";
+  }
+  BuiltinVaListKind getBuiltinVaListKind() const override {
+    return TargetInfo::SystemZBuiltinVaList;
+  }
+  bool setCPU(const std::string &Name) override {
+    bool CPUKnown = llvm::StringSwitch<bool>(Name)
+      .Case("z10", true)
+      .Case("z196", true)
+      .Case("zEC12", true)
+      .Default(false);
+
+    // No need to store the CPU yet.  There aren't any CPU-specific
+    // macros to define.
+    return CPUKnown;
+  }
+};
+
+const char *const SystemZTargetInfo::GCCRegNames[] = {
+  "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",
+  "r8",  "r9",  "r10", "r11", "r12", "r13", "r14", "r15",
+  "f0",  "f2",  "f4",  "f6",  "f1",  "f3",  "f5",  "f7",
+  "f8",  "f10", "f12", "f14", "f9",  "f11", "f13", "f15"
+};
+
+void SystemZTargetInfo::getGCCRegNames(const char *const *&Names,
+                                       unsigned &NumNames) const {
+  Names = GCCRegNames;
+  NumNames = llvm::array_lengthof(GCCRegNames);
+}
+
+bool SystemZTargetInfo::
+validateAsmConstraint(const char *&Name,
+                      TargetInfo::ConstraintInfo &Info) const {
+  switch (*Name) {
+  default:
+    return false;
+
+  case 'a': // Address register
+  case 'd': // Data register (equivalent to 'r')
+  case 'f': // Floating-point register
+    Info.setAllowsRegister();
+    return true;
+
+  case 'I': // Unsigned 8-bit constant
+  case 'J': // Unsigned 12-bit constant
+  case 'K': // Signed 16-bit constant
+  case 'L': // Signed 20-bit displacement (on all targets we support)
+  case 'M': // 0x7fffffff
+    return true;
+
+  case 'Q': // Memory with base and unsigned 12-bit displacement
+  case 'R': // Likewise, plus an index
+  case 'S': // Memory with base and signed 20-bit displacement
+  case 'T': // Likewise, plus an index
+    Info.setAllowsMemory();
+    return true;
+  }
+}
 }
 
 namespace {
@@ -4714,45 +5173,44 @@
       SuitableAlign = 16;
       SizeType = UnsignedInt;
       IntMaxType = SignedLongLong;
-      UIntMaxType = UnsignedLongLong;
       IntPtrType = SignedInt;
       PtrDiffType = SignedInt;
       SigAtomicType = SignedLong;
-      DescriptionString = "e-p:16:16:16-i8:8:8-i16:16:16-i32:16:32-n8:16";
-   }
-    virtual void getTargetDefines(const LangOptions &Opts,
-                                  MacroBuilder &Builder) const {
+      DescriptionString = "e-m:e-p:16:16-i32:16:32-n8:16";
+    }
+    void getTargetDefines(const LangOptions &Opts,
+                          MacroBuilder &Builder) const override {
       Builder.defineMacro("MSP430");
       Builder.defineMacro("__MSP430__");
       // FIXME: defines for different 'flavours' of MCU
     }
-    virtual void getTargetBuiltins(const Builtin::Info *&Records,
-                                   unsigned &NumRecords) const {
-     // FIXME: Implement.
-      Records = 0;
+    void getTargetBuiltins(const Builtin::Info *&Records,
+                           unsigned &NumRecords) const override {
+      // FIXME: Implement.
+      Records = nullptr;
       NumRecords = 0;
     }
-    virtual bool hasFeature(StringRef Feature) const {
+    bool hasFeature(StringRef Feature) const override {
       return Feature == "msp430";
     }
-    virtual void getGCCRegNames(const char * const *&Names,
-                                unsigned &NumNames) const;
-    virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
-                                  unsigned &NumAliases) const {
+    void getGCCRegNames(const char * const *&Names,
+                        unsigned &NumNames) const override;
+    void getGCCRegAliases(const GCCRegAlias *&Aliases,
+                          unsigned &NumAliases) const override {
       // No aliases.
-      Aliases = 0;
+      Aliases = nullptr;
       NumAliases = 0;
     }
-    virtual bool validateAsmConstraint(const char *&Name,
-                                       TargetInfo::ConstraintInfo &info) const {
+    bool validateAsmConstraint(const char *&Name,
+                               TargetInfo::ConstraintInfo &info) const override {
       // No target constraints for now.
       return false;
     }
-    virtual const char *getClobbers() const {
+    const char *getClobbers() const override {
       // FIXME: Is this really right?
       return "";
     }
-    virtual BuiltinVaListKind getBuiltinVaListKind() const {
+    BuiltinVaListKind getBuiltinVaListKind() const override {
       // FIXME: implement
       return TargetInfo::CharPtrBuiltinVaList;
    }
@@ -4802,7 +5260,6 @@
       SuitableAlign = 32;
       SizeType = UnsignedInt;
       IntMaxType = SignedLong;
-      UIntMaxType = UnsignedLong;
       IntPtrType = SignedInt;
       PtrDiffType = SignedInt;
       FloatWidth = 32;
@@ -4814,40 +5271,38 @@
       FloatFormat = &llvm::APFloat::IEEEsingle;
       DoubleFormat = &llvm::APFloat::IEEEsingle;
       LongDoubleFormat = &llvm::APFloat::IEEEsingle;
-      DescriptionString = "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-"
-                          "v128:32:32-a0:0:32-n32";
+      DescriptionString = "E-p:32:32-i8:8:32-i16:16:32-i64:32"
+                          "-f64:32-v64:32-v128:32-a:0:32-n32";
       AddrSpaceMap = &TCEOpenCLAddrSpaceMap;
       UseAddrSpaceMapMangling = true;
     }
 
-    virtual void getTargetDefines(const LangOptions &Opts,
-                                  MacroBuilder &Builder) const {
+    void getTargetDefines(const LangOptions &Opts,
+                          MacroBuilder &Builder) const override {
       DefineStd(Builder, "tce", Opts);
       Builder.defineMacro("__TCE__");
       Builder.defineMacro("__TCE_V1__");
     }
-    virtual bool hasFeature(StringRef Feature) const {
+    bool hasFeature(StringRef Feature) const override {
       return Feature == "tce";
     }
-    
-    virtual void getTargetBuiltins(const Builtin::Info *&Records,
-                                   unsigned &NumRecords) const {}
-    virtual const char *getClobbers() const {
+
+    void getTargetBuiltins(const Builtin::Info *&Records,
+                           unsigned &NumRecords) const override {}
+    const char *getClobbers() const override {
       return "";
     }
-    virtual BuiltinVaListKind getBuiltinVaListKind() const {
+    BuiltinVaListKind getBuiltinVaListKind() const override {
       return TargetInfo::VoidPtrBuiltinVaList;
     }
-    virtual void getGCCRegNames(const char * const *&Names,
-                                unsigned &NumNames) const {}
-    virtual bool validateAsmConstraint(const char *&Name,
-                                       TargetInfo::ConstraintInfo &info) const {
+    void getGCCRegNames(const char * const *&Names,
+                        unsigned &NumNames) const override {}
+    bool validateAsmConstraint(const char *&Name,
+                               TargetInfo::ConstraintInfo &info) const override{
       return true;
     }
-    virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
-                                  unsigned &NumAliases) const {}
+    void getGCCRegAliases(const GCCRegAlias *&Aliases,
+                          unsigned &NumAliases) const override {}
   };
 }
 
@@ -4880,21 +5335,57 @@
         IsNan2008(false), IsSingleFloat(false), FloatABI(HardFloat),
         DspRev(NoDSP), HasMSA(false), HasFP64(false), ABI(ABIStr) {}
 
-  virtual const char *getABI() const { return ABI.c_str(); }
-  virtual bool setABI(const std::string &Name) = 0;
-  virtual bool setCPU(const std::string &Name) {
-    CPU = Name;
-    return true;
-  }
-  void getDefaultFeatures(llvm::StringMap<bool> &Features) const {
-    Features[ABI] = true;
-    Features[CPU] = true;
+  bool isNaN2008Default() const {
+    return CPU == "mips32r6" || CPU == "mips64r6";
   }
 
-  virtual void getTargetDefines(const LangOptions &Opts,
-                                MacroBuilder &Builder) const {
-    DefineStd(Builder, "mips", Opts);
+  bool isFP64Default() const {
+    return CPU == "mips32r6" || ABI == "n32" || ABI == "n64" || ABI == "64";
+  }
+
+  StringRef getABI() const override { return ABI; }
+  bool setCPU(const std::string &Name) override {
+    bool IsMips32 = getTriple().getArch() == llvm::Triple::mips ||
+                    getTriple().getArch() == llvm::Triple::mipsel;
+    CPU = Name;
+    return llvm::StringSwitch<bool>(Name)
+        .Case("mips1", IsMips32)
+        .Case("mips2", IsMips32)
+        .Case("mips3", true)
+        .Case("mips4", true)
+        .Case("mips5", true)
+        .Case("mips32", IsMips32)
+        .Case("mips32r2", IsMips32)
+        .Case("mips32r6", IsMips32)
+        .Case("mips64", true)
+        .Case("mips64r2", true)
+        .Case("mips64r6", true)
+        .Case("octeon", true)
+        .Default(false);
+  }
+  const std::string& getCPU() const { return CPU; }
+  void getDefaultFeatures(llvm::StringMap<bool> &Features) const override {
+    // The backend enables certain ABI's by default according to the
+    // architecture.
+    // Disable both possible defaults so that we don't end up with multiple
+    // ABI's selected and trigger an assertion.
+    Features["o32"] = false;
+    Features["n64"] = false;
+
+    Features[ABI] = true;
+    if (CPU == "octeon")
+      Features["mips64r2"] = Features["cnmips"] = true;
+    else
+      Features[CPU] = true;
+  }
+
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override {
+    Builder.defineMacro("__mips__");
     Builder.defineMacro("_mips");
+    if (Opts.GNUMode)
+      Builder.defineMacro("mips");
+
     Builder.defineMacro("__REGISTER_PREFIX__", "");
 
     switch (FloatABI) {
@@ -4947,22 +5438,22 @@
     Builder.defineMacro("_MIPS_ARCH_" + StringRef(CPU).upper());
   }
 
-  virtual void getTargetBuiltins(const Builtin::Info *&Records,
-                                 unsigned &NumRecords) const {
+  void getTargetBuiltins(const Builtin::Info *&Records,
+                         unsigned &NumRecords) const override {
     Records = BuiltinInfo;
     NumRecords = clang::Mips::LastTSBuiltin - Builtin::FirstTSBuiltin;
   }
-  virtual bool hasFeature(StringRef Feature) const {
+  bool hasFeature(StringRef Feature) const override {
     return llvm::StringSwitch<bool>(Feature)
       .Case("mips", true)
       .Case("fp64", HasFP64)
       .Default(false);
   }
-  virtual BuiltinVaListKind getBuiltinVaListKind() const {
+  BuiltinVaListKind getBuiltinVaListKind() const override {
     return TargetInfo::VoidPtrBuiltinVaList;
   }
-  virtual void getGCCRegNames(const char * const *&Names,
-                              unsigned &NumNames) const {
+  void getGCCRegNames(const char * const *&Names,
+                      unsigned &NumNames) const override {
     static const char *const GCCRegNames[] = {
       // CPU register names
       // Must match second column of GCCRegAliases
@@ -4990,17 +5481,17 @@
     Names = GCCRegNames;
     NumNames = llvm::array_lengthof(GCCRegNames);
   }
-  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
-                                unsigned &NumAliases) const = 0;
-  virtual bool validateAsmConstraint(const char *&Name,
-                                     TargetInfo::ConstraintInfo &Info) const {
+  void getGCCRegAliases(const GCCRegAlias *&Aliases,
+                        unsigned &NumAliases) const override = 0;
+  bool validateAsmConstraint(const char *&Name,
+                             TargetInfo::ConstraintInfo &Info) const override {
     switch (*Name) {
     default:
       return false;
         
     case 'r': // CPU registers.
     case 'd': // Equivalent to "r" unless generating MIPS16 code.
-    case 'y': // Equivalent to "r", backwards compatibility only.
+    case 'y': // Equivalent to "r", backward compatibility only.
     case 'f': // floating-point registers.
     case 'c': // $25 for indirect jumps
     case 'l': // lo register
@@ -5013,20 +5504,20 @@
     }
   }
 
-  virtual const char *getClobbers() const {
+  const char *getClobbers() const override {
     // FIXME: Implement!
     return "";
   }
 
-  virtual bool handleTargetFeatures(std::vector<std::string> &Features,
-                                    DiagnosticsEngine &Diags) {
+  bool handleTargetFeatures(std::vector<std::string> &Features,
+                            DiagnosticsEngine &Diags) override {
     IsMips16 = false;
     IsMicromips = false;
-    IsNan2008 = false;
+    IsNan2008 = isNaN2008Default();
     IsSingleFloat = false;
     FloatABI = HardFloat;
     DspRev = NoDSP;
-    HasFP64 = ABI == "n32" || ABI == "n64" || ABI == "64";
+    HasFP64 = isFP64Default();
 
     for (std::vector<std::string>::iterator it = Features.begin(),
          ie = Features.end(); it != ie; ++it) {
@@ -5050,6 +5541,8 @@
         HasFP64 = false;
       else if (*it == "+nan2008")
         IsNan2008 = true;
+      else if (*it == "-nan2008")
+        IsNan2008 = false;
     }
 
     // Remove front-end specific options.
@@ -5057,20 +5550,19 @@
       std::find(Features.begin(), Features.end(), "+soft-float");
     if (it != Features.end())
       Features.erase(it);
-    it = std::find(Features.begin(), Features.end(), "+nan2008");
-    if (it != Features.end())
-      Features.erase(it);
 
     setDescriptionString();
 
     return true;
   }
 
-  virtual int getEHDataRegisterNumber(unsigned RegNo) const {
+  int getEHDataRegisterNumber(unsigned RegNo) const override {
     if (RegNo == 0) return 4;
     if (RegNo == 1) return 5;
     return -1;
   }
+
+  bool isCLZForZeroUndef() const override { return false; }
 };
 
 const Builtin::Info MipsTargetInfoBase::BuiltinInfo[] = {
@@ -5083,25 +5575,31 @@
 class Mips32TargetInfoBase : public MipsTargetInfoBase {
 public:
   Mips32TargetInfoBase(const llvm::Triple &Triple)
-      : MipsTargetInfoBase(Triple, "o32", "mips32") {
+      : MipsTargetInfoBase(Triple, "o32", "mips32r2") {
     SizeType = UnsignedInt;
     PtrDiffType = SignedInt;
     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32;
   }
-  virtual bool setABI(const std::string &Name) {
-    if ((Name == "o32") || (Name == "eabi")) {
+  bool setABI(const std::string &Name) override {
+    if (Name == "o32" || Name == "eabi") {
       ABI = Name;
       return true;
-    } else if (Name == "32") {
-      ABI = "o32";
-      return true;
-    } else
-      return false;
+    }
+    return false;
   }
-  virtual void getTargetDefines(const LangOptions &Opts,
-                                MacroBuilder &Builder) const {
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override {
     MipsTargetInfoBase::getTargetDefines(Opts, Builder);
 
+    Builder.defineMacro("__mips", "32");
+    Builder.defineMacro("_MIPS_ISA", "_MIPS_ISA_MIPS32");
+
+    const std::string& CPUStr = getCPU();
+    if (CPUStr == "mips32")
+      Builder.defineMacro("__mips_isa_rev", "1");
+    else if (CPUStr == "mips32r2")
+      Builder.defineMacro("__mips_isa_rev", "2");
+
     if (ABI == "o32") {
       Builder.defineMacro("__mips_o32");
       Builder.defineMacro("_ABIO32", "1");
@@ -5112,8 +5610,8 @@
     else
       llvm_unreachable("Invalid ABI for Mips32.");
   }
-  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
-                                unsigned &NumAliases) const {
+  void getGCCRegAliases(const GCCRegAlias *&Aliases,
+                        unsigned &NumAliases) const override {
     static const TargetInfo::GCCRegAlias GCCRegAliases[] = {
       { { "at" },  "$1" },
       { { "v0" },  "$2" },
@@ -5153,17 +5651,16 @@
 };
 
 class Mips32EBTargetInfo : public Mips32TargetInfoBase {
-  virtual void setDescriptionString() {
-    DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
-                        "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32-S64";
+  void setDescriptionString() override {
+    DescriptionString = "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64";
   }
 
 public:
   Mips32EBTargetInfo(const llvm::Triple &Triple)
       : Mips32TargetInfoBase(Triple) {
   }
-  virtual void getTargetDefines(const LangOptions &Opts,
-                                MacroBuilder &Builder) const {
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override {
     DefineStd(Builder, "MIPSEB", Opts);
     Builder.defineMacro("_MIPSEB");
     Mips32TargetInfoBase::getTargetDefines(Opts, Builder);
@@ -5171,9 +5668,8 @@
 };
 
 class Mips32ELTargetInfo : public Mips32TargetInfoBase {
-  virtual void setDescriptionString() {
-    DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
-                        "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32-S64";
+  void setDescriptionString() override {
+    DescriptionString = "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64";
   }
 
 public:
@@ -5181,8 +5677,8 @@
       : Mips32TargetInfoBase(Triple) {
     BigEndian = false;
   }
-  virtual void getTargetDefines(const LangOptions &Opts,
-                                MacroBuilder &Builder) const {
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override {
     DefineStd(Builder, "MIPSEL", Opts);
     Builder.defineMacro("_MIPSEL");
     Mips32TargetInfoBase::getTargetDefines(Opts, Builder);
@@ -5192,39 +5688,60 @@
 class Mips64TargetInfoBase : public MipsTargetInfoBase {
 public:
   Mips64TargetInfoBase(const llvm::Triple &Triple)
-      : MipsTargetInfoBase(Triple, "n64", "mips64") {
-    LongWidth = LongAlign = 64;
-    PointerWidth = PointerAlign = 64;
+      : MipsTargetInfoBase(Triple, "n64", "mips64r2") {
     LongDoubleWidth = LongDoubleAlign = 128;
     LongDoubleFormat = &llvm::APFloat::IEEEquad;
     if (getTriple().getOS() == llvm::Triple::FreeBSD) {
       LongDoubleWidth = LongDoubleAlign = 64;
       LongDoubleFormat = &llvm::APFloat::IEEEdouble;
     }
+    setN64ABITypes();
     SuitableAlign = 128;
     MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
   }
-  virtual bool setABI(const std::string &Name) {
-    if (Name == "n32") {
-      LongWidth = LongAlign = 32;
-      PointerWidth = PointerAlign = 32;
-      ABI = Name;
-      return true;
-    } else if (Name == "n64") {
-      ABI = Name;
-      return true;
-    } else if (Name == "64") {
-      ABI = "n64";
-      return true;
-    } else
-      return false;
+
+  void setN64ABITypes() {
+    LongWidth = LongAlign = 64;
+    PointerWidth = PointerAlign = 64;
+    SizeType = UnsignedLong;
+    PtrDiffType = SignedLong;
   }
-  virtual void getTargetDefines(const LangOptions &Opts,
-                                MacroBuilder &Builder) const {
+
+  void setN32ABITypes() {
+    LongWidth = LongAlign = 32;
+    PointerWidth = PointerAlign = 32;
+    SizeType = UnsignedInt;
+    PtrDiffType = SignedInt;
+  }
+
+  bool setABI(const std::string &Name) override {
+    if (Name == "n32") {
+      setN32ABITypes();
+      ABI = Name;
+      return true;
+    }
+    if (Name == "n64") {
+      setN64ABITypes();
+      ABI = Name;
+      return true;
+    }
+    return false;
+  }
+
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override {
     MipsTargetInfoBase::getTargetDefines(Opts, Builder);
 
+    Builder.defineMacro("__mips", "64");
     Builder.defineMacro("__mips64");
     Builder.defineMacro("__mips64__");
+    Builder.defineMacro("_MIPS_ISA", "_MIPS_ISA_MIPS64");
+
+    const std::string& CPUStr = getCPU();
+    if (CPUStr == "mips64")
+      Builder.defineMacro("__mips_isa_rev", "1");
+    else if (CPUStr == "mips64r2")
+      Builder.defineMacro("__mips_isa_rev", "2");
 
     if (ABI == "n32") {
       Builder.defineMacro("__mips_n32");
@@ -5239,8 +5756,8 @@
     else
       llvm_unreachable("Invalid ABI for Mips64.");
   }
-  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
-                                unsigned &NumAliases) const {
+  void getGCCRegAliases(const GCCRegAlias *&Aliases,
+                        unsigned &NumAliases) const override {
     static const TargetInfo::GCCRegAlias GCCRegAliases[] = {
       { { "at" },  "$1" },
       { { "v0" },  "$2" },
@@ -5277,26 +5794,24 @@
     Aliases = GCCRegAliases;
     NumAliases = llvm::array_lengthof(GCCRegAliases);
   }
+
+  bool hasInt128Type() const override { return true; }
 };
 
 class Mips64EBTargetInfo : public Mips64TargetInfoBase {
-  virtual void setDescriptionString() {
+  void setDescriptionString() override {
     if (ABI == "n32")
-      DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
-                          "i64:64:64-f32:32:32-f64:64:64-f128:128:128-"
-                          "v64:64:64-n32:64-S128";
+      DescriptionString = "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32:64-S128";
     else
-      DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
-                          "i64:64:64-f32:32:32-f64:64:64-f128:128:128-"
-                          "v64:64:64-n32:64-S128";
+      DescriptionString = "E-m:m-i8:8:32-i16:16:32-i64:64-n32:64-S128";
 
   }
 
 public:
   Mips64EBTargetInfo(const llvm::Triple &Triple)
       : Mips64TargetInfoBase(Triple) {}
-  virtual void getTargetDefines(const LangOptions &Opts,
-                                MacroBuilder &Builder) const {
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override {
     DefineStd(Builder, "MIPSEB", Opts);
     Builder.defineMacro("_MIPSEB");
     Mips64TargetInfoBase::getTargetDefines(Opts, Builder);
@@ -5304,15 +5819,11 @@
 };
 
 class Mips64ELTargetInfo : public Mips64TargetInfoBase {
-  virtual void setDescriptionString() {
+  void setDescriptionString() override {
     if (ABI == "n32")
-      DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
-                          "i64:64:64-f32:32:32-f64:64:64-f128:128:128"
-                          "-v64:64:64-n32:64-S128";
+      DescriptionString = "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32:64-S128";
     else
-      DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
-                          "i64:64:64-f32:32:32-f64:64:64-f128:128:128-"
-                          "v64:64:64-n32:64-S128";
+      DescriptionString = "e-m:m-i8:8:32-i16:16:32-i64:64-n32:64-S128";
   }
 public:
   Mips64ELTargetInfo(const llvm::Triple &Triple)
@@ -5320,8 +5831,8 @@
     // Default ABI is n64.
     BigEndian = false;
   }
-  virtual void getTargetDefines(const LangOptions &Opts,
-                                MacroBuilder &Builder) const {
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override {
     DefineStd(Builder, "MIPSEL", Opts);
     Builder.defineMacro("_MIPSEL");
     Mips64TargetInfoBase::getTargetDefines(Opts, Builder);
@@ -5339,7 +5850,6 @@
     this->PointerAlign = 32;
     this->PointerWidth = 32;
     this->IntMaxType = TargetInfo::SignedLongLong;
-    this->UIntMaxType = TargetInfo::UnsignedLongLong;
     this->Int64Type = TargetInfo::SignedLongLong;
     this->DoubleAlign = 64;
     this->LongDoubleWidth = 64;
@@ -5360,8 +5870,7 @@
     //
     // Set the natural stack alignment to 16 bytes to accomodate 128-bit
     // aligned vectors.
-    DescriptionString = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-"
-                        "f32:32:32-f64:64:64-p:32:32:32-v128:32:128-n32-S128";
+    DescriptionString = "e-p:32:32-i64:64-v128:32:128-n32-S128";
   }
 
   void getDefaultFeatures(llvm::StringMap<bool> &Features) const {
@@ -5419,7 +5928,6 @@
     this->PointerAlign = 32;
     this->PointerWidth = 32;
     this->IntMaxType = TargetInfo::SignedLongLong;
-    this->UIntMaxType = TargetInfo::UnsignedLongLong;
     this->Int64Type = TargetInfo::SignedLongLong;
     this->DoubleAlign = 64;
     this->LongDoubleWidth = 64;
@@ -5428,54 +5936,50 @@
     this->PtrDiffType = TargetInfo::SignedInt;
     this->IntPtrType = TargetInfo::SignedInt;
     this->RegParmMax = 0; // Disallow regparm
-    DescriptionString = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-"
-                        "f32:32:32-f64:64:64-p:32:32:32-v128:32:32";
   }
 
-  void getDefaultFeatures(llvm::StringMap<bool> &Features) const {
+  void getDefaultFeatures(llvm::StringMap<bool> &Features) const override {
   }
-  virtual void getArchDefines(const LangOptions &Opts,
-                              MacroBuilder &Builder) const {
+  void getArchDefines(const LangOptions &Opts, MacroBuilder &Builder) const {
     Builder.defineMacro("__le32__");
     Builder.defineMacro("__pnacl__");
   }
-  virtual void getTargetDefines(const LangOptions &Opts,
-                                MacroBuilder &Builder) const {
-    Builder.defineMacro("__LITTLE_ENDIAN__");
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override {
     getArchDefines(Opts, Builder);
   }
-  virtual bool hasFeature(StringRef Feature) const {
+  bool hasFeature(StringRef Feature) const override {
     return Feature == "pnacl";
   }
-  virtual void getTargetBuiltins(const Builtin::Info *&Records,
-                                 unsigned &NumRecords) const {
+  void getTargetBuiltins(const Builtin::Info *&Records,
+                         unsigned &NumRecords) const override {
   }
-  virtual BuiltinVaListKind getBuiltinVaListKind() const {
+  BuiltinVaListKind getBuiltinVaListKind() const override {
     return TargetInfo::PNaClABIBuiltinVaList;
   }
-  virtual void getGCCRegNames(const char * const *&Names,
-                              unsigned &NumNames) const;
-  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
-                                unsigned &NumAliases) const;
-  virtual bool validateAsmConstraint(const char *&Name,
-                                     TargetInfo::ConstraintInfo &Info) const {
+  void getGCCRegNames(const char * const *&Names,
+                      unsigned &NumNames) const override;
+  void getGCCRegAliases(const GCCRegAlias *&Aliases,
+                        unsigned &NumAliases) const override;
+  bool validateAsmConstraint(const char *&Name,
+                             TargetInfo::ConstraintInfo &Info) const override {
     return false;
   }
 
-  virtual const char *getClobbers() const {
+  const char *getClobbers() const override {
     return "";
   }
 };
 
 void PNaClTargetInfo::getGCCRegNames(const char * const *&Names,
                                      unsigned &NumNames) const {
-  Names = NULL;
+  Names = nullptr;
   NumNames = 0;
 }
 
 void PNaClTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
                                        unsigned &NumAliases) const {
-  Aliases = NULL;
+  Aliases = nullptr;
   NumAliases = 0;
 }
 } // end anonymous namespace.
@@ -5505,28 +6009,28 @@
       // These must be defined in sorted order!
       NoAsmVariants = true;
     }
-    virtual void getTargetDefines(const LangOptions &Opts,
-                                  MacroBuilder &Builder) const {
+    void getTargetDefines(const LangOptions &Opts,
+                          MacroBuilder &Builder) const override {
       DefineStd(Builder, "SPIR", Opts);
     }
-    virtual bool hasFeature(StringRef Feature) const {
+    bool hasFeature(StringRef Feature) const override {
       return Feature == "spir";
     }
-    
-    virtual void getTargetBuiltins(const Builtin::Info *&Records,
-                                   unsigned &NumRecords) const {}
-    virtual const char *getClobbers() const {
+
+    void getTargetBuiltins(const Builtin::Info *&Records,
+                           unsigned &NumRecords) const override {}
+    const char *getClobbers() const override {
       return "";
     }
-    virtual void getGCCRegNames(const char * const *&Names,
-                                unsigned &NumNames) const {}
-    virtual bool validateAsmConstraint(const char *&Name,
-                                       TargetInfo::ConstraintInfo &info) const {
+    void getGCCRegNames(const char * const *&Names,
+                        unsigned &NumNames) const override {}
+    bool validateAsmConstraint(const char *&Name,
+                               TargetInfo::ConstraintInfo &info) const override {
       return true;
     }
-    virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
-                                  unsigned &NumAliases) const {}
-    virtual BuiltinVaListKind getBuiltinVaListKind() const {
+    void getGCCRegAliases(const GCCRegAlias *&Aliases,
+                          unsigned &NumAliases) const override {}
+    BuiltinVaListKind getBuiltinVaListKind() const override {
       return TargetInfo::VoidPtrBuiltinVaList;
     }
   };
@@ -5539,13 +6043,11 @@
       SizeType     = TargetInfo::UnsignedInt;
       PtrDiffType = IntPtrType = TargetInfo::SignedInt;
       DescriptionString
-        = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-"
-          "f32:32:32-f64:64:64-v16:16:16-v24:32:32-v32:32:32-v48:64:64-"
-          "v64:64:64-v96:128:128-v128:128:128-v192:256:256-v256:256:256-"
-          "v512:512:512-v1024:1024:1024";
+        = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-"
+          "v96:128-v192:256-v256:256-v512:512-v1024:1024";
     }
-    virtual void getTargetDefines(const LangOptions &Opts,
-                                  MacroBuilder &Builder) const {
+    void getTargetDefines(const LangOptions &Opts,
+                          MacroBuilder &Builder) const override {
       DefineStd(Builder, "SPIR32", Opts);
     }
   };
@@ -5556,14 +6058,11 @@
       PointerWidth = PointerAlign = 64;
       SizeType     = TargetInfo::UnsignedLong;
       PtrDiffType = IntPtrType = TargetInfo::SignedLong;
-      DescriptionString
-        = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-"
-          "f32:32:32-f64:64:64-v16:16:16-v24:32:32-v32:32:32-v48:64:64-"
-          "v64:64:64-v96:128:128-v128:128:128-v192:256:256-v256:256:256-"
-          "v512:512:512-v1024:1024:1024";
+      DescriptionString = "e-i64:64-v16:16-v24:32-v32:32-v48:64-"
+                          "v96:128-v192:256-v256:256-v512:512-v1024:1024";
     }
-    virtual void getTargetDefines(const LangOptions &Opts,
-                                  MacroBuilder &Builder) const {
+    void getTargetDefines(const LangOptions &Opts,
+                          MacroBuilder &Builder) const override {
       DefineStd(Builder, "SPIR64", Opts);
     }
   };
@@ -5585,27 +6084,26 @@
     WCharType = UnsignedChar;
     WIntType = UnsignedInt;
     UseZeroLengthBitfieldAlignment = true;
-    DescriptionString = "e-p:32:32:32-a0:0:32-n32"
-                        "-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32"
-                        "-f16:16:32-f32:32:32-f64:32:32";
+    DescriptionString = "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:32"
+                        "-f64:32-a:0:32-n32";
   }
-  virtual void getTargetDefines(const LangOptions &Opts,
-                                MacroBuilder &Builder) const {
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override {
     Builder.defineMacro("__XS1B__");
   }
-  virtual void getTargetBuiltins(const Builtin::Info *&Records,
-                                 unsigned &NumRecords) const {
+  void getTargetBuiltins(const Builtin::Info *&Records,
+                         unsigned &NumRecords) const override {
     Records = BuiltinInfo;
     NumRecords = clang::XCore::LastTSBuiltin-Builtin::FirstTSBuiltin;
   }
-  virtual BuiltinVaListKind getBuiltinVaListKind() const {
+  BuiltinVaListKind getBuiltinVaListKind() const override {
     return TargetInfo::VoidPtrBuiltinVaList;
   }
-  virtual const char *getClobbers() const {
+  const char *getClobbers() const override {
     return "";
   }
-  virtual void getGCCRegNames(const char * const *&Names,
-                              unsigned &NumNames) const {
+  void getGCCRegNames(const char * const *&Names,
+                      unsigned &NumNames) const override {
     static const char * const GCCRegNames[] = {
       "r0",   "r1",   "r2",   "r3",   "r4",   "r5",   "r6",   "r7",
       "r8",   "r9",   "r10",  "r11",  "cp",   "dp",   "sp",   "lr"
@@ -5613,15 +6111,19 @@
     Names = GCCRegNames;
     NumNames = llvm::array_lengthof(GCCRegNames);
   }
-  virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
-                                unsigned &NumAliases) const {
-    Aliases = NULL;
+  void getGCCRegAliases(const GCCRegAlias *&Aliases,
+                        unsigned &NumAliases) const override {
+    Aliases = nullptr;
     NumAliases = 0;
   }
-  virtual bool validateAsmConstraint(const char *&Name,
-                                     TargetInfo::ConstraintInfo &Info) const {
+  bool validateAsmConstraint(const char *&Name,
+                             TargetInfo::ConstraintInfo &Info) const override {
     return false;
   }
+  int getEHDataRegisterNumber(unsigned RegNo) const override {
+    // R0=ExceptionPointerRegister R1=ExceptionSelectorRegister
+    return (RegNo < 2)? RegNo : -1;
+  }
 };
 
 const Builtin::Info XCoreTargetInfo::BuiltinInfo[] = {
@@ -5642,7 +6144,7 @@
 
   switch (Triple.getArch()) {
   default:
-    return NULL;
+    return nullptr;
 
   case llvm::Triple::xcore:
     return new XCoreTargetInfo(Triple);
@@ -5651,35 +6153,85 @@
     return new HexagonTargetInfo(Triple);
 
   case llvm::Triple::aarch64:
+  case llvm::Triple::arm64:
+    if (Triple.isOSDarwin())
+      return new DarwinAArch64TargetInfo(Triple);
+
     switch (os) {
     case llvm::Triple::Linux:
-      return new LinuxTargetInfo<AArch64TargetInfo>(Triple);
+      return new LinuxTargetInfo<AArch64leTargetInfo>(Triple);
+    case llvm::Triple::NetBSD:
+      return new NetBSDTargetInfo<AArch64leTargetInfo>(Triple);
     default:
-      return new AArch64TargetInfo(Triple);
+      return new AArch64leTargetInfo(Triple);
+    }
+
+  case llvm::Triple::aarch64_be:
+  case llvm::Triple::arm64_be:
+    switch (os) {
+    case llvm::Triple::Linux:
+      return new LinuxTargetInfo<AArch64beTargetInfo>(Triple);
+    case llvm::Triple::NetBSD:
+      return new NetBSDTargetInfo<AArch64beTargetInfo>(Triple);
+    default:
+      return new AArch64beTargetInfo(Triple);
     }
 
   case llvm::Triple::arm:
   case llvm::Triple::thumb:
+    if (Triple.isOSBinFormatMachO())
+      return new DarwinARMTargetInfo(Triple);
+
+    switch (os) {
+    case llvm::Triple::Linux:
+      return new LinuxTargetInfo<ARMleTargetInfo>(Triple);
+    case llvm::Triple::FreeBSD:
+      return new FreeBSDTargetInfo<ARMleTargetInfo>(Triple);
+    case llvm::Triple::NetBSD:
+      return new NetBSDTargetInfo<ARMleTargetInfo>(Triple);
+    case llvm::Triple::OpenBSD:
+      return new OpenBSDTargetInfo<ARMleTargetInfo>(Triple);
+    case llvm::Triple::Bitrig:
+      return new BitrigTargetInfo<ARMleTargetInfo>(Triple);
+    case llvm::Triple::RTEMS:
+      return new RTEMSTargetInfo<ARMleTargetInfo>(Triple);
+    case llvm::Triple::NaCl:
+      return new NaClTargetInfo<ARMleTargetInfo>(Triple);
+    case llvm::Triple::Win32:
+      switch (Triple.getEnvironment()) {
+      default:
+        return new ARMleTargetInfo(Triple);
+      case llvm::Triple::Itanium:
+        return new ItaniumWindowsARMleTargetInfo(Triple);
+      case llvm::Triple::MSVC:
+        return new MicrosoftARMleTargetInfo(Triple);
+      }
+    default:
+      return new ARMleTargetInfo(Triple);
+    }
+
+  case llvm::Triple::armeb:
+  case llvm::Triple::thumbeb:
     if (Triple.isOSDarwin())
       return new DarwinARMTargetInfo(Triple);
 
     switch (os) {
     case llvm::Triple::Linux:
-      return new LinuxTargetInfo<ARMTargetInfo>(Triple);
+      return new LinuxTargetInfo<ARMbeTargetInfo>(Triple);
     case llvm::Triple::FreeBSD:
-      return new FreeBSDTargetInfo<ARMTargetInfo>(Triple);
+      return new FreeBSDTargetInfo<ARMbeTargetInfo>(Triple);
     case llvm::Triple::NetBSD:
-      return new NetBSDTargetInfo<ARMTargetInfo>(Triple);
+      return new NetBSDTargetInfo<ARMbeTargetInfo>(Triple);
     case llvm::Triple::OpenBSD:
-      return new OpenBSDTargetInfo<ARMTargetInfo>(Triple);
+      return new OpenBSDTargetInfo<ARMbeTargetInfo>(Triple);
     case llvm::Triple::Bitrig:
-      return new BitrigTargetInfo<ARMTargetInfo>(Triple);
+      return new BitrigTargetInfo<ARMbeTargetInfo>(Triple);
     case llvm::Triple::RTEMS:
-      return new RTEMSTargetInfo<ARMTargetInfo>(Triple);
+      return new RTEMSTargetInfo<ARMbeTargetInfo>(Triple);
     case llvm::Triple::NaCl:
-      return new NaClTargetInfo<ARMTargetInfo>(Triple);
+      return new NaClTargetInfo<ARMbeTargetInfo>(Triple);
     default:
-      return new ARMTargetInfo(Triple);
+      return new ARMbeTargetInfo(Triple);
     }
 
   case llvm::Triple::msp430:
@@ -5760,7 +6312,7 @@
       case llvm::Triple::NaCl:
         return new NaClTargetInfo<PNaClTargetInfo>(Triple);
       default:
-        return NULL;
+        return nullptr;
     }
 
   case llvm::Triple::ppc:
@@ -5885,12 +6437,19 @@
       return new MinixTargetInfo<X86_32TargetInfo>(Triple);
     case llvm::Triple::Solaris:
       return new SolarisTargetInfo<X86_32TargetInfo>(Triple);
-    case llvm::Triple::Cygwin:
-      return new CygwinX86_32TargetInfo(Triple);
-    case llvm::Triple::MinGW32:
-      return new MinGWX86_32TargetInfo(Triple);
-    case llvm::Triple::Win32:
-      return new VisualStudioWindowsX86_32TargetInfo(Triple);
+    case llvm::Triple::Win32: {
+      switch (Triple.getEnvironment()) {
+      default:
+        return new X86_32TargetInfo(Triple);
+      case llvm::Triple::Cygnus:
+        return new CygwinX86_32TargetInfo(Triple);
+      case llvm::Triple::GNU:
+        return new MinGWX86_32TargetInfo(Triple);
+      case llvm::Triple::Itanium:
+      case llvm::Triple::MSVC:
+        return new MicrosoftX86_32TargetInfo(Triple);
+      }
+    }
     case llvm::Triple::Haiku:
       return new HaikuX86_32TargetInfo(Triple);
     case llvm::Triple::RTEMS:
@@ -5902,7 +6461,7 @@
     }
 
   case llvm::Triple::x86_64:
-    if (Triple.isOSDarwin() || Triple.getEnvironment() == llvm::Triple::MachO)
+    if (Triple.isOSDarwin() || Triple.isOSBinFormatMachO())
       return new DarwinX86_64TargetInfo(Triple);
 
     switch (os) {
@@ -5924,10 +6483,16 @@
       return new KFreeBSDTargetInfo<X86_64TargetInfo>(Triple);
     case llvm::Triple::Solaris:
       return new SolarisTargetInfo<X86_64TargetInfo>(Triple);
-    case llvm::Triple::MinGW32:
-      return new MinGWX86_64TargetInfo(Triple);
-    case llvm::Triple::Win32:   // This is what Triple.h supports now.
-      return new VisualStudioWindowsX86_64TargetInfo(Triple);
+    case llvm::Triple::Win32: {
+      switch (Triple.getEnvironment()) {
+      default:
+        return new X86_64TargetInfo(Triple);
+      case llvm::Triple::GNU:
+        return new MinGWX86_64TargetInfo(Triple);
+      case llvm::Triple::MSVC:
+        return new MicrosoftX86_64TargetInfo(Triple);
+      }
+    }
     case llvm::Triple::NaCl:
       return new NaClTargetInfo<X86_64TargetInfo>(Triple);
     default:
@@ -5937,13 +6502,13 @@
     case llvm::Triple::spir: {
       if (Triple.getOS() != llvm::Triple::UnknownOS ||
           Triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
-        return NULL;
+        return nullptr;
       return new SPIR32TargetInfo(Triple);
     }
     case llvm::Triple::spir64: {
       if (Triple.getOS() != llvm::Triple::UnknownOS ||
           Triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
-        return NULL;
+        return nullptr;
       return new SPIR64TargetInfo(Triple);
     }
   }
@@ -5951,40 +6516,35 @@
 
 /// CreateTargetInfo - Return the target info object for the specified target
 /// triple.
-TargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags,
-                                         TargetOptions *Opts) {
+TargetInfo *
+TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags,
+                             const std::shared_ptr<TargetOptions> &Opts) {
   llvm::Triple Triple(Opts->Triple);
 
   // Construct the target
-  OwningPtr<TargetInfo> Target(AllocateTarget(Triple));
+  std::unique_ptr<TargetInfo> Target(AllocateTarget(Triple));
   if (!Target) {
     Diags.Report(diag::err_target_unknown_triple) << Triple.str();
-    return 0;
+    return nullptr;
   }
-  Target->setTargetOpts(Opts);
+  Target->TargetOpts = Opts;
 
   // Set the target CPU if specified.
   if (!Opts->CPU.empty() && !Target->setCPU(Opts->CPU)) {
     Diags.Report(diag::err_target_unknown_cpu) << Opts->CPU;
-    return 0;
+    return nullptr;
   }
 
   // Set the target ABI if specified.
   if (!Opts->ABI.empty() && !Target->setABI(Opts->ABI)) {
     Diags.Report(diag::err_target_unknown_abi) << Opts->ABI;
-    return 0;
-  }
-
-  // Set the target C++ ABI.
-  if (!Opts->CXXABI.empty() && !Target->setCXXABI(Opts->CXXABI)) {
-    Diags.Report(diag::err_target_unknown_cxxabi) << Opts->CXXABI;
-    return 0;
+    return nullptr;
   }
 
   // Set the fp math unit.
   if (!Opts->FPMath.empty() && !Target->setFPMath(Opts->FPMath)) {
     Diags.Report(diag::err_target_unknown_fpmath) << Opts->FPMath;
-    return 0;
+    return nullptr;
   }
 
   // Compute the default target features, we need the target to handle this
@@ -6010,7 +6570,7 @@
          ie = Features.end(); it != ie; ++it)
     Opts->Features.push_back((it->second ? "+" : "-") + it->first().str());
   if (!Target->handleTargetFeatures(Opts->Features, Diags))
-    return 0;
+    return nullptr;
 
-  return Target.take();
+  return Target.release();
 }
diff --git a/lib/Basic/TokenKinds.cpp b/lib/Basic/TokenKinds.cpp
index 6ce076e..3b1f8fe 100644
--- a/lib/Basic/TokenKinds.cpp
+++ b/lib/Basic/TokenKinds.cpp
@@ -12,27 +12,37 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Basic/TokenKinds.h"
-#include <cassert>
+#include "llvm/Support/ErrorHandling.h"
 using namespace clang;
 
 static const char * const TokNames[] = {
 #define TOK(X) #X,
 #define KEYWORD(X,Y) #X,
 #include "clang/Basic/TokenKinds.def"
-  0
+  nullptr
 };
 
-const char *tok::getTokenName(enum TokenKind Kind) {
-  assert(Kind < tok::NUM_TOKENS);
-  return TokNames[Kind];
+const char *tok::getTokenName(TokenKind Kind) {
+  if (Kind < tok::NUM_TOKENS)
+    return TokNames[Kind];
+  llvm_unreachable("unknown TokenKind");
+  return nullptr;
 }
 
-const char *tok::getTokenSimpleSpelling(enum TokenKind Kind) {
+const char *tok::getPunctuatorSpelling(TokenKind Kind) {
   switch (Kind) {
 #define PUNCTUATOR(X,Y) case X: return Y;
 #include "clang/Basic/TokenKinds.def"
   default: break;
   }
+  return nullptr;
+}
 
-  return 0;
+const char *tok::getKeywordSpelling(TokenKind Kind) {
+  switch (Kind) {
+#define KEYWORD(X,Y) case kw_ ## X: return #X;
+#include "clang/Basic/TokenKinds.def"
+    default: break;
+  }
+  return nullptr;
 }
diff --git a/lib/Basic/Version.cpp b/lib/Basic/Version.cpp
index 88b827d..c2b7753 100644
--- a/lib/Basic/Version.cpp
+++ b/lib/Basic/Version.cpp
@@ -13,7 +13,7 @@
 
 #include "clang/Basic/Version.h"
 #include "clang/Basic/LLVM.h"
-#include "llvm/Config/config.h"
+#include "clang/Config/config.h"
 #include "llvm/Support/raw_ostream.h"
 #include <cstdlib>
 #include <cstring>
@@ -102,11 +102,11 @@
       OS << Revision;
     }
     OS << ')';
-  }  
+  }
   // Support LLVM in a separate repository.
   std::string LLVMRev = getLLVMRevision();
   if (!LLVMRev.empty() && LLVMRev != Revision) {
-    OS << " (";    
+    OS << " (";
     std::string LLVMRepo = getLLVMRepositoryPath();
     if (!LLVMRepo.empty())
       OS << LLVMRepo << ' ';
@@ -116,17 +116,21 @@
 }
 
 std::string getClangFullVersion() {
+  return getClangToolFullVersion("clang");
+}
+
+std::string getClangToolFullVersion(StringRef ToolName) {
   std::string buf;
   llvm::raw_string_ostream OS(buf);
 #ifdef CLANG_VENDOR
   OS << CLANG_VENDOR;
 #endif
-  OS << "clang version " CLANG_VERSION_STRING " "
+  OS << ToolName << " version " CLANG_VERSION_STRING " "
      << getClangFullRepositoryVersion();
 
   // If vendor supplied, include the base LLVM version as well.
 #ifdef CLANG_VENDOR
-  OS << " (based on LLVM " << PACKAGE_VERSION << ")";
+  OS << " (based on " << BACKEND_PACKAGE_STRING << ")";
 #endif
 
   return OS.str();
diff --git a/lib/Basic/VirtualFileSystem.cpp b/lib/Basic/VirtualFileSystem.cpp
new file mode 100644
index 0000000..a5c83b8
--- /dev/null
+++ b/lib/Basic/VirtualFileSystem.cpp
@@ -0,0 +1,1209 @@
+//===- VirtualFileSystem.cpp - Virtual File System Layer --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// This file implements the VirtualFileSystem interface.
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/VirtualFileSystem.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/YAMLParser.h"
+#include <atomic>
+#include <memory>
+
+using namespace clang;
+using namespace clang::vfs;
+using namespace llvm;
+using llvm::sys::fs::file_status;
+using llvm::sys::fs::file_type;
+using llvm::sys::fs::perms;
+using llvm::sys::fs::UniqueID;
+
+Status::Status(const file_status &Status)
+    : UID(Status.getUniqueID()), MTime(Status.getLastModificationTime()),
+      User(Status.getUser()), Group(Status.getGroup()), Size(Status.getSize()),
+      Type(Status.type()), Perms(Status.permissions()), IsVFSMapped(false)  {}
+
+Status::Status(StringRef Name, StringRef ExternalName, UniqueID UID,
+               sys::TimeValue MTime, uint32_t User, uint32_t Group,
+               uint64_t Size, file_type Type, perms Perms)
+    : Name(Name), UID(UID), MTime(MTime), User(User), Group(Group), Size(Size),
+      Type(Type), Perms(Perms), IsVFSMapped(false) {}
+
+bool Status::equivalent(const Status &Other) const {
+  return getUniqueID() == Other.getUniqueID();
+}
+bool Status::isDirectory() const {
+  return Type == file_type::directory_file;
+}
+bool Status::isRegularFile() const {
+  return Type == file_type::regular_file;
+}
+bool Status::isOther() const {
+  return exists() && !isRegularFile() && !isDirectory() && !isSymlink();
+}
+bool Status::isSymlink() const {
+  return Type == file_type::symlink_file;
+}
+bool Status::isStatusKnown() const {
+  return Type != file_type::status_error;
+}
+bool Status::exists() const {
+  return isStatusKnown() && Type != file_type::file_not_found;
+}
+
+File::~File() {}
+
+FileSystem::~FileSystem() {}
+
+std::error_code FileSystem::getBufferForFile(
+    const llvm::Twine &Name, std::unique_ptr<MemoryBuffer> &Result,
+    int64_t FileSize, bool RequiresNullTerminator, bool IsVolatile) {
+  std::unique_ptr<File> F;
+  if (std::error_code EC = openFileForRead(Name, F))
+    return EC;
+
+  std::error_code EC =
+      F->getBuffer(Name, Result, FileSize, RequiresNullTerminator, IsVolatile);
+  return EC;
+}
+
+//===-----------------------------------------------------------------------===/
+// RealFileSystem implementation
+//===-----------------------------------------------------------------------===/
+
+namespace {
+/// \brief Wrapper around a raw file descriptor.
+class RealFile : public File {
+  int FD;
+  Status S;
+  friend class RealFileSystem;
+  RealFile(int FD) : FD(FD) {
+    assert(FD >= 0 && "Invalid or inactive file descriptor");
+  }
+
+public:
+  ~RealFile();
+  ErrorOr<Status> status() override;
+  std::error_code getBuffer(const Twine &Name,
+                            std::unique_ptr<MemoryBuffer> &Result,
+                            int64_t FileSize = -1,
+                            bool RequiresNullTerminator = true,
+                            bool IsVolatile = false) override;
+  std::error_code close() override;
+  void setName(StringRef Name) override;
+};
+} // end anonymous namespace
+RealFile::~RealFile() { close(); }
+
+ErrorOr<Status> RealFile::status() {
+  assert(FD != -1 && "cannot stat closed file");
+  if (!S.isStatusKnown()) {
+    file_status RealStatus;
+    if (std::error_code EC = sys::fs::status(FD, RealStatus))
+      return EC;
+    Status NewS(RealStatus);
+    NewS.setName(S.getName());
+    S = std::move(NewS);
+  }
+  return S;
+}
+
+std::error_code RealFile::getBuffer(const Twine &Name,
+                                    std::unique_ptr<MemoryBuffer> &Result,
+                                    int64_t FileSize,
+                                    bool RequiresNullTerminator,
+                                    bool IsVolatile) {
+  assert(FD != -1 && "cannot get buffer for closed file");
+  ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
+      MemoryBuffer::getOpenFile(FD, Name.str().c_str(), FileSize,
+                                RequiresNullTerminator, IsVolatile);
+  if (std::error_code EC = BufferOrErr.getError())
+    return EC;
+  Result = std::move(BufferOrErr.get());
+  return std::error_code();
+}
+
+// FIXME: This is terrible, we need this for ::close.
+#if !defined(_MSC_VER) && !defined(__MINGW32__)
+#include <unistd.h>
+#include <sys/uio.h>
+#else
+#include <io.h>
+#ifndef S_ISFIFO
+#define S_ISFIFO(x) (0)
+#endif
+#endif
+std::error_code RealFile::close() {
+  if (::close(FD))
+    return std::error_code(errno, std::generic_category());
+  FD = -1;
+  return std::error_code();
+}
+
+void RealFile::setName(StringRef Name) {
+  S.setName(Name);
+}
+
+namespace {
+/// \brief The file system according to your operating system.
+class RealFileSystem : public FileSystem {
+public:
+  ErrorOr<Status> status(const Twine &Path) override;
+  std::error_code openFileForRead(const Twine &Path,
+                                  std::unique_ptr<File> &Result) override;
+  directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override;
+};
+} // end anonymous namespace
+
+ErrorOr<Status> RealFileSystem::status(const Twine &Path) {
+  sys::fs::file_status RealStatus;
+  if (std::error_code EC = sys::fs::status(Path, RealStatus))
+    return EC;
+  Status Result(RealStatus);
+  Result.setName(Path.str());
+  return Result;
+}
+
+std::error_code RealFileSystem::openFileForRead(const Twine &Name,
+                                                std::unique_ptr<File> &Result) {
+  int FD;
+  if (std::error_code EC = sys::fs::openFileForRead(Name, FD))
+    return EC;
+  Result.reset(new RealFile(FD));
+  Result->setName(Name.str());
+  return std::error_code();
+}
+
+IntrusiveRefCntPtr<FileSystem> vfs::getRealFileSystem() {
+  static IntrusiveRefCntPtr<FileSystem> FS = new RealFileSystem();
+  return FS;
+}
+
+namespace {
+class RealFSDirIter : public clang::vfs::detail::DirIterImpl {
+  std::string Path;
+  llvm::sys::fs::directory_iterator Iter;
+public:
+  RealFSDirIter(const Twine &_Path, std::error_code &EC)
+      : Path(_Path.str()), Iter(Path, EC) {
+    if (!EC && Iter != llvm::sys::fs::directory_iterator()) {
+      llvm::sys::fs::file_status S;
+      EC = Iter->status(S);
+      if (!EC) {
+        CurrentEntry = Status(S);
+        CurrentEntry.setName(Iter->path());
+      }
+    }
+  }
+
+  std::error_code increment() override {
+    std::error_code EC;
+    Iter.increment(EC);
+    if (EC) {
+      return EC;
+    } else if (Iter == llvm::sys::fs::directory_iterator()) {
+      CurrentEntry = Status();
+    } else {
+      llvm::sys::fs::file_status S;
+      EC = Iter->status(S);
+      CurrentEntry = Status(S);
+      CurrentEntry.setName(Iter->path());
+    }
+    return EC;
+  }
+};
+}
+
+directory_iterator RealFileSystem::dir_begin(const Twine &Dir,
+                                             std::error_code &EC) {
+  return directory_iterator(std::make_shared<RealFSDirIter>(Dir, EC));
+}
+
+//===-----------------------------------------------------------------------===/
+// OverlayFileSystem implementation
+//===-----------------------------------------------------------------------===/
+OverlayFileSystem::OverlayFileSystem(IntrusiveRefCntPtr<FileSystem> BaseFS) {
+  pushOverlay(BaseFS);
+}
+
+void OverlayFileSystem::pushOverlay(IntrusiveRefCntPtr<FileSystem> FS) {
+  FSList.push_back(FS);
+}
+
+ErrorOr<Status> OverlayFileSystem::status(const Twine &Path) {
+  // FIXME: handle symlinks that cross file systems
+  for (iterator I = overlays_begin(), E = overlays_end(); I != E; ++I) {
+    ErrorOr<Status> Status = (*I)->status(Path);
+    if (Status || Status.getError() != llvm::errc::no_such_file_or_directory)
+      return Status;
+  }
+  return make_error_code(llvm::errc::no_such_file_or_directory);
+}
+
+std::error_code
+OverlayFileSystem::openFileForRead(const llvm::Twine &Path,
+                                   std::unique_ptr<File> &Result) {
+  // FIXME: handle symlinks that cross file systems
+  for (iterator I = overlays_begin(), E = overlays_end(); I != E; ++I) {
+    std::error_code EC = (*I)->openFileForRead(Path, Result);
+    if (!EC || EC != llvm::errc::no_such_file_or_directory)
+      return EC;
+  }
+  return make_error_code(llvm::errc::no_such_file_or_directory);
+}
+
+clang::vfs::detail::DirIterImpl::~DirIterImpl() { }
+
+namespace {
+class OverlayFSDirIterImpl : public clang::vfs::detail::DirIterImpl {
+  OverlayFileSystem &Overlays;
+  std::string Path;
+  OverlayFileSystem::iterator CurrentFS;
+  directory_iterator CurrentDirIter;
+  llvm::StringSet<> SeenNames;
+
+  std::error_code incrementFS() {
+    assert(CurrentFS != Overlays.overlays_end() && "incrementing past end");
+    ++CurrentFS;
+    for (auto E = Overlays.overlays_end(); CurrentFS != E; ++CurrentFS) {
+      std::error_code EC;
+      CurrentDirIter = (*CurrentFS)->dir_begin(Path, EC);
+      if (EC && EC != errc::no_such_file_or_directory)
+        return EC;
+      if (CurrentDirIter != directory_iterator())
+        break; // found
+    }
+    return std::error_code();
+  }
+
+  std::error_code incrementDirIter(bool IsFirstTime) {
+    assert((IsFirstTime || CurrentDirIter != directory_iterator()) &&
+           "incrementing past end");
+    std::error_code EC;
+    if (!IsFirstTime)
+      CurrentDirIter.increment(EC);
+    if (!EC && CurrentDirIter == directory_iterator())
+      EC = incrementFS();
+    return EC;
+  }
+
+  std::error_code incrementImpl(bool IsFirstTime) {
+    while (true) {
+      std::error_code EC = incrementDirIter(IsFirstTime);
+      if (EC || CurrentDirIter == directory_iterator()) {
+        CurrentEntry = Status();
+        return EC;
+      }
+      CurrentEntry = *CurrentDirIter;
+      StringRef Name = llvm::sys::path::filename(CurrentEntry.getName());
+      if (SeenNames.insert(Name))
+        return EC; // name not seen before
+    }
+    llvm_unreachable("returned above");
+  }
+
+public:
+  OverlayFSDirIterImpl(const Twine &Path, OverlayFileSystem &FS,
+                       std::error_code &EC)
+      : Overlays(FS), Path(Path.str()), CurrentFS(Overlays.overlays_begin()) {
+    CurrentDirIter = (*CurrentFS)->dir_begin(Path, EC);
+    EC = incrementImpl(true);
+  }
+
+  std::error_code increment() override { return incrementImpl(false); }
+};
+} // end anonymous namespace
+
+directory_iterator OverlayFileSystem::dir_begin(const Twine &Dir,
+                                                std::error_code &EC) {
+  return directory_iterator(
+      std::make_shared<OverlayFSDirIterImpl>(Dir, *this, EC));
+}
+
+//===-----------------------------------------------------------------------===/
+// VFSFromYAML implementation
+//===-----------------------------------------------------------------------===/
+
+// Allow DenseMap<StringRef, ...>.  This is useful below because we know all the
+// strings are literals and will outlive the map, and there is no reason to
+// store them.
+namespace llvm {
+  template<>
+  struct DenseMapInfo<StringRef> {
+    // This assumes that "" will never be a valid key.
+    static inline StringRef getEmptyKey() { return StringRef(""); }
+    static inline StringRef getTombstoneKey() { return StringRef(); }
+    static unsigned getHashValue(StringRef Val) { return HashString(Val); }
+    static bool isEqual(StringRef LHS, StringRef RHS) { return LHS == RHS; }
+  };
+}
+
+namespace {
+
+enum EntryKind {
+  EK_Directory,
+  EK_File
+};
+
+/// \brief A single file or directory in the VFS.
+class Entry {
+  EntryKind Kind;
+  std::string Name;
+
+public:
+  virtual ~Entry();
+  Entry(EntryKind K, StringRef Name) : Kind(K), Name(Name) {}
+  StringRef getName() const { return Name; }
+  EntryKind getKind() const { return Kind; }
+};
+
+class DirectoryEntry : public Entry {
+  std::vector<Entry *> Contents;
+  Status S;
+
+public:
+  virtual ~DirectoryEntry();
+  DirectoryEntry(StringRef Name, std::vector<Entry *> Contents, Status S)
+      : Entry(EK_Directory, Name), Contents(std::move(Contents)),
+        S(std::move(S)) {}
+  Status getStatus() { return S; }
+  typedef std::vector<Entry *>::iterator iterator;
+  iterator contents_begin() { return Contents.begin(); }
+  iterator contents_end() { return Contents.end(); }
+  static bool classof(const Entry *E) { return E->getKind() == EK_Directory; }
+};
+
+class FileEntry : public Entry {
+public:
+  enum NameKind {
+    NK_NotSet,
+    NK_External,
+    NK_Virtual
+  };
+private:
+  std::string ExternalContentsPath;
+  NameKind UseName;
+public:
+  FileEntry(StringRef Name, StringRef ExternalContentsPath, NameKind UseName)
+      : Entry(EK_File, Name), ExternalContentsPath(ExternalContentsPath),
+        UseName(UseName) {}
+  StringRef getExternalContentsPath() const { return ExternalContentsPath; }
+  /// \brief whether to use the external path as the name for this file.
+  bool useExternalName(bool GlobalUseExternalName) const {
+    return UseName == NK_NotSet ? GlobalUseExternalName
+                                : (UseName == NK_External);
+  }
+  static bool classof(const Entry *E) { return E->getKind() == EK_File; }
+};
+
+class VFSFromYAML;
+
+class VFSFromYamlDirIterImpl : public clang::vfs::detail::DirIterImpl {
+  std::string Dir;
+  VFSFromYAML &FS;
+  DirectoryEntry::iterator Current, End;
+public:
+  VFSFromYamlDirIterImpl(const Twine &Path, VFSFromYAML &FS,
+                         DirectoryEntry::iterator Begin,
+                         DirectoryEntry::iterator End, std::error_code &EC);
+  std::error_code increment() override;
+};
+
+/// \brief A virtual file system parsed from a YAML file.
+///
+/// Currently, this class allows creating virtual directories and mapping
+/// virtual file paths to existing external files, available in \c ExternalFS.
+///
+/// The basic structure of the parsed file is:
+/// \verbatim
+/// {
+///   'version': <version number>,
+///   <optional configuration>
+///   'roots': [
+///              <directory entries>
+///            ]
+/// }
+/// \endverbatim
+///
+/// All configuration options are optional.
+///   'case-sensitive': <boolean, default=true>
+///   'use-external-names': <boolean, default=true>
+///
+/// Virtual directories are represented as
+/// \verbatim
+/// {
+///   'type': 'directory',
+///   'name': <string>,
+///   'contents': [ <file or directory entries> ]
+/// }
+/// \endverbatim
+///
+/// The default attributes for virtual directories are:
+/// \verbatim
+/// MTime = now() when created
+/// Perms = 0777
+/// User = Group = 0
+/// Size = 0
+/// UniqueID = unspecified unique value
+/// \endverbatim
+///
+/// Re-mapped files are represented as
+/// \verbatim
+/// {
+///   'type': 'file',
+///   'name': <string>,
+///   'use-external-name': <boolean> # Optional
+///   'external-contents': <path to external file>)
+/// }
+/// \endverbatim
+///
+/// and inherit their attributes from the external contents.
+///
+/// In both cases, the 'name' field may contain multiple path components (e.g.
+/// /path/to/file). However, any directory that contains more than one child
+/// must be uniquely represented by a directory entry.
+class VFSFromYAML : public vfs::FileSystem {
+  std::vector<Entry *> Roots; ///< The root(s) of the virtual file system.
+  /// \brief The file system to use for external references.
+  IntrusiveRefCntPtr<FileSystem> ExternalFS;
+
+  /// @name Configuration
+  /// @{
+
+  /// \brief Whether to perform case-sensitive comparisons.
+  ///
+  /// Currently, case-insensitive matching only works correctly with ASCII.
+  bool CaseSensitive;
+
+  /// \brief Whether to use to use the value of 'external-contents' for the
+  /// names of files.  This global value is overridable on a per-file basis.
+  bool UseExternalNames;
+  /// @}
+
+  friend class VFSFromYAMLParser;
+
+private:
+  VFSFromYAML(IntrusiveRefCntPtr<FileSystem> ExternalFS)
+      : ExternalFS(ExternalFS), CaseSensitive(true), UseExternalNames(true) {}
+
+  /// \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,
+                              sys::path::const_iterator End, Entry *From);
+
+  /// \brief Get the status of a given an \c Entry.
+  ErrorOr<Status> status(const Twine &Path, Entry *E);
+
+public:
+  ~VFSFromYAML();
+
+  /// \brief Parses \p Buffer, which is expected to be in YAML format and
+  /// returns a virtual file system representing its contents.
+  ///
+  /// Takes ownership of \p Buffer.
+  static VFSFromYAML *create(MemoryBuffer *Buffer,
+                             SourceMgr::DiagHandlerTy DiagHandler,
+                             void *DiagContext,
+                             IntrusiveRefCntPtr<FileSystem> ExternalFS);
+
+  ErrorOr<Status> status(const Twine &Path) override;
+  std::error_code openFileForRead(const Twine &Path,
+                                  std::unique_ptr<File> &Result) override;
+
+  directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override{
+    ErrorOr<Entry *> E = lookupPath(Dir);
+    if (!E) {
+      EC = E.getError();
+      return directory_iterator();
+    }
+    ErrorOr<Status> S = status(Dir, *E);
+    if (!S) {
+      EC = S.getError();
+      return directory_iterator();
+    }
+    if (!S->isDirectory()) {
+      EC = std::error_code(static_cast<int>(errc::not_a_directory),
+                           std::system_category());
+      return directory_iterator();
+    }
+
+    DirectoryEntry *D = cast<DirectoryEntry>(*E);
+    return directory_iterator(std::make_shared<VFSFromYamlDirIterImpl>(Dir,
+        *this, D->contents_begin(), D->contents_end(), EC));
+  }
+};
+
+/// \brief A helper class to hold the common YAML parsing state.
+class VFSFromYAMLParser {
+  yaml::Stream &Stream;
+
+  void error(yaml::Node *N, const Twine &Msg) {
+    Stream.printError(N, Msg);
+  }
+
+  // false on error
+  bool parseScalarString(yaml::Node *N, StringRef &Result,
+                         SmallVectorImpl<char> &Storage) {
+    yaml::ScalarNode *S = dyn_cast<yaml::ScalarNode>(N);
+    if (!S) {
+      error(N, "expected string");
+      return false;
+    }
+    Result = S->getValue(Storage);
+    return true;
+  }
+
+  // false on error
+  bool parseScalarBool(yaml::Node *N, bool &Result) {
+    SmallString<5> Storage;
+    StringRef Value;
+    if (!parseScalarString(N, Value, Storage))
+      return false;
+
+    if (Value.equals_lower("true") || Value.equals_lower("on") ||
+        Value.equals_lower("yes") || Value == "1") {
+      Result = true;
+      return true;
+    } else if (Value.equals_lower("false") || Value.equals_lower("off") ||
+               Value.equals_lower("no") || Value == "0") {
+      Result = false;
+      return true;
+    }
+
+    error(N, "expected boolean value");
+    return false;
+  }
+
+  struct KeyStatus {
+    KeyStatus(bool Required=false) : Required(Required), Seen(false) {}
+    bool Required;
+    bool Seen;
+  };
+  typedef std::pair<StringRef, KeyStatus> KeyStatusPair;
+
+  // false on error
+  bool checkDuplicateOrUnknownKey(yaml::Node *KeyNode, StringRef Key,
+                                  DenseMap<StringRef, KeyStatus> &Keys) {
+    if (!Keys.count(Key)) {
+      error(KeyNode, "unknown key");
+      return false;
+    }
+    KeyStatus &S = Keys[Key];
+    if (S.Seen) {
+      error(KeyNode, Twine("duplicate key '") + Key + "'");
+      return false;
+    }
+    S.Seen = true;
+    return true;
+  }
+
+  // false on error
+  bool checkMissingKeys(yaml::Node *Obj, DenseMap<StringRef, KeyStatus> &Keys) {
+    for (DenseMap<StringRef, KeyStatus>::iterator I = Keys.begin(),
+         E = Keys.end();
+         I != E; ++I) {
+      if (I->second.Required && !I->second.Seen) {
+        error(Obj, Twine("missing key '") + I->first + "'");
+        return false;
+      }
+    }
+    return true;
+  }
+
+  Entry *parseEntry(yaml::Node *N) {
+    yaml::MappingNode *M = dyn_cast<yaml::MappingNode>(N);
+    if (!M) {
+      error(N, "expected mapping node for file or directory entry");
+      return nullptr;
+    }
+
+    KeyStatusPair Fields[] = {
+      KeyStatusPair("name", true),
+      KeyStatusPair("type", true),
+      KeyStatusPair("contents", false),
+      KeyStatusPair("external-contents", false),
+      KeyStatusPair("use-external-name", false),
+    };
+
+    DenseMap<StringRef, KeyStatus> Keys(
+        &Fields[0], Fields + sizeof(Fields)/sizeof(Fields[0]));
+
+    bool HasContents = false; // external or otherwise
+    std::vector<Entry *> EntryArrayContents;
+    std::string ExternalContentsPath;
+    std::string Name;
+    FileEntry::NameKind UseExternalName = FileEntry::NK_NotSet;
+    EntryKind Kind;
+
+    for (yaml::MappingNode::iterator I = M->begin(), E = M->end(); I != E;
+         ++I) {
+      StringRef Key;
+      // Reuse the buffer for key and value, since we don't look at key after
+      // parsing value.
+      SmallString<256> Buffer;
+      if (!parseScalarString(I->getKey(), Key, Buffer))
+        return nullptr;
+
+      if (!checkDuplicateOrUnknownKey(I->getKey(), Key, Keys))
+        return nullptr;
+
+      StringRef Value;
+      if (Key == "name") {
+        if (!parseScalarString(I->getValue(), Value, Buffer))
+          return nullptr;
+        Name = Value;
+      } else if (Key == "type") {
+        if (!parseScalarString(I->getValue(), Value, Buffer))
+          return nullptr;
+        if (Value == "file")
+          Kind = EK_File;
+        else if (Value == "directory")
+          Kind = EK_Directory;
+        else {
+          error(I->getValue(), "unknown value for 'type'");
+          return nullptr;
+        }
+      } else if (Key == "contents") {
+        if (HasContents) {
+          error(I->getKey(),
+                "entry already has 'contents' or 'external-contents'");
+          return nullptr;
+        }
+        HasContents = true;
+        yaml::SequenceNode *Contents =
+            dyn_cast<yaml::SequenceNode>(I->getValue());
+        if (!Contents) {
+          // FIXME: this is only for directories, what about files?
+          error(I->getValue(), "expected array");
+          return nullptr;
+        }
+
+        for (yaml::SequenceNode::iterator I = Contents->begin(),
+                                          E = Contents->end();
+             I != E; ++I) {
+          if (Entry *E = parseEntry(&*I))
+            EntryArrayContents.push_back(E);
+          else
+            return nullptr;
+        }
+      } else if (Key == "external-contents") {
+        if (HasContents) {
+          error(I->getKey(),
+                "entry already has 'contents' or 'external-contents'");
+          return nullptr;
+        }
+        HasContents = true;
+        if (!parseScalarString(I->getValue(), Value, Buffer))
+          return nullptr;
+        ExternalContentsPath = Value;
+      } else if (Key == "use-external-name") {
+        bool Val;
+        if (!parseScalarBool(I->getValue(), Val))
+          return nullptr;
+        UseExternalName = Val ? FileEntry::NK_External : FileEntry::NK_Virtual;
+      } else {
+        llvm_unreachable("key missing from Keys");
+      }
+    }
+
+    if (Stream.failed())
+      return nullptr;
+
+    // check for missing keys
+    if (!HasContents) {
+      error(N, "missing key 'contents' or 'external-contents'");
+      return nullptr;
+    }
+    if (!checkMissingKeys(N, Keys))
+      return nullptr;
+
+    // check invalid configuration
+    if (Kind == EK_Directory && UseExternalName != FileEntry::NK_NotSet) {
+      error(N, "'use-external-name' is not supported for directories");
+      return nullptr;
+    }
+
+    // Remove trailing slash(es), being careful not to remove the root path
+    StringRef Trimmed(Name);
+    size_t RootPathLen = sys::path::root_path(Trimmed).size();
+    while (Trimmed.size() > RootPathLen &&
+           sys::path::is_separator(Trimmed.back()))
+      Trimmed = Trimmed.slice(0, Trimmed.size()-1);
+    // Get the last component
+    StringRef LastComponent = sys::path::filename(Trimmed);
+
+    Entry *Result = nullptr;
+    switch (Kind) {
+    case EK_File:
+      Result = new FileEntry(LastComponent, std::move(ExternalContentsPath),
+                             UseExternalName);
+      break;
+    case EK_Directory:
+      Result = new DirectoryEntry(LastComponent, std::move(EntryArrayContents),
+          Status("", "", getNextVirtualUniqueID(), sys::TimeValue::now(), 0, 0,
+                 0, file_type::directory_file, sys::fs::all_all));
+      break;
+    }
+
+    StringRef Parent = sys::path::parent_path(Trimmed);
+    if (Parent.empty())
+      return Result;
+
+    // if 'name' contains multiple components, create implicit directory entries
+    for (sys::path::reverse_iterator I = sys::path::rbegin(Parent),
+                                     E = sys::path::rend(Parent);
+         I != E; ++I) {
+      Result = new DirectoryEntry(*I, llvm::makeArrayRef(Result),
+          Status("", "", getNextVirtualUniqueID(), sys::TimeValue::now(), 0, 0,
+                 0, file_type::directory_file, sys::fs::all_all));
+    }
+    return Result;
+  }
+
+public:
+  VFSFromYAMLParser(yaml::Stream &S) : Stream(S) {}
+
+  // false on error
+  bool parse(yaml::Node *Root, VFSFromYAML *FS) {
+    yaml::MappingNode *Top = dyn_cast<yaml::MappingNode>(Root);
+    if (!Top) {
+      error(Root, "expected mapping node");
+      return false;
+    }
+
+    KeyStatusPair Fields[] = {
+      KeyStatusPair("version", true),
+      KeyStatusPair("case-sensitive", false),
+      KeyStatusPair("use-external-names", false),
+      KeyStatusPair("roots", true),
+    };
+
+    DenseMap<StringRef, KeyStatus> Keys(
+        &Fields[0], Fields + sizeof(Fields)/sizeof(Fields[0]));
+
+    // Parse configuration and 'roots'
+    for (yaml::MappingNode::iterator I = Top->begin(), E = Top->end(); I != E;
+         ++I) {
+      SmallString<10> KeyBuffer;
+      StringRef Key;
+      if (!parseScalarString(I->getKey(), Key, KeyBuffer))
+        return false;
+
+      if (!checkDuplicateOrUnknownKey(I->getKey(), Key, Keys))
+        return false;
+
+      if (Key == "roots") {
+        yaml::SequenceNode *Roots = dyn_cast<yaml::SequenceNode>(I->getValue());
+        if (!Roots) {
+          error(I->getValue(), "expected array");
+          return false;
+        }
+
+        for (yaml::SequenceNode::iterator I = Roots->begin(), E = Roots->end();
+             I != E; ++I) {
+          if (Entry *E = parseEntry(&*I))
+            FS->Roots.push_back(E);
+          else
+            return false;
+        }
+      } else if (Key == "version") {
+        StringRef VersionString;
+        SmallString<4> Storage;
+        if (!parseScalarString(I->getValue(), VersionString, Storage))
+          return false;
+        int Version;
+        if (VersionString.getAsInteger<int>(10, Version)) {
+          error(I->getValue(), "expected integer");
+          return false;
+        }
+        if (Version < 0) {
+          error(I->getValue(), "invalid version number");
+          return false;
+        }
+        if (Version != 0) {
+          error(I->getValue(), "version mismatch, expected 0");
+          return false;
+        }
+      } else if (Key == "case-sensitive") {
+        if (!parseScalarBool(I->getValue(), FS->CaseSensitive))
+          return false;
+      } else if (Key == "use-external-names") {
+        if (!parseScalarBool(I->getValue(), FS->UseExternalNames))
+          return false;
+      } else {
+        llvm_unreachable("key missing from Keys");
+      }
+    }
+
+    if (Stream.failed())
+      return false;
+
+    if (!checkMissingKeys(Top, Keys))
+      return false;
+    return true;
+  }
+};
+} // end of anonymous namespace
+
+Entry::~Entry() {}
+DirectoryEntry::~DirectoryEntry() { llvm::DeleteContainerPointers(Contents); }
+
+VFSFromYAML::~VFSFromYAML() { llvm::DeleteContainerPointers(Roots); }
+
+VFSFromYAML *VFSFromYAML::create(MemoryBuffer *Buffer,
+                                 SourceMgr::DiagHandlerTy DiagHandler,
+                                 void *DiagContext,
+                                 IntrusiveRefCntPtr<FileSystem> ExternalFS) {
+
+  SourceMgr SM;
+  yaml::Stream Stream(Buffer, SM);
+
+  SM.setDiagHandler(DiagHandler, DiagContext);
+  yaml::document_iterator DI = Stream.begin();
+  yaml::Node *Root = DI->getRoot();
+  if (DI == Stream.end() || !Root) {
+    SM.PrintMessage(SMLoc(), SourceMgr::DK_Error, "expected root node");
+    return nullptr;
+  }
+
+  VFSFromYAMLParser P(Stream);
+
+  std::unique_ptr<VFSFromYAML> FS(new VFSFromYAML(ExternalFS));
+  if (!P.parse(Root, FS.get()))
+    return nullptr;
+
+  return FS.release();
+}
+
+ErrorOr<Entry *> VFSFromYAML::lookupPath(const Twine &Path_) {
+  SmallString<256> Path;
+  Path_.toVector(Path);
+
+  // Handle relative paths
+  if (std::error_code EC = sys::fs::make_absolute(Path))
+    return EC;
+
+  if (Path.empty())
+    return make_error_code(llvm::errc::invalid_argument);
+
+  sys::path::const_iterator Start = sys::path::begin(Path);
+  sys::path::const_iterator End = sys::path::end(Path);
+  for (std::vector<Entry *>::iterator I = Roots.begin(), E = Roots.end();
+       I != E; ++I) {
+    ErrorOr<Entry *> Result = lookupPath(Start, End, *I);
+    if (Result || Result.getError() != llvm::errc::no_such_file_or_directory)
+      return Result;
+  }
+  return make_error_code(llvm::errc::no_such_file_or_directory);
+}
+
+ErrorOr<Entry *> VFSFromYAML::lookupPath(sys::path::const_iterator Start,
+                                         sys::path::const_iterator End,
+                                         Entry *From) {
+  if (Start->equals("."))
+    ++Start;
+
+  // FIXME: handle ..
+  if (CaseSensitive ? !Start->equals(From->getName())
+                    : !Start->equals_lower(From->getName()))
+    // failure to match
+    return make_error_code(llvm::errc::no_such_file_or_directory);
+
+  ++Start;
+
+  if (Start == End) {
+    // Match!
+    return From;
+  }
+
+  DirectoryEntry *DE = dyn_cast<DirectoryEntry>(From);
+  if (!DE)
+    return make_error_code(llvm::errc::not_a_directory);
+
+  for (DirectoryEntry::iterator I = DE->contents_begin(),
+                                E = DE->contents_end();
+       I != E; ++I) {
+    ErrorOr<Entry *> Result = lookupPath(Start, End, *I);
+    if (Result || Result.getError() != llvm::errc::no_such_file_or_directory)
+      return Result;
+  }
+  return make_error_code(llvm::errc::no_such_file_or_directory);
+}
+
+ErrorOr<Status> VFSFromYAML::status(const Twine &Path, Entry *E) {
+  assert(E != nullptr);
+  std::string PathStr(Path.str());
+  if (FileEntry *F = dyn_cast<FileEntry>(E)) {
+    ErrorOr<Status> S = ExternalFS->status(F->getExternalContentsPath());
+    assert(!S || S->getName() == F->getExternalContentsPath());
+    if (S && !F->useExternalName(UseExternalNames))
+      S->setName(PathStr);
+    if (S)
+      S->IsVFSMapped = true;
+    return S;
+  } else { // directory
+    DirectoryEntry *DE = cast<DirectoryEntry>(E);
+    Status S = DE->getStatus();
+    S.setName(PathStr);
+    return S;
+  }
+}
+
+ErrorOr<Status> VFSFromYAML::status(const Twine &Path) {
+  ErrorOr<Entry *> Result = lookupPath(Path);
+  if (!Result)
+    return Result.getError();
+  return status(Path, *Result);
+}
+
+std::error_code
+VFSFromYAML::openFileForRead(const Twine &Path,
+                             std::unique_ptr<vfs::File> &Result) {
+  ErrorOr<Entry *> E = lookupPath(Path);
+  if (!E)
+    return E.getError();
+
+  FileEntry *F = dyn_cast<FileEntry>(*E);
+  if (!F) // FIXME: errc::not_a_file?
+    return make_error_code(llvm::errc::invalid_argument);
+
+  if (std::error_code EC =
+          ExternalFS->openFileForRead(F->getExternalContentsPath(), Result))
+    return EC;
+
+  if (!F->useExternalName(UseExternalNames))
+    Result->setName(Path.str());
+
+  return std::error_code();
+}
+
+IntrusiveRefCntPtr<FileSystem>
+vfs::getVFSFromYAML(MemoryBuffer *Buffer, SourceMgr::DiagHandlerTy DiagHandler,
+                    void *DiagContext,
+                    IntrusiveRefCntPtr<FileSystem> ExternalFS) {
+  return VFSFromYAML::create(Buffer, DiagHandler, DiagContext, ExternalFS);
+}
+
+UniqueID vfs::getNextVirtualUniqueID() {
+  static std::atomic<unsigned> UID;
+  unsigned ID = ++UID;
+  // The following assumes that uint64_t max will never collide with a real
+  // dev_t value from the OS.
+  return UniqueID(std::numeric_limits<uint64_t>::max(), ID);
+}
+
+#ifndef NDEBUG
+static bool pathHasTraversal(StringRef Path) {
+  using namespace llvm::sys;
+  for (StringRef Comp : llvm::make_range(path::begin(Path), path::end(Path)))
+    if (Comp == "." || Comp == "..")
+      return true;
+  return false;
+}
+#endif
+
+void YAMLVFSWriter::addFileMapping(StringRef VirtualPath, StringRef RealPath) {
+  assert(sys::path::is_absolute(VirtualPath) && "virtual path not absolute");
+  assert(sys::path::is_absolute(RealPath) && "real path not absolute");
+  assert(!pathHasTraversal(VirtualPath) && "path traversal is not supported");
+  Mappings.emplace_back(VirtualPath, RealPath);
+}
+
+namespace {
+class JSONWriter {
+  llvm::raw_ostream &OS;
+  SmallVector<StringRef, 16> DirStack;
+  inline unsigned getDirIndent() { return 4 * DirStack.size(); }
+  inline unsigned getFileIndent() { return 4 * (DirStack.size() + 1); }
+  bool containedIn(StringRef Parent, StringRef Path);
+  StringRef containedPart(StringRef Parent, StringRef Path);
+  void startDirectory(StringRef Path);
+  void endDirectory();
+  void writeEntry(StringRef VPath, StringRef RPath);
+
+public:
+  JSONWriter(llvm::raw_ostream &OS) : OS(OS) {}
+  void write(ArrayRef<YAMLVFSEntry> Entries, Optional<bool> IsCaseSensitive);
+};
+}
+
+bool JSONWriter::containedIn(StringRef Parent, StringRef Path) {
+  using namespace llvm::sys;
+  // Compare each path component.
+  auto IParent = path::begin(Parent), EParent = path::end(Parent);
+  for (auto IChild = path::begin(Path), EChild = path::end(Path);
+       IParent != EParent && IChild != EChild; ++IParent, ++IChild) {
+    if (*IParent != *IChild)
+      return false;
+  }
+  // Have we exhausted the parent path?
+  return IParent == EParent;
+}
+
+StringRef JSONWriter::containedPart(StringRef Parent, StringRef Path) {
+  assert(!Parent.empty());
+  assert(containedIn(Parent, Path));
+  return Path.slice(Parent.size() + 1, StringRef::npos);
+}
+
+void JSONWriter::startDirectory(StringRef Path) {
+  StringRef Name =
+      DirStack.empty() ? Path : containedPart(DirStack.back(), Path);
+  DirStack.push_back(Path);
+  unsigned Indent = getDirIndent();
+  OS.indent(Indent) << "{\n";
+  OS.indent(Indent + 2) << "'type': 'directory',\n";
+  OS.indent(Indent + 2) << "'name': \"" << llvm::yaml::escape(Name) << "\",\n";
+  OS.indent(Indent + 2) << "'contents': [\n";
+}
+
+void JSONWriter::endDirectory() {
+  unsigned Indent = getDirIndent();
+  OS.indent(Indent + 2) << "]\n";
+  OS.indent(Indent) << "}";
+
+  DirStack.pop_back();
+}
+
+void JSONWriter::writeEntry(StringRef VPath, StringRef RPath) {
+  unsigned Indent = getFileIndent();
+  OS.indent(Indent) << "{\n";
+  OS.indent(Indent + 2) << "'type': 'file',\n";
+  OS.indent(Indent + 2) << "'name': \"" << llvm::yaml::escape(VPath) << "\",\n";
+  OS.indent(Indent + 2) << "'external-contents': \""
+                        << llvm::yaml::escape(RPath) << "\"\n";
+  OS.indent(Indent) << "}";
+}
+
+void JSONWriter::write(ArrayRef<YAMLVFSEntry> Entries,
+                       Optional<bool> IsCaseSensitive) {
+  using namespace llvm::sys;
+
+  OS << "{\n"
+        "  'version': 0,\n";
+  if (IsCaseSensitive.hasValue())
+    OS << "  'case-sensitive': '"
+       << (IsCaseSensitive.getValue() ? "true" : "false") << "',\n";
+  OS << "  'roots': [\n";
+
+  if (!Entries.empty()) {
+    const YAMLVFSEntry &Entry = Entries.front();
+    startDirectory(path::parent_path(Entry.VPath));
+    writeEntry(path::filename(Entry.VPath), Entry.RPath);
+
+    for (const auto &Entry : Entries.slice(1)) {
+      StringRef Dir = path::parent_path(Entry.VPath);
+      if (Dir == DirStack.back())
+        OS << ",\n";
+      else {
+        while (!DirStack.empty() && !containedIn(DirStack.back(), Dir)) {
+          OS << "\n";
+          endDirectory();
+        }
+        OS << ",\n";
+        startDirectory(Dir);
+      }
+      writeEntry(path::filename(Entry.VPath), Entry.RPath);
+    }
+
+    while (!DirStack.empty()) {
+      OS << "\n";
+      endDirectory();
+    }
+    OS << "\n";
+  }
+
+  OS << "  ]\n"
+     << "}\n";
+}
+
+void YAMLVFSWriter::write(llvm::raw_ostream &OS) {
+  std::sort(Mappings.begin(), Mappings.end(),
+            [](const YAMLVFSEntry &LHS, const YAMLVFSEntry &RHS) {
+    return LHS.VPath < RHS.VPath;
+  });
+
+  JSONWriter(OS).write(Mappings, IsCaseSensitive);
+}
+
+VFSFromYamlDirIterImpl::VFSFromYamlDirIterImpl(const Twine &_Path,
+                                               VFSFromYAML &FS,
+                                               DirectoryEntry::iterator Begin,
+                                               DirectoryEntry::iterator End,
+                                               std::error_code &EC)
+    : Dir(_Path.str()), FS(FS), Current(Begin), End(End) {
+  if (Current != End) {
+    SmallString<128> PathStr(Dir);
+    llvm::sys::path::append(PathStr, (*Current)->getName());
+    llvm::ErrorOr<vfs::Status> S = FS.status(PathStr.str());
+    if (S)
+      CurrentEntry = *S;
+    else
+      EC = S.getError();
+  }
+}
+
+std::error_code VFSFromYamlDirIterImpl::increment() {
+  assert(Current != End && "cannot iterate past end");
+  if (++Current != End) {
+    SmallString<128> PathStr(Dir);
+    llvm::sys::path::append(PathStr, (*Current)->getName());
+    llvm::ErrorOr<vfs::Status> S = FS.status(PathStr.str());
+    if (!S)
+      return S.getError();
+    CurrentEntry = *S;
+  } else {
+    CurrentEntry = Status();
+  }
+  return std::error_code();
+}
+
+vfs::recursive_directory_iterator::recursive_directory_iterator(FileSystem &FS_,
+                                                           const Twine &Path,
+                                                           std::error_code &EC)
+    : FS(&FS_) {
+  directory_iterator I = FS->dir_begin(Path, EC);
+  if (!EC && I != directory_iterator()) {
+    State = std::make_shared<IterState>();
+    State->push(I);
+  }
+}
+
+vfs::recursive_directory_iterator &
+recursive_directory_iterator::increment(std::error_code &EC) {
+  assert(FS && State && !State->empty() && "incrementing past end");
+  assert(State->top()->isStatusKnown() && "non-canonical end iterator");
+  vfs::directory_iterator End;
+  if (State->top()->isDirectory()) {
+    vfs::directory_iterator I = FS->dir_begin(State->top()->getName(), EC);
+    if (EC)
+      return *this;
+    if (I != End) {
+      State->push(I);
+      return *this;
+    }
+  }
+
+  while (!State->empty() && State->top().increment(EC) == End)
+    State->pop();
+
+  if (State->empty())
+    State.reset(); // end iterator
+
+  return *this;
+}
diff --git a/lib/Basic/Warnings.cpp b/lib/Basic/Warnings.cpp
new file mode 100644
index 0000000..6306cea
--- /dev/null
+++ b/lib/Basic/Warnings.cpp
@@ -0,0 +1,230 @@
+//===--- Warnings.cpp - C-Language Front-end ------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Command line warning options handler.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is responsible for handling all warning options. This includes
+// a number of -Wfoo options and their variants, which are driven by TableGen-
+// generated data, and the special cases -pedantic, -pedantic-errors, -w,
+// -Werror and -Wfatal-errors.
+//
+// Each warning option controls any number of actual warnings.
+// Given a warning option 'foo', the following are valid:
+//    -Wfoo, -Wno-foo, -Werror=foo, -Wfatal-errors=foo
+//
+// Remark options are also handled here, analogously, except that they are much
+// simpler because a remark can't be promoted to an error.
+#include "clang/Basic/AllDiagnostics.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticOptions.h"
+#include <algorithm>
+#include <cstring>
+#include <utility>
+using namespace clang;
+
+// EmitUnknownDiagWarning - Emit a warning and typo hint for unknown warning
+// opts
+static void EmitUnknownDiagWarning(DiagnosticsEngine &Diags,
+                                   diag::Flavor Flavor, StringRef Prefix,
+                                   StringRef Opt) {
+  StringRef Suggestion = DiagnosticIDs::getNearestOption(Flavor, Opt);
+  Diags.Report(diag::warn_unknown_diag_option)
+    << (Flavor == diag::Flavor::WarningOrError ? 0 : 1) << (Prefix.str() += Opt)
+    << !Suggestion.empty() << (Prefix.str() += Suggestion);
+}
+
+void clang::ProcessWarningOptions(DiagnosticsEngine &Diags,
+                                  const DiagnosticOptions &Opts,
+                                  bool ReportDiags) {
+  Diags.setSuppressSystemWarnings(true);  // Default to -Wno-system-headers
+  Diags.setIgnoreAllWarnings(Opts.IgnoreWarnings);
+  Diags.setShowOverloads(Opts.getShowOverloads());
+
+  Diags.setElideType(Opts.ElideType);
+  Diags.setPrintTemplateTree(Opts.ShowTemplateTree);
+  Diags.setShowColors(Opts.ShowColors);
+ 
+  // Handle -ferror-limit
+  if (Opts.ErrorLimit)
+    Diags.setErrorLimit(Opts.ErrorLimit);
+  if (Opts.TemplateBacktraceLimit)
+    Diags.setTemplateBacktraceLimit(Opts.TemplateBacktraceLimit);
+  if (Opts.ConstexprBacktraceLimit)
+    Diags.setConstexprBacktraceLimit(Opts.ConstexprBacktraceLimit);
+
+  // If -pedantic or -pedantic-errors was specified, then we want to map all
+  // extension diagnostics onto WARNING or ERROR unless the user has futz'd
+  // around with them explicitly.
+  if (Opts.PedanticErrors)
+    Diags.setExtensionHandlingBehavior(diag::Severity::Error);
+  else if (Opts.Pedantic)
+    Diags.setExtensionHandlingBehavior(diag::Severity::Warning);
+  else
+    Diags.setExtensionHandlingBehavior(diag::Severity::Ignored);
+
+  SmallVector<diag::kind, 10> _Diags;
+  const IntrusiveRefCntPtr< DiagnosticIDs > DiagIDs =
+    Diags.getDiagnosticIDs();
+  // We parse the warning options twice.  The first pass sets diagnostic state,
+  // while the second pass reports warnings/errors.  This has the effect that
+  // we follow the more canonical "last option wins" paradigm when there are 
+  // conflicting options.
+  for (unsigned Report = 0, ReportEnd = 2; Report != ReportEnd; ++Report) {
+    bool SetDiagnostic = (Report == 0);
+
+    // If we've set the diagnostic state and are not reporting diagnostics then
+    // we're done.
+    if (!SetDiagnostic && !ReportDiags)
+      break;
+
+    for (unsigned i = 0, e = Opts.Warnings.size(); i != e; ++i) {
+      const auto Flavor = diag::Flavor::WarningOrError;
+      StringRef Opt = Opts.Warnings[i];
+      StringRef OrigOpt = Opts.Warnings[i];
+
+      // Treat -Wformat=0 as an alias for -Wno-format.
+      if (Opt == "format=0")
+        Opt = "no-format";
+
+      // Check to see if this warning starts with "no-", if so, this is a
+      // negative form of the option.
+      bool isPositive = true;
+      if (Opt.startswith("no-")) {
+        isPositive = false;
+        Opt = Opt.substr(3);
+      }
+
+      // Figure out how this option affects the warning.  If -Wfoo, map the
+      // diagnostic to a warning, if -Wno-foo, map it to ignore.
+      diag::Severity Mapping =
+          isPositive ? diag::Severity::Warning : diag::Severity::Ignored;
+
+      // -Wsystem-headers is a special case, not driven by the option table.  It
+      // cannot be controlled with -Werror.
+      if (Opt == "system-headers") {
+        if (SetDiagnostic)
+          Diags.setSuppressSystemWarnings(!isPositive);
+        continue;
+      }
+      
+      // -Weverything is a special case as well.  It implicitly enables all
+      // warnings, including ones not explicitly in a warning group.
+      if (Opt == "everything") {
+        if (SetDiagnostic) {
+          if (isPositive) {
+            Diags.setEnableAllWarnings(true);
+          } else {
+            Diags.setEnableAllWarnings(false);
+            Diags.setSeverityForAll(Flavor, diag::Severity::Ignored);
+          }
+        }
+        continue;
+      }
+      
+      // -Werror/-Wno-error is a special case, not controlled by the option 
+      // table. It also has the "specifier" form of -Werror=foo and -Werror-foo.
+      if (Opt.startswith("error")) {
+        StringRef Specifier;
+        if (Opt.size() > 5) {  // Specifier must be present.
+          if ((Opt[5] != '=' && Opt[5] != '-') || Opt.size() == 6) {
+            if (Report)
+              Diags.Report(diag::warn_unknown_warning_specifier)
+                << "-Werror" << ("-W" + OrigOpt.str());
+            continue;
+          }
+          Specifier = Opt.substr(6);
+        }
+        
+        if (Specifier.empty()) {
+          if (SetDiagnostic)
+            Diags.setWarningsAsErrors(isPositive);
+          continue;
+        }
+        
+        if (SetDiagnostic) {
+          // Set the warning as error flag for this specifier.
+          Diags.setDiagnosticGroupWarningAsError(Specifier, isPositive);
+        } else if (DiagIDs->getDiagnosticsInGroup(Flavor, Specifier, _Diags)) {
+          EmitUnknownDiagWarning(Diags, Flavor, "-Werror=", Specifier);
+        }
+        continue;
+      }
+      
+      // -Wfatal-errors is yet another special case.
+      if (Opt.startswith("fatal-errors")) {
+        StringRef Specifier;
+        if (Opt.size() != 12) {
+          if ((Opt[12] != '=' && Opt[12] != '-') || Opt.size() == 13) {
+            if (Report)
+              Diags.Report(diag::warn_unknown_warning_specifier)
+                << "-Wfatal-errors" << ("-W" + OrigOpt.str());
+            continue;
+          }
+          Specifier = Opt.substr(13);
+        }
+
+        if (Specifier.empty()) {
+          if (SetDiagnostic)
+            Diags.setErrorsAsFatal(isPositive);
+          continue;
+        }
+        
+        if (SetDiagnostic) {
+          // Set the error as fatal flag for this specifier.
+          Diags.setDiagnosticGroupErrorAsFatal(Specifier, isPositive);
+        } else if (DiagIDs->getDiagnosticsInGroup(Flavor, Specifier, _Diags)) {
+          EmitUnknownDiagWarning(Diags, Flavor, "-Wfatal-errors=", Specifier);
+        }
+        continue;
+      }
+      
+      if (Report) {
+        if (DiagIDs->getDiagnosticsInGroup(Flavor, Opt, _Diags))
+          EmitUnknownDiagWarning(Diags, Flavor, isPositive ? "-W" : "-Wno-",
+                                 Opt);
+      } else {
+        Diags.setSeverityForGroup(Flavor, Opt, Mapping);
+      }
+    }
+
+    for (unsigned i = 0, e = Opts.Remarks.size(); i != e; ++i) {
+      StringRef Opt = Opts.Remarks[i];
+      const auto Flavor = diag::Flavor::Remark;
+
+      // Check to see if this warning starts with "no-", if so, this is a
+      // negative form of the option.
+      bool IsPositive = !Opt.startswith("no-");
+      if (!IsPositive) Opt = Opt.substr(3);
+
+      auto Severity = IsPositive ? diag::Severity::Remark
+                                 : diag::Severity::Ignored;
+
+      // -Reverything sets the state of all remarks. Note that all remarks are
+      // in remark groups, so we don't need a separate 'all remarks enabled'
+      // flag.
+      if (Opt == "everything") {
+        if (SetDiagnostic)
+          Diags.setSeverityForAll(Flavor, Severity);
+        continue;
+      }
+
+      if (Report) {
+        if (DiagIDs->getDiagnosticsInGroup(Flavor, Opt, _Diags))
+          EmitUnknownDiagWarning(Diags, Flavor, IsPositive ? "-R" : "-Rno-",
+                                 Opt);
+      } else {
+        Diags.setSeverityForGroup(Flavor, Opt,
+                                  IsPositive ? diag::Severity::Remark
+                                             : diag::Severity::Ignored);
+      }
+    }
+  }
+}
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index 7bb65e9..dfd819a 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -3,9 +3,7 @@
 add_subdirectory(Lex)
 add_subdirectory(Parse)
 add_subdirectory(AST)
-if(CLANG_ENABLE_REWRITER)
-  add_subdirectory(ASTMatchers)
-endif()
+add_subdirectory(ASTMatchers)
 add_subdirectory(Sema)
 add_subdirectory(CodeGen)
 add_subdirectory(Analysis)
diff --git a/lib/CodeGen/ABIInfo.h b/lib/CodeGen/ABIInfo.h
index 468fe04..d3ec46c 100644
--- a/lib/CodeGen/ABIInfo.h
+++ b/lib/CodeGen/ABIInfo.h
@@ -11,8 +11,8 @@
 #define CLANG_CODEGEN_ABIINFO_H
 
 #include "clang/AST/Type.h"
-#include "llvm/IR/Type.h"
 #include "llvm/IR/CallingConv.h"
+#include "llvm/IR/Type.h"
 
 namespace llvm {
   class Value;
diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp
index 90b0f68..cec48f3 100644
--- a/lib/CodeGen/BackendUtil.cpp
+++ b/lib/CodeGen/BackendUtil.cpp
@@ -13,13 +13,15 @@
 #include "clang/Basic/TargetOptions.h"
 #include "clang/Frontend/CodeGenOptions.h"
 #include "clang/Frontend/FrontendDiagnostic.h"
-#include "llvm/Analysis/Verifier.h"
-#include "llvm/Assembly/PrintModulePass.h"
-#include "llvm/Bitcode/ReaderWriter.h"
+#include "clang/Frontend/Utils.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Bitcode/BitcodeWriterPass.h"
 #include "llvm/CodeGen/RegAllocRegistry.h"
 #include "llvm/CodeGen/SchedulerRegistry.h"
 #include "llvm/IR/DataLayout.h"
+#include "llvm/IR/IRPrintingPasses.h"
 #include "llvm/IR/Module.h"
+#include "llvm/IR/Verifier.h"
 #include "llvm/MC/SubtargetFeature.h"
 #include "llvm/PassManager.h"
 #include "llvm/Support/CommandLine.h"
@@ -36,6 +38,7 @@
 #include "llvm/Transforms/Instrumentation.h"
 #include "llvm/Transforms/ObjCARC.h"
 #include "llvm/Transforms/Scalar.h"
+#include <memory>
 using namespace clang;
 using namespace llvm;
 
@@ -55,38 +58,37 @@
   mutable FunctionPassManager *PerFunctionPasses;
 
 private:
-  PassManager *getCodeGenPasses(TargetMachine *TM) const {
+  PassManager *getCodeGenPasses() const {
     if (!CodeGenPasses) {
       CodeGenPasses = new PassManager();
-      CodeGenPasses->add(new DataLayout(TheModule));
+      CodeGenPasses->add(new DataLayoutPass(TheModule));
       if (TM)
         TM->addAnalysisPasses(*CodeGenPasses);
     }
     return CodeGenPasses;
   }
 
-  PassManager *getPerModulePasses(TargetMachine *TM) const {
+  PassManager *getPerModulePasses() const {
     if (!PerModulePasses) {
       PerModulePasses = new PassManager();
-      PerModulePasses->add(new DataLayout(TheModule));
+      PerModulePasses->add(new DataLayoutPass(TheModule));
       if (TM)
         TM->addAnalysisPasses(*PerModulePasses);
     }
     return PerModulePasses;
   }
 
-  FunctionPassManager *getPerFunctionPasses(TargetMachine *TM) const {
+  FunctionPassManager *getPerFunctionPasses() const {
     if (!PerFunctionPasses) {
       PerFunctionPasses = new FunctionPassManager(TheModule);
-      PerFunctionPasses->add(new DataLayout(TheModule));
+      PerFunctionPasses->add(new DataLayoutPass(TheModule));
       if (TM)
         TM->addAnalysisPasses(*PerFunctionPasses);
     }
     return PerFunctionPasses;
   }
 
-
-  void CreatePasses(TargetMachine *TM);
+  void CreatePasses();
 
   /// CreateTargetMachine - Generates the TargetMachine.
   /// Returns Null if it is unable to create the target machine.
@@ -101,8 +103,7 @@
   /// AddEmitPasses - Add passes necessary to emit assembly or LLVM IR.
   ///
   /// \return True on success.
-  bool AddEmitPasses(BackendAction Action, formatted_raw_ostream &OS,
-                     TargetMachine *TM);
+  bool AddEmitPasses(BackendAction Action, formatted_raw_ostream &OS);
 
 public:
   EmitAssemblyHelper(DiagnosticsEngine &_Diags,
@@ -112,14 +113,19 @@
                      Module *M)
     : Diags(_Diags), CodeGenOpts(CGOpts), TargetOpts(TOpts), LangOpts(LOpts),
       TheModule(M), CodeGenerationTime("Code Generation Time"),
-      CodeGenPasses(0), PerModulePasses(0), PerFunctionPasses(0) {}
+      CodeGenPasses(nullptr), PerModulePasses(nullptr),
+      PerFunctionPasses(nullptr) {}
 
   ~EmitAssemblyHelper() {
     delete CodeGenPasses;
     delete PerModulePasses;
     delete PerFunctionPasses;
+    if (CodeGenOpts.DisableFree)
+      BuryPointer(TM.release());
   }
 
+  std::unique_ptr<TargetMachine> TM;
+
   void EmitAssembly(BackendAction Action, raw_ostream *OS);
 };
 
@@ -162,6 +168,11 @@
   PM.add(createSampleProfileLoaderPass(CGOpts.SampleProfileFile));
 }
 
+static void addAddDiscriminatorsPass(const PassManagerBuilder &Builder,
+                                     PassManagerBase &PM) {
+  PM.add(createAddDiscriminatorsPass());
+}
+
 static void addBoundsCheckingPass(const PassManagerBuilder &Builder,
                                     PassManagerBase &PM) {
   PM.add(createBoundsCheckingPass());
@@ -169,20 +180,8 @@
 
 static void addAddressSanitizerPasses(const PassManagerBuilder &Builder,
                                       PassManagerBase &PM) {
-  const PassManagerBuilderWrapper &BuilderWrapper =
-      static_cast<const PassManagerBuilderWrapper&>(Builder);
-  const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts();
-  const LangOptions &LangOpts = BuilderWrapper.getLangOpts();
-  PM.add(createAddressSanitizerFunctionPass(
-      LangOpts.Sanitize.InitOrder,
-      LangOpts.Sanitize.UseAfterReturn,
-      LangOpts.Sanitize.UseAfterScope,
-      CGOpts.SanitizerBlacklistFile,
-      CGOpts.SanitizeAddressZeroBaseShadow));
-  PM.add(createAddressSanitizerModulePass(
-      LangOpts.Sanitize.InitOrder,
-      CGOpts.SanitizerBlacklistFile,
-      CGOpts.SanitizeAddressZeroBaseShadow));
+  PM.add(createAddressSanitizerFunctionPass());
+  PM.add(createAddressSanitizerModulePass());
 }
 
 static void addMemorySanitizerPass(const PassManagerBuilder &Builder,
@@ -190,8 +189,7 @@
   const PassManagerBuilderWrapper &BuilderWrapper =
       static_cast<const PassManagerBuilderWrapper&>(Builder);
   const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts();
-  PM.add(createMemorySanitizerPass(CGOpts.SanitizeMemoryTrackOrigins,
-                                   CGOpts.SanitizerBlacklistFile));
+  PM.add(createMemorySanitizerPass(CGOpts.SanitizeMemoryTrackOrigins));
 
   // MemorySanitizer inserts complex instrumentation that mostly follows
   // the logic of the original code, but operates on "shadow" values.
@@ -208,10 +206,7 @@
 
 static void addThreadSanitizerPass(const PassManagerBuilder &Builder,
                                    PassManagerBase &PM) {
-  const PassManagerBuilderWrapper &BuilderWrapper =
-      static_cast<const PassManagerBuilderWrapper&>(Builder);
-  const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts();
-  PM.add(createThreadSanitizerPass(CGOpts.SanitizerBlacklistFile));
+  PM.add(createThreadSanitizerPass());
 }
 
 static void addDataFlowSanitizerPass(const PassManagerBuilder &Builder,
@@ -222,7 +217,7 @@
   PM.add(createDataFlowSanitizerPass(CGOpts.SanitizerBlacklistFile));
 }
 
-void EmitAssemblyHelper::CreatePasses(TargetMachine *TM) {
+void EmitAssemblyHelper::CreatePasses() {
   unsigned OptLevel = CodeGenOpts.OptimizationLevel;
   CodeGenOptions::InliningMethod Inlining = CodeGenOpts.getInlining();
 
@@ -240,10 +235,14 @@
   PMBuilder.SLPVectorize = CodeGenOpts.VectorizeSLP;
   PMBuilder.LoopVectorize = CodeGenOpts.VectorizeLoop;
 
+  PMBuilder.DisableTailCalls = CodeGenOpts.DisableTailCalls;
   PMBuilder.DisableUnitAtATime = !CodeGenOpts.UnitAtATime;
   PMBuilder.DisableUnrollLoops = !CodeGenOpts.UnrollLoops;
   PMBuilder.RerollLoops = CodeGenOpts.RerollLoops;
 
+  PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,
+                         addAddDiscriminatorsPass);
+
   if (!CodeGenOpts.SampleProfileFile.empty())
     PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,
                            addSampleProfileLoaderPass);
@@ -298,19 +297,12 @@
   PMBuilder.LibraryInfo = new TargetLibraryInfo(TargetTriple);
   if (!CodeGenOpts.SimplifyLibCalls)
     PMBuilder.LibraryInfo->disableAllFunctions();
-  
+
   switch (Inlining) {
   case CodeGenOptions::NoInlining: break;
   case CodeGenOptions::NormalInlining: {
-    // FIXME: Derive these constants in a principled fashion.
-    unsigned Threshold = 225;
-    if (CodeGenOpts.OptimizeSize == 1)      // -Os
-      Threshold = 75;
-    else if (CodeGenOpts.OptimizeSize == 2) // -Oz
-      Threshold = 25;
-    else if (OptLevel > 2)
-      Threshold = 275;
-    PMBuilder.Inliner = createFunctionInliningPass(Threshold);
+    PMBuilder.Inliner =
+        createFunctionInliningPass(OptLevel, CodeGenOpts.OptimizeSize);
     break;
   }
   case CodeGenOptions::OnlyAlwaysInlining:
@@ -324,13 +316,15 @@
   }
 
   // Set up the per-function pass manager.
-  FunctionPassManager *FPM = getPerFunctionPasses(TM);
+  FunctionPassManager *FPM = getPerFunctionPasses();
   if (CodeGenOpts.VerifyModule)
     FPM->add(createVerifierPass());
   PMBuilder.populateFunctionPassManager(*FPM);
 
   // Set up the per-module pass manager.
-  PassManager *MPM = getPerModulePasses(TM);
+  PassManager *MPM = getPerModulePasses();
+  if (CodeGenOpts.VerifyModule)
+    MPM->add(createDebugInfoVerifierPass());
 
   if (!CodeGenOpts.DisableGCov &&
       (CodeGenOpts.EmitGcovArcs || CodeGenOpts.EmitGcovNotes)) {
@@ -360,32 +354,19 @@
   if (!TheTarget) {
     if (MustCreateTM)
       Diags.Report(diag::err_fe_unable_to_create_target) << Error;
-    return 0;
+    return nullptr;
   }
 
-  // FIXME: Expose these capabilities via actual APIs!!!! Aside from just
-  // being gross, this is also totally broken if we ever care about
-  // concurrency.
-
-  TargetMachine::setAsmVerbosityDefault(CodeGenOpts.AsmVerbose);
-
-  TargetMachine::setFunctionSections(CodeGenOpts.FunctionSections);
-  TargetMachine::setDataSections    (CodeGenOpts.DataSections);
-
-  // FIXME: Parse this earlier.
-  llvm::CodeModel::Model CM;
-  if (CodeGenOpts.CodeModel == "small") {
-    CM = llvm::CodeModel::Small;
-  } else if (CodeGenOpts.CodeModel == "kernel") {
-    CM = llvm::CodeModel::Kernel;
-  } else if (CodeGenOpts.CodeModel == "medium") {
-    CM = llvm::CodeModel::Medium;
-  } else if (CodeGenOpts.CodeModel == "large") {
-    CM = llvm::CodeModel::Large;
-  } else {
-    assert(CodeGenOpts.CodeModel.empty() && "Invalid code model!");
-    CM = llvm::CodeModel::Default;
-  }
+  unsigned CodeModel =
+    llvm::StringSwitch<unsigned>(CodeGenOpts.CodeModel)
+      .Case("small", llvm::CodeModel::Small)
+      .Case("kernel", llvm::CodeModel::Kernel)
+      .Case("medium", llvm::CodeModel::Medium)
+      .Case("large", llvm::CodeModel::Large)
+      .Case("default", llvm::CodeModel::Default)
+      .Default(~0u);
+  assert(CodeModel != ~0u && "invalid code model!");
+  llvm::CodeModel::Model CM = static_cast<llvm::CodeModel::Model>(CodeModel);
 
   SmallVector<const char *, 16> BackendArgs;
   BackendArgs.push_back("clang"); // Fake program name.
@@ -402,8 +383,8 @@
   for (unsigned i = 0, e = CodeGenOpts.BackendOptions.size(); i != e; ++i)
     BackendArgs.push_back(CodeGenOpts.BackendOptions[i].c_str());
   if (CodeGenOpts.NoGlobalMerge)
-    BackendArgs.push_back("-global-merge=false");
-  BackendArgs.push_back(0);
+    BackendArgs.push_back("-enable-global-merge=false");
+  BackendArgs.push_back(nullptr);
   llvm::cl::ParseCommandLineOptions(BackendArgs.size() - 1,
                                     BackendArgs.data());
 
@@ -437,6 +418,12 @@
 
   llvm::TargetOptions Options;
 
+  if (CodeGenOpts.DisableIntegratedAS)
+    Options.DisableIntegratedAS = true;
+
+  if (CodeGenOpts.CompressDebugSections)
+    Options.CompressDebugSections = true;
+
   // Set frame pointer elimination mode.
   if (!CodeGenOpts.DisableFPElim) {
     Options.NoFramePointerElim = false;
@@ -482,32 +469,27 @@
   Options.DisableTailCalls = CodeGenOpts.DisableTailCalls;
   Options.TrapFuncName = CodeGenOpts.TrapFuncName;
   Options.PositionIndependentExecutable = LangOpts.PIELevel != 0;
-  Options.EnableSegmentedStacks = CodeGenOpts.EnableSegmentedStacks;
+  Options.FunctionSections = CodeGenOpts.FunctionSections;
+  Options.DataSections = CodeGenOpts.DataSections;
+
+  Options.MCOptions.MCRelaxAll = CodeGenOpts.RelaxAll;
+  Options.MCOptions.MCSaveTempLabels = CodeGenOpts.SaveTempLabels;
+  Options.MCOptions.MCUseDwarfDirectory = !CodeGenOpts.NoDwarfDirectoryAsm;
+  Options.MCOptions.MCNoExecStack = CodeGenOpts.NoExecStack;
+  Options.MCOptions.AsmVerbose = CodeGenOpts.AsmVerbose;
 
   TargetMachine *TM = TheTarget->createTargetMachine(Triple, TargetOpts.CPU,
                                                      FeaturesStr, Options,
                                                      RM, CM, OptLevel);
 
-  if (CodeGenOpts.RelaxAll)
-    TM->setMCRelaxAll(true);
-  if (CodeGenOpts.SaveTempLabels)
-    TM->setMCSaveTempLabels(true);
-  if (CodeGenOpts.NoDwarf2CFIAsm)
-    TM->setMCUseCFI(false);
-  if (!CodeGenOpts.NoDwarfDirectoryAsm)
-    TM->setMCUseDwarfDirectory(true);
-  if (CodeGenOpts.NoExecStack)
-    TM->setMCNoExecStack(true);
-
   return TM;
 }
 
 bool EmitAssemblyHelper::AddEmitPasses(BackendAction Action,
-                                       formatted_raw_ostream &OS,
-                                       TargetMachine *TM) {
+                                       formatted_raw_ostream &OS) {
 
   // Create the code generator passes.
-  PassManager *PM = getCodeGenPasses(TM);
+  PassManager *PM = getCodeGenPasses();
 
   // Add LibraryInfo.
   llvm::Triple TargetTriple(TheModule->getTargetTriple());
@@ -546,33 +528,34 @@
 }
 
 void EmitAssemblyHelper::EmitAssembly(BackendAction Action, raw_ostream *OS) {
-  TimeRegion Region(llvm::TimePassesIsEnabled ? &CodeGenerationTime : 0);
+  TimeRegion Region(llvm::TimePassesIsEnabled ? &CodeGenerationTime : nullptr);
   llvm::formatted_raw_ostream FormattedOS;
 
   bool UsesCodeGen = (Action != Backend_EmitNothing &&
                       Action != Backend_EmitBC &&
                       Action != Backend_EmitLL);
-  TargetMachine *TM = CreateTargetMachine(UsesCodeGen);
+  if (!TM)
+    TM.reset(CreateTargetMachine(UsesCodeGen));
+
   if (UsesCodeGen && !TM) return;
-  llvm::OwningPtr<TargetMachine> TMOwner(CodeGenOpts.DisableFree ? 0 : TM);
-  CreatePasses(TM);
+  CreatePasses();
 
   switch (Action) {
   case Backend_EmitNothing:
     break;
 
   case Backend_EmitBC:
-    getPerModulePasses(TM)->add(createBitcodeWriterPass(*OS));
+    getPerModulePasses()->add(createBitcodeWriterPass(*OS));
     break;
 
   case Backend_EmitLL:
     FormattedOS.setStream(*OS, formatted_raw_ostream::PRESERVE_STREAM);
-    getPerModulePasses(TM)->add(createPrintModulePass(&FormattedOS));
+    getPerModulePasses()->add(createPrintModulePass(FormattedOS));
     break;
 
   default:
     FormattedOS.setStream(*OS, formatted_raw_ostream::PRESERVE_STREAM);
-    if (!AddEmitPasses(Action, FormattedOS, TM))
+    if (!AddEmitPasses(Action, FormattedOS))
       return;
   }
 
@@ -607,10 +590,23 @@
 void clang::EmitBackendOutput(DiagnosticsEngine &Diags,
                               const CodeGenOptions &CGOpts,
                               const clang::TargetOptions &TOpts,
-                              const LangOptions &LOpts,
-                              Module *M,
-                              BackendAction Action, raw_ostream *OS) {
+                              const LangOptions &LOpts, StringRef TDesc,
+                              Module *M, BackendAction Action,
+                              raw_ostream *OS) {
   EmitAssemblyHelper AsmHelper(Diags, CGOpts, TOpts, LOpts, M);
 
   AsmHelper.EmitAssembly(Action, OS);
+
+  // If an optional clang TargetInfo description string was passed in, use it to
+  // verify the LLVM TargetMachine's DataLayout.
+  if (AsmHelper.TM && !TDesc.empty()) {
+    std::string DLDesc =
+        AsmHelper.TM->getDataLayout()->getStringRepresentation();
+    if (DLDesc != TDesc) {
+      unsigned DiagID = Diags.getCustomDiagID(
+          DiagnosticsEngine::Error, "backend data layout '%0' does not match "
+                                    "expected target description '%1'");
+      Diags.Report(DiagID) << DLDesc << TDesc;
+    }
+  }
 }
diff --git a/lib/CodeGen/CGAtomic.cpp b/lib/CodeGen/CGAtomic.cpp
index 0df2a40..89bde2c 100644
--- a/lib/CodeGen/CGAtomic.cpp
+++ b/lib/CodeGen/CGAtomic.cpp
@@ -24,16 +24,6 @@
 using namespace clang;
 using namespace CodeGen;
 
-// The ABI values for various atomic memory orderings.
-enum AtomicOrderingKind {
-  AO_ABI_memory_order_relaxed = 0,
-  AO_ABI_memory_order_consume = 1,
-  AO_ABI_memory_order_acquire = 2,
-  AO_ABI_memory_order_release = 3,
-  AO_ABI_memory_order_acq_rel = 4,
-  AO_ABI_memory_order_seq_cst = 5
-};
-
 namespace {
   class AtomicInfo {
     CodeGenFunction &CGF;
@@ -57,10 +47,10 @@
       ASTContext &C = CGF.getContext();
 
       uint64_t valueAlignInBits;
-      llvm::tie(ValueSizeInBits, valueAlignInBits) = C.getTypeInfo(ValueTy);
+      std::tie(ValueSizeInBits, valueAlignInBits) = C.getTypeInfo(ValueTy);
 
       uint64_t atomicAlignInBits;
-      llvm::tie(AtomicSizeInBits, atomicAlignInBits) = C.getTypeInfo(AtomicTy);
+      std::tie(AtomicSizeInBits, atomicAlignInBits) = C.getTypeInfo(AtomicTy);
 
       assert(ValueSizeInBits <= AtomicSizeInBits);
       assert(valueAlignInBits <= atomicAlignInBits);
@@ -184,10 +174,139 @@
   return true;
 }
 
-static void
-EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, llvm::Value *Dest,
-             llvm::Value *Ptr, llvm::Value *Val1, llvm::Value *Val2,
-             uint64_t Size, unsigned Align, llvm::AtomicOrdering Order) {
+static void emitAtomicCmpXchg(CodeGenFunction &CGF, AtomicExpr *E, bool IsWeak,
+                              llvm::Value *Dest, llvm::Value *Ptr,
+                              llvm::Value *Val1, llvm::Value *Val2,
+                              uint64_t Size, unsigned Align,
+                              llvm::AtomicOrdering SuccessOrder,
+                              llvm::AtomicOrdering FailureOrder) {
+  // Note that cmpxchg doesn't support weak cmpxchg, at least at the moment.
+  llvm::LoadInst *Expected = CGF.Builder.CreateLoad(Val1);
+  Expected->setAlignment(Align);
+  llvm::LoadInst *Desired = CGF.Builder.CreateLoad(Val2);
+  Desired->setAlignment(Align);
+
+  llvm::AtomicCmpXchgInst *Pair = CGF.Builder.CreateAtomicCmpXchg(
+      Ptr, Expected, Desired, SuccessOrder, FailureOrder);
+  Pair->setVolatile(E->isVolatile());
+  Pair->setWeak(IsWeak);
+
+  // Cmp holds the result of the compare-exchange operation: true on success,
+  // false on failure.
+  llvm::Value *Old = CGF.Builder.CreateExtractValue(Pair, 0);
+  llvm::Value *Cmp = CGF.Builder.CreateExtractValue(Pair, 1);
+
+  // This basic block is used to hold the store instruction if the operation
+  // failed.
+  llvm::BasicBlock *StoreExpectedBB =
+      CGF.createBasicBlock("cmpxchg.store_expected", CGF.CurFn);
+
+  // This basic block is the exit point of the operation, we should end up
+  // here regardless of whether or not the operation succeeded.
+  llvm::BasicBlock *ContinueBB =
+      CGF.createBasicBlock("cmpxchg.continue", CGF.CurFn);
+
+  // Update Expected if Expected isn't equal to Old, otherwise branch to the
+  // exit point.
+  CGF.Builder.CreateCondBr(Cmp, ContinueBB, StoreExpectedBB);
+
+  CGF.Builder.SetInsertPoint(StoreExpectedBB);
+  // Update the memory at Expected with Old's value.
+  llvm::StoreInst *StoreExpected = CGF.Builder.CreateStore(Old, Val1);
+  StoreExpected->setAlignment(Align);
+  // Finally, branch to the exit point.
+  CGF.Builder.CreateBr(ContinueBB);
+
+  CGF.Builder.SetInsertPoint(ContinueBB);
+  // Update the memory at Dest with Cmp's value.
+  CGF.EmitStoreOfScalar(Cmp, CGF.MakeAddrLValue(Dest, E->getType()));
+  return;
+}
+
+/// Given an ordering required on success, emit all possible cmpxchg
+/// instructions to cope with the provided (but possibly only dynamically known)
+/// FailureOrder.
+static void emitAtomicCmpXchgFailureSet(CodeGenFunction &CGF, AtomicExpr *E,
+                                        bool IsWeak, llvm::Value *Dest,
+                                        llvm::Value *Ptr, llvm::Value *Val1,
+                                        llvm::Value *Val2,
+                                        llvm::Value *FailureOrderVal,
+                                        uint64_t Size, unsigned Align,
+                                        llvm::AtomicOrdering SuccessOrder) {
+  llvm::AtomicOrdering FailureOrder;
+  if (llvm::ConstantInt *FO = dyn_cast<llvm::ConstantInt>(FailureOrderVal)) {
+    switch (FO->getSExtValue()) {
+    default:
+      FailureOrder = llvm::Monotonic;
+      break;
+    case AtomicExpr::AO_ABI_memory_order_consume:
+    case AtomicExpr::AO_ABI_memory_order_acquire:
+      FailureOrder = llvm::Acquire;
+      break;
+    case AtomicExpr::AO_ABI_memory_order_seq_cst:
+      FailureOrder = llvm::SequentiallyConsistent;
+      break;
+    }
+    if (FailureOrder >= SuccessOrder) {
+      // Don't assert on undefined behaviour.
+      FailureOrder =
+        llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(SuccessOrder);
+    }
+    emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, Align,
+                      SuccessOrder, FailureOrder);
+    return;
+  }
+
+  // Create all the relevant BB's
+  llvm::BasicBlock *MonotonicBB = nullptr, *AcquireBB = nullptr,
+                   *SeqCstBB = nullptr;
+  MonotonicBB = CGF.createBasicBlock("monotonic_fail", CGF.CurFn);
+  if (SuccessOrder != llvm::Monotonic && SuccessOrder != llvm::Release)
+    AcquireBB = CGF.createBasicBlock("acquire_fail", CGF.CurFn);
+  if (SuccessOrder == llvm::SequentiallyConsistent)
+    SeqCstBB = CGF.createBasicBlock("seqcst_fail", CGF.CurFn);
+
+  llvm::BasicBlock *ContBB = CGF.createBasicBlock("atomic.continue", CGF.CurFn);
+
+  llvm::SwitchInst *SI = CGF.Builder.CreateSwitch(FailureOrderVal, MonotonicBB);
+
+  // Emit all the different atomics
+
+  // MonotonicBB is arbitrarily chosen as the default case; in practice, this
+  // doesn't matter unless someone is crazy enough to use something that
+  // doesn't fold to a constant for the ordering.
+  CGF.Builder.SetInsertPoint(MonotonicBB);
+  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2,
+                    Size, Align, SuccessOrder, llvm::Monotonic);
+  CGF.Builder.CreateBr(ContBB);
+
+  if (AcquireBB) {
+    CGF.Builder.SetInsertPoint(AcquireBB);
+    emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2,
+                      Size, Align, SuccessOrder, llvm::Acquire);
+    CGF.Builder.CreateBr(ContBB);
+    SI->addCase(CGF.Builder.getInt32(AtomicExpr::AO_ABI_memory_order_consume),
+                AcquireBB);
+    SI->addCase(CGF.Builder.getInt32(AtomicExpr::AO_ABI_memory_order_acquire),
+                AcquireBB);
+  }
+  if (SeqCstBB) {
+    CGF.Builder.SetInsertPoint(SeqCstBB);
+    emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2,
+                      Size, Align, SuccessOrder, llvm::SequentiallyConsistent);
+    CGF.Builder.CreateBr(ContBB);
+    SI->addCase(CGF.Builder.getInt32(AtomicExpr::AO_ABI_memory_order_seq_cst),
+                SeqCstBB);
+  }
+
+  CGF.Builder.SetInsertPoint(ContBB);
+}
+
+static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, llvm::Value *Dest,
+                         llvm::Value *Ptr, llvm::Value *Val1, llvm::Value *Val2,
+                         llvm::Value *IsWeak, llvm::Value *FailureOrder,
+                         uint64_t Size, unsigned Align,
+                         llvm::AtomicOrdering Order) {
   llvm::AtomicRMWInst::BinOp Op = llvm::AtomicRMWInst::Add;
   llvm::Instruction::BinaryOps PostOp = (llvm::Instruction::BinaryOps)0;
 
@@ -196,25 +315,43 @@
     llvm_unreachable("Already handled!");
 
   case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
+    emitAtomicCmpXchgFailureSet(CGF, E, false, Dest, Ptr, Val1, Val2,
+                                FailureOrder, Size, Align, Order);
+    return;
   case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
+    emitAtomicCmpXchgFailureSet(CGF, E, true, Dest, Ptr, Val1, Val2,
+                                FailureOrder, Size, Align, Order);
+    return;
   case AtomicExpr::AO__atomic_compare_exchange:
   case AtomicExpr::AO__atomic_compare_exchange_n: {
-    // Note that cmpxchg only supports specifying one ordering and
-    // doesn't support weak cmpxchg, at least at the moment.
-    llvm::LoadInst *LoadVal1 = CGF.Builder.CreateLoad(Val1);
-    LoadVal1->setAlignment(Align);
-    llvm::LoadInst *LoadVal2 = CGF.Builder.CreateLoad(Val2);
-    LoadVal2->setAlignment(Align);
-    llvm::AtomicCmpXchgInst *CXI =
-        CGF.Builder.CreateAtomicCmpXchg(Ptr, LoadVal1, LoadVal2, Order);
-    CXI->setVolatile(E->isVolatile());
-    llvm::StoreInst *StoreVal1 = CGF.Builder.CreateStore(CXI, Val1);
-    StoreVal1->setAlignment(Align);
-    llvm::Value *Cmp = CGF.Builder.CreateICmpEQ(CXI, LoadVal1);
-    CGF.EmitStoreOfScalar(Cmp, CGF.MakeAddrLValue(Dest, E->getType()));
+    if (llvm::ConstantInt *IsWeakC = dyn_cast<llvm::ConstantInt>(IsWeak)) {
+      emitAtomicCmpXchgFailureSet(CGF, E, IsWeakC->getZExtValue(), Dest, Ptr,
+                                  Val1, Val2, FailureOrder, Size, Align, Order);
+    } else {
+      // Create all the relevant BB's
+      llvm::BasicBlock *StrongBB =
+          CGF.createBasicBlock("cmpxchg.strong", CGF.CurFn);
+      llvm::BasicBlock *WeakBB = CGF.createBasicBlock("cmxchg.weak", CGF.CurFn);
+      llvm::BasicBlock *ContBB =
+          CGF.createBasicBlock("cmpxchg.continue", CGF.CurFn);
+
+      llvm::SwitchInst *SI = CGF.Builder.CreateSwitch(IsWeak, WeakBB);
+      SI->addCase(CGF.Builder.getInt1(false), StrongBB);
+
+      CGF.Builder.SetInsertPoint(StrongBB);
+      emitAtomicCmpXchgFailureSet(CGF, E, false, Dest, Ptr, Val1, Val2,
+                                  FailureOrder, Size, Align, Order);
+      CGF.Builder.CreateBr(ContBB);
+
+      CGF.Builder.SetInsertPoint(WeakBB);
+      emitAtomicCmpXchgFailureSet(CGF, E, true, Dest, Ptr, Val1, Val2,
+                                  FailureOrder, Size, Align, Order);
+      CGF.Builder.CreateBr(ContBB);
+
+      CGF.Builder.SetInsertPoint(ContBB);
+    }
     return;
   }
-
   case AtomicExpr::AO__c11_atomic_load:
   case AtomicExpr::AO__atomic_load_n:
   case AtomicExpr::AO__atomic_load: {
@@ -351,17 +488,18 @@
   bool UseLibcall = (Size != Align ||
                      getContext().toBits(sizeChars) > MaxInlineWidthInBits);
 
-  llvm::Value *Ptr, *Order, *OrderFail = 0, *Val1 = 0, *Val2 = 0;
-  Ptr = EmitScalarExpr(E->getPtr());
+  llvm::Value *IsWeak = nullptr, *OrderFail = nullptr, *Val1 = nullptr,
+              *Val2 = nullptr;
+  llvm::Value *Ptr = EmitScalarExpr(E->getPtr());
 
   if (E->getOp() == AtomicExpr::AO__c11_atomic_init) {
     assert(!Dest && "Init does not return a value");
     LValue lvalue = LValue::MakeAddr(Ptr, AtomicTy, alignChars, getContext());
     EmitAtomicInit(E->getVal1(), lvalue);
-    return RValue::get(0);
+    return RValue::get(nullptr);
   }
 
-  Order = EmitScalarExpr(E->getOrder());
+  llvm::Value *Order = EmitScalarExpr(E->getOrder());
 
   switch (E->getOp()) {
   case AtomicExpr::AO__c11_atomic_init:
@@ -394,9 +532,8 @@
     else
       Val2 = EmitValToTemp(*this, E->getVal2());
     OrderFail = EmitScalarExpr(E->getOrderFail());
-    // Evaluate and discard the 'weak' argument.
     if (E->getNumSubExprs() == 6)
-      EmitScalarExpr(E->getWeak());
+      IsWeak = EmitScalarExpr(E->getWeak());
     break;
 
   case AtomicExpr::AO__c11_atomic_fetch_add:
@@ -476,6 +613,8 @@
     Args.add(RValue::get(EmitCastToVoidPtr(Ptr)), getContext().VoidPtrTy);
 
     std::string LibCallName;
+    QualType LoweredMemTy =
+      MemTy->isPointerType() ? getContext().getIntPtrType() : MemTy;
     QualType RetTy;
     bool HaveRetTy = false;
     switch (E->getOp()) {
@@ -531,7 +670,7 @@
     case AtomicExpr::AO__c11_atomic_fetch_add:
     case AtomicExpr::AO__atomic_fetch_add:
       LibCallName = "__atomic_fetch_add";
-      AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1, MemTy,
+      AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1, LoweredMemTy,
                         E->getExprLoc());
       break;
     // T __atomic_fetch_and_N(T *mem, T val, int order)
@@ -552,7 +691,7 @@
     case AtomicExpr::AO__c11_atomic_fetch_sub:
     case AtomicExpr::AO__atomic_fetch_sub:
       LibCallName = "__atomic_fetch_sub";
-      AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1, MemTy,
+      AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1, LoweredMemTy,
                         E->getExprLoc());
       break;
     // T __atomic_fetch_xor_N(T *mem, T val, int order)
@@ -593,7 +732,7 @@
     if (!RetTy->isVoidType())
       return Res;
     if (E->getType()->isVoidType())
-      return RValue::get(0);
+      return RValue::get(nullptr);
     return convertTempToRValue(Dest, E->getType(), E->getExprLoc());
   }
 
@@ -615,32 +754,32 @@
   if (isa<llvm::ConstantInt>(Order)) {
     int ord = cast<llvm::ConstantInt>(Order)->getZExtValue();
     switch (ord) {
-    case AO_ABI_memory_order_relaxed:
-      EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, Size, Align,
-                   llvm::Monotonic);
+    case AtomicExpr::AO_ABI_memory_order_relaxed:
+      EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
+                   Size, Align, llvm::Monotonic);
       break;
-    case AO_ABI_memory_order_consume:
-    case AO_ABI_memory_order_acquire:
+    case AtomicExpr::AO_ABI_memory_order_consume:
+    case AtomicExpr::AO_ABI_memory_order_acquire:
       if (IsStore)
         break; // Avoid crashing on code with undefined behavior
-      EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, Size, Align,
-                   llvm::Acquire);
+      EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
+                   Size, Align, llvm::Acquire);
       break;
-    case AO_ABI_memory_order_release:
+    case AtomicExpr::AO_ABI_memory_order_release:
       if (IsLoad)
         break; // Avoid crashing on code with undefined behavior
-      EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, Size, Align,
-                   llvm::Release);
+      EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
+                   Size, Align, llvm::Release);
       break;
-    case AO_ABI_memory_order_acq_rel:
+    case AtomicExpr::AO_ABI_memory_order_acq_rel:
       if (IsLoad || IsStore)
         break; // Avoid crashing on code with undefined behavior
-      EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, Size, Align,
-                   llvm::AcquireRelease);
+      EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
+                   Size, Align, llvm::AcquireRelease);
       break;
-    case AO_ABI_memory_order_seq_cst:
-      EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, Size, Align,
-                   llvm::SequentiallyConsistent);
+    case AtomicExpr::AO_ABI_memory_order_seq_cst:
+      EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
+                   Size, Align, llvm::SequentiallyConsistent);
       break;
     default: // invalid order
       // We should not ever get here normally, but it's hard to
@@ -648,15 +787,16 @@
       break;
     }
     if (E->getType()->isVoidType())
-      return RValue::get(0);
+      return RValue::get(nullptr);
     return convertTempToRValue(OrigDest, E->getType(), E->getExprLoc());
   }
 
   // Long case, when Order isn't obviously constant.
 
   // Create all the relevant BB's
-  llvm::BasicBlock *MonotonicBB = 0, *AcquireBB = 0, *ReleaseBB = 0,
-                   *AcqRelBB = 0, *SeqCstBB = 0;
+  llvm::BasicBlock *MonotonicBB = nullptr, *AcquireBB = nullptr,
+                   *ReleaseBB = nullptr, *AcqRelBB = nullptr,
+                   *SeqCstBB = nullptr;
   MonotonicBB = createBasicBlock("monotonic", CurFn);
   if (!IsStore)
     AcquireBB = createBasicBlock("acquire", CurFn);
@@ -676,41 +816,46 @@
 
   // Emit all the different atomics
   Builder.SetInsertPoint(MonotonicBB);
-  EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, Size, Align,
-               llvm::Monotonic);
+  EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
+               Size, Align, llvm::Monotonic);
   Builder.CreateBr(ContBB);
   if (!IsStore) {
     Builder.SetInsertPoint(AcquireBB);
-    EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, Size, Align,
-                 llvm::Acquire);
+    EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
+                 Size, Align, llvm::Acquire);
     Builder.CreateBr(ContBB);
-    SI->addCase(Builder.getInt32(1), AcquireBB);
-    SI->addCase(Builder.getInt32(2), AcquireBB);
+    SI->addCase(Builder.getInt32(AtomicExpr::AO_ABI_memory_order_consume),
+                AcquireBB);
+    SI->addCase(Builder.getInt32(AtomicExpr::AO_ABI_memory_order_acquire),
+                AcquireBB);
   }
   if (!IsLoad) {
     Builder.SetInsertPoint(ReleaseBB);
-    EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, Size, Align,
-                 llvm::Release);
+    EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
+                 Size, Align, llvm::Release);
     Builder.CreateBr(ContBB);
-    SI->addCase(Builder.getInt32(3), ReleaseBB);
+    SI->addCase(Builder.getInt32(AtomicExpr::AO_ABI_memory_order_release),
+                ReleaseBB);
   }
   if (!IsLoad && !IsStore) {
     Builder.SetInsertPoint(AcqRelBB);
-    EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, Size, Align,
-                 llvm::AcquireRelease);
+    EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
+                 Size, Align, llvm::AcquireRelease);
     Builder.CreateBr(ContBB);
-    SI->addCase(Builder.getInt32(4), AcqRelBB);
+    SI->addCase(Builder.getInt32(AtomicExpr::AO_ABI_memory_order_acq_rel),
+                AcqRelBB);
   }
   Builder.SetInsertPoint(SeqCstBB);
-  EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, Size, Align,
-               llvm::SequentiallyConsistent);
+  EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
+               Size, Align, llvm::SequentiallyConsistent);
   Builder.CreateBr(ContBB);
-  SI->addCase(Builder.getInt32(5), SeqCstBB);
+  SI->addCase(Builder.getInt32(AtomicExpr::AO_ABI_memory_order_seq_cst),
+              SeqCstBB);
 
   // Cleanup and return
   Builder.SetInsertPoint(ContBB);
   if (E->getType()->isVoidType())
-    return RValue::get(0);
+    return RValue::get(nullptr);
   return convertTempToRValue(OrigDest, E->getType(), E->getExprLoc());
 }
 
@@ -761,8 +906,8 @@
              getContext().VoidPtrTy);
     args.add(RValue::get(EmitCastToVoidPtr(tempAddr)),
              getContext().VoidPtrTy);
-    args.add(RValue::get(llvm::ConstantInt::get(IntTy,
-                                                AO_ABI_memory_order_seq_cst)),
+    args.add(RValue::get(llvm::ConstantInt::get(
+                 IntTy, AtomicExpr::AO_ABI_memory_order_seq_cst)),
              getContext().IntTy);
     emitAtomicLibcall(*this, "__atomic_load", getContext().VoidTy, args);
 
@@ -788,7 +933,7 @@
 
   // If we're ignoring an aggregate return, don't do anything.
   if (atomics.getEvaluationKind() == TEK_Aggregate && resultSlot.isIgnored())
-    return RValue::getAggregate(0, false);
+    return RValue::getAggregate(nullptr, false);
 
   // The easiest way to do this this is to go through memory, but we
   // try not to in some easy cases.
@@ -911,8 +1056,8 @@
              getContext().VoidPtrTy);
     args.add(RValue::get(EmitCastToVoidPtr(srcAddr)),
              getContext().VoidPtrTy);
-    args.add(RValue::get(llvm::ConstantInt::get(IntTy,
-                                                AO_ABI_memory_order_seq_cst)),
+    args.add(RValue::get(llvm::ConstantInt::get(
+                 IntTy, AtomicExpr::AO_ABI_memory_order_seq_cst)),
              getContext().IntTy);
     emitAtomicLibcall(*this, "__atomic_store", getContext().VoidTy, args);
     return;
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp
index 692f9a0..72fde9d 100644
--- a/lib/CodeGen/CGBlocks.cpp
+++ b/lib/CodeGen/CGBlocks.cpp
@@ -18,9 +18,9 @@
 #include "CodeGenModule.h"
 #include "clang/AST/DeclObjC.h"
 #include "llvm/ADT/SmallSet.h"
+#include "llvm/IR/CallSite.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/Module.h"
-#include "llvm/Support/CallSite.h"
 #include <algorithm>
 #include <cstdio>
 
@@ -30,9 +30,9 @@
 CGBlockInfo::CGBlockInfo(const BlockDecl *block, StringRef name)
   : Name(name), CXXThisIndex(0), CanBeGlobal(false), NeedsCopyDispose(false),
     HasCXXObject(false), UsesStret(false), HasCapturedVariableLayout(false),
-    StructureType(0), Block(block),
-    DominatingIP(0) {
-    
+    StructureType(nullptr), Block(block),
+    DominatingIP(nullptr) {
+
   // Skip asm prefix, if any.  'name' is usually taken directly from
   // the mangled name of the enclosing function.
   if (!name.empty() && name[0] == '\01')
@@ -53,7 +53,7 @@
   return CodeGenFunction(CGM).GenerateCopyHelperFunction(blockInfo);
 }
 
-/// Build the helper function to dipose of a block.
+/// Build the helper function to dispose of a block.
 static llvm::Constant *buildDisposeHelper(CodeGenModule &CGM,
                                           const CGBlockInfo &blockInfo) {
   return CodeGenFunction(CGM).GenerateDestroyHelperFunction(blockInfo);
@@ -78,7 +78,13 @@
   ASTContext &C = CGM.getContext();
 
   llvm::Type *ulong = CGM.getTypes().ConvertType(C.UnsignedLongTy);
-  llvm::Type *i8p = CGM.getTypes().ConvertType(C.VoidPtrTy);
+  llvm::Type *i8p = NULL;
+  if (CGM.getLangOpts().OpenCL)
+    i8p = 
+      llvm::Type::getInt8PtrTy(
+           CGM.getLLVMContext(), C.getTargetAddressSpace(LangAS::opencl_constant));
+  else
+    i8p = CGM.getTypes().ConvertType(C.VoidPtrTy);
 
   SmallVector<llvm::Constant*, 6> elements;
 
@@ -246,7 +252,7 @@
   // Only records can be unsafe.
   if (!recordType) return true;
 
-  const CXXRecordDecl *record = cast<CXXRecordDecl>(recordType->getDecl());
+  const auto *record = cast<CXXRecordDecl>(recordType->getDecl());
 
   // Maintain semantics for classes with non-trivial dtors or copy ctors.
   if (!record->hasTrivialDestructor()) return false;
@@ -269,7 +275,7 @@
   QualType type = var->getType();
 
   // We can only do this if the variable is const.
-  if (!type.isConstQualified()) return 0;
+  if (!type.isConstQualified()) return nullptr;
 
   // Furthermore, in C++ we have to worry about mutable fields:
   // C++ [dcl.type.cv]p4:
@@ -277,13 +283,13 @@
   //   modified, any attempt to modify a const object during its
   //   lifetime results in undefined behavior.
   if (CGM.getLangOpts().CPlusPlus && !isSafeForCXXConstantCapture(type))
-    return 0;
+    return nullptr;
 
   // If the variable doesn't have any initializer (shouldn't this be
   // invalid?), it's not clear what we should do.  Maybe capture as
   // zero?
   const Expr *init = var->getInit();
-  if (!init) return 0;
+  if (!init) return nullptr;
 
   return CGM.EmitConstantInit(*var, CGF);
 }
@@ -300,8 +306,8 @@
 
   // The header is basically a 'struct { void *; int; int; void *; void *; }'.
   CharUnits ptrSize, ptrAlign, intSize, intAlign;
-  llvm::tie(ptrSize, ptrAlign) = C.getTypeInfoInChars(C.VoidPtrTy);
-  llvm::tie(intSize, intAlign) = C.getTypeInfoInChars(C.IntTy);
+  std::tie(ptrSize, ptrAlign) = C.getTypeInfoInChars(C.VoidPtrTy);
+  std::tie(intSize, intAlign) = C.getTypeInfoInChars(C.IntTy);
 
   // Are there crazy embedded platforms where this isn't true?
   assert(intSize <= ptrSize && "layout assumptions horribly violated");
@@ -366,15 +372,14 @@
 
     layout.push_back(BlockLayoutChunk(tinfo.second, tinfo.first,
                                       Qualifiers::OCL_None,
-                                      0, llvmType));
+                                      nullptr, llvmType));
   }
 
   // Next, all the block captures.
-  for (BlockDecl::capture_const_iterator ci = block->capture_begin(),
-         ce = block->capture_end(); ci != ce; ++ci) {
-    const VarDecl *variable = ci->getVariable();
+  for (const auto &CI : block->captures()) {
+    const VarDecl *variable = CI.getVariable();
 
-    if (ci->isByRef()) {
+    if (CI.isByRef()) {
       // We have to copy/dispose of the __block reference.
       info.NeedsCopyDispose = true;
 
@@ -387,8 +392,7 @@
       maxFieldAlign = std::max(maxFieldAlign, tinfo.second);
 
       layout.push_back(BlockLayoutChunk(tinfo.second, tinfo.first,
-                                        Qualifiers::OCL_None,
-                                        &*ci, llvmType));
+                                        Qualifiers::OCL_None, &CI, llvmType));
       continue;
     }
 
@@ -422,7 +426,7 @@
       lifetime = Qualifiers::OCL_Strong;
 
     // So do types that require non-trivial copy construction.
-    } else if (ci->hasCopyExpr()) {
+    } else if (CI.hasCopyExpr()) {
       info.NeedsCopyDispose = true;
       info.HasCXXObject = true;
 
@@ -446,7 +450,7 @@
     llvm::Type *llvmType =
       CGM.getTypes().ConvertTypeForMem(VT);
     
-    layout.push_back(BlockLayoutChunk(align, size, lifetime, &*ci, llvmType));
+    layout.push_back(BlockLayoutChunk(align, size, lifetime, &CI, llvmType));
   }
 
   // If that was everything, we're done here.
@@ -581,14 +585,13 @@
 
   // Walk through the captures (in order) and find the ones not
   // captured by constant.
-  for (BlockDecl::capture_const_iterator ci = block->capture_begin(),
-         ce = block->capture_end(); ci != ce; ++ci) {
+  for (const auto &CI : block->captures()) {
     // Ignore __block captures; there's nothing special in the
     // on-stack block that we need to do for them.
-    if (ci->isByRef()) continue;
+    if (CI.isByRef()) continue;
 
     // Ignore variables that are constant-captured.
-    const VarDecl *variable = ci->getVariable();
+    const VarDecl *variable = CI.getVariable();
     CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
     if (capture.isConstant()) continue;
 
@@ -664,7 +667,7 @@
     CGBlockInfo *cur = head;
     head = cur->NextBlockInfo;
     delete cur;
-  } while (head != 0);
+  } while (head != nullptr);
 }
 
 /// Emit a block literal expression in the current function.
@@ -679,7 +682,7 @@
   }
 
   // Find the block info for this block and take ownership of it.
-  OwningPtr<CGBlockInfo> blockInfo;
+  std::unique_ptr<CGBlockInfo> blockInfo;
   blockInfo.reset(findAndRemoveBlockInfo(&FirstBlockInfo,
                                          blockExpr->getBlockDecl()));
 
@@ -741,9 +744,8 @@
   }
 
   // Next, captured variables.
-  for (BlockDecl::capture_const_iterator ci = blockDecl->capture_begin(),
-         ce = blockDecl->capture_end(); ci != ce; ++ci) {
-    const VarDecl *variable = ci->getVariable();
+  for (const auto &CI : blockDecl->captures()) {
+    const VarDecl *variable = CI.getVariable();
     const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
 
     // Ignore constant captures.
@@ -761,7 +763,7 @@
     // Compute the address of the thing we're going to move into the
     // block literal.
     llvm::Value *src;
-    if (BlockInfo && ci->isNested()) {
+    if (BlockInfo && CI.isNested()) {
       // We need to use the capture from the enclosing block.
       const CGBlockInfo::Capture &enclosingCapture =
         BlockInfo->getCapture(variable);
@@ -773,15 +775,15 @@
     } else if (blockDecl->isConversionFromLambda()) {
       // The lambda capture in a lambda's conversion-to-block-pointer is
       // special; we'll simply emit it directly.
-      src = 0;
+      src = nullptr;
     } else {
       // Just look it up in the locals map, which will give us back a
       // [[type]]*.  If that doesn't work, do the more elaborate DRE
       // emission.
       src = LocalDeclMap.lookup(variable);
       if (!src) {
-        DeclRefExpr declRef(const_cast<VarDecl*>(variable),
-                            /*refersToEnclosing*/ ci->isNested(), type,
+        DeclRefExpr declRef(const_cast<VarDecl *>(variable),
+                            /*refersToEnclosing*/ CI.isNested(), type,
                             VK_LValue, SourceLocation());
         src = EmitDeclRefLValue(&declRef).getAddress();
       }
@@ -791,9 +793,9 @@
     // the block field.  There's no need to chase the forwarding
     // pointer at this point, since we're building something that will
     // live a shorter life than the stack byref anyway.
-    if (ci->isByRef()) {
+    if (CI.isByRef()) {
       // Get a void* that points to the byref struct.
-      if (ci->isNested())
+      if (CI.isNested())
         src = Builder.CreateAlignedLoad(src, align.getQuantity(),
                                         "byref.capture");
       else
@@ -803,7 +805,7 @@
       Builder.CreateAlignedStore(src, blockField, align.getQuantity());
 
     // If we have a copy constructor, evaluate that into the block field.
-    } else if (const Expr *copyExpr = ci->getCopyExpr()) {
+    } else if (const Expr *copyExpr = CI.getCopyExpr()) {
       if (blockDecl->isConversionFromLambda()) {
         // If we have a lambda conversion, emit the expression
         // directly into the block instead.
@@ -845,13 +847,14 @@
     } else {
       // Fake up a new variable so that EmitScalarInit doesn't think
       // we're referring to the variable in its own initializer.
-      ImplicitParamDecl blockFieldPseudoVar(/*DC*/ 0, SourceLocation(),
-                                            /*name*/ 0, type);
+      ImplicitParamDecl blockFieldPseudoVar(getContext(), /*DC*/ nullptr,
+                                            SourceLocation(), /*name*/ nullptr,
+                                            type);
 
       // We use one of these or the other depending on whether the
       // reference is nested.
       DeclRefExpr declRef(const_cast<VarDecl*>(variable),
-                          /*refersToEnclosing*/ ci->isNested(), type,
+                          /*refersToEnclosing*/ CI.isNested(), type,
                           VK_LValue, SourceLocation());
 
       ImplicitCastExpr l2r(ImplicitCastExpr::OnStack, type, CK_LValueToRValue,
@@ -862,7 +865,7 @@
     }
 
     // Activate the cleanup if layout pushed one.
-    if (!ci->isByRef()) {
+    if (!CI.isByRef()) {
       EHScopeStack::stable_iterator cleanup = capture.getCleanup();
       if (cleanup.isValid())
         ActivateCleanupBlock(cleanup, blockInfo.DominatingIP);
@@ -1023,7 +1026,7 @@
   blockInfo.BlockExpression = blockExpr;
 
   // Compute information about the layout, etc., of this block.
-  computeBlockInfo(*this, 0, blockInfo);
+  computeBlockInfo(*this, nullptr, blockInfo);
 
   // Using that metadata, generate the actual block function.
   llvm::Constant *blockFn;
@@ -1097,7 +1100,7 @@
   // to be local to this function as well, in case they're directly
   // referenced in a block.
   for (DeclMapTy::const_iterator i = ldm.begin(), e = ldm.end(); i != e; ++i) {
-    const VarDecl *var = dyn_cast<VarDecl>(i->first);
+    const auto *var = dyn_cast<VarDecl>(i->first);
     if (var && !var->hasLocalStorage())
       LocalDeclMap[var] = i->second;
   }
@@ -1112,35 +1115,32 @@
   QualType selfTy = getContext().VoidPtrTy;
   IdentifierInfo *II = &CGM.getContext().Idents.get(".block_descriptor");
 
-  ImplicitParamDecl selfDecl(const_cast<BlockDecl*>(blockDecl),
+  ImplicitParamDecl selfDecl(getContext(), const_cast<BlockDecl*>(blockDecl),
                              SourceLocation(), II, selfTy);
   args.push_back(&selfDecl);
 
   // Now add the rest of the parameters.
-  for (BlockDecl::param_const_iterator i = blockDecl->param_begin(),
-       e = blockDecl->param_end(); i != e; ++i)
-    args.push_back(*i);
+  for (auto i : blockDecl->params())
+    args.push_back(i);
 
   // Create the function declaration.
   const FunctionProtoType *fnType = blockInfo.getBlockExpr()->getFunctionType();
-  const CGFunctionInfo &fnInfo =
-    CGM.getTypes().arrangeFunctionDeclaration(fnType->getResultType(), args,
-                                              fnType->getExtInfo(),
-                                              fnType->isVariadic());
-  if (CGM.ReturnTypeUsesSRet(fnInfo))
+  const CGFunctionInfo &fnInfo = CGM.getTypes().arrangeFreeFunctionDeclaration(
+      fnType->getReturnType(), args, fnType->getExtInfo(),
+      fnType->isVariadic());
+  if (CGM.ReturnSlotInterferesWithArgs(fnInfo))
     blockInfo.UsesStret = true;
 
   llvm::FunctionType *fnLLVMType = CGM.getTypes().GetFunctionType(fnInfo);
 
-  MangleBuffer name;
-  CGM.getBlockMangledName(GD, name, blockDecl);
-  llvm::Function *fn =
-    llvm::Function::Create(fnLLVMType, llvm::GlobalValue::InternalLinkage, 
-                           name.getString(), &CGM.getModule());
+  StringRef name = CGM.getBlockMangledName(GD, blockDecl);
+  llvm::Function *fn = llvm::Function::Create(
+      fnLLVMType, llvm::GlobalValue::InternalLinkage, name, &CGM.getModule());
   CGM.SetInternalFunctionAttributes(blockDecl, fn, fnInfo);
 
   // Begin generating the function.
-  StartFunction(blockDecl, fnType->getResultType(), fn, fnInfo, args,
+  StartFunction(blockDecl, fnType->getReturnType(), fn, fnInfo, args,
+                blockDecl->getLocation(),
                 blockInfo.getBlockExpr()->getBody()->getLocStart());
 
   // Okay.  Undo some of what StartFunction did.
@@ -1177,9 +1177,8 @@
   }
 
   // Also force all the constant captures.
-  for (BlockDecl::capture_const_iterator ci = blockDecl->capture_begin(),
-         ce = blockDecl->capture_end(); ci != ce; ++ci) {
-    const VarDecl *variable = ci->getVariable();
+  for (const auto &CI : blockDecl->captures()) {
+    const VarDecl *variable = CI.getVariable();
     const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
     if (!capture.isConstant()) continue;
 
@@ -1201,8 +1200,14 @@
 
   if (IsLambdaConversionToBlock)
     EmitLambdaBlockInvokeBody();
-  else
+  else {
+    PGO.assignRegionCounters(blockDecl, fn);
+    RegionCounter Cnt = getPGORegionCounter(blockDecl->getBody());
+    Cnt.beginRegion(Builder);
     EmitStmt(blockDecl->getBody());
+    PGO.emitInstrumentationData();
+    PGO.destroyRegionCounters();
+  }
 
   // Remember where we were...
   llvm::BasicBlock *resume = Builder.GetInsertBlock();
@@ -1214,9 +1219,8 @@
   // Emit debug information for all the DeclRefExprs.
   // FIXME: also for 'this'
   if (CGDebugInfo *DI = getDebugInfo()) {
-    for (BlockDecl::capture_const_iterator ci = blockDecl->capture_begin(),
-           ce = blockDecl->capture_end(); ci != ce; ++ci) {
-      const VarDecl *variable = ci->getVariable();
+    for (const auto &CI : blockDecl->captures()) {
+      const VarDecl *variable = CI.getVariable();
       DI->EmitLocation(Builder, variable->getLocation());
 
       if (CGM.getCodeGenOpts().getDebugInfo()
@@ -1238,7 +1242,7 @@
   }
 
   // And resume where we left off.
-  if (resume == 0)
+  if (resume == nullptr)
     Builder.ClearInsertionPoint();
   else
     Builder.SetInsertPoint(resume);
@@ -1280,15 +1284,15 @@
   ASTContext &C = getContext();
 
   FunctionArgList args;
-  ImplicitParamDecl dstDecl(0, SourceLocation(), 0, C.VoidPtrTy);
+  ImplicitParamDecl dstDecl(getContext(), nullptr, SourceLocation(), nullptr,
+                            C.VoidPtrTy);
   args.push_back(&dstDecl);
-  ImplicitParamDecl srcDecl(0, SourceLocation(), 0, C.VoidPtrTy);
+  ImplicitParamDecl srcDecl(getContext(), nullptr, SourceLocation(), nullptr,
+                            C.VoidPtrTy);
   args.push_back(&srcDecl);
 
-  const CGFunctionInfo &FI =
-    CGM.getTypes().arrangeFunctionDeclaration(C.VoidTy, args,
-                                              FunctionType::ExtInfo(),
-                                              /*variadic*/ false);
+  const CGFunctionInfo &FI = CGM.getTypes().arrangeFreeFunctionDeclaration(
+      C.VoidTy, args, FunctionType::ExtInfo(), /*variadic=*/false);
 
   // FIXME: it would be nice if these were mergeable with things with
   // identical semantics.
@@ -1304,13 +1308,13 @@
   FunctionDecl *FD = FunctionDecl::Create(C,
                                           C.getTranslationUnitDecl(),
                                           SourceLocation(),
-                                          SourceLocation(), II, C.VoidTy, 0,
-                                          SC_Static,
+                                          SourceLocation(), II, C.VoidTy,
+                                          nullptr, SC_Static,
                                           false,
                                           false);
   // Create a scope with an artificial location for the body of this function.
   ArtificialLocation AL(*this, Builder);
-  StartFunction(FD, C.VoidTy, Fn, FI, args, SourceLocation());
+  StartFunction(FD, C.VoidTy, Fn, FI, args);
   AL.Emit();
 
   llvm::Type *structPtrTy = blockInfo.StructureType->getPointerTo();
@@ -1325,25 +1329,24 @@
 
   const BlockDecl *blockDecl = blockInfo.getBlockDecl();
 
-  for (BlockDecl::capture_const_iterator ci = blockDecl->capture_begin(),
-         ce = blockDecl->capture_end(); ci != ce; ++ci) {
-    const VarDecl *variable = ci->getVariable();
+  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();
+    const Expr *copyExpr = CI.getCopyExpr();
     BlockFieldFlags flags;
 
     bool useARCWeakCopy = false;
     bool useARCStrongCopy = false;
 
     if (copyExpr) {
-      assert(!ci->isByRef());
+      assert(!CI.isByRef());
       // don't bother computing flags
 
-    } else if (ci->isByRef()) {
+    } else if (CI.isByRef()) {
       flags = BLOCK_FIELD_IS_BYREF;
       if (type.isObjCGCWeak())
         flags |= BLOCK_FIELD_IS_WEAK;
@@ -1400,7 +1403,7 @@
         // storeStrong doesn't over-release) and then call storeStrong.
         // This is a workaround to not having an initStrong call.
         if (CGM.getCodeGenOpts().OptimizationLevel == 0) {
-          llvm::PointerType *ty = cast<llvm::PointerType>(srcValue->getType());
+          auto *ty = cast<llvm::PointerType>(srcValue->getType());
           llvm::Value *null = llvm::ConstantPointerNull::get(ty);
           Builder.CreateStore(null, dstField);
           EmitARCStoreStrongCall(dstField, srcValue, true);
@@ -1423,7 +1426,7 @@
         };
 
         bool copyCanThrow = false;
-        if (ci->isByRef() && variable->getType()->getAsCXXRecordDecl()) {
+        if (CI.isByRef() && variable->getType()->getAsCXXRecordDecl()) {
           const Expr *copyExpr =
             CGM.getContext().getBlockVarCopyInits(variable);
           if (copyExpr) {
@@ -1457,13 +1460,12 @@
   ASTContext &C = getContext();
 
   FunctionArgList args;
-  ImplicitParamDecl srcDecl(0, SourceLocation(), 0, C.VoidPtrTy);
+  ImplicitParamDecl srcDecl(getContext(), nullptr, SourceLocation(), nullptr,
+                            C.VoidPtrTy);
   args.push_back(&srcDecl);
 
-  const CGFunctionInfo &FI =
-    CGM.getTypes().arrangeFunctionDeclaration(C.VoidTy, args,
-                                              FunctionType::ExtInfo(),
-                                              /*variadic*/ false);
+  const CGFunctionInfo &FI = CGM.getTypes().arrangeFreeFunctionDeclaration(
+      C.VoidTy, args, FunctionType::ExtInfo(), /*variadic=*/false);
 
   // FIXME: We'd like to put these into a mergable by content, with
   // internal linkage.
@@ -1478,12 +1480,12 @@
 
   FunctionDecl *FD = FunctionDecl::Create(C, C.getTranslationUnitDecl(),
                                           SourceLocation(),
-                                          SourceLocation(), II, C.VoidTy, 0,
-                                          SC_Static,
+                                          SourceLocation(), II, C.VoidTy,
+                                          nullptr, SC_Static,
                                           false, false);
   // Create a scope with an artificial location for the body of this function.
   ArtificialLocation AL(*this, Builder);
-  StartFunction(FD, C.VoidTy, Fn, FI, args, SourceLocation());
+  StartFunction(FD, C.VoidTy, Fn, FI, args);
   AL.Emit();
 
   llvm::Type *structPtrTy = blockInfo.StructureType->getPointerTo();
@@ -1496,21 +1498,20 @@
 
   CodeGenFunction::RunCleanupsScope cleanups(*this);
 
-  for (BlockDecl::capture_const_iterator ci = blockDecl->capture_begin(),
-         ce = blockDecl->capture_end(); ci != ce; ++ci) {
-    const VarDecl *variable = ci->getVariable();
+  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;
 
     BlockFieldFlags flags;
-    const CXXDestructorDecl *dtor = 0;
+    const CXXDestructorDecl *dtor = nullptr;
 
     bool useARCWeakDestroy = false;
     bool useARCStrongDestroy = false;
 
-    if (ci->isByRef()) {
+    if (CI.isByRef()) {
       flags = BLOCK_FIELD_IS_BYREF;
       if (type.isObjCGCWeak())
         flags |= BLOCK_FIELD_IS_WEAK;
@@ -1587,7 +1588,7 @@
     : ByrefHelpers(alignment), Flags(flags) {}
 
   void emitCopy(CodeGenFunction &CGF, llvm::Value *destField,
-                llvm::Value *srcField) {
+                llvm::Value *srcField) override {
     destField = CGF.Builder.CreateBitCast(destField, CGF.VoidPtrTy);
 
     srcField = CGF.Builder.CreateBitCast(srcField, CGF.VoidPtrPtrTy);
@@ -1602,14 +1603,14 @@
     CGF.EmitNounwindRuntimeCall(fn, args);
   }
 
-  void emitDispose(CodeGenFunction &CGF, llvm::Value *field) {
+  void emitDispose(CodeGenFunction &CGF, llvm::Value *field) override {
     field = CGF.Builder.CreateBitCast(field, CGF.Int8PtrTy->getPointerTo(0));
     llvm::Value *value = CGF.Builder.CreateLoad(field);
 
     CGF.BuildBlockRelease(value, Flags | BLOCK_BYREF_CALLER);
   }
 
-  void profileImpl(llvm::FoldingSetNodeID &id) const {
+  void profileImpl(llvm::FoldingSetNodeID &id) const override {
     id.AddInteger(Flags.getBitMask());
   }
 };
@@ -1620,15 +1621,15 @@
   ARCWeakByrefHelpers(CharUnits alignment) : ByrefHelpers(alignment) {}
 
   void emitCopy(CodeGenFunction &CGF, llvm::Value *destField,
-                llvm::Value *srcField) {
+                llvm::Value *srcField) override {
     CGF.EmitARCMoveWeak(destField, srcField);
   }
 
-  void emitDispose(CodeGenFunction &CGF, llvm::Value *field) {
+  void emitDispose(CodeGenFunction &CGF, llvm::Value *field) override {
     CGF.EmitARCDestroyWeak(field);
   }
 
-  void profileImpl(llvm::FoldingSetNodeID &id) const {
+  void profileImpl(llvm::FoldingSetNodeID &id) const override {
     // 0 is distinguishable from all pointers and byref flags
     id.AddInteger(0);
   }
@@ -1641,7 +1642,7 @@
   ARCStrongByrefHelpers(CharUnits alignment) : ByrefHelpers(alignment) {}
 
   void emitCopy(CodeGenFunction &CGF, llvm::Value *destField,
-                llvm::Value *srcField) {
+                llvm::Value *srcField) override {
     // Do a "move" by copying the value and then zeroing out the old
     // variable.
 
@@ -1665,11 +1666,11 @@
     store->setAlignment(Alignment.getQuantity());
   }
 
-  void emitDispose(CodeGenFunction &CGF, llvm::Value *field) {
+  void emitDispose(CodeGenFunction &CGF, llvm::Value *field) override {
     CGF.EmitARCDestroyStrong(field, ARCImpreciseLifetime);
   }
 
-  void profileImpl(llvm::FoldingSetNodeID &id) const {
+  void profileImpl(llvm::FoldingSetNodeID &id) const override {
     // 1 is distinguishable from all pointers and byref flags
     id.AddInteger(1);
   }
@@ -1682,7 +1683,7 @@
   ARCStrongBlockByrefHelpers(CharUnits alignment) : ByrefHelpers(alignment) {}
 
   void emitCopy(CodeGenFunction &CGF, llvm::Value *destField,
-                llvm::Value *srcField) {
+                llvm::Value *srcField) override {
     // Do the copy with objc_retainBlock; that's all that
     // _Block_object_assign would do anyway, and we'd have to pass the
     // right arguments to make sure it doesn't get no-op'ed.
@@ -1695,11 +1696,11 @@
     store->setAlignment(Alignment.getQuantity());
   }
 
-  void emitDispose(CodeGenFunction &CGF, llvm::Value *field) {
+  void emitDispose(CodeGenFunction &CGF, llvm::Value *field) override {
     CGF.EmitARCDestroyStrong(field, ARCImpreciseLifetime);
   }
 
-  void profileImpl(llvm::FoldingSetNodeID &id) const {
+  void profileImpl(llvm::FoldingSetNodeID &id) const override {
     // 2 is distinguishable from all pointers and byref flags
     id.AddInteger(2);
   }
@@ -1716,20 +1717,20 @@
                   const Expr *copyExpr)
     : ByrefHelpers(alignment), VarType(type), CopyExpr(copyExpr) {}
 
-  bool needsCopy() const { return CopyExpr != 0; }
+  bool needsCopy() const override { return CopyExpr != nullptr; }
   void emitCopy(CodeGenFunction &CGF, llvm::Value *destField,
-                llvm::Value *srcField) {
+                llvm::Value *srcField) override {
     if (!CopyExpr) return;
     CGF.EmitSynthesizedCXXCopyCtor(destField, srcField, CopyExpr);
   }
 
-  void emitDispose(CodeGenFunction &CGF, llvm::Value *field) {
+  void emitDispose(CodeGenFunction &CGF, llvm::Value *field) override {
     EHScopeStack::stable_iterator cleanupDepth = CGF.EHStack.stable_begin();
     CGF.PushDestructorCleanup(VarType, field);
     CGF.PopCleanupBlocks(cleanupDepth);
   }
 
-  void profileImpl(llvm::FoldingSetNodeID &id) const {
+  void profileImpl(llvm::FoldingSetNodeID &id) const override {
     id.AddPointer(VarType.getCanonicalType().getAsOpaquePtr());
   }
 };
@@ -1745,16 +1746,16 @@
   QualType R = Context.VoidTy;
 
   FunctionArgList args;
-  ImplicitParamDecl dst(0, SourceLocation(), 0, Context.VoidPtrTy);
+  ImplicitParamDecl dst(CGF.getContext(), nullptr, SourceLocation(), nullptr,
+                        Context.VoidPtrTy);
   args.push_back(&dst);
 
-  ImplicitParamDecl src(0, SourceLocation(), 0, Context.VoidPtrTy);
+  ImplicitParamDecl src(CGF.getContext(), nullptr, SourceLocation(), nullptr,
+                        Context.VoidPtrTy);
   args.push_back(&src);
 
-  const CGFunctionInfo &FI =
-    CGF.CGM.getTypes().arrangeFunctionDeclaration(R, args,
-                                                  FunctionType::ExtInfo(),
-                                                  /*variadic*/ false);
+  const CGFunctionInfo &FI = CGF.CGM.getTypes().arrangeFreeFunctionDeclaration(
+      R, args, FunctionType::ExtInfo(), /*variadic=*/false);
 
   CodeGenTypes &Types = CGF.CGM.getTypes();
   llvm::FunctionType *LTy = Types.GetFunctionType(FI);
@@ -1771,11 +1772,11 @@
   FunctionDecl *FD = FunctionDecl::Create(Context,
                                           Context.getTranslationUnitDecl(),
                                           SourceLocation(),
-                                          SourceLocation(), II, R, 0,
+                                          SourceLocation(), II, R, nullptr,
                                           SC_Static,
                                           false, false);
 
-  CGF.StartFunction(FD, R, Fn, FI, args, SourceLocation());
+  CGF.StartFunction(FD, R, Fn, FI, args);
 
   if (byrefInfo.needsCopy()) {
     llvm::Type *byrefPtrType = byrefType.getPointerTo(0);
@@ -1819,13 +1820,12 @@
   QualType R = Context.VoidTy;
 
   FunctionArgList args;
-  ImplicitParamDecl src(0, SourceLocation(), 0, Context.VoidPtrTy);
+  ImplicitParamDecl src(CGF.getContext(), nullptr, SourceLocation(), nullptr,
+                        Context.VoidPtrTy);
   args.push_back(&src);
 
-  const CGFunctionInfo &FI =
-    CGF.CGM.getTypes().arrangeFunctionDeclaration(R, args,
-                                                  FunctionType::ExtInfo(),
-                                                  /*variadic*/ false);
+  const CGFunctionInfo &FI = CGF.CGM.getTypes().arrangeFreeFunctionDeclaration(
+      R, args, FunctionType::ExtInfo(), /*variadic=*/false);
 
   CodeGenTypes &Types = CGF.CGM.getTypes();
   llvm::FunctionType *LTy = Types.GetFunctionType(FI);
@@ -1843,10 +1843,10 @@
   FunctionDecl *FD = FunctionDecl::Create(Context,
                                           Context.getTranslationUnitDecl(),
                                           SourceLocation(),
-                                          SourceLocation(), II, R, 0,
+                                          SourceLocation(), II, R, nullptr,
                                           SC_Static,
                                           false, false);
-  CGF.StartFunction(FD, R, Fn, FI, args, SourceLocation());
+  CGF.StartFunction(FD, R, Fn, FI, args);
 
   if (byrefInfo.needsDispose()) {
     llvm::Value *V = CGF.GetAddrOfLocalVar(&src);
@@ -1913,7 +1913,7 @@
 
   if (const CXXRecordDecl *record = type->getAsCXXRecordDecl()) {
     const Expr *copyExpr = CGM.getContext().getBlockVarCopyInits(&var);
-    if (!copyExpr && record->hasTrivialDestructor()) return 0;
+    if (!copyExpr && record->hasTrivialDestructor()) return nullptr;
 
     CXXByrefHelpers byrefInfo(emission.Alignment, type, copyExpr);
     return ::buildByrefHelpers(CGM, byrefType, byrefValueIndex, byrefInfo);
@@ -1921,7 +1921,7 @@
 
   // Otherwise, if we don't have a retainable type, there's nothing to do.
   // that the runtime does extra copies.
-  if (!type->isObjCRetainableType()) return 0;
+  if (!type->isObjCRetainableType()) return nullptr;
 
   Qualifiers qs = type.getQualifiers();
 
@@ -1935,7 +1935,7 @@
     // These are just bits as far as the runtime is concerned.
     case Qualifiers::OCL_ExplicitNone:
     case Qualifiers::OCL_Autoreleasing:
-      return 0;
+      return nullptr;
 
     // Tell the runtime that this is ARC __weak, called by the
     // byref routines.
@@ -1969,7 +1969,7 @@
              type->isObjCObjectPointerType()) {
     flags |= BLOCK_FIELD_IS_OBJECT;
   } else {
-    return 0;
+    return nullptr;
   }
 
   if (type.isObjCGCWeak())
@@ -2218,7 +2218,7 @@
     llvm::Value *Addr;
     CallBlockRelease(llvm::Value *Addr) : Addr(Addr) {}
 
-    void Emit(CodeGenFunction &CGF, Flags flags) {
+    void Emit(CodeGenFunction &CGF, Flags flags) override {
       // Should we be passing FIELD_IS_WEAK here?
       CGF.BuildBlockRelease(Addr, BLOCK_FIELD_IS_BYREF);
     }
@@ -2242,9 +2242,8 @@
                                          llvm::Constant *C) {
   if (!CGM.getLangOpts().BlocksRuntimeOptional) return;
 
-  llvm::GlobalValue *GV = cast<llvm::GlobalValue>(C->stripPointerCasts());
-  if (GV->isDeclaration() &&
-      GV->getLinkage() == llvm::GlobalValue::ExternalLinkage)
+  auto *GV = cast<llvm::GlobalValue>(C->stripPointerCasts());
+  if (GV->isDeclaration() && GV->hasExternalLinkage())
     GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
 }
 
@@ -2277,7 +2276,8 @@
     return NSConcreteGlobalBlock;
 
   NSConcreteGlobalBlock = GetOrCreateLLVMGlobal("_NSConcreteGlobalBlock",
-                                                Int8PtrTy->getPointerTo(), 0);
+                                                Int8PtrTy->getPointerTo(),
+                                                nullptr);
   configureBlocksRuntimeObject(*this, NSConcreteGlobalBlock);
   return NSConcreteGlobalBlock;
 }
@@ -2287,7 +2287,8 @@
     return NSConcreteStackBlock;
 
   NSConcreteStackBlock = GetOrCreateLLVMGlobal("_NSConcreteStackBlock",
-                                               Int8PtrTy->getPointerTo(), 0);
+                                               Int8PtrTy->getPointerTo(),
+                                               nullptr);
   configureBlocksRuntimeObject(*this, NSConcreteStackBlock);
   return NSConcreteStackBlock;  
 }
diff --git a/lib/CodeGen/CGBlocks.h b/lib/CodeGen/CGBlocks.h
index 020638a..0031e32 100644
--- a/lib/CodeGen/CGBlocks.h
+++ b/lib/CodeGen/CGBlocks.h
@@ -28,15 +28,15 @@
 #include "llvm/IR/Module.h"
 
 namespace llvm {
-  class Module;
-  class Constant;
-  class Function;
-  class GlobalValue;
-  class DataLayout;
-  class FunctionType;
-  class PointerType;
-  class Value;
-  class LLVMContext;
+class Module;
+class Constant;
+class Function;
+class GlobalValue;
+class DataLayout;
+class FunctionType;
+class PointerType;
+class Value;
+class LLVMContext;
 }
 
 namespace clang {
diff --git a/lib/CodeGen/CGBuilder.h b/lib/CodeGen/CGBuilder.h
index fd21e7e..f113b97 100644
--- a/lib/CodeGen/CGBuilder.h
+++ b/lib/CodeGen/CGBuilder.h
@@ -15,12 +15,39 @@
 namespace clang {
 namespace CodeGen {
 
+class CodeGenFunction;
+
+/// \brief This is an IRBuilder insertion helper that forwards to
+/// CodeGenFunction::InsertHelper, which adds nesessary metadata to
+/// instructions.
+template <bool PreserveNames>
+class CGBuilderInserter
+  : protected llvm::IRBuilderDefaultInserter<PreserveNames> {
+public:
+  CGBuilderInserter() : CGF(nullptr) {}
+  explicit CGBuilderInserter(CodeGenFunction *CGF) : CGF(CGF) {}
+
+protected:
+  /// \brief This forwards to CodeGenFunction::InsertHelper.
+  void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name,
+                    llvm::BasicBlock *BB,
+                    llvm::BasicBlock::iterator InsertPt) const;
+private:
+  void operator=(const CGBuilderInserter &) LLVM_DELETED_FUNCTION;
+
+  CodeGenFunction *CGF;
+};
+
 // Don't preserve names on values in an optimized build.
 #ifdef NDEBUG
-typedef llvm::IRBuilder<false> CGBuilderTy;
+#define PreserveNames false
 #else
-typedef llvm::IRBuilder<> CGBuilderTy;
+#define PreserveNames true
 #endif
+typedef CGBuilderInserter<PreserveNames> CGBuilderInserterTy;
+typedef llvm::IRBuilder<PreserveNames, llvm::ConstantFolder,
+                        CGBuilderInserterTy> CGBuilderTy;
+#undef PreserveNames
 
 }  // end namespace CodeGen
 }  // end namespace clang
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index 8b23f0c..03a0397 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -213,11 +213,14 @@
   default: break;  // Handle intrinsics and libm functions below.
   case Builtin::BI__builtin___CFStringMakeConstantString:
   case Builtin::BI__builtin___NSStringMakeConstantString:
-    return RValue::get(CGM.EmitConstantExpr(E, E->getType(), 0));
+    return RValue::get(CGM.EmitConstantExpr(E, E->getType(), nullptr));
   case Builtin::BI__builtin_stdarg_start:
   case Builtin::BI__builtin_va_start:
+  case Builtin::BI__va_start:
   case Builtin::BI__builtin_va_end: {
-    Value *ArgValue = EmitVAListRef(E->getArg(0));
+    Value *ArgValue = (BuiltinID == Builtin::BI__va_start)
+                          ? EmitScalarExpr(E->getArg(0))
+                          : EmitVAListRef(E->getArg(0));
     llvm::Type *DestType = Int8PtrTy;
     if (ArgValue->getType() != DestType)
       ArgValue = Builder.CreateBitCast(ArgValue, DestType,
@@ -430,6 +433,12 @@
     Value *F = CGM.getIntrinsic(Intrinsic::readcyclecounter);
     return RValue::get(Builder.CreateCall(F));
   }
+  case Builtin::BI__builtin___clear_cache: {
+    Value *Begin = EmitScalarExpr(E->getArg(0));
+    Value *End = EmitScalarExpr(E->getArg(1));
+    Value *F = CGM.getIntrinsic(Intrinsic::clear_cache);
+    return RValue::get(Builder.CreateCall2(F, Begin, End));
+  }
   case Builtin::BI__builtin_trap: {
     Value *F = CGM.getIntrinsic(Intrinsic::trap);
     return RValue::get(Builder.CreateCall(F));
@@ -439,17 +448,18 @@
     return RValue::get(Builder.CreateCall(F));
   }
   case Builtin::BI__builtin_unreachable: {
-    if (SanOpts->Unreachable)
+    if (SanOpts->Unreachable) {
+      SanitizerScope SanScope(this);
       EmitCheck(Builder.getFalse(), "builtin_unreachable",
                 EmitCheckSourceLocation(E->getExprLoc()),
                 ArrayRef<llvm::Value *>(), CRK_Unrecoverable);
-    else
+    } else
       Builder.CreateUnreachable();
 
     // We do need to preserve an insertion point.
     EmitBlock(createBasicBlock("unreachable.cont"));
 
-    return RValue::get(0);
+    return RValue::get(nullptr);
   }
 
   case Builtin::BI__builtin_powi:
@@ -782,7 +792,7 @@
     // We do need to preserve an insertion point.
     EmitBlock(createBasicBlock("builtin_eh_return.cont"));
 
-    return RValue::get(0);
+    return RValue::get(nullptr);
   }
   case Builtin::BI__builtin_unwind_init: {
     Value *F = CGM.getIntrinsic(Intrinsic::eh_unwind_init);
@@ -848,7 +858,7 @@
     // We do need to preserve an insertion point.
     EmitBlock(createBasicBlock("longjmp.cont"));
 
-    return RValue::get(0);
+    return RValue::get(nullptr);
   }
   case Builtin::BI__sync_fetch_and_add:
   case Builtin::BI__sync_fetch_and_sub:
@@ -965,7 +975,9 @@
     Args[2] = EmitToInt(*this, EmitScalarExpr(E->getArg(2)), T, IntType);
 
     Value *Result = Builder.CreateAtomicCmpXchg(Args[0], Args[1], Args[2],
+                                                llvm::SequentiallyConsistent,
                                                 llvm::SequentiallyConsistent);
+    Result = Builder.CreateExtractValue(Result, 0);
     Result = EmitFromInt(*this, Result, T, ValueType);
     return RValue::get(Result);
   }
@@ -989,10 +1001,10 @@
     Args[1] = EmitToInt(*this, EmitScalarExpr(E->getArg(1)), T, IntType);
     Args[2] = EmitToInt(*this, EmitScalarExpr(E->getArg(2)), T, IntType);
 
-    Value *OldVal = Args[1];
-    Value *PrevVal = Builder.CreateAtomicCmpXchg(Args[0], Args[1], Args[2],
-                                                 llvm::SequentiallyConsistent);
-    Value *Result = Builder.CreateICmpEQ(PrevVal, OldVal);
+    Value *Pair = Builder.CreateAtomicCmpXchg(Args[0], Args[1], Args[2],
+                                              llvm::SequentiallyConsistent,
+                                              llvm::SequentiallyConsistent);
+    Value *Result = Builder.CreateExtractValue(Pair, 1);
     // zext bool to int.
     Result = Builder.CreateZExt(Result, ConvertType(E->getType()));
     return RValue::get(Result);
@@ -1027,7 +1039,7 @@
       Builder.CreateStore(llvm::Constant::getNullValue(ITy), Ptr);
     Store->setAlignment(StoreSize.getQuantity());
     Store->setAtomic(llvm::Release);
-    return RValue::get(0);
+    return RValue::get(nullptr);
   }
 
   case Builtin::BI__sync_synchronize: {
@@ -1061,7 +1073,7 @@
       Builder.CreateFence(llvm::SequentiallyConsistent);
     }
     // @LOCALMOD-END
-    return RValue::get(0);
+    return RValue::get(nullptr);
   }
 
   case Builtin::BI__c11_atomic_is_lock_free:
@@ -1102,7 +1114,7 @@
     Value *Order = EmitScalarExpr(E->getArg(1));
     if (isa<llvm::ConstantInt>(Order)) {
       int ord = cast<llvm::ConstantInt>(Order)->getZExtValue();
-      AtomicRMWInst *Result = 0;
+      AtomicRMWInst *Result = nullptr;
       switch (ord) {
       case 0:  // memory_order_relaxed
       default: // invalid order
@@ -1202,7 +1214,7 @@
         Store->setOrdering(llvm::SequentiallyConsistent);
         break;
       }
-      return RValue::get(0);
+      return RValue::get(nullptr);
     }
 
     llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn);
@@ -1232,7 +1244,7 @@
     SI->addCase(Builder.getInt32(5), BBs[2]);
 
     Builder.SetInsertPoint(ContBB);
-    return RValue::get(0);
+    return RValue::get(nullptr);
   }
 
   case Builtin::BI__atomic_thread_fence:
@@ -1266,7 +1278,7 @@
         Builder.CreateFence(llvm::SequentiallyConsistent, Scope);
         break;
       }
-      return RValue::get(0);
+      return RValue::get(nullptr);
     }
 
     llvm::BasicBlock *AcquireBB, *ReleaseBB, *AcqRelBB, *SeqCstBB;
@@ -1301,7 +1313,7 @@
     SI->addCase(Builder.getInt32(5), SeqCstBB);
 
     Builder.SetInsertPoint(ContBB);
-    return RValue::get(0);
+    return RValue::get(nullptr);
   }
 
     // Library functions with special handling.
@@ -1334,7 +1346,6 @@
     llvm::Type *ArgType = Base->getType();
     Value *F = CGM.getIntrinsic(Intrinsic::pow, ArgType);
     return RValue::get(Builder.CreateCall2(F, Base, Exponent));
-    break;
   }
 
   case Builtin::BIfma:
@@ -1521,8 +1532,84 @@
   }
   case Builtin::BI__builtin_addressof:
     return RValue::get(EmitLValue(E->getArg(0)).getAddress());
+  case Builtin::BI__builtin_operator_new:
+    return EmitBuiltinNewDeleteCall(FD->getType()->castAs<FunctionProtoType>(),
+                                    E->getArg(0), false);
+  case Builtin::BI__builtin_operator_delete:
+    return EmitBuiltinNewDeleteCall(FD->getType()->castAs<FunctionProtoType>(),
+                                    E->getArg(0), true);
   case Builtin::BI__noop:
-    return RValue::get(0);
+    // __noop always evaluates to an integer literal zero.
+    return RValue::get(ConstantInt::get(IntTy, 0));
+  case Builtin::BI__assume:
+    // Until LLVM supports assumptions at the IR level, this becomes nothing.
+    return RValue::get(nullptr);
+  case Builtin::BI_InterlockedExchange:
+  case Builtin::BI_InterlockedExchangePointer:
+    return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xchg, E);
+  case Builtin::BI_InterlockedCompareExchangePointer: {
+    llvm::Type *RTy;
+    llvm::IntegerType *IntType =
+      IntegerType::get(getLLVMContext(),
+                       getContext().getTypeSize(E->getType()));
+    llvm::Type *IntPtrType = IntType->getPointerTo();
+
+    llvm::Value *Destination =
+      Builder.CreateBitCast(EmitScalarExpr(E->getArg(0)), IntPtrType);
+
+    llvm::Value *Exchange = EmitScalarExpr(E->getArg(1));
+    RTy = Exchange->getType();
+    Exchange = Builder.CreatePtrToInt(Exchange, IntType);
+
+    llvm::Value *Comparand =
+      Builder.CreatePtrToInt(EmitScalarExpr(E->getArg(2)), IntType);
+
+    auto Result = Builder.CreateAtomicCmpXchg(Destination, Comparand, Exchange,
+                                              SequentiallyConsistent,
+                                              SequentiallyConsistent);
+    Result->setVolatile(true);
+
+    return RValue::get(Builder.CreateIntToPtr(Builder.CreateExtractValue(Result,
+                                                                         0),
+                                              RTy));
+  }
+  case Builtin::BI_InterlockedCompareExchange: {
+    AtomicCmpXchgInst *CXI = Builder.CreateAtomicCmpXchg(
+        EmitScalarExpr(E->getArg(0)),
+        EmitScalarExpr(E->getArg(2)),
+        EmitScalarExpr(E->getArg(1)),
+        SequentiallyConsistent,
+        SequentiallyConsistent);
+      CXI->setVolatile(true);
+      return RValue::get(Builder.CreateExtractValue(CXI, 0));
+  }
+  case Builtin::BI_InterlockedIncrement: {
+    AtomicRMWInst *RMWI = Builder.CreateAtomicRMW(
+      AtomicRMWInst::Add,
+      EmitScalarExpr(E->getArg(0)),
+      ConstantInt::get(Int32Ty, 1),
+      llvm::SequentiallyConsistent);
+    RMWI->setVolatile(true);
+    return RValue::get(Builder.CreateAdd(RMWI, ConstantInt::get(Int32Ty, 1)));
+  }
+  case Builtin::BI_InterlockedDecrement: {
+    AtomicRMWInst *RMWI = Builder.CreateAtomicRMW(
+      AtomicRMWInst::Sub,
+      EmitScalarExpr(E->getArg(0)),
+      ConstantInt::get(Int32Ty, 1),
+      llvm::SequentiallyConsistent);
+    RMWI->setVolatile(true);
+    return RValue::get(Builder.CreateSub(RMWI, ConstantInt::get(Int32Ty, 1)));
+  }
+  case Builtin::BI_InterlockedExchangeAdd: {
+    AtomicRMWInst *RMWI = Builder.CreateAtomicRMW(
+      AtomicRMWInst::Add,
+      EmitScalarExpr(E->getArg(0)),
+      EmitScalarExpr(E->getArg(1)),
+      llvm::SequentiallyConsistent);
+    RMWI->setVolatile(true);
+    return RValue::get(RMWI);
+  }
   }
 
   // If this is an alias for a lib function (e.g. __builtin_sin), emit
@@ -1541,8 +1628,14 @@
   const char *Name = getContext().BuiltinInfo.GetName(BuiltinID);
   Intrinsic::ID IntrinsicID = Intrinsic::not_intrinsic;
   if (const char *Prefix =
-      llvm::Triple::getArchTypePrefix(getTarget().getTriple().getArch()))
+          llvm::Triple::getArchTypePrefix(getTarget().getTriple().getArch())) {
     IntrinsicID = Intrinsic::getIntrinsicForGCCBuiltin(Prefix, Name);
+    // NOTE we dont need to perform a compatibility flag check here since the
+    // intrinsics are declared in Builtins*.def via LANGBUILTIN which filter the
+    // MS builtins via ALL_MS_LANGUAGES and are filtered earlier.
+    if (IntrinsicID == Intrinsic::not_intrinsic)
+      IntrinsicID = Intrinsic::getIntrinsicForMSBuiltin(Prefix, Name);
+  }
 
   if (IntrinsicID != Intrinsic::not_intrinsic) {
     SmallVector<Value*, 16> Args;
@@ -1613,11 +1706,16 @@
 Value *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID,
                                               const CallExpr *E) {
   switch (getTarget().getTriple().getArch()) {
-  case llvm::Triple::aarch64:
-    return EmitAArch64BuiltinExpr(BuiltinID, E);
   case llvm::Triple::arm:
+  case llvm::Triple::armeb:
   case llvm::Triple::thumb:
+  case llvm::Triple::thumbeb:
     return EmitARMBuiltinExpr(BuiltinID, E);
+  case llvm::Triple::aarch64:
+  case llvm::Triple::aarch64_be:
+  case llvm::Triple::arm64:
+  case llvm::Triple::arm64_be:
+    return EmitAArch64BuiltinExpr(BuiltinID, E);
   case llvm::Triple::x86:
   case llvm::Triple::x86_64:
     return EmitX86BuiltinExpr(BuiltinID, E);
@@ -1625,8 +1723,10 @@
   case llvm::Triple::ppc64:
   case llvm::Triple::ppc64le:
     return EmitPPCBuiltinExpr(BuiltinID, E);
+  case llvm::Triple::r600:
+    return EmitR600BuiltinExpr(BuiltinID, E);
   default:
-    return 0;
+    return nullptr;
   }
 }
 
@@ -1647,6 +1747,11 @@
   case NeonTypeFlags::Int64:
   case NeonTypeFlags::Poly64:
     return llvm::VectorType::get(CGF->Int64Ty, V1Ty ? 1 : (1 << IsQuad));
+  case NeonTypeFlags::Poly128:
+    // FIXME: i128 and f128 doesn't get fully support in Clang and llvm.
+    // There is a lot of i128 and f128 API missing.
+    // so we use v16i8 to represent poly128 and get pattern matched.
+    return llvm::VectorType::get(CGF->Int8Ty, 16);
   case NeonTypeFlags::Float32:
     return llvm::VectorType::get(CGF->FloatTy, V1Ty ? 1 : (2 << IsQuad));
   case NeonTypeFlags::Float64:
@@ -1772,756 +1877,1150 @@
   return std::make_pair(EmitScalarExpr(Addr), Align);
 }
 
-static Value *EmitAArch64ScalarBuiltinExpr(CodeGenFunction &CGF,
-                                           unsigned BuiltinID,
-                                           const CallExpr *E) {
-  unsigned int Int = 0;
-  // Scalar result generated across vectors
-  bool AcrossVec = false;
-  // Extend element of one-element vector
-  bool ExtendEle = false;
-  bool OverloadInt = false;
-  bool OverloadCmpInt = false;
-  bool OverloadWideInt = false;
-  bool OverloadNarrowInt = false;
-  const char *s = NULL;
+enum {
+  AddRetType = (1 << 0),
+  Add1ArgType = (1 << 1),
+  Add2ArgTypes = (1 << 2),
 
-  SmallVector<Value *, 4> Ops;
-  for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) {
-    Ops.push_back(CGF.EmitScalarExpr(E->getArg(i)));
+  VectorizeRetType = (1 << 3),
+  VectorizeArgTypes = (1 << 4),
+
+  InventFloatType = (1 << 5),
+  UnsignedAlts = (1 << 6),
+
+  Use64BitVectors = (1 << 7),
+  Use128BitVectors = (1 << 8),
+
+  Vectorize1ArgType = Add1ArgType | VectorizeArgTypes,
+  VectorRet = AddRetType | VectorizeRetType,
+  VectorRetGetArgs01 =
+      AddRetType | Add2ArgTypes | VectorizeRetType | VectorizeArgTypes,
+  FpCmpzModifiers =
+      AddRetType | VectorizeRetType | Add1ArgType | InventFloatType
+};
+
+ struct NeonIntrinsicInfo {
+  unsigned BuiltinID;
+  unsigned LLVMIntrinsic;
+  unsigned AltLLVMIntrinsic;
+  const char *NameHint;
+  unsigned TypeModifier;
+
+  bool operator<(unsigned RHSBuiltinID) const {
+    return BuiltinID < RHSBuiltinID;
+  }
+};
+
+#define NEONMAP0(NameBase) \
+  { NEON::BI__builtin_neon_ ## NameBase, 0, 0, #NameBase, 0 }
+
+#define NEONMAP1(NameBase, LLVMIntrinsic, TypeModifier) \
+  { NEON:: BI__builtin_neon_ ## NameBase, \
+      Intrinsic::LLVMIntrinsic, 0, #NameBase, TypeModifier }
+
+#define NEONMAP2(NameBase, LLVMIntrinsic, AltLLVMIntrinsic, TypeModifier) \
+  { NEON:: BI__builtin_neon_ ## NameBase, \
+      Intrinsic::LLVMIntrinsic, Intrinsic::AltLLVMIntrinsic, \
+      #NameBase, TypeModifier }
+
+static NeonIntrinsicInfo ARMSIMDIntrinsicMap [] = {
+  NEONMAP2(vabd_v, arm_neon_vabdu, arm_neon_vabds, Add1ArgType | UnsignedAlts),
+  NEONMAP2(vabdq_v, arm_neon_vabdu, arm_neon_vabds, Add1ArgType | UnsignedAlts),
+  NEONMAP1(vabs_v, arm_neon_vabs, 0),
+  NEONMAP1(vabsq_v, arm_neon_vabs, 0),
+  NEONMAP0(vaddhn_v),
+  NEONMAP1(vaesdq_v, arm_neon_aesd, 0),
+  NEONMAP1(vaeseq_v, arm_neon_aese, 0),
+  NEONMAP1(vaesimcq_v, arm_neon_aesimc, 0),
+  NEONMAP1(vaesmcq_v, arm_neon_aesmc, 0),
+  NEONMAP1(vbsl_v, arm_neon_vbsl, AddRetType),
+  NEONMAP1(vbslq_v, arm_neon_vbsl, AddRetType),
+  NEONMAP1(vcage_v, arm_neon_vacge, 0),
+  NEONMAP1(vcageq_v, arm_neon_vacge, 0),
+  NEONMAP1(vcagt_v, arm_neon_vacgt, 0),
+  NEONMAP1(vcagtq_v, arm_neon_vacgt, 0),
+  NEONMAP1(vcale_v, arm_neon_vacge, 0),
+  NEONMAP1(vcaleq_v, arm_neon_vacge, 0),
+  NEONMAP1(vcalt_v, arm_neon_vacgt, 0),
+  NEONMAP1(vcaltq_v, arm_neon_vacgt, 0),
+  NEONMAP1(vcls_v, arm_neon_vcls, Add1ArgType),
+  NEONMAP1(vclsq_v, arm_neon_vcls, Add1ArgType),
+  NEONMAP1(vclz_v, ctlz, Add1ArgType),
+  NEONMAP1(vclzq_v, ctlz, Add1ArgType),
+  NEONMAP1(vcnt_v, ctpop, Add1ArgType),
+  NEONMAP1(vcntq_v, ctpop, Add1ArgType),
+  NEONMAP1(vcvt_f16_v, arm_neon_vcvtfp2hf, 0),
+  NEONMAP1(vcvt_f32_f16, arm_neon_vcvthf2fp, 0),
+  NEONMAP0(vcvt_f32_v),
+  NEONMAP2(vcvt_n_f32_v, arm_neon_vcvtfxu2fp, arm_neon_vcvtfxs2fp, 0),
+  NEONMAP1(vcvt_n_s32_v, arm_neon_vcvtfp2fxs, 0),
+  NEONMAP1(vcvt_n_s64_v, arm_neon_vcvtfp2fxs, 0),
+  NEONMAP1(vcvt_n_u32_v, arm_neon_vcvtfp2fxu, 0),
+  NEONMAP1(vcvt_n_u64_v, arm_neon_vcvtfp2fxu, 0),
+  NEONMAP0(vcvt_s32_v),
+  NEONMAP0(vcvt_s64_v),
+  NEONMAP0(vcvt_u32_v),
+  NEONMAP0(vcvt_u64_v),
+  NEONMAP1(vcvta_s32_v, arm_neon_vcvtas, 0),
+  NEONMAP1(vcvta_s64_v, arm_neon_vcvtas, 0),
+  NEONMAP1(vcvta_u32_v, arm_neon_vcvtau, 0),
+  NEONMAP1(vcvta_u64_v, arm_neon_vcvtau, 0),
+  NEONMAP1(vcvtaq_s32_v, arm_neon_vcvtas, 0),
+  NEONMAP1(vcvtaq_s64_v, arm_neon_vcvtas, 0),
+  NEONMAP1(vcvtaq_u32_v, arm_neon_vcvtau, 0),
+  NEONMAP1(vcvtaq_u64_v, arm_neon_vcvtau, 0),
+  NEONMAP1(vcvtm_s32_v, arm_neon_vcvtms, 0),
+  NEONMAP1(vcvtm_s64_v, arm_neon_vcvtms, 0),
+  NEONMAP1(vcvtm_u32_v, arm_neon_vcvtmu, 0),
+  NEONMAP1(vcvtm_u64_v, arm_neon_vcvtmu, 0),
+  NEONMAP1(vcvtmq_s32_v, arm_neon_vcvtms, 0),
+  NEONMAP1(vcvtmq_s64_v, arm_neon_vcvtms, 0),
+  NEONMAP1(vcvtmq_u32_v, arm_neon_vcvtmu, 0),
+  NEONMAP1(vcvtmq_u64_v, arm_neon_vcvtmu, 0),
+  NEONMAP1(vcvtn_s32_v, arm_neon_vcvtns, 0),
+  NEONMAP1(vcvtn_s64_v, arm_neon_vcvtns, 0),
+  NEONMAP1(vcvtn_u32_v, arm_neon_vcvtnu, 0),
+  NEONMAP1(vcvtn_u64_v, arm_neon_vcvtnu, 0),
+  NEONMAP1(vcvtnq_s32_v, arm_neon_vcvtns, 0),
+  NEONMAP1(vcvtnq_s64_v, arm_neon_vcvtns, 0),
+  NEONMAP1(vcvtnq_u32_v, arm_neon_vcvtnu, 0),
+  NEONMAP1(vcvtnq_u64_v, arm_neon_vcvtnu, 0),
+  NEONMAP1(vcvtp_s32_v, arm_neon_vcvtps, 0),
+  NEONMAP1(vcvtp_s64_v, arm_neon_vcvtps, 0),
+  NEONMAP1(vcvtp_u32_v, arm_neon_vcvtpu, 0),
+  NEONMAP1(vcvtp_u64_v, arm_neon_vcvtpu, 0),
+  NEONMAP1(vcvtpq_s32_v, arm_neon_vcvtps, 0),
+  NEONMAP1(vcvtpq_s64_v, arm_neon_vcvtps, 0),
+  NEONMAP1(vcvtpq_u32_v, arm_neon_vcvtpu, 0),
+  NEONMAP1(vcvtpq_u64_v, arm_neon_vcvtpu, 0),
+  NEONMAP0(vcvtq_f32_v),
+  NEONMAP2(vcvtq_n_f32_v, arm_neon_vcvtfxu2fp, arm_neon_vcvtfxs2fp, 0),
+  NEONMAP1(vcvtq_n_s32_v, arm_neon_vcvtfp2fxs, 0),
+  NEONMAP1(vcvtq_n_s64_v, arm_neon_vcvtfp2fxs, 0),
+  NEONMAP1(vcvtq_n_u32_v, arm_neon_vcvtfp2fxu, 0),
+  NEONMAP1(vcvtq_n_u64_v, arm_neon_vcvtfp2fxu, 0),
+  NEONMAP0(vcvtq_s32_v),
+  NEONMAP0(vcvtq_s64_v),
+  NEONMAP0(vcvtq_u32_v),
+  NEONMAP0(vcvtq_u64_v),
+  NEONMAP0(vext_v),
+  NEONMAP0(vextq_v),
+  NEONMAP0(vfma_v),
+  NEONMAP0(vfmaq_v),
+  NEONMAP2(vhadd_v, arm_neon_vhaddu, arm_neon_vhadds, Add1ArgType | UnsignedAlts),
+  NEONMAP2(vhaddq_v, arm_neon_vhaddu, arm_neon_vhadds, Add1ArgType | UnsignedAlts),
+  NEONMAP2(vhsub_v, arm_neon_vhsubu, arm_neon_vhsubs, Add1ArgType | UnsignedAlts),
+  NEONMAP2(vhsubq_v, arm_neon_vhsubu, arm_neon_vhsubs, Add1ArgType | UnsignedAlts),
+  NEONMAP0(vld1_dup_v),
+  NEONMAP1(vld1_v, arm_neon_vld1, 0),
+  NEONMAP0(vld1q_dup_v),
+  NEONMAP1(vld1q_v, arm_neon_vld1, 0),
+  NEONMAP1(vld2_lane_v, arm_neon_vld2lane, 0),
+  NEONMAP1(vld2_v, arm_neon_vld2, 0),
+  NEONMAP1(vld2q_lane_v, arm_neon_vld2lane, 0),
+  NEONMAP1(vld2q_v, arm_neon_vld2, 0),
+  NEONMAP1(vld3_lane_v, arm_neon_vld3lane, 0),
+  NEONMAP1(vld3_v, arm_neon_vld3, 0),
+  NEONMAP1(vld3q_lane_v, arm_neon_vld3lane, 0),
+  NEONMAP1(vld3q_v, arm_neon_vld3, 0),
+  NEONMAP1(vld4_lane_v, arm_neon_vld4lane, 0),
+  NEONMAP1(vld4_v, arm_neon_vld4, 0),
+  NEONMAP1(vld4q_lane_v, arm_neon_vld4lane, 0),
+  NEONMAP1(vld4q_v, arm_neon_vld4, 0),
+  NEONMAP2(vmax_v, arm_neon_vmaxu, arm_neon_vmaxs, Add1ArgType | UnsignedAlts),
+  NEONMAP2(vmaxq_v, arm_neon_vmaxu, arm_neon_vmaxs, Add1ArgType | UnsignedAlts),
+  NEONMAP2(vmin_v, arm_neon_vminu, arm_neon_vmins, Add1ArgType | UnsignedAlts),
+  NEONMAP2(vminq_v, arm_neon_vminu, arm_neon_vmins, Add1ArgType | UnsignedAlts),
+  NEONMAP0(vmovl_v),
+  NEONMAP0(vmovn_v),
+  NEONMAP1(vmul_v, arm_neon_vmulp, Add1ArgType),
+  NEONMAP0(vmull_v),
+  NEONMAP1(vmulq_v, arm_neon_vmulp, Add1ArgType),
+  NEONMAP2(vpadal_v, arm_neon_vpadalu, arm_neon_vpadals, UnsignedAlts),
+  NEONMAP2(vpadalq_v, arm_neon_vpadalu, arm_neon_vpadals, UnsignedAlts),
+  NEONMAP1(vpadd_v, arm_neon_vpadd, Add1ArgType),
+  NEONMAP2(vpaddl_v, arm_neon_vpaddlu, arm_neon_vpaddls, UnsignedAlts),
+  NEONMAP2(vpaddlq_v, arm_neon_vpaddlu, arm_neon_vpaddls, UnsignedAlts),
+  NEONMAP1(vpaddq_v, arm_neon_vpadd, Add1ArgType),
+  NEONMAP2(vpmax_v, arm_neon_vpmaxu, arm_neon_vpmaxs, Add1ArgType | UnsignedAlts),
+  NEONMAP2(vpmin_v, arm_neon_vpminu, arm_neon_vpmins, Add1ArgType | UnsignedAlts),
+  NEONMAP1(vqabs_v, arm_neon_vqabs, Add1ArgType),
+  NEONMAP1(vqabsq_v, arm_neon_vqabs, Add1ArgType),
+  NEONMAP2(vqadd_v, arm_neon_vqaddu, arm_neon_vqadds, Add1ArgType | UnsignedAlts),
+  NEONMAP2(vqaddq_v, arm_neon_vqaddu, arm_neon_vqadds, Add1ArgType | UnsignedAlts),
+  NEONMAP2(vqdmlal_v, arm_neon_vqdmull, arm_neon_vqadds, 0),
+  NEONMAP2(vqdmlsl_v, arm_neon_vqdmull, arm_neon_vqsubs, 0),
+  NEONMAP1(vqdmulh_v, arm_neon_vqdmulh, Add1ArgType),
+  NEONMAP1(vqdmulhq_v, arm_neon_vqdmulh, Add1ArgType),
+  NEONMAP1(vqdmull_v, arm_neon_vqdmull, Add1ArgType),
+  NEONMAP2(vqmovn_v, arm_neon_vqmovnu, arm_neon_vqmovns, Add1ArgType | UnsignedAlts),
+  NEONMAP1(vqmovun_v, arm_neon_vqmovnsu, Add1ArgType),
+  NEONMAP1(vqneg_v, arm_neon_vqneg, Add1ArgType),
+  NEONMAP1(vqnegq_v, arm_neon_vqneg, Add1ArgType),
+  NEONMAP1(vqrdmulh_v, arm_neon_vqrdmulh, Add1ArgType),
+  NEONMAP1(vqrdmulhq_v, arm_neon_vqrdmulh, Add1ArgType),
+  NEONMAP2(vqrshl_v, arm_neon_vqrshiftu, arm_neon_vqrshifts, Add1ArgType | UnsignedAlts),
+  NEONMAP2(vqrshlq_v, arm_neon_vqrshiftu, arm_neon_vqrshifts, Add1ArgType | UnsignedAlts),
+  NEONMAP2(vqshl_n_v, arm_neon_vqshiftu, arm_neon_vqshifts, UnsignedAlts),
+  NEONMAP2(vqshl_v, arm_neon_vqshiftu, arm_neon_vqshifts, Add1ArgType | UnsignedAlts),
+  NEONMAP2(vqshlq_n_v, arm_neon_vqshiftu, arm_neon_vqshifts, UnsignedAlts),
+  NEONMAP2(vqshlq_v, arm_neon_vqshiftu, arm_neon_vqshifts, Add1ArgType | UnsignedAlts),
+  NEONMAP2(vqsub_v, arm_neon_vqsubu, arm_neon_vqsubs, Add1ArgType | UnsignedAlts),
+  NEONMAP2(vqsubq_v, arm_neon_vqsubu, arm_neon_vqsubs, Add1ArgType | UnsignedAlts),
+  NEONMAP1(vraddhn_v, arm_neon_vraddhn, Add1ArgType),
+  NEONMAP2(vrecpe_v, arm_neon_vrecpe, arm_neon_vrecpe, 0),
+  NEONMAP2(vrecpeq_v, arm_neon_vrecpe, arm_neon_vrecpe, 0),
+  NEONMAP1(vrecps_v, arm_neon_vrecps, Add1ArgType),
+  NEONMAP1(vrecpsq_v, arm_neon_vrecps, Add1ArgType),
+  NEONMAP2(vrhadd_v, arm_neon_vrhaddu, arm_neon_vrhadds, Add1ArgType | UnsignedAlts),
+  NEONMAP2(vrhaddq_v, arm_neon_vrhaddu, arm_neon_vrhadds, Add1ArgType | UnsignedAlts),
+  NEONMAP2(vrshl_v, arm_neon_vrshiftu, arm_neon_vrshifts, Add1ArgType | UnsignedAlts),
+  NEONMAP2(vrshlq_v, arm_neon_vrshiftu, arm_neon_vrshifts, Add1ArgType | UnsignedAlts),
+  NEONMAP2(vrsqrte_v, arm_neon_vrsqrte, arm_neon_vrsqrte, 0),
+  NEONMAP2(vrsqrteq_v, arm_neon_vrsqrte, arm_neon_vrsqrte, 0),
+  NEONMAP1(vrsqrts_v, arm_neon_vrsqrts, Add1ArgType),
+  NEONMAP1(vrsqrtsq_v, arm_neon_vrsqrts, Add1ArgType),
+  NEONMAP1(vrsubhn_v, arm_neon_vrsubhn, Add1ArgType),
+  NEONMAP1(vsha1su0q_v, arm_neon_sha1su0, 0),
+  NEONMAP1(vsha1su1q_v, arm_neon_sha1su1, 0),
+  NEONMAP1(vsha256h2q_v, arm_neon_sha256h2, 0),
+  NEONMAP1(vsha256hq_v, arm_neon_sha256h, 0),
+  NEONMAP1(vsha256su0q_v, arm_neon_sha256su0, 0),
+  NEONMAP1(vsha256su1q_v, arm_neon_sha256su1, 0),
+  NEONMAP0(vshl_n_v),
+  NEONMAP2(vshl_v, arm_neon_vshiftu, arm_neon_vshifts, Add1ArgType | UnsignedAlts),
+  NEONMAP0(vshll_n_v),
+  NEONMAP0(vshlq_n_v),
+  NEONMAP2(vshlq_v, arm_neon_vshiftu, arm_neon_vshifts, Add1ArgType | UnsignedAlts),
+  NEONMAP0(vshr_n_v),
+  NEONMAP0(vshrn_n_v),
+  NEONMAP0(vshrq_n_v),
+  NEONMAP1(vst1_v, arm_neon_vst1, 0),
+  NEONMAP1(vst1q_v, arm_neon_vst1, 0),
+  NEONMAP1(vst2_lane_v, arm_neon_vst2lane, 0),
+  NEONMAP1(vst2_v, arm_neon_vst2, 0),
+  NEONMAP1(vst2q_lane_v, arm_neon_vst2lane, 0),
+  NEONMAP1(vst2q_v, arm_neon_vst2, 0),
+  NEONMAP1(vst3_lane_v, arm_neon_vst3lane, 0),
+  NEONMAP1(vst3_v, arm_neon_vst3, 0),
+  NEONMAP1(vst3q_lane_v, arm_neon_vst3lane, 0),
+  NEONMAP1(vst3q_v, arm_neon_vst3, 0),
+  NEONMAP1(vst4_lane_v, arm_neon_vst4lane, 0),
+  NEONMAP1(vst4_v, arm_neon_vst4, 0),
+  NEONMAP1(vst4q_lane_v, arm_neon_vst4lane, 0),
+  NEONMAP1(vst4q_v, arm_neon_vst4, 0),
+  NEONMAP0(vsubhn_v),
+  NEONMAP0(vtrn_v),
+  NEONMAP0(vtrnq_v),
+  NEONMAP0(vtst_v),
+  NEONMAP0(vtstq_v),
+  NEONMAP0(vuzp_v),
+  NEONMAP0(vuzpq_v),
+  NEONMAP0(vzip_v),
+  NEONMAP0(vzipq_v)
+};
+
+static NeonIntrinsicInfo AArch64SIMDIntrinsicMap[] = {
+  NEONMAP1(vabs_v, aarch64_neon_abs, 0),
+  NEONMAP1(vabsq_v, aarch64_neon_abs, 0),
+  NEONMAP0(vaddhn_v),
+  NEONMAP1(vaesdq_v, aarch64_crypto_aesd, 0),
+  NEONMAP1(vaeseq_v, aarch64_crypto_aese, 0),
+  NEONMAP1(vaesimcq_v, aarch64_crypto_aesimc, 0),
+  NEONMAP1(vaesmcq_v, aarch64_crypto_aesmc, 0),
+  NEONMAP1(vcage_v, aarch64_neon_facge, 0),
+  NEONMAP1(vcageq_v, aarch64_neon_facge, 0),
+  NEONMAP1(vcagt_v, aarch64_neon_facgt, 0),
+  NEONMAP1(vcagtq_v, aarch64_neon_facgt, 0),
+  NEONMAP1(vcale_v, aarch64_neon_facge, 0),
+  NEONMAP1(vcaleq_v, aarch64_neon_facge, 0),
+  NEONMAP1(vcalt_v, aarch64_neon_facgt, 0),
+  NEONMAP1(vcaltq_v, aarch64_neon_facgt, 0),
+  NEONMAP1(vcls_v, aarch64_neon_cls, Add1ArgType),
+  NEONMAP1(vclsq_v, aarch64_neon_cls, Add1ArgType),
+  NEONMAP1(vclz_v, ctlz, Add1ArgType),
+  NEONMAP1(vclzq_v, ctlz, Add1ArgType),
+  NEONMAP1(vcnt_v, ctpop, Add1ArgType),
+  NEONMAP1(vcntq_v, ctpop, Add1ArgType),
+  NEONMAP1(vcvt_f16_v, aarch64_neon_vcvtfp2hf, 0),
+  NEONMAP1(vcvt_f32_f16, aarch64_neon_vcvthf2fp, 0),
+  NEONMAP0(vcvt_f32_v),
+  NEONMAP2(vcvt_n_f32_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0),
+  NEONMAP2(vcvt_n_f64_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0),
+  NEONMAP1(vcvt_n_s32_v, aarch64_neon_vcvtfp2fxs, 0),
+  NEONMAP1(vcvt_n_s64_v, aarch64_neon_vcvtfp2fxs, 0),
+  NEONMAP1(vcvt_n_u32_v, aarch64_neon_vcvtfp2fxu, 0),
+  NEONMAP1(vcvt_n_u64_v, aarch64_neon_vcvtfp2fxu, 0),
+  NEONMAP0(vcvtq_f32_v),
+  NEONMAP2(vcvtq_n_f32_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0),
+  NEONMAP2(vcvtq_n_f64_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0),
+  NEONMAP1(vcvtq_n_s32_v, aarch64_neon_vcvtfp2fxs, 0),
+  NEONMAP1(vcvtq_n_s64_v, aarch64_neon_vcvtfp2fxs, 0),
+  NEONMAP1(vcvtq_n_u32_v, aarch64_neon_vcvtfp2fxu, 0),
+  NEONMAP1(vcvtq_n_u64_v, aarch64_neon_vcvtfp2fxu, 0),
+  NEONMAP1(vcvtx_f32_v, aarch64_neon_fcvtxn, AddRetType | Add1ArgType),
+  NEONMAP0(vext_v),
+  NEONMAP0(vextq_v),
+  NEONMAP0(vfma_v),
+  NEONMAP0(vfmaq_v),
+  NEONMAP2(vhadd_v, aarch64_neon_uhadd, aarch64_neon_shadd, Add1ArgType | UnsignedAlts),
+  NEONMAP2(vhaddq_v, aarch64_neon_uhadd, aarch64_neon_shadd, Add1ArgType | UnsignedAlts),
+  NEONMAP2(vhsub_v, aarch64_neon_uhsub, aarch64_neon_shsub, Add1ArgType | UnsignedAlts),
+  NEONMAP2(vhsubq_v, aarch64_neon_uhsub, aarch64_neon_shsub, Add1ArgType | UnsignedAlts),
+  NEONMAP0(vmovl_v),
+  NEONMAP0(vmovn_v),
+  NEONMAP1(vmul_v, aarch64_neon_pmul, Add1ArgType),
+  NEONMAP1(vmulq_v, aarch64_neon_pmul, Add1ArgType),
+  NEONMAP1(vpadd_v, aarch64_neon_addp, Add1ArgType),
+  NEONMAP2(vpaddl_v, aarch64_neon_uaddlp, aarch64_neon_saddlp, UnsignedAlts),
+  NEONMAP2(vpaddlq_v, aarch64_neon_uaddlp, aarch64_neon_saddlp, UnsignedAlts),
+  NEONMAP1(vpaddq_v, aarch64_neon_addp, Add1ArgType),
+  NEONMAP1(vqabs_v, aarch64_neon_sqabs, Add1ArgType),
+  NEONMAP1(vqabsq_v, aarch64_neon_sqabs, Add1ArgType),
+  NEONMAP2(vqadd_v, aarch64_neon_uqadd, aarch64_neon_sqadd, Add1ArgType | UnsignedAlts),
+  NEONMAP2(vqaddq_v, aarch64_neon_uqadd, aarch64_neon_sqadd, Add1ArgType | UnsignedAlts),
+  NEONMAP2(vqdmlal_v, aarch64_neon_sqdmull, aarch64_neon_sqadd, 0),
+  NEONMAP2(vqdmlsl_v, aarch64_neon_sqdmull, aarch64_neon_sqsub, 0),
+  NEONMAP1(vqdmulh_v, aarch64_neon_sqdmulh, Add1ArgType),
+  NEONMAP1(vqdmulhq_v, aarch64_neon_sqdmulh, Add1ArgType),
+  NEONMAP1(vqdmull_v, aarch64_neon_sqdmull, Add1ArgType),
+  NEONMAP2(vqmovn_v, aarch64_neon_uqxtn, aarch64_neon_sqxtn, Add1ArgType | UnsignedAlts),
+  NEONMAP1(vqmovun_v, aarch64_neon_sqxtun, Add1ArgType),
+  NEONMAP1(vqneg_v, aarch64_neon_sqneg, Add1ArgType),
+  NEONMAP1(vqnegq_v, aarch64_neon_sqneg, Add1ArgType),
+  NEONMAP1(vqrdmulh_v, aarch64_neon_sqrdmulh, Add1ArgType),
+  NEONMAP1(vqrdmulhq_v, aarch64_neon_sqrdmulh, Add1ArgType),
+  NEONMAP2(vqrshl_v, aarch64_neon_uqrshl, aarch64_neon_sqrshl, Add1ArgType | UnsignedAlts),
+  NEONMAP2(vqrshlq_v, aarch64_neon_uqrshl, aarch64_neon_sqrshl, Add1ArgType | UnsignedAlts),
+  NEONMAP2(vqshl_n_v, aarch64_neon_uqshl, aarch64_neon_sqshl, UnsignedAlts),
+  NEONMAP2(vqshl_v, aarch64_neon_uqshl, aarch64_neon_sqshl, Add1ArgType | UnsignedAlts),
+  NEONMAP2(vqshlq_n_v, aarch64_neon_uqshl, aarch64_neon_sqshl,UnsignedAlts),
+  NEONMAP2(vqshlq_v, aarch64_neon_uqshl, aarch64_neon_sqshl, Add1ArgType | UnsignedAlts),
+  NEONMAP2(vqsub_v, aarch64_neon_uqsub, aarch64_neon_sqsub, Add1ArgType | UnsignedAlts),
+  NEONMAP2(vqsubq_v, aarch64_neon_uqsub, aarch64_neon_sqsub, Add1ArgType | UnsignedAlts),
+  NEONMAP1(vraddhn_v, aarch64_neon_raddhn, Add1ArgType),
+  NEONMAP2(vrecpe_v, aarch64_neon_frecpe, aarch64_neon_urecpe, 0),
+  NEONMAP2(vrecpeq_v, aarch64_neon_frecpe, aarch64_neon_urecpe, 0),
+  NEONMAP1(vrecps_v, aarch64_neon_frecps, Add1ArgType),
+  NEONMAP1(vrecpsq_v, aarch64_neon_frecps, Add1ArgType),
+  NEONMAP2(vrhadd_v, aarch64_neon_urhadd, aarch64_neon_srhadd, Add1ArgType | UnsignedAlts),
+  NEONMAP2(vrhaddq_v, aarch64_neon_urhadd, aarch64_neon_srhadd, Add1ArgType | UnsignedAlts),
+  NEONMAP2(vrshl_v, aarch64_neon_urshl, aarch64_neon_srshl, Add1ArgType | UnsignedAlts),
+  NEONMAP2(vrshlq_v, aarch64_neon_urshl, aarch64_neon_srshl, Add1ArgType | UnsignedAlts),
+  NEONMAP2(vrsqrte_v, aarch64_neon_frsqrte, aarch64_neon_ursqrte, 0),
+  NEONMAP2(vrsqrteq_v, aarch64_neon_frsqrte, aarch64_neon_ursqrte, 0),
+  NEONMAP1(vrsqrts_v, aarch64_neon_frsqrts, Add1ArgType),
+  NEONMAP1(vrsqrtsq_v, aarch64_neon_frsqrts, Add1ArgType),
+  NEONMAP1(vrsubhn_v, aarch64_neon_rsubhn, Add1ArgType),
+  NEONMAP1(vsha1su0q_v, aarch64_crypto_sha1su0, 0),
+  NEONMAP1(vsha1su1q_v, aarch64_crypto_sha1su1, 0),
+  NEONMAP1(vsha256h2q_v, aarch64_crypto_sha256h2, 0),
+  NEONMAP1(vsha256hq_v, aarch64_crypto_sha256h, 0),
+  NEONMAP1(vsha256su0q_v, aarch64_crypto_sha256su0, 0),
+  NEONMAP1(vsha256su1q_v, aarch64_crypto_sha256su1, 0),
+  NEONMAP0(vshl_n_v),
+  NEONMAP2(vshl_v, aarch64_neon_ushl, aarch64_neon_sshl, Add1ArgType | UnsignedAlts),
+  NEONMAP0(vshll_n_v),
+  NEONMAP0(vshlq_n_v),
+  NEONMAP2(vshlq_v, aarch64_neon_ushl, aarch64_neon_sshl, Add1ArgType | UnsignedAlts),
+  NEONMAP0(vshr_n_v),
+  NEONMAP0(vshrn_n_v),
+  NEONMAP0(vshrq_n_v),
+  NEONMAP0(vsubhn_v),
+  NEONMAP0(vtst_v),
+  NEONMAP0(vtstq_v),
+};
+
+static NeonIntrinsicInfo AArch64SISDIntrinsicMap[] = {
+  NEONMAP1(vabdd_f64, aarch64_sisd_fabd, Add1ArgType),
+  NEONMAP1(vabds_f32, aarch64_sisd_fabd, Add1ArgType),
+  NEONMAP1(vabsd_s64, aarch64_neon_abs, Add1ArgType),
+  NEONMAP1(vaddlv_s32, aarch64_neon_saddlv, AddRetType | Add1ArgType),
+  NEONMAP1(vaddlv_u32, aarch64_neon_uaddlv, AddRetType | Add1ArgType),
+  NEONMAP1(vaddlvq_s32, aarch64_neon_saddlv, AddRetType | Add1ArgType),
+  NEONMAP1(vaddlvq_u32, aarch64_neon_uaddlv, AddRetType | Add1ArgType),
+  NEONMAP1(vaddv_f32, aarch64_neon_faddv, AddRetType | Add1ArgType),
+  NEONMAP1(vaddv_s32, aarch64_neon_saddv, AddRetType | Add1ArgType),
+  NEONMAP1(vaddv_u32, aarch64_neon_uaddv, AddRetType | Add1ArgType),
+  NEONMAP1(vaddvq_f32, aarch64_neon_faddv, AddRetType | Add1ArgType),
+  NEONMAP1(vaddvq_f64, aarch64_neon_faddv, AddRetType | Add1ArgType),
+  NEONMAP1(vaddvq_s32, aarch64_neon_saddv, AddRetType | Add1ArgType),
+  NEONMAP1(vaddvq_s64, aarch64_neon_saddv, AddRetType | Add1ArgType),
+  NEONMAP1(vaddvq_u32, aarch64_neon_uaddv, AddRetType | Add1ArgType),
+  NEONMAP1(vaddvq_u64, aarch64_neon_uaddv, AddRetType | Add1ArgType),
+  NEONMAP1(vcaged_f64, aarch64_neon_facge, AddRetType | Add1ArgType),
+  NEONMAP1(vcages_f32, aarch64_neon_facge, AddRetType | Add1ArgType),
+  NEONMAP1(vcagtd_f64, aarch64_neon_facgt, AddRetType | Add1ArgType),
+  NEONMAP1(vcagts_f32, aarch64_neon_facgt, AddRetType | Add1ArgType),
+  NEONMAP1(vcaled_f64, aarch64_neon_facge, AddRetType | Add1ArgType),
+  NEONMAP1(vcales_f32, aarch64_neon_facge, AddRetType | Add1ArgType),
+  NEONMAP1(vcaltd_f64, aarch64_neon_facgt, AddRetType | Add1ArgType),
+  NEONMAP1(vcalts_f32, aarch64_neon_facgt, AddRetType | Add1ArgType),
+  NEONMAP1(vcvtad_s64_f64, aarch64_neon_fcvtas, AddRetType | Add1ArgType),
+  NEONMAP1(vcvtad_u64_f64, aarch64_neon_fcvtau, AddRetType | Add1ArgType),
+  NEONMAP1(vcvtas_s32_f32, aarch64_neon_fcvtas, AddRetType | Add1ArgType),
+  NEONMAP1(vcvtas_u32_f32, aarch64_neon_fcvtau, AddRetType | Add1ArgType),
+  NEONMAP1(vcvtd_n_f64_s64, aarch64_neon_vcvtfxs2fp, AddRetType | Add1ArgType),
+  NEONMAP1(vcvtd_n_f64_u64, aarch64_neon_vcvtfxu2fp, AddRetType | Add1ArgType),
+  NEONMAP1(vcvtd_n_s64_f64, aarch64_neon_vcvtfp2fxs, AddRetType | Add1ArgType),
+  NEONMAP1(vcvtd_n_u64_f64, aarch64_neon_vcvtfp2fxu, AddRetType | Add1ArgType),
+  NEONMAP1(vcvtmd_s64_f64, aarch64_neon_fcvtms, AddRetType | Add1ArgType),
+  NEONMAP1(vcvtmd_u64_f64, aarch64_neon_fcvtmu, AddRetType | Add1ArgType),
+  NEONMAP1(vcvtms_s32_f32, aarch64_neon_fcvtms, AddRetType | Add1ArgType),
+  NEONMAP1(vcvtms_u32_f32, aarch64_neon_fcvtmu, AddRetType | Add1ArgType),
+  NEONMAP1(vcvtnd_s64_f64, aarch64_neon_fcvtns, AddRetType | Add1ArgType),
+  NEONMAP1(vcvtnd_u64_f64, aarch64_neon_fcvtnu, AddRetType | Add1ArgType),
+  NEONMAP1(vcvtns_s32_f32, aarch64_neon_fcvtns, AddRetType | Add1ArgType),
+  NEONMAP1(vcvtns_u32_f32, aarch64_neon_fcvtnu, AddRetType | Add1ArgType),
+  NEONMAP1(vcvtpd_s64_f64, aarch64_neon_fcvtps, AddRetType | Add1ArgType),
+  NEONMAP1(vcvtpd_u64_f64, aarch64_neon_fcvtpu, AddRetType | Add1ArgType),
+  NEONMAP1(vcvtps_s32_f32, aarch64_neon_fcvtps, AddRetType | Add1ArgType),
+  NEONMAP1(vcvtps_u32_f32, aarch64_neon_fcvtpu, AddRetType | Add1ArgType),
+  NEONMAP1(vcvts_n_f32_s32, aarch64_neon_vcvtfxs2fp, AddRetType | Add1ArgType),
+  NEONMAP1(vcvts_n_f32_u32, aarch64_neon_vcvtfxu2fp, AddRetType | Add1ArgType),
+  NEONMAP1(vcvts_n_s32_f32, aarch64_neon_vcvtfp2fxs, AddRetType | Add1ArgType),
+  NEONMAP1(vcvts_n_u32_f32, aarch64_neon_vcvtfp2fxu, AddRetType | Add1ArgType),
+  NEONMAP1(vcvtxd_f32_f64, aarch64_sisd_fcvtxn, 0),
+  NEONMAP1(vmaxnmv_f32, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType),
+  NEONMAP1(vmaxnmvq_f32, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType),
+  NEONMAP1(vmaxnmvq_f64, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType),
+  NEONMAP1(vmaxv_f32, aarch64_neon_fmaxv, AddRetType | Add1ArgType),
+  NEONMAP1(vmaxv_s32, aarch64_neon_smaxv, AddRetType | Add1ArgType),
+  NEONMAP1(vmaxv_u32, aarch64_neon_umaxv, AddRetType | Add1ArgType),
+  NEONMAP1(vmaxvq_f32, aarch64_neon_fmaxv, AddRetType | Add1ArgType),
+  NEONMAP1(vmaxvq_f64, aarch64_neon_fmaxv, AddRetType | Add1ArgType),
+  NEONMAP1(vmaxvq_s32, aarch64_neon_smaxv, AddRetType | Add1ArgType),
+  NEONMAP1(vmaxvq_u32, aarch64_neon_umaxv, AddRetType | Add1ArgType),
+  NEONMAP1(vminnmv_f32, aarch64_neon_fminnmv, AddRetType | Add1ArgType),
+  NEONMAP1(vminnmvq_f32, aarch64_neon_fminnmv, AddRetType | Add1ArgType),
+  NEONMAP1(vminnmvq_f64, aarch64_neon_fminnmv, AddRetType | Add1ArgType),
+  NEONMAP1(vminv_f32, aarch64_neon_fminv, AddRetType | Add1ArgType),
+  NEONMAP1(vminv_s32, aarch64_neon_sminv, AddRetType | Add1ArgType),
+  NEONMAP1(vminv_u32, aarch64_neon_uminv, AddRetType | Add1ArgType),
+  NEONMAP1(vminvq_f32, aarch64_neon_fminv, AddRetType | Add1ArgType),
+  NEONMAP1(vminvq_f64, aarch64_neon_fminv, AddRetType | Add1ArgType),
+  NEONMAP1(vminvq_s32, aarch64_neon_sminv, AddRetType | Add1ArgType),
+  NEONMAP1(vminvq_u32, aarch64_neon_uminv, AddRetType | Add1ArgType),
+  NEONMAP1(vmull_p64, aarch64_neon_pmull64, 0),
+  NEONMAP1(vmulxd_f64, aarch64_neon_fmulx, Add1ArgType),
+  NEONMAP1(vmulxs_f32, aarch64_neon_fmulx, Add1ArgType),
+  NEONMAP1(vpaddd_s64, aarch64_neon_uaddv, AddRetType | Add1ArgType),
+  NEONMAP1(vpaddd_u64, aarch64_neon_uaddv, AddRetType | Add1ArgType),
+  NEONMAP1(vpmaxnmqd_f64, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType),
+  NEONMAP1(vpmaxnms_f32, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType),
+  NEONMAP1(vpmaxqd_f64, aarch64_neon_fmaxv, AddRetType | Add1ArgType),
+  NEONMAP1(vpmaxs_f32, aarch64_neon_fmaxv, AddRetType | Add1ArgType),
+  NEONMAP1(vpminnmqd_f64, aarch64_neon_fminnmv, AddRetType | Add1ArgType),
+  NEONMAP1(vpminnms_f32, aarch64_neon_fminnmv, AddRetType | Add1ArgType),
+  NEONMAP1(vpminqd_f64, aarch64_neon_fminv, AddRetType | Add1ArgType),
+  NEONMAP1(vpmins_f32, aarch64_neon_fminv, AddRetType | Add1ArgType),
+  NEONMAP1(vqabsb_s8, aarch64_neon_sqabs, Vectorize1ArgType | Use64BitVectors),
+  NEONMAP1(vqabsd_s64, aarch64_neon_sqabs, Add1ArgType),
+  NEONMAP1(vqabsh_s16, aarch64_neon_sqabs, Vectorize1ArgType | Use64BitVectors),
+  NEONMAP1(vqabss_s32, aarch64_neon_sqabs, Add1ArgType),
+  NEONMAP1(vqaddb_s8, aarch64_neon_sqadd, Vectorize1ArgType | Use64BitVectors),
+  NEONMAP1(vqaddb_u8, aarch64_neon_uqadd, Vectorize1ArgType | Use64BitVectors),
+  NEONMAP1(vqaddd_s64, aarch64_neon_sqadd, Add1ArgType),
+  NEONMAP1(vqaddd_u64, aarch64_neon_uqadd, Add1ArgType),
+  NEONMAP1(vqaddh_s16, aarch64_neon_sqadd, Vectorize1ArgType | Use64BitVectors),
+  NEONMAP1(vqaddh_u16, aarch64_neon_uqadd, Vectorize1ArgType | Use64BitVectors),
+  NEONMAP1(vqadds_s32, aarch64_neon_sqadd, Add1ArgType),
+  NEONMAP1(vqadds_u32, aarch64_neon_uqadd, Add1ArgType),
+  NEONMAP1(vqdmulhh_s16, aarch64_neon_sqdmulh, Vectorize1ArgType | Use64BitVectors),
+  NEONMAP1(vqdmulhs_s32, aarch64_neon_sqdmulh, Add1ArgType),
+  NEONMAP1(vqdmullh_s16, aarch64_neon_sqdmull, VectorRet | Use128BitVectors),
+  NEONMAP1(vqdmulls_s32, aarch64_neon_sqdmulls_scalar, 0),
+  NEONMAP1(vqmovnd_s64, aarch64_neon_scalar_sqxtn, AddRetType | Add1ArgType),
+  NEONMAP1(vqmovnd_u64, aarch64_neon_scalar_uqxtn, AddRetType | Add1ArgType),
+  NEONMAP1(vqmovnh_s16, aarch64_neon_sqxtn, VectorRet | Use64BitVectors),
+  NEONMAP1(vqmovnh_u16, aarch64_neon_uqxtn, VectorRet | Use64BitVectors),
+  NEONMAP1(vqmovns_s32, aarch64_neon_sqxtn, VectorRet | Use64BitVectors),
+  NEONMAP1(vqmovns_u32, aarch64_neon_uqxtn, VectorRet | Use64BitVectors),
+  NEONMAP1(vqmovund_s64, aarch64_neon_scalar_sqxtun, AddRetType | Add1ArgType),
+  NEONMAP1(vqmovunh_s16, aarch64_neon_sqxtun, VectorRet | Use64BitVectors),
+  NEONMAP1(vqmovuns_s32, aarch64_neon_sqxtun, VectorRet | Use64BitVectors),
+  NEONMAP1(vqnegb_s8, aarch64_neon_sqneg, Vectorize1ArgType | Use64BitVectors),
+  NEONMAP1(vqnegd_s64, aarch64_neon_sqneg, Add1ArgType),
+  NEONMAP1(vqnegh_s16, aarch64_neon_sqneg, Vectorize1ArgType | Use64BitVectors),
+  NEONMAP1(vqnegs_s32, aarch64_neon_sqneg, Add1ArgType),
+  NEONMAP1(vqrdmulhh_s16, aarch64_neon_sqrdmulh, Vectorize1ArgType | Use64BitVectors),
+  NEONMAP1(vqrdmulhs_s32, aarch64_neon_sqrdmulh, Add1ArgType),
+  NEONMAP1(vqrshlb_s8, aarch64_neon_sqrshl, Vectorize1ArgType | Use64BitVectors),
+  NEONMAP1(vqrshlb_u8, aarch64_neon_uqrshl, Vectorize1ArgType | Use64BitVectors),
+  NEONMAP1(vqrshld_s64, aarch64_neon_sqrshl, Add1ArgType),
+  NEONMAP1(vqrshld_u64, aarch64_neon_uqrshl, Add1ArgType),
+  NEONMAP1(vqrshlh_s16, aarch64_neon_sqrshl, Vectorize1ArgType | Use64BitVectors),
+  NEONMAP1(vqrshlh_u16, aarch64_neon_uqrshl, Vectorize1ArgType | Use64BitVectors),
+  NEONMAP1(vqrshls_s32, aarch64_neon_sqrshl, Add1ArgType),
+  NEONMAP1(vqrshls_u32, aarch64_neon_uqrshl, Add1ArgType),
+  NEONMAP1(vqrshrnd_n_s64, aarch64_neon_sqrshrn, AddRetType),
+  NEONMAP1(vqrshrnd_n_u64, aarch64_neon_uqrshrn, AddRetType),
+  NEONMAP1(vqrshrnh_n_s16, aarch64_neon_sqrshrn, VectorRet | Use64BitVectors),
+  NEONMAP1(vqrshrnh_n_u16, aarch64_neon_uqrshrn, VectorRet | Use64BitVectors),
+  NEONMAP1(vqrshrns_n_s32, aarch64_neon_sqrshrn, VectorRet | Use64BitVectors),
+  NEONMAP1(vqrshrns_n_u32, aarch64_neon_uqrshrn, VectorRet | Use64BitVectors),
+  NEONMAP1(vqrshrund_n_s64, aarch64_neon_sqrshrun, AddRetType),
+  NEONMAP1(vqrshrunh_n_s16, aarch64_neon_sqrshrun, VectorRet | Use64BitVectors),
+  NEONMAP1(vqrshruns_n_s32, aarch64_neon_sqrshrun, VectorRet | Use64BitVectors),
+  NEONMAP1(vqshlb_n_s8, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors),
+  NEONMAP1(vqshlb_n_u8, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors),
+  NEONMAP1(vqshlb_s8, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors),
+  NEONMAP1(vqshlb_u8, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors),
+  NEONMAP1(vqshld_s64, aarch64_neon_sqshl, Add1ArgType),
+  NEONMAP1(vqshld_u64, aarch64_neon_uqshl, Add1ArgType),
+  NEONMAP1(vqshlh_n_s16, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors),
+  NEONMAP1(vqshlh_n_u16, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors),
+  NEONMAP1(vqshlh_s16, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors),
+  NEONMAP1(vqshlh_u16, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors),
+  NEONMAP1(vqshls_n_s32, aarch64_neon_sqshl, Add1ArgType),
+  NEONMAP1(vqshls_n_u32, aarch64_neon_uqshl, Add1ArgType),
+  NEONMAP1(vqshls_s32, aarch64_neon_sqshl, Add1ArgType),
+  NEONMAP1(vqshls_u32, aarch64_neon_uqshl, Add1ArgType),
+  NEONMAP1(vqshlub_n_s8, aarch64_neon_sqshlu, Vectorize1ArgType | Use64BitVectors),
+  NEONMAP1(vqshluh_n_s16, aarch64_neon_sqshlu, Vectorize1ArgType | Use64BitVectors),
+  NEONMAP1(vqshlus_n_s32, aarch64_neon_sqshlu, Add1ArgType),
+  NEONMAP1(vqshrnd_n_s64, aarch64_neon_sqshrn, AddRetType),
+  NEONMAP1(vqshrnd_n_u64, aarch64_neon_uqshrn, AddRetType),
+  NEONMAP1(vqshrnh_n_s16, aarch64_neon_sqshrn, VectorRet | Use64BitVectors),
+  NEONMAP1(vqshrnh_n_u16, aarch64_neon_uqshrn, VectorRet | Use64BitVectors),
+  NEONMAP1(vqshrns_n_s32, aarch64_neon_sqshrn, VectorRet | Use64BitVectors),
+  NEONMAP1(vqshrns_n_u32, aarch64_neon_uqshrn, VectorRet | Use64BitVectors),
+  NEONMAP1(vqshrund_n_s64, aarch64_neon_sqshrun, AddRetType),
+  NEONMAP1(vqshrunh_n_s16, aarch64_neon_sqshrun, VectorRet | Use64BitVectors),
+  NEONMAP1(vqshruns_n_s32, aarch64_neon_sqshrun, VectorRet | Use64BitVectors),
+  NEONMAP1(vqsubb_s8, aarch64_neon_sqsub, Vectorize1ArgType | Use64BitVectors),
+  NEONMAP1(vqsubb_u8, aarch64_neon_uqsub, Vectorize1ArgType | Use64BitVectors),
+  NEONMAP1(vqsubd_s64, aarch64_neon_sqsub, Add1ArgType),
+  NEONMAP1(vqsubd_u64, aarch64_neon_uqsub, Add1ArgType),
+  NEONMAP1(vqsubh_s16, aarch64_neon_sqsub, Vectorize1ArgType | Use64BitVectors),
+  NEONMAP1(vqsubh_u16, aarch64_neon_uqsub, Vectorize1ArgType | Use64BitVectors),
+  NEONMAP1(vqsubs_s32, aarch64_neon_sqsub, Add1ArgType),
+  NEONMAP1(vqsubs_u32, aarch64_neon_uqsub, Add1ArgType),
+  NEONMAP1(vrecped_f64, aarch64_neon_frecpe, Add1ArgType),
+  NEONMAP1(vrecpes_f32, aarch64_neon_frecpe, Add1ArgType),
+  NEONMAP1(vrecpxd_f64, aarch64_neon_frecpx, Add1ArgType),
+  NEONMAP1(vrecpxs_f32, aarch64_neon_frecpx, Add1ArgType),
+  NEONMAP1(vrshld_s64, aarch64_neon_srshl, Add1ArgType),
+  NEONMAP1(vrshld_u64, aarch64_neon_urshl, Add1ArgType),
+  NEONMAP1(vrsqrted_f64, aarch64_neon_frsqrte, Add1ArgType),
+  NEONMAP1(vrsqrtes_f32, aarch64_neon_frsqrte, Add1ArgType),
+  NEONMAP1(vrsqrtsd_f64, aarch64_neon_frsqrts, Add1ArgType),
+  NEONMAP1(vrsqrtss_f32, aarch64_neon_frsqrts, Add1ArgType),
+  NEONMAP1(vsha1cq_u32, aarch64_crypto_sha1c, 0),
+  NEONMAP1(vsha1h_u32, aarch64_crypto_sha1h, 0),
+  NEONMAP1(vsha1mq_u32, aarch64_crypto_sha1m, 0),
+  NEONMAP1(vsha1pq_u32, aarch64_crypto_sha1p, 0),
+  NEONMAP1(vshld_s64, aarch64_neon_sshl, Add1ArgType),
+  NEONMAP1(vshld_u64, aarch64_neon_ushl, Add1ArgType),
+  NEONMAP1(vslid_n_s64, aarch64_neon_vsli, Vectorize1ArgType),
+  NEONMAP1(vslid_n_u64, aarch64_neon_vsli, Vectorize1ArgType),
+  NEONMAP1(vsqaddb_u8, aarch64_neon_usqadd, Vectorize1ArgType | Use64BitVectors),
+  NEONMAP1(vsqaddd_u64, aarch64_neon_usqadd, Add1ArgType),
+  NEONMAP1(vsqaddh_u16, aarch64_neon_usqadd, Vectorize1ArgType | Use64BitVectors),
+  NEONMAP1(vsqadds_u32, aarch64_neon_usqadd, Add1ArgType),
+  NEONMAP1(vsrid_n_s64, aarch64_neon_vsri, Vectorize1ArgType),
+  NEONMAP1(vsrid_n_u64, aarch64_neon_vsri, Vectorize1ArgType),
+  NEONMAP1(vuqaddb_s8, aarch64_neon_suqadd, Vectorize1ArgType | Use64BitVectors),
+  NEONMAP1(vuqaddd_s64, aarch64_neon_suqadd, Add1ArgType),
+  NEONMAP1(vuqaddh_s16, aarch64_neon_suqadd, Vectorize1ArgType | Use64BitVectors),
+  NEONMAP1(vuqadds_s32, aarch64_neon_suqadd, Add1ArgType),
+};
+
+#undef NEONMAP0
+#undef NEONMAP1
+#undef NEONMAP2
+
+static bool NEONSIMDIntrinsicsProvenSorted = false;
+
+static bool AArch64SIMDIntrinsicsProvenSorted = false;
+static bool AArch64SISDIntrinsicsProvenSorted = false;
+
+
+static const NeonIntrinsicInfo *
+findNeonIntrinsicInMap(ArrayRef<NeonIntrinsicInfo> IntrinsicMap,
+                       unsigned BuiltinID, bool &MapProvenSorted) {
+
+#ifndef NDEBUG
+  if (!MapProvenSorted) {
+    // FIXME: use std::is_sorted once C++11 is allowed
+    for (unsigned i = 0; i < IntrinsicMap.size() - 1; ++i)
+      assert(IntrinsicMap[i].BuiltinID <= IntrinsicMap[i + 1].BuiltinID);
+    MapProvenSorted = true;
+  }
+#endif
+
+  const NeonIntrinsicInfo *Builtin =
+      std::lower_bound(IntrinsicMap.begin(), IntrinsicMap.end(), BuiltinID);
+
+  if (Builtin != IntrinsicMap.end() && Builtin->BuiltinID == BuiltinID)
+    return Builtin;
+
+  return nullptr;
+}
+
+Function *CodeGenFunction::LookupNeonLLVMIntrinsic(unsigned IntrinsicID,
+                                                   unsigned Modifier,
+                                                   llvm::Type *ArgType,
+                                                   const CallExpr *E) {
+  int VectorSize = 0;
+  if (Modifier & Use64BitVectors)
+    VectorSize = 64;
+  else if (Modifier & Use128BitVectors)
+    VectorSize = 128;
+
+  // Return type.
+  SmallVector<llvm::Type *, 3> Tys;
+  if (Modifier & AddRetType) {
+    llvm::Type *Ty = ConvertType(E->getCallReturnType());
+    if (Modifier & VectorizeRetType)
+      Ty = llvm::VectorType::get(
+          Ty, VectorSize ? VectorSize / Ty->getPrimitiveSizeInBits() : 1);
+
+    Tys.push_back(Ty);
   }
 
-  // AArch64 scalar builtins are not overloaded, they do not have an extra
-  // argument that specifies the vector type, need to handle each case.
+  // Arguments.
+  if (Modifier & VectorizeArgTypes) {
+    int Elts = VectorSize ? VectorSize / ArgType->getPrimitiveSizeInBits() : 1;
+    ArgType = llvm::VectorType::get(ArgType, Elts);
+  }
+
+  if (Modifier & (Add1ArgType | Add2ArgTypes))
+    Tys.push_back(ArgType);
+
+  if (Modifier & Add2ArgTypes)
+    Tys.push_back(ArgType);
+
+  if (Modifier & InventFloatType)
+    Tys.push_back(FloatTy);
+
+  return CGM.getIntrinsic(IntrinsicID, Tys);
+}
+
+static Value *EmitCommonNeonSISDBuiltinExpr(CodeGenFunction &CGF,
+                                            const NeonIntrinsicInfo &SISDInfo,
+                                            SmallVectorImpl<Value *> &Ops,
+                                            const CallExpr *E) {
+  unsigned BuiltinID = SISDInfo.BuiltinID;
+  unsigned int Int = SISDInfo.LLVMIntrinsic;
+  unsigned Modifier = SISDInfo.TypeModifier;
+  const char *s = SISDInfo.NameHint;
+
   switch (BuiltinID) {
-  default: break;
-  case AArch64::BI__builtin_neon_vfmas_lane_f32:
-  case AArch64::BI__builtin_neon_vfmas_laneq_f32:
-  case AArch64::BI__builtin_neon_vfmad_lane_f64:
-  case AArch64::BI__builtin_neon_vfmad_laneq_f64: {
-    llvm::Type *Ty = CGF.ConvertType(E->getCallReturnType());
-    Value *F = CGF.CGM.getIntrinsic(Intrinsic::fma, Ty);
-    // extract lane acc += x * v[i]
-    Ops[2] = CGF.Builder.CreateExtractElement(Ops[2], Ops[3], "extract");
-    return CGF.Builder.CreateCall3(F, Ops[1], Ops[2], Ops[0]);
-  }
-  // Scalar Floating-point Multiply Extended
-  case AArch64::BI__builtin_neon_vmulxs_f32:
-  case AArch64::BI__builtin_neon_vmulxd_f64: {
-    Int = Intrinsic::aarch64_neon_vmulx;
-    llvm::Type *Ty = CGF.ConvertType(E->getCallReturnType());
-    return CGF.EmitNeonCall(CGF.CGM.getIntrinsic(Int, Ty), Ops, "vmulx");
-  }
-  case AArch64::BI__builtin_neon_vmul_n_f64: {
-    // v1f64 vmul_n_f64  should be mapped to Neon scalar mul lane
-    llvm::Type *VTy = GetNeonType(&CGF,
-      NeonTypeFlags(NeonTypeFlags::Float64, false, false));
-    Ops[0] = CGF.Builder.CreateBitCast(Ops[0], VTy);
-    llvm::Value *Idx = llvm::ConstantInt::get(CGF.Int32Ty, 0);
-    Ops[0] = CGF.Builder.CreateExtractElement(Ops[0], Idx, "extract");
-    Value *Result = CGF.Builder.CreateFMul(Ops[0], Ops[1]);
-    return CGF.Builder.CreateBitCast(Result, VTy);
-  }
-  case AArch64::BI__builtin_neon_vget_lane_i8:
-  case AArch64::BI__builtin_neon_vget_lane_i16:
-  case AArch64::BI__builtin_neon_vget_lane_i32:
-  case AArch64::BI__builtin_neon_vget_lane_i64:
-  case AArch64::BI__builtin_neon_vget_lane_f32:
-  case AArch64::BI__builtin_neon_vget_lane_f64:
-  case AArch64::BI__builtin_neon_vgetq_lane_i8:
-  case AArch64::BI__builtin_neon_vgetq_lane_i16:
-  case AArch64::BI__builtin_neon_vgetq_lane_i32:
-  case AArch64::BI__builtin_neon_vgetq_lane_i64:
-  case AArch64::BI__builtin_neon_vgetq_lane_f32:
-  case AArch64::BI__builtin_neon_vgetq_lane_f64:
-    return CGF.EmitARMBuiltinExpr(ARM::BI__builtin_neon_vget_lane_i8, E);
-  case AArch64::BI__builtin_neon_vset_lane_i8:
-  case AArch64::BI__builtin_neon_vset_lane_i16:
-  case AArch64::BI__builtin_neon_vset_lane_i32:
-  case AArch64::BI__builtin_neon_vset_lane_i64:
-  case AArch64::BI__builtin_neon_vset_lane_f32:
-  case AArch64::BI__builtin_neon_vset_lane_f64:
-  case AArch64::BI__builtin_neon_vsetq_lane_i8:
-  case AArch64::BI__builtin_neon_vsetq_lane_i16:
-  case AArch64::BI__builtin_neon_vsetq_lane_i32:
-  case AArch64::BI__builtin_neon_vsetq_lane_i64:
-  case AArch64::BI__builtin_neon_vsetq_lane_f32:
-  case AArch64::BI__builtin_neon_vsetq_lane_f64:
-    return CGF.EmitARMBuiltinExpr(ARM::BI__builtin_neon_vset_lane_i8, E);
-  // Crypto
-  case AArch64::BI__builtin_neon_vsha1h_u32:
-    Int = Intrinsic::arm_neon_sha1h;
-    s = "sha1h"; OverloadInt = true; break;
-  case AArch64::BI__builtin_neon_vsha1cq_u32:
-    Int = Intrinsic::aarch64_neon_sha1c;
-    s = "sha1c"; break;
-  case AArch64::BI__builtin_neon_vsha1pq_u32:
-    Int = Intrinsic::aarch64_neon_sha1p;
-    s = "sha1p"; break;
-  case AArch64::BI__builtin_neon_vsha1mq_u32:
-    Int = Intrinsic::aarch64_neon_sha1m;
-    s = "sha1m"; break;
-  // Scalar Add
-  case AArch64::BI__builtin_neon_vaddd_s64:
-    Int = Intrinsic::aarch64_neon_vaddds;
-    s = "vaddds"; break;
-  case AArch64::BI__builtin_neon_vaddd_u64:
-    Int = Intrinsic::aarch64_neon_vadddu;
-    s = "vadddu"; break;
-  // Scalar Sub
-  case AArch64::BI__builtin_neon_vsubd_s64:
-    Int = Intrinsic::aarch64_neon_vsubds;
-    s = "vsubds"; break;
-  case AArch64::BI__builtin_neon_vsubd_u64:
-    Int = Intrinsic::aarch64_neon_vsubdu;
-    s = "vsubdu"; break;
-  // Scalar Saturating Add
-  case AArch64::BI__builtin_neon_vqaddb_s8:
-  case AArch64::BI__builtin_neon_vqaddh_s16:
-  case AArch64::BI__builtin_neon_vqadds_s32:
-  case AArch64::BI__builtin_neon_vqaddd_s64:
-    Int = Intrinsic::aarch64_neon_vqadds;
-    s = "vqadds"; OverloadInt = true; break;
-  case AArch64::BI__builtin_neon_vqaddb_u8:
-  case AArch64::BI__builtin_neon_vqaddh_u16:
-  case AArch64::BI__builtin_neon_vqadds_u32:
-  case AArch64::BI__builtin_neon_vqaddd_u64:
-    Int = Intrinsic::aarch64_neon_vqaddu;
-    s = "vqaddu"; OverloadInt = true; break;
-  // Scalar Saturating Sub
-  case AArch64::BI__builtin_neon_vqsubb_s8:
-  case AArch64::BI__builtin_neon_vqsubh_s16:
-  case AArch64::BI__builtin_neon_vqsubs_s32:
-  case AArch64::BI__builtin_neon_vqsubd_s64:
-    Int = Intrinsic::aarch64_neon_vqsubs;
-    s = "vqsubs"; OverloadInt = true; break;
-  case AArch64::BI__builtin_neon_vqsubb_u8:
-  case AArch64::BI__builtin_neon_vqsubh_u16:
-  case AArch64::BI__builtin_neon_vqsubs_u32:
-  case AArch64::BI__builtin_neon_vqsubd_u64:
-    Int = Intrinsic::aarch64_neon_vqsubu;
-    s = "vqsubu"; OverloadInt = true; break;
-  // Scalar Shift Left
-  case AArch64::BI__builtin_neon_vshld_s64:
-    Int = Intrinsic::aarch64_neon_vshlds;
-    s = "vshlds"; break;
-  case AArch64::BI__builtin_neon_vshld_u64:
-    Int = Intrinsic::aarch64_neon_vshldu;
-    s = "vshldu"; break;
-  // Scalar Saturating Shift Left
-  case AArch64::BI__builtin_neon_vqshlb_s8:
-  case AArch64::BI__builtin_neon_vqshlh_s16:
-  case AArch64::BI__builtin_neon_vqshls_s32:
-  case AArch64::BI__builtin_neon_vqshld_s64:
-    Int = Intrinsic::aarch64_neon_vqshls;
-    s = "vqshls"; OverloadInt = true; break;
-  case AArch64::BI__builtin_neon_vqshlb_u8:
-  case AArch64::BI__builtin_neon_vqshlh_u16:
-  case AArch64::BI__builtin_neon_vqshls_u32:
-  case AArch64::BI__builtin_neon_vqshld_u64:
-    Int = Intrinsic::aarch64_neon_vqshlu;
-    s = "vqshlu"; OverloadInt = true; break;
-  // Scalar Rouding Shift Left
-  case AArch64::BI__builtin_neon_vrshld_s64:
-    Int = Intrinsic::aarch64_neon_vrshlds;
-    s = "vrshlds"; break;
-  case AArch64::BI__builtin_neon_vrshld_u64:
-    Int = Intrinsic::aarch64_neon_vrshldu;
-    s = "vrshldu"; break;
-  // Scalar Saturating Rouding Shift Left
-  case AArch64::BI__builtin_neon_vqrshlb_s8:
-  case AArch64::BI__builtin_neon_vqrshlh_s16:
-  case AArch64::BI__builtin_neon_vqrshls_s32:
-  case AArch64::BI__builtin_neon_vqrshld_s64:
-    Int = Intrinsic::aarch64_neon_vqrshls;
-    s = "vqrshls"; OverloadInt = true; break;
-  case AArch64::BI__builtin_neon_vqrshlb_u8:
-  case AArch64::BI__builtin_neon_vqrshlh_u16:
-  case AArch64::BI__builtin_neon_vqrshls_u32:
-  case AArch64::BI__builtin_neon_vqrshld_u64:
-    Int = Intrinsic::aarch64_neon_vqrshlu;
-    s = "vqrshlu"; OverloadInt = true; break;
-  // Scalar Reduce Pairwise Add
-  case AArch64::BI__builtin_neon_vpaddd_s64:
-    Int = Intrinsic::aarch64_neon_vpadd; s = "vpadd";
+  case NEON::BI__builtin_neon_vcled_s64:
+  case NEON::BI__builtin_neon_vcled_u64:
+  case NEON::BI__builtin_neon_vcles_f32:
+  case NEON::BI__builtin_neon_vcled_f64:
+  case NEON::BI__builtin_neon_vcltd_s64:
+  case NEON::BI__builtin_neon_vcltd_u64:
+  case NEON::BI__builtin_neon_vclts_f32:
+  case NEON::BI__builtin_neon_vcltd_f64:
+  case NEON::BI__builtin_neon_vcales_f32:
+  case NEON::BI__builtin_neon_vcaled_f64:
+  case NEON::BI__builtin_neon_vcalts_f32:
+  case NEON::BI__builtin_neon_vcaltd_f64:
+    // Only one direction of comparisons actually exist, cmle is actually a cmge
+    // with swapped operands. The table gives us the right intrinsic but we
+    // still need to do the swap.
+    std::swap(Ops[0], Ops[1]);
     break;
-  case AArch64::BI__builtin_neon_vpadds_f32:
-    Int = Intrinsic::aarch64_neon_vpfadd; s = "vpfadd";
-    break;
-  case AArch64::BI__builtin_neon_vpaddd_f64:
-    Int = Intrinsic::aarch64_neon_vpfaddq; s = "vpfaddq";
-    break;
-  // Scalar Reduce Pairwise Floating Point Max
-  case AArch64::BI__builtin_neon_vpmaxs_f32:
-    Int = Intrinsic::aarch64_neon_vpmax; s = "vpmax";
-    break;
-  case AArch64::BI__builtin_neon_vpmaxqd_f64:
-    Int = Intrinsic::aarch64_neon_vpmaxq; s = "vpmaxq";
-    break;
-  // Scalar Reduce Pairwise Floating Point Min
-  case AArch64::BI__builtin_neon_vpmins_f32:
-    Int = Intrinsic::aarch64_neon_vpmin; s = "vpmin";
-    break;
-  case AArch64::BI__builtin_neon_vpminqd_f64:
-    Int = Intrinsic::aarch64_neon_vpminq; s = "vpminq";
-    break;
-  // Scalar Reduce Pairwise Floating Point Maxnm
-  case AArch64::BI__builtin_neon_vpmaxnms_f32:
-    Int = Intrinsic::aarch64_neon_vpfmaxnm; s = "vpfmaxnm";
-    break;
-  case AArch64::BI__builtin_neon_vpmaxnmqd_f64:
-    Int = Intrinsic::aarch64_neon_vpfmaxnmq; s = "vpfmaxnmq";
-    break;
-  // Scalar Reduce Pairwise Floating Point Minnm
-  case AArch64::BI__builtin_neon_vpminnms_f32:
-    Int = Intrinsic::aarch64_neon_vpfminnm; s = "vpfminnm";
-    break;
-  case AArch64::BI__builtin_neon_vpminnmqd_f64:
-    Int = Intrinsic::aarch64_neon_vpfminnmq; s = "vpfminnmq";
-    break;
-  // The followings are intrinsics with scalar results generated AcrossVec vectors
-  case AArch64::BI__builtin_neon_vaddlv_s8:
-  case AArch64::BI__builtin_neon_vaddlv_s16:
-  case AArch64::BI__builtin_neon_vaddlvq_s8:
-  case AArch64::BI__builtin_neon_vaddlvq_s16:
-  case AArch64::BI__builtin_neon_vaddlvq_s32:
-    Int = Intrinsic::aarch64_neon_saddlv;
-    AcrossVec = true; ExtendEle = true; s = "saddlv"; break;
-  case AArch64::BI__builtin_neon_vaddlv_u8:
-  case AArch64::BI__builtin_neon_vaddlv_u16:
-  case AArch64::BI__builtin_neon_vaddlvq_u8:
-  case AArch64::BI__builtin_neon_vaddlvq_u16:
-  case AArch64::BI__builtin_neon_vaddlvq_u32:
-    Int = Intrinsic::aarch64_neon_uaddlv;
-    AcrossVec = true; ExtendEle = true; s = "uaddlv"; break;
-  case AArch64::BI__builtin_neon_vmaxv_s8:
-  case AArch64::BI__builtin_neon_vmaxv_s16:
-  case AArch64::BI__builtin_neon_vmaxvq_s8:
-  case AArch64::BI__builtin_neon_vmaxvq_s16:
-  case AArch64::BI__builtin_neon_vmaxvq_s32:
-    Int = Intrinsic::aarch64_neon_smaxv;
-    AcrossVec = true; ExtendEle = false; s = "smaxv"; break;
-  case AArch64::BI__builtin_neon_vmaxv_u8:
-  case AArch64::BI__builtin_neon_vmaxv_u16:
-  case AArch64::BI__builtin_neon_vmaxvq_u8:
-  case AArch64::BI__builtin_neon_vmaxvq_u16:
-  case AArch64::BI__builtin_neon_vmaxvq_u32:
-    Int = Intrinsic::aarch64_neon_umaxv;
-    AcrossVec = true; ExtendEle = false; s = "umaxv"; break;
-  case AArch64::BI__builtin_neon_vminv_s8:
-  case AArch64::BI__builtin_neon_vminv_s16:
-  case AArch64::BI__builtin_neon_vminvq_s8:
-  case AArch64::BI__builtin_neon_vminvq_s16:
-  case AArch64::BI__builtin_neon_vminvq_s32:
-    Int = Intrinsic::aarch64_neon_sminv;
-    AcrossVec = true; ExtendEle = false; s = "sminv"; break;
-  case AArch64::BI__builtin_neon_vminv_u8:
-  case AArch64::BI__builtin_neon_vminv_u16:
-  case AArch64::BI__builtin_neon_vminvq_u8:
-  case AArch64::BI__builtin_neon_vminvq_u16:
-  case AArch64::BI__builtin_neon_vminvq_u32:
-    Int = Intrinsic::aarch64_neon_uminv;
-    AcrossVec = true; ExtendEle = false; s = "uminv"; break;
-  case AArch64::BI__builtin_neon_vaddv_s8:
-  case AArch64::BI__builtin_neon_vaddv_s16:
-  case AArch64::BI__builtin_neon_vaddvq_s8:
-  case AArch64::BI__builtin_neon_vaddvq_s16:
-  case AArch64::BI__builtin_neon_vaddvq_s32:
-  case AArch64::BI__builtin_neon_vaddv_u8:
-  case AArch64::BI__builtin_neon_vaddv_u16:
-  case AArch64::BI__builtin_neon_vaddvq_u8:
-  case AArch64::BI__builtin_neon_vaddvq_u16:
-  case AArch64::BI__builtin_neon_vaddvq_u32:
-    Int = Intrinsic::aarch64_neon_vaddv;
-    AcrossVec = true; ExtendEle = false; s = "vaddv"; break;      
-  case AArch64::BI__builtin_neon_vmaxvq_f32:
-    Int = Intrinsic::aarch64_neon_vmaxv;
-    AcrossVec = true; ExtendEle = false; s = "vmaxv"; break;
-  case AArch64::BI__builtin_neon_vminvq_f32:
-    Int = Intrinsic::aarch64_neon_vminv;
-    AcrossVec = true; ExtendEle = false; s = "vminv"; break;
-  case AArch64::BI__builtin_neon_vmaxnmvq_f32:
-    Int = Intrinsic::aarch64_neon_vmaxnmv;
-    AcrossVec = true; ExtendEle = false; s = "vmaxnmv"; break;
-  case AArch64::BI__builtin_neon_vminnmvq_f32:
-    Int = Intrinsic::aarch64_neon_vminnmv;
-    AcrossVec = true; ExtendEle = false; s = "vminnmv"; break;
-  // Scalar Integer Saturating Doubling Multiply Half High
-  case AArch64::BI__builtin_neon_vqdmulhh_s16:
-  case AArch64::BI__builtin_neon_vqdmulhs_s32:
-    Int = Intrinsic::arm_neon_vqdmulh;
-    s = "vqdmulh"; OverloadInt = true; break;
-  // Scalar Integer Saturating Rounding Doubling Multiply Half High
-  case AArch64::BI__builtin_neon_vqrdmulhh_s16:
-  case AArch64::BI__builtin_neon_vqrdmulhs_s32:
-    Int = Intrinsic::arm_neon_vqrdmulh;
-    s = "vqrdmulh"; OverloadInt = true; break;
-  // Scalar Floating-point Reciprocal Step and
-  case AArch64::BI__builtin_neon_vrecpss_f32:
-  case AArch64::BI__builtin_neon_vrecpsd_f64:
-    Int = Intrinsic::arm_neon_vrecps;
-    s = "vrecps"; OverloadInt = true; break;
-  // Scalar Floating-point Reciprocal Square Root Step
-  case AArch64::BI__builtin_neon_vrsqrtss_f32:
-  case AArch64::BI__builtin_neon_vrsqrtsd_f64:
-    Int = Intrinsic::arm_neon_vrsqrts;
-    s = "vrsqrts"; OverloadInt = true; break;
-  // Scalar Signed Integer Convert To Floating-point
-  case AArch64::BI__builtin_neon_vcvts_f32_s32:
-    Int = Intrinsic::aarch64_neon_vcvtf32_s32,
-    s = "vcvtf"; OverloadInt = false; break;
-  case AArch64::BI__builtin_neon_vcvtd_f64_s64:
-    Int = Intrinsic::aarch64_neon_vcvtf64_s64,
-    s = "vcvtf"; OverloadInt = false; break;
-  // Scalar Unsigned Integer Convert To Floating-point
-  case AArch64::BI__builtin_neon_vcvts_f32_u32:
-    Int = Intrinsic::aarch64_neon_vcvtf32_u32,
-    s = "vcvtf"; OverloadInt = false; break;
-  case AArch64::BI__builtin_neon_vcvtd_f64_u64:
-    Int = Intrinsic::aarch64_neon_vcvtf64_u64,
-    s = "vcvtf"; OverloadInt = false; break;
-  // Scalar Floating-point Reciprocal Estimate
-  case AArch64::BI__builtin_neon_vrecpes_f32:
-  case AArch64::BI__builtin_neon_vrecped_f64:
-    Int = Intrinsic::arm_neon_vrecpe;
-    s = "vrecpe"; OverloadInt = true; break;
-  // Scalar Floating-point Reciprocal Exponent
-  case AArch64::BI__builtin_neon_vrecpxs_f32:
-  case AArch64::BI__builtin_neon_vrecpxd_f64:
-    Int = Intrinsic::aarch64_neon_vrecpx;
-    s = "vrecpx"; OverloadInt = true; break;
-  // Scalar Floating-point Reciprocal Square Root Estimate
-  case AArch64::BI__builtin_neon_vrsqrtes_f32:
-  case AArch64::BI__builtin_neon_vrsqrted_f64:
-    Int = Intrinsic::arm_neon_vrsqrte;
-    s = "vrsqrte"; OverloadInt = true; break;
-  // Scalar Compare Equal
-  case AArch64::BI__builtin_neon_vceqd_s64:
-  case AArch64::BI__builtin_neon_vceqd_u64:
-    Int = Intrinsic::aarch64_neon_vceq; s = "vceq";
-    OverloadCmpInt = true; break;
-  // Scalar Compare Equal To Zero
-  case AArch64::BI__builtin_neon_vceqzd_s64:
-  case AArch64::BI__builtin_neon_vceqzd_u64:
-    Int = Intrinsic::aarch64_neon_vceq; s = "vceq";
-    // Add implicit zero operand.
-    Ops.push_back(llvm::Constant::getNullValue(Ops[0]->getType()));
-    OverloadCmpInt = true; break;
-  // Scalar Compare Greater Than or Equal
-  case AArch64::BI__builtin_neon_vcged_s64:
-    Int = Intrinsic::aarch64_neon_vcge; s = "vcge";
-    OverloadCmpInt = true; break;
-  case AArch64::BI__builtin_neon_vcged_u64:
-    Int = Intrinsic::aarch64_neon_vchs; s = "vcge";
-    OverloadCmpInt = true; break;
-  // Scalar Compare Greater Than or Equal To Zero
-  case AArch64::BI__builtin_neon_vcgezd_s64:
-    Int = Intrinsic::aarch64_neon_vcge; s = "vcge";
-    // Add implicit zero operand.
-    Ops.push_back(llvm::Constant::getNullValue(Ops[0]->getType()));
-    OverloadCmpInt = true; break;
-  // Scalar Compare Greater Than
-  case AArch64::BI__builtin_neon_vcgtd_s64:
-    Int = Intrinsic::aarch64_neon_vcgt; s = "vcgt";
-    OverloadCmpInt = true; break;
-  case AArch64::BI__builtin_neon_vcgtd_u64:
-    Int = Intrinsic::aarch64_neon_vchi; s = "vcgt";
-    OverloadCmpInt = true; break;
-  // Scalar Compare Greater Than Zero
-  case AArch64::BI__builtin_neon_vcgtzd_s64:
-    Int = Intrinsic::aarch64_neon_vcgt; s = "vcgt";
-    // Add implicit zero operand.
-    Ops.push_back(llvm::Constant::getNullValue(Ops[0]->getType()));
-    OverloadCmpInt = true; break;
-  // Scalar Compare Less Than or Equal
-  case AArch64::BI__builtin_neon_vcled_s64:
-    Int = Intrinsic::aarch64_neon_vcge; s = "vcge";
-    OverloadCmpInt = true; std::swap(Ops[0], Ops[1]); break;
-  case AArch64::BI__builtin_neon_vcled_u64:
-    Int = Intrinsic::aarch64_neon_vchs; s = "vchs";
-    OverloadCmpInt = true; std::swap(Ops[0], Ops[1]); break;
-  // Scalar Compare Less Than or Equal To Zero
-  case AArch64::BI__builtin_neon_vclezd_s64:
-    Int = Intrinsic::aarch64_neon_vclez; s = "vcle";
-    // Add implicit zero operand.
-    Ops.push_back(llvm::Constant::getNullValue(Ops[0]->getType()));
-    OverloadCmpInt = true; break;
-  // Scalar Compare Less Than
-  case AArch64::BI__builtin_neon_vcltd_s64:
-    Int = Intrinsic::aarch64_neon_vcgt; s = "vcgt";
-    OverloadCmpInt = true; std::swap(Ops[0], Ops[1]); break;
-  case AArch64::BI__builtin_neon_vcltd_u64:
-    Int = Intrinsic::aarch64_neon_vchi; s = "vchi";
-    OverloadCmpInt = true; std::swap(Ops[0], Ops[1]); break;
-  // Scalar Compare Less Than Zero
-  case AArch64::BI__builtin_neon_vcltzd_s64:
-    Int = Intrinsic::aarch64_neon_vcltz; s = "vclt";
-    // Add implicit zero operand.
-    Ops.push_back(llvm::Constant::getNullValue(Ops[0]->getType()));
-    OverloadCmpInt = true; break;
-  // Scalar Floating-point Compare Equal
-  case AArch64::BI__builtin_neon_vceqs_f32:
-  case AArch64::BI__builtin_neon_vceqd_f64:
-    Int = Intrinsic::aarch64_neon_vceq; s = "vceq";
-    OverloadCmpInt = true; break;
-  // Scalar Floating-point Compare Equal To Zero
-  case AArch64::BI__builtin_neon_vceqzs_f32:
-  case AArch64::BI__builtin_neon_vceqzd_f64:
-    Int = Intrinsic::aarch64_neon_vceq; s = "vceq";
-    // Add implicit zero operand.
-    Ops.push_back(llvm::Constant::getNullValue(Ops[0]->getType()));
-    OverloadCmpInt = true; break;
-  // Scalar Floating-point Compare Greater Than Or Equal
-  case AArch64::BI__builtin_neon_vcges_f32:
-  case AArch64::BI__builtin_neon_vcged_f64:
-    Int = Intrinsic::aarch64_neon_vcge; s = "vcge";
-    OverloadCmpInt = true; break;
-  // Scalar Floating-point Compare Greater Than Or Equal To Zero
-  case AArch64::BI__builtin_neon_vcgezs_f32:
-  case AArch64::BI__builtin_neon_vcgezd_f64:
-    Int = Intrinsic::aarch64_neon_vcge; s = "vcge";
-    // Add implicit zero operand.
-    Ops.push_back(llvm::Constant::getNullValue(Ops[0]->getType()));
-    OverloadCmpInt = true; break;
-  // Scalar Floating-point Compare Greather Than
-  case AArch64::BI__builtin_neon_vcgts_f32:
-  case AArch64::BI__builtin_neon_vcgtd_f64:
-    Int = Intrinsic::aarch64_neon_vcgt; s = "vcgt";
-    OverloadCmpInt = true; break;
-  // Scalar Floating-point Compare Greather Than Zero
-  case AArch64::BI__builtin_neon_vcgtzs_f32:
-  case AArch64::BI__builtin_neon_vcgtzd_f64:
-    Int = Intrinsic::aarch64_neon_vcgt; s = "vcgt";
-    // Add implicit zero operand.
-    Ops.push_back(llvm::Constant::getNullValue(Ops[0]->getType()));
-    OverloadCmpInt = true; break;
-  // Scalar Floating-point Compare Less Than or Equal
-  case AArch64::BI__builtin_neon_vcles_f32:
-  case AArch64::BI__builtin_neon_vcled_f64:
-    Int = Intrinsic::aarch64_neon_vcge; s = "vcge";
-    OverloadCmpInt = true; break;
-  // Scalar Floating-point Compare Less Than Or Equal To Zero
-  case AArch64::BI__builtin_neon_vclezs_f32:
-  case AArch64::BI__builtin_neon_vclezd_f64:
-    Int = Intrinsic::aarch64_neon_vclez; s = "vcle";
-    // Add implicit zero operand.
-    Ops.push_back(llvm::Constant::getNullValue(Ops[0]->getType()));
-    OverloadCmpInt = true; break;
-  // Scalar Floating-point Compare Less Than Zero
-  case AArch64::BI__builtin_neon_vclts_f32:
-  case AArch64::BI__builtin_neon_vcltd_f64:
-    Int = Intrinsic::aarch64_neon_vcgt; s = "vcgt";
-    OverloadCmpInt = true; std::swap(Ops[0], Ops[1]); break;
-  // Scalar Floating-point Compare Less Than Zero
-  case AArch64::BI__builtin_neon_vcltzs_f32:
-  case AArch64::BI__builtin_neon_vcltzd_f64:
-    Int = Intrinsic::aarch64_neon_vcltz; s = "vclt";
-    // Add implicit zero operand.
-    Ops.push_back(llvm::Constant::getNullValue(Ops[0]->getType()));
-    OverloadCmpInt = true; break;
-  // Scalar Floating-point Absolute Compare Greater Than Or Equal
-  case AArch64::BI__builtin_neon_vcages_f32:
-  case AArch64::BI__builtin_neon_vcaged_f64:
-    Int = Intrinsic::aarch64_neon_vcage; s = "vcage";
-    OverloadCmpInt = true; break;
-  // Scalar Floating-point Absolute Compare Greater Than
-  case AArch64::BI__builtin_neon_vcagts_f32:
-  case AArch64::BI__builtin_neon_vcagtd_f64:
-    Int = Intrinsic::aarch64_neon_vcagt; s = "vcagt";
-    OverloadCmpInt = true; break;
-  // Scalar Floating-point Absolute Compare Less Than Or Equal
-  case AArch64::BI__builtin_neon_vcales_f32:
-  case AArch64::BI__builtin_neon_vcaled_f64:
-    Int = Intrinsic::aarch64_neon_vcage; s = "vcage";
-    OverloadCmpInt = true; std::swap(Ops[0], Ops[1]); break;
-  // Scalar Floating-point Absolute Compare Less Than
-  case AArch64::BI__builtin_neon_vcalts_f32:
-  case AArch64::BI__builtin_neon_vcaltd_f64:
-    Int = Intrinsic::aarch64_neon_vcagt; s = "vcalt";
-    OverloadCmpInt = true; std::swap(Ops[0], Ops[1]); break;
-  // Scalar Compare Bitwise Test Bits
-  case AArch64::BI__builtin_neon_vtstd_s64:
-  case AArch64::BI__builtin_neon_vtstd_u64:
-    Int = Intrinsic::aarch64_neon_vtstd; s = "vtst";
-    OverloadCmpInt = true; break;
-  // Scalar Absolute Value
-  case AArch64::BI__builtin_neon_vabsd_s64:
-    Int = Intrinsic::aarch64_neon_vabs;
-    s = "vabs"; OverloadInt = false; break;
-  // Scalar Signed Saturating Absolute Value
-  case AArch64::BI__builtin_neon_vqabsb_s8:
-  case AArch64::BI__builtin_neon_vqabsh_s16:
-  case AArch64::BI__builtin_neon_vqabss_s32:
-  case AArch64::BI__builtin_neon_vqabsd_s64:
-    Int = Intrinsic::arm_neon_vqabs;
-    s = "vqabs"; OverloadInt = true; break;
-  // Scalar Negate
-  case AArch64::BI__builtin_neon_vnegd_s64:
-    Int = Intrinsic::aarch64_neon_vneg;
-    s = "vneg"; OverloadInt = false; break;
-  // Scalar Signed Saturating Negate
-  case AArch64::BI__builtin_neon_vqnegb_s8:
-  case AArch64::BI__builtin_neon_vqnegh_s16:
-  case AArch64::BI__builtin_neon_vqnegs_s32:
-  case AArch64::BI__builtin_neon_vqnegd_s64:
-    Int = Intrinsic::arm_neon_vqneg;
-    s = "vqneg"; OverloadInt = true; break;
-  // Scalar Signed Saturating Accumulated of Unsigned Value
-  case AArch64::BI__builtin_neon_vuqaddb_s8:
-  case AArch64::BI__builtin_neon_vuqaddh_s16:
-  case AArch64::BI__builtin_neon_vuqadds_s32:
-  case AArch64::BI__builtin_neon_vuqaddd_s64:
-    Int = Intrinsic::aarch64_neon_vuqadd;
-    s = "vuqadd"; OverloadInt = true; break;
-  // Scalar Unsigned Saturating Accumulated of Signed Value
-  case AArch64::BI__builtin_neon_vsqaddb_u8:
-  case AArch64::BI__builtin_neon_vsqaddh_u16:
-  case AArch64::BI__builtin_neon_vsqadds_u32:
-  case AArch64::BI__builtin_neon_vsqaddd_u64:
-    Int = Intrinsic::aarch64_neon_vsqadd;
-    s = "vsqadd"; OverloadInt = true; break;
-  // Signed Saturating Doubling Multiply-Add Long
-  case AArch64::BI__builtin_neon_vqdmlalh_s16:
-  case AArch64::BI__builtin_neon_vqdmlals_s32:
-    Int = Intrinsic::aarch64_neon_vqdmlal;
-    s = "vqdmlal"; OverloadWideInt = true; break;
-  // Signed Saturating Doubling Multiply-Subtract Long
-  case AArch64::BI__builtin_neon_vqdmlslh_s16:
-  case AArch64::BI__builtin_neon_vqdmlsls_s32:
-    Int = Intrinsic::aarch64_neon_vqdmlsl;
-    s = "vqdmlsl"; OverloadWideInt = true; break;
-  // Signed Saturating Doubling Multiply Long
-  case AArch64::BI__builtin_neon_vqdmullh_s16:
-  case AArch64::BI__builtin_neon_vqdmulls_s32:
-    Int = Intrinsic::aarch64_neon_vqdmull;
-    s = "vqdmull"; OverloadWideInt = true; break;
-  // Scalar Signed Saturating Extract Unsigned Narrow
-  case AArch64::BI__builtin_neon_vqmovunh_s16:
-  case AArch64::BI__builtin_neon_vqmovuns_s32:
-  case AArch64::BI__builtin_neon_vqmovund_s64:
-    Int = Intrinsic::arm_neon_vqmovnsu;
-    s = "vqmovun"; OverloadNarrowInt = true; break;
-  // Scalar Signed Saturating Extract Narrow
-  case AArch64::BI__builtin_neon_vqmovnh_s16:
-  case AArch64::BI__builtin_neon_vqmovns_s32:
-  case AArch64::BI__builtin_neon_vqmovnd_s64:
-    Int = Intrinsic::arm_neon_vqmovns;
-    s = "vqmovn"; OverloadNarrowInt = true; break;
-  // Scalar Unsigned Saturating Extract Narrow
-  case AArch64::BI__builtin_neon_vqmovnh_u16:
-  case AArch64::BI__builtin_neon_vqmovns_u32:
-  case AArch64::BI__builtin_neon_vqmovnd_u64:
-    Int = Intrinsic::arm_neon_vqmovnu;
-    s = "vqmovn"; OverloadNarrowInt = true; break;
-  // Scalar Signed Shift Right (Immediate)
-  case AArch64::BI__builtin_neon_vshrd_n_s64:
-    Int = Intrinsic::aarch64_neon_vshrds_n;
-    s = "vsshr"; OverloadInt = false; break;
-  // Scalar Unsigned Shift Right (Immediate)
-  case AArch64::BI__builtin_neon_vshrd_n_u64:
-    Int = Intrinsic::aarch64_neon_vshrdu_n;
-    s = "vushr"; OverloadInt = false; break;
-  // Scalar Signed Rounding Shift Right (Immediate)
-  case AArch64::BI__builtin_neon_vrshrd_n_s64:
-    Int = Intrinsic::aarch64_neon_vsrshr;
-    s = "vsrshr"; OverloadInt = true; break;
-  // Scalar Unsigned Rounding Shift Right (Immediate)
-  case AArch64::BI__builtin_neon_vrshrd_n_u64:
-    Int = Intrinsic::aarch64_neon_vurshr;
-    s = "vurshr"; OverloadInt = true; break;
-  // Scalar Signed Shift Right and Accumulate (Immediate)
-  case AArch64::BI__builtin_neon_vsrad_n_s64:
-    Int = Intrinsic::aarch64_neon_vsrads_n;
-    s = "vssra"; OverloadInt = false; break;
-  // Scalar Unsigned Shift Right and Accumulate (Immediate)
-  case AArch64::BI__builtin_neon_vsrad_n_u64:
-    Int = Intrinsic::aarch64_neon_vsradu_n;
-    s = "vusra"; OverloadInt = false; break;
-  // Scalar Signed Rounding Shift Right and Accumulate (Immediate)
-  case AArch64::BI__builtin_neon_vrsrad_n_s64:
-    Int = Intrinsic::aarch64_neon_vrsrads_n;
-    s = "vsrsra"; OverloadInt = false; break;
-  // Scalar Unsigned Rounding Shift Right and Accumulate (Immediate)
-  case AArch64::BI__builtin_neon_vrsrad_n_u64:
-    Int = Intrinsic::aarch64_neon_vrsradu_n;
-    s = "vursra"; OverloadInt = false; break;
-  // Scalar Signed/Unsigned Shift Left (Immediate)
-  case AArch64::BI__builtin_neon_vshld_n_s64:
-  case AArch64::BI__builtin_neon_vshld_n_u64:
-    Int = Intrinsic::aarch64_neon_vshld_n;
-    s = "vshl"; OverloadInt = false; break;
-  // Signed Saturating Shift Left (Immediate)
-  case AArch64::BI__builtin_neon_vqshlb_n_s8:
-  case AArch64::BI__builtin_neon_vqshlh_n_s16:
-  case AArch64::BI__builtin_neon_vqshls_n_s32:
-  case AArch64::BI__builtin_neon_vqshld_n_s64:
-    Int = Intrinsic::aarch64_neon_vqshls_n;
-    s = "vsqshl"; OverloadInt = true; break;
-  // Unsigned Saturating Shift Left (Immediate)
-  case AArch64::BI__builtin_neon_vqshlb_n_u8:
-  case AArch64::BI__builtin_neon_vqshlh_n_u16:
-  case AArch64::BI__builtin_neon_vqshls_n_u32:
-  case AArch64::BI__builtin_neon_vqshld_n_u64:
-    Int = Intrinsic::aarch64_neon_vqshlu_n;
-    s = "vuqshl"; OverloadInt = true; break;
-  // Signed Saturating Shift Left Unsigned (Immediate)
-  case AArch64::BI__builtin_neon_vqshlub_n_s8:
-  case AArch64::BI__builtin_neon_vqshluh_n_s16:
-  case AArch64::BI__builtin_neon_vqshlus_n_s32:
-  case AArch64::BI__builtin_neon_vqshlud_n_s64:
-    Int = Intrinsic::aarch64_neon_vsqshlu;
-    s = "vsqshlu"; OverloadInt = true; break;
-  // Shift Right And Insert (Immediate)
-  case AArch64::BI__builtin_neon_vsrid_n_s64:
-  case AArch64::BI__builtin_neon_vsrid_n_u64:
-    Int = Intrinsic::aarch64_neon_vsri;
-    s = "vsri"; OverloadInt = true; break;
-  // Shift Left And Insert (Immediate)
-  case AArch64::BI__builtin_neon_vslid_n_s64:
-  case AArch64::BI__builtin_neon_vslid_n_u64:
-    Int = Intrinsic::aarch64_neon_vsli;
-    s = "vsli"; OverloadInt = true; break;
-  // Signed Saturating Shift Right Narrow (Immediate)
-  case AArch64::BI__builtin_neon_vqshrnh_n_s16:
-  case AArch64::BI__builtin_neon_vqshrns_n_s32:
-  case AArch64::BI__builtin_neon_vqshrnd_n_s64:
-    Int = Intrinsic::aarch64_neon_vsqshrn;
-    s = "vsqshrn"; OverloadInt = true; break;
-  // Unsigned Saturating Shift Right Narrow (Immediate)
-  case AArch64::BI__builtin_neon_vqshrnh_n_u16:
-  case AArch64::BI__builtin_neon_vqshrns_n_u32:
-  case AArch64::BI__builtin_neon_vqshrnd_n_u64:
-    Int = Intrinsic::aarch64_neon_vuqshrn;
-    s = "vuqshrn"; OverloadInt = true; break;
-  // Signed Saturating Rounded Shift Right Narrow (Immediate)
-  case AArch64::BI__builtin_neon_vqrshrnh_n_s16:
-  case AArch64::BI__builtin_neon_vqrshrns_n_s32:
-  case AArch64::BI__builtin_neon_vqrshrnd_n_s64:
-    Int = Intrinsic::aarch64_neon_vsqrshrn;
-    s = "vsqrshrn"; OverloadInt = true; break;
-  // Unsigned Saturating Rounded Shift Right Narrow (Immediate)
-  case AArch64::BI__builtin_neon_vqrshrnh_n_u16:
-  case AArch64::BI__builtin_neon_vqrshrns_n_u32:
-  case AArch64::BI__builtin_neon_vqrshrnd_n_u64:
-    Int = Intrinsic::aarch64_neon_vuqrshrn;
-    s = "vuqrshrn"; OverloadInt = true; break;
-  // Signed Saturating Shift Right Unsigned Narrow (Immediate)
-  case AArch64::BI__builtin_neon_vqshrunh_n_s16:
-  case AArch64::BI__builtin_neon_vqshruns_n_s32:
-  case AArch64::BI__builtin_neon_vqshrund_n_s64:
-    Int = Intrinsic::aarch64_neon_vsqshrun;
-    s = "vsqshrun"; OverloadInt = true; break;
-  // Signed Saturating Rounded Shift Right Unsigned Narrow (Immediate)
-  case AArch64::BI__builtin_neon_vqrshrunh_n_s16:
-  case AArch64::BI__builtin_neon_vqrshruns_n_s32:
-  case AArch64::BI__builtin_neon_vqrshrund_n_s64:
-    Int = Intrinsic::aarch64_neon_vsqrshrun;
-    s = "vsqrshrun"; OverloadInt = true; break;
-  // Scalar Signed Fixed-point Convert To Floating-Point (Immediate)
-  case AArch64::BI__builtin_neon_vcvts_n_f32_s32:
-    Int = Intrinsic::aarch64_neon_vcvtf32_n_s32;
-    s = "vcvtf"; OverloadInt = false; break;
-  case AArch64::BI__builtin_neon_vcvtd_n_f64_s64:
-    Int = Intrinsic::aarch64_neon_vcvtf64_n_s64;
-    s = "vcvtf"; OverloadInt = false; break;
-  // Scalar Unsigned Fixed-point Convert To Floating-Point (Immediate)
-  case AArch64::BI__builtin_neon_vcvts_n_f32_u32:
-    Int = Intrinsic::aarch64_neon_vcvtf32_n_u32;
-    s = "vcvtf"; OverloadInt = false; break;
-  case AArch64::BI__builtin_neon_vcvtd_n_f64_u64:
-    Int = Intrinsic::aarch64_neon_vcvtf64_n_u64;
-    s = "vcvtf"; OverloadInt = false; break;
-  // Scalar Floating-point Convert To Signed Fixed-point (Immediate)
-  case AArch64::BI__builtin_neon_vcvts_n_s32_f32:
-    Int = Intrinsic::aarch64_neon_vcvts_n_s32_f32;
-    s = "fcvtzs"; OverloadInt = false; break;
-  case AArch64::BI__builtin_neon_vcvtd_n_s64_f64:
-    Int = Intrinsic::aarch64_neon_vcvtd_n_s64_f64;
-    s = "fcvtzs"; OverloadInt = false; break;
-  // Scalar Floating-point Convert To Unsigned Fixed-point (Immediate)
-  case AArch64::BI__builtin_neon_vcvts_n_u32_f32:
-    Int = Intrinsic::aarch64_neon_vcvts_n_u32_f32;
-    s = "fcvtzu"; OverloadInt = false; break;
-  case AArch64::BI__builtin_neon_vcvtd_n_u64_f64:
-    Int = Intrinsic::aarch64_neon_vcvtd_n_u64_f64;
-    s = "fcvtzu"; OverloadInt = false; break;
   }
 
-  if (!Int)
-    return 0;
+  assert(Int && "Generic code assumes a valid intrinsic");
 
-  // AArch64 scalar builtin that returns scalar type
-  // and should be mapped to AArch64 intrinsic that returns
-  // one-element vector type.
-  Function *F = 0;
-  if (AcrossVec) {
-    // Gen arg type
-    const Expr *Arg = E->getArg(E->getNumArgs()-1);
-    llvm::Type *Ty = CGF.ConvertType(Arg->getType());
-    llvm::VectorType *VTy = cast<llvm::VectorType>(Ty);
-    llvm::Type *ETy = VTy->getElementType();
-    llvm::VectorType *RTy = llvm::VectorType::get(ETy, 1);
-  
-    if (ExtendEle) {
-      assert(!ETy->isFloatingPointTy());
-      RTy = llvm::VectorType::getExtendedElementVectorType(RTy);
-    }
+  // Determine the type(s) of this overloaded AArch64 intrinsic.
+  const Expr *Arg = E->getArg(0);
+  llvm::Type *ArgTy = CGF.ConvertType(Arg->getType());
+  Function *F = CGF.LookupNeonLLVMIntrinsic(Int, Modifier, ArgTy, E);
 
-    llvm::Type *Tys[2] = {RTy, VTy};
-    F = CGF.CGM.getIntrinsic(Int, Tys);
-    assert(E->getNumArgs() == 1);
-  } else if (OverloadInt) {
-    // Determine the type of this overloaded AArch64 intrinsic
-    llvm::Type *Ty = CGF.ConvertType(E->getCallReturnType());
-    llvm::VectorType *VTy = llvm::VectorType::get(Ty, 1);
-    assert(VTy);
+  int j = 0;
+  ConstantInt *C0 = ConstantInt::get(CGF.SizeTy, 0);
+  for (Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end();
+       ai != ae; ++ai, ++j) {
+    llvm::Type *ArgTy = ai->getType();
+    if (Ops[j]->getType()->getPrimitiveSizeInBits() ==
+             ArgTy->getPrimitiveSizeInBits())
+      continue;
 
-    F = CGF.CGM.getIntrinsic(Int, VTy);
-  } else if (OverloadWideInt || OverloadNarrowInt) {
-    // Determine the type of this overloaded AArch64 intrinsic
-    const Expr *Arg = E->getArg(E->getNumArgs()-1);
-    llvm::Type *Ty = CGF.ConvertType(Arg->getType());
-    llvm::VectorType *VTy = llvm::VectorType::get(Ty, 1);
-    llvm::VectorType *RTy = OverloadWideInt ? 
-      llvm::VectorType::getExtendedElementVectorType(VTy) :
-      llvm::VectorType::getTruncatedElementVectorType(VTy);
-    F = CGF.CGM.getIntrinsic(Int, RTy);
-  } else if (OverloadCmpInt) {
-    // Determine the types of this overloaded AArch64 intrinsic
-    SmallVector<llvm::Type *, 3> Tys;
-    const Expr *Arg = E->getArg(E->getNumArgs()-1);
-    llvm::Type *Ty = CGF.ConvertType(E->getCallReturnType());
-    llvm::VectorType *VTy = llvm::VectorType::get(Ty, 1);
-    Tys.push_back(VTy);
-    Ty = CGF.ConvertType(Arg->getType());
-    VTy = llvm::VectorType::get(Ty, 1);
-    Tys.push_back(VTy);
-    Tys.push_back(VTy);
-
-    F = CGF.CGM.getIntrinsic(Int, Tys);
-  } else
-    F = CGF.CGM.getIntrinsic(Int);
+    assert(ArgTy->isVectorTy() && !Ops[j]->getType()->isVectorTy());
+    // The constant argument to an _n_ intrinsic always has Int32Ty, so truncate
+    // it before inserting.
+    Ops[j] =
+        CGF.Builder.CreateTruncOrBitCast(Ops[j], ArgTy->getVectorElementType());
+    Ops[j] =
+        CGF.Builder.CreateInsertElement(UndefValue::get(ArgTy), Ops[j], C0);
+  }
 
   Value *Result = CGF.EmitNeonCall(F, Ops, s);
   llvm::Type *ResultType = CGF.ConvertType(E->getType());
+  if (ResultType->getPrimitiveSizeInBits() <
+      Result->getType()->getPrimitiveSizeInBits())
+    return CGF.Builder.CreateExtractElement(Result, C0);
+
+  return CGF.Builder.CreateBitCast(Result, ResultType, s);
+}
+
+Value *CodeGenFunction::EmitCommonNeonBuiltinExpr(
+    unsigned BuiltinID, unsigned LLVMIntrinsic, unsigned AltLLVMIntrinsic,
+    const char *NameHint, unsigned Modifier, const CallExpr *E,
+    SmallVectorImpl<llvm::Value *> &Ops, llvm::Value *Align) {
+  // Get the last argument, which specifies the vector type.
+  llvm::APSInt NeonTypeConst;
+  const Expr *Arg = E->getArg(E->getNumArgs() - 1);
+  if (!Arg->isIntegerConstantExpr(NeonTypeConst, getContext()))
+    return nullptr;
+
+  // Determine the type of this overloaded NEON intrinsic.
+  NeonTypeFlags Type(NeonTypeConst.getZExtValue());
+  bool Usgn = Type.isUnsigned();
+  bool Quad = Type.isQuad();
+
+  llvm::VectorType *VTy = GetNeonType(this, Type);
+  llvm::Type *Ty = VTy;
+  if (!Ty)
+    return nullptr;
+
+  unsigned Int = LLVMIntrinsic;
+  if ((Modifier & UnsignedAlts) && !Usgn)
+    Int = AltLLVMIntrinsic;
+
+  switch (BuiltinID) {
+  default: break;
+  case NEON::BI__builtin_neon_vabs_v:
+  case NEON::BI__builtin_neon_vabsq_v:
+    if (VTy->getElementType()->isFloatingPointTy())
+      return EmitNeonCall(CGM.getIntrinsic(Intrinsic::fabs, Ty), Ops, "vabs");
+    return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Ty), Ops, "vabs");
+  case NEON::BI__builtin_neon_vaddhn_v: {
+    llvm::VectorType *SrcTy =
+        llvm::VectorType::getExtendedElementVectorType(VTy);
+
+    // %sum = add <4 x i32> %lhs, %rhs
+    Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy);
+    Ops[1] = Builder.CreateBitCast(Ops[1], SrcTy);
+    Ops[0] = Builder.CreateAdd(Ops[0], Ops[1], "vaddhn");
+
+    // %high = lshr <4 x i32> %sum, <i32 16, i32 16, i32 16, i32 16>
+    Constant *ShiftAmt = ConstantInt::get(SrcTy->getElementType(),
+                                       SrcTy->getScalarSizeInBits() / 2);
+    ShiftAmt = ConstantVector::getSplat(VTy->getNumElements(), ShiftAmt);
+    Ops[0] = Builder.CreateLShr(Ops[0], ShiftAmt, "vaddhn");
+
+    // %res = trunc <4 x i32> %high to <4 x i16>
+    return Builder.CreateTrunc(Ops[0], VTy, "vaddhn");
+  }
+  case NEON::BI__builtin_neon_vcale_v:
+  case NEON::BI__builtin_neon_vcaleq_v:
+  case NEON::BI__builtin_neon_vcalt_v:
+  case NEON::BI__builtin_neon_vcaltq_v:
+    std::swap(Ops[0], Ops[1]);
+  case NEON::BI__builtin_neon_vcage_v:
+  case NEON::BI__builtin_neon_vcageq_v:
+  case NEON::BI__builtin_neon_vcagt_v:
+  case NEON::BI__builtin_neon_vcagtq_v: {
+    llvm::Type *VecFlt = llvm::VectorType::get(
+        VTy->getScalarSizeInBits() == 32 ? FloatTy : DoubleTy,
+        VTy->getNumElements());
+    llvm::Type *Tys[] = { VTy, VecFlt };
+    Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys);
+    return EmitNeonCall(F, Ops, NameHint);
+  }
+  case NEON::BI__builtin_neon_vclz_v:
+  case NEON::BI__builtin_neon_vclzq_v:
+    // We generate target-independent intrinsic, which needs a second argument
+    // for whether or not clz of zero is undefined; on ARM it isn't.
+    Ops.push_back(Builder.getInt1(getTarget().isCLZForZeroUndef()));
+    break;
+  case NEON::BI__builtin_neon_vcvt_f32_v:
+  case NEON::BI__builtin_neon_vcvtq_f32_v:
+    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
+    Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, Quad));
+    return Usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt")
+                : Builder.CreateSIToFP(Ops[0], Ty, "vcvt");
+  case NEON::BI__builtin_neon_vcvt_n_f32_v:
+  case NEON::BI__builtin_neon_vcvt_n_f64_v:
+  case NEON::BI__builtin_neon_vcvtq_n_f32_v:
+  case NEON::BI__builtin_neon_vcvtq_n_f64_v: {
+    bool Double =
+      (cast<llvm::IntegerType>(VTy->getElementType())->getBitWidth() == 64);
+    llvm::Type *FloatTy =
+        GetNeonType(this, NeonTypeFlags(Double ? NeonTypeFlags::Float64
+                                               : NeonTypeFlags::Float32,
+                                        false, Quad));
+    llvm::Type *Tys[2] = { FloatTy, Ty };
+    Int = Usgn ? LLVMIntrinsic : AltLLVMIntrinsic;
+    Function *F = CGM.getIntrinsic(Int, Tys);
+    return EmitNeonCall(F, Ops, "vcvt_n");
+  }
+  case NEON::BI__builtin_neon_vcvt_n_s32_v:
+  case NEON::BI__builtin_neon_vcvt_n_u32_v:
+  case NEON::BI__builtin_neon_vcvt_n_s64_v:
+  case NEON::BI__builtin_neon_vcvt_n_u64_v:
+  case NEON::BI__builtin_neon_vcvtq_n_s32_v:
+  case NEON::BI__builtin_neon_vcvtq_n_u32_v:
+  case NEON::BI__builtin_neon_vcvtq_n_s64_v:
+  case NEON::BI__builtin_neon_vcvtq_n_u64_v: {
+    bool Double =
+      (cast<llvm::IntegerType>(VTy->getElementType())->getBitWidth() == 64);
+    llvm::Type *FloatTy =
+        GetNeonType(this, NeonTypeFlags(Double ? NeonTypeFlags::Float64
+                                               : NeonTypeFlags::Float32,
+                                        false, Quad));
+    llvm::Type *Tys[2] = { Ty, FloatTy };
+    Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys);
+    return EmitNeonCall(F, Ops, "vcvt_n");
+  }
+  case NEON::BI__builtin_neon_vcvt_s32_v:
+  case NEON::BI__builtin_neon_vcvt_u32_v:
+  case NEON::BI__builtin_neon_vcvt_s64_v:
+  case NEON::BI__builtin_neon_vcvt_u64_v:
+  case NEON::BI__builtin_neon_vcvtq_s32_v:
+  case NEON::BI__builtin_neon_vcvtq_u32_v:
+  case NEON::BI__builtin_neon_vcvtq_s64_v:
+  case NEON::BI__builtin_neon_vcvtq_u64_v: {
+    bool Double =
+      (cast<llvm::IntegerType>(VTy->getElementType())->getBitWidth() == 64);
+    llvm::Type *FloatTy =
+        GetNeonType(this, NeonTypeFlags(Double ? NeonTypeFlags::Float64
+                                               : NeonTypeFlags::Float32,
+                                        false, Quad));
+    Ops[0] = Builder.CreateBitCast(Ops[0], FloatTy);
+    return Usgn ? Builder.CreateFPToUI(Ops[0], Ty, "vcvt")
+                : Builder.CreateFPToSI(Ops[0], Ty, "vcvt");
+  }
+  case NEON::BI__builtin_neon_vcvta_s32_v:
+  case NEON::BI__builtin_neon_vcvta_s64_v:
+  case NEON::BI__builtin_neon_vcvta_u32_v:
+  case NEON::BI__builtin_neon_vcvta_u64_v:
+  case NEON::BI__builtin_neon_vcvtaq_s32_v:
+  case NEON::BI__builtin_neon_vcvtaq_s64_v:
+  case NEON::BI__builtin_neon_vcvtaq_u32_v:
+  case NEON::BI__builtin_neon_vcvtaq_u64_v:
+  case NEON::BI__builtin_neon_vcvtn_s32_v:
+  case NEON::BI__builtin_neon_vcvtn_s64_v:
+  case NEON::BI__builtin_neon_vcvtn_u32_v:
+  case NEON::BI__builtin_neon_vcvtn_u64_v:
+  case NEON::BI__builtin_neon_vcvtnq_s32_v:
+  case NEON::BI__builtin_neon_vcvtnq_s64_v:
+  case NEON::BI__builtin_neon_vcvtnq_u32_v:
+  case NEON::BI__builtin_neon_vcvtnq_u64_v:
+  case NEON::BI__builtin_neon_vcvtp_s32_v:
+  case NEON::BI__builtin_neon_vcvtp_s64_v:
+  case NEON::BI__builtin_neon_vcvtp_u32_v:
+  case NEON::BI__builtin_neon_vcvtp_u64_v:
+  case NEON::BI__builtin_neon_vcvtpq_s32_v:
+  case NEON::BI__builtin_neon_vcvtpq_s64_v:
+  case NEON::BI__builtin_neon_vcvtpq_u32_v:
+  case NEON::BI__builtin_neon_vcvtpq_u64_v:
+  case NEON::BI__builtin_neon_vcvtm_s32_v:
+  case NEON::BI__builtin_neon_vcvtm_s64_v:
+  case NEON::BI__builtin_neon_vcvtm_u32_v:
+  case NEON::BI__builtin_neon_vcvtm_u64_v:
+  case NEON::BI__builtin_neon_vcvtmq_s32_v:
+  case NEON::BI__builtin_neon_vcvtmq_s64_v:
+  case NEON::BI__builtin_neon_vcvtmq_u32_v:
+  case NEON::BI__builtin_neon_vcvtmq_u64_v: {
+    bool Double =
+      (cast<llvm::IntegerType>(VTy->getElementType())->getBitWidth() == 64);
+    llvm::Type *InTy =
+      GetNeonType(this,
+                  NeonTypeFlags(Double ? NeonTypeFlags::Float64
+                                : NeonTypeFlags::Float32, false, Quad));
+    llvm::Type *Tys[2] = { Ty, InTy };
+    return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Tys), Ops, NameHint);
+  }
+  case NEON::BI__builtin_neon_vext_v:
+  case NEON::BI__builtin_neon_vextq_v: {
+    int CV = cast<ConstantInt>(Ops[2])->getSExtValue();
+    SmallVector<Constant*, 16> Indices;
+    for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i)
+      Indices.push_back(ConstantInt::get(Int32Ty, i+CV));
+
+    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
+    Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
+    Value *SV = llvm::ConstantVector::get(Indices);
+    return Builder.CreateShuffleVector(Ops[0], Ops[1], SV, "vext");
+  }
+  case NEON::BI__builtin_neon_vfma_v:
+  case NEON::BI__builtin_neon_vfmaq_v: {
+    Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty);
+    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
+    Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
+    Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
+
+    // NEON intrinsic puts accumulator first, unlike the LLVM fma.
+    return Builder.CreateCall3(F, Ops[1], Ops[2], Ops[0]);
+  }
+  case NEON::BI__builtin_neon_vld1_v:
+  case NEON::BI__builtin_neon_vld1q_v:
+    Ops.push_back(Align);
+    return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Ty), Ops, "vld1");
+  case NEON::BI__builtin_neon_vld2_v:
+  case NEON::BI__builtin_neon_vld2q_v:
+  case NEON::BI__builtin_neon_vld3_v:
+  case NEON::BI__builtin_neon_vld3q_v:
+  case NEON::BI__builtin_neon_vld4_v:
+  case NEON::BI__builtin_neon_vld4q_v: {
+    Function *F = CGM.getIntrinsic(LLVMIntrinsic, Ty);
+    Ops[1] = Builder.CreateCall2(F, Ops[1], Align, NameHint);
+    Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
+    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
+    return Builder.CreateStore(Ops[1], Ops[0]);
+  }
+  case NEON::BI__builtin_neon_vld1_dup_v:
+  case NEON::BI__builtin_neon_vld1q_dup_v: {
+    Value *V = UndefValue::get(Ty);
+    Ty = llvm::PointerType::getUnqual(VTy->getElementType());
+    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
+    LoadInst *Ld = Builder.CreateLoad(Ops[0]);
+    Ld->setAlignment(cast<ConstantInt>(Align)->getZExtValue());
+    llvm::Constant *CI = ConstantInt::get(SizeTy, 0);
+    Ops[0] = Builder.CreateInsertElement(V, Ld, CI);
+    return EmitNeonSplat(Ops[0], CI);
+  }
+  case NEON::BI__builtin_neon_vld2_lane_v:
+  case NEON::BI__builtin_neon_vld2q_lane_v:
+  case NEON::BI__builtin_neon_vld3_lane_v:
+  case NEON::BI__builtin_neon_vld3q_lane_v:
+  case NEON::BI__builtin_neon_vld4_lane_v:
+  case NEON::BI__builtin_neon_vld4q_lane_v: {
+    Function *F = CGM.getIntrinsic(LLVMIntrinsic, Ty);
+    for (unsigned I = 2; I < Ops.size() - 1; ++I)
+      Ops[I] = Builder.CreateBitCast(Ops[I], Ty);
+    Ops.push_back(Align);
+    Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), NameHint);
+    Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
+    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
+    return Builder.CreateStore(Ops[1], Ops[0]);
+  }
+  case NEON::BI__builtin_neon_vmovl_v: {
+    llvm::Type *DTy =llvm::VectorType::getTruncatedElementVectorType(VTy);
+    Ops[0] = Builder.CreateBitCast(Ops[0], DTy);
+    if (Usgn)
+      return Builder.CreateZExt(Ops[0], Ty, "vmovl");
+    return Builder.CreateSExt(Ops[0], Ty, "vmovl");
+  }
+  case NEON::BI__builtin_neon_vmovn_v: {
+    llvm::Type *QTy = llvm::VectorType::getExtendedElementVectorType(VTy);
+    Ops[0] = Builder.CreateBitCast(Ops[0], QTy);
+    return Builder.CreateTrunc(Ops[0], Ty, "vmovn");
+  }
+  case NEON::BI__builtin_neon_vmull_v:
+    // FIXME: the integer vmull operations could be emitted in terms of pure
+    // LLVM IR (2 exts followed by a mul). Unfortunately LLVM has a habit of
+    // hoisting the exts outside loops. Until global ISel comes along that can
+    // see through such movement this leads to bad CodeGen. So we need an
+    // intrinsic for now.
+    Int = Usgn ? Intrinsic::arm_neon_vmullu : Intrinsic::arm_neon_vmulls;
+    Int = Type.isPoly() ? (unsigned)Intrinsic::arm_neon_vmullp : Int;
+    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmull");
+  case NEON::BI__builtin_neon_vpadal_v:
+  case NEON::BI__builtin_neon_vpadalq_v: {
+    // The source operand type has twice as many elements of half the size.
+    unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
+    llvm::Type *EltTy =
+      llvm::IntegerType::get(getLLVMContext(), EltBits / 2);
+    llvm::Type *NarrowTy =
+      llvm::VectorType::get(EltTy, VTy->getNumElements() * 2);
+    llvm::Type *Tys[2] = { Ty, NarrowTy };
+    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, NameHint);
+  }
+  case NEON::BI__builtin_neon_vpaddl_v:
+  case NEON::BI__builtin_neon_vpaddlq_v: {
+    // The source operand type has twice as many elements of half the size.
+    unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
+    llvm::Type *EltTy = llvm::IntegerType::get(getLLVMContext(), EltBits / 2);
+    llvm::Type *NarrowTy =
+      llvm::VectorType::get(EltTy, VTy->getNumElements() * 2);
+    llvm::Type *Tys[2] = { Ty, NarrowTy };
+    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vpaddl");
+  }
+  case NEON::BI__builtin_neon_vqdmlal_v:
+  case NEON::BI__builtin_neon_vqdmlsl_v: {
+    SmallVector<Value *, 2> MulOps(Ops.begin() + 1, Ops.end());
+    Value *Mul = EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Ty),
+                              MulOps, "vqdmlal");
+
+    SmallVector<Value *, 2> AccumOps;
+    AccumOps.push_back(Ops[0]);
+    AccumOps.push_back(Mul);
+    return EmitNeonCall(CGM.getIntrinsic(AltLLVMIntrinsic, Ty),
+                        AccumOps, NameHint);
+  }
+  case NEON::BI__builtin_neon_vqshl_n_v:
+  case NEON::BI__builtin_neon_vqshlq_n_v:
+    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshl_n",
+                        1, false);
+  case NEON::BI__builtin_neon_vrecpe_v:
+  case NEON::BI__builtin_neon_vrecpeq_v:
+  case NEON::BI__builtin_neon_vrsqrte_v:
+  case NEON::BI__builtin_neon_vrsqrteq_v:
+    Int = Ty->isFPOrFPVectorTy() ? LLVMIntrinsic : AltLLVMIntrinsic;
+    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, NameHint);
+
+  case NEON::BI__builtin_neon_vshl_n_v:
+  case NEON::BI__builtin_neon_vshlq_n_v:
+    Ops[1] = EmitNeonShiftVector(Ops[1], Ty, false);
+    return Builder.CreateShl(Builder.CreateBitCast(Ops[0],Ty), Ops[1],
+                             "vshl_n");
+  case NEON::BI__builtin_neon_vshll_n_v: {
+    llvm::Type *SrcTy = llvm::VectorType::getTruncatedElementVectorType(VTy);
+    Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy);
+    if (Usgn)
+      Ops[0] = Builder.CreateZExt(Ops[0], VTy);
+    else
+      Ops[0] = Builder.CreateSExt(Ops[0], VTy);
+    Ops[1] = EmitNeonShiftVector(Ops[1], VTy, false);
+    return Builder.CreateShl(Ops[0], Ops[1], "vshll_n");
+  }
+  case NEON::BI__builtin_neon_vshrn_n_v: {
+    llvm::Type *SrcTy = llvm::VectorType::getExtendedElementVectorType(VTy);
+    Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy);
+    Ops[1] = EmitNeonShiftVector(Ops[1], SrcTy, false);
+    if (Usgn)
+      Ops[0] = Builder.CreateLShr(Ops[0], Ops[1]);
+    else
+      Ops[0] = Builder.CreateAShr(Ops[0], Ops[1]);
+    return Builder.CreateTrunc(Ops[0], Ty, "vshrn_n");
+  }
+  case NEON::BI__builtin_neon_vshr_n_v:
+  case NEON::BI__builtin_neon_vshrq_n_v:
+    return EmitNeonRShiftImm(Ops[0], Ops[1], Ty, Usgn, "vshr_n");
+  case NEON::BI__builtin_neon_vst1_v:
+  case NEON::BI__builtin_neon_vst1q_v:
+  case NEON::BI__builtin_neon_vst2_v:
+  case NEON::BI__builtin_neon_vst2q_v:
+  case NEON::BI__builtin_neon_vst3_v:
+  case NEON::BI__builtin_neon_vst3q_v:
+  case NEON::BI__builtin_neon_vst4_v:
+  case NEON::BI__builtin_neon_vst4q_v:
+  case NEON::BI__builtin_neon_vst2_lane_v:
+  case NEON::BI__builtin_neon_vst2q_lane_v:
+  case NEON::BI__builtin_neon_vst3_lane_v:
+  case NEON::BI__builtin_neon_vst3q_lane_v:
+  case NEON::BI__builtin_neon_vst4_lane_v:
+  case NEON::BI__builtin_neon_vst4q_lane_v:
+    Ops.push_back(Align);
+    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "");
+  case NEON::BI__builtin_neon_vsubhn_v: {
+    llvm::VectorType *SrcTy =
+        llvm::VectorType::getExtendedElementVectorType(VTy);
+
+    // %sum = add <4 x i32> %lhs, %rhs
+    Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy);
+    Ops[1] = Builder.CreateBitCast(Ops[1], SrcTy);
+    Ops[0] = Builder.CreateSub(Ops[0], Ops[1], "vsubhn");
+
+    // %high = lshr <4 x i32> %sum, <i32 16, i32 16, i32 16, i32 16>
+    Constant *ShiftAmt = ConstantInt::get(SrcTy->getElementType(),
+                                       SrcTy->getScalarSizeInBits() / 2);
+    ShiftAmt = ConstantVector::getSplat(VTy->getNumElements(), ShiftAmt);
+    Ops[0] = Builder.CreateLShr(Ops[0], ShiftAmt, "vsubhn");
+
+    // %res = trunc <4 x i32> %high to <4 x i16>
+    return Builder.CreateTrunc(Ops[0], VTy, "vsubhn");
+  }
+  case NEON::BI__builtin_neon_vtrn_v:
+  case NEON::BI__builtin_neon_vtrnq_v: {
+    Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty));
+    Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
+    Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
+    Value *SV = nullptr;
+
+    for (unsigned vi = 0; vi != 2; ++vi) {
+      SmallVector<Constant*, 16> Indices;
+      for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) {
+        Indices.push_back(Builder.getInt32(i+vi));
+        Indices.push_back(Builder.getInt32(i+e+vi));
+      }
+      Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ops[0], vi);
+      SV = llvm::ConstantVector::get(Indices);
+      SV = Builder.CreateShuffleVector(Ops[1], Ops[2], SV, "vtrn");
+      SV = Builder.CreateStore(SV, Addr);
+    }
+    return SV;
+  }
+  case NEON::BI__builtin_neon_vtst_v:
+  case NEON::BI__builtin_neon_vtstq_v: {
+    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
+    Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
+    Ops[0] = Builder.CreateAnd(Ops[0], Ops[1]);
+    Ops[0] = Builder.CreateICmp(ICmpInst::ICMP_NE, Ops[0],
+                                ConstantAggregateZero::get(Ty));
+    return Builder.CreateSExt(Ops[0], Ty, "vtst");
+  }
+  case NEON::BI__builtin_neon_vuzp_v:
+  case NEON::BI__builtin_neon_vuzpq_v: {
+    Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty));
+    Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
+    Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
+    Value *SV = nullptr;
+
+    for (unsigned vi = 0; vi != 2; ++vi) {
+      SmallVector<Constant*, 16> Indices;
+      for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i)
+        Indices.push_back(ConstantInt::get(Int32Ty, 2*i+vi));
+
+      Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ops[0], vi);
+      SV = llvm::ConstantVector::get(Indices);
+      SV = Builder.CreateShuffleVector(Ops[1], Ops[2], SV, "vuzp");
+      SV = Builder.CreateStore(SV, Addr);
+    }
+    return SV;
+  }
+  case NEON::BI__builtin_neon_vzip_v:
+  case NEON::BI__builtin_neon_vzipq_v: {
+    Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty));
+    Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
+    Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
+    Value *SV = nullptr;
+
+    for (unsigned vi = 0; vi != 2; ++vi) {
+      SmallVector<Constant*, 16> Indices;
+      for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) {
+        Indices.push_back(ConstantInt::get(Int32Ty, (i + vi*e) >> 1));
+        Indices.push_back(ConstantInt::get(Int32Ty, ((i + vi*e) >> 1)+e));
+      }
+      Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ops[0], vi);
+      SV = llvm::ConstantVector::get(Indices);
+      SV = Builder.CreateShuffleVector(Ops[1], Ops[2], SV, "vzip");
+      SV = Builder.CreateStore(SV, Addr);
+    }
+    return SV;
+  }
+  }
+
+  assert(Int && "Expected valid intrinsic number");
+
+  // Determine the type(s) of this overloaded AArch64 intrinsic.
+  Function *F = LookupNeonLLVMIntrinsic(Int, Modifier, Ty, E);
+
+  Value *Result = EmitNeonCall(F, Ops, NameHint);
+  llvm::Type *ResultType = ConvertType(E->getType());
   // AArch64 intrinsic one-element vector type cast to
   // scalar type expected by the builtin
-  return CGF.Builder.CreateBitCast(Result, ResultType, s);
+  return Builder.CreateBitCast(Result, ResultType, NameHint);
 }
 
 Value *CodeGenFunction::EmitAArch64CompareBuiltinExpr(
     Value *Op, llvm::Type *Ty, const CmpInst::Predicate Fp,
     const CmpInst::Predicate Ip, const Twine &Name) {
-  llvm::Type *OTy = ((llvm::User *)Op)->getOperand(0)->getType();
-  if (OTy->isPointerTy())
-    OTy = Ty;
+  llvm::Type *OTy = Op->getType();
+
+  // FIXME: this is utterly horrific. We should not be looking at previous
+  // codegen context to find out what needs doing. Unfortunately TableGen
+  // currently gives us exactly the same calls for vceqz_f32 and vceqz_s32
+  // (etc).
+  if (BitCastInst *BI = dyn_cast<BitCastInst>(Op))
+    OTy = BI->getOperand(0)->getType();
+
   Op = Builder.CreateBitCast(Op, OTy);
-  if (((llvm::VectorType *)OTy)->getElementType()->isFloatingPointTy()) {
-    Op = Builder.CreateFCmp(Fp, Op, ConstantAggregateZero::get(OTy));
+  if (OTy->getScalarType()->isFloatingPointTy()) {
+    Op = Builder.CreateFCmp(Fp, Op, Constant::getNullValue(OTy));
   } else {
-    Op = Builder.CreateICmp(Ip, Op, ConstantAggregateZero::get(OTy));
+    Op = Builder.CreateICmp(Ip, Op, Constant::getNullValue(OTy));
   }
-  return Builder.CreateZExt(Op, Ty, Name);
+  return Builder.CreateSExt(Op, Ty, Name);
 }
 
 static Value *packTBLDVectorList(CodeGenFunction &CGF, ArrayRef<Value *> Ops,
@@ -2556,1208 +3055,54 @@
                                                      ZeroTbl, SV, Name));
   }
 
-  TblTy = llvm::VectorType::get(TblTy->getElementType(),
-                                2*TblTy->getNumElements());
-  llvm::Type *Tys[2] = { ResTy, TblTy };
-
   Function *TblF;
   TblOps.push_back(IndexOp);
-  TblF = CGF.CGM.getIntrinsic(IntID, Tys);
+  TblF = CGF.CGM.getIntrinsic(IntID, ResTy);
   
   return CGF.EmitNeonCall(TblF, TblOps, Name);
 }
 
-static Value *EmitAArch64TblBuiltinExpr(CodeGenFunction &CGF,
-                                        unsigned BuiltinID,
-                                        const CallExpr *E) {
-  unsigned int Int = 0;
-  const char *s = NULL;
-
-  unsigned TblPos;
-  switch (BuiltinID) {
-  default:
-    return 0;
-  case AArch64::BI__builtin_neon_vtbl1_v:
-  case AArch64::BI__builtin_neon_vqtbl1_v:
-  case AArch64::BI__builtin_neon_vqtbl1q_v:
-  case AArch64::BI__builtin_neon_vtbl2_v:
-  case AArch64::BI__builtin_neon_vqtbl2_v:
-  case AArch64::BI__builtin_neon_vqtbl2q_v:
-  case AArch64::BI__builtin_neon_vtbl3_v:
-  case AArch64::BI__builtin_neon_vqtbl3_v:
-  case AArch64::BI__builtin_neon_vqtbl3q_v:
-  case AArch64::BI__builtin_neon_vtbl4_v:
-  case AArch64::BI__builtin_neon_vqtbl4_v:
-  case AArch64::BI__builtin_neon_vqtbl4q_v:
-    TblPos = 0;
-    break;
-  case AArch64::BI__builtin_neon_vtbx1_v:
-  case AArch64::BI__builtin_neon_vqtbx1_v:
-  case AArch64::BI__builtin_neon_vqtbx1q_v:
-  case AArch64::BI__builtin_neon_vtbx2_v:
-  case AArch64::BI__builtin_neon_vqtbx2_v:
-  case AArch64::BI__builtin_neon_vqtbx2q_v:
-  case AArch64::BI__builtin_neon_vtbx3_v:
-  case AArch64::BI__builtin_neon_vqtbx3_v:
-  case AArch64::BI__builtin_neon_vqtbx3q_v:
-  case AArch64::BI__builtin_neon_vtbx4_v:
-  case AArch64::BI__builtin_neon_vqtbx4_v:
-  case AArch64::BI__builtin_neon_vqtbx4q_v:
-    TblPos = 1;
-    break;
-  }
-
-  assert(E->getNumArgs() >= 3);
-
-  // Get the last argument, which specifies the vector type.
-  llvm::APSInt Result;
-  const Expr *Arg = E->getArg(E->getNumArgs() - 1);
-  if (!Arg->isIntegerConstantExpr(Result, CGF.getContext()))
-    return 0;
-
-  // Determine the type of this overloaded NEON intrinsic.
-  NeonTypeFlags Type(Result.getZExtValue());
-  llvm::VectorType *VTy = GetNeonType(&CGF, Type);
-  llvm::Type *Ty = VTy;
-  if (!Ty)
-    return 0;
-
-  SmallVector<Value *, 4> Ops;
-  for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) {
-    Ops.push_back(CGF.EmitScalarExpr(E->getArg(i)));
-  }
-
-  Arg = E->getArg(TblPos);
-  llvm::Type *TblTy = CGF.ConvertType(Arg->getType());
-  llvm::VectorType *VTblTy = cast<llvm::VectorType>(TblTy);
-  llvm::Type *Tys[2] = { Ty, VTblTy };
-  unsigned nElts = VTy->getNumElements();  
-
-  // AArch64 scalar builtins are not overloaded, they do not have an extra
-  // argument that specifies the vector type, need to handle each case.
-  SmallVector<Value *, 2> TblOps;
-  switch (BuiltinID) {
-  case AArch64::BI__builtin_neon_vtbl1_v: {
-    TblOps.push_back(Ops[0]);
-    return packTBLDVectorList(CGF, TblOps, 0, Ops[1], Ty,
-                              Intrinsic::aarch64_neon_vtbl1, "vtbl1");
-  }
-  case AArch64::BI__builtin_neon_vtbl2_v: {
-    TblOps.push_back(Ops[0]);
-    TblOps.push_back(Ops[1]);
-    return packTBLDVectorList(CGF, TblOps, 0, Ops[2], Ty,
-                              Intrinsic::aarch64_neon_vtbl1, "vtbl1");
-  }
-  case AArch64::BI__builtin_neon_vtbl3_v: {
-    TblOps.push_back(Ops[0]);
-    TblOps.push_back(Ops[1]);
-    TblOps.push_back(Ops[2]);
-    return packTBLDVectorList(CGF, TblOps, 0, Ops[3], Ty,
-                              Intrinsic::aarch64_neon_vtbl2, "vtbl2");
-  }
-  case AArch64::BI__builtin_neon_vtbl4_v: {
-    TblOps.push_back(Ops[0]);
-    TblOps.push_back(Ops[1]);
-    TblOps.push_back(Ops[2]);
-    TblOps.push_back(Ops[3]);
-    return packTBLDVectorList(CGF, TblOps, 0, Ops[4], Ty,
-                              Intrinsic::aarch64_neon_vtbl2, "vtbl2");
-  }
-  case AArch64::BI__builtin_neon_vtbx1_v: {
-    TblOps.push_back(Ops[1]);
-    Value *TblRes = packTBLDVectorList(CGF, TblOps, 0, Ops[2], Ty,
-                                    Intrinsic::aarch64_neon_vtbl1, "vtbl1");
-
-    llvm::Constant *Eight = ConstantInt::get(VTy->getElementType(), 8);
-    Value* EightV = llvm::ConstantVector::getSplat(nElts, Eight);
-    Value *CmpRes = CGF.Builder.CreateICmp(ICmpInst::ICMP_UGE, Ops[2], EightV);
-    CmpRes = CGF.Builder.CreateSExt(CmpRes, Ty);
-
-    SmallVector<Value *, 4> BslOps;
-    BslOps.push_back(CmpRes);
-    BslOps.push_back(Ops[0]);
-    BslOps.push_back(TblRes);
-    Function *BslF = CGF.CGM.getIntrinsic(Intrinsic::arm_neon_vbsl, Ty);
-    return CGF.EmitNeonCall(BslF, BslOps, "vbsl");
-  }
-  case AArch64::BI__builtin_neon_vtbx2_v: {
-    TblOps.push_back(Ops[1]);
-    TblOps.push_back(Ops[2]);
-    return packTBLDVectorList(CGF, TblOps, Ops[0], Ops[3], Ty,
-                              Intrinsic::aarch64_neon_vtbx1, "vtbx1");
-  }
-  case AArch64::BI__builtin_neon_vtbx3_v: {
-    TblOps.push_back(Ops[1]);
-    TblOps.push_back(Ops[2]);
-    TblOps.push_back(Ops[3]);
-    Value *TblRes = packTBLDVectorList(CGF, TblOps, 0, Ops[4], Ty,
-                                       Intrinsic::aarch64_neon_vtbl2, "vtbl2");
-
-    llvm::Constant *TwentyFour = ConstantInt::get(VTy->getElementType(), 24);
-    Value* TwentyFourV = llvm::ConstantVector::getSplat(nElts, TwentyFour);
-    Value *CmpRes = CGF.Builder.CreateICmp(ICmpInst::ICMP_UGE, Ops[4],
-                                           TwentyFourV);
-    CmpRes = CGF.Builder.CreateSExt(CmpRes, Ty);
-  
-    SmallVector<Value *, 4> BslOps;
-    BslOps.push_back(CmpRes);
-    BslOps.push_back(Ops[0]);
-    BslOps.push_back(TblRes);
-    Function *BslF = CGF.CGM.getIntrinsic(Intrinsic::arm_neon_vbsl, Ty);
-    return CGF.EmitNeonCall(BslF, BslOps, "vbsl");
-  }
-  case AArch64::BI__builtin_neon_vtbx4_v: {
-    TblOps.push_back(Ops[1]);
-    TblOps.push_back(Ops[2]);
-    TblOps.push_back(Ops[3]);
-    TblOps.push_back(Ops[4]);
-    return packTBLDVectorList(CGF, TblOps, Ops[0], Ops[5], Ty,
-                              Intrinsic::aarch64_neon_vtbx2, "vtbx2");
-  }
-  case AArch64::BI__builtin_neon_vqtbl1_v:
-  case AArch64::BI__builtin_neon_vqtbl1q_v:
-    Int = Intrinsic::aarch64_neon_vtbl1; s = "vtbl1"; break;
-  case AArch64::BI__builtin_neon_vqtbl2_v:
-  case AArch64::BI__builtin_neon_vqtbl2q_v: {
-    Int = Intrinsic::aarch64_neon_vtbl2; s = "vtbl2"; break;
-  case AArch64::BI__builtin_neon_vqtbl3_v:
-  case AArch64::BI__builtin_neon_vqtbl3q_v:
-    Int = Intrinsic::aarch64_neon_vtbl3; s = "vtbl3"; break;
-  case AArch64::BI__builtin_neon_vqtbl4_v:
-  case AArch64::BI__builtin_neon_vqtbl4q_v:
-    Int = Intrinsic::aarch64_neon_vtbl4; s = "vtbl4"; break;
-  case AArch64::BI__builtin_neon_vqtbx1_v:
-  case AArch64::BI__builtin_neon_vqtbx1q_v:
-    Int = Intrinsic::aarch64_neon_vtbx1; s = "vtbx1"; break;
-  case AArch64::BI__builtin_neon_vqtbx2_v:
-  case AArch64::BI__builtin_neon_vqtbx2q_v:
-    Int = Intrinsic::aarch64_neon_vtbx2; s = "vtbx2"; break;
-  case AArch64::BI__builtin_neon_vqtbx3_v:
-  case AArch64::BI__builtin_neon_vqtbx3q_v:
-    Int = Intrinsic::aarch64_neon_vtbx3; s = "vtbx3"; break;
-  case AArch64::BI__builtin_neon_vqtbx4_v:
-  case AArch64::BI__builtin_neon_vqtbx4q_v:
-    Int = Intrinsic::aarch64_neon_vtbx4; s = "vtbx4"; break;
-  }
-  }
-
-  if (!Int)
-    return 0;
-
-  Function *F = CGF.CGM.getIntrinsic(Int, Tys);
-  return CGF.EmitNeonCall(F, Ops, s);
-}
-
-Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
-                                               const CallExpr *E) {
-  // Process AArch64 scalar builtins
-  if (Value *Result = EmitAArch64ScalarBuiltinExpr(*this, BuiltinID, E))
-    return Result;
-
-  // Process AArch64 table lookup builtins
-  if (Value *Result = EmitAArch64TblBuiltinExpr(*this, BuiltinID, E))
-    return Result;
-
-  if (BuiltinID == AArch64::BI__clear_cache) {
-    assert(E->getNumArgs() == 2 &&
-           "Variadic __clear_cache slipped through on AArch64");
-
-    const FunctionDecl *FD = E->getDirectCallee();
-    SmallVector<Value *, 2> Ops;
-    for (unsigned i = 0; i < E->getNumArgs(); i++)
-      Ops.push_back(EmitScalarExpr(E->getArg(i)));
-    llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType());
-    llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty);
-    StringRef Name = FD->getName();
-    return EmitNounwindRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Ops);
-  }
-
-  SmallVector<Value *, 4> Ops;
-  llvm::Value *Align = 0; // Alignment for load/store
-  for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) {
-    if (i == 0) {
-      switch (BuiltinID) {
-      case AArch64::BI__builtin_neon_vst1_x2_v:
-      case AArch64::BI__builtin_neon_vst1q_x2_v:
-      case AArch64::BI__builtin_neon_vst1_x3_v:
-      case AArch64::BI__builtin_neon_vst1q_x3_v:
-      case AArch64::BI__builtin_neon_vst1_x4_v:
-      case AArch64::BI__builtin_neon_vst1q_x4_v:
-      // Handle ld1/st1 lane in this function a little different from ARM.
-      case AArch64::BI__builtin_neon_vld1_lane_v:
-      case AArch64::BI__builtin_neon_vld1q_lane_v:
-      case AArch64::BI__builtin_neon_vst1_lane_v:
-      case AArch64::BI__builtin_neon_vst1q_lane_v:
-        // Get the alignment for the argument in addition to the value;
-        // we'll use it later.
-        std::pair<llvm::Value *, unsigned> Src =
-            EmitPointerWithAlignment(E->getArg(0));
-        Ops.push_back(Src.first);
-        Align = Builder.getInt32(Src.second);
-        continue;
-      }
-    }
-    if (i == 1) {
-      switch (BuiltinID) {
-      case AArch64::BI__builtin_neon_vld1_x2_v:
-      case AArch64::BI__builtin_neon_vld1q_x2_v:
-      case AArch64::BI__builtin_neon_vld1_x3_v:
-      case AArch64::BI__builtin_neon_vld1q_x3_v:
-      case AArch64::BI__builtin_neon_vld1_x4_v:
-      case AArch64::BI__builtin_neon_vld1q_x4_v:
-      // Handle ld1/st1 dup lane in this function a little different from ARM.
-      case AArch64::BI__builtin_neon_vld2_dup_v:
-      case AArch64::BI__builtin_neon_vld2q_dup_v:
-      case AArch64::BI__builtin_neon_vld3_dup_v:
-      case AArch64::BI__builtin_neon_vld3q_dup_v:
-      case AArch64::BI__builtin_neon_vld4_dup_v:
-      case AArch64::BI__builtin_neon_vld4q_dup_v:
-      case AArch64::BI__builtin_neon_vld2_lane_v:
-      case AArch64::BI__builtin_neon_vld2q_lane_v:
-        // Get the alignment for the argument in addition to the value;
-        // we'll use it later.
-        std::pair<llvm::Value *, unsigned> Src =
-            EmitPointerWithAlignment(E->getArg(1));
-        Ops.push_back(Src.first);
-        Align = Builder.getInt32(Src.second);
-        continue;
-      }
-    }
-    Ops.push_back(EmitScalarExpr(E->getArg(i)));
-  }
-
-  // Get the last argument, which specifies the vector type.
-  llvm::APSInt Result;
-  const Expr *Arg = E->getArg(E->getNumArgs() - 1);
-  if (!Arg->isIntegerConstantExpr(Result, getContext()))
-    return 0;
-
-  // Determine the type of this overloaded NEON intrinsic.
-  NeonTypeFlags Type(Result.getZExtValue());
-  bool usgn = Type.isUnsigned();
-
-  llvm::VectorType *VTy = GetNeonType(this, Type);
-  llvm::Type *Ty = VTy;
-  if (!Ty)
-    return 0;
-
-  unsigned Int;
-  switch (BuiltinID) {
-  default:
-    return 0;
-
-  // AArch64 builtins mapping to legacy ARM v7 builtins.
-  // FIXME: the mapped builtins listed correspond to what has been tested
-  // in aarch64-neon-intrinsics.c so far.
-  case AArch64::BI__builtin_neon_vuzp_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vuzp_v, E);
-  case AArch64::BI__builtin_neon_vuzpq_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vuzpq_v, E);
-  case AArch64::BI__builtin_neon_vzip_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vzip_v, E);
-  case AArch64::BI__builtin_neon_vzipq_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vzipq_v, E);
-  case AArch64::BI__builtin_neon_vtrn_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vtrn_v, E);
-  case AArch64::BI__builtin_neon_vtrnq_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vtrnq_v, E);
-  case AArch64::BI__builtin_neon_vext_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vext_v, E);
-  case AArch64::BI__builtin_neon_vextq_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vextq_v, E);
-  case AArch64::BI__builtin_neon_vmul_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vmul_v, E);
-  case AArch64::BI__builtin_neon_vmulq_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vmulq_v, E);
-  case AArch64::BI__builtin_neon_vabd_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vabd_v, E);
-  case AArch64::BI__builtin_neon_vabdq_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vabdq_v, E);
-  case AArch64::BI__builtin_neon_vfma_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vfma_v, E);
-  case AArch64::BI__builtin_neon_vfmaq_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vfmaq_v, E);
-  case AArch64::BI__builtin_neon_vbsl_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vbsl_v, E);
-  case AArch64::BI__builtin_neon_vbslq_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vbslq_v, E);
-  case AArch64::BI__builtin_neon_vrsqrts_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrsqrts_v, E);
-  case AArch64::BI__builtin_neon_vrsqrtsq_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrsqrtsq_v, E);
-  case AArch64::BI__builtin_neon_vrecps_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrecps_v, E);
-  case AArch64::BI__builtin_neon_vrecpsq_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrecpsq_v, E);
-  case AArch64::BI__builtin_neon_vcage_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcage_v, E);
-  case AArch64::BI__builtin_neon_vcale_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcale_v, E);
-  case AArch64::BI__builtin_neon_vcaleq_v:
-    std::swap(Ops[0], Ops[1]);
-  case AArch64::BI__builtin_neon_vcageq_v: {
-    Function *F;
-    if (VTy->getElementType()->isIntegerTy(64))
-      F = CGM.getIntrinsic(Intrinsic::aarch64_neon_vacgeq);
-    else
-      F = CGM.getIntrinsic(Intrinsic::arm_neon_vacgeq);
-    return EmitNeonCall(F, Ops, "vcage");
-  }
-  case AArch64::BI__builtin_neon_vcalt_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcalt_v, E);
-  case AArch64::BI__builtin_neon_vcagt_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcagt_v, E);
-  case AArch64::BI__builtin_neon_vcaltq_v:
-    std::swap(Ops[0], Ops[1]);
-  case AArch64::BI__builtin_neon_vcagtq_v: {
-    Function *F;
-    if (VTy->getElementType()->isIntegerTy(64))
-      F = CGM.getIntrinsic(Intrinsic::aarch64_neon_vacgtq);
-    else
-      F = CGM.getIntrinsic(Intrinsic::arm_neon_vacgtq);
-    return EmitNeonCall(F, Ops, "vcagt");
-  }
-  case AArch64::BI__builtin_neon_vtst_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vtst_v, E);
-  case AArch64::BI__builtin_neon_vtstq_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vtstq_v, E);
-  case AArch64::BI__builtin_neon_vhadd_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vhadd_v, E);
-  case AArch64::BI__builtin_neon_vhaddq_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vhaddq_v, E);
-  case AArch64::BI__builtin_neon_vhsub_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vhsub_v, E);
-  case AArch64::BI__builtin_neon_vhsubq_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vhsubq_v, E);
-  case AArch64::BI__builtin_neon_vrhadd_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrhadd_v, E);
-  case AArch64::BI__builtin_neon_vrhaddq_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrhaddq_v, E);
-  case AArch64::BI__builtin_neon_vqadd_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqadd_v, E);
-  case AArch64::BI__builtin_neon_vqaddq_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqaddq_v, E);
-  case AArch64::BI__builtin_neon_vqsub_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqsub_v, E);
-  case AArch64::BI__builtin_neon_vqsubq_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqsubq_v, E);
-  case AArch64::BI__builtin_neon_vshl_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vshl_v, E);
-  case AArch64::BI__builtin_neon_vshlq_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vshlq_v, E);
-  case AArch64::BI__builtin_neon_vqshl_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqshl_v, E);
-  case AArch64::BI__builtin_neon_vqshlq_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqshlq_v, E);
-  case AArch64::BI__builtin_neon_vrshl_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrshl_v, E);
-  case AArch64::BI__builtin_neon_vrshlq_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrshlq_v, E);
-  case AArch64::BI__builtin_neon_vqrshl_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqrshl_v, E);
-  case AArch64::BI__builtin_neon_vqrshlq_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqrshlq_v, E);
-  case AArch64::BI__builtin_neon_vaddhn_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vaddhn_v, E);
-  case AArch64::BI__builtin_neon_vraddhn_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vraddhn_v, E);
-  case AArch64::BI__builtin_neon_vsubhn_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vsubhn_v, E);
-  case AArch64::BI__builtin_neon_vrsubhn_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrsubhn_v, E);
-  case AArch64::BI__builtin_neon_vmull_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vmull_v, E);
-  case AArch64::BI__builtin_neon_vqdmull_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqdmull_v, E);
-  case AArch64::BI__builtin_neon_vqdmlal_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqdmlal_v, E);
-  case AArch64::BI__builtin_neon_vqdmlsl_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqdmlsl_v, E);
-  case AArch64::BI__builtin_neon_vmax_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vmax_v, E);
-  case AArch64::BI__builtin_neon_vmaxq_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vmaxq_v, E);
-  case AArch64::BI__builtin_neon_vmin_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vmin_v, E);
-  case AArch64::BI__builtin_neon_vminq_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vminq_v, E);
-  case AArch64::BI__builtin_neon_vpmax_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vpmax_v, E);
-  case AArch64::BI__builtin_neon_vpmin_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vpmin_v, E);
-  case AArch64::BI__builtin_neon_vpadd_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vpadd_v, E);
-  case AArch64::BI__builtin_neon_vqdmulh_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqdmulh_v, E);
-  case AArch64::BI__builtin_neon_vqdmulhq_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqdmulhq_v, E);
-  case AArch64::BI__builtin_neon_vqrdmulh_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqrdmulh_v, E);
-  case AArch64::BI__builtin_neon_vqrdmulhq_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqrdmulhq_v, E);
-
-  // Shift by immediate
-  case AArch64::BI__builtin_neon_vshr_n_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vshr_n_v, E);
-  case AArch64::BI__builtin_neon_vshrq_n_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vshrq_n_v, E);
-  case AArch64::BI__builtin_neon_vrshr_n_v:
-  case AArch64::BI__builtin_neon_vrshrq_n_v:
-    Int = usgn ? Intrinsic::aarch64_neon_vurshr
-               : Intrinsic::aarch64_neon_vsrshr;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshr_n");
-  case AArch64::BI__builtin_neon_vsra_n_v:
-    if (VTy->getElementType()->isIntegerTy(64)) {
-      Int = usgn ? Intrinsic::aarch64_neon_vsradu_n
-                 : Intrinsic::aarch64_neon_vsrads_n;
-      return EmitNeonCall(CGM.getIntrinsic(Int), Ops, "vsra_n");
-    }
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vsra_n_v, E);
-  case AArch64::BI__builtin_neon_vsraq_n_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vsraq_n_v, E);
-  case AArch64::BI__builtin_neon_vrsra_n_v:
-    if (VTy->getElementType()->isIntegerTy(64)) {
-      Int = usgn ? Intrinsic::aarch64_neon_vrsradu_n
-                 : Intrinsic::aarch64_neon_vrsrads_n;
-      return EmitNeonCall(CGM.getIntrinsic(Int), Ops, "vrsra_n");
-    }
-    // fall through
-  case AArch64::BI__builtin_neon_vrsraq_n_v: {
-    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
-    Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
-    Int = usgn ? Intrinsic::aarch64_neon_vurshr
-               : Intrinsic::aarch64_neon_vsrshr;
-    Ops[1] = Builder.CreateCall2(CGM.getIntrinsic(Int, Ty), Ops[1], Ops[2]);
-    return Builder.CreateAdd(Ops[0], Ops[1], "vrsra_n");
-  }
-  case AArch64::BI__builtin_neon_vshl_n_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vshl_n_v, E);
-  case AArch64::BI__builtin_neon_vshlq_n_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vshlq_n_v, E);
-  case AArch64::BI__builtin_neon_vqshl_n_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqshl_n_v, E);
-  case AArch64::BI__builtin_neon_vqshlq_n_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqshlq_n_v, E);
-  case AArch64::BI__builtin_neon_vqshlu_n_v:
-  case AArch64::BI__builtin_neon_vqshluq_n_v:
-    Int = Intrinsic::aarch64_neon_vsqshlu;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshlu_n");
-  case AArch64::BI__builtin_neon_vsri_n_v:
-  case AArch64::BI__builtin_neon_vsriq_n_v:
-    Int = Intrinsic::aarch64_neon_vsri;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsri_n");
-  case AArch64::BI__builtin_neon_vsli_n_v:
-  case AArch64::BI__builtin_neon_vsliq_n_v:
-    Int = Intrinsic::aarch64_neon_vsli;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsli_n");
-  case AArch64::BI__builtin_neon_vshll_n_v: {
-    llvm::Type *SrcTy = llvm::VectorType::getTruncatedElementVectorType(VTy);
-    Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy);
-    if (usgn)
-      Ops[0] = Builder.CreateZExt(Ops[0], VTy);
-    else
-      Ops[0] = Builder.CreateSExt(Ops[0], VTy);
-    Ops[1] = EmitNeonShiftVector(Ops[1], VTy, false);
-    return Builder.CreateShl(Ops[0], Ops[1], "vshll_n");
-  }
-  case AArch64::BI__builtin_neon_vshrn_n_v: {
-    llvm::Type *SrcTy = llvm::VectorType::getExtendedElementVectorType(VTy);
-    Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy);
-    Ops[1] = EmitNeonShiftVector(Ops[1], SrcTy, false);
-    if (usgn)
-      Ops[0] = Builder.CreateLShr(Ops[0], Ops[1]);
-    else
-      Ops[0] = Builder.CreateAShr(Ops[0], Ops[1]);
-    return Builder.CreateTrunc(Ops[0], Ty, "vshrn_n");
-  }
-  case AArch64::BI__builtin_neon_vqshrun_n_v:
-    Int = Intrinsic::aarch64_neon_vsqshrun;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrun_n");
-  case AArch64::BI__builtin_neon_vrshrn_n_v:
-    Int = Intrinsic::aarch64_neon_vrshrn;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshrn_n");
-  case AArch64::BI__builtin_neon_vqrshrun_n_v:
-    Int = Intrinsic::aarch64_neon_vsqrshrun;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrun_n");
-  case AArch64::BI__builtin_neon_vqshrn_n_v:
-    Int = usgn ? Intrinsic::aarch64_neon_vuqshrn
-               : Intrinsic::aarch64_neon_vsqshrn;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrn_n");
-  case AArch64::BI__builtin_neon_vqrshrn_n_v:
-    Int = usgn ? Intrinsic::aarch64_neon_vuqrshrn
-               : Intrinsic::aarch64_neon_vsqrshrn;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrn_n");
-
-  // Convert
-  case AArch64::BI__builtin_neon_vmovl_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vmovl_v, E);
-  case AArch64::BI__builtin_neon_vcvt_n_f32_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcvt_n_f32_v, E);
-  case AArch64::BI__builtin_neon_vcvtq_n_f32_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcvtq_n_f32_v, E);
-  case AArch64::BI__builtin_neon_vcvtq_n_f64_v: {
-    llvm::Type *FloatTy =
-        GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float64, false, true));
-    llvm::Type *Tys[2] = { FloatTy, Ty };
-    Int = usgn ? Intrinsic::arm_neon_vcvtfxu2fp
-               : Intrinsic::arm_neon_vcvtfxs2fp;
-    Function *F = CGM.getIntrinsic(Int, Tys);
-    return EmitNeonCall(F, Ops, "vcvt_n");
-  }
-  case AArch64::BI__builtin_neon_vcvt_n_s32_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcvt_n_s32_v, E);
-  case AArch64::BI__builtin_neon_vcvtq_n_s32_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcvtq_n_s32_v, E);
-  case AArch64::BI__builtin_neon_vcvt_n_u32_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcvt_n_u32_v, E);
-  case AArch64::BI__builtin_neon_vcvtq_n_u32_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcvtq_n_u32_v, E);
-  case AArch64::BI__builtin_neon_vcvtq_n_s64_v:
-  case AArch64::BI__builtin_neon_vcvtq_n_u64_v: {
-    llvm::Type *FloatTy =
-        GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float64, false, true));
-    llvm::Type *Tys[2] = { Ty, FloatTy };
-    Int = usgn ? Intrinsic::arm_neon_vcvtfp2fxu
-               : Intrinsic::arm_neon_vcvtfp2fxs;
-    Function *F = CGM.getIntrinsic(Int, Tys);
-    return EmitNeonCall(F, Ops, "vcvt_n");
-  }
-
-  // Load/Store
-  case AArch64::BI__builtin_neon_vld1_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vld1_v, E);
-  case AArch64::BI__builtin_neon_vld1q_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vld1q_v, E);
-  case AArch64::BI__builtin_neon_vld2_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vld2_v, E);
-  case AArch64::BI__builtin_neon_vld2q_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vld2q_v, E);
-  case AArch64::BI__builtin_neon_vld3_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vld3_v, E);
-  case AArch64::BI__builtin_neon_vld3q_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vld3q_v, E);
-  case AArch64::BI__builtin_neon_vld4_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vld4_v, E);
-  case AArch64::BI__builtin_neon_vld4q_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vld4q_v, E);
-  case AArch64::BI__builtin_neon_vst1_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vst1_v, E);
-  case AArch64::BI__builtin_neon_vst1q_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vst1q_v, E);
-  case AArch64::BI__builtin_neon_vst2_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vst2_v, E);
-  case AArch64::BI__builtin_neon_vst2q_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vst2q_v, E);
-  case AArch64::BI__builtin_neon_vst3_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vst3_v, E);
-  case AArch64::BI__builtin_neon_vst3q_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vst3q_v, E);
-  case AArch64::BI__builtin_neon_vst4_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vst4_v, E);
-  case AArch64::BI__builtin_neon_vst4q_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vst4q_v, E);
-  case AArch64::BI__builtin_neon_vld1_x2_v:
-  case AArch64::BI__builtin_neon_vld1q_x2_v:
-  case AArch64::BI__builtin_neon_vld1_x3_v:
-  case AArch64::BI__builtin_neon_vld1q_x3_v:
-  case AArch64::BI__builtin_neon_vld1_x4_v:
-  case AArch64::BI__builtin_neon_vld1q_x4_v: {
-    unsigned Int;
-    switch (BuiltinID) {
-    case AArch64::BI__builtin_neon_vld1_x2_v:
-    case AArch64::BI__builtin_neon_vld1q_x2_v:
-      Int = Intrinsic::aarch64_neon_vld1x2;
-      break;
-    case AArch64::BI__builtin_neon_vld1_x3_v:
-    case AArch64::BI__builtin_neon_vld1q_x3_v:
-      Int = Intrinsic::aarch64_neon_vld1x3;
-      break;
-    case AArch64::BI__builtin_neon_vld1_x4_v:
-    case AArch64::BI__builtin_neon_vld1q_x4_v:
-      Int = Intrinsic::aarch64_neon_vld1x4;
-      break;
-    }
-    Function *F = CGM.getIntrinsic(Int, Ty);
-    Ops[1] = Builder.CreateCall2(F, Ops[1], Align, "vld1xN");
-    Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
-    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
-    return Builder.CreateStore(Ops[1], Ops[0]);
-  }
-  case AArch64::BI__builtin_neon_vst1_x2_v:
-  case AArch64::BI__builtin_neon_vst1q_x2_v:
-  case AArch64::BI__builtin_neon_vst1_x3_v:
-  case AArch64::BI__builtin_neon_vst1q_x3_v:
-  case AArch64::BI__builtin_neon_vst1_x4_v:
-  case AArch64::BI__builtin_neon_vst1q_x4_v: {
-    Ops.push_back(Align);
-    unsigned Int;
-    switch (BuiltinID) {
-    case AArch64::BI__builtin_neon_vst1_x2_v:
-    case AArch64::BI__builtin_neon_vst1q_x2_v:
-      Int = Intrinsic::aarch64_neon_vst1x2;
-      break;
-    case AArch64::BI__builtin_neon_vst1_x3_v:
-    case AArch64::BI__builtin_neon_vst1q_x3_v:
-      Int = Intrinsic::aarch64_neon_vst1x3;
-      break;
-    case AArch64::BI__builtin_neon_vst1_x4_v:
-    case AArch64::BI__builtin_neon_vst1q_x4_v:
-      Int = Intrinsic::aarch64_neon_vst1x4;
-      break;
-    }
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "");
-  }
-  case AArch64::BI__builtin_neon_vld1_lane_v:
-  case AArch64::BI__builtin_neon_vld1q_lane_v: {
-    Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
-    Ty = llvm::PointerType::getUnqual(VTy->getElementType());
-    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
-    LoadInst *Ld = Builder.CreateLoad(Ops[0]);
-    Ld->setAlignment(cast<ConstantInt>(Align)->getZExtValue());
-    return Builder.CreateInsertElement(Ops[1], Ld, Ops[2], "vld1_lane");
-  }
-  case AArch64::BI__builtin_neon_vld2_lane_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vld2q_lane_v, E);
-  case AArch64::BI__builtin_neon_vld2q_lane_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vld2q_lane_v, E);
-  case AArch64::BI__builtin_neon_vld3_lane_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vld3_lane_v, E);
-  case AArch64::BI__builtin_neon_vld3q_lane_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vld3q_lane_v, E);
-  case AArch64::BI__builtin_neon_vld4_lane_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vld4_lane_v, E);
-  case AArch64::BI__builtin_neon_vld4q_lane_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vld4q_lane_v, E);
-  case AArch64::BI__builtin_neon_vst1_lane_v:
-  case AArch64::BI__builtin_neon_vst1q_lane_v: {
-    Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
-    Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2]);
-    Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
-    StoreInst *St =
-        Builder.CreateStore(Ops[1], Builder.CreateBitCast(Ops[0], Ty));
-    St->setAlignment(cast<ConstantInt>(Align)->getZExtValue());
-    return St;
-  }
-  case AArch64::BI__builtin_neon_vst2_lane_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vst2_lane_v, E);
-  case AArch64::BI__builtin_neon_vst2q_lane_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vst2q_lane_v, E);
-  case AArch64::BI__builtin_neon_vst3_lane_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vst3_lane_v, E);
-  case AArch64::BI__builtin_neon_vst3q_lane_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vst3q_lane_v, E);
-  case AArch64::BI__builtin_neon_vst4_lane_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vst4_lane_v, E);
-  case AArch64::BI__builtin_neon_vst4q_lane_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vst4q_lane_v, E);
-  case AArch64::BI__builtin_neon_vld1_dup_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vld1_dup_v, E);
-  case AArch64::BI__builtin_neon_vld1q_dup_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vld1q_dup_v, E);
-  case AArch64::BI__builtin_neon_vld2_dup_v:
-  case AArch64::BI__builtin_neon_vld2q_dup_v:
-  case AArch64::BI__builtin_neon_vld3_dup_v:
-  case AArch64::BI__builtin_neon_vld3q_dup_v:
-  case AArch64::BI__builtin_neon_vld4_dup_v:
-  case AArch64::BI__builtin_neon_vld4q_dup_v: {
-    // Handle 64-bit x 1 elements as a special-case.  There is no "dup" needed.
-    if (VTy->getElementType()->getPrimitiveSizeInBits() == 64 &&
-        VTy->getNumElements() == 1) {
-      switch (BuiltinID) {
-      case AArch64::BI__builtin_neon_vld2_dup_v:
-        Int = Intrinsic::arm_neon_vld2;
-        break;
-      case AArch64::BI__builtin_neon_vld3_dup_v:
-        Int = Intrinsic::arm_neon_vld3;
-        break;
-      case AArch64::BI__builtin_neon_vld4_dup_v:
-        Int = Intrinsic::arm_neon_vld4;
-        break;
-      default:
-        llvm_unreachable("unknown vld_dup intrinsic?");
-      }
-      Function *F = CGM.getIntrinsic(Int, Ty);
-      Ops[1] = Builder.CreateCall2(F, Ops[1], Align, "vld_dup");
-      Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
-      Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
-      return Builder.CreateStore(Ops[1], Ops[0]);
-    }
-    switch (BuiltinID) {
-    case AArch64::BI__builtin_neon_vld2_dup_v:
-    case AArch64::BI__builtin_neon_vld2q_dup_v:
-      Int = Intrinsic::arm_neon_vld2lane;
-      break;
-    case AArch64::BI__builtin_neon_vld3_dup_v:
-    case AArch64::BI__builtin_neon_vld3q_dup_v:
-      Int = Intrinsic::arm_neon_vld3lane;
-      break;
-    case AArch64::BI__builtin_neon_vld4_dup_v:
-    case AArch64::BI__builtin_neon_vld4q_dup_v:
-      Int = Intrinsic::arm_neon_vld4lane;
-      break;
-    }
-    Function *F = CGM.getIntrinsic(Int, Ty);
-    llvm::StructType *STy = cast<llvm::StructType>(F->getReturnType());
-
-    SmallVector<Value *, 6> Args;
-    Args.push_back(Ops[1]);
-    Args.append(STy->getNumElements(), UndefValue::get(Ty));
-
-    llvm::Constant *CI = ConstantInt::get(Int32Ty, 0);
-    Args.push_back(CI);
-    Args.push_back(Align);
-
-    Ops[1] = Builder.CreateCall(F, Args, "vld_dup");
-    // splat lane 0 to all elts in each vector of the result.
-    for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
-      Value *Val = Builder.CreateExtractValue(Ops[1], i);
-      Value *Elt = Builder.CreateBitCast(Val, Ty);
-      Elt = EmitNeonSplat(Elt, CI);
-      Elt = Builder.CreateBitCast(Elt, Val->getType());
-      Ops[1] = Builder.CreateInsertValue(Ops[1], Elt, i);
-    }
-    Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
-    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
-    return Builder.CreateStore(Ops[1], Ops[0]);
-  }
-
-  // Crypto
-  case AArch64::BI__builtin_neon_vaeseq_v:
-    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_aese, Ty),
-                        Ops, "aese");
-  case AArch64::BI__builtin_neon_vaesdq_v:
-    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_aesd, Ty),
-                        Ops, "aesd");
-  case AArch64::BI__builtin_neon_vaesmcq_v:
-    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_aesmc, Ty),
-                        Ops, "aesmc");
-  case AArch64::BI__builtin_neon_vaesimcq_v:
-    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_aesimc, Ty),
-                        Ops, "aesimc");
-  case AArch64::BI__builtin_neon_vsha1su1q_v:
-    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1su1, Ty),
-                        Ops, "sha1su1");
-  case AArch64::BI__builtin_neon_vsha256su0q_v:
-    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha256su0, Ty),
-                        Ops, "sha256su0");
-  case AArch64::BI__builtin_neon_vsha1su0q_v:
-    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1su0, Ty),
-                        Ops, "sha1su0");
-  case AArch64::BI__builtin_neon_vsha256hq_v:
-    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha256h, Ty),
-                        Ops, "sha256h");
-  case AArch64::BI__builtin_neon_vsha256h2q_v:
-    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha256h2, Ty),
-                        Ops, "sha256h2");
-  case AArch64::BI__builtin_neon_vsha256su1q_v:
-    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha256su1, Ty),
-                        Ops, "sha256su1");
-  case AArch64::BI__builtin_neon_vmul_lane_v:
-  case AArch64::BI__builtin_neon_vmul_laneq_v: {
-    // v1f64 vmul_lane should be mapped to Neon scalar mul lane
-    bool Quad = false;
-    if (BuiltinID == AArch64::BI__builtin_neon_vmul_laneq_v)
-      Quad = true;
-    Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy);
-    llvm::Type *VTy = GetNeonType(this,
-      NeonTypeFlags(NeonTypeFlags::Float64, false, Quad ? true : false));
-    Ops[1] = Builder.CreateBitCast(Ops[1], VTy);
-    Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2], "extract");
-    Value *Result = Builder.CreateFMul(Ops[0], Ops[1]);
-    return Builder.CreateBitCast(Result, Ty);
-  }
-
-  // AArch64-only builtins
-  case AArch64::BI__builtin_neon_vfmaq_laneq_v: {
-    Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty);
-    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
-    Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
-
-    Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
-    Ops[2] = EmitNeonSplat(Ops[2], cast<ConstantInt>(Ops[3]));
-    return Builder.CreateCall3(F, Ops[2], Ops[1], Ops[0]);
-  }
-  case AArch64::BI__builtin_neon_vfmaq_lane_v: {
-    Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty);
-    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
-    Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
-
-    llvm::VectorType *VTy = cast<llvm::VectorType>(Ty);
-    llvm::Type *STy = llvm::VectorType::get(VTy->getElementType(),
-                                            VTy->getNumElements() / 2);
-    Ops[2] = Builder.CreateBitCast(Ops[2], STy);
-    Value* SV = llvm::ConstantVector::getSplat(VTy->getNumElements(),
-                                               cast<ConstantInt>(Ops[3]));
-    Ops[2] = Builder.CreateShuffleVector(Ops[2], Ops[2], SV, "lane");
-
-    return Builder.CreateCall3(F, Ops[2], Ops[1], Ops[0]);
-  }
-  case AArch64::BI__builtin_neon_vfma_lane_v: {
-    llvm::VectorType *VTy = cast<llvm::VectorType>(Ty);
-    // v1f64 fma should be mapped to Neon scalar f64 fma
-    if (VTy && VTy->getElementType() == DoubleTy) {
-      Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy);
-      Ops[1] = Builder.CreateBitCast(Ops[1], DoubleTy);
-      llvm::Type *VTy = GetNeonType(this,
-        NeonTypeFlags(NeonTypeFlags::Float64, false, false));
-      Ops[2] = Builder.CreateBitCast(Ops[2], VTy);
-      Ops[2] = Builder.CreateExtractElement(Ops[2], Ops[3], "extract");
-      Value *F = CGM.getIntrinsic(Intrinsic::fma, DoubleTy);
-      Value *Result = Builder.CreateCall3(F, Ops[1], Ops[2], Ops[0]);
-      return Builder.CreateBitCast(Result, Ty);
-    }
-    Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty);
-    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
-    Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
-
-    Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
-    Ops[2] = EmitNeonSplat(Ops[2], cast<ConstantInt>(Ops[3]));
-    return Builder.CreateCall3(F, Ops[2], Ops[1], Ops[0]);
-  }
-  case AArch64::BI__builtin_neon_vfma_laneq_v: {
-    llvm::VectorType *VTy = cast<llvm::VectorType>(Ty);
-    // v1f64 fma should be mapped to Neon scalar f64 fma
-    if (VTy && VTy->getElementType() == DoubleTy) {
-      Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy);
-      Ops[1] = Builder.CreateBitCast(Ops[1], DoubleTy);
-      llvm::Type *VTy = GetNeonType(this,
-        NeonTypeFlags(NeonTypeFlags::Float64, false, true));
-      Ops[2] = Builder.CreateBitCast(Ops[2], VTy);
-      Ops[2] = Builder.CreateExtractElement(Ops[2], Ops[3], "extract");
-      Value *F = CGM.getIntrinsic(Intrinsic::fma, DoubleTy);
-      Value *Result = Builder.CreateCall3(F, Ops[1], Ops[2], Ops[0]);
-      return Builder.CreateBitCast(Result, Ty);
-    }
-    Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty);
-    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
-    Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
-
-    llvm::Type *STy = llvm::VectorType::get(VTy->getElementType(),
-                                            VTy->getNumElements() * 2);
-    Ops[2] = Builder.CreateBitCast(Ops[2], STy);
-    Value* SV = llvm::ConstantVector::getSplat(VTy->getNumElements(),
-                                               cast<ConstantInt>(Ops[3]));
-    Ops[2] = Builder.CreateShuffleVector(Ops[2], Ops[2], SV, "lane");
-
-    return Builder.CreateCall3(F, Ops[2], Ops[1], Ops[0]);
-  }
-  case AArch64::BI__builtin_neon_vfms_v:
-  case AArch64::BI__builtin_neon_vfmsq_v: {
-    Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty);
-    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
-    Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
-    Ops[1] = Builder.CreateFNeg(Ops[1]);
-    Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
-
-    // LLVM's fma intrinsic puts the accumulator in the last position, but the
-    // AArch64 intrinsic has it first.
-    return Builder.CreateCall3(F, Ops[1], Ops[2], Ops[0]);
-  }
-  case AArch64::BI__builtin_neon_vmaxnm_v:
-  case AArch64::BI__builtin_neon_vmaxnmq_v: {
-    Int = Intrinsic::aarch64_neon_vmaxnm;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmaxnm");
-  }
-  case AArch64::BI__builtin_neon_vminnm_v:
-  case AArch64::BI__builtin_neon_vminnmq_v: {
-    Int = Intrinsic::aarch64_neon_vminnm;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vminnm");
-  }
-  case AArch64::BI__builtin_neon_vpmaxnm_v:
-  case AArch64::BI__builtin_neon_vpmaxnmq_v: {
-    Int = Intrinsic::aarch64_neon_vpmaxnm;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmaxnm");
-  }
-  case AArch64::BI__builtin_neon_vpminnm_v:
-  case AArch64::BI__builtin_neon_vpminnmq_v: {
-    Int = Intrinsic::aarch64_neon_vpminnm;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpminnm");
-  }
-  case AArch64::BI__builtin_neon_vpmaxq_v: {
-    Int = usgn ? Intrinsic::arm_neon_vpmaxu : Intrinsic::arm_neon_vpmaxs;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmax");
-  }
-  case AArch64::BI__builtin_neon_vpminq_v: {
-    Int = usgn ? Intrinsic::arm_neon_vpminu : Intrinsic::arm_neon_vpmins;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmin");
-  }
-  case AArch64::BI__builtin_neon_vpaddq_v: {
-    Int = Intrinsic::arm_neon_vpadd;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpadd");
-  }
-  case AArch64::BI__builtin_neon_vmulx_v:
-  case AArch64::BI__builtin_neon_vmulxq_v: {
-    Int = Intrinsic::aarch64_neon_vmulx;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmulx");
-  }
-  case AArch64::BI__builtin_neon_vpaddl_v:
-  case AArch64::BI__builtin_neon_vpaddlq_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vpaddl_v, E);
-  case AArch64::BI__builtin_neon_vpadal_v:
-  case AArch64::BI__builtin_neon_vpadalq_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vpadal_v, E);
-  case AArch64::BI__builtin_neon_vqabs_v:
-  case AArch64::BI__builtin_neon_vqabsq_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqabs_v, E);
-  case AArch64::BI__builtin_neon_vqneg_v:
-  case AArch64::BI__builtin_neon_vqnegq_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqneg_v, E);
-  case AArch64::BI__builtin_neon_vabs_v:
-  case AArch64::BI__builtin_neon_vabsq_v: {
-    if (VTy->getElementType()->isFloatingPointTy()) {
-      return EmitNeonCall(CGM.getIntrinsic(Intrinsic::fabs, Ty), Ops, "vabs");
-    }
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vabs_v, E);
-  }
-  case AArch64::BI__builtin_neon_vsqadd_v:
-  case AArch64::BI__builtin_neon_vsqaddq_v: {
-    Int = Intrinsic::aarch64_neon_usqadd;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsqadd");
-  }
-  case AArch64::BI__builtin_neon_vuqadd_v:
-  case AArch64::BI__builtin_neon_vuqaddq_v: {
-    Int = Intrinsic::aarch64_neon_suqadd;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vuqadd");
-  }
-  case AArch64::BI__builtin_neon_vcls_v:
-  case AArch64::BI__builtin_neon_vclsq_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcls_v, E);
-  case AArch64::BI__builtin_neon_vclz_v:
-  case AArch64::BI__builtin_neon_vclzq_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vclz_v, E);
-  case AArch64::BI__builtin_neon_vcnt_v:
-  case AArch64::BI__builtin_neon_vcntq_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcnt_v, E);
-  case AArch64::BI__builtin_neon_vrbit_v:
-  case AArch64::BI__builtin_neon_vrbitq_v:
-    Int = Intrinsic::aarch64_neon_rbit;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrbit");
-  case AArch64::BI__builtin_neon_vmovn_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vmovn_v, E);
-  case AArch64::BI__builtin_neon_vqmovun_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqmovun_v, E);
-  case AArch64::BI__builtin_neon_vqmovn_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqmovn_v, E);
-  case AArch64::BI__builtin_neon_vcvt_f16_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcvt_f16_v, E);
-  case AArch64::BI__builtin_neon_vcvt_f32_f16:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcvt_f32_f16, E);
-  case AArch64::BI__builtin_neon_vcvt_f32_f64: {
-    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
-    Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, false));
-    return Builder.CreateFPTrunc(Ops[0], Ty, "vcvt");
-  }
-  case AArch64::BI__builtin_neon_vcvtx_f32_v: {
-    llvm::Type *EltTy = FloatTy;
-    llvm::Type *ResTy = llvm::VectorType::get(EltTy, 2);
-    llvm::Type *Tys[2] = { ResTy, Ty };
-    Int = Intrinsic::aarch64_neon_fcvtxn;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtx_f32_f64");
-  }
-  case AArch64::BI__builtin_neon_vcvt_f64_v: {
-    llvm::Type *OpTy =
-        GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, false));
-    Ops[0] = Builder.CreateBitCast(Ops[0], OpTy);
-    return Builder.CreateFPExt(Ops[0], Ty, "vcvt");
-  }
-  case AArch64::BI__builtin_neon_vcvtq_f64_v: {
-    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
-    Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float64, false, true));
-    return usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt")
-                : Builder.CreateSIToFP(Ops[0], Ty, "vcvt");
-  }
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqmovun_v, E);
-  case AArch64::BI__builtin_neon_vrndn_v:
-  case AArch64::BI__builtin_neon_vrndnq_v: {
-    Int = Intrinsic::aarch64_neon_frintn;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndn");
-  }
-  case AArch64::BI__builtin_neon_vrnda_v:
-  case AArch64::BI__builtin_neon_vrndaq_v: {
-    Int = Intrinsic::round;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrnda");
-  }
-  case AArch64::BI__builtin_neon_vrndp_v:
-  case AArch64::BI__builtin_neon_vrndpq_v: {
-    Int = Intrinsic::ceil;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndp");
-  }
-  case AArch64::BI__builtin_neon_vrndm_v:
-  case AArch64::BI__builtin_neon_vrndmq_v: {
-    Int = Intrinsic::floor;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndm");
-  }
-  case AArch64::BI__builtin_neon_vrndx_v:
-  case AArch64::BI__builtin_neon_vrndxq_v: {
-    Int = Intrinsic::rint;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndx");
-  }
-  case AArch64::BI__builtin_neon_vrnd_v:
-  case AArch64::BI__builtin_neon_vrndq_v: {
-    Int = Intrinsic::trunc;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrnd");
-  }
-  case AArch64::BI__builtin_neon_vrndi_v:
-  case AArch64::BI__builtin_neon_vrndiq_v: {
-    Int = Intrinsic::nearbyint;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndi");
-  }
-  case AArch64::BI__builtin_neon_vcvt_s32_v:
-  case AArch64::BI__builtin_neon_vcvt_u32_v:
-  case AArch64::BI__builtin_neon_vcvtq_s32_v:
-  case AArch64::BI__builtin_neon_vcvtq_u32_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcvtq_u32_v, E);
-  case AArch64::BI__builtin_neon_vcvtq_s64_v:
-  case AArch64::BI__builtin_neon_vcvtq_u64_v: {
-    llvm::Type *DoubleTy =
-        GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float64, false, true));
-    Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy);
-    return usgn ? Builder.CreateFPToUI(Ops[0], Ty, "vcvt")
-                : Builder.CreateFPToSI(Ops[0], Ty, "vcvt");
-  }
-  case AArch64::BI__builtin_neon_vcvtn_s32_v:
-  case AArch64::BI__builtin_neon_vcvtnq_s32_v: {
-    llvm::Type *OpTy = llvm::VectorType::get(FloatTy, VTy->getNumElements());
-    llvm::Type *Tys[2] = { Ty, OpTy };
-    Int = Intrinsic::aarch64_neon_fcvtns;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtns_f32");
-  }
-  case AArch64::BI__builtin_neon_vcvtnq_s64_v: {
-    llvm::Type *OpTy = llvm::VectorType::get(DoubleTy, VTy->getNumElements());
-    llvm::Type *Tys[2] = { Ty, OpTy };
-    Int = Intrinsic::aarch64_neon_fcvtns;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtns_f64");
-  }
-  case AArch64::BI__builtin_neon_vcvtn_u32_v:
-  case AArch64::BI__builtin_neon_vcvtnq_u32_v: {
-    llvm::Type *OpTy = llvm::VectorType::get(FloatTy, VTy->getNumElements());
-    llvm::Type *Tys[2] = { Ty, OpTy };
-    Int = Intrinsic::aarch64_neon_fcvtnu;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtnu_f32");
-  }
-  case AArch64::BI__builtin_neon_vcvtnq_u64_v: {
-    llvm::Type *OpTy = llvm::VectorType::get(DoubleTy, VTy->getNumElements());
-    llvm::Type *Tys[2] = { Ty, OpTy };
-    Int = Intrinsic::aarch64_neon_fcvtnu;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtnu_f64");
-  }
-  case AArch64::BI__builtin_neon_vcvtp_s32_v:
-  case AArch64::BI__builtin_neon_vcvtpq_s32_v: {
-    llvm::Type *OpTy = llvm::VectorType::get(FloatTy, VTy->getNumElements());
-    llvm::Type *Tys[2] = { Ty, OpTy };
-    Int = Intrinsic::aarch64_neon_fcvtps;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtps_f32");
-  }
-  case AArch64::BI__builtin_neon_vcvtpq_s64_v: {
-    llvm::Type *OpTy = llvm::VectorType::get(DoubleTy, VTy->getNumElements());
-    llvm::Type *Tys[2] = { Ty, OpTy };
-    Int = Intrinsic::aarch64_neon_fcvtps;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtps_f64");
-  }
-  case AArch64::BI__builtin_neon_vcvtp_u32_v:
-  case AArch64::BI__builtin_neon_vcvtpq_u32_v: {
-    llvm::Type *OpTy = llvm::VectorType::get(FloatTy, VTy->getNumElements());
-    llvm::Type *Tys[2] = { Ty, OpTy };
-    Int = Intrinsic::aarch64_neon_fcvtpu;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtpu_f32");
-  }
-  case AArch64::BI__builtin_neon_vcvtpq_u64_v: {
-    llvm::Type *OpTy = llvm::VectorType::get(DoubleTy, VTy->getNumElements());
-    llvm::Type *Tys[2] = { Ty, OpTy };
-    Int = Intrinsic::aarch64_neon_fcvtpu;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtpu_f64");
-  }
-  case AArch64::BI__builtin_neon_vcvtm_s32_v:
-  case AArch64::BI__builtin_neon_vcvtmq_s32_v: {
-    llvm::Type *OpTy = llvm::VectorType::get(FloatTy, VTy->getNumElements());
-    llvm::Type *Tys[2] = { Ty, OpTy };
-    Int = Intrinsic::aarch64_neon_fcvtms;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtms_f32");
-  }
-  case AArch64::BI__builtin_neon_vcvtmq_s64_v: {
-    llvm::Type *OpTy = llvm::VectorType::get(DoubleTy, VTy->getNumElements());
-    llvm::Type *Tys[2] = { Ty, OpTy };
-    Int = Intrinsic::aarch64_neon_fcvtms;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtms_f64");
-  }
-  case AArch64::BI__builtin_neon_vcvtm_u32_v:
-  case AArch64::BI__builtin_neon_vcvtmq_u32_v: {
-    llvm::Type *OpTy = llvm::VectorType::get(FloatTy, VTy->getNumElements());
-    llvm::Type *Tys[2] = { Ty, OpTy };
-    Int = Intrinsic::aarch64_neon_fcvtmu;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtmu_f32");
-  }
-  case AArch64::BI__builtin_neon_vcvtmq_u64_v: {
-    llvm::Type *OpTy = llvm::VectorType::get(DoubleTy, VTy->getNumElements());
-    llvm::Type *Tys[2] = { Ty, OpTy };
-    Int = Intrinsic::aarch64_neon_fcvtmu;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtmu_f64");
-  }
-  case AArch64::BI__builtin_neon_vcvta_s32_v:
-  case AArch64::BI__builtin_neon_vcvtaq_s32_v: {
-    llvm::Type *OpTy = llvm::VectorType::get(FloatTy, VTy->getNumElements());
-    llvm::Type *Tys[2] = { Ty, OpTy };
-    Int = Intrinsic::aarch64_neon_fcvtas;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtas_f32");
-  }
-  case AArch64::BI__builtin_neon_vcvtaq_s64_v: {
-    llvm::Type *OpTy = llvm::VectorType::get(DoubleTy, VTy->getNumElements());
-    llvm::Type *Tys[2] = { Ty, OpTy };
-    Int = Intrinsic::aarch64_neon_fcvtas;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtas_f64");
-  }
-  case AArch64::BI__builtin_neon_vcvta_u32_v:
-  case AArch64::BI__builtin_neon_vcvtaq_u32_v: {
-    llvm::Type *OpTy = llvm::VectorType::get(FloatTy, VTy->getNumElements());
-    llvm::Type *Tys[2] = { Ty, OpTy };
-    Int = Intrinsic::aarch64_neon_fcvtau;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtau_f32");
-  }
-  case AArch64::BI__builtin_neon_vcvtaq_u64_v: {
-    llvm::Type *OpTy = llvm::VectorType::get(DoubleTy, VTy->getNumElements());
-    llvm::Type *Tys[2] = { Ty, OpTy };
-    Int = Intrinsic::aarch64_neon_fcvtau;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtau_f64");
-  }
-  case AArch64::BI__builtin_neon_vrecpe_v:
-  case AArch64::BI__builtin_neon_vrecpeq_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrecpe_v, E);
-  case AArch64::BI__builtin_neon_vrsqrte_v:
-  case AArch64::BI__builtin_neon_vrsqrteq_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vrsqrte_v, E);
-  case AArch64::BI__builtin_neon_vsqrt_v:
-  case AArch64::BI__builtin_neon_vsqrtq_v: {
-    Int = Intrinsic::aarch64_neon_fsqrt;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsqrt");
-  }
-  case AArch64::BI__builtin_neon_vcvt_f32_v:
-  case AArch64::BI__builtin_neon_vcvtq_f32_v:
-    return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vcvt_f32_v, E);
-  case AArch64::BI__builtin_neon_vceqz_v:
-  case AArch64::BI__builtin_neon_vceqzq_v:
-    return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OEQ,
-                                         ICmpInst::ICMP_EQ, "vceqz");
-  case AArch64::BI__builtin_neon_vcgez_v:
-  case AArch64::BI__builtin_neon_vcgezq_v:
-    return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OGE,
-                                         ICmpInst::ICMP_SGE, "vcgez");
-  case AArch64::BI__builtin_neon_vclez_v:
-  case AArch64::BI__builtin_neon_vclezq_v:
-    return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OLE,
-                                         ICmpInst::ICMP_SLE, "vclez");
-  case AArch64::BI__builtin_neon_vcgtz_v:
-  case AArch64::BI__builtin_neon_vcgtzq_v:
-    return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OGT,
-                                         ICmpInst::ICMP_SGT, "vcgtz");
-  case AArch64::BI__builtin_neon_vcltz_v:
-  case AArch64::BI__builtin_neon_vcltzq_v:
-    return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OLT,
-                                         ICmpInst::ICMP_SLT, "vcltz");
-  }
-}
-
 Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,
                                            const CallExpr *E) {
+  unsigned HintID = static_cast<unsigned>(-1);
+  switch (BuiltinID) {
+  default: break;
+  case ARM::BI__builtin_arm_nop:
+    HintID = 0;
+    break;
+  case ARM::BI__builtin_arm_yield:
+  case ARM::BI__yield:
+    HintID = 1;
+    break;
+  case ARM::BI__builtin_arm_wfe:
+  case ARM::BI__wfe:
+    HintID = 2;
+    break;
+  case ARM::BI__builtin_arm_wfi:
+  case ARM::BI__wfi:
+    HintID = 3;
+    break;
+  case ARM::BI__builtin_arm_sev:
+  case ARM::BI__sev:
+    HintID = 4;
+    break;
+  case ARM::BI__builtin_arm_sevl:
+  case ARM::BI__sevl:
+    HintID = 5;
+    break;
+  }
+
+  if (HintID != static_cast<unsigned>(-1)) {
+    Function *F = CGM.getIntrinsic(Intrinsic::arm_hint);
+    return Builder.CreateCall(F, llvm::ConstantInt::get(Int32Ty, HintID));
+  }
+
+  if (BuiltinID == ARM::BI__builtin_arm_rbit) {
+    return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_rbit),
+                                               EmitScalarExpr(E->getArg(0)),
+                              "rbit");
+  }
+
   if (BuiltinID == ARM::BI__clear_cache) {
     assert(E->getNumArgs() == 2 && "__clear_cache takes 2 arguments");
     const FunctionDecl *FD = E->getDirectCallee();
@@ -3771,9 +3116,23 @@
   }
 
   if (BuiltinID == ARM::BI__builtin_arm_ldrexd ||
-      (BuiltinID == ARM::BI__builtin_arm_ldrex &&
-       getContext().getTypeSize(E->getType()) == 64)) {
-    Function *F = CGM.getIntrinsic(Intrinsic::arm_ldrexd);
+      ((BuiltinID == ARM::BI__builtin_arm_ldrex ||
+        BuiltinID == ARM::BI__builtin_arm_ldaex) &&
+       getContext().getTypeSize(E->getType()) == 64) ||
+      BuiltinID == ARM::BI__ldrexd) {
+    Function *F;
+
+    switch (BuiltinID) {
+    default: llvm_unreachable("unexpected builtin");
+    case ARM::BI__builtin_arm_ldaex:
+      F = CGM.getIntrinsic(Intrinsic::arm_ldaexd);
+      break;
+    case ARM::BI__builtin_arm_ldrexd:
+    case ARM::BI__builtin_arm_ldrex:
+    case ARM::BI__ldrexd:
+      F = CGM.getIntrinsic(Intrinsic::arm_ldrexd);
+      break;
+    }
 
     Value *LdPtr = EmitScalarExpr(E->getArg(0));
     Value *Val = Builder.CreateCall(F, Builder.CreateBitCast(LdPtr, Int8PtrTy),
@@ -3790,7 +3149,8 @@
     return Builder.CreateBitCast(Val, ConvertType(E->getType()));
   }
 
-  if (BuiltinID == ARM::BI__builtin_arm_ldrex) {
+  if (BuiltinID == ARM::BI__builtin_arm_ldrex ||
+      BuiltinID == ARM::BI__builtin_arm_ldaex) {
     Value *LoadAddr = EmitScalarExpr(E->getArg(0));
 
     QualType Ty = E->getType();
@@ -3799,7 +3159,10 @@
                                                   getContext().getTypeSize(Ty));
     LoadAddr = Builder.CreateBitCast(LoadAddr, IntResTy->getPointerTo());
 
-    Function *F = CGM.getIntrinsic(Intrinsic::arm_ldrex, LoadAddr->getType());
+    Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_ldaex
+                                       ? Intrinsic::arm_ldaex
+                                       : Intrinsic::arm_ldrex,
+                                   LoadAddr->getType());
     Value *Val = Builder.CreateCall(F, LoadAddr, "ldrex");
 
     if (RealResTy->isPointerTy())
@@ -3811,9 +3174,12 @@
   }
 
   if (BuiltinID == ARM::BI__builtin_arm_strexd ||
-      (BuiltinID == ARM::BI__builtin_arm_strex &&
+      ((BuiltinID == ARM::BI__builtin_arm_stlex ||
+        BuiltinID == ARM::BI__builtin_arm_strex) &&
        getContext().getTypeSize(E->getArg(0)->getType()) == 64)) {
-    Function *F = CGM.getIntrinsic(Intrinsic::arm_strexd);
+    Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_stlex
+                                       ? Intrinsic::arm_stlexd
+                                       : Intrinsic::arm_strexd);
     llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty, NULL);
 
     Value *Tmp = CreateMemTemp(E->getArg(0)->getType());
@@ -3829,7 +3195,8 @@
     return Builder.CreateCall3(F, Arg0, Arg1, StPtr, "strexd");
   }
 
-  if (BuiltinID == ARM::BI__builtin_arm_strex) {
+  if (BuiltinID == ARM::BI__builtin_arm_strex ||
+      BuiltinID == ARM::BI__builtin_arm_stlex) {
     Value *StoreVal = EmitScalarExpr(E->getArg(0));
     Value *StoreAddr = EmitScalarExpr(E->getArg(1));
 
@@ -3845,7 +3212,10 @@
       StoreVal = Builder.CreateZExtOrBitCast(StoreVal, Int32Ty);
     }
 
-    Function *F = CGM.getIntrinsic(Intrinsic::arm_strex, StoreAddr->getType());
+    Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_stlex
+                                       ? Intrinsic::arm_stlex
+                                       : Intrinsic::arm_strex,
+                                   StoreAddr->getType());
     return Builder.CreateCall2(F, StoreVal, StoreAddr, "strex");
   }
 
@@ -3854,11 +3224,6 @@
     return Builder.CreateCall(F);
   }
 
-  if (BuiltinID == ARM::BI__builtin_arm_sevl) {
-    Function *F = CGM.getIntrinsic(Intrinsic::arm_sevl);
-    return Builder.CreateCall(F);
-  }
-
   // CRC32
   Intrinsic::ID CRCIntrinsicID = Intrinsic::not_intrinsic;
   switch (BuiltinID) {
@@ -3903,32 +3268,32 @@
   }
 
   SmallVector<Value*, 4> Ops;
-  llvm::Value *Align = 0;
+  llvm::Value *Align = nullptr;
   for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) {
     if (i == 0) {
       switch (BuiltinID) {
-      case ARM::BI__builtin_neon_vld1_v:
-      case ARM::BI__builtin_neon_vld1q_v:
-      case ARM::BI__builtin_neon_vld1q_lane_v:
-      case ARM::BI__builtin_neon_vld1_lane_v:
-      case ARM::BI__builtin_neon_vld1_dup_v:
-      case ARM::BI__builtin_neon_vld1q_dup_v:
-      case ARM::BI__builtin_neon_vst1_v:
-      case ARM::BI__builtin_neon_vst1q_v:
-      case ARM::BI__builtin_neon_vst1q_lane_v:
-      case ARM::BI__builtin_neon_vst1_lane_v:
-      case ARM::BI__builtin_neon_vst2_v:
-      case ARM::BI__builtin_neon_vst2q_v:
-      case ARM::BI__builtin_neon_vst2_lane_v:
-      case ARM::BI__builtin_neon_vst2q_lane_v:
-      case ARM::BI__builtin_neon_vst3_v:
-      case ARM::BI__builtin_neon_vst3q_v:
-      case ARM::BI__builtin_neon_vst3_lane_v:
-      case ARM::BI__builtin_neon_vst3q_lane_v:
-      case ARM::BI__builtin_neon_vst4_v:
-      case ARM::BI__builtin_neon_vst4q_v:
-      case ARM::BI__builtin_neon_vst4_lane_v:
-      case ARM::BI__builtin_neon_vst4q_lane_v:
+      case NEON::BI__builtin_neon_vld1_v:
+      case NEON::BI__builtin_neon_vld1q_v:
+      case NEON::BI__builtin_neon_vld1q_lane_v:
+      case NEON::BI__builtin_neon_vld1_lane_v:
+      case NEON::BI__builtin_neon_vld1_dup_v:
+      case NEON::BI__builtin_neon_vld1q_dup_v:
+      case NEON::BI__builtin_neon_vst1_v:
+      case NEON::BI__builtin_neon_vst1q_v:
+      case NEON::BI__builtin_neon_vst1q_lane_v:
+      case NEON::BI__builtin_neon_vst1_lane_v:
+      case NEON::BI__builtin_neon_vst2_v:
+      case NEON::BI__builtin_neon_vst2q_v:
+      case NEON::BI__builtin_neon_vst2_lane_v:
+      case NEON::BI__builtin_neon_vst2q_lane_v:
+      case NEON::BI__builtin_neon_vst3_v:
+      case NEON::BI__builtin_neon_vst3q_v:
+      case NEON::BI__builtin_neon_vst3_lane_v:
+      case NEON::BI__builtin_neon_vst3q_lane_v:
+      case NEON::BI__builtin_neon_vst4_v:
+      case NEON::BI__builtin_neon_vst4q_v:
+      case NEON::BI__builtin_neon_vst4_lane_v:
+      case NEON::BI__builtin_neon_vst4q_lane_v:
         // Get the alignment for the argument in addition to the value;
         // we'll use it later.
         std::pair<llvm::Value*, unsigned> Src =
@@ -3940,21 +3305,21 @@
     }
     if (i == 1) {
       switch (BuiltinID) {
-      case ARM::BI__builtin_neon_vld2_v:
-      case ARM::BI__builtin_neon_vld2q_v:
-      case ARM::BI__builtin_neon_vld3_v:
-      case ARM::BI__builtin_neon_vld3q_v:
-      case ARM::BI__builtin_neon_vld4_v:
-      case ARM::BI__builtin_neon_vld4q_v:
-      case ARM::BI__builtin_neon_vld2_lane_v:
-      case ARM::BI__builtin_neon_vld2q_lane_v:
-      case ARM::BI__builtin_neon_vld3_lane_v:
-      case ARM::BI__builtin_neon_vld3q_lane_v:
-      case ARM::BI__builtin_neon_vld4_lane_v:
-      case ARM::BI__builtin_neon_vld4q_lane_v:
-      case ARM::BI__builtin_neon_vld2_dup_v:
-      case ARM::BI__builtin_neon_vld3_dup_v:
-      case ARM::BI__builtin_neon_vld4_dup_v:
+      case NEON::BI__builtin_neon_vld2_v:
+      case NEON::BI__builtin_neon_vld2q_v:
+      case NEON::BI__builtin_neon_vld3_v:
+      case NEON::BI__builtin_neon_vld3q_v:
+      case NEON::BI__builtin_neon_vld4_v:
+      case NEON::BI__builtin_neon_vld4q_v:
+      case NEON::BI__builtin_neon_vld2_lane_v:
+      case NEON::BI__builtin_neon_vld2q_lane_v:
+      case NEON::BI__builtin_neon_vld3_lane_v:
+      case NEON::BI__builtin_neon_vld3q_lane_v:
+      case NEON::BI__builtin_neon_vld4_lane_v:
+      case NEON::BI__builtin_neon_vld4q_lane_v:
+      case NEON::BI__builtin_neon_vld2_dup_v:
+      case NEON::BI__builtin_neon_vld3_dup_v:
+      case NEON::BI__builtin_neon_vld4_dup_v:
         // Get the alignment for the argument in addition to the value;
         // we'll use it later.
         std::pair<llvm::Value*, unsigned> Src =
@@ -3967,41 +3332,59 @@
     Ops.push_back(EmitScalarExpr(E->getArg(i)));
   }
 
-  // vget_lane and vset_lane are not overloaded and do not have an extra
-  // argument that specifies the vector type.
   switch (BuiltinID) {
   default: break;
-  case ARM::BI__builtin_neon_vget_lane_i8:
-  case ARM::BI__builtin_neon_vget_lane_i16:
-  case ARM::BI__builtin_neon_vget_lane_i32:
-  case ARM::BI__builtin_neon_vget_lane_i64:
-  case ARM::BI__builtin_neon_vget_lane_f32:
-  case ARM::BI__builtin_neon_vgetq_lane_i8:
-  case ARM::BI__builtin_neon_vgetq_lane_i16:
-  case ARM::BI__builtin_neon_vgetq_lane_i32:
-  case ARM::BI__builtin_neon_vgetq_lane_i64:
-  case ARM::BI__builtin_neon_vgetq_lane_f32:
+  // vget_lane and vset_lane are not overloaded and do not have an extra
+  // argument that specifies the vector type.
+  case NEON::BI__builtin_neon_vget_lane_i8:
+  case NEON::BI__builtin_neon_vget_lane_i16:
+  case NEON::BI__builtin_neon_vget_lane_i32:
+  case NEON::BI__builtin_neon_vget_lane_i64:
+  case NEON::BI__builtin_neon_vget_lane_f32:
+  case NEON::BI__builtin_neon_vgetq_lane_i8:
+  case NEON::BI__builtin_neon_vgetq_lane_i16:
+  case NEON::BI__builtin_neon_vgetq_lane_i32:
+  case NEON::BI__builtin_neon_vgetq_lane_i64:
+  case NEON::BI__builtin_neon_vgetq_lane_f32:
     return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
                                         "vget_lane");
-  case ARM::BI__builtin_neon_vset_lane_i8:
-  case ARM::BI__builtin_neon_vset_lane_i16:
-  case ARM::BI__builtin_neon_vset_lane_i32:
-  case ARM::BI__builtin_neon_vset_lane_i64:
-  case ARM::BI__builtin_neon_vset_lane_f32:
-  case ARM::BI__builtin_neon_vsetq_lane_i8:
-  case ARM::BI__builtin_neon_vsetq_lane_i16:
-  case ARM::BI__builtin_neon_vsetq_lane_i32:
-  case ARM::BI__builtin_neon_vsetq_lane_i64:
-  case ARM::BI__builtin_neon_vsetq_lane_f32:
+  case NEON::BI__builtin_neon_vset_lane_i8:
+  case NEON::BI__builtin_neon_vset_lane_i16:
+  case NEON::BI__builtin_neon_vset_lane_i32:
+  case NEON::BI__builtin_neon_vset_lane_i64:
+  case NEON::BI__builtin_neon_vset_lane_f32:
+  case NEON::BI__builtin_neon_vsetq_lane_i8:
+  case NEON::BI__builtin_neon_vsetq_lane_i16:
+  case NEON::BI__builtin_neon_vsetq_lane_i32:
+  case NEON::BI__builtin_neon_vsetq_lane_i64:
+  case NEON::BI__builtin_neon_vsetq_lane_f32:
     Ops.push_back(EmitScalarExpr(E->getArg(2)));
     return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane");
+
+  // Non-polymorphic crypto instructions also not overloaded
+  case NEON::BI__builtin_neon_vsha1h_u32:
+    Ops.push_back(EmitScalarExpr(E->getArg(0)));
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1h), Ops,
+                        "vsha1h");
+  case NEON::BI__builtin_neon_vsha1cq_u32:
+    Ops.push_back(EmitScalarExpr(E->getArg(2)));
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1c), Ops,
+                        "vsha1h");
+  case NEON::BI__builtin_neon_vsha1pq_u32:
+    Ops.push_back(EmitScalarExpr(E->getArg(2)));
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1p), Ops,
+                        "vsha1h");
+  case NEON::BI__builtin_neon_vsha1mq_u32:
+    Ops.push_back(EmitScalarExpr(E->getArg(2)));
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1m), Ops,
+                        "vsha1h");
   }
 
   // Get the last argument, which specifies the vector type.
   llvm::APSInt Result;
   const Expr *Arg = E->getArg(E->getNumArgs()-1);
   if (!Arg->isIntegerConstantExpr(Result, getContext()))
-    return 0;
+    return nullptr;
 
   if (BuiltinID == ARM::BI__builtin_arm_vcvtr_f ||
       BuiltinID == ARM::BI__builtin_arm_vcvtr_d) {
@@ -4024,166 +3407,27 @@
   // Determine the type of this overloaded NEON intrinsic.
   NeonTypeFlags Type(Result.getZExtValue());
   bool usgn = Type.isUnsigned();
-  bool quad = Type.isQuad();
   bool rightShift = false;
 
   llvm::VectorType *VTy = GetNeonType(this, Type);
   llvm::Type *Ty = VTy;
   if (!Ty)
-    return 0;
+    return nullptr;
+
+  // Many NEON builtins have identical semantics and uses in ARM and
+  // AArch64. Emit these in a single function.
+  ArrayRef<NeonIntrinsicInfo> IntrinsicMap(ARMSIMDIntrinsicMap);
+  const NeonIntrinsicInfo *Builtin = findNeonIntrinsicInMap(
+      IntrinsicMap, BuiltinID, NEONSIMDIntrinsicsProvenSorted);
+  if (Builtin)
+    return EmitCommonNeonBuiltinExpr(
+        Builtin->BuiltinID, Builtin->LLVMIntrinsic, Builtin->AltLLVMIntrinsic,
+        Builtin->NameHint, Builtin->TypeModifier, E, Ops, Align);
 
   unsigned Int;
   switch (BuiltinID) {
-  default: return 0;
-  case ARM::BI__builtin_neon_vbsl_v:
-  case ARM::BI__builtin_neon_vbslq_v:
-    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vbsl, Ty),
-                        Ops, "vbsl");
-  case ARM::BI__builtin_neon_vabd_v:
-  case ARM::BI__builtin_neon_vabdq_v:
-    Int = usgn ? Intrinsic::arm_neon_vabdu : Intrinsic::arm_neon_vabds;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vabd");
-  case ARM::BI__builtin_neon_vabs_v:
-  case ARM::BI__builtin_neon_vabsq_v:
-    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vabs, Ty),
-                        Ops, "vabs");
-  case ARM::BI__builtin_neon_vaddhn_v: {
-    llvm::VectorType *SrcTy =
-        llvm::VectorType::getExtendedElementVectorType(VTy);
-
-    // %sum = add <4 x i32> %lhs, %rhs
-    Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy);
-    Ops[1] = Builder.CreateBitCast(Ops[1], SrcTy);
-    Ops[0] = Builder.CreateAdd(Ops[0], Ops[1], "vaddhn");
-
-    // %high = lshr <4 x i32> %sum, <i32 16, i32 16, i32 16, i32 16>
-    Constant *ShiftAmt = ConstantInt::get(SrcTy->getElementType(),
-                                       SrcTy->getScalarSizeInBits() / 2);
-    ShiftAmt = ConstantVector::getSplat(VTy->getNumElements(), ShiftAmt);
-    Ops[0] = Builder.CreateLShr(Ops[0], ShiftAmt, "vaddhn");
-
-    // %res = trunc <4 x i32> %high to <4 x i16>
-    return Builder.CreateTrunc(Ops[0], VTy, "vaddhn");
-  }
-  case ARM::BI__builtin_neon_vcale_v:
-    std::swap(Ops[0], Ops[1]);
-  case ARM::BI__builtin_neon_vcage_v: {
-    Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vacged);
-    return EmitNeonCall(F, Ops, "vcage");
-  }
-  case ARM::BI__builtin_neon_vcaleq_v:
-    std::swap(Ops[0], Ops[1]);
-  case ARM::BI__builtin_neon_vcageq_v: {
-    Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vacgeq);
-    return EmitNeonCall(F, Ops, "vcage");
-  }
-  case ARM::BI__builtin_neon_vcalt_v:
-    std::swap(Ops[0], Ops[1]);
-  case ARM::BI__builtin_neon_vcagt_v: {
-    Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vacgtd);
-    return EmitNeonCall(F, Ops, "vcagt");
-  }
-  case ARM::BI__builtin_neon_vcaltq_v:
-    std::swap(Ops[0], Ops[1]);
-  case ARM::BI__builtin_neon_vcagtq_v: {
-    Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vacgtq);
-    return EmitNeonCall(F, Ops, "vcagt");
-  }
-  case ARM::BI__builtin_neon_vcls_v:
-  case ARM::BI__builtin_neon_vclsq_v: {
-    Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vcls, Ty);
-    return EmitNeonCall(F, Ops, "vcls");
-  }
-  case ARM::BI__builtin_neon_vclz_v:
-  case ARM::BI__builtin_neon_vclzq_v: {
-    // Generate target-independent intrinsic; also need to add second argument
-    // for whether or not clz of zero is undefined; on ARM it isn't.
-    Function *F = CGM.getIntrinsic(Intrinsic::ctlz, Ty);
-    Ops.push_back(Builder.getInt1(getTarget().isCLZForZeroUndef()));
-    return EmitNeonCall(F, Ops, "vclz");
-  }
-  case ARM::BI__builtin_neon_vcnt_v:
-  case ARM::BI__builtin_neon_vcntq_v: {
-    // generate target-independent intrinsic
-    Function *F = CGM.getIntrinsic(Intrinsic::ctpop, Ty);
-    return EmitNeonCall(F, Ops, "vctpop");
-  }
-  case ARM::BI__builtin_neon_vcvt_f16_v: {
-    assert(Type.getEltType() == NeonTypeFlags::Float16 && !quad &&
-           "unexpected vcvt_f16_v builtin");
-    Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vcvtfp2hf);
-    return EmitNeonCall(F, Ops, "vcvt");
-  }
-  case ARM::BI__builtin_neon_vcvt_f32_f16: {
-    assert(Type.getEltType() == NeonTypeFlags::Float16 && !quad &&
-           "unexpected vcvt_f32_f16 builtin");
-    Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vcvthf2fp);
-    return EmitNeonCall(F, Ops, "vcvt");
-  }
-  case ARM::BI__builtin_neon_vcvt_f32_v:
-  case ARM::BI__builtin_neon_vcvtq_f32_v:
-    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
-    Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, quad));
-    return usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt")
-                : Builder.CreateSIToFP(Ops[0], Ty, "vcvt");
-  case ARM::BI__builtin_neon_vcvt_s32_v:
-  case ARM::BI__builtin_neon_vcvt_u32_v:
-  case ARM::BI__builtin_neon_vcvtq_s32_v:
-  case ARM::BI__builtin_neon_vcvtq_u32_v: {
-    llvm::Type *FloatTy =
-      GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, quad));
-    Ops[0] = Builder.CreateBitCast(Ops[0], FloatTy);
-    return usgn ? Builder.CreateFPToUI(Ops[0], Ty, "vcvt")
-                : Builder.CreateFPToSI(Ops[0], Ty, "vcvt");
-  }
-  case ARM::BI__builtin_neon_vcvt_n_f32_v:
-  case ARM::BI__builtin_neon_vcvtq_n_f32_v: {
-    llvm::Type *FloatTy =
-      GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, quad));
-    llvm::Type *Tys[2] = { FloatTy, Ty };
-    Int = usgn ? Intrinsic::arm_neon_vcvtfxu2fp
-               : Intrinsic::arm_neon_vcvtfxs2fp;
-    Function *F = CGM.getIntrinsic(Int, Tys);
-    return EmitNeonCall(F, Ops, "vcvt_n");
-  }
-  case ARM::BI__builtin_neon_vcvt_n_s32_v:
-  case ARM::BI__builtin_neon_vcvt_n_u32_v:
-  case ARM::BI__builtin_neon_vcvtq_n_s32_v:
-  case ARM::BI__builtin_neon_vcvtq_n_u32_v: {
-    llvm::Type *FloatTy =
-      GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, quad));
-    llvm::Type *Tys[2] = { Ty, FloatTy };
-    Int = usgn ? Intrinsic::arm_neon_vcvtfp2fxu
-               : Intrinsic::arm_neon_vcvtfp2fxs;
-    Function *F = CGM.getIntrinsic(Int, Tys);
-    return EmitNeonCall(F, Ops, "vcvt_n");
-  }
-  case ARM::BI__builtin_neon_vext_v:
-  case ARM::BI__builtin_neon_vextq_v: {
-    int CV = cast<ConstantInt>(Ops[2])->getSExtValue();
-    SmallVector<Constant*, 16> Indices;
-    for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i)
-      Indices.push_back(ConstantInt::get(Int32Ty, i+CV));
-
-    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
-    Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
-    Value *SV = llvm::ConstantVector::get(Indices);
-    return Builder.CreateShuffleVector(Ops[0], Ops[1], SV, "vext");
-  }
-  case ARM::BI__builtin_neon_vhadd_v:
-  case ARM::BI__builtin_neon_vhaddq_v:
-    Int = usgn ? Intrinsic::arm_neon_vhaddu : Intrinsic::arm_neon_vhadds;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vhadd");
-  case ARM::BI__builtin_neon_vhsub_v:
-  case ARM::BI__builtin_neon_vhsubq_v:
-    Int = usgn ? Intrinsic::arm_neon_vhsubu : Intrinsic::arm_neon_vhsubs;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vhsub");
-  case ARM::BI__builtin_neon_vld1_v:
-  case ARM::BI__builtin_neon_vld1q_v:
-    Ops.push_back(Align);
-    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vld1, Ty),
-                        Ops, "vld1");
-  case ARM::BI__builtin_neon_vld1q_lane_v:
+  default: return nullptr;
+  case NEON::BI__builtin_neon_vld1q_lane_v:
     // Handle 64-bit integer elements as a special case.  Use shuffles of
     // one-element vectors to avoid poor code for i64 in the backend.
     if (VTy->getElementType()->isIntegerTy(64)) {
@@ -4204,7 +3448,7 @@
       return Builder.CreateShuffleVector(Ops[1], Ld, SV, "vld1q_lane");
     }
     // fall through
-  case ARM::BI__builtin_neon_vld1_lane_v: {
+  case NEON::BI__builtin_neon_vld1_lane_v: {
     Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
     Ty = llvm::PointerType::getUnqual(VTy->getElementType());
     Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
@@ -4212,90 +3456,19 @@
     Ld->setAlignment(cast<ConstantInt>(Align)->getZExtValue());
     return Builder.CreateInsertElement(Ops[1], Ld, Ops[2], "vld1_lane");
   }
-  case ARM::BI__builtin_neon_vld1_dup_v:
-  case ARM::BI__builtin_neon_vld1q_dup_v: {
-    Value *V = UndefValue::get(Ty);
-    Ty = llvm::PointerType::getUnqual(VTy->getElementType());
-    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
-    LoadInst *Ld = Builder.CreateLoad(Ops[0]);
-    Ld->setAlignment(cast<ConstantInt>(Align)->getZExtValue());
-    llvm::Constant *CI = ConstantInt::get(Int32Ty, 0);
-    Ops[0] = Builder.CreateInsertElement(V, Ld, CI);
-    return EmitNeonSplat(Ops[0], CI);
-  }
-  case ARM::BI__builtin_neon_vld2_v:
-  case ARM::BI__builtin_neon_vld2q_v: {
-    Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld2, Ty);
-    Ops[1] = Builder.CreateCall2(F, Ops[1], Align, "vld2");
-    Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
-    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
-    return Builder.CreateStore(Ops[1], Ops[0]);
-  }
-  case ARM::BI__builtin_neon_vld3_v:
-  case ARM::BI__builtin_neon_vld3q_v: {
-    Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld3, Ty);
-    Ops[1] = Builder.CreateCall2(F, Ops[1], Align, "vld3");
-    Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
-    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
-    return Builder.CreateStore(Ops[1], Ops[0]);
-  }
-  case ARM::BI__builtin_neon_vld4_v:
-  case ARM::BI__builtin_neon_vld4q_v: {
-    Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld4, Ty);
-    Ops[1] = Builder.CreateCall2(F, Ops[1], Align, "vld4");
-    Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
-    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
-    return Builder.CreateStore(Ops[1], Ops[0]);
-  }
-  case ARM::BI__builtin_neon_vld2_lane_v:
-  case ARM::BI__builtin_neon_vld2q_lane_v: {
-    Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld2lane, Ty);
-    Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
-    Ops[3] = Builder.CreateBitCast(Ops[3], Ty);
-    Ops.push_back(Align);
-    Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld2_lane");
-    Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
-    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
-    return Builder.CreateStore(Ops[1], Ops[0]);
-  }
-  case ARM::BI__builtin_neon_vld3_lane_v:
-  case ARM::BI__builtin_neon_vld3q_lane_v: {
-    Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld3lane, Ty);
-    Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
-    Ops[3] = Builder.CreateBitCast(Ops[3], Ty);
-    Ops[4] = Builder.CreateBitCast(Ops[4], Ty);
-    Ops.push_back(Align);
-    Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld3_lane");
-    Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
-    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
-    return Builder.CreateStore(Ops[1], Ops[0]);
-  }
-  case ARM::BI__builtin_neon_vld4_lane_v:
-  case ARM::BI__builtin_neon_vld4q_lane_v: {
-    Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld4lane, Ty);
-    Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
-    Ops[3] = Builder.CreateBitCast(Ops[3], Ty);
-    Ops[4] = Builder.CreateBitCast(Ops[4], Ty);
-    Ops[5] = Builder.CreateBitCast(Ops[5], Ty);
-    Ops.push_back(Align);
-    Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld3_lane");
-    Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
-    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
-    return Builder.CreateStore(Ops[1], Ops[0]);
-  }
-  case ARM::BI__builtin_neon_vld2_dup_v:
-  case ARM::BI__builtin_neon_vld3_dup_v:
-  case ARM::BI__builtin_neon_vld4_dup_v: {
+  case NEON::BI__builtin_neon_vld2_dup_v:
+  case NEON::BI__builtin_neon_vld3_dup_v:
+  case NEON::BI__builtin_neon_vld4_dup_v: {
     // Handle 64-bit elements as a special-case.  There is no "dup" needed.
     if (VTy->getElementType()->getPrimitiveSizeInBits() == 64) {
       switch (BuiltinID) {
-      case ARM::BI__builtin_neon_vld2_dup_v:
+      case NEON::BI__builtin_neon_vld2_dup_v:
         Int = Intrinsic::arm_neon_vld2;
         break;
-      case ARM::BI__builtin_neon_vld3_dup_v:
+      case NEON::BI__builtin_neon_vld3_dup_v:
         Int = Intrinsic::arm_neon_vld3;
         break;
-      case ARM::BI__builtin_neon_vld4_dup_v:
+      case NEON::BI__builtin_neon_vld4_dup_v:
         Int = Intrinsic::arm_neon_vld4;
         break;
       default: llvm_unreachable("unknown vld_dup intrinsic?");
@@ -4307,13 +3480,13 @@
       return Builder.CreateStore(Ops[1], Ops[0]);
     }
     switch (BuiltinID) {
-    case ARM::BI__builtin_neon_vld2_dup_v:
+    case NEON::BI__builtin_neon_vld2_dup_v:
       Int = Intrinsic::arm_neon_vld2lane;
       break;
-    case ARM::BI__builtin_neon_vld3_dup_v:
+    case NEON::BI__builtin_neon_vld3_dup_v:
       Int = Intrinsic::arm_neon_vld3lane;
       break;
-    case ARM::BI__builtin_neon_vld4_dup_v:
+    case NEON::BI__builtin_neon_vld4_dup_v:
       Int = Intrinsic::arm_neon_vld4lane;
       break;
     default: llvm_unreachable("unknown vld_dup intrinsic?");
@@ -4342,251 +3515,58 @@
     Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
     return Builder.CreateStore(Ops[1], Ops[0]);
   }
-  case ARM::BI__builtin_neon_vmax_v:
-  case ARM::BI__builtin_neon_vmaxq_v:
-    Int = usgn ? Intrinsic::arm_neon_vmaxu : Intrinsic::arm_neon_vmaxs;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmax");
-  case ARM::BI__builtin_neon_vmin_v:
-  case ARM::BI__builtin_neon_vminq_v:
-    Int = usgn ? Intrinsic::arm_neon_vminu : Intrinsic::arm_neon_vmins;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmin");
-  case ARM::BI__builtin_neon_vmovl_v: {
-    llvm::Type *DTy =llvm::VectorType::getTruncatedElementVectorType(VTy);
-    Ops[0] = Builder.CreateBitCast(Ops[0], DTy);
-    if (usgn)
-      return Builder.CreateZExt(Ops[0], Ty, "vmovl");
-    return Builder.CreateSExt(Ops[0], Ty, "vmovl");
-  }
-  case ARM::BI__builtin_neon_vmovn_v: {
-    llvm::Type *QTy = llvm::VectorType::getExtendedElementVectorType(VTy);
-    Ops[0] = Builder.CreateBitCast(Ops[0], QTy);
-    return Builder.CreateTrunc(Ops[0], Ty, "vmovn");
-  }
-  case ARM::BI__builtin_neon_vmul_v:
-  case ARM::BI__builtin_neon_vmulq_v:
-    assert(Type.isPoly() && "vmul builtin only supported for polynomial types");
-    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vmulp, Ty),
-                        Ops, "vmul");
-  case ARM::BI__builtin_neon_vmull_v:
-    // FIXME: the integer vmull operations could be emitted in terms of pure
-    // LLVM IR (2 exts followed by a mul). Unfortunately LLVM has a habit of
-    // hoisting the exts outside loops. Until global ISel comes along that can
-    // see through such movement this leads to bad CodeGen. So we need an
-    // intrinsic for now.
-    Int = usgn ? Intrinsic::arm_neon_vmullu : Intrinsic::arm_neon_vmulls;
-    Int = Type.isPoly() ? (unsigned)Intrinsic::arm_neon_vmullp : Int;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmull");
-  case ARM::BI__builtin_neon_vfma_v:
-  case ARM::BI__builtin_neon_vfmaq_v: {
-    Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty);
-    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
-    Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
-    Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
-
-    // NEON intrinsic puts accumulator first, unlike the LLVM fma.
-    return Builder.CreateCall3(F, Ops[1], Ops[2], Ops[0]);
-  }
-  case ARM::BI__builtin_neon_vpadal_v:
-  case ARM::BI__builtin_neon_vpadalq_v: {
-    Int = usgn ? Intrinsic::arm_neon_vpadalu : Intrinsic::arm_neon_vpadals;
-    // The source operand type has twice as many elements of half the size.
-    unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
-    llvm::Type *EltTy =
-      llvm::IntegerType::get(getLLVMContext(), EltBits / 2);
-    llvm::Type *NarrowTy =
-      llvm::VectorType::get(EltTy, VTy->getNumElements() * 2);
-    llvm::Type *Tys[2] = { Ty, NarrowTy };
-    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vpadal");
-  }
-  case ARM::BI__builtin_neon_vpadd_v:
-    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vpadd, Ty),
-                        Ops, "vpadd");
-  case ARM::BI__builtin_neon_vpaddl_v:
-  case ARM::BI__builtin_neon_vpaddlq_v: {
-    Int = usgn ? Intrinsic::arm_neon_vpaddlu : Intrinsic::arm_neon_vpaddls;
-    // The source operand type has twice as many elements of half the size.
-    unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
-    llvm::Type *EltTy = llvm::IntegerType::get(getLLVMContext(), EltBits / 2);
-    llvm::Type *NarrowTy =
-      llvm::VectorType::get(EltTy, VTy->getNumElements() * 2);
-    llvm::Type *Tys[2] = { Ty, NarrowTy };
-    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vpaddl");
-  }
-  case ARM::BI__builtin_neon_vpmax_v:
-    Int = usgn ? Intrinsic::arm_neon_vpmaxu : Intrinsic::arm_neon_vpmaxs;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmax");
-  case ARM::BI__builtin_neon_vpmin_v:
-    Int = usgn ? Intrinsic::arm_neon_vpminu : Intrinsic::arm_neon_vpmins;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmin");
-  case ARM::BI__builtin_neon_vqabs_v:
-  case ARM::BI__builtin_neon_vqabsq_v:
-    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqabs, Ty),
-                        Ops, "vqabs");
-  case ARM::BI__builtin_neon_vqadd_v:
-  case ARM::BI__builtin_neon_vqaddq_v:
-    Int = usgn ? Intrinsic::arm_neon_vqaddu : Intrinsic::arm_neon_vqadds;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqadd");
-  case ARM::BI__builtin_neon_vqdmlal_v: {
-    SmallVector<Value *, 2> MulOps(Ops.begin() + 1, Ops.end());
-    Value *Mul = EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqdmull, Ty),
-                              MulOps, "vqdmlal");
-
-    SmallVector<Value *, 2> AddOps;
-    AddOps.push_back(Ops[0]);
-    AddOps.push_back(Mul);
-    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqadds, Ty),
-                        AddOps, "vqdmlal");
-  }
-  case ARM::BI__builtin_neon_vqdmlsl_v: {
-    SmallVector<Value *, 2> MulOps(Ops.begin() + 1, Ops.end());
-    Value *Mul = EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqdmull, Ty),
-                              MulOps, "vqdmlsl");
-
-    SmallVector<Value *, 2> SubOps;
-    SubOps.push_back(Ops[0]);
-    SubOps.push_back(Mul);
-    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqsubs, Ty),
-                        SubOps, "vqdmlsl");
-  }
-  case ARM::BI__builtin_neon_vqdmulh_v:
-  case ARM::BI__builtin_neon_vqdmulhq_v:
-    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqdmulh, Ty),
-                        Ops, "vqdmulh");
-  case ARM::BI__builtin_neon_vqdmull_v:
-    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqdmull, Ty),
-                        Ops, "vqdmull");
-  case ARM::BI__builtin_neon_vqmovn_v:
-    Int = usgn ? Intrinsic::arm_neon_vqmovnu : Intrinsic::arm_neon_vqmovns;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqmovn");
-  case ARM::BI__builtin_neon_vqmovun_v:
-    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqmovnsu, Ty),
-                        Ops, "vqdmull");
-  case ARM::BI__builtin_neon_vqneg_v:
-  case ARM::BI__builtin_neon_vqnegq_v:
-    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqneg, Ty),
-                        Ops, "vqneg");
-  case ARM::BI__builtin_neon_vqrdmulh_v:
-  case ARM::BI__builtin_neon_vqrdmulhq_v:
-    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqrdmulh, Ty),
-                        Ops, "vqrdmulh");
-  case ARM::BI__builtin_neon_vqrshl_v:
-  case ARM::BI__builtin_neon_vqrshlq_v:
-    Int = usgn ? Intrinsic::arm_neon_vqrshiftu : Intrinsic::arm_neon_vqrshifts;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshl");
-  case ARM::BI__builtin_neon_vqrshrn_n_v:
+  case NEON::BI__builtin_neon_vqrshrn_n_v:
     Int =
       usgn ? Intrinsic::arm_neon_vqrshiftnu : Intrinsic::arm_neon_vqrshiftns;
     return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrn_n",
                         1, true);
-  case ARM::BI__builtin_neon_vqrshrun_n_v:
+  case NEON::BI__builtin_neon_vqrshrun_n_v:
     return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqrshiftnsu, Ty),
                         Ops, "vqrshrun_n", 1, true);
-  case ARM::BI__builtin_neon_vqshl_v:
-  case ARM::BI__builtin_neon_vqshlq_v:
-    Int = usgn ? Intrinsic::arm_neon_vqshiftu : Intrinsic::arm_neon_vqshifts;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshl");
-  case ARM::BI__builtin_neon_vqshl_n_v:
-  case ARM::BI__builtin_neon_vqshlq_n_v:
-    Int = usgn ? Intrinsic::arm_neon_vqshiftu : Intrinsic::arm_neon_vqshifts;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshl_n",
-                        1, false);
-  case ARM::BI__builtin_neon_vqshlu_n_v:
-  case ARM::BI__builtin_neon_vqshluq_n_v:
+  case NEON::BI__builtin_neon_vqshlu_n_v:
+  case NEON::BI__builtin_neon_vqshluq_n_v:
     return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqshiftsu, Ty),
                         Ops, "vqshlu", 1, false);
-  case ARM::BI__builtin_neon_vqshrn_n_v:
+  case NEON::BI__builtin_neon_vqshrn_n_v:
     Int = usgn ? Intrinsic::arm_neon_vqshiftnu : Intrinsic::arm_neon_vqshiftns;
     return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrn_n",
                         1, true);
-  case ARM::BI__builtin_neon_vqshrun_n_v:
+  case NEON::BI__builtin_neon_vqshrun_n_v:
     return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqshiftnsu, Ty),
                         Ops, "vqshrun_n", 1, true);
-  case ARM::BI__builtin_neon_vqsub_v:
-  case ARM::BI__builtin_neon_vqsubq_v:
-    Int = usgn ? Intrinsic::arm_neon_vqsubu : Intrinsic::arm_neon_vqsubs;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqsub");
-  case ARM::BI__builtin_neon_vraddhn_v:
-    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vraddhn, Ty),
-                        Ops, "vraddhn");
-  case ARM::BI__builtin_neon_vrecpe_v:
-  case ARM::BI__builtin_neon_vrecpeq_v:
+  case NEON::BI__builtin_neon_vrecpe_v:
+  case NEON::BI__builtin_neon_vrecpeq_v:
     return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrecpe, Ty),
                         Ops, "vrecpe");
-  case ARM::BI__builtin_neon_vrecps_v:
-  case ARM::BI__builtin_neon_vrecpsq_v:
-    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrecps, Ty),
-                        Ops, "vrecps");
-  case ARM::BI__builtin_neon_vrhadd_v:
-  case ARM::BI__builtin_neon_vrhaddq_v:
-    Int = usgn ? Intrinsic::arm_neon_vrhaddu : Intrinsic::arm_neon_vrhadds;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrhadd");
-  case ARM::BI__builtin_neon_vrshl_v:
-  case ARM::BI__builtin_neon_vrshlq_v:
-    Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshl");
-  case ARM::BI__builtin_neon_vrshrn_n_v:
+  case NEON::BI__builtin_neon_vrshrn_n_v:
     return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrshiftn, Ty),
                         Ops, "vrshrn_n", 1, true);
-  case ARM::BI__builtin_neon_vrshr_n_v:
-  case ARM::BI__builtin_neon_vrshrq_n_v:
+  case NEON::BI__builtin_neon_vrshr_n_v:
+  case NEON::BI__builtin_neon_vrshrq_n_v:
     Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts;
     return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshr_n", 1, true);
-  case ARM::BI__builtin_neon_vrsqrte_v:
-  case ARM::BI__builtin_neon_vrsqrteq_v:
-    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrsqrte, Ty),
-                        Ops, "vrsqrte");
-  case ARM::BI__builtin_neon_vrsqrts_v:
-  case ARM::BI__builtin_neon_vrsqrtsq_v:
-    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrsqrts, Ty),
-                        Ops, "vrsqrts");
-  case ARM::BI__builtin_neon_vrsra_n_v:
-  case ARM::BI__builtin_neon_vrsraq_n_v:
+  case NEON::BI__builtin_neon_vrsra_n_v:
+  case NEON::BI__builtin_neon_vrsraq_n_v:
     Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
     Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
     Ops[2] = EmitNeonShiftVector(Ops[2], Ty, true);
     Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts;
     Ops[1] = Builder.CreateCall2(CGM.getIntrinsic(Int, Ty), Ops[1], Ops[2]);
     return Builder.CreateAdd(Ops[0], Ops[1], "vrsra_n");
-  case ARM::BI__builtin_neon_vrsubhn_v:
-    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrsubhn, Ty),
-                        Ops, "vrsubhn");
-  case ARM::BI__builtin_neon_vshl_v:
-  case ARM::BI__builtin_neon_vshlq_v:
-    Int = usgn ? Intrinsic::arm_neon_vshiftu : Intrinsic::arm_neon_vshifts;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vshl");
-  case ARM::BI__builtin_neon_vshll_n_v:
-    Int = usgn ? Intrinsic::arm_neon_vshiftlu : Intrinsic::arm_neon_vshiftls;
-    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vshll", 1);
-  case ARM::BI__builtin_neon_vshl_n_v:
-  case ARM::BI__builtin_neon_vshlq_n_v:
-    Ops[1] = EmitNeonShiftVector(Ops[1], Ty, false);
-    return Builder.CreateShl(Builder.CreateBitCast(Ops[0],Ty), Ops[1],
-                             "vshl_n");
-  case ARM::BI__builtin_neon_vshrn_n_v:
-    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vshiftn, Ty),
-                        Ops, "vshrn_n", 1, true);
-  case ARM::BI__builtin_neon_vshr_n_v:
-  case ARM::BI__builtin_neon_vshrq_n_v:
-    return EmitNeonRShiftImm(Ops[0], Ops[1], Ty, usgn, "vshr_n");
-  case ARM::BI__builtin_neon_vsri_n_v:
-  case ARM::BI__builtin_neon_vsriq_n_v:
+  case NEON::BI__builtin_neon_vsri_n_v:
+  case NEON::BI__builtin_neon_vsriq_n_v:
     rightShift = true;
-  case ARM::BI__builtin_neon_vsli_n_v:
-  case ARM::BI__builtin_neon_vsliq_n_v:
+  case NEON::BI__builtin_neon_vsli_n_v:
+  case NEON::BI__builtin_neon_vsliq_n_v:
     Ops[2] = EmitNeonShiftVector(Ops[2], Ty, rightShift);
     return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vshiftins, Ty),
                         Ops, "vsli_n");
-  case ARM::BI__builtin_neon_vsra_n_v:
-  case ARM::BI__builtin_neon_vsraq_n_v:
+  case NEON::BI__builtin_neon_vsra_n_v:
+  case NEON::BI__builtin_neon_vsraq_n_v:
     Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
     Ops[1] = EmitNeonRShiftImm(Ops[1], Ops[2], Ty, usgn, "vsra_n");
     return Builder.CreateAdd(Ops[0], Ops[1]);
-  case ARM::BI__builtin_neon_vst1_v:
-  case ARM::BI__builtin_neon_vst1q_v:
-    Ops.push_back(Align);
-    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst1, Ty),
-                        Ops, "");
-  case ARM::BI__builtin_neon_vst1q_lane_v:
+  case NEON::BI__builtin_neon_vst1q_lane_v:
     // Handle 64-bit integer elements as a special case.  Use a shuffle to get
     // a one-element vector and avoid poor code for i64 in the backend.
     if (VTy->getElementType()->isIntegerTy(64)) {
@@ -4598,7 +3578,7 @@
                                                  Ops[1]->getType()), Ops);
     }
     // fall through
-  case ARM::BI__builtin_neon_vst1_lane_v: {
+  case NEON::BI__builtin_neon_vst1_lane_v: {
     Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
     Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2]);
     Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
@@ -4607,99 +3587,1984 @@
     St->setAlignment(cast<ConstantInt>(Align)->getZExtValue());
     return St;
   }
-  case ARM::BI__builtin_neon_vst2_v:
-  case ARM::BI__builtin_neon_vst2q_v:
-    Ops.push_back(Align);
-    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst2, Ty),
-                        Ops, "");
-  case ARM::BI__builtin_neon_vst2_lane_v:
-  case ARM::BI__builtin_neon_vst2q_lane_v:
-    Ops.push_back(Align);
-    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst2lane, Ty),
-                        Ops, "");
-  case ARM::BI__builtin_neon_vst3_v:
-  case ARM::BI__builtin_neon_vst3q_v:
-    Ops.push_back(Align);
-    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst3, Ty),
-                        Ops, "");
-  case ARM::BI__builtin_neon_vst3_lane_v:
-  case ARM::BI__builtin_neon_vst3q_lane_v:
-    Ops.push_back(Align);
-    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst3lane, Ty),
-                        Ops, "");
-  case ARM::BI__builtin_neon_vst4_v:
-  case ARM::BI__builtin_neon_vst4q_v:
-    Ops.push_back(Align);
-    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst4, Ty),
-                        Ops, "");
-  case ARM::BI__builtin_neon_vst4_lane_v:
-  case ARM::BI__builtin_neon_vst4q_lane_v:
-    Ops.push_back(Align);
-    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst4lane, Ty),
-                        Ops, "");
-  case ARM::BI__builtin_neon_vsubhn_v: {
-    llvm::VectorType *SrcTy =
-        llvm::VectorType::getExtendedElementVectorType(VTy);
-
-    // %sum = add <4 x i32> %lhs, %rhs
-    Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy);
-    Ops[1] = Builder.CreateBitCast(Ops[1], SrcTy);
-    Ops[0] = Builder.CreateSub(Ops[0], Ops[1], "vsubhn");
-
-    // %high = lshr <4 x i32> %sum, <i32 16, i32 16, i32 16, i32 16>
-    Constant *ShiftAmt = ConstantInt::get(SrcTy->getElementType(),
-                                       SrcTy->getScalarSizeInBits() / 2);
-    ShiftAmt = ConstantVector::getSplat(VTy->getNumElements(), ShiftAmt);
-    Ops[0] = Builder.CreateLShr(Ops[0], ShiftAmt, "vsubhn");
-
-    // %res = trunc <4 x i32> %high to <4 x i16>
-    return Builder.CreateTrunc(Ops[0], VTy, "vsubhn");
-  }
-  case ARM::BI__builtin_neon_vtbl1_v:
+  case NEON::BI__builtin_neon_vtbl1_v:
     return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl1),
                         Ops, "vtbl1");
-  case ARM::BI__builtin_neon_vtbl2_v:
+  case NEON::BI__builtin_neon_vtbl2_v:
     return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl2),
                         Ops, "vtbl2");
-  case ARM::BI__builtin_neon_vtbl3_v:
+  case NEON::BI__builtin_neon_vtbl3_v:
     return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl3),
                         Ops, "vtbl3");
-  case ARM::BI__builtin_neon_vtbl4_v:
+  case NEON::BI__builtin_neon_vtbl4_v:
     return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl4),
                         Ops, "vtbl4");
-  case ARM::BI__builtin_neon_vtbx1_v:
+  case NEON::BI__builtin_neon_vtbx1_v:
     return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx1),
                         Ops, "vtbx1");
-  case ARM::BI__builtin_neon_vtbx2_v:
+  case NEON::BI__builtin_neon_vtbx2_v:
     return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx2),
                         Ops, "vtbx2");
-  case ARM::BI__builtin_neon_vtbx3_v:
+  case NEON::BI__builtin_neon_vtbx3_v:
     return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx3),
                         Ops, "vtbx3");
-  case ARM::BI__builtin_neon_vtbx4_v:
+  case NEON::BI__builtin_neon_vtbx4_v:
     return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx4),
                         Ops, "vtbx4");
-  case ARM::BI__builtin_neon_vtst_v:
-  case ARM::BI__builtin_neon_vtstq_v: {
+  }
+}
+
+static Value *EmitAArch64TblBuiltinExpr(CodeGenFunction &CGF, unsigned BuiltinID,
+                                      const CallExpr *E,
+                                      SmallVectorImpl<Value *> &Ops) {
+  unsigned int Int = 0;
+  const char *s = nullptr;
+
+  switch (BuiltinID) {
+  default:
+    return nullptr;
+  case NEON::BI__builtin_neon_vtbl1_v:
+  case NEON::BI__builtin_neon_vqtbl1_v:
+  case NEON::BI__builtin_neon_vqtbl1q_v:
+  case NEON::BI__builtin_neon_vtbl2_v:
+  case NEON::BI__builtin_neon_vqtbl2_v:
+  case NEON::BI__builtin_neon_vqtbl2q_v:
+  case NEON::BI__builtin_neon_vtbl3_v:
+  case NEON::BI__builtin_neon_vqtbl3_v:
+  case NEON::BI__builtin_neon_vqtbl3q_v:
+  case NEON::BI__builtin_neon_vtbl4_v:
+  case NEON::BI__builtin_neon_vqtbl4_v:
+  case NEON::BI__builtin_neon_vqtbl4q_v:
+    break;
+  case NEON::BI__builtin_neon_vtbx1_v:
+  case NEON::BI__builtin_neon_vqtbx1_v:
+  case NEON::BI__builtin_neon_vqtbx1q_v:
+  case NEON::BI__builtin_neon_vtbx2_v:
+  case NEON::BI__builtin_neon_vqtbx2_v:
+  case NEON::BI__builtin_neon_vqtbx2q_v:
+  case NEON::BI__builtin_neon_vtbx3_v:
+  case NEON::BI__builtin_neon_vqtbx3_v:
+  case NEON::BI__builtin_neon_vqtbx3q_v:
+  case NEON::BI__builtin_neon_vtbx4_v:
+  case NEON::BI__builtin_neon_vqtbx4_v:
+  case NEON::BI__builtin_neon_vqtbx4q_v:
+    break;
+  }
+
+  assert(E->getNumArgs() >= 3);
+
+  // Get the last argument, which specifies the vector type.
+  llvm::APSInt Result;
+  const Expr *Arg = E->getArg(E->getNumArgs() - 1);
+  if (!Arg->isIntegerConstantExpr(Result, CGF.getContext()))
+    return nullptr;
+
+  // Determine the type of this overloaded NEON intrinsic.
+  NeonTypeFlags Type(Result.getZExtValue());
+  llvm::VectorType *VTy = GetNeonType(&CGF, Type);
+  llvm::Type *Ty = VTy;
+  if (!Ty)
+    return nullptr;
+
+  unsigned nElts = VTy->getNumElements();
+
+  CodeGen::CGBuilderTy &Builder = CGF.Builder;
+
+  // AArch64 scalar builtins are not overloaded, they do not have an extra
+  // argument that specifies the vector type, need to handle each case.
+  SmallVector<Value *, 2> TblOps;
+  switch (BuiltinID) {
+  case NEON::BI__builtin_neon_vtbl1_v: {
+    TblOps.push_back(Ops[0]);
+    return packTBLDVectorList(CGF, TblOps, nullptr, Ops[1], Ty,
+                              Intrinsic::aarch64_neon_tbl1, "vtbl1");
+  }
+  case NEON::BI__builtin_neon_vtbl2_v: {
+    TblOps.push_back(Ops[0]);
+    TblOps.push_back(Ops[1]);
+    return packTBLDVectorList(CGF, TblOps, nullptr, Ops[2], Ty,
+                              Intrinsic::aarch64_neon_tbl1, "vtbl1");
+  }
+  case NEON::BI__builtin_neon_vtbl3_v: {
+    TblOps.push_back(Ops[0]);
+    TblOps.push_back(Ops[1]);
+    TblOps.push_back(Ops[2]);
+    return packTBLDVectorList(CGF, TblOps, nullptr, Ops[3], Ty,
+                              Intrinsic::aarch64_neon_tbl2, "vtbl2");
+  }
+  case NEON::BI__builtin_neon_vtbl4_v: {
+    TblOps.push_back(Ops[0]);
+    TblOps.push_back(Ops[1]);
+    TblOps.push_back(Ops[2]);
+    TblOps.push_back(Ops[3]);
+    return packTBLDVectorList(CGF, TblOps, nullptr, Ops[4], Ty,
+                              Intrinsic::aarch64_neon_tbl2, "vtbl2");
+  }
+  case NEON::BI__builtin_neon_vtbx1_v: {
+    TblOps.push_back(Ops[1]);
+    Value *TblRes = packTBLDVectorList(CGF, TblOps, nullptr, Ops[2], Ty,
+                                       Intrinsic::aarch64_neon_tbl1, "vtbl1");
+
+    llvm::Constant *Eight = ConstantInt::get(VTy->getElementType(), 8);
+    Value* EightV = llvm::ConstantVector::getSplat(nElts, Eight);
+    Value *CmpRes = Builder.CreateICmp(ICmpInst::ICMP_UGE, Ops[2], EightV);
+    CmpRes = Builder.CreateSExt(CmpRes, Ty);
+
+    Value *EltsFromInput = Builder.CreateAnd(CmpRes, Ops[0]);
+    Value *EltsFromTbl = Builder.CreateAnd(Builder.CreateNot(CmpRes), TblRes);
+    return Builder.CreateOr(EltsFromInput, EltsFromTbl, "vtbx");
+  }
+  case NEON::BI__builtin_neon_vtbx2_v: {
+    TblOps.push_back(Ops[1]);
+    TblOps.push_back(Ops[2]);
+    return packTBLDVectorList(CGF, TblOps, Ops[0], Ops[3], Ty,
+                              Intrinsic::aarch64_neon_tbx1, "vtbx1");
+  }
+  case NEON::BI__builtin_neon_vtbx3_v: {
+    TblOps.push_back(Ops[1]);
+    TblOps.push_back(Ops[2]);
+    TblOps.push_back(Ops[3]);
+    Value *TblRes = packTBLDVectorList(CGF, TblOps, nullptr, Ops[4], Ty,
+                                       Intrinsic::aarch64_neon_tbl2, "vtbl2");
+
+    llvm::Constant *TwentyFour = ConstantInt::get(VTy->getElementType(), 24);
+    Value* TwentyFourV = llvm::ConstantVector::getSplat(nElts, TwentyFour);
+    Value *CmpRes = Builder.CreateICmp(ICmpInst::ICMP_UGE, Ops[4],
+                                           TwentyFourV);
+    CmpRes = Builder.CreateSExt(CmpRes, Ty);
+
+    Value *EltsFromInput = Builder.CreateAnd(CmpRes, Ops[0]);
+    Value *EltsFromTbl = Builder.CreateAnd(Builder.CreateNot(CmpRes), TblRes);
+    return Builder.CreateOr(EltsFromInput, EltsFromTbl, "vtbx");
+  }
+  case NEON::BI__builtin_neon_vtbx4_v: {
+    TblOps.push_back(Ops[1]);
+    TblOps.push_back(Ops[2]);
+    TblOps.push_back(Ops[3]);
+    TblOps.push_back(Ops[4]);
+    return packTBLDVectorList(CGF, TblOps, Ops[0], Ops[5], Ty,
+                              Intrinsic::aarch64_neon_tbx2, "vtbx2");
+  }
+  case NEON::BI__builtin_neon_vqtbl1_v:
+  case NEON::BI__builtin_neon_vqtbl1q_v:
+    Int = Intrinsic::aarch64_neon_tbl1; s = "vtbl1"; break;
+  case NEON::BI__builtin_neon_vqtbl2_v:
+  case NEON::BI__builtin_neon_vqtbl2q_v: {
+    Int = Intrinsic::aarch64_neon_tbl2; s = "vtbl2"; break;
+  case NEON::BI__builtin_neon_vqtbl3_v:
+  case NEON::BI__builtin_neon_vqtbl3q_v:
+    Int = Intrinsic::aarch64_neon_tbl3; s = "vtbl3"; break;
+  case NEON::BI__builtin_neon_vqtbl4_v:
+  case NEON::BI__builtin_neon_vqtbl4q_v:
+    Int = Intrinsic::aarch64_neon_tbl4; s = "vtbl4"; break;
+  case NEON::BI__builtin_neon_vqtbx1_v:
+  case NEON::BI__builtin_neon_vqtbx1q_v:
+    Int = Intrinsic::aarch64_neon_tbx1; s = "vtbx1"; break;
+  case NEON::BI__builtin_neon_vqtbx2_v:
+  case NEON::BI__builtin_neon_vqtbx2q_v:
+    Int = Intrinsic::aarch64_neon_tbx2; s = "vtbx2"; break;
+  case NEON::BI__builtin_neon_vqtbx3_v:
+  case NEON::BI__builtin_neon_vqtbx3q_v:
+    Int = Intrinsic::aarch64_neon_tbx3; s = "vtbx3"; break;
+  case NEON::BI__builtin_neon_vqtbx4_v:
+  case NEON::BI__builtin_neon_vqtbx4q_v:
+    Int = Intrinsic::aarch64_neon_tbx4; s = "vtbx4"; break;
+  }
+  }
+
+  if (!Int)
+    return nullptr;
+
+  Function *F = CGF.CGM.getIntrinsic(Int, Ty);
+  return CGF.EmitNeonCall(F, Ops, s);
+}
+
+Value *CodeGenFunction::vectorWrapScalar16(Value *Op) {
+  llvm::Type *VTy = llvm::VectorType::get(Int16Ty, 4);
+  Op = Builder.CreateBitCast(Op, Int16Ty);
+  Value *V = UndefValue::get(VTy);
+  llvm::Constant *CI = ConstantInt::get(SizeTy, 0);
+  Op = Builder.CreateInsertElement(V, Op, CI);
+  return Op;
+}
+
+Value *CodeGenFunction::vectorWrapScalar8(Value *Op) {
+  llvm::Type *VTy = llvm::VectorType::get(Int8Ty, 8);
+  Op = Builder.CreateBitCast(Op, Int8Ty);
+  Value *V = UndefValue::get(VTy);
+  llvm::Constant *CI = ConstantInt::get(SizeTy, 0);
+  Op = Builder.CreateInsertElement(V, Op, CI);
+  return Op;
+}
+
+Value *CodeGenFunction::
+emitVectorWrappedScalar8Intrinsic(unsigned Int, SmallVectorImpl<Value*> &Ops,
+                                  const char *Name) {
+  // i8 is not a legal types for AArch64, so we can't just use
+  // a normal overloaded intrinsic call for these scalar types. Instead
+  // we'll build 64-bit vectors w/ lane zero being our input values and
+  // perform the operation on that. The back end can pattern match directly
+  // to the scalar instruction.
+  Ops[0] = vectorWrapScalar8(Ops[0]);
+  Ops[1] = vectorWrapScalar8(Ops[1]);
+  llvm::Type *VTy = llvm::VectorType::get(Int8Ty, 8);
+  Value *V = EmitNeonCall(CGM.getIntrinsic(Int, VTy), Ops, Name);
+  Constant *CI = ConstantInt::get(SizeTy, 0);
+  return Builder.CreateExtractElement(V, CI, "lane0");
+}
+
+Value *CodeGenFunction::
+emitVectorWrappedScalar16Intrinsic(unsigned Int, SmallVectorImpl<Value*> &Ops,
+                                   const char *Name) {
+  // i16 is not a legal types for AArch64, so we can't just use
+  // a normal overloaded intrinsic call for these scalar types. Instead
+  // we'll build 64-bit vectors w/ lane zero being our input values and
+  // perform the operation on that. The back end can pattern match directly
+  // to the scalar instruction.
+  Ops[0] = vectorWrapScalar16(Ops[0]);
+  Ops[1] = vectorWrapScalar16(Ops[1]);
+  llvm::Type *VTy = llvm::VectorType::get(Int16Ty, 4);
+  Value *V = EmitNeonCall(CGM.getIntrinsic(Int, VTy), Ops, Name);
+  Constant *CI = ConstantInt::get(SizeTy, 0);
+  return Builder.CreateExtractElement(V, CI, "lane0");
+}
+
+Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
+                                               const CallExpr *E) {
+  unsigned HintID = static_cast<unsigned>(-1);
+  switch (BuiltinID) {
+  default: break;
+  case AArch64::BI__builtin_arm_nop:
+    HintID = 0;
+    break;
+  case AArch64::BI__builtin_arm_yield:
+    HintID = 1;
+    break;
+  case AArch64::BI__builtin_arm_wfe:
+    HintID = 2;
+    break;
+  case AArch64::BI__builtin_arm_wfi:
+    HintID = 3;
+    break;
+  case AArch64::BI__builtin_arm_sev:
+    HintID = 4;
+    break;
+  case AArch64::BI__builtin_arm_sevl:
+    HintID = 5;
+    break;
+  }
+
+  if (HintID != static_cast<unsigned>(-1)) {
+    Function *F = CGM.getIntrinsic(Intrinsic::aarch64_hint);
+    return Builder.CreateCall(F, llvm::ConstantInt::get(Int32Ty, HintID));
+  }
+
+  if (BuiltinID == AArch64::BI__builtin_arm_rbit) {
+    assert((getContext().getTypeSize(E->getType()) == 32) &&
+           "rbit of unusual size!");
+    llvm::Value *Arg = EmitScalarExpr(E->getArg(0));
+    return Builder.CreateCall(
+        CGM.getIntrinsic(Intrinsic::aarch64_rbit, Arg->getType()), Arg, "rbit");
+  }
+  if (BuiltinID == AArch64::BI__builtin_arm_rbit64) {
+    assert((getContext().getTypeSize(E->getType()) == 64) &&
+           "rbit of unusual size!");
+    llvm::Value *Arg = EmitScalarExpr(E->getArg(0));
+    return Builder.CreateCall(
+        CGM.getIntrinsic(Intrinsic::aarch64_rbit, Arg->getType()), Arg, "rbit");
+  }
+
+  if (BuiltinID == AArch64::BI__clear_cache) {
+    assert(E->getNumArgs() == 2 && "__clear_cache takes 2 arguments");
+    const FunctionDecl *FD = E->getDirectCallee();
+    SmallVector<Value*, 2> Ops;
+    for (unsigned i = 0; i < 2; i++)
+      Ops.push_back(EmitScalarExpr(E->getArg(i)));
+    llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType());
+    llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty);
+    StringRef Name = FD->getName();
+    return EmitNounwindRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Ops);
+  }
+
+  if ((BuiltinID == AArch64::BI__builtin_arm_ldrex ||
+      BuiltinID == AArch64::BI__builtin_arm_ldaex) &&
+      getContext().getTypeSize(E->getType()) == 128) {
+    Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_ldaex
+                                       ? Intrinsic::aarch64_ldaxp
+                                       : Intrinsic::aarch64_ldxp);
+
+    Value *LdPtr = EmitScalarExpr(E->getArg(0));
+    Value *Val = Builder.CreateCall(F, Builder.CreateBitCast(LdPtr, Int8PtrTy),
+                                    "ldxp");
+
+    Value *Val0 = Builder.CreateExtractValue(Val, 1);
+    Value *Val1 = Builder.CreateExtractValue(Val, 0);
+    llvm::Type *Int128Ty = llvm::IntegerType::get(getLLVMContext(), 128);
+    Val0 = Builder.CreateZExt(Val0, Int128Ty);
+    Val1 = Builder.CreateZExt(Val1, Int128Ty);
+
+    Value *ShiftCst = llvm::ConstantInt::get(Int128Ty, 64);
+    Val = Builder.CreateShl(Val0, ShiftCst, "shl", true /* nuw */);
+    Val = Builder.CreateOr(Val, Val1);
+    return Builder.CreateBitCast(Val, ConvertType(E->getType()));
+  } else if (BuiltinID == AArch64::BI__builtin_arm_ldrex ||
+             BuiltinID == AArch64::BI__builtin_arm_ldaex) {
+    Value *LoadAddr = EmitScalarExpr(E->getArg(0));
+
+    QualType Ty = E->getType();
+    llvm::Type *RealResTy = ConvertType(Ty);
+    llvm::Type *IntResTy = llvm::IntegerType::get(getLLVMContext(),
+                                                  getContext().getTypeSize(Ty));
+    LoadAddr = Builder.CreateBitCast(LoadAddr, IntResTy->getPointerTo());
+
+    Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_ldaex
+                                       ? Intrinsic::aarch64_ldaxr
+                                       : Intrinsic::aarch64_ldxr,
+                                   LoadAddr->getType());
+    Value *Val = Builder.CreateCall(F, LoadAddr, "ldxr");
+
+    if (RealResTy->isPointerTy())
+      return Builder.CreateIntToPtr(Val, RealResTy);
+
+    Val = Builder.CreateTruncOrBitCast(Val, IntResTy);
+    return Builder.CreateBitCast(Val, RealResTy);
+  }
+
+  if ((BuiltinID == AArch64::BI__builtin_arm_strex ||
+       BuiltinID == AArch64::BI__builtin_arm_stlex) &&
+      getContext().getTypeSize(E->getArg(0)->getType()) == 128) {
+    Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_stlex
+                                       ? Intrinsic::aarch64_stlxp
+                                       : Intrinsic::aarch64_stxp);
+    llvm::Type *STy = llvm::StructType::get(Int64Ty, Int64Ty, NULL);
+
+    Value *One = llvm::ConstantInt::get(Int32Ty, 1);
+    Value *Tmp = Builder.CreateAlloca(ConvertType(E->getArg(0)->getType()),
+                                      One);
+    Value *Val = EmitScalarExpr(E->getArg(0));
+    Builder.CreateStore(Val, Tmp);
+
+    Value *LdPtr = Builder.CreateBitCast(Tmp,llvm::PointerType::getUnqual(STy));
+    Val = Builder.CreateLoad(LdPtr);
+
+    Value *Arg0 = Builder.CreateExtractValue(Val, 0);
+    Value *Arg1 = Builder.CreateExtractValue(Val, 1);
+    Value *StPtr = Builder.CreateBitCast(EmitScalarExpr(E->getArg(1)),
+                                         Int8PtrTy);
+    return Builder.CreateCall3(F, Arg0, Arg1, StPtr, "stxp");
+  } else if (BuiltinID == AArch64::BI__builtin_arm_strex ||
+             BuiltinID == AArch64::BI__builtin_arm_stlex) {
+    Value *StoreVal = EmitScalarExpr(E->getArg(0));
+    Value *StoreAddr = EmitScalarExpr(E->getArg(1));
+
+    QualType Ty = E->getArg(0)->getType();
+    llvm::Type *StoreTy = llvm::IntegerType::get(getLLVMContext(),
+                                                 getContext().getTypeSize(Ty));
+    StoreAddr = Builder.CreateBitCast(StoreAddr, StoreTy->getPointerTo());
+
+    if (StoreVal->getType()->isPointerTy())
+      StoreVal = Builder.CreatePtrToInt(StoreVal, Int64Ty);
+    else {
+      StoreVal = Builder.CreateBitCast(StoreVal, StoreTy);
+      StoreVal = Builder.CreateZExtOrBitCast(StoreVal, Int64Ty);
+    }
+
+    Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_stlex
+                                       ? Intrinsic::aarch64_stlxr
+                                       : Intrinsic::aarch64_stxr,
+                                   StoreAddr->getType());
+    return Builder.CreateCall2(F, StoreVal, StoreAddr, "stxr");
+  }
+
+  if (BuiltinID == AArch64::BI__builtin_arm_clrex) {
+    Function *F = CGM.getIntrinsic(Intrinsic::aarch64_clrex);
+    return Builder.CreateCall(F);
+  }
+
+  // CRC32
+  Intrinsic::ID CRCIntrinsicID = Intrinsic::not_intrinsic;
+  switch (BuiltinID) {
+  case AArch64::BI__builtin_arm_crc32b:
+    CRCIntrinsicID = Intrinsic::aarch64_crc32b; break;
+  case AArch64::BI__builtin_arm_crc32cb:
+    CRCIntrinsicID = Intrinsic::aarch64_crc32cb; break;
+  case AArch64::BI__builtin_arm_crc32h:
+    CRCIntrinsicID = Intrinsic::aarch64_crc32h; break;
+  case AArch64::BI__builtin_arm_crc32ch:
+    CRCIntrinsicID = Intrinsic::aarch64_crc32ch; break;
+  case AArch64::BI__builtin_arm_crc32w:
+    CRCIntrinsicID = Intrinsic::aarch64_crc32w; break;
+  case AArch64::BI__builtin_arm_crc32cw:
+    CRCIntrinsicID = Intrinsic::aarch64_crc32cw; break;
+  case AArch64::BI__builtin_arm_crc32d:
+    CRCIntrinsicID = Intrinsic::aarch64_crc32x; break;
+  case AArch64::BI__builtin_arm_crc32cd:
+    CRCIntrinsicID = Intrinsic::aarch64_crc32cx; break;
+  }
+
+  if (CRCIntrinsicID != Intrinsic::not_intrinsic) {
+    Value *Arg0 = EmitScalarExpr(E->getArg(0));
+    Value *Arg1 = EmitScalarExpr(E->getArg(1));
+    Function *F = CGM.getIntrinsic(CRCIntrinsicID);
+
+    llvm::Type *DataTy = F->getFunctionType()->getParamType(1);
+    Arg1 = Builder.CreateZExtOrBitCast(Arg1, DataTy);
+
+    return Builder.CreateCall2(F, Arg0, Arg1);
+  }
+
+  llvm::SmallVector<Value*, 4> Ops;
+  for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++)
+    Ops.push_back(EmitScalarExpr(E->getArg(i)));
+
+  ArrayRef<NeonIntrinsicInfo> SISDMap(AArch64SISDIntrinsicMap);
+  const NeonIntrinsicInfo *Builtin = findNeonIntrinsicInMap(
+      SISDMap, BuiltinID, AArch64SISDIntrinsicsProvenSorted);
+
+  if (Builtin) {
+    Ops.push_back(EmitScalarExpr(E->getArg(E->getNumArgs() - 1)));
+    Value *Result = EmitCommonNeonSISDBuiltinExpr(*this, *Builtin, Ops, E);
+    assert(Result && "SISD intrinsic should have been handled");
+    return Result;
+  }
+
+  llvm::APSInt Result;
+  const Expr *Arg = E->getArg(E->getNumArgs()-1);
+  NeonTypeFlags Type(0);
+  if (Arg->isIntegerConstantExpr(Result, getContext()))
+    // Determine the type of this overloaded NEON intrinsic.
+    Type = NeonTypeFlags(Result.getZExtValue());
+
+  bool usgn = Type.isUnsigned();
+  bool quad = Type.isQuad();
+
+  // Handle non-overloaded intrinsics first.
+  switch (BuiltinID) {
+  default: break;
+  case NEON::BI__builtin_neon_vldrq_p128: {
+    llvm::Type *Int128PTy = llvm::Type::getIntNPtrTy(getLLVMContext(), 128);
+    Value *Ptr = Builder.CreateBitCast(EmitScalarExpr(E->getArg(0)), Int128PTy);
+    return Builder.CreateLoad(Ptr);
+  }
+  case NEON::BI__builtin_neon_vstrq_p128: {
+    llvm::Type *Int128PTy = llvm::Type::getIntNPtrTy(getLLVMContext(), 128);
+    Value *Ptr = Builder.CreateBitCast(Ops[0], Int128PTy);
+    return Builder.CreateStore(EmitScalarExpr(E->getArg(1)), Ptr);
+  }
+  case NEON::BI__builtin_neon_vcvts_u32_f32:
+  case NEON::BI__builtin_neon_vcvtd_u64_f64:
+    usgn = true;
+    // FALL THROUGH
+  case NEON::BI__builtin_neon_vcvts_s32_f32:
+  case NEON::BI__builtin_neon_vcvtd_s64_f64: {
+    Ops.push_back(EmitScalarExpr(E->getArg(0)));
+    bool Is64 = Ops[0]->getType()->getPrimitiveSizeInBits() == 64;
+    llvm::Type *InTy = Is64 ? Int64Ty : Int32Ty;
+    llvm::Type *FTy = Is64 ? DoubleTy : FloatTy;
+    Ops[0] = Builder.CreateBitCast(Ops[0], FTy);
+    if (usgn)
+      return Builder.CreateFPToUI(Ops[0], InTy);
+    return Builder.CreateFPToSI(Ops[0], InTy);
+  }
+  case NEON::BI__builtin_neon_vcvts_f32_u32:
+  case NEON::BI__builtin_neon_vcvtd_f64_u64:
+    usgn = true;
+    // FALL THROUGH
+  case NEON::BI__builtin_neon_vcvts_f32_s32:
+  case NEON::BI__builtin_neon_vcvtd_f64_s64: {
+    Ops.push_back(EmitScalarExpr(E->getArg(0)));
+    bool Is64 = Ops[0]->getType()->getPrimitiveSizeInBits() == 64;
+    llvm::Type *InTy = Is64 ? Int64Ty : Int32Ty;
+    llvm::Type *FTy = Is64 ? DoubleTy : FloatTy;
+    Ops[0] = Builder.CreateBitCast(Ops[0], InTy);
+    if (usgn)
+      return Builder.CreateUIToFP(Ops[0], FTy);
+    return Builder.CreateSIToFP(Ops[0], FTy);
+  }
+  case NEON::BI__builtin_neon_vpaddd_s64: {
+    llvm::Type *Ty =
+      llvm::VectorType::get(llvm::Type::getInt64Ty(getLLVMContext()), 2);
+    Value *Vec = EmitScalarExpr(E->getArg(0));
+    // The vector is v2f64, so make sure it's bitcast to that.
+    Vec = Builder.CreateBitCast(Vec, Ty, "v2i64");
+    llvm::Value *Idx0 = llvm::ConstantInt::get(SizeTy, 0);
+    llvm::Value *Idx1 = llvm::ConstantInt::get(SizeTy, 1);
+    Value *Op0 = Builder.CreateExtractElement(Vec, Idx0, "lane0");
+    Value *Op1 = Builder.CreateExtractElement(Vec, Idx1, "lane1");
+    // Pairwise addition of a v2f64 into a scalar f64.
+    return Builder.CreateAdd(Op0, Op1, "vpaddd");
+  }
+  case NEON::BI__builtin_neon_vpaddd_f64: {
+    llvm::Type *Ty =
+      llvm::VectorType::get(llvm::Type::getDoubleTy(getLLVMContext()), 2);
+    Value *Vec = EmitScalarExpr(E->getArg(0));
+    // The vector is v2f64, so make sure it's bitcast to that.
+    Vec = Builder.CreateBitCast(Vec, Ty, "v2f64");
+    llvm::Value *Idx0 = llvm::ConstantInt::get(SizeTy, 0);
+    llvm::Value *Idx1 = llvm::ConstantInt::get(SizeTy, 1);
+    Value *Op0 = Builder.CreateExtractElement(Vec, Idx0, "lane0");
+    Value *Op1 = Builder.CreateExtractElement(Vec, Idx1, "lane1");
+    // Pairwise addition of a v2f64 into a scalar f64.
+    return Builder.CreateFAdd(Op0, Op1, "vpaddd");
+  }
+  case NEON::BI__builtin_neon_vpadds_f32: {
+    llvm::Type *Ty =
+      llvm::VectorType::get(llvm::Type::getFloatTy(getLLVMContext()), 2);
+    Value *Vec = EmitScalarExpr(E->getArg(0));
+    // The vector is v2f32, so make sure it's bitcast to that.
+    Vec = Builder.CreateBitCast(Vec, Ty, "v2f32");
+    llvm::Value *Idx0 = llvm::ConstantInt::get(SizeTy, 0);
+    llvm::Value *Idx1 = llvm::ConstantInt::get(SizeTy, 1);
+    Value *Op0 = Builder.CreateExtractElement(Vec, Idx0, "lane0");
+    Value *Op1 = Builder.CreateExtractElement(Vec, Idx1, "lane1");
+    // Pairwise addition of a v2f32 into a scalar f32.
+    return Builder.CreateFAdd(Op0, Op1, "vpaddd");
+  }
+  case NEON::BI__builtin_neon_vceqzd_s64:
+  case NEON::BI__builtin_neon_vceqzd_f64:
+  case NEON::BI__builtin_neon_vceqzs_f32:
+    Ops.push_back(EmitScalarExpr(E->getArg(0)));
+    return EmitAArch64CompareBuiltinExpr(
+        Ops[0], ConvertType(E->getCallReturnType()), ICmpInst::FCMP_OEQ,
+        ICmpInst::ICMP_EQ, "vceqz");
+  case NEON::BI__builtin_neon_vcgezd_s64:
+  case NEON::BI__builtin_neon_vcgezd_f64:
+  case NEON::BI__builtin_neon_vcgezs_f32:
+    Ops.push_back(EmitScalarExpr(E->getArg(0)));
+    return EmitAArch64CompareBuiltinExpr(
+        Ops[0], ConvertType(E->getCallReturnType()), ICmpInst::FCMP_OGE,
+        ICmpInst::ICMP_SGE, "vcgez");
+  case NEON::BI__builtin_neon_vclezd_s64:
+  case NEON::BI__builtin_neon_vclezd_f64:
+  case NEON::BI__builtin_neon_vclezs_f32:
+    Ops.push_back(EmitScalarExpr(E->getArg(0)));
+    return EmitAArch64CompareBuiltinExpr(
+        Ops[0], ConvertType(E->getCallReturnType()), ICmpInst::FCMP_OLE,
+        ICmpInst::ICMP_SLE, "vclez");
+  case NEON::BI__builtin_neon_vcgtzd_s64:
+  case NEON::BI__builtin_neon_vcgtzd_f64:
+  case NEON::BI__builtin_neon_vcgtzs_f32:
+    Ops.push_back(EmitScalarExpr(E->getArg(0)));
+    return EmitAArch64CompareBuiltinExpr(
+        Ops[0], ConvertType(E->getCallReturnType()), ICmpInst::FCMP_OGT,
+        ICmpInst::ICMP_SGT, "vcgtz");
+  case NEON::BI__builtin_neon_vcltzd_s64:
+  case NEON::BI__builtin_neon_vcltzd_f64:
+  case NEON::BI__builtin_neon_vcltzs_f32:
+    Ops.push_back(EmitScalarExpr(E->getArg(0)));
+    return EmitAArch64CompareBuiltinExpr(
+        Ops[0], ConvertType(E->getCallReturnType()), ICmpInst::FCMP_OLT,
+        ICmpInst::ICMP_SLT, "vcltz");
+
+  case NEON::BI__builtin_neon_vceqzd_u64: {
+    llvm::Type *Ty = llvm::Type::getInt64Ty(getLLVMContext());
+    Ops.push_back(EmitScalarExpr(E->getArg(0)));
+    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
+    Ops[0] = Builder.CreateICmp(llvm::ICmpInst::ICMP_EQ, Ops[0],
+                                llvm::Constant::getNullValue(Ty));
+    return Builder.CreateSExt(Ops[0], Ty, "vceqzd");
+  }
+  case NEON::BI__builtin_neon_vceqd_f64:
+  case NEON::BI__builtin_neon_vcled_f64:
+  case NEON::BI__builtin_neon_vcltd_f64:
+  case NEON::BI__builtin_neon_vcged_f64:
+  case NEON::BI__builtin_neon_vcgtd_f64: {
+    llvm::CmpInst::Predicate P;
+    switch (BuiltinID) {
+    default: llvm_unreachable("missing builtin ID in switch!");
+    case NEON::BI__builtin_neon_vceqd_f64: P = llvm::FCmpInst::FCMP_OEQ; break;
+    case NEON::BI__builtin_neon_vcled_f64: P = llvm::FCmpInst::FCMP_OLE; break;
+    case NEON::BI__builtin_neon_vcltd_f64: P = llvm::FCmpInst::FCMP_OLT; break;
+    case NEON::BI__builtin_neon_vcged_f64: P = llvm::FCmpInst::FCMP_OGE; break;
+    case NEON::BI__builtin_neon_vcgtd_f64: P = llvm::FCmpInst::FCMP_OGT; break;
+    }
+    Ops.push_back(EmitScalarExpr(E->getArg(1)));
+    Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy);
+    Ops[1] = Builder.CreateBitCast(Ops[1], DoubleTy);
+    Ops[0] = Builder.CreateFCmp(P, Ops[0], Ops[1]);
+    return Builder.CreateSExt(Ops[0], Int64Ty, "vcmpd");
+  }
+  case NEON::BI__builtin_neon_vceqs_f32:
+  case NEON::BI__builtin_neon_vcles_f32:
+  case NEON::BI__builtin_neon_vclts_f32:
+  case NEON::BI__builtin_neon_vcges_f32:
+  case NEON::BI__builtin_neon_vcgts_f32: {
+    llvm::CmpInst::Predicate P;
+    switch (BuiltinID) {
+    default: llvm_unreachable("missing builtin ID in switch!");
+    case NEON::BI__builtin_neon_vceqs_f32: P = llvm::FCmpInst::FCMP_OEQ; break;
+    case NEON::BI__builtin_neon_vcles_f32: P = llvm::FCmpInst::FCMP_OLE; break;
+    case NEON::BI__builtin_neon_vclts_f32: P = llvm::FCmpInst::FCMP_OLT; break;
+    case NEON::BI__builtin_neon_vcges_f32: P = llvm::FCmpInst::FCMP_OGE; break;
+    case NEON::BI__builtin_neon_vcgts_f32: P = llvm::FCmpInst::FCMP_OGT; break;
+    }
+    Ops.push_back(EmitScalarExpr(E->getArg(1)));
+    Ops[0] = Builder.CreateBitCast(Ops[0], FloatTy);
+    Ops[1] = Builder.CreateBitCast(Ops[1], FloatTy);
+    Ops[0] = Builder.CreateFCmp(P, Ops[0], Ops[1]);
+    return Builder.CreateSExt(Ops[0], Int32Ty, "vcmpd");
+  }
+  case NEON::BI__builtin_neon_vceqd_s64:
+  case NEON::BI__builtin_neon_vceqd_u64:
+  case NEON::BI__builtin_neon_vcgtd_s64:
+  case NEON::BI__builtin_neon_vcgtd_u64:
+  case NEON::BI__builtin_neon_vcltd_s64:
+  case NEON::BI__builtin_neon_vcltd_u64:
+  case NEON::BI__builtin_neon_vcged_u64:
+  case NEON::BI__builtin_neon_vcged_s64:
+  case NEON::BI__builtin_neon_vcled_u64:
+  case NEON::BI__builtin_neon_vcled_s64: {
+    llvm::CmpInst::Predicate P;
+    switch (BuiltinID) {
+    default: llvm_unreachable("missing builtin ID in switch!");
+    case NEON::BI__builtin_neon_vceqd_s64:
+    case NEON::BI__builtin_neon_vceqd_u64:P = llvm::ICmpInst::ICMP_EQ;break;
+    case NEON::BI__builtin_neon_vcgtd_s64:P = llvm::ICmpInst::ICMP_SGT;break;
+    case NEON::BI__builtin_neon_vcgtd_u64:P = llvm::ICmpInst::ICMP_UGT;break;
+    case NEON::BI__builtin_neon_vcltd_s64:P = llvm::ICmpInst::ICMP_SLT;break;
+    case NEON::BI__builtin_neon_vcltd_u64:P = llvm::ICmpInst::ICMP_ULT;break;
+    case NEON::BI__builtin_neon_vcged_u64:P = llvm::ICmpInst::ICMP_UGE;break;
+    case NEON::BI__builtin_neon_vcged_s64:P = llvm::ICmpInst::ICMP_SGE;break;
+    case NEON::BI__builtin_neon_vcled_u64:P = llvm::ICmpInst::ICMP_ULE;break;
+    case NEON::BI__builtin_neon_vcled_s64:P = llvm::ICmpInst::ICMP_SLE;break;
+    }
+    Ops.push_back(EmitScalarExpr(E->getArg(1)));
+    Ops[0] = Builder.CreateBitCast(Ops[0], Int64Ty);
+    Ops[1] = Builder.CreateBitCast(Ops[1], Int64Ty);
+    Ops[0] = Builder.CreateICmp(P, Ops[0], Ops[1]);
+    return Builder.CreateSExt(Ops[0], Int64Ty, "vceqd");
+  }
+  case NEON::BI__builtin_neon_vtstd_s64:
+  case NEON::BI__builtin_neon_vtstd_u64: {
+    llvm::Type *Ty = llvm::Type::getInt64Ty(getLLVMContext());
+    Ops.push_back(EmitScalarExpr(E->getArg(1)));
     Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
     Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
     Ops[0] = Builder.CreateAnd(Ops[0], Ops[1]);
     Ops[0] = Builder.CreateICmp(ICmpInst::ICMP_NE, Ops[0],
-                                ConstantAggregateZero::get(Ty));
-    return Builder.CreateSExt(Ops[0], Ty, "vtst");
+                                llvm::Constant::getNullValue(Ty));
+    return Builder.CreateSExt(Ops[0], Ty, "vtstd");
   }
-  case ARM::BI__builtin_neon_vtrn_v:
-  case ARM::BI__builtin_neon_vtrnq_v: {
+  case NEON::BI__builtin_neon_vset_lane_i8:
+  case NEON::BI__builtin_neon_vset_lane_i16:
+  case NEON::BI__builtin_neon_vset_lane_i32:
+  case NEON::BI__builtin_neon_vset_lane_i64:
+  case NEON::BI__builtin_neon_vset_lane_f32:
+  case NEON::BI__builtin_neon_vsetq_lane_i8:
+  case NEON::BI__builtin_neon_vsetq_lane_i16:
+  case NEON::BI__builtin_neon_vsetq_lane_i32:
+  case NEON::BI__builtin_neon_vsetq_lane_i64:
+  case NEON::BI__builtin_neon_vsetq_lane_f32:
+    Ops.push_back(EmitScalarExpr(E->getArg(2)));
+    return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane");
+  case NEON::BI__builtin_neon_vset_lane_f64:
+    // The vector type needs a cast for the v1f64 variant.
+    Ops[1] = Builder.CreateBitCast(Ops[1],
+                                   llvm::VectorType::get(DoubleTy, 1));
+    Ops.push_back(EmitScalarExpr(E->getArg(2)));
+    return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane");
+  case NEON::BI__builtin_neon_vsetq_lane_f64:
+    // The vector type needs a cast for the v2f64 variant.
+    Ops[1] = Builder.CreateBitCast(Ops[1],
+        llvm::VectorType::get(llvm::Type::getDoubleTy(getLLVMContext()), 2));
+    Ops.push_back(EmitScalarExpr(E->getArg(2)));
+    return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane");
+
+  case NEON::BI__builtin_neon_vget_lane_i8:
+  case NEON::BI__builtin_neon_vdupb_lane_i8:
+    Ops[0] = Builder.CreateBitCast(Ops[0],
+        llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 8), 8));
+    return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
+                                        "vget_lane");
+  case NEON::BI__builtin_neon_vgetq_lane_i8:
+  case NEON::BI__builtin_neon_vdupb_laneq_i8:
+    Ops[0] = Builder.CreateBitCast(Ops[0],
+        llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 8), 16));
+    return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
+                                        "vgetq_lane");
+  case NEON::BI__builtin_neon_vget_lane_i16:
+  case NEON::BI__builtin_neon_vduph_lane_i16:
+    Ops[0] = Builder.CreateBitCast(Ops[0],
+        llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 16), 4));
+    return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
+                                        "vget_lane");
+  case NEON::BI__builtin_neon_vgetq_lane_i16:
+  case NEON::BI__builtin_neon_vduph_laneq_i16:
+    Ops[0] = Builder.CreateBitCast(Ops[0],
+        llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 16), 8));
+    return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
+                                        "vgetq_lane");
+  case NEON::BI__builtin_neon_vget_lane_i32:
+  case NEON::BI__builtin_neon_vdups_lane_i32:
+    Ops[0] = Builder.CreateBitCast(
+        Ops[0],
+        llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 32), 2));
+    return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
+                                        "vget_lane");
+  case NEON::BI__builtin_neon_vdups_lane_f32:
+    Ops[0] = Builder.CreateBitCast(Ops[0],
+        llvm::VectorType::get(llvm::Type::getFloatTy(getLLVMContext()), 2));
+    return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
+                                        "vdups_lane");
+  case NEON::BI__builtin_neon_vgetq_lane_i32:
+  case NEON::BI__builtin_neon_vdups_laneq_i32:
+    Ops[0] = Builder.CreateBitCast(Ops[0],
+        llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 32), 4));
+    return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
+                                        "vgetq_lane");
+  case NEON::BI__builtin_neon_vget_lane_i64:
+  case NEON::BI__builtin_neon_vdupd_lane_i64:
+    Ops[0] = Builder.CreateBitCast(Ops[0],
+        llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 64), 1));
+    return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
+                                        "vget_lane");
+  case NEON::BI__builtin_neon_vdupd_lane_f64:
+    Ops[0] = Builder.CreateBitCast(Ops[0],
+        llvm::VectorType::get(llvm::Type::getDoubleTy(getLLVMContext()), 1));
+    return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
+                                        "vdupd_lane");
+  case NEON::BI__builtin_neon_vgetq_lane_i64:
+  case NEON::BI__builtin_neon_vdupd_laneq_i64:
+    Ops[0] = Builder.CreateBitCast(Ops[0],
+        llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 64), 2));
+    return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
+                                        "vgetq_lane");
+  case NEON::BI__builtin_neon_vget_lane_f32:
+    Ops[0] = Builder.CreateBitCast(Ops[0],
+        llvm::VectorType::get(llvm::Type::getFloatTy(getLLVMContext()), 2));
+    return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
+                                        "vget_lane");
+  case NEON::BI__builtin_neon_vget_lane_f64:
+    Ops[0] = Builder.CreateBitCast(Ops[0],
+        llvm::VectorType::get(llvm::Type::getDoubleTy(getLLVMContext()), 1));
+    return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
+                                        "vget_lane");
+  case NEON::BI__builtin_neon_vgetq_lane_f32:
+  case NEON::BI__builtin_neon_vdups_laneq_f32:
+    Ops[0] = Builder.CreateBitCast(Ops[0],
+        llvm::VectorType::get(llvm::Type::getFloatTy(getLLVMContext()), 4));
+    return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
+                                        "vgetq_lane");
+  case NEON::BI__builtin_neon_vgetq_lane_f64:
+  case NEON::BI__builtin_neon_vdupd_laneq_f64:
+    Ops[0] = Builder.CreateBitCast(Ops[0],
+        llvm::VectorType::get(llvm::Type::getDoubleTy(getLLVMContext()), 2));
+    return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
+                                        "vgetq_lane");
+  case NEON::BI__builtin_neon_vaddd_s64:
+  case NEON::BI__builtin_neon_vaddd_u64:
+    return Builder.CreateAdd(Ops[0], EmitScalarExpr(E->getArg(1)), "vaddd");
+  case NEON::BI__builtin_neon_vsubd_s64:
+  case NEON::BI__builtin_neon_vsubd_u64:
+    return Builder.CreateSub(Ops[0], EmitScalarExpr(E->getArg(1)), "vsubd");
+  case NEON::BI__builtin_neon_vqdmlalh_s16:
+  case NEON::BI__builtin_neon_vqdmlslh_s16: {
+    SmallVector<Value *, 2> ProductOps;
+    ProductOps.push_back(vectorWrapScalar16(Ops[1]));
+    ProductOps.push_back(vectorWrapScalar16(EmitScalarExpr(E->getArg(2))));
+    llvm::Type *VTy = llvm::VectorType::get(Int32Ty, 4);
+    Ops[1] = EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmull, VTy),
+                          ProductOps, "vqdmlXl");
+    Constant *CI = ConstantInt::get(SizeTy, 0);
+    Ops[1] = Builder.CreateExtractElement(Ops[1], CI, "lane0");
+
+    unsigned AccumInt = BuiltinID == NEON::BI__builtin_neon_vqdmlalh_s16
+                                        ? Intrinsic::aarch64_neon_sqadd
+                                        : Intrinsic::aarch64_neon_sqsub;
+    return EmitNeonCall(CGM.getIntrinsic(AccumInt, Int32Ty), Ops, "vqdmlXl");
+  }
+  case NEON::BI__builtin_neon_vqshlud_n_s64: {
+    Ops.push_back(EmitScalarExpr(E->getArg(1)));
+    Ops[1] = Builder.CreateZExt(Ops[1], Int64Ty);
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqshlu, Int64Ty),
+                        Ops, "vqshlu_n");
+  }
+  case NEON::BI__builtin_neon_vqshld_n_u64:
+  case NEON::BI__builtin_neon_vqshld_n_s64: {
+    unsigned Int = BuiltinID == NEON::BI__builtin_neon_vqshld_n_u64
+                                   ? Intrinsic::aarch64_neon_uqshl
+                                   : Intrinsic::aarch64_neon_sqshl;
+    Ops.push_back(EmitScalarExpr(E->getArg(1)));
+    Ops[1] = Builder.CreateZExt(Ops[1], Int64Ty);
+    return EmitNeonCall(CGM.getIntrinsic(Int, Int64Ty), Ops, "vqshl_n");
+  }
+  case NEON::BI__builtin_neon_vrshrd_n_u64:
+  case NEON::BI__builtin_neon_vrshrd_n_s64: {
+    unsigned Int = BuiltinID == NEON::BI__builtin_neon_vrshrd_n_u64
+                                   ? Intrinsic::aarch64_neon_urshl
+                                   : Intrinsic::aarch64_neon_srshl;
+    Ops.push_back(EmitScalarExpr(E->getArg(1)));
+    int SV = cast<ConstantInt>(Ops[1])->getSExtValue();
+    Ops[1] = ConstantInt::get(Int64Ty, -SV);
+    return EmitNeonCall(CGM.getIntrinsic(Int, Int64Ty), Ops, "vrshr_n");
+  }
+  case NEON::BI__builtin_neon_vrsrad_n_u64:
+  case NEON::BI__builtin_neon_vrsrad_n_s64: {
+    unsigned Int = BuiltinID == NEON::BI__builtin_neon_vrsrad_n_u64
+                                   ? Intrinsic::aarch64_neon_urshl
+                                   : Intrinsic::aarch64_neon_srshl;
+    Ops[1] = Builder.CreateBitCast(Ops[1], Int64Ty);
+    Ops.push_back(Builder.CreateNeg(EmitScalarExpr(E->getArg(2))));
+    Ops[1] = Builder.CreateCall2(CGM.getIntrinsic(Int, Int64Ty), Ops[1],
+                                 Builder.CreateSExt(Ops[2], Int64Ty));
+    return Builder.CreateAdd(Ops[0], Builder.CreateBitCast(Ops[1], Int64Ty));
+  }
+  case NEON::BI__builtin_neon_vshld_n_s64:
+  case NEON::BI__builtin_neon_vshld_n_u64: {
+    llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(1)));
+    return Builder.CreateShl(
+        Ops[0], ConstantInt::get(Int64Ty, Amt->getZExtValue()), "shld_n");
+  }
+  case NEON::BI__builtin_neon_vshrd_n_s64: {
+    llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(1)));
+    return Builder.CreateAShr(
+        Ops[0], ConstantInt::get(Int64Ty, std::min(static_cast<uint64_t>(63),
+                                                   Amt->getZExtValue())),
+        "shrd_n");
+  }
+  case NEON::BI__builtin_neon_vshrd_n_u64: {
+    llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(1)));
+    uint64_t ShiftAmt = Amt->getZExtValue();
+    // Right-shifting an unsigned value by its size yields 0.
+    if (ShiftAmt == 64)
+      return ConstantInt::get(Int64Ty, 0);
+    return Builder.CreateLShr(Ops[0], ConstantInt::get(Int64Ty, ShiftAmt),
+                              "shrd_n");
+  }
+  case NEON::BI__builtin_neon_vsrad_n_s64: {
+    llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(2)));
+    Ops[1] = Builder.CreateAShr(
+        Ops[1], ConstantInt::get(Int64Ty, std::min(static_cast<uint64_t>(63),
+                                                   Amt->getZExtValue())),
+        "shrd_n");
+    return Builder.CreateAdd(Ops[0], Ops[1]);
+  }
+  case NEON::BI__builtin_neon_vsrad_n_u64: {
+    llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(2)));
+    uint64_t ShiftAmt = Amt->getZExtValue();
+    // Right-shifting an unsigned value by its size yields 0.
+    // As Op + 0 = Op, return Ops[0] directly.
+    if (ShiftAmt == 64)
+      return Ops[0];
+    Ops[1] = Builder.CreateLShr(Ops[1], ConstantInt::get(Int64Ty, ShiftAmt),
+                                "shrd_n");
+    return Builder.CreateAdd(Ops[0], Ops[1]);
+  }
+  case NEON::BI__builtin_neon_vqdmlalh_lane_s16:
+  case NEON::BI__builtin_neon_vqdmlalh_laneq_s16:
+  case NEON::BI__builtin_neon_vqdmlslh_lane_s16:
+  case NEON::BI__builtin_neon_vqdmlslh_laneq_s16: {
+    Ops[2] = Builder.CreateExtractElement(Ops[2], EmitScalarExpr(E->getArg(3)),
+                                          "lane");
+    SmallVector<Value *, 2> ProductOps;
+    ProductOps.push_back(vectorWrapScalar16(Ops[1]));
+    ProductOps.push_back(vectorWrapScalar16(Ops[2]));
+    llvm::Type *VTy = llvm::VectorType::get(Int32Ty, 4);
+    Ops[1] = EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmull, VTy),
+                          ProductOps, "vqdmlXl");
+    Constant *CI = ConstantInt::get(SizeTy, 0);
+    Ops[1] = Builder.CreateExtractElement(Ops[1], CI, "lane0");
+    Ops.pop_back();
+
+    unsigned AccInt = (BuiltinID == NEON::BI__builtin_neon_vqdmlalh_lane_s16 ||
+                       BuiltinID == NEON::BI__builtin_neon_vqdmlalh_laneq_s16)
+                          ? Intrinsic::aarch64_neon_sqadd
+                          : Intrinsic::aarch64_neon_sqsub;
+    return EmitNeonCall(CGM.getIntrinsic(AccInt, Int32Ty), Ops, "vqdmlXl");
+  }
+  case NEON::BI__builtin_neon_vqdmlals_s32:
+  case NEON::BI__builtin_neon_vqdmlsls_s32: {
+    SmallVector<Value *, 2> ProductOps;
+    ProductOps.push_back(Ops[1]);
+    ProductOps.push_back(EmitScalarExpr(E->getArg(2)));
+    Ops[1] =
+        EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmulls_scalar),
+                     ProductOps, "vqdmlXl");
+
+    unsigned AccumInt = BuiltinID == NEON::BI__builtin_neon_vqdmlals_s32
+                                        ? Intrinsic::aarch64_neon_sqadd
+                                        : Intrinsic::aarch64_neon_sqsub;
+    return EmitNeonCall(CGM.getIntrinsic(AccumInt, Int64Ty), Ops, "vqdmlXl");
+  }
+  case NEON::BI__builtin_neon_vqdmlals_lane_s32:
+  case NEON::BI__builtin_neon_vqdmlals_laneq_s32:
+  case NEON::BI__builtin_neon_vqdmlsls_lane_s32:
+  case NEON::BI__builtin_neon_vqdmlsls_laneq_s32: {
+    Ops[2] = Builder.CreateExtractElement(Ops[2], EmitScalarExpr(E->getArg(3)),
+                                          "lane");
+    SmallVector<Value *, 2> ProductOps;
+    ProductOps.push_back(Ops[1]);
+    ProductOps.push_back(Ops[2]);
+    Ops[1] =
+        EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmulls_scalar),
+                     ProductOps, "vqdmlXl");
+    Ops.pop_back();
+
+    unsigned AccInt = (BuiltinID == NEON::BI__builtin_neon_vqdmlals_lane_s32 ||
+                       BuiltinID == NEON::BI__builtin_neon_vqdmlals_laneq_s32)
+                          ? Intrinsic::aarch64_neon_sqadd
+                          : Intrinsic::aarch64_neon_sqsub;
+    return EmitNeonCall(CGM.getIntrinsic(AccInt, Int64Ty), Ops, "vqdmlXl");
+  }
+  }
+
+  llvm::VectorType *VTy = GetNeonType(this, Type);
+  llvm::Type *Ty = VTy;
+  if (!Ty)
+    return nullptr;
+
+  // Not all intrinsics handled by the common case work for AArch64 yet, so only
+  // defer to common code if it's been added to our special map.
+  Builtin = findNeonIntrinsicInMap(AArch64SIMDIntrinsicMap, BuiltinID,
+                                   AArch64SIMDIntrinsicsProvenSorted);
+
+  if (Builtin)
+    return EmitCommonNeonBuiltinExpr(
+        Builtin->BuiltinID, Builtin->LLVMIntrinsic, Builtin->AltLLVMIntrinsic,
+        Builtin->NameHint, Builtin->TypeModifier, E, Ops, nullptr);
+
+  if (Value *V = EmitAArch64TblBuiltinExpr(*this, BuiltinID, E, Ops))
+    return V;
+
+  unsigned Int;
+  switch (BuiltinID) {
+  default: return nullptr;
+  case NEON::BI__builtin_neon_vbsl_v:
+  case NEON::BI__builtin_neon_vbslq_v: {
+    llvm::Type *BitTy = llvm::VectorType::getInteger(VTy);
+    Ops[0] = Builder.CreateBitCast(Ops[0], BitTy, "vbsl");
+    Ops[1] = Builder.CreateBitCast(Ops[1], BitTy, "vbsl");
+    Ops[2] = Builder.CreateBitCast(Ops[2], BitTy, "vbsl");
+
+    Ops[1] = Builder.CreateAnd(Ops[0], Ops[1], "vbsl");
+    Ops[2] = Builder.CreateAnd(Builder.CreateNot(Ops[0]), Ops[2], "vbsl");
+    Ops[0] = Builder.CreateOr(Ops[1], Ops[2], "vbsl");
+    return Builder.CreateBitCast(Ops[0], Ty);
+  }
+  case NEON::BI__builtin_neon_vfma_lane_v:
+  case NEON::BI__builtin_neon_vfmaq_lane_v: { // Only used for FP types
+    // The ARM builtins (and instructions) have the addend as the first
+    // operand, but the 'fma' intrinsics have it last. Swap it around here.
+    Value *Addend = Ops[0];
+    Value *Multiplicand = Ops[1];
+    Value *LaneSource = Ops[2];
+    Ops[0] = Multiplicand;
+    Ops[1] = LaneSource;
+    Ops[2] = Addend;
+
+    // Now adjust things to handle the lane access.
+    llvm::Type *SourceTy = BuiltinID == NEON::BI__builtin_neon_vfmaq_lane_v ?
+      llvm::VectorType::get(VTy->getElementType(), VTy->getNumElements() / 2) :
+      VTy;
+    llvm::Constant *cst = cast<Constant>(Ops[3]);
+    Value *SV = llvm::ConstantVector::getSplat(VTy->getNumElements(), cst);
+    Ops[1] = Builder.CreateBitCast(Ops[1], SourceTy);
+    Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV, "lane");
+
+    Ops.pop_back();
+    Int = Intrinsic::fma;
+    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "fmla");
+  }
+  case NEON::BI__builtin_neon_vfma_laneq_v: {
+    llvm::VectorType *VTy = cast<llvm::VectorType>(Ty);
+    // v1f64 fma should be mapped to Neon scalar f64 fma
+    if (VTy && VTy->getElementType() == DoubleTy) {
+      Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy);
+      Ops[1] = Builder.CreateBitCast(Ops[1], DoubleTy);
+      llvm::Type *VTy = GetNeonType(this,
+        NeonTypeFlags(NeonTypeFlags::Float64, false, true));
+      Ops[2] = Builder.CreateBitCast(Ops[2], VTy);
+      Ops[2] = Builder.CreateExtractElement(Ops[2], Ops[3], "extract");
+      Value *F = CGM.getIntrinsic(Intrinsic::fma, DoubleTy);
+      Value *Result = Builder.CreateCall3(F, Ops[1], Ops[2], Ops[0]);
+      return Builder.CreateBitCast(Result, Ty);
+    }
+    Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty);
+    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
+    Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
+
+    llvm::Type *STy = llvm::VectorType::get(VTy->getElementType(),
+                                            VTy->getNumElements() * 2);
+    Ops[2] = Builder.CreateBitCast(Ops[2], STy);
+    Value* SV = llvm::ConstantVector::getSplat(VTy->getNumElements(),
+                                               cast<ConstantInt>(Ops[3]));
+    Ops[2] = Builder.CreateShuffleVector(Ops[2], Ops[2], SV, "lane");
+
+    return Builder.CreateCall3(F, Ops[2], Ops[1], Ops[0]);
+  }
+  case NEON::BI__builtin_neon_vfmaq_laneq_v: {
+    Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty);
+    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
+    Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
+
+    Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
+    Ops[2] = EmitNeonSplat(Ops[2], cast<ConstantInt>(Ops[3]));
+    return Builder.CreateCall3(F, Ops[2], Ops[1], Ops[0]);
+  }
+  case NEON::BI__builtin_neon_vfmas_lane_f32:
+  case NEON::BI__builtin_neon_vfmas_laneq_f32:
+  case NEON::BI__builtin_neon_vfmad_lane_f64:
+  case NEON::BI__builtin_neon_vfmad_laneq_f64: {
+    Ops.push_back(EmitScalarExpr(E->getArg(3)));
+    llvm::Type *Ty = ConvertType(E->getCallReturnType());
+    Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty);
+    Ops[2] = Builder.CreateExtractElement(Ops[2], Ops[3], "extract");
+    return Builder.CreateCall3(F, Ops[1], Ops[2], Ops[0]);
+  }
+  case NEON::BI__builtin_neon_vfms_v:
+  case NEON::BI__builtin_neon_vfmsq_v: {  // Only used for FP types
+    // FIXME: probably remove when we no longer support aarch64_simd.h
+    // (arm_neon.h delegates to vfma).
+
+    // The ARM builtins (and instructions) have the addend as the first
+    // operand, but the 'fma' intrinsics have it last. Swap it around here.
+    Value *Subtrahend = Ops[0];
+    Value *Multiplicand = Ops[2];
+    Ops[0] = Multiplicand;
+    Ops[2] = Subtrahend;
+    Ops[1] = Builder.CreateBitCast(Ops[1], VTy);
+    Ops[1] = Builder.CreateFNeg(Ops[1]);
+    Int = Intrinsic::fma;
+    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "fmls");
+  }
+  case NEON::BI__builtin_neon_vmull_v:
+    // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics.
+    Int = usgn ? Intrinsic::aarch64_neon_umull : Intrinsic::aarch64_neon_smull;
+    if (Type.isPoly()) Int = Intrinsic::aarch64_neon_pmull;
+    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmull");
+  case NEON::BI__builtin_neon_vmax_v:
+  case NEON::BI__builtin_neon_vmaxq_v:
+    // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics.
+    Int = usgn ? Intrinsic::aarch64_neon_umax : Intrinsic::aarch64_neon_smax;
+    if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fmax;
+    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmax");
+  case NEON::BI__builtin_neon_vmin_v:
+  case NEON::BI__builtin_neon_vminq_v:
+    // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics.
+    Int = usgn ? Intrinsic::aarch64_neon_umin : Intrinsic::aarch64_neon_smin;
+    if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fmin;
+    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmin");
+  case NEON::BI__builtin_neon_vabd_v:
+  case NEON::BI__builtin_neon_vabdq_v:
+    // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics.
+    Int = usgn ? Intrinsic::aarch64_neon_uabd : Intrinsic::aarch64_neon_sabd;
+    if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fabd;
+    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vabd");
+  case NEON::BI__builtin_neon_vpadal_v:
+  case NEON::BI__builtin_neon_vpadalq_v: {
+    unsigned ArgElts = VTy->getNumElements();
+    llvm::IntegerType *EltTy = cast<IntegerType>(VTy->getElementType());
+    unsigned BitWidth = EltTy->getBitWidth();
+    llvm::Type *ArgTy = llvm::VectorType::get(
+        llvm::IntegerType::get(getLLVMContext(), BitWidth/2), 2*ArgElts);
+    llvm::Type* Tys[2] = { VTy, ArgTy };
+    Int = usgn ? Intrinsic::aarch64_neon_uaddlp : Intrinsic::aarch64_neon_saddlp;
+    SmallVector<llvm::Value*, 1> TmpOps;
+    TmpOps.push_back(Ops[1]);
+    Function *F = CGM.getIntrinsic(Int, Tys);
+    llvm::Value *tmp = EmitNeonCall(F, TmpOps, "vpadal");
+    llvm::Value *addend = Builder.CreateBitCast(Ops[0], tmp->getType());
+    return Builder.CreateAdd(tmp, addend);
+  }
+  case NEON::BI__builtin_neon_vpmin_v:
+  case NEON::BI__builtin_neon_vpminq_v:
+    // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics.
+    Int = usgn ? Intrinsic::aarch64_neon_uminp : Intrinsic::aarch64_neon_sminp;
+    if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fminp;
+    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmin");
+  case NEON::BI__builtin_neon_vpmax_v:
+  case NEON::BI__builtin_neon_vpmaxq_v:
+    // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics.
+    Int = usgn ? Intrinsic::aarch64_neon_umaxp : Intrinsic::aarch64_neon_smaxp;
+    if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fmaxp;
+    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmax");
+  case NEON::BI__builtin_neon_vminnm_v:
+  case NEON::BI__builtin_neon_vminnmq_v:
+    Int = Intrinsic::aarch64_neon_fminnm;
+    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vminnm");
+  case NEON::BI__builtin_neon_vmaxnm_v:
+  case NEON::BI__builtin_neon_vmaxnmq_v:
+    Int = Intrinsic::aarch64_neon_fmaxnm;
+    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmaxnm");
+  case NEON::BI__builtin_neon_vrecpss_f32: {
+    llvm::Type *f32Type = llvm::Type::getFloatTy(getLLVMContext());
+    Ops.push_back(EmitScalarExpr(E->getArg(1)));
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_frecps, f32Type),
+                        Ops, "vrecps");
+  }
+  case NEON::BI__builtin_neon_vrecpsd_f64: {
+    llvm::Type *f64Type = llvm::Type::getDoubleTy(getLLVMContext());
+    Ops.push_back(EmitScalarExpr(E->getArg(1)));
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_frecps, f64Type),
+                        Ops, "vrecps");
+  }
+  case NEON::BI__builtin_neon_vrshr_n_v:
+  case NEON::BI__builtin_neon_vrshrq_n_v:
+    // FIXME: this can be shared with 32-bit ARM, but not AArch64 at the
+    // moment. After the final merge it should be added to
+    // EmitCommonNeonBuiltinExpr.
+    Int = usgn ? Intrinsic::aarch64_neon_urshl : Intrinsic::aarch64_neon_srshl;
+    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshr_n", 1, true);
+  case NEON::BI__builtin_neon_vqshlu_n_v:
+  case NEON::BI__builtin_neon_vqshluq_n_v:
+    // FIXME: AArch64 and ARM use different intrinsics for this, but are
+    // essentially compatible. It should be in EmitCommonNeonBuiltinExpr after
+    // the final merge.
+    Int = Intrinsic::aarch64_neon_sqshlu;
+    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshlu_n", 1, false);
+  case NEON::BI__builtin_neon_vqshrun_n_v:
+    // FIXME: as above
+    Int = Intrinsic::aarch64_neon_sqshrun;
+    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrun_n");
+  case NEON::BI__builtin_neon_vqrshrun_n_v:
+    // FIXME: and again.
+    Int = Intrinsic::aarch64_neon_sqrshrun;
+    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrun_n");
+  case NEON::BI__builtin_neon_vqshrn_n_v:
+    // FIXME: guess
+    Int = usgn ? Intrinsic::aarch64_neon_uqshrn : Intrinsic::aarch64_neon_sqshrn;
+    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrn_n");
+  case NEON::BI__builtin_neon_vrshrn_n_v:
+    // FIXME: there might be a pattern here.
+    Int = Intrinsic::aarch64_neon_rshrn;
+    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshrn_n");
+  case NEON::BI__builtin_neon_vqrshrn_n_v:
+    // FIXME: another one
+    Int = usgn ? Intrinsic::aarch64_neon_uqrshrn : Intrinsic::aarch64_neon_sqrshrn;
+    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrn_n");
+  case NEON::BI__builtin_neon_vrnda_v:
+  case NEON::BI__builtin_neon_vrndaq_v: {
+    Int = Intrinsic::round;
+    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrnda");
+  }
+  case NEON::BI__builtin_neon_vrndi_v:
+  case NEON::BI__builtin_neon_vrndiq_v: {
+    Int = Intrinsic::nearbyint;
+    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndi");
+  }
+  case NEON::BI__builtin_neon_vrndm_v:
+  case NEON::BI__builtin_neon_vrndmq_v: {
+    Int = Intrinsic::floor;
+    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndm");
+  }
+  case NEON::BI__builtin_neon_vrndn_v:
+  case NEON::BI__builtin_neon_vrndnq_v: {
+    Int = Intrinsic::aarch64_neon_frintn;
+    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndn");
+  }
+  case NEON::BI__builtin_neon_vrndp_v:
+  case NEON::BI__builtin_neon_vrndpq_v: {
+    Int = Intrinsic::ceil;
+    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndp");
+  }
+  case NEON::BI__builtin_neon_vrndx_v:
+  case NEON::BI__builtin_neon_vrndxq_v: {
+    Int = Intrinsic::rint;
+    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndx");
+  }
+  case NEON::BI__builtin_neon_vrnd_v:
+  case NEON::BI__builtin_neon_vrndq_v: {
+    Int = Intrinsic::trunc;
+    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndz");
+  }
+  case NEON::BI__builtin_neon_vceqz_v:
+  case NEON::BI__builtin_neon_vceqzq_v:
+    return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OEQ,
+                                         ICmpInst::ICMP_EQ, "vceqz");
+  case NEON::BI__builtin_neon_vcgez_v:
+  case NEON::BI__builtin_neon_vcgezq_v:
+    return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OGE,
+                                         ICmpInst::ICMP_SGE, "vcgez");
+  case NEON::BI__builtin_neon_vclez_v:
+  case NEON::BI__builtin_neon_vclezq_v:
+    return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OLE,
+                                         ICmpInst::ICMP_SLE, "vclez");
+  case NEON::BI__builtin_neon_vcgtz_v:
+  case NEON::BI__builtin_neon_vcgtzq_v:
+    return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OGT,
+                                         ICmpInst::ICMP_SGT, "vcgtz");
+  case NEON::BI__builtin_neon_vcltz_v:
+  case NEON::BI__builtin_neon_vcltzq_v:
+    return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OLT,
+                                         ICmpInst::ICMP_SLT, "vcltz");
+  case NEON::BI__builtin_neon_vcvt_f64_v:
+  case NEON::BI__builtin_neon_vcvtq_f64_v:
+    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
+    Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float64, false, quad));
+    return usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt")
+                : Builder.CreateSIToFP(Ops[0], Ty, "vcvt");
+  case NEON::BI__builtin_neon_vcvt_f64_f32: {
+    assert(Type.getEltType() == NeonTypeFlags::Float64 && quad &&
+           "unexpected vcvt_f64_f32 builtin");
+    NeonTypeFlags SrcFlag = NeonTypeFlags(NeonTypeFlags::Float32, false, false);
+    Ops[0] = Builder.CreateBitCast(Ops[0], GetNeonType(this, SrcFlag));
+
+    return Builder.CreateFPExt(Ops[0], Ty, "vcvt");
+  }
+  case NEON::BI__builtin_neon_vcvt_f32_f64: {
+    assert(Type.getEltType() == NeonTypeFlags::Float32 &&
+           "unexpected vcvt_f32_f64 builtin");
+    NeonTypeFlags SrcFlag = NeonTypeFlags(NeonTypeFlags::Float64, false, true);
+    Ops[0] = Builder.CreateBitCast(Ops[0], GetNeonType(this, SrcFlag));
+
+    return Builder.CreateFPTrunc(Ops[0], Ty, "vcvt");
+  }
+  case NEON::BI__builtin_neon_vcvt_s32_v:
+  case NEON::BI__builtin_neon_vcvt_u32_v:
+  case NEON::BI__builtin_neon_vcvt_s64_v:
+  case NEON::BI__builtin_neon_vcvt_u64_v:
+  case NEON::BI__builtin_neon_vcvtq_s32_v:
+  case NEON::BI__builtin_neon_vcvtq_u32_v:
+  case NEON::BI__builtin_neon_vcvtq_s64_v:
+  case NEON::BI__builtin_neon_vcvtq_u64_v: {
+    bool Double =
+      (cast<llvm::IntegerType>(VTy->getElementType())->getBitWidth() == 64);
+    llvm::Type *InTy =
+      GetNeonType(this,
+                  NeonTypeFlags(Double ? NeonTypeFlags::Float64
+                                : NeonTypeFlags::Float32, false, quad));
+    Ops[0] = Builder.CreateBitCast(Ops[0], InTy);
+    if (usgn)
+      return Builder.CreateFPToUI(Ops[0], Ty);
+    return Builder.CreateFPToSI(Ops[0], Ty);
+  }
+  case NEON::BI__builtin_neon_vcvta_s32_v:
+  case NEON::BI__builtin_neon_vcvtaq_s32_v:
+  case NEON::BI__builtin_neon_vcvta_u32_v:
+  case NEON::BI__builtin_neon_vcvtaq_u32_v:
+  case NEON::BI__builtin_neon_vcvta_s64_v:
+  case NEON::BI__builtin_neon_vcvtaq_s64_v:
+  case NEON::BI__builtin_neon_vcvta_u64_v:
+  case NEON::BI__builtin_neon_vcvtaq_u64_v: {
+    Int = usgn ? Intrinsic::aarch64_neon_fcvtau : Intrinsic::aarch64_neon_fcvtas;
+    bool Double =
+      (cast<llvm::IntegerType>(VTy->getElementType())->getBitWidth() == 64);
+    llvm::Type *InTy =
+      GetNeonType(this,
+                  NeonTypeFlags(Double ? NeonTypeFlags::Float64
+                                : NeonTypeFlags::Float32, false, quad));
+    llvm::Type *Tys[2] = { Ty, InTy };
+    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvta");
+  }
+  case NEON::BI__builtin_neon_vcvtm_s32_v:
+  case NEON::BI__builtin_neon_vcvtmq_s32_v:
+  case NEON::BI__builtin_neon_vcvtm_u32_v:
+  case NEON::BI__builtin_neon_vcvtmq_u32_v:
+  case NEON::BI__builtin_neon_vcvtm_s64_v:
+  case NEON::BI__builtin_neon_vcvtmq_s64_v:
+  case NEON::BI__builtin_neon_vcvtm_u64_v:
+  case NEON::BI__builtin_neon_vcvtmq_u64_v: {
+    Int = usgn ? Intrinsic::aarch64_neon_fcvtmu : Intrinsic::aarch64_neon_fcvtms;
+    bool Double =
+      (cast<llvm::IntegerType>(VTy->getElementType())->getBitWidth() == 64);
+    llvm::Type *InTy =
+      GetNeonType(this,
+                  NeonTypeFlags(Double ? NeonTypeFlags::Float64
+                                : NeonTypeFlags::Float32, false, quad));
+    llvm::Type *Tys[2] = { Ty, InTy };
+    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtm");
+  }
+  case NEON::BI__builtin_neon_vcvtn_s32_v:
+  case NEON::BI__builtin_neon_vcvtnq_s32_v:
+  case NEON::BI__builtin_neon_vcvtn_u32_v:
+  case NEON::BI__builtin_neon_vcvtnq_u32_v:
+  case NEON::BI__builtin_neon_vcvtn_s64_v:
+  case NEON::BI__builtin_neon_vcvtnq_s64_v:
+  case NEON::BI__builtin_neon_vcvtn_u64_v:
+  case NEON::BI__builtin_neon_vcvtnq_u64_v: {
+    Int = usgn ? Intrinsic::aarch64_neon_fcvtnu : Intrinsic::aarch64_neon_fcvtns;
+    bool Double =
+      (cast<llvm::IntegerType>(VTy->getElementType())->getBitWidth() == 64);
+    llvm::Type *InTy =
+      GetNeonType(this,
+                  NeonTypeFlags(Double ? NeonTypeFlags::Float64
+                                : NeonTypeFlags::Float32, false, quad));
+    llvm::Type *Tys[2] = { Ty, InTy };
+    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtn");
+  }
+  case NEON::BI__builtin_neon_vcvtp_s32_v:
+  case NEON::BI__builtin_neon_vcvtpq_s32_v:
+  case NEON::BI__builtin_neon_vcvtp_u32_v:
+  case NEON::BI__builtin_neon_vcvtpq_u32_v:
+  case NEON::BI__builtin_neon_vcvtp_s64_v:
+  case NEON::BI__builtin_neon_vcvtpq_s64_v:
+  case NEON::BI__builtin_neon_vcvtp_u64_v:
+  case NEON::BI__builtin_neon_vcvtpq_u64_v: {
+    Int = usgn ? Intrinsic::aarch64_neon_fcvtpu : Intrinsic::aarch64_neon_fcvtps;
+    bool Double =
+      (cast<llvm::IntegerType>(VTy->getElementType())->getBitWidth() == 64);
+    llvm::Type *InTy =
+      GetNeonType(this,
+                  NeonTypeFlags(Double ? NeonTypeFlags::Float64
+                                : NeonTypeFlags::Float32, false, quad));
+    llvm::Type *Tys[2] = { Ty, InTy };
+    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtp");
+  }
+  case NEON::BI__builtin_neon_vmulx_v:
+  case NEON::BI__builtin_neon_vmulxq_v: {
+    Int = Intrinsic::aarch64_neon_fmulx;
+    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmulx");
+  }
+  case NEON::BI__builtin_neon_vmul_lane_v:
+  case NEON::BI__builtin_neon_vmul_laneq_v: {
+    // v1f64 vmul_lane should be mapped to Neon scalar mul lane
+    bool Quad = false;
+    if (BuiltinID == NEON::BI__builtin_neon_vmul_laneq_v)
+      Quad = true;
+    Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy);
+    llvm::Type *VTy = GetNeonType(this,
+      NeonTypeFlags(NeonTypeFlags::Float64, false, Quad));
+    Ops[1] = Builder.CreateBitCast(Ops[1], VTy);
+    Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2], "extract");
+    Value *Result = Builder.CreateFMul(Ops[0], Ops[1]);
+    return Builder.CreateBitCast(Result, Ty);
+  }
+  case NEON::BI__builtin_neon_vnegd_s64:
+    return Builder.CreateNeg(EmitScalarExpr(E->getArg(0)), "vnegd");
+  case NEON::BI__builtin_neon_vpmaxnm_v:
+  case NEON::BI__builtin_neon_vpmaxnmq_v: {
+    Int = Intrinsic::aarch64_neon_fmaxnmp;
+    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmaxnm");
+  }
+  case NEON::BI__builtin_neon_vpminnm_v:
+  case NEON::BI__builtin_neon_vpminnmq_v: {
+    Int = Intrinsic::aarch64_neon_fminnmp;
+    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpminnm");
+  }
+  case NEON::BI__builtin_neon_vsqrt_v:
+  case NEON::BI__builtin_neon_vsqrtq_v: {
+    Int = Intrinsic::sqrt;
+    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
+    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsqrt");
+  }
+  case NEON::BI__builtin_neon_vrbit_v:
+  case NEON::BI__builtin_neon_vrbitq_v: {
+    Int = Intrinsic::aarch64_neon_rbit;
+    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrbit");
+  }
+  case NEON::BI__builtin_neon_vaddv_u8:
+    // FIXME: These are handled by the AArch64 scalar code.
+    usgn = true;
+    // FALLTHROUGH
+  case NEON::BI__builtin_neon_vaddv_s8: {
+    Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv;
+    Ty = llvm::IntegerType::get(getLLVMContext(), 32);
+    VTy =
+      llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 8), 8);
+    llvm::Type *Tys[2] = { Ty, VTy };
+    Ops.push_back(EmitScalarExpr(E->getArg(0)));
+    Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv");
+    return Builder.CreateTrunc(Ops[0],
+             llvm::IntegerType::get(getLLVMContext(), 8));
+  }
+  case NEON::BI__builtin_neon_vaddv_u16:
+    usgn = true;
+    // FALLTHROUGH
+  case NEON::BI__builtin_neon_vaddv_s16: {
+    Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv;
+    Ty = llvm::IntegerType::get(getLLVMContext(), 32);
+    VTy =
+      llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 16), 4);
+    llvm::Type *Tys[2] = { Ty, VTy };
+    Ops.push_back(EmitScalarExpr(E->getArg(0)));
+    Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv");
+    return Builder.CreateTrunc(Ops[0],
+             llvm::IntegerType::get(getLLVMContext(), 16));
+  }
+  case NEON::BI__builtin_neon_vaddvq_u8:
+    usgn = true;
+    // FALLTHROUGH
+  case NEON::BI__builtin_neon_vaddvq_s8: {
+    Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv;
+    Ty = llvm::IntegerType::get(getLLVMContext(), 32);
+    VTy =
+      llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 8), 16);
+    llvm::Type *Tys[2] = { Ty, VTy };
+    Ops.push_back(EmitScalarExpr(E->getArg(0)));
+    Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv");
+    return Builder.CreateTrunc(Ops[0],
+             llvm::IntegerType::get(getLLVMContext(), 8));
+  }
+  case NEON::BI__builtin_neon_vaddvq_u16:
+    usgn = true;
+    // FALLTHROUGH
+  case NEON::BI__builtin_neon_vaddvq_s16: {
+    Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv;
+    Ty = llvm::IntegerType::get(getLLVMContext(), 32);
+    VTy =
+      llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 16), 8);
+    llvm::Type *Tys[2] = { Ty, VTy };
+    Ops.push_back(EmitScalarExpr(E->getArg(0)));
+    Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv");
+    return Builder.CreateTrunc(Ops[0],
+             llvm::IntegerType::get(getLLVMContext(), 16));
+  }
+  case NEON::BI__builtin_neon_vmaxv_u8: {
+    Int = Intrinsic::aarch64_neon_umaxv;
+    Ty = llvm::IntegerType::get(getLLVMContext(), 32);
+    VTy =
+      llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 8), 8);
+    llvm::Type *Tys[2] = { Ty, VTy };
+    Ops.push_back(EmitScalarExpr(E->getArg(0)));
+    Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
+    return Builder.CreateTrunc(Ops[0],
+             llvm::IntegerType::get(getLLVMContext(), 8));
+  }
+  case NEON::BI__builtin_neon_vmaxv_u16: {
+    Int = Intrinsic::aarch64_neon_umaxv;
+    Ty = llvm::IntegerType::get(getLLVMContext(), 32);
+    VTy =
+      llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 16), 4);
+    llvm::Type *Tys[2] = { Ty, VTy };
+    Ops.push_back(EmitScalarExpr(E->getArg(0)));
+    Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
+    return Builder.CreateTrunc(Ops[0],
+             llvm::IntegerType::get(getLLVMContext(), 16));
+  }
+  case NEON::BI__builtin_neon_vmaxvq_u8: {
+    Int = Intrinsic::aarch64_neon_umaxv;
+    Ty = llvm::IntegerType::get(getLLVMContext(), 32);
+    VTy =
+      llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 8), 16);
+    llvm::Type *Tys[2] = { Ty, VTy };
+    Ops.push_back(EmitScalarExpr(E->getArg(0)));
+    Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
+    return Builder.CreateTrunc(Ops[0],
+             llvm::IntegerType::get(getLLVMContext(), 8));
+  }
+  case NEON::BI__builtin_neon_vmaxvq_u16: {
+    Int = Intrinsic::aarch64_neon_umaxv;
+    Ty = llvm::IntegerType::get(getLLVMContext(), 32);
+    VTy =
+      llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 16), 8);
+    llvm::Type *Tys[2] = { Ty, VTy };
+    Ops.push_back(EmitScalarExpr(E->getArg(0)));
+    Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
+    return Builder.CreateTrunc(Ops[0],
+             llvm::IntegerType::get(getLLVMContext(), 16));
+  }
+  case NEON::BI__builtin_neon_vmaxv_s8: {
+    Int = Intrinsic::aarch64_neon_smaxv;
+    Ty = llvm::IntegerType::get(getLLVMContext(), 32);
+    VTy =
+      llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 8), 8);
+    llvm::Type *Tys[2] = { Ty, VTy };
+    Ops.push_back(EmitScalarExpr(E->getArg(0)));
+    Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
+    return Builder.CreateTrunc(Ops[0],
+             llvm::IntegerType::get(getLLVMContext(), 8));
+  }
+  case NEON::BI__builtin_neon_vmaxv_s16: {
+    Int = Intrinsic::aarch64_neon_smaxv;
+    Ty = llvm::IntegerType::get(getLLVMContext(), 32);
+    VTy =
+      llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 16), 4);
+    llvm::Type *Tys[2] = { Ty, VTy };
+    Ops.push_back(EmitScalarExpr(E->getArg(0)));
+    Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
+    return Builder.CreateTrunc(Ops[0],
+             llvm::IntegerType::get(getLLVMContext(), 16));
+  }
+  case NEON::BI__builtin_neon_vmaxvq_s8: {
+    Int = Intrinsic::aarch64_neon_smaxv;
+    Ty = llvm::IntegerType::get(getLLVMContext(), 32);
+    VTy =
+      llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 8), 16);
+    llvm::Type *Tys[2] = { Ty, VTy };
+    Ops.push_back(EmitScalarExpr(E->getArg(0)));
+    Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
+    return Builder.CreateTrunc(Ops[0],
+             llvm::IntegerType::get(getLLVMContext(), 8));
+  }
+  case NEON::BI__builtin_neon_vmaxvq_s16: {
+    Int = Intrinsic::aarch64_neon_smaxv;
+    Ty = llvm::IntegerType::get(getLLVMContext(), 32);
+    VTy =
+      llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 16), 8);
+    llvm::Type *Tys[2] = { Ty, VTy };
+    Ops.push_back(EmitScalarExpr(E->getArg(0)));
+    Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
+    return Builder.CreateTrunc(Ops[0],
+             llvm::IntegerType::get(getLLVMContext(), 16));
+  }
+  case NEON::BI__builtin_neon_vminv_u8: {
+    Int = Intrinsic::aarch64_neon_uminv;
+    Ty = llvm::IntegerType::get(getLLVMContext(), 32);
+    VTy =
+      llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 8), 8);
+    llvm::Type *Tys[2] = { Ty, VTy };
+    Ops.push_back(EmitScalarExpr(E->getArg(0)));
+    Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
+    return Builder.CreateTrunc(Ops[0],
+             llvm::IntegerType::get(getLLVMContext(), 8));
+  }
+  case NEON::BI__builtin_neon_vminv_u16: {
+    Int = Intrinsic::aarch64_neon_uminv;
+    Ty = llvm::IntegerType::get(getLLVMContext(), 32);
+    VTy =
+      llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 16), 4);
+    llvm::Type *Tys[2] = { Ty, VTy };
+    Ops.push_back(EmitScalarExpr(E->getArg(0)));
+    Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
+    return Builder.CreateTrunc(Ops[0],
+             llvm::IntegerType::get(getLLVMContext(), 16));
+  }
+  case NEON::BI__builtin_neon_vminvq_u8: {
+    Int = Intrinsic::aarch64_neon_uminv;
+    Ty = llvm::IntegerType::get(getLLVMContext(), 32);
+    VTy =
+      llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 8), 16);
+    llvm::Type *Tys[2] = { Ty, VTy };
+    Ops.push_back(EmitScalarExpr(E->getArg(0)));
+    Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
+    return Builder.CreateTrunc(Ops[0],
+             llvm::IntegerType::get(getLLVMContext(), 8));
+  }
+  case NEON::BI__builtin_neon_vminvq_u16: {
+    Int = Intrinsic::aarch64_neon_uminv;
+    Ty = llvm::IntegerType::get(getLLVMContext(), 32);
+    VTy =
+      llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 16), 8);
+    llvm::Type *Tys[2] = { Ty, VTy };
+    Ops.push_back(EmitScalarExpr(E->getArg(0)));
+    Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
+    return Builder.CreateTrunc(Ops[0],
+             llvm::IntegerType::get(getLLVMContext(), 16));
+  }
+  case NEON::BI__builtin_neon_vminv_s8: {
+    Int = Intrinsic::aarch64_neon_sminv;
+    Ty = llvm::IntegerType::get(getLLVMContext(), 32);
+    VTy =
+      llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 8), 8);
+    llvm::Type *Tys[2] = { Ty, VTy };
+    Ops.push_back(EmitScalarExpr(E->getArg(0)));
+    Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
+    return Builder.CreateTrunc(Ops[0],
+             llvm::IntegerType::get(getLLVMContext(), 8));
+  }
+  case NEON::BI__builtin_neon_vminv_s16: {
+    Int = Intrinsic::aarch64_neon_sminv;
+    Ty = llvm::IntegerType::get(getLLVMContext(), 32);
+    VTy =
+      llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 16), 4);
+    llvm::Type *Tys[2] = { Ty, VTy };
+    Ops.push_back(EmitScalarExpr(E->getArg(0)));
+    Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
+    return Builder.CreateTrunc(Ops[0],
+             llvm::IntegerType::get(getLLVMContext(), 16));
+  }
+  case NEON::BI__builtin_neon_vminvq_s8: {
+    Int = Intrinsic::aarch64_neon_sminv;
+    Ty = llvm::IntegerType::get(getLLVMContext(), 32);
+    VTy =
+      llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 8), 16);
+    llvm::Type *Tys[2] = { Ty, VTy };
+    Ops.push_back(EmitScalarExpr(E->getArg(0)));
+    Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
+    return Builder.CreateTrunc(Ops[0],
+             llvm::IntegerType::get(getLLVMContext(), 8));
+  }
+  case NEON::BI__builtin_neon_vminvq_s16: {
+    Int = Intrinsic::aarch64_neon_sminv;
+    Ty = llvm::IntegerType::get(getLLVMContext(), 32);
+    VTy =
+      llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 16), 8);
+    llvm::Type *Tys[2] = { Ty, VTy };
+    Ops.push_back(EmitScalarExpr(E->getArg(0)));
+    Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
+    return Builder.CreateTrunc(Ops[0],
+             llvm::IntegerType::get(getLLVMContext(), 16));
+  }
+  case NEON::BI__builtin_neon_vmul_n_f64: {
+    Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy);
+    Value *RHS = Builder.CreateBitCast(EmitScalarExpr(E->getArg(1)), DoubleTy);
+    return Builder.CreateFMul(Ops[0], RHS);
+  }
+  case NEON::BI__builtin_neon_vaddlv_u8: {
+    Int = Intrinsic::aarch64_neon_uaddlv;
+    Ty = llvm::IntegerType::get(getLLVMContext(), 32);
+    VTy =
+      llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 8), 8);
+    llvm::Type *Tys[2] = { Ty, VTy };
+    Ops.push_back(EmitScalarExpr(E->getArg(0)));
+    Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
+    return Builder.CreateTrunc(Ops[0],
+             llvm::IntegerType::get(getLLVMContext(), 16));
+  }
+  case NEON::BI__builtin_neon_vaddlv_u16: {
+    Int = Intrinsic::aarch64_neon_uaddlv;
+    Ty = llvm::IntegerType::get(getLLVMContext(), 32);
+    VTy =
+      llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 16), 4);
+    llvm::Type *Tys[2] = { Ty, VTy };
+    Ops.push_back(EmitScalarExpr(E->getArg(0)));
+    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
+  }
+  case NEON::BI__builtin_neon_vaddlvq_u8: {
+    Int = Intrinsic::aarch64_neon_uaddlv;
+    Ty = llvm::IntegerType::get(getLLVMContext(), 32);
+    VTy =
+      llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 8), 16);
+    llvm::Type *Tys[2] = { Ty, VTy };
+    Ops.push_back(EmitScalarExpr(E->getArg(0)));
+    Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
+    return Builder.CreateTrunc(Ops[0],
+             llvm::IntegerType::get(getLLVMContext(), 16));
+  }
+  case NEON::BI__builtin_neon_vaddlvq_u16: {
+    Int = Intrinsic::aarch64_neon_uaddlv;
+    Ty = llvm::IntegerType::get(getLLVMContext(), 32);
+    VTy =
+      llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 16), 8);
+    llvm::Type *Tys[2] = { Ty, VTy };
+    Ops.push_back(EmitScalarExpr(E->getArg(0)));
+    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
+  }
+  case NEON::BI__builtin_neon_vaddlv_s8: {
+    Int = Intrinsic::aarch64_neon_saddlv;
+    Ty = llvm::IntegerType::get(getLLVMContext(), 32);
+    VTy =
+      llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 8), 8);
+    llvm::Type *Tys[2] = { Ty, VTy };
+    Ops.push_back(EmitScalarExpr(E->getArg(0)));
+    Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
+    return Builder.CreateTrunc(Ops[0],
+             llvm::IntegerType::get(getLLVMContext(), 16));
+  }
+  case NEON::BI__builtin_neon_vaddlv_s16: {
+    Int = Intrinsic::aarch64_neon_saddlv;
+    Ty = llvm::IntegerType::get(getLLVMContext(), 32);
+    VTy =
+      llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 16), 4);
+    llvm::Type *Tys[2] = { Ty, VTy };
+    Ops.push_back(EmitScalarExpr(E->getArg(0)));
+    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
+  }
+  case NEON::BI__builtin_neon_vaddlvq_s8: {
+    Int = Intrinsic::aarch64_neon_saddlv;
+    Ty = llvm::IntegerType::get(getLLVMContext(), 32);
+    VTy =
+      llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 8), 16);
+    llvm::Type *Tys[2] = { Ty, VTy };
+    Ops.push_back(EmitScalarExpr(E->getArg(0)));
+    Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
+    return Builder.CreateTrunc(Ops[0],
+             llvm::IntegerType::get(getLLVMContext(), 16));
+  }
+  case NEON::BI__builtin_neon_vaddlvq_s16: {
+    Int = Intrinsic::aarch64_neon_saddlv;
+    Ty = llvm::IntegerType::get(getLLVMContext(), 32);
+    VTy =
+      llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 16), 8);
+    llvm::Type *Tys[2] = { Ty, VTy };
+    Ops.push_back(EmitScalarExpr(E->getArg(0)));
+    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
+  }
+  case NEON::BI__builtin_neon_vsri_n_v:
+  case NEON::BI__builtin_neon_vsriq_n_v: {
+    Int = Intrinsic::aarch64_neon_vsri;
+    llvm::Function *Intrin = CGM.getIntrinsic(Int, Ty);
+    return EmitNeonCall(Intrin, Ops, "vsri_n");
+  }
+  case NEON::BI__builtin_neon_vsli_n_v:
+  case NEON::BI__builtin_neon_vsliq_n_v: {
+    Int = Intrinsic::aarch64_neon_vsli;
+    llvm::Function *Intrin = CGM.getIntrinsic(Int, Ty);
+    return EmitNeonCall(Intrin, Ops, "vsli_n");
+  }
+  case NEON::BI__builtin_neon_vsra_n_v:
+  case NEON::BI__builtin_neon_vsraq_n_v:
+    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
+    Ops[1] = EmitNeonRShiftImm(Ops[1], Ops[2], Ty, usgn, "vsra_n");
+    return Builder.CreateAdd(Ops[0], Ops[1]);
+  case NEON::BI__builtin_neon_vrsra_n_v:
+  case NEON::BI__builtin_neon_vrsraq_n_v: {
+    Int = usgn ? Intrinsic::aarch64_neon_urshl : Intrinsic::aarch64_neon_srshl;
+    SmallVector<llvm::Value*,2> TmpOps;
+    TmpOps.push_back(Ops[1]);
+    TmpOps.push_back(Ops[2]);
+    Function* F = CGM.getIntrinsic(Int, Ty);
+    llvm::Value *tmp = EmitNeonCall(F, TmpOps, "vrshr_n", 1, true);
+    Ops[0] = Builder.CreateBitCast(Ops[0], VTy);
+    return Builder.CreateAdd(Ops[0], tmp);
+  }
+    // FIXME: Sharing loads & stores with 32-bit is complicated by the absence
+    // of an Align parameter here.
+  case NEON::BI__builtin_neon_vld1_x2_v:
+  case NEON::BI__builtin_neon_vld1q_x2_v:
+  case NEON::BI__builtin_neon_vld1_x3_v:
+  case NEON::BI__builtin_neon_vld1q_x3_v:
+  case NEON::BI__builtin_neon_vld1_x4_v:
+  case NEON::BI__builtin_neon_vld1q_x4_v: {
+    llvm::Type *PTy = llvm::PointerType::getUnqual(VTy->getVectorElementType());
+    Ops[1] = Builder.CreateBitCast(Ops[1], PTy);
+    llvm::Type *Tys[2] = { VTy, PTy };
+    unsigned Int;
+    switch (BuiltinID) {
+    case NEON::BI__builtin_neon_vld1_x2_v:
+    case NEON::BI__builtin_neon_vld1q_x2_v:
+      Int = Intrinsic::aarch64_neon_ld1x2;
+      break;
+    case NEON::BI__builtin_neon_vld1_x3_v:
+    case NEON::BI__builtin_neon_vld1q_x3_v:
+      Int = Intrinsic::aarch64_neon_ld1x3;
+      break;
+    case NEON::BI__builtin_neon_vld1_x4_v:
+    case NEON::BI__builtin_neon_vld1q_x4_v:
+      Int = Intrinsic::aarch64_neon_ld1x4;
+      break;
+    }
+    Function *F = CGM.getIntrinsic(Int, Tys);
+    Ops[1] = Builder.CreateCall(F, Ops[1], "vld1xN");
+    Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
+    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
+    return Builder.CreateStore(Ops[1], Ops[0]);
+  }
+  case NEON::BI__builtin_neon_vst1_x2_v:
+  case NEON::BI__builtin_neon_vst1q_x2_v:
+  case NEON::BI__builtin_neon_vst1_x3_v:
+  case NEON::BI__builtin_neon_vst1q_x3_v:
+  case NEON::BI__builtin_neon_vst1_x4_v:
+  case NEON::BI__builtin_neon_vst1q_x4_v: {
+    llvm::Type *PTy = llvm::PointerType::getUnqual(VTy->getVectorElementType());
+    llvm::Type *Tys[2] = { VTy, PTy };
+    unsigned Int;
+    switch (BuiltinID) {
+    case NEON::BI__builtin_neon_vst1_x2_v:
+    case NEON::BI__builtin_neon_vst1q_x2_v:
+      Int = Intrinsic::aarch64_neon_st1x2;
+      break;
+    case NEON::BI__builtin_neon_vst1_x3_v:
+    case NEON::BI__builtin_neon_vst1q_x3_v:
+      Int = Intrinsic::aarch64_neon_st1x3;
+      break;
+    case NEON::BI__builtin_neon_vst1_x4_v:
+    case NEON::BI__builtin_neon_vst1q_x4_v:
+      Int = Intrinsic::aarch64_neon_st1x4;
+      break;
+    }
+    SmallVector<Value *, 4> IntOps(Ops.begin()+1, Ops.end());
+    IntOps.push_back(Ops[0]);
+    return EmitNeonCall(CGM.getIntrinsic(Int, Tys), IntOps, "");
+  }
+  case NEON::BI__builtin_neon_vld1_v:
+  case NEON::BI__builtin_neon_vld1q_v:
+    Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(VTy));
+    return Builder.CreateLoad(Ops[0]);
+  case NEON::BI__builtin_neon_vst1_v:
+  case NEON::BI__builtin_neon_vst1q_v:
+    Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(VTy));
+    Ops[1] = Builder.CreateBitCast(Ops[1], VTy);
+    return Builder.CreateStore(Ops[1], Ops[0]);
+  case NEON::BI__builtin_neon_vld1_lane_v:
+  case NEON::BI__builtin_neon_vld1q_lane_v:
+    Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
+    Ty = llvm::PointerType::getUnqual(VTy->getElementType());
+    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
+    Ops[0] = Builder.CreateLoad(Ops[0]);
+    return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vld1_lane");
+  case NEON::BI__builtin_neon_vld1_dup_v:
+  case NEON::BI__builtin_neon_vld1q_dup_v: {
+    Value *V = UndefValue::get(Ty);
+    Ty = llvm::PointerType::getUnqual(VTy->getElementType());
+    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
+    Ops[0] = Builder.CreateLoad(Ops[0]);
+    llvm::Constant *CI = ConstantInt::get(Int32Ty, 0);
+    Ops[0] = Builder.CreateInsertElement(V, Ops[0], CI);
+    return EmitNeonSplat(Ops[0], CI);
+  }
+  case NEON::BI__builtin_neon_vst1_lane_v:
+  case NEON::BI__builtin_neon_vst1q_lane_v:
+    Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
+    Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2]);
+    Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
+    return Builder.CreateStore(Ops[1], Builder.CreateBitCast(Ops[0], Ty));
+  case NEON::BI__builtin_neon_vld2_v:
+  case NEON::BI__builtin_neon_vld2q_v: {
+    llvm::Type *PTy = llvm::PointerType::getUnqual(VTy);
+    Ops[1] = Builder.CreateBitCast(Ops[1], PTy);
+    llvm::Type *Tys[2] = { VTy, PTy };
+    Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2, Tys);
+    Ops[1] = Builder.CreateCall(F, Ops[1], "vld2");
+    Ops[0] = Builder.CreateBitCast(Ops[0],
+                llvm::PointerType::getUnqual(Ops[1]->getType()));
+    return Builder.CreateStore(Ops[1], Ops[0]);
+  }
+  case NEON::BI__builtin_neon_vld3_v:
+  case NEON::BI__builtin_neon_vld3q_v: {
+    llvm::Type *PTy = llvm::PointerType::getUnqual(VTy);
+    Ops[1] = Builder.CreateBitCast(Ops[1], PTy);
+    llvm::Type *Tys[2] = { VTy, PTy };
+    Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3, Tys);
+    Ops[1] = Builder.CreateCall(F, Ops[1], "vld3");
+    Ops[0] = Builder.CreateBitCast(Ops[0],
+                llvm::PointerType::getUnqual(Ops[1]->getType()));
+    return Builder.CreateStore(Ops[1], Ops[0]);
+  }
+  case NEON::BI__builtin_neon_vld4_v:
+  case NEON::BI__builtin_neon_vld4q_v: {
+    llvm::Type *PTy = llvm::PointerType::getUnqual(VTy);
+    Ops[1] = Builder.CreateBitCast(Ops[1], PTy);
+    llvm::Type *Tys[2] = { VTy, PTy };
+    Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4, Tys);
+    Ops[1] = Builder.CreateCall(F, Ops[1], "vld4");
+    Ops[0] = Builder.CreateBitCast(Ops[0],
+                llvm::PointerType::getUnqual(Ops[1]->getType()));
+    return Builder.CreateStore(Ops[1], Ops[0]);
+  }
+  case NEON::BI__builtin_neon_vld2_dup_v:
+  case NEON::BI__builtin_neon_vld2q_dup_v: {
+    llvm::Type *PTy =
+      llvm::PointerType::getUnqual(VTy->getElementType());
+    Ops[1] = Builder.CreateBitCast(Ops[1], PTy);
+    llvm::Type *Tys[2] = { VTy, PTy };
+    Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2r, Tys);
+    Ops[1] = Builder.CreateCall(F, Ops[1], "vld2");
+    Ops[0] = Builder.CreateBitCast(Ops[0],
+                llvm::PointerType::getUnqual(Ops[1]->getType()));
+    return Builder.CreateStore(Ops[1], Ops[0]);
+  }
+  case NEON::BI__builtin_neon_vld3_dup_v:
+  case NEON::BI__builtin_neon_vld3q_dup_v: {
+    llvm::Type *PTy =
+      llvm::PointerType::getUnqual(VTy->getElementType());
+    Ops[1] = Builder.CreateBitCast(Ops[1], PTy);
+    llvm::Type *Tys[2] = { VTy, PTy };
+    Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3r, Tys);
+    Ops[1] = Builder.CreateCall(F, Ops[1], "vld3");
+    Ops[0] = Builder.CreateBitCast(Ops[0],
+                llvm::PointerType::getUnqual(Ops[1]->getType()));
+    return Builder.CreateStore(Ops[1], Ops[0]);
+  }
+  case NEON::BI__builtin_neon_vld4_dup_v:
+  case NEON::BI__builtin_neon_vld4q_dup_v: {
+    llvm::Type *PTy =
+      llvm::PointerType::getUnqual(VTy->getElementType());
+    Ops[1] = Builder.CreateBitCast(Ops[1], PTy);
+    llvm::Type *Tys[2] = { VTy, PTy };
+    Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4r, Tys);
+    Ops[1] = Builder.CreateCall(F, Ops[1], "vld4");
+    Ops[0] = Builder.CreateBitCast(Ops[0],
+                llvm::PointerType::getUnqual(Ops[1]->getType()));
+    return Builder.CreateStore(Ops[1], Ops[0]);
+  }
+  case NEON::BI__builtin_neon_vld2_lane_v:
+  case NEON::BI__builtin_neon_vld2q_lane_v: {
+    llvm::Type *Tys[2] = { VTy, Ops[1]->getType() };
+    Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2lane, Tys);
+    Ops.push_back(Ops[1]);
+    Ops.erase(Ops.begin()+1);
+    Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
+    Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
+    Ops[3] = Builder.CreateZExt(Ops[3],
+                llvm::IntegerType::get(getLLVMContext(), 64));
+    Ops[1] = Builder.CreateCall(F,
+                ArrayRef<Value*>(Ops).slice(1), "vld2_lane");
+    Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
+    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
+    return Builder.CreateStore(Ops[1], Ops[0]);
+  }
+  case NEON::BI__builtin_neon_vld3_lane_v:
+  case NEON::BI__builtin_neon_vld3q_lane_v: {
+    llvm::Type *Tys[2] = { VTy, Ops[1]->getType() };
+    Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3lane, Tys);
+    Ops.push_back(Ops[1]);
+    Ops.erase(Ops.begin()+1);
+    Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
+    Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
+    Ops[3] = Builder.CreateBitCast(Ops[3], Ty);
+    Ops[4] = Builder.CreateZExt(Ops[4],
+                llvm::IntegerType::get(getLLVMContext(), 64));
+    Ops[1] = Builder.CreateCall(F,
+                ArrayRef<Value*>(Ops).slice(1), "vld3_lane");
+    Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
+    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
+    return Builder.CreateStore(Ops[1], Ops[0]);
+  }
+  case NEON::BI__builtin_neon_vld4_lane_v:
+  case NEON::BI__builtin_neon_vld4q_lane_v: {
+    llvm::Type *Tys[2] = { VTy, Ops[1]->getType() };
+    Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4lane, Tys);
+    Ops.push_back(Ops[1]);
+    Ops.erase(Ops.begin()+1);
+    Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
+    Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
+    Ops[3] = Builder.CreateBitCast(Ops[3], Ty);
+    Ops[4] = Builder.CreateBitCast(Ops[4], Ty);
+    Ops[5] = Builder.CreateZExt(Ops[5],
+                llvm::IntegerType::get(getLLVMContext(), 64));
+    Ops[1] = Builder.CreateCall(F,
+                ArrayRef<Value*>(Ops).slice(1), "vld4_lane");
+    Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
+    Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
+    return Builder.CreateStore(Ops[1], Ops[0]);
+  }
+  case NEON::BI__builtin_neon_vst2_v:
+  case NEON::BI__builtin_neon_vst2q_v: {
+    Ops.push_back(Ops[0]);
+    Ops.erase(Ops.begin());
+    llvm::Type *Tys[2] = { VTy, Ops[2]->getType() };
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st2, Tys),
+                        Ops, "");
+  }
+  case NEON::BI__builtin_neon_vst2_lane_v:
+  case NEON::BI__builtin_neon_vst2q_lane_v: {
+    Ops.push_back(Ops[0]);
+    Ops.erase(Ops.begin());
+    Ops[2] = Builder.CreateZExt(Ops[2],
+                llvm::IntegerType::get(getLLVMContext(), 64));
+    llvm::Type *Tys[2] = { VTy, Ops[3]->getType() };
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st2lane, Tys),
+                        Ops, "");
+  }
+  case NEON::BI__builtin_neon_vst3_v:
+  case NEON::BI__builtin_neon_vst3q_v: {
+    Ops.push_back(Ops[0]);
+    Ops.erase(Ops.begin());
+    llvm::Type *Tys[2] = { VTy, Ops[3]->getType() };
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st3, Tys),
+                        Ops, "");
+  }
+  case NEON::BI__builtin_neon_vst3_lane_v:
+  case NEON::BI__builtin_neon_vst3q_lane_v: {
+    Ops.push_back(Ops[0]);
+    Ops.erase(Ops.begin());
+    Ops[3] = Builder.CreateZExt(Ops[3],
+                llvm::IntegerType::get(getLLVMContext(), 64));
+    llvm::Type *Tys[2] = { VTy, Ops[4]->getType() };
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st3lane, Tys),
+                        Ops, "");
+  }
+  case NEON::BI__builtin_neon_vst4_v:
+  case NEON::BI__builtin_neon_vst4q_v: {
+    Ops.push_back(Ops[0]);
+    Ops.erase(Ops.begin());
+    llvm::Type *Tys[2] = { VTy, Ops[4]->getType() };
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st4, Tys),
+                        Ops, "");
+  }
+  case NEON::BI__builtin_neon_vst4_lane_v:
+  case NEON::BI__builtin_neon_vst4q_lane_v: {
+    Ops.push_back(Ops[0]);
+    Ops.erase(Ops.begin());
+    Ops[4] = Builder.CreateZExt(Ops[4],
+                llvm::IntegerType::get(getLLVMContext(), 64));
+    llvm::Type *Tys[2] = { VTy, Ops[5]->getType() };
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st4lane, Tys),
+                        Ops, "");
+  }
+  case NEON::BI__builtin_neon_vtrn_v:
+  case NEON::BI__builtin_neon_vtrnq_v: {
     Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty));
     Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
     Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
-    Value *SV = 0;
+    Value *SV = nullptr;
 
     for (unsigned vi = 0; vi != 2; ++vi) {
       SmallVector<Constant*, 16> Indices;
       for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) {
-        Indices.push_back(Builder.getInt32(i+vi));
-        Indices.push_back(Builder.getInt32(i+e+vi));
+        Indices.push_back(ConstantInt::get(Int32Ty, i+vi));
+        Indices.push_back(ConstantInt::get(Int32Ty, i+e+vi));
       }
       Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ops[0], vi);
       SV = llvm::ConstantVector::get(Indices);
@@ -4708,12 +5573,12 @@
     }
     return SV;
   }
-  case ARM::BI__builtin_neon_vuzp_v:
-  case ARM::BI__builtin_neon_vuzpq_v: {
+  case NEON::BI__builtin_neon_vuzp_v:
+  case NEON::BI__builtin_neon_vuzpq_v: {
     Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty));
     Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
     Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
-    Value *SV = 0;
+    Value *SV = nullptr;
 
     for (unsigned vi = 0; vi != 2; ++vi) {
       SmallVector<Constant*, 16> Indices;
@@ -4727,12 +5592,12 @@
     }
     return SV;
   }
-  case ARM::BI__builtin_neon_vzip_v:
-  case ARM::BI__builtin_neon_vzipq_v: {
+  case NEON::BI__builtin_neon_vzip_v:
+  case NEON::BI__builtin_neon_vzipq_v: {
     Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty));
     Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
     Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
-    Value *SV = 0;
+    Value *SV = nullptr;
 
     for (unsigned vi = 0; vi != 2; ++vi) {
       SmallVector<Constant*, 16> Indices;
@@ -4747,6 +5612,48 @@
     }
     return SV;
   }
+  case NEON::BI__builtin_neon_vqtbl1q_v: {
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl1, Ty),
+                        Ops, "vtbl1");
+  }
+  case NEON::BI__builtin_neon_vqtbl2q_v: {
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl2, Ty),
+                        Ops, "vtbl2");
+  }
+  case NEON::BI__builtin_neon_vqtbl3q_v: {
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl3, Ty),
+                        Ops, "vtbl3");
+  }
+  case NEON::BI__builtin_neon_vqtbl4q_v: {
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl4, Ty),
+                        Ops, "vtbl4");
+  }
+  case NEON::BI__builtin_neon_vqtbx1q_v: {
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx1, Ty),
+                        Ops, "vtbx1");
+  }
+  case NEON::BI__builtin_neon_vqtbx2q_v: {
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx2, Ty),
+                        Ops, "vtbx2");
+  }
+  case NEON::BI__builtin_neon_vqtbx3q_v: {
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx3, Ty),
+                        Ops, "vtbx3");
+  }
+  case NEON::BI__builtin_neon_vqtbx4q_v: {
+    return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx4, Ty),
+                        Ops, "vtbx4");
+  }
+  case NEON::BI__builtin_neon_vsqadd_v:
+  case NEON::BI__builtin_neon_vsqaddq_v: {
+    Int = Intrinsic::aarch64_neon_usqadd;
+    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsqadd");
+  }
+  case NEON::BI__builtin_neon_vuqadd_v:
+  case NEON::BI__builtin_neon_vuqaddq_v: {
+    Int = Intrinsic::aarch64_neon_suqadd;
+    return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vuqadd");
+  }
   }
 }
 
@@ -4802,7 +5709,15 @@
   }
 
   switch (BuiltinID) {
-  default: return 0;
+  default: return nullptr;
+  case X86::BI_mm_prefetch: {
+    Value *Address = EmitScalarExpr(E->getArg(0));
+    Value *RW = ConstantInt::get(Int32Ty, 0);
+    Value *Locality = EmitScalarExpr(E->getArg(1));
+    Value *Data = ConstantInt::get(Int32Ty, 1);
+    Value *F = CGM.getIntrinsic(Intrinsic::prefetch);
+    return Builder.CreateCall4(F, Address, RW, Locality, Data);
+  }
   case X86::BI__builtin_ia32_vec_init_v8qi:
   case X86::BI__builtin_ia32_vec_init_v4hi:
   case X86::BI__builtin_ia32_vec_init_v2si:
@@ -4833,7 +5748,7 @@
 
     // extract (0, 1)
     unsigned Index = BuiltinID == X86::BI__builtin_ia32_storelps ? 0 : 1;
-    llvm::Value *Idx = llvm::ConstantInt::get(Int32Ty, Index);
+    llvm::Value *Idx = llvm::ConstantInt::get(SizeTy, Index);
     Ops[1] = Builder.CreateExtractElement(Ops[1], Idx, "extract");
 
     // cast pointer to i64 & store
@@ -4971,7 +5886,7 @@
   // 3DNow!
   case X86::BI__builtin_ia32_pswapdsf:
   case X86::BI__builtin_ia32_pswapdsi: {
-    const char *name = 0;
+    const char *name = nullptr;
     Intrinsic::ID ID = Intrinsic::not_intrinsic;
     switch(BuiltinID) {
     default: llvm_unreachable("Unsupported intrinsic!");
@@ -5040,7 +5955,7 @@
   Intrinsic::ID ID = Intrinsic::not_intrinsic;
 
   switch (BuiltinID) {
-  default: return 0;
+  default: return nullptr;
 
   // vec_ld, vec_lvsl, vec_lvsr
   case PPC::BI__builtin_altivec_lvx:
@@ -5118,3 +6033,83 @@
   }
   }
 }
+
+// Emit an intrinsic that has 1 float or double.
+static Value *emitUnaryFPBuiltin(CodeGenFunction &CGF,
+                                 const CallExpr *E,
+                                 unsigned IntrinsicID) {
+  llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0));
+
+  Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType());
+  return CGF.Builder.CreateCall(F, Src0);
+}
+
+// Emit an intrinsic that has 3 float or double operands.
+static Value *emitTernaryFPBuiltin(CodeGenFunction &CGF,
+                                   const CallExpr *E,
+                                   unsigned IntrinsicID) {
+  llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0));
+  llvm::Value *Src1 = CGF.EmitScalarExpr(E->getArg(1));
+  llvm::Value *Src2 = CGF.EmitScalarExpr(E->getArg(2));
+
+  Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType());
+  return CGF.Builder.CreateCall3(F, Src0, Src1, Src2);
+}
+
+Value *CodeGenFunction::EmitR600BuiltinExpr(unsigned BuiltinID,
+                                            const CallExpr *E) {
+  switch (BuiltinID) {
+  case R600::BI__builtin_amdgpu_div_scale:
+  case R600::BI__builtin_amdgpu_div_scalef: {
+    // Translate from the intrinsics's struct return to the builtin's out
+    // argument.
+
+    std::pair<llvm::Value *, unsigned> FlagOutPtr
+      = EmitPointerWithAlignment(E->getArg(3));
+
+    llvm::Value *X = EmitScalarExpr(E->getArg(0));
+    llvm::Value *Y = EmitScalarExpr(E->getArg(1));
+    llvm::Value *Z = EmitScalarExpr(E->getArg(2));
+
+    llvm::Value *Callee = CGM.getIntrinsic(Intrinsic::AMDGPU_div_scale,
+                                           X->getType());
+
+    llvm::Value *Tmp = Builder.CreateCall3(Callee, X, Y, Z);
+
+    llvm::Value *Result = Builder.CreateExtractValue(Tmp, 0);
+    llvm::Value *Flag = Builder.CreateExtractValue(Tmp, 1);
+
+    llvm::Type *RealFlagType
+      = FlagOutPtr.first->getType()->getPointerElementType();
+
+    llvm::Value *FlagExt = Builder.CreateZExt(Flag, RealFlagType);
+    llvm::StoreInst *FlagStore = Builder.CreateStore(FlagExt, FlagOutPtr.first);
+    FlagStore->setAlignment(FlagOutPtr.second);
+    return Result;
+  }
+  case R600::BI__builtin_amdgpu_div_fmas:
+  case R600::BI__builtin_amdgpu_div_fmasf:
+    return emitTernaryFPBuiltin(*this, E, Intrinsic::AMDGPU_div_fmas);
+  case R600::BI__builtin_amdgpu_div_fixup:
+  case R600::BI__builtin_amdgpu_div_fixupf:
+    return emitTernaryFPBuiltin(*this, E, Intrinsic::AMDGPU_div_fixup);
+  case R600::BI__builtin_amdgpu_trig_preop:
+  case R600::BI__builtin_amdgpu_trig_preopf: {
+    Value *Src0 = EmitScalarExpr(E->getArg(0));
+    Value *Src1 = EmitScalarExpr(E->getArg(1));
+    Value *F = CGM.getIntrinsic(Intrinsic::AMDGPU_trig_preop, Src0->getType());
+    return Builder.CreateCall2(F, Src0, Src1);
+  }
+  case R600::BI__builtin_amdgpu_rcp:
+  case R600::BI__builtin_amdgpu_rcpf:
+    return emitUnaryFPBuiltin(*this, E, Intrinsic::AMDGPU_rcp);
+  case R600::BI__builtin_amdgpu_rsq:
+  case R600::BI__builtin_amdgpu_rsqf:
+    return emitUnaryFPBuiltin(*this, E, Intrinsic::AMDGPU_rsq);
+  case R600::BI__builtin_amdgpu_rsq_clamped:
+  case R600::BI__builtin_amdgpu_rsq_clampedf:
+    return emitUnaryFPBuiltin(*this, E, Intrinsic::AMDGPU_rsq_clamped);
+   default:
+    return nullptr;
+  }
+}
diff --git a/lib/CodeGen/CGCUDANV.cpp b/lib/CodeGen/CGCUDANV.cpp
index 0ebf1aa..fb11751 100644
--- a/lib/CodeGen/CGCUDANV.cpp
+++ b/lib/CodeGen/CGCUDANV.cpp
@@ -17,9 +17,9 @@
 #include "CodeGenModule.h"
 #include "clang/AST/Decl.h"
 #include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/CallSite.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DerivedTypes.h"
-#include "llvm/Support/CallSite.h"
 #include <vector>
 
 using namespace clang;
@@ -39,7 +39,7 @@
 public:
   CGNVCUDARuntime(CodeGenModule &CGM);
 
-  void EmitDeviceStubBody(CodeGenFunction &CGF, FunctionArgList &Args);
+  void EmitDeviceStubBody(CodeGenFunction &CGF, FunctionArgList &Args) override;
 };
 
 }
diff --git a/lib/CodeGen/CGCUDARuntime.cpp b/lib/CodeGen/CGCUDARuntime.cpp
index eaf31bb..29e0a91 100644
--- a/lib/CodeGen/CGCUDARuntime.cpp
+++ b/lib/CodeGen/CGCUDARuntime.cpp
@@ -31,12 +31,13 @@
   llvm::BasicBlock *ContBlock = CGF.createBasicBlock("kcall.end");
 
   CodeGenFunction::ConditionalEvaluation eval(CGF);
-  CGF.EmitBranchOnBoolExpr(E->getConfig(), ContBlock, ConfigOKBlock);
+  CGF.EmitBranchOnBoolExpr(E->getConfig(), ContBlock, ConfigOKBlock,
+                           /*TrueCount=*/0);
 
   eval.begin(CGF);
   CGF.EmitBlock(ConfigOKBlock);
 
-  const Decl *TargetDecl = 0;
+  const Decl *TargetDecl = nullptr;
   if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E->getCallee())) {
     if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CE->getSubExpr())) {
       TargetDecl = DRE->getDecl();
@@ -51,5 +52,5 @@
   CGF.EmitBlock(ContBlock);
   eval.end(CGF);
 
-  return RValue::get(0);
+  return RValue::get(nullptr);
 }
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index 22baa65..545c5ef 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -35,7 +35,7 @@
     return true;
 
   // Producing an alias to a base class ctor/dtor can degrade debug quality
-  // as the debugger cannot tell them appart.
+  // as the debugger cannot tell them apart.
   if (getCodeGenOpts().OptimizationLevel == 0)
     return true;
 
@@ -44,6 +44,10 @@
   if (!D->hasTrivialBody())
     return true;
 
+  // For exported destructors, we need a full definition.
+  if (D->hasAttr<DLLExportAttr>())
+    return true;
+
   const CXXRecordDecl *Class = D->getParent();
 
   // If we need to manipulate a VTT parameter, give up.
@@ -56,22 +60,20 @@
 
   // If any field has a non-trivial destructor, we have to emit the
   // destructor separately.
-  for (CXXRecordDecl::field_iterator I = Class->field_begin(),
-         E = Class->field_end(); I != E; ++I)
+  for (const auto *I : Class->fields())
     if (I->getType().isDestructedType())
       return true;
 
   // Try to find a unique base class with a non-trivial destructor.
-  const CXXRecordDecl *UniqueBase = 0;
-  for (CXXRecordDecl::base_class_const_iterator I = Class->bases_begin(),
-         E = Class->bases_end(); I != E; ++I) {
+  const CXXRecordDecl *UniqueBase = nullptr;
+  for (const auto &I : Class->bases()) {
 
     // We're in the base destructor, so skip virtual bases.
-    if (I->isVirtual()) continue;
+    if (I.isVirtual()) continue;
 
     // Skip base classes with trivial destructors.
-    const CXXRecordDecl *Base
-      = cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+    const auto *Base =
+        cast<CXXRecordDecl>(I.getType()->getAs<RecordType>()->getDecl());
     if (Base->hasTrivialDestructor()) continue;
 
     // If we've already found a base class with a non-trivial
@@ -92,7 +94,13 @@
   if (!ClassLayout.getBaseClassOffset(UniqueBase).isZero())
     return true;
 
+  // Give up if the calling conventions don't match. We could update the call,
+  // but it is probably not worth it.
   const CXXDestructorDecl *BaseD = UniqueBase->getDestructor();
+  if (BaseD->getType()->getAs<FunctionType>()->getCallConv() !=
+      D->getType()->getAs<FunctionType>()->getCallConv())
+    return true;
+
   return TryEmitDefinitionAsAlias(GlobalDecl(D, Dtor_Base),
                                   GlobalDecl(BaseD, Dtor_Base),
                                   false);
@@ -107,7 +115,7 @@
   if (!getCodeGenOpts().CXXCtorDtorAliases)
     return true;
 
-  // The alias will use the linkage of the referrent.  If we can't
+  // The alias will use the linkage of the referent.  If we can't
   // support aliases with that linkage, fail.
   llvm::GlobalValue::LinkageTypes Linkage = getFunctionLinkage(AliasDecl);
 
@@ -130,17 +138,24 @@
   llvm::PointerType *AliasType
     = getTypes().GetFunctionType(AliasDecl)->getPointerTo();
 
-  // Find the referrent.  Some aliases might require a bitcast, in
+  // Find the referent.  Some aliases might require a bitcast, in
   // which case the caller is responsible for ensuring the soundness
   // of these semantics.
-  llvm::GlobalValue *Ref = cast<llvm::GlobalValue>(GetAddrOfGlobal(TargetDecl));
+  auto *Ref = cast<llvm::GlobalValue>(GetAddrOfGlobal(TargetDecl));
   llvm::Constant *Aliasee = Ref;
   if (Ref->getType() != AliasType)
     Aliasee = llvm::ConstantExpr::getBitCast(Ref, AliasType);
 
   // Instead of creating as alias to a linkonce_odr, replace all of the uses
-  // of the aliassee.
-  if (llvm::GlobalValue::isDiscardableIfUnused(Linkage)) {
+  // of the aliasee.
+  if (llvm::GlobalValue::isDiscardableIfUnused(Linkage) &&
+     (TargetLinkage != llvm::GlobalValue::AvailableExternallyLinkage ||
+      !TargetDecl.getDecl()->hasAttr<AlwaysInlineAttr>())) {
+    // FIXME: An extern template instantiation will create functions with
+    // linkage "AvailableExternally". In libc++, some classes also define
+    // members with attribute "AlwaysInline" and expect no reference to
+    // be generated. It is desirable to reenable this optimisation after
+    // corresponding LLVM changes.
     Replacements[MangledName] = Aliasee;
     return false;
   }
@@ -161,8 +176,8 @@
     return true;
 
   // Create the alias with no name.
-  llvm::GlobalAlias *Alias = 
-    new llvm::GlobalAlias(AliasType, Linkage, "", Aliasee, &getModule());
+  auto *Alias = llvm::GlobalAlias::create(AliasType->getElementType(), 0,
+                                          Linkage, "", Aliasee, &getModule());
 
   // Switch any previous uses to the alias.
   if (Entry) {
@@ -183,11 +198,13 @@
 
 void CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *ctor,
                                        CXXCtorType ctorType) {
-  // The complete constructor is equivalent to the base constructor
-  // for classes with no virtual bases.  Try to emit it as an alias.
-  if (getTarget().getCXXABI().hasConstructorVariants() &&
-      !ctor->getParent()->getNumVBases() &&
-      (ctorType == Ctor_Complete || ctorType == Ctor_Base)) {
+  if (!getTarget().getCXXABI().hasConstructorVariants()) {
+    // If there are no constructor variants, always emit the complete destructor.
+    ctorType = Ctor_Complete;
+  } else if (!ctor->getParent()->getNumVBases() &&
+             (ctorType == Ctor_Complete || ctorType == Ctor_Base)) {
+    // The complete constructor is equivalent to the base constructor
+    // for classes with no virtual bases.  Try to emit it as an alias.
     bool ProducedAlias =
         !TryEmitDefinitionAsAlias(GlobalDecl(ctor, Ctor_Complete),
                                   GlobalDecl(ctor, Ctor_Base), true);
@@ -198,20 +215,21 @@
   const CGFunctionInfo &fnInfo =
     getTypes().arrangeCXXConstructorDeclaration(ctor, ctorType);
 
-  llvm::Function *fn =
-    cast<llvm::Function>(GetAddrOfCXXConstructor(ctor, ctorType, &fnInfo));
+  auto *fn = cast<llvm::Function>(
+      GetAddrOfCXXConstructor(ctor, ctorType, &fnInfo, true));
   setFunctionLinkage(GlobalDecl(ctor, ctorType), fn);
 
   CodeGenFunction(*this).GenerateCode(GlobalDecl(ctor, ctorType), fn, fnInfo);
 
-  SetFunctionDefinitionAttributes(ctor, fn);
+  setFunctionDefinitionAttributes(ctor, fn);
   SetLLVMFunctionAttributesForDefinition(ctor, fn);
 }
 
 llvm::GlobalValue *
 CodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *ctor,
                                        CXXCtorType ctorType,
-                                       const CGFunctionInfo *fnInfo) {
+                                       const CGFunctionInfo *fnInfo,
+                                       bool DontDefer) {
   GlobalDecl GD(ctor, ctorType);
   
   StringRef name = getMangledName(GD);
@@ -223,7 +241,8 @@
 
   llvm::FunctionType *fnType = getTypes().GetFunctionType(*fnInfo);
   return cast<llvm::Function>(GetOrCreateLLVMFunction(name, fnType, GD,
-                                                      /*ForVTable=*/false));
+                                                      /*ForVTable=*/false,
+                                                      DontDefer));
 }
 
 void CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *dtor,
@@ -253,13 +272,13 @@
   const CGFunctionInfo &fnInfo =
     getTypes().arrangeCXXDestructor(dtor, dtorType);
 
-  llvm::Function *fn =
-    cast<llvm::Function>(GetAddrOfCXXDestructor(dtor, dtorType, &fnInfo));
+  auto *fn = cast<llvm::Function>(
+      GetAddrOfCXXDestructor(dtor, dtorType, &fnInfo, nullptr, true));
   setFunctionLinkage(GlobalDecl(dtor, dtorType), fn);
 
   CodeGenFunction(*this).GenerateCode(GlobalDecl(dtor, dtorType), fn, fnInfo);
 
-  SetFunctionDefinitionAttributes(dtor, fn);
+  setFunctionDefinitionAttributes(dtor, fn);
   SetLLVMFunctionAttributesForDefinition(dtor, fn);
 }
 
@@ -267,7 +286,8 @@
 CodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *dtor,
                                       CXXDtorType dtorType,
                                       const CGFunctionInfo *fnInfo,
-                                      llvm::FunctionType *fnType) {
+                                      llvm::FunctionType *fnType,
+                                      bool DontDefer) {
   GlobalDecl GD(dtor, dtorType);
 
   StringRef name = getMangledName(GD);
@@ -279,7 +299,8 @@
     fnType = getTypes().GetFunctionType(*fnInfo);
   }
   return cast<llvm::Function>(GetOrCreateLLVMFunction(name, fnType, GD,
-                                                      /*ForVTable=*/false));
+                                                      /*ForVTable=*/false,
+                                                      DontDefer));
 }
 
 static llvm::Value *BuildAppleKextVirtualCall(CodeGenFunction &CGF,
@@ -318,9 +339,9 @@
   QualType T = QualType(QTy, 0);
   const RecordType *RT = T->getAs<RecordType>();
   assert(RT && "BuildAppleKextVirtualCall - Qual type must be record");
-  const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
-  
-  if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD))
+  const auto *RD = cast<CXXRecordDecl>(RT->getDecl());
+
+  if (const auto *DD = dyn_cast<CXXDestructorDecl>(MD))
     return BuildAppleKextVirtualDestructorCall(DD, Dtor_Complete, RD);
 
   return ::BuildAppleKextVirtualCall(*this, MD, Ty, RD);
@@ -333,7 +354,7 @@
                                             const CXXDestructorDecl *DD,
                                             CXXDtorType Type,
                                             const CXXRecordDecl *RD) {
-  const CXXMethodDecl *MD = cast<CXXMethodDecl>(DD);
+  const auto *MD = cast<CXXMethodDecl>(DD);
   // FIXME. Dtor_Base dtor is always direct!!
   // It need be somehow inline expanded into the caller.
   // -O does that. But need to support -O0 as well.
@@ -344,5 +365,5 @@
     llvm::Type *Ty = CGM.getTypes().GetFunctionType(FInfo);
     return ::BuildAppleKextVirtualCall(*this, GlobalDecl(DD, Type), Ty, RD);
   }
-  return 0;
+  return nullptr;
 }
diff --git a/lib/CodeGen/CGCXXABI.cpp b/lib/CodeGen/CGCXXABI.cpp
index 412b278..55ddd66 100644
--- a/lib/CodeGen/CGCXXABI.cpp
+++ b/lib/CodeGen/CGCXXABI.cpp
@@ -28,6 +28,41 @@
     << S;
 }
 
+bool CGCXXABI::canCopyArgument(const CXXRecordDecl *RD) const {
+  // If RD has a non-trivial move or copy constructor, we cannot copy the
+  // argument.
+  if (RD->hasNonTrivialCopyConstructor() || RD->hasNonTrivialMoveConstructor())
+    return false;
+
+  // If RD has a non-trivial destructor, we cannot copy the argument.
+  if (RD->hasNonTrivialDestructor())
+    return false;
+
+  // We can only copy the argument if there exists at least one trivial,
+  // non-deleted copy or move constructor.
+  // FIXME: This assumes that all lazily declared copy and move constructors are
+  // not deleted.  This assumption might not be true in some corner cases.
+  bool CopyDeleted = false;
+  bool MoveDeleted = false;
+  for (const CXXConstructorDecl *CD : RD->ctors()) {
+    if (CD->isCopyConstructor() || CD->isMoveConstructor()) {
+      assert(CD->isTrivial());
+      // We had at least one undeleted trivial copy or move ctor.  Return
+      // directly.
+      if (!CD->isDeleted())
+        return true;
+      if (CD->isCopyConstructor())
+        CopyDeleted = true;
+      else
+        MoveDeleted = true;
+    }
+  }
+
+  // If all trivial copy and move constructors are deleted, we cannot copy the
+  // argument.
+  return !(CopyDeleted && MoveDeleted);
+}
+
 llvm::Constant *CGCXXABI::GetBogusMemberPointer(QualType T) {
   return llvm::Constant::getNullValue(CGM.getTypes().ConvertType(T));
 }
@@ -37,10 +72,9 @@
   return CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType());
 }
 
-llvm::Value *CGCXXABI::EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
-                                                       llvm::Value *&This,
-                                                       llvm::Value *MemPtr,
-                                                 const MemberPointerType *MPT) {
+llvm::Value *CGCXXABI::EmitLoadOfMemberFunctionPointer(
+    CodeGenFunction &CGF, const Expr *E, llvm::Value *&This,
+    llvm::Value *MemPtr, const MemberPointerType *MPT) {
   ErrorUnsupportedABI(CGF, "calls through member pointers");
 
   const FunctionProtoType *FPT = 
@@ -52,10 +86,10 @@
   return llvm::Constant::getNullValue(FTy->getPointerTo());
 }
 
-llvm::Value *CGCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF,
-                                                    llvm::Value *Base,
-                                                    llvm::Value *MemPtr,
-                                              const MemberPointerType *MPT) {
+llvm::Value *
+CGCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF, const Expr *E,
+                                       llvm::Value *Base, llvm::Value *MemPtr,
+                                       const MemberPointerType *MPT) {
   ErrorUnsupportedABI(CGF, "loads of member pointers");
   llvm::Type *Ty = CGF.ConvertType(MPT->getPointeeType())->getPointerTo();
   return llvm::Constant::getNullValue(Ty);
@@ -116,13 +150,13 @@
   return true;
 }
 
-void CGCXXABI::BuildThisParam(CodeGenFunction &CGF, FunctionArgList &params) {
+void CGCXXABI::buildThisParam(CodeGenFunction &CGF, FunctionArgList &params) {
   const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl());
 
   // FIXME: I'm not entirely sure I like using a fake decl just for code
   // generation. Maybe we can come up with a better way?
   ImplicitParamDecl *ThisDecl
-    = ImplicitParamDecl::Create(CGM.getContext(), 0, MD->getLocation(),
+    = ImplicitParamDecl::Create(CGM.getContext(), nullptr, MD->getLocation(),
                                 &CGM.getContext().Idents.get("this"),
                                 MD->getThisType(CGM.getContext()));
   params.push_back(ThisDecl);
@@ -160,7 +194,7 @@
                                              QualType ElementType) {
   // Should never be called.
   ErrorUnsupportedABI(CGF, "array cookie initialization");
-  return 0;
+  return nullptr;
 }
 
 bool CGCXXABI::requiresArrayCookie(const CXXDeleteExpr *expr,
@@ -194,7 +228,7 @@
   // If we don't need an array cookie, bail out early.
   if (!requiresArrayCookie(expr, eltTy)) {
     allocPtr = ptr;
-    numElements = 0;
+    numElements = nullptr;
     cookieSize = CharUnits::Zero();
     return;
   }
@@ -273,16 +307,17 @@
     llvm_unreachable("shouldn't be called in this ABI");
 
   ErrorUnsupportedABI(CGF, "complete object detection in ctor");
-  return 0;
+  return nullptr;
 }
 
 void CGCXXABI::EmitThreadLocalInitFuncs(
-    llvm::ArrayRef<std::pair<const VarDecl *, llvm::GlobalVariable *> > Decls,
+    ArrayRef<std::pair<const VarDecl *, llvm::GlobalVariable *> > Decls,
     llvm::Function *InitFunc) {
 }
 
-LValue CGCXXABI::EmitThreadLocalDeclRefExpr(CodeGenFunction &CGF,
-                                          const DeclRefExpr *DRE) {
+LValue CGCXXABI::EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
+                                              const VarDecl *VD,
+                                              QualType LValType) {
   ErrorUnsupportedABI(CGF, "odr-use of thread_local global");
   return LValue();
 }
diff --git a/lib/CodeGen/CGCXXABI.h b/lib/CodeGen/CGCXXABI.h
index 44bdf66..91e4970 100644
--- a/lib/CodeGen/CGCXXABI.h
+++ b/lib/CodeGen/CGCXXABI.h
@@ -19,29 +19,29 @@
 #include "clang/Basic/LLVM.h"
 
 namespace llvm {
-  class Constant;
-  class Type;
-  class Value;
+class Constant;
+class Type;
+class Value;
 }
 
 namespace clang {
-  class CastExpr;
-  class CXXConstructorDecl;
-  class CXXDestructorDecl;
-  class CXXMethodDecl;
-  class CXXRecordDecl;
-  class FieldDecl;
-  class MangleContext;
+class CastExpr;
+class CXXConstructorDecl;
+class CXXDestructorDecl;
+class CXXMethodDecl;
+class CXXRecordDecl;
+class FieldDecl;
+class MangleContext;
 
 namespace CodeGen {
-  class CodeGenFunction;
-  class CodeGenModule;
+class CodeGenFunction;
+class CodeGenModule;
 
 /// \brief Implements C++ ABI-specific code generation functions.
 class CGCXXABI {
 protected:
   CodeGenModule &CGM;
-  OwningPtr<MangleContext> MangleCtx;
+  std::unique_ptr<MangleContext> MangleCtx;
 
   CGCXXABI(CodeGenModule &CGM)
     : CGM(CGM), MangleCtx(CGM.getContext().createMangleContext()) {}
@@ -60,15 +60,6 @@
   /// Get a null value for unsupported member pointers.
   llvm::Constant *GetBogusMemberPointer(QualType T);
 
-  // FIXME: Every place that calls getVTT{Decl,Value} is something
-  // that needs to be abstracted properly.
-  ImplicitParamDecl *&getVTTDecl(CodeGenFunction &CGF) {
-    return CGF.CXXStructorImplicitParamDecl;
-  }
-  llvm::Value *&getVTTValue(CodeGenFunction &CGF) {
-    return CGF.CXXStructorImplicitParamValue;
-  }
-
   ImplicitParamDecl *&getStructorImplicitParamDecl(CodeGenFunction &CGF) {
     return CGF.CXXStructorImplicitParamDecl;
   }
@@ -76,11 +67,8 @@
     return CGF.CXXStructorImplicitParamValue;
   }
 
-  /// Build a parameter variable suitable for 'this'.
-  void BuildThisParam(CodeGenFunction &CGF, FunctionArgList &Params);
-
   /// Perform prolog initialization of the parameter variable suitable
-  /// for 'this' emitted by BuildThisParam.
+  /// for 'this' emitted by buildThisParam.
   void EmitThisParam(CodeGenFunction &CGF);
 
   ASTContext &getContext() const { return CGM.getContext(); }
@@ -105,8 +93,9 @@
   /// when called virtually, and code generation does not support the case.
   virtual bool HasThisReturn(GlobalDecl GD) const { return false; }
 
-  /// Returns true if the given record type should be returned indirectly.
-  virtual bool isReturnTypeIndirect(const CXXRecordDecl *RD) const = 0;
+  /// If the C++ ABI requires the given type be returned in a particular way,
+  /// this method sets RetAI and returns true.
+  virtual bool classifyReturnType(CGFunctionInfo &FI) const = 0;
 
   /// Specify how one should pass an argument of a record type.
   enum RecordArgABI {
@@ -123,9 +112,17 @@
     RAA_Indirect
   };
 
+  /// Returns true if C++ allows us to copy the memory of an object of type RD
+  /// when it is passed as an argument.
+  bool canCopyArgument(const CXXRecordDecl *RD) const;
+
   /// Returns how an argument of the given record type should be passed.
   virtual RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const = 0;
 
+  /// Returns true if the implicit 'sret' parameter comes after the implicit
+  /// 'this' parameter of C++ instance methods.
+  virtual bool isSRetParameterAfterThis() const { return false; }
+
   /// Find the LLVM type used to represent the given member pointer
   /// type.
   virtual llvm::Type *
@@ -134,17 +131,15 @@
   /// Load a member function from an object and a member function
   /// pointer.  Apply the this-adjustment and set 'This' to the
   /// adjusted value.
-  virtual llvm::Value *
-  EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
-                                  llvm::Value *&This,
-                                  llvm::Value *MemPtr,
-                                  const MemberPointerType *MPT);
+  virtual llvm::Value *EmitLoadOfMemberFunctionPointer(
+      CodeGenFunction &CGF, const Expr *E, llvm::Value *&This,
+      llvm::Value *MemPtr, const MemberPointerType *MPT);
 
   /// Calculate an l-value from an object and a data member pointer.
-  virtual llvm::Value *EmitMemberDataPointerAddress(CodeGenFunction &CGF,
-                                                    llvm::Value *Base,
-                                                    llvm::Value *MemPtr,
-                                            const MemberPointerType *MPT);
+  virtual llvm::Value *
+  EmitMemberDataPointerAddress(CodeGenFunction &CGF, const Expr *E,
+                               llvm::Value *Base, llvm::Value *MemPtr,
+                               const MemberPointerType *MPT);
 
   /// Perform a derived-to-base, base-to-derived, or bitcast member
   /// pointer conversion.
@@ -212,6 +207,30 @@
                                               llvm::Value *ptr,
                                               QualType type) = 0;
 
+  virtual llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty) = 0;
+
+  virtual bool shouldTypeidBeNullChecked(bool IsDeref,
+                                         QualType SrcRecordTy) = 0;
+  virtual void EmitBadTypeidCall(CodeGenFunction &CGF) = 0;
+  virtual llvm::Value *EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy,
+                                  llvm::Value *ThisPtr,
+                                  llvm::Type *StdTypeInfoPtrTy) = 0;
+
+  virtual bool shouldDynamicCastCallBeNullChecked(bool SrcIsPtr,
+                                                  QualType SrcRecordTy) = 0;
+
+  virtual llvm::Value *
+  EmitDynamicCastCall(CodeGenFunction &CGF, llvm::Value *Value,
+                      QualType SrcRecordTy, QualType DestTy,
+                      QualType DestRecordTy, llvm::BasicBlock *CastEnd) = 0;
+
+  virtual llvm::Value *EmitDynamicCastToVoid(CodeGenFunction &CGF,
+                                             llvm::Value *Value,
+                                             QualType SrcRecordTy,
+                                             QualType DestTy) = 0;
+
+  virtual bool EmitBadCastCall(CodeGenFunction &CGF) = 0;
+
   virtual llvm::Value *GetVirtualBaseClassOffset(CodeGenFunction &CGF,
                                                  llvm::Value *This,
                                                  const CXXRecordDecl *ClassDecl,
@@ -272,23 +291,27 @@
   }
 
   /// Perform ABI-specific "this" argument adjustment required prior to
-  /// a virtual function call.
-  virtual llvm::Value *adjustThisArgumentForVirtualCall(CodeGenFunction &CGF,
-                                                        GlobalDecl GD,
-                                                        llvm::Value *This) {
+  /// a call of a virtual function.
+  /// The "VirtualCall" argument is true iff the call itself is virtual.
+  virtual llvm::Value *
+  adjustThisArgumentForVirtualFunctionCall(CodeGenFunction &CGF, GlobalDecl GD,
+                                           llvm::Value *This,
+                                           bool VirtualCall) {
     return This;
   }
 
-  /// Build the ABI-specific portion of the parameter list for a
-  /// function.  This generally involves a 'this' parameter and
-  /// possibly some extra data for constructors and destructors.
+  /// Build a parameter variable suitable for 'this'.
+  void buildThisParam(CodeGenFunction &CGF, FunctionArgList &Params);
+
+  /// Insert any ABI-specific implicit parameters into the parameter list for a
+  /// function.  This generally involves extra data for constructors and
+  /// destructors.
   ///
   /// ABIs may also choose to override the return type, which has been
   /// initialized with the type of 'this' if HasThisReturn(CGF.CurGD) is true or
   /// the formal return type of the function otherwise.
-  virtual void BuildInstanceFunctionParams(CodeGenFunction &CGF,
-                                           QualType &ResTy,
-                                           FunctionArgList &Params) = 0;
+  virtual void addImplicitStructorParams(CodeGenFunction &CGF, QualType &ResTy,
+                                         FunctionArgList &Params) = 0;
 
   /// Perform ABI-specific "this" parameter adjustment in a virtual function
   /// prologue.
@@ -300,14 +323,20 @@
   /// Emit the ABI-specific prolog for the function.
   virtual void EmitInstanceFunctionProlog(CodeGenFunction &CGF) = 0;
 
-  /// Emit the constructor call. Return the function that is called.
-  virtual void EmitConstructorCall(CodeGenFunction &CGF,
-                                   const CXXConstructorDecl *D,
-                                   CXXCtorType Type,
-                                   bool ForVirtualBase, bool Delegating,
-                                   llvm::Value *This,
-                                   CallExpr::const_arg_iterator ArgBeg,
-                                   CallExpr::const_arg_iterator ArgEnd) = 0;
+  /// 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
+  addImplicitConstructorArgs(CodeGenFunction &CGF, const CXXConstructorDecl *D,
+                             CXXCtorType Type, bool ForVirtualBase,
+                             bool Delegating, CallArgList &Args) = 0;
+
+  /// Emit the destructor call.
+  virtual void EmitDestructorCall(CodeGenFunction &CGF,
+                                  const CXXDestructorDecl *DD, CXXDtorType Type,
+                                  bool ForVirtualBase, bool Delegating,
+                                  llvm::Value *This) = 0;
 
   /// Emits the VTable definitions required for the given record type.
   virtual void emitVTableDefinitions(CodeGenVTables &CGVT,
@@ -354,7 +383,8 @@
   /// base tables.
   virtual void emitVirtualInheritanceTables(const CXXRecordDecl *RD) = 0;
 
-  virtual void setThunkLinkage(llvm::Function *Thunk, bool ForVTable) = 0;
+  virtual void setThunkLinkage(llvm::Function *Thunk, bool ForVTable,
+                               GlobalDecl GD, bool ReturnAdjustment) = 0;
 
   virtual llvm::Value *performThisAdjustment(CodeGenFunction &CGF,
                                              llvm::Value *This,
@@ -475,14 +505,15 @@
   ///        initialization or non-trivial destruction for thread_local
   ///        variables, a function to perform the initialization. Otherwise, 0.
   virtual void EmitThreadLocalInitFuncs(
-      llvm::ArrayRef<std::pair<const VarDecl *, llvm::GlobalVariable *> > Decls,
+      ArrayRef<std::pair<const VarDecl *, llvm::GlobalVariable *> > Decls,
       llvm::Function *InitFunc);
 
   /// Emit a reference to a non-local thread_local variable (including
   /// triggering the initialization of all thread_local variables in its
   /// translation unit).
-  virtual LValue EmitThreadLocalDeclRefExpr(CodeGenFunction &CGF,
-                                            const DeclRefExpr *DRE);
+  virtual LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
+                                              const VarDecl *VD,
+                                              QualType LValType);
 };
 
 // Create an instance of a C++ ABI class:
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index 22f2467..17c3354 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -26,10 +26,10 @@
 #include "clang/Frontend/CodeGenOptions.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/IR/Attributes.h"
+#include "llvm/IR/CallSite.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/InlineAsm.h"
-#include "llvm/MC/SubtargetFeature.h"
-#include "llvm/Support/CallSite.h"
+#include "llvm/IR/Intrinsics.h"
 #include "llvm/Transforms/Utils/Local.h"
 using namespace clang;
 using namespace CodeGen;
@@ -79,23 +79,26 @@
 CodeGenTypes::arrangeFreeFunctionType(CanQual<FunctionNoProtoType> FTNP) {
   // When translating an unprototyped function type, always use a
   // variadic type.
-  return arrangeLLVMFunctionInfo(FTNP->getResultType().getUnqualifiedType(),
-                                 None, FTNP->getExtInfo(), RequiredArgs(0));
+  return arrangeLLVMFunctionInfo(FTNP->getReturnType().getUnqualifiedType(),
+                                 false, None, FTNP->getExtInfo(),
+                                 RequiredArgs(0));
 }
 
 /// Arrange the LLVM function layout for a value of the given function
 /// type, on top of any implicit parameters already stored.  Use the
 /// given ExtInfo instead of the ExtInfo from the function type.
 static const CGFunctionInfo &arrangeLLVMFunctionInfo(CodeGenTypes &CGT,
+                                                     bool IsInstanceMethod,
                                        SmallVectorImpl<CanQualType> &prefix,
                                              CanQual<FunctionProtoType> FTP,
                                               FunctionType::ExtInfo extInfo) {
   RequiredArgs required = RequiredArgs::forPrototypePlus(FTP, prefix.size());
   // FIXME: Kill copy.
-  for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
-    prefix.push_back(FTP->getArgType(i));
-  CanQualType resultType = FTP->getResultType().getUnqualifiedType();
-  return CGT.arrangeLLVMFunctionInfo(resultType, prefix, extInfo, required);
+  for (unsigned i = 0, e = FTP->getNumParams(); i != e; ++i)
+    prefix.push_back(FTP->getParamType(i));
+  CanQualType resultType = FTP->getReturnType().getUnqualifiedType();
+  return CGT.arrangeLLVMFunctionInfo(resultType, IsInstanceMethod, prefix,
+                                     extInfo, required);
 }
 
 /// Arrange the argument and result information for a free function (i.e.
@@ -103,7 +106,7 @@
 static const CGFunctionInfo &arrangeFreeFunctionType(CodeGenTypes &CGT,
                                       SmallVectorImpl<CanQualType> &prefix,
                                             CanQual<FunctionProtoType> FTP) {
-  return arrangeLLVMFunctionInfo(CGT, prefix, FTP, FTP->getExtInfo());
+  return arrangeLLVMFunctionInfo(CGT, false, prefix, FTP, FTP->getExtInfo());
 }
 
 /// Arrange the argument and result information for a free function (i.e.
@@ -112,7 +115,7 @@
                                       SmallVectorImpl<CanQualType> &prefix,
                                             CanQual<FunctionProtoType> FTP) {
   FunctionType::ExtInfo extInfo = FTP->getExtInfo();
-  return arrangeLLVMFunctionInfo(CGT, prefix, FTP, extInfo);
+  return arrangeLLVMFunctionInfo(CGT, true, prefix, FTP, extInfo);
 }
 
 /// Arrange the argument and result information for a value of the
@@ -123,7 +126,7 @@
   return ::arrangeFreeFunctionType(*this, argTypes, FTP);
 }
 
-static CallingConv getCallingConventionForDecl(const Decl *D) {
+static CallingConv getCallingConventionForDecl(const Decl *D, bool IsWindows) {
   // Set the appropriate calling convention for the Function.
   if (D->hasAttr<StdCallAttr>())
     return CC_X86StdCall;
@@ -146,9 +149,32 @@
   if (D->hasAttr<IntelOclBiccAttr>())
     return CC_IntelOclBicc;
 
+  if (D->hasAttr<MSABIAttr>())
+    return IsWindows ? CC_C : CC_X86_64Win64;
+
+  if (D->hasAttr<SysVABIAttr>())
+    return IsWindows ? CC_X86_64SysV : CC_C;
+
   return CC_C;
 }
 
+static bool isAAPCSVFP(const CGFunctionInfo &FI, const TargetInfo &Target) {
+  switch (FI.getEffectiveCallingConvention()) {
+  case llvm::CallingConv::C:
+    switch (Target.getTriple().getEnvironment()) {
+    case llvm::Triple::EABIHF:
+    case llvm::Triple::GNUEABIHF:
+      return true;
+    default:
+      return false;
+    }
+  case llvm::CallingConv::ARM_AAPCS_VFP:
+    return true;
+  default:
+    return false;
+  }
+}
+
 /// Arrange the argument and result information for a call to an
 /// unknown C++ non-static member function of the given abstract type.
 /// (Zero value of RD means we don't have any meaningful "this" argument type,
@@ -202,18 +228,41 @@
   CanQualType resultType =
     TheCXXABI.HasThisReturn(GD) ? argTypes.front() : Context.VoidTy;
 
-  TheCXXABI.BuildConstructorSignature(D, ctorKind, resultType, argTypes);
-
   CanQual<FunctionProtoType> FTP = GetFormalType(D);
 
-  RequiredArgs required = RequiredArgs::forPrototypePlus(FTP, argTypes.size());
-
   // Add the formal parameters.
-  for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
-    argTypes.push_back(FTP->getArgType(i));
+  for (unsigned i = 0, e = FTP->getNumParams(); i != e; ++i)
+    argTypes.push_back(FTP->getParamType(i));
+
+  TheCXXABI.BuildConstructorSignature(D, ctorKind, resultType, argTypes);
+
+  RequiredArgs required =
+      (D->isVariadic() ? RequiredArgs(argTypes.size()) : RequiredArgs::All);
 
   FunctionType::ExtInfo extInfo = FTP->getExtInfo();
-  return arrangeLLVMFunctionInfo(resultType, argTypes, extInfo, required);
+  return arrangeLLVMFunctionInfo(resultType, true, argTypes, extInfo, required);
+}
+
+/// Arrange a call to a C++ method, passing the given arguments.
+const CGFunctionInfo &
+CodeGenTypes::arrangeCXXConstructorCall(const CallArgList &args,
+                                        const CXXConstructorDecl *D,
+                                        CXXCtorType CtorKind,
+                                        unsigned ExtraArgs) {
+  // FIXME: Kill copy.
+  SmallVector<CanQualType, 16> ArgTypes;
+  for (CallArgList::const_iterator i = args.begin(), e = args.end(); i != e;
+       ++i)
+    ArgTypes.push_back(Context.getCanonicalParamType(i->Ty));
+
+  CanQual<FunctionProtoType> FPT = GetFormalType(D);
+  RequiredArgs Required = RequiredArgs::forPrototypePlus(FPT, 1 + ExtraArgs);
+  GlobalDecl GD(D, CtorKind);
+  CanQualType ResultType =
+      TheCXXABI.HasThisReturn(GD) ? ArgTypes.front() : Context.VoidTy;
+
+  FunctionType::ExtInfo Info = FPT->getExtInfo();
+  return arrangeLLVMFunctionInfo(ResultType, true, ArgTypes, Info, Required);
 }
 
 /// Arrange the argument and result information for a declaration,
@@ -232,11 +281,11 @@
   TheCXXABI.BuildDestructorSignature(D, dtorKind, resultType, argTypes);
 
   CanQual<FunctionProtoType> FTP = GetFormalType(D);
-  assert(FTP->getNumArgs() == 0 && "dtor with formal parameters");
+  assert(FTP->getNumParams() == 0 && "dtor with formal parameters");
   assert(FTP->isVariadic() == 0 && "dtor with formal parameters");
 
   FunctionType::ExtInfo extInfo = FTP->getExtInfo();
-  return arrangeLLVMFunctionInfo(resultType, argTypes, extInfo,
+  return arrangeLLVMFunctionInfo(resultType, true, argTypes, extInfo,
                                  RequiredArgs::All);
 }
 
@@ -256,7 +305,7 @@
   // non-variadic type.
   if (isa<FunctionNoProtoType>(FTy)) {
     CanQual<FunctionNoProtoType> noProto = FTy.getAs<FunctionNoProtoType>();
-    return arrangeLLVMFunctionInfo(noProto->getResultType(), None,
+    return arrangeLLVMFunctionInfo(noProto->getReturnType(), false, None,
                                    noProto->getExtInfo(), RequiredArgs::All);
   }
 
@@ -286,13 +335,13 @@
   argTys.push_back(Context.getCanonicalParamType(receiverType));
   argTys.push_back(Context.getCanonicalParamType(Context.getObjCSelType()));
   // FIXME: Kill copy?
-  for (ObjCMethodDecl::param_const_iterator i = MD->param_begin(),
-         e = MD->param_end(); i != e; ++i) {
-    argTys.push_back(Context.getCanonicalParamType((*i)->getType()));
+  for (const auto *I : MD->params()) {
+    argTys.push_back(Context.getCanonicalParamType(I->getType()));
   }
 
   FunctionType::ExtInfo einfo;
-  einfo = einfo.withCallingConv(getCallingConventionForDecl(MD));
+  bool IsWindows = getContext().getTargetInfo().getTriple().isOSWindows();
+  einfo = einfo.withCallingConv(getCallingConventionForDecl(MD, IsWindows));
 
   if (getContext().getLangOpts().ObjCAutoRefCount &&
       MD->hasAttr<NSReturnsRetainedAttr>())
@@ -301,8 +350,8 @@
   RequiredArgs required =
     (MD->isVariadic() ? RequiredArgs(argTys.size()) : RequiredArgs::All);
 
-  return arrangeLLVMFunctionInfo(GetReturnType(MD->getResultType()), argTys,
-                                 einfo, required);
+  return arrangeLLVMFunctionInfo(GetReturnType(MD->getReturnType()), false,
+                                 argTys, einfo, required);
 }
 
 const CGFunctionInfo &
@@ -336,7 +385,7 @@
   // extra prefix plus the arguments in the prototype.
   if (const FunctionProtoType *proto = dyn_cast<FunctionProtoType>(fnType)) {
     if (proto->isVariadic())
-      required = RequiredArgs(proto->getNumArgs() + numExtraRequiredArgs);
+      required = RequiredArgs(proto->getNumParams() + numExtraRequiredArgs);
 
   // If we don't have a prototype at all, but we're supposed to
   // explicitly use the variadic convention for unprototyped calls,
@@ -348,7 +397,7 @@
     required = RequiredArgs(args.size());
   }
 
-  return CGT.arrangeFreeFunctionCall(fnType->getResultType(), args,
+  return CGT.arrangeFreeFunctionCall(fnType->getReturnType(), args,
                                      fnType->getExtInfo(), required);
 }
 
@@ -380,8 +429,8 @@
   for (CallArgList::const_iterator i = args.begin(), e = args.end();
        i != e; ++i)
     argTypes.push_back(Context.getCanonicalParamType(i->Ty));
-  return arrangeLLVMFunctionInfo(GetReturnType(resultType), argTypes, info,
-                                 required);
+  return arrangeLLVMFunctionInfo(GetReturnType(resultType), false, argTypes,
+                                 info, required);
 }
 
 /// Arrange a call to a C++ method, passing the given arguments.
@@ -396,15 +445,13 @@
     argTypes.push_back(Context.getCanonicalParamType(i->Ty));
 
   FunctionType::ExtInfo info = FPT->getExtInfo();
-  return arrangeLLVMFunctionInfo(GetReturnType(FPT->getResultType()),
+  return arrangeLLVMFunctionInfo(GetReturnType(FPT->getReturnType()), true,
                                  argTypes, info, required);
 }
 
-const CGFunctionInfo &
-CodeGenTypes::arrangeFunctionDeclaration(QualType resultType,
-                                         const FunctionArgList &args,
-                                         const FunctionType::ExtInfo &info,
-                                         bool isVariadic) {
+const CGFunctionInfo &CodeGenTypes::arrangeFreeFunctionDeclaration(
+    QualType resultType, const FunctionArgList &args,
+    const FunctionType::ExtInfo &info, bool isVariadic) {
   // FIXME: Kill copy.
   SmallVector<CanQualType, 16> argTypes;
   for (FunctionArgList::const_iterator i = args.begin(), e = args.end();
@@ -413,12 +460,12 @@
 
   RequiredArgs required =
     (isVariadic ? RequiredArgs(args.size()) : RequiredArgs::All);
-  return arrangeLLVMFunctionInfo(GetReturnType(resultType), argTypes, info,
+  return arrangeLLVMFunctionInfo(GetReturnType(resultType), false, argTypes, info,
                                  required);
 }
 
 const CGFunctionInfo &CodeGenTypes::arrangeNullaryFunction() {
-  return arrangeLLVMFunctionInfo(getContext().VoidTy, None,
+  return arrangeLLVMFunctionInfo(getContext().VoidTy, false, None,
                                  FunctionType::ExtInfo(), RequiredArgs::All);
 }
 
@@ -427,6 +474,7 @@
 /// above functions ultimately defer to.
 const CGFunctionInfo &
 CodeGenTypes::arrangeLLVMFunctionInfo(CanQualType resultType,
+                                      bool IsInstanceMethod,
                                       ArrayRef<CanQualType> argTypes,
                                       FunctionType::ExtInfo info,
                                       RequiredArgs required) {
@@ -440,15 +488,17 @@
 
   // Lookup or create unique function info.
   llvm::FoldingSetNodeID ID;
-  CGFunctionInfo::Profile(ID, info, required, resultType, argTypes);
+  CGFunctionInfo::Profile(ID, IsInstanceMethod, info, required, resultType,
+                          argTypes);
 
-  void *insertPos = 0;
+  void *insertPos = nullptr;
   CGFunctionInfo *FI = FunctionInfos.FindNodeOrInsertPos(ID, insertPos);
   if (FI)
     return *FI;
 
   // Construct the function info.  We co-allocate the ArgInfos.
-  FI = CGFunctionInfo::create(CC, info, resultType, argTypes, required);
+  FI = CGFunctionInfo::create(CC, IsInstanceMethod, info, resultType, argTypes,
+                              required);
   FunctionInfos.InsertNode(FI, insertPos);
 
   bool inserted = FunctionsBeingProcessed.insert(FI); (void)inserted;
@@ -461,13 +511,12 @@
   // them are direct or extend without a specified coerce type, specify the
   // default now.
   ABIArgInfo &retInfo = FI->getReturnInfo();
-  if (retInfo.canHaveCoerceToType() && retInfo.getCoerceToType() == 0)
+  if (retInfo.canHaveCoerceToType() && retInfo.getCoerceToType() == nullptr)
     retInfo.setCoerceToType(ConvertType(FI->getReturnType()));
 
-  for (CGFunctionInfo::arg_iterator I = FI->arg_begin(), E = FI->arg_end();
-       I != E; ++I)
-    if (I->info.canHaveCoerceToType() && I->info.getCoerceToType() == 0)
-      I->info.setCoerceToType(ConvertType(I->type));
+  for (auto &I : FI->arguments())
+    if (I.info.canHaveCoerceToType() && I.info.getCoerceToType() == nullptr)
+      I.info.setCoerceToType(ConvertType(I.type));
 
   bool erased = FunctionsBeingProcessed.erase(FI); (void)erased;
   assert(erased && "Not in set?");
@@ -476,6 +525,7 @@
 }
 
 CGFunctionInfo *CGFunctionInfo::create(unsigned llvmCC,
+                                       bool IsInstanceMethod,
                                        const FunctionType::ExtInfo &info,
                                        CanQualType resultType,
                                        ArrayRef<CanQualType> argTypes,
@@ -486,11 +536,13 @@
   FI->CallingConvention = llvmCC;
   FI->EffectiveCallingConvention = llvmCC;
   FI->ASTCallingConvention = info.getCC();
+  FI->InstanceMethod = IsInstanceMethod;
   FI->NoReturn = info.getNoReturn();
   FI->ReturnsRetained = info.getProducesResult();
   FI->Required = required;
   FI->HasRegParm = info.getHasRegParm();
   FI->RegParm = info.getRegParm();
+  FI->ArgStruct = nullptr;
   FI->NumArgs = argTypes.size();
   FI->getArgsBuffer()[0].type = resultType;
   for (unsigned i = 0, e = argTypes.size(); i != e; ++i)
@@ -513,12 +565,10 @@
     if (RD->isUnion()) {
       // Unions can be here only in degenerative cases - all the fields are same
       // after flattening. Thus we have to use the "largest" field.
-      const FieldDecl *LargestFD = 0;
+      const FieldDecl *LargestFD = nullptr;
       CharUnits UnionSize = CharUnits::Zero();
 
-      for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
-           i != e; ++i) {
-        const FieldDecl *FD = *i;
+      for (const auto *FD : RD->fields()) {
         assert(!FD->isBitField() &&
                "Cannot expand structure with bit-field members.");
         CharUnits FieldSize = getContext().getTypeSizeInChars(FD->getType());
@@ -530,11 +580,10 @@
       if (LargestFD)
         GetExpandedTypes(LargestFD->getType(), expandedTypes);
     } else {
-      for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
-           i != e; ++i) {
-        assert(!i->isBitField() &&
+      for (const auto *I : RD->fields()) {
+        assert(!I->isBitField() &&
                "Cannot expand structure with bit-field members.");
-        GetExpandedTypes(i->getType(), expandedTypes);
+        GetExpandedTypes(I->getType(), expandedTypes);
       }
     }
   } else if (const ComplexType *CT = type->getAs<ComplexType>()) {
@@ -564,12 +613,10 @@
     if (RD->isUnion()) {
       // Unions can be here only in degenerative cases - all the fields are same
       // after flattening. Thus we have to use the "largest" field.
-      const FieldDecl *LargestFD = 0;
+      const FieldDecl *LargestFD = nullptr;
       CharUnits UnionSize = CharUnits::Zero();
 
-      for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
-           i != e; ++i) {
-        const FieldDecl *FD = *i;
+      for (const auto *FD : RD->fields()) {
         assert(!FD->isBitField() &&
                "Cannot expand structure with bit-field members.");
         CharUnits FieldSize = getContext().getTypeSizeInChars(FD->getType());
@@ -584,9 +631,7 @@
         AI = ExpandTypeFromArgs(LargestFD->getType(), SubLV, AI);
       }
     } else {
-      for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
-           i != e; ++i) {
-        FieldDecl *FD = *i;
+      for (const auto *FD : RD->fields()) {
         QualType FT = FD->getType();
 
         // FIXME: What are the right qualifiers here?
@@ -672,8 +717,9 @@
     if (DL.isBigEndian()) {
       // Preserve the high bits on big-endian targets.
       // That is what memory coercion does.
-      uint64_t SrcSize = DL.getTypeAllocSizeInBits(Val->getType());
-      uint64_t DstSize = DL.getTypeAllocSizeInBits(DestIntTy);
+      uint64_t SrcSize = DL.getTypeSizeInBits(Val->getType());
+      uint64_t DstSize = DL.getTypeSizeInBits(DestIntTy);
+
       if (SrcSize > DstSize) {
         Val = CGF.Builder.CreateLShr(Val, SrcSize - DstSize, "coerce.highbits");
         Val = CGF.Builder.CreateTrunc(Val, DestIntTy, "coerce.val.ii");
@@ -850,6 +896,11 @@
   return FI.getReturnInfo().isIndirect();
 }
 
+bool CodeGenModule::ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI) {
+  return ReturnTypeUsesSRet(FI) &&
+         getTargetCodeGenInfo().doesReturnSlotInterfereWithArgs();
+}
+
 bool CodeGenModule::ReturnTypeUsesFPRet(QualType ResultType) {
   if (const BuiltinType *BT = ResultType->getAs<BuiltinType>()) {
     switch (BT->getKind()) {
@@ -889,8 +940,9 @@
   bool Inserted = FunctionsBeingProcessed.insert(&FI); (void)Inserted;
   assert(Inserted && "Recursively being processed?");
   
+  bool SwapThisWithSRet = false;
   SmallVector<llvm::Type*, 8> argTypes;
-  llvm::Type *resultType = 0;
+  llvm::Type *resultType = nullptr;
 
   const ABIArgInfo &retAI = FI.getReturnInfo();
   switch (retAI.getKind()) {
@@ -902,6 +954,18 @@
     resultType = retAI.getCoerceToType();
     break;
 
+  case ABIArgInfo::InAlloca:
+    if (retAI.getInAllocaSRet()) {
+      // sret things on win32 aren't void, they return the sret pointer.
+      QualType ret = FI.getReturnType();
+      llvm::Type *ty = ConvertType(ret);
+      unsigned addressSpace = Context.getTargetAddressSpace(ret);
+      resultType = llvm::PointerType::get(ty, addressSpace);
+    } else {
+      resultType = llvm::Type::getVoidTy(getLLVMContext());
+    }
+    break;
+
   case ABIArgInfo::Indirect: {
     assert(!retAI.getIndirectAlign() && "Align unused on indirect return.");
     resultType = llvm::Type::getVoidTy(getLLVMContext());
@@ -910,6 +974,8 @@
     llvm::Type *ty = ConvertType(ret);
     unsigned addressSpace = Context.getTargetAddressSpace(ret);
     argTypes.push_back(llvm::PointerType::get(ty, addressSpace));
+
+    SwapThisWithSRet = retAI.isSRetAfterThis();
     break;
   }
 
@@ -934,6 +1000,7 @@
 
     switch (argAI.getKind()) {
     case ABIArgInfo::Ignore:
+    case ABIArgInfo::InAlloca:
       break;
 
     case ABIArgInfo::Indirect: {
@@ -948,8 +1015,11 @@
       // If the coerce-to type is a first class aggregate, flatten it.  Either
       // way is semantically identical, but fast-isel and the optimizer
       // generally likes scalar values better than FCAs.
+      // We cannot do this for functions using the AAPCS calling convention,
+      // as structures are treated differently by that calling convention.
       llvm::Type *argType = argAI.getCoerceToType();
-      if (llvm::StructType *st = dyn_cast<llvm::StructType>(argType)) {
+      llvm::StructType *st = dyn_cast<llvm::StructType>(argType);
+      if (st && !isAAPCSVFP(FI, getTarget())) {
         for (unsigned i = 0, e = st->getNumElements(); i != e; ++i)
           argTypes.push_back(st->getElementType(i));
       } else {
@@ -964,6 +1034,13 @@
     }
   }
 
+  // Add the inalloca struct as the last parameter type.
+  if (llvm::StructType *ArgStruct = FI.getArgStruct())
+    argTypes.push_back(ArgStruct->getPointerTo());
+
+  if (SwapThisWithSRet)
+    std::swap(argTypes[0], argTypes[1]);
+
   bool Erased = FunctionsBeingProcessed.erase(&FI); (void)Erased;
   assert(Erased && "Not in set?");
   
@@ -1006,6 +1083,8 @@
       FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
     if (TargetDecl->hasAttr<NoReturnAttr>())
       FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
+    if (TargetDecl->hasAttr<NoDuplicateAttr>())
+      FuncAttrs.addAttribute(llvm::Attribute::NoDuplicate);
 
     if (const FunctionDecl *Fn = dyn_cast<FunctionDecl>(TargetDecl)) {
       const FunctionProtoType *FPT = Fn->getType()->getAs<FunctionProtoType>();
@@ -1028,6 +1107,8 @@
     }
     if (TargetDecl->hasAttr<MallocAttr>())
       RetAttrs.addAttribute(llvm::Attribute::NoAlias);
+    if (TargetDecl->hasAttr<ReturnsNonNullAttr>())
+      RetAttrs.addAttribute(llvm::Attribute::NonNull);
   }
 
   if (CodeGenOpts.OptimizeSize)
@@ -1038,6 +1119,9 @@
     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.
@@ -1074,6 +1158,7 @@
 
   QualType RetTy = FI.getReturnType();
   unsigned Index = 1;
+  bool SwapThisWithSRet = false;
   const ABIArgInfo &RetAI = FI.getReturnInfo();
   switch (RetAI.getKind()) {
   case ABIArgInfo::Extend:
@@ -1089,15 +1174,24 @@
   case ABIArgInfo::Ignore:
     break;
 
+  case ABIArgInfo::InAlloca: {
+    // inalloca disables readnone and readonly
+    FuncAttrs.removeAttribute(llvm::Attribute::ReadOnly)
+      .removeAttribute(llvm::Attribute::ReadNone);
+    break;
+  }
+
   case ABIArgInfo::Indirect: {
     llvm::AttrBuilder SRETAttrs;
     SRETAttrs.addAttribute(llvm::Attribute::StructRet);
     if (RetAI.getInReg())
       SRETAttrs.addAttribute(llvm::Attribute::InReg);
-    PAL.push_back(llvm::
-                  AttributeSet::get(getLLVMContext(), Index, SRETAttrs));
+    SwapThisWithSRet = RetAI.isSRetAfterThis();
+    PAL.push_back(llvm::AttributeSet::get(
+        getLLVMContext(), SwapThisWithSRet ? 2 : Index, SRETAttrs));
 
-    ++Index;
+    if (!SwapThisWithSRet)
+      ++Index;
     // sret disables readnone and readonly
     FuncAttrs.removeAttribute(llvm::Attribute::ReadOnly)
       .removeAttribute(llvm::Attribute::ReadNone);
@@ -1108,18 +1202,31 @@
     llvm_unreachable("Invalid ABI kind for return argument");
   }
 
+  if (const auto *RefTy = RetTy->getAs<ReferenceType>()) {
+    QualType PTy = RefTy->getPointeeType();
+    if (!PTy->isIncompleteType() && PTy->isConstantSizeType())
+      RetAttrs.addDereferenceableAttr(getContext().getTypeSizeInChars(PTy)
+                                        .getQuantity());
+    else if (getContext().getTargetAddressSpace(PTy) == 0)
+      RetAttrs.addAttribute(llvm::Attribute::NonNull);
+  }
+
   if (RetAttrs.hasAttributes())
     PAL.push_back(llvm::
                   AttributeSet::get(getLLVMContext(),
                                     llvm::AttributeSet::ReturnIndex,
                                     RetAttrs));
 
-  for (CGFunctionInfo::const_arg_iterator it = FI.arg_begin(),
-         ie = FI.arg_end(); it != ie; ++it) {
-    QualType ParamType = it->type;
-    const ABIArgInfo &AI = it->info;
+  for (const auto &I : FI.arguments()) {
+    QualType ParamType = I.type;
+    const ABIArgInfo &AI = I.info;
     llvm::AttrBuilder Attrs;
 
+    // Skip over the sret parameter when it comes second.  We already handled it
+    // above.
+    if (Index == 2 && SwapThisWithSRet)
+      ++Index;
+
     if (AI.getPaddingType()) {
       if (AI.getPaddingInReg())
         PAL.push_back(llvm::AttributeSet::get(getLLVMContext(), Index,
@@ -1138,14 +1245,15 @@
       else if (ParamType->isUnsignedIntegerOrEnumerationType())
         Attrs.addAttribute(llvm::Attribute::ZExt);
       // FALL THROUGH
-    case ABIArgInfo::Direct:
+    case ABIArgInfo::Direct: {
       if (AI.getInReg())
         Attrs.addAttribute(llvm::Attribute::InReg);
 
       // FIXME: handle sseregparm someday...
 
-      if (llvm::StructType *STy =
-          dyn_cast<llvm::StructType>(AI.getCoerceToType())) {
+      llvm::StructType *STy =
+          dyn_cast<llvm::StructType>(AI.getCoerceToType());
+      if (!isAAPCSVFP(FI, getTarget()) && STy) {
         unsigned Extra = STy->getNumElements()-1;  // 1 will be added below.
         if (Attrs.hasAttributes())
           for (unsigned I = 0; I < Extra; ++I)
@@ -1154,7 +1262,7 @@
         Index += Extra;
       }
       break;
-
+    }
     case ABIArgInfo::Indirect:
       if (AI.getInReg())
         Attrs.addAttribute(llvm::Attribute::InReg);
@@ -1173,6 +1281,13 @@
       // Skip increment, no matching LLVM parameter.
       continue;
 
+    case ABIArgInfo::InAlloca:
+      // inalloca disables readnone and readonly.
+      FuncAttrs.removeAttribute(llvm::Attribute::ReadOnly)
+          .removeAttribute(llvm::Attribute::ReadNone);
+      // Skip increment, no matching LLVM parameter.
+      continue;
+
     case ABIArgInfo::Expand: {
       SmallVector<llvm::Type*, 8> types;
       // FIXME: This is rather inefficient. Do we ever actually need to do
@@ -1184,10 +1299,27 @@
     }
     }
 
+    if (const auto *RefTy = ParamType->getAs<ReferenceType>()) {
+      QualType PTy = RefTy->getPointeeType();
+      if (!PTy->isIncompleteType() && PTy->isConstantSizeType())
+        Attrs.addDereferenceableAttr(getContext().getTypeSizeInChars(PTy)
+                                       .getQuantity());
+      else if (getContext().getTargetAddressSpace(PTy) == 0)
+        Attrs.addAttribute(llvm::Attribute::NonNull);
+    }
+
     if (Attrs.hasAttributes())
       PAL.push_back(llvm::AttributeSet::get(getLLVMContext(), Index, Attrs));
     ++Index;
   }
+
+  // Add the inalloca attribute to the trailing inalloca parameter if present.
+  if (FI.usesInAlloca()) {
+    llvm::AttrBuilder Attrs;
+    Attrs.addAttribute(llvm::Attribute::InAlloca);
+    PAL.push_back(llvm::AttributeSet::get(getLLVMContext(), Index, Attrs));
+  }
+
   if (FuncAttrs.hasAttributes())
     PAL.push_back(llvm::
                   AttributeSet::get(getLLVMContext(),
@@ -1224,7 +1356,7 @@
   // return statements.
   if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(CurCodeDecl)) {
     if (FD->hasImplicitReturnZero()) {
-      QualType RetTy = FD->getResultType().getUnqualifiedType();
+      QualType RetTy = FD->getReturnType().getUnqualifiedType();
       llvm::Type* LLVMTy = CGM.getTypes().ConvertType(RetTy);
       llvm::Constant* Zero = llvm::Constant::getNullValue(LLVMTy);
       Builder.CreateStore(Zero, ReturnValue);
@@ -1237,15 +1369,48 @@
   // Emit allocs for param decls.  Give the LLVM Argument nodes names.
   llvm::Function::arg_iterator AI = Fn->arg_begin();
 
-  // Name the struct return argument.
-  if (CGM.ReturnTypeUsesSRet(FI)) {
-    AI->setName("agg.result");
-    AI->addAttr(llvm::AttributeSet::get(getLLVMContext(),
-                                        AI->getArgNo() + 1,
-                                        llvm::Attribute::NoAlias));
-    ++AI;
+  // If we're using inalloca, all the memory arguments are GEPs off of the last
+  // parameter, which is a pointer to the complete memory area.
+  llvm::Value *ArgStruct = nullptr;
+  if (FI.usesInAlloca()) {
+    llvm::Function::arg_iterator EI = Fn->arg_end();
+    --EI;
+    ArgStruct = EI;
+    assert(ArgStruct->getType() == FI.getArgStruct()->getPointerTo());
   }
 
+  // Name the struct return parameter, which can come first or second.
+  const ABIArgInfo &RetAI = FI.getReturnInfo();
+  bool SwapThisWithSRet = false;
+  if (RetAI.isIndirect()) {
+    SwapThisWithSRet = RetAI.isSRetAfterThis();
+    if (SwapThisWithSRet)
+      ++AI;
+    AI->setName("agg.result");
+    AI->addAttr(llvm::AttributeSet::get(getLLVMContext(), AI->getArgNo() + 1,
+                                        llvm::Attribute::NoAlias));
+    if (SwapThisWithSRet)
+      --AI;  // Go back to the beginning for 'this'.
+    else
+      ++AI;  // Skip the sret parameter.
+  }
+
+  // Get the function-level nonnull attribute if it exists.
+  const NonNullAttr *NNAtt =
+    CurCodeDecl ? CurCodeDecl->getAttr<NonNullAttr>() : nullptr;
+
+  // Track if we received the parameter as a pointer (indirect, byval, or
+  // inalloca).  If already have a pointer, EmitParmDecl doesn't need to copy it
+  // into a local alloca for us.
+  enum ValOrPointer { HaveValue = 0, HavePointer = 1 };
+  typedef llvm::PointerIntPair<llvm::Value *, 1> ValueAndIsPtr;
+  SmallVector<ValueAndIsPtr, 16> ArgVals;
+  ArgVals.reserve(Args.size());
+
+  // Create a pointer value for every parameter declaration.  This usually
+  // entails copying one or more LLVM IR arguments into an alloca.  Don't push
+  // any cleanups or do anything that might unwind.  We do that separately, so
+  // we can push the cleanups in the correct order for the ABI.
   assert(FI.arg_size() == Args.size() &&
          "Mismatch between function signature & arguments.");
   unsigned ArgNo = 1;
@@ -1264,6 +1429,13 @@
       ++AI;
 
     switch (ArgI.getKind()) {
+    case ABIArgInfo::InAlloca: {
+      llvm::Value *V = Builder.CreateStructGEP(
+          ArgStruct, ArgI.getInAllocaFieldIndex(), Arg->getName());
+      ArgVals.push_back(ValueAndIsPtr(V, HavePointer));
+      continue;  // Don't increment AI!
+    }
+
     case ABIArgInfo::Indirect: {
       llvm::Value *V = AI;
 
@@ -1290,6 +1462,7 @@
                                false);
           V = AlignedTemp;
         }
+        ArgVals.push_back(ValueAndIsPtr(V, HavePointer));
       } else {
         // Load scalar value from indirect argument.
         CharUnits Alignment = getContext().getTypeAlignInChars(Ty);
@@ -1298,8 +1471,8 @@
 
         if (isPromoted)
           V = emitArgumentDemotion(*this, Arg, V);
+        ArgVals.push_back(ValueAndIsPtr(V, HaveValue));
       }
-      EmitParmDecl(*Arg, V, ArgNo);
       break;
     }
 
@@ -1313,6 +1486,49 @@
         assert(AI != Fn->arg_end() && "Argument mismatch!");
         llvm::Value *V = AI;
 
+        if (const ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(Arg)) {
+          if ((NNAtt && NNAtt->isNonNull(PVD->getFunctionScopeIndex())) ||
+              PVD->hasAttr<NonNullAttr>())
+            AI->addAttr(llvm::AttributeSet::get(getLLVMContext(),
+                                                AI->getArgNo() + 1,
+                                                llvm::Attribute::NonNull));
+
+          QualType OTy = PVD->getOriginalType();
+          if (const auto *ArrTy =
+              getContext().getAsConstantArrayType(OTy)) {
+            // A C99 array parameter declaration with the static keyword also
+            // indicates dereferenceability, and if the size is constant we can
+            // use the dereferenceable attribute (which requires the size in
+            // bytes).
+            if (ArrTy->getSizeModifier() == ArrayType::Static) {
+              QualType ETy = ArrTy->getElementType();
+              uint64_t ArrSize = ArrTy->getSize().getZExtValue();
+              if (!ETy->isIncompleteType() && ETy->isConstantSizeType() &&
+                  ArrSize) {
+                llvm::AttrBuilder Attrs;
+                Attrs.addDereferenceableAttr(
+                  getContext().getTypeSizeInChars(ETy).getQuantity()*ArrSize);
+                AI->addAttr(llvm::AttributeSet::get(getLLVMContext(),
+                                                    AI->getArgNo() + 1, Attrs));
+              } else if (getContext().getTargetAddressSpace(ETy) == 0) {
+                AI->addAttr(llvm::AttributeSet::get(getLLVMContext(),
+                                                    AI->getArgNo() + 1,
+                                                    llvm::Attribute::NonNull));
+              }
+            }
+          } else if (const auto *ArrTy =
+                     getContext().getAsVariableArrayType(OTy)) {
+            // For C99 VLAs with the static keyword, we don't know the size so
+            // we can't use the dereferenceable attribute, but in addrspace(0)
+            // we know that it must be nonnull.
+            if (ArrTy->getSizeModifier() == VariableArrayType::Static &&
+                !getContext().getTargetAddressSpace(ArrTy->getElementType()))
+              AI->addAttr(llvm::AttributeSet::get(getLLVMContext(),
+                                                  AI->getArgNo() + 1,
+                                                  llvm::Attribute::NonNull));
+          }
+        }
+
         if (Arg->getType().isRestrictQualified())
           AI->addAttr(llvm::AttributeSet::get(getLLVMContext(),
                                               AI->getArgNo() + 1,
@@ -1340,7 +1556,7 @@
         if (V->getType() != LTy)
           V = Builder.CreateBitCast(V, LTy);
 
-        EmitParmDecl(*Arg, V, ArgNo);
+        ArgVals.push_back(ValueAndIsPtr(V, HaveValue));
         break;
       }
 
@@ -1368,8 +1584,10 @@
       // If the coerce-to type is a first class aggregate, we flatten it and
       // pass the elements. Either way is semantically identical, but fast-isel
       // and the optimizer generally likes scalar values better than FCAs.
+      // We cannot do this for functions using the AAPCS calling convention,
+      // as structures are treated differently by that calling convention.
       llvm::StructType *STy = dyn_cast<llvm::StructType>(ArgI.getCoerceToType());
-      if (STy && STy->getNumElements() > 1) {
+      if (!isAAPCSVFP(FI, getTarget()) && STy && STy->getNumElements() > 1) {
         uint64_t SrcSize = CGM.getDataLayout().getTypeAllocSize(STy);
         llvm::Type *DstTy =
           cast<llvm::PointerType>(Ptr->getType())->getElementType();
@@ -1412,8 +1630,10 @@
         V = EmitLoadOfScalar(V, false, AlignmentToUse, Ty, Arg->getLocStart());
         if (isPromoted)
           V = emitArgumentDemotion(*this, Arg, V);
+        ArgVals.push_back(ValueAndIsPtr(V, HaveValue));
+      } else {
+        ArgVals.push_back(ValueAndIsPtr(V, HavePointer));
       }
-      EmitParmDecl(*Arg, V, ArgNo);
       continue;  // Skip ++AI increment, already done.
     }
 
@@ -1426,7 +1646,7 @@
       Alloca->setAlignment(Align.getQuantity());
       LValue LV = MakeAddrLValue(Alloca, Ty, Align);
       llvm::Function::arg_iterator End = ExpandTypeFromArgs(Ty, LV, AI);
-      EmitParmDecl(*Arg, Alloca, ArgNo);
+      ArgVals.push_back(ValueAndIsPtr(Alloca, HavePointer));
 
       // Name the arguments used in expansion and increment AI.
       unsigned Index = 0;
@@ -1437,19 +1657,36 @@
 
     case ABIArgInfo::Ignore:
       // Initialize the local variable appropriately.
-      if (!hasScalarEvaluationKind(Ty))
-        EmitParmDecl(*Arg, CreateMemTemp(Ty), ArgNo);
-      else
-        EmitParmDecl(*Arg, llvm::UndefValue::get(ConvertType(Arg->getType())),
-                     ArgNo);
+      if (!hasScalarEvaluationKind(Ty)) {
+        ArgVals.push_back(ValueAndIsPtr(CreateMemTemp(Ty), HavePointer));
+      } else {
+        llvm::Value *U = llvm::UndefValue::get(ConvertType(Arg->getType()));
+        ArgVals.push_back(ValueAndIsPtr(U, HaveValue));
+      }
 
       // Skip increment, no matching LLVM parameter.
       continue;
     }
 
     ++AI;
+
+    if (ArgNo == 1 && SwapThisWithSRet)
+      ++AI;  // Skip the sret parameter.
   }
+
+  if (FI.usesInAlloca())
+    ++AI;
   assert(AI == Fn->arg_end() && "Argument mismatch!");
+
+  if (getTarget().getCXXABI().areArgsDestroyedLeftToRightInCallee()) {
+    for (int I = Args.size() - 1; I >= 0; --I)
+      EmitParmDecl(*Args[I], ArgVals[I].getPointer(), ArgVals[I].getInt(),
+                   I + 1);
+  } else {
+    for (unsigned I = 0, E = Args.size(); I != E; ++I)
+      EmitParmDecl(*Args[I], ArgVals[I].getPointer(), ArgVals[I].getInt(),
+                   I + 1);
+  }
 }
 
 static void eraseUnusedBitCasts(llvm::Instruction *insn) {
@@ -1468,8 +1705,8 @@
                                                     llvm::Value *result) {
   // We must be immediately followed the cast.
   llvm::BasicBlock *BB = CGF.Builder.GetInsertBlock();
-  if (BB->empty()) return 0;
-  if (&BB->back() != result) return 0;
+  if (BB->empty()) return nullptr;
+  if (&BB->back() != result) return nullptr;
 
   llvm::Type *resultType = result->getType();
 
@@ -1487,7 +1724,7 @@
 
     // Require the generator to be immediately followed by the cast.
     if (generator->getNextNode() != bitcast)
-      return 0;
+      return nullptr;
 
     insnsToKill.push_back(bitcast);
   }
@@ -1497,7 +1734,7 @@
   // or
   //   %generator = call i8* @objc_retainAutoreleasedReturnValue(i8* %originalResult)
   llvm::CallInst *call = dyn_cast<llvm::CallInst>(generator);
-  if (!call) return 0;
+  if (!call) return nullptr;
 
   bool doRetainAutorelease;
 
@@ -1525,7 +1762,7 @@
       insnsToKill.push_back(prev);
     }
   } else {
-    return 0;
+    return nullptr;
   }
 
   result = call->getArgOperand(0);
@@ -1558,16 +1795,16 @@
   // This is only applicable to a method with an immutable 'self'.
   const ObjCMethodDecl *method =
     dyn_cast_or_null<ObjCMethodDecl>(CGF.CurCodeDecl);
-  if (!method) return 0;
+  if (!method) return nullptr;
   const VarDecl *self = method->getSelfDecl();
-  if (!self->getType().isConstQualified()) return 0;
+  if (!self->getType().isConstQualified()) return nullptr;
 
   // Look for a retain call.
   llvm::CallInst *retainCall =
     dyn_cast<llvm::CallInst>(result->stripPointerCasts());
   if (!retainCall ||
       retainCall->getCalledValue() != CGF.CGM.getARCEntrypoints().objc_retain)
-    return 0;
+    return nullptr;
 
   // Look for an ordinary load of 'self'.
   llvm::Value *retainedValue = retainCall->getArgOperand(0);
@@ -1575,7 +1812,7 @@
     dyn_cast<llvm::LoadInst>(retainedValue->stripPointerCasts());
   if (!load || load->isAtomic() || load->isVolatile() || 
       load->getPointerOperand() != CGF.GetAddrOfLocalVar(self))
-    return 0;
+    return nullptr;
 
   // Okay!  Burn it all down.  This relies for correctness on the
   // assumption that the retain is emitted as part of the return and
@@ -1617,17 +1854,17 @@
   // with noreturn cleanups.
   if (!CGF.ReturnValue->hasOneUse()) {
     llvm::BasicBlock *IP = CGF.Builder.GetInsertBlock();
-    if (IP->empty()) return 0;
+    if (IP->empty()) return nullptr;
     llvm::StoreInst *store = dyn_cast<llvm::StoreInst>(&IP->back());
-    if (!store) return 0;
-    if (store->getPointerOperand() != CGF.ReturnValue) return 0;
+    if (!store) return nullptr;
+    if (store->getPointerOperand() != CGF.ReturnValue) return nullptr;
     assert(!store->isAtomic() && !store->isVolatile()); // see below
     return store;
   }
 
   llvm::StoreInst *store =
-    dyn_cast<llvm::StoreInst>(CGF.ReturnValue->use_back());
-  if (!store) return 0;
+    dyn_cast<llvm::StoreInst>(CGF.ReturnValue->user_back());
+  if (!store) return nullptr;
 
   // These aren't actually possible for non-coerced returns, and we
   // only care about non-coerced returns on this code path.
@@ -1639,7 +1876,7 @@
   llvm::BasicBlock *IP = CGF.Builder.GetInsertBlock();
   while (IP != StoreBB) {
     if (!(IP = IP->getSinglePredecessor()))
-      return 0;
+      return nullptr;
   }
 
   // Okay, the store's basic block dominates the insertion point; we
@@ -1651,25 +1888,41 @@
                                          bool EmitRetDbgLoc,
                                          SourceLocation EndLoc) {
   // Functions with no result always return void.
-  if (ReturnValue == 0) {
+  if (!ReturnValue) {
     Builder.CreateRetVoid();
     return;
   }
 
   llvm::DebugLoc RetDbgLoc;
-  llvm::Value *RV = 0;
+  llvm::Value *RV = nullptr;
   QualType RetTy = FI.getReturnType();
   const ABIArgInfo &RetAI = FI.getReturnInfo();
 
   switch (RetAI.getKind()) {
+  case ABIArgInfo::InAlloca:
+    // Aggregrates get evaluated directly into the destination.  Sometimes we
+    // need to return the sret value in a register, though.
+    assert(hasAggregateEvaluationKind(RetTy));
+    if (RetAI.getInAllocaSRet()) {
+      llvm::Function::arg_iterator EI = CurFn->arg_end();
+      --EI;
+      llvm::Value *ArgStruct = EI;
+      llvm::Value *SRet =
+          Builder.CreateStructGEP(ArgStruct, RetAI.getInAllocaFieldIndex());
+      RV = Builder.CreateLoad(SRet, "sret");
+    }
+    break;
+
   case ABIArgInfo::Indirect: {
+    auto AI = CurFn->arg_begin();
+    if (RetAI.isSRetAfterThis())
+      ++AI;
     switch (getEvaluationKind(RetTy)) {
     case TEK_Complex: {
       ComplexPairTy RT =
         EmitLoadOfComplex(MakeNaturalAlignAddrLValue(ReturnValue, RetTy),
                           EndLoc);
-      EmitStoreOfComplex(RT,
-                       MakeNaturalAlignAddrLValue(CurFn->arg_begin(), RetTy),
+      EmitStoreOfComplex(RT, MakeNaturalAlignAddrLValue(AI, RetTy),
                          /*isInit*/ true);
       break;
     }
@@ -1678,7 +1931,7 @@
       break;
     case TEK_Scalar:
       EmitStoreOfScalar(Builder.CreateLoad(ReturnValue),
-                        MakeNaturalAlignAddrLValue(CurFn->arg_begin(), RetTy),
+                        MakeNaturalAlignAddrLValue(AI, RetTy),
                         /*isInit*/ true);
       break;
     }
@@ -1707,7 +1960,7 @@
         // If that was the only use of the return value, nuke it as well now.
         if (ReturnValue->use_empty() && isa<llvm::AllocaInst>(ReturnValue)) {
           cast<llvm::AllocaInst>(ReturnValue)->eraseFromParent();
-          ReturnValue = 0;
+          ReturnValue = nullptr;
         }
 
       // Otherwise, we have to do a simple load.
@@ -1750,6 +2003,25 @@
     Ret->setDebugLoc(RetDbgLoc);
 }
 
+static bool isInAllocaArgument(CGCXXABI &ABI, QualType type) {
+  const CXXRecordDecl *RD = type->getAsCXXRecordDecl();
+  return RD && ABI.getRecordArgABI(RD) == CGCXXABI::RAA_DirectInMemory;
+}
+
+static AggValueSlot createPlaceholderSlot(CodeGenFunction &CGF, QualType Ty) {
+  // FIXME: Generate IR in one pass, rather than going back and fixing up these
+  // placeholders.
+  llvm::Type *IRTy = CGF.ConvertTypeForMem(Ty);
+  llvm::Value *Placeholder =
+      llvm::UndefValue::get(IRTy->getPointerTo()->getPointerTo());
+  Placeholder = CGF.Builder.CreateLoad(Placeholder);
+  return AggValueSlot::forAddr(Placeholder, CharUnits::Zero(),
+                               Ty.getQualifiers(),
+                               AggValueSlot::IsNotDestructed,
+                               AggValueSlot::DoesNotNeedGCBarriers,
+                               AggValueSlot::IsNotAliased);
+}
+
 void CodeGenFunction::EmitDelegateCallArg(CallArgList &args,
                                           const VarDecl *param,
                                           SourceLocation loc) {
@@ -1773,6 +2045,20 @@
     return args.add(RValue::get(Builder.CreateLoad(local)), type);
   }
 
+  if (isInAllocaArgument(CGM.getCXXABI(), type)) {
+    AggValueSlot Slot = createPlaceholderSlot(*this, type);
+    Slot.setExternallyDestructed();
+
+    // FIXME: Either emit a copy constructor call, or figure out how to do
+    // guaranteed tail calls with perfect forwarding in LLVM.
+    CGM.ErrorUnsupported(param, "non-trivial argument copy for thunk");
+    EmitNullInitialization(Slot.getAddr(), type);
+
+    RValue RV = Slot.asRValue();
+    args.add(RV, type);
+    return;
+  }
+
   args.add(convertTempToRValue(local, type, loc), type);
 }
 
@@ -1792,7 +2078,7 @@
   assert(!isProvablyNull(srcAddr) &&
          "shouldn't have writeback for provably null argument");
 
-  llvm::BasicBlock *contBB = 0;
+  llvm::BasicBlock *contBB = nullptr;
 
   // If the argument wasn't provably non-null, we need to null check
   // before doing the store.
@@ -1852,14 +2138,13 @@
 
 static void emitWritebacks(CodeGenFunction &CGF,
                            const CallArgList &args) {
-  for (CallArgList::writeback_iterator
-         i = args.writeback_begin(), e = args.writeback_end(); i != e; ++i)
-    emitWriteback(CGF, *i);
+  for (const auto &I : args.writebacks())
+    emitWriteback(CGF, I);
 }
 
 static void deactivateArgCleanupsBeforeCall(CodeGenFunction &CGF,
                                             const CallArgList &CallArgs) {
-  assert(CGF.getTarget().getCXXABI().isArgumentDestroyedByCallee());
+  assert(CGF.getTarget().getCXXABI().areArgsDestroyedLeftToRightInCallee());
   ArrayRef<CallArgList::CallArgCleanup> Cleanups =
     CallArgs.getCleanupsToDeactivate();
   // Iterate in reverse to increase the likelihood of popping the cleanup.
@@ -1874,7 +2159,7 @@
   if (const UnaryOperator *uop = dyn_cast<UnaryOperator>(E->IgnoreParens()))
     if (uop->getOpcode() == UO_AddrOf)
       return uop->getSubExpr();
-  return 0;
+  return nullptr;
 }
 
 /// Emit an argument that's being passed call-by-writeback.  That is,
@@ -1928,9 +2213,9 @@
         cast<llvm::PointerType>(destType->getElementType()));
     CGF.Builder.CreateStore(null, temp);
   }
-  
-  llvm::BasicBlock *contBB = 0;
-  llvm::BasicBlock *originBB = 0;
+
+  llvm::BasicBlock *contBB = nullptr;
+  llvm::BasicBlock *originBB = nullptr;
 
   // If the address is *not* known to be non-null, we need to switch.
   llvm::Value *finalArgument;
@@ -1957,7 +2242,7 @@
     }
   }
 
-  llvm::Value *valueToUse = 0;
+  llvm::Value *valueToUse = nullptr;
 
   // Perform a copy if necessary.
   if (shouldCopy) {
@@ -2004,6 +2289,99 @@
   args.add(RValue::get(finalArgument), CRE->getType());
 }
 
+void CallArgList::allocateArgumentMemory(CodeGenFunction &CGF) {
+  assert(!StackBase && !StackCleanup.isValid());
+
+  // Save the stack.
+  llvm::Function *F = CGF.CGM.getIntrinsic(llvm::Intrinsic::stacksave);
+  StackBase = CGF.Builder.CreateCall(F, "inalloca.save");
+
+  // Control gets really tied up in landing pads, so we have to spill the
+  // stacksave to an alloca to avoid violating SSA form.
+  // TODO: This is dead if we never emit the cleanup.  We should create the
+  // alloca and store lazily on the first cleanup emission.
+  StackBaseMem = CGF.CreateTempAlloca(CGF.Int8PtrTy, "inalloca.spmem");
+  CGF.Builder.CreateStore(StackBase, StackBaseMem);
+  CGF.pushStackRestore(EHCleanup, StackBaseMem);
+  StackCleanup = CGF.EHStack.getInnermostEHScope();
+  assert(StackCleanup.isValid());
+}
+
+void CallArgList::freeArgumentMemory(CodeGenFunction &CGF) const {
+  if (StackBase) {
+    CGF.DeactivateCleanupBlock(StackCleanup, StackBase);
+    llvm::Value *F = CGF.CGM.getIntrinsic(llvm::Intrinsic::stackrestore);
+    // We could load StackBase from StackBaseMem, but in the non-exceptional
+    // case we can skip it.
+    CGF.Builder.CreateCall(F, StackBase);
+  }
+}
+
+void CodeGenFunction::EmitCallArgs(CallArgList &Args,
+                                   ArrayRef<QualType> ArgTypes,
+                                   CallExpr::const_arg_iterator ArgBeg,
+                                   CallExpr::const_arg_iterator ArgEnd,
+                                   bool ForceColumnInfo) {
+  CGDebugInfo *DI = getDebugInfo();
+  SourceLocation CallLoc;
+  if (DI) CallLoc = DI->getLocation();
+
+  // We *have* to evaluate arguments from right to left in the MS C++ ABI,
+  // because arguments are destroyed left to right in the callee.
+  if (CGM.getTarget().getCXXABI().areArgsDestroyedLeftToRightInCallee()) {
+    // Insert a stack save if we're going to need any inalloca args.
+    bool HasInAllocaArgs = false;
+    for (ArrayRef<QualType>::iterator I = ArgTypes.begin(), E = ArgTypes.end();
+         I != E && !HasInAllocaArgs; ++I)
+      HasInAllocaArgs = isInAllocaArgument(CGM.getCXXABI(), *I);
+    if (HasInAllocaArgs) {
+      assert(getTarget().getTriple().getArch() == llvm::Triple::x86);
+      Args.allocateArgumentMemory(*this);
+    }
+
+    // Evaluate each argument.
+    size_t CallArgsStart = Args.size();
+    for (int I = ArgTypes.size() - 1; I >= 0; --I) {
+      CallExpr::const_arg_iterator Arg = ArgBeg + I;
+      EmitCallArg(Args, *Arg, ArgTypes[I]);
+      // Restore the debug location.
+      if (DI) DI->EmitLocation(Builder, CallLoc, ForceColumnInfo);
+    }
+
+    // Un-reverse the arguments we just evaluated so they match up with the LLVM
+    // IR function.
+    std::reverse(Args.begin() + CallArgsStart, Args.end());
+    return;
+  }
+
+  for (unsigned I = 0, E = ArgTypes.size(); I != E; ++I) {
+    CallExpr::const_arg_iterator Arg = ArgBeg + I;
+    assert(Arg != ArgEnd);
+    EmitCallArg(Args, *Arg, ArgTypes[I]);
+    // Restore the debug location.
+    if (DI) DI->EmitLocation(Builder, CallLoc, ForceColumnInfo);
+  }
+}
+
+namespace {
+
+struct DestroyUnpassedArg : EHScopeStack::Cleanup {
+  DestroyUnpassedArg(llvm::Value *Addr, QualType Ty)
+      : Addr(Addr), Ty(Ty) {}
+
+  llvm::Value *Addr;
+  QualType Ty;
+
+  void Emit(CodeGenFunction &CGF, Flags flags) override {
+    const CXXDestructorDecl *Dtor = Ty->getAsCXXRecordDecl()->getDestructor();
+    assert(!Dtor->isTrivial());
+    CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete, /*for vbase*/ false,
+                              /*Delegating=*/false, Addr);
+  }
+};
+
+}
+
 void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E,
                                   QualType type) {
   if (const ObjCIndirectCopyRestoreExpr *CRE
@@ -2027,22 +2405,36 @@
   // However, we still have to push an EH-only cleanup in case we unwind before
   // we make it to the call.
   if (HasAggregateEvalKind &&
-      CGM.getTarget().getCXXABI().isArgumentDestroyedByCallee()) {
-    const CXXRecordDecl *RD = type->getAsCXXRecordDecl();
-    if (RD && RD->hasNonTrivialDestructor()) {
-      AggValueSlot Slot = CreateAggTemp(type, "agg.arg.tmp");
-      Slot.setExternallyDestructed();
-      EmitAggExpr(E, Slot);
-      RValue RV = Slot.asRValue();
-      args.add(RV, type);
+      CGM.getTarget().getCXXABI().areArgsDestroyedLeftToRightInCallee()) {
+    // If we're using inalloca, use the argument memory.  Otherwise, use a
+    // temporary.
+    AggValueSlot Slot;
+    if (args.isUsingInAlloca())
+      Slot = createPlaceholderSlot(*this, type);
+    else
+      Slot = CreateAggTemp(type, "agg.tmp");
 
-      pushDestroy(EHCleanup, RV.getAggregateAddr(), type, destroyCXXObject,
-                  /*useEHCleanupForArray*/ true);
+    const CXXRecordDecl *RD = type->getAsCXXRecordDecl();
+    bool DestroyedInCallee =
+        RD && RD->hasNonTrivialDestructor() &&
+        CGM.getCXXABI().getRecordArgABI(RD) != CGCXXABI::RAA_Default;
+    if (DestroyedInCallee)
+      Slot.setExternallyDestructed();
+
+    EmitAggExpr(E, Slot);
+    RValue RV = Slot.asRValue();
+    args.add(RV, type);
+
+    if (DestroyedInCallee) {
+      // Create a no-op GEP between the placeholder and the cleanup so we can
+      // RAUW it successfully.  It also serves as a marker of the first
+      // instruction where the cleanup is active.
+      pushFullExprCleanup<DestroyUnpassedArg>(EHCleanup, Slot.getAddr(), type);
       // This unreachable is a temporary marker which will be removed later.
       llvm::Instruction *IsActive = Builder.CreateUnreachable();
       args.addArgCleanupDeactivation(EHStack.getInnermostEHScope(), IsActive);
-      return;
     }
+    return;
   }
 
   if (HasAggregateEvalKind && isa<ImplicitCastExpr>(E) &&
@@ -2128,6 +2520,7 @@
     call->setCallingConv(getRuntimeCC());
     Builder.CreateUnreachable();
   }
+  PGO.setCurrentRegionUnreachable();
 }
 
 /// Emits a call or invoke instruction to the given nullary runtime
@@ -2206,12 +2599,10 @@
     LValue LV = MakeAddrLValue(RV.getAggregateAddr(), Ty);
 
     if (RD->isUnion()) {
-      const FieldDecl *LargestFD = 0;
+      const FieldDecl *LargestFD = nullptr;
       CharUnits UnionSize = CharUnits::Zero();
 
-      for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
-           i != e; ++i) {
-        const FieldDecl *FD = *i;
+      for (const auto *FD : RD->fields()) {
         assert(!FD->isBitField() &&
                "Cannot expand structure with bit-field members.");
         CharUnits FieldSize = getContext().getTypeSizeInChars(FD->getType());
@@ -2225,10 +2616,7 @@
         ExpandTypeToArgs(LargestFD->getType(), FldRV, Args, IRFuncTy);
       }
     } else {
-      for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
-           i != e; ++i) {
-        FieldDecl *FD = *i;
-
+      for (const auto *FD : RD->fields()) {
         RValue FldRV = EmitRValueForField(LV, FD, SourceLocation());
         ExpandTypeToArgs(FD->getType(), FldRV, Args, IRFuncTy);
       }
@@ -2251,6 +2639,20 @@
   }
 }
 
+/// \brief Store a non-aggregate value to an address to initialize it.  For
+/// initialization, a non-atomic store will be used.
+static void EmitInitStoreOfNonAggregate(CodeGenFunction &CGF, RValue Src,
+                                        LValue Dst) {
+  if (Src.isScalar())
+    CGF.EmitStoreOfScalar(Src.getScalarVal(), Dst, /*init=*/true);
+  else
+    CGF.EmitStoreOfComplex(Src.getComplexVal(), Dst, /*init=*/true);
+}
+
+void CodeGenFunction::deferPlaceholderReplacement(llvm::Instruction *Old,
+                                                  llvm::Value *New) {
+  DeferredReplacements.push_back(std::make_pair(Old, New));
+}
 
 RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
                                  llvm::Value *Callee,
@@ -2272,14 +2674,44 @@
     cast<llvm::FunctionType>(
                   cast<llvm::PointerType>(Callee->getType())->getElementType());
 
+  // If we're using inalloca, insert the allocation after the stack save.
+  // FIXME: Do this earlier rather than hacking it in here!
+  llvm::Value *ArgMemory = nullptr;
+  if (llvm::StructType *ArgStruct = CallInfo.getArgStruct()) {
+    llvm::Instruction *IP = CallArgs.getStackBase();
+    llvm::AllocaInst *AI;
+    if (IP) {
+      IP = IP->getNextNode();
+      AI = new llvm::AllocaInst(ArgStruct, "argmem", IP);
+    } else {
+      AI = CreateTempAlloca(ArgStruct, "argmem");
+    }
+    AI->setUsedWithInAlloca(true);
+    assert(AI->isUsedWithInAlloca() && !AI->isStaticAlloca());
+    ArgMemory = AI;
+  }
+
   // If the call returns a temporary with struct return, create a temporary
   // alloca to hold the result, unless one is given to us.
-  if (CGM.ReturnTypeUsesSRet(CallInfo)) {
-    llvm::Value *Value = ReturnValue.getValue();
-    if (!Value)
-      Value = CreateMemTemp(RetTy);
-    Args.push_back(Value);
-    checkArgMatches(Value, IRArgNo, IRFuncTy);
+  llvm::Value *SRetPtr = nullptr;
+  bool SwapThisWithSRet = false;
+  if (RetAI.isIndirect() || RetAI.isInAlloca()) {
+    SRetPtr = ReturnValue.getValue();
+    if (!SRetPtr)
+      SRetPtr = CreateMemTemp(RetTy);
+    if (RetAI.isIndirect()) {
+      Args.push_back(SRetPtr);
+      SwapThisWithSRet = RetAI.isSRetAfterThis();
+      if (SwapThisWithSRet)
+        IRArgNo = 1;
+      checkArgMatches(SRetPtr, IRArgNo, IRFuncTy);
+      if (SwapThisWithSRet)
+        IRArgNo = 0;
+    } else {
+      llvm::Value *Addr =
+          Builder.CreateStructGEP(ArgMemory, RetAI.getInAllocaFieldIndex());
+      Builder.CreateStore(SRetPtr, Addr);
+    }
   }
 
   assert(CallInfo.arg_size() == CallArgs.size() &&
@@ -2290,6 +2722,10 @@
     const ABIArgInfo &ArgInfo = info_it->info;
     RValue RV = I->RV;
 
+    // Skip 'sret' if it came second.
+    if (IRArgNo == 1 && SwapThisWithSRet)
+      ++IRArgNo;
+
     CharUnits TypeAlign = getContext().getTypeAlignInChars(I->Ty);
 
     // Insert a padding argument to ensure proper alignment.
@@ -2299,6 +2735,35 @@
     }
 
     switch (ArgInfo.getKind()) {
+    case ABIArgInfo::InAlloca: {
+      assert(getTarget().getTriple().getArch() == llvm::Triple::x86);
+      if (RV.isAggregate()) {
+        // Replace the placeholder with the appropriate argument slot GEP.
+        llvm::Instruction *Placeholder =
+            cast<llvm::Instruction>(RV.getAggregateAddr());
+        CGBuilderTy::InsertPoint IP = Builder.saveIP();
+        Builder.SetInsertPoint(Placeholder);
+        llvm::Value *Addr = Builder.CreateStructGEP(
+            ArgMemory, ArgInfo.getInAllocaFieldIndex());
+        Builder.restoreIP(IP);
+        deferPlaceholderReplacement(Placeholder, Addr);
+      } else {
+        // Store the RValue into the argument struct.
+        llvm::Value *Addr =
+            Builder.CreateStructGEP(ArgMemory, ArgInfo.getInAllocaFieldIndex());
+        unsigned AS = Addr->getType()->getPointerAddressSpace();
+        llvm::Type *MemType = ConvertTypeForMem(I->Ty)->getPointerTo(AS);
+        // There are some cases where a trivial bitcast is not avoidable.  The
+        // definition of a type later in a translation unit may change it's type
+        // from {}* to (%struct.foo*)*.
+        if (Addr->getType() != MemType)
+          Addr = Builder.CreateBitCast(Addr, MemType);
+        LValue argLV = MakeAddrLValue(Addr, I->Ty, TypeAlign);
+        EmitInitStoreOfNonAggregate(*this, RV, argLV);
+      }
+      break; // Don't increment IRArgNo!
+    }
+
     case ABIArgInfo::Indirect: {
       if (RV.isScalar() || RV.isComplex()) {
         // Make a temporary alloca to pass the argument.
@@ -2307,13 +2772,8 @@
           AI->setAlignment(ArgInfo.getIndirectAlign());
         Args.push_back(AI);
 
-        LValue argLV =
-          MakeAddrLValue(Args.back(), I->Ty, TypeAlign);
-        
-        if (RV.isScalar())
-          EmitStoreOfScalar(RV.getScalarVal(), argLV, /*init*/ true);
-        else
-          EmitStoreOfComplex(RV.getComplexVal(), argLV, /*init*/ true);
+        LValue argLV = MakeAddrLValue(Args.back(), I->Ty, TypeAlign);
+        EmitInitStoreOfNonAggregate(*this, RV, argLV);
         
         // Validate argument match.
         checkArgMatches(AI, IRArgNo, IRFuncTy);
@@ -2386,11 +2846,7 @@
       if (RV.isScalar() || RV.isComplex()) {
         SrcPtr = CreateMemTemp(I->Ty, "coerce");
         LValue SrcLV = MakeAddrLValue(SrcPtr, I->Ty, TypeAlign);
-        if (RV.isScalar()) {
-          EmitStoreOfScalar(RV.getScalarVal(), SrcLV, /*init*/ true);
-        } else {
-          EmitStoreOfComplex(RV.getComplexVal(), SrcLV, /*init*/ true);
-        }
+        EmitInitStoreOfNonAggregate(*this, RV, SrcLV);
       } else
         SrcPtr = RV.getAggregateAddr();
 
@@ -2406,8 +2862,11 @@
       // If the coerce-to type is a first class aggregate, we flatten it and
       // pass the elements. Either way is semantically identical, but fast-isel
       // and the optimizer generally likes scalar values better than FCAs.
-      if (llvm::StructType *STy =
-            dyn_cast<llvm::StructType>(ArgInfo.getCoerceToType())) {
+      // We cannot do this for functions using the AAPCS calling convention,
+      // as structures are treated differently by that calling convention.
+      llvm::StructType *STy =
+            dyn_cast<llvm::StructType>(ArgInfo.getCoerceToType());
+      if (STy && !isAAPCSVFP(CallInfo, getTarget())) {
         llvm::Type *SrcTy =
           cast<llvm::PointerType>(SrcPtr->getType())->getElementType();
         uint64_t SrcSize = CGM.getDataLayout().getTypeAllocSize(SrcTy);
@@ -2456,6 +2915,42 @@
     }
   }
 
+  if (SwapThisWithSRet)
+    std::swap(Args[0], Args[1]);
+
+  if (ArgMemory) {
+    llvm::Value *Arg = ArgMemory;
+    if (CallInfo.isVariadic()) {
+      // When passing non-POD arguments by value to variadic functions, we will
+      // end up with a variadic prototype and an inalloca call site.  In such
+      // cases, we can't do any parameter mismatch checks.  Give up and bitcast
+      // the callee.
+      unsigned CalleeAS =
+          cast<llvm::PointerType>(Callee->getType())->getAddressSpace();
+      Callee = Builder.CreateBitCast(
+          Callee, getTypes().GetFunctionType(CallInfo)->getPointerTo(CalleeAS));
+    } else {
+      llvm::Type *LastParamTy =
+          IRFuncTy->getParamType(IRFuncTy->getNumParams() - 1);
+      if (Arg->getType() != LastParamTy) {
+#ifndef NDEBUG
+        // Assert that these structs have equivalent element types.
+        llvm::StructType *FullTy = CallInfo.getArgStruct();
+        llvm::StructType *DeclaredTy = cast<llvm::StructType>(
+            cast<llvm::PointerType>(LastParamTy)->getElementType());
+        assert(DeclaredTy->getNumElements() == FullTy->getNumElements());
+        for (llvm::StructType::element_iterator DI = DeclaredTy->element_begin(),
+                                                DE = DeclaredTy->element_end(),
+                                                FI = FullTy->element_begin();
+             DI != DE; ++DI, ++FI)
+          assert(*DI == *FI);
+#endif
+        Arg = Builder.CreateBitCast(Arg, LastParamTy);
+      }
+    }
+    Args.push_back(Arg);
+  }
+
   if (!CallArgs.getCleanupsToDeactivate().empty())
     deactivateArgCleanupsBeforeCall(*this, CallArgs);
 
@@ -2496,7 +2991,7 @@
   llvm::AttributeSet Attrs = llvm::AttributeSet::get(getLLVMContext(),
                                                      AttributeList);
 
-  llvm::BasicBlock *InvokeDest = 0;
+  llvm::BasicBlock *InvokeDest = nullptr;
   if (!Attrs.hasAttribute(llvm::AttributeSet::FunctionIndex,
                           llvm::Attribute::NoUnwind))
     InvokeDest = getInvokeDest();
@@ -2512,6 +3007,12 @@
   if (callOrInvoke)
     *callOrInvoke = CS.getInstruction();
 
+  if (CurCodeDecl && CurCodeDecl->hasAttr<FlattenAttr>() &&
+      !CS.hasFnAttr(llvm::Attribute::NoInline))
+    Attrs =
+        Attrs.addAttribute(getLLVMContext(), llvm::AttributeSet::FunctionIndex,
+                           llvm::Attribute::AlwaysInline);
+
   CS.setAttributes(Attrs);
   CS.setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));
 
@@ -2545,9 +3046,14 @@
   if (CallArgs.hasWritebacks())
     emitWritebacks(*this, CallArgs);
 
+  // The stack cleanup for inalloca arguments has to run out of the normal
+  // lexical order, so deactivate it and run it manually here.
+  CallArgs.freeArgumentMemory(*this);
+
   switch (RetAI.getKind()) {
+  case ABIArgInfo::InAlloca:
   case ABIArgInfo::Indirect:
-    return convertTempToRValue(Args[0], RetTy, SourceLocation());
+    return convertTempToRValue(SRetPtr, RetTy, SourceLocation());
 
   case ABIArgInfo::Ignore:
     // If we are ignoring an argument that had a result, make sure to
diff --git a/lib/CodeGen/CGCall.h b/lib/CodeGen/CGCall.h
index 532cb59..9510a1c 100644
--- a/lib/CodeGen/CGCall.h
+++ b/lib/CodeGen/CGCall.h
@@ -56,6 +56,8 @@
   class CallArgList :
     public SmallVector<CallArg, 16> {
   public:
+    CallArgList() : StackBase(nullptr), StackBaseMem(nullptr) {}
+
     struct Writeback {
       /// The original argument.  Note that the argument l-value
       /// is potentially null.
@@ -97,9 +99,12 @@
 
     bool hasWritebacks() const { return !Writebacks.empty(); }
 
-    typedef SmallVectorImpl<Writeback>::const_iterator writeback_iterator;
-    writeback_iterator writeback_begin() const { return Writebacks.begin(); }
-    writeback_iterator writeback_end() const { return Writebacks.end(); }
+    typedef llvm::iterator_range<SmallVectorImpl<Writeback>::const_iterator>
+      writeback_const_range;
+
+    writeback_const_range writebacks() const {
+      return writeback_const_range(Writebacks.begin(), Writebacks.end());
+    }
 
     void addArgCleanupDeactivation(EHScopeStack::stable_iterator Cleanup,
                                    llvm::Instruction *IsActiveIP) {
@@ -113,6 +118,14 @@
       return CleanupsToDeactivate;
     }
 
+    void allocateArgumentMemory(CodeGenFunction &CGF);
+    llvm::Instruction *getStackBase() const { return StackBase; }
+    void freeArgumentMemory(CodeGenFunction &CGF) const;
+
+    /// \brief Returns if we're using an inalloca struct to pass arguments in
+    /// memory.
+    bool isUsingInAlloca() const { return StackBase; }
+
   private:
     SmallVector<Writeback, 1> Writebacks;
 
@@ -120,6 +133,17 @@
     /// is used to cleanup objects that are owned by the callee once the call
     /// occurs.
     SmallVector<CallArgCleanup, 1> CleanupsToDeactivate;
+
+    /// The stacksave call.  It dominates all of the argument evaluation.
+    llvm::CallInst *StackBase;
+
+    /// The alloca holding the stackbase.  We need it to maintain SSA form.
+    llvm::AllocaInst *StackBaseMem;
+
+    /// The iterator pointing to the stack restore cleanup.  We manually run and
+    /// deactivate this cleanup after the call in the unexceptional case because
+    /// it doesn't run in the normal order.
+    EHScopeStack::stable_iterator StackCleanup;
   };
 
   /// FunctionArgList - Type for representing both the decl and type
diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp
index 4848d75..9427de1 100644
--- a/lib/CodeGen/CGClass.cpp
+++ b/lib/CodeGen/CGClass.cpp
@@ -12,10 +12,10 @@
 //===----------------------------------------------------------------------===//
 
 #include "CGBlocks.h"
+#include "CGCXXABI.h"
 #include "CGDebugInfo.h"
 #include "CGRecordLayout.h"
 #include "CodeGenFunction.h"
-#include "CGCXXABI.h"
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/EvaluatedExprVisitor.h"
@@ -66,8 +66,8 @@
     ComputeNonVirtualBaseClassOffset(getContext(), ClassDecl,
                                      PathBegin, PathEnd);
   if (Offset.isZero())
-    return 0;
-  
+    return nullptr;
+
   llvm::Type *PtrDiffTy = 
   Types.ConvertType(getContext().getPointerDiffType());
   
@@ -114,7 +114,7 @@
                                 CharUnits nonVirtualOffset,
                                 llvm::Value *virtualOffset) {
   // Assert that we have something to do.
-  assert(!nonVirtualOffset.isZero() || virtualOffset != 0);
+  assert(!nonVirtualOffset.isZero() || virtualOffset != nullptr);
 
   // Compute the offset from the static and dynamic components.
   llvm::Value *baseOffset;
@@ -143,8 +143,8 @@
   assert(PathBegin != PathEnd && "Base path should not be empty!");
 
   CastExpr::path_const_iterator Start = PathBegin;
-  const CXXRecordDecl *VBase = 0;
-  
+  const CXXRecordDecl *VBase = nullptr;
+
   // Sema has done some convenient canonicalization here: if the
   // access path involved any virtual steps, the conversion path will
   // *start* with a step down to the correct virtual base subobject,
@@ -169,7 +169,7 @@
     const ASTRecordLayout &layout = getContext().getASTRecordLayout(Derived);
     CharUnits vBaseOffset = layout.getVBaseClassOffset(VBase);
     NonVirtualOffset += vBaseOffset;
-    VBase = 0; // we no longer have a virtual step
+    VBase = nullptr; // we no longer have a virtual step
   }
 
   // Get the base pointer type.
@@ -180,11 +180,11 @@
   // just do a bitcast; null checks are unnecessary.
   if (NonVirtualOffset.isZero() && !VBase) {
     return Builder.CreateBitCast(Value, BasePtrTy);
-  }    
+  }
 
-  llvm::BasicBlock *origBB = 0;
-  llvm::BasicBlock *endBB = 0;
-  
+  llvm::BasicBlock *origBB = nullptr;
+  llvm::BasicBlock *endBB = nullptr;
+
   // Skip over the offset (and the vtable load) if we're supposed to
   // null-check the pointer.
   if (NullCheckValue) {
@@ -198,7 +198,7 @@
   }
 
   // Compute the virtual offset.
-  llvm::Value *VirtualOffset = 0;
+  llvm::Value *VirtualOffset = nullptr;
   if (VBase) {
     VirtualOffset =
       CGM.getCXXABI().GetVirtualBaseClassOffset(*this, Value, Derived, VBase);
@@ -246,11 +246,11 @@
     // No offset, we can just cast back.
     return Builder.CreateBitCast(Value, DerivedPtrTy);
   }
-  
-  llvm::BasicBlock *CastNull = 0;
-  llvm::BasicBlock *CastNotNull = 0;
-  llvm::BasicBlock *CastEnd = 0;
-  
+
+  llvm::BasicBlock *CastNull = nullptr;
+  llvm::BasicBlock *CastNotNull = nullptr;
+  llvm::BasicBlock *CastEnd = nullptr;
+
   if (NullCheckValue) {
     CastNull = createBasicBlock("cast.null");
     CastNotNull = createBasicBlock("cast.notnull");
@@ -290,7 +290,7 @@
                                               bool Delegating) {
   if (!CGM.getCXXABI().NeedsVTTParameter(GD)) {
     // This constructor/destructor does not need a VTT parameter.
-    return 0;
+    return nullptr;
   }
   
   const CXXRecordDecl *RD = cast<CXXMethodDecl>(CurCodeDecl)->getParent();
@@ -342,7 +342,7 @@
     CallBaseDtor(const CXXRecordDecl *Base, bool BaseIsVirtual)
       : BaseClass(Base), BaseIsVirtual(BaseIsVirtual) {}
 
-    void Emit(CodeGenFunction &CGF, Flags flags) {
+    void Emit(CodeGenFunction &CGF, Flags flags) override {
       const CXXRecordDecl *DerivedClass =
         cast<CXXMethodDecl>(CGF.CurCodeDecl)->getParent();
 
@@ -454,7 +454,7 @@
 
     switch (CGF.getEvaluationKind(T)) {
     case TEK_Scalar:
-      CGF.EmitScalarInit(Init, /*decl*/ 0, LV, false);
+      CGF.EmitScalarInit(Init, /*decl*/ nullptr, LV, false);
       break;
     case TEK_Complex:
       CGF.EmitComplexExprIntoLValue(Init, LV, /*isInit*/ true);
@@ -549,10 +549,8 @@
     // If we are initializing an anonymous union field, drill down to
     // the field.
     IndirectFieldDecl *IndirectField = MemberInit->getIndirectMember();
-    IndirectFieldDecl::chain_iterator I = IndirectField->chain_begin(),
-      IEnd = IndirectField->chain_end();
-    for ( ; I != IEnd; ++I)
-      LHS = CGF.EmitLValueForFieldInitialization(LHS, cast<FieldDecl>(*I));
+    for (const auto *I : IndirectField->chain())
+      LHS = CGF.EmitLValueForFieldInitialization(LHS, cast<FieldDecl>(I));
     FieldType = MemberInit->getIndirectMember()->getAnonField()->getType();
   } else {
     LHS = CGF.EmitLValueForFieldInitialization(LHS, Field);
@@ -609,7 +607,7 @@
     EmitComplexExprIntoLValue(Init, LHS, /*isInit*/ true);
     break;
   case TEK_Aggregate: {
-    llvm::Value *ArrayIndexVar = 0;
+    llvm::Value *ArrayIndexVar = nullptr;
     if (ArrayIndexes.size()) {
       llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
       
@@ -699,6 +697,10 @@
   const CXXConstructorDecl *Ctor = cast<CXXConstructorDecl>(CurGD.getDecl());
   CXXCtorType CtorType = CurGD.getCtorType();
 
+  assert((CGM.getTarget().getCXXABI().hasConstructorVariants() ||
+          CtorType == Ctor_Complete) &&
+         "can only generate complete ctor for this ABI");
+
   // Before we go any further, try the complete->base constructor
   // delegation optimization.
   if (CtorType == Ctor_Complete && IsConstructorDelegationValid(Ctor) &&
@@ -717,6 +719,9 @@
   if (IsTryBody)
     EnterCXXTryStmt(*cast<CXXTryStmt>(Body), true);
 
+  RegionCounter Cnt = getPGORegionCounter(Body);
+  Cnt.beginRegion(Builder);
+
   RunCleanupsScope RunCleanups(*this);
 
   // TODO: in restricted cases, we can emit the vbase initializers of
@@ -772,8 +777,8 @@
                     const VarDecl *SrcRec)
       : CGF(CGF), ClassDecl(ClassDecl), SrcRec(SrcRec), 
         RecLayout(CGF.getContext().getASTRecordLayout(ClassDecl)),
-        FirstField(0), LastField(0), FirstFieldOffset(0), LastFieldOffset(0),
-        LastAddedFieldIndex(0) { }
+        FirstField(nullptr), LastField(nullptr), FirstFieldOffset(0),
+        LastFieldOffset(0), LastAddedFieldIndex(0) {}
 
     static bool isMemcpyableField(FieldDecl *F) {
       Qualifiers Qual = F->getType().getQualifiers();
@@ -783,7 +788,7 @@
     }
 
     void addMemcpyableField(FieldDecl *F) {
-      if (FirstField == 0)
+      if (!FirstField)
         addInitialField(F);
       else
         addNextField(F);
@@ -805,7 +810,7 @@
     void emitMemcpy() {
       // Give the subclass a chance to bail out if it feels the memcpy isn't
       // worth it (e.g. Hasn't aggregated enough data).
-      if (FirstField == 0) {
+      if (!FirstField) {
         return;
       }
 
@@ -839,7 +844,7 @@
     }
 
     void reset() {
-      FirstField = 0;
+      FirstField = nullptr;
     }
 
   protected:
@@ -912,7 +917,7 @@
                                                FunctionArgList &Args) {
       if (CD->isCopyOrMoveConstructor() && CD->isDefaulted())
         return Args[Args.size() - 1];
-      return 0; 
+      return nullptr;
     }
 
     // Returns true if a CXXCtorInitializer represents a member initialization
@@ -921,7 +926,7 @@
       if (!MemcpyableCtor)
         return false;
       FieldDecl *Field = MemberInit->getMember();
-      assert(Field != 0 && "No field for member init.");
+      assert(Field && "No field for member init.");
       QualType FieldType = Field->getType();
       CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(MemberInit->getInit());
 
@@ -1009,71 +1014,71 @@
     // exists. Otherwise returns null.
     FieldDecl *getMemcpyableField(Stmt *S) {
       if (!AssignmentsMemcpyable)
-        return 0;
+        return nullptr;
       if (BinaryOperator *BO = dyn_cast<BinaryOperator>(S)) {
         // Recognise trivial assignments.
         if (BO->getOpcode() != BO_Assign)
-          return 0;
+          return nullptr;
         MemberExpr *ME = dyn_cast<MemberExpr>(BO->getLHS());
         if (!ME)
-          return 0;
+          return nullptr;
         FieldDecl *Field = dyn_cast<FieldDecl>(ME->getMemberDecl());
         if (!Field || !isMemcpyableField(Field))
-          return 0;
+          return nullptr;
         Stmt *RHS = BO->getRHS();
         if (ImplicitCastExpr *EC = dyn_cast<ImplicitCastExpr>(RHS))
           RHS = EC->getSubExpr();
         if (!RHS)
-          return 0;
+          return nullptr;
         MemberExpr *ME2 = dyn_cast<MemberExpr>(RHS);
         if (dyn_cast<FieldDecl>(ME2->getMemberDecl()) != Field)
-          return 0;
+          return nullptr;
         return Field;
       } else if (CXXMemberCallExpr *MCE = dyn_cast<CXXMemberCallExpr>(S)) {
         CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MCE->getCalleeDecl());
         if (!(MD && (MD->isCopyAssignmentOperator() ||
                        MD->isMoveAssignmentOperator()) &&
               MD->isTrivial()))
-          return 0;
+          return nullptr;
         MemberExpr *IOA = dyn_cast<MemberExpr>(MCE->getImplicitObjectArgument());
         if (!IOA)
-          return 0;
+          return nullptr;
         FieldDecl *Field = dyn_cast<FieldDecl>(IOA->getMemberDecl());
         if (!Field || !isMemcpyableField(Field))
-          return 0;
+          return nullptr;
         MemberExpr *Arg0 = dyn_cast<MemberExpr>(MCE->getArg(0));
         if (!Arg0 || Field != dyn_cast<FieldDecl>(Arg0->getMemberDecl()))
-          return 0;
+          return nullptr;
         return Field;
       } else if (CallExpr *CE = dyn_cast<CallExpr>(S)) {
         FunctionDecl *FD = dyn_cast<FunctionDecl>(CE->getCalleeDecl());
         if (!FD || FD->getBuiltinID() != Builtin::BI__builtin_memcpy)
-          return 0;
+          return nullptr;
         Expr *DstPtr = CE->getArg(0);
         if (ImplicitCastExpr *DC = dyn_cast<ImplicitCastExpr>(DstPtr))
           DstPtr = DC->getSubExpr();
         UnaryOperator *DUO = dyn_cast<UnaryOperator>(DstPtr);
         if (!DUO || DUO->getOpcode() != UO_AddrOf)
-          return 0;
+          return nullptr;
         MemberExpr *ME = dyn_cast<MemberExpr>(DUO->getSubExpr());
         if (!ME)
-          return 0;
+          return nullptr;
         FieldDecl *Field = dyn_cast<FieldDecl>(ME->getMemberDecl());
         if (!Field || !isMemcpyableField(Field))
-          return 0;
+          return nullptr;
         Expr *SrcPtr = CE->getArg(1);
         if (ImplicitCastExpr *SC = dyn_cast<ImplicitCastExpr>(SrcPtr))
           SrcPtr = SC->getSubExpr();
         UnaryOperator *SUO = dyn_cast<UnaryOperator>(SrcPtr);
         if (!SUO || SUO->getOpcode() != UO_AddrOf)
-          return 0;
+          return nullptr;
         MemberExpr *ME2 = dyn_cast<MemberExpr>(SUO->getSubExpr());
         if (!ME2 || Field != dyn_cast<FieldDecl>(ME2->getMemberDecl()))
-          return 0;
+          return nullptr;
         return Field;
       }
 
-      return 0;
+      return nullptr;
     }
 
     bool AssignmentsMemcpyable;
@@ -1132,7 +1137,7 @@
   CXXConstructorDecl::init_const_iterator B = CD->init_begin(),
                                           E = CD->init_end();
 
-  llvm::BasicBlock *BaseCtorContinueBB = 0;
+  llvm::BasicBlock *BaseCtorContinueBB = nullptr;
   if (ClassDecl->getNumVBases() &&
       !CGM.getTarget().getCXXABI().hasConstructorVariants()) {
     // The ABIs that don't have constructor variants need to put a branch
@@ -1190,23 +1195,17 @@
     return false;
 
   // Check fields.
-  for (CXXRecordDecl::field_iterator I = BaseClassDecl->field_begin(),
-       E = BaseClassDecl->field_end(); I != E; ++I) {
-    const FieldDecl *Field = *I;
-    
+  for (const auto *Field : BaseClassDecl->fields())
     if (!FieldHasTrivialDestructorBody(Context, Field))
       return false;
-  }
 
   // Check non-virtual bases.
-  for (CXXRecordDecl::base_class_const_iterator I = 
-       BaseClassDecl->bases_begin(), E = BaseClassDecl->bases_end();
-       I != E; ++I) {
-    if (I->isVirtual())
+  for (const auto &I : BaseClassDecl->bases()) {
+    if (I.isVirtual())
       continue;
 
     const CXXRecordDecl *NonVirtualBase =
-      cast<CXXRecordDecl>(I->getType()->castAs<RecordType>()->getDecl());
+      cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
     if (!HasTrivialDestructorBody(Context, NonVirtualBase,
                                   MostDerivedClassDecl))
       return false;
@@ -1214,11 +1213,9 @@
 
   if (BaseClassDecl == MostDerivedClassDecl) {
     // Check virtual bases.
-    for (CXXRecordDecl::base_class_const_iterator I = 
-         BaseClassDecl->vbases_begin(), E = BaseClassDecl->vbases_end();
-         I != E; ++I) {
+    for (const auto &I : BaseClassDecl->vbases()) {
       const CXXRecordDecl *VirtualBase =
-        cast<CXXRecordDecl>(I->getType()->castAs<RecordType>()->getDecl());
+        cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
       if (!HasTrivialDestructorBody(Context, VirtualBase,
                                     MostDerivedClassDecl))
         return false;      
@@ -1251,13 +1248,9 @@
 
   // Check the fields.
   const CXXRecordDecl *ClassDecl = Dtor->getParent();
-  for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(),
-       E = ClassDecl->field_end(); I != E; ++I) {
-    const FieldDecl *Field = *I;
-
+  for (const auto *Field : ClassDecl->fields())
     if (!FieldHasTrivialDestructorBody(Context, Field))
       return false;
-  }
 
   return true;
 }
@@ -1315,6 +1308,9 @@
   case Dtor_Base:
     assert(Body);
 
+    RegionCounter Cnt = getPGORegionCounter(Body);
+    Cnt.beginRegion(Builder);
+
     // Enter the cleanup scopes for fields and non-virtual bases.
     EnterDtorCleanups(Dtor, Dtor_Base);
 
@@ -1355,11 +1351,8 @@
   LexicalScope Scope(*this, RootCS->getSourceRange());
 
   AssignmentMemcpyizer AM(*this, AssignOp, Args);
-  for (CompoundStmt::const_body_iterator I = RootCS->body_begin(),
-                                         E = RootCS->body_end();
-       I != E; ++I) {
-    AM.emitAssignment(*I);  
-  }
+  for (auto *I : RootCS->body())
+    AM.emitAssignment(I);  
   AM.finish();
 }
 
@@ -1368,7 +1361,7 @@
   struct CallDtorDelete : EHScopeStack::Cleanup {
     CallDtorDelete() {}
 
-    void Emit(CodeGenFunction &CGF, Flags flags) {
+    void Emit(CodeGenFunction &CGF, Flags flags) override {
       const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CGF.CurCodeDecl);
       const CXXRecordDecl *ClassDecl = Dtor->getParent();
       CGF.EmitDeleteCall(Dtor->getOperatorDelete(), CGF.LoadCXXThis(),
@@ -1381,10 +1374,10 @@
   public:
     CallDtorDeleteConditional(llvm::Value *ShouldDeleteCondition)
       : ShouldDeleteCondition(ShouldDeleteCondition) {
-      assert(ShouldDeleteCondition != NULL);
+      assert(ShouldDeleteCondition != nullptr);
     }
 
-    void Emit(CodeGenFunction &CGF, Flags flags) {
+    void Emit(CodeGenFunction &CGF, Flags flags) override {
       llvm::BasicBlock *callDeleteBB = CGF.createBasicBlock("dtor.call_delete");
       llvm::BasicBlock *continueBB = CGF.createBasicBlock("dtor.continue");
       llvm::Value *ShouldCallDelete
@@ -1413,7 +1406,7 @@
       : field(field), destroyer(destroyer),
         useEHCleanupForArray(useEHCleanupForArray) {}
 
-    void Emit(CodeGenFunction &CGF, Flags flags) {
+    void Emit(CodeGenFunction &CGF, Flags flags) override {
       // Find the address of the field.
       llvm::Value *thisValue = CGF.LoadCXXThis();
       QualType RecordTy = CGF.getContext().getTagDeclType(field->getParent());
@@ -1427,19 +1420,19 @@
   };
 }
 
-/// EmitDtorEpilogue - Emit all code that comes at the end of class's
+/// \brief Emit all code that comes at the end of class's
 /// destructor. This is to call destructors on members and base classes
 /// in reverse order of their construction.
 void CodeGenFunction::EnterDtorCleanups(const CXXDestructorDecl *DD,
                                         CXXDtorType DtorType) {
-  assert(!DD->isTrivial() &&
-         "Should not emit dtor epilogue for trivial dtor!");
+  assert((!DD->isTrivial() || DD->hasAttr<DLLExportAttr>()) &&
+         "Should not emit dtor epilogue for non-exported trivial dtor!");
 
   // The deleting-destructor phase just needs to call the appropriate
   // operator delete that Sema picked up.
   if (DtorType == Dtor_Deleting) {
     assert(DD->getOperatorDelete() && 
-           "operator delete missing - EmitDtorEpilogue");
+           "operator delete missing - EnterDtorCleanups");
     if (CXXStructorImplicitParamValue) {
       // If there is an implicit param to the deleting dtor, it's a boolean
       // telling whether we should call delete at the end of the dtor.
@@ -1462,10 +1455,7 @@
 
     // We push them in the forward order so that they'll be popped in
     // the reverse order.
-    for (CXXRecordDecl::base_class_const_iterator I = 
-           ClassDecl->vbases_begin(), E = ClassDecl->vbases_end();
-              I != E; ++I) {
-      const CXXBaseSpecifier &Base = *I;
+    for (const auto &Base : ClassDecl->vbases()) {
       CXXRecordDecl *BaseClassDecl
         = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
     
@@ -1484,10 +1474,7 @@
   assert(DtorType == Dtor_Base);
   
   // Destroy non-virtual bases.
-  for (CXXRecordDecl::base_class_const_iterator I = 
-        ClassDecl->bases_begin(), E = ClassDecl->bases_end(); I != E; ++I) {
-    const CXXBaseSpecifier &Base = *I;
-    
+  for (const auto &Base : ClassDecl->bases()) {
     // Ignore virtual bases.
     if (Base.isVirtual())
       continue;
@@ -1504,11 +1491,8 @@
   }
 
   // Destroy direct fields.
-  SmallVector<const FieldDecl *, 16> FieldDecls;
-  for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(),
-       E = ClassDecl->field_end(); I != E; ++I) {
-    const FieldDecl *field = *I;
-    QualType type = field->getType();
+  for (const auto *Field : ClassDecl->fields()) {
+    QualType type = Field->getType();
     QualType::DestructionKind dtorKind = type.isDestructedType();
     if (!dtorKind) continue;
 
@@ -1517,7 +1501,7 @@
     if (RT && RT->getDecl()->isAnonymousStructOrUnion()) continue;
 
     CleanupKind cleanupKind = getCleanupKind(dtorKind);
-    EHStack.pushCleanup<DestroyField>(cleanupKind, field,
+    EHStack.pushCleanup<DestroyField>(cleanupKind, Field,
                                       getDestroyer(dtorKind),
                                       cleanupKind & EHCleanup);
   }
@@ -1568,7 +1552,7 @@
   // because of GCC extensions that permit zero-length arrays.  There
   // are probably legitimate places where we could assume that this
   // doesn't happen, but it's not clear that it's worth it.
-  llvm::BranchInst *zeroCheckBranch = 0;
+  llvm::BranchInst *zeroCheckBranch = nullptr;
 
   // Optimize for a constant count.
   llvm::ConstantInt *constantCount
@@ -1683,9 +1667,31 @@
     return;
   }
 
-  // Non-trivial constructors are handled in an ABI-specific manner.
-  CGM.getCXXABI().EmitConstructorCall(*this, D, Type, ForVirtualBase,
-                                      Delegating, This, ArgBeg, ArgEnd);
+  // C++11 [class.mfct.non-static]p2:
+  //   If a non-static member function of a class X is called for an object that
+  //   is not of type X, or of a type derived from X, the behavior is undefined.
+  // FIXME: Provide a source location here.
+  EmitTypeCheck(CodeGenFunction::TCK_ConstructorCall, SourceLocation(), This,
+                getContext().getRecordType(D->getParent()));
+
+  CallArgList Args;
+
+  // Push the this ptr.
+  Args.add(RValue::get(This), D->getThisType(getContext()));
+
+  // Add the rest of the user-supplied arguments.
+  const FunctionProtoType *FPT = D->getType()->castAs<FunctionProtoType>();
+  EmitCallArgs(Args, FPT, ArgBeg, ArgEnd);
+
+  // Insert any ABI-specific implicit constructor arguments.
+  unsigned ExtraArgs = CGM.getCXXABI().addImplicitConstructorArgs(
+      *this, D, Type, ForVirtualBase, Delegating, Args);
+
+  // Emit the call.
+  llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type);
+  const CGFunctionInfo &Info =
+      CGM.getTypes().arrangeCXXConstructorCall(Args, D, Type, ExtraArgs);
+  EmitCall(Info, Callee, ReturnValueSlot(), Args, D);
 }
 
 void
@@ -1704,38 +1710,23 @@
   assert(D->isInstance() &&
          "Trying to emit a member call expr on a static method!");
   
-  const FunctionProtoType *FPT = D->getType()->getAs<FunctionProtoType>();
+  const FunctionProtoType *FPT = D->getType()->castAs<FunctionProtoType>();
   
   CallArgList Args;
   
   // Push the this ptr.
   Args.add(RValue::get(This), D->getThisType(getContext()));
   
-  
   // Push the src ptr.
-  QualType QT = *(FPT->arg_type_begin());
+  QualType QT = *(FPT->param_type_begin());
   llvm::Type *t = CGM.getTypes().ConvertType(QT);
   Src = Builder.CreateBitCast(Src, t);
   Args.add(RValue::get(Src), QT);
-  
+
   // Skip over first argument (Src).
-  ++ArgBeg;
-  CallExpr::const_arg_iterator Arg = ArgBeg;
-  for (FunctionProtoType::arg_type_iterator I = FPT->arg_type_begin()+1,
-       E = FPT->arg_type_end(); I != E; ++I, ++Arg) {
-    assert(Arg != ArgEnd && "Running over edge of argument list!");
-    EmitCallArg(Args, *Arg, *I);
-  }
-  // Either we've emitted all the call args, or we have a call to a
-  // variadic function.
-  assert((Arg == ArgEnd || FPT->isVariadic()) &&
-         "Extra arguments in non-variadic function!");
-  // If we still have any arguments, emit them using the type of the argument.
-  for (; Arg != ArgEnd; ++Arg) {
-    QualType ArgType = Arg->getType();
-    EmitCallArg(Args, *Arg, ArgType);
-  }
-  
+  EmitCallArgs(Args, FPT->isVariadic(), FPT->param_type_begin() + 1,
+               FPT->param_type_end(), ArgBeg + 1, ArgEnd);
+
   EmitCall(CGM.getTypes().arrangeCXXMethodCall(Args, FPT, RequiredArgs::All),
            Callee, ReturnValueSlot(), Args, D);
 }
@@ -1790,7 +1781,7 @@
                            CXXDtorType Type)
       : Dtor(D), Addr(Addr), Type(Type) {}
 
-    void Emit(CodeGenFunction &CGF, Flags flags) {
+    void Emit(CodeGenFunction &CGF, Flags flags) override {
       CGF.EmitCXXDestructorCall(Dtor, Type, /*ForVirtualBase=*/false,
                                 /*Delegating=*/true, Addr);
     }
@@ -1830,23 +1821,8 @@
                                             bool ForVirtualBase,
                                             bool Delegating,
                                             llvm::Value *This) {
-  GlobalDecl GD(DD, Type);
-  llvm::Value *VTT = GetVTTParameter(GD, ForVirtualBase, Delegating);
-  llvm::Value *Callee = 0;
-  if (getLangOpts().AppleKext)
-    Callee = BuildAppleKextVirtualDestructorCall(DD, Type, 
-                                                 DD->getParent());
-    
-  if (!Callee)
-    Callee = CGM.GetAddrOfCXXDestructor(DD, Type);
-
-  if (DD->isVirtual())
-    This = CGM.getCXXABI().adjustThisArgumentForVirtualCall(*this, GD, This);
-
-  // FIXME: Provide a source location here.
-  EmitCXXMemberCall(DD, SourceLocation(), Callee, ReturnValueSlot(), This,
-                    VTT, getContext().getPointerType(getContext().VoidPtrTy),
-                    0, 0);
+  CGM.getCXXABI().EmitDestructorCall(*this, DD, Type, ForVirtualBase,
+                                     Delegating, This);
 }
 
 namespace {
@@ -1857,7 +1833,7 @@
     CallLocalDtor(const CXXDestructorDecl *D, llvm::Value *Addr)
       : Dtor(D), Addr(Addr) {}
 
-    void Emit(CodeGenFunction &CGF, Flags flags) {
+    void Emit(CodeGenFunction &CGF, Flags flags) override {
       CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete,
                                 /*ForVirtualBase=*/false,
                                 /*Delegating=*/false, Addr);
@@ -1894,7 +1870,7 @@
     return;
 
   // Compute where to store the address point.
-  llvm::Value *VirtualOffset = 0;
+  llvm::Value *VirtualOffset = nullptr;
   CharUnits NonVirtualOffset = CharUnits::Zero();
   
   if (NeedsVirtualOffset) {
@@ -1944,10 +1920,9 @@
   const CXXRecordDecl *RD = Base.getBase();
 
   // Traverse bases.
-  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 
-       E = RD->bases_end(); I != E; ++I) {
+  for (const auto &I : RD->bases()) {
     CXXRecordDecl *BaseDecl
-      = cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+      = cast<CXXRecordDecl>(I.getType()->getAs<RecordType>()->getDecl());
 
     // Ignore classes without a vtable.
     if (!BaseDecl->isDynamicClass())
@@ -1957,7 +1932,7 @@
     CharUnits BaseOffsetFromNearestVBase;
     bool BaseDeclIsNonVirtualPrimaryBase;
 
-    if (I->isVirtual()) {
+    if (I.isVirtual()) {
       // Check if we've visited this virtual base before.
       if (!VBases.insert(BaseDecl))
         continue;
@@ -1978,7 +1953,7 @@
     }
     
     InitializeVTablePointers(BaseSubobject(BaseDecl, BaseOffset), 
-                             I->isVirtual() ? BaseDecl : NearestVBase,
+                             I.isVirtual() ? BaseDecl : NearestVBase,
                              BaseOffsetFromNearestVBase,
                              BaseDeclIsNonVirtualPrimaryBase, 
                              VTableClass, VBases);
@@ -1993,7 +1968,7 @@
   // Initialize the vtable pointers for this class and all of its bases.
   VisitedVirtualBasesSetTy VBases;
   InitializeVTablePointers(BaseSubobject(RD, CharUnits::Zero()), 
-                           /*NearestVBase=*/0, 
+                           /*NearestVBase=*/nullptr,
                            /*OffsetFromNearestVBase=*/CharUnits::Zero(),
                            /*BaseIsNonVirtualPrimaryBase=*/false, RD, VBases);
 
@@ -2127,7 +2102,7 @@
   // Prepare the return slot.
   const FunctionProtoType *FPT =
     callOperator->getType()->castAs<FunctionProtoType>();
-  QualType resultType = FPT->getResultType();
+  QualType resultType = FPT->getReturnType();
   ReturnValueSlot returnSlot;
   if (!resultType->isVoidType() &&
       calleeFnInfo.getReturnInfo().getKind() == ABIArgInfo::Indirect &&
@@ -2162,11 +2137,9 @@
   CallArgs.add(RValue::get(ThisPtr), ThisType);
 
   // Add the rest of the parameters.
-  for (BlockDecl::param_const_iterator I = BD->param_begin(),
-       E = BD->param_end(); I != E; ++I) {
-    ParmVarDecl *param = *I;
+  for (auto param : BD->params())
     EmitDelegateCallArg(CallArgs, param, param->getLocStart());
-  }
+
   assert(!Lambda->isGenericLambda() && 
             "generic lambda interconversion to block not implemented");
   EmitForwardingCallToLambda(Lambda->getLambdaCallOperator(), CallArgs);
@@ -2194,11 +2167,9 @@
   CallArgs.add(RValue::get(ThisPtr), ThisType);
 
   // Add the rest of the parameters.
-  for (FunctionDecl::param_const_iterator I = MD->param_begin(),
-       E = MD->param_end(); I != E; ++I) {
-    ParmVarDecl *param = *I;
-    EmitDelegateCallArg(CallArgs, param, param->getLocStart());
-  }
+  for (auto Param : MD->params())
+    EmitDelegateCallArg(CallArgs, Param, Param->getLocStart());
+
   const CXXMethodDecl *CallOp = Lambda->getLambdaCallOperator();
   // For a generic lambda, find the corresponding call operator specialization
   // to which the call to the static-invoker shall be forwarded.
@@ -2206,9 +2177,9 @@
     assert(MD->isFunctionTemplateSpecialization());
     const TemplateArgumentList *TAL = MD->getTemplateSpecializationArgs();
     FunctionTemplateDecl *CallOpTemplate = CallOp->getDescribedFunctionTemplate();
-    void *InsertPos = 0;
+    void *InsertPos = nullptr;
     FunctionDecl *CorrespondingCallOpSpecialization = 
-        CallOpTemplate->findSpecialization(TAL->data(), TAL->size(), InsertPos); 
+        CallOpTemplate->findSpecialization(TAL->asArray(), InsertPos);
     assert(CorrespondingCallOpSpecialization);
     CallOp = cast<CXXMethodDecl>(CorrespondingCallOpSpecialization);
   }
diff --git a/lib/CodeGen/CGCleanup.cpp b/lib/CodeGen/CGCleanup.cpp
index 65de4d4..ed9f96d 100644
--- a/lib/CodeGen/CGCleanup.cpp
+++ b/lib/CodeGen/CGCleanup.cpp
@@ -50,7 +50,7 @@
     CodeGenFunction::ComplexPairTy V = rv.getComplexVal();
     llvm::Type *ComplexTy =
       llvm::StructType::get(V.first->getType(), V.second->getType(),
-                            (void*) 0);
+                            (void*) nullptr);
     llvm::Value *addr = CGF.CreateTempAlloca(ComplexTy, "saved-complex");
     CGF.Builder.CreateStore(V.first, CGF.Builder.CreateStructGEP(addr, 0));
     CGF.Builder.CreateStore(V.second, CGF.Builder.CreateStructGEP(addr, 1));
@@ -245,7 +245,7 @@
   assert(BranchFixups.size() >= MinSize && "fixup stack out of order");
 
   while (BranchFixups.size() > MinSize &&
-         BranchFixups.back().Destination == 0)
+         BranchFixups.back().Destination == nullptr)
     BranchFixups.pop_back();
 }
 
@@ -263,7 +263,7 @@
 
   // Set that as the active flag in the cleanup.
   EHCleanupScope &cleanup = cast<EHCleanupScope>(*EHStack.begin());
-  assert(cleanup.getActiveFlag() == 0 && "cleanup already has active flag?");
+  assert(!cleanup.getActiveFlag() && "cleanup already has active flag?");
   cleanup.setActiveFlag(active);
 
   if (cleanup.isNormalCleanup()) cleanup.setTestFlagInNormalCleanup();
@@ -283,7 +283,7 @@
   for (unsigned I = 0, E = CGF.EHStack.getNumBranchFixups(); I != E; ++I) {
     // Skip this fixup if its destination isn't set.
     BranchFixup &Fixup = CGF.EHStack.getBranchFixup(I);
-    if (Fixup.Destination == 0) continue;
+    if (Fixup.Destination == nullptr) continue;
 
     // If there isn't an OptimisticBranchBlock, then InitialBranch is
     // still pointing directly to its destination; forward it to the
@@ -293,7 +293,7 @@
     //   lbl:
     // i.e. where there's an unresolved fixup inside a single cleanup
     // entry which we're currently popping.
-    if (Fixup.OptimisticBranchBlock == 0) {
+    if (Fixup.OptimisticBranchBlock == nullptr) {
       new llvm::StoreInst(CGF.Builder.getInt32(Fixup.DestinationIndex),
                           CGF.getNormalCleanupDestSlot(),
                           Fixup.InitialBranch);
@@ -347,7 +347,7 @@
     BranchFixup &Fixup = EHStack.getBranchFixup(I);
     if (Fixup.Destination != Block) continue;
 
-    Fixup.Destination = 0;
+    Fixup.Destination = nullptr;
     ResolvedAny = true;
 
     // If it doesn't have an optimistic branch block, LatestBranch is
@@ -473,7 +473,7 @@
 
   // If there's an active flag, load it and skip the cleanup if it's
   // false.
-  llvm::BasicBlock *ContBB = 0;
+  llvm::BasicBlock *ContBB = nullptr;
   if (ActiveFlag) {
     ContBB = CGF.createBasicBlock("cleanup.done");
     llvm::BasicBlock *CleanupBB = CGF.createBasicBlock("cleanup.action");
@@ -528,7 +528,7 @@
   llvm::BasicBlock *unreachableBB = CGF.getUnreachableBlock();
   for (llvm::BasicBlock::use_iterator
          i = entry->use_begin(), e = entry->use_end(); i != e; ) {
-    llvm::Use &use = i.getUse();
+    llvm::Use &use = *i;
     ++i;
 
     use.set(unreachableBB);
@@ -568,15 +568,15 @@
   // Remember activation information.
   bool IsActive = Scope.isActive();
   llvm::Value *NormalActiveFlag =
-    Scope.shouldTestFlagInNormalCleanup() ? Scope.getActiveFlag() : 0;
+    Scope.shouldTestFlagInNormalCleanup() ? Scope.getActiveFlag() : nullptr;
   llvm::Value *EHActiveFlag = 
-    Scope.shouldTestFlagInEHCleanup() ? Scope.getActiveFlag() : 0;
+    Scope.shouldTestFlagInEHCleanup() ? Scope.getActiveFlag() : nullptr;
 
   // Check whether we need an EH cleanup.  This is only true if we've
   // generated a lazy EH cleanup block.
   llvm::BasicBlock *EHEntry = Scope.getCachedEHDispatchBlock();
-  assert(Scope.hasEHBranches() == (EHEntry != 0));
-  bool RequiresEHCleanup = (EHEntry != 0);
+  assert(Scope.hasEHBranches() == (EHEntry != nullptr));
+  bool RequiresEHCleanup = (EHEntry != nullptr);
   EHScopeStack::stable_iterator EHParent = Scope.getEnclosingEHScope();
 
   // Check the three conditions which might require a normal cleanup:
@@ -590,7 +590,7 @@
 
   // - whether there's a fallthrough
   llvm::BasicBlock *FallthroughSource = Builder.GetInsertBlock();
-  bool HasFallthrough = (FallthroughSource != 0 && IsActive);
+  bool HasFallthrough = (FallthroughSource != nullptr && IsActive);
 
   // Branch-through fall-throughs leave the insertion point set to the
   // end of the last cleanup, which points to the current scope.  The
@@ -720,7 +720,7 @@
       //   - if fall-through is a branch-through
       //   - if there are fixups that will be optimistically forwarded
       //     to the enclosing cleanup
-      llvm::BasicBlock *BranchThroughDest = 0;
+      llvm::BasicBlock *BranchThroughDest = nullptr;
       if (Scope.hasBranchThroughs() ||
           (FallthroughSource && FallthroughIsBranchThrough) ||
           (HasFixups && HasEnclosingCleanups)) {
@@ -729,7 +729,7 @@
         BranchThroughDest = CreateNormalEntry(*this, cast<EHCleanupScope>(S));
       }
 
-      llvm::BasicBlock *FallthroughDest = 0;
+      llvm::BasicBlock *FallthroughDest = nullptr;
       SmallVector<llvm::Instruction*, 2> InstsToAppend;
 
       // If there's exactly one branch-after and no other threads,
@@ -860,7 +860,9 @@
 
   // Emit the EH cleanup if required.
   if (RequiresEHCleanup) {
-    if (CGDebugInfo *DI = getDebugInfo())
+    CGDebugInfo *DI = getDebugInfo();
+    SaveAndRestoreLocation AutoRestoreLocation(*this, Builder);
+    if (DI)
       DI->EmitLocation(Builder, CurEHLocation);
 
     CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
@@ -941,7 +943,7 @@
     Fixup.Destination = Dest.getBlock();
     Fixup.DestinationIndex = Dest.getDestIndex();
     Fixup.InitialBranch = BI;
-    Fixup.OptimisticBranchBlock = 0;
+    Fixup.OptimisticBranchBlock = nullptr;
 
     Builder.ClearInsertionPoint();
     return;
diff --git a/lib/CodeGen/CGCleanup.h b/lib/CodeGen/CGCleanup.h
index 1bd6bba..1d4606f 100644
--- a/lib/CodeGen/CGCleanup.h
+++ b/lib/CodeGen/CGCleanup.h
@@ -96,7 +96,7 @@
   enum Kind { Cleanup, Catch, Terminate, Filter };
 
   EHScope(Kind kind, EHScopeStack::stable_iterator enclosingEHScope)
-    : CachedLandingPad(0), CachedEHDispatchBlock(0),
+    : CachedLandingPad(nullptr), CachedEHDispatchBlock(nullptr),
       EnclosingEHScope(enclosingEHScope) {
     CommonBits.Kind = kind;
   }
@@ -145,12 +145,12 @@
   struct Handler {
     /// A type info value, or null (C++ null, not an LLVM null pointer)
     /// for a catch-all.
-    llvm::Value *Type;
+    llvm::Constant *Type;
 
     /// The catch handler for this type.
     llvm::BasicBlock *Block;
 
-    bool isCatchAll() const { return Type == 0; }
+    bool isCatchAll() const { return Type == nullptr; }
   };
 
 private:
@@ -180,10 +180,10 @@
   }
 
   void setCatchAllHandler(unsigned I, llvm::BasicBlock *Block) {
-    setHandler(I, /*catchall*/ 0, Block);
+    setHandler(I, /*catchall*/ nullptr, Block);
   }
 
-  void setHandler(unsigned I, llvm::Value *Type, llvm::BasicBlock *Block) {
+  void setHandler(unsigned I, llvm::Constant *Type, llvm::BasicBlock *Block) {
     assert(I < getNumHandlers());
     getHandlers()[I].Type = Type;
     getHandlers()[I].Block = Block;
@@ -194,6 +194,15 @@
     return getHandlers()[I];
   }
 
+  // Clear all handler blocks.
+  // FIXME: it's better to always call clearHandlerBlocks in DTOR and have a
+  // 'takeHandler' or some such function which removes ownership from the
+  // EHCatchScope object if the handlers should live longer than EHCatchScope.
+  void clearHandlerBlocks() {
+    for (unsigned I = 0, N = getNumHandlers(); I != N; ++I)
+      delete getHandler(I).Block;
+  }
+
   typedef const Handler *iterator;
   iterator begin() const { return getHandlers(); }
   iterator end() const { return getHandlers() + getNumHandlers(); }
@@ -259,7 +268,7 @@
                  EHScopeStack::stable_iterator enclosingNormal,
                  EHScopeStack::stable_iterator enclosingEH)
     : EHScope(EHScope::Cleanup, enclosingEH), EnclosingNormal(enclosingNormal),
-      NormalBlock(0), ActiveFlag(0), ExtInfo(0) {
+      NormalBlock(nullptr), ActiveFlag(nullptr), ExtInfo(nullptr) {
     CleanupBits.IsNormalCleanup = isNormal;
     CleanupBits.IsEHCleanup = isEH;
     CleanupBits.IsActive = isActive;
@@ -446,7 +455,7 @@
   explicit iterator(char *Ptr) : Ptr(Ptr) {}
 
 public:
-  iterator() : Ptr(0) {}
+  iterator() : Ptr(nullptr) {}
 
   EHScope *get() const { 
     return reinterpret_cast<EHScope*>(Ptr);
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index fcb26f0..048c8f8 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -37,7 +37,7 @@
 #include "llvm/IR/Module.h"
 #include "llvm/Support/Dwarf.h"
 #include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Path.h"

+#include "llvm/Support/Path.h"
 using namespace clang;
 using namespace clang::CodeGen;
 
@@ -52,30 +52,35 @@
          "Region stack mismatch, stack not empty!");
 }
 
-
-NoLocation::NoLocation(CodeGenFunction &CGF, CGBuilderTy &B)
-  : DI(CGF.getDebugInfo()), Builder(B) {
+SaveAndRestoreLocation::SaveAndRestoreLocation(CodeGenFunction &CGF,
+                                               CGBuilderTy &B)
+    : DI(CGF.getDebugInfo()), Builder(B) {
   if (DI) {
     SavedLoc = DI->getLocation();
     DI->CurLoc = SourceLocation();
-    Builder.SetCurrentDebugLocation(llvm::DebugLoc());
   }
 }
 
+SaveAndRestoreLocation::~SaveAndRestoreLocation() {
+  if (DI)
+    DI->EmitLocation(Builder, SavedLoc);
+}
+
+NoLocation::NoLocation(CodeGenFunction &CGF, CGBuilderTy &B)
+  : SaveAndRestoreLocation(CGF, B) {
+  if (DI)
+    Builder.SetCurrentDebugLocation(llvm::DebugLoc());
+}
+
 NoLocation::~NoLocation() {
-  if (DI) {
+  if (DI)
     assert(Builder.getCurrentDebugLocation().isUnknown());
-    DI->CurLoc = SavedLoc;
-  }
 }
 
 ArtificialLocation::ArtificialLocation(CodeGenFunction &CGF, CGBuilderTy &B)
-  : DI(CGF.getDebugInfo()), Builder(B) {
-  if (DI) {
-    SavedLoc = DI->getLocation();
-    DI->CurLoc = SourceLocation();
+  : SaveAndRestoreLocation(CGF, B) {
+  if (DI)
     Builder.SetCurrentDebugLocation(llvm::DebugLoc());
-  }
 }
 
 void ArtificialLocation::Emit() {
@@ -91,10 +96,8 @@
 }
 
 ArtificialLocation::~ArtificialLocation() {
-  if (DI) {
+  if (DI)
     assert(Builder.getCurrentDebugLocation().getLine() == 0);
-    DI->CurLoc = SavedLoc;
-  }
 }
 
 void CGDebugInfo::setLocation(SourceLocation Loc) {
@@ -109,17 +112,14 @@
   if (LexicalBlockStack.empty()) return;
 
   SourceManager &SM = CGM.getContext().getSourceManager();
+  llvm::DIScope Scope(LexicalBlockStack.back());
   PresumedLoc PCLoc = SM.getPresumedLoc(CurLoc);
-  PresumedLoc PPLoc = SM.getPresumedLoc(PrevLoc);
 
-  if (PCLoc.isInvalid() || PPLoc.isInvalid() ||
-      !strcmp(PPLoc.getFilename(), PCLoc.getFilename()))
+  if (PCLoc.isInvalid() || Scope.getFilename() == PCLoc.getFilename())
     return;
 
-  llvm::MDNode *LB = LexicalBlockStack.back();
-  llvm::DIScope Scope = llvm::DIScope(LB);
   if (Scope.isLexicalBlockFile()) {
-    llvm::DILexicalBlockFile LBF = llvm::DILexicalBlockFile(LB);
+    llvm::DILexicalBlockFile LBF = llvm::DILexicalBlockFile(Scope);
     llvm::DIDescriptor D
       = DBuilder.createLexicalBlockFile(LBF.getScope(),
                                         getOrCreateFile(CurLoc));
@@ -225,34 +225,20 @@
 /// getClassName - Get class name including template argument list.
 StringRef
 CGDebugInfo::getClassName(const RecordDecl *RD) {
-  const ClassTemplateSpecializationDecl *Spec
-    = dyn_cast<ClassTemplateSpecializationDecl>(RD);
-  if (!Spec)
+  // quick optimization to avoid having to intern strings that are already
+  // stored reliably elsewhere
+  if (!isa<ClassTemplateSpecializationDecl>(RD))
     return RD->getName();
 
-  const TemplateArgument *Args;
-  unsigned NumArgs;
-  if (TypeSourceInfo *TAW = Spec->getTypeAsWritten()) {
-    const TemplateSpecializationType *TST =
-      cast<TemplateSpecializationType>(TAW->getType());
-    Args = TST->getArgs();
-    NumArgs = TST->getNumArgs();
-  } else {
-    const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
-    Args = TemplateArgs.data();
-    NumArgs = TemplateArgs.size();
-  }
-  StringRef Name = RD->getIdentifier()->getName();
-  PrintingPolicy Policy(CGM.getLangOpts());
-  SmallString<128> TemplateArgList;
+  SmallString<128> Name;
   {
-    llvm::raw_svector_ostream OS(TemplateArgList);
-    TemplateSpecializationType::PrintTemplateArgumentList(OS, Args, NumArgs,
-                                                          Policy);
+    llvm::raw_svector_ostream OS(Name);
+    RD->getNameForDiagnostic(OS, CGM.getContext().getPrintingPolicy(),
+                             /*Qualified*/ false);
   }
 
   // Copy this name on the side and use its reference.
-  return internString(Name, TemplateArgList);
+  return internString(Name);
 }
 
 /// getOrCreateFile - Get the file debug info descriptor for the input location.
@@ -328,11 +314,18 @@
 /// CreateCompileUnit - Create new compile unit.
 void CGDebugInfo::CreateCompileUnit() {
 
+  // 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
+  // mismatch with source locations and create extra lexical scopes or
+  // mismatched debug info (a CU with a DW_AT_file of "-", because that's what
+  // the driver passed, but functions/other things have DW_AT_file of "<stdin>"
+  // because that's what the SourceManager says)
+
   // Get absolute path name.
   SourceManager &SM = CGM.getContext().getSourceManager();
   std::string MainFileName = CGM.getCodeGenOpts().MainFileName;
   if (MainFileName.empty())
-    MainFileName = "<unknown>";
+    MainFileName = "<stdin>";
 
   // The main file name provided via the "-main-file-name" option contains just
   // the file name itself with no path information. This file name may have had
@@ -342,9 +335,9 @@
   if (const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID())) {
     MainFileDir = MainFile->getDir()->getName();
     if (MainFileDir != ".") {
-      llvm::SmallString<1024> MainFileDirSS(MainFileDir);

-      llvm::sys::path::append(MainFileDirSS, MainFileName);

-      MainFileName = MainFileDirSS.str();

+      llvm::SmallString<1024> MainFileDirSS(MainFileDir);
+      llvm::sys::path::append(MainFileDirSS, MainFileName);
+      MainFileName = MainFileDirSS.str();
     }
   }
 
@@ -355,7 +348,7 @@
   std::string SplitDwarfFile = CGM.getCodeGenOpts().SplitDwarfFile;
   StringRef SplitDwarfFilename = internString(SplitDwarfFile);
 
-  unsigned LangTag;
+  llvm::dwarf::SourceLanguage LangTag;
   const LangOptions &LO = CGM.getLangOpts();
   if (LO.CPlusPlus) {
     if (LO.ObjC1)
@@ -379,16 +372,19 @@
 
   // Create new compile unit.
   // FIXME - Eliminate TheCU.
-  TheCU = DBuilder.createCompileUnit(LangTag, Filename, getCurrentDirname(),
-                                     Producer, LO.Optimize,
-                                     CGM.getCodeGenOpts().DwarfDebugFlags,
-                                     RuntimeVers, SplitDwarfFilename);
+  TheCU = DBuilder.createCompileUnit(
+      LangTag, Filename, getCurrentDirname(), Producer, LO.Optimize,
+      CGM.getCodeGenOpts().DwarfDebugFlags, RuntimeVers, SplitDwarfFilename,
+      DebugKind <= CodeGenOptions::DebugLineTablesOnly
+          ? llvm::DIBuilder::LineTablesOnly
+          : llvm::DIBuilder::FullDebug,
+      DebugKind != CodeGenOptions::LocTrackingOnly);
 }
 
 /// CreateType - Get the Basic type from the cache or create a new
 /// one if necessary.
 llvm::DIType CGDebugInfo::CreateType(const BuiltinType *BT) {
-  unsigned Encoding = 0;
+  llvm::dwarf::TypeKind Encoding;
   StringRef BTName;
   switch (BT->getKind()) {
 #define BUILTIN_TYPE(Id, SingletonId)
@@ -402,11 +398,10 @@
   case BuiltinType::Void:
     return llvm::DIType();
   case BuiltinType::ObjCClass:
-    if (ClassTy)
-      return ClassTy;
-    ClassTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
-                                         "objc_class", TheCU,
-                                         getOrCreateMainFile(), 0);
+    if (!ClassTy)
+      ClassTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
+                                           "objc_class", TheCU,
+                                           getOrCreateMainFile(), 0);
     return ClassTy;
   case BuiltinType::ObjCId: {
     // typedef struct objc_class *Class;
@@ -435,12 +430,10 @@
     return ObjTy;
   }
   case BuiltinType::ObjCSel: {
-    if (SelTy)
-      return SelTy;
-    SelTy =
-      DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
-                                 "objc_selector", TheCU, getOrCreateMainFile(),
-                                 0);
+    if (!SelTy)
+      SelTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
+                                         "objc_selector", TheCU,
+                                         getOrCreateMainFile(), 0);
     return SelTy;
   }
 
@@ -515,7 +508,7 @@
 
 llvm::DIType CGDebugInfo::CreateType(const ComplexType *Ty) {
   // Bit size, align and offset of the type.
-  unsigned Encoding = llvm::dwarf::DW_ATE_complex_float;
+  llvm::dwarf::TypeKind Encoding = llvm::dwarf::DW_ATE_complex_float;
   if (Ty->isComplexIntegerType())
     Encoding = llvm::dwarf::DW_ATE_lo_user;
 
@@ -540,7 +533,7 @@
 
   // We will create one Derived type for one qualifier and recurse to handle any
   // additional ones.
-  unsigned Tag;
+  llvm::dwarf::Tag Tag;
   if (Qc.hasConst()) {
     Tag = llvm::dwarf::DW_TAG_const_type;
     Qc.removeConst();
@@ -620,7 +613,7 @@
   unsigned Line = getLineNumber(RD->getLocation());
   StringRef RDName = getClassName(RD);
 
-  unsigned Tag = 0;
+  llvm::dwarf::Tag Tag;
   if (RD->isStruct() || RD->isInterface())
     Tag = llvm::dwarf::DW_TAG_structure_type;
   else if (RD->isUnion())
@@ -632,11 +625,13 @@
 
   // Create the type.
   SmallString<256> FullName = getUniqueTagTypeName(Ty, CGM, TheCU);
-  return DBuilder.createForwardDecl(Tag, RDName, Ctx, DefUnit, Line, 0, 0, 0,
-                                    FullName);
+  llvm::DICompositeType RetTy = DBuilder.createReplaceableForwardDecl(
+      Tag, RDName, Ctx, DefUnit, Line, 0, 0, 0, FullName);
+  ReplaceMap.push_back(std::make_pair(Ty, static_cast<llvm::Value *>(RetTy)));
+  return RetTy;
 }
 
-llvm::DIType CGDebugInfo::CreatePointerLikeType(unsigned Tag,
+llvm::DIType CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag,
                                                 const Type *Ty,
                                                 QualType PointeeTy,
                                                 llvm::DIFile Unit) {
@@ -728,22 +723,47 @@
   return BlockLiteralGeneric;
 }
 
+llvm::DIType CGDebugInfo::CreateType(const TemplateSpecializationType *Ty, llvm::DIFile Unit) {
+  assert(Ty->isTypeAlias());
+  llvm::DIType Src = getOrCreateType(Ty->getAliasedType(), Unit);
+
+  SmallString<128> NS;
+  llvm::raw_svector_ostream OS(NS);
+  Ty->getTemplateName().print(OS, CGM.getContext().getPrintingPolicy(), /*qualified*/ false);
+
+  TemplateSpecializationType::PrintTemplateArgumentList(
+      OS, Ty->getArgs(), Ty->getNumArgs(),
+      CGM.getContext().getPrintingPolicy());
+
+  TypeAliasDecl *AliasDecl =
+      cast<TypeAliasTemplateDecl>(Ty->getTemplateName().getAsTemplateDecl())
+          ->getTemplatedDecl();
+
+  SourceLocation Loc = AliasDecl->getLocation();
+  llvm::DIFile File = getOrCreateFile(Loc);
+  unsigned Line = getLineNumber(Loc);
+
+  llvm::DIDescriptor Ctxt = getContextDescriptor(cast<Decl>(AliasDecl->getDeclContext()));
+
+  return DBuilder.createTypedef(Src, internString(OS.str()), File, Line, Ctxt);
+}
+
 llvm::DIType CGDebugInfo::CreateType(const TypedefType *Ty, llvm::DIFile Unit) {
   // Typedefs are derived from some other type.  If we have a typedef of a
   // typedef, make sure to emit the whole chain.
   llvm::DIType Src = getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit);
-  if (!Src)
-    return llvm::DIType();
   // We don't set size information, but do specify where the typedef was
   // declared.
-  unsigned Line = getLineNumber(Ty->getDecl()->getLocation());
+  SourceLocation Loc = Ty->getDecl()->getLocation();
+  llvm::DIFile File = getOrCreateFile(Loc);
+  unsigned Line = getLineNumber(Loc);
   const TypedefNameDecl *TyDecl = Ty->getDecl();
 
   llvm::DIDescriptor TypedefContext =
     getContextDescriptor(cast<Decl>(Ty->getDecl()->getDeclContext()));
 
   return
-    DBuilder.createTypedef(Src, TyDecl->getName(), Unit, Line, TypedefContext);
+    DBuilder.createTypedef(Src, TyDecl->getName(), File, Line, TypedefContext);
 }
 
 llvm::DIType CGDebugInfo::CreateType(const FunctionType *Ty,
@@ -751,15 +771,17 @@
   SmallVector<llvm::Value *, 16> EltTys;
 
   // Add the result type at least.
-  EltTys.push_back(getOrCreateType(Ty->getResultType(), Unit));
+  EltTys.push_back(getOrCreateType(Ty->getReturnType(), Unit));
 
   // Set up remainder of arguments if there is a prototype.
-  // FIXME: IF NOT, HOW IS THIS REPRESENTED?  llvm-gcc doesn't represent '...'!
+  // otherwise emit it as a variadic function.
   if (isa<FunctionNoProtoType>(Ty))
     EltTys.push_back(DBuilder.createUnspecifiedParameter());
   else if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(Ty)) {
-    for (unsigned i = 0, e = FPT->getNumArgs(); i != e; ++i)
-      EltTys.push_back(getOrCreateType(FPT->getArgType(i), Unit));
+    for (unsigned i = 0, e = FPT->getNumParams(); i != e; ++i)
+      EltTys.push_back(getOrCreateType(FPT->getParamType(i), Unit));
+    if (FPT->isVariadic())
+      EltTys.push_back(DBuilder.createUnspecifiedParameter());
   }
 
   llvm::DIArray EltTypeArray = DBuilder.getOrCreateArray(EltTys);
@@ -784,7 +806,7 @@
   uint64_t sizeInBits = 0;
   unsigned alignInBits = 0;
   if (!type->isIncompleteArrayType()) {
-    llvm::tie(sizeInBits, alignInBits) = CGM.getContext().getTypeInfo(type);
+    std::tie(sizeInBits, alignInBits) = CGM.getContext().getTypeInfo(type);
 
     if (sizeInBitsOverride)
       sizeInBits = sizeInBitsOverride;
@@ -813,7 +835,7 @@
   unsigned fieldno = 0;
   for (CXXRecordDecl::capture_const_iterator I = CXXDecl->captures_begin(),
          E = CXXDecl->captures_end(); I != E; ++I, ++Field, ++fieldno) {
-    const LambdaExpr::Capture C = *I;
+    const LambdaCapture &C = *I;
     if (C.capturesVariable()) {
       VarDecl *V = C.getCapturedVar();
       llvm::DIFile VUnit = getOrCreateFile(C.getLocation());
@@ -857,7 +879,7 @@
 
   unsigned LineNumber = getLineNumber(Var->getLocation());
   StringRef VName = Var->getName();
-  llvm::Constant *C = NULL;
+  llvm::Constant *C = nullptr;
   if (Var->getInit()) {
     const APValue *Value = Var->evaluateValue();
     if (Value) {
@@ -926,9 +948,8 @@
 
     // Static and non-static members should appear in the same order as
     // the corresponding declarations in the source program.
-    for (RecordDecl::decl_iterator I = record->decls_begin(),
-           E = record->decls_end(); I != E; ++I)
-      if (const VarDecl *V = dyn_cast<VarDecl>(*I)) {
+    for (const auto *I : record->decls())
+      if (const auto *V = dyn_cast<VarDecl>(I)) {
         // Reuse the existing static member declaration if one exists
         llvm::DenseMap<const Decl *, llvm::WeakVH>::iterator MI =
             StaticDataMemberCache.find(V->getCanonicalDecl());
@@ -939,7 +960,7 @@
               llvm::DIDerivedType(cast<llvm::MDNode>(MI->second)));
         } else
           elements.push_back(CreateRecordStaticField(V, RecordTy));
-      } else if (FieldDecl *field = dyn_cast<FieldDecl>(*I)) {
+      } else if (const auto *field = dyn_cast<FieldDecl>(I)) {
         CollectRecordNormalField(field, layout.getFieldOffset(fieldNo),
                                  tunit, elements, RecordTy);
 
@@ -1005,7 +1026,13 @@
 
   llvm::DIArray EltTypeArray = DBuilder.getOrCreateArray(Elts);
 
-  return DBuilder.createSubroutineType(Unit, EltTypeArray);
+  unsigned Flags = 0;
+  if (Func->getExtProtoInfo().RefQualifier == RQ_LValue)
+    Flags |= llvm::DIDescriptor::FlagLValueReference;
+  if (Func->getExtProtoInfo().RefQualifier == RQ_RValue)
+    Flags |= llvm::DIDescriptor::FlagRValueReference;
+
+  return DBuilder.createSubroutineType(Unit, EltTypeArray, Flags);
 }
 
 /// isFunctionLocalClass - Return true if CXXRecordDecl is defined
@@ -1084,6 +1111,10 @@
   }
   if (Method->hasPrototype())
     Flags |= llvm::DIDescriptor::FlagPrototyped;
+  if (Method->getRefQualifier() == RQ_LValue)
+    Flags |= llvm::DIDescriptor::FlagLValueReference;
+  if (Method->getRefQualifier() == RQ_RValue)
+    Flags |= llvm::DIDescriptor::FlagRValueReference;
 
   llvm::DIArray TParamsArray = CollectFunctionTemplateParams(Method, Unit);
   llvm::DISubprogram SP =
@@ -1092,7 +1123,7 @@
                           MethodTy, /*isLocalToUnit=*/false,
                           /* isDefinition=*/ false,
                           Virtuality, VIndex, ContainingType,
-                          Flags, CGM.getLangOpts().Optimize, NULL,
+                          Flags, CGM.getLangOpts().Optimize, nullptr,
                           TParamsArray);
 
   SPCache[Method->getCanonicalDecl()] = llvm::WeakVH(SP);
@@ -1111,9 +1142,8 @@
   // Since we want more than just the individual member decls if we
   // have templated functions iterate over every declaration to gather
   // the functions.
-  for(DeclContext::decl_iterator I = RD->decls_begin(),
-        E = RD->decls_end(); I != E; ++I) {
-    if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(*I)) {
+  for(const auto *I : RD->decls()) {
+    if (const auto *Method = dyn_cast<CXXMethodDecl>(I)) {
       // Reuse the existing member function declaration if it exists.
       // It may be associated with the declaration of the type & should be
       // reused as we're building the definition.
@@ -1130,16 +1160,13 @@
           EltTys.push_back(CreateCXXMemberFunction(Method, Unit, RecordTy));
       } else
         EltTys.push_back(MI->second);
-    } else if (const FunctionTemplateDecl *FTD =
-                   dyn_cast<FunctionTemplateDecl>(*I)) {
+    } else if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(I)) {
       // Add any template specializations that have already been seen. Like
       // implicit member functions, these may have been added to a declaration
       // in the case of vtable-based debug info reduction.
-      for (FunctionTemplateDecl::spec_iterator SI = FTD->spec_begin(),
-                                               SE = FTD->spec_end();
-           SI != SE; ++SI) {
+      for (const auto *SI : FTD->specializations()) {
         llvm::DenseMap<const FunctionDecl *, llvm::WeakVH>::iterator MI =
-            SPCache.find(cast<CXXMethodDecl>(*SI)->getCanonicalDecl());
+            SPCache.find(cast<CXXMethodDecl>(SI)->getCanonicalDecl());
         if (MI != SPCache.end())
           EltTys.push_back(MI->second);
       }
@@ -1156,15 +1183,14 @@
                 llvm::DIType RecordTy) {
 
   const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
-  for (CXXRecordDecl::base_class_const_iterator BI = RD->bases_begin(),
-         BE = RD->bases_end(); BI != BE; ++BI) {
+  for (const auto &BI : RD->bases()) {
     unsigned BFlags = 0;
     uint64_t BaseOffset;
 
     const CXXRecordDecl *Base =
-      cast<CXXRecordDecl>(BI->getType()->getAs<RecordType>()->getDecl());
+      cast<CXXRecordDecl>(BI.getType()->getAs<RecordType>()->getDecl());
 
-    if (BI->isVirtual()) {
+    if (BI.isVirtual()) {
       // virtual base offset offset is -ve. The code generator emits dwarf
       // expression where it expects +ve number.
       BaseOffset =
@@ -1176,7 +1202,7 @@
     // FIXME: Inconsistent units for BaseOffset. It is in bytes when
     // BI->isVirtual() and bits when not.
 
-    AccessSpecifier Access = BI->getAccessSpecifier();
+    AccessSpecifier Access = BI.getAccessSpecifier();
     if (Access == clang::AS_private)
       BFlags |= llvm::DIDescriptor::FlagPrivate;
     else if (Access == clang::AS_protected)
@@ -1184,7 +1210,7 @@
 
     llvm::DIType DTy =
       DBuilder.createInheritance(RecordTy,
-                                 getOrCreateType(BI->getType(), Unit),
+                                 getOrCreateType(BI.getType(), Unit),
                                  BaseOffset, BFlags);
     EltTys.push_back(DTy);
   }
@@ -1225,7 +1251,7 @@
                                                ->getTypeForDecl())
                        : CGM.getContext().getPointerType(D->getType());
       llvm::DIType TTy = getOrCreateType(T, Unit);
-      llvm::Value *V = 0;
+      llvm::Value *V = nullptr;
       // Variable pointer template parameters have a value that is the address
       // of the variable.
       if (const VarDecl *VD = dyn_cast<VarDecl>(D))
@@ -1239,7 +1265,7 @@
         V = CGM.GetAddrOfFunction(FD);
       // Member data pointers have special handling too to compute the fixed
       // offset within the object.
-      if (isa<FieldDecl>(D)) {
+      if (isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D)) {
         // These five lines (& possibly the above member function pointer
         // handling) might be able to be refactored to use similar code in
         // CodeGenModule::getMemberPointerConstant
@@ -1257,7 +1283,7 @@
     case TemplateArgument::NullPtr: {
       QualType T = TA.getNullPtrType();
       llvm::DIType TTy = getOrCreateType(T, Unit);
-      llvm::Value *V = 0;
+      llvm::Value *V = nullptr;
       // Special case member data pointer null values since they're actually -1
       // instead of zero.
       if (const MemberPointerType *MPT =
@@ -1287,7 +1313,7 @@
       llvm::DITemplateValueParameter TVP =
           DBuilder.createTemplateParameterPack(
               TheCU, Name, llvm::DIType(),
-              CollectTemplateParams(NULL, TA.getPackAsArray(), Unit));
+              CollectTemplateParams(nullptr, TA.getPackAsArray(), Unit));
       TemplateParams.push_back(TVP);
     } break;
     case TemplateArgument::Expression: {
@@ -1331,14 +1357,11 @@
 llvm::DIArray CGDebugInfo::
 CollectCXXTemplateParams(const ClassTemplateSpecializationDecl *TSpecial,
                          llvm::DIFile Unit) {
-  llvm::PointerUnion<ClassTemplateDecl *,
-                     ClassTemplatePartialSpecializationDecl *>
-    PU = TSpecial->getSpecializedTemplateOrPartial();
-
-  TemplateParameterList *TPList = PU.is<ClassTemplateDecl *>() ?
-    PU.get<ClassTemplateDecl *>()->getTemplateParameters() :
-    PU.get<ClassTemplatePartialSpecializationDecl *>()->getTemplateParameters();
-  const TemplateArgumentList &TAList = TSpecial->getTemplateInstantiationArgs();
+  // Always get the full list of parameters, not just the ones from
+  // the specialization.
+  TemplateParameterList *TPList =
+    TSpecial->getSpecializedTemplate()->getTemplateParameters();
+  const TemplateArgumentList &TAList = TSpecial->getTemplateArgs();
   return CollectTemplateParams(TPList, TAList.asArray(), Unit);
 }
 
@@ -1409,6 +1432,21 @@
   return T;
 }
 
+void CGDebugInfo::completeType(const EnumDecl *ED) {
+  if (DebugKind <= CodeGenOptions::DebugLineTablesOnly)
+    return;
+  QualType Ty = CGM.getContext().getEnumType(ED);
+  void* TyPtr = Ty.getAsOpaquePtr();
+  auto I = TypeCache.find(TyPtr);
+  if (I == TypeCache.end() ||
+      !llvm::DIType(cast<llvm::MDNode>(static_cast<llvm::Value *>(I->second)))
+           .isForwardDecl())
+    return;
+  llvm::DIType Res = CreateTypeDefinition(Ty->castAs<EnumType>());
+  assert(!Res.isForwardDecl());
+  TypeCache[TyPtr] = Res;
+}
+
 void CGDebugInfo::completeType(const RecordDecl *RD) {
   if (DebugKind > CodeGenOptions::LimitedDebugInfo ||
       !CGM.getLangOpts().CPlusPlus)
@@ -1416,6 +1454,9 @@
 }
 
 void CGDebugInfo::completeRequiredType(const RecordDecl *RD) {
+  if (DebugKind <= CodeGenOptions::DebugLineTablesOnly)
+    return;
+
   if (const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD))
     if (CXXDecl->isDynamicClass())
       return;
@@ -1431,40 +1472,67 @@
     return;
   QualType Ty = CGM.getContext().getRecordType(RD);
   void* TyPtr = Ty.getAsOpaquePtr();
-  if (CompletedTypeCache.count(TyPtr))
+  auto I = TypeCache.find(TyPtr);
+  if (I != TypeCache.end() &&
+      !llvm::DIType(cast<llvm::MDNode>(static_cast<llvm::Value *>(I->second)))
+           .isForwardDecl())
     return;
   llvm::DIType Res = CreateTypeDefinition(Ty->castAs<RecordType>());
   assert(!Res.isForwardDecl());
-  CompletedTypeCache[TyPtr] = Res;
   TypeCache[TyPtr] = Res;
 }
 
+static bool hasExplicitMemberDefinition(CXXRecordDecl::method_iterator I,
+                                        CXXRecordDecl::method_iterator End) {
+  for (; I != End; ++I)
+    if (FunctionDecl *Tmpl = I->getInstantiatedFromMemberFunction())
+      if (!Tmpl->isImplicit() && Tmpl->isThisDeclarationADefinition() &&
+          !I->getMemberSpecializationInfo()->isExplicitSpecialization())
+        return true;
+  return false;
+}
+
+static bool shouldOmitDefinition(CodeGenOptions::DebugInfoKind DebugKind,
+                                 const RecordDecl *RD,
+                                 const LangOptions &LangOpts) {
+  if (DebugKind > CodeGenOptions::LimitedDebugInfo)
+    return false;
+
+  if (!LangOpts.CPlusPlus)
+    return false;
+
+  if (!RD->isCompleteDefinitionRequired())
+    return true;
+
+  const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
+
+  if (!CXXDecl)
+    return false;
+
+  if (CXXDecl->hasDefinition() && CXXDecl->isDynamicClass())
+    return true;
+
+  TemplateSpecializationKind Spec = TSK_Undeclared;
+  if (const ClassTemplateSpecializationDecl *SD =
+          dyn_cast<ClassTemplateSpecializationDecl>(RD))
+    Spec = SD->getSpecializationKind();
+
+  if (Spec == TSK_ExplicitInstantiationDeclaration &&
+      hasExplicitMemberDefinition(CXXDecl->method_begin(),
+                                  CXXDecl->method_end()))
+    return true;
+
+  return false;
+}
+
 /// CreateType - get structure or union type.
 llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty) {
   RecordDecl *RD = Ty->getDecl();
-  const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
-  // Always emit declarations for types that aren't required to be complete when
-  // in limit-debug-info mode. If the type is later found to be required to be
-  // complete this declaration will be upgraded to a definition by
-  // `completeRequiredType`.
-  // If the type is dynamic, only emit the definition in TUs that require class
-  // data. This is handled by `completeClassData`.
   llvm::DICompositeType T(getTypeOrNull(QualType(Ty, 0)));
-  // If we've already emitted the type, just use that, even if it's only a
-  // declaration. The completeType, completeRequiredType, and completeClassData
-  // callbacks will handle promoting the declaration to a definition.
-  if (T ||
-      (DebugKind <= CodeGenOptions::LimitedDebugInfo &&
-       // Under -flimit-debug-info, emit only a declaration unless the type is
-       // required to be complete.
-       !RD->isCompleteDefinitionRequired() && CGM.getLangOpts().CPlusPlus) ||
-      // If the class is dynamic, only emit a declaration. A definition will be
-      // emitted whenever the vtable is emitted.
-      (CXXDecl && CXXDecl->hasDefinition() && CXXDecl->isDynamicClass()) || T) {
-    llvm::DIDescriptor FDContext =
-      getContextDescriptor(cast<Decl>(RD->getDeclContext()));
+  if (T || shouldOmitDefinition(DebugKind, RD, CGM.getLangOpts())) {
     if (!T)
-      T = getOrCreateRecordFwdDecl(Ty, FDContext);
+      T = getOrCreateRecordFwdDecl(
+          Ty, getContextDescriptor(cast<Decl>(RD->getDeclContext())));
     return T;
   }
 
@@ -1498,9 +1566,6 @@
   LexicalBlockStack.push_back(&*FwdDecl);
   RegionMap[Ty->getDecl()] = llvm::WeakVH(FwdDecl);
 
-  // Add this to the completed-type cache while we're completing it recursively.
-  CompletedTypeCache[QualType(Ty, 0).getAsOpaquePtr()] = FwdDecl;
-
   // Convert all the elements.
   SmallVector<llvm::Value *, 16> EltTys;
   // what about nested types?
@@ -1572,20 +1637,28 @@
   // Get overall information about the record type for the debug info.
   llvm::DIFile DefUnit = getOrCreateFile(ID->getLocation());
   unsigned Line = getLineNumber(ID->getLocation());
-  unsigned RuntimeLang = TheCU.getLanguage();
+  llvm::dwarf::SourceLanguage RuntimeLang = TheCU.getLanguage();
 
   // If this is just a forward declaration return a special forward-declaration
   // debug type since we won't be able to lay out the entire type.
   ObjCInterfaceDecl *Def = ID->getDefinition();
-  if (!Def) {
-    llvm::DIType FwdDecl =
-      DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
-                                 ID->getName(), TheCU, DefUnit, Line,
-                                 RuntimeLang);
+  if (!Def || !Def->getImplementation()) {
+    llvm::DIType FwdDecl = DBuilder.createReplaceableForwardDecl(
+        llvm::dwarf::DW_TAG_structure_type, ID->getName(), TheCU, DefUnit, Line,
+        RuntimeLang);
+    ObjCInterfaceCache.push_back(ObjCInterfaceCacheEntry(Ty, FwdDecl, Unit));
     return FwdDecl;
   }
 
-  ID = Def;
+
+  return CreateTypeDefinition(Ty, Unit);
+}
+
+llvm::DIType CGDebugInfo::CreateTypeDefinition(const ObjCInterfaceType *Ty, llvm::DIFile Unit) {
+  ObjCInterfaceDecl *ID = Ty->getDecl();
+  llvm::DIFile DefUnit = getOrCreateFile(ID->getLocation());
+  unsigned Line = getLineNumber(ID->getLocation());
+  unsigned RuntimeLang = TheCU.getLanguage();
 
   // Bit size, align and offset of the type.
   uint64_t Size = CGM.getContext().getTypeSize(Ty);
@@ -1600,10 +1673,8 @@
                               Line, Size, Align, Flags,
                               llvm::DIType(), llvm::DIArray(), RuntimeLang);
 
-  // Otherwise, insert it into the CompletedTypeCache so that recursive uses
-  // will find it and we're emitting the complete type.
-  QualType QualTy = QualType(Ty, 0);
-  CompletedTypeCache[QualTy.getAsOpaquePtr()] = RealDecl;
+  QualType QTy(Ty, 0);
+  TypeCache[QTy.getAsOpaquePtr()] = RealDecl;
 
   // Push the struct on region stack.
   LexicalBlockStack.push_back(static_cast<llvm::MDNode*>(RealDecl));
@@ -1625,9 +1696,7 @@
   }
 
   // Create entries for all of the properties.
-  for (ObjCContainerDecl::prop_iterator I = ID->prop_begin(),
-         E = ID->prop_end(); I != E; ++I) {
-    const ObjCPropertyDecl *PD = *I;
+  for (const auto *PD : ID->properties()) {
     SourceLocation Loc = PD->getLocation();
     llvm::DIFile PUnit = getOrCreateFile(Loc);
     unsigned PLine = getLineNumber(Loc);
@@ -1697,7 +1766,7 @@
     else if (Field->getAccessControl() == ObjCIvarDecl::Private)
       Flags = llvm::DIDescriptor::FlagPrivate;
 
-    llvm::MDNode *PropertyNode = NULL;
+    llvm::MDNode *PropertyNode = nullptr;
     if (ObjCImplementationDecl *ImpD = ID->getImplementation()) {
       if (ObjCPropertyImplDecl *PImpD =
           ImpD->FindPropertyImplIvarDecl(Field->getIdentifier())) {
@@ -1729,12 +1798,6 @@
   llvm::DIArray Elements = DBuilder.getOrCreateArray(EltTys);
   RealDecl.setTypeArray(Elements);
 
-  // If the implementation is not yet set, we do not want to mark it
-  // as complete. An implementation may declare additional
-  // private ivars that we would miss otherwise.
-  if (ID->getImplementation() == 0)
-    CompletedTypeCache.erase(QualTy.getAsOpaquePtr());
-
   LexicalBlockStack.pop_back();
   return RealDecl;
 }
@@ -1829,11 +1892,13 @@
   if (!Ty->getPointeeType()->isFunctionType())
     return DBuilder.createMemberPointerType(
         getOrCreateType(Ty->getPointeeType(), U), ClassType);
+
+  const FunctionProtoType *FPT =
+    Ty->getPointeeType()->getAs<FunctionProtoType>();
   return DBuilder.createMemberPointerType(getOrCreateInstanceMethodType(
-      CGM.getContext().getPointerType(
-          QualType(Ty->getClass(), Ty->getPointeeType().getCVRQualifiers())),
-      Ty->getPointeeType()->getAs<FunctionProtoType>(), U),
-                                          ClassType);
+      CGM.getContext().getPointerType(QualType(Ty->getClass(),
+                                               FPT->getTypeQuals())),
+      FPT, U), ClassType);
 }
 
 llvm::DIType CGDebugInfo::CreateType(const AtomicType *Ty,
@@ -1863,17 +1928,31 @@
     llvm::DIFile DefUnit = getOrCreateFile(ED->getLocation());
     unsigned Line = getLineNumber(ED->getLocation());
     StringRef EDName = ED->getName();
-    return DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_enumeration_type,
-                                      EDName, EDContext, DefUnit, Line, 0,
-                                      Size, Align, FullName);
+    llvm::DIType RetTy = DBuilder.createReplaceableForwardDecl(
+        llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit, Line,
+        0, Size, Align, FullName);
+    ReplaceMap.push_back(std::make_pair(Ty, static_cast<llvm::Value *>(RetTy)));
+    return RetTy;
   }
 
+  return CreateTypeDefinition(Ty);
+}
+
+llvm::DIType CGDebugInfo::CreateTypeDefinition(const EnumType *Ty) {
+  const EnumDecl *ED = Ty->getDecl();
+  uint64_t Size = 0;
+  uint64_t Align = 0;
+  if (!ED->getTypeForDecl()->isIncompleteType()) {
+    Size = CGM.getContext().getTypeSize(ED->getTypeForDecl());
+    Align = CGM.getContext().getTypeAlign(ED->getTypeForDecl());
+  }
+
+  SmallString<256> FullName = getUniqueTagTypeName(Ty, CGM, TheCU);
+
   // Create DIEnumerator elements for each enumerator.
   SmallVector<llvm::Value *, 16> Enumerators;
   ED = ED->getDefinition();
-  for (EnumDecl::enumerator_iterator
-         Enum = ED->enumerator_begin(), EnumEnd = ED->enumerator_end();
-       Enum != EnumEnd; ++Enum) {
+  for (const auto *Enum : ED->enumerators()) {
     Enumerators.push_back(
       DBuilder.createEnumerator(Enum->getName(),
                                 Enum->getInitVal().getSExtValue()));
@@ -1907,9 +1986,12 @@
     switch (T->getTypeClass()) {
     default:
       return C.getQualifiedType(T.getTypePtr(), Quals);
-    case Type::TemplateSpecialization:
-      T = cast<TemplateSpecializationType>(T)->desugar();
-      break;
+    case Type::TemplateSpecialization: {
+      const auto *Spec = cast<TemplateSpecializationType>(T);
+      if (Spec->isTypeAlias())
+        return C.getQualifiedType(T.getTypePtr(), Quals);
+      T = Spec->desugar();
+      break; }
     case Type::TypeOfExpr:
       T = cast<TypeOfExprType>(T)->getUnderlyingExpr()->getType();
       break;
@@ -1954,16 +2036,7 @@
   // Unwrap the type as needed for debug information.
   Ty = UnwrapTypeForDebugInfo(Ty, CGM.getContext());
 
-  // Check for existing entry.
-  if (Ty->getTypeClass() == Type::ObjCInterface) {
-    llvm::Value *V = getCachedInterfaceTypeOrNull(Ty);
-    if (V)
-      return llvm::DIType(cast<llvm::MDNode>(V));
-    else return llvm::DIType();
-  }
-
-  llvm::DenseMap<void *, llvm::WeakVH>::iterator it =
-    TypeCache.find(Ty.getAsOpaquePtr());
+  auto it = TypeCache.find(Ty.getAsOpaquePtr());
   if (it != TypeCache.end()) {
     // Verify that the debug info still exists.
     if (llvm::Value *V = it->second)
@@ -1973,41 +2046,15 @@
   return llvm::DIType();
 }
 
-/// getCompletedTypeOrNull - Get the type from the cache or return null if it
-/// doesn't exist.
-llvm::DIType CGDebugInfo::getCompletedTypeOrNull(QualType Ty) {
+void CGDebugInfo::completeTemplateDefinition(
+    const ClassTemplateSpecializationDecl &SD) {
+  if (DebugKind <= CodeGenOptions::DebugLineTablesOnly)
+    return;
 
-  // Unwrap the type as needed for debug information.
-  Ty = UnwrapTypeForDebugInfo(Ty, CGM.getContext());
-
-  // Check for existing entry.
-  llvm::Value *V = 0;
-  llvm::DenseMap<void *, llvm::WeakVH>::iterator it =
-    CompletedTypeCache.find(Ty.getAsOpaquePtr());
-  if (it != CompletedTypeCache.end())
-    V = it->second;
-  else {
-    V = getCachedInterfaceTypeOrNull(Ty);
-  }
-
-  // Verify that any cached debug info still exists.
-  return llvm::DIType(cast_or_null<llvm::MDNode>(V));
-}
-
-/// getCachedInterfaceTypeOrNull - Get the type from the interface
-/// cache, unless it needs to regenerated. Otherwise return null.
-llvm::Value *CGDebugInfo::getCachedInterfaceTypeOrNull(QualType Ty) {
-  // Is there a cached interface that hasn't changed?
-  llvm::DenseMap<void *, std::pair<llvm::WeakVH, unsigned > >
-    ::iterator it1 = ObjCInterfaceCache.find(Ty.getAsOpaquePtr());
-
-  if (it1 != ObjCInterfaceCache.end())
-    if (ObjCInterfaceDecl* Decl = getObjCInterfaceDecl(Ty))
-      if (Checksum(Decl) == it1->second.second)
-        // Return cached forward declaration.
-        return it1->second.first;
-
-  return 0;
+  completeClassData(&SD);
+  // In case this type has no member function definitions being emitted, ensure
+  // it is retained
+  RetainedTypes.push_back(CGM.getContext().getRecordType(&SD).getAsOpaquePtr());
 }
 
 /// getOrCreateType - Get the type from the cache or create a new
@@ -2019,7 +2066,7 @@
   // Unwrap the type as needed for debug information.
   Ty = UnwrapTypeForDebugInfo(Ty, CGM.getContext());
 
-  if (llvm::DIType T = getCompletedTypeOrNull(Ty))
+  if (llvm::DIType T = getTypeOrNull(Ty))
     return T;
 
   // Otherwise create the type.
@@ -2029,39 +2076,6 @@
   // And update the type cache.
   TypeCache[TyPtr] = Res;
 
-  // FIXME: this getTypeOrNull call seems silly when we just inserted the type
-  // into the cache - but getTypeOrNull has a special case for cached interface
-  // types. We should probably just pull that out as a special case for the
-  // "else" block below & skip the otherwise needless lookup.
-  llvm::DIType TC = getTypeOrNull(Ty);
-  if (TC && TC.isForwardDecl())
-    ReplaceMap.push_back(std::make_pair(TyPtr, static_cast<llvm::Value*>(TC)));
-  else if (ObjCInterfaceDecl* Decl = getObjCInterfaceDecl(Ty)) {
-    // Interface types may have elements added to them by a
-    // subsequent implementation or extension, so we keep them in
-    // the ObjCInterfaceCache together with a checksum. Instead of
-    // the (possibly) incomplete interface type, we return a forward
-    // declaration that gets RAUW'd in CGDebugInfo::finalize().
-    std::pair<llvm::WeakVH, unsigned> &V = ObjCInterfaceCache[TyPtr];
-    if (V.first)
-      return llvm::DIType(cast<llvm::MDNode>(V.first));
-    TC = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
-                                    Decl->getName(), TheCU, Unit,
-                                    getLineNumber(Decl->getLocation()),
-                                    TheCU.getLanguage());
-    // Store the forward declaration in the cache.
-    V.first = TC;
-    V.second = Checksum(Decl);
-
-    // Register the type for replacement in finalize().
-    ReplaceMap.push_back(std::make_pair(TyPtr, static_cast<llvm::Value*>(TC)));
-
-    return TC;
-  }
-
-  if (!Res.isForwardDecl())
-    CompletedTypeCache[TyPtr] = Res;
-
   return Res;
 }
 
@@ -2073,7 +2087,7 @@
   // a checksum.
   unsigned Sum = 0;
   for (const ObjCIvarDecl *Ivar = ID->all_declared_ivar_begin();
-       Ivar != 0; Ivar = Ivar->getNextIvar())
+       Ivar != nullptr; Ivar = Ivar->getNextIvar())
     ++Sum;
 
   return Sum;
@@ -2087,7 +2101,7 @@
   case Type::ObjCInterface:
     return cast<ObjCInterfaceType>(Ty)->getDecl();
   default:
-    return 0;
+    return nullptr;
   }
 }
 
@@ -2097,7 +2111,7 @@
   if (Ty.hasLocalQualifiers())
     return CreateQualifiedType(Ty, Unit);
 
-  const char *Diag = 0;
+  const char *Diag = nullptr;
 
   // Work out details of type.
   switch (Ty->getTypeClass()) {
@@ -2123,10 +2137,11 @@
     return CreateType(cast<ComplexType>(Ty));
   case Type::Pointer:
     return CreateType(cast<PointerType>(Ty), Unit);
+  case Type::Adjusted:
   case Type::Decayed:
-    // Decayed types are just pointers in LLVM and DWARF.
+    // Decayed and adjusted types use the adjusted type in LLVM and DWARF.
     return CreateType(
-        cast<PointerType>(cast<DecayedType>(Ty)->getDecayedType()), Unit);
+        cast<PointerType>(cast<AdjustedType>(Ty)->getAdjustedType()), Unit);
   case Type::BlockPointer:
     return CreateType(cast<BlockPointerType>(Ty), Unit);
   case Type::Typedef:
@@ -2154,8 +2169,10 @@
   case Type::Atomic:
     return CreateType(cast<AtomicType>(Ty), Unit);
 
-  case Type::Attributed:
   case Type::TemplateSpecialization:
+    return CreateType(cast<TemplateSpecializationType>(Ty), Unit);
+
+  case Type::Attributed:
   case Type::Elaborated:
   case Type::Paren:
   case Type::SubstTemplateTypeParm:
@@ -2199,10 +2216,6 @@
   // correct order if the full type is needed.
   Res.setTypeArray(T.getTypeArray());
 
-  if (T && T.isForwardDecl())
-    ReplaceMap.push_back(
-        std::make_pair(QTy.getAsOpaquePtr(), static_cast<llvm::Value *>(T)));
-
   // And update the type cache.
   TypeCache[QTy.getAsOpaquePtr()] = Res;
   return Res;
@@ -2222,20 +2235,14 @@
 
   // If we ended up creating the type during the context chain construction,
   // just return that.
-  // FIXME: this could be dealt with better if the type was recorded as
-  // completed before we started this (see the CompletedTypeCache usage in
-  // CGDebugInfo::CreateTypeDefinition(const RecordType*) - that would need to
-  // be pushed to before context creation, but after it was known to be
-  // destined for completion (might still have an issue if this caller only
-  // required a declaration but the context construction ended up creating a
-  // definition)
   llvm::DICompositeType T(getTypeOrNull(CGM.getContext().getRecordType(RD)));
   if (T && (!T.isForwardDecl() || !RD->getDefinition()))
       return T;
 
-  // If this is just a forward declaration, construct an appropriately
-  // marked node and just return it.
-  if (!RD->getDefinition())
+  // If this is just a forward or incomplete declaration, construct an
+  // appropriately marked node and just return it.
+  const RecordDecl *D = RD->getDefinition();
+  if (!D || !D->isCompleteDefinition())
     return getOrCreateRecordFwdDecl(Ty, RDContext);
 
   uint64_t Size = CGM.getContext().getTypeSize(Ty);
@@ -2277,7 +2284,7 @@
   llvm::DICompositeType ContainingType;
   const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
   if (const CXXRecordDecl *PBase = RL.getPrimaryBase()) {
-    // Seek non virtual primary base root.
+    // Seek non-virtual primary base root.
     while (1) {
       const ASTRecordLayout &BRL = CGM.getContext().getASTRecordLayout(PBase);
       const CXXRecordDecl *PBT = BRL.getPrimaryBase();
@@ -2309,7 +2316,7 @@
   return Ty;
 }
 
-llvm::DIDescriptor CGDebugInfo::getDeclarationOrDefinition(const Decl *D) {
+llvm::DIScope CGDebugInfo::getDeclarationOrDefinition(const Decl *D) {
   // We only need a declaration (not a definition) of the type - so use whatever
   // we would otherwise do to get a type for a pointee. (forward declarations in
   // limited debug info, full definitions (if the type definition is available)
@@ -2327,15 +2334,15 @@
   llvm::DenseMap<const Decl *, llvm::WeakVH>::iterator I =
       DeclCache.find(D->getCanonicalDecl());
   if (I == DeclCache.end())
-    return llvm::DIDescriptor();
+    return llvm::DIScope();
   llvm::Value *V = I->second;
-  return llvm::DIDescriptor(dyn_cast_or_null<llvm::MDNode>(V));
+  return llvm::DIScope(dyn_cast_or_null<llvm::MDNode>(V));
 }
 
 /// getFunctionDeclaration - Return debug info descriptor to describe method
 /// declaration for the given method definition.
 llvm::DISubprogram CGDebugInfo::getFunctionDeclaration(const Decl *D) {
-  if (!D || DebugKind == CodeGenOptions::DebugLineTablesOnly)
+  if (!D || DebugKind <= CodeGenOptions::DebugLineTablesOnly)
     return llvm::DISubprogram();
 
   const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
@@ -2352,7 +2359,6 @@
       llvm::DICompositeType T(S);
       llvm::DISubprogram SP =
           CreateCXXMemberFunction(MD, getOrCreateFile(MD->getLocation()), T);
-      T.addMember(SP);
       return SP;
     }
   }
@@ -2363,9 +2369,7 @@
       return SP;
   }
 
-  for (FunctionDecl::redecl_iterator I = FD->redecls_begin(),
-         E = FD->redecls_end(); I != E; ++I) {
-    const FunctionDecl *NextFD = *I;
+  for (auto NextFD : FD->redecls()) {
     llvm::DenseMap<const FunctionDecl *, llvm::WeakVH>::iterator
       MI = SPCache.find(NextFD->getCanonicalDecl());
     if (MI != SPCache.end()) {
@@ -2383,7 +2387,7 @@
 llvm::DICompositeType CGDebugInfo::getOrCreateFunctionType(const Decl *D,
                                                            QualType FnType,
                                                            llvm::DIFile F) {
-  if (!D || DebugKind == CodeGenOptions::DebugLineTablesOnly)
+  if (!D || DebugKind <= CodeGenOptions::DebugLineTablesOnly)
     // Create fake but valid subroutine type. Otherwise
     // llvm::DISubprogram::Verify() would return false, and
     // subprogram DIE will miss DW_AT_decl_file and
@@ -2397,7 +2401,7 @@
     SmallVector<llvm::Value *, 16> Elts;
 
     // First element is always return type. For 'void' functions it is NULL.
-    QualType ResultTy = OMethod->getResultType();
+    QualType ResultTy = OMethod->getReturnType();
 
     // Replace the instancetype keyword with the actual type.
     if (ResultTy == CGM.getContext().getObjCInstanceType())
@@ -2413,18 +2417,35 @@
     llvm::DIType CmdTy = getOrCreateType(OMethod->getCmdDecl()->getType(), F);
     Elts.push_back(DBuilder.createArtificialType(CmdTy));
     // Get rest of the arguments.
-    for (ObjCMethodDecl::param_const_iterator PI = OMethod->param_begin(),
-           PE = OMethod->param_end(); PI != PE; ++PI)
-      Elts.push_back(getOrCreateType((*PI)->getType(), F));
+    for (const auto *PI : OMethod->params())
+      Elts.push_back(getOrCreateType(PI->getType(), F));
 
     llvm::DIArray EltTypeArray = DBuilder.getOrCreateArray(Elts);
     return DBuilder.createSubroutineType(F, EltTypeArray);
   }
+
+  // Handle variadic function types; they need an additional
+  // unspecified parameter.
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+    if (FD->isVariadic()) {
+      SmallVector<llvm::Value *, 16> EltTys;
+      EltTys.push_back(getOrCreateType(FD->getReturnType(), F));
+      if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FnType))
+        for (unsigned i = 0, e = FPT->getNumParams(); i != e; ++i)
+          EltTys.push_back(getOrCreateType(FPT->getParamType(i), F));
+      EltTys.push_back(DBuilder.createUnspecifiedParameter());
+      llvm::DIArray EltTypeArray = DBuilder.getOrCreateArray(EltTys);
+      return DBuilder.createSubroutineType(F, EltTypeArray);
+    }
+
   return llvm::DICompositeType(getOrCreateType(FnType, F));
 }
 
 /// EmitFunctionStart - Constructs the debug code for entering a function.
-void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType,
+void CGDebugInfo::EmitFunctionStart(GlobalDecl GD,
+                                    SourceLocation Loc,
+                                    SourceLocation ScopeLoc,
+                                    QualType FnType,
                                     llvm::Function *Fn,
                                     CGBuilderTy &Builder) {
 
@@ -2434,13 +2455,7 @@
   FnBeginRegionCount.push_back(LexicalBlockStack.size());
 
   const Decl *D = GD.getDecl();
-  // Function may lack declaration in source code if it is created by Clang
-  // CodeGen (examples: _GLOBAL__I_a, __cxx_global_array_dtor, thunk).
-  bool HasDecl = (D != 0);
-  // Use the location of the declaration.
-  SourceLocation Loc;
-  if (HasDecl)
-    Loc = D->getLocation();
+  bool HasDecl = (D != nullptr);
 
   unsigned Flags = 0;
   llvm::DIFile Unit = getOrCreateFile(Loc);
@@ -2500,23 +2515,34 @@
   if (!Name.empty() && Name[0] == '\01')
     Name = Name.substr(1);
 
-  unsigned LineNo = getLineNumber(Loc);
-  if (!HasDecl || D->isImplicit())
+  if (!HasDecl || D->isImplicit()) {
     Flags |= llvm::DIDescriptor::FlagArtificial;
+    // Artificial functions without a location should not silently reuse CurLoc.
+    if (Loc.isInvalid())
+      CurLoc = SourceLocation();
+  }
+  unsigned LineNo = getLineNumber(Loc);
+  unsigned ScopeLine = getLineNumber(ScopeLoc);
 
+  // FIXME: The function declaration we're constructing here is mostly reusing
+  // declarations from CXXMethodDecl and not constructing new ones for arbitrary
+  // FunctionDecls. When/if we fix this we can have FDContext be TheCU/null for
+  // all subprograms instead of the actual context since subprogram definitions
+  // are emitted as CU level entities by the backend.
   llvm::DISubprogram SP =
       DBuilder.createFunction(FDContext, Name, LinkageName, Unit, LineNo,
                               getOrCreateFunctionType(D, FnType, Unit),
                               Fn->hasInternalLinkage(), true /*definition*/,
-                              getLineNumber(CurLoc), Flags,
+                              ScopeLine, Flags,
                               CGM.getLangOpts().Optimize, Fn, TParamsArray,
                               getFunctionDeclaration(D));
   if (HasDecl)
     DeclCache.insert(std::make_pair(D->getCanonicalDecl(), llvm::WeakVH(SP)));
 
-  // Push function on region stack.
+  // Push the function onto the lexical block stack.
   llvm::MDNode *SPN = SP;
   LexicalBlockStack.push_back(SPN);
+
   if (HasDecl)
     RegionMap[D] = llvm::WeakVH(SP);
 }
@@ -2554,13 +2580,11 @@
 /// CreateLexicalBlock - Creates a new lexical block node and pushes it on
 /// the stack.
 void CGDebugInfo::CreateLexicalBlock(SourceLocation Loc) {
-  llvm::DIDescriptor D =
-    DBuilder.createLexicalBlock(LexicalBlockStack.empty() ?
-                                llvm::DIDescriptor() :
-                                llvm::DIDescriptor(LexicalBlockStack.back()),
-                                getOrCreateFile(CurLoc),
-                                getLineNumber(CurLoc),
-                                getColumnNumber(CurLoc));
+  llvm::DIDescriptor D = DBuilder.createLexicalBlock(
+      llvm::DIDescriptor(LexicalBlockStack.empty() ? nullptr
+                                                   : LexicalBlockStack.back()),
+      getOrCreateFile(CurLoc), getLineNumber(CurLoc), getColumnNumber(CurLoc),
+      0);
   llvm::MDNode *DN = D;
   LexicalBlockStack.push_back(DN);
 }
@@ -2664,7 +2688,7 @@
   }
 
   FType = Type;
-  llvm::DIType FieldTy = CGDebugInfo::getOrCreateType(FType, Unit);
+  llvm::DIType FieldTy = getOrCreateType(FType, Unit);
   FieldSize = CGM.getContext().getTypeSize(FType);
   FieldAlign = CGM.getContext().toBits(Align);
 
@@ -2684,7 +2708,7 @@
 }
 
 /// EmitDeclare - Emit local variable declaration debug info.
-void CGDebugInfo::EmitDeclare(const VarDecl *VD, unsigned Tag,
+void CGDebugInfo::EmitDeclare(const VarDecl *VD, llvm::dwarf::LLVMConstants Tag,
                               llvm::Value *Storage,
                               unsigned ArgNo, CGBuilderTy &Builder) {
   assert(DebugKind >= CodeGenOptions::LimitedDebugInfo);
@@ -2768,10 +2792,7 @@
     // all union fields.
     const RecordDecl *RD = cast<RecordDecl>(RT->getDecl());
     if (RD->isUnion() && RD->isAnonymousStructOrUnion()) {
-      for (RecordDecl::field_iterator I = RD->field_begin(),
-             E = RD->field_end();
-           I != E; ++I) {
-        FieldDecl *Field = *I;
+      for (const auto *Field : RD->fields()) {
         llvm::DIType FieldTy = getOrCreateType(Field->getType(), Unit);
         StringRef FieldName = Field->getName();
 
@@ -2824,7 +2845,6 @@
                                          llvm::DIType Ty) {
   llvm::DIType CachedTy = getTypeOrNull(QualTy);
   if (CachedTy) Ty = CachedTy;
-  else DEBUG(llvm::dbgs() << "No cached type for self.");
   return DBuilder.createObjectPointerType(Ty);
 }
 
@@ -2835,7 +2855,7 @@
   assert(DebugKind >= CodeGenOptions::LimitedDebugInfo);
   assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!");
 
-  if (Builder.GetInsertBlock() == 0)
+  if (Builder.GetInsertBlock() == nullptr)
     return;
 
   bool isByRef = VD->hasAttr<BlocksAttr>();
@@ -2965,15 +2985,12 @@
     BlockLayoutChunk chunk;
     chunk.OffsetInBits =
       blockLayout->getElementOffsetInBits(block.CXXThisIndex);
-    chunk.Capture = 0;
+    chunk.Capture = nullptr;
     chunks.push_back(chunk);
   }
 
   // Variable captures.
-  for (BlockDecl::capture_const_iterator
-         i = blockDecl->capture_begin(), e = blockDecl->capture_end();
-       i != e; ++i) {
-    const BlockDecl::Capture &capture = *i;
+  for (const auto &capture : blockDecl->captures()) {
     const VarDecl *variable = capture.getVariable();
     const CGBlockInfo::Capture &captureInfo = block.getCapture(variable);
 
@@ -3085,10 +3102,40 @@
   llvm::DICompositeType Ctxt(
       getContextDescriptor(cast<Decl>(D->getDeclContext())));
   llvm::DIDerivedType T = CreateRecordStaticField(D, Ctxt);
-  Ctxt.addMember(T);
   return T;
 }
 
+/// 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
+CGDebugInfo::CollectAnonRecordDecls(const RecordDecl *RD, llvm::DIFile Unit,
+                                    unsigned LineNo, StringRef LinkageName,
+                                    llvm::GlobalVariable *Var,
+                                    llvm::DIDescriptor DContext) {
+  llvm::DIGlobalVariable GV;
+
+  for (const auto *Field : RD->fields()) {
+    llvm::DIType FieldTy = getOrCreateType(Field->getType(), Unit);
+    StringRef FieldName = Field->getName();
+
+    // Ignore unnamed fields, but recurse into anonymous records.
+    if (FieldName.empty()) {
+      const RecordType *RT = dyn_cast<RecordType>(Field->getType());
+      if (RT)
+        GV = CollectAnonRecordDecls(RT->getDecl(), Unit, LineNo, LinkageName,
+                                    Var, DContext);
+      continue;
+    }
+    // Use VarDecl's Tag, Scope and Line number.
+    GV = DBuilder.createStaticVariable(DContext, FieldName, LinkageName, Unit,
+                                       LineNo, FieldTy,
+                                       Var->hasInternalLinkage(), Var,
+                                       llvm::DIDerivedType());
+  }
+  return GV;
+}
+
 /// EmitGlobalVariable - Emit information about a global variable.
 void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
                                      const VarDecl *D) {
@@ -3109,46 +3156,36 @@
     T = CGM.getContext().getConstantArrayType(ET, ConstVal,
                                               ArrayType::Normal, 0);
   }
+
   StringRef DeclName = D->getName();
   StringRef LinkageName;
-  if (D->getDeclContext() && !isa<FunctionDecl>(D->getDeclContext())
-      && !isa<ObjCMethodDecl>(D->getDeclContext()))
+  if (D->getDeclContext() && !isa<FunctionDecl>(D->getDeclContext()) &&
+      !isa<ObjCMethodDecl>(D->getDeclContext()))
     LinkageName = Var->getName();
   if (LinkageName == DeclName)
     LinkageName = StringRef();
+
   llvm::DIDescriptor DContext =
     getContextDescriptor(dyn_cast<Decl>(D->getDeclContext()));
-  llvm::DIGlobalVariable GV = DBuilder.createStaticVariable(
-      DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(T, Unit),
-      Var->hasInternalLinkage(), Var,
-      getOrCreateStaticDataMemberDeclarationOrNull(D));
-  DeclCache.insert(std::make_pair(D->getCanonicalDecl(), llvm::WeakVH(GV)));
-}
 
-/// EmitGlobalVariable - Emit information about an objective-c interface.
-void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
-                                     ObjCInterfaceDecl *ID) {
-  assert(DebugKind >= CodeGenOptions::LimitedDebugInfo);
-  // Create global variable debug descriptor.
-  llvm::DIFile Unit = getOrCreateFile(ID->getLocation());
-  unsigned LineNo = getLineNumber(ID->getLocation());
+  // Attempt to store one global variable for the declaration - even if we
+  // emit a lot of fields.
+  llvm::DIGlobalVariable GV;
 
-  StringRef Name = ID->getName();
-
-  QualType T = CGM.getContext().getObjCInterfaceType(ID);
-  if (T->isIncompleteArrayType()) {
-
-    // CodeGen turns int[] into int[1] so we'll do the same here.
-    llvm::APInt ConstVal(32, 1);
-    QualType ET = CGM.getContext().getAsArrayType(T)->getElementType();
-
-    T = CGM.getContext().getConstantArrayType(ET, ConstVal,
-                                           ArrayType::Normal, 0);
+  // 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
+  // to find the name of any field in the union.
+  if (T->isUnionType() && DeclName.empty()) {
+    const RecordDecl *RD = cast<RecordType>(T)->getDecl();
+    assert(RD->isAnonymousStructOrUnion() && "unnamed non-anonymous struct or union?");
+    GV = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
+  } else {
+      GV = DBuilder.createStaticVariable(
+        DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(T, Unit),
+        Var->hasInternalLinkage(), Var,
+        getOrCreateStaticDataMemberDeclarationOrNull(D));
   }
-
-  DBuilder.createGlobalVariable(Name, Unit, LineNo,
-                                getOrCreateType(T, Unit),
-                                Var->hasInternalLinkage(), Var);
+  DeclCache.insert(std::make_pair(D->getCanonicalDecl(), llvm::WeakVH(GV)));
 }
 
 /// EmitGlobalVariable - Emit global variable's debug info.
@@ -3167,10 +3204,20 @@
   // Do not use DIGlobalVariable for enums.
   if (Ty.getTag() == llvm::dwarf::DW_TAG_enumeration_type)
     return;
+  // Do not emit separate definitions for function local const/statics.
+  if (isa<FunctionDecl>(VD->getDeclContext()))
+    return;
+  VD = cast<ValueDecl>(VD->getCanonicalDecl());
+  auto pair = DeclCache.insert(std::make_pair(VD, llvm::WeakVH()));
+  if (!pair.second)
+    return;
+  llvm::DIDescriptor DContext =
+      getContextDescriptor(dyn_cast<Decl>(VD->getDeclContext()));
   llvm::DIGlobalVariable GV = DBuilder.createStaticVariable(
-      Unit, Name, Name, Unit, getLineNumber(VD->getLocation()), Ty, true, Init,
+      DContext, Name, StringRef(), Unit, getLineNumber(VD->getLocation()), Ty,
+      true, Init,
       getOrCreateStaticDataMemberDeclarationOrNull(cast<VarDecl>(VD)));
-  DeclCache.insert(std::make_pair(VD->getCanonicalDecl(), llvm::WeakVH(GV)));
+  pair.first->second = llvm::WeakVH(GV);
 }
 
 llvm::DIScope CGDebugInfo::getCurrentContextDescriptor(const Decl *D) {
@@ -3196,7 +3243,7 @@
   // Emitting one decl is sufficient - debuggers can detect that this is an
   // overloaded name & provide lookup for all the overloads.
   const UsingShadowDecl &USD = **UD.shadow_begin();
-  if (llvm::DIDescriptor Target =
+  if (llvm::DIScope Target =
           getDeclarationOrDefinition(USD.getUnderlyingDecl()))
     DBuilder.createImportedDeclaration(
         getCurrentContextDescriptor(cast<Decl>(USD.getDeclContext())), Target,
@@ -3206,20 +3253,20 @@
 llvm::DIImportedEntity
 CGDebugInfo::EmitNamespaceAlias(const NamespaceAliasDecl &NA) {
   if (CGM.getCodeGenOpts().getDebugInfo() < CodeGenOptions::LimitedDebugInfo)
-    return llvm::DIImportedEntity(0);
+    return llvm::DIImportedEntity(nullptr);
   llvm::WeakVH &VH = NamespaceAliasCache[&NA];
   if (VH)
     return llvm::DIImportedEntity(cast<llvm::MDNode>(VH));
-  llvm::DIImportedEntity R(0);
+  llvm::DIImportedEntity R(nullptr);
   if (const NamespaceAliasDecl *Underlying =
           dyn_cast<NamespaceAliasDecl>(NA.getAliasedNamespace()))
     // This could cache & dedup here rather than relying on metadata deduping.
-    R = DBuilder.createImportedModule(
+    R = DBuilder.createImportedDeclaration(
         getCurrentContextDescriptor(cast<Decl>(NA.getDeclContext())),
         EmitNamespaceAlias(*Underlying), getLineNumber(NA.getLocation()),
         NA.getName());
   else
-    R = DBuilder.createImportedModule(
+    R = DBuilder.createImportedDeclaration(
         getCurrentContextDescriptor(cast<Decl>(NA.getDeclContext())),
         getOrCreateNameSpace(cast<NamespaceDecl>(NA.getAliasedNamespace())),
         getLineNumber(NA.getLocation()), NA.getName());
@@ -3248,23 +3295,27 @@
 }
 
 void CGDebugInfo::finalize() {
-  for (std::vector<std::pair<void *, llvm::WeakVH> >::const_iterator VI
-         = ReplaceMap.begin(), VE = ReplaceMap.end(); VI != VE; ++VI) {
-    llvm::DIType Ty, RepTy;
-    // Verify that the debug info still exists.
-    if (llvm::Value *V = VI->second)
-      Ty = llvm::DIType(cast<llvm::MDNode>(V));
+  // Creating types might create further types - invalidating the current
+  // element and the size(), so don't cache/reference them.
+  for (size_t i = 0; i != ObjCInterfaceCache.size(); ++i) {
+    ObjCInterfaceCacheEntry E = ObjCInterfaceCache[i];
+    E.Decl.replaceAllUsesWith(CGM.getLLVMContext(),
+                              E.Type->getDecl()->getDefinition()
+                                  ? CreateTypeDefinition(E.Type, E.Unit)
+                                  : E.Decl);
+  }
 
-    llvm::DenseMap<void *, llvm::WeakVH>::iterator it =
-      TypeCache.find(VI->first);
-    if (it != TypeCache.end()) {
-      // Verify that the debug info still exists.
-      if (llvm::Value *V = it->second)
-        RepTy = llvm::DIType(cast<llvm::MDNode>(V));
-    }
+  for (auto p : ReplaceMap) {
+    assert(p.second);
+    llvm::DIType Ty(cast<llvm::MDNode>(p.second));
+    assert(Ty.isForwardDecl());
 
-    if (Ty && Ty.isForwardDecl() && RepTy)
-      Ty.replaceAllUsesWith(RepTy);
+    auto it = TypeCache.find(p.first);
+    assert(it != TypeCache.end());
+    assert(it->second);
+
+    llvm::DIType RepTy(cast<llvm::MDNode>(it->second));
+    Ty.replaceAllUsesWith(CGM.getLLVMContext(), RepTy);
   }
 
   // We keep our own list of retained types, because we need to look
diff --git a/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h
index 0ca274f..fc3f434 100644
--- a/lib/CodeGen/CGDebugInfo.h
+++ b/lib/CodeGen/CGDebugInfo.h
@@ -7,7 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This is the source level debug info generator for llvm translation.
+// This is the source-level debug info generator for llvm translation.
 //
 //===----------------------------------------------------------------------===//
 
@@ -20,10 +20,10 @@
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Frontend/CodeGenOptions.h"
 #include "llvm/ADT/DenseMap.h"
-#include "llvm/DIBuilder.h"
-#include "llvm/DebugInfo.h"
+#include "llvm/IR/DIBuilder.h"
+#include "llvm/IR/DebugInfo.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/Support/Allocator.h"
-#include "llvm/Support/ValueHandle.h"
 
 namespace llvm {
   class MDNode;
@@ -47,8 +47,8 @@
 /// and is responsible for emitting to llvm globals or pass directly to
 /// the backend.
 class CGDebugInfo {
-  friend class NoLocation;
   friend class ArtificialLocation;
+  friend class SaveAndRestoreLocation;
   CodeGenModule &CGM;
   const CodeGenOptions::DebugInfoKind DebugKind;
   llvm::DIBuilder DBuilder;
@@ -65,21 +65,27 @@
   llvm::DIType BlockLiteralGeneric;
 
   /// TypeCache - Cache of previously constructed Types.
-  llvm::DenseMap<void *, llvm::WeakVH> TypeCache;
+  llvm::DenseMap<const void *, llvm::WeakVH> TypeCache;
+
+  struct ObjCInterfaceCacheEntry {
+    const ObjCInterfaceType *Type;
+    llvm::DIType Decl;
+    llvm::DIFile Unit;
+    ObjCInterfaceCacheEntry(const ObjCInterfaceType *Type, llvm::DIType Decl,
+                            llvm::DIFile Unit)
+        : Type(Type), Decl(Decl), Unit(Unit) {}
+  };
 
   /// ObjCInterfaceCache - Cache of previously constructed interfaces
-  /// which may change. Storing a pair of DIType and checksum.
-  llvm::DenseMap<void *, std::pair<llvm::WeakVH, unsigned> > ObjCInterfaceCache;
+  /// which may change.
+  llvm::SmallVector<ObjCInterfaceCacheEntry, 32> ObjCInterfaceCache;
 
   /// RetainedTypes - list of interfaces we want to keep even if orphaned.
   std::vector<void *> RetainedTypes;
 
-  /// CompleteTypeCache - Cache of previously constructed complete RecordTypes.
-  llvm::DenseMap<void *, llvm::WeakVH> CompletedTypeCache;
-
   /// ReplaceMap - Cache of forward declared types to RAUW at the end of
   /// compilation.
-  std::vector<std::pair<void *, llvm::WeakVH> >ReplaceMap;
+  std::vector<std::pair<const TagType *, llvm::WeakVH>> ReplaceMap;
 
   // LexicalBlockStack - Keep track of our current nested lexical block.
   std::vector<llvm::TrackingVH<llvm::MDNode> > LexicalBlockStack;
@@ -109,6 +115,7 @@
   llvm::DIType CreateType(const ComplexType *Ty);
   llvm::DIType CreateQualifiedType(QualType Ty, llvm::DIFile Fg);
   llvm::DIType CreateType(const TypedefType *Ty, llvm::DIFile Fg);
+  llvm::DIType CreateType(const TemplateSpecializationType *Ty, llvm::DIFile Fg);
   llvm::DIType CreateType(const ObjCObjectPointerType *Ty,
                           llvm::DIFile F);
   llvm::DIType CreateType(const PointerType *Ty, llvm::DIFile F);
@@ -119,6 +126,7 @@
   llvm::DICompositeType CreateLimitedType(const RecordType *Ty);
   void CollectContainingType(const CXXRecordDecl *RD, llvm::DICompositeType CT);
   llvm::DIType CreateType(const ObjCInterfaceType *Ty, llvm::DIFile F);
+  llvm::DIType CreateTypeDefinition(const ObjCInterfaceType *Ty, llvm::DIFile F);
   llvm::DIType CreateType(const ObjCObjectType *Ty, llvm::DIFile F);
   llvm::DIType CreateType(const VectorType *Ty, llvm::DIFile F);
   llvm::DIType CreateType(const ArrayType *Ty, llvm::DIFile F);
@@ -127,9 +135,9 @@
   llvm::DIType CreateType(const MemberPointerType *Ty, llvm::DIFile F);
   llvm::DIType CreateType(const AtomicType *Ty, llvm::DIFile F);
   llvm::DIType CreateEnumType(const EnumType *Ty);
+  llvm::DIType CreateTypeDefinition(const EnumType *Ty);
   llvm::DIType CreateSelfType(const QualType &QualTy, llvm::DIType Ty);
   llvm::DIType getTypeOrNull(const QualType);
-  llvm::DIType getCompletedTypeOrNull(const QualType);
   llvm::DICompositeType getOrCreateMethodType(const CXXMethodDecl *Method,
                                               llvm::DIFile F);
   llvm::DICompositeType getOrCreateInstanceMethodType(
@@ -139,7 +147,7 @@
   llvm::DIType getOrCreateVTablePtrType(llvm::DIFile F);
   llvm::DINameSpace getOrCreateNameSpace(const NamespaceDecl *N);
   llvm::DIType getOrCreateTypeDeclaration(QualType PointeeTy, llvm::DIFile F);
-  llvm::DIType CreatePointerLikeType(unsigned Tag,
+  llvm::DIType CreatePointerLikeType(llvm::dwarf::Tag Tag,
                                      const Type *Ty, QualType PointeeTy,
                                      llvm::DIFile F);
 
@@ -219,8 +227,12 @@
 
   /// EmitFunctionStart - Emit a call to llvm.dbg.function.start to indicate
   /// start of a new function.
-  void EmitFunctionStart(GlobalDecl GD, QualType FnType,
-                         llvm::Function *Fn, CGBuilderTy &Builder);
+  /// \param Loc       The location of the function header.
+  /// \param ScopeLoc  The location of the function body.
+  void EmitFunctionStart(GlobalDecl GD,
+                         SourceLocation Loc, SourceLocation ScopeLoc,
+                         QualType FnType, llvm::Function *Fn,
+                         CGBuilderTy &Builder);
 
   /// EmitFunctionEnd - Constructs the debug code for exiting a function.
   void EmitFunctionEnd(CGBuilderTy &Builder);
@@ -261,9 +273,6 @@
   /// EmitGlobalVariable - Emit information about a global variable.
   void EmitGlobalVariable(llvm::GlobalVariable *GV, const VarDecl *Decl);
 
-  /// EmitGlobalVariable - Emit information about an objective-c interface.
-  void EmitGlobalVariable(llvm::GlobalVariable *GV, ObjCInterfaceDecl *Decl);
-
   /// EmitGlobalVariable - Emit global variable's debug info.
   void EmitGlobalVariable(const ValueDecl *VD, llvm::Constant *Init);
 
@@ -284,14 +293,19 @@
   llvm::DIType getOrCreateInterfaceType(QualType Ty,
                                         SourceLocation Loc);
 
+  void completeType(const EnumDecl *ED);
   void completeType(const RecordDecl *RD);
   void completeRequiredType(const RecordDecl *RD);
   void completeClassData(const RecordDecl *RD);
 
+  void completeTemplateDefinition(const ClassTemplateSpecializationDecl &SD);
+
 private:
   /// EmitDeclare - Emit call to llvm.dbg.declare for a variable declaration.
-  void EmitDeclare(const VarDecl *decl, unsigned Tag, llvm::Value *AI,
-                   unsigned ArgNo, CGBuilderTy &Builder);
+  /// Tag accepts custom types DW_TAG_arg_variable and DW_TAG_auto_variable,
+  /// otherwise would be of type llvm::dwarf::Tag.
+  void EmitDeclare(const VarDecl *decl, llvm::dwarf::LLVMConstants Tag,
+                   llvm::Value *AI, unsigned ArgNo, CGBuilderTy &Builder);
 
   // EmitTypeForVarWithBlocksAttr - Build up structure info for the byref.
   // See BuildByRefType.
@@ -342,9 +356,9 @@
   llvm::DIType CreateMemberType(llvm::DIFile Unit, QualType FType,
                                 StringRef Name, uint64_t *Offset);
 
-  /// \brief Retrieve the DIDescriptor, if any, for the canonical form of this
+  /// \brief Retrieve the DIScope, if any, for the canonical form of this
   /// declaration.
-  llvm::DIDescriptor getDeclarationOrDefinition(const Decl *D);
+  llvm::DIScope getDeclarationOrDefinition(const Decl *D);
 
   /// getFunctionDeclaration - Return debug info descriptor to describe method
   /// declaration for the given method definition.
@@ -355,6 +369,13 @@
   llvm::DIDerivedType
   getOrCreateStaticDataMemberDeclarationOrNull(const VarDecl *D);
 
+  /// Return a global variable that represents one of the collection of
+  /// global variables created for an anonmyous union.
+  llvm::DIGlobalVariable
+  CollectAnonRecordDecls(const RecordDecl *RD, llvm::DIFile Unit, unsigned LineNo,
+                         StringRef LinkageName, llvm::GlobalVariable *Var,
+                         llvm::DIDescriptor DContext);
+
   /// getFunctionName - Get function name for the given FunctionDecl. If the
   /// name is constructed on demand (e.g. C++ destructor) then the name
   /// is stored on the side.
@@ -394,16 +415,26 @@
   }
 };
 
-/// NoLocation - An RAII object that temporarily disables debug
-/// locations. This is useful for emitting instructions that should be
-/// counted towards the function prologue.
-class NoLocation {
+/// SaveAndRestoreLocation - An RAII object saves the current location
+/// and automatically restores it to the original value.
+class SaveAndRestoreLocation {
+protected:
   SourceLocation SavedLoc;
   CGDebugInfo *DI;
   CGBuilderTy &Builder;
 public:
+  SaveAndRestoreLocation(CodeGenFunction &CGF, CGBuilderTy &B);
+  /// Autorestore everything back to normal.
+  ~SaveAndRestoreLocation();
+};
+
+/// NoLocation - An RAII object that temporarily disables debug
+/// locations. This is useful for emitting instructions that should be
+/// counted towards the function prologue.
+class NoLocation : public SaveAndRestoreLocation {
+public:
   NoLocation(CodeGenFunction &CGF, CGBuilderTy &B);
-  /// ~NoLocation - Autorestore everything back to normal.
+  /// Autorestore everything back to normal.
   ~NoLocation();
 };
 
@@ -418,10 +449,7 @@
 /// This is necessary because passing an empty SourceLocation to
 /// CGDebugInfo::setLocation() will result in the last valid location
 /// being reused.
-class ArtificialLocation {
-  SourceLocation SavedLoc;
-  CGDebugInfo *DI;
-  CGBuilderTy &Builder;
+class ArtificialLocation : public SaveAndRestoreLocation {
 public:
   ArtificialLocation(CodeGenFunction &CGF, CGBuilderTy &B);
 
@@ -429,7 +457,7 @@
   /// (= the top of the LexicalBlockStack).
   void Emit();
 
-  /// ~ArtificialLocation - Autorestore everything back to normal.
+  /// Autorestore everything back to normal.
   ~ArtificialLocation();
 };
 
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
index 66d6b33..91f8041 100644
--- a/lib/CodeGen/CGDecl.cpp
+++ b/lib/CodeGen/CGDecl.cpp
@@ -126,17 +126,11 @@
 void CodeGenFunction::EmitVarDecl(const VarDecl &D) {
   if (D.isStaticLocal()) {
     llvm::GlobalValue::LinkageTypes Linkage =
-      llvm::GlobalValue::InternalLinkage;
+        CGM.getLLVMLinkageVarDefinition(&D, /*isConstant=*/false);
 
-    // If the variable is externally visible, it must have weak linkage so it
-    // can be uniqued.
-    if (D.isExternallyVisible()) {
-      Linkage = llvm::GlobalValue::LinkOnceODRLinkage;
-
-      // FIXME: We need to force the emission/use of a guard variable for
-      // some variables even if we can constant-evaluate them because
-      // we can't guarantee every translation unit will constant-evaluate them.
-    }
+    // FIXME: We need to force the emission/use of a guard variable for
+    // some variables even if we can constant-evaluate them because
+    // we can't guarantee every translation unit will constant-evaluate them.
 
     return EmitStaticVarDecl(D, Linkage);
   }
@@ -155,35 +149,30 @@
 static std::string GetStaticDeclName(CodeGenFunction &CGF, const VarDecl &D,
                                      const char *Separator) {
   CodeGenModule &CGM = CGF.CGM;
-  if (CGF.getLangOpts().CPlusPlus) {
-    StringRef Name = CGM.getMangledName(&D);
-    return Name.str();
-  }
 
-  std::string ContextName;
+  if (CGF.getLangOpts().CPlusPlus)
+    return CGM.getMangledName(&D).str();
+
+  StringRef ContextName;
   if (!CGF.CurFuncDecl) {
     // Better be in a block declared in global scope.
     const NamedDecl *ND = cast<NamedDecl>(&D);
     const DeclContext *DC = ND->getDeclContext();
-    if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {
-      MangleBuffer Name;
-      CGM.getBlockMangledName(GlobalDecl(), Name, BD);
-      ContextName = Name.getString();
-    }
+    if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC))
+      ContextName = CGM.getBlockMangledName(GlobalDecl(), BD);
     else
       llvm_unreachable("Unknown context for block static var decl");
-  } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CGF.CurFuncDecl)) {
-    StringRef Name = CGM.getMangledName(FD);
-    ContextName = Name.str();
-  } else if (isa<ObjCMethodDecl>(CGF.CurFuncDecl))
+  } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CGF.CurFuncDecl))
+    ContextName = CGM.getMangledName(FD);
+  else if (isa<ObjCMethodDecl>(CGF.CurFuncDecl))
     ContextName = CGF.CurFn->getName();
   else
     llvm_unreachable("Unknown context for static var decl");
 
-  return ContextName + Separator + D.getNameAsString();
+  return ContextName.str() + Separator + D.getNameAsString();
 }
 
-llvm::GlobalVariable *
+llvm::Constant *
 CodeGenFunction::CreateStaticVarDecl(const VarDecl &D,
                                      const char *Separator,
                                      llvm::GlobalValue::LinkageTypes Linkage) {
@@ -203,7 +192,7 @@
   llvm::GlobalVariable *GV =
     new llvm::GlobalVariable(CGM.getModule(), LTy,
                              Ty.isConstant(getContext()), Linkage,
-                             CGM.EmitNullConstant(D.getType()), Name, 0,
+                             CGM.EmitNullConstant(D.getType()), Name, nullptr,
                              llvm::GlobalVariable::NotThreadLocal,
                              AddrSpace);
   GV->setAlignment(getContext().getDeclAlign(&D).getQuantity());
@@ -212,6 +201,20 @@
   if (D.getTLSKind())
     CGM.setTLSMode(GV, D);
 
+  if (D.isExternallyVisible()) {
+    if (D.hasAttr<DLLImportAttr>())
+      GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass);
+    else if (D.hasAttr<DLLExportAttr>())
+      GV->setDLLStorageClass(llvm::GlobalVariable::DLLExportStorageClass);
+  }
+
+  // Make sure the result is of the correct type.
+  unsigned ExpectedAddrSpace = CGM.getContext().getTargetAddressSpace(Ty);
+  if (AddrSpace != ExpectedAddrSpace) {
+    llvm::PointerType *PTy = llvm::PointerType::get(LTy, ExpectedAddrSpace);
+    return llvm::ConstantExpr::getAddrSpaceCast(GV, PTy);
+  }
+
   return GV;
 }
 
@@ -290,7 +293,7 @@
 void CodeGenFunction::EmitStaticVarDecl(const VarDecl &D,
                                       llvm::GlobalValue::LinkageTypes Linkage) {
   llvm::Value *&DMEntry = LocalDeclMap[&D];
-  assert(DMEntry == 0 && "Decl already exists in localdeclmap!");
+  assert(!DMEntry && "Decl already exists in localdeclmap!");
 
   // Check to see if we already have a global variable for this
   // declaration.  This can happen when double-emitting function
@@ -298,12 +301,8 @@
   llvm::Constant *addr =
     CGM.getStaticLocalDeclAddress(&D);
 
-  llvm::GlobalVariable *var;
-  if (addr) {
-    var = cast<llvm::GlobalVariable>(addr->stripPointerCasts());
-  } else {
-    addr = var = CreateStaticVarDecl(D, ".", Linkage);
-  }
+  if (!addr)
+    addr = CreateStaticVarDecl(D, ".", Linkage);
 
   // Store into LocalDeclMap before generating initializer to handle
   // circular references.
@@ -319,6 +318,8 @@
   // Save the type in case adding the initializer forces a type change.
   llvm::Type *expectedType = addr->getType();
 
+  llvm::GlobalVariable *var =
+    cast<llvm::GlobalVariable>(addr->stripPointerCasts());
   // If this value has an initializer, emit it.
   if (D.getInit())
     var = AddInitializerToStaticVarDecl(D, var);
@@ -332,17 +333,20 @@
     var->setSection(SA->getName());
 
   if (D.hasAttr<UsedAttr>())
-    CGM.AddUsedGlobal(var);
+    CGM.addUsedGlobal(var);
 
   // We may have to cast the constant because of the initializer
   // mismatch above.
   //
   // FIXME: It is really dangerous to store this in the map; if anyone
   // RAUW's the GV uses of this constant will be invalid.
-  llvm::Constant *castedAddr = llvm::ConstantExpr::getBitCast(var, expectedType);
+  llvm::Constant *castedAddr =
+    llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(var, expectedType);
   DMEntry = castedAddr;
   CGM.setStaticLocalDeclAddress(&D, castedAddr);
 
+  CGM.reportGlobalToASan(var, D);
+
   // Emit global variable debug descriptor for static vars.
   CGDebugInfo *DI = getDebugInfo();
   if (DI &&
@@ -365,7 +369,7 @@
     CodeGenFunction::Destroyer *destroyer;
     bool useEHCleanupForArray;
 
-    void Emit(CodeGenFunction &CGF, Flags flags) {
+    void Emit(CodeGenFunction &CGF, Flags flags) override {
       // Don't use an EH cleanup recursively from an EH cleanup.
       bool useEHCleanupForArray =
         flags.isForNormalCleanup() && this->useEHCleanupForArray;
@@ -384,11 +388,11 @@
     llvm::Value *NRVOFlag;
     llvm::Value *Loc;
 
-    void Emit(CodeGenFunction &CGF, Flags flags) {
+    void Emit(CodeGenFunction &CGF, Flags flags) override {
       // Along the exceptions path we always execute the dtor.
       bool NRVO = flags.isForNormalCleanup() && NRVOFlag;
 
-      llvm::BasicBlock *SkipDtorBB = 0;
+      llvm::BasicBlock *SkipDtorBB = nullptr;
       if (NRVO) {
         // If we exited via NRVO, we skip the destructor call.
         llvm::BasicBlock *RunDtorBB = CGF.createBasicBlock("nrvo.unused");
@@ -410,7 +414,7 @@
   struct CallStackRestore : EHScopeStack::Cleanup {
     llvm::Value *Stack;
     CallStackRestore(llvm::Value *Stack) : Stack(Stack) {}
-    void Emit(CodeGenFunction &CGF, Flags flags) {
+    void Emit(CodeGenFunction &CGF, Flags flags) override {
       llvm::Value *V = CGF.Builder.CreateLoad(Stack);
       llvm::Value *F = CGF.CGM.getIntrinsic(llvm::Intrinsic::stackrestore);
       CGF.Builder.CreateCall(F, V);
@@ -421,7 +425,7 @@
     const VarDecl &Var;
     ExtendGCLifetime(const VarDecl *var) : Var(*var) {}
 
-    void Emit(CodeGenFunction &CGF, Flags flags) {
+    void Emit(CodeGenFunction &CGF, Flags flags) override {
       // Compute the address of the local variable, in case it's a
       // byref or something.
       DeclRefExpr DRE(const_cast<VarDecl*>(&Var), false,
@@ -441,7 +445,7 @@
                         const VarDecl *Var)
       : CleanupFn(CleanupFn), FnInfo(*Info), Var(*Var) {}
 
-    void Emit(CodeGenFunction &CGF, Flags flags) {
+    void Emit(CodeGenFunction &CGF, Flags flags) override {
       DeclRefExpr DRE(const_cast<VarDecl*>(&Var), false,
                       Var.getType(), VK_LValue, SourceLocation());
       // Compute the address of the local variable, in case it's a byref
@@ -473,7 +477,7 @@
     CallLifetimeEnd(llvm::Value *addr, llvm::Value *size)
       : Addr(addr), Size(size) {}
 
-    void Emit(CodeGenFunction &CGF, Flags flags) {
+    void Emit(CodeGenFunction &CGF, Flags flags) override {
       llvm::Value *castAddr = CGF.Builder.CreateBitCast(Addr, CGF.Int8PtrTy);
       CGF.Builder.CreateCall2(CGF.CGM.getLLVMLifetimeEndFn(),
                               Size, castAddr)
@@ -530,9 +534,8 @@
       return (ref->getDecl() == &var);
     if (const BlockExpr *be = dyn_cast<BlockExpr>(e)) {
       const BlockDecl *block = be->getBlockDecl();
-      for (BlockDecl::capture_const_iterator i = block->capture_begin(),
-           e = block->capture_end(); i != e; ++i) {
-        if (i->getVariable() == &var)
+      for (const auto &I : block->captures()) {
+        if (I.getVariable() == &var)
           return true;
       }
     }
@@ -571,7 +574,10 @@
     EmitStoreThroughLValue(RValue::get(value), lvalue, true);
     return;
   }
-
+  
+  if (const CXXDefaultInitExpr *DIE = dyn_cast<CXXDefaultInitExpr>(init))
+    init = DIE->getExpr();
+    
   // If we're emitting a value with lifetime, we have to do the
   // initialization *before* we leave the cleanup scopes.
   if (const ExprWithCleanups *ewc = dyn_cast<ExprWithCleanups>(init)) {
@@ -613,7 +619,7 @@
   }
 
   // Emit the initializer.
-  llvm::Value *value = 0;
+  llvm::Value *value = nullptr;
 
   switch (lifetime) {
   case Qualifiers::OCL_None:
@@ -798,9 +804,6 @@
 /// Should we use the LLVM lifetime intrinsics for the given local variable?
 static bool shouldUseLifetimeMarkers(CodeGenFunction &CGF, const VarDecl &D,
                                      unsigned Size) {
-  // Always emit lifetime markers in -fsanitize=use-after-scope mode.
-  if (CGF.getLangOpts().Sanitize.UseAfterScope)
-    return true;
   // For now, only in optimized builds.
   if (CGF.CGM.getCodeGenOpts().OptimizationLevel == 0)
     return false;
@@ -823,7 +826,7 @@
 }
 
 /// EmitAutoVarAlloca - Emit the alloca and debug information for a
-/// local variable.  Does not emit initalization or destruction.
+/// local variable.  Does not emit initialization or destruction.
 CodeGenFunction::AutoVarEmission
 CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
   QualType Ty = D.getType();
@@ -866,7 +869,7 @@
           CGM.isTypeConstant(Ty, true)) {
         EmitStaticVarDecl(D, llvm::GlobalValue::InternalLinkage);
 
-        emission.Address = 0; // signal this condition to later callbacks
+        emission.Address = nullptr; // signal this condition to later callbacks
         assert(emission.wasEmittedAsGlobal());
         return emission;
       }
@@ -944,12 +947,12 @@
 
       // Push a cleanup block and restore the stack there.
       // FIXME: in general circumstances, this should be an EH cleanup.
-      EHStack.pushCleanup<CallStackRestore>(NormalCleanup, Stack);
+      pushStackRestore(NormalCleanup, Stack);
     }
 
     llvm::Value *elementCount;
     QualType elementType;
-    llvm::tie(elementCount, elementType) = getVLASize(Ty);
+    std::tie(elementCount, elementType) = getVLASize(Ty);
 
     llvm::Type *llvmTy = ConvertTypeForMem(elementType);
 
@@ -961,7 +964,7 @@
   }
 
   llvm::Value *&DMEntry = LocalDeclMap[&D];
-  assert(DMEntry == 0 && "Decl already exists in localdeclmap!");
+  assert(!DMEntry && "Decl already exists in localdeclmap!");
   DMEntry = DeclPtr;
   emission.Address = DeclPtr;
 
@@ -990,9 +993,8 @@
 
   if (const BlockExpr *be = dyn_cast<BlockExpr>(e)) {
     const BlockDecl *block = be->getBlockDecl();
-    for (BlockDecl::capture_const_iterator i = block->capture_begin(),
-           e = block->capture_end(); i != e; ++i) {
-      if (i->getVariable() == &var)
+    for (const auto &I : block->captures()) {
+      if (I.getVariable() == &var)
         return true;
     }
 
@@ -1002,18 +1004,16 @@
 
   if (const StmtExpr *SE = dyn_cast<StmtExpr>(e)) {
     const CompoundStmt *CS = SE->getSubStmt();
-    for (CompoundStmt::const_body_iterator BI = CS->body_begin(),
-	   BE = CS->body_end(); BI != BE; ++BI)
-      if (Expr *E = dyn_cast<Expr>((*BI))) {
+    for (const auto *BI : CS->body())
+      if (const auto *E = dyn_cast<Expr>(BI)) {
         if (isCapturedBy(var, E))
             return true;
       }
-      else if (DeclStmt *DS = dyn_cast<DeclStmt>((*BI))) {
+      else if (const auto *DS = dyn_cast<DeclStmt>(BI)) {
           // special case declarations
-          for (DeclStmt::decl_iterator I = DS->decl_begin(), E = DS->decl_end();
-               I != E; ++I) {
-              if (VarDecl *VD = dyn_cast<VarDecl>((*I))) {
-                Expr *Init = VD->getInit();
+          for (const auto *I : DS->decls()) {
+              if (const auto *VD = dyn_cast<VarDecl>((I))) {
+                const Expr *Init = VD->getInit();
                 if (Init && isCapturedBy(var, Init))
                   return true;
               }
@@ -1084,7 +1084,7 @@
   llvm::Value *Loc =
     capturedByInit ? emission.Address : emission.getObjectAddress(*this);
 
-  llvm::Constant *constant = 0;
+  llvm::Constant *constant = nullptr;
   if (emission.IsConstantAggregate || D.isConstexpr()) {
     assert(!capturedByInit && "constant init contains a capturing block?");
     constant = CGM.EmitConstantInit(D, this);
@@ -1211,7 +1211,7 @@
   QualType type = var->getType();
 
   CleanupKind cleanupKind = NormalAndEHCleanup;
-  CodeGenFunction::Destroyer *destroyer = 0;
+  CodeGenFunction::Destroyer *destroyer = nullptr;
 
   switch (dtorKind) {
   case QualType::DK_none:
@@ -1344,6 +1344,10 @@
                                      destroyer, useEHCleanupForArray);
 }
 
+void CodeGenFunction::pushStackRestore(CleanupKind Kind, llvm::Value *SPMem) {
+  EHStack.pushCleanup<CallStackRestore>(Kind, SPMem);
+}
+
 void CodeGenFunction::pushLifetimeExtendedDestroy(
     CleanupKind cleanupKind, llvm::Value *addr, QualType type,
     Destroyer *destroyer, bool useEHCleanupForArray) {
@@ -1505,7 +1509,7 @@
       : ArrayBegin(arrayBegin), ArrayEnd(arrayEnd),
         ElementType(elementType), Destroyer(destroyer) {}
 
-    void Emit(CodeGenFunction &CGF, Flags flags) {
+    void Emit(CodeGenFunction &CGF, Flags flags) override {
       emitPartialArrayDestroy(CGF, ArrayBegin, ArrayEnd,
                               ElementType, Destroyer);
     }
@@ -1527,7 +1531,7 @@
       : ArrayBegin(arrayBegin), ArrayEndPointer(arrayEndPointer),
         ElementType(elementType), Destroyer(destroyer) {}
 
-    void Emit(CodeGenFunction &CGF, Flags flags) {
+    void Emit(CodeGenFunction &CGF, Flags flags) override {
       llvm::Value *arrayEnd = CGF.Builder.CreateLoad(ArrayEndPointer);
       emitPartialArrayDestroy(CGF, ArrayBegin, arrayEnd,
                               ElementType, Destroyer);
@@ -1594,7 +1598,7 @@
     llvm::Value *Param;
     ARCPreciseLifetime_t Precise;
 
-    void Emit(CodeGenFunction &CGF, Flags flags) {
+    void Emit(CodeGenFunction &CGF, Flags flags) override {
       CGF.EmitARCRelease(Param, Precise);
     }
   };
@@ -1603,7 +1607,7 @@
 /// Emit an alloca (or GlobalValue depending on target)
 /// for the specified parameter and set up LocalDeclMap.
 void CodeGenFunction::EmitParmDecl(const VarDecl &D, llvm::Value *Arg,
-                                   unsigned ArgNo) {
+                                   bool ArgIsPointer, unsigned ArgNo) {
   // FIXME: Why isn't ImplicitParamDecl a ParmVarDecl?
   assert((isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)) &&
          "Invalid argument to EmitParmDecl");
@@ -1617,7 +1621,7 @@
     // The only implicit argument a block has is its literal.
     if (BlockInfo) {
       LocalDeclMap[&D] = Arg;
-      llvm::Value *LocalAddr = 0;
+      llvm::Value *LocalAddr = nullptr;
       if (CGM.getCodeGenOpts().OptimizationLevel == 0) {
         // Allocate a stack slot to let the debug info survive the RA.
         llvm::AllocaInst *Alloc = CreateTempAlloca(ConvertTypeForMem(Ty),
@@ -1641,30 +1645,35 @@
   }
 
   llvm::Value *DeclPtr;
-  bool HasNonScalarEvalKind = !CodeGenFunction::hasScalarEvaluationKind(Ty);
-  // If this is an aggregate or variable sized value, reuse the input pointer.
-  if (HasNonScalarEvalKind || !Ty->isConstantSizeType()) {
-    DeclPtr = Arg;
+  bool DoStore = false;
+  bool IsScalar = hasScalarEvaluationKind(Ty);
+  CharUnits Align = getContext().getDeclAlign(&D);
+  // If we already have a pointer to the argument, reuse the input pointer.
+  if (ArgIsPointer) {
+    // If we have a prettier pointer type at this point, bitcast to that.
+    unsigned AS = cast<llvm::PointerType>(Arg->getType())->getAddressSpace();
+    llvm::Type *IRTy = ConvertTypeForMem(Ty)->getPointerTo(AS);
+    DeclPtr = Arg->getType() == IRTy ? Arg : Builder.CreateBitCast(Arg, IRTy,
+                                                                   D.getName());
     // Push a destructor cleanup for this parameter if the ABI requires it.
-    if (HasNonScalarEvalKind &&
-        getTarget().getCXXABI().isArgumentDestroyedByCallee()) {
-      if (const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl()) {
-        if (RD->hasNonTrivialDestructor())
-          pushDestroy(QualType::DK_cxx_destructor, DeclPtr, Ty);
-      }
+    if (!IsScalar &&
+        getTarget().getCXXABI().areArgsDestroyedLeftToRightInCallee()) {
+      const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();
+      if (RD && RD->hasNonTrivialDestructor())
+        pushDestroy(QualType::DK_cxx_destructor, DeclPtr, Ty);
     }
   } else {
     // Otherwise, create a temporary to hold the value.
     llvm::AllocaInst *Alloc = CreateTempAlloca(ConvertTypeForMem(Ty),
                                                D.getName() + ".addr");
-    CharUnits Align = getContext().getDeclAlign(&D);
     Alloc->setAlignment(Align.getQuantity());
     DeclPtr = Alloc;
+    DoStore = true;
+  }
 
-    bool doStore = true;
-
+  LValue lv = MakeAddrLValue(DeclPtr, Ty, Align);
+  if (IsScalar) {
     Qualifiers qs = Ty.getQualifiers();
-    LValue lv = MakeAddrLValue(DeclPtr, Ty, Align);
     if (Qualifiers::ObjCLifetime lt = qs.getObjCLifetime()) {
       // We honor __attribute__((ns_consumed)) for types with lifetime.
       // For __strong, it's handled by just skipping the initial retain;
@@ -1693,7 +1702,7 @@
             llvm::Value *Null = CGM.EmitNullConstant(D.getType());
             EmitStoreOfScalar(Null, lv, /* isInitialization */ true);
             EmitARCStoreStrongCall(lv.getAddress(), Arg, true);
-            doStore = false;
+            DoStore = false;
           }
           else
           // Don't use objc_retainBlock for block pointers, because we
@@ -1712,21 +1721,21 @@
 
         if (lt == Qualifiers::OCL_Weak) {
           EmitARCInitWeak(DeclPtr, Arg);
-          doStore = false; // The weak init is a store, no need to do two.
+          DoStore = false; // The weak init is a store, no need to do two.
         }
       }
 
       // Enter the cleanup scope.
       EmitAutoVarWithLifetime(*this, D, DeclPtr, lt);
     }
-
-    // Store the initial value into the alloca.
-    if (doStore)
-      EmitStoreOfScalar(Arg, lv, /* isInitialization */ true);
   }
 
+  // Store the initial value into the alloca.
+  if (DoStore)
+    EmitStoreOfScalar(Arg, lv, /* isInitialization */ true);
+
   llvm::Value *&DMEntry = LocalDeclMap[&D];
-  assert(DMEntry == 0 && "Decl already exists in localdeclmap!");
+  assert(!DMEntry && "Decl already exists in localdeclmap!");
   DMEntry = DeclPtr;
 
   // Emit debug info for param declaration.
diff --git a/lib/CodeGen/CGDeclCXX.cpp b/lib/CodeGen/CGDeclCXX.cpp
index 7bdb9eb..94cfe21 100644
--- a/lib/CodeGen/CGDeclCXX.cpp
+++ b/lib/CodeGen/CGDeclCXX.cpp
@@ -17,6 +17,7 @@
 #include "clang/Frontend/CodeGenOptions.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/IR/Intrinsics.h"
+#include "llvm/Support/Path.h"
 
 using namespace clang;
 using namespace CodeGen;
@@ -89,7 +90,7 @@
 
   // Special-case non-array C++ destructors, where there's a function
   // with the right signature that we can just call.
-  const CXXRecordDecl *record = 0;
+  const CXXRecordDecl *record = nullptr;
   if (dtorKind == QualType::DK_cxx_destructor &&
       (record = type->getAsCXXRecordDecl())) {
     assert(!record->hasTrivialDestructor());
@@ -178,8 +179,7 @@
   CodeGenFunction CGF(CGM);
 
   CGF.StartFunction(&VD, CGM.getContext().VoidTy, fn,
-                    CGM.getTypes().arrangeNullaryFunction(), FunctionArgList(),
-                    SourceLocation());
+                    CGM.getTypes().arrangeNullaryFunction(), FunctionArgList());
 
   llvm::CallInst *call = CGF.Builder.CreateCall(dtor, addr);
  
@@ -245,16 +245,44 @@
   if (!CGM.getLangOpts().Exceptions)
     Fn->setDoesNotThrow();
 
-  if (CGM.getSanOpts().Address)
-    Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
-  if (CGM.getSanOpts().Thread)
-    Fn->addFnAttr(llvm::Attribute::SanitizeThread);
-  if (CGM.getSanOpts().Memory)
-    Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
+  if (!CGM.getSanitizerBlacklist().isIn(*Fn)) {
+    if (CGM.getLangOpts().Sanitize.Address)
+      Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
+    if (CGM.getLangOpts().Sanitize.Thread)
+      Fn->addFnAttr(llvm::Attribute::SanitizeThread);
+    if (CGM.getLangOpts().Sanitize.Memory)
+      Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
+  }
 
   return Fn;
 }
 
+/// Create a global pointer to a function that will initialize a global
+/// variable.  The user has requested that this pointer be emitted in a specific
+/// section.
+void CodeGenModule::EmitPointerToInitFunc(const VarDecl *D,
+                                          llvm::GlobalVariable *GV,
+                                          llvm::Function *InitFunc,
+                                          InitSegAttr *ISA) {
+  llvm::GlobalVariable *PtrArray = new llvm::GlobalVariable(
+      TheModule, InitFunc->getType(), /*isConstant=*/true,
+      llvm::GlobalValue::PrivateLinkage, InitFunc, "__cxx_init_fn_ptr");
+  PtrArray->setSection(ISA->getSection());
+  addUsedGlobal(PtrArray);
+
+  // If the GV is already in a comdat group, then we have to join it.
+  llvm::Comdat *C = GV->getComdat();
+
+  // LinkOnce and Weak linkage are lowered down to a single-member comdat group.
+  // Make an explicit group so we can join it.
+  if (!C && (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage())) {
+    C = TheModule.getOrInsertComdat(GV->getName());
+    GV->setComdat(C);
+  }
+  if (C)
+    PtrArray->setComdat(C);
+}
+
 void
 CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D,
                                             llvm::GlobalVariable *Addr,
@@ -270,9 +298,9 @@
   llvm::Function *Fn =
       CreateGlobalInitOrDestructFunction(*this, FTy, FnName.str());
 
+  auto *ISA = D->getAttr<InitSegAttr>();
   CodeGenFunction(*this).GenerateCXXGlobalVarDeclInitFunc(Fn, D, Addr,
                                                           PerformInit);
-
   if (D->getTLSKind()) {
     // FIXME: Should we support init_priority for thread_local?
     // FIXME: Ideally, initialization of instantiated thread_local static data
@@ -281,9 +309,11 @@
     // FIXME: We only need to register one __cxa_thread_atexit function for the
     // entire TU.
     CXXThreadLocalInits.push_back(Fn);
-  } else if (D->hasAttr<InitPriorityAttr>()) {
-    unsigned int order = D->getAttr<InitPriorityAttr>()->getPriority();
-    OrderGlobalInits Key(order, PrioritizedCXXGlobalInits.size());
+  } else if (PerformInit && ISA) {
+    EmitPointerToInitFunc(D, Addr, Fn, ISA);
+    DelayedCXXInitPosition.erase(D);
+  } else if (auto *IPA = D->getAttr<InitPriorityAttr>()) {
+    OrderGlobalInits Key(IPA->getPriority(), PrioritizedCXXGlobalInits.size());
     PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn));
     DelayedCXXInitPosition.erase(D);
   } else if (D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization &&
@@ -295,10 +325,12 @@
     //   have unordered initialization.
     //
     // As a consequence, we can put them into their own llvm.global_ctors entry.
-    // This should allow GlobalOpt to fire more often, and allow us to implement
-    // the Microsoft C++ ABI, which uses COMDAT elimination to avoid double
-    // initializaiton.
-    AddGlobalCtor(Fn);
+    //
+    // In addition, put the initializer into a COMDAT group with the global
+    // being initialized.  On most platforms, this is a minor startup time
+    // optimization.  In the MS C++ ABI, there are no guard variables, so this
+    // COMDAT key is required for correctness.
+    AddGlobalCtor(Fn, 65535, Addr);
     DelayedCXXInitPosition.erase(D);
   } else {
     llvm::DenseMap<const Decl *, unsigned>::iterator I =
@@ -306,7 +338,7 @@
     if (I == DelayedCXXInitPosition.end()) {
       CXXGlobalInits.push_back(Fn);
     } else {
-      assert(CXXGlobalInits[I->second] == 0);
+      assert(CXXGlobalInits[I->second] == nullptr);
       CXXGlobalInits[I->second] = Fn;
       DelayedCXXInitPosition.erase(I);
     }
@@ -314,7 +346,7 @@
 }
 
 void CodeGenModule::EmitCXXThreadLocalInitFunc() {
-  llvm::Function *InitFn = 0;
+  llvm::Function *InitFn = nullptr;
   if (!CXXThreadLocalInits.empty()) {
     // Generate a guarded initialization function.
     llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
@@ -364,7 +396,7 @@
       // Compute the function suffix from priority. Prepend with zeroes to make
       // sure the function names are also ordered as priorities.
       std::string PrioritySuffix = llvm::utostr(Priority);
-      // Priority is always <= 65535 (enforced by sema)..
+      // Priority is always <= 65535 (enforced by sema).
       PrioritySuffix = std::string(6-PrioritySuffix.size(), '0')+PrioritySuffix;
       llvm::Function *Fn = 
         CreateGlobalInitOrDestructFunction(*this, FTy,
@@ -378,8 +410,20 @@
     }
   }
   
-  llvm::Function *Fn = 
-    CreateGlobalInitOrDestructFunction(*this, FTy, "_GLOBAL__I_a");
+  // Include the filename in the symbol name. Including "sub_" matches gcc and
+  // makes sure these symbols appear lexicographically behind the symbols with
+  // priority emitted above.
+  SourceManager &SM = Context.getSourceManager();
+  SmallString<128> FileName(llvm::sys::path::filename(
+      SM.getFileEntryForID(SM.getMainFileID())->getName()));
+  for (size_t i = 0; i < FileName.size(); ++i) {
+    // Replace everything that's not [a-zA-Z0-9._] with a _. This set happens
+    // to be the set of C preprocessing numbers.
+    if (!isPreprocessingNumberBody(FileName[i]))
+      FileName[i] = '_';
+  }
+  llvm::Function *Fn = CreateGlobalInitOrDestructFunction(
+      *this, FTy, llvm::Twine("_GLOBAL__sub_I_", FileName));
 
   CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, CXXGlobalInits);
   AddGlobalCtor(Fn);
@@ -409,17 +453,17 @@
                                                        bool PerformInit) {
   // Check if we need to emit debug info for variable initializer.
   if (D->hasAttr<NoDebugAttr>())
-    DebugInfo = NULL; // disable debug info indefinitely for this function
+    DebugInfo = nullptr; // disable debug info indefinitely for this function
 
   StartFunction(GlobalDecl(D), getContext().VoidTy, Fn,
                 getTypes().arrangeNullaryFunction(),
-                FunctionArgList(), D->getInit()->getExprLoc());
+                FunctionArgList(), D->getLocation(),
+                D->getInit()->getExprLoc());
 
   // Use guarded initialization if the global variable is weak. This
   // occurs for, e.g., instantiated static data members and
   // definitions explicitly marked weak.
-  if (Addr->getLinkage() == llvm::GlobalValue::WeakODRLinkage ||
-      Addr->getLinkage() == llvm::GlobalValue::WeakAnyLinkage) {
+  if (Addr->hasWeakLinkage() || Addr->hasLinkOnceLinkage()) {
     EmitCXXGuardedInit(*D, Addr, PerformInit);
   } else {
     EmitCXXGlobalVarDeclInit(*D, Addr, PerformInit);
@@ -432,44 +476,49 @@
 CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn,
                                            ArrayRef<llvm::Constant *> Decls,
                                            llvm::GlobalVariable *Guard) {
-  StartFunction(GlobalDecl(), getContext().VoidTy, Fn,
-                getTypes().arrangeNullaryFunction(),
-                FunctionArgList(), SourceLocation());
+  {
+    ArtificialLocation AL(*this, Builder);
+    StartFunction(GlobalDecl(), getContext().VoidTy, Fn,
+                  getTypes().arrangeNullaryFunction(), FunctionArgList());
+    // Emit an artificial location for this function.
+    AL.Emit();
 
-  llvm::BasicBlock *ExitBlock = 0;
-  if (Guard) {
-    // If we have a guard variable, check whether we've already performed these
-    // initializations. This happens for TLS initialization functions.
-    llvm::Value *GuardVal = Builder.CreateLoad(Guard);
-    llvm::Value *Uninit = Builder.CreateIsNull(GuardVal, "guard.uninitialized");
-    // Mark as initialized before initializing anything else. If the
-    // initializers use previously-initialized thread_local vars, that's
-    // probably supposed to be OK, but the standard doesn't say.
-    Builder.CreateStore(llvm::ConstantInt::get(GuardVal->getType(), 1), Guard);
-    llvm::BasicBlock *InitBlock = createBasicBlock("init");
-    ExitBlock = createBasicBlock("exit");
-    Builder.CreateCondBr(Uninit, InitBlock, ExitBlock);
-    EmitBlock(InitBlock);
-  }
+    llvm::BasicBlock *ExitBlock = nullptr;
+    if (Guard) {
+      // If we have a guard variable, check whether we've already performed
+      // these initializations. This happens for TLS initialization functions.
+      llvm::Value *GuardVal = Builder.CreateLoad(Guard);
+      llvm::Value *Uninit = Builder.CreateIsNull(GuardVal,
+                                                 "guard.uninitialized");
+      // Mark as initialized before initializing anything else. If the
+      // initializers use previously-initialized thread_local vars, that's
+      // probably supposed to be OK, but the standard doesn't say.
+      Builder.CreateStore(llvm::ConstantInt::get(GuardVal->getType(),1), Guard);
+      llvm::BasicBlock *InitBlock = createBasicBlock("init");
+      ExitBlock = createBasicBlock("exit");
+      Builder.CreateCondBr(Uninit, InitBlock, ExitBlock);
+      EmitBlock(InitBlock);
+    }
 
-  RunCleanupsScope Scope(*this);
+    RunCleanupsScope Scope(*this);
 
-  // When building in Objective-C++ ARC mode, create an autorelease pool
-  // around the global initializers.
-  if (getLangOpts().ObjCAutoRefCount && getLangOpts().CPlusPlus) {    
-    llvm::Value *token = EmitObjCAutoreleasePoolPush();
-    EmitObjCAutoreleasePoolCleanup(token);
-  }
+    // When building in Objective-C++ ARC mode, create an autorelease pool
+    // around the global initializers.
+    if (getLangOpts().ObjCAutoRefCount && getLangOpts().CPlusPlus) {
+      llvm::Value *token = EmitObjCAutoreleasePoolPush();
+      EmitObjCAutoreleasePoolCleanup(token);
+    }
 
-  for (unsigned i = 0, e = Decls.size(); i != e; ++i)
-    if (Decls[i])
-      EmitRuntimeCall(Decls[i]);
+    for (unsigned i = 0, e = Decls.size(); i != e; ++i)
+      if (Decls[i])
+        EmitRuntimeCall(Decls[i]);
 
-  Scope.ForceCleanup();
+    Scope.ForceCleanup();
 
-  if (ExitBlock) {
-    Builder.CreateBr(ExitBlock);
-    EmitBlock(ExitBlock);
+    if (ExitBlock) {
+      Builder.CreateBr(ExitBlock);
+      EmitBlock(ExitBlock);
+    }
   }
 
   FinishFunction();
@@ -478,18 +527,22 @@
 void CodeGenFunction::GenerateCXXGlobalDtorsFunc(llvm::Function *Fn,
                   const std::vector<std::pair<llvm::WeakVH, llvm::Constant*> >
                                                 &DtorsAndObjects) {
-  StartFunction(GlobalDecl(), getContext().VoidTy, Fn,
-                getTypes().arrangeNullaryFunction(),
-                FunctionArgList(), SourceLocation());
+  {
+    ArtificialLocation AL(*this, Builder);
+    StartFunction(GlobalDecl(), getContext().VoidTy, Fn,
+                  getTypes().arrangeNullaryFunction(), FunctionArgList());
+    // Emit an artificial location for this function.
+    AL.Emit();
 
-  // Emit the dtors, in reverse order from construction.
-  for (unsigned i = 0, e = DtorsAndObjects.size(); i != e; ++i) {
-    llvm::Value *Callee = DtorsAndObjects[e - i - 1].first;
-    llvm::CallInst *CI = Builder.CreateCall(Callee,
-                                            DtorsAndObjects[e - i - 1].second);
-    // Make sure the call and the callee agree on calling convention.
-    if (llvm::Function *F = dyn_cast<llvm::Function>(Callee))
-      CI->setCallingConv(F->getCallingConv());
+    // Emit the dtors, in reverse order from construction.
+    for (unsigned i = 0, e = DtorsAndObjects.size(); i != e; ++i) {
+      llvm::Value *Callee = DtorsAndObjects[e - i - 1].first;
+      llvm::CallInst *CI = Builder.CreateCall(Callee,
+                                          DtorsAndObjects[e - i - 1].second);
+      // Make sure the call and the callee agree on calling convention.
+      if (llvm::Function *F = dyn_cast<llvm::Function>(Callee))
+        CI->setCallingConv(F->getCallingConv());
+    }
   }
 
   FinishFunction();
@@ -501,18 +554,17 @@
     llvm::Constant *addr, QualType type, Destroyer *destroyer,
     bool useEHCleanupForArray, const VarDecl *VD) {
   FunctionArgList args;
-  ImplicitParamDecl dst(0, SourceLocation(), 0, getContext().VoidPtrTy);
+  ImplicitParamDecl dst(getContext(), nullptr, SourceLocation(), nullptr,
+                        getContext().VoidPtrTy);
   args.push_back(&dst);
-  
-  const CGFunctionInfo &FI = 
-    CGM.getTypes().arrangeFunctionDeclaration(getContext().VoidTy, args,
-                                              FunctionType::ExtInfo(),
-                                              /*variadic*/ false);
+
+  const CGFunctionInfo &FI = CGM.getTypes().arrangeFreeFunctionDeclaration(
+      getContext().VoidTy, args, FunctionType::ExtInfo(), /*variadic=*/false);
   llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI);
   llvm::Function *fn = 
     CreateGlobalInitOrDestructFunction(CGM, FTy, "__cxx_global_array_dtor");
 
-  StartFunction(VD, getContext().VoidTy, fn, FI, args, SourceLocation());
+  StartFunction(VD, getContext().VoidTy, fn, FI, args);
 
   emitDestroy(addr, type, destroyer, useEHCleanupForArray);
   
diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp
index 39a992a..1bbda5c 100644
--- a/lib/CodeGen/CGException.cpp
+++ b/lib/CodeGen/CGException.cpp
@@ -17,8 +17,8 @@
 #include "TargetInfo.h"
 #include "clang/AST/StmtCXX.h"
 #include "clang/AST/StmtObjC.h"
+#include "llvm/IR/CallSite.h"
 #include "llvm/IR/Intrinsics.h"
-#include "llvm/Support/CallSite.h"
 
 using namespace clang;
 using namespace CodeGen;
@@ -97,24 +97,6 @@
   return CGM.CreateRuntimeFunction(FTy, "__cxa_call_unexpected");
 }
 
-llvm::Constant *CodeGenFunction::getUnwindResumeFn() {
-  llvm::FunctionType *FTy =
-    llvm::FunctionType::get(VoidTy, Int8PtrTy, /*IsVarArgs=*/false);
-
-  if (CGM.getLangOpts().SjLjExceptions)
-    return CGM.CreateRuntimeFunction(FTy, "_Unwind_SjLj_Resume");
-  return CGM.CreateRuntimeFunction(FTy, "_Unwind_Resume");
-}
-
-llvm::Constant *CodeGenFunction::getUnwindResumeOrRethrowFn() {
-  llvm::FunctionType *FTy =
-    llvm::FunctionType::get(VoidTy, Int8PtrTy, /*IsVarArgs=*/false);
-
-  if (CGM.getLangOpts().SjLjExceptions)
-    return CGM.CreateRuntimeFunction(FTy, "_Unwind_SjLj_Resume_or_Rethrow");
-  return CGM.CreateRuntimeFunction(FTy, "_Unwind_Resume_or_Rethrow");
-}
-
 static llvm::Constant *getTerminateFn(CodeGenModule &CGM) {
   // void __terminate();
 
@@ -164,18 +146,21 @@
   };
 }
 
-const EHPersonality EHPersonality::GNU_C = { "__gcc_personality_v0", 0 };
-const EHPersonality EHPersonality::GNU_C_SJLJ = { "__gcc_personality_sj0", 0 };
-const EHPersonality EHPersonality::NeXT_ObjC = { "__objc_personality_v0", 0 };
-const EHPersonality EHPersonality::GNU_CPlusPlus = { "__gxx_personality_v0", 0};
+const EHPersonality EHPersonality::GNU_C = { "__gcc_personality_v0", nullptr };
 const EHPersonality
-EHPersonality::GNU_CPlusPlus_SJLJ = { "__gxx_personality_sj0", 0 };
+EHPersonality::GNU_C_SJLJ = { "__gcc_personality_sj0", nullptr };
+const EHPersonality
+EHPersonality::NeXT_ObjC = { "__objc_personality_v0", nullptr };
+const EHPersonality
+EHPersonality::GNU_CPlusPlus = { "__gxx_personality_v0", nullptr };
+const EHPersonality
+EHPersonality::GNU_CPlusPlus_SJLJ = { "__gxx_personality_sj0", nullptr };
 const EHPersonality
 EHPersonality::GNU_ObjC = {"__gnu_objc_personality_v0", "objc_exception_throw"};
 const EHPersonality
-EHPersonality::GNU_ObjCXX = { "__gnustep_objcxx_personality_v0", 0 };
+EHPersonality::GNU_ObjCXX = { "__gnustep_objcxx_personality_v0", nullptr };
 const EHPersonality
-EHPersonality::GNUstep_ObjC = { "__gnustep_objc_personality_v0", 0 };
+EHPersonality::GNUstep_ObjC = { "__gnustep_objc_personality_v0", nullptr };
 
 static const EHPersonality &getCPersonality(const LangOptions &L) {
   if (L.SjLjExceptions)
@@ -263,12 +248,9 @@
 /// Check whether a personality function could reasonably be swapped
 /// for a C++ personality function.
 static bool PersonalityHasOnlyCXXUses(llvm::Constant *Fn) {
-  for (llvm::Constant::use_iterator
-         I = Fn->use_begin(), E = Fn->use_end(); I != E; ++I) {
-    llvm::User *User = *I;
-
+  for (llvm::User *U : Fn->users()) {
     // Conditionally white-list bitcasts.
-    if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(User)) {
+    if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(U)) {
       if (CE->getOpcode() != llvm::Instruction::BitCast) return false;
       if (!PersonalityHasOnlyCXXUses(CE))
         return false;
@@ -276,7 +258,7 @@
     }
 
     // Otherwise, it has to be a landingpad instruction.
-    llvm::LandingPadInst *LPI = dyn_cast<llvm::LandingPadInst>(User);
+    llvm::LandingPadInst *LPI = dyn_cast<llvm::LandingPadInst>(U);
     if (!LPI) return false;
 
     for (unsigned I = 0, E = LPI->getNumClauses(); I != E; ++I) {
@@ -363,7 +345,7 @@
   struct FreeException : EHScopeStack::Cleanup {
     llvm::Value *exn;
     FreeException(llvm::Value *exn) : exn(exn) {}
-    void Emit(CodeGenFunction &CGF, Flags flags) {
+    void Emit(CodeGenFunction &CGF, Flags flags) override {
       CGF.EmitNounwindRuntimeCall(getFreeExceptionFn(CGF.CGM), exn);
     }
   };
@@ -421,6 +403,11 @@
 
 void CodeGenFunction::EmitCXXThrowExpr(const CXXThrowExpr *E,
                                        bool KeepInsertionPoint) {
+  if (CGM.getTarget().getTriple().isWindowsMSVCEnvironment()) {
+    ErrorUnsupported(E, "throw expression");
+    return;
+  }
+
   if (!E->getSubExpr()) {
     EmitNoreturnRuntimeCallOrInvoke(getReThrowFn(CGM),
                                     ArrayRef<llvm::Value*>());
@@ -465,7 +452,7 @@
 
   // The address of the destructor.  If the exception type has a
   // trivial destructor (or isn't a record), we just pass null.
-  llvm::Constant *Dtor = 0;
+  llvm::Constant *Dtor = nullptr;
   if (const RecordType *RecordTy = ThrowType->getAs<RecordType>()) {
     CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordTy->getDecl());
     if (!Record->hasTrivialDestructor()) {
@@ -490,10 +477,16 @@
     return;
   
   const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
-  if (FD == 0)
+  if (!FD) {
+    // Check if CapturedDecl is nothrow and create terminate scope for it.
+    if (const CapturedDecl* CD = dyn_cast_or_null<CapturedDecl>(D)) {
+      if (CD->isNothrow())
+        EHStack.pushTerminate();
+    }
     return;
+  }
   const FunctionProtoType *Proto = FD->getType()->getAs<FunctionProtoType>();
-  if (Proto == 0)
+  if (!Proto)
     return;
 
   ExceptionSpecificationType EST = Proto->getExceptionSpecType();
@@ -558,10 +551,16 @@
     return;
   
   const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
-  if (FD == 0)
+  if (!FD) {
+    // Check if CapturedDecl is nothrow and pop terminate scope for it.
+    if (const CapturedDecl* CD = dyn_cast_or_null<CapturedDecl>(D)) {
+      if (CD->isNothrow())
+        EHStack.popTerminate();
+    }
     return;
+  }
   const FunctionProtoType *Proto = FD->getType()->getAs<FunctionProtoType>();
-  if (Proto == 0)
+  if (!Proto)
     return;
 
   ExceptionSpecificationType EST = Proto->getExceptionSpecType();
@@ -577,6 +576,11 @@
 }
 
 void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) {
+  if (CGM.getTarget().getTriple().isWindowsMSVCEnvironment()) {
+    ErrorUnsupported(&S, "try statement");
+    return;
+  }
+
   EnterCXXTryStmt(S);
   EmitStmt(S.getTryBlock());
   ExitCXXTryStmt(S);
@@ -600,7 +604,7 @@
       QualType CaughtType = C->getCaughtType();
       CaughtType = CaughtType.getNonReferenceType().getUnqualifiedType();
 
-      llvm::Value *TypeInfo = 0;
+      llvm::Constant *TypeInfo = nullptr;
       if (CaughtType->isObjCObjectPointerType())
         TypeInfo = CGM.getObjCRuntime().GetEHType(CaughtType);
       else
@@ -678,7 +682,7 @@
   assert(!EHStack.empty());
 
   if (!CGM.getLangOpts().Exceptions)
-    return 0;
+    return nullptr;
 
   // Check the innermost scope for a cached landing pad.  If this is
   // a non-EH cleanup, we'll check enclosing scopes in EmitLandingPad.
@@ -699,56 +703,6 @@
   return LP;
 }
 
-// This code contains a hack to work around a design flaw in
-// LLVM's EH IR which breaks semantics after inlining.  This same
-// hack is implemented in llvm-gcc.
-//
-// The LLVM EH abstraction is basically a thin veneer over the
-// traditional GCC zero-cost design: for each range of instructions
-// in the function, there is (at most) one "landing pad" with an
-// associated chain of EH actions.  A language-specific personality
-// function interprets this chain of actions and (1) decides whether
-// or not to resume execution at the landing pad and (2) if so,
-// provides an integer indicating why it's stopping.  In LLVM IR,
-// the association of a landing pad with a range of instructions is
-// achieved via an invoke instruction, the chain of actions becomes
-// the arguments to the @llvm.eh.selector call, and the selector
-// call returns the integer indicator.  Other than the required
-// presence of two intrinsic function calls in the landing pad,
-// the IR exactly describes the layout of the output code.
-//
-// A principal advantage of this design is that it is completely
-// language-agnostic; in theory, the LLVM optimizers can treat
-// landing pads neutrally, and targets need only know how to lower
-// the intrinsics to have a functioning exceptions system (assuming
-// that platform exceptions follow something approximately like the
-// GCC design).  Unfortunately, landing pads cannot be combined in a
-// language-agnostic way: given selectors A and B, there is no way
-// to make a single landing pad which faithfully represents the
-// semantics of propagating an exception first through A, then
-// through B, without knowing how the personality will interpret the
-// (lowered form of the) selectors.  This means that inlining has no
-// choice but to crudely chain invokes (i.e., to ignore invokes in
-// the inlined function, but to turn all unwindable calls into
-// invokes), which is only semantically valid if every unwind stops
-// at every landing pad.
-//
-// Therefore, the invoke-inline hack is to guarantee that every
-// landing pad has a catch-all.
-enum CleanupHackLevel_t {
-  /// A level of hack that requires that all landing pads have
-  /// catch-alls.
-  CHL_MandatoryCatchall,
-
-  /// A level of hack that requires that all landing pads handle
-  /// cleanups.
-  CHL_MandatoryCleanup,
-
-  /// No hacks at all;  ideal IR generation.
-  CHL_Ideal
-};
-const CleanupHackLevel_t CleanupHackLevel = CHL_MandatoryCleanup;
-
 llvm::BasicBlock *CodeGenFunction::EmitLandingPad() {
   assert(EHStack.requiresLandingPad());
 
@@ -766,11 +720,9 @@
 
   // Save the current IR generation state.
   CGBuilderTy::InsertPoint savedIP = Builder.saveAndClearIP();
-  SourceLocation SavedLocation;
-  if (CGDebugInfo *DI = getDebugInfo()) {
-    SavedLocation = DI->getLocation();
+  SaveAndRestoreLocation AutoRestoreLocation(*this, Builder);
+  if (CGDebugInfo *DI = getDebugInfo())
     DI->EmitLocation(Builder, CurEHLocation);
-  }
 
   const EHPersonality &personality = EHPersonality::get(getLangOpts());
 
@@ -877,11 +829,8 @@
       LPadInst->setCleanup(true);
 
   // Otherwise, signal that we at least have cleanups.
-  } else if (CleanupHackLevel == CHL_MandatoryCatchall || hasCleanup) {
-    if (CleanupHackLevel == CHL_MandatoryCatchall)
-      LPadInst->addClause(getCatchAllValue(*this));
-    else
-      LPadInst->setCleanup(true);
+  } else if (hasCleanup) {
+    LPadInst->setCleanup(true);
   }
 
   assert((LPadInst->getNumClauses() > 0 || LPadInst->isCleanup()) &&
@@ -892,8 +841,6 @@
 
   // Restore the old IR generation state.
   Builder.restoreIP(savedIP);
-  if (CGDebugInfo *DI = getDebugInfo())
-    DI->EmitLocation(Builder, SavedLocation);
 
   return lpad;
 }
@@ -915,7 +862,7 @@
     CallEndCatch(bool MightThrow) : MightThrow(MightThrow) {}
     bool MightThrow;
 
-    void Emit(CodeGenFunction &CGF, Flags flags) {
+    void Emit(CodeGenFunction &CGF, Flags flags) override {
       if (!MightThrow) {
         CGF.EmitNounwindRuntimeCall(getEndCatchFn(CGF.CGM));
         return;
@@ -1244,6 +1191,7 @@
 
   // If the catch was not required, bail out now.
   if (!CatchScope.hasEHBranches()) {
+    CatchScope.clearHandlerBlocks();
     EHStack.popCatch();
     return;
   }
@@ -1294,6 +1242,10 @@
     // Initialize the catch variable and set up the cleanups.
     BeginCatch(*this, C);
 
+    // Emit the PGO counter increment.
+    RegionCounter CatchCnt = getPGORegionCounter(C);
+    CatchCnt.beginRegion(Builder);
+
     // Perform the body of the catch.
     EmitStmt(C->getHandlerBlock());
 
@@ -1320,7 +1272,9 @@
       Builder.CreateBr(ContBB);
   }
 
+  RegionCounter ContCnt = getPGORegionCounter(&S);
   EmitBlock(ContBB);
+  ContCnt.beginRegion(Builder);
 }
 
 namespace {
@@ -1330,7 +1284,7 @@
     CallEndCatchForFinally(llvm::Value *ForEHVar, llvm::Value *EndCatchFn)
       : ForEHVar(ForEHVar), EndCatchFn(EndCatchFn) {}
 
-    void Emit(CodeGenFunction &CGF, Flags flags) {
+    void Emit(CodeGenFunction &CGF, Flags flags) override {
       llvm::BasicBlock *EndCatchBB = CGF.createBasicBlock("finally.endcatch");
       llvm::BasicBlock *CleanupContBB =
         CGF.createBasicBlock("finally.cleanup.cont");
@@ -1357,7 +1311,7 @@
       : Body(Body), ForEHVar(ForEHVar), EndCatchFn(EndCatchFn),
         RethrowFn(RethrowFn), SavedExnVar(SavedExnVar) {}
 
-    void Emit(CodeGenFunction &CGF, Flags flags) {
+    void Emit(CodeGenFunction &CGF, Flags flags) override {
       // Enter a cleanup to call the end-catch function if one was provided.
       if (EndCatchFn)
         CGF.EHStack.pushCleanup<CallEndCatchForFinally>(NormalAndEHCleanup,
@@ -1422,7 +1376,7 @@
                                          llvm::Constant *beginCatchFn,
                                          llvm::Constant *endCatchFn,
                                          llvm::Constant *rethrowFn) {
-  assert((beginCatchFn != 0) == (endCatchFn != 0) &&
+  assert((beginCatchFn != nullptr) == (endCatchFn != nullptr) &&
          "begin/end catch functions not paired");
   assert(rethrowFn && "rethrow function is required");
 
@@ -1437,7 +1391,7 @@
   llvm::FunctionType *rethrowFnTy =
     cast<llvm::FunctionType>(
       cast<llvm::PointerType>(rethrowFn->getType())->getElementType());
-  SavedExnVar = 0;
+  SavedExnVar = nullptr;
   if (rethrowFnTy->getNumParams())
     SavedExnVar = CGF.CreateTempAlloca(CGF.Int8PtrTy, "finally.exn");
 
@@ -1487,7 +1441,7 @@
     CGBuilderTy::InsertPoint savedIP = CGF.Builder.saveAndClearIP();
     CGF.EmitBlock(catchBB);
 
-    llvm::Value *exn = 0;
+    llvm::Value *exn = nullptr;
 
     // If there's a begin-catch function, call it.
     if (BeginCatchFn) {
@@ -1651,54 +1605,34 @@
   // This can always be a call because we necessarily didn't find
   // anything on the EH stack which needs our help.
   const char *RethrowName = Personality.CatchallRethrowFn;
-  if (RethrowName != 0 && !isCleanup) {
+  if (RethrowName != nullptr && !isCleanup) {
     EmitRuntimeCall(getCatchallRethrowFn(CGM, RethrowName),
-                      getExceptionFromSlot())
+                    getExceptionFromSlot())
       ->setDoesNotReturn();
-  } else {
-    switch (CleanupHackLevel) {
-    case CHL_MandatoryCatchall:
-      // In mandatory-catchall mode, we need to use
-      // _Unwind_Resume_or_Rethrow, or whatever the personality's
-      // equivalent is.
-      EmitRuntimeCall(getUnwindResumeOrRethrowFn(),
-                        getExceptionFromSlot())
-        ->setDoesNotReturn();
-      break;
-    case CHL_MandatoryCleanup: {
-      // In mandatory-cleanup mode, we should use 'resume'.
-
-      // Recreate the landingpad's return value for the 'resume' instruction.
-      llvm::Value *Exn = getExceptionFromSlot();
-      llvm::Value *Sel = getSelectorFromSlot();
-
-      llvm::Type *LPadType = llvm::StructType::get(Exn->getType(),
-                                                   Sel->getType(), NULL);
-      llvm::Value *LPadVal = llvm::UndefValue::get(LPadType);
-      LPadVal = Builder.CreateInsertValue(LPadVal, Exn, 0, "lpad.val");
-      LPadVal = Builder.CreateInsertValue(LPadVal, Sel, 1, "lpad.val");
-
-      Builder.CreateResume(LPadVal);
-      Builder.restoreIP(SavedIP);
-      return EHResumeBlock;
-    }
-    case CHL_Ideal:
-      // In an idealized mode where we don't have to worry about the
-      // optimizer combining landing pads, we should just use
-      // _Unwind_Resume (or the personality's equivalent).
-      EmitRuntimeCall(getUnwindResumeFn(), getExceptionFromSlot())
-        ->setDoesNotReturn();
-      break;
-    }
+    Builder.CreateUnreachable();
+    Builder.restoreIP(SavedIP);
+    return EHResumeBlock;
   }
 
-  Builder.CreateUnreachable();
+  // Recreate the landingpad's return value for the 'resume' instruction.
+  llvm::Value *Exn = getExceptionFromSlot();
+  llvm::Value *Sel = getSelectorFromSlot();
 
+  llvm::Type *LPadType = llvm::StructType::get(Exn->getType(),
+                                               Sel->getType(), NULL);
+  llvm::Value *LPadVal = llvm::UndefValue::get(LPadType);
+  LPadVal = Builder.CreateInsertValue(LPadVal, Exn, 0, "lpad.val");
+  LPadVal = Builder.CreateInsertValue(LPadVal, Sel, 1, "lpad.val");
+
+  Builder.CreateResume(LPadVal);
   Builder.restoreIP(SavedIP);
-
   return EHResumeBlock;
 }
 
 void CodeGenFunction::EmitSEHTryStmt(const SEHTryStmt &S) {
   CGM.ErrorUnsupported(&S, "SEH __try");
 }
+
+void CodeGenFunction::EmitSEHLeaveStmt(const SEHLeaveStmt &S) {
+  CGM.ErrorUnsupported(&S, "SEH __leave");
+}
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index be50f4e..512b323 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -21,6 +21,7 @@
 #include "TargetInfo.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclObjC.h"
+#include "clang/AST/Attr.h"
 #include "clang/Frontend/CodeGenOptions.h"
 #include "llvm/ADT/Hashing.h"
 #include "llvm/IR/DataLayout.h"
@@ -53,13 +54,13 @@
 llvm::AllocaInst *CodeGenFunction::CreateTempAlloca(llvm::Type *Ty,
                                                     const Twine &Name) {
   if (!Builder.isNamePreserving())
-    return new llvm::AllocaInst(Ty, 0, "", AllocaInsertPt);
-  return new llvm::AllocaInst(Ty, 0, Name, AllocaInsertPt);
+    return new llvm::AllocaInst(Ty, nullptr, "", AllocaInsertPt);
+  return new llvm::AllocaInst(Ty, nullptr, Name, AllocaInsertPt);
 }
 
 void CodeGenFunction::InitTempAlloca(llvm::AllocaInst *Var,
                                      llvm::Value *Init) {
-  llvm::StoreInst *Store = new llvm::StoreInst(Init, Var);
+  auto *Store = new llvm::StoreInst(Init, Var);
   llvm::BasicBlock *Block = AllocaInsertPt->getParent();
   Block->getInstList().insertAfter(&*AllocaInsertPt, Store);
 }
@@ -85,6 +86,7 @@
 /// EvaluateExprAsBool - Perform the usual unary conversions on the specified
 /// expression and compare the result against zero, returning an Int1Ty value.
 llvm::Value *CodeGenFunction::EvaluateExprAsBool(const Expr *E) {
+  PGO.setCurrentStmt(E);
   if (const MemberPointerType *MPT = E->getType()->getAs<MemberPointerType>()) {
     llvm::Value *MemPtr = EmitScalarExpr(E);
     return CGM.getCXXABI().EmitMemberPointerIsNotNull(*this, MemPtr, MPT);
@@ -240,11 +242,11 @@
     }
   }
 
-  CXXDestructorDecl *ReferenceTemporaryDtor = 0;
+  CXXDestructorDecl *ReferenceTemporaryDtor = nullptr;
   if (const RecordType *RT =
           E->getType()->getBaseElementTypeUnsafe()->getAs<RecordType>()) {
     // Get the destructor for the reference temporary.
-    CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(RT->getDecl());
+    auto *ClassDecl = cast<CXXRecordDecl>(RT->getDecl());
     if (!ClassDecl->hasTrivialDestructor())
       ReferenceTemporaryDtor = ClassDecl->getDestructor();
   }
@@ -322,7 +324,7 @@
     llvm::Value *Object = createReferenceTemporary(*this, M, E);
     LValue RefTempDst = MakeAddrLValue(Object, M->getType());
 
-    if (llvm::GlobalVariable *Var = dyn_cast<llvm::GlobalVariable>(Object)) {
+    if (auto *Var = dyn_cast<llvm::GlobalVariable>(Object)) {
       // We should not have emitted the initializer for this temporary as a
       // constant.
       assert(!Var->hasInitializer());
@@ -342,7 +344,7 @@
   for (unsigned I = 0, N = CommaLHSs.size(); I != N; ++I)
     EmitIgnoredExpr(CommaLHSs[I]);
 
-  if (const OpaqueValueExpr *opaque = dyn_cast<OpaqueValueExpr>(E)) {
+  if (const auto *opaque = dyn_cast<OpaqueValueExpr>(E)) {
     if (opaque->getType()->isRecordType()) {
       assert(Adjustments.empty());
       return EmitOpaqueValueLValue(opaque);
@@ -351,7 +353,7 @@
 
   // Create and initialize the reference temporary.
   llvm::Value *Object = createReferenceTemporary(*this, M, E);
-  if (llvm::GlobalVariable *Var = dyn_cast<llvm::GlobalVariable>(Object)) {
+  if (auto *Var = dyn_cast<llvm::GlobalVariable>(Object)) {
     // If the temporary is a global and has a constant initializer, we may
     // have already initialized it.
     if (!Var->hasInitializer()) {
@@ -389,7 +391,7 @@
     case SubobjectAdjustment::MemberPointerAdjustment: {
       llvm::Value *Ptr = EmitScalarExpr(Adjustment.Ptr.RHS);
       Object = CGM.getCXXABI().EmitMemberDataPointerAddress(
-                    *this, Object, Ptr, Adjustment.Ptr.MPT);
+          *this, E, Object, Ptr, Adjustment.Ptr.MPT);
       break;
     }
     }
@@ -405,7 +407,7 @@
   assert(LV.isSimple());
   llvm::Value *Value = LV.getAddress();
 
-  if (SanitizePerformTypeCheck && !E->getType()->isFunctionType()) {
+  if (sanitizePerformTypeCheck() && !E->getType()->isFunctionType()) {
     // C++11 [dcl.ref]p5 (as amended by core issue 453):
     //   If a glvalue to which a reference is directly bound designates neither
     //   an existing object or function of an appropriate type nor a region of
@@ -439,10 +441,15 @@
   return Builder.CreateMul(B1, KMul);
 }
 
+bool CodeGenFunction::sanitizePerformTypeCheck() const {
+  return SanOpts->Null | SanOpts->Alignment | SanOpts->ObjectSize |
+         SanOpts->Vptr;
+}
+
 void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
                                     llvm::Value *Address,
                                     QualType Ty, CharUnits Alignment) {
-  if (!SanitizePerformTypeCheck)
+  if (!sanitizePerformTypeCheck())
     return;
 
   // Don't check pointers outside the default address space. The null check
@@ -451,10 +458,12 @@
   if (Address->getType()->getPointerAddressSpace())
     return;
 
-  llvm::Value *Cond = 0;
-  llvm::BasicBlock *Done = 0;
+  SanitizerScope SanScope(this);
 
-  if (SanOpts->Null) {
+  llvm::Value *Cond = nullptr;
+  llvm::BasicBlock *Done = nullptr;
+
+  if (SanOpts->Null || TCK == TCK_DowncastPointer) {
     // The glvalue must not be an empty glvalue.
     Cond = Builder.CreateICmpNE(
         Address, llvm::Constant::getNullValue(Address->getType()));
@@ -466,7 +475,7 @@
       llvm::BasicBlock *Rest = createBasicBlock("not.null");
       Builder.CreateCondBr(Cond, Rest, Done);
       EmitBlock(Rest);
-      Cond = 0;
+      Cond = nullptr;
     }
   }
 
@@ -537,44 +546,48 @@
     llvm::raw_svector_ostream Out(MangledName);
     CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty.getUnqualifiedType(),
                                                      Out);
-    llvm::hash_code TypeHash = hash_value(Out.str());
 
-    // Load the vptr, and compute hash_16_bytes(TypeHash, vptr).
-    llvm::Value *Low = llvm::ConstantInt::get(Int64Ty, TypeHash);
-    llvm::Type *VPtrTy = llvm::PointerType::get(IntPtrTy, 0);
-    llvm::Value *VPtrAddr = Builder.CreateBitCast(Address, VPtrTy);
-    llvm::Value *VPtrVal = Builder.CreateLoad(VPtrAddr);
-    llvm::Value *High = Builder.CreateZExt(VPtrVal, Int64Ty);
+    // Blacklist based on the mangled type.
+    if (!CGM.getSanitizerBlacklist().isBlacklistedType(Out.str())) {
+      llvm::hash_code TypeHash = hash_value(Out.str());
 
-    llvm::Value *Hash = emitHash16Bytes(Builder, Low, High);
-    Hash = Builder.CreateTrunc(Hash, IntPtrTy);
+      // Load the vptr, and compute hash_16_bytes(TypeHash, vptr).
+      llvm::Value *Low = llvm::ConstantInt::get(Int64Ty, TypeHash);
+      llvm::Type *VPtrTy = llvm::PointerType::get(IntPtrTy, 0);
+      llvm::Value *VPtrAddr = Builder.CreateBitCast(Address, VPtrTy);
+      llvm::Value *VPtrVal = Builder.CreateLoad(VPtrAddr);
+      llvm::Value *High = Builder.CreateZExt(VPtrVal, Int64Ty);
 
-    // Look the hash up in our cache.
-    const int CacheSize = 128;
-    llvm::Type *HashTable = llvm::ArrayType::get(IntPtrTy, CacheSize);
-    llvm::Value *Cache = CGM.CreateRuntimeVariable(HashTable,
-                                                   "__ubsan_vptr_type_cache");
-    llvm::Value *Slot = Builder.CreateAnd(Hash,
-                                          llvm::ConstantInt::get(IntPtrTy,
-                                                                 CacheSize-1));
-    llvm::Value *Indices[] = { Builder.getInt32(0), Slot };
-    llvm::Value *CacheVal =
-      Builder.CreateLoad(Builder.CreateInBoundsGEP(Cache, Indices));
+      llvm::Value *Hash = emitHash16Bytes(Builder, Low, High);
+      Hash = Builder.CreateTrunc(Hash, IntPtrTy);
 
-    // If the hash isn't in the cache, call a runtime handler to perform the
-    // hard work of checking whether the vptr is for an object of the right
-    // type. This will either fill in the cache and return, or produce a
-    // diagnostic.
-    llvm::Constant *StaticData[] = {
-      EmitCheckSourceLocation(Loc),
-      EmitCheckTypeDescriptor(Ty),
-      CGM.GetAddrOfRTTIDescriptor(Ty.getUnqualifiedType()),
-      llvm::ConstantInt::get(Int8Ty, TCK)
-    };
-    llvm::Value *DynamicData[] = { Address, Hash };
-    EmitCheck(Builder.CreateICmpEQ(CacheVal, Hash),
-              "dynamic_type_cache_miss", StaticData, DynamicData,
-              CRK_AlwaysRecoverable);
+      // Look the hash up in our cache.
+      const int CacheSize = 128;
+      llvm::Type *HashTable = llvm::ArrayType::get(IntPtrTy, CacheSize);
+      llvm::Value *Cache = CGM.CreateRuntimeVariable(HashTable,
+                                                     "__ubsan_vptr_type_cache");
+      llvm::Value *Slot = Builder.CreateAnd(Hash,
+                                            llvm::ConstantInt::get(IntPtrTy,
+                                                                   CacheSize-1));
+      llvm::Value *Indices[] = { Builder.getInt32(0), Slot };
+      llvm::Value *CacheVal =
+        Builder.CreateLoad(Builder.CreateInBoundsGEP(Cache, Indices));
+
+      // If the hash isn't in the cache, call a runtime handler to perform the
+      // hard work of checking whether the vptr is for an object of the right
+      // type. This will either fill in the cache and return, or produce a
+      // diagnostic.
+      llvm::Constant *StaticData[] = {
+        EmitCheckSourceLocation(Loc),
+        EmitCheckTypeDescriptor(Ty),
+        CGM.GetAddrOfRTTIDescriptor(Ty.getUnqualifiedType()),
+        llvm::ConstantInt::get(Int8Ty, TCK)
+      };
+      llvm::Value *DynamicData[] = { Address, Hash };
+      EmitCheck(Builder.CreateICmpEQ(CacheVal, Hash),
+                "dynamic_type_cache_miss", StaticData, DynamicData,
+                CRK_AlwaysRecoverable);
+    }
   }
 
   if (Done) {
@@ -589,7 +602,7 @@
   // For compatibility with existing code, we treat arrays of length 0 or
   // 1 as flexible array members.
   const ArrayType *AT = E->getType()->castAsArrayTypeUnsafe();
-  if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT)) {
+  if (const auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
     if (CAT->getSize().ugt(1))
       return false;
   } else if (!isa<IncompleteArrayType>(AT))
@@ -598,10 +611,10 @@
   E = E->IgnoreParens();
 
   // A flexible array member must be the last member in the class.
-  if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
+  if (const auto *ME = dyn_cast<MemberExpr>(E)) {
     // FIXME: If the base type of the member expr is not FD->getParent(),
     // this should not be treated as a flexible array member access.
-    if (const FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
+    if (const auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
       RecordDecl::field_iterator FI(
           DeclContext::decl_iterator(const_cast<FieldDecl *>(FD)));
       return ++FI == FD->getParent()->field_end();
@@ -623,19 +636,19 @@
 
   Base = Base->IgnoreParens();
 
-  if (const CastExpr *CE = dyn_cast<CastExpr>(Base)) {
+  if (const auto *CE = dyn_cast<CastExpr>(Base)) {
     if (CE->getCastKind() == CK_ArrayToPointerDecay &&
         !isFlexibleArrayMemberExpr(CE->getSubExpr())) {
       IndexedType = CE->getSubExpr()->getType();
       const ArrayType *AT = IndexedType->castAsArrayTypeUnsafe();
-      if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT))
+      if (const auto *CAT = dyn_cast<ConstantArrayType>(AT))
         return CGF.Builder.getInt(CAT->getSize());
-      else if (const VariableArrayType *VAT = dyn_cast<VariableArrayType>(AT))
+      else if (const auto *VAT = dyn_cast<VariableArrayType>(AT))
         return CGF.getVLASize(VAT).first;
     }
   }
 
-  return 0;
+  return nullptr;
 }
 
 void CodeGenFunction::EmitBoundsCheck(const Expr *E, const Expr *Base,
@@ -643,6 +656,7 @@
                                       bool Accessed) {
   assert(SanOpts->ArrayBounds &&
          "should not be called unless adding bounds checks");
+  SanitizerScope SanScope(this);
 
   QualType IndexedType;
   llvm::Value *Bound = getArrayIndexingBound(*this, Base, IndexedType);
@@ -704,7 +718,7 @@
 
 RValue CodeGenFunction::GetUndefRValue(QualType Ty) {
   if (Ty->isVoidType())
-    return RValue::get(0);
+    return RValue::get(nullptr);
 
   switch (getEvaluationKind(Ty)) {
   case TEK_Complex: {
@@ -819,7 +833,7 @@
     return EmitLambdaLValue(cast<LambdaExpr>(E));
 
   case Expr::ExprWithCleanupsClass: {
-    const ExprWithCleanups *cleanups = cast<ExprWithCleanups>(E);
+    const auto *cleanups = cast<ExprWithCleanups>(E);
     enterFullExpression(cleanups);
     RunCleanupsScope Scope(*this);
     return EmitLValue(cleanups->getSubExpr());
@@ -887,8 +901,8 @@
 
   // Otherwise, all object types satisfy this except C++ classes with
   // mutable subobjects or non-trivial copy/destroy behavior.
-  if (const RecordType *RT = dyn_cast<RecordType>(type))
-    if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
+  if (const auto *RT = dyn_cast<RecordType>(type))
+    if (const auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
       if (RD->hasMutableFields() || !RD->isTrivial())
         return false;
 
@@ -910,7 +924,7 @@
 };
 static ConstantEmissionKind checkVarTypeForConstantEmission(QualType type) {
   type = type.getCanonicalType();
-  if (const ReferenceType *ref = dyn_cast<ReferenceType>(type)) {
+  if (const auto *ref = dyn_cast<ReferenceType>(type)) {
     if (isConstantEmittableObjectType(ref->getPointeeType()))
       return CEK_AsValueOrReference;
     return CEK_AsReferenceOnly;
@@ -933,7 +947,7 @@
   ConstantEmissionKind CEK;
   if (isa<ParmVarDecl>(value)) {
     CEK = CEK_None;
-  } else if (VarDecl *var = dyn_cast<VarDecl>(value)) {
+  } else if (auto *var = dyn_cast<VarDecl>(value)) {
     CEK = checkVarTypeForConstantEmission(var->getType());
   } else if (isa<EnumConstantDecl>(value)) {
     CEK = CEK_AsValueOnly;
@@ -1046,7 +1060,7 @@
   llvm::APInt Min, End;
   if (!getRangeForType(*this, Ty, Min, End,
                        CGM.getCodeGenOpts().StrictEnums))
-    return 0;
+    return nullptr;
 
   llvm::MDBuilder MDHelper(getLLVMContext());
   return MDHelper.createRange(Min, End);
@@ -1064,7 +1078,7 @@
     const llvm::Type *EltTy =
     cast<llvm::PointerType>(Addr->getType())->getElementType();
 
-    const llvm::VectorType *VTy = cast<llvm::VectorType>(EltTy);
+    const auto *VTy = cast<llvm::VectorType>(EltTy);
 
     // Handle vectors of size 3, like size 4 for better performance.
     if (VTy->getNumElements() == 3) {
@@ -1118,6 +1132,7 @@
 
   if ((SanOpts->Bool && hasBooleanRepresentation(Ty)) ||
       (SanOpts->Enum && Ty->getAs<EnumType>())) {
+    SanitizerScope SanScope(this);
     llvm::APInt Min, End;
     if (getRangeForType(*this, Ty, Min, End, true)) {
       --End;
@@ -1180,7 +1195,7 @@
   // Handle vectors differently to get better performance.
   if (Ty->isVectorType()) {
     llvm::Type *SrcTy = Value->getType();
-    llvm::VectorType *VecTy = cast<llvm::VectorType>(SrcTy);
+    auto *VecTy = cast<llvm::VectorType>(SrcTy);
     // Handle vec3 special.
     if (VecTy->getNumElements() == 3) {
       llvm::LLVMContext &VMContext = getLLVMContext();
@@ -1201,7 +1216,7 @@
                                           MaskV, "extractVec");
       SrcTy = llvm::VectorType::get(VecTy->getElementType(), 4);
     }
-    llvm::PointerType *DstPtr = cast<llvm::PointerType>(Addr->getType());
+    auto *DstPtr = cast<llvm::PointerType>(Addr->getType());
     if (DstPtr->getElementType() != SrcTy) {
       llvm::Type *MemTy =
       llvm::PointerType::get(SrcTy, DstPtr->getAddressSpace());
@@ -1275,6 +1290,10 @@
   if (LV.isExtVectorElt())
     return EmitLoadOfExtVectorElementLValue(LV);
 
+  // Global Register variables always invoke intrinsics
+  if (LV.isGlobalReg())
+    return EmitLoadOfGlobalRegLValue(LV);
+
   assert(LV.isBitField() && "Unknown LValue type!");
   return EmitLoadOfBitfieldLValue(LV);
 }
@@ -1325,7 +1344,7 @@
   const VectorType *ExprVT = LV.getType()->getAs<VectorType>();
   if (!ExprVT) {
     unsigned InIdx = getAccessedFieldNo(0, Elts);
-    llvm::Value *Elt = llvm::ConstantInt::get(Int32Ty, InIdx);
+    llvm::Value *Elt = llvm::ConstantInt::get(SizeTy, InIdx);
     return RValue::get(Builder.CreateExtractElement(Vec, Elt));
   }
 
@@ -1342,6 +1361,26 @@
   return RValue::get(Vec);
 }
 
+/// @brief Load of global gamed gegisters are always calls to intrinsics.
+RValue CodeGenFunction::EmitLoadOfGlobalRegLValue(LValue LV) {
+  assert((LV.getType()->isIntegerType() || LV.getType()->isPointerType()) &&
+         "Bad type for register variable");
+  llvm::MDNode *RegName = dyn_cast<llvm::MDNode>(LV.getGlobalReg());
+  assert(RegName && "Register LValue is not metadata");
+
+  // We accept integer and pointer types only
+  llvm::Type *OrigTy = CGM.getTypes().ConvertType(LV.getType());
+  llvm::Type *Ty = OrigTy;
+  if (OrigTy->isPointerTy())
+    Ty = CGM.getTypes().getDataLayout().getIntPtrType(OrigTy);
+  llvm::Type *Types[] = { Ty };
+
+  llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::read_register, Types);
+  llvm::Value *Call = Builder.CreateCall(F, RegName);
+  if (OrigTy->isPointerTy())
+    Call = Builder.CreateIntToPtr(Call, OrigTy);
+  return RValue::get(Call);
+}
 
 
 /// EmitStoreThroughLValue - Store the specified rvalue into the specified
@@ -1369,6 +1408,9 @@
     if (Dst.isExtVectorElt())
       return EmitStoreThroughExtVectorComponentLValue(Src, Dst);
 
+    if (Dst.isGlobalReg())
+      return EmitStoreThroughGlobalRegLValue(Src, Dst);
+
     assert(Dst.isBitField() && "Unknown LValue type");
     return EmitStoreThroughBitfieldLValue(Src, Dst);
   }
@@ -1553,6 +1595,12 @@
       for (unsigned i = 0; i != NumDstElts; ++i)
         Mask.push_back(Builder.getInt32(i));
 
+      // When the vector size is odd and .odd or .hi is used, the last element
+      // of the Elts constant array will be one past the size of the vector.
+      // Ignore the last element here, if it is greater than the mask size.
+      if (getAccessedFieldNo(NumSrcElts - 1, Elts) == Mask.size())
+        NumSrcElts--;
+
       // modify when what gets shuffled in
       for (unsigned i = 0; i != NumSrcElts; ++i)
         Mask[getAccessedFieldNo(i, Elts)] = Builder.getInt32(i+NumDstElts);
@@ -1565,7 +1613,7 @@
   } else {
     // If the Src is a scalar (not a vector) it must be updating one element.
     unsigned InIdx = getAccessedFieldNo(0, Elts);
-    llvm::Value *Elt = llvm::ConstantInt::get(Int32Ty, InIdx);
+    llvm::Value *Elt = llvm::ConstantInt::get(SizeTy, InIdx);
     Vec = Builder.CreateInsertElement(Vec, SrcVal, Elt);
   }
 
@@ -1574,7 +1622,28 @@
   Store->setAlignment(Dst.getAlignment().getQuantity());
 }
 
-// setObjCGCLValueClass - sets class of he lvalue for the purpose of
+/// @brief Store of global named registers are always calls to intrinsics.
+void CodeGenFunction::EmitStoreThroughGlobalRegLValue(RValue Src, LValue Dst) {
+  assert((Dst.getType()->isIntegerType() || Dst.getType()->isPointerType()) &&
+         "Bad type for register variable");
+  llvm::MDNode *RegName = dyn_cast<llvm::MDNode>(Dst.getGlobalReg());
+  assert(RegName && "Register LValue is not metadata");
+
+  // We accept integer and pointer types only
+  llvm::Type *OrigTy = CGM.getTypes().ConvertType(Dst.getType());
+  llvm::Type *Ty = OrigTy;
+  if (OrigTy->isPointerTy())
+    Ty = CGM.getTypes().getDataLayout().getIntPtrType(OrigTy);
+  llvm::Type *Types[] = { Ty };
+
+  llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::write_register, Types);
+  llvm::Value *Value = Src.getScalarVal();
+  if (OrigTy->isPointerTy())
+    Value = Builder.CreatePtrToInt(Value, Ty);
+  Builder.CreateCall2(F, RegName, Value);
+}
+
+// setObjCGCLValueClass - sets class of the lvalue for the purpose of
 // generating write-barries API. It is currently a global, ivar,
 // or neither.
 static void setObjCGCLValueClass(const ASTContext &Ctx, const Expr *E,
@@ -1596,14 +1665,14 @@
       }
     }
     LV.setObjCIvar(true);
-    ObjCIvarRefExpr *Exp = cast<ObjCIvarRefExpr>(const_cast<Expr*>(E));
+    auto *Exp = cast<ObjCIvarRefExpr>(const_cast<Expr *>(E));
     LV.setBaseIvarExp(Exp->getBase());
     LV.setObjCArray(E->getType()->isArrayType());
     return;
   }
 
-  if (const DeclRefExpr *Exp = dyn_cast<DeclRefExpr>(E)) {
-    if (const VarDecl *VD = dyn_cast<VarDecl>(Exp->getDecl())) {
+  if (const auto *Exp = dyn_cast<DeclRefExpr>(E)) {
+    if (const auto *VD = dyn_cast<VarDecl>(Exp->getDecl())) {
       if (VD->hasGlobalStorage()) {
         LV.setGlobalObjCRef(true);
         LV.setThreadLocalRef(VD->getTLSKind() != VarDecl::TLS_None);
@@ -1613,12 +1682,12 @@
     return;
   }
 
-  if (const UnaryOperator *Exp = dyn_cast<UnaryOperator>(E)) {
+  if (const auto *Exp = dyn_cast<UnaryOperator>(E)) {
     setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV, IsMemberAccess);
     return;
   }
 
-  if (const ParenExpr *Exp = dyn_cast<ParenExpr>(E)) {
+  if (const auto *Exp = dyn_cast<ParenExpr>(E)) {
     setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV, IsMemberAccess);
     if (LV.isObjCIvar()) {
       // If cast is to a structure pointer, follow gcc's behavior and make it
@@ -1632,27 +1701,27 @@
     return;
   }
 
-  if (const GenericSelectionExpr *Exp = dyn_cast<GenericSelectionExpr>(E)) {
+  if (const auto *Exp = dyn_cast<GenericSelectionExpr>(E)) {
     setObjCGCLValueClass(Ctx, Exp->getResultExpr(), LV);
     return;
   }
 
-  if (const ImplicitCastExpr *Exp = dyn_cast<ImplicitCastExpr>(E)) {
+  if (const auto *Exp = dyn_cast<ImplicitCastExpr>(E)) {
     setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV, IsMemberAccess);
     return;
   }
 
-  if (const CStyleCastExpr *Exp = dyn_cast<CStyleCastExpr>(E)) {
+  if (const auto *Exp = dyn_cast<CStyleCastExpr>(E)) {
     setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV, IsMemberAccess);
     return;
   }
 
-  if (const ObjCBridgedCastExpr *Exp = dyn_cast<ObjCBridgedCastExpr>(E)) {
+  if (const auto *Exp = dyn_cast<ObjCBridgedCastExpr>(E)) {
     setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV, IsMemberAccess);
     return;
   }
 
-  if (const ArraySubscriptExpr *Exp = dyn_cast<ArraySubscriptExpr>(E)) {
+  if (const auto *Exp = dyn_cast<ArraySubscriptExpr>(E)) {
     setObjCGCLValueClass(Ctx, Exp->getBase(), LV);
     if (LV.isObjCIvar() && !LV.isObjCArray())
       // Using array syntax to assigning to what an ivar points to is not
@@ -1665,7 +1734,7 @@
     return;
   }
 
-  if (const MemberExpr *Exp = dyn_cast<MemberExpr>(E)) {
+  if (const auto *Exp = dyn_cast<MemberExpr>(E)) {
     setObjCGCLValueClass(Ctx, Exp->getBase(), LV, true);
     // We don't know if member is an 'ivar', but this flag is looked at
     // only in the context of LV.isObjCIvar().
@@ -1684,11 +1753,16 @@
 
 static LValue EmitGlobalVarDeclLValue(CodeGenFunction &CGF,
                                       const Expr *E, const VarDecl *VD) {
+  QualType T = E->getType();
+
+  // If it's thread_local, emit a call to its wrapper function instead.
+  if (VD->getTLSKind() == VarDecl::TLS_Dynamic)
+    return CGF.CGM.getCXXABI().EmitThreadLocalVarDeclLValue(CGF, VD, T);
+
   llvm::Value *V = CGF.CGM.GetAddrOfGlobalVar(VD);
   llvm::Type *RealVarTy = CGF.getTypes().ConvertTypeForMem(VD->getType());
   V = EmitBitCastOfLValueToProperType(CGF, V, RealVarTy);
   CharUnits Alignment = CGF.getContext().getDeclAlign(VD);
-  QualType T = E->getType();
   LValue LV;
   if (VD->getType()->isReferenceType()) {
     llvm::LoadInst *LI = CGF.Builder.CreateLoad(V);
@@ -1696,7 +1770,7 @@
     V = LI;
     LV = CGF.MakeNaturalAlignAddrLValue(V, T);
   } else {
-    LV = CGF.MakeAddrLValue(V, E->getType(), Alignment);
+    LV = CGF.MakeAddrLValue(V, T, Alignment);
   }
   setObjCGCLValueClass(CGF.getContext(), E, LV);
   return LV;
@@ -1712,7 +1786,7 @@
       // isn't the same as the type of a use.  Correct for this with a
       // bitcast.
       QualType NoProtoType =
-          CGF.getContext().getFunctionNoProtoType(Proto->getResultType());
+          CGF.getContext().getFunctionNoProtoType(Proto->getReturnType());
       NoProtoType = CGF.getContext().getPointerType(NoProtoType);
       V = CGF.Builder.CreateBitCast(V, CGF.ConvertType(NoProtoType));
     }
@@ -1728,14 +1802,44 @@
   return CGF.EmitLValueForField(LV, FD);
 }
 
+/// Named Registers are named metadata pointing to the register name
+/// which will be read from/written to as an argument to the intrinsic
+/// @llvm.read/write_register.
+/// So far, only the name is being passed down, but other options such as
+/// register type, allocation type or even optimization options could be
+/// passed down via the metadata node.
+static LValue EmitGlobalNamedRegister(const VarDecl *VD,
+                                      CodeGenModule &CGM,
+                                      CharUnits Alignment) {
+  SmallString<64> Name("llvm.named.register.");
+  AsmLabelAttr *Asm = VD->getAttr<AsmLabelAttr>();
+  assert(Asm->getLabel().size() < 64-Name.size() &&
+      "Register name too big");
+  Name.append(Asm->getLabel());
+  llvm::NamedMDNode *M =
+    CGM.getModule().getOrInsertNamedMetadata(Name);
+  if (M->getNumOperands() == 0) {
+    llvm::MDString *Str = llvm::MDString::get(CGM.getLLVMContext(),
+                                              Asm->getLabel());
+    llvm::Value *Ops[] = { Str };
+    M->addOperand(llvm::MDNode::get(CGM.getLLVMContext(), Ops));
+  }
+  return LValue::MakeGlobalReg(M->getOperand(0), VD->getType(), Alignment);
+}
+
 LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
   const NamedDecl *ND = E->getDecl();
   CharUnits Alignment = getContext().getDeclAlign(ND);
   QualType T = E->getType();
 
-  // A DeclRefExpr for a reference initialized by a constant expression can
-  // appear without being odr-used. Directly emit the constant initializer.
-  if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
+  if (const auto *VD = dyn_cast<VarDecl>(ND)) {
+    // Global Named registers access via intrinsics only
+    if (VD->getStorageClass() == SC_Register &&
+        VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())
+      return EmitGlobalNamedRegister(VD, CGM, Alignment);
+
+    // A DeclRefExpr for a reference initialized by a constant expression can
+    // appear without being odr-used. Directly emit the constant initializer.
     const Expr *Init = VD->getAnyInitializer(VD);
     if (Init && !isa<ParmVarDecl>(VD) && VD->getType()->isReferenceType() &&
         VD->isUsableInConstantExpressions(getContext()) &&
@@ -1756,19 +1860,15 @@
          "Should not use decl without marking it used!");
 
   if (ND->hasAttr<WeakRefAttr>()) {
-    const ValueDecl *VD = cast<ValueDecl>(ND);
+    const auto *VD = cast<ValueDecl>(ND);
     llvm::Constant *Aliasee = CGM.GetWeakRefReference(VD);
     return MakeAddrLValue(Aliasee, T, Alignment);
   }
 
-  if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
+  if (const auto *VD = dyn_cast<VarDecl>(ND)) {
     // Check if this is a global variable.
-    if (VD->hasLinkage() || VD->isStaticDataMember()) {
-      // If it's thread_local, emit a call to its wrapper function instead.
-      if (VD->getTLSKind() == VarDecl::TLS_Dynamic)
-        return CGM.getCXXABI().EmitThreadLocalDeclRefExpr(*this, E);
+    if (VD->hasLinkage() || VD->isStaticDataMember())
       return EmitGlobalVarDeclLValue(*this, E, VD);
-    }
 
     bool isBlockVariable = VD->hasAttr<BlocksAttr>();
 
@@ -1824,7 +1924,7 @@
     return LV;
   }
 
-  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND))
+  if (const auto *FD = dyn_cast<FunctionDecl>(ND))
     return EmitFunctionDeclLValue(*this, E, FD);
 
   llvm_unreachable("Unhandled DeclRefExpr");
@@ -1901,30 +2001,6 @@
                         E->getType());
 }
 
-static llvm::Constant*
-GetAddrOfConstantWideString(StringRef Str,
-                            const char *GlobalName,
-                            ASTContext &Context,
-                            QualType Ty, SourceLocation Loc,
-                            CodeGenModule &CGM) {
-
-  StringLiteral *SL = StringLiteral::Create(Context,
-                                            Str,
-                                            StringLiteral::Wide,
-                                            /*Pascal = */false,
-                                            Ty, Loc);
-  llvm::Constant *C = CGM.GetConstantArrayFromStringLiteral(SL);
-  llvm::GlobalVariable *GV =
-    new llvm::GlobalVariable(CGM.getModule(), C->getType(),
-                             !CGM.getLangOpts().WritableStrings,
-                             llvm::GlobalValue::PrivateLinkage,
-                             C, GlobalName);
-  const unsigned WideAlignment =
-    Context.getTypeAlignInChars(Ty).getQuantity();
-  GV->setAlignment(WideAlignment);
-  return GV;
-}
-
 static void ConvertUTF8ToWideString(unsigned CharByteWidth, StringRef Source,
                                     SmallString<32>& Target) {
   Target.resize(CharByteWidth * (Source.size() + 1));
@@ -1945,37 +2021,31 @@
   case PredefinedExpr::Function:
   case PredefinedExpr::LFunction:
   case PredefinedExpr::FuncDName:
+  case PredefinedExpr::FuncSig:
   case PredefinedExpr::PrettyFunction: {
     PredefinedExpr::IdentType IdentType = E->getIdentType();
-    std::string GlobalVarName;
+    std::string GVName;
 
+    // FIXME: We should use the string literal mangling for the Microsoft C++
+    // ABI so that strings get merged.
     switch (IdentType) {
     default: llvm_unreachable("Invalid type");
-    case PredefinedExpr::Func:
-      GlobalVarName = "__func__.";
-      break;
-    case PredefinedExpr::Function:
-      GlobalVarName = "__FUNCTION__.";
-      break;
-    case PredefinedExpr::FuncDName:
-      GlobalVarName = "__FUNCDNAME__.";
-      break;
-    case PredefinedExpr::LFunction:
-      GlobalVarName = "L__FUNCTION__.";
-      break;
-    case PredefinedExpr::PrettyFunction:
-      GlobalVarName = "__PRETTY_FUNCTION__.";
-      break;
+    case PredefinedExpr::Func:           GVName = "__func__."; break;
+    case PredefinedExpr::Function:       GVName = "__FUNCTION__."; break;
+    case PredefinedExpr::FuncDName:      GVName = "__FUNCDNAME__."; break;
+    case PredefinedExpr::FuncSig:        GVName = "__FUNCSIG__."; break;
+    case PredefinedExpr::LFunction:      GVName = "L__FUNCTION__."; break;
+    case PredefinedExpr::PrettyFunction: GVName = "__PRETTY_FUNCTION__."; break;
     }
 
     StringRef FnName = CurFn->getName();
     if (FnName.startswith("\01"))
       FnName = FnName.substr(1);
-    GlobalVarName += FnName;
+    GVName += FnName;
 
     // If this is outside of a function use the top level decl.
     const Decl *CurDecl = CurCodeDecl;
-    if (CurDecl == 0 || isa<VarDecl>(CurDecl))
+    if (!CurDecl || isa<VarDecl>(CurDecl))
       CurDecl = getContext().getTranslationUnitDecl();
 
     const Type *ElemType = E->getType()->getArrayElementTypeNoTypeQual();
@@ -1999,18 +2069,14 @@
     if (ElemType->isWideCharType()) {
       SmallString<32> RawChars;
       ConvertUTF8ToWideString(
-          getContext().getTypeSizeInChars(ElemType).getQuantity(),
-          FunctionName, RawChars);
-      C = GetAddrOfConstantWideString(RawChars,
-                                      GlobalVarName.c_str(),
-                                      getContext(),
-                                      E->getType(),
-                                      E->getLocation(),
-                                      CGM);
+          getContext().getTypeSizeInChars(ElemType).getQuantity(), FunctionName,
+          RawChars);
+      StringLiteral *SL = StringLiteral::Create(
+          getContext(), RawChars, StringLiteral::Wide,
+          /*Pascal = */ false, E->getType(), E->getLocation());
+      C = CGM.GetAddrOfConstantStringFromLiteral(SL);
     } else {
-      C = CGM.GetAddrOfConstantCString(FunctionName,
-                                       GlobalVarName.c_str(),
-                                       1);
+      C = CGM.GetAddrOfConstantCString(FunctionName, GVName.c_str(), 1);
     }
     return MakeAddrLValue(C, E->getType());
   }
@@ -2028,7 +2094,7 @@
 /// integer, 1 for a floating point value, and -1 for anything else.
 llvm::Constant *CodeGenFunction::EmitCheckTypeDescriptor(QualType T) {
   // Only emit each type's descriptor once.
-  if (llvm::Constant *C = CGM.getTypeDescriptor(T))
+  if (llvm::Constant *C = CGM.getTypeDescriptorFromMap(T))
     return C;
 
   uint16_t TypeKind = -1;
@@ -2048,7 +2114,7 @@
   SmallString<32> Buffer;
   CGM.getDiags().ConvertArgToString(DiagnosticsEngine::ak_qualtype,
                                     (intptr_t)T.getAsOpaquePtr(),
-                                    0, 0, 0, 0, 0, 0, Buffer,
+                                    StringRef(), StringRef(), None, Buffer,
                                     ArrayRef<intptr_t>());
 
   llvm::Constant *Components[] = {
@@ -2057,15 +2123,14 @@
   };
   llvm::Constant *Descriptor = llvm::ConstantStruct::getAnon(Components);
 
-  llvm::GlobalVariable *GV =
-    new llvm::GlobalVariable(CGM.getModule(), Descriptor->getType(),
-                             /*isConstant=*/true,
-                             llvm::GlobalVariable::PrivateLinkage,
-                             Descriptor);
+  auto *GV = new llvm::GlobalVariable(
+      CGM.getModule(), Descriptor->getType(),
+      /*isConstant=*/true, llvm::GlobalVariable::PrivateLinkage, Descriptor);
   GV->setUnnamedAddr(true);
+  CGM.disableSanitizerForGlobal(GV);
 
   // Remember the descriptor for this type.
-  CGM.setTypeDescriptor(T, GV);
+  CGM.setTypeDescriptorInMap(T, GV);
 
   return GV;
 }
@@ -2106,14 +2171,23 @@
 /// \endcode
 /// For an invalid SourceLocation, the Filename pointer is null.
 llvm::Constant *CodeGenFunction::EmitCheckSourceLocation(SourceLocation Loc) {
-  PresumedLoc PLoc = getContext().getSourceManager().getPresumedLoc(Loc);
+  llvm::Constant *Filename;
+  int Line, Column;
 
-  llvm::Constant *Data[] = {
-    PLoc.isValid() ? CGM.GetAddrOfConstantCString(PLoc.getFilename(), ".src")
-                   : llvm::Constant::getNullValue(Int8PtrTy),
-    Builder.getInt32(PLoc.isValid() ? PLoc.getLine() : 0),
-    Builder.getInt32(PLoc.isValid() ? PLoc.getColumn() : 0)
-  };
+  PresumedLoc PLoc = getContext().getSourceManager().getPresumedLoc(Loc);
+  if (PLoc.isValid()) {
+    auto FilenameGV = CGM.GetAddrOfConstantCString(PLoc.getFilename(), ".src");
+    CGM.disableSanitizerForGlobal(FilenameGV);
+    Filename = FilenameGV;
+    Line = PLoc.getLine();
+    Column = PLoc.getColumn();
+  } else {
+    Filename = llvm::Constant::getNullValue(Int8PtrTy);
+    Line = Column = 0;
+  }
+
+  llvm::Constant *Data[] = {Filename, Builder.getInt32(Line),
+                            Builder.getInt32(Column)};
 
   return llvm::ConstantStruct::getAnon(Data);
 }
@@ -2123,6 +2197,7 @@
                                 ArrayRef<llvm::Value *> DynamicArgs,
                                 CheckRecoverableKind RecoverKind) {
   assert(SanOpts != &SanitizerOptions::Disabled);
+  assert(IsSanitizerScope);
 
   if (CGM.getCodeGenOpts().SanitizeUndefinedTrapOnError) {
     assert (RecoverKind != CRK_AlwaysRecoverable &&
@@ -2145,10 +2220,11 @@
   EmitBlock(Handler);
 
   llvm::Constant *Info = llvm::ConstantStruct::getAnon(StaticArgs);
-  llvm::GlobalValue *InfoPtr =
+  auto *InfoPtr =
       new llvm::GlobalVariable(CGM.getModule(), Info->getType(), false,
                                llvm::GlobalVariable::PrivateLinkage, Info);
   InfoPtr->setUnnamedAddr(true);
+  CGM.disableSanitizerForGlobal(InfoPtr);
 
   SmallVector<llvm::Value *, 4> Args;
   SmallVector<llvm::Type *, 4> ArgTypes;
@@ -2165,9 +2241,9 @@
     ArgTypes.push_back(IntPtrTy);
   }
 
-  bool Recover = (RecoverKind == CRK_AlwaysRecoverable) ||
-                 ((RecoverKind == CRK_Recoverable) &&
-                   CGM.getCodeGenOpts().SanitizeRecover);
+  bool Recover = RecoverKind == CRK_AlwaysRecoverable ||
+                 (RecoverKind == CRK_Recoverable &&
+                  CGM.getCodeGenOpts().SanitizeRecover);
 
   llvm::FunctionType *FnType =
     llvm::FunctionType::get(CGM.VoidTy, ArgTypes, false);
@@ -2179,15 +2255,14 @@
   B.addAttribute(llvm::Attribute::UWTable);
 
   // Checks that have two variants use a suffix to differentiate them
-  bool NeedsAbortSuffix = (RecoverKind != CRK_Unrecoverable) &&
-                           !CGM.getCodeGenOpts().SanitizeRecover;
+  bool NeedsAbortSuffix = RecoverKind != CRK_Unrecoverable &&
+                          !CGM.getCodeGenOpts().SanitizeRecover;
   std::string FunctionName = ("__ubsan_handle_" + CheckName +
                               (NeedsAbortSuffix? "_abort" : "")).str();
-  llvm::Value *Fn =
-    CGM.CreateRuntimeFunction(FnType, FunctionName,
-                              llvm::AttributeSet::get(getLLVMContext(),
-                                              llvm::AttributeSet::FunctionIndex,
-                                                      B));
+  llvm::Value *Fn = CGM.CreateRuntimeFunction(
+      FnType, FunctionName,
+      llvm::AttributeSet::get(getLLVMContext(),
+                              llvm::AttributeSet::FunctionIndex, B));
   llvm::CallInst *HandlerCall = EmitNounwindRuntimeCall(Fn, Args);
   if (Recover) {
     Builder.CreateBr(Cont);
@@ -2224,14 +2299,14 @@
 /// array to pointer, return the array subexpression.
 static const Expr *isSimpleArrayDecayOperand(const Expr *E) {
   // If this isn't just an array->pointer decay, bail out.
-  const CastExpr *CE = dyn_cast<CastExpr>(E);
-  if (CE == 0 || CE->getCastKind() != CK_ArrayToPointerDecay)
-    return 0;
+  const auto *CE = dyn_cast<CastExpr>(E);
+  if (!CE || CE->getCastKind() != CK_ArrayToPointerDecay)
+    return nullptr;
 
   // If this is a decay from variable width array, bail out.
   const Expr *SubExpr = CE->getSubExpr();
   if (SubExpr->getType()->isVariableArrayType())
-    return 0;
+    return nullptr;
 
   return SubExpr;
 }
@@ -2252,7 +2327,6 @@
     // Emit the vector as an lvalue to get its address.
     LValue LHS = EmitLValue(E->getBase());
     assert(LHS.isSimple() && "Can only subscript lvalue vectors here!");
-    Idx = Builder.CreateIntCast(Idx, Int32Ty, IdxSigned, "vidx");
     return LValue::MakeVectorElt(LHS.getAddress(), Idx,
                                  E->getBase()->getType(), LHS.getAlignment());
   }
@@ -2263,7 +2337,7 @@
 
   // We know that the pointer points to a type of the correct size, unless the
   // size is a VLA or Objective-C interface.
-  llvm::Value *Address = 0;
+  llvm::Value *Address = nullptr;
   CharUnits ArrayAlignment;
   if (const VariableArrayType *vla =
         getContext().getAsVariableArrayType(E->getType())) {
@@ -2309,7 +2383,7 @@
     LValue ArrayLV;
     // For simple multidimensional array indexing, set the 'accessed' flag for
     // better bounds-checking of the base expression.
-    if (const ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(Array))
+    if (const auto *ASE = dyn_cast<ArraySubscriptExpr>(Array))
       ArrayLV = EmitArraySubscriptExpr(ASE, /*Accessed*/ true);
     else
       ArrayLV = EmitLValue(Array);
@@ -2436,16 +2510,16 @@
     BaseLV = EmitCheckedLValue(BaseExpr, TCK_MemberAccess);
 
   NamedDecl *ND = E->getMemberDecl();
-  if (FieldDecl *Field = dyn_cast<FieldDecl>(ND)) {
+  if (auto *Field = dyn_cast<FieldDecl>(ND)) {
     LValue LV = EmitLValueForField(BaseLV, Field);
     setObjCGCLValueClass(getContext(), E, LV);
     return LV;
   }
 
-  if (VarDecl *VD = dyn_cast<VarDecl>(ND))
+  if (auto *VD = dyn_cast<VarDecl>(ND))
     return EmitGlobalVarDeclLValue(*this, E, VD);
 
-  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND))
+  if (const auto *FD = dyn_cast<FunctionDecl>(ND))
     return EmitFunctionDeclLValue(*this, E, FD);
 
   llvm_unreachable("Unhandled member declaration!");
@@ -2635,6 +2709,19 @@
   return EmitLValue(E->getInit(0));
 }
 
+/// Emit the operand of a glvalue conditional operator. This is either a glvalue
+/// or a (possibly-parenthesized) throw-expression. If this is a throw, no
+/// LValue is returned and the current block has been terminated.
+static Optional<LValue> EmitLValueOrThrowExpression(CodeGenFunction &CGF,
+                                                    const Expr *Operand) {
+  if (auto *ThrowExpr = dyn_cast<CXXThrowExpr>(Operand->IgnoreParens())) {
+    CGF.EmitCXXThrowExpr(ThrowExpr, /*KeepInsertionPoint*/false);
+    return None;
+  }
+
+  return CGF.EmitLValue(Operand);
+}
+
 LValue CodeGenFunction::
 EmitConditionalOperatorLValue(const AbstractConditionalOperator *expr) {
   if (!expr->isGLValue()) {
@@ -2645,6 +2732,7 @@
   }
 
   OpaqueValueMapping binding(*this, expr);
+  RegionCounter Cnt = getPGORegionCounter(expr);
 
   const Expr *condExpr = expr->getCond();
   bool CondExprBool;
@@ -2652,8 +2740,12 @@
     const Expr *live = expr->getTrueExpr(), *dead = expr->getFalseExpr();
     if (!CondExprBool) std::swap(live, dead);
 
-    if (!ContainsLabel(dead))
+    if (!ContainsLabel(dead)) {
+      // If the true case is live, we need to track its region.
+      if (CondExprBool)
+        Cnt.beginRegion(Builder);
       return EmitLValue(live);
+    }
   }
 
   llvm::BasicBlock *lhsBlock = createBasicBlock("cond.true");
@@ -2661,36 +2753,46 @@
   llvm::BasicBlock *contBlock = createBasicBlock("cond.end");
 
   ConditionalEvaluation eval(*this);
-  EmitBranchOnBoolExpr(condExpr, lhsBlock, rhsBlock);
+  EmitBranchOnBoolExpr(condExpr, lhsBlock, rhsBlock, Cnt.getCount());
 
   // Any temporaries created here are conditional.
   EmitBlock(lhsBlock);
+  Cnt.beginRegion(Builder);
   eval.begin(*this);
-  LValue lhs = EmitLValue(expr->getTrueExpr());
+  Optional<LValue> lhs =
+      EmitLValueOrThrowExpression(*this, expr->getTrueExpr());
   eval.end(*this);
 
-  if (!lhs.isSimple())
+  if (lhs && !lhs->isSimple())
     return EmitUnsupportedLValue(expr, "conditional operator");
 
   lhsBlock = Builder.GetInsertBlock();
-  Builder.CreateBr(contBlock);
+  if (lhs)
+    Builder.CreateBr(contBlock);
 
   // Any temporaries created here are conditional.
   EmitBlock(rhsBlock);
   eval.begin(*this);
-  LValue rhs = EmitLValue(expr->getFalseExpr());
+  Optional<LValue> rhs =
+      EmitLValueOrThrowExpression(*this, expr->getFalseExpr());
   eval.end(*this);
-  if (!rhs.isSimple())
+  if (rhs && !rhs->isSimple())
     return EmitUnsupportedLValue(expr, "conditional operator");
   rhsBlock = Builder.GetInsertBlock();
 
   EmitBlock(contBlock);
 
-  llvm::PHINode *phi = Builder.CreatePHI(lhs.getAddress()->getType(), 2,
-                                         "cond-lvalue");
-  phi->addIncoming(lhs.getAddress(), lhsBlock);
-  phi->addIncoming(rhs.getAddress(), rhsBlock);
-  return MakeAddrLValue(phi, expr->getType());
+  if (lhs && rhs) {
+    llvm::PHINode *phi = Builder.CreatePHI(lhs->getAddress()->getType(),
+                                           2, "cond-lvalue");
+    phi->addIncoming(lhs->getAddress(), lhsBlock);
+    phi->addIncoming(rhs->getAddress(), rhsBlock);
+    return MakeAddrLValue(phi, expr->getType());
+  } else {
+    assert((lhs || rhs) &&
+           "both operands of glvalue conditional are throw-expressions?");
+    return lhs ? *lhs : *rhs;
+  }
 }
 
 /// EmitCastLValue - Casts are never lvalues unless that cast is to a reference
@@ -2738,6 +2840,7 @@
   case CK_ARCReclaimReturnedObject:
   case CK_ARCExtendBlockObject:
   case CK_CopyAndAutoreleaseBlockObject:
+  case CK_AddressSpaceConversion:
     return EmitUnsupportedLValue(E, "unexpected cast lvalue");
 
   case CK_Dependent:
@@ -2754,7 +2857,7 @@
   case CK_Dynamic: {
     LValue LV = EmitLValue(E->getSubExpr());
     llvm::Value *V = LV.getAddress();
-    const CXXDynamicCastExpr *DCE = cast<CXXDynamicCastExpr>(E);
+    const auto *DCE = cast<CXXDynamicCastExpr>(E);
     return MakeAddrLValue(EmitDynamicCast(V, DCE), E->getType());
   }
 
@@ -2770,8 +2873,7 @@
   case CK_DerivedToBase: {
     const RecordType *DerivedClassTy =
       E->getSubExpr()->getType()->getAs<RecordType>();
-    CXXRecordDecl *DerivedClassDecl =
-      cast<CXXRecordDecl>(DerivedClassTy->getDecl());
+    auto *DerivedClassDecl = cast<CXXRecordDecl>(DerivedClassTy->getDecl());
 
     LValue LV = EmitLValue(E->getSubExpr());
     llvm::Value *This = LV.getAddress();
@@ -2788,8 +2890,7 @@
     return EmitAggExprToLValue(E);
   case CK_BaseToDerived: {
     const RecordType *DerivedClassTy = E->getType()->getAs<RecordType>();
-    CXXRecordDecl *DerivedClassDecl =
-      cast<CXXRecordDecl>(DerivedClassTy->getDecl());
+    auto *DerivedClassDecl = cast<CXXRecordDecl>(DerivedClassTy->getDecl());
 
     LValue LV = EmitLValue(E->getSubExpr());
 
@@ -2801,7 +2902,7 @@
 
     // C++11 [expr.static.cast]p2: Behavior is undefined if a downcast is
     // performed and the object is not of the derived type.
-    if (SanitizePerformTypeCheck)
+    if (sanitizePerformTypeCheck())
       EmitTypeCheck(TCK_DowncastReference, E->getExprLoc(),
                     Derived, E->getType());
 
@@ -2809,7 +2910,7 @@
   }
   case CK_LValueBitCast: {
     // This must be a reinterpret_cast (or c-style equivalent).
-    const ExplicitCastExpr *CE = cast<ExplicitCastExpr>(E);
+    const auto *CE = cast<ExplicitCastExpr>(E);
 
     LValue LV = EmitLValue(E->getSubExpr());
     llvm::Value *V = Builder.CreateBitCast(LV.getAddress(),
@@ -2861,6 +2962,10 @@
     SourceLocation Loc = E->getLocStart();
     // Force column info to be generated so we can differentiate
     // multiple call sites on the same line in the debug info.
+    // FIXME: This is insufficient. Two calls coming from the same macro
+    // expansion will still get the same line/column and break debug info. It's
+    // possible that LLVM can be fixed to not rely on this uniqueness, at which
+    // point this workaround can be removed.
     const FunctionDecl* Callee = E->getDirectCallee();
     bool ForceColumnInfo = Callee && Callee->isInlineSpecified();
     DI->EmitLocation(Builder, Loc, ForceColumnInfo);
@@ -2870,10 +2975,10 @@
   if (E->getCallee()->getType()->isBlockPointerType())
     return EmitBlockCallExpr(E, ReturnValue);
 
-  if (const CXXMemberCallExpr *CE = dyn_cast<CXXMemberCallExpr>(E))
+  if (const auto *CE = dyn_cast<CXXMemberCallExpr>(E))
     return EmitCXXMemberCallExpr(CE, ReturnValue);
 
-  if (const CUDAKernelCallExpr *CE = dyn_cast<CUDAKernelCallExpr>(E))
+  if (const auto *CE = dyn_cast<CUDAKernelCallExpr>(E))
     return EmitCUDAKernelCallExpr(CE, ReturnValue);
 
   const Decl *TargetDecl = E->getCalleeDecl();
@@ -2882,12 +2987,12 @@
       return EmitBuiltinExpr(FD, builtinID, E);
   }
 
-  if (const CXXOperatorCallExpr *CE = dyn_cast<CXXOperatorCallExpr>(E))
+  if (const auto *CE = dyn_cast<CXXOperatorCallExpr>(E))
     if (const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(TargetDecl))
       return EmitCXXOperatorMemberCallExpr(CE, MD, ReturnValue);
 
-  if (const CXXPseudoDestructorExpr *PseudoDtor
-          = dyn_cast<CXXPseudoDestructorExpr>(E->getCallee()->IgnoreParens())) {
+  if (const auto *PseudoDtor =
+          dyn_cast<CXXPseudoDestructorExpr>(E->getCallee()->IgnoreParens())) {
     QualType DestroyedType = PseudoDtor->getDestroyedType();
     if (getLangOpts().ObjCAutoRefCount &&
         DestroyedType->isObjCLifetimeType() &&
@@ -2897,7 +3002,7 @@
       //   If the pseudo-expression names a retainable object with weak or
       //   strong lifetime, the object shall be released.
       Expr *BaseExpr = PseudoDtor->getBase();
-      llvm::Value *BaseValue = NULL;
+      llvm::Value *BaseValue = nullptr;
       Qualifiers BaseQuals;
 
       // If this is s.x, emit s as an lvalue. If it is s->x, emit s as a scalar.
@@ -2937,7 +3042,7 @@
       EmitScalarExpr(E->getCallee());
     }
 
-    return RValue::get(0);
+    return RValue::get(nullptr);
   }
 
   llvm::Value *Callee = EmitScalarExpr(E->getCallee());
@@ -3055,7 +3160,7 @@
   if (!RV.isScalar())
     return MakeAddrLValue(RV.getAggregateAddr(), E->getType());
 
-  assert(E->getMethodDecl()->getResultType()->isReferenceType() &&
+  assert(E->getMethodDecl()->getReturnType()->isReferenceType() &&
          "Can't have a scalar return unless the return type is a "
          "reference type!");
 
@@ -3083,7 +3188,7 @@
 
 LValue CodeGenFunction::EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E) {
   // FIXME: A lot of the code below could be shared with EmitMemberExpr.
-  llvm::Value *BaseValue = 0;
+  llvm::Value *BaseValue = nullptr;
   const Expr *BaseExpr = E->getBase();
   Qualifiers BaseQuals;
   QualType ObjectTy;
@@ -3125,11 +3230,15 @@
 
   CalleeType = getContext().getCanonicalType(CalleeType);
 
-  const FunctionType *FnType
-    = cast<FunctionType>(cast<PointerType>(CalleeType)->getPointeeType());
+  const auto *FnType =
+      cast<FunctionType>(cast<PointerType>(CalleeType)->getPointeeType());
 
   // Force column info to differentiate multiple inlined call sites on
   // the same line, analoguous to EmitCallExpr.
+  // FIXME: This is insufficient. Two calls coming from the same macro expansion
+  // will still get the same line/column and break debug info. It's possible
+  // that LLVM can be fixed to not rely on this uniqueness, at which point this
+  // workaround can be removed.
   bool ForceColumnInfo = false;
   if (const FunctionDecl* FD = dyn_cast_or_null<const FunctionDecl>(TargetDecl))
     ForceColumnInfo = FD->isInlineSpecified();
@@ -3138,6 +3247,7 @@
       (!TargetDecl || !isa<FunctionDecl>(TargetDecl))) {
     if (llvm::Constant *PrefixSig =
             CGM.getTargetCodeGenInfo().getUBSanFunctionSignature(CGM)) {
+      SanitizerScope SanScope(this);
       llvm::Constant *FTRTTIConst =
           CGM.GetAddrOfRTTIDescriptor(QualType(FnType, 0), /*ForEH=*/true);
       llvm::Type *PrefixStructTyElems[] = {
@@ -3225,8 +3335,8 @@
   const MemberPointerType *MPT
     = E->getRHS()->getType()->getAs<MemberPointerType>();
 
-  llvm::Value *AddV =
-    CGM.getCXXABI().EmitMemberDataPointerAddress(*this, BaseV, OffsetV, MPT);
+  llvm::Value *AddV = CGM.getCXXABI().EmitMemberDataPointerAddress(
+      *this, E, BaseV, OffsetV, MPT);
 
   return MakeAddrLValue(AddV, MPT->getPointeeType());
 }
@@ -3282,7 +3392,7 @@
 
     // If this semantic expression is an opaque value, bind it
     // to the result of its source expression.
-    if (const OpaqueValueExpr *ov = dyn_cast<OpaqueValueExpr>(semantic)) {
+    if (const auto *ov = dyn_cast<OpaqueValueExpr>(semantic)) {
 
       // If this is the result expression, we may need to evaluate
       // directly into the slot.
diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp
index ea366dd..4cf94c0 100644
--- a/lib/CodeGen/CGExprAgg.cpp
+++ b/lib/CodeGen/CGExprAgg.cpp
@@ -370,6 +370,29 @@
   }
 }
 
+/// \brief Determine if E is a trivial array filler, that is, one that is
+/// equivalent to zero-initialization.
+static bool isTrivialFiller(Expr *E) {
+  if (!E)
+    return true;
+
+  if (isa<ImplicitValueInitExpr>(E))
+    return true;
+
+  if (auto *ILE = dyn_cast<InitListExpr>(E)) {
+    if (ILE->getNumInits())
+      return false;
+    return isTrivialFiller(ILE->getArrayFiller());
+  }
+
+  if (auto *Cons = dyn_cast_or_null<CXXConstructExpr>(E))
+    return Cons->getConstructor()->isDefaultConstructor() &&
+           Cons->getConstructor()->isTrivial();
+
+  // FIXME: Are there other cases where we can avoid emitting an initializer?
+  return false;
+}
+
 /// \brief Emit initialization of an array from an initializer list.
 void AggExprEmitter::EmitArrayInit(llvm::Value *DestPtr, llvm::ArrayType *AType,
                                    QualType elementType, InitListExpr *E) {
@@ -389,9 +412,9 @@
   // already-constructed members if an initializer throws.
   // For that, we'll need an EH cleanup.
   QualType::DestructionKind dtorKind = elementType.isDestructedType();
-  llvm::AllocaInst *endOfInit = 0;
+  llvm::AllocaInst *endOfInit = nullptr;
   EHScopeStack::stable_iterator cleanup;
-  llvm::Instruction *cleanupDominator = 0;
+  llvm::Instruction *cleanupDominator = nullptr;
   if (CGF.needsEHCleanup(dtorKind)) {
     // In principle we could tell the cleanup where we are more
     // directly, but the control flow can get so varied here that it
@@ -435,14 +458,8 @@
   }
 
   // Check whether there's a non-trivial array-fill expression.
-  // Note that this will be a CXXConstructExpr even if the element
-  // type is an array (or array of array, etc.) of class type.
   Expr *filler = E->getArrayFiller();
-  bool hasTrivialFiller = true;
-  if (CXXConstructExpr *cons = dyn_cast_or_null<CXXConstructExpr>(filler)) {
-    assert(cons->getConstructor()->isDefaultConstructor());
-    hasTrivialFiller = cons->getConstructor()->isTrivial();
-  }
+  bool hasTrivialFiller = isTrivialFiller(filler);
 
   // Any remaining elements need to be zero-initialized, possibly
   // using the filler expression.  We can skip this if the we're
@@ -539,7 +556,7 @@
       if (castE->getCastKind() == CK_NoOp)
         continue;
     }
-    return 0;
+    return nullptr;
   }
 }
 
@@ -713,6 +730,7 @@
   case CK_CopyAndAutoreleaseBlockObject:
   case CK_BuiltinFnToFnPtr:
   case CK_ZeroToOCLEvent:
+  case CK_AddressSpaceConversion:
     llvm_unreachable("cast kind invalid for aggregate types");
   }
 }
@@ -891,14 +909,16 @@
   // Bind the common expression if necessary.
   CodeGenFunction::OpaqueValueMapping binding(CGF, E);
 
+  RegionCounter Cnt = CGF.getPGORegionCounter(E);
   CodeGenFunction::ConditionalEvaluation eval(CGF);
-  CGF.EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock);
+  CGF.EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock, Cnt.getCount());
 
   // Save whether the destination's lifetime is externally managed.
   bool isExternallyDestructed = Dest.isExternallyDestructed();
 
   eval.begin(CGF);
   CGF.EmitBlock(LHSBlock);
+  Cnt.beginRegion(Builder);
   Visit(E->getTrueExpr());
   eval.end(CGF);
 
@@ -1041,7 +1061,7 @@
     return;
   case TEK_Scalar:
     if (LV.isSimple()) {
-      CGF.EmitScalarInit(E, /*D=*/0, LV, /*Captured=*/false);
+      CGF.EmitScalarInit(E, /*D=*/nullptr, LV, /*Captured=*/false);
     } else {
       CGF.EmitStoreThroughLValue(RValue::get(CGF.EmitScalarExpr(E)), LV);
     }
@@ -1117,6 +1137,16 @@
     return;
   }
 
+  if (E->getType()->isAtomicType()) {
+    // An _Atomic(T) object can be list-initialized from an expression
+    // of the same type.
+    assert(E->getNumInits() == 1 &&
+           CGF.getContext().hasSameUnqualifiedType(E->getInit(0)->getType(),
+                                                   E->getType()) &&
+           "unexpected list initialization for atomic object");
+    return Visit(E->getInit(0));
+  }
+
   assert(E->getType()->isRecordType() && "Only support structs/unions here!");
 
   // Do struct initialization; this code just sets each individual member
@@ -1138,9 +1168,7 @@
 #ifndef NDEBUG
       // Make sure that it's really an empty and not a failure of
       // semantic analysis.
-      for (RecordDecl::field_iterator Field = record->field_begin(),
-                                   FieldEnd = record->field_end();
-           Field != FieldEnd; ++Field)
+      for (const auto *Field : record->fields())
         assert(Field->isUnnamedBitfield() && "Only unnamed bitfields allowed");
 #endif
       return;
@@ -1164,14 +1192,12 @@
   // We'll need to enter cleanup scopes in case any of the member
   // initializers throw an exception.
   SmallVector<EHScopeStack::stable_iterator, 16> cleanups;
-  llvm::Instruction *cleanupDominator = 0;
+  llvm::Instruction *cleanupDominator = nullptr;
 
   // Here we iterate over the fields; this makes it simpler to both
   // default-initialize fields and skip over unnamed fields.
   unsigned curInitIndex = 0;
-  for (RecordDecl::field_iterator field = record->field_begin(),
-                               fieldEnd = record->field_end();
-       field != fieldEnd; ++field) {
+  for (const auto *field : record->fields()) {
     // We're done once we hit the flexible array member.
     if (field->getType()->isIncompleteArrayType())
       break;
@@ -1188,7 +1214,7 @@
       break;
     
 
-    LValue LV = CGF.EmitLValueForFieldInitialization(DestLV, *field);
+    LValue LV = CGF.EmitLValueForFieldInitialization(DestLV, field);
     // We never generate write-barries for initialized fields.
     LV.setNonGC(true);
     
@@ -1253,7 +1279,7 @@
   // If this is an initlist expr, sum up the size of sizes of the (present)
   // elements.  If this is something weird, assume the whole thing is non-zero.
   const InitListExpr *ILE = dyn_cast<InitListExpr>(E);
-  if (ILE == 0 || !CGF.getTypes().isZeroInitializable(ILE->getType()))
+  if (!ILE || !CGF.getTypes().isZeroInitializable(ILE->getType()))
     return CGF.getContext().getTypeSizeInChars(E->getType());
   
   // InitListExprs for structs have to be handled carefully.  If there are
@@ -1265,8 +1291,7 @@
       CharUnits NumNonZeroBytes = CharUnits::Zero();
       
       unsigned ILEElement = 0;
-      for (RecordDecl::field_iterator Field = SD->field_begin(),
-           FieldEnd = SD->field_end(); Field != FieldEnd; ++Field) {
+      for (const auto *Field : SD->fields()) {
         // We're done once we hit the flexible array member or run out of
         // InitListExpr elements.
         if (Field->getType()->isIncompleteArrayType() ||
@@ -1303,7 +1328,8 @@
                                      CodeGenFunction &CGF) {
   // If the slot is already known to be zeroed, nothing to do.  Don't mess with
   // volatile stores.
-  if (Slot.isZeroed() || Slot.isVolatile() || Slot.getAddr() == 0) return;
+  if (Slot.isZeroed() || Slot.isVolatile() || Slot.getAddr() == nullptr)
+    return;
 
   // C++ objects with a user-declared constructor don't need zero'ing.
   if (CGF.getLangOpts().CPlusPlus)
@@ -1350,7 +1376,7 @@
 void CodeGenFunction::EmitAggExpr(const Expr *E, AggValueSlot Slot) {
   assert(E && hasAggregateEvaluationKind(E->getType()) &&
          "Invalid aggregate expression to emit");
-  assert((Slot.getAddr() != 0 || Slot.isIgnored()) &&
+  assert((Slot.getAddr() != nullptr || Slot.isIgnored()) &&
          "slot has bits but no address");
 
   // Optimize the slot if possible.
@@ -1470,10 +1496,10 @@
   // memcpy, as well as the TBAA tags for the members of the struct, in case
   // the optimizer wishes to expand it in to scalar memory operations.
   llvm::MDNode *TBAAStructTag = CGM.getTBAAStructInfo(Ty);
-  
+
   Builder.CreateMemCpy(DestPtr, SrcPtr,
                        llvm::ConstantInt::get(IntPtrTy, 
                                               TypeInfo.first.getQuantity()),
                        alignment.getQuantity(), isVolatile,
-                       /*TBAATag=*/0, TBAAStructTag);
+                       /*TBAATag=*/nullptr, TBAAStructTag);
 }
diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp
index a748620..7aacee4 100644
--- a/lib/CodeGen/CGExprCXX.cpp
+++ b/lib/CodeGen/CGExprCXX.cpp
@@ -18,8 +18,8 @@
 #include "CGObjCRuntime.h"
 #include "clang/CodeGen/CGFunctionInfo.h"
 #include "clang/Frontend/CodeGenOptions.h"
+#include "llvm/IR/CallSite.h"
 #include "llvm/IR/Intrinsics.h"
-#include "llvm/Support/CallSite.h"
 
 using namespace clang;
 using namespace CodeGen;
@@ -95,7 +95,7 @@
   const Expr *Base = ME->getBase();
   bool CanUseVirtualCall = MD->isVirtual() && !ME->hasQualifier();
 
-  const CXXMethodDecl *DevirtualizedMethod = NULL;
+  const CXXMethodDecl *DevirtualizedMethod = nullptr;
   if (CanUseVirtualCall && CanDevirtualizeMemberFunctionCall(Base, MD)) {
     const CXXRecordDecl *BestDynamicDecl = Base->getBestDynamicClassType();
     DevirtualizedMethod = MD->getCorrespondingMethodInClass(BestDynamicDecl);
@@ -111,7 +111,7 @@
       // one or the one of the full expression, we would have to build
       // a derived-to-base cast to compute the correct this pointer, but
       // we don't have support for that yet, so do a virtual call.
-      DevirtualizedMethod = NULL;
+      DevirtualizedMethod = nullptr;
     }
     // If the return types are not the same, this might be a case where more
     // code needs to run to compensate for it. For example, the derived
@@ -119,9 +119,9 @@
     // type of MD and has a prefix.
     // For now we just avoid devirtualizing these covariant cases.
     if (DevirtualizedMethod &&
-        DevirtualizedMethod->getResultType().getCanonicalType() !=
-        MD->getResultType().getCanonicalType())
-      DevirtualizedMethod = NULL;
+        DevirtualizedMethod->getReturnType().getCanonicalType() !=
+            MD->getReturnType().getCanonicalType())
+      DevirtualizedMethod = nullptr;
   }
 
   llvm::Value *This;
@@ -132,10 +132,10 @@
 
 
   if (MD->isTrivial()) {
-    if (isa<CXXDestructorDecl>(MD)) return RValue::get(0);
+    if (isa<CXXDestructorDecl>(MD)) return RValue::get(nullptr);
     if (isa<CXXConstructorDecl>(MD) && 
         cast<CXXConstructorDecl>(MD)->isDefaultConstructor())
-      return RValue::get(0);
+      return RValue::get(nullptr);
 
     if (MD->isCopyAssignmentOperator() || MD->isMoveAssignmentOperator()) {
       // We don't like to generate the trivial copy/move assignment operator
@@ -158,7 +158,7 @@
 
   // Compute the function type we're calling.
   const CXXMethodDecl *CalleeDecl = DevirtualizedMethod ? DevirtualizedMethod : MD;
-  const CGFunctionInfo *FInfo = 0;
+  const CGFunctionInfo *FInfo = nullptr;
   if (const CXXDestructorDecl *Dtor = dyn_cast<CXXDestructorDecl>(CalleeDecl))
     FInfo = &CGM.getTypes().arrangeCXXDestructor(Dtor,
                                                  Dtor_Complete);
@@ -199,9 +199,9 @@
         Callee = CGM.GetAddrOfFunction(GlobalDecl(DDtor, Dtor_Complete), Ty);
       }
       EmitCXXMemberCall(MD, CE->getExprLoc(), Callee, ReturnValue, This,
-                        /*ImplicitParam=*/0, QualType(), 0, 0);
+                        /*ImplicitParam=*/nullptr, QualType(), nullptr,nullptr);
     }
-    return RValue::get(0);
+    return RValue::get(nullptr);
   }
   
   if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(MD)) {
@@ -220,11 +220,13 @@
     }
   }
 
-  if (MD->isVirtual())
-    This = CGM.getCXXABI().adjustThisArgumentForVirtualCall(*this, MD, This);
+  if (MD->isVirtual()) {
+    This = CGM.getCXXABI().adjustThisArgumentForVirtualFunctionCall(
+        *this, MD, This, UseVirtualCall);
+  }
 
   return EmitCXXMemberCall(MD, CE->getExprLoc(), Callee, ReturnValue, This,
-                           /*ImplicitParam=*/0, QualType(),
+                           /*ImplicitParam=*/nullptr, QualType(),
                            CE->arg_begin(), CE->arg_end());
 }
 
@@ -260,7 +262,7 @@
 
   // Ask the ABI to load the callee.  Note that This is modified.
   llvm::Value *Callee =
-    CGM.getCXXABI().EmitLoadOfMemberFunctionPointer(*this, This, MemFnPtr, MPT);
+    CGM.getCXXABI().EmitLoadOfMemberFunctionPointer(*this, BO, This, MemFnPtr, MPT);
   
   CallArgList Args;
 
@@ -297,7 +299,7 @@
 
   llvm::Value *Callee = EmitCXXOperatorMemberCallee(E, MD, This);
   return EmitCXXMemberCall(MD, E->getExprLoc(), Callee, ReturnValue, This,
-                           /*ImplicitParam=*/0, QualType(),
+                           /*ImplicitParam=*/nullptr, QualType(),
                            E->arg_begin() + 1, E->arg_end());
 }
 
@@ -316,7 +318,7 @@
 
   const ASTRecordLayout &Layout = CGF.getContext().getASTRecordLayout(Base);
   CharUnits Size = Layout.getNonVirtualSize();
-  CharUnits Align = Layout.getNonVirtualAlign();
+  CharUnits Align = Layout.getNonVirtualAlignment();
 
   llvm::Value *SizeVal = CGF.CGM.getSize(Size);
 
@@ -584,7 +586,7 @@
     //      size := sizeWithoutCookie + cookieSize
     //    and check whether it overflows.
 
-    llvm::Value *hasOverflow = 0;
+    llvm::Value *hasOverflow = nullptr;
 
     // If numElementsWidth > sizeWidth, then one way or another, we're
     // going to have to do a comparison for (2), and this happens to
@@ -720,12 +722,12 @@
 
 static void StoreAnyExprIntoOneUnit(CodeGenFunction &CGF, const Expr *Init,
                                     QualType AllocType, llvm::Value *NewPtr) {
-
+  // FIXME: Refactor with EmitExprAsInit.
   CharUnits Alignment = CGF.getContext().getTypeAlignInChars(AllocType);
   switch (CGF.getEvaluationKind(AllocType)) {
   case TEK_Scalar:
-    CGF.EmitScalarInit(Init, 0, CGF.MakeAddrLValue(NewPtr, AllocType,
-                                                   Alignment),
+    CGF.EmitScalarInit(Init, nullptr, CGF.MakeAddrLValue(NewPtr, AllocType,
+                                                         Alignment),
                        false);
     return;
   case TEK_Complex:
@@ -747,169 +749,249 @@
 }
 
 void
-CodeGenFunction::EmitNewArrayInitializer(const CXXNewExpr *E, 
-                                         QualType elementType,
-                                         llvm::Value *beginPtr,
-                                         llvm::Value *numElements) {
+CodeGenFunction::EmitNewArrayInitializer(const CXXNewExpr *E,
+                                         QualType ElementType,
+                                         llvm::Value *BeginPtr,
+                                         llvm::Value *NumElements,
+                                         llvm::Value *AllocSizeWithoutCookie) {
+  // If we have a type with trivial initialization and no initializer,
+  // there's nothing to do.
   if (!E->hasInitializer())
-    return; // We have a POD type.
+    return;
 
-  llvm::Value *explicitPtr = beginPtr;
-  // Find the end of the array, hoisted out of the loop.
-  llvm::Value *endPtr =
-    Builder.CreateInBoundsGEP(beginPtr, numElements, "array.end");
+  llvm::Value *CurPtr = BeginPtr;
 
-  unsigned initializerElements = 0;
+  unsigned InitListElements = 0;
 
   const Expr *Init = E->getInitializer();
-  llvm::AllocaInst *endOfInit = 0;
-  QualType::DestructionKind dtorKind = elementType.isDestructedType();
-  EHScopeStack::stable_iterator cleanup;
-  llvm::Instruction *cleanupDominator = 0;
+  llvm::AllocaInst *EndOfInit = nullptr;
+  QualType::DestructionKind DtorKind = ElementType.isDestructedType();
+  EHScopeStack::stable_iterator Cleanup;
+  llvm::Instruction *CleanupDominator = nullptr;
+
   // If the initializer is an initializer list, first do the explicit elements.
   if (const InitListExpr *ILE = dyn_cast<InitListExpr>(Init)) {
-    initializerElements = ILE->getNumInits();
+    InitListElements = ILE->getNumInits();
 
-    // Enter a partial-destruction cleanup if necessary.
-    if (needsEHCleanup(dtorKind)) {
-      // In principle we could tell the cleanup where we are more
+    // If this is a multi-dimensional array new, we will initialize multiple
+    // elements with each init list element.
+    QualType AllocType = E->getAllocatedType();
+    if (const ConstantArrayType *CAT = dyn_cast_or_null<ConstantArrayType>(
+            AllocType->getAsArrayTypeUnsafe())) {
+      unsigned AS = CurPtr->getType()->getPointerAddressSpace();
+      llvm::Type *AllocPtrTy = ConvertTypeForMem(AllocType)->getPointerTo(AS);
+      CurPtr = Builder.CreateBitCast(CurPtr, AllocPtrTy);
+      InitListElements *= getContext().getConstantArrayElementCount(CAT);
+    }
+
+    // Enter a partial-destruction Cleanup if necessary.
+    if (needsEHCleanup(DtorKind)) {
+      // In principle we could tell the Cleanup where we are more
       // directly, but the control flow can get so varied here that it
       // would actually be quite complex.  Therefore we go through an
       // alloca.
-      endOfInit = CreateTempAlloca(beginPtr->getType(), "array.endOfInit");
-      cleanupDominator = Builder.CreateStore(beginPtr, endOfInit);
-      pushIrregularPartialArrayCleanup(beginPtr, endOfInit, elementType,
-                                       getDestroyer(dtorKind));
-      cleanup = EHStack.stable_begin();
+      EndOfInit = CreateTempAlloca(BeginPtr->getType(), "array.init.end");
+      CleanupDominator = Builder.CreateStore(BeginPtr, EndOfInit);
+      pushIrregularPartialArrayCleanup(BeginPtr, EndOfInit, ElementType,
+                                       getDestroyer(DtorKind));
+      Cleanup = EHStack.stable_begin();
     }
 
     for (unsigned i = 0, e = ILE->getNumInits(); i != e; ++i) {
       // Tell the cleanup that it needs to destroy up to this
       // element.  TODO: some of these stores can be trivially
       // observed to be unnecessary.
-      if (endOfInit) Builder.CreateStore(explicitPtr, endOfInit);
-      StoreAnyExprIntoOneUnit(*this, ILE->getInit(i), elementType, explicitPtr);
-      explicitPtr =Builder.CreateConstGEP1_32(explicitPtr, 1, "array.exp.next");
+      if (EndOfInit)
+        Builder.CreateStore(Builder.CreateBitCast(CurPtr, BeginPtr->getType()),
+                            EndOfInit);
+      // FIXME: If the last initializer is an incomplete initializer list for
+      // an array, and we have an array filler, we can fold together the two
+      // initialization loops.
+      StoreAnyExprIntoOneUnit(*this, ILE->getInit(i),
+                              ILE->getInit(i)->getType(), CurPtr);
+      CurPtr = Builder.CreateConstInBoundsGEP1_32(CurPtr, 1, "array.exp.next");
     }
 
     // The remaining elements are filled with the array filler expression.
     Init = ILE->getArrayFiller();
+
+    // Extract the initializer for the individual array elements by pulling
+    // out the array filler from all the nested initializer lists. This avoids
+    // generating a nested loop for the initialization.
+    while (Init && Init->getType()->isConstantArrayType()) {
+      auto *SubILE = dyn_cast<InitListExpr>(Init);
+      if (!SubILE)
+        break;
+      assert(SubILE->getNumInits() == 0 && "explicit inits in array filler?");
+      Init = SubILE->getArrayFiller();
+    }
+
+    // Switch back to initializing one base element at a time.
+    CurPtr = Builder.CreateBitCast(CurPtr, BeginPtr->getType());
   }
 
-  // Create the continuation block.
-  llvm::BasicBlock *contBB = createBasicBlock("new.loop.end");
+  // Attempt to perform zero-initialization using memset.
+  auto TryMemsetInitialization = [&]() -> bool {
+    // FIXME: If the type is a pointer-to-data-member under the Itanium ABI,
+    // we can initialize with a memset to -1.
+    if (!CGM.getTypes().isZeroInitializable(ElementType))
+      return false;
+
+    // Optimization: since zero initialization will just set the memory
+    // to all zeroes, generate a single memset to do it in one shot.
+
+    // Subtract out the size of any elements we've already initialized.
+    auto *RemainingSize = AllocSizeWithoutCookie;
+    if (InitListElements) {
+      // We know this can't overflow; we check this when doing the allocation.
+      auto *InitializedSize = llvm::ConstantInt::get(
+          RemainingSize->getType(),
+          getContext().getTypeSizeInChars(ElementType).getQuantity() *
+              InitListElements);
+      RemainingSize = Builder.CreateSub(RemainingSize, InitializedSize);
+    }
+
+    // Create the memset.
+    CharUnits Alignment = getContext().getTypeAlignInChars(ElementType);
+    Builder.CreateMemSet(CurPtr, Builder.getInt8(0), RemainingSize,
+                         Alignment.getQuantity(), false);
+    return true;
+  };
+
+  // If all elements have already been initialized, skip any further
+  // initialization.
+  llvm::ConstantInt *ConstNum = dyn_cast<llvm::ConstantInt>(NumElements);
+  if (ConstNum && ConstNum->getZExtValue() <= InitListElements) {
+    // If there was a Cleanup, deactivate it.
+    if (CleanupDominator)
+      DeactivateCleanupBlock(Cleanup, CleanupDominator);
+    return;
+  }
+
+  assert(Init && "have trailing elements to initialize but no initializer");
+
+  // If this is a constructor call, try to optimize it out, and failing that
+  // emit a single loop to initialize all remaining elements.
+  if (const CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(Init)) {
+    CXXConstructorDecl *Ctor = CCE->getConstructor();
+    if (Ctor->isTrivial()) {
+      // If new expression did not specify value-initialization, then there
+      // is no initialization.
+      if (!CCE->requiresZeroInitialization() || Ctor->getParent()->isEmpty())
+        return;
+
+      if (TryMemsetInitialization())
+        return;
+    }
+
+    // Store the new Cleanup position for irregular Cleanups.
+    //
+    // FIXME: Share this cleanup with the constructor call emission rather than
+    // having it create a cleanup of its own.
+    if (EndOfInit) Builder.CreateStore(CurPtr, EndOfInit);
+
+    // Emit a constructor call loop to initialize the remaining elements.
+    if (InitListElements)
+      NumElements = Builder.CreateSub(
+          NumElements,
+          llvm::ConstantInt::get(NumElements->getType(), InitListElements));
+    EmitCXXAggrConstructorCall(Ctor, NumElements, CurPtr,
+                               CCE->arg_begin(), CCE->arg_end(),
+                               CCE->requiresZeroInitialization());
+    return;
+  }
+
+  // If this is value-initialization, we can usually use memset.
+  ImplicitValueInitExpr IVIE(ElementType);
+  if (isa<ImplicitValueInitExpr>(Init)) {
+    if (TryMemsetInitialization())
+      return;
+
+    // Switch to an ImplicitValueInitExpr for the element type. This handles
+    // only one case: multidimensional array new of pointers to members. In
+    // all other cases, we already have an initializer for the array element.
+    Init = &IVIE;
+  }
+
+  // At this point we should have found an initializer for the individual
+  // elements of the array.
+  assert(getContext().hasSameUnqualifiedType(ElementType, Init->getType()) &&
+         "got wrong type of element to initialize");
+
+  // If we have an empty initializer list, we can usually use memset.
+  if (auto *ILE = dyn_cast<InitListExpr>(Init))
+    if (ILE->getNumInits() == 0 && TryMemsetInitialization())
+      return;
+
+  // Create the loop blocks.
+  llvm::BasicBlock *EntryBB = Builder.GetInsertBlock();
+  llvm::BasicBlock *LoopBB = createBasicBlock("new.loop");
+  llvm::BasicBlock *ContBB = createBasicBlock("new.loop.end");
+
+  // Find the end of the array, hoisted out of the loop.
+  llvm::Value *EndPtr =
+    Builder.CreateInBoundsGEP(BeginPtr, NumElements, "array.end");
 
   // If the number of elements isn't constant, we have to now check if there is
   // anything left to initialize.
-  if (llvm::ConstantInt *constNum = dyn_cast<llvm::ConstantInt>(numElements)) {
-    // If all elements have already been initialized, skip the whole loop.
-    if (constNum->getZExtValue() <= initializerElements) {
-      // If there was a cleanup, deactivate it.
-      if (cleanupDominator)
-        DeactivateCleanupBlock(cleanup, cleanupDominator);
-      return;
-    }
-  } else {
-    llvm::BasicBlock *nonEmptyBB = createBasicBlock("new.loop.nonempty");
-    llvm::Value *isEmpty = Builder.CreateICmpEQ(explicitPtr, endPtr,
+  if (!ConstNum) {
+    llvm::Value *IsEmpty = Builder.CreateICmpEQ(CurPtr, EndPtr,
                                                 "array.isempty");
-    Builder.CreateCondBr(isEmpty, contBB, nonEmptyBB);
-    EmitBlock(nonEmptyBB);
+    Builder.CreateCondBr(IsEmpty, ContBB, LoopBB);
   }
 
   // Enter the loop.
-  llvm::BasicBlock *entryBB = Builder.GetInsertBlock();
-  llvm::BasicBlock *loopBB = createBasicBlock("new.loop");
-
-  EmitBlock(loopBB);
+  EmitBlock(LoopBB);
 
   // Set up the current-element phi.
-  llvm::PHINode *curPtr =
-    Builder.CreatePHI(explicitPtr->getType(), 2, "array.cur");
-  curPtr->addIncoming(explicitPtr, entryBB);
+  llvm::PHINode *CurPtrPhi =
+    Builder.CreatePHI(CurPtr->getType(), 2, "array.cur");
+  CurPtrPhi->addIncoming(CurPtr, EntryBB);
+  CurPtr = CurPtrPhi;
 
-  // Store the new cleanup position for irregular cleanups.
-  if (endOfInit) Builder.CreateStore(curPtr, endOfInit);
+  // Store the new Cleanup position for irregular Cleanups.
+  if (EndOfInit) Builder.CreateStore(CurPtr, EndOfInit);
 
-  // Enter a partial-destruction cleanup if necessary.
-  if (!cleanupDominator && needsEHCleanup(dtorKind)) {
-    pushRegularPartialArrayCleanup(beginPtr, curPtr, elementType,
-                                   getDestroyer(dtorKind));
-    cleanup = EHStack.stable_begin();
-    cleanupDominator = Builder.CreateUnreachable();
+  // Enter a partial-destruction Cleanup if necessary.
+  if (!CleanupDominator && needsEHCleanup(DtorKind)) {
+    pushRegularPartialArrayCleanup(BeginPtr, CurPtr, ElementType,
+                                   getDestroyer(DtorKind));
+    Cleanup = EHStack.stable_begin();
+    CleanupDominator = Builder.CreateUnreachable();
   }
 
   // Emit the initializer into this element.
-  StoreAnyExprIntoOneUnit(*this, Init, E->getAllocatedType(), curPtr);
+  StoreAnyExprIntoOneUnit(*this, Init, Init->getType(), CurPtr);
 
-  // Leave the cleanup if we entered one.
-  if (cleanupDominator) {
-    DeactivateCleanupBlock(cleanup, cleanupDominator);
-    cleanupDominator->eraseFromParent();
+  // Leave the Cleanup if we entered one.
+  if (CleanupDominator) {
+    DeactivateCleanupBlock(Cleanup, CleanupDominator);
+    CleanupDominator->eraseFromParent();
   }
 
-  // Advance to the next element.
-  llvm::Value *nextPtr = Builder.CreateConstGEP1_32(curPtr, 1, "array.next");
+  // Advance to the next element by adjusting the pointer type as necessary.
+  llvm::Value *NextPtr =
+      Builder.CreateConstInBoundsGEP1_32(CurPtr, 1, "array.next");
 
   // Check whether we've gotten to the end of the array and, if so,
   // exit the loop.
-  llvm::Value *isEnd = Builder.CreateICmpEQ(nextPtr, endPtr, "array.atend");
-  Builder.CreateCondBr(isEnd, contBB, loopBB);
-  curPtr->addIncoming(nextPtr, Builder.GetInsertBlock());
+  llvm::Value *IsEnd = Builder.CreateICmpEQ(NextPtr, EndPtr, "array.atend");
+  Builder.CreateCondBr(IsEnd, ContBB, LoopBB);
+  CurPtrPhi->addIncoming(NextPtr, Builder.GetInsertBlock());
 
-  EmitBlock(contBB);
+  EmitBlock(ContBB);
 }
 
-static void EmitZeroMemSet(CodeGenFunction &CGF, QualType T,
-                           llvm::Value *NewPtr, llvm::Value *Size) {
-  CGF.EmitCastToVoidPtr(NewPtr);
-  CharUnits Alignment = CGF.getContext().getTypeAlignInChars(T);
-  CGF.Builder.CreateMemSet(NewPtr, CGF.Builder.getInt8(0), Size,
-                           Alignment.getQuantity(), false);
-}
-                       
 static void EmitNewInitializer(CodeGenFunction &CGF, const CXXNewExpr *E,
                                QualType ElementType,
                                llvm::Value *NewPtr,
                                llvm::Value *NumElements,
                                llvm::Value *AllocSizeWithoutCookie) {
-  const Expr *Init = E->getInitializer();
-  if (E->isArray()) {
-    if (const CXXConstructExpr *CCE = dyn_cast_or_null<CXXConstructExpr>(Init)){
-      CXXConstructorDecl *Ctor = CCE->getConstructor();
-      if (Ctor->isTrivial()) {
-        // If new expression did not specify value-initialization, then there
-        // is no initialization.
-        if (!CCE->requiresZeroInitialization() || Ctor->getParent()->isEmpty())
-          return;
-      
-        if (CGF.CGM.getTypes().isZeroInitializable(ElementType)) {
-          // Optimization: since zero initialization will just set the memory
-          // to all zeroes, generate a single memset to do it in one shot.
-          EmitZeroMemSet(CGF, ElementType, NewPtr, AllocSizeWithoutCookie);
-          return;
-        }
-      }
-
-      CGF.EmitCXXAggrConstructorCall(Ctor, NumElements, NewPtr,
-                                     CCE->arg_begin(),  CCE->arg_end(),
-                                     CCE->requiresZeroInitialization());
-      return;
-    } else if (Init && isa<ImplicitValueInitExpr>(Init) &&
-               CGF.CGM.getTypes().isZeroInitializable(ElementType)) {
-      // Optimization: since zero initialization will just set the memory
-      // to all zeroes, generate a single memset to do it in one shot.
-      EmitZeroMemSet(CGF, ElementType, NewPtr, AllocSizeWithoutCookie);
-      return;
-    }
-    CGF.EmitNewArrayInitializer(E, ElementType, NewPtr, NumElements);
-    return;
-  }
-
-  if (!Init)
-    return;
-
-  StoreAnyExprIntoOneUnit(CGF, Init, E->getAllocatedType(), NewPtr);
+  if (E->isArray())
+    CGF.EmitNewArrayInitializer(E, ElementType, NewPtr, NumElements,
+                                AllocSizeWithoutCookie);
+  else if (const Expr *Init = E->getInitializer())
+    StoreAnyExprIntoOneUnit(CGF, Init, E->getAllocatedType(), NewPtr);
 }
 
 /// Emit a call to an operator new or operator delete function, as implicitly
@@ -947,6 +1029,24 @@
   return RV;
 }
 
+RValue CodeGenFunction::EmitBuiltinNewDeleteCall(const FunctionProtoType *Type,
+                                                 const Expr *Arg,
+                                                 bool IsDelete) {
+  CallArgList Args;
+  const Stmt *ArgS = Arg;
+  EmitCallArgs(Args, *Type->param_type_begin(),
+               ConstExprIterator(&ArgS), ConstExprIterator(&ArgS + 1));
+  // Find the allocation or deallocation function that we're calling.
+  ASTContext &Ctx = getContext();
+  DeclarationName Name = Ctx.DeclarationNames
+      .getCXXOperatorName(IsDelete ? OO_Delete : OO_New);
+  for (auto *Decl : Ctx.getTranslationUnitDecl()->lookup(Name))
+    if (auto *FD = dyn_cast<FunctionDecl>(Decl))
+      if (Ctx.hasSameType(FD->getType(), QualType(Type, 0)))
+        return EmitNewDeleteCall(*this, cast<FunctionDecl>(Decl), Type, Args);
+  llvm_unreachable("predeclared global operator new/delete is missing");
+}
+
 namespace {
   /// A cleanup to call the given 'operator delete' function upon
   /// abnormal exit from a new expression.
@@ -975,20 +1075,20 @@
       getPlacementArgs()[I] = Arg;
     }
 
-    void Emit(CodeGenFunction &CGF, Flags flags) {
+    void Emit(CodeGenFunction &CGF, Flags flags) override {
       const FunctionProtoType *FPT
         = OperatorDelete->getType()->getAs<FunctionProtoType>();
-      assert(FPT->getNumArgs() == NumPlacementArgs + 1 ||
-             (FPT->getNumArgs() == 2 && NumPlacementArgs == 0));
+      assert(FPT->getNumParams() == NumPlacementArgs + 1 ||
+             (FPT->getNumParams() == 2 && NumPlacementArgs == 0));
 
       CallArgList DeleteArgs;
 
       // The first argument is always a void*.
-      FunctionProtoType::arg_type_iterator AI = FPT->arg_type_begin();
+      FunctionProtoType::param_type_iterator AI = FPT->param_type_begin();
       DeleteArgs.add(RValue::get(Ptr), *AI++);
 
       // A member 'operator delete' can take an extra 'size_t' argument.
-      if (FPT->getNumArgs() == NumPlacementArgs + 2)
+      if (FPT->getNumParams() == NumPlacementArgs + 2)
         DeleteArgs.add(RValue::get(AllocSize), *AI++);
 
       // Pass the rest of the arguments, which must match exactly.
@@ -1030,20 +1130,20 @@
       getPlacementArgs()[I] = Arg;
     }
 
-    void Emit(CodeGenFunction &CGF, Flags flags) {
+    void Emit(CodeGenFunction &CGF, Flags flags) override {
       const FunctionProtoType *FPT
         = OperatorDelete->getType()->getAs<FunctionProtoType>();
-      assert(FPT->getNumArgs() == NumPlacementArgs + 1 ||
-             (FPT->getNumArgs() == 2 && NumPlacementArgs == 0));
+      assert(FPT->getNumParams() == NumPlacementArgs + 1 ||
+             (FPT->getNumParams() == 2 && NumPlacementArgs == 0));
 
       CallArgList DeleteArgs;
 
       // The first argument is always a void*.
-      FunctionProtoType::arg_type_iterator AI = FPT->arg_type_begin();
+      FunctionProtoType::param_type_iterator AI = FPT->param_type_begin();
       DeleteArgs.add(Ptr.restore(CGF), *AI++);
 
       // A member 'operator delete' can take an extra 'size_t' argument.
-      if (FPT->getNumArgs() == NumPlacementArgs + 2) {
+      if (FPT->getNumParams() == NumPlacementArgs + 2) {
         RValue RV = AllocSize.restore(CGF);
         DeleteArgs.add(RV, *AI++);
       }
@@ -1121,43 +1221,20 @@
       minElements = ILE->getNumInits();
   }
 
-  llvm::Value *numElements = 0;
-  llvm::Value *allocSizeWithoutCookie = 0;
+  llvm::Value *numElements = nullptr;
+  llvm::Value *allocSizeWithoutCookie = nullptr;
   llvm::Value *allocSize =
     EmitCXXNewAllocSize(*this, E, minElements, numElements,
                         allocSizeWithoutCookie);
   
   allocatorArgs.add(RValue::get(allocSize), sizeType);
 
-  // Emit the rest of the arguments.
-  // FIXME: Ideally, this should just use EmitCallArgs.
-  CXXNewExpr::const_arg_iterator placementArg = E->placement_arg_begin();
-
-  // First, use the types from the function type.
   // We start at 1 here because the first argument (the allocation size)
   // has already been emitted.
-  for (unsigned i = 1, e = allocatorType->getNumArgs(); i != e;
-       ++i, ++placementArg) {
-    QualType argType = allocatorType->getArgType(i);
-
-    assert(getContext().hasSameUnqualifiedType(argType.getNonReferenceType(),
-                                               placementArg->getType()) &&
-           "type mismatch in call argument!");
-
-    EmitCallArg(allocatorArgs, *placementArg, argType);
-  }
-
-  // Either we've emitted all the call args, or we have a call to a
-  // variadic function.
-  assert((placementArg == E->placement_arg_end() ||
-          allocatorType->isVariadic()) &&
-         "Extra arguments to non-variadic function!");
-
-  // If we still have any arguments, emit them using the type of the argument.
-  for (CXXNewExpr::const_arg_iterator placementArgsEnd = E->placement_arg_end();
-       placementArg != placementArgsEnd; ++placementArg) {
-    EmitCallArg(allocatorArgs, *placementArg, placementArg->getType());
-  }
+  EmitCallArgs(allocatorArgs, allocatorType->isVariadic(),
+               allocatorType->param_type_begin() + 1,
+               allocatorType->param_type_end(), E->placement_arg_begin(),
+               E->placement_arg_end());
 
   // Emit the allocation call.  If the allocator is a global placement
   // operator, just "inline" it directly.
@@ -1179,8 +1256,8 @@
   bool nullCheck = allocatorType->isNothrow(getContext()) &&
     (!allocType.isPODType(getContext()) || E->hasInitializer());
 
-  llvm::BasicBlock *nullCheckBB = 0;
-  llvm::BasicBlock *contBB = 0;
+  llvm::BasicBlock *nullCheckBB = nullptr;
+  llvm::BasicBlock *contBB = nullptr;
 
   llvm::Value *allocation = RV.getScalarVal();
   unsigned AS = allocation->getType()->getPointerAddressSpace();
@@ -1204,7 +1281,7 @@
   // If there's an operator delete, enter a cleanup to call it if an
   // exception is thrown.
   EHScopeStack::stable_iterator operatorDeleteCleanup;
-  llvm::Instruction *cleanupDominator = 0;
+  llvm::Instruction *cleanupDominator = nullptr;
   if (E->getOperatorDelete() &&
       !E->getOperatorDelete()->isReservedGlobalPlacementOperator()) {
     EnterNewDeleteCleanup(*this, E, allocation, allocSize, allocatorArgs);
@@ -1271,16 +1348,16 @@
   CallArgList DeleteArgs;
 
   // Check if we need to pass the size to the delete operator.
-  llvm::Value *Size = 0;
+  llvm::Value *Size = nullptr;
   QualType SizeTy;
-  if (DeleteFTy->getNumArgs() == 2) {
-    SizeTy = DeleteFTy->getArgType(1);
+  if (DeleteFTy->getNumParams() == 2) {
+    SizeTy = DeleteFTy->getParamType(1);
     CharUnits DeleteTypeSize = getContext().getTypeSizeInChars(DeleteTy);
     Size = llvm::ConstantInt::get(ConvertType(SizeTy), 
                                   DeleteTypeSize.getQuantity());
   }
-  
-  QualType ArgTy = DeleteFTy->getArgType(0);
+
+  QualType ArgTy = DeleteFTy->getParamType(0);
   llvm::Value *DeletePtr = Builder.CreateBitCast(Ptr, ConvertType(ArgTy));
   DeleteArgs.add(RValue::get(DeletePtr), ArgTy);
 
@@ -1303,7 +1380,7 @@
                      QualType ElementType)
       : Ptr(Ptr), OperatorDelete(OperatorDelete), ElementType(ElementType) {}
 
-    void Emit(CodeGenFunction &CGF, Flags flags) {
+    void Emit(CodeGenFunction &CGF, Flags flags) override {
       CGF.EmitDeleteCall(OperatorDelete, Ptr, ElementType);
     }
   };
@@ -1317,7 +1394,7 @@
                              bool UseGlobalDelete) {
   // Find the destructor for the type, if applicable.  If the
   // destructor is virtual, we'll just emit the vcall and return.
-  const CXXDestructorDecl *Dtor = 0;
+  const CXXDestructorDecl *Dtor = nullptr;
   if (const RecordType *RT = ElementType->getAs<RecordType>()) {
     CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
     if (RD->hasDefinition() && !RD->hasTrivialDestructor()) {
@@ -1406,22 +1483,22 @@
       : Ptr(Ptr), OperatorDelete(OperatorDelete), NumElements(NumElements),
         ElementType(ElementType), CookieSize(CookieSize) {}
 
-    void Emit(CodeGenFunction &CGF, Flags flags) {
+    void Emit(CodeGenFunction &CGF, Flags flags) override {
       const FunctionProtoType *DeleteFTy =
         OperatorDelete->getType()->getAs<FunctionProtoType>();
-      assert(DeleteFTy->getNumArgs() == 1 || DeleteFTy->getNumArgs() == 2);
+      assert(DeleteFTy->getNumParams() == 1 || DeleteFTy->getNumParams() == 2);
 
       CallArgList Args;
       
       // Pass the pointer as the first argument.
-      QualType VoidPtrTy = DeleteFTy->getArgType(0);
+      QualType VoidPtrTy = DeleteFTy->getParamType(0);
       llvm::Value *DeletePtr
         = CGF.Builder.CreateBitCast(Ptr, CGF.ConvertType(VoidPtrTy));
       Args.add(RValue::get(DeletePtr), VoidPtrTy);
 
       // Pass the original requested size as the second argument.
-      if (DeleteFTy->getNumArgs() == 2) {
-        QualType size_t = DeleteFTy->getArgType(1);
+      if (DeleteFTy->getNumParams() == 2) {
+        QualType size_t = DeleteFTy->getParamType(1);
         llvm::IntegerType *SizeTy
           = cast<llvm::IntegerType>(CGF.ConvertType(size_t));
         
@@ -1454,8 +1531,8 @@
                             const CXXDeleteExpr *E,
                             llvm::Value *deletedPtr,
                             QualType elementType) {
-  llvm::Value *numElements = 0;
-  llvm::Value *allocatedPtr = 0;
+  llvm::Value *numElements = nullptr;
+  llvm::Value *allocatedPtr = nullptr;
   CharUnits cookieSize;
   CGF.CGM.getCXXABI().ReadArrayCookie(CGF, deletedPtr, E, elementType,
                                       numElements, allocatedPtr, cookieSize);
@@ -1538,21 +1615,39 @@
   EmitBlock(DeleteEnd);
 }
 
-static llvm::Constant *getBadTypeidFn(CodeGenFunction &CGF) {
-  // void __cxa_bad_typeid();
-  llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.VoidTy, false);
-  
-  return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_bad_typeid");
+static bool isGLValueFromPointerDeref(const Expr *E) {
+  E = E->IgnoreParens();
+
+  if (const auto *CE = dyn_cast<CastExpr>(E)) {
+    if (!CE->getSubExpr()->isGLValue())
+      return false;
+    return isGLValueFromPointerDeref(CE->getSubExpr());
+  }
+
+  if (const auto *OVE = dyn_cast<OpaqueValueExpr>(E))
+    return isGLValueFromPointerDeref(OVE->getSourceExpr());
+
+  if (const auto *BO = dyn_cast<BinaryOperator>(E))
+    if (BO->getOpcode() == BO_Comma)
+      return isGLValueFromPointerDeref(BO->getRHS());
+
+  if (const auto *ACO = dyn_cast<AbstractConditionalOperator>(E))
+    return isGLValueFromPointerDeref(ACO->getTrueExpr()) ||
+           isGLValueFromPointerDeref(ACO->getFalseExpr());
+
+  // C++11 [expr.sub]p1:
+  //   The expression E1[E2] is identical (by definition) to *((E1)+(E2))
+  if (isa<ArraySubscriptExpr>(E))
+    return true;
+
+  if (const auto *UO = dyn_cast<UnaryOperator>(E))
+    if (UO->getOpcode() == UO_Deref)
+      return true;
+
+  return false;
 }
 
-static void EmitBadTypeidCall(CodeGenFunction &CGF) {
-  llvm::Value *Fn = getBadTypeidFn(CGF);
-  CGF.EmitRuntimeCallOrInvoke(Fn).setDoesNotReturn();
-  CGF.Builder.CreateUnreachable();
-}
-
-static llvm::Value *EmitTypeidFromVTable(CodeGenFunction &CGF,
-                                         const Expr *E, 
+static llvm::Value *EmitTypeidFromVTable(CodeGenFunction &CGF, const Expr *E,
                                          llvm::Type *StdTypeInfoPtrTy) {
   // Get the vtable pointer.
   llvm::Value *ThisPtr = CGF.EmitLValue(E).getAddress();
@@ -1561,28 +1656,27 @@
   //   If the glvalue expression is obtained by applying the unary * operator to
   //   a pointer and the pointer is a null pointer value, the typeid expression
   //   throws the std::bad_typeid exception.
-  if (const UnaryOperator *UO = dyn_cast<UnaryOperator>(E->IgnoreParens())) {
-    if (UO->getOpcode() == UO_Deref) {
-      llvm::BasicBlock *BadTypeidBlock = 
+  //
+  // However, this paragraph's intent is not clear.  We choose a very generous
+  // interpretation which implores us to consider comma operators, conditional
+  // operators, parentheses and other such constructs.
+  QualType SrcRecordTy = E->getType();
+  if (CGF.CGM.getCXXABI().shouldTypeidBeNullChecked(
+          isGLValueFromPointerDeref(E), SrcRecordTy)) {
+    llvm::BasicBlock *BadTypeidBlock =
         CGF.createBasicBlock("typeid.bad_typeid");
-      llvm::BasicBlock *EndBlock =
-        CGF.createBasicBlock("typeid.end");
+    llvm::BasicBlock *EndBlock = CGF.createBasicBlock("typeid.end");
 
-      llvm::Value *IsNull = CGF.Builder.CreateIsNull(ThisPtr);
-      CGF.Builder.CreateCondBr(IsNull, BadTypeidBlock, EndBlock);
+    llvm::Value *IsNull = CGF.Builder.CreateIsNull(ThisPtr);
+    CGF.Builder.CreateCondBr(IsNull, BadTypeidBlock, EndBlock);
 
-      CGF.EmitBlock(BadTypeidBlock);
-      EmitBadTypeidCall(CGF);
-      CGF.EmitBlock(EndBlock);
-    }
+    CGF.EmitBlock(BadTypeidBlock);
+    CGF.CGM.getCXXABI().EmitBadTypeidCall(CGF);
+    CGF.EmitBlock(EndBlock);
   }
 
-  llvm::Value *Value = CGF.GetVTablePtr(ThisPtr, 
-                                        StdTypeInfoPtrTy->getPointerTo());
-
-  // Load the type info.
-  Value = CGF.Builder.CreateConstInBoundsGEP1_64(Value, -1ULL);
-  return CGF.Builder.CreateLoad(Value);
+  return CGF.CGM.getCXXABI().EmitTypeid(CGF, SrcRecordTy, ThisPtr,
+                                        StdTypeInfoPtrTy);
 }
 
 llvm::Value *CodeGenFunction::EmitCXXTypeidExpr(const CXXTypeidExpr *E) {
@@ -1609,173 +1703,6 @@
                                StdTypeInfoPtrTy);
 }
 
-static llvm::Constant *getDynamicCastFn(CodeGenFunction &CGF) {
-  // void *__dynamic_cast(const void *sub,
-  //                      const abi::__class_type_info *src,
-  //                      const abi::__class_type_info *dst,
-  //                      std::ptrdiff_t src2dst_offset);
-  
-  llvm::Type *Int8PtrTy = CGF.Int8PtrTy;
-  llvm::Type *PtrDiffTy = 
-    CGF.ConvertType(CGF.getContext().getPointerDiffType());
-
-  llvm::Type *Args[4] = { Int8PtrTy, Int8PtrTy, Int8PtrTy, PtrDiffTy };
-
-  llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, Args, false);
-
-  // Mark the function as nounwind readonly.
-  llvm::Attribute::AttrKind FuncAttrs[] = { llvm::Attribute::NoUnwind,
-                                            llvm::Attribute::ReadOnly };
-  llvm::AttributeSet Attrs = llvm::AttributeSet::get(
-      CGF.getLLVMContext(), llvm::AttributeSet::FunctionIndex, FuncAttrs);
-
-  return CGF.CGM.CreateRuntimeFunction(FTy, "__dynamic_cast", Attrs);
-}
-
-static llvm::Constant *getBadCastFn(CodeGenFunction &CGF) {
-  // void __cxa_bad_cast();
-  llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.VoidTy, false);
-  return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_bad_cast");
-}
-
-static void EmitBadCastCall(CodeGenFunction &CGF) {
-  llvm::Value *Fn = getBadCastFn(CGF);
-  CGF.EmitRuntimeCallOrInvoke(Fn).setDoesNotReturn();
-  CGF.Builder.CreateUnreachable();
-}
-
-/// \brief Compute the src2dst_offset hint as described in the
-/// Itanium C++ ABI [2.9.7]
-static CharUnits computeOffsetHint(ASTContext &Context,
-                                   const CXXRecordDecl *Src,
-                                   const CXXRecordDecl *Dst) {
-  CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
-                     /*DetectVirtual=*/false);
-
-  // If Dst is not derived from Src we can skip the whole computation below and
-  // return that Src is not a public base of Dst.  Record all inheritance paths.
-  if (!Dst->isDerivedFrom(Src, Paths))
-    return CharUnits::fromQuantity(-2ULL);
-
-  unsigned NumPublicPaths = 0;
-  CharUnits Offset;
-
-  // Now walk all possible inheritance paths.
-  for (CXXBasePaths::paths_iterator I = Paths.begin(), E = Paths.end();
-       I != E; ++I) {
-    if (I->Access != AS_public) // Ignore non-public inheritance.
-      continue;
-
-    ++NumPublicPaths;
-
-    for (CXXBasePath::iterator J = I->begin(), JE = I->end(); J != JE; ++J) {
-      // If the path contains a virtual base class we can't give any hint.
-      // -1: no hint.
-      if (J->Base->isVirtual())
-        return CharUnits::fromQuantity(-1ULL);
-
-      if (NumPublicPaths > 1) // Won't use offsets, skip computation.
-        continue;
-
-      // Accumulate the base class offsets.
-      const ASTRecordLayout &L = Context.getASTRecordLayout(J->Class);
-      Offset += L.getBaseClassOffset(J->Base->getType()->getAsCXXRecordDecl());
-    }
-  }
-
-  // -2: Src is not a public base of Dst.
-  if (NumPublicPaths == 0)
-    return CharUnits::fromQuantity(-2ULL);
-
-  // -3: Src is a multiple public base type but never a virtual base type.
-  if (NumPublicPaths > 1)
-    return CharUnits::fromQuantity(-3ULL);
-
-  // Otherwise, the Src type is a unique public nonvirtual base type of Dst.
-  // Return the offset of Src from the origin of Dst.
-  return Offset;
-}
-
-static llvm::Value *
-EmitDynamicCastCall(CodeGenFunction &CGF, llvm::Value *Value,
-                    QualType SrcTy, QualType DestTy,
-                    llvm::BasicBlock *CastEnd) {
-  llvm::Type *PtrDiffLTy = 
-    CGF.ConvertType(CGF.getContext().getPointerDiffType());
-  llvm::Type *DestLTy = CGF.ConvertType(DestTy);
-
-  if (const PointerType *PTy = DestTy->getAs<PointerType>()) {
-    if (PTy->getPointeeType()->isVoidType()) {
-      // C++ [expr.dynamic.cast]p7:
-      //   If T is "pointer to cv void," then the result is a pointer to the
-      //   most derived object pointed to by v.
-
-      // Get the vtable pointer.
-      llvm::Value *VTable = CGF.GetVTablePtr(Value, PtrDiffLTy->getPointerTo());
-
-      // Get the offset-to-top from the vtable.
-      llvm::Value *OffsetToTop = 
-        CGF.Builder.CreateConstInBoundsGEP1_64(VTable, -2ULL);
-      OffsetToTop = CGF.Builder.CreateLoad(OffsetToTop, "offset.to.top");
-
-      // Finally, add the offset to the pointer.
-      Value = CGF.EmitCastToVoidPtr(Value);
-      Value = CGF.Builder.CreateInBoundsGEP(Value, OffsetToTop);
-
-      return CGF.Builder.CreateBitCast(Value, DestLTy);
-    }
-  }
-
-  QualType SrcRecordTy;
-  QualType DestRecordTy;
-  
-  if (const PointerType *DestPTy = DestTy->getAs<PointerType>()) {
-    SrcRecordTy = SrcTy->castAs<PointerType>()->getPointeeType();
-    DestRecordTy = DestPTy->getPointeeType();
-  } else {
-    SrcRecordTy = SrcTy;
-    DestRecordTy = DestTy->castAs<ReferenceType>()->getPointeeType();
-  }
-
-  assert(SrcRecordTy->isRecordType() && "source type must be a record type!");
-  assert(DestRecordTy->isRecordType() && "dest type must be a record type!");
-
-  llvm::Value *SrcRTTI =
-    CGF.CGM.GetAddrOfRTTIDescriptor(SrcRecordTy.getUnqualifiedType());
-  llvm::Value *DestRTTI =
-    CGF.CGM.GetAddrOfRTTIDescriptor(DestRecordTy.getUnqualifiedType());
-
-  // Compute the offset hint.
-  const CXXRecordDecl *SrcDecl = SrcRecordTy->getAsCXXRecordDecl();
-  const CXXRecordDecl *DestDecl = DestRecordTy->getAsCXXRecordDecl();
-  llvm::Value *OffsetHint =
-    llvm::ConstantInt::get(PtrDiffLTy,
-                           computeOffsetHint(CGF.getContext(), SrcDecl,
-                                             DestDecl).getQuantity());
-
-  // Emit the call to __dynamic_cast.
-  Value = CGF.EmitCastToVoidPtr(Value);
-
-  llvm::Value *args[] = { Value, SrcRTTI, DestRTTI, OffsetHint };
-  Value = CGF.EmitNounwindRuntimeCall(getDynamicCastFn(CGF), args);
-  Value = CGF.Builder.CreateBitCast(Value, DestLTy);
-
-  /// C++ [expr.dynamic.cast]p9:
-  ///   A failed cast to reference type throws std::bad_cast
-  if (DestTy->isReferenceType()) {
-    llvm::BasicBlock *BadCastBlock = 
-      CGF.createBasicBlock("dynamic_cast.bad_cast");
-
-    llvm::Value *IsNull = CGF.Builder.CreateIsNull(Value);
-    CGF.Builder.CreateCondBr(IsNull, BadCastBlock, CastEnd);
-
-    CGF.EmitBlock(BadCastBlock);
-    EmitBadCastCall(CGF);
-  }
-
-  return Value;
-}
-
 static llvm::Value *EmitDynamicCastToNull(CodeGenFunction &CGF,
                                           QualType DestTy) {
   llvm::Type *DestLTy = CGF.ConvertType(DestTy);
@@ -1784,7 +1711,8 @@
 
   /// C++ [expr.dynamic.cast]p9:
   ///   A failed cast to reference type throws std::bad_cast
-  EmitBadCastCall(CGF);
+  if (!CGF.CGM.getCXXABI().EmitBadCastCall(CGF))
+    return nullptr;
 
   CGF.EmitBlock(CGF.createBasicBlock("dynamic_cast.end"));
   return llvm::UndefValue::get(DestLTy);
@@ -1795,17 +1723,40 @@
   QualType DestTy = DCE->getTypeAsWritten();
 
   if (DCE->isAlwaysNull())
-    return EmitDynamicCastToNull(*this, DestTy);
+    if (llvm::Value *T = EmitDynamicCastToNull(*this, DestTy))
+      return T;
 
   QualType SrcTy = DCE->getSubExpr()->getType();
 
+  // C++ [expr.dynamic.cast]p7:
+  //   If T is "pointer to cv void," then the result is a pointer to the most
+  //   derived object pointed to by v.
+  const PointerType *DestPTy = DestTy->getAs<PointerType>();
+
+  bool isDynamicCastToVoid;
+  QualType SrcRecordTy;
+  QualType DestRecordTy;
+  if (DestPTy) {
+    isDynamicCastToVoid = DestPTy->getPointeeType()->isVoidType();
+    SrcRecordTy = SrcTy->castAs<PointerType>()->getPointeeType();
+    DestRecordTy = DestPTy->getPointeeType();
+  } else {
+    isDynamicCastToVoid = false;
+    SrcRecordTy = SrcTy;
+    DestRecordTy = DestTy->castAs<ReferenceType>()->getPointeeType();
+  }
+
+  assert(SrcRecordTy->isRecordType() && "source type must be a record type!");
+
   // C++ [expr.dynamic.cast]p4: 
   //   If the value of v is a null pointer value in the pointer case, the result
   //   is the null pointer value of type T.
-  bool ShouldNullCheckSrcValue = SrcTy->isPointerType();
-  
-  llvm::BasicBlock *CastNull = 0;
-  llvm::BasicBlock *CastNotNull = 0;
+  bool ShouldNullCheckSrcValue =
+      CGM.getCXXABI().shouldDynamicCastCallBeNullChecked(SrcTy->isPointerType(),
+                                                         SrcRecordTy);
+
+  llvm::BasicBlock *CastNull = nullptr;
+  llvm::BasicBlock *CastNotNull = nullptr;
   llvm::BasicBlock *CastEnd = createBasicBlock("dynamic_cast.end");
   
   if (ShouldNullCheckSrcValue) {
@@ -1817,7 +1768,15 @@
     EmitBlock(CastNotNull);
   }
 
-  Value = EmitDynamicCastCall(*this, Value, SrcTy, DestTy, CastEnd);
+  if (isDynamicCastToVoid) {
+    Value = CGM.getCXXABI().EmitDynamicCastToVoid(*this, Value, SrcRecordTy,
+                                                  DestTy);
+  } else {
+    assert(DestRecordTy->isRecordType() &&
+           "destination type must be a record type!");
+    Value = CGM.getCXXABI().EmitDynamicCastCall(*this, Value, SrcRecordTy,
+                                                DestTy, DestRecordTy, CastEnd);
+  }
 
   if (ShouldNullCheckSrcValue) {
     EmitBranch(CastEnd);
diff --git a/lib/CodeGen/CGExprComplex.cpp b/lib/CodeGen/CGExprComplex.cpp
index 73d5bcb..7244b9e 100644
--- a/lib/CodeGen/CGExprComplex.cpp
+++ b/lib/CodeGen/CGExprComplex.cpp
@@ -93,7 +93,7 @@
   ComplexPairTy Visit(Expr *E) {
     return StmtVisitor<ComplexExprEmitter, ComplexPairTy>::Visit(E);
   }
-    
+
   ComplexPairTy VisitStmt(Stmt *S) {
     S->dump(CGF.getContext().getSourceManager());
     llvm_unreachable("Stmt can't have complex result type!");
@@ -306,7 +306,7 @@
   unsigned ComplexAlign = C.getTypeAlignInChars(ComplexTy).getQuantity();
   unsigned AlignI = std::min(AlignR, ComplexAlign);
 
-  llvm::Value *Real=0, *Imag=0;
+  llvm::Value *Real=nullptr, *Imag=nullptr;
 
   if (!IgnoreReal || isVolatile) {
     llvm::Value *RealP = Builder.CreateStructGEP(SrcPtr, 0,
@@ -410,7 +410,7 @@
   return ComplexPairTy(Val, llvm::Constant::getNullValue(Val->getType()));
 }
 
-ComplexPairTy ComplexExprEmitter::EmitCast(CastExpr::CastKind CK, Expr *Op, 
+ComplexPairTy ComplexExprEmitter::EmitCast(CastExpr::CastKind CK, Expr *Op,
                                            QualType DestTy) {
   switch (CK) {
   case CK_Dependent: llvm_unreachable("dependent cast kind in IR gen!");
@@ -427,7 +427,7 @@
   case CK_LValueBitCast: {
     LValue origLV = CGF.EmitLValue(Op);
     llvm::Value *V = origLV.getAddress();
-    V = Builder.CreateBitCast(V, 
+    V = Builder.CreateBitCast(V,
                     CGF.ConvertType(CGF.getContext().getPointerType(DestTy)));
     return EmitLoadOfLValue(CGF.MakeAddrLValue(V, DestTy,
                                                origLV.getAlignment()),
@@ -475,6 +475,7 @@
   case CK_CopyAndAutoreleaseBlockObject:
   case CK_BuiltinFnToFnPtr:
   case CK_ZeroToOCLEvent:
+  case CK_AddressSpaceConversion:
     llvm_unreachable("invalid cast kind for complex value");
 
   case CK_FloatingRealToComplex:
@@ -652,7 +653,7 @@
   assert(CGF.getContext().hasSameUnqualifiedType(OpInfo.Ty,
                                                  E->getRHS()->getType()));
   OpInfo.RHS = Visit(E->getRHS());
-  
+
   LValue LHS = CGF.EmitLValue(E->getLHS());
 
   // Load from the l-value and convert it.
@@ -702,7 +703,7 @@
 
 LValue ComplexExprEmitter::EmitBinAssignLValue(const BinaryOperator *E,
                                                ComplexPairTy &Val) {
-  assert(CGF.getContext().hasSameUnqualifiedType(E->getLHS()->getType(), 
+  assert(CGF.getContext().hasSameUnqualifiedType(E->getLHS()->getType(),
                                                  E->getRHS()->getType()) &&
          "Invalid assignment");
   TestAndClearIgnoreReal();
@@ -751,11 +752,13 @@
   // Bind the common expression if necessary.
   CodeGenFunction::OpaqueValueMapping binding(CGF, E);
 
+  RegionCounter Cnt = CGF.getPGORegionCounter(E);
   CodeGenFunction::ConditionalEvaluation eval(CGF);
-  CGF.EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock);
+  CGF.EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock, Cnt.getCount());
 
   eval.begin(CGF);
   CGF.EmitBlock(LHSBlock);
+  Cnt.beginRegion(Builder);
   ComplexPairTy LHS = Visit(E->getTrueExpr());
   LHSBlock = Builder.GetInsertBlock();
   CGF.EmitBranch(ContBlock);
diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp
index f4d6861..b508dcb 100644
--- a/lib/CodeGen/CGExprConstant.cpp
+++ b/lib/CodeGen/CGExprConstant.cpp
@@ -530,7 +530,7 @@
   ConstStructBuilder Builder(CGM, CGF);
 
   if (!Builder.Build(ILE))
-    return 0;
+    return nullptr;
 
   return Builder.Finalize(ILE->getType());
 }
@@ -572,7 +572,7 @@
   //===--------------------------------------------------------------------===//
 
   llvm::Constant *VisitStmt(Stmt *S) {
-    return 0;
+    return nullptr;
   }
 
   llvm::Constant *VisitParenExpr(ParenExpr *PE) {
@@ -599,7 +599,7 @@
   llvm::Constant *VisitCastExpr(CastExpr* E) {
     Expr *subExpr = E->getSubExpr();
     llvm::Constant *C = CGM.EmitConstantExpr(subExpr, subExpr->getType(), CGF);
-    if (!C) return 0;
+    if (!C) return nullptr;
 
     llvm::Type *destType = ConvertType(E->getType());
 
@@ -633,6 +633,9 @@
       return llvm::ConstantStruct::get(STy, Elts);
     }
 
+    case CK_AddressSpaceConversion:
+      return llvm::ConstantExpr::getAddrSpaceCast(C, destType);
+
     case CK_LValueToRValue:
     case CK_AtomicToNonAtomic:
     case CK_NonAtomicToAtomic:
@@ -657,7 +660,7 @@
     case CK_ARCReclaimReturnedObject:
     case CK_ARCExtendBlockObject:
     case CK_CopyAndAutoreleaseBlockObject:
-      return 0;
+      return nullptr;
 
     // These don't need to be handled here because Evaluate knows how to
     // evaluate them in the cases where they can be folded.
@@ -698,7 +701,7 @@
     case CK_FloatingToBoolean:
     case CK_FloatingCast:
     case CK_ZeroToOCLEvent:
-      return 0;
+      return nullptr;
     }
     llvm_unreachable("Invalid CastKind");
   }
@@ -740,7 +743,7 @@
       Expr *Init = ILE->getInit(i);
       llvm::Constant *C = CGM.EmitConstantExpr(Init, Init->getType(), CGF);
       if (!C)
-        return 0;
+        return nullptr;
       RewriteType |= (C->getType() != ElemTy);
       Elts.push_back(C);
     }
@@ -753,7 +756,7 @@
     else
       fillC = llvm::Constant::getNullValue(ElemTy);
     if (!fillC)
-      return 0;
+      return nullptr;
     RewriteType |= (fillC->getType() != ElemTy);
     Elts.resize(NumElements, fillC);
 
@@ -786,12 +789,12 @@
     if (ILE->getType()->isRecordType())
       return EmitRecordInitialization(ILE);
 
-    return 0;
+    return nullptr;
   }
 
   llvm::Constant *VisitCXXConstructExpr(CXXConstructExpr *E) {
     if (!E->getConstructor()->isTrivial())
-      return 0;
+      return nullptr;
 
     QualType Ty = E->getType();
 
@@ -803,8 +806,8 @@
     // If the class doesn't have a trivial destructor, we can't emit it as a
     // constant expr.
     if (!RD->hasTrivialDestructor())
-      return 0;
-    
+      return nullptr;
+
     // Only copy and default constructors can be trivial.
 
 
@@ -833,7 +836,10 @@
     // as an inline array.
     std::string Str;
     CGM.getContext().getObjCEncodingForType(E->getEncodedType(), Str);
-    const ConstantArrayType *CAT = cast<ConstantArrayType>(E->getType());
+    QualType T = E->getType();
+    if (T->getTypeClass() == Type::TypeOfExpr)
+      T = cast<TypeOfExprType>(T)->getUnderlyingExpr()->getType();
+    const ConstantArrayType *CAT = cast<ConstantArrayType>(T);
 
     // Resize the string to the right size, adding zeros at the end, or
     // truncating as needed.
@@ -866,7 +872,7 @@
             return CGM.getStaticLocalDeclAddress(VD);
         }
       }
-      return 0;
+      return nullptr;
     }
 
     Expr *E = const_cast<Expr*>(LVBase.get<const Expr*>());
@@ -883,7 +889,7 @@
         C = new llvm::GlobalVariable(CGM.getModule(), C->getType(),
                                      E->getType().isConstant(CGM.getContext()),
                                      llvm::GlobalValue::InternalLinkage,
-                                     C, ".compoundliteral", 0,
+                                     C, ".compoundliteral", nullptr,
                                      llvm::GlobalVariable::NotThreadLocal,
                           CGM.getContext().getTargetAddressSpace(E->getType()));
       return C;
@@ -917,7 +923,7 @@
     }
     case Expr::CallExprClass: {
       CallExpr* CE = cast<CallExpr>(E);
-      unsigned builtin = CE->isBuiltinCall();
+      unsigned builtin = CE->getBuiltinCallee();
       if (builtin !=
             Builtin::BI__builtin___CFStringMakeConstantString &&
           builtin !=
@@ -964,7 +970,7 @@
     }
     }
 
-    return 0;
+    return nullptr;
   }
 };
 
@@ -998,7 +1004,7 @@
   // interprets that as the (pointer) value of the reference, rather than the
   // desired value of the referee.
   if (D.getType()->isReferenceType())
-    return 0;
+    return nullptr;
 
   const Expr *E = D.getInit();
   assert(E && "No initializer to emit");
@@ -1023,7 +1029,7 @@
   else
     Success = E->EvaluateAsRValue(Result, Context);
 
-  llvm::Constant *C = 0;
+  llvm::Constant *C = nullptr;
   if (Success && !Result.HasSideEffects)
     C = EmitConstantValue(Result.Val, DestType, CGF);
   else
@@ -1039,6 +1045,25 @@
 llvm::Constant *CodeGenModule::EmitConstantValue(const APValue &Value,
                                                  QualType DestType,
                                                  CodeGenFunction *CGF) {
+  // For an _Atomic-qualified constant, we may need to add tail padding.
+  if (auto *AT = DestType->getAs<AtomicType>()) {
+    QualType InnerType = AT->getValueType();
+    auto *Inner = EmitConstantValue(Value, InnerType, CGF);
+
+    uint64_t InnerSize = Context.getTypeSize(InnerType);
+    uint64_t OuterSize = Context.getTypeSize(DestType);
+    if (InnerSize == OuterSize)
+      return Inner;
+
+    assert(InnerSize < OuterSize && "emitted over-large constant for atomic");
+    llvm::Constant *Elts[] = {
+      Inner,
+      llvm::ConstantAggregateZero::get(
+          llvm::ArrayType::get(Int8Ty, (OuterSize - InnerSize) / 8))
+    };
+    return llvm::ConstantStruct::getAnon(Elts);
+  }
+
   switch (Value.getKind()) {
   case APValue::Uninitialized:
     llvm_unreachable("Constant expressions should be initialized.");
@@ -1060,15 +1085,17 @@
 
       // Apply offset if necessary.
       if (!Offset->isNullValue()) {
-        llvm::Constant *Casted = llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
+        unsigned AS = C->getType()->getPointerAddressSpace();
+        llvm::Type *CharPtrTy = Int8Ty->getPointerTo(AS);
+        llvm::Constant *Casted = llvm::ConstantExpr::getBitCast(C, CharPtrTy);
         Casted = llvm::ConstantExpr::getGetElementPtr(Casted, Offset);
-        C = llvm::ConstantExpr::getBitCast(Casted, C->getType());
+        C = llvm::ConstantExpr::getPointerCast(Casted, C->getType());
       }
 
       // Convert to the appropriate type; this could be an lvalue for
       // an integer.
       if (isa<llvm::PointerType>(DestTy))
-        return llvm::ConstantExpr::getBitCast(C, DestTy);
+        return llvm::ConstantExpr::getPointerCast(C, DestTy);
 
       return llvm::ConstantExpr::getPtrToInt(C, DestTy);
     } else {
@@ -1166,13 +1193,13 @@
     Elts.reserve(NumElements);
 
     // Emit array filler, if there is one.
-    llvm::Constant *Filler = 0;
+    llvm::Constant *Filler = nullptr;
     if (Value.hasArrayFiller())
       Filler = EmitConstantValueForMemory(Value.getArrayFiller(),
                                           CAT->getElementType(), CGF);
 
     // Emit initializer elements.
-    llvm::Type *CommonElementType = 0;
+    llvm::Type *CommonElementType = nullptr;
     for (unsigned I = 0; I < NumElements; ++I) {
       llvm::Constant *C = Filler;
       if (I < NumInitElts)
@@ -1183,7 +1210,7 @@
       if (I == 0)
         CommonElementType = C->getType();
       else if (C->getType() != CommonElementType)
-        CommonElementType = 0;
+        CommonElementType = nullptr;
       Elts.push_back(C);
     }
 
@@ -1222,7 +1249,7 @@
 llvm::Constant *
 CodeGenModule::GetAddrOfConstantCompoundLiteral(const CompoundLiteralExpr *E) {
   assert(E->isFileScope() && "not a file-scope compound literal expr");
-  return ConstExprEmitter(*this, 0).EmitLValue(E);
+  return ConstExprEmitter(*this, nullptr).EmitLValue(E);
 }
 
 llvm::Constant *
@@ -1265,15 +1292,14 @@
     const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
 
     // Go through all bases and fill in any null pointer to data members.
-    for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
-         E = RD->bases_end(); I != E; ++I) {
-      if (I->isVirtual()) {
+    for (const auto &I : RD->bases()) {
+      if (I.isVirtual()) {
         // Ignore virtual bases.
         continue;
       }
       
       const CXXRecordDecl *BaseDecl = 
-      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+      cast<CXXRecordDecl>(I.getType()->getAs<RecordType>()->getDecl());
       
       // Ignore empty bases.
       if (BaseDecl->isEmpty())
@@ -1285,7 +1311,7 @@
 
       uint64_t BaseOffset =
         CGM.getContext().toBits(Layout.getBaseClassOffset(BaseDecl));
-      FillInNullDataMemberPointers(CGM, I->getType(),
+      FillInNullDataMemberPointers(CGM, I.getType(),
                                    Elements, StartOffset + BaseOffset);
     }
     
@@ -1335,16 +1361,15 @@
   std::vector<llvm::Constant *> elements(numElements);
 
   // Fill in all the bases.
-  for (CXXRecordDecl::base_class_const_iterator
-         I = record->bases_begin(), E = record->bases_end(); I != E; ++I) {
-    if (I->isVirtual()) {
+  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;
     }
 
     const CXXRecordDecl *base = 
-      cast<CXXRecordDecl>(I->getType()->castAs<RecordType>()->getDecl());
+      cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
 
     // Ignore empty bases.
     if (base->isEmpty())
@@ -1356,28 +1381,24 @@
   }
 
   // Fill in all the fields.
-  for (RecordDecl::field_iterator I = record->field_begin(),
-         E = record->field_end(); I != E; ++I) {
-    const FieldDecl *field = *I;
-
+  for (const auto *Field : record->fields()) {
     // Fill in non-bitfields. (Bitfields always use a zero pattern, which we
     // will fill in later.)
-    if (!field->isBitField()) {
-      unsigned fieldIndex = layout.getLLVMFieldNo(field);
-      elements[fieldIndex] = CGM.EmitNullConstant(field->getType());
+    if (!Field->isBitField()) {
+      unsigned fieldIndex = layout.getLLVMFieldNo(Field);
+      elements[fieldIndex] = CGM.EmitNullConstant(Field->getType());
     }
 
     // For unions, stop after the first named field.
-    if (record->isUnion() && field->getDeclName())
+    if (record->isUnion() && Field->getDeclName())
       break;
   }
 
   // Fill in the virtual bases, if we're working with the complete object.
   if (asCompleteObject) {
-    for (CXXRecordDecl::base_class_const_iterator
-           I = record->vbases_begin(), E = record->vbases_end(); I != E; ++I) {
+    for (const auto &I : record->vbases()) {
       const CXXRecordDecl *base = 
-        cast<CXXRecordDecl>(I->getType()->castAs<RecordType>()->getDecl());
+        cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
 
       // Ignore empty bases.
       if (base->isEmpty())
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index f3a5387..9e0fbcf 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -22,13 +22,13 @@
 #include "clang/AST/StmtVisitor.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Frontend/CodeGenOptions.h"
+#include "llvm/IR/CFG.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/GlobalVariable.h"
 #include "llvm/IR/Intrinsics.h"
 #include "llvm/IR/Module.h"
-#include "llvm/Support/CFG.h"
 #include <cstdarg>
 
 using namespace clang;
@@ -246,7 +246,7 @@
   }
   Value *VisitObjCMessageExpr(ObjCMessageExpr *E) {
     if (E->getMethodDecl() &&
-        E->getMethodDecl()->getResultType()->isReferenceType())
+        E->getMethodDecl()->getReturnType()->isReferenceType())
       return EmitLoadOfLValue(E);
     return CGF.EmitObjCMessageExpr(E).getScalarVal();
   }
@@ -365,13 +365,10 @@
   }
   Value *VisitCXXDeleteExpr(const CXXDeleteExpr *E) {
     CGF.EmitCXXDeleteExpr(E);
-    return 0;
-  }
-  Value *VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) {
-    return Builder.getInt1(E->getValue());
+    return nullptr;
   }
 
-  Value *VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E) {
+  Value *VisitTypeTraitExpr(const TypeTraitExpr *E) {
     return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
   }
 
@@ -390,7 +387,7 @@
     //   effect is the evaluation of the postfix-expression before the dot or
     //   arrow.
     CGF.EmitScalarExpr(E->getBase());
-    return 0;
+    return nullptr;
   }
 
   Value *VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E) {
@@ -399,7 +396,7 @@
 
   Value *VisitCXXThrowExpr(const CXXThrowExpr *E) {
     CGF.EmitCXXThrowExpr(E);
-    return 0;
+    return nullptr;
   }
 
   Value *VisitCXXNoexceptExpr(const CXXNoexceptExpr *E) {
@@ -557,12 +554,13 @@
                                                  Value *Src, QualType SrcType,
                                                  QualType DstType,
                                                  llvm::Type *DstTy) {
+  CodeGenFunction::SanitizerScope SanScope(&CGF);
   using llvm::APFloat;
   using llvm::APSInt;
 
   llvm::Type *SrcTy = Src->getType();
 
-  llvm::Value *Check = 0;
+  llvm::Value *Check = nullptr;
   if (llvm::IntegerType *IntTy = dyn_cast<llvm::IntegerType>(SrcTy)) {
     // Integer to floating-point. This can fail for unsigned short -> __half
     // or unsigned __int128 -> float.
@@ -696,7 +694,7 @@
   DstType = CGF.getContext().getCanonicalType(DstType);
   if (SrcType == DstType) return Src;
 
-  if (DstType->isVoidType()) return 0;
+  if (DstType->isVoidType()) return nullptr;
 
   llvm::Value *OrigSrc = Src;
   QualType OrigSrcType = SrcType;
@@ -704,7 +702,10 @@
 
   // If casting to/from storage-only half FP, use special intrinsics.
   if (SrcType->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) {
-    Src = Builder.CreateCall(CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_from_fp16), Src);
+    Src = Builder.CreateCall(
+        CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_from_fp16,
+                             CGF.CGM.FloatTy),
+        Src);
     SrcType = CGF.getContext().FloatTy;
     SrcTy = CGF.FloatTy;
   }
@@ -761,7 +762,7 @@
     return Builder.CreateBitCast(Src, DstTy, "conv");
 
   // Finally, we have the arithmetic types: real int/float.
-  Value *Res = NULL;
+  Value *Res = nullptr;
   llvm::Type *ResTy = DstTy;
 
   // An overflowing conversion has undefined behavior if either the source type
@@ -800,7 +801,9 @@
 
   if (DstTy != ResTy) {
     assert(ResTy->isIntegerTy(16) && "Only half FP requires extra conversion");
-    Res = Builder.CreateCall(CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_to_fp16), Res);
+    Res = Builder.CreateCall(
+        CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_to_fp16, CGF.CGM.FloatTy),
+        Res);
   }
 
   return Res;
@@ -838,6 +841,7 @@
 /// might actually be a unary increment which has been lowered to a binary
 /// operation). The check passes if \p Check, which is an \c i1, is \c true.
 void ScalarExprEmitter::EmitBinOpCheck(Value *Check, const BinOpInfo &Info) {
+  assert(CGF.IsSanitizerScope);
   StringRef CheckName;
   SmallVector<llvm::Constant *, 4> StaticData;
   SmallVector<llvm::Value *, 2> DynamicData;
@@ -890,7 +894,7 @@
 Value *ScalarExprEmitter::VisitExpr(Expr *E) {
   CGF.ErrorUnsupported(E, "scalar expression");
   if (E->getType()->isVoidType())
-    return 0;
+    return nullptr;
   return llvm::UndefValue::get(CGF.ConvertType(E->getType()));
 }
 
@@ -943,9 +947,8 @@
                                                   MTy->getNumElements());
     Value* NewV = llvm::UndefValue::get(RTy);
     for (unsigned i = 0, e = MTy->getNumElements(); i != e; ++i) {
-      Value *IIndx = Builder.getInt32(i);
+      Value *IIndx = llvm::ConstantInt::get(CGF.SizeTy, i);
       Value *Indx = Builder.CreateExtractElement(Mask, IIndx, "shuf_idx");
-      Indx = Builder.CreateZExt(Indx, CGF.Int32Ty, "idx_zext");
 
       Value *VExt = Builder.CreateExtractElement(LHS, Indx, "shuf_elt");
       NewV = Builder.CreateInsertElement(NewV, VExt, IIndx, "shuf_ins");
@@ -1016,7 +1019,7 @@
   }
 
   // We have the arithmetic types: real int/float.
-  Value *Res = NULL;
+  Value *Res = nullptr;
 
   if (isa<llvm::IntegerType>(SrcEltTy)) {
     bool InputSigned = SrcEltType->isSignedIntegerOrEnumerationType();
@@ -1076,8 +1079,6 @@
   if (CGF.SanOpts->ArrayBounds)
     CGF.EmitBoundsCheck(E, E->getBase(), Idx, IdxTy, /*Accessed*/true);
 
-  bool IdxSigned = IdxTy->isSignedIntegerOrEnumerationType();
-  Idx = Builder.CreateIntCast(Idx, CGF.Int32Ty, IdxSigned, "vecidxcast");
   return Builder.CreateExtractElement(Base, Idx, "vecext");
 }
 
@@ -1136,7 +1137,7 @@
 
         if (EI->getVectorOperandType()->getNumElements() == ResElts) {
           llvm::ConstantInt *C = cast<llvm::ConstantInt>(EI->getIndexOperand());
-          Value *LHS = 0, *RHS = 0;
+          Value *LHS = nullptr, *RHS = nullptr;
           if (CurIdx == 0) {
             // insert into undef -> shuffle (src, undef)
             Args.push_back(C);
@@ -1299,7 +1300,18 @@
   case CK_AnyPointerToBlockPointerCast:
   case CK_BitCast: {
     Value *Src = Visit(const_cast<Expr*>(E));
-    return Builder.CreateBitCast(Src, ConvertType(DestTy));
+    llvm::Type *SrcTy = Src->getType();
+    llvm::Type *DstTy = ConvertType(DestTy);
+    if (SrcTy->isPtrOrPtrVectorTy() && DstTy->isPtrOrPtrVectorTy() &&
+        SrcTy->getPointerAddressSpace() != DstTy->getPointerAddressSpace()) {
+      llvm::Type *MidTy = CGF.CGM.getDataLayout().getIntPtrType(SrcTy);
+      return Builder.CreateIntToPtr(Builder.CreatePtrToInt(Src, MidTy), DstTy);
+    }
+    return Builder.CreateBitCast(Src, DstTy);
+  }
+  case CK_AddressSpaceConversion: {
+    Value *Src = Visit(const_cast<Expr*>(E));
+    return Builder.CreateAddrSpaceCast(Src, ConvertType(DestTy));
   }
   case CK_AtomicToNonAtomic:
   case CK_NonAtomicToAtomic:
@@ -1320,7 +1332,7 @@
 
     // C++11 [expr.static.cast]p11: Behavior is undefined if a downcast is
     // performed and the object is not of the derived type.
-    if (CGF.SanitizePerformTypeCheck)
+    if (CGF.sanitizePerformTypeCheck())
       CGF.EmitTypeCheck(CodeGenFunction::TCK_DowncastPointer, CE->getExprLoc(),
                         Derived, DestTy->getPointeeType());
 
@@ -1360,7 +1372,7 @@
 
     // Make sure the array decay ends up being the right type.  This matters if
     // the array type was of an incomplete type.
-    return CGF.Builder.CreateBitCast(V, ConvertType(CE->getType()));
+    return CGF.Builder.CreatePointerCast(V, ConvertType(CE->getType()));
   }
   case CK_FunctionToPointerDecay:
     return EmitLValue(E).getAddress();
@@ -1442,7 +1454,7 @@
 
   case CK_ToVoid: {
     CGF.EmitIgnoredExpr(E);
-    return 0;
+    return nullptr;
   }
   case CK_VectorSplat: {
     llvm::Type *DstTy = ConvertType(DestTy);
@@ -1452,7 +1464,7 @@
 
     // Splat the element across to all elements
     unsigned NumElements = cast<llvm::VectorType>(DstTy)->getNumElements();
-    return Builder.CreateVectorSplat(NumElements, Elt, "splat");;
+    return Builder.CreateVectorSplat(NumElements, Elt, "splat");
   }
 
   case CK_IntegralCast:
@@ -1485,7 +1497,7 @@
   }
 
   case CK_ZeroToOCLEvent: {
-    assert(DestTy->isEventT() && "CK_ZeroToOCLEvent cast on non event type");
+    assert(DestTy->isEventT() && "CK_ZeroToOCLEvent cast on non-event type");
     return llvm::Constant::getNullValue(ConvertType(DestTy));
   }
 
@@ -1499,7 +1511,7 @@
   llvm::Value *RetAlloca = CGF.EmitCompoundStmt(*E->getSubStmt(),
                                                 !E->getType()->isVoidType());
   if (!RetAlloca)
-    return 0;
+    return nullptr;
   return CGF.EmitLoadOfScalar(CGF.MakeAddrLValue(RetAlloca, E->getType()),
                               E->getExprLoc());
 }
@@ -1537,7 +1549,7 @@
                                            bool isInc, bool isPre) {
 
   QualType type = E->getSubExpr()->getType();
-  llvm::PHINode *atomicPHI = 0;
+  llvm::PHINode *atomicPHI = nullptr;
   llvm::Value *value;
   llvm::Value *input;
 
@@ -1610,12 +1622,11 @@
 
     // Note that signed integer inc/dec with width less than int can't
     // overflow because of promotion rules; we're just eliding a few steps here.
-    if (value->getType()->getPrimitiveSizeInBits() >=
-            CGF.IntTy->getBitWidth() &&
-        type->isSignedIntegerOrEnumerationType()) {
+    bool CanOverflow = value->getType()->getIntegerBitWidth() >=
+                       CGF.IntTy->getIntegerBitWidth();
+    if (CanOverflow && type->isSignedIntegerOrEnumerationType()) {
       value = EmitAddConsiderOverflowBehavior(E, value, amt, isInc);
-    } else if (value->getType()->getPrimitiveSizeInBits() >=
-               CGF.IntTy->getBitWidth() && type->isUnsignedIntegerType() &&
+    } else if (CanOverflow && type->isUnsignedIntegerType() &&
                CGF.SanOpts->UnsignedIntegerOverflow) {
       BinOpInfo BinOp;
       BinOp.LHS = value;
@@ -1682,9 +1693,10 @@
 
     if (type->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) {
       // Another special case: half FP increment should be done via float
-      value =
-    Builder.CreateCall(CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_from_fp16),
-                       input);
+      value = Builder.CreateCall(
+          CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_from_fp16,
+                               CGF.CGM.FloatTy),
+          input);
     }
 
     if (value->getType()->isFloatTy())
@@ -1703,9 +1715,10 @@
     value = Builder.CreateFAdd(value, amt, isInc ? "inc" : "dec");
 
     if (type->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType)
-      value =
-       Builder.CreateCall(CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_to_fp16),
-                          value);
+      value = Builder.CreateCall(
+          CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_to_fp16,
+                               CGF.CGM.FloatTy),
+          value);
 
   // Objective-C pointer types.
   } else {
@@ -1727,10 +1740,12 @@
   if (atomicPHI) {
     llvm::BasicBlock *opBB = Builder.GetInsertBlock();
     llvm::BasicBlock *contBB = CGF.createBasicBlock("atomic_cont", CGF.CurFn);
-    llvm::Value *old = Builder.CreateAtomicCmpXchg(LV.getAddress(), atomicPHI,
-        CGF.EmitToMemory(value, type), llvm::SequentiallyConsistent);
+    llvm::Value *pair = Builder.CreateAtomicCmpXchg(
+        LV.getAddress(), atomicPHI, CGF.EmitToMemory(value, type),
+        llvm::SequentiallyConsistent, llvm::SequentiallyConsistent);
+    llvm::Value *old = Builder.CreateExtractValue(pair, 0);
+    llvm::Value *success = Builder.CreateExtractValue(pair, 1);
     atomicPHI->addIncoming(old, opBB);
-    llvm::Value *success = Builder.CreateICmpEQ(old, atomicPHI);
     Builder.CreateCondBr(success, contBB, opBB);
     Builder.SetInsertPoint(contBB);
     return isPre ? value : input;
@@ -1810,7 +1825,7 @@
   QualType CurrentType = E->getTypeSourceInfo()->getType();
   for (unsigned i = 0; i != n; ++i) {
     OffsetOfExpr::OffsetOfNode ON = E->getComponent(i);
-    llvm::Value *Offset = 0;
+    llvm::Value *Offset = nullptr;
     switch (ON.getKind()) {
     case OffsetOfExpr::OffsetOfNode::Array: {
       // Compute the index
@@ -1906,7 +1921,7 @@
 
       QualType eltType;
       llvm::Value *numElts;
-      llvm::tie(numElts, eltType) = CGF.getVLASize(VAT);
+      std::tie(numElts, eltType) = CGF.getVLASize(VAT);
 
       llvm::Value *size = numElts;
 
@@ -2000,7 +2015,7 @@
   // Load/convert the LHS.
   LValue LHSLV = EmitCheckedLValue(E->getLHS(), CodeGenFunction::TCK_Store);
 
-  llvm::PHINode *atomicPHI = 0;
+  llvm::PHINode *atomicPHI = nullptr;
   if (const AtomicType *atomicTy = LHSTy->getAs<AtomicType>()) {
     QualType type = atomicTy->getValueType();
     if (!type->isBooleanType() && type->isIntegerType() &&
@@ -2069,10 +2084,12 @@
   if (atomicPHI) {
     llvm::BasicBlock *opBB = Builder.GetInsertBlock();
     llvm::BasicBlock *contBB = CGF.createBasicBlock("atomic_cont", CGF.CurFn);
-    llvm::Value *old = Builder.CreateAtomicCmpXchg(LHSLV.getAddress(), atomicPHI,
-        CGF.EmitToMemory(Result, LHSTy), llvm::SequentiallyConsistent);
+    llvm::Value *pair = Builder.CreateAtomicCmpXchg(
+        LHSLV.getAddress(), atomicPHI, CGF.EmitToMemory(Result, LHSTy),
+        llvm::SequentiallyConsistent, llvm::SequentiallyConsistent);
+    llvm::Value *old = Builder.CreateExtractValue(pair, 0);
+    llvm::Value *success = Builder.CreateExtractValue(pair, 1);
     atomicPHI->addIncoming(old, opBB);
-    llvm::Value *success = Builder.CreateICmpEQ(old, atomicPHI);
     Builder.CreateCondBr(success, contBB, opBB);
     Builder.SetInsertPoint(contBB);
     return LHSLV;
@@ -2098,7 +2115,7 @@
 
   // If the result is clearly ignored, return now.
   if (Ignore)
-    return 0;
+    return nullptr;
 
   // The result of an assignment in C is the assigned r-value.
   if (!CGF.getLangOpts().CPlusPlus)
@@ -2114,7 +2131,7 @@
 
 void ScalarExprEmitter::EmitUndefinedBehaviorIntegerDivAndRemCheck(
     const BinOpInfo &Ops, llvm::Value *Zero, bool isDiv) {
-  llvm::Value *Cond = 0;
+  llvm::Value *Cond = nullptr;
 
   if (CGF.SanOpts->IntegerDivideByZero)
     Cond = Builder.CreateICmpNE(Ops.RHS, Zero);
@@ -2138,15 +2155,18 @@
 }
 
 Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) {
-  if ((CGF.SanOpts->IntegerDivideByZero ||
-       CGF.SanOpts->SignedIntegerOverflow) &&
-      Ops.Ty->isIntegerType()) {
-    llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
-    EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero, true);
-  } else if (CGF.SanOpts->FloatDivideByZero &&
-             Ops.Ty->isRealFloatingType()) {
-    llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
-    EmitBinOpCheck(Builder.CreateFCmpUNE(Ops.RHS, Zero), Ops);
+  {
+    CodeGenFunction::SanitizerScope SanScope(&CGF);
+    if ((CGF.SanOpts->IntegerDivideByZero ||
+         CGF.SanOpts->SignedIntegerOverflow) &&
+        Ops.Ty->isIntegerType()) {
+      llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
+      EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero, true);
+    } else if (CGF.SanOpts->FloatDivideByZero &&
+               Ops.Ty->isRealFloatingType()) {
+      llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
+      EmitBinOpCheck(Builder.CreateFCmpUNE(Ops.RHS, Zero), Ops);
+    }
   }
 
   if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
@@ -2170,6 +2190,7 @@
 Value *ScalarExprEmitter::EmitRem(const BinOpInfo &Ops) {
   // Rem in C can't be a floating point type: C99 6.5.5p2.
   if (CGF.SanOpts->IntegerDivideByZero) {
+    CodeGenFunction::SanitizerScope SanScope(&CGF);
     llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
 
     if (Ops.Ty->isIntegerType())
@@ -2227,9 +2248,10 @@
   if (handlerName->empty()) {
     // If the signed-integer-overflow sanitizer is enabled, emit a call to its
     // runtime. Otherwise, this is a -ftrapv check, so just emit a trap.
-    if (!isSigned || CGF.SanOpts->SignedIntegerOverflow)
+    if (!isSigned || CGF.SanOpts->SignedIntegerOverflow) {
+      CodeGenFunction::SanitizerScope SanScope(&CGF);
       EmitBinOpCheck(Builder.CreateNot(overflow), Ops);
-    else
+    } else
       CGF.EmitTrapCheck(Builder.CreateNot(overflow));
     return result;
   }
@@ -2238,7 +2260,7 @@
   llvm::BasicBlock *initialBB = Builder.GetInsertBlock();
   llvm::Function::iterator insertPt = initialBB;
   llvm::BasicBlock *continueBB = CGF.createBasicBlock("nooverflow", CGF.CurFn,
-                                                      llvm::next(insertPt));
+                                                      std::next(insertPt));
   llvm::BasicBlock *overflowBB = CGF.createBasicBlock("overflow", CGF.CurFn);
 
   Builder.CreateCondBr(overflow, overflowBB, continueBB);
@@ -2418,12 +2440,12 @@
 
   // Check whether this op is marked as fusable.
   if (!op.FPContractable)
-    return 0;
+    return nullptr;
 
   // Check whether -ffp-contract=on. (If -ffp-contract=off/fast, fusing is
   // either disabled, or handled entirely by the LLVM backend).
   if (CGF.CGM.getCodeGenOpts().getFPContractMode() != CodeGenOptions::FPC_On)
-    return 0;
+    return nullptr;
 
   // We have a potentially fusable op. Look for a mul on one of the operands.
   if (llvm::BinaryOperator* LHSBinOp = dyn_cast<llvm::BinaryOperator>(op.LHS)) {
@@ -2441,7 +2463,7 @@
     }
   }
 
-  return 0;
+  return nullptr;
 }
 
 Value *ScalarExprEmitter::EmitAdd(const BinOpInfo &op) {
@@ -2523,13 +2545,13 @@
   const BinaryOperator *expr = cast<BinaryOperator>(op.E);
   QualType elementType = expr->getLHS()->getType()->getPointeeType();
 
-  llvm::Value *divisor = 0;
+  llvm::Value *divisor = nullptr;
 
   // For a variable-length array, this is going to be non-constant.
   if (const VariableArrayType *vla
         = CGF.getContext().getAsVariableArrayType(elementType)) {
     llvm::Value *numElements;
-    llvm::tie(numElements, elementType) = CGF.getVLASize(vla);
+    std::tie(numElements, elementType) = CGF.getVLASize(vla);
 
     divisor = numElements;
 
@@ -2581,6 +2603,7 @@
 
   if (CGF.SanOpts->Shift && !CGF.getLangOpts().OpenCL &&
       isa<llvm::IntegerType>(Ops.LHS->getType())) {
+    CodeGenFunction::SanitizerScope SanScope(&CGF);
     llvm::Value *WidthMinusOne = GetWidthMinusOneValue(Ops.LHS, RHS);
     llvm::Value *Valid = Builder.CreateICmpULE(RHS, WidthMinusOne);
 
@@ -2632,8 +2655,10 @@
     RHS = Builder.CreateIntCast(RHS, Ops.LHS->getType(), false, "sh_prom");
 
   if (CGF.SanOpts->Shift && !CGF.getLangOpts().OpenCL &&
-      isa<llvm::IntegerType>(Ops.LHS->getType()))
+      isa<llvm::IntegerType>(Ops.LHS->getType())) {
+    CodeGenFunction::SanitizerScope SanScope(&CGF);
     EmitBinOpCheck(Builder.CreateICmpULE(RHS, GetWidthMinusOneValue(Ops.LHS, RHS)), Ops);
+  }
 
   // OpenCL 6.3j: shift values are effectively % word size of LHS.
   if (CGF.getLangOpts().OpenCL)
@@ -2818,11 +2843,11 @@
 
   switch (E->getLHS()->getType().getObjCLifetime()) {
   case Qualifiers::OCL_Strong:
-    llvm::tie(LHS, RHS) = CGF.EmitARCStoreStrong(E, Ignore);
+    std::tie(LHS, RHS) = CGF.EmitARCStoreStrong(E, Ignore);
     break;
 
   case Qualifiers::OCL_Autoreleasing:
-    llvm::tie(LHS,RHS) = CGF.EmitARCStoreAutoreleasing(E);
+    std::tie(LHS, RHS) = CGF.EmitARCStoreAutoreleasing(E);
     break;
 
   case Qualifiers::OCL_Weak:
@@ -2851,7 +2876,7 @@
 
   // If the result is clearly ignored, return now.
   if (Ignore)
-    return 0;
+    return nullptr;
 
   // The result of an assignment in C is the assigned r-value.
   if (!CGF.getLangOpts().CPlusPlus)
@@ -2866,8 +2891,12 @@
 }
 
 Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) {
+  RegionCounter Cnt = CGF.getPGORegionCounter(E);
+
   // Perform vector logical and on comparisons with zero vectors.
   if (E->getType()->isVectorType()) {
+    Cnt.beginRegion(Builder);
+
     Value *LHS = Visit(E->getLHS());
     Value *RHS = Visit(E->getRHS());
     Value *Zero = llvm::ConstantAggregateZero::get(LHS->getType());
@@ -2889,6 +2918,8 @@
   bool LHSCondVal;
   if (CGF.ConstantFoldsToSimpleInteger(E->getLHS(), LHSCondVal)) {
     if (LHSCondVal) { // If we have 1 && X, just emit X.
+      Cnt.beginRegion(Builder);
+
       Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
       // ZExt result to int or bool.
       return Builder.CreateZExtOrBitCast(RHSCond, ResTy, "land.ext");
@@ -2905,7 +2936,7 @@
   CodeGenFunction::ConditionalEvaluation eval(CGF);
 
   // Branch on the LHS first.  If it is false, go to the failure (cont) block.
-  CGF.EmitBranchOnBoolExpr(E->getLHS(), RHSBlock, ContBlock);
+  CGF.EmitBranchOnBoolExpr(E->getLHS(), RHSBlock, ContBlock, Cnt.getCount());
 
   // Any edges into the ContBlock are now from an (indeterminate number of)
   // edges from this first condition.  All of these values will be false.  Start
@@ -2918,18 +2949,20 @@
 
   eval.begin(CGF);
   CGF.EmitBlock(RHSBlock);
+  Cnt.beginRegion(Builder);
   Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
   eval.end(CGF);
 
   // Reaquire the RHS block, as there may be subblocks inserted.
   RHSBlock = Builder.GetInsertBlock();
 
-  // Emit an unconditional branch from this block to ContBlock.  Insert an entry
-  // into the phi node for the edge with the value of RHSCond.
-  if (CGF.getDebugInfo())
+  // Emit an unconditional branch from this block to ContBlock.
+  {
     // There is no need to emit line number for unconditional branch.
-    Builder.SetCurrentDebugLocation(llvm::DebugLoc());
-  CGF.EmitBlock(ContBlock);
+    SuppressDebugLocation S(Builder);
+    CGF.EmitBlock(ContBlock);
+  }
+  // Insert an entry into the phi node for the edge with the value of RHSCond.
   PN->addIncoming(RHSCond, RHSBlock);
 
   // ZExt result to int.
@@ -2937,8 +2970,12 @@
 }
 
 Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) {
+  RegionCounter Cnt = CGF.getPGORegionCounter(E);
+
   // Perform vector logical or on comparisons with zero vectors.
   if (E->getType()->isVectorType()) {
+    Cnt.beginRegion(Builder);
+
     Value *LHS = Visit(E->getLHS());
     Value *RHS = Visit(E->getRHS());
     Value *Zero = llvm::ConstantAggregateZero::get(LHS->getType());
@@ -2960,6 +2997,8 @@
   bool LHSCondVal;
   if (CGF.ConstantFoldsToSimpleInteger(E->getLHS(), LHSCondVal)) {
     if (!LHSCondVal) { // If we have 0 || X, just emit X.
+      Cnt.beginRegion(Builder);
+
       Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
       // ZExt result to int or bool.
       return Builder.CreateZExtOrBitCast(RHSCond, ResTy, "lor.ext");
@@ -2976,7 +3015,8 @@
   CodeGenFunction::ConditionalEvaluation eval(CGF);
 
   // Branch on the LHS first.  If it is true, go to the success (cont) block.
-  CGF.EmitBranchOnBoolExpr(E->getLHS(), ContBlock, RHSBlock);
+  CGF.EmitBranchOnBoolExpr(E->getLHS(), ContBlock, RHSBlock,
+                           Cnt.getParentCount() - Cnt.getCount());
 
   // Any edges into the ContBlock are now from an (indeterminate number of)
   // edges from this first condition.  All of these values will be true.  Start
@@ -2991,6 +3031,7 @@
 
   // Emit the RHS condition as a bool value.
   CGF.EmitBlock(RHSBlock);
+  Cnt.beginRegion(Builder);
   Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS());
 
   eval.end(CGF);
@@ -3041,6 +3082,7 @@
 
   // Bind the common expression if necessary.
   CodeGenFunction::OpaqueValueMapping binding(CGF, E);
+  RegionCounter Cnt = CGF.getPGORegionCounter(E);
 
   Expr *condExpr = E->getCond();
   Expr *lhsExpr = E->getTrueExpr();
@@ -3055,6 +3097,8 @@
 
     // If the dead side doesn't have labels we need, just emit the Live part.
     if (!CGF.ContainsLabel(dead)) {
+      if (CondExprBool)
+        Cnt.beginRegion(Builder);
       Value *Result = Visit(live);
 
       // If the live part is a throw expression, it acts like it has a void
@@ -3071,6 +3115,8 @@
   // the select function.
   if (CGF.getLangOpts().OpenCL
       && condExpr->getType()->isVectorType()) {
+    Cnt.beginRegion(Builder);
+
     llvm::Value *CondV = CGF.EmitScalarExpr(condExpr);
     llvm::Value *LHS = Visit(lhsExpr);
     llvm::Value *RHS = Visit(rhsExpr);
@@ -3114,13 +3160,15 @@
   // safe to evaluate the LHS and RHS unconditionally.
   if (isCheapEnoughToEvaluateUnconditionally(lhsExpr, CGF) &&
       isCheapEnoughToEvaluateUnconditionally(rhsExpr, CGF)) {
+    Cnt.beginRegion(Builder);
+
     llvm::Value *CondV = CGF.EvaluateExprAsBool(condExpr);
     llvm::Value *LHS = Visit(lhsExpr);
     llvm::Value *RHS = Visit(rhsExpr);
     if (!LHS) {
       // If the conditional has void type, make sure we return a null Value*.
       assert(!RHS && "LHS and RHS types must match");
-      return 0;
+      return nullptr;
     }
     return Builder.CreateSelect(CondV, LHS, RHS, "cond");
   }
@@ -3130,9 +3178,10 @@
   llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end");
 
   CodeGenFunction::ConditionalEvaluation eval(CGF);
-  CGF.EmitBranchOnBoolExpr(condExpr, LHSBlock, RHSBlock);
+  CGF.EmitBranchOnBoolExpr(condExpr, LHSBlock, RHSBlock, Cnt.getCount());
 
   CGF.EmitBlock(LHSBlock);
+  Cnt.beginRegion(Builder);
   eval.begin(CGF);
   Value *LHS = Visit(lhsExpr);
   eval.end(CGF);
@@ -3166,6 +3215,10 @@
 }
 
 Value *ScalarExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
+  QualType Ty = VE->getType();
+  if (Ty->isVariablyModifiedType())
+    CGF.EmitVariablyModifiedType(Ty);
+
   llvm::Value *ArgValue = CGF.EmitVAListRef(VE->getSubExpr());
   llvm::Value *ArgPtr = CGF.EmitVAArg(ArgValue, VE->getType());
 
@@ -3312,7 +3365,7 @@
 LValue CodeGenFunction::EmitCompoundAssignmentLValue(
                                             const CompoundAssignOperator *E) {
   ScalarExprEmitter Scalar(*this);
-  Value *Result = 0;
+  Value *Result = nullptr;
   switch (E->getOpcode()) {
 #define COMPOUND_OP(Op)                                                       \
     case BO_##Op##Assign:                                                     \
diff --git a/lib/CodeGen/CGLoopInfo.cpp b/lib/CodeGen/CGLoopInfo.cpp
new file mode 100644
index 0000000..a273f1d
--- /dev/null
+++ b/lib/CodeGen/CGLoopInfo.cpp
@@ -0,0 +1,112 @@
+//===---- CGLoopInfo.cpp - LLVM CodeGen for loop metadata -*- C++ -*-------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CGLoopInfo.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Metadata.h"
+using namespace clang;
+using namespace CodeGen;
+using namespace llvm;
+
+static MDNode *createMetadata(LLVMContext &Ctx, const LoopAttributes &Attrs) {
+
+  if (!Attrs.IsParallel && Attrs.VectorizerWidth == 0 &&
+      Attrs.VectorizerUnroll == 0 &&
+      Attrs.VectorizerEnable == LoopAttributes::VecUnspecified)
+    return nullptr;
+
+  SmallVector<Value *, 4> Args;
+  // Reserve operand 0 for loop id self reference.
+  MDNode *TempNode = MDNode::getTemporary(Ctx, None);
+  Args.push_back(TempNode);
+
+  // Setting vectorizer.width
+  if (Attrs.VectorizerWidth > 0) {
+    Value *Vals[] = { MDString::get(Ctx, "llvm.loop.vectorize.width"),
+                      ConstantInt::get(Type::getInt32Ty(Ctx),
+                                       Attrs.VectorizerWidth) };
+    Args.push_back(MDNode::get(Ctx, Vals));
+  }
+
+  // Setting vectorizer.unroll
+  if (Attrs.VectorizerUnroll > 0) {
+    Value *Vals[] = { MDString::get(Ctx, "llvm.loop.interleave.count"),
+                      ConstantInt::get(Type::getInt32Ty(Ctx),
+                                       Attrs.VectorizerUnroll) };
+    Args.push_back(MDNode::get(Ctx, Vals));
+  }
+
+  // Setting vectorizer.enable
+  if (Attrs.VectorizerEnable != LoopAttributes::VecUnspecified) {
+    Value *Vals[] = { MDString::get(Ctx, "llvm.loop.vectorize.enable"),
+                      ConstantInt::get(Type::getInt1Ty(Ctx),
+                                       (Attrs.VectorizerEnable ==
+                                        LoopAttributes::VecEnable)) };
+    Args.push_back(MDNode::get(Ctx, Vals));
+  }
+
+  MDNode *LoopID = MDNode::get(Ctx, Args);
+  assert(LoopID->use_empty() && "LoopID should not be used");
+
+  // Set the first operand to itself.
+  LoopID->replaceOperandWith(0, LoopID);
+  MDNode::deleteTemporary(TempNode);
+  return LoopID;
+}
+
+LoopAttributes::LoopAttributes(bool IsParallel)
+    : IsParallel(IsParallel), VectorizerEnable(LoopAttributes::VecUnspecified),
+      VectorizerWidth(0), VectorizerUnroll(0) {}
+
+void LoopAttributes::clear() {
+  IsParallel = false;
+  VectorizerWidth = 0;
+  VectorizerUnroll = 0;
+  VectorizerEnable = LoopAttributes::VecUnspecified;
+}
+
+LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs)
+    : LoopID(nullptr), Header(Header), Attrs(Attrs) {
+  LoopID = createMetadata(Header->getContext(), Attrs);
+}
+
+void LoopInfoStack::push(BasicBlock *Header) {
+  Active.push_back(LoopInfo(Header, StagedAttrs));
+  // Clear the attributes so nested loops do not inherit them.
+  StagedAttrs.clear();
+}
+
+void LoopInfoStack::pop() {
+  assert(!Active.empty() && "No active loops to pop");
+  Active.pop_back();
+}
+
+void LoopInfoStack::InsertHelper(Instruction *I) const {
+  if (!hasInfo())
+    return;
+
+  const LoopInfo &L = getInfo();
+  if (!L.getLoopID())
+    return;
+
+  if (TerminatorInst *TI = dyn_cast<TerminatorInst>(I)) {
+    for (unsigned i = 0, ie = TI->getNumSuccessors(); i < ie; ++i)
+      if (TI->getSuccessor(i) == L.getHeader()) {
+        TI->setMetadata("llvm.loop", L.getLoopID());
+        break;
+      }
+    return;
+  }
+
+  if (L.getAttributes().IsParallel && I->mayReadOrWriteMemory())
+    I->setMetadata("llvm.mem.parallel_loop_access", L.getLoopID());
+}
diff --git a/lib/CodeGen/CGLoopInfo.h b/lib/CodeGen/CGLoopInfo.h
new file mode 100644
index 0000000..2f6f172
--- /dev/null
+++ b/lib/CodeGen/CGLoopInfo.h
@@ -0,0 +1,136 @@
+//===---- CGLoopInfo.h - LLVM CodeGen for loop metadata -*- C++ -*---------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is the internal state used for llvm translation for loop statement
+// metadata.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_CODEGEN_CGLOOPINFO_H
+#define CLANG_CODEGEN_CGLOOPINFO_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/Value.h"
+#include "llvm/Support/Compiler.h"
+
+namespace llvm {
+class BasicBlock;
+class Instruction;
+class MDNode;
+} // end namespace llvm
+
+namespace clang {
+namespace CodeGen {
+
+/// \brief Attributes that may be specified on loops.
+struct LoopAttributes {
+  explicit LoopAttributes(bool IsParallel = false);
+  void clear();
+
+  /// \brief Generate llvm.loop.parallel metadata for loads and stores.
+  bool IsParallel;
+
+  /// \brief Values of llvm.loop.vectorize.enable metadata.
+  enum LVEnableState { VecUnspecified, VecEnable, VecDisable };
+
+  /// \brief llvm.loop.vectorize.enable
+  LVEnableState VectorizerEnable;
+
+  /// \brief llvm.loop.vectorize.width
+  unsigned VectorizerWidth;
+
+  /// \brief llvm.loop.interleave.count
+  unsigned VectorizerUnroll;
+};
+
+/// \brief Information used when generating a structured loop.
+class LoopInfo {
+public:
+  /// \brief Construct a new LoopInfo for the loop with entry Header.
+  LoopInfo(llvm::BasicBlock *Header, const LoopAttributes &Attrs);
+
+  /// \brief Get the loop id metadata for this loop.
+  llvm::MDNode *getLoopID() const { return LoopID; }
+
+  /// \brief Get the header block of this loop.
+  llvm::BasicBlock *getHeader() const { return Header; }
+
+  /// \brief Get the set of attributes active for this loop.
+  const LoopAttributes &getAttributes() const { return Attrs; }
+
+private:
+  /// \brief Loop ID metadata.
+  llvm::MDNode *LoopID;
+  /// \brief Header block of this loop.
+  llvm::BasicBlock *Header;
+  /// \brief The attributes for this loop.
+  LoopAttributes Attrs;
+};
+
+/// \brief A stack of loop information corresponding to loop nesting levels.
+/// This stack can be used to prepare attributes which are applied when a loop
+/// is emitted.
+class LoopInfoStack {
+  LoopInfoStack(const LoopInfoStack &) LLVM_DELETED_FUNCTION;
+  void operator=(const LoopInfoStack &) LLVM_DELETED_FUNCTION;
+
+public:
+  LoopInfoStack() {}
+
+  /// \brief Begin a new structured loop. The set of staged attributes will be
+  /// applied to the loop and then cleared.
+  void push(llvm::BasicBlock *Header);
+
+  /// \brief End the current loop.
+  void pop();
+
+  /// \brief Return the top loop id metadata.
+  llvm::MDNode *getCurLoopID() const { return getInfo().getLoopID(); }
+
+  /// \brief Return true if the top loop is parallel.
+  bool getCurLoopParallel() const {
+    return hasInfo() ? getInfo().getAttributes().IsParallel : false;
+  }
+
+  /// \brief Function called by the CodeGenFunction when an instruction is
+  /// created.
+  void InsertHelper(llvm::Instruction *I) const;
+
+  /// \brief Set the next pushed loop as parallel.
+  void setParallel(bool Enable = true) { StagedAttrs.IsParallel = Enable; }
+
+  /// \brief Set the next pushed loop 'vectorizer.enable'
+  void setVectorizerEnable(bool Enable = true) {
+    StagedAttrs.VectorizerEnable =
+        Enable ? LoopAttributes::VecEnable : LoopAttributes::VecDisable;
+  }
+
+  /// \brief Set the vectorizer width for the next loop pushed.
+  void setVectorizerWidth(unsigned W) { StagedAttrs.VectorizerWidth = W; }
+
+  /// \brief Set the vectorizer unroll for the next loop pushed.
+  void setVectorizerUnroll(unsigned U) { StagedAttrs.VectorizerUnroll = U; }
+
+private:
+  /// \brief Returns true if there is LoopInfo on the stack.
+  bool hasInfo() const { return !Active.empty(); }
+  /// \brief Return the LoopInfo for the current loop. HasInfo should be called
+  /// first to ensure LoopInfo is present.
+  const LoopInfo &getInfo() const { return Active.back(); }
+  /// \brief The set of attributes that will be applied to the next pushed loop.
+  LoopAttributes StagedAttrs;
+  /// \brief Stack of active loops.
+  llvm::SmallVector<LoopInfo, 4> Active;
+};
+
+} // end namespace CodeGen
+} // end namespace clang
+
+#endif // CLANG_CODEGEN_CGLOOPINFO_H
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp
index 0bda053..8ca8080 100644
--- a/lib/CodeGen/CGObjC.cpp
+++ b/lib/CodeGen/CGObjC.cpp
@@ -22,7 +22,7 @@
 #include "clang/Basic/Diagnostic.h"
 #include "clang/CodeGen/CGFunctionInfo.h"
 #include "llvm/ADT/STLExtras.h"
-#include "llvm/Support/CallSite.h"
+#include "llvm/IR/CallSite.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/InlineAsm.h"
 using namespace clang;
@@ -79,10 +79,10 @@
   RValue RV = EmitAnyExpr(SubExpr);
   CallArgList Args;
   Args.add(RV, ArgQT);
-  
-  RValue result = Runtime.GenerateMessageSend(*this, ReturnValueSlot(), 
-                                              BoxingMethod->getResultType(), Sel, Receiver, Args, 
-                                              ClassDecl, BoxingMethod);
+
+  RValue result = Runtime.GenerateMessageSend(
+      *this, ReturnValueSlot(), BoxingMethod->getReturnType(), Sel, Receiver,
+      Args, ClassDecl, BoxingMethod);
   return Builder.CreateBitCast(result.getScalarVal(), 
                                ConvertType(E->getType()));
 }
@@ -90,7 +90,7 @@
 llvm::Value *CodeGenFunction::EmitObjCCollectionLiteral(const Expr *E,
                                     const ObjCMethodDecl *MethodWithObjects) {
   ASTContext &Context = CGM.getContext();
-  const ObjCDictionaryLiteral *DLE = 0;
+  const ObjCDictionaryLiteral *DLE = nullptr;
   const ObjCArrayLiteral *ALE = dyn_cast<ObjCArrayLiteral>(E);
   if (!ALE)
     DLE = cast<ObjCDictionaryLiteral>(E);
@@ -106,8 +106,8 @@
                                    ArrayType::Normal, /*IndexTypeQuals=*/0);
 
   // Allocate the temporary array(s).
-  llvm::Value *Objects = CreateMemTemp(ElementArrayType, "objects");  
-  llvm::Value *Keys = 0;
+  llvm::Value *Objects = CreateMemTemp(ElementArrayType, "objects");
+  llvm::Value *Keys = nullptr;
   if (DLE)
     Keys = CreateMemTemp(ElementArrayType, "keys");
   
@@ -186,12 +186,9 @@
   llvm::Value *Receiver = Runtime.GetClass(*this, Class);
 
   // Generate the message send.
-  RValue result
-    = Runtime.GenerateMessageSend(*this, ReturnValueSlot(), 
-                                  MethodWithObjects->getResultType(),
-                                  Sel,
-                                  Receiver, Args, Class,
-                                  MethodWithObjects);
+  RValue result = Runtime.GenerateMessageSend(
+      *this, ReturnValueSlot(), MethodWithObjects->getReturnType(), Sel,
+      Receiver, Args, Class, MethodWithObjects);
 
   // The above message send needs these objects, but in ARC they are
   // passed in a buffer that is essentially __unsafe_unretained.
@@ -238,7 +235,7 @@
     return Result;
 
   if (!Method->hasRelatedResultType() ||
-      CGF.getContext().hasSameType(ExpT, Method->getResultType()) ||
+      CGF.getContext().hasSameType(ExpT, Method->getReturnType()) ||
       !Result.isScalar())
     return Result;
   
@@ -317,10 +314,10 @@
   CGObjCRuntime &Runtime = CGM.getObjCRuntime();
   bool isSuperMessage = false;
   bool isClassMessage = false;
-  ObjCInterfaceDecl *OID = 0;
+  ObjCInterfaceDecl *OID = nullptr;
   // Find the receiver
   QualType ReceiverType;
-  llvm::Value *Receiver = 0;
+  llvm::Value *Receiver = nullptr;
   switch (E->getReceiverKind()) {
   case ObjCMessageExpr::Instance:
     ReceiverType = E->getInstanceReceiver()->getType();
@@ -369,8 +366,7 @@
       shouldExtendReceiverForInnerPointerMessage(E))
     Receiver = EmitARCRetainAutorelease(ReceiverType, Receiver);
 
-  QualType ResultType =
-    method ? method->getResultType() : E->getType();
+  QualType ResultType = method ? method->getReturnType() : E->getType();
 
   CallArgList Args;
   EmitCallArgs(Args, method, E->arg_begin(), E->arg_end());
@@ -435,7 +431,7 @@
 
 namespace {
 struct FinishARCDealloc : EHScopeStack::Cleanup {
-  void Emit(CodeGenFunction &CGF, Flags flags) {
+  void Emit(CodeGenFunction &CGF, Flags flags) override {
     const ObjCMethodDecl *method = cast<ObjCMethodDecl>(CGF.CurCodeDecl);
 
     const ObjCImplDecl *impl = cast<ObjCImplDecl>(method->getDeclContext());
@@ -470,7 +466,7 @@
   FunctionArgList args;
   // Check if we should generate debug info for this method.
   if (OMD->hasAttr<NoDebugAttr>())
-    DebugInfo = NULL; // disable debug info indefinitely for this function
+    DebugInfo = nullptr; // disable debug info indefinitely for this function
 
   llvm::Function *Fn = CGM.getObjCRuntime().GenerateMethod(OMD, CD);
 
@@ -480,13 +476,13 @@
   args.push_back(OMD->getSelfDecl());
   args.push_back(OMD->getCmdDecl());
 
-  for (ObjCMethodDecl::param_const_iterator PI = OMD->param_begin(),
-         E = OMD->param_end(); PI != E; ++PI)
-    args.push_back(*PI);
+  for (const auto *PI : OMD->params())
+    args.push_back(PI);
 
   CurGD = OMD;
 
-  StartFunction(OMD, OMD->getResultType(), Fn, FI, args, StartLoc);
+  StartFunction(OMD, OMD->getReturnType(), Fn, FI, args,
+                OMD->getLocation(), StartLoc);
 
   // In ARC, certain methods get an extra cleanup.
   if (CGM.getLangOpts().ObjCAutoRefCount &&
@@ -506,8 +502,14 @@
 /// its pointer, name, and types registered in the class struture.
 void CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) {
   StartObjCMethod(OMD, OMD->getClassInterface(), OMD->getLocStart());
-  EmitStmt(OMD->getBody());
+  PGO.assignRegionCounters(OMD, CurFn);
+  assert(isa<CompoundStmt>(OMD->getBody()));
+  RegionCounter Cnt = getPGORegionCounter(OMD->getBody());
+  Cnt.beginRegion(Builder);
+  EmitCompoundStmtWithoutScope(*cast<CompoundStmt>(OMD->getBody()));
   FinishFunction(OMD->getBodyRBrace());
+  PGO.emitInstrumentationData();
+  PGO.destroyRegionCounters();
 }
 
 /// emitStructGetterCall - Call the runtime function to load a property
@@ -622,8 +624,8 @@
   // Evaluate the ivar's size and alignment.
   ObjCIvarDecl *ivar = propImpl->getPropertyIvarDecl();
   QualType ivarType = ivar->getType();
-  llvm::tie(IvarSize, IvarAlignment)
-    = CGM.getContext().getTypeInfoInChars(ivarType);
+  std::tie(IvarSize, IvarAlignment) =
+      CGM.getContext().getTypeInfoInChars(ivarType);
 
   // If we have a copy property, we always have to use getProperty/setProperty.
   // TODO: we could actually use setProperty and an expression for non-atomics.
@@ -818,7 +820,7 @@
   if (!hasTrivialGetExpr(propImpl)) {
     if (!AtomicHelperFn) {
       ReturnStmt ret(SourceLocation(), propImpl->getGetterCXXConstructor(),
-                     /*nrvo*/ 0);
+                     /*nrvo*/ nullptr);
       EmitReturnStmt(ret);
     }
     else {
@@ -895,16 +897,21 @@
 
     // FIXME: We shouldn't need to get the function info here, the
     // runtime already should have computed it to build the function.
+    llvm::Instruction *CallInstruction;
     RValue RV = EmitCall(getTypes().arrangeFreeFunctionCall(propType, args,
                                                        FunctionType::ExtInfo(),
                                                             RequiredArgs::All),
-                         getPropertyFn, ReturnValueSlot(), args);
+                         getPropertyFn, ReturnValueSlot(), args, nullptr,
+                         &CallInstruction);
+    if (llvm::CallInst *call = dyn_cast<llvm::CallInst>(CallInstruction))
+      call->setTailCall();
 
     // We need to fix the type here. Ivars with copy & retain are
     // always objects so we don't need to worry about complex or
     // aggregates.
-    RV = RValue::get(Builder.CreateBitCast(RV.getScalarVal(),
-           getTypes().ConvertType(getterMethod->getResultType())));
+    RV = RValue::get(Builder.CreateBitCast(
+        RV.getScalarVal(),
+        getTypes().ConvertType(getterMethod->getReturnType())));
 
     EmitReturnOfRValue(RV, propType);
 
@@ -955,8 +962,8 @@
         }
 
         value = Builder.CreateBitCast(value, ConvertType(propType));
-        value = Builder.CreateBitCast(value, 
-                  ConvertType(GetterMethodDecl->getResultType()));
+        value = Builder.CreateBitCast(
+            value, ConvertType(GetterMethodDecl->getReturnType()));
       }
       
       EmitReturnOfRValue(RValue::get(value), propType);
@@ -1139,9 +1146,9 @@
 
   case PropertyImplStrategy::GetSetProperty:
   case PropertyImplStrategy::SetPropertyAndExpressionGet: {
-  
-    llvm::Value *setOptimizedPropertyFn = 0;
-    llvm::Value *setPropertyFn = 0;
+
+    llvm::Value *setOptimizedPropertyFn = nullptr;
+    llvm::Value *setPropertyFn = nullptr;
     if (UseOptimizedSetter(CGM)) {
       // 10.8 and iOS 6.0 code and GC is off
       setOptimizedPropertyFn = 
@@ -1292,7 +1299,7 @@
       : addr(addr), ivar(ivar), destroyer(destroyer),
         useEHCleanupForArray(useEHCleanupForArray) {}
 
-    void Emit(CodeGenFunction &CGF, Flags flags) {
+    void Emit(CodeGenFunction &CGF, Flags flags) override {
       LValue lvalue
         = CGF.EmitLValueForIvar(CGF.TypeOfSelfObject(), addr, ivar, /*CVR*/ 0);
       CGF.emitDestroy(lvalue.getAddress(), ivar->getType(), destroyer,
@@ -1324,7 +1331,7 @@
     QualType::DestructionKind dtorKind = type.isDestructedType();
     if (!dtorKind) continue;
 
-    CodeGenFunction::Destroyer *destroyer = 0;
+    CodeGenFunction::Destroyer *destroyer = nullptr;
 
     // Use a call to objc_storeStrong to destroy strong ivars, for the
     // general benefit of the tools.
@@ -1356,12 +1363,9 @@
     // Suppress the final autorelease in ARC.
     AutoreleaseResult = false;
 
-    SmallVector<CXXCtorInitializer *, 8> IvarInitializers;
-    for (ObjCImplementationDecl::init_const_iterator B = IMP->init_begin(),
-           E = IMP->init_end(); B != E; ++B) {
-      CXXCtorInitializer *IvarInit = (*B);
+    for (const auto *IvarInit : IMP->inits()) {
       FieldDecl *Field = IvarInit->getAnyMember();
-      ObjCIvarDecl  *Ivar = cast<ObjCIvarDecl>(Field);
+      ObjCIvarDecl *Ivar = cast<ObjCIvarDecl>(Field);
       LValue LV = EmitLValueForIvar(TypeOfSelfObject(), 
                                     LoadObjCSelf(), Ivar, 0);
       EmitAggExpr(IvarInit->getInit(),
@@ -1506,9 +1510,13 @@
   llvm::Value *zero = llvm::Constant::getNullValue(UnsignedLongLTy);
 
   // If the limit pointer was zero to begin with, the collection is
-  // empty; skip all this.
+  // empty; skip all this. Set the branch weight assuming this has the same
+  // probability of exiting the loop as any other loop exit.
+  uint64_t EntryCount = PGO.getCurrentRegionCount();
+  RegionCounter Cnt = getPGORegionCounter(&S);
   Builder.CreateCondBr(Builder.CreateICmpEQ(initialBufferLimit, zero, "iszero"),
-                       EmptyBB, LoopInitBB);
+                       EmptyBB, LoopInitBB,
+                       PGO.createBranchWeights(EntryCount, Cnt.getCount()));
 
   // Otherwise, initialize the loop.
   EmitBlock(LoopInitBB);
@@ -1537,6 +1545,8 @@
   llvm::PHINode *count = Builder.CreatePHI(UnsignedLongLTy, 3, "forcoll.count");
   count->addIncoming(initialBufferLimit, LoopInitBB);
 
+  Cnt.beginRegion(Builder);
+
   // Check whether the mutations value has changed from where it was
   // at start.  StateMutationsPtr should actually be invariant between
   // refreshes.
@@ -1644,8 +1654,12 @@
     = Builder.CreateAdd(index, llvm::ConstantInt::get(UnsignedLongLTy, 1));
 
   // If we haven't overrun the buffer yet, we can continue.
+  // Set the branch weights based on the simplifying assumption that this is
+  // like a while-loop, i.e., ignoring that the false branch fetches more
+  // elements and then returns to the loop.
   Builder.CreateCondBr(Builder.CreateICmpULT(indexPlusOne, count),
-                       LoopBodyBB, FetchMoreBB);
+                       LoopBodyBB, FetchMoreBB,
+                       PGO.createBranchWeights(Cnt.getCount(), EntryCount));
 
   index->addIncoming(indexPlusOne, AfterBody.getBlock());
   count->addIncoming(count, AfterBody.getBlock());
@@ -1715,7 +1729,7 @@
     CallObjCRelease(llvm::Value *object) : object(object) {}
     llvm::Value *object;
 
-    void Emit(CodeGenFunction &CGF, Flags flags) {
+    void Emit(CodeGenFunction &CGF, Flags flags) override {
       // Releases at the end of the full-expression are imprecise.
       CGF.EmitARCRelease(object, ARCImpreciseLifetime);
     }
@@ -1857,7 +1871,7 @@
   };
   llvm::CallInst *result = CGF.EmitNounwindRuntimeCall(fn, args);
 
-  if (ignored) return 0;
+  if (ignored) return nullptr;
 
   return CGF.Builder.CreateBitCast(result, origType);
 }
@@ -2055,7 +2069,7 @@
   };
   EmitNounwindRuntimeCall(fn, args);
 
-  if (ignored) return 0;
+  if (ignored) return nullptr;
   return value;
 }
 
@@ -2324,7 +2338,7 @@
 
     CallObjCAutoreleasePoolObject(llvm::Value *token) : Token(token) {}
 
-    void Emit(CodeGenFunction &CGF, Flags flags) {
+    void Emit(CodeGenFunction &CGF, Flags flags) override {
       CGF.EmitObjCAutoreleasePoolPop(Token);
     }
   };
@@ -2333,7 +2347,7 @@
 
     CallObjCMRRAutoreleasePoolObject(llvm::Value *token) : Token(token) {}
 
-    void Emit(CodeGenFunction &CGF, Flags flags) {
+    void Emit(CodeGenFunction &CGF, Flags flags) override {
       CGF.EmitObjCMRRAutoreleasePoolPop(Token);
     }
   };
@@ -2550,7 +2564,7 @@
 
   // The desired result type, if it differs from the type of the
   // ultimate opaque expression.
-  llvm::Type *resultType = 0;
+  llvm::Type *resultType = nullptr;
 
   while (true) {
     e = e->IgnoreParens();
@@ -2824,9 +2838,8 @@
     EHStack.pushCleanup<CallObjCMRRAutoreleasePoolObject>(NormalCleanup, token);
   }
 
-  for (CompoundStmt::const_body_iterator I = S.body_begin(),
-       E = S.body_end(); I != E; ++I)
-    EmitStmt(*I);
+  for (const auto *I : S.body())
+    EmitStmt(I);
 
   if (DI)
     DI->EmitLexicalBlockEnd(Builder, S.getRBracLoc());
@@ -2857,16 +2870,16 @@
                                         const ObjCPropertyImplDecl *PID) {
   if (!getLangOpts().CPlusPlus ||
       !getLangOpts().ObjCRuntime.hasAtomicCopyHelper())
-    return 0;
+    return nullptr;
   QualType Ty = PID->getPropertyIvarDecl()->getType();
   if (!Ty->isRecordType())
-    return 0;
+    return nullptr;
   const ObjCPropertyDecl *PD = PID->getPropertyDecl();
   if ((!(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_atomic)))
-    return 0;
-  llvm::Constant * HelperFn = 0;
+    return nullptr;
+  llvm::Constant *HelperFn = nullptr;
   if (hasTrivialSetExpr(PID))
-    return 0;
+    return nullptr;
   assert(PID->getSetterCXXAssignment() && "SetterCXXAssignment - null");
   if ((HelperFn = CGM.getAtomicSetterHelperFnMap(Ty)))
     return HelperFn;
@@ -2877,27 +2890,25 @@
   FunctionDecl *FD = FunctionDecl::Create(C,
                                           C.getTranslationUnitDecl(),
                                           SourceLocation(),
-                                          SourceLocation(), II, C.VoidTy, 0,
-                                          SC_Static,
+                                          SourceLocation(), II, C.VoidTy,
+                                          nullptr, SC_Static,
                                           false,
                                           false);
-  
+
   QualType DestTy = C.getPointerType(Ty);
   QualType SrcTy = Ty;
   SrcTy.addConst();
   SrcTy = C.getPointerType(SrcTy);
   
   FunctionArgList args;
-  ImplicitParamDecl dstDecl(FD, SourceLocation(), 0, DestTy);
+  ImplicitParamDecl dstDecl(getContext(), FD, SourceLocation(), nullptr,DestTy);
   args.push_back(&dstDecl);
-  ImplicitParamDecl srcDecl(FD, SourceLocation(), 0, SrcTy);
+  ImplicitParamDecl srcDecl(getContext(), FD, SourceLocation(), nullptr, SrcTy);
   args.push_back(&srcDecl);
-  
-  const CGFunctionInfo &FI =
-    CGM.getTypes().arrangeFunctionDeclaration(C.VoidTy, args,
-                                              FunctionType::ExtInfo(),
-                                              RequiredArgs::All);
-  
+
+  const CGFunctionInfo &FI = CGM.getTypes().arrangeFreeFunctionDeclaration(
+      C.VoidTy, args, FunctionType::ExtInfo(), RequiredArgs::All);
+
   llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI);
   
   llvm::Function *Fn =
@@ -2905,7 +2916,7 @@
                            "__assign_helper_atomic_property_",
                            &CGM.getModule());
   
-  StartFunction(FD, C.VoidTy, Fn, FI, args, SourceLocation());
+  StartFunction(FD, C.VoidTy, Fn, FI, args);
   
   DeclRefExpr DstExpr(&dstDecl, false, DestTy,
                       VK_RValue, SourceLocation());
@@ -2936,17 +2947,17 @@
                                             const ObjCPropertyImplDecl *PID) {
   if (!getLangOpts().CPlusPlus ||
       !getLangOpts().ObjCRuntime.hasAtomicCopyHelper())
-    return 0;
+    return nullptr;
   const ObjCPropertyDecl *PD = PID->getPropertyDecl();
   QualType Ty = PD->getType();
   if (!Ty->isRecordType())
-    return 0;
+    return nullptr;
   if ((!(PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_atomic)))
-    return 0;
-  llvm::Constant * HelperFn = 0;
-  
+    return nullptr;
+  llvm::Constant *HelperFn = nullptr;
+
   if (hasTrivialGetExpr(PID))
-    return 0;
+    return nullptr;
   assert(PID->getGetterCXXConstructor() && "getGetterCXXConstructor - null");
   if ((HelperFn = CGM.getAtomicGetterHelperFnMap(Ty)))
     return HelperFn;
@@ -2958,34 +2969,32 @@
   FunctionDecl *FD = FunctionDecl::Create(C,
                                           C.getTranslationUnitDecl(),
                                           SourceLocation(),
-                                          SourceLocation(), II, C.VoidTy, 0,
-                                          SC_Static,
+                                          SourceLocation(), II, C.VoidTy,
+                                          nullptr, SC_Static,
                                           false,
                                           false);
-  
+
   QualType DestTy = C.getPointerType(Ty);
   QualType SrcTy = Ty;
   SrcTy.addConst();
   SrcTy = C.getPointerType(SrcTy);
   
   FunctionArgList args;
-  ImplicitParamDecl dstDecl(FD, SourceLocation(), 0, DestTy);
+  ImplicitParamDecl dstDecl(getContext(), FD, SourceLocation(), nullptr,DestTy);
   args.push_back(&dstDecl);
-  ImplicitParamDecl srcDecl(FD, SourceLocation(), 0, SrcTy);
+  ImplicitParamDecl srcDecl(getContext(), FD, SourceLocation(), nullptr, SrcTy);
   args.push_back(&srcDecl);
-  
-  const CGFunctionInfo &FI =
-  CGM.getTypes().arrangeFunctionDeclaration(C.VoidTy, args,
-                                            FunctionType::ExtInfo(),
-                                            RequiredArgs::All);
-  
+
+  const CGFunctionInfo &FI = CGM.getTypes().arrangeFreeFunctionDeclaration(
+      C.VoidTy, args, FunctionType::ExtInfo(), RequiredArgs::All);
+
   llvm::FunctionType *LTy = CGM.getTypes().GetFunctionType(FI);
   
   llvm::Function *Fn =
   llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
                          "__copy_helper_atomic_property_", &CGM.getModule());
   
-  StartFunction(FD, C.VoidTy, Fn, FI, args, SourceLocation());
+  StartFunction(FD, C.VoidTy, Fn, FI, args);
   
   DeclRefExpr SrcExpr(&srcDecl, false, SrcTy,
                       VK_RValue, SourceLocation());
@@ -3012,6 +3021,7 @@
                              ConstructorArgs,
                              CXXConstExpr->hadMultipleCandidates(),
                              CXXConstExpr->isListInitialization(),
+                             CXXConstExpr->isStdInitListInitialization(),
                              CXXConstExpr->requiresZeroInitialization(),
                              CXXConstExpr->getConstructionKind(),
                              SourceRange());
@@ -3050,11 +3060,11 @@
   RValue Result;
   Result = Runtime.GenerateMessageSend(*this, ReturnValueSlot(),
                                        Ty, CopySelector,
-                                       Val, CallArgList(), 0, 0);
+                                       Val, CallArgList(), nullptr, nullptr);
   Val = Result.getScalarVal();
   Result = Runtime.GenerateMessageSend(*this, ReturnValueSlot(),
                                        Ty, AutoreleaseSelector,
-                                       Val, CallArgList(), 0, 0);
+                                       Val, CallArgList(), nullptr, nullptr);
   Val = Result.getScalarVal();
   return Val;
 }
diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp
index 5203e00..619a66a 100644
--- a/lib/CodeGen/CGObjCGNU.cpp
+++ b/lib/CodeGen/CGObjCGNU.cpp
@@ -27,11 +27,11 @@
 #include "clang/Basic/SourceManager.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringMap.h"
+#include "llvm/IR/CallSite.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/Intrinsics.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
-#include "llvm/Support/CallSite.h"
 #include "llvm/Support/Compiler.h"
 #include <cstdarg>
 
@@ -53,7 +53,8 @@
     /// Constructor leaves this class uninitialized, because it is intended to
     /// be used as a field in another class and not all of the types that are
     /// used as arguments will necessarily be available at construction time.
-    LazyRuntimeFunction() : CGM(0), FunctionName(0), Function(0) {}
+    LazyRuntimeFunction()
+      : CGM(nullptr), FunctionName(nullptr), Function(nullptr) {}
 
     /// Initialises the lazy function with the name, return type, and the types
     /// of the arguments.
@@ -62,7 +63,7 @@
         llvm::Type *RetTy, ...) {
        CGM =Mod;
        FunctionName = name;
-       Function = 0;
+       Function = nullptr;
        ArgTys.clear();
        va_list Args;
        va_start(Args, RetTy);
@@ -76,7 +77,7 @@
    /// LLVM constant.
    operator llvm::Constant*() {
      if (!Function) {
-       if (0 == FunctionName) return 0;
+       if (!FunctionName) return nullptr;
        // We put the return type on the end of the vector, so pop it back off
        llvm::Type *RetTy = ArgTys.back();
        ArgTys.pop_back();
@@ -236,9 +237,8 @@
       NameAndAttributes += TypeStr;
       NameAndAttributes += '\0';
       NameAndAttributes += PD->getNameAsString();
-      NameAndAttributes += '\0';
       return llvm::ConstantExpr::getGetElementPtr(
-          CGM.GetAddrOfConstantString(NameAndAttributes), Zeros);
+          CGM.GetAddrOfConstantCString(NameAndAttributes), Zeros);
     }
     return MakeConstantString(PD->getNameAsString());
   }
@@ -479,103 +479,92 @@
   CGObjCGNU(CodeGenModule &cgm, unsigned runtimeABIVersion,
       unsigned protocolClassVersion);
 
-  virtual llvm::Constant *GenerateConstantString(const StringLiteral *);
+  llvm::Constant *GenerateConstantString(const StringLiteral *) override;
 
-  virtual RValue
-  GenerateMessageSend(CodeGenFunction &CGF,
-                      ReturnValueSlot Return,
-                      QualType ResultType,
-                      Selector Sel,
-                      llvm::Value *Receiver,
-                      const CallArgList &CallArgs,
+  RValue
+  GenerateMessageSend(CodeGenFunction &CGF, ReturnValueSlot Return,
+                      QualType ResultType, Selector Sel,
+                      llvm::Value *Receiver, const CallArgList &CallArgs,
                       const ObjCInterfaceDecl *Class,
-                      const ObjCMethodDecl *Method);
-  virtual RValue
-  GenerateMessageSendSuper(CodeGenFunction &CGF,
-                           ReturnValueSlot Return,
-                           QualType ResultType,
-                           Selector Sel,
+                      const ObjCMethodDecl *Method) override;
+  RValue
+  GenerateMessageSendSuper(CodeGenFunction &CGF, ReturnValueSlot Return,
+                           QualType ResultType, Selector Sel,
                            const ObjCInterfaceDecl *Class,
-                           bool isCategoryImpl,
-                           llvm::Value *Receiver,
-                           bool IsClassMessage,
-                           const CallArgList &CallArgs,
-                           const ObjCMethodDecl *Method);
-  virtual llvm::Value *GetClass(CodeGenFunction &CGF,
-                                const ObjCInterfaceDecl *OID);
-  virtual llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel,
-                                   bool lval = false);
-  virtual llvm::Value *GetSelector(CodeGenFunction &CGF, const ObjCMethodDecl
-      *Method);
-  virtual llvm::Constant *GetEHType(QualType T);
+                           bool isCategoryImpl, llvm::Value *Receiver,
+                           bool IsClassMessage, const CallArgList &CallArgs,
+                           const ObjCMethodDecl *Method) override;
+  llvm::Value *GetClass(CodeGenFunction &CGF,
+                        const ObjCInterfaceDecl *OID) override;
+  llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel,
+                           bool lval = false) override;
+  llvm::Value *GetSelector(CodeGenFunction &CGF,
+                           const ObjCMethodDecl *Method) override;
+  llvm::Constant *GetEHType(QualType T) override;
 
-  virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
-                                         const ObjCContainerDecl *CD);
-  virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
-  virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
-  virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD);
-  virtual llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
-                                           const ObjCProtocolDecl *PD);
-  virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
-  virtual llvm::Function *ModuleInitFunction();
-  virtual llvm::Constant *GetPropertyGetFunction();
-  virtual llvm::Constant *GetPropertySetFunction();
-  virtual llvm::Constant *GetOptimizedPropertySetFunction(bool atomic, 
-                                                          bool copy);
-  virtual llvm::Constant *GetSetStructFunction();
-  virtual llvm::Constant *GetGetStructFunction();
-  virtual llvm::Constant *GetCppAtomicObjectGetFunction();
-  virtual llvm::Constant *GetCppAtomicObjectSetFunction();
-  virtual llvm::Constant *EnumerationMutationFunction();
+  llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
+                                 const ObjCContainerDecl *CD) override;
+  void GenerateCategory(const ObjCCategoryImplDecl *CMD) override;
+  void GenerateClass(const ObjCImplementationDecl *ClassDecl) override;
+  void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) override;
+  llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
+                                   const ObjCProtocolDecl *PD) override;
+  void GenerateProtocol(const ObjCProtocolDecl *PD) override;
+  llvm::Function *ModuleInitFunction() override;
+  llvm::Constant *GetPropertyGetFunction() override;
+  llvm::Constant *GetPropertySetFunction() override;
+  llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
+                                                  bool copy) override;
+  llvm::Constant *GetSetStructFunction() override;
+  llvm::Constant *GetGetStructFunction() override;
+  llvm::Constant *GetCppAtomicObjectGetFunction() override;
+  llvm::Constant *GetCppAtomicObjectSetFunction() override;
+  llvm::Constant *EnumerationMutationFunction() override;
 
-  virtual void EmitTryStmt(CodeGenFunction &CGF,
-                           const ObjCAtTryStmt &S);
-  virtual void EmitSynchronizedStmt(CodeGenFunction &CGF,
-                                    const ObjCAtSynchronizedStmt &S);
-  virtual void EmitThrowStmt(CodeGenFunction &CGF,
-                             const ObjCAtThrowStmt &S,
-                             bool ClearInsertionPoint=true);
-  virtual llvm::Value * EmitObjCWeakRead(CodeGenFunction &CGF,
-                                         llvm::Value *AddrWeakObj);
-  virtual void EmitObjCWeakAssign(CodeGenFunction &CGF,
-                                  llvm::Value *src, llvm::Value *dst);
-  virtual void EmitObjCGlobalAssign(CodeGenFunction &CGF,
-                                    llvm::Value *src, llvm::Value *dest,
-                                    bool threadlocal=false);
-  virtual void EmitObjCIvarAssign(CodeGenFunction &CGF,
-                                    llvm::Value *src, llvm::Value *dest,
-                                    llvm::Value *ivarOffset);
-  virtual void EmitObjCStrongCastAssign(CodeGenFunction &CGF,
-                                        llvm::Value *src, llvm::Value *dest);
-  virtual void EmitGCMemmoveCollectable(CodeGenFunction &CGF,
-                                        llvm::Value *DestPtr,
-                                        llvm::Value *SrcPtr,
-                                        llvm::Value *Size);
-  virtual LValue EmitObjCValueForIvar(CodeGenFunction &CGF,
-                                      QualType ObjectTy,
-                                      llvm::Value *BaseValue,
-                                      const ObjCIvarDecl *Ivar,
-                                      unsigned CVRQualifiers);
-  virtual llvm::Value *EmitIvarOffset(CodeGenFunction &CGF,
-                                      const ObjCInterfaceDecl *Interface,
-                                      const ObjCIvarDecl *Ivar);
-  virtual llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF);
-  virtual llvm::Constant *BuildGCBlockLayout(CodeGenModule &CGM,
-                                             const CGBlockInfo &blockInfo) {
+  void EmitTryStmt(CodeGenFunction &CGF,
+                   const ObjCAtTryStmt &S) override;
+  void EmitSynchronizedStmt(CodeGenFunction &CGF,
+                            const ObjCAtSynchronizedStmt &S) override;
+  void EmitThrowStmt(CodeGenFunction &CGF,
+                     const ObjCAtThrowStmt &S,
+                     bool ClearInsertionPoint=true) override;
+  llvm::Value * EmitObjCWeakRead(CodeGenFunction &CGF,
+                                 llvm::Value *AddrWeakObj) override;
+  void EmitObjCWeakAssign(CodeGenFunction &CGF,
+                          llvm::Value *src, llvm::Value *dst) override;
+  void EmitObjCGlobalAssign(CodeGenFunction &CGF,
+                            llvm::Value *src, llvm::Value *dest,
+                            bool threadlocal=false) override;
+  void EmitObjCIvarAssign(CodeGenFunction &CGF, llvm::Value *src,
+                          llvm::Value *dest, llvm::Value *ivarOffset) override;
+  void EmitObjCStrongCastAssign(CodeGenFunction &CGF,
+                                llvm::Value *src, llvm::Value *dest) override;
+  void EmitGCMemmoveCollectable(CodeGenFunction &CGF, llvm::Value *DestPtr,
+                                llvm::Value *SrcPtr,
+                                llvm::Value *Size) override;
+  LValue EmitObjCValueForIvar(CodeGenFunction &CGF, QualType ObjectTy,
+                              llvm::Value *BaseValue, const ObjCIvarDecl *Ivar,
+                              unsigned CVRQualifiers) override;
+  llvm::Value *EmitIvarOffset(CodeGenFunction &CGF,
+                              const ObjCInterfaceDecl *Interface,
+                              const ObjCIvarDecl *Ivar) override;
+  llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) override;
+  llvm::Constant *BuildGCBlockLayout(CodeGenModule &CGM,
+                                     const CGBlockInfo &blockInfo) override {
     return NULLPtr;
   }
-  virtual llvm::Constant *BuildRCBlockLayout(CodeGenModule &CGM,
-                                             const CGBlockInfo &blockInfo) {
+  llvm::Constant *BuildRCBlockLayout(CodeGenModule &CGM,
+                                     const CGBlockInfo &blockInfo) override {
     return NULLPtr;
   }
-  
-  virtual llvm::Constant *BuildByrefLayout(CodeGenModule &CGM,
-                                           QualType T) {
+
+  llvm::Constant *BuildByrefLayout(CodeGenModule &CGM, QualType T) override {
     return NULLPtr;
   }
-  
-  virtual llvm::GlobalVariable *GetClassGlobal(const std::string &Name) {
-    return 0;
+
+  llvm::GlobalVariable *GetClassGlobal(const std::string &Name,
+                                       bool Weak = false) override {
+    return nullptr;
   }
 };
 /// Class representing the legacy GCC Objective-C ABI.  This is the default when
@@ -595,11 +584,9 @@
   /// arguments.  Returns the IMP for the corresponding method.
   LazyRuntimeFunction MsgLookupSuperFn;
 protected:
-  virtual llvm::Value *LookupIMP(CodeGenFunction &CGF,
-                                 llvm::Value *&Receiver,
-                                 llvm::Value *cmd,
-                                 llvm::MDNode *node,
-                                 MessageSendInfo &MSI) {
+  llvm::Value *LookupIMP(CodeGenFunction &CGF, llvm::Value *&Receiver,
+                         llvm::Value *cmd, llvm::MDNode *node,
+                         MessageSendInfo &MSI) override {
     CGBuilderTy &Builder = CGF.Builder;
     llvm::Value *args[] = {
             EnforceType(Builder, Receiver, IdTy),
@@ -608,10 +595,8 @@
     imp->setMetadata(msgSendMDKind, node);
     return imp.getInstruction();
   }
-  virtual llvm::Value *LookupIMPSuper(CodeGenFunction &CGF,
-                                      llvm::Value *ObjCSuper,
-                                      llvm::Value *cmd,
-                                      MessageSendInfo &MSI) {
+  llvm::Value *LookupIMPSuper(CodeGenFunction &CGF, llvm::Value *ObjCSuper,
+                              llvm::Value *cmd, MessageSendInfo &MSI) override {
       CGBuilderTy &Builder = CGF.Builder;
       llvm::Value *lookupArgs[] = {EnforceType(Builder, ObjCSuper,
           PtrToObjCSuperTy), cmd};
@@ -620,10 +605,11 @@
   public:
     CGObjCGCC(CodeGenModule &Mod) : CGObjCGNU(Mod, 8, 2) {
       // IMP objc_msg_lookup(id, SEL);
-      MsgLookupFn.init(&CGM, "objc_msg_lookup", IMPTy, IdTy, SelectorTy, NULL);
+      MsgLookupFn.init(&CGM, "objc_msg_lookup", IMPTy, IdTy, SelectorTy,
+                       nullptr);
       // IMP objc_msg_lookup_super(struct objc_super*, SEL);
       MsgLookupSuperFn.init(&CGM, "objc_msg_lookup_super", IMPTy,
-              PtrToObjCSuperTy, SelectorTy, NULL);
+              PtrToObjCSuperTy, SelectorTy, nullptr);
     }
 };
 /// Class used when targeting the new GNUstep runtime ABI.
@@ -654,13 +640,11 @@
     /// lookup functions.
     llvm::Type *SlotTy;
   public:
-    virtual llvm::Constant *GetEHType(QualType T);
+    llvm::Constant *GetEHType(QualType T) override;
   protected:
-    virtual llvm::Value *LookupIMP(CodeGenFunction &CGF,
-                                   llvm::Value *&Receiver,
-                                   llvm::Value *cmd,
-                                   llvm::MDNode *node,
-                                   MessageSendInfo &MSI) {
+    llvm::Value *LookupIMP(CodeGenFunction &CGF, llvm::Value *&Receiver,
+                           llvm::Value *cmd, llvm::MDNode *node,
+                           MessageSendInfo &MSI) override {
       CGBuilderTy &Builder = CGF.Builder;
       llvm::Function *LookupFn = SlotLookupFn;
 
@@ -696,10 +680,9 @@
       Receiver = Builder.CreateLoad(ReceiverPtr, true);
       return imp;
     }
-    virtual llvm::Value *LookupIMPSuper(CodeGenFunction &CGF,
-                                        llvm::Value *ObjCSuper,
-                                        llvm::Value *cmd,
-                                        MessageSendInfo &MSI) {
+    llvm::Value *LookupIMPSuper(CodeGenFunction &CGF, llvm::Value *ObjCSuper,
+                                llvm::Value *cmd,
+                                MessageSendInfo &MSI) override {
       CGBuilderTy &Builder = CGF.Builder;
       llvm::Value *lookupArgs[] = {ObjCSuper, cmd};
 
@@ -714,68 +697,68 @@
       const ObjCRuntime &R = CGM.getLangOpts().ObjCRuntime;
 
       llvm::StructType *SlotStructTy = llvm::StructType::get(PtrTy,
-          PtrTy, PtrTy, IntTy, IMPTy, NULL);
+          PtrTy, PtrTy, IntTy, IMPTy, nullptr);
       SlotTy = llvm::PointerType::getUnqual(SlotStructTy);
       // Slot_t objc_msg_lookup_sender(id *receiver, SEL selector, id sender);
       SlotLookupFn.init(&CGM, "objc_msg_lookup_sender", SlotTy, PtrToIdTy,
-          SelectorTy, IdTy, NULL);
+          SelectorTy, IdTy, nullptr);
       // Slot_t objc_msg_lookup_super(struct objc_super*, SEL);
       SlotLookupSuperFn.init(&CGM, "objc_slot_lookup_super", SlotTy,
-              PtrToObjCSuperTy, SelectorTy, NULL);
+              PtrToObjCSuperTy, SelectorTy, nullptr);
       // If we're in ObjC++ mode, then we want to make 
       if (CGM.getLangOpts().CPlusPlus) {
         llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
         // void *__cxa_begin_catch(void *e)
-        EnterCatchFn.init(&CGM, "__cxa_begin_catch", PtrTy, PtrTy, NULL);
+        EnterCatchFn.init(&CGM, "__cxa_begin_catch", PtrTy, PtrTy, nullptr);
         // void __cxa_end_catch(void)
-        ExitCatchFn.init(&CGM, "__cxa_end_catch", VoidTy, NULL);
+        ExitCatchFn.init(&CGM, "__cxa_end_catch", VoidTy, nullptr);
         // void _Unwind_Resume_or_Rethrow(void*)
         ExceptionReThrowFn.init(&CGM, "_Unwind_Resume_or_Rethrow", VoidTy,
-            PtrTy, NULL);
+            PtrTy, nullptr);
       } else if (R.getVersion() >= VersionTuple(1, 7)) {
         llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
         // id objc_begin_catch(void *e)
-        EnterCatchFn.init(&CGM, "objc_begin_catch", IdTy, PtrTy, NULL);
+        EnterCatchFn.init(&CGM, "objc_begin_catch", IdTy, PtrTy, nullptr);
         // void objc_end_catch(void)
-        ExitCatchFn.init(&CGM, "objc_end_catch", VoidTy, NULL);
+        ExitCatchFn.init(&CGM, "objc_end_catch", VoidTy, nullptr);
         // void _Unwind_Resume_or_Rethrow(void*)
         ExceptionReThrowFn.init(&CGM, "objc_exception_rethrow", VoidTy,
-            PtrTy, NULL);
+            PtrTy, nullptr);
       }
       llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
       SetPropertyAtomic.init(&CGM, "objc_setProperty_atomic", VoidTy, IdTy,
-          SelectorTy, IdTy, PtrDiffTy, NULL);
+          SelectorTy, IdTy, PtrDiffTy, nullptr);
       SetPropertyAtomicCopy.init(&CGM, "objc_setProperty_atomic_copy", VoidTy,
-          IdTy, SelectorTy, IdTy, PtrDiffTy, NULL);
+          IdTy, SelectorTy, IdTy, PtrDiffTy, nullptr);
       SetPropertyNonAtomic.init(&CGM, "objc_setProperty_nonatomic", VoidTy,
-          IdTy, SelectorTy, IdTy, PtrDiffTy, NULL);
+          IdTy, SelectorTy, IdTy, PtrDiffTy, nullptr);
       SetPropertyNonAtomicCopy.init(&CGM, "objc_setProperty_nonatomic_copy",
-          VoidTy, IdTy, SelectorTy, IdTy, PtrDiffTy, NULL);
+          VoidTy, IdTy, SelectorTy, IdTy, PtrDiffTy, nullptr);
       // void objc_setCppObjectAtomic(void *dest, const void *src, void
       // *helper);
       CxxAtomicObjectSetFn.init(&CGM, "objc_setCppObjectAtomic", VoidTy, PtrTy,
-          PtrTy, PtrTy, NULL);
+          PtrTy, PtrTy, nullptr);
       // void objc_getCppObjectAtomic(void *dest, const void *src, void
       // *helper);
       CxxAtomicObjectGetFn.init(&CGM, "objc_getCppObjectAtomic", VoidTy, PtrTy,
-          PtrTy, PtrTy, NULL);
+          PtrTy, PtrTy, nullptr);
     }
-    virtual llvm::Constant *GetCppAtomicObjectGetFunction() {
+    llvm::Constant *GetCppAtomicObjectGetFunction() override {
       // The optimised functions were added in version 1.7 of the GNUstep
       // runtime.
       assert (CGM.getLangOpts().ObjCRuntime.getVersion() >=
           VersionTuple(1, 7));
       return CxxAtomicObjectGetFn;
     }
-    virtual llvm::Constant *GetCppAtomicObjectSetFunction() {
+    llvm::Constant *GetCppAtomicObjectSetFunction() override {
       // The optimised functions were added in version 1.7 of the GNUstep
       // runtime.
       assert (CGM.getLangOpts().ObjCRuntime.getVersion() >=
           VersionTuple(1, 7));
       return CxxAtomicObjectSetFn;
     }
-    virtual llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
-                                                            bool copy) {
+    llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
+                                                    bool copy) override {
       // The optimised property functions omit the GC check, and so are not
       // safe to use in GC mode.  The standard functions are fast in GC mode,
       // so there is less advantage in using them.
@@ -789,15 +772,12 @@
         if (copy) return SetPropertyAtomicCopy;
         return SetPropertyAtomic;
       }
-      if (copy) return SetPropertyNonAtomicCopy;
-      return SetPropertyNonAtomic;
 
-      return 0;
+      return copy ? SetPropertyNonAtomicCopy : SetPropertyNonAtomic;
     }
 };
 
-/// Support for the ObjFW runtime. Support here is due to
-/// Jonathan Schleifer <js@webkeks.org>, the ObjFW maintainer.
+/// Support for the ObjFW runtime.
 class CGObjCObjFW: public CGObjCGNU {
 protected:
   /// The GCC ABI message lookup function.  Returns an IMP pointing to the
@@ -811,11 +791,9 @@
   /// arguments.  Returns the IMP for the corresponding method.
   LazyRuntimeFunction MsgLookupSuperFn, MsgLookupSuperFnSRet;
 
-  virtual llvm::Value *LookupIMP(CodeGenFunction &CGF,
-                                 llvm::Value *&Receiver,
-                                 llvm::Value *cmd,
-                                 llvm::MDNode *node,
-                                 MessageSendInfo &MSI) {
+  llvm::Value *LookupIMP(CodeGenFunction &CGF, llvm::Value *&Receiver,
+                         llvm::Value *cmd, llvm::MDNode *node,
+                         MessageSendInfo &MSI) override {
     CGBuilderTy &Builder = CGF.Builder;
     llvm::Value *args[] = {
             EnforceType(Builder, Receiver, IdTy),
@@ -831,10 +809,8 @@
     return imp.getInstruction();
   }
 
-  virtual llvm::Value *LookupIMPSuper(CodeGenFunction &CGF,
-                                      llvm::Value *ObjCSuper,
-                                      llvm::Value *cmd,
-                                      MessageSendInfo &MSI) {
+  llvm::Value *LookupIMPSuper(CodeGenFunction &CGF, llvm::Value *ObjCSuper,
+                              llvm::Value *cmd, MessageSendInfo &MSI) override {
       CGBuilderTy &Builder = CGF.Builder;
       llvm::Value *lookupArgs[] = {EnforceType(Builder, ObjCSuper,
           PtrToObjCSuperTy), cmd};
@@ -845,8 +821,8 @@
         return CGF.EmitNounwindRuntimeCall(MsgLookupSuperFn, lookupArgs);
     }
 
-  virtual llvm::Value *GetClassNamed(CodeGenFunction &CGF,
-                                     const std::string &Name, bool isWeak) {
+  llvm::Value *GetClassNamed(CodeGenFunction &CGF,
+                             const std::string &Name, bool isWeak) override {
     if (isWeak)
       return CGObjCGNU::GetClassNamed(CGF, Name, isWeak);
 
@@ -859,7 +835,7 @@
     if (!ClassSymbol)
       ClassSymbol = new llvm::GlobalVariable(TheModule, LongTy, false,
                                              llvm::GlobalValue::ExternalLinkage,
-                                             0, SymbolName);
+                                             nullptr, SymbolName);
 
     return ClassSymbol;
   }
@@ -867,14 +843,14 @@
 public:
   CGObjCObjFW(CodeGenModule &Mod): CGObjCGNU(Mod, 9, 3) {
     // IMP objc_msg_lookup(id, SEL);
-    MsgLookupFn.init(&CGM, "objc_msg_lookup", IMPTy, IdTy, SelectorTy, NULL);
+    MsgLookupFn.init(&CGM, "objc_msg_lookup", IMPTy, IdTy, SelectorTy, nullptr);
     MsgLookupFnSRet.init(&CGM, "objc_msg_lookup_stret", IMPTy, IdTy,
-                         SelectorTy, NULL);
+                         SelectorTy, nullptr);
     // IMP objc_msg_lookup_super(struct objc_super*, SEL);
     MsgLookupSuperFn.init(&CGM, "objc_msg_lookup_super", IMPTy,
-                          PtrToObjCSuperTy, SelectorTy, NULL);
+                          PtrToObjCSuperTy, SelectorTy, nullptr);
     MsgLookupSuperFnSRet.init(&CGM, "objc_msg_lookup_super_stret", IMPTy,
-                              PtrToObjCSuperTy, SelectorTy, NULL);
+                              PtrToObjCSuperTy, SelectorTy, nullptr);
   }
 };
 } // end anonymous namespace
@@ -892,7 +868,8 @@
   llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(symbolName);
   if (!ClassSymbol) {
     ClassSymbol = new llvm::GlobalVariable(TheModule, LongTy, false,
-        llvm::GlobalValue::ExternalLinkage, 0, symbolName);
+                                           llvm::GlobalValue::ExternalLinkage,
+                                           nullptr, symbolName);
   }
   new llvm::GlobalVariable(TheModule, ClassSymbol->getType(), true,
     llvm::GlobalValue::WeakAnyLinkage, ClassSymbol, symbolRef);
@@ -909,10 +886,11 @@
 }
 
 CGObjCGNU::CGObjCGNU(CodeGenModule &cgm, unsigned runtimeABIVersion,
-    unsigned protocolClassVersion)
+                     unsigned protocolClassVersion)
   : CGObjCRuntime(cgm), TheModule(CGM.getModule()),
-    VMContext(cgm.getLLVMContext()), ClassPtrAlias(0), MetaClassPtrAlias(0),
-    RuntimeVersion(runtimeABIVersion), ProtocolVersion(protocolClassVersion) {
+    VMContext(cgm.getLLVMContext()), ClassPtrAlias(nullptr),
+    MetaClassPtrAlias(nullptr), RuntimeVersion(runtimeABIVersion),
+    ProtocolVersion(protocolClassVersion) {
 
   msgSendMDKind = VMContext.getMDKindID("GNUObjCMessageSend");
 
@@ -949,7 +927,7 @@
   Int64Ty = llvm::Type::getInt64Ty(VMContext);
 
   IntPtrTy =
-      TheModule.getPointerSize() == llvm::Module::Pointer32 ? Int32Ty : Int64Ty;
+      CGM.getDataLayout().getPointerSizeInBits() == 32 ? Int32Ty : Int64Ty;
 
   // Object type
   QualType UnqualIdTy = CGM.getContext().getObjCIdType();
@@ -962,35 +940,35 @@
   }
   PtrToIdTy = llvm::PointerType::getUnqual(IdTy);
 
-  ObjCSuperTy = llvm::StructType::get(IdTy, IdTy, NULL);
+  ObjCSuperTy = llvm::StructType::get(IdTy, IdTy, nullptr);
   PtrToObjCSuperTy = llvm::PointerType::getUnqual(ObjCSuperTy);
 
   llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
 
   // void objc_exception_throw(id);
-  ExceptionThrowFn.init(&CGM, "objc_exception_throw", VoidTy, IdTy, NULL);
-  ExceptionReThrowFn.init(&CGM, "objc_exception_throw", VoidTy, IdTy, NULL);
+  ExceptionThrowFn.init(&CGM, "objc_exception_throw", VoidTy, IdTy, nullptr);
+  ExceptionReThrowFn.init(&CGM, "objc_exception_throw", VoidTy, IdTy, nullptr);
   // int objc_sync_enter(id);
-  SyncEnterFn.init(&CGM, "objc_sync_enter", IntTy, IdTy, NULL);
+  SyncEnterFn.init(&CGM, "objc_sync_enter", IntTy, IdTy, nullptr);
   // int objc_sync_exit(id);
-  SyncExitFn.init(&CGM, "objc_sync_exit", IntTy, IdTy, NULL);
+  SyncExitFn.init(&CGM, "objc_sync_exit", IntTy, IdTy, nullptr);
 
   // void objc_enumerationMutation (id)
   EnumerationMutationFn.init(&CGM, "objc_enumerationMutation", VoidTy,
-      IdTy, NULL);
+      IdTy, nullptr);
 
   // id objc_getProperty(id, SEL, ptrdiff_t, BOOL)
   GetPropertyFn.init(&CGM, "objc_getProperty", IdTy, IdTy, SelectorTy,
-      PtrDiffTy, BoolTy, NULL);
+      PtrDiffTy, BoolTy, nullptr);
   // void objc_setProperty(id, SEL, ptrdiff_t, id, BOOL, BOOL)
   SetPropertyFn.init(&CGM, "objc_setProperty", VoidTy, IdTy, SelectorTy,
-      PtrDiffTy, IdTy, BoolTy, BoolTy, NULL);
+      PtrDiffTy, IdTy, BoolTy, BoolTy, nullptr);
   // void objc_setPropertyStruct(void*, void*, ptrdiff_t, BOOL, BOOL)
   GetStructPropertyFn.init(&CGM, "objc_getPropertyStruct", VoidTy, PtrTy, PtrTy, 
-      PtrDiffTy, BoolTy, BoolTy, NULL);
+      PtrDiffTy, BoolTy, BoolTy, nullptr);
   // void objc_setPropertyStruct(void*, void*, ptrdiff_t, BOOL, BOOL)
   SetStructPropertyFn.init(&CGM, "objc_setPropertyStruct", VoidTy, PtrTy, PtrTy, 
-      PtrDiffTy, BoolTy, BoolTy, NULL);
+      PtrDiffTy, BoolTy, BoolTy, nullptr);
 
   // IMP type
   llvm::Type *IMPArgs[] = { IdTy, SelectorTy };
@@ -1015,20 +993,20 @@
 
     // id objc_assign_ivar(id, id, ptrdiff_t);
     IvarAssignFn.init(&CGM, "objc_assign_ivar", IdTy, IdTy, IdTy, PtrDiffTy,
-        NULL);
+        nullptr);
     // id objc_assign_strongCast (id, id*)
     StrongCastAssignFn.init(&CGM, "objc_assign_strongCast", IdTy, IdTy,
-        PtrToIdTy, NULL);
+        PtrToIdTy, nullptr);
     // id objc_assign_global(id, id*);
     GlobalAssignFn.init(&CGM, "objc_assign_global", IdTy, IdTy, PtrToIdTy,
-        NULL);
+        nullptr);
     // id objc_assign_weak(id, id*);
-    WeakAssignFn.init(&CGM, "objc_assign_weak", IdTy, IdTy, PtrToIdTy, NULL);
+    WeakAssignFn.init(&CGM, "objc_assign_weak", IdTy, IdTy, PtrToIdTy, nullptr);
     // id objc_read_weak(id*);
-    WeakReadFn.init(&CGM, "objc_read_weak", IdTy, PtrToIdTy, NULL);
+    WeakReadFn.init(&CGM, "objc_read_weak", IdTy, PtrToIdTy, nullptr);
     // void *objc_memmove_collectable(void*, void *, size_t);
     MemMoveFn.init(&CGM, "objc_memmove_collectable", PtrTy, PtrTy, PtrTy,
-        SizeTy, NULL);
+        SizeTy, nullptr);
   }
 }
 
@@ -1067,8 +1045,7 @@
     const std::string &TypeEncoding, bool lval) {
 
   SmallVectorImpl<TypedSelector> &Types = SelectorTable[Sel];
-  llvm::GlobalAlias *SelValue = 0;
-
+  llvm::GlobalAlias *SelValue = nullptr;
 
   for (SmallVectorImpl<TypedSelector>::iterator i = Types.begin(),
       e = Types.end() ; i!=e ; i++) {
@@ -1077,11 +1054,10 @@
       break;
     }
   }
-  if (0 == SelValue) {
-    SelValue = new llvm::GlobalAlias(SelectorTy,
-                                     llvm::GlobalValue::PrivateLinkage,
-                                     ".objc_selector_"+Sel.getAsString(), NULL,
-                                     &TheModule);
+  if (!SelValue) {
+    SelValue = llvm::GlobalAlias::create(
+        SelectorTy->getElementType(), 0, llvm::GlobalValue::PrivateLinkage,
+        ".objc_selector_" + Sel.getAsString(), &TheModule);
     Types.push_back(TypedSelector(TypeEncoding, SelValue));
   }
 
@@ -1114,7 +1090,7 @@
     if (CGM.getLangOpts().ObjCRuntime.isNonFragile()) {
       return MakeConstantString("@id");
     } else {
-      return 0;
+      return nullptr;
     }
   }
 
@@ -1143,7 +1119,7 @@
         new llvm::GlobalVariable(CGM.getModule(), PtrToInt8Ty,
                                  false,
                                  llvm::GlobalValue::ExternalLinkage,
-                                 0, "__objc_id_type_info");
+                                 nullptr, "__objc_id_type_info");
     return llvm::ConstantExpr::getBitCast(IDEHType, PtrToInt8Ty);
   }
 
@@ -1170,7 +1146,8 @@
   llvm::Constant *Vtable = TheModule.getGlobalVariable(vtableName);
   if (!Vtable) {
     Vtable = new llvm::GlobalVariable(TheModule, PtrToInt8Ty, true,
-            llvm::GlobalValue::ExternalLinkage, 0, vtableName);
+                                      llvm::GlobalValue::ExternalLinkage,
+                                      nullptr, vtableName);
   }
   llvm::Constant *Two = llvm::ConstantInt::get(IntTy, 2);
   Vtable = llvm::ConstantExpr::getGetElementPtr(Vtable, Two);
@@ -1184,7 +1161,7 @@
   fields.push_back(typeName);
   llvm::Constant *TI = 
       MakeGlobal(llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty,
-              NULL), fields, "__objc_eh_typeinfo_" + className,
+              nullptr), fields, "__objc_eh_typeinfo_" + className,
           llvm::GlobalValue::LinkOnceODRLinkage);
   return llvm::ConstantExpr::getBitCast(TI, PtrToInt8Ty);
 }
@@ -1210,7 +1187,7 @@
 
   if (!isa)
     isa = new llvm::GlobalVariable(TheModule, IdTy, /* isConstant */false,
-            llvm::GlobalValue::ExternalWeakLinkage, 0, Sym);
+            llvm::GlobalValue::ExternalWeakLinkage, nullptr, Sym);
   else if (isa->getType() != PtrToIdTy)
     isa = llvm::ConstantExpr::getBitCast(isa, PtrToIdTy);
 
@@ -1219,7 +1196,7 @@
   Ivars.push_back(MakeConstantString(Str));
   Ivars.push_back(llvm::ConstantInt::get(IntTy, Str.size()));
   llvm::Constant *ObjCStr = MakeGlobal(
-    llvm::StructType::get(PtrToIdTy, PtrToInt8Ty, IntTy, NULL),
+    llvm::StructType::get(PtrToIdTy, PtrToInt8Ty, IntTy, nullptr),
     Ivars, ".objc_str");
   ObjCStr = llvm::ConstantExpr::getBitCast(ObjCStr, PtrToInt8Ty);
   ObjCStrings[Str] = ObjCStr;
@@ -1248,7 +1225,7 @@
                   CGM.getTypes().ConvertType(ResultType)));
     }
     if (Sel == ReleaseSel) {
-      return RValue::get(0);
+      return RValue::get(nullptr);
     }
   }
 
@@ -1263,9 +1240,9 @@
 
   MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
 
-  llvm::Value *ReceiverClass = 0;
+  llvm::Value *ReceiverClass = nullptr;
   if (isCategoryImpl) {
-    llvm::Constant *classLookupFunction = 0;
+    llvm::Constant *classLookupFunction = nullptr;
     if (IsClassMessage)  {
       classLookupFunction = CGM.CreateRuntimeFunction(llvm::FunctionType::get(
             IdTy, PtrTy, true), "objc_get_meta_class");
@@ -1283,16 +1260,16 @@
     // super_class pointer from either the class or metaclass structure.
     if (IsClassMessage)  {
       if (!MetaClassPtrAlias) {
-        MetaClassPtrAlias = new llvm::GlobalAlias(IdTy,
-            llvm::GlobalValue::InternalLinkage, ".objc_metaclass_ref" +
-            Class->getNameAsString(), NULL, &TheModule);
+        MetaClassPtrAlias = llvm::GlobalAlias::create(
+            IdTy->getElementType(), 0, llvm::GlobalValue::InternalLinkage,
+            ".objc_metaclass_ref" + Class->getNameAsString(), &TheModule);
       }
       ReceiverClass = MetaClassPtrAlias;
     } else {
       if (!ClassPtrAlias) {
-        ClassPtrAlias = new llvm::GlobalAlias(IdTy,
-            llvm::GlobalValue::InternalLinkage, ".objc_class_ref" +
-            Class->getNameAsString(), NULL, &TheModule);
+        ClassPtrAlias = llvm::GlobalAlias::create(
+            IdTy->getElementType(), 0, llvm::GlobalValue::InternalLinkage,
+            ".objc_class_ref" + Class->getNameAsString(), &TheModule);
       }
       ReceiverClass = ClassPtrAlias;
     }
@@ -1300,14 +1277,14 @@
   // Cast the pointer to a simplified version of the class structure
   ReceiverClass = Builder.CreateBitCast(ReceiverClass,
       llvm::PointerType::getUnqual(
-        llvm::StructType::get(IdTy, IdTy, NULL)));
+        llvm::StructType::get(IdTy, IdTy, nullptr)));
   // Get the superclass pointer
   ReceiverClass = Builder.CreateStructGEP(ReceiverClass, 1);
   // Load the superclass pointer
   ReceiverClass = Builder.CreateLoad(ReceiverClass);
   // Construct the structure used to look up the IMP
   llvm::StructType *ObjCSuperTy = llvm::StructType::get(
-      Receiver->getType(), IdTy, NULL);
+      Receiver->getType(), IdTy, nullptr);
   llvm::Value *ObjCSuper = Builder.CreateAlloca(ObjCSuperTy);
 
   Builder.CreateStore(Receiver, Builder.CreateStructGEP(ObjCSuper, 0));
@@ -1327,7 +1304,8 @@
   llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD);
 
   llvm::Instruction *call;
-  RValue msgRet = CGF.EmitCall(MSI.CallInfo, imp, Return, ActualArgs, 0, &call);
+  RValue msgRet = CGF.EmitCall(MSI.CallInfo, imp, Return, ActualArgs, nullptr,
+                               &call);
   call->setMetadata(msgSendMDKind, node);
   return msgRet;
 }
@@ -1351,7 +1329,7 @@
                   CGM.getTypes().ConvertType(ResultType)));
     }
     if (Sel == ReleaseSel) {
-      return RValue::get(0);
+      return RValue::get(nullptr);
     }
   }
 
@@ -1369,9 +1347,9 @@
   bool isPointerSizedReturn = (ResultType->isAnyPointerType() ||
       ResultType->isIntegralOrEnumerationType() || ResultType->isVoidType());
 
-  llvm::BasicBlock *startBB = 0;
-  llvm::BasicBlock *messageBB = 0;
-  llvm::BasicBlock *continueBB = 0;
+  llvm::BasicBlock *startBB = nullptr;
+  llvm::BasicBlock *messageBB = nullptr;
+  llvm::BasicBlock *continueBB = nullptr;
 
   if (!isPointerSizedReturn) {
     startBB = Builder.GetInsertBlock();
@@ -1396,7 +1374,8 @@
   llvm::Value *impMD[] = {
         llvm::MDString::get(VMContext, Sel.getAsString()),
         llvm::MDString::get(VMContext, Class ? Class->getNameAsString() :""),
-        llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), Class!=0)
+        llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext),
+                               Class!=nullptr)
    };
   llvm::MDNode *node = llvm::MDNode::get(VMContext, impMD);
 
@@ -1439,7 +1418,8 @@
   imp = EnforceType(Builder, imp, MSI.MessengerType);
 
   llvm::Instruction *call;
-  RValue msgRet = CGF.EmitCall(MSI.CallInfo, imp, Return, ActualArgs, 0, &call);
+  RValue msgRet = CGF.EmitCall(MSI.CallInfo, imp, Return, ActualArgs, nullptr,
+                               &call);
   call->setMetadata(msgSendMDKind, node);
 
 
@@ -1495,7 +1475,7 @@
     PtrToInt8Ty, // Really a selector, but the runtime creates it us.
     PtrToInt8Ty, // Method types
     IMPTy, //Method pointer
-    NULL);
+    nullptr);
   std::vector<llvm::Constant*> Methods;
   std::vector<llvm::Constant*> Elements;
   for (unsigned int i = 0, e = MethodTypes.size(); i < e; ++i) {
@@ -1527,7 +1507,7 @@
       NextPtrTy,
       IntTy,
       ObjCMethodArrayTy,
-      NULL);
+      nullptr);
 
   Methods.clear();
   Methods.push_back(llvm::ConstantPointerNull::get(
@@ -1551,7 +1531,7 @@
     PtrToInt8Ty,
     PtrToInt8Ty,
     IntTy,
-    NULL);
+    nullptr);
   std::vector<llvm::Constant*> Ivars;
   std::vector<llvm::Constant*> Elements;
   for (unsigned int i = 0, e = IvarNames.size() ; i < e ; i++) {
@@ -1573,7 +1553,7 @@
   // Structure containing array and array count
   llvm::StructType *ObjCIvarListTy = llvm::StructType::get(IntTy,
     ObjCIvarArrayTy,
-    NULL);
+    nullptr);
 
   // Create an instance of the structure
   return MakeGlobal(ObjCIvarListTy, Elements, ".objc_ivar_list");
@@ -1623,7 +1603,7 @@
       Properties->getType(),  // properties
       IntPtrTy,               // strong_pointers
       IntPtrTy,               // weak_pointers
-      NULL);
+      nullptr);
   llvm::Constant *Zero = llvm::ConstantInt::get(LongTy, 0);
   // Fill in the structure
   std::vector<llvm::Constant*> Elements;
@@ -1677,7 +1657,7 @@
   llvm::StructType *ObjCMethodDescTy = llvm::StructType::get(
     PtrToInt8Ty, // Really a selector, but the runtime does the casting for us.
     PtrToInt8Ty,
-    NULL);
+    nullptr);
   std::vector<llvm::Constant*> Methods;
   std::vector<llvm::Constant*> Elements;
   for (unsigned int i = 0, e = MethodTypes.size() ; i < e ; i++) {
@@ -1691,7 +1671,7 @@
   llvm::Constant *Array = llvm::ConstantArray::get(ObjCMethodArrayTy,
                                                    Methods);
   llvm::StructType *ObjCMethodDescListTy = llvm::StructType::get(
-      IntTy, ObjCMethodArrayTy, NULL);
+      IntTy, ObjCMethodArrayTy, nullptr);
   Methods.clear();
   Methods.push_back(llvm::ConstantInt::get(IntTy, MethodNames.size()));
   Methods.push_back(Array);
@@ -1706,11 +1686,11 @@
       PtrTy, //Should be a recurisve pointer, but it's always NULL here.
       SizeTy,
       ProtocolArrayTy,
-      NULL);
+      nullptr);
   std::vector<llvm::Constant*> Elements;
   for (const std::string *iter = Protocols.begin(), *endIter = Protocols.end();
       iter != endIter ; iter++) {
-    llvm::Constant *protocol = 0;
+    llvm::Constant *protocol = nullptr;
     llvm::StringMap<llvm::Constant*>::iterator value =
       ExistingProtocols.find(*iter);
     if (value == ExistingProtocols.end()) {
@@ -1756,7 +1736,7 @@
       MethodList->getType(),
       MethodList->getType(),
       MethodList->getType(),
-      NULL);
+      nullptr);
   std::vector<llvm::Constant*> Elements;
   // The isa pointer must be set to a magic number so the runtime knows it's
   // the correct layout.
@@ -1780,24 +1760,22 @@
     PD = Def;
 
   SmallVector<std::string, 16> Protocols;
-  for (ObjCProtocolDecl::protocol_iterator PI = PD->protocol_begin(),
-       E = PD->protocol_end(); PI != E; ++PI)
-    Protocols.push_back((*PI)->getNameAsString());
+  for (const auto *PI : PD->protocols())
+    Protocols.push_back(PI->getNameAsString());
   SmallVector<llvm::Constant*, 16> InstanceMethodNames;
   SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
   SmallVector<llvm::Constant*, 16> OptionalInstanceMethodNames;
   SmallVector<llvm::Constant*, 16> OptionalInstanceMethodTypes;
-  for (ObjCProtocolDecl::instmeth_iterator iter = PD->instmeth_begin(),
-       E = PD->instmeth_end(); iter != E; iter++) {
+  for (const auto *I : PD->instance_methods()) {
     std::string TypeStr;
-    Context.getObjCEncodingForMethodDecl(*iter, TypeStr);
-    if ((*iter)->getImplementationControl() == ObjCMethodDecl::Optional) {
+    Context.getObjCEncodingForMethodDecl(I, TypeStr);
+    if (I->getImplementationControl() == ObjCMethodDecl::Optional) {
       OptionalInstanceMethodNames.push_back(
-          MakeConstantString((*iter)->getSelector().getAsString()));
+          MakeConstantString(I->getSelector().getAsString()));
       OptionalInstanceMethodTypes.push_back(MakeConstantString(TypeStr));
     } else {
       InstanceMethodNames.push_back(
-          MakeConstantString((*iter)->getSelector().getAsString()));
+          MakeConstantString(I->getSelector().getAsString()));
       InstanceMethodTypes.push_back(MakeConstantString(TypeStr));
     }
   }
@@ -1806,18 +1784,16 @@
   SmallVector<llvm::Constant*, 16> ClassMethodTypes;
   SmallVector<llvm::Constant*, 16> OptionalClassMethodNames;
   SmallVector<llvm::Constant*, 16> OptionalClassMethodTypes;
-  for (ObjCProtocolDecl::classmeth_iterator
-         iter = PD->classmeth_begin(), endIter = PD->classmeth_end();
-       iter != endIter ; iter++) {
+  for (const auto *I : PD->class_methods()) {
     std::string TypeStr;
-    Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
-    if ((*iter)->getImplementationControl() == ObjCMethodDecl::Optional) {
+    Context.getObjCEncodingForMethodDecl(I,TypeStr);
+    if (I->getImplementationControl() == ObjCMethodDecl::Optional) {
       OptionalClassMethodNames.push_back(
-          MakeConstantString((*iter)->getSelector().getAsString()));
+          MakeConstantString(I->getSelector().getAsString()));
       OptionalClassMethodTypes.push_back(MakeConstantString(TypeStr));
     } else {
       ClassMethodNames.push_back(
-          MakeConstantString((*iter)->getSelector().getAsString()));
+          MakeConstantString(I->getSelector().getAsString()));
       ClassMethodTypes.push_back(MakeConstantString(TypeStr));
     }
   }
@@ -1841,19 +1817,16 @@
   // structures for protocol metadata everywhere.
   llvm::StructType *PropertyMetadataTy = llvm::StructType::get(
           PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty,
-          PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, NULL);
+          PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, nullptr);
   std::vector<llvm::Constant*> Properties;
   std::vector<llvm::Constant*> OptionalProperties;
 
   // Add all of the property methods need adding to the method list and to the
   // property metadata list.
-  for (ObjCContainerDecl::prop_iterator
-         iter = PD->prop_begin(), endIter = PD->prop_end();
-       iter != endIter ; iter++) {
+  for (auto *property : PD->properties()) {
     std::vector<llvm::Constant*> Fields;
-    ObjCPropertyDecl *property = *iter;
 
-    Fields.push_back(MakePropertyEncodingString(property, 0));
+    Fields.push_back(MakePropertyEncodingString(property, nullptr));
     PushPropertyAttributes(Fields, property);
 
     if (ObjCMethodDecl *getter = property->getGetterMethodDecl()) {
@@ -1920,7 +1893,7 @@
       OptionalClassMethodList->getType(),
       PropertyList->getType(),
       OptionalPropertyList->getType(),
-      NULL);
+      nullptr);
   std::vector<llvm::Constant*> Elements;
   // The isa pointer must be set to a magic number so the runtime knows it's
   // the correct layout.
@@ -1961,7 +1934,7 @@
       PtrTy, //Should be a recurisve pointer, but it's always NULL here.
       SizeTy,
       ProtocolArrayTy,
-      NULL);
+      nullptr);
   std::vector<llvm::Constant*> ProtocolElements;
   for (llvm::StringMapIterator<llvm::Constant*> iter =
        ExistingProtocols.begin(), endIter = ExistingProtocols.end();
@@ -1981,7 +1954,7 @@
                   ProtocolElements, ".objc_protocol_list"), PtrTy));
   Categories.push_back(llvm::ConstantExpr::getBitCast(
         MakeGlobal(llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty,
-            PtrTy, PtrTy, PtrTy, NULL), Elements), PtrTy));
+            PtrTy, PtrTy, PtrTy, nullptr), Elements), PtrTy));
 }
 
 /// Libobjc2 uses a bitfield representation where small(ish) bitfields are
@@ -1997,8 +1970,7 @@
 /// bitfield / with the 63rd bit set will be 1<<64.
 llvm::Constant *CGObjCGNU::MakeBitField(ArrayRef<bool> bits) {
   int bitCount = bits.size();
-  int ptrBits =
-        (TheModule.getPointerSize() == llvm::Module::Pointer32) ? 32 : 64;
+  int ptrBits = CGM.getDataLayout().getPointerSizeInBits();
   if (bitCount < ptrBits) {
     uint64_t val = 1;
     for (int i=0 ; i<bitCount ; ++i) {
@@ -2022,7 +1994,7 @@
       llvm::ConstantInt::get(Int32Ty, values.size()),
       array };
   llvm::Constant *GS = MakeGlobal(llvm::StructType::get(Int32Ty, arrayTy,
-        NULL), fields);
+        nullptr), fields);
   llvm::Constant *ptr = llvm::ConstantExpr::getPtrToInt(GS, IntPtrTy);
   return ptr;
 }
@@ -2033,24 +2005,20 @@
   // Collect information about instance methods
   SmallVector<Selector, 16> InstanceMethodSels;
   SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
-  for (ObjCCategoryImplDecl::instmeth_iterator
-         iter = OCD->instmeth_begin(), endIter = OCD->instmeth_end();
-       iter != endIter ; iter++) {
-    InstanceMethodSels.push_back((*iter)->getSelector());
+  for (const auto *I : OCD->instance_methods()) {
+    InstanceMethodSels.push_back(I->getSelector());
     std::string TypeStr;
-    CGM.getContext().getObjCEncodingForMethodDecl(*iter,TypeStr);
+    CGM.getContext().getObjCEncodingForMethodDecl(I,TypeStr);
     InstanceMethodTypes.push_back(MakeConstantString(TypeStr));
   }
 
   // Collect information about class methods
   SmallVector<Selector, 16> ClassMethodSels;
   SmallVector<llvm::Constant*, 16> ClassMethodTypes;
-  for (ObjCCategoryImplDecl::classmeth_iterator
-         iter = OCD->classmeth_begin(), endIter = OCD->classmeth_end();
-       iter != endIter ; iter++) {
-    ClassMethodSels.push_back((*iter)->getSelector());
+  for (const auto *I : OCD->class_methods()) {
+    ClassMethodSels.push_back(I->getSelector());
     std::string TypeStr;
-    CGM.getContext().getObjCEncodingForMethodDecl(*iter,TypeStr);
+    CGM.getContext().getObjCEncodingForMethodDecl(I,TypeStr);
     ClassMethodTypes.push_back(MakeConstantString(TypeStr));
   }
 
@@ -2078,7 +2046,7 @@
         GenerateProtocolList(Protocols), PtrTy));
   Categories.push_back(llvm::ConstantExpr::getBitCast(
         MakeGlobal(llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty,
-            PtrTy, PtrTy, PtrTy, NULL), Elements), PtrTy));
+            PtrTy, PtrTy, PtrTy, nullptr), Elements), PtrTy));
 }
 
 llvm::Constant *CGObjCGNU::GeneratePropertyList(const ObjCImplementationDecl *OID,
@@ -2089,17 +2057,14 @@
   // setter name, setter types, getter name, getter types.
   llvm::StructType *PropertyMetadataTy = llvm::StructType::get(
           PtrToInt8Ty, Int8Ty, Int8Ty, Int8Ty, Int8Ty, PtrToInt8Ty,
-          PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, NULL);
+          PtrToInt8Ty, PtrToInt8Ty, PtrToInt8Ty, nullptr);
   std::vector<llvm::Constant*> Properties;
 
   // Add all of the property methods need adding to the method list and to the
   // property metadata list.
-  for (ObjCImplDecl::propimpl_iterator
-         iter = OID->propimpl_begin(), endIter = OID->propimpl_end();
-       iter != endIter ; iter++) {
+  for (auto *propertyImpl : OID->property_impls()) {
     std::vector<llvm::Constant*> Fields;
-    ObjCPropertyDecl *property = iter->getPropertyDecl();
-    ObjCPropertyImplDecl *propertyImpl = *iter;
+    ObjCPropertyDecl *property = propertyImpl->getPropertyDecl();
     bool isSynthesized = (propertyImpl->getPropertyImplementation() == 
         ObjCPropertyImplDecl::Synthesize);
     bool isDynamic = (propertyImpl->getPropertyImplementation() == 
@@ -2266,12 +2231,10 @@
   // Collect information about instance methods
   SmallVector<Selector, 16> InstanceMethodSels;
   SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
-  for (ObjCImplementationDecl::instmeth_iterator
-         iter = OID->instmeth_begin(), endIter = OID->instmeth_end();
-       iter != endIter ; iter++) {
-    InstanceMethodSels.push_back((*iter)->getSelector());
+  for (const auto *I : OID->instance_methods()) {
+    InstanceMethodSels.push_back(I->getSelector());
     std::string TypeStr;
-    Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
+    Context.getObjCEncodingForMethodDecl(I,TypeStr);
     InstanceMethodTypes.push_back(MakeConstantString(TypeStr));
   }
 
@@ -2282,22 +2245,16 @@
   // Collect information about class methods
   SmallVector<Selector, 16> ClassMethodSels;
   SmallVector<llvm::Constant*, 16> ClassMethodTypes;
-  for (ObjCImplementationDecl::classmeth_iterator
-         iter = OID->classmeth_begin(), endIter = OID->classmeth_end();
-       iter != endIter ; iter++) {
-    ClassMethodSels.push_back((*iter)->getSelector());
+  for (const auto *I : OID->class_methods()) {
+    ClassMethodSels.push_back(I->getSelector());
     std::string TypeStr;
-    Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
+    Context.getObjCEncodingForMethodDecl(I,TypeStr);
     ClassMethodTypes.push_back(MakeConstantString(TypeStr));
   }
   // Collect the names of referenced protocols
   SmallVector<std::string, 16> Protocols;
-  for (ObjCInterfaceDecl::protocol_iterator
-         I = ClassDecl->protocol_begin(),
-         E = ClassDecl->protocol_end(); I != E; ++I)
-    Protocols.push_back((*I)->getNameAsString());
-
-
+  for (const auto *I : ClassDecl->protocols())
+    Protocols.push_back(I->getNameAsString());
 
   // Get the superclass pointer.
   llvm::Constant *SuperClass;
@@ -2327,7 +2284,7 @@
   // the offset (third field in ivar structure)
   llvm::Type *IndexTy = Int32Ty;
   llvm::Constant *offsetPointerIndexes[] = {Zeros[0],
-      llvm::ConstantInt::get(IndexTy, 1), 0,
+      llvm::ConstantInt::get(IndexTy, 1), nullptr,
       llvm::ConstantInt::get(IndexTy, 2) };
 
   unsigned ivarIndex = 0;
@@ -2358,14 +2315,14 @@
   llvm::Constant *ZeroPtr = llvm::ConstantInt::get(IntPtrTy, 0);
   //Generate metaclass for class methods
   llvm::Constant *MetaClassStruct = GenerateClassStructure(NULLPtr,
-      NULLPtr, 0x12L, ClassName.c_str(), 0, Zeros[0], GenerateIvarList(
+      NULLPtr, 0x12L, ClassName.c_str(), nullptr, Zeros[0], GenerateIvarList(
         empty, empty, empty), ClassMethodList, NULLPtr,
       NULLPtr, NULLPtr, ZeroPtr, ZeroPtr, true);
 
   // Generate the class structure
   llvm::Constant *ClassStruct =
     GenerateClassStructure(MetaClassStruct, SuperClass, 0x11L,
-                           ClassName.c_str(), 0,
+                           ClassName.c_str(), nullptr,
       llvm::ConstantInt::get(LongTy, instanceSize), IvarList,
       MethodList, GenerateProtocolList(Protocols), IvarOffsetArray,
       Properties, StrongIvarBitmap, WeakIvarBitmap);
@@ -2375,13 +2332,13 @@
     ClassPtrAlias->replaceAllUsesWith(
         llvm::ConstantExpr::getBitCast(ClassStruct, IdTy));
     ClassPtrAlias->eraseFromParent();
-    ClassPtrAlias = 0;
+    ClassPtrAlias = nullptr;
   }
   if (MetaClassPtrAlias) {
     MetaClassPtrAlias->replaceAllUsesWith(
         llvm::ConstantExpr::getBitCast(MetaClassStruct, IdTy));
     MetaClassPtrAlias->eraseFromParent();
-    MetaClassPtrAlias = 0;
+    MetaClassPtrAlias = nullptr;
   }
 
   // Add class structure to list to be added to the symtab later
@@ -2394,7 +2351,7 @@
   // Only emit an ObjC load function if no Objective-C stuff has been called
   if (Classes.empty() && Categories.empty() && ConstantStrings.empty() &&
       ExistingProtocols.empty() && SelectorTable.empty())
-    return NULL;
+    return nullptr;
 
   // Add all referenced protocols to a category.
   GenerateProtocolHolderCategory();
@@ -2402,8 +2359,8 @@
   llvm::StructType *SelStructTy = dyn_cast<llvm::StructType>(
           SelectorTy->getElementType());
   llvm::Type *SelStructPtrTy = SelectorTy;
-  if (SelStructTy == 0) {
-    SelStructTy = llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, NULL);
+  if (!SelStructTy) {
+    SelStructTy = llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, nullptr);
     SelStructPtrTy = llvm::PointerType::getUnqual(SelStructTy);
   }
 
@@ -2424,7 +2381,7 @@
     Elements.push_back(llvm::ConstantArray::get(StaticsArrayTy,
        ConstantStrings));
     llvm::StructType *StaticsListTy =
-      llvm::StructType::get(PtrToInt8Ty, StaticsArrayTy, NULL);
+      llvm::StructType::get(PtrToInt8Ty, StaticsArrayTy, nullptr);
     llvm::Type *StaticsListPtrTy =
       llvm::PointerType::getUnqual(StaticsListTy);
     Statics = MakeGlobal(StaticsListTy, Elements, ".objc_statics");
@@ -2442,7 +2399,7 @@
   llvm::StructType *SymTabTy = llvm::StructType::get(LongTy, SelStructPtrTy,
                                                      llvm::Type::getInt16Ty(VMContext),
                                                      llvm::Type::getInt16Ty(VMContext),
-                                                     ClassListTy, NULL);
+                                                     ClassListTy, nullptr);
 
   Elements.clear();
   // Pointer to an array of selectors used in this module.
@@ -2523,7 +2480,7 @@
   // constants
   llvm::StructType * ModuleTy = llvm::StructType::get(LongTy, LongTy,
       PtrToInt8Ty, llvm::PointerType::getUnqual(SymTabTy), 
-      (RuntimeVersion >= 10) ? IntTy : NULL, NULL);
+      (RuntimeVersion >= 10) ? IntTy : nullptr, nullptr);
   Elements.clear();
   // Runtime version, used for ABI compatibility checking.
   Elements.push_back(llvm::ConstantInt::get(LongTy, RuntimeVersion));
@@ -2596,7 +2553,7 @@
             llvm::Constant::getNullValue(RegisterAlias->getType()));
     Builder.CreateCondBr(HasRegisterAlias, AliasBB, NoAliasBB);
 
-    // The true branch (has alias registration fucntion):
+    // The true branch (has alias registration function):
     Builder.SetInsertPoint(AliasBB);
     // Emit alias registration calls:
     for (std::vector<ClassAliasPair>::iterator iter = ClassAliases.begin();
@@ -2604,7 +2561,7 @@
        llvm::Constant *TheClass =
          TheModule.getGlobalVariable(("_OBJC_CLASS_" + iter->first).c_str(),
             true);
-       if (0 != TheClass) {
+       if (TheClass) {
          TheClass = llvm::ConstantExpr::getBitCast(TheClass, PtrTy);
          Builder.CreateCall2(RegisterAlias, TheClass,
             MakeConstantString(iter->second));
@@ -2654,7 +2611,7 @@
 
 llvm::Constant *CGObjCGNU::GetOptimizedPropertySetFunction(bool atomic,
                                                            bool copy) {
-  return 0;
+  return nullptr;
 }
 
 llvm::Constant *CGObjCGNU::GetGetStructFunction() {
@@ -2664,10 +2621,10 @@
   return SetStructPropertyFn;
 }
 llvm::Constant *CGObjCGNU::GetCppAtomicObjectGetFunction() {
-  return 0;
+  return nullptr;
 }
 llvm::Constant *CGObjCGNU::GetCppAtomicObjectSetFunction() {
-  return 0;
+  return nullptr;
 }
 
 llvm::Constant *CGObjCGNU::EnumerationMutationFunction() {
@@ -2815,7 +2772,7 @@
     } else {
       IvarOffsetPointer = new llvm::GlobalVariable(TheModule,
               llvm::Type::getInt32PtrTy(VMContext), false,
-              llvm::GlobalValue::ExternalLinkage, 0, Name);
+              llvm::GlobalValue::ExternalLinkage, nullptr, Name);
     }
   }
   return IvarOffsetPointer;
@@ -2845,7 +2802,7 @@
   if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
     return FindIvarInterface(Context, Super, OIVD);
 
-  return 0;
+  return nullptr;
 }
 
 llvm::Value *CGObjCGNU::EmitIvarOffset(CodeGenFunction &CGF,
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index 2b2a5b8..6f0979d 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -29,12 +29,12 @@
 #include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/IR/CallSite.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/InlineAsm.h"
 #include "llvm/IR/IntrinsicInst.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
-#include "llvm/Support/CallSite.h"
 #include "llvm/Support/raw_ostream.h"
 #include <cstdio>
 
@@ -174,6 +174,7 @@
 public:
   llvm::Type *ShortTy, *IntTy, *LongTy, *LongLongTy;
   llvm::Type *Int8PtrTy, *Int8PtrPtrTy;
+  llvm::Type *IvarOffsetVarTy;
 
   /// ObjectPtrTy - LLVM type for object handles (typeof(id))
   llvm::Type *ObjectPtrTy;
@@ -243,8 +244,8 @@
     Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());
     Params.push_back(Ctx.BoolTy);
     llvm::FunctionType *FTy =
-      Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(IdType, Params,
-                                                    FunctionType::ExtInfo(),
+      Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(IdType, false, Params,
+                                                          FunctionType::ExtInfo(),
                                                           RequiredArgs::All));
     return CGM.CreateRuntimeFunction(FTy, "objc_getProperty");
   }
@@ -263,8 +264,9 @@
     Params.push_back(Ctx.BoolTy);
     Params.push_back(Ctx.BoolTy);
     llvm::FunctionType *FTy =
-      Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, Params,
-                                                     FunctionType::ExtInfo(),
+      Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, false,
+                                                          Params,
+                                                          FunctionType::ExtInfo(),
                                                           RequiredArgs::All));
     return CGM.CreateRuntimeFunction(FTy, "objc_setProperty");
   }
@@ -289,7 +291,8 @@
     Params.push_back(IdType);
     Params.push_back(Ctx.getPointerDiffType()->getCanonicalTypeUnqualified());
     llvm::FunctionType *FTy =
-    Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, Params,
+    Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, false,
+                                                        Params,
                                                         FunctionType::ExtInfo(),
                                                         RequiredArgs::All));
     const char *name;
@@ -316,8 +319,9 @@
     Params.push_back(Ctx.BoolTy);
     Params.push_back(Ctx.BoolTy);
     llvm::FunctionType *FTy =
-      Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, Params,
-                                                     FunctionType::ExtInfo(),
+      Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, false,
+                                                          Params,
+                                                          FunctionType::ExtInfo(),
                                                           RequiredArgs::All));
     return CGM.CreateRuntimeFunction(FTy, "objc_copyStruct");
   }
@@ -335,8 +339,9 @@
     Params.push_back(Ctx.VoidPtrTy);
     Params.push_back(Ctx.VoidPtrTy);
     llvm::FunctionType *FTy =
-      Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, Params,
-                                                     FunctionType::ExtInfo(),
+      Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, false,
+                                                          Params,
+                                                          FunctionType::ExtInfo(),
                                                           RequiredArgs::All));
     return CGM.CreateRuntimeFunction(FTy, "objc_copyCppObjectAtomic");
   }
@@ -348,8 +353,9 @@
     SmallVector<CanQualType,1> Params;
     Params.push_back(Ctx.getCanonicalParamType(Ctx.getObjCIdType()));
     llvm::FunctionType *FTy =
-      Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, Params,
-                                                      FunctionType::ExtInfo(),
+      Types.GetFunctionType(Types.arrangeLLVMFunctionInfo(Ctx.VoidTy, false,
+                                                          Params,
+                                                          FunctionType::ExtInfo(),
                                                       RequiredArgs::All));
     return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation");
   }
@@ -849,7 +855,7 @@
   llvm::SetVector<IdentifierInfo*> DefinedSymbols;
 
   /// ClassNames - uniqued class names.
-  llvm::DenseMap<IdentifierInfo*, llvm::GlobalVariable*> ClassNames;
+  llvm::StringMap<llvm::GlobalVariable*> ClassNames;
 
   /// MethodVarNames - uniqued method variable names.
   llvm::DenseMap<Selector, llvm::GlobalVariable*> MethodVarNames;
@@ -885,6 +891,9 @@
 
   /// DefinedClasses - List of defined classes.
   SmallVector<llvm::GlobalValue*, 16> DefinedClasses;
+  
+  /// ImplementedClasses - List of @implemented classes.
+  SmallVector<const ObjCInterfaceDecl*, 16> ImplementedClasses;
 
   /// DefinedNonLazyClasses - List of defined "non-lazy" classes.
   SmallVector<llvm::GlobalValue*, 16> DefinedNonLazyClasses;
@@ -923,8 +932,9 @@
                                         const Decl *Container);
 
   /// GetClassName - Return a unique constant for the given selector's
-  /// name. The return value has type char *.
-  llvm::Constant *GetClassName(IdentifierInfo *Ident);
+  /// runtime name (which may change via use of objc_runtime_name attribute on
+  /// class or protocol definition. The return value has type char *.
+  llvm::Constant *GetClassName(StringRef RuntimeName);
 
   llvm::Function *GetMethodDefinition(const ObjCMethodDecl *MD);
 
@@ -991,7 +1001,7 @@
     llvm::SmallPtrSet<const IdentifierInfo*, 16> &PropertySet,
     SmallVectorImpl<llvm::Constant*> &Properties,
     const Decl *Container,
-    const ObjCProtocolDecl *PROTO,
+    const ObjCProtocolDecl *Proto,
     const ObjCCommonTypesHelper &ObjCTypes);
 
   /// GetProtocolRef - Return a reference to the internal protocol
@@ -1009,14 +1019,12 @@
   /// \param Name - The variable name.
   /// \param Init - The variable initializer; this is also used to
   /// define the type of the variable.
-  /// \param Section - The section the variable should go into, or 0.
+  /// \param Section - The section the variable should go into, or empty.
   /// \param Align - The alignment for the variable, or 0.
   /// \param AddToUsed - Whether the variable should be added to
   /// "llvm.used".
-  llvm::GlobalVariable *CreateMetadataVar(Twine Name,
-                                          llvm::Constant *Init,
-                                          const char *Section,
-                                          unsigned Align,
+  llvm::GlobalVariable *CreateMetadataVar(Twine Name, llvm::Constant *Init,
+                                          StringRef Section, unsigned Align,
                                           bool AddToUsed);
 
   CodeGen::RValue EmitMessageSend(CodeGen::CodeGenFunction &CGF,
@@ -1038,12 +1046,12 @@
   CGObjCCommonMac(CodeGen::CodeGenModule &cgm) :
     CGObjCRuntime(cgm), VMContext(cgm.getLLVMContext()) { }
 
-  virtual llvm::Constant *GenerateConstantString(const StringLiteral *SL);
-  
-  virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
-                                         const ObjCContainerDecl *CD=0);
+  llvm::Constant *GenerateConstantString(const StringLiteral *SL) override;
 
-  virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
+  llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
+                                 const ObjCContainerDecl *CD=nullptr) override;
+
+  void GenerateProtocol(const ObjCProtocolDecl *PD) override;
 
   /// GetOrEmitProtocol - Get the protocol object for the given
   /// declaration, emitting it if necessary. The return value has type
@@ -1055,13 +1063,13 @@
   /// forward references will be filled in with empty bodies if no
   /// definition is seen. The return value has type ProtocolPtrTy.
   virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD)=0;
-  virtual llvm::Constant *BuildGCBlockLayout(CodeGen::CodeGenModule &CGM,
-                                             const CGBlockInfo &blockInfo);
-  virtual llvm::Constant *BuildRCBlockLayout(CodeGen::CodeGenModule &CGM,
-                                             const CGBlockInfo &blockInfo);
-  
-  virtual llvm::Constant *BuildByrefLayout(CodeGen::CodeGenModule &CGM,
-                                           QualType T);
+  llvm::Constant *BuildGCBlockLayout(CodeGen::CodeGenModule &CGM,
+                                     const CGBlockInfo &blockInfo) override;
+  llvm::Constant *BuildRCBlockLayout(CodeGen::CodeGenModule &CGM,
+                                     const CGBlockInfo &blockInfo) override;
+
+  llvm::Constant *BuildByrefLayout(CodeGen::CodeGenModule &CGM,
+                                   QualType T) override;
 };
 
 class CGObjCMac : public CGObjCCommonMac {
@@ -1092,9 +1100,9 @@
   
   llvm::Value *EmitClassRefFromId(CodeGenFunction &CGF,
                                   IdentifierInfo *II);
-  
-  llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF);
-  
+
+  llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) override;
+
   /// EmitSuperClassRef - Emits reference to class's main metadata class.
   llvm::Value *EmitSuperClassRef(const ObjCInterfaceDecl *ID);
 
@@ -1145,13 +1153,13 @@
   /// GetOrEmitProtocol - Get the protocol object for the given
   /// declaration, emitting it if necessary. The return value has type
   /// ProtocolPtrTy.
-  virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD);
+  llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD) override;
 
   /// GetOrEmitProtocolRef - Get a forward reference to the protocol
   /// object for the given declaration, emitting it if needed. These
   /// forward references will be filled in with empty bodies if no
   /// definition is seen. The return value has type ProtocolPtrTy.
-  virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD);
+  llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) override;
 
   /// EmitProtocolExtension - Generate the protocol extension
   /// structure used to store optional instance and class methods, and
@@ -1177,97 +1185,90 @@
 public:
   CGObjCMac(CodeGen::CodeGenModule &cgm);
 
-  virtual llvm::Function *ModuleInitFunction();
+  llvm::Function *ModuleInitFunction() override;
 
-  virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
-                                              ReturnValueSlot Return,
-                                              QualType ResultType,
-                                              Selector Sel,
-                                              llvm::Value *Receiver,
-                                              const CallArgList &CallArgs,
-                                              const ObjCInterfaceDecl *Class,
-                                              const ObjCMethodDecl *Method);
+  CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
+                                      ReturnValueSlot Return,
+                                      QualType ResultType,
+                                      Selector Sel, llvm::Value *Receiver,
+                                      const CallArgList &CallArgs,
+                                      const ObjCInterfaceDecl *Class,
+                                      const ObjCMethodDecl *Method) override;
 
-  virtual CodeGen::RValue
+  CodeGen::RValue
   GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
-                           ReturnValueSlot Return,
-                           QualType ResultType,
-                           Selector Sel,
-                           const ObjCInterfaceDecl *Class,
-                           bool isCategoryImpl,
-                           llvm::Value *Receiver,
-                           bool IsClassMessage,
-                           const CallArgList &CallArgs,
-                           const ObjCMethodDecl *Method);
+                           ReturnValueSlot Return, QualType ResultType,
+                           Selector Sel, const ObjCInterfaceDecl *Class,
+                           bool isCategoryImpl, llvm::Value *Receiver,
+                           bool IsClassMessage, const CallArgList &CallArgs,
+                           const ObjCMethodDecl *Method) override;
 
-  virtual llvm::Value *GetClass(CodeGenFunction &CGF,
-                                const ObjCInterfaceDecl *ID);
+  llvm::Value *GetClass(CodeGenFunction &CGF,
+                        const ObjCInterfaceDecl *ID) override;
 
-  virtual llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel, 
-                                   bool lval = false);
+  llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel,
+                           bool lval = false) override;
 
   /// The NeXT/Apple runtimes do not support typed selectors; just emit an
   /// untyped one.
-  virtual llvm::Value *GetSelector(CodeGenFunction &CGF,
-                                   const ObjCMethodDecl *Method);
+  llvm::Value *GetSelector(CodeGenFunction &CGF,
+                           const ObjCMethodDecl *Method) override;
 
-  virtual llvm::Constant *GetEHType(QualType T);
+  llvm::Constant *GetEHType(QualType T) override;
 
-  virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
+  void GenerateCategory(const ObjCCategoryImplDecl *CMD) override;
 
-  virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
+  void GenerateClass(const ObjCImplementationDecl *ClassDecl) override;
 
-  virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) {}
+  void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) override {}
 
-  virtual llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
-                                           const ObjCProtocolDecl *PD);
+  llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
+                                   const ObjCProtocolDecl *PD) override;
 
-  virtual llvm::Constant *GetPropertyGetFunction();
-  virtual llvm::Constant *GetPropertySetFunction();
-  virtual llvm::Constant *GetOptimizedPropertySetFunction(bool atomic, 
-                                                          bool copy);
-  virtual llvm::Constant *GetGetStructFunction();
-  virtual llvm::Constant *GetSetStructFunction();
-  virtual llvm::Constant *GetCppAtomicObjectGetFunction();
-  virtual llvm::Constant *GetCppAtomicObjectSetFunction();
-  virtual llvm::Constant *EnumerationMutationFunction();
+  llvm::Constant *GetPropertyGetFunction() override;
+  llvm::Constant *GetPropertySetFunction() override;
+  llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
+                                                  bool copy) override;
+  llvm::Constant *GetGetStructFunction() override;
+  llvm::Constant *GetSetStructFunction() override;
+  llvm::Constant *GetCppAtomicObjectGetFunction() override;
+  llvm::Constant *GetCppAtomicObjectSetFunction() override;
+  llvm::Constant *EnumerationMutationFunction() override;
 
-  virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
-                           const ObjCAtTryStmt &S);
-  virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
-                                    const ObjCAtSynchronizedStmt &S);
+  void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
+                   const ObjCAtTryStmt &S) override;
+  void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
+                            const ObjCAtSynchronizedStmt &S) override;
   void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, const Stmt &S);
-  virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
-                             const ObjCAtThrowStmt &S,
-                             bool ClearInsertionPoint=true);
-  virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
-                                         llvm::Value *AddrWeakObj);
-  virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
-                                  llvm::Value *src, llvm::Value *dst);
-  virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
-                                    llvm::Value *src, llvm::Value *dest,
-                                    bool threadlocal = false);
-  virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
-                                  llvm::Value *src, llvm::Value *dest,
-                                  llvm::Value *ivarOffset);
-  virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
-                                        llvm::Value *src, llvm::Value *dest);
-  virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
-                                        llvm::Value *dest, llvm::Value *src,
-                                        llvm::Value *size);
+  void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtThrowStmt &S,
+                     bool ClearInsertionPoint=true) override;
+  llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
+                                 llvm::Value *AddrWeakObj) override;
+  void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
+                          llvm::Value *src, llvm::Value *dst) override;
+  void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
+                            llvm::Value *src, llvm::Value *dest,
+                            bool threadlocal = false) override;
+  void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
+                          llvm::Value *src, llvm::Value *dest,
+                          llvm::Value *ivarOffset) override;
+  void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
+                                llvm::Value *src, llvm::Value *dest) override;
+  void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
+                                llvm::Value *dest, llvm::Value *src,
+                                llvm::Value *size) override;
 
-  virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
-                                      QualType ObjectTy,
-                                      llvm::Value *BaseValue,
-                                      const ObjCIvarDecl *Ivar,
-                                      unsigned CVRQualifiers);
-  virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
-                                      const ObjCInterfaceDecl *Interface,
-                                      const ObjCIvarDecl *Ivar);
-  
+  LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, QualType ObjectTy,
+                              llvm::Value *BaseValue, const ObjCIvarDecl *Ivar,
+                              unsigned CVRQualifiers) override;
+  llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
+                              const ObjCInterfaceDecl *Interface,
+                              const ObjCIvarDecl *Ivar) override;
+
   /// GetClassGlobal - Return the global variable for the Objective-C
   /// class of the given name.
-  virtual llvm::GlobalVariable *GetClassGlobal(const std::string &Name) {
+  llvm::GlobalVariable *GetClassGlobal(const std::string &Name,
+                                       bool Weak = false) override {
     llvm_unreachable("CGObjCMac::GetClassGlobal");
   }
 };
@@ -1312,11 +1313,12 @@
                                               unsigned InstanceStart,
                                               unsigned InstanceSize,
                                               const ObjCImplementationDecl *ID);
-  llvm::GlobalVariable * BuildClassMetaData(std::string &ClassName,
+  llvm::GlobalVariable * BuildClassMetaData(const std::string &ClassName,
                                             llvm::Constant *IsAGV,
                                             llvm::Constant *SuperClassGV,
                                             llvm::Constant *ClassRoGV,
-                                            bool HiddenVisibility);
+                                            bool HiddenVisibility,
+                                            bool Weak);
 
   llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD);
 
@@ -1341,13 +1343,13 @@
   /// GetOrEmitProtocol - Get the protocol object for the given
   /// declaration, emitting it if necessary. The return value has type
   /// ProtocolPtrTy.
-  virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD);
+  llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD) override;
 
   /// GetOrEmitProtocolRef - Get a forward reference to the protocol
   /// object for the given declaration, emitting it if needed. These
   /// forward references will be filled in with empty bodies if no
   /// definition is seen. The return value has type ProtocolPtrTy.
-  virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD);
+  llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD) override;
 
   /// EmitProtocolList - Generate the list of referenced
   /// protocols. The return value has type ProtocolListPtrTy.
@@ -1367,17 +1369,19 @@
   
   /// GetClassGlobal - Return the global variable for the Objective-C
   /// class of the given name.
-  llvm::GlobalVariable *GetClassGlobal(const std::string &Name);
-    
+  llvm::GlobalVariable *GetClassGlobal(const std::string &Name,
+                                       bool Weak = false) override;
+
   /// EmitClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
   /// for the given class reference.
   llvm::Value *EmitClassRef(CodeGenFunction &CGF,
                             const ObjCInterfaceDecl *ID);
   
   llvm::Value *EmitClassRefFromId(CodeGenFunction &CGF,
-                                  IdentifierInfo *II);
-  
-  llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF);
+                                  IdentifierInfo *II, bool Weak,
+                                  const ObjCInterfaceDecl *ID);
+
+  llvm::Value *EmitNSAutoreleasePoolClassRef(CodeGenFunction &CGF) override;
 
   /// EmitSuperClassRef - Return a Value*, of type ObjCTypes.ClassPtrTy,
   /// for the given super class reference.
@@ -1387,7 +1391,7 @@
   /// EmitMetaClassRef - Return a Value * of the address of _class_t
   /// meta-data
   llvm::Value *EmitMetaClassRef(CodeGenFunction &CGF,
-                                const ObjCInterfaceDecl *ID);
+                                const ObjCInterfaceDecl *ID, bool Weak);
 
   /// ObjCIvarOffsetVariable - Returns the ivar offset variable for
   /// the given ivar.
@@ -1434,11 +1438,10 @@
   bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const;
 
   bool IsIvarOffsetKnownIdempotent(const CodeGen::CodeGenFunction &CGF,
-                                   const ObjCInterfaceDecl *ID,
                                    const ObjCIvarDecl *IV) {
-    // Annotate the load as an invariant load iff the object type is the type,
-    // or a derived type, of the class containing the ivar within an ObjC
-    // method.  This check is needed because the ivar offset is a lazily
+    // Annotate the load as an invariant load iff inside an instance method
+    // and ivar belongs to instance method's class and one of its super class.
+    // This check is needed because the ivar offset is a lazily
     // initialised value that may depend on objc_msgSend to perform a fixup on
     // the first message dispatch.
     //
@@ -1446,128 +1449,122 @@
     // base of the ivar access is a parameter to an Objective C method.
     // However, because the parameters are not available in the current
     // interface, we cannot perform this check.
-    if (CGF.CurFuncDecl && isa<ObjCMethodDecl>(CGF.CurFuncDecl))
-      if (IV->getContainingInterface()->isSuperClassOf(ID))
-        return true;
+    if (const ObjCMethodDecl *MD =
+          dyn_cast_or_null<ObjCMethodDecl>(CGF.CurFuncDecl))
+      if (MD->isInstanceMethod())
+        if (const ObjCInterfaceDecl *ID = MD->getClassInterface())
+          return IV->getContainingInterface()->isSuperClassOf(ID);
     return false;
   }
 
 public:
   CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm);
   // FIXME. All stubs for now!
-  virtual llvm::Function *ModuleInitFunction();
+  llvm::Function *ModuleInitFunction() override;
 
-  virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
-                                              ReturnValueSlot Return,
-                                              QualType ResultType,
-                                              Selector Sel,
-                                              llvm::Value *Receiver,
-                                              const CallArgList &CallArgs,
-                                              const ObjCInterfaceDecl *Class,
-                                              const ObjCMethodDecl *Method);
+  CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF,
+                                      ReturnValueSlot Return,
+                                      QualType ResultType, Selector Sel,
+                                      llvm::Value *Receiver,
+                                      const CallArgList &CallArgs,
+                                      const ObjCInterfaceDecl *Class,
+                                      const ObjCMethodDecl *Method) override;
 
-  virtual CodeGen::RValue
+  CodeGen::RValue
   GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF,
-                           ReturnValueSlot Return,
-                           QualType ResultType,
-                           Selector Sel,
-                           const ObjCInterfaceDecl *Class,
-                           bool isCategoryImpl,
-                           llvm::Value *Receiver,
-                           bool IsClassMessage,
-                           const CallArgList &CallArgs,
-                           const ObjCMethodDecl *Method);
+                           ReturnValueSlot Return, QualType ResultType,
+                           Selector Sel, const ObjCInterfaceDecl *Class,
+                           bool isCategoryImpl, llvm::Value *Receiver,
+                           bool IsClassMessage, const CallArgList &CallArgs,
+                           const ObjCMethodDecl *Method) override;
 
-  virtual llvm::Value *GetClass(CodeGenFunction &CGF,
-                                const ObjCInterfaceDecl *ID);
+  llvm::Value *GetClass(CodeGenFunction &CGF,
+                        const ObjCInterfaceDecl *ID) override;
 
-  virtual llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel,
-                                   bool lvalue = false)
+  llvm::Value *GetSelector(CodeGenFunction &CGF, Selector Sel,
+                           bool lvalue = false) override
     { return EmitSelector(CGF, Sel, lvalue); }
 
   /// The NeXT/Apple runtimes do not support typed selectors; just emit an
   /// untyped one.
-  virtual llvm::Value *GetSelector(CodeGenFunction &CGF,
-                                   const ObjCMethodDecl *Method)
+  llvm::Value *GetSelector(CodeGenFunction &CGF,
+                           const ObjCMethodDecl *Method) override
     { return EmitSelector(CGF, Method->getSelector()); }
 
-  virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
+  void GenerateCategory(const ObjCCategoryImplDecl *CMD) override;
 
-  virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
+  void GenerateClass(const ObjCImplementationDecl *ClassDecl) override;
 
-  virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) {}
+  void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) override {}
 
-  virtual llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
-                                           const ObjCProtocolDecl *PD);
+  llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
+                                   const ObjCProtocolDecl *PD) override;
 
-  virtual llvm::Constant *GetEHType(QualType T);
+  llvm::Constant *GetEHType(QualType T) override;
 
-  virtual llvm::Constant *GetPropertyGetFunction() {
+  llvm::Constant *GetPropertyGetFunction() override {
     return ObjCTypes.getGetPropertyFn();
   }
-  virtual llvm::Constant *GetPropertySetFunction() {
+  llvm::Constant *GetPropertySetFunction() override {
     return ObjCTypes.getSetPropertyFn();
   }
-  
-  virtual llvm::Constant *GetOptimizedPropertySetFunction(bool atomic, 
-                                                          bool copy) {
+
+  llvm::Constant *GetOptimizedPropertySetFunction(bool atomic,
+                                                  bool copy) override {
     return ObjCTypes.getOptimizedSetPropertyFn(atomic, copy);
   }
-  
-  virtual llvm::Constant *GetSetStructFunction() {
+
+  llvm::Constant *GetSetStructFunction() override {
     return ObjCTypes.getCopyStructFn();
   }
-  virtual llvm::Constant *GetGetStructFunction() {
+  llvm::Constant *GetGetStructFunction() override {
     return ObjCTypes.getCopyStructFn();
   }
-  virtual llvm::Constant *GetCppAtomicObjectSetFunction() {
+  llvm::Constant *GetCppAtomicObjectSetFunction() override {
     return ObjCTypes.getCppAtomicObjectFunction();
   }
-  virtual llvm::Constant *GetCppAtomicObjectGetFunction() {
+  llvm::Constant *GetCppAtomicObjectGetFunction() override {
     return ObjCTypes.getCppAtomicObjectFunction();
   }
-  
-  virtual llvm::Constant *EnumerationMutationFunction() {
+
+  llvm::Constant *EnumerationMutationFunction() override {
     return ObjCTypes.getEnumerationMutationFn();
   }
 
-  virtual void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
-                           const ObjCAtTryStmt &S);
-  virtual void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
-                                    const ObjCAtSynchronizedStmt &S);
-  virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF,
-                             const ObjCAtThrowStmt &S,
-                             bool ClearInsertionPoint=true);
-  virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
-                                         llvm::Value *AddrWeakObj);
-  virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
-                                  llvm::Value *src, llvm::Value *dst);
-  virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
-                                    llvm::Value *src, llvm::Value *dest,
-                                    bool threadlocal = false);
-  virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
-                                  llvm::Value *src, llvm::Value *dest,
-                                  llvm::Value *ivarOffset);
-  virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
-                                        llvm::Value *src, llvm::Value *dest);
-  virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
-                                        llvm::Value *dest, llvm::Value *src,
-                                        llvm::Value *size);
-  virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
-                                      QualType ObjectTy,
-                                      llvm::Value *BaseValue,
-                                      const ObjCIvarDecl *Ivar,
-                                      unsigned CVRQualifiers);
-  virtual llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
-                                      const ObjCInterfaceDecl *Interface,
-                                      const ObjCIvarDecl *Ivar);
+  void EmitTryStmt(CodeGen::CodeGenFunction &CGF,
+                   const ObjCAtTryStmt &S) override;
+  void EmitSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
+                            const ObjCAtSynchronizedStmt &S) override;
+  void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, const ObjCAtThrowStmt &S,
+                     bool ClearInsertionPoint=true) override;
+  llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF,
+                                 llvm::Value *AddrWeakObj) override;
+  void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF,
+                          llvm::Value *src, llvm::Value *dst) override;
+  void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF,
+                            llvm::Value *src, llvm::Value *dest,
+                            bool threadlocal = false) override;
+  void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF,
+                          llvm::Value *src, llvm::Value *dest,
+                          llvm::Value *ivarOffset) override;
+  void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
+                                llvm::Value *src, llvm::Value *dest) override;
+  void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
+                                llvm::Value *dest, llvm::Value *src,
+                                llvm::Value *size) override;
+  LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, QualType ObjectTy,
+                              llvm::Value *BaseValue, const ObjCIvarDecl *Ivar,
+                              unsigned CVRQualifiers) override;
+  llvm::Value *EmitIvarOffset(CodeGen::CodeGenFunction &CGF,
+                              const ObjCInterfaceDecl *Interface,
+                              const ObjCIvarDecl *Ivar) override;
 };
 
 /// A helper class for performing the null-initialization of a return
 /// value.
 struct NullReturnState {
   llvm::BasicBlock *NullBB;
-  NullReturnState() : NullBB(0) {}
+  NullReturnState() : NullBB(nullptr) {}
 
   /// Perform a null-check of the given receiver.
   void init(CodeGenFunction &CGF, llvm::Value *receiver) {
@@ -1596,8 +1593,8 @@
 
     // The continuation block.  This will be left null if we don't have an
     // IP, which can happen if the method we're calling is marked noreturn.
-    llvm::BasicBlock *contBB = 0;
-    
+    llvm::BasicBlock *contBB = nullptr;
+
     // Finish the call path.
     llvm::BasicBlock *callBB = CGF.Builder.GetInsertBlock();
     if (callBB) {
@@ -1878,14 +1875,14 @@
   MessageSendInfo MSI = getMessageSendInfo(Method, ResultType, ActualArgs);
 
   if (Method)
-    assert(CGM.getContext().getCanonicalType(Method->getResultType()) ==
-           CGM.getContext().getCanonicalType(ResultType) &&
+    assert(CGM.getContext().getCanonicalType(Method->getReturnType()) ==
+               CGM.getContext().getCanonicalType(ResultType) &&
            "Result type mismatch!");
 
   NullReturnState nullReturn;
 
-  llvm::Constant *Fn = NULL;
-  if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) {
+  llvm::Constant *Fn = nullptr;
+  if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) {
     if (!IsSuper) nullReturn.init(CGF, Arg0);
     Fn = (ObjCABI == 2) ?  ObjCTypes.getSendStretFn2(IsSuper)
       : ObjCTypes.getSendStretFn(IsSuper);
@@ -1896,15 +1893,17 @@
     Fn = (ObjCABI == 2) ? ObjCTypes.getSendFp2RetFn2(IsSuper)
       : ObjCTypes.getSendFp2retFn(IsSuper);
   } else {
+    // arm64 uses objc_msgSend for stret methods and yet null receiver check
+    // must be made for it.
+    if (!IsSuper && CGM.ReturnTypeUsesSRet(MSI.CallInfo))
+      nullReturn.init(CGF, Arg0);
     Fn = (ObjCABI == 2) ? ObjCTypes.getSendFn2(IsSuper)
       : ObjCTypes.getSendFn(IsSuper);
   }
   
   bool requiresnullCheck = false;
   if (CGM.getLangOpts().ObjCAutoRefCount && Method)
-    for (ObjCMethodDecl::param_const_iterator i = Method->param_begin(),
-         e = Method->param_end(); i != e; ++i) {
-      const ParmVarDecl *ParamDecl = (*i);
+    for (const auto *ParamDecl : Method->params()) {
       if (ParamDecl->hasAttr<NSConsumedAttr>()) {
         if (!nullReturn.NullBB)
           nullReturn.init(CGF, Arg0);
@@ -1916,7 +1915,7 @@
   Fn = llvm::ConstantExpr::getBitCast(Fn, MSI.MessengerType);
   RValue rvalue = CGF.EmitCall(MSI.CallInfo, Fn, Return, ActualArgs);
   return nullReturn.complete(CGF, rvalue, ResultType, CallArgs,
-                             requiresnullCheck ? Method : 0);
+                             requiresnullCheck ? Method : nullptr);
 }
 
 static Qualifiers::GC GetGCAttrTypeForType(ASTContext &Ctx, QualType FQT) {
@@ -1967,9 +1966,8 @@
   // to be GC'ed.
 
   // Walk the captured variables.
-  for (BlockDecl::capture_const_iterator ci = blockDecl->capture_begin(),
-         ce = blockDecl->capture_end(); ci != ce; ++ci) {
-    const VarDecl *variable = ci->getVariable();
+  for (const auto &CI : blockDecl->captures()) {
+    const VarDecl *variable = CI.getVariable();
     QualType type = variable->getType();
 
     const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
@@ -1980,7 +1978,7 @@
     uint64_t fieldOffset = layout->getElementOffset(capture.getIndex());
 
     // __block variables are passed by their descriptor address.
-    if (ci->isByRef()) {
+    if (CI.isByRef()) {
       IvarsInfo.push_back(GC_IVAR(fieldOffset, /*size in words*/ 1));
       continue;
     }
@@ -2071,8 +2069,8 @@
                                           bool ByrefLayout) {
   bool IsUnion = (RD && RD->isUnion());
   CharUnits MaxUnionSize = CharUnits::Zero();
-  const FieldDecl *MaxField = 0;
-  const FieldDecl *LastFieldBitfieldOrUnnamed = 0;
+  const FieldDecl *MaxField = nullptr;
+  const FieldDecl *LastFieldBitfieldOrUnnamed = nullptr;
   CharUnits MaxFieldOffset = CharUnits::Zero();
   CharUnits LastBitfieldOrUnnamedOffset = CharUnits::Zero();
   
@@ -2094,8 +2092,8 @@
       LastBitfieldOrUnnamedOffset = FieldOffset;
       continue;
     }
-    
-    LastFieldBitfieldOrUnnamed = 0;
+
+    LastFieldBitfieldOrUnnamed = nullptr;
     QualType FQT = Field->getType();
     if (FQT->isRecordType() || FQT->isUnionType()) {
       if (FQT->isUnionType())
@@ -2118,9 +2116,6 @@
         ElCount *= CArray->getSize().getZExtValue();
         FQT = CArray->getElementType();
       }
-      
-      assert(!FQT->isUnionType() &&
-             "layout for array of unions not supported");
       if (FQT->isRecordType() && ElCount) {
         int OldIndex = RunSkipBlockVars.size() - 1;
         const RecordType *RT = FQT->getAs<RecordType>();
@@ -2196,10 +2191,7 @@
                                                   bool &HasUnion,
                                                   bool ByrefLayout) {
   const RecordDecl *RD = RT->getDecl();
-  SmallVector<const FieldDecl*, 16> Fields;
-  for (RecordDecl::field_iterator i = RD->field_begin(),
-       e = RD->field_end(); i != e; ++i)
-    Fields.push_back(*i);
+  SmallVector<const FieldDecl*, 16> Fields(RD->fields());
   llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0));
   const llvm::StructLayout *RecLayout =
     CGM.getDataLayout().getStructLayout(cast<llvm::StructType>(Ty));
@@ -2486,9 +2478,8 @@
                            blockInfo.BlockHeaderForcedGapOffset,
                            blockInfo.BlockHeaderForcedGapSize);
   // Walk the captured variables.
-  for (BlockDecl::capture_const_iterator ci = blockDecl->capture_begin(),
-       ce = blockDecl->capture_end(); ci != ce; ++ci) {
-    const VarDecl *variable = ci->getVariable();
+  for (const auto &CI : blockDecl->captures()) {
+    const VarDecl *variable = CI.getVariable();
     QualType type = variable->getType();
     
     const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
@@ -2500,17 +2491,17 @@
        CharUnits::fromQuantity(layout->getElementOffset(capture.getIndex()));
     
     assert(!type->isArrayType() && "array variable should not be caught");
-    if (!ci->isByRef())
+    if (!CI.isByRef())
       if (const RecordType *record = type->getAs<RecordType>()) {
         BuildRCBlockVarRecordLayout(record, fieldOffset, hasUnion);
         continue;
       }
     CharUnits fieldSize;
-    if (ci->isByRef())
+    if (CI.isByRef())
       fieldSize = CharUnits::fromQuantity(WordSizeInBytes);
     else
       fieldSize = CGM.getContext().getTypeSizeInChars(type);
-    UpdateRunSkipBlockVars(ci->isByRef(), getBlockCaptureLifetime(type, false),
+    UpdateRunSkipBlockVars(CI.isByRef(), getBlockCaptureLifetime(type, false),
                            fieldOffset, fieldSize);
   }
   return getBitmapBlockLayout(false);
@@ -2562,8 +2553,16 @@
   return GetOrEmitProtocolRef(PD);
 }
 
+static void assertPrivateName(const llvm::GlobalValue *GV) {
+  StringRef NameRef = GV->getName();
+  (void)NameRef;
+  assert(NameRef[0] == '\01' && (NameRef[1] == 'L' || NameRef[1] == 'l'));
+  assert(GV->getVisibility() == llvm::GlobalValue::DefaultVisibility);
+  assert(GV->hasPrivateLinkage());
+}
+
 /*
-// APPLE LOCAL radar 4585769 - Objective-C 1.0 extensions
+// Objective-C 1.0 extensions
 struct _objc_protocol {
 struct _objc_protocol_extension *isa;
 char *protocol_name;
@@ -2593,9 +2592,7 @@
   std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
   std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
   std::vector<llvm::Constant*> MethodTypesExt, OptMethodTypesExt;
-  for (ObjCProtocolDecl::instmeth_iterator
-         i = PD->instmeth_begin(), e = PD->instmeth_end(); i != e; ++i) {
-    ObjCMethodDecl *MD = *i;
+  for (const auto *MD : PD->instance_methods()) {
     llvm::Constant *C = GetMethodDescriptionConstant(MD);
     if (!C)
       return GetOrEmitProtocolRef(PD);
@@ -2609,9 +2606,7 @@
     }
   }
 
-  for (ObjCProtocolDecl::classmeth_iterator
-         i = PD->classmeth_begin(), e = PD->classmeth_end(); i != e; ++i) {
-    ObjCMethodDecl *MD = *i;
+  for (const auto *MD : PD->class_methods()) {
     llvm::Constant *C = GetMethodDescriptionConstant(MD);
     if (!C)
       return GetOrEmitProtocolRef(PD);
@@ -2631,7 +2626,7 @@
   llvm::Constant *Values[] = {
     EmitProtocolExtension(PD, OptInstanceMethods, OptClassMethods, 
                           MethodTypesExt),
-    GetClassName(PD->getIdentifier()),
+    GetClassName(PD->getObjCRuntimeNameAsString()),
     EmitProtocolList("\01L_OBJC_PROTOCOL_REFS_" + PD->getName(),
                      PD->protocol_begin(),
                      PD->protocol_end()),
@@ -2646,13 +2641,13 @@
                                                    Values);
 
   if (Entry) {
-    // Already created, fix the linkage and update the initializer.
-    Entry->setLinkage(llvm::GlobalValue::InternalLinkage);
+    // Already created, update the initializer.
+    assert(Entry->hasPrivateLinkage());
     Entry->setInitializer(Init);
   } else {
     Entry =
       new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy, false,
-                               llvm::GlobalValue::InternalLinkage,
+                               llvm::GlobalValue::PrivateLinkage,
                                Init,
                                "\01L_OBJC_PROTOCOL_" + PD->getName());
     Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
@@ -2661,7 +2656,8 @@
 
     Protocols[PD->getIdentifier()] = Entry;
   }
-  CGM.AddUsedGlobal(Entry);
+  assertPrivateName(Entry);
+  CGM.addCompilerUsedGlobal(Entry);
 
   return Entry;
 }
@@ -2675,13 +2671,14 @@
     // contents for protocols which were referenced but never defined.
     Entry =
       new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolTy, false,
-                               llvm::GlobalValue::ExternalLinkage,
-                               0,
+                               llvm::GlobalValue::PrivateLinkage,
+                               nullptr,
                                "\01L_OBJC_PROTOCOL_" + PD->getName());
     Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
     // FIXME: Is this necessary? Why only for protocol?
     Entry->setAlignment(4);
   }
+  assertPrivateName(Entry);
 
   return Entry;
 }
@@ -2711,8 +2708,8 @@
     EmitMethodDescList("\01L_OBJC_PROTOCOL_CLASS_METHODS_OPT_" + PD->getName(),
                        "__OBJC,__cat_cls_meth,regular,no_dead_strip",
                        OptClassMethods),
-    EmitPropertyList("\01L_OBJC_$_PROP_PROTO_LIST_" + PD->getName(), 0, PD,
-                     ObjCTypes),
+    EmitPropertyList("\01L_OBJC_$_PROP_PROTO_LIST_" + PD->getName(), nullptr,
+                     PD, ObjCTypes),
     EmitProtocolMethodTypes("\01L_OBJC_PROTOCOL_METHOD_TYPES_" + PD->getName(),
                             MethodTypesExt, ObjCTypes)
   };
@@ -2726,9 +2723,8 @@
     llvm::ConstantStruct::get(ObjCTypes.ProtocolExtensionTy, Values);
 
   // No special section, but goes in llvm.used
-  return CreateMetadataVar("\01L_OBJC_PROTOCOLEXT_" + PD->getName(),
-                           Init,
-                           0, 0, true);
+  return CreateMetadataVar("\01l_OBJC_PROTOCOLEXT_" + PD->getName(), Init,
+                           StringRef(), 0, true);
 }
 
 /*
@@ -2775,14 +2771,11 @@
 PushProtocolProperties(llvm::SmallPtrSet<const IdentifierInfo*,16> &PropertySet,
                        SmallVectorImpl<llvm::Constant *> &Properties,
                        const Decl *Container,
-                       const ObjCProtocolDecl *PROTO,
+                       const ObjCProtocolDecl *Proto,
                        const ObjCCommonTypesHelper &ObjCTypes) {
-  for (ObjCProtocolDecl::protocol_iterator P = PROTO->protocol_begin(),
-         E = PROTO->protocol_end(); P != E; ++P) 
-    PushProtocolProperties(PropertySet, Properties, Container, (*P), ObjCTypes);
-  for (ObjCContainerDecl::prop_iterator I = PROTO->prop_begin(),
-       E = PROTO->prop_end(); I != E; ++I) {
-    const ObjCPropertyDecl *PD = *I;
+  for (const auto *P : Proto->protocols()) 
+    PushProtocolProperties(PropertySet, Properties, Container, P, ObjCTypes);
+  for (const auto *PD : Proto->properties()) {
     if (!PropertySet.insert(PD->getIdentifier()))
       continue;
     llvm::Constant *Prop[] = {
@@ -2811,9 +2804,7 @@
                                        const ObjCCommonTypesHelper &ObjCTypes) {
   SmallVector<llvm::Constant *, 16> Properties;
   llvm::SmallPtrSet<const IdentifierInfo*, 16> PropertySet;
-  for (ObjCContainerDecl::prop_iterator I = OCD->prop_begin(),
-         E = OCD->prop_end(); I != E; ++I) {
-    const ObjCPropertyDecl *PD = *I;
+  for (const auto *PD : OCD->properties()) {
     PropertySet.insert(PD->getIdentifier());
     llvm::Constant *Prop[] = {
       GetPropertyName(PD->getIdentifier()),
@@ -2823,17 +2814,12 @@
                                                    Prop));
   }
   if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) {
-    for (ObjCInterfaceDecl::all_protocol_iterator
-         P = OID->all_referenced_protocol_begin(),
-         E = OID->all_referenced_protocol_end(); P != E; ++P)
-      PushProtocolProperties(PropertySet, Properties, Container, (*P), 
-                             ObjCTypes);
+    for (const auto *P : OID->all_referenced_protocols())
+      PushProtocolProperties(PropertySet, Properties, Container, P, ObjCTypes);
   }
   else if (const ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(OCD)) {
-    for (ObjCCategoryDecl::protocol_iterator P = CD->protocol_begin(),
-         E = CD->protocol_end(); P != E; ++P)
-      PushProtocolProperties(PropertySet, Properties, Container, (*P), 
-                             ObjCTypes);
+    for (const auto *P : CD->protocols())
+      PushProtocolProperties(PropertySet, Properties, Container, P, ObjCTypes);
   }
 
   // Return null for empty list.
@@ -2871,11 +2857,9 @@
                                              MethodTypes.size());
   llvm::Constant *Init = llvm::ConstantArray::get(AT, MethodTypes);
 
-  llvm::GlobalVariable *GV = 
-    CreateMetadataVar(Name, Init,
-                      (ObjCABI == 2) ? "__DATA, __objc_const" : 0,
-                      (ObjCABI == 2) ? 8 : 4,
-                      true);
+  llvm::GlobalVariable *GV = CreateMetadataVar(
+      Name, Init, (ObjCABI == 2) ? "__DATA, __objc_const" : StringRef(),
+      (ObjCABI == 2) ? 8 : 4, true);
   return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.Int8PtrPtrTy);
 }
 
@@ -2893,8 +2877,8 @@
     GetMethodVarType(MD)
   };
   if (!Desc[1])
-    return 0;
-  
+    return nullptr;
+
   return llvm::ConstantStruct::get(ObjCTypes.MethodDescriptionTy,
                                    Desc);
 }
@@ -2945,20 +2929,17 @@
                                      << OCD->getName();
 
   SmallVector<llvm::Constant *, 16> InstanceMethods, ClassMethods;
-  for (ObjCCategoryImplDecl::instmeth_iterator
-         i = OCD->instmeth_begin(), e = OCD->instmeth_end(); i != e; ++i) {
+  for (const auto *I : OCD->instance_methods())
     // Instance methods should always be defined.
-    InstanceMethods.push_back(GetMethodConstant(*i));
-  }
-  for (ObjCCategoryImplDecl::classmeth_iterator
-         i = OCD->classmeth_begin(), e = OCD->classmeth_end(); i != e; ++i) {
+    InstanceMethods.push_back(GetMethodConstant(I));
+
+  for (const auto *I : OCD->class_methods())
     // Class methods should always be defined.
-    ClassMethods.push_back(GetMethodConstant(*i));
-  }
+    ClassMethods.push_back(GetMethodConstant(I));
 
   llvm::Constant *Values[7];
-  Values[0] = GetClassName(OCD->getIdentifier());
-  Values[1] = GetClassName(Interface->getIdentifier());
+  Values[0] = GetClassName(OCD->getName());
+  Values[1] = GetClassName(Interface->getObjCRuntimeNameAsString());
   LazySymbols.insert(Interface->getIdentifier());
   Values[2] =
     EmitMethodList("\01L_OBJC_CATEGORY_INSTANCE_METHODS_" + ExtName.str(),
@@ -3073,21 +3054,15 @@
     Flags |= FragileABI_Class_Hidden;
 
   SmallVector<llvm::Constant *, 16> InstanceMethods, ClassMethods;
-  for (ObjCImplementationDecl::instmeth_iterator
-         i = ID->instmeth_begin(), e = ID->instmeth_end(); i != e; ++i) {
+  for (const auto *I : ID->instance_methods())
     // Instance methods should always be defined.
-    InstanceMethods.push_back(GetMethodConstant(*i));
-  }
-  for (ObjCImplementationDecl::classmeth_iterator
-         i = ID->classmeth_begin(), e = ID->classmeth_end(); i != e; ++i) {
+    InstanceMethods.push_back(GetMethodConstant(I));
+
+  for (const auto *I : ID->class_methods())
     // Class methods should always be defined.
-    ClassMethods.push_back(GetMethodConstant(*i));
-  }
+    ClassMethods.push_back(GetMethodConstant(I));
 
-  for (ObjCImplementationDecl::propimpl_iterator
-         i = ID->propimpl_begin(), e = ID->propimpl_end(); i != e; ++i) {
-    ObjCPropertyImplDecl *PID = *i;
-
+  for (const auto *PID : ID->property_impls()) {
     if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
       ObjCPropertyDecl *PD = PID->getPropertyDecl();
 
@@ -3107,12 +3082,12 @@
     LazySymbols.insert(Super->getIdentifier());
 
     Values[ 1] =
-      llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
+      llvm::ConstantExpr::getBitCast(GetClassName(Super->getObjCRuntimeNameAsString()),
                                      ObjCTypes.ClassPtrTy);
   } else {
     Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
   }
-  Values[ 2] = GetClassName(ID->getIdentifier());
+  Values[ 2] = GetClassName(ID->getObjCRuntimeNameAsString());
   // Version is always 0.
   Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
   Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
@@ -3133,19 +3108,19 @@
   Name += ClassName;
   const char *Section = "__OBJC,__class,regular,no_dead_strip";
   // Check for a forward reference.
-  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
+  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);
   if (GV) {
     assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
            "Forward metaclass reference has incorrect type.");
-    GV->setLinkage(llvm::GlobalValue::InternalLinkage);
     GV->setInitializer(Init);
     GV->setSection(Section);
     GV->setAlignment(4);
-    CGM.AddUsedGlobal(GV);
-  } 
-  else
+    CGM.addCompilerUsedGlobal(GV);
+  } else
     GV = CreateMetadataVar(Name, Init, Section, 4, true);
+  assertPrivateName(GV);
   DefinedClasses.push_back(GV);
+  ImplementedClasses.push_back(Interface);
   // method definition entries must be clear for next implementation.
   MethodDefinitions.clear();
 }
@@ -3165,19 +3140,19 @@
   while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
     Root = Super;
   Values[ 0] =
-    llvm::ConstantExpr::getBitCast(GetClassName(Root->getIdentifier()),
+    llvm::ConstantExpr::getBitCast(GetClassName(Root->getObjCRuntimeNameAsString()),
                                    ObjCTypes.ClassPtrTy);
   // The super class for the metaclass is emitted as the name of the
   // super class. The runtime fixes this up to point to the
   // *metaclass* for the super class.
   if (ObjCInterfaceDecl *Super = ID->getClassInterface()->getSuperClass()) {
     Values[ 1] =
-      llvm::ConstantExpr::getBitCast(GetClassName(Super->getIdentifier()),
+      llvm::ConstantExpr::getBitCast(GetClassName(Super->getObjCRuntimeNameAsString()),
                                      ObjCTypes.ClassPtrTy);
   } else {
     Values[ 1] = llvm::Constant::getNullValue(ObjCTypes.ClassPtrTy);
   }
-  Values[ 2] = GetClassName(ID->getIdentifier());
+  Values[ 2] = GetClassName(ID->getObjCRuntimeNameAsString());
   // Version is always 0.
   Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0);
   Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags);
@@ -3201,20 +3176,20 @@
   Name += ID->getName();
 
   // Check for a forward reference.
-  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
+  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);
   if (GV) {
     assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
            "Forward metaclass reference has incorrect type.");
-    GV->setLinkage(llvm::GlobalValue::InternalLinkage);
     GV->setInitializer(Init);
   } else {
     GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
-                                  llvm::GlobalValue::InternalLinkage,
+                                  llvm::GlobalValue::PrivateLinkage,
                                   Init, Name);
   }
+  assertPrivateName(GV);
   GV->setSection("__OBJC,__meta_class,regular,no_dead_strip");
   GV->setAlignment(4);
-  CGM.AddUsedGlobal(GV);
+  CGM.addCompilerUsedGlobal(GV);
 
   return GV;
 }
@@ -3230,35 +3205,31 @@
   // Check for an existing forward reference.
   // Previously, metaclass with internal linkage may have been defined.
   // pass 'true' as 2nd argument so it is returned.
-  if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name,
-                                                                   true)) {
-    assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
-           "Forward metaclass reference has incorrect type.");
-    return GV;
-  } else {
-    // Generate as an external reference to keep a consistent
-    // module. This will be patched up when we emit the metaclass.
-    return new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
-                                    llvm::GlobalValue::ExternalLinkage,
-                                    0,
-                                    Name);
-  }
+  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);
+  if (!GV)
+    GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
+                                  llvm::GlobalValue::PrivateLinkage, nullptr,
+                                  Name);
+
+  assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
+         "Forward metaclass reference has incorrect type.");
+  assertPrivateName(GV);
+  return GV;
 }
 
 llvm::Value *CGObjCMac::EmitSuperClassRef(const ObjCInterfaceDecl *ID) {
   std::string Name = "\01L_OBJC_CLASS_" + ID->getNameAsString();
-  
-  if (llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name,
-                                                                   true)) {
-    assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
-           "Forward class metadata reference has incorrect type.");
-    return GV;
-  } else {
-    return new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
-                                    llvm::GlobalValue::ExternalLinkage,
-                                    0,
-                                    Name);
-  }
+  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);
+
+  if (!GV)
+    GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassTy, false,
+                                  llvm::GlobalValue::PrivateLinkage, nullptr,
+                                  Name);
+
+  assert(GV->getType()->getElementType() == ObjCTypes.ClassTy &&
+         "Forward class metadata reference has incorrect type.");
+  assertPrivateName(GV);
+  return GV;
 }
 
 /*
@@ -3373,7 +3344,7 @@
 llvm::Constant *CGObjCMac::GetMethodConstant(const ObjCMethodDecl *MD) {
   llvm::Function *Fn = GetMethodDefinition(MD);
   if (!Fn)
-    return 0;
+    return nullptr;
 
   llvm::Constant *Method[] = {
     llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
@@ -3421,29 +3392,29 @@
   return Method;
 }
 
-llvm::GlobalVariable *
-CGObjCCommonMac::CreateMetadataVar(Twine Name,
-                                   llvm::Constant *Init,
-                                   const char *Section,
-                                   unsigned Align,
-                                   bool AddToUsed) {
+llvm::GlobalVariable *CGObjCCommonMac::CreateMetadataVar(Twine Name,
+                                                         llvm::Constant *Init,
+                                                         StringRef Section,
+                                                         unsigned Align,
+                                                         bool AddToUsed) {
   llvm::Type *Ty = Init->getType();
   llvm::GlobalVariable *GV =
     new llvm::GlobalVariable(CGM.getModule(), Ty, false,
-                             llvm::GlobalValue::InternalLinkage, Init, Name);
-  if (Section)
+                             llvm::GlobalValue::PrivateLinkage, Init, Name);
+  assertPrivateName(GV);
+  if (!Section.empty())
     GV->setSection(Section);
   if (Align)
     GV->setAlignment(Align);
   if (AddToUsed)
-    CGM.AddUsedGlobal(GV);
+    CGM.addCompilerUsedGlobal(GV);
   return GV;
 }
 
 llvm::Function *CGObjCMac::ModuleInitFunction() {
   // Abuse this interface function as a place to finalize.
   FinishModule();
-  return NULL;
+  return nullptr;
 }
 
 llvm::Constant *CGObjCMac::GetPropertyGetFunction() {
@@ -3501,7 +3472,7 @@
       : S(*S), SyncArgSlot(SyncArgSlot), CallTryExitVar(CallTryExitVar),
         ExceptionData(ExceptionData), ObjCTypes(*ObjCTypes) {}
 
-    void Emit(CodeGenFunction &CGF, Flags flags) {
+    void Emit(CodeGenFunction &CGF, Flags flags) override {
       // Check whether we need to call objc_exception_try_exit.
       // In optimized code, this branch will always be folded.
       llvm::BasicBlock *FinallyCallExit =
@@ -3826,7 +3797,7 @@
   // @synchronized.  We can't avoid a temp here because we need the
   // value to be preserved.  If the backend ever does liveness
   // correctly after setjmp, this will be unnecessary.
-  llvm::Value *SyncArgSlot = 0;
+  llvm::Value *SyncArgSlot = nullptr;
   if (!isTry) {
     llvm::Value *SyncArg =
       CGF.EmitScalarExpr(cast<ObjCAtSynchronizedStmt>(S).getSynchExpr());
@@ -3861,7 +3832,7 @@
 
   // A slot containing the exception to rethrow.  Only needed when we
   // have both a @catch and a @finally.
-  llvm::Value *PropagatingExnVar = 0;
+  llvm::Value *PropagatingExnVar = nullptr;
 
   // Push a normal cleanup to leave the try scope.
   CGF.EHStack.pushCleanup<PerformFragileFinally>(NormalAndEHCleanup, &S,
@@ -3927,10 +3898,10 @@
 
     const ObjCAtTryStmt* AtTryStmt = cast<ObjCAtTryStmt>(&S);
 
-    bool HasFinally = (AtTryStmt->getFinallyStmt() != 0);
+    bool HasFinally = (AtTryStmt->getFinallyStmt() != nullptr);
 
-    llvm::BasicBlock *CatchBlock = 0;
-    llvm::BasicBlock *CatchHandler = 0;
+    llvm::BasicBlock *CatchBlock = nullptr;
+    llvm::BasicBlock *CatchHandler = nullptr;
     if (HasFinally) {
       // Save the currently-propagating exception before
       // objc_exception_try_enter clears the exception slot.
@@ -3968,7 +3939,7 @@
       const ObjCAtCatchStmt *CatchStmt = AtTryStmt->getCatchStmt(I);
 
       const VarDecl *CatchParam = CatchStmt->getCatchParamDecl();
-      const ObjCObjectPointerType *OPT = 0;
+      const ObjCObjectPointerType *OPT = nullptr;
 
       // catch(...) always matches.
       if (!CatchParam) {
@@ -4293,14 +4264,14 @@
 ///   unsigned flags;
 /// };
 enum ImageInfoFlags {
-  eImageInfo_FixAndContinue      = (1 << 0),
+  eImageInfo_FixAndContinue      = (1 << 0), // This flag is no longer set by clang.
   eImageInfo_GarbageCollected    = (1 << 1),
   eImageInfo_GCOnly              = (1 << 2),
-  eImageInfo_OptimizedByDyld     = (1 << 3), // FIXME: When is this set.
+  eImageInfo_OptimizedByDyld     = (1 << 3), // This flag is set by the dyld shared cache.
 
   // A flag indicating that the module has no instances of a @synthesize of a
   // superclass variable. <rdar://problem/6803242>
-  eImageInfo_CorrectedSynthesize = (1 << 4),
+  eImageInfo_CorrectedSynthesize = (1 << 4), // This flag is no longer set by clang.
   eImageInfo_ImageIsSimulated    = (1 << 5)
 };
 
@@ -4373,7 +4344,7 @@
     llvm::ConstantInt::get(ObjCTypes.LongTy, ModuleVersion),
     llvm::ConstantInt::get(ObjCTypes.LongTy, Size),
     // This used to be the filename, now it is unused. <rdr://4327263>
-    GetClassName(&CGM.getContext().Idents.get("")),
+    GetClassName(StringRef("")),
     EmitModuleSymbols()
   };
   CreateMetadataVar("\01L_OBJC_MODULES",
@@ -4399,9 +4370,17 @@
   // The runtime expects exactly the list of defined classes followed
   // by the list of defined categories, in a single array.
   SmallVector<llvm::Constant*, 8> Symbols(NumClasses + NumCategories);
-  for (unsigned i=0; i<NumClasses; i++)
+  for (unsigned i=0; i<NumClasses; i++) {
+    const ObjCInterfaceDecl *ID = ImplementedClasses[i];
+    assert(ID);
+    if (ObjCImplementationDecl *IMP = ID->getImplementation())
+      // We are implementing a weak imported interface. Give it external linkage
+      if (ID->isWeakImported() && !IMP->isWeakImported())
+        DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
+    
     Symbols[i] = llvm::ConstantExpr::getBitCast(DefinedClasses[i],
                                                 ObjCTypes.Int8PtrTy);
+  }
   for (unsigned i=0; i<NumCategories; i++)
     Symbols[NumClasses + i] =
       llvm::ConstantExpr::getBitCast(DefinedCategories[i],
@@ -4429,7 +4408,7 @@
   
   if (!Entry) {
     llvm::Constant *Casted =
-    llvm::ConstantExpr::getBitCast(GetClassName(II),
+    llvm::ConstantExpr::getBitCast(GetClassName(II->getName()),
                                    ObjCTypes.ClassPtrTy);
     Entry =
     CreateMetadataVar("\01L_OBJC_CLASS_REFERENCES_", Casted,
@@ -4470,19 +4449,17 @@
   return CGF.Builder.CreateLoad(Entry);
 }
 
-llvm::Constant *CGObjCCommonMac::GetClassName(IdentifierInfo *Ident) {
-  llvm::GlobalVariable *&Entry = ClassNames[Ident];
-
-  if (!Entry)
-    Entry = CreateMetadataVar("\01L_OBJC_CLASS_NAME_",
-                              llvm::ConstantDataArray::getString(VMContext,
-                                                         Ident->getNameStart()),
-                              ((ObjCABI == 2) ?
-                               "__TEXT,__objc_classname,cstring_literals" :
-                               "__TEXT,__cstring,cstring_literals"),
-                              1, true);
-
-  return getConstantGEP(VMContext, Entry, 0, 0);
+llvm::Constant *CGObjCCommonMac::GetClassName(StringRef RuntimeName) {
+    llvm::GlobalVariable *&Entry = ClassNames[RuntimeName];
+    if (!Entry)
+        Entry = CreateMetadataVar("\01L_OBJC_CLASS_NAME_",
+                                  llvm::ConstantDataArray::getString(VMContext,
+                                                                     RuntimeName),
+                                  ((ObjCABI == 2) ?
+                                   "__TEXT,__objc_classname,cstring_literals" :
+                                   "__TEXT,__cstring,cstring_literals"),
+                                  1, true);
+    return getConstantGEP(VMContext, Entry, 0, 0);
 }
 
 llvm::Function *CGObjCCommonMac::GetMethodDefinition(const ObjCMethodDecl *MD) {
@@ -4491,7 +4468,7 @@
   if (I != MethodDefinitions.end())
     return I->second;
 
-  return NULL;
+  return nullptr;
 }
 
 /// GetIvarLayoutName - Returns a unique constant for the given
@@ -4507,16 +4484,13 @@
                                                 bool &HasUnion) {
   const RecordDecl *RD = RT->getDecl();
   // FIXME - Use iterator.
-  SmallVector<const FieldDecl*, 16> Fields;
-  for (RecordDecl::field_iterator i = RD->field_begin(),
-                                  e = RD->field_end(); i != e; ++i)
-    Fields.push_back(*i);
+  SmallVector<const FieldDecl*, 16> Fields(RD->fields());
   llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0));
   const llvm::StructLayout *RecLayout =
     CGM.getDataLayout().getStructLayout(cast<llvm::StructType>(Ty));
 
-  BuildAggrIvarLayout(0, RecLayout, RD, Fields, BytePos,
-                      ForStrongLayout, HasUnion);
+  BuildAggrIvarLayout(nullptr, RecLayout, RD, Fields, BytePos, ForStrongLayout,
+                      HasUnion);
 }
 
 void CGObjCCommonMac::BuildAggrIvarLayout(const ObjCImplementationDecl *OI,
@@ -4528,9 +4502,9 @@
   bool IsUnion = (RD && RD->isUnion());
   uint64_t MaxUnionIvarSize = 0;
   uint64_t MaxSkippedUnionIvarSize = 0;
-  const FieldDecl *MaxField = 0;
-  const FieldDecl *MaxSkippedField = 0;
-  const FieldDecl *LastFieldBitfieldOrUnnamed = 0;
+  const FieldDecl *MaxField = nullptr;
+  const FieldDecl *MaxSkippedField = nullptr;
+  const FieldDecl *LastFieldBitfieldOrUnnamed = nullptr;
   uint64_t MaxFieldOffset = 0;
   uint64_t MaxSkippedFieldOffset = 0;
   uint64_t LastBitfieldOrUnnamedOffset = 0;
@@ -4565,7 +4539,7 @@
       continue;
     }
 
-    LastFieldBitfieldOrUnnamed = 0;
+    LastFieldBitfieldOrUnnamed = nullptr;
     QualType FQT = Field->getType();
     if (FQT->isRecordType() || FQT->isUnionType()) {
       if (FQT->isUnionType())
@@ -4589,9 +4563,6 @@
         ElCount *= CArray->getSize().getZExtValue();
         FQT = CArray->getElementType();
       }
-
-      assert(!FQT->isUnionType() &&
-             "layout for array of unions not supported");
       if (FQT->isRecordType() && ElCount) {
         int OldIndex = IvarsInfo.size() - 1;
         int OldSkIndex = SkipIvars.size() -1;
@@ -4859,7 +4830,8 @@
   SkipIvars.clear();
   IvarsInfo.clear();
 
-  BuildAggrIvarLayout(OMD, 0, 0, RecFields, 0, ForStrongLayout, hasUnion);
+  BuildAggrIvarLayout(OMD, nullptr, nullptr, RecFields, 0, ForStrongLayout,
+                      hasUnion);
   if (IvarsInfo.empty())
     return llvm::Constant::getNullValue(PtrTy);
   // Sort on byte position in case we encounterred a union nested in
@@ -4875,7 +4847,7 @@
    if (CGM.getLangOpts().ObjCGCBitmapPrint) {
     printf("\n%s ivar layout for class '%s': ",
            ForStrongLayout ? "strong" : "weak",
-           OMD->getClassInterface()->getName().data());
+           OMD->getClassInterface()->getName().str().c_str());
     const unsigned char *s = (const unsigned char*)BitMap.c_str();
     for (unsigned i = 0, e = BitMap.size(); i < e; i++)
       if (!(s[i] & 0xf0))
@@ -4928,7 +4900,7 @@
                                                   bool Extended) {
   std::string TypeStr;
   if (CGM.getContext().getObjCEncodingForMethodDecl(D, TypeStr, Extended))
-    return 0;
+    return nullptr;
 
   llvm::GlobalVariable *&Entry = MethodVarTypes[TypeStr];
 
@@ -4948,11 +4920,10 @@
   llvm::GlobalVariable *&Entry = PropertyNames[Ident];
 
   if (!Entry)
-    Entry = CreateMetadataVar("\01L_OBJC_PROP_NAME_ATTR_",
-                        llvm::ConstantDataArray::getString(VMContext,
-                                                       Ident->getNameStart()),
-                              "__TEXT,__cstring,cstring_literals",
-                              1, true);
+    Entry = CreateMetadataVar(
+        "\01L_OBJC_PROP_NAME_ATTR_",
+        llvm::ConstantDataArray::getString(VMContext, Ident->getName()),
+        "__TEXT,__cstring,cstring_literals", 1, true);
 
   return getConstantGEP(VMContext, Entry, 0, 0);
 }
@@ -4992,14 +4963,14 @@
 
     llvm::Constant *Values[5];
     Values[0] = llvm::Constant::getNullValue(ObjCTypes.ProtocolExtensionPtrTy);
-    Values[1] = GetClassName(I->first);
+    Values[1] = GetClassName(I->first->getName());
     Values[2] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListPtrTy);
     Values[3] = Values[4] =
       llvm::Constant::getNullValue(ObjCTypes.MethodDescriptionListPtrTy);
-    I->second->setLinkage(llvm::GlobalValue::InternalLinkage);
+    assertPrivateName(I->second);
     I->second->setInitializer(llvm::ConstantStruct::get(ObjCTypes.ProtocolTy,
                                                         Values));
-    CGM.AddUsedGlobal(I->second);
+    CGM.addCompilerUsedGlobal(I->second);
   }
 
   // Add assembler directives to add lazy undefined symbol references
@@ -5035,14 +5006,14 @@
 CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm)
   : CGObjCCommonMac(cgm),
     ObjCTypes(cgm) {
-  ObjCEmptyCacheVar = ObjCEmptyVtableVar = NULL;
+  ObjCEmptyCacheVar = ObjCEmptyVtableVar = nullptr;
   ObjCABI = 2;
 }
 
 /* *** */
 
 ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
-  : VMContext(cgm.getLLVMContext()), CGM(cgm), ExternalProtocolPtrTy(0) 
+  : VMContext(cgm.getLLVMContext()), CGM(cgm), ExternalProtocolPtrTy(nullptr)
 {
   CodeGen::CodeGenTypes &Types = CGM.getTypes();
   ASTContext &Ctx = CGM.getContext();
@@ -5054,6 +5025,14 @@
   Int8PtrTy = CGM.Int8PtrTy;
   Int8PtrPtrTy = CGM.Int8PtrPtrTy;
 
+  // arm64 targets use "int" ivar offset variables. All others,
+  // including OS X x86_64 and Windows x86_64, use "long" ivar offsets.
+  if (CGM.getTarget().getTriple().getArch() == llvm::Triple::arm64 ||
+      CGM.getTarget().getTriple().getArch() == llvm::Triple::aarch64)
+    IvarOffsetVarTy = IntTy;
+  else
+    IvarOffsetVarTy = LongTy;
+
   ObjectPtrTy = Types.ConvertType(Ctx.getObjCIdType());
   PtrObjectPtrTy = llvm::PointerType::getUnqual(ObjectPtrTy);
   SelectorPtrTy = Types.ConvertType(Ctx.getObjCSelType());
@@ -5074,11 +5053,12 @@
                                       Ctx.getTranslationUnitDecl(),
                                       SourceLocation(), SourceLocation(),
                                       &Ctx.Idents.get("_objc_super"));
-  RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
-                                Ctx.getObjCIdType(), 0, 0, false, ICIS_NoInit));
-  RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
-                                Ctx.getObjCClassType(), 0, 0, false,
-                                ICIS_NoInit));
+  RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
+                                nullptr, Ctx.getObjCIdType(), nullptr, nullptr,
+                                false, ICIS_NoInit));
+  RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
+                                nullptr, Ctx.getObjCClassType(), nullptr,
+                                nullptr, false, ICIS_NoInit));
   RD->completeDefinition();
 
   SuperCTy = Ctx.getTagDeclType(RD);
@@ -5357,16 +5337,15 @@
   ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolListnfABITy);
 
   // struct _ivar_t {
-  //   unsigned long int *offset;  // pointer to ivar offset location
+  //   unsigned [long] int *offset;  // pointer to ivar offset location
   //   char *name;
   //   char *type;
   //   uint32_t alignment;
   //   uint32_t size;
   // }
-  IvarnfABITy =
-    llvm::StructType::create("struct._ivar_t",
-                             llvm::PointerType::getUnqual(LongTy),
-                             Int8PtrTy, Int8PtrTy, IntTy, IntTy, NULL);
+  IvarnfABITy = llvm::StructType::create(
+      "struct._ivar_t", llvm::PointerType::getUnqual(IvarOffsetVarTy),
+      Int8PtrTy, Int8PtrTy, IntTy, IntTy, NULL);
 
   // struct _ivar_list_t {
   //   uint32 entsize;  // sizeof(struct _ivar_t)
@@ -5456,11 +5435,12 @@
                                       Ctx.getTranslationUnitDecl(),
                                       SourceLocation(), SourceLocation(),
                                       &Ctx.Idents.get("_message_ref_t"));
-  RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
-                                Ctx.VoidPtrTy, 0, 0, false, ICIS_NoInit));
-  RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(), 0,
-                                Ctx.getObjCSelType(), 0, 0, false,
+  RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
+                                nullptr, Ctx.VoidPtrTy, nullptr, nullptr, false,
                                 ICIS_NoInit));
+  RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), SourceLocation(),
+                                nullptr, Ctx.getObjCSelType(), nullptr, nullptr,
+                                false, ICIS_NoInit));
   RD->completeDefinition();
 
   MessageRefCTy = Ctx.getTagDeclType(RD);
@@ -5498,7 +5478,7 @@
 llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() {
   FinishNonFragileABIModule();
 
-  return NULL;
+  return nullptr;
 }
 
 void CGObjCNonFragileABIMac::
@@ -5521,12 +5501,13 @@
 
   llvm::GlobalVariable *GV =
     new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
-                             llvm::GlobalValue::InternalLinkage,
+                             llvm::GlobalValue::PrivateLinkage,
                              Init,
                              SymbolName);
+  assertPrivateName(GV);
   GV->setAlignment(CGM.getDataLayout().getABITypeAlignment(Init->getType()));
   GV->setSection(SectionName);
-  CGM.AddUsedGlobal(GV);
+  CGM.addCompilerUsedGlobal(GV);
 }
 
 void CGObjCNonFragileABIMac::FinishNonFragileABIModule() {
@@ -5534,24 +5515,22 @@
 
   // Build list of all implemented class addresses in array
   // L_OBJC_LABEL_CLASS_$.
+
+  for (unsigned i=0, NumClasses=ImplementedClasses.size(); i<NumClasses; i++) {
+    const ObjCInterfaceDecl *ID = ImplementedClasses[i];
+    assert(ID);
+    if (ObjCImplementationDecl *IMP = ID->getImplementation())
+      // We are implementing a weak imported interface. Give it external linkage
+      if (ID->isWeakImported() && !IMP->isWeakImported()) {
+        DefinedClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
+        DefinedMetaClasses[i]->setLinkage(llvm::GlobalVariable::ExternalLinkage);
+      }
+  }
+  
   AddModuleClassList(DefinedClasses,
                      "\01L_OBJC_LABEL_CLASS_$",
                      "__DATA, __objc_classlist, regular, no_dead_strip");
-  
-  for (unsigned i = 0, e = DefinedClasses.size(); i < e; i++) {
-    llvm::GlobalValue *IMPLGV = DefinedClasses[i];
-    if (IMPLGV->getLinkage() != llvm::GlobalValue::ExternalWeakLinkage)
-      continue;
-    IMPLGV->setLinkage(llvm::GlobalValue::ExternalLinkage);
-  }
-  
-  for (unsigned i = 0, e = DefinedMetaClasses.size(); i < e; i++) {
-    llvm::GlobalValue *IMPLGV = DefinedMetaClasses[i];
-    if (IMPLGV->getLinkage() != llvm::GlobalValue::ExternalWeakLinkage)
-      continue;
-    IMPLGV->setLinkage(llvm::GlobalValue::ExternalLinkage);
-  }    
-  
+
   AddModuleClassList(DefinedNonLazyClasses,
                      "\01L_OBJC_LABEL_NONLAZY_CLASS_$",
                      "__DATA, __objc_nlclslist, regular, no_dead_strip");
@@ -5650,7 +5629,7 @@
   unsigned InstanceStart,
   unsigned InstanceSize,
   const ObjCImplementationDecl *ID) {
-  std::string ClassName = ID->getNameAsString();
+  std::string ClassName = ID->getObjCRuntimeNameAsString();
   llvm::Constant *Values[10]; // 11 for 64bit targets!
 
   if (CGM.getLangOpts().ObjCAutoRefCount)
@@ -5661,30 +5640,26 @@
   Values[ 2] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceSize);
   // FIXME. For 64bit targets add 0 here.
   Values[ 3] = (flags & NonFragileABI_Class_Meta)
-    ? GetIvarLayoutName(0, ObjCTypes)
+    ? GetIvarLayoutName(nullptr, ObjCTypes)
     : BuildIvarLayout(ID, true);
-  Values[ 4] = GetClassName(ID->getIdentifier());
+  Values[ 4] = GetClassName(ID->getObjCRuntimeNameAsString());
   // const struct _method_list_t * const baseMethods;
   std::vector<llvm::Constant*> Methods;
   std::string MethodListName("\01l_OBJC_$_");
   if (flags & NonFragileABI_Class_Meta) {
-    MethodListName += "CLASS_METHODS_" + ID->getNameAsString();
-    for (ObjCImplementationDecl::classmeth_iterator
-           i = ID->classmeth_begin(), e = ID->classmeth_end(); i != e; ++i) {
+    MethodListName += "CLASS_METHODS_";
+    MethodListName += ID->getObjCRuntimeNameAsString();
+    for (const auto *I : ID->class_methods())
       // Class methods should always be defined.
-      Methods.push_back(GetMethodConstant(*i));
-    }
+      Methods.push_back(GetMethodConstant(I));
   } else {
-    MethodListName += "INSTANCE_METHODS_" + ID->getNameAsString();
-    for (ObjCImplementationDecl::instmeth_iterator
-           i = ID->instmeth_begin(), e = ID->instmeth_end(); i != e; ++i) {
+    MethodListName += "INSTANCE_METHODS_";
+    MethodListName += ID->getObjCRuntimeNameAsString();
+    for (const auto *I : ID->instance_methods())
       // Instance methods should always be defined.
-      Methods.push_back(GetMethodConstant(*i));
-    }
-    for (ObjCImplementationDecl::propimpl_iterator
-           i = ID->propimpl_begin(), e = ID->propimpl_end(); i != e; ++i) {
-      ObjCPropertyImplDecl *PID = *i;
+      Methods.push_back(GetMethodConstant(I));
 
+    for (const auto *PID : ID->property_impls()) {
       if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize){
         ObjCPropertyDecl *PD = PID->getPropertyDecl();
 
@@ -5703,29 +5678,30 @@
   const ObjCInterfaceDecl *OID = ID->getClassInterface();
   assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer");
   Values[ 6] = EmitProtocolList("\01l_OBJC_CLASS_PROTOCOLS_$_"
-                                + OID->getName(),
+                                + OID->getObjCRuntimeNameAsString(),
                                 OID->all_referenced_protocol_begin(),
                                 OID->all_referenced_protocol_end());
 
   if (flags & NonFragileABI_Class_Meta) {
     Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
-    Values[ 8] = GetIvarLayoutName(0, ObjCTypes);
+    Values[ 8] = GetIvarLayoutName(nullptr, ObjCTypes);
     Values[ 9] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
   } else {
     Values[ 7] = EmitIvarList(ID);
     Values[ 8] = BuildIvarLayout(ID, false);
-    Values[ 9] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getName(),
+    Values[ 9] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ID->getObjCRuntimeNameAsString(),
                                   ID, ID->getClassInterface(), ObjCTypes);
   }
   llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassRonfABITy,
                                                    Values);
   llvm::GlobalVariable *CLASS_RO_GV =
     new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassRonfABITy, false,
-                             llvm::GlobalValue::InternalLinkage,
+                             llvm::GlobalValue::PrivateLinkage,
                              Init,
                              (flags & NonFragileABI_Class_Meta) ?
                              std::string("\01l_OBJC_METACLASS_RO_$_")+ClassName :
                              std::string("\01l_OBJC_CLASS_RO_$_")+ClassName);
+  assertPrivateName(CLASS_RO_GV);
   CLASS_RO_GV->setAlignment(
     CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ClassRonfABITy));
   CLASS_RO_GV->setSection("__DATA, __objc_const");
@@ -5743,12 +5719,9 @@
 ///   struct class_ro_t *ro;
 /// }
 ///
-llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassMetaData(
-  std::string &ClassName,
-  llvm::Constant *IsAGV,
-  llvm::Constant *SuperClassGV,
-  llvm::Constant *ClassRoGV,
-  bool HiddenVisibility) {
+llvm::GlobalVariable *CGObjCNonFragileABIMac::BuildClassMetaData(
+    const std::string &ClassName, llvm::Constant *IsAGV, llvm::Constant *SuperClassGV,
+    llvm::Constant *ClassRoGV, bool HiddenVisibility, bool Weak) {
   llvm::Constant *Values[] = {
     IsAGV,
     SuperClassGV,
@@ -5763,7 +5736,7 @@
                   llvm::PointerType::getUnqual(ObjCTypes.ImpnfABITy));
   llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassnfABITy,
                                                    Values);
-  llvm::GlobalVariable *GV = GetClassGlobal(ClassName);
+  llvm::GlobalVariable *GV = GetClassGlobal(ClassName, Weak);
   GV->setInitializer(Init);
   GV->setSection("__DATA, __objc_data");
   GV->setAlignment(
@@ -5775,7 +5748,7 @@
 
 bool
 CGObjCNonFragileABIMac::ImplementationIsNonLazy(const ObjCImplDecl *OD) const {
-  return OD->getClassMethod(GetNullarySelector("load")) != 0;
+  return OD->getClassMethod(GetNullarySelector("load")) != nullptr;
 }
 
 void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID,
@@ -5795,29 +5768,29 @@
 }
 
 void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) {
-  std::string ClassName = ID->getNameAsString();
+  std::string ClassName = ID->getObjCRuntimeNameAsString();
   if (!ObjCEmptyCacheVar) {
     ObjCEmptyCacheVar = new llvm::GlobalVariable(
       CGM.getModule(),
       ObjCTypes.CacheTy,
       false,
       llvm::GlobalValue::ExternalLinkage,
-      0,
+      nullptr,
       "_objc_empty_cache");
-    
+
     // Make this entry NULL for any iOS device target, any iOS simulator target,
     // OS X with deployment target 10.9 or later.
     const llvm::Triple &Triple = CGM.getTarget().getTriple();
     if (Triple.isiOS() || (Triple.isMacOSX() && !Triple.isMacOSXVersionLT(10, 9)))
       // This entry will be null.
-      ObjCEmptyVtableVar = 0;
+      ObjCEmptyVtableVar = nullptr;
     else
       ObjCEmptyVtableVar = new llvm::GlobalVariable(
                                                     CGM.getModule(),
                                                     ObjCTypes.ImpnfABITy,
                                                     false,
                                                     llvm::GlobalValue::ExternalLinkage,
-                                                    0,
+                                                    nullptr,
                                                     "_objc_empty_vtable");
   }
   assert(ID->getClassInterface() &&
@@ -5827,8 +5800,9 @@
     CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ClassnfABITy);
   uint32_t InstanceSize = InstanceStart;
   uint32_t flags = NonFragileABI_Class_Meta;
-  std::string ObjCMetaClassName(getMetaclassSymbolPrefix());
-  std::string ObjCClassName(getClassSymbolPrefix());
+  llvm::SmallString<64> ObjCMetaClassName(getMetaclassSymbolPrefix());
+  llvm::SmallString<64> ObjCClassName(getClassSymbolPrefix());
+  llvm::SmallString<64> TClassName;
 
   llvm::GlobalVariable *SuperClassGV, *IsAGV;
 
@@ -5849,31 +5823,39 @@
   if (!ID->getClassInterface()->getSuperClass()) {
     // class is root
     flags |= NonFragileABI_Class_Root;
-    SuperClassGV = GetClassGlobal(ObjCClassName + ClassName);
-    IsAGV = GetClassGlobal(ObjCMetaClassName + ClassName);
+    TClassName = ObjCClassName;
+    TClassName += ClassName;
+    SuperClassGV = GetClassGlobal(TClassName.str(),
+                                  ID->getClassInterface()->isWeakImported());
+    TClassName = ObjCMetaClassName;
+    TClassName += ClassName;
+    IsAGV = GetClassGlobal(TClassName.str(),
+                           ID->getClassInterface()->isWeakImported());
   } else {
     // Has a root. Current class is not a root.
     const ObjCInterfaceDecl *Root = ID->getClassInterface();
     while (const ObjCInterfaceDecl *Super = Root->getSuperClass())
       Root = Super;
-    IsAGV = GetClassGlobal(ObjCMetaClassName + Root->getNameAsString());
-    if (Root->isWeakImported())
-      IsAGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
+    TClassName = ObjCMetaClassName ;
+    TClassName += Root->getObjCRuntimeNameAsString();
+    IsAGV = GetClassGlobal(TClassName.str(),
+                           Root->isWeakImported());
+
     // work on super class metadata symbol.
-    std::string SuperClassName =
-      ObjCMetaClassName + 
-        ID->getClassInterface()->getSuperClass()->getNameAsString();
-    SuperClassGV = GetClassGlobal(SuperClassName);
-    if (ID->getClassInterface()->getSuperClass()->isWeakImported())
-      SuperClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
+    TClassName = ObjCMetaClassName;
+    TClassName += ID->getClassInterface()->getSuperClass()->getObjCRuntimeNameAsString();
+    SuperClassGV = GetClassGlobal(
+                                  TClassName.str(),
+                                  ID->getClassInterface()->getSuperClass()->isWeakImported());
   }
   llvm::GlobalVariable *CLASS_RO_GV = BuildClassRoTInitializer(flags,
                                                                InstanceStart,
                                                                InstanceSize,ID);
-  std::string TClassName = ObjCMetaClassName + ClassName;
-  llvm::GlobalVariable *MetaTClass =
-    BuildClassMetaData(TClassName, IsAGV, SuperClassGV, CLASS_RO_GV,
-                       classIsHidden);
+  TClassName = ObjCMetaClassName;
+  TClassName += ClassName;
+  llvm::GlobalVariable *MetaTClass = BuildClassMetaData(
+      TClassName.str(), IsAGV, SuperClassGV, CLASS_RO_GV, classIsHidden,
+      ID->getClassInterface()->isWeakImported());
   DefinedMetaClasses.push_back(MetaTClass);
 
   // Metadata for the class
@@ -5899,14 +5881,14 @@
 
   if (!ID->getClassInterface()->getSuperClass()) {
     flags |= NonFragileABI_Class_Root;
-    SuperClassGV = 0;
+    SuperClassGV = nullptr;
   } else {
     // Has a root. Current class is not a root.
-    std::string RootClassName =
-      ID->getClassInterface()->getSuperClass()->getNameAsString();
-    SuperClassGV = GetClassGlobal(ObjCClassName + RootClassName);
-    if (ID->getClassInterface()->getSuperClass()->isWeakImported())
-      SuperClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
+    TClassName = ObjCClassName;
+    TClassName += ID->getClassInterface()->getSuperClass()->getObjCRuntimeNameAsString();
+    SuperClassGV = GetClassGlobal(
+                                  TClassName.str(),
+                                  ID->getClassInterface()->getSuperClass()->isWeakImported());
   }
   GetClassSizeInfo(ID, InstanceStart, InstanceSize);
   CLASS_RO_GV = BuildClassRoTInitializer(flags,
@@ -5914,11 +5896,14 @@
                                          InstanceSize,
                                          ID);
 
-  TClassName = ObjCClassName + ClassName;
+  TClassName = ObjCClassName;
+  TClassName += ClassName;
   llvm::GlobalVariable *ClassMD =
-    BuildClassMetaData(TClassName, MetaTClass, SuperClassGV, CLASS_RO_GV,
-                       classIsHidden);
+    BuildClassMetaData(TClassName.str(), MetaTClass, SuperClassGV, CLASS_RO_GV,
+                       classIsHidden,
+                       ID->getClassInterface()->isWeakImported());
   DefinedClasses.push_back(ClassMD);
+  ImplementedClasses.push_back(ID->getClassInterface());
 
   // Determine if this class is also "non-lazy".
   if (ImplementationIsNonLazy(ID))
@@ -5950,7 +5935,7 @@
                                    ObjCTypes.getExternalProtocolPtrTy());
 
   std::string ProtocolName("\01l_OBJC_PROTOCOL_REFERENCE_$_");
-  ProtocolName += PD->getName();
+  ProtocolName += PD->getObjCRuntimeNameAsString();
 
   llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName);
   if (PTGV)
@@ -5963,7 +5948,7 @@
     ProtocolName);
   PTGV->setSection("__DATA, __objc_protorefs, coalesced, no_dead_strip");
   PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
-  CGM.AddUsedGlobal(PTGV);
+  CGM.addCompilerUsedGlobal(PTGV);
   return CGF.Builder.CreateLoad(PTGV);
 }
 
@@ -5980,58 +5965,63 @@
 void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
   const ObjCInterfaceDecl *Interface = OCD->getClassInterface();
   const char *Prefix = "\01l_OBJC_$_CATEGORY_";
-  std::string ExtCatName(Prefix + Interface->getNameAsString()+
-                         "_$_" + OCD->getNameAsString());
-  std::string ExtClassName(getClassSymbolPrefix() +
-                           Interface->getNameAsString());
+    
+  llvm::SmallString<64> ExtCatName(Prefix);
+  ExtCatName += Interface->getObjCRuntimeNameAsString();
+  ExtCatName += "_$_";
+  ExtCatName += OCD->getNameAsString();
+    
+  llvm::SmallString<64> ExtClassName(getClassSymbolPrefix());
+  ExtClassName += Interface->getObjCRuntimeNameAsString();
 
   llvm::Constant *Values[6];
-  Values[0] = GetClassName(OCD->getIdentifier());
+  Values[0] = GetClassName(OCD->getIdentifier()->getName());
   // meta-class entry symbol
-  llvm::GlobalVariable *ClassGV = GetClassGlobal(ExtClassName);
-  if (Interface->isWeakImported())
-    ClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
-  
+  llvm::GlobalVariable *ClassGV =
+      GetClassGlobal(ExtClassName.str(), Interface->isWeakImported());
+
   Values[1] = ClassGV;
   std::vector<llvm::Constant*> Methods;
-  std::string MethodListName(Prefix);
-  MethodListName += "INSTANCE_METHODS_" + Interface->getNameAsString() +
-    "_$_" + OCD->getNameAsString();
+  llvm::SmallString<64> MethodListName(Prefix);
+    
+  MethodListName += "INSTANCE_METHODS_";
+  MethodListName += Interface->getObjCRuntimeNameAsString();
+  MethodListName += "_$_";
+  MethodListName += OCD->getName();
 
-  for (ObjCCategoryImplDecl::instmeth_iterator
-         i = OCD->instmeth_begin(), e = OCD->instmeth_end(); i != e; ++i) {
+  for (const auto *I : OCD->instance_methods())
     // Instance methods should always be defined.
-    Methods.push_back(GetMethodConstant(*i));
-  }
+    Methods.push_back(GetMethodConstant(I));
 
-  Values[2] = EmitMethodList(MethodListName,
+  Values[2] = EmitMethodList(MethodListName.str(),
                              "__DATA, __objc_const",
                              Methods);
 
   MethodListName = Prefix;
-  MethodListName += "CLASS_METHODS_" + Interface->getNameAsString() + "_$_" +
-    OCD->getNameAsString();
+  MethodListName += "CLASS_METHODS_";
+  MethodListName += Interface->getObjCRuntimeNameAsString();
+  MethodListName += "_$_";
+  MethodListName += OCD->getNameAsString();
+    
   Methods.clear();
-  for (ObjCCategoryImplDecl::classmeth_iterator
-         i = OCD->classmeth_begin(), e = OCD->classmeth_end(); i != e; ++i) {
+  for (const auto *I : OCD->class_methods())
     // Class methods should always be defined.
-    Methods.push_back(GetMethodConstant(*i));
-  }
+    Methods.push_back(GetMethodConstant(I));
 
-  Values[3] = EmitMethodList(MethodListName,
+  Values[3] = EmitMethodList(MethodListName.str(),
                              "__DATA, __objc_const",
                              Methods);
   const ObjCCategoryDecl *Category =
     Interface->FindCategoryDeclaration(OCD->getIdentifier());
   if (Category) {
     SmallString<256> ExtName;
-    llvm::raw_svector_ostream(ExtName) << Interface->getName() << "_$_"
+    llvm::raw_svector_ostream(ExtName) << Interface->getObjCRuntimeNameAsString() << "_$_"
                                        << OCD->getName();
     Values[4] = EmitProtocolList("\01l_OBJC_CATEGORY_PROTOCOLS_$_"
-                                 + Interface->getName() + "_$_"
-                                 + Category->getName(),
-                                 Category->protocol_begin(),
-                                 Category->protocol_end());
+                                   + Interface->getObjCRuntimeNameAsString() + "_$_"
+                                   + Category->getName(),
+                                   Category->protocol_begin(),
+                                   Category->protocol_end());
     Values[5] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + ExtName.str(),
                                  OCD, Category, ObjCTypes);
   } else {
@@ -6045,13 +6035,14 @@
   llvm::GlobalVariable *GCATV
     = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.CategorynfABITy,
                                false,
-                               llvm::GlobalValue::InternalLinkage,
+                               llvm::GlobalValue::PrivateLinkage,
                                Init,
-                               ExtCatName);
+                               ExtCatName.str());
+  assertPrivateName(GCATV);
   GCATV->setAlignment(
     CGM.getDataLayout().getABITypeAlignment(ObjCTypes.CategorynfABITy));
   GCATV->setSection("__DATA, __objc_const");
-  CGM.AddUsedGlobal(GCATV);
+  CGM.addCompilerUsedGlobal(GCATV);
   DefinedCategories.push_back(GCATV);
 
   // Determine if this category is also "non-lazy".
@@ -6068,7 +6059,7 @@
   const ObjCMethodDecl *MD) {
   llvm::Function *Fn = GetMethodDefinition(MD);
   if (!Fn)
-    return 0;
+    return nullptr;
 
   llvm::Constant *Method[] = {
     llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
@@ -6107,10 +6098,11 @@
 
   llvm::GlobalVariable *GV =
     new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
-                             llvm::GlobalValue::InternalLinkage, Init, Name);
+                             llvm::GlobalValue::PrivateLinkage, Init, Name);
+  assertPrivateName(GV);
   GV->setAlignment(CGM.getDataLayout().getABITypeAlignment(Init->getType()));
   GV->setSection(Section);
-  CGM.AddUsedGlobal(GV);
+  CGM.addCompilerUsedGlobal(GV);
   return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListnfABIPtrTy);
 }
 
@@ -6119,18 +6111,18 @@
 llvm::GlobalVariable *
 CGObjCNonFragileABIMac::ObjCIvarOffsetVariable(const ObjCInterfaceDecl *ID,
                                                const ObjCIvarDecl *Ivar) {
+    
   const ObjCInterfaceDecl *Container = Ivar->getContainingInterface();
-  std::string Name = "OBJC_IVAR_$_" + Container->getNameAsString() +
-    '.' + Ivar->getNameAsString();
+  llvm::SmallString<64> Name("OBJC_IVAR_$_");
+  Name += Container->getObjCRuntimeNameAsString();
+  Name += ".";
+  Name += Ivar->getName();
   llvm::GlobalVariable *IvarOffsetGV =
     CGM.getModule().getGlobalVariable(Name);
   if (!IvarOffsetGV)
-    IvarOffsetGV =
-      new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.LongTy,
-                               false,
-                               llvm::GlobalValue::ExternalLinkage,
-                               0,
-                               Name);
+    IvarOffsetGV = new llvm::GlobalVariable(
+      CGM.getModule(), ObjCTypes.IvarOffsetVarTy, false,
+      llvm::GlobalValue::ExternalLinkage, nullptr, Name.str());
   return IvarOffsetGV;
 }
 
@@ -6139,10 +6131,10 @@
                                           const ObjCIvarDecl *Ivar,
                                           unsigned long int Offset) {
   llvm::GlobalVariable *IvarOffsetGV = ObjCIvarOffsetVariable(ID, Ivar);
-  IvarOffsetGV->setInitializer(llvm::ConstantInt::get(ObjCTypes.LongTy,
-                                                      Offset));
+  IvarOffsetGV->setInitializer(
+      llvm::ConstantInt::get(ObjCTypes.IvarOffsetVarTy, Offset));
   IvarOffsetGV->setAlignment(
-    CGM.getDataLayout().getABITypeAlignment(ObjCTypes.LongTy));
+      CGM.getDataLayout().getABITypeAlignment(ObjCTypes.IvarOffsetVarTy));
 
   // FIXME: This matches gcc, but shouldn't the visibility be set on the use as
   // well (i.e., in ObjCIvarOffsetVariable).
@@ -6160,7 +6152,7 @@
 /// implementation. The return value has type
 /// IvarListnfABIPtrTy.
 ///  struct _ivar_t {
-///   unsigned long int *offset;  // pointer to ivar offset location
+///   unsigned [long] int *offset;  // pointer to ivar offset location
 ///   char *name;
 ///   char *type;
 ///   uint32_t alignment;
@@ -6223,14 +6215,15 @@
   const char *Prefix = "\01l_OBJC_$_INSTANCE_VARIABLES_";
   llvm::GlobalVariable *GV =
     new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
-                             llvm::GlobalValue::InternalLinkage,
+                             llvm::GlobalValue::PrivateLinkage,
                              Init,
-                             Prefix + OID->getName());
+                             Prefix + OID->getObjCRuntimeNameAsString());
+  assertPrivateName(GV);
   GV->setAlignment(
     CGM.getDataLayout().getABITypeAlignment(Init->getType()));
   GV->setSection("__DATA, __objc_const");
 
-  CGM.AddUsedGlobal(GV);
+  CGM.addCompilerUsedGlobal(GV);
   return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListnfABIPtrTy);
 }
 
@@ -6243,10 +6236,10 @@
     // reference or not. At module finalization we add the empty
     // contents for protocols which were referenced but never defined.
     Entry =
-      new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy, false,
-                               llvm::GlobalValue::ExternalLinkage,
-                               0,
-                               "\01l_OBJC_PROTOCOL_$_" + PD->getName());
+        new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
+                                 false, llvm::GlobalValue::WeakAnyLinkage,
+                                 nullptr,
+                                 "\01l_OBJC_PROTOCOL_$_" + PD->getObjCRuntimeNameAsString());
     Entry->setSection("__DATA,__datacoal_nt,coalesced");
   }
 
@@ -6287,9 +6280,7 @@
   std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
   std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
   std::vector<llvm::Constant*> MethodTypesExt, OptMethodTypesExt;
-  for (ObjCProtocolDecl::instmeth_iterator
-         i = PD->instmeth_begin(), e = PD->instmeth_end(); i != e; ++i) {
-    ObjCMethodDecl *MD = *i;
+  for (const auto *MD : PD->instance_methods()) {
     llvm::Constant *C = GetMethodDescriptionConstant(MD);
     if (!C)
       return GetOrEmitProtocolRef(PD);
@@ -6303,9 +6294,7 @@
     }
   }
 
-  for (ObjCProtocolDecl::classmeth_iterator
-         i = PD->classmeth_begin(), e = PD->classmeth_end(); i != e; ++i) {
-    ObjCMethodDecl *MD = *i;
+  for (const auto *MD : PD->class_methods()) {
     llvm::Constant *C = GetMethodDescriptionConstant(MD);
     if (!C)
       return GetOrEmitProtocolRef(PD);
@@ -6325,48 +6314,48 @@
   llvm::Constant *Values[11];
   // isa is NULL
   Values[0] = llvm::Constant::getNullValue(ObjCTypes.ObjectPtrTy);
-  Values[1] = GetClassName(PD->getIdentifier());
-  Values[2] = EmitProtocolList("\01l_OBJC_$_PROTOCOL_REFS_" + PD->getName(),
+  Values[1] = GetClassName(PD->getObjCRuntimeNameAsString());
+  Values[2] = EmitProtocolList("\01l_OBJC_$_PROTOCOL_REFS_" + PD->getObjCRuntimeNameAsString(),
                                PD->protocol_begin(),
                                PD->protocol_end());
 
   Values[3] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_"
-                             + PD->getName(),
+                             + PD->getObjCRuntimeNameAsString(),
                              "__DATA, __objc_const",
                              InstanceMethods);
   Values[4] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_"
-                             + PD->getName(),
+                             + PD->getObjCRuntimeNameAsString(),
                              "__DATA, __objc_const",
                              ClassMethods);
   Values[5] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_"
-                             + PD->getName(),
+                             + PD->getObjCRuntimeNameAsString(),
                              "__DATA, __objc_const",
                              OptInstanceMethods);
   Values[6] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_"
-                             + PD->getName(),
+                             + PD->getObjCRuntimeNameAsString(),
                              "__DATA, __objc_const",
                              OptClassMethods);
-  Values[7] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + PD->getName(),
-                               0, PD, ObjCTypes);
+  Values[7] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + PD->getObjCRuntimeNameAsString(),
+                               nullptr, PD, ObjCTypes);
   uint32_t Size =
     CGM.getDataLayout().getTypeAllocSize(ObjCTypes.ProtocolnfABITy);
   Values[8] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
   Values[9] = llvm::Constant::getNullValue(ObjCTypes.IntTy);
   Values[10] = EmitProtocolMethodTypes("\01l_OBJC_$_PROTOCOL_METHOD_TYPES_"
-                                       + PD->getName(),
+                                       + PD->getObjCRuntimeNameAsString(),
                                        MethodTypesExt, ObjCTypes);
   llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolnfABITy,
                                                    Values);
 
   if (Entry) {
-    // Already created, fix the linkage and update the initializer.
-    Entry->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
+    // Already created, update the initializer.
+    assert(Entry->hasWeakAnyLinkage());
     Entry->setInitializer(Init);
   } else {
     Entry =
       new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABITy,
                                false, llvm::GlobalValue::WeakAnyLinkage, Init,
-                               "\01l_OBJC_PROTOCOL_$_" + PD->getName());
+                               "\01l_OBJC_PROTOCOL_$_" + PD->getObjCRuntimeNameAsString());
     Entry->setAlignment(
       CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ProtocolnfABITy));
     Entry->setSection("__DATA,__datacoal_nt,coalesced");
@@ -6374,19 +6363,19 @@
     Protocols[PD->getIdentifier()] = Entry;
   }
   Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
-  CGM.AddUsedGlobal(Entry);
+  CGM.addCompilerUsedGlobal(Entry);
 
   // Use this protocol meta-data to build protocol list table in section
   // __DATA, __objc_protolist
   llvm::GlobalVariable *PTGV =
     new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ProtocolnfABIPtrTy,
                              false, llvm::GlobalValue::WeakAnyLinkage, Entry,
-                             "\01l_OBJC_LABEL_PROTOCOL_$_" + PD->getName());
+                             "\01l_OBJC_LABEL_PROTOCOL_$_" + PD->getObjCRuntimeNameAsString());
   PTGV->setAlignment(
     CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ProtocolnfABIPtrTy));
   PTGV->setSection("__DATA, __objc_protolist, coalesced, no_dead_strip");
   PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
-  CGM.AddUsedGlobal(PTGV);
+  CGM.addCompilerUsedGlobal(PTGV);
   return Entry;
 }
 
@@ -6433,12 +6422,13 @@
 
   llvm::Constant *Init = llvm::ConstantStruct::getAnon(Values);
   GV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), false,
-                                llvm::GlobalValue::InternalLinkage,
+                                llvm::GlobalValue::PrivateLinkage,
                                 Init, Name);
+  assertPrivateName(GV);
   GV->setSection("__DATA, __objc_const");
   GV->setAlignment(
     CGM.getDataLayout().getABITypeAlignment(Init->getType()));
-  CGM.AddUsedGlobal(GV);
+  CGM.addCompilerUsedGlobal(GV);
   return llvm::ConstantExpr::getBitCast(GV,
                                         ObjCTypes.ProtocolListnfABIPtrTy);
 }
@@ -6458,8 +6448,8 @@
                                    ObjCTypes.SelectorPtrTy);
   Desc[1] = GetMethodVarType(MD);
   if (!Desc[1])
-    return 0;
-  
+    return nullptr;
+
   // Protocol methods have no implementation. So, this entry is always NULL.
   Desc[2] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
   return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Desc);
@@ -6479,12 +6469,6 @@
                                                unsigned CVRQualifiers) {
   ObjCInterfaceDecl *ID = ObjectTy->getAs<ObjCObjectType>()->getInterface();
   llvm::Value *Offset = EmitIvarOffset(CGF, ID, Ivar);
-
-  if (IsIvarOffsetKnownIdempotent(CGF, ID, Ivar))
-    if (llvm::LoadInst *LI = cast<llvm::LoadInst>(Offset))
-      LI->setMetadata(CGM.getModule().getMDKindID("invariant.load"),
-                      llvm::MDNode::get(VMContext, ArrayRef<llvm::Value*>()));
-
   return EmitValueForIvarAtOffset(CGF, ID, BaseValue, Ivar, CVRQualifiers,
                                   Offset);
 }
@@ -6493,7 +6477,20 @@
   CodeGen::CodeGenFunction &CGF,
   const ObjCInterfaceDecl *Interface,
   const ObjCIvarDecl *Ivar) {
-  return CGF.Builder.CreateLoad(ObjCIvarOffsetVariable(Interface, Ivar),"ivar");
+  llvm::Value *IvarOffsetValue = ObjCIvarOffsetVariable(Interface, Ivar);
+  IvarOffsetValue = CGF.Builder.CreateLoad(IvarOffsetValue, "ivar");
+  if (IsIvarOffsetKnownIdempotent(CGF, Ivar))
+    cast<llvm::LoadInst>(IvarOffsetValue)
+        ->setMetadata(CGM.getModule().getMDKindID("invariant.load"),
+                      llvm::MDNode::get(VMContext, ArrayRef<llvm::Value *>()));
+
+  // This could be 32bit int or 64bit integer depending on the architecture.
+  // Cast it to 64bit integer value, if it is a 32bit integer ivar offset value
+  //  as this is what caller always expectes.
+  if (ObjCTypes.IvarOffsetVarTy == ObjCTypes.IntTy)
+    IvarOffsetValue = CGF.Builder.CreateIntCast(
+        IvarOffsetValue, ObjCTypes.LongTy, true, "ivar.conv");
+  return IvarOffsetValue;
 }
 
 static void appendSelectorForMessageRefTable(std::string &buffer,
@@ -6539,7 +6536,7 @@
 
   // Second argument: a pointer to the message ref structure.  Leave
   // the actual argument value blank for now.
-  args.add(RValue::get(0), ObjCTypes.MessageRefCPtrTy);
+  args.add(RValue::get(nullptr), ObjCTypes.MessageRefCPtrTy);
 
   args.insert(args.end(), formalArgs.begin(), formalArgs.end());
 
@@ -6554,9 +6551,9 @@
   // The runtime currently never uses vtable dispatch for anything
   // except normal, non-super message-sends.
   // FIXME: don't use this for that.
-  llvm::Constant *fn = 0;
+  llvm::Constant *fn = nullptr;
   std::string messageRefName("\01l_");
-  if (CGM.ReturnTypeUsesSRet(MSI.CallInfo)) {
+  if (CGM.ReturnSlotInterferesWithArgs(MSI.CallInfo)) {
     if (isSuper) {
       fn = ObjCTypes.getMessageSendSuper2StretFixupFn();
       messageRefName += "objc_msgSendSuper2_stret_fixup";
@@ -6603,9 +6600,7 @@
   
   bool requiresnullCheck = false;
   if (CGM.getLangOpts().ObjCAutoRefCount && method)
-    for (ObjCMethodDecl::param_const_iterator i = method->param_begin(),
-         e = method->param_end(); i != e; ++i) {
-      const ParmVarDecl *ParamDecl = (*i);
+    for (const auto *ParamDecl : method->params()) {
       if (ParamDecl->hasAttr<NSConsumedAttr>()) {
         if (!nullReturn.NullBB)
           nullReturn.init(CGF, arg0);
@@ -6627,8 +6622,8 @@
   callee = CGF.Builder.CreateBitCast(callee, MSI.MessengerType);
 
   RValue result = CGF.EmitCall(MSI.CallInfo, callee, returnSlot, args);
-  return nullReturn.complete(CGF, result, resultType, formalArgs, 
-                             requiresnullCheck ? method : 0);
+  return nullReturn.complete(CGF, result, resultType, formalArgs,
+                             requiresnullCheck ? method : nullptr);
 }
 
 /// Generate code for a message send expression in the nonfragile abi.
@@ -6652,49 +6647,56 @@
 }
 
 llvm::GlobalVariable *
-CGObjCNonFragileABIMac::GetClassGlobal(const std::string &Name) {
+CGObjCNonFragileABIMac::GetClassGlobal(const std::string &Name, bool Weak) {
+  llvm::GlobalValue::LinkageTypes L =
+      Weak ? llvm::GlobalValue::ExternalWeakLinkage
+           : llvm::GlobalValue::ExternalLinkage;
+
   llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
 
-  if (!GV) {
+  if (!GV)
     GV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABITy,
-                                  false, llvm::GlobalValue::ExternalLinkage,
-                                  0, Name);
-  }
+                                  false, L, nullptr, Name);
 
+  assert(GV->getLinkage() == L);
   return GV;
 }
 
 llvm::Value *CGObjCNonFragileABIMac::EmitClassRefFromId(CodeGenFunction &CGF,
-                                                        IdentifierInfo *II) {
+                                                        IdentifierInfo *II,
+                                                        bool Weak,
+                                                        const ObjCInterfaceDecl *ID) {
   llvm::GlobalVariable *&Entry = ClassReferences[II];
   
   if (!Entry) {
-    std::string ClassName(getClassSymbolPrefix() + II->getName().str());
-    llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName);
+    std::string ClassName(
+      getClassSymbolPrefix() +
+      (ID ? ID->getObjCRuntimeNameAsString() : II->getName()).str());
+    llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName, Weak);
     Entry =
     new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
-                             false, llvm::GlobalValue::InternalLinkage,
+                             false, llvm::GlobalValue::PrivateLinkage,
                              ClassGV,
                              "\01L_OBJC_CLASSLIST_REFERENCES_$_");
     Entry->setAlignment(
                         CGM.getDataLayout().getABITypeAlignment(
                                                                 ObjCTypes.ClassnfABIPtrTy));
     Entry->setSection("__DATA, __objc_classrefs, regular, no_dead_strip");
-    CGM.AddUsedGlobal(Entry);
+    CGM.addCompilerUsedGlobal(Entry);
   }
-  
+  assertPrivateName(Entry);
   return CGF.Builder.CreateLoad(Entry);
 }
 
 llvm::Value *CGObjCNonFragileABIMac::EmitClassRef(CodeGenFunction &CGF,
                                                   const ObjCInterfaceDecl *ID) {
-  return EmitClassRefFromId(CGF, ID->getIdentifier());
+  return EmitClassRefFromId(CGF, ID->getIdentifier(), ID->isWeakImported(), ID);
 }
 
 llvm::Value *CGObjCNonFragileABIMac::EmitNSAutoreleasePoolClassRef(
                                                     CodeGenFunction &CGF) {
   IdentifierInfo *II = &CGM.getContext().Idents.get("NSAutoreleasePool");
-  return EmitClassRefFromId(CGF, II);
+  return EmitClassRefFromId(CGF, II, false, 0);
 }
 
 llvm::Value *
@@ -6703,20 +6705,22 @@
   llvm::GlobalVariable *&Entry = SuperClassReferences[ID->getIdentifier()];
 
   if (!Entry) {
-    std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
-    llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName);
+    llvm::SmallString<64> ClassName(getClassSymbolPrefix());
+    ClassName += ID->getObjCRuntimeNameAsString();
+    llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName.str(),
+                                                   ID->isWeakImported());
     Entry =
       new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
-                               false, llvm::GlobalValue::InternalLinkage,
+                               false, llvm::GlobalValue::PrivateLinkage,
                                ClassGV,
                                "\01L_OBJC_CLASSLIST_SUP_REFS_$_");
     Entry->setAlignment(
       CGM.getDataLayout().getABITypeAlignment(
         ObjCTypes.ClassnfABIPtrTy));
     Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip");
-    CGM.AddUsedGlobal(Entry);
+    CGM.addCompilerUsedGlobal(Entry);
   }
-
+  assertPrivateName(Entry);
   return CGF.Builder.CreateLoad(Entry);
 }
 
@@ -6724,25 +6728,27 @@
 /// meta-data
 ///
 llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(CodeGenFunction &CGF,
-                                                      const ObjCInterfaceDecl *ID) {
+                                                      const ObjCInterfaceDecl *ID,
+                                                      bool Weak) {
   llvm::GlobalVariable * &Entry = MetaClassReferences[ID->getIdentifier()];
-  if (Entry)
-    return CGF.Builder.CreateLoad(Entry);
+  if (!Entry) {
+    llvm::SmallString<64> MetaClassName(getMetaclassSymbolPrefix());
+    MetaClassName += ID->getObjCRuntimeNameAsString();
+    llvm::GlobalVariable *MetaClassGV =
+      GetClassGlobal(MetaClassName.str(), Weak);
+      
+    Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy,
+                                     false, llvm::GlobalValue::PrivateLinkage,
+                                     MetaClassGV,
+                                     "\01L_OBJC_CLASSLIST_SUP_REFS_$_");
+    Entry->setAlignment(
+        CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ClassnfABIPtrTy));
 
-  std::string MetaClassName(getMetaclassSymbolPrefix() + ID->getNameAsString());
-  llvm::GlobalVariable *MetaClassGV = GetClassGlobal(MetaClassName);
-  Entry =
-    new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.ClassnfABIPtrTy, false,
-                             llvm::GlobalValue::InternalLinkage,
-                             MetaClassGV,
-                             "\01L_OBJC_CLASSLIST_SUP_REFS_$_");
-  Entry->setAlignment(
-    CGM.getDataLayout().getABITypeAlignment(
-      ObjCTypes.ClassnfABIPtrTy));
+    Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip");
+    CGM.addCompilerUsedGlobal(Entry);
+  }
 
-  Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip");
-  CGM.AddUsedGlobal(Entry);
-
+  assertPrivateName(Entry);
   return CGF.Builder.CreateLoad(Entry);
 }
 
@@ -6751,9 +6757,11 @@
 llvm::Value *CGObjCNonFragileABIMac::GetClass(CodeGenFunction &CGF,
                                               const ObjCInterfaceDecl *ID) {
   if (ID->isWeakImported()) {
-    std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
-    llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName);
-    ClassGV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
+    llvm::SmallString<64> ClassName(getClassSymbolPrefix());
+    ClassName += ID->getObjCRuntimeNameAsString();
+    llvm::GlobalVariable *ClassGV = GetClassGlobal(ClassName.str(), true);
+    (void)ClassGV;
+    assert(ClassGV->hasExternalWeakLinkage());
   }
   
   return EmitClassRef(CGF, ID);
@@ -6787,7 +6795,8 @@
   // If this is a class message the metaclass is passed as the target.
   llvm::Value *Target;
   if (IsClassMessage)
-      Target = EmitMetaClassRef(CGF, Class);
+      Target = EmitMetaClassRef(CGF, Class,
+                                (isCategoryImpl && Class->isWeakImported()));
   else
     Target = EmitSuperClassRef(CGF, Class);
 
@@ -6819,12 +6828,13 @@
                                      ObjCTypes.SelectorPtrTy);
     Entry =
       new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.SelectorPtrTy, false,
-                               llvm::GlobalValue::InternalLinkage,
+                               llvm::GlobalValue::PrivateLinkage,
                                Casted, "\01L_OBJC_SELECTOR_REFERENCES_");
     Entry->setExternallyInitialized(true);
     Entry->setSection("__DATA, __objc_selrefs, literal_pointers, no_dead_strip");
-    CGM.AddUsedGlobal(Entry);
+    CGM.addCompilerUsedGlobal(Entry);
   }
+  assertPrivateName(Entry);
 
   if (lval)
     return Entry;
@@ -6969,7 +6979,7 @@
         new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy,
                                  false,
                                  llvm::GlobalValue::ExternalLinkage,
-                                 0, "OBJC_EHTYPE_id");
+                                 nullptr, "OBJC_EHTYPE_id");
     return IDEHType;
   }
 
@@ -7024,17 +7034,18 @@
     // attribute, emit an external reference.
     if (hasObjCExceptionAttribute(CGM.getContext(), ID))
       return Entry =
-        new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
-                                 llvm::GlobalValue::ExternalLinkage,
-                                 0,
-                                 ("OBJC_EHTYPE_$_" +
-                                  ID->getIdentifier()->getName()));
+          new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
+                                   llvm::GlobalValue::ExternalLinkage,
+                                   nullptr,
+                                   ("OBJC_EHTYPE_$_" +
+                                    ID->getObjCRuntimeNameAsString()));
   }
 
   // Otherwise we need to either make a new entry or fill in the
   // initializer.
   assert((!Entry || !Entry->hasInitializer()) && "Duplicate EHType definition");
-  std::string ClassName(getClassSymbolPrefix() + ID->getNameAsString());
+  llvm::SmallString<64> ClassName(getClassSymbolPrefix());
+  ClassName += ID->getObjCRuntimeNameAsString();
   std::string VTableName = "objc_ehtype_vtable";
   llvm::GlobalVariable *VTableGV =
     CGM.getModule().getGlobalVariable(VTableName);
@@ -7042,39 +7053,42 @@
     VTableGV = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.Int8PtrTy,
                                         false,
                                         llvm::GlobalValue::ExternalLinkage,
-                                        0, VTableName);
+                                        nullptr, VTableName);
 
   llvm::Value *VTableIdx = llvm::ConstantInt::get(CGM.Int32Ty, 2);
 
   llvm::Constant *Values[] = {
     llvm::ConstantExpr::getGetElementPtr(VTableGV, VTableIdx),
-    GetClassName(ID->getIdentifier()),
-    GetClassGlobal(ClassName)
+    GetClassName(ID->getObjCRuntimeNameAsString()),
+    GetClassGlobal(ClassName.str())
   };
   llvm::Constant *Init =
     llvm::ConstantStruct::get(ObjCTypes.EHTypeTy, Values);
 
+  llvm::GlobalValue::LinkageTypes L = ForDefinition
+                                          ? llvm::GlobalValue::ExternalLinkage
+                                          : llvm::GlobalValue::WeakAnyLinkage;
   if (Entry) {
     Entry->setInitializer(Init);
   } else {
+    llvm::SmallString<64> EHTYPEName("OBJC_EHTYPE_$_");
+    EHTYPEName += ID->getObjCRuntimeNameAsString();
     Entry = new llvm::GlobalVariable(CGM.getModule(), ObjCTypes.EHTypeTy, false,
-                                     llvm::GlobalValue::WeakAnyLinkage,
+                                     L,
                                      Init,
-                                     ("OBJC_EHTYPE_$_" +
-                                      ID->getIdentifier()->getName()));
+                                     EHTYPEName.str());
   }
+  assert(Entry->getLinkage() == L);
 
   if (ID->getVisibility() == HiddenVisibility)
     Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
   Entry->setAlignment(CGM.getDataLayout().getABITypeAlignment(
       ObjCTypes.EHTypeTy));
 
-  if (ForDefinition) {
+  if (ForDefinition)
     Entry->setSection("__DATA,__objc_const");
-    Entry->setLinkage(llvm::GlobalValue::ExternalLinkage);
-  } else {
+  else
     Entry->setSection("__DATA,__datacoal_nt,coalesced");
-  }
 
   return Entry;
 }
diff --git a/lib/CodeGen/CGObjCRuntime.cpp b/lib/CodeGen/CGObjCRuntime.cpp
index d097b6f..3d013da 100644
--- a/lib/CodeGen/CGObjCRuntime.cpp
+++ b/lib/CodeGen/CGObjCRuntime.cpp
@@ -21,7 +21,7 @@
 #include "clang/AST/RecordLayout.h"
 #include "clang/AST/StmtObjC.h"
 #include "clang/CodeGen/CGFunctionInfo.h"
-#include "llvm/Support/CallSite.h"
+#include "llvm/IR/CallSite.h"
 
 using namespace clang;
 using namespace CodeGen;
@@ -65,7 +65,7 @@
 uint64_t CGObjCRuntime::ComputeIvarBaseOffset(CodeGen::CodeGenModule &CGM,
                                               const ObjCInterfaceDecl *OID,
                                               const ObjCIvarDecl *Ivar) {
-  return LookupFieldBitOffset(CGM, OID, 0, Ivar) / 
+  return LookupFieldBitOffset(CGM, OID, nullptr, Ivar) /
     CGM.getContext().getCharWidth();
 }
 
@@ -116,7 +116,7 @@
   // Note, there is a subtle invariant here: we can only call this routine on
   // non-synthesized ivars but we may be called for synthesized ivars.  However,
   // a synthesized ivar can never be a bit-field, so this is safe.
-  uint64_t FieldBitOffset = LookupFieldBitOffset(CGF.CGM, OID, 0, Ivar);
+  uint64_t FieldBitOffset = LookupFieldBitOffset(CGF.CGM, OID, nullptr, Ivar);
   uint64_t BitOffset = FieldBitOffset % CGF.CGM.getContext().getCharWidth();
   uint64_t AlignmentBits = CGF.CGM.getTarget().getCharAlign();
   uint64_t BitFieldSize = Ivar->getBitWidthValue(CGF.getContext());
@@ -149,7 +149,7 @@
     const VarDecl *Variable;
     const Stmt *Body;
     llvm::BasicBlock *Block;
-    llvm::Value *TypeInfo;
+    llvm::Constant *TypeInfo;
   };
 
   struct CallObjCEndCatch : EHScopeStack::Cleanup {
@@ -158,7 +158,7 @@
     bool MightThrow;
     llvm::Value *Fn;
 
-    void Emit(CodeGenFunction &CGF, Flags flags) {
+    void Emit(CodeGenFunction &CGF, Flags flags) override {
       if (!MightThrow) {
         CGF.Builder.CreateCall(Fn)->setDoesNotThrow();
         return;
@@ -201,7 +201,7 @@
 
       // @catch(...) always matches.
       if (!CatchDecl) {
-        Handler.TypeInfo = 0; // catch-all
+        Handler.TypeInfo = nullptr; // catch-all
         // Don't consider any other catches.
         break;
       }
@@ -242,7 +242,7 @@
 
     if (endCatchFn) {
       // Add a cleanup to leave the catch.
-      bool EndCatchMightThrow = (Handler.Variable == 0);
+      bool EndCatchMightThrow = (Handler.Variable == nullptr);
 
       CGF.EHStack.pushCleanup<CallObjCEndCatch>(NormalAndEHCleanup,
                                                 EndCatchMightThrow,
@@ -303,7 +303,7 @@
     CallSyncExit(llvm::Value *SyncExitFn, llvm::Value *SyncArg)
       : SyncExitFn(SyncExitFn), SyncArg(SyncArg) {}
 
-    void Emit(CodeGenFunction &CGF, Flags flags) {
+    void Emit(CodeGenFunction &CGF, Flags flags) override {
       CGF.Builder.CreateCall(SyncExitFn, SyncArg)->setDoesNotThrow();
     }
   };
diff --git a/lib/CodeGen/CGObjCRuntime.h b/lib/CodeGen/CGObjCRuntime.h
index 7f030f2..fc6bee3 100644
--- a/lib/CodeGen/CGObjCRuntime.h
+++ b/lib/CodeGen/CGObjCRuntime.h
@@ -156,8 +156,8 @@
                       Selector Sel,
                       llvm::Value *Receiver,
                       const CallArgList &CallArgs,
-                      const ObjCInterfaceDecl *Class = 0,
-                      const ObjCMethodDecl *Method = 0) = 0;
+                      const ObjCInterfaceDecl *Class = nullptr,
+                      const ObjCMethodDecl *Method = nullptr) = 0;
 
   /// Generate an Objective-C message send operation to the super
   /// class initiated in a method for Class and with the given Self
@@ -175,7 +175,7 @@
                            llvm::Value *Self,
                            bool IsClassMessage,
                            const CallArgList &CallArgs,
-                           const ObjCMethodDecl *Method = 0) = 0;
+                           const ObjCMethodDecl *Method = nullptr) = 0;
 
   /// Emit the code to return the named protocol as an object, as in a
   /// \@protocol expression.
@@ -268,7 +268,8 @@
                                   const CodeGen::CGBlockInfo &blockInfo) = 0;
   virtual llvm::Constant *BuildByrefLayout(CodeGen::CodeGenModule &CGM,
                                            QualType T) = 0;
-  virtual llvm::GlobalVariable *GetClassGlobal(const std::string &Name) = 0;
+  virtual llvm::GlobalVariable *GetClassGlobal(const std::string &Name,
+                                               bool Weak = false) = 0;
 
   struct MessageSendInfo {
     const CGFunctionInfo &CallInfo;
diff --git a/lib/CodeGen/CGOpenCLRuntime.cpp b/lib/CodeGen/CGOpenCLRuntime.cpp
index 7c454ac..079ef72 100644
--- a/lib/CodeGen/CGOpenCLRuntime.cpp
+++ b/lib/CodeGen/CGOpenCLRuntime.cpp
@@ -33,32 +33,35 @@
   assert(T->isOpenCLSpecificType() &&
          "Not an OpenCL specific type!");
 
+  llvm::LLVMContext& Ctx = CGM.getLLVMContext();
+  uint32_t ImgAddrSpc =
+    CGM.getContext().getTargetAddressSpace(LangAS::opencl_global);
   switch (cast<BuiltinType>(T)->getKind()) {
   default: 
     llvm_unreachable("Unexpected opencl builtin type!");
-    return 0;
+    return nullptr;
   case BuiltinType::OCLImage1d:
     return llvm::PointerType::get(llvm::StructType::create(
-                           CGM.getLLVMContext(), "opencl.image1d_t"), 0);
+                           Ctx, "opencl.image1d_t"), ImgAddrSpc);
   case BuiltinType::OCLImage1dArray:
     return llvm::PointerType::get(llvm::StructType::create(
-                           CGM.getLLVMContext(), "opencl.image1d_array_t"), 0);
+                           Ctx, "opencl.image1d_array_t"), ImgAddrSpc);
   case BuiltinType::OCLImage1dBuffer:
     return llvm::PointerType::get(llvm::StructType::create(
-                           CGM.getLLVMContext(), "opencl.image1d_buffer_t"), 0);
+                           Ctx, "opencl.image1d_buffer_t"), ImgAddrSpc);
   case BuiltinType::OCLImage2d:
     return llvm::PointerType::get(llvm::StructType::create(
-                           CGM.getLLVMContext(), "opencl.image2d_t"), 0);
+                           Ctx, "opencl.image2d_t"), ImgAddrSpc);
   case BuiltinType::OCLImage2dArray:
     return llvm::PointerType::get(llvm::StructType::create(
-                           CGM.getLLVMContext(), "opencl.image2d_array_t"), 0);
+                           Ctx, "opencl.image2d_array_t"), ImgAddrSpc);
   case BuiltinType::OCLImage3d:
     return llvm::PointerType::get(llvm::StructType::create(
-                           CGM.getLLVMContext(), "opencl.image3d_t"), 0);
+                           Ctx, "opencl.image3d_t"), ImgAddrSpc);
   case BuiltinType::OCLSampler:
-    return llvm::IntegerType::get(CGM.getLLVMContext(),32);
+    return llvm::IntegerType::get(Ctx, 32);
   case BuiltinType::OCLEvent:
     return llvm::PointerType::get(llvm::StructType::create(
-                           CGM.getLLVMContext(), "opencl.event_t"), 0);
+                           Ctx, "opencl.event_t"), 0);
   }
 }
diff --git a/lib/CodeGen/CGOpenMPRuntime.cpp b/lib/CodeGen/CGOpenMPRuntime.cpp
new file mode 100644
index 0000000..12a3a77
--- /dev/null
+++ b/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -0,0 +1,182 @@
+//===----- CGOpenMPRuntime.cpp - Interface to OpenMP Runtimes -------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This provides a class for OpenMP runtime code generation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CGOpenMPRuntime.h"
+#include "CodeGenFunction.h"
+#include "clang/AST/Decl.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/Value.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+
+using namespace clang;
+using namespace CodeGen;
+
+CGOpenMPRuntime::CGOpenMPRuntime(CodeGenModule &CGM)
+    : CGM(CGM), DefaultOpenMPPSource(nullptr) {
+  IdentTy = llvm::StructType::create(
+      "ident_t", CGM.Int32Ty /* reserved_1 */, CGM.Int32Ty /* flags */,
+      CGM.Int32Ty /* reserved_2 */, CGM.Int32Ty /* reserved_3 */,
+      CGM.Int8PtrTy /* psource */, NULL);
+  // Build void (*kmpc_micro)(kmp_int32 *global_tid, kmp_int32 *bound_tid,...)
+  llvm::Type *MicroParams[] = {llvm::PointerType::getUnqual(CGM.Int32Ty),
+                               llvm::PointerType::getUnqual(CGM.Int32Ty)};
+  Kmpc_MicroTy = llvm::FunctionType::get(CGM.VoidTy, MicroParams, true);
+}
+
+llvm::Value *
+CGOpenMPRuntime::GetOrCreateDefaultOpenMPLocation(OpenMPLocationFlags Flags) {
+  llvm::Value *Entry = OpenMPDefaultLocMap.lookup(Flags);
+  if (!Entry) {
+    if (!DefaultOpenMPPSource) {
+      // Initialize default location for psource field of ident_t structure of
+      // all ident_t objects. Format is ";file;function;line;column;;".
+      // Taken from
+      // http://llvm.org/svn/llvm-project/openmp/trunk/runtime/src/kmp_str.c
+      DefaultOpenMPPSource =
+          CGM.GetAddrOfConstantCString(";unknown;unknown;0;0;;");
+      DefaultOpenMPPSource =
+          llvm::ConstantExpr::getBitCast(DefaultOpenMPPSource, CGM.Int8PtrTy);
+    }
+    llvm::GlobalVariable *DefaultOpenMPLocation = cast<llvm::GlobalVariable>(
+        CGM.CreateRuntimeVariable(IdentTy, ".kmpc_default_loc.addr"));
+    DefaultOpenMPLocation->setUnnamedAddr(true);
+    DefaultOpenMPLocation->setConstant(true);
+    DefaultOpenMPLocation->setLinkage(llvm::GlobalValue::PrivateLinkage);
+
+    llvm::Constant *Zero = llvm::ConstantInt::get(CGM.Int32Ty, 0, true);
+    llvm::Constant *Values[] = {Zero,
+                                llvm::ConstantInt::get(CGM.Int32Ty, Flags),
+                                Zero, Zero, DefaultOpenMPPSource};
+    llvm::Constant *Init = llvm::ConstantStruct::get(IdentTy, Values);
+    DefaultOpenMPLocation->setInitializer(Init);
+    return DefaultOpenMPLocation;
+  }
+  return Entry;
+}
+
+llvm::Value *CGOpenMPRuntime::EmitOpenMPUpdateLocation(
+    CodeGenFunction &CGF, SourceLocation Loc, OpenMPLocationFlags Flags) {
+  // If no debug info is generated - return global default location.
+  if (CGM.getCodeGenOpts().getDebugInfo() == CodeGenOptions::NoDebugInfo ||
+      Loc.isInvalid())
+    return GetOrCreateDefaultOpenMPLocation(Flags);
+
+  assert(CGF.CurFn && "No function in current CodeGenFunction.");
+
+  llvm::Value *LocValue = nullptr;
+  OpenMPLocMapTy::iterator I = OpenMPLocMap.find(CGF.CurFn);
+  if (I != OpenMPLocMap.end()) {
+    LocValue = I->second;
+  } else {
+    // Generate "ident_t .kmpc_loc.addr;"
+    llvm::AllocaInst *AI = CGF.CreateTempAlloca(IdentTy, ".kmpc_loc.addr");
+    AI->setAlignment(CGM.getDataLayout().getPrefTypeAlignment(IdentTy));
+    OpenMPLocMap[CGF.CurFn] = AI;
+    LocValue = AI;
+
+    CGBuilderTy::InsertPointGuard IPG(CGF.Builder);
+    CGF.Builder.SetInsertPoint(CGF.AllocaInsertPt);
+    CGF.Builder.CreateMemCpy(LocValue, GetOrCreateDefaultOpenMPLocation(Flags),
+                             llvm::ConstantExpr::getSizeOf(IdentTy),
+                             CGM.PointerAlignInBytes);
+  }
+
+  // char **psource = &.kmpc_loc_<flags>.addr.psource;
+  llvm::Value *PSource =
+      CGF.Builder.CreateConstInBoundsGEP2_32(LocValue, 0, IdentField_PSource);
+
+  auto OMPDebugLoc = OpenMPDebugLocMap.lookup(Loc.getRawEncoding());
+  if (OMPDebugLoc == nullptr) {
+    SmallString<128> Buffer2;
+    llvm::raw_svector_ostream OS2(Buffer2);
+    // Build debug location
+    PresumedLoc PLoc = CGF.getContext().getSourceManager().getPresumedLoc(Loc);
+    OS2 << ";" << PLoc.getFilename() << ";";
+    if (const FunctionDecl *FD =
+            dyn_cast_or_null<FunctionDecl>(CGF.CurFuncDecl)) {
+      OS2 << FD->getQualifiedNameAsString();
+    }
+    OS2 << ";" << PLoc.getLine() << ";" << PLoc.getColumn() << ";;";
+    OMPDebugLoc = CGF.Builder.CreateGlobalStringPtr(OS2.str());
+    OpenMPDebugLocMap[Loc.getRawEncoding()] = OMPDebugLoc;
+  }
+  // *psource = ";<File>;<Function>;<Line>;<Column>;;";
+  CGF.Builder.CreateStore(OMPDebugLoc, PSource);
+
+  return LocValue;
+}
+
+llvm::Value *CGOpenMPRuntime::GetOpenMPGlobalThreadNum(CodeGenFunction &CGF,
+                                                       SourceLocation Loc) {
+  assert(CGF.CurFn && "No function in current CodeGenFunction.");
+
+  llvm::Value *GTid = nullptr;
+  OpenMPGtidMapTy::iterator I = OpenMPGtidMap.find(CGF.CurFn);
+  if (I != OpenMPGtidMap.end()) {
+    GTid = I->second;
+  } else {
+    // Generate "int32 .kmpc_global_thread_num.addr;"
+    CGBuilderTy::InsertPointGuard IPG(CGF.Builder);
+    CGF.Builder.SetInsertPoint(CGF.AllocaInsertPt);
+    llvm::Value *Args[] = {EmitOpenMPUpdateLocation(CGF, Loc)};
+    GTid = CGF.EmitRuntimeCall(
+        CreateRuntimeFunction(OMPRTL__kmpc_global_thread_num), Args);
+    OpenMPGtidMap[CGF.CurFn] = GTid;
+  }
+  return GTid;
+}
+
+void CGOpenMPRuntime::FunctionFinished(CodeGenFunction &CGF) {
+  assert(CGF.CurFn && "No function in current CodeGenFunction.");
+  if (OpenMPGtidMap.count(CGF.CurFn))
+    OpenMPGtidMap.erase(CGF.CurFn);
+  if (OpenMPLocMap.count(CGF.CurFn))
+    OpenMPLocMap.erase(CGF.CurFn);
+}
+
+llvm::Type *CGOpenMPRuntime::getIdentTyPointerTy() {
+  return llvm::PointerType::getUnqual(IdentTy);
+}
+
+llvm::Type *CGOpenMPRuntime::getKmpc_MicroPointerTy() {
+  return llvm::PointerType::getUnqual(Kmpc_MicroTy);
+}
+
+llvm::Constant *
+CGOpenMPRuntime::CreateRuntimeFunction(OpenMPRTLFunction Function) {
+  llvm::Constant *RTLFn = nullptr;
+  switch (Function) {
+  case OMPRTL__kmpc_fork_call: {
+    // Build void __kmpc_fork_call(ident_t *loc, kmp_int32 argc, kmpc_micro
+    // microtask, ...);
+    llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
+                                getKmpc_MicroPointerTy()};
+    llvm::FunctionType *FnTy =
+        llvm::FunctionType::get(CGM.VoidTy, TypeParams, true);
+    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_fork_call");
+    break;
+  }
+  case OMPRTL__kmpc_global_thread_num: {
+    // Build kmp_int32 __kmpc_global_thread_num(ident_t *loc);
+    llvm::Type *TypeParams[] = {getIdentTyPointerTy()};
+    llvm::FunctionType *FnTy =
+        llvm::FunctionType::get(CGM.Int32Ty, TypeParams, false);
+    RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_global_thread_num");
+    break;
+  }
+  }
+  return RTLFn;
+}
diff --git a/lib/CodeGen/CGOpenMPRuntime.h b/lib/CodeGen/CGOpenMPRuntime.h
new file mode 100644
index 0000000..862e8a1
--- /dev/null
+++ b/lib/CodeGen/CGOpenMPRuntime.h
@@ -0,0 +1,177 @@
+//===----- CGOpenMPRuntime.h - Interface to OpenMP Runtimes -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This provides a class for OpenMP runtime code generation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_CODEGEN_OPENMPRUNTIME_H
+#define CLANG_CODEGEN_OPENMPRUNTIME_H
+
+#include "clang/AST/Type.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/IR/Type.h"
+#include "llvm/IR/Value.h"
+
+namespace llvm {
+class AllocaInst;
+class CallInst;
+class GlobalVariable;
+class Constant;
+class Function;
+class Module;
+class StructLayout;
+class FunctionType;
+class StructType;
+class Type;
+class Value;
+} // namespace llvm
+
+namespace clang {
+
+namespace CodeGen {
+
+class CodeGenFunction;
+class CodeGenModule;
+
+class CGOpenMPRuntime {
+public:
+  /// \brief Values for bit flags used in the ident_t to describe the fields.
+  /// All enumeric elements are named and described in accordance with the code
+  /// from http://llvm.org/svn/llvm-project/openmp/trunk/runtime/src/kmp.h
+  enum OpenMPLocationFlags {
+    /// \brief Use trampoline for internal microtask.
+    OMP_IDENT_IMD = 0x01,
+    /// \brief Use c-style ident structure.
+    OMP_IDENT_KMPC = 0x02,
+    /// \brief Atomic reduction option for kmpc_reduce.
+    OMP_ATOMIC_REDUCE = 0x10,
+    /// \brief Explicit 'barrier' directive.
+    OMP_IDENT_BARRIER_EXPL = 0x20,
+    /// \brief Implicit barrier in code.
+    OMP_IDENT_BARRIER_IMPL = 0x40,
+    /// \brief Implicit barrier in 'for' directive.
+    OMP_IDENT_BARRIER_IMPL_FOR = 0x40,
+    /// \brief Implicit barrier in 'sections' directive.
+    OMP_IDENT_BARRIER_IMPL_SECTIONS = 0xC0,
+    /// \brief Implicit barrier in 'single' directive.
+    OMP_IDENT_BARRIER_IMPL_SINGLE = 0x140
+  };
+  enum OpenMPRTLFunction {
+    // Call to void __kmpc_fork_call(ident_t *loc, kmp_int32 argc, kmpc_micro
+    // microtask, ...);
+    OMPRTL__kmpc_fork_call,
+    // Call to kmp_int32 kmpc_global_thread_num(ident_t *loc);
+    OMPRTL__kmpc_global_thread_num
+  };
+
+private:
+  CodeGenModule &CGM;
+  /// \brief Default const ident_t object used for initialization of all other
+  /// ident_t objects.
+  llvm::Constant *DefaultOpenMPPSource;
+  /// \brief Map of flags and corrsponding default locations.
+  typedef llvm::DenseMap<unsigned, llvm::Value *> OpenMPDefaultLocMapTy;
+  OpenMPDefaultLocMapTy OpenMPDefaultLocMap;
+  llvm::Value *GetOrCreateDefaultOpenMPLocation(OpenMPLocationFlags Flags);
+  /// \brief Describes ident structure that describes a source location.
+  /// All descriptions are taken from
+  /// http://llvm.org/svn/llvm-project/openmp/trunk/runtime/src/kmp.h
+  /// Original structure:
+  /// typedef struct ident {
+  ///    kmp_int32 reserved_1;   /**<  might be used in Fortran;
+  ///                                  see above  */
+  ///    kmp_int32 flags;        /**<  also f.flags; KMP_IDENT_xxx flags;
+  ///                                  KMP_IDENT_KMPC identifies this union
+  ///                                  member  */
+  ///    kmp_int32 reserved_2;   /**<  not really used in Fortran any more;
+  ///                                  see above */
+  ///#if USE_ITT_BUILD
+  ///                            /*  but currently used for storing
+  ///                                region-specific ITT */
+  ///                            /*  contextual information. */
+  ///#endif /* USE_ITT_BUILD */
+  ///    kmp_int32 reserved_3;   /**< source[4] in Fortran, do not use for
+  ///                                 C++  */
+  ///    char const *psource;    /**< String describing the source location.
+  ///                            The string is composed of semi-colon separated
+  //                             fields which describe the source file,
+  ///                            the function and a pair of line numbers that
+  ///                            delimit the construct.
+  ///                             */
+  /// } ident_t;
+  enum IdentFieldIndex {
+    /// \brief might be used in Fortran
+    IdentField_Reserved_1,
+    /// \brief OMP_IDENT_xxx flags; OMP_IDENT_KMPC identifies this union member.
+    IdentField_Flags,
+    /// \brief Not really used in Fortran any more
+    IdentField_Reserved_2,
+    /// \brief Source[4] in Fortran, do not use for C++
+    IdentField_Reserved_3,
+    /// \brief String describing the source location. The string is composed of
+    /// semi-colon separated fields which describe the source file, the function
+    /// and a pair of line numbers that delimit the construct.
+    IdentField_PSource
+  };
+  llvm::StructType *IdentTy;
+  /// \brief Map for Sourcelocation and OpenMP runtime library debug locations.
+  typedef llvm::DenseMap<unsigned, llvm::Value *> OpenMPDebugLocMapTy;
+  OpenMPDebugLocMapTy OpenMPDebugLocMap;
+  /// \brief The type for a microtask which gets passed to __kmpc_fork_call().
+  /// Original representation is:
+  /// typedef void (kmpc_micro)(kmp_int32 global_tid, kmp_int32 bound_tid,...);
+  llvm::FunctionType *Kmpc_MicroTy;
+  /// \brief Map of local debug location and functions.
+  typedef llvm::DenseMap<llvm::Function *, llvm::Value *> OpenMPLocMapTy;
+  OpenMPLocMapTy OpenMPLocMap;
+  /// \brief Map of local gtid and functions.
+  typedef llvm::DenseMap<llvm::Function *, llvm::Value *> OpenMPGtidMapTy;
+  OpenMPGtidMapTy OpenMPGtidMap;
+
+public:
+  explicit CGOpenMPRuntime(CodeGenModule &CGM);
+  ~CGOpenMPRuntime() {}
+
+  /// \brief Cleans up references to the objects in finished function.
+  /// \param CGF Reference to finished CodeGenFunction.
+  ///
+  void FunctionFinished(CodeGenFunction &CGF);
+
+  /// \brief Emits object of ident_t type with info for source location.
+  /// \param CGF Reference to current CodeGenFunction.
+  /// \param Loc Clang source location.
+  /// \param Flags Flags for OpenMP location.
+  ///
+  llvm::Value *
+  EmitOpenMPUpdateLocation(CodeGenFunction &CGF, SourceLocation Loc,
+                           OpenMPLocationFlags Flags = OMP_IDENT_KMPC);
+
+  /// \brief Generates global thread number value.
+  /// \param CGF Reference to current CodeGenFunction.
+  /// \param Loc Clang source location.
+  ///
+  llvm::Value *GetOpenMPGlobalThreadNum(CodeGenFunction &CGF,
+                                        SourceLocation Loc);
+
+  /// \brief Returns pointer to ident_t type;
+  llvm::Type *getIdentTyPointerTy();
+
+  /// \brief Returns pointer to kmpc_micro type;
+  llvm::Type *getKmpc_MicroPointerTy();
+
+  /// \brief Returns specified OpenMP runtime function.
+  /// \param Function OpenMP runtime function.
+  /// \return Specified function.
+  llvm::Constant *CreateRuntimeFunction(OpenMPRTLFunction Function);
+};
+} // namespace CodeGen
+} // namespace clang
+
+#endif
diff --git a/lib/CodeGen/CGRTTI.cpp b/lib/CodeGen/CGRTTI.cpp
deleted file mode 100644
index aa687b9..0000000
--- a/lib/CodeGen/CGRTTI.cpp
+++ /dev/null
@@ -1,977 +0,0 @@
-//===--- CGCXXRTTI.cpp - Emit LLVM Code for C++ RTTI descriptors ----------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This contains code dealing with C++ code generation of RTTI descriptors.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CodeGenModule.h"
-#include "CGCXXABI.h"
-#include "CGObjCRuntime.h"
-#include "clang/AST/RecordLayout.h"
-#include "clang/AST/Type.h"
-#include "clang/Frontend/CodeGenOptions.h"
-
-using namespace clang;
-using namespace CodeGen;
-
-namespace {
-class RTTIBuilder {
-  CodeGenModule &CGM;  // Per-module state.
-  llvm::LLVMContext &VMContext;
-  
-  /// Fields - The fields of the RTTI descriptor currently being built.
-  SmallVector<llvm::Constant *, 16> Fields;
-
-  /// GetAddrOfTypeName - Returns the mangled type name of the given type.
-  llvm::GlobalVariable *
-  GetAddrOfTypeName(QualType Ty, llvm::GlobalVariable::LinkageTypes Linkage);
-
-  /// GetAddrOfExternalRTTIDescriptor - Returns the constant for the RTTI 
-  /// descriptor of the given type.
-  llvm::Constant *GetAddrOfExternalRTTIDescriptor(QualType Ty);
-  
-  /// BuildVTablePointer - Build the vtable pointer for the given type.
-  void BuildVTablePointer(const Type *Ty);
-  
-  /// BuildSIClassTypeInfo - Build an abi::__si_class_type_info, used for single
-  /// inheritance, according to the Itanium C++ ABI, 2.9.5p6b.
-  void BuildSIClassTypeInfo(const CXXRecordDecl *RD);
-  
-  /// BuildVMIClassTypeInfo - Build an abi::__vmi_class_type_info, used for
-  /// classes with bases that do not satisfy the abi::__si_class_type_info 
-  /// constraints, according ti the Itanium C++ ABI, 2.9.5p5c.
-  void BuildVMIClassTypeInfo(const CXXRecordDecl *RD);
-  
-  /// BuildPointerTypeInfo - Build an abi::__pointer_type_info struct, used
-  /// for pointer types.
-  void BuildPointerTypeInfo(QualType PointeeTy);
-
-  /// BuildObjCObjectTypeInfo - Build the appropriate kind of
-  /// type_info for an object type.
-  void BuildObjCObjectTypeInfo(const ObjCObjectType *Ty);
-  
-  /// BuildPointerToMemberTypeInfo - Build an abi::__pointer_to_member_type_info 
-  /// struct, used for member pointer types.
-  void BuildPointerToMemberTypeInfo(const MemberPointerType *Ty);
-  
-public:
-  RTTIBuilder(CodeGenModule &CGM) : CGM(CGM), 
-    VMContext(CGM.getModule().getContext()) { }
-
-  // Pointer type info flags.
-  enum {
-    /// PTI_Const - Type has const qualifier.
-    PTI_Const = 0x1,
-    
-    /// PTI_Volatile - Type has volatile qualifier.
-    PTI_Volatile = 0x2,
-    
-    /// PTI_Restrict - Type has restrict qualifier.
-    PTI_Restrict = 0x4,
-    
-    /// PTI_Incomplete - Type is incomplete.
-    PTI_Incomplete = 0x8,
-    
-    /// PTI_ContainingClassIncomplete - Containing class is incomplete.
-    /// (in pointer to member).
-    PTI_ContainingClassIncomplete = 0x10
-  };
-  
-  // VMI type info flags.
-  enum {
-    /// VMI_NonDiamondRepeat - Class has non-diamond repeated inheritance.
-    VMI_NonDiamondRepeat = 0x1,
-    
-    /// VMI_DiamondShaped - Class is diamond shaped.
-    VMI_DiamondShaped = 0x2
-  };
-  
-  // Base class type info flags.
-  enum {
-    /// BCTI_Virtual - Base class is virtual.
-    BCTI_Virtual = 0x1,
-    
-    /// BCTI_Public - Base class is public.
-    BCTI_Public = 0x2
-  };
-  
-  /// BuildTypeInfo - Build the RTTI type info struct for the given type.
-  ///
-  /// \param Force - true to force the creation of this RTTI value
-  llvm::Constant *BuildTypeInfo(QualType Ty, bool Force = false);
-};
-}
-
-llvm::GlobalVariable *
-RTTIBuilder::GetAddrOfTypeName(QualType Ty, 
-                               llvm::GlobalVariable::LinkageTypes Linkage) {
-  SmallString<256> OutName;
-  llvm::raw_svector_ostream Out(OutName);
-  CGM.getCXXABI().getMangleContext().mangleCXXRTTIName(Ty, Out);
-  Out.flush();
-  StringRef Name = OutName.str();
-
-  // We know that the mangled name of the type starts at index 4 of the
-  // mangled name of the typename, so we can just index into it in order to
-  // get the mangled name of the type.
-  llvm::Constant *Init = llvm::ConstantDataArray::getString(VMContext,
-                                                            Name.substr(4));
-
-  llvm::GlobalVariable *GV = 
-    CGM.CreateOrReplaceCXXRuntimeVariable(Name, Init->getType(), Linkage);
-
-  GV->setInitializer(Init);
-
-  return GV;
-}
-
-llvm::Constant *RTTIBuilder::GetAddrOfExternalRTTIDescriptor(QualType Ty) {
-  // Mangle the RTTI name.
-  SmallString<256> OutName;
-  llvm::raw_svector_ostream Out(OutName);
-  CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty, Out);
-  Out.flush();
-  StringRef Name = OutName.str();
-
-  // Look for an existing global.
-  llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(Name);
-  
-  if (!GV) {
-    // Create a new global variable.
-    GV = new llvm::GlobalVariable(CGM.getModule(), CGM.Int8PtrTy,
-                                  /*Constant=*/true,
-                                  llvm::GlobalValue::ExternalLinkage, 0, Name);
-  }
-  
-  return llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy);
-}
-
-/// TypeInfoIsInStandardLibrary - Given a builtin type, returns whether the type
-/// info for that type is defined in the standard library.
-static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty) {
-  // Itanium C++ ABI 2.9.2:
-  //   Basic type information (e.g. for "int", "bool", etc.) will be kept in
-  //   the run-time support library. Specifically, the run-time support
-  //   library should contain type_info objects for the types X, X* and 
-  //   X const*, for every X in: void, std::nullptr_t, bool, wchar_t, char,
-  //   unsigned char, signed char, short, unsigned short, int, unsigned int,
-  //   long, unsigned long, long long, unsigned long long, float, double,
-  //   long double, char16_t, char32_t, and the IEEE 754r decimal and 
-  //   half-precision floating point types.
-  switch (Ty->getKind()) {
-    case BuiltinType::Void:
-    case BuiltinType::NullPtr:
-    case BuiltinType::Bool:
-    case BuiltinType::WChar_S:
-    case BuiltinType::WChar_U:
-    case BuiltinType::Char_U:
-    case BuiltinType::Char_S:
-    case BuiltinType::UChar:
-    case BuiltinType::SChar:
-    case BuiltinType::Short:
-    case BuiltinType::UShort:
-    case BuiltinType::Int:
-    case BuiltinType::UInt:
-    case BuiltinType::Long:
-    case BuiltinType::ULong:
-    case BuiltinType::LongLong:
-    case BuiltinType::ULongLong:
-    case BuiltinType::Half:
-    case BuiltinType::Float:
-    case BuiltinType::Double:
-    case BuiltinType::LongDouble:
-    case BuiltinType::Char16:
-    case BuiltinType::Char32:
-    case BuiltinType::Int128:
-    case BuiltinType::UInt128:
-    case BuiltinType::OCLImage1d:
-    case BuiltinType::OCLImage1dArray:
-    case BuiltinType::OCLImage1dBuffer:
-    case BuiltinType::OCLImage2d:
-    case BuiltinType::OCLImage2dArray:
-    case BuiltinType::OCLImage3d:
-    case BuiltinType::OCLSampler:
-    case BuiltinType::OCLEvent:
-      return true;
-      
-    case BuiltinType::Dependent:
-#define BUILTIN_TYPE(Id, SingletonId)
-#define PLACEHOLDER_TYPE(Id, SingletonId) \
-    case BuiltinType::Id:
-#include "clang/AST/BuiltinTypes.def"
-      llvm_unreachable("asking for RRTI for a placeholder type!");
-      
-    case BuiltinType::ObjCId:
-    case BuiltinType::ObjCClass:
-    case BuiltinType::ObjCSel:
-      llvm_unreachable("FIXME: Objective-C types are unsupported!");
-  }
-
-  llvm_unreachable("Invalid BuiltinType Kind!");
-}
-
-static bool TypeInfoIsInStandardLibrary(const PointerType *PointerTy) {
-  QualType PointeeTy = PointerTy->getPointeeType();
-  const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(PointeeTy);
-  if (!BuiltinTy)
-    return false;
-    
-  // Check the qualifiers.
-  Qualifiers Quals = PointeeTy.getQualifiers();
-  Quals.removeConst();
-    
-  if (!Quals.empty())
-    return false;
-    
-  return TypeInfoIsInStandardLibrary(BuiltinTy);
-}
-
-/// IsStandardLibraryRTTIDescriptor - Returns whether the type
-/// information for the given type exists in the standard library.
-static bool IsStandardLibraryRTTIDescriptor(QualType Ty) {
-  // Type info for builtin types is defined in the standard library.
-  if (const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))
-    return TypeInfoIsInStandardLibrary(BuiltinTy);
-  
-  // Type info for some pointer types to builtin types is defined in the
-  // standard library.
-  if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
-    return TypeInfoIsInStandardLibrary(PointerTy);
-
-  return false;
-}
-
-/// ShouldUseExternalRTTIDescriptor - Returns whether the type information for
-/// the given type exists somewhere else, and that we should not emit the type
-/// information in this translation unit.  Assumes that it is not a
-/// standard-library type.
-static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM,
-                                            QualType Ty) {
-  ASTContext &Context = CGM.getContext();
-
-  // If RTTI is disabled, assume it might be disabled in the
-  // translation unit that defines any potential key function, too.
-  if (!Context.getLangOpts().RTTI) return false;
-
-  if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
-    const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
-    if (!RD->hasDefinition())
-      return false;
-
-    if (!RD->isDynamicClass())
-      return false;
-
-    // FIXME: this may need to be reconsidered if the key function
-    // changes.
-    return CGM.getVTables().isVTableExternal(RD);
-  }
-  
-  return false;
-}
-
-/// IsIncompleteClassType - Returns whether the given record type is incomplete.
-static bool IsIncompleteClassType(const RecordType *RecordTy) {
-  return !RecordTy->getDecl()->isCompleteDefinition();
-}  
-
-/// ContainsIncompleteClassType - Returns whether the given type contains an
-/// incomplete class type. This is true if
-///
-///   * The given type is an incomplete class type.
-///   * The given type is a pointer type whose pointee type contains an 
-///     incomplete class type.
-///   * The given type is a member pointer type whose class is an incomplete
-///     class type.
-///   * The given type is a member pointer type whoise pointee type contains an
-///     incomplete class type.
-/// is an indirect or direct pointer to an incomplete class type.
-static bool ContainsIncompleteClassType(QualType Ty) {
-  if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
-    if (IsIncompleteClassType(RecordTy))
-      return true;
-  }
-  
-  if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
-    return ContainsIncompleteClassType(PointerTy->getPointeeType());
-  
-  if (const MemberPointerType *MemberPointerTy = 
-      dyn_cast<MemberPointerType>(Ty)) {
-    // Check if the class type is incomplete.
-    const RecordType *ClassType = cast<RecordType>(MemberPointerTy->getClass());
-    if (IsIncompleteClassType(ClassType))
-      return true;
-    
-    return ContainsIncompleteClassType(MemberPointerTy->getPointeeType());
-  }
-  
-  return false;
-}
-
-/// getTypeInfoLinkage - Return the linkage that the type info and type info
-/// name constants should have for the given type.
-static llvm::GlobalVariable::LinkageTypes 
-getTypeInfoLinkage(CodeGenModule &CGM, QualType Ty) {
-  // Itanium C++ ABI 2.9.5p7:
-  //   In addition, it and all of the intermediate abi::__pointer_type_info 
-  //   structs in the chain down to the abi::__class_type_info for the
-  //   incomplete class type must be prevented from resolving to the 
-  //   corresponding type_info structs for the complete class type, possibly
-  //   by making them local static objects. Finally, a dummy class RTTI is
-  //   generated for the incomplete type that will not resolve to the final 
-  //   complete class RTTI (because the latter need not exist), possibly by 
-  //   making it a local static object.
-  if (ContainsIncompleteClassType(Ty))
-    return llvm::GlobalValue::InternalLinkage;
-  
-  switch (Ty->getLinkage()) {
-  case NoLinkage:
-  case VisibleNoLinkage:
-  case InternalLinkage:
-  case UniqueExternalLinkage:
-    return llvm::GlobalValue::InternalLinkage;
-
-  case ExternalLinkage:
-    if (!CGM.getLangOpts().RTTI) {
-      // RTTI is not enabled, which means that this type info struct is going
-      // to be used for exception handling. Give it linkonce_odr linkage.
-      return llvm::GlobalValue::LinkOnceODRLinkage;
-    }
-
-    if (const RecordType *Record = dyn_cast<RecordType>(Ty)) {
-      const CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
-      if (RD->hasAttr<WeakAttr>())
-        return llvm::GlobalValue::WeakODRLinkage;
-      if (RD->isDynamicClass())
-        return CGM.getVTableLinkage(RD);
-    }
-
-    return llvm::GlobalValue::LinkOnceODRLinkage;
-  }
-
-  llvm_unreachable("Invalid linkage!");
-}
-
-// CanUseSingleInheritance - Return whether the given record decl has a "single, 
-// public, non-virtual base at offset zero (i.e. the derived class is dynamic 
-// iff the base is)", according to Itanium C++ ABI, 2.95p6b.
-static bool CanUseSingleInheritance(const CXXRecordDecl *RD) {
-  // Check the number of bases.
-  if (RD->getNumBases() != 1)
-    return false;
-  
-  // Get the base.
-  CXXRecordDecl::base_class_const_iterator Base = RD->bases_begin();
-  
-  // Check that the base is not virtual.
-  if (Base->isVirtual())
-    return false;
-  
-  // Check that the base is public.
-  if (Base->getAccessSpecifier() != AS_public)
-    return false;
-  
-  // Check that the class is dynamic iff the base is.
-  const CXXRecordDecl *BaseDecl = 
-    cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
-  if (!BaseDecl->isEmpty() && 
-      BaseDecl->isDynamicClass() != RD->isDynamicClass())
-    return false;
-  
-  return true;
-}
-
-void RTTIBuilder::BuildVTablePointer(const Type *Ty) {
-  // abi::__class_type_info.
-  static const char * const ClassTypeInfo =
-    "_ZTVN10__cxxabiv117__class_type_infoE";
-  // abi::__si_class_type_info.
-  static const char * const SIClassTypeInfo =
-    "_ZTVN10__cxxabiv120__si_class_type_infoE";
-  // abi::__vmi_class_type_info.
-  static const char * const VMIClassTypeInfo =
-    "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
-
-  const char *VTableName = 0;
-
-  switch (Ty->getTypeClass()) {
-#define TYPE(Class, Base)
-#define ABSTRACT_TYPE(Class, Base)
-#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
-#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
-#define DEPENDENT_TYPE(Class, Base) case Type::Class:
-#include "clang/AST/TypeNodes.def"
-    llvm_unreachable("Non-canonical and dependent types shouldn't get here");
-
-  case Type::LValueReference:
-  case Type::RValueReference:
-    llvm_unreachable("References shouldn't get here");
-
-  case Type::Auto:
-    llvm_unreachable("Undeduced auto type shouldn't get here");
-
-  case Type::Builtin:
-  // GCC treats vector and complex types as fundamental types.
-  case Type::Vector:
-  case Type::ExtVector:
-  case Type::Complex:
-  case Type::Atomic:
-  // FIXME: GCC treats block pointers as fundamental types?!
-  case Type::BlockPointer:
-    // abi::__fundamental_type_info.
-    VTableName = "_ZTVN10__cxxabiv123__fundamental_type_infoE";
-    break;
-
-  case Type::ConstantArray:
-  case Type::IncompleteArray:
-  case Type::VariableArray:
-    // abi::__array_type_info.
-    VTableName = "_ZTVN10__cxxabiv117__array_type_infoE";
-    break;
-
-  case Type::FunctionNoProto:
-  case Type::FunctionProto:
-    // abi::__function_type_info.
-    VTableName = "_ZTVN10__cxxabiv120__function_type_infoE";
-    break;
-
-  case Type::Enum:
-    // abi::__enum_type_info.
-    VTableName = "_ZTVN10__cxxabiv116__enum_type_infoE";
-    break;
-
-  case Type::Record: {
-    const CXXRecordDecl *RD = 
-      cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
-    
-    if (!RD->hasDefinition() || !RD->getNumBases()) {
-      VTableName = ClassTypeInfo;
-    } else if (CanUseSingleInheritance(RD)) {
-      VTableName = SIClassTypeInfo;
-    } else {
-      VTableName = VMIClassTypeInfo;
-    }
-    
-    break;
-  }
-
-  case Type::ObjCObject:
-    // Ignore protocol qualifiers.
-    Ty = cast<ObjCObjectType>(Ty)->getBaseType().getTypePtr();
-
-    // Handle id and Class.
-    if (isa<BuiltinType>(Ty)) {
-      VTableName = ClassTypeInfo;
-      break;
-    }
-
-    assert(isa<ObjCInterfaceType>(Ty));
-    // Fall through.
-
-  case Type::ObjCInterface:
-    if (cast<ObjCInterfaceType>(Ty)->getDecl()->getSuperClass()) {
-      VTableName = SIClassTypeInfo;
-    } else {
-      VTableName = ClassTypeInfo;
-    }
-    break;
-
-  case Type::ObjCObjectPointer:
-  case Type::Pointer:
-    // abi::__pointer_type_info.
-    VTableName = "_ZTVN10__cxxabiv119__pointer_type_infoE";
-    break;
-
-  case Type::MemberPointer:
-    // abi::__pointer_to_member_type_info.
-    VTableName = "_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
-    break;
-  }
-
-  llvm::Constant *VTable = 
-    CGM.getModule().getOrInsertGlobal(VTableName, CGM.Int8PtrTy);
-    
-  llvm::Type *PtrDiffTy = 
-    CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType());
-
-  // The vtable address point is 2.
-  llvm::Constant *Two = llvm::ConstantInt::get(PtrDiffTy, 2);
-  VTable = llvm::ConstantExpr::getInBoundsGetElementPtr(VTable, Two);
-  VTable = llvm::ConstantExpr::getBitCast(VTable, CGM.Int8PtrTy);
-
-  Fields.push_back(VTable);
-}
-
-llvm::Constant *RTTIBuilder::BuildTypeInfo(QualType Ty, bool Force) {
-  // We want to operate on the canonical type.
-  Ty = CGM.getContext().getCanonicalType(Ty);
-
-  // Check if we've already emitted an RTTI descriptor for this type.
-  SmallString<256> OutName;
-  llvm::raw_svector_ostream Out(OutName);
-  CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty, Out);
-  Out.flush();
-  StringRef Name = OutName.str();
-
-  llvm::GlobalVariable *OldGV = CGM.getModule().getNamedGlobal(Name);
-  if (OldGV && !OldGV->isDeclaration()) {
-    assert(!OldGV->hasAvailableExternallyLinkage() &&
-           "available_externally typeinfos not yet implemented");
-
-    return llvm::ConstantExpr::getBitCast(OldGV, CGM.Int8PtrTy);
-  }
-
-  // Check if there is already an external RTTI descriptor for this type.
-  bool IsStdLib = IsStandardLibraryRTTIDescriptor(Ty);
-  if (!Force && (IsStdLib || ShouldUseExternalRTTIDescriptor(CGM, Ty)))
-    return GetAddrOfExternalRTTIDescriptor(Ty);
-
-  // Emit the standard library with external linkage.
-  llvm::GlobalVariable::LinkageTypes Linkage;
-  if (IsStdLib)
-    Linkage = llvm::GlobalValue::ExternalLinkage;
-  else
-    Linkage = getTypeInfoLinkage(CGM, Ty);
-
-  // Add the vtable pointer.
-  BuildVTablePointer(cast<Type>(Ty));
-  
-  // And the name.
-  llvm::GlobalVariable *TypeName = GetAddrOfTypeName(Ty, Linkage);
-
-  Fields.push_back(llvm::ConstantExpr::getBitCast(TypeName, CGM.Int8PtrTy));
-
-  switch (Ty->getTypeClass()) {
-#define TYPE(Class, Base)
-#define ABSTRACT_TYPE(Class, Base)
-#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
-#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
-#define DEPENDENT_TYPE(Class, Base) case Type::Class:
-#include "clang/AST/TypeNodes.def"
-    llvm_unreachable("Non-canonical and dependent types shouldn't get here");
-
-  // GCC treats vector types as fundamental types.
-  case Type::Builtin:
-  case Type::Vector:
-  case Type::ExtVector:
-  case Type::Complex:
-  case Type::BlockPointer:
-    // Itanium C++ ABI 2.9.5p4:
-    // abi::__fundamental_type_info adds no data members to std::type_info.
-    break;
-
-  case Type::LValueReference:
-  case Type::RValueReference:
-    llvm_unreachable("References shouldn't get here");
-
-  case Type::Auto:
-    llvm_unreachable("Undeduced auto type shouldn't get here");
-
-  case Type::ConstantArray:
-  case Type::IncompleteArray:
-  case Type::VariableArray:
-    // Itanium C++ ABI 2.9.5p5:
-    // abi::__array_type_info adds no data members to std::type_info.
-    break;
-
-  case Type::FunctionNoProto:
-  case Type::FunctionProto:
-    // Itanium C++ ABI 2.9.5p5:
-    // abi::__function_type_info adds no data members to std::type_info.
-    break;
-
-  case Type::Enum:
-    // Itanium C++ ABI 2.9.5p5:
-    // abi::__enum_type_info adds no data members to std::type_info.
-    break;
-
-  case Type::Record: {
-    const CXXRecordDecl *RD = 
-      cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
-    if (!RD->hasDefinition() || !RD->getNumBases()) {
-      // We don't need to emit any fields.
-      break;
-    }
-    
-    if (CanUseSingleInheritance(RD))
-      BuildSIClassTypeInfo(RD);
-    else 
-      BuildVMIClassTypeInfo(RD);
-
-    break;
-  }
-
-  case Type::ObjCObject:
-  case Type::ObjCInterface:
-    BuildObjCObjectTypeInfo(cast<ObjCObjectType>(Ty));
-    break;
-
-  case Type::ObjCObjectPointer:
-    BuildPointerTypeInfo(cast<ObjCObjectPointerType>(Ty)->getPointeeType());
-    break; 
-      
-  case Type::Pointer:
-    BuildPointerTypeInfo(cast<PointerType>(Ty)->getPointeeType());
-    break;
-
-  case Type::MemberPointer:
-    BuildPointerToMemberTypeInfo(cast<MemberPointerType>(Ty));
-    break;
-
-  case Type::Atomic:
-    // No fields, at least for the moment.
-    break;
-  }
-
-  llvm::Constant *Init = llvm::ConstantStruct::getAnon(Fields);
-
-  llvm::GlobalVariable *GV = 
-    new llvm::GlobalVariable(CGM.getModule(), Init->getType(), 
-                             /*Constant=*/true, Linkage, Init, Name);
-  
-  // If there's already an old global variable, replace it with the new one.
-  if (OldGV) {
-    GV->takeName(OldGV);
-    llvm::Constant *NewPtr = 
-      llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
-    OldGV->replaceAllUsesWith(NewPtr);
-    OldGV->eraseFromParent();
-  }
-
-  // GCC only relies on the uniqueness of the type names, not the
-  // type_infos themselves, so we can emit these as hidden symbols.
-  // But don't do this if we're worried about strict visibility
-  // compatibility.
-  if (const RecordType *RT = dyn_cast<RecordType>(Ty)) {
-    const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
-
-    CGM.setTypeVisibility(GV, RD, CodeGenModule::TVK_ForRTTI);
-    CGM.setTypeVisibility(TypeName, RD, CodeGenModule::TVK_ForRTTIName);
-  } else {
-    Visibility TypeInfoVisibility = DefaultVisibility;
-    if (CGM.getCodeGenOpts().HiddenWeakVTables &&
-        Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
-      TypeInfoVisibility = HiddenVisibility;
-
-    // The type name should have the same visibility as the type itself.
-    Visibility ExplicitVisibility = Ty->getVisibility();
-    TypeName->setVisibility(CodeGenModule::
-                            GetLLVMVisibility(ExplicitVisibility));
-  
-    TypeInfoVisibility = minVisibility(TypeInfoVisibility, Ty->getVisibility());
-    GV->setVisibility(CodeGenModule::GetLLVMVisibility(TypeInfoVisibility));
-  }
-
-  GV->setUnnamedAddr(true);
-
-  return llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy);
-}
-
-/// ComputeQualifierFlags - Compute the pointer type info flags from the
-/// given qualifier.
-static unsigned ComputeQualifierFlags(Qualifiers Quals) {
-  unsigned Flags = 0;
-
-  if (Quals.hasConst())
-    Flags |= RTTIBuilder::PTI_Const;
-  if (Quals.hasVolatile())
-    Flags |= RTTIBuilder::PTI_Volatile;
-  if (Quals.hasRestrict())
-    Flags |= RTTIBuilder::PTI_Restrict;
-
-  return Flags;
-}
-
-/// BuildObjCObjectTypeInfo - Build the appropriate kind of type_info
-/// for the given Objective-C object type.
-void RTTIBuilder::BuildObjCObjectTypeInfo(const ObjCObjectType *OT) {
-  // Drop qualifiers.
-  const Type *T = OT->getBaseType().getTypePtr();
-  assert(isa<BuiltinType>(T) || isa<ObjCInterfaceType>(T));
-
-  // The builtin types are abi::__class_type_infos and don't require
-  // extra fields.
-  if (isa<BuiltinType>(T)) return;
-
-  ObjCInterfaceDecl *Class = cast<ObjCInterfaceType>(T)->getDecl();
-  ObjCInterfaceDecl *Super = Class->getSuperClass();
-
-  // Root classes are also __class_type_info.
-  if (!Super) return;
-
-  QualType SuperTy = CGM.getContext().getObjCInterfaceType(Super);
-
-  // Everything else is single inheritance.
-  llvm::Constant *BaseTypeInfo = RTTIBuilder(CGM).BuildTypeInfo(SuperTy);
-  Fields.push_back(BaseTypeInfo);
-}
-
-/// BuildSIClassTypeInfo - Build an abi::__si_class_type_info, used for single
-/// inheritance, according to the Itanium C++ ABI, 2.95p6b.
-void RTTIBuilder::BuildSIClassTypeInfo(const CXXRecordDecl *RD) {
-  // Itanium C++ ABI 2.9.5p6b:
-  // It adds to abi::__class_type_info a single member pointing to the 
-  // type_info structure for the base type,
-  llvm::Constant *BaseTypeInfo = 
-    RTTIBuilder(CGM).BuildTypeInfo(RD->bases_begin()->getType());
-  Fields.push_back(BaseTypeInfo);
-}
-
-namespace {
-  /// SeenBases - Contains virtual and non-virtual bases seen when traversing
-  /// a class hierarchy.
-  struct SeenBases {
-    llvm::SmallPtrSet<const CXXRecordDecl *, 16> NonVirtualBases;
-    llvm::SmallPtrSet<const CXXRecordDecl *, 16> VirtualBases;
-  };
-}
-
-/// ComputeVMIClassTypeInfoFlags - Compute the value of the flags member in
-/// abi::__vmi_class_type_info.
-///
-static unsigned ComputeVMIClassTypeInfoFlags(const CXXBaseSpecifier *Base, 
-                                             SeenBases &Bases) {
-  
-  unsigned Flags = 0;
-  
-  const CXXRecordDecl *BaseDecl = 
-    cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
-  
-  if (Base->isVirtual()) {
-    // Mark the virtual base as seen.
-    if (!Bases.VirtualBases.insert(BaseDecl)) {
-      // If this virtual base has been seen before, then the class is diamond
-      // shaped.
-      Flags |= RTTIBuilder::VMI_DiamondShaped;
-    } else {
-      if (Bases.NonVirtualBases.count(BaseDecl))
-        Flags |= RTTIBuilder::VMI_NonDiamondRepeat;
-    }
-  } else {
-    // Mark the non-virtual base as seen.
-    if (!Bases.NonVirtualBases.insert(BaseDecl)) {
-      // If this non-virtual base has been seen before, then the class has non-
-      // diamond shaped repeated inheritance.
-      Flags |= RTTIBuilder::VMI_NonDiamondRepeat;
-    } else {
-      if (Bases.VirtualBases.count(BaseDecl))
-        Flags |= RTTIBuilder::VMI_NonDiamondRepeat;
-    }
-  }
-
-  // Walk all bases.
-  for (CXXRecordDecl::base_class_const_iterator I = BaseDecl->bases_begin(),
-       E = BaseDecl->bases_end(); I != E; ++I) 
-    Flags |= ComputeVMIClassTypeInfoFlags(I, Bases);
-  
-  return Flags;
-}
-
-static unsigned ComputeVMIClassTypeInfoFlags(const CXXRecordDecl *RD) {
-  unsigned Flags = 0;
-  SeenBases Bases;
-  
-  // Walk all bases.
-  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
-       E = RD->bases_end(); I != E; ++I) 
-    Flags |= ComputeVMIClassTypeInfoFlags(I, Bases);
-  
-  return Flags;
-}
-
-/// BuildVMIClassTypeInfo - Build an abi::__vmi_class_type_info, used for
-/// classes with bases that do not satisfy the abi::__si_class_type_info 
-/// constraints, according ti the Itanium C++ ABI, 2.9.5p5c.
-void RTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) {
-  llvm::Type *UnsignedIntLTy = 
-    CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
-  
-  // Itanium C++ ABI 2.9.5p6c:
-  //   __flags is a word with flags describing details about the class 
-  //   structure, which may be referenced by using the __flags_masks 
-  //   enumeration. These flags refer to both direct and indirect bases. 
-  unsigned Flags = ComputeVMIClassTypeInfoFlags(RD);
-  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
-
-  // Itanium C++ ABI 2.9.5p6c:
-  //   __base_count is a word with the number of direct proper base class 
-  //   descriptions that follow.
-  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, RD->getNumBases()));
-  
-  if (!RD->getNumBases())
-    return;
-  
-  llvm::Type *LongLTy = 
-    CGM.getTypes().ConvertType(CGM.getContext().LongTy);
-
-  // Now add the base class descriptions.
-  
-  // Itanium C++ ABI 2.9.5p6c:
-  //   __base_info[] is an array of base class descriptions -- one for every 
-  //   direct proper base. Each description is of the type:
-  //
-  //   struct abi::__base_class_type_info {
-  //   public:
-  //     const __class_type_info *__base_type;
-  //     long __offset_flags;
-  //
-  //     enum __offset_flags_masks {
-  //       __virtual_mask = 0x1,
-  //       __public_mask = 0x2,
-  //       __offset_shift = 8
-  //     };
-  //   };
-  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
-       E = RD->bases_end(); I != E; ++I) {
-    const CXXBaseSpecifier *Base = I;
-
-    // The __base_type member points to the RTTI for the base type.
-    Fields.push_back(RTTIBuilder(CGM).BuildTypeInfo(Base->getType()));
-
-    const CXXRecordDecl *BaseDecl = 
-      cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
-
-    int64_t OffsetFlags = 0;
-    
-    // All but the lower 8 bits of __offset_flags are a signed offset. 
-    // For a non-virtual base, this is the offset in the object of the base
-    // subobject. For a virtual base, this is the offset in the virtual table of
-    // the virtual base offset for the virtual base referenced (negative).
-    CharUnits Offset;
-    if (Base->isVirtual())
-      Offset = 
-        CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(RD, BaseDecl);
-    else {
-      const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
-      Offset = Layout.getBaseClassOffset(BaseDecl);
-    };
-    
-    OffsetFlags = uint64_t(Offset.getQuantity()) << 8;
-    
-    // The low-order byte of __offset_flags contains flags, as given by the 
-    // masks from the enumeration __offset_flags_masks.
-    if (Base->isVirtual())
-      OffsetFlags |= BCTI_Virtual;
-    if (Base->getAccessSpecifier() == AS_public)
-      OffsetFlags |= BCTI_Public;
-
-    Fields.push_back(llvm::ConstantInt::get(LongLTy, OffsetFlags));
-  }
-}
-
-/// BuildPointerTypeInfo - Build an abi::__pointer_type_info struct,
-/// used for pointer types.
-void RTTIBuilder::BuildPointerTypeInfo(QualType PointeeTy) {  
-  Qualifiers Quals;
-  QualType UnqualifiedPointeeTy = 
-    CGM.getContext().getUnqualifiedArrayType(PointeeTy, Quals);
-  
-  // Itanium C++ ABI 2.9.5p7:
-  //   __flags is a flag word describing the cv-qualification and other 
-  //   attributes of the type pointed to
-  unsigned Flags = ComputeQualifierFlags(Quals);
-
-  // Itanium C++ ABI 2.9.5p7:
-  //   When the abi::__pbase_type_info is for a direct or indirect pointer to an
-  //   incomplete class type, the incomplete target type flag is set. 
-  if (ContainsIncompleteClassType(UnqualifiedPointeeTy))
-    Flags |= PTI_Incomplete;
-
-  llvm::Type *UnsignedIntLTy = 
-    CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
-  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
-  
-  // Itanium C++ ABI 2.9.5p7:
-  //  __pointee is a pointer to the std::type_info derivation for the 
-  //  unqualified type being pointed to.
-  llvm::Constant *PointeeTypeInfo = 
-    RTTIBuilder(CGM).BuildTypeInfo(UnqualifiedPointeeTy);
-  Fields.push_back(PointeeTypeInfo);
-}
-
-/// BuildPointerToMemberTypeInfo - Build an abi::__pointer_to_member_type_info 
-/// struct, used for member pointer types.
-void RTTIBuilder::BuildPointerToMemberTypeInfo(const MemberPointerType *Ty) {
-  QualType PointeeTy = Ty->getPointeeType();
-  
-  Qualifiers Quals;
-  QualType UnqualifiedPointeeTy = 
-    CGM.getContext().getUnqualifiedArrayType(PointeeTy, Quals);
-  
-  // Itanium C++ ABI 2.9.5p7:
-  //   __flags is a flag word describing the cv-qualification and other 
-  //   attributes of the type pointed to.
-  unsigned Flags = ComputeQualifierFlags(Quals);
-
-  const RecordType *ClassType = cast<RecordType>(Ty->getClass());
-
-  // Itanium C++ ABI 2.9.5p7:
-  //   When the abi::__pbase_type_info is for a direct or indirect pointer to an
-  //   incomplete class type, the incomplete target type flag is set. 
-  if (ContainsIncompleteClassType(UnqualifiedPointeeTy))
-    Flags |= PTI_Incomplete;
-
-  if (IsIncompleteClassType(ClassType))
-    Flags |= PTI_ContainingClassIncomplete;
-  
-  llvm::Type *UnsignedIntLTy = 
-    CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
-  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
-  
-  // Itanium C++ ABI 2.9.5p7:
-  //   __pointee is a pointer to the std::type_info derivation for the 
-  //   unqualified type being pointed to.
-  llvm::Constant *PointeeTypeInfo = 
-    RTTIBuilder(CGM).BuildTypeInfo(UnqualifiedPointeeTy);
-  Fields.push_back(PointeeTypeInfo);
-
-  // Itanium C++ ABI 2.9.5p9:
-  //   __context is a pointer to an abi::__class_type_info corresponding to the
-  //   class type containing the member pointed to 
-  //   (e.g., the "A" in "int A::*").
-  Fields.push_back(RTTIBuilder(CGM).BuildTypeInfo(QualType(ClassType, 0)));
-}
-
-llvm::Constant *CodeGenModule::GetAddrOfRTTIDescriptor(QualType Ty,
-                                                       bool ForEH) {
-  // Return a bogus pointer if RTTI is disabled, unless it's for EH.
-  // FIXME: should we even be calling this method if RTTI is disabled
-  // and it's not for EH?
-  if (!ForEH && !getLangOpts().RTTI)
-    return llvm::Constant::getNullValue(Int8PtrTy);
-  
-  if (ForEH && Ty->isObjCObjectPointerType() &&
-      LangOpts.ObjCRuntime.isGNUFamily())
-    return ObjCRuntime->GetEHType(Ty);
-
-  return RTTIBuilder(*this).BuildTypeInfo(Ty);
-}
-
-void CodeGenModule::EmitFundamentalRTTIDescriptor(QualType Type) {
-  QualType PointerType = Context.getPointerType(Type);
-  QualType PointerTypeConst = Context.getPointerType(Type.withConst());
-  RTTIBuilder(*this).BuildTypeInfo(Type, true);
-  RTTIBuilder(*this).BuildTypeInfo(PointerType, true);
-  RTTIBuilder(*this).BuildTypeInfo(PointerTypeConst, true);
-}
-
-void CodeGenModule::EmitFundamentalRTTIDescriptors() {
-  QualType FundamentalTypes[] = { Context.VoidTy, Context.NullPtrTy,
-                                  Context.BoolTy, Context.WCharTy,
-                                  Context.CharTy, Context.UnsignedCharTy,
-                                  Context.SignedCharTy, Context.ShortTy, 
-                                  Context.UnsignedShortTy, Context.IntTy,
-                                  Context.UnsignedIntTy, Context.LongTy, 
-                                  Context.UnsignedLongTy, Context.LongLongTy, 
-                                  Context.UnsignedLongLongTy, Context.FloatTy,
-                                  Context.DoubleTy, Context.LongDoubleTy,
-                                  Context.Char16Ty, Context.Char32Ty };
-  for (unsigned i = 0; i < llvm::array_lengthof(FundamentalTypes); ++i)
-    EmitFundamentalRTTIDescriptor(FundamentalTypes[i]);
-}
diff --git a/lib/CodeGen/CGRecordLayout.h b/lib/CodeGen/CGRecordLayout.h
index b29fc98..b45fee5 100644
--- a/lib/CodeGen/CGRecordLayout.h
+++ b/lib/CodeGen/CGRecordLayout.h
@@ -130,7 +130,7 @@
   llvm::DenseMap<const FieldDecl *, CGBitFieldInfo> BitFields;
 
   // FIXME: Maybe we could use a CXXBaseSpecifier as the key and use a single
-  // map for both virtual and non virtual bases.
+  // map for both virtual and non-virtual bases.
   llvm::DenseMap<const CXXRecordDecl *, unsigned> NonVirtualBases;
 
   /// Map from virtual bases to their field index in the complete object.
@@ -183,6 +183,7 @@
   /// \brief Return llvm::StructType element number that corresponds to the
   /// field FD.
   unsigned getLLVMFieldNo(const FieldDecl *FD) const {
+    FD = FD->getCanonicalDecl();
     assert(FieldInfo.count(FD) && "Invalid field for record!");
     return FieldInfo.lookup(FD);
   }
@@ -201,7 +202,8 @@
 
   /// \brief Return the BitFieldInfo that corresponds to the field FD.
   const CGBitFieldInfo &getBitFieldInfo(const FieldDecl *FD) const {
-    assert(FD->isBitField() && "Invalid call for non bit-field decl!");
+    FD = FD->getCanonicalDecl();
+    assert(FD->isBitField() && "Invalid call for non-bit-field decl!");
     llvm::DenseMap<const FieldDecl *, CGBitFieldInfo>::const_iterator
       it = BitFields.find(FD);
     assert(it != BitFields.end() && "Unable to find bitfield info");
diff --git a/lib/CodeGen/CGRecordLayoutBuilder.cpp b/lib/CodeGen/CGRecordLayoutBuilder.cpp
index ab92563..a10d8e7 100644
--- a/lib/CodeGen/CGRecordLayoutBuilder.cpp
+++ b/lib/CodeGen/CGRecordLayoutBuilder.cpp
@@ -25,205 +25,579 @@
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/Type.h"
 #include "llvm/Support/Debug.h"
+#include "llvm/Support/MathExtras.h"
 #include "llvm/Support/raw_ostream.h"
 using namespace clang;
 using namespace CodeGen;
 
 namespace {
-
-class CGRecordLayoutBuilder {
-public:
-  /// FieldTypes - Holds the LLVM types that the struct is created from.
-  /// 
+/// The CGRecordLowering is responsible for lowering an ASTRecordLayout to an
+/// llvm::Type.  Some of the lowering is straightforward, some is not.  Here we
+/// detail some of the complexities and weirdnesses here.
+/// * LLVM does not have unions - Unions can, in theory be represented by any
+///   llvm::Type with correct size.  We choose a field via a specific heuristic
+///   and add padding if necessary.
+/// * LLVM does not have bitfields - Bitfields are collected into contiguous
+///   runs and allocated as a single storage type for the run.  ASTRecordLayout
+///   contains enough information to determine where the runs break.  Microsoft
+///   and Itanium follow different rules and use different codepaths.
+/// * It is desired that, when possible, bitfields use the appropriate iN type
+///   when lowered to llvm types.  For example unsigned x : 24 gets lowered to
+///   i24.  This isn't always possible because i24 has storage size of 32 bit
+///   and if it is possible to use that extra byte of padding we must use
+///   [i8 x 3] instead of i24.  The function clipTailPadding does this.
+///   C++ examples that require clipping:
+///   struct { int a : 24; char b; }; // a must be clipped, b goes at offset 3
+///   struct A { int a : 24; }; // a must be clipped because a struct like B
+//    could exist: struct B : A { char b; }; // b goes at offset 3
+/// * Clang ignores 0 sized bitfields and 0 sized bases but *not* zero sized
+///   fields.  The existing asserts suggest that LLVM assumes that *every* field
+///   has an underlying storage type.  Therefore empty structures containing
+///   zero sized subobjects such as empty records or zero sized arrays still get
+///   a zero sized (empty struct) storage type.
+/// * Clang reads the complete type rather than the base type when generating
+///   code to access fields.  Bitfields in tail position with tail padding may
+///   be clipped in the base class but not the complete class (we may discover
+///   that the tail padding is not used in the complete class.) However,
+///   because LLVM reads from the complete type it can generate incorrect code
+///   if we do not clip the tail padding off of the bitfield in the complete
+///   layout.  This introduces a somewhat awkward extra unnecessary clip stage.
+///   The location of the clip is stored internally as a sentinal of type
+///   SCISSOR.  If LLVM were updated to read base types (which it probably
+///   should because locations of things such as VBases are bogus in the llvm
+///   type anyway) then we could eliminate the SCISSOR.
+/// * Itanium allows nearly empty primary virtual bases.  These bases don't get
+///   get their own storage because they're laid out as part of another base
+///   or at the beginning of the structure.  Determining if a VBase actually
+///   gets storage awkwardly involves a walk of all bases.
+/// * VFPtrs and VBPtrs do *not* make a record NotZeroInitializable.
+struct CGRecordLowering {
+  // MemberInfo is a helper structure that contains information about a record
+  // member.  In additional to the standard member types, there exists a
+  // sentinal member type that ensures correct rounding.
+  struct MemberInfo {
+    CharUnits Offset;
+    enum InfoKind { VFPtr, VBPtr, Field, Base, VBase, Scissor } Kind;
+    llvm::Type *Data;
+    union {
+      const FieldDecl *FD;
+      const CXXRecordDecl *RD;
+    };
+    MemberInfo(CharUnits Offset, InfoKind Kind, llvm::Type *Data,
+               const FieldDecl *FD = nullptr)
+      : Offset(Offset), Kind(Kind), Data(Data), FD(FD) {}
+    MemberInfo(CharUnits Offset, InfoKind Kind, llvm::Type *Data,
+               const CXXRecordDecl *RD)
+      : Offset(Offset), Kind(Kind), Data(Data), RD(RD) {}
+    // MemberInfos are sorted so we define a < operator.
+    bool operator <(const MemberInfo& a) const { return Offset < a.Offset; }
+  };
+  // The constructor.
+  CGRecordLowering(CodeGenTypes &Types, const RecordDecl *D);
+  // Short helper routines.
+  /// \brief Constructs a MemberInfo instance from an offset and llvm::Type *.
+  MemberInfo StorageInfo(CharUnits Offset, llvm::Type *Data) {
+    return MemberInfo(Offset, MemberInfo::Field, Data);
+  }
+  bool useMSABI() {
+    return Context.getTargetInfo().getCXXABI().isMicrosoft() ||
+           D->isMsStruct(Context);
+  }
+  /// \brief Wraps llvm::Type::getIntNTy with some implicit arguments.
+  llvm::Type *getIntNType(uint64_t NumBits) {
+    return llvm::Type::getIntNTy(Types.getLLVMContext(),
+        (unsigned)llvm::RoundUpToAlignment(NumBits, 8));
+  }
+  /// \brief Gets an llvm type of size NumBytes and alignment 1.
+  llvm::Type *getByteArrayType(CharUnits NumBytes) {
+    assert(!NumBytes.isZero() && "Empty byte arrays aren't allowed.");
+    llvm::Type *Type = llvm::Type::getInt8Ty(Types.getLLVMContext());
+    return NumBytes == CharUnits::One() ? Type :
+        (llvm::Type *)llvm::ArrayType::get(Type, NumBytes.getQuantity());
+  }
+  /// \brief Gets the storage type for a field decl and handles storage
+  /// for itanium bitfields that are smaller than their declared type.
+  llvm::Type *getStorageType(const FieldDecl *FD) {
+    llvm::Type *Type = Types.ConvertTypeForMem(FD->getType());
+    return useMSABI() || !FD->isBitField() ? Type :
+        getIntNType(std::min(FD->getBitWidthValue(Context),
+                             (unsigned)Context.toBits(getSize(Type))));
+  }
+  /// \brief Gets the llvm Basesubobject type from a CXXRecordDecl.
+  llvm::Type *getStorageType(const CXXRecordDecl *RD) {
+    return Types.getCGRecordLayout(RD).getBaseSubobjectLLVMType();
+  }
+  CharUnits bitsToCharUnits(uint64_t BitOffset) {
+    return Context.toCharUnitsFromBits(BitOffset);
+  }
+  CharUnits getSize(llvm::Type *Type) {
+    return CharUnits::fromQuantity(DataLayout.getTypeAllocSize(Type));
+  }
+  CharUnits getAlignment(llvm::Type *Type) {
+    return CharUnits::fromQuantity(DataLayout.getABITypeAlignment(Type));
+  }
+  bool isZeroInitializable(const FieldDecl *FD) {
+    const Type *Type = FD->getType()->getBaseElementTypeUnsafe();
+    if (const MemberPointerType *MPT = Type->getAs<MemberPointerType>())
+      return Types.getCXXABI().isZeroInitializable(MPT);
+    if (const RecordType *RT = Type->getAs<RecordType>())
+      return isZeroInitializable(RT->getDecl());
+    return true;
+  }
+  bool isZeroInitializable(const RecordDecl *RD) {
+    return Types.getCGRecordLayout(RD).isZeroInitializable();
+  }
+  void appendPaddingBytes(CharUnits Size) {
+    if (!Size.isZero())
+      FieldTypes.push_back(getByteArrayType(Size));
+  }
+  uint64_t getFieldBitOffset(const FieldDecl *FD) {
+    return Layout.getFieldOffset(FD->getFieldIndex());
+  }
+  // Layout routines.
+  void setBitFieldInfo(const FieldDecl *FD, CharUnits StartOffset, 
+                       llvm::Type *StorageType);
+  /// \brief Lowers an ASTRecordLayout to a llvm type.
+  void lower(bool NonVirtualBaseType);
+  void lowerUnion();
+  void accumulateFields();
+  void accumulateBitFields(RecordDecl::field_iterator Field,
+                        RecordDecl::field_iterator FieldEnd);
+  void accumulateBases();
+  void accumulateVPtrs();
+  void accumulateVBases();
+  /// \brief Recursively searches all of the bases to find out if a vbase is
+  /// not the primary vbase of some base class.
+  bool hasOwnStorage(const CXXRecordDecl *Decl, const CXXRecordDecl *Query);
+  void calculateZeroInit();
+  /// \brief Lowers bitfield storage types to I8 arrays for bitfields with tail
+  /// padding that is or can potentially be used.
+  void clipTailPadding();
+  /// \brief Determines if we need a packed llvm struct.
+  void determinePacked();
+  /// \brief Inserts padding everwhere it's needed.
+  void insertPadding();
+  /// \brief Fills out the structures that are ultimately consumed.
+  void fillOutputFields();
+  // Input memoization fields.
+  CodeGenTypes &Types;
+  const ASTContext &Context;
+  const RecordDecl *D;
+  const CXXRecordDecl *RD;
+  const ASTRecordLayout &Layout;
+  const llvm::DataLayout &DataLayout;
+  // Helpful intermediate data-structures.
+  std::vector<MemberInfo> Members;
+  // Output fields, consumed by CodeGenTypes::ComputeRecordLayout.
   SmallVector<llvm::Type *, 16> FieldTypes;
-
-  /// BaseSubobjectType - Holds the LLVM type for the non-virtual part
-  /// of the struct. For example, consider:
-  ///
-  /// struct A { int i; };
-  /// struct B { void *v; };
-  /// struct C : virtual A, B { };
-  ///
-  /// The LLVM type of C will be
-  /// %struct.C = type { i32 (...)**, %struct.A, i32, %struct.B }
-  ///
-  /// And the LLVM type of the non-virtual base struct will be
-  /// %struct.C.base = type { i32 (...)**, %struct.A, i32 }
-  ///
-  /// This only gets initialized if the base subobject type is
-  /// different from the complete-object type.
-  llvm::StructType *BaseSubobjectType;
-
-  /// FieldInfo - Holds a field and its corresponding LLVM field number.
   llvm::DenseMap<const FieldDecl *, unsigned> Fields;
-
-  /// BitFieldInfo - Holds location and size information about a bit field.
   llvm::DenseMap<const FieldDecl *, CGBitFieldInfo> BitFields;
-
   llvm::DenseMap<const CXXRecordDecl *, unsigned> NonVirtualBases;
   llvm::DenseMap<const CXXRecordDecl *, unsigned> VirtualBases;
-
-  /// IndirectPrimaryBases - Virtual base classes, direct or indirect, that are
-  /// primary base classes for some other direct or indirect base class.
-  CXXIndirectPrimaryBaseSet IndirectPrimaryBases;
-
-  /// LaidOutVirtualBases - A set of all laid out virtual bases, used to avoid
-  /// avoid laying out virtual bases more than once.
-  llvm::SmallPtrSet<const CXXRecordDecl *, 4> LaidOutVirtualBases;
-  
-  /// IsZeroInitializable - Whether this struct can be C++
-  /// zero-initialized with an LLVM zeroinitializer.
-  bool IsZeroInitializable;
-  bool IsZeroInitializableAsBase;
-
-  /// Packed - Whether the resulting LLVM struct will be packed or not.
-  bool Packed;
-
+  bool IsZeroInitializable : 1;
+  bool IsZeroInitializableAsBase : 1;
+  bool Packed : 1;
 private:
-  CodeGenTypes &Types;
-
-  /// LastLaidOutBaseInfo - Contains the offset and non-virtual size of the
-  /// last base laid out. Used so that we can replace the last laid out base
-  /// type with an i8 array if needed.
-  struct LastLaidOutBaseInfo {
-    CharUnits Offset;
-    CharUnits NonVirtualSize;
-
-    bool isValid() const { return !NonVirtualSize.isZero(); }
-    void invalidate() { NonVirtualSize = CharUnits::Zero(); }
-  
-  } LastLaidOutBase;
-
-  /// Alignment - Contains the alignment of the RecordDecl.
-  CharUnits Alignment;
-
-  /// NextFieldOffset - Holds the next field offset.
-  CharUnits NextFieldOffset;
-
-  /// LayoutUnionField - Will layout a field in an union and return the type
-  /// that the field will have.
-  llvm::Type *LayoutUnionField(const FieldDecl *Field,
-                               const ASTRecordLayout &Layout);
-  
-  /// LayoutUnion - Will layout a union RecordDecl.
-  void LayoutUnion(const RecordDecl *D);
-
-  /// Lay out a sequence of contiguous bitfields.
-  bool LayoutBitfields(const ASTRecordLayout &Layout,
-                       unsigned &FirstFieldNo,
-                       RecordDecl::field_iterator &FI,
-                       RecordDecl::field_iterator FE);
-
-  /// LayoutFields - try to layout all fields in the record decl.
-  /// Returns false if the operation failed because the struct is not packed.
-  bool LayoutFields(const RecordDecl *D);
-
-  /// Layout a single base, virtual or non-virtual
-  bool LayoutBase(const CXXRecordDecl *base,
-                  const CGRecordLayout &baseLayout,
-                  CharUnits baseOffset);
-
-  /// LayoutVirtualBase - layout a single virtual base.
-  bool LayoutVirtualBase(const CXXRecordDecl *base,
-                         CharUnits baseOffset);
-
-  /// LayoutVirtualBases - layout the virtual bases of a record decl.
-  bool LayoutVirtualBases(const CXXRecordDecl *RD,
-                          const ASTRecordLayout &Layout);
-
-  /// MSLayoutVirtualBases - layout the virtual bases of a record decl,
-  /// like MSVC.
-  bool MSLayoutVirtualBases(const CXXRecordDecl *RD,
-                            const ASTRecordLayout &Layout);
-  
-  /// LayoutNonVirtualBase - layout a single non-virtual base.
-  bool LayoutNonVirtualBase(const CXXRecordDecl *base,
-                            CharUnits baseOffset);
-  
-  /// LayoutNonVirtualBases - layout the virtual bases of a record decl.
-  bool LayoutNonVirtualBases(const CXXRecordDecl *RD, 
-                             const ASTRecordLayout &Layout);
-
-  /// ComputeNonVirtualBaseType - Compute the non-virtual base field types.
-  bool ComputeNonVirtualBaseType(const CXXRecordDecl *RD);
-  
-  /// LayoutField - layout a single field. Returns false if the operation failed
-  /// because the current struct is not packed.
-  bool LayoutField(const FieldDecl *D, uint64_t FieldOffset);
-
-  /// LayoutBitField - layout a single bit field.
-  void LayoutBitField(const FieldDecl *D, uint64_t FieldOffset);
-
-  /// AppendField - Appends a field with the given offset and type.
-  void AppendField(CharUnits fieldOffset, llvm::Type *FieldTy);
-
-  /// AppendPadding - Appends enough padding bytes so that the total
-  /// struct size is a multiple of the field alignment.
-  void AppendPadding(CharUnits fieldOffset, CharUnits fieldAlignment);
-
-  /// ResizeLastBaseFieldIfNecessary - Fields and bases can be laid out in the
-  /// tail padding of a previous base. If this happens, the type of the previous
-  /// base needs to be changed to an array of i8. Returns true if the last
-  /// laid out base was resized.
-  bool ResizeLastBaseFieldIfNecessary(CharUnits offset);
-
-  /// getByteArrayType - Returns a byte array type with the given number of
-  /// elements.
-  llvm::Type *getByteArrayType(CharUnits NumBytes);
-  
-  /// AppendBytes - Append a given number of bytes to the record.
-  void AppendBytes(CharUnits numBytes);
-
-  /// AppendTailPadding - Append enough tail padding so that the type will have
-  /// the passed size.
-  void AppendTailPadding(CharUnits RecordSize);
-
-  CharUnits getTypeAlignment(llvm::Type *Ty) const;
-
-  /// getAlignmentAsLLVMStruct - Returns the maximum alignment of all the
-  /// LLVM element types.
-  CharUnits getAlignmentAsLLVMStruct() const;
-
-  /// CheckZeroInitializable - Check if the given type contains a pointer
-  /// to data member.
-  void CheckZeroInitializable(QualType T);
-
-public:
-  CGRecordLayoutBuilder(CodeGenTypes &Types)
-    : BaseSubobjectType(0),
-      IsZeroInitializable(true), IsZeroInitializableAsBase(true),
-      Packed(false), Types(Types) { }
-
-  /// Layout - Will layout a RecordDecl.
-  void Layout(const RecordDecl *D);
+  CGRecordLowering(const CGRecordLowering &) LLVM_DELETED_FUNCTION;
+  void operator =(const CGRecordLowering &) LLVM_DELETED_FUNCTION;
 };
+} // namespace {
 
+CGRecordLowering::CGRecordLowering(CodeGenTypes &Types, const RecordDecl *D)
+  : Types(Types), Context(Types.getContext()), D(D),
+    RD(dyn_cast<CXXRecordDecl>(D)),
+    Layout(Types.getContext().getASTRecordLayout(D)),
+    DataLayout(Types.getDataLayout()), IsZeroInitializable(true),
+    IsZeroInitializableAsBase(true), Packed(false) {}
+
+void CGRecordLowering::setBitFieldInfo(
+    const FieldDecl *FD, CharUnits StartOffset, llvm::Type *StorageType) {
+  CGBitFieldInfo &Info = BitFields[FD->getCanonicalDecl()];
+  Info.IsSigned = FD->getType()->isSignedIntegerOrEnumerationType();
+  Info.Offset = (unsigned)(getFieldBitOffset(FD) - Context.toBits(StartOffset));
+  Info.Size = FD->getBitWidthValue(Context);
+  Info.StorageSize = (unsigned)DataLayout.getTypeAllocSizeInBits(StorageType);
+  // Here we calculate the actual storage alignment of the bits.  E.g if we've
+  // got an alignment >= 2 and the bitfield starts at offset 6 we've got an
+  // alignment of 2.
+  Info.StorageAlignment =
+      Layout.getAlignment().alignmentAtOffset(StartOffset).getQuantity();
+  if (Info.Size > Info.StorageSize)
+    Info.Size = Info.StorageSize;
+  // Reverse the bit offsets for big endian machines. Because we represent
+  // a bitfield as a single large integer load, we can imagine the bits
+  // counting from the most-significant-bit instead of the
+  // least-significant-bit.
+  if (DataLayout.isBigEndian())
+    Info.Offset = Info.StorageSize - (Info.Offset + Info.Size);
 }
 
-void CGRecordLayoutBuilder::Layout(const RecordDecl *D) {
-  const ASTRecordLayout &Layout = Types.getContext().getASTRecordLayout(D);
-  Alignment = Layout.getAlignment();
-  Packed = D->hasAttr<PackedAttr>() || Layout.getSize() % Alignment != 0;
+void CGRecordLowering::lower(bool NVBaseType) {
+  // The lowering process implemented in this function takes a variety of
+  // carefully ordered phases.
+  // 1) Store all members (fields and bases) in a list and sort them by offset.
+  // 2) Add a 1-byte capstone member at the Size of the structure.
+  // 3) Clip bitfield storages members if their tail padding is or might be
+  //    used by another field or base.  The clipping process uses the capstone 
+  //    by treating it as another object that occurs after the record.
+  // 4) Determine if the llvm-struct requires packing.  It's important that this
+  //    phase occur after clipping, because clipping changes the llvm type.
+  //    This phase reads the offset of the capstone when determining packedness
+  //    and updates the alignment of the capstone to be equal of the alignment
+  //    of the record after doing so.
+  // 5) Insert padding everywhere it is needed.  This phase requires 'Packed' to
+  //    have been computed and needs to know the alignment of the record in
+  //    order to understand if explicit tail padding is needed.
+  // 6) Remove the capstone, we don't need it anymore.
+  // 7) Determine if this record can be zero-initialized.  This phase could have
+  //    been placed anywhere after phase 1.
+  // 8) Format the complete list of members in a way that can be consumed by
+  //    CodeGenTypes::ComputeRecordLayout.
+  CharUnits Size = NVBaseType ? Layout.getNonVirtualSize() : Layout.getSize();
+  if (D->isUnion())
+    return lowerUnion();
+  accumulateFields();
+  // RD implies C++.
+  if (RD) {
+    accumulateVPtrs();
+    accumulateBases();
+    if (Members.empty())
+      return appendPaddingBytes(Size);
+    if (!NVBaseType)
+      accumulateVBases();
+  }
+  std::stable_sort(Members.begin(), Members.end());
+  Members.push_back(StorageInfo(Size, getIntNType(8)));
+  clipTailPadding();
+  determinePacked();
+  insertPadding();
+  Members.pop_back();
+  calculateZeroInit();
+  fillOutputFields();
+}
 
-  if (D->isUnion()) {
-    LayoutUnion(D);
+void CGRecordLowering::lowerUnion() {
+  CharUnits LayoutSize = Layout.getSize();
+  llvm::Type *StorageType = nullptr;
+  // Compute zero-initializable status.
+  if (!D->field_empty() && !isZeroInitializable(*D->field_begin()))
+    IsZeroInitializable = IsZeroInitializableAsBase = false;
+  // Iterate through the fields setting bitFieldInfo and the Fields array. Also
+  // locate the "most appropriate" storage type.  The heuristic for finding the
+  // storage type isn't necessary, the first (non-0-length-bitfield) field's
+  // type would work fine and be simpler but would be differen than what we've
+  // been doing and cause lit tests to change.
+  for (const auto *Field : D->fields()) {
+    if (Field->isBitField()) {
+      // Skip 0 sized bitfields.
+      if (Field->getBitWidthValue(Context) == 0)
+        continue;
+      llvm::Type *FieldType = getStorageType(Field);
+      if (LayoutSize < getSize(FieldType))
+        FieldType = getByteArrayType(LayoutSize);
+      setBitFieldInfo(Field, CharUnits::Zero(), FieldType);
+    }
+    Fields[Field->getCanonicalDecl()] = 0;
+    llvm::Type *FieldType = getStorageType(Field);
+    // Conditionally update our storage type if we've got a new "better" one.
+    if (!StorageType ||
+        getAlignment(FieldType) >  getAlignment(StorageType) ||
+        (getAlignment(FieldType) == getAlignment(StorageType) &&
+        getSize(FieldType) > getSize(StorageType)))
+      StorageType = FieldType;
+  }
+  // If we have no storage type just pad to the appropriate size and return.
+  if (!StorageType)
+    return appendPaddingBytes(LayoutSize);
+  // If our storage size was bigger than our required size (can happen in the
+  // case of packed bitfields on Itanium) then just use an I8 array.
+  if (LayoutSize < getSize(StorageType))
+    StorageType = getByteArrayType(LayoutSize);
+  FieldTypes.push_back(StorageType);
+  appendPaddingBytes(LayoutSize - getSize(StorageType));
+  // Set packed if we need it.
+  if (LayoutSize % getAlignment(StorageType))
+    Packed = true;
+}
+
+void CGRecordLowering::accumulateFields() {
+  for (RecordDecl::field_iterator Field = D->field_begin(),
+                                  FieldEnd = D->field_end();
+    Field != FieldEnd;)
+    if (Field->isBitField()) {
+      RecordDecl::field_iterator Start = Field;
+      // Iterate to gather the list of bitfields.
+      for (++Field; Field != FieldEnd && Field->isBitField(); ++Field);
+      accumulateBitFields(Start, Field);
+    } else {
+      Members.push_back(MemberInfo(
+          bitsToCharUnits(getFieldBitOffset(*Field)), MemberInfo::Field,
+          getStorageType(*Field), *Field));
+      ++Field;
+    }
+}
+
+void
+CGRecordLowering::accumulateBitFields(RecordDecl::field_iterator Field,
+                                      RecordDecl::field_iterator FieldEnd) {
+  // Run stores the first element of the current run of bitfields.  FieldEnd is
+  // used as a special value to note that we don't have a current run.  A
+  // bitfield run is a contiguous collection of bitfields that can be stored in
+  // the same storage block.  Zero-sized bitfields and bitfields that would
+  // cross an alignment boundary break a run and start a new one.
+  RecordDecl::field_iterator Run = FieldEnd;
+  // Tail is the offset of the first bit off the end of the current run.  It's
+  // used to determine if the ASTRecordLayout is treating these two bitfields as
+  // contiguous.  StartBitOffset is offset of the beginning of the Run.
+  uint64_t StartBitOffset, Tail = 0;
+  if (useMSABI()) {
+    for (; Field != FieldEnd; ++Field) {
+      uint64_t BitOffset = getFieldBitOffset(*Field);
+      // Zero-width bitfields end runs.
+      if (Field->getBitWidthValue(Context) == 0) {
+        Run = FieldEnd;
+        continue;
+      }
+      llvm::Type *Type = Types.ConvertTypeForMem(Field->getType());
+      // If we don't have a run yet, or don't live within the previous run's
+      // allocated storage then we allocate some storage and start a new run.
+      if (Run == FieldEnd || BitOffset >= Tail) {
+        Run = Field;
+        StartBitOffset = BitOffset;
+        Tail = StartBitOffset + DataLayout.getTypeAllocSizeInBits(Type);
+        // Add the storage member to the record.  This must be added to the
+        // record before the bitfield members so that it gets laid out before
+        // the bitfields it contains get laid out.
+        Members.push_back(StorageInfo(bitsToCharUnits(StartBitOffset), Type));
+      }
+      // Bitfields get the offset of their storage but come afterward and remain
+      // there after a stable sort.
+      Members.push_back(MemberInfo(bitsToCharUnits(StartBitOffset),
+                                   MemberInfo::Field, nullptr, *Field));
+    }
     return;
   }
+  for (;;) {
+    // Check to see if we need to start a new run.
+    if (Run == FieldEnd) {
+      // If we're out of fields, return.
+      if (Field == FieldEnd)
+        break;
+      // Any non-zero-length bitfield can start a new run.
+      if (Field->getBitWidthValue(Context) != 0) {
+        Run = Field;
+        StartBitOffset = getFieldBitOffset(*Field);
+        Tail = StartBitOffset + Field->getBitWidthValue(Context);
+      }
+      ++Field;
+      continue;
+    }
+    // Add bitfields to the run as long as they qualify.
+    if (Field != FieldEnd && Field->getBitWidthValue(Context) != 0 &&
+        Tail == getFieldBitOffset(*Field)) {
+      Tail += Field->getBitWidthValue(Context);
+      ++Field;
+      continue;
+    }
+    // We've hit a break-point in the run and need to emit a storage field.
+    llvm::Type *Type = getIntNType(Tail - StartBitOffset);
+    // Add the storage member to the record and set the bitfield info for all of
+    // the bitfields in the run.  Bitfields get the offset of their storage but
+    // come afterward and remain there after a stable sort.
+    Members.push_back(StorageInfo(bitsToCharUnits(StartBitOffset), Type));
+    for (; Run != Field; ++Run)
+      Members.push_back(MemberInfo(bitsToCharUnits(StartBitOffset),
+                                   MemberInfo::Field, nullptr, *Run));
+    Run = FieldEnd;
+  }
+}
 
-  if (LayoutFields(D))
+void CGRecordLowering::accumulateBases() {
+  // If we've got a primary virtual base, we need to add it with the bases.
+  if (Layout.isPrimaryBaseVirtual()) {
+    const CXXRecordDecl *BaseDecl = Layout.getPrimaryBase();
+    Members.push_back(MemberInfo(CharUnits::Zero(), MemberInfo::Base,
+                                 getStorageType(BaseDecl), BaseDecl));
+  }
+  // Accumulate the non-virtual bases.
+  for (const auto &Base : RD->bases()) {
+    if (Base.isVirtual())
+      continue;
+    const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
+    if (!BaseDecl->isEmpty())
+      Members.push_back(MemberInfo(Layout.getBaseClassOffset(BaseDecl),
+          MemberInfo::Base, getStorageType(BaseDecl), BaseDecl));
+  }
+}
+
+void CGRecordLowering::accumulateVPtrs() {
+  if (Layout.hasOwnVFPtr())
+    Members.push_back(MemberInfo(CharUnits::Zero(), MemberInfo::VFPtr,
+        llvm::FunctionType::get(getIntNType(32), /*isVarArg=*/true)->
+            getPointerTo()->getPointerTo()));
+  if (Layout.hasOwnVBPtr())
+    Members.push_back(MemberInfo(Layout.getVBPtrOffset(), MemberInfo::VBPtr,
+        llvm::Type::getInt32PtrTy(Types.getLLVMContext())));
+}
+
+void CGRecordLowering::accumulateVBases() {
+  CharUnits ScissorOffset = Layout.getNonVirtualSize();
+  // In the itanium ABI, it's possible to place a vbase at a dsize that is
+  // smaller than the nvsize.  Here we check to see if such a base is placed
+  // before the nvsize and set the scissor offset to that, instead of the
+  // nvsize.
+  if (!useMSABI())
+    for (const auto &Base : RD->vbases()) {
+      const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
+      if (BaseDecl->isEmpty())
+        continue;
+      // If the vbase is a primary virtual base of some base, then it doesn't
+      // get its own storage location but instead lives inside of that base.
+      if (Context.isNearlyEmpty(BaseDecl) && !hasOwnStorage(RD, BaseDecl))
+        continue;
+      ScissorOffset = std::min(ScissorOffset,
+                               Layout.getVBaseClassOffset(BaseDecl));
+    }
+  Members.push_back(MemberInfo(ScissorOffset, MemberInfo::Scissor, nullptr,
+                               RD));
+  for (const auto &Base : RD->vbases()) {
+    const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
+    if (BaseDecl->isEmpty())
+      continue;
+    CharUnits Offset = Layout.getVBaseClassOffset(BaseDecl);
+    // If the vbase is a primary virtual base of some base, then it doesn't
+    // get its own storage location but instead lives inside of that base.
+    if (!useMSABI() && Context.isNearlyEmpty(BaseDecl) &&
+        !hasOwnStorage(RD, BaseDecl)) {
+      Members.push_back(MemberInfo(Offset, MemberInfo::VBase, nullptr,
+                                   BaseDecl));
+      continue;
+    }
+    // If we've got a vtordisp, add it as a storage type.
+    if (Layout.getVBaseOffsetsMap().find(BaseDecl)->second.hasVtorDisp())
+      Members.push_back(StorageInfo(Offset - CharUnits::fromQuantity(4),
+                                    getIntNType(32)));
+    Members.push_back(MemberInfo(Offset, MemberInfo::VBase,
+                                 getStorageType(BaseDecl), BaseDecl));
+  }
+}
+
+bool CGRecordLowering::hasOwnStorage(const CXXRecordDecl *Decl,
+                                     const CXXRecordDecl *Query) {
+  const ASTRecordLayout &DeclLayout = Context.getASTRecordLayout(Decl);
+  if (DeclLayout.isPrimaryBaseVirtual() && DeclLayout.getPrimaryBase() == Query)
+    return false;
+  for (const auto &Base : Decl->bases())
+    if (!hasOwnStorage(Base.getType()->getAsCXXRecordDecl(), Query))
+      return false;
+  return true;
+}
+
+void CGRecordLowering::calculateZeroInit() {
+  for (std::vector<MemberInfo>::const_iterator Member = Members.begin(),
+                                               MemberEnd = Members.end();
+       IsZeroInitializableAsBase && Member != MemberEnd; ++Member) {
+    if (Member->Kind == MemberInfo::Field) {
+      if (!Member->FD || isZeroInitializable(Member->FD))
+        continue;
+      IsZeroInitializable = IsZeroInitializableAsBase = false;
+    } else if (Member->Kind == MemberInfo::Base ||
+               Member->Kind == MemberInfo::VBase) {
+      if (isZeroInitializable(Member->RD))
+        continue;
+      IsZeroInitializable = false;
+      if (Member->Kind == MemberInfo::Base)
+        IsZeroInitializableAsBase = false;
+    }
+  }
+}
+
+void CGRecordLowering::clipTailPadding() {
+  std::vector<MemberInfo>::iterator Prior = Members.begin();
+  CharUnits Tail = getSize(Prior->Data);
+  for (std::vector<MemberInfo>::iterator Member = Prior + 1,
+                                         MemberEnd = Members.end();
+       Member != MemberEnd; ++Member) {
+    // Only members with data and the scissor can cut into tail padding.
+    if (!Member->Data && Member->Kind != MemberInfo::Scissor)
+      continue;
+    if (Member->Offset < Tail) {
+      assert(Prior->Kind == MemberInfo::Field && !Prior->FD &&
+             "Only storage fields have tail padding!");
+      Prior->Data = getByteArrayType(bitsToCharUnits(llvm::RoundUpToAlignment(
+          cast<llvm::IntegerType>(Prior->Data)->getIntegerBitWidth(), 8)));
+    }
+    if (Member->Data)
+      Prior = Member;
+    Tail = Prior->Offset + getSize(Prior->Data);
+  }
+}
+
+void CGRecordLowering::determinePacked() {
+  CharUnits Alignment = CharUnits::One();
+  for (std::vector<MemberInfo>::const_iterator Member = Members.begin(),
+                                               MemberEnd = Members.end();
+       Member != MemberEnd; ++Member) {
+    if (!Member->Data)
+      continue;
+    // If any member falls at an offset that it not a multiple of its alignment,
+    // then the entire record must be packed.
+    if (Member->Offset % getAlignment(Member->Data))
+      Packed = true;
+    Alignment = std::max(Alignment, getAlignment(Member->Data));
+  }
+  // If the size of the record (the capstone's offset) is not a multiple of the
+  // record's alignment, it must be packed.
+  if (Members.back().Offset % Alignment)
+    Packed = true;
+  // Update the alignment of the sentinal.
+  if (!Packed)
+    Members.back().Data = getIntNType(Context.toBits(Alignment));
+}
+
+void CGRecordLowering::insertPadding() {
+  std::vector<std::pair<CharUnits, CharUnits> > Padding;
+  CharUnits Size = CharUnits::Zero();
+  for (std::vector<MemberInfo>::const_iterator Member = Members.begin(),
+                                               MemberEnd = Members.end();
+       Member != MemberEnd; ++Member) {
+    if (!Member->Data)
+      continue;
+    CharUnits Offset = Member->Offset;
+    assert(Offset >= Size);
+    // Insert padding if we need to.
+    if (Offset != Size.RoundUpToAlignment(Packed ? CharUnits::One() :
+                                          getAlignment(Member->Data)))
+      Padding.push_back(std::make_pair(Size, Offset - Size));
+    Size = Offset + getSize(Member->Data);
+  }
+  if (Padding.empty())
     return;
+  // Add the padding to the Members list and sort it.
+  for (std::vector<std::pair<CharUnits, CharUnits> >::const_iterator
+        Pad = Padding.begin(), PadEnd = Padding.end();
+        Pad != PadEnd; ++Pad)
+    Members.push_back(StorageInfo(Pad->first, getByteArrayType(Pad->second)));
+  std::stable_sort(Members.begin(), Members.end());
+}
 
-  // We weren't able to layout the struct. Try again with a packed struct
-  Packed = true;
-  LastLaidOutBase.invalidate();
-  NextFieldOffset = CharUnits::Zero();
-  FieldTypes.clear();
-  Fields.clear();
-  BitFields.clear();
-  NonVirtualBases.clear();
-  VirtualBases.clear();
-
-  LayoutFields(D);
+void CGRecordLowering::fillOutputFields() {
+  for (std::vector<MemberInfo>::const_iterator Member = Members.begin(),
+                                               MemberEnd = Members.end();
+       Member != MemberEnd; ++Member) {
+    if (Member->Data)
+      FieldTypes.push_back(Member->Data);
+    if (Member->Kind == MemberInfo::Field) {
+      if (Member->FD)
+        Fields[Member->FD->getCanonicalDecl()] = FieldTypes.size() - 1;
+      // A field without storage must be a bitfield.
+      if (!Member->Data)
+        setBitFieldInfo(Member->FD, Member->Offset, FieldTypes.back());
+    } else if (Member->Kind == MemberInfo::Base)
+      NonVirtualBases[Member->RD] = FieldTypes.size() - 1;
+    else if (Member->Kind == MemberInfo::VBase)
+      VirtualBases[Member->RD] = FieldTypes.size() - 1;
+  }
 }
 
 CGBitFieldInfo CGBitFieldInfo::MakeInfo(CodeGenTypes &Types,
@@ -231,6 +605,9 @@
                                         uint64_t Offset, uint64_t Size,
                                         uint64_t StorageSize,
                                         uint64_t StorageAlignment) {
+  // This function is vestigial from CGRecordLayoutBuilder days but is still 
+  // used in GCObjCRuntime.cpp.  That usage has a "fixme" attached to it that
+  // when addressed will allow for the removal of this function.
   llvm::Type *Ty = Types.ConvertTypeForMem(FD->getType());
   CharUnits TypeSizeInBytes =
     CharUnits::fromQuantity(Types.getDataLayout().getTypeAllocSize(Ty));
@@ -262,709 +639,33 @@
   return CGBitFieldInfo(Offset, Size, IsSigned, StorageSize, StorageAlignment);
 }
 
-/// \brief Layout the range of bitfields from BFI to BFE as contiguous storage.
-bool CGRecordLayoutBuilder::LayoutBitfields(const ASTRecordLayout &Layout,
-                                            unsigned &FirstFieldNo,
-                                            RecordDecl::field_iterator &FI,
-                                            RecordDecl::field_iterator FE) {
-  assert(FI != FE);
-  uint64_t FirstFieldOffset = Layout.getFieldOffset(FirstFieldNo);
-  uint64_t NextFieldOffsetInBits = Types.getContext().toBits(NextFieldOffset);
-
-  unsigned CharAlign = Types.getTarget().getCharAlign();
-  assert(FirstFieldOffset % CharAlign == 0 &&
-         "First field offset is misaligned");
-  CharUnits FirstFieldOffsetInBytes
-    = Types.getContext().toCharUnitsFromBits(FirstFieldOffset);
-
-  unsigned StorageAlignment
-    = llvm::MinAlign(Alignment.getQuantity(),
-                     FirstFieldOffsetInBytes.getQuantity());
-
-  if (FirstFieldOffset < NextFieldOffsetInBits) {
-    CharUnits FieldOffsetInCharUnits =
-      Types.getContext().toCharUnitsFromBits(FirstFieldOffset);
-
-    // Try to resize the last base field.
-    if (!ResizeLastBaseFieldIfNecessary(FieldOffsetInCharUnits))
-      llvm_unreachable("We must be able to resize the last base if we need to "
-                       "pack bits into it.");
-
-    NextFieldOffsetInBits = Types.getContext().toBits(NextFieldOffset);
-    assert(FirstFieldOffset >= NextFieldOffsetInBits);
-  }
-
-  // Append padding if necessary.
-  AppendPadding(Types.getContext().toCharUnitsFromBits(FirstFieldOffset),
-                CharUnits::One());
-
-  // Find the last bitfield in a contiguous run of bitfields.
-  RecordDecl::field_iterator BFI = FI;
-  unsigned LastFieldNo = FirstFieldNo;
-  uint64_t NextContiguousFieldOffset = FirstFieldOffset;
-  for (RecordDecl::field_iterator FJ = FI;
-       (FJ != FE && (*FJ)->isBitField() &&
-        NextContiguousFieldOffset == Layout.getFieldOffset(LastFieldNo) &&
-        (*FJ)->getBitWidthValue(Types.getContext()) != 0); FI = FJ++) {
-    NextContiguousFieldOffset += (*FJ)->getBitWidthValue(Types.getContext());
-    ++LastFieldNo;
-
-    // We must use packed structs for packed fields, and also unnamed bit
-    // fields since they don't affect the struct alignment.
-    if (!Packed && ((*FJ)->hasAttr<PackedAttr>() || !(*FJ)->getDeclName()))
-      return false;
-  }
-  RecordDecl::field_iterator BFE = llvm::next(FI);
-  --LastFieldNo;
-  assert(LastFieldNo >= FirstFieldNo && "Empty run of contiguous bitfields");
-  FieldDecl *LastFD = *FI;
-
-  // Find the last bitfield's offset, add its size, and round it up to the
-  // character alignment to compute the storage required.
-  uint64_t LastFieldOffset = Layout.getFieldOffset(LastFieldNo);
-  uint64_t LastFieldSize = LastFD->getBitWidthValue(Types.getContext());
-  uint64_t TotalBits = (LastFieldOffset + LastFieldSize) - FirstFieldOffset;
-  CharUnits StorageBytes = Types.getContext().toCharUnitsFromBits(
-    llvm::RoundUpToAlignment(TotalBits, CharAlign));
-  uint64_t StorageBits = Types.getContext().toBits(StorageBytes);
-
-  // Grow the storage to encompass any known padding in the layout when doing
-  // so will make the storage a power-of-two. There are two cases when we can
-  // do this. The first is when we have a subsequent field and can widen up to
-  // its offset. The second is when the data size of the AST record layout is
-  // past the end of the current storage. The latter is true when there is tail
-  // padding on a struct and no members of a super class can be packed into it.
-  //
-  // Note that we widen the storage as much as possible here to express the
-  // maximum latitude the language provides, and rely on the backend to lower
-  // these in conjunction with shifts and masks to narrower operations where
-  // beneficial.
-  uint64_t EndOffset = Types.getContext().toBits(Layout.getDataSize());
-  if (BFE != FE)
-    // If there are more fields to be laid out, the offset at the end of the
-    // bitfield is the offset of the next field in the record.
-    EndOffset = Layout.getFieldOffset(LastFieldNo + 1);
-  assert(EndOffset >= (FirstFieldOffset + TotalBits) &&
-         "End offset is not past the end of the known storage bits.");
-  uint64_t SpaceBits = EndOffset - FirstFieldOffset;
-  uint64_t LongBits = Types.getTarget().getLongWidth();
-  uint64_t WidenedBits = (StorageBits / LongBits) * LongBits +
-                         llvm::NextPowerOf2(StorageBits % LongBits - 1);
-  assert(WidenedBits >= StorageBits && "Widening shrunk the bits!");
-  if (WidenedBits <= SpaceBits) {
-    StorageBits = WidenedBits;
-    StorageBytes = Types.getContext().toCharUnitsFromBits(StorageBits);
-    assert(StorageBits == (uint64_t)Types.getContext().toBits(StorageBytes));
-  }
-
-  unsigned FieldIndex = FieldTypes.size();
-  AppendBytes(StorageBytes);
-
-  // Now walk the bitfields associating them with this field of storage and
-  // building up the bitfield specific info.
-  unsigned FieldNo = FirstFieldNo;
-  for (; BFI != BFE; ++BFI, ++FieldNo) {
-    FieldDecl *FD = *BFI;
-    uint64_t FieldOffset = Layout.getFieldOffset(FieldNo) - FirstFieldOffset;
-    uint64_t FieldSize = FD->getBitWidthValue(Types.getContext());
-    Fields[FD] = FieldIndex;
-    BitFields[FD] = CGBitFieldInfo::MakeInfo(Types, FD, FieldOffset, FieldSize,
-                                             StorageBits, StorageAlignment);
-  }
-  FirstFieldNo = LastFieldNo;
-  return true;
-}
-
-bool CGRecordLayoutBuilder::LayoutField(const FieldDecl *D,
-                                        uint64_t fieldOffset) {
-  // If the field is packed, then we need a packed struct.
-  if (!Packed && D->hasAttr<PackedAttr>())
-    return false;
-
-  assert(!D->isBitField() && "Bitfields should be laid out seperately.");
-
-  CheckZeroInitializable(D->getType());
-
-  assert(fieldOffset % Types.getTarget().getCharWidth() == 0
-         && "field offset is not on a byte boundary!");
-  CharUnits fieldOffsetInBytes
-    = Types.getContext().toCharUnitsFromBits(fieldOffset);
-
-  llvm::Type *Ty = Types.ConvertTypeForMem(D->getType());
-  CharUnits typeAlignment = getTypeAlignment(Ty);
-
-  // If the type alignment is larger then the struct alignment, we must use
-  // a packed struct.
-  if (typeAlignment > Alignment) {
-    assert(!Packed && "Alignment is wrong even with packed struct!");
-    return false;
-  }
-
-  if (!Packed) {
-    if (const RecordType *RT = D->getType()->getAs<RecordType>()) {
-      const RecordDecl *RD = cast<RecordDecl>(RT->getDecl());
-      if (const MaxFieldAlignmentAttr *MFAA =
-            RD->getAttr<MaxFieldAlignmentAttr>()) {
-        if (MFAA->getAlignment() != Types.getContext().toBits(typeAlignment))
-          return false;
-      }
-    }
-  }
-
-  // Round up the field offset to the alignment of the field type.
-  CharUnits alignedNextFieldOffsetInBytes =
-    NextFieldOffset.RoundUpToAlignment(typeAlignment);
-
-  if (fieldOffsetInBytes < alignedNextFieldOffsetInBytes) {
-    // Try to resize the last base field.
-    if (ResizeLastBaseFieldIfNecessary(fieldOffsetInBytes)) {
-      alignedNextFieldOffsetInBytes = 
-        NextFieldOffset.RoundUpToAlignment(typeAlignment);
-    }
-  }
-
-  if (fieldOffsetInBytes < alignedNextFieldOffsetInBytes) {
-    assert(!Packed && "Could not place field even with packed struct!");
-    return false;
-  }
-
-  AppendPadding(fieldOffsetInBytes, typeAlignment);
-
-  // Now append the field.
-  Fields[D] = FieldTypes.size();
-  AppendField(fieldOffsetInBytes, Ty);
-
-  LastLaidOutBase.invalidate();
-  return true;
-}
-
-llvm::Type *
-CGRecordLayoutBuilder::LayoutUnionField(const FieldDecl *Field,
-                                        const ASTRecordLayout &Layout) {
-  Fields[Field] = 0;
-  if (Field->isBitField()) {
-    uint64_t FieldSize = Field->getBitWidthValue(Types.getContext());
-
-    // Ignore zero sized bit fields.
-    if (FieldSize == 0)
-      return 0;
-
-    unsigned StorageBits = llvm::RoundUpToAlignment(
-      FieldSize, Types.getTarget().getCharAlign());
-    CharUnits NumBytesToAppend
-      = Types.getContext().toCharUnitsFromBits(StorageBits);
-
-    llvm::Type *FieldTy = llvm::Type::getInt8Ty(Types.getLLVMContext());
-    if (NumBytesToAppend > CharUnits::One())
-      FieldTy = llvm::ArrayType::get(FieldTy, NumBytesToAppend.getQuantity());
-
-    // Add the bit field info.
-    BitFields[Field] = CGBitFieldInfo::MakeInfo(Types, Field, 0, FieldSize,
-                                                StorageBits,
-                                                Alignment.getQuantity());
-    return FieldTy;
-  }
-
-  // This is a regular union field.
-  return Types.ConvertTypeForMem(Field->getType());
-}
-
-void CGRecordLayoutBuilder::LayoutUnion(const RecordDecl *D) {
-  assert(D->isUnion() && "Can't call LayoutUnion on a non-union record!");
-
-  const ASTRecordLayout &layout = Types.getContext().getASTRecordLayout(D);
-
-  llvm::Type *unionType = 0;
-  CharUnits unionSize = CharUnits::Zero();
-  CharUnits unionAlign = CharUnits::Zero();
-
-  bool hasOnlyZeroSizedBitFields = true;
-  bool checkedFirstFieldZeroInit = false;
-
-  unsigned fieldNo = 0;
-  for (RecordDecl::field_iterator field = D->field_begin(),
-       fieldEnd = D->field_end(); field != fieldEnd; ++field, ++fieldNo) {
-    assert(layout.getFieldOffset(fieldNo) == 0 &&
-          "Union field offset did not start at the beginning of record!");
-    llvm::Type *fieldType = LayoutUnionField(*field, layout);
-
-    if (!fieldType)
-      continue;
-
-    if (field->getDeclName() && !checkedFirstFieldZeroInit) {
-      CheckZeroInitializable(field->getType());
-      checkedFirstFieldZeroInit = true;
-    }
-
-    hasOnlyZeroSizedBitFields = false;
-
-    CharUnits fieldAlign = CharUnits::fromQuantity(
-                          Types.getDataLayout().getABITypeAlignment(fieldType));
-    CharUnits fieldSize = CharUnits::fromQuantity(
-                             Types.getDataLayout().getTypeAllocSize(fieldType));
-
-    if (fieldAlign < unionAlign)
-      continue;
-
-    if (fieldAlign > unionAlign || fieldSize > unionSize) {
-      unionType = fieldType;
-      unionAlign = fieldAlign;
-      unionSize = fieldSize;
-    }
-  }
-
-  // Now add our field.
-  if (unionType) {
-    AppendField(CharUnits::Zero(), unionType);
-
-    if (getTypeAlignment(unionType) > layout.getAlignment()) {
-      // We need a packed struct.
-      Packed = true;
-      unionAlign = CharUnits::One();
-    }
-  }
-  if (unionAlign.isZero()) {
-    (void)hasOnlyZeroSizedBitFields;
-    assert(hasOnlyZeroSizedBitFields &&
-           "0-align record did not have all zero-sized bit-fields!");
-    unionAlign = CharUnits::One();
-  }
-
-  // Append tail padding.
-  CharUnits recordSize = layout.getSize();
-  if (recordSize > unionSize)
-    AppendPadding(recordSize, unionAlign);
-}
-
-bool CGRecordLayoutBuilder::LayoutBase(const CXXRecordDecl *base,
-                                       const CGRecordLayout &baseLayout,
-                                       CharUnits baseOffset) {
-  ResizeLastBaseFieldIfNecessary(baseOffset);
-
-  AppendPadding(baseOffset, CharUnits::One());
-
-  const ASTRecordLayout &baseASTLayout
-    = Types.getContext().getASTRecordLayout(base);
-
-  LastLaidOutBase.Offset = NextFieldOffset;
-  LastLaidOutBase.NonVirtualSize = baseASTLayout.getNonVirtualSize();
-
-  llvm::StructType *subobjectType = baseLayout.getBaseSubobjectLLVMType();
-  if (getTypeAlignment(subobjectType) > Alignment)
-    return false;
-
-  AppendField(baseOffset, subobjectType);
-  return true;
-}
-
-bool CGRecordLayoutBuilder::LayoutNonVirtualBase(const CXXRecordDecl *base,
-                                                 CharUnits baseOffset) {
-  // Ignore empty bases.
-  if (base->isEmpty()) return true;
-
-  const CGRecordLayout &baseLayout = Types.getCGRecordLayout(base);
-  if (IsZeroInitializableAsBase) {
-    assert(IsZeroInitializable &&
-           "class zero-initializable as base but not as complete object");
-
-    IsZeroInitializable = IsZeroInitializableAsBase =
-      baseLayout.isZeroInitializableAsBase();
-  }
-
-  if (!LayoutBase(base, baseLayout, baseOffset))
-    return false;
-  NonVirtualBases[base] = (FieldTypes.size() - 1);
-  return true;
-}
-
-bool
-CGRecordLayoutBuilder::LayoutVirtualBase(const CXXRecordDecl *base,
-                                         CharUnits baseOffset) {
-  // Ignore empty bases.
-  if (base->isEmpty()) return true;
-
-  const CGRecordLayout &baseLayout = Types.getCGRecordLayout(base);
-  if (IsZeroInitializable)
-    IsZeroInitializable = baseLayout.isZeroInitializableAsBase();
-
-  if (!LayoutBase(base, baseLayout, baseOffset))
-    return false;
-  VirtualBases[base] = (FieldTypes.size() - 1);
-  return true;
-}
-
-bool
-CGRecordLayoutBuilder::MSLayoutVirtualBases(const CXXRecordDecl *RD,
-                                          const ASTRecordLayout &Layout) {
-  if (!RD->getNumVBases())
-    return true;
-
-  // The vbases list is uniqued and ordered by a depth-first
-  // traversal, which is what we need here.
-  for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(),
-        E = RD->vbases_end(); I != E; ++I) {
-
-    const CXXRecordDecl *BaseDecl = 
-      cast<CXXRecordDecl>(I->getType()->castAs<RecordType>()->getDecl());
-
-    CharUnits vbaseOffset = Layout.getVBaseClassOffset(BaseDecl);
-    if (!LayoutVirtualBase(BaseDecl, vbaseOffset))
-      return false;
-  }
-  return true;
-}
-
-/// LayoutVirtualBases - layout the non-virtual bases of a record decl.
-bool
-CGRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *RD,
-                                          const ASTRecordLayout &Layout) {
-  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
-       E = RD->bases_end(); I != E; ++I) {
-    const CXXRecordDecl *BaseDecl = 
-      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
-
-    // We only want to lay out virtual bases that aren't indirect primary bases
-    // of some other base.
-    if (I->isVirtual() && !IndirectPrimaryBases.count(BaseDecl)) {
-      // Only lay out the base once.
-      if (!LaidOutVirtualBases.insert(BaseDecl))
-        continue;
-
-      CharUnits vbaseOffset = Layout.getVBaseClassOffset(BaseDecl);
-      if (!LayoutVirtualBase(BaseDecl, vbaseOffset))
-        return false;
-    }
-
-    if (!BaseDecl->getNumVBases()) {
-      // This base isn't interesting since it doesn't have any virtual bases.
-      continue;
-    }
-    
-    if (!LayoutVirtualBases(BaseDecl, Layout))
-      return false;
-  }
-  return true;
-}
-
-bool
-CGRecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD,
-                                             const ASTRecordLayout &Layout) {
-  const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
-
-  // If we have a primary base, lay it out first.
-  if (PrimaryBase) {
-    if (!Layout.isPrimaryBaseVirtual()) {
-      if (!LayoutNonVirtualBase(PrimaryBase, CharUnits::Zero()))
-        return false;
-    } else {
-      if (!LayoutVirtualBase(PrimaryBase, CharUnits::Zero()))
-        return false;
-    }
-
-  // Otherwise, add a vtable / vf-table if the layout says to do so.
-  } else if (Layout.hasOwnVFPtr()) {
-    llvm::Type *FunctionType =
-      llvm::FunctionType::get(llvm::Type::getInt32Ty(Types.getLLVMContext()),
-                              /*isVarArg=*/true);
-    llvm::Type *VTableTy = FunctionType->getPointerTo();
-
-    if (getTypeAlignment(VTableTy) > Alignment) {
-      // FIXME: Should we allow this to happen in Sema?
-      assert(!Packed && "Alignment is wrong even with packed struct!");
-      return false;
-    }
-
-    assert(NextFieldOffset.isZero() &&
-           "VTable pointer must come first!");
-    AppendField(CharUnits::Zero(), VTableTy->getPointerTo());
-  }
-
-  // Layout the non-virtual bases.
-  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
-       E = RD->bases_end(); I != E; ++I) {
-    if (I->isVirtual())
-      continue;
-
-    const CXXRecordDecl *BaseDecl = 
-      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
-
-    // We've already laid out the primary base.
-    if (BaseDecl == PrimaryBase && !Layout.isPrimaryBaseVirtual())
-      continue;
-
-    if (!LayoutNonVirtualBase(BaseDecl, Layout.getBaseClassOffset(BaseDecl)))
-      return false;
-  }
-
-  // Add a vb-table pointer if the layout insists.
-    if (Layout.hasOwnVBPtr()) {
-    CharUnits VBPtrOffset = Layout.getVBPtrOffset();
-    llvm::Type *Vbptr = llvm::Type::getInt32PtrTy(Types.getLLVMContext());
-    AppendPadding(VBPtrOffset, getTypeAlignment(Vbptr));
-    AppendField(VBPtrOffset, Vbptr);
-  }
-
-  return true;
-}
-
-bool
-CGRecordLayoutBuilder::ComputeNonVirtualBaseType(const CXXRecordDecl *RD) {
-  const ASTRecordLayout &Layout = Types.getContext().getASTRecordLayout(RD);
-
-  CharUnits NonVirtualSize  = Layout.getNonVirtualSize();
-  CharUnits NonVirtualAlign = Layout.getNonVirtualAlign();
-  CharUnits AlignedNonVirtualTypeSize =
-    NonVirtualSize.RoundUpToAlignment(NonVirtualAlign);
-  
-  // First check if we can use the same fields as for the complete class.
-  CharUnits RecordSize = Layout.getSize();
-  if (AlignedNonVirtualTypeSize == RecordSize)
-    return true;
-
-  // Check if we need padding.
-  CharUnits AlignedNextFieldOffset =
-    NextFieldOffset.RoundUpToAlignment(getAlignmentAsLLVMStruct());
-
-  if (AlignedNextFieldOffset > AlignedNonVirtualTypeSize) {
-    assert(!Packed && "cannot layout even as packed struct");
-    return false; // Needs packing.
-  }
-
-  bool needsPadding = (AlignedNonVirtualTypeSize != AlignedNextFieldOffset);
-  if (needsPadding) {
-    CharUnits NumBytes = AlignedNonVirtualTypeSize - AlignedNextFieldOffset;
-    FieldTypes.push_back(getByteArrayType(NumBytes));
-  }
-  
-  BaseSubobjectType = llvm::StructType::create(Types.getLLVMContext(),
-                                               FieldTypes, "", Packed);
-  Types.addRecordTypeName(RD, BaseSubobjectType, ".base");
-
-  // Pull the padding back off.
-  if (needsPadding)
-    FieldTypes.pop_back();
-
-  return true;
-}
-
-bool CGRecordLayoutBuilder::LayoutFields(const RecordDecl *D) {
-  assert(!D->isUnion() && "Can't call LayoutFields on a union!");
-  assert(!Alignment.isZero() && "Did not set alignment!");
-
-  const ASTRecordLayout &Layout = Types.getContext().getASTRecordLayout(D);
-
-  const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D);
-  if (RD)
-    if (!LayoutNonVirtualBases(RD, Layout))
-      return false;
-
-  unsigned FieldNo = 0;
-  
-  for (RecordDecl::field_iterator FI = D->field_begin(), FE = D->field_end();
-       FI != FE; ++FI, ++FieldNo) {
-    FieldDecl *FD = *FI;
-
-    // If this field is a bitfield, layout all of the consecutive
-    // non-zero-length bitfields and the last zero-length bitfield; these will
-    // all share storage.
-    if (FD->isBitField()) {
-      // If all we have is a zero-width bitfield, skip it.
-      if (FD->getBitWidthValue(Types.getContext()) == 0)
-        continue;
-
-      // Layout this range of bitfields.
-      if (!LayoutBitfields(Layout, FieldNo, FI, FE)) {
-        assert(!Packed &&
-               "Could not layout bitfields even with a packed LLVM struct!");
-        return false;
-      }
-      assert(FI != FE && "Advanced past the last bitfield");
-      continue;
-    }
-
-    if (!LayoutField(FD, Layout.getFieldOffset(FieldNo))) {
-      assert(!Packed &&
-             "Could not layout fields even with a packed LLVM struct!");
-      return false;
-    }
-  }
-
-  if (RD) {
-    // We've laid out the non-virtual bases and the fields, now compute the
-    // non-virtual base field types.
-    if (!ComputeNonVirtualBaseType(RD)) {
-      assert(!Packed && "Could not layout even with a packed LLVM struct!");
-      return false;
-    }
-
-    // Lay out the virtual bases.  The MS ABI uses a different
-    // algorithm here due to the lack of primary virtual bases.
-    if (Types.getTarget().getCXXABI().hasPrimaryVBases()) {
-      RD->getIndirectPrimaryBases(IndirectPrimaryBases);
-      if (Layout.isPrimaryBaseVirtual())
-        IndirectPrimaryBases.insert(Layout.getPrimaryBase());
-
-      if (!LayoutVirtualBases(RD, Layout))
-        return false;
-    } else {
-      if (!MSLayoutVirtualBases(RD, Layout))
-        return false;
-    }
-  }
-  
-  // Append tail padding if necessary.
-  AppendTailPadding(Layout.getSize());
-
-  return true;
-}
-
-void CGRecordLayoutBuilder::AppendTailPadding(CharUnits RecordSize) {
-  ResizeLastBaseFieldIfNecessary(RecordSize);
-
-  assert(NextFieldOffset <= RecordSize && "Size mismatch!");
-
-  CharUnits AlignedNextFieldOffset =
-    NextFieldOffset.RoundUpToAlignment(getAlignmentAsLLVMStruct());
-
-  if (AlignedNextFieldOffset == RecordSize) {
-    // We don't need any padding.
-    return;
-  }
-
-  CharUnits NumPadBytes = RecordSize - NextFieldOffset;
-  AppendBytes(NumPadBytes);
-}
-
-void CGRecordLayoutBuilder::AppendField(CharUnits fieldOffset,
-                                        llvm::Type *fieldType) {
-  CharUnits fieldSize =
-    CharUnits::fromQuantity(Types.getDataLayout().getTypeAllocSize(fieldType));
-
-  FieldTypes.push_back(fieldType);
-
-  NextFieldOffset = fieldOffset + fieldSize;
-}
-
-void CGRecordLayoutBuilder::AppendPadding(CharUnits fieldOffset,
-                                          CharUnits fieldAlignment) {
-  assert(NextFieldOffset <= fieldOffset &&
-         "Incorrect field layout!");
-
-  // Do nothing if we're already at the right offset.
-  if (fieldOffset == NextFieldOffset) return;
-
-  // If we're not emitting a packed LLVM type, try to avoid adding
-  // unnecessary padding fields.
-  if (!Packed) {
-    // Round up the field offset to the alignment of the field type.
-    CharUnits alignedNextFieldOffset =
-      NextFieldOffset.RoundUpToAlignment(fieldAlignment);
-    assert(alignedNextFieldOffset <= fieldOffset);
-
-    // If that's the right offset, we're done.
-    if (alignedNextFieldOffset == fieldOffset) return;
-  }
-
-  // Otherwise we need explicit padding.
-  CharUnits padding = fieldOffset - NextFieldOffset;
-  AppendBytes(padding);
-}
-
-bool CGRecordLayoutBuilder::ResizeLastBaseFieldIfNecessary(CharUnits offset) {
-  // Check if we have a base to resize.
-  if (!LastLaidOutBase.isValid())
-    return false;
-
-  // This offset does not overlap with the tail padding.
-  if (offset >= NextFieldOffset)
-    return false;
-
-  // Restore the field offset and append an i8 array instead.
-  FieldTypes.pop_back();
-  NextFieldOffset = LastLaidOutBase.Offset;
-  AppendBytes(LastLaidOutBase.NonVirtualSize);
-  LastLaidOutBase.invalidate();
-
-  return true;
-}
-
-llvm::Type *CGRecordLayoutBuilder::getByteArrayType(CharUnits numBytes) {
-  assert(!numBytes.isZero() && "Empty byte arrays aren't allowed.");
-
-  llvm::Type *Ty = llvm::Type::getInt8Ty(Types.getLLVMContext());
-  if (numBytes > CharUnits::One())
-    Ty = llvm::ArrayType::get(Ty, numBytes.getQuantity());
-
-  return Ty;
-}
-
-void CGRecordLayoutBuilder::AppendBytes(CharUnits numBytes) {
-  if (numBytes.isZero())
-    return;
-
-  // Append the padding field
-  AppendField(NextFieldOffset, getByteArrayType(numBytes));
-}
-
-CharUnits CGRecordLayoutBuilder::getTypeAlignment(llvm::Type *Ty) const {
-  if (Packed)
-    return CharUnits::One();
-
-  return CharUnits::fromQuantity(Types.getDataLayout().getABITypeAlignment(Ty));
-}
-
-CharUnits CGRecordLayoutBuilder::getAlignmentAsLLVMStruct() const {
-  if (Packed)
-    return CharUnits::One();
-
-  CharUnits maxAlignment = CharUnits::One();
-  for (size_t i = 0; i != FieldTypes.size(); ++i)
-    maxAlignment = std::max(maxAlignment, getTypeAlignment(FieldTypes[i]));
-
-  return maxAlignment;
-}
-
-/// Merge in whether a field of the given type is zero-initializable.
-void CGRecordLayoutBuilder::CheckZeroInitializable(QualType T) {
-  // This record already contains a member pointer.
-  if (!IsZeroInitializableAsBase)
-    return;
-
-  // Can only have member pointers if we're compiling C++.
-  if (!Types.getContext().getLangOpts().CPlusPlus)
-    return;
-
-  const Type *elementType = T->getBaseElementTypeUnsafe();
-
-  if (const MemberPointerType *MPT = elementType->getAs<MemberPointerType>()) {
-    if (!Types.getCXXABI().isZeroInitializable(MPT))
-      IsZeroInitializable = IsZeroInitializableAsBase = false;
-  } else if (const RecordType *RT = elementType->getAs<RecordType>()) {
-    const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
-    const CGRecordLayout &Layout = Types.getCGRecordLayout(RD);
-    if (!Layout.isZeroInitializable())
-      IsZeroInitializable = IsZeroInitializableAsBase = false;
-  }
-}
-
 CGRecordLayout *CodeGenTypes::ComputeRecordLayout(const RecordDecl *D,
                                                   llvm::StructType *Ty) {
-  CGRecordLayoutBuilder Builder(*this);
+  CGRecordLowering Builder(*this, D);
 
-  Builder.Layout(D);
-
-  Ty->setBody(Builder.FieldTypes, Builder.Packed);
+  Builder.lower(false);
 
   // If we're in C++, compute the base subobject type.
-  llvm::StructType *BaseTy = 0;
-  if (isa<CXXRecordDecl>(D) && !D->isUnion()) {
-    BaseTy = Builder.BaseSubobjectType;
-    if (!BaseTy) BaseTy = Ty;
+  llvm::StructType *BaseTy = nullptr;
+  if (isa<CXXRecordDecl>(D) && !D->isUnion() && !D->hasAttr<FinalAttr>()) {
+    BaseTy = Ty;
+    if (Builder.Layout.getNonVirtualSize() != Builder.Layout.getSize()) {
+      CGRecordLowering BaseBuilder(*this, D);
+      BaseBuilder.lower(true);
+      BaseTy = llvm::StructType::create(
+          getLLVMContext(), BaseBuilder.FieldTypes, "", BaseBuilder.Packed);
+      addRecordTypeName(D, BaseTy, ".base");
+    }
   }
 
+  // Fill in the struct *after* computing the base type.  Filling in the body
+  // signifies that the type is no longer opaque and record layout is complete,
+  // but we may need to recursively layout D while laying D out as a base type.
+  Ty->setBody(Builder.FieldTypes, Builder.Packed);
+
   CGRecordLayout *RL =
     new CGRecordLayout(Ty, BaseTy, Builder.IsZeroInitializable,
-                       Builder.IsZeroInitializableAsBase);
+                        Builder.IsZeroInitializableAsBase);
 
   RL->NonVirtualBases.swap(Builder.NonVirtualBases);
   RL->CompleteObjectVirtualBases.swap(Builder.VirtualBases);
@@ -994,12 +695,9 @@
 
   if (BaseTy) {
     CharUnits NonVirtualSize  = Layout.getNonVirtualSize();
-    CharUnits NonVirtualAlign = Layout.getNonVirtualAlign();
-    CharUnits AlignedNonVirtualTypeSize = 
-      NonVirtualSize.RoundUpToAlignment(NonVirtualAlign);
 
     uint64_t AlignedNonVirtualTypeSizeInBits = 
-      getContext().toBits(AlignedNonVirtualTypeSize);
+      getContext().toBits(NonVirtualSize);
 
     assert(AlignedNonVirtualTypeSizeInBits == 
            getDataLayout().getTypeAllocSizeInBits(BaseTy) &&
diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp
index 1eab794..53b8c33 100644
--- a/lib/CodeGen/CGStmt.cpp
+++ b/lib/CodeGen/CGStmt.cpp
@@ -16,14 +16,15 @@
 #include "CodeGenModule.h"
 #include "TargetInfo.h"
 #include "clang/AST/StmtVisitor.h"
-#include "clang/Sema/SemaDiagnostic.h"
 #include "clang/Basic/PrettyStackTrace.h"
 #include "clang/Basic/TargetInfo.h"
+#include "clang/Sema/LoopHint.h"
+#include "clang/Sema/SemaDiagnostic.h"
 #include "llvm/ADT/StringExtras.h"
+#include "llvm/IR/CallSite.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/InlineAsm.h"
 #include "llvm/IR/Intrinsics.h"
-#include "llvm/Support/CallSite.h"
 using namespace clang;
 using namespace CodeGen;
 
@@ -43,6 +44,7 @@
 
 void CodeGenFunction::EmitStmt(const Stmt *S) {
   assert(S && "Null statement?");
+  PGO.setCurrentStmt(S);
 
   // These statements have their own debug info handling.
   if (EmitSimpleStmt(S))
@@ -75,7 +77,6 @@
   case Stmt::SEHExceptStmtClass:
   case Stmt::SEHFinallyStmtClass:
   case Stmt::MSDependentExistsStmtClass:
-  case Stmt::OMPParallelDirectiveClass:
     llvm_unreachable("invalid statement class to emit generically");
   case Stmt::NullStmtClass:
   case Stmt::CompoundStmtClass:
@@ -172,6 +173,54 @@
   case Stmt::SEHTryStmtClass:
     EmitSEHTryStmt(cast<SEHTryStmt>(*S));
     break;
+  case Stmt::SEHLeaveStmtClass:
+    EmitSEHLeaveStmt(cast<SEHLeaveStmt>(*S));
+    break;
+  case Stmt::OMPParallelDirectiveClass:
+    EmitOMPParallelDirective(cast<OMPParallelDirective>(*S));
+    break;
+  case Stmt::OMPSimdDirectiveClass:
+    EmitOMPSimdDirective(cast<OMPSimdDirective>(*S));
+    break;
+  case Stmt::OMPForDirectiveClass:
+    EmitOMPForDirective(cast<OMPForDirective>(*S));
+    break;
+  case Stmt::OMPSectionsDirectiveClass:
+    EmitOMPSectionsDirective(cast<OMPSectionsDirective>(*S));
+    break;
+  case Stmt::OMPSectionDirectiveClass:
+    EmitOMPSectionDirective(cast<OMPSectionDirective>(*S));
+    break;
+  case Stmt::OMPSingleDirectiveClass:
+    EmitOMPSingleDirective(cast<OMPSingleDirective>(*S));
+    break;
+  case Stmt::OMPMasterDirectiveClass:
+    EmitOMPMasterDirective(cast<OMPMasterDirective>(*S));
+    break;
+  case Stmt::OMPCriticalDirectiveClass:
+    EmitOMPCriticalDirective(cast<OMPCriticalDirective>(*S));
+    break;
+  case Stmt::OMPParallelForDirectiveClass:
+    EmitOMPParallelForDirective(cast<OMPParallelForDirective>(*S));
+    break;
+  case Stmt::OMPParallelSectionsDirectiveClass:
+    EmitOMPParallelSectionsDirective(cast<OMPParallelSectionsDirective>(*S));
+    break;
+  case Stmt::OMPTaskDirectiveClass:
+    EmitOMPTaskDirective(cast<OMPTaskDirective>(*S));
+    break;
+  case Stmt::OMPTaskyieldDirectiveClass:
+    EmitOMPTaskyieldDirective(cast<OMPTaskyieldDirective>(*S));
+    break;
+  case Stmt::OMPBarrierDirectiveClass:
+    EmitOMPBarrierDirective(cast<OMPBarrierDirective>(*S));
+    break;
+  case Stmt::OMPTaskwaitDirectiveClass:
+    EmitOMPTaskwaitDirective(cast<OMPTaskwaitDirective>(*S));
+    break;
+  case Stmt::OMPFlushDirectiveClass:
+    EmitOMPFlushDirective(cast<OMPFlushDirective>(*S));
+    break;
   }
 }
 
@@ -217,7 +266,7 @@
        E = S.body_end()-GetLast; I != E; ++I)
     EmitStmt(*I);
 
-  llvm::Value *RetAlloca = 0;
+  llvm::Value *RetAlloca = nullptr;
   if (GetLast) {
     // We have to special case labels here.  They are statements, but when put
     // at the end of a statement expression, they yield the value of their
@@ -242,7 +291,7 @@
       EmitAnyExprToMem(cast<Expr>(LastStmt), RetAlloca, Qualifiers(),
                        /*IsInit*/false);
     }
-      
+
   }
 
   return RetAlloca;
@@ -309,9 +358,8 @@
 
 void CodeGenFunction::EmitBlockAfterUses(llvm::BasicBlock *block) {
   bool inserted = false;
-  for (llvm::BasicBlock::use_iterator
-         i = block->use_begin(), e = block->use_end(); i != e; ++i) {
-    if (llvm::Instruction *insn = dyn_cast<llvm::Instruction>(*i)) {
+  for (llvm::User *u : block->users()) {
+    if (llvm::Instruction *insn = dyn_cast<llvm::Instruction>(u)) {
       CurFn->getBasicBlockList().insertAfter(insn->getParent(), block);
       inserted = true;
       break;
@@ -358,7 +406,9 @@
     ResolveBranchFixups(Dest.getBlock());
   }
 
+  RegionCounter Cnt = getPGORegionCounter(D->getStmt());
   EmitBlock(Dest.getBlock());
+  Cnt.beginRegion(Builder);
 }
 
 /// Change the cleanup scope of the labels in this lexical scope to
@@ -391,7 +441,23 @@
 }
 
 void CodeGenFunction::EmitAttributedStmt(const AttributedStmt &S) {
-  EmitStmt(S.getSubStmt());
+  const Stmt *SubStmt = S.getSubStmt();
+  switch (SubStmt->getStmtClass()) {
+  case Stmt::DoStmtClass:
+    EmitDoStmt(cast<DoStmt>(*SubStmt), S.getAttrs());
+    break;
+  case Stmt::ForStmtClass:
+    EmitForStmt(cast<ForStmt>(*SubStmt), S.getAttrs());
+    break;
+  case Stmt::WhileStmtClass:
+    EmitWhileStmt(cast<WhileStmt>(*SubStmt), S.getAttrs());
+    break;
+  case Stmt::CXXForRangeStmtClass:
+    EmitCXXForRangeStmt(cast<CXXForRangeStmt>(*SubStmt), S.getAttrs());
+    break;
+  default:
+    EmitStmt(SubStmt);
+  }
 }
 
 void CodeGenFunction::EmitGotoStmt(const GotoStmt &S) {
@@ -429,7 +495,8 @@
 void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
   // C99 6.8.4.1: The first substatement is executed if the expression compares
   // unequal to 0.  The condition must be a scalar type.
-  LexicalScope ConditionScope(*this, S.getSourceRange());
+  LexicalScope ConditionScope(*this, S.getCond()->getSourceRange());
+  RegionCounter Cnt = getPGORegionCounter(&S);
 
   if (S.getConditionVariable())
     EmitAutoVarDecl(*S.getConditionVariable());
@@ -447,6 +514,8 @@
     // If the skipped block has no labels in it, just emit the executed block.
     // This avoids emitting dead code and simplifies the CFG substantially.
     if (!ContainsLabel(Skipped)) {
+      if (CondConstant)
+        Cnt.beginRegion(Builder);
       if (Executed) {
         RunCleanupsScope ExecutedScope(*this);
         EmitStmt(Executed);
@@ -462,10 +531,12 @@
   llvm::BasicBlock *ElseBlock = ContBlock;
   if (S.getElse())
     ElseBlock = createBasicBlock("if.else");
-  EmitBranchOnBoolExpr(S.getCond(), ThenBlock, ElseBlock);
+
+  EmitBranchOnBoolExpr(S.getCond(), ThenBlock, ElseBlock, Cnt.getCount());
 
   // Emit the 'then' code.
-  EmitBlock(ThenBlock); 
+  EmitBlock(ThenBlock);
+  Cnt.beginRegion(Builder);
   {
     RunCleanupsScope ThenScope(*this);
     EmitStmt(S.getThen());
@@ -474,30 +545,121 @@
 
   // Emit the 'else' code if present.
   if (const Stmt *Else = S.getElse()) {
-    // There is no need to emit line number for unconditional branch.
-    if (getDebugInfo())
-      Builder.SetCurrentDebugLocation(llvm::DebugLoc());
-    EmitBlock(ElseBlock);
+    {
+      // There is no need to emit line number for unconditional branch.
+      SuppressDebugLocation S(Builder);
+      EmitBlock(ElseBlock);
+    }
     {
       RunCleanupsScope ElseScope(*this);
       EmitStmt(Else);
     }
-    // There is no need to emit line number for unconditional branch.
-    if (getDebugInfo())
-      Builder.SetCurrentDebugLocation(llvm::DebugLoc());
-    EmitBranch(ContBlock);
+    {
+      // There is no need to emit line number for unconditional branch.
+      SuppressDebugLocation S(Builder);
+      EmitBranch(ContBlock);
+    }
   }
 
   // Emit the continuation block for code after the if.
   EmitBlock(ContBlock, true);
 }
 
-void CodeGenFunction::EmitWhileStmt(const WhileStmt &S) {
+void CodeGenFunction::EmitCondBrHints(llvm::LLVMContext &Context,
+                                      llvm::BranchInst *CondBr,
+                                      const ArrayRef<const Attr *> &Attrs) {
+  // Return if there are no hints.
+  if (Attrs.empty())
+    return;
+
+  // Add vectorize and unroll hints to the metadata on the conditional branch.
+  SmallVector<llvm::Value *, 2> Metadata(1);
+  for (const auto *Attr : Attrs) {
+    const LoopHintAttr *LH = dyn_cast<LoopHintAttr>(Attr);
+
+    // Skip non loop hint attributes
+    if (!LH)
+      continue;
+
+    LoopHintAttr::OptionType Option = LH->getOption();
+    int ValueInt = LH->getValue();
+
+    const char *MetadataName;
+    switch (Option) {
+    case LoopHintAttr::Vectorize:
+    case LoopHintAttr::VectorizeWidth:
+      MetadataName = "llvm.loop.vectorize.width";
+      break;
+    case LoopHintAttr::Interleave:
+    case LoopHintAttr::InterleaveCount:
+      MetadataName = "llvm.loop.interleave.count";
+      break;
+    case LoopHintAttr::Unroll:
+      MetadataName = "llvm.loop.unroll.enable";
+      break;
+    case LoopHintAttr::UnrollCount:
+      MetadataName = "llvm.loop.unroll.count";
+      break;
+    }
+
+    llvm::Value *Value;
+    llvm::MDString *Name;
+    switch (Option) {
+    case LoopHintAttr::Vectorize:
+    case LoopHintAttr::Interleave:
+      if (ValueInt == 1) {
+        // FIXME: In the future I will modifiy the behavior of the metadata
+        // so we can enable/disable vectorization and interleaving separately.
+        Name = llvm::MDString::get(Context, "llvm.loop.vectorize.enable");
+        Value = Builder.getTrue();
+        break;
+      }
+      // Vectorization/interleaving is disabled, set width/count to 1.
+      ValueInt = 1;
+      // Fallthrough.
+    case LoopHintAttr::VectorizeWidth:
+    case LoopHintAttr::InterleaveCount:
+      Name = llvm::MDString::get(Context, MetadataName);
+      Value = llvm::ConstantInt::get(Int32Ty, ValueInt);
+      break;
+    case LoopHintAttr::Unroll:
+      Name = llvm::MDString::get(Context, MetadataName);
+      Value = (ValueInt == 0) ? Builder.getFalse() : Builder.getTrue();
+      break;
+    case LoopHintAttr::UnrollCount:
+      Name = llvm::MDString::get(Context, MetadataName);
+      Value = llvm::ConstantInt::get(Int32Ty, ValueInt);
+      break;
+    }
+
+    SmallVector<llvm::Value *, 2> OpValues;
+    OpValues.push_back(Name);
+    OpValues.push_back(Value);
+
+    // Set or overwrite metadata indicated by Name.
+    Metadata.push_back(llvm::MDNode::get(Context, OpValues));
+  }
+
+  if (!Metadata.empty()) {
+    // Add llvm.loop MDNode to CondBr.
+    llvm::MDNode *LoopID = llvm::MDNode::get(Context, Metadata);
+    LoopID->replaceOperandWith(0, LoopID); // First op points to itself.
+
+    CondBr->setMetadata("llvm.loop", LoopID);
+  }
+}
+
+void CodeGenFunction::EmitWhileStmt(const WhileStmt &S,
+                                    const ArrayRef<const Attr *> &WhileAttrs) {
+  RegionCounter Cnt = getPGORegionCounter(&S);
+
   // Emit the header for the loop, which will also become
   // the continue target.
   JumpDest LoopHeader = getJumpDestInCurrentScope("while.cond");
   EmitBlock(LoopHeader.getBlock());
 
+  LoopStack.push(LoopHeader.getBlock());
+
   // Create an exit block for when the condition fails, which will
   // also become the break target.
   JumpDest LoopExit = getJumpDestInCurrentScope("while.end");
@@ -535,13 +697,17 @@
     llvm::BasicBlock *ExitBlock = LoopExit.getBlock();
     if (ConditionScope.requiresCleanups())
       ExitBlock = createBasicBlock("while.exit");
-
-    Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock);
+    llvm::BranchInst *CondBr =
+        Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock,
+                             PGO.createLoopWeights(S.getCond(), Cnt));
 
     if (ExitBlock != LoopExit.getBlock()) {
       EmitBlock(ExitBlock);
       EmitBranchThroughCleanup(LoopExit);
     }
+
+    // Attach metadata to loop body conditional branch.
+    EmitCondBrHints(LoopBody->getContext(), CondBr, WhileAttrs);
   }
 
   // Emit the loop body.  We have to emit this in a cleanup scope
@@ -549,6 +715,7 @@
   {
     RunCleanupsScope BodyScope(*this);
     EmitBlock(LoopBody);
+    Cnt.beginRegion(Builder);
     EmitStmt(S.getBody());
   }
 
@@ -560,6 +727,8 @@
   // Branch to the loop header again.
   EmitBranch(LoopHeader.getBlock());
 
+  LoopStack.pop();
+
   // Emit the exit block.
   EmitBlock(LoopExit.getBlock(), true);
 
@@ -569,23 +738,27 @@
     SimplifyForwardingBlocks(LoopHeader.getBlock());
 }
 
-void CodeGenFunction::EmitDoStmt(const DoStmt &S) {
+void CodeGenFunction::EmitDoStmt(const DoStmt &S,
+                                 const ArrayRef<const Attr *> &DoAttrs) {
   JumpDest LoopExit = getJumpDestInCurrentScope("do.end");
   JumpDest LoopCond = getJumpDestInCurrentScope("do.cond");
 
+  RegionCounter Cnt = getPGORegionCounter(&S);
+
   // Store the blocks to use for break and continue.
   BreakContinueStack.push_back(BreakContinue(LoopExit, LoopCond));
 
   // Emit the body of the loop.
   llvm::BasicBlock *LoopBody = createBasicBlock("do.body");
-  EmitBlock(LoopBody);
+
+  LoopStack.push(LoopBody);
+
+  EmitBlockWithFallThrough(LoopBody, Cnt);
   {
     RunCleanupsScope BodyScope(*this);
     EmitStmt(S.getBody());
   }
 
-  BreakContinueStack.pop_back();
-
   EmitBlock(LoopCond.getBlock());
 
   // C99 6.8.5.2: "The evaluation of the controlling expression takes place
@@ -596,6 +769,8 @@
   // compares unequal to 0.  The condition must be a scalar type.
   llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());
 
+  BreakContinueStack.pop_back();
+
   // "do {} while (0)" is common in macros, avoid extra blocks.  Be sure
   // to correctly handle break/continue though.
   bool EmitBoolCondBranch = true;
@@ -604,8 +779,16 @@
       EmitBoolCondBranch = false;
 
   // As long as the condition is true, iterate the loop.
-  if (EmitBoolCondBranch)
-    Builder.CreateCondBr(BoolCondVal, LoopBody, LoopExit.getBlock());
+  if (EmitBoolCondBranch) {
+    llvm::BranchInst *CondBr =
+        Builder.CreateCondBr(BoolCondVal, LoopBody, LoopExit.getBlock(),
+                             PGO.createLoopWeights(S.getCond(), Cnt));
+
+    // Attach metadata to loop body conditional branch.
+    EmitCondBrHints(LoopBody->getContext(), CondBr, DoAttrs);
+  }
+
+  LoopStack.pop();
 
   // Emit the exit block.
   EmitBlock(LoopExit.getBlock());
@@ -616,7 +799,8 @@
     SimplifyForwardingBlocks(LoopCond.getBlock());
 }
 
-void CodeGenFunction::EmitForStmt(const ForStmt &S) {
+void CodeGenFunction::EmitForStmt(const ForStmt &S,
+                                  const ArrayRef<const Attr *> &ForAttrs) {
   JumpDest LoopExit = getJumpDestInCurrentScope("for.end");
 
   RunCleanupsScope ForScope(*this);
@@ -629,6 +813,8 @@
   if (S.getInit())
     EmitStmt(S.getInit());
 
+  RegionCounter Cnt = getPGORegionCounter(&S);
+
   // Start the loop with a block that tests the condition.
   // If there's an increment, the continue scope will be overwritten
   // later.
@@ -636,6 +822,18 @@
   llvm::BasicBlock *CondBlock = Continue.getBlock();
   EmitBlock(CondBlock);
 
+  LoopStack.push(CondBlock);
+
+  // If the for loop doesn't have an increment we can just use the
+  // condition as the continue block.  Otherwise we'll need to create
+  // a block for it (in the current scope, i.e. in the scope of the
+  // condition), and that we will become our continue block.
+  if (S.getInc())
+    Continue = getJumpDestInCurrentScope("for.inc");
+
+  // Store the blocks to use for break and continue.
+  BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
+
   // Create a cleanup scope for the condition variable cleanups.
   RunCleanupsScope ConditionScope(*this);
 
@@ -657,7 +855,13 @@
 
     // C99 6.8.5p2/p4: The first substatement is executed if the expression
     // compares unequal to 0.  The condition must be a scalar type.
-    EmitBranchOnBoolExpr(S.getCond(), ForBody, ExitBlock);
+    llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());
+    llvm::BranchInst *CondBr =
+        Builder.CreateCondBr(BoolCondVal, ForBody, ExitBlock,
+                             PGO.createLoopWeights(S.getCond(), Cnt));
+
+    // Attach metadata to loop body conditional branch.
+    EmitCondBrHints(ForBody->getContext(), CondBr, ForAttrs);
 
     if (ExitBlock != LoopExit.getBlock()) {
       EmitBlock(ExitBlock);
@@ -669,16 +873,7 @@
     // Treat it as a non-zero constant.  Don't even create a new block for the
     // body, just fall into it.
   }
-
-  // If the for loop doesn't have an increment we can just use the
-  // condition as the continue block.  Otherwise we'll need to create
-  // a block for it (in the current scope, i.e. in the scope of the
-  // condition), and that we will become our continue block.
-  if (S.getInc())
-    Continue = getJumpDestInCurrentScope("for.inc");
-
-  // Store the blocks to use for break and continue.
-  BreakContinueStack.push_back(BreakContinue(LoopExit, Continue));
+  Cnt.beginRegion(Builder);
 
   {
     // Create a separate cleanup scope for the body, in case it is not
@@ -703,11 +898,15 @@
   if (DI)
     DI->EmitLexicalBlockEnd(Builder, S.getSourceRange().getEnd());
 
+  LoopStack.pop();
+
   // Emit the fall-through block.
   EmitBlock(LoopExit.getBlock(), true);
 }
 
-void CodeGenFunction::EmitCXXForRangeStmt(const CXXForRangeStmt &S) {
+void
+CodeGenFunction::EmitCXXForRangeStmt(const CXXForRangeStmt &S,
+                                     const ArrayRef<const Attr *> &ForAttrs) {
   JumpDest LoopExit = getJumpDestInCurrentScope("for.end");
 
   RunCleanupsScope ForScope(*this);
@@ -720,12 +919,16 @@
   EmitStmt(S.getRangeStmt());
   EmitStmt(S.getBeginEndStmt());
 
+  RegionCounter Cnt = getPGORegionCounter(&S);
+
   // Start the loop with a block that tests the condition.
   // If there's an increment, the continue scope will be overwritten
   // later.
   llvm::BasicBlock *CondBlock = createBasicBlock("for.cond");
   EmitBlock(CondBlock);
 
+  LoopStack.push(CondBlock);
+
   // If there are any cleanups between here and the loop-exit scope,
   // create a block to stage a loop exit along.
   llvm::BasicBlock *ExitBlock = LoopExit.getBlock();
@@ -737,7 +940,12 @@
 
   // The body is executed if the expression, contextually converted
   // to bool, is true.
-  EmitBranchOnBoolExpr(S.getCond(), ForBody, ExitBlock);
+  llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());
+  llvm::BranchInst *CondBr = Builder.CreateCondBr(
+      BoolCondVal, ForBody, ExitBlock, PGO.createLoopWeights(S.getCond(), Cnt));
+
+  // Attach metadata to loop body conditional branch.
+  EmitCondBrHints(ForBody->getContext(), CondBr, ForAttrs);
 
   if (ExitBlock != LoopExit.getBlock()) {
     EmitBlock(ExitBlock);
@@ -745,6 +953,7 @@
   }
 
   EmitBlock(ForBody);
+  Cnt.beginRegion(Builder);
 
   // Create a block for the increment. In case of a 'continue', we jump there.
   JumpDest Continue = getJumpDestInCurrentScope("for.inc");
@@ -772,6 +981,8 @@
   if (DI)
     DI->EmitLexicalBlockEnd(Builder, S.getSourceRange().getEnd());
 
+  LoopStack.pop();
+
   // Emit the fall-through block.
   EmitBlock(LoopExit.getBlock(), true);
 }
@@ -809,7 +1020,8 @@
 
   // FIXME: Clean this up by using an LValue for ReturnTemp,
   // EmitStoreThroughLValue, and EmitAnyExpr.
-  if (S.getNRVOCandidate() && S.getNRVOCandidate()->isNRVOVariable()) {
+  if (getLangOpts().ElideConstructors &&
+      S.getNRVOCandidate() && S.getNRVOCandidate()->isNRVOVariable()) {
     // Apply the named return value optimization for this return statement,
     // which means doing nothing: the appropriate result has already been
     // constructed into the NRVO variable.
@@ -818,12 +1030,12 @@
     // that the cleanup code should not destroy the variable.
     if (llvm::Value *NRVOFlag = NRVOFlags[S.getNRVOCandidate()])
       Builder.CreateStore(Builder.getTrue(), NRVOFlag);
-  } else if (!ReturnValue) {
+  } else if (!ReturnValue || (RV && RV->getType()->isVoidType())) {
     // Make sure not to return anything, but evaluate the expression
     // for side effects.
     if (RV)
       EmitAnyExpr(RV);
-  } else if (RV == 0) {
+  } else if (!RV) {
     // Do nothing (return value is left uninitialized)
   } else if (FnRetTy->isReferenceType()) {
     // If this function returns a reference, take the address of the expression
@@ -853,7 +1065,7 @@
   }
 
   ++NumReturnExprs;
-  if (RV == 0 || RV->isEvaluatable(getContext()))
+  if (!RV || RV->isEvaluatable(getContext()))
     ++NumSimpleReturnExprs;
 
   cleanupScope.ForceCleanup();
@@ -866,9 +1078,8 @@
   if (HaveInsertPoint())
     EmitStopPoint(&S);
 
-  for (DeclStmt::const_decl_iterator I = S.decl_begin(), E = S.decl_end();
-       I != E; ++I)
-    EmitDecl(**I);
+  for (const auto *I : S.decls())
+    EmitDecl(*I);
 }
 
 void CodeGenFunction::EmitBreakStmt(const BreakStmt &S) {
@@ -880,8 +1091,7 @@
   if (HaveInsertPoint())
     EmitStopPoint(&S);
 
-  JumpDest Block = BreakContinueStack.back().BreakBlock;
-  EmitBranchThroughCleanup(Block);
+  EmitBranchThroughCleanup(BreakContinueStack.back().BreakBlock);
 }
 
 void CodeGenFunction::EmitContinueStmt(const ContinueStmt &S) {
@@ -893,8 +1103,7 @@
   if (HaveInsertPoint())
     EmitStopPoint(&S);
 
-  JumpDest Block = BreakContinueStack.back().ContinueBlock;
-  EmitBranchThroughCleanup(Block);
+  EmitBranchThroughCleanup(BreakContinueStack.back().ContinueBlock);
 }
 
 /// EmitCaseStmtRange - If case statement range is not too big then
@@ -906,11 +1115,13 @@
   llvm::APSInt LHS = S.getLHS()->EvaluateKnownConstInt(getContext());
   llvm::APSInt RHS = S.getRHS()->EvaluateKnownConstInt(getContext());
 
+  RegionCounter CaseCnt = getPGORegionCounter(&S);
+
   // Emit the code for this case. We do this first to make sure it is
   // properly chained from our predecessor before generating the
   // switch machinery to enter this block.
-  EmitBlock(createBasicBlock("sw.bb"));
-  llvm::BasicBlock *CaseDest = Builder.GetInsertBlock();
+  llvm::BasicBlock *CaseDest = createBasicBlock("sw.bb");
+  EmitBlockWithFallThrough(CaseDest, CaseCnt);
   EmitStmt(S.getSubStmt());
 
   // If range is empty, do nothing.
@@ -921,7 +1132,18 @@
   // FIXME: parameters such as this should not be hardcoded.
   if (Range.ult(llvm::APInt(Range.getBitWidth(), 64))) {
     // Range is small enough to add multiple switch instruction cases.
-    for (unsigned i = 0, e = Range.getZExtValue() + 1; i != e; ++i) {
+    uint64_t Total = CaseCnt.getCount();
+    unsigned NCases = Range.getZExtValue() + 1;
+    // We only have one region counter for the entire set of cases here, so we
+    // need to divide the weights evenly between the generated cases, ensuring
+    // that the total weight is preserved. E.g., a weight of 5 over three cases
+    // will be distributed as weights of 2, 2, and 1.
+    uint64_t Weight = Total / NCases, Rem = Total % NCases;
+    for (unsigned I = 0; I != NCases; ++I) {
+      if (SwitchWeights)
+        SwitchWeights->push_back(Weight + (Rem ? 1 : 0));
+      if (Rem)
+        Rem--;
       SwitchInsn->addCase(Builder.getInt(LHS), CaseDest);
       LHS++;
     }
@@ -946,7 +1168,19 @@
     Builder.CreateSub(SwitchInsn->getCondition(), Builder.getInt(LHS));
   llvm::Value *Cond =
     Builder.CreateICmpULE(Diff, Builder.getInt(Range), "inbounds");
-  Builder.CreateCondBr(Cond, CaseDest, FalseDest);
+
+  llvm::MDNode *Weights = nullptr;
+  if (SwitchWeights) {
+    uint64_t ThisCount = CaseCnt.getCount();
+    uint64_t DefaultCount = (*SwitchWeights)[0];
+    Weights = PGO.createBranchWeights(ThisCount, DefaultCount);
+
+    // Since we're chaining the switch default through each large case range, we
+    // need to update the weight for the default, ie, the first case, to include
+    // this case.
+    (*SwitchWeights)[0] += ThisCount;
+  }
+  Builder.CreateCondBr(Cond, CaseDest, FalseDest, Weights);
 
   // Restore the appropriate insertion point.
   if (RestoreBB)
@@ -959,7 +1193,7 @@
   // If there is no enclosing switch instance that we're aware of, then this
   // case statement and its block can be elided.  This situation only happens
   // when we've constant-folded the switch, are emitting the constant case,
-  // and part of the constant case includes another case statement.  For 
+  // and part of the constant case includes another case statement.  For
   // instance: switch (4) { case 4: do { case 5: } while (1); }
   if (!SwitchInsn) {
     EmitStmt(S.getSubStmt());
@@ -972,17 +1206,22 @@
     return;
   }
 
+  RegionCounter CaseCnt = getPGORegionCounter(&S);
   llvm::ConstantInt *CaseVal =
     Builder.getInt(S.getLHS()->EvaluateKnownConstInt(getContext()));
 
-  // If the body of the case is just a 'break', and if there was no fallthrough,
-  // try to not emit an empty block.
-  if ((CGM.getCodeGenOpts().OptimizationLevel > 0) &&
+  // If the body of the case is just a 'break', try to not emit an empty block.
+  // If we're profiling or we're not optimizing, leave the block in for better
+  // debug and coverage analysis.
+  if (!CGM.getCodeGenOpts().ProfileInstrGenerate &&
+      CGM.getCodeGenOpts().OptimizationLevel > 0 &&
       isa<BreakStmt>(S.getSubStmt())) {
     JumpDest Block = BreakContinueStack.back().BreakBlock;
 
     // Only do this optimization if there are no cleanups that need emitting.
     if (isObviouslyBranchWithoutCleanups(Block)) {
+      if (SwitchWeights)
+        SwitchWeights->push_back(CaseCnt.getCount());
       SwitchInsn->addCase(CaseVal, Block.getBlock());
 
       // If there was a fallthrough into this case, make sure to redirect it to
@@ -995,8 +1234,10 @@
     }
   }
 
-  EmitBlock(createBasicBlock("sw.bb"));
-  llvm::BasicBlock *CaseDest = Builder.GetInsertBlock();
+  llvm::BasicBlock *CaseDest = createBasicBlock("sw.bb");
+  EmitBlockWithFallThrough(CaseDest, CaseCnt);
+  if (SwitchWeights)
+    SwitchWeights->push_back(CaseCnt.getCount());
   SwitchInsn->addCase(CaseVal, CaseDest);
 
   // Recursively emitting the statement is acceptable, but is not wonderful for
@@ -1012,10 +1253,19 @@
   const CaseStmt *NextCase = dyn_cast<CaseStmt>(S.getSubStmt());
 
   // Otherwise, iteratively add consecutive cases to this switch stmt.
-  while (NextCase && NextCase->getRHS() == 0) {
+  while (NextCase && NextCase->getRHS() == nullptr) {
     CurCase = NextCase;
-    llvm::ConstantInt *CaseVal = 
+    llvm::ConstantInt *CaseVal =
       Builder.getInt(CurCase->getLHS()->EvaluateKnownConstInt(getContext()));
+
+    CaseCnt = getPGORegionCounter(NextCase);
+    if (SwitchWeights)
+      SwitchWeights->push_back(CaseCnt.getCount());
+    if (CGM.getCodeGenOpts().ProfileInstrGenerate) {
+      CaseDest = createBasicBlock("sw.bb");
+      EmitBlockWithFallThrough(CaseDest, CaseCnt);
+    }
+
     SwitchInsn->addCase(CaseVal, CaseDest);
     NextCase = dyn_cast<CaseStmt>(CurCase->getSubStmt());
   }
@@ -1028,7 +1278,10 @@
   llvm::BasicBlock *DefaultBlock = SwitchInsn->getDefaultDest();
   assert(DefaultBlock->empty() &&
          "EmitDefaultStmt: Default block already defined?");
-  EmitBlock(DefaultBlock);
+
+  RegionCounter Cnt = getPGORegionCounter(&S);
+  EmitBlockWithFallThrough(DefaultBlock, Cnt);
+
   EmitStmt(S.getSubStmt());
 }
 
@@ -1061,7 +1314,7 @@
                                             bool &FoundCase,
                               SmallVectorImpl<const Stmt*> &ResultStmts) {
   // If this is a null statement, just succeed.
-  if (S == 0)
+  if (!S)
     return Case ? CSFC_Success : CSFC_FallThrough;
 
   // If this is the switchcase (case 4: or default) that we're looking for, then
@@ -1069,7 +1322,7 @@
   if (const SwitchCase *SC = dyn_cast<SwitchCase>(S)) {
     if (S == Case) {
       FoundCase = true;
-      return CollectStatementsForCase(SC->getSubStmt(), 0, FoundCase,
+      return CollectStatementsForCase(SC->getSubStmt(), nullptr, FoundCase,
                                       ResultStmts);
     }
 
@@ -1080,7 +1333,7 @@
 
   // If we are in the live part of the code and we found our break statement,
   // return a success!
-  if (Case == 0 && isa<BreakStmt>(S))
+  if (!Case && isa<BreakStmt>(S))
     return CSFC_Success;
 
   // If this is a switch statement, then it might contain the SwitchCase, the
@@ -1125,7 +1378,7 @@
           // statements in the compound statement as candidates for inclusion.
           assert(FoundCase && "Didn't find case but returned fallthrough?");
           // We recursively found Case, so we're not looking for it anymore.
-          Case = 0;
+          Case = nullptr;
 
           // If we found the case and skipped declarations, we can't do the
           // optimization.
@@ -1139,7 +1392,7 @@
     // If we have statements in our range, then we know that the statements are
     // live and need to be added to the set of statements we're tracking.
     for (; I != E; ++I) {
-      switch (CollectStatementsForCase(*I, 0, FoundCase, ResultStmts)) {
+      switch (CollectStatementsForCase(*I, nullptr, FoundCase, ResultStmts)) {
       case CSFC_Failure: return CSFC_Failure;
       case CSFC_FallThrough:
         // A fallthrough result means that the statement was simple and just
@@ -1185,11 +1438,12 @@
 static bool FindCaseStatementsForValue(const SwitchStmt &S,
                                        const llvm::APSInt &ConstantCondValue,
                                 SmallVectorImpl<const Stmt*> &ResultStmts,
-                                       ASTContext &C) {
+                                       ASTContext &C,
+                                       const SwitchCase *&ResultCase) {
   // First step, find the switch case that is being branched to.  We can do this
   // efficiently by scanning the SwitchCase list.
   const SwitchCase *Case = S.getSwitchCaseList();
-  const DefaultStmt *DefaultCase = 0;
+  const DefaultStmt *DefaultCase = nullptr;
 
   for (; Case; Case = Case->getNextSwitchCase()) {
     // It's either a default or case.  Just remember the default statement in
@@ -1211,10 +1465,10 @@
 
   // If we didn't find a matching case, we use a default if it exists, or we
   // elide the whole switch body!
-  if (Case == 0) {
+  if (!Case) {
     // It is safe to elide the body of the switch if it doesn't contain labels
     // etc.  If it is safe, return successfully with an empty ResultStmts list.
-    if (DefaultCase == 0)
+    if (!DefaultCase)
       return !CodeGenFunction::ContainsLabel(&S);
     Case = DefaultCase;
   }
@@ -1228,21 +1482,16 @@
   //   while (1) {
   //     case 4: ...
   bool FoundCase = false;
+  ResultCase = Case;
   return CollectStatementsForCase(S.getBody(), Case, FoundCase,
                                   ResultStmts) != CSFC_Failure &&
          FoundCase;
 }
 
 void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) {
-  JumpDest SwitchExit = getJumpDestInCurrentScope("sw.epilog");
-
-  RunCleanupsScope ConditionScope(*this);
-
-  if (S.getConditionVariable())
-    EmitAutoVarDecl(*S.getConditionVariable());
-
   // Handle nested switch statements.
   llvm::SwitchInst *SavedSwitchInsn = SwitchInsn;
+  SmallVector<uint64_t, 16> *SavedSwitchWeights = SwitchWeights;
   llvm::BasicBlock *SavedCRBlock = CaseRangeBlock;
 
   // See if we can constant fold the condition of the switch and therefore only
@@ -1250,19 +1499,31 @@
   llvm::APSInt ConstantCondValue;
   if (ConstantFoldsToSimpleInteger(S.getCond(), ConstantCondValue)) {
     SmallVector<const Stmt*, 4> CaseStmts;
+    const SwitchCase *Case = nullptr;
     if (FindCaseStatementsForValue(S, ConstantCondValue, CaseStmts,
-                                   getContext())) {
+                                   getContext(), Case)) {
+      if (Case) {
+        RegionCounter CaseCnt = getPGORegionCounter(Case);
+        CaseCnt.beginRegion(Builder);
+      }
       RunCleanupsScope ExecutedScope(*this);
 
+      // Emit the condition variable if needed inside the entire cleanup scope
+      // used by this special case for constant folded switches.
+      if (S.getConditionVariable())
+        EmitAutoVarDecl(*S.getConditionVariable());
+
       // At this point, we are no longer "within" a switch instance, so
       // we can temporarily enforce this to ensure that any embedded case
       // statements are not emitted.
-      SwitchInsn = 0;
+      SwitchInsn = nullptr;
 
       // Okay, we can dead code eliminate everything except this case.  Emit the
       // specified series of statements and we're good.
       for (unsigned i = 0, e = CaseStmts.size(); i != e; ++i)
         EmitStmt(CaseStmts[i]);
+      RegionCounter ExitCnt = getPGORegionCounter(&S);
+      ExitCnt.beginRegion(Builder);
 
       // Now we want to restore the saved switch instance so that nested
       // switches continue to function properly
@@ -1272,6 +1533,11 @@
     }
   }
 
+  JumpDest SwitchExit = getJumpDestInCurrentScope("sw.epilog");
+
+  RunCleanupsScope ConditionScope(*this);
+  if (S.getConditionVariable())
+    EmitAutoVarDecl(*S.getConditionVariable());
   llvm::Value *CondV = EmitScalarExpr(S.getCond());
 
   // Create basic block to hold stuff that comes after switch
@@ -1280,12 +1546,29 @@
   // failure.
   llvm::BasicBlock *DefaultBlock = createBasicBlock("sw.default");
   SwitchInsn = Builder.CreateSwitch(CondV, DefaultBlock);
+  if (PGO.haveRegionCounts()) {
+    // Walk the SwitchCase list to find how many there are.
+    uint64_t DefaultCount = 0;
+    unsigned NumCases = 0;
+    for (const SwitchCase *Case = S.getSwitchCaseList();
+         Case;
+         Case = Case->getNextSwitchCase()) {
+      if (isa<DefaultStmt>(Case))
+        DefaultCount = getPGORegionCounter(Case).getCount();
+      NumCases += 1;
+    }
+    SwitchWeights = new SmallVector<uint64_t, 16>();
+    SwitchWeights->reserve(NumCases);
+    // The default needs to be first. We store the edge count, so we already
+    // know the right weight.
+    SwitchWeights->push_back(DefaultCount);
+  }
   CaseRangeBlock = DefaultBlock;
 
   // Clear the insertion point to indicate we are in unreachable code.
   Builder.ClearInsertionPoint();
 
-  // All break statements jump to NextBlock. If BreakContinueStack is non empty
+  // All break statements jump to NextBlock. If BreakContinueStack is non-empty
   // then reuse last ContinueBlock.
   JumpDest OuterContinue;
   if (!BreakContinueStack.empty())
@@ -1320,14 +1603,26 @@
 
   // Emit continuation.
   EmitBlock(SwitchExit.getBlock(), true);
+  RegionCounter ExitCnt = getPGORegionCounter(&S);
+  ExitCnt.beginRegion(Builder);
 
+  if (SwitchWeights) {
+    assert(SwitchWeights->size() == 1 + SwitchInsn->getNumCases() &&
+           "switch weights do not match switch cases");
+    // If there's only one jump destination there's no sense weighting it.
+    if (SwitchWeights->size() > 1)
+      SwitchInsn->setMetadata(llvm::LLVMContext::MD_prof,
+                              PGO.createBranchWeights(*SwitchWeights));
+    delete SwitchWeights;
+  }
   SwitchInsn = SavedSwitchInsn;
+  SwitchWeights = SavedSwitchWeights;
   CaseRangeBlock = SavedCRBlock;
 }
 
 static std::string
 SimplifyConstraint(const char *Constraint, const TargetInfo &Target,
-                 SmallVectorImpl<TargetInfo::ConstraintInfo> *OutCons=0) {
+                 SmallVectorImpl<TargetInfo::ConstraintInfo> *OutCons=nullptr) {
   std::string Result;
 
   while (*Constraint) {
@@ -1493,7 +1788,7 @@
       Name = GAS->getOutputName(i);
     TargetInfo::ConstraintInfo Info(S.getOutputConstraint(i), Name);
     bool IsValid = getTarget().validateOutputConstraint(Info); (void)IsValid;
-    assert(IsValid && "Failed to parse output constraint"); 
+    assert(IsValid && "Failed to parse output constraint");
     OutputConstraintInfos.push_back(Info);
   }
 
@@ -1803,20 +2098,32 @@
   return SlotLV;
 }
 
+static void InitVLACaptures(CodeGenFunction &CGF, const CapturedStmt &S) {
+  for (auto &C : S.captures()) {
+    if (C.capturesVariable()) {
+      QualType QTy;
+      auto VD = C.getCapturedVar();
+      if (const ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(VD))
+        QTy = PVD->getOriginalType();
+      else
+        QTy = VD->getType();
+      if (QTy->isVariablyModifiedType()) {
+        CGF.EmitVariablyModifiedType(QTy);
+      }
+    }
+  }
+}
+
 /// Generate an outlined function for the body of a CapturedStmt, store any
 /// captured variables into the captured struct, and call the outlined function.
 llvm::Function *
 CodeGenFunction::EmitCapturedStmt(const CapturedStmt &S, CapturedRegionKind K) {
-  const CapturedDecl *CD = S.getCapturedDecl();
-  const RecordDecl *RD = S.getCapturedRecordDecl();
-  assert(CD->hasBody() && "missing CapturedDecl body");
-
   LValue CapStruct = InitCapturedStruct(*this, S);
 
   // Emit the CapturedDecl
   CodeGenFunction CGF(CGM, true);
   CGF.CapturedStmtInfo = new CGCapturedStmtInfo(S, K);
-  llvm::Function *F = CGF.GenerateCapturedStmtFunction(CD, RD, S.getLocStart());
+  llvm::Function *F = CGF.GenerateCapturedStmtFunction(S);
   delete CGF.CapturedStmtInfo;
 
   // Emit call to the helper function.
@@ -1825,13 +2132,21 @@
   return F;
 }
 
+llvm::Value *
+CodeGenFunction::GenerateCapturedStmtArgument(const CapturedStmt &S) {
+  LValue CapStruct = InitCapturedStruct(*this, S);
+  return CapStruct.getAddress();
+}
+
 /// Creates the outlined function for a CapturedStmt.
 llvm::Function *
-CodeGenFunction::GenerateCapturedStmtFunction(const CapturedDecl *CD,
-                                              const RecordDecl *RD,
-                                              SourceLocation Loc) {
+CodeGenFunction::GenerateCapturedStmtFunction(const CapturedStmt &S) {
   assert(CapturedStmtInfo &&
     "CapturedStmtInfo should be set when generating the captured function");
+  const CapturedDecl *CD = S.getCapturedDecl();
+  const RecordDecl *RD = S.getCapturedRecordDecl();
+  SourceLocation Loc = S.getLocStart();
+  assert(CD->hasBody() && "missing CapturedDecl body");
 
   // Build the argument list.
   ASTContext &Ctx = CGM.getContext();
@@ -1841,8 +2156,8 @@
   // Create the function declaration.
   FunctionType::ExtInfo ExtInfo;
   const CGFunctionInfo &FuncInfo =
-    CGM.getTypes().arrangeFunctionDeclaration(Ctx.VoidTy, Args, ExtInfo,
-                                              /*IsVariadic=*/false);
+      CGM.getTypes().arrangeFreeFunctionDeclaration(Ctx.VoidTy, Args, ExtInfo,
+                                                    /*IsVariadic=*/false);
   llvm::FunctionType *FuncLLVMTy = CGM.getTypes().GetFunctionType(FuncInfo);
 
   llvm::Function *F =
@@ -1851,13 +2166,17 @@
   CGM.SetInternalFunctionAttributes(CD, F, FuncInfo);
 
   // Generate the function.
-  StartFunction(CD, Ctx.VoidTy, F, FuncInfo, Args, CD->getBody()->getLocStart());
-
+  StartFunction(CD, Ctx.VoidTy, F, FuncInfo, Args,
+                CD->getLocation(),
+                CD->getBody()->getLocStart());
   // Set the context parameter in CapturedStmtInfo.
   llvm::Value *DeclPtr = LocalDeclMap[CD->getContextParam()];
   assert(DeclPtr && "missing context parameter for CapturedStmt");
   CapturedStmtInfo->setContextValue(Builder.CreateLoad(DeclPtr));
 
+  // Initialize variable-length arrays.
+  InitVLACaptures(*this, S);
+
   // If 'this' is captured, load it into CXXThisValue.
   if (CapturedStmtInfo->isCXXThisExprCaptured()) {
     FieldDecl *FD = CapturedStmtInfo->getThisFieldDecl();
@@ -1867,8 +2186,11 @@
     CXXThisValue = EmitLoadOfLValue(ThisLValue, Loc).getScalarVal();
   }
 
+  PGO.assignRegionCounters(CD, F);
   CapturedStmtInfo->EmitBody(*this, CD->getBody());
   FinishFunction(CD->getBodyRBrace());
+  PGO.emitInstrumentationData();
+  PGO.destroyRegionCounters();
 
   return F;
 }
diff --git a/lib/CodeGen/CGStmtOpenMP.cpp b/lib/CodeGen/CGStmtOpenMP.cpp
new file mode 100644
index 0000000..867f415
--- /dev/null
+++ b/lib/CodeGen/CGStmtOpenMP.cpp
@@ -0,0 +1,130 @@
+//===--- CGStmtOpenMP.cpp - Emit LLVM Code from Statements ----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This contains code to emit OpenMP nodes as LLVM code.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CGOpenMPRuntime.h"
+#include "CodeGenFunction.h"
+#include "CodeGenModule.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtOpenMP.h"
+using namespace clang;
+using namespace CodeGen;
+
+//===----------------------------------------------------------------------===//
+//                              OpenMP Directive Emission
+//===----------------------------------------------------------------------===//
+
+void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) {
+  const CapturedStmt *CS = cast<CapturedStmt>(S.getAssociatedStmt());
+  llvm::Value *CapturedStruct = GenerateCapturedStmtArgument(*CS);
+
+  llvm::Value *OutlinedFn;
+  {
+    CodeGenFunction CGF(CGM, true);
+    CGCapturedStmtInfo CGInfo(*CS, CS->getCapturedRegionKind());
+    CGF.CapturedStmtInfo = &CGInfo;
+    OutlinedFn = CGF.GenerateCapturedStmtFunction(*CS);
+  }
+
+  // Build call __kmpc_fork_call(loc, 1, microtask, captured_struct/*context*/)
+  llvm::Value *Args[] = {
+      CGM.getOpenMPRuntime().EmitOpenMPUpdateLocation(*this, S.getLocStart()),
+      Builder.getInt32(1), // Number of arguments after 'microtask' argument
+      // (there is only one additional argument - 'context')
+      Builder.CreateBitCast(OutlinedFn,
+                            CGM.getOpenMPRuntime().getKmpc_MicroPointerTy()),
+      EmitCastToVoidPtr(CapturedStruct)};
+  llvm::Constant *RTLFn = CGM.getOpenMPRuntime().CreateRuntimeFunction(
+      CGOpenMPRuntime::OMPRTL__kmpc_fork_call);
+  EmitRuntimeCall(RTLFn, Args);
+}
+
+void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {
+  const CapturedStmt *CS = cast<CapturedStmt>(S.getAssociatedStmt());
+  const Stmt *Body = CS->getCapturedStmt();
+  LoopStack.setParallel();
+  LoopStack.setVectorizerEnable(true);
+  for (auto C : S.clauses()) {
+    switch (C->getClauseKind()) {
+    case OMPC_safelen: {
+      RValue Len = EmitAnyExpr(cast<OMPSafelenClause>(C)->getSafelen(),
+                               AggValueSlot::ignored(), true);
+      llvm::ConstantInt *Val = cast<llvm::ConstantInt>(Len.getScalarVal());
+      LoopStack.setVectorizerWidth(Val->getZExtValue());
+      // In presence of finite 'safelen', it may be unsafe to mark all
+      // the memory instructions parallel, because loop-carried
+      // dependences of 'safelen' iterations are possible.
+      LoopStack.setParallel(false);
+      break;
+    }
+    default:
+      // Not handled yet
+      ;
+    }
+  }
+  EmitStmt(Body);
+}
+
+void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &) {
+  llvm_unreachable("CodeGen for 'omp for' is not supported yet.");
+}
+
+void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &) {
+  llvm_unreachable("CodeGen for 'omp sections' is not supported yet.");
+}
+
+void CodeGenFunction::EmitOMPSectionDirective(const OMPSectionDirective &) {
+  llvm_unreachable("CodeGen for 'omp section' is not supported yet.");
+}
+
+void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &) {
+  llvm_unreachable("CodeGen for 'omp single' is not supported yet.");
+}
+
+void CodeGenFunction::EmitOMPMasterDirective(const OMPMasterDirective &) {
+  llvm_unreachable("CodeGen for 'omp master' is not supported yet.");
+}
+
+void CodeGenFunction::EmitOMPCriticalDirective(const OMPCriticalDirective &) {
+  llvm_unreachable("CodeGen for 'omp critical' is not supported yet.");
+}
+
+void
+CodeGenFunction::EmitOMPParallelForDirective(const OMPParallelForDirective &) {
+  llvm_unreachable("CodeGen for 'omp parallel for' is not supported yet.");
+}
+
+void CodeGenFunction::EmitOMPParallelSectionsDirective(
+    const OMPParallelSectionsDirective &) {
+  llvm_unreachable("CodeGen for 'omp parallel sections' is not supported yet.");
+}
+
+void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &) {
+  llvm_unreachable("CodeGen for 'omp task' is not supported yet.");
+}
+
+void CodeGenFunction::EmitOMPTaskyieldDirective(const OMPTaskyieldDirective &) {
+  llvm_unreachable("CodeGen for 'omp taskyield' is not supported yet.");
+}
+
+void CodeGenFunction::EmitOMPBarrierDirective(const OMPBarrierDirective &) {
+  llvm_unreachable("CodeGen for 'omp barrier' is not supported yet.");
+}
+
+void CodeGenFunction::EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &) {
+  llvm_unreachable("CodeGen for 'omp taskwait' is not supported yet.");
+}
+
+void CodeGenFunction::EmitOMPFlushDirective(const OMPFlushDirective &) {
+  llvm_unreachable("CodeGen for 'omp flush' is not supported yet.");
+}
+
diff --git a/lib/CodeGen/CGVTT.cpp b/lib/CodeGen/CGVTT.cpp
index bfff470..bd280ea 100644
--- a/lib/CodeGen/CGVTT.cpp
+++ b/lib/CodeGen/CGVTT.cpp
@@ -66,7 +66,8 @@
     if (VTTVT.getBase() == RD) {
       // Just get the address point for the regular vtable.
       AddressPoint =
-          ItaniumVTContext.getVTableLayout(RD).getAddressPoint(i->VTableBase);
+          getItaniumVTableContext().getVTableLayout(RD).getAddressPoint(
+              i->VTableBase);
       assert(AddressPoint != 0 && "Did not find vtable address point!");
     } else {
       AddressPoint = VTableAddressPoints[i->VTableIndex].lookup(i->VTableBase);
@@ -94,7 +95,7 @@
   VTT->setLinkage(Linkage);
 
   // Set the right visibility.
-  CGM.setTypeVisibility(VTT, RD, CodeGenModule::TVK_ForVTT);
+  CGM.setGlobalVisibility(VTT, RD);
 }
 
 llvm::GlobalVariable *CodeGenVTables::GetAddrOfVTT(const CXXRecordDecl *RD) {
diff --git a/lib/CodeGen/CGVTables.cpp b/lib/CodeGen/CGVTables.cpp
index 42e22f0..0df2c43 100644
--- a/lib/CodeGen/CGVTables.cpp
+++ b/lib/CodeGen/CGVTables.cpp
@@ -30,14 +30,7 @@
 using namespace CodeGen;
 
 CodeGenVTables::CodeGenVTables(CodeGenModule &CGM)
-  : CGM(CGM), ItaniumVTContext(CGM.getContext()) {
-  if (CGM.getTarget().getCXXABI().isMicrosoft()) {
-    // FIXME: Eventually, we should only have one of V*TContexts available.
-    // Today we use both in the Microsoft ABI as MicrosoftVFTableContext
-    // is not completely supported in CodeGen yet.
-    MicrosoftVTContext.reset(new MicrosoftVTableContext(CGM.getContext()));
-  }
-}
+    : CGM(CGM), VTContext(CGM.getContext().getVTableContext()) {}
 
 llvm::Constant *CodeGenModule::GetAddrOfThunk(GlobalDecl GD, 
                                               const ThunkInfo &Thunk) {
@@ -54,54 +47,13 @@
   Out.flush();
 
   llvm::Type *Ty = getTypes().GetFunctionTypeForVTable(GD);
-  return GetOrCreateLLVMFunction(Name, Ty, GD, /*ForVTable=*/true);
+  return GetOrCreateLLVMFunction(Name, Ty, GD, /*ForVTable=*/true,
+                                 /*DontDefer*/ true);
 }
 
 static void setThunkVisibility(CodeGenModule &CGM, const CXXMethodDecl *MD,
                                const ThunkInfo &Thunk, llvm::Function *Fn) {
   CGM.setGlobalVisibility(Fn, MD);
-
-  if (!CGM.getCodeGenOpts().HiddenWeakVTables)
-    return;
-
-  // If the thunk has weak/linkonce linkage, but the function must be
-  // emitted in every translation unit that references it, then we can
-  // emit its thunks with hidden visibility, since its thunks must be
-  // emitted when the function is.
-
-  // This follows CodeGenModule::setTypeVisibility; see the comments
-  // there for explanation.
-
-  if ((Fn->getLinkage() != llvm::GlobalVariable::LinkOnceODRLinkage &&
-       Fn->getLinkage() != llvm::GlobalVariable::WeakODRLinkage) ||
-      Fn->getVisibility() != llvm::GlobalVariable::DefaultVisibility)
-    return;
-
-  if (MD->getExplicitVisibility(ValueDecl::VisibilityForValue))
-    return;
-
-  switch (MD->getTemplateSpecializationKind()) {
-  case TSK_ExplicitInstantiationDefinition:
-  case TSK_ExplicitInstantiationDeclaration:
-    return;
-
-  case TSK_Undeclared:
-    break;
-
-  case TSK_ExplicitSpecialization:
-  case TSK_ImplicitInstantiation:
-    return;
-    break;
-  }
-
-  // If there's an explicit definition, and that definition is
-  // out-of-line, then we can't assume that all users will have a
-  // definition to emit.
-  const FunctionDecl *Def = 0;
-  if (MD->hasBody(Def) && Def->isOutOfLine())
-    return;
-
-  Fn->setVisibility(llvm::GlobalValue::HiddenVisibility);
 }
 
 #ifndef NDEBUG
@@ -119,11 +71,11 @@
                                       const ThunkInfo &Thunk) {
   // Emit the return adjustment.
   bool NullCheckValue = !ResultType->isReferenceType();
-  
-  llvm::BasicBlock *AdjustNull = 0;
-  llvm::BasicBlock *AdjustNotNull = 0;
-  llvm::BasicBlock *AdjustEnd = 0;
-  
+
+  llvm::BasicBlock *AdjustNull = nullptr;
+  llvm::BasicBlock *AdjustNotNull = nullptr;
+  llvm::BasicBlock *AdjustEnd = nullptr;
+
   llvm::Value *ReturnValue = RV.getScalarVal();
 
   if (NullCheckValue) {
@@ -177,7 +129,7 @@
                                       GlobalDecl GD, const ThunkInfo &Thunk) {
   const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
   const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
-  QualType ResultType = FPT->getResultType();
+  QualType ResultType = FPT->getReturnType();
 
   // Get the original function
   assert(FnInfo.isVariadic());
@@ -207,7 +159,7 @@
   // with "this".
   llvm::Value *ThisPtr = &*AI;
   llvm::BasicBlock *EntryBB = Fn->begin();
-  llvm::Instruction *ThisStore = 0;
+  llvm::Instruction *ThisStore = nullptr;
   for (llvm::BasicBlock::iterator I = EntryBB->begin(), E = EntryBB->end();
        I != E; I++) {
     if (isa<llvm::StoreInst>(I) && I->getOperand(0) == ThisPtr) {
@@ -248,11 +200,11 @@
   QualType ThisType = MD->getThisType(getContext());
   const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
   QualType ResultType =
-    CGM.getCXXABI().HasThisReturn(GD) ? ThisType : FPT->getResultType();
+      CGM.getCXXABI().HasThisReturn(GD) ? ThisType : FPT->getReturnType();
   FunctionArgList FunctionArgs;
 
   // Create the implicit 'this' parameter declaration.
-  CGM.getCXXABI().BuildInstanceFunctionParams(*this, ResultType, FunctionArgs);
+  CGM.getCXXABI().buildThisParam(*this, FunctionArgs);
 
   // Add the rest of the parameters.
   for (FunctionDecl::param_const_iterator I = MD->param_begin(),
@@ -260,9 +212,12 @@
        I != E; ++I)
     FunctionArgs.push_back(*I);
 
+  if (isa<CXXDestructorDecl>(MD))
+    CGM.getCXXABI().addImplicitStructorParams(*this, ResultType, FunctionArgs);
+
   // Start defining the function.
   StartFunction(GlobalDecl(), ResultType, Fn, FnInfo, FunctionArgs,
-                SourceLocation());
+                MD->getLocation(), SourceLocation());
 
   // Since we didn't pass a GlobalDecl to StartFunction, do this ourselves.
   CGM.getCXXABI().EmitInstanceFunctionProlog(*this);
@@ -316,7 +271,7 @@
 
   // Determine whether we have a return value slot to use.
   QualType ResultType =
-    CGM.getCXXABI().HasThisReturn(GD) ? ThisType : FPT->getResultType();
+      CGM.getCXXABI().HasThisReturn(GD) ? ThisType : FPT->getReturnType();
   ReturnValueSlot Slot;
   if (!ResultType->isVoidType() &&
       CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect &&
@@ -366,27 +321,30 @@
   const CGFunctionInfo &FnInfo = CGM.getTypes().arrangeGlobalDeclaration(GD);
 
   // FIXME: re-use FnInfo in this computation.
-  llvm::Constant *Entry = CGM.GetAddrOfThunk(GD, Thunk);
-  
+  llvm::Constant *C = CGM.GetAddrOfThunk(GD, Thunk);
+  llvm::GlobalValue *Entry;
+
   // Strip off a bitcast if we got one back.
-  if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Entry)) {
+  if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(C)) {
     assert(CE->getOpcode() == llvm::Instruction::BitCast);
-    Entry = CE->getOperand(0);
+    Entry = cast<llvm::GlobalValue>(CE->getOperand(0));
+  } else {
+    Entry = cast<llvm::GlobalValue>(C);
   }
-  
+
   // There's already a declaration with the same name, check if it has the same
   // type or if we need to replace it.
-  if (cast<llvm::GlobalValue>(Entry)->getType()->getElementType() != 
+  if (Entry->getType()->getElementType() !=
       CGM.getTypes().GetFunctionTypeForVTable(GD)) {
-    llvm::GlobalValue *OldThunkFn = cast<llvm::GlobalValue>(Entry);
-    
+    llvm::GlobalValue *OldThunkFn = Entry;
+
     // If the types mismatch then we have to rewrite the definition.
     assert(OldThunkFn->isDeclaration() &&
            "Shouldn't replace non-declaration");
 
     // Remove the name from the old thunk function and get a new thunk.
     OldThunkFn->setName(StringRef());
-    Entry = CGM.GetAddrOfThunk(GD, Thunk);
+    Entry = cast<llvm::GlobalValue>(CGM.GetAddrOfThunk(GD, Thunk));
     
     // If needed, replace the old thunk with a bitcast.
     if (!OldThunkFn->use_empty()) {
@@ -422,14 +380,17 @@
     // expensive/sucky at the moment, so don't generate the thunk unless
     // we have to.
     // FIXME: Do something better here; GenerateVarArgsThunk is extremely ugly.
-    if (!UseAvailableExternallyLinkage)
+    if (!UseAvailableExternallyLinkage) {
       CodeGenFunction(CGM).GenerateVarArgsThunk(ThunkFn, FnInfo, GD, Thunk);
+      CGM.getCXXABI().setThunkLinkage(ThunkFn, ForVTable, GD,
+                                      !Thunk.Return.isEmpty());
+    }
   } else {
     // Normal thunk body generation.
     CodeGenFunction(CGM).GenerateThunk(ThunkFn, FnInfo, GD, Thunk);
+    CGM.getCXXABI().setThunkLinkage(ThunkFn, ForVTable, GD,
+                                    !Thunk.Return.isEmpty());
   }
-
-  CGM.getCXXABI().setThunkLinkage(ThunkFn, ForVTable);
 }
 
 void CodeGenVTables::maybeEmitThunkForVTable(GlobalDecl GD,
@@ -460,12 +421,8 @@
   if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base)
     return;
 
-  const VTableContextBase::ThunkInfoVectorTy *ThunkInfoVector;
-  if (MicrosoftVTContext.isValid()) {
-    ThunkInfoVector = MicrosoftVTContext->getThunkInfo(GD);
-  } else {
-    ThunkInfoVector = ItaniumVTContext.getThunkInfo(GD);
-  }
+  const VTableContextBase::ThunkInfoVectorTy *ThunkInfoVector =
+      VTContext->getThunkInfo(GD);
 
   if (!ThunkInfoVector)
     return;
@@ -474,12 +431,10 @@
     emitThunk(GD, (*ThunkInfoVector)[I], /*ForVTable=*/false);
 }
 
-llvm::Constant *
-CodeGenVTables::CreateVTableInitializer(const CXXRecordDecl *RD,
-                                        const VTableComponent *Components, 
-                                        unsigned NumComponents,
-                                const VTableLayout::VTableThunkTy *VTableThunks,
-                                        unsigned NumVTableThunks) {
+llvm::Constant *CodeGenVTables::CreateVTableInitializer(
+    const CXXRecordDecl *RD, const VTableComponent *Components,
+    unsigned NumComponents, const VTableLayout::VTableThunkTy *VTableThunks,
+    unsigned NumVTableThunks, llvm::Constant *RTTI) {
   SmallVector<llvm::Constant *, 64> Inits;
 
   llvm::Type *Int8PtrTy = CGM.Int8PtrTy;
@@ -487,17 +442,14 @@
   llvm::Type *PtrDiffTy = 
     CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType());
 
-  QualType ClassType = CGM.getContext().getTagDeclType(RD);
-  llvm::Constant *RTTI = CGM.GetAddrOfRTTIDescriptor(ClassType);
-  
   unsigned NextVTableThunkIndex = 0;
-  
-  llvm::Constant *PureVirtualFn = 0, *DeletedVirtualFn = 0;
+
+  llvm::Constant *PureVirtualFn = nullptr, *DeletedVirtualFn = nullptr;
 
   for (unsigned I = 0; I != NumComponents; ++I) {
     VTableComponent Component = Components[I];
 
-    llvm::Constant *Init = 0;
+    llvm::Constant *Init = nullptr;
 
     switch (Component.getKind()) {
     case VTableComponent::CK_VCallOffset:
@@ -602,8 +554,8 @@
   if (CGDebugInfo *DI = CGM.getModuleDebugInfo())
     DI->completeClassData(Base.getBase());
 
-  OwningPtr<VTableLayout> VTLayout(
-      ItaniumVTContext.createConstructionVTableLayout(
+  std::unique_ptr<VTableLayout> VTLayout(
+      getItaniumVTableContext().createConstructionVTableLayout(
           Base.getBase(), Base.getBaseOffset(), BaseIsVirtual, RD));
 
   // Add the address points.
@@ -632,18 +584,19 @@
   // Create the variable that will hold the construction vtable.
   llvm::GlobalVariable *VTable = 
     CGM.CreateOrReplaceCXXRuntimeVariable(Name, ArrayType, Linkage);
-  CGM.setTypeVisibility(VTable, RD, CodeGenModule::TVK_ForConstructionVTable);
+  CGM.setGlobalVisibility(VTable, RD);
 
   // V-tables are always unnamed_addr.
   VTable->setUnnamedAddr(true);
 
+  llvm::Constant *RTTI = CGM.GetAddrOfRTTIDescriptor(
+      CGM.getContext().getTagDeclType(Base.getBase()));
+
   // Create and set the initializer.
-  llvm::Constant *Init = 
-    CreateVTableInitializer(Base.getBase(), 
-                            VTLayout->vtable_component_begin(), 
-                            VTLayout->getNumVTableComponents(),
-                            VTLayout->vtable_thunk_begin(),
-                            VTLayout->getNumVTableThunks());
+  llvm::Constant *Init = CreateVTableInitializer(
+      Base.getBase(), VTLayout->vtable_component_begin(),
+      VTLayout->getNumVTableComponents(), VTLayout->vtable_thunk_begin(),
+      VTLayout->getNumVTableThunks(), RTTI);
   VTable->setInitializer(Init);
   
   return VTable;
@@ -662,7 +615,7 @@
   if (const CXXMethodDecl *keyFunction = Context.getCurrentKeyFunction(RD)) {
     // If this class has a key function, use that to determine the
     // linkage of the vtable.
-    const FunctionDecl *def = 0;
+    const FunctionDecl *def = nullptr;
     if (keyFunction->hasBody(def))
       keyFunction = cast<CXXMethodDecl>(def);
     
@@ -696,18 +649,31 @@
   // internal linkage.
   if (Context.getLangOpts().AppleKext)
     return llvm::Function::InternalLinkage;
-  
+
+  llvm::GlobalVariable::LinkageTypes DiscardableODRLinkage =
+      llvm::GlobalValue::LinkOnceODRLinkage;
+  llvm::GlobalVariable::LinkageTypes NonDiscardableODRLinkage =
+      llvm::GlobalValue::WeakODRLinkage;
+  if (RD->hasAttr<DLLExportAttr>()) {
+    // Cannot discard exported vtables.
+    DiscardableODRLinkage = NonDiscardableODRLinkage;
+  } else if (RD->hasAttr<DLLImportAttr>()) {
+    // Imported vtables are available externally.
+    DiscardableODRLinkage = llvm::GlobalVariable::AvailableExternallyLinkage;
+    NonDiscardableODRLinkage = llvm::GlobalVariable::AvailableExternallyLinkage;
+  }
+
   switch (RD->getTemplateSpecializationKind()) {
   case TSK_Undeclared:
   case TSK_ExplicitSpecialization:
   case TSK_ImplicitInstantiation:
-    return llvm::GlobalVariable::LinkOnceODRLinkage;
+    return DiscardableODRLinkage;
 
   case TSK_ExplicitInstantiationDeclaration:
     llvm_unreachable("Should not have been asked to emit this");
 
   case TSK_ExplicitInstantiationDefinition:
-      return llvm::GlobalVariable::WeakODRLinkage;
+    return NonDiscardableODRLinkage;
   }
 
   llvm_unreachable("Invalid TemplateSpecializationKind!");
@@ -751,7 +717,7 @@
 /// strongly elsewhere.  Otherwise, we'd just like to avoid emitting
 /// v-tables when unnecessary.
 bool CodeGenVTables::isVTableExternal(const CXXRecordDecl *RD) {
-  assert(RD->isDynamicClass() && "Non dynamic classes have no VTable.");
+  assert(RD->isDynamicClass() && "Non-dynamic classes have no VTable.");
 
   // If we have an explicit instantiation declaration (and not a
   // definition), the v-table is defined elsewhere.
diff --git a/lib/CodeGen/CGVTables.h b/lib/CodeGen/CGVTables.h
index e8cd55e..69cf079 100644
--- a/lib/CodeGen/CGVTables.h
+++ b/lib/CodeGen/CGVTables.h
@@ -31,11 +31,8 @@
 class CodeGenVTables {
   CodeGenModule &CGM;
 
-  // FIXME: Consider moving ItaniumVTContext and MicrosoftVTContext into
-  // respective CXXABI classes?
-  ItaniumVTableContext ItaniumVTContext;
-  OwningPtr<MicrosoftVTableContext> MicrosoftVTContext;
-  
+  VTableContextBase *VTContext;
+
   /// VTableAddressPointsMapTy - Address points for a single vtable.
   typedef llvm::DenseMap<BaseSubobject, uint64_t> VTableAddressPointsMapTy;
 
@@ -64,18 +61,19 @@
   /// decl.
   /// \param Components - The vtable components; this is really an array of
   /// VTableComponents.
-  llvm::Constant *CreateVTableInitializer(const CXXRecordDecl *RD,
-                                          const VTableComponent *Components, 
-                                          unsigned NumComponents,
-                                const VTableLayout::VTableThunkTy *VTableThunks,
-                                          unsigned NumVTableThunks);
+  llvm::Constant *CreateVTableInitializer(
+      const CXXRecordDecl *RD, const VTableComponent *Components,
+      unsigned NumComponents, const VTableLayout::VTableThunkTy *VTableThunks,
+      unsigned NumVTableThunks, llvm::Constant *RTTI);
 
   CodeGenVTables(CodeGenModule &CGM);
 
-  ItaniumVTableContext &getItaniumVTableContext() { return ItaniumVTContext; }
+  ItaniumVTableContext &getItaniumVTableContext() {
+    return *cast<ItaniumVTableContext>(VTContext);
+  }
 
   MicrosoftVTableContext &getMicrosoftVTableContext() {
-    return *MicrosoftVTContext.get();
+    return *cast<MicrosoftVTableContext>(VTContext);
   }
 
   /// getSubVTTIndex - Return the index of the sub-VTT for the base class of the
@@ -100,7 +98,7 @@
                              VTableAddressPointsMapTy& AddressPoints);
 
     
-  /// GetAddrOfVTable - Get the address of the VTT for the given record decl.
+  /// GetAddrOfVTT - Get the address of the VTT for the given record decl.
   llvm::GlobalVariable *GetAddrOfVTT(const CXXRecordDecl *RD);
 
   /// EmitVTTDefinition - Emit the definition of the given vtable.
diff --git a/lib/CodeGen/CGValue.h b/lib/CodeGen/CGValue.h
index da2a034..956f324 100644
--- a/lib/CodeGen/CGValue.h
+++ b/lib/CodeGen/CGValue.h
@@ -110,7 +110,8 @@
     Simple,       // This is a normal l-value, use getAddress().
     VectorElt,    // This is a vector element l-value (V[i]), use getVector*
     BitField,     // This is a bitfield l-value, use getBitfield*.
-    ExtVectorElt  // This is an extended vector subset, use getExtVectorComp
+    ExtVectorElt, // This is an extended vector subset, use getExtVectorComp
+    GlobalReg     // This is a register l-value, use getGlobalReg()
   } LVType;
 
   llvm::Value *V;
@@ -168,7 +169,7 @@
 private:
   void Initialize(QualType Type, Qualifiers Quals,
                   CharUnits Alignment,
-                  llvm::MDNode *TBAAInfo = 0) {
+                  llvm::MDNode *TBAAInfo = nullptr) {
     this->Type = Type;
     this->Quals = Quals;
     this->Alignment = Alignment.getQuantity();
@@ -179,7 +180,7 @@
     this->Ivar = this->ObjIsArray = this->NonGC = this->GlobalObjCRef = false;
     this->ImpreciseLifetime = false;
     this->ThreadLocalRef = false;
-    this->BaseIvarExp = 0;
+    this->BaseIvarExp = nullptr;
 
     // Initialize fields for TBAA.
     this->TBAABaseType = Type;
@@ -192,6 +193,7 @@
   bool isVectorElt() const { return LVType == VectorElt; }
   bool isBitField() const { return LVType == BitField; }
   bool isExtVectorElt() const { return LVType == ExtVectorElt; }
+  bool isGlobalReg() const { return LVType == GlobalReg; }
 
   bool isVolatileQualified() const { return Quals.hasVolatile(); }
   bool isRestrictQualified() const { return Quals.hasRestrict(); }
@@ -286,9 +288,12 @@
     return *BitFieldInfo;
   }
 
+  // global register lvalue
+  llvm::Value *getGlobalReg() const { assert(isGlobalReg()); return V; }
+
   static LValue MakeAddr(llvm::Value *address, QualType type,
                          CharUnits alignment, ASTContext &Context,
-                         llvm::MDNode *TBAAInfo = 0) {
+                         llvm::MDNode *TBAAInfo = nullptr) {
     Qualifiers qs = type.getQualifiers();
     qs.setObjCGCAttr(Context.getObjCGCAttrKind(type));
 
@@ -336,6 +341,16 @@
     return R;
   }
 
+  static LValue MakeGlobalReg(llvm::Value *Reg,
+                              QualType type,
+                              CharUnits Alignment) {
+    LValue R;
+    R.LVType = GlobalReg;
+    R.V = Reg;
+    R.Initialize(type, type.getQualifiers(), Alignment);
+    return R;
+  }
+
   RValue asAggregateRValue() const {
     // FIMXE: Alignment
     return RValue::getAggregate(getAddress(), isVolatileQualified());
@@ -390,7 +405,7 @@
   /// ignored - Returns an aggregate value slot indicating that the
   /// aggregate value is being ignored.
   static AggValueSlot ignored() {
-    return forAddr(0, CharUnits(), Qualifiers(), IsNotDestructed,
+    return forAddr(nullptr, CharUnits(), Qualifiers(), IsNotDestructed,
                    DoesNotNeedGCBarriers, IsNotAliased);
   }
 
@@ -460,7 +475,7 @@
   }
 
   bool isIgnored() const {
-    return Addr == 0;
+    return Addr == nullptr;
   }
 
   CharUnits getAlignment() const {
diff --git a/lib/CodeGen/CMakeLists.txt b/lib/CodeGen/CMakeLists.txt
index 83dbbf0..00a87d8 100644
--- a/lib/CodeGen/CMakeLists.txt
+++ b/lib/CodeGen/CMakeLists.txt
@@ -1,12 +1,19 @@
 set(LLVM_LINK_COMPONENTS
-  asmparser
-  bitreader
-  bitwriter
-  irreader
-  instrumentation
-  ipo
-  linker
-  vectorize
+  BitReader
+  BitWriter
+  Core
+  IPO
+  IRReader
+  InstCombine
+  Instrumentation
+  Linker
+  MC
+  ObjCARCOpts
+  ProfileData
+  ScalarOpts
+  Support
+  Target
+  TransformUtils
   )
 
 add_clang_library(clangCodeGen
@@ -14,12 +21,12 @@
   CGAtomic.cpp
   CGBlocks.cpp
   CGBuiltin.cpp
-  CGCall.cpp
-  CGClass.cpp
   CGCUDANV.cpp
   CGCUDARuntime.cpp
   CGCXX.cpp
   CGCXXABI.cpp
+  CGCall.cpp
+  CGClass.cpp
   CGCleanup.cpp
   CGDebugInfo.cpp
   CGDecl.cpp
@@ -27,46 +34,40 @@
   CGException.cpp
   CGExpr.cpp
   CGExprAgg.cpp
+  CGExprCXX.cpp
   CGExprComplex.cpp
   CGExprConstant.cpp
-  CGExprCXX.cpp
   CGExprScalar.cpp
+  CGLoopInfo.cpp
   CGObjC.cpp
   CGObjCGNU.cpp
   CGObjCMac.cpp
   CGObjCRuntime.cpp
   CGOpenCLRuntime.cpp
+  CGOpenMPRuntime.cpp
   CGRecordLayoutBuilder.cpp
-  CGRTTI.cpp
   CGStmt.cpp
-  CGVTables.cpp
+  CGStmtOpenMP.cpp
   CGVTT.cpp
+  CGVTables.cpp
   CodeGenABITypes.cpp
   CodeGenAction.cpp
   CodeGenFunction.cpp
   CodeGenModule.cpp
+  CodeGenPGO.cpp
   CodeGenTBAA.cpp
   CodeGenTypes.cpp
   ItaniumCXXABI.cpp
   MicrosoftCXXABI.cpp
-  MicrosoftVBTables.cpp
   ModuleBuilder.cpp
+  SanitizerBlacklist.cpp
   TargetInfo.cpp
-  )
 
-add_dependencies(clangCodeGen
-  ClangARMNeon
-  ClangAttrClasses
-  ClangAttrList
-  ClangCommentNodes
-  ClangDeclNodes
-  ClangDiagnosticCommon
-  ClangDiagnosticFrontend
-  ClangStmtNodes
-  )
+  DEPENDS
+  intrinsics_gen
 
-target_link_libraries(clangCodeGen
-  clangBasic
+  LINK_LIBS
   clangAST
+  clangBasic
   clangFrontend
   )
diff --git a/lib/CodeGen/CodeGenABITypes.cpp b/lib/CodeGen/CodeGenABITypes.cpp
index 18c836c..180cd51 100644
--- a/lib/CodeGen/CodeGenABITypes.cpp
+++ b/lib/CodeGen/CodeGenABITypes.cpp
@@ -17,23 +17,23 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/CodeGen/CodeGenABITypes.h"
-
-#include "clang/CodeGen/CGFunctionInfo.h"
 #include "CodeGenModule.h"
+#include "clang/CodeGen/CGFunctionInfo.h"
+#include "clang/Frontend/CodeGenOptions.h"
 
 using namespace clang;
 using namespace CodeGen;
 
 CodeGenABITypes::CodeGenABITypes(ASTContext &C,
-                                 const CodeGenOptions &CodeGenOpts,
                                  llvm::Module &M,
-                                 const llvm::DataLayout &TD,
-                                 DiagnosticsEngine &Diags)
-  : CGM(new CodeGen::CodeGenModule(C, CodeGenOpts, M, TD, Diags)) {
+                                 const llvm::DataLayout &TD)
+  : CGO(new CodeGenOptions),
+    CGM(new CodeGen::CodeGenModule(C, *CGO, M, TD, C.getDiagnostics())) {
 }
 
 CodeGenABITypes::~CodeGenABITypes()
 {
+  delete CGO;
   delete CGM;
 }
 
@@ -60,10 +60,10 @@
 }
 
 const CGFunctionInfo &
-CodeGenABITypes::arrangeLLVMFunctionInfo(CanQualType returnType,
-                                         llvm::ArrayRef<CanQualType> argTypes,
+CodeGenABITypes::arrangeFreeFunctionCall(CanQualType returnType,
+                                         ArrayRef<CanQualType> argTypes,
                                          FunctionType::ExtInfo info,
                                          RequiredArgs args) {
-  return CGM->getTypes().arrangeLLVMFunctionInfo(returnType, argTypes,
-                                                info, args);
+  return CGM->getTypes().arrangeLLVMFunctionInfo(
+      returnType, /*IsInstanceMethod=*/false, argTypes, info, args);
 }
diff --git a/lib/CodeGen/CodeGenAction.cpp b/lib/CodeGen/CodeGenAction.cpp
index 3072204..04d2cd9 100644
--- a/lib/CodeGen/CodeGenAction.cpp
+++ b/lib/CodeGen/CodeGenAction.cpp
@@ -11,6 +11,7 @@
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclGroup.h"
+#include "clang/AST/DeclCXX.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
@@ -18,17 +19,20 @@
 #include "clang/CodeGen/ModuleBuilder.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/FrontendDiagnostic.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/IR/DebugInfo.h"
+#include "llvm/IR/DiagnosticInfo.h"
+#include "llvm/IR/DiagnosticPrinter.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IRReader/IRReader.h"
-#include "llvm/Linker.h"
+#include "llvm/Linker/Linker.h"
 #include "llvm/Pass.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/SourceMgr.h"
 #include "llvm/Support/Timer.h"
+#include <memory>
 using namespace clang;
 using namespace llvm;
 
@@ -45,42 +49,33 @@
 
     Timer LLVMIRGeneration;
 
-    OwningPtr<CodeGenerator> Gen;
+    std::unique_ptr<CodeGenerator> Gen;
 
-    OwningPtr<llvm::Module> TheModule, LinkModule;
+    std::unique_ptr<llvm::Module> TheModule, LinkModule;
 
   public:
     BackendConsumer(BackendAction action, DiagnosticsEngine &_Diags,
                     const CodeGenOptions &compopts,
                     const TargetOptions &targetopts,
-                    const LangOptions &langopts,
-                    bool TimePasses,
-                    const std::string &infile,
-                    llvm::Module *LinkModule,
-                    raw_ostream *OS,
-                    LLVMContext &C) :
-      Diags(_Diags),
-      Action(action),
-      CodeGenOpts(compopts),
-      TargetOpts(targetopts),
-      LangOpts(langopts),
-      AsmOutStream(OS),
-      Context(), 
-      LLVMIRGeneration("LLVM IR Generation Time"),
-      Gen(CreateLLVMCodeGen(Diags, infile, compopts, targetopts, C)),
-      LinkModule(LinkModule)
-    {
+                    const LangOptions &langopts, bool TimePasses,
+                    const std::string &infile, llvm::Module *LinkModule,
+                    raw_ostream *OS, LLVMContext &C)
+        : Diags(_Diags), Action(action), CodeGenOpts(compopts),
+          TargetOpts(targetopts), LangOpts(langopts), AsmOutStream(OS),
+          Context(), LLVMIRGeneration("LLVM IR Generation Time"),
+          Gen(CreateLLVMCodeGen(Diags, infile, compopts, targetopts, C)),
+          LinkModule(LinkModule) {
       llvm::TimePassesIsEnabled = TimePasses;
     }
 
-    llvm::Module *takeModule() { return TheModule.take(); }
-    llvm::Module *takeLinkModule() { return LinkModule.take(); }
+    llvm::Module *takeModule() { return TheModule.release(); }
+    llvm::Module *takeLinkModule() { return LinkModule.release(); }
 
-    virtual void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) {
+    void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override {
       Gen->HandleCXXStaticMemberVarInstantiation(VD);
     }
 
-    virtual void Initialize(ASTContext &Ctx) {
+    void Initialize(ASTContext &Ctx) override {
       Context = &Ctx;
 
       if (llvm::TimePassesIsEnabled)
@@ -94,7 +89,7 @@
         LLVMIRGeneration.stopTimer();
     }
 
-    virtual bool HandleTopLevelDecl(DeclGroupRef D) {
+    bool HandleTopLevelDecl(DeclGroupRef D) override {
       PrettyStackTraceDecl CrashInfo(*D.begin(), SourceLocation(),
                                      Context->getSourceManager(),
                                      "LLVM IR generation of declaration");
@@ -110,7 +105,20 @@
       return true;
     }
 
-    virtual void HandleTranslationUnit(ASTContext &C) {
+    void HandleInlineMethodDefinition(CXXMethodDecl *D) override {
+      PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
+                                     Context->getSourceManager(),
+                                     "LLVM IR generation of inline method");
+      if (llvm::TimePassesIsEnabled)
+        LLVMIRGeneration.startTimer();
+
+      Gen->HandleInlineMethodDefinition(D);
+
+      if (llvm::TimePassesIsEnabled)
+        LLVMIRGeneration.stopTimer();
+    }
+
+    void HandleTranslationUnit(ASTContext &C) override {
       {
         PrettyStackTraceString CrashInfo("Per-file LLVM IR generation");
         if (llvm::TimePassesIsEnabled)
@@ -132,7 +140,7 @@
       if (!M) {
         // The module has been released by IR gen on failures, do not double
         // free.
-        TheModule.take();
+        TheModule.release();
         return;
       }
 
@@ -158,41 +166,49 @@
       void *OldContext = Ctx.getInlineAsmDiagnosticContext();
       Ctx.setInlineAsmDiagnosticHandler(InlineAsmDiagHandler, this);
 
+      LLVMContext::DiagnosticHandlerTy OldDiagnosticHandler =
+          Ctx.getDiagnosticHandler();
+      void *OldDiagnosticContext = Ctx.getDiagnosticContext();
+      Ctx.setDiagnosticHandler(DiagnosticHandler, this);
+
       EmitBackendOutput(Diags, CodeGenOpts, TargetOpts, LangOpts,
+                        C.getTargetInfo().getTargetDescription(),
                         TheModule.get(), Action, AsmOutStream);
-      
+
       Ctx.setInlineAsmDiagnosticHandler(OldHandler, OldContext);
+
+      Ctx.setDiagnosticHandler(OldDiagnosticHandler, OldDiagnosticContext);
     }
 
-    virtual void HandleTagDeclDefinition(TagDecl *D) {
+    void HandleTagDeclDefinition(TagDecl *D) override {
       PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
                                      Context->getSourceManager(),
                                      "LLVM IR generation of declaration");
       Gen->HandleTagDeclDefinition(D);
     }
 
-    virtual void HandleTagDeclRequiredDefinition(const TagDecl *D) {
+    void HandleTagDeclRequiredDefinition(const TagDecl *D) override {
       Gen->HandleTagDeclRequiredDefinition(D);
     }
 
-    virtual void CompleteTentativeDefinition(VarDecl *D) {
+    void CompleteTentativeDefinition(VarDecl *D) override {
       Gen->CompleteTentativeDefinition(D);
     }
 
-    virtual void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) {
+    void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) override {
       Gen->HandleVTable(RD, DefinitionRequired);
     }
 
-    virtual void HandleLinkerOptionPragma(llvm::StringRef Opts) {
+    void HandleLinkerOptionPragma(llvm::StringRef Opts) override {
       Gen->HandleLinkerOptionPragma(Opts);
     }
 
-    virtual void HandleDetectMismatch(llvm::StringRef Name,
-                                      llvm::StringRef Value) {
+    void HandleDetectMismatch(llvm::StringRef Name,
+                                      llvm::StringRef Value) override {
       Gen->HandleDetectMismatch(Name, Value);
     }
 
-    virtual void HandleDependentLibrary(llvm::StringRef Opts) {
+    void HandleDependentLibrary(llvm::StringRef Opts) override {
       Gen->HandleDependentLibrary(Opts);
     }
 
@@ -202,8 +218,36 @@
       ((BackendConsumer*)Context)->InlineAsmDiagHandler2(SM, Loc);
     }
 
+    static void DiagnosticHandler(const llvm::DiagnosticInfo &DI,
+                                  void *Context) {
+      ((BackendConsumer *)Context)->DiagnosticHandlerImpl(DI);
+    }
+
     void InlineAsmDiagHandler2(const llvm::SMDiagnostic &,
                                SourceLocation LocCookie);
+
+    void DiagnosticHandlerImpl(const llvm::DiagnosticInfo &DI);
+    /// \brief Specialized handler for InlineAsm diagnostic.
+    /// \return True if the diagnostic has been successfully reported, false
+    /// otherwise.
+    bool InlineAsmDiagHandler(const llvm::DiagnosticInfoInlineAsm &D);
+    /// \brief Specialized handler for StackSize diagnostic.
+    /// \return True if the diagnostic has been successfully reported, false
+    /// otherwise.
+    bool StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D);
+    /// \brief Specialized handlers for optimization remarks.
+    /// Note that these handlers only accept remarks and they always handle
+    /// them.
+    void EmitOptimizationMessage(const llvm::DiagnosticInfoOptimizationBase &D,
+                                 unsigned DiagID);
+    void
+    OptimizationRemarkHandler(const llvm::DiagnosticInfoOptimizationRemark &D);
+    void OptimizationRemarkHandler(
+        const llvm::DiagnosticInfoOptimizationRemarkMissed &D);
+    void OptimizationRemarkHandler(
+        const llvm::DiagnosticInfoOptimizationRemarkAnalysis &D);
+    void OptimizationFailureHandler(
+        const llvm::DiagnosticInfoOptimizationFailure &D);
   };
   
   void BackendConsumer::anchor() {}
@@ -224,13 +268,15 @@
   LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc()));
 
   // Create the copy and transfer ownership to clang::SourceManager.
+  // TODO: Avoid copying files into memory.
   llvm::MemoryBuffer *CBuf =
   llvm::MemoryBuffer::getMemBufferCopy(LBuf->getBuffer(),
                                        LBuf->getBufferIdentifier());
-  FileID FID = CSM.createFileIDForMemBuffer(CBuf);
+  // FIXME: Keep a file ID map instead of creating new IDs for each location.
+  FileID FID = CSM.createFileID(CBuf);
 
   // Translate the offset into the file.
-  unsigned Offset = D.getLoc().getPointer()  - LBuf->getBufferStart();
+  unsigned Offset = D.getLoc().getPointer() - LBuf->getBufferStart();
   SourceLocation NewLoc =
   CSM.getLocForStartOfFile(FID).getLocWithOffset(Offset);
   return FullSourceLoc(NewLoc, CSM);
@@ -254,13 +300,24 @@
   FullSourceLoc Loc;
   if (D.getLoc() != SMLoc())
     Loc = ConvertBackendLocation(D, Context->getSourceManager());
-  
 
+  unsigned DiagID;
+  switch (D.getKind()) {
+  case llvm::SourceMgr::DK_Error:
+    DiagID = diag::err_fe_inline_asm;
+    break;
+  case llvm::SourceMgr::DK_Warning:
+    DiagID = diag::warn_fe_inline_asm;
+    break;
+  case llvm::SourceMgr::DK_Note:
+    DiagID = diag::note_fe_inline_asm;
+    break;
+  }
   // If this problem has clang-level source location information, report the
-  // issue as being an error in the source with a note showing the instantiated
+  // issue in the source with a note showing the instantiated
   // code.
   if (LocCookie.isValid()) {
-    Diags.Report(LocCookie, diag::err_fe_inline_asm).AddString(Message);
+    Diags.Report(LocCookie, DiagID).AddString(Message);
     
     if (D.getLoc().isValid()) {
       DiagnosticBuilder B = Diags.Report(Loc, diag::note_fe_inline_asm_here);
@@ -276,16 +333,224 @@
     return;
   }
   
-  // Otherwise, report the backend error as occurring in the generated .s file.
-  // If Loc is invalid, we still need to report the error, it just gets no
+  // Otherwise, report the backend issue as occurring in the generated .s file.
+  // If Loc is invalid, we still need to report the issue, it just gets no
   // location info.
-  Diags.Report(Loc, diag::err_fe_inline_asm).AddString(Message);
+  Diags.Report(Loc, DiagID).AddString(Message);
 }
 
-//
+#define ComputeDiagID(Severity, GroupName, DiagID)                             \
+  do {                                                                         \
+    switch (Severity) {                                                        \
+    case llvm::DS_Error:                                                       \
+      DiagID = diag::err_fe_##GroupName;                                       \
+      break;                                                                   \
+    case llvm::DS_Warning:                                                     \
+      DiagID = diag::warn_fe_##GroupName;                                      \
+      break;                                                                   \
+    case llvm::DS_Remark:                                                      \
+      llvm_unreachable("'remark' severity not expected");                      \
+      break;                                                                   \
+    case llvm::DS_Note:                                                        \
+      DiagID = diag::note_fe_##GroupName;                                      \
+      break;                                                                   \
+    }                                                                          \
+  } while (false)
+
+#define ComputeDiagRemarkID(Severity, GroupName, DiagID)                       \
+  do {                                                                         \
+    switch (Severity) {                                                        \
+    case llvm::DS_Error:                                                       \
+      DiagID = diag::err_fe_##GroupName;                                       \
+      break;                                                                   \
+    case llvm::DS_Warning:                                                     \
+      DiagID = diag::warn_fe_##GroupName;                                      \
+      break;                                                                   \
+    case llvm::DS_Remark:                                                      \
+      DiagID = diag::remark_fe_##GroupName;                                    \
+      break;                                                                   \
+    case llvm::DS_Note:                                                        \
+      DiagID = diag::note_fe_##GroupName;                                      \
+      break;                                                                   \
+    }                                                                          \
+  } while (false)
+
+bool
+BackendConsumer::InlineAsmDiagHandler(const llvm::DiagnosticInfoInlineAsm &D) {
+  unsigned DiagID;
+  ComputeDiagID(D.getSeverity(), inline_asm, DiagID);
+  std::string Message = D.getMsgStr().str();
+
+  // If this problem has clang-level source location information, report the
+  // issue as being a problem in the source with a note showing the instantiated
+  // code.
+  SourceLocation LocCookie =
+      SourceLocation::getFromRawEncoding(D.getLocCookie());
+  if (LocCookie.isValid())
+    Diags.Report(LocCookie, DiagID).AddString(Message);
+  else {
+    // Otherwise, report the backend diagnostic as occurring in the generated
+    // .s file.
+    // If Loc is invalid, we still need to report the diagnostic, it just gets
+    // no location info.
+    FullSourceLoc Loc;
+    Diags.Report(Loc, DiagID).AddString(Message);
+  }
+  // We handled all the possible severities.
+  return true;
+}
+
+bool
+BackendConsumer::StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D) {
+  if (D.getSeverity() != llvm::DS_Warning)
+    // For now, the only support we have for StackSize diagnostic is warning.
+    // We do not know how to format other severities.
+    return false;
+
+  if (const Decl *ND = Gen->GetDeclForMangledName(D.getFunction().getName())) {
+    Diags.Report(ND->getASTContext().getFullLoc(ND->getLocation()),
+                 diag::warn_fe_frame_larger_than)
+        << D.getStackSize() << Decl::castToDeclContext(ND);
+    return true;
+  }
+
+  return false;
+}
+
+void BackendConsumer::EmitOptimizationMessage(
+    const llvm::DiagnosticInfoOptimizationBase &D, unsigned DiagID) {
+  // We only support warnings and remarks.
+  assert(D.getSeverity() == llvm::DS_Remark ||
+         D.getSeverity() == llvm::DS_Warning);
+
+  SourceManager &SourceMgr = Context->getSourceManager();
+  FileManager &FileMgr = SourceMgr.getFileManager();
+  StringRef Filename;
+  unsigned Line, Column;
+  D.getLocation(&Filename, &Line, &Column);
+  SourceLocation DILoc;
+  const FileEntry *FE = FileMgr.getFile(Filename);
+  if (FE && Line > 0) {
+    // If -gcolumn-info was not used, Column will be 0. This upsets the
+    // source manager, so pass 1 if Column is not set.
+    DILoc = SourceMgr.translateFileLineCol(FE, Line, Column ? Column : 1);
+  }
+
+  // If a location isn't available, try to approximate it using the associated
+  // function definition. We use the definition's right brace to differentiate
+  // from diagnostics that genuinely relate to the function itself.
+  FullSourceLoc Loc(DILoc, SourceMgr);
+  if (Loc.isInvalid())
+    if (const Decl *FD = Gen->GetDeclForMangledName(D.getFunction().getName()))
+      Loc = FD->getASTContext().getFullLoc(FD->getBodyRBrace());
+
+  Diags.Report(Loc, DiagID)
+      << AddFlagValue(D.getPassName() ? D.getPassName() : "")
+      << D.getMsg().str();
+
+  if (DILoc.isInvalid())
+    // If we were not able to translate the file:line:col information
+    // back to a SourceLocation, at least emit a note stating that
+    // we could not translate this location. This can happen in the
+    // case of #line directives.
+    Diags.Report(Loc, diag::note_fe_backend_optimization_remark_invalid_loc)
+        << Filename << Line << Column;
+}
+
+void BackendConsumer::OptimizationRemarkHandler(
+    const llvm::DiagnosticInfoOptimizationRemark &D) {
+  // 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);
+}
+
+void BackendConsumer::OptimizationRemarkHandler(
+    const llvm::DiagnosticInfoOptimizationRemarkMissed &D) {
+  // Missed optimization remarks are active only if the -Rpass-missed
+  // flag has a regular expression that matches the name of the pass
+  // name in \p D.
+  if (CodeGenOpts.OptimizationRemarkMissedPattern &&
+      CodeGenOpts.OptimizationRemarkMissedPattern->match(D.getPassName()))
+    EmitOptimizationMessage(D,
+                            diag::remark_fe_backend_optimization_remark_missed);
+}
+
+void BackendConsumer::OptimizationRemarkHandler(
+    const llvm::DiagnosticInfoOptimizationRemarkAnalysis &D) {
+  // Optimization analysis remarks are active only if the -Rpass-analysis
+  // flag has a regular expression that matches the name of the pass
+  // name in \p D.
+  if (CodeGenOpts.OptimizationRemarkAnalysisPattern &&
+      CodeGenOpts.OptimizationRemarkAnalysisPattern->match(D.getPassName()))
+    EmitOptimizationMessage(
+        D, diag::remark_fe_backend_optimization_remark_analysis);
+}
+
+void BackendConsumer::OptimizationFailureHandler(
+    const llvm::DiagnosticInfoOptimizationFailure &D) {
+  EmitOptimizationMessage(D, diag::warn_fe_backend_optimization_failure);
+}
+
+/// \brief This function is invoked when the backend needs
+/// to report something to the user.
+void BackendConsumer::DiagnosticHandlerImpl(const DiagnosticInfo &DI) {
+  unsigned DiagID = diag::err_fe_inline_asm;
+  llvm::DiagnosticSeverity Severity = DI.getSeverity();
+  // Get the diagnostic ID based.
+  switch (DI.getKind()) {
+  case llvm::DK_InlineAsm:
+    if (InlineAsmDiagHandler(cast<DiagnosticInfoInlineAsm>(DI)))
+      return;
+    ComputeDiagID(Severity, inline_asm, DiagID);
+    break;
+  case llvm::DK_StackSize:
+    if (StackSizeDiagHandler(cast<DiagnosticInfoStackSize>(DI)))
+      return;
+    ComputeDiagID(Severity, backend_frame_larger_than, DiagID);
+    break;
+  case llvm::DK_OptimizationRemark:
+    // Optimization remarks are always handled completely by this
+    // handler. There is no generic way of emitting them.
+    OptimizationRemarkHandler(cast<DiagnosticInfoOptimizationRemark>(DI));
+    return;
+  case llvm::DK_OptimizationRemarkMissed:
+    // Optimization remarks are always handled completely by this
+    // handler. There is no generic way of emitting them.
+    OptimizationRemarkHandler(cast<DiagnosticInfoOptimizationRemarkMissed>(DI));
+    return;
+  case llvm::DK_OptimizationRemarkAnalysis:
+    // Optimization remarks are always handled completely by this
+    // handler. There is no generic way of emitting them.
+    OptimizationRemarkHandler(
+        cast<DiagnosticInfoOptimizationRemarkAnalysis>(DI));
+    return;
+  case llvm::DK_OptimizationFailure:
+    // Optimization failures are always handled completely by this
+    // handler.
+    OptimizationFailureHandler(cast<DiagnosticInfoOptimizationFailure>(DI));
+    return;
+  default:
+    // Plugin IDs are not bound to any value as they are set dynamically.
+    ComputeDiagRemarkID(Severity, backend_plugin, DiagID);
+    break;
+  }
+  std::string MsgStorage;
+  {
+    raw_string_ostream Stream(MsgStorage);
+    DiagnosticPrinterRawOStream DP(Stream);
+    DI.print(DP);
+  }
+
+  // Report the backend message using the usual diagnostic mechanism.
+  FullSourceLoc Loc;
+  Diags.Report(Loc, DiagID).AddString(MsgStorage);
+}
+#undef ComputeDiagID
 
 CodeGenAction::CodeGenAction(unsigned _Act, LLVMContext *_VMContext)
-  : Act(_Act), LinkModule(0),
+  : Act(_Act), LinkModule(nullptr),
     VMContext(_VMContext ? _VMContext : new LLVMContext),
     OwnsVMContext(!_VMContext) {}
 
@@ -310,9 +575,7 @@
   TheModule.reset(BEConsumer->takeModule());
 }
 
-llvm::Module *CodeGenAction::takeModule() {
-  return TheModule.take();
-}
+llvm::Module *CodeGenAction::takeModule() { return TheModule.release(); }
 
 llvm::LLVMContext *CodeGenAction::takeLLVMContext() {
   OwnsVMContext = false;
@@ -330,8 +593,9 @@
   case Backend_EmitBC:
     return CI.createDefaultOutputFile(true, InFile, "bc");
   case Backend_EmitNothing:
-    return 0;
+    return nullptr;
   case Backend_EmitMCNull:
+    return CI.createNullOutputFile();
   case Backend_EmitObj:
     return CI.createDefaultOutputFile(true, InFile, "o");
   }
@@ -342,9 +606,9 @@
 ASTConsumer *CodeGenAction::CreateASTConsumer(CompilerInstance &CI,
                                               StringRef InFile) {
   BackendAction BA = static_cast<BackendAction>(Act);
-  OwningPtr<raw_ostream> OS(GetOutputStream(CI, InFile, BA));
+  std::unique_ptr<raw_ostream> OS(GetOutputStream(CI, InFile, BA));
   if (BA != Backend_EmitNothing && !OS)
-    return 0;
+    return nullptr;
 
   llvm::Module *LinkModuleToUse = LinkModule;
 
@@ -359,23 +623,23 @@
     if (!BCBuf) {
       CI.getDiagnostics().Report(diag::err_cannot_open_file)
         << LinkBCFile << ErrorStr;
-      return 0;
+      return nullptr;
     }
 
-    LinkModuleToUse = getLazyBitcodeModule(BCBuf, *VMContext, &ErrorStr);
-    if (!LinkModuleToUse) {
+    ErrorOr<llvm::Module *> ModuleOrErr =
+        getLazyBitcodeModule(BCBuf, *VMContext);
+    if (std::error_code EC = ModuleOrErr.getError()) {
       CI.getDiagnostics().Report(diag::err_cannot_open_file)
-        << LinkBCFile << ErrorStr;
-      return 0;
+        << LinkBCFile << EC.message();
+      return nullptr;
     }
+    LinkModuleToUse = ModuleOrErr.get();
   }
 
-  BEConsumer = 
-      new BackendConsumer(BA, CI.getDiagnostics(),
-                          CI.getCodeGenOpts(), CI.getTargetOpts(),
-                          CI.getLangOpts(),
-                          CI.getFrontendOpts().ShowTimers, InFile,
-                          LinkModuleToUse, OS.take(), *VMContext);
+  BEConsumer = new BackendConsumer(BA, CI.getDiagnostics(), CI.getCodeGenOpts(),
+                                   CI.getTargetOpts(), CI.getLangOpts(),
+                                   CI.getFrontendOpts().ShowTimers, InFile,
+                                   LinkModuleToUse, OS.release(), *VMContext);
   return BEConsumer;
 }
 
@@ -390,49 +654,48 @@
 
     bool Invalid;
     SourceManager &SM = CI.getSourceManager();
-    const llvm::MemoryBuffer *MainFile = SM.getBuffer(SM.getMainFileID(),
-                                                      &Invalid);
+    FileID FID = SM.getMainFileID();
+    llvm::MemoryBuffer *MainFile = SM.getBuffer(FID, &Invalid);
     if (Invalid)
       return;
 
-    // FIXME: This is stupid, IRReader shouldn't take ownership.
-    llvm::MemoryBuffer *MainFileCopy =
-      llvm::MemoryBuffer::getMemBufferCopy(MainFile->getBuffer(),
-                                           getCurrentFile());
-
     llvm::SMDiagnostic Err;
-    TheModule.reset(ParseIR(MainFileCopy, Err, *VMContext));
+    TheModule.reset(ParseIR(MainFile, Err, *VMContext));
     if (!TheModule) {
-      // Translate from the diagnostic info to the SourceManager location.
-      SourceLocation Loc = SM.translateFileLineCol(
-        SM.getFileEntryForID(SM.getMainFileID()), Err.getLineNo(),
-        Err.getColumnNo() + 1);
+      // Translate from the diagnostic info to the SourceManager location if
+      // available.
+      // TODO: Unify this with ConvertBackendLocation()
+      SourceLocation Loc;
+      if (Err.getLineNo() > 0) {
+        assert(Err.getColumnNo() >= 0);
+        Loc = SM.translateFileLineCol(SM.getFileEntryForID(FID),
+                                      Err.getLineNo(), Err.getColumnNo() + 1);
+      }
 
-      // Get a custom diagnostic for the error. We strip off a leading
-      // diagnostic code if there is one.
+      // Strip off a leading diagnostic code if there is one.
       StringRef Msg = Err.getMessage();
       if (Msg.startswith("error: "))
         Msg = Msg.substr(7);
 
-      // Escape '%', which is interpreted as a format character.
-      SmallString<128> EscapedMessage;
-      for (unsigned i = 0, e = Msg.size(); i != e; ++i) {
-        if (Msg[i] == '%')
-          EscapedMessage += '%';
-        EscapedMessage += Msg[i];
-      }
+      unsigned DiagID =
+          CI.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error, "%0");
 
-      unsigned DiagID = CI.getDiagnostics().getCustomDiagID(
-          DiagnosticsEngine::Error, EscapedMessage);
-
-      CI.getDiagnostics().Report(Loc, DiagID);
+      CI.getDiagnostics().Report(Loc, DiagID) << Msg;
       return;
     }
+    const TargetOptions &TargetOpts = CI.getTargetOpts();
+    if (TheModule->getTargetTriple() != TargetOpts.Triple) {
+      unsigned DiagID = CI.getDiagnostics().getCustomDiagID(
+          DiagnosticsEngine::Warning,
+          "overriding the module target triple with %0");
 
-    EmitBackendOutput(CI.getDiagnostics(), CI.getCodeGenOpts(),
-                      CI.getTargetOpts(), CI.getLangOpts(),
-                      TheModule.get(),
-                      BA, OS);
+      CI.getDiagnostics().Report(SourceLocation(), DiagID) << TargetOpts.Triple;
+      TheModule->setTargetTriple(TargetOpts.Triple);
+    }
+
+    EmitBackendOutput(CI.getDiagnostics(), CI.getCodeGenOpts(), TargetOpts,
+                      CI.getLangOpts(), CI.getTarget().getTargetDescription(),
+                      TheModule.get(), BA, OS);
     return;
   }
 
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index ce1b445..5ca3a78 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -15,13 +15,14 @@
 #include "CGCUDARuntime.h"
 #include "CGCXXABI.h"
 #include "CGDebugInfo.h"
+#include "CGOpenMPRuntime.h"
 #include "CodeGenModule.h"
+#include "CodeGenPGO.h"
 #include "TargetInfo.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/StmtCXX.h"
-#include "clang/Basic/OpenCL.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/CodeGen/CGFunctionInfo.h"
 #include "clang/Frontend/CodeGenOptions.h"
@@ -34,22 +35,23 @@
 
 CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext)
     : CodeGenTypeCache(cgm), CGM(cgm), Target(cgm.getTarget()),
-      Builder(cgm.getModule().getContext()), CapturedStmtInfo(0),
-      SanitizePerformTypeCheck(CGM.getSanOpts().Null |
-                               CGM.getSanOpts().Alignment |
-                               CGM.getSanOpts().ObjectSize |
-                               CGM.getSanOpts().Vptr),
-      SanOpts(&CGM.getSanOpts()), AutoreleaseResult(false), BlockInfo(0),
-      BlockPointer(0), LambdaThisCaptureField(0), NormalCleanupDest(0),
-      NextCleanupDestIndex(1), FirstBlockInfo(0), EHResumeBlock(0),
-      ExceptionSlot(0), EHSelectorSlot(0), DebugInfo(CGM.getModuleDebugInfo()),
-      DisableDebugInfo(false), DidCallStackSave(false), IndirectBranch(0),
-      SwitchInsn(0), CaseRangeBlock(0), UnreachableBlock(0), NumReturnExprs(0),
-      NumSimpleReturnExprs(0), CXXABIThisDecl(0), CXXABIThisValue(0),
-      CXXThisValue(0), CXXDefaultInitExprThis(0),
-      CXXStructorImplicitParamDecl(0), CXXStructorImplicitParamValue(0),
-      OutermostConditional(0), CurLexicalScope(0), TerminateLandingPad(0),
-      TerminateHandler(0), TrapBB(0) {
+      Builder(cgm.getModule().getContext(), llvm::ConstantFolder(),
+              CGBuilderInserterTy(this)),
+      CapturedStmtInfo(nullptr), SanOpts(&CGM.getLangOpts().Sanitize),
+      IsSanitizerScope(false), AutoreleaseResult(false), BlockInfo(nullptr),
+      BlockPointer(nullptr), LambdaThisCaptureField(nullptr),
+      NormalCleanupDest(nullptr), NextCleanupDestIndex(1),
+      FirstBlockInfo(nullptr), EHResumeBlock(nullptr), ExceptionSlot(nullptr),
+      EHSelectorSlot(nullptr), DebugInfo(CGM.getModuleDebugInfo()),
+      DisableDebugInfo(false), DidCallStackSave(false), IndirectBranch(nullptr),
+      PGO(cgm), SwitchInsn(nullptr), SwitchWeights(nullptr),
+      CaseRangeBlock(nullptr), UnreachableBlock(nullptr), NumReturnExprs(0),
+      NumSimpleReturnExprs(0), CXXABIThisDecl(nullptr),
+      CXXABIThisValue(nullptr), CXXThisValue(nullptr),
+      CXXDefaultInitExprThis(nullptr), CXXStructorImplicitParamDecl(nullptr),
+      CXXStructorImplicitParamValue(nullptr), OutermostConditional(nullptr),
+      CurLexicalScope(nullptr), TerminateLandingPad(nullptr),
+      TerminateHandler(nullptr), TrapBB(nullptr) {
   if (!suppressNewContext)
     CGM.getCXXABI().getMangleContext().startNewFunction();
 
@@ -71,6 +73,10 @@
   // something.
   if (FirstBlockInfo)
     destroyBlockInfos(FirstBlockInfo);
+
+  if (getLangOpts().OpenMP) {
+    CGM.getOpenMPRuntime().FunctionFinished(*this);
+  }
 }
 
 
@@ -157,7 +163,7 @@
   // cleans up functions which started with a unified return block.
   if (ReturnBlock.getBlock()->hasOneUse()) {
     llvm::BranchInst *BI =
-      dyn_cast<llvm::BranchInst>(*ReturnBlock.getBlock()->use_begin());
+      dyn_cast<llvm::BranchInst>(*ReturnBlock.getBlock()->user_begin());
     if (BI && BI->isUnconditional() &&
         BI->getSuccessor(0) == ReturnBlock.getBlock()) {
       // Reset insertion point, including debug location, and delete the
@@ -255,7 +261,7 @@
 
   // Remove the AllocaInsertPt instruction, which is just a convenience for us.
   llvm::Instruction *Ptr = AllocaInsertPt;
-  AllocaInsertPt = 0;
+  AllocaInsertPt = nullptr;
   Ptr->eraseFromParent();
 
   // If someone took the address of a label but never did an indirect goto, we
@@ -275,6 +281,14 @@
 
   if (CGM.getCodeGenOpts().EmitDeclMetadata)
     EmitDeclMetadata();
+
+  for (SmallVectorImpl<std::pair<llvm::Instruction *, llvm::Value *> >::iterator
+           I = DeferredReplacements.begin(),
+           E = DeferredReplacements.end();
+       I != E; ++I) {
+    I->first->replaceAllUsesWith(I->second);
+    I->first->eraseFromParent();
+  }
 }
 
 /// ShouldInstrumentFunction - Return true if the current function should be
@@ -330,6 +344,8 @@
   // Each MDNode is a list in the form of "key", N number of values which is
   // the same number of values as their are kernel arguments.
 
+  const PrintingPolicy &Policy = ASTCtx.getPrintingPolicy();
+
   // MDNode for the kernel argument address space qualifiers.
   SmallVector<llvm::Value*, 8> addressQuals;
   addressQuals.push_back(llvm::MDString::get(Context, "kernel_arg_addr_space"));
@@ -363,7 +379,8 @@
         pointeeTy.getAddressSpace())));
 
       // Get argument type name.
-      std::string typeName = pointeeTy.getUnqualifiedType().getAsString() + "*";
+      std::string typeName =
+          pointeeTy.getUnqualifiedType().getAsString(Policy) + "*";
 
       // Turn "unsigned type" to "utype"
       std::string::size_type pos = typeName.find("unsigned");
@@ -381,10 +398,15 @@
       if (pointeeTy.isVolatileQualified())
         typeQuals += typeQuals.empty() ? "volatile" : " volatile";
     } else {
-      addressQuals.push_back(Builder.getInt32(0));
+      uint32_t AddrSpc = 0;
+      if (ty->isImageType())
+        AddrSpc =
+          CGM.getContext().getTargetAddressSpace(LangAS::opencl_global);
+
+      addressQuals.push_back(Builder.getInt32(AddrSpc));
 
       // Get argument type name.
-      std::string typeName = ty.getUnqualifiedType().getAsString();
+      std::string typeName = ty.getUnqualifiedType().getAsString(Policy);
 
       // Turn "unsigned type" to "utype"
       std::string::size_type pos = typeName.find("unsigned");
@@ -399,16 +421,17 @@
       if (ty.isVolatileQualified())
         typeQuals += typeQuals.empty() ? "volatile" : " volatile";
     }
-    
+
     argTypeQuals.push_back(llvm::MDString::get(Context, typeQuals));
 
     // Get image access qualifier:
     if (ty->isImageType()) {
-      if (parm->hasAttr<OpenCLImageAccessAttr>() &&
-          parm->getAttr<OpenCLImageAccessAttr>()->getAccess() == CLIA_write_only)
+      const OpenCLImageAccessAttr *A = parm->getAttr<OpenCLImageAccessAttr>();
+      if (A && A->isWriteOnly())
         accessQuals.push_back(llvm::MDString::get(Context, "write_only"));
       else
         accessQuals.push_back(llvm::MDString::get(Context, "read_only"));
+      // FIXME: what about read_write?
     } else
       accessQuals.push_back(llvm::MDString::get(Context, "none"));
 
@@ -438,16 +461,15 @@
     GenOpenCLArgMetadata(FD, Fn, CGM, Context, kernelMDArgs,
                          Builder, getContext());
 
-  if (FD->hasAttr<VecTypeHintAttr>()) {
-    VecTypeHintAttr *attr = FD->getAttr<VecTypeHintAttr>();
-    QualType hintQTy = attr->getTypeHint();
+  if (const VecTypeHintAttr *A = FD->getAttr<VecTypeHintAttr>()) {
+    QualType hintQTy = A->getTypeHint();
     const ExtVectorType *hintEltQTy = hintQTy->getAs<ExtVectorType>();
     bool isSignedInteger =
         hintQTy->isSignedIntegerType() ||
         (hintEltQTy && hintEltQTy->getElementType()->isSignedIntegerType());
     llvm::Value *attrMDArgs[] = {
       llvm::MDString::get(Context, "vec_type_hint"),
-      llvm::UndefValue::get(CGM.getTypes().ConvertType(attr->getTypeHint())),
+      llvm::UndefValue::get(CGM.getTypes().ConvertType(A->getTypeHint())),
       llvm::ConstantInt::get(
           llvm::IntegerType::get(Context, 32),
           llvm::APInt(32, (uint64_t)(isSignedInteger ? 1 : 0)))
@@ -455,24 +477,22 @@
     kernelMDArgs.push_back(llvm::MDNode::get(Context, attrMDArgs));
   }
 
-  if (FD->hasAttr<WorkGroupSizeHintAttr>()) {
-    WorkGroupSizeHintAttr *attr = FD->getAttr<WorkGroupSizeHintAttr>();
+  if (const WorkGroupSizeHintAttr *A = FD->getAttr<WorkGroupSizeHintAttr>()) {
     llvm::Value *attrMDArgs[] = {
       llvm::MDString::get(Context, "work_group_size_hint"),
-      Builder.getInt32(attr->getXDim()),
-      Builder.getInt32(attr->getYDim()),
-      Builder.getInt32(attr->getZDim())
+      Builder.getInt32(A->getXDim()),
+      Builder.getInt32(A->getYDim()),
+      Builder.getInt32(A->getZDim())
     };
     kernelMDArgs.push_back(llvm::MDNode::get(Context, attrMDArgs));
   }
 
-  if (FD->hasAttr<ReqdWorkGroupSizeAttr>()) {
-    ReqdWorkGroupSizeAttr *attr = FD->getAttr<ReqdWorkGroupSizeAttr>();
+  if (const ReqdWorkGroupSizeAttr *A = FD->getAttr<ReqdWorkGroupSizeAttr>()) {
     llvm::Value *attrMDArgs[] = {
       llvm::MDString::get(Context, "reqd_work_group_size"),
-      Builder.getInt32(attr->getXDim()),
-      Builder.getInt32(attr->getYDim()),
-      Builder.getInt32(attr->getZDim())
+      Builder.getInt32(A->getXDim()),
+      Builder.getInt32(A->getYDim()),
+      Builder.getInt32(A->getZDim())
     };
     kernelMDArgs.push_back(llvm::MDNode::get(Context, attrMDArgs));
   }
@@ -483,37 +503,55 @@
   OpenCLKernelMetadata->addOperand(kernelMDNode);
 }
 
+/// Determine whether the function F ends with a return stmt.
+static bool endsWithReturn(const Decl* F) {
+  const Stmt *Body = nullptr;
+  if (auto *FD = dyn_cast_or_null<FunctionDecl>(F))
+    Body = FD->getBody();
+  else if (auto *OMD = dyn_cast_or_null<ObjCMethodDecl>(F))
+    Body = OMD->getBody();
+
+  if (auto *CS = dyn_cast_or_null<CompoundStmt>(Body)) {
+    auto LastStmt = CS->body_rbegin();
+    if (LastStmt != CS->body_rend())
+      return isa<ReturnStmt>(*LastStmt);
+  }
+  return false;
+}
+
 void CodeGenFunction::StartFunction(GlobalDecl GD,
                                     QualType RetTy,
                                     llvm::Function *Fn,
                                     const CGFunctionInfo &FnInfo,
                                     const FunctionArgList &Args,
+                                    SourceLocation Loc,
                                     SourceLocation StartLoc) {
   const Decl *D = GD.getDecl();
 
   DidCallStackSave = false;
   CurCodeDecl = D;
-  CurFuncDecl = (D ? D->getNonClosureContext() : 0);
+  CurFuncDecl = (D ? D->getNonClosureContext() : nullptr);
   FnRetTy = RetTy;
   CurFn = Fn;
   CurFnInfo = &FnInfo;
   assert(CurFn->isDeclaration() && "Function already has body?");
 
-  if (CGM.getSanitizerBlacklist().isIn(*Fn)) {
+  if (CGM.getSanitizerBlacklist().isIn(*Fn))
     SanOpts = &SanitizerOptions::Disabled;
-    SanitizePerformTypeCheck = false;
-  }
 
   // Pass inline keyword to optimizer if it appears explicitly on any
-  // declaration.
-  if (!CGM.getCodeGenOpts().NoInline)
-    if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
-      for (FunctionDecl::redecl_iterator RI = FD->redecls_begin(),
-             RE = FD->redecls_end(); RI != RE; ++RI)
+  // declaration. Also, in the case of -fno-inline attach NoInline
+  // attribute to all function that are not marked AlwaysInline.
+  if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) {
+    if (!CGM.getCodeGenOpts().NoInline) {
+      for (auto RI : FD->redecls())
         if (RI->isInlineSpecified()) {
           Fn->addFnAttr(llvm::Attribute::InlineHint);
           break;
         }
+    } else if (!FD->hasAttr<AlwaysInlineAttr>())
+      Fn->addFnAttr(llvm::Attribute::NoInline);
+  }
 
   if (getLangOpts().OpenCL) {
     // Add metadata for a kernel function.
@@ -562,9 +600,7 @@
     QualType FnType =
       getContext().getFunctionType(RetTy, ArgTypes,
                                    FunctionProtoType::ExtProtoInfo());
-
-    DI->setLocation(StartLoc);
-    DI->EmitFunctionStart(GD, FnType, CurFn, Builder);
+    DI->EmitFunctionStart(GD, Loc, StartLoc, FnType, CurFn, Builder);
   }
 
   if (ShouldInstrumentFunction())
@@ -575,12 +611,27 @@
 
   if (RetTy->isVoidType()) {
     // Void type; nothing to return.
-    ReturnValue = 0;
+    ReturnValue = nullptr;
+
+    // Count the implicit return.
+    if (!endsWithReturn(D))
+      ++NumReturnExprs;
   } else if (CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::Indirect &&
              !hasScalarEvaluationKind(CurFnInfo->getReturnType())) {
     // Indirect aggregate return; emit returned value directly into sret slot.
     // This reduces code size, and affects correctness in C++.
-    ReturnValue = CurFn->arg_begin();
+    auto AI = CurFn->arg_begin();
+    if (CurFnInfo->getReturnInfo().isSRetAfterThis())
+      ++AI;
+    ReturnValue = AI;
+  } else if (CurFnInfo->getReturnInfo().getKind() == ABIArgInfo::InAlloca &&
+             !hasScalarEvaluationKind(CurFnInfo->getReturnType())) {
+    // Load the sret pointer from the argument struct and return into that.
+    unsigned Idx = CurFnInfo->getReturnInfo().getInAllocaFieldIndex();
+    llvm::Function::arg_iterator EI = CurFn->arg_end();
+    --EI;
+    llvm::Value *Addr = Builder.CreateStructGEP(EI, Idx);
+    ReturnValue = Builder.CreateLoad(Addr, "agg.result");
   } else {
     ReturnValue = CreateIRTemp(RetTy, "retval");
 
@@ -645,12 +696,34 @@
 
 void CodeGenFunction::EmitFunctionBody(FunctionArgList &Args,
                                        const Stmt *Body) {
+  RegionCounter Cnt = getPGORegionCounter(Body);
+  Cnt.beginRegion(Builder);
   if (const CompoundStmt *S = dyn_cast<CompoundStmt>(Body))
     EmitCompoundStmtWithoutScope(*S);
   else
     EmitStmt(Body);
 }
 
+/// When instrumenting to collect profile data, the counts for some blocks
+/// such as switch cases need to not include the fall-through counts, so
+/// emit a branch around the instrumentation code. When not instrumenting,
+/// this just calls EmitBlock().
+void CodeGenFunction::EmitBlockWithFallThrough(llvm::BasicBlock *BB,
+                                               RegionCounter &Cnt) {
+  llvm::BasicBlock *SkipCountBB = nullptr;
+  if (HaveInsertPoint() && CGM.getCodeGenOpts().ProfileInstrGenerate) {
+    // When instrumenting for profiling, the fallthrough to certain
+    // statements needs to skip over the instrumentation code so that we
+    // get an accurate count.
+    SkipCountBB = createBasicBlock("skipcount");
+    EmitBranch(SkipCountBB);
+  }
+  EmitBlock(BB);
+  Cnt.beginRegion(Builder, /*AddIncomingFallThrough=*/true);
+  if (SkipCountBB)
+    EmitBlock(SkipCountBB);
+}
+
 /// Tries to mark the given function nounwind based on the
 /// non-existence of any throwing calls within it.  We believe this is
 /// lightweight enough to do at -O0.
@@ -688,30 +761,47 @@
 
   // Check if we should generate debug info for this function.
   if (FD->hasAttr<NoDebugAttr>())
-    DebugInfo = NULL; // disable debug info indefinitely for this function
+    DebugInfo = nullptr; // disable debug info indefinitely for this function
 
   FunctionArgList Args;
-  QualType ResTy = FD->getResultType();
+  QualType ResTy = FD->getReturnType();
 
   CurGD = GD;
-  const CXXMethodDecl *MD;
-  if ((MD = dyn_cast<CXXMethodDecl>(FD)) && MD->isInstance()) {
+  const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
+  if (MD && MD->isInstance()) {
     if (CGM.getCXXABI().HasThisReturn(GD))
       ResTy = MD->getThisType(getContext());
-    CGM.getCXXABI().BuildInstanceFunctionParams(*this, ResTy, Args);
+    CGM.getCXXABI().buildThisParam(*this, Args);
   }
 
   for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i)
     Args.push_back(FD->getParamDecl(i));
 
+  if (MD && (isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD)))
+    CGM.getCXXABI().addImplicitStructorParams(*this, ResTy, Args);
+
   SourceRange BodyRange;
   if (Stmt *Body = FD->getBody()) BodyRange = Body->getSourceRange();
   CurEHLocation = BodyRange.getEnd();
 
+  // Use the location of the start of the function to determine where
+  // the function definition is located. By default use the location
+  // of the declaration as the location for the subprogram. A function
+  // may lack a declaration in the source code if it is created by code
+  // gen. (examples: _GLOBAL__I_a, __cxx_global_array_dtor, thunk).
+  SourceLocation Loc = FD->getLocation();
+
+  // If this is a function specialization then use the pattern body
+  // as the location for the function.
+  if (const FunctionDecl *SpecDecl = FD->getTemplateInstantiationPattern())
+    if (SpecDecl->hasBody(SpecDecl))
+      Loc = SpecDecl->getLocation();
+
   // Emit the standard function prologue.
-  StartFunction(GD, ResTy, Fn, FnInfo, Args, BodyRange.getBegin());
+  StartFunction(GD, ResTy, Fn, FnInfo, Args, Loc, BodyRange.getBegin());
 
   // Generate the body of the function.
+  PGO.assignRegionCounters(GD.getDecl(), CurFn);
   if (isa<CXXDestructorDecl>(FD))
     EmitDestructorBody(Args);
   else if (isa<CXXConstructorDecl>(FD))
@@ -753,12 +843,13 @@
   //   If the '}' that terminates a function is reached, and the value of the
   //   function call is used by the caller, the behavior is undefined.
   if (getLangOpts().CPlusPlus && !FD->hasImplicitReturnZero() &&
-      !FD->getResultType()->isVoidType() && Builder.GetInsertBlock()) {
-    if (SanOpts->Return)
+      !FD->getReturnType()->isVoidType() && Builder.GetInsertBlock()) {
+    if (SanOpts->Return) {
+      SanitizerScope SanScope(this);
       EmitCheck(Builder.getFalse(), "missing_return",
                 EmitCheckSourceLocation(FD->getLocation()),
                 ArrayRef<llvm::Value *>(), CRK_Unrecoverable);
-    else if (CGM.getCodeGenOpts().OptimizationLevel == 0)
+    } else if (CGM.getCodeGenOpts().OptimizationLevel == 0)
       Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::trap));
     Builder.CreateUnreachable();
     Builder.ClearInsertionPoint();
@@ -771,6 +862,9 @@
   // a quick pass now to see if we can.
   if (!CurFn->doesNotThrow())
     TryMarkNoThrow(CurFn);
+
+  PGO.emitInstrumentationData();
+  PGO.destroyRegionCounters();
 }
 
 /// ContainsLabel - Return true if the statement contains a label in it.  If
@@ -778,7 +872,7 @@
 /// that we can just remove the code.
 bool CodeGenFunction::ContainsLabel(const Stmt *S, bool IgnoreCaseStmts) {
   // Null statement, not a label!
-  if (S == 0) return false;
+  if (!S) return false;
 
   // If this is a label, we have to emit the code, consider something like:
   // if (0) {  ...  foo:  bar(); }  goto foo;
@@ -810,7 +904,7 @@
 /// inside of it, this is fine.
 bool CodeGenFunction::containsBreak(const Stmt *S) {
   // Null statement, not a label!
-  if (S == 0) return false;
+  if (!S) return false;
 
   // If this is a switch or loop that defines its own break scope, then we can
   // include it and anything inside of it.
@@ -869,19 +963,25 @@
 ///
 void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond,
                                            llvm::BasicBlock *TrueBlock,
-                                           llvm::BasicBlock *FalseBlock) {
+                                           llvm::BasicBlock *FalseBlock,
+                                           uint64_t TrueCount) {
   Cond = Cond->IgnoreParens();
 
   if (const BinaryOperator *CondBOp = dyn_cast<BinaryOperator>(Cond)) {
+
     // Handle X && Y in a condition.
     if (CondBOp->getOpcode() == BO_LAnd) {
+      RegionCounter Cnt = getPGORegionCounter(CondBOp);
+
       // If we have "1 && X", simplify the code.  "0 && X" would have constant
       // folded if the case was simple enough.
       bool ConstantBool = false;
       if (ConstantFoldsToSimpleInteger(CondBOp->getLHS(), ConstantBool) &&
           ConstantBool) {
         // br(1 && X) -> br(X).
-        return EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock);
+        Cnt.beginRegion(Builder);
+        return EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock,
+                                    TrueCount);
       }
 
       // If we have "X && 1", simplify the code to use an uncond branch.
@@ -889,33 +989,42 @@
       if (ConstantFoldsToSimpleInteger(CondBOp->getRHS(), ConstantBool) &&
           ConstantBool) {
         // br(X && 1) -> br(X).
-        return EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, FalseBlock);
+        return EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, FalseBlock,
+                                    TrueCount);
       }
 
       // Emit the LHS as a conditional.  If the LHS conditional is false, we
       // want to jump to the FalseBlock.
       llvm::BasicBlock *LHSTrue = createBasicBlock("land.lhs.true");
+      // The counter tells us how often we evaluate RHS, and all of TrueCount
+      // can be propagated to that branch.
+      uint64_t RHSCount = Cnt.getCount();
 
       ConditionalEvaluation eval(*this);
-      EmitBranchOnBoolExpr(CondBOp->getLHS(), LHSTrue, FalseBlock);
+      EmitBranchOnBoolExpr(CondBOp->getLHS(), LHSTrue, FalseBlock, RHSCount);
       EmitBlock(LHSTrue);
 
       // Any temporaries created here are conditional.
+      Cnt.beginRegion(Builder);
       eval.begin(*this);
-      EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock);
+      EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock, TrueCount);
       eval.end(*this);
 
       return;
     }
 
     if (CondBOp->getOpcode() == BO_LOr) {
+      RegionCounter Cnt = getPGORegionCounter(CondBOp);
+
       // If we have "0 || X", simplify the code.  "1 || X" would have constant
       // folded if the case was simple enough.
       bool ConstantBool = false;
       if (ConstantFoldsToSimpleInteger(CondBOp->getLHS(), ConstantBool) &&
           !ConstantBool) {
         // br(0 || X) -> br(X).
-        return EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock);
+        Cnt.beginRegion(Builder);
+        return EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock,
+                                    TrueCount);
       }
 
       // If we have "X || 0", simplify the code to use an uncond branch.
@@ -923,20 +1032,28 @@
       if (ConstantFoldsToSimpleInteger(CondBOp->getRHS(), ConstantBool) &&
           !ConstantBool) {
         // br(X || 0) -> br(X).
-        return EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, FalseBlock);
+        return EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, FalseBlock,
+                                    TrueCount);
       }
 
       // Emit the LHS as a conditional.  If the LHS conditional is true, we
       // want to jump to the TrueBlock.
       llvm::BasicBlock *LHSFalse = createBasicBlock("lor.lhs.false");
+      // We have the count for entry to the RHS and for the whole expression
+      // being true, so we can divy up True count between the short circuit and
+      // the RHS.
+      uint64_t LHSCount = Cnt.getParentCount() - Cnt.getCount();
+      uint64_t RHSCount = TrueCount - LHSCount;
 
       ConditionalEvaluation eval(*this);
-      EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, LHSFalse);
+      EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, LHSFalse, LHSCount);
       EmitBlock(LHSFalse);
 
       // Any temporaries created here are conditional.
+      Cnt.beginRegion(Builder);
       eval.begin(*this);
-      EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock);
+      EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock, RHSCount);
+
       eval.end(*this);
 
       return;
@@ -945,8 +1062,13 @@
 
   if (const UnaryOperator *CondUOp = dyn_cast<UnaryOperator>(Cond)) {
     // br(!x, t, f) -> br(x, f, t)
-    if (CondUOp->getOpcode() == UO_LNot)
-      return EmitBranchOnBoolExpr(CondUOp->getSubExpr(), FalseBlock, TrueBlock);
+    if (CondUOp->getOpcode() == UO_LNot) {
+      // Negate the count.
+      uint64_t FalseCount = PGO.getCurrentRegionCount() - TrueCount;
+      // Negate the condition and swap the destination blocks.
+      return EmitBranchOnBoolExpr(CondUOp->getSubExpr(), FalseBlock, TrueBlock,
+                                  FalseCount);
+    }
   }
 
   if (const ConditionalOperator *CondOp = dyn_cast<ConditionalOperator>(Cond)) {
@@ -954,17 +1076,32 @@
     llvm::BasicBlock *LHSBlock = createBasicBlock("cond.true");
     llvm::BasicBlock *RHSBlock = createBasicBlock("cond.false");
 
+    RegionCounter Cnt = getPGORegionCounter(CondOp);
     ConditionalEvaluation cond(*this);
-    EmitBranchOnBoolExpr(CondOp->getCond(), LHSBlock, RHSBlock);
+    EmitBranchOnBoolExpr(CondOp->getCond(), LHSBlock, RHSBlock, Cnt.getCount());
+
+    // When computing PGO branch weights, we only know the overall count for
+    // the true block. This code is essentially doing tail duplication of the
+    // naive code-gen, introducing new edges for which counts are not
+    // available. Divide the counts proportionally between the LHS and RHS of
+    // the conditional operator.
+    uint64_t LHSScaledTrueCount = 0;
+    if (TrueCount) {
+      double LHSRatio = Cnt.getCount() / (double) Cnt.getParentCount();
+      LHSScaledTrueCount = TrueCount * LHSRatio;
+    }
 
     cond.begin(*this);
     EmitBlock(LHSBlock);
-    EmitBranchOnBoolExpr(CondOp->getLHS(), TrueBlock, FalseBlock);
+    Cnt.beginRegion(Builder);
+    EmitBranchOnBoolExpr(CondOp->getLHS(), TrueBlock, FalseBlock,
+                         LHSScaledTrueCount);
     cond.end(*this);
 
     cond.begin(*this);
     EmitBlock(RHSBlock);
-    EmitBranchOnBoolExpr(CondOp->getRHS(), TrueBlock, FalseBlock);
+    EmitBranchOnBoolExpr(CondOp->getRHS(), TrueBlock, FalseBlock,
+                         TrueCount - LHSScaledTrueCount);
     cond.end(*this);
 
     return;
@@ -980,9 +1117,15 @@
     return;
   }
 
+  // Create branch weights based on the number of times we get here and the
+  // number of times the condition should be true.
+  uint64_t CurrentCount = std::max(PGO.getCurrentRegionCount(), TrueCount);
+  llvm::MDNode *Weights = PGO.createBranchWeights(TrueCount,
+                                                  CurrentCount - TrueCount);
+
   // Emit the code with the fully general case.
   llvm::Value *CondV = EvaluateExprAsBool(Cond);
-  Builder.CreateCondBr(CondV, TrueBlock, FalseBlock);
+  Builder.CreateCondBr(CondV, TrueBlock, FalseBlock, Weights);
 }
 
 /// ErrorUnsupported - Print out an error that codegen doesn't support the
@@ -1075,7 +1218,7 @@
                                           getContext().getAsArrayType(Ty))) {
       QualType eltType;
       llvm::Value *numElts;
-      llvm::tie(numElts, eltType) = getVLASize(vlaType);
+      std::tie(numElts, eltType) = getVLASize(vlaType);
 
       SizeVal = numElts;
       CharUnits eltSize = getContext().getTypeSizeInChars(eltType);
@@ -1087,7 +1230,7 @@
     }
   } else {
     SizeVal = CGM.getSize(Size);
-    vla = 0;
+    vla = nullptr;
   }
 
   // If the type contains a pointer to data member we can't memset it to zero.
@@ -1124,7 +1267,7 @@
 
 llvm::BlockAddress *CodeGenFunction::GetAddrOfLabel(const LabelDecl *L) {
   // Make sure that there is a block for the indirect goto.
-  if (IndirectBranch == 0)
+  if (!IndirectBranch)
     GetIndirectGotoBlock();
 
   llvm::BasicBlock *BB = getJumpDestForLabel(L).getBlock();
@@ -1158,7 +1301,7 @@
 
   // If it's a VLA, we have to load the stored size.  Note that
   // this is the size of the VLA in bytes, not its size in elements.
-  llvm::Value *numVLAElements = 0;
+  llvm::Value *numVLAElements = nullptr;
   if (isa<VariableArrayType>(arrayType)) {
     numVLAElements = getVLASize(cast<VariableArrayType>(arrayType)).first;
 
@@ -1251,7 +1394,7 @@
 std::pair<llvm::Value*, QualType>
 CodeGenFunction::getVLASize(const VariableArrayType *type) {
   // The number of elements so far; always size_t.
-  llvm::Value *numElements = 0;
+  llvm::Value *numElements = nullptr;
 
   QualType elementType;
   do {
@@ -1264,7 +1407,7 @@
       numElements = vlaSize;
     } else {
       // It's undefined behavior if this wraps around, so mark it that way.
-      // FIXME: Teach -fcatch-undefined-behavior to trap this.
+      // FIXME: Teach -fsanitize=undefined to trap this.
       numElements = Builder.CreateNUWMul(numElements, vlaSize);
     }
   } while ((type = getContext().getAsVariableArrayType(elementType)));
@@ -1308,6 +1451,10 @@
     case Type::ObjCObjectPointer:
       llvm_unreachable("type class is never variably-modified!");
 
+    case Type::Adjusted:
+      type = cast<AdjustedType>(ty)->getAdjustedType();
+      break;
+
     case Type::Decayed:
       type = cast<DecayedType>(ty)->getPointeeType();
       break;
@@ -1354,6 +1501,7 @@
           //   greater than zero.
           if (SanOpts->VLABound &&
               size->getType()->isSignedIntegerType()) {
+            SanitizerScope SanScope(this);
             llvm::Value *Zero = llvm::Constant::getNullValue(Size->getType());
             llvm::Constant *StaticArgs[] = {
               EmitCheckSourceLocation(size->getLocStart()),
@@ -1375,7 +1523,7 @@
 
     case Type::FunctionProto:
     case Type::FunctionNoProto:
-      type = cast<FunctionType>(ty)->getResultType();
+      type = cast<FunctionType>(ty)->getReturnType();
       break;
 
     case Type::Paren:
@@ -1464,12 +1612,10 @@
   assert(D->hasAttr<AnnotateAttr>() && "no annotate attribute");
   // FIXME We create a new bitcast for every annotation because that's what
   // llvm-gcc was doing.
-  for (specific_attr_iterator<AnnotateAttr>
-       ai = D->specific_attr_begin<AnnotateAttr>(),
-       ae = D->specific_attr_end<AnnotateAttr>(); ai != ae; ++ai)
+  for (const auto *I : D->specific_attrs<AnnotateAttr>())
     EmitAnnotationCall(CGM.getIntrinsic(llvm::Intrinsic::var_annotation),
                        Builder.CreateBitCast(V, CGM.Int8PtrTy, V->getName()),
-                       (*ai)->getAnnotation(), D->getLocation());
+                       I->getAnnotation(), D->getLocation());
 }
 
 llvm::Value *CodeGenFunction::EmitFieldAnnotations(const FieldDecl *D,
@@ -1479,15 +1625,13 @@
   llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::ptr_annotation,
                                     CGM.Int8PtrTy);
 
-  for (specific_attr_iterator<AnnotateAttr>
-       ai = D->specific_attr_begin<AnnotateAttr>(),
-       ae = D->specific_attr_end<AnnotateAttr>(); ai != ae; ++ai) {
+  for (const auto *I : D->specific_attrs<AnnotateAttr>()) {
     // FIXME Always emit the cast inst so we can differentiate between
     // annotation on the first field of a struct and annotation on the struct
     // itself.
     if (VTy != CGM.Int8PtrTy)
       V = Builder.Insert(new llvm::BitCastInst(V, CGM.Int8PtrTy));
-    V = EmitAnnotationCall(F, V, (*ai)->getAnnotation(), D->getLocation());
+    V = EmitAnnotationCall(F, V, I->getAnnotation(), D->getLocation());
     V = Builder.CreateBitCast(V, VTy);
   }
 
@@ -1495,3 +1639,45 @@
 }
 
 CodeGenFunction::CGCapturedStmtInfo::~CGCapturedStmtInfo() { }
+
+CodeGenFunction::SanitizerScope::SanitizerScope(CodeGenFunction *CGF)
+    : CGF(CGF) {
+  assert(!CGF->IsSanitizerScope);
+  CGF->IsSanitizerScope = true;
+}
+
+CodeGenFunction::SanitizerScope::~SanitizerScope() {
+  CGF->IsSanitizerScope = false;
+}
+
+void CodeGenFunction::InsertHelper(llvm::Instruction *I,
+                                   const llvm::Twine &Name,
+                                   llvm::BasicBlock *BB,
+                                   llvm::BasicBlock::iterator InsertPt) const {
+  LoopStack.InsertHelper(I);
+  if (IsSanitizerScope) {
+    I->setMetadata(
+        CGM.getModule().getMDKindID("nosanitize"),
+        llvm::MDNode::get(CGM.getLLVMContext(), ArrayRef<llvm::Value *>()));
+  }
+}
+
+template <bool PreserveNames>
+void CGBuilderInserter<PreserveNames>::InsertHelper(
+    llvm::Instruction *I, const llvm::Twine &Name, llvm::BasicBlock *BB,
+    llvm::BasicBlock::iterator InsertPt) const {
+  llvm::IRBuilderDefaultInserter<PreserveNames>::InsertHelper(I, Name, BB,
+                                                              InsertPt);
+  if (CGF)
+    CGF->InsertHelper(I, Name, BB, InsertPt);
+}
+
+#ifdef NDEBUG
+#define PreserveNames false
+#else
+#define PreserveNames true
+#endif
+template void CGBuilderInserter<PreserveNames>::InsertHelper(
+    llvm::Instruction *I, const llvm::Twine &Name, llvm::BasicBlock *BB,
+    llvm::BasicBlock::iterator InsertPt) const;
+#undef PreserveNames
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index db291e3..59cc30d 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -16,9 +16,11 @@
 
 #include "CGBuilder.h"
 #include "CGDebugInfo.h"
+#include "CGLoopInfo.h"
 #include "CGValue.h"
-#include "EHScopeStack.h"
 #include "CodeGenModule.h"
+#include "CodeGenPGO.h"
+#include "EHScopeStack.h"
 #include "clang/AST/CharUnits.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
@@ -30,55 +32,55 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/ValueHandle.h"
 #include "llvm/Support/Debug.h"
-#include "llvm/Support/ValueHandle.h"
 
 namespace llvm {
-  class BasicBlock;
-  class LLVMContext;
-  class MDNode;
-  class Module;
-  class SwitchInst;
-  class Twine;
-  class Value;
-  class CallSite;
+class BasicBlock;
+class LLVMContext;
+class MDNode;
+class Module;
+class SwitchInst;
+class Twine;
+class Value;
+class CallSite;
 }
 
 namespace clang {
-  class ASTContext;
-  class BlockDecl;
-  class CXXDestructorDecl;
-  class CXXForRangeStmt;
-  class CXXTryStmt;
-  class Decl;
-  class LabelDecl;
-  class EnumConstantDecl;
-  class FunctionDecl;
-  class FunctionProtoType;
-  class LabelStmt;
-  class ObjCContainerDecl;
-  class ObjCInterfaceDecl;
-  class ObjCIvarDecl;
-  class ObjCMethodDecl;
-  class ObjCImplementationDecl;
-  class ObjCPropertyImplDecl;
-  class TargetInfo;
-  class TargetCodeGenInfo;
-  class VarDecl;
-  class ObjCForCollectionStmt;
-  class ObjCAtTryStmt;
-  class ObjCAtThrowStmt;
-  class ObjCAtSynchronizedStmt;
-  class ObjCAutoreleasePoolStmt;
+class ASTContext;
+class BlockDecl;
+class CXXDestructorDecl;
+class CXXForRangeStmt;
+class CXXTryStmt;
+class Decl;
+class LabelDecl;
+class EnumConstantDecl;
+class FunctionDecl;
+class FunctionProtoType;
+class LabelStmt;
+class ObjCContainerDecl;
+class ObjCInterfaceDecl;
+class ObjCIvarDecl;
+class ObjCMethodDecl;
+class ObjCImplementationDecl;
+class ObjCPropertyImplDecl;
+class TargetInfo;
+class TargetCodeGenInfo;
+class VarDecl;
+class ObjCForCollectionStmt;
+class ObjCAtTryStmt;
+class ObjCAtThrowStmt;
+class ObjCAtSynchronizedStmt;
+class ObjCAutoreleasePoolStmt;
 
 namespace CodeGen {
-  class CodeGenTypes;
-  class CGFunctionInfo;
-  class CGRecordLayout;
-  class CGBlockInfo;
-  class CGCXXABI;
-  class BlockFlags;
-  class BlockFieldFlags;
+class CodeGenTypes;
+class CGFunctionInfo;
+class CGRecordLayout;
+class CGBlockInfo;
+class CGCXXABI;
+class BlockFlags;
+class BlockFieldFlags;
 
 /// The kind of evaluation to perform on values of a particular
 /// type.  Basically, is the code in CGExprScalar, CGExprComplex, or
@@ -91,6 +93,19 @@
   TEK_Aggregate
 };
 
+class SuppressDebugLocation {
+  llvm::DebugLoc CurLoc;
+  llvm::IRBuilderBase &Builder;
+public:
+  SuppressDebugLocation(llvm::IRBuilderBase &Builder)
+      : CurLoc(Builder.getCurrentDebugLocation()), Builder(Builder) {
+    Builder.SetCurrentDebugLocation(llvm::DebugLoc());
+  }
+  ~SuppressDebugLocation() {
+    Builder.SetCurrentDebugLocation(CurLoc);
+  }
+};
+
 /// CodeGenFunction - This class organizes the per-function state that is used
 /// while generating LLVM code.
 class CodeGenFunction : public CodeGenTypeCache {
@@ -102,13 +117,13 @@
   /// A jump destination is an abstract label, branching to which may
   /// require a jump out through normal cleanups.
   struct JumpDest {
-    JumpDest() : Block(0), ScopeDepth(), Index(0) {}
+    JumpDest() : Block(nullptr), ScopeDepth(), Index(0) {}
     JumpDest(llvm::BasicBlock *Block,
              EHScopeStack::stable_iterator Depth,
              unsigned Index)
       : Block(Block), ScopeDepth(Depth), Index(Index) {}
 
-    bool isValid() const { return Block != 0; }
+    bool isValid() const { return Block != nullptr; }
     llvm::BasicBlock *getBlock() const { return Block; }
     EHScopeStack::stable_iterator getScopeDepth() const { return ScopeDepth; }
     unsigned getDestIndex() const { return Index; }
@@ -128,8 +143,15 @@
   const TargetInfo &Target;
 
   typedef std::pair<llvm::Value *, llvm::Value *> ComplexPairTy;
+  LoopInfoStack LoopStack;
   CGBuilderTy Builder;
 
+  /// \brief CGBuilder insert helper. This function is called after an
+  /// instruction is created using Builder.
+  void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name,
+                    llvm::BasicBlock *BB,
+                    llvm::BasicBlock::iterator InsertPt) const;
+
   /// CurFuncDecl - Holds the Decl for the current outermost
   /// non-closure context.
   const Decl *CurFuncDecl;
@@ -162,7 +184,7 @@
   public:
     explicit CGCapturedStmtInfo(const CapturedStmt &S,
                                 CapturedRegionKind K = CR_Default)
-      : Kind(K), ThisValue(0), CXXThisFieldDecl(0) {
+      : Kind(K), ThisValue(nullptr), CXXThisFieldDecl(nullptr) {
 
       RecordDecl::field_iterator Field =
         S.getCapturedRecordDecl()->field_begin();
@@ -189,11 +211,13 @@
       return CaptureFields.lookup(VD);
     }
 
-    bool isCXXThisExprCaptured() const { return CXXThisFieldDecl != 0; }
+    bool isCXXThisExprCaptured() const { return CXXThisFieldDecl != nullptr; }
     FieldDecl *getThisFieldDecl() const { return CXXThisFieldDecl; }
 
     /// \brief Emit the captured statement body.
     virtual void EmitBody(CodeGenFunction &CGF, Stmt *S) {
+      RegionCounter Cnt = CGF.getPGORegionCounter(S);
+      Cnt.beginRegion(CGF.Builder);
       CGF.EmitStmt(S);
     }
 
@@ -220,13 +244,20 @@
   /// potentially higher performance penalties.
   unsigned char BoundsChecking;
 
-  /// \brief Whether any type-checking sanitizers are enabled. If \c false,
-  /// calls to EmitTypeCheck can be skipped.
-  bool SanitizePerformTypeCheck;
-
   /// \brief Sanitizer options to use for this function.
   const SanitizerOptions *SanOpts;
 
+  /// \brief True if CodeGen currently emits code implementing sanitizer checks.
+  bool IsSanitizerScope;
+
+  /// \brief RAII object to set/unset CodeGenFunction::IsSanitizerScope.
+  class SanitizerScope {
+    CodeGenFunction *CGF;
+  public:
+    SanitizerScope(CodeGenFunction *CGF);
+    ~SanitizerScope();
+  };
+
   /// In ARC, whether we should autorelease the return value.
   bool AutoreleaseResult;
 
@@ -608,9 +639,9 @@
     }
 
     void end(CodeGenFunction &CGF) {
-      assert(CGF.OutermostConditional != 0);
+      assert(CGF.OutermostConditional != nullptr);
       if (CGF.OutermostConditional == this)
-        CGF.OutermostConditional = 0;
+        CGF.OutermostConditional = nullptr;
     }
 
     /// Returns a block which will be executed prior to each
@@ -622,7 +653,7 @@
 
   /// isInConditionalBranch - Return true if we're currently emitting
   /// one branch or the other of a conditional expression.
-  bool isInConditionalBranch() const { return OutermostConditional != 0; }
+  bool isInConditionalBranch() const { return OutermostConditional != nullptr; }
 
   void setBeforeOutermostConditional(llvm::Value *value, llvm::Value *addr) {
     assert(isInConditionalBranch());
@@ -643,7 +674,7 @@
   public:
     StmtExprEvaluation(CodeGenFunction &CGF)
       : CGF(CGF), SavedOutermostConditional(CGF.OutermostConditional) {
-      CGF.OutermostConditional = 0;
+      CGF.OutermostConditional = nullptr;
     }
 
     ~StmtExprEvaluation() {
@@ -660,7 +691,7 @@
     friend class CodeGenFunction;
 
   public:
-    PeepholeProtection() : Inst(0) {}
+    PeepholeProtection() : Inst(nullptr) {}
   };
 
   /// A non-RAII class containing all the information about a bound
@@ -678,7 +709,7 @@
                            bool boundLValue)
       : OpaqueValue(ov), BoundLValue(boundLValue) {}
   public:
-    OpaqueValueMappingData() : OpaqueValue(0) {}
+    OpaqueValueMappingData() : OpaqueValue(nullptr) {}
 
     static bool shouldBindAsLValue(const Expr *expr) {
       // gl-values should be bound as l-values for obvious reasons.
@@ -687,8 +718,8 @@
       // act exactly like l-values but are formally required to be
       // r-values in C.
       return expr->isGLValue() ||
-             expr->getType()->isRecordType() ||
-             expr->getType()->isFunctionType();
+             expr->getType()->isFunctionType() ||
+             hasAggregateEvaluationKind(expr->getType());
     }
 
     static OpaqueValueMappingData bind(CodeGenFunction &CGF,
@@ -723,8 +754,8 @@
       return data;
     }
 
-    bool isValid() const { return OpaqueValue != 0; }
-    void clear() { OpaqueValue = 0; }
+    bool isValid() const { return OpaqueValue != nullptr; }
+    void clear() { OpaqueValue = nullptr; }
 
     void unbind(CodeGenFunction &CGF) {
       assert(OpaqueValue && "no data to unbind!");
@@ -827,9 +858,21 @@
   };
   SmallVector<BreakContinue, 8> BreakContinueStack;
 
+  CodeGenPGO PGO;
+
+public:
+  /// Get a counter for instrumentation of the region associated with the given
+  /// statement.
+  RegionCounter getPGORegionCounter(const Stmt *S) {
+    return RegionCounter(PGO, S);
+  }
+private:
+
   /// SwitchInsn - This is nearest current switch instruction. It is null if
   /// current context is not in a switch.
   llvm::SwitchInst *SwitchInsn;
+  /// The branch weights of SwitchInsn when doing instrumentation based PGO.
+  SmallVector<uint64_t, 16> *SwitchWeights;
 
   /// CaseRangeBlock - This block holds if condition check for last case
   /// statement range in current switch instruction.
@@ -955,7 +998,7 @@
   ASTContext &getContext() const { return CGM.getContext(); }
   CGDebugInfo *getDebugInfo() { 
     if (DisableDebugInfo) 
-      return NULL;
+      return nullptr;
     return DebugInfo; 
   }
   void disableDebugInfo() { DisableDebugInfo = true; }
@@ -988,7 +1031,7 @@
   }
 
   llvm::BasicBlock *getInvokeDest() {
-    if (!EHStack.requiresLandingPad()) return 0;
+    if (!EHStack.requiresLandingPad()) return nullptr;
     return getInvokeDestImpl();
   }
 
@@ -1019,6 +1062,7 @@
   void pushLifetimeExtendedDestroy(CleanupKind kind, llvm::Value *addr,
                                    QualType type, Destroyer *destroyer,
                                    bool useEHCleanupForArray);
+  void pushStackRestore(CleanupKind kind, llvm::Value *SPMem);
   void emitDestroy(llvm::Value *addr, QualType type, Destroyer *destroyer,
                    bool useEHCleanupForArray);
   llvm::Function *generateDestroyHelper(llvm::Constant *addr, QualType type,
@@ -1126,17 +1170,22 @@
 
   void GenerateCode(GlobalDecl GD, llvm::Function *Fn,
                     const CGFunctionInfo &FnInfo);
+  /// \brief Emit code for the start of a function.
+  /// \param Loc       The location to be associated with the function.
+  /// \param StartLoc  The location of the function body.
   void StartFunction(GlobalDecl GD,
                      QualType RetTy,
                      llvm::Function *Fn,
                      const CGFunctionInfo &FnInfo,
                      const FunctionArgList &Args,
-                     SourceLocation StartLoc);
+                     SourceLocation Loc = SourceLocation(),
+                     SourceLocation StartLoc = SourceLocation());
 
   void EmitConstructorBody(FunctionArgList &Args);
   void EmitDestructorBody(FunctionArgList &Args);
   void emitImplicitAssignmentOperatorBody(FunctionArgList &Args);
   void EmitFunctionBody(FunctionArgList &Args, const Stmt *Body);
+  void EmitBlockWithFallThrough(llvm::BasicBlock *BB, RegionCounter &Cnt);
 
   void EmitForwardingCallToLambda(const CXXMethodDecl *LambdaCallOperator,
                                   CallArgList &CallArgs);
@@ -1270,8 +1319,8 @@
 
   /// createBasicBlock - Create an LLVM basic block.
   llvm::BasicBlock *createBasicBlock(const Twine &name = "",
-                                     llvm::Function *parent = 0,
-                                     llvm::BasicBlock *before = 0) {
+                                     llvm::Function *parent = nullptr,
+                                     llvm::BasicBlock *before = nullptr) {
 #ifdef NDEBUG
     return llvm::BasicBlock::Create(getLLVMContext(), "", parent, before);
 #else
@@ -1315,7 +1364,7 @@
   /// HaveInsertPoint - True if an insertion point is defined. If not, this
   /// indicates that the current code being emitted is unreachable.
   bool HaveInsertPoint() const {
-    return Builder.GetInsertBlock() != 0;
+    return Builder.GetInsertBlock() != nullptr;
   }
 
   /// EnsureInsertPoint - Ensure that an insertion point is defined so that
@@ -1380,6 +1429,10 @@
                                  AggValueSlot::IsNotAliased);
   }
 
+  /// CreateInAllocaTmp - Create a temporary memory object for the given
+  /// aggregate type.
+  AggValueSlot CreateInAllocaTmp(QualType T, const Twine &Name = "inalloca");
+
   /// Emit a cast to void* in the appropriate address space.
   llvm::Value *EmitCastToVoidPtr(llvm::Value *value);
 
@@ -1614,7 +1667,8 @@
                              llvm::Value *This);
 
   void EmitNewArrayInitializer(const CXXNewExpr *E, QualType elementType,
-                               llvm::Value *NewPtr, llvm::Value *NumElements);
+                               llvm::Value *NewPtr, llvm::Value *NumElements,
+                               llvm::Value *AllocSizeWithoutCookie);
 
   void EmitCXXTemporary(const CXXTemporary *Temporary, QualType TempType,
                         llvm::Value *Ptr);
@@ -1625,6 +1679,9 @@
   void EmitDeleteCall(const FunctionDecl *DeleteFD, llvm::Value *Ptr,
                       QualType DeleteTy);
 
+  RValue EmitBuiltinNewDeleteCall(const FunctionProtoType *Type,
+                                  const Expr *Arg, bool IsDelete);
+
   llvm::Value* EmitCXXTypeidExpr(const CXXTypeidExpr *E);
   llvm::Value *EmitDynamicCast(llvm::Value *V, const CXXDynamicCastExpr *DCE);
   llvm::Value* EmitCXXUuidofExpr(const CXXUuidofExpr *E);
@@ -1656,6 +1713,10 @@
     TCK_DowncastReference
   };
 
+  /// \brief Whether any type-checking sanitizers are enabled. If \c false,
+  /// calls to EmitTypeCheck can be skipped.
+  bool sanitizePerformTypeCheck() const;
+
   /// \brief Emit a check that \p V is the address of storage of the
   /// appropriate size and alignment for an object of type \p Type.
   void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, llvm::Value *V,
@@ -1722,19 +1783,21 @@
     llvm::Value *SizeForLifetimeMarkers;
 
     struct Invalid {};
-    AutoVarEmission(Invalid) : Variable(0) {}
+    AutoVarEmission(Invalid) : Variable(nullptr) {}
 
     AutoVarEmission(const VarDecl &variable)
-      : Variable(&variable), Address(0), NRVOFlag(0),
+      : Variable(&variable), Address(nullptr), NRVOFlag(nullptr),
         IsByRef(false), IsConstantAggregate(false),
-        SizeForLifetimeMarkers(0) {}
+        SizeForLifetimeMarkers(nullptr) {}
 
-    bool wasEmittedAsGlobal() const { return Address == 0; }
+    bool wasEmittedAsGlobal() const { return Address == nullptr; }
 
   public:
     static AutoVarEmission invalid() { return AutoVarEmission(Invalid()); }
 
-    bool useLifetimeMarkers() const { return SizeForLifetimeMarkers != 0; }
+    bool useLifetimeMarkers() const {
+      return SizeForLifetimeMarkers != nullptr;
+    }
     llvm::Value *getSizeForLifetimeMarkers() const {
       assert(useLifetimeMarkers());
       return SizeForLifetimeMarkers;
@@ -1767,7 +1830,8 @@
                          llvm::GlobalValue::LinkageTypes Linkage);
 
   /// EmitParmDecl - Emit a ParmVarDecl or an ImplicitParamDecl.
-  void EmitParmDecl(const VarDecl &D, llvm::Value *Arg, unsigned ArgNo);
+  void EmitParmDecl(const VarDecl &D, llvm::Value *Arg, bool ArgIsPointer,
+                    unsigned ArgNo);
 
   /// protectFromPeepholes - Protect a value that we're intending to
   /// store to the side, but which will probably be used later, from
@@ -1820,9 +1884,14 @@
   void EmitGotoStmt(const GotoStmt &S);
   void EmitIndirectGotoStmt(const IndirectGotoStmt &S);
   void EmitIfStmt(const IfStmt &S);
-  void EmitWhileStmt(const WhileStmt &S);
-  void EmitDoStmt(const DoStmt &S);
-  void EmitForStmt(const ForStmt &S);
+
+  void EmitCondBrHints(llvm::LLVMContext &Context, llvm::BranchInst *CondBr,
+                       const ArrayRef<const Attr *> &Attrs);
+  void EmitWhileStmt(const WhileStmt &S,
+                     const ArrayRef<const Attr *> &Attrs = None);
+  void EmitDoStmt(const DoStmt &S, const ArrayRef<const Attr *> &Attrs = None);
+  void EmitForStmt(const ForStmt &S,
+                   const ArrayRef<const Attr *> &Attrs = None);
   void EmitReturnStmt(const ReturnStmt &S);
   void EmitDeclStmt(const DeclStmt &S);
   void EmitBreakStmt(const BreakStmt &S);
@@ -1839,19 +1908,34 @@
   void EmitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt &S);
   void EmitObjCAutoreleasePoolStmt(const ObjCAutoreleasePoolStmt &S);
 
-  llvm::Constant *getUnwindResumeFn();
-  llvm::Constant *getUnwindResumeOrRethrowFn();
   void EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock = false);
   void ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock = false);
 
   void EmitCXXTryStmt(const CXXTryStmt &S);
   void EmitSEHTryStmt(const SEHTryStmt &S);
-  void EmitCXXForRangeStmt(const CXXForRangeStmt &S);
+  void EmitSEHLeaveStmt(const SEHLeaveStmt &S);
+  void EmitCXXForRangeStmt(const CXXForRangeStmt &S,
+                           const ArrayRef<const Attr *> &Attrs = None);
 
   llvm::Function *EmitCapturedStmt(const CapturedStmt &S, CapturedRegionKind K);
-  llvm::Function *GenerateCapturedStmtFunction(const CapturedDecl *CD,
-                                               const RecordDecl *RD,
-                                               SourceLocation Loc);
+  llvm::Function *GenerateCapturedStmtFunction(const CapturedStmt &S);
+  llvm::Value *GenerateCapturedStmtArgument(const CapturedStmt &S);
+
+  void EmitOMPParallelDirective(const OMPParallelDirective &S);
+  void EmitOMPSimdDirective(const OMPSimdDirective &S);
+  void EmitOMPForDirective(const OMPForDirective &S);
+  void EmitOMPSectionsDirective(const OMPSectionsDirective &S);
+  void EmitOMPSectionDirective(const OMPSectionDirective &S);
+  void EmitOMPSingleDirective(const OMPSingleDirective &S);
+  void EmitOMPMasterDirective(const OMPMasterDirective &S);
+  void EmitOMPCriticalDirective(const OMPCriticalDirective &S);
+  void EmitOMPParallelForDirective(const OMPParallelForDirective &S);
+  void EmitOMPParallelSectionsDirective(const OMPParallelSectionsDirective &S);
+  void EmitOMPTaskDirective(const OMPTaskDirective &S);
+  void EmitOMPTaskyieldDirective(const OMPTaskyieldDirective &S);
+  void EmitOMPBarrierDirective(const OMPBarrierDirective &S);
+  void EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S);
+  void EmitOMPFlushDirective(const OMPFlushDirective &S);
 
   //===--------------------------------------------------------------------===//
   //                         LValue Expression Emission
@@ -1918,7 +2002,7 @@
   llvm::Value *EmitLoadOfScalar(llvm::Value *Addr, bool Volatile,
                                 unsigned Alignment, QualType Ty,
                                 SourceLocation Loc,
-                                llvm::MDNode *TBAAInfo = 0,
+                                llvm::MDNode *TBAAInfo = nullptr,
                                 QualType TBAABaseTy = QualType(),
                                 uint64_t TBAAOffset = 0);
 
@@ -1933,7 +2017,7 @@
   /// the LLVM value representation.
   void EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr,
                          bool Volatile, unsigned Alignment, QualType Ty,
-                         llvm::MDNode *TBAAInfo = 0, bool isInit = false,
+                         llvm::MDNode *TBAAInfo = nullptr, bool isInit = false,
                          QualType TBAABaseTy = QualType(),
                          uint64_t TBAAOffset = 0);
 
@@ -1950,12 +2034,14 @@
   RValue EmitLoadOfLValue(LValue V, SourceLocation Loc);
   RValue EmitLoadOfExtVectorElementLValue(LValue V);
   RValue EmitLoadOfBitfieldLValue(LValue LV);
+  RValue EmitLoadOfGlobalRegLValue(LValue LV);
 
   /// EmitStoreThroughLValue - Store the specified rvalue into the specified
   /// lvalue, where both are guaranteed to the have the same type, and that type
   /// is 'Ty'.
   void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false);
   void EmitStoreThroughExtVectorComponentLValue(RValue Src, LValue Dst);
+  void EmitStoreThroughGlobalRegLValue(RValue Src, LValue Dst);
 
   /// EmitStoreThroughBitfieldLValue - Store Src into Dst with same constraints
   /// as EmitStoreThroughLValue.
@@ -1964,7 +2050,7 @@
   /// bit-field contents after the store, appropriate for use as the result of
   /// an assignment to the bit-field.
   void EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,
-                                      llvm::Value **Result=0);
+                                      llvm::Value **Result=nullptr);
 
   /// Emit an l-value for an assignment (simple or compound) of complex type.
   LValue EmitComplexAssignmentLValue(const BinaryOperator *E);
@@ -1980,6 +2066,7 @@
   // Note: only available for agg return types
   LValue EmitVAArgExprLValue(const VAArgExpr *E);
   LValue EmitDeclRefLValue(const DeclRefExpr *E);
+  LValue EmitReadRegister(const VarDecl *VD);
   LValue EmitStringLiteralLValue(const StringLiteral *E);
   LValue EmitObjCEncodeExprLValue(const ObjCEncodeExpr *E);
   LValue EmitPredefinedLValue(const PredefinedExpr *E);
@@ -2011,7 +2098,9 @@
       return ConstantEmission(C, false);
     }
 
-    LLVM_EXPLICIT operator bool() const { return ValueAndIsReference.getOpaqueValue() != 0; }
+    LLVM_EXPLICIT operator bool() const {
+      return ValueAndIsReference.getOpaqueValue() != nullptr;
+    }
 
     bool isReference() const { return ValueAndIsReference.getInt(); }
     LValue getReferenceLValue(CodeGenFunction &CGF, Expr *refExpr) const {
@@ -2074,15 +2163,15 @@
                   llvm::Value *Callee,
                   ReturnValueSlot ReturnValue,
                   const CallArgList &Args,
-                  const Decl *TargetDecl = 0,
-                  llvm::Instruction **callOrInvoke = 0);
+                  const Decl *TargetDecl = nullptr,
+                  llvm::Instruction **callOrInvoke = nullptr);
 
   RValue EmitCall(QualType FnType, llvm::Value *Callee,
                   SourceLocation CallLoc,
                   ReturnValueSlot ReturnValue,
                   CallExpr::const_arg_iterator ArgBeg,
                   CallExpr::const_arg_iterator ArgEnd,
-                  const Decl *TargetDecl = 0);
+                  const Decl *TargetDecl = nullptr);
   RValue EmitCallExpr(const CallExpr *E,
                       ReturnValueSlot ReturnValue = ReturnValueSlot());
 
@@ -2156,9 +2245,19 @@
                                              const llvm::CmpInst::Predicate Fp,
                                              const llvm::CmpInst::Predicate Ip,
                                              const llvm::Twine &Name = "");
-  llvm::Value *EmitAArch64CompareBuiltinExpr(llvm::Value *Op, llvm::Type *Ty);
-  llvm::Value *EmitAArch64BuiltinExpr(unsigned BuiltinID, const CallExpr *E);
   llvm::Value *EmitARMBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
+
+  llvm::Value *EmitCommonNeonBuiltinExpr(unsigned BuiltinID,
+                                         unsigned LLVMIntrinsic,
+                                         unsigned AltLLVMIntrinsic,
+                                         const char *NameHint,
+                                         unsigned Modifier,
+                                         const CallExpr *E,
+                                         SmallVectorImpl<llvm::Value *> &Ops,
+                                         llvm::Value *Align = nullptr);
+  llvm::Function *LookupNeonLLVMIntrinsic(unsigned IntrinsicID,
+                                          unsigned Modifier, llvm::Type *ArgTy,
+                                          const CallExpr *E);
   llvm::Value *EmitNeonCall(llvm::Function *F,
                             SmallVectorImpl<llvm::Value*> &O,
                             const char *name,
@@ -2168,10 +2267,22 @@
                                    bool negateForRightShift);
   llvm::Value *EmitNeonRShiftImm(llvm::Value *Vec, llvm::Value *Amt,
                                  llvm::Type *Ty, bool usgn, const char *name);
+  // Helper functions for EmitAArch64BuiltinExpr.
+  llvm::Value *vectorWrapScalar8(llvm::Value *Op);
+  llvm::Value *vectorWrapScalar16(llvm::Value *Op);
+  llvm::Value *emitVectorWrappedScalar8Intrinsic(
+      unsigned Int, SmallVectorImpl<llvm::Value *> &Ops, const char *Name);
+  llvm::Value *emitVectorWrappedScalar16Intrinsic(
+      unsigned Int, SmallVectorImpl<llvm::Value *> &Ops, const char *Name);
+  llvm::Value *EmitAArch64BuiltinExpr(unsigned BuiltinID, const CallExpr *E);
+  llvm::Value *EmitNeon64Call(llvm::Function *F,
+                              llvm::SmallVectorImpl<llvm::Value *> &O,
+                              const char *name);
 
   llvm::Value *BuildVector(ArrayRef<llvm::Value*> Ops);
   llvm::Value *EmitX86BuiltinExpr(unsigned BuiltinID, const CallExpr *E);
   llvm::Value *EmitPPCBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
+  llvm::Value *EmitR600BuiltinExpr(unsigned BuiltinID, const CallExpr *E);
 
   llvm::Value *EmitObjCProtocolExpr(const ObjCProtocolExpr *E);
   llvm::Value *EmitObjCStringLiteral(const ObjCStringLiteral *E);
@@ -2231,7 +2342,7 @@
   llvm::Value *EmitARCRetainScalarExpr(const Expr *expr);
   llvm::Value *EmitARCRetainAutoreleaseScalarExpr(const Expr *expr);
 
-  void EmitARCIntrinsicUse(llvm::ArrayRef<llvm::Value*> values);
+  void EmitARCIntrinsicUse(ArrayRef<llvm::Value*> values);
 
   static Destroyer destroyARCStrongImprecise;
   static Destroyer destroyARCStrongPrecise;
@@ -2304,9 +2415,9 @@
 
   /// CreateStaticVarDecl - Create a zero-initialized LLVM global for
   /// a static local variable.
-  llvm::GlobalVariable *CreateStaticVarDecl(const VarDecl &D,
-                                            const char *Separator,
-                                       llvm::GlobalValue::LinkageTypes Linkage);
+  llvm::Constant *CreateStaticVarDecl(const VarDecl &D,
+                                      const char *Separator,
+                                      llvm::GlobalValue::LinkageTypes Linkage);
 
   /// AddInitializerToStaticVarDecl - Add the initializer for 'D' to the
   /// global variable that has already been created for it.  If the initializer
@@ -2339,7 +2450,7 @@
   /// variables.
   void GenerateCXXGlobalInitFunc(llvm::Function *Fn,
                                  ArrayRef<llvm::Constant *> Decls,
-                                 llvm::GlobalVariable *Guard = 0);
+                                 llvm::GlobalVariable *Guard = nullptr);
 
   /// GenerateCXXGlobalDtorsFunc - Generates code for destroying global
   /// variables.
@@ -2367,7 +2478,7 @@
 
   void EmitLambdaExpr(const LambdaExpr *E, AggValueSlot Dest);
 
-  RValue EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest = 0);
+  RValue EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest = nullptr);
 
   //===--------------------------------------------------------------------===//
   //                         Annotations Emission
@@ -2413,8 +2524,10 @@
   /// EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g. for an
   /// if statement) to the specified blocks.  Based on the condition, this might
   /// try to simplify the codegen of the conditional based on the branch.
+  /// TrueCount should be the number of times we expect the condition to
+  /// evaluate to true based on PGO data.
   void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock,
-                            llvm::BasicBlock *FalseBlock);
+                            llvm::BasicBlock *FalseBlock, uint64_t TrueCount);
 
   /// \brief Emit a description of a type in a format suitable for passing to
   /// a runtime sanitizer handler.
@@ -2467,6 +2580,11 @@
   llvm::MDNode *getRangeForLoadFromType(QualType Ty);
   void EmitReturnOfRValue(RValue RV, QualType Ty);
 
+  void deferPlaceholderReplacement(llvm::Instruction *Old, llvm::Value *New);
+
+  llvm::SmallVector<std::pair<llvm::Instruction *, llvm::Value *>, 4>
+  DeferredReplacements;
+
   /// ExpandTypeFromArgs - Reconstruct a structure of type \arg Ty
   /// from function arguments into \arg Dst. See ABIArgInfo::Expand.
   ///
@@ -2492,69 +2610,82 @@
                                   std::string &ConstraintStr,
                                   SourceLocation Loc);
 
+public:
   /// EmitCallArgs - Emit call arguments for a function.
-  /// The CallArgTypeInfo parameter is used for iterating over the known
-  /// argument types of the function being called.
-  template<typename T>
-  void EmitCallArgs(CallArgList& Args, const T* CallArgTypeInfo,
+  template <typename T>
+  void EmitCallArgs(CallArgList &Args, const T *CallArgTypeInfo,
                     CallExpr::const_arg_iterator ArgBeg,
                     CallExpr::const_arg_iterator ArgEnd,
                     bool ForceColumnInfo = false) {
-    CGDebugInfo *DI = getDebugInfo();
-    SourceLocation CallLoc;
-    if (DI) CallLoc = DI->getLocation();
-
-    CallExpr::const_arg_iterator Arg = ArgBeg;
-
-    // First, use the argument types that the type info knows about
     if (CallArgTypeInfo) {
-      for (typename T::arg_type_iterator I = CallArgTypeInfo->arg_type_begin(),
-           E = CallArgTypeInfo->arg_type_end(); I != E; ++I, ++Arg) {
-        assert(Arg != ArgEnd && "Running over edge of argument list!");
-        QualType ArgType = *I;
-#ifndef NDEBUG
-        QualType ActualArgType = Arg->getType();
-        if (ArgType->isPointerType() && ActualArgType->isPointerType()) {
-          QualType ActualBaseType =
-            ActualArgType->getAs<PointerType>()->getPointeeType();
-          QualType ArgBaseType =
-            ArgType->getAs<PointerType>()->getPointeeType();
-          if (ArgBaseType->isVariableArrayType()) {
-            if (const VariableArrayType *VAT =
-                getContext().getAsVariableArrayType(ActualBaseType)) {
-              if (!VAT->getSizeExpr())
-                ActualArgType = ArgType;
-            }
-          }
-        }
-        assert(getContext().getCanonicalType(ArgType.getNonReferenceType()).
-               getTypePtr() ==
-               getContext().getCanonicalType(ActualArgType).getTypePtr() &&
-               "type mismatch in call argument!");
-#endif
-        EmitCallArg(Args, *Arg, ArgType);
-
-        // Each argument expression could modify the debug
-        // location. Restore it.
-        if (DI) DI->EmitLocation(Builder, CallLoc, ForceColumnInfo);
-      }
-
-      // Either we've emitted all the call args, or we have a call to a
-      // variadic function.
-      assert((Arg == ArgEnd || CallArgTypeInfo->isVariadic()) &&
-             "Extra arguments in non-variadic function!");
-
-    }
-
-    // If we still have any arguments, emit them using the type of the argument.
-    for (; Arg != ArgEnd; ++Arg) {
-      EmitCallArg(Args, *Arg, Arg->getType());
-
-      // Restore the debug location.
-      if (DI) DI->EmitLocation(Builder, CallLoc, ForceColumnInfo);
+      EmitCallArgs(Args, CallArgTypeInfo->isVariadic(),
+                   CallArgTypeInfo->param_type_begin(),
+                   CallArgTypeInfo->param_type_end(), ArgBeg, ArgEnd,
+                   ForceColumnInfo);
+    } else {
+      // T::param_type_iterator might not have a default ctor.
+      const QualType *NoIter = nullptr;
+      EmitCallArgs(Args, /*AllowExtraArguments=*/true, NoIter, NoIter, ArgBeg,
+                   ArgEnd, ForceColumnInfo);
     }
   }
 
+  template<typename ArgTypeIterator>
+  void EmitCallArgs(CallArgList& Args,
+                    bool AllowExtraArguments,
+                    ArgTypeIterator ArgTypeBeg,
+                    ArgTypeIterator ArgTypeEnd,
+                    CallExpr::const_arg_iterator ArgBeg,
+                    CallExpr::const_arg_iterator ArgEnd,
+                    bool ForceColumnInfo = false) {
+    SmallVector<QualType, 16> ArgTypes;
+    CallExpr::const_arg_iterator Arg = ArgBeg;
+
+    // First, use the argument types that the type info knows about
+    for (ArgTypeIterator I = ArgTypeBeg, E = ArgTypeEnd; I != E; ++I, ++Arg) {
+      assert(Arg != ArgEnd && "Running over edge of argument list!");
+#ifndef NDEBUG
+      QualType ArgType = *I;
+      QualType ActualArgType = Arg->getType();
+      if (ArgType->isPointerType() && ActualArgType->isPointerType()) {
+        QualType ActualBaseType =
+            ActualArgType->getAs<PointerType>()->getPointeeType();
+        QualType ArgBaseType =
+            ArgType->getAs<PointerType>()->getPointeeType();
+        if (ArgBaseType->isVariableArrayType()) {
+          if (const VariableArrayType *VAT =
+              getContext().getAsVariableArrayType(ActualBaseType)) {
+            if (!VAT->getSizeExpr())
+              ActualArgType = ArgType;
+          }
+        }
+      }
+      assert(getContext().getCanonicalType(ArgType.getNonReferenceType()).
+             getTypePtr() ==
+             getContext().getCanonicalType(ActualArgType).getTypePtr() &&
+             "type mismatch in call argument!");
+#endif
+      ArgTypes.push_back(*I);
+    }
+
+    // Either we've emitted all the call args, or we have a call to variadic
+    // function or some other call that allows extra arguments.
+    assert((Arg == ArgEnd || AllowExtraArguments) &&
+           "Extra arguments in non-variadic function!");
+
+    // If we still have any arguments, emit them using the type of the argument.
+    for (; Arg != ArgEnd; ++Arg)
+      ArgTypes.push_back(Arg->getType());
+
+    EmitCallArgs(Args, ArgTypes, ArgBeg, ArgEnd, ForceColumnInfo);
+  }
+
+  void EmitCallArgs(CallArgList &Args, ArrayRef<QualType> ArgTypes,
+                    CallExpr::const_arg_iterator ArgBeg,
+                    CallExpr::const_arg_iterator ArgEnd,
+                    bool ForceColumnInfo = false);
+
+private:
   const TargetCodeGenInfo &getTargetHooks() const {
     return CGM.getTargetCodeGenInfo();
   }
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 1d0f3d2..1615d77 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -18,7 +18,9 @@
 #include "CGDebugInfo.h"
 #include "CGObjCRuntime.h"
 #include "CGOpenCLRuntime.h"
+#include "CGOpenMPRuntime.h"
 #include "CodeGenFunction.h"
+#include "CodeGenPGO.h"
 #include "CodeGenTBAA.h"
 #include "TargetInfo.h"
 #include "clang/AST/ASTContext.h"
@@ -40,31 +42,32 @@
 #include "clang/Sema/SemaDiagnostic.h"
 #include "llvm/ADT/APSInt.h"
 #include "llvm/ADT/Triple.h"
+#include "llvm/IR/CallSite.h"
 #include "llvm/IR/CallingConv.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/Intrinsics.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
-#include "llvm/Support/CallSite.h"
+#include "llvm/ProfileData/InstrProfReader.h"
 #include "llvm/Support/ConvertUTF.h"
 #include "llvm/Support/ErrorHandling.h"
-#include "llvm/Target/Mangler.h"
 
 using namespace clang;
 using namespace CodeGen;
 
 static const char AnnotationSection[] = "llvm.metadata";
 
-static CGCXXABI &createCXXABI(CodeGenModule &CGM) {
+static CGCXXABI *createCXXABI(CodeGenModule &CGM) {
   switch (CGM.getTarget().getCXXABI().getKind()) {
   case TargetCXXABI::GenericAArch64:
   case TargetCXXABI::GenericARM:
   case TargetCXXABI::Emscripten:
   case TargetCXXABI::iOS:
+  case TargetCXXABI::iOS64:
   case TargetCXXABI::GenericItanium:
-    return *CreateItaniumCXXABI(CGM);
+    return CreateItaniumCXXABI(CGM);
   case TargetCXXABI::Microsoft:
-    return *CreateMicrosoftCXXABI(CGM);
+    return CreateMicrosoftCXXABI(CGM);
   }
 
   llvm_unreachable("invalid C++ ABI kind");
@@ -75,18 +78,18 @@
                              DiagnosticsEngine &diags)
     : Context(C), LangOpts(C.getLangOpts()), CodeGenOpts(CGO), TheModule(M),
       Diags(diags), TheDataLayout(TD), Target(C.getTargetInfo()),
-      ABI(createCXXABI(*this)), VMContext(M.getContext()), TBAA(0),
-      TheTargetCodeGenInfo(0), Types(*this), VTables(*this), ObjCRuntime(0),
-      OpenCLRuntime(0), CUDARuntime(0), DebugInfo(0), ARCData(0),
-      NoObjCARCExceptionsMetadata(0), RRData(0), CFConstantStringClassRef(0),
-      ConstantStringClassRef(0), NSConstantStringType(0),
-      NSConcreteGlobalBlock(0), NSConcreteStackBlock(0), BlockObjectAssign(0),
-      BlockObjectDispose(0), BlockDescriptorType(0), GenericBlockLiteralType(0),
-      LifetimeStartFn(0), LifetimeEndFn(0),
-      SanitizerBlacklist(
-          llvm::SpecialCaseList::createOrDie(CGO.SanitizerBlacklistFile)),
-      SanOpts(SanitizerBlacklist->isIn(M) ? SanitizerOptions::Disabled
-                                          : LangOpts.Sanitize) {
+      ABI(createCXXABI(*this)), VMContext(M.getContext()), TBAA(nullptr),
+      TheTargetCodeGenInfo(nullptr), Types(*this), VTables(*this),
+      ObjCRuntime(nullptr), OpenCLRuntime(nullptr), OpenMPRuntime(nullptr),
+      CUDARuntime(nullptr), DebugInfo(nullptr), ARCData(nullptr),
+      NoObjCARCExceptionsMetadata(nullptr), RRData(nullptr), PGOReader(nullptr),
+      CFConstantStringClassRef(nullptr), ConstantStringClassRef(nullptr),
+      NSConstantStringType(nullptr), NSConcreteGlobalBlock(nullptr),
+      NSConcreteStackBlock(nullptr), BlockObjectAssign(nullptr),
+      BlockObjectDispose(nullptr), BlockDescriptorType(nullptr),
+      GenericBlockLiteralType(nullptr), LifetimeStartFn(nullptr),
+      LifetimeEndFn(nullptr), SanitizerBL(llvm::SpecialCaseList::createOrDie(
+                                  CGO.SanitizerBlacklistFile)) {
 
   // Initialize the type cache.
   llvm::LLVMContext &LLVMContext = M.getContext();
@@ -111,14 +114,16 @@
     createObjCRuntime();
   if (LangOpts.OpenCL)
     createOpenCLRuntime();
+  if (LangOpts.OpenMP)
+    createOpenMPRuntime();
   if (LangOpts.CUDA)
     createCUDARuntime();
 
   // Enable TBAA unless it's suppressed. ThreadSanitizer needs TBAA even at O0.
-  if (SanOpts.Thread ||
+  if (LangOpts.Sanitize.Thread ||
       (!CodeGenOpts.RelaxedAliasing && CodeGenOpts.OptimizationLevel > 0))
     TBAA = new CodeGenTBAA(Context, VMContext, CodeGenOpts, getLangOpts(),
-                           ABI.getMangleContext());
+                           getCXXABI().getMangleContext());
 
   // If debug info or coverage generation is enabled, create the CGDebugInfo
   // object.
@@ -132,14 +137,23 @@
   if (C.getLangOpts().ObjCAutoRefCount)
     ARCData = new ARCEntrypoints();
   RRData = new RREntrypoints();
+
+  if (!CodeGenOpts.InstrProfileInput.empty()) {
+    if (std::error_code EC = llvm::IndexedInstrProfReader::create(
+            CodeGenOpts.InstrProfileInput, PGOReader)) {
+      unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
+                                              "Could not read profile: %0");
+      getDiags().Report(DiagID) << EC.message();
+    }
+  }
 }
 
 CodeGenModule::~CodeGenModule() {
   delete ObjCRuntime;
   delete OpenCLRuntime;
+  delete OpenMPRuntime;
   delete CUDARuntime;
   delete TheTargetCodeGenInfo;
-  delete &ABI;
   delete TBAA;
   delete DebugInfo;
   delete ARCData;
@@ -169,6 +183,10 @@
   OpenCLRuntime = new CGOpenCLRuntime(*this);
 }
 
+void CodeGenModule::createOpenMPRuntime() {
+  OpenMPRuntime = new CGOpenMPRuntime(*this);
+}
+
 void CodeGenModule::createCUDARuntime() {
   CUDARuntime = CreateNVCUDARuntime(*this);
 }
@@ -182,13 +200,17 @@
     llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
     if (!Entry)
       continue;
-    llvm::Function *OldF = cast<llvm::Function>(Entry);
-    llvm::Function *NewF = dyn_cast<llvm::Function>(Replacement);
+    auto *OldF = cast<llvm::Function>(Entry);
+    auto *NewF = dyn_cast<llvm::Function>(Replacement);
     if (!NewF) {
-      llvm::ConstantExpr *CE = cast<llvm::ConstantExpr>(Replacement);
-      assert(CE->getOpcode() == llvm::Instruction::BitCast ||
-             CE->getOpcode() == llvm::Instruction::GetElementPtr);
-      NewF = dyn_cast<llvm::Function>(CE->getOperand(0));
+      if (auto *Alias = dyn_cast<llvm::GlobalAlias>(Replacement)) {
+        NewF = dyn_cast<llvm::Function>(Alias->getAliasee());
+      } else {
+        auto *CE = cast<llvm::ConstantExpr>(Replacement);
+        assert(CE->getOpcode() == llvm::Instruction::BitCast ||
+               CE->getOpcode() == llvm::Instruction::GetElementPtr);
+        NewF = dyn_cast<llvm::Function>(CE->getOperand(0));
+      }
     }
 
     // Replace old with new, but keep the old order.
@@ -201,23 +223,75 @@
   }
 }
 
+// This is only used in aliases that we created and we know they have a
+// linear structure.
+static const llvm::GlobalObject *getAliasedGlobal(const llvm::GlobalAlias &GA) {
+  llvm::SmallPtrSet<const llvm::GlobalAlias*, 4> Visited;
+  const llvm::Constant *C = &GA;
+  for (;;) {
+    C = C->stripPointerCasts();
+    if (auto *GO = dyn_cast<llvm::GlobalObject>(C))
+      return GO;
+    // stripPointerCasts will not walk over weak aliases.
+    auto *GA2 = dyn_cast<llvm::GlobalAlias>(C);
+    if (!GA2)
+      return nullptr;
+    if (!Visited.insert(GA2))
+      return nullptr;
+    C = GA2->getAliasee();
+  }
+}
+
 void CodeGenModule::checkAliases() {
+  // Check if the constructed aliases are well formed. It is really unfortunate
+  // that we have to do this in CodeGen, but we only construct mangled names
+  // and aliases during codegen.
   bool Error = false;
+  DiagnosticsEngine &Diags = getDiags();
   for (std::vector<GlobalDecl>::iterator I = Aliases.begin(),
          E = Aliases.end(); I != E; ++I) {
     const GlobalDecl &GD = *I;
-    const ValueDecl *D = cast<ValueDecl>(GD.getDecl());
+    const auto *D = cast<ValueDecl>(GD.getDecl());
     const AliasAttr *AA = D->getAttr<AliasAttr>();
     StringRef MangledName = getMangledName(GD);
     llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
-    llvm::GlobalAlias *Alias = cast<llvm::GlobalAlias>(Entry);
-    llvm::GlobalValue *GV = Alias->getAliasedGlobal();
-    if (GV->isDeclaration()) {
+    auto *Alias = cast<llvm::GlobalAlias>(Entry);
+    const llvm::GlobalValue *GV = getAliasedGlobal(*Alias);
+    if (!GV) {
       Error = true;
-      getDiags().Report(AA->getLocation(), diag::err_alias_to_undefined);
-    } else if (!Alias->resolveAliasedGlobal(/*stopOnWeak*/ false)) {
+      Diags.Report(AA->getLocation(), diag::err_cyclic_alias);
+    } else if (GV->isDeclaration()) {
       Error = true;
-      getDiags().Report(AA->getLocation(), diag::err_cyclic_alias);
+      Diags.Report(AA->getLocation(), diag::err_alias_to_undefined);
+    }
+
+    llvm::Constant *Aliasee = Alias->getAliasee();
+    llvm::GlobalValue *AliaseeGV;
+    if (auto CE = dyn_cast<llvm::ConstantExpr>(Aliasee))
+      AliaseeGV = cast<llvm::GlobalValue>(CE->getOperand(0));
+    else
+      AliaseeGV = cast<llvm::GlobalValue>(Aliasee);
+
+    if (const SectionAttr *SA = D->getAttr<SectionAttr>()) {
+      StringRef AliasSection = SA->getName();
+      if (AliasSection != AliaseeGV->getSection())
+        Diags.Report(SA->getLocation(), diag::warn_alias_with_section)
+            << AliasSection;
+    }
+
+    // We have to handle alias to weak aliases in here. LLVM itself disallows
+    // this since the object semantics would not match the IL one. For
+    // compatibility with gcc we implement it by just pointing the alias
+    // to its aliasee's aliasee. We also warn, since the user is probably
+    // expecting the link to be weak.
+    if (auto GA = dyn_cast<llvm::GlobalAlias>(AliaseeGV)) {
+      if (GA->mayBeOverridden()) {
+        Diags.Report(AA->getLocation(), diag::warn_alias_to_weak_alias)
+            << GV->getName() << GA->getName();
+        Aliasee = llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(
+            GA->getAliasee(), Alias->getType());
+        Alias->setAliasee(Aliasee);
+      }
     }
   }
   if (!Error)
@@ -228,12 +302,29 @@
     const GlobalDecl &GD = *I;
     StringRef MangledName = getMangledName(GD);
     llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
-    llvm::GlobalAlias *Alias = cast<llvm::GlobalAlias>(Entry);
+    auto *Alias = cast<llvm::GlobalAlias>(Entry);
     Alias->replaceAllUsesWith(llvm::UndefValue::get(Alias->getType()));
     Alias->eraseFromParent();
   }
 }
 
+void CodeGenModule::clear() {
+  DeferredDeclsToEmit.clear();
+}
+
+void InstrProfStats::reportDiagnostics(DiagnosticsEngine &Diags,
+                                       StringRef MainFile) {
+  if (!hasDiagnostics())
+    return;
+  if (VisitedInMainFile > 0 && VisitedInMainFile == MissingInMainFile) {
+    if (MainFile.empty())
+      MainFile = "<stdin>";
+    Diags.Report(diag::warn_profile_data_unprofiled) << MainFile;
+  } else
+    Diags.Report(diag::warn_profile_data_out_of_date) << Visited << Missing
+                                                      << Mismatched;
+}
+
 void CodeGenModule::Release() {
   EmitDeferred();
   applyReplacements();
@@ -244,11 +335,16 @@
   if (ObjCRuntime)
     if (llvm::Function *ObjCInitFunction = ObjCRuntime->ModuleInitFunction())
       AddGlobalCtor(ObjCInitFunction);
+  if (getCodeGenOpts().ProfileInstrGenerate)
+    if (llvm::Function *PGOInit = CodeGenPGO::emitInitialization(*this))
+      AddGlobalCtor(PGOInit, 0);
+  if (PGOReader && PGOStats.hasDiagnostics())
+    PGOStats.reportDiagnostics(getDiags(), getCodeGenOpts().MainFileName);
   EmitCtorList(GlobalCtors, "llvm.global_ctors");
   EmitCtorList(GlobalDtors, "llvm.global_dtors");
   EmitGlobalAnnotations();
   EmitStaticExternCAliases();
-  EmitLLVMUsed();
+  emitLLVMUsed();
 
   if (CodeGenOpts.Autolink &&
       (Context.getLangOpts().Modules || !LinkerOptionsMetadata.empty())) {
@@ -259,6 +355,29 @@
     // We can change from Warning to Latest if such mode is supported.
     getModule().addModuleFlag(llvm::Module::Warning, "Dwarf Version",
                               CodeGenOpts.DwarfVersion);
+  if (DebugInfo)
+    // We support a single version in the linked module. The LLVM
+    // parser will drop debug info with a different version number
+    // (and warn about it, too).
+    getModule().addModuleFlag(llvm::Module::Warning, "Debug Info Version",
+                              llvm::DEBUG_METADATA_VERSION);
+
+  // We need to record the widths of enums and wchar_t, so that we can generate
+  // the correct build attributes in the ARM backend.
+  llvm::Triple::ArchType Arch = Context.getTargetInfo().getTriple().getArch();
+  if (   Arch == llvm::Triple::arm
+      || Arch == llvm::Triple::armeb
+      || Arch == llvm::Triple::thumb
+      || Arch == llvm::Triple::thumbeb) {
+    // Width of wchar_t in bytes
+    uint64_t WCharWidth =
+        Context.getTypeSizeInChars(Context.getWideCharType()).getQuantity();
+    getModule().addModuleFlag(llvm::Module::Error, "wchar_size", WCharWidth);
+
+    // The minimum width of an enum in bytes
+    uint64_t EnumWidth = Context.getLangOpts().ShortEnums ? 1 : 4;
+    getModule().addModuleFlag(llvm::Module::Error, "min_enum_size", EnumWidth);
+  }
 
   SimplifyPersonality();
 
@@ -272,6 +391,8 @@
     DebugInfo->finalize();
 
   EmitVersionIdentMetadata();
+
+  EmitTargetMetadata();
 }
 
 void CodeGenModule::UpdateCompletedType(const TagDecl *TD) {
@@ -281,25 +402,25 @@
 
 llvm::MDNode *CodeGenModule::getTBAAInfo(QualType QTy) {
   if (!TBAA)
-    return 0;
+    return nullptr;
   return TBAA->getTBAAInfo(QTy);
 }
 
 llvm::MDNode *CodeGenModule::getTBAAInfoForVTablePtr() {
   if (!TBAA)
-    return 0;
+    return nullptr;
   return TBAA->getTBAAInfoForVTablePtr();
 }
 
 llvm::MDNode *CodeGenModule::getTBAAStructInfo(QualType QTy) {
   if (!TBAA)
-    return 0;
+    return nullptr;
   return TBAA->getTBAAStructInfo(QTy);
 }
 
 llvm::MDNode *CodeGenModule::getTBAAStructTypeInfo(QualType QTy) {
   if (!TBAA)
-    return 0;
+    return nullptr;
   return TBAA->getTBAAStructTypeInfo(QTy);
 }
 
@@ -307,7 +428,7 @@
                                                   llvm::MDNode *AccessN,
                                                   uint64_t O) {
   if (!TBAA)
-    return 0;
+    return nullptr;
   return TBAA->getTBAAStructTagInfo(BaseTy, AccessN, O);
 }
 
@@ -325,9 +446,9 @@
     Inst->setMetadata(llvm::LLVMContext::MD_tbaa, TBAAInfo);
 }
 
-void CodeGenModule::Error(SourceLocation loc, StringRef error) {
-  unsigned diagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error, error);
-  getDiags().Report(Context.getFullLoc(loc), diagID);
+void CodeGenModule::Error(SourceLocation loc, StringRef message) {
+  unsigned diagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error, "%0");
+  getDiags().Report(Context.getFullLoc(loc), diagID) << message;
 }
 
 /// ErrorUnsupported - Print out an error that codegen doesn't support the
@@ -398,130 +519,61 @@
   TLM = GetLLVMTLSModel(CodeGenOpts.getDefaultTLSModel());
 
   // Override the TLS model if it is explicitly specified.
-  if (D.hasAttr<TLSModelAttr>()) {
-    const TLSModelAttr *Attr = D.getAttr<TLSModelAttr>();
+  if (const TLSModelAttr *Attr = D.getAttr<TLSModelAttr>()) {
     TLM = GetLLVMTLSModel(Attr->getModel());
   }
 
   GV->setThreadLocalMode(TLM);
 }
 
-/// Set the symbol visibility of type information (vtable and RTTI)
-/// associated with the given type.
-void CodeGenModule::setTypeVisibility(llvm::GlobalValue *GV,
-                                      const CXXRecordDecl *RD,
-                                      TypeVisibilityKind TVK) const {
-  setGlobalVisibility(GV, RD);
-
-  if (!CodeGenOpts.HiddenWeakVTables)
-    return;
-
-  // We never want to drop the visibility for RTTI names.
-  if (TVK == TVK_ForRTTIName)
-    return;
-
-  // We want to drop the visibility to hidden for weak type symbols.
-  // This isn't possible if there might be unresolved references
-  // elsewhere that rely on this symbol being visible.
-
-  // This should be kept roughly in sync with setThunkVisibility
-  // in CGVTables.cpp.
-
-  // Preconditions.
-  if (GV->getLinkage() != llvm::GlobalVariable::LinkOnceODRLinkage ||
-      GV->getVisibility() != llvm::GlobalVariable::DefaultVisibility)
-    return;
-
-  // Don't override an explicit visibility attribute.
-  if (RD->getExplicitVisibility(NamedDecl::VisibilityForType))
-    return;
-
-  switch (RD->getTemplateSpecializationKind()) {
-  // We have to disable the optimization if this is an EI definition
-  // because there might be EI declarations in other shared objects.
-  case TSK_ExplicitInstantiationDefinition:
-  case TSK_ExplicitInstantiationDeclaration:
-    return;
-
-  // Every use of a non-template class's type information has to emit it.
-  case TSK_Undeclared:
-    break;
-
-  // In theory, implicit instantiations can ignore the possibility of
-  // an explicit instantiation declaration because there necessarily
-  // must be an EI definition somewhere with default visibility.  In
-  // practice, it's possible to have an explicit instantiation for
-  // an arbitrary template class, and linkers aren't necessarily able
-  // to deal with mixed-visibility symbols.
-  case TSK_ExplicitSpecialization:
-  case TSK_ImplicitInstantiation:
-    return;
-  }
-
-  // If there's a key function, there may be translation units
-  // that don't have the key function's definition.  But ignore
-  // this if we're emitting RTTI under -fno-rtti.
-  if (!(TVK != TVK_ForRTTI) || LangOpts.RTTI) {
-    // FIXME: what should we do if we "lose" the key function during
-    // the emission of the file?
-    if (Context.getCurrentKeyFunction(RD))
-      return;
-  }
-
-  // Otherwise, drop the visibility to hidden.
-  GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
-  GV->setUnnamedAddr(true);
-}
-
 StringRef CodeGenModule::getMangledName(GlobalDecl GD) {
-  const NamedDecl *ND = cast<NamedDecl>(GD.getDecl());
+  StringRef &FoundStr = MangledDeclNames[GD.getCanonicalDecl()];
+  if (!FoundStr.empty())
+    return FoundStr;
 
-  StringRef &Str = MangledDeclNames[GD.getCanonicalDecl()];
-  if (!Str.empty())
-    return Str;
-
-  if (!getCXXABI().getMangleContext().shouldMangleDeclName(ND)) {
+  const auto *ND = cast<NamedDecl>(GD.getDecl());
+  SmallString<256> Buffer;
+  StringRef Str;
+  if (getCXXABI().getMangleContext().shouldMangleDeclName(ND)) {
+    llvm::raw_svector_ostream Out(Buffer);
+    if (const auto *D = dyn_cast<CXXConstructorDecl>(ND))
+      getCXXABI().getMangleContext().mangleCXXCtor(D, GD.getCtorType(), Out);
+    else if (const auto *D = dyn_cast<CXXDestructorDecl>(ND))
+      getCXXABI().getMangleContext().mangleCXXDtor(D, GD.getDtorType(), Out);
+    else
+      getCXXABI().getMangleContext().mangleName(ND, Out);
+    Str = Out.str();
+  } else {
     IdentifierInfo *II = ND->getIdentifier();
     assert(II && "Attempt to mangle unnamed decl.");
-
     Str = II->getName();
-    return Str;
   }
-  
-  SmallString<256> Buffer;
-  llvm::raw_svector_ostream Out(Buffer);
-  if (const CXXConstructorDecl *D = dyn_cast<CXXConstructorDecl>(ND))
-    getCXXABI().getMangleContext().mangleCXXCtor(D, GD.getCtorType(), Out);
-  else if (const CXXDestructorDecl *D = dyn_cast<CXXDestructorDecl>(ND))
-    getCXXABI().getMangleContext().mangleCXXDtor(D, GD.getDtorType(), Out);
-  else
-    getCXXABI().getMangleContext().mangleName(ND, Out);
 
-  // Allocate space for the mangled name.
-  Out.flush();
-  size_t Length = Buffer.size();
-  char *Name = MangledNamesAllocator.Allocate<char>(Length);
-  std::copy(Buffer.begin(), Buffer.end(), Name);
-  
-  Str = StringRef(Name, Length);
-  
-  return Str;
+  auto &Mangled = Manglings.GetOrCreateValue(Str);
+  Mangled.second = GD;
+  return FoundStr = Mangled.first();
 }
 
-void CodeGenModule::getBlockMangledName(GlobalDecl GD, MangleBuffer &Buffer,
-                                        const BlockDecl *BD) {
+StringRef CodeGenModule::getBlockMangledName(GlobalDecl GD,
+                                             const BlockDecl *BD) {
   MangleContext &MangleCtx = getCXXABI().getMangleContext();
   const Decl *D = GD.getDecl();
-  llvm::raw_svector_ostream Out(Buffer.getBuffer());
-  if (D == 0)
+
+  SmallString<256> Buffer;
+  llvm::raw_svector_ostream Out(Buffer);
+  if (!D)
     MangleCtx.mangleGlobalBlock(BD, 
       dyn_cast_or_null<VarDecl>(initializedGlobalDecl.getDecl()), Out);
-  else if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(D))
+  else if (const auto *CD = dyn_cast<CXXConstructorDecl>(D))
     MangleCtx.mangleCtorBlock(CD, GD.getCtorType(), BD, Out);
-  else if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(D))
+  else if (const auto *DD = dyn_cast<CXXDestructorDecl>(D))
     MangleCtx.mangleDtorBlock(DD, GD.getDtorType(), BD, Out);
   else
     MangleCtx.mangleBlock(cast<DeclContext>(D), BD, Out);
+
+  auto &Mangled = Manglings.GetOrCreateValue(Out.str());
+  Mangled.second = BD;
+  return Mangled.first();
 }
 
 llvm::GlobalValue *CodeGenModule::GetGlobalValue(StringRef Name) {
@@ -530,16 +582,17 @@
 
 /// AddGlobalCtor - Add a function to the list that will be called before
 /// main() runs.
-void CodeGenModule::AddGlobalCtor(llvm::Function * Ctor, int Priority) {
+void CodeGenModule::AddGlobalCtor(llvm::Function *Ctor, int Priority,
+                                  llvm::Constant *AssociatedData) {
   // FIXME: Type coercion of void()* types.
-  GlobalCtors.push_back(std::make_pair(Ctor, Priority));
+  GlobalCtors.push_back(Structor(Priority, Ctor, AssociatedData));
 }
 
 /// AddGlobalDtor - Add a function to the list that will be called
 /// when the module is unloaded.
-void CodeGenModule::AddGlobalDtor(llvm::Function * Dtor, int Priority) {
+void CodeGenModule::AddGlobalDtor(llvm::Function *Dtor, int Priority) {
   // FIXME: Type coercion of void()* types.
-  GlobalDtors.push_back(std::make_pair(Dtor, Priority));
+  GlobalDtors.push_back(Structor(Priority, Dtor, nullptr));
 }
 
 void CodeGenModule::EmitCtorList(const CtorList &Fns, const char *GlobalName) {
@@ -547,16 +600,19 @@
   llvm::FunctionType* CtorFTy = llvm::FunctionType::get(VoidTy, false);
   llvm::Type *CtorPFTy = llvm::PointerType::getUnqual(CtorFTy);
 
-  // Get the type of a ctor entry, { i32, void ()* }.
-  llvm::StructType *CtorStructTy =
-    llvm::StructType::get(Int32Ty, llvm::PointerType::getUnqual(CtorFTy), NULL);
+  // Get the type of a ctor entry, { i32, void ()*, i8* }.
+  llvm::StructType *CtorStructTy = llvm::StructType::get(
+      Int32Ty, llvm::PointerType::getUnqual(CtorFTy), VoidPtrTy, NULL);
 
   // Construct the constructor and destructor arrays.
   SmallVector<llvm::Constant*, 8> Ctors;
   for (CtorList::const_iterator I = Fns.begin(), E = Fns.end(); I != E; ++I) {
     llvm::Constant *S[] = {
-      llvm::ConstantInt::get(Int32Ty, I->second, false),
-      llvm::ConstantExpr::getBitCast(I->first, CtorPFTy)
+      llvm::ConstantInt::get(Int32Ty, I->Priority, false),
+      llvm::ConstantExpr::getBitCast(I->Initializer, CtorPFTy),
+      (I->AssociatedData
+           ? llvm::ConstantExpr::getBitCast(I->AssociatedData, VoidPtrTy)
+           : llvm::Constant::getNullValue(VoidPtrTy))
     };
     Ctors.push_back(llvm::ConstantStruct::get(CtorStructTy, S));
   }
@@ -572,67 +628,25 @@
 
 llvm::GlobalValue::LinkageTypes
 CodeGenModule::getFunctionLinkage(GlobalDecl GD) {
-  const FunctionDecl *D = cast<FunctionDecl>(GD.getDecl());
-
-  if (isa<CXXDestructorDecl>(D) &&
-      getCXXABI().useThunkForDtorVariant(cast<CXXDestructorDecl>(D),
-                                         GD.getDtorType()))
-    return llvm::Function::LinkOnceODRLinkage;
+  const auto *D = cast<FunctionDecl>(GD.getDecl());
 
   GVALinkage Linkage = getContext().GetGVALinkageForFunction(D);
 
-  if (Linkage == GVA_Internal)
-    return llvm::Function::InternalLinkage;
-  
-  if (D->hasAttr<DLLExportAttr>())
-    return llvm::Function::DLLExportLinkage;
-  
-  if (D->hasAttr<WeakAttr>())
-    return llvm::Function::WeakAnyLinkage;
-  
-  // In C99 mode, 'inline' functions are guaranteed to have a strong
-  // definition somewhere else, so we can use available_externally linkage.
-  if (Linkage == GVA_C99Inline)
-    return llvm::Function::AvailableExternallyLinkage;
+  if (isa<CXXDestructorDecl>(D) &&
+      getCXXABI().useThunkForDtorVariant(cast<CXXDestructorDecl>(D),
+                                         GD.getDtorType())) {
+    // Destructor variants in the Microsoft C++ ABI are always internal or
+    // linkonce_odr thunks emitted on an as-needed basis.
+    return Linkage == GVA_Internal ? llvm::GlobalValue::InternalLinkage
+                                   : llvm::GlobalValue::LinkOnceODRLinkage;
+  }
 
-  // Note that Apple's kernel linker doesn't support symbol
-  // coalescing, so we need to avoid linkonce and weak linkages there.
-  // Normally, this means we just map to internal, but for explicit
-  // instantiations we'll map to external.
-
-  // In C++, the compiler has to emit a definition in every translation unit
-  // that references the function.  We should use linkonce_odr because
-  // a) if all references in this translation unit are optimized away, we
-  // don't need to codegen it.  b) if the function persists, it needs to be
-  // merged with other definitions. c) C++ has the ODR, so we know the
-  // definition is dependable.
-  if (Linkage == GVA_CXXInline || Linkage == GVA_TemplateInstantiation)
-    return !Context.getLangOpts().AppleKext 
-             ? llvm::Function::LinkOnceODRLinkage 
-             : llvm::Function::InternalLinkage;
-  
-  // An explicit instantiation of a template has weak linkage, since
-  // explicit instantiations can occur in multiple translation units
-  // and must all be equivalent. However, we are not allowed to
-  // throw away these explicit instantiations.
-  if (Linkage == GVA_ExplicitTemplateInstantiation)
-    return !Context.getLangOpts().AppleKext
-             ? llvm::Function::WeakODRLinkage
-             : llvm::Function::ExternalLinkage;
-  
-  // Otherwise, we have strong external linkage.
-  assert(Linkage == GVA_StrongExternal);
-  return llvm::Function::ExternalLinkage;
+  return getLLVMLinkageForDeclarator(D, Linkage, /*isConstantVariable=*/false);
 }
 
-
-/// SetFunctionDefinitionAttributes - Set attributes for a global.
-///
-/// FIXME: This is currently only done for aliases and functions, but not for
-/// variables (these details are set in EmitGlobalVarDefinition for variables).
-void CodeGenModule::SetFunctionDefinitionAttributes(const FunctionDecl *D,
-                                                    llvm::GlobalValue *GV) {
-  SetCommonAttributes(D, GV);
+void CodeGenModule::setFunctionDefinitionAttributes(const FunctionDecl *D,
+                                                    llvm::Function *F) {
+  setNonAliasAttributes(D, F);
 }
 
 void CodeGenModule::SetLLVMFunctionAttributes(const Decl *D,
@@ -679,10 +693,15 @@
     // Naked implies noinline: we should not be inlining such functions.
     B.addAttribute(llvm::Attribute::Naked);
     B.addAttribute(llvm::Attribute::NoInline);
+  } else if (D->hasAttr<OptimizeNoneAttr>()) {
+    // OptimizeNone implies noinline; we should not be inlining such functions.
+    B.addAttribute(llvm::Attribute::OptimizeNone);
+    B.addAttribute(llvm::Attribute::NoInline);
+  } else if (D->hasAttr<NoDuplicateAttr>()) {
+    B.addAttribute(llvm::Attribute::NoDuplicate);
   } else if (D->hasAttr<NoInlineAttr>()) {
     B.addAttribute(llvm::Attribute::NoInline);
-  } else if ((D->hasAttr<AlwaysInlineAttr>() ||
-              D->hasAttr<ForceInlineAttr>()) &&
+  } else if (D->hasAttr<AlwaysInlineAttr>() &&
              !F->getAttributes().hasAttribute(llvm::AttributeSet::FunctionIndex,
                                               llvm::Attribute::NoInline)) {
     // (noinline wins over always_inline, and we can't specify both in IR)
@@ -697,23 +716,30 @@
   if (D->hasAttr<MinSizeAttr>())
     B.addAttribute(llvm::Attribute::MinSize);
 
+  if (D->hasAttr<OptimizeNoneAttr>()) {
+    // OptimizeNone wins over OptimizeForSize and MinSize.
+    B.removeAttribute(llvm::Attribute::OptimizeForSize);
+    B.removeAttribute(llvm::Attribute::MinSize);
+  }
+
   if (LangOpts.getStackProtector() == LangOptions::SSPOn)
     B.addAttribute(llvm::Attribute::StackProtect);
+  else if (LangOpts.getStackProtector() == LangOptions::SSPStrong)
+    B.addAttribute(llvm::Attribute::StackProtectStrong);
   else if (LangOpts.getStackProtector() == LangOptions::SSPReq)
     B.addAttribute(llvm::Attribute::StackProtectReq);
 
   // Add sanitizer attributes if function is not blacklisted.
-  if (!SanitizerBlacklist->isIn(*F)) {
+  if (!SanitizerBL.isIn(*F)) {
     // When AddressSanitizer is enabled, set SanitizeAddress attribute
     // unless __attribute__((no_sanitize_address)) is used.
-    if (SanOpts.Address && !D->hasAttr<NoSanitizeAddressAttr>())
+    if (LangOpts.Sanitize.Address && !D->hasAttr<NoSanitizeAddressAttr>())
       B.addAttribute(llvm::Attribute::SanitizeAddress);
     // Same for ThreadSanitizer and __attribute__((no_sanitize_thread))
-    if (SanOpts.Thread && !D->hasAttr<NoSanitizeThreadAttr>()) {
+    if (LangOpts.Sanitize.Thread && !D->hasAttr<NoSanitizeThreadAttr>())
       B.addAttribute(llvm::Attribute::SanitizeThread);
-    }
     // Same for MemorySanitizer and __attribute__((no_sanitize_memory))
-    if (SanOpts.Memory && !D->hasAttr<NoSanitizeMemoryAttr>())
+    if (LangOpts.Sanitize.Memory && !D->hasAttr<NoSanitizeMemoryAttr>())
       B.addAttribute(llvm::Attribute::SanitizeMemory);
   }
 
@@ -723,7 +749,7 @@
 
   if (isa<CXXConstructorDecl>(D) || isa<CXXDestructorDecl>(D))
     F->setUnnamedAddr(true);
-  else if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D))
+  else if (const auto *MD = dyn_cast<CXXMethodDecl>(D))
     if (MD->isVirtual())
       F->setUnnamedAddr(true);
 
@@ -740,20 +766,23 @@
 
 void CodeGenModule::SetCommonAttributes(const Decl *D,
                                         llvm::GlobalValue *GV) {
-  if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
+  if (const auto *ND = dyn_cast<NamedDecl>(D))
     setGlobalVisibility(GV, ND);
   else
     GV->setVisibility(llvm::GlobalValue::DefaultVisibility);
 
   if (D->hasAttr<UsedAttr>())
-    AddUsedGlobal(GV);
+    addUsedGlobal(GV);
+}
+
+void CodeGenModule::setNonAliasAttributes(const Decl *D,
+                                          llvm::GlobalObject *GO) {
+  SetCommonAttributes(D, GO);
 
   if (const SectionAttr *SA = D->getAttr<SectionAttr>())
-    GV->setSection(SA->getName());
+    GO->setSection(SA->getName());
 
-  // Alias cannot have attributes. Filter them here.
-  if (!isa<llvm::GlobalAlias>(GV))
-    getTargetCodeGenInfo().SetTargetAttributes(D, GV, *this);
+  getTargetCodeGenInfo().SetTargetAttributes(D, GO, *this);
 }
 
 void CodeGenModule::SetInternalFunctionAttributes(const Decl *D,
@@ -764,7 +793,32 @@
 
   F->setLinkage(llvm::Function::InternalLinkage);
 
-  SetCommonAttributes(D, F);
+  setNonAliasAttributes(D, F);
+}
+
+static void setLinkageAndVisibilityForGV(llvm::GlobalValue *GV,
+                                         const NamedDecl *ND) {
+  // Set linkage and visibility in case we never see a definition.
+  LinkageInfo LV = ND->getLinkageAndVisibility();
+  if (LV.getLinkage() != ExternalLinkage) {
+    // Don't set internal linkage on declarations.
+  } else {
+    if (ND->hasAttr<DLLImportAttr>()) {
+      GV->setLinkage(llvm::GlobalValue::ExternalLinkage);
+      GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
+    } else if (ND->hasAttr<DLLExportAttr>()) {
+      GV->setLinkage(llvm::GlobalValue::ExternalLinkage);
+      GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
+    } else if (ND->hasAttr<WeakAttr>() || ND->isWeakImported()) {
+      // "extern_weak" is overloaded in LLVM; we probably should have
+      // separate linkage types for this.
+      GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
+    }
+
+    // Set visibility on a declaration only if it's explicit.
+    if (LV.isVisibilityExplicit())
+      GV->setVisibility(CodeGenModule::GetLLVMVisibility(LV.getVisibility()));
+  }
 }
 
 void CodeGenModule::SetFunctionAttributes(GlobalDecl GD,
@@ -778,12 +832,17 @@
     return;
   }
 
-  const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
+  const auto *FD = cast<FunctionDecl>(GD.getDecl());
 
   if (!IsIncompleteFunction)
     SetLLVMFunctionAttributes(FD, getTypes().arrangeGlobalDeclaration(GD), F);
 
-  if (getCXXABI().HasThisReturn(GD)) {
+  // Add the Returned attribute for "this", except for iOS 5 and earlier
+  // where substantial code, including the libstdc++ dylib, was compiled with
+  // GCC and does not actually return "this".
+  if (getCXXABI().HasThisReturn(GD) &&
+      !(getTarget().getTriple().isiOS() &&
+        getTarget().getTriple().isOSVersionLT(6))) {
     assert(!F->arg_empty() &&
            F->arg_begin()->getType()
              ->canLosslesslyBitCastTo(F->getReturnType()) &&
@@ -794,19 +853,12 @@
   // Only a few attributes are set on declarations; these may later be
   // overridden by a definition.
 
-  if (FD->hasAttr<DLLImportAttr>()) {
-    F->setLinkage(llvm::Function::DLLImportLinkage);
-  } else if (FD->hasAttr<WeakAttr>() ||
-             FD->isWeakImported()) {
-    // "extern_weak" is overloaded in LLVM; we probably should have
-    // separate linkage types for this.
-    F->setLinkage(llvm::Function::ExternalWeakLinkage);
-  } else {
-    F->setLinkage(llvm::Function::ExternalLinkage);
+  setLinkageAndVisibilityForGV(F, FD);
 
-    LinkageInfo LV = FD->getLinkageAndVisibility();
-    if (LV.getLinkage() == ExternalLinkage && LV.isVisibilityExplicit()) {
-      F->setVisibility(GetLLVMVisibility(LV.getVisibility()));
+  if (const auto *Dtor = dyn_cast_or_null<CXXDestructorDecl>(FD)) {
+    if (getCXXABI().useThunkForDtorVariant(Dtor, GD.getDtorType())) {
+      // Don't dllexport/import destructor thunks.
+      F->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
     }
   }
 
@@ -820,39 +872,49 @@
                     llvm::Attribute::NoBuiltin);
 }
 
-void CodeGenModule::AddUsedGlobal(llvm::GlobalValue *GV) {
+void CodeGenModule::addUsedGlobal(llvm::GlobalValue *GV) {
   assert(!GV->isDeclaration() &&
          "Only globals with definition can force usage.");
   LLVMUsed.push_back(GV);
 }
 
-void CodeGenModule::EmitLLVMUsed() {
+void CodeGenModule::addCompilerUsedGlobal(llvm::GlobalValue *GV) {
+  assert(!GV->isDeclaration() &&
+         "Only globals with definition can force usage.");
+  LLVMCompilerUsed.push_back(GV);
+}
+
+static void emitUsed(CodeGenModule &CGM, StringRef Name,
+                     std::vector<llvm::WeakVH> &List) {
   // Don't create llvm.used if there is no need.
-  if (LLVMUsed.empty())
+  if (List.empty())
     return;
 
-  // Convert LLVMUsed to what ConstantArray needs.
+  // Convert List to what ConstantArray needs.
   SmallVector<llvm::Constant*, 8> UsedArray;
-  UsedArray.resize(LLVMUsed.size());
-  for (unsigned i = 0, e = LLVMUsed.size(); i != e; ++i) {
+  UsedArray.resize(List.size());
+  for (unsigned i = 0, e = List.size(); i != e; ++i) {
     UsedArray[i] =
-     llvm::ConstantExpr::getBitCast(cast<llvm::Constant>(&*LLVMUsed[i]),
-                                    Int8PtrTy);
+     llvm::ConstantExpr::getBitCast(cast<llvm::Constant>(&*List[i]),
+                                    CGM.Int8PtrTy);
   }
 
   if (UsedArray.empty())
     return;
-  llvm::ArrayType *ATy = llvm::ArrayType::get(Int8PtrTy, UsedArray.size());
+  llvm::ArrayType *ATy = llvm::ArrayType::get(CGM.Int8PtrTy, UsedArray.size());
 
-  llvm::GlobalVariable *GV =
-    new llvm::GlobalVariable(getModule(), ATy, false,
-                             llvm::GlobalValue::AppendingLinkage,
-                             llvm::ConstantArray::get(ATy, UsedArray),
-                             "llvm.used");
+  auto *GV = new llvm::GlobalVariable(
+      CGM.getModule(), ATy, false, llvm::GlobalValue::AppendingLinkage,
+      llvm::ConstantArray::get(ATy, UsedArray), Name);
 
   GV->setSection("llvm.metadata");
 }
 
+void CodeGenModule::emitLLVMUsed() {
+  emitUsed(*this, "llvm.used", LLVMUsed);
+  emitUsed(*this, "llvm.compiler.used", LLVMCompilerUsed);
+}
+
 void CodeGenModule::AppendLinkerOptions(StringRef Opts) {
   llvm::Value *MDOpts = llvm::MDString::get(getLLVMContext(), Opts);
   LinkerOptionsMetadata.push_back(llvm::MDNode::get(getLLVMContext(), MDOpts));
@@ -997,31 +1059,23 @@
     // Stop if we're out of both deferred v-tables and deferred declarations.
     if (DeferredDeclsToEmit.empty()) break;
 
-    GlobalDecl D = DeferredDeclsToEmit.back();
+    DeferredGlobal &G = DeferredDeclsToEmit.back();
+    GlobalDecl D = G.GD;
+    llvm::GlobalValue *GV = G.GV;
     DeferredDeclsToEmit.pop_back();
 
+    assert(GV == GetGlobalValue(getMangledName(D)));
     // Check to see if we've already emitted this.  This is necessary
     // for a couple of reasons: first, decls can end up in the
     // deferred-decls queue multiple times, and second, decls can end
     // up with definitions in unusual ways (e.g. by an extern inline
     // function acquiring a strong function redefinition).  Just
     // ignore these cases.
-    //
-    // TODO: That said, looking this up multiple times is very wasteful.
-    StringRef Name = getMangledName(D);
-    llvm::GlobalValue *CGRef = GetGlobalValue(Name);
-    assert(CGRef && "Deferred decl wasn't referenced?");
-
-    if (!CGRef->isDeclaration())
-      continue;
-
-    // GlobalAlias::isDeclaration() defers to the aliasee, but for our
-    // purposes an alias counts as a definition.
-    if (isa<llvm::GlobalAlias>(CGRef))
+    if(!GV->isDeclaration())
       continue;
 
     // Otherwise, emit the definition and move on to the next one.
-    EmitGlobalDefinition(D);
+    EmitGlobalDefinition(D, GV);
   }
 }
 
@@ -1032,9 +1086,9 @@
   // Create a new global variable for the ConstantStruct in the Module.
   llvm::Constant *Array = llvm::ConstantArray::get(llvm::ArrayType::get(
     Annotations[0]->getType(), Annotations.size()), Annotations);
-  llvm::GlobalValue *gv = new llvm::GlobalVariable(getModule(),
-    Array->getType(), false, llvm::GlobalValue::AppendingLinkage, Array,
-    "llvm.global.annotations");
+  auto *gv = new llvm::GlobalVariable(getModule(), Array->getType(), false,
+                                      llvm::GlobalValue::AppendingLinkage,
+                                      Array, "llvm.global.annotations");
   gv->setSection(AnnotationSection);
 }
 
@@ -1045,8 +1099,9 @@
 
   // Not found yet, create a new global.
   llvm::Constant *s = llvm::ConstantDataArray::getString(getLLVMContext(), Str);
-  llvm::GlobalValue *gv = new llvm::GlobalVariable(getModule(), s->getType(),
-    true, llvm::GlobalValue::PrivateLinkage, s, ".str");
+  auto *gv =
+      new llvm::GlobalVariable(getModule(), s->getType(), true,
+                               llvm::GlobalValue::PrivateLinkage, s, ".str");
   gv->setSection(AnnotationSection);
   gv->setUnnamedAddr(true);
   AStr = gv;
@@ -1091,10 +1146,8 @@
                                          llvm::GlobalValue *GV) {
   assert(D->hasAttr<AnnotateAttr>() && "no annotate attribute");
   // Get the struct elements for these annotations.
-  for (specific_attr_iterator<AnnotateAttr>
-       ai = D->specific_attr_begin<AnnotateAttr>(),
-       ae = D->specific_attr_end<AnnotateAttr>(); ai != ae; ++ai)
-    Annotations.push_back(EmitAnnotateAttr(GV, *ai, D->getLocation()));
+  for (const auto *I : D->specific_attrs<AnnotateAttr>())
+    Annotations.push_back(EmitAnnotateAttr(GV, I, D->getLocation()));
 }
 
 bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) {
@@ -1120,7 +1173,7 @@
   llvm::Constant *Init = EmitUuidofInitializer(Uuid, E->getType());
   assert(Init && "failed to initialize as constant");
 
-  llvm::GlobalVariable *GV = new llvm::GlobalVariable(
+  auto *GV = new llvm::GlobalVariable(
       getModule(), Init->getType(),
       /*isConstant=*/true, llvm::GlobalValue::LinkOnceODRLinkage, Init, Name);
   return GV;
@@ -1146,9 +1199,10 @@
                                       /*ForVTable=*/false);
   else
     Aliasee = GetOrCreateLLVMGlobal(AA->getAliasee(),
-                                    llvm::PointerType::getUnqual(DeclTy), 0);
+                                    llvm::PointerType::getUnqual(DeclTy),
+                                    nullptr);
 
-  llvm::GlobalValue* F = cast<llvm::GlobalValue>(Aliasee);
+  auto *F = cast<llvm::GlobalValue>(Aliasee);
   F->setLinkage(llvm::Function::ExternalWeakLinkage);
   WeakRefReferences.insert(F);
 
@@ -1156,7 +1210,7 @@
 }
 
 void CodeGenModule::EmitGlobal(GlobalDecl GD) {
-  const ValueDecl *Global = cast<ValueDecl>(GD.getDecl());
+  const auto *Global = cast<ValueDecl>(GD.getDecl());
 
   // Weak references don't produce any output by themselves.
   if (Global->hasAttr<WeakRefAttr>())
@@ -1185,25 +1239,28 @@
   }
 
   // Ignore declarations, they will be emitted on their first use.
-  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Global)) {
+  if (const auto *FD = dyn_cast<FunctionDecl>(Global)) {
     // Forward declarations are emitted lazily on first use.
     if (!FD->doesThisDeclarationHaveABody()) {
       if (!FD->doesDeclarationForceExternallyVisibleDefinition())
         return;
 
-      const FunctionDecl *InlineDefinition = 0;
-      FD->getBody(InlineDefinition);
-
       StringRef MangledName = getMangledName(GD);
-      DeferredDecls.erase(MangledName);
-      EmitGlobalDefinition(InlineDefinition);
+
+      // Compute the function info and LLVM type.
+      const CGFunctionInfo &FI = getTypes().arrangeGlobalDeclaration(GD);
+      llvm::Type *Ty = getTypes().GetFunctionType(FI);
+
+      GetOrCreateLLVMFunction(MangledName, Ty, GD, /*ForVTable=*/false,
+                              /*DontDefer=*/false);
       return;
     }
   } else {
-    const VarDecl *VD = cast<VarDecl>(Global);
+    const auto *VD = cast<VarDecl>(Global);
     assert(VD->isFileVarDecl() && "Cannot emit local var decl as global.");
 
-    if (VD->isThisDeclarationADefinition() != VarDecl::Definition)
+    if (VD->isThisDeclarationADefinition() != VarDecl::Definition &&
+        !Context.isMSStaticDataMemberInlineDefinition(VD))
       return;
   }
 
@@ -1220,14 +1277,14 @@
   if (getLangOpts().CPlusPlus && isa<VarDecl>(Global) &&
       cast<VarDecl>(Global)->hasInit()) {
     DelayedCXXInitPosition[Global] = CXXGlobalInits.size();
-    CXXGlobalInits.push_back(0);
+    CXXGlobalInits.push_back(nullptr);
   }
   
   // If the value has already been used, add it directly to the
   // DeferredDeclsToEmit list.
   StringRef MangledName = getMangledName(GD);
-  if (GetGlobalValue(MangledName))
-    DeferredDeclsToEmit.push_back(GD);
+  if (llvm::GlobalValue *GV = GetGlobalValue(MangledName))
+    addDeferredDeclToEmit(GV, GD);
   else {
     // Otherwise, remember that we saw a deferred decl with this name.  The
     // first use of the mangled name will cause it to move into
@@ -1295,9 +1352,8 @@
 CodeGenModule::shouldEmitFunction(GlobalDecl GD) {
   if (getFunctionLinkage(GD) != llvm::Function::AvailableExternallyLinkage)
     return true;
-  const FunctionDecl *F = cast<FunctionDecl>(GD.getDecl());
-  if (CodeGenOpts.OptimizationLevel == 0 &&
-      !F->hasAttr<AlwaysInlineAttr>() && !F->hasAttr<ForceInlineAttr>())
+  const auto *F = cast<FunctionDecl>(GD.getDecl());
+  if (CodeGenOpts.OptimizationLevel == 0 && !F->hasAttr<AlwaysInlineAttr>())
     return false;
   // PR9614. Avoid cases where the source code is lying to us. An available
   // externally function should have an equivalent function somewhere else,
@@ -1318,14 +1374,13 @@
 
   if (CGDebugInfo *DI = getModuleDebugInfo())
     if (getCodeGenOpts().getDebugInfo() >= CodeGenOptions::LimitedDebugInfo) {
-      const PointerType *ThisPtr =
-        cast<PointerType>(D->getThisType(getContext()));
+      const auto *ThisPtr = cast<PointerType>(D->getThisType(getContext()));
       DI->getOrCreateRecordType(ThisPtr->getPointeeType(), D->getLocation());
     }
 }
 
-void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD) {
-  const ValueDecl *D = cast<ValueDecl>(GD.getDecl());
+void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD, llvm::GlobalValue *GV) {
+  const auto *D = cast<ValueDecl>(GD.getDecl());
 
   PrettyStackTraceDecl CrashInfo(const_cast<ValueDecl *>(D), D->getLocation(), 
                                  Context.getSourceManager(),
@@ -1337,16 +1392,16 @@
     if (!shouldEmitFunction(GD))
       return;
 
-    if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
+    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 CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(Method))
+      if (const auto *CD = dyn_cast<CXXConstructorDecl>(Method))
         EmitCXXConstructor(CD, GD.getCtorType());
-      else if (const CXXDestructorDecl *DD =dyn_cast<CXXDestructorDecl>(Method))
+      else if (const auto *DD = dyn_cast<CXXDestructorDecl>(Method))
         EmitCXXDestructor(DD, GD.getDtorType());
       else
-        EmitGlobalFunctionDefinition(GD);
+        EmitGlobalFunctionDefinition(GD, GV);
 
       if (Method->isVirtual())
         getVTables().EmitThunks(GD);
@@ -1354,10 +1409,10 @@
       return;
     }
 
-    return EmitGlobalFunctionDefinition(GD);
+    return EmitGlobalFunctionDefinition(GD, GV);
   }
-  
-  if (const VarDecl *VD = dyn_cast<VarDecl>(D))
+
+  if (const auto *VD = dyn_cast<VarDecl>(D))
     return EmitGlobalVarDefinition(VD);
   
   llvm_unreachable("Invalid argument to EmitGlobalDefinition()");
@@ -1374,6 +1429,7 @@
 CodeGenModule::GetOrCreateLLVMFunction(StringRef MangledName,
                                        llvm::Type *Ty,
                                        GlobalDecl GD, bool ForVTable,
+                                       bool DontDefer,
                                        llvm::AttributeSet ExtraAttrs) {
   const Decl *D = GD.getDecl();
 
@@ -1393,14 +1449,6 @@
     return llvm::ConstantExpr::getBitCast(Entry, Ty->getPointerTo());
   }
 
-  // All MSVC dtors other than the base dtor are linkonce_odr and delegate to
-  // each other bottoming out with the base dtor.  Therefore we emit non-base
-  // dtors on usage, even if there is no dtor definition in the TU.
-  if (D && isa<CXXDestructorDecl>(D) &&
-      getCXXABI().useThunkForDtorVariant(cast<CXXDestructorDecl>(D),
-                                         GD.getDtorType()))
-    DeferredDeclsToEmit.push_back(GD);
-
   // This function doesn't have a complete type (for example, the return
   // type is an incomplete struct). Use a fake type instead, and make
   // sure not to try to set attributes.
@@ -1428,50 +1476,64 @@
                                              B));
   }
 
-  // This is the first use or definition of a mangled name.  If there is a
-  // deferred decl with this name, remember that we need to emit it at the end
-  // of the file.
-  llvm::StringMap<GlobalDecl>::iterator DDI = DeferredDecls.find(MangledName);
-  if (DDI != DeferredDecls.end()) {
-    // Move the potentially referenced deferred decl to the DeferredDeclsToEmit
-    // list, and remove it from DeferredDecls (since we don't need it anymore).
-    DeferredDeclsToEmit.push_back(DDI->second);
-    DeferredDecls.erase(DDI);
+  if (!DontDefer) {
+    // All MSVC dtors other than the base dtor are linkonce_odr and delegate to
+    // each other bottoming out with the base dtor.  Therefore we emit non-base
+    // dtors on usage, even if there is no dtor definition in the TU.
+    if (D && isa<CXXDestructorDecl>(D) &&
+        getCXXABI().useThunkForDtorVariant(cast<CXXDestructorDecl>(D),
+                                           GD.getDtorType()))
+      addDeferredDeclToEmit(F, GD);
 
-  // Otherwise, if this is a sized deallocation function, emit a weak definition
-  // for it at the end of the translation unit.
-  } else if (D && cast<FunctionDecl>(D)
-                      ->getCorrespondingUnsizedGlobalDeallocationFunction()) {
-    DeferredDeclsToEmit.push_back(GD);
+    // This is the first use or definition of a mangled name.  If there is a
+    // deferred decl with this name, remember that we need to emit it at the end
+    // of the file.
+    auto DDI = DeferredDecls.find(MangledName);
+    if (DDI != DeferredDecls.end()) {
+      // Move the potentially referenced deferred decl to the
+      // DeferredDeclsToEmit list, and remove it from DeferredDecls (since we
+      // don't need it anymore).
+      addDeferredDeclToEmit(F, DDI->second);
+      DeferredDecls.erase(DDI);
 
-  // Otherwise, there are cases we have to worry about where we're
-  // using a declaration for which we must emit a definition but where
-  // we might not find a top-level definition:
-  //   - member functions defined inline in their classes
-  //   - friend functions defined inline in some class
-  //   - special member functions with implicit definitions
-  // If we ever change our AST traversal to walk into class methods,
-  // this will be unnecessary.
-  //
-  // We also don't emit a definition for a function if it's going to be an entry
-  // in a vtable, unless it's already marked as used.
-  } else if (getLangOpts().CPlusPlus && D) {
-    // Look for a declaration that's lexically in a record.
-    const FunctionDecl *FD = cast<FunctionDecl>(D);
-    FD = FD->getMostRecentDecl();
-    do {
-      if (isa<CXXRecordDecl>(FD->getLexicalDeclContext())) {
-        if (FD->isImplicit() && !ForVTable) {
-          assert(FD->isUsed() && "Sema didn't mark implicit function as used!");
-          DeferredDeclsToEmit.push_back(GD.getWithDecl(FD));
-          break;
-        } else if (FD->doesThisDeclarationHaveABody()) {
-          DeferredDeclsToEmit.push_back(GD.getWithDecl(FD));
-          break;
+      // Otherwise, if this is a sized deallocation function, emit a weak
+      // definition
+      // for it at the end of the translation unit.
+    } else if (D && cast<FunctionDecl>(D)
+                        ->getCorrespondingUnsizedGlobalDeallocationFunction()) {
+      addDeferredDeclToEmit(F, GD);
+
+      // Otherwise, there are cases we have to worry about where we're
+      // using a declaration for which we must emit a definition but where
+      // we might not find a top-level definition:
+      //   - member functions defined inline in their classes
+      //   - friend functions defined inline in some class
+      //   - special member functions with implicit definitions
+      // If we ever change our AST traversal to walk into class methods,
+      // this will be unnecessary.
+      //
+      // We also don't emit a definition for a function if it's going to be an
+      // entry
+      // in a vtable, unless it's already marked as used.
+    } else if (getLangOpts().CPlusPlus && D) {
+      // Look for a declaration that's lexically in a record.
+      const auto *FD = cast<FunctionDecl>(D);
+      FD = FD->getMostRecentDecl();
+      do {
+        if (isa<CXXRecordDecl>(FD->getLexicalDeclContext())) {
+          if (FD->isImplicit() && !ForVTable) {
+            assert(FD->isUsed() &&
+                   "Sema didn't mark implicit function as used!");
+            addDeferredDeclToEmit(F, GD.getWithDecl(FD));
+            break;
+          } else if (FD->doesThisDeclarationHaveABody()) {
+            addDeferredDeclToEmit(F, GD.getWithDecl(FD));
+            break;
+          }
         }
-      }
-      FD = FD->getPreviousDecl();
-    } while (FD);
+        FD = FD->getPreviousDecl();
+      } while (FD);
+    }
   }
 
   // Make sure the result is of the requested type.
@@ -1489,13 +1551,14 @@
 /// create it (this occurs when we see a definition of the function).
 llvm::Constant *CodeGenModule::GetAddrOfFunction(GlobalDecl GD,
                                                  llvm::Type *Ty,
-                                                 bool ForVTable) {
+                                                 bool ForVTable,
+                                                 bool DontDefer) {
   // If there was no specific requested type, just convert it now.
   if (!Ty)
     Ty = getTypes().ConvertType(cast<ValueDecl>(GD.getDecl())->getType());
   
   StringRef MangledName = getMangledName(GD);
-  return GetOrCreateLLVMFunction(MangledName, Ty, GD, ForVTable);
+  return GetOrCreateLLVMFunction(MangledName, Ty, GD, ForVTable, DontDefer);
 }
 
 /// CreateRuntimeFunction - Create a new runtime function with the specified
@@ -1504,10 +1567,10 @@
 CodeGenModule::CreateRuntimeFunction(llvm::FunctionType *FTy,
                                      StringRef Name,
                                      llvm::AttributeSet ExtraAttrs) {
-  llvm::Constant *C
-    = GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(), /*ForVTable=*/false,
-                              ExtraAttrs);
-  if (llvm::Function *F = dyn_cast<llvm::Function>(C))
+  llvm::Constant *C =
+      GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(), /*ForVTable=*/false,
+                              /*DontDefer=*/false, ExtraAttrs);
+  if (auto *F = dyn_cast<llvm::Function>(C))
     if (F->empty())
       F->setCallingConv(getRuntimeCC());
   return C;
@@ -1543,8 +1606,7 @@
 llvm::Constant *
 CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName,
                                      llvm::PointerType *Ty,
-                                     const VarDecl *D,
-                                     bool UnnamedAddr) {
+                                     const VarDecl *D) {
   // Lookup the entry, lazily creating it if necessary.
   llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
   if (Entry) {
@@ -1553,9 +1615,6 @@
         Entry->setLinkage(llvm::Function::ExternalLinkage);
     }
 
-    if (UnnamedAddr)
-      Entry->setUnnamedAddr(true);
-
     if (Entry->getType() == Ty)
       return Entry;
 
@@ -1566,50 +1625,49 @@
     return llvm::ConstantExpr::getBitCast(Entry, Ty);
   }
 
+  unsigned AddrSpace = GetGlobalVarAddressSpace(D, Ty->getAddressSpace());
+  auto *GV = new llvm::GlobalVariable(
+      getModule(), Ty->getElementType(), false,
+      llvm::GlobalValue::ExternalLinkage, nullptr, MangledName, nullptr,
+      llvm::GlobalVariable::NotThreadLocal, AddrSpace);
+
   // This is the first use or definition of a mangled name.  If there is a
   // deferred decl with this name, remember that we need to emit it at the end
   // of the file.
-  llvm::StringMap<GlobalDecl>::iterator DDI = DeferredDecls.find(MangledName);
+  auto DDI = DeferredDecls.find(MangledName);
   if (DDI != DeferredDecls.end()) {
     // Move the potentially referenced deferred decl to the DeferredDeclsToEmit
     // list, and remove it from DeferredDecls (since we don't need it anymore).
-    DeferredDeclsToEmit.push_back(DDI->second);
+    addDeferredDeclToEmit(GV, DDI->second);
     DeferredDecls.erase(DDI);
   }
 
-  unsigned AddrSpace = GetGlobalVarAddressSpace(D, Ty->getAddressSpace());
-  llvm::GlobalVariable *GV =
-    new llvm::GlobalVariable(getModule(), Ty->getElementType(), false,
-                             llvm::GlobalValue::ExternalLinkage,
-                             0, MangledName, 0,
-                             llvm::GlobalVariable::NotThreadLocal, AddrSpace);
-
   // Handle things which are present even on external declarations.
   if (D) {
     // FIXME: This code is overly simple and should be merged with other global
     // handling.
     GV->setConstant(isTypeConstant(D->getType(), false));
 
-    // Set linkage and visibility in case we never see a definition.
-    LinkageInfo LV = D->getLinkageAndVisibility();
-    if (LV.getLinkage() != ExternalLinkage) {
-      // Don't set internal linkage on declarations.
-    } else {
-      if (D->hasAttr<DLLImportAttr>())
-        GV->setLinkage(llvm::GlobalValue::DLLImportLinkage);
-      else if (D->hasAttr<WeakAttr>() || D->isWeakImported())
-        GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
-
-      // Set visibility on a declaration only if it's explicit.
-      if (LV.isVisibilityExplicit())
-        GV->setVisibility(GetLLVMVisibility(LV.getVisibility()));
-    }
+    setLinkageAndVisibilityForGV(GV, D);
 
     if (D->getTLSKind()) {
       if (D->getTLSKind() == VarDecl::TLS_Dynamic)
         CXXThreadLocals.push_back(std::make_pair(D, GV));
       setTLSMode(GV, *D);
     }
+
+    // If required by the ABI, treat declarations of static data members with
+    // inline initializers as definitions.
+    if (getContext().isMSStaticDataMemberInlineDefinition(D)) {
+      EmitGlobalVarDefinition(D);
+    }
+
+    // Handle XCore specific ABI requirements.
+    if (getTarget().getTriple().getArch() == llvm::Triple::xcore &&
+        D->getLanguageLinkage() == CLanguageLinkage &&
+        D->getType().isConstant(Context) &&
+        isExternallyVisible(D->getLinkageAndVisibility().getLinkage()))
+      GV->setSection(".cp.rodata");
   }
 
   if (AddrSpace != Ty->getAddressSpace())
@@ -1624,9 +1682,8 @@
                                       llvm::Type *Ty,
                                       llvm::GlobalValue::LinkageTypes Linkage) {
   llvm::GlobalVariable *GV = getModule().getNamedGlobal(Name);
-  llvm::GlobalVariable *OldGV = 0;
+  llvm::GlobalVariable *OldGV = nullptr;
 
-  
   if (GV) {
     // Check if the variable has the right type.
     if (GV->getType()->getElementType() == Ty)
@@ -1640,8 +1697,8 @@
   
   // Create a new variable.
   GV = new llvm::GlobalVariable(getModule(), Ty, /*isConstant=*/true,
-                                Linkage, 0, Name);
-  
+                                Linkage, nullptr, Name);
+
   if (OldGV) {
     // Replace occurrences of the old variable if needed.
     GV->takeName(OldGV);
@@ -1666,7 +1723,7 @@
                                                   llvm::Type *Ty) {
   assert(D->hasGlobalStorage() && "Not a global variable");
   QualType ASTTy = D->getType();
-  if (Ty == 0)
+  if (!Ty)
     Ty = getTypes().ConvertTypeForMem(ASTTy);
 
   llvm::PointerType *PTy =
@@ -1681,8 +1738,7 @@
 llvm::Constant *
 CodeGenModule::CreateRuntimeVariable(llvm::Type *Ty,
                                      StringRef Name) {
-  return GetOrCreateLLVMGlobal(Name, llvm::PointerType::getUnqual(Ty), 0,
-                               true);
+  return GetOrCreateLLVMGlobal(Name, llvm::PointerType::getUnqual(Ty), nullptr);
 }
 
 void CodeGenModule::EmitTentativeDefinition(const VarDecl *D) {
@@ -1752,11 +1808,11 @@
   // If we have multiple internal linkage entities with the same name
   // in extern "C" regions, none of them gets that name.
   if (!R.second)
-    R.first->second = 0;
+    R.first->second = nullptr;
 }
 
 void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
-  llvm::Constant *Init = 0;
+  llvm::Constant *Init = nullptr;
   QualType ASTTy = D->getType();
   CXXRecordDecl *RD = ASTTy->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
   bool NeedsGlobalCtor = false;
@@ -1806,7 +1862,7 @@
   llvm::Constant *Entry = GetAddrOfGlobalVar(D, InitType);
 
   // Strip off a bitcast if we got one back.
-  if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Entry)) {
+  if (auto *CE = dyn_cast<llvm::ConstantExpr>(Entry)) {
     assert(CE->getOpcode() == llvm::Instruction::BitCast ||
            CE->getOpcode() == llvm::Instruction::AddrSpaceCast ||
            // All zero index gep.
@@ -1815,7 +1871,7 @@
   }
 
   // Entry is now either a Function or GlobalVariable.
-  llvm::GlobalVariable *GV = dyn_cast<llvm::GlobalVariable>(Entry);
+  auto *GV = dyn_cast<llvm::GlobalVariable>(Entry);
 
   // We have a definition after a declaration with the wrong type.
   // We must make a new GlobalVariable* and update everything that used OldGV
@@ -1826,7 +1882,7 @@
   // "extern int x[];") and then a definition of a different type (e.g.
   // "int x[10];"). This also happens when an initializer has a different type
   // from the type of the global (this happens with unions).
-  if (GV == 0 ||
+  if (!GV ||
       GV->getType()->getElementType() != InitType ||
       GV->getType()->getAddressSpace() !=
        GetGlobalVarAddressSpace(D, getContext().getTargetAddressSpace(ASTTy))) {
@@ -1860,30 +1916,35 @@
   GV->setAlignment(getContext().getDeclAlign(D).getQuantity());
 
   // Set the llvm linkage type as appropriate.
-  llvm::GlobalValue::LinkageTypes Linkage = 
-    GetLLVMLinkageVarDefinition(D, GV->isConstant());
+  llvm::GlobalValue::LinkageTypes Linkage =
+      getLLVMLinkageVarDefinition(D, GV->isConstant());
+
+  // On Darwin, the backing variable for a C++11 thread_local variable always
+  // has internal linkage; all accesses should just be calls to the
+  // Itanium-specified entry point, which has the normal linkage of the
+  // variable.
+  if (const auto *VD = dyn_cast<VarDecl>(D))
+    if (!VD->isStaticLocal() && VD->getTLSKind() == VarDecl::TLS_Dynamic &&
+        Context.getTargetInfo().getTriple().isMacOSX())
+      Linkage = llvm::GlobalValue::InternalLinkage;
+
   GV->setLinkage(Linkage);
+  if (D->hasAttr<DLLImportAttr>())
+    GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass);
+  else if (D->hasAttr<DLLExportAttr>())
+    GV->setDLLStorageClass(llvm::GlobalVariable::DLLExportStorageClass);
+
   if (Linkage == llvm::GlobalVariable::CommonLinkage)
     // common vars aren't constant even if declared const.
     GV->setConstant(false);
 
-  SetCommonAttributes(D, GV);
+  setNonAliasAttributes(D, GV);
 
   // Emit the initializer function if necessary.
   if (NeedsGlobalCtor || NeedsGlobalDtor)
     EmitCXXGlobalVarDeclInitFunc(D, GV, NeedsGlobalCtor);
 
-  // If we are compiling with ASan, add metadata indicating dynamically
-  // initialized globals.
-  if (SanOpts.Address && NeedsGlobalCtor) {
-    llvm::Module &M = getModule();
-
-    llvm::NamedMDNode *DynamicInitializers =
-        M.getOrInsertNamedMetadata("llvm.asan.dynamically_initialized_globals");
-    llvm::Value *GlobalToAdd[] = { GV };
-    llvm::MDNode *ThisGlobal = llvm::MDNode::get(VMContext, GlobalToAdd);
-    DynamicInitializers->addOperand(ThisGlobal);
-  }
+  reportGlobalToASan(GV, *D, NeedsGlobalCtor);
 
   // Emit global variable debug information.
   if (CGDebugInfo *DI = getModuleDebugInfo())
@@ -1891,47 +1952,164 @@
       DI->EmitGlobalVariable(GV, D);
 }
 
-llvm::GlobalValue::LinkageTypes
-CodeGenModule::GetLLVMLinkageVarDefinition(const VarDecl *D, bool isConstant) {
-  GVALinkage Linkage = getContext().GetGVALinkageForVariable(D);
+void CodeGenModule::reportGlobalToASan(llvm::GlobalVariable *GV,
+                                       SourceLocation Loc, StringRef Name,
+                                       bool IsDynInit, bool IsBlacklisted) {
+  if (!LangOpts.Sanitize.Address)
+    return;
+  IsDynInit &= !SanitizerBL.isIn(*GV, "init");
+  IsBlacklisted |= SanitizerBL.isIn(*GV);
+
+  llvm::GlobalVariable *LocDescr = nullptr;
+  llvm::GlobalVariable *GlobalName = nullptr;
+  if (!IsBlacklisted) {
+    // Don't generate source location and global name if it is blacklisted -
+    // it won't be instrumented anyway.
+    PresumedLoc PLoc = Context.getSourceManager().getPresumedLoc(Loc);
+    if (PLoc.isValid()) {
+      llvm::Constant *LocData[] = {
+          GetAddrOfConstantCString(PLoc.getFilename()),
+          llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
+                                 PLoc.getLine()),
+          llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
+                                 PLoc.getColumn()),
+      };
+      auto LocStruct = llvm::ConstantStruct::getAnon(LocData);
+      LocDescr = new llvm::GlobalVariable(TheModule, LocStruct->getType(), true,
+                                          llvm::GlobalValue::PrivateLinkage,
+                                          LocStruct, ".asan_loc_descr");
+      LocDescr->setUnnamedAddr(true);
+      // Add LocDescr to llvm.compiler.used, so that it won't be removed by
+      // the optimizer before the ASan instrumentation pass.
+      addCompilerUsedGlobal(LocDescr);
+    }
+    if (!Name.empty()) {
+      GlobalName = GetAddrOfConstantCString(Name);
+      // GlobalName shouldn't be removed by the optimizer.
+      addCompilerUsedGlobal(GlobalName);
+    }
+  }
+
+  llvm::Value *GlobalMetadata[] = {
+      GV, LocDescr, GlobalName,
+      llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), IsDynInit),
+      llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), IsBlacklisted)};
+
+  llvm::MDNode *ThisGlobal = llvm::MDNode::get(VMContext, GlobalMetadata);
+  llvm::NamedMDNode *AsanGlobals =
+      TheModule.getOrInsertNamedMetadata("llvm.asan.globals");
+  AsanGlobals->addOperand(ThisGlobal);
+}
+
+void CodeGenModule::reportGlobalToASan(llvm::GlobalVariable *GV,
+                                       const VarDecl &D, bool IsDynInit) {
+  if (!LangOpts.Sanitize.Address)
+    return;
+  std::string QualName;
+  llvm::raw_string_ostream OS(QualName);
+  D.printQualifiedName(OS);
+  reportGlobalToASan(GV, D.getLocation(), OS.str(), IsDynInit);
+}
+
+void CodeGenModule::disableSanitizerForGlobal(llvm::GlobalVariable *GV) {
+  // For now, just make sure the global is not modified by the ASan
+  // instrumentation.
+  if (LangOpts.Sanitize.Address)
+    reportGlobalToASan(GV, SourceLocation(), "", false, true);
+}
+
+static bool isVarDeclStrongDefinition(const VarDecl *D, bool NoCommon) {
+  // Don't give variables common linkage if -fno-common was specified unless it
+  // was overridden by a NoCommon attribute.
+  if ((NoCommon || D->hasAttr<NoCommonAttr>()) && !D->hasAttr<CommonAttr>())
+    return true;
+
+  // C11 6.9.2/2:
+  //   A declaration of an identifier for an object that has file scope without
+  //   an initializer, and without a storage-class specifier or with the
+  //   storage-class specifier static, constitutes a tentative definition.
+  if (D->getInit() || D->hasExternalStorage())
+    return true;
+
+  // A variable cannot be both common and exist in a section.
+  if (D->hasAttr<SectionAttr>())
+    return true;
+
+  // Thread local vars aren't considered common linkage.
+  if (D->getTLSKind())
+    return true;
+
+  // Tentative definitions marked with WeakImportAttr are true definitions.
+  if (D->hasAttr<WeakImportAttr>())
+    return true;
+
+  return false;
+}
+
+llvm::GlobalValue::LinkageTypes CodeGenModule::getLLVMLinkageForDeclarator(
+    const DeclaratorDecl *D, GVALinkage Linkage, bool IsConstantVariable) {
   if (Linkage == GVA_Internal)
     return llvm::Function::InternalLinkage;
-  else if (D->hasAttr<DLLImportAttr>())
-    return llvm::Function::DLLImportLinkage;
-  else if (D->hasAttr<DLLExportAttr>())
-    return llvm::Function::DLLExportLinkage;
-  else if (D->hasAttr<SelectAnyAttr>()) {
-    // selectany symbols are externally visible, so use weak instead of
-    // linkonce.  MSVC optimizes away references to const selectany globals, so
-    // all definitions should be the same and ODR linkage should be used.
-    // http://msdn.microsoft.com/en-us/library/5tkz6s71.aspx
-    return llvm::GlobalVariable::WeakODRLinkage;
-  } else if (D->hasAttr<WeakAttr>()) {
-    if (isConstant)
+
+  if (D->hasAttr<WeakAttr>()) {
+    if (IsConstantVariable)
       return llvm::GlobalVariable::WeakODRLinkage;
     else
       return llvm::GlobalVariable::WeakAnyLinkage;
-  } else if (Linkage == GVA_TemplateInstantiation ||
-             Linkage == GVA_ExplicitTemplateInstantiation)
-    return llvm::GlobalVariable::WeakODRLinkage;
-  else if (!getLangOpts().CPlusPlus && 
-           ((!CodeGenOpts.NoCommon && !D->getAttr<NoCommonAttr>()) ||
-             D->getAttr<CommonAttr>()) &&
-           !D->hasExternalStorage() && !D->getInit() &&
-           !D->getAttr<SectionAttr>() && !D->getTLSKind() &&
-           !D->getAttr<WeakImportAttr>()) {
-    // Thread local vars aren't considered common linkage.
+  }
+
+  // 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;
+
+  // Note that Apple's kernel linker doesn't support symbol
+  // coalescing, so we need to avoid linkonce and weak linkages there.
+  // Normally, this means we just map to internal, but for explicit
+  // instantiations we'll map to external.
+
+  // In C++, the compiler has to emit a definition in every translation unit
+  // that references the function.  We should use linkonce_odr because
+  // a) if all references in this translation unit are optimized away, we
+  // don't need to codegen it.  b) if the function persists, it needs to be
+  // merged with other definitions. c) C++ has the ODR, so we know the
+  // definition is dependable.
+  if (Linkage == GVA_DiscardableODR)
+    return !Context.getLangOpts().AppleKext ? llvm::Function::LinkOnceODRLinkage
+                                            : llvm::Function::InternalLinkage;
+
+  // An explicit instantiation of a template has weak linkage, since
+  // explicit instantiations can occur in multiple translation units
+  // and must all be equivalent. However, we are not allowed to
+  // throw away these explicit instantiations.
+  if (Linkage == GVA_StrongODR)
+    return !Context.getLangOpts().AppleKext ? llvm::Function::WeakODRLinkage
+                                            : llvm::Function::ExternalLinkage;
+
+  // C++ doesn't have tentative definitions and thus cannot have common
+  // linkage.
+  if (!getLangOpts().CPlusPlus && isa<VarDecl>(D) &&
+      !isVarDeclStrongDefinition(cast<VarDecl>(D), CodeGenOpts.NoCommon))
     return llvm::GlobalVariable::CommonLinkage;
-  } else if (D->getTLSKind() == VarDecl::TLS_Dynamic &&
-             getTarget().getTriple().isMacOSX())
-    // On Darwin, the backing variable for a C++11 thread_local variable always
-    // has internal linkage; all accesses should just be calls to the
-    // Itanium-specified entry point, which has the normal linkage of the
-    // variable.
-    return llvm::GlobalValue::InternalLinkage;
+
+  // selectany symbols are externally visible, so use weak instead of
+  // linkonce.  MSVC optimizes away references to const selectany globals, so
+  // all definitions should be the same and ODR linkage should be used.
+  // http://msdn.microsoft.com/en-us/library/5tkz6s71.aspx
+  if (D->hasAttr<SelectAnyAttr>())
+    return llvm::GlobalVariable::WeakODRLinkage;
+
+  // Otherwise, we have strong external linkage.
+  assert(Linkage == GVA_StrongExternal);
   return llvm::GlobalVariable::ExternalLinkage;
 }
 
+llvm::GlobalValue::LinkageTypes CodeGenModule::getLLVMLinkageVarDefinition(
+    const VarDecl *VD, bool IsConstant) {
+  GVALinkage Linkage = getContext().GetGVALinkageForVariable(VD);
+  return getLLVMLinkageForDeclarator(VD, Linkage, IsConstant);
+}
+
 /// Replace the uses of a function that was declared with a non-proto type.
 /// We want to silently drop extra arguments from call sites
 static void replaceUsesOfNonProtoConstant(llvm::Constant *old,
@@ -1945,11 +2123,11 @@
   for (llvm::Value::use_iterator ui = old->use_begin(), ue = old->use_end();
          ui != ue; ) {
     llvm::Value::use_iterator use = ui++; // Increment before the use is erased.
-    llvm::User *user = *use;
+    llvm::User *user = use->getUser();
 
     // Recognize and replace uses of bitcasts.  Most calls to
     // unprototyped functions will use bitcasts.
-    if (llvm::ConstantExpr *bitcast = dyn_cast<llvm::ConstantExpr>(user)) {
+    if (auto *bitcast = dyn_cast<llvm::ConstantExpr>(user)) {
       if (bitcast->getOpcode() == llvm::Instruction::BitCast)
         replaceUsesOfNonProtoConstant(bitcast, newFn);
       continue;
@@ -1958,7 +2136,7 @@
     // Recognize calls to the function.
     llvm::CallSite callSite(user);
     if (!callSite) continue;
-    if (!callSite.isCallee(use)) continue;
+    if (!callSite.isCallee(&*use)) continue;
 
     // If the return types don't match exactly, then we can't
     // transform this call unless it's dead.
@@ -2013,8 +2191,7 @@
       newCall = llvm::CallInst::Create(newFn, newArgs, "",
                                        callSite.getInstruction());
     } else {
-      llvm::InvokeInst *oldInvoke =
-        cast<llvm::InvokeInst>(callSite.getInstruction());
+      auto *oldInvoke = cast<llvm::InvokeInst>(callSite.getInstruction());
       newCall = llvm::InvokeInst::Create(newFn,
                                          oldInvoke->getNormalDest(),
                                          oldInvoke->getUnwindDest(),
@@ -2067,29 +2244,36 @@
   EmitTopLevelDecl(VD);
 }
 
-void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) {
-  const FunctionDecl *D = cast<FunctionDecl>(GD.getDecl());
+void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD,
+                                                 llvm::GlobalValue *GV) {
+  const auto *D = cast<FunctionDecl>(GD.getDecl());
 
   // Compute the function info and LLVM type.
   const CGFunctionInfo &FI = getTypes().arrangeGlobalDeclaration(GD);
   llvm::FunctionType *Ty = getTypes().GetFunctionType(FI);
 
   // Get or create the prototype for the function.
-  llvm::Constant *Entry = GetAddrOfFunction(GD, Ty);
+  if (!GV) {
+    llvm::Constant *C =
+        GetAddrOfFunction(GD, Ty, /*ForVTable=*/false, /*DontDefer*/ true);
 
-  // Strip off a bitcast if we got one back.
-  if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Entry)) {
-    assert(CE->getOpcode() == llvm::Instruction::BitCast);
-    Entry = CE->getOperand(0);
+    // Strip off a bitcast if we got one back.
+    if (auto *CE = dyn_cast<llvm::ConstantExpr>(C)) {
+      assert(CE->getOpcode() == llvm::Instruction::BitCast);
+      GV = cast<llvm::GlobalValue>(CE->getOperand(0));
+    } else {
+      GV = cast<llvm::GlobalValue>(C);
+    }
   }
 
+  if (!GV->isDeclaration()) {
+    getDiags().Report(D->getLocation(), diag::err_duplicate_mangled_name);
+    return;
+  }
 
-  if (cast<llvm::GlobalValue>(Entry)->getType()->getElementType() != Ty) {
-    llvm::GlobalValue *OldFn = cast<llvm::GlobalValue>(Entry);
-
+  if (GV->getType()->getElementType() != Ty) {
     // If the types mismatch then we have to rewrite the definition.
-    assert(OldFn->isDeclaration() &&
-           "Shouldn't replace non-declaration");
+    assert(GV->isDeclaration() && "Shouldn't replace non-declaration");
 
     // F is the Function* for the one with the wrong type, we must make a new
     // Function* and update everything that used F (a declaration) with the new
@@ -2099,8 +2283,8 @@
     // (e.g. "int f()") and then a definition of a different type
     // (e.g. "int f(int x)").  Move the old function aside so that it
     // doesn't interfere with GetAddrOfFunction.
-    OldFn->setName(StringRef());
-    llvm::Function *NewFn = cast<llvm::Function>(GetAddrOfFunction(GD, Ty));
+    GV->setName(StringRef());
+    auto *NewFn = cast<llvm::Function>(GetAddrOfFunction(GD, Ty));
 
     // This might be an implementation of a function without a
     // prototype, in which case, try to do special replacement of
@@ -2109,39 +2293,39 @@
     // so as to make a direct call, which makes the inliner happier
     // and suppresses a number of optimizer warnings (!) about
     // dropping arguments.
-    if (!OldFn->use_empty()) {
-      ReplaceUsesOfNonProtoTypeWithRealFunction(OldFn, NewFn);
-      OldFn->removeDeadConstantUsers();
+    if (!GV->use_empty()) {
+      ReplaceUsesOfNonProtoTypeWithRealFunction(GV, NewFn);
+      GV->removeDeadConstantUsers();
     }
 
     // Replace uses of F with the Function we will endow with a body.
-    if (!Entry->use_empty()) {
+    if (!GV->use_empty()) {
       llvm::Constant *NewPtrForOldDecl =
-        llvm::ConstantExpr::getBitCast(NewFn, Entry->getType());
-      Entry->replaceAllUsesWith(NewPtrForOldDecl);
+          llvm::ConstantExpr::getBitCast(NewFn, GV->getType());
+      GV->replaceAllUsesWith(NewPtrForOldDecl);
     }
 
     // Ok, delete the old function now, which is dead.
-    OldFn->eraseFromParent();
+    GV->eraseFromParent();
 
-    Entry = NewFn;
+    GV = NewFn;
   }
 
   // We need to set linkage and visibility on the function before
   // generating code for it because various parts of IR generation
   // want to propagate this information down (e.g. to local static
   // declarations).
-  llvm::Function *Fn = cast<llvm::Function>(Entry);
+  auto *Fn = cast<llvm::Function>(GV);
   setFunctionLinkage(GD, Fn);
 
-  // FIXME: this is redundant with part of SetFunctionDefinitionAttributes
+  // FIXME: this is redundant with part of setFunctionDefinitionAttributes
   setGlobalVisibility(Fn, D);
 
   MaybeHandleStaticInExternC(D, Fn);
 
   CodeGenFunction(*this).GenerateCode(D, Fn, FI);
 
-  SetFunctionDefinitionAttributes(D, Fn);
+  setFunctionDefinitionAttributes(D, Fn);
   SetLLVMFunctionAttributesForDefinition(D, Fn);
 
   if (const ConstructorAttr *CA = D->getAttr<ConstructorAttr>())
@@ -2153,7 +2337,7 @@
 }
 
 void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) {
-  const ValueDecl *D = cast<ValueDecl>(GD.getDecl());
+  const auto *D = cast<ValueDecl>(GD.getDecl());
   const AliasAttr *AA = D->getAttr<AliasAttr>();
   assert(AA && "Not an alias?");
 
@@ -2177,15 +2361,20 @@
                                       /*ForVTable=*/false);
   else
     Aliasee = GetOrCreateLLVMGlobal(AA->getAliasee(),
-                                    llvm::PointerType::getUnqual(DeclTy), 0);
+                                    llvm::PointerType::getUnqual(DeclTy),
+                                    nullptr);
 
   // Create the new alias itself, but don't set a name yet.
-  llvm::GlobalValue *GA =
-    new llvm::GlobalAlias(Aliasee->getType(),
-                          llvm::Function::ExternalLinkage,
-                          "", Aliasee, &getModule());
+  auto *GA = llvm::GlobalAlias::create(
+      cast<llvm::PointerType>(Aliasee->getType())->getElementType(), 0,
+      llvm::Function::ExternalLinkage, "", Aliasee, &getModule());
 
   if (Entry) {
+    if (GA->getAliasee() == Entry) {
+      Diags.Report(AA->getLocation(), diag::err_cyclic_alias);
+      return;
+    }
+
     assert(Entry->isDeclaration());
 
     // If there is a declaration in the module, then we had an extern followed
@@ -2208,12 +2397,12 @@
   // specialization of the attributes which may be set on a global
   // variable/function.
   if (D->hasAttr<DLLExportAttr>()) {
-    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
       // The dllexport attribute is ignored for undefined symbols.
       if (FD->hasBody())
-        GA->setLinkage(llvm::Function::DLLExportLinkage);
+        GA->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
     } else {
-      GA->setLinkage(llvm::Function::DLLExportLinkage);
+      GA->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
     }
   } else if (D->hasAttr<WeakAttr>() ||
              D->hasAttr<WeakRefAttr>() ||
@@ -2306,8 +2495,7 @@
 
   QualType CFTy = getContext().getCFConstantStringType();
 
-  llvm::StructType *STy =
-    cast<llvm::StructType>(getTypes().ConvertType(CFTy));
+  auto *STy = cast<llvm::StructType>(getTypes().ConvertType(CFTy));
 
   llvm::Constant *Fields[4];
 
@@ -2320,7 +2508,7 @@
     llvm::ConstantInt::get(Ty, 0x07C8);
 
   // String pointer.
-  llvm::Constant *C = 0;
+  llvm::Constant *C = nullptr;
   if (isUTF16) {
     ArrayRef<uint16_t> Arr =
       llvm::makeArrayRef<uint16_t>(reinterpret_cast<uint16_t*>(
@@ -2331,30 +2519,25 @@
     C = llvm::ConstantDataArray::getString(VMContext, Entry.getKey());
   }
 
-  llvm::GlobalValue::LinkageTypes Linkage;
-  if (isUTF16)
-    // FIXME: why do utf strings get "_" labels instead of "L" labels?
-    Linkage = llvm::GlobalValue::InternalLinkage;
-  else
-    // FIXME: With OS X ld 123.2 (xcode 4) and LTO we would get a linker error
-    // when using private linkage. It is not clear if this is a bug in ld
-    // or a reasonable new restriction.
-    Linkage = llvm::GlobalValue::LinkerPrivateLinkage;
-  
   // Note: -fwritable-strings doesn't make the backing store strings of
   // CFStrings writable. (See <rdar://problem/10657500>)
-  llvm::GlobalVariable *GV =
-    new llvm::GlobalVariable(getModule(), C->getType(), /*isConstant=*/true,
-                             Linkage, C, ".str");
+  auto *GV =
+      new llvm::GlobalVariable(getModule(), C->getType(), /*isConstant=*/true,
+                               llvm::GlobalValue::PrivateLinkage, C, ".str");
   GV->setUnnamedAddr(true);
   // Don't enforce the target's minimum global alignment, since the only use
   // of the string is via this class initializer.
+  // FIXME: We set the section explicitly to avoid a bug in ld64 224.1. Without
+  // it LLVM can merge the string with a non unnamed_addr one during LTO. Doing
+  // that changes the section it ends in, which surprises ld64.
   if (isUTF16) {
     CharUnits Align = getContext().getTypeAlignInChars(getContext().ShortTy);
     GV->setAlignment(Align.getQuantity());
+    GV->setSection("__TEXT,__ustring");
   } else {
     CharUnits Align = getContext().getTypeAlignInChars(getContext().CharTy);
     GV->setAlignment(Align.getQuantity());
+    GV->setSection("__TEXT,__cstring,cstring_literals");
   }
 
   // String.
@@ -2373,23 +2556,12 @@
   GV = new llvm::GlobalVariable(getModule(), C->getType(), true,
                                 llvm::GlobalVariable::PrivateLinkage, C,
                                 "_unnamed_cfstring_");
-  if (const char *Sect = getTarget().getCFStringSection())
-    GV->setSection(Sect);
+  GV->setSection("__DATA,__cfstring");
   Entry.setValue(GV);
 
   return GV;
 }
 
-static RecordDecl *
-CreateRecordDecl(const ASTContext &Ctx, RecordDecl::TagKind TK,
-                 DeclContext *DC, IdentifierInfo *Id) {
-  SourceLocation Loc;
-  if (Ctx.getLangOpts().CPlusPlus)
-    return CXXRecordDecl::Create(Ctx, TK, DC, Loc, Loc, Id);
-  else
-    return RecordDecl::Create(Ctx, TK, DC, Loc, Loc, Id);
-}
-
 llvm::Constant *
 CodeGenModule::GetAddrOfConstantString(const StringLiteral *Literal) {
   unsigned StringLength = 0;
@@ -2432,9 +2604,7 @@
 
   if (!NSConstantStringType) {
     // Construct the type for a constant NSString.
-    RecordDecl *D = CreateRecordDecl(Context, TTK_Struct, 
-                                     Context.getTranslationUnitDecl(),
-                                   &Context.Idents.get("__builtin_NSString"));
+    RecordDecl *D = Context.buildImplicitRecord("__builtin_NSString");
     D->startDefinition();
       
     QualType FieldTypes[3];
@@ -2450,9 +2620,9 @@
     for (unsigned i = 0; i < 3; ++i) {
       FieldDecl *Field = FieldDecl::Create(Context, D,
                                            SourceLocation(),
-                                           SourceLocation(), 0,
-                                           FieldTypes[i], /*TInfo=*/0,
-                                           /*BitWidth=*/0,
+                                           SourceLocation(), nullptr,
+                                           FieldTypes[i], /*TInfo=*/nullptr,
+                                           /*BitWidth=*/nullptr,
                                            /*Mutable=*/false,
                                            ICIS_NoInit);
       Field->setAccess(AS_public);
@@ -2477,10 +2647,9 @@
   bool isConstant;
   Linkage = llvm::GlobalValue::PrivateLinkage;
   isConstant = !LangOpts.WritableStrings;
-  
-  llvm::GlobalVariable *GV =
-  new llvm::GlobalVariable(getModule(), C->getType(), isConstant, Linkage, C,
-                           ".str");
+
+  auto *GV = new llvm::GlobalVariable(getModule(), C->getType(), isConstant,
+                                      Linkage, C, ".str");
   GV->setUnnamedAddr(true);
   // Don't enforce the target's minimum global alignment, since the only use
   // of the string is via this class initializer.
@@ -2497,12 +2666,13 @@
   GV = new llvm::GlobalVariable(getModule(), C->getType(), true,
                                 llvm::GlobalVariable::PrivateLinkage, C,
                                 "_unnamed_nsstring_");
+  const char *NSStringSection = "__OBJC,__cstring_object,regular,no_dead_strip";
+  const char *NSStringNonFragileABISection =
+      "__DATA,__objc_stringobj,regular,no_dead_strip";
   // FIXME. Fix section.
-  if (const char *Sect = 
-        LangOpts.ObjCRuntime.isNonFragile() 
-          ? getTarget().getNSStringNonFragileABISection() 
-          : getTarget().getNSStringSection())
-    GV->setSection(Sect);
+  GV->setSection(LangOpts.ObjCRuntime.isNonFragile()
+                     ? NSStringNonFragileABISection
+                     : NSStringSection);
   Entry.setValue(GV);
   
   return GV;
@@ -2510,9 +2680,7 @@
 
 QualType CodeGenModule::getObjCFastEnumerationStateType() {
   if (ObjCFastEnumerationStateType.isNull()) {
-    RecordDecl *D = CreateRecordDecl(Context, TTK_Struct, 
-                                     Context.getTranslationUnitDecl(),
-                      &Context.Idents.get("__objcFastEnumerationState"));
+    RecordDecl *D = Context.buildImplicitRecord("__objcFastEnumerationState");
     D->startDefinition();
     
     QualType FieldTypes[] = {
@@ -2527,9 +2695,9 @@
       FieldDecl *Field = FieldDecl::Create(Context,
                                            D,
                                            SourceLocation(),
-                                           SourceLocation(), 0,
-                                           FieldTypes[i], /*TInfo=*/0,
-                                           /*BitWidth=*/0,
+                                           SourceLocation(), nullptr,
+                                           FieldTypes[i], /*TInfo=*/nullptr,
+                                           /*BitWidth=*/nullptr,
                                            /*Mutable=*/false,
                                            ICIS_NoInit);
       Field->setAccess(AS_public);
@@ -2557,9 +2725,8 @@
     Str.resize(CAT->getSize().getZExtValue());
     return llvm::ConstantDataArray::getString(VMContext, Str, false);
   }
-  
-  llvm::ArrayType *AType =
-    cast<llvm::ArrayType>(getTypes().ConvertType(E->getType()));
+
+  auto *AType = cast<llvm::ArrayType>(getTypes().ConvertType(E->getType()));
   llvm::Type *ElemTy = AType->getElementType();
   unsigned NumElements = AType->getNumElements();
 
@@ -2584,36 +2751,73 @@
   return llvm::ConstantDataArray::get(VMContext, Elements);
 }
 
+static llvm::GlobalVariable *
+GenerateStringLiteral(llvm::Constant *C, llvm::GlobalValue::LinkageTypes LT,
+                      CodeGenModule &CGM, StringRef GlobalName,
+                      unsigned Alignment) {
+  // OpenCL v1.2 s6.5.3: a string literal is in the constant address space.
+  unsigned AddrSpace = 0;
+  if (CGM.getLangOpts().OpenCL)
+    AddrSpace = CGM.getContext().getTargetAddressSpace(LangAS::opencl_constant);
+
+  // Create a global variable for this string
+  auto *GV = new llvm::GlobalVariable(
+      CGM.getModule(), C->getType(), !CGM.getLangOpts().WritableStrings, LT, C,
+      GlobalName, nullptr, llvm::GlobalVariable::NotThreadLocal, AddrSpace);
+  GV->setAlignment(Alignment);
+  GV->setUnnamedAddr(true);
+  return GV;
+}
+
 /// GetAddrOfConstantStringFromLiteral - Return a pointer to a
 /// constant array for the given string literal.
-llvm::Constant *
+llvm::GlobalVariable *
 CodeGenModule::GetAddrOfConstantStringFromLiteral(const StringLiteral *S) {
-  CharUnits Align = getContext().getAlignOfGlobalVarInChars(S->getType());
-  if (S->isAscii() || S->isUTF8()) {
-    SmallString<64> Str(S->getString());
-    
-    // Resize the string to the right size, which is indicated by its type.
-    const ConstantArrayType *CAT = Context.getAsConstantArrayType(S->getType());
-    Str.resize(CAT->getSize().getZExtValue());
-    return GetAddrOfConstantString(Str, /*GlobalName*/ 0, Align.getQuantity());
+  auto Alignment =
+      getContext().getAlignOfGlobalVarInChars(S->getType()).getQuantity();
+
+  llvm::Constant *C = GetConstantArrayFromStringLiteral(S);
+  llvm::GlobalVariable **Entry = nullptr;
+  if (!LangOpts.WritableStrings) {
+    Entry = &ConstantStringMap[C];
+    if (auto GV = *Entry) {
+      if (Alignment > GV->getAlignment())
+        GV->setAlignment(Alignment);
+      return GV;
+    }
   }
 
-  // FIXME: the following does not memoize wide strings.
-  llvm::Constant *C = GetConstantArrayFromStringLiteral(S);
-  llvm::GlobalVariable *GV =
-    new llvm::GlobalVariable(getModule(),C->getType(),
-                             !LangOpts.WritableStrings,
-                             llvm::GlobalValue::PrivateLinkage,
-                             C,".str");
+  SmallString<256> MangledNameBuffer;
+  StringRef GlobalVariableName;
+  llvm::GlobalValue::LinkageTypes LT;
 
-  GV->setAlignment(Align.getQuantity());
-  GV->setUnnamedAddr(true);
+  // Mangle the string literal if the ABI allows for it.  However, we cannot
+  // do this if  we are compiling with ASan or -fwritable-strings because they
+  // rely on strings having normal linkage.
+  if (!LangOpts.WritableStrings && !LangOpts.Sanitize.Address &&
+      getCXXABI().getMangleContext().shouldMangleStringLiteral(S)) {
+    llvm::raw_svector_ostream Out(MangledNameBuffer);
+    getCXXABI().getMangleContext().mangleStringLiteral(S, Out);
+    Out.flush();
+
+    LT = llvm::GlobalValue::LinkOnceODRLinkage;
+    GlobalVariableName = MangledNameBuffer;
+  } else {
+    LT = llvm::GlobalValue::PrivateLinkage;
+    GlobalVariableName = ".str";
+  }
+
+  auto GV = GenerateStringLiteral(C, LT, *this, GlobalVariableName, Alignment);
+  if (Entry)
+    *Entry = GV;
+
+  reportGlobalToASan(GV, S->getStrTokenLoc(0), "<string literal>");
   return GV;
 }
 
 /// GetAddrOfConstantStringFromObjCEncode - Return a pointer to a constant
 /// array for the given ObjCEncodeExpr node.
-llvm::Constant *
+llvm::GlobalVariable *
 CodeGenModule::GetAddrOfConstantStringFromObjCEncode(const ObjCEncodeExpr *E) {
   std::string Str;
   getContext().getObjCEncodingForType(E->getEncodedType(), Str);
@@ -2621,87 +2825,48 @@
   return GetAddrOfConstantCString(Str);
 }
 
-
-/// GenerateWritableString -- Creates storage for a string literal.
-static llvm::GlobalVariable *GenerateStringLiteral(StringRef str,
-                                             bool constant,
-                                             CodeGenModule &CGM,
-                                             const char *GlobalName,
-                                             unsigned Alignment) {
-  // Create Constant for this string literal. Don't add a '\0'.
-  llvm::Constant *C =
-      llvm::ConstantDataArray::getString(CGM.getLLVMContext(), str, false);
-
-  // OpenCL v1.1 s6.5.3: a string literal is in the constant address space.
-  unsigned AddrSpace = 0;
-  if (CGM.getLangOpts().OpenCL)
-    AddrSpace = CGM.getContext().getTargetAddressSpace(LangAS::opencl_constant);
-
-  // Create a global variable for this string
-  llvm::GlobalVariable *GV = new llvm::GlobalVariable(
-      CGM.getModule(), C->getType(), constant,
-      llvm::GlobalValue::PrivateLinkage, C, GlobalName, 0,
-      llvm::GlobalVariable::NotThreadLocal, AddrSpace);
-  GV->setAlignment(Alignment);
-  GV->setUnnamedAddr(true);
-  return GV;
-}
-
-/// GetAddrOfConstantString - Returns a pointer to a character array
-/// containing the literal. This contents are exactly that of the
-/// given string, i.e. it will not be null terminated automatically;
-/// see GetAddrOfConstantCString. Note that whether the result is
-/// actually a pointer to an LLVM constant depends on
-/// Feature.WriteableStrings.
-///
+/// GetAddrOfConstantCString - Returns a pointer to a character array containing
+/// the literal and a terminating '\0' character.
 /// The result has pointer to array type.
-llvm::Constant *CodeGenModule::GetAddrOfConstantString(StringRef Str,
-                                                       const char *GlobalName,
-                                                       unsigned Alignment) {
+llvm::GlobalVariable *CodeGenModule::GetAddrOfConstantCString(
+    const std::string &Str, const char *GlobalName, unsigned Alignment) {
+  StringRef StrWithNull(Str.c_str(), Str.size() + 1);
+  if (Alignment == 0) {
+    Alignment = getContext()
+                    .getAlignOfGlobalVarInChars(getContext().CharTy)
+                    .getQuantity();
+  }
+
+  llvm::Constant *C =
+      llvm::ConstantDataArray::getString(getLLVMContext(), StrWithNull, false);
+
+  // Don't share any string literals if strings aren't constant.
+  llvm::GlobalVariable **Entry = nullptr;
+  if (!LangOpts.WritableStrings) {
+    Entry = &ConstantStringMap[C];
+    if (auto GV = *Entry) {
+      if (Alignment > GV->getAlignment())
+        GV->setAlignment(Alignment);
+      return GV;
+    }
+  }
+
   // Get the default prefix if a name wasn't specified.
   if (!GlobalName)
     GlobalName = ".str";
-
-  if (Alignment == 0)
-    Alignment = getContext().getAlignOfGlobalVarInChars(getContext().CharTy)
-      .getQuantity();
-
-  // Don't share any string literals if strings aren't constant.
-  if (LangOpts.WritableStrings)
-    return GenerateStringLiteral(Str, false, *this, GlobalName, Alignment);
-
-  llvm::StringMapEntry<llvm::GlobalVariable *> &Entry =
-    ConstantStringMap.GetOrCreateValue(Str);
-
-  if (llvm::GlobalVariable *GV = Entry.getValue()) {
-    if (Alignment > GV->getAlignment()) {
-      GV->setAlignment(Alignment);
-    }
-    return GV;
-  }
-
   // Create a global variable for this.
-  llvm::GlobalVariable *GV = GenerateStringLiteral(Str, true, *this, GlobalName,
-                                                   Alignment);
-  Entry.setValue(GV);
+  auto GV = GenerateStringLiteral(C, llvm::GlobalValue::PrivateLinkage, *this,
+                                  GlobalName, Alignment);
+  if (Entry)
+    *Entry = GV;
   return GV;
 }
 
-/// GetAddrOfConstantCString - Returns a pointer to a character
-/// array containing the literal and a terminating '\0'
-/// character. The result has pointer to array type.
-llvm::Constant *CodeGenModule::GetAddrOfConstantCString(const std::string &Str,
-                                                        const char *GlobalName,
-                                                        unsigned Alignment) {
-  StringRef StrWithNull(Str.c_str(), Str.size() + 1);
-  return GetAddrOfConstantString(StrWithNull, GlobalName, Alignment);
-}
-
 llvm::Constant *CodeGenModule::GetAddrOfGlobalTemporary(
     const MaterializeTemporaryExpr *E, const Expr *Init) {
   assert((E->getStorageDuration() == SD_Static ||
           E->getStorageDuration() == SD_Thread) && "not a global temporary");
-  const VarDecl *VD = cast<VarDecl>(E->getExtendingDecl());
+  const auto *VD = cast<VarDecl>(E->getExtendingDecl());
 
   // If we're not materializing a subobject of the temporary, keep the
   // cv-qualifiers from the type of the MaterializeTemporaryExpr.
@@ -2718,10 +2883,11 @@
   // we also need to make the temporaries externally-visible).
   SmallString<256> Name;
   llvm::raw_svector_ostream Out(Name);
-  getCXXABI().getMangleContext().mangleReferenceTemporary(VD, Out);
+  getCXXABI().getMangleContext().mangleReferenceTemporary(
+      VD, E->getManglingNumber(), Out);
   Out.flush();
 
-  APValue *Value = 0;
+  APValue *Value = nullptr;
   if (E->getStorageDuration() == SD_Static) {
     // We might have a cached constant initializer for this temporary. Note
     // that this might have a different value from the value computed by
@@ -2729,7 +2895,7 @@
     // modifies the temporary.
     Value = getContext().getMaterializedTemporaryValue(E, false);
     if (Value && Value->isUninit())
-      Value = 0;
+      Value = nullptr;
   }
 
   // Try evaluating it now, it might have a constant initializer.
@@ -2738,12 +2904,12 @@
       !EvalResult.hasSideEffects())
     Value = &EvalResult.Val;
 
-  llvm::Constant *InitialValue = 0;
+  llvm::Constant *InitialValue = nullptr;
   bool Constant = false;
   llvm::Type *Type;
   if (Value) {
     // The temporary has a constant initializer, use it.
-    InitialValue = EmitConstantValue(*Value, MaterializedType, 0);
+    InitialValue = EmitConstantValue(*Value, MaterializedType, nullptr);
     Constant = isTypeConstant(MaterializedType, /*ExcludeCtor*/Value);
     Type = InitialValue->getType();
   } else {
@@ -2753,10 +2919,19 @@
   }
 
   // Create a global variable for this lifetime-extended temporary.
-  llvm::GlobalVariable *GV =
-    new llvm::GlobalVariable(getModule(), Type, Constant,
-                             llvm::GlobalValue::PrivateLinkage,
-                             InitialValue, Name.c_str());
+  llvm::GlobalValue::LinkageTypes Linkage =
+      getLLVMLinkageVarDefinition(VD, Constant);
+  // There is no need for this temporary to have global linkage if the global
+  // variable has external linkage.
+  if (Linkage == llvm::GlobalVariable::ExternalLinkage)
+    Linkage = llvm::GlobalVariable::PrivateLinkage;
+  unsigned AddrSpace = GetGlobalVarAddressSpace(
+      VD, getContext().getTargetAddressSpace(MaterializedType));
+  auto *GV = new llvm::GlobalVariable(
+      getModule(), Type, Constant, Linkage, InitialValue, Name.c_str(),
+      /*InsertBefore=*/nullptr, llvm::GlobalVariable::NotThreadLocal,
+      AddrSpace);
+  setGlobalVisibility(GV, VD);
   GV->setAlignment(
       getContext().getTypeAlignInChars(MaterializedType).getQuantity());
   if (VD->getTLSKind())
@@ -2769,10 +2944,7 @@
 /// properties for an implementation.
 void CodeGenModule::EmitObjCPropertyImplementations(const
                                                     ObjCImplementationDecl *D) {
-  for (ObjCImplementationDecl::propimpl_iterator
-         i = D->propimpl_begin(), e = D->propimpl_end(); i != e; ++i) {
-    ObjCPropertyImplDecl *PID = *i;
-
+  for (const auto *PID : D->property_impls()) {
     // Dynamic is just for type-checking.
     if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
       ObjCPropertyDecl *PD = PID->getPropertyDecl();
@@ -2812,7 +2984,7 @@
     Selector cxxSelector = getContext().Selectors.getSelector(0, &II);
     ObjCMethodDecl *DTORMethod =
       ObjCMethodDecl::Create(getContext(), D->getLocation(), D->getLocation(),
-                             cxxSelector, getContext().VoidTy, 0, D,
+                             cxxSelector, getContext().VoidTy, nullptr, D,
                              /*isInstance=*/true, /*isVariadic=*/false,
                           /*isPropertyAccessor=*/true, /*isImplicitlyDeclared=*/true,
                              /*isDefined=*/false, ObjCMethodDecl::Required);
@@ -2833,8 +3005,8 @@
                                                 D->getLocation(),
                                                 D->getLocation(),
                                                 cxxSelector,
-                                                getContext().getObjCIdType(), 0, 
-                                                D, /*isInstance=*/true,
+                                                getContext().getObjCIdType(),
+                                                nullptr, D, /*isInstance=*/true,
                                                 /*isVariadic=*/false,
                                                 /*isPropertyAccessor=*/true,
                                                 /*isImplicitlyDeclared=*/true,
@@ -2847,13 +3019,12 @@
 
 /// EmitNamespace - Emit all declarations in a namespace.
 void CodeGenModule::EmitNamespace(const NamespaceDecl *ND) {
-  for (RecordDecl::decl_iterator I = ND->decls_begin(), E = ND->decls_end();
-       I != E; ++I) {
-    if (const VarDecl *VD = dyn_cast<VarDecl>(*I))
+  for (auto *I : ND->decls()) {
+    if (const auto *VD = dyn_cast<VarDecl>(I))
       if (VD->getTemplateSpecializationKind() != TSK_ExplicitSpecialization &&
           VD->getTemplateSpecializationKind() != TSK_Undeclared)
         continue;
-    EmitTopLevelDecl(*I);
+    EmitTopLevelDecl(I);
   }
 }
 
@@ -2865,17 +3036,14 @@
     return;
   }
 
-  for (RecordDecl::decl_iterator I = LSD->decls_begin(), E = LSD->decls_end();
-       I != E; ++I) {
+  for (auto *I : LSD->decls()) {
     // Meta-data for ObjC class includes references to implemented methods.
     // Generate class's method definitions first.
-    if (ObjCImplDecl *OID = dyn_cast<ObjCImplDecl>(*I)) {
-      for (ObjCContainerDecl::method_iterator M = OID->meth_begin(),
-           MEnd = OID->meth_end();
-           M != MEnd; ++M)
-        EmitTopLevelDecl(*M);
+    if (auto *OID = dyn_cast<ObjCImplDecl>(I)) {
+      for (auto *M : OID->methods())
+        EmitTopLevelDecl(M);
     }
-    EmitTopLevelDecl(*I);
+    EmitTopLevelDecl(I);
   }
 }
 
@@ -2916,7 +3084,6 @@
     break;
     // No code generation needed.
   case Decl::UsingShadow:
-  case Decl::Using:
   case Decl::ClassTemplate:
   case Decl::VarTemplate:
   case Decl::VarTemplatePartialSpecialization:
@@ -2925,6 +3092,10 @@
   case Decl::Block:
   case Decl::Empty:
     break;
+  case Decl::Using:          // using X; [C++]
+    if (CGDebugInfo *DI = getModuleDebugInfo())
+        DI->EmitUsingDecl(cast<UsingDecl>(*D));
+    return;
   case Decl::NamespaceAlias:
     if (CGDebugInfo *DI = getModuleDebugInfo())
         DI->EmitNamespaceAlias(cast<NamespaceAliasDecl>(*D));
@@ -2959,7 +3130,7 @@
     break;
 
   case Decl::ObjCProtocol: {
-    ObjCProtocolDecl *Proto = cast<ObjCProtocolDecl>(D);
+    auto *Proto = cast<ObjCProtocolDecl>(D);
     if (Proto->isThisDeclarationADefinition())
       ObjCRuntime->GenerateProtocol(Proto);
     break;
@@ -2972,7 +3143,7 @@
     break;
 
   case Decl::ObjCImplementation: {
-    ObjCImplementationDecl *OMD = cast<ObjCImplementationDecl>(D);
+    auto *OMD = cast<ObjCImplementationDecl>(D);
     EmitObjCPropertyImplementations(OMD);
     EmitObjCIvarInitializations(OMD);
     ObjCRuntime->GenerateClass(OMD);
@@ -2984,7 +3155,7 @@
     break;
   }
   case Decl::ObjCMethod: {
-    ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(D);
+    auto *OMD = cast<ObjCMethodDecl>(D);
     // If this is not a prototype, emit the body.
     if (OMD->getBody())
       CodeGenFunction(*this).GenerateObjCMethod(OMD);
@@ -2999,7 +3170,7 @@
     break;
 
   case Decl::FileScopeAsm: {
-    FileScopeAsmDecl *AD = cast<FileScopeAsmDecl>(D);
+    auto *AD = cast<FileScopeAsmDecl>(D);
     StringRef AsmString = AD->getAsmString()->getString();
 
     const std::string &S = getModule().getModuleInlineAsm();
@@ -3013,7 +3184,7 @@
   }
 
   case Decl::Import: {
-    ImportDecl *Import = cast<ImportDecl>(D);
+    auto *Import = cast<ImportDecl>(D);
 
     // Ignore import declarations that come from imported modules.
     if (clang::Module *Owner = Import->getOwningModule()) {
@@ -3024,7 +3195,14 @@
 
     ImportedModules.insert(Import->getImportedModule());
     break;
- }
+  }
+
+  case Decl::ClassTemplateSpecialization: {
+    const auto *Spec = cast<ClassTemplateSpecializationDecl>(D);
+    if (DebugInfo &&
+        Spec->getSpecializationKind() == TSK_ExplicitInstantiationDefinition)
+      DebugInfo->completeTemplateDefinition(*Spec);
+  }
 
   default:
     // Make sure we handled everything we should, every other kind is a
@@ -3070,11 +3248,19 @@
     IdentifierInfo *Name = I->first;
     llvm::GlobalValue *Val = I->second;
     if (Val && !getModule().getNamedValue(Name->getName()))
-      AddUsedGlobal(new llvm::GlobalAlias(Val->getType(), Val->getLinkage(),
-                                          Name->getName(), Val, &getModule()));
+      addUsedGlobal(llvm::GlobalAlias::create(Name->getName(), Val));
   }
 }
 
+bool CodeGenModule::lookupRepresentativeDecl(StringRef MangledName,
+                                             GlobalDecl &Result) const {
+  auto Res = Manglings.find(MangledName);
+  if (Res == Manglings.end())
+    return false;
+  Result = Res->getValue();
+  return true;
+}
+
 /// Emits metadata nodes associating all the global values in the
 /// current module with the Decls they came from.  This is useful for
 /// projects using IR gen as a subroutine.
@@ -3083,14 +3269,12 @@
 /// with an llvm::GlobalValue, we create a global named metadata
 /// with the name 'clang.global.decl.ptrs'.
 void CodeGenModule::EmitDeclMetadata() {
-  llvm::NamedMDNode *GlobalMetadata = 0;
+  llvm::NamedMDNode *GlobalMetadata = nullptr;
 
   // StaticLocalDeclMap
-  for (llvm::DenseMap<GlobalDecl,StringRef>::iterator
-         I = MangledDeclNames.begin(), E = MangledDeclNames.end();
-       I != E; ++I) {
-    llvm::GlobalValue *Addr = getModule().getNamedValue(I->second);
-    EmitGlobalDeclMetadata(*this, GlobalMetadata, I->first, Addr);
+  for (auto &I : MangledDeclNames) {
+    llvm::GlobalValue *Addr = getModule().getNamedValue(I.second);
+    EmitGlobalDeclMetadata(*this, GlobalMetadata, I.first, Addr);
   }
 }
 
@@ -3104,17 +3288,15 @@
   // Find the unique metadata ID for this name.
   unsigned DeclPtrKind = Context.getMDKindID("clang.decl.ptr");
 
-  llvm::NamedMDNode *GlobalMetadata = 0;
+  llvm::NamedMDNode *GlobalMetadata = nullptr;
 
-  for (llvm::DenseMap<const Decl*, llvm::Value*>::iterator
-         I = LocalDeclMap.begin(), E = LocalDeclMap.end(); I != E; ++I) {
-    const Decl *D = I->first;
-    llvm::Value *Addr = I->second;
-
-    if (llvm::AllocaInst *Alloca = dyn_cast<llvm::AllocaInst>(Addr)) {
+  for (auto &I : LocalDeclMap) {
+    const Decl *D = I.first;
+    llvm::Value *Addr = I.second;
+    if (auto *Alloca = dyn_cast<llvm::AllocaInst>(Addr)) {
       llvm::Value *DAddr = GetPointerConstant(getLLVMContext(), D);
       Alloca->setMetadata(DeclPtrKind, llvm::MDNode::get(Context, DAddr));
-    } else if (llvm::GlobalValue *GV = dyn_cast<llvm::GlobalValue>(Addr)) {
+    } else if (auto *GV = dyn_cast<llvm::GlobalValue>(Addr)) {
       GlobalDecl GD = GlobalDecl(cast<VarDecl>(D));
       EmitGlobalDeclMetadata(CGM, GlobalMetadata, GD, GV);
     }
@@ -3133,6 +3315,14 @@
   IdentMetadata->addOperand(llvm::MDNode::get(Ctx, IdentNode));
 }
 
+void CodeGenModule::EmitTargetMetadata() {
+  for (auto &I : MangledDeclNames) {
+    const Decl *D = I.first.getDecl()->getMostRecentDecl();
+    llvm::GlobalValue *GV = GetGlobalValue(I.second);
+    getTargetCodeGenInfo().emitTargetMD(D, GV, *this);
+  }
+}
+
 void CodeGenModule::EmitCoverageFile() {
   if (!getCodeGenOpts().CoverageFile.empty()) {
     if (llvm::NamedMDNode *CUNode = TheModule.getNamedMetadata("llvm.dbg.cu")) {
@@ -3176,3 +3366,19 @@
 
   return llvm::ConstantStruct::getAnon(Fields);
 }
+
+llvm::Constant *CodeGenModule::GetAddrOfRTTIDescriptor(QualType Ty,
+                                                       bool ForEH) {
+  // Return a bogus pointer if RTTI is disabled, unless it's for EH.
+  // FIXME: should we even be calling this method if RTTI is disabled
+  // and it's not for EH?
+  if (!ForEH && !getLangOpts().RTTI)
+    return llvm::Constant::getNullValue(Int8PtrTy);
+  
+  if (ForEH && Ty->isObjCObjectPointerType() &&
+      LangOpts.ObjCRuntime.isGNUFamily())
+    return ObjCRuntime->GetEHType(Ty);
+
+  return getCXXABI().getAddrOfRTTIDescriptor(Ty);
+}
+
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index c161224..9533a8d 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -16,6 +16,7 @@
 
 #include "CGVTables.h"
 #include "CodeGenTypes.h"
+#include "SanitizerBlacklist.h"
 #include "clang/AST/Attr.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
@@ -30,129 +31,124 @@
 #include "llvm/ADT/StringMap.h"
 #include "llvm/IR/CallingConv.h"
 #include "llvm/IR/Module.h"
-#include "llvm/Support/ValueHandle.h"
-#include "llvm/Transforms/Utils/SpecialCaseList.h"
+#include "llvm/IR/ValueHandle.h"
 
 namespace llvm {
-  class Module;
-  class Constant;
-  class ConstantInt;
-  class Function;
-  class GlobalValue;
-  class DataLayout;
-  class FunctionType;
-  class LLVMContext;
+class Module;
+class Constant;
+class ConstantInt;
+class Function;
+class GlobalValue;
+class DataLayout;
+class FunctionType;
+class LLVMContext;
+class IndexedInstrProfReader;
 }
 
 namespace clang {
-  class TargetCodeGenInfo;
-  class ASTContext;
-  class AtomicType;
-  class FunctionDecl;
-  class IdentifierInfo;
-  class ObjCMethodDecl;
-  class ObjCImplementationDecl;
-  class ObjCCategoryImplDecl;
-  class ObjCProtocolDecl;
-  class ObjCEncodeExpr;
-  class BlockExpr;
-  class CharUnits;
-  class Decl;
-  class Expr;
-  class Stmt;
-  class InitListExpr;
-  class StringLiteral;
-  class NamedDecl;
-  class ValueDecl;
-  class VarDecl;
-  class LangOptions;
-  class CodeGenOptions;
-  class DiagnosticsEngine;
-  class AnnotateAttr;
-  class CXXDestructorDecl;
-  class MangleBuffer;
-  class Module;
+class TargetCodeGenInfo;
+class ASTContext;
+class AtomicType;
+class FunctionDecl;
+class IdentifierInfo;
+class ObjCMethodDecl;
+class ObjCImplementationDecl;
+class ObjCCategoryImplDecl;
+class ObjCProtocolDecl;
+class ObjCEncodeExpr;
+class BlockExpr;
+class CharUnits;
+class Decl;
+class Expr;
+class Stmt;
+class InitListExpr;
+class StringLiteral;
+class NamedDecl;
+class ValueDecl;
+class VarDecl;
+class LangOptions;
+class CodeGenOptions;
+class DiagnosticsEngine;
+class AnnotateAttr;
+class CXXDestructorDecl;
+class Module;
 
 namespace CodeGen {
 
-  class CallArgList;
-  class CodeGenFunction;
-  class CodeGenTBAA;
-  class CGCXXABI;
-  class CGDebugInfo;
-  class CGObjCRuntime;
-  class CGOpenCLRuntime;
-  class CGCUDARuntime;
-  class BlockFieldFlags;
-  class FunctionArgList;
-  
-  struct OrderGlobalInits {
-    unsigned int priority;
-    unsigned int lex_order;
-    OrderGlobalInits(unsigned int p, unsigned int l) 
+class CallArgList;
+class CodeGenFunction;
+class CodeGenTBAA;
+class CGCXXABI;
+class CGDebugInfo;
+class CGObjCRuntime;
+class CGOpenCLRuntime;
+class CGOpenMPRuntime;
+class CGCUDARuntime;
+class BlockFieldFlags;
+class FunctionArgList;
+
+struct OrderGlobalInits {
+  unsigned int priority;
+  unsigned int lex_order;
+  OrderGlobalInits(unsigned int p, unsigned int l)
       : priority(p), lex_order(l) {}
-    
-    bool operator==(const OrderGlobalInits &RHS) const {
-      return priority == RHS.priority &&
-             lex_order == RHS.lex_order;
-    }
-    
-    bool operator<(const OrderGlobalInits &RHS) const {
-      if (priority < RHS.priority)
-        return true;
-      
-      return priority == RHS.priority && lex_order < RHS.lex_order;
-    }
+
+  bool operator==(const OrderGlobalInits &RHS) const {
+    return priority == RHS.priority && lex_order == RHS.lex_order;
+  }
+
+  bool operator<(const OrderGlobalInits &RHS) const {
+    return std::tie(priority, lex_order) <
+           std::tie(RHS.priority, RHS.lex_order);
+  }
+};
+
+struct CodeGenTypeCache {
+  /// void
+  llvm::Type *VoidTy;
+
+  /// i8, i16, i32, and i64
+  llvm::IntegerType *Int8Ty, *Int16Ty, *Int32Ty, *Int64Ty;
+  /// float, double
+  llvm::Type *FloatTy, *DoubleTy;
+
+  /// int
+  llvm::IntegerType *IntTy;
+
+  /// intptr_t, size_t, and ptrdiff_t, which we assume are the same size.
+  union {
+    llvm::IntegerType *IntPtrTy;
+    llvm::IntegerType *SizeTy;
+    llvm::IntegerType *PtrDiffTy;
   };
 
-  struct CodeGenTypeCache {
-    /// void
-    llvm::Type *VoidTy;
-
-    /// i8, i16, i32, and i64
-    llvm::IntegerType *Int8Ty, *Int16Ty, *Int32Ty, *Int64Ty;
-    /// float, double
-    llvm::Type *FloatTy, *DoubleTy;
-
-    /// int
-    llvm::IntegerType *IntTy;
-
-    /// intptr_t, size_t, and ptrdiff_t, which we assume are the same size.
-    union {
-      llvm::IntegerType *IntPtrTy;
-      llvm::IntegerType *SizeTy;
-      llvm::IntegerType *PtrDiffTy;
-    };
-
-    /// void* in address space 0
-    union {
-      llvm::PointerType *VoidPtrTy;
-      llvm::PointerType *Int8PtrTy;
-    };
-
-    /// void** in address space 0
-    union {
-      llvm::PointerType *VoidPtrPtrTy;
-      llvm::PointerType *Int8PtrPtrTy;
-    };
-
-    /// The width of a pointer into the generic address space.
-    unsigned char PointerWidthInBits;
-
-    /// The size and alignment of a pointer into the generic address
-    /// space.
-    union {
-      unsigned char PointerAlignInBytes;
-      unsigned char PointerSizeInBytes;
-      unsigned char SizeSizeInBytes;     // sizeof(size_t)
-    };
-
-    llvm::CallingConv::ID RuntimeCC;
-    llvm::CallingConv::ID getRuntimeCC() const {
-      return RuntimeCC;
-    }
+  /// void* in address space 0
+  union {
+    llvm::PointerType *VoidPtrTy;
+    llvm::PointerType *Int8PtrTy;
   };
 
+  /// void** in address space 0
+  union {
+    llvm::PointerType *VoidPtrPtrTy;
+    llvm::PointerType *Int8PtrPtrTy;
+  };
+
+  /// The width of a pointer into the generic address space.
+  unsigned char PointerWidthInBits;
+
+  /// The size and alignment of a pointer into the generic address
+  /// space.
+  union {
+    unsigned char PointerAlignInBytes;
+    unsigned char PointerSizeInBytes;
+    unsigned char SizeSizeInBytes; // sizeof(size_t)
+  };
+
+  llvm::CallingConv::ID RuntimeCC;
+  llvm::CallingConv::ID getRuntimeCC() const { return RuntimeCC; }
+};
+
 struct RREntrypoints {
   RREntrypoints() { memset(this, 0, sizeof(*this)); }
   /// void objc_autoreleasePoolPop(void*);
@@ -221,13 +217,57 @@
   llvm::Constant *clang_arc_use;
 };
 
-/// CodeGenModule - This class organizes the cross-function state that is used
-/// while generating LLVM code.
+/// This class records statistics on instrumentation based profiling.
+class InstrProfStats {
+  uint32_t VisitedInMainFile;
+  uint32_t MissingInMainFile;
+  uint32_t Visited;
+  uint32_t Missing;
+  uint32_t Mismatched;
+
+public:
+  InstrProfStats()
+      : VisitedInMainFile(0), MissingInMainFile(0), Visited(0), Missing(0),
+        Mismatched(0) {}
+  /// Record that we've visited a function and whether or not that function was
+  /// in the main source file.
+  void addVisited(bool MainFile) {
+    if (MainFile)
+      ++VisitedInMainFile;
+    ++Visited;
+  }
+  /// Record that a function we've visited has no profile data.
+  void addMissing(bool MainFile) {
+    if (MainFile)
+      ++MissingInMainFile;
+    ++Missing;
+  }
+  /// Record that a function we've visited has mismatched profile data.
+  void addMismatched(bool MainFile) { ++Mismatched; }
+  /// Whether or not the stats we've gathered indicate any potential problems.
+  bool hasDiagnostics() { return Missing || Mismatched; }
+  /// Report potential problems we've found to \c Diags.
+  void reportDiagnostics(DiagnosticsEngine &Diags, StringRef MainFile);
+};
+
+/// This class organizes the cross-function state that is used while generating
+/// LLVM code.
 class CodeGenModule : public CodeGenTypeCache {
   CodeGenModule(const CodeGenModule &) LLVM_DELETED_FUNCTION;
   void operator=(const CodeGenModule &) LLVM_DELETED_FUNCTION;
 
-  typedef std::vector<std::pair<llvm::Constant*, int> > CtorList;
+  struct Structor {
+    Structor() : Priority(0), Initializer(nullptr), AssociatedData(nullptr) {}
+    Structor(int Priority, llvm::Constant *Initializer,
+             llvm::Constant *AssociatedData)
+        : Priority(Priority), Initializer(Initializer),
+          AssociatedData(AssociatedData) {}
+    int Priority;
+    llvm::Constant *Initializer;
+    llvm::Constant *AssociatedData;
+  };
+
+  typedef std::vector<Structor> CtorList;
 
   ASTContext &Context;
   const LangOptions &LangOpts;
@@ -236,7 +276,7 @@
   DiagnosticsEngine &Diags;
   const llvm::DataLayout &TheDataLayout;
   const TargetInfo &Target;
-  CGCXXABI &ABI;
+  std::unique_ptr<CGCXXABI> ABI;
   llvm::LLVMContext &VMContext;
 
   CodeGenTBAA *TBAA;
@@ -248,32 +288,42 @@
   // if TheTargetCodeGenInfo is NULL
   CodeGenTypes Types;
  
-  /// VTables - Holds information about C++ vtables.
+  /// Holds information about C++ vtables.
   CodeGenVTables VTables;
 
   CGObjCRuntime* ObjCRuntime;
   CGOpenCLRuntime* OpenCLRuntime;
+  CGOpenMPRuntime* OpenMPRuntime;
   CGCUDARuntime* CUDARuntime;
   CGDebugInfo* DebugInfo;
   ARCEntrypoints *ARCData;
   llvm::MDNode *NoObjCARCExceptionsMetadata;
   RREntrypoints *RRData;
+  std::unique_ptr<llvm::IndexedInstrProfReader> PGOReader;
+  InstrProfStats PGOStats;
 
-  // WeakRefReferences - A set of references that have only been seen via
-  // a weakref so far. This is used to remove the weak of the reference if we
-  // ever see a direct reference or a definition.
+  // A set of references that have only been seen via a weakref so far. This is
+  // used to remove the weak of the reference if we ever see a direct reference
+  // or a definition.
   llvm::SmallPtrSet<llvm::GlobalValue*, 10> WeakRefReferences;
 
-  /// DeferredDecls - This contains all the decls which have definitions but
-  /// which are deferred for emission and therefore should only be output if
-  /// they are actually used.  If a decl is in this, then it is known to have
-  /// not been referenced yet.
-  llvm::StringMap<GlobalDecl> DeferredDecls;
+  /// This contains all the decls which have definitions but/ which are deferred
+  /// for emission and therefore should only be output if they are actually
+  /// used. If a decl is in this, then it is known to have not been referenced
+  /// yet.
+  std::map<StringRef, GlobalDecl> DeferredDecls;
 
-  /// DeferredDeclsToEmit - This is a list of deferred decls which we have seen
-  /// that *are* actually referenced.  These get code generated when the module
-  /// is done.
-  std::vector<GlobalDecl> DeferredDeclsToEmit;
+  /// This is a list of deferred decls which we have seen that *are* actually
+  /// referenced. These get code generated when the module is done.
+  struct DeferredGlobal {
+    DeferredGlobal(llvm::GlobalValue *GV, GlobalDecl GD) : GV(GV), GD(GD) {}
+    llvm::AssertingVH<llvm::GlobalValue> GV;
+    GlobalDecl GD;
+  };
+  std::vector<DeferredGlobal> DeferredDeclsToEmit;
+  void addDeferredDeclToEmit(llvm::GlobalValue *GV, GlobalDecl GD) {
+    DeferredDeclsToEmit.push_back(DeferredGlobal(GV, GD));
+  }
 
   /// List of alias we have emitted. Used to make sure that what they point to
   /// is defined once we get to the end of the of the translation unit.
@@ -282,27 +332,27 @@
   typedef llvm::StringMap<llvm::TrackingVH<llvm::Constant> > ReplacementsTy;
   ReplacementsTy Replacements;
 
-  /// DeferredVTables - A queue of (optional) vtables to consider emitting.
+  /// A queue of (optional) vtables to consider emitting.
   std::vector<const CXXRecordDecl*> DeferredVTables;
 
-  /// LLVMUsed - List of global values which are required to be
-  /// present in the object file; bitcast to i8*. This is used for
-  /// forcing visibility of symbols which may otherwise be optimized
-  /// out.
+  /// List of global values which are required to be present in the object file;
+  /// bitcast to i8*. This is used for forcing visibility of symbols which may
+  /// otherwise be optimized out.
   std::vector<llvm::WeakVH> LLVMUsed;
+  std::vector<llvm::WeakVH> LLVMCompilerUsed;
 
-  /// GlobalCtors - Store the list of global constructors and their respective
-  /// priorities to be emitted when the translation unit is complete.
+  /// Store the list of global constructors and their respective priorities to
+  /// be emitted when the translation unit is complete.
   CtorList GlobalCtors;
 
-  /// GlobalDtors - Store the list of global destructors and their respective
-  /// priorities to be emitted when the translation unit is complete.
+  /// Store the list of global destructors and their respective priorities to be
+  /// emitted when the translation unit is complete.
   CtorList GlobalDtors;
 
-  /// MangledDeclNames - A map of canonical GlobalDecls to their mangled names.
-  llvm::DenseMap<GlobalDecl, StringRef> MangledDeclNames;
-  llvm::BumpPtrAllocator MangledNamesAllocator;
-  
+  /// An ordered map of canonical GlobalDecls to their mangled names.
+  llvm::MapVector<GlobalDecl, StringRef> MangledDeclNames;
+  llvm::StringMap<GlobalDecl, llvm::BumpPtrAllocator> Manglings;
+
   /// Global annotations.
   std::vector<llvm::Constant*> Annotations;
 
@@ -310,7 +360,8 @@
   llvm::StringMap<llvm::Constant*> AnnotationStrings;
 
   llvm::StringMap<llvm::Constant*> CFConstantStringMap;
-  llvm::StringMap<llvm::GlobalVariable*> ConstantStringMap;
+
+  llvm::DenseMap<llvm::Constant *, llvm::GlobalVariable *> ConstantStringMap;
   llvm::DenseMap<const Decl*, llvm::Constant *> StaticLocalDeclMap;
   llvm::DenseMap<const Decl*, llvm::GlobalVariable*> StaticLocalDeclGuardMap;
   llvm::DenseMap<const Expr*, llvm::Constant *> MaterializedGlobalTemporaryMap;
@@ -335,8 +386,7 @@
   /// before any thread_local variable in this TU is odr-used.
   std::vector<llvm::Constant*> CXXThreadLocalInits;
 
-  /// CXXGlobalInits - Global variables with initializers that need to run
-  /// before main.
+  /// Global variables with initializers that need to run before main.
   std::vector<llvm::Constant*> CXXGlobalInits;
 
   /// When a C++ decl with an initializer is deferred, null is
@@ -354,12 +404,11 @@
     }
   };
 
-  /// - Global variables with initializers whose order of initialization
-  /// is set by init_priority attribute.
+  /// Global variables with initializers whose order of initialization is set by
+  /// init_priority attribute.
   SmallVector<GlobalInitData, 8> PrioritizedCXXGlobalInits;
 
-  /// CXXGlobalDtors - Global destructor functions and arguments that need to
-  /// run on termination.
+  /// Global destructor functions and arguments that need to run on termination.
   std::vector<std::pair<llvm::WeakVH,llvm::Constant*> > CXXGlobalDtors;
 
   /// \brief The complete set of modules that has been imported.
@@ -371,12 +420,12 @@
   /// @name Cache for Objective-C runtime types
   /// @{
 
-  /// CFConstantStringClassRef - Cached reference to the class for constant
-  /// strings. This value has type int * but is actually an Obj-C class pointer.
+  /// Cached reference to the class for constant strings. This value has type
+  /// int * but is actually an Obj-C class pointer.
   llvm::WeakVH CFConstantStringClassRef;
 
-  /// ConstantStringClassRef - Cached reference to the class for constant
-  /// strings. This value has type int * but is actually an Obj-C class pointer.
+  /// Cached reference to the class for constant strings. This value has type
+  /// int * but is actually an Obj-C class pointer.
   llvm::WeakVH ConstantStringClassRef;
 
   /// \brief The LLVM type corresponding to NSConstantString.
@@ -392,6 +441,7 @@
   void createObjCRuntime();
 
   void createOpenCLRuntime();
+  void createOpenMPRuntime();
   void createCUDARuntime();
 
   bool isTriviallyRecursive(const FunctionDecl *F);
@@ -421,9 +471,7 @@
 
   GlobalDecl initializedGlobalDecl;
 
-  llvm::OwningPtr<llvm::SpecialCaseList> SanitizerBlacklist;
-
-  const SanitizerOptions &SanOpts;
+  SanitizerBlacklist SanitizerBL;
 
   /// @}
 public:
@@ -433,42 +481,51 @@
 
   ~CodeGenModule();
 
-  /// Release - Finalize LLVM code generation.
+  void clear();
+
+  /// Finalize LLVM code generation.
   void Release();
 
-  /// getObjCRuntime() - Return a reference to the configured
-  /// Objective-C runtime.
+  /// Return a reference to the configured Objective-C runtime.
   CGObjCRuntime &getObjCRuntime() {
     if (!ObjCRuntime) createObjCRuntime();
     return *ObjCRuntime;
   }
 
-  /// hasObjCRuntime() - Return true iff an Objective-C runtime has
-  /// been configured.
+  /// Return true iff an Objective-C runtime has been configured.
   bool hasObjCRuntime() { return !!ObjCRuntime; }
 
-  /// getOpenCLRuntime() - Return a reference to the configured OpenCL runtime.
+  /// Return a reference to the configured OpenCL runtime.
   CGOpenCLRuntime &getOpenCLRuntime() {
-    assert(OpenCLRuntime != 0);
+    assert(OpenCLRuntime != nullptr);
     return *OpenCLRuntime;
   }
 
-  /// getCUDARuntime() - Return a reference to the configured CUDA runtime.
+  /// Return a reference to the configured OpenMP runtime.
+  CGOpenMPRuntime &getOpenMPRuntime() {
+    assert(OpenMPRuntime != nullptr);
+    return *OpenMPRuntime;
+  }
+
+  /// Return a reference to the configured CUDA runtime.
   CGCUDARuntime &getCUDARuntime() {
-    assert(CUDARuntime != 0);
+    assert(CUDARuntime != nullptr);
     return *CUDARuntime;
   }
 
   ARCEntrypoints &getARCEntrypoints() const {
-    assert(getLangOpts().ObjCAutoRefCount && ARCData != 0);
+    assert(getLangOpts().ObjCAutoRefCount && ARCData != nullptr);
     return *ARCData;
   }
 
   RREntrypoints &getRREntrypoints() const {
-    assert(RRData != 0);
+    assert(RRData != nullptr);
     return *RRData;
   }
 
+  InstrProfStats &getPGOStats() { return PGOStats; }
+  llvm::IndexedInstrProfReader *getPGOReader() const { return PGOReader.get(); }
+
   llvm::Constant *getStaticLocalDeclAddress(const VarDecl *D) {
     return StaticLocalDeclMap[D];
   }
@@ -485,6 +542,9 @@
     StaticLocalDeclGuardMap[D] = C;
   }
 
+  bool lookupRepresentativeDecl(StringRef MangledName,
+                                GlobalDecl &Result) const;
+
   llvm::Constant *getAtomicSetterHelperFnMap(QualType Ty) {
     return AtomicSetterHelperFnMap[Ty];
   }
@@ -501,10 +561,10 @@
     AtomicGetterHelperFnMap[Ty] = Fn;
   }
 
-  llvm::Constant *getTypeDescriptor(QualType Ty) {
+  llvm::Constant *getTypeDescriptorFromMap(QualType Ty) {
     return TypeDescriptorMap[Ty];
   }
-  void setTypeDescriptor(QualType Ty, llvm::Constant *C) {
+  void setTypeDescriptorInMap(QualType Ty, llvm::Constant *C) {
     TypeDescriptorMap[Ty] = C;
   }
 
@@ -525,10 +585,10 @@
   DiagnosticsEngine &getDiags() const { return Diags; }
   const llvm::DataLayout &getDataLayout() const { return TheDataLayout; }
   const TargetInfo &getTarget() const { return Target; }
-  CGCXXABI &getCXXABI() { return ABI; }
+  CGCXXABI &getCXXABI() const { return *ABI; }
   llvm::LLVMContext &getLLVMContext() { return VMContext; }
-  
-  bool shouldUseTBAA() const { return TBAA != 0; }
+
+  bool shouldUseTBAA() const { return TBAA != nullptr; }
 
   const TargetCodeGenInfo &getTargetCodeGenInfo(); 
   
@@ -566,32 +626,16 @@
                            llvm::MDNode *TBAAInfo,
                            bool ConvertTypeToTag = true);
 
-  /// getSize - Emit the given number of characters as a value of type size_t.
+  /// Emit the given number of characters as a value of type size_t.
   llvm::ConstantInt *getSize(CharUnits numChars);
 
-  /// setGlobalVisibility - Set the visibility for the given LLVM
-  /// GlobalValue.
+  /// Set the visibility for the given LLVM GlobalValue.
   void setGlobalVisibility(llvm::GlobalValue *GV, const NamedDecl *D) const;
 
-  /// setTLSMode - Set the TLS mode for the given LLVM GlobalVariable
-  /// for the thread-local variable declaration D.
+  /// Set the TLS mode for the given LLVM GlobalVariable for the thread-local
+  /// variable declaration D.
   void setTLSMode(llvm::GlobalVariable *GV, const VarDecl &D) const;
 
-  /// TypeVisibilityKind - The kind of global variable that is passed to 
-  /// setTypeVisibility
-  enum TypeVisibilityKind {
-    TVK_ForVTT,
-    TVK_ForVTable,
-    TVK_ForConstructionVTable,
-    TVK_ForRTTI,
-    TVK_ForRTTIName
-  };
-
-  /// setTypeVisibility - Set the visibility for the given global
-  /// value which holds information about a type.
-  void setTypeVisibility(llvm::GlobalValue *GV, const CXXRecordDecl *D,
-                         TypeVisibilityKind TVK) const;
-
   static llvm::GlobalValue::VisibilityTypes GetLLVMVisibility(Visibility V) {
     switch (V) {
     case DefaultVisibility:   return llvm::GlobalValue::DefaultVisibility;
@@ -614,50 +658,47 @@
       return GetAddrOfGlobalVar(cast<VarDecl>(GD.getDecl()));
   }
 
-  /// CreateOrReplaceCXXRuntimeVariable - Will return a global variable of the
-  /// given type. If a variable with a different type already exists then a new 
-  /// variable with the right type will be created and all uses of the old
-  /// variable will be replaced with a bitcast to the new variable.
+  /// Will return a global variable of the given type. If a variable with a
+  /// different type already exists then a new  variable with the right type
+  /// will be created and all uses of the old variable will be replaced with a
+  /// bitcast to the new variable.
   llvm::GlobalVariable *
   CreateOrReplaceCXXRuntimeVariable(StringRef Name, llvm::Type *Ty,
                                     llvm::GlobalValue::LinkageTypes Linkage);
 
-  /// GetGlobalVarAddressSpace - Return the address space of the underlying
-  /// global variable for D, as determined by its declaration.  Normally this
-  /// is the same as the address space of D's type, but in CUDA, address spaces
-  /// are associated with declarations, not types.
+  /// Return the address space of the underlying global variable for D, as
+  /// determined by its declaration. Normally this is the same as the address
+  /// space of D's type, but in CUDA, address spaces are associated with
+  /// declarations, not types.
   unsigned GetGlobalVarAddressSpace(const VarDecl *D, unsigned AddrSpace);
 
-  /// GetAddrOfGlobalVar - Return the llvm::Constant for the address of the
-  /// given global variable.  If Ty is non-null and if the global doesn't exist,
-  /// then it will be greated with the specified type instead of whatever the
-  /// normal requested type would be.
+  /// Return the llvm::Constant for the address of the given global variable.
+  /// If Ty is non-null and if the global doesn't exist, then it will be greated
+  /// with the specified type instead of whatever the normal requested type
+  /// would be.
   llvm::Constant *GetAddrOfGlobalVar(const VarDecl *D,
-                                     llvm::Type *Ty = 0);
+                                     llvm::Type *Ty = nullptr);
 
+  /// Return the address of the given function. If Ty is non-null, then this
+  /// function will use the specified type if it has to create it.
+  llvm::Constant *GetAddrOfFunction(GlobalDecl GD, llvm::Type *Ty = 0,
+                                    bool ForVTable = false,
+                                    bool DontDefer = false);
 
-  /// GetAddrOfFunction - Return the address of the given function.  If Ty is
-  /// non-null, then this function will use the specified type if it has to
-  /// create it.
-  llvm::Constant *GetAddrOfFunction(GlobalDecl GD,
-                                    llvm::Type *Ty = 0,
-                                    bool ForVTable = false);
-
-  /// GetAddrOfRTTIDescriptor - Get the address of the RTTI descriptor 
-  /// for the given type.
+  /// Get the address of the RTTI descriptor for the given type.
   llvm::Constant *GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH = false);
 
-  /// GetAddrOfUuidDescriptor - Get the address of a uuid descriptor .
+  /// Get the address of a uuid descriptor .
   llvm::Constant *GetAddrOfUuidDescriptor(const CXXUuidofExpr* E);
 
-  /// GetAddrOfThunk - Get the address of the thunk for the given global decl.
+  /// Get the address of the thunk for the given global decl.
   llvm::Constant *GetAddrOfThunk(GlobalDecl GD, const ThunkInfo &Thunk);
 
-  /// GetWeakRefReference - Get a reference to the target of VD.
+  /// Get a reference to the target of VD.
   llvm::Constant *GetWeakRefReference(const ValueDecl *VD);
 
-  /// GetNonVirtualBaseClassOffset - Returns the offset from a derived class to 
-  /// a class. Returns null if the offset is 0. 
+  /// Returns the offset from a derived class to  a class. Returns null if the
+  /// offset is 0.
   llvm::Constant *
   GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl,
                                CastExpr::path_const_iterator PathBegin,
@@ -693,67 +734,49 @@
 
   llvm::FoldingSet<ByrefHelpers> ByrefHelpersCache;
 
-  /// getUniqueBlockCount - Fetches the global unique block count.
+  /// Fetches the global unique block count.
   int getUniqueBlockCount() { return ++Block.GlobalUniqueCount; }
   
-  /// getBlockDescriptorType - Fetches the type of a generic block
-  /// descriptor.
+  /// Fetches the type of a generic block descriptor.
   llvm::Type *getBlockDescriptorType();
 
-  /// getGenericBlockLiteralType - The type of a generic block literal.
+  /// The type of a generic block literal.
   llvm::Type *getGenericBlockLiteralType();
 
-  /// GetAddrOfGlobalBlock - Gets the address of a block which
-  /// requires no captures.
+  /// Gets the address of a block which requires no captures.
   llvm::Constant *GetAddrOfGlobalBlock(const BlockExpr *BE, const char *);
   
-  /// GetAddrOfConstantCFString - Return a pointer to a constant CFString object
-  /// for the given string.
+  /// Return a pointer to a constant CFString object for the given string.
   llvm::Constant *GetAddrOfConstantCFString(const StringLiteral *Literal);
-  
-  /// GetAddrOfConstantString - Return a pointer to a constant NSString object
-  /// for the given string. Or a user defined String object as defined via
+
+  /// Return a pointer to a constant NSString object for the given string. Or a
+  /// user defined String object as defined via
   /// -fconstant-string-class=class_name option.
   llvm::Constant *GetAddrOfConstantString(const StringLiteral *Literal);
 
-  /// GetConstantArrayFromStringLiteral - Return a constant array for the given
-  /// string.
+  /// Return a constant array for the given string.
   llvm::Constant *GetConstantArrayFromStringLiteral(const StringLiteral *E);
 
-  /// GetAddrOfConstantStringFromLiteral - Return a pointer to a constant array
-  /// for the given string literal.
-  llvm::Constant *GetAddrOfConstantStringFromLiteral(const StringLiteral *S);
+  /// Return a pointer to a constant array for the given string literal.
+  llvm::GlobalVariable *
+  GetAddrOfConstantStringFromLiteral(const StringLiteral *S);
 
-  /// GetAddrOfConstantStringFromObjCEncode - Return a pointer to a constant
-  /// array for the given ObjCEncodeExpr node.
-  llvm::Constant *GetAddrOfConstantStringFromObjCEncode(const ObjCEncodeExpr *);
+  /// Return a pointer to a constant array for the given ObjCEncodeExpr node.
+  llvm::GlobalVariable *
+  GetAddrOfConstantStringFromObjCEncode(const ObjCEncodeExpr *);
 
-  /// GetAddrOfConstantString - Returns a pointer to a character array
-  /// containing the literal. This contents are exactly that of the given
-  /// string, i.e. it will not be null terminated automatically; see
-  /// GetAddrOfConstantCString. Note that whether the result is actually a
-  /// pointer to an LLVM constant depends on Feature.WriteableStrings.
-  ///
-  /// The result has pointer to array type.
-  ///
-  /// \param GlobalName If provided, the name to use for the global
-  /// (if one is created).
-  llvm::Constant *GetAddrOfConstantString(StringRef Str,
-                                          const char *GlobalName=0,
-                                          unsigned Alignment=0);
-
-  /// GetAddrOfConstantCString - Returns a pointer to a character array
-  /// containing the literal and a terminating '\0' character. The result has
-  /// pointer to array type.
+  /// Returns a pointer to a character array containing the literal and a
+  /// terminating '\0' character. The result has pointer to array type.
   ///
   /// \param GlobalName If provided, the name to use for the global (if one is
   /// created).
-  llvm::Constant *GetAddrOfConstantCString(const std::string &str,
-                                           const char *GlobalName=0,
-                                           unsigned Alignment=0);
+  llvm::GlobalVariable *
+  GetAddrOfConstantCString(const std::string &Str,
+                           const char *GlobalName = nullptr,
+                           unsigned Alignment = 0);
 
-  /// GetAddrOfConstantCompoundLiteral - Returns a pointer to a constant global
-  /// variable for the given file-scope compound literal expression.
+  /// Returns a pointer to a constant global variable for the given file-scope
+  /// compound literal expression.
   llvm::Constant *GetAddrOfConstantCompoundLiteral(const CompoundLiteralExpr*E);
 
   /// \brief Returns a pointer to a global variable representing a temporary
@@ -765,31 +788,31 @@
   /// Objective-C fast enumeration loop (for..in).
   QualType getObjCFastEnumerationStateType();
   
-  /// GetAddrOfCXXConstructor - Return the address of the constructor of the
-  /// given type.
-  llvm::GlobalValue *GetAddrOfCXXConstructor(const CXXConstructorDecl *ctor,
-                                             CXXCtorType ctorType,
-                                             const CGFunctionInfo *fnInfo = 0);
+  /// Return the address of the constructor of the given type.
+  llvm::GlobalValue *
+  GetAddrOfCXXConstructor(const CXXConstructorDecl *ctor, CXXCtorType ctorType,
+                          const CGFunctionInfo *fnInfo = nullptr,
+                          bool DontDefer = false);
 
-  /// GetAddrOfCXXDestructor - Return the address of the constructor of the
-  /// given type.
-  llvm::GlobalValue *GetAddrOfCXXDestructor(const CXXDestructorDecl *dtor,
-                                            CXXDtorType dtorType,
-                                            const CGFunctionInfo *fnInfo = 0,
-                                            llvm::FunctionType *fnType = 0);
+  /// Return the address of the constructor of the given type.
+  llvm::GlobalValue *
+  GetAddrOfCXXDestructor(const CXXDestructorDecl *dtor,
+                         CXXDtorType dtorType,
+                         const CGFunctionInfo *fnInfo = nullptr,
+                         llvm::FunctionType *fnType = nullptr,
+                         bool DontDefer = false);
 
-  /// getBuiltinLibFunction - Given a builtin id for a function like
-  /// "__builtin_fabsf", return a Function* for "fabsf".
+  /// Given a builtin id for a function like "__builtin_fabsf", return a
+  /// Function* for "fabsf".
   llvm::Value *getBuiltinLibFunction(const FunctionDecl *FD,
                                      unsigned BuiltinID);
 
   llvm::Function *getIntrinsic(unsigned IID, ArrayRef<llvm::Type*> Tys = None);
 
-  /// EmitTopLevelDecl - Emit code for a single top level declaration.
+  /// Emit code for a single top level declaration.
   void EmitTopLevelDecl(Decl *D);
 
-  /// HandleCXXStaticMemberVarInstantiation - Tell the consumer that this
-  // variable has been instantiated.
+  /// Tell the consumer that this variable has been instantiated.
   void HandleCXXStaticMemberVarInstantiation(VarDecl *VD);
 
   /// \brief If the declaration has internal linkage but is inside an
@@ -798,25 +821,23 @@
   template<typename SomeDecl>
   void MaybeHandleStaticInExternC(const SomeDecl *D, llvm::GlobalValue *GV);
 
-  /// AddUsedGlobal - Add a global which should be forced to be
-  /// present in the object file; these are emitted to the llvm.used
-  /// metadata global.
-  void AddUsedGlobal(llvm::GlobalValue *GV);
+  /// Add a global to a list to be added to the llvm.used metadata.
+  void addUsedGlobal(llvm::GlobalValue *GV);
 
-  /// AddCXXDtorEntry - Add a destructor and object to add to the C++ global
-  /// destructor function.
+  /// Add a global to a list to be added to the llvm.compiler.used metadata.
+  void addCompilerUsedGlobal(llvm::GlobalValue *GV);
+
+  /// Add a destructor and object to add to the C++ global destructor function.
   void AddCXXDtorEntry(llvm::Constant *DtorFn, llvm::Constant *Object) {
     CXXGlobalDtors.push_back(std::make_pair(DtorFn, Object));
   }
 
-  /// CreateRuntimeFunction - Create a new runtime function with the specified
-  /// type and name.
+  /// Create a new runtime function with the specified type and name.
   llvm::Constant *CreateRuntimeFunction(llvm::FunctionType *Ty,
                                         StringRef Name,
                                         llvm::AttributeSet ExtraAttrs =
                                           llvm::AttributeSet());
-  /// CreateRuntimeVariable - Create a new runtime global variable with the
-  /// specified type and name.
+  /// Create a new runtime global variable with the specified type and name.
   llvm::Constant *CreateRuntimeVariable(llvm::Type *Ty,
                                         StringRef Name);
 
@@ -833,85 +854,80 @@
   llvm::Constant *getLLVMLifetimeStartFn();
   llvm::Constant *getLLVMLifetimeEndFn();
 
-  // UpdateCompleteType - Make sure that this type is translated.
+  // Make sure that this type is translated.
   void UpdateCompletedType(const TagDecl *TD);
 
   llvm::Constant *getMemberPointerConstant(const UnaryOperator *e);
 
-  /// EmitConstantInit - Try to emit the initializer for the given declaration
-  /// as a constant; returns 0 if the expression cannot be emitted as a
-  /// constant.
-  llvm::Constant *EmitConstantInit(const VarDecl &D, CodeGenFunction *CGF = 0);
+  /// Try to emit the initializer for the given declaration as a constant;
+  /// returns 0 if the expression cannot be emitted as a constant.
+  llvm::Constant *EmitConstantInit(const VarDecl &D,
+                                   CodeGenFunction *CGF = nullptr);
 
-  /// EmitConstantExpr - Try to emit the given expression as a
-  /// constant; returns 0 if the expression cannot be emitted as a
-  /// constant.
+  /// Try to emit the given expression as a constant; returns 0 if the
+  /// expression cannot be emitted as a constant.
   llvm::Constant *EmitConstantExpr(const Expr *E, QualType DestType,
-                                   CodeGenFunction *CGF = 0);
+                                   CodeGenFunction *CGF = nullptr);
 
-  /// EmitConstantValue - Emit the given constant value as a constant, in the
-  /// type's scalar representation.
+  /// Emit the given constant value as a constant, in the type's scalar
+  /// representation.
   llvm::Constant *EmitConstantValue(const APValue &Value, QualType DestType,
-                                    CodeGenFunction *CGF = 0);
+                                    CodeGenFunction *CGF = nullptr);
 
-  /// EmitConstantValueForMemory - Emit the given constant value as a constant,
-  /// in the type's memory representation.
+  /// Emit the given constant value as a constant, in the type's memory
+  /// representation.
   llvm::Constant *EmitConstantValueForMemory(const APValue &Value,
                                              QualType DestType,
-                                             CodeGenFunction *CGF = 0);
+                                             CodeGenFunction *CGF = nullptr);
 
-  /// EmitNullConstant - Return the result of value-initializing the given
-  /// type, i.e. a null expression of the given type.  This is usually,
-  /// but not always, an LLVM null constant.
+  /// Return the result of value-initializing the given type, i.e. a null
+  /// expression of the given type.  This is usually, but not always, an LLVM
+  /// null constant.
   llvm::Constant *EmitNullConstant(QualType T);
 
-  /// EmitNullConstantForBase - Return a null constant appropriate for 
-  /// zero-initializing a base class with the given type.  This is usually,
-  /// but not always, an LLVM null constant.
+  /// Return a null constant appropriate for zero-initializing a base class with
+  /// the given type. This is usually, but not always, an LLVM null constant.
   llvm::Constant *EmitNullConstantForBase(const CXXRecordDecl *Record);
 
-  /// Error - Emit a general error that something can't be done.
+  /// Emit a general error that something can't be done.
   void Error(SourceLocation loc, StringRef error);
 
-  /// ErrorUnsupported - Print out an error that codegen doesn't support the
-  /// specified stmt yet.
+  /// Print out an error that codegen doesn't support the specified stmt yet.
   void ErrorUnsupported(const Stmt *S, const char *Type);
 
-  /// ErrorUnsupported - Print out an error that codegen doesn't support the
-  /// specified decl yet.
+  /// Print out an error that codegen doesn't support the specified decl yet.
   void ErrorUnsupported(const Decl *D, const char *Type);
 
-  /// SetInternalFunctionAttributes - Set the attributes on the LLVM
-  /// function for the given decl and function info. This applies
-  /// attributes necessary for handling the ABI as well as user
-  /// specified attributes like section.
+  /// Set the attributes on the LLVM function for the given decl and function
+  /// info. This applies attributes necessary for handling the ABI as well as
+  /// user specified attributes like section.
   void SetInternalFunctionAttributes(const Decl *D, llvm::Function *F,
                                      const CGFunctionInfo &FI);
 
-  /// SetLLVMFunctionAttributes - Set the LLVM function attributes
-  /// (sext, zext, etc).
+  /// Set the LLVM function attributes (sext, zext, etc).
   void SetLLVMFunctionAttributes(const Decl *D,
                                  const CGFunctionInfo &Info,
                                  llvm::Function *F);
 
-  /// SetLLVMFunctionAttributesForDefinition - Set the LLVM function attributes
-  /// which only apply to a function definintion.
+  /// Set the LLVM function attributes which only apply to a function
+  /// definintion.
   void SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F);
 
-  /// ReturnTypeUsesSRet - Return true iff the given type uses 'sret' when used
-  /// as a return type.
+  /// Return true iff the given type uses 'sret' when used as a return type.
   bool ReturnTypeUsesSRet(const CGFunctionInfo &FI);
 
-  /// ReturnTypeUsesFPRet - Return true iff the given type uses 'fpret' when
-  /// used as a return type.
+  /// Return true iff the given type uses an argument slot when 'sret' is used
+  /// as a return type.
+  bool ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI);
+
+  /// Return true iff the given type uses 'fpret' when used as a return type.
   bool ReturnTypeUsesFPRet(QualType ResultType);
 
-  /// ReturnTypeUsesFP2Ret - Return true iff the given type uses 'fp2ret' when
-  /// used as a return type.
+  /// Return true iff the given type uses 'fp2ret' when used as a return type.
   bool ReturnTypeUsesFP2Ret(QualType ResultType);
 
-  /// ConstructAttributeList - Get the LLVM attributes and calling convention to
-  /// use for a particular function type.
+  /// Get the LLVM attributes and calling convention to use for a particular
+  /// function type.
   ///
   /// \param Info - The function type information.
   /// \param TargetDecl - The decl these attributes are being constructed
@@ -926,15 +942,13 @@
                               bool AttrOnCallSite);
 
   StringRef getMangledName(GlobalDecl GD);
-  void getBlockMangledName(GlobalDecl GD, MangleBuffer &Buffer,
-                           const BlockDecl *BD);
+  StringRef getBlockMangledName(GlobalDecl GD, const BlockDecl *BD);
 
   void EmitTentativeDefinition(const VarDecl *D);
 
   void EmitVTable(CXXRecordDecl *Class, bool DefinitionRequired);
 
-  /// EmitFundamentalRTTIDescriptors - Emit the RTTI descriptors for the
-  /// builtin types.
+  /// Emit the RTTI descriptors for the builtin types.
   void EmitFundamentalRTTIDescriptors();
 
   /// \brief Appends Opts to the "Linker Options" metadata value.
@@ -948,23 +962,26 @@
 
   llvm::GlobalVariable::LinkageTypes getFunctionLinkage(GlobalDecl GD);
 
-  void setFunctionLinkage(GlobalDecl GD, llvm::GlobalValue *V) {
-    V->setLinkage(getFunctionLinkage(GD));
+  void setFunctionLinkage(GlobalDecl GD, llvm::Function *F) {
+    F->setLinkage(getFunctionLinkage(GD));
   }
 
-  /// getVTableLinkage - Return the appropriate linkage for the vtable, VTT,
-  /// and type information of the given class.
+  /// Return the appropriate linkage for the vtable, VTT, and type information
+  /// of the given class.
   llvm::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD);
 
-  /// GetTargetTypeStoreSize - Return the store size, in character units, of
-  /// the given LLVM type.
+  /// Return the store size, in character units, of the given LLVM type.
   CharUnits GetTargetTypeStoreSize(llvm::Type *Ty) const;
   
-  /// GetLLVMLinkageVarDefinition - Returns LLVM linkage for a global 
-  /// variable.
-  llvm::GlobalValue::LinkageTypes 
-  GetLLVMLinkageVarDefinition(const VarDecl *D, bool isConstant);
-  
+  /// Returns LLVM linkage for a declarator.
+  llvm::GlobalValue::LinkageTypes
+  getLLVMLinkageForDeclarator(const DeclaratorDecl *D, GVALinkage Linkage,
+                              bool IsConstantVariable);
+
+  /// Returns LLVM linkage for a declarator.
+  llvm::GlobalValue::LinkageTypes
+  getLLVMLinkageVarDefinition(const VarDecl *VD, bool IsConstant);
+
   /// Emit all the global annotations.
   void EmitGlobalAnnotations();
 
@@ -977,8 +994,8 @@
   /// Emit the annotation line number.
   llvm::Constant *EmitAnnotationLineNo(SourceLocation L);
 
-  /// EmitAnnotateAttr - Generate the llvm::ConstantStruct which contains the
-  /// annotation information for a given GlobalValue. The annotation struct is
+  /// Generate the llvm::ConstantStruct which contains the annotation
+  /// information for a given GlobalValue. The annotation struct is
   /// {i8 *, i8 *, i8 *, i32}. The first field is a constant expression, the
   /// GlobalValue being annotated. The second field is the constant string
   /// created from the AnnotateAttr's annotation. The third field is a constant
@@ -992,54 +1009,59 @@
   /// annotations are emitted during finalization of the LLVM code.
   void AddGlobalAnnotations(const ValueDecl *D, llvm::GlobalValue *GV);
 
-  const llvm::SpecialCaseList &getSanitizerBlacklist() const {
-    return *SanitizerBlacklist;
+  const SanitizerBlacklist &getSanitizerBlacklist() const {
+    return SanitizerBL;
   }
 
-  const SanitizerOptions &getSanOpts() const { return SanOpts; }
+  void reportGlobalToASan(llvm::GlobalVariable *GV, const VarDecl &D,
+                          bool IsDynInit = false);
+  void reportGlobalToASan(llvm::GlobalVariable *GV, SourceLocation Loc,
+                          StringRef Name, bool IsDynInit = false,
+                          bool IsBlacklisted = false);
+
+  /// Disable sanitizer instrumentation for this global.
+  void disableSanitizerForGlobal(llvm::GlobalVariable *GV);
 
   void addDeferredVTable(const CXXRecordDecl *RD) {
     DeferredVTables.push_back(RD);
   }
 
-  /// EmitGlobal - Emit code for a singal global function or var decl. Forward
-  /// declarations are emitted lazily.
+  /// Emit code for a singal global function or var decl. Forward declarations
+  /// are emitted lazily.
   void EmitGlobal(GlobalDecl D);
 
 private:
   llvm::GlobalValue *GetGlobalValue(StringRef Ref);
 
-  llvm::Constant *GetOrCreateLLVMFunction(StringRef MangledName,
-                                          llvm::Type *Ty,
-                                          GlobalDecl D,
-                                          bool ForVTable,
-                                          llvm::AttributeSet ExtraAttrs =
-                                            llvm::AttributeSet());
+  llvm::Constant *
+  GetOrCreateLLVMFunction(StringRef MangledName, llvm::Type *Ty, GlobalDecl D,
+                          bool ForVTable, bool DontDefer = false,
+                          llvm::AttributeSet ExtraAttrs = llvm::AttributeSet());
+
   llvm::Constant *GetOrCreateLLVMGlobal(StringRef MangledName,
                                         llvm::PointerType *PTy,
-                                        const VarDecl *D,
-                                        bool UnnamedAddr = false);
+                                        const VarDecl *D);
 
-  /// SetCommonAttributes - Set attributes which are common to any
-  /// form of a global definition (alias, Objective-C method,
-  /// function, global variable).
+  /// Set attributes which are common to any form of a global definition (alias,
+  /// Objective-C method, function, global variable).
   ///
   /// NOTE: This should only be called for definitions.
   void SetCommonAttributes(const Decl *D, llvm::GlobalValue *GV);
 
-  /// SetFunctionDefinitionAttributes - Set attributes for a global definition.
-  void SetFunctionDefinitionAttributes(const FunctionDecl *D,
-                                       llvm::GlobalValue *GV);
+  void setNonAliasAttributes(const Decl *D, llvm::GlobalObject *GO);
 
-  /// SetFunctionAttributes - Set function attributes for a function
-  /// declaration.
+  /// Set attributes for a global definition.
+  void setFunctionDefinitionAttributes(const FunctionDecl *D,
+                                       llvm::Function *F);
+
+  /// Set function attributes for a function declaration.
   void SetFunctionAttributes(GlobalDecl GD,
                              llvm::Function *F,
                              bool IsIncompleteFunction);
 
-  void EmitGlobalDefinition(GlobalDecl D);
+  void EmitGlobalDefinition(GlobalDecl D, llvm::GlobalValue *GV = nullptr);
 
-  void EmitGlobalFunctionDefinition(GlobalDecl GD);
+  void EmitGlobalFunctionDefinition(GlobalDecl GD, llvm::GlobalValue *GV);
   void EmitGlobalVarDefinition(const VarDecl *D);
   void EmitAliasDefinition(GlobalDecl GD);
   void EmitObjCPropertyImplementations(const ObjCImplementationDecl *D);
@@ -1055,44 +1077,44 @@
   void EmitLinkageSpec(const LinkageSpecDecl *D);
   void CompleteDIClassType(const CXXMethodDecl* D);
 
-  /// EmitCXXConstructor - Emit a single constructor with the given type from
-  /// a C++ constructor Decl.
+  /// Emit a single constructor with the given type from a C++ constructor Decl.
   void EmitCXXConstructor(const CXXConstructorDecl *D, CXXCtorType Type);
 
-  /// EmitCXXDestructor - Emit a single destructor with the given type from
-  /// a C++ destructor Decl.
+  /// Emit a single destructor with the given type from a C++ destructor Decl.
   void EmitCXXDestructor(const CXXDestructorDecl *D, CXXDtorType Type);
 
   /// \brief Emit the function that initializes C++ thread_local variables.
   void EmitCXXThreadLocalInitFunc();
 
-  /// EmitCXXGlobalInitFunc - Emit the function that initializes C++ globals.
+  /// Emit the function that initializes C++ globals.
   void EmitCXXGlobalInitFunc();
 
-  /// EmitCXXGlobalDtorFunc - Emit the function that destroys C++ globals.
+  /// Emit the function that destroys C++ globals.
   void EmitCXXGlobalDtorFunc();
 
-  /// EmitCXXGlobalVarDeclInitFunc - Emit the function that initializes the
-  /// specified global (if PerformInit is true) and registers its destructor.
+  /// Emit the function that initializes the specified global (if PerformInit is
+  /// true) and registers its destructor.
   void EmitCXXGlobalVarDeclInitFunc(const VarDecl *D,
                                     llvm::GlobalVariable *Addr,
                                     bool PerformInit);
 
-  // FIXME: Hardcoding priority here is gross.
-  void AddGlobalCtor(llvm::Function *Ctor, int Priority=65535);
-  void AddGlobalDtor(llvm::Function *Dtor, int Priority=65535);
+  void EmitPointerToInitFunc(const VarDecl *VD, llvm::GlobalVariable *Addr,
+                             llvm::Function *InitFunc, InitSegAttr *ISA);
 
-  /// EmitCtorList - Generates a global array of functions and priorities using
-  /// the given list and name. This array will have appending linkage and is
-  /// suitable for use as a LLVM constructor or destructor array.
+  // FIXME: Hardcoding priority here is gross.
+  void AddGlobalCtor(llvm::Function *Ctor, int Priority = 65535,
+                     llvm::Constant *AssociatedData = 0);
+  void AddGlobalDtor(llvm::Function *Dtor, int Priority = 65535);
+
+  /// Generates a global array of functions and priorities using the given list
+  /// and name. This array will have appending linkage and is suitable for use
+  /// as a LLVM constructor or destructor array.
   void EmitCtorList(const CtorList &Fns, const char *GlobalName);
 
-  /// EmitFundamentalRTTIDescriptor - Emit the RTTI descriptors for the
-  /// given type.
+  /// Emit the RTTI descriptors for the given type.
   void EmitFundamentalRTTIDescriptor(QualType Type);
 
-  /// EmitDeferred - Emit any needed decls for which code generation
-  /// was deferred.
+  /// Emit any needed decls for which code generation was deferred.
   void EmitDeferred();
 
   /// Call replaceAllUsesWith on all pairs in Replacements.
@@ -1100,13 +1122,11 @@
 
   void checkAliases();
 
-  /// EmitDeferredVTables - Emit any vtables which we deferred and
-  /// still have a use for.
+  /// Emit any vtables which we deferred and still have a use for.
   void EmitDeferredVTables();
 
-  /// EmitLLVMUsed - Emit the llvm.used metadata used to force
-  /// references to global which may otherwise be optimized out.
-  void EmitLLVMUsed();
+  /// Emit the llvm.used and llvm.compiler.used metadata.
+  void emitLLVMUsed();
 
   /// \brief Emit the link options introduced by imported modules.
   void EmitModuleLinkOptions();
@@ -1120,20 +1140,22 @@
   /// \brief Emit the Clang version as llvm.ident metadata.
   void EmitVersionIdentMetadata();
 
-  /// EmitCoverageFile - Emit the llvm.gcov metadata used to tell LLVM where
-  /// to emit the .gcno and .gcda files in a way that persists in .bc files.
+  /// Emits target specific Metadata for global declarations.
+  void EmitTargetMetadata();
+
+  /// Emit the llvm.gcov metadata used to tell LLVM where to emit the .gcno and
+  /// .gcda files in a way that persists in .bc files.
   void EmitCoverageFile();
 
   /// Emits the initializer for a uuidof string.
   llvm::Constant *EmitUuidofInitializer(StringRef uuidstr, QualType IIDType);
 
-  /// MayDeferGeneration - Determine if the given decl can be emitted
-  /// lazily; this is only relevant for definitions. The given decl
-  /// must be either a function or var decl.
+  /// Determine if the given decl can be emitted lazily; this is only relevant
+  /// for definitions. The given decl must be either a function or var decl.
   bool MayDeferGeneration(const ValueDecl *D);
 
-  /// SimplifyPersonality - Check whether we can use a "simpler", more
-  /// core exceptions personality function.
+  /// Check whether we can use a "simpler", more core exceptions personality
+  /// function.
   void SimplifyPersonality();
 };
 }  // end namespace CodeGen
diff --git a/lib/CodeGen/CodeGenPGO.cpp b/lib/CodeGen/CodeGenPGO.cpp
new file mode 100644
index 0000000..b233e3c
--- /dev/null
+++ b/lib/CodeGen/CodeGenPGO.cpp
@@ -0,0 +1,1011 @@
+//===--- CodeGenPGO.cpp - PGO Instrumentation for LLVM CodeGen --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Instrumentation-based profile-guided optimization
+//
+//===----------------------------------------------------------------------===//
+
+#include "CodeGenPGO.h"
+#include "CodeGenFunction.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/StmtVisitor.h"
+#include "llvm/IR/MDBuilder.h"
+#include "llvm/ProfileData/InstrProfReader.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MD5.h"
+
+using namespace clang;
+using namespace CodeGen;
+
+void CodeGenPGO::setFuncName(llvm::Function *Fn) {
+  RawFuncName = Fn->getName();
+
+  // Function names may be prefixed with a binary '1' to indicate
+  // that the backend should not modify the symbols due to any platform
+  // naming convention. Do not include that '1' in the PGO profile name.
+  if (RawFuncName[0] == '\1')
+    RawFuncName = RawFuncName.substr(1);
+
+  if (!Fn->hasLocalLinkage()) {
+    PrefixedFuncName.reset(new std::string(RawFuncName));
+    return;
+  }
+
+  // For local symbols, prepend the main file name to distinguish them.
+  // Do not include the full path in the file name since there's no guarantee
+  // that it will stay the same, e.g., if the files are checked out from
+  // version control in different locations.
+  PrefixedFuncName.reset(new std::string(CGM.getCodeGenOpts().MainFileName));
+  if (PrefixedFuncName->empty())
+    PrefixedFuncName->assign("<unknown>");
+  PrefixedFuncName->append(":");
+  PrefixedFuncName->append(RawFuncName);
+}
+
+static llvm::Function *getRegisterFunc(CodeGenModule &CGM) {
+  return CGM.getModule().getFunction("__llvm_profile_register_functions");
+}
+
+static llvm::BasicBlock *getOrInsertRegisterBB(CodeGenModule &CGM) {
+  // Don't do this for Darwin.  compiler-rt uses linker magic.
+  if (CGM.getTarget().getTriple().isOSDarwin())
+    return nullptr;
+
+  // Only need to insert this once per module.
+  if (llvm::Function *RegisterF = getRegisterFunc(CGM))
+    return &RegisterF->getEntryBlock();
+
+  // Construct the function.
+  auto *VoidTy = llvm::Type::getVoidTy(CGM.getLLVMContext());
+  auto *RegisterFTy = llvm::FunctionType::get(VoidTy, false);
+  auto *RegisterF = llvm::Function::Create(RegisterFTy,
+                                           llvm::GlobalValue::InternalLinkage,
+                                           "__llvm_profile_register_functions",
+                                           &CGM.getModule());
+  RegisterF->setUnnamedAddr(true);
+  if (CGM.getCodeGenOpts().DisableRedZone)
+    RegisterF->addFnAttr(llvm::Attribute::NoRedZone);
+
+  // Construct and return the entry block.
+  auto *BB = llvm::BasicBlock::Create(CGM.getLLVMContext(), "", RegisterF);
+  CGBuilderTy Builder(BB);
+  Builder.CreateRetVoid();
+  return BB;
+}
+
+static llvm::Constant *getOrInsertRuntimeRegister(CodeGenModule &CGM) {
+  auto *VoidTy = llvm::Type::getVoidTy(CGM.getLLVMContext());
+  auto *VoidPtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
+  auto *RuntimeRegisterTy = llvm::FunctionType::get(VoidTy, VoidPtrTy, false);
+  return CGM.getModule().getOrInsertFunction("__llvm_profile_register_function",
+                                             RuntimeRegisterTy);
+}
+
+static bool isMachO(const CodeGenModule &CGM) {
+  return CGM.getTarget().getTriple().isOSBinFormatMachO();
+}
+
+static StringRef getCountersSection(const CodeGenModule &CGM) {
+  return isMachO(CGM) ? "__DATA,__llvm_prf_cnts" : "__llvm_prf_cnts";
+}
+
+static StringRef getNameSection(const CodeGenModule &CGM) {
+  return isMachO(CGM) ? "__DATA,__llvm_prf_names" : "__llvm_prf_names";
+}
+
+static StringRef getDataSection(const CodeGenModule &CGM) {
+  return isMachO(CGM) ? "__DATA,__llvm_prf_data" : "__llvm_prf_data";
+}
+
+llvm::GlobalVariable *CodeGenPGO::buildDataVar() {
+  // Create name variable.
+  llvm::LLVMContext &Ctx = CGM.getLLVMContext();
+  auto *VarName = llvm::ConstantDataArray::getString(Ctx, getFuncName(),
+                                                     false);
+  auto *Name = new llvm::GlobalVariable(CGM.getModule(), VarName->getType(),
+                                        true, VarLinkage, VarName,
+                                        getFuncVarName("name"));
+  Name->setSection(getNameSection(CGM));
+  Name->setAlignment(1);
+
+  // Create data variable.
+  auto *Int32Ty = llvm::Type::getInt32Ty(Ctx);
+  auto *Int64Ty = llvm::Type::getInt64Ty(Ctx);
+  auto *Int8PtrTy = llvm::Type::getInt8PtrTy(Ctx);
+  auto *Int64PtrTy = llvm::Type::getInt64PtrTy(Ctx);
+  llvm::Type *DataTypes[] = {
+    Int32Ty, Int32Ty, Int64Ty, Int8PtrTy, Int64PtrTy
+  };
+  auto *DataTy = llvm::StructType::get(Ctx, makeArrayRef(DataTypes));
+  llvm::Constant *DataVals[] = {
+    llvm::ConstantInt::get(Int32Ty, getFuncName().size()),
+    llvm::ConstantInt::get(Int32Ty, NumRegionCounters),
+    llvm::ConstantInt::get(Int64Ty, FunctionHash),
+    llvm::ConstantExpr::getBitCast(Name, Int8PtrTy),
+    llvm::ConstantExpr::getBitCast(RegionCounters, Int64PtrTy)
+  };
+  auto *Data =
+    new llvm::GlobalVariable(CGM.getModule(), DataTy, true, VarLinkage,
+                             llvm::ConstantStruct::get(DataTy, DataVals),
+                             getFuncVarName("data"));
+
+  // All the data should be packed into an array in its own section.
+  Data->setSection(getDataSection(CGM));
+  Data->setAlignment(8);
+
+  // Hide all these symbols so that we correctly get a copy for each
+  // executable.  The profile format expects names and counters to be
+  // contiguous, so references into shared objects would be invalid.
+  if (!llvm::GlobalValue::isLocalLinkage(VarLinkage)) {
+    Name->setVisibility(llvm::GlobalValue::HiddenVisibility);
+    Data->setVisibility(llvm::GlobalValue::HiddenVisibility);
+    RegionCounters->setVisibility(llvm::GlobalValue::HiddenVisibility);
+  }
+
+  // Make sure the data doesn't get deleted.
+  CGM.addUsedGlobal(Data);
+  return Data;
+}
+
+void CodeGenPGO::emitInstrumentationData() {
+  if (!RegionCounters)
+    return;
+
+  // Build the data.
+  auto *Data = buildDataVar();
+
+  // Register the data.
+  auto *RegisterBB = getOrInsertRegisterBB(CGM);
+  if (!RegisterBB)
+    return;
+  CGBuilderTy Builder(RegisterBB->getTerminator());
+  auto *VoidPtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
+  Builder.CreateCall(getOrInsertRuntimeRegister(CGM),
+                     Builder.CreateBitCast(Data, VoidPtrTy));
+}
+
+llvm::Function *CodeGenPGO::emitInitialization(CodeGenModule &CGM) {
+  if (!CGM.getCodeGenOpts().ProfileInstrGenerate)
+    return nullptr;
+
+  assert(CGM.getModule().getFunction("__llvm_profile_init") == nullptr &&
+         "profile initialization already emitted");
+
+  // Get the function to call at initialization.
+  llvm::Constant *RegisterF = getRegisterFunc(CGM);
+  if (!RegisterF)
+    return nullptr;
+
+  // Create the initialization function.
+  auto *VoidTy = llvm::Type::getVoidTy(CGM.getLLVMContext());
+  auto *F = llvm::Function::Create(llvm::FunctionType::get(VoidTy, false),
+                                   llvm::GlobalValue::InternalLinkage,
+                                   "__llvm_profile_init", &CGM.getModule());
+  F->setUnnamedAddr(true);
+  F->addFnAttr(llvm::Attribute::NoInline);
+  if (CGM.getCodeGenOpts().DisableRedZone)
+    F->addFnAttr(llvm::Attribute::NoRedZone);
+
+  // Add the basic block and the necessary calls.
+  CGBuilderTy Builder(llvm::BasicBlock::Create(CGM.getLLVMContext(), "", F));
+  Builder.CreateCall(RegisterF);
+  Builder.CreateRetVoid();
+
+  return F;
+}
+
+namespace {
+/// \brief Stable hasher for PGO region counters.
+///
+/// PGOHash produces a stable hash of a given function's control flow.
+///
+/// Changing the output of this hash will invalidate all previously generated
+/// profiles -- i.e., don't do it.
+///
+/// \note  When this hash does eventually change (years?), we still need to
+/// support old hashes.  We'll need to pull in the version number from the
+/// profile data format and use the matching hash function.
+class PGOHash {
+  uint64_t Working;
+  unsigned Count;
+  llvm::MD5 MD5;
+
+  static const int NumBitsPerType = 6;
+  static const unsigned NumTypesPerWord = sizeof(uint64_t) * 8 / NumBitsPerType;
+  static const unsigned TooBig = 1u << NumBitsPerType;
+
+public:
+  /// \brief Hash values for AST nodes.
+  ///
+  /// Distinct values for AST nodes that have region counters attached.
+  ///
+  /// These values must be stable.  All new members must be added at the end,
+  /// and no members should be removed.  Changing the enumeration value for an
+  /// AST node will affect the hash of every function that contains that node.
+  enum HashType : unsigned char {
+    None = 0,
+    LabelStmt = 1,
+    WhileStmt,
+    DoStmt,
+    ForStmt,
+    CXXForRangeStmt,
+    ObjCForCollectionStmt,
+    SwitchStmt,
+    CaseStmt,
+    DefaultStmt,
+    IfStmt,
+    CXXTryStmt,
+    CXXCatchStmt,
+    ConditionalOperator,
+    BinaryOperatorLAnd,
+    BinaryOperatorLOr,
+    BinaryConditionalOperator,
+
+    // Keep this last.  It's for the static assert that follows.
+    LastHashType
+  };
+  static_assert(LastHashType <= TooBig, "Too many types in HashType");
+
+  // TODO: When this format changes, take in a version number here, and use the
+  // old hash calculation for file formats that used the old hash.
+  PGOHash() : Working(0), Count(0) {}
+  void combine(HashType Type);
+  uint64_t finalize();
+};
+const int PGOHash::NumBitsPerType;
+const unsigned PGOHash::NumTypesPerWord;
+const unsigned PGOHash::TooBig;
+
+  /// A RecursiveASTVisitor that fills a map of statements to PGO counters.
+  struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
+    /// The next counter value to assign.
+    unsigned NextCounter;
+    /// The function hash.
+    PGOHash Hash;
+    /// The map of statements to counters.
+    llvm::DenseMap<const Stmt *, unsigned> &CounterMap;
+
+    MapRegionCounters(llvm::DenseMap<const Stmt *, unsigned> &CounterMap)
+        : NextCounter(0), CounterMap(CounterMap) {}
+
+    // Blocks and lambdas are handled as separate functions, so we need not
+    // traverse them in the parent context.
+    bool TraverseBlockExpr(BlockExpr *BE) { return true; }
+    bool TraverseLambdaBody(LambdaExpr *LE) { return true; }
+    bool TraverseCapturedStmt(CapturedStmt *CS) { return true; }
+
+    bool VisitDecl(const Decl *D) {
+      switch (D->getKind()) {
+      default:
+        break;
+      case Decl::Function:
+      case Decl::CXXMethod:
+      case Decl::CXXConstructor:
+      case Decl::CXXDestructor:
+      case Decl::CXXConversion:
+      case Decl::ObjCMethod:
+      case Decl::Block:
+      case Decl::Captured:
+        CounterMap[D->getBody()] = NextCounter++;
+        break;
+      }
+      return true;
+    }
+
+    bool VisitStmt(const Stmt *S) {
+      auto Type = getHashType(S);
+      if (Type == PGOHash::None)
+        return true;
+
+      CounterMap[S] = NextCounter++;
+      Hash.combine(Type);
+      return true;
+    }
+    PGOHash::HashType getHashType(const Stmt *S) {
+      switch (S->getStmtClass()) {
+      default:
+        break;
+      case Stmt::LabelStmtClass:
+        return PGOHash::LabelStmt;
+      case Stmt::WhileStmtClass:
+        return PGOHash::WhileStmt;
+      case Stmt::DoStmtClass:
+        return PGOHash::DoStmt;
+      case Stmt::ForStmtClass:
+        return PGOHash::ForStmt;
+      case Stmt::CXXForRangeStmtClass:
+        return PGOHash::CXXForRangeStmt;
+      case Stmt::ObjCForCollectionStmtClass:
+        return PGOHash::ObjCForCollectionStmt;
+      case Stmt::SwitchStmtClass:
+        return PGOHash::SwitchStmt;
+      case Stmt::CaseStmtClass:
+        return PGOHash::CaseStmt;
+      case Stmt::DefaultStmtClass:
+        return PGOHash::DefaultStmt;
+      case Stmt::IfStmtClass:
+        return PGOHash::IfStmt;
+      case Stmt::CXXTryStmtClass:
+        return PGOHash::CXXTryStmt;
+      case Stmt::CXXCatchStmtClass:
+        return PGOHash::CXXCatchStmt;
+      case Stmt::ConditionalOperatorClass:
+        return PGOHash::ConditionalOperator;
+      case Stmt::BinaryConditionalOperatorClass:
+        return PGOHash::BinaryConditionalOperator;
+      case Stmt::BinaryOperatorClass: {
+        const BinaryOperator *BO = cast<BinaryOperator>(S);
+        if (BO->getOpcode() == BO_LAnd)
+          return PGOHash::BinaryOperatorLAnd;
+        if (BO->getOpcode() == BO_LOr)
+          return PGOHash::BinaryOperatorLOr;
+        break;
+      }
+      }
+      return PGOHash::None;
+    }
+  };
+
+  /// A StmtVisitor that propagates the raw counts through the AST and
+  /// records the count at statements where the value may change.
+  struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> {
+    /// PGO state.
+    CodeGenPGO &PGO;
+
+    /// A flag that is set when the current count should be recorded on the
+    /// next statement, such as at the exit of a loop.
+    bool RecordNextStmtCount;
+
+    /// The map of statements to count values.
+    llvm::DenseMap<const Stmt *, uint64_t> &CountMap;
+
+    /// BreakContinueStack - Keep counts of breaks and continues inside loops.
+    struct BreakContinue {
+      uint64_t BreakCount;
+      uint64_t ContinueCount;
+      BreakContinue() : BreakCount(0), ContinueCount(0) {}
+    };
+    SmallVector<BreakContinue, 8> BreakContinueStack;
+
+    ComputeRegionCounts(llvm::DenseMap<const Stmt *, uint64_t> &CountMap,
+                        CodeGenPGO &PGO)
+        : PGO(PGO), RecordNextStmtCount(false), CountMap(CountMap) {}
+
+    void RecordStmtCount(const Stmt *S) {
+      if (RecordNextStmtCount) {
+        CountMap[S] = PGO.getCurrentRegionCount();
+        RecordNextStmtCount = false;
+      }
+    }
+
+    void VisitStmt(const Stmt *S) {
+      RecordStmtCount(S);
+      for (Stmt::const_child_range I = S->children(); I; ++I) {
+        if (*I)
+         this->Visit(*I);
+      }
+    }
+
+    void VisitFunctionDecl(const FunctionDecl *D) {
+      // Counter tracks entry to the function body.
+      RegionCounter Cnt(PGO, D->getBody());
+      Cnt.beginRegion();
+      CountMap[D->getBody()] = PGO.getCurrentRegionCount();
+      Visit(D->getBody());
+    }
+
+    // Skip lambda expressions. We visit these as FunctionDecls when we're
+    // generating them and aren't interested in the body when generating a
+    // parent context.
+    void VisitLambdaExpr(const LambdaExpr *LE) {}
+
+    void VisitCapturedDecl(const CapturedDecl *D) {
+      // Counter tracks entry to the capture body.
+      RegionCounter Cnt(PGO, D->getBody());
+      Cnt.beginRegion();
+      CountMap[D->getBody()] = PGO.getCurrentRegionCount();
+      Visit(D->getBody());
+    }
+
+    void VisitObjCMethodDecl(const ObjCMethodDecl *D) {
+      // Counter tracks entry to the method body.
+      RegionCounter Cnt(PGO, D->getBody());
+      Cnt.beginRegion();
+      CountMap[D->getBody()] = PGO.getCurrentRegionCount();
+      Visit(D->getBody());
+    }
+
+    void VisitBlockDecl(const BlockDecl *D) {
+      // Counter tracks entry to the block body.
+      RegionCounter Cnt(PGO, D->getBody());
+      Cnt.beginRegion();
+      CountMap[D->getBody()] = PGO.getCurrentRegionCount();
+      Visit(D->getBody());
+    }
+
+    void VisitReturnStmt(const ReturnStmt *S) {
+      RecordStmtCount(S);
+      if (S->getRetValue())
+        Visit(S->getRetValue());
+      PGO.setCurrentRegionUnreachable();
+      RecordNextStmtCount = true;
+    }
+
+    void VisitGotoStmt(const GotoStmt *S) {
+      RecordStmtCount(S);
+      PGO.setCurrentRegionUnreachable();
+      RecordNextStmtCount = true;
+    }
+
+    void VisitLabelStmt(const LabelStmt *S) {
+      RecordNextStmtCount = false;
+      // Counter tracks the block following the label.
+      RegionCounter Cnt(PGO, S);
+      Cnt.beginRegion();
+      CountMap[S] = PGO.getCurrentRegionCount();
+      Visit(S->getSubStmt());
+    }
+
+    void VisitBreakStmt(const BreakStmt *S) {
+      RecordStmtCount(S);
+      assert(!BreakContinueStack.empty() && "break not in a loop or switch!");
+      BreakContinueStack.back().BreakCount += PGO.getCurrentRegionCount();
+      PGO.setCurrentRegionUnreachable();
+      RecordNextStmtCount = true;
+    }
+
+    void VisitContinueStmt(const ContinueStmt *S) {
+      RecordStmtCount(S);
+      assert(!BreakContinueStack.empty() && "continue stmt not in a loop!");
+      BreakContinueStack.back().ContinueCount += PGO.getCurrentRegionCount();
+      PGO.setCurrentRegionUnreachable();
+      RecordNextStmtCount = true;
+    }
+
+    void VisitWhileStmt(const WhileStmt *S) {
+      RecordStmtCount(S);
+      // Counter tracks the body of the loop.
+      RegionCounter Cnt(PGO, S);
+      BreakContinueStack.push_back(BreakContinue());
+      // Visit the body region first so the break/continue adjustments can be
+      // included when visiting the condition.
+      Cnt.beginRegion();
+      CountMap[S->getBody()] = PGO.getCurrentRegionCount();
+      Visit(S->getBody());
+      Cnt.adjustForControlFlow();
+
+      // ...then go back and propagate counts through the condition. The count
+      // at the start of the condition is the sum of the incoming edges,
+      // the backedge from the end of the loop body, and the edges from
+      // continue statements.
+      BreakContinue BC = BreakContinueStack.pop_back_val();
+      Cnt.setCurrentRegionCount(Cnt.getParentCount() +
+                                Cnt.getAdjustedCount() + BC.ContinueCount);
+      CountMap[S->getCond()] = PGO.getCurrentRegionCount();
+      Visit(S->getCond());
+      Cnt.adjustForControlFlow();
+      Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount);
+      RecordNextStmtCount = true;
+    }
+
+    void VisitDoStmt(const DoStmt *S) {
+      RecordStmtCount(S);
+      // Counter tracks the body of the loop.
+      RegionCounter Cnt(PGO, S);
+      BreakContinueStack.push_back(BreakContinue());
+      Cnt.beginRegion(/*AddIncomingFallThrough=*/true);
+      CountMap[S->getBody()] = PGO.getCurrentRegionCount();
+      Visit(S->getBody());
+      Cnt.adjustForControlFlow();
+
+      BreakContinue BC = BreakContinueStack.pop_back_val();
+      // The count at the start of the condition is equal to the count at the
+      // end of the body. The adjusted count does not include either the
+      // fall-through count coming into the loop or the continue count, so add
+      // both of those separately. This is coincidentally the same equation as
+      // with while loops but for different reasons.
+      Cnt.setCurrentRegionCount(Cnt.getParentCount() +
+                                Cnt.getAdjustedCount() + BC.ContinueCount);
+      CountMap[S->getCond()] = PGO.getCurrentRegionCount();
+      Visit(S->getCond());
+      Cnt.adjustForControlFlow();
+      Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount);
+      RecordNextStmtCount = true;
+    }
+
+    void VisitForStmt(const ForStmt *S) {
+      RecordStmtCount(S);
+      if (S->getInit())
+        Visit(S->getInit());
+      // Counter tracks the body of the loop.
+      RegionCounter Cnt(PGO, S);
+      BreakContinueStack.push_back(BreakContinue());
+      // Visit the body region first. (This is basically the same as a while
+      // loop; see further comments in VisitWhileStmt.)
+      Cnt.beginRegion();
+      CountMap[S->getBody()] = PGO.getCurrentRegionCount();
+      Visit(S->getBody());
+      Cnt.adjustForControlFlow();
+
+      // The increment is essentially part of the body but it needs to include
+      // the count for all the continue statements.
+      if (S->getInc()) {
+        Cnt.setCurrentRegionCount(PGO.getCurrentRegionCount() +
+                                  BreakContinueStack.back().ContinueCount);
+        CountMap[S->getInc()] = PGO.getCurrentRegionCount();
+        Visit(S->getInc());
+        Cnt.adjustForControlFlow();
+      }
+
+      BreakContinue BC = BreakContinueStack.pop_back_val();
+
+      // ...then go back and propagate counts through the condition.
+      if (S->getCond()) {
+        Cnt.setCurrentRegionCount(Cnt.getParentCount() +
+                                  Cnt.getAdjustedCount() +
+                                  BC.ContinueCount);
+        CountMap[S->getCond()] = PGO.getCurrentRegionCount();
+        Visit(S->getCond());
+        Cnt.adjustForControlFlow();
+      }
+      Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount);
+      RecordNextStmtCount = true;
+    }
+
+    void VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
+      RecordStmtCount(S);
+      Visit(S->getRangeStmt());
+      Visit(S->getBeginEndStmt());
+      // Counter tracks the body of the loop.
+      RegionCounter Cnt(PGO, S);
+      BreakContinueStack.push_back(BreakContinue());
+      // Visit the body region first. (This is basically the same as a while
+      // loop; see further comments in VisitWhileStmt.)
+      Cnt.beginRegion();
+      CountMap[S->getLoopVarStmt()] = PGO.getCurrentRegionCount();
+      Visit(S->getLoopVarStmt());
+      Visit(S->getBody());
+      Cnt.adjustForControlFlow();
+
+      // The increment is essentially part of the body but it needs to include
+      // the count for all the continue statements.
+      Cnt.setCurrentRegionCount(PGO.getCurrentRegionCount() +
+                                BreakContinueStack.back().ContinueCount);
+      CountMap[S->getInc()] = PGO.getCurrentRegionCount();
+      Visit(S->getInc());
+      Cnt.adjustForControlFlow();
+
+      BreakContinue BC = BreakContinueStack.pop_back_val();
+
+      // ...then go back and propagate counts through the condition.
+      Cnt.setCurrentRegionCount(Cnt.getParentCount() +
+                                Cnt.getAdjustedCount() +
+                                BC.ContinueCount);
+      CountMap[S->getCond()] = PGO.getCurrentRegionCount();
+      Visit(S->getCond());
+      Cnt.adjustForControlFlow();
+      Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount);
+      RecordNextStmtCount = true;
+    }
+
+    void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
+      RecordStmtCount(S);
+      Visit(S->getElement());
+      // Counter tracks the body of the loop.
+      RegionCounter Cnt(PGO, S);
+      BreakContinueStack.push_back(BreakContinue());
+      Cnt.beginRegion();
+      CountMap[S->getBody()] = PGO.getCurrentRegionCount();
+      Visit(S->getBody());
+      BreakContinue BC = BreakContinueStack.pop_back_val();
+      Cnt.adjustForControlFlow();
+      Cnt.applyAdjustmentsToRegion(BC.BreakCount + BC.ContinueCount);
+      RecordNextStmtCount = true;
+    }
+
+    void VisitSwitchStmt(const SwitchStmt *S) {
+      RecordStmtCount(S);
+      Visit(S->getCond());
+      PGO.setCurrentRegionUnreachable();
+      BreakContinueStack.push_back(BreakContinue());
+      Visit(S->getBody());
+      // If the switch is inside a loop, add the continue counts.
+      BreakContinue BC = BreakContinueStack.pop_back_val();
+      if (!BreakContinueStack.empty())
+        BreakContinueStack.back().ContinueCount += BC.ContinueCount;
+      // Counter tracks the exit block of the switch.
+      RegionCounter ExitCnt(PGO, S);
+      ExitCnt.beginRegion();
+      RecordNextStmtCount = true;
+    }
+
+    void VisitCaseStmt(const CaseStmt *S) {
+      RecordNextStmtCount = false;
+      // Counter for this particular case. This counts only jumps from the
+      // switch header and does not include fallthrough from the case before
+      // this one.
+      RegionCounter Cnt(PGO, S);
+      Cnt.beginRegion(/*AddIncomingFallThrough=*/true);
+      CountMap[S] = Cnt.getCount();
+      RecordNextStmtCount = true;
+      Visit(S->getSubStmt());
+    }
+
+    void VisitDefaultStmt(const DefaultStmt *S) {
+      RecordNextStmtCount = false;
+      // Counter for this default case. This does not include fallthrough from
+      // the previous case.
+      RegionCounter Cnt(PGO, S);
+      Cnt.beginRegion(/*AddIncomingFallThrough=*/true);
+      CountMap[S] = Cnt.getCount();
+      RecordNextStmtCount = true;
+      Visit(S->getSubStmt());
+    }
+
+    void VisitIfStmt(const IfStmt *S) {
+      RecordStmtCount(S);
+      // Counter tracks the "then" part of an if statement. The count for
+      // the "else" part, if it exists, will be calculated from this counter.
+      RegionCounter Cnt(PGO, S);
+      Visit(S->getCond());
+
+      Cnt.beginRegion();
+      CountMap[S->getThen()] = PGO.getCurrentRegionCount();
+      Visit(S->getThen());
+      Cnt.adjustForControlFlow();
+
+      if (S->getElse()) {
+        Cnt.beginElseRegion();
+        CountMap[S->getElse()] = PGO.getCurrentRegionCount();
+        Visit(S->getElse());
+        Cnt.adjustForControlFlow();
+      }
+      Cnt.applyAdjustmentsToRegion(0);
+      RecordNextStmtCount = true;
+    }
+
+    void VisitCXXTryStmt(const CXXTryStmt *S) {
+      RecordStmtCount(S);
+      Visit(S->getTryBlock());
+      for (unsigned I = 0, E = S->getNumHandlers(); I < E; ++I)
+        Visit(S->getHandler(I));
+      // Counter tracks the continuation block of the try statement.
+      RegionCounter Cnt(PGO, S);
+      Cnt.beginRegion();
+      RecordNextStmtCount = true;
+    }
+
+    void VisitCXXCatchStmt(const CXXCatchStmt *S) {
+      RecordNextStmtCount = false;
+      // Counter tracks the catch statement's handler block.
+      RegionCounter Cnt(PGO, S);
+      Cnt.beginRegion();
+      CountMap[S] = PGO.getCurrentRegionCount();
+      Visit(S->getHandlerBlock());
+    }
+
+    void VisitAbstractConditionalOperator(
+        const AbstractConditionalOperator *E) {
+      RecordStmtCount(E);
+      // Counter tracks the "true" part of a conditional operator. The
+      // count in the "false" part will be calculated from this counter.
+      RegionCounter Cnt(PGO, E);
+      Visit(E->getCond());
+
+      Cnt.beginRegion();
+      CountMap[E->getTrueExpr()] = PGO.getCurrentRegionCount();
+      Visit(E->getTrueExpr());
+      Cnt.adjustForControlFlow();
+
+      Cnt.beginElseRegion();
+      CountMap[E->getFalseExpr()] = PGO.getCurrentRegionCount();
+      Visit(E->getFalseExpr());
+      Cnt.adjustForControlFlow();
+
+      Cnt.applyAdjustmentsToRegion(0);
+      RecordNextStmtCount = true;
+    }
+
+    void VisitBinLAnd(const BinaryOperator *E) {
+      RecordStmtCount(E);
+      // Counter tracks the right hand side of a logical and operator.
+      RegionCounter Cnt(PGO, E);
+      Visit(E->getLHS());
+      Cnt.beginRegion();
+      CountMap[E->getRHS()] = PGO.getCurrentRegionCount();
+      Visit(E->getRHS());
+      Cnt.adjustForControlFlow();
+      Cnt.applyAdjustmentsToRegion(0);
+      RecordNextStmtCount = true;
+    }
+
+    void VisitBinLOr(const BinaryOperator *E) {
+      RecordStmtCount(E);
+      // Counter tracks the right hand side of a logical or operator.
+      RegionCounter Cnt(PGO, E);
+      Visit(E->getLHS());
+      Cnt.beginRegion();
+      CountMap[E->getRHS()] = PGO.getCurrentRegionCount();
+      Visit(E->getRHS());
+      Cnt.adjustForControlFlow();
+      Cnt.applyAdjustmentsToRegion(0);
+      RecordNextStmtCount = true;
+    }
+  };
+}
+
+void PGOHash::combine(HashType Type) {
+  // Check that we never combine 0 and only have six bits.
+  assert(Type && "Hash is invalid: unexpected type 0");
+  assert(unsigned(Type) < TooBig && "Hash is invalid: too many types");
+
+  // Pass through MD5 if enough work has built up.
+  if (Count && Count % NumTypesPerWord == 0) {
+    using namespace llvm::support;
+    uint64_t Swapped = endian::byte_swap<uint64_t, little>(Working);
+    MD5.update(llvm::makeArrayRef((uint8_t *)&Swapped, sizeof(Swapped)));
+    Working = 0;
+  }
+
+  // Accumulate the current type.
+  ++Count;
+  Working = Working << NumBitsPerType | Type;
+}
+
+uint64_t PGOHash::finalize() {
+  // Use Working as the hash directly if we never used MD5.
+  if (Count <= NumTypesPerWord)
+    // No need to byte swap here, since none of the math was endian-dependent.
+    // This number will be byte-swapped as required on endianness transitions,
+    // so we will see the same value on the other side.
+    return Working;
+
+  // Check for remaining work in Working.
+  if (Working)
+    MD5.update(Working);
+
+  // Finalize the MD5 and return the hash.
+  llvm::MD5::MD5Result Result;
+  MD5.final(Result);
+  using namespace llvm::support;
+  return endian::read<uint64_t, little, unaligned>(Result);
+}
+
+static void emitRuntimeHook(CodeGenModule &CGM) {
+  const char *const RuntimeVarName = "__llvm_profile_runtime";
+  const char *const RuntimeUserName = "__llvm_profile_runtime_user";
+  if (CGM.getModule().getGlobalVariable(RuntimeVarName))
+    return;
+
+  // Declare the runtime hook.
+  llvm::LLVMContext &Ctx = CGM.getLLVMContext();
+  auto *Int32Ty = llvm::Type::getInt32Ty(Ctx);
+  auto *Var = new llvm::GlobalVariable(CGM.getModule(), Int32Ty, false,
+                                       llvm::GlobalValue::ExternalLinkage,
+                                       nullptr, RuntimeVarName);
+
+  // Make a function that uses it.
+  auto *User = llvm::Function::Create(llvm::FunctionType::get(Int32Ty, false),
+                                      llvm::GlobalValue::LinkOnceODRLinkage,
+                                      RuntimeUserName, &CGM.getModule());
+  User->addFnAttr(llvm::Attribute::NoInline);
+  if (CGM.getCodeGenOpts().DisableRedZone)
+    User->addFnAttr(llvm::Attribute::NoRedZone);
+  CGBuilderTy Builder(llvm::BasicBlock::Create(CGM.getLLVMContext(), "", User));
+  auto *Load = Builder.CreateLoad(Var);
+  Builder.CreateRet(Load);
+
+  // Create a use of the function.  Now the definition of the runtime variable
+  // should get pulled in, along with any static initializears.
+  CGM.addUsedGlobal(User);
+}
+
+void CodeGenPGO::assignRegionCounters(const Decl *D, llvm::Function *Fn) {
+  bool InstrumentRegions = CGM.getCodeGenOpts().ProfileInstrGenerate;
+  llvm::IndexedInstrProfReader *PGOReader = CGM.getPGOReader();
+  if (!InstrumentRegions && !PGOReader)
+    return;
+  if (D->isImplicit())
+    return;
+  setFuncName(Fn);
+
+  // Set the linkage for variables based on the function linkage.  Usually, we
+  // want to match it, but available_externally and extern_weak both have the
+  // wrong semantics.
+  VarLinkage = Fn->getLinkage();
+  switch (VarLinkage) {
+  case llvm::GlobalValue::ExternalWeakLinkage:
+    VarLinkage = llvm::GlobalValue::LinkOnceAnyLinkage;
+    break;
+  case llvm::GlobalValue::AvailableExternallyLinkage:
+    VarLinkage = llvm::GlobalValue::LinkOnceODRLinkage;
+    break;
+  default:
+    break;
+  }
+
+  mapRegionCounters(D);
+  if (InstrumentRegions) {
+    emitRuntimeHook(CGM);
+    emitCounterVariables();
+  }
+  if (PGOReader) {
+    SourceManager &SM = CGM.getContext().getSourceManager();
+    loadRegionCounts(PGOReader, SM.isInMainFile(D->getLocation()));
+    computeRegionCounts(D);
+    applyFunctionAttributes(PGOReader, Fn);
+  }
+}
+
+void CodeGenPGO::mapRegionCounters(const Decl *D) {
+  RegionCounterMap.reset(new llvm::DenseMap<const Stmt *, unsigned>);
+  MapRegionCounters Walker(*RegionCounterMap);
+  if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
+    Walker.TraverseDecl(const_cast<FunctionDecl *>(FD));
+  else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
+    Walker.TraverseDecl(const_cast<ObjCMethodDecl *>(MD));
+  else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
+    Walker.TraverseDecl(const_cast<BlockDecl *>(BD));
+  else if (const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D))
+    Walker.TraverseDecl(const_cast<CapturedDecl *>(CD));
+  assert(Walker.NextCounter > 0 && "no entry counter mapped for decl");
+  NumRegionCounters = Walker.NextCounter;
+  FunctionHash = Walker.Hash.finalize();
+}
+
+void CodeGenPGO::computeRegionCounts(const Decl *D) {
+  StmtCountMap.reset(new llvm::DenseMap<const Stmt *, uint64_t>);
+  ComputeRegionCounts Walker(*StmtCountMap, *this);
+  if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
+    Walker.VisitFunctionDecl(FD);
+  else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
+    Walker.VisitObjCMethodDecl(MD);
+  else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
+    Walker.VisitBlockDecl(BD);
+  else if (const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D))
+    Walker.VisitCapturedDecl(const_cast<CapturedDecl *>(CD));
+}
+
+void
+CodeGenPGO::applyFunctionAttributes(llvm::IndexedInstrProfReader *PGOReader,
+                                    llvm::Function *Fn) {
+  if (!haveRegionCounts())
+    return;
+
+  uint64_t MaxFunctionCount = PGOReader->getMaximumFunctionCount();
+  uint64_t FunctionCount = getRegionCount(0);
+  if (FunctionCount >= (uint64_t)(0.3 * (double)MaxFunctionCount))
+    // Turn on InlineHint attribute for hot functions.
+    // FIXME: 30% is from preliminary tuning on SPEC, it may not be optimal.
+    Fn->addFnAttr(llvm::Attribute::InlineHint);
+  else if (FunctionCount <= (uint64_t)(0.01 * (double)MaxFunctionCount))
+    // Turn on Cold attribute for cold functions.
+    // FIXME: 1% is from preliminary tuning on SPEC, it may not be optimal.
+    Fn->addFnAttr(llvm::Attribute::Cold);
+}
+
+void CodeGenPGO::emitCounterVariables() {
+  llvm::LLVMContext &Ctx = CGM.getLLVMContext();
+  llvm::ArrayType *CounterTy = llvm::ArrayType::get(llvm::Type::getInt64Ty(Ctx),
+                                                    NumRegionCounters);
+  RegionCounters =
+    new llvm::GlobalVariable(CGM.getModule(), CounterTy, false, VarLinkage,
+                             llvm::Constant::getNullValue(CounterTy),
+                             getFuncVarName("counters"));
+  RegionCounters->setAlignment(8);
+  RegionCounters->setSection(getCountersSection(CGM));
+}
+
+void CodeGenPGO::emitCounterIncrement(CGBuilderTy &Builder, unsigned Counter) {
+  if (!RegionCounters)
+    return;
+  llvm::Value *Addr =
+    Builder.CreateConstInBoundsGEP2_64(RegionCounters, 0, Counter);
+  llvm::Value *Count = Builder.CreateLoad(Addr, "pgocount");
+  Count = Builder.CreateAdd(Count, Builder.getInt64(1));
+  Builder.CreateStore(Count, Addr);
+}
+
+void CodeGenPGO::loadRegionCounts(llvm::IndexedInstrProfReader *PGOReader,
+                                  bool IsInMainFile) {
+  CGM.getPGOStats().addVisited(IsInMainFile);
+  RegionCounts.reset(new std::vector<uint64_t>);
+  uint64_t Hash;
+  if (PGOReader->getFunctionCounts(getFuncName(), Hash, *RegionCounts)) {
+    CGM.getPGOStats().addMissing(IsInMainFile);
+    RegionCounts.reset();
+  } else if (Hash != FunctionHash ||
+             RegionCounts->size() != NumRegionCounters) {
+    CGM.getPGOStats().addMismatched(IsInMainFile);
+    RegionCounts.reset();
+  }
+}
+
+void CodeGenPGO::destroyRegionCounters() {
+  RegionCounterMap.reset();
+  StmtCountMap.reset();
+  RegionCounts.reset();
+  RegionCounters = nullptr;
+}
+
+/// \brief Calculate what to divide by to scale weights.
+///
+/// Given the maximum weight, calculate a divisor that will scale all the
+/// weights to strictly less than UINT32_MAX.
+static uint64_t calculateWeightScale(uint64_t MaxWeight) {
+  return MaxWeight < UINT32_MAX ? 1 : MaxWeight / UINT32_MAX + 1;
+}
+
+/// \brief Scale an individual branch weight (and add 1).
+///
+/// Scale a 64-bit weight down to 32-bits using \c Scale.
+///
+/// According to Laplace's Rule of Succession, it is better to compute the
+/// weight based on the count plus 1, so universally add 1 to the value.
+///
+/// \pre \c Scale was calculated by \a calculateWeightScale() with a weight no
+/// greater than \c Weight.
+static uint32_t scaleBranchWeight(uint64_t Weight, uint64_t Scale) {
+  assert(Scale && "scale by 0?");
+  uint64_t Scaled = Weight / Scale + 1;
+  assert(Scaled <= UINT32_MAX && "overflow 32-bits");
+  return Scaled;
+}
+
+llvm::MDNode *CodeGenPGO::createBranchWeights(uint64_t TrueCount,
+                                              uint64_t FalseCount) {
+  // Check for empty weights.
+  if (!TrueCount && !FalseCount)
+    return nullptr;
+
+  // Calculate how to scale down to 32-bits.
+  uint64_t Scale = calculateWeightScale(std::max(TrueCount, FalseCount));
+
+  llvm::MDBuilder MDHelper(CGM.getLLVMContext());
+  return MDHelper.createBranchWeights(scaleBranchWeight(TrueCount, Scale),
+                                      scaleBranchWeight(FalseCount, Scale));
+}
+
+llvm::MDNode *CodeGenPGO::createBranchWeights(ArrayRef<uint64_t> Weights) {
+  // We need at least two elements to create meaningful weights.
+  if (Weights.size() < 2)
+    return nullptr;
+
+  // Check for empty weights.
+  uint64_t MaxWeight = *std::max_element(Weights.begin(), Weights.end());
+  if (MaxWeight == 0)
+    return nullptr;
+
+  // Calculate how to scale down to 32-bits.
+  uint64_t Scale = calculateWeightScale(MaxWeight);
+
+  SmallVector<uint32_t, 16> ScaledWeights;
+  ScaledWeights.reserve(Weights.size());
+  for (uint64_t W : Weights)
+    ScaledWeights.push_back(scaleBranchWeight(W, Scale));
+
+  llvm::MDBuilder MDHelper(CGM.getLLVMContext());
+  return MDHelper.createBranchWeights(ScaledWeights);
+}
+
+llvm::MDNode *CodeGenPGO::createLoopWeights(const Stmt *Cond,
+                                            RegionCounter &Cnt) {
+  if (!haveRegionCounts())
+    return nullptr;
+  uint64_t LoopCount = Cnt.getCount();
+  uint64_t CondCount = 0;
+  bool Found = getStmtCount(Cond, CondCount);
+  assert(Found && "missing expected loop condition count");
+  (void)Found;
+  if (CondCount == 0)
+    return nullptr;
+  return createBranchWeights(LoopCount,
+                             std::max(CondCount, LoopCount) - LoopCount);
+}
diff --git a/lib/CodeGen/CodeGenPGO.h b/lib/CodeGen/CodeGenPGO.h
new file mode 100644
index 0000000..2f4aa66
--- /dev/null
+++ b/lib/CodeGen/CodeGenPGO.h
@@ -0,0 +1,236 @@
+//===--- CodeGenPGO.h - PGO Instrumentation for LLVM CodeGen ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Instrumentation-based profile-guided optimization
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_CODEGEN_CODEGENPGO_H
+#define CLANG_CODEGEN_CODEGENPGO_H
+
+#include "CGBuilder.h"
+#include "CodeGenModule.h"
+#include "CodeGenTypes.h"
+#include "clang/Frontend/CodeGenOptions.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include <memory>
+
+namespace clang {
+namespace CodeGen {
+class RegionCounter;
+
+/// Per-function PGO state. This class should generally not be used directly,
+/// but instead through the CodeGenFunction and RegionCounter types.
+class CodeGenPGO {
+private:
+  CodeGenModule &CGM;
+  std::unique_ptr<std::string> PrefixedFuncName;
+  StringRef RawFuncName;
+  llvm::GlobalValue::LinkageTypes VarLinkage;
+
+  unsigned NumRegionCounters;
+  uint64_t FunctionHash;
+  llvm::GlobalVariable *RegionCounters;
+  std::unique_ptr<llvm::DenseMap<const Stmt *, unsigned>> RegionCounterMap;
+  std::unique_ptr<llvm::DenseMap<const Stmt *, uint64_t>> StmtCountMap;
+  std::unique_ptr<std::vector<uint64_t>> RegionCounts;
+  uint64_t CurrentRegionCount;
+
+public:
+  CodeGenPGO(CodeGenModule &CGM)
+      : CGM(CGM), NumRegionCounters(0), FunctionHash(0),
+        RegionCounters(nullptr), CurrentRegionCount(0) {}
+
+  /// Whether or not we have PGO region data for the current function. This is
+  /// false both when we have no data at all and when our data has been
+  /// discarded.
+  bool haveRegionCounts() const { return RegionCounts != nullptr; }
+
+  /// Get the string used to identify this function in the profile data.
+  /// For functions with local linkage, this includes the main file name.
+  StringRef getFuncName() const { return StringRef(*PrefixedFuncName); }
+  std::string getFuncVarName(StringRef VarName) const {
+    return ("__llvm_profile_" + VarName + "_" + RawFuncName).str();
+  }
+
+  /// Return the counter value of the current region.
+  uint64_t getCurrentRegionCount() const { return CurrentRegionCount; }
+
+  /// Set the counter value for the current region. This is used to keep track
+  /// of changes to the most recent counter from control flow and non-local
+  /// exits.
+  void setCurrentRegionCount(uint64_t Count) { CurrentRegionCount = Count; }
+
+  /// Indicate that the current region is never reached, and thus should have a
+  /// counter value of zero. This is important so that subsequent regions can
+  /// correctly track their parent counts.
+  void setCurrentRegionUnreachable() { setCurrentRegionCount(0); }
+
+  /// Check if an execution count is known for a given statement. If so, return
+  /// true and put the value in Count; else return false.
+  bool getStmtCount(const Stmt *S, uint64_t &Count) {
+    if (!StmtCountMap)
+      return false;
+    llvm::DenseMap<const Stmt*, uint64_t>::const_iterator
+      I = StmtCountMap->find(S);
+    if (I == StmtCountMap->end())
+      return false;
+    Count = I->second;
+    return true;
+  }
+
+  /// If the execution count for the current statement is known, record that
+  /// as the current count.
+  void setCurrentStmt(const Stmt *S) {
+    uint64_t Count;
+    if (getStmtCount(S, Count))
+      setCurrentRegionCount(Count);
+  }
+
+  /// Calculate branch weights appropriate for PGO data
+  llvm::MDNode *createBranchWeights(uint64_t TrueCount, uint64_t FalseCount);
+  llvm::MDNode *createBranchWeights(ArrayRef<uint64_t> Weights);
+  llvm::MDNode *createLoopWeights(const Stmt *Cond, RegionCounter &Cnt);
+
+  /// Assign counters to regions and configure them for PGO of a given
+  /// function. Does nothing if instrumentation is not enabled and either
+  /// generates global variables or associates PGO data with each of the
+  /// counters depending on whether we are generating or using instrumentation.
+  void assignRegionCounters(const Decl *D, llvm::Function *Fn);
+  /// Emit static data structures for instrumentation data.
+  void emitInstrumentationData();
+  /// Clean up region counter state. Must be called if assignRegionCounters is
+  /// used.
+  void destroyRegionCounters();
+  /// Emit static initialization code, if any.
+  static llvm::Function *emitInitialization(CodeGenModule &CGM);
+
+private:
+  void setFuncName(llvm::Function *Fn);
+  void mapRegionCounters(const Decl *D);
+  void computeRegionCounts(const Decl *D);
+  void applyFunctionAttributes(llvm::IndexedInstrProfReader *PGOReader,
+                               llvm::Function *Fn);
+  void loadRegionCounts(llvm::IndexedInstrProfReader *PGOReader,
+                        bool IsInMainFile);
+  void emitCounterVariables();
+  llvm::GlobalVariable *buildDataVar();
+
+  /// Emit code to increment the counter at the given index
+  void emitCounterIncrement(CGBuilderTy &Builder, unsigned Counter);
+
+  /// Return the region counter for the given statement. This should only be
+  /// called on statements that have a dedicated counter.
+  unsigned getRegionCounter(const Stmt *S) {
+    if (!RegionCounterMap)
+      return 0;
+    return (*RegionCounterMap)[S];
+  }
+
+  /// Return the region count for the counter at the given index.
+  uint64_t getRegionCount(unsigned Counter) {
+    if (!haveRegionCounts())
+      return 0;
+    return (*RegionCounts)[Counter];
+  }
+
+  friend class RegionCounter;
+};
+
+/// A counter for a particular region. This is the primary interface through
+/// which clients manage PGO counters and their values.
+class RegionCounter {
+  CodeGenPGO *PGO;
+  unsigned Counter;
+  uint64_t Count;
+  uint64_t ParentCount;
+  uint64_t RegionCount;
+  int64_t Adjust;
+
+  RegionCounter(CodeGenPGO &PGO, unsigned CounterIndex)
+    : PGO(&PGO), Counter(CounterIndex), Count(PGO.getRegionCount(Counter)),
+      ParentCount(PGO.getCurrentRegionCount()), Adjust(0) {}
+
+public:
+  RegionCounter(CodeGenPGO &PGO, const Stmt *S)
+    : PGO(&PGO), Counter(PGO.getRegionCounter(S)),
+      Count(PGO.getRegionCount(Counter)),
+      ParentCount(PGO.getCurrentRegionCount()), Adjust(0) {}
+
+  /// Get the value of the counter. In most cases this is the number of times
+  /// the region of the counter was entered, but for switch labels it's the
+  /// number of direct jumps to that label.
+  uint64_t getCount() const { return Count; }
+
+  /// Get the value of the counter with adjustments applied. Adjustments occur
+  /// when control enters or leaves the region abnormally; i.e., if there is a
+  /// jump to a label within the region, or if the function can return from
+  /// within the region. The adjusted count, then, is the value of the counter
+  /// at the end of the region.
+  uint64_t getAdjustedCount() const {
+    return Count + Adjust;
+  }
+
+  /// Get the value of the counter in this region's parent, i.e., the region
+  /// that was active when this region began. This is useful for deriving
+  /// counts in implicitly counted regions, like the false case of a condition
+  /// or the normal exits of a loop.
+  uint64_t getParentCount() const { return ParentCount; }
+
+  /// Activate the counter by emitting an increment and starting to track
+  /// adjustments. If AddIncomingFallThrough is true, the current region count
+  /// will be added to the counter for the purposes of tracking the region.
+  void beginRegion(CGBuilderTy &Builder, bool AddIncomingFallThrough=false) {
+    beginRegion(AddIncomingFallThrough);
+    PGO->emitCounterIncrement(Builder, Counter);
+  }
+  void beginRegion(bool AddIncomingFallThrough=false) {
+    RegionCount = Count;
+    if (AddIncomingFallThrough)
+      RegionCount += PGO->getCurrentRegionCount();
+    PGO->setCurrentRegionCount(RegionCount);
+  }
+
+  /// For counters on boolean branches, begins tracking adjustments for the
+  /// uncounted path.
+  void beginElseRegion() {
+    RegionCount = ParentCount - Count;
+    PGO->setCurrentRegionCount(RegionCount);
+  }
+
+  /// Reset the current region count.
+  void setCurrentRegionCount(uint64_t CurrentCount) {
+    RegionCount = CurrentCount;
+    PGO->setCurrentRegionCount(RegionCount);
+  }
+
+  /// Adjust for non-local control flow after emitting a subexpression or
+  /// substatement. This must be called to account for constructs such as gotos,
+  /// labels, and returns, so that we can ensure that our region's count is
+  /// correct in the code that follows.
+  void adjustForControlFlow() {
+    Adjust += PGO->getCurrentRegionCount() - RegionCount;
+    // Reset the region count in case this is called again later.
+    RegionCount = PGO->getCurrentRegionCount();
+  }
+
+  /// Commit all adjustments to the current region. If the region is a loop,
+  /// the LoopAdjust value should be the count of all the breaks and continues
+  /// from the loop, to compensate for those counts being deducted from the
+  /// adjustments for the body of the loop.
+  void applyAdjustmentsToRegion(uint64_t LoopAdjust) {
+    PGO->setCurrentRegionCount(ParentCount + Adjust + LoopAdjust);
+  }
+};
+
+}  // end namespace CodeGen
+}  // end namespace clang
+
+#endif
diff --git a/lib/CodeGen/CodeGenTBAA.cpp b/lib/CodeGen/CodeGenTBAA.cpp
index 11e376f..53ba02a 100644
--- a/lib/CodeGen/CodeGenTBAA.cpp
+++ b/lib/CodeGen/CodeGenTBAA.cpp
@@ -33,7 +33,7 @@
                          const CodeGenOptions &CGO,
                          const LangOptions &Features, MangleContext &MContext)
   : Context(Ctx), CodeGenOpts(CGO), Features(Features), MContext(MContext),
-    MDHelper(VMContext), Root(0), Char(0) {
+    MDHelper(VMContext), Root(nullptr), Char(nullptr) {
 }
 
 CodeGenTBAA::~CodeGenTBAA() {
@@ -88,7 +88,7 @@
 CodeGenTBAA::getTBAAInfo(QualType QTy) {
   // At -O0 or relaxed aliasing, TBAA is not emitted for regular types.
   if (CodeGenOpts.OptimizationLevel == 0 || CodeGenOpts.RelaxedAliasing)
-    return NULL;
+    return nullptr;
 
   // If the type has the may_alias attribute (even on a typedef), it is
   // effectively in the general char alias class.
@@ -152,11 +152,9 @@
     if (!Features.CPlusPlus || !ETy->getDecl()->isExternallyVisible())
       return MetadataCache[Ty] = getChar();
 
-    // TODO: This is using the RTTI name. Is there a better way to get
-    // a unique string for a type?
     SmallString<256> OutName;
     llvm::raw_svector_ostream Out(OutName);
-    MContext.mangleCXXRTTIName(QualType(ETy, 0), Out);
+    MContext.mangleTypeName(QualType(ETy, 0), Out);
     Out.flush();
     return MetadataCache[Ty] = createTBAAScalarType(OutName, getChar());
   }
@@ -223,7 +221,7 @@
     return MDHelper.createTBAAStructNode(Fields);
 
   // For now, handle any other kind of type conservatively.
-  return StructMetadataCache[Ty] = NULL;
+  return StructMetadataCache[Ty] = nullptr;
 }
 
 /// Check if the given type can be handled by path-aware TBAA.
@@ -263,18 +261,16 @@
       else
         FieldNode = getTBAAInfo(FieldQTy);
       if (!FieldNode)
-        return StructTypeMetadataCache[Ty] = NULL;
+        return StructTypeMetadataCache[Ty] = nullptr;
       Fields.push_back(std::make_pair(
           FieldNode, Layout.getFieldOffset(idx) / Context.getCharWidth()));
     }
 
-    // TODO: This is using the RTTI name. Is there a better way to get
-    // a unique string for a type?
     SmallString<256> OutName;
     if (Features.CPlusPlus) {
-      // Don't use mangleCXXRTTIName for C code.
+      // Don't use the mangler for C code.
       llvm::raw_svector_ostream Out(OutName);
-      MContext.mangleCXXRTTIName(QualType(Ty, 0), Out);
+      MContext.mangleTypeName(QualType(Ty, 0), Out);
       Out.flush();
     } else {
       OutName = RD->getName();
@@ -284,7 +280,7 @@
       MDHelper.createTBAAStructTypeNode(OutName, Fields);
   }
 
-  return StructMetadataCache[Ty] = NULL;
+  return StructMetadataCache[Ty] = nullptr;
 }
 
 /// Return a TBAA tag node for both scalar TBAA and struct-path aware TBAA.
@@ -292,7 +288,7 @@
 CodeGenTBAA::getTBAAStructTagInfo(QualType BaseQTy, llvm::MDNode *AccessNode,
                                   uint64_t Offset) {
   if (!AccessNode)
-    return NULL;
+    return nullptr;
 
   if (!CodeGenOpts.StructPathTBAA)
     return getTBAAScalarTagInfo(AccessNode);
@@ -302,7 +298,7 @@
   if (llvm::MDNode *N = StructTagMetadataCache[PathTag])
     return N;
 
-  llvm::MDNode *BNode = 0;
+  llvm::MDNode *BNode = nullptr;
   if (isTBAAPathStruct(BaseQTy))
     BNode  = getTBAAStructTypeInfo(BaseQTy);
   if (!BNode)
@@ -316,7 +312,7 @@
 llvm::MDNode *
 CodeGenTBAA::getTBAAScalarTagInfo(llvm::MDNode *AccessNode) {
   if (!AccessNode)
-    return NULL;
+    return nullptr;
   if (llvm::MDNode *N = ScalarTagMetadataCache[AccessNode])
     return N;
 
diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp
index 5f3c59c..d4e2262 100644
--- a/lib/CodeGen/CodeGenTypes.cpp
+++ b/lib/CodeGen/CodeGenTypes.cpp
@@ -38,10 +38,7 @@
 }
 
 CodeGenTypes::~CodeGenTypes() {
-  for (llvm::DenseMap<const Type *, CGRecordLayout *>::iterator
-         I = CGRecordLayouts.begin(), E = CGRecordLayouts.end();
-      I != E; ++I)
-    delete I->second;
+  llvm::DeleteContainerSeconds(CGRecordLayouts);
 
   for (llvm::FoldingSet<CGFunctionInfo>::iterator
        I = FunctionInfos.begin(), E = FunctionInfos.end(); I != E; )
@@ -134,17 +131,15 @@
   // when a class is translated, even though they aren't embedded by-value into
   // the class.
   if (const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
-    for (CXXRecordDecl::base_class_const_iterator I = CRD->bases_begin(),
-         E = CRD->bases_end(); I != E; ++I)
-      if (!isSafeToConvert(I->getType()->getAs<RecordType>()->getDecl(),
+    for (const auto &I : CRD->bases())
+      if (!isSafeToConvert(I.getType()->getAs<RecordType>()->getDecl(),
                            CGT, AlreadyChecked))
         return false;
   }
   
   // If this type would require laying out members that are currently being laid
   // out, don't do it.
-  for (RecordDecl::field_iterator I = RD->field_begin(),
-       E = RD->field_end(); I != E; ++I)
+  for (const auto *I : RD->fields())
     if (!isSafeToConvert(I->getType(), CGT, AlreadyChecked))
       return false;
   
@@ -186,24 +181,23 @@
   return isSafeToConvert(RD, CGT, AlreadyChecked);
 }
 
-
-/// isFuncTypeArgumentConvertible - Return true if the specified type in a 
-/// function argument or result position can be converted to an IR type at this
+/// isFuncParamTypeConvertible - Return true if the specified type in a
+/// function parameter or result position can be converted to an IR type at this
 /// point.  This boils down to being whether it is complete, as well as whether
 /// we've temporarily deferred expanding the type because we're in a recursive
 /// context.
-bool CodeGenTypes::isFuncTypeArgumentConvertible(QualType Ty) {
+bool CodeGenTypes::isFuncParamTypeConvertible(QualType Ty) {
   // If this isn't a tagged type, we can convert it!
   const TagType *TT = Ty->getAs<TagType>();
-  if (TT == 0) return true;
-    
+  if (!TT) return true;
+
   // Incomplete types cannot be converted.
   if (TT->isIncompleteType())
     return false;
   
   // If this is an enum, then it is always safe to convert.
   const RecordType *RT = dyn_cast<RecordType>(TT);
-  if (RT == 0) return true;
+  if (!RT) return true;
 
   // Otherwise, we have to be careful.  If it is a struct that we're in the
   // process of expanding, then we can't convert the function type.  That's ok
@@ -217,17 +211,17 @@
 
 
 /// Code to verify a given function type is complete, i.e. the return type
-/// and all of the argument types are complete.  Also check to see if we are in
+/// and all of the parameter types are complete.  Also check to see if we are in
 /// a RS_StructPointer context, and if so whether any struct types have been
 /// pended.  If so, we don't want to ask the ABI lowering code to handle a type
 /// that cannot be converted to an IR type.
 bool CodeGenTypes::isFuncTypeConvertible(const FunctionType *FT) {
-  if (!isFuncTypeArgumentConvertible(FT->getResultType()))
+  if (!isFuncParamTypeConvertible(FT->getReturnType()))
     return false;
   
   if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT))
-    for (unsigned i = 0, e = FPT->getNumArgs(); i != e; i++)
-      if (!isFuncTypeArgumentConvertible(FPT->getArgType(i)))
+    for (unsigned i = 0, e = FPT->getNumParams(); i != e; i++)
+      if (!isFuncParamTypeConvertible(FPT->getParamType(i)))
         return false;
 
   return true;
@@ -248,6 +242,10 @@
       if (!ConvertType(ED->getIntegerType())->isIntegerTy(32))
         TypeCache.clear();
     }
+    // If necessary, provide the full definition of a type only used with a
+    // declaration so far.
+    if (CGDebugInfo *DI = CGM.getModuleDebugInfo())
+      DI->completeType(ED);
     return;
   }
   
@@ -306,7 +304,7 @@
     return TCI->second;
 
   // If we don't have it in the cache, convert it now.
-  llvm::Type *ResultType = 0;
+  llvm::Type *ResultType = nullptr;
   switch (Ty->getTypeClass()) {
   case Type::Record: // Handled above.
 #define TYPE(Class, Base)
@@ -479,11 +477,11 @@
 
       // Force conversion of all the relevant record types, to make sure
       // we re-convert the FunctionType when appropriate.
-      if (const RecordType *RT = FT->getResultType()->getAs<RecordType>())
+      if (const RecordType *RT = FT->getReturnType()->getAs<RecordType>())
         ConvertRecordDeclType(RT->getDecl());
       if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT))
-        for (unsigned i = 0, e = FPT->getNumArgs(); i != e; i++)
-          if (const RecordType *RT = FPT->getArgType(i)->getAs<RecordType>())
+        for (unsigned i = 0, e = FPT->getNumParams(); i != e; i++)
+          if (const RecordType *RT = FPT->getParamType(i)->getAs<RecordType>())
             ConvertRecordDeclType(RT->getDecl());
 
       // Return a placeholder type.
@@ -493,7 +491,7 @@
       break;
     }
 
-    // While we're converting the argument types for a function, we don't want
+    // While we're converting the parameter types for a function, we don't want
     // to recursively convert any pointed-to structs.  Converting directly-used
     // structs is ok though.
     if (!RecordsBeingLaidOut.insert(Ty)) {
@@ -631,7 +629,7 @@
   llvm::StructType *&Entry = RecordDeclTypes[Key];
 
   // If we don't have a StructType at all yet, create the forward declaration.
-  if (Entry == 0) {
+  if (!Entry) {
     Entry = llvm::StructType::create(getLLVMContext());
     addRecordTypeName(RD, Entry, "");
   }
@@ -640,7 +638,7 @@
   // If this is still a forward declaration, or the LLVM type is already
   // complete, there's nothing more to do.
   RD = RD->getDefinition();
-  if (RD == 0 || !RD->isCompleteDefinition() || !Ty->isOpaque())
+  if (!RD || !RD->isCompleteDefinition() || !Ty->isOpaque())
     return Ty;
   
   // If converting this type would cause us to infinitely loop, don't do it!
@@ -655,11 +653,10 @@
   
   // Force conversion of non-virtual base classes recursively.
   if (const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
-    for (CXXRecordDecl::base_class_const_iterator i = CRD->bases_begin(),
-         e = CRD->bases_end(); i != e; ++i) {
-      if (i->isVirtual()) continue;
+    for (const auto &I : CRD->bases()) {
+      if (I.isVirtual()) continue;
       
-      ConvertRecordDeclType(i->getType()->getAs<RecordType>()->getDecl());
+      ConvertRecordDeclType(I.getType()->getAs<RecordType>()->getDecl());
     }
   }
 
diff --git a/lib/CodeGen/CodeGenTypes.h b/lib/CodeGen/CodeGenTypes.h
index 94ca9e2..fe155b5 100644
--- a/lib/CodeGen/CodeGenTypes.h
+++ b/lib/CodeGen/CodeGenTypes.h
@@ -104,7 +104,7 @@
   
 private:
   /// TypeCache - This map keeps cache of llvm::Types
-  /// and maps llvm::Types to corresponding clang::Type.
+  /// and maps clang::Type to corresponding llvm::Type.
   llvm::DenseMap<const Type *, llvm::Type *> TypeCache;
 
 public:
@@ -136,8 +136,8 @@
   /// be converted to an LLVM type (i.e. doesn't depend on an incomplete tag
   /// type).
   bool isFuncTypeConvertible(const FunctionType *FT);
-  bool isFuncTypeArgumentConvertible(QualType Ty);
-  
+  bool isFuncParamTypeConvertible(QualType Ty);
+
   /// GetFunctionTypeForVTable - Get the LLVM function type for use in a vtable,
   /// given a CXXMethodDecl. If the method to has an incomplete return type,
   /// and/or incomplete argument types, this will return the opaque type.
@@ -175,10 +175,10 @@
 
   const CGFunctionInfo &arrangeGlobalDeclaration(GlobalDecl GD);
   const CGFunctionInfo &arrangeFunctionDeclaration(const FunctionDecl *FD);
-  const CGFunctionInfo &arrangeFunctionDeclaration(QualType ResTy,
-                                                   const FunctionArgList &Args,
-                                             const FunctionType::ExtInfo &Info,
-                                                   bool isVariadic);
+  const CGFunctionInfo &
+  arrangeFreeFunctionDeclaration(QualType ResTy, const FunctionArgList &Args,
+                                 const FunctionType::ExtInfo &Info,
+                                 bool isVariadic);
 
   const CGFunctionInfo &arrangeObjCMethodDeclaration(const ObjCMethodDecl *MD);
   const CGFunctionInfo &arrangeObjCMessageSendSignature(const ObjCMethodDecl *MD,
@@ -188,6 +188,10 @@
   const CGFunctionInfo &arrangeCXXConstructorDeclaration(
                                                     const CXXConstructorDecl *D,
                                                     CXXCtorType Type);
+  const CGFunctionInfo &arrangeCXXConstructorCall(const CallArgList &Args,
+                                                  const CXXConstructorDecl *D,
+                                                  CXXCtorType CtorKind,
+                                                  unsigned ExtraArgs);
   const CGFunctionInfo &arrangeCXXDestructor(const CXXDestructorDecl *D,
                                              CXXDtorType Type);
 
@@ -216,6 +220,7 @@
   ///
   /// \param argTypes - must all actually be canonical as params
   const CGFunctionInfo &arrangeLLVMFunctionInfo(CanQualType returnType,
+                                                bool IsInstanceMethod,
                                                 ArrayRef<CanQualType> argTypes,
                                                 FunctionType::ExtInfo info,
                                                 RequiredArgs args);
diff --git a/lib/CodeGen/EHScopeStack.h b/lib/CodeGen/EHScopeStack.h
index e9d9a33..b9ccfb6 100644
--- a/lib/CodeGen/EHScopeStack.h
+++ b/lib/CodeGen/EHScopeStack.h
@@ -19,8 +19,8 @@
 #include "clang/Basic/LLVM.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/Value.h"
 #include "llvm/IR/Instructions.h"
+#include "llvm/IR/Value.h"
 
 namespace clang {
 namespace CodeGen {
@@ -65,9 +65,9 @@
 template <class T> struct DominatingValue : InvariantValue<T> {};
 
 template <class T, bool mightBeInstruction =
-            llvm::is_base_of<llvm::Value, T>::value &&
-            !llvm::is_base_of<llvm::Constant, T>::value &&
-            !llvm::is_base_of<llvm::BasicBlock, T>::value>
+            std::is_base_of<llvm::Value, T>::value &&
+            !std::is_base_of<llvm::Constant, T>::value &&
+            !std::is_base_of<llvm::BasicBlock, T>::value>
 struct DominatingPointer;
 template <class T> struct DominatingPointer<T,false> : InvariantValue<T*> {};
 // template <class T> struct DominatingPointer<T,true> at end of file
@@ -182,7 +182,7 @@
     typedef typename DominatingValue<A0>::saved_type A0_saved;
     A0_saved a0_saved;
 
-    void Emit(CodeGenFunction &CGF, Flags flags) {
+    void Emit(CodeGenFunction &CGF, Flags flags) override {
       A0 a0 = DominatingValue<A0>::restore(CGF, a0_saved);
       T(a0).Emit(CGF, flags);
     }
@@ -199,7 +199,7 @@
     A0_saved a0_saved;
     A1_saved a1_saved;
 
-    void Emit(CodeGenFunction &CGF, Flags flags) {
+    void Emit(CodeGenFunction &CGF, Flags flags) override {
       A0 a0 = DominatingValue<A0>::restore(CGF, a0_saved);
       A1 a1 = DominatingValue<A1>::restore(CGF, a1_saved);
       T(a0, a1).Emit(CGF, flags);
@@ -219,7 +219,7 @@
     A1_saved a1_saved;
     A2_saved a2_saved;
 
-    void Emit(CodeGenFunction &CGF, Flags flags) {
+    void Emit(CodeGenFunction &CGF, Flags flags) override {
       A0 a0 = DominatingValue<A0>::restore(CGF, a0_saved);
       A1 a1 = DominatingValue<A1>::restore(CGF, a1_saved);
       A2 a2 = DominatingValue<A2>::restore(CGF, a2_saved);
@@ -242,7 +242,7 @@
     A2_saved a2_saved;
     A3_saved a3_saved;
 
-    void Emit(CodeGenFunction &CGF, Flags flags) {
+    void Emit(CodeGenFunction &CGF, Flags flags) override {
       A0 a0 = DominatingValue<A0>::restore(CGF, a0_saved);
       A1 a1 = DominatingValue<A1>::restore(CGF, a1_saved);
       A2 a2 = DominatingValue<A2>::restore(CGF, a2_saved);
@@ -301,8 +301,8 @@
   void *pushCleanup(CleanupKind K, size_t DataSize);
 
 public:
-  EHScopeStack() : StartOfBuffer(0), EndOfBuffer(0), StartOfData(0),
-                   InnermostNormalCleanup(stable_end()),
+  EHScopeStack() : StartOfBuffer(nullptr), EndOfBuffer(nullptr),
+                   StartOfData(nullptr), InnermostNormalCleanup(stable_end()),
                    InnermostEHScope(stable_end()) {}
   ~EHScopeStack() { delete[] StartOfBuffer; }
 
diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp
index c9e52a8..e9fa1d4 100644
--- a/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/lib/CodeGen/ItaniumCXXABI.cpp
@@ -25,6 +25,7 @@
 #include "CodeGenModule.h"
 #include "clang/AST/Mangle.h"
 #include "clang/AST/Type.h"
+#include "llvm/IR/CallSite.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/Intrinsics.h"
 #include "llvm/IR/Value.h"
@@ -52,128 +53,154 @@
     CGCXXABI(CGM), UseARMMethodPtrABI(UseARMMethodPtrABI),
     UseARMGuardVarABI(UseARMGuardVarABI) { }
 
-  bool isReturnTypeIndirect(const CXXRecordDecl *RD) const {
-    // Structures with either a non-trivial destructor or a non-trivial
-    // copy constructor are always indirect.
-    return !RD->hasTrivialDestructor() || RD->hasNonTrivialCopyConstructor();
-  }
+  bool classifyReturnType(CGFunctionInfo &FI) const override;
 
-  RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const {
+  RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const override {
     // Structures with either a non-trivial destructor or a non-trivial
     // copy constructor are always indirect.
-    if (!RD->hasTrivialDestructor() || RD->hasNonTrivialCopyConstructor())
+    // FIXME: Use canCopyArgument() when it is fixed to handle lazily declared
+    // special members.
+    if (RD->hasNonTrivialDestructor() || RD->hasNonTrivialCopyConstructor())
       return RAA_Indirect;
     return RAA_Default;
   }
 
-  bool isZeroInitializable(const MemberPointerType *MPT);
+  bool isZeroInitializable(const MemberPointerType *MPT) override;
 
-  llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT);
+  llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT) override;
 
-  llvm::Value *EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
-                                               llvm::Value *&This,
-                                               llvm::Value *MemFnPtr,
-                                               const MemberPointerType *MPT);
+  llvm::Value *
+    EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
+                                    const Expr *E,
+                                    llvm::Value *&This,
+                                    llvm::Value *MemFnPtr,
+                                    const MemberPointerType *MPT) override;
 
-  llvm::Value *EmitMemberDataPointerAddress(CodeGenFunction &CGF,
-                                            llvm::Value *Base,
-                                            llvm::Value *MemPtr,
-                                            const MemberPointerType *MPT);
+  llvm::Value *
+    EmitMemberDataPointerAddress(CodeGenFunction &CGF, const Expr *E,
+                                 llvm::Value *Base,
+                                 llvm::Value *MemPtr,
+                                 const MemberPointerType *MPT) override;
 
   llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF,
                                            const CastExpr *E,
-                                           llvm::Value *Src);
+                                           llvm::Value *Src) override;
   llvm::Constant *EmitMemberPointerConversion(const CastExpr *E,
-                                              llvm::Constant *Src);
+                                              llvm::Constant *Src) override;
 
-  llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT);
+  llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT) override;
 
-  llvm::Constant *EmitMemberPointer(const CXXMethodDecl *MD);
+  llvm::Constant *EmitMemberPointer(const CXXMethodDecl *MD) override;
   llvm::Constant *EmitMemberDataPointer(const MemberPointerType *MPT,
-                                        CharUnits offset);
-  llvm::Constant *EmitMemberPointer(const APValue &MP, QualType MPT);
+                                        CharUnits offset) override;
+  llvm::Constant *EmitMemberPointer(const APValue &MP, QualType MPT) override;
   llvm::Constant *BuildMemberPointer(const CXXMethodDecl *MD,
                                      CharUnits ThisAdjustment);
 
   llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF,
-                                           llvm::Value *L,
-                                           llvm::Value *R,
+                                           llvm::Value *L, llvm::Value *R,
                                            const MemberPointerType *MPT,
-                                           bool Inequality);
+                                           bool Inequality) override;
 
   llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
-                                          llvm::Value *Addr,
-                                          const MemberPointerType *MPT);
+                                         llvm::Value *Addr,
+                                         const MemberPointerType *MPT) override;
 
-  llvm::Value *adjustToCompleteObject(CodeGenFunction &CGF,
-                                      llvm::Value *ptr,
-                                      QualType type);
+  llvm::Value *adjustToCompleteObject(CodeGenFunction &CGF, llvm::Value *ptr,
+                                      QualType type) override;
 
-  llvm::Value *GetVirtualBaseClassOffset(CodeGenFunction &CGF,
-                                         llvm::Value *This,
-                                         const CXXRecordDecl *ClassDecl,
-                                         const CXXRecordDecl *BaseClassDecl);
+  void EmitFundamentalRTTIDescriptor(QualType Type);
+  void EmitFundamentalRTTIDescriptors();
+  llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty) override;
+
+  bool shouldTypeidBeNullChecked(bool IsDeref, QualType SrcRecordTy) override;
+  void EmitBadTypeidCall(CodeGenFunction &CGF) override;
+  llvm::Value *EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy,
+                          llvm::Value *ThisPtr,
+                          llvm::Type *StdTypeInfoPtrTy) override;
+
+  bool shouldDynamicCastCallBeNullChecked(bool SrcIsPtr,
+                                          QualType SrcRecordTy) override;
+
+  llvm::Value *EmitDynamicCastCall(CodeGenFunction &CGF, llvm::Value *Value,
+                                   QualType SrcRecordTy, QualType DestTy,
+                                   QualType DestRecordTy,
+                                   llvm::BasicBlock *CastEnd) override;
+
+  llvm::Value *EmitDynamicCastToVoid(CodeGenFunction &CGF, llvm::Value *Value,
+                                     QualType SrcRecordTy,
+                                     QualType DestTy) override;
+
+  bool EmitBadCastCall(CodeGenFunction &CGF) override;
+
+  llvm::Value *
+    GetVirtualBaseClassOffset(CodeGenFunction &CGF, llvm::Value *This,
+                              const CXXRecordDecl *ClassDecl,
+                              const CXXRecordDecl *BaseClassDecl) override;
 
   void BuildConstructorSignature(const CXXConstructorDecl *Ctor,
-                                 CXXCtorType T,
-                                 CanQualType &ResTy,
-                                 SmallVectorImpl<CanQualType> &ArgTys);
+                                 CXXCtorType T, CanQualType &ResTy,
+                                 SmallVectorImpl<CanQualType> &ArgTys) override;
 
-  void EmitCXXConstructors(const CXXConstructorDecl *D);
+  void EmitCXXConstructors(const CXXConstructorDecl *D) override;
 
   void BuildDestructorSignature(const CXXDestructorDecl *Dtor,
-                                CXXDtorType T,
-                                CanQualType &ResTy,
-                                SmallVectorImpl<CanQualType> &ArgTys);
+                                CXXDtorType T, CanQualType &ResTy,
+                                SmallVectorImpl<CanQualType> &ArgTys) override;
 
   bool useThunkForDtorVariant(const CXXDestructorDecl *Dtor,
-                              CXXDtorType DT) const {
+                              CXXDtorType DT) const override {
     // Itanium does not emit any destructor variant as an inline thunk.
     // Delegating may occur as an optimization, but all variants are either
     // emitted with external linkage or as linkonce if they are inline and used.
     return false;
   }
 
-  void EmitCXXDestructors(const CXXDestructorDecl *D);
+  void EmitCXXDestructors(const CXXDestructorDecl *D) override;
 
-  void BuildInstanceFunctionParams(CodeGenFunction &CGF,
-                                   QualType &ResTy,
-                                   FunctionArgList &Params);
+  void addImplicitStructorParams(CodeGenFunction &CGF, QualType &ResTy,
+                                 FunctionArgList &Params) override;
 
-  void EmitInstanceFunctionProlog(CodeGenFunction &CGF);
+  void EmitInstanceFunctionProlog(CodeGenFunction &CGF) override;
 
-  void EmitConstructorCall(CodeGenFunction &CGF,
-                           const CXXConstructorDecl *D, CXXCtorType Type,
-                           bool ForVirtualBase, bool Delegating,
-                           llvm::Value *This,
-                           CallExpr::const_arg_iterator ArgBeg,
-                           CallExpr::const_arg_iterator ArgEnd);
+  unsigned addImplicitConstructorArgs(CodeGenFunction &CGF,
+                                      const CXXConstructorDecl *D,
+                                      CXXCtorType Type, bool ForVirtualBase,
+                                      bool Delegating,
+                                      CallArgList &Args) override;
 
-  void emitVTableDefinitions(CodeGenVTables &CGVT, const CXXRecordDecl *RD);
+  void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD,
+                          CXXDtorType Type, bool ForVirtualBase,
+                          bool Delegating, llvm::Value *This) override;
+
+  void emitVTableDefinitions(CodeGenVTables &CGVT,
+                             const CXXRecordDecl *RD) override;
 
   llvm::Value *getVTableAddressPointInStructor(
       CodeGenFunction &CGF, const CXXRecordDecl *VTableClass,
       BaseSubobject Base, const CXXRecordDecl *NearestVBase,
-      bool &NeedsVirtualOffset);
+      bool &NeedsVirtualOffset) override;
 
   llvm::Constant *
   getVTableAddressPointForConstExpr(BaseSubobject Base,
-                                    const CXXRecordDecl *VTableClass);
+                                    const CXXRecordDecl *VTableClass) override;
 
   llvm::GlobalVariable *getAddrOfVTable(const CXXRecordDecl *RD,
-                                        CharUnits VPtrOffset);
+                                        CharUnits VPtrOffset) override;
 
   llvm::Value *getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD,
-                                         llvm::Value *This, llvm::Type *Ty);
+                                         llvm::Value *This,
+                                         llvm::Type *Ty) override;
 
   void EmitVirtualDestructorCall(CodeGenFunction &CGF,
                                  const CXXDestructorDecl *Dtor,
                                  CXXDtorType DtorType, SourceLocation CallLoc,
-                                 llvm::Value *This);
+                                 llvm::Value *This) override;
 
-  void emitVirtualInheritanceTables(const CXXRecordDecl *RD);
+  void emitVirtualInheritanceTables(const CXXRecordDecl *RD) override;
 
-  void setThunkLinkage(llvm::Function *Thunk, bool ForVTable) {
+  void setThunkLinkage(llvm::Function *Thunk, bool ForVTable, GlobalDecl GD,
+                       bool ReturnAdjustment) override {
     // Allow inlining of thunks by emitting them with available_externally
     // linkage together with vtables when needed.
     if (ForVTable)
@@ -181,38 +208,71 @@
   }
 
   llvm::Value *performThisAdjustment(CodeGenFunction &CGF, llvm::Value *This,
-                                     const ThisAdjustment &TA);
+                                     const ThisAdjustment &TA) override;
 
   llvm::Value *performReturnAdjustment(CodeGenFunction &CGF, llvm::Value *Ret,
-                                       const ReturnAdjustment &RA);
+                                       const ReturnAdjustment &RA) override;
 
-  StringRef GetPureVirtualCallName() { return "__cxa_pure_virtual"; }
-  StringRef GetDeletedVirtualCallName() { return "__cxa_deleted_virtual"; }
+  StringRef GetPureVirtualCallName() override { return "__cxa_pure_virtual"; }
+  StringRef GetDeletedVirtualCallName() override
+    { return "__cxa_deleted_virtual"; }
 
-  CharUnits getArrayCookieSizeImpl(QualType elementType);
+  CharUnits getArrayCookieSizeImpl(QualType elementType) override;
   llvm::Value *InitializeArrayCookie(CodeGenFunction &CGF,
                                      llvm::Value *NewPtr,
                                      llvm::Value *NumElements,
                                      const CXXNewExpr *expr,
-                                     QualType ElementType);
+                                     QualType ElementType) override;
   llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF,
                                    llvm::Value *allocPtr,
-                                   CharUnits cookieSize);
+                                   CharUnits cookieSize) override;
 
   void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
-                       llvm::GlobalVariable *DeclPtr, bool PerformInit);
+                       llvm::GlobalVariable *DeclPtr,
+                       bool PerformInit) override;
   void registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D,
-                          llvm::Constant *dtor, llvm::Constant *addr);
+                          llvm::Constant *dtor, llvm::Constant *addr) override;
 
   llvm::Function *getOrCreateThreadLocalWrapper(const VarDecl *VD,
                                                 llvm::GlobalVariable *Var);
   void EmitThreadLocalInitFuncs(
-      llvm::ArrayRef<std::pair<const VarDecl *, llvm::GlobalVariable *> > Decls,
-      llvm::Function *InitFunc);
-  LValue EmitThreadLocalDeclRefExpr(CodeGenFunction &CGF,
-                                    const DeclRefExpr *DRE);
+      ArrayRef<std::pair<const VarDecl *, llvm::GlobalVariable *> > Decls,
+      llvm::Function *InitFunc) override;
+  LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF, const VarDecl *VD,
+                                      QualType LValType) override;
 
-  bool NeedsVTTParameter(GlobalDecl GD);
+  bool NeedsVTTParameter(GlobalDecl GD) override;
+
+  /**************************** RTTI Uniqueness ******************************/
+
+protected:
+  /// Returns true if the ABI requires RTTI type_info objects to be unique
+  /// across a program.
+  virtual bool shouldRTTIBeUnique() const { return true; }
+
+public:
+  /// What sort of unique-RTTI behavior should we use?
+  enum RTTIUniquenessKind {
+    /// We are guaranteeing, or need to guarantee, that the RTTI string
+    /// is unique.
+    RUK_Unique,
+
+    /// We are not guaranteeing uniqueness for the RTTI string, so we
+    /// can demote to hidden visibility but must use string comparisons.
+    RUK_NonUniqueHidden,
+
+    /// We are not guaranteeing uniqueness for the RTTI string, so we
+    /// have to use string comparisons, but we also have to emit it with
+    /// non-hidden visibility.
+    RUK_NonUniqueVisible
+  };
+
+  /// Return the required visibility status for the given type and linkage in
+  /// the current ABI.
+  RTTIUniquenessKind
+  classifyRTTIUniqueness(QualType CanTy,
+                         llvm::GlobalValue::LinkageTypes Linkage) const;
+  friend class ItaniumRTTIBuilder;
 };
 
 class ARMCXXABI : public ItaniumCXXABI {
@@ -221,22 +281,31 @@
     ItaniumCXXABI(CGM, /* UseARMMethodPtrABI = */ true,
                   /* UseARMGuardVarABI = */ true) {}
 
-  bool HasThisReturn(GlobalDecl GD) const {
+  bool HasThisReturn(GlobalDecl GD) const override {
     return (isa<CXXConstructorDecl>(GD.getDecl()) || (
               isa<CXXDestructorDecl>(GD.getDecl()) &&
               GD.getDtorType() != Dtor_Deleting));
   }
 
-  void EmitReturnFromThunk(CodeGenFunction &CGF, RValue RV, QualType ResTy);
+  void EmitReturnFromThunk(CodeGenFunction &CGF, RValue RV,
+                           QualType ResTy) override;
 
-  CharUnits getArrayCookieSizeImpl(QualType elementType);
+  CharUnits getArrayCookieSizeImpl(QualType elementType) override;
   llvm::Value *InitializeArrayCookie(CodeGenFunction &CGF,
                                      llvm::Value *NewPtr,
                                      llvm::Value *NumElements,
                                      const CXXNewExpr *expr,
-                                     QualType ElementType);
+                                     QualType ElementType) override;
   llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF, llvm::Value *allocPtr,
-                                   CharUnits cookieSize);
+                                   CharUnits cookieSize) override;
+};
+
+class iOS64CXXABI : public ARMCXXABI {
+public:
+  iOS64CXXABI(CodeGen::CodeGenModule &CGM) : ARMCXXABI(CGM) {}
+
+  // ARM64 libraries are prepared for non-unique RTTI.
+  bool shouldRTTIBeUnique() const override { return false; }
 };
 }
 
@@ -248,6 +317,9 @@
   case TargetCXXABI::iOS:
     return new ARMCXXABI(CGM);
 
+  case TargetCXXABI::iOS64:
+    return new iOS64CXXABI(CGM);
+
   // Note that AArch64 uses the generic ItaniumCXXABI class since it doesn't
   // include the other 32-bit ARM oddities: constructor/destructor return values
   // and array cookies.
@@ -306,11 +378,9 @@
 ///
 /// If the member is non-virtual, memptr.ptr is the address of
 /// the function to call.
-llvm::Value *
-ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
-                                               llvm::Value *&This,
-                                               llvm::Value *MemFnPtr,
-                                               const MemberPointerType *MPT) {
+llvm::Value *ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
+    CodeGenFunction &CGF, const Expr *E, llvm::Value *&This,
+    llvm::Value *MemFnPtr, const MemberPointerType *MPT) {
   CGBuilderTy &Builder = CGF.Builder;
 
   const FunctionProtoType *FPT = 
@@ -362,8 +432,7 @@
 
   // Cast the adjusted this to a pointer to vtable pointer and load.
   llvm::Type *VTableTy = Builder.getInt8PtrTy();
-  llvm::Value *VTable = Builder.CreateBitCast(This, VTableTy->getPointerTo());
-  VTable = Builder.CreateLoad(VTable, "memptr.vtable");
+  llvm::Value *VTable = CGF.GetVTablePtr(This, VTableTy);
 
   // Apply the offset.
   llvm::Value *VTableOffset = FnAsInt;
@@ -392,10 +461,9 @@
 
 /// Compute an l-value by applying the given pointer-to-member to a
 /// base object.
-llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF,
-                                                         llvm::Value *Base,
-                                                         llvm::Value *MemPtr,
-                                           const MemberPointerType *MPT) {
+llvm::Value *ItaniumCXXABI::EmitMemberDataPointerAddress(
+    CodeGenFunction &CGF, const Expr *E, llvm::Value *Base, llvm::Value *MemPtr,
+    const MemberPointerType *MPT) {
   assert(MemPtr->getType() == CGM.PtrDiffTy);
 
   CGBuilderTy &Builder = CGF.Builder;
@@ -755,6 +823,21 @@
   return Result;
 }
 
+bool ItaniumCXXABI::classifyReturnType(CGFunctionInfo &FI) const {
+  const CXXRecordDecl *RD = FI.getReturnType()->getAsCXXRecordDecl();
+  if (!RD)
+    return false;
+
+  // Return indirectly if we have a non-trivial copy ctor or non-trivial dtor.
+  // FIXME: Use canCopyArgument() when it is fixed to handle lazily declared
+  // special members.
+  if (RD->hasNonTrivialDestructor() || RD->hasNonTrivialCopyConstructor()) {
+    FI.getReturnInfo() = ABIArgInfo::getIndirect(0, /*ByVal=*/false);
+    return true;
+  }
+  return false;
+}
+
 /// The Itanium ABI requires non-zero initialization only for data
 /// member pointers, for which '0' is a valid offset.
 bool ItaniumCXXABI::isZeroInitializable(const MemberPointerType *MPT) {
@@ -780,6 +863,194 @@
   return CGF.Builder.CreateInBoundsGEP(ptr, offset);
 }
 
+static llvm::Constant *getItaniumDynamicCastFn(CodeGenFunction &CGF) {
+  // void *__dynamic_cast(const void *sub,
+  //                      const abi::__class_type_info *src,
+  //                      const abi::__class_type_info *dst,
+  //                      std::ptrdiff_t src2dst_offset);
+  
+  llvm::Type *Int8PtrTy = CGF.Int8PtrTy;
+  llvm::Type *PtrDiffTy = 
+    CGF.ConvertType(CGF.getContext().getPointerDiffType());
+
+  llvm::Type *Args[4] = { Int8PtrTy, Int8PtrTy, Int8PtrTy, PtrDiffTy };
+
+  llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, Args, false);
+
+  // Mark the function as nounwind readonly.
+  llvm::Attribute::AttrKind FuncAttrs[] = { llvm::Attribute::NoUnwind,
+                                            llvm::Attribute::ReadOnly };
+  llvm::AttributeSet Attrs = llvm::AttributeSet::get(
+      CGF.getLLVMContext(), llvm::AttributeSet::FunctionIndex, FuncAttrs);
+
+  return CGF.CGM.CreateRuntimeFunction(FTy, "__dynamic_cast", Attrs);
+}
+
+static llvm::Constant *getBadCastFn(CodeGenFunction &CGF) {
+  // void __cxa_bad_cast();
+  llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.VoidTy, false);
+  return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_bad_cast");
+}
+
+/// \brief Compute the src2dst_offset hint as described in the
+/// Itanium C++ ABI [2.9.7]
+static CharUnits computeOffsetHint(ASTContext &Context,
+                                   const CXXRecordDecl *Src,
+                                   const CXXRecordDecl *Dst) {
+  CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
+                     /*DetectVirtual=*/false);
+
+  // If Dst is not derived from Src we can skip the whole computation below and
+  // return that Src is not a public base of Dst.  Record all inheritance paths.
+  if (!Dst->isDerivedFrom(Src, Paths))
+    return CharUnits::fromQuantity(-2ULL);
+
+  unsigned NumPublicPaths = 0;
+  CharUnits Offset;
+
+  // Now walk all possible inheritance paths.
+  for (CXXBasePaths::paths_iterator I = Paths.begin(), E = Paths.end(); I != E;
+       ++I) {
+    if (I->Access != AS_public) // Ignore non-public inheritance.
+      continue;
+
+    ++NumPublicPaths;
+
+    for (CXXBasePath::iterator J = I->begin(), JE = I->end(); J != JE; ++J) {
+      // If the path contains a virtual base class we can't give any hint.
+      // -1: no hint.
+      if (J->Base->isVirtual())
+        return CharUnits::fromQuantity(-1ULL);
+
+      if (NumPublicPaths > 1) // Won't use offsets, skip computation.
+        continue;
+
+      // Accumulate the base class offsets.
+      const ASTRecordLayout &L = Context.getASTRecordLayout(J->Class);
+      Offset += L.getBaseClassOffset(J->Base->getType()->getAsCXXRecordDecl());
+    }
+  }
+
+  // -2: Src is not a public base of Dst.
+  if (NumPublicPaths == 0)
+    return CharUnits::fromQuantity(-2ULL);
+
+  // -3: Src is a multiple public base type but never a virtual base type.
+  if (NumPublicPaths > 1)
+    return CharUnits::fromQuantity(-3ULL);
+
+  // Otherwise, the Src type is a unique public nonvirtual base type of Dst.
+  // Return the offset of Src from the origin of Dst.
+  return Offset;
+}
+
+static llvm::Constant *getBadTypeidFn(CodeGenFunction &CGF) {
+  // void __cxa_bad_typeid();
+  llvm::FunctionType *FTy = llvm::FunctionType::get(CGF.VoidTy, false);
+
+  return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_bad_typeid");
+}
+
+bool ItaniumCXXABI::shouldTypeidBeNullChecked(bool IsDeref,
+                                              QualType SrcRecordTy) {
+  return IsDeref;
+}
+
+void ItaniumCXXABI::EmitBadTypeidCall(CodeGenFunction &CGF) {
+  llvm::Value *Fn = getBadTypeidFn(CGF);
+  CGF.EmitRuntimeCallOrInvoke(Fn).setDoesNotReturn();
+  CGF.Builder.CreateUnreachable();
+}
+
+llvm::Value *ItaniumCXXABI::EmitTypeid(CodeGenFunction &CGF,
+                                       QualType SrcRecordTy,
+                                       llvm::Value *ThisPtr,
+                                       llvm::Type *StdTypeInfoPtrTy) {
+  llvm::Value *Value =
+      CGF.GetVTablePtr(ThisPtr, StdTypeInfoPtrTy->getPointerTo());
+
+  // Load the type info.
+  Value = CGF.Builder.CreateConstInBoundsGEP1_64(Value, -1ULL);
+  return CGF.Builder.CreateLoad(Value);
+}
+
+bool ItaniumCXXABI::shouldDynamicCastCallBeNullChecked(bool SrcIsPtr,
+                                                       QualType SrcRecordTy) {
+  return SrcIsPtr;
+}
+
+llvm::Value *ItaniumCXXABI::EmitDynamicCastCall(
+    CodeGenFunction &CGF, llvm::Value *Value, QualType SrcRecordTy,
+    QualType DestTy, QualType DestRecordTy, llvm::BasicBlock *CastEnd) {
+  llvm::Type *PtrDiffLTy =
+      CGF.ConvertType(CGF.getContext().getPointerDiffType());
+  llvm::Type *DestLTy = CGF.ConvertType(DestTy);
+
+  llvm::Value *SrcRTTI =
+      CGF.CGM.GetAddrOfRTTIDescriptor(SrcRecordTy.getUnqualifiedType());
+  llvm::Value *DestRTTI =
+      CGF.CGM.GetAddrOfRTTIDescriptor(DestRecordTy.getUnqualifiedType());
+
+  // Compute the offset hint.
+  const CXXRecordDecl *SrcDecl = SrcRecordTy->getAsCXXRecordDecl();
+  const CXXRecordDecl *DestDecl = DestRecordTy->getAsCXXRecordDecl();
+  llvm::Value *OffsetHint = llvm::ConstantInt::get(
+      PtrDiffLTy,
+      computeOffsetHint(CGF.getContext(), SrcDecl, DestDecl).getQuantity());
+
+  // Emit the call to __dynamic_cast.
+  Value = CGF.EmitCastToVoidPtr(Value);
+
+  llvm::Value *args[] = {Value, SrcRTTI, DestRTTI, OffsetHint};
+  Value = CGF.EmitNounwindRuntimeCall(getItaniumDynamicCastFn(CGF), args);
+  Value = CGF.Builder.CreateBitCast(Value, DestLTy);
+
+  /// C++ [expr.dynamic.cast]p9:
+  ///   A failed cast to reference type throws std::bad_cast
+  if (DestTy->isReferenceType()) {
+    llvm::BasicBlock *BadCastBlock =
+        CGF.createBasicBlock("dynamic_cast.bad_cast");
+
+    llvm::Value *IsNull = CGF.Builder.CreateIsNull(Value);
+    CGF.Builder.CreateCondBr(IsNull, BadCastBlock, CastEnd);
+
+    CGF.EmitBlock(BadCastBlock);
+    EmitBadCastCall(CGF);
+  }
+
+  return Value;
+}
+
+llvm::Value *ItaniumCXXABI::EmitDynamicCastToVoid(CodeGenFunction &CGF,
+                                                  llvm::Value *Value,
+                                                  QualType SrcRecordTy,
+                                                  QualType DestTy) {
+  llvm::Type *PtrDiffLTy =
+      CGF.ConvertType(CGF.getContext().getPointerDiffType());
+  llvm::Type *DestLTy = CGF.ConvertType(DestTy);
+
+  // Get the vtable pointer.
+  llvm::Value *VTable = CGF.GetVTablePtr(Value, PtrDiffLTy->getPointerTo());
+
+  // Get the offset-to-top from the vtable.
+  llvm::Value *OffsetToTop =
+      CGF.Builder.CreateConstInBoundsGEP1_64(VTable, -2ULL);
+  OffsetToTop = CGF.Builder.CreateLoad(OffsetToTop, "offset.to.top");
+
+  // Finally, add the offset to the pointer.
+  Value = CGF.EmitCastToVoidPtr(Value);
+  Value = CGF.Builder.CreateInBoundsGEP(Value, OffsetToTop);
+
+  return CGF.Builder.CreateBitCast(Value, DestLTy);
+}
+
+bool ItaniumCXXABI::EmitBadCastCall(CodeGenFunction &CGF) {
+  llvm::Value *Fn = getBadCastFn(CGF);
+  CGF.EmitRuntimeCallOrInvoke(Fn).setDoesNotReturn();
+  CGF.Builder.CreateUnreachable();
+  return true;
+}
+
 llvm::Value *
 ItaniumCXXABI::GetVirtualBaseClassOffset(CodeGenFunction &CGF,
                                          llvm::Value *This,
@@ -804,34 +1075,35 @@
 
 /// The generic ABI passes 'this', plus a VTT if it's initializing a
 /// base subobject.
-void ItaniumCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor,
-                                              CXXCtorType Type,
-                                              CanQualType &ResTy,
-                                SmallVectorImpl<CanQualType> &ArgTys) {
+void
+ItaniumCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor,
+                                         CXXCtorType Type, CanQualType &ResTy,
+                                         SmallVectorImpl<CanQualType> &ArgTys) {
   ASTContext &Context = getContext();
 
-  // 'this' parameter is already there, as well as 'this' return if
-  // HasThisReturn(GlobalDecl(Ctor, Type)) is true
+  // All parameters are already in place except VTT, which goes after 'this'.
+  // 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 (Type == Ctor_Base && Ctor->getParent()->getNumVBases() != 0)
-    ArgTys.push_back(Context.getPointerType(Context.VoidPtrTy));
+    ArgTys.insert(ArgTys.begin() + 1,
+                  Context.getPointerType(Context.VoidPtrTy));
 }
 
 void ItaniumCXXABI::EmitCXXConstructors(const CXXConstructorDecl *D) {
   // Just make sure we're in sync with TargetCXXABI.
   assert(CGM.getTarget().getCXXABI().hasConstructorVariants());
 
+  // The constructor used for constructing this as a base class;
+  // ignores virtual bases.
+  CGM.EmitGlobal(GlobalDecl(D, Ctor_Base));
+
   // The constructor used for constructing this as a complete class;
   // constucts the virtual bases, then calls the base constructor.
   if (!D->getParent()->isAbstract()) {
     // We don't need to emit the complete ctor if the class is abstract.
     CGM.EmitGlobal(GlobalDecl(D, Ctor_Complete));
   }
-
-  // The constructor used for constructing this as a base class;
-  // ignores virtual bases.
-  CGM.EmitGlobal(GlobalDecl(D, Ctor_Base));
 }
 
 /// The generic ABI passes 'this', plus a VTT if it's destroying a
@@ -851,29 +1123,26 @@
 }
 
 void ItaniumCXXABI::EmitCXXDestructors(const CXXDestructorDecl *D) {
-  // The destructor in a virtual table is always a 'deleting'
-  // destructor, which calls the complete destructor and then uses the
-  // appropriate operator delete.
-  if (D->isVirtual())
-    CGM.EmitGlobal(GlobalDecl(D, Dtor_Deleting));
+  // The destructor used for destructing this as a base class; ignores
+  // virtual bases.
+  CGM.EmitGlobal(GlobalDecl(D, Dtor_Base));
 
   // The destructor used for destructing this as a most-derived class;
   // call the base destructor and then destructs any virtual bases.
   CGM.EmitGlobal(GlobalDecl(D, Dtor_Complete));
 
-  // The destructor used for destructing this as a base class; ignores
-  // virtual bases.
-  CGM.EmitGlobal(GlobalDecl(D, Dtor_Base));
+  // The destructor in a virtual table is always a 'deleting'
+  // destructor, which calls the complete destructor and then uses the
+  // appropriate operator delete.
+  if (D->isVirtual())
+    CGM.EmitGlobal(GlobalDecl(D, Dtor_Deleting));
 }
 
-void ItaniumCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF,
-                                                QualType &ResTy,
-                                                FunctionArgList &Params) {
-  /// Create the 'this' variable.
-  BuildThisParam(CGF, Params);
-
+void ItaniumCXXABI::addImplicitStructorParams(CodeGenFunction &CGF,
+                                              QualType &ResTy,
+                                              FunctionArgList &Params) {
   const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl());
-  assert(MD->isInstance());
+  assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD));
 
   // Check if we need a VTT parameter as well.
   if (NeedsVTTParameter(CGF.CurGD)) {
@@ -882,10 +1151,10 @@
     // FIXME: avoid the fake decl
     QualType T = Context.getPointerType(Context.VoidPtrTy);
     ImplicitParamDecl *VTTDecl
-      = ImplicitParamDecl::Create(Context, 0, MD->getLocation(),
+      = ImplicitParamDecl::Create(Context, nullptr, MD->getLocation(),
                                   &Context.Idents.get("vtt"), T);
-    Params.push_back(VTTDecl);
-    getVTTDecl(CGF) = VTTDecl;
+    Params.insert(Params.begin() + 1, VTTDecl);
+    getStructorImplicitParamDecl(CGF) = VTTDecl;
   }
 }
 
@@ -894,10 +1163,9 @@
   EmitThisParam(CGF);
 
   /// Initialize the 'vtt' slot if needed.
-  if (getVTTDecl(CGF)) {
-    getVTTValue(CGF)
-      = CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(getVTTDecl(CGF)),
-                               "vtt");
+  if (getStructorImplicitParamDecl(CGF)) {
+    getStructorImplicitParamValue(CGF) = CGF.Builder.CreateLoad(
+        CGF.GetAddrOfLocalVar(getStructorImplicitParamDecl(CGF)), "vtt");
   }
 
   /// If this is a function that the ABI specifies returns 'this', initialize
@@ -912,21 +1180,39 @@
     CGF.Builder.CreateStore(getThisValue(CGF), CGF.ReturnValue);
 }
 
-void ItaniumCXXABI::EmitConstructorCall(CodeGenFunction &CGF,
-                                        const CXXConstructorDecl *D,
-                                        CXXCtorType Type,
-                                        bool ForVirtualBase, bool Delegating,
-                                        llvm::Value *This,
-                                        CallExpr::const_arg_iterator ArgBeg,
-                                        CallExpr::const_arg_iterator ArgEnd) {
-  llvm::Value *VTT = CGF.GetVTTParameter(GlobalDecl(D, Type), ForVirtualBase,
-                                         Delegating);
+unsigned ItaniumCXXABI::addImplicitConstructorArgs(
+    CodeGenFunction &CGF, const CXXConstructorDecl *D, CXXCtorType Type,
+    bool ForVirtualBase, bool Delegating, CallArgList &Args) {
+  if (!NeedsVTTParameter(GlobalDecl(D, Type)))
+    return 0;
+
+  // Insert the implicit 'vtt' argument as the second argument.
+  llvm::Value *VTT =
+      CGF.GetVTTParameter(GlobalDecl(D, Type), ForVirtualBase, Delegating);
   QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
-  llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Type);
+  Args.insert(Args.begin() + 1,
+              CallArg(RValue::get(VTT), VTTTy, /*needscopy=*/false));
+  return 1;  // Added one arg.
+}
+
+void ItaniumCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
+                                       const CXXDestructorDecl *DD,
+                                       CXXDtorType Type, bool ForVirtualBase,
+                                       bool Delegating, llvm::Value *This) {
+  GlobalDecl GD(DD, Type);
+  llvm::Value *VTT = CGF.GetVTTParameter(GD, ForVirtualBase, Delegating);
+  QualType VTTTy = getContext().getPointerType(getContext().VoidPtrTy);
+
+  llvm::Value *Callee = nullptr;
+  if (getContext().getLangOpts().AppleKext)
+    Callee = CGF.BuildAppleKextVirtualDestructorCall(DD, Type, DD->getParent());
+
+  if (!Callee)
+    Callee = CGM.GetAddrOfCXXDestructor(DD, Type);
 
   // FIXME: Provide a source location here.
-  CGF.EmitCXXMemberCall(D, SourceLocation(), Callee, ReturnValueSlot(),
-                        This, VTT, VTTTy, ArgBeg, ArgEnd);
+  CGF.EmitCXXMemberCall(DD, SourceLocation(), Callee, ReturnValueSlot(), This,
+                        VTT, VTTTy, nullptr, nullptr);
 }
 
 void ItaniumCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,
@@ -938,18 +1224,20 @@
   ItaniumVTableContext &VTContext = CGM.getItaniumVTableContext();
   const VTableLayout &VTLayout = VTContext.getVTableLayout(RD);
   llvm::GlobalVariable::LinkageTypes Linkage = CGM.getVTableLinkage(RD);
+  llvm::Constant *RTTI =
+      CGM.GetAddrOfRTTIDescriptor(CGM.getContext().getTagDeclType(RD));
 
   // Create and set the initializer.
   llvm::Constant *Init = CGVT.CreateVTableInitializer(
       RD, VTLayout.vtable_component_begin(), VTLayout.getNumVTableComponents(),
-      VTLayout.vtable_thunk_begin(), VTLayout.getNumVTableThunks());
+      VTLayout.vtable_thunk_begin(), VTLayout.getNumVTableThunks(), RTTI);
   VTable->setInitializer(Init);
 
   // Set the correct linkage.
   VTable->setLinkage(Linkage);
 
   // Set the right visibility.
-  CGM.setTypeVisibility(VTable, RD, CodeGenModule::TVK_ForVTable);
+  CGM.setGlobalVisibility(VTable, RD);
 
   // If this is the magic class __cxxabiv1::__fundamental_type_info,
   // we will emit the typeinfo for the fundamental types. This is the
@@ -960,7 +1248,7 @@
       isa<NamespaceDecl>(DC) && cast<NamespaceDecl>(DC)->getIdentifier() &&
       cast<NamespaceDecl>(DC)->getIdentifier()->isStr("__cxxabiv1") &&
       DC->getParent()->isTranslationUnit())
-    CGM.EmitFundamentalRTTIDescriptors();
+    EmitFundamentalRTTIDescriptors();
 }
 
 llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructor(
@@ -1035,6 +1323,12 @@
   VTable = CGM.CreateOrReplaceCXXRuntimeVariable(
       Name, ArrayType, llvm::GlobalValue::ExternalLinkage);
   VTable->setUnnamedAddr(true);
+
+  if (RD->hasAttr<DLLImportAttr>())
+    VTable->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
+  else if (RD->hasAttr<DLLExportAttr>())
+    VTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
+
   return VTable;
 }
 
@@ -1066,7 +1360,8 @@
       getVirtualFunctionPointer(CGF, GlobalDecl(Dtor, DtorType), This, Ty);
 
   CGF.EmitCXXMemberCall(Dtor, CallLoc, Callee, ReturnValueSlot(), This,
-                        /*ImplicitParam=*/0, QualType(), 0, 0);
+                        /*ImplicitParam=*/nullptr, QualType(), nullptr,
+                        nullptr);
 }
 
 void ItaniumCXXABI::emitVirtualInheritanceTables(const CXXRecordDecl *RD) {
@@ -1312,7 +1607,7 @@
     llvm::GlobalVariable *Guard;
     CallGuardAbort(llvm::GlobalVariable *Guard) : Guard(Guard) {}
 
-    void Emit(CodeGenFunction &CGF, Flags flags) {
+    void Emit(CodeGenFunction &CGF, Flags flags) override {
       CGF.EmitNounwindRuntimeCall(getGuardAbortFn(CGF.CGM, Guard->getType()),
                                   Guard);
     }
@@ -1372,25 +1667,7 @@
   }
 
   // Test whether the variable has completed initialization.
-  llvm::Value *isInitialized;
-
-  // ARM C++ ABI 3.2.3.1:
-  //   To support the potential use of initialization guard variables
-  //   as semaphores that are the target of ARM SWP and LDREX/STREX
-  //   synchronizing instructions we define a static initialization
-  //   guard variable to be a 4-byte aligned, 4- byte word with the
-  //   following inline access protocol.
-  //     #define INITIALIZED 1
-  //     if ((obj_guard & INITIALIZED) != INITIALIZED) {
-  //       if (__cxa_guard_acquire(&obj_guard))
-  //         ...
-  //     }
-  if (UseARMGuardVarABI && !useInt8GuardVariable) {
-    llvm::Value *V = Builder.CreateLoad(guard);
-    llvm::Value *Test1 = llvm::ConstantInt::get(guardTy, 1);
-    V = Builder.CreateAnd(V, Test1);
-    isInitialized = Builder.CreateIsNull(V, "guard.uninitialized");
-
+  //
   // Itanium C++ ABI 3.3.2:
   //   The following is pseudo-code showing how these functions can be used:
   //     if (obj_guard.first_byte == 0) {
@@ -1405,23 +1682,46 @@
   //         __cxa_guard_release (&obj_guard);
   //       }
   //     }
-  } else {
-    // Load the first byte of the guard variable.
-    llvm::LoadInst *LI = 
+
+  // Load the first byte of the guard variable.
+  llvm::LoadInst *LI =
       Builder.CreateLoad(Builder.CreateBitCast(guard, CGM.Int8PtrTy));
-    LI->setAlignment(1);
+  LI->setAlignment(1);
 
-    // Itanium ABI:
-    //   An implementation supporting thread-safety on multiprocessor
-    //   systems must also guarantee that references to the initialized
-    //   object do not occur before the load of the initialization flag.
-    //
-    // In LLVM, we do this by marking the load Acquire.
-    if (threadsafe)
-      LI->setAtomic(llvm::Acquire);
+  // Itanium ABI:
+  //   An implementation supporting thread-safety on multiprocessor
+  //   systems must also guarantee that references to the initialized
+  //   object do not occur before the load of the initialization flag.
+  //
+  // In LLVM, we do this by marking the load Acquire.
+  if (threadsafe)
+    LI->setAtomic(llvm::Acquire);
 
-    isInitialized = Builder.CreateIsNull(LI, "guard.uninitialized");
-  }
+  // For ARM, we should only check the first bit, rather than the entire byte:
+  //
+  // ARM C++ ABI 3.2.3.1:
+  //   To support the potential use of initialization guard variables
+  //   as semaphores that are the target of ARM SWP and LDREX/STREX
+  //   synchronizing instructions we define a static initialization
+  //   guard variable to be a 4-byte aligned, 4-byte word with the
+  //   following inline access protocol.
+  //     #define INITIALIZED 1
+  //     if ((obj_guard & INITIALIZED) != INITIALIZED) {
+  //       if (__cxa_guard_acquire(&obj_guard))
+  //         ...
+  //     }
+  //
+  // and similarly for ARM64:
+  //
+  // ARM64 C++ ABI 3.2.2:
+  //   This ABI instead only specifies the value bit 0 of the static guard
+  //   variable; all other bits are platform defined. Bit 0 shall be 0 when the
+  //   variable is not initialized and 1 when it is.
+  llvm::Value *V =
+      (UseARMGuardVarABI && !useInt8GuardVariable)
+          ? Builder.CreateAnd(LI, llvm::ConstantInt::get(CGM.Int8Ty, 1))
+          : LI;
+  llvm::Value *isInitialized = Builder.CreateIsNull(V, "guard.uninitialized");
 
   llvm::BasicBlock *InitCheckBlock = CGF.createBasicBlock("init.check");
   llvm::BasicBlock *EndBlock = CGF.createBasicBlock("init.end");
@@ -1525,16 +1825,34 @@
   CGF.registerGlobalDtorWithAtExit(D, dtor, addr);
 }
 
+static bool isThreadWrapperReplaceable(const VarDecl *VD,
+                                       CodeGen::CodeGenModule &CGM) {
+  assert(!VD->isStaticLocal() && "static local VarDecls don't need wrappers!");
+  // OS X prefers to have references to thread local variables to go through
+  // the thread wrapper instead of directly referencing the backing variable.
+  return VD->getTLSKind() == VarDecl::TLS_Dynamic &&
+         CGM.getTarget().getTriple().isMacOSX();
+}
+
 /// Get the appropriate linkage for the wrapper function. This is essentially
-/// the weak form of the variable's linkage; every translation unit which wneeds
+/// the weak form of the variable's linkage; every translation unit which needs
 /// the wrapper emits a copy, and we want the linker to merge them.
-static llvm::GlobalValue::LinkageTypes getThreadLocalWrapperLinkage(
-    llvm::GlobalValue::LinkageTypes VarLinkage) {
-  if (llvm::GlobalValue::isLinkerPrivateLinkage(VarLinkage))
-    return llvm::GlobalValue::LinkerPrivateWeakLinkage;
+static llvm::GlobalValue::LinkageTypes
+getThreadLocalWrapperLinkage(const VarDecl *VD, CodeGen::CodeGenModule &CGM) {
+  llvm::GlobalValue::LinkageTypes VarLinkage =
+      CGM.getLLVMLinkageVarDefinition(VD, /*isConstant=*/false);
+
   // For internal linkage variables, we don't need an external or weak wrapper.
   if (llvm::GlobalValue::isLocalLinkage(VarLinkage))
     return VarLinkage;
+
+  // If the thread wrapper is replaceable, give it appropriate linkage.
+  if (isThreadWrapperReplaceable(VD, CGM)) {
+    if (llvm::GlobalVariable::isLinkOnceLinkage(VarLinkage) ||
+        llvm::GlobalVariable::isWeakODRLinkage(VarLinkage))
+      return llvm::GlobalVariable::WeakAnyLinkage;
+    return VarLinkage;
+  }
   return llvm::GlobalValue::WeakODRLinkage;
 }
 
@@ -1557,21 +1875,28 @@
     RetTy = RetTy->getPointerElementType();
 
   llvm::FunctionType *FnTy = llvm::FunctionType::get(RetTy, false);
-  llvm::Function *Wrapper = llvm::Function::Create(
-      FnTy, getThreadLocalWrapperLinkage(Var->getLinkage()), WrapperName.str(),
-      &CGM.getModule());
+  llvm::Function *Wrapper =
+      llvm::Function::Create(FnTy, getThreadLocalWrapperLinkage(VD, CGM),
+                             WrapperName.str(), &CGM.getModule());
   // Always resolve references to the wrapper at link time.
-  Wrapper->setVisibility(llvm::GlobalValue::HiddenVisibility);
+  if (!Wrapper->hasLocalLinkage() && !isThreadWrapperReplaceable(VD, CGM))
+    Wrapper->setVisibility(llvm::GlobalValue::HiddenVisibility);
   return Wrapper;
 }
 
 void ItaniumCXXABI::EmitThreadLocalInitFuncs(
-    llvm::ArrayRef<std::pair<const VarDecl *, llvm::GlobalVariable *> > Decls,
+    ArrayRef<std::pair<const VarDecl *, llvm::GlobalVariable *> > Decls,
     llvm::Function *InitFunc) {
   for (unsigned I = 0, N = Decls.size(); I != N; ++I) {
     const VarDecl *VD = Decls[I].first;
     llvm::GlobalVariable *Var = Decls[I].second;
 
+    // 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())
+      continue;
+
     // Mangle the name for the thread_local initialization function.
     SmallString<256> InitFnName;
     {
@@ -1583,14 +1908,13 @@
     // If we have a definition for the variable, emit the initialization
     // function as an alias to the global Init function (if any). Otherwise,
     // produce a declaration of the initialization function.
-    llvm::GlobalValue *Init = 0;
+    llvm::GlobalValue *Init = nullptr;
     bool InitIsInitFunc = false;
     if (VD->hasDefinition()) {
       InitIsInitFunc = true;
       if (InitFunc)
-        Init =
-            new llvm::GlobalAlias(InitFunc->getType(), Var->getLinkage(),
-                                  InitFnName.str(), InitFunc, &CGM.getModule());
+        Init = llvm::GlobalAlias::create(Var->getLinkage(), InitFnName.str(),
+                                         InitFunc);
     } else {
       // Emit a weak global function referring to the initialization function.
       // This function will not exist if the TU defining the thread_local
@@ -1639,9 +1963,9 @@
   }
 }
 
-LValue ItaniumCXXABI::EmitThreadLocalDeclRefExpr(CodeGenFunction &CGF,
-                                                 const DeclRefExpr *DRE) {
-  const VarDecl *VD = cast<VarDecl>(DRE->getDecl());
+LValue ItaniumCXXABI::EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
+                                                   const VarDecl *VD,
+                                                   QualType LValType) {
   QualType T = VD->getType();
   llvm::Type *Ty = CGF.getTypes().ConvertTypeForMem(T);
   llvm::Value *Val = CGF.CGM.GetAddrOfGlobalVar(VD, Ty);
@@ -1652,10 +1976,9 @@
 
   LValue LV;
   if (VD->getType()->isReferenceType())
-    LV = CGF.MakeNaturalAlignAddrLValue(Val, T);
+    LV = CGF.MakeNaturalAlignAddrLValue(Val, LValType);
   else
-    LV = CGF.MakeAddrLValue(Val, DRE->getType(),
-                            CGF.getContext().getDeclAlign(VD));
+    LV = CGF.MakeAddrLValue(Val, LValType, CGF.getContext().getDeclAlign(VD));
   // FIXME: need setObjCGCLValueClass?
   return LV;
 }
@@ -1679,3 +2002,996 @@
   
   return false;
 }
+
+namespace {
+class ItaniumRTTIBuilder {
+  CodeGenModule &CGM;  // Per-module state.
+  llvm::LLVMContext &VMContext;
+  const ItaniumCXXABI &CXXABI;  // Per-module state.
+
+  /// Fields - The fields of the RTTI descriptor currently being built.
+  SmallVector<llvm::Constant *, 16> Fields;
+
+  /// GetAddrOfTypeName - Returns the mangled type name of the given type.
+  llvm::GlobalVariable *
+  GetAddrOfTypeName(QualType Ty, llvm::GlobalVariable::LinkageTypes Linkage);
+
+  /// GetAddrOfExternalRTTIDescriptor - Returns the constant for the RTTI
+  /// descriptor of the given type.
+  llvm::Constant *GetAddrOfExternalRTTIDescriptor(QualType Ty);
+
+  /// BuildVTablePointer - Build the vtable pointer for the given type.
+  void BuildVTablePointer(const Type *Ty);
+
+  /// BuildSIClassTypeInfo - Build an abi::__si_class_type_info, used for single
+  /// inheritance, according to the Itanium C++ ABI, 2.9.5p6b.
+  void BuildSIClassTypeInfo(const CXXRecordDecl *RD);
+
+  /// BuildVMIClassTypeInfo - Build an abi::__vmi_class_type_info, used for
+  /// classes with bases that do not satisfy the abi::__si_class_type_info
+  /// constraints, according ti the Itanium C++ ABI, 2.9.5p5c.
+  void BuildVMIClassTypeInfo(const CXXRecordDecl *RD);
+
+  /// BuildPointerTypeInfo - Build an abi::__pointer_type_info struct, used
+  /// for pointer types.
+  void BuildPointerTypeInfo(QualType PointeeTy);
+
+  /// BuildObjCObjectTypeInfo - Build the appropriate kind of
+  /// type_info for an object type.
+  void BuildObjCObjectTypeInfo(const ObjCObjectType *Ty);
+
+  /// BuildPointerToMemberTypeInfo - Build an abi::__pointer_to_member_type_info
+  /// struct, used for member pointer types.
+  void BuildPointerToMemberTypeInfo(const MemberPointerType *Ty);
+
+public:
+  ItaniumRTTIBuilder(const ItaniumCXXABI &ABI)
+      : CGM(ABI.CGM), VMContext(CGM.getModule().getContext()), CXXABI(ABI) {}
+
+  // Pointer type info flags.
+  enum {
+    /// PTI_Const - Type has const qualifier.
+    PTI_Const = 0x1,
+
+    /// PTI_Volatile - Type has volatile qualifier.
+    PTI_Volatile = 0x2,
+
+    /// PTI_Restrict - Type has restrict qualifier.
+    PTI_Restrict = 0x4,
+
+    /// PTI_Incomplete - Type is incomplete.
+    PTI_Incomplete = 0x8,
+
+    /// PTI_ContainingClassIncomplete - Containing class is incomplete.
+    /// (in pointer to member).
+    PTI_ContainingClassIncomplete = 0x10
+  };
+
+  // VMI type info flags.
+  enum {
+    /// VMI_NonDiamondRepeat - Class has non-diamond repeated inheritance.
+    VMI_NonDiamondRepeat = 0x1,
+
+    /// VMI_DiamondShaped - Class is diamond shaped.
+    VMI_DiamondShaped = 0x2
+  };
+
+  // Base class type info flags.
+  enum {
+    /// BCTI_Virtual - Base class is virtual.
+    BCTI_Virtual = 0x1,
+
+    /// BCTI_Public - Base class is public.
+    BCTI_Public = 0x2
+  };
+
+  /// BuildTypeInfo - Build the RTTI type info struct for the given type.
+  ///
+  /// \param Force - true to force the creation of this RTTI value
+  llvm::Constant *BuildTypeInfo(QualType Ty, bool Force = false);
+};
+}
+
+llvm::GlobalVariable *ItaniumRTTIBuilder::GetAddrOfTypeName(
+    QualType Ty, llvm::GlobalVariable::LinkageTypes Linkage) {
+  SmallString<256> OutName;
+  llvm::raw_svector_ostream Out(OutName);
+  CGM.getCXXABI().getMangleContext().mangleCXXRTTIName(Ty, Out);
+  Out.flush();
+  StringRef Name = OutName.str();
+
+  // We know that the mangled name of the type starts at index 4 of the
+  // mangled name of the typename, so we can just index into it in order to
+  // get the mangled name of the type.
+  llvm::Constant *Init = llvm::ConstantDataArray::getString(VMContext,
+                                                            Name.substr(4));
+
+  llvm::GlobalVariable *GV =
+    CGM.CreateOrReplaceCXXRuntimeVariable(Name, Init->getType(), Linkage);
+
+  GV->setInitializer(Init);
+
+  return GV;
+}
+
+llvm::Constant *
+ItaniumRTTIBuilder::GetAddrOfExternalRTTIDescriptor(QualType Ty) {
+  // Mangle the RTTI name.
+  SmallString<256> OutName;
+  llvm::raw_svector_ostream Out(OutName);
+  CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty, Out);
+  Out.flush();
+  StringRef Name = OutName.str();
+
+  // Look for an existing global.
+  llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(Name);
+
+  if (!GV) {
+    // Create a new global variable.
+    GV = new llvm::GlobalVariable(CGM.getModule(), CGM.Int8PtrTy,
+                                  /*Constant=*/true,
+                                  llvm::GlobalValue::ExternalLinkage, nullptr,
+                                  Name);
+  }
+
+  return llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy);
+}
+
+/// TypeInfoIsInStandardLibrary - Given a builtin type, returns whether the type
+/// info for that type is defined in the standard library.
+static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty) {
+  // Itanium C++ ABI 2.9.2:
+  //   Basic type information (e.g. for "int", "bool", etc.) will be kept in
+  //   the run-time support library. Specifically, the run-time support
+  //   library should contain type_info objects for the types X, X* and
+  //   X const*, for every X in: void, std::nullptr_t, bool, wchar_t, char,
+  //   unsigned char, signed char, short, unsigned short, int, unsigned int,
+  //   long, unsigned long, long long, unsigned long long, float, double,
+  //   long double, char16_t, char32_t, and the IEEE 754r decimal and
+  //   half-precision floating point types.
+  switch (Ty->getKind()) {
+    case BuiltinType::Void:
+    case BuiltinType::NullPtr:
+    case BuiltinType::Bool:
+    case BuiltinType::WChar_S:
+    case BuiltinType::WChar_U:
+    case BuiltinType::Char_U:
+    case BuiltinType::Char_S:
+    case BuiltinType::UChar:
+    case BuiltinType::SChar:
+    case BuiltinType::Short:
+    case BuiltinType::UShort:
+    case BuiltinType::Int:
+    case BuiltinType::UInt:
+    case BuiltinType::Long:
+    case BuiltinType::ULong:
+    case BuiltinType::LongLong:
+    case BuiltinType::ULongLong:
+    case BuiltinType::Half:
+    case BuiltinType::Float:
+    case BuiltinType::Double:
+    case BuiltinType::LongDouble:
+    case BuiltinType::Char16:
+    case BuiltinType::Char32:
+    case BuiltinType::Int128:
+    case BuiltinType::UInt128:
+    case BuiltinType::OCLImage1d:
+    case BuiltinType::OCLImage1dArray:
+    case BuiltinType::OCLImage1dBuffer:
+    case BuiltinType::OCLImage2d:
+    case BuiltinType::OCLImage2dArray:
+    case BuiltinType::OCLImage3d:
+    case BuiltinType::OCLSampler:
+    case BuiltinType::OCLEvent:
+      return true;
+
+    case BuiltinType::Dependent:
+#define BUILTIN_TYPE(Id, SingletonId)
+#define PLACEHOLDER_TYPE(Id, SingletonId) \
+    case BuiltinType::Id:
+#include "clang/AST/BuiltinTypes.def"
+      llvm_unreachable("asking for RRTI for a placeholder type!");
+
+    case BuiltinType::ObjCId:
+    case BuiltinType::ObjCClass:
+    case BuiltinType::ObjCSel:
+      llvm_unreachable("FIXME: Objective-C types are unsupported!");
+  }
+
+  llvm_unreachable("Invalid BuiltinType Kind!");
+}
+
+static bool TypeInfoIsInStandardLibrary(const PointerType *PointerTy) {
+  QualType PointeeTy = PointerTy->getPointeeType();
+  const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(PointeeTy);
+  if (!BuiltinTy)
+    return false;
+
+  // Check the qualifiers.
+  Qualifiers Quals = PointeeTy.getQualifiers();
+  Quals.removeConst();
+
+  if (!Quals.empty())
+    return false;
+
+  return TypeInfoIsInStandardLibrary(BuiltinTy);
+}
+
+/// IsStandardLibraryRTTIDescriptor - Returns whether the type
+/// information for the given type exists in the standard library.
+static bool IsStandardLibraryRTTIDescriptor(QualType Ty) {
+  // Type info for builtin types is defined in the standard library.
+  if (const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))
+    return TypeInfoIsInStandardLibrary(BuiltinTy);
+
+  // Type info for some pointer types to builtin types is defined in the
+  // standard library.
+  if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
+    return TypeInfoIsInStandardLibrary(PointerTy);
+
+  return false;
+}
+
+/// ShouldUseExternalRTTIDescriptor - Returns whether the type information for
+/// the given type exists somewhere else, and that we should not emit the type
+/// information in this translation unit.  Assumes that it is not a
+/// standard-library type.
+static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM,
+                                            QualType Ty) {
+  ASTContext &Context = CGM.getContext();
+
+  // If RTTI is disabled, assume it might be disabled in the
+  // translation unit that defines any potential key function, too.
+  if (!Context.getLangOpts().RTTI) return false;
+
+  if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
+    const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
+    if (!RD->hasDefinition())
+      return false;
+
+    if (!RD->isDynamicClass())
+      return false;
+
+    // FIXME: this may need to be reconsidered if the key function
+    // changes.
+    return CGM.getVTables().isVTableExternal(RD);
+  }
+
+  return false;
+}
+
+/// IsIncompleteClassType - Returns whether the given record type is incomplete.
+static bool IsIncompleteClassType(const RecordType *RecordTy) {
+  return !RecordTy->getDecl()->isCompleteDefinition();
+}
+
+/// ContainsIncompleteClassType - Returns whether the given type contains an
+/// incomplete class type. This is true if
+///
+///   * The given type is an incomplete class type.
+///   * The given type is a pointer type whose pointee type contains an
+///     incomplete class type.
+///   * The given type is a member pointer type whose class is an incomplete
+///     class type.
+///   * The given type is a member pointer type whoise pointee type contains an
+///     incomplete class type.
+/// is an indirect or direct pointer to an incomplete class type.
+static bool ContainsIncompleteClassType(QualType Ty) {
+  if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
+    if (IsIncompleteClassType(RecordTy))
+      return true;
+  }
+
+  if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
+    return ContainsIncompleteClassType(PointerTy->getPointeeType());
+
+  if (const MemberPointerType *MemberPointerTy =
+      dyn_cast<MemberPointerType>(Ty)) {
+    // Check if the class type is incomplete.
+    const RecordType *ClassType = cast<RecordType>(MemberPointerTy->getClass());
+    if (IsIncompleteClassType(ClassType))
+      return true;
+
+    return ContainsIncompleteClassType(MemberPointerTy->getPointeeType());
+  }
+
+  return false;
+}
+
+// CanUseSingleInheritance - Return whether the given record decl has a "single,
+// public, non-virtual base at offset zero (i.e. the derived class is dynamic
+// iff the base is)", according to Itanium C++ ABI, 2.95p6b.
+static bool CanUseSingleInheritance(const CXXRecordDecl *RD) {
+  // Check the number of bases.
+  if (RD->getNumBases() != 1)
+    return false;
+
+  // Get the base.
+  CXXRecordDecl::base_class_const_iterator Base = RD->bases_begin();
+
+  // Check that the base is not virtual.
+  if (Base->isVirtual())
+    return false;
+
+  // Check that the base is public.
+  if (Base->getAccessSpecifier() != AS_public)
+    return false;
+
+  // Check that the class is dynamic iff the base is.
+  const CXXRecordDecl *BaseDecl =
+    cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+  if (!BaseDecl->isEmpty() &&
+      BaseDecl->isDynamicClass() != RD->isDynamicClass())
+    return false;
+
+  return true;
+}
+
+void ItaniumRTTIBuilder::BuildVTablePointer(const Type *Ty) {
+  // abi::__class_type_info.
+  static const char * const ClassTypeInfo =
+    "_ZTVN10__cxxabiv117__class_type_infoE";
+  // abi::__si_class_type_info.
+  static const char * const SIClassTypeInfo =
+    "_ZTVN10__cxxabiv120__si_class_type_infoE";
+  // abi::__vmi_class_type_info.
+  static const char * const VMIClassTypeInfo =
+    "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
+
+  const char *VTableName = nullptr;
+
+  switch (Ty->getTypeClass()) {
+#define TYPE(Class, Base)
+#define ABSTRACT_TYPE(Class, Base)
+#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
+#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
+#define DEPENDENT_TYPE(Class, Base) case Type::Class:
+#include "clang/AST/TypeNodes.def"
+    llvm_unreachable("Non-canonical and dependent types shouldn't get here");
+
+  case Type::LValueReference:
+  case Type::RValueReference:
+    llvm_unreachable("References shouldn't get here");
+
+  case Type::Auto:
+    llvm_unreachable("Undeduced auto type shouldn't get here");
+
+  case Type::Builtin:
+  // GCC treats vector and complex types as fundamental types.
+  case Type::Vector:
+  case Type::ExtVector:
+  case Type::Complex:
+  case Type::Atomic:
+  // FIXME: GCC treats block pointers as fundamental types?!
+  case Type::BlockPointer:
+    // abi::__fundamental_type_info.
+    VTableName = "_ZTVN10__cxxabiv123__fundamental_type_infoE";
+    break;
+
+  case Type::ConstantArray:
+  case Type::IncompleteArray:
+  case Type::VariableArray:
+    // abi::__array_type_info.
+    VTableName = "_ZTVN10__cxxabiv117__array_type_infoE";
+    break;
+
+  case Type::FunctionNoProto:
+  case Type::FunctionProto:
+    // abi::__function_type_info.
+    VTableName = "_ZTVN10__cxxabiv120__function_type_infoE";
+    break;
+
+  case Type::Enum:
+    // abi::__enum_type_info.
+    VTableName = "_ZTVN10__cxxabiv116__enum_type_infoE";
+    break;
+
+  case Type::Record: {
+    const CXXRecordDecl *RD =
+      cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
+
+    if (!RD->hasDefinition() || !RD->getNumBases()) {
+      VTableName = ClassTypeInfo;
+    } else if (CanUseSingleInheritance(RD)) {
+      VTableName = SIClassTypeInfo;
+    } else {
+      VTableName = VMIClassTypeInfo;
+    }
+
+    break;
+  }
+
+  case Type::ObjCObject:
+    // Ignore protocol qualifiers.
+    Ty = cast<ObjCObjectType>(Ty)->getBaseType().getTypePtr();
+
+    // Handle id and Class.
+    if (isa<BuiltinType>(Ty)) {
+      VTableName = ClassTypeInfo;
+      break;
+    }
+
+    assert(isa<ObjCInterfaceType>(Ty));
+    // Fall through.
+
+  case Type::ObjCInterface:
+    if (cast<ObjCInterfaceType>(Ty)->getDecl()->getSuperClass()) {
+      VTableName = SIClassTypeInfo;
+    } else {
+      VTableName = ClassTypeInfo;
+    }
+    break;
+
+  case Type::ObjCObjectPointer:
+  case Type::Pointer:
+    // abi::__pointer_type_info.
+    VTableName = "_ZTVN10__cxxabiv119__pointer_type_infoE";
+    break;
+
+  case Type::MemberPointer:
+    // abi::__pointer_to_member_type_info.
+    VTableName = "_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
+    break;
+  }
+
+  llvm::Constant *VTable =
+    CGM.getModule().getOrInsertGlobal(VTableName, CGM.Int8PtrTy);
+
+  llvm::Type *PtrDiffTy =
+    CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType());
+
+  // The vtable address point is 2.
+  llvm::Constant *Two = llvm::ConstantInt::get(PtrDiffTy, 2);
+  VTable = llvm::ConstantExpr::getInBoundsGetElementPtr(VTable, Two);
+  VTable = llvm::ConstantExpr::getBitCast(VTable, CGM.Int8PtrTy);
+
+  Fields.push_back(VTable);
+}
+
+/// \brief Return the linkage that the type info and type info name constants
+/// should have for the given type.
+static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(CodeGenModule &CGM,
+                                                             QualType Ty) {
+  // Itanium C++ ABI 2.9.5p7:
+  //   In addition, it and all of the intermediate abi::__pointer_type_info
+  //   structs in the chain down to the abi::__class_type_info for the
+  //   incomplete class type must be prevented from resolving to the
+  //   corresponding type_info structs for the complete class type, possibly
+  //   by making them local static objects. Finally, a dummy class RTTI is
+  //   generated for the incomplete type that will not resolve to the final
+  //   complete class RTTI (because the latter need not exist), possibly by
+  //   making it a local static object.
+  if (ContainsIncompleteClassType(Ty))
+    return llvm::GlobalValue::InternalLinkage;
+
+  switch (Ty->getLinkage()) {
+  case NoLinkage:
+  case InternalLinkage:
+  case UniqueExternalLinkage:
+    return llvm::GlobalValue::InternalLinkage;
+
+  case VisibleNoLinkage:
+  case ExternalLinkage:
+    if (!CGM.getLangOpts().RTTI) {
+      // RTTI is not enabled, which means that this type info struct is going
+      // to be used for exception handling. Give it linkonce_odr linkage.
+      return llvm::GlobalValue::LinkOnceODRLinkage;
+    }
+
+    if (const RecordType *Record = dyn_cast<RecordType>(Ty)) {
+      const CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
+      if (RD->hasAttr<WeakAttr>())
+        return llvm::GlobalValue::WeakODRLinkage;
+      if (RD->isDynamicClass())
+        return CGM.getVTableLinkage(RD);
+    }
+
+    return llvm::GlobalValue::LinkOnceODRLinkage;
+  }
+
+  llvm_unreachable("Invalid linkage!");
+}
+
+llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty, bool Force) {
+  // We want to operate on the canonical type.
+  Ty = CGM.getContext().getCanonicalType(Ty);
+
+  // Check if we've already emitted an RTTI descriptor for this type.
+  SmallString<256> OutName;
+  llvm::raw_svector_ostream Out(OutName);
+  CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty, Out);
+  Out.flush();
+  StringRef Name = OutName.str();
+
+  llvm::GlobalVariable *OldGV = CGM.getModule().getNamedGlobal(Name);
+  if (OldGV && !OldGV->isDeclaration()) {
+    assert(!OldGV->hasAvailableExternallyLinkage() &&
+           "available_externally typeinfos not yet implemented");
+
+    return llvm::ConstantExpr::getBitCast(OldGV, CGM.Int8PtrTy);
+  }
+
+  // Check if there is already an external RTTI descriptor for this type.
+  bool IsStdLib = IsStandardLibraryRTTIDescriptor(Ty);
+  if (!Force && (IsStdLib || ShouldUseExternalRTTIDescriptor(CGM, Ty)))
+    return GetAddrOfExternalRTTIDescriptor(Ty);
+
+  // Emit the standard library with external linkage.
+  llvm::GlobalVariable::LinkageTypes Linkage;
+  if (IsStdLib)
+    Linkage = llvm::GlobalValue::ExternalLinkage;
+  else
+    Linkage = getTypeInfoLinkage(CGM, Ty);
+
+  // Add the vtable pointer.
+  BuildVTablePointer(cast<Type>(Ty));
+
+  // And the name.
+  llvm::GlobalVariable *TypeName = GetAddrOfTypeName(Ty, Linkage);
+  llvm::Constant *TypeNameField;
+
+  // If we're supposed to demote the visibility, be sure to set a flag
+  // to use a string comparison for type_info comparisons.
+  ItaniumCXXABI::RTTIUniquenessKind RTTIUniqueness =
+      CXXABI.classifyRTTIUniqueness(Ty, Linkage);
+  if (RTTIUniqueness != ItaniumCXXABI::RUK_Unique) {
+    // The flag is the sign bit, which on ARM64 is defined to be clear
+    // for global pointers.  This is very ARM64-specific.
+    TypeNameField = llvm::ConstantExpr::getPtrToInt(TypeName, CGM.Int64Ty);
+    llvm::Constant *flag =
+        llvm::ConstantInt::get(CGM.Int64Ty, ((uint64_t)1) << 63);
+    TypeNameField = llvm::ConstantExpr::getAdd(TypeNameField, flag);
+    TypeNameField =
+        llvm::ConstantExpr::getIntToPtr(TypeNameField, CGM.Int8PtrTy);
+  } else {
+    TypeNameField = llvm::ConstantExpr::getBitCast(TypeName, CGM.Int8PtrTy);
+  }
+  Fields.push_back(TypeNameField);
+
+  switch (Ty->getTypeClass()) {
+#define TYPE(Class, Base)
+#define ABSTRACT_TYPE(Class, Base)
+#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) case Type::Class:
+#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
+#define DEPENDENT_TYPE(Class, Base) case Type::Class:
+#include "clang/AST/TypeNodes.def"
+    llvm_unreachable("Non-canonical and dependent types shouldn't get here");
+
+  // GCC treats vector types as fundamental types.
+  case Type::Builtin:
+  case Type::Vector:
+  case Type::ExtVector:
+  case Type::Complex:
+  case Type::BlockPointer:
+    // Itanium C++ ABI 2.9.5p4:
+    // abi::__fundamental_type_info adds no data members to std::type_info.
+    break;
+
+  case Type::LValueReference:
+  case Type::RValueReference:
+    llvm_unreachable("References shouldn't get here");
+
+  case Type::Auto:
+    llvm_unreachable("Undeduced auto type shouldn't get here");
+
+  case Type::ConstantArray:
+  case Type::IncompleteArray:
+  case Type::VariableArray:
+    // Itanium C++ ABI 2.9.5p5:
+    // abi::__array_type_info adds no data members to std::type_info.
+    break;
+
+  case Type::FunctionNoProto:
+  case Type::FunctionProto:
+    // Itanium C++ ABI 2.9.5p5:
+    // abi::__function_type_info adds no data members to std::type_info.
+    break;
+
+  case Type::Enum:
+    // Itanium C++ ABI 2.9.5p5:
+    // abi::__enum_type_info adds no data members to std::type_info.
+    break;
+
+  case Type::Record: {
+    const CXXRecordDecl *RD =
+      cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
+    if (!RD->hasDefinition() || !RD->getNumBases()) {
+      // We don't need to emit any fields.
+      break;
+    }
+
+    if (CanUseSingleInheritance(RD))
+      BuildSIClassTypeInfo(RD);
+    else
+      BuildVMIClassTypeInfo(RD);
+
+    break;
+  }
+
+  case Type::ObjCObject:
+  case Type::ObjCInterface:
+    BuildObjCObjectTypeInfo(cast<ObjCObjectType>(Ty));
+    break;
+
+  case Type::ObjCObjectPointer:
+    BuildPointerTypeInfo(cast<ObjCObjectPointerType>(Ty)->getPointeeType());
+    break;
+
+  case Type::Pointer:
+    BuildPointerTypeInfo(cast<PointerType>(Ty)->getPointeeType());
+    break;
+
+  case Type::MemberPointer:
+    BuildPointerToMemberTypeInfo(cast<MemberPointerType>(Ty));
+    break;
+
+  case Type::Atomic:
+    // No fields, at least for the moment.
+    break;
+  }
+
+  llvm::Constant *Init = llvm::ConstantStruct::getAnon(Fields);
+
+  llvm::GlobalVariable *GV =
+    new llvm::GlobalVariable(CGM.getModule(), Init->getType(),
+                             /*Constant=*/true, Linkage, Init, Name);
+
+  // If there's already an old global variable, replace it with the new one.
+  if (OldGV) {
+    GV->takeName(OldGV);
+    llvm::Constant *NewPtr =
+      llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
+    OldGV->replaceAllUsesWith(NewPtr);
+    OldGV->eraseFromParent();
+  }
+
+  // The Itanium ABI specifies that type_info objects must be globally
+  // unique, with one exception: if the type is an incomplete class
+  // type or a (possibly indirect) pointer to one.  That exception
+  // affects the general case of comparing type_info objects produced
+  // by the typeid operator, which is why the comparison operators on
+  // std::type_info generally use the type_info name pointers instead
+  // of the object addresses.  However, the language's built-in uses
+  // of RTTI generally require class types to be complete, even when
+  // manipulating pointers to those class types.  This allows the
+  // implementation of dynamic_cast to rely on address equality tests,
+  // which is much faster.
+
+  // All of this is to say that it's important that both the type_info
+  // object and the type_info name be uniqued when weakly emitted.
+
+  // Give the type_info object and name the formal visibility of the
+  // type itself.
+  llvm::GlobalValue::VisibilityTypes llvmVisibility;
+  if (llvm::GlobalValue::isLocalLinkage(Linkage))
+    // If the linkage is local, only default visibility makes sense.
+    llvmVisibility = llvm::GlobalValue::DefaultVisibility;
+  else if (RTTIUniqueness == ItaniumCXXABI::RUK_NonUniqueHidden)
+    llvmVisibility = llvm::GlobalValue::HiddenVisibility;
+  else
+    llvmVisibility = CodeGenModule::GetLLVMVisibility(Ty->getVisibility());
+  TypeName->setVisibility(llvmVisibility);
+  GV->setVisibility(llvmVisibility);
+
+  return llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy);
+}
+
+/// ComputeQualifierFlags - Compute the pointer type info flags from the
+/// given qualifier.
+static unsigned ComputeQualifierFlags(Qualifiers Quals) {
+  unsigned Flags = 0;
+
+  if (Quals.hasConst())
+    Flags |= ItaniumRTTIBuilder::PTI_Const;
+  if (Quals.hasVolatile())
+    Flags |= ItaniumRTTIBuilder::PTI_Volatile;
+  if (Quals.hasRestrict())
+    Flags |= ItaniumRTTIBuilder::PTI_Restrict;
+
+  return Flags;
+}
+
+/// BuildObjCObjectTypeInfo - Build the appropriate kind of type_info
+/// for the given Objective-C object type.
+void ItaniumRTTIBuilder::BuildObjCObjectTypeInfo(const ObjCObjectType *OT) {
+  // Drop qualifiers.
+  const Type *T = OT->getBaseType().getTypePtr();
+  assert(isa<BuiltinType>(T) || isa<ObjCInterfaceType>(T));
+
+  // The builtin types are abi::__class_type_infos and don't require
+  // extra fields.
+  if (isa<BuiltinType>(T)) return;
+
+  ObjCInterfaceDecl *Class = cast<ObjCInterfaceType>(T)->getDecl();
+  ObjCInterfaceDecl *Super = Class->getSuperClass();
+
+  // Root classes are also __class_type_info.
+  if (!Super) return;
+
+  QualType SuperTy = CGM.getContext().getObjCInterfaceType(Super);
+
+  // Everything else is single inheritance.
+  llvm::Constant *BaseTypeInfo =
+      ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(SuperTy);
+  Fields.push_back(BaseTypeInfo);
+}
+
+/// BuildSIClassTypeInfo - Build an abi::__si_class_type_info, used for single
+/// inheritance, according to the Itanium C++ ABI, 2.95p6b.
+void ItaniumRTTIBuilder::BuildSIClassTypeInfo(const CXXRecordDecl *RD) {
+  // Itanium C++ ABI 2.9.5p6b:
+  // It adds to abi::__class_type_info a single member pointing to the
+  // type_info structure for the base type,
+  llvm::Constant *BaseTypeInfo =
+    ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(RD->bases_begin()->getType());
+  Fields.push_back(BaseTypeInfo);
+}
+
+namespace {
+  /// SeenBases - Contains virtual and non-virtual bases seen when traversing
+  /// a class hierarchy.
+  struct SeenBases {
+    llvm::SmallPtrSet<const CXXRecordDecl *, 16> NonVirtualBases;
+    llvm::SmallPtrSet<const CXXRecordDecl *, 16> VirtualBases;
+  };
+}
+
+/// ComputeVMIClassTypeInfoFlags - Compute the value of the flags member in
+/// abi::__vmi_class_type_info.
+///
+static unsigned ComputeVMIClassTypeInfoFlags(const CXXBaseSpecifier *Base,
+                                             SeenBases &Bases) {
+
+  unsigned Flags = 0;
+
+  const CXXRecordDecl *BaseDecl =
+    cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+
+  if (Base->isVirtual()) {
+    // Mark the virtual base as seen.
+    if (!Bases.VirtualBases.insert(BaseDecl)) {
+      // If this virtual base has been seen before, then the class is diamond
+      // shaped.
+      Flags |= ItaniumRTTIBuilder::VMI_DiamondShaped;
+    } else {
+      if (Bases.NonVirtualBases.count(BaseDecl))
+        Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
+    }
+  } else {
+    // Mark the non-virtual base as seen.
+    if (!Bases.NonVirtualBases.insert(BaseDecl)) {
+      // If this non-virtual base has been seen before, then the class has non-
+      // diamond shaped repeated inheritance.
+      Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
+    } else {
+      if (Bases.VirtualBases.count(BaseDecl))
+        Flags |= ItaniumRTTIBuilder::VMI_NonDiamondRepeat;
+    }
+  }
+
+  // Walk all bases.
+  for (const auto &I : BaseDecl->bases())
+    Flags |= ComputeVMIClassTypeInfoFlags(&I, Bases);
+
+  return Flags;
+}
+
+static unsigned ComputeVMIClassTypeInfoFlags(const CXXRecordDecl *RD) {
+  unsigned Flags = 0;
+  SeenBases Bases;
+
+  // Walk all bases.
+  for (const auto &I : RD->bases())
+    Flags |= ComputeVMIClassTypeInfoFlags(&I, Bases);
+
+  return Flags;
+}
+
+/// BuildVMIClassTypeInfo - Build an abi::__vmi_class_type_info, used for
+/// classes with bases that do not satisfy the abi::__si_class_type_info
+/// constraints, according ti the Itanium C++ ABI, 2.9.5p5c.
+void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) {
+  llvm::Type *UnsignedIntLTy =
+    CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
+
+  // Itanium C++ ABI 2.9.5p6c:
+  //   __flags is a word with flags describing details about the class
+  //   structure, which may be referenced by using the __flags_masks
+  //   enumeration. These flags refer to both direct and indirect bases.
+  unsigned Flags = ComputeVMIClassTypeInfoFlags(RD);
+  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
+
+  // Itanium C++ ABI 2.9.5p6c:
+  //   __base_count is a word with the number of direct proper base class
+  //   descriptions that follow.
+  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, RD->getNumBases()));
+
+  if (!RD->getNumBases())
+    return;
+
+  llvm::Type *LongLTy =
+    CGM.getTypes().ConvertType(CGM.getContext().LongTy);
+
+  // Now add the base class descriptions.
+
+  // Itanium C++ ABI 2.9.5p6c:
+  //   __base_info[] is an array of base class descriptions -- one for every
+  //   direct proper base. Each description is of the type:
+  //
+  //   struct abi::__base_class_type_info {
+  //   public:
+  //     const __class_type_info *__base_type;
+  //     long __offset_flags;
+  //
+  //     enum __offset_flags_masks {
+  //       __virtual_mask = 0x1,
+  //       __public_mask = 0x2,
+  //       __offset_shift = 8
+  //     };
+  //   };
+  for (const auto &Base : RD->bases()) {
+    // The __base_type member points to the RTTI for the base type.
+    Fields.push_back(ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(Base.getType()));
+
+    const CXXRecordDecl *BaseDecl =
+      cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
+
+    int64_t OffsetFlags = 0;
+
+    // All but the lower 8 bits of __offset_flags are a signed offset.
+    // For a non-virtual base, this is the offset in the object of the base
+    // subobject. For a virtual base, this is the offset in the virtual table of
+    // the virtual base offset for the virtual base referenced (negative).
+    CharUnits Offset;
+    if (Base.isVirtual())
+      Offset =
+        CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(RD, BaseDecl);
+    else {
+      const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
+      Offset = Layout.getBaseClassOffset(BaseDecl);
+    };
+
+    OffsetFlags = uint64_t(Offset.getQuantity()) << 8;
+
+    // The low-order byte of __offset_flags contains flags, as given by the
+    // masks from the enumeration __offset_flags_masks.
+    if (Base.isVirtual())
+      OffsetFlags |= BCTI_Virtual;
+    if (Base.getAccessSpecifier() == AS_public)
+      OffsetFlags |= BCTI_Public;
+
+    Fields.push_back(llvm::ConstantInt::get(LongLTy, OffsetFlags));
+  }
+}
+
+/// BuildPointerTypeInfo - Build an abi::__pointer_type_info struct,
+/// used for pointer types.
+void ItaniumRTTIBuilder::BuildPointerTypeInfo(QualType PointeeTy) {
+  Qualifiers Quals;
+  QualType UnqualifiedPointeeTy =
+    CGM.getContext().getUnqualifiedArrayType(PointeeTy, Quals);
+
+  // Itanium C++ ABI 2.9.5p7:
+  //   __flags is a flag word describing the cv-qualification and other
+  //   attributes of the type pointed to
+  unsigned Flags = ComputeQualifierFlags(Quals);
+
+  // Itanium C++ ABI 2.9.5p7:
+  //   When the abi::__pbase_type_info is for a direct or indirect pointer to an
+  //   incomplete class type, the incomplete target type flag is set.
+  if (ContainsIncompleteClassType(UnqualifiedPointeeTy))
+    Flags |= PTI_Incomplete;
+
+  llvm::Type *UnsignedIntLTy =
+    CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
+  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
+
+  // Itanium C++ ABI 2.9.5p7:
+  //  __pointee is a pointer to the std::type_info derivation for the
+  //  unqualified type being pointed to.
+  llvm::Constant *PointeeTypeInfo =
+    ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(UnqualifiedPointeeTy);
+  Fields.push_back(PointeeTypeInfo);
+}
+
+/// BuildPointerToMemberTypeInfo - Build an abi::__pointer_to_member_type_info
+/// struct, used for member pointer types.
+void
+ItaniumRTTIBuilder::BuildPointerToMemberTypeInfo(const MemberPointerType *Ty) {
+  QualType PointeeTy = Ty->getPointeeType();
+
+  Qualifiers Quals;
+  QualType UnqualifiedPointeeTy =
+    CGM.getContext().getUnqualifiedArrayType(PointeeTy, Quals);
+
+  // Itanium C++ ABI 2.9.5p7:
+  //   __flags is a flag word describing the cv-qualification and other
+  //   attributes of the type pointed to.
+  unsigned Flags = ComputeQualifierFlags(Quals);
+
+  const RecordType *ClassType = cast<RecordType>(Ty->getClass());
+
+  // Itanium C++ ABI 2.9.5p7:
+  //   When the abi::__pbase_type_info is for a direct or indirect pointer to an
+  //   incomplete class type, the incomplete target type flag is set.
+  if (ContainsIncompleteClassType(UnqualifiedPointeeTy))
+    Flags |= PTI_Incomplete;
+
+  if (IsIncompleteClassType(ClassType))
+    Flags |= PTI_ContainingClassIncomplete;
+
+  llvm::Type *UnsignedIntLTy =
+    CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
+  Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
+
+  // Itanium C++ ABI 2.9.5p7:
+  //   __pointee is a pointer to the std::type_info derivation for the
+  //   unqualified type being pointed to.
+  llvm::Constant *PointeeTypeInfo =
+    ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(UnqualifiedPointeeTy);
+  Fields.push_back(PointeeTypeInfo);
+
+  // Itanium C++ ABI 2.9.5p9:
+  //   __context is a pointer to an abi::__class_type_info corresponding to the
+  //   class type containing the member pointed to
+  //   (e.g., the "A" in "int A::*").
+  Fields.push_back(
+      ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(QualType(ClassType, 0)));
+}
+
+llvm::Constant *ItaniumCXXABI::getAddrOfRTTIDescriptor(QualType Ty) {
+  return ItaniumRTTIBuilder(*this).BuildTypeInfo(Ty);
+}
+
+void ItaniumCXXABI::EmitFundamentalRTTIDescriptor(QualType Type) {
+  QualType PointerType = getContext().getPointerType(Type);
+  QualType PointerTypeConst = getContext().getPointerType(Type.withConst());
+  ItaniumRTTIBuilder(*this).BuildTypeInfo(Type, true);
+  ItaniumRTTIBuilder(*this).BuildTypeInfo(PointerType, true);
+  ItaniumRTTIBuilder(*this).BuildTypeInfo(PointerTypeConst, true);
+}
+
+void ItaniumCXXABI::EmitFundamentalRTTIDescriptors() {
+  QualType FundamentalTypes[] = {
+      getContext().VoidTy,             getContext().NullPtrTy,
+      getContext().BoolTy,             getContext().WCharTy,
+      getContext().CharTy,             getContext().UnsignedCharTy,
+      getContext().SignedCharTy,       getContext().ShortTy,
+      getContext().UnsignedShortTy,    getContext().IntTy,
+      getContext().UnsignedIntTy,      getContext().LongTy,
+      getContext().UnsignedLongTy,     getContext().LongLongTy,
+      getContext().UnsignedLongLongTy, getContext().HalfTy,
+      getContext().FloatTy,            getContext().DoubleTy,
+      getContext().LongDoubleTy,       getContext().Char16Ty,
+      getContext().Char32Ty,
+  };
+  for (const QualType &FundamentalType : FundamentalTypes)
+    EmitFundamentalRTTIDescriptor(FundamentalType);
+}
+
+/// What sort of uniqueness rules should we use for the RTTI for the
+/// given type?
+ItaniumCXXABI::RTTIUniquenessKind ItaniumCXXABI::classifyRTTIUniqueness(
+    QualType CanTy, llvm::GlobalValue::LinkageTypes Linkage) const {
+  if (shouldRTTIBeUnique())
+    return RUK_Unique;
+
+  // It's only necessary for linkonce_odr or weak_odr linkage.
+  if (Linkage != llvm::GlobalValue::LinkOnceODRLinkage &&
+      Linkage != llvm::GlobalValue::WeakODRLinkage)
+    return RUK_Unique;
+
+  // It's only necessary with default visibility.
+  if (CanTy->getVisibility() != DefaultVisibility)
+    return RUK_Unique;
+
+  // If we're not required to publish this symbol, hide it.
+  if (Linkage == llvm::GlobalValue::LinkOnceODRLinkage)
+    return RUK_NonUniqueHidden;
+
+  // If we're required to publish this symbol, as we might be under an
+  // explicit instantiation, leave it with default visibility but
+  // enable string-comparisons.
+  assert(Linkage == llvm::GlobalValue::WeakODRLinkage);
+  return RUK_NonUniqueVisible;
+}
diff --git a/lib/CodeGen/MicrosoftCXXABI.cpp b/lib/CodeGen/MicrosoftCXXABI.cpp
index 4a02d4d..a69d4dd 100644
--- a/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -15,62 +15,92 @@
 //===----------------------------------------------------------------------===//
 
 #include "CGCXXABI.h"
-#include "CodeGenModule.h"
 #include "CGVTables.h"
-#include "MicrosoftVBTables.h"
+#include "CodeGenModule.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/VTableBuilder.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringSet.h"
+#include "llvm/IR/CallSite.h"
 
 using namespace clang;
 using namespace CodeGen;
 
 namespace {
 
+/// Holds all the vbtable globals for a given class.
+struct VBTableGlobals {
+  const VPtrInfoVector *VBTables;
+  SmallVector<llvm::GlobalVariable *, 2> Globals;
+};
+
 class MicrosoftCXXABI : public CGCXXABI {
 public:
-  MicrosoftCXXABI(CodeGenModule &CGM) : CGCXXABI(CGM) {}
+  MicrosoftCXXABI(CodeGenModule &CGM)
+      : CGCXXABI(CGM), BaseClassDescriptorType(nullptr),
+        ClassHierarchyDescriptorType(nullptr),
+        CompleteObjectLocatorType(nullptr) {}
 
-  bool HasThisReturn(GlobalDecl GD) const;
+  bool HasThisReturn(GlobalDecl GD) const override;
 
-  bool isReturnTypeIndirect(const CXXRecordDecl *RD) const {
-    // Structures that are not C++03 PODs are always indirect.
-    return !RD->isPOD();
-  }
+  bool classifyReturnType(CGFunctionInfo &FI) const override;
 
-  RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const {
-    if (RD->hasNonTrivialCopyConstructor() || RD->hasNonTrivialDestructor())
-      return RAA_DirectInMemory;
-    return RAA_Default;
-  }
+  RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const override;
 
-  StringRef GetPureVirtualCallName() { return "_purecall"; }
+  bool isSRetParameterAfterThis() const override { return true; }
+
+  StringRef GetPureVirtualCallName() override { return "_purecall"; }
   // No known support for deleted functions in MSVC yet, so this choice is
   // arbitrary.
-  StringRef GetDeletedVirtualCallName() { return "_purecall"; }
+  StringRef GetDeletedVirtualCallName() override { return "_purecall"; }
 
   llvm::Value *adjustToCompleteObject(CodeGenFunction &CGF,
                                       llvm::Value *ptr,
-                                      QualType type);
+                                      QualType type) override;
 
-  llvm::Value *GetVirtualBaseClassOffset(CodeGenFunction &CGF,
-                                         llvm::Value *This,
-                                         const CXXRecordDecl *ClassDecl,
-                                         const CXXRecordDecl *BaseClassDecl);
+  llvm::GlobalVariable *getMSCompleteObjectLocator(const CXXRecordDecl *RD,
+                                                   const VPtrInfo *Info);
+
+  llvm::Constant *getAddrOfRTTIDescriptor(QualType Ty) override;
+
+  bool shouldTypeidBeNullChecked(bool IsDeref, QualType SrcRecordTy) override;
+  void EmitBadTypeidCall(CodeGenFunction &CGF) override;
+  llvm::Value *EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy,
+                          llvm::Value *ThisPtr,
+                          llvm::Type *StdTypeInfoPtrTy) override;
+
+  bool shouldDynamicCastCallBeNullChecked(bool SrcIsPtr,
+                                          QualType SrcRecordTy) override;
+
+  llvm::Value *EmitDynamicCastCall(CodeGenFunction &CGF, llvm::Value *Value,
+                                   QualType SrcRecordTy, QualType DestTy,
+                                   QualType DestRecordTy,
+                                   llvm::BasicBlock *CastEnd) override;
+
+  llvm::Value *EmitDynamicCastToVoid(CodeGenFunction &CGF, llvm::Value *Value,
+                                     QualType SrcRecordTy,
+                                     QualType DestTy) override;
+
+  bool EmitBadCastCall(CodeGenFunction &CGF) override;
+
+  llvm::Value *
+  GetVirtualBaseClassOffset(CodeGenFunction &CGF, llvm::Value *This,
+                            const CXXRecordDecl *ClassDecl,
+                            const CXXRecordDecl *BaseClassDecl) override;
 
   void BuildConstructorSignature(const CXXConstructorDecl *Ctor,
-                                 CXXCtorType Type,
-                                 CanQualType &ResTy,
-                                 SmallVectorImpl<CanQualType> &ArgTys);
+                                 CXXCtorType Type, CanQualType &ResTy,
+                                 SmallVectorImpl<CanQualType> &ArgTys) override;
 
-  llvm::BasicBlock *EmitCtorCompleteObjectHandler(CodeGenFunction &CGF,
-                                                  const CXXRecordDecl *RD);
+  llvm::BasicBlock *
+  EmitCtorCompleteObjectHandler(CodeGenFunction &CGF,
+                                const CXXRecordDecl *RD) override;
 
   void initializeHiddenVirtualInheritanceMembers(CodeGenFunction &CGF,
-                                                 const CXXRecordDecl *RD);
+                                              const CXXRecordDecl *RD) override;
 
-  void EmitCXXConstructors(const CXXConstructorDecl *D);
+  void EmitCXXConstructors(const CXXConstructorDecl *D) override;
 
   // Background on MSVC destructors
   // ==============================
@@ -107,17 +137,18 @@
   void BuildDestructorSignature(const CXXDestructorDecl *Dtor,
                                 CXXDtorType Type,
                                 CanQualType &ResTy,
-                                SmallVectorImpl<CanQualType> &ArgTys);
+                                SmallVectorImpl<CanQualType> &ArgTys) override;
 
   /// Non-base dtors should be emitted as delegating thunks in this ABI.
   bool useThunkForDtorVariant(const CXXDestructorDecl *Dtor,
-                              CXXDtorType DT) const {
+                              CXXDtorType DT) const override {
     return DT != Dtor_Base;
   }
 
-  void EmitCXXDestructors(const CXXDestructorDecl *D);
+  void EmitCXXDestructors(const CXXDestructorDecl *D) override;
 
-  const CXXRecordDecl *getThisArgumentTypeForMethod(const CXXMethodDecl *MD) {
+  const CXXRecordDecl *
+  getThisArgumentTypeForMethod(const CXXMethodDecl *MD) override {
     MD = MD->getCanonicalDecl();
     if (MD->isVirtual() && !isa<CXXDestructorDecl>(MD)) {
       MicrosoftVTableContext::MethodVFTableLocation ML =
@@ -129,76 +160,100 @@
       // FIXME: might want to have a more precise type in the non-virtual
       // multiple inheritance case.
       if (ML.VBase || !ML.VFPtrOffset.isZero())
-        return 0;
+        return nullptr;
     }
     return MD->getParent();
   }
 
-  llvm::Value *adjustThisArgumentForVirtualCall(CodeGenFunction &CGF,
-                                                GlobalDecl GD,
-                                                llvm::Value *This);
+  llvm::Value *
+  adjustThisArgumentForVirtualFunctionCall(CodeGenFunction &CGF, GlobalDecl GD,
+                                           llvm::Value *This,
+                                           bool VirtualCall) override;
 
-  void BuildInstanceFunctionParams(CodeGenFunction &CGF,
-                                   QualType &ResTy,
-                                   FunctionArgList &Params);
+  void addImplicitStructorParams(CodeGenFunction &CGF, QualType &ResTy,
+                                 FunctionArgList &Params) override;
 
   llvm::Value *adjustThisParameterInVirtualFunctionPrologue(
-      CodeGenFunction &CGF, GlobalDecl GD, llvm::Value *This);
+      CodeGenFunction &CGF, GlobalDecl GD, llvm::Value *This) override;
 
-  void EmitInstanceFunctionProlog(CodeGenFunction &CGF);
+  void EmitInstanceFunctionProlog(CodeGenFunction &CGF) override;
 
-  void EmitConstructorCall(CodeGenFunction &CGF,
-                           const CXXConstructorDecl *D, CXXCtorType Type,
-                           bool ForVirtualBase, bool Delegating,
-                           llvm::Value *This,
-                           CallExpr::const_arg_iterator ArgBeg,
-                           CallExpr::const_arg_iterator ArgEnd);
+  unsigned addImplicitConstructorArgs(CodeGenFunction &CGF,
+                                      const CXXConstructorDecl *D,
+                                      CXXCtorType Type, bool ForVirtualBase,
+                                      bool Delegating,
+                                      CallArgList &Args) override;
 
-  void emitVTableDefinitions(CodeGenVTables &CGVT, const CXXRecordDecl *RD);
+  void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD,
+                          CXXDtorType Type, bool ForVirtualBase,
+                          bool Delegating, llvm::Value *This) override;
+
+  void emitVTableDefinitions(CodeGenVTables &CGVT,
+                             const CXXRecordDecl *RD) override;
 
   llvm::Value *getVTableAddressPointInStructor(
       CodeGenFunction &CGF, const CXXRecordDecl *VTableClass,
       BaseSubobject Base, const CXXRecordDecl *NearestVBase,
-      bool &NeedsVirtualOffset);
+      bool &NeedsVirtualOffset) override;
 
   llvm::Constant *
   getVTableAddressPointForConstExpr(BaseSubobject Base,
-                                    const CXXRecordDecl *VTableClass);
+                                    const CXXRecordDecl *VTableClass) override;
 
   llvm::GlobalVariable *getAddrOfVTable(const CXXRecordDecl *RD,
-                                        CharUnits VPtrOffset);
+                                        CharUnits VPtrOffset) override;
 
   llvm::Value *getVirtualFunctionPointer(CodeGenFunction &CGF, GlobalDecl GD,
-                                         llvm::Value *This, llvm::Type *Ty);
+                                         llvm::Value *This,
+                                         llvm::Type *Ty) override;
 
   void EmitVirtualDestructorCall(CodeGenFunction &CGF,
                                  const CXXDestructorDecl *Dtor,
                                  CXXDtorType DtorType, SourceLocation CallLoc,
-                                 llvm::Value *This);
+                                 llvm::Value *This) override;
 
   void adjustCallArgsForDestructorThunk(CodeGenFunction &CGF, GlobalDecl GD,
-                                        CallArgList &CallArgs) {
+                                        CallArgList &CallArgs) override {
     assert(GD.getDtorType() == Dtor_Deleting &&
            "Only deleting destructor thunks are available in this ABI");
     CallArgs.add(RValue::get(getStructorImplicitParamValue(CGF)),
                              CGM.getContext().IntTy);
   }
 
-  void emitVirtualInheritanceTables(const CXXRecordDecl *RD);
+  void emitVirtualInheritanceTables(const CXXRecordDecl *RD) override;
 
-  void setThunkLinkage(llvm::Function *Thunk, bool ForVTable) {
-    Thunk->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
+  llvm::GlobalVariable *
+  getAddrOfVBTable(const VPtrInfo &VBT, const CXXRecordDecl *RD,
+                   llvm::GlobalVariable::LinkageTypes Linkage);
+
+  void emitVBTableDefinition(const VPtrInfo &VBT, const CXXRecordDecl *RD,
+                             llvm::GlobalVariable *GV) const;
+
+  void setThunkLinkage(llvm::Function *Thunk, bool ForVTable,
+                       GlobalDecl GD, bool ReturnAdjustment) override {
+    // Never dllimport/dllexport thunks.
+    Thunk->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
+
+    GVALinkage Linkage =
+        getContext().GetGVALinkageForFunction(cast<FunctionDecl>(GD.getDecl()));
+
+    if (Linkage == GVA_Internal)
+      Thunk->setLinkage(llvm::GlobalValue::InternalLinkage);
+    else if (ReturnAdjustment)
+      Thunk->setLinkage(llvm::GlobalValue::WeakODRLinkage);
+    else
+      Thunk->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
   }
 
   llvm::Value *performThisAdjustment(CodeGenFunction &CGF, llvm::Value *This,
-                                     const ThisAdjustment &TA);
+                                     const ThisAdjustment &TA) override;
 
   llvm::Value *performReturnAdjustment(CodeGenFunction &CGF, llvm::Value *Ret,
-                                       const ReturnAdjustment &RA);
+                                       const ReturnAdjustment &RA) override;
 
   void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
                        llvm::GlobalVariable *DeclPtr,
-                       bool PerformInit);
+                       bool PerformInit) override;
 
   // ==== Notes on array cookies =========
   //
@@ -223,17 +278,126 @@
   //   }
   // Whereas it prints "104" and "104" if you give A a destructor.
 
-  bool requiresArrayCookie(const CXXDeleteExpr *expr, QualType elementType);
-  bool requiresArrayCookie(const CXXNewExpr *expr);
-  CharUnits getArrayCookieSizeImpl(QualType type);
+  bool requiresArrayCookie(const CXXDeleteExpr *expr,
+                           QualType elementType) override;
+  bool requiresArrayCookie(const CXXNewExpr *expr) override;
+  CharUnits getArrayCookieSizeImpl(QualType type) override;
   llvm::Value *InitializeArrayCookie(CodeGenFunction &CGF,
                                      llvm::Value *NewPtr,
                                      llvm::Value *NumElements,
                                      const CXXNewExpr *expr,
-                                     QualType ElementType);
+                                     QualType ElementType) override;
   llvm::Value *readArrayCookieImpl(CodeGenFunction &CGF,
                                    llvm::Value *allocPtr,
-                                   CharUnits cookieSize);
+                                   CharUnits cookieSize) override;
+
+  friend struct MSRTTIBuilder;
+
+  bool isImageRelative() const {
+    return CGM.getTarget().getPointerWidth(/*AddressSpace=*/0) == 64;
+  }
+
+  // 5 routines for constructing the llvm types for MS RTTI structs.
+  llvm::StructType *getTypeDescriptorType(StringRef TypeInfoString) {
+    llvm::SmallString<32> TDTypeName("rtti.TypeDescriptor");
+    TDTypeName += llvm::utostr(TypeInfoString.size());
+    llvm::StructType *&TypeDescriptorType =
+        TypeDescriptorTypeMap[TypeInfoString.size()];
+    if (TypeDescriptorType)
+      return TypeDescriptorType;
+    llvm::Type *FieldTypes[] = {
+        CGM.Int8PtrPtrTy,
+        CGM.Int8PtrTy,
+        llvm::ArrayType::get(CGM.Int8Ty, TypeInfoString.size() + 1)};
+    TypeDescriptorType =
+        llvm::StructType::create(CGM.getLLVMContext(), FieldTypes, TDTypeName);
+    return TypeDescriptorType;
+  }
+
+  llvm::Type *getImageRelativeType(llvm::Type *PtrType) {
+    if (!isImageRelative())
+      return PtrType;
+    return CGM.IntTy;
+  }
+
+  llvm::StructType *getBaseClassDescriptorType() {
+    if (BaseClassDescriptorType)
+      return BaseClassDescriptorType;
+    llvm::Type *FieldTypes[] = {
+        getImageRelativeType(CGM.Int8PtrTy),
+        CGM.IntTy,
+        CGM.IntTy,
+        CGM.IntTy,
+        CGM.IntTy,
+        CGM.IntTy,
+        getImageRelativeType(getClassHierarchyDescriptorType()->getPointerTo()),
+    };
+    BaseClassDescriptorType = llvm::StructType::create(
+        CGM.getLLVMContext(), FieldTypes, "rtti.BaseClassDescriptor");
+    return BaseClassDescriptorType;
+  }
+
+  llvm::StructType *getClassHierarchyDescriptorType() {
+    if (ClassHierarchyDescriptorType)
+      return ClassHierarchyDescriptorType;
+    // Forward-declare RTTIClassHierarchyDescriptor to break a cycle.
+    ClassHierarchyDescriptorType = llvm::StructType::create(
+        CGM.getLLVMContext(), "rtti.ClassHierarchyDescriptor");
+    llvm::Type *FieldTypes[] = {
+        CGM.IntTy,
+        CGM.IntTy,
+        CGM.IntTy,
+        getImageRelativeType(
+            getBaseClassDescriptorType()->getPointerTo()->getPointerTo()),
+    };
+    ClassHierarchyDescriptorType->setBody(FieldTypes);
+    return ClassHierarchyDescriptorType;
+  }
+
+  llvm::StructType *getCompleteObjectLocatorType() {
+    if (CompleteObjectLocatorType)
+      return CompleteObjectLocatorType;
+    CompleteObjectLocatorType = llvm::StructType::create(
+        CGM.getLLVMContext(), "rtti.CompleteObjectLocator");
+    llvm::Type *FieldTypes[] = {
+        CGM.IntTy,
+        CGM.IntTy,
+        CGM.IntTy,
+        getImageRelativeType(CGM.Int8PtrTy),
+        getImageRelativeType(getClassHierarchyDescriptorType()->getPointerTo()),
+        getImageRelativeType(CompleteObjectLocatorType),
+    };
+    llvm::ArrayRef<llvm::Type *> FieldTypesRef(FieldTypes);
+    if (!isImageRelative())
+      FieldTypesRef = FieldTypesRef.drop_back();
+    CompleteObjectLocatorType->setBody(FieldTypesRef);
+    return CompleteObjectLocatorType;
+  }
+
+  llvm::GlobalVariable *getImageBase() {
+    StringRef Name = "__ImageBase";
+    if (llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(Name))
+      return GV;
+
+    return new llvm::GlobalVariable(CGM.getModule(), CGM.Int8Ty,
+                                    /*isConstant=*/true,
+                                    llvm::GlobalValue::ExternalLinkage,
+                                    /*Initializer=*/nullptr, Name);
+  }
+
+  llvm::Constant *getImageRelativeConstant(llvm::Constant *PtrVal) {
+    if (!isImageRelative())
+      return PtrVal;
+
+    llvm::Constant *ImageBaseAsInt =
+        llvm::ConstantExpr::getPtrToInt(getImageBase(), CGM.IntPtrTy);
+    llvm::Constant *PtrValAsInt =
+        llvm::ConstantExpr::getPtrToInt(PtrVal, CGM.IntPtrTy);
+    llvm::Constant *Diff =
+        llvm::ConstantExpr::getSub(PtrValAsInt, ImageBaseAsInt,
+                                   /*HasNUW=*/true, /*HasNSW=*/true);
+    return llvm::ConstantExpr::getTrunc(Diff, CGM.IntTy);
+  }
 
 private:
   MicrosoftMangleContext &getMangleContext() {
@@ -256,15 +420,12 @@
     return C ? C : getZeroInt();
   }
 
+  CharUnits getVirtualFunctionPrologueThisAdjustment(GlobalDecl GD);
+
   void
   GetNullMemberPointerFields(const MemberPointerType *MPT,
                              llvm::SmallVectorImpl<llvm::Constant *> &fields);
 
-  /// \brief Finds the offset from the base of RD to the vbptr it uses, even if
-  /// it is reusing a vbptr from a non-virtual base.  RD must have morally
-  /// virtual bases.
-  CharUnits GetVBPtrOffsetFromBases(const CXXRecordDecl *RD);
-
   /// \brief Shared code for virtual base adjustment.  Returns the offset from
   /// the vbptr to the virtual base.  Optionally returns the address of the
   /// vbptr itself.
@@ -272,13 +433,13 @@
                                        llvm::Value *Base,
                                        llvm::Value *VBPtrOffset,
                                        llvm::Value *VBTableOffset,
-                                       llvm::Value **VBPtr = 0);
+                                       llvm::Value **VBPtr = nullptr);
 
   llvm::Value *GetVBaseOffsetFromVBPtr(CodeGenFunction &CGF,
                                        llvm::Value *Base,
                                        int32_t VBPtrOffset,
                                        int32_t VBTableOffset,
-                                       llvm::Value **VBPtr = 0) {
+                                       llvm::Value **VBPtr = nullptr) {
     llvm::Value *VBPOffset = llvm::ConstantInt::get(CGM.IntTy, VBPtrOffset),
                 *VBTOffset = llvm::ConstantInt::get(CGM.IntTy, VBTableOffset);
     return GetVBaseOffsetFromVBPtr(CGF, Base, VBPOffset, VBTOffset, VBPtr);
@@ -286,8 +447,8 @@
 
   /// \brief Performs a full virtual base adjustment.  Used to dereference
   /// pointers to members of virtual bases.
-  llvm::Value *AdjustVirtualBase(CodeGenFunction &CGF, const CXXRecordDecl *RD,
-                                 llvm::Value *Base,
+  llvm::Value *AdjustVirtualBase(CodeGenFunction &CGF, const Expr *E,
+                                 const CXXRecordDecl *RD, llvm::Value *Base,
                                  llvm::Value *VirtualBaseAdjustmentOffset,
                                  llvm::Value *VBPtrOffset /* optional */);
 
@@ -309,69 +470,71 @@
   void EmitVBPtrStores(CodeGenFunction &CGF, const CXXRecordDecl *RD);
 
   /// \brief Caching wrapper around VBTableBuilder::enumerateVBTables().
-  const VBTableVector &EnumerateVBTables(const CXXRecordDecl *RD);
+  const VBTableGlobals &enumerateVBTables(const CXXRecordDecl *RD);
 
   /// \brief Generate a thunk for calling a virtual member function MD.
-  llvm::Function *EmitVirtualMemPtrThunk(const CXXMethodDecl *MD,
-                                         StringRef ThunkName);
+  llvm::Function *EmitVirtualMemPtrThunk(
+      const CXXMethodDecl *MD,
+      const MicrosoftVTableContext::MethodVFTableLocation &ML);
 
 public:
-  virtual llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT);
+  llvm::Type *ConvertMemberPointerType(const MemberPointerType *MPT) override;
 
-  virtual bool isZeroInitializable(const MemberPointerType *MPT);
+  bool isZeroInitializable(const MemberPointerType *MPT) override;
 
-  virtual llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT);
+  llvm::Constant *EmitNullMemberPointer(const MemberPointerType *MPT) override;
 
-  virtual llvm::Constant *EmitMemberDataPointer(const MemberPointerType *MPT,
-                                                CharUnits offset);
-  virtual llvm::Constant *EmitMemberPointer(const CXXMethodDecl *MD);
-  virtual llvm::Constant *EmitMemberPointer(const APValue &MP, QualType MPT);
+  llvm::Constant *EmitMemberDataPointer(const MemberPointerType *MPT,
+                                        CharUnits offset) override;
+  llvm::Constant *EmitMemberPointer(const CXXMethodDecl *MD) override;
+  llvm::Constant *EmitMemberPointer(const APValue &MP, QualType MPT) override;
 
-  virtual llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF,
-                                                   llvm::Value *L,
-                                                   llvm::Value *R,
-                                                   const MemberPointerType *MPT,
-                                                   bool Inequality);
+  llvm::Value *EmitMemberPointerComparison(CodeGenFunction &CGF,
+                                           llvm::Value *L,
+                                           llvm::Value *R,
+                                           const MemberPointerType *MPT,
+                                           bool Inequality) override;
 
-  virtual llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
-                                                  llvm::Value *MemPtr,
-                                                  const MemberPointerType *MPT);
+  llvm::Value *EmitMemberPointerIsNotNull(CodeGenFunction &CGF,
+                                          llvm::Value *MemPtr,
+                                          const MemberPointerType *MPT) override;
 
-  virtual llvm::Value *EmitMemberDataPointerAddress(CodeGenFunction &CGF,
-                                                    llvm::Value *Base,
-                                                    llvm::Value *MemPtr,
-                                                  const MemberPointerType *MPT);
+  llvm::Value *
+  EmitMemberDataPointerAddress(CodeGenFunction &CGF, const Expr *E,
+                               llvm::Value *Base, llvm::Value *MemPtr,
+                               const MemberPointerType *MPT) override;
 
-  virtual llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF,
-                                                   const CastExpr *E,
-                                                   llvm::Value *Src);
+  llvm::Value *EmitMemberPointerConversion(CodeGenFunction &CGF,
+                                           const CastExpr *E,
+                                           llvm::Value *Src) override;
 
-  virtual llvm::Constant *EmitMemberPointerConversion(const CastExpr *E,
-                                                      llvm::Constant *Src);
+  llvm::Constant *EmitMemberPointerConversion(const CastExpr *E,
+                                              llvm::Constant *Src) override;
 
-  virtual llvm::Value *
-  EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
-                                  llvm::Value *&This,
-                                  llvm::Value *MemPtr,
-                                  const MemberPointerType *MPT);
+  llvm::Value *
+  EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF, const Expr *E,
+                                  llvm::Value *&This, llvm::Value *MemPtr,
+                                  const MemberPointerType *MPT) override;
 
 private:
   typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy;
-  typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalVariable *> VFTablesMapTy;
+  typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalVariable *> VTablesMapTy;
+  typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalValue *> VFTablesMapTy;
   /// \brief All the vftables that have been referenced.
   VFTablesMapTy VFTablesMap;
+  VTablesMapTy VTablesMap;
 
   /// \brief This set holds the record decls we've deferred vtable emission for.
   llvm::SmallPtrSet<const CXXRecordDecl *, 4> DeferredVFTables;
 
 
   /// \brief All the vbtables which have been referenced.
-  llvm::DenseMap<const CXXRecordDecl *, VBTableVector> VBTablesMap;
+  llvm::DenseMap<const CXXRecordDecl *, VBTableGlobals> VBTablesMap;
 
   /// Info on the global variable used to guard initialization of static locals.
   /// The BitIndex field is only used for externally invisible declarations.
   struct GuardInfo {
-    GuardInfo() : Guard(0), BitIndex(0) {}
+    GuardInfo() : Guard(nullptr), BitIndex(0) {}
     llvm::GlobalVariable *Guard;
     unsigned BitIndex;
   };
@@ -379,10 +542,69 @@
   /// Map from DeclContext to the current guard variable.  We assume that the
   /// AST is visited in source code order.
   llvm::DenseMap<const DeclContext *, GuardInfo> GuardVariableMap;
+
+  llvm::DenseMap<size_t, llvm::StructType *> TypeDescriptorTypeMap;
+  llvm::StructType *BaseClassDescriptorType;
+  llvm::StructType *ClassHierarchyDescriptorType;
+  llvm::StructType *CompleteObjectLocatorType;
 };
 
 }
 
+CGCXXABI::RecordArgABI
+MicrosoftCXXABI::getRecordArgABI(const CXXRecordDecl *RD) const {
+  switch (CGM.getTarget().getTriple().getArch()) {
+  default:
+    // FIXME: Implement for other architectures.
+    return RAA_Default;
+
+  case llvm::Triple::x86:
+    // All record arguments are passed in memory on x86.  Decide whether to
+    // construct the object directly in argument memory, or to construct the
+    // argument elsewhere and copy the bytes during the call.
+
+    // If C++ prohibits us from making a copy, construct the arguments directly
+    // into argument memory.
+    if (!canCopyArgument(RD))
+      return RAA_DirectInMemory;
+
+    // Otherwise, construct the argument into a temporary and copy the bytes
+    // into the outgoing argument memory.
+    return RAA_Default;
+
+  case llvm::Triple::x86_64:
+    // Win64 passes objects with non-trivial copy ctors indirectly.
+    if (RD->hasNonTrivialCopyConstructor())
+      return RAA_Indirect;
+
+    // Win64 passes objects larger than 8 bytes indirectly.
+    if (getContext().getTypeSize(RD->getTypeForDecl()) > 64)
+      return RAA_Indirect;
+
+    // We have a trivial copy constructor or no copy constructors, but we have
+    // to make sure it isn't deleted.
+    bool CopyDeleted = false;
+    for (const CXXConstructorDecl *CD : RD->ctors()) {
+      if (CD->isCopyConstructor()) {
+        assert(CD->isTrivial());
+        // We had at least one undeleted trivial copy ctor.  Return directly.
+        if (!CD->isDeleted())
+          return RAA_Default;
+        CopyDeleted = true;
+      }
+    }
+
+    // The trivial copy constructor was deleted.  Return indirectly.
+    if (CopyDeleted)
+      return RAA_Indirect;
+
+    // There were no copy ctors.  Return in RAX.
+    return RAA_Default;
+  }
+
+  llvm_unreachable("invalid enum");
+}
+
 llvm::Value *MicrosoftCXXABI::adjustToCompleteObject(CodeGenFunction &CGF,
                                                      llvm::Value *ptr,
                                                      QualType type) {
@@ -390,33 +612,127 @@
   return ptr;
 }
 
-/// \brief Finds the first non-virtual base of RD that has virtual bases.  If RD
-/// doesn't have a vbptr, it will reuse the vbptr of the returned class.
-static const CXXRecordDecl *FindFirstNVBaseWithVBases(const CXXRecordDecl *RD) {
-  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
-       E = RD->bases_end(); I != E; ++I) {
-    const CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl();
-    if (!I->isVirtual() && Base->getNumVBases() > 0)
-      return Base;
-  }
-  llvm_unreachable("RD must have an nv base with vbases");
+/// \brief Gets the offset to the virtual base that contains the vfptr for
+/// MS-ABI polymorphic types.
+static llvm::Value *getPolymorphicOffset(CodeGenFunction &CGF,
+                                         const CXXRecordDecl *RD,
+                                         llvm::Value *Value) {
+  const ASTContext &Context = RD->getASTContext();
+  for (const CXXBaseSpecifier &Base : RD->vbases())
+    if (Context.getASTRecordLayout(Base.getType()->getAsCXXRecordDecl())
+            .hasExtendableVFPtr())
+      return CGF.CGM.getCXXABI().GetVirtualBaseClassOffset(
+          CGF, Value, RD, Base.getType()->getAsCXXRecordDecl());
+  llvm_unreachable("One of our vbases should be polymorphic.");
 }
 
-CharUnits MicrosoftCXXABI::GetVBPtrOffsetFromBases(const CXXRecordDecl *RD) {
-  assert(RD->getNumVBases());
-  CharUnits Total = CharUnits::Zero();
-  while (RD) {
-    const ASTRecordLayout &RDLayout = getContext().getASTRecordLayout(RD);
-    CharUnits VBPtrOffset = RDLayout.getVBPtrOffset();
-    // -1 is the sentinel for no vbptr.
-    if (VBPtrOffset != CharUnits::fromQuantity(-1)) {
-      Total += VBPtrOffset;
-      break;
-    }
-    RD = FindFirstNVBaseWithVBases(RD);
-    Total += RDLayout.getBaseClassOffset(RD);
-  }
-  return Total;
+static std::pair<llvm::Value *, llvm::Value *>
+performBaseAdjustment(CodeGenFunction &CGF, llvm::Value *Value,
+                      QualType SrcRecordTy) {
+  Value = CGF.Builder.CreateBitCast(Value, CGF.Int8PtrTy);
+  const CXXRecordDecl *SrcDecl = SrcRecordTy->getAsCXXRecordDecl();
+
+  if (CGF.getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr())
+    return std::make_pair(Value, llvm::ConstantInt::get(CGF.Int32Ty, 0));
+
+  // Perform a base adjustment.
+  llvm::Value *Offset = getPolymorphicOffset(CGF, SrcDecl, Value);
+  Value = CGF.Builder.CreateInBoundsGEP(Value, Offset);
+  Offset = CGF.Builder.CreateTrunc(Offset, CGF.Int32Ty);
+  return std::make_pair(Value, Offset);
+}
+
+bool MicrosoftCXXABI::shouldTypeidBeNullChecked(bool IsDeref,
+                                                QualType SrcRecordTy) {
+  const CXXRecordDecl *SrcDecl = SrcRecordTy->getAsCXXRecordDecl();
+  return IsDeref &&
+         !CGM.getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
+}
+
+static llvm::CallSite emitRTtypeidCall(CodeGenFunction &CGF,
+                                       llvm::Value *Argument) {
+  llvm::Type *ArgTypes[] = {CGF.Int8PtrTy};
+  llvm::FunctionType *FTy =
+      llvm::FunctionType::get(CGF.Int8PtrTy, ArgTypes, false);
+  llvm::Value *Args[] = {Argument};
+  llvm::Constant *Fn = CGF.CGM.CreateRuntimeFunction(FTy, "__RTtypeid");
+  return CGF.EmitRuntimeCallOrInvoke(Fn, Args);
+}
+
+void MicrosoftCXXABI::EmitBadTypeidCall(CodeGenFunction &CGF) {
+  llvm::CallSite Call =
+      emitRTtypeidCall(CGF, llvm::Constant::getNullValue(CGM.VoidPtrTy));
+  Call.setDoesNotReturn();
+  CGF.Builder.CreateUnreachable();
+}
+
+llvm::Value *MicrosoftCXXABI::EmitTypeid(CodeGenFunction &CGF,
+                                         QualType SrcRecordTy,
+                                         llvm::Value *ThisPtr,
+                                         llvm::Type *StdTypeInfoPtrTy) {
+  llvm::Value *Offset;
+  std::tie(ThisPtr, Offset) = performBaseAdjustment(CGF, ThisPtr, SrcRecordTy);
+  return CGF.Builder.CreateBitCast(
+      emitRTtypeidCall(CGF, ThisPtr).getInstruction(), StdTypeInfoPtrTy);
+}
+
+bool MicrosoftCXXABI::shouldDynamicCastCallBeNullChecked(bool SrcIsPtr,
+                                                         QualType SrcRecordTy) {
+  const CXXRecordDecl *SrcDecl = SrcRecordTy->getAsCXXRecordDecl();
+  return SrcIsPtr &&
+         !CGM.getContext().getASTRecordLayout(SrcDecl).hasExtendableVFPtr();
+}
+
+llvm::Value *MicrosoftCXXABI::EmitDynamicCastCall(
+    CodeGenFunction &CGF, llvm::Value *Value, QualType SrcRecordTy,
+    QualType DestTy, QualType DestRecordTy, llvm::BasicBlock *CastEnd) {
+  llvm::Type *DestLTy = CGF.ConvertType(DestTy);
+
+  llvm::Value *SrcRTTI =
+      CGF.CGM.GetAddrOfRTTIDescriptor(SrcRecordTy.getUnqualifiedType());
+  llvm::Value *DestRTTI =
+      CGF.CGM.GetAddrOfRTTIDescriptor(DestRecordTy.getUnqualifiedType());
+
+  llvm::Value *Offset;
+  std::tie(Value, Offset) = performBaseAdjustment(CGF, Value, SrcRecordTy);
+
+  // PVOID __RTDynamicCast(
+  //   PVOID inptr,
+  //   LONG VfDelta,
+  //   PVOID SrcType,
+  //   PVOID TargetType,
+  //   BOOL isReference)
+  llvm::Type *ArgTypes[] = {CGF.Int8PtrTy, CGF.Int32Ty, CGF.Int8PtrTy,
+                            CGF.Int8PtrTy, CGF.Int32Ty};
+  llvm::Constant *Function = CGF.CGM.CreateRuntimeFunction(
+      llvm::FunctionType::get(CGF.Int8PtrTy, ArgTypes, false),
+      "__RTDynamicCast");
+  llvm::Value *Args[] = {
+      Value, Offset, SrcRTTI, DestRTTI,
+      llvm::ConstantInt::get(CGF.Int32Ty, DestTy->isReferenceType())};
+  Value = CGF.EmitRuntimeCallOrInvoke(Function, Args).getInstruction();
+  return CGF.Builder.CreateBitCast(Value, DestLTy);
+}
+
+llvm::Value *
+MicrosoftCXXABI::EmitDynamicCastToVoid(CodeGenFunction &CGF, llvm::Value *Value,
+                                       QualType SrcRecordTy,
+                                       QualType DestTy) {
+  llvm::Value *Offset;
+  std::tie(Value, Offset) = performBaseAdjustment(CGF, Value, SrcRecordTy);
+
+  // PVOID __RTCastToVoid(
+  //   PVOID inptr)
+  llvm::Type *ArgTypes[] = {CGF.Int8PtrTy};
+  llvm::Constant *Function = CGF.CGM.CreateRuntimeFunction(
+      llvm::FunctionType::get(CGF.Int8PtrTy, ArgTypes, false),
+      "__RTCastToVoid");
+  llvm::Value *Args[] = {Value};
+  return CGF.EmitRuntimeCall(Function, Args);
+}
+
+bool MicrosoftCXXABI::EmitBadCastCall(CodeGenFunction &CGF) {
+  return false;
 }
 
 llvm::Value *
@@ -424,7 +740,8 @@
                                            llvm::Value *This,
                                            const CXXRecordDecl *ClassDecl,
                                            const CXXRecordDecl *BaseClassDecl) {
-  int64_t VBPtrChars = GetVBPtrOffsetFromBases(ClassDecl).getQuantity();
+  int64_t VBPtrChars =
+      getContext().getASTRecordLayout(ClassDecl).getVBPtrOffset().getQuantity();
   llvm::Value *VBPtrOffset = llvm::ConstantInt::get(CGM.PtrDiffTy, VBPtrChars);
   CharUnits IntSize = getContext().getTypeSizeInChars(getContext().IntTy);
   CharUnits VBTableChars =
@@ -444,16 +761,41 @@
   return isa<CXXConstructorDecl>(GD.getDecl());
 }
 
-void MicrosoftCXXABI::BuildConstructorSignature(const CXXConstructorDecl *Ctor,
-                                 CXXCtorType Type,
-                                 CanQualType &ResTy,
-                                 SmallVectorImpl<CanQualType> &ArgTys) {
-  // 'this' parameter and 'this' return are already in place
+bool MicrosoftCXXABI::classifyReturnType(CGFunctionInfo &FI) const {
+  const CXXRecordDecl *RD = FI.getReturnType()->getAsCXXRecordDecl();
+  if (!RD)
+    return false;
+
+  if (FI.isInstanceMethod()) {
+    // If it's an instance method, aggregates are always returned indirectly via
+    // the second parameter.
+    FI.getReturnInfo() = ABIArgInfo::getIndirect(0, /*ByVal=*/false);
+    FI.getReturnInfo().setSRetAfterThis(FI.isInstanceMethod());
+    return true;
+  } else if (!RD->isPOD()) {
+    // If it's a free function, non-POD types are returned indirectly.
+    FI.getReturnInfo() = ABIArgInfo::getIndirect(0, /*ByVal=*/false);
+    return true;
+  }
+
+  // Otherwise, use the C ABI rules.
+  return false;
+}
+
+void MicrosoftCXXABI::BuildConstructorSignature(
+    const CXXConstructorDecl *Ctor, CXXCtorType Type, CanQualType &ResTy,
+    SmallVectorImpl<CanQualType> &ArgTys) {
+
+  // All parameters are already in place except is_most_derived, which goes
+  // after 'this' if it's variadic and last if it's not.
 
   const CXXRecordDecl *Class = Ctor->getParent();
+  const FunctionProtoType *FPT = Ctor->getType()->castAs<FunctionProtoType>();
   if (Class->getNumVBases()) {
-    // Constructors of classes with virtual bases take an implicit parameter.
-    ArgTys.push_back(CGM.getContext().IntTy);
+    if (FPT->isVariadic())
+      ArgTys.insert(ArgTys.begin() + 1, CGM.getContext().IntTy);
+    else
+      ArgTys.push_back(CGM.getContext().IntTy);
   }
 }
 
@@ -503,7 +845,7 @@
 
   unsigned AS =
       cast<llvm::PointerType>(getThisValue(CGF)->getType())->getAddressSpace();
-  llvm::Value *Int8This = 0;  // Initialize lazily.
+  llvm::Value *Int8This = nullptr;  // Initialize lazily.
 
   for (VBOffsets::const_iterator I = VBaseMap.begin(), E = VBaseMap.end();
         I != E; ++I) {
@@ -545,19 +887,23 @@
                                       const CXXRecordDecl *RD) {
   llvm::Value *ThisInt8Ptr =
     CGF.Builder.CreateBitCast(getThisValue(CGF), CGM.Int8PtrTy, "this.int8");
+  const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
 
-  const VBTableVector &VBTables = EnumerateVBTables(RD);
-  for (VBTableVector::const_iterator I = VBTables.begin(), E = VBTables.end();
-       I != E; ++I) {
+  const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
+  for (unsigned I = 0, E = VBGlobals.VBTables->size(); I != E; ++I) {
+    const VPtrInfo *VBT = (*VBGlobals.VBTables)[I];
+    llvm::GlobalVariable *GV = VBGlobals.Globals[I];
     const ASTRecordLayout &SubobjectLayout =
-      CGM.getContext().getASTRecordLayout(I->VBPtrSubobject.getBase());
-    uint64_t Offs = (I->VBPtrSubobject.getBaseOffset() +
-                     SubobjectLayout.getVBPtrOffset()).getQuantity();
+        CGM.getContext().getASTRecordLayout(VBT->BaseWithVPtr);
+    CharUnits Offs = VBT->NonVirtualOffset;
+    Offs += SubobjectLayout.getVBPtrOffset();
+    if (VBT->getVBaseWithVPtr())
+      Offs += Layout.getVBaseClassOffset(VBT->getVBaseWithVPtr());
     llvm::Value *VBPtr =
-        CGF.Builder.CreateConstInBoundsGEP1_64(ThisInt8Ptr, Offs);
-    VBPtr = CGF.Builder.CreateBitCast(VBPtr, I->GV->getType()->getPointerTo(0),
-                                      "vbptr." + I->ReusingBase->getName());
-    CGF.Builder.CreateStore(I->GV, VBPtr);
+        CGF.Builder.CreateConstInBoundsGEP1_64(ThisInt8Ptr, Offs.getQuantity());
+    VBPtr = CGF.Builder.CreateBitCast(VBPtr, GV->getType()->getPointerTo(0),
+                                      "vbptr." + VBT->ReusingBase->getName());
+    CGF.Builder.CreateStore(GV, VBPtr);
   }
 }
 
@@ -581,12 +927,61 @@
   CGM.EmitGlobal(GlobalDecl(D, Dtor_Base));
 }
 
-llvm::Value *MicrosoftCXXABI::adjustThisArgumentForVirtualCall(
-    CodeGenFunction &CGF, GlobalDecl GD, llvm::Value *This) {
+CharUnits
+MicrosoftCXXABI::getVirtualFunctionPrologueThisAdjustment(GlobalDecl GD) {
   GD = GD.getCanonicalDecl();
   const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
-  // FIXME: consider splitting the vdtor vs regular method code into two
-  // functions.
+
+  GlobalDecl LookupGD = GD;
+  if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
+    // Complete destructors take a pointer to the complete object as a
+    // parameter, thus don't need this adjustment.
+    if (GD.getDtorType() == Dtor_Complete)
+      return CharUnits();
+
+    // There's no Dtor_Base in vftable but it shares the this adjustment with
+    // the deleting one, so look it up instead.
+    LookupGD = GlobalDecl(DD, Dtor_Deleting);
+  }
+
+  MicrosoftVTableContext::MethodVFTableLocation ML =
+      CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD);
+  CharUnits Adjustment = ML.VFPtrOffset;
+
+  // Normal virtual instance methods need to adjust from the vfptr that first
+  // defined the virtual method to the virtual base subobject, but destructors
+  // do not.  The vector deleting destructor thunk applies this adjustment for
+  // us if necessary.
+  if (isa<CXXDestructorDecl>(MD))
+    Adjustment = CharUnits::Zero();
+
+  if (ML.VBase) {
+    const ASTRecordLayout &DerivedLayout =
+        CGM.getContext().getASTRecordLayout(MD->getParent());
+    Adjustment += DerivedLayout.getVBaseClassOffset(ML.VBase);
+  }
+
+  return Adjustment;
+}
+
+llvm::Value *MicrosoftCXXABI::adjustThisArgumentForVirtualFunctionCall(
+    CodeGenFunction &CGF, GlobalDecl GD, llvm::Value *This, bool VirtualCall) {
+  if (!VirtualCall) {
+    // If the call of a virtual function is not virtual, we just have to
+    // compensate for the adjustment the virtual function does in its prologue.
+    CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(GD);
+    if (Adjustment.isZero())
+      return This;
+
+    unsigned AS = cast<llvm::PointerType>(This->getType())->getAddressSpace();
+    llvm::Type *charPtrTy = CGF.Int8Ty->getPointerTo(AS);
+    This = CGF.Builder.CreateBitCast(This, charPtrTy);
+    assert(Adjustment.isPositive());
+    return CGF.Builder.CreateConstGEP1_32(This, Adjustment.getQuantity());
+  }
+
+  GD = GD.getCanonicalDecl();
+  const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
 
   GlobalDecl LookupGD = GD;
   if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
@@ -605,51 +1000,18 @@
   unsigned AS = cast<llvm::PointerType>(This->getType())->getAddressSpace();
   llvm::Type *charPtrTy = CGF.Int8Ty->getPointerTo(AS);
   CharUnits StaticOffset = ML.VFPtrOffset;
+
+  // Base destructors expect 'this' to point to the beginning of the base
+  // subobject, not the first vfptr that happens to contain the virtual dtor.
+  // However, we still need to apply the virtual base adjustment.
+  if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base)
+    StaticOffset = CharUnits::Zero();
+
   if (ML.VBase) {
-    bool AvoidVirtualOffset = false;
-    if (isa<CXXDestructorDecl>(MD) && GD.getDtorType() == Dtor_Base) {
-      // A base destructor can only be called from a complete destructor of the
-      // same record type or another destructor of a more derived type;
-      // or a constructor of the same record type if an exception is thrown.
-      assert(isa<CXXDestructorDecl>(CGF.CurGD.getDecl()) ||
-             isa<CXXConstructorDecl>(CGF.CurGD.getDecl()));
-      const CXXRecordDecl *CurRD =
-          cast<CXXMethodDecl>(CGF.CurGD.getDecl())->getParent();
-
-      if (MD->getParent() == CurRD) {
-        if (isa<CXXDestructorDecl>(CGF.CurGD.getDecl()))
-          assert(CGF.CurGD.getDtorType() == Dtor_Complete);
-        if (isa<CXXConstructorDecl>(CGF.CurGD.getDecl()))
-          assert(CGF.CurGD.getCtorType() == Ctor_Complete);
-        // We're calling the main base dtor from a complete structor,
-        // so we know the "this" offset statically.
-        AvoidVirtualOffset = true;
-      } else {
-        // Let's see if we try to call a destructor of a non-virtual base.
-        for (CXXRecordDecl::base_class_const_iterator I = CurRD->bases_begin(),
-             E = CurRD->bases_end(); I != E; ++I) {
-          if (I->getType()->getAsCXXRecordDecl() != MD->getParent())
-            continue;
-          // If we call a base destructor for a non-virtual base, we statically
-          // know where it expects the vfptr and "this" to be.
-          // The total offset should reflect the adjustment done by
-          // adjustThisParameterInVirtualFunctionPrologue().
-          AvoidVirtualOffset = true;
-          break;
-        }
-      }
-    }
-
-    if (AvoidVirtualOffset) {
-      const ASTRecordLayout &Layout =
-          CGF.getContext().getASTRecordLayout(MD->getParent());
-      StaticOffset += Layout.getVBaseClassOffset(ML.VBase);
-    } else {
-      This = CGF.Builder.CreateBitCast(This, charPtrTy);
-      llvm::Value *VBaseOffset =
-          GetVirtualBaseClassOffset(CGF, This, MD->getParent(), ML.VBase);
-      This = CGF.Builder.CreateInBoundsGEP(This, VBaseOffset);
-    }
+    This = CGF.Builder.CreateBitCast(This, charPtrTy);
+    llvm::Value *VBaseOffset =
+        GetVirtualBaseClassOffset(CGF, This, MD->getParent(), ML.VBase);
+    This = CGF.Builder.CreateInBoundsGEP(This, VBaseOffset);
   }
   if (!StaticOffset.isZero()) {
     assert(StaticOffset.isPositive());
@@ -676,24 +1038,29 @@
   return false;
 }
 
-void MicrosoftCXXABI::BuildInstanceFunctionParams(CodeGenFunction &CGF,
-                                                  QualType &ResTy,
-                                                  FunctionArgList &Params) {
-  BuildThisParam(CGF, Params);
-
+void MicrosoftCXXABI::addImplicitStructorParams(CodeGenFunction &CGF,
+                                                QualType &ResTy,
+                                                FunctionArgList &Params) {
   ASTContext &Context = getContext();
   const CXXMethodDecl *MD = cast<CXXMethodDecl>(CGF.CurGD.getDecl());
+  assert(isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD));
   if (isa<CXXConstructorDecl>(MD) && MD->getParent()->getNumVBases()) {
     ImplicitParamDecl *IsMostDerived
-      = ImplicitParamDecl::Create(Context, 0,
+      = ImplicitParamDecl::Create(Context, nullptr,
                                   CGF.CurGD.getDecl()->getLocation(),
                                   &Context.Idents.get("is_most_derived"),
                                   Context.IntTy);
-    Params.push_back(IsMostDerived);
+    // The 'most_derived' parameter goes second if the ctor is variadic and last
+    // if it's not.  Dtors can't be variadic.
+    const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();
+    if (FPT->isVariadic())
+      Params.insert(Params.begin() + 1, IsMostDerived);
+    else
+      Params.push_back(IsMostDerived);
     getStructorImplicitParamDecl(CGF) = IsMostDerived;
   } else if (IsDeletingDtor(CGF.CurGD)) {
     ImplicitParamDecl *ShouldDelete
-      = ImplicitParamDecl::Create(Context, 0,
+      = ImplicitParamDecl::Create(Context, nullptr,
                                   CGF.CurGD.getDecl()->getLocation(),
                                   &Context.Idents.get("should_call_delete"),
                                   Context.IntTy);
@@ -704,36 +1071,12 @@
 
 llvm::Value *MicrosoftCXXABI::adjustThisParameterInVirtualFunctionPrologue(
     CodeGenFunction &CGF, GlobalDecl GD, llvm::Value *This) {
-  GD = GD.getCanonicalDecl();
-  const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
-
-  GlobalDecl LookupGD = GD;
-  if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
-    // Complete destructors take a pointer to the complete object as a
-    // parameter, thus don't need this adjustment.
-    if (GD.getDtorType() == Dtor_Complete)
-      return This;
-
-    // There's no Dtor_Base in vftable but it shares the this adjustment with
-    // the deleting one, so look it up instead.
-    LookupGD = GlobalDecl(DD, Dtor_Deleting);
-  }
-
   // In this ABI, every virtual function takes a pointer to one of the
   // subobjects that first defines it as the 'this' parameter, rather than a
-  // pointer to ther final overrider subobject. Thus, we need to adjust it back
+  // pointer to the final overrider subobject. Thus, we need to adjust it back
   // to the final overrider subobject before use.
   // See comments in the MicrosoftVFTableContext implementation for the details.
-
-  MicrosoftVTableContext::MethodVFTableLocation ML =
-      CGM.getMicrosoftVTableContext().getMethodVFTableLocation(LookupGD);
-  CharUnits Adjustment = ML.VFPtrOffset;
-  if (ML.VBase) {
-    const ASTRecordLayout &DerivedLayout =
-        CGF.getContext().getASTRecordLayout(MD->getParent());
-    Adjustment += DerivedLayout.getVBaseClassOffset(ML.VBase);
-  }
-
+  CharUnits Adjustment = getVirtualFunctionPrologueThisAdjustment(GD);
   if (Adjustment.isZero())
     return This;
 
@@ -782,61 +1125,81 @@
   }
 }
 
-void MicrosoftCXXABI::EmitConstructorCall(CodeGenFunction &CGF,
-                                          const CXXConstructorDecl *D,
-                                          CXXCtorType Type, 
-                                          bool ForVirtualBase,
-                                          bool Delegating,
-                                          llvm::Value *This,
-                                          CallExpr::const_arg_iterator ArgBeg,
-                                          CallExpr::const_arg_iterator ArgEnd) {
+unsigned MicrosoftCXXABI::addImplicitConstructorArgs(
+    CodeGenFunction &CGF, const CXXConstructorDecl *D, CXXCtorType Type,
+    bool ForVirtualBase, bool Delegating, CallArgList &Args) {
   assert(Type == Ctor_Complete || Type == Ctor_Base);
-  llvm::Value *Callee = CGM.GetAddrOfCXXConstructor(D, Ctor_Complete);
 
-  llvm::Value *ImplicitParam = 0;
-  QualType ImplicitParamTy;
-  if (D->getParent()->getNumVBases()) {
-    ImplicitParam = llvm::ConstantInt::get(CGM.Int32Ty, Type == Ctor_Complete);
-    ImplicitParamTy = getContext().IntTy;
+  // Check if we need a 'most_derived' parameter.
+  if (!D->getParent()->getNumVBases())
+    return 0;
+
+  // Add the 'most_derived' argument second if we are variadic or last if not.
+  const FunctionProtoType *FPT = D->getType()->castAs<FunctionProtoType>();
+  llvm::Value *MostDerivedArg =
+      llvm::ConstantInt::get(CGM.Int32Ty, Type == Ctor_Complete);
+  RValue RV = RValue::get(MostDerivedArg);
+  if (MostDerivedArg) {
+    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.
+}
+
+void MicrosoftCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
+                                         const CXXDestructorDecl *DD,
+                                         CXXDtorType Type, bool ForVirtualBase,
+                                         bool Delegating, llvm::Value *This) {
+  llvm::Value *Callee = CGM.GetAddrOfCXXDestructor(DD, Type);
+
+  if (DD->isVirtual()) {
+    assert(Type != CXXDtorType::Dtor_Deleting &&
+           "The deleting destructor should only be called via a virtual call");
+    This = adjustThisArgumentForVirtualFunctionCall(CGF, GlobalDecl(DD, Type),
+                                                    This, false);
   }
 
   // FIXME: Provide a source location here.
-  CGF.EmitCXXMemberCall(D, SourceLocation(), Callee, ReturnValueSlot(), This,
-                        ImplicitParam, ImplicitParamTy, ArgBeg, ArgEnd);
+  CGF.EmitCXXMemberCall(DD, SourceLocation(), Callee, ReturnValueSlot(), This,
+                        /*ImplicitParam=*/nullptr,
+                        /*ImplicitParamTy=*/QualType(), nullptr, nullptr);
 }
 
 void MicrosoftCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,
                                             const CXXRecordDecl *RD) {
   MicrosoftVTableContext &VFTContext = CGM.getMicrosoftVTableContext();
-  MicrosoftVTableContext::VFPtrListTy VFPtrs = VFTContext.getVFPtrOffsets(RD);
-  llvm::GlobalVariable::LinkageTypes Linkage = CGM.getVTableLinkage(RD);
+  VPtrInfoVector VFPtrs = VFTContext.getVFPtrOffsets(RD);
 
-  for (MicrosoftVTableContext::VFPtrListTy::iterator I = VFPtrs.begin(),
-       E = VFPtrs.end(); I != E; ++I) {
-    llvm::GlobalVariable *VTable = getAddrOfVTable(RD, I->VFPtrFullOffset);
+  for (VPtrInfo *Info : VFPtrs) {
+    llvm::GlobalVariable *VTable = getAddrOfVTable(RD, Info->FullOffsetInMDC);
     if (VTable->hasInitializer())
       continue;
 
+    llvm::Constant *RTTI = getMSCompleteObjectLocator(RD, Info);
+
     const VTableLayout &VTLayout =
-        VFTContext.getVFTableLayout(RD, I->VFPtrFullOffset);
+      VFTContext.getVFTableLayout(RD, Info->FullOffsetInMDC);
     llvm::Constant *Init = CGVT.CreateVTableInitializer(
         RD, VTLayout.vtable_component_begin(),
         VTLayout.getNumVTableComponents(), VTLayout.vtable_thunk_begin(),
-        VTLayout.getNumVTableThunks());
-    VTable->setInitializer(Init);
+        VTLayout.getNumVTableThunks(), RTTI);
 
-    VTable->setLinkage(Linkage);
-    CGM.setTypeVisibility(VTable, RD, CodeGenModule::TVK_ForVTable);
+    VTable->setInitializer(Init);
   }
 }
 
 llvm::Value *MicrosoftCXXABI::getVTableAddressPointInStructor(
     CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, BaseSubobject Base,
     const CXXRecordDecl *NearestVBase, bool &NeedsVirtualOffset) {
-  NeedsVirtualOffset = (NearestVBase != 0);
+  NeedsVirtualOffset = (NearestVBase != nullptr);
 
-  llvm::Value *VTableAddressPoint =
-      getAddrOfVTable(VTableClass, Base.getBaseOffset());
+  (void)getAddrOfVTable(VTableClass, Base.getBaseOffset());
+  VFTableIdTy ID(VTableClass, Base.getBaseOffset());
+  llvm::GlobalValue *VTableAddressPoint = VFTablesMap[ID];
   if (!VTableAddressPoint) {
     assert(Base.getBase()->getNumVBases() &&
            !CGM.getContext().getASTRecordLayout(Base.getBase()).hasOwnVFPtr());
@@ -845,17 +1208,19 @@
 }
 
 static void mangleVFTableName(MicrosoftMangleContext &MangleContext,
-                              const CXXRecordDecl *RD, const VFPtrInfo &VFPtr,
+                              const CXXRecordDecl *RD, const VPtrInfo *VFPtr,
                               SmallString<256> &Name) {
   llvm::raw_svector_ostream Out(Name);
-  MangleContext.mangleCXXVFTable(RD, VFPtr.PathToMangle, Out);
+  MangleContext.mangleCXXVFTable(RD, VFPtr->MangledPath, Out);
 }
 
 llvm::Constant *MicrosoftCXXABI::getVTableAddressPointForConstExpr(
     BaseSubobject Base, const CXXRecordDecl *VTableClass) {
-  llvm::Constant *VTable = getAddrOfVTable(VTableClass, Base.getBaseOffset());
-  assert(VTable && "Couldn't find a vftable for the given base?");
-  return VTable;
+  (void)getAddrOfVTable(VTableClass, Base.getBaseOffset());
+  VFTableIdTy ID(VTableClass, Base.getBaseOffset());
+  llvm::GlobalValue *VFTable = VFTablesMap[ID];
+  assert(VFTable && "Couldn't find a vftable for the given base?");
+  return VFTable;
 }
 
 llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(const CXXRecordDecl *RD,
@@ -864,18 +1229,16 @@
   // shouldn't be used in the given record type. We want to cache this result in
   // VFTablesMap, thus a simple zero check is not sufficient.
   VFTableIdTy ID(RD, VPtrOffset);
-  VFTablesMapTy::iterator I;
+  VTablesMapTy::iterator I;
   bool Inserted;
-  llvm::tie(I, Inserted) = VFTablesMap.insert(
-      std::make_pair(ID, static_cast<llvm::GlobalVariable *>(0)));
+  std::tie(I, Inserted) = VTablesMap.insert(std::make_pair(ID, nullptr));
   if (!Inserted)
     return I->second;
 
   llvm::GlobalVariable *&VTable = I->second;
 
   MicrosoftVTableContext &VTContext = CGM.getMicrosoftVTableContext();
-  const MicrosoftVTableContext::VFPtrListTy &VFPtrs =
-      VTContext.getVFPtrOffsets(RD);
+  const VPtrInfoVector &VFPtrs = VTContext.getVFPtrOffsets(RD);
 
   if (DeferredVFTables.insert(RD)) {
     // We haven't processed this record type before.
@@ -896,19 +1259,94 @@
   }
 
   for (size_t J = 0, F = VFPtrs.size(); J != F; ++J) {
-    if (VFPtrs[J].VFPtrFullOffset != VPtrOffset)
+    if (VFPtrs[J]->FullOffsetInMDC != VPtrOffset)
       continue;
+    SmallString<256> VFTableName;
+    mangleVFTableName(getMangleContext(), RD, VFPtrs[J], VFTableName);
+    StringRef VTableName = VFTableName;
 
-    llvm::ArrayType *ArrayType = llvm::ArrayType::get(
-        CGM.Int8PtrTy,
-        VTContext.getVFTableLayout(RD, VFPtrs[J].VFPtrFullOffset)
-            .getNumVTableComponents());
+    uint64_t NumVTableSlots =
+        VTContext.getVFTableLayout(RD, VFPtrs[J]->FullOffsetInMDC)
+            .getNumVTableComponents();
+    llvm::GlobalValue::LinkageTypes VTableLinkage =
+        llvm::GlobalValue::ExternalLinkage;
+    llvm::ArrayType *VTableType =
+        llvm::ArrayType::get(CGM.Int8PtrTy, NumVTableSlots);
+    if (getContext().getLangOpts().RTTIData) {
+      VTableLinkage = llvm::GlobalValue::PrivateLinkage;
+      VTableName = "";
+    }
 
-    SmallString<256> Name;
-    mangleVFTableName(getMangleContext(), RD, VFPtrs[J], Name);
-    VTable = CGM.CreateOrReplaceCXXRuntimeVariable(
-        Name.str(), ArrayType, llvm::GlobalValue::ExternalLinkage);
-    VTable->setUnnamedAddr(true);
+    VTable = CGM.getModule().getNamedGlobal(VFTableName);
+    if (!VTable) {
+      // Create a backing variable for the contents of VTable.  The VTable may
+      // or may not include space for a pointer to RTTI data.
+      llvm::GlobalValue *VFTable = VTable = new llvm::GlobalVariable(
+          CGM.getModule(), VTableType, /*isConstant=*/true, VTableLinkage,
+          /*Initializer=*/nullptr, VTableName);
+      VTable->setUnnamedAddr(true);
+
+      // Only insert a pointer into the VFTable for RTTI data if we are not
+      // importing it.  We never reference the RTTI data directly so there is no
+      // need to make room for it.
+      if (getContext().getLangOpts().RTTIData &&
+          !RD->hasAttr<DLLImportAttr>()) {
+        llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.IntTy, 0),
+                                     llvm::ConstantInt::get(CGM.IntTy, 1)};
+        // Create a GEP which points just after the first entry in the VFTable,
+        // this should be the location of the first virtual method.
+        llvm::Constant *VTableGEP =
+            llvm::ConstantExpr::getInBoundsGetElementPtr(VTable, GEPIndices);
+        // The symbol for the VFTable is an alias to the GEP.  It is
+        // transparent, to other modules, what the nature of this symbol is; all
+        // that matters is that the alias be the address of the first virtual
+        // method.
+        VFTable = llvm::GlobalAlias::create(
+            cast<llvm::SequentialType>(VTableGEP->getType())->getElementType(),
+            /*AddressSpace=*/0, llvm::GlobalValue::ExternalLinkage,
+            VFTableName.str(), VTableGEP, &CGM.getModule());
+      } else {
+        // We don't need a GlobalAlias to be a symbol for the VTable if we won't
+        // be referencing any RTTI data.  The GlobalVariable will end up being
+        // an appropriate definition of the VFTable.
+        VTable->setName(VFTableName.str());
+      }
+
+      VFTable->setUnnamedAddr(true);
+      if (RD->hasAttr<DLLImportAttr>())
+        VFTable->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
+      else if (RD->hasAttr<DLLExportAttr>())
+        VFTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
+
+      llvm::GlobalValue::LinkageTypes VFTableLinkage = CGM.getVTableLinkage(RD);
+      if (VFTable != VTable) {
+        if (llvm::GlobalValue::isAvailableExternallyLinkage(VFTableLinkage)) {
+          // AvailableExternally implies that we grabbed the data from another
+          // executable.  No need to stick the alias in a Comdat.
+        } else if (llvm::GlobalValue::isInternalLinkage(VFTableLinkage) ||
+                   llvm::GlobalValue::isWeakODRLinkage(VFTableLinkage) ||
+                   llvm::GlobalValue::isLinkOnceODRLinkage(VFTableLinkage)) {
+          // The alias is going to be dropped into a Comdat, no need to make it
+          // weak.
+          if (!llvm::GlobalValue::isInternalLinkage(VFTableLinkage))
+            VFTableLinkage = llvm::GlobalValue::ExternalLinkage;
+          llvm::Comdat *C =
+              CGM.getModule().getOrInsertComdat(VFTable->getName());
+          // We must indicate which VFTable is larger to support linking between
+          // translation units which do and do not have RTTI data.  The largest
+          // VFTable contains the RTTI data; translation units which reference
+          // the smaller VFTable always reference it relative to the first
+          // virtual method.
+          C->setSelectionKind(llvm::Comdat::Largest);
+          VTable->setComdat(C);
+        } else {
+          llvm_unreachable("unexpected linkage for vftable!");
+        }
+      }
+      VFTable->setLinkage(VFTableLinkage);
+      CGM.setGlobalVisibility(VFTable, RD);
+      VFTablesMap[ID] = VFTable;
+    }
     break;
   }
 
@@ -923,7 +1361,8 @@
   CGBuilderTy &Builder = CGF.Builder;
 
   Ty = Ty->getPointerTo()->getPointerTo();
-  llvm::Value *VPtr = adjustThisArgumentForVirtualCall(CGF, GD, This);
+  llvm::Value *VPtr =
+      adjustThisArgumentForVirtualFunctionCall(CGF, GD, This, true);
   llvm::Value *VTable = CGF.GetVTablePtr(VPtr, Ty);
 
   MicrosoftVTableContext::MethodVFTableLocation ML =
@@ -953,30 +1392,47 @@
       llvm::ConstantInt::get(llvm::IntegerType::getInt32Ty(CGF.getLLVMContext()),
                              DtorType == Dtor_Deleting);
 
-  This = adjustThisArgumentForVirtualCall(CGF, GD, This);
+  This = adjustThisArgumentForVirtualFunctionCall(CGF, GD, This, true);
   CGF.EmitCXXMemberCall(Dtor, CallLoc, Callee, ReturnValueSlot(), This,
-                        ImplicitParam, Context.IntTy, 0, 0);
+                        ImplicitParam, Context.IntTy, nullptr, nullptr);
 }
 
-const VBTableVector &
-MicrosoftCXXABI::EnumerateVBTables(const CXXRecordDecl *RD) {
+const VBTableGlobals &
+MicrosoftCXXABI::enumerateVBTables(const CXXRecordDecl *RD) {
   // At this layer, we can key the cache off of a single class, which is much
-  // easier than caching at the GlobalVariable layer.
-  llvm::DenseMap<const CXXRecordDecl*, VBTableVector>::iterator I;
-  bool added;
-  llvm::tie(I, added) = VBTablesMap.insert(std::make_pair(RD, VBTableVector()));
-  VBTableVector &VBTables = I->second;
-  if (!added)
-    return VBTables;
+  // easier than caching each vbtable individually.
+  llvm::DenseMap<const CXXRecordDecl*, VBTableGlobals>::iterator Entry;
+  bool Added;
+  std::tie(Entry, Added) =
+      VBTablesMap.insert(std::make_pair(RD, VBTableGlobals()));
+  VBTableGlobals &VBGlobals = Entry->second;
+  if (!Added)
+    return VBGlobals;
 
-  VBTableBuilder(CGM, RD).enumerateVBTables(VBTables);
+  MicrosoftVTableContext &Context = CGM.getMicrosoftVTableContext();
+  VBGlobals.VBTables = &Context.enumerateVBTables(RD);
 
-  return VBTables;
+  // Cache the globals for all vbtables so we don't have to recompute the
+  // mangled names.
+  llvm::GlobalVariable::LinkageTypes Linkage = CGM.getVTableLinkage(RD);
+  for (VPtrInfoVector::const_iterator I = VBGlobals.VBTables->begin(),
+                                      E = VBGlobals.VBTables->end();
+       I != E; ++I) {
+    VBGlobals.Globals.push_back(getAddrOfVBTable(**I, RD, Linkage));
+  }
+
+  return VBGlobals;
 }
 
-llvm::Function *
-MicrosoftCXXABI::EmitVirtualMemPtrThunk(const CXXMethodDecl *MD,
-                                        StringRef ThunkName) {
+llvm::Function *MicrosoftCXXABI::EmitVirtualMemPtrThunk(
+    const CXXMethodDecl *MD,
+    const MicrosoftVTableContext::MethodVFTableLocation &ML) {
+  // Calculate the mangled name.
+  SmallString<256> ThunkName;
+  llvm::raw_svector_ostream Out(ThunkName);
+  getMangleContext().mangleVirtualMemPtrThunk(MD, Out);
+  Out.flush();
+
   // If the thunk has been generated previously, just return it.
   if (llvm::GlobalValue *GV = CGM.getModule().getNamedValue(ThunkName))
     return cast<llvm::Function>(GV);
@@ -1000,26 +1456,129 @@
   CodeGenFunction CGF(CGM);
   CGF.StartThunk(ThunkFn, MD, FnInfo);
 
-  // Get to the Callee.
+  // Load the vfptr and then callee from the vftable.  The callee should have
+  // adjusted 'this' so that the vfptr is at offset zero.
   llvm::Value *This = CGF.LoadCXXThis();
-  llvm::Value *Callee = getVirtualFunctionPointer(CGF, MD, This, ThunkTy);
+  llvm::Value *VTable =
+      CGF.GetVTablePtr(This, ThunkTy->getPointerTo()->getPointerTo());
+  llvm::Value *VFuncPtr =
+      CGF.Builder.CreateConstInBoundsGEP1_64(VTable, ML.Index, "vfn");
+  llvm::Value *Callee = CGF.Builder.CreateLoad(VFuncPtr);
 
-  // Make the call and return the result.
-  CGF.EmitCallAndReturnForThunk(MD, Callee, 0);
+  unsigned CallingConv;
+  CodeGen::AttributeListType AttributeList;
+  CGM.ConstructAttributeList(FnInfo, MD, AttributeList, CallingConv, true);
+  llvm::AttributeSet Attrs =
+      llvm::AttributeSet::get(CGF.getLLVMContext(), AttributeList);
+
+  // Do a musttail call with perfect argument forwarding.  Any inalloca argument
+  // will be forwarded in place without any copy.
+  SmallVector<llvm::Value *, 8> Args;
+  for (llvm::Argument &A : ThunkFn->args())
+    Args.push_back(&A);
+  llvm::CallInst *Call = CGF.Builder.CreateCall(Callee, Args);
+  Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
+  Call->setAttributes(Attrs);
+  Call->setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));
+
+  if (Call->getType()->isVoidTy())
+    CGF.Builder.CreateRetVoid();
+  else
+    CGF.Builder.CreateRet(Call);
+
+  // Finish the function to maintain CodeGenFunction invariants.
+  // FIXME: Don't emit unreachable code.
+  CGF.EmitBlock(CGF.createBasicBlock());
+  CGF.FinishFunction();
 
   return ThunkFn;
 }
 
 void MicrosoftCXXABI::emitVirtualInheritanceTables(const CXXRecordDecl *RD) {
-  const VBTableVector &VBTables = EnumerateVBTables(RD);
-  llvm::GlobalVariable::LinkageTypes Linkage = CGM.getVTableLinkage(RD);
-
-  for (VBTableVector::const_iterator I = VBTables.begin(), E = VBTables.end();
-       I != E; ++I) {
-    I->EmitVBTableDefinition(CGM, RD, Linkage);
+  const VBTableGlobals &VBGlobals = enumerateVBTables(RD);
+  for (unsigned I = 0, E = VBGlobals.VBTables->size(); I != E; ++I) {
+    const VPtrInfo *VBT = (*VBGlobals.VBTables)[I];
+    llvm::GlobalVariable *GV = VBGlobals.Globals[I];
+    emitVBTableDefinition(*VBT, RD, GV);
   }
 }
 
+llvm::GlobalVariable *
+MicrosoftCXXABI::getAddrOfVBTable(const VPtrInfo &VBT, const CXXRecordDecl *RD,
+                                  llvm::GlobalVariable::LinkageTypes Linkage) {
+  SmallString<256> OutName;
+  llvm::raw_svector_ostream Out(OutName);
+  getMangleContext().mangleCXXVBTable(RD, VBT.MangledPath, Out);
+  Out.flush();
+  StringRef Name = OutName.str();
+
+  llvm::ArrayType *VBTableType =
+      llvm::ArrayType::get(CGM.IntTy, 1 + VBT.ReusingBase->getNumVBases());
+
+  assert(!CGM.getModule().getNamedGlobal(Name) &&
+         "vbtable with this name already exists: mangling bug?");
+  llvm::GlobalVariable *GV =
+      CGM.CreateOrReplaceCXXRuntimeVariable(Name, VBTableType, Linkage);
+  GV->setUnnamedAddr(true);
+
+  if (RD->hasAttr<DLLImportAttr>())
+    GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
+  else if (RD->hasAttr<DLLExportAttr>())
+    GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
+
+  return GV;
+}
+
+void MicrosoftCXXABI::emitVBTableDefinition(const VPtrInfo &VBT,
+                                            const CXXRecordDecl *RD,
+                                            llvm::GlobalVariable *GV) const {
+  const CXXRecordDecl *ReusingBase = VBT.ReusingBase;
+
+  assert(RD->getNumVBases() && ReusingBase->getNumVBases() &&
+         "should only emit vbtables for classes with vbtables");
+
+  const ASTRecordLayout &BaseLayout =
+      CGM.getContext().getASTRecordLayout(VBT.BaseWithVPtr);
+  const ASTRecordLayout &DerivedLayout =
+    CGM.getContext().getASTRecordLayout(RD);
+
+  SmallVector<llvm::Constant *, 4> Offsets(1 + ReusingBase->getNumVBases(),
+                                           nullptr);
+
+  // The offset from ReusingBase's vbptr to itself always leads.
+  CharUnits VBPtrOffset = BaseLayout.getVBPtrOffset();
+  Offsets[0] = llvm::ConstantInt::get(CGM.IntTy, -VBPtrOffset.getQuantity());
+
+  MicrosoftVTableContext &Context = CGM.getMicrosoftVTableContext();
+  for (const auto &I : ReusingBase->vbases()) {
+    const CXXRecordDecl *VBase = I.getType()->getAsCXXRecordDecl();
+    CharUnits Offset = DerivedLayout.getVBaseClassOffset(VBase);
+    assert(!Offset.isNegative());
+
+    // Make it relative to the subobject vbptr.
+    CharUnits CompleteVBPtrOffset = VBT.NonVirtualOffset + VBPtrOffset;
+    if (VBT.getVBaseWithVPtr())
+      CompleteVBPtrOffset +=
+          DerivedLayout.getVBaseClassOffset(VBT.getVBaseWithVPtr());
+    Offset -= CompleteVBPtrOffset;
+
+    unsigned VBIndex = Context.getVBTableIndex(ReusingBase, VBase);
+    assert(Offsets[VBIndex] == nullptr && "The same vbindex seen twice?");
+    Offsets[VBIndex] = llvm::ConstantInt::get(CGM.IntTy, Offset.getQuantity());
+  }
+
+  assert(Offsets.size() ==
+         cast<llvm::ArrayType>(cast<llvm::PointerType>(GV->getType())
+                               ->getElementType())->getNumElements());
+  llvm::ArrayType *VBTableType =
+    llvm::ArrayType::get(CGM.IntTy, Offsets.size());
+  llvm::Constant *Init = llvm::ConstantArray::get(VBTableType, Offsets);
+  GV->setInitializer(Init);
+
+  // Set the right visibility.
+  CGM.setGlobalVisibility(GV, RD);
+}
+
 llvm::Value *MicrosoftCXXABI::performThisAdjustment(CodeGenFunction &CGF,
                                                     llvm::Value *This,
                                                     const ThisAdjustment &TA) {
@@ -1147,6 +1706,15 @@
 void MicrosoftCXXABI::EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D,
                                       llvm::GlobalVariable *GV,
                                       bool PerformInit) {
+  // MSVC only uses guards for static locals.
+  if (!D.isStaticLocal()) {
+    assert(GV->hasWeakLinkage() || GV->hasLinkOnceLinkage());
+    // GlobalOpt is allowed to discard the initializer, so use linkonce_odr.
+    CGF.CurFn->setLinkage(llvm::GlobalValue::LinkOnceODRLinkage);
+    CGF.EmitCXXGlobalVarDeclInit(D, GV, PerformInit);
+    return;
+  }
+
   // MSVC always uses an i32 bitfield to guard initialization, which is *not*
   // threadsafe.  Since the user may be linking in inline functions compiled by
   // cl.exe, there's no reason to provide a false sense of security by using
@@ -1160,29 +1728,29 @@
   llvm::ConstantInt *Zero = llvm::ConstantInt::get(GuardTy, 0);
 
   // Get the guard variable for this function if we have one already.
-  GuardInfo &GI = GuardVariableMap[D.getDeclContext()];
+  GuardInfo *GI = &GuardVariableMap[D.getDeclContext()];
 
   unsigned BitIndex;
-  if (D.isExternallyVisible()) {
+  if (D.isStaticLocal() && D.isExternallyVisible()) {
     // Externally visible variables have to be numbered in Sema to properly
     // handle unreachable VarDecls.
-    BitIndex = getContext().getManglingNumber(&D);
+    BitIndex = getContext().getStaticLocalNumber(&D);
     assert(BitIndex > 0);
     BitIndex--;
   } else {
     // Non-externally visible variables are numbered here in CodeGen.
-    BitIndex = GI.BitIndex++;
+    BitIndex = GI->BitIndex++;
   }
 
   if (BitIndex >= 32) {
     if (D.isExternallyVisible())
       ErrorUnsupportedABI(CGF, "more than 32 guarded initializations");
     BitIndex %= 32;
-    GI.Guard = 0;
+    GI->Guard = nullptr;
   }
 
   // Lazily create the i32 bitfield for this function.
-  if (!GI.Guard) {
+  if (!GI->Guard) {
     // Mangle the name for the guard.
     SmallString<256> GuardName;
     {
@@ -1191,13 +1759,15 @@
       Out.flush();
     }
 
-    // Create the guard variable with a zero-initializer.  Just absorb linkage
-    // and visibility from the guarded variable.
-    GI.Guard = new llvm::GlobalVariable(CGM.getModule(), GuardTy, false,
-                                     GV->getLinkage(), Zero, GuardName.str());
-    GI.Guard->setVisibility(GV->getVisibility());
+    // Create the guard variable with a zero-initializer. Just absorb linkage,
+    // visibility and dll storage class from the guarded variable.
+    GI->Guard =
+        new llvm::GlobalVariable(CGM.getModule(), GuardTy, false,
+                                 GV->getLinkage(), Zero, GuardName.str());
+    GI->Guard->setVisibility(GV->getVisibility());
+    GI->Guard->setDLLStorageClass(GV->getDLLStorageClass());
   } else {
-    assert(GI.Guard->getLinkage() == GV->getLinkage() &&
+    assert(GI->Guard->getLinkage() == GV->getLinkage() &&
            "static local from the same function had different linkage");
   }
 
@@ -1209,7 +1779,7 @@
 
   // Test our bit from the guard variable.
   llvm::ConstantInt *Bit = llvm::ConstantInt::get(GuardTy, 1U << BitIndex);
-  llvm::LoadInst *LI = Builder.CreateLoad(GI.Guard);
+  llvm::LoadInst *LI = Builder.CreateLoad(GI->Guard);
   llvm::Value *IsInitialized =
       Builder.CreateICmpNE(Builder.CreateAnd(LI, Bit), Zero);
   llvm::BasicBlock *InitBlock = CGF.createBasicBlock("init");
@@ -1219,7 +1789,7 @@
   // Set our bit in the guard variable and emit the initializer and add a global
   // destructor if appropriate.
   CGF.EmitBlock(InitBlock);
-  Builder.CreateStore(Builder.CreateOr(LI, Bit), GI.Guard);
+  Builder.CreateStore(Builder.CreateOr(LI, Bit), GI->Guard);
   CGF.EmitCXXGlobalVarDeclInit(D, GV, PerformInit);
   Builder.CreateBr(EndBlock);
 
@@ -1227,38 +1797,6 @@
   CGF.EmitBlock(EndBlock);
 }
 
-// Member pointer helpers.
-static bool hasVBPtrOffsetField(MSInheritanceModel Inheritance) {
-  return Inheritance == MSIM_Unspecified;
-}
-
-static bool hasOnlyOneField(bool IsMemberFunction,
-                            MSInheritanceModel Inheritance) {
-  return Inheritance <= MSIM_SinglePolymorphic ||
-      (!IsMemberFunction && Inheritance <= MSIM_MultiplePolymorphic);
-}
-
-// Only member pointers to functions need a this adjustment, since it can be
-// combined with the field offset for data pointers.
-static bool hasNonVirtualBaseAdjustmentField(bool IsMemberFunction,
-                                             MSInheritanceModel Inheritance) {
-  return (IsMemberFunction && Inheritance >= MSIM_Multiple);
-}
-
-static bool hasVirtualBaseAdjustmentField(MSInheritanceModel Inheritance) {
-  return Inheritance >= MSIM_Virtual;
-}
-
-// Use zero for the field offset of a null data member pointer if we can
-// guarantee that zero is not a valid field offset, or if the member pointer has
-// multiple fields.  Polymorphic classes have a vfptr at offset zero, so we can
-// use zero for null.  If there are multiple fields, we can use zero even if it
-// is a valid field offset because null-ness testing will check the other
-// fields.
-static bool nullFieldOffsetIsZero(MSInheritanceModel Inheritance) {
-  return Inheritance != MSIM_Multiple && Inheritance != MSIM_Single;
-}
-
 bool MicrosoftCXXABI::isZeroInitializable(const MemberPointerType *MPT) {
   // Null-ness for function memptrs only depends on the first field, which is
   // the function pointer.  The rest don't matter, so we can zero initialize.
@@ -1268,28 +1806,28 @@
   // The virtual base adjustment field is always -1 for null, so if we have one
   // we can't zero initialize.  The field offset is sometimes also -1 if 0 is a
   // valid field offset.
-  const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
-  MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
-  return (!hasVirtualBaseAdjustmentField(Inheritance) &&
-          nullFieldOffsetIsZero(Inheritance));
+  const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
+  MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
+  return (!MSInheritanceAttr::hasVBTableOffsetField(Inheritance) &&
+          RD->nullFieldOffsetIsZero());
 }
 
 llvm::Type *
 MicrosoftCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) {
-  const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
-  MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
+  const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
+  MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
   llvm::SmallVector<llvm::Type *, 4> fields;
   if (MPT->isMemberFunctionPointer())
     fields.push_back(CGM.VoidPtrTy);  // FunctionPointerOrVirtualThunk
   else
     fields.push_back(CGM.IntTy);  // FieldOffset
 
-  if (hasNonVirtualBaseAdjustmentField(MPT->isMemberFunctionPointer(),
-                                       Inheritance))
+  if (MSInheritanceAttr::hasNVOffsetField(MPT->isMemberFunctionPointer(),
+                                          Inheritance))
     fields.push_back(CGM.IntTy);
-  if (hasVBPtrOffsetField(Inheritance))
+  if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
     fields.push_back(CGM.IntTy);
-  if (hasVirtualBaseAdjustmentField(Inheritance))
+  if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
     fields.push_back(CGM.IntTy);  // VirtualBaseAdjustmentOffset
 
   if (fields.size() == 1)
@@ -1301,24 +1839,24 @@
 GetNullMemberPointerFields(const MemberPointerType *MPT,
                            llvm::SmallVectorImpl<llvm::Constant *> &fields) {
   assert(fields.empty());
-  const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
-  MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
+  const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
+  MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
   if (MPT->isMemberFunctionPointer()) {
     // FunctionPointerOrVirtualThunk
     fields.push_back(llvm::Constant::getNullValue(CGM.VoidPtrTy));
   } else {
-    if (nullFieldOffsetIsZero(Inheritance))
+    if (RD->nullFieldOffsetIsZero())
       fields.push_back(getZeroInt());  // FieldOffset
     else
       fields.push_back(getAllOnesInt());  // FieldOffset
   }
 
-  if (hasNonVirtualBaseAdjustmentField(MPT->isMemberFunctionPointer(),
-                                       Inheritance))
+  if (MSInheritanceAttr::hasNVOffsetField(MPT->isMemberFunctionPointer(),
+                                          Inheritance))
     fields.push_back(getZeroInt());
-  if (hasVBPtrOffsetField(Inheritance))
+  if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
     fields.push_back(getZeroInt());
-  if (hasVirtualBaseAdjustmentField(Inheritance))
+  if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
     fields.push_back(getAllOnesInt());
 }
 
@@ -1339,29 +1877,29 @@
                                        const CXXRecordDecl *RD,
                                        CharUnits NonVirtualBaseAdjustment)
 {
-  MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
+  MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
 
   // Single inheritance class member pointer are represented as scalars instead
   // of aggregates.
-  if (hasOnlyOneField(IsMemberFunction, Inheritance))
+  if (MSInheritanceAttr::hasOnlyOneField(IsMemberFunction, Inheritance))
     return FirstField;
 
   llvm::SmallVector<llvm::Constant *, 4> fields;
   fields.push_back(FirstField);
 
-  if (hasNonVirtualBaseAdjustmentField(IsMemberFunction, Inheritance))
+  if (MSInheritanceAttr::hasNVOffsetField(IsMemberFunction, Inheritance))
     fields.push_back(llvm::ConstantInt::get(
       CGM.IntTy, NonVirtualBaseAdjustment.getQuantity()));
 
-  if (hasVBPtrOffsetField(Inheritance)) {
+  if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance)) {
     CharUnits Offs = CharUnits::Zero();
     if (RD->getNumVBases())
-      Offs = GetVBPtrOffsetFromBases(RD);
+      Offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
     fields.push_back(llvm::ConstantInt::get(CGM.IntTy, Offs.getQuantity()));
   }
 
   // The rest of the fields are adjusted by conversions to a more derived class.
-  if (hasVirtualBaseAdjustmentField(Inheritance))
+  if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
     fields.push_back(getZeroInt());
 
   return llvm::ConstantStruct::getAnon(fields);
@@ -1370,7 +1908,7 @@
 llvm::Constant *
 MicrosoftCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT,
                                        CharUnits offset) {
-  const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
+  const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
   llvm::Constant *FirstField =
     llvm::ConstantInt::get(CGM.IntTy, offset.getQuantity());
   return EmitFullMemberPointer(FirstField, /*IsMemberFunction=*/false, RD,
@@ -1393,8 +1931,8 @@
   // FIXME PR15713: Support virtual inheritance paths.
 
   if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD))
-    return BuildMemberPointer(MPT->getClass()->getAsCXXRecordDecl(),
-                              MD, ThisAdjustment);
+    return BuildMemberPointer(MPT->getMostRecentCXXRecordDecl(), MD,
+                              ThisAdjustment);
 
   CharUnits FieldOffset =
     getContext().toCharUnitsFromBits(getContext().getFieldOffset(MPD));
@@ -1407,6 +1945,7 @@
                                     CharUnits NonVirtualBaseAdjustment) {
   assert(MD->isInstance() && "Member function must not be static!");
   MD = MD->getCanonicalDecl();
+  RD = RD->getMostRecentDecl();
   CodeGenTypes &Types = CGM.getTypes();
 
   llvm::Constant *FirstField;
@@ -1440,16 +1979,10 @@
                                "member function in virtual base class");
       FirstField = llvm::Constant::getNullValue(CGM.VoidPtrTy);
     } else {
-      SmallString<256> ThunkName;
-      int OffsetInVFTable =
-          ML.Index *
-          getContext().getTypeSizeInChars(getContext().VoidPtrTy).getQuantity();
-      llvm::raw_svector_ostream Out(ThunkName);
-      getMangleContext().mangleVirtualMemPtrThunk(MD, OffsetInVFTable, Out);
-      Out.flush();
-
-      llvm::Function *Thunk = EmitVirtualMemPtrThunk(MD, ThunkName.str());
+      llvm::Function *Thunk = EmitVirtualMemPtrThunk(MD, ML);
       FirstField = llvm::ConstantExpr::getBitCast(Thunk, CGM.VoidPtrTy);
+      // Include the vfptr adjustment if the method is in a non-primary vftable.
+      NonVirtualBaseAdjustment += ML.VFPtrOffset;
     }
   }
 
@@ -1484,9 +2017,10 @@
 
   // If this is a single field member pointer (single inheritance), this is a
   // single icmp.
-  const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
-  MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
-  if (hasOnlyOneField(MPT->isMemberFunctionPointer(), Inheritance))
+  const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
+  MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
+  if (MSInheritanceAttr::hasOnlyOneField(MPT->isMemberFunctionPointer(),
+                                         Inheritance))
     return Builder.CreateICmp(Eq, L, R);
 
   // Compare the first field.
@@ -1495,7 +2029,7 @@
   llvm::Value *Cmp0 = Builder.CreateICmp(Eq, L0, R0, "memptr.cmp.first");
 
   // Compare everything other than the first field.
-  llvm::Value *Res = 0;
+  llvm::Value *Res = nullptr;
   llvm::StructType *LType = cast<llvm::StructType>(L->getType());
   for (unsigned I = 1, E = LType->getNumElements(); I != E; ++I) {
     llvm::Value *LF = Builder.CreateExtractValue(L, I);
@@ -1546,7 +2080,7 @@
   for (int I = 1, E = fields.size(); I < E; ++I) {
     llvm::Value *Field = Builder.CreateExtractValue(MemPtr, I);
     llvm::Value *Next = Builder.CreateICmpNE(Field, fields[I], "memptr.cmp");
-    Res = Builder.CreateAnd(Res, Next, "memptr.tobool");
+    Res = Builder.CreateOr(Res, Next, "memptr.tobool");
   }
   return Res;
 }
@@ -1605,16 +2139,14 @@
 
 // Returns an adjusted base cast to i8*, since we do more address arithmetic on
 // it.
-llvm::Value *
-MicrosoftCXXABI::AdjustVirtualBase(CodeGenFunction &CGF,
-                                   const CXXRecordDecl *RD, llvm::Value *Base,
-                                   llvm::Value *VBTableOffset,
-                                   llvm::Value *VBPtrOffset) {
+llvm::Value *MicrosoftCXXABI::AdjustVirtualBase(
+    CodeGenFunction &CGF, const Expr *E, const CXXRecordDecl *RD,
+    llvm::Value *Base, llvm::Value *VBTableOffset, llvm::Value *VBPtrOffset) {
   CGBuilderTy &Builder = CGF.Builder;
   Base = Builder.CreateBitCast(Base, CGM.Int8PtrTy);
-  llvm::BasicBlock *OriginalBB = 0;
-  llvm::BasicBlock *SkipAdjustBB = 0;
-  llvm::BasicBlock *VBaseAdjustBB = 0;
+  llvm::BasicBlock *OriginalBB = nullptr;
+  llvm::BasicBlock *SkipAdjustBB = nullptr;
+  llvm::BasicBlock *VBaseAdjustBB = nullptr;
 
   // In the unspecified inheritance model, there might not be a vbtable at all,
   // in which case we need to skip the virtual base lookup.  If there is a
@@ -1635,12 +2167,18 @@
   // know the vbptr offset.
   if (!VBPtrOffset) {
     CharUnits offs = CharUnits::Zero();
-    if (RD->getNumVBases()) {
-      offs = GetVBPtrOffsetFromBases(RD);
-    }
+    if (!RD->hasDefinition()) {
+      DiagnosticsEngine &Diags = CGF.CGM.getDiags();
+      unsigned DiagID = Diags.getCustomDiagID(
+          DiagnosticsEngine::Error,
+          "member pointer representation requires a "
+          "complete class type for %0 to perform this expression");
+      Diags.Report(E->getExprLoc(), DiagID) << RD << E->getSourceRange();
+    } else if (RD->getNumVBases())
+      offs = getContext().getASTRecordLayout(RD).getVBPtrOffset();
     VBPtrOffset = llvm::ConstantInt::get(CGM.IntTy, offs.getQuantity());
   }
-  llvm::Value *VBPtr = 0;
+  llvm::Value *VBPtr = nullptr;
   llvm::Value *VBaseOffs =
     GetVBaseOffsetFromVBPtr(CGF, Base, VBPtrOffset, VBTableOffset, &VBPtr);
   llvm::Value *AdjustedBase = Builder.CreateInBoundsGEP(VBPtr, VBaseOffs);
@@ -1657,38 +2195,41 @@
   return AdjustedBase;
 }
 
-llvm::Value *
-MicrosoftCXXABI::EmitMemberDataPointerAddress(CodeGenFunction &CGF,
-                                              llvm::Value *Base,
-                                              llvm::Value *MemPtr,
-                                              const MemberPointerType *MPT) {
+llvm::Value *MicrosoftCXXABI::EmitMemberDataPointerAddress(
+    CodeGenFunction &CGF, const Expr *E, llvm::Value *Base, llvm::Value *MemPtr,
+    const MemberPointerType *MPT) {
   assert(MPT->isMemberDataPointer());
   unsigned AS = Base->getType()->getPointerAddressSpace();
   llvm::Type *PType =
       CGF.ConvertTypeForMem(MPT->getPointeeType())->getPointerTo(AS);
   CGBuilderTy &Builder = CGF.Builder;
-  const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
-  MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
+  const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
+  MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
 
   // Extract the fields we need, regardless of model.  We'll apply them if we
   // have them.
   llvm::Value *FieldOffset = MemPtr;
-  llvm::Value *VirtualBaseAdjustmentOffset = 0;
-  llvm::Value *VBPtrOffset = 0;
+  llvm::Value *VirtualBaseAdjustmentOffset = nullptr;
+  llvm::Value *VBPtrOffset = nullptr;
   if (MemPtr->getType()->isStructTy()) {
     // We need to extract values.
     unsigned I = 0;
     FieldOffset = Builder.CreateExtractValue(MemPtr, I++);
-    if (hasVBPtrOffsetField(Inheritance))
+    if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
       VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
-    if (hasVirtualBaseAdjustmentField(Inheritance))
+    if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
       VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
   }
 
   if (VirtualBaseAdjustmentOffset) {
-    Base = AdjustVirtualBase(CGF, RD, Base, VirtualBaseAdjustmentOffset,
+    Base = AdjustVirtualBase(CGF, E, RD, Base, VirtualBaseAdjustmentOffset,
                              VBPtrOffset);
   }
+
+  // Cast to char*.
+  Base = Builder.CreateBitCast(Base, Builder.getInt8Ty()->getPointerTo(AS));
+
+  // Apply the offset, which we assume is non-null.
   llvm::Value *Addr =
     Builder.CreateInBoundsGEP(Base, FieldOffset, "memptr.offset");
 
@@ -1697,9 +2238,9 @@
   return Builder.CreateBitCast(Addr, PType);
 }
 
-static MSInheritanceModel
+static MSInheritanceAttr::Spelling
 getInheritanceFromMemptr(const MemberPointerType *MPT) {
-  return MPT->getClass()->getAsCXXRecordDecl()->getMSInheritanceModel();
+  return MPT->getMostRecentCXXRecordDecl()->getMSInheritanceModel();
 }
 
 llvm::Value *
@@ -1719,15 +2260,17 @@
   const MemberPointerType *SrcTy =
     E->getSubExpr()->getType()->castAs<MemberPointerType>();
   const MemberPointerType *DstTy = E->getType()->castAs<MemberPointerType>();
-  MSInheritanceModel SrcInheritance = getInheritanceFromMemptr(SrcTy);
-  MSInheritanceModel DstInheritance = getInheritanceFromMemptr(DstTy);
   bool IsFunc = SrcTy->isMemberFunctionPointer();
 
   // If the classes use the same null representation, reinterpret_cast is a nop.
   bool IsReinterpret = E->getCastKind() == CK_ReinterpretMemberPointer;
-  if (IsReinterpret && (IsFunc ||
-                        nullFieldOffsetIsZero(SrcInheritance) ==
-                        nullFieldOffsetIsZero(DstInheritance)))
+  if (IsReinterpret && IsFunc)
+    return Src;
+
+  CXXRecordDecl *SrcRD = SrcTy->getMostRecentCXXRecordDecl();
+  CXXRecordDecl *DstRD = DstTy->getMostRecentCXXRecordDecl();
+  if (IsReinterpret &&
+      SrcRD->nullFieldOffsetIsZero() == DstRD->nullFieldOffsetIsZero())
     return Src;
 
   CGBuilderTy &Builder = CGF.Builder;
@@ -1753,18 +2296,19 @@
 
   // Decompose src.
   llvm::Value *FirstField = Src;
-  llvm::Value *NonVirtualBaseAdjustment = 0;
-  llvm::Value *VirtualBaseAdjustmentOffset = 0;
-  llvm::Value *VBPtrOffset = 0;
-  if (!hasOnlyOneField(IsFunc, SrcInheritance)) {
+  llvm::Value *NonVirtualBaseAdjustment = nullptr;
+  llvm::Value *VirtualBaseAdjustmentOffset = nullptr;
+  llvm::Value *VBPtrOffset = nullptr;
+  MSInheritanceAttr::Spelling SrcInheritance = SrcRD->getMSInheritanceModel();
+  if (!MSInheritanceAttr::hasOnlyOneField(IsFunc, SrcInheritance)) {
     // We need to extract values.
     unsigned I = 0;
     FirstField = Builder.CreateExtractValue(Src, I++);
-    if (hasNonVirtualBaseAdjustmentField(IsFunc, SrcInheritance))
+    if (MSInheritanceAttr::hasNVOffsetField(IsFunc, SrcInheritance))
       NonVirtualBaseAdjustment = Builder.CreateExtractValue(Src, I++);
-    if (hasVBPtrOffsetField(SrcInheritance))
+    if (MSInheritanceAttr::hasVBPtrOffsetField(SrcInheritance))
       VBPtrOffset = Builder.CreateExtractValue(Src, I++);
-    if (hasVirtualBaseAdjustmentField(SrcInheritance))
+    if (MSInheritanceAttr::hasVBTableOffsetField(SrcInheritance))
       VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(Src, I++);
   }
 
@@ -1786,20 +2330,21 @@
   // FIXME PR15713: Support conversions through virtually derived classes.
 
   // Recompose dst from the null struct and the adjusted fields from src.
+  MSInheritanceAttr::Spelling DstInheritance = DstRD->getMSInheritanceModel();
   llvm::Value *Dst;
-  if (hasOnlyOneField(IsFunc, DstInheritance)) {
+  if (MSInheritanceAttr::hasOnlyOneField(IsFunc, DstInheritance)) {
     Dst = FirstField;
   } else {
     Dst = llvm::UndefValue::get(DstNull->getType());
     unsigned Idx = 0;
     Dst = Builder.CreateInsertValue(Dst, FirstField, Idx++);
-    if (hasNonVirtualBaseAdjustmentField(IsFunc, DstInheritance))
+    if (MSInheritanceAttr::hasNVOffsetField(IsFunc, DstInheritance))
       Dst = Builder.CreateInsertValue(
         Dst, getValueOrZeroInt(NonVirtualBaseAdjustment), Idx++);
-    if (hasVBPtrOffsetField(DstInheritance))
+    if (MSInheritanceAttr::hasVBPtrOffsetField(DstInheritance))
       Dst = Builder.CreateInsertValue(
         Dst, getValueOrZeroInt(VBPtrOffset), Idx++);
-    if (hasVirtualBaseAdjustmentField(DstInheritance))
+    if (MSInheritanceAttr::hasVBTableOffsetField(DstInheritance))
       Dst = Builder.CreateInsertValue(
         Dst, getValueOrZeroInt(VirtualBaseAdjustmentOffset), Idx++);
   }
@@ -1831,24 +2376,24 @@
   if (E->getCastKind() == CK_ReinterpretMemberPointer)
     return Src;
 
-  MSInheritanceModel SrcInheritance = getInheritanceFromMemptr(SrcTy);
-  MSInheritanceModel DstInheritance = getInheritanceFromMemptr(DstTy);
+  MSInheritanceAttr::Spelling SrcInheritance = getInheritanceFromMemptr(SrcTy);
+  MSInheritanceAttr::Spelling DstInheritance = getInheritanceFromMemptr(DstTy);
 
   // Decompose src.
   llvm::Constant *FirstField = Src;
-  llvm::Constant *NonVirtualBaseAdjustment = 0;
-  llvm::Constant *VirtualBaseAdjustmentOffset = 0;
-  llvm::Constant *VBPtrOffset = 0;
+  llvm::Constant *NonVirtualBaseAdjustment = nullptr;
+  llvm::Constant *VirtualBaseAdjustmentOffset = nullptr;
+  llvm::Constant *VBPtrOffset = nullptr;
   bool IsFunc = SrcTy->isMemberFunctionPointer();
-  if (!hasOnlyOneField(IsFunc, SrcInheritance)) {
+  if (!MSInheritanceAttr::hasOnlyOneField(IsFunc, SrcInheritance)) {
     // We need to extract values.
     unsigned I = 0;
     FirstField = Src->getAggregateElement(I++);
-    if (hasNonVirtualBaseAdjustmentField(IsFunc, SrcInheritance))
+    if (MSInheritanceAttr::hasNVOffsetField(IsFunc, SrcInheritance))
       NonVirtualBaseAdjustment = Src->getAggregateElement(I++);
-    if (hasVBPtrOffsetField(SrcInheritance))
+    if (MSInheritanceAttr::hasVBPtrOffsetField(SrcInheritance))
       VBPtrOffset = Src->getAggregateElement(I++);
-    if (hasVirtualBaseAdjustmentField(SrcInheritance))
+    if (MSInheritanceAttr::hasVBTableOffsetField(SrcInheritance))
       VirtualBaseAdjustmentOffset = Src->getAggregateElement(I++);
   }
 
@@ -1871,56 +2416,54 @@
   // FIXME PR15713: Support conversions through virtually derived classes.
 
   // Recompose dst from the null struct and the adjusted fields from src.
-  if (hasOnlyOneField(IsFunc, DstInheritance))
+  if (MSInheritanceAttr::hasOnlyOneField(IsFunc, DstInheritance))
     return FirstField;
 
   llvm::SmallVector<llvm::Constant *, 4> Fields;
   Fields.push_back(FirstField);
-  if (hasNonVirtualBaseAdjustmentField(IsFunc, DstInheritance))
+  if (MSInheritanceAttr::hasNVOffsetField(IsFunc, DstInheritance))
     Fields.push_back(getConstantOrZeroInt(NonVirtualBaseAdjustment));
-  if (hasVBPtrOffsetField(DstInheritance))
+  if (MSInheritanceAttr::hasVBPtrOffsetField(DstInheritance))
     Fields.push_back(getConstantOrZeroInt(VBPtrOffset));
-  if (hasVirtualBaseAdjustmentField(DstInheritance))
+  if (MSInheritanceAttr::hasVBTableOffsetField(DstInheritance))
     Fields.push_back(getConstantOrZeroInt(VirtualBaseAdjustmentOffset));
   return llvm::ConstantStruct::getAnon(Fields);
 }
 
-llvm::Value *
-MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
-                                                 llvm::Value *&This,
-                                                 llvm::Value *MemPtr,
-                                                 const MemberPointerType *MPT) {
+llvm::Value *MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer(
+    CodeGenFunction &CGF, const Expr *E, llvm::Value *&This,
+    llvm::Value *MemPtr, const MemberPointerType *MPT) {
   assert(MPT->isMemberFunctionPointer());
   const FunctionProtoType *FPT =
     MPT->getPointeeType()->castAs<FunctionProtoType>();
-  const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
+  const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
   llvm::FunctionType *FTy =
     CGM.getTypes().GetFunctionType(
       CGM.getTypes().arrangeCXXMethodType(RD, FPT));
   CGBuilderTy &Builder = CGF.Builder;
 
-  MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
+  MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
 
   // Extract the fields we need, regardless of model.  We'll apply them if we
   // have them.
   llvm::Value *FunctionPointer = MemPtr;
-  llvm::Value *NonVirtualBaseAdjustment = NULL;
-  llvm::Value *VirtualBaseAdjustmentOffset = NULL;
-  llvm::Value *VBPtrOffset = NULL;
+  llvm::Value *NonVirtualBaseAdjustment = nullptr;
+  llvm::Value *VirtualBaseAdjustmentOffset = nullptr;
+  llvm::Value *VBPtrOffset = nullptr;
   if (MemPtr->getType()->isStructTy()) {
     // We need to extract values.
     unsigned I = 0;
     FunctionPointer = Builder.CreateExtractValue(MemPtr, I++);
-    if (hasNonVirtualBaseAdjustmentField(MPT, Inheritance))
+    if (MSInheritanceAttr::hasNVOffsetField(MPT, Inheritance))
       NonVirtualBaseAdjustment = Builder.CreateExtractValue(MemPtr, I++);
-    if (hasVBPtrOffsetField(Inheritance))
+    if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance))
       VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++);
-    if (hasVirtualBaseAdjustmentField(Inheritance))
+    if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance))
       VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++);
   }
 
   if (VirtualBaseAdjustmentOffset) {
-    This = AdjustVirtualBase(CGF, RD, This, VirtualBaseAdjustmentOffset,
+    This = AdjustVirtualBase(CGF, E, RD, This, VirtualBaseAdjustmentOffset,
                              VBPtrOffset);
   }
 
@@ -1937,3 +2480,398 @@
 CGCXXABI *clang::CodeGen::CreateMicrosoftCXXABI(CodeGenModule &CGM) {
   return new MicrosoftCXXABI(CGM);
 }
+
+// MS RTTI Overview:
+// The run time type information emitted by cl.exe contains 5 distinct types of
+// structures.  Many of them reference each other.
+//
+// TypeInfo:  Static classes that are returned by typeid.
+//
+// CompleteObjectLocator:  Referenced by vftables.  They contain information
+//   required for dynamic casting, including OffsetFromTop.  They also contain
+//   a reference to the TypeInfo for the type and a reference to the
+//   CompleteHierarchyDescriptor for the type.
+//
+// ClassHieararchyDescriptor: Contains information about a class hierarchy.
+//   Used during dynamic_cast to walk a class hierarchy.  References a base
+//   class array and the size of said array.
+//
+// BaseClassArray: Contains a list of classes in a hierarchy.  BaseClassArray is
+//   somewhat of a misnomer because the most derived class is also in the list
+//   as well as multiple copies of virtual bases (if they occur multiple times
+//   in the hiearchy.)  The BaseClassArray contains one BaseClassDescriptor for
+//   every path in the hierarchy, in pre-order depth first order.  Note, we do
+//   not declare a specific llvm type for BaseClassArray, it's merely an array
+//   of BaseClassDescriptor pointers.
+//
+// BaseClassDescriptor: Contains information about a class in a class hierarchy.
+//   BaseClassDescriptor is also somewhat of a misnomer for the same reason that
+//   BaseClassArray is.  It contains information about a class within a
+//   hierarchy such as: is this base is ambiguous and what is its offset in the
+//   vbtable.  The names of the BaseClassDescriptors have all of their fields
+//   mangled into them so they can be aggressively deduplicated by the linker.
+
+static llvm::GlobalVariable *getTypeInfoVTable(CodeGenModule &CGM) {
+  StringRef MangledName("\01??_7type_info@@6B@");
+  if (auto VTable = CGM.getModule().getNamedGlobal(MangledName))
+    return VTable;
+  return new llvm::GlobalVariable(CGM.getModule(), CGM.Int8PtrTy,
+                                  /*Constant=*/true,
+                                  llvm::GlobalVariable::ExternalLinkage,
+                                  /*Initializer=*/nullptr, MangledName);
+}
+
+namespace {
+
+/// \brief A Helper struct that stores information about a class in a class
+/// hierarchy.  The information stored in these structs struct is used during
+/// the generation of ClassHierarchyDescriptors and BaseClassDescriptors.
+// During RTTI creation, MSRTTIClasses are stored in a contiguous array with
+// implicit depth first pre-order tree connectivity.  getFirstChild and
+// getNextSibling allow us to walk the tree efficiently.
+struct MSRTTIClass {
+  enum {
+    IsPrivateOnPath = 1 | 8,
+    IsAmbiguous = 2,
+    IsPrivate = 4,
+    IsVirtual = 16,
+    HasHierarchyDescriptor = 64
+  };
+  MSRTTIClass(const CXXRecordDecl *RD) : RD(RD) {}
+  uint32_t initialize(const MSRTTIClass *Parent,
+                      const CXXBaseSpecifier *Specifier);
+
+  MSRTTIClass *getFirstChild() { return this + 1; }
+  static MSRTTIClass *getNextChild(MSRTTIClass *Child) {
+    return Child + 1 + Child->NumBases;
+  }
+
+  const CXXRecordDecl *RD, *VirtualRoot;
+  uint32_t Flags, NumBases, OffsetInVBase;
+};
+
+/// \brief Recursively initialize the base class array.
+uint32_t MSRTTIClass::initialize(const MSRTTIClass *Parent,
+                                 const CXXBaseSpecifier *Specifier) {
+  Flags = HasHierarchyDescriptor;
+  if (!Parent) {
+    VirtualRoot = nullptr;
+    OffsetInVBase = 0;
+  } else {
+    if (Specifier->getAccessSpecifier() != AS_public)
+      Flags |= IsPrivate | IsPrivateOnPath;
+    if (Specifier->isVirtual()) {
+      Flags |= IsVirtual;
+      VirtualRoot = RD;
+      OffsetInVBase = 0;
+    } else {
+      if (Parent->Flags & IsPrivateOnPath)
+        Flags |= IsPrivateOnPath;
+      VirtualRoot = Parent->VirtualRoot;
+      OffsetInVBase = Parent->OffsetInVBase + RD->getASTContext()
+          .getASTRecordLayout(Parent->RD).getBaseClassOffset(RD).getQuantity();
+    }
+  }
+  NumBases = 0;
+  MSRTTIClass *Child = getFirstChild();
+  for (const CXXBaseSpecifier &Base : RD->bases()) {
+    NumBases += Child->initialize(this, &Base) + 1;
+    Child = getNextChild(Child);
+  }
+  return NumBases;
+}
+
+static llvm::GlobalValue::LinkageTypes getLinkageForRTTI(QualType Ty) {
+  switch (Ty->getLinkage()) {
+  case NoLinkage:
+  case InternalLinkage:
+  case UniqueExternalLinkage:
+    return llvm::GlobalValue::InternalLinkage;
+
+  case VisibleNoLinkage:
+  case ExternalLinkage:
+    return llvm::GlobalValue::LinkOnceODRLinkage;
+  }
+  llvm_unreachable("Invalid linkage!");
+}
+
+/// \brief An ephemeral helper class for building MS RTTI types.  It caches some
+/// calls to the module and information about the most derived class in a
+/// hierarchy.
+struct MSRTTIBuilder {
+  enum {
+    HasBranchingHierarchy = 1,
+    HasVirtualBranchingHierarchy = 2,
+    HasAmbiguousBases = 4
+  };
+
+  MSRTTIBuilder(MicrosoftCXXABI &ABI, const CXXRecordDecl *RD)
+      : CGM(ABI.CGM), Context(CGM.getContext()),
+        VMContext(CGM.getLLVMContext()), Module(CGM.getModule()), RD(RD),
+        Linkage(getLinkageForRTTI(CGM.getContext().getTagDeclType(RD))),
+        ABI(ABI) {}
+
+  llvm::GlobalVariable *getBaseClassDescriptor(const MSRTTIClass &Classes);
+  llvm::GlobalVariable *
+  getBaseClassArray(SmallVectorImpl<MSRTTIClass> &Classes);
+  llvm::GlobalVariable *getClassHierarchyDescriptor();
+  llvm::GlobalVariable *getCompleteObjectLocator(const VPtrInfo *Info);
+
+  CodeGenModule &CGM;
+  ASTContext &Context;
+  llvm::LLVMContext &VMContext;
+  llvm::Module &Module;
+  const CXXRecordDecl *RD;
+  llvm::GlobalVariable::LinkageTypes Linkage;
+  MicrosoftCXXABI &ABI;
+};
+
+} // namespace
+
+/// \brief Recursively serializes a class hierarchy in pre-order depth first
+/// order.
+static void serializeClassHierarchy(SmallVectorImpl<MSRTTIClass> &Classes,
+                                    const CXXRecordDecl *RD) {
+  Classes.push_back(MSRTTIClass(RD));
+  for (const CXXBaseSpecifier &Base : RD->bases())
+    serializeClassHierarchy(Classes, Base.getType()->getAsCXXRecordDecl());
+}
+
+/// \brief Find ambiguity among base classes.
+static void
+detectAmbiguousBases(SmallVectorImpl<MSRTTIClass> &Classes) {
+  llvm::SmallPtrSet<const CXXRecordDecl *, 8> VirtualBases;
+  llvm::SmallPtrSet<const CXXRecordDecl *, 8> UniqueBases;
+  llvm::SmallPtrSet<const CXXRecordDecl *, 8> AmbiguousBases;
+  for (MSRTTIClass *Class = &Classes.front(); Class <= &Classes.back();) {
+    if ((Class->Flags & MSRTTIClass::IsVirtual) &&
+        !VirtualBases.insert(Class->RD)) {
+      Class = MSRTTIClass::getNextChild(Class);
+      continue;
+    }
+    if (!UniqueBases.insert(Class->RD))
+      AmbiguousBases.insert(Class->RD);
+    Class++;
+  }
+  if (AmbiguousBases.empty())
+    return;
+  for (MSRTTIClass &Class : Classes)
+    if (AmbiguousBases.count(Class.RD))
+      Class.Flags |= MSRTTIClass::IsAmbiguous;
+}
+
+llvm::GlobalVariable *MSRTTIBuilder::getClassHierarchyDescriptor() {
+  SmallString<256> MangledName;
+  {
+    llvm::raw_svector_ostream Out(MangledName);
+    ABI.getMangleContext().mangleCXXRTTIClassHierarchyDescriptor(RD, Out);
+  }
+
+  // Check to see if we've already declared this ClassHierarchyDescriptor.
+  if (auto CHD = Module.getNamedGlobal(MangledName))
+    return CHD;
+
+  // Serialize the class hierarchy and initialize the CHD Fields.
+  SmallVector<MSRTTIClass, 8> Classes;
+  serializeClassHierarchy(Classes, RD);
+  Classes.front().initialize(/*Parent=*/nullptr, /*Specifier=*/nullptr);
+  detectAmbiguousBases(Classes);
+  int Flags = 0;
+  for (auto Class : Classes) {
+    if (Class.RD->getNumBases() > 1)
+      Flags |= HasBranchingHierarchy;
+    // Note: cl.exe does not calculate "HasAmbiguousBases" correctly.  We
+    // believe the field isn't actually used.
+    if (Class.Flags & MSRTTIClass::IsAmbiguous)
+      Flags |= HasAmbiguousBases;
+  }
+  if ((Flags & HasBranchingHierarchy) && RD->getNumVBases() != 0)
+    Flags |= HasVirtualBranchingHierarchy;
+  // These gep indices are used to get the address of the first element of the
+  // base class array.
+  llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.IntTy, 0),
+                               llvm::ConstantInt::get(CGM.IntTy, 0)};
+
+  // Forward-declare the class hierarchy descriptor
+  auto Type = ABI.getClassHierarchyDescriptorType();
+  auto CHD = new llvm::GlobalVariable(Module, Type, /*Constant=*/true, Linkage,
+                                      /*Initializer=*/nullptr,
+                                      MangledName.c_str());
+
+  // Initialize the base class ClassHierarchyDescriptor.
+  llvm::Constant *Fields[] = {
+      llvm::ConstantInt::get(CGM.IntTy, 0), // Unknown
+      llvm::ConstantInt::get(CGM.IntTy, Flags),
+      llvm::ConstantInt::get(CGM.IntTy, Classes.size()),
+      ABI.getImageRelativeConstant(llvm::ConstantExpr::getInBoundsGetElementPtr(
+          getBaseClassArray(Classes),
+          llvm::ArrayRef<llvm::Value *>(GEPIndices))),
+  };
+  CHD->setInitializer(llvm::ConstantStruct::get(Type, Fields));
+  return CHD;
+}
+
+llvm::GlobalVariable *
+MSRTTIBuilder::getBaseClassArray(SmallVectorImpl<MSRTTIClass> &Classes) {
+  SmallString<256> MangledName;
+  {
+    llvm::raw_svector_ostream Out(MangledName);
+    ABI.getMangleContext().mangleCXXRTTIBaseClassArray(RD, Out);
+  }
+
+  // Forward-declare the base class array.
+  // cl.exe pads the base class array with 1 (in 32 bit mode) or 4 (in 64 bit
+  // mode) bytes of padding.  We provide a pointer sized amount of padding by
+  // adding +1 to Classes.size().  The sections have pointer alignment and are
+  // marked pick-any so it shouldn't matter.
+  llvm::Type *PtrType = ABI.getImageRelativeType(
+      ABI.getBaseClassDescriptorType()->getPointerTo());
+  auto *ArrType = llvm::ArrayType::get(PtrType, Classes.size() + 1);
+  auto *BCA = new llvm::GlobalVariable(
+      Module, ArrType,
+      /*Constant=*/true, Linkage, /*Initializer=*/nullptr, MangledName.c_str());
+
+  // Initialize the BaseClassArray.
+  SmallVector<llvm::Constant *, 8> BaseClassArrayData;
+  for (MSRTTIClass &Class : Classes)
+    BaseClassArrayData.push_back(
+        ABI.getImageRelativeConstant(getBaseClassDescriptor(Class)));
+  BaseClassArrayData.push_back(llvm::Constant::getNullValue(PtrType));
+  BCA->setInitializer(llvm::ConstantArray::get(ArrType, BaseClassArrayData));
+  return BCA;
+}
+
+llvm::GlobalVariable *
+MSRTTIBuilder::getBaseClassDescriptor(const MSRTTIClass &Class) {
+  // Compute the fields for the BaseClassDescriptor.  They are computed up front
+  // because they are mangled into the name of the object.
+  uint32_t OffsetInVBTable = 0;
+  int32_t VBPtrOffset = -1;
+  if (Class.VirtualRoot) {
+    auto &VTableContext = CGM.getMicrosoftVTableContext();
+    OffsetInVBTable = VTableContext.getVBTableIndex(RD, Class.VirtualRoot) * 4;
+    VBPtrOffset = Context.getASTRecordLayout(RD).getVBPtrOffset().getQuantity();
+  }
+
+  SmallString<256> MangledName;
+  {
+    llvm::raw_svector_ostream Out(MangledName);
+    ABI.getMangleContext().mangleCXXRTTIBaseClassDescriptor(
+        Class.RD, Class.OffsetInVBase, VBPtrOffset, OffsetInVBTable,
+        Class.Flags, Out);
+  }
+
+  // Check to see if we've already declared this object.
+  if (auto BCD = Module.getNamedGlobal(MangledName))
+    return BCD;
+
+  // Forward-declare the base class descriptor.
+  auto Type = ABI.getBaseClassDescriptorType();
+  auto BCD = new llvm::GlobalVariable(Module, Type, /*Constant=*/true, Linkage,
+                                      /*Initializer=*/nullptr,
+                                      MangledName.c_str());
+
+  // Initialize the BaseClassDescriptor.
+  llvm::Constant *Fields[] = {
+      ABI.getImageRelativeConstant(
+          ABI.getAddrOfRTTIDescriptor(Context.getTypeDeclType(Class.RD))),
+      llvm::ConstantInt::get(CGM.IntTy, Class.NumBases),
+      llvm::ConstantInt::get(CGM.IntTy, Class.OffsetInVBase),
+      llvm::ConstantInt::get(CGM.IntTy, VBPtrOffset),
+      llvm::ConstantInt::get(CGM.IntTy, OffsetInVBTable),
+      llvm::ConstantInt::get(CGM.IntTy, Class.Flags),
+      ABI.getImageRelativeConstant(
+          MSRTTIBuilder(ABI, Class.RD).getClassHierarchyDescriptor()),
+  };
+  BCD->setInitializer(llvm::ConstantStruct::get(Type, Fields));
+  return BCD;
+}
+
+llvm::GlobalVariable *
+MSRTTIBuilder::getCompleteObjectLocator(const VPtrInfo *Info) {
+  SmallString<256> MangledName;
+  {
+    llvm::raw_svector_ostream Out(MangledName);
+    ABI.getMangleContext().mangleCXXRTTICompleteObjectLocator(RD, Info->MangledPath, Out);
+  }
+
+  // Check to see if we've already computed this complete object locator.
+  if (auto COL = Module.getNamedGlobal(MangledName))
+    return COL;
+
+  // Compute the fields of the complete object locator.
+  int OffsetToTop = Info->FullOffsetInMDC.getQuantity();
+  int VFPtrOffset = 0;
+  // The offset includes the vtordisp if one exists.
+  if (const CXXRecordDecl *VBase = Info->getVBaseWithVPtr())
+    if (Context.getASTRecordLayout(RD)
+      .getVBaseOffsetsMap()
+      .find(VBase)
+      ->second.hasVtorDisp())
+      VFPtrOffset = Info->NonVirtualOffset.getQuantity() + 4;
+
+  // Forward-declare the complete object locator.
+  llvm::StructType *Type = ABI.getCompleteObjectLocatorType();
+  auto COL = new llvm::GlobalVariable(Module, Type, /*Constant=*/true, Linkage,
+    /*Initializer=*/nullptr, MangledName.c_str());
+
+  // Initialize the CompleteObjectLocator.
+  llvm::Constant *Fields[] = {
+      llvm::ConstantInt::get(CGM.IntTy, ABI.isImageRelative()),
+      llvm::ConstantInt::get(CGM.IntTy, OffsetToTop),
+      llvm::ConstantInt::get(CGM.IntTy, VFPtrOffset),
+      ABI.getImageRelativeConstant(
+          CGM.GetAddrOfRTTIDescriptor(Context.getTypeDeclType(RD))),
+      ABI.getImageRelativeConstant(getClassHierarchyDescriptor()),
+      ABI.getImageRelativeConstant(COL),
+  };
+  llvm::ArrayRef<llvm::Constant *> FieldsRef(Fields);
+  if (!ABI.isImageRelative())
+    FieldsRef = FieldsRef.drop_back();
+  COL->setInitializer(llvm::ConstantStruct::get(Type, FieldsRef));
+  return COL;
+}
+
+/// \brief Gets a TypeDescriptor.  Returns a llvm::Constant * rather than a
+/// llvm::GlobalVariable * because different type descriptors have different
+/// types, and need to be abstracted.  They are abstracting by casting the
+/// address to an Int8PtrTy.
+llvm::Constant *MicrosoftCXXABI::getAddrOfRTTIDescriptor(QualType Type) {
+  SmallString<256> MangledName, TypeInfoString;
+  {
+    llvm::raw_svector_ostream Out(MangledName);
+    getMangleContext().mangleCXXRTTI(Type, Out);
+  }
+
+  // Check to see if we've already declared this TypeDescriptor.
+  if (llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(MangledName))
+    return llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy);
+
+  // Compute the fields for the TypeDescriptor.
+  {
+    llvm::raw_svector_ostream Out(TypeInfoString);
+    getMangleContext().mangleCXXRTTIName(Type, Out);
+  }
+
+  // Declare and initialize the TypeDescriptor.
+  llvm::Constant *Fields[] = {
+    getTypeInfoVTable(CGM),                        // VFPtr
+    llvm::ConstantPointerNull::get(CGM.Int8PtrTy), // Runtime data
+    llvm::ConstantDataArray::getString(CGM.getLLVMContext(), TypeInfoString)};
+  llvm::StructType *TypeDescriptorType =
+      getTypeDescriptorType(TypeInfoString);
+  return llvm::ConstantExpr::getBitCast(
+      new llvm::GlobalVariable(
+          CGM.getModule(), TypeDescriptorType, /*Constant=*/false,
+          getLinkageForRTTI(Type),
+          llvm::ConstantStruct::get(TypeDescriptorType, Fields),
+          MangledName.c_str()),
+      CGM.Int8PtrTy);
+}
+
+/// \brief Gets or a creates a Microsoft CompleteObjectLocator.
+llvm::GlobalVariable *
+MicrosoftCXXABI::getMSCompleteObjectLocator(const CXXRecordDecl *RD,
+                                            const VPtrInfo *Info) {
+  return MSRTTIBuilder(*this, RD).getCompleteObjectLocator(Info);
+}
diff --git a/lib/CodeGen/MicrosoftVBTables.cpp b/lib/CodeGen/MicrosoftVBTables.cpp
deleted file mode 100644
index dabf52c..0000000
--- a/lib/CodeGen/MicrosoftVBTables.cpp
+++ /dev/null
@@ -1,233 +0,0 @@
-//===--- MicrosoftVBTables.cpp - Virtual Base Table Emission --------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This class generates data about MSVC virtual base tables.
-//
-//===----------------------------------------------------------------------===//
-
-#include "MicrosoftVBTables.h"
-#include "CodeGenModule.h"
-#include "CGCXXABI.h"
-
-namespace clang {
-namespace CodeGen {
-
-/// Holds intermediate data about a path to a vbptr inside a base subobject.
-struct VBTablePath {
-  VBTablePath(const VBTableInfo &VBInfo)
-    : VBInfo(VBInfo), NextBase(VBInfo.VBPtrSubobject.getBase()) { }
-
-  /// All the data needed to build a vbtable, minus the GlobalVariable whose
-  /// name we haven't computed yet.
-  VBTableInfo VBInfo;
-
-  /// Next base to use for disambiguation.  Can be null if we've already
-  /// disambiguated this path once.
-  const CXXRecordDecl *NextBase;
-
-  /// Path is not really a full path like a CXXBasePath.  It holds the subset of
-  /// records that need to be mangled into the vbtable symbol name in order to get
-  /// a unique name.
-  llvm::SmallVector<const CXXRecordDecl *, 1> Path;
-};
-
-VBTableBuilder::VBTableBuilder(CodeGenModule &CGM,
-                               const CXXRecordDecl *MostDerived)
-    : CGM(CGM), MostDerived(MostDerived),
-      DerivedLayout(CGM.getContext().getASTRecordLayout(MostDerived)) {}
-
-void VBTableBuilder::enumerateVBTables(VBTableVector &VBTables) {
-  VBTablePathVector Paths;
-  findUnambiguousPaths(MostDerived, BaseSubobject(MostDerived,
-                                                  CharUnits::Zero()), Paths);
-  for (VBTablePathVector::iterator I = Paths.begin(), E = Paths.end();
-       I != E; ++I) {
-    VBTablePath *P = *I;
-    P->VBInfo.GV = getAddrOfVBTable(P->VBInfo.ReusingBase, P->Path);
-    VBTables.push_back(P->VBInfo);
-  }
-}
-
-
-void VBTableBuilder::findUnambiguousPaths(const CXXRecordDecl *ReusingBase,
-                                          BaseSubobject CurSubobject,
-                                          VBTablePathVector &Paths) {
-  size_t PathsStart = Paths.size();
-  bool ReuseVBPtrFromBase = true;
-  const CXXRecordDecl *CurBase = CurSubobject.getBase();
-  const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(CurBase);
-
-  // If this base has a vbptr, then we've found a path.  These are not full
-  // paths, so we don't use CXXBasePath.
-  if (Layout.hasOwnVBPtr()) {
-    ReuseVBPtrFromBase = false;
-    VBTablePath *Info = new VBTablePath(
-      VBTableInfo(ReusingBase, CurSubobject, /*GV=*/0));
-    Paths.push_back(Info);
-  }
-
-  // Recurse onto any bases which themselves have virtual bases.
-  for (CXXRecordDecl::base_class_const_iterator I = CurBase->bases_begin(),
-       E = CurBase->bases_end(); I != E; ++I) {
-    const CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl();
-    if (!Base->getNumVBases())
-      continue;  // Bases without virtual bases have no vbptrs.
-    CharUnits NextOffset;
-    const CXXRecordDecl *NextReusingBase = Base;
-    if (I->isVirtual()) {
-      if (!VBasesSeen.insert(Base))
-        continue;  // Don't visit virtual bases twice.
-      NextOffset = DerivedLayout.getVBaseClassOffset(Base);
-    } else {
-      NextOffset = (CurSubobject.getBaseOffset() +
-                    Layout.getBaseClassOffset(Base));
-
-      // If CurBase didn't have a vbptr, then ReusingBase will reuse the vbptr
-      // from the first non-virtual base with vbases for its vbptr.
-      if (ReuseVBPtrFromBase) {
-        NextReusingBase = ReusingBase;
-        ReuseVBPtrFromBase = false;
-      }
-    }
-
-    size_t NumPaths = Paths.size();
-    findUnambiguousPaths(NextReusingBase, BaseSubobject(Base, NextOffset),
-                         Paths);
-
-    // Tag paths through this base with the base itself.  We might use it to
-    // disambiguate.
-    for (size_t I = NumPaths, E = Paths.size(); I != E; ++I)
-      Paths[I]->NextBase = Base;
-  }
-
-  bool AmbiguousPaths = rebucketPaths(Paths, PathsStart);
-  if (AmbiguousPaths)
-    rebucketPaths(Paths, PathsStart, /*SecondPass=*/true);
-
-#ifndef NDEBUG
-  // Check that the paths are in fact unique.
-  for (size_t I = PathsStart + 1, E = Paths.size(); I != E; ++I) {
-    assert(Paths[I]->Path != Paths[I - 1]->Path && "vbtable paths are not unique");
-  }
-#endif
-}
-
-static bool pathCompare(VBTablePath *LHS, VBTablePath *RHS) {
-  return LHS->Path < RHS->Path;
-}
-
-void VBTableBuilder::extendPath(VBTablePath *P, bool SecondPass) {
-  assert(P->NextBase || SecondPass);
-  if (P->NextBase) {
-    P->Path.push_back(P->NextBase);
-    P->NextBase = 0;  // Prevent the path from being extended twice.
-  }
-}
-
-bool VBTableBuilder::rebucketPaths(VBTablePathVector &Paths, size_t PathsStart,
-                                   bool SecondPass) {
-  // What we're essentially doing here is bucketing together ambiguous paths.
-  // Any bucket with more than one path in it gets extended by NextBase, which
-  // is usually the direct base of the inherited the vbptr.  This code uses a
-  // sorted vector to implement a multiset to form the buckets.  Note that the
-  // ordering is based on pointers, but it doesn't change our output order.  The
-  // current algorithm is designed to match MSVC 2012's names.
-  // TODO: Implement MSVC 2010 or earlier names to avoid extra vbtable cruft.
-  VBTablePathVector PathsSorted(&Paths[PathsStart], &Paths.back() + 1);
-  std::sort(PathsSorted.begin(), PathsSorted.end(), pathCompare);
-  bool AmbiguousPaths = false;
-  for (size_t I = 0, E = PathsSorted.size(); I != E;) {
-    // Scan forward to find the end of the bucket.
-    size_t BucketStart = I;
-    do {
-      ++I;
-    } while (I != E && PathsSorted[BucketStart]->Path == PathsSorted[I]->Path);
-
-    // If this bucket has multiple paths, extend them all.
-    if (I - BucketStart > 1) {
-      AmbiguousPaths = true;
-      for (size_t II = BucketStart; II != I; ++II)
-        extendPath(PathsSorted[II], SecondPass);
-    }
-  }
-  return AmbiguousPaths;
-}
-
-llvm::GlobalVariable *
-VBTableBuilder::getAddrOfVBTable(const CXXRecordDecl *ReusingBase,
-                                 ArrayRef<const CXXRecordDecl *> BasePath) {
-  // Caching at this layer is redundant with the caching in EnumerateVBTables().
-
-  SmallString<256> OutName;
-  llvm::raw_svector_ostream Out(OutName);
-  MicrosoftMangleContext &Mangler =
-      cast<MicrosoftMangleContext>(CGM.getCXXABI().getMangleContext());
-  Mangler.mangleCXXVBTable(MostDerived, BasePath, Out);
-  Out.flush();
-  StringRef Name = OutName.str();
-
-  llvm::ArrayType *VBTableType =
-    llvm::ArrayType::get(CGM.IntTy, 1 + ReusingBase->getNumVBases());
-
-  assert(!CGM.getModule().getNamedGlobal(Name) &&
-         "vbtable with this name already exists: mangling bug?");
-  llvm::GlobalVariable *VBTable =
-    CGM.CreateOrReplaceCXXRuntimeVariable(Name, VBTableType,
-                                          llvm::GlobalValue::ExternalLinkage);
-  VBTable->setUnnamedAddr(true);
-  return VBTable;
-}
-
-void VBTableInfo::EmitVBTableDefinition(
-    CodeGenModule &CGM, const CXXRecordDecl *RD,
-    llvm::GlobalVariable::LinkageTypes Linkage) const {
-  assert(RD->getNumVBases() && ReusingBase->getNumVBases() &&
-         "should only emit vbtables for classes with vbtables");
-
-  const ASTRecordLayout &BaseLayout =
-    CGM.getContext().getASTRecordLayout(VBPtrSubobject.getBase());
-  const ASTRecordLayout &DerivedLayout =
-    CGM.getContext().getASTRecordLayout(RD);
-
-  SmallVector<llvm::Constant *, 4> Offsets(1 + ReusingBase->getNumVBases(), 0);
-
-  // The offset from ReusingBase's vbptr to itself always leads.
-  CharUnits VBPtrOffset = BaseLayout.getVBPtrOffset();
-  Offsets[0] = llvm::ConstantInt::get(CGM.IntTy, -VBPtrOffset.getQuantity());
-
-  MicrosoftVTableContext &Context = CGM.getMicrosoftVTableContext();
-  for (CXXRecordDecl::base_class_const_iterator I = ReusingBase->vbases_begin(),
-       E = ReusingBase->vbases_end(); I != E; ++I) {
-    const CXXRecordDecl *VBase = I->getType()->getAsCXXRecordDecl();
-    CharUnits Offset = DerivedLayout.getVBaseClassOffset(VBase);
-    assert(!Offset.isNegative());
-    // Make it relative to the subobject vbptr.
-    Offset -= VBPtrSubobject.getBaseOffset() + VBPtrOffset;
-    unsigned VBIndex = Context.getVBTableIndex(ReusingBase, VBase);
-    assert(Offsets[VBIndex] == 0 && "The same vbindex seen twice?");
-    Offsets[VBIndex] = llvm::ConstantInt::get(CGM.IntTy, Offset.getQuantity());
-  }
-
-  assert(Offsets.size() ==
-         cast<llvm::ArrayType>(cast<llvm::PointerType>(GV->getType())
-                               ->getElementType())->getNumElements());
-  llvm::ArrayType *VBTableType =
-    llvm::ArrayType::get(CGM.IntTy, Offsets.size());
-  llvm::Constant *Init = llvm::ConstantArray::get(VBTableType, Offsets);
-  GV->setInitializer(Init);
-
-  // Set the correct linkage.
-  GV->setLinkage(Linkage);
-
-  // Set the right visibility.
-  CGM.setTypeVisibility(GV, RD, CodeGenModule::TVK_ForVTable);
-}
-
-} // namespace CodeGen
-} // namespace clang
diff --git a/lib/CodeGen/MicrosoftVBTables.h b/lib/CodeGen/MicrosoftVBTables.h
deleted file mode 100644
index 4ad8e07..0000000
--- a/lib/CodeGen/MicrosoftVBTables.h
+++ /dev/null
@@ -1,129 +0,0 @@
-//===--- MicrosoftVBTables.h - Virtual Base Table Emission ----------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This class generates data about MSVC virtual base tables.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/BaseSubobject.h"
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/IR/GlobalVariable.h"
-#include <vector>
-
-namespace clang {
-
-class ASTRecordLayout;
-
-namespace CodeGen {
-
-class CodeGenModule;
-
-struct VBTableInfo {
-  VBTableInfo(const CXXRecordDecl *ReusingBase, BaseSubobject VBPtrSubobject,
-              llvm::GlobalVariable *GV)
-    : ReusingBase(ReusingBase), VBPtrSubobject(VBPtrSubobject), GV(GV) { }
-
-  /// The vbtable will hold all of the virtual bases of ReusingBase.  This may
-  /// or may not be the same class as VBPtrSubobject.Base.  A derived class will
-  /// reuse the vbptr of the first non-virtual base subobject that has one.
-  const CXXRecordDecl *ReusingBase;
-
-  /// The vbptr is stored inside this subobject.
-  BaseSubobject VBPtrSubobject;
-
-  /// The GlobalVariable for this vbtable.
-  llvm::GlobalVariable *GV;
-
-  /// \brief Emits a definition for GV by setting it's initializer.
-  void EmitVBTableDefinition(CodeGenModule &CGM, const CXXRecordDecl *RD,
-                             llvm::GlobalVariable::LinkageTypes Linkage) const;
-};
-
-// These are embedded in a DenseMap and the elements are large, so we don't want
-// SmallVector.
-typedef std::vector<VBTableInfo> VBTableVector;
-
-struct VBTablePath;
-
-typedef llvm::SmallVector<VBTablePath *, 6> VBTablePathVector;
-
-/// Produces MSVC-compatible vbtable data.  The symbols produced by this builder
-/// match those produced by MSVC 2012, which is different from MSVC 2010.
-///
-/// Unlike Itanium, which uses only one vtable per class, MSVC uses a different
-/// symbol for every "address point" installed in base subobjects.  As a result,
-/// we have to compute unique symbols for every table.  Since there can be
-/// multiple non-virtual base subobjects of the same class, combining the most
-/// derived class with the base containing the vtable is insufficient.  The most
-/// trivial algorithm would be to mangle in the entire path from base to most
-/// derived, but that would be too easy and would create unnecessarily large
-/// symbols.  ;)
-///
-/// MSVC 2012 appears to minimize the vbtable names using the following
-/// algorithm.  First, walk the class hierarchy in the usual order, depth first,
-/// left to right, to find all of the subobjects which contain a vbptr field.
-/// Visiting each class node yields a list of inheritance paths to vbptrs.  Each
-/// record with a vbptr creates an initially empty path.
-///
-/// To combine paths from child nodes, the paths are compared to check for
-/// ambiguity.  Paths are "ambiguous" if multiple paths have the same set of
-/// components in the same order.  Each group of ambiguous paths is extended by
-/// appending the class of the base from which it came.  If the current class
-/// node produced an ambiguous path, its path is extended with the current class.
-/// After extending paths, MSVC again checks for ambiguity, and extends any
-/// ambiguous path which wasn't already extended.  Because each node yields an
-/// unambiguous set of paths, MSVC doesn't need to extend any path more than once
-/// to produce an unambiguous set of paths.
-///
-/// The VBTableBuilder class attempts to implement this algorithm by repeatedly
-/// bucketing paths together by sorting them.
-///
-/// TODO: Presumably vftables use the same algorithm.
-///
-/// TODO: Implement the MSVC 2010 name mangling scheme to avoid emitting
-/// duplicate vbtables with different symbols.
-class VBTableBuilder {
-public:
-  VBTableBuilder(CodeGenModule &CGM, const CXXRecordDecl *MostDerived);
-
-  void enumerateVBTables(VBTableVector &VBTables);
-
-private:
-  bool hasVBPtr(const CXXRecordDecl *RD);
-
-  llvm::GlobalVariable *getAddrOfVBTable(const CXXRecordDecl *ReusingBase,
-                                      ArrayRef<const CXXRecordDecl *> BasePath);
-
-  /// Enumerates paths to bases with vbptrs.  The paths elements are compressed
-  /// to contain only the classes necessary to form an unambiguous path.
-  void findUnambiguousPaths(const CXXRecordDecl *ReusingBase,
-                            BaseSubobject CurSubobject,
-                            VBTablePathVector &Paths);
-
-  void extendPath(VBTablePath *Info, bool SecondPass);
-
-  bool rebucketPaths(VBTablePathVector &Paths, size_t PathsStart,
-                     bool SecondPass = false);
-
-  CodeGenModule &CGM;
-
-  const CXXRecordDecl *MostDerived;
-
-  /// Caches the layout of the most derived class.
-  const ASTRecordLayout &DerivedLayout;
-
-  /// Set of vbases to avoid re-visiting the same vbases.
-  llvm::SmallPtrSet<const CXXRecordDecl*, 4> VBasesSeen;
-};
-
-} // namespace CodeGen
-
-} // namespace clang
diff --git a/lib/CodeGen/ModuleBuilder.cpp b/lib/CodeGen/ModuleBuilder.cpp
index bc7acbc..c5d18d3 100644
--- a/lib/CodeGen/ModuleBuilder.cpp
+++ b/lib/CodeGen/ModuleBuilder.cpp
@@ -12,30 +12,31 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/CodeGen/ModuleBuilder.h"
-#include "CodeGenModule.h"
 #include "CGDebugInfo.h"
+#include "CodeGenModule.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/Expr.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Frontend/CodeGenOptions.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
+#include <memory>
 using namespace clang;
 
 namespace {
   class CodeGeneratorImpl : public CodeGenerator {
     DiagnosticsEngine &Diags;
-    OwningPtr<const llvm::DataLayout> TD;
+    std::unique_ptr<const llvm::DataLayout> TD;
     ASTContext *Ctx;
     const CodeGenOptions CodeGenOpts;  // Intentionally copied in.
   protected:
-    OwningPtr<llvm::Module> M;
-    OwningPtr<CodeGen::CodeGenModule> Builder;
+    std::unique_ptr<llvm::Module> M;
+    std::unique_ptr<CodeGen::CodeGenModule> Builder;
+
   public:
     CodeGeneratorImpl(DiagnosticsEngine &diags, const std::string& ModuleName,
                       const CodeGenOptions &CGO, llvm::LLVMContext& C)
@@ -44,15 +45,28 @@
 
     virtual ~CodeGeneratorImpl() {}
 
-    virtual llvm::Module* GetModule() {
+    llvm::Module* GetModule() override {
       return M.get();
     }
 
-    virtual llvm::Module* ReleaseModule() {
-      return M.take();
+    const Decl *GetDeclForMangledName(StringRef MangledName) override {
+      GlobalDecl Result;
+      if (!Builder->lookupRepresentativeDecl(MangledName, Result))
+        return nullptr;
+      const Decl *D = Result.getCanonicalDecl().getDecl();
+      if (auto FD = dyn_cast<FunctionDecl>(D)) {
+        if (FD->hasBody(FD))
+          return FD;
+      } else if (auto TD = dyn_cast<TagDecl>(D)) {
+        if (auto Def = TD->getDefinition())
+          return Def;
+      }
+      return D;
     }
 
-    virtual void Initialize(ASTContext &Context) {
+    llvm::Module *ReleaseModule() override { return M.release(); }
+
+    void Initialize(ASTContext &Context) override {
       Ctx = &Context;
 
       M->setTargetTriple(Ctx->getTargetInfo().getTriple().getTriple());
@@ -65,48 +79,71 @@
         HandleDependentLibrary(CodeGenOpts.DependentLibraries[i]);
     }
 
-    virtual void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) {
+    void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override {
       if (Diags.hasErrorOccurred())
         return;
 
       Builder->HandleCXXStaticMemberVarInstantiation(VD);
     }
 
-    virtual bool HandleTopLevelDecl(DeclGroupRef DG) {
+    bool HandleTopLevelDecl(DeclGroupRef DG) override {
       if (Diags.hasErrorOccurred())
         return true;
 
       // Make sure to emit all elements of a Decl.
       for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
         Builder->EmitTopLevelDecl(*I);
+
+      // Emit any deferred inline method definitions.
+      for (CXXMethodDecl *MD : DeferredInlineMethodDefinitions)
+        Builder->EmitTopLevelDecl(MD);
+      DeferredInlineMethodDefinitions.clear();
+
       return true;
     }
 
+    void HandleInlineMethodDefinition(CXXMethodDecl *D) override {
+      if (Diags.hasErrorOccurred())
+        return;
+
+      assert(D->doesThisDeclarationHaveABody());
+
+      // We may want to emit this definition. However, that decision might be
+      // based on computing the linkage, and we have to defer that in case we
+      // are inside of something that will change the method's final linkage,
+      // e.g.
+      //   typedef struct {
+      //     void bar();
+      //     void foo() { bar(); }
+      //   } A;
+      DeferredInlineMethodDefinitions.push_back(D);
+    }
+
     /// HandleTagDeclDefinition - This callback is invoked each time a TagDecl
     /// to (e.g. struct, union, enum, class) is completed. This allows the
     /// client hack on the type, which can occur at any point in the file
     /// (because these can be defined in declspecs).
-    virtual void HandleTagDeclDefinition(TagDecl *D) {
+    void HandleTagDeclDefinition(TagDecl *D) override {
       if (Diags.hasErrorOccurred())
         return;
 
       Builder->UpdateCompletedType(D);
-      
-      // In C++, we may have member functions that need to be emitted at this 
-      // point.
-      if (Ctx->getLangOpts().CPlusPlus && !D->isDependentContext()) {
-        for (DeclContext::decl_iterator M = D->decls_begin(), 
-                                     MEnd = D->decls_end();
-             M != MEnd; ++M)
-          if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(*M))
-            if (Method->doesThisDeclarationHaveABody() &&
-                (Method->hasAttr<UsedAttr>() || 
-                 Method->hasAttr<ConstructorAttr>()))
-              Builder->EmitTopLevelDecl(Method);
+
+      // For MSVC compatibility, treat declarations of static data members with
+      // inline initializers as definitions.
+      if (Ctx->getLangOpts().MSVCCompat) {
+        for (Decl *Member : D->decls()) {
+          if (VarDecl *VD = dyn_cast<VarDecl>(Member)) {
+            if (Ctx->isMSStaticDataMemberInlineDefinition(VD) &&
+                Ctx->DeclMustBeEmitted(VD)) {
+              Builder->EmitGlobal(VD);
+            }
+          }
+        }
       }
     }
 
-    virtual void HandleTagDeclRequiredDefinition(const TagDecl *D) LLVM_OVERRIDE {
+    void HandleTagDeclRequiredDefinition(const TagDecl *D) override {
       if (Diags.hasErrorOccurred())
         return;
 
@@ -115,8 +152,10 @@
           DI->completeRequiredType(RD);
     }
 
-    virtual void HandleTranslationUnit(ASTContext &Ctx) {
+    void HandleTranslationUnit(ASTContext &Ctx) override {
       if (Diags.hasErrorOccurred()) {
+        if (Builder)
+          Builder->clear();
         M.reset();
         return;
       }
@@ -125,32 +164,35 @@
         Builder->Release();
     }
 
-    virtual void CompleteTentativeDefinition(VarDecl *D) {
+    void CompleteTentativeDefinition(VarDecl *D) override {
       if (Diags.hasErrorOccurred())
         return;
 
       Builder->EmitTentativeDefinition(D);
     }
 
-    virtual void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) {
+    void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) override {
       if (Diags.hasErrorOccurred())
         return;
 
       Builder->EmitVTable(RD, DefinitionRequired);
     }
 
-    virtual void HandleLinkerOptionPragma(llvm::StringRef Opts) {
+    void HandleLinkerOptionPragma(llvm::StringRef Opts) override {
       Builder->AppendLinkerOptions(Opts);
     }
 
-    virtual void HandleDetectMismatch(llvm::StringRef Name,
-                                      llvm::StringRef Value) {
+    void HandleDetectMismatch(llvm::StringRef Name,
+                              llvm::StringRef Value) override {
       Builder->AddDetectMismatch(Name, Value);
     }
 
-    virtual void HandleDependentLibrary(llvm::StringRef Lib) {
+    void HandleDependentLibrary(llvm::StringRef Lib) override {
       Builder->AddDependentLib(Lib);
     }
+
+  private:
+    std::vector<CXXMethodDecl *> DeferredInlineMethodDefinitions;
   };
 }
 
diff --git a/lib/CodeGen/SanitizerBlacklist.cpp b/lib/CodeGen/SanitizerBlacklist.cpp
new file mode 100644
index 0000000..9f1ddc8
--- /dev/null
+++ b/lib/CodeGen/SanitizerBlacklist.cpp
@@ -0,0 +1,52 @@
+//===--- SanitizerBlacklist.cpp - Blacklist for sanitizers ----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// User-provided blacklist used to disable/alter instrumentation done in
+// sanitizers.
+//
+//===----------------------------------------------------------------------===//
+#include "SanitizerBlacklist.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/Module.h"
+
+using namespace clang;
+using namespace CodeGen;
+
+static StringRef GetGlobalTypeString(const llvm::GlobalValue &G) {
+  // Types of GlobalVariables are always pointer types.
+  llvm::Type *GType = G.getType()->getElementType();
+  // For now we support blacklisting struct types only.
+  if (llvm::StructType *SGType = dyn_cast<llvm::StructType>(GType)) {
+    if (!SGType->isLiteral())
+      return SGType->getName();
+  }
+  return "<unknown type>";
+}
+
+bool SanitizerBlacklist::isIn(const llvm::Module &M,
+                              const StringRef Category) const {
+  return SCL->inSection("src", M.getModuleIdentifier(), Category);
+}
+
+bool SanitizerBlacklist::isIn(const llvm::Function &F) const {
+  return isIn(*F.getParent()) ||
+         SCL->inSection("fun", F.getName(), "");
+}
+
+bool SanitizerBlacklist::isIn(const llvm::GlobalVariable &G,
+                              const StringRef Category) const {
+  return isIn(*G.getParent(), Category) ||
+         SCL->inSection("global", G.getName(), Category) ||
+         SCL->inSection("type", GetGlobalTypeString(G), Category);
+}
+
+bool SanitizerBlacklist::isBlacklistedType(StringRef MangledTypeName) const {
+  return SCL->inSection("type", MangledTypeName);
+}
diff --git a/lib/CodeGen/SanitizerBlacklist.h b/lib/CodeGen/SanitizerBlacklist.h
new file mode 100644
index 0000000..659441d
--- /dev/null
+++ b/lib/CodeGen/SanitizerBlacklist.h
@@ -0,0 +1,46 @@
+//===--- SanitizerBlacklist.h - Blacklist for sanitizers --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// User-provided blacklist used to disable/alter instrumentation done in
+// sanitizers.
+//
+//===----------------------------------------------------------------------===//
+#ifndef CLANG_CODEGEN_SANITIZERBLACKLIST_H
+#define CLANG_CODEGEN_SANITIZERBLACKLIST_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/SpecialCaseList.h"
+#include <memory>
+
+namespace llvm {
+class GlobalVariable;
+class Function;
+class Module;
+}
+
+namespace clang {
+namespace CodeGen {
+
+class SanitizerBlacklist {
+  std::unique_ptr<llvm::SpecialCaseList> SCL;
+
+public:
+  SanitizerBlacklist(llvm::SpecialCaseList *SCL) : SCL(SCL) {}
+  bool isIn(const llvm::Module &M,
+            const StringRef Category = StringRef()) const;
+  bool isIn(const llvm::Function &F) const;
+  bool isIn(const llvm::GlobalVariable &G,
+            const StringRef Category = StringRef()) const;
+  bool isBlacklistedType(StringRef MangledTypeName) const;
+};
+}  // end namespace CodeGen
+}  // end namespace clang
+
+#endif
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp
index 9ed0dc0..82365e3 100644
--- a/lib/CodeGen/TargetInfo.cpp
+++ b/lib/CodeGen/TargetInfo.cpp
@@ -23,6 +23,9 @@
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/Type.h"
 #include "llvm/Support/raw_ostream.h"
+
+#include <algorithm>    // std::sort
+
 using namespace clang;
 using namespace CodeGen;
 
@@ -45,22 +48,6 @@
 
 ABIInfo::~ABIInfo() {}
 
-static bool isRecordReturnIndirect(const RecordType *RT,
-                                   CGCXXABI &CXXABI) {
-  const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
-  if (!RD)
-    return false;
-  return CXXABI.isReturnTypeIndirect(RD);
-}
-
-
-static bool isRecordReturnIndirect(QualType T, CGCXXABI &CXXABI) {
-  const RecordType *RT = T->getAs<RecordType>();
-  if (!RT)
-    return false;
-  return isRecordReturnIndirect(RT, CXXABI);
-}
-
 static CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT,
                                               CGCXXABI &CXXABI) {
   const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
@@ -114,6 +101,9 @@
   case Ignore:
     OS << "Ignore";
     break;
+  case InAlloca:
+    OS << "InAlloca Offset=" << getInAllocaFieldIndex();
+    break;
   case Indirect:
     OS << "Indirect Align=" << getIndirectAlign()
        << " ByVal=" << getIndirectByVal()
@@ -206,14 +196,12 @@
 
   // If this is a C++ record, check the bases first.
   if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
-    for (CXXRecordDecl::base_class_const_iterator i = CXXRD->bases_begin(),
-           e = CXXRD->bases_end(); i != e; ++i)
-      if (!isEmptyRecord(Context, i->getType(), true))
+    for (const auto &I : CXXRD->bases())
+      if (!isEmptyRecord(Context, I.getType(), true))
         return false;
 
-  for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
-         i != e; ++i)
-    if (!isEmptyField(Context, *i, AllowArrays))
+  for (const auto *I : RD->fields())
+    if (!isEmptyField(Context, I, AllowArrays))
       return false;
   return true;
 }
@@ -229,38 +217,35 @@
 static const Type *isSingleElementStruct(QualType T, ASTContext &Context) {
   const RecordType *RT = T->getAsStructureType();
   if (!RT)
-    return 0;
+    return nullptr;
 
   const RecordDecl *RD = RT->getDecl();
   if (RD->hasFlexibleArrayMember())
-    return 0;
+    return nullptr;
 
-  const Type *Found = 0;
+  const Type *Found = nullptr;
 
   // If this is a C++ record, check the bases first.
   if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
-    for (CXXRecordDecl::base_class_const_iterator i = CXXRD->bases_begin(),
-           e = CXXRD->bases_end(); i != e; ++i) {
+    for (const auto &I : CXXRD->bases()) {
       // Ignore empty records.
-      if (isEmptyRecord(Context, i->getType(), true))
+      if (isEmptyRecord(Context, I.getType(), true))
         continue;
 
       // If we already found an element then this isn't a single-element struct.
       if (Found)
-        return 0;
+        return nullptr;
 
       // If this is non-empty and not a single element struct, the composite
       // cannot be a single element struct.
-      Found = isSingleElementStruct(i->getType(), Context);
+      Found = isSingleElementStruct(I.getType(), Context);
       if (!Found)
-        return 0;
+        return nullptr;
     }
   }
 
   // Check for single element.
-  for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
-         i != e; ++i) {
-    const FieldDecl *FD = *i;
+  for (const auto *FD : RD->fields()) {
     QualType FT = FD->getType();
 
     // Ignore empty fields.
@@ -270,7 +255,7 @@
     // If we already found an element then this isn't a single-element
     // struct.
     if (Found)
-      return 0;
+      return nullptr;
 
     // Treat single element arrays as the element.
     while (const ConstantArrayType *AT = Context.getAsConstantArrayType(FT)) {
@@ -284,14 +269,14 @@
     } else {
       Found = isSingleElementStruct(FT, Context);
       if (!Found)
-        return 0;
+        return nullptr;
     }
   }
 
   // We don't consider a struct a single-element struct if it has
   // padding beyond the element type.
   if (Found && Context.getTypeSize(Found) != Context.getTypeSize(T))
-    return 0;
+    return nullptr;
 
   return Found;
 }
@@ -336,10 +321,7 @@
 
   uint64_t Size = 0;
 
-  for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
-         i != e; ++i) {
-    const FieldDecl *FD = *i;
-
+  for (const auto *FD : RD->fields()) {
     if (!is32Or64BitBasicType(FD->getType(), Context))
       return false;
 
@@ -371,15 +353,15 @@
   ABIArgInfo classifyReturnType(QualType RetTy) const;
   ABIArgInfo classifyArgumentType(QualType RetTy) const;
 
-  virtual void computeInfo(CGFunctionInfo &FI) const {
-    FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
-    for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
-         it != ie; ++it)
-      it->info = classifyArgumentType(it->type);
+  void computeInfo(CGFunctionInfo &FI) const override {
+    if (!getCXXABI().classifyReturnType(FI))
+      FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
+    for (auto &I : FI.arguments())
+      I.info = classifyArgumentType(I.type);
   }
 
-  virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
-                                 CodeGenFunction &CGF) const;
+  llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+                         CodeGenFunction &CGF) const override;
 };
 
 class DefaultTargetCodeGenInfo : public TargetCodeGenInfo {
@@ -390,18 +372,12 @@
 
 llvm::Value *DefaultABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
                                        CodeGenFunction &CGF) const {
-  return 0;
+  return nullptr;
 }
 
 ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty) const {
-  if (isAggregateTypeForABI(Ty)) {
-    // Records with non trivial destructors/constructors should not be passed
-    // by value.
-    if (isRecordReturnIndirect(Ty, getCXXABI()))
-      return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
-
+  if (isAggregateTypeForABI(Ty))
     return ABIArgInfo::getIndirect(0);
-  }
 
   // Treat an enum type as its underlying type.
   if (const EnumType *EnumTy = Ty->getAs<EnumType>())
@@ -494,9 +470,9 @@
   ABIArgInfo classifyReturnType(QualType RetTy) const;
   ABIArgInfo classifyArgumentType(QualType RetTy) const;
 
-  virtual void computeInfo(CGFunctionInfo &FI) const;
-  virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
-                                 CodeGenFunction &CGF) const;
+  void computeInfo(CGFunctionInfo &FI) const override;
+  llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+                         CodeGenFunction &CGF) const override;
 };
 
 class PNaClTargetCodeGenInfo : public TargetCodeGenInfo {
@@ -509,16 +485,16 @@
 };
 
 void PNaClABIInfo::computeInfo(CGFunctionInfo &FI) const {
+  if (!getCXXABI().classifyReturnType(FI))
     FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
 
-    for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
-         it != ie; ++it)
-      it->info = classifyArgumentType(it->type);
-  }
+  for (auto &I : FI.arguments())
+    I.info = classifyArgumentType(I.type);
+}
 
 llvm::Value *PNaClABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
                                        CodeGenFunction &CGF) const {
-  return 0;
+  return nullptr;
 }
 
 /// \brief Classify argument of given type \p Ty.
@@ -569,7 +545,7 @@
   if ((Constraint == "y" || Constraint == "&y") && Ty->isVectorTy()) {
     if (cast<llvm::VectorType>(Ty)->getBitWidth() != 64) {
       // Invalid MMX constraint
-      return 0;
+      return nullptr;
     }
 
     return llvm::Type::getX86_MMXTy(CGF.getLLVMContext());
@@ -583,6 +559,16 @@
 // X86-32 ABI Implementation
 //===----------------------------------------------------------------------===//
 
+/// \brief Similar to llvm::CCState, but for Clang.
+struct CCState {
+  CCState(unsigned CC) : CC(CC), FreeRegs(0) {}
+
+  unsigned CC;
+  unsigned FreeRegs;
+  unsigned StackOffset;
+  bool UseInAlloca;
+};
+
 /// X86_32ABIInfo - The X86-32 ABI information.
 class X86_32ABIInfo : public ABIInfo {
   enum Class {
@@ -601,30 +587,35 @@
     return (Size == 8 || Size == 16 || Size == 32 || Size == 64);
   }
 
-  static bool shouldReturnTypeInRegister(QualType Ty, ASTContext &Context, 
-                                          unsigned callingConvention);
+  bool shouldReturnTypeInRegister(QualType Ty, ASTContext &Context) const;
 
   /// getIndirectResult - Give a source type \arg Ty, return a suitable result
   /// such that the argument will be passed in memory.
-  ABIArgInfo getIndirectResult(QualType Ty, bool ByVal,
-                               unsigned &FreeRegs) const;
+  ABIArgInfo getIndirectResult(QualType Ty, bool ByVal, CCState &State) const;
+
+  ABIArgInfo getIndirectReturnResult(CCState &State) const;
 
   /// \brief Return the alignment to use for the given type on the stack.
   unsigned getTypeStackAlignInBytes(QualType Ty, unsigned Align) const;
 
   Class classify(QualType Ty) const;
-  ABIArgInfo classifyReturnType(QualType RetTy,
-                                unsigned callingConvention) const;
-  ABIArgInfo classifyArgumentType(QualType RetTy, unsigned &FreeRegs,
-                                  bool IsFastCall) const;
-  bool shouldUseInReg(QualType Ty, unsigned &FreeRegs,
-                      bool IsFastCall, bool &NeedsPadding) const;
+  ABIArgInfo classifyReturnType(QualType RetTy, CCState &State) const;
+  ABIArgInfo classifyArgumentType(QualType RetTy, CCState &State) const;
+  bool shouldUseInReg(QualType Ty, CCState &State, bool &NeedsPadding) const;
+
+  /// \brief Rewrite the function info so that all memory arguments use
+  /// inalloca.
+  void rewriteWithInAlloca(CGFunctionInfo &FI) const;
+
+  void addFieldToArgStruct(SmallVector<llvm::Type *, 6> &FrameFields,
+                           unsigned &StackOffset, ABIArgInfo &Info,
+                           QualType Type) const;
 
 public:
 
-  virtual void computeInfo(CGFunctionInfo &FI) const;
-  virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
-                                 CodeGenFunction &CGF) const;
+  void computeInfo(CGFunctionInfo &FI) const override;
+  llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+                         CodeGenFunction &CGF) const override;
 
   X86_32ABIInfo(CodeGen::CodeGenTypes &CGT, bool d, bool p, bool w,
                 unsigned r)
@@ -642,24 +633,25 @@
       const llvm::Triple &Triple, const CodeGenOptions &Opts);
 
   void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
-                           CodeGen::CodeGenModule &CGM) const;
+                           CodeGen::CodeGenModule &CGM) const override;
 
-  int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const {
+  int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const override {
     // Darwin uses different dwarf register numbers for EH.
     if (CGM.getTarget().getTriple().isOSDarwin()) return 5;
     return 4;
   }
 
   bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
-                               llvm::Value *Address) const;
+                               llvm::Value *Address) const override;
 
   llvm::Type* adjustInlineAsmType(CodeGen::CodeGenFunction &CGF,
                                   StringRef Constraint,
-                                  llvm::Type* Ty) const {
+                                  llvm::Type* Ty) const override {
     return X86AdjustInlineAsmType(CGF, Constraint, Ty);
   }
 
-  llvm::Constant *getUBSanFunctionSignature(CodeGen::CodeGenModule &CGM) const {
+  llvm::Constant *
+  getUBSanFunctionSignature(CodeGen::CodeGenModule &CGM) const override {
     unsigned Sig = (0xeb << 0) |  // jmp rel8
                    (0x06 << 8) |  //           .+0x08
                    ('F' << 16) |
@@ -674,8 +666,7 @@
 /// shouldReturnTypeInRegister - Determine if the given type should be
 /// passed in a register (for the Darwin ABI).
 bool X86_32ABIInfo::shouldReturnTypeInRegister(QualType Ty,
-                                               ASTContext &Context,
-                                               unsigned callingConvention) {
+                                               ASTContext &Context) const {
   uint64_t Size = Context.getTypeSize(Ty);
 
   // Type must be register sized.
@@ -700,8 +691,7 @@
 
   // Arrays are treated like records.
   if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty))
-    return shouldReturnTypeInRegister(AT->getElementType(), Context,
-                                      callingConvention);
+    return shouldReturnTypeInRegister(AT->getElementType(), Context);
 
   // Otherwise, it must be a record type.
   const RecordType *RT = Ty->getAs<RecordType>();
@@ -709,33 +699,31 @@
 
   // FIXME: Traverse bases here too.
 
-  // For thiscall conventions, structures will never be returned in
-  // a register.  This is for compatibility with the MSVC ABI
-  if (callingConvention == llvm::CallingConv::X86_ThisCall && 
-      RT->isStructureType()) {
-    return false;
-  }
-
   // Structure types are passed in register if all fields would be
   // passed in a register.
-  for (RecordDecl::field_iterator i = RT->getDecl()->field_begin(),
-         e = RT->getDecl()->field_end(); i != e; ++i) {
-    const FieldDecl *FD = *i;
-
+  for (const auto *FD : RT->getDecl()->fields()) {
     // Empty fields are ignored.
     if (isEmptyField(Context, FD, true))
       continue;
 
     // Check fields recursively.
-    if (!shouldReturnTypeInRegister(FD->getType(), Context, 
-                                    callingConvention))
+    if (!shouldReturnTypeInRegister(FD->getType(), Context))
       return false;
   }
   return true;
 }
 
-ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy, 
-                                            unsigned callingConvention) const {
+ABIArgInfo X86_32ABIInfo::getIndirectReturnResult(CCState &State) const {
+  // If the return value is indirect, then the hidden argument is consuming one
+  // integer register.
+  if (State.FreeRegs) {
+    --State.FreeRegs;
+    return ABIArgInfo::getIndirectInReg(/*Align=*/0, /*ByVal=*/false);
+  }
+  return ABIArgInfo::getIndirect(/*Align=*/0, /*ByVal=*/false);
+}
+
+ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy, CCState &State) const {
   if (RetTy->isVoidType())
     return ABIArgInfo::getIgnore();
 
@@ -758,7 +746,7 @@
         return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(),
                                                             Size));
 
-      return ABIArgInfo::getIndirect(0);
+      return getIndirectReturnResult(State);
     }
 
     return ABIArgInfo::getDirect();
@@ -766,22 +754,18 @@
 
   if (isAggregateTypeForABI(RetTy)) {
     if (const RecordType *RT = RetTy->getAs<RecordType>()) {
-      if (isRecordReturnIndirect(RT, getCXXABI()))
-        return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
-
       // Structures with flexible arrays are always indirect.
       if (RT->getDecl()->hasFlexibleArrayMember())
-        return ABIArgInfo::getIndirect(0);
+        return getIndirectReturnResult(State);
     }
 
     // If specified, structs and unions are always indirect.
     if (!IsSmallStructInRegABI && !RetTy->isAnyComplexType())
-      return ABIArgInfo::getIndirect(0);
+      return getIndirectReturnResult(State);
 
     // Small structures which are register sized are generally returned
     // in a register.
-    if (X86_32ABIInfo::shouldReturnTypeInRegister(RetTy, getContext(), 
-                                                  callingConvention)) {
+    if (shouldReturnTypeInRegister(RetTy, getContext())) {
       uint64_t Size = getContext().getTypeSize(RetTy);
 
       // As a special-case, if the struct is a "single-element" struct, and
@@ -799,7 +783,7 @@
       return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(),Size));
     }
 
-    return ABIArgInfo::getIndirect(0);
+    return getIndirectReturnResult(State);
   }
 
   // Treat an enum type as its underlying type.
@@ -822,13 +806,11 @@
 
   // If this is a C++ record, check the bases first.
   if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
-    for (CXXRecordDecl::base_class_const_iterator i = CXXRD->bases_begin(),
-           e = CXXRD->bases_end(); i != e; ++i)
-      if (!isRecordWithSSEVectorType(Context, i->getType()))
+    for (const auto &I : CXXRD->bases())
+      if (!isRecordWithSSEVectorType(Context, I.getType()))
         return false;
 
-  for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
-       i != e; ++i) {
+  for (const auto *i : RD->fields()) {
     QualType FT = i->getType();
 
     if (isSSEVectorType(Context, FT))
@@ -863,10 +845,10 @@
 }
 
 ABIArgInfo X86_32ABIInfo::getIndirectResult(QualType Ty, bool ByVal,
-                                            unsigned &FreeRegs) const {
+                                            CCState &State) const {
   if (!ByVal) {
-    if (FreeRegs) {
-      --FreeRegs; // Non byval indirects just use one pointer.
+    if (State.FreeRegs) {
+      --State.FreeRegs; // Non-byval indirects just use one pointer.
       return ABIArgInfo::getIndirectInReg(0, false);
     }
     return ABIArgInfo::getIndirect(0, false);
@@ -876,15 +858,12 @@
   unsigned TypeAlign = getContext().getTypeAlign(Ty) / 8;
   unsigned StackAlign = getTypeStackAlignInBytes(Ty, TypeAlign);
   if (StackAlign == 0)
-    return ABIArgInfo::getIndirect(4);
+    return ABIArgInfo::getIndirect(4, /*ByVal=*/true);
 
   // If the stack alignment is less than the type alignment, realign the
   // argument.
-  if (StackAlign < TypeAlign)
-    return ABIArgInfo::getIndirect(StackAlign, /*ByVal=*/true,
-                                   /*Realign=*/true);
-
-  return ABIArgInfo::getIndirect(StackAlign);
+  bool Realign = TypeAlign > StackAlign;
+  return ABIArgInfo::getIndirect(StackAlign, /*ByVal=*/true, Realign);
 }
 
 X86_32ABIInfo::Class X86_32ABIInfo::classify(QualType Ty) const {
@@ -900,8 +879,8 @@
   return Integer;
 }
 
-bool X86_32ABIInfo::shouldUseInReg(QualType Ty, unsigned &FreeRegs,
-                                   bool IsFastCall, bool &NeedsPadding) const {
+bool X86_32ABIInfo::shouldUseInReg(QualType Ty, CCState &State,
+                                   bool &NeedsPadding) const {
   NeedsPadding = false;
   Class C = classify(Ty);
   if (C == Float)
@@ -913,14 +892,14 @@
   if (SizeInRegs == 0)
     return false;
 
-  if (SizeInRegs > FreeRegs) {
-    FreeRegs = 0;
+  if (SizeInRegs > State.FreeRegs) {
+    State.FreeRegs = 0;
     return false;
   }
 
-  FreeRegs -= SizeInRegs;
+  State.FreeRegs -= SizeInRegs;
 
-  if (IsFastCall) {
+  if (State.CC == llvm::CallingConv::X86_FastCall) {
     if (Size > 32)
       return false;
 
@@ -933,7 +912,7 @@
     if (Ty->isReferenceType())
       return true;
 
-    if (FreeRegs)
+    if (State.FreeRegs)
       NeedsPadding = true;
 
     return false;
@@ -943,20 +922,26 @@
 }
 
 ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
-                                               unsigned &FreeRegs,
-                                               bool IsFastCall) const {
+                                               CCState &State) const {
   // FIXME: Set alignment on indirect arguments.
   if (isAggregateTypeForABI(Ty)) {
     if (const RecordType *RT = Ty->getAs<RecordType>()) {
-      if (IsWin32StructABI)
-        return getIndirectResult(Ty, true, FreeRegs);
+      // Check with the C++ ABI first.
+      CGCXXABI::RecordArgABI RAA = getRecordArgABI(RT, getCXXABI());
+      if (RAA == CGCXXABI::RAA_Indirect) {
+        return getIndirectResult(Ty, false, State);
+      } else if (RAA == CGCXXABI::RAA_DirectInMemory) {
+        // The field index doesn't matter, we'll fix it up later.
+        return ABIArgInfo::getInAlloca(/*FieldIndex=*/0);
+      }
 
-      if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(RT, getCXXABI()))
-        return getIndirectResult(Ty, RAA == CGCXXABI::RAA_DirectInMemory, FreeRegs);
+      // Structs are always byval on win32, regardless of what they contain.
+      if (IsWin32StructABI)
+        return getIndirectResult(Ty, true, State);
 
       // Structures with flexible arrays are always indirect.
       if (RT->getDecl()->hasFlexibleArrayMember())
-        return getIndirectResult(Ty, true, FreeRegs);
+        return getIndirectResult(Ty, true, State);
     }
 
     // Ignore empty structs/unions.
@@ -966,13 +951,13 @@
     llvm::LLVMContext &LLVMContext = getVMContext();
     llvm::IntegerType *Int32 = llvm::Type::getInt32Ty(LLVMContext);
     bool NeedsPadding;
-    if (shouldUseInReg(Ty, FreeRegs, IsFastCall, NeedsPadding)) {
+    if (shouldUseInReg(Ty, State, NeedsPadding)) {
       unsigned SizeInRegs = (getContext().getTypeSize(Ty) + 31) / 32;
       SmallVector<llvm::Type*, 3> Elements(SizeInRegs, Int32);
       llvm::Type *Result = llvm::StructType::get(LLVMContext, Elements);
       return ABIArgInfo::getDirectInReg(Result);
     }
-    llvm::IntegerType *PaddingType = NeedsPadding ? Int32 : 0;
+    llvm::IntegerType *PaddingType = NeedsPadding ? Int32 : nullptr;
 
     // Expand small (<= 128-bit) record types when we know that the stack layout
     // of those arguments will match the struct. This is important because the
@@ -980,9 +965,10 @@
     // optimizations.
     if (getContext().getTypeSize(Ty) <= 4*32 &&
         canExpandIndirectArgument(Ty, getContext()))
-      return ABIArgInfo::getExpandWithPadding(IsFastCall, PaddingType);
+      return ABIArgInfo::getExpandWithPadding(
+          State.CC == llvm::CallingConv::X86_FastCall, PaddingType);
 
-    return getIndirectResult(Ty, true, FreeRegs);
+    return getIndirectResult(Ty, true, State);
   }
 
   if (const VectorType *VT = Ty->getAs<VectorType>()) {
@@ -1007,7 +993,7 @@
     Ty = EnumTy->getDecl()->getIntegerType();
 
   bool NeedsPadding;
-  bool InReg = shouldUseInReg(Ty, FreeRegs, IsFastCall, NeedsPadding);
+  bool InReg = shouldUseInReg(Ty, State, NeedsPadding);
 
   if (Ty->isPromotableIntegerType()) {
     if (InReg)
@@ -1020,32 +1006,105 @@
 }
 
 void X86_32ABIInfo::computeInfo(CGFunctionInfo &FI) const {
-  FI.getReturnInfo() = classifyReturnType(FI.getReturnType(),
-                                          FI.getCallingConvention());
-
-  unsigned CC = FI.getCallingConvention();
-  bool IsFastCall = CC == llvm::CallingConv::X86_FastCall;
-  unsigned FreeRegs;
-  if (IsFastCall)
-    FreeRegs = 2;
+  CCState State(FI.getCallingConvention());
+  if (State.CC == llvm::CallingConv::X86_FastCall)
+    State.FreeRegs = 2;
   else if (FI.getHasRegParm())
-    FreeRegs = FI.getRegParm();
+    State.FreeRegs = FI.getRegParm();
   else
-    FreeRegs = DefaultNumRegisterParameters;
+    State.FreeRegs = DefaultNumRegisterParameters;
 
-  // If the return value is indirect, then the hidden argument is consuming one
-  // integer register.
-  if (FI.getReturnInfo().isIndirect() && FreeRegs) {
-    --FreeRegs;
-    ABIArgInfo &Old = FI.getReturnInfo();
-    Old = ABIArgInfo::getIndirectInReg(Old.getIndirectAlign(),
-                                       Old.getIndirectByVal(),
-                                       Old.getIndirectRealign());
+  if (!getCXXABI().classifyReturnType(FI)) {
+    FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), State);
+  } else if (FI.getReturnInfo().isIndirect()) {
+    // The C++ ABI is not aware of register usage, so we have to check if the
+    // return value was sret and put it in a register ourselves if appropriate.
+    if (State.FreeRegs) {
+      --State.FreeRegs;  // The sret parameter consumes a register.
+      FI.getReturnInfo().setInReg(true);
+    }
   }
 
-  for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
-       it != ie; ++it)
-    it->info = classifyArgumentType(it->type, FreeRegs, IsFastCall);
+  bool UsedInAlloca = false;
+  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
+  // all the memory arguments to use inalloca.
+  if (UsedInAlloca)
+    rewriteWithInAlloca(FI);
+}
+
+void
+X86_32ABIInfo::addFieldToArgStruct(SmallVector<llvm::Type *, 6> &FrameFields,
+                                   unsigned &StackOffset,
+                                   ABIArgInfo &Info, QualType Type) const {
+  assert(StackOffset % 4U == 0 && "unaligned inalloca struct");
+  Info = ABIArgInfo::getInAlloca(FrameFields.size());
+  FrameFields.push_back(CGT.ConvertTypeForMem(Type));
+  StackOffset += getContext().getTypeSizeInChars(Type).getQuantity();
+
+  // Insert padding bytes to respect alignment.  For x86_32, each argument is 4
+  // byte aligned.
+  if (StackOffset % 4U) {
+    unsigned OldOffset = StackOffset;
+    StackOffset = llvm::RoundUpToAlignment(StackOffset, 4U);
+    unsigned NumBytes = StackOffset - OldOffset;
+    assert(NumBytes);
+    llvm::Type *Ty = llvm::Type::getInt8Ty(getVMContext());
+    Ty = llvm::ArrayType::get(Ty, NumBytes);
+    FrameFields.push_back(Ty);
+  }
+}
+
+void X86_32ABIInfo::rewriteWithInAlloca(CGFunctionInfo &FI) const {
+  assert(IsWin32StructABI && "inalloca only supported on win32");
+
+  // Build a packed struct type for all of the arguments in memory.
+  SmallVector<llvm::Type *, 6> FrameFields;
+
+  unsigned StackOffset = 0;
+
+  // Put the sret parameter into the inalloca struct if it's in memory.
+  ABIArgInfo &Ret = FI.getReturnInfo();
+  if (Ret.isIndirect() && !Ret.getInReg()) {
+    CanQualType PtrTy = getContext().getPointerType(FI.getReturnType());
+    addFieldToArgStruct(FrameFields, StackOffset, Ret, PtrTy);
+    // On Windows, the hidden sret parameter is always returned in eax.
+    Ret.setInAllocaSRet(IsWin32StructABI);
+  }
+
+  // Skip the 'this' parameter in ecx.
+  CGFunctionInfo::arg_iterator I = FI.arg_begin(), E = FI.arg_end();
+  if (FI.getCallingConvention() == llvm::CallingConv::X86_ThisCall)
+    ++I;
+
+  // Put arguments passed in memory into the struct.
+  for (; I != E; ++I) {
+
+    // Leave ignored and inreg arguments alone.
+    switch (I->info.getKind()) {
+    case ABIArgInfo::Indirect:
+      assert(I->info.getIndirectByVal());
+      break;
+    case ABIArgInfo::Ignore:
+      continue;
+    case ABIArgInfo::Direct:
+    case ABIArgInfo::Extend:
+      if (I->info.getInReg())
+        continue;
+      break;
+    default:
+      break;
+    }
+
+    addFieldToArgStruct(FrameFields, StackOffset, I->info, I->type);
+  }
+
+  FI.setArgStruct(llvm::StructType::get(getVMContext(), FrameFields,
+                                        /*isPacked=*/true));
 }
 
 llvm::Value *X86_32ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
@@ -1088,6 +1147,44 @@
   return AddrTyped;
 }
 
+bool X86_32TargetCodeGenInfo::isStructReturnInRegABI(
+    const llvm::Triple &Triple, const CodeGenOptions &Opts) {
+  assert(Triple.getArch() == llvm::Triple::x86);
+
+  switch (Opts.getStructReturnConvention()) {
+  case CodeGenOptions::SRCK_Default:
+    break;
+  case CodeGenOptions::SRCK_OnStack:  // -fpcc-struct-return
+    return false;
+  case CodeGenOptions::SRCK_InRegs:  // -freg-struct-return
+    return true;
+  }
+
+  if (Triple.isOSDarwin())
+    return true;
+
+  switch (Triple.getOS()) {
+  case llvm::Triple::AuroraUX:
+  case llvm::Triple::DragonFly:
+  case llvm::Triple::FreeBSD:
+  case llvm::Triple::OpenBSD:
+  case llvm::Triple::Bitrig:
+    return true;
+  case llvm::Triple::Win32:
+    switch (Triple.getEnvironment()) {
+    case llvm::Triple::UnknownEnvironment:
+    case llvm::Triple::Cygnus:
+    case llvm::Triple::GNU:
+    case llvm::Triple::MSVC:
+      return true;
+    default:
+      return false;
+    }
+  default:
+    return false;
+  }
+}
+
 void X86_32TargetCodeGenInfo::SetTargetAttributes(const Decl *D,
                                                   llvm::GlobalValue *GV,
                                             CodeGen::CodeGenModule &CGM) const {
@@ -1276,10 +1373,10 @@
     return false;
   }
 
-  virtual void computeInfo(CGFunctionInfo &FI) const;
+  void computeInfo(CGFunctionInfo &FI) const override;
 
-  virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
-                                 CodeGenFunction &CGF) const;
+  llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+                         CodeGenFunction &CGF) const override;
 };
 
 /// WinX86_64ABIInfo - The Windows X86_64 ABI information.
@@ -1290,10 +1387,10 @@
 public:
   WinX86_64ABIInfo(CodeGen::CodeGenTypes &CGT) : ABIInfo(CGT) {}
 
-  virtual void computeInfo(CGFunctionInfo &FI) const;
+  void computeInfo(CGFunctionInfo &FI) const override;
 
-  virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
-                                 CodeGenFunction &CGF) const;
+  llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+                         CodeGenFunction &CGF) const override;
 };
 
 class X86_64TargetCodeGenInfo : public TargetCodeGenInfo {
@@ -1305,12 +1402,12 @@
     return static_cast<const X86_64ABIInfo&>(TargetCodeGenInfo::getABIInfo());
   }
 
-  int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const {
+  int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const override {
     return 7;
   }
 
   bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
-                               llvm::Value *Address) const {
+                               llvm::Value *Address) const override {
     llvm::Value *Eight8 = llvm::ConstantInt::get(CGF.Int8Ty, 8);
 
     // 0-15 are the 16 integer registers.
@@ -1321,12 +1418,12 @@
 
   llvm::Type* adjustInlineAsmType(CodeGen::CodeGenFunction &CGF,
                                   StringRef Constraint,
-                                  llvm::Type* Ty) const {
+                                  llvm::Type* Ty) const override {
     return X86AdjustInlineAsmType(CGF, Constraint, Ty);
   }
 
   bool isNoProtoCallVariadic(const CallArgList &args,
-                             const FunctionNoProtoType *fnType) const {
+                             const FunctionNoProtoType *fnType) const override {
     // The default CC on x86-64 sets %al to the number of SSA
     // registers used, and GCC sets this when calling an unprototyped
     // function, so we override the default behavior.  However, don't do
@@ -1350,7 +1447,8 @@
     return TargetCodeGenInfo::isNoProtoCallVariadic(args, fnType);
   }
 
-  llvm::Constant *getUBSanFunctionSignature(CodeGen::CodeGenModule &CGM) const {
+  llvm::Constant *
+  getUBSanFunctionSignature(CodeGen::CodeGenModule &CGM) const override {
     unsigned Sig = (0xeb << 0) |  // jmp rel8
                    (0x0a << 8) |  //           .+0x0c
                    ('F' << 16) |
@@ -1376,14 +1474,14 @@
     : X86_32TargetCodeGenInfo(CGT, d, p, w, RegParms) {}
 
   void getDependentLibraryOption(llvm::StringRef Lib,
-                                 llvm::SmallString<24> &Opt) const {
+                                 llvm::SmallString<24> &Opt) const override {
     Opt = "/DEFAULTLIB:";
     Opt += qualifyWindowsLibrary(Lib);
   }
 
   void getDetectMismatchOption(llvm::StringRef Name,
                                llvm::StringRef Value,
-                               llvm::SmallString<32> &Opt) const {
+                               llvm::SmallString<32> &Opt) const override {
     Opt = "/FAILIFMISMATCH:\"" + Name.str() + "=" + Value.str() + "\"";
   }
 };
@@ -1393,12 +1491,12 @@
   WinX86_64TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT)
     : TargetCodeGenInfo(new WinX86_64ABIInfo(CGT)) {}
 
-  int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const {
+  int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const override {
     return 7;
   }
 
   bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
-                               llvm::Value *Address) const {
+                               llvm::Value *Address) const override {
     llvm::Value *Eight8 = llvm::ConstantInt::get(CGF.Int8Ty, 8);
 
     // 0-15 are the 16 integer registers.
@@ -1408,14 +1506,14 @@
   }
 
   void getDependentLibraryOption(llvm::StringRef Lib,
-                                 llvm::SmallString<24> &Opt) const {
+                                 llvm::SmallString<24> &Opt) const override {
     Opt = "/DEFAULTLIB:";
     Opt += qualifyWindowsLibrary(Lib);
   }
 
   void getDetectMismatchOption(llvm::StringRef Name,
                                llvm::StringRef Value,
-                               llvm::SmallString<32> &Opt) const {
+                               llvm::SmallString<32> &Opt) const override {
     Opt = "/FAILIFMISMATCH:\"" + Name.str() + "=" + Value.str() + "\"";
   }
 };
@@ -1545,10 +1643,25 @@
   }
 
   if (Ty->isMemberPointerType()) {
-    if (Ty->isMemberFunctionPointerType() && Has64BitPointers)
-      Lo = Hi = Integer;
-    else
+    if (Ty->isMemberFunctionPointerType()) {
+      if (Has64BitPointers) {
+        // If Has64BitPointers, this is an {i64, i64}, so classify both
+        // Lo and Hi now.
+        Lo = Hi = Integer;
+      } else {
+        // Otherwise, with 32-bit pointers, this is an {i32, i32}. If that
+        // straddles an eightbyte boundary, Hi should be classified as well.
+        uint64_t EB_FuncPtr = (OffsetBase) / 64;
+        uint64_t EB_ThisAdj = (OffsetBase + 64 - 1) / 64;
+        if (EB_FuncPtr != EB_ThisAdj) {
+          Lo = Hi = Integer;
+        } else {
+          Current = Integer;
+        }
+      }
+    } else {
       Current = Integer;
+    }
     return;
   }
 
@@ -1699,12 +1812,11 @@
 
     // If this is a C++ record, classify the bases first.
     if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
-      for (CXXRecordDecl::base_class_const_iterator i = CXXRD->bases_begin(),
-             e = CXXRD->bases_end(); i != e; ++i) {
-        assert(!i->isVirtual() && !i->getType()->isDependentType() &&
+      for (const auto &I : CXXRD->bases()) {
+        assert(!I.isVirtual() && !I.getType()->isDependentType() &&
                "Unexpected base class!");
         const CXXRecordDecl *Base =
-          cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
+          cast<CXXRecordDecl>(I.getType()->getAs<RecordType>()->getDecl());
 
         // Classify this field.
         //
@@ -1714,7 +1826,7 @@
         Class FieldLo, FieldHi;
         uint64_t Offset =
           OffsetBase + getContext().toBits(Layout.getBaseClassOffset(Base));
-        classify(i->getType(), Offset, FieldLo, FieldHi, isNamedArg);
+        classify(I.getType(), Offset, FieldLo, FieldHi, isNamedArg);
         Lo = merge(Lo, FieldLo);
         Hi = merge(Hi, FieldHi);
         if (Lo == Memory || Hi == Memory)
@@ -1944,19 +2056,18 @@
 
     // If this is a C++ record, check the bases first.
     if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
-      for (CXXRecordDecl::base_class_const_iterator i = CXXRD->bases_begin(),
-           e = CXXRD->bases_end(); i != e; ++i) {
-        assert(!i->isVirtual() && !i->getType()->isDependentType() &&
+      for (const auto &I : CXXRD->bases()) {
+        assert(!I.isVirtual() && !I.getType()->isDependentType() &&
                "Unexpected base class!");
         const CXXRecordDecl *Base =
-          cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
+          cast<CXXRecordDecl>(I.getType()->getAs<RecordType>()->getDecl());
 
         // If the base is after the span we care about, ignore it.
         unsigned BaseOffset = Context.toBits(Layout.getBaseClassOffset(Base));
         if (BaseOffset >= EndBit) continue;
 
         unsigned BaseStart = BaseOffset < StartBit ? StartBit-BaseOffset :0;
-        if (!BitsContainNoUserData(i->getType(), BaseStart,
+        if (!BitsContainNoUserData(I.getType(), BaseStart,
                                    EndBit-BaseOffset, Context))
           return false;
       }
@@ -2052,7 +2163,7 @@
 /// the source type.  IROffset is an offset in bytes into the LLVM IR type that
 /// the 8-byte value references.  PrefType may be null.
 ///
-/// SourceTy is the source level type for the entire argument.  SourceOffset is
+/// SourceTy is the source-level type for the entire argument.  SourceOffset is
 /// an offset into this that we're processing (which is always either 0 or 8).
 ///
 llvm::Type *X86_64ABIInfo::
@@ -2171,7 +2282,7 @@
   assert((Hi != Memory || Lo == Memory) && "Invalid memory classification.");
   assert((Hi != SSEUp || Lo == SSE) && "Invalid SSEUp classification.");
 
-  llvm::Type *ResType = 0;
+  llvm::Type *ResType = nullptr;
   switch (Lo) {
   case NoClass:
     if (Hi == NoClass)
@@ -2232,7 +2343,7 @@
     break;
   }
 
-  llvm::Type *HighPart = 0;
+  llvm::Type *HighPart = nullptr;
   switch (Hi) {
     // Memory was handled previously and X87 should
     // never occur as a hi class.
@@ -2304,7 +2415,7 @@
 
   neededInt = 0;
   neededSSE = 0;
-  llvm::Type *ResType = 0;
+  llvm::Type *ResType = nullptr;
   switch (Lo) {
   case NoClass:
     if (Hi == NoClass)
@@ -2365,7 +2476,7 @@
   }
   }
 
-  llvm::Type *HighPart = 0;
+  llvm::Type *HighPart = nullptr;
   switch (Hi) {
     // Memory was handled previously, ComplexX87 and X87 should
     // never occur as hi classes, and X87Up must be preceded by X87,
@@ -2418,7 +2529,8 @@
 
 void X86_64ABIInfo::computeInfo(CGFunctionInfo &FI) const {
 
-  FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
+  if (!getCXXABI().classifyReturnType(FI))
+    FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
 
   // Keep track of the number of assigned registers.
   unsigned freeIntRegs = 6, freeSSERegs = 8;
@@ -2539,9 +2651,9 @@
   // NOTE: 304 is a typo, there are (6 * 8 + 8 * 16) = 176 bytes of
   // register save space).
 
-  llvm::Value *InRegs = 0;
-  llvm::Value *gp_offset_p = 0, *gp_offset = 0;
-  llvm::Value *fp_offset_p = 0, *fp_offset = 0;
+  llvm::Value *InRegs = nullptr;
+  llvm::Value *gp_offset_p = nullptr, *gp_offset = nullptr;
+  llvm::Value *fp_offset_p = nullptr, *fp_offset = nullptr;
   if (neededInt) {
     gp_offset_p = CGF.Builder.CreateStructGEP(VAListAddr, 0, "gp_offset_p");
     gp_offset = CGF.Builder.CreateLoad(gp_offset_p, "gp_offset");
@@ -2596,8 +2708,8 @@
     llvm::Type *PTyHi = llvm::PointerType::getUnqual(TyHi);
     llvm::Value *GPAddr = CGF.Builder.CreateGEP(RegAddr, gp_offset);
     llvm::Value *FPAddr = CGF.Builder.CreateGEP(RegAddr, fp_offset);
-    llvm::Value *RegLoAddr = TyLo->isFloatingPointTy() ? FPAddr : GPAddr;
-    llvm::Value *RegHiAddr = TyLo->isFloatingPointTy() ? GPAddr : FPAddr;
+    llvm::Value *RegLoAddr = TyLo->isFPOrFPVectorTy() ? FPAddr : GPAddr;
+    llvm::Value *RegHiAddr = TyLo->isFPOrFPVectorTy() ? GPAddr : FPAddr;
     llvm::Value *V =
       CGF.Builder.CreateLoad(CGF.Builder.CreateBitCast(RegLoAddr, PTyLo));
     CGF.Builder.CreateStore(V, CGF.Builder.CreateStructGEP(Tmp, 0));
@@ -2687,11 +2799,9 @@
 
   uint64_t Size = getContext().getTypeSize(Ty);
 
-  if (const RecordType *RT = Ty->getAs<RecordType>()) {
-    if (IsReturnType) {
-      if (isRecordReturnIndirect(RT, getCXXABI()))
-        return ABIArgInfo::getIndirect(0, false);
-    } else {
+  const RecordType *RT = Ty->getAs<RecordType>();
+  if (RT) {
+    if (!IsReturnType) {
       if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(RT, getCXXABI()))
         return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory);
     }
@@ -2700,18 +2810,27 @@
       return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
 
     // FIXME: mingw-w64-gcc emits 128-bit struct as i128
-    if (Size == 128 && getTarget().getTriple().getOS() == llvm::Triple::MinGW32)
+    if (Size == 128 && getTarget().getTriple().isWindowsGNUEnvironment())
       return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(),
                                                           Size));
+  }
 
+  if (Ty->isMemberPointerType()) {
+    // If the member pointer is represented by an LLVM int or ptr, pass it
+    // directly.
+    llvm::Type *LLTy = CGT.ConvertType(Ty);
+    if (LLTy->isPointerTy() || LLTy->isIntegerTy())
+      return ABIArgInfo::getDirect();
+  }
+
+  if (RT || Ty->isMemberPointerType()) {
     // MS x64 ABI requirement: "Any argument that doesn't fit in 8 bytes, or is
     // not 1, 2, 4, or 8 bytes, must be passed by reference."
-    if (Size <= 64 &&
-        (Size & (Size - 1)) == 0)
-      return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(),
-                                                          Size));
+    if (Size > 64 || !llvm::isPowerOf2_64(Size))
+      return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
 
-    return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
+    // Otherwise, coerce it to a small integer.
+    return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(), Size));
   }
 
   if (Ty->isPromotableIntegerType())
@@ -2721,13 +2840,11 @@
 }
 
 void WinX86_64ABIInfo::computeInfo(CGFunctionInfo &FI) const {
+  if (!getCXXABI().classifyReturnType(FI))
+    FI.getReturnInfo() = classify(FI.getReturnType(), true);
 
-  QualType RetTy = FI.getReturnType();
-  FI.getReturnInfo() = classify(RetTy, true);
-
-  for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
-       it != ie; ++it)
-    it->info = classify(it->type, false);
+  for (auto &I : FI.arguments())
+    I.info = classify(I.type, false);
 }
 
 llvm::Value *WinX86_64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
@@ -2758,9 +2875,9 @@
  public:
   NaClX86_64ABIInfo(CodeGen::CodeGenTypes &CGT, bool HasAVX)
       : ABIInfo(CGT), PInfo(CGT), NInfo(CGT, HasAVX) {}
-  virtual void computeInfo(CGFunctionInfo &FI) const;
-  virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
-                                 CodeGenFunction &CGF) const;
+  void computeInfo(CGFunctionInfo &FI) const override;
+  llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+                         CodeGenFunction &CGF) const override;
  private:
   PNaClABIInfo PInfo;  // Used for generating calls with pnaclcall callingconv.
   X86_64ABIInfo NInfo; // Used for everything else.
@@ -2796,13 +2913,13 @@
 public:
   PPC32TargetCodeGenInfo(CodeGenTypes &CGT) : DefaultTargetCodeGenInfo(CGT) {}
 
-  int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const {
+  int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override {
     // This is recovered from gcc output.
     return 1; // r1 is the dedicated stack pointer
   }
 
   bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
-                               llvm::Value *Address) const;
+                               llvm::Value *Address) const override;
 };
 
 }
@@ -2853,11 +2970,24 @@
 namespace {
 /// PPC64_SVR4_ABIInfo - The 64-bit PowerPC ELF (SVR4) ABI information.
 class PPC64_SVR4_ABIInfo : public DefaultABIInfo {
+public:
+  enum ABIKind {
+    ELFv1 = 0,
+    ELFv2
+  };
+
+private:
+  static const unsigned GPRBits = 64;
+  ABIKind Kind;
 
 public:
-  PPC64_SVR4_ABIInfo(CodeGen::CodeGenTypes &CGT) : DefaultABIInfo(CGT) {}
+  PPC64_SVR4_ABIInfo(CodeGen::CodeGenTypes &CGT, ABIKind Kind)
+    : DefaultABIInfo(CGT), Kind(Kind) {}
 
   bool isPromotableTypeForABI(QualType Ty) const;
+  bool isAlignedParamType(QualType Ty) const;
+  bool isHomogeneousAggregate(QualType Ty, const Type *&Base,
+                              uint64_t &Members) const;
 
   ABIArgInfo classifyReturnType(QualType RetTy) const;
   ABIArgInfo classifyArgumentType(QualType Ty) const;
@@ -2868,56 +2998,57 @@
   // floating-point value) to avoid pushing them to memory on function
   // entry.  This would require changing the logic in PPCISelLowering
   // when lowering the parameters in the caller and args in the callee.
-  virtual void computeInfo(CGFunctionInfo &FI) const {
-    FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
-    for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
-         it != ie; ++it) {
+  void computeInfo(CGFunctionInfo &FI) const override {
+    if (!getCXXABI().classifyReturnType(FI))
+      FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
+    for (auto &I : FI.arguments()) {
       // We rely on the default argument classification for the most part.
       // One exception:  An aggregate containing a single floating-point
       // or vector item must be passed in a register if one is available.
-      const Type *T = isSingleElementStruct(it->type, getContext());
+      const Type *T = isSingleElementStruct(I.type, getContext());
       if (T) {
         const BuiltinType *BT = T->getAs<BuiltinType>();
-        if (T->isVectorType() || (BT && BT->isFloatingPoint())) {
+        if ((T->isVectorType() && getContext().getTypeSize(T) == 128) ||
+            (BT && BT->isFloatingPoint())) {
           QualType QT(T, 0);
-          it->info = ABIArgInfo::getDirectInReg(CGT.ConvertType(QT));
+          I.info = ABIArgInfo::getDirectInReg(CGT.ConvertType(QT));
           continue;
         }
       }
-      it->info = classifyArgumentType(it->type);
+      I.info = classifyArgumentType(I.type);
     }
   }
 
-  virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, 
-                                 QualType Ty,
-                                 CodeGenFunction &CGF) const;
+  llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+                         CodeGenFunction &CGF) const override;
 };
 
 class PPC64_SVR4_TargetCodeGenInfo : public TargetCodeGenInfo {
 public:
-  PPC64_SVR4_TargetCodeGenInfo(CodeGenTypes &CGT)
-    : TargetCodeGenInfo(new PPC64_SVR4_ABIInfo(CGT)) {}
+  PPC64_SVR4_TargetCodeGenInfo(CodeGenTypes &CGT,
+                               PPC64_SVR4_ABIInfo::ABIKind Kind)
+    : TargetCodeGenInfo(new PPC64_SVR4_ABIInfo(CGT, Kind)) {}
 
-  int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const {
+  int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override {
     // This is recovered from gcc output.
     return 1; // r1 is the dedicated stack pointer
   }
 
   bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
-                               llvm::Value *Address) const;
+                               llvm::Value *Address) const override;
 };
 
 class PPC64TargetCodeGenInfo : public DefaultTargetCodeGenInfo {
 public:
   PPC64TargetCodeGenInfo(CodeGenTypes &CGT) : DefaultTargetCodeGenInfo(CGT) {}
 
-  int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const {
+  int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override {
     // This is recovered from gcc output.
     return 1; // r1 is the dedicated stack pointer
   }
 
   bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
-                               llvm::Value *Address) const;
+                               llvm::Value *Address) const override;
 };
 
 }
@@ -2948,16 +3079,205 @@
   return false;
 }
 
+/// isAlignedParamType - Determine whether a type requires 16-byte
+/// alignment in the parameter area.
+bool
+PPC64_SVR4_ABIInfo::isAlignedParamType(QualType Ty) const {
+  // Complex types are passed just like their elements.
+  if (const ComplexType *CTy = Ty->getAs<ComplexType>())
+    Ty = CTy->getElementType();
+
+  // Only vector types of size 16 bytes need alignment (larger types are
+  // passed via reference, smaller types are not aligned).
+  if (Ty->isVectorType())
+    return getContext().getTypeSize(Ty) == 128;
+
+  // For single-element float/vector structs, we consider the whole type
+  // to have the same alignment requirements as its single element.
+  const Type *AlignAsType = nullptr;
+  const Type *EltType = isSingleElementStruct(Ty, getContext());
+  if (EltType) {
+    const BuiltinType *BT = EltType->getAs<BuiltinType>();
+    if ((EltType->isVectorType() &&
+         getContext().getTypeSize(EltType) == 128) ||
+        (BT && BT->isFloatingPoint()))
+      AlignAsType = EltType;
+  }
+
+  // Likewise for ELFv2 homogeneous aggregates.
+  const Type *Base = nullptr;
+  uint64_t Members = 0;
+  if (!AlignAsType && Kind == ELFv2 &&
+      isAggregateTypeForABI(Ty) && isHomogeneousAggregate(Ty, Base, Members))
+    AlignAsType = Base;
+
+  // With special case aggregates, only vector base types need alignment.
+  if (AlignAsType)
+    return AlignAsType->isVectorType();
+
+  // Otherwise, we only need alignment for any aggregate type that
+  // has an alignment requirement of >= 16 bytes.
+  if (isAggregateTypeForABI(Ty) && getContext().getTypeAlign(Ty) >= 128)
+    return true;
+
+  return false;
+}
+
+/// isHomogeneousAggregate - Return true if a type is an ELFv2 homogeneous
+/// aggregate.  Base is set to the base element type, and Members is set
+/// to the number of base elements.
+bool
+PPC64_SVR4_ABIInfo::isHomogeneousAggregate(QualType Ty, const Type *&Base,
+                                           uint64_t &Members) const {
+  if (const ConstantArrayType *AT = getContext().getAsConstantArrayType(Ty)) {
+    uint64_t NElements = AT->getSize().getZExtValue();
+    if (NElements == 0)
+      return false;
+    if (!isHomogeneousAggregate(AT->getElementType(), Base, Members))
+      return false;
+    Members *= NElements;
+  } else if (const RecordType *RT = Ty->getAs<RecordType>()) {
+    const RecordDecl *RD = RT->getDecl();
+    if (RD->hasFlexibleArrayMember())
+      return false;
+
+    Members = 0;
+    for (const auto *FD : RD->fields()) {
+      // Ignore (non-zero arrays of) empty records.
+      QualType FT = FD->getType();
+      while (const ConstantArrayType *AT =
+             getContext().getAsConstantArrayType(FT)) {
+        if (AT->getSize().getZExtValue() == 0)
+          return false;
+        FT = AT->getElementType();
+      }
+      if (isEmptyRecord(getContext(), FT, true))
+        continue;
+
+      // For compatibility with GCC, ignore empty bitfields in C++ mode.
+      if (getContext().getLangOpts().CPlusPlus &&
+          FD->isBitField() && FD->getBitWidthValue(getContext()) == 0)
+        continue;
+
+      uint64_t FldMembers;
+      if (!isHomogeneousAggregate(FD->getType(), Base, FldMembers))
+        return false;
+
+      Members = (RD->isUnion() ?
+                 std::max(Members, FldMembers) : Members + FldMembers);
+    }
+
+    if (!Base)
+      return false;
+
+    // Ensure there is no padding.
+    if (getContext().getTypeSize(Base) * Members !=
+        getContext().getTypeSize(Ty))
+      return false;
+  } else {
+    Members = 1;
+    if (const ComplexType *CT = Ty->getAs<ComplexType>()) {
+      Members = 2;
+      Ty = CT->getElementType();
+    }
+
+    // Homogeneous aggregates for ELFv2 must have base types of float,
+    // double, long double, or 128-bit vectors.
+    if (const BuiltinType *BT = Ty->getAs<BuiltinType>()) {
+      if (BT->getKind() != BuiltinType::Float &&
+          BT->getKind() != BuiltinType::Double &&
+          BT->getKind() != BuiltinType::LongDouble)
+        return false;
+    } else if (const VectorType *VT = Ty->getAs<VectorType>()) {
+      if (getContext().getTypeSize(VT) != 128)
+        return false;
+    } else {
+      return false;
+    }
+
+    // The base type must be the same for all members.  Types that
+    // agree in both total size and mode (float vs. vector) are
+    // treated as being equivalent here.
+    const Type *TyPtr = Ty.getTypePtr();
+    if (!Base)
+      Base = TyPtr;
+
+    if (Base->isVectorType() != TyPtr->isVectorType() ||
+        getContext().getTypeSize(Base) != getContext().getTypeSize(TyPtr))
+      return false;
+  }
+
+  // Vector types require one register, floating point types require one
+  // or two registers depending on their size.
+  uint32_t NumRegs = Base->isVectorType() ? 1 :
+                       (getContext().getTypeSize(Base) + 63) / 64;
+
+  // Homogeneous Aggregates may occupy at most 8 registers.
+  return (Members > 0 && Members * NumRegs <= 8);
+}
+
 ABIArgInfo
 PPC64_SVR4_ABIInfo::classifyArgumentType(QualType Ty) const {
   if (Ty->isAnyComplexType())
     return ABIArgInfo::getDirect();
 
+  // Non-Altivec vector types are passed in GPRs (smaller than 16 bytes)
+  // or via reference (larger than 16 bytes).
+  if (Ty->isVectorType()) {
+    uint64_t Size = getContext().getTypeSize(Ty);
+    if (Size > 128)
+      return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
+    else if (Size < 128) {
+      llvm::Type *CoerceTy = llvm::IntegerType::get(getVMContext(), Size);
+      return ABIArgInfo::getDirect(CoerceTy);
+    }
+  }
+
   if (isAggregateTypeForABI(Ty)) {
     if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI()))
       return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory);
 
-    return ABIArgInfo::getIndirect(0);
+    uint64_t ABIAlign = isAlignedParamType(Ty)? 16 : 8;
+    uint64_t TyAlign = getContext().getTypeAlign(Ty) / 8;
+
+    // ELFv2 homogeneous aggregates are passed as array types.
+    const Type *Base = nullptr;
+    uint64_t Members = 0;
+    if (Kind == ELFv2 &&
+        isHomogeneousAggregate(Ty, Base, Members)) {
+      llvm::Type *BaseTy = CGT.ConvertType(QualType(Base, 0));
+      llvm::Type *CoerceTy = llvm::ArrayType::get(BaseTy, Members);
+      return ABIArgInfo::getDirect(CoerceTy);
+    }
+
+    // If an aggregate may end up fully in registers, we do not
+    // use the ByVal method, but pass the aggregate as array.
+    // This is usually beneficial since we avoid forcing the
+    // back-end to store the argument to memory.
+    uint64_t Bits = getContext().getTypeSize(Ty);
+    if (Bits > 0 && Bits <= 8 * GPRBits) {
+      llvm::Type *CoerceTy;
+
+      // Types up to 8 bytes are passed as integer type (which will be
+      // properly aligned in the argument save area doubleword).
+      if (Bits <= GPRBits)
+        CoerceTy = llvm::IntegerType::get(getVMContext(),
+                                          llvm::RoundUpToAlignment(Bits, 8));
+      // Larger types are passed as arrays, with the base type selected
+      // according to the required alignment in the save area.
+      else {
+        uint64_t RegBits = ABIAlign * 8;
+        uint64_t NumRegs = llvm::RoundUpToAlignment(Bits, RegBits) / RegBits;
+        llvm::Type *RegTy = llvm::IntegerType::get(getVMContext(), RegBits);
+        CoerceTy = llvm::ArrayType::get(RegTy, NumRegs);
+      }
+
+      return ABIArgInfo::getDirect(CoerceTy);
+    }
+
+    // All other aggregates are passed ByVal.
+    return ABIArgInfo::getIndirect(ABIAlign, /*ByVal=*/true,
+                                   /*Realign=*/TyAlign > ABIAlign);
   }
 
   return (isPromotableTypeForABI(Ty) ?
@@ -2972,8 +3292,48 @@
   if (RetTy->isAnyComplexType())
     return ABIArgInfo::getDirect();
 
-  if (isAggregateTypeForABI(RetTy))
+  // Non-Altivec vector types are returned in GPRs (smaller than 16 bytes)
+  // or via reference (larger than 16 bytes).
+  if (RetTy->isVectorType()) {
+    uint64_t Size = getContext().getTypeSize(RetTy);
+    if (Size > 128)
+      return ABIArgInfo::getIndirect(0);
+    else if (Size < 128) {
+      llvm::Type *CoerceTy = llvm::IntegerType::get(getVMContext(), Size);
+      return ABIArgInfo::getDirect(CoerceTy);
+    }
+  }
+
+  if (isAggregateTypeForABI(RetTy)) {
+    // ELFv2 homogeneous aggregates are returned as array types.
+    const Type *Base = nullptr;
+    uint64_t Members = 0;
+    if (Kind == ELFv2 &&
+        isHomogeneousAggregate(RetTy, Base, Members)) {
+      llvm::Type *BaseTy = CGT.ConvertType(QualType(Base, 0));
+      llvm::Type *CoerceTy = llvm::ArrayType::get(BaseTy, Members);
+      return ABIArgInfo::getDirect(CoerceTy);
+    }
+
+    // ELFv2 small aggregates are returned in up to two registers.
+    uint64_t Bits = getContext().getTypeSize(RetTy);
+    if (Kind == ELFv2 && Bits <= 2 * GPRBits) {
+      if (Bits == 0)
+        return ABIArgInfo::getIgnore();
+
+      llvm::Type *CoerceTy;
+      if (Bits > GPRBits) {
+        CoerceTy = llvm::IntegerType::get(getVMContext(), GPRBits);
+        CoerceTy = llvm::StructType::get(CoerceTy, CoerceTy, NULL);
+      } else
+        CoerceTy = llvm::IntegerType::get(getVMContext(),
+                                          llvm::RoundUpToAlignment(Bits, 8));
+      return ABIArgInfo::getDirect(CoerceTy);
+    }
+
+    // All other aggregates are returned indirectly.
     return ABIArgInfo::getIndirect(0);
+  }
 
   return (isPromotableTypeForABI(RetTy) ?
           ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
@@ -2990,6 +3350,14 @@
   llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, BPP, "ap");
   llvm::Value *Addr = Builder.CreateLoad(VAListAddrAsBPP, "ap.cur");
 
+  // Handle types that require 16-byte alignment in the parameter save area.
+  if (isAlignedParamType(Ty)) {
+    llvm::Value *AddrAsInt = Builder.CreatePtrToInt(Addr, CGF.Int64Ty);
+    AddrAsInt = Builder.CreateAdd(AddrAsInt, Builder.getInt64(15));
+    AddrAsInt = Builder.CreateAnd(AddrAsInt, Builder.getInt64(-16));
+    Addr = Builder.CreateIntToPtr(AddrAsInt, BP, "ap.align");
+  }
+
   // Update the va_list pointer.  The pointer should be bumped by the
   // size of the object.  We can trust getTypeSize() except for a complex
   // type whose base type is smaller than a doubleword.  For these, the
@@ -3020,8 +3388,12 @@
   if (CplxBaseSize && CplxBaseSize < 8) {
     llvm::Value *RealAddr = Builder.CreatePtrToInt(Addr, CGF.Int64Ty);
     llvm::Value *ImagAddr = RealAddr;
-    RealAddr = Builder.CreateAdd(RealAddr, Builder.getInt64(8 - CplxBaseSize));
-    ImagAddr = Builder.CreateAdd(ImagAddr, Builder.getInt64(16 - CplxBaseSize));
+    if (CGF.CGM.getDataLayout().isBigEndian()) {
+      RealAddr = Builder.CreateAdd(RealAddr, Builder.getInt64(8 - CplxBaseSize));
+      ImagAddr = Builder.CreateAdd(ImagAddr, Builder.getInt64(16 - CplxBaseSize));
+    } else {
+      ImagAddr = Builder.CreateAdd(ImagAddr, Builder.getInt64(8));
+    }
     llvm::Type *PBaseTy = llvm::PointerType::getUnqual(CGF.ConvertType(BaseTy));
     RealAddr = Builder.CreateIntToPtr(RealAddr, PBaseTy);
     ImagAddr = Builder.CreateIntToPtr(ImagAddr, PBaseTy);
@@ -3039,7 +3411,7 @@
   // If the argument is smaller than 8 bytes, it is right-adjusted in
   // its doubleword slot.  Adjust the pointer to pick it up from the
   // correct offset.
-  if (SizeInBytes < 8) {
+  if (SizeInBytes < 8 && CGF.CGM.getDataLayout().isBigEndian()) {
     llvm::Value *AddrAsInt = Builder.CreatePtrToInt(Addr, CGF.Int64Ty);
     AddrAsInt = Builder.CreateAdd(AddrAsInt, Builder.getInt64(8 - SizeInBytes));
     Addr = Builder.CreateIntToPtr(AddrAsInt, BP);
@@ -3106,6 +3478,598 @@
 }
 
 //===----------------------------------------------------------------------===//
+// AArch64 ABI Implementation
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+class AArch64ABIInfo : public ABIInfo {
+public:
+  enum ABIKind {
+    AAPCS = 0,
+    DarwinPCS
+  };
+
+private:
+  ABIKind Kind;
+
+public:
+  AArch64ABIInfo(CodeGenTypes &CGT, ABIKind Kind) : ABIInfo(CGT), Kind(Kind) {}
+
+private:
+  ABIKind getABIKind() const { return Kind; }
+  bool isDarwinPCS() const { return Kind == DarwinPCS; }
+
+  ABIArgInfo classifyReturnType(QualType RetTy) const;
+  ABIArgInfo classifyArgumentType(QualType RetTy, unsigned &AllocatedVFP,
+                                  bool &IsHA, unsigned &AllocatedGPR,
+                                  bool &IsSmallAggr, bool IsNamedArg) const;
+  bool isIllegalVectorType(QualType Ty) const;
+
+  virtual void computeInfo(CGFunctionInfo &FI) const {
+    // To correctly handle Homogeneous Aggregate, we need to keep track of the
+    // number of SIMD and Floating-point registers allocated so far.
+    // If the argument is an HFA or an HVA and there are sufficient unallocated
+    // SIMD and Floating-point registers, then the argument is allocated to SIMD
+    // and Floating-point Registers (with one register per member of the HFA or
+    // HVA). Otherwise, the NSRN is set to 8.
+    unsigned AllocatedVFP = 0;
+
+    // To correctly handle small aggregates, we need to keep track of the number
+    // of GPRs allocated so far. If the small aggregate can't all fit into
+    // registers, it will be on stack. We don't allow the aggregate to be
+    // partially in registers.
+    unsigned AllocatedGPR = 0;
+
+    // Find the number of named arguments. Variadic arguments get special
+    // treatment with the Darwin ABI.
+    unsigned NumRequiredArgs = (FI.isVariadic() ?
+                                FI.getRequiredArgs().getNumRequiredArgs() :
+                                FI.arg_size());
+
+    if (!getCXXABI().classifyReturnType(FI))
+      FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
+    for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
+         it != ie; ++it) {
+      unsigned PreAllocation = AllocatedVFP, PreGPR = AllocatedGPR;
+      bool IsHA = false, IsSmallAggr = false;
+      const unsigned NumVFPs = 8;
+      const unsigned NumGPRs = 8;
+      bool IsNamedArg = ((it - FI.arg_begin()) <
+                         static_cast<signed>(NumRequiredArgs));
+      it->info = classifyArgumentType(it->type, AllocatedVFP, IsHA,
+                                      AllocatedGPR, IsSmallAggr, IsNamedArg);
+
+      // Under AAPCS the 64-bit stack slot alignment means we can't pass HAs
+      // as sequences of floats since they'll get "holes" inserted as
+      // padding by the back end.
+      if (IsHA && AllocatedVFP > NumVFPs && !isDarwinPCS() &&
+          getContext().getTypeAlign(it->type) < 64) {
+        uint32_t NumStackSlots = getContext().getTypeSize(it->type);
+        NumStackSlots = llvm::RoundUpToAlignment(NumStackSlots, 64) / 64;
+
+        llvm::Type *CoerceTy = llvm::ArrayType::get(
+            llvm::Type::getDoubleTy(getVMContext()), NumStackSlots);
+        it->info = ABIArgInfo::getDirect(CoerceTy);
+      }
+
+      // If we do not have enough VFP registers for the HA, any VFP registers
+      // that are unallocated are marked as unavailable. To achieve this, we add
+      // padding of (NumVFPs - PreAllocation) floats.
+      if (IsHA && AllocatedVFP > NumVFPs && PreAllocation < NumVFPs) {
+        llvm::Type *PaddingTy = llvm::ArrayType::get(
+            llvm::Type::getFloatTy(getVMContext()), NumVFPs - PreAllocation);
+        it->info.setPaddingType(PaddingTy);
+      }
+
+      // If we do not have enough GPRs for the small aggregate, any GPR regs
+      // that are unallocated are marked as unavailable.
+      if (IsSmallAggr && AllocatedGPR > NumGPRs && PreGPR < NumGPRs) {
+        llvm::Type *PaddingTy = llvm::ArrayType::get(
+            llvm::Type::getInt32Ty(getVMContext()), NumGPRs - PreGPR);
+        it->info =
+            ABIArgInfo::getDirect(it->info.getCoerceToType(), 0, PaddingTy);
+      }
+    }
+  }
+
+  llvm::Value *EmitDarwinVAArg(llvm::Value *VAListAddr, QualType Ty,
+                               CodeGenFunction &CGF) const;
+
+  llvm::Value *EmitAAPCSVAArg(llvm::Value *VAListAddr, QualType Ty,
+                              CodeGenFunction &CGF) const;
+
+  virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+                                 CodeGenFunction &CGF) const {
+    return isDarwinPCS() ? EmitDarwinVAArg(VAListAddr, Ty, CGF)
+                         : EmitAAPCSVAArg(VAListAddr, Ty, CGF);
+  }
+};
+
+class AArch64TargetCodeGenInfo : public TargetCodeGenInfo {
+public:
+  AArch64TargetCodeGenInfo(CodeGenTypes &CGT, AArch64ABIInfo::ABIKind Kind)
+      : TargetCodeGenInfo(new AArch64ABIInfo(CGT, Kind)) {}
+
+  StringRef getARCRetainAutoreleasedReturnValueMarker() const {
+    return "mov\tfp, fp\t\t; marker for objc_retainAutoreleaseReturnValue";
+  }
+
+  int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const { return 31; }
+
+  virtual bool doesReturnSlotInterfereWithArgs() const { return false; }
+};
+}
+
+static bool isHomogeneousAggregate(QualType Ty, const Type *&Base,
+                                   ASTContext &Context,
+                                   uint64_t *HAMembers = nullptr);
+
+ABIArgInfo AArch64ABIInfo::classifyArgumentType(QualType Ty,
+                                                unsigned &AllocatedVFP,
+                                                bool &IsHA,
+                                                unsigned &AllocatedGPR,
+                                                bool &IsSmallAggr,
+                                                bool IsNamedArg) const {
+  // Handle illegal vector types here.
+  if (isIllegalVectorType(Ty)) {
+    uint64_t Size = getContext().getTypeSize(Ty);
+    if (Size <= 32) {
+      llvm::Type *ResType = llvm::Type::getInt32Ty(getVMContext());
+      AllocatedGPR++;
+      return ABIArgInfo::getDirect(ResType);
+    }
+    if (Size == 64) {
+      llvm::Type *ResType =
+          llvm::VectorType::get(llvm::Type::getInt32Ty(getVMContext()), 2);
+      AllocatedVFP++;
+      return ABIArgInfo::getDirect(ResType);
+    }
+    if (Size == 128) {
+      llvm::Type *ResType =
+          llvm::VectorType::get(llvm::Type::getInt32Ty(getVMContext()), 4);
+      AllocatedVFP++;
+      return ABIArgInfo::getDirect(ResType);
+    }
+    AllocatedGPR++;
+    return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
+  }
+  if (Ty->isVectorType())
+    // Size of a legal vector should be either 64 or 128.
+    AllocatedVFP++;
+  if (const BuiltinType *BT = Ty->getAs<BuiltinType>()) {
+    if (BT->getKind() == BuiltinType::Half ||
+        BT->getKind() == BuiltinType::Float ||
+        BT->getKind() == BuiltinType::Double ||
+        BT->getKind() == BuiltinType::LongDouble)
+      AllocatedVFP++;
+  }
+
+  if (!isAggregateTypeForABI(Ty)) {
+    // Treat an enum type as its underlying type.
+    if (const EnumType *EnumTy = Ty->getAs<EnumType>())
+      Ty = EnumTy->getDecl()->getIntegerType();
+
+    if (!Ty->isFloatingType() && !Ty->isVectorType()) {
+      unsigned Alignment = getContext().getTypeAlign(Ty);
+      if (!isDarwinPCS() && Alignment > 64)
+        AllocatedGPR = llvm::RoundUpToAlignment(AllocatedGPR, Alignment / 64);
+
+      int RegsNeeded = getContext().getTypeSize(Ty) > 64 ? 2 : 1;
+      AllocatedGPR += RegsNeeded;
+    }
+    return (Ty->isPromotableIntegerType() && isDarwinPCS()
+                ? ABIArgInfo::getExtend()
+                : ABIArgInfo::getDirect());
+  }
+
+  // Structures with either a non-trivial destructor or a non-trivial
+  // copy constructor are always indirect.
+  if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) {
+    AllocatedGPR++;
+    return ABIArgInfo::getIndirect(0, /*ByVal=*/RAA ==
+                                          CGCXXABI::RAA_DirectInMemory);
+  }
+
+  // Empty records are always ignored on Darwin, but actually passed in C++ mode
+  // elsewhere for GNU compatibility.
+  if (isEmptyRecord(getContext(), Ty, true)) {
+    if (!getContext().getLangOpts().CPlusPlus || isDarwinPCS())
+      return ABIArgInfo::getIgnore();
+
+    ++AllocatedGPR;
+    return ABIArgInfo::getDirect(llvm::Type::getInt8Ty(getVMContext()));
+  }
+
+  // Homogeneous Floating-point Aggregates (HFAs) need to be expanded.
+  const Type *Base = nullptr;
+  uint64_t Members = 0;
+  if (isHomogeneousAggregate(Ty, Base, getContext(), &Members)) {
+    IsHA = true;
+    if (!IsNamedArg && isDarwinPCS()) {
+      // With the Darwin ABI, variadic arguments are always passed on the stack
+      // and should not be expanded. Treat variadic HFAs as arrays of doubles.
+      uint64_t Size = getContext().getTypeSize(Ty);
+      llvm::Type *BaseTy = llvm::Type::getDoubleTy(getVMContext());
+      return ABIArgInfo::getDirect(llvm::ArrayType::get(BaseTy, Size / 64));
+    }
+    AllocatedVFP += Members;
+    return ABIArgInfo::getExpand();
+  }
+
+  // Aggregates <= 16 bytes are passed directly in registers or on the stack.
+  uint64_t Size = getContext().getTypeSize(Ty);
+  if (Size <= 128) {
+    unsigned Alignment = getContext().getTypeAlign(Ty);
+    if (!isDarwinPCS() && Alignment > 64)
+      AllocatedGPR = llvm::RoundUpToAlignment(AllocatedGPR, Alignment / 64);
+
+    Size = 64 * ((Size + 63) / 64); // round up to multiple of 8 bytes
+    AllocatedGPR += Size / 64;
+    IsSmallAggr = true;
+    // We use a pair of i64 for 16-byte aggregate with 8-byte alignment.
+    // For aggregates with 16-byte alignment, we use i128.
+    if (Alignment < 128 && Size == 128) {
+      llvm::Type *BaseTy = llvm::Type::getInt64Ty(getVMContext());
+      return ABIArgInfo::getDirect(llvm::ArrayType::get(BaseTy, Size / 64));
+    }
+    return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(), Size));
+  }
+
+  AllocatedGPR++;
+  return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
+}
+
+ABIArgInfo AArch64ABIInfo::classifyReturnType(QualType RetTy) const {
+  if (RetTy->isVoidType())
+    return ABIArgInfo::getIgnore();
+
+  // Large vector types should be returned via memory.
+  if (RetTy->isVectorType() && getContext().getTypeSize(RetTy) > 128)
+    return ABIArgInfo::getIndirect(0);
+
+  if (!isAggregateTypeForABI(RetTy)) {
+    // Treat an enum type as its underlying type.
+    if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
+      RetTy = EnumTy->getDecl()->getIntegerType();
+
+    return (RetTy->isPromotableIntegerType() && isDarwinPCS()
+                ? ABIArgInfo::getExtend()
+                : ABIArgInfo::getDirect());
+  }
+
+  if (isEmptyRecord(getContext(), RetTy, true))
+    return ABIArgInfo::getIgnore();
+
+  const Type *Base = nullptr;
+  if (isHomogeneousAggregate(RetTy, Base, getContext()))
+    // Homogeneous Floating-point Aggregates (HFAs) are returned directly.
+    return ABIArgInfo::getDirect();
+
+  // Aggregates <= 16 bytes are returned directly in registers or on the stack.
+  uint64_t Size = getContext().getTypeSize(RetTy);
+  if (Size <= 128) {
+    Size = 64 * ((Size + 63) / 64); // round up to multiple of 8 bytes
+    return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(), Size));
+  }
+
+  return ABIArgInfo::getIndirect(0);
+}
+
+/// isIllegalVectorType - check whether the vector type is legal for AArch64.
+bool AArch64ABIInfo::isIllegalVectorType(QualType Ty) const {
+  if (const VectorType *VT = Ty->getAs<VectorType>()) {
+    // Check whether VT is legal.
+    unsigned NumElements = VT->getNumElements();
+    uint64_t Size = getContext().getTypeSize(VT);
+    // NumElements should be power of 2 between 1 and 16.
+    if ((NumElements & (NumElements - 1)) != 0 || NumElements > 16)
+      return true;
+    return Size != 64 && (Size != 128 || NumElements == 1);
+  }
+  return false;
+}
+
+static llvm::Value *EmitAArch64VAArg(llvm::Value *VAListAddr, QualType Ty,
+                                     int AllocatedGPR, int AllocatedVFP,
+                                     bool IsIndirect, CodeGenFunction &CGF) {
+  // The AArch64 va_list type and handling is specified in the Procedure Call
+  // Standard, section B.4:
+  //
+  // struct {
+  //   void *__stack;
+  //   void *__gr_top;
+  //   void *__vr_top;
+  //   int __gr_offs;
+  //   int __vr_offs;
+  // };
+
+  llvm::BasicBlock *MaybeRegBlock = CGF.createBasicBlock("vaarg.maybe_reg");
+  llvm::BasicBlock *InRegBlock = CGF.createBasicBlock("vaarg.in_reg");
+  llvm::BasicBlock *OnStackBlock = CGF.createBasicBlock("vaarg.on_stack");
+  llvm::BasicBlock *ContBlock = CGF.createBasicBlock("vaarg.end");
+  auto &Ctx = CGF.getContext();
+
+  llvm::Value *reg_offs_p = nullptr, *reg_offs = nullptr;
+  int reg_top_index;
+  int RegSize;
+  if (AllocatedGPR) {
+    assert(!AllocatedVFP && "Arguments never split between int & VFP regs");
+    // 3 is the field number of __gr_offs
+    reg_offs_p = CGF.Builder.CreateStructGEP(VAListAddr, 3, "gr_offs_p");
+    reg_offs = CGF.Builder.CreateLoad(reg_offs_p, "gr_offs");
+    reg_top_index = 1; // field number for __gr_top
+    RegSize = 8 * AllocatedGPR;
+  } else {
+    assert(!AllocatedGPR && "Argument must go in VFP or int regs");
+    // 4 is the field number of __vr_offs.
+    reg_offs_p = CGF.Builder.CreateStructGEP(VAListAddr, 4, "vr_offs_p");
+    reg_offs = CGF.Builder.CreateLoad(reg_offs_p, "vr_offs");
+    reg_top_index = 2; // field number for __vr_top
+    RegSize = 16 * AllocatedVFP;
+  }
+
+  //=======================================
+  // Find out where argument was passed
+  //=======================================
+
+  // If reg_offs >= 0 we're already using the stack for this type of
+  // argument. We don't want to keep updating reg_offs (in case it overflows,
+  // though anyone passing 2GB of arguments, each at most 16 bytes, deserves
+  // whatever they get).
+  llvm::Value *UsingStack = nullptr;
+  UsingStack = CGF.Builder.CreateICmpSGE(
+      reg_offs, llvm::ConstantInt::get(CGF.Int32Ty, 0));
+
+  CGF.Builder.CreateCondBr(UsingStack, OnStackBlock, MaybeRegBlock);
+
+  // Otherwise, at least some kind of argument could go in these registers, the
+  // question is whether this particular type is too big.
+  CGF.EmitBlock(MaybeRegBlock);
+
+  // Integer arguments may need to correct register alignment (for example a
+  // "struct { __int128 a; };" gets passed in x_2N, x_{2N+1}). In this case we
+  // align __gr_offs to calculate the potential address.
+  if (AllocatedGPR && !IsIndirect && Ctx.getTypeAlign(Ty) > 64) {
+    int Align = Ctx.getTypeAlign(Ty) / 8;
+
+    reg_offs = CGF.Builder.CreateAdd(
+        reg_offs, llvm::ConstantInt::get(CGF.Int32Ty, Align - 1),
+        "align_regoffs");
+    reg_offs = CGF.Builder.CreateAnd(
+        reg_offs, llvm::ConstantInt::get(CGF.Int32Ty, -Align),
+        "aligned_regoffs");
+  }
+
+  // Update the gr_offs/vr_offs pointer for next call to va_arg on this va_list.
+  llvm::Value *NewOffset = nullptr;
+  NewOffset = CGF.Builder.CreateAdd(
+      reg_offs, llvm::ConstantInt::get(CGF.Int32Ty, RegSize), "new_reg_offs");
+  CGF.Builder.CreateStore(NewOffset, reg_offs_p);
+
+  // Now we're in a position to decide whether this argument really was in
+  // registers or not.
+  llvm::Value *InRegs = nullptr;
+  InRegs = CGF.Builder.CreateICmpSLE(
+      NewOffset, llvm::ConstantInt::get(CGF.Int32Ty, 0), "inreg");
+
+  CGF.Builder.CreateCondBr(InRegs, InRegBlock, OnStackBlock);
+
+  //=======================================
+  // Argument was in registers
+  //=======================================
+
+  // Now we emit the code for if the argument was originally passed in
+  // registers. First start the appropriate block:
+  CGF.EmitBlock(InRegBlock);
+
+  llvm::Value *reg_top_p = nullptr, *reg_top = nullptr;
+  reg_top_p =
+      CGF.Builder.CreateStructGEP(VAListAddr, reg_top_index, "reg_top_p");
+  reg_top = CGF.Builder.CreateLoad(reg_top_p, "reg_top");
+  llvm::Value *BaseAddr = CGF.Builder.CreateGEP(reg_top, reg_offs);
+  llvm::Value *RegAddr = nullptr;
+  llvm::Type *MemTy = llvm::PointerType::getUnqual(CGF.ConvertTypeForMem(Ty));
+
+  if (IsIndirect) {
+    // If it's been passed indirectly (actually a struct), whatever we find from
+    // stored registers or on the stack will actually be a struct **.
+    MemTy = llvm::PointerType::getUnqual(MemTy);
+  }
+
+  const Type *Base = nullptr;
+  uint64_t NumMembers;
+  bool IsHFA = isHomogeneousAggregate(Ty, Base, Ctx, &NumMembers);
+  if (IsHFA && NumMembers > 1) {
+    // Homogeneous aggregates passed in registers will have their elements split
+    // and stored 16-bytes apart regardless of size (they're notionally in qN,
+    // qN+1, ...). We reload and store into a temporary local variable
+    // contiguously.
+    assert(!IsIndirect && "Homogeneous aggregates should be passed directly");
+    llvm::Type *BaseTy = CGF.ConvertType(QualType(Base, 0));
+    llvm::Type *HFATy = llvm::ArrayType::get(BaseTy, NumMembers);
+    llvm::Value *Tmp = CGF.CreateTempAlloca(HFATy);
+    int Offset = 0;
+
+    if (CGF.CGM.getDataLayout().isBigEndian() && Ctx.getTypeSize(Base) < 128)
+      Offset = 16 - Ctx.getTypeSize(Base) / 8;
+    for (unsigned i = 0; i < NumMembers; ++i) {
+      llvm::Value *BaseOffset =
+          llvm::ConstantInt::get(CGF.Int32Ty, 16 * i + Offset);
+      llvm::Value *LoadAddr = CGF.Builder.CreateGEP(BaseAddr, BaseOffset);
+      LoadAddr = CGF.Builder.CreateBitCast(
+          LoadAddr, llvm::PointerType::getUnqual(BaseTy));
+      llvm::Value *StoreAddr = CGF.Builder.CreateStructGEP(Tmp, i);
+
+      llvm::Value *Elem = CGF.Builder.CreateLoad(LoadAddr);
+      CGF.Builder.CreateStore(Elem, StoreAddr);
+    }
+
+    RegAddr = CGF.Builder.CreateBitCast(Tmp, MemTy);
+  } else {
+    // Otherwise the object is contiguous in memory
+    unsigned BeAlign = reg_top_index == 2 ? 16 : 8;
+    if (CGF.CGM.getDataLayout().isBigEndian() &&
+        (IsHFA || !isAggregateTypeForABI(Ty)) &&
+        Ctx.getTypeSize(Ty) < (BeAlign * 8)) {
+      int Offset = BeAlign - Ctx.getTypeSize(Ty) / 8;
+      BaseAddr = CGF.Builder.CreatePtrToInt(BaseAddr, CGF.Int64Ty);
+
+      BaseAddr = CGF.Builder.CreateAdd(
+          BaseAddr, llvm::ConstantInt::get(CGF.Int64Ty, Offset), "align_be");
+
+      BaseAddr = CGF.Builder.CreateIntToPtr(BaseAddr, CGF.Int8PtrTy);
+    }
+
+    RegAddr = CGF.Builder.CreateBitCast(BaseAddr, MemTy);
+  }
+
+  CGF.EmitBranch(ContBlock);
+
+  //=======================================
+  // Argument was on the stack
+  //=======================================
+  CGF.EmitBlock(OnStackBlock);
+
+  llvm::Value *stack_p = nullptr, *OnStackAddr = nullptr;
+  stack_p = CGF.Builder.CreateStructGEP(VAListAddr, 0, "stack_p");
+  OnStackAddr = CGF.Builder.CreateLoad(stack_p, "stack");
+
+  // Again, stack arguments may need realigmnent. In this case both integer and
+  // floating-point ones might be affected.
+  if (!IsIndirect && Ctx.getTypeAlign(Ty) > 64) {
+    int Align = Ctx.getTypeAlign(Ty) / 8;
+
+    OnStackAddr = CGF.Builder.CreatePtrToInt(OnStackAddr, CGF.Int64Ty);
+
+    OnStackAddr = CGF.Builder.CreateAdd(
+        OnStackAddr, llvm::ConstantInt::get(CGF.Int64Ty, Align - 1),
+        "align_stack");
+    OnStackAddr = CGF.Builder.CreateAnd(
+        OnStackAddr, llvm::ConstantInt::get(CGF.Int64Ty, -Align),
+        "align_stack");
+
+    OnStackAddr = CGF.Builder.CreateIntToPtr(OnStackAddr, CGF.Int8PtrTy);
+  }
+
+  uint64_t StackSize;
+  if (IsIndirect)
+    StackSize = 8;
+  else
+    StackSize = Ctx.getTypeSize(Ty) / 8;
+
+  // All stack slots are 8 bytes
+  StackSize = llvm::RoundUpToAlignment(StackSize, 8);
+
+  llvm::Value *StackSizeC = llvm::ConstantInt::get(CGF.Int32Ty, StackSize);
+  llvm::Value *NewStack =
+      CGF.Builder.CreateGEP(OnStackAddr, StackSizeC, "new_stack");
+
+  // Write the new value of __stack for the next call to va_arg
+  CGF.Builder.CreateStore(NewStack, stack_p);
+
+  if (CGF.CGM.getDataLayout().isBigEndian() && !isAggregateTypeForABI(Ty) &&
+      Ctx.getTypeSize(Ty) < 64) {
+    int Offset = 8 - Ctx.getTypeSize(Ty) / 8;
+    OnStackAddr = CGF.Builder.CreatePtrToInt(OnStackAddr, CGF.Int64Ty);
+
+    OnStackAddr = CGF.Builder.CreateAdd(
+        OnStackAddr, llvm::ConstantInt::get(CGF.Int64Ty, Offset), "align_be");
+
+    OnStackAddr = CGF.Builder.CreateIntToPtr(OnStackAddr, CGF.Int8PtrTy);
+  }
+
+  OnStackAddr = CGF.Builder.CreateBitCast(OnStackAddr, MemTy);
+
+  CGF.EmitBranch(ContBlock);
+
+  //=======================================
+  // Tidy up
+  //=======================================
+  CGF.EmitBlock(ContBlock);
+
+  llvm::PHINode *ResAddr = CGF.Builder.CreatePHI(MemTy, 2, "vaarg.addr");
+  ResAddr->addIncoming(RegAddr, InRegBlock);
+  ResAddr->addIncoming(OnStackAddr, OnStackBlock);
+
+  if (IsIndirect)
+    return CGF.Builder.CreateLoad(ResAddr, "vaarg.addr");
+
+  return ResAddr;
+}
+
+llvm::Value *AArch64ABIInfo::EmitAAPCSVAArg(llvm::Value *VAListAddr, QualType Ty,
+                                          CodeGenFunction &CGF) const {
+
+  unsigned AllocatedGPR = 0, AllocatedVFP = 0;
+  bool IsHA = false, IsSmallAggr = false;
+  ABIArgInfo AI = classifyArgumentType(Ty, AllocatedVFP, IsHA, AllocatedGPR,
+                                       IsSmallAggr, false /*IsNamedArg*/);
+
+  return EmitAArch64VAArg(VAListAddr, Ty, AllocatedGPR, AllocatedVFP,
+                          AI.isIndirect(), CGF);
+}
+
+llvm::Value *AArch64ABIInfo::EmitDarwinVAArg(llvm::Value *VAListAddr, QualType Ty,
+                                           CodeGenFunction &CGF) const {
+  // We do not support va_arg for aggregates or illegal vector types.
+  // Lower VAArg here for these cases and use the LLVM va_arg instruction for
+  // other cases.
+  if (!isAggregateTypeForABI(Ty) && !isIllegalVectorType(Ty))
+    return nullptr;
+
+  uint64_t Size = CGF.getContext().getTypeSize(Ty) / 8;
+  uint64_t Align = CGF.getContext().getTypeAlign(Ty) / 8;
+
+  const Type *Base = nullptr;
+  bool isHA = isHomogeneousAggregate(Ty, Base, getContext());
+
+  bool isIndirect = false;
+  // Arguments bigger than 16 bytes which aren't homogeneous aggregates should
+  // be passed indirectly.
+  if (Size > 16 && !isHA) {
+    isIndirect = true;
+    Size = 8;
+    Align = 8;
+  }
+
+  llvm::Type *BP = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
+  llvm::Type *BPP = llvm::PointerType::getUnqual(BP);
+
+  CGBuilderTy &Builder = CGF.Builder;
+  llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, BPP, "ap");
+  llvm::Value *Addr = Builder.CreateLoad(VAListAddrAsBPP, "ap.cur");
+
+  if (isEmptyRecord(getContext(), Ty, true)) {
+    // These are ignored for parameter passing purposes.
+    llvm::Type *PTy = llvm::PointerType::getUnqual(CGF.ConvertType(Ty));
+    return Builder.CreateBitCast(Addr, PTy);
+  }
+
+  const uint64_t MinABIAlign = 8;
+  if (Align > MinABIAlign) {
+    llvm::Value *Offset = llvm::ConstantInt::get(CGF.Int32Ty, Align - 1);
+    Addr = Builder.CreateGEP(Addr, Offset);
+    llvm::Value *AsInt = Builder.CreatePtrToInt(Addr, CGF.Int64Ty);
+    llvm::Value *Mask = llvm::ConstantInt::get(CGF.Int64Ty, ~(Align - 1));
+    llvm::Value *Aligned = Builder.CreateAnd(AsInt, Mask);
+    Addr = Builder.CreateIntToPtr(Aligned, BP, "ap.align");
+  }
+
+  uint64_t Offset = llvm::RoundUpToAlignment(Size, MinABIAlign);
+  llvm::Value *NextAddr = Builder.CreateGEP(
+      Addr, llvm::ConstantInt::get(CGF.Int32Ty, Offset), "ap.next");
+  Builder.CreateStore(NextAddr, VAListAddrAsBPP);
+
+  if (isIndirect)
+    Addr = Builder.CreateLoad(Builder.CreateBitCast(Addr, BPP));
+  llvm::Type *PTy = llvm::PointerType::getUnqual(CGF.ConvertType(Ty));
+  llvm::Value *AddrTyped = Builder.CreateBitCast(Addr, PTy);
+
+  return AddrTyped;
+}
+
+//===----------------------------------------------------------------------===//
 // ARM ABI Implementation
 //===----------------------------------------------------------------------===//
 
@@ -3121,35 +4085,62 @@
 
 private:
   ABIKind Kind;
+  mutable int VFPRegs[16];
+  const unsigned NumVFPs;
+  const unsigned NumGPRs;
+  mutable unsigned AllocatedGPRs;
+  mutable unsigned AllocatedVFPs;
 
 public:
-  ARMABIInfo(CodeGenTypes &CGT, ABIKind _Kind) : ABIInfo(CGT), Kind(_Kind) {
+  ARMABIInfo(CodeGenTypes &CGT, ABIKind _Kind) : ABIInfo(CGT), Kind(_Kind),
+    NumVFPs(16), NumGPRs(4) {
     setRuntimeCC();
+    resetAllocatedRegs();
   }
 
   bool isEABI() const {
-    StringRef Env = getTarget().getTriple().getEnvironmentName();
-    return (Env == "gnueabi" || Env == "eabi" ||
-            Env == "android" || Env == "androideabi");
+    switch (getTarget().getTriple().getEnvironment()) {
+    case llvm::Triple::Android:
+    case llvm::Triple::EABI:
+    case llvm::Triple::EABIHF:
+    case llvm::Triple::GNUEABI:
+    case llvm::Triple::GNUEABIHF:
+      return true;
+    default:
+      return false;
+    }
+  }
+
+  bool isEABIHF() const {
+    switch (getTarget().getTriple().getEnvironment()) {
+    case llvm::Triple::EABIHF:
+    case llvm::Triple::GNUEABIHF:
+      return true;
+    default:
+      return false;
+    }
   }
 
   ABIKind getABIKind() const { return Kind; }
 
 private:
-  ABIArgInfo classifyReturnType(QualType RetTy) const;
-  ABIArgInfo classifyArgumentType(QualType RetTy, int *VFPRegs,
-                                  unsigned &AllocatedVFP,
-                                  bool &IsHA) const;
+  ABIArgInfo classifyReturnType(QualType RetTy, bool isVariadic) const;
+  ABIArgInfo classifyArgumentType(QualType RetTy, bool isVariadic,
+                                  bool &IsCPRC) const;
   bool isIllegalVectorType(QualType Ty) const;
 
-  virtual void computeInfo(CGFunctionInfo &FI) const;
+  void computeInfo(CGFunctionInfo &FI) const override;
 
-  virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
-                                 CodeGenFunction &CGF) const;
+  llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+                         CodeGenFunction &CGF) const override;
 
   llvm::CallingConv::ID getLLVMDefaultCC() const;
   llvm::CallingConv::ID getABIDefaultCC() const;
   void setRuntimeCC();
+
+  void markAllocatedGPRs(unsigned Alignment, unsigned NumRequired) const;
+  void markAllocatedVFPs(unsigned Alignment, unsigned NumRequired) const;
+  void resetAllocatedRegs(void) const;
 };
 
 class ARMTargetCodeGenInfo : public TargetCodeGenInfo {
@@ -3161,16 +4152,16 @@
     return static_cast<const ARMABIInfo&>(TargetCodeGenInfo::getABIInfo());
   }
 
-  int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const {
+  int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override {
     return 13;
   }
 
-  StringRef getARCRetainAutoreleasedReturnValueMarker() const {
+  StringRef getARCRetainAutoreleasedReturnValueMarker() const override {
     return "mov\tr7, r7\t\t@ marker for objc_retainAutoreleaseReturnValue";
   }
 
   bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
-                               llvm::Value *Address) const {
+                               llvm::Value *Address) const override {
     llvm::Value *Four8 = llvm::ConstantInt::get(CGF.Int8Ty, 4);
 
     // 0-15 are the 16 integer registers.
@@ -3178,13 +4169,13 @@
     return false;
   }
 
-  unsigned getSizeOfUnwindException() const {
+  unsigned getSizeOfUnwindException() const override {
     if (getABIInfo().isEABI()) return 88;
     return TargetCodeGenInfo::getSizeOfUnwindException();
   }
 
   void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
-                           CodeGen::CodeGenModule &CGM) const {
+                           CodeGen::CodeGenModule &CGM) const override {
     const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
     if (!FD)
       return;
@@ -3233,24 +4224,43 @@
   // allocated to the lowest-numbered sequence of such registers.
   // C.2.vfp If the argument is a VFP CPRC then any VFP registers that are
   // unallocated are marked as unavailable. 
-  unsigned AllocatedVFP = 0;
-  int VFPRegs[16] = { 0 };
-  FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
-  for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
-       it != ie; ++it) {
-    unsigned PreAllocation = AllocatedVFP;
-    bool IsHA = false;
+  resetAllocatedRegs();
+
+  if (getCXXABI().classifyReturnType(FI)) {
+    if (FI.getReturnInfo().isIndirect())
+      markAllocatedGPRs(1, 1);
+  } else {
+    FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), FI.isVariadic());
+  }
+  for (auto &I : FI.arguments()) {
+    unsigned PreAllocationVFPs = AllocatedVFPs;
+    unsigned PreAllocationGPRs = AllocatedGPRs;
+    bool IsCPRC = false;
     // 6.1.2.3 There is one VFP co-processor register class using registers
     // s0-s15 (d0-d7) for passing arguments.
-    const unsigned NumVFPs = 16;
-    it->info = classifyArgumentType(it->type, VFPRegs, AllocatedVFP, IsHA);
-    // If we do not have enough VFP registers for the HA, any VFP registers
-    // that are unallocated are marked as unavailable. To achieve this, we add
-    // padding of (NumVFPs - PreAllocation) floats.
-    if (IsHA && AllocatedVFP > NumVFPs && PreAllocation < NumVFPs) {
+    I.info = classifyArgumentType(I.type, FI.isVariadic(), IsCPRC);
+
+    // If we have allocated some arguments onto the stack (due to running
+    // out of VFP registers), we cannot split an argument between GPRs and
+    // the stack. If this situation occurs, we add padding to prevent the
+    // GPRs from being used. In this situation, the current argument could
+    // only be allocated by rule C.8, so rule C.6 would mark these GPRs as
+    // unusable anyway.
+    // We do not have to do this if the argument is being passed ByVal, as the
+    // backend can handle that situation correctly.
+    const bool StackUsed = PreAllocationGPRs > NumGPRs || PreAllocationVFPs > NumVFPs;
+    const bool IsByVal = I.info.isIndirect() && I.info.getIndirectByVal();
+    if (!IsCPRC && PreAllocationGPRs < NumGPRs && AllocatedGPRs > NumGPRs &&
+        StackUsed && !IsByVal) {
       llvm::Type *PaddingTy = llvm::ArrayType::get(
-          llvm::Type::getFloatTy(getVMContext()), NumVFPs - PreAllocation);
-      it->info = ABIArgInfo::getExpandWithPadding(false, PaddingTy);
+          llvm::Type::getInt32Ty(getVMContext()), NumGPRs - PreAllocationGPRs);
+      if (I.info.canHaveCoerceToType()) {
+        I.info = ABIArgInfo::getDirect(I.info.getCoerceToType() /* type */, 0 /* offset */,
+                                       PaddingTy);
+      } else {
+        I.info = ABIArgInfo::getDirect(nullptr /* type */, 0 /* offset */,
+                                       PaddingTy);
+      }
     }
   }
 
@@ -3266,7 +4276,7 @@
 /// Return the default calling convention that LLVM will use.
 llvm::CallingConv::ID ARMABIInfo::getLLVMDefaultCC() const {
   // The default calling convention that LLVM will infer.
-  if (getTarget().getTriple().getEnvironmentName()=="gnueabihf")
+  if (isEABIHF())
     return llvm::CallingConv::ARM_AAPCS_VFP;
   else if (isEABI())
     return llvm::CallingConv::ARM_AAPCS;
@@ -3300,8 +4310,7 @@
 /// contained in the type is returned through it; this is used for the
 /// recursive calls that check aggregate component types.
 static bool isHomogeneousAggregate(QualType Ty, const Type *&Base,
-                                   ASTContext &Context,
-                                   uint64_t *HAMembers = 0) {
+                                   ASTContext &Context, uint64_t *HAMembers) {
   uint64_t Members = 0;
   if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty)) {
     if (!isHomogeneousAggregate(AT->getElementType(), Base, Context, &Members))
@@ -3313,9 +4322,7 @@
       return false;
 
     Members = 0;
-    for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
-         i != e; ++i) {
-      const FieldDecl *FD = *i;
+    for (const auto *FD : RD->fields()) {
       uint64_t FldMembers;
       if (!isHomogeneousAggregate(FD->getType(), Base, Context, &FldMembers))
         return false;
@@ -3350,10 +4357,29 @@
     const Type *TyPtr = Ty.getTypePtr();
     if (!Base)
       Base = TyPtr;
-    if (Base != TyPtr &&
-        (!Base->isVectorType() || !TyPtr->isVectorType() ||
-         Context.getTypeSize(Base) != Context.getTypeSize(TyPtr)))
-      return false;
+
+    if (Base != TyPtr) {
+      // Homogeneous aggregates are defined as containing members with the
+      // same machine type. There are two cases in which two members have
+      // different TypePtrs but the same machine type:
+
+      // 1) Vectors of the same length, regardless of the type and number
+      //    of their members.
+      const bool SameLengthVectors = Base->isVectorType() && TyPtr->isVectorType()
+        && (Context.getTypeSize(Base) == Context.getTypeSize(TyPtr));
+
+      // 2) In the 32-bit AAPCS, `double' and `long double' have the same
+      //    machine type. This is not the case for the 64-bit AAPCS.
+      const bool SameSizeDoubles =
+           (   (   Base->isSpecificBuiltinType(BuiltinType::Double)
+                && TyPtr->isSpecificBuiltinType(BuiltinType::LongDouble))
+            || (   Base->isSpecificBuiltinType(BuiltinType::LongDouble)
+                && TyPtr->isSpecificBuiltinType(BuiltinType::Double)))
+        && (Context.getTypeSize(Base) == Context.getTypeSize(TyPtr));
+
+      if (!SameLengthVectors && !SameSizeDoubles)
+        return false;
+    }
   }
 
   // Homogeneous Aggregates can have at most 4 members of the base type.
@@ -3365,12 +4391,15 @@
 
 /// markAllocatedVFPs - update VFPRegs according to the alignment and
 /// number of VFP registers (unit is S register) requested.
-static void markAllocatedVFPs(int *VFPRegs, unsigned &AllocatedVFP,
-                              unsigned Alignment,
-                              unsigned NumRequired) {
+void ARMABIInfo::markAllocatedVFPs(unsigned Alignment,
+                                   unsigned NumRequired) const {
   // Early Exit.
-  if (AllocatedVFP >= 16)
+  if (AllocatedVFPs >= 16) {
+    // We use AllocatedVFP > 16 to signal that some CPRCs were allocated on
+    // the stack.
+    AllocatedVFPs = 17;
     return;
+  }
   // C.1.vfp If the argument is a VFP CPRC and there are sufficient consecutive
   // VFP registers of the appropriate type unallocated then the argument is
   // allocated to the lowest-numbered sequence of such registers.
@@ -3384,7 +4413,7 @@
     if (FoundSlot) {
       for (unsigned J = I, JEnd = I + NumRequired; J < JEnd; J++)
         VFPRegs[J] = 1;
-      AllocatedVFP += NumRequired;
+      AllocatedVFPs += NumRequired;
       return;
     }
   }
@@ -3392,12 +4421,31 @@
   // unallocated are marked as unavailable.
   for (unsigned I = 0; I < 16; I++)
     VFPRegs[I] = 1;
-  AllocatedVFP = 17; // We do not have enough VFP registers.
+  AllocatedVFPs = 17; // We do not have enough VFP registers.
 }
 
-ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty, int *VFPRegs,
-                                            unsigned &AllocatedVFP,
-                                            bool &IsHA) const {
+/// Update AllocatedGPRs to record the number of general purpose registers
+/// which have been allocated. It is valid for AllocatedGPRs to go above 4,
+/// this represents arguments being stored on the stack.
+void ARMABIInfo::markAllocatedGPRs(unsigned Alignment,
+                                   unsigned NumRequired) const {
+  assert((Alignment == 1 || Alignment == 2) && "Alignment must be 4 or 8 bytes");
+
+  if (Alignment == 2 && AllocatedGPRs & 0x1)
+    AllocatedGPRs += 1;
+
+  AllocatedGPRs += NumRequired;
+}
+
+void ARMABIInfo::resetAllocatedRegs(void) const {
+  AllocatedGPRs = 0;
+  AllocatedVFPs = 0;
+  for (unsigned i = 0; i < NumVFPs; ++i)
+    VFPRegs[i] = 0;
+}
+
+ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty, bool isVariadic,
+                                            bool &IsCPRC) const {
   // We update number of allocated VFPs according to
   // 6.1.2.1 The following argument types are VFP CPRCs:
   //   A single-precision floating-point type (including promoted
@@ -3413,58 +4461,85 @@
     if (Size <= 32) {
       llvm::Type *ResType =
           llvm::Type::getInt32Ty(getVMContext());
+      markAllocatedGPRs(1, 1);
       return ABIArgInfo::getDirect(ResType);
     }
     if (Size == 64) {
       llvm::Type *ResType = llvm::VectorType::get(
           llvm::Type::getInt32Ty(getVMContext()), 2);
-      markAllocatedVFPs(VFPRegs, AllocatedVFP, 2, 2);
+      if (getABIKind() == ARMABIInfo::AAPCS || isVariadic){
+        markAllocatedGPRs(2, 2);
+      } else {
+        markAllocatedVFPs(2, 2);
+        IsCPRC = true;
+      }
       return ABIArgInfo::getDirect(ResType);
     }
     if (Size == 128) {
       llvm::Type *ResType = llvm::VectorType::get(
           llvm::Type::getInt32Ty(getVMContext()), 4);
-      markAllocatedVFPs(VFPRegs, AllocatedVFP, 4, 4);
+      if (getABIKind() == ARMABIInfo::AAPCS || isVariadic) {
+        markAllocatedGPRs(2, 4);
+      } else {
+        markAllocatedVFPs(4, 4);
+        IsCPRC = true;
+      }
       return ABIArgInfo::getDirect(ResType);
     }
+    markAllocatedGPRs(1, 1);
     return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
   }
   // Update VFPRegs for legal vector types.
-  if (const VectorType *VT = Ty->getAs<VectorType>()) {
-    uint64_t Size = getContext().getTypeSize(VT);
-    // Size of a legal vector should be power of 2 and above 64.
-    markAllocatedVFPs(VFPRegs, AllocatedVFP, Size >= 128 ? 4 : 2, Size / 32);
+  if (getABIKind() == ARMABIInfo::AAPCS_VFP && !isVariadic) {
+    if (const VectorType *VT = Ty->getAs<VectorType>()) {
+      uint64_t Size = getContext().getTypeSize(VT);
+      // Size of a legal vector should be power of 2 and above 64.
+      markAllocatedVFPs(Size >= 128 ? 4 : 2, Size / 32);
+      IsCPRC = true;
+    }
   }
   // Update VFPRegs for floating point types.
-  if (const BuiltinType *BT = Ty->getAs<BuiltinType>()) {
-    if (BT->getKind() == BuiltinType::Half ||
-        BT->getKind() == BuiltinType::Float)
-      markAllocatedVFPs(VFPRegs, AllocatedVFP, 1, 1);
-    if (BT->getKind() == BuiltinType::Double ||
-        BT->getKind() == BuiltinType::LongDouble)
-      markAllocatedVFPs(VFPRegs, AllocatedVFP, 2, 2);
+  if (getABIKind() == ARMABIInfo::AAPCS_VFP && !isVariadic) {
+    if (const BuiltinType *BT = Ty->getAs<BuiltinType>()) {
+      if (BT->getKind() == BuiltinType::Half ||
+          BT->getKind() == BuiltinType::Float) {
+        markAllocatedVFPs(1, 1);
+        IsCPRC = true;
+      }
+      if (BT->getKind() == BuiltinType::Double ||
+          BT->getKind() == BuiltinType::LongDouble) {
+        markAllocatedVFPs(2, 2);
+        IsCPRC = true;
+      }
+    }
   }
 
   if (!isAggregateTypeForABI(Ty)) {
     // Treat an enum type as its underlying type.
-    if (const EnumType *EnumTy = Ty->getAs<EnumType>())
+    if (const EnumType *EnumTy = Ty->getAs<EnumType>()) {
       Ty = EnumTy->getDecl()->getIntegerType();
+    }
 
+    unsigned Size = getContext().getTypeSize(Ty);
+    if (!IsCPRC)
+      markAllocatedGPRs(Size > 32 ? 2 : 1, (Size + 31) / 32);
     return (Ty->isPromotableIntegerType() ?
             ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
   }
 
-  if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI()))
+  if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) {
+    markAllocatedGPRs(1, 1);
     return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory);
+  }
 
   // Ignore empty records.
   if (isEmptyRecord(getContext(), Ty, true))
     return ABIArgInfo::getIgnore();
 
-  if (getABIKind() == ARMABIInfo::AAPCS_VFP) {
+  if (getABIKind() == ARMABIInfo::AAPCS_VFP && !isVariadic) {
     // Homogeneous Aggregates need to be expanded when we can fit the aggregate
     // into VFP registers.
-    const Type *Base = 0;
+    const Type *Base = nullptr;
     uint64_t Members = 0;
     if (isHomogeneousAggregate(Ty, Base, getContext(), &Members)) {
       assert(Base && "Base class should be set for homogeneous aggregate");
@@ -3472,17 +4547,17 @@
       if (Base->isVectorType()) {
         // ElementSize is in number of floats.
         unsigned ElementSize = getContext().getTypeSize(Base) == 64 ? 2 : 4;
-        markAllocatedVFPs(VFPRegs, AllocatedVFP, ElementSize,
+        markAllocatedVFPs(ElementSize,
                           Members * ElementSize);
       } else if (Base->isSpecificBuiltinType(BuiltinType::Float))
-        markAllocatedVFPs(VFPRegs, AllocatedVFP, 1, Members);
+        markAllocatedVFPs(1, Members);
       else {
         assert(Base->isSpecificBuiltinType(BuiltinType::Double) ||
                Base->isSpecificBuiltinType(BuiltinType::LongDouble));
-        markAllocatedVFPs(VFPRegs, AllocatedVFP, 2, Members * 2);
+        markAllocatedVFPs(2, Members * 2);
       }
-      IsHA = true;
-      return ABIArgInfo::getExpand();
+      IsCPRC = true;
+      return ABIArgInfo::getDirect();
     }
   }
 
@@ -3496,7 +4571,12 @@
       getABIKind() == ARMABIInfo::AAPCS)
     ABIAlign = std::min(std::max(TyAlign, (uint64_t)4), (uint64_t)8);
   if (getContext().getTypeSizeInChars(Ty) > CharUnits::fromQuantity(64)) {
-    return ABIArgInfo::getIndirect(0, /*ByVal=*/true,
+    // Update Allocated GPRs. Since this is only used when the size of the
+    // argument is greater than 64 bytes, this will always use up any available
+    // registers (of which there are 4). We also don't care about getting the
+    // alignment right, because general-purpose registers cannot be back-filled.
+    markAllocatedGPRs(1, 4);
+    return ABIArgInfo::getIndirect(TyAlign, /*ByVal=*/true,
            /*Realign=*/TyAlign > ABIAlign);
   }
 
@@ -3508,9 +4588,11 @@
   if (getContext().getTypeAlign(Ty) <= 32) {
     ElemTy = llvm::Type::getInt32Ty(getVMContext());
     SizeRegs = (getContext().getTypeSize(Ty) + 31) / 32;
+    markAllocatedGPRs(1, SizeRegs);
   } else {
     ElemTy = llvm::Type::getInt64Ty(getVMContext());
     SizeRegs = (getContext().getTypeSize(Ty) + 63) / 64;
+    markAllocatedGPRs(2, SizeRegs * 2);
   }
 
   llvm::Type *STy =
@@ -3603,13 +4685,16 @@
   return true;
 }
 
-ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy) const {
+ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy,
+                                          bool isVariadic) const {
   if (RetTy->isVoidType())
     return ABIArgInfo::getIgnore();
 
   // Large vector types should be returned via memory.
-  if (RetTy->isVectorType() && getContext().getTypeSize(RetTy) > 128)
+  if (RetTy->isVectorType() && getContext().getTypeSize(RetTy) > 128) {
+    markAllocatedGPRs(1, 1);
     return ABIArgInfo::getIndirect(0);
+  }
 
   if (!isAggregateTypeForABI(RetTy)) {
     // Treat an enum type as its underlying type.
@@ -3620,11 +4705,6 @@
             ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
   }
 
-  // Structures with either a non-trivial destructor or a non-trivial
-  // copy constructor are always indirect.
-  if (isRecordReturnIndirect(RetTy, getCXXABI()))
-    return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
-
   // Are we following APCS?
   if (getABIKind() == APCS) {
     if (isEmptyRecord(getContext(), RetTy, false))
@@ -3650,6 +4730,7 @@
     }
 
     // Otherwise return in memory.
+    markAllocatedGPRs(1, 1);
     return ABIArgInfo::getIndirect(0);
   }
 
@@ -3659,8 +4740,8 @@
     return ABIArgInfo::getIgnore();
 
   // Check for homogeneous aggregates with AAPCS-VFP.
-  if (getABIKind() == AAPCS_VFP) {
-    const Type *Base = 0;
+  if (getABIKind() == AAPCS_VFP && !isVariadic) {
+    const Type *Base = nullptr;
     if (isHomogeneousAggregate(RetTy, Base, getContext())) {
       assert(Base && "Base class should be set for homogeneous aggregate");
       // Homogeneous Aggregates are returned directly.
@@ -3672,6 +4753,10 @@
   // are returned indirectly.
   uint64_t Size = getContext().getTypeSize(RetTy);
   if (Size <= 32) {
+    if (getDataLayout().isBigEndian())
+      // Return in 32 bit integer integer type (as if loaded by LDR, AAPCS 5.4)
+      return ABIArgInfo::getDirect(llvm::Type::getInt32Ty(getVMContext()));
+
     // Return in the smallest viable integer type.
     if (Size <= 8)
       return ABIArgInfo::getDirect(llvm::Type::getInt8Ty(getVMContext()));
@@ -3680,6 +4765,7 @@
     return ABIArgInfo::getDirect(llvm::Type::getInt32Ty(getVMContext()));
   }
 
+  markAllocatedGPRs(1, 1);
   return ABIArgInfo::getIndirect(0);
 }
 
@@ -3780,9 +4866,9 @@
  public:
   NaClARMABIInfo(CodeGen::CodeGenTypes &CGT, ARMABIInfo::ABIKind Kind)
       : ABIInfo(CGT), PInfo(CGT), NInfo(CGT, Kind) {}
-  virtual void computeInfo(CGFunctionInfo &FI) const;
-  virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
-                                 CodeGenFunction &CGF) const;
+  void computeInfo(CGFunctionInfo &FI) const override;
+  llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+                         CodeGenFunction &CGF) const override;
  private:
   PNaClABIInfo PInfo; // Used for generating calls with pnaclcall callingconv.
   ARMABIInfo NInfo; // Used for everything else.
@@ -3811,418 +4897,6 @@
 }
 
 //===----------------------------------------------------------------------===//
-// AArch64 ABI Implementation
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-class AArch64ABIInfo : public ABIInfo {
-public:
-  AArch64ABIInfo(CodeGenTypes &CGT) : ABIInfo(CGT) {}
-
-private:
-  // The AArch64 PCS is explicit about return types and argument types being
-  // handled identically, so we don't need to draw a distinction between
-  // Argument and Return classification.
-  ABIArgInfo classifyGenericType(QualType Ty, int &FreeIntRegs,
-                                 int &FreeVFPRegs) const;
-
-  ABIArgInfo tryUseRegs(QualType Ty, int &FreeRegs, int RegsNeeded, bool IsInt,
-                        llvm::Type *DirectTy = 0) const;
-
-  virtual void computeInfo(CGFunctionInfo &FI) const;
-
-  virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
-                                 CodeGenFunction &CGF) const;
-};
-
-class AArch64TargetCodeGenInfo : public TargetCodeGenInfo {
-public:
-  AArch64TargetCodeGenInfo(CodeGenTypes &CGT)
-    :TargetCodeGenInfo(new AArch64ABIInfo(CGT)) {}
-
-  const AArch64ABIInfo &getABIInfo() const {
-    return static_cast<const AArch64ABIInfo&>(TargetCodeGenInfo::getABIInfo());
-  }
-
-  int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const {
-    return 31;
-  }
-
-  bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
-                               llvm::Value *Address) const {
-    // 0-31 are x0-x30 and sp: 8 bytes each
-    llvm::Value *Eight8 = llvm::ConstantInt::get(CGF.Int8Ty, 8);
-    AssignToArrayRange(CGF.Builder, Address, Eight8, 0, 31);
-
-    // 64-95 are v0-v31: 16 bytes each
-    llvm::Value *Sixteen8 = llvm::ConstantInt::get(CGF.Int8Ty, 16);
-    AssignToArrayRange(CGF.Builder, Address, Sixteen8, 64, 95);
-
-    return false;
-  }
-
-};
-
-}
-
-void AArch64ABIInfo::computeInfo(CGFunctionInfo &FI) const {
-  int FreeIntRegs = 8, FreeVFPRegs = 8;
-
-  FI.getReturnInfo() = classifyGenericType(FI.getReturnType(),
-                                           FreeIntRegs, FreeVFPRegs);
-
-  FreeIntRegs = FreeVFPRegs = 8;
-  for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
-       it != ie; ++it) {
-    it->info = classifyGenericType(it->type, FreeIntRegs, FreeVFPRegs);
-
-  }
-}
-
-ABIArgInfo
-AArch64ABIInfo::tryUseRegs(QualType Ty, int &FreeRegs, int RegsNeeded,
-                           bool IsInt, llvm::Type *DirectTy) const {
-  if (FreeRegs >= RegsNeeded) {
-    FreeRegs -= RegsNeeded;
-    return ABIArgInfo::getDirect(DirectTy);
-  }
-
-  llvm::Type *Padding = 0;
-
-  // We need padding so that later arguments don't get filled in anyway. That
-  // wouldn't happen if only ByVal arguments followed in the same category, but
-  // a large structure will simply seem to be a pointer as far as LLVM is
-  // concerned.
-  if (FreeRegs > 0) {
-    if (IsInt)
-      Padding = llvm::Type::getInt64Ty(getVMContext());
-    else
-      Padding = llvm::Type::getFloatTy(getVMContext());
-
-    // Either [N x i64] or [N x float].
-    Padding = llvm::ArrayType::get(Padding, FreeRegs);
-    FreeRegs = 0;
-  }
-
-  return ABIArgInfo::getIndirect(getContext().getTypeAlign(Ty) / 8,
-                                 /*IsByVal=*/ true, /*Realign=*/ false,
-                                 Padding);
-}
-
-
-ABIArgInfo AArch64ABIInfo::classifyGenericType(QualType Ty,
-                                               int &FreeIntRegs,
-                                               int &FreeVFPRegs) const {
-  // Can only occurs for return, but harmless otherwise.
-  if (Ty->isVoidType())
-    return ABIArgInfo::getIgnore();
-
-  // Large vector types should be returned via memory. There's no such concept
-  // in the ABI, but they'd be over 16 bytes anyway so no matter how they're
-  // classified they'd go into memory (see B.3).
-  if (Ty->isVectorType() && getContext().getTypeSize(Ty) > 128) {
-    if (FreeIntRegs > 0)
-      --FreeIntRegs;
-    return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
-  }
-
-  // All non-aggregate LLVM types have a concrete ABI representation so they can
-  // be passed directly. After this block we're guaranteed to be in a
-  // complicated case.
-  if (!isAggregateTypeForABI(Ty)) {
-    // Treat an enum type as its underlying type.
-    if (const EnumType *EnumTy = Ty->getAs<EnumType>())
-      Ty = EnumTy->getDecl()->getIntegerType();
-
-    if (Ty->isFloatingType() || Ty->isVectorType())
-      return tryUseRegs(Ty, FreeVFPRegs, /*RegsNeeded=*/ 1, /*IsInt=*/ false);
-
-    assert(getContext().getTypeSize(Ty) <= 128 &&
-           "unexpectedly large scalar type");
-
-    int RegsNeeded = getContext().getTypeSize(Ty) > 64 ? 2 : 1;
-
-    // If the type may need padding registers to ensure "alignment", we must be
-    // careful when this is accounted for. Increasing the effective size covers
-    // all cases.
-    if (getContext().getTypeAlign(Ty) == 128)
-      RegsNeeded += FreeIntRegs % 2 != 0;
-
-    return tryUseRegs(Ty, FreeIntRegs, RegsNeeded, /*IsInt=*/ true);
-  }
-
-  if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) {
-    if (FreeIntRegs > 0 && RAA == CGCXXABI::RAA_Indirect)
-      --FreeIntRegs;
-    return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory);
-  }
-
-  if (isEmptyRecord(getContext(), Ty, true)) {
-    if (!getContext().getLangOpts().CPlusPlus) {
-      // Empty structs outside C++ mode are a GNU extension, so no ABI can
-      // possibly tell us what to do. It turns out (I believe) that GCC ignores
-      // the object for parameter-passsing purposes.
-      return ABIArgInfo::getIgnore();
-    }
-
-    // The combination of C++98 9p5 (sizeof(struct) != 0) and the pseudocode
-    // description of va_arg in the PCS require that an empty struct does
-    // actually occupy space for parameter-passing. I'm hoping for a
-    // clarification giving an explicit paragraph to point to in future.
-    return tryUseRegs(Ty, FreeIntRegs, /*RegsNeeded=*/ 1, /*IsInt=*/ true,
-                      llvm::Type::getInt8Ty(getVMContext()));
-  }
-
-  // Homogeneous vector aggregates get passed in registers or on the stack.
-  const Type *Base = 0;
-  uint64_t NumMembers = 0;
-  if (isHomogeneousAggregate(Ty, Base, getContext(), &NumMembers)) {
-    assert(Base && "Base class should be set for homogeneous aggregate");
-    // Homogeneous aggregates are passed and returned directly.
-    return tryUseRegs(Ty, FreeVFPRegs, /*RegsNeeded=*/ NumMembers,
-                      /*IsInt=*/ false);
-  }
-
-  uint64_t Size = getContext().getTypeSize(Ty);
-  if (Size <= 128) {
-    // Small structs can use the same direct type whether they're in registers
-    // or on the stack.
-    llvm::Type *BaseTy;
-    unsigned NumBases;
-    int SizeInRegs = (Size + 63) / 64;
-
-    if (getContext().getTypeAlign(Ty) == 128) {
-      BaseTy = llvm::Type::getIntNTy(getVMContext(), 128);
-      NumBases = 1;
-
-      // If the type may need padding registers to ensure "alignment", we must
-      // be careful when this is accounted for. Increasing the effective size
-      // covers all cases.
-      SizeInRegs += FreeIntRegs % 2 != 0;
-    } else {
-      BaseTy = llvm::Type::getInt64Ty(getVMContext());
-      NumBases = SizeInRegs;
-    }
-    llvm::Type *DirectTy = llvm::ArrayType::get(BaseTy, NumBases);
-
-    return tryUseRegs(Ty, FreeIntRegs, /*RegsNeeded=*/ SizeInRegs,
-                      /*IsInt=*/ true, DirectTy);
-  }
-
-  // If the aggregate is > 16 bytes, it's passed and returned indirectly. In
-  // LLVM terms the return uses an "sret" pointer, but that's handled elsewhere.
-  --FreeIntRegs;
-  return ABIArgInfo::getIndirect(0, /* byVal = */ false);
-}
-
-llvm::Value *AArch64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
-                                       CodeGenFunction &CGF) const {
-  // The AArch64 va_list type and handling is specified in the Procedure Call
-  // Standard, section B.4:
-  //
-  // struct {
-  //   void *__stack;
-  //   void *__gr_top;
-  //   void *__vr_top;
-  //   int __gr_offs;
-  //   int __vr_offs;
-  // };
-
-  assert(!CGF.CGM.getDataLayout().isBigEndian()
-         && "va_arg not implemented for big-endian AArch64");
-
-  int FreeIntRegs = 8, FreeVFPRegs = 8;
-  Ty = CGF.getContext().getCanonicalType(Ty);
-  ABIArgInfo AI = classifyGenericType(Ty, FreeIntRegs, FreeVFPRegs);
-
-  llvm::BasicBlock *MaybeRegBlock = CGF.createBasicBlock("vaarg.maybe_reg");
-  llvm::BasicBlock *InRegBlock = CGF.createBasicBlock("vaarg.in_reg");
-  llvm::BasicBlock *OnStackBlock = CGF.createBasicBlock("vaarg.on_stack");
-  llvm::BasicBlock *ContBlock = CGF.createBasicBlock("vaarg.end");
-
-  llvm::Value *reg_offs_p = 0, *reg_offs = 0;
-  int reg_top_index;
-  int RegSize;
-  if (FreeIntRegs < 8) {
-    assert(FreeVFPRegs == 8 && "Arguments never split between int & VFP regs");
-    // 3 is the field number of __gr_offs
-    reg_offs_p = CGF.Builder.CreateStructGEP(VAListAddr, 3, "gr_offs_p");
-    reg_offs = CGF.Builder.CreateLoad(reg_offs_p, "gr_offs");
-    reg_top_index = 1; // field number for __gr_top
-    RegSize = 8 * (8 - FreeIntRegs);
-  } else {
-    assert(FreeVFPRegs < 8 && "Argument must go in VFP or int regs");
-    // 4 is the field number of __vr_offs.
-    reg_offs_p = CGF.Builder.CreateStructGEP(VAListAddr, 4, "vr_offs_p");
-    reg_offs = CGF.Builder.CreateLoad(reg_offs_p, "vr_offs");
-    reg_top_index = 2; // field number for __vr_top
-    RegSize = 16 * (8 - FreeVFPRegs);
-  }
-
-  //=======================================
-  // Find out where argument was passed
-  //=======================================
-
-  // If reg_offs >= 0 we're already using the stack for this type of
-  // argument. We don't want to keep updating reg_offs (in case it overflows,
-  // though anyone passing 2GB of arguments, each at most 16 bytes, deserves
-  // whatever they get).
-  llvm::Value *UsingStack = 0;
-  UsingStack = CGF.Builder.CreateICmpSGE(reg_offs,
-                                         llvm::ConstantInt::get(CGF.Int32Ty, 0));
-
-  CGF.Builder.CreateCondBr(UsingStack, OnStackBlock, MaybeRegBlock);
-
-  // Otherwise, at least some kind of argument could go in these registers, the
-  // quesiton is whether this particular type is too big.
-  CGF.EmitBlock(MaybeRegBlock);
-
-  // Integer arguments may need to correct register alignment (for example a
-  // "struct { __int128 a; };" gets passed in x_2N, x_{2N+1}). In this case we
-  // align __gr_offs to calculate the potential address.
-  if (FreeIntRegs < 8 && AI.isDirect() && getContext().getTypeAlign(Ty) > 64) {
-    int Align = getContext().getTypeAlign(Ty) / 8;
-
-    reg_offs = CGF.Builder.CreateAdd(reg_offs,
-                                 llvm::ConstantInt::get(CGF.Int32Ty, Align - 1),
-                                 "align_regoffs");
-    reg_offs = CGF.Builder.CreateAnd(reg_offs,
-                                    llvm::ConstantInt::get(CGF.Int32Ty, -Align),
-                                    "aligned_regoffs");
-  }
-
-  // Update the gr_offs/vr_offs pointer for next call to va_arg on this va_list.
-  llvm::Value *NewOffset = 0;
-  NewOffset = CGF.Builder.CreateAdd(reg_offs,
-                                    llvm::ConstantInt::get(CGF.Int32Ty, RegSize),
-                                    "new_reg_offs");
-  CGF.Builder.CreateStore(NewOffset, reg_offs_p);
-
-  // Now we're in a position to decide whether this argument really was in
-  // registers or not.
-  llvm::Value *InRegs = 0;
-  InRegs = CGF.Builder.CreateICmpSLE(NewOffset,
-                                     llvm::ConstantInt::get(CGF.Int32Ty, 0),
-                                     "inreg");
-
-  CGF.Builder.CreateCondBr(InRegs, InRegBlock, OnStackBlock);
-
-  //=======================================
-  // Argument was in registers
-  //=======================================
-
-  // Now we emit the code for if the argument was originally passed in
-  // registers. First start the appropriate block:
-  CGF.EmitBlock(InRegBlock);
-
-  llvm::Value *reg_top_p = 0, *reg_top = 0;
-  reg_top_p = CGF.Builder.CreateStructGEP(VAListAddr, reg_top_index, "reg_top_p");
-  reg_top = CGF.Builder.CreateLoad(reg_top_p, "reg_top");
-  llvm::Value *BaseAddr = CGF.Builder.CreateGEP(reg_top, reg_offs);
-  llvm::Value *RegAddr = 0;
-  llvm::Type *MemTy = llvm::PointerType::getUnqual(CGF.ConvertTypeForMem(Ty));
-
-  if (!AI.isDirect()) {
-    // If it's been passed indirectly (actually a struct), whatever we find from
-    // stored registers or on the stack will actually be a struct **.
-    MemTy = llvm::PointerType::getUnqual(MemTy);
-  }
-
-  const Type *Base = 0;
-  uint64_t NumMembers;
-  if (isHomogeneousAggregate(Ty, Base, getContext(), &NumMembers)
-      && NumMembers > 1) {
-    // Homogeneous aggregates passed in registers will have their elements split
-    // and stored 16-bytes apart regardless of size (they're notionally in qN,
-    // qN+1, ...). We reload and store into a temporary local variable
-    // contiguously.
-    assert(AI.isDirect() && "Homogeneous aggregates should be passed directly");
-    llvm::Type *BaseTy = CGF.ConvertType(QualType(Base, 0));
-    llvm::Type *HFATy = llvm::ArrayType::get(BaseTy, NumMembers);
-    llvm::Value *Tmp = CGF.CreateTempAlloca(HFATy);
-
-    for (unsigned i = 0; i < NumMembers; ++i) {
-      llvm::Value *BaseOffset = llvm::ConstantInt::get(CGF.Int32Ty, 16 * i);
-      llvm::Value *LoadAddr = CGF.Builder.CreateGEP(BaseAddr, BaseOffset);
-      LoadAddr = CGF.Builder.CreateBitCast(LoadAddr,
-                                           llvm::PointerType::getUnqual(BaseTy));
-      llvm::Value *StoreAddr = CGF.Builder.CreateStructGEP(Tmp, i);
-
-      llvm::Value *Elem = CGF.Builder.CreateLoad(LoadAddr);
-      CGF.Builder.CreateStore(Elem, StoreAddr);
-    }
-
-    RegAddr = CGF.Builder.CreateBitCast(Tmp, MemTy);
-  } else {
-    // Otherwise the object is contiguous in memory
-    RegAddr = CGF.Builder.CreateBitCast(BaseAddr, MemTy);
-  }
-
-  CGF.EmitBranch(ContBlock);
-
-  //=======================================
-  // Argument was on the stack
-  //=======================================
-  CGF.EmitBlock(OnStackBlock);
-
-  llvm::Value *stack_p = 0, *OnStackAddr = 0;
-  stack_p = CGF.Builder.CreateStructGEP(VAListAddr, 0, "stack_p");
-  OnStackAddr = CGF.Builder.CreateLoad(stack_p, "stack");
-
-  // Again, stack arguments may need realigmnent. In this case both integer and
-  // floating-point ones might be affected.
-  if (AI.isDirect() && getContext().getTypeAlign(Ty) > 64) {
-    int Align = getContext().getTypeAlign(Ty) / 8;
-
-    OnStackAddr = CGF.Builder.CreatePtrToInt(OnStackAddr, CGF.Int64Ty);
-
-    OnStackAddr = CGF.Builder.CreateAdd(OnStackAddr,
-                                 llvm::ConstantInt::get(CGF.Int64Ty, Align - 1),
-                                 "align_stack");
-    OnStackAddr = CGF.Builder.CreateAnd(OnStackAddr,
-                                    llvm::ConstantInt::get(CGF.Int64Ty, -Align),
-                                    "align_stack");
-
-    OnStackAddr = CGF.Builder.CreateIntToPtr(OnStackAddr, CGF.Int8PtrTy);
-  }
-
-  uint64_t StackSize;
-  if (AI.isDirect())
-    StackSize = getContext().getTypeSize(Ty) / 8;
-  else
-    StackSize = 8;
-
-  // All stack slots are 8 bytes
-  StackSize = llvm::RoundUpToAlignment(StackSize, 8);
-
-  llvm::Value *StackSizeC = llvm::ConstantInt::get(CGF.Int32Ty, StackSize);
-  llvm::Value *NewStack = CGF.Builder.CreateGEP(OnStackAddr, StackSizeC,
-                                                "new_stack");
-
-  // Write the new value of __stack for the next call to va_arg
-  CGF.Builder.CreateStore(NewStack, stack_p);
-
-  OnStackAddr = CGF.Builder.CreateBitCast(OnStackAddr, MemTy);
-
-  CGF.EmitBranch(ContBlock);
-
-  //=======================================
-  // Tidy up
-  //=======================================
-  CGF.EmitBlock(ContBlock);
-
-  llvm::PHINode *ResAddr = CGF.Builder.CreatePHI(MemTy, 2, "vaarg.addr");
-  ResAddr->addIncoming(RegAddr, InRegBlock);
-  ResAddr->addIncoming(OnStackAddr, OnStackBlock);
-
-  if (AI.isDirect())
-    return ResAddr;
-
-  return CGF.Builder.CreateLoad(ResAddr, "vaarg.addr");
-}
-
-//===----------------------------------------------------------------------===//
 // NVPTX ABI Implementation
 //===----------------------------------------------------------------------===//
 
@@ -4235,42 +4909,54 @@
   ABIArgInfo classifyReturnType(QualType RetTy) const;
   ABIArgInfo classifyArgumentType(QualType Ty) const;
 
-  virtual void computeInfo(CGFunctionInfo &FI) const;
-  virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
-                                 CodeGenFunction &CFG) const;
+  void computeInfo(CGFunctionInfo &FI) const override;
+  llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+                         CodeGenFunction &CFG) const override;
 };
 
 class NVPTXTargetCodeGenInfo : public TargetCodeGenInfo {
 public:
   NVPTXTargetCodeGenInfo(CodeGenTypes &CGT)
     : TargetCodeGenInfo(new NVPTXABIInfo(CGT)) {}
-    
-  virtual void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
-                                   CodeGen::CodeGenModule &M) const;
+
+  void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
+                           CodeGen::CodeGenModule &M) const override;
 private:
-  static void addKernelMetadata(llvm::Function *F);
+  // Adds a NamedMDNode with F, Name, and Operand as operands, and adds the
+  // resulting MDNode to the nvvm.annotations MDNode.
+  static void addNVVMMetadata(llvm::Function *F, StringRef Name, int Operand);
 };
 
 ABIArgInfo NVPTXABIInfo::classifyReturnType(QualType RetTy) const {
   if (RetTy->isVoidType())
     return ABIArgInfo::getIgnore();
-  if (isAggregateTypeForABI(RetTy))
-    return ABIArgInfo::getIndirect(0);
-  return ABIArgInfo::getDirect();
+
+  // note: this is different from default ABI
+  if (!RetTy->isScalarType())
+    return ABIArgInfo::getDirect();
+
+  // Treat an enum type as its underlying type.
+  if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
+    RetTy = EnumTy->getDecl()->getIntegerType();
+
+  return (RetTy->isPromotableIntegerType() ?
+          ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
 }
 
 ABIArgInfo NVPTXABIInfo::classifyArgumentType(QualType Ty) const {
-  if (isAggregateTypeForABI(Ty))
-    return ABIArgInfo::getIndirect(0);
+  // Treat an enum type as its underlying type.
+  if (const EnumType *EnumTy = Ty->getAs<EnumType>())
+    Ty = EnumTy->getDecl()->getIntegerType();
 
-  return ABIArgInfo::getDirect();
+  return (Ty->isPromotableIntegerType() ?
+          ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
 }
 
 void NVPTXABIInfo::computeInfo(CGFunctionInfo &FI) const {
-  FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
-  for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
-       it != ie; ++it)
-    it->info = classifyArgumentType(it->type);
+  if (!getCXXABI().classifyReturnType(FI))
+    FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
+  for (auto &I : FI.arguments())
+    I.info = classifyArgumentType(I.type);
 
   // Always honor user-specified calling convention.
   if (FI.getCallingConvention() != llvm::CallingConv::C)
@@ -4298,7 +4984,8 @@
     // By default, all functions are device functions
     if (FD->hasAttr<OpenCLKernelAttr>()) {
       // OpenCL __kernel functions get kernel metadata
-      addKernelMetadata(F);
+      // Create !{<func-ref>, metadata !"kernel", i32 1} node
+      addNVVMMetadata(F, "kernel", 1);
       // And kernel functions are not subject to inlining
       F->addFnAttr(llvm::Attribute::NoInline);
     }
@@ -4309,28 +4996,41 @@
     // CUDA __global__ functions get a kernel metadata entry.  Since
     // __global__ functions cannot be called from the device, we do not
     // need to set the noinline attribute.
-    if (FD->getAttr<CUDAGlobalAttr>())
-      addKernelMetadata(F);
+    if (FD->hasAttr<CUDAGlobalAttr>()) {
+      // Create !{<func-ref>, metadata !"kernel", i32 1} node
+      addNVVMMetadata(F, "kernel", 1);
+    }
+    if (FD->hasAttr<CUDALaunchBoundsAttr>()) {
+      // Create !{<func-ref>, metadata !"maxntidx", i32 <val>} node
+      addNVVMMetadata(F, "maxntidx",
+                      FD->getAttr<CUDALaunchBoundsAttr>()->getMaxThreads());
+      // min blocks is a default argument for CUDALaunchBoundsAttr, so getting a
+      // zero value from getMinBlocks either means it was not specified in
+      // __launch_bounds__ or the user specified a 0 value. In both cases, we
+      // don't have to add a PTX directive.
+      int MinCTASM = FD->getAttr<CUDALaunchBoundsAttr>()->getMinBlocks();
+      if (MinCTASM > 0) {
+        // Create !{<func-ref>, metadata !"minctasm", i32 <val>} node
+        addNVVMMetadata(F, "minctasm", MinCTASM);
+      }
+    }
   }
 }
 
-void NVPTXTargetCodeGenInfo::addKernelMetadata(llvm::Function *F) {
+void NVPTXTargetCodeGenInfo::addNVVMMetadata(llvm::Function *F, StringRef Name,
+                                             int Operand) {
   llvm::Module *M = F->getParent();
   llvm::LLVMContext &Ctx = M->getContext();
 
   // Get "nvvm.annotations" metadata node
   llvm::NamedMDNode *MD = M->getOrInsertNamedMetadata("nvvm.annotations");
 
-  // Create !{<func-ref>, metadata !"kernel", i32 1} node
-  llvm::SmallVector<llvm::Value *, 3> MDVals;
-  MDVals.push_back(F);
-  MDVals.push_back(llvm::MDString::get(Ctx, "kernel"));
-  MDVals.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(Ctx), 1));
-
+  llvm::Value *MDVals[] = {
+      F, llvm::MDString::get(Ctx, Name),
+      llvm::ConstantInt::get(llvm::Type::getInt32Ty(Ctx), Operand)};
   // Append metadata to nvvm.annotations
   MD->addOperand(llvm::MDNode::get(Ctx, MDVals));
 }
-
 }
 
 //===----------------------------------------------------------------------===//
@@ -4350,15 +5050,15 @@
   ABIArgInfo classifyReturnType(QualType RetTy) const;
   ABIArgInfo classifyArgumentType(QualType ArgTy) const;
 
-  virtual void computeInfo(CGFunctionInfo &FI) const {
-    FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
-    for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
-         it != ie; ++it)
-      it->info = classifyArgumentType(it->type);
+  void computeInfo(CGFunctionInfo &FI) const override {
+    if (!getCXXABI().classifyReturnType(FI))
+      FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
+    for (auto &I : FI.arguments())
+      I.info = classifyArgumentType(I.type);
   }
 
-  virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
-                                 CodeGenFunction &CGF) const;
+  llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+                         CodeGenFunction &CGF) const override;
 };
 
 class SystemZTargetCodeGenInfo : public TargetCodeGenInfo {
@@ -4410,9 +5110,8 @@
 
     // If this is a C++ record, check the bases first.
     if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
-      for (CXXRecordDecl::base_class_const_iterator I = CXXRD->bases_begin(),
-             E = CXXRD->bases_end(); I != E; ++I) {
-        QualType Base = I->getType();
+      for (const auto &I : CXXRD->bases()) {
+        QualType Base = I.getType();
 
         // Empty bases don't affect things either way.
         if (isEmptyRecord(getContext(), Base, true))
@@ -4426,10 +5125,7 @@
       }
 
     // Check the fields.
-    for (RecordDecl::field_iterator I = RD->field_begin(),
-           E = RD->field_end(); I != E; ++I) {
-      const FieldDecl *FD = *I;
-
+    for (const auto *FD : RD->fields()) {
       // Empty bitfields don't affect things either way.
       // Unlike isSingleElementStruct(), empty structure and array fields
       // do count.  So do anonymous bitfields that aren't zero-sized.
@@ -4502,7 +5198,7 @@
   llvm::Type *IndexTy = RegCount->getType();
   llvm::Value *MaxRegsV = llvm::ConstantInt::get(IndexTy, MaxRegs);
   llvm::Value *InRegs = CGF.Builder.CreateICmpULT(RegCount, MaxRegsV,
-						  "fits_in_regs");
+                                                 "fits_in_regs");
 
   llvm::BasicBlock *InRegBlock = CGF.createBasicBlock("vaarg.in_reg");
   llvm::BasicBlock *InMemBlock = CGF.createBasicBlock("vaarg.in_mem");
@@ -4568,37 +5264,6 @@
   return ResAddr;
 }
 
-bool X86_32TargetCodeGenInfo::isStructReturnInRegABI(
-    const llvm::Triple &Triple, const CodeGenOptions &Opts) {
-  assert(Triple.getArch() == llvm::Triple::x86);
-
-  switch (Opts.getStructReturnConvention()) {
-  case CodeGenOptions::SRCK_Default:
-    break;
-  case CodeGenOptions::SRCK_OnStack:  // -fpcc-struct-return
-    return false;
-  case CodeGenOptions::SRCK_InRegs:  // -freg-struct-return
-    return true;
-  }
-
-  if (Triple.isOSDarwin())
-    return true;
-
-  switch (Triple.getOS()) {
-  case llvm::Triple::Cygwin:
-  case llvm::Triple::MinGW32:
-  case llvm::Triple::AuroraUX:
-  case llvm::Triple::DragonFly:
-  case llvm::Triple::FreeBSD:
-  case llvm::Triple::OpenBSD:
-  case llvm::Triple::Bitrig:
-  case llvm::Triple::Win32:
-    return true;
-  default:
-    return false;
-  }
-}
-
 ABIArgInfo SystemZABIInfo::classifyReturnType(QualType RetTy) const {
   if (RetTy->isVoidType())
     return ABIArgInfo::getIgnore();
@@ -4620,7 +5285,7 @@
   // Values that are not 1, 2, 4 or 8 bytes in size are passed indirectly.
   uint64_t Size = getContext().getTypeSize(Ty);
   if (Size != 8 && Size != 16 && Size != 32 && Size != 64)
-    return ABIArgInfo::getIndirect(0);
+    return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
 
   // Handle small structures.
   if (const RecordType *RT = Ty->getAs<RecordType>()) {
@@ -4628,7 +5293,7 @@
     // fail the size test above.
     const RecordDecl *RD = RT->getDecl();
     if (RD->hasFlexibleArrayMember())
-      return ABIArgInfo::getIndirect(0);
+      return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
 
     // The structure is passed as an unextended integer, a float, or a double.
     llvm::Type *PassTy;
@@ -4645,9 +5310,9 @@
 
   // Non-structure compounds are passed indirectly.
   if (isCompoundType(Ty))
-    return ABIArgInfo::getIndirect(0);
+    return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
 
-  return ABIArgInfo::getDirect(0);
+  return ABIArgInfo::getDirect(nullptr);
 }
 
 //===----------------------------------------------------------------------===//
@@ -4661,7 +5326,7 @@
   MSP430TargetCodeGenInfo(CodeGenTypes &CGT)
     : TargetCodeGenInfo(new DefaultABIInfo(CGT)) {}
   void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
-                           CodeGen::CodeGenModule &M) const;
+                           CodeGen::CodeGenModule &M) const override;
 };
 
 }
@@ -4682,9 +5347,8 @@
 
       // Step 3: Emit ISR vector alias.
       unsigned Num = attr->getNumber() / 2;
-      new llvm::GlobalAlias(GV->getType(), llvm::Function::ExternalLinkage,
-                            "__isr_" + Twine(Num),
-                            GV, &M.getModule());
+      llvm::GlobalAlias::create(llvm::Function::ExternalLinkage,
+                                "__isr_" + Twine(Num), F);
     }
   }
 }
@@ -4710,9 +5374,9 @@
 
   ABIArgInfo classifyReturnType(QualType RetTy) const;
   ABIArgInfo classifyArgumentType(QualType RetTy, uint64_t &Offset) const;
-  virtual void computeInfo(CGFunctionInfo &FI) const;
-  virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
-                                 CodeGenFunction &CGF) const;
+  void computeInfo(CGFunctionInfo &FI) const override;
+  llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+                         CodeGenFunction &CGF) const override;
 };
 
 class MIPSTargetCodeGenInfo : public TargetCodeGenInfo {
@@ -4722,12 +5386,12 @@
     : TargetCodeGenInfo(new MipsABIInfo(CGT, IsO32)),
       SizeOfUnwindException(IsO32 ? 24 : 32) {}
 
-  int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const {
+  int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const override {
     return 29;
   }
 
   void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
-                           CodeGen::CodeGenModule &CGM) const {
+                           CodeGen::CodeGenModule &CGM) const override {
     const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
     if (!FD) return;
     llvm::Function *Fn = cast<llvm::Function>(GV);
@@ -4740,9 +5404,9 @@
   }
 
   bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
-                               llvm::Value *Address) const;
+                               llvm::Value *Address) const override;
 
-  unsigned getSizeOfUnwindException() const {
+  unsigned getSizeOfUnwindException() const override {
     return SizeOfUnwindException;
   }
 };
@@ -4825,7 +5489,7 @@
 llvm::Type *MipsABIInfo::getPaddingType(uint64_t OrigOffset,
                                         uint64_t Offset) const {
   if (OrigOffset + MinABIStackAlignInBytes > Offset)
-    return 0;
+    return nullptr;
 
   return llvm::IntegerType::get(getVMContext(), (Offset - OrigOffset) * 8);
 }
@@ -4866,7 +5530,7 @@
     return ABIArgInfo::getExtend();
 
   return ABIArgInfo::getDirect(
-      0, 0, IsO32 ? 0 : getPaddingType(OrigOffset, CurrOffset));
+      nullptr, 0, IsO32 ? nullptr : getPaddingType(OrigOffset, CurrOffset));
 }
 
 llvm::Type*
@@ -4918,9 +5582,6 @@
     return ABIArgInfo::getIgnore();
 
   if (isAggregateTypeForABI(RetTy) || RetTy->isVectorType()) {
-    if (isRecordReturnIndirect(RetTy, getCXXABI()))
-      return ABIArgInfo::getIndirect(0);
-
     if (Size <= 128) {
       if (RetTy->isAnyComplexType())
         return ABIArgInfo::getDirect();
@@ -4946,14 +5607,14 @@
 
 void MipsABIInfo::computeInfo(CGFunctionInfo &FI) const {
   ABIArgInfo &RetInfo = FI.getReturnInfo();
-  RetInfo = classifyReturnType(FI.getReturnType());
+  if (!getCXXABI().classifyReturnType(FI))
+    RetInfo = classifyReturnType(FI.getReturnType());
 
   // Check if a pointer to an aggregate is passed as a hidden argument.  
   uint64_t Offset = RetInfo.isIndirect() ? MinABIStackAlignInBytes : 0;
 
-  for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
-       it != ie; ++it)
-    it->info = classifyArgumentType(it->type, Offset);
+  for (auto &I : FI.arguments())
+    I.info = classifyArgumentType(I.type, Offset);
 }
 
 llvm::Value* MipsABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
@@ -5034,8 +5695,8 @@
   TCETargetCodeGenInfo(CodeGenTypes &CGT)
     : DefaultTargetCodeGenInfo(CGT) {}
 
-  virtual void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
-                                   CodeGen::CodeGenModule &M) const;
+  void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
+                           CodeGen::CodeGenModule &M) const override;
 };
 
 void TCETargetCodeGenInfo::SetTargetAttributes(const Decl *D,
@@ -5050,9 +5711,8 @@
     if (FD->hasAttr<OpenCLKernelAttr>()) {
       // OpenCL C Kernel functions are not subject to inlining
       F->addFnAttr(llvm::Attribute::NoInline);
-          
-      if (FD->hasAttr<ReqdWorkGroupSizeAttr>()) {
-
+      const ReqdWorkGroupSizeAttr *Attr = FD->getAttr<ReqdWorkGroupSizeAttr>();
+      if (Attr) {
         // Convert the reqd_work_group_size() attributes to metadata.
         llvm::LLVMContext &Context = F->getContext();
         llvm::NamedMDNode *OpenCLMetadata = 
@@ -5062,14 +5722,11 @@
         Operands.push_back(F);
 
         Operands.push_back(llvm::Constant::getIntegerValue(M.Int32Ty, 
-                             llvm::APInt(32, 
-                             FD->getAttr<ReqdWorkGroupSizeAttr>()->getXDim())));
+                             llvm::APInt(32, Attr->getXDim())));
         Operands.push_back(llvm::Constant::getIntegerValue(M.Int32Ty,
-                             llvm::APInt(32,
-                               FD->getAttr<ReqdWorkGroupSizeAttr>()->getYDim())));
+                             llvm::APInt(32, Attr->getYDim())));
         Operands.push_back(llvm::Constant::getIntegerValue(M.Int32Ty, 
-                             llvm::APInt(32, 
-                               FD->getAttr<ReqdWorkGroupSizeAttr>()->getZDim())));
+                             llvm::APInt(32, Attr->getZDim())));
 
         // Add a boolean constant operand for "required" (true) or "hint" (false)
         // for implementing the work_group_size_hint attr later. Currently 
@@ -5100,10 +5757,10 @@
   ABIArgInfo classifyReturnType(QualType RetTy) const;
   ABIArgInfo classifyArgumentType(QualType RetTy) const;
 
-  virtual void computeInfo(CGFunctionInfo &FI) const;
+  void computeInfo(CGFunctionInfo &FI) const override;
 
-  virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
-                                 CodeGenFunction &CGF) const;
+  llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+                         CodeGenFunction &CGF) const override;
 };
 
 class HexagonTargetCodeGenInfo : public TargetCodeGenInfo {
@@ -5111,7 +5768,7 @@
   HexagonTargetCodeGenInfo(CodeGenTypes &CGT)
     :TargetCodeGenInfo(new HexagonABIInfo(CGT)) {}
 
-  int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const {
+  int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override {
     return 29;
   }
 };
@@ -5119,10 +5776,10 @@
 }
 
 void HexagonABIInfo::computeInfo(CGFunctionInfo &FI) const {
-  FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
-  for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
-       it != ie; ++it)
-    it->info = classifyArgumentType(it->type);
+  if (!getCXXABI().classifyReturnType(FI))
+    FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
+  for (auto &I : FI.arguments())
+    I.info = classifyArgumentType(I.type);
 }
 
 ABIArgInfo HexagonABIInfo::classifyArgumentType(QualType Ty) const {
@@ -5173,11 +5830,6 @@
             ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
   }
 
-  // Structures with either a non-trivial destructor or a non-trivial
-  // copy constructor are always indirect.
-  if (isRecordReturnIndirect(RetTy, getCXXABI()))
-    return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
-
   if (isEmptyRecord(getContext(), RetTy, true))
     return ABIArgInfo::getIgnore();
 
@@ -5255,9 +5907,9 @@
 
 private:
   ABIArgInfo classifyType(QualType RetTy, unsigned SizeLimit) const;
-  virtual void computeInfo(CGFunctionInfo &FI) const;
-  virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
-                                 CodeGenFunction &CGF) const;
+  void computeInfo(CGFunctionInfo &FI) const override;
+  llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+                         CodeGenFunction &CGF) const override;
 
   // Coercion type builder for structs passed in registers. The coercion type
   // serves two purposes:
@@ -5396,6 +6048,11 @@
   if (!isAggregateTypeForABI(Ty))
     return ABIArgInfo::getDirect();
 
+  // If a C++ object has either a non-trivial copy constructor or a non-trivial
+  // destructor, it is passed with an explicit indirect pointer / sret pointer.
+  if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI()))
+    return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory);
+
   // This is a small aggregate type that should be passed in registers.
   // Build a coercion type from the LLVM struct type.
   llvm::StructType *StrTy = dyn_cast<llvm::StructType>(CGT.ConvertType(Ty));
@@ -5432,6 +6089,7 @@
 
   switch (AI.getKind()) {
   case ABIArgInfo::Expand:
+  case ABIArgInfo::InAlloca:
     llvm_unreachable("Unsupported ABI kind for va_arg");
 
   case ABIArgInfo::Extend:
@@ -5467,9 +6125,8 @@
 
 void SparcV9ABIInfo::computeInfo(CGFunctionInfo &FI) const {
   FI.getReturnInfo() = classifyType(FI.getReturnType(), 32 * 8);
-  for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
-       it != ie; ++it)
-    it->info = classifyType(it->type, 16 * 8);
+  for (auto &I : FI.arguments())
+    I.info = classifyType(I.type, 16 * 8);
 }
 
 namespace {
@@ -5477,26 +6134,165 @@
 public:
   SparcV9TargetCodeGenInfo(CodeGenTypes &CGT)
     : TargetCodeGenInfo(new SparcV9ABIInfo(CGT)) {}
+
+  int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override {
+    return 14;
+  }
+
+  bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
+                               llvm::Value *Address) const override;
 };
 } // end anonymous namespace
 
+bool
+SparcV9TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
+                                                llvm::Value *Address) const {
+  // This is calculated from the LLVM and GCC tables and verified
+  // against gcc output.  AFAIK all ABIs use the same encoding.
+
+  CodeGen::CGBuilderTy &Builder = CGF.Builder;
+
+  llvm::IntegerType *i8 = CGF.Int8Ty;
+  llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4);
+  llvm::Value *Eight8 = llvm::ConstantInt::get(i8, 8);
+
+  // 0-31: the 8-byte general-purpose registers
+  AssignToArrayRange(Builder, Address, Eight8, 0, 31);
+
+  // 32-63: f0-31, the 4-byte floating-point registers
+  AssignToArrayRange(Builder, Address, Four8, 32, 63);
+
+  //   Y   = 64
+  //   PSR = 65
+  //   WIM = 66
+  //   TBR = 67
+  //   PC  = 68
+  //   NPC = 69
+  //   FSR = 70
+  //   CSR = 71
+  AssignToArrayRange(Builder, Address, Eight8, 64, 71);
+   
+  // 72-87: d0-15, the 8-byte floating-point registers
+  AssignToArrayRange(Builder, Address, Eight8, 72, 87);
+
+  return false;
+}
+
 
 //===----------------------------------------------------------------------===//
-// Xcore ABI Implementation
+// XCore ABI Implementation
 //===----------------------------------------------------------------------===//
+
 namespace {
+
+/// A SmallStringEnc instance is used to build up the TypeString by passing
+/// it by reference between functions that append to it.
+typedef llvm::SmallString<128> SmallStringEnc;
+
+/// TypeStringCache caches the meta encodings of Types.
+///
+/// The reason for caching TypeStrings is two fold:
+///   1. To cache a type's encoding for later uses;
+///   2. As a means to break recursive member type inclusion.
+///
+/// A cache Entry can have a Status of:
+///   NonRecursive:   The type encoding is not recursive;
+///   Recursive:      The type encoding is recursive;
+///   Incomplete:     An incomplete TypeString;
+///   IncompleteUsed: An incomplete TypeString that has been used in a
+///                   Recursive type encoding.
+///
+/// A NonRecursive entry will have all of its sub-members expanded as fully
+/// as possible. Whilst it may contain types which are recursive, the type
+/// itself is not recursive and thus its encoding may be safely used whenever
+/// the type is encountered.
+///
+/// A Recursive entry will have all of its sub-members expanded as fully as
+/// possible. The type itself is recursive and it may contain other types which
+/// are recursive. The Recursive encoding must not be used during the expansion
+/// of a recursive type's recursive branch. For simplicity the code uses
+/// IncompleteCount to reject all usage of Recursive encodings for member types.
+///
+/// An Incomplete entry is always a RecordType and only encodes its
+/// identifier e.g. "s(S){}". Incomplete 'StubEnc' entries are ephemeral and
+/// are placed into the cache during type expansion as a means to identify and
+/// handle recursive inclusion of types as sub-members. If there is recursion
+/// the entry becomes IncompleteUsed.
+///
+/// During the expansion of a RecordType's members:
+///
+///   If the cache contains a NonRecursive encoding for the member type, the
+///   cached encoding is used;
+///
+///   If the cache contains a Recursive encoding for the member type, the
+///   cached encoding is 'Swapped' out, as it may be incorrect, and...
+///
+///   If the member is a RecordType, an Incomplete encoding is placed into the
+///   cache to break potential recursive inclusion of itself as a sub-member;
+///
+///   Once a member RecordType has been expanded, its temporary incomplete
+///   entry is removed from the cache. If a Recursive encoding was swapped out
+///   it is swapped back in;
+///
+///   If an incomplete entry is used to expand a sub-member, the incomplete
+///   entry is marked as IncompleteUsed. The cache keeps count of how many
+///   IncompleteUsed entries it currently contains in IncompleteUsedCount;
+///
+///   If a member's encoding is found to be a NonRecursive or Recursive viz:
+///   IncompleteUsedCount==0, the member's encoding is added to the cache.
+///   Else the member is part of a recursive type and thus the recursion has
+///   been exited too soon for the encoding to be correct for the member.
+///
+class TypeStringCache {
+  enum Status {NonRecursive, Recursive, Incomplete, IncompleteUsed};
+  struct Entry {
+    std::string Str;     // The encoded TypeString for the type.
+    enum Status State;   // Information about the encoding in 'Str'.
+    std::string Swapped; // A temporary place holder for a Recursive encoding
+                         // during the expansion of RecordType's members.
+  };
+  std::map<const IdentifierInfo *, struct Entry> Map;
+  unsigned IncompleteCount;     // Number of Incomplete entries in the Map.
+  unsigned IncompleteUsedCount; // Number of IncompleteUsed entries in the Map.
+public:
+  TypeStringCache() : IncompleteCount(0), IncompleteUsedCount(0) {};
+  void addIncomplete(const IdentifierInfo *ID, std::string StubEnc);
+  bool removeIncomplete(const IdentifierInfo *ID);
+  void addIfComplete(const IdentifierInfo *ID, StringRef Str,
+                     bool IsRecursive);
+  StringRef lookupStr(const IdentifierInfo *ID);
+};
+
+/// TypeString encodings for enum & union fields must be order.
+/// FieldEncoding is a helper for this ordering process.
+class FieldEncoding {
+  bool HasName;
+  std::string Enc;
+public:
+  FieldEncoding(bool b, SmallStringEnc &e) : HasName(b), Enc(e.c_str()) {};
+  StringRef str() {return Enc.c_str();};
+  bool operator<(const FieldEncoding &rhs) const {
+    if (HasName != rhs.HasName) return HasName;
+    return Enc < rhs.Enc;
+  }
+};
+
 class XCoreABIInfo : public DefaultABIInfo {
 public:
   XCoreABIInfo(CodeGen::CodeGenTypes &CGT) : DefaultABIInfo(CGT) {}
-  virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
-                                 CodeGenFunction &CGF) const;
+  llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+                         CodeGenFunction &CGF) const override;
 };
 
-class XcoreTargetCodeGenInfo : public TargetCodeGenInfo {
+class XCoreTargetCodeGenInfo : public TargetCodeGenInfo {
+  mutable TypeStringCache TSC;
 public:
-  XcoreTargetCodeGenInfo(CodeGenTypes &CGT)
+  XCoreTargetCodeGenInfo(CodeGenTypes &CGT)
     :TargetCodeGenInfo(new XCoreABIInfo(CGT)) {}
+  void emitTargetMD(const Decl *D, llvm::GlobalValue *GV,
+                    CodeGen::CodeGenModule &M) const override;
 };
+
 } // End anonymous namespace.
 
 llvm::Value *XCoreABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
@@ -5518,6 +6314,7 @@
   uint64_t ArgSize = 0;
   switch (AI.getKind()) {
   case ABIArgInfo::Expand:
+  case ABIArgInfo::InAlloca:
     llvm_unreachable("Unsupported ABI kind for va_arg");
   case ABIArgInfo::Ignore:
     Val = llvm::UndefValue::get(ArgPtrTy);
@@ -5547,6 +6344,461 @@
   return Val;
 }
 
+/// During the expansion of a RecordType, an incomplete TypeString is placed
+/// into the cache as a means to identify and break recursion.
+/// If there is a Recursive encoding in the cache, it is swapped out and will
+/// be reinserted by removeIncomplete().
+/// All other types of encoding should have been used rather than arriving here.
+void TypeStringCache::addIncomplete(const IdentifierInfo *ID,
+                                    std::string StubEnc) {
+  if (!ID)
+    return;
+  Entry &E = Map[ID];
+  assert( (E.Str.empty() || E.State == Recursive) &&
+         "Incorrectly use of addIncomplete");
+  assert(!StubEnc.empty() && "Passing an empty string to addIncomplete()");
+  E.Swapped.swap(E.Str); // swap out the Recursive
+  E.Str.swap(StubEnc);
+  E.State = Incomplete;
+  ++IncompleteCount;
+}
+
+/// Once the RecordType has been expanded, the temporary incomplete TypeString
+/// must be removed from the cache.
+/// If a Recursive was swapped out by addIncomplete(), it will be replaced.
+/// Returns true if the RecordType was defined recursively.
+bool TypeStringCache::removeIncomplete(const IdentifierInfo *ID) {
+  if (!ID)
+    return false;
+  auto I = Map.find(ID);
+  assert(I != Map.end() && "Entry not present");
+  Entry &E = I->second;
+  assert( (E.State == Incomplete ||
+           E.State == IncompleteUsed) &&
+         "Entry must be an incomplete type");
+  bool IsRecursive = false;
+  if (E.State == IncompleteUsed) {
+    // We made use of our Incomplete encoding, thus we are recursive.
+    IsRecursive = true;
+    --IncompleteUsedCount;
+  }
+  if (E.Swapped.empty())
+    Map.erase(I);
+  else {
+    // Swap the Recursive back.
+    E.Swapped.swap(E.Str);
+    E.Swapped.clear();
+    E.State = Recursive;
+  }
+  --IncompleteCount;
+  return IsRecursive;
+}
+
+/// Add the encoded TypeString to the cache only if it is NonRecursive or
+/// Recursive (viz: all sub-members were expanded as fully as possible).
+void TypeStringCache::addIfComplete(const IdentifierInfo *ID, StringRef Str,
+                                    bool IsRecursive) {
+  if (!ID || IncompleteUsedCount)
+    return; // No key or it is is an incomplete sub-type so don't add.
+  Entry &E = Map[ID];
+  if (IsRecursive && !E.Str.empty()) {
+    assert(E.State==Recursive && E.Str.size() == Str.size() &&
+           "This is not the same Recursive entry");
+    // The parent container was not recursive after all, so we could have used
+    // this Recursive sub-member entry after all, but we assumed the worse when
+    // we started viz: IncompleteCount!=0.
+    return;
+  }
+  assert(E.Str.empty() && "Entry already present");
+  E.Str = Str.str();
+  E.State = IsRecursive? Recursive : NonRecursive;
+}
+
+/// Return a cached TypeString encoding for the ID. If there isn't one, or we
+/// are recursively expanding a type (IncompleteCount != 0) and the cached
+/// encoding is Recursive, return an empty StringRef.
+StringRef TypeStringCache::lookupStr(const IdentifierInfo *ID) {
+  if (!ID)
+    return StringRef();   // We have no key.
+  auto I = Map.find(ID);
+  if (I == Map.end())
+    return StringRef();   // We have no encoding.
+  Entry &E = I->second;
+  if (E.State == Recursive && IncompleteCount)
+    return StringRef();   // We don't use Recursive encodings for member types.
+
+  if (E.State == Incomplete) {
+    // The incomplete type is being used to break out of recursion.
+    E.State = IncompleteUsed;
+    ++IncompleteUsedCount;
+  }
+  return E.Str.c_str();
+}
+
+/// The XCore ABI includes a type information section that communicates symbol
+/// type information to the linker. The linker uses this information to verify
+/// safety/correctness of things such as array bound and pointers et al.
+/// The ABI only requires C (and XC) language modules to emit TypeStrings.
+/// This type information (TypeString) is emitted into meta data for all global
+/// symbols: definitions, declarations, functions & variables.
+///
+/// The TypeString carries type, qualifier, name, size & value details.
+/// Please see 'Tools Development Guide' section 2.16.2 for format details:
+/// <https://www.xmos.com/download/public/Tools-Development-Guide%28X9114A%29.pdf>
+/// The output is tested by test/CodeGen/xcore-stringtype.c.
+///
+static bool getTypeString(SmallStringEnc &Enc, const Decl *D,
+                          CodeGen::CodeGenModule &CGM, TypeStringCache &TSC);
+
+/// XCore uses emitTargetMD to emit TypeString metadata for global symbols.
+void XCoreTargetCodeGenInfo::emitTargetMD(const Decl *D, llvm::GlobalValue *GV,
+                                          CodeGen::CodeGenModule &CGM) const {
+  SmallStringEnc Enc;
+  if (getTypeString(Enc, D, CGM, TSC)) {
+    llvm::LLVMContext &Ctx = CGM.getModule().getContext();
+    llvm::SmallVector<llvm::Value *, 2> MDVals;
+    MDVals.push_back(GV);
+    MDVals.push_back(llvm::MDString::get(Ctx, Enc.str()));
+    llvm::NamedMDNode *MD =
+      CGM.getModule().getOrInsertNamedMetadata("xcore.typestrings");
+    MD->addOperand(llvm::MDNode::get(Ctx, MDVals));
+  }
+}
+
+static bool appendType(SmallStringEnc &Enc, QualType QType,
+                       const CodeGen::CodeGenModule &CGM,
+                       TypeStringCache &TSC);
+
+/// Helper function for appendRecordType().
+/// Builds a SmallVector containing the encoded field types in declaration order.
+static bool extractFieldType(SmallVectorImpl<FieldEncoding> &FE,
+                             const RecordDecl *RD,
+                             const CodeGen::CodeGenModule &CGM,
+                             TypeStringCache &TSC) {
+  for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
+       I != E; ++I) {
+    SmallStringEnc Enc;
+    Enc += "m(";
+    Enc += I->getName();
+    Enc += "){";
+    if (I->isBitField()) {
+      Enc += "b(";
+      llvm::raw_svector_ostream OS(Enc);
+      OS.resync();
+      OS << I->getBitWidthValue(CGM.getContext());
+      OS.flush();
+      Enc += ':';
+    }
+    if (!appendType(Enc, I->getType(), CGM, TSC))
+      return false;
+    if (I->isBitField())
+      Enc += ')';
+    Enc += '}';
+    FE.push_back(FieldEncoding(!I->getName().empty(), Enc));
+  }
+  return true;
+}
+
+/// Appends structure and union types to Enc and adds encoding to cache.
+/// Recursively calls appendType (via extractFieldType) for each field.
+/// Union types have their fields ordered according to the ABI.
+static bool appendRecordType(SmallStringEnc &Enc, const RecordType *RT,
+                             const CodeGen::CodeGenModule &CGM,
+                             TypeStringCache &TSC, const IdentifierInfo *ID) {
+  // Append the cached TypeString if we have one.
+  StringRef TypeString = TSC.lookupStr(ID);
+  if (!TypeString.empty()) {
+    Enc += TypeString;
+    return true;
+  }
+
+  // Start to emit an incomplete TypeString.
+  size_t Start = Enc.size();
+  Enc += (RT->isUnionType()? 'u' : 's');
+  Enc += '(';
+  if (ID)
+    Enc += ID->getName();
+  Enc += "){";
+
+  // We collect all encoded fields and order as necessary.
+  bool IsRecursive = false;
+  const RecordDecl *RD = RT->getDecl()->getDefinition();
+  if (RD && !RD->field_empty()) {
+    // An incomplete TypeString stub is placed in the cache for this RecordType
+    // so that recursive calls to this RecordType will use it whilst building a
+    // complete TypeString for this RecordType.
+    SmallVector<FieldEncoding, 16> FE;
+    std::string StubEnc(Enc.substr(Start).str());
+    StubEnc += '}';  // StubEnc now holds a valid incomplete TypeString.
+    TSC.addIncomplete(ID, std::move(StubEnc));
+    if (!extractFieldType(FE, RD, CGM, TSC)) {
+      (void) TSC.removeIncomplete(ID);
+      return false;
+    }
+    IsRecursive = TSC.removeIncomplete(ID);
+    // The ABI requires unions to be sorted but not structures.
+    // See FieldEncoding::operator< for sort algorithm.
+    if (RT->isUnionType())
+      std::sort(FE.begin(), FE.end());
+    // We can now complete the TypeString.
+    unsigned E = FE.size();
+    for (unsigned I = 0; I != E; ++I) {
+      if (I)
+        Enc += ',';
+      Enc += FE[I].str();
+    }
+  }
+  Enc += '}';
+  TSC.addIfComplete(ID, Enc.substr(Start), IsRecursive);
+  return true;
+}
+
+/// Appends enum types to Enc and adds the encoding to the cache.
+static bool appendEnumType(SmallStringEnc &Enc, const EnumType *ET,
+                           TypeStringCache &TSC,
+                           const IdentifierInfo *ID) {
+  // Append the cached TypeString if we have one.
+  StringRef TypeString = TSC.lookupStr(ID);
+  if (!TypeString.empty()) {
+    Enc += TypeString;
+    return true;
+  }
+
+  size_t Start = Enc.size();
+  Enc += "e(";
+  if (ID)
+    Enc += ID->getName();
+  Enc += "){";
+
+  // We collect all encoded enumerations and order them alphanumerically.
+  if (const EnumDecl *ED = ET->getDecl()->getDefinition()) {
+    SmallVector<FieldEncoding, 16> FE;
+    for (auto I = ED->enumerator_begin(), E = ED->enumerator_end(); I != E;
+         ++I) {
+      SmallStringEnc EnumEnc;
+      EnumEnc += "m(";
+      EnumEnc += I->getName();
+      EnumEnc += "){";
+      I->getInitVal().toString(EnumEnc);
+      EnumEnc += '}';
+      FE.push_back(FieldEncoding(!I->getName().empty(), EnumEnc));
+    }
+    std::sort(FE.begin(), FE.end());
+    unsigned E = FE.size();
+    for (unsigned I = 0; I != E; ++I) {
+      if (I)
+        Enc += ',';
+      Enc += FE[I].str();
+    }
+  }
+  Enc += '}';
+  TSC.addIfComplete(ID, Enc.substr(Start), false);
+  return true;
+}
+
+/// Appends type's qualifier to Enc.
+/// This is done prior to appending the type's encoding.
+static void appendQualifier(SmallStringEnc &Enc, QualType QT) {
+  // Qualifiers are emitted in alphabetical order.
+  static const char *Table[] = {"","c:","r:","cr:","v:","cv:","rv:","crv:"};
+  int Lookup = 0;
+  if (QT.isConstQualified())
+    Lookup += 1<<0;
+  if (QT.isRestrictQualified())
+    Lookup += 1<<1;
+  if (QT.isVolatileQualified())
+    Lookup += 1<<2;
+  Enc += Table[Lookup];
+}
+
+/// Appends built-in types to Enc.
+static bool appendBuiltinType(SmallStringEnc &Enc, const BuiltinType *BT) {
+  const char *EncType;
+  switch (BT->getKind()) {
+    case BuiltinType::Void:
+      EncType = "0";
+      break;
+    case BuiltinType::Bool:
+      EncType = "b";
+      break;
+    case BuiltinType::Char_U:
+      EncType = "uc";
+      break;
+    case BuiltinType::UChar:
+      EncType = "uc";
+      break;
+    case BuiltinType::SChar:
+      EncType = "sc";
+      break;
+    case BuiltinType::UShort:
+      EncType = "us";
+      break;
+    case BuiltinType::Short:
+      EncType = "ss";
+      break;
+    case BuiltinType::UInt:
+      EncType = "ui";
+      break;
+    case BuiltinType::Int:
+      EncType = "si";
+      break;
+    case BuiltinType::ULong:
+      EncType = "ul";
+      break;
+    case BuiltinType::Long:
+      EncType = "sl";
+      break;
+    case BuiltinType::ULongLong:
+      EncType = "ull";
+      break;
+    case BuiltinType::LongLong:
+      EncType = "sll";
+      break;
+    case BuiltinType::Float:
+      EncType = "ft";
+      break;
+    case BuiltinType::Double:
+      EncType = "d";
+      break;
+    case BuiltinType::LongDouble:
+      EncType = "ld";
+      break;
+    default:
+      return false;
+  }
+  Enc += EncType;
+  return true;
+}
+
+/// Appends a pointer encoding to Enc before calling appendType for the pointee.
+static bool appendPointerType(SmallStringEnc &Enc, const PointerType *PT,
+                              const CodeGen::CodeGenModule &CGM,
+                              TypeStringCache &TSC) {
+  Enc += "p(";
+  if (!appendType(Enc, PT->getPointeeType(), CGM, TSC))
+    return false;
+  Enc += ')';
+  return true;
+}
+
+/// Appends array encoding to Enc before calling appendType for the element.
+static bool appendArrayType(SmallStringEnc &Enc, QualType QT,
+                            const ArrayType *AT,
+                            const CodeGen::CodeGenModule &CGM,
+                            TypeStringCache &TSC, StringRef NoSizeEnc) {
+  if (AT->getSizeModifier() != ArrayType::Normal)
+    return false;
+  Enc += "a(";
+  if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT))
+    CAT->getSize().toStringUnsigned(Enc);
+  else
+    Enc += NoSizeEnc; // Global arrays use "*", otherwise it is "".
+  Enc += ':';
+  // The Qualifiers should be attached to the type rather than the array.
+  appendQualifier(Enc, QT);
+  if (!appendType(Enc, AT->getElementType(), CGM, TSC))
+    return false;
+  Enc += ')';
+  return true;
+}
+
+/// Appends a function encoding to Enc, calling appendType for the return type
+/// and the arguments.
+static bool appendFunctionType(SmallStringEnc &Enc, const FunctionType *FT,
+                             const CodeGen::CodeGenModule &CGM,
+                             TypeStringCache &TSC) {
+  Enc += "f{";
+  if (!appendType(Enc, FT->getReturnType(), CGM, TSC))
+    return false;
+  Enc += "}(";
+  if (const FunctionProtoType *FPT = FT->getAs<FunctionProtoType>()) {
+    // N.B. we are only interested in the adjusted param types.
+    auto I = FPT->param_type_begin();
+    auto E = FPT->param_type_end();
+    if (I != E) {
+      do {
+        if (!appendType(Enc, *I, CGM, TSC))
+          return false;
+        ++I;
+        if (I != E)
+          Enc += ',';
+      } while (I != E);
+      if (FPT->isVariadic())
+        Enc += ",va";
+    } else {
+      if (FPT->isVariadic())
+        Enc += "va";
+      else
+        Enc += '0';
+    }
+  }
+  Enc += ')';
+  return true;
+}
+
+/// Handles the type's qualifier before dispatching a call to handle specific
+/// type encodings.
+static bool appendType(SmallStringEnc &Enc, QualType QType,
+                       const CodeGen::CodeGenModule &CGM,
+                       TypeStringCache &TSC) {
+
+  QualType QT = QType.getCanonicalType();
+
+  if (const ArrayType *AT = QT->getAsArrayTypeUnsafe())
+    // The Qualifiers should be attached to the type rather than the array.
+    // Thus we don't call appendQualifier() here.
+    return appendArrayType(Enc, QT, AT, CGM, TSC, "");
+
+  appendQualifier(Enc, QT);
+
+  if (const BuiltinType *BT = QT->getAs<BuiltinType>())
+    return appendBuiltinType(Enc, BT);
+
+  if (const PointerType *PT = QT->getAs<PointerType>())
+    return appendPointerType(Enc, PT, CGM, TSC);
+
+  if (const EnumType *ET = QT->getAs<EnumType>())
+    return appendEnumType(Enc, ET, TSC, QT.getBaseTypeIdentifier());
+
+  if (const RecordType *RT = QT->getAsStructureType())
+    return appendRecordType(Enc, RT, CGM, TSC, QT.getBaseTypeIdentifier());
+
+  if (const RecordType *RT = QT->getAsUnionType())
+    return appendRecordType(Enc, RT, CGM, TSC, QT.getBaseTypeIdentifier());
+
+  if (const FunctionType *FT = QT->getAs<FunctionType>())
+    return appendFunctionType(Enc, FT, CGM, TSC);
+
+  return false;
+}
+
+static bool getTypeString(SmallStringEnc &Enc, const Decl *D,
+                          CodeGen::CodeGenModule &CGM, TypeStringCache &TSC) {
+  if (!D)
+    return false;
+
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    if (FD->getLanguageLinkage() != CLanguageLinkage)
+      return false;
+    return appendType(Enc, FD->getType(), CGM, TSC);
+  }
+
+  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+    if (VD->getLanguageLinkage() != CLanguageLinkage)
+      return false;
+    QualType QT = VD->getType().getCanonicalType();
+    if (const ArrayType *AT = QT->getAsArrayTypeUnsafe()) {
+      // Global ArrayTypes are given a size of '*' if the size is unknown.
+      // The Qualifiers should be attached to the type rather than the array.
+      // Thus we don't call appendQualifier() here.
+      return appendArrayType(Enc, QT, AT, CGM, TSC, "*");
+    }
+    return appendType(Enc, QT, CGM, TSC);
+  }
+  return false;
+}
+
+
 //===----------------------------------------------------------------------===//
 // Driver code
 //===----------------------------------------------------------------------===//
@@ -5574,13 +6826,23 @@
     return *(TheTargetCodeGenInfo = new MIPSTargetCodeGenInfo(Types, false));
 
   case llvm::Triple::aarch64:
-    return *(TheTargetCodeGenInfo = new AArch64TargetCodeGenInfo(Types));
+  case llvm::Triple::aarch64_be:
+  case llvm::Triple::arm64:
+  case llvm::Triple::arm64_be: {
+    AArch64ABIInfo::ABIKind Kind = AArch64ABIInfo::AAPCS;
+    if (getTarget().getABI() == "darwinpcs")
+      Kind = AArch64ABIInfo::DarwinPCS;
+
+    return *(TheTargetCodeGenInfo = new AArch64TargetCodeGenInfo(Types, Kind));
+  }
 
   case llvm::Triple::arm:
+  case llvm::Triple::armeb:
   case llvm::Triple::thumb:
+  case llvm::Triple::thumbeb:
     {
       ARMABIInfo::ABIKind Kind = ARMABIInfo::AAPCS;
-      if (strcmp(getTarget().getABI(), "apcs-gnu") == 0)
+      if (getTarget().getABI() == "apcs-gnu")
         Kind = ARMABIInfo::APCS;
       else if (CodeGenOpts.FloatABI == "hard" ||
                (CodeGenOpts.FloatABI != "soft" &&
@@ -5600,13 +6862,20 @@
   case llvm::Triple::ppc:
     return *(TheTargetCodeGenInfo = new PPC32TargetCodeGenInfo(Types));
   case llvm::Triple::ppc64:
-    if (Triple.isOSBinFormatELF())
-      return *(TheTargetCodeGenInfo = new PPC64_SVR4_TargetCodeGenInfo(Types));
-    else
+    if (Triple.isOSBinFormatELF()) {
+      // FIXME: Should be switchable via command-line option.
+      PPC64_SVR4_ABIInfo::ABIKind Kind = PPC64_SVR4_ABIInfo::ELFv1;
+      return *(TheTargetCodeGenInfo =
+               new PPC64_SVR4_TargetCodeGenInfo(Types, Kind));
+    } else
       return *(TheTargetCodeGenInfo = new PPC64TargetCodeGenInfo(Types));
-  case llvm::Triple::ppc64le:
+  case llvm::Triple::ppc64le: {
     assert(Triple.isOSBinFormatELF() && "PPC64 LE non-ELF not supported!");
-    return *(TheTargetCodeGenInfo = new PPC64_SVR4_TargetCodeGenInfo(Types));
+    // FIXME: Should be switchable via command-line option.
+    PPC64_SVR4_ABIInfo::ABIKind Kind = PPC64_SVR4_ABIInfo::ELFv2;
+    return *(TheTargetCodeGenInfo =
+             new PPC64_SVR4_TargetCodeGenInfo(Types, Kind));
+  }
 
   case llvm::Triple::nvptx:
   case llvm::Triple::nvptx64:
@@ -5625,7 +6894,7 @@
     bool IsDarwinVectorABI = Triple.isOSDarwin();
     bool IsSmallStructInRegABI =
         X86_32TargetCodeGenInfo::isStructReturnInRegABI(Triple, CodeGenOpts);
-    bool IsWin32FloatStructABI = (Triple.getOS() == llvm::Triple::Win32);
+    bool IsWin32FloatStructABI = Triple.isWindowsMSVCEnvironment();
 
     if (Triple.getOS() == llvm::Triple::Win32) {
       return *(TheTargetCodeGenInfo =
@@ -5643,12 +6912,10 @@
   }
 
   case llvm::Triple::x86_64: {
-    bool HasAVX = strcmp(getTarget().getABI(), "avx") == 0;
+    bool HasAVX = getTarget().getABI() == "avx";
 
     switch (Triple.getOS()) {
     case llvm::Triple::Win32:
-    case llvm::Triple::MinGW32:
-    case llvm::Triple::Cygwin:
       return *(TheTargetCodeGenInfo = new WinX86_64TargetCodeGenInfo(Types));
     case llvm::Triple::NaCl:
       return *(TheTargetCodeGenInfo = new NaClX86_64TargetCodeGenInfo(Types,
@@ -5663,7 +6930,6 @@
   case llvm::Triple::sparcv9:
     return *(TheTargetCodeGenInfo = new SparcV9TargetCodeGenInfo(Types));
   case llvm::Triple::xcore:
-    return *(TheTargetCodeGenInfo = new XcoreTargetCodeGenInfo(Types));
-
+    return *(TheTargetCodeGenInfo = new XCoreTargetCodeGenInfo(Types));
   }
 }
diff --git a/lib/CodeGen/TargetInfo.h b/lib/CodeGen/TargetInfo.h
index fdf8a16..a7d4257 100644
--- a/lib/CodeGen/TargetInfo.h
+++ b/lib/CodeGen/TargetInfo.h
@@ -17,211 +17,221 @@
 
 #include "clang/AST/Type.h"
 #include "clang/Basic/LLVM.h"
-#include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
 
 namespace llvm {
-  class Constant;
-  class GlobalValue;
-  class Type;
-  class Value;
+class Constant;
+class GlobalValue;
+class Type;
+class Value;
 }
 
 namespace clang {
-  class ABIInfo;
-  class Decl;
+class ABIInfo;
+class Decl;
 
-  namespace CodeGen {
-    class CallArgList;
-    class CodeGenModule;
-    class CodeGenFunction;
-    class CGFunctionInfo;
+namespace CodeGen {
+class CallArgList;
+class CodeGenModule;
+class CodeGenFunction;
+class CGFunctionInfo;
+}
+
+/// TargetCodeGenInfo - This class organizes various target-specific
+/// codegeneration issues, like target-specific attributes, builtins and so
+/// on.
+class TargetCodeGenInfo {
+  ABIInfo *Info;
+
+public:
+  // WARNING: Acquires the ownership of ABIInfo.
+  TargetCodeGenInfo(ABIInfo *info = 0) : Info(info) {}
+  virtual ~TargetCodeGenInfo();
+
+  /// getABIInfo() - Returns ABI info helper for the target.
+  const ABIInfo &getABIInfo() const { return *Info; }
+
+  /// SetTargetAttributes - Provides a convenient hook to handle extra
+  /// target-specific attributes for the given global.
+  virtual void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
+                                   CodeGen::CodeGenModule &M) const {}
+
+  /// EmitTargetMD - Provides a convenient hook to handle extra
+  /// target-specific metadata for the given global.
+  virtual void emitTargetMD(const Decl *D, llvm::GlobalValue *GV,
+                            CodeGen::CodeGenModule &M) const {}
+
+  /// Determines the size of struct _Unwind_Exception on this platform,
+  /// in 8-bit units.  The Itanium ABI defines this as:
+  ///   struct _Unwind_Exception {
+  ///     uint64 exception_class;
+  ///     _Unwind_Exception_Cleanup_Fn exception_cleanup;
+  ///     uint64 private_1;
+  ///     uint64 private_2;
+  ///   };
+  virtual unsigned getSizeOfUnwindException() const;
+
+  /// Controls whether __builtin_extend_pointer should sign-extend
+  /// pointers to uint64_t or zero-extend them (the default).  Has
+  /// no effect for targets:
+  ///   - that have 64-bit pointers, or
+  ///   - that cannot address through registers larger than pointers, or
+  ///   - that implicitly ignore/truncate the top bits when addressing
+  ///     through such registers.
+  virtual bool extendPointerWithSExt() const { return false; }
+
+  /// Determines the DWARF register number for the stack pointer, for
+  /// exception-handling purposes.  Implements __builtin_dwarf_sp_column.
+  ///
+  /// Returns -1 if the operation is unsupported by this target.
+  virtual int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const {
+    return -1;
   }
 
-  /// TargetCodeGenInfo - This class organizes various target-specific
-  /// codegeneration issues, like target-specific attributes, builtins and so
-  /// on.
-  class TargetCodeGenInfo {
-    ABIInfo *Info;
-  public:
-    // WARNING: Acquires the ownership of ABIInfo.
-    TargetCodeGenInfo(ABIInfo *info = 0):Info(info) { }
-    virtual ~TargetCodeGenInfo();
+  /// Initializes the given DWARF EH register-size table, a char*.
+  /// Implements __builtin_init_dwarf_reg_size_table.
+  ///
+  /// Returns true if the operation is unsupported by this target.
+  virtual bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
+                                       llvm::Value *Address) const {
+    return true;
+  }
 
-    /// getABIInfo() - Returns ABI info helper for the target.
-    const ABIInfo& getABIInfo() const { return *Info; }
+  /// Performs the code-generation required to convert a return
+  /// address as stored by the system into the actual address of the
+  /// next instruction that will be executed.
+  ///
+  /// Used by __builtin_extract_return_addr().
+  virtual llvm::Value *decodeReturnAddress(CodeGen::CodeGenFunction &CGF,
+                                           llvm::Value *Address) const {
+    return Address;
+  }
 
-    /// SetTargetAttributes - Provides a convenient hook to handle extra
-    /// target-specific attributes for the given global.
-    virtual void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
-                                     CodeGen::CodeGenModule &M) const { }
+  /// Performs the code-generation required to convert the address
+  /// of an instruction into a return address suitable for storage
+  /// by the system in a return slot.
+  ///
+  /// Used by __builtin_frob_return_addr().
+  virtual llvm::Value *encodeReturnAddress(CodeGen::CodeGenFunction &CGF,
+                                           llvm::Value *Address) const {
+    return Address;
+  }
 
-    /// Determines the size of struct _Unwind_Exception on this platform,
-    /// in 8-bit units.  The Itanium ABI defines this as:
-    ///   struct _Unwind_Exception {
-    ///     uint64 exception_class;
-    ///     _Unwind_Exception_Cleanup_Fn exception_cleanup;
-    ///     uint64 private_1;
-    ///     uint64 private_2;
-    ///   };
-    virtual unsigned getSizeOfUnwindException() const;
+  /// Corrects the low-level LLVM type for a given constraint and "usual"
+  /// type.
+  ///
+  /// \returns A pointer to a new LLVM type, possibly the same as the original
+  /// on success; 0 on failure.
+  virtual llvm::Type *adjustInlineAsmType(CodeGen::CodeGenFunction &CGF,
+                                          StringRef Constraint,
+                                          llvm::Type *Ty) const {
+    return Ty;
+  }
 
-    /// Controls whether __builtin_extend_pointer should sign-extend
-    /// pointers to uint64_t or zero-extend them (the default).  Has
-    /// no effect for targets:
-    ///   - that have 64-bit pointers, or
-    ///   - that cannot address through registers larger than pointers, or
-    ///   - that implicitly ignore/truncate the top bits when addressing
-    ///     through such registers.
-    virtual bool extendPointerWithSExt() const { return false; }
+  /// doesReturnSlotInterfereWithArgs - Return true if the target uses an
+  /// argument slot for an 'sret' type.
+  virtual bool doesReturnSlotInterfereWithArgs() const { return true; }
 
-    /// Determines the DWARF register number for the stack pointer, for
-    /// exception-handling purposes.  Implements __builtin_dwarf_sp_column.
-    ///
-    /// Returns -1 if the operation is unsupported by this target.
-    virtual int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const {
-      return -1;
-    }
+  /// Retrieve the address of a function to call immediately before
+  /// calling objc_retainAutoreleasedReturnValue.  The
+  /// implementation of objc_autoreleaseReturnValue sniffs the
+  /// instruction stream following its return address to decide
+  /// whether it's a call to objc_retainAutoreleasedReturnValue.
+  /// This can be prohibitively expensive, depending on the
+  /// relocation model, and so on some targets it instead sniffs for
+  /// a particular instruction sequence.  This functions returns
+  /// that instruction sequence in inline assembly, which will be
+  /// empty if none is required.
+  virtual StringRef getARCRetainAutoreleasedReturnValueMarker() const {
+    return "";
+  }
 
-    /// Initializes the given DWARF EH register-size table, a char*.
-    /// Implements __builtin_init_dwarf_reg_size_table.
-    ///
-    /// Returns true if the operation is unsupported by this target.
-    virtual bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
-                                         llvm::Value *Address) const {
-      return true;
-    }
+  /// Return a constant used by UBSan as a signature to identify functions
+  /// possessing type information, or 0 if the platform is unsupported.
+  virtual llvm::Constant *
+  getUBSanFunctionSignature(CodeGen::CodeGenModule &CGM) const {
+    return nullptr;
+  }
 
-    /// Performs the code-generation required to convert a return
-    /// address as stored by the system into the actual address of the
-    /// next instruction that will be executed.
-    ///
-    /// Used by __builtin_extract_return_addr().
-    virtual llvm::Value *decodeReturnAddress(CodeGen::CodeGenFunction &CGF,
-                                             llvm::Value *Address) const {
-      return Address;
-    }
+  /// Determine whether a call to an unprototyped functions under
+  /// the given calling convention should use the variadic
+  /// convention or the non-variadic convention.
+  ///
+  /// There's a good reason to make a platform's variadic calling
+  /// convention be different from its non-variadic calling
+  /// convention: the non-variadic arguments can be passed in
+  /// registers (better for performance), and the variadic arguments
+  /// can be passed on the stack (also better for performance).  If
+  /// this is done, however, unprototyped functions *must* use the
+  /// non-variadic convention, because C99 states that a call
+  /// through an unprototyped function type must succeed if the
+  /// function was defined with a non-variadic prototype with
+  /// compatible parameters.  Therefore, splitting the conventions
+  /// makes it impossible to call a variadic function through an
+  /// unprototyped type.  Since function prototypes came out in the
+  /// late 1970s, this is probably an acceptable trade-off.
+  /// Nonetheless, not all platforms are willing to make it, and in
+  /// particularly x86-64 bends over backwards to make the
+  /// conventions compatible.
+  ///
+  /// The default is false.  This is correct whenever:
+  ///   - the conventions are exactly the same, because it does not
+  ///     matter and the resulting IR will be somewhat prettier in
+  ///     certain cases; or
+  ///   - the conventions are substantively different in how they pass
+  ///     arguments, because in this case using the variadic convention
+  ///     will lead to C99 violations.
+  ///
+  /// However, some platforms make the conventions identical except
+  /// for passing additional out-of-band information to a variadic
+  /// function: for example, x86-64 passes the number of SSE
+  /// arguments in %al.  On these platforms, it is desirable to
+  /// call unprototyped functions using the variadic convention so
+  /// that unprototyped calls to varargs functions still succeed.
+  ///
+  /// Relatedly, platforms which pass the fixed arguments to this:
+  ///   A foo(B, C, D);
+  /// differently than they would pass them to this:
+  ///   A foo(B, C, D, ...);
+  /// may need to adjust the debugger-support code in Sema to do the
+  /// right thing when calling a function with no know signature.
+  virtual bool isNoProtoCallVariadic(const CodeGen::CallArgList &args,
+                                     const FunctionNoProtoType *fnType) const;
 
-    /// Performs the code-generation required to convert the address
-    /// of an instruction into a return address suitable for storage
-    /// by the system in a return slot.
-    ///
-    /// Used by __builtin_frob_return_addr().
-    virtual llvm::Value *encodeReturnAddress(CodeGen::CodeGenFunction &CGF,
-                                             llvm::Value *Address) const {
-      return Address;
-    }
+  /// Gets the linker options necessary to link a dependent library on this
+  /// platform.
+  virtual void getDependentLibraryOption(llvm::StringRef Lib,
+                                         llvm::SmallString<24> &Opt) const;
 
-    /// Corrects the low-level LLVM type for a given constraint and "usual"
-    /// type.
-    ///
-    /// \returns A pointer to a new LLVM type, possibly the same as the original
-    /// on success; 0 on failure.
-    virtual llvm::Type* adjustInlineAsmType(CodeGen::CodeGenFunction &CGF,
-                                            StringRef Constraint,
-                                            llvm::Type* Ty) const {
-      return Ty;
-    }
+  /// Gets the linker options necessary to detect object file mismatches on
+  /// this platform.
+  virtual void getDetectMismatchOption(llvm::StringRef Name,
+                                       llvm::StringRef Value,
+                                       llvm::SmallString<32> &Opt) const {}
 
-    /// Retrieve the address of a function to call immediately before
-    /// calling objc_retainAutoreleasedReturnValue.  The
-    /// implementation of objc_autoreleaseReturnValue sniffs the
-    /// instruction stream following its return address to decide
-    /// whether it's a call to objc_retainAutoreleasedReturnValue.
-    /// This can be prohibitively expensive, depending on the
-    /// relocation model, and so on some targets it instead sniffs for
-    /// a particular instruction sequence.  This functions returns
-    /// that instruction sequence in inline assembly, which will be
-    /// empty if none is required.
-    virtual StringRef getARCRetainAutoreleasedReturnValueMarker() const {
-      return "";
-    }
+  // @LOCALMOD-START
+  /// Determine whether the sequentially consistent fence generated for
+  /// the legacy GCC-style ``__sync_synchronize()`` builtin should be
+  /// surrounded by empty assembly directives which touch all of
+  /// memory. This allows platforms which aim for portability to
+  /// isolate themselves from changes in sequentially consistent
+  /// fence's semantics, since its intent is to represent the
+  /// C11/C++11 memory model which only orders atomic memory accesses.
+  /// This won't guarantee that all accesses (e.g. those to
+  /// non-escaping objects) will not be reordered.
+  virtual bool addAsmMemoryAroundSyncSynchronize() const {
+    return false;
+  }
 
-    /// Return a constant used by UBSan as a signature to identify functions
-    /// possessing type information, or 0 if the platform is unsupported.
-    virtual llvm::Constant *getUBSanFunctionSignature(
-        CodeGen::CodeGenModule &CGM) const {
-      return 0;
-    }
-
-    /// Determine whether a call to an unprototyped functions under
-    /// the given calling convention should use the variadic
-    /// convention or the non-variadic convention.
-    ///
-    /// There's a good reason to make a platform's variadic calling
-    /// convention be different from its non-variadic calling
-    /// convention: the non-variadic arguments can be passed in
-    /// registers (better for performance), and the variadic arguments
-    /// can be passed on the stack (also better for performance).  If
-    /// this is done, however, unprototyped functions *must* use the
-    /// non-variadic convention, because C99 states that a call
-    /// through an unprototyped function type must succeed if the
-    /// function was defined with a non-variadic prototype with
-    /// compatible parameters.  Therefore, splitting the conventions
-    /// makes it impossible to call a variadic function through an
-    /// unprototyped type.  Since function prototypes came out in the
-    /// late 1970s, this is probably an acceptable trade-off.
-    /// Nonetheless, not all platforms are willing to make it, and in
-    /// particularly x86-64 bends over backwards to make the
-    /// conventions compatible.
-    ///
-    /// The default is false.  This is correct whenever:
-    ///   - the conventions are exactly the same, because it does not
-    ///     matter and the resulting IR will be somewhat prettier in
-    ///     certain cases; or
-    ///   - the conventions are substantively different in how they pass
-    ///     arguments, because in this case using the variadic convention
-    ///     will lead to C99 violations.
-    ///
-    /// However, some platforms make the conventions identical except
-    /// for passing additional out-of-band information to a variadic
-    /// function: for example, x86-64 passes the number of SSE
-    /// arguments in %al.  On these platforms, it is desireable to
-    /// call unprototyped functions using the variadic convention so
-    /// that unprototyped calls to varargs functions still succeed.
-    ///
-    /// Relatedly, platforms which pass the fixed arguments to this:
-    ///   A foo(B, C, D);
-    /// differently than they would pass them to this:
-    ///   A foo(B, C, D, ...);
-    /// may need to adjust the debugger-support code in Sema to do the
-    /// right thing when calling a function with no know signature.
-    virtual bool isNoProtoCallVariadic(const CodeGen::CallArgList &args,
-                                       const FunctionNoProtoType *fnType) const;
-
-    /// Gets the linker options necessary to link a dependent library on this
-    /// platform.
-    virtual void getDependentLibraryOption(llvm::StringRef Lib,
-                                           llvm::SmallString<24> &Opt) const;
-
-    /// Gets the linker options necessary to detect object file mismatches on
-    /// this platform.
-    virtual void getDetectMismatchOption(llvm::StringRef Name,
-                                         llvm::StringRef Value,
-                                         llvm::SmallString<32> &Opt) const {}
-
-    // @LOCALMOD-START
-    /// Determine whether the sequentially consistent fence generated for
-    /// the legacy GCC-style ``__sync_synchronize()`` builtin should be
-    /// surrounded by empty assembly directives which touch all of
-    /// memory. This allows platforms which aim for portability to
-    /// isolate themselves from changes in sequentially consistent
-    /// fence's semantics, since its intent is to represent the
-    /// C11/C++11 memory model which only orders atomic memory accesses.
-    /// This won't guarantee that all accesses (e.g. those to
-    /// non-escaping objects) will not be reordered.
-    virtual bool addAsmMemoryAroundSyncSynchronize() const {
-      return false;
-    }
-
-    /// Determine whether a full sequentially consistent fence should be
-    /// emitted when ``asm("":::"memory")`` is encountered, treating it
-    /// like ``__sync_synchronize()``.
-    virtual bool asmMemoryIsFence() const {
-      return false;
-    }
-    // @LOCALMOD-END
-  };
+  /// Determine whether a full sequentially consistent fence should be
+  /// emitted when ``asm("":::"memory")`` is encountered, treating it
+  /// like ``__sync_synchronize()``.
+  virtual bool asmMemoryIsFence() const {
+    return false;
+  }
+  // @LOCALMOD-END
+};
 }
 
 #endif // CLANG_CODEGEN_TARGETINFO_H
diff --git a/lib/Driver/Action.cpp b/lib/Driver/Action.cpp
index ddd2d59..86a48fd 100644
--- a/lib/Driver/Action.cpp
+++ b/lib/Driver/Action.cpp
@@ -33,7 +33,8 @@
   case LinkJobClass: return "linker";
   case LipoJobClass: return "lipo";
   case DsymutilJobClass: return "dsymutil";
-  case VerifyJobClass: return "verify";
+  case VerifyDebugInfoJobClass: return "verify-debug-info";
+  case VerifyPCHJobClass: return "verify-pch";
   }
 
   llvm_unreachable("invalid class");
@@ -117,6 +118,29 @@
 
 void VerifyJobAction::anchor() {}
 
-VerifyJobAction::VerifyJobAction(ActionList &Inputs, types::ID Type)
-  : JobAction(VerifyJobClass, Inputs, Type) {
+VerifyJobAction::VerifyJobAction(ActionClass Kind, Action *Input,
+                                 types::ID Type)
+    : JobAction(Kind, Input, Type) {
+  assert((Kind == VerifyDebugInfoJobClass || Kind == VerifyPCHJobClass) &&
+         "ActionClass is not a valid VerifyJobAction");
+}
+
+VerifyJobAction::VerifyJobAction(ActionClass Kind, ActionList &Inputs,
+                                 types::ID Type)
+    : JobAction(Kind, Inputs, Type) {
+  assert((Kind == VerifyDebugInfoJobClass || Kind == VerifyPCHJobClass) &&
+           "ActionClass is not a valid VerifyJobAction");
+}
+
+void VerifyDebugInfoJobAction::anchor() {}
+
+VerifyDebugInfoJobAction::VerifyDebugInfoJobAction(Action *Input,
+                                                   types::ID Type)
+    : VerifyJobAction(VerifyDebugInfoJobClass, Input, Type) {
+}
+
+void VerifyPCHJobAction::anchor() {}
+
+VerifyPCHJobAction::VerifyPCHJobAction(Action *Input, types::ID Type)
+    : VerifyJobAction(VerifyPCHJobClass, Input, Type) {
 }
diff --git a/lib/Driver/CC1AsOptions.cpp b/lib/Driver/CC1AsOptions.cpp
deleted file mode 100644
index 22180c9..0000000
--- a/lib/Driver/CC1AsOptions.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-//===--- CC1AsOptions.cpp - Clang Assembler Options Table -----------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Driver/CC1AsOptions.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/Option/OptTable.h"
-#include "llvm/Option/Option.h"
-using namespace clang;
-using namespace clang::driver;
-using namespace llvm::opt;
-using namespace clang::driver::cc1asoptions;
-
-#define PREFIX(NAME, VALUE) static const char *const NAME[] = VALUE;
-#include "clang/Driver/CC1AsOptions.inc"
-#undef PREFIX
-
-static const OptTable::Info CC1AsInfoTable[] = {
-#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
-               HELPTEXT, METAVAR)   \
-  { PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, Option::KIND##Class, PARAM, \
-    FLAGS, OPT_##GROUP, OPT_##ALIAS, ALIASARGS },
-#include "clang/Driver/CC1AsOptions.inc"
-#undef OPTION
-};
-
-namespace {
-
-class CC1AsOptTable : public OptTable {
-public:
-  CC1AsOptTable()
-    : OptTable(CC1AsInfoTable, llvm::array_lengthof(CC1AsInfoTable)) {}
-};
-
-}
-
-OptTable *clang::driver::createCC1AsOptTable() {
-  return new CC1AsOptTable();
-}
diff --git a/lib/Driver/CMakeLists.txt b/lib/Driver/CMakeLists.txt
index 0152b19..33db5e9 100644
--- a/lib/Driver/CMakeLists.txt
+++ b/lib/Driver/CMakeLists.txt
@@ -1,10 +1,15 @@
+set(LLVM_LINK_COMPONENTS
+  Option
+  Support
+  )
+
 add_clang_library(clangDriver
   Action.cpp
-  CC1AsOptions.cpp
   Compilation.cpp
   Driver.cpp
   DriverOptions.cpp
   Job.cpp
+  Multilib.cpp
   Phases.cpp
   SanitizerArgs.cpp
   Tool.cpp
@@ -13,18 +18,10 @@
   WindowsToolChain.cpp
   Tools.cpp
   Types.cpp
-  )
 
-add_dependencies(clangDriver
-  ClangAttrList
-  ClangCC1AsOptions
-  ClangDiagnosticCommon
-  ClangDiagnosticDriver
+  DEPENDS
   ClangDriverOptions
-  )
 
-target_link_libraries(clangDriver
+  LINK_LIBS
   clangBasic
-  LLVMOption
-  LLVMTransformUtils
   )
diff --git a/lib/Driver/Compilation.cpp b/lib/Driver/Compilation.cpp
index f077fd6..49b7edd 100644
--- a/lib/Driver/Compilation.cpp
+++ b/lib/Driver/Compilation.cpp
@@ -17,8 +17,6 @@
 #include "llvm/Option/ArgList.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/raw_ostream.h"
-#include <errno.h>
-#include <sys/stat.h>
 
 using namespace clang::driver;
 using namespace clang;
@@ -26,9 +24,9 @@
 
 Compilation::Compilation(const Driver &D, const ToolChain &_DefaultToolChain,
                          InputArgList *_Args, DerivedArgList *_TranslatedArgs)
-  : TheDriver(D), DefaultToolChain(_DefaultToolChain), Args(_Args),
-    TranslatedArgs(_TranslatedArgs), Redirects(0) {
-}
+    : TheDriver(D), DefaultToolChain(_DefaultToolChain), Args(_Args),
+      TranslatedArgs(_TranslatedArgs), Redirects(nullptr),
+      ForDiagnostics(false) {}
 
 Compilation::~Compilation() {
   delete TranslatedArgs;
@@ -70,8 +68,6 @@
 }
 
 bool Compilation::CleanupFile(const char *File, bool IssueErrors) const {
-  std::string P(File);
-
   // FIXME: Why are we trying to remove files that we have not created? For
   // example we should only try to remove a temporary assembly file if
   // "clang -cc1" succeed in writing it. Was this a workaround for when
@@ -88,7 +84,7 @@
   if (!llvm::sys::fs::can_write(File) || !llvm::sys::fs::is_regular_file(File))
     return true;
 
-  if (llvm::error_code EC = llvm::sys::fs::remove(File)) {
+  if (std::error_code EC = llvm::sys::fs::remove(File)) {
     // Failure is only failure if the file exists and is "regular". We checked
     // for it being regular before, and llvm::sys::fs::remove ignores ENOENT,
     // so we don't need to check again.
@@ -137,7 +133,8 @@
     if (getDriver().CCPrintOptions && getDriver().CCPrintOptionsFilename) {
       std::string Error;
       OS = new llvm::raw_fd_ostream(getDriver().CCPrintOptionsFilename, Error,
-                                    llvm::sys::fs::F_Append);
+                                    llvm::sys::fs::F_Append |
+                                        llvm::sys::fs::F_Text);
       if (!Error.empty()) {
         getDriver().Diag(clang::diag::err_drv_cc_print_options_failure)
           << Error;
@@ -200,7 +197,7 @@
   if (const Command *C = dyn_cast<Command>(&J)) {
     if (!InputsOk(*C, FailingCommands))
       return;
-    const Command *FailingCommand = 0;
+    const Command *FailingCommand = nullptr;
     if (int Res = ExecuteCommand(*C, FailingCommand))
       FailingCommands.push_back(std::make_pair(Res, FailingCommand));
   } else {
@@ -212,6 +209,8 @@
 }
 
 void Compilation::initCompilationForDiagnostics() {
+  ForDiagnostics = true;
+
   // Free actions and jobs.
   DeleteContainerPointers(Actions);
   Jobs.clear();
@@ -233,7 +232,7 @@
 
   // Redirect stdout/stderr to /dev/null.
   Redirects = new const StringRef*[3]();
-  Redirects[0] = 0;
+  Redirects[0] = nullptr;
   Redirects[1] = new const StringRef();
   Redirects[2] = new const StringRef();
 }
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index 977efe7..7320ca2 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -11,6 +11,7 @@
 #include "InputInfo.h"
 #include "ToolChains.h"
 #include "clang/Basic/Version.h"
+#include "clang/Config/config.h"
 #include "clang/Driver/Action.h"
 #include "clang/Driver/Compilation.h"
 #include "clang/Driver/DriverDiagnostic.h"
@@ -19,27 +20,25 @@
 #include "clang/Driver/Tool.h"
 #include "clang/Driver/ToolChain.h"
 #include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringSet.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Option/Arg.h"
 #include "llvm/Option/ArgList.h"
+#include "llvm/Option/OptSpecifier.h"
 #include "llvm/Option/OptTable.h"
 #include "llvm/Option/Option.h"
-#include "llvm/Option/OptSpecifier.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/Process.h"
 #include "llvm/Support/Program.h"
 #include "llvm/Support/raw_ostream.h"
 #include <map>
-
-// FIXME: It would prevent us from including llvm-config.h
-// if config.h were included before system_error.h.
-#include "clang/Config/config.h"
+#include <memory>
 
 using namespace clang::driver;
 using namespace clang;
@@ -47,15 +46,14 @@
 
 Driver::Driver(StringRef ClangExecutable,
                StringRef DefaultTargetTriple,
-               StringRef DefaultImageName,
                DiagnosticsEngine &Diags)
   : Opts(createDriverOptTable()), Diags(Diags), Mode(GCCMode),
     ClangExecutable(ClangExecutable), SysRoot(DEFAULT_SYSROOT),
     UseStdLib(true), DefaultTargetTriple(DefaultTargetTriple),
-    DefaultImageName(DefaultImageName),
+    DefaultImageName("a.out"),
     DriverTitle("clang LLVM compiler"),
-    CCPrintOptionsFilename(0), CCPrintHeadersFilename(0),
-    CCLogDiagnosticsFilename(0),
+    CCPrintOptionsFilename(nullptr), CCPrintHeadersFilename(nullptr),
+    CCLogDiagnosticsFilename(nullptr),
     CCCPrintBindings(false),
     CCPrintHeaders(false), CCLogDiagnostics(false),
     CCGenDiagnostics(false), CCCGenericGCCName(""), CheckInputsExist(true),
@@ -77,10 +75,7 @@
 Driver::~Driver() {
   delete Opts;
 
-  for (llvm::StringMap<ToolChain *>::iterator I = ToolChains.begin(),
-                                              E = ToolChains.end();
-       I != E; ++I)
-    delete I->second;
+  llvm::DeleteContainerSeconds(ToolChains);
 }
 
 void Driver::ParseDriverMode(ArrayRef<const char *> Args) {
@@ -112,7 +107,7 @@
 
   unsigned IncludedFlagsBitmask;
   unsigned ExcludedFlagsBitmask;
-  llvm::tie(IncludedFlagsBitmask, ExcludedFlagsBitmask) =
+  std::tie(IncludedFlagsBitmask, ExcludedFlagsBitmask) =
     getIncludeExcludeOptionFlagMasks();
 
   unsigned MissingArgIndex, MissingArgCount;
@@ -156,18 +151,21 @@
 // option we used to determine the final phase.
 phases::ID Driver::getFinalPhase(const DerivedArgList &DAL, Arg **FinalPhaseArg)
 const {
-  Arg *PhaseArg = 0;
+  Arg *PhaseArg = nullptr;
   phases::ID FinalPhase;
 
-  // -{E,M,MM} only run the preprocessor.
+  // -{E,EP,P,M,MM} only run the preprocessor.
   if (CCCIsCPP() ||
       (PhaseArg = DAL.getLastArg(options::OPT_E)) ||
-      (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM))) {
+      (PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) ||
+      (PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) ||
+      (PhaseArg = DAL.getLastArg(options::OPT__SLASH_P))) {
     FinalPhase = phases::Preprocess;
 
     // -{fsyntax-only,-analyze,emit-ast,S} only run up to the compiler.
   } else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
              (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
+             (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
              (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
              (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
              (PhaseArg = DAL.getLastArg(options::OPT__migrate)) ||
@@ -191,10 +189,11 @@
   return FinalPhase;
 }
 
-static Arg* MakeInputArg(const DerivedArgList &Args, OptTable *Opts,
+static Arg* MakeInputArg(DerivedArgList &Args, OptTable *Opts,
                          StringRef Value) {
   Arg *A = new Arg(Opts->getOption(options::OPT_INPUT), Value,
                    Args.getBaseArgs().MakeIndex(Value), Value.data());
+  Args.AddSynthesizedArg(A);
   A->claim();
   return A;
 }
@@ -336,9 +335,10 @@
   // FIXME: DefaultTargetTriple is used by the target-prefixed calls to as/ld
   // and getToolChain is const.
   if (IsCLMode()) {
-    // clang-cl targets Win32.
+    // clang-cl targets MSVC-style Win32.
     llvm::Triple T(DefaultTargetTriple);
-    T.setOSName(llvm::Triple::getOSTypeName(llvm::Triple::Win32));
+    T.setOS(llvm::Triple::Win32);
+    T.setEnvironment(llvm::Triple::MSVC);
     DefaultTargetTriple = T.str();
   }
   if (const Arg *A = Args->getLastArg(options::OPT_target))
@@ -378,8 +378,8 @@
   BuildInputs(C->getDefaultToolChain(), *TranslatedArgs, Inputs);
 
   // Construct the list of abstract actions to perform for this compilation. On
-  // Darwin target OSes this uses the driver-driver and universal actions.
-  if (TC.getTriple().isOSDarwin())
+  // MachO targets this uses the driver-driver and universal actions.
+  if (TC.getTriple().isOSBinFormatMachO())
     BuildUniversalActions(C->getDefaultToolChain(), C->getArgs(),
                           Inputs, C->getActions());
   else
@@ -419,7 +419,6 @@
   // Suppress driver output and emit preprocessor output to temp file.
   Mode = CPPMode;
   CCGenDiagnostics = true;
-  C.getArgs().AddFlagArg(0, Opts->getOption(options::OPT_frewrite_includes));
 
   // Save the original job command(s).
   std::string Cmd;
@@ -447,13 +446,14 @@
     bool IgnoreInput = false;
 
     // Ignore input from stdin or any inputs that cannot be preprocessed.
-    if (!strcmp(it->second->getValue(), "-")) {
+    // Check type first as not all linker inputs have a value.
+   if (types::getPreprocessedType(it->first) == types::TY_INVALID) {
+      IgnoreInput = true;
+    } else if (!strcmp(it->second->getValue(), "-")) {
       Diag(clang::diag::note_drv_command_failed_diag_msg)
         << "Error generating preprocessed source(s) - ignoring input from stdin"
         ".";
       IgnoreInput = true;
-    } else if (types::getPreprocessedType(it->first) == types::TY_INVALID) {
-      IgnoreInput = true;
     }
 
     if (IgnoreInput) {
@@ -491,7 +491,7 @@
   // Construct the list of abstract actions to perform for this compilation. On
   // Darwin OSes this uses the driver-driver and builds universal actions.
   const ToolChain &TC = C.getDefaultToolChain();
-  if (TC.getTriple().isOSDarwin())
+  if (TC.getTriple().isOSBinFormatMachO())
     BuildUniversalActions(TC, C.getArgs(), Inputs, C.getActions());
   else
     BuildActions(TC, C.getArgs(), Inputs, C.getActions());
@@ -519,17 +519,25 @@
     for (ArgStringList::const_iterator it = Files.begin(), ie = Files.end();
          it != ie; ++it) {
       Diag(clang::diag::note_drv_command_failed_diag_msg) << *it;
+      std::string Script = StringRef(*it).rsplit('.').first;
+      // In some cases (modules) we'll dump extra data to help with reproducing
+      // the crash into a directory next to the output.
+      SmallString<128> VFS;
+      if (llvm::sys::fs::exists(Script + ".cache")) {
+        Diag(clang::diag::note_drv_command_failed_diag_msg)
+            << Script + ".cache";
+        VFS = llvm::sys::path::filename(Script + ".cache");
+        llvm::sys::path::append(VFS, "vfs", "vfs.yaml");
+      }
 
       std::string Err;
-      std::string Script = StringRef(*it).rsplit('.').first;
       Script += ".sh";
-      llvm::raw_fd_ostream ScriptOS(
-          Script.c_str(), Err, llvm::sys::fs::F_Excl | llvm::sys::fs::F_Binary);
+      llvm::raw_fd_ostream ScriptOS(Script.c_str(), Err, llvm::sys::fs::F_Excl);
       if (!Err.empty()) {
         Diag(clang::diag::note_drv_command_failed_diag_msg)
           << "Error generating run script: " + Script + " " + Err;
       } else {
-        // Append the new filename with correct preprocessed suffix.
+        // Replace the original filename with the preprocessed one.
         size_t I, E;
         I = Cmd.find("-main-file-name ");
         assert (I != std::string::npos && "Expected to find -main-file-name");
@@ -542,6 +550,11 @@
         E = I + OldFilename.size();
         I = Cmd.rfind(" ", I) + 1;
         Cmd.replace(I, E - I, NewFilename.data(), NewFilename.size());
+        if (!VFS.empty()) {
+          // Add the VFS overlay to the reproduction script.
+          I += NewFilename.size();
+          Cmd.insert(I, std::string(" -ivfsoverlay ") + VFS.c_str());
+        }
         ScriptOS << Cmd;
         Diag(clang::diag::note_drv_command_failed_diag_msg) << Script;
       }
@@ -599,7 +612,7 @@
     // Print extra information about abnormal failures, if possible.
     //
     // This is ad-hoc, but we don't want to be excessively noisy. If the result
-    // status was 1, assume the command failed normally. In particular, if it 
+    // status was 1, assume the command failed normally. In particular, if it
     // was the compiler then assume it gave a reasonable error code. Failures
     // in other tools are less common, and they generally have worse
     // diagnostics, so always print the diagnostic there.
@@ -621,7 +634,7 @@
 void Driver::PrintHelp(bool ShowHidden) const {
   unsigned IncludedFlagsBitmask;
   unsigned ExcludedFlagsBitmask;
-  llvm::tie(IncludedFlagsBitmask, ExcludedFlagsBitmask) =
+  std::tie(IncludedFlagsBitmask, ExcludedFlagsBitmask) =
     getIncludeExcludeOptionFlagMasks();
 
   ExcludedFlagsBitmask |= options::NoDriverOption;
@@ -746,54 +759,37 @@
   }
 
   if (C.getArgs().hasArg(options::OPT_print_multi_lib)) {
-    // FIXME: We need tool chain support for this.
-    llvm::outs() << ".;\n";
+    const MultilibSet &Multilibs = TC.getMultilibs();
 
-    switch (C.getDefaultToolChain().getTriple().getArch()) {
-    default:
-      break;
-
-    case llvm::Triple::x86_64:
-      llvm::outs() << "x86_64;@m64" << "\n";
-      break;
-
-    case llvm::Triple::ppc64:
-      llvm::outs() << "ppc64;@m64" << "\n";
-      break;
-
-    case llvm::Triple::ppc64le:
-      llvm::outs() << "ppc64le;@m64" << "\n";
-      break;
+    for (MultilibSet::const_iterator I = Multilibs.begin(), E = Multilibs.end();
+         I != E; ++I) {
+      llvm::outs() << *I << "\n";
     }
     return false;
   }
 
-  // FIXME: What is the difference between print-multi-directory and
-  // print-multi-os-directory?
-  if (C.getArgs().hasArg(options::OPT_print_multi_directory) ||
-      C.getArgs().hasArg(options::OPT_print_multi_os_directory)) {
-    switch (C.getDefaultToolChain().getTriple().getArch()) {
-    default:
-    case llvm::Triple::x86:
-    case llvm::Triple::ppc:
-      llvm::outs() << "." << "\n";
-      break;
-
-    case llvm::Triple::x86_64:
-      llvm::outs() << "x86_64" << "\n";
-      break;
-
-    case llvm::Triple::ppc64:
-      llvm::outs() << "ppc64" << "\n";
-      break;
-
-    case llvm::Triple::ppc64le:
-      llvm::outs() << "ppc64le" << "\n";
-      break;
+  if (C.getArgs().hasArg(options::OPT_print_multi_directory)) {
+    const MultilibSet &Multilibs = TC.getMultilibs();
+    for (MultilibSet::const_iterator I = Multilibs.begin(), E = Multilibs.end();
+         I != E; ++I) {
+      if (I->gccSuffix().empty())
+        llvm::outs() << ".\n";
+      else {
+        StringRef Suffix(I->gccSuffix());
+        assert(Suffix.front() == '/');
+        llvm::outs() << Suffix.substr(1) << "\n";
+      }
     }
     return false;
   }
 
+  if (C.getArgs().hasArg(options::OPT_print_multi_os_directory)) {
+    // FIXME: This should print out "lib/../lib", "lib/../lib64", or
+    // "lib/../lib32" as appropriate for the toolchain. For now, print
+    // nothing because it's not supported yet.
+    return false;
+  }
+
   return true;
 }
 
@@ -867,7 +863,7 @@
       // Validate the option here; we don't save the type here because its
       // particular spelling may participate in other driver choices.
       llvm::Triple::ArchType Arch =
-        tools::darwin::getArchTypeForDarwinArchName(A->getValue());
+        tools::darwin::getArchTypeForMachOArchName(A->getValue());
       if (Arch == llvm::Triple::UnknownArch) {
         Diag(clang::diag::err_drv_invalid_arch_name)
           << A->getAsString(Args);
@@ -934,13 +930,12 @@
         Actions.push_back(new DsymutilJobAction(Inputs, types::TY_dSYM));
       }
 
-      // Verify the output (debug information only) if we passed '-verify'.
-      if (Args.hasArg(options::OPT_verify)) {
-        ActionList VerifyInputs;
-        VerifyInputs.push_back(Actions.back());
+      // Verify the debug info output.
+      if (Args.hasArg(options::OPT_verify_debug_info)) {
+        Action *VerifyInput = Actions.back();
         Actions.pop_back();
-        Actions.push_back(new VerifyJobAction(VerifyInputs,
-                                              types::TY_Nothing));
+        Actions.push_back(new VerifyDebugInfoJobAction(VerifyInput,
+                                                       types::TY_Nothing));
       }
     }
   }
@@ -948,7 +943,7 @@
 
 /// \brief Check that the file referenced by Value exists. If it doesn't,
 /// issue a diagnostic and return false.
-static bool DiagnoseInputExistance(const Driver &D, const DerivedArgList &Args,
+static bool DiagnoseInputExistence(const Driver &D, const DerivedArgList &Args,
                                    StringRef Value) {
   if (!D.getCheckInputsExist())
     return true;
@@ -969,18 +964,21 @@
   if (llvm::sys::fs::exists(Twine(Path)))
     return true;
 
+  if (D.IsCLMode() && llvm::sys::Process::FindInEnvPath("LIB", Value))
+    return true;
+
   D.Diag(clang::diag::err_drv_no_such_file) << Path.str();
   return false;
 }
 
 // Construct a the list of inputs and their types.
-void Driver::BuildInputs(const ToolChain &TC, const DerivedArgList &Args,
+void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args,
                          InputList &Inputs) const {
   // Track the current user specified (-x) input. We also explicitly track the
   // argument used to set the type; we only want to claim the type when we
   // actually use it, so we warn about unused -x arguments.
   types::ID InputType = types::TY_Nothing;
-  Arg *InputTypeArg = 0;
+  Arg *InputTypeArg = nullptr;
 
   // The last /TC or /TP option sets the input type to C or C++ globally.
   if (Arg *TCTP = Args.getLastArg(options::OPT__SLASH_TC,
@@ -1029,7 +1027,8 @@
           // Otherwise emit an error but still use a valid type to avoid
           // spurious errors (e.g., no inputs).
           if (!Args.hasArgNoClaim(options::OPT_E) && !CCCIsCPP())
-            Diag(clang::diag::err_drv_unknown_stdin_type);
+            Diag(IsCLMode() ? clang::diag::err_drv_unknown_stdin_type_clang_cl
+                            : clang::diag::err_drv_unknown_stdin_type);
           Ty = types::TY_C;
         } else {
           // Otherwise lookup by extension.
@@ -1075,19 +1074,19 @@
         Ty = InputType;
       }
 
-      if (DiagnoseInputExistance(*this, Args, Value))
+      if (DiagnoseInputExistence(*this, Args, Value))
         Inputs.push_back(std::make_pair(Ty, A));
 
     } else if (A->getOption().matches(options::OPT__SLASH_Tc)) {
       StringRef Value = A->getValue();
-      if (DiagnoseInputExistance(*this, Args, Value)) {
+      if (DiagnoseInputExistence(*this, Args, Value)) {
         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 (DiagnoseInputExistance(*this, Args, Value)) {
+      if (DiagnoseInputExistence(*this, Args, Value)) {
         Arg *InputArg = MakeInputArg(Args, Opts, A->getValue());
         Inputs.push_back(std::make_pair(types::TY_CXX, InputArg));
       }
@@ -1177,7 +1176,7 @@
 
   // Construct the actions to perform.
   ActionList LinkerInputs;
-  ActionList SplitInputs;
+
   llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> PL;
   for (unsigned i = 0, e = Inputs.size(); i != e; ++i) {
     types::ID InputType = Inputs[i].first;
@@ -1211,18 +1210,18 @@
         Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
           << InputArg->getAsString(Args)
           << !!FinalPhaseArg
-          << FinalPhaseArg ? FinalPhaseArg->getOption().getName() : "";
+          << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() : "");
       else
         Diag(clang::diag::warn_drv_input_file_unused)
           << InputArg->getAsString(Args)
           << getPhaseName(InitialPhase)
           << !!FinalPhaseArg
-          << FinalPhaseArg ? FinalPhaseArg->getOption().getName() : "";
+          << (FinalPhaseArg ? FinalPhaseArg->getOption().getName() : "");
       continue;
     }
 
     // Build the pipeline for this file.
-    OwningPtr<Action> Current(new InputAction(*InputArg, InputType));
+    std::unique_ptr<Action> Current(new InputAction(*InputArg, InputType));
     for (SmallVectorImpl<phases::ID>::iterator
            i = PL.begin(), e = PL.end(); i != e; ++i) {
       phases::ID Phase = *i;
@@ -1234,7 +1233,7 @@
       // Queue linker inputs.
       if (Phase == phases::Link) {
         assert((i + 1) == e && "linking must be final compilation step.");
-        LinkerInputs.push_back(Current.take());
+        LinkerInputs.push_back(Current.release());
         break;
       }
 
@@ -1245,14 +1244,14 @@
         continue;
 
       // Otherwise construct the appropriate action.
-      Current.reset(ConstructPhaseAction(Args, Phase, Current.take()));
+      Current.reset(ConstructPhaseAction(Args, Phase, Current.release()));
       if (Current->getType() == types::TY_Nothing)
         break;
     }
 
     // If we ended with something, add to the output list.
     if (Current)
-      Actions.push_back(Current.take());
+      Actions.push_back(Current.release());
   }
 
   // Add a link action if necessary.
@@ -1284,7 +1283,8 @@
     } else {
       OutputTy = Input->getType();
       if (!Args.hasFlag(options::OPT_frewrite_includes,
-                        options::OPT_fno_rewrite_includes, false))
+                        options::OPT_fno_rewrite_includes, false) &&
+          !CCGenDiagnostics)
         OutputTy = types::getPreprocessedType(OutputTy);
       assert(OutputTy != types::TY_INVALID &&
              "Cannot preprocess this input type!");
@@ -1314,6 +1314,8 @@
       return new CompileJobAction(Input, types::TY_AST);
     } else if (Args.hasArg(options::OPT_module_file_info)) {
       return new CompileJobAction(Input, types::TY_ModuleFile);
+    } else if (Args.hasArg(options::OPT_verify_pch)) {
+      return new VerifyPCHJobAction(Input, types::TY_Nothing);
     } else if (IsUsingLTO(Args)) {
       types::ID Output =
         Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
@@ -1356,13 +1358,13 @@
 
     if (NumOutputs > 1) {
       Diag(clang::diag::err_drv_output_argument_with_multiple_files);
-      FinalOutput = 0;
+      FinalOutput = nullptr;
     }
   }
 
   // Collect the list of architectures.
   llvm::StringSet<> ArchNames;
-  if (C.getDefaultToolChain().getTriple().isOSDarwin()) {
+  if (C.getDefaultToolChain().getTriple().isOSBinFormatMachO()) {
     for (ArgList::const_iterator it = C.getArgs().begin(), ie = C.getArgs().end();
          it != ie; ++it) {
       Arg *A = *it;
@@ -1381,7 +1383,7 @@
     //
     // FIXME: This is a hack; find a cleaner way to integrate this into the
     // process.
-    const char *LinkingOutput = 0;
+    const char *LinkingOutput = nullptr;
     if (isa<LipoJobAction>(A)) {
       if (FinalOutput)
         LinkingOutput = FinalOutput->getValue();
@@ -1391,7 +1393,7 @@
 
     InputInfo II;
     BuildJobsForAction(C, A, &C.getDefaultToolChain(),
-                       /*BoundArch*/0,
+                       /*BoundArch*/nullptr,
                        /*AtTopLevel*/ true,
                        /*MultipleArchs*/ ArchNames.size() > 1,
                        /*LinkingOutput*/ LinkingOutput,
@@ -1448,7 +1450,7 @@
 static const Tool *SelectToolForJob(Compilation &C, const ToolChain *TC,
                                     const JobAction *JA,
                                     const ActionList *&Inputs) {
-  const Tool *ToolForJob = 0;
+  const Tool *ToolForJob = nullptr;
 
   // See if we should look for a compiler with an integrated assembler. We match
   // bottom up, so what we are actually looking for is an assembler job with a
@@ -1456,6 +1458,7 @@
 
   if (TC->useIntegratedAs() &&
       !C.getArgs().hasArg(options::OPT_save_temps) &&
+      !C.getArgs().hasArg(options::OPT_via_file_asm) &&
       !C.getArgs().hasArg(options::OPT__SLASH_FA) &&
       !C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
       isa<AssembleJobAction>(JA) &&
@@ -1463,7 +1466,7 @@
     const Tool *Compiler =
       TC->SelectTool(cast<JobAction>(**Inputs->begin()));
     if (!Compiler)
-      return NULL;
+      return nullptr;
     if (Compiler->hasIntegratedAssembler()) {
       Inputs = &(*Inputs)[0]->getInputs();
       ToolForJob = Compiler;
@@ -1587,7 +1590,7 @@
 static const char *MakeCLOutputFilename(const ArgList &Args, StringRef ArgValue,
                                         StringRef BaseName, types::ID FileType) {
   SmallString<128> Filename = ArgValue;
-  
+
   if (ArgValue.empty()) {
     // If the argument is empty, output to BaseName in the current dir.
     Filename = BaseName;
@@ -1626,6 +1629,17 @@
       return C.addResultFile(FinalOutput->getValue(), &JA);
   }
 
+  // For /P, preprocess to file named after BaseInput.
+  if (C.getArgs().hasArg(options::OPT__SLASH_P)) {
+    assert(AtTopLevel && isa<PreprocessJobAction>(JA));
+    StringRef BaseName = llvm::sys::path::filename(BaseInput);
+    StringRef NameArg;
+    if (Arg *A = C.getArgs().getLastArg(options::OPT__SLASH_Fi))
+      NameArg = A->getValue();
+    return C.addResultFile(MakeCLOutputFilename(C.getArgs(), NameArg, BaseName,
+                                                types::TY_PP_C), &JA);
+  }
+
   // Default to writing to stdout?
   if (AtTopLevel && !CCGenDiagnostics &&
       (isa<PreprocessJobAction>(JA) || JA.getType() == types::TY_ModuleFile))
@@ -1831,8 +1845,7 @@
 std::string Driver::GetTemporaryPath(StringRef Prefix, const char *Suffix)
   const {
   SmallString<128> Path;
-  llvm::error_code EC =
-      llvm::sys::fs::createTemporaryFile(Prefix, Suffix, Path);
+  std::error_code EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, Path);
   if (EC) {
     Diag(clang::diag::err_unable_to_make_temp) << EC.message();
     return "";
@@ -1854,36 +1867,43 @@
 
   llvm::Triple Target(llvm::Triple::normalize(DefaultTargetTriple));
 
-  // Handle Darwin-specific options available here.
-  if (Target.isOSDarwin()) {
+  // Handle Apple-specific options available here.
+  if (Target.isOSBinFormatMachO()) {
     // If an explict Darwin arch name is given, that trumps all.
     if (!DarwinArchName.empty()) {
-      Target.setArch(
-        tools::darwin::getArchTypeForDarwinArchName(DarwinArchName));
+      tools::darwin::setTripleTypeForMachOArchName(Target, DarwinArchName);
       return Target;
     }
 
     // Handle the Darwin '-arch' flag.
     if (Arg *A = Args.getLastArg(options::OPT_arch)) {
-      llvm::Triple::ArchType DarwinArch
-        = tools::darwin::getArchTypeForDarwinArchName(A->getValue());
-      if (DarwinArch != llvm::Triple::UnknownArch)
-        Target.setArch(DarwinArch);
+      StringRef ArchName = A->getValue();
+      tools::darwin::setTripleTypeForMachOArchName(Target, ArchName);
     }
   }
 
-  // Handle pseudo-target flags '-EL' and '-EB'.
-  if (Arg *A = Args.getLastArg(options::OPT_EL, options::OPT_EB)) {
-    if (A->getOption().matches(options::OPT_EL)) {
+  // Handle pseudo-target flags '-mlittle-endian'/'-EL' and
+  // '-mbig-endian'/'-EB'.
+  if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
+                               options::OPT_mbig_endian)) {
+    if (A->getOption().matches(options::OPT_mlittle_endian)) {
       if (Target.getArch() == llvm::Triple::mips)
         Target.setArch(llvm::Triple::mipsel);
       else if (Target.getArch() == llvm::Triple::mips64)
         Target.setArch(llvm::Triple::mips64el);
+      else if (Target.getArch() == llvm::Triple::aarch64_be)
+        Target.setArch(llvm::Triple::aarch64);
+      else if (Target.getArch() == llvm::Triple::arm64_be)
+        Target.setArch(llvm::Triple::arm64);
     } else {
       if (Target.getArch() == llvm::Triple::mipsel)
         Target.setArch(llvm::Triple::mips);
       else if (Target.getArch() == llvm::Triple::mips64el)
         Target.setArch(llvm::Triple::mips64);
+      else if (Target.getArch() == llvm::Triple::aarch64)
+        Target.setArch(llvm::Triple::aarch64_be);
+      else if (Target.getArch() == llvm::Triple::arm64)
+        Target.setArch(llvm::Triple::arm64_be);
     }
   }
 
@@ -1893,20 +1913,27 @@
       Target.getOS() == llvm::Triple::Minix)
     return Target;
 
-  // Handle pseudo-target flags '-m32' and '-m64'.
-  // FIXME: Should this information be in llvm::Triple?
-  if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) {
-    if (A->getOption().matches(options::OPT_m32)) {
-      if (Target.getArch() == llvm::Triple::x86_64)
-        Target.setArch(llvm::Triple::x86);
-      if (Target.getArch() == llvm::Triple::ppc64)
-        Target.setArch(llvm::Triple::ppc);
-    } else {
-      if (Target.getArch() == llvm::Triple::x86)
-        Target.setArch(llvm::Triple::x86_64);
-      if (Target.getArch() == llvm::Triple::ppc)
-        Target.setArch(llvm::Triple::ppc64);
+  // Handle pseudo-target flags '-m64', '-mx32', '-m32' and '-m16'.
+  if (Arg *A = Args.getLastArg(options::OPT_m64, options::OPT_mx32,
+                               options::OPT_m32, options::OPT_m16)) {
+    llvm::Triple::ArchType AT = llvm::Triple::UnknownArch;
+
+    if (A->getOption().matches(options::OPT_m64))
+      AT = Target.get64BitArchVariant().getArch();
+    else if (A->getOption().matches(options::OPT_mx32) &&
+             Target.get64BitArchVariant().getArch() == llvm::Triple::x86_64) {
+      AT = llvm::Triple::x86_64;
+      Target.setEnvironment(llvm::Triple::GNUX32);
+    } else if (A->getOption().matches(options::OPT_m32))
+      AT = Target.get32BitArchVariant().getArch();
+    else if (A->getOption().matches(options::OPT_m16) &&
+             Target.get32BitArchVariant().getArch() == llvm::Triple::x86) {
+      AT = llvm::Triple::x86;
+      Target.setEnvironment(llvm::Triple::CODE16);
     }
+
+    if (AT != llvm::Triple::UnknownArch)
+      Target.setArch(AT);
   }
 
   return Target;
@@ -1926,13 +1953,7 @@
     case llvm::Triple::Darwin:
     case llvm::Triple::MacOSX:
     case llvm::Triple::IOS:
-      if (Target.getArch() == llvm::Triple::x86 ||
-          Target.getArch() == llvm::Triple::x86_64 ||
-          Target.getArch() == llvm::Triple::arm ||
-          Target.getArch() == llvm::Triple::thumb)
-        TC = new toolchains::DarwinClang(*this, Target, Args);
-      else
-        TC = new toolchains::Darwin_Generic_GCC(*this, Target, Args);
+      TC = new toolchains::DarwinClang(*this, Target, Args);
       break;
     case llvm::Triple::DragonFly:
       TC = new toolchains::DragonFly(*this, Target, Args);
@@ -1958,17 +1979,41 @@
       else
         TC = new toolchains::Linux(*this, Target, Args);
       break;
+    // @LOCALMOD-START
+    case llvm::Triple::NaCl:
+      TC = new toolchains::NaCl_TC(*this, Target, Args);
+      break;
+    // @LOCALMOD-END
     case llvm::Triple::Solaris:
       TC = new toolchains::Solaris(*this, Target, Args);
       break;
     case llvm::Triple::Win32:
-      TC = new toolchains::Windows(*this, Target, Args);
+      switch (Target.getEnvironment()) {
+      default:
+        if (Target.isOSBinFormatELF())
+          TC = new toolchains::Generic_ELF(*this, Target, Args);
+        else if (Target.isOSBinFormatMachO())
+          TC = new toolchains::MachO(*this, Target, Args);
+        else
+          TC = new toolchains::Generic_GCC(*this, Target, Args);
+        break;
+      case llvm::Triple::GNU:
+        // FIXME: We need a MinGW toolchain.  Use the default Generic_GCC
+        // toolchain for now as the default case would below otherwise.
+        if (Target.isOSBinFormatELF())
+          TC = new toolchains::Generic_ELF(*this, Target, Args);
+        else
+          TC = new toolchains::Generic_GCC(*this, Target, Args);
+        break;
+      case llvm::Triple::MSVC:
+      case llvm::Triple::UnknownEnvironment:
+        TC = new toolchains::Windows(*this, Target, Args);
+        break;
+      }
       break;
     case llvm::Triple::Emscripten:
       TC = new toolchains::EmscriptenToolChain(*this, Target, Args);
       break;
-    case llvm::Triple::MinGW32:
-      // FIXME: We need a MinGW toolchain. Fallthrough for now.
     default:
       // TCE is an OSless target
       if (Target.getArchName() == "tce") {
@@ -1984,6 +2029,14 @@
         TC = new toolchains::XCore(*this, Target, Args);
         break;
       }
+      if (Target.isOSBinFormatELF()) {
+        TC = new toolchains::Generic_ELF(*this, Target, Args);
+        break;
+      }
+      if (Target.getObjectFormat() == llvm::Triple::MachO) {
+        TC = new toolchains::MachO(*this, Target, Args);
+        break;
+      }
       TC = new toolchains::Generic_GCC(*this, Target, Args);
       break;
     }
@@ -2058,3 +2111,7 @@
 
   return std::make_pair(IncludedFlagsBitmask, ExcludedFlagsBitmask);
 }
+
+bool clang::driver::isOptimizationLevelFast(const llvm::opt::ArgList &Args) {
+  return Args.hasFlag(options::OPT_Ofast, options::OPT_O_Group, false);
+}
diff --git a/lib/Driver/Job.cpp b/lib/Driver/Job.cpp
index ee68e6f..42cc1bc 100644
--- a/lib/Driver/Job.cpp
+++ b/lib/Driver/Job.cpp
@@ -7,7 +7,11 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
 #include "clang/Driver/Job.h"
+#include "clang/Driver/Tool.h"
+#include "clang/Driver/ToolChain.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/StringSwitch.h"
@@ -37,7 +41,7 @@
     .Cases("-internal-externc-isystem", "-iprefix", "-iwithprefix", true)
     .Cases("-iwithprefixbefore", "-isysroot", "-isystem", "-iquote", true)
     .Cases("-resource-dir", "-serialize-diagnostic-file", true)
-    .Case("-dwarf-debug-flags", true)
+    .Cases("-dwarf-debug-flags", "-ivfsoverlay", true)
     .Default(false);
 
   // Match found.
@@ -58,7 +62,8 @@
 
   // These flags are treated as a single argument (e.g., -F<Dir>).
   StringRef FlagRef(Flag);
-  if (FlagRef.startswith("-F") || FlagRef.startswith("-I"))
+  if (FlagRef.startswith("-F") || FlagRef.startswith("-I") ||
+      FlagRef.startswith("-fmodules-cache-path="))
     return 1;
 
   return 0;
@@ -119,9 +124,9 @@
   Argv.push_back(Executable);
   for (size_t i = 0, e = Arguments.size(); i != e; ++i)
     Argv.push_back(Arguments[i]);
-  Argv.push_back(0);
+  Argv.push_back(nullptr);
 
-  return llvm::sys::ExecuteAndWait(Executable, Argv.data(), /*env*/ 0,
+  return llvm::sys::ExecuteAndWait(Executable, Argv.data(), /*env*/ nullptr,
                                    Redirects, /*secondsToWait*/ 0,
                                    /*memoryLimit*/ 0, ErrMsg, ExecutionFailed);
 }
@@ -159,6 +164,9 @@
   if (ExecutionFailed)
     *ExecutionFailed = false;
 
+  const Driver &D = getCreator().getToolChain().getDriver();
+  D.Diag(diag::warn_drv_invoking_fallback) << Fallback->getExecutable();
+
   int SecondaryStatus = Fallback->Execute(Redirects, ErrMsg, ExecutionFailed);
   return SecondaryStatus;
 }
diff --git a/lib/Driver/Multilib.cpp b/lib/Driver/Multilib.cpp
new file mode 100644
index 0000000..484ce16
--- /dev/null
+++ b/lib/Driver/Multilib.cpp
@@ -0,0 +1,334 @@
+//===--- Multilib.cpp - Multilib Implementation ---------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Driver/Multilib.h"
+#include "Tools.h"
+#include "clang/Driver/Options.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Option/Arg.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Option/OptTable.h"
+#include "llvm/Option/Option.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Regex.h"
+#include "llvm/Support/YAMLParser.h"
+#include "llvm/Support/YAMLTraits.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+
+using namespace clang::driver;
+using namespace clang;
+using namespace llvm::opt;
+using namespace llvm::sys;
+
+/// normalize Segment to "/foo/bar" or "".
+static void normalizePathSegment(std::string &Segment) {
+  StringRef seg = Segment;
+
+  // Prune trailing "/" or "./"
+  while (1) {
+    StringRef last = *--path::end(seg);
+    if (last != ".")
+      break;
+    seg = path::parent_path(seg);
+  }
+
+  if (seg.empty() || seg == "/") {
+    Segment = "";
+    return;
+  }
+
+  // Add leading '/'
+  if (seg.front() != '/') {
+    Segment = "/" + seg.str();
+  } else {
+    Segment = seg;
+  }
+}
+
+Multilib::Multilib(StringRef GCCSuffix, StringRef OSSuffix,
+                   StringRef IncludeSuffix)
+    : GCCSuffix(GCCSuffix), OSSuffix(OSSuffix), IncludeSuffix(IncludeSuffix) {
+  normalizePathSegment(this->GCCSuffix);
+  normalizePathSegment(this->OSSuffix);
+  normalizePathSegment(this->IncludeSuffix);
+}
+
+Multilib &Multilib::gccSuffix(StringRef S) {
+  GCCSuffix = S;
+  normalizePathSegment(GCCSuffix);
+  return *this;
+}
+
+Multilib &Multilib::osSuffix(StringRef S) {
+  OSSuffix = S;
+  normalizePathSegment(OSSuffix);
+  return *this;
+}
+
+Multilib &Multilib::includeSuffix(StringRef S) {
+  IncludeSuffix = S;
+  normalizePathSegment(IncludeSuffix);
+  return *this;
+}
+
+void Multilib::print(raw_ostream &OS) const {
+  assert(GCCSuffix.empty() || (StringRef(GCCSuffix).front() == '/'));
+  if (GCCSuffix.empty())
+    OS << ".";
+  else {
+    OS << StringRef(GCCSuffix).drop_front();
+  }
+  OS << ";";
+  for (StringRef Flag : Flags) {
+    if (Flag.front() == '+')
+      OS << "@" << Flag.substr(1);
+  }
+}
+
+bool Multilib::isValid() const {
+  llvm::StringMap<int> FlagSet;
+  for (unsigned I = 0, N = Flags.size(); I != N; ++I) {
+    StringRef Flag(Flags[I]);
+    llvm::StringMap<int>::iterator SI = FlagSet.find(Flag.substr(1));
+
+    assert(StringRef(Flag).front() == '+' || StringRef(Flag).front() == '-');
+
+    if (SI == FlagSet.end())
+      FlagSet[Flag.substr(1)] = I;
+    else if (Flags[I] != Flags[SI->getValue()])
+      return false;
+  }
+  return true;
+}
+
+bool Multilib::operator==(const Multilib &Other) const {
+  // Check whether the flags sets match
+  // allowing for the match to be order invariant
+  llvm::StringSet<> MyFlags;
+  for (const auto &Flag : Flags)
+    MyFlags.insert(Flag);
+
+  for (const auto &Flag : Other.Flags)
+    if (MyFlags.find(Flag) == MyFlags.end())
+      return false;
+
+  if (osSuffix() != Other.osSuffix())
+    return false;
+
+  if (gccSuffix() != Other.gccSuffix())
+    return false;
+
+  if (includeSuffix() != Other.includeSuffix())
+    return false;
+
+  return true;
+}
+
+raw_ostream &clang::driver::operator<<(raw_ostream &OS, const Multilib &M) {
+  M.print(OS);
+  return OS;
+}
+
+MultilibSet &MultilibSet::Maybe(const Multilib &M) {
+  Multilib Opposite;
+  // Negate any '+' flags
+  for (StringRef Flag : M.flags()) {
+    if (Flag.front() == '+')
+      Opposite.flags().push_back(("-" + Flag.substr(1)).str());
+  }
+  return Either(M, Opposite);
+}
+
+MultilibSet &MultilibSet::Either(const Multilib &M1, const Multilib &M2) {
+  std::vector<Multilib> Ms;
+  Ms.push_back(M1);
+  Ms.push_back(M2);
+  return Either(Ms);
+}
+
+MultilibSet &MultilibSet::Either(const Multilib &M1, const Multilib &M2,
+                                 const Multilib &M3) {
+  std::vector<Multilib> Ms;
+  Ms.push_back(M1);
+  Ms.push_back(M2);
+  Ms.push_back(M3);
+  return Either(Ms);
+}
+
+MultilibSet &MultilibSet::Either(const Multilib &M1, const Multilib &M2,
+                                 const Multilib &M3, const Multilib &M4) {
+  std::vector<Multilib> Ms;
+  Ms.push_back(M1);
+  Ms.push_back(M2);
+  Ms.push_back(M3);
+  Ms.push_back(M4);
+  return Either(Ms);
+}
+
+MultilibSet &MultilibSet::Either(const Multilib &M1, const Multilib &M2,
+                                 const Multilib &M3, const Multilib &M4,
+                                 const Multilib &M5) {
+  std::vector<Multilib> Ms;
+  Ms.push_back(M1);
+  Ms.push_back(M2);
+  Ms.push_back(M3);
+  Ms.push_back(M4);
+  Ms.push_back(M5);
+  return Either(Ms);
+}
+
+static Multilib compose(const Multilib &Base, const Multilib &New) {
+  SmallString<128> GCCSuffix;
+  llvm::sys::path::append(GCCSuffix, "/", Base.gccSuffix(), New.gccSuffix());
+  SmallString<128> OSSuffix;
+  llvm::sys::path::append(OSSuffix, "/", Base.osSuffix(), New.osSuffix());
+  SmallString<128> IncludeSuffix;
+  llvm::sys::path::append(IncludeSuffix, "/", Base.includeSuffix(),
+                          New.includeSuffix());
+
+  Multilib Composed(GCCSuffix.str(), OSSuffix.str(), IncludeSuffix.str());
+
+  Multilib::flags_list &Flags = Composed.flags();
+
+  Flags.insert(Flags.end(), Base.flags().begin(), Base.flags().end());
+  Flags.insert(Flags.end(), New.flags().begin(), New.flags().end());
+
+  return Composed;
+}
+
+MultilibSet &
+MultilibSet::Either(const std::vector<Multilib> &MultilibSegments) {
+  multilib_list Composed;
+
+  if (Multilibs.empty())
+    Multilibs.insert(Multilibs.end(), MultilibSegments.begin(),
+                     MultilibSegments.end());
+  else {
+    for (const Multilib &New : MultilibSegments) {
+      for (const Multilib &Base : *this) {
+        Multilib MO = compose(Base, New);
+        if (MO.isValid())
+          Composed.push_back(MO);
+      }
+    }
+
+    Multilibs = Composed;
+  }
+
+  return *this;
+}
+
+MultilibSet &MultilibSet::FilterOut(const MultilibSet::FilterCallback &F) {
+  filterInPlace(F, Multilibs);
+  return *this;
+}
+
+MultilibSet &MultilibSet::FilterOut(std::string Regex) {
+  class REFilter : public MultilibSet::FilterCallback {
+    mutable llvm::Regex R;
+
+  public:
+    REFilter(std::string Regex) : R(Regex) {}
+    bool operator()(const Multilib &M) const override {
+      std::string Error;
+      if (!R.isValid(Error)) {
+        llvm::errs() << Error;
+        assert(false);
+        return false;
+      }
+      return R.match(M.gccSuffix());
+    }
+  };
+
+  REFilter REF(Regex);
+  filterInPlace(REF, Multilibs);
+  return *this;
+}
+
+void MultilibSet::push_back(const Multilib &M) { Multilibs.push_back(M); }
+
+void MultilibSet::combineWith(const MultilibSet &Other) {
+  Multilibs.insert(Multilibs.end(), Other.begin(), Other.end());
+}
+
+bool MultilibSet::select(const Multilib::flags_list &Flags, Multilib &M) const {
+  class FilterFlagsMismatch : public MultilibSet::FilterCallback {
+    llvm::StringMap<bool> FlagSet;
+
+  public:
+    FilterFlagsMismatch(const std::vector<std::string> &Flags) {
+      // Stuff all of the flags into the FlagSet such that a true mappend
+      // indicates the flag was enabled, and a false mappend indicates the
+      // flag was disabled
+      for (StringRef Flag : Flags)
+        FlagSet[Flag.substr(1)] = isFlagEnabled(Flag);
+    }
+    bool operator()(const Multilib &M) const override {
+      for (StringRef Flag : M.flags()) {
+        llvm::StringMap<bool>::const_iterator SI = FlagSet.find(Flag.substr(1));
+        if (SI != FlagSet.end())
+          if (SI->getValue() != isFlagEnabled(Flag))
+            return true;
+      }
+      return false;
+    }
+  private:
+    bool isFlagEnabled(StringRef Flag) const {
+      char Indicator = Flag.front();
+      assert(Indicator == '+' || Indicator == '-');
+      return Indicator == '+';
+    }
+  };
+
+  FilterFlagsMismatch FlagsMismatch(Flags);
+
+  multilib_list Filtered = filterCopy(FlagsMismatch, Multilibs);
+
+  if (Filtered.size() == 0) {
+    return false;
+  } else if (Filtered.size() == 1) {
+    M = Filtered[0];
+    return true;
+  }
+
+  // TODO: pick the "best" multlib when more than one is suitable
+  assert(false);
+
+  return false;
+}
+
+void MultilibSet::print(raw_ostream &OS) const {
+  for (const Multilib &M : *this)
+    OS << M << "\n";
+}
+
+MultilibSet::multilib_list
+MultilibSet::filterCopy(const MultilibSet::FilterCallback &F,
+                        const multilib_list &Ms) {
+  multilib_list Copy(Ms);
+  filterInPlace(F, Copy);
+  return Copy;
+}
+
+void MultilibSet::filterInPlace(const MultilibSet::FilterCallback &F,
+                                multilib_list &Ms) {
+  Ms.erase(std::remove_if(Ms.begin(), Ms.end(),
+                          [&F](const Multilib &M) { return F(M); }),
+           Ms.end());
+}
+
+raw_ostream &clang::driver::operator<<(raw_ostream &OS, const MultilibSet &MS) {
+  MS.print(OS);
+  return OS;
+}
diff --git a/lib/Driver/SanitizerArgs.cpp b/lib/Driver/SanitizerArgs.cpp
index 43209f0..b64f027 100644
--- a/lib/Driver/SanitizerArgs.cpp
+++ b/lib/Driver/SanitizerArgs.cpp
@@ -7,16 +7,16 @@
 //
 //===----------------------------------------------------------------------===//
 #include "clang/Driver/SanitizerArgs.h"
-
 #include "clang/Driver/Driver.h"
 #include "clang/Driver/DriverDiagnostic.h"
 #include "clang/Driver/Options.h"
 #include "clang/Driver/ToolChain.h"
-#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
-#include "llvm/Transforms/Utils/SpecialCaseList.h"
+#include "llvm/Support/SpecialCaseList.h"
+#include <memory>
 
 using namespace clang::driver;
 using namespace llvm::opt;
@@ -24,9 +24,10 @@
 void SanitizerArgs::clear() {
   Kind = 0;
   BlacklistFile = "";
-  MsanTrackOrigins = false;
+  MsanTrackOrigins = 0;
   AsanZeroBaseShadow = false;
   UbsanTrapOnError = false;
+  AsanSharedRuntime = false;
 }
 
 SanitizerArgs::SanitizerArgs() {
@@ -72,30 +73,14 @@
   }
 
   UbsanTrapOnError =
-    Args.hasArg(options::OPT_fcatch_undefined_behavior) ||
     Args.hasFlag(options::OPT_fsanitize_undefined_trap_on_error,
                  options::OPT_fno_sanitize_undefined_trap_on_error, false);
 
-  if (Args.hasArg(options::OPT_fcatch_undefined_behavior) &&
-      !Args.hasFlag(options::OPT_fsanitize_undefined_trap_on_error,
-                    options::OPT_fno_sanitize_undefined_trap_on_error, true)) {
-    D.Diag(diag::err_drv_argument_not_allowed_with)
-      << "-fcatch-undefined-behavior"
-      << "-fno-sanitize-undefined-trap-on-error";
-  }
-
   // Warn about undefined sanitizer options that require runtime support.
   if (UbsanTrapOnError && notAllowedWithTrap()) {
-    if (Args.hasArg(options::OPT_fcatch_undefined_behavior))
-      D.Diag(diag::err_drv_argument_not_allowed_with)
-        << lastArgumentForKind(D, Args, NotAllowedWithTrap)
-        << "-fcatch-undefined-behavior";
-    else if (Args.hasFlag(options::OPT_fsanitize_undefined_trap_on_error,
-                          options::OPT_fno_sanitize_undefined_trap_on_error,
-                          false))
-      D.Diag(diag::err_drv_argument_not_allowed_with)
-        << lastArgumentForKind(D, Args, NotAllowedWithTrap)
-        << "-fsanitize-undefined-trap-on-error";
+    D.Diag(diag::err_drv_argument_not_allowed_with)
+      << lastArgumentForKind(D, Args, NotAllowedWithTrap)
+      << "-fsanitize-undefined-trap-on-error";
   }
 
   // Only one runtime library can be used at once.
@@ -123,19 +108,11 @@
     D.Diag(diag::err_drv_argument_not_allowed_with)
       << lastArgumentForKind(D, Args, NeedsLeakDetection)
       << lastArgumentForKind(D, Args, NeedsMsanRt);
-  // FIXME: Currenly -fsanitize=leak is silently ignored in the presence of
+  // FIXME: Currently -fsanitize=leak is silently ignored in the presence of
   // -fsanitize=address. Perhaps it should print an error, or perhaps
   // -f(-no)sanitize=leak should change whether leak detection is enabled by
   // default in ASan?
 
-  // If -fsanitize contains extra features of ASan, it should also
-  // explicitly contain -fsanitize=address (probably, turned off later in the
-  // command line).
-  if ((Kind & AddressFull) != 0 && (AllAdd & Address) == 0)
-    D.Diag(diag::warn_drv_unused_sanitizer)
-     << lastArgumentForKind(D, Args, AddressFull)
-     << "-fsanitize=address";
-
   // Parse -f(no-)sanitize-blacklist options.
   if (Arg *BLArg = Args.getLastArg(options::OPT_fsanitize_blacklist,
                                    options::OPT_fno_sanitize_blacklist)) {
@@ -144,7 +121,7 @@
       if (llvm::sys::fs::exists(BLPath)) {
         // Validate the blacklist format.
         std::string BLError;
-        llvm::OwningPtr<llvm::SpecialCaseList> SCL(
+        std::unique_ptr<llvm::SpecialCaseList> SCL(
             llvm::SpecialCaseList::create(BLPath, BLError));
         if (!SCL.get())
           D.Diag(diag::err_drv_malformed_sanitizer_blacklist) << BLError;
@@ -163,28 +140,34 @@
       BlacklistFile = BLPath;
   }
 
-  // Parse -f(no-)sanitize-memory-track-origins options.
-  if (NeedsMsan)
-    MsanTrackOrigins =
-      Args.hasFlag(options::OPT_fsanitize_memory_track_origins,
-                   options::OPT_fno_sanitize_memory_track_origins,
-                   /* Default */false);
-
-  // Parse -f(no-)sanitize-address-zero-base-shadow options.
-  if (NeedsAsan) {
-    bool IsAndroid = (TC.getTriple().getEnvironment() == llvm::Triple::Android);
-    bool ZeroBaseShadowDefault = IsAndroid;
-    AsanZeroBaseShadow =
-        Args.hasFlag(options::OPT_fsanitize_address_zero_base_shadow,
-                     options::OPT_fno_sanitize_address_zero_base_shadow,
-                     ZeroBaseShadowDefault);
-    // Zero-base shadow is a requirement on Android.
-    if (IsAndroid && !AsanZeroBaseShadow) {
-      D.Diag(diag::err_drv_argument_not_allowed_with)
-          << "-fno-sanitize-address-zero-base-shadow"
-          << lastArgumentForKind(D, Args, Address);
+  // Parse -f[no-]sanitize-memory-track-origins[=level] options.
+  if (NeedsMsan) {
+    if (Arg *A =
+            Args.getLastArg(options::OPT_fsanitize_memory_track_origins_EQ,
+                            options::OPT_fsanitize_memory_track_origins,
+                            options::OPT_fno_sanitize_memory_track_origins)) {
+      if (A->getOption().matches(options::OPT_fsanitize_memory_track_origins)) {
+        MsanTrackOrigins = 1;
+      } else if (A->getOption().matches(
+                     options::OPT_fno_sanitize_memory_track_origins)) {
+        MsanTrackOrigins = 0;
+      } else {
+        StringRef S = A->getValue();
+        if (S.getAsInteger(0, MsanTrackOrigins) || MsanTrackOrigins < 0 ||
+            MsanTrackOrigins > 2) {
+          D.Diag(diag::err_drv_invalid_value) << A->getAsString(Args) << S;
+        }
+      }
     }
   }
+
+  if (NeedsAsan) {
+    AsanSharedRuntime =
+        Args.hasArg(options::OPT_shared_libasan) ||
+        (TC.getTriple().getEnvironment() == llvm::Triple::Android);
+    AsanZeroBaseShadow =
+        (TC.getTriple().getEnvironment() == llvm::Triple::Android);
+  }
 }
 
 void SanitizerArgs::addArgs(const llvm::opt::ArgList &Args,
@@ -205,11 +188,8 @@
   }
 
   if (MsanTrackOrigins)
-    CmdArgs.push_back(Args.MakeArgString("-fsanitize-memory-track-origins"));
-
-  if (AsanZeroBaseShadow)
-    CmdArgs.push_back(
-        Args.MakeArgString("-fsanitize-address-zero-base-shadow"));
+    CmdArgs.push_back(Args.MakeArgString("-fsanitize-memory-track-origins=" +
+                                         llvm::utostr(MsanTrackOrigins)));
 
   // Workaround for PR16386.
   if (needsMsanRt())
@@ -222,11 +202,6 @@
 #define SANITIZER_GROUP(NAME, ID, ALIAS) .Case(NAME, ID##Group)
 #include "clang/Basic/Sanitizers.def"
     .Default(SanitizeKind());
-  // Assume -fsanitize=address implies -fsanitize=init-order,use-after-return.
-  // FIXME: This should be either specified in Sanitizers.def, or go away when
-  // we get rid of "-fsanitize=init-order,use-after-return" flags at all.
-  if (ParsedKind & Address)
-    ParsedKind |= InitOrder | UseAfterReturn;
   return ParsedKind;
 }
 
@@ -296,28 +271,7 @@
                           unsigned &Remove, bool DiagnoseErrors) {
   Add = 0;
   Remove = 0;
-  const char *DeprecatedReplacement = 0;
-  if (A->getOption().matches(options::OPT_faddress_sanitizer)) {
-    Add = Address;
-    DeprecatedReplacement = "-fsanitize=address";
-  } else if (A->getOption().matches(options::OPT_fno_address_sanitizer)) {
-    Remove = Address;
-    DeprecatedReplacement = "-fno-sanitize=address";
-  } else if (A->getOption().matches(options::OPT_fthread_sanitizer)) {
-    Add = Thread;
-    DeprecatedReplacement = "-fsanitize=thread";
-  } else if (A->getOption().matches(options::OPT_fno_thread_sanitizer)) {
-    Remove = Thread;
-    DeprecatedReplacement = "-fno-sanitize=thread";
-  } else if (A->getOption().matches(options::OPT_fcatch_undefined_behavior)) {
-    Add = UndefinedTrap;
-    DeprecatedReplacement =
-      "-fsanitize=undefined-trap -fsanitize-undefined-trap-on-error";
-  } else if (A->getOption().matches(options::OPT_fbounds_checking) ||
-             A->getOption().matches(options::OPT_fbounds_checking_EQ)) {
-    Add = LocalBounds;
-    DeprecatedReplacement = "-fsanitize=local-bounds";
-  } else if (A->getOption().matches(options::OPT_fsanitize_EQ)) {
+  if (A->getOption().matches(options::OPT_fsanitize_EQ)) {
     Add = parse(D, A, DiagnoseErrors);
   } else if (A->getOption().matches(options::OPT_fno_sanitize_EQ)) {
     Remove = parse(D, A, DiagnoseErrors);
@@ -325,11 +279,6 @@
     // Flag is not relevant to sanitizers.
     return false;
   }
-  // If this is a deprecated synonym, produce a warning directing users
-  // towards the new spelling.
-  if (DeprecatedReplacement && DiagnoseErrors)
-    D.Diag(diag::warn_drv_deprecated_arg)
-      << A->getAsString(Args) << DeprecatedReplacement;
   return true;
 }
 
@@ -369,7 +318,7 @@
 
 bool SanitizerArgs::getDefaultBlacklistForKind(const Driver &D, unsigned Kind,
                                                std::string &BLPath) {
-  const char *BlacklistFile = 0;
+  const char *BlacklistFile = nullptr;
   if (Kind & NeedsAsanRt)
     BlacklistFile = "asan_blacklist.txt";
   else if (Kind & NeedsMsanRt)
diff --git a/lib/Driver/ToolChain.cpp b/lib/Driver/ToolChain.cpp
index faa06b6..4f90d08 100644
--- a/lib/Driver/ToolChain.cpp
+++ b/lib/Driver/ToolChain.cpp
@@ -15,6 +15,7 @@
 #include "clang/Driver/Options.h"
 #include "clang/Driver/SanitizerArgs.h"
 #include "clang/Driver/ToolChain.h"
+#include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Option/Arg.h"
 #include "llvm/Option/ArgList.h"
@@ -38,8 +39,8 @@
 }
 
 bool ToolChain::useIntegratedAs() const {
-  return Args.hasFlag(options::OPT_integrated_as,
-                      options::OPT_no_integrated_as,
+  return Args.hasFlag(options::OPT_fintegrated_as,
+                      options::OPT_fno_integrated_as,
                       IsIntegratedAssemblerDefault());
 }
 
@@ -114,7 +115,7 @@
   case Action::BindArchClass:
   case Action::LipoJobClass:
   case Action::DsymutilJobClass:
-  case Action::VerifyJobClass:
+  case Action::VerifyDebugInfoJobClass:
     llvm_unreachable("Invalid tool kind.");
 
   case Action::CompileJobClass:
@@ -122,6 +123,7 @@
   case Action::PreprocessJobClass:
   case Action::AnalyzeJobClass:
   case Action::MigrateJobClass:
+  case Action::VerifyPCHJobClass:
     return getClang();
   }
 
@@ -146,6 +148,30 @@
   return D.GetProgramPath(Name, *this);
 }
 
+std::string ToolChain::GetLinkerPath() const {
+  if (Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ)) {
+    StringRef Suffix = A->getValue();
+
+    // If we're passed -fuse-ld= with no argument, or with the argument ld,
+    // then use whatever the default system linker is.
+    if (Suffix.empty() || Suffix == "ld")
+      return GetProgramPath("ld");
+
+    llvm::SmallString<8> LinkerName("ld.");
+    LinkerName.append(Suffix);
+
+    std::string LinkerPath(GetProgramPath(LinkerName.c_str()));
+    if (llvm::sys::fs::exists(LinkerPath))
+      return LinkerPath;
+
+    getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args);
+    return "";
+  }
+
+  return GetProgramPath("ld");
+}
+
+
 types::ID ToolChain::LookupTypeForExtension(const char *Ext) const {
   return types::lookupTypeForExtension(Ext);
 }
@@ -154,104 +180,27 @@
   return false;
 }
 
+bool ToolChain::isCrossCompiling() const {
+  llvm::Triple HostTriple(LLVM_HOST_TRIPLE);
+  switch (HostTriple.getArch()) {
+  // The A32/T32/T16 instruction sets are not separate architectures in this
+  // context.
+  case llvm::Triple::arm:
+  case llvm::Triple::armeb:
+  case llvm::Triple::thumb:
+  case llvm::Triple::thumbeb:
+    return getArch() != llvm::Triple::arm && getArch() != llvm::Triple::thumb &&
+           getArch() != llvm::Triple::armeb && getArch() != llvm::Triple::thumbeb;
+  default:
+    return HostTriple.getArch() != getArch();
+  }
+}
+
 ObjCRuntime ToolChain::getDefaultObjCRuntime(bool isNonFragile) const {
   return ObjCRuntime(isNonFragile ? ObjCRuntime::GNUstep : ObjCRuntime::GCC,
                      VersionTuple());
 }
 
-/// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targeting.
-//
-// FIXME: tblgen this.
-static const char *getARMTargetCPU(const ArgList &Args,
-                                   const llvm::Triple &Triple) {
-  // For Darwin targets, the -arch option (which is translated to a
-  // corresponding -march option) should determine the architecture
-  // (and the Mach-O slice) regardless of any -mcpu options.
-  if (!Triple.isOSDarwin()) {
-    // FIXME: Warn on inconsistent use of -mcpu and -march.
-    // If we have -mcpu=, use that.
-    if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
-      return A->getValue();
-  }
-
-  StringRef MArch;
-  if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
-    // Otherwise, if we have -march= choose the base CPU for that arch.
-    MArch = A->getValue();
-  } else {
-    // Otherwise, use the Arch from the triple.
-    MArch = Triple.getArchName();
-  }
-
-  const char *result = llvm::StringSwitch<const char *>(MArch)
-    .Cases("armv2", "armv2a","arm2")
-    .Case("armv3", "arm6")
-    .Case("armv3m", "arm7m")
-    .Case("armv4", "strongarm")
-    .Case("armv4t", "arm7tdmi")
-    .Cases("armv5", "armv5t", "arm10tdmi")
-    .Cases("armv5e", "armv5te", "arm1026ejs")
-    .Case("armv5tej", "arm926ej-s")
-    .Cases("armv6", "armv6k", "arm1136jf-s")
-    .Case("armv6j", "arm1136j-s")
-    .Cases("armv6z", "armv6zk", "arm1176jzf-s")
-    .Case("armv6t2", "arm1156t2-s")
-    .Cases("armv6m", "armv6-m", "cortex-m0")
-    .Cases("armv7", "armv7a", "armv7-a", "cortex-a8")
-    .Cases("armv7l", "armv7-l", "cortex-a8")
-    .Cases("armv7f", "armv7-f", "cortex-a9-mp")
-    .Cases("armv7s", "armv7-s", "swift")
-    .Cases("armv7r", "armv7-r", "cortex-r4")
-    .Cases("armv7m", "armv7-m", "cortex-m3")
-    .Cases("armv7em", "armv7e-m", "cortex-m4")
-    .Cases("armv8", "armv8a", "armv8-a", "cortex-a53")
-    .Case("ep9312", "ep9312")
-    .Case("iwmmxt", "iwmmxt")
-    .Case("xscale", "xscale")
-    // If all else failed, return the most base CPU with thumb interworking
-    // supported by LLVM.
-    .Default(0);
-
-  if (result)
-    return result;
-
-  return
-    Triple.getEnvironment() == llvm::Triple::GNUEABIHF
-      ? "arm1176jzf-s"
-      : "arm7tdmi";
-}
-
-/// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular
-/// CPU.
-//
-// FIXME: This is redundant with -mcpu, why does LLVM use this.
-// FIXME: tblgen this, or kill it!
-static const char *getLLVMArchSuffixForARM(StringRef CPU) {
-  return llvm::StringSwitch<const char *>(CPU)
-    .Case("strongarm", "v4")
-    .Cases("arm7tdmi", "arm7tdmi-s", "arm710t", "v4t")
-    .Cases("arm720t", "arm9", "arm9tdmi", "v4t")
-    .Cases("arm920", "arm920t", "arm922t", "v4t")
-    .Cases("arm940t", "ep9312","v4t")
-    .Cases("arm10tdmi",  "arm1020t", "v5")
-    .Cases("arm9e",  "arm926ej-s",  "arm946e-s", "v5e")
-    .Cases("arm966e-s",  "arm968e-s",  "arm10e", "v5e")
-    .Cases("arm1020e",  "arm1022e",  "xscale", "iwmmxt", "v5e")
-    .Cases("arm1136j-s",  "arm1136jf-s",  "arm1176jz-s", "v6")
-    .Cases("arm1176jzf-s",  "mpcorenovfp",  "mpcore", "v6")
-    .Cases("arm1156t2-s",  "arm1156t2f-s", "v6t2")
-    .Cases("cortex-a5", "cortex-a7", "cortex-a8", "v7")
-    .Cases("cortex-a9", "cortex-a12", "cortex-a15", "v7")
-    .Cases("cortex-r4", "cortex-r5", "v7r")
-    .Case("cortex-m0", "v6m")
-    .Case("cortex-m3", "v7m")
-    .Case("cortex-m4", "v7em")
-    .Case("cortex-a9-mp", "v7f")
-    .Case("swift", "v7s")
-    .Cases("cortex-a53", "cortex-a57", "v8")
-    .Default("");
-}
-
 std::string ToolChain::ComputeLLVMTriple(const ArgList &Args,
                                          types::ID InputType) const {
   switch (getTriple().getArch()) {
@@ -260,7 +209,7 @@
 
   case llvm::Triple::x86_64: {
     llvm::Triple Triple = getTriple();
-    if (!Triple.isOSDarwin())
+    if (!Triple.isOSBinFormatMachO())
       return getTripleString();
 
     if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
@@ -273,23 +222,51 @@
     return Triple.getTriple();
   }
   case llvm::Triple::arm:
-  case llvm::Triple::thumb: {
+  case llvm::Triple::armeb:
+  case llvm::Triple::thumb:
+  case llvm::Triple::thumbeb: {
     // FIXME: Factor into subclasses.
     llvm::Triple Triple = getTriple();
+    bool IsBigEndian = getTriple().getArch() == llvm::Triple::armeb ||
+                       getTriple().getArch() == llvm::Triple::thumbeb;
+
+    // Handle pseudo-target flags '-mlittle-endian'/'-EL' and
+    // '-mbig-endian'/'-EB'.
+    if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
+                                 options::OPT_mbig_endian)) {
+      if (A->getOption().matches(options::OPT_mlittle_endian))
+        IsBigEndian = false;
+      else
+        IsBigEndian = true;
+    }
 
     // Thumb2 is the default for V7 on Darwin.
     //
     // FIXME: Thumb should just be another -target-feaure, not in the triple.
-    StringRef Suffix =
-      getLLVMArchSuffixForARM(getARMTargetCPU(Args, Triple));
-    bool ThumbDefault = Suffix.startswith("v6m") ||
-      (Suffix.startswith("v7") && getTriple().isOSDarwin());
-    std::string ArchName = "arm";
+    StringRef Suffix = Triple.isOSBinFormatMachO()
+      ? tools::arm::getLLVMArchSuffixForARM(tools::arm::getARMCPUForMArch(Args, Triple))
+      : tools::arm::getLLVMArchSuffixForARM(tools::arm::getARMTargetCPU(Args, Triple));
+    bool ThumbDefault = Suffix.startswith("v6m") || Suffix.startswith("v7m") ||
+      Suffix.startswith("v7em") ||
+      (Suffix.startswith("v7") && getTriple().isOSBinFormatMachO());
+    // FIXME: this is invalid for WindowsCE
+    if (getTriple().isOSWindows())
+      ThumbDefault = true;
+    std::string ArchName;
+    if (IsBigEndian)
+      ArchName = "armeb";
+    else
+      ArchName = "arm";
 
     // Assembly files should start in ARM mode.
     if (InputType != types::TY_PP_Asm &&
         Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, ThumbDefault))
-      ArchName = "thumb";
+    {
+      if (IsBigEndian)
+        ArchName = "thumbeb";
+      else
+        ArchName = "thumb";
+    }
     Triple.setArchName(ArchName + Suffix.str());
 
     return Triple.getTriple();
@@ -299,13 +276,6 @@
 
 std::string ToolChain::ComputeEffectiveClangTriple(const ArgList &Args, 
                                                    types::ID InputType) const {
-  // Diagnose use of Darwin OS deployment target arguments on non-Darwin.
-  if (Arg *A = Args.getLastArg(options::OPT_mmacosx_version_min_EQ,
-                               options::OPT_miphoneos_version_min_EQ,
-                               options::OPT_mios_simulator_version_min_EQ))
-    getDriver().Diag(diag::err_drv_clang_unsupported)
-      << A->getAsString(Args);
-
   return ComputeLLVMTriple(Args, InputType);
 }
 
@@ -318,6 +288,8 @@
                                       ArgStringList &CC1Args) const {
 }
 
+void ToolChain::addClangWarningOptions(ArgStringList &CC1Args) const {}
+
 ToolChain::RuntimeLibType ToolChain::GetRuntimeLibType(
   const ArgList &Args) const
 {
@@ -425,16 +397,19 @@
 
 bool ToolChain::AddFastMathRuntimeIfAvailable(const ArgList &Args,
                                               ArgStringList &CmdArgs) const {
-  // Check if -ffast-math or -funsafe-math is enabled.
-  Arg *A = Args.getLastArg(options::OPT_ffast_math,
-                           options::OPT_fno_fast_math,
-                           options::OPT_funsafe_math_optimizations,
-                           options::OPT_fno_unsafe_math_optimizations);
+  // Do not check for -fno-fast-math or -fno-unsafe-math when -Ofast passed
+  // (to keep the linker options consistent with gcc and clang itself).
+  if (!isOptimizationLevelFast(Args)) {
+    // Check if -ffast-math or -funsafe-math.
+    Arg *A =
+        Args.getLastArg(options::OPT_ffast_math, options::OPT_fno_fast_math,
+                        options::OPT_funsafe_math_optimizations,
+                        options::OPT_fno_unsafe_math_optimizations);
 
-  if (!A || A->getOption().getID() == options::OPT_fno_fast_math ||
-      A->getOption().getID() == options::OPT_fno_unsafe_math_optimizations)
-    return false;
-
+    if (!A || A->getOption().getID() == options::OPT_fno_fast_math ||
+        A->getOption().getID() == options::OPT_fno_unsafe_math_optimizations)
+      return false;
+  }
   // If crtfastmath.o exists add it to the arguments.
   std::string Path = GetFilePath("crtfastmath.o");
   if (Path == "crtfastmath.o") // Not found.
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index 479f2cc..387c950 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -10,6 +10,7 @@
 #include "ToolChains.h"
 #include "clang/Basic/ObjCRuntime.h"
 #include "clang/Basic/Version.h"
+#include "clang/Config/config.h" // for GCC_INSTALL_PREFIX
 #include "clang/Driver/Compilation.h"
 #include "clang/Driver/Driver.h"
 #include "clang/Driver/DriverDiagnostic.h"
@@ -27,26 +28,33 @@
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/system_error.h"
 #include "llvm/Support/Program.h"
-
-// FIXME: This needs to be listed last until we fix the broken include guards
-// in these files and the LLVM config.h files.
-#include "clang/Config/config.h" // for GCC_INSTALL_PREFIX
-
+#include "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;
 
-/// Darwin - Darwin tool chain for i386 and x86_64.
+MachO::MachO(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);
 
-Darwin::Darwin(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
-  : ToolChain(D, Triple, Args), TargetInitialized(false)
-{
+  // 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) {
   // Compute the initial Darwin version from the triple
   unsigned Major, Minor, Micro;
   if (!Triple.getMacOSXVersion(Major, Minor, Micro))
@@ -67,7 +75,7 @@
     << Major << '.' << Minor << '.' << Micro;
 }
 
-types::ID Darwin::LookupTypeForExtension(const char *Ext) const {
+types::ID MachO::LookupTypeForExtension(const char *Ext) const {
   types::ID Ty = types::lookupTypeForExtension(Ext);
 
   // Darwin always preprocesses assembly files (unless -x is used explicitly).
@@ -77,13 +85,13 @@
   return Ty;
 }
 
-bool Darwin::HasNativeLLVMSupport() const {
+bool MachO::HasNativeLLVMSupport() const {
   return true;
 }
 
 /// Darwin provides an ARC runtime starting in MacOS X 10.7 and iOS 5.0.
 ObjCRuntime Darwin::getDefaultObjCRuntime(bool isNonFragile) const {
-  if (isTargetIPhoneOS())
+  if (isTargetIOSBased())
     return ObjCRuntime(ObjCRuntime::iOS, TargetVersion);
   if (isNonFragile)
     return ObjCRuntime(ObjCRuntime::MacOSX, TargetVersion);
@@ -92,10 +100,12 @@
 
 /// Darwin provides a blocks runtime starting in MacOS X 10.6 and iOS 3.2.
 bool Darwin::hasBlocksRuntime() const {
-  if (isTargetIPhoneOS())
+  if (isTargetIOSBased())
     return !isIPhoneOSVersionLT(3, 2);
-  else
+  else {
+    assert(isTargetMacOS() && "unexpected darwin target");
     return !isMacosxVersionLT(10, 6);
+  }
 }
 
 static const char *GetArmArchForMArch(StringRef Value) {
@@ -109,11 +119,10 @@
     .Cases("armv7a", "armv7-a", "armv7")
     .Cases("armv7r", "armv7-r", "armv7")
     .Cases("armv7em", "armv7e-m", "armv7em")
-    .Cases("armv7f", "armv7-f", "armv7f")
     .Cases("armv7k", "armv7-k", "armv7k")
     .Cases("armv7m", "armv7-m", "armv7m")
     .Cases("armv7s", "armv7-s", "armv7s")
-    .Default(0);
+    .Default(nullptr);
 }
 
 static const char *GetArmArchForMCpu(StringRef Value) {
@@ -124,17 +133,27 @@
     .Case("xscale", "xscale")
     .Cases("arm1136j-s", "arm1136jf-s", "arm1176jz-s", "arm1176jzf-s", "armv6")
     .Case("cortex-m0", "armv6m")
-    .Cases("cortex-a5", "cortex-a7", "cortex-a8", "armv7")
-    .Cases("cortex-a9", "cortex-a12", "cortex-a15", "armv7")
+    .Cases("cortex-a5", "cortex-a7", "cortex-a8", "cortex-a9-mp", "armv7")
+    .Cases("cortex-a9", "cortex-a12", "cortex-a15", "krait", "armv7")
     .Cases("cortex-r4", "cortex-r5", "armv7r")
-    .Case("cortex-a9-mp", "armv7f")
     .Case("cortex-m3", "armv7m")
     .Case("cortex-m4", "armv7em")
     .Case("swift", "armv7s")
-    .Default(0);
+    .Default(nullptr);
 }
 
-StringRef Darwin::getDarwinArchName(const ArgList &Args) const {
+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 getArchName();
@@ -157,6 +176,17 @@
 Darwin::~Darwin() {
 }
 
+MachO::~MachO() {
+}
+
+
+std::string MachO::ComputeEffectiveClangTriple(const ArgList &Args,
+                                                    types::ID InputType) const {
+  llvm::Triple Triple(ComputeLLVMTriple(Args, InputType));
+
+  return Triple.getTriple();
+}
+
 std::string Darwin::ComputeEffectiveClangTriple(const ArgList &Args,
                                                 types::ID InputType) const {
   llvm::Triple Triple(ComputeLLVMTriple(Args, InputType));
@@ -166,25 +196,17 @@
   if (!isTargetInitialized())
     return Triple.getTriple();
 
-  if (Triple.getArchName() == "thumbv6m" ||
-      Triple.getArchName() == "thumbv7m" ||
-      Triple.getArchName() == "thumbv7em") {
-    // OS is ios or macosx unless it's the v6m or v7m.
-    Triple.setOS(llvm::Triple::Darwin);
-    Triple.setEnvironment(llvm::Triple::EABI);
-  } else {
-    SmallString<16> Str;
-    Str += isTargetIPhoneOS() ? "ios" : "macosx";
-    Str += getTargetVersion().getAsString();
-    Triple.setOSName(Str);
-  }
+  SmallString<16> Str;
+  Str += isTargetIOSBased() ? "ios" : "macosx";
+  Str += getTargetVersion().getAsString();
+  Triple.setOSName(Str);
 
   return Triple.getTriple();
 }
 
 void Generic_ELF::anchor() {}
 
-Tool *Darwin::getTool(Action::ActionClass AC) const {
+Tool *MachO::getTool(Action::ActionClass AC) const {
   switch (AC) {
   case Action::LipoJobClass:
     if (!Lipo)
@@ -194,7 +216,7 @@
     if (!Dsymutil)
       Dsymutil.reset(new tools::darwin::Dsymutil(*this));
     return Dsymutil.get();
-  case Action::VerifyJobClass:
+  case Action::VerifyDebugInfoJobClass:
     if (!VerifyDebug)
       VerifyDebug.reset(new tools::darwin::VerifyDebug(*this));
     return VerifyDebug.get();
@@ -203,30 +225,50 @@
   }
 }
 
-Tool *Darwin::buildLinker() const {
+Tool *MachO::buildLinker() const {
   return new tools::darwin::Link(*this);
 }
 
-Tool *Darwin::buildAssembler() const {
+Tool *MachO::buildAssembler() const {
   return new tools::darwin::Assemble(*this);
 }
 
 DarwinClang::DarwinClang(const Driver &D, const llvm::Triple& Triple,
                          const ArgList &Args)
-  : Darwin(D, Triple, Args)
-{
-  getProgramPaths().push_back(getDriver().getInstalledDir());
-  if (getDriver().getInstalledDir() != getDriver().Dir)
-    getProgramPaths().push_back(getDriver().Dir);
+  : Darwin(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);
+void DarwinClang::addClangWarningOptions(ArgStringList &CC1Args) const {
+  // For iOS, 64-bit, promote certain warnings to errors.
+  if (!isTargetMacOS() && 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");
+
+    // Also error about implicit function declarations, as that
+    // can impact calling conventions.
+    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);
@@ -245,12 +287,12 @@
   CmdArgs.push_back(Args.MakeArgString(P));
 }
 
-void DarwinClang::AddLinkRuntimeLib(const ArgList &Args,
-                                    ArgStringList &CmdArgs,
-                                    const char *DarwinStaticLib,
-                                    bool AlwaysLink) const {
+void MachO::AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs,
+                              StringRef DarwinStaticLib, bool AlwaysLink,
+                              bool IsEmbedded) const {
   SmallString<128> P(getDriver().ResourceDir);
-  llvm::sys::path::append(P, "lib", "darwin", DarwinStaticLib);
+  llvm::sys::path::append(P, "lib", IsEmbedded ? "macho_embedded" : "darwin",
+                          DarwinStaticLib);
 
   // For now, allow missing resource libraries to support developers who may
   // not have compiler-rt checked out or integrated into their build (unless
@@ -290,14 +332,14 @@
   // If we are building profile support, link that library in.
   if (Args.hasArg(options::OPT_fprofile_arcs) ||
       Args.hasArg(options::OPT_fprofile_generate) ||
+      Args.hasArg(options::OPT_fprofile_instr_generate) ||
       Args.hasArg(options::OPT_fcreate_profile) ||
       Args.hasArg(options::OPT_coverage)) {
     // Select the appropriate runtime library for the target.
-    if (isTargetIPhoneOS()) {
+    if (isTargetIOSBased())
       AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.profile_ios.a");
-    } else {
+    else
       AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.profile_osx.a");
-    }
   }
 
   const SanitizerArgs &Sanitize = getSanitizerArgs();
@@ -305,10 +347,11 @@
   // Add Ubsan runtime library, if required.
   if (Sanitize.needsUbsanRt()) {
     // FIXME: Move this check to SanitizerArgs::filterUnsupportedKinds.
-    if (isTargetIPhoneOS()) {
+    if (isTargetIOSBased()) {
       getDriver().Diag(diag::err_drv_clang_unsupported_per_platform)
         << "-fsanitize=undefined";
     } else {
+      assert(isTargetMacOS() && "unexpected non OS X target");
       AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.ubsan_osx.a", true);
 
       // The Ubsan runtime library requires C++.
@@ -320,7 +363,7 @@
   // should not be linked with the runtime library.
   if (Sanitize.needsAsanRt()) {
     // FIXME: Move this check to SanitizerArgs::filterUnsupportedKinds.
-    if (isTargetIPhoneOS() && !isTargetIOSSimulator()) {
+    if (isTargetIPhoneOS()) {
       getDriver().Diag(diag::err_drv_clang_unsupported_per_platform)
         << "-fsanitize=address";
     } else {
@@ -348,16 +391,19 @@
   CmdArgs.push_back("-lSystem");
 
   // Select the dynamic runtime library and the target specific static library.
-  if (isTargetIPhoneOS()) {
+  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())
+    if (isIPhoneOSVersionLT(5, 0) && !isTargetIOSSimulator() &&
+        (getTriple().getArch() != llvm::Triple::arm64 &&
+         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))
@@ -400,7 +446,7 @@
       if (llvm::sys::path::is_absolute(env) && llvm::sys::fs::exists(env) &&
           StringRef(env) != "/") {
         Args.append(Args.MakeSeparateArg(
-                      0, Opts.getOption(options::OPT_isysroot), env));
+                      nullptr, Opts.getOption(options::OPT_isysroot), env));
       }
     }
   }
@@ -414,12 +460,12 @@
     getDriver().Diag(diag::err_drv_argument_not_allowed_with)
           << OSXVersion->getAsString(Args)
           << (iOSVersion ? iOSVersion : iOSSimVersion)->getAsString(Args);
-    iOSVersion = iOSSimVersion = 0;
+    iOSVersion = iOSSimVersion = nullptr;
   } else if (iOSVersion && iOSSimVersion) {
     getDriver().Diag(diag::err_drv_argument_not_allowed_with)
           << iOSVersion->getAsString(Args)
           << iOSSimVersion->getAsString(Args);
-    iOSSimVersion = 0;
+    iOSSimVersion = nullptr;
   } else if (!OSXVersion && !iOSVersion && !iOSSimVersion) {
     // If no deployment target was specified on the command line, check for
     // environment defines.
@@ -440,7 +486,7 @@
       if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
         StringRef first, second;
         StringRef isysroot = A->getValue();
-        llvm::tie(first, second) = isysroot.split(StringRef("SDKs/iPhoneOS"));
+        std::tie(first, second) = isysroot.split(StringRef("SDKs/iPhoneOS"));
         if (second != "")
           iOSTarget = second.substr(0,3);
       }
@@ -448,9 +494,10 @@
 
     // If no OSX or iOS target has been specified and we're compiling for armv7,
     // go ahead as assume we're targeting iOS.
+    StringRef MachOArchName = getMachOArchName(Args);
     if (OSXTarget.empty() && iOSTarget.empty() &&
-        (getDarwinArchName(Args) == "armv7" ||
-         getDarwinArchName(Args) == "armv7s"))
+        (MachOArchName == "armv7" || MachOArchName == "armv7s" ||
+         MachOArchName == "arm64"))
         iOSTarget = iOSVersionMin;
 
     // Handle conflicting deployment targets
@@ -469,6 +516,8 @@
     // default platform.
     if (!OSXTarget.empty() && !iOSTarget.empty()) {
       if (getTriple().getArch() == llvm::Triple::arm ||
+          getTriple().getArch() == llvm::Triple::arm64 ||
+          getTriple().getArch() == llvm::Triple::aarch64 ||
           getTriple().getArch() == llvm::Triple::thumb)
         OSXTarget = "";
       else
@@ -477,25 +526,36 @@
 
     if (!OSXTarget.empty()) {
       const Option O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
-      OSXVersion = Args.MakeJoinedArg(0, O, OSXTarget);
+      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(0, O, iOSTarget);
+      iOSVersion = Args.MakeJoinedArg(nullptr, O, iOSTarget);
       Args.append(iOSVersion);
     } else if (!iOSSimTarget.empty()) {
       const Option O = Opts.getOption(
         options::OPT_mios_simulator_version_min_EQ);
-      iOSSimVersion = Args.MakeJoinedArg(0, O, iOSSimTarget);
+      iOSSimVersion = Args.MakeJoinedArg(nullptr, O, iOSSimTarget);
       Args.append(iOSSimVersion);
-    } else {
+    } else if (MachOArchName != "armv6m" && MachOArchName != "armv7m" &&
+               MachOArchName != "armv7em") {
       // Otherwise, assume we are targeting OS X.
       const Option O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
-      OSXVersion = Args.MakeJoinedArg(0, O, MacosxVersionMin);
+      OSXVersion = Args.MakeJoinedArg(nullptr, O, MacosxVersionMin);
       Args.append(OSXVersion);
     }
   }
 
+  DarwinPlatformKind Platform;
+  if (OSXVersion)
+    Platform = MacOS;
+  else if (iOSVersion)
+    Platform = IPhoneOS;
+  else if (iOSSimVersion)
+    Platform = IPhoneOSSimulator;
+  else
+    llvm_unreachable("Unable to infer Darwin variant");
+
   // Reject invalid architecture combinations.
   if (iOSSimVersion && (getTriple().getArch() != llvm::Triple::x86 &&
                         getTriple().getArch() != llvm::Triple::x86_64)) {
@@ -506,14 +566,14 @@
   // Set the tool chain target information.
   unsigned Major, Minor, Micro;
   bool HadExtra;
-  if (OSXVersion) {
+  if (Platform == MacOS) {
     assert((!iOSVersion && !iOSSimVersion) && "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 {
+  } else if (Platform == IPhoneOS || Platform == IPhoneOSSimulator) {
     const Arg *Version = iOSVersion ? iOSVersion : iOSSimVersion;
     assert(Version && "Unknown target platform!");
     if (!Driver::GetReleaseVersion(Version->getValue(), Major, Minor,
@@ -521,9 +581,8 @@
         Major >= 10 || Minor >= 100 || Micro >= 100)
       getDriver().Diag(diag::err_drv_invalid_version_number)
         << Version->getAsString(Args);
-  }
-
-  bool IsIOSSim = bool(iOSSimVersion);
+  } else
+    llvm_unreachable("unknown kind of Darwin platform");
 
   // In GCC, the simulator historically was treated as being OS X in some
   // contexts, like determining the link logic, despite generally being called
@@ -531,9 +590,9 @@
   // simulator as iOS + x86, and treat it differently in a few contexts.
   if (iOSVersion && (getTriple().getArch() == llvm::Triple::x86 ||
                      getTriple().getArch() == llvm::Triple::x86_64))
-    IsIOSSim = true;
+    Platform = IPhoneOSSimulator;
 
-  setTarget(/*IsIPhoneOS=*/ !OSXVersion, Major, Minor, Micro, IsIOSSim);
+  setTarget(Platform, Major, Minor, Micro);
 }
 
 void DarwinClang::AddCXXStdlibLibArgs(const ArgList &Args,
@@ -594,6 +653,8 @@
 
   // Use the newer cc_kext for iOS ARM after 6.0.
   if (!isTargetIPhoneOS() || isTargetIOSSimulator() ||
+      getTriple().getArch() == llvm::Triple::arm64 ||
+      getTriple().getArch() == llvm::Triple::aarch64 ||
       !isIPhoneOSVersionLT(6, 0)) {
     llvm::sys::path::append(P, "libclang_rt.cc_kext.a");
   } else {
@@ -606,8 +667,8 @@
     CmdArgs.push_back(Args.MakeArgString(P.str()));
 }
 
-DerivedArgList *Darwin::TranslateArgs(const DerivedArgList &Args,
-                                      const char *BoundArch) const {
+DerivedArgList *MachO::TranslateArgs(const DerivedArgList &Args,
+                                     const char *BoundArch) const {
   DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
   const OptTable &Opts = getDriver().getOpts();
 
@@ -618,24 +679,21 @@
   // have something that works, we should reevaluate each translation
   // and try to push it down into tool specific logic.
 
-  for (ArgList::const_iterator it = Args.begin(),
-         ie = Args.end(); it != ie; ++it) {
-    Arg *A = *it;
-
+  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::getArchTypeForDarwinArchName(A->getValue(0));
+        tools::darwin::getArchTypeForMachOArchName(A->getValue(0));
       if (!(XarchArch == getArch()  ||
             (BoundArch && XarchArch ==
-             tools::darwin::getArchTypeForDarwinArchName(BoundArch))))
+             tools::darwin::getArchTypeForMachOArchName(BoundArch))))
         continue;
 
       Arg *OriginalArg = A;
       unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(1));
       unsigned Prev = Index;
-      Arg *XarchArg = Opts.ParseOneArg(Args, 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
@@ -656,8 +714,8 @@
       }
 
       XarchArg->setBaseArg(A);
-      A = XarchArg;
 
+      A = XarchArg.release();
       DAL->AddSynthesizedArg(A);
 
       // Linker input arguments require custom handling. The problem is that we
@@ -741,7 +799,8 @@
   if (getTriple().getArch() == llvm::Triple::x86 ||
       getTriple().getArch() == llvm::Triple::x86_64)
     if (!Args.hasArgNoClaim(options::OPT_mtune_EQ))
-      DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mtune_EQ), "core2");
+      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.
@@ -755,89 +814,114 @@
     if (Name == "ppc")
       ;
     else if (Name == "ppc601")
-      DAL->AddJoinedArg(0, MCpu, "601");
+      DAL->AddJoinedArg(nullptr, MCpu, "601");
     else if (Name == "ppc603")
-      DAL->AddJoinedArg(0, MCpu, "603");
+      DAL->AddJoinedArg(nullptr, MCpu, "603");
     else if (Name == "ppc604")
-      DAL->AddJoinedArg(0, MCpu, "604");
+      DAL->AddJoinedArg(nullptr, MCpu, "604");
     else if (Name == "ppc604e")
-      DAL->AddJoinedArg(0, MCpu, "604e");
+      DAL->AddJoinedArg(nullptr, MCpu, "604e");
     else if (Name == "ppc750")
-      DAL->AddJoinedArg(0, MCpu, "750");
+      DAL->AddJoinedArg(nullptr, MCpu, "750");
     else if (Name == "ppc7400")
-      DAL->AddJoinedArg(0, MCpu, "7400");
+      DAL->AddJoinedArg(nullptr, MCpu, "7400");
     else if (Name == "ppc7450")
-      DAL->AddJoinedArg(0, MCpu, "7450");
+      DAL->AddJoinedArg(nullptr, MCpu, "7450");
     else if (Name == "ppc970")
-      DAL->AddJoinedArg(0, MCpu, "970");
+      DAL->AddJoinedArg(nullptr, MCpu, "970");
 
     else if (Name == "ppc64" || Name == "ppc64le")
-      DAL->AddFlagArg(0, Opts.getOption(options::OPT_m64));
+      DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));
 
     else if (Name == "i386")
       ;
     else if (Name == "i486")
-      DAL->AddJoinedArg(0, MArch, "i486");
+      DAL->AddJoinedArg(nullptr, MArch, "i486");
     else if (Name == "i586")
-      DAL->AddJoinedArg(0, MArch, "i586");
+      DAL->AddJoinedArg(nullptr, MArch, "i586");
     else if (Name == "i686")
-      DAL->AddJoinedArg(0, MArch, "i686");
+      DAL->AddJoinedArg(nullptr, MArch, "i686");
     else if (Name == "pentium")
-      DAL->AddJoinedArg(0, MArch, "pentium");
+      DAL->AddJoinedArg(nullptr, MArch, "pentium");
     else if (Name == "pentium2")
-      DAL->AddJoinedArg(0, MArch, "pentium2");
+      DAL->AddJoinedArg(nullptr, MArch, "pentium2");
     else if (Name == "pentpro")
-      DAL->AddJoinedArg(0, MArch, "pentiumpro");
+      DAL->AddJoinedArg(nullptr, MArch, "pentiumpro");
     else if (Name == "pentIIm3")
-      DAL->AddJoinedArg(0, MArch, "pentium2");
+      DAL->AddJoinedArg(nullptr, MArch, "pentium2");
 
     else if (Name == "x86_64")
-      DAL->AddFlagArg(0, Opts.getOption(options::OPT_m64));
+      DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));
     else if (Name == "x86_64h") {
-      DAL->AddFlagArg(0, Opts.getOption(options::OPT_m64));
-      DAL->AddJoinedArg(0, MArch, "x86_64h");
+      DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_m64));
+      DAL->AddJoinedArg(nullptr, MArch, "x86_64h");
     }
 
     else if (Name == "arm")
-      DAL->AddJoinedArg(0, MArch, "armv4t");
+      DAL->AddJoinedArg(nullptr, MArch, "armv4t");
     else if (Name == "armv4t")
-      DAL->AddJoinedArg(0, MArch, "armv4t");
+      DAL->AddJoinedArg(nullptr, MArch, "armv4t");
     else if (Name == "armv5")
-      DAL->AddJoinedArg(0, MArch, "armv5tej");
+      DAL->AddJoinedArg(nullptr, MArch, "armv5tej");
     else if (Name == "xscale")
-      DAL->AddJoinedArg(0, MArch, "xscale");
+      DAL->AddJoinedArg(nullptr, MArch, "xscale");
     else if (Name == "armv6")
-      DAL->AddJoinedArg(0, MArch, "armv6k");
+      DAL->AddJoinedArg(nullptr, MArch, "armv6k");
     else if (Name == "armv6m")
-      DAL->AddJoinedArg(0, MArch, "armv6m");
+      DAL->AddJoinedArg(nullptr, MArch, "armv6m");
     else if (Name == "armv7")
-      DAL->AddJoinedArg(0, MArch, "armv7a");
+      DAL->AddJoinedArg(nullptr, MArch, "armv7a");
     else if (Name == "armv7em")
-      DAL->AddJoinedArg(0, MArch, "armv7em");
-    else if (Name == "armv7f")
-      DAL->AddJoinedArg(0, MArch, "armv7f");
+      DAL->AddJoinedArg(nullptr, MArch, "armv7em");
     else if (Name == "armv7k")
-      DAL->AddJoinedArg(0, MArch, "armv7k");
+      DAL->AddJoinedArg(nullptr, MArch, "armv7k");
     else if (Name == "armv7m")
-      DAL->AddJoinedArg(0, MArch, "armv7m");
+      DAL->AddJoinedArg(nullptr, MArch, "armv7m");
     else if (Name == "armv7s")
-      DAL->AddJoinedArg(0, MArch, "armv7s");
-
-    else
-      llvm_unreachable("invalid Darwin arch");
+      DAL->AddJoinedArg(nullptr, MArch, "armv7s");
   }
 
+  return DAL;
+}
+
+void MachO::AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args,
+                                  llvm::opt::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(getDriver(), Args, getTriple()) == "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,
+                                      const char *BoundArch) const {
+  // First get the generic Apple args, before moving onto Darwin-specific ones.
+  DerivedArgList *DAL = MachO::TranslateArgs(Args, BoundArch);
+  const OptTable &Opts = getDriver().getOpts();
+
+  // If no architecture is bound, none of the translations here are relevant.
+  if (!BoundArch)
+    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.
-  if (BoundArch)
-    AddDeploymentTarget(*DAL);
+  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 (isTargetIPhoneOS() && !isIPhoneOSVersionLT(6, 0)) {
+  if (isTargetIOSBased() && !isIPhoneOSVersionLT(6, 0) &&
+      getTriple().getArch() != llvm::Triple::arm64 &&
+      getTriple().getArch() != llvm::Triple::aarch64) {
     for (ArgList::iterator it = DAL->begin(), ie = DAL->end(); it != ie; ) {
       Arg *A = *it;
       ++it;
@@ -854,9 +938,10 @@
 
   // Default to use libc++ on OS X 10.9+ and iOS 7+.
   if (((isTargetMacOS() && !isMacosxVersionLT(10, 9)) ||
-       (isTargetIPhoneOS() && !isIPhoneOSVersionLT(7, 0))) &&
+       (isTargetIOSBased() && !isIPhoneOSVersionLT(7, 0))) &&
       !Args.getLastArg(options::OPT_stdlib_EQ))
-    DAL->AddJoinedArg(0, Opts.getOption(options::OPT_stdlib_EQ), "libc++");
+    DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_stdlib_EQ),
+                      "libc++");
 
   // Validate the C++ standard library choice.
   CXXStdlibType Type = GetCXXStdlibType(*DAL);
@@ -864,8 +949,8 @@
     // Check whether the target provides libc++.
     StringRef where;
 
-    // Complain about targetting iOS < 5.0 in any way.
-    if (isTargetIPhoneOS() && isIPhoneOSVersionLT(5, 0))
+    // Complain about targeting iOS < 5.0 in any way.
+    if (isTargetIOSBased() && isIPhoneOSVersionLT(5, 0))
       where = "iOS 5.0";
 
     if (where != StringRef()) {
@@ -877,11 +962,11 @@
   return DAL;
 }
 
-bool Darwin::IsUnwindTablesDefault() const {
+bool MachO::IsUnwindTablesDefault() const {
   return getArch() == llvm::Triple::x86_64;
 }
 
-bool Darwin::UseDwarfDebugFlags() const {
+bool MachO::UseDwarfDebugFlags() const {
   if (const char *S = ::getenv("RC_DEBUG_OPTIONS"))
     return S[0] != '\0';
   return false;
@@ -893,40 +978,145 @@
           getTriple().getArch() == llvm::Triple::thumb);
 }
 
-bool Darwin::isPICDefault() const {
+bool MachO::isPICDefault() const {
   return true;
 }
 
-bool Darwin::isPIEDefault() const {
+bool MachO::isPIEDefault() const {
   return false;
 }
 
-bool Darwin::isPICDefaultForced() const {
-  return getArch() == llvm::Triple::x86_64;
+bool MachO::isPICDefaultForced() const {
+  return (getArch() == llvm::Triple::x86_64 ||
+          getArch() == llvm::Triple::arm64 ||
+          getArch() == llvm::Triple::aarch64);
 }
 
-bool Darwin::SupportsProfiling() const {
+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 llvm::opt::ArgList &Args,
+                               llvm::opt::ArgStringList &CmdArgs) const {
+  VersionTuple TargetVersion = getTargetVersion();
+
+  // If we had an explicit -mios-simulator-version-min argument, honor that,
+  // otherwise use the traditional deployment targets. We can't just check the
+  // is-sim attribute because existing code follows this path, and the linker
+  // may not handle the argument.
+  //
+  // FIXME: We may be able to remove this, once we can verify no one depends on
+  // it.
+  if (Args.hasArg(options::OPT_mios_simulator_version_min_EQ))
+    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 llvm::opt::ArgList &Args,
+                                    llvm::opt::ArgStringList &CmdArgs) const {
+  // Derived from startfile spec.
+  if (Args.hasArg(options::OPT_dynamiclib)) {
+    // Derived from darwin_dylib1 spec.
+    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 (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 (isTargetIOSSimulator()) {
+            ; // iOS simulator does not need crt1.o.
+          } else if (isTargetIPhoneOS()) {
+            if (getArch() == llvm::Triple::arm64 ||
+                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) &&
+      isMacosxVersionLT(10, 5)) {
+    const char *Str = Args.MakeArgString(GetFilePath("crt3.o"));
+    CmdArgs.push_back(Str);
+  }
+}
+
 bool Darwin::SupportsObjCGC() const {
-  // Garbage collection is supported everywhere except on iPhone OS.
-  return !isTargetIPhoneOS();
+  return isTargetMacOS();
 }
 
 void Darwin::CheckObjCARC() const {
-  if (isTargetIPhoneOS() || !isMacosxVersionLT(10, 6))
+  if (isTargetIOSBased()|| (isTargetMacOS() && !isMacosxVersionLT(10, 6)))
     return;
   getDriver().Diag(diag::err_arc_unsupported_on_toolchain);
 }
 
-std::string
-Darwin_Generic_GCC::ComputeEffectiveClangTriple(const ArgList &Args,
-                                                types::ID InputType) const {
-  return ComputeLLVMTriple(Args, InputType);
-}
-
 /// Generic_GCC - A tool chain using the 'gcc' command to perform
 /// all subcommands; this relies on gcc translating the majority of
 /// command line options.
@@ -1007,14 +1197,14 @@
   return false;
 }
 
-static StringRef getGCCToolchainDir(const ArgList &Args) {
+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 Construct a GCCInstallationDetector from the driver.
+/// \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.
@@ -1023,13 +1213,12 @@
 /// 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.
-Generic_GCC::GCCInstallationDetector::GCCInstallationDetector(
-    const Driver &D, const llvm::Triple &TargetTriple, const ArgList &Args)
-    : IsValid(false), D(D) {
+void
+Generic_GCC::GCCInstallationDetector::init(
+    const Driver &D, const llvm::Triple &TargetTriple, const ArgList &Args) {
   llvm::Triple BiarchVariantTriple =
       TargetTriple.isArch32Bit() ? TargetTriple.get64BitArchVariant()
                                  : TargetTriple.get32BitArchVariant();
-  llvm::Triple::ArchType TargetArch = TargetTriple.getArch();
   // The library directories which may contain GCC installations.
   SmallVector<StringRef, 4> CandidateLibDirs, CandidateBiarchLibDirs;
   // The compatible GCC triples for this particular architecture.
@@ -1056,12 +1245,22 @@
       Prefixes.push_back(D.SysRoot + "/usr");
     }
 
-    // Then look for gcc installed alongside clang.
-    Prefixes.push_back(D.InstalledDir + "/..");
+    // @LOCALMOD-START
+    if (TargetTriple.getOS() == llvm::Triple::NaCl) {
+      if (TargetTriple.getArch() == llvm::Triple::arm)
+        Prefixes.push_back(D.InstalledDir + "/../arm-nacl");
+      else
+        Prefixes.push_back(D.InstalledDir + "/../x86_64-nacl");
+    } else {
+      // Then look for gcc installed alongside clang.
+      Prefixes.push_back(D.InstalledDir + "/..");
 
-    // And finally in /usr.
-    if (D.SysRoot.empty())
-      Prefixes.push_back("/usr");
+      // And finally in /usr.
+      if (D.SysRoot.empty())
+        Prefixes.push_back("/usr");
+    }
+    // @LOCALMOD-END
+
   }
 
   // Loop over the various components which exist and select the best GCC
@@ -1075,7 +1274,7 @@
       if (!llvm::sys::fs::exists(LibDir))
         continue;
       for (unsigned k = 0, ke = CandidateTripleAliases.size(); k < ke; ++k)
-        ScanLibDirForGCCTriple(TargetArch, Args, LibDir,
+        ScanLibDirForGCCTriple(TargetTriple, Args, LibDir,
                                CandidateTripleAliases[k]);
     }
     for (unsigned j = 0, je = CandidateBiarchLibDirs.size(); j < je; ++j) {
@@ -1084,7 +1283,7 @@
         continue;
       for (unsigned k = 0, ke = CandidateBiarchTripleAliases.size(); k < ke;
            ++k)
-        ScanLibDirForGCCTriple(TargetArch, Args, LibDir,
+        ScanLibDirForGCCTriple(TargetTriple, Args, LibDir,
                                CandidateBiarchTripleAliases[k],
                                /*NeedsBiarchSuffix=*/ true);
     }
@@ -1092,13 +1291,25 @@
 }
 
 void Generic_GCC::GCCInstallationDetector::print(raw_ostream &OS) const {
-  for (std::set<std::string>::const_iterator
-           I = CandidateGCCInstallPaths.begin(),
-           E = CandidateGCCInstallPaths.end();
-       I != E; ++I)
-    OS << "Found candidate GCC installation: " << *I << "\n";
+  for (const auto &InstallPath : CandidateGCCInstallPaths)
+    OS << "Found candidate GCC installation: " << InstallPath << "\n";
 
-  OS << "Selected GCC installation: " << GCCInstallPath << "\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(
@@ -1110,43 +1321,62 @@
   // 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[] = { "/lib" };
+  static const char *const AArch64LibDirs[] = { "/lib64", "/lib" };
   static const char *const AArch64Triples[] = { "aarch64-none-linux-gnu",
-                                                "aarch64-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-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-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-gnu" };
+                                             "mips-mti-linux-gnu",
+                                             "mips-img-linux-gnu" };
   static const char *const MIPSELLibDirs[] = { "/lib" };
   static const char *const MIPSELTriples[] = { "mipsel-linux-gnu",
-                                               "mipsel-linux-android" };
+                                               "mipsel-linux-android",
+                                               "mips-img-linux-gnu" };
 
   static const char *const MIPS64LibDirs[] = { "/lib64", "/lib" };
   static const char *const MIPS64Triples[] = { "mips64-linux-gnu",
-                                               "mips-mti-linux-gnu" };
+                                               "mips-mti-linux-gnu",
+                                               "mips-img-linux-gnu",
+                                               "mips64-linux-gnuabi64" };
   static const char *const MIPS64ELLibDirs[] = { "/lib64", "/lib" };
   static const char *const MIPS64ELTriples[] = { "mips64el-linux-gnu",
-                                                 "mips-mti-linux-gnu" };
+                                                 "mips-mti-linux-gnu",
+                                                 "mips-img-linux-gnu",
+                                                 "mips64el-linux-android",
+                                                 "mips64el-linux-gnuabi64" };
 
   static const char *const PPCLibDirs[] = { "/lib32", "/lib" };
   static const char *const PPCTriples[] = {
@@ -1164,6 +1394,13 @@
                                                 "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",
@@ -1171,6 +1408,7 @@
   };
 
   switch (TargetTriple.getArch()) {
+  case llvm::Triple::arm64:
   case llvm::Triple::aarch64:
     LibDirs.append(AArch64LibDirs,
                    AArch64LibDirs + llvm::array_lengthof(AArch64LibDirs));
@@ -1181,6 +1419,17 @@
     BiarchTripleAliases.append(
         AArch64Triples, AArch64Triples + llvm::array_lengthof(AArch64Triples));
     break;
+  case llvm::Triple::arm64_be:
+  case llvm::Triple::aarch64_be:
+    LibDirs.append(AArch64beLibDirs,
+                   AArch64beLibDirs + llvm::array_lengthof(AArch64beLibDirs));
+    TripleAliases.append(AArch64beTriples,
+                         AArch64beTriples + llvm::array_lengthof(AArch64beTriples));
+    BiarchLibDirs.append(AArch64beLibDirs,
+                         AArch64beLibDirs + llvm::array_lengthof(AArch64beLibDirs));
+    BiarchTripleAliases.append(
+        AArch64beTriples, AArch64beTriples + llvm::array_lengthof(AArch64beTriples));
+    break;
   case llvm::Triple::arm:
   case llvm::Triple::thumb:
     LibDirs.append(ARMLibDirs, ARMLibDirs + llvm::array_lengthof(ARMLibDirs));
@@ -1192,15 +1441,35 @@
                            ARMTriples + llvm::array_lengthof(ARMTriples));
     }
     break;
+  case llvm::Triple::armeb:
+  case llvm::Triple::thumbeb:
+    LibDirs.append(ARMebLibDirs, ARMebLibDirs + llvm::array_lengthof(ARMebLibDirs));
+    if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) {
+      TripleAliases.append(ARMebHFTriples,
+                           ARMebHFTriples + llvm::array_lengthof(ARMebHFTriples));
+    } else {
+      TripleAliases.append(ARMebTriples,
+                           ARMebTriples + llvm::array_lengthof(ARMebTriples));
+    }
+    break;
   case llvm::Triple::x86_64:
     LibDirs.append(X86_64LibDirs,
                    X86_64LibDirs + llvm::array_lengthof(X86_64LibDirs));
     TripleAliases.append(X86_64Triples,
                          X86_64Triples + llvm::array_lengthof(X86_64Triples));
-    BiarchLibDirs.append(X86LibDirs,
-                         X86LibDirs + llvm::array_lengthof(X86LibDirs));
-    BiarchTripleAliases.append(X86Triples,
-                               X86Triples + llvm::array_lengthof(X86Triples));
+    // x32 is always available when x86_64 is available, so adding it as secondary
+    // arch with x86_64 triples
+    if (TargetTriple.getEnvironment() == llvm::Triple::GNUX32) {
+      BiarchLibDirs.append(X32LibDirs,
+                           X32LibDirs + llvm::array_lengthof(X32LibDirs));
+      BiarchTripleAliases.append(X86_64Triples,
+                                 X86_64Triples + llvm::array_lengthof(X86_64Triples));
+    } else {
+      BiarchLibDirs.append(X86LibDirs,
+                           X86LibDirs + llvm::array_lengthof(X86LibDirs));
+      BiarchTripleAliases.append(X86Triples,
+                                 X86Triples + llvm::array_lengthof(X86Triples));
+    }
     break;
   case llvm::Triple::x86:
     LibDirs.append(X86LibDirs, X86LibDirs + llvm::array_lengthof(X86LibDirs));
@@ -1283,6 +1552,26 @@
     TripleAliases.append(PPC64LETriples,
                          PPC64LETriples + llvm::array_lengthof(PPC64LETriples));
     break;
+  case llvm::Triple::sparc:
+    LibDirs.append(SPARCv8LibDirs,
+                   SPARCv8LibDirs + llvm::array_lengthof(SPARCv8LibDirs));
+    TripleAliases.append(SPARCv8Triples,
+                         SPARCv8Triples + llvm::array_lengthof(SPARCv8Triples));
+    BiarchLibDirs.append(SPARCv9LibDirs,
+                         SPARCv9LibDirs + llvm::array_lengthof(SPARCv9LibDirs));
+    BiarchTripleAliases.append(
+        SPARCv9Triples, SPARCv9Triples + llvm::array_lengthof(SPARCv9Triples));
+    break;
+  case llvm::Triple::sparcv9:
+    LibDirs.append(SPARCv9LibDirs,
+                   SPARCv9LibDirs + llvm::array_lengthof(SPARCv9LibDirs));
+    TripleAliases.append(SPARCv9Triples,
+                         SPARCv9Triples + llvm::array_lengthof(SPARCv9Triples));
+    BiarchLibDirs.append(SPARCv8LibDirs,
+                         SPARCv8LibDirs + llvm::array_lengthof(SPARCv8LibDirs));
+    BiarchTripleAliases.append(
+        SPARCv8Triples, SPARCv8Triples + llvm::array_lengthof(SPARCv8Triples));
+    break;
   case llvm::Triple::systemz:
     LibDirs.append(SystemZLibDirs,
                    SystemZLibDirs + llvm::array_lengthof(SystemZLibDirs));
@@ -1305,22 +1594,41 @@
     BiarchTripleAliases.push_back(BiarchTriple.str());
 }
 
-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;
+namespace {
+// Filter to remove Multilibs that don't exist as a suffix to Path
+class FilterNonExistent : public MultilibSet::FilterCallback {
+  std::string Base;
+public:
+  FilterNonExistent(std::string Base) : Base(Base) {}
+  bool operator()(const Multilib &M) const override {
+    return !llvm::sys::fs::exists(Base + M.gccSuffix() + "/crtbegin.o");
+  }
+};
+} // end anonymous namespace
 
-  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 isMipsArch(llvm::Triple::ArchType Arch) {
-  return Arch == llvm::Triple::mips ||
-         Arch == llvm::Triple::mipsel ||
-         Arch == llvm::Triple::mips64 ||
-         Arch == llvm::Triple::mips64el;
+  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) {
@@ -1329,67 +1637,27 @@
   return A && A->getOption().matches(options::OPT_mips16);
 }
 
-static bool isMips32r2(const ArgList &Args) {
-  Arg *A = Args.getLastArg(options::OPT_march_EQ,
-                           options::OPT_mcpu_EQ);
-
-  return A && A->getValue() == StringRef("mips32r2");
-}
-
-static bool isMips64r2(const ArgList &Args) {
-  Arg *A = Args.getLastArg(options::OPT_march_EQ,
-                           options::OPT_mcpu_EQ);
-
-  return A && A->getValue() == StringRef("mips64r2");
-}
-
 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 bool isMipsNan2008(const ArgList &Args) {
-  Arg *A = Args.getLastArg(options::OPT_mnan_EQ);
-  return A && A->getValue() == StringRef("2008");
-}
+struct DetectedMultilibs {
+  /// The set of multilibs that the detected installation supports.
+  MultilibSet Multilibs;
 
-// FIXME: There is the same routine in the Tools.cpp.
-static bool hasMipsN32ABIArg(const ArgList &Args) {
-  Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
-  return A && (A->getValue() == StringRef("n32"));
-}
+  /// The primary multilib appropriate for the given flags.
+  Multilib SelectedMultilib;
 
-static bool hasCrtBeginObj(Twine Path) {
-  return llvm::sys::fs::exists(Path + "/crtbegin.o");
-}
+  /// On Biarch systems, this corresponds to the default multilib when
+  /// targeting the non-default multilib. Otherwise, it is empty.
+  llvm::Optional<Multilib> BiarchSibling;
+};
 
-static bool findTargetBiarchSuffix(std::string &Suffix, StringRef Path,
-                                   llvm::Triple::ArchType TargetArch,
-                                   const ArgList &Args) {
-  // FIXME: This routine was only intended to model bi-arch toolchains which
-  // use -m32 and -m64 to swap between variants of a target. It shouldn't be
-  // doing ABI-based builtin location for MIPS.
-  if (hasMipsN32ABIArg(Args))
-    Suffix = "/n32";
-  else if (TargetArch == llvm::Triple::x86_64 ||
-           TargetArch == llvm::Triple::ppc64 ||
-           TargetArch == llvm::Triple::systemz ||
-           TargetArch == llvm::Triple::mips64 ||
-           TargetArch == llvm::Triple::mips64el)
-    Suffix = "/64";
-  else
-    Suffix = "/32";
-
-  return hasCrtBeginObj(Path + Suffix);
-}
-
-void Generic_GCC::GCCInstallationDetector::findMIPSABIDirSuffix(
-    std::string &Suffix, llvm::Triple::ArchType TargetArch, StringRef Path,
-    const llvm::opt::ArgList &Args) {
-  if (!isMipsArch(TargetArch))
-    return;
-
+static bool findMIPSMultilibs(const llvm::Triple &TargetTriple, StringRef Path,
+                              const llvm::opt::ArgList &Args,
+                              DetectedMultilibs &Result) {
   // Some MIPS toolchains put libraries and object files compiled
   // using different options in to the sub-directoris which names
   // reflects the flags used for compilation. For example sysroot
@@ -1414,66 +1682,362 @@
   // /mips32
   //     /usr
   //       /lib  <= crt*.o files compiled with '-mips32'
-  //
-  // Unfortunately different toolchains use different and partially
-  // overlapped naming schemes. So we have to make a trick for detection
-  // of using toolchain. We lookup a path which unique for each toolchains.
 
-  bool IsMentorToolChain = hasCrtBeginObj(Path + "/mips16/soft-float");
-  bool IsFSFToolChain = hasCrtBeginObj(Path + "/mips32/mips16/sof");
+  FilterNonExistent NonExistent(Path);
 
-  if (IsMentorToolChain && IsFSFToolChain)
-    D.Diag(diag::err_drv_unknown_toolchain);
+  // Check for FSF toolchain multilibs
+  MultilibSet FSFMipsMultilibs;
+  {
+    Multilib MArchMips32 = Multilib()
+      .gccSuffix("/mips32")
+      .osSuffix("/mips32")
+      .includeSuffix("/mips32")
+      .flag("+m32").flag("-m64").flag("-mmicromips").flag("+march=mips32");
 
-  if (IsMentorToolChain) {
-    if (isMips16(Args))
-      Suffix += "/mips16";
-    else if (isMicroMips(Args))
-      Suffix += "/micromips";
+    Multilib MArchMicroMips = Multilib()
+      .gccSuffix("/micromips")
+      .osSuffix("/micromips")
+      .includeSuffix("/micromips")
+      .flag("+m32").flag("-m64").flag("+mmicromips");
 
-    if (isSoftFloatABI(Args))
-      Suffix += "/soft-float";
+    Multilib MArchMips64r2 = Multilib()
+      .gccSuffix("/mips64r2")
+      .osSuffix("/mips64r2")
+      .includeSuffix("/mips64r2")
+      .flag("-m32").flag("+m64").flag("+march=mips64r2");
 
-    if (TargetArch == llvm::Triple::mipsel ||
-        TargetArch == llvm::Triple::mips64el)
-      Suffix += "/el";
-  } else if (IsFSFToolChain) {
-    if (TargetArch == llvm::Triple::mips ||
-        TargetArch == llvm::Triple::mipsel) {
-      if (isMicroMips(Args))
-        Suffix += "/micromips";
-      else if (isMips32r2(Args))
-        Suffix += "";
-      else
-        Suffix += "/mips32";
+    Multilib MArchMips64 = Multilib()
+      .gccSuffix("/mips64")
+      .osSuffix("/mips64")
+      .includeSuffix("/mips64")
+      .flag("-m32").flag("+m64").flag("-march=mips64r2");
 
-      if (isMips16(Args))
-        Suffix += "/mips16";
-    } else {
-      if (isMips64r2(Args))
-        Suffix += hasMipsN32ABIArg(Args) ? "/mips64r2" : "/mips64r2/64";
-      else
-        Suffix += hasMipsN32ABIArg(Args) ? "/mips64" : "/mips64/64";
-    }
+    Multilib MArchDefault = Multilib()
+      .flag("+m32").flag("-m64").flag("-mmicromips").flag("+march=mips32r2");
 
-    if (TargetArch == llvm::Triple::mipsel ||
-        TargetArch == llvm::Triple::mips64el)
-      Suffix += "/el";
+    Multilib Mips16 = Multilib()
+      .gccSuffix("/mips16")
+      .osSuffix("/mips16")
+      .includeSuffix("/mips16")
+      .flag("+mips16");
 
-    if (isSoftFloatABI(Args))
-      Suffix += "/sof";
-    else if (isMipsNan2008(Args))
-      Suffix += "/nan2008";
+    Multilib MAbi64 = Multilib()
+      .gccSuffix("/64")
+      .osSuffix("/64")
+      .includeSuffix("/64")
+      .flag("+mabi=n64").flag("-mabi=n32").flag("-m32");
+
+    Multilib BigEndian = Multilib()
+      .flag("+EB").flag("-EL");
+
+    Multilib LittleEndian = Multilib()
+      .gccSuffix("/el")
+      .osSuffix("/el")
+      .includeSuffix("/el")
+      .flag("+EL").flag("-EB");
+
+    Multilib SoftFloat = Multilib()
+      .gccSuffix("/sof")
+      .osSuffix("/sof")
+      .includeSuffix("/sof")
+      .flag("+msoft-float");
+
+    Multilib Nan2008 = Multilib()
+      .gccSuffix("/nan2008")
+      .osSuffix("/nan2008")
+      .includeSuffix("/nan2008")
+      .flag("+mnan=2008");
+
+    FSFMipsMultilibs = MultilibSet()
+      .Either(MArchMips32, MArchMicroMips, 
+              MArchMips64r2, MArchMips64, MArchDefault)
+      .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);
   }
 
-  if (!hasCrtBeginObj(Path + Suffix))
-    Suffix.clear();
+  // Check for Code Sourcery toolchain multilibs
+  MultilibSet CSMipsMultilibs;
+  {
+    Multilib MArchMips16 = Multilib()
+      .gccSuffix("/mips16")
+      .osSuffix("/mips16")
+      .includeSuffix("/mips16")
+      .flag("+m32").flag("+mips16");
+
+    Multilib MArchMicroMips = Multilib()
+      .gccSuffix("/micromips")
+      .osSuffix("/micromips")
+      .includeSuffix("/micromips")
+      .flag("+m32").flag("+mmicromips");
+
+    Multilib MArchDefault = Multilib()
+      .flag("-mips16").flag("-mmicromips");
+
+    Multilib SoftFloat = Multilib()
+      .gccSuffix("/soft-float")
+      .osSuffix("/soft-float")
+      .includeSuffix("/soft-float")
+      .flag("+msoft-float");
+
+    Multilib Nan2008 = Multilib()
+      .gccSuffix("/nan2008")
+      .osSuffix("/nan2008")
+      .includeSuffix("/nan2008")
+      .flag("+mnan=2008");
+
+    Multilib DefaultFloat = Multilib()
+      .flag("-msoft-float").flag("-mnan=2008");
+
+    Multilib BigEndian = Multilib()
+      .flag("+EB").flag("-EL");
+
+    Multilib LittleEndian = Multilib()
+      .gccSuffix("/el")
+      .osSuffix("/el")
+      .includeSuffix("/el")
+      .flag("+EL").flag("-EB");
+
+    // Note that this one's osSuffix is ""
+    Multilib MAbi64 = Multilib()
+      .gccSuffix("/64")
+      .includeSuffix("/64")
+      .flag("+mabi=n64").flag("-mabi=n32").flag("-m32");
+
+    CSMipsMultilibs = MultilibSet()
+      .Either(MArchMips16, MArchMicroMips, MArchDefault)
+      .Either(SoftFloat, Nan2008, DefaultFloat)
+      .FilterOut("/micromips/nan2008")
+      .FilterOut("/mips16/nan2008")
+      .Either(BigEndian, LittleEndian)
+      .Maybe(MAbi64)
+      .FilterOut("/mips16.*/64")
+      .FilterOut("/micromips.*/64")
+      .FilterOut(NonExistent);
+  }
+
+  MultilibSet AndroidMipsMultilibs = MultilibSet()
+    .Maybe(Multilib("/mips-r2").flag("+march=mips32r2"))
+    .FilterOut(NonExistent);
+
+  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);
+  }
+
+  MultilibSet ImgMultilibs;
+  {
+    Multilib Mips64r6 = Multilib()
+      .gccSuffix("/mips64r6")
+      .osSuffix("/mips64r6")
+      .includeSuffix("/mips64r6")
+      .flag("+m64").flag("-m32");
+
+    Multilib LittleEndian = Multilib()
+      .gccSuffix("/el")
+      .osSuffix("/el")
+      .includeSuffix("/el")
+      .flag("+EL").flag("-EB");
+
+    Multilib MAbi64 = Multilib()
+      .gccSuffix("/64")
+      .osSuffix("/64")
+      .includeSuffix("/64")
+      .flag("+mabi=n64").flag("-mabi=n32").flag("-m32");
+
+    ImgMultilibs = MultilibSet()
+      .Maybe(Mips64r6)
+      .Maybe(MAbi64)
+      .Maybe(LittleEndian)
+      .FilterOut(NonExistent);
+  }
+
+  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", "march=mips32r2", Flags);
+  addMultilibFlag(CPUName == "mips64", "march=mips64", Flags);
+  addMultilibFlag(CPUName == "mips64r2" || CPUName == "octeon",
+                  "march=mips64r2", Flags);
+  addMultilibFlag(isMicroMips(Args), "mmicromips", 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.getEnvironment() == llvm::Triple::Android) {
+    // Select Android toolchain. It's the only choice in that case.
+    if (AndroidMipsMultilibs.select(Flags, Result.SelectedMultilib)) {
+      Result.Multilibs = AndroidMipsMultilibs;
+      return true;
+    }
+    return false;
+  }
+
+  if (TargetTriple.getVendor() == llvm::Triple::ImaginationTechnologies &&
+      TargetTriple.getOS() == llvm::Triple::Linux &&
+      TargetTriple.getEnvironment() == llvm::Triple::GNU) {
+    // Select mips-img-linux-gnu toolchain.
+    if (ImgMultilibs.select(Flags, Result.SelectedMultilib)) {
+      Result.Multilibs = ImgMultilibs;
+      return true;
+    }
+    return false;
+  }
+
+  // Sort candidates. Toolchain that best meets the directories goes first.
+  // Then select the first toolchains matches command line flags.
+  MultilibSet *candidates[] = { &DebianMipsMultilibs, &FSFMipsMultilibs,
+                                &CSMipsMultilibs };
+  std::sort(
+      std::begin(candidates), std::end(candidates),
+      [](MultilibSet *a, MultilibSet *b) { return a->size() > b->size(); });
+  for (const auto &candidate : candidates) {
+    if (candidate->select(Flags, Result.SelectedMultilib)) {
+      if (candidate == &DebianMipsMultilibs)
+        Result.BiarchSibling = Multilib();
+      Result.Multilibs = *candidate;
+      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 bool findBiarchMultilibs(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");
+
+  FilterNonExistent NonExistent(Path);
+
+  // 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::ScanLibDirForGCCTriple(
-    llvm::Triple::ArchType TargetArch, const ArgList &Args,
+    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.
@@ -1505,7 +2069,7 @@
       (llvm::array_lengthof(LibSuffixes) - (TargetArch != llvm::Triple::x86));
   for (unsigned i = 0; i < NumLibSuffixes; ++i) {
     StringRef LibSuffix = LibSuffixes[i];
-    llvm::error_code EC;
+    std::error_code EC;
     for (llvm::sys::fs::directory_iterator LI(LibDir + LibSuffix, EC), LE;
          !EC && LI != LE; LI = LI.increment(EC)) {
       StringRef VersionText = llvm::sys::path::filename(LI->path());
@@ -1518,28 +2082,21 @@
       if (CandidateVersion <= Version)
         continue;
 
-      std::string MIPSABIDirSuffix;
-      findMIPSABIDirSuffix(MIPSABIDirSuffix, TargetArch, LI->path(), Args);
+      DetectedMultilibs Detected;
 
-      // 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.
-
-      std::string BiarchSuffix;
-      if (findTargetBiarchSuffix(BiarchSuffix,
-                                 LI->path() + MIPSABIDirSuffix,
-                                 TargetArch, Args)) {
-        GCCBiarchSuffix = BiarchSuffix;
-      } else if (NeedsBiarchSuffix ||
-                 !hasCrtBeginObj(LI->path() + MIPSABIDirSuffix)) {
+      // Debian mips multilibs behave more like the rest of the biarch ones,
+      // so handle them there
+      if (isMipsArch(TargetArch)) {
+        if (!findMIPSMultilibs(TargetTriple, LI->path(), Args, Detected))
+          continue;
+      } else if (!findBiarchMultilibs(TargetTriple, LI->path(), Args,
+                                      NeedsBiarchSuffix, Detected)) {
         continue;
-      } else {
-        GCCBiarchSuffix.clear();
       }
 
+      Multilibs = Detected.Multilibs;
+      SelectedMultilib = Detected.SelectedMultilib;
+      BiarchSibling = Detected.BiarchSibling;
       Version = CandidateVersion;
       GCCTriple.setTriple(CandidateTriple);
       // FIXME: We hack together the directory name here instead of
@@ -1547,7 +2104,6 @@
       // Linux.
       GCCInstallPath = LibDir + LibSuffixes[i] + "/" + VersionText.str();
       GCCParentLibPath = GCCInstallPath + InstallSuffixes[i];
-      GCCMIPSABIDirSuffix = MIPSABIDirSuffix;
       IsValid = true;
     }
   }
@@ -1555,7 +2111,7 @@
 
 Generic_GCC::Generic_GCC(const Driver &D, const llvm::Triple& Triple,
                          const ArgList &Args)
-  : ToolChain(D, Triple, Args), GCCInstallation(getDriver(), Triple, Args) {
+  : ToolChain(D, Triple, Args), GCCInstallation() {
   getProgramPaths().push_back(getDriver().getInstalledDir());
   if (getDriver().getInstalledDir() != getDriver().Dir)
     getProgramPaths().push_back(getDriver().Dir);
@@ -1570,10 +2126,6 @@
     if (!Preprocess)
       Preprocess.reset(new tools::gcc::Preprocess(*this));
     return Preprocess.get();
-  case Action::PrecompileJobClass:
-    if (!Precompile)
-      Precompile.reset(new tools::gcc::Precompile(*this));
-    return Precompile.get();
   case Action::CompileJobClass:
     if (!Compile)
       Compile.reset(new tools::gcc::Compile(*this));
@@ -1584,7 +2136,7 @@
 }
 
 Tool *Generic_GCC::buildAssembler() const {
-  return new tools::gcc::Assemble(*this);
+  return new tools::gnutools::Assemble(*this);
 }
 
 Tool *Generic_GCC::buildLinker() const {
@@ -1612,6 +2164,37 @@
   return false;
 }
 
+bool Generic_GCC::IsIntegratedAssemblerDefault() const {
+  return getTriple().getArch() == llvm::Triple::x86 ||
+         getTriple().getArch() == llvm::Triple::x86_64 ||
+         getTriple().getArch() == llvm::Triple::aarch64 ||
+         getTriple().getArch() == llvm::Triple::aarch64_be ||
+         getTriple().getArch() == llvm::Triple::arm64 ||
+         getTriple().getArch() == llvm::Triple::arm64_be ||
+         getTriple().getArch() == llvm::Triple::arm ||
+         getTriple().getArch() == llvm::Triple::armeb ||
+         getTriple().getArch() == llvm::Triple::thumb ||
+         getTriple().getArch() == llvm::Triple::thumbeb;
+}
+
+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().getArch() == llvm::Triple::arm64 ||
+      getTriple().getArch() == llvm::Triple::arm64_be ||
+      (getTriple().getOS() == llvm::Triple::Linux &&
+       (!V.isOlderThan(4, 7, 0) ||
+        getTriple().getEnvironment() == llvm::Triple::Android));
+
+  if (DriverArgs.hasFlag(options::OPT_fuse_init_array,
+                         options::OPT_fno_use_init_array,
+                         UseInitArrayDefault))
+    CC1Args.push_back("-fuse-init-array");
+}
+
 /// Hexagon Toolchain
 
 std::string Hexagon_TC::GetGnuDir(const std::string &InstalledDir) {
@@ -1696,7 +2279,7 @@
 
   // Determine version of GCC libraries and headers to use.
   const std::string HexagonDir(GnuDir + "/lib/gcc/hexagon");
-  llvm::error_code ec;
+  std::error_code ec;
   GCCVersion MaxVersion= GCCVersion::Parse("0.0.0");
   for (llvm::sys::fs::directory_iterator di(HexagonDir, ec), de;
        !ec && di != de; di = di.increment(ec)) {
@@ -1823,6 +2406,141 @@
 }
 // End Hexagon
 
+// @LOCALMOD-START
+/// NaCl Toolchain
+NaCl_TC::NaCl_TC(const Driver &D, const llvm::Triple &Triple,
+                 const ArgList &Args)
+  : Linux(D, Triple, Args) {
+
+  // Remove paths added by Linux toolchain. NaCl Toolchain can not 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: {
+      FilePath += "x86_64-nacl/lib32";
+      ProgPath += "x86_64-nacl/bin";
+      ToolPath += "i686-nacl";
+      break;
+    }
+    case llvm::Triple::x86_64: {
+      FilePath += "x86_64-nacl/lib";
+      ProgPath += "x86_64-nacl/bin";
+      ToolPath += "x86_64-nacl";
+      break;
+    }
+    case llvm::Triple::arm: {
+      FilePath += "arm-nacl/lib";
+      ProgPath += "arm-nacl/bin";
+      ToolPath += "arm-nacl";
+      break;
+    }
+    default:
+      break;
+  }
+
+  file_paths.push_back(FilePath);
+  file_paths.push_back(ToolPath);
+  prog_paths.push_back(ProgPath);
+
+  // Use provided linker, not system linker
+  Linker = GetProgramPath("ld");
+}
+
+void NaCl_TC::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;
+
+  if (getTriple().getArch() == llvm::Triple::arm) {
+    SmallString<128> P(D.Dir + "/../");
+    llvm::sys::path::append(P, "arm-nacl/include");
+    addSystemInclude(DriverArgs, CC1Args, P.str());
+  } else if (getTriple().getArch() == llvm::Triple::x86) {
+    SmallString<128> P(D.Dir + "/../");
+    llvm::sys::path::append(P, "x86_64-nacl/include");
+    addSystemInclude(DriverArgs, CC1Args, P.str());
+  } else if (getTriple().getArch() == llvm::Triple::x86_64) {
+    SmallString<128> P(D.Dir + "/../");
+    llvm::sys::path::append(P, "x86_64-nacl/include");
+    addSystemInclude(DriverArgs, CC1Args, P.str());
+  }
+}
+
+void NaCl_TC::AddCXXStdlibLibArgs(const ArgList &Args,
+                                    ArgStringList &CmdArgs) const {
+  // Allow and ignore -stdlib=libc++ without warning, but not libstdc++
+  GetCXXStdlibType(Args);
+  CmdArgs.push_back("-lc++");
+}
+void NaCl_TC::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
+                                          ArgStringList &CC1Args) const {
+  const Driver &D = getDriver();
+  if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
+      DriverArgs.hasArg(options::OPT_nostdincxx))
+    return;
+
+  // Allow and ignore -stdlib=libc++ without warning, but not libstdc++
+  GetCXXStdlibType(DriverArgs);
+
+  if (getTriple().getArch() == llvm::Triple::arm) {
+    SmallString<128> P(D.Dir + "/../");
+    llvm::sys::path::append(P, "arm-nacl/include/c++/v1");
+    addSystemInclude(DriverArgs, CC1Args, P.str());
+  } else if (getTriple().getArch() == llvm::Triple::x86) {
+    SmallString<128> P(D.Dir + "/../");
+    llvm::sys::path::append(P, "x86_64-nacl/include/c++/v1");
+    addSystemInclude(DriverArgs, CC1Args, P.str());
+  } else if (getTriple().getArch() == llvm::Triple::x86_64) {
+    SmallString<128> P(D.Dir + "/../");
+    llvm::sys::path::append(P, "x86_64-nacl/include/c++/v1");
+    addSystemInclude(DriverArgs, CC1Args, P.str());
+  }
+}
+
+
+ToolChain::CXXStdlibType NaCl_TC::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;
+}
+
+Tool *NaCl_TC::buildLinker() const {
+  return new tools::nacltools::Link(*this);
+}
+// End NaCl
+// @LOCALMOD-END
+
 /// 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.
@@ -1918,6 +2636,21 @@
   return new tools::bitrig::Link(*this);
 }
 
+ToolChain::CXXStdlibType
+Bitrig::GetCXXStdlibType(const ArgList &Args) const {
+  if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
+    StringRef Value = A->getValue();
+    if (Value == "libstdc++")
+      return ToolChain::CST_Libstdcxx;
+    if (Value == "libc++")
+      return ToolChain::CST_Libcxx;
+
+    getDriver().Diag(diag::err_drv_invalid_stdlib_name)
+      << A->getAsString(Args);
+  }
+  return ToolChain::CST_Libcxx;
+}
+
 void Bitrig::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
                                           ArgStringList &CC1Args) const {
   if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
@@ -1927,7 +2660,7 @@
   switch (GetCXXStdlibType(DriverArgs)) {
   case ToolChain::CST_Libcxx:
     addSystemInclude(DriverArgs, CC1Args,
-                     getDriver().SysRoot + "/usr/include/c++/");
+                     getDriver().SysRoot + "/usr/include/c++/v1");
     break;
   case ToolChain::CST_Libstdcxx:
     addSystemInclude(DriverArgs, CC1Args,
@@ -1953,9 +2686,8 @@
   switch (GetCXXStdlibType(Args)) {
   case ToolChain::CST_Libcxx:
     CmdArgs.push_back("-lc++");
-    CmdArgs.push_back("-lcxxrt");
-    // Include supc++ to provide Unwind until provided by libcxx.
-    CmdArgs.push_back("-lgcc");
+    CmdArgs.push_back("-lc++abi");
+    CmdArgs.push_back("-lpthread");
     break;
   case ToolChain::CST_Libstdcxx:
     CmdArgs.push_back("-lstdc++");
@@ -2026,6 +2758,7 @@
 bool FreeBSD::UseSjLjExceptions() 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;
@@ -2036,6 +2769,14 @@
   }
 }
 
+bool FreeBSD::HasNativeLLVMSupport() const {
+  return true;
+}
+
+bool FreeBSD::isPIEDefault() const {
+  return getSanitizerArgs().hasZeroBaseShadow();
+}
+
 /// 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)
@@ -2047,8 +2788,39 @@
     // 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.
-    if (Triple.getArch() == llvm::Triple::x86)
+    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::EABIHF:
+      case llvm::Triple::GNUEABI:
+      case llvm::Triple::GNUEABIHF:
+        getFilePaths().push_back("=/usr/lib/eabi");
+        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::sparc:
+      getFilePaths().push_back("=/usr/lib/sparc");
+      break;
+    default:
+      break;
+    }
 
     getFilePaths().push_back("=/usr/lib");
   }
@@ -2077,9 +2849,18 @@
 
   unsigned Major, Minor, Micro;
   getTriple().getOSVersion(Major, Minor, Micro);
-  if (Major >= 7 || (Major == 6 && Minor == 99 && Micro >= 23) || Major == 0) {
-    if (getArch() == llvm::Triple::x86 || getArch() == llvm::Triple::x86_64)
+  if (Major >= 7 || (Major == 6 && Minor == 99 && Micro >= 40) || Major == 0) {
+    switch (getArch()) {
+    case llvm::Triple::arm:
+    case llvm::Triple::armeb:
+    case llvm::Triple::thumb:
+    case llvm::Triple::thumbeb:
+    case llvm::Triple::x86:
+    case llvm::Triple::x86_64:
       return ToolChain::CST_Libcxx;
+    default:
+      break;
+    }
   }
   return ToolChain::CST_Libstdcxx;
 }
@@ -2215,8 +2996,9 @@
 }
 
 static Distro DetectDistro(llvm::Triple::ArchType Arch) {
-  OwningPtr<llvm::MemoryBuffer> File;
-  if (!llvm::MemoryBuffer::getFile("/etc/lsb-release", File)) {
+  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> File =
+      llvm::MemoryBuffer::getFile("/etc/lsb-release");
+  if (File) {
     StringRef Data = File.get()->getBuffer();
     SmallVector<StringRef, 8> Lines;
     Data.split(Lines, "\n");
@@ -2241,25 +3023,25 @@
     return Version;
   }
 
-  if (!llvm::MemoryBuffer::getFile("/etc/redhat-release", File)) {
+  File = llvm::MemoryBuffer::getFile("/etc/redhat-release");
+  if (File) {
     StringRef Data = File.get()->getBuffer();
     if (Data.startswith("Fedora release"))
       return Fedora;
-    else if (Data.startswith("Red Hat Enterprise Linux") &&
-             Data.find("release 6") != StringRef::npos)
-      return RHEL6;
-    else if ((Data.startswith("Red Hat Enterprise Linux") ||
-              Data.startswith("CentOS")) &&
-             Data.find("release 5") != StringRef::npos)
-      return RHEL5;
-    else if ((Data.startswith("Red Hat Enterprise Linux") ||
-              Data.startswith("CentOS")) &&
-             Data.find("release 4") != StringRef::npos)
-      return RHEL4;
+    if (Data.startswith("Red Hat Enterprise Linux") ||
+        Data.startswith("CentOS")) {
+      if (Data.find("release 6") != StringRef::npos)
+        return RHEL6;
+      else if (Data.find("release 5") != StringRef::npos)
+        return RHEL5;
+      else if (Data.find("release 4") != StringRef::npos)
+        return RHEL4;
+    }
     return UnknownDistro;
   }
 
-  if (!llvm::MemoryBuffer::getFile("/etc/debian_version", File)) {
+  File = llvm::MemoryBuffer::getFile("/etc/debian_version");
+  if (File) {
     StringRef Data = File.get()->getBuffer();
     if (Data[0] == '5')
       return DebianLenny;
@@ -2290,7 +3072,7 @@
 /// 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 llvm::Triple TargetTriple,
+static std::string getMultiarchTriple(const llvm::Triple &TargetTriple,
                                       StringRef SysRoot) {
   // For most architectures, just use whatever we have rather than trying to be
   // clever.
@@ -2312,18 +3094,36 @@
         return "arm-linux-gnueabi";
     }
     return TargetTriple.str();
+  case llvm::Triple::armeb:
+  case llvm::Triple::thumbeb:
+    if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) {
+      if (llvm::sys::fs::exists(SysRoot + "/lib/armeb-linux-gnueabihf"))
+        return "armeb-linux-gnueabihf";
+    } else {
+      if (llvm::sys::fs::exists(SysRoot + "/lib/armeb-linux-gnueabi"))
+        return "armeb-linux-gnueabi";
+    }
+    return TargetTriple.str();
   case llvm::Triple::x86:
     if (llvm::sys::fs::exists(SysRoot + "/lib/i386-linux-gnu"))
       return "i386-linux-gnu";
     return TargetTriple.str();
   case llvm::Triple::x86_64:
-    if (llvm::sys::fs::exists(SysRoot + "/lib/x86_64-linux-gnu"))
+    // We don't want this for x32, otherwise it will match x86_64 libs
+    if (TargetTriple.getEnvironment() != llvm::Triple::GNUX32 &&
+        llvm::sys::fs::exists(SysRoot + "/lib/x86_64-linux-gnu"))
       return "x86_64-linux-gnu";
     return TargetTriple.str();
+  case llvm::Triple::arm64:
   case llvm::Triple::aarch64:
     if (llvm::sys::fs::exists(SysRoot + "/lib/aarch64-linux-gnu"))
       return "aarch64-linux-gnu";
     return TargetTriple.str();
+  case llvm::Triple::arm64_be:
+  case llvm::Triple::aarch64_be:
+    if (llvm::sys::fs::exists(SysRoot + "/lib/aarch64_be-linux-gnu"))
+      return "aarch64_be-linux-gnu";
+    return TargetTriple.str();
   case llvm::Triple::mips:
     if (llvm::sys::fs::exists(SysRoot + "/lib/mips-linux-gnu"))
       return "mips-linux-gnu";
@@ -2332,6 +3132,18 @@
     if (llvm::sys::fs::exists(SysRoot + "/lib/mipsel-linux-gnu"))
       return "mipsel-linux-gnu";
     return TargetTriple.str();
+  case llvm::Triple::mips64:
+    if (llvm::sys::fs::exists(SysRoot + "/lib/mips64-linux-gnu"))
+      return "mips64-linux-gnu";
+    if (llvm::sys::fs::exists(SysRoot + "/lib/mips64-linux-gnuabi64"))
+      return "mips64-linux-gnuabi64";
+    return TargetTriple.str();
+  case llvm::Triple::mips64el:
+    if (llvm::sys::fs::exists(SysRoot + "/lib/mips64el-linux-gnu"))
+      return "mips64el-linux-gnu";
+    if (llvm::sys::fs::exists(SysRoot + "/lib/mips64el-linux-gnuabi64"))
+      return "mips64el-linux-gnuabi64";
+    return TargetTriple.str();
   case llvm::Triple::ppc:
     if (llvm::sys::fs::exists(SysRoot + "/lib/powerpc-linux-gnuspe"))
       return "powerpc-linux-gnuspe";
@@ -2352,35 +3164,40 @@
   if (llvm::sys::fs::exists(Path)) Paths.push_back(Path.str());
 }
 
-static StringRef getMultilibDir(const llvm::Triple &Triple,
-                                const ArgList &Args) {
+static StringRef getOSLibDir(const llvm::Triple &Triple, const ArgList &Args) {
   if (isMipsArch(Triple.getArch())) {
     // 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 (hasMipsN32ABIArg(Args))
+    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 multilib, and
+  // 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' multilib search path being considered. So we only enable
+  // 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 multilib spellings with the lib dir spellings in the
+  // 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";
 }
 
 Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
   : Generic_ELF(D, Triple, Args) {
+  GCCInstallation.init(D, Triple, Args);
+  Multilibs = GCCInstallation.getMultilibs();
   llvm::Triple::ArchType Arch = Triple.getArch();
   std::string SysRoot = computeSysRoot();
 
@@ -2396,7 +3213,7 @@
   PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" +
                          GCCInstallation.getTriple().str() + "/bin").str());
 
-  Linker = GetProgramPath("ld");
+  Linker = GetLinkerPath();
 
   Distro Distro = DetectDistro(Arch);
 
@@ -2448,29 +3265,20 @@
   // to the link paths.
   path_list &Paths = getFilePaths();
 
-  const std::string Multilib = getMultilibDir(Triple, Args);
+  const std::string OSLibDir = getOSLibDir(Triple, Args);
   const std::string MultiarchTriple = getMultiarchTriple(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();
 
     // Sourcery CodeBench MIPS toolchain holds some libraries under
     // a biarch-like suffix of the GCC installation.
-    //
-    // FIXME: It would be cleaner to model this as a variant of bi-arch. IE,
-    // instead of a '64' biarch suffix it would be 'el' or something.
-    if (IsAndroid && IsMips && isMips32r2(Args)) {
-      assert(GCCInstallation.getBiarchSuffix().empty() &&
-             "Unexpected bi-arch suffix");
-      addPathIfExists(GCCInstallation.getInstallPath() + "/mips-r2", Paths);
-    } else {
-      addPathIfExists((GCCInstallation.getInstallPath() +
-                       GCCInstallation.getMIPSABIDirSuffix() +
-                       GCCInstallation.getBiarchSuffix()),
-                      Paths);
-    }
+    addPathIfExists((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
@@ -2478,7 +3286,7 @@
     // <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 targetting a sysroot using a GCC
+    // 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
@@ -2490,8 +3298,8 @@
     //
     // Note that this matches the GCC behavior. See the below comment for where
     // Clang diverges from GCC's behavior.
-    addPathIfExists(LibPath + "/../" + GCCTriple.str() + "/lib/../" + Multilib +
-                    GCCInstallation.getMIPSABIDirSuffix(),
+    addPathIfExists(LibPath + "/../" + GCCTriple.str() + "/lib/../" + OSLibDir +
+                    Multilib.osSuffix(),
                     Paths);
 
     // If the GCC installation we found is inside of the sysroot, we want to
@@ -2505,45 +3313,64 @@
     // a bug.
     if (StringRef(LibPath).startswith(SysRoot)) {
       addPathIfExists(LibPath + "/" + MultiarchTriple, Paths);
-      addPathIfExists(LibPath + "/../" + Multilib, Paths);
+      addPathIfExists(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.Dir + "/../lib/" + MultiarchTriple, Paths);
+    addPathIfExists(D.Dir + "/../" + OSLibDir, Paths);
+  }
+
   addPathIfExists(SysRoot + "/lib/" + MultiarchTriple, Paths);
-  addPathIfExists(SysRoot + "/lib/../" + Multilib, Paths);
+  addPathIfExists(SysRoot + "/lib/../" + OSLibDir, Paths);
   addPathIfExists(SysRoot + "/usr/lib/" + MultiarchTriple, Paths);
-  addPathIfExists(SysRoot + "/usr/lib/../" + Multilib, Paths);
+  addPathIfExists(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(SysRoot + "/usr/lib/" + GCCInstallation.getTriple().str() +
-                    "/../../" + Multilib, Paths);
+                    "/../../" + OSLibDir, Paths);
 
-    // Add the non-multilib suffixed paths (if potentially different).
-    const std::string &LibPath = GCCInstallation.getParentLibPath();
-    const llvm::Triple &GCCTriple = GCCInstallation.getTriple();
-    if (!GCCInstallation.getBiarchSuffix().empty())
+    // Add the 'other' biarch variant path
+    Multilib BiarchSibling;
+    if (GCCInstallation.getBiarchSibling(BiarchSibling)) {
       addPathIfExists(GCCInstallation.getInstallPath() +
-                      GCCInstallation.getMIPSABIDirSuffix(), Paths);
+                      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(LibPath + "/../" + GCCTriple.str() +
-                    "/lib" + GCCInstallation.getMIPSABIDirSuffix(), Paths);
+                    "/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(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.Dir + "/../lib", Paths);
+
   addPathIfExists(SysRoot + "/lib", Paths);
   addPathIfExists(SysRoot + "/usr/lib", Paths);
 }
 
-bool FreeBSD::HasNativeLLVMSupport() const {
-  return true;
-}
-
 bool Linux::HasNativeLLVMSupport() const {
   return true;
 }
@@ -2556,19 +3383,6 @@
   return new tools::gnutools::Assemble(*this);
 }
 
-void Linux::addClangTargetOptions(const ArgList &DriverArgs,
-                                  ArgStringList &CC1Args) const {
-  const Generic_GCC::GCCVersion &V = GCCInstallation.getVersion();
-  bool UseInitArrayDefault =
-      !V.isOlderThan(4, 7, 0) ||
-      getTriple().getArch() == llvm::Triple::aarch64 ||
-      getTriple().getEnvironment() == llvm::Triple::Android;
-  if (DriverArgs.hasFlag(options::OPT_fuse_init_array,
-                         options::OPT_fno_use_init_array,
-                         UseInitArrayDefault))
-    CC1Args.push_back("-fuse-init-array");
-}
-
 std::string Linux::computeSysRoot() const {
   if (!getDriver().SysRoot.empty())
     return getDriver().SysRoot;
@@ -2582,15 +3396,15 @@
 
   const StringRef InstallDir = GCCInstallation.getInstallPath();
   const StringRef TripleStr = GCCInstallation.getTriple().str();
-  const StringRef MIPSABIDirSuffix = GCCInstallation.getMIPSABIDirSuffix();
+  const Multilib &Multilib = GCCInstallation.getMultilib();
 
   std::string Path = (InstallDir + "/../../../../" + TripleStr + "/libc" +
-                      MIPSABIDirSuffix).str();
+                      Multilib.osSuffix()).str();
 
   if (llvm::sys::fs::exists(Path))
     return Path;
 
-  Path = (InstallDir + "/../../../../sysroot" + MIPSABIDirSuffix).str();
+  Path = (InstallDir + "/../../../../sysroot" + Multilib.osSuffix()).str();
 
   if (llvm::sys::fs::exists(Path))
     return Path;
@@ -2623,10 +3437,9 @@
   if (CIncludeDirs != "") {
     SmallVector<StringRef, 5> dirs;
     CIncludeDirs.split(dirs, ":");
-    for (SmallVectorImpl<StringRef>::iterator I = dirs.begin(), E = dirs.end();
-         I != E; ++I) {
-      StringRef Prefix = llvm::sys::path::is_absolute(*I) ? SysRoot : "";
-      addExternCSystemInclude(DriverArgs, CC1Args, Prefix + *I);
+    for (StringRef dir : dirs) {
+      StringRef Prefix = llvm::sys::path::is_absolute(dir) ? SysRoot : "";
+      addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir);
     }
     return;
   }
@@ -2683,18 +3496,32 @@
   const StringRef MIPSELMultiarchIncludeDirs[] = {
     "/usr/include/mipsel-linux-gnu"
   };
+  const StringRef MIPS64MultiarchIncludeDirs[] = {
+    "/usr/include/mips64-linux-gnu",
+    "/usr/include/mips64-linux-gnuabi64"
+  };
+  const StringRef MIPS64ELMultiarchIncludeDirs[] = {
+    "/usr/include/mips64el-linux-gnu",
+    "/usr/include/mips64el-linux-gnuabi64"
+  };
   const StringRef PPCMultiarchIncludeDirs[] = {
     "/usr/include/powerpc-linux-gnu"
   };
   const StringRef PPC64MultiarchIncludeDirs[] = {
     "/usr/include/powerpc64-linux-gnu"
   };
+  const StringRef PPC64LEMultiarchIncludeDirs[] = {
+    "/usr/include/powerpc64le-linux-gnu"
+  };
   ArrayRef<StringRef> MultiarchIncludeDirs;
   if (getTriple().getArch() == llvm::Triple::x86_64) {
     MultiarchIncludeDirs = X86_64MultiarchIncludeDirs;
   } else if (getTriple().getArch() == llvm::Triple::x86) {
     MultiarchIncludeDirs = X86MultiarchIncludeDirs;
-  } else if (getTriple().getArch() == llvm::Triple::aarch64) {
+  } else if (getTriple().getArch() == llvm::Triple::aarch64 ||
+             getTriple().getArch() == llvm::Triple::aarch64_be ||
+             getTriple().getArch() == llvm::Triple::arm64 ||
+             getTriple().getArch() == llvm::Triple::arm64_be) {
     MultiarchIncludeDirs = AArch64MultiarchIncludeDirs;
   } else if (getTriple().getArch() == llvm::Triple::arm) {
     if (getTriple().getEnvironment() == llvm::Triple::GNUEABIHF)
@@ -2705,16 +3532,20 @@
     MultiarchIncludeDirs = MIPSMultiarchIncludeDirs;
   } else if (getTriple().getArch() == llvm::Triple::mipsel) {
     MultiarchIncludeDirs = MIPSELMultiarchIncludeDirs;
+  } else if (getTriple().getArch() == llvm::Triple::mips64) {
+    MultiarchIncludeDirs = MIPS64MultiarchIncludeDirs;
+  } else if (getTriple().getArch() == llvm::Triple::mips64el) {
+    MultiarchIncludeDirs = MIPS64ELMultiarchIncludeDirs;
   } else if (getTriple().getArch() == llvm::Triple::ppc) {
     MultiarchIncludeDirs = PPCMultiarchIncludeDirs;
   } else if (getTriple().getArch() == llvm::Triple::ppc64) {
     MultiarchIncludeDirs = PPC64MultiarchIncludeDirs;
+  } else if (getTriple().getArch() == llvm::Triple::ppc64le) {
+    MultiarchIncludeDirs = PPC64LEMultiarchIncludeDirs;
   }
-  for (ArrayRef<StringRef>::iterator I = MultiarchIncludeDirs.begin(),
-                                     E = MultiarchIncludeDirs.end();
-       I != E; ++I) {
-    if (llvm::sys::fs::exists(SysRoot + *I)) {
-      addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + *I);
+  for (StringRef Dir : MultiarchIncludeDirs) {
+    if (llvm::sys::fs::exists(SysRoot + Dir)) {
+      addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + Dir);
       break;
     }
   }
@@ -2730,33 +3561,39 @@
   addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include");
 }
 
-/// \brief Helper to add the three variant paths for a libstdc++ installation.
-/*static*/ bool Linux::addLibStdCXXIncludePaths(Twine Base, Twine TargetArchDir,
-                                                const ArgList &DriverArgs,
-                                                ArgStringList &CC1Args) {
-  if (!llvm::sys::fs::exists(Base))
-    return false;
-  addSystemInclude(DriverArgs, CC1Args, Base);
-  addSystemInclude(DriverArgs, CC1Args, Base + "/" + TargetArchDir);
-  addSystemInclude(DriverArgs, CC1Args, Base + "/backward");
-  return true;
-}
-
-/// \brief Helper to add an extra variant path for an (Ubuntu) multilib
-/// libstdc++ installation.
+/// \brief Helper to add the variant paths of a libstdc++ installation.
 /*static*/ bool Linux::addLibStdCXXIncludePaths(Twine Base, Twine Suffix,
-                                                Twine TargetArchDir,
-                                                Twine BiarchSuffix,
-                                                Twine MIPSABIDirSuffix,
+                                                StringRef GCCTriple,
+                                                StringRef GCCMultiarchTriple,
+                                                StringRef TargetMultiarchTriple,
+                                                Twine IncludeSuffix,
                                                 const ArgList &DriverArgs,
                                                 ArgStringList &CC1Args) {
-  if (!addLibStdCXXIncludePaths(Base + Suffix,
-                                TargetArchDir + MIPSABIDirSuffix + BiarchSuffix,
-                                DriverArgs, CC1Args))
+  if (!llvm::sys::fs::exists(Base + Suffix))
     return false;
 
-  addSystemInclude(DriverArgs, CC1Args, Base + "/" + TargetArchDir + Suffix
-                   + MIPSABIDirSuffix + BiarchSuffix);
+  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()) ||
+      llvm::sys::fs::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;
 }
 
@@ -2768,9 +3605,23 @@
 
   // Check if libc++ has been enabled and provide its include paths if so.
   if (GetCXXStdlibType(DriverArgs) == ToolChain::CST_Libcxx) {
-    // libc++ is always installed at a fixed path on Linux currently.
-    addSystemInclude(DriverArgs, CC1Args,
-                     getDriver().SysRoot + "/usr/include/c++/v1");
+    const std::string LibCXXIncludePathCandidates[] = {
+      // The primary location is within the Clang installation.
+      // FIXME: We shouldn't hard code 'v1' here to make Clang future proof to
+      // newer ABI versions.
+      getDriver().Dir + "/../include/c++/v1",
+
+      // We also check the system as for a long time this is the only place Clang looked.
+      // FIXME: We should really remove this. It doesn't make any sense.
+      getDriver().SysRoot + "/usr/include/c++/v1"
+    };
+    for (const auto &IncludePath : LibCXXIncludePathCandidates) {
+      if (!llvm::sys::fs::exists(IncludePath))
+        continue;
+      // Add the first candidate that exists.
+      addSystemInclude(DriverArgs, CC1Args, IncludePath);
+      break;
+    }
     return;
   }
 
@@ -2785,16 +3636,23 @@
   StringRef LibDir = GCCInstallation.getParentLibPath();
   StringRef InstallDir = GCCInstallation.getInstallPath();
   StringRef TripleStr = GCCInstallation.getTriple().str();
-  StringRef MIPSABIDirSuffix = GCCInstallation.getMIPSABIDirSuffix();
-  StringRef BiarchSuffix = GCCInstallation.getBiarchSuffix();
+  const Multilib &Multilib = GCCInstallation.getMultilib();
+  const std::string GCCMultiarchTriple =
+      getMultiarchTriple(GCCInstallation.getTriple(), getDriver().SysRoot);
+  const std::string TargetMultiarchTriple =
+      getMultiarchTriple(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, BiarchSuffix,
-                               MIPSABIDirSuffix, DriverArgs, CC1Args))
+                               "/c++/" + Version.Text, TripleStr, GCCMultiarchTriple,
+                               TargetMultiarchTriple,
+                               Multilib.includeSuffix(), DriverArgs, CC1Args))
     return;
 
-  const std::string IncludePathCandidates[] = {
+  // 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.MajorStr + "." +
@@ -2807,10 +3665,11 @@
     LibDir.str() + "/../include/c++",
   };
 
-  for (unsigned i = 0; i < llvm::array_lengthof(IncludePathCandidates); ++i) {
-    if (addLibStdCXXIncludePaths(IncludePathCandidates[i],
-                                 TripleStr + MIPSABIDirSuffix + BiarchSuffix,
-                                 DriverArgs, CC1Args))
+  for (const auto &IncludePath : LibStdCXXIncludePathCandidates) {
+    if (addLibStdCXXIncludePaths(IncludePath, /*Suffix*/ "", TripleStr,
+                                 /*GCCMultiarchTriple*/ "",
+                                 /*TargetMultiarchTriple*/ "",
+                                 Multilib.includeSuffix(), DriverArgs, CC1Args))
       break;
   }
 }
@@ -2880,7 +3739,6 @@
   return false;
 }
 
-
 void XCore::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
                                       ArgStringList &CC1Args) const {
   if (DriverArgs.hasArg(options::OPT_nostdinc) ||
diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h
index f46e2f6..e689394 100644
--- a/lib/Driver/ToolChains.h
+++ b/lib/Driver/ToolChains.h
@@ -13,11 +13,13 @@
 #include "Tools.h"
 #include "clang/Basic/VersionTuple.h"
 #include "clang/Driver/Action.h"
+#include "clang/Driver/Multilib.h"
 #include "clang/Driver/ToolChain.h"
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Optional.h"
 #include "llvm/Support/Compiler.h"
-#include <vector>
 #include <set>
+#include <vector>
 
 namespace clang {
 namespace driver {
@@ -67,7 +69,6 @@
     bool operator>=(const GCCVersion &RHS) const { return !(*this < RHS); }
   };
 
-
   /// \brief This is a class to find a viable GCC installation for Clang to
   /// use.
   ///
@@ -76,14 +77,17 @@
   /// Driver, and has logic for fuzzing that where appropriate.
   class GCCInstallationDetector {
     bool IsValid;
-    const Driver &D;
     llvm::Triple GCCTriple;
 
     // FIXME: These might be better as path objects.
     std::string GCCInstallPath;
-    std::string GCCBiarchSuffix;
     std::string GCCParentLibPath;
-    std::string GCCMIPSABIDirSuffix;
+
+    /// 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;
 
@@ -91,8 +95,12 @@
     // 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:
-    GCCInstallationDetector(const Driver &D, const llvm::Triple &TargetTriple,
+    GCCInstallationDetector() : IsValid(false) {}
+    void init(const Driver &D, const llvm::Triple &TargetTriple,
                             const llvm::opt::ArgList &Args);
 
     /// \brief Check whether we detected a valid GCC install.
@@ -104,26 +112,18 @@
     /// \brief Get the detected GCC installation path.
     StringRef getInstallPath() const { return GCCInstallPath; }
 
-    /// \brief Get the detected GCC installation path suffix for the bi-arch
-    /// target variant.
-    StringRef getBiarchSuffix() const { return GCCBiarchSuffix; }
-
     /// \brief Get the detected GCC parent lib path.
     StringRef getParentLibPath() const { return GCCParentLibPath; }
 
-    /// \brief Get the detected GCC MIPS ABI directory suffix.
-    ///
-    /// This is used as a suffix both to the install directory of GCC and as
-    /// a suffix to its parent lib path in order to select a MIPS ABI-specific
-    /// subdirectory.
-    ///
-    /// This will always be empty for any non-MIPS target.
-    ///
-    // FIXME: This probably shouldn't exist at all, and should be factored
-    // into the multiarch and/or biarch support. Please don't add more uses of
-    // this interface, it is meant as a legacy crutch for the MIPS driver
-    // logic.
-    StringRef getMIPSABIDirSuffix() const { return GCCMIPSABIDirSuffix; }
+    /// \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; }
@@ -140,15 +140,11 @@
                              SmallVectorImpl<StringRef> &BiarchLibDirs,
                              SmallVectorImpl<StringRef> &BiarchTripleAliases);
 
-    void ScanLibDirForGCCTriple(llvm::Triple::ArchType TargetArch,
+    void ScanLibDirForGCCTriple(const llvm::Triple &TargetArch,
                                 const llvm::opt::ArgList &Args,
                                 const std::string &LibDir,
                                 StringRef CandidateTriple,
                                 bool NeedsBiarchSuffix = false);
-
-    void findMIPSABIDirSuffix(std::string &Suffix,
-                              llvm::Triple::ArchType TargetArch, StringRef Path,
-                              const llvm::opt::ArgList &Args);
   };
 
   GCCInstallationDetector GCCInstallation;
@@ -158,17 +154,18 @@
               const llvm::opt::ArgList &Args);
   ~Generic_GCC();
 
-  virtual void printVerboseInfo(raw_ostream &OS) const;
+  void printVerboseInfo(raw_ostream &OS) const override;
 
-  virtual bool IsUnwindTablesDefault() const;
-  virtual bool isPICDefault() const;
-  virtual bool isPIEDefault() const;
-  virtual bool isPICDefaultForced() const;
+  bool IsUnwindTablesDefault() const override;
+  bool isPICDefault() const override;
+  bool isPIEDefault() const override;
+  bool isPICDefaultForced() const override;
+  bool IsIntegratedAssemblerDefault() const override;
 
 protected:
-  virtual Tool *getTool(Action::ActionClass AC) const;
-  virtual Tool *buildAssembler() const;
-  virtual Tool *buildLinker() const;
+  Tool *getTool(Action::ActionClass AC) const override;
+  Tool *buildAssembler() const override;
+  Tool *buildLinker() const override;
 
   /// \name ToolChain Implementation Helper Functions
   /// @{
@@ -182,27 +179,138 @@
   /// @}
 
 private:
-  mutable OwningPtr<tools::gcc::Preprocess> Preprocess;
-  mutable OwningPtr<tools::gcc::Precompile> Precompile;
-  mutable OwningPtr<tools::gcc::Compile> Compile;
+  mutable std::unique_ptr<tools::gcc::Preprocess> Preprocess;
+  mutable std::unique_ptr<tools::gcc::Compile> 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();
+
+  /// @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 DarwinStaticLib,
+                         bool AlwaysLink = false,
+                         bool IsEmbedded = false) const;
+
+  /// }
+  /// @name ToolChain Implementation
+  /// {
+
+  std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args,
+                                          types::ID InputType) const override;
+
+  types::ID LookupTypeForExtension(const char *Ext) const override;
+
+  bool HasNativeLLVMSupport() const override;
+
+  llvm::opt::DerivedArgList *
+  TranslateArgs(const llvm::opt::DerivedArgList &Args,
+                const char *BoundArch) const override;
+
+  bool IsBlocksDefault() const override {
+    // Always allow blocks on Apple; users interested in versioning are
+    // expected to use /usr/include/Blocks.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 override {
+    return false;
+  }
+
+  /// }
 };
 
   /// Darwin - The base Darwin tool chain.
-class LLVM_LIBRARY_VISIBILITY Darwin : public ToolChain {
+class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
 public:
   /// The host version.
   unsigned DarwinVersion[3];
 
-protected:
-  virtual Tool *buildAssembler() const;
-  virtual Tool *buildLinker() const;
-  virtual Tool *getTool(Action::ActionClass AC) const;
-
-private:
-  mutable OwningPtr<tools::darwin::Lipo> Lipo;
-  mutable OwningPtr<tools::darwin::Dsymutil> Dsymutil;
-  mutable OwningPtr<tools::darwin::VerifyDebug> VerifyDebug;
-
   /// Whether the information on the target has been initialized.
   //
   // FIXME: This should be eliminated. What we want to do is make this part of
@@ -210,11 +318,13 @@
   // the argument translation business.
   mutable bool TargetInitialized;
 
-  /// Whether we are targeting iPhoneOS target.
-  mutable bool TargetIsIPhoneOS;
+  enum DarwinPlatformKind {
+    MacOS,
+    IPhoneOS,
+    IPhoneOSSimulator
+  };
 
-  /// Whether we are targeting the iPhoneOS simulator target.
-  mutable bool TargetIsIPhoneOSSimulator;
+  mutable DarwinPlatformKind TargetPlatform;
 
   /// The OS version we are targeting.
   mutable VersionTuple TargetVersion;
@@ -237,43 +347,62 @@
   ~Darwin();
 
   std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args,
-                                          types::ID InputType) const;
+                                          types::ID InputType) const override;
 
-  /// @name Darwin Specific Toolchain API
+  /// @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) ||
+           getTriple().getArch() == llvm::Triple::arm64;
+  }
+
+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(bool IsIPhoneOS, unsigned Major, unsigned Minor,
-                 unsigned Micro, bool IsIOSSim) const {
-    assert((!IsIOSSim || IsIPhoneOS) && "Unexpected deployment target!");
-
+  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 && TargetIsIPhoneOS == IsIPhoneOS &&
-        TargetIsIPhoneOSSimulator == IsIOSSim &&
+    if (TargetInitialized && TargetPlatform == Platform &&
         TargetVersion == VersionTuple(Major, Minor, Micro))
       return;
 
     assert(!TargetInitialized && "Target already initialized!");
     TargetInitialized = true;
-    TargetIsIPhoneOS = IsIPhoneOS;
-    TargetIsIPhoneOSSimulator = IsIOSSim;
+    TargetPlatform = Platform;
     TargetVersion = VersionTuple(Major, Minor, Micro);
   }
 
   bool isTargetIPhoneOS() const {
     assert(TargetInitialized && "Target not initialized!");
-    return TargetIsIPhoneOS;
+    return TargetPlatform == IPhoneOS;
   }
 
   bool isTargetIOSSimulator() const {
     assert(TargetInitialized && "Target not initialized!");
-    return TargetIsIPhoneOSSimulator;
+    return TargetPlatform == IPhoneOSSimulator;
+  }
+
+  bool isTargetIOSBased() const {
+    assert(TargetInitialized && "Target not initialized!");
+    return isTargetIPhoneOS() || isTargetIOSSimulator();
   }
 
   bool isTargetMacOS() const {
-    return !isTargetIOSSimulator() && !isTargetIPhoneOS();
+    return TargetPlatform == MacOS;
   }
 
   bool isTargetInitialized() const { return TargetInitialized; }
@@ -283,101 +412,58 @@
     return TargetVersion;
   }
 
-  /// getDarwinArchName - Get the "Darwin" arch name for a particular compiler
-  /// invocation. For example, Darwin treats different ARM variations as
-  /// distinct architectures.
-  StringRef getDarwinArchName(const llvm::opt::ArgList &Args) const;
-
   bool isIPhoneOSVersionLT(unsigned V0, unsigned V1=0, unsigned V2=0) const {
-    assert(isTargetIPhoneOS() && "Unexpected call for OS X target!");
+    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(!isTargetIPhoneOS() && "Unexpected call for iPhoneOS target!");
+    assert(isTargetMacOS() && "Unexpected call for non OS X target!");
     return TargetVersion < VersionTuple(V0, V1, V2);
   }
 
-  /// AddLinkARCArgs - Add the linker arguments to link the ARC runtime library.
-  virtual void AddLinkARCArgs(const llvm::opt::ArgList &Args,
-                              llvm::opt::ArgStringList &CmdArgs) const = 0;
-
-  /// AddLinkRuntimeLibArgs - Add the linker arguments to link the compiler
-  /// runtime library.
-  virtual void
-  AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args,
-                        llvm::opt::ArgStringList &CmdArgs) const = 0;
-
+public:
   /// }
   /// @name ToolChain Implementation
   /// {
 
-  virtual types::ID LookupTypeForExtension(const char *Ext) const;
+  // 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; }
 
-  virtual bool HasNativeLLVMSupport() const;
-
-  virtual ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const;
-  virtual bool hasBlocksRuntime() const;
-
-  virtual llvm::opt::DerivedArgList *
+  llvm::opt::DerivedArgList *
   TranslateArgs(const llvm::opt::DerivedArgList &Args,
-                const char *BoundArch) const;
+                const char *BoundArch) const override;
 
-  virtual bool IsBlocksDefault() const {
-    // Always allow blocks on Darwin; users interested in versioning are
-    // expected to use /usr/include/Blocks.h.
-    return true;
-  }
-  virtual bool IsIntegratedAssemblerDefault() const {
-    // Default integrated assembler to on for Darwin.
-    return true;
-  }
+  ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const override;
+  bool hasBlocksRuntime() const override;
 
-  virtual bool IsMathErrnoDefault() const {
-    return false;
-  }
-
-  virtual bool IsEncodeExtendedBlockSignatureDefault() const {
-    return true;
-  }
-  
-  virtual bool IsObjCNonFragileABIDefault() const {
-    // Non-fragile ABI is default for everything but i386.
-    return getTriple().getArch() != llvm::Triple::x86;
-  }
-
-  virtual bool UseObjCMixedDispatch() const {
+  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 !(!isTargetIPhoneOS() && isMacosxVersionLT(10, 6));
+    return !(isTargetMacOS() && isMacosxVersionLT(10, 6));
   }
-  virtual bool IsUnwindTablesDefault() const;
-  virtual unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const {
+
+  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
-    return isTargetIPhoneOS() ||
-      (!isMacosxVersionLT(10, 6) ||
-         (!isMacosxVersionLT(10, 5) && !KernelOrKext));
+    if (isTargetIOSBased())
+      return 1;
+    else if (isTargetMacOS() && !isMacosxVersionLT(10, 6))
+      return 1;
+    else if (isTargetMacOS() && !isMacosxVersionLT(10, 5) && !KernelOrKext)
+      return 1;
+
+    return 0;
   }
-  virtual RuntimeLibType GetDefaultRuntimeLibType() const {
-    return ToolChain::RLT_CompilerRT;
-  }
-  virtual bool isPICDefault() const;
-  virtual bool isPIEDefault() const;
-  virtual bool isPICDefaultForced() const;
 
-  virtual bool SupportsProfiling() const;
+  bool SupportsObjCGC() const override;
 
-  virtual bool SupportsObjCGC() const;
+  void CheckObjCARC() const override;
 
-  virtual void CheckObjCARC() const;
-
-  virtual bool UseDwarfDebugFlags() const;
-
-  virtual bool UseSjLjExceptions() const;
-
-  /// }
+  bool UseSjLjExceptions() const override;
 };
 
 /// DarwinClang - The Darwin toolchain used by Clang.
@@ -386,40 +472,29 @@
   DarwinClang(const Driver &D, const llvm::Triple &Triple,
               const llvm::opt::ArgList &Args);
 
-  /// @name Darwin ToolChain Implementation
+  /// @name Apple ToolChain Implementation
   /// {
 
-  virtual void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args,
-                                     llvm::opt::ArgStringList &CmdArgs) const;
-  void AddLinkRuntimeLib(const llvm::opt::ArgList &Args,
-                         llvm::opt::ArgStringList &CmdArgs,
-                         const char *DarwinStaticLib,
-                         bool AlwaysLink = false) const;
+  void
+  AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args,
+                        llvm::opt::ArgStringList &CmdArgs) const override;
 
-  virtual void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
-                                   llvm::opt::ArgStringList &CmdArgs) const;
+  void
+  AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
+                      llvm::opt::ArgStringList &CmdArgs) const override;
 
-  virtual void AddCCKextLibArgs(const llvm::opt::ArgList &Args,
-                                llvm::opt::ArgStringList &CmdArgs) const;
+  void
+  AddCCKextLibArgs(const llvm::opt::ArgList &Args,
+                   llvm::opt::ArgStringList &CmdArgs) const override;
 
-  virtual void AddLinkARCArgs(const llvm::opt::ArgList &Args,
-                              llvm::opt::ArgStringList &CmdArgs) const;
+  virtual void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const;
+
+  void
+  AddLinkARCArgs(const llvm::opt::ArgList &Args,
+                 llvm::opt::ArgStringList &CmdArgs) const override;
   /// }
 };
 
-/// Darwin_Generic_GCC - Generic Darwin tool chain using gcc.
-class LLVM_LIBRARY_VISIBILITY Darwin_Generic_GCC : public Generic_GCC {
-public:
-  Darwin_Generic_GCC(const Driver &D, const llvm::Triple &Triple,
-                     const llvm::opt::ArgList &Args)
-      : Generic_GCC(D, Triple, Args) {}
-
-  std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args,
-                                          types::ID InputType) const;
-
-  virtual bool isPICDefault() const { return false; }
-};
-
 class LLVM_LIBRARY_VISIBILITY Generic_ELF : public Generic_GCC {
   virtual void anchor();
 public:
@@ -427,12 +502,8 @@
               const llvm::opt::ArgList &Args)
       : Generic_GCC(D, Triple, Args) {}
 
-  virtual bool IsIntegratedAssemblerDefault() const {
-    // Default integrated assembler to on for x86.
-    return (getTriple().getArch() == llvm::Triple::aarch64 ||
-            getTriple().getArch() == llvm::Triple::x86 ||
-            getTriple().getArch() == llvm::Triple::x86_64);
-  }
+  void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
+                             llvm::opt::ArgStringList &CC1Args) const override;
 };
 
 class LLVM_LIBRARY_VISIBILITY AuroraUX : public Generic_GCC {
@@ -441,8 +512,8 @@
            const llvm::opt::ArgList &Args);
 
 protected:
-  virtual Tool *buildAssembler() const;
-  virtual Tool *buildLinker() const;
+  Tool *buildAssembler() const override;
+  Tool *buildLinker() const override;
 };
 
 class LLVM_LIBRARY_VISIBILITY Solaris : public Generic_GCC {
@@ -450,10 +521,10 @@
   Solaris(const Driver &D, const llvm::Triple &Triple,
           const llvm::opt::ArgList &Args);
 
-  virtual bool IsIntegratedAssemblerDefault() const { return true; }
+  bool IsIntegratedAssemblerDefault() const override { return true; }
 protected:
-  virtual Tool *buildAssembler() const;
-  virtual Tool *buildLinker() const;
+  Tool *buildAssembler() const override;
+  Tool *buildLinker() const override;
 
 };
 
@@ -463,17 +534,25 @@
   OpenBSD(const Driver &D, const llvm::Triple &Triple,
           const llvm::opt::ArgList &Args);
 
-  virtual bool IsMathErrnoDefault() const { return false; }
-  virtual bool IsObjCNonFragileABIDefault() const { return true; }
-  virtual bool isPIEDefault() const { return true; }
+  bool IsMathErrnoDefault() const override { return false; }
+  bool IsObjCNonFragileABIDefault() const override { return true; }
+  bool isPIEDefault() const override { return true; }
 
-  virtual unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const {
-    return 1;
+  unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const override {
+    return 2;
+  }
+
+  virtual bool IsIntegratedAssemblerDefault() const override {
+    if (getTriple().getArch() == llvm::Triple::ppc ||
+        getTriple().getArch() == llvm::Triple::sparc ||
+        getTriple().getArch() == llvm::Triple::sparcv9)
+      return true;
+    return Generic_ELF::IsIntegratedAssemblerDefault();
   }
 
 protected:
-  virtual Tool *buildAssembler() const;
-  virtual Tool *buildLinker() const;
+  Tool *buildAssembler() const override;
+  Tool *buildLinker() const override;
 };
 
 class LLVM_LIBRARY_VISIBILITY Bitrig : public Generic_ELF {
@@ -481,43 +560,49 @@
   Bitrig(const Driver &D, const llvm::Triple &Triple,
          const llvm::opt::ArgList &Args);
 
-  virtual bool IsMathErrnoDefault() const { return false; }
-  virtual bool IsObjCNonFragileABIDefault() const { return true; }
-  virtual bool IsObjCLegacyDispatchDefault() const { return false; }
+  bool IsMathErrnoDefault() const override { return false; }
+  bool IsObjCNonFragileABIDefault() const override { return true; }
 
-  virtual void
+  CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override;
+  void
   AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs,
-                               llvm::opt::ArgStringList &CC1Args) const;
-  virtual void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
-                                   llvm::opt::ArgStringList &CmdArgs) const;
-  virtual unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const {
+                              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:
-  virtual Tool *buildAssembler() const;
-  virtual Tool *buildLinker() const;
+  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);
-  virtual bool HasNativeLLVMSupport() const;
+  bool HasNativeLLVMSupport() const override;
 
-  virtual bool IsMathErrnoDefault() const { return false; }
-  virtual bool IsObjCNonFragileABIDefault() const { return true; }
+  bool IsMathErrnoDefault() const override { return false; }
+  bool IsObjCNonFragileABIDefault() const override { return true; }
 
-  virtual CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const;
-  virtual void
+  CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override;
+  void
   AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs,
-                               llvm::opt::ArgStringList &CC1Args) const;
+                               llvm::opt::ArgStringList &CC1Args) const override;
+  bool IsIntegratedAssemblerDefault() const override {
+    if (getTriple().getArch() == llvm::Triple::ppc ||
+        getTriple().getArch() == llvm::Triple::ppc64)
+      return true;
+    return Generic_ELF::IsIntegratedAssemblerDefault();
+  }
 
-
-  virtual bool UseSjLjExceptions() const;
+  bool UseSjLjExceptions() const override;
+  bool isPIEDefault() const override;
 protected:
-  virtual Tool *buildAssembler() const;
-  virtual Tool *buildLinker() const;
+  Tool *buildAssembler() const override;
+  Tool *buildLinker() const override;
 };
 
 class LLVM_LIBRARY_VISIBILITY NetBSD : public Generic_ELF {
@@ -525,26 +610,26 @@
   NetBSD(const Driver &D, const llvm::Triple &Triple,
          const llvm::opt::ArgList &Args);
 
-  virtual bool IsMathErrnoDefault() const { return false; }
-  virtual bool IsObjCNonFragileABIDefault() const { return true; }
+  bool IsMathErrnoDefault() const override { return false; }
+  bool IsObjCNonFragileABIDefault() const override { return true; }
 
-  virtual CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const;
+  CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override;
 
-  virtual void
+  void
   AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs,
-                               llvm::opt::ArgStringList &CC1Args) const;
-  virtual bool IsUnwindTablesDefault() const {
+                              llvm::opt::ArgStringList &CC1Args) const override;
+  bool IsUnwindTablesDefault() const override {
     return true;
   }
-  virtual bool IsIntegratedAssemblerDefault() const {
+  bool IsIntegratedAssemblerDefault() const override {
     if (getTriple().getArch() == llvm::Triple::ppc)
       return true;
     return Generic_ELF::IsIntegratedAssemblerDefault();
   }
 
 protected:
-  virtual Tool *buildAssembler() const;
-  virtual Tool *buildLinker() const;
+  Tool *buildAssembler() const override;
+  Tool *buildLinker() const override;
 };
 
 class LLVM_LIBRARY_VISIBILITY Minix : public Generic_ELF {
@@ -553,8 +638,8 @@
         const llvm::opt::ArgList &Args);
 
 protected:
-  virtual Tool *buildAssembler() const;
-  virtual Tool *buildLinker() const;
+  Tool *buildAssembler() const override;
+  Tool *buildLinker() const override;
 };
 
 class LLVM_LIBRARY_VISIBILITY DragonFly : public Generic_ELF {
@@ -562,11 +647,11 @@
   DragonFly(const Driver &D, const llvm::Triple &Triple,
             const llvm::opt::ArgList &Args);
 
-  virtual bool IsMathErrnoDefault() const { return false; }
+  bool IsMathErrnoDefault() const override { return false; }
 
 protected:
-  virtual Tool *buildAssembler() const;
-  virtual Tool *buildLinker() const;
+  Tool *buildAssembler() const override;
+  Tool *buildLinker() const override;
 };
 
 class LLVM_LIBRARY_VISIBILITY Linux : public Generic_ELF {
@@ -574,33 +659,29 @@
   Linux(const Driver &D, const llvm::Triple &Triple,
         const llvm::opt::ArgList &Args);
 
-  virtual bool HasNativeLLVMSupport() const;
+  bool HasNativeLLVMSupport() const override;
 
-  virtual void
+  void
   AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
-                            llvm::opt::ArgStringList &CC1Args) const;
-  virtual void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
-                                     llvm::opt::ArgStringList &CC1Args) const;
-  virtual void
+                            llvm::opt::ArgStringList &CC1Args) const override;
+  void
   AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs,
-                               llvm::opt::ArgStringList &CC1Args) const;
-  virtual bool isPIEDefault() const;
+                               llvm::opt::ArgStringList &CC1Args) const override;
+  bool isPIEDefault() const override;
 
   std::string Linker;
   std::vector<std::string> ExtraOpts;
 
 protected:
-  virtual Tool *buildAssembler() const;
-  virtual Tool *buildLinker() const;
+  Tool *buildAssembler() const override;
+  Tool *buildLinker() const override;
 
 private:
   static bool addLibStdCXXIncludePaths(Twine Base, Twine Suffix,
-                                       Twine TargetArchDir,
-                                       Twine BiarchSuffix,
-                                       Twine MIPSABIDirSuffix,
-                                       const llvm::opt::ArgList &DriverArgs,
-                                       llvm::opt::ArgStringList &CC1Args);
-  static bool addLibStdCXXIncludePaths(Twine Base, Twine TargetArchDir,
+                                       StringRef GCCTriple,
+                                       StringRef GCCMultiarchTriple,
+                                       StringRef TargetMultiarchTriple,
+                                       Twine IncludeSuffix,
                                        const llvm::opt::ArgList &DriverArgs,
                                        llvm::opt::ArgStringList &CC1Args);
 
@@ -610,21 +691,21 @@
 class LLVM_LIBRARY_VISIBILITY Hexagon_TC : public Linux {
 protected:
   GCCVersion GCCLibAndIncVersion;
-  virtual Tool *buildAssembler() const;
-  virtual Tool *buildLinker() const;
+  Tool *buildAssembler() const override;
+  Tool *buildLinker() const override;
 
 public:
   Hexagon_TC(const Driver &D, const llvm::Triple &Triple,
              const llvm::opt::ArgList &Args);
   ~Hexagon_TC();
 
-  virtual void
+  void
   AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
-                            llvm::opt::ArgStringList &CC1Args) const;
-  virtual void
+                            llvm::opt::ArgStringList &CC1Args) const override;
+  void
   AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs,
-                               llvm::opt::ArgStringList &CC1Args) const;
-  virtual CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const;
+                              llvm::opt::ArgStringList &CC1Args) const override;
+  CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override;
 
   StringRef GetGCCLibAndIncVersion() const { return GCCLibAndIncVersion.Text; }
 
@@ -633,6 +714,32 @@
   static StringRef GetTargetCPU(const llvm::opt::ArgList &Args);
 };
 
+// @LOCALMOD-START
+class LLVM_LIBRARY_VISIBILITY NaCl_TC : public Linux {
+public:
+  NaCl_TC(const Driver &D, const llvm::Triple &Triple,
+          const llvm::opt::ArgList &Args);
+
+  virtual void
+  AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+                            llvm::opt::ArgStringList &CC1Args) const;
+  virtual void
+  AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+                               llvm::opt::ArgStringList &CC1Args) const;
+
+  virtual CXXStdlibType
+  GetCXXStdlibType(const llvm::opt::ArgList &Args) const;
+
+  virtual void
+  AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
+                      llvm::opt::ArgStringList &CmdArgs) const;
+
+protected:
+  virtual Tool *buildLinker() const;
+};
+// @LOCALMOD-END
+
+
 /// 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 {
@@ -641,10 +748,10 @@
                const llvm::opt::ArgList &Args);
   ~TCEToolChain();
 
-  bool IsMathErrnoDefault() const;
-  bool isPICDefault() const;
-  bool isPIEDefault() const;
-  bool isPICDefaultForced() const;
+  bool IsMathErrnoDefault() const override;
+  bool isPICDefault() const override;
+  bool isPIEDefault() const override;
+  bool isPICDefaultForced() const override;
 };
 
 /// EmscriptenToolChain - A tool chain for the Emscripten C/C++ to JS compiler.
@@ -666,22 +773,22 @@
   Windows(const Driver &D, const llvm::Triple &Triple,
           const llvm::opt::ArgList &Args);
 
-  virtual bool IsIntegratedAssemblerDefault() const;
-  virtual bool IsUnwindTablesDefault() const;
-  virtual bool isPICDefault() const;
-  virtual bool isPIEDefault() const;
-  virtual bool isPICDefaultForced() const;
+  bool IsIntegratedAssemblerDefault() const override;
+  bool IsUnwindTablesDefault() const override;
+  bool isPICDefault() const override;
+  bool isPIEDefault() const override;
+  bool isPICDefaultForced() const override;
 
-  virtual void
+  void
   AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
-                            llvm::opt::ArgStringList &CC1Args) const;
-  virtual void
+                            llvm::opt::ArgStringList &CC1Args) const override;
+  void
   AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs,
-                               llvm::opt::ArgStringList &CC1Args) const;
+                               llvm::opt::ArgStringList &CC1Args) const override;
 
 protected:
-  virtual Tool *buildLinker() const;
-  virtual Tool *buildAssembler() const;
+  Tool *buildLinker() const override;
+  Tool *buildAssembler() const override;
 };
 
 
@@ -690,22 +797,22 @@
   XCore(const Driver &D, const llvm::Triple &Triple,
           const llvm::opt::ArgList &Args);
 protected:
-  virtual Tool *buildAssembler() const;
-  virtual Tool *buildLinker() const;
+  Tool *buildAssembler() const override;
+  Tool *buildLinker() const override;
 public:
-  virtual bool isPICDefault() const;
-  virtual bool isPIEDefault() const;
-  virtual bool isPICDefaultForced() const;
-  virtual bool SupportsProfiling() const;
-  virtual bool hasBlocksRuntime() const;
-  virtual void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
-                            llvm::opt::ArgStringList &CC1Args) const;
-  virtual void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
-                                     llvm::opt::ArgStringList &CC1Args) const;
-  virtual void AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs,
-                               llvm::opt::ArgStringList &CC1Args) const;
-  virtual void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
-                                   llvm::opt::ArgStringList &CmdArgs) const;
+  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
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index ad03e2e..6f0a455 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -10,6 +10,7 @@
 #include "Tools.h"
 #include "InputInfo.h"
 #include "ToolChains.h"
+#include "clang/Basic/LangOptions.h"
 #include "clang/Basic/ObjCRuntime.h"
 #include "clang/Basic/Version.h"
 #include "clang/Driver/Action.h"
@@ -21,7 +22,6 @@
 #include "clang/Driver/SanitizerArgs.h"
 #include "clang/Driver/ToolChain.h"
 #include "clang/Driver/Util.h"
-#include "clang/Sema/SemaDiagnostic.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringSwitch.h"
@@ -29,28 +29,47 @@
 #include "llvm/Option/Arg.h"
 #include "llvm/Option/ArgList.h"
 #include "llvm/Option/Option.h"
+#include "llvm/Support/Compression.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Format.h"
 #include "llvm/Support/Host.h"
 #include "llvm/Support/Path.h"
-#include "llvm/Support/Program.h"
 #include "llvm/Support/Process.h"
+#include "llvm/Support/Program.h"
 #include "llvm/Support/raw_ostream.h"
-#include <sys/stat.h>
 
 using namespace clang::driver;
 using namespace clang::driver::tools;
 using namespace clang;
 using namespace llvm::opt;
 
+static void addAssemblerKPIC(const ArgList &Args, ArgStringList &CmdArgs) {
+  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)
+    return;
+  if (LastPICArg->getOption().matches(options::OPT_fPIC) ||
+      LastPICArg->getOption().matches(options::OPT_fpic) ||
+      LastPICArg->getOption().matches(options::OPT_fPIE) ||
+      LastPICArg->getOption().matches(options::OPT_fpie)) {
+    CmdArgs.push_back("-KPIC");
+  }
+}
+
 /// CheckPreprocessingOptions - Perform some validation of preprocessing
 /// arguments that is shared with gcc.
 static void CheckPreprocessingOptions(const Driver &D, const ArgList &Args) {
-  if (Arg *A = Args.getLastArg(options::OPT_C, options::OPT_CC))
-    if (!Args.hasArg(options::OPT_E) && !D.CCCIsCPP())
+  if (Arg *A = Args.getLastArg(options::OPT_C, options::OPT_CC)) {
+    if (!Args.hasArg(options::OPT_E) && !Args.hasArg(options::OPT__SLASH_P) &&
+        !Args.hasArg(options::OPT__SLASH_EP) && !D.CCCIsCPP()) {
       D.Diag(diag::err_drv_argument_only_allowed_with)
-        << A->getAsString(Args) << "-E";
+          << A->getBaseArg().getAsString(Args)
+          << (D.IsCLMode() ? "/E, /P or /EP" : "-E");
+    }
+  }
 }
 
 /// CheckCodeGenerationOptions - Perform some validation of code generation
@@ -157,10 +176,7 @@
   // (constructed via -Xarch_).
   Args.AddAllArgValues(CmdArgs, options::OPT_Zlinker_input);
 
-  for (InputInfoList::const_iterator
-         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
-    const InputInfo &II = *it;
-
+  for (const auto &II : Inputs) {
     if (!TC.HasNativeLLVMSupport()) {
       // Don't try to pass LLVM inputs unless we have native support.
       if (II.getType() == types::TY_LLVM_IR ||
@@ -181,16 +197,23 @@
     const Arg &A = II.getInputArg();
 
     // Handle reserved library options.
-    if (A.getOption().matches(options::OPT_Z_reserved_lib_stdcxx)) {
+    if (A.getOption().matches(options::OPT_Z_reserved_lib_stdcxx))
       TC.AddCXXStdlibLibArgs(Args, CmdArgs);
-    } else if (A.getOption().matches(options::OPT_Z_reserved_lib_cckext)) {
+    else if (A.getOption().matches(options::OPT_Z_reserved_lib_cckext))
       TC.AddCCKextLibArgs(Args, CmdArgs);
-    } else
-      A.renderAsInput(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.
-  addDirectoryList(Args, CmdArgs, "-L", "LIBRARY_PATH");
+  //                and only supported on native toolchains.
+  if (!TC.isCrossCompiling())
+    addDirectoryList(Args, CmdArgs, "-L", "LIBRARY_PATH");
 }
 
 /// \brief Determine whether Objective-C automated reference counting is
@@ -208,25 +231,6 @@
   return Args.hasArg(options::OPT_fobjc_link_runtime);
 }
 
-static void addProfileRT(const ToolChain &TC, const ArgList &Args,
-                         ArgStringList &CmdArgs,
-                         llvm::Triple Triple) {
-  if (!(Args.hasArg(options::OPT_fprofile_arcs) ||
-        Args.hasArg(options::OPT_fprofile_generate) ||
-        Args.hasArg(options::OPT_fcreate_profile) ||
-        Args.hasArg(options::OPT_coverage)))
-    return;
-
-  // GCC links libgcov.a by adding -L<inst>/gcc/lib/gcc/<triple>/<ver> -lgcov to
-  // the link line. We cannot do the same thing because unlike gcov there is a
-  // libprofile_rt.so. We used to use the -l:libprofile_rt.a syntax, but that is
-  // not supported by old linkers.
-  std::string ProfileRT =
-    std::string(TC.getDriver().Dir) + "/../lib/libprofile_rt.a";
-
-  CmdArgs.push_back(Args.MakeArgString(ProfileRT));
-}
-
 static bool forwardToGCC(const Option &O) {
   // Don't forward inputs from the original command line.  They are added from
   // InputInfoList.
@@ -297,6 +301,9 @@
     if (A->getOption().matches(options::OPT_M) ||
         A->getOption().matches(options::OPT_MD))
       CmdArgs.push_back("-sys-header-deps");
+
+    if (isa<PrecompileJobAction>(JA))
+      CmdArgs.push_back("-module-file-deps");
   }
 
   if (Args.hasArg(options::OPT_MG)) {
@@ -442,124 +449,6 @@
   getToolChain().AddClangSystemIncludeArgs(Args, CmdArgs);
 }
 
-/// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular
-/// CPU.
-//
-// FIXME: This is redundant with -mcpu, why does LLVM use this.
-// FIXME: tblgen this, or kill it!
-static const char *getLLVMArchSuffixForARM(StringRef CPU) {
-  return llvm::StringSwitch<const char *>(CPU)
-    .Case("strongarm", "v4")
-    .Cases("arm7tdmi", "arm7tdmi-s", "arm710t", "v4t")
-    .Cases("arm720t", "arm9", "arm9tdmi", "v4t")
-    .Cases("arm920", "arm920t", "arm922t", "v4t")
-    .Cases("arm940t", "ep9312","v4t")
-    .Cases("arm10tdmi",  "arm1020t", "v5")
-    .Cases("arm9e",  "arm926ej-s",  "arm946e-s", "v5e")
-    .Cases("arm966e-s",  "arm968e-s",  "arm10e", "v5e")
-    .Cases("arm1020e",  "arm1022e",  "xscale", "iwmmxt", "v5e")
-    .Cases("arm1136j-s",  "arm1136jf-s",  "arm1176jz-s", "v6")
-    .Cases("arm1176jzf-s",  "mpcorenovfp",  "mpcore", "v6")
-    .Cases("arm1156t2-s",  "arm1156t2f-s", "v6t2")
-    .Cases("cortex-a5", "cortex-a7", "cortex-a8", "v7")
-    .Cases("cortex-a9", "cortex-a12", "cortex-a15", "v7")
-    .Cases("cortex-r4", "cortex-r5", "v7r")
-    .Case("cortex-m0", "v6m")
-    .Case("cortex-m3", "v7m")
-    .Case("cortex-m4", "v7em")
-    .Case("cortex-a9-mp", "v7f")
-    .Case("swift", "v7s")
-    .Cases("cortex-a53", "cortex-a57", "v8")
-    .Default("");
-}
-
-/// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targeting.
-//
-// FIXME: tblgen this.
-static std::string getARMTargetCPU(const ArgList &Args,
-                                   const llvm::Triple &Triple) {
-  // FIXME: Warn on inconsistent use of -mcpu and -march.
-
-  // If we have -mcpu=, use that.
-  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
-    StringRef MCPU = A->getValue();
-    // Handle -mcpu=native.
-    if (MCPU == "native")
-      return llvm::sys::getHostCPUName();
-    else
-      return MCPU;
-  }
-
-  StringRef MArch;
-  if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
-    // Otherwise, if we have -march= choose the base CPU for that arch.
-    MArch = A->getValue();
-  } else {
-    // Otherwise, use the Arch from the triple.
-    MArch = Triple.getArchName();
-  }
-
-  // Handle -march=native.
-  std::string NativeMArch;
-  if (MArch == "native") {
-    std::string CPU = llvm::sys::getHostCPUName();
-    if (CPU != "generic") {
-      // Translate the native cpu into the architecture. The switch below will
-      // then chose the minimum cpu for that arch.
-      NativeMArch = std::string("arm") + getLLVMArchSuffixForARM(CPU);
-      MArch = NativeMArch;
-    }
-  }
-
-  return llvm::StringSwitch<const char *>(MArch)
-    .Cases("armv2", "armv2a","arm2")
-    .Case("armv3", "arm6")
-    .Case("armv3m", "arm7m")
-    .Case("armv4", "strongarm")
-    .Case("armv4t", "arm7tdmi")
-    .Cases("armv5", "armv5t", "arm10tdmi")
-    .Cases("armv5e", "armv5te", "arm1022e")
-    .Case("armv5tej", "arm926ej-s")
-    .Cases("armv6", "armv6k", "arm1136jf-s")
-    .Case("armv6j", "arm1136j-s")
-    .Cases("armv6z", "armv6zk", "arm1176jzf-s")
-    .Case("armv6t2", "arm1156t2-s")
-    .Cases("armv6m", "armv6-m", "cortex-m0")
-    .Cases("armv7", "armv7a", "armv7-a", "cortex-a8")
-    .Cases("armv7em", "armv7e-m", "cortex-m4")
-    .Cases("armv7f", "armv7-f", "cortex-a9-mp")
-    .Cases("armv7s", "armv7-s", "swift")
-    .Cases("armv7r", "armv7-r", "cortex-r4")
-    .Cases("armv7m", "armv7-m", "cortex-m3")
-    .Cases("armv8", "armv8a", "armv8-a", "cortex-a53")
-    .Case("ep9312", "ep9312")
-    .Case("iwmmxt", "iwmmxt")
-    .Case("xscale", "xscale")
-    // If all else failed, return the most base CPU with thumb interworking
-    // supported by LLVM.
-    .Default("arm7tdmi");
-}
-
-/// getAArch64TargetCPU - Get the (LLVM) name of the AArch64 cpu we are targeting.
-//
-// FIXME: tblgen this.
-static std::string getAArch64TargetCPU(const ArgList &Args,
-                                       const llvm::Triple &Triple) {
-  // FIXME: Warn on inconsistent use of -mcpu and -march.
-
-  // If we have -mcpu=, use that.
-  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
-    StringRef MCPU = A->getValue();
-    // Handle -mcpu=native.
-    if (MCPU == "native")
-      return llvm::sys::getHostCPUName();
-    else
-      return MCPU;
-  }
-
-  return "generic";
-}
-
 // FIXME: Move to target hook.
 static bool isSignedCharDefault(const llvm::Triple &Triple) {
   switch (Triple.getArch()) {
@@ -567,7 +456,15 @@
     return true;
 
   case llvm::Triple::aarch64:
+  case llvm::Triple::aarch64_be:
+  case llvm::Triple::arm64:
+  case llvm::Triple::arm64_be:
   case llvm::Triple::arm:
+  case llvm::Triple::armeb:
+    if (Triple.isOSDarwin() || Triple.isOSWindows())
+      return true;
+    return false;
+
   case llvm::Triple::ppc:
   case llvm::Triple::ppc64:
     if (Triple.isOSDarwin())
@@ -591,33 +488,6 @@
   }
 }
 
-// Handle -mfpu=.
-//
-// FIXME: Centralize feature selection, defaulting shouldn't be also in the
-// frontend target.
-static void getAArch64FPUFeatures(const Driver &D, const Arg *A,
-                                  const ArgList &Args,
-                                  std::vector<const char *> &Features) {
-  StringRef FPU = A->getValue();
-  if (FPU == "fp-armv8") {
-    Features.push_back("+fp-armv8");
-  } else if (FPU == "neon-fp-armv8") {
-    Features.push_back("+fp-armv8");
-    Features.push_back("+neon");
-  } else if (FPU == "crypto-neon-fp-armv8") {
-    Features.push_back("+fp-armv8");
-    Features.push_back("+neon");
-    Features.push_back("+crypto");
-  } else if (FPU == "neon") {
-    Features.push_back("+neon");
-  } else if (FPU == "none") {
-    Features.push_back("-fp-armv8");
-    Features.push_back("-crypto");
-    Features.push_back("-neon");
-  } else
-    D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
-}
-
 // Handle -mhwdiv=.
 static void getARMHWDivFeatures(const Driver &D, const Arg *A,
                               const ArgList &Args,
@@ -654,16 +524,28 @@
     Features.push_back("-vfp2");
     Features.push_back("-vfp3");
     Features.push_back("-neon");
+  } else if (FPU == "vfp") {
+    Features.push_back("+vfp2");
+    Features.push_back("-neon");
   } else if (FPU == "vfp3-d16" || FPU == "vfpv3-d16") {
     Features.push_back("+vfp3");
     Features.push_back("+d16");
     Features.push_back("-neon");
-  } else if (FPU == "vfp") {
-    Features.push_back("+vfp2");
-    Features.push_back("-neon");
   } else if (FPU == "vfp3" || FPU == "vfpv3") {
     Features.push_back("+vfp3");
     Features.push_back("-neon");
+  } else if (FPU == "vfp4-d16" || FPU == "vfpv4-d16") {
+    Features.push_back("+vfp4");
+    Features.push_back("+d16");
+    Features.push_back("-neon");
+  } else if (FPU == "vfp4" || FPU == "vfpv4") {
+    Features.push_back("+vfp4");
+    Features.push_back("-neon");
+  } else if (FPU == "fp4-sp-d16" || FPU == "fpv4-sp-d16") {
+    Features.push_back("+vfp4");
+    Features.push_back("+d16");
+    Features.push_back("+fp-only-sp");
+    Features.push_back("-neon");
   } else if (FPU == "fp-armv8") {
     Features.push_back("+fp-armv8");
     Features.push_back("-neon");
@@ -691,9 +573,8 @@
 
 // Select the float ABI as determined by -msoft-float, -mhard-float, and
 // -mfloat-abi=.
-static StringRef getARMFloatABI(const Driver &D,
-                                const ArgList &Args,
-                                const llvm::Triple &Triple) {
+StringRef tools::arm::getARMFloatABI(const Driver &D, const ArgList &Args,
+                                     const llvm::Triple &Triple) {
   StringRef FloatABI;
   if (Arg *A = Args.getLastArg(options::OPT_msoft_float,
                                options::OPT_mhard_float,
@@ -722,7 +603,7 @@
       //
       // FIXME: Factor out an ARM class so we can cache the arch somewhere.
       std::string ArchName =
-        getLLVMArchSuffixForARM(getARMTargetCPU(Args, Triple));
+        arm::getLLVMArchSuffixForARM(arm::getARMTargetCPU(Args, Triple));
       if (StringRef(ArchName).startswith("v6") ||
           StringRef(ArchName).startswith("v7"))
         FloatABI = "softfp";
@@ -731,9 +612,21 @@
       break;
     }
 
+    // FIXME: this is invalid for WindowsCE
+    case llvm::Triple::Win32:
+      FloatABI = "hard";
+      break;
+
     case llvm::Triple::FreeBSD:
-      // FreeBSD defaults to soft float
-      FloatABI = "soft";
+      switch(Triple.getEnvironment()) {
+      case llvm::Triple::GNUEABIHF:
+        FloatABI = "hard";
+        break;
+      default:
+        // FreeBSD defaults to soft float
+        FloatABI = "soft";
+        break;
+      }
       break;
 
     default:
@@ -744,13 +637,16 @@
       case llvm::Triple::GNUEABI:
         FloatABI = "softfp";
         break;
+      case llvm::Triple::EABIHF:
+        FloatABI = "hard";
+        break;
       case llvm::Triple::EABI:
         // EABI is always AAPCS, and if it was not marked 'hard', it's softfp
         FloatABI = "softfp";
         break;
       case llvm::Triple::Android: {
         std::string ArchName =
-          getLLVMArchSuffixForARM(getARMTargetCPU(Args, Triple));
+          arm::getLLVMArchSuffixForARM(arm::getARMTargetCPU(Args, Triple));
         if (StringRef(ArchName).startswith("v7"))
           FloatABI = "softfp";
         else
@@ -760,7 +656,9 @@
       default:
         // Assume "soft", but warn the user we are guessing.
         FloatABI = "soft";
-        D.Diag(diag::warn_drv_assuming_mfloat_abi_is) << "soft";
+        if (Triple.getOS() != llvm::Triple::UnknownOS ||
+            !Triple.isOSBinFormatMachO())
+          D.Diag(diag::warn_drv_assuming_mfloat_abi_is) << "soft";
         break;
       }
     }
@@ -771,18 +669,30 @@
 
 static void getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple,
                                  const ArgList &Args,
-                                 std::vector<const char *> &Features) {
-  StringRef FloatABI = getARMFloatABI(D, Args, Triple);
-  // 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.
-  // Use software floating point operations?
-  if (FloatABI == "soft")
-    Features.push_back("+soft-float");
+                                 std::vector<const char *> &Features,
+                                 bool ForAS) {
+  StringRef FloatABI = tools::arm::getARMFloatABI(D, Args, Triple);
+  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 argument passing?
-  if (FloatABI != "hard")
-    Features.push_back("+soft-float-abi");
+    // Use software floating point operations?
+    if (FloatABI == "soft")
+      Features.push_back("+soft-float");
+
+    // Use software floating point argument passing?
+    if (FloatABI != "hard")
+      Features.push_back("+soft-float-abi");
+  }
 
   // Honor -mfpu=.
   if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ))
@@ -792,8 +702,11 @@
 
   // Setting -msoft-float effectively disables NEON because of the GCC
   // implementation, although the same isn't true of VFP or VFP3.
-  if (FloatABI == "soft")
+  if (FloatABI == "soft") {
     Features.push_back("-neon");
+    // Also need to explicitly disable features which imply NEON.
+    Features.push_back("-crypto");
+  }
 
   // En/disable crc
   if (Arg *A = Args.getLastArg(options::OPT_mcrc,
@@ -812,23 +725,28 @@
   // Get the effective triple, which takes into account the deployment target.
   std::string TripleStr = getToolChain().ComputeEffectiveClangTriple(Args);
   llvm::Triple Triple(TripleStr);
-  std::string CPUName = getARMTargetCPU(Args, Triple);
+  std::string CPUName = arm::getARMTargetCPU(Args, Triple);
 
   // Select the ABI to use.
   //
   // FIXME: Support -meabi.
-  const char *ABIName = 0;
+  const char *ABIName = nullptr;
   if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) {
     ABIName = A->getValue();
-  } else if (Triple.isOSDarwin()) {
+  } else if (Triple.isOSBinFormatMachO()) {
     // The backend is hardwired to assume AAPCS for M-class processors, ensure
     // the frontend matches that.
     if (Triple.getEnvironment() == llvm::Triple::EABI ||
+        (Triple.getOS() == llvm::Triple::UnknownOS &&
+         Triple.getObjectFormat() == llvm::Triple::MachO) ||
         StringRef(CPUName).startswith("cortex-m")) {
       ABIName = "aapcs";
     } 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()) {
@@ -837,6 +755,7 @@
     case llvm::Triple::GNUEABIHF:
       ABIName = "aapcs-linux";
       break;
+    case llvm::Triple::EABIHF:
     case llvm::Triple::EABI:
       ABIName = "aapcs";
       break;
@@ -848,7 +767,7 @@
   CmdArgs.push_back(ABIName);
 
   // Determine floating point ABI from the options & target defaults.
-  StringRef FloatABI = getARMFloatABI(D, Args, Triple);
+  StringRef FloatABI = tools::arm::getARMFloatABI(D, Args, Triple);
   if (FloatABI == "soft") {
     // Floating point operations and argument passing are soft.
     //
@@ -895,23 +814,97 @@
                     true))
     CmdArgs.push_back("-no-implicit-float");
 
-    // 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)) {
-      CmdArgs.push_back("-backend-option");
-      CmdArgs.push_back("-arm-reserve-r9");
-    }
+  // 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)) {
+    CmdArgs.push_back("-backend-option");
+    CmdArgs.push_back("-arm-reserve-r9");
+  }
+}
+
+/// getAArch64TargetCPU - Get the (LLVM) name of the AArch64 cpu we are
+/// targeting.
+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 = A->getValue();
+  } else if ((A = Args.getLastArg(options::OPT_mcpu_EQ))) {
+    StringRef Mcpu = A->getValue();
+    CPU = Mcpu.split("+").first;
+  }
+
+  // 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 {
+  std::string TripleStr = getToolChain().ComputeEffectiveClangTriple(Args);
+  llvm::Triple Triple(TripleStr);
+
+  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 (Args.hasArg(options::OPT_mstrict_align)) {
+    CmdArgs.push_back("-backend-option");
+    CmdArgs.push_back("-aarch64-strict-align");
+  }
+
+  // Setting -mno-global-merge disables the codegen global merge pass. Setting
+  // -mglobal-merge has no effect as the pass is enabled by default.
+  if (Arg *A = Args.getLastArg(options::OPT_mglobal_merge,
+                               options::OPT_mno_global_merge)) {
+    if (A->getOption().matches(options::OPT_mno_global_merge))
+      CmdArgs.push_back("-mno-global-merge");
+  }
 }
 
 // Get CPU and ABI names. They are not independent
 // so we have to calculate them together.
-static void getMipsCPUAndABI(const ArgList &Args,
-                             const llvm::Triple &Triple,
-                             StringRef &CPUName,
-                             StringRef &ABIName) {
-  const char *DefMips32CPU = "mips32";
-  const char *DefMips64CPU = "mips64";
+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";
+  }
 
   if (Arg *A = Args.getLastArg(options::OPT_march_EQ,
                                options::OPT_mcpu_EQ))
@@ -943,22 +936,22 @@
     }
   }
 
-  if (!ABIName.empty()) {
-    // Deduce CPU name from ABI name.
-    CPUName = llvm::StringSwitch<const char *>(ABIName)
-      .Cases("32", "o32", "eabi", DefMips32CPU)
-      .Cases("n32", "n64", "64", DefMips64CPU)
-      .Default("");
-  }
-  else if (!CPUName.empty()) {
-    // Deduce ABI name from CPU name.
-    ABIName = llvm::StringSwitch<const char *>(CPUName)
-      .Cases("mips32", "mips32r2", "o32")
-      .Cases("mips64", "mips64r2", "n64")
-      .Default("");
+  if (ABIName.empty()) {
+    // Deduce ABI name from the target triple.
+    if (Triple.getArch() == llvm::Triple::mips ||
+        Triple.getArch() == llvm::Triple::mipsel)
+      ABIName = "o32";
+    else
+      ABIName = "n64";
   }
 
-  // FIXME: Warn on inconsistent cpu and abi usage.
+  if (CPUName.empty()) {
+    // Deduce CPU name from ABI name.
+    CPUName = llvm::StringSwitch<const char *>(ABIName)
+      .Cases("o32", "eabi", DefMips32CPU)
+      .Cases("n32", "n64", DefMips64CPU)
+      .Default("");
+  }
 }
 
 // Convert ABI name to the GNU tools acceptable variant.
@@ -1012,11 +1005,27 @@
   }
 }
 
-static void getMIPSTargetFeatures(const Driver &D, const ArgList &Args,
+static void getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple,
+                                  const ArgList &Args,
                                   std::vector<const char *> &Features) {
+  StringRef CPUName;
+  StringRef ABIName;
+  mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
+  ABIName = getGnuCompatibleMipsABIName(ABIName);
+
+  // Always override the backend's default ABI.
+  std::string ABIFeature = llvm::StringSwitch<StringRef>(ABIName)
+                               .Case("32", "+o32")
+                               .Case("n32", "+n32")
+                               .Case("64", "+n64")
+                               .Case("eabi", "+eabi")
+                               .Default(("+" + ABIName).str());
+  Features.push_back("-o32");
+  Features.push_back("-n64");
+  Features.push_back(Args.MakeArgString(ABIFeature));
+
   StringRef FloatABI = getMipsFloatABI(D, Args);
-  bool IsMips16 = Args.getLastArg(options::OPT_mips16) != NULL;
-  if (FloatABI == "soft" || (FloatABI == "hard" && IsMips16)) {
+  if (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.
@@ -1024,8 +1033,14 @@
   }
 
   if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) {
-    if (StringRef(A->getValue()) == "2008")
+    StringRef Val = StringRef(A->getValue());
+    if (Val == "2008")
       Features.push_back("+nan2008");
+    else if (Val == "legacy")
+      Features.push_back("-nan2008");
+    else
+      D.Diag(diag::err_drv_unsupported_option_argument)
+          << A->getOption().getName() << Val;
   }
 
   AddTargetFeature(Args, Features, options::OPT_msingle_float,
@@ -1040,8 +1055,25 @@
                    "dspr2");
   AddTargetFeature(Args, Features, options::OPT_mmsa, options::OPT_mno_msa,
                    "msa");
-  AddTargetFeature(Args, Features, options::OPT_mfp64, options::OPT_mfp32,
-                   "fp64");
+
+  // Add the last -mfp32/-mfpxx/-mfp64 or if none are given and the ABI is O32
+  // pass -mfpxx
+  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::isFPXXDefault(Triple, CPUName, ABIName)) {
+    Features.push_back(Args.MakeArgString("+fpxx"));
+    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,
@@ -1050,25 +1082,18 @@
   StringRef CPUName;
   StringRef ABIName;
   const llvm::Triple &Triple = getToolChain().getTriple();
-  getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
+  mips::getMipsCPUAndABI(Args, Triple, CPUName, ABIName);
 
   CmdArgs.push_back("-target-abi");
   CmdArgs.push_back(ABIName.data());
 
   StringRef FloatABI = getMipsFloatABI(D, Args);
 
-  bool IsMips16 = Args.getLastArg(options::OPT_mips16) != NULL;
-
-  if (FloatABI == "soft" || (FloatABI == "hard" && IsMips16)) {
+  if (FloatABI == "soft") {
     // Floating point operations and argument passing are soft.
     CmdArgs.push_back("-msoft-float");
     CmdArgs.push_back("-mfloat-abi");
     CmdArgs.push_back("soft");
-
-    if (FloatABI == "hard" && IsMips16) {
-      CmdArgs.push_back("-mllvm");
-      CmdArgs.push_back("-mips16-hard-float");
-    }
   }
   else {
     // Floating point operations and argument passing are hard.
@@ -1154,6 +1179,7 @@
       .Case("power6", "pwr6")
       .Case("power6x", "pwr6x")
       .Case("power7", "pwr7")
+      .Case("power8", "pwr8")
       .Case("pwr3", "pwr3")
       .Case("pwr4", "pwr4")
       .Case("pwr5", "pwr5")
@@ -1161,6 +1187,7 @@
       .Case("pwr6", "pwr6")
       .Case("pwr6x", "pwr6x")
       .Case("pwr7", "pwr7")
+      .Case("pwr8", "pwr8")
       .Case("powerpc", "ppc")
       .Case("powerpc64", "ppc64")
       .Case("powerpc64le", "ppc64le")
@@ -1234,7 +1261,7 @@
                              ArgStringList &CmdArgs) const {
   const Driver &D = getToolChain().getDriver();
 
-  // Select the float ABI as determined by -msoft-float, -mhard-float, and
+  // Select the float ABI as determined by -msoft-float and -mhard-float.
   StringRef FloatABI;
   if (Arg *A = Args.getLastArg(options::OPT_msoft_float,
                                options::OPT_mhard_float)) {
@@ -1292,7 +1319,7 @@
 
   if (Triple.getArch() != llvm::Triple::x86_64 &&
       Triple.getArch() != llvm::Triple::x86)
-    return 0; // This routine is only handling x86 targets.
+    return nullptr; // This routine is only handling x86 targets.
 
   bool Is64Bit = Triple.getArch() == llvm::Triple::x86_64;
 
@@ -1303,10 +1330,9 @@
     return Is64Bit ? "core2" : "yonah";
   }
 
-  // All x86 devices running Android have core2 as their common
-  // denominator. This makes a better choice than pentium4.
+  // On Android use targets compatible with gcc
   if (Triple.getEnvironment() == llvm::Triple::Android)
-    return "core2";
+    return Is64Bit ? "x86-64" : "i686";
 
   // Everything else goes to x86-64 in 64-bit mode.
   if (Is64Bit)
@@ -1333,11 +1359,16 @@
     return "";
 
   case llvm::Triple::aarch64:
-    return getAArch64TargetCPU(Args, T);
+  case llvm::Triple::aarch64_be:
+  case llvm::Triple::arm64:
+  case llvm::Triple::arm64_be:
+    return getAArch64TargetCPU(Args);
 
   case llvm::Triple::arm:
+  case llvm::Triple::armeb:
   case llvm::Triple::thumb:
-    return getARMTargetCPU(Args, T);
+  case llvm::Triple::thumbeb:
+    return arm::getARMTargetCPU(Args, T);
 
   case llvm::Triple::mips:
   case llvm::Triple::mipsel:
@@ -1345,7 +1376,7 @@
   case llvm::Triple::mips64el: {
     StringRef CPUName;
     StringRef ABIName;
-    getMipsCPUAndABI(Args, T, CPUName, ABIName);
+    mips::getMipsCPUAndABI(Args, T, CPUName, ABIName);
     return CPUName;
   }
 
@@ -1368,7 +1399,8 @@
   }
 
   case llvm::Triple::sparc:
-    if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
+  case llvm::Triple::sparcv9:
+    if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
       return A->getValue();
     return "";
 
@@ -1387,7 +1419,26 @@
   }
 }
 
-static void getX86TargetFeatures(const llvm::Triple &Triple,
+static void AddGoldPlugin(const ToolChain &ToolChain, const ArgList &Args,
+                          ArgStringList &CmdArgs) {
+  // 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/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));
+}
+
+static void getX86TargetFeatures(const Driver & D,
+                                 const llvm::Triple &Triple,
                                  const ArgList &Args,
                                  std::vector<const char *> &Features) {
   if (Triple.getArchName() == "x86_64h") {
@@ -1401,6 +1452,40 @@
     Features.push_back("-fsgsbase");
   }
 
+  // Add features to comply with gcc on Android
+  if (Triple.getEnvironment() == llvm::Triple::Android) {
+    if (Triple.getArch() == 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 (Triple.getArch() == llvm::Triple::x86_64 ||
+        Triple.getArch() == llvm::Triple::x86) {
+      if (Arch == "AVX" || Arch == "AVX2") {
+        ArchUsed = true;
+        Features.push_back(Args.MakeArgString("+" + Arch.lower()));
+      }
+    }
+    // Then, look for x86-specific flags.
+    if (Triple.getArch() == 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.
   for (arg_iterator it = Args.filtered_begin(options::OPT_m_x86_Features_Group),
@@ -1444,6 +1529,17 @@
   }
   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;
+    }
+  }
 }
 
 static inline bool HasPICArg(const ArgList &Args) {
@@ -1491,15 +1587,146 @@
   CmdArgs.push_back ("-machine-sink-split=0");
 }
 
+// Decode AArch64 features from string like +[no]featureA+[no]featureB+...
+static bool DecodeAArch64Features(const Driver &D, const StringRef &text,
+                                  std::vector<const char *> &Features) {
+  SmallVector<StringRef, 8> Split;
+  text.split(Split, StringRef("+"), -1, false);
+
+  for (unsigned I = 0, E = Split.size(); I != E; ++I) {
+    const char *result = llvm::StringSwitch<const char *>(Split[I])
+                             .Case("fp", "+fp-armv8")
+                             .Case("simd", "+neon")
+                             .Case("crc", "+crc")
+                             .Case("crypto", "+crypto")
+                             .Case("nofp", "-fp-armv8")
+                             .Case("nosimd", "-neon")
+                             .Case("nocrc", "-crc")
+                             .Case("nocrypto", "-crypto")
+                             .Default(nullptr);
+    if (result)
+      Features.push_back(result);
+    else if (Split[I] == "neon" || Split[I] == "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<const char *> &Features) {
+  std::pair<StringRef, StringRef> Split = Mcpu.split("+");
+  CPU = Split.first;
+  if (CPU == "cyclone" || CPU == "cortex-a53" || CPU == "cortex-a57") {
+    Features.push_back("+neon");
+    Features.push_back("+crc");
+    Features.push_back("+crypto");
+  } else if (CPU == "generic") {
+    Features.push_back("+neon");
+  } else {
+    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<const char *> &Features) {
+  std::pair<StringRef, StringRef> Split = March.split("+");
+  if (Split.first != "armv8-a")
+    return false;
+
+  if (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<const char *> &Features) {
+  StringRef CPU;
+  if (!DecodeAArch64Mcpu(D, Mcpu, CPU, Features))
+    return false;
+
+  return true;
+}
+
+static bool
+getAArch64MicroArchFeaturesFromMtune(const Driver &D, StringRef Mtune,
+                                     const ArgList &Args,
+                                     std::vector<const char *> &Features) {
+  // Handle CPU name is 'native'.
+  if (Mtune == "native")
+    Mtune = llvm::sys::getHostCPUName();
+  if (Mtune == "cyclone") {
+    Features.push_back("+zcm");
+    Features.push_back("+zcz");
+  }
+  return true;
+}
+
+static bool
+getAArch64MicroArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu,
+                                    const ArgList &Args,
+                                    std::vector<const char *> &Features) {
+  StringRef CPU;
+  std::vector<const char *> DecodedFeature;
+  if (!DecodeAArch64Mcpu(D, Mcpu, CPU, DecodedFeature))
+    return false;
+
+  return getAArch64MicroArchFeaturesFromMtune(D, CPU, Args, Features);
+}
+
 static void getAArch64TargetFeatures(const Driver &D, const ArgList &Args,
                                      std::vector<const char *> &Features) {
-  // Honor -mfpu=.
-  if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ))
-    getAArch64FPUFeatures(D, A, Args, 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);
+
+  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);
+
+  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");
+  }
 }
 
 static void getTargetFeatures(const Driver &D, const llvm::Triple &Triple,
-                              const ArgList &Args, ArgStringList &CmdArgs) {
+                              const ArgList &Args, ArgStringList &CmdArgs,
+                              bool ForAS) {
   std::vector<const char *> Features;
   switch (Triple.getArch()) {
   default:
@@ -1508,12 +1735,14 @@
   case llvm::Triple::mipsel:
   case llvm::Triple::mips64:
   case llvm::Triple::mips64el:
-    getMIPSTargetFeatures(D, Args, Features);
+    getMIPSTargetFeatures(D, Triple, Args, Features);
     break;
 
   case llvm::Triple::arm:
+  case llvm::Triple::armeb:
   case llvm::Triple::thumb:
-    getARMTargetFeatures(D, Triple, Args, Features);
+  case llvm::Triple::thumbeb:
+    getARMTargetFeatures(D, Triple, Args, Features, ForAS);
     break;
 
   case llvm::Triple::ppc:
@@ -1525,11 +1754,14 @@
     getSparcTargetFeatures(Args, Features);
     break;
   case llvm::Triple::aarch64:
+  case llvm::Triple::aarch64_be:
+  case llvm::Triple::arm64:
+  case llvm::Triple::arm64_be:
     getAArch64TargetFeatures(D, Args, Features);
     break;
   case llvm::Triple::x86:
   case llvm::Triple::x86_64:
-    getX86TargetFeatures(Triple, Args, Features);
+    getX86TargetFeatures(D, Triple, Args, Features);
     break;
   }
 
@@ -1564,7 +1796,7 @@
   if (runtime.isNonFragile())
     return true;
 
-  if (!Triple.isOSDarwin())
+  if (!Triple.isMacOSX())
     return false;
 
   return (!Triple.isMacOSXVersionLT(10,5) &&
@@ -1572,6 +1804,45 @@
            Triple.getArch() == llvm::Triple::arm));
 }
 
+namespace {
+  struct ExceptionSettings {
+    bool ExceptionsEnabled;
+    bool ShouldUseExceptionTables;
+    ExceptionSettings() : ExceptionsEnabled(false),
+                          ShouldUseExceptionTables(false) {}
+  };
+} // end anonymous namespace.
+
+// exceptionSettings() exists to share the logic between -cc1 and linker
+// invocations.
+static ExceptionSettings exceptionSettings(const ArgList &Args,
+                                           const llvm::Triple &Triple) {
+  ExceptionSettings ES;
+
+  // Are exceptions enabled by default?
+  ES.ExceptionsEnabled = (Triple.getArch() != llvm::Triple::xcore);
+
+  // This keeps track of whether exceptions were explicitly turned on or off.
+  bool DidHaveExplicitExceptionFlag = false;
+
+  if (Arg *A = Args.getLastArg(options::OPT_fexceptions,
+                               options::OPT_fno_exceptions)) {
+    if (A->getOption().matches(options::OPT_fexceptions))
+      ES.ExceptionsEnabled = true;
+    else
+      ES.ExceptionsEnabled = false;
+
+    DidHaveExplicitExceptionFlag = true;
+  }
+
+  // Exception tables and cleanups can be enabled with -fexceptions even if the
+  // language itself doesn't support exceptions.
+  if (ES.ExceptionsEnabled && DidHaveExplicitExceptionFlag)
+    ES.ShouldUseExceptionTables = true;
+
+  return ES;
+}
+
 /// addExceptionArgs - 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.
@@ -1594,28 +1865,8 @@
     return;
   }
 
-  // Exceptions are enabled by default.
-  bool ExceptionsEnabled = true;
-
-  // This keeps track of whether exceptions were explicitly turned on or off.
-  bool DidHaveExplicitExceptionFlag = false;
-
-  if (Arg *A = Args.getLastArg(options::OPT_fexceptions,
-                               options::OPT_fno_exceptions)) {
-    if (A->getOption().matches(options::OPT_fexceptions))
-      ExceptionsEnabled = true;
-    else
-      ExceptionsEnabled = false;
-
-    DidHaveExplicitExceptionFlag = true;
-  }
-
-  bool ShouldUseExceptionTables = false;
-
-  // Exception tables and cleanups can be enabled with -fexceptions even if the
-  // language itself doesn't support exceptions.
-  if (ExceptionsEnabled && DidHaveExplicitExceptionFlag)
-    ShouldUseExceptionTables = true;
+   // Gather the exception settings from the command line arguments.
+   ExceptionSettings ES = exceptionSettings(Args, Triple);
 
   // Obj-C exceptions are enabled by default, regardless of -fexceptions. This
   // is not necessarily sensible, but follows GCC.
@@ -1625,12 +1876,12 @@
                    true)) {
     CmdArgs.push_back("-fobjc-exceptions");
 
-    ShouldUseExceptionTables |=
+    ES.ShouldUseExceptionTables |=
       shouldUseExceptionTablesForObjCExceptions(objcRuntime, Triple);
   }
 
   if (types::isCXX(InputType)) {
-    bool CXXExceptionsEnabled = ExceptionsEnabled;
+    bool CXXExceptionsEnabled = ES.ExceptionsEnabled;
 
     if (Arg *A = Args.getLastArg(options::OPT_fcxx_exceptions,
                                  options::OPT_fno_cxx_exceptions,
@@ -1645,11 +1896,11 @@
     if (CXXExceptionsEnabled) {
       CmdArgs.push_back("-fcxx-exceptions");
 
-      ShouldUseExceptionTables = true;
+      ES.ShouldUseExceptionTables = true;
     }
   }
 
-  if (ShouldUseExceptionTables)
+  if (ES.ShouldUseExceptionTables)
     CmdArgs.push_back("-fexceptions");
 }
 
@@ -1665,19 +1916,6 @@
                        Default);
 }
 
-static bool ShouldDisableCFI(const ArgList &Args,
-                             const ToolChain &TC) {
-  bool Default = true;
-  if (TC.getTriple().isOSDarwin()) {
-    // The native darwin assembler doesn't support cfi directives, so
-    // we disable them if we think the .s file will be passed to it.
-    Default = TC.useIntegratedAs();
-  }
-  return !Args.hasFlag(options::OPT_fdwarf2_cfi_asm,
-                       options::OPT_fno_dwarf2_cfi_asm,
-                       Default);
-}
-
 static bool ShouldDisableDwarfDirectory(const ArgList &Args,
                                         const ToolChain &TC) {
   bool UseDwarfDirectory = Args.hasFlag(options::OPT_fdwarf_directory_asm,
@@ -1691,8 +1929,8 @@
   if (isa<CompileJobAction>(A))
     return true;
 
-  for (Action::const_iterator it = A->begin(), ie = A->end(); it != ie; ++it)
-    if (ContainsCompileAction(*it))
+  for (const auto &Act : *A)
+    if (ContainsCompileAction(Act))
       return true;
 
   return false;
@@ -1708,9 +1946,8 @@
 
   if (RelaxDefault) {
     RelaxDefault = false;
-    for (ActionList::const_iterator it = C.getActions().begin(),
-           ie = C.getActions().end(); it != ie; ++it) {
-      if (ContainsCompileAction(*it)) {
+    for (const auto &Act : C.getActions()) {
+      if (ContainsCompileAction(Act)) {
         RelaxDefault = true;
         break;
       }
@@ -1737,6 +1974,7 @@
 
     // When using an integrated assembler, translate -Wa, and -Xassembler
     // options.
+    bool CompressDebugSections = false;
     for (arg_iterator it = Args.filtered_begin(options::OPT_Wa_COMMA,
                                                options::OPT_Xassembler),
            ie = Args.filtered_end(); it != ie; ++it) {
@@ -1760,48 +1998,116 @@
           CmdArgs.push_back("-fatal-assembler-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.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-")) {
+          CmdArgs.push_back(Value.data());
         } 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);
+    }
 }
 
-static void addProfileRTLinux(
+// Until ARM libraries are build separately, we have them all in one library
+static StringRef getArchNameForCompilerRTLib(const ToolChain &TC) {
+  if (TC.getArch() == llvm::Triple::arm ||
+      TC.getArch() == llvm::Triple::armeb)
+    return "arm";
+  else
+    return TC.getArchName();
+}
+
+static SmallString<128> getCompilerRTLibDir(const ToolChain &TC) {
+  // The runtimes are located in the OS-specific resource directory.
+  SmallString<128> Res(TC.getDriver().ResourceDir);
+  const llvm::Triple &Triple = TC.getTriple();
+  // TC.getOS() yield "freebsd10.0" whereas "freebsd" is expected.
+  StringRef OSLibName = (Triple.getOS() == llvm::Triple::FreeBSD) ?
+    "freebsd" : TC.getOS();
+  llvm::sys::path::append(Res, "lib", OSLibName);
+  return Res;
+}
+
+// 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 addClangRTLinux(
+    const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs) {
+  SmallString<128> LibClangRT = getCompilerRTLibDir(TC);
+  llvm::sys::path::append(LibClangRT, Twine("libclang_rt.builtins-") +
+                                          getArchNameForCompilerRTLib(TC) +
+                                          ".a");
+
+  CmdArgs.push_back(Args.MakeArgString(LibClangRT));
+  CmdArgs.push_back("-lgcc_s");
+  if (TC.getDriver().CCCIsCXX())
+    CmdArgs.push_back("-lgcc_eh");
+}
+
+static void addProfileRT(
     const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs) {
   if (!(Args.hasArg(options::OPT_fprofile_arcs) ||
         Args.hasArg(options::OPT_fprofile_generate) ||
+        Args.hasArg(options::OPT_fprofile_instr_generate) ||
         Args.hasArg(options::OPT_fcreate_profile) ||
         Args.hasArg(options::OPT_coverage)))
     return;
 
-  // The profile runtime is located in the Linux library directory and has name
-  // "libclang_rt.profile-<ArchName>.a".
-  SmallString<128> LibProfile(TC.getDriver().ResourceDir);
-  llvm::sys::path::append(
-      LibProfile, "lib", "linux",
-      Twine("libclang_rt.profile-") + TC.getArchName() + ".a");
+  // -fprofile-instr-generate requires position-independent code to build with
+  // shared objects.  Link against the right archive.
+  const char *Lib = "libclang_rt.profile-";
+  if (Args.hasArg(options::OPT_fprofile_instr_generate) &&
+      Args.hasArg(options::OPT_shared))
+    Lib = "libclang_rt.profile-pic-";
+
+  SmallString<128> LibProfile = getCompilerRTLibDir(TC);
+  llvm::sys::path::append(LibProfile,
+      Twine(Lib) + getArchNameForCompilerRTLib(TC) + ".a");
 
   CmdArgs.push_back(Args.MakeArgString(LibProfile));
 }
 
-static void addSanitizerRTLinkFlagsLinux(
-    const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs,
-    const StringRef Sanitizer, bool BeforeLibStdCXX,
-    bool ExportSymbols = true) {
-  // Sanitizer runtime is located in the Linux library directory and
-  // has name "libclang_rt.<Sanitizer>-<ArchName>.a".
-  SmallString<128> LibSanitizer(TC.getDriver().ResourceDir);
-  llvm::sys::path::append(
-      LibSanitizer, "lib", "linux",
-      (Twine("libclang_rt.") + Sanitizer + "-" + TC.getArchName() + ".a"));
+static SmallString<128> getSanitizerRTLibName(const ToolChain &TC,
+                                              const StringRef Sanitizer,
+                                              bool Shared) {
+  // Sanitizer runtime has name "libclang_rt.<Sanitizer>-<ArchName>.{a,so}"
+  // (or "libclang_rt.<Sanitizer>-<ArchName>-android.so for Android)
+  const char *EnvSuffix =
+    TC.getTriple().getEnvironment() == llvm::Triple::Android ?  "-android" : "";
+  SmallString<128> LibSanitizer = getCompilerRTLibDir(TC);
+  llvm::sys::path::append(LibSanitizer,
+                          Twine("libclang_rt.") + Sanitizer + "-" +
+                              getArchNameForCompilerRTLib(TC) + EnvSuffix +
+                              (Shared ? ".so" : ".a"));
+  return LibSanitizer;
+}
+
+static void addSanitizerRTLinkFlags(const ToolChain &TC, const ArgList &Args,
+                                    ArgStringList &CmdArgs,
+                                    const StringRef Sanitizer,
+                                    bool BeforeLibStdCXX,
+                                    bool ExportSymbols = true,
+                                    bool LinkDeps = true) {
+  SmallString<128> LibSanitizer =
+      getSanitizerRTLibName(TC, Sanitizer, /*Shared*/ false);
 
   // Sanitizer runtime may need to come before -lstdc++ (or -lc++, libstdc++.a,
   // etc.) so that the linker picks custom versions of the global 'operator
@@ -1817,10 +2123,15 @@
   CmdArgs.insert(BeforeLibStdCXX ? CmdArgs.begin() : CmdArgs.end(),
                  LibSanitizerArgs.begin(), LibSanitizerArgs.end());
 
-  CmdArgs.push_back("-lpthread");
-  CmdArgs.push_back("-lrt");
-  CmdArgs.push_back("-ldl");
-  CmdArgs.push_back("-lm");
+  if (LinkDeps) {
+    // Link sanitizer dependencies explicitly
+    CmdArgs.push_back("-lpthread");
+    CmdArgs.push_back("-lrt");
+    CmdArgs.push_back("-lm");
+    // There's no libdl on FreeBSD.
+    if (TC.getTriple().getOS() != llvm::Triple::FreeBSD)
+      CmdArgs.push_back("-ldl");
+  }
 
   // If possible, use a dynamic symbols file to export the symbols from the
   // runtime library. If we can't do so, use -export-dynamic instead to export
@@ -1836,66 +2147,102 @@
 
 /// If AddressSanitizer is enabled, add appropriate linker flags (Linux).
 /// This needs to be called before we add the C run-time (malloc, etc).
-static void addAsanRTLinux(const ToolChain &TC, const ArgList &Args,
-                           ArgStringList &CmdArgs) {
-  if (TC.getTriple().getEnvironment() == llvm::Triple::Android) {
-    SmallString<128> LibAsan(TC.getDriver().ResourceDir);
-    llvm::sys::path::append(LibAsan, "lib", "linux",
-        (Twine("libclang_rt.asan-") +
-            TC.getArchName() + "-android.so"));
-    CmdArgs.insert(CmdArgs.begin(), Args.MakeArgString(LibAsan));
+static void addAsanRT(const ToolChain &TC, const ArgList &Args,
+                      ArgStringList &CmdArgs, bool Shared, bool IsCXX) {
+  if (Shared) {
+    // Link dynamic runtime if necessary.
+    SmallString<128> LibSanitizer =
+        getSanitizerRTLibName(TC, "asan", Shared);
+    CmdArgs.insert(CmdArgs.begin(), Args.MakeArgString(LibSanitizer));
+  }
+
+  // Do not link static runtime to DSOs or if compiling for Android.
+  if (Args.hasArg(options::OPT_shared) ||
+      (TC.getTriple().getEnvironment() == llvm::Triple::Android))
+    return;
+
+  if (Shared) {
+    addSanitizerRTLinkFlags(TC, Args, CmdArgs, "asan-preinit",
+                            /*BeforeLibStdCXX*/ true, /*ExportSymbols*/ false,
+                            /*LinkDeps*/ false);
   } else {
-    if (!Args.hasArg(options::OPT_shared))
-      addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "asan", true);
+    addSanitizerRTLinkFlags(TC, Args, CmdArgs, "asan", true);
+    if (IsCXX)
+      addSanitizerRTLinkFlags(TC, Args, CmdArgs, "asan_cxx", true);
   }
 }
 
 /// If ThreadSanitizer is enabled, add appropriate linker flags (Linux).
 /// This needs to be called before we add the C run-time (malloc, etc).
-static void addTsanRTLinux(const ToolChain &TC, const ArgList &Args,
-                           ArgStringList &CmdArgs) {
+static void addTsanRT(const ToolChain &TC, const ArgList &Args,
+                      ArgStringList &CmdArgs) {
   if (!Args.hasArg(options::OPT_shared))
-    addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "tsan", true);
+    addSanitizerRTLinkFlags(TC, Args, CmdArgs, "tsan", true);
 }
 
 /// If MemorySanitizer is enabled, add appropriate linker flags (Linux).
 /// This needs to be called before we add the C run-time (malloc, etc).
-static void addMsanRTLinux(const ToolChain &TC, const ArgList &Args,
-                           ArgStringList &CmdArgs) {
+static void addMsanRT(const ToolChain &TC, const ArgList &Args,
+                      ArgStringList &CmdArgs) {
   if (!Args.hasArg(options::OPT_shared))
-    addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "msan", true);
+    addSanitizerRTLinkFlags(TC, Args, CmdArgs, "msan", true);
 }
 
 /// If LeakSanitizer is enabled, add appropriate linker flags (Linux).
 /// This needs to be called before we add the C run-time (malloc, etc).
-static void addLsanRTLinux(const ToolChain &TC, const ArgList &Args,
-                           ArgStringList &CmdArgs) {
+static void addLsanRT(const ToolChain &TC, const ArgList &Args,
+                      ArgStringList &CmdArgs) {
   if (!Args.hasArg(options::OPT_shared))
-    addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "lsan", true);
+    addSanitizerRTLinkFlags(TC, Args, CmdArgs, "lsan", true);
 }
 
 /// If UndefinedBehaviorSanitizer is enabled, add appropriate linker flags
 /// (Linux).
-static void addUbsanRTLinux(const ToolChain &TC, const ArgList &Args,
-                            ArgStringList &CmdArgs, bool IsCXX,
-                            bool HasOtherSanitizerRt) {
+static void addUbsanRT(const ToolChain &TC, const ArgList &Args,
+                       ArgStringList &CmdArgs, bool IsCXX,
+                       bool HasOtherSanitizerRt) {
+  // Do not link runtime into shared libraries.
+  if (Args.hasArg(options::OPT_shared))
+    return;
+
   // Need a copy of sanitizer_common. This could come from another sanitizer
   // runtime; if we're not including one, include our own copy.
   if (!HasOtherSanitizerRt)
-    addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "san", true, false);
+    addSanitizerRTLinkFlags(TC, Args, CmdArgs, "san", true, false);
 
-  addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "ubsan", false);
+  addSanitizerRTLinkFlags(TC, Args, CmdArgs, "ubsan", false, true);
 
   // Only include the bits of the runtime which need a C++ ABI library if
   // we're linking in C++ mode.
   if (IsCXX)
-    addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "ubsan_cxx", false);
+    addSanitizerRTLinkFlags(TC, Args, CmdArgs, "ubsan_cxx", false, true);
 }
 
-static void addDfsanRTLinux(const ToolChain &TC, const ArgList &Args,
-                            ArgStringList &CmdArgs) {
+static void addDfsanRT(const ToolChain &TC, const ArgList &Args,
+                       ArgStringList &CmdArgs) {
   if (!Args.hasArg(options::OPT_shared))
-    addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "dfsan", true);
+    addSanitizerRTLinkFlags(TC, Args, CmdArgs, "dfsan", true);
+}
+
+// Should be called before we add C++ ABI library.
+static void addSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
+                                 ArgStringList &CmdArgs) {
+  const SanitizerArgs &Sanitize = TC.getSanitizerArgs();
+  const Driver &D = TC.getDriver();
+  if (Sanitize.needsUbsanRt())
+    addUbsanRT(TC, Args, CmdArgs, D.CCCIsCXX(),
+                    Sanitize.needsAsanRt() || Sanitize.needsTsanRt() ||
+                    Sanitize.needsMsanRt() || Sanitize.needsLsanRt());
+  if (Sanitize.needsAsanRt())
+    addAsanRT(TC, Args, CmdArgs, Sanitize.needsSharedAsanRt(), D.CCCIsCXX());
+  if (Sanitize.needsTsanRt())
+    addTsanRT(TC, Args, CmdArgs);
+  if (Sanitize.needsMsanRt())
+    addMsanRT(TC, Args, CmdArgs);
+  if (Sanitize.needsLsanRt())
+    addLsanRT(TC, Args, CmdArgs);
+  if (Sanitize.needsDfsanRt())
+    addDfsanRT(TC, Args, CmdArgs);
 }
 
 static bool shouldUseFramePointerForTarget(const ArgList &Args,
@@ -1957,7 +2304,8 @@
     return Args.MakeArgString(T);
   } else {
     // Use the compilation dir.
-    SmallString<128> T(Args.getLastArgValue(options::OPT_fdebug_compilation_dir));
+    SmallString<128> T(
+        Args.getLastArgValue(options::OPT_fdebug_compilation_dir));
     SmallString<128> F(llvm::sys::path::stem(Inputs[0].getBaseInput()));
     llvm::sys::path::replace_extension(F, "dwo");
     T += F;
@@ -1990,15 +2338,9 @@
   C.addCommand(new Command(JA, T, Exec, StripArgs));
 }
 
-static bool isOptimizationLevelFast(const ArgList &Args) {
-  if (Arg *A = Args.getLastArg(options::OPT_O_Group))
-    if (A->getOption().matches(options::OPT_Ofast))
-      return true;
-  return false;
-}
-
 /// \brief Vectorize at all optimization levels greater than 1 except for -Oz.
-static bool shouldEnableVectorizerAtOLevel(const ArgList &Args) {
+/// 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))
@@ -2014,9 +2356,9 @@
     if (S == "s")
       return true;
 
-    // Don't vectorize -Oz.
+    // Don't vectorize -Oz, unless it's the slp vectorizer.
     if (S == "z")
-      return false;
+      return isSlpVec;
 
     unsigned OptLevel = 0;
     if (S.getAsInteger(10, OptLevel))
@@ -2028,6 +2370,41 @@
   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 std::string getMSCompatibilityVersion(const char *VersionStr) {
+  unsigned Version;
+  if (StringRef(VersionStr).getAsInteger(10, Version))
+    return "0";
+
+  if (Version < 100)
+    return llvm::utostr_32(Version) + ".0";
+
+  if (Version < 10000)
+    return llvm::utostr_32(Version / 100) + "." +
+        llvm::utostr_32(Version % 100);
+
+  unsigned Build = 0, Factor = 1;
+  for ( ; Version > 10000; Version = Version / 10, Factor = Factor * 10)
+    Build = Build + (Version % 10) * Factor;
+  return llvm::utostr_32(Version / 100) + "." +
+      llvm::utostr_32(Version % 100) + "." +
+      llvm::utostr_32(Build);
+}
+
 void Clang::ConstructJob(Compilation &C, const JobAction &JA,
                          const InputInfo &Output,
                          const InputInfoList &Inputs,
@@ -2038,6 +2415,11 @@
   const Driver &D = getToolChain().getDriver();
   ArgStringList CmdArgs;
 
+  bool IsWindowsGNU = getToolChain().getTriple().isWindowsGNUEnvironment();
+  bool IsWindowsCygnus =
+      getToolChain().getTriple().isWindowsCygwinEnvironment();
+  bool IsWindowsMSVC = getToolChain().getTriple().isWindowsMSVCEnvironment();
+
   assert(Inputs.size() == 1 && "Unable to handle multiple inputs.");
 
   // Invoke ourselves in -cc1 mode.
@@ -2050,6 +2432,22 @@
   std::string TripleStr = getToolChain().ComputeEffectiveClangTriple(Args);
   CmdArgs.push_back(Args.MakeArgString(TripleStr));
 
+  const llvm::Triple TT(TripleStr);
+  if (TT.isOSWindows() && (TT.getArch() == llvm::Triple::arm ||
+                           TT.getArch() == llvm::Triple::thumb)) {
+    unsigned Offset = TT.getArch() == llvm::Triple::arm ? 4 : 6;
+    unsigned Version;
+    TT.getArchName().substr(Offset).getAsInteger(10, Version);
+    if (Version < 7)
+      D.Diag(diag::err_target_unsupported_arch) << TT.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;
   
@@ -2084,6 +2482,8 @@
       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) && "Invalid action for clang tool.");
 
@@ -2113,8 +2513,11 @@
     }
   }
 
-  // The make clang go fast button.
-  CmdArgs.push_back("-disable-free");
+  // We normally speed up the clang process a bit by skipping destructors at
+  // exit, but when we're generating diagnostics we can rely on some of the
+  // cleanup.
+  if (!C.isForDiagnostics())
+    CmdArgs.push_back("-disable-free");
 
   // Disable the verification pass in -asserts builds.
 #ifdef NDEBUG
@@ -2144,7 +2547,7 @@
     if (!Args.hasArg(options::OPT__analyzer_no_default_checks)) {
       CmdArgs.push_back("-analyzer-checker=core");
 
-      if (getToolChain().getTriple().getOS() != llvm::Triple::Win32)
+      if (!IsWindowsMSVC)
         CmdArgs.push_back("-analyzer-checker=unix");
 
       if (getToolChain().getTriple().getVendor() == llvm::Triple::Apple)
@@ -2155,8 +2558,9 @@
       if (types::isCXX(Inputs[0].getType()))
         CmdArgs.push_back("-analyzer-checker=cplusplus");
 
-      // Enable the following experimental checkers for testing. 
-      CmdArgs.push_back("-analyzer-checker=security.insecureAPI.UncheckedReturn");
+      // Enable the following experimental checkers for testing.
+      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");      
@@ -2187,6 +2591,54 @@
   bool PIC = PIE || getToolChain().isPICDefault();
   bool IsPICLevelTwo = PIC;
 
+  // Android-specific defaults for PIC/PIE
+  if (getToolChain().getTriple().getEnvironment() == llvm::Triple::Android) {
+    switch (getToolChain().getTriple().getArch()) {
+    case llvm::Triple::arm:
+    case llvm::Triple::armeb:
+    case llvm::Triple::thumb:
+    case llvm::Triple::thumbeb:
+    case llvm::Triple::aarch64:
+    case llvm::Triple::arm64:
+    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 (getToolChain().getTriple().getOS() == llvm::Triple::OpenBSD) {
+    switch (getToolChain().getTriple().getArch()) {
+    case llvm::Triple::mips64:
+    case llvm::Triple::mips64el:
+    case llvm::Triple::sparc:
+    case llvm::Triple::x86:
+    case llvm::Triple::x86_64:
+      IsPICLevelTwo = false; // "-fpie"
+      break;
+
+    case llvm::Triple::ppc:
+    case llvm::Triple::sparcv9:
+      IsPICLevelTwo = true; // "-fPIE"
+      break;
+
+    default:
+      break;
+    }
+  }
+
   // For the PIC and PIE flag options, this logic is different from the
   // legacy logic in very old versions of GCC, as that logic was just
   // a bug no one had ever fixed. This logic is both more rational and
@@ -2227,8 +2679,9 @@
   // Note that these flags are trump-cards. Regardless of the order w.r.t. the
   // PIC or PIE options above, if these show up, PIC is disabled.
   llvm::Triple Triple(TripleStr);
-  if (KernelOrKext &&
-      (!Triple.isiOS() || Triple.isOSVersionLT(6)))
+  if (KernelOrKext && (!Triple.isiOS() || Triple.isOSVersionLT(6) ||
+                       Triple.getArch() == llvm::Triple::arm64 ||
+                       Triple.getArch() == llvm::Triple::aarch64))
     PIC = PIE = false;
   if (Args.hasArg(options::OPT_static))
     PIC = PIE = false;
@@ -2274,6 +2727,13 @@
 
   // LLVM Code Generator Options.
 
+  if (Arg *A = Args.getLastArg(options::OPT_Wframe_larger_than_EQ)) {
+    StringRef v = A->getValue();
+    CmdArgs.push_back("-mllvm");
+    CmdArgs.push_back(Args.MakeArgString("-warn-stack-size=" + v));
+    A->claim();
+  }
+
   if (Arg *A = Args.getLastArg(options::OPT_mregparm_EQ)) {
     CmdArgs.push_back("-mregparm");
     CmdArgs.push_back(A->getValue());
@@ -2306,8 +2766,11 @@
   // 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, true))
+                    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))
@@ -2454,18 +2917,24 @@
                                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 (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 IsVerboseAsmDefault = getToolChain().IsIntegratedAssemblerDefault();
+  bool IsIntegratedAssemblerDefault =
+      getToolChain().IsIntegratedAssemblerDefault();
   if (Args.hasFlag(options::OPT_fverbose_asm, options::OPT_fno_verbose_asm,
-                   IsVerboseAsmDefault) ||
+                   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");
@@ -2493,10 +2962,11 @@
   // -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() &&
-                 !KernelOrKext);
+      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");
@@ -2531,7 +3001,7 @@
   }
 
   // Add the target features
-  getTargetFeatures(D, ETriple, Args, CmdArgs);
+  getTargetFeatures(D, ETriple, Args, CmdArgs, false);
 
   // Add target specific flags.
   switch(getToolChain().getArch()) {
@@ -2539,10 +3009,19 @@
     break;
 
   case llvm::Triple::arm:
+  case llvm::Triple::armeb:
   case llvm::Triple::thumb:
+  case llvm::Triple::thumbeb:
     AddARMTargetArgs(Args, CmdArgs, KernelOrKext);
     break;
 
+  case llvm::Triple::aarch64:
+  case llvm::Triple::aarch64_be:
+  case llvm::Triple::arm64:
+  case llvm::Triple::arm64_be:
+    AddAArch64TargetArgs(Args, CmdArgs);
+    break;
+
   case llvm::Triple::mips:
   case llvm::Triple::mipsel:
   case llvm::Triple::mips64:
@@ -2551,6 +3030,7 @@
     break;
 
   case llvm::Triple::sparc:
+  case llvm::Triple::sparcv9:
     AddSparcTargetArgs(Args, CmdArgs);
     break;
 
@@ -2608,13 +3088,20 @@
                       D.CCLogDiagnosticsFilename : "-");
   }
 
-  // Use the last option from "-g" group. "-gline-tables-only"
-  // is preserved, all other debug options are substituted with "-g".
+  // Use the last option from "-g" group. "-gline-tables-only" and "-gdwarf-x"
+  // are preserved, all other debug options are substituted with "-g".
   Args.ClaimAllArgs(options::OPT_g_Group);
   if (Arg *A = Args.getLastArg(options::OPT_g_Group)) {
-    if (A->getOption().matches(options::OPT_gline_tables_only))
+    if (A->getOption().matches(options::OPT_gline_tables_only)) {
+      // FIXME: we should support specifying dwarf version with
+      // -gline-tables-only.
       CmdArgs.push_back("-gline-tables-only");
-    else if (A->getOption().matches(options::OPT_gdwarf_2))
+      // Default is dwarf-2 for Darwin, OpenBSD and FreeBSD.
+      const llvm::Triple &Triple = getToolChain().getTriple();
+      if (Triple.isOSDarwin() || Triple.getOS() == llvm::Triple::OpenBSD ||
+          Triple.getOS() == llvm::Triple::FreeBSD)
+        CmdArgs.push_back("-gdwarf-2");
+    } else if (A->getOption().matches(options::OPT_gdwarf_2))
       CmdArgs.push_back("-gdwarf-2");
     else if (A->getOption().matches(options::OPT_gdwarf_3))
       CmdArgs.push_back("-gdwarf-3");
@@ -2622,8 +3109,10 @@
       CmdArgs.push_back("-gdwarf-4");
     else if (!A->getOption().matches(options::OPT_g0) &&
              !A->getOption().matches(options::OPT_ggdb0)) {
-      // Default is dwarf-2 for darwin.
-      if (getToolChain().getTriple().isOSDarwin())
+      // Default is dwarf-2 for Darwin, OpenBSD and FreeBSD.
+      const llvm::Triple &Triple = getToolChain().getTriple();
+      if (Triple.isOSDarwin() || Triple.getOS() == llvm::Triple::OpenBSD ||
+          Triple.getOS() == llvm::Triple::FreeBSD)
         CmdArgs.push_back("-gdwarf-2");
       else
         CmdArgs.push_back("-g");
@@ -2632,7 +3121,8 @@
 
   // We ignore flags -gstrict-dwarf and -grecord-gcc-switches for now.
   Args.ClaimAllArgs(options::OPT_g_flags_Group);
-  if (Args.hasArg(options::OPT_gcolumn_info))
+  if (Args.hasFlag(options::OPT_gcolumn_info, options::OPT_gno_column_info,
+                   /*Default*/ true))
     CmdArgs.push_back("-dwarf-column-info");
 
   // FIXME: Move backend command line options to the module.
@@ -2652,13 +3142,44 @@
     CmdArgs.push_back("-generate-gnu-dwarf-pub-sections");
   }
 
-  Args.AddAllArgs(CmdArgs, options::OPT_fdebug_types_section);
+  // -gdwarf-aranges turns on the emission of the aranges section in the
+  // backend.
+  if (Args.hasArg(options::OPT_gdwarf_aranges)) {
+    CmdArgs.push_back("-backend-option");
+    CmdArgs.push_back("-generate-arange-section");
+  }
 
-  Args.AddAllArgs(CmdArgs, options::OPT_ffunction_sections);
-  Args.AddAllArgs(CmdArgs, options::OPT_fdata_sections);
+  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");
+  }
+
+  if (Args.hasFlag(options::OPT_ffunction_sections,
+                   options::OPT_fno_function_sections, false)) {
+    CmdArgs.push_back("-ffunction-sections");
+  }
+
+  if (Args.hasFlag(options::OPT_fdata_sections,
+                   options::OPT_fno_data_sections, false)) {
+    CmdArgs.push_back("-fdata-sections");
+  }
 
   Args.AddAllArgs(CmdArgs, options::OPT_finstrument_functions);
 
+  if (Args.hasArg(options::OPT_fprofile_instr_generate) &&
+      (Args.hasArg(options::OPT_fprofile_instr_use) ||
+       Args.hasArg(options::OPT_fprofile_instr_use_EQ)))
+    D.Diag(diag::err_drv_argument_not_allowed_with)
+      << "-fprofile-instr-generate" << "-fprofile-instr-use";
+
+  Args.AddAllArgs(CmdArgs, options::OPT_fprofile_instr_generate);
+
+  if (Arg *A = Args.getLastArg(options::OPT_fprofile_instr_use_EQ))
+    A->render(Args, CmdArgs);
+  else if (Args.hasArg(options::OPT_fprofile_instr_use))
+    CmdArgs.push_back("-fprofile-instr-use=pgo-data");
+
   if (Args.hasArg(options::OPT_ftest_coverage) ||
       Args.hasArg(options::OPT_coverage))
     CmdArgs.push_back("-femit-coverage-notes");
@@ -2764,7 +3285,8 @@
     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_white_list_dir_path);
+    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
@@ -2790,10 +3312,18 @@
     }
   }
 
+  // Warn about ignored options to clang.
+  for (arg_iterator it = Args.filtered_begin(
+       options::OPT_clang_ignored_gcc_optimization_f_Group),
+       ie = Args.filtered_end(); it != ie; ++it) {
+    D.Diag(diag::warn_ignored_gcc_optimization) << (*it)->getAsString(Args);
+  }
+
   // Don't warn about unused -flto.  This can happen when we're preprocessing or
   // precompiling.
   Args.ClaimAllArgs(options::OPT_flto);
 
+  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");
@@ -2828,7 +3358,7 @@
     if (!types::isCXX(InputType))
       Args.AddAllArgsTranslated(CmdArgs, options::OPT_std_default_EQ,
                                 "-std=", /*Joined=*/true);
-    else if (getToolChain().getTriple().getOS() == llvm::Triple::Win32)
+    else if (IsWindowsMSVC)
       CmdArgs.push_back("-std=c++11");
 
     Args.AddLastArg(CmdArgs, options::OPT_trigraphs);
@@ -2844,9 +3374,13 @@
   // 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)) {
-    DiagnosticsEngine::Level DiagLevel = D.getDiags().getDiagnosticLevel(
-        diag::warn_deprecated_string_literal_conversion_c, SourceLocation());
-    if (DiagLevel > DiagnosticsEngine::Ignored)
+    // 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");
   }
 
@@ -2867,9 +3401,6 @@
       CmdArgs.push_back("-fno-gnu-keywords");
   }
 
-  if (ShouldDisableCFI(Args, getToolChain()))
-    CmdArgs.push_back("-fno-dwarf2-cfi-asm");
-
   if (ShouldDisableDwarfDirectory(Args, getToolChain()))
     CmdArgs.push_back("-fno-dwarf-directory-asm");
 
@@ -2987,8 +3518,8 @@
   // 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_flimit_debug_info);
-  Args.AddLastArg(CmdArgs, options::OPT_fno_limit_debug_info);
+  Args.AddLastArg(CmdArgs, options::OPT_fstandalone_debug);
+  Args.AddLastArg(CmdArgs, options::OPT_fno_standalone_debug);
   Args.AddLastArg(CmdArgs, options::OPT_fno_operator_names);
   // AltiVec language extensions aren't relevant for assembling.
   if (!isa<PreprocessJobAction>(JA) || 
@@ -3005,8 +3536,7 @@
                     true))
     CmdArgs.push_back("-fno-sanitize-recover");
 
-  if (Args.hasArg(options::OPT_fcatch_undefined_behavior) ||
-      Args.hasFlag(options::OPT_fsanitize_undefined_trap_on_error,
+  if (Args.hasFlag(options::OPT_fsanitize_undefined_trap_on_error,
                    options::OPT_fno_sanitize_undefined_trap_on_error, false))
     CmdArgs.push_back("-fsanitize-undefined-trap-on-error");
 
@@ -3029,10 +3559,6 @@
   if (Args.getLastArg(options::OPT_fapple_kext))
     CmdArgs.push_back("-fapple-kext");
 
-  if (Args.hasFlag(options::OPT_frewrite_includes,
-                   options::OPT_fno_rewrite_includes, false))
-    CmdArgs.push_back("-frewrite-includes");
-
   Args.AddLastArg(CmdArgs, options::OPT_fobjc_sender_dependent_dispatch);
   Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_print_source_range_info);
   Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_parseable_fixits);
@@ -3074,11 +3600,15 @@
   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 = 1;
+    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 = 2;
+      StackProtectorLevel = LangOptions::SSPReq;
   } else {
     StackProtectorLevel =
       getToolChain().GetDefaultStackProtectorLevel(KernelOrKext);
@@ -3123,10 +3653,22 @@
                                  options::OPT_munaligned_access)) {
       if (A->getOption().matches(options::OPT_mno_unaligned_access)) {
         CmdArgs.push_back("-backend-option");
-        CmdArgs.push_back("-arm-strict-align");
+        if (getToolChain().getTriple().getArch() == llvm::Triple::aarch64 ||
+            getToolChain().getTriple().getArch() == llvm::Triple::aarch64_be ||
+            getToolChain().getTriple().getArch() == llvm::Triple::arm64 ||
+            getToolChain().getTriple().getArch() == llvm::Triple::arm64_be)
+          CmdArgs.push_back("-aarch64-strict-align");
+        else
+          CmdArgs.push_back("-arm-strict-align");
       } else {
         CmdArgs.push_back("-backend-option");
-        CmdArgs.push_back("-arm-no-strict-align");
+        if (getToolChain().getTriple().getArch() == llvm::Triple::aarch64 ||
+            getToolChain().getTriple().getArch() == llvm::Triple::aarch64_be ||
+            getToolChain().getTriple().getArch() == llvm::Triple::arm64 ||
+            getToolChain().getTriple().getArch() == llvm::Triple::arm64_be)
+          CmdArgs.push_back("-aarch64-no-strict-align");
+        else
+          CmdArgs.push_back("-arm-no-strict-align");
       }
     }
   }
@@ -3140,6 +3682,22 @@
       CmdArgs.push_back("-backend-option");
       CmdArgs.push_back("-arm-no-restrict-it");
     }
+  } else if (TT.isOSWindows() && (TT.getArch() == llvm::Triple::arm ||
+                                  TT.getArch() == llvm::Triple::thumb)) {
+    // Windows on ARM expects restricted IT blocks
+    CmdArgs.push_back("-backend-option");
+    CmdArgs.push_back("-arm-restrict-it");
+  }
+
+  if (TT.getArch() == llvm::Triple::arm ||
+      TT.getArch() == llvm::Triple::thumb) {
+    if (Arg *A = Args.getLastArg(options::OPT_mlong_calls,
+                                 options::OPT_mno_long_calls)) {
+      if (A->getOption().matches(options::OPT_mlong_calls)) {
+        CmdArgs.push_back("-backend-option");
+        CmdArgs.push_back("-arm-long-calls");
+      }
+    }
   }
 
   // Forward -f options with positive and negative forms; we translate
@@ -3209,44 +3767,78 @@
     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");
+  }
+
   // -fmodule-name specifies the module that is currently being built (or
   // used for header checking by -fmodule-maps).
-  if (Arg *A = Args.getLastArg(options::OPT_fmodule_name)) {
-    A->claim();
+  if (Arg *A = Args.getLastArg(options::OPT_fmodule_name))
     A->render(Args, CmdArgs);
-  }
 
   // -fmodule-map-file can be used to specify a file containing module
   // definitions.
-  if (Arg *A = Args.getLastArg(options::OPT_fmodule_map_file)) {
-    A->claim();
+  if (Arg *A = Args.getLastArg(options::OPT_fmodule_map_file))
     A->render(Args, CmdArgs);
+
+  // -fmodule-cache-path specifies where our module files should be written.
+  SmallString<128> ModuleCachePath;
+  if (Arg *A = Args.getLastArg(options::OPT_fmodules_cache_path))
+    ModuleCachePath = A->getValue();
+  if (HaveModules) {
+    if (C.isForDiagnostics()) {
+      // When generating crash reports, we want to emit the modules along with
+      // the reproduction sources, so we ignore any provided module path.
+      ModuleCachePath = Output.getFilename();
+      llvm::sys::path::replace_extension(ModuleCachePath, ".cache");
+      llvm::sys::path::append(ModuleCachePath, "modules");
+    } else if (ModuleCachePath.empty()) {
+      // No module path was provided: use the default.
+      llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/false,
+                                             ModuleCachePath);
+      llvm::sys::path::append(ModuleCachePath, "org.llvm.clang");
+      llvm::sys::path::append(ModuleCachePath, "ModuleCache");
+    }
+    const char Arg[] = "-fmodules-cache-path=";
+    ModuleCachePath.insert(ModuleCachePath.begin(), Arg, Arg + strlen(Arg));
+    CmdArgs.push_back(Args.MakeArgString(ModuleCachePath));
   }
 
-  // If a module path was provided, pass it along. Otherwise, use a temporary
-  // directory.
-  if (Arg *A = Args.getLastArg(options::OPT_fmodules_cache_path)) {
-    A->claim();
-    if (HaveModules) {
-      A->render(Args, CmdArgs);
-    }
-  } else if (HaveModules) {
-    SmallString<128> DefaultModuleCache;
-    llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/false,
-                                           DefaultModuleCache);
-    llvm::sys::path::append(DefaultModuleCache, "org.llvm.clang");
-    llvm::sys::path::append(DefaultModuleCache, "ModuleCache");
-    const char Arg[] = "-fmodules-cache-path=";
-    DefaultModuleCache.insert(DefaultModuleCache.begin(),
-                              Arg, Arg + strlen(Arg));
-    CmdArgs.push_back(Args.MakeArgString(DefaultModuleCache));
+  // When building modules and generating crashdumps, we need to dump a module
+  // dependency VFS alongside the output.
+  if (HaveModules && C.isForDiagnostics()) {
+    SmallString<128> VFSDir(Output.getFilename());
+    llvm::sys::path::replace_extension(VFSDir, ".cache");
+    llvm::sys::path::append(VFSDir, "vfs");
+    CmdArgs.push_back("-module-dependency-dir");
+    CmdArgs.push_back(Args.MakeArgString(VFSDir));
   }
 
+  if (Arg *A = Args.getLastArg(options::OPT_fmodules_user_build_path))
+    if (HaveModules)
+      A->render(Args, CmdArgs);
+
   // Pass through all -fmodules-ignore-macro arguments.
   Args.AddAllArgs(CmdArgs, options::OPT_fmodules_ignore_macro);
   Args.AddLastArg(CmdArgs, options::OPT_fmodules_prune_interval);
   Args.AddLastArg(CmdArgs, options::OPT_fmodules_prune_after);
 
+  Args.AddLastArg(CmdArgs, options::OPT_fbuild_session_timestamp);
+
+  if (Args.getLastArg(options::OPT_fmodules_validate_once_per_build_session)) {
+    if (!Args.getLastArg(options::OPT_fbuild_session_timestamp))
+      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);
+
   // -faccess-control is default.
   if (Args.hasFlag(options::OPT_fno_access_control,
                    options::OPT_faccess_control,
@@ -3293,40 +3885,51 @@
     CmdArgs.push_back("-fno-threadsafe-statics");
 
   // -fuse-cxa-atexit is default.
-  if (!Args.hasFlag(
-           options::OPT_fuse_cxa_atexit, options::OPT_fno_use_cxa_atexit,
-           getToolChain().getTriple().getOS() != llvm::Triple::Cygwin &&
-               getToolChain().getTriple().getOS() != llvm::Triple::MinGW32 &&
-               getToolChain().getArch() != llvm::Triple::hexagon &&
-               getToolChain().getArch() != llvm::Triple::xcore) ||
+  if (!Args.hasFlag(options::OPT_fuse_cxa_atexit,
+                    options::OPT_fno_use_cxa_atexit,
+                    !IsWindowsCygnus && !IsWindowsGNU &&
+                    getToolChain().getArch() != llvm::Triple::hexagon &&
+                    getToolChain().getArch() != llvm::Triple::xcore) ||
       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,
-                   getToolChain().getTriple().getOS() == llvm::Triple::Win32))
+                   IsWindowsMSVC))
     CmdArgs.push_back("-fms-extensions");
 
   // -fms-compatibility=0 is default.
   if (Args.hasFlag(options::OPT_fms_compatibility, 
                    options::OPT_fno_ms_compatibility,
-                   (getToolChain().getTriple().getOS() == llvm::Triple::Win32 &&
-                    Args.hasFlag(options::OPT_fms_extensions, 
-                                 options::OPT_fno_ms_extensions,
-                                 true))))
+                   (IsWindowsMSVC && Args.hasFlag(options::OPT_fms_extensions,
+                                                  options::OPT_fno_ms_extensions,
+                                                  true))))
     CmdArgs.push_back("-fms-compatibility");
 
-  // -fmsc-version=1700 is default.
+  // -fms-compatibility-version=17.00 is default.
   if (Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
-                   getToolChain().getTriple().getOS() == llvm::Triple::Win32) ||
-      Args.hasArg(options::OPT_fmsc_version)) {
-    StringRef msc_ver = Args.getLastArgValue(options::OPT_fmsc_version);
-    if (msc_ver.empty())
-      CmdArgs.push_back("-fmsc-version=1700");
-    else
-      CmdArgs.push_back(Args.MakeArgString("-fmsc-version=" + msc_ver));
-  }
+                   IsWindowsMSVC) || Args.hasArg(options::OPT_fmsc_version) ||
+      Args.hasArg(options::OPT_fms_compatibility_version)) {
+    const Arg *MSCVersion = Args.getLastArg(options::OPT_fmsc_version);
+    const Arg *MSCompatibilityVersion =
+      Args.getLastArg(options::OPT_fms_compatibility_version);
 
+    if (MSCVersion && MSCompatibilityVersion)
+      D.Diag(diag::err_drv_argument_not_allowed_with)
+          << MSCVersion->getAsString(Args)
+          << MSCompatibilityVersion->getAsString(Args);
+
+    std::string Ver;
+    if (MSCompatibilityVersion)
+      Ver = Args.getLastArgValue(options::OPT_fms_compatibility_version);
+    else if (MSCVersion)
+      Ver = getMSCompatibilityVersion(MSCVersion->getValue());
+
+    if (Ver.empty())
+      CmdArgs.push_back("-fms-compatibility-version=17.00");
+    else
+      CmdArgs.push_back(Args.MakeArgString("-fms-compatibility-version=" + Ver));
+  }
 
   // -fno-borland-extensions is default.
   if (Args.hasFlag(options::OPT_fborland_extensions,
@@ -3336,8 +3939,7 @@
   // -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,
-                   getToolChain().getTriple().getOS() == llvm::Triple::Win32))
+                   options::OPT_fno_delayed_template_parsing, IsWindowsMSVC))
     CmdArgs.push_back("-fdelayed-template-parsing");
 
   // -fgnu-keywords default varies depending on language; only pass if
@@ -3360,9 +3962,10 @@
   ObjCRuntime objcRuntime = AddObjCRuntimeArgs(Args, CmdArgs, rewriteKind);
 
   // -fobjc-dispatch-method is only relevant with the nonfragile-abi, and
-  // legacy is the default. Next runtime is always legacy dispatch and
-  // -fno-objc-legacy-dispatch gets ignored silently.
-  if (objcRuntime.isNonFragile() && !objcRuntime.isNeXTFamily()) {
+  // legacy is the default. Except for deployment taget 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(
@@ -3438,9 +4041,10 @@
     }
   }
 
-  // Add exception args.
-  addExceptionArgs(Args, InputType, getToolChain().getTriple(),
-                   KernelOrKext, objcRuntime, CmdArgs);
+  // Handle GCC-style exception args.
+  if (!C.getDriver().IsCLMode())
+    addExceptionArgs(Args, InputType, getToolChain().getTriple(), KernelOrKext,
+                     objcRuntime, CmdArgs);
 
   if (getToolChain().UseSjLjExceptions())
     CmdArgs.push_back("-fsjlj-exceptions");
@@ -3460,7 +4064,8 @@
 
   // -fshort-wchar default varies depending on platform; only
   // pass if specified.
-  if (Arg *A = Args.getLastArg(options::OPT_fshort_wchar))
+  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.
@@ -3503,6 +4108,14 @@
     D.Diag(diag::err_drv_clang_unsupported)
       << Args.getLastArg(options::OPT_fno_for_scope)->getAsString(Args);
 
+  // -finput_charset=UTF-8 is default. Reject others
+  if (Arg *inputCharset = Args.getLastArg(
+          options::OPT_finput_charset_EQ)) {
+      StringRef value = inputCharset->getValue();
+      if (value != "UTF-8")
+          D.Diag(diag::err_drv_invalid_value) << inputCharset->getAsString(Args) << value;
+  }
+
   // -fcaret-diagnostics is default.
   if (!Args.hasFlag(options::OPT_fcaret_diagnostics,
                     options::OPT_fno_caret_diagnostics, true))
@@ -3545,9 +4158,8 @@
   // Support both clang's -f[no-]color-diagnostics and gcc's
   // -f[no-]diagnostics-colors[=never|always|auto].
   enum { Colors_On, Colors_Off, Colors_Auto } ShowColors = Colors_Auto;
-  for (ArgList::const_iterator it = Args.begin(), ie = Args.end();
-       it != ie; ++it) {
-    const Option &O = (*it)->getOption();
+  for (const auto &Arg : Args) {
+    const Option &O = Arg->getOption();
     if (!O.matches(options::OPT_fcolor_diagnostics) &&
         !O.matches(options::OPT_fdiagnostics_color) &&
         !O.matches(options::OPT_fno_color_diagnostics) &&
@@ -3555,7 +4167,7 @@
         !O.matches(options::OPT_fdiagnostics_color_EQ))
       continue;
 
-    (*it)->claim();
+    Arg->claim();
     if (O.matches(options::OPT_fcolor_diagnostics) ||
         O.matches(options::OPT_fdiagnostics_color)) {
       ShowColors = Colors_On;
@@ -3564,7 +4176,7 @@
       ShowColors = Colors_Off;
     } else {
       assert(O.matches(options::OPT_fdiagnostics_color_EQ));
-      StringRef value((*it)->getValue());
+      StringRef value(Arg->getValue());
       if (value == "always")
         ShowColors = Colors_On;
       else if (value == "never")
@@ -3605,16 +4217,19 @@
   // 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);
+  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 default.
-  if (Args.hasFlag(options::OPT_fslp_vectorize,
-                   options::OPT_fno_slp_vectorize, true))
+  // -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.
@@ -3668,6 +4283,15 @@
   }
 #endif
 
+  // Enable rewrite includes if the user's asked for it or if we're generating
+  // diagnostics.
+  // TODO: Once -module-dependency-dir works with -frewrite-includes it'd be
+  // nice to enable this when doing a crashdump for modules as well.
+  if (Args.hasFlag(options::OPT_frewrite_includes,
+                   options::OPT_fno_rewrite_includes, false) ||
+      (C.isForDiagnostics() && !HaveModules))
+    CmdArgs.push_back("-frewrite-includes");
+
   // Only allow -traditional or -traditional-cpp outside in preprocessing modes.
   if (Arg *A = Args.getLastArg(options::OPT_traditional,
                                options::OPT_traditional_cpp)) {
@@ -3718,14 +4342,9 @@
     assert(Output.isNothing() && "Invalid output.");
   }
 
-  for (InputInfoList::const_iterator
-         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
-    const InputInfo &II = *it;
-    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(II.getType()));
+  for (const auto &II : Inputs) {
+    addDashXForInput(Args, II, CmdArgs);
+
     if (II.isFilename())
       CmdArgs.push_back(II.getFilename());
     else
@@ -3740,9 +4359,8 @@
   // analysis.
   if (getToolChain().UseDwarfDebugFlags()) {
     ArgStringList OriginalArgs;
-    for (ArgList::const_iterator it = Args.begin(),
-           ie = Args.end(); it != ie; ++it)
-      (*it)->render(Args, OriginalArgs);
+    for (const auto &Arg : Args)
+      Arg->render(Args, OriginalArgs);
 
     SmallString<256> Flags;
     Flags += Exec;
@@ -3767,10 +4385,11 @@
   }
 
   // Finally add the compile command to the compilation.
-  if (Args.hasArg(options::OPT__SLASH_fallback)) {
-    tools::visualstudio::Compile CL(getToolChain());
-    Command *CLCommand = CL.GetCommand(C, JA, Output, Inputs, Args,
-                                       LinkingOutput);
+  if (Args.hasArg(options::OPT__SLASH_fallback) &&
+      Output.getType() == types::TY_Object &&
+      (InputType == types::TY_C || InputType == types::TY_CXX)) {
+    Command *CLCommand = getCLFallback()->GetCommand(C, JA, Output, Inputs,
+                                                     Args, LinkingOutput);
     C.addCommand(new FallbackCommand(JA, *this, Exec, CmdArgs, CLCommand));
   } else {
     C.addCommand(new Command(JA, *this, Exec, CmdArgs));
@@ -3929,6 +4548,45 @@
   return runtime;
 }
 
+static bool maybeConsumeDash(const std::string &EH, size_t &I) {
+  bool HaveDash = (I + 1 < EH.size() && EH[I + 1] == '-');
+  I += HaveDash;
+  return !HaveDash;
+}
+
+struct EHFlags {
+  EHFlags() : Synch(false), Asynch(false), NoExceptC(false) {}
+  bool Synch;
+  bool Asynch;
+  bool NoExceptC;
+};
+
+/// /EH controls whether to run destructor cleanups when exceptions are
+/// thrown.  There are three modifiers:
+/// - s: Cleanup after "synchronous" exceptions, aka C++ exceptions.
+/// - a: Cleanup after "asynchronous" exceptions, aka structured exceptions.
+///      The 'a' modifier is unimplemented and fundamentally hard in LLVM IR.
+/// - c: Assume that extern "C" functions are implicitly noexcept.  This
+///      modifier is an optimization, so we ignore it for now.
+/// The default is /EHs-c-, meaning cleanups are disabled.
+static EHFlags parseClangCLEHFlags(const Driver &D, const ArgList &Args) {
+  EHFlags EH;
+  std::vector<std::string> EHArgs = Args.getAllArgValues(options::OPT__SLASH_EH);
+  for (auto EHVal : EHArgs) {
+    for (size_t I = 0, E = EHVal.size(); I != E; ++I) {
+      switch (EHVal[I]) {
+      case 'a': EH.Asynch = maybeConsumeDash(EHVal, I); continue;
+      case 'c': EH.NoExceptC = maybeConsumeDash(EHVal, I); continue;
+      case 's': EH.Synch = maybeConsumeDash(EHVal, I); continue;
+      default: break;
+      }
+      D.Diag(clang::diag::err_drv_invalid_value) << "/EH" << EHVal;
+      break;
+    }
+  }
+  return EH;
+}
+
 void Clang::AddClangCLArgs(const ArgList &Args, ArgStringList &CmdArgs) const {
   unsigned RTOptionID = options::OPT__SLASH_MT;
 
@@ -3974,11 +4632,58 @@
   // implemented in clang.
   CmdArgs.push_back("--dependent-lib=oldnames");
 
-  // FIXME: Make this default for the win32 triple.
-  CmdArgs.push_back("-cxx-abi");
-  CmdArgs.push_back("microsoft");
+  // 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);
 
-  if (Arg *A = Args.getLastArg(options::OPT_show_includes))
+  // This controls whether or not we emit RTTI data for polymorphic types.
+  if (Args.hasFlag(options::OPT__SLASH_GR_, options::OPT__SLASH_GR,
+                   /*default=*/false))
+    CmdArgs.push_back("-fno-rtti-data");
+
+  const Driver &D = getToolChain().getDriver();
+  EHFlags EH = parseClangCLEHFlags(D, Args);
+  // FIXME: Do something with NoExceptC.
+  if (EH.Synch || EH.Asynch) {
+    CmdArgs.push_back("-fexceptions");
+    CmdArgs.push_back("-fcxx-exceptions");
+  }
+
+  // /EP should expand to -E -P.
+  if (Args.hasArg(options::OPT__SLASH_EP)) {
+    CmdArgs.push_back("-E");
+    CmdArgs.push_back("-P");
+  }
+
+  Arg *MostGeneralArg = Args.getLastArg(options::OPT__SLASH_vmg);
+  Arg *BestCaseArg = Args.getLastArg(options::OPT__SLASH_vmb);
+  if (MostGeneralArg && BestCaseArg)
+    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 (Arg *A = Args.getLastArg(options::OPT_vtordisp_mode_EQ))
     A->render(Args, CmdArgs);
 
   if (!Args.hasArg(options::OPT_fdiagnostics_format_EQ)) {
@@ -3990,6 +4695,12 @@
   }
 }
 
+visualstudio::Compile *Clang::getCLFallback() const {
+  if (!CLFallback)
+    CLFallback.reset(new visualstudio::Compile(getToolChain()));
+  return CLFallback.get();
+}
+
 void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
                            const InputInfo &Output,
                            const InputInfoList &Inputs,
@@ -4036,7 +4747,7 @@
 
   // Add the target features
   const Driver &D = getToolChain().getDriver();
-  getTargetFeatures(D, Triple, Args, CmdArgs);
+  getTargetFeatures(D, Triple, Args, CmdArgs, true);
 
   // Ignore explicit -force_cpusubtype_ALL option.
   (void) Args.hasArg(options::OPT_force__cpusubtype__ALL);
@@ -4057,6 +4768,13 @@
       if (!A->getOption().matches(options::OPT_g0))
         CmdArgs.push_back("-g");
 
+    if (Args.hasArg(options::OPT_gdwarf_2))
+      CmdArgs.push_back("-gdwarf-2");
+    if (Args.hasArg(options::OPT_gdwarf_3))
+      CmdArgs.push_back("-gdwarf-3");
+    if (Args.hasArg(options::OPT_gdwarf_4))
+      CmdArgs.push_back("-gdwarf-4");
+
     // Add the -fdebug-compilation-dir flag if needed.
     addDebugCompDirArg(Args, CmdArgs);
 
@@ -4070,9 +4788,8 @@
   // analysis.
   if (getToolChain().UseDwarfDebugFlags()) {
     ArgStringList OriginalArgs;
-    for (ArgList::const_iterator it = Args.begin(),
-           ie = Args.end(); it != ie; ++it)
-      (*it)->render(Args, OriginalArgs);
+    for (const auto &Arg : Args)
+      Arg->render(Args, OriginalArgs);
 
     SmallString<256> Flags;
     const char *Exec = getToolChain().getDriver().getClangProgramPath();
@@ -4087,6 +4804,16 @@
 
   // FIXME: Add -static support, once we have it.
 
+  // 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
+  for (arg_iterator it = Args.filtered_begin(options::OPT_W_Group),
+                    ie = Args.filtered_end();
+       it != ie; ++it)
+    (*it)->claim();
+
   CollectArgsForIntegratedAssembler(C, Args, CmdArgs,
                                     getToolChain().getDriver());
 
@@ -4119,9 +4846,7 @@
   const Driver &D = getToolChain().getDriver();
   ArgStringList CmdArgs;
 
-  for (ArgList::const_iterator
-         it = Args.begin(), ie = Args.end(); it != ie; ++it) {
-    Arg *A = *it;
+  for (const auto &A : Args) {
     if (forwardToGCC(A->getOption())) {
       // Don't forward any -g arguments to assembly steps.
       if (isa<AssembleJobAction>(JA) &&
@@ -4190,10 +4915,7 @@
   //
   // FIXME: For the linker case specifically, can we safely convert
   // inputs into '-Wl,' options?
-  for (InputInfoList::const_iterator
-         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
-    const InputInfo &II = *it;
-
+  for (const auto &II : Inputs) {
     // Don't try to pass LLVM or AST inputs to a generic gcc.
     if (II.getType() == types::TY_LLVM_IR || II.getType() == types::TY_LTO_IR ||
         II.getType() == types::TY_LLVM_BC || II.getType() == types::TY_LTO_BC)
@@ -4246,11 +4968,6 @@
   CmdArgs.push_back("-E");
 }
 
-void gcc::Precompile::RenderExtraToolArgs(const JobAction &JA,
-                                          ArgStringList &CmdArgs) const {
-  // The type is good enough.
-}
-
 void gcc::Compile::RenderExtraToolArgs(const JobAction &JA,
                                        ArgStringList &CmdArgs) const {
   const Driver &D = getToolChain().getDriver();
@@ -4268,11 +4985,6 @@
   }
 }
 
-void gcc::Assemble::RenderExtraToolArgs(const JobAction &JA,
-                                        ArgStringList &CmdArgs) const {
-  CmdArgs.push_back("-c");
-}
-
 void gcc::Link::RenderExtraToolArgs(const JobAction &JA,
                                     ArgStringList &CmdArgs) const {
   // The types are (hopefully) good enough.
@@ -4322,10 +5034,7 @@
   //
   // FIXME: For the linker case specifically, can we safely convert
   // inputs into '-Wl,' options?
-  for (InputInfoList::const_iterator
-         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
-    const InputInfo &II = *it;
-
+  for (const auto &II : Inputs) {
     // Don't try to pass LLVM or AST inputs to a generic gcc.
     if (II.getType() == types::TY_LLVM_IR || II.getType() == types::TY_LTO_IR ||
         II.getType() == types::TY_LLVM_BC || II.getType() == types::TY_LTO_BC)
@@ -4346,11 +5055,10 @@
   }
 
   const char *GCCName = "hexagon-as";
-  const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath(GCCName));
+  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath(GCCName));
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
-
 }
+
 void hexagon::Link::RenderExtraToolArgs(const JobAction &JA,
                                     ArgStringList &CmdArgs) const {
   // The types are (hopefully) good enough.
@@ -4392,10 +5100,8 @@
   //----------------------------------------------------------------------------
   //
   //----------------------------------------------------------------------------
-  for (std::vector<std::string>::const_iterator i = ToolChain.ExtraOpts.begin(),
-         e = ToolChain.ExtraOpts.end();
-       i != e; ++i)
-    CmdArgs.push_back(i->c_str());
+  for (const auto &Opt : ToolChain.ExtraOpts)
+    CmdArgs.push_back(Opt.c_str());
 
   std::string MarchString = toolchains::Hexagon_TC::GetTargetCPU(Args);
   CmdArgs.push_back(Args.MakeArgString("-m" + MarchString));
@@ -4471,12 +5177,8 @@
   // Library Search Paths
   //----------------------------------------------------------------------------
   const ToolChain::path_list &LibPaths = ToolChain.getFilePaths();
-  for (ToolChain::path_list::const_iterator
-         i = LibPaths.begin(),
-         e = LibPaths.end();
-       i != e;
-       ++i)
-    CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + *i));
+  for (const auto &LibPath : LibPaths)
+    CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + LibPath));
 
   //----------------------------------------------------------------------------
   //
@@ -4524,7 +5226,116 @@
 }
 // Hexagon tools end.
 
-llvm::Triple::ArchType darwin::getArchTypeForDarwinArchName(StringRef Str) {
+/// Get the (LLVM) name of the minimum ARM CPU for the arch we are targeting.
+const char *arm::getARMCPUForMArch(const ArgList &Args,
+                                   const llvm::Triple &Triple) {
+  StringRef MArch;
+  if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
+    // Otherwise, if we have -march= choose the base CPU for that arch.
+    MArch = A->getValue();
+  } else {
+    // Otherwise, use the Arch from the triple.
+    MArch = Triple.getArchName();
+  }
+
+  // Handle -march=native.
+  if (MArch == "native") {
+    std::string CPU = llvm::sys::getHostCPUName();
+    if (CPU != "generic") {
+      // Translate the native cpu into the architecture. The switch below will
+      // then chose the minimum cpu for that arch.
+      MArch = std::string("arm") + arm::getLLVMArchSuffixForARM(CPU);
+    }
+  }
+
+  return Triple.getARMCPUForArch(MArch);
+}
+
+/// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targeting.
+StringRef arm::getARMTargetCPU(const ArgList &Args,
+                               const llvm::Triple &Triple) {
+  // FIXME: Warn on inconsistent use of -mcpu and -march.
+  // If we have -mcpu=, use that.
+  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
+    StringRef MCPU = A->getValue();
+    // Handle -mcpu=native.
+    if (MCPU == "native")
+      return llvm::sys::getHostCPUName();
+    else
+      return MCPU;
+  }
+
+  return getARMCPUForMArch(Args, Triple);
+}
+
+/// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular
+/// CPU.
+//
+// FIXME: This is redundant with -mcpu, why does LLVM use this.
+// FIXME: tblgen this, or kill it!
+const char *arm::getLLVMArchSuffixForARM(StringRef CPU) {
+  return llvm::StringSwitch<const char *>(CPU)
+    .Case("strongarm", "v4")
+    .Cases("arm7tdmi", "arm7tdmi-s", "arm710t", "v4t")
+    .Cases("arm720t", "arm9", "arm9tdmi", "v4t")
+    .Cases("arm920", "arm920t", "arm922t", "v4t")
+    .Cases("arm940t", "ep9312","v4t")
+    .Cases("arm10tdmi",  "arm1020t", "v5")
+    .Cases("arm9e",  "arm926ej-s",  "arm946e-s", "v5e")
+    .Cases("arm966e-s",  "arm968e-s",  "arm10e", "v5e")
+    .Cases("arm1020e",  "arm1022e",  "xscale", "iwmmxt", "v5e")
+    .Cases("arm1136j-s",  "arm1136jf-s",  "arm1176jz-s", "v6")
+    .Cases("arm1176jzf-s",  "mpcorenovfp",  "mpcore", "v6")
+    .Cases("arm1156t2-s",  "arm1156t2f-s", "v6t2")
+    .Cases("cortex-a5", "cortex-a7", "cortex-a8", "cortex-a9-mp", "v7")
+    .Cases("cortex-a9", "cortex-a12", "cortex-a15", "krait", "v7")
+    .Cases("cortex-r4", "cortex-r5", "v7r")
+    .Case("cortex-m0", "v6m")
+    .Case("cortex-m3", "v7m")
+    .Case("cortex-m4", "v7em")
+    .Case("swift", "v7s")
+    .Case("cyclone", "v8")
+    .Cases("cortex-a53", "cortex-a57", "v8")
+    .Default("");
+}
+
+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::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::isFPXXDefault(const llvm::Triple &Triple, StringRef CPUName,
+                         StringRef ABIName) {
+  if (Triple.getVendor() != llvm::Triple::ImaginationTechnologies &&
+      Triple.getVendor() != llvm::Triple::MipsTechnologies)
+    return false;
+
+  if (ABIName != "32")
+    return false;
+
+  return llvm::StringSwitch<bool>(CPUName)
+             .Cases("mips2", "mips3", "mips4", "mips5", true)
+             .Cases("mips32", "mips32r2", true)
+             .Cases("mips64", "mips64r2", true)
+             .Default(false);
+}
+
+llvm::Triple::ArchType darwin::getArchTypeForMachOArchName(StringRef Str) {
   // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
   // archs which Darwin doesn't use.
 
@@ -4547,8 +5358,9 @@
     .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", "armv7f", "armv7k", "armv7m", llvm::Triple::arm)
+    .Cases("armv7", "armv7em", "armv7k", "armv7m", llvm::Triple::arm)
     .Cases("armv7s", "xscale", llvm::Triple::arm)
+    .Case("arm64", llvm::Triple::arm64)
     .Case("r600", llvm::Triple::r600)
     .Case("nvptx", llvm::Triple::nvptx)
     .Case("nvptx64", llvm::Triple::nvptx64)
@@ -4557,6 +5369,18 @@
     .Default(llvm::Triple::UnknownArch);
 }
 
+void darwin::setTripleTypeForMachOArchName(llvm::Triple &T, StringRef Str) {
+  llvm::Triple::ArchType Arch = getArchTypeForMachOArchName(Str);
+  T.setArch(Arch);
+
+  if (Str == "x86_64h")
+    T.setArchName(Str);
+  else if (Str == "armv6m" || Str == "armv7m" || Str == "armv7em") {
+    T.setOS(llvm::Triple::UnknownOS);
+    T.setObjectFormat(llvm::Triple::MachO);
+  }
+}
+
 const char *Clang::getBaseInputName(const ArgList &Args,
                                     const InputInfoList &Inputs) {
   return Args.MakeArgString(
@@ -4604,10 +5428,16 @@
     SourceAction = SourceAction->getInputs()[0];
   }
 
-  // If -no_integrated_as is used add -Q to the darwin assember driver to make
+  // 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.
-  if (Args.hasArg(options::OPT_no_integrated_as))
-    CmdArgs.push_back("-Q");
+  // 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 (future)
+  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 ||
@@ -4619,7 +5449,7 @@
   }
 
   // Derived from asm spec.
-  AddDarwinArch(Args, CmdArgs);
+  AddMachOArch(Args, CmdArgs);
 
   // Use -force_cpusubtype_ALL on x86 by default.
   if (getToolChain().getArch() == llvm::Triple::x86 ||
@@ -4630,8 +5460,7 @@
   if (getToolChain().getArch() != llvm::Triple::x86_64 &&
       (((Args.hasArg(options::OPT_mkernel) ||
          Args.hasArg(options::OPT_fapple_kext)) &&
-        (!getDarwinToolChain().isTargetIPhoneOS() ||
-         getDarwinToolChain().isIPhoneOSVersionLT(6, 0))) ||
+        getMachOToolChain().isKernelStatic()) ||
        Args.hasArg(options::OPT_static)))
     CmdArgs.push_back("-static");
 
@@ -4652,11 +5481,11 @@
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
-void darwin::DarwinTool::anchor() {}
+void darwin::MachOTool::anchor() {}
 
-void darwin::DarwinTool::AddDarwinArch(const ArgList &Args,
-                                       ArgStringList &CmdArgs) const {
-  StringRef ArchName = getDarwinToolChain().getDarwinArchName(Args);
+void darwin::MachOTool::AddMachOArch(const ArgList &Args,
+                                     ArgStringList &CmdArgs) const {
+  StringRef ArchName = getMachOToolChain().getMachOArchName(Args);
 
   // Derived from darwin_arch spec.
   CmdArgs.push_back("-arch");
@@ -4671,9 +5500,8 @@
   // We only need to generate a temp path for LTO if we aren't compiling object
   // files. When compiling source files, we run 'dsymutil' after linking. We
   // don't run 'dsymutil' when compiling object files.
-  for (InputInfoList::const_iterator
-         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it)
-    if (it->getType() != types::TY_Object)
+  for (const auto &Input : Inputs)
+    if (Input.getType() != types::TY_Object)
       return true;
 
   return false;
@@ -4684,7 +5512,7 @@
                                ArgStringList &CmdArgs,
                                const InputInfoList &Inputs) const {
   const Driver &D = getToolChain().getDriver();
-  const toolchains::Darwin &DarwinTC = getDarwinToolChain();
+  const toolchains::MachO &MachOTC = getMachOToolChain();
 
   unsigned Version[3] = { 0, 0, 0 };
   if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) {
@@ -4696,27 +5524,10 @@
         << A->getAsString(Args);
   }
 
-  // Newer linkers support -demangle, pass it if supported and not disabled by
+  // 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)) {
-    // Don't pass -demangle to ld_classic.
-    //
-    // FIXME: This is a temporary workaround, ld should be handling this.
-    bool UsesLdClassic = (getToolChain().getArch() == llvm::Triple::x86 &&
-                          Args.hasArg(options::OPT_static));
-    if (getToolChain().getArch() == llvm::Triple::x86) {
-      for (arg_iterator it = Args.filtered_begin(options::OPT_Xlinker,
-                                                 options::OPT_Wl_COMMA),
-             ie = Args.filtered_end(); it != ie; ++it) {
-        const Arg *A = *it;
-        for (unsigned i = 0, e = A->getNumValues(); i != e; ++i)
-          if (StringRef(A->getValue(i)) == "-kext")
-            UsesLdClassic = true;
-      }
-    }
-    if (!UsesLdClassic)
-      CmdArgs.push_back("-demangle");
-  }
+  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");
@@ -4742,7 +5553,7 @@
   }
 
   if (!Args.hasArg(options::OPT_dynamiclib)) {
-    AddDarwinArch(Args, CmdArgs);
+    AddMachOArch(Args, CmdArgs);
     // FIXME: Why do this only on this path?
     Args.AddLastArg(CmdArgs, options::OPT_force__cpusubtype__ALL);
 
@@ -4778,7 +5589,7 @@
     Args.AddAllArgsTranslated(CmdArgs, options::OPT_current__version,
                               "-dylib_current_version");
 
-    AddDarwinArch(Args, CmdArgs);
+    AddMachOArch(Args, CmdArgs);
 
     Args.AddAllArgsTranslated(CmdArgs, options::OPT_install__name,
                               "-dylib_install_name");
@@ -4787,7 +5598,7 @@
   Args.AddLastArg(CmdArgs, options::OPT_all__load);
   Args.AddAllArgs(CmdArgs, options::OPT_allowable__client);
   Args.AddLastArg(CmdArgs, options::OPT_bind__at__load);
-  if (DarwinTC.isTargetIPhoneOS())
+  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);
@@ -4801,22 +5612,7 @@
   Args.AddAllArgs(CmdArgs, options::OPT_init);
 
   // Add the deployment target.
-  VersionTuple TargetVersion = DarwinTC.getTargetVersion();
-
-  // If we had an explicit -mios-simulator-version-min argument, honor that,
-  // otherwise use the traditional deployment targets. We can't just check the
-  // is-sim attribute because existing code follows this path, and the linker
-  // may not handle the argument.
-  //
-  // FIXME: We may be able to remove this, once we can verify no one depends on
-  // it.
-  if (Args.hasArg(options::OPT_mios_simulator_version_min_EQ))
-    CmdArgs.push_back("-ios_simulator_version_min");
-  else if (DarwinTC.isTargetIPhoneOS())
-    CmdArgs.push_back("-iphoneos_version_min");
-  else
-    CmdArgs.push_back("-macosx_version_min");
-  CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString()));
+  MachOTC.addMinVersionArgs(Args, CmdArgs);
 
   Args.AddLastArg(CmdArgs, options::OPT_nomultidefs);
   Args.AddLastArg(CmdArgs, options::OPT_multi__module);
@@ -4885,6 +5681,12 @@
   Args.AddLastArg(CmdArgs, options::OPT_Mach);
 }
 
+enum LibOpenMP {
+  LibUnknown,
+  LibGOMP,
+  LibIOMP5
+};
+
 void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
                                 const InputInfo &Output,
                                 const InputInfoList &Inputs,
@@ -4900,8 +5702,8 @@
   /// Hack(tm) to ignore linking errors when we are doing ARC migration.
   if (Args.hasArg(options::OPT_ccc_arcmt_check,
                   options::OPT_ccc_arcmt_migrate)) {
-    for (ArgList::const_iterator I = Args.begin(), E = Args.end(); I != E; ++I)
-      (*I)->claim();
+    for (const auto &Arg : Args)
+      Arg->claim();
     const char *Exec =
       Args.MakeArgString(getToolChain().GetProgramPath("touch"));
     CmdArgs.push_back(Output.getFilename());
@@ -4931,120 +5733,42 @@
   CmdArgs.push_back(Output.getFilename());
 
   if (!Args.hasArg(options::OPT_nostdlib) &&
-      !Args.hasArg(options::OPT_nostartfiles)) {
-    // Derived from startfile spec.
-    if (Args.hasArg(options::OPT_dynamiclib)) {
-      // Derived from darwin_dylib1 spec.
-      if (getDarwinToolChain().isTargetIOSSimulator()) {
-        // The simulator doesn't have a versioned crt1 file.
-        CmdArgs.push_back("-ldylib1.o");
-      } else if (getDarwinToolChain().isTargetIPhoneOS()) {
-        if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1))
-          CmdArgs.push_back("-ldylib1.o");
-      } else {
-        if (getDarwinToolChain().isMacosxVersionLT(10, 5))
-          CmdArgs.push_back("-ldylib1.o");
-        else if (getDarwinToolChain().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 (getDarwinToolChain().isTargetIOSSimulator()) {
-            // The simulator doesn't have a versioned crt1 file.
-            CmdArgs.push_back("-lbundle1.o");
-          } else if (getDarwinToolChain().isTargetIPhoneOS()) {
-            if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1))
-              CmdArgs.push_back("-lbundle1.o");
-          } else {
-            if (getDarwinToolChain().isMacosxVersionLT(10, 6))
-              CmdArgs.push_back("-lbundle1.o");
-          }
-        }
-      } else {
-        if (Args.hasArg(options::OPT_pg) &&
-            getToolChain().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 (getDarwinToolChain().isTargetMacOS() &&
-              !getDarwinToolChain().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 (getDarwinToolChain().isTargetIOSSimulator()) {
-              // The simulator doesn't have a versioned crt1 file.
-              CmdArgs.push_back("-lcrt1.o");
-            } else if (getDarwinToolChain().isTargetIPhoneOS()) {
-              if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1))
-                CmdArgs.push_back("-lcrt1.o");
-              else if (getDarwinToolChain().isIPhoneOSVersionLT(6, 0))
-                CmdArgs.push_back("-lcrt1.3.1.o");
-            } else {
-              if (getDarwinToolChain().isMacosxVersionLT(10, 5))
-                CmdArgs.push_back("-lcrt1.o");
-              else if (getDarwinToolChain().isMacosxVersionLT(10, 6))
-                CmdArgs.push_back("-lcrt1.10.5.o");
-              else if (getDarwinToolChain().isMacosxVersionLT(10, 8))
-                CmdArgs.push_back("-lcrt1.10.6.o");
-
-              // darwin_crt2 spec is empty.
-            }
-          }
-        }
-      }
-    }
-
-    if (!getDarwinToolChain().isTargetIPhoneOS() &&
-        Args.hasArg(options::OPT_shared_libgcc) &&
-        getDarwinToolChain().isMacosxVersionLT(10, 5)) {
-      const char *Str =
-        Args.MakeArgString(getToolChain().GetFilePath("crt3.o"));
-      CmdArgs.push_back(Str);
-    }
-  }
+      !Args.hasArg(options::OPT_nostartfiles))
+    getMachOToolChain().addStartObjectFileArgs(Args, CmdArgs);
 
   Args.AddAllArgs(CmdArgs, options::OPT_L);
 
-  if (Args.hasArg(options::OPT_fopenmp))
-    // This is more complicated in gcc...
+  LibOpenMP UsedOpenMPLib = LibUnknown;
+  if (Args.hasArg(options::OPT_fopenmp)) {
+    UsedOpenMPLib = LibGOMP;
+  } else if (const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ)) {
+    UsedOpenMPLib = llvm::StringSwitch<LibOpenMP>(A->getValue())
+        .Case("libgomp",  LibGOMP)
+        .Case("libiomp5", LibIOMP5)
+        .Default(LibUnknown);
+    if (UsedOpenMPLib == LibUnknown)
+      getToolChain().getDriver().Diag(diag::err_drv_unsupported_option_argument)
+        << A->getOption().getName() << A->getValue();
+  }
+  switch (UsedOpenMPLib) {
+  case LibGOMP:
     CmdArgs.push_back("-lgomp");
+    break;
+  case LibIOMP5:
+    CmdArgs.push_back("-liomp5");
+    break;
+  case LibUnknown:
+    break;
+  }
 
   AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
   
   if (isObjCRuntimeLinked(Args) &&
       !Args.hasArg(options::OPT_nostdlib) &&
       !Args.hasArg(options::OPT_nodefaultlibs)) {
-    // Avoid linking compatibility stubs on i386 mac.
-    if (!getDarwinToolChain().isTargetMacOS() ||
-        getDarwinToolChain().getArch() != llvm::Triple::x86) {
-      // If we don't have ARC or subscripting runtime support, link in the
-      // runtime stubs.  We have to do this *before* adding any of the normal
-      // linker inputs so that its initializer gets run first.
-      ObjCRuntime runtime =
-        getDarwinToolChain().getDefaultObjCRuntime(/*nonfragile*/ true);
-      // We use arclite library for both ARC and subscripting support.
-      if ((!runtime.hasNativeARC() && isObjCAutoRefCount(Args)) ||
-          !runtime.hasSubscripting())
-        getDarwinToolChain().AddLinkARCArgs(Args, CmdArgs);
-    }
+    // We use arclite library for both ARC and subscripting support.
+    getMachOToolChain().AddLinkARCArgs(Args, CmdArgs);
+
     CmdArgs.push_back("-framework");
     CmdArgs.push_back("Foundation");
     // Link libobj.
@@ -5068,7 +5792,7 @@
     // link_ssp spec is empty.
 
     // Let the tool chain choose which runtime library to link.
-    getDarwinToolChain().AddLinkRuntimeLibArgs(Args, CmdArgs);
+    getMachOToolChain().AddLinkRuntimeLibArgs(Args, CmdArgs);
   }
 
   if (!Args.hasArg(options::OPT_nostdlib) &&
@@ -5080,7 +5804,7 @@
   Args.AddAllArgs(CmdArgs, options::OPT_F);
 
   const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+    Args.MakeArgString(getToolChain().GetLinkerPath());
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -5097,14 +5821,12 @@
   CmdArgs.push_back("-output");
   CmdArgs.push_back(Output.getFilename());
 
-  for (InputInfoList::const_iterator
-         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
-    const InputInfo &II = *it;
+  for (const auto &II : Inputs) {
     assert(II.isFilename() && "Unexpected lipo input.");
     CmdArgs.push_back(II.getFilename());
   }
-  const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath("lipo"));
+
+  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("lipo"));
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -5164,18 +5886,13 @@
   CmdArgs.push_back("-o");
   CmdArgs.push_back(Output.getFilename());
 
-  for (InputInfoList::const_iterator
-         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
-    const InputInfo &II = *it;
+  for (const auto &II : Inputs)
     CmdArgs.push_back(II.getFilename());
-  }
 
-  const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath("as"));
+  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
-
 void solaris::Link::ConstructJob(Compilation &C, const JobAction &JA,
                                   const InputInfo &Output,
                                   const InputInfoList &Inputs,
@@ -5274,10 +5991,10 @@
   }
   CmdArgs.push_back(Args.MakeArgString(LibPath + "crtn.o"));
 
-  addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple());
+  addProfileRT(getToolChain(), Args, CmdArgs);
 
   const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+    Args.MakeArgString(getToolChain().GetLinkerPath());
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -5294,14 +6011,10 @@
   CmdArgs.push_back("-o");
   CmdArgs.push_back(Output.getFilename());
 
-  for (InputInfoList::const_iterator
-         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
-    const InputInfo &II = *it;
+  for (const auto &II : Inputs)
     CmdArgs.push_back(II.getFilename());
-  }
 
-  const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath("gas"));
+  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("gas"));
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -5386,10 +6099,10 @@
                                 getToolChain().GetFilePath("crtend.o")));
   }
 
-  addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple());
+  addProfileRT(getToolChain(), Args, CmdArgs);
 
   const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+    Args.MakeArgString(getToolChain().GetLinkerPath());
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -5399,6 +6112,55 @@
                                      const ArgList &Args,
                                      const char *LinkingOutput) const {
   ArgStringList CmdArgs;
+  bool NeedsKPIC = false;
+
+  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:
+    CmdArgs.push_back("-32");
+    NeedsKPIC = true;
+    break;
+
+  case llvm::Triple::sparcv9:
+    CmdArgs.push_back("-64");
+    CmdArgs.push_back("-Av9a");
+    NeedsKPIC = true;
+    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");
+
+    NeedsKPIC = true;
+    break;
+  }
+
+  default:
+    break;
+  }
+
+  if (NeedsKPIC)
+    addAssemblerKPIC(Args, CmdArgs);
 
   Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
                        options::OPT_Xassembler);
@@ -5406,11 +6168,8 @@
   CmdArgs.push_back("-o");
   CmdArgs.push_back(Output.getFilename());
 
-  for (InputInfoList::const_iterator
-         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
-    const InputInfo &II = *it;
+  for (const auto &II : Inputs)
     CmdArgs.push_back(II.getFilename());
-  }
 
   const char *Exec =
     Args.MakeArgString(getToolChain().GetProgramPath("as"));
@@ -5433,6 +6192,11 @@
   // 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)) &&
       (!Args.hasArg(options::OPT_shared))) {
     CmdArgs.push_back("-e");
@@ -5540,7 +6304,7 @@
   }
 
   const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+    Args.MakeArgString(getToolChain().GetLinkerPath());
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -5557,14 +6321,10 @@
   CmdArgs.push_back("-o");
   CmdArgs.push_back(Output.getFilename());
 
-  for (InputInfoList::const_iterator
-         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
-    const InputInfo &II = *it;
+  for (const auto &II : Inputs)
     CmdArgs.push_back(II.getFilename());
-  }
 
-  const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath("as"));
+  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -5680,7 +6440,7 @@
   }
 
   const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+    Args.MakeArgString(getToolChain().GetLinkerPath());
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -5703,7 +6463,7 @@
            getToolChain().getArch() == llvm::Triple::mips64el) {
     StringRef CPUName;
     StringRef ABIName;
-    getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
+    mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
 
     CmdArgs.push_back("-march");
     CmdArgs.push_back(CPUName.data());
@@ -5717,21 +6477,23 @@
     else
       CmdArgs.push_back("-EL");
 
-    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 &&
-        (LastPICArg->getOption().matches(options::OPT_fPIC) ||
-         LastPICArg->getOption().matches(options::OPT_fpic) ||
-         LastPICArg->getOption().matches(options::OPT_fPIE) ||
-         LastPICArg->getOption().matches(options::OPT_fpie))) {
-      CmdArgs.push_back("-KPIC");
-    }
+    addAssemblerKPIC(Args, CmdArgs);
   } else if (getToolChain().getArch() == llvm::Triple::arm ||
-             getToolChain().getArch() == llvm::Triple::thumb) {
-    CmdArgs.push_back("-mfpu=softvfp");
+             getToolChain().getArch() == llvm::Triple::armeb ||
+             getToolChain().getArch() == llvm::Triple::thumb ||
+             getToolChain().getArch() == llvm::Triple::thumbeb) {
+    const Driver &D = getToolChain().getDriver();
+    const llvm::Triple &Triple = getToolChain().getTriple();
+    StringRef FloatABI = arm::getARMFloatABI(D, Args, Triple);
+
+    if (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");
@@ -5740,6 +6502,14 @@
     default:
       CmdArgs.push_back("-matpcs");
     }
+  } else if (getToolChain().getArch() == llvm::Triple::sparc ||
+             getToolChain().getArch() == llvm::Triple::sparcv9) {
+    if (getToolChain().getArch() == llvm::Triple::sparc)
+      CmdArgs.push_back("-Av8plusa");
+    else
+      CmdArgs.push_back("-Av9a");
+
+    addAssemblerKPIC(Args, CmdArgs);
   }
 
   Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
@@ -5748,14 +6518,10 @@
   CmdArgs.push_back("-o");
   CmdArgs.push_back(Output.getFilename());
 
-  for (InputInfoList::const_iterator
-         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
-    const InputInfo &II = *it;
+  for (const auto &II : Inputs)
     CmdArgs.push_back(II.getFilename());
-  }
 
-  const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath("as"));
+  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -5767,6 +6533,9 @@
   const toolchains::FreeBSD& ToolChain = 
     static_cast<const toolchains::FreeBSD&>(getToolChain());
   const Driver &D = ToolChain.getDriver();
+  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"
@@ -5780,7 +6549,7 @@
   if (!D.SysRoot.empty())
     CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
 
-  if (Args.hasArg(options::OPT_pie))
+  if (IsPIE)
     CmdArgs.push_back("-pie");
 
   if (Args.hasArg(options::OPT_static)) {
@@ -5826,11 +6595,11 @@
 
   if (!Args.hasArg(options::OPT_nostdlib) &&
       !Args.hasArg(options::OPT_nostartfiles)) {
-    const char *crt1 = NULL;
+    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))
+      else if (IsPIE)
         crt1 = "Scrt1.o";
       else
         crt1 = "crt1.o";
@@ -5840,10 +6609,10 @@
 
     CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
 
-    const char *crtbegin = NULL;
+    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))
+    else if (Args.hasArg(options::OPT_shared) || IsPIE)
       crtbegin = "crtbeginS.o";
     else
       crtbegin = "crtbegin.o";
@@ -5853,9 +6622,8 @@
 
   Args.AddAllArgs(CmdArgs, options::OPT_L);
   const ToolChain::path_list Paths = ToolChain.getFilePaths();
-  for (ToolChain::path_list::const_iterator i = Paths.begin(), e = Paths.end();
-       i != e; ++i)
-    CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + *i));
+  for (const auto &Path : Paths)
+    CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + Path));
   Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
   Args.AddAllArgs(CmdArgs, options::OPT_e);
   Args.AddAllArgs(CmdArgs, options::OPT_s);
@@ -5863,25 +6631,8 @@
   Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
   Args.AddAllArgs(CmdArgs, options::OPT_r);
 
-  // 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.
-  if (D.IsUsingLTO(Args)) {
-    CmdArgs.push_back("-plugin");
-    std::string Plugin = ToolChain.getDriver().Dir + "/../lib/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 (D.IsUsingLTO(Args))
+    AddGoldPlugin(ToolChain, Args, CmdArgs);
 
   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
 
@@ -5941,17 +6692,19 @@
 
   if (!Args.hasArg(options::OPT_nostdlib) &&
       !Args.hasArg(options::OPT_nostartfiles)) {
-    if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
+    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")));
   }
 
-  addProfileRT(ToolChain, Args, CmdArgs, ToolChain.getTriple());
+  addSanitizerRuntimes(getToolChain(), Args, CmdArgs);
+
+  addProfileRT(ToolChain, Args, CmdArgs);
 
   const char *Exec =
-    Args.MakeArgString(ToolChain.GetProgramPath("ld"));
+    Args.MakeArgString(getToolChain().GetLinkerPath());
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -5962,16 +6715,59 @@
                                      const char *LinkingOutput) const {
   ArgStringList CmdArgs;
 
-  // When building 32-bit code on NetBSD/amd64, we have to explicitly
-  // instruct as in the base system to assemble 32-bit code.
-  if (getToolChain().getArch() == llvm::Triple::x86)
+  // 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: {
+    std::string MArch(arm::getARMTargetCPU(Args, getToolChain().getTriple()));
+    CmdArgs.push_back(Args.MakeArgString("-mcpu=" + MArch));
+    break;
+  }
 
-  // Set byte order explicitly
-  if (getToolChain().getArch() == llvm::Triple::mips)
-    CmdArgs.push_back("-EB");
-  else if (getToolChain().getArch() == llvm::Triple::mipsel)
-    CmdArgs.push_back("-EL");
+  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(Args, CmdArgs);
+    break;
+  }
+
+  case llvm::Triple::sparc:
+    CmdArgs.push_back("-32");
+    addAssemblerKPIC(Args, CmdArgs);
+    break;
+
+  case llvm::Triple::sparcv9:
+    CmdArgs.push_back("-64");
+    CmdArgs.push_back("-Av9");
+    addAssemblerKPIC(Args, CmdArgs);
+    break;
+
+  default:
+    break;  
+  }
 
   Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
                        options::OPT_Xassembler);
@@ -5979,11 +6775,8 @@
   CmdArgs.push_back("-o");
   CmdArgs.push_back(Output.getFilename());
 
-  for (InputInfoList::const_iterator
-         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
-    const InputInfo &II = *it;
+  for (const auto &II : Inputs)
     CmdArgs.push_back(II.getFilename());
-  }
 
   const char *Exec = Args.MakeArgString((getToolChain().GetProgramPath("as")));
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
@@ -6000,12 +6793,12 @@
   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");
-    CmdArgs.push_back("--eh-frame-hdr");
     if (Args.hasArg(options::OPT_shared)) {
       CmdArgs.push_back("-Bshareable");
     } else {
@@ -6014,11 +6807,61 @@
     }
   }
 
-  // When building 32-bit code on NetBSD/amd64, we have to explicitly
-  // instruct ld in the base system to link 32-bit code.
-  if (getToolChain().getArch() == llvm::Triple::x86) {
+  // 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::armeb:
+  case llvm::Triple::thumb:
+  case llvm::Triple::thumbeb:
+    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::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::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()) {
@@ -6058,10 +6901,19 @@
   unsigned Major, Minor, Micro;
   getToolChain().getTriple().getOSVersion(Major, Minor, Micro);
   bool useLibgcc = true;
-  if (Major >= 7 || (Major == 6 && Minor == 99 && Micro >= 23) || Major == 0) {
-    if (getToolChain().getArch() == llvm::Triple::x86 ||
-        getToolChain().getArch() == llvm::Triple::x86_64)
+  if (Major >= 7 || (Major == 6 && Minor == 99 && Micro >= 40) || Major == 0) {
+    switch(getToolChain().getArch()) {
+    case llvm::Triple::arm:
+    case llvm::Triple::armeb:
+    case llvm::Triple::thumb:
+    case llvm::Triple::thumbeb:
+    case llvm::Triple::x86:
+    case llvm::Triple::x86_64:
       useLibgcc = false;
+      break;
+    default:
+      break;
+    }
   }
 
   if (!Args.hasArg(options::OPT_nostdlib) &&
@@ -6103,9 +6955,9 @@
                                                                     "crtn.o")));
   }
 
-  addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple());
+  addProfileRT(getToolChain(), Args, CmdArgs);
 
-  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+  const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -6115,13 +6967,17 @@
                                       const ArgList &Args,
                                       const char *LinkingOutput) const {
   ArgStringList CmdArgs;
+  bool NeedsKPIC = false;
 
   // Add --32/--64 to make sure we get the format we want.
   // This is incomplete
   if (getToolChain().getArch() == llvm::Triple::x86) {
     CmdArgs.push_back("--32");
   } else if (getToolChain().getArch() == llvm::Triple::x86_64) {
-    CmdArgs.push_back("--64");
+    if (getToolChain().getTriple().getEnvironment() == llvm::Triple::GNUX32)
+      CmdArgs.push_back("--x32");
+    else
+      CmdArgs.push_back("--64");
   } else if (getToolChain().getArch() == llvm::Triple::ppc) {
     CmdArgs.push_back("-a32");
     CmdArgs.push_back("-mppc");
@@ -6132,21 +6988,41 @@
     CmdArgs.push_back("-many");
   } else if (getToolChain().getArch() == llvm::Triple::ppc64le) {
     CmdArgs.push_back("-a64");
-    CmdArgs.push_back("-mppc64le");
+    CmdArgs.push_back("-mppc64");
     CmdArgs.push_back("-many");
-  } else if (getToolChain().getArch() == llvm::Triple::arm) {
+    CmdArgs.push_back("-mlittle-endian");
+  } else if (getToolChain().getArch() == llvm::Triple::sparc) {
+    CmdArgs.push_back("-32");
+    CmdArgs.push_back("-Av8plusa");
+    NeedsKPIC = true;
+  } else if (getToolChain().getArch() == llvm::Triple::sparcv9) {
+    CmdArgs.push_back("-64");
+    CmdArgs.push_back("-Av9a");
+    NeedsKPIC = true;
+  } else if (getToolChain().getArch() == llvm::Triple::arm ||
+             getToolChain().getArch() == llvm::Triple::armeb) {
     StringRef MArch = getToolChain().getArchName();
     if (MArch == "armv7" || MArch == "armv7a" || MArch == "armv7-a")
       CmdArgs.push_back("-mfpu=neon");
-    if (MArch == "armv8" || MArch == "armv8a" || MArch == "armv8-a")
+    if (MArch == "armv8" || MArch == "armv8a" || MArch == "armv8-a" ||
+        MArch == "armebv8" || MArch == "armebv8a" || MArch == "armebv8-a")
       CmdArgs.push_back("-mfpu=crypto-neon-fp-armv8");
 
-    StringRef ARMFloatABI = getARMFloatABI(getToolChain().getDriver(), Args,
-                                           getToolChain().getTriple());
+    StringRef ARMFloatABI = tools::arm::getARMFloatABI(
+        getToolChain().getDriver(), Args, getToolChain().getTriple());
     CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=" + ARMFloatABI));
 
     Args.AddLastArg(CmdArgs, options::OPT_march_EQ);
-    Args.AddLastArg(CmdArgs, options::OPT_mcpu_EQ);
+
+    // FIXME: remove krait check when GNU tools support krait cpu
+    // for now replace it with -march=armv7-a  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()) == "krait")
+        CmdArgs.push_back("-march=armv7-a");
+    else
+      Args.AddLastArg(CmdArgs, options::OPT_mcpu_EQ);
     Args.AddLastArg(CmdArgs, options::OPT_mfpu_EQ);
   } else if (getToolChain().getArch() == llvm::Triple::mips ||
              getToolChain().getArch() == llvm::Triple::mipsel ||
@@ -6154,13 +7030,34 @@
              getToolChain().getArch() == llvm::Triple::mips64el) {
     StringRef CPUName;
     StringRef ABIName;
-    getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, 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(getGnuCompatibleMipsABIName(ABIName).data());
+    CmdArgs.push_back(ABIName.data());
+
+    // -mno-shared should be emitted unless -fpic, -fpie, -fPIC, -fPIE,
+    // or -mshared (not implemented) is in effect.
+    bool IsPicOrPie = false;
+    if (Arg *A = 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 (A->getOption().matches(options::OPT_fPIC) ||
+          A->getOption().matches(options::OPT_fpic) ||
+          A->getOption().matches(options::OPT_fPIE) ||
+          A->getOption().matches(options::OPT_fpie))
+        IsPicOrPie = true;
+    }
+    if (!IsPicOrPie)
+      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)
@@ -6173,23 +7070,47 @@
         CmdArgs.push_back(Args.MakeArgString("-mnan=2008"));
     }
 
-    Args.AddLastArg(CmdArgs, options::OPT_mips16, options::OPT_mno_mips16);
+    // 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::isFPXXDefault(getToolChain().getTriple(), CPUName,
+                                   ABIName))
+      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);
 
-    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 &&
-        (LastPICArg->getOption().matches(options::OPT_fPIC) ||
-         LastPICArg->getOption().matches(options::OPT_fpic) ||
-         LastPICArg->getOption().matches(options::OPT_fPIE) ||
-         LastPICArg->getOption().matches(options::OPT_fpie))) {
-      CmdArgs.push_back("-KPIC");
+    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_modd_spreg,
+                    options::OPT_mno_odd_spreg);
+
+    NeedsKPIC = true;
   } else if (getToolChain().getArch() == llvm::Triple::systemz) {
     // Always pass an -march option, since our default of z10 is later
     // than the GNU assembler's default.
@@ -6197,20 +7118,19 @@
     CmdArgs.push_back(Args.MakeArgString("-march=" + CPUName));
   }
 
+  if (NeedsKPIC)
+    addAssemblerKPIC(Args, CmdArgs);
+
   Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
                        options::OPT_Xassembler);
 
   CmdArgs.push_back("-o");
   CmdArgs.push_back(Output.getFilename());
 
-  for (InputInfoList::const_iterator
-         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
-    const InputInfo &II = *it;
+  for (const auto &II : Inputs)
     CmdArgs.push_back(II.getFilename());
-  }
 
-  const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath("as"));
+  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 
   // Handle the debug info splitting at object creation time if we're
@@ -6222,7 +7142,7 @@
                    SplitDebugName(Args, Inputs));
 }
 
-static void AddLibgcc(llvm::Triple Triple, const Driver &D,
+static void AddLibgcc(const llvm::Triple &Triple, const Driver &D,
                       ArgStringList &CmdArgs, const ArgList &Args) {
   bool isAndroid = Triple.getEnvironment() == llvm::Triple::Android;
   bool StaticLibgcc = Args.hasArg(options::OPT_static_libgcc) ||
@@ -6255,44 +7175,77 @@
     CmdArgs.push_back("-ldl");
 }
 
-static bool hasMipsN32ABIArg(const ArgList &Args) {
-  Arg *A = Args.getLastArg(options::OPT_mabi_EQ);
-  return A && (A->getValue() == StringRef("n32"));
-}
-
 static StringRef getLinuxDynamicLinker(const ArgList &Args,
                                        const toolchains::Linux &ToolChain) {
-  if (ToolChain.getTriple().getEnvironment() == llvm::Triple::Android)
-    return "/system/bin/linker";
-  else if (ToolChain.getArch() == llvm::Triple::x86)
+  if (ToolChain.getTriple().getEnvironment() == llvm::Triple::Android) {
+    if (ToolChain.getTriple().isArch64Bit())
+      return "/system/bin/linker64";
+    else
+      return "/system/bin/linker";
+  } else if (ToolChain.getArch() == llvm::Triple::x86 ||
+             ToolChain.getArch() == llvm::Triple::sparc)
     return "/lib/ld-linux.so.2";
-  else if (ToolChain.getArch() == llvm::Triple::aarch64)
+  else if (ToolChain.getArch() == llvm::Triple::aarch64 ||
+           ToolChain.getArch() == llvm::Triple::arm64)
     return "/lib/ld-linux-aarch64.so.1";
+  else if (ToolChain.getArch() == llvm::Triple::aarch64_be ||
+           ToolChain.getArch() == llvm::Triple::arm64_be)
+    return "/lib/ld-linux-aarch64_be.so.1";
   else if (ToolChain.getArch() == llvm::Triple::arm ||
            ToolChain.getArch() == llvm::Triple::thumb) {
     if (ToolChain.getTriple().getEnvironment() == llvm::Triple::GNUEABIHF)
       return "/lib/ld-linux-armhf.so.3";
     else
       return "/lib/ld-linux.so.3";
-  } else if (ToolChain.getArch() == llvm::Triple::mips ||
-             ToolChain.getArch() == llvm::Triple::mipsel)
-    return "/lib/ld.so.1";
-  else if (ToolChain.getArch() == llvm::Triple::mips64 ||
-           ToolChain.getArch() == llvm::Triple::mips64el) {
-    if (hasMipsN32ABIArg(Args))
-      return "/lib32/ld.so.1";
+  } else if (ToolChain.getArch() == llvm::Triple::armeb ||
+             ToolChain.getArch() == llvm::Triple::thumbeb) {
+    if (ToolChain.getTriple().getEnvironment() == llvm::Triple::GNUEABIHF)
+      return "/lib/ld-linux-armhf.so.3";        /* TODO: check which dynamic linker name.  */
     else
-      return "/lib64/ld.so.1";
+      return "/lib/ld-linux.so.3";              /* TODO: check which dynamic linker name.  */
+  } else if (ToolChain.getArch() == llvm::Triple::mips ||
+             ToolChain.getArch() == llvm::Triple::mipsel) {
+    if (mips::isNaN2008(Args, ToolChain.getTriple()))
+      return "/lib/ld-linux-mipsn8.so.1";
+    return "/lib/ld.so.1";
+  } else if (ToolChain.getArch() == llvm::Triple::mips64 ||
+             ToolChain.getArch() == llvm::Triple::mips64el) {
+    if (mips::hasMipsAbiArg(Args, "n32"))
+      return mips::isNaN2008(Args, ToolChain.getTriple())
+                 ? "/lib32/ld-linux-mipsn8.so.1" : "/lib32/ld.so.1";
+    return mips::isNaN2008(Args, ToolChain.getTriple())
+               ? "/lib64/ld-linux-mipsn8.so.1" : "/lib64/ld.so.1";
   } else if (ToolChain.getArch() == llvm::Triple::ppc)
     return "/lib/ld.so.1";
   else if (ToolChain.getArch() == llvm::Triple::ppc64 ||
-           ToolChain.getArch() == llvm::Triple::ppc64le ||
            ToolChain.getArch() == llvm::Triple::systemz)
     return "/lib64/ld64.so.1";
+  else if (ToolChain.getArch() == llvm::Triple::ppc64le)
+    return "/lib64/ld64.so.2";
+  else if (ToolChain.getArch() == llvm::Triple::sparcv9)
+    return "/lib64/ld-linux.so.2";
+  else if (ToolChain.getArch() == llvm::Triple::x86_64 &&
+           ToolChain.getTriple().getEnvironment() == llvm::Triple::GNUX32)
+    return "/libx32/ld-linux-x32.so.2";
   else
     return "/lib64/ld-linux-x86-64.so.2";
 }
 
+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:
+    addClangRTLinux(TC, Args, CmdArgs);
+    break;
+  case ToolChain::RLT_Libgcc:
+    AddLibgcc(TC.getTriple(), D, CmdArgs, Args);
+    break;
+  }
+}
+
 void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA,
                                   const InputInfo &Output,
                                   const InputInfoList &Inputs,
@@ -6303,10 +7256,14 @@
   const Driver &D = ToolChain.getDriver();
   const bool isAndroid =
     ToolChain.getTriple().getEnvironment() == llvm::Triple::Android;
-  const SanitizerArgs &Sanitize = ToolChain.getSanitizerArgs();
   const bool IsPIE =
     !Args.hasArg(options::OPT_shared) &&
-    (Args.hasArg(options::OPT_pie) || Sanitize.hasZeroBaseShadow());
+    !Args.hasArg(options::OPT_static) &&
+    (Args.hasArg(options::OPT_pie) || ToolChain.isPIEDefault() ||
+     // On Android every code is PIC so every executable is PIE
+     // Cannot use isPIEDefault here since otherwise
+     // PIE only logic will be enabled during compilation
+     isAndroid);
 
   ArgStringList CmdArgs;
 
@@ -6330,10 +7287,8 @@
   if (Args.hasArg(options::OPT_s))
     CmdArgs.push_back("-s");
 
-  for (std::vector<std::string>::const_iterator i = ToolChain.ExtraOpts.begin(),
-         e = ToolChain.ExtraOpts.end();
-       i != e; ++i)
-    CmdArgs.push_back(i->c_str());
+  for (const auto &Opt : ToolChain.ExtraOpts)
+    CmdArgs.push_back(Opt.c_str());
 
   if (!Args.hasArg(options::OPT_static)) {
     CmdArgs.push_back("--eh-frame-hdr");
@@ -6342,51 +7297,68 @@
   CmdArgs.push_back("-m");
   if (ToolChain.getArch() == llvm::Triple::x86)
     CmdArgs.push_back("elf_i386");
-  else if (ToolChain.getArch() == llvm::Triple::aarch64)
+  else if (ToolChain.getArch() == llvm::Triple::aarch64 ||
+           ToolChain.getArch() == llvm::Triple::arm64)
     CmdArgs.push_back("aarch64linux");
+  else if (ToolChain.getArch() == llvm::Triple::aarch64_be ||
+           ToolChain.getArch() == llvm::Triple::arm64_be)
+    CmdArgs.push_back("aarch64_be_linux");
   else if (ToolChain.getArch() == llvm::Triple::arm
            ||  ToolChain.getArch() == llvm::Triple::thumb)
     CmdArgs.push_back("armelf_linux_eabi");
+  else if (ToolChain.getArch() == llvm::Triple::armeb
+           ||  ToolChain.getArch() == llvm::Triple::thumbeb)
+    CmdArgs.push_back("armebelf_linux_eabi"); /* TODO: check which NAME.  */
   else if (ToolChain.getArch() == llvm::Triple::ppc)
     CmdArgs.push_back("elf32ppclinux");
   else if (ToolChain.getArch() == llvm::Triple::ppc64)
     CmdArgs.push_back("elf64ppc");
+  else if (ToolChain.getArch() == llvm::Triple::ppc64le)
+    CmdArgs.push_back("elf64lppc");
+  else if (ToolChain.getArch() == llvm::Triple::sparc)
+    CmdArgs.push_back("elf32_sparc");
+  else if (ToolChain.getArch() == llvm::Triple::sparcv9)
+    CmdArgs.push_back("elf64_sparc");
   else if (ToolChain.getArch() == llvm::Triple::mips)
     CmdArgs.push_back("elf32btsmip");
   else if (ToolChain.getArch() == llvm::Triple::mipsel)
     CmdArgs.push_back("elf32ltsmip");
   else if (ToolChain.getArch() == llvm::Triple::mips64) {
-    if (hasMipsN32ABIArg(Args))
+    if (mips::hasMipsAbiArg(Args, "n32"))
       CmdArgs.push_back("elf32btsmipn32");
     else
       CmdArgs.push_back("elf64btsmip");
   }
   else if (ToolChain.getArch() == llvm::Triple::mips64el) {
-    if (hasMipsN32ABIArg(Args))
+    if (mips::hasMipsAbiArg(Args, "n32"))
       CmdArgs.push_back("elf32ltsmipn32");
     else
       CmdArgs.push_back("elf64ltsmip");
   }
   else if (ToolChain.getArch() == llvm::Triple::systemz)
     CmdArgs.push_back("elf64_s390");
+  else if (ToolChain.getArch() == llvm::Triple::x86_64 &&
+           ToolChain.getTriple().getEnvironment() == llvm::Triple::GNUX32)
+    CmdArgs.push_back("elf32_x86_64");
   else
     CmdArgs.push_back("elf_x86_64");
 
   if (Args.hasArg(options::OPT_static)) {
-    if (ToolChain.getArch() == llvm::Triple::arm
-        || ToolChain.getArch() == llvm::Triple::thumb)
+    if (ToolChain.getArch() == llvm::Triple::arm ||
+        ToolChain.getArch() == llvm::Triple::armeb ||
+        ToolChain.getArch() == llvm::Triple::thumb ||
+        ToolChain.getArch() == llvm::Triple::thumbeb)
       CmdArgs.push_back("-Bstatic");
     else
       CmdArgs.push_back("-static");
   } else if (Args.hasArg(options::OPT_shared)) {
     CmdArgs.push_back("-shared");
-    if (isAndroid) {
-      CmdArgs.push_back("-Bsymbolic");
-    }
   }
 
   if (ToolChain.getArch() == llvm::Triple::arm ||
+      ToolChain.getArch() == llvm::Triple::armeb ||
       ToolChain.getArch() == llvm::Triple::thumb ||
+      ToolChain.getArch() == llvm::Triple::thumbeb ||
       (!Args.hasArg(options::OPT_static) &&
        !Args.hasArg(options::OPT_shared))) {
     CmdArgs.push_back("-dynamic-linker");
@@ -6400,7 +7372,7 @@
   if (!Args.hasArg(options::OPT_nostdlib) &&
       !Args.hasArg(options::OPT_nostartfiles)) {
     if (!isAndroid) {
-      const char *crt1 = NULL;
+      const char *crt1 = nullptr;
       if (!Args.hasArg(options::OPT_shared)){
         if (Args.hasArg(options::OPT_pg))
           crt1 = "gcrt1.o";
@@ -6431,57 +7403,24 @@
   }
 
   Args.AddAllArgs(CmdArgs, options::OPT_L);
+  Args.AddAllArgs(CmdArgs, options::OPT_u);
 
   const ToolChain::path_list Paths = ToolChain.getFilePaths();
 
-  for (ToolChain::path_list::const_iterator i = Paths.begin(), e = Paths.end();
-       i != e; ++i)
-    CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + *i));
+  for (const auto &Path : Paths)
+    CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + Path));
 
-  // 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.
-  if (D.IsUsingLTO(Args)) {
-    CmdArgs.push_back("-plugin");
-    std::string Plugin = ToolChain.getDriver().Dir + "/../lib/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 (D.IsUsingLTO(Args))
+    AddGoldPlugin(ToolChain, Args, CmdArgs);
 
   if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
     CmdArgs.push_back("--no-demangle");
 
   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
 
-  // Call these before we add the C++ ABI library.
-  if (Sanitize.needsUbsanRt())
-    addUbsanRTLinux(getToolChain(), Args, CmdArgs, D.CCCIsCXX(),
-                    Sanitize.needsAsanRt() || Sanitize.needsTsanRt() ||
-                    Sanitize.needsMsanRt() || Sanitize.needsLsanRt());
-  if (Sanitize.needsAsanRt())
-    addAsanRTLinux(getToolChain(), Args, CmdArgs);
-  if (Sanitize.needsTsanRt())
-    addTsanRTLinux(getToolChain(), Args, CmdArgs);
-  if (Sanitize.needsMsanRt())
-    addMsanRTLinux(getToolChain(), Args, CmdArgs);
-  if (Sanitize.needsLsanRt())
-    addLsanRTLinux(getToolChain(), Args, CmdArgs);
-  if (Sanitize.needsDfsanRt())
-    addDfsanRTLinux(getToolChain(), Args, CmdArgs);
-
+  addSanitizerRuntimes(getToolChain(), Args, CmdArgs);
   // The profile runtime also needs access to system libraries.
-  addProfileRTLinux(getToolChain(), Args, CmdArgs);
+  addProfileRT(getToolChain(), Args, CmdArgs);
 
   if (D.CCCIsCXX() &&
       !Args.hasArg(options::OPT_nostdlib) &&
@@ -6501,19 +7440,37 @@
       if (Args.hasArg(options::OPT_static))
         CmdArgs.push_back("--start-group");
 
-      bool OpenMP = Args.hasArg(options::OPT_fopenmp);
-      if (OpenMP) {
+      LibOpenMP UsedOpenMPLib = LibUnknown;
+      if (Args.hasArg(options::OPT_fopenmp)) {
+        UsedOpenMPLib = LibGOMP;
+      } else if (const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ)) {
+        UsedOpenMPLib = llvm::StringSwitch<LibOpenMP>(A->getValue())
+            .Case("libgomp",  LibGOMP)
+            .Case("libiomp5", LibIOMP5)
+            .Default(LibUnknown);
+        if (UsedOpenMPLib == LibUnknown)
+          D.Diag(diag::err_drv_unsupported_option_argument)
+            << A->getOption().getName() << A->getValue();
+      }
+      switch (UsedOpenMPLib) {
+      case LibGOMP:
         CmdArgs.push_back("-lgomp");
 
-        // FIXME: Exclude this for platforms whith libgomp that doesn't require
-        // librt. Most modern Linux platfroms require it, but some may not.
+        // 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 LibIOMP5:
+        CmdArgs.push_back("-liomp5");
+        break;
+      case LibUnknown:
+        break;
       }
+      AddRunTimeLibs(ToolChain, D, CmdArgs, Args);
 
-      AddLibgcc(ToolChain.getTriple(), D, CmdArgs, Args);
-
-      if (Args.hasArg(options::OPT_pthread) ||
-          Args.hasArg(options::OPT_pthreads) || OpenMP)
+      if ((Args.hasArg(options::OPT_pthread) ||
+           Args.hasArg(options::OPT_pthreads) || UsedOpenMPLib != LibUnknown) &&
+          !isAndroid)
         CmdArgs.push_back("-lpthread");
 
       CmdArgs.push_back("-lc");
@@ -6521,7 +7478,7 @@
       if (Args.hasArg(options::OPT_static))
         CmdArgs.push_back("--end-group");
       else
-        AddLibgcc(ToolChain.getTriple(), D, CmdArgs, Args);
+        AddRunTimeLibs(ToolChain, D, CmdArgs, Args);
     }
 
     if (!Args.hasArg(options::OPT_nostartfiles)) {
@@ -6542,6 +7499,145 @@
   C.addCommand(new Command(JA, *this, ToolChain.Linker.c_str(), CmdArgs));
 }
 
+// @LOCALMOD-BEGIN
+void nacltools::Link::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 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");
+
+  for (std::vector<std::string>::const_iterator i = ToolChain.ExtraOpts.begin(),
+         e = ToolChain.ExtraOpts.end();
+       i != e; ++i)
+    CmdArgs.push_back(i->c_str());
+
+  if (!IsStatic)
+    CmdArgs.push_back("--eh-frame-hdr");
+
+  CmdArgs.push_back("-m");
+  if (ToolChain.getArch() == llvm::Triple::x86)
+    CmdArgs.push_back("elf_i386_nacl");
+  else if (ToolChain.getArch() == llvm::Triple::arm)
+    CmdArgs.push_back("armelf_nacl");
+  else
+    CmdArgs.push_back("elf_x86_64_nacl");
+
+  if (IsStatic)
+    CmdArgs.push_back("-static");
+  else if (Args.hasArg(options::OPT_shared))
+    CmdArgs.push_back("-shared");
+  else
+    CmdArgs.push_back("-dynamic");
+
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+
+  if (!Args.hasArg(options::OPT_nostdlib) &&
+      !Args.hasArg(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);
+
+  const ToolChain::path_list Paths = ToolChain.getFilePaths();
+
+  for (ToolChain::path_list::const_iterator i = Paths.begin(), e = Paths.end();
+       i != e; ++i)
+    CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + *i));
+
+  if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
+    CmdArgs.push_back("--no-demangle");
+
+  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
+
+  if (D.CCCIsCXX() &&
+      !Args.hasArg(options::OPT_nostdlib) &&
+      !Args.hasArg(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");
+      // TODO(dschuff): Remove this explicit -lnacl and make -lc a linker script
+      // like arm-nacl-gcc
+      CmdArgs.push_back("-lnacl");
+      // libc++ and PPAPI programs always require libpthread, so just always
+      // include it in the group.
+      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");
+      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")));
+    }
+  }
+
+  C.addCommand(new Command(JA, *this, ToolChain.Linker.c_str(), CmdArgs));
+}
+// @LOCALMOD-END
+
 void minix::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
                                    const InputInfo &Output,
                                    const InputInfoList &Inputs,
@@ -6549,20 +7645,15 @@
                                    const char *LinkingOutput) const {
   ArgStringList CmdArgs;
 
-  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
-                       options::OPT_Xassembler);
+  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
 
   CmdArgs.push_back("-o");
   CmdArgs.push_back(Output.getFilename());
 
-  for (InputInfoList::const_iterator
-         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
-    const InputInfo &II = *it;
+  for (const auto &II : Inputs)
     CmdArgs.push_back(II.getFilename());
-  }
 
-  const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath("as"));
+  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -6595,7 +7686,7 @@
 
   AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
 
-  addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple());
+  addProfileRT(getToolChain(), Args, CmdArgs);
 
   if (!Args.hasArg(options::OPT_nostdlib) &&
       !Args.hasArg(options::OPT_nodefaultlibs)) {
@@ -6616,7 +7707,7 @@
          Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
   }
 
-  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+  const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -6636,20 +7727,15 @@
   if (getToolChain().getArch() == llvm::Triple::x86)
     CmdArgs.push_back("--32");
 
-  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
-                       options::OPT_Xassembler);
+  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
 
   CmdArgs.push_back("-o");
   CmdArgs.push_back(Output.getFilename());
 
-  for (InputInfoList::const_iterator
-         it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
-    const InputInfo &II = *it;
+  for (const auto &II : Inputs)
     CmdArgs.push_back(II.getFilename());
-  }
 
-  const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath("as"));
+  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -6797,13 +7883,21 @@
                             getToolChain().GetFilePath("crtn.o")));
   }
 
-  addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple());
+  addProfileRT(getToolChain(), Args, CmdArgs);
 
-  const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+  const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
+static void addSanitizerRTWindows(const ToolChain &TC, const ArgList &Args,
+                                  ArgStringList &CmdArgs,
+                                  const StringRef RTName) {
+  SmallString<128> LibSanitizer(getCompilerRTLibDir(TC));
+  llvm::sys::path::append(LibSanitizer,
+                          Twine("clang_rt.") + RTName + ".lib");
+  CmdArgs.push_back(Args.MakeArgString(LibSanitizer));
+}
+
 void visualstudio::Link::ConstructJob(Compilation &C, const JobAction &JA,
                                       const InputInfo &Output,
                                       const InputInfoList &Inputs,
@@ -6826,6 +7920,10 @@
 
   CmdArgs.push_back("-nologo");
 
+  if (Args.hasArg(options::OPT_g_Group)) {
+    CmdArgs.push_back("-debug");
+  }
+
   bool DLL = Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd);
 
   if (DLL) {
@@ -6840,28 +7938,25 @@
   if (getToolChain().getSanitizerArgs().needsAsanRt()) {
     CmdArgs.push_back(Args.MakeArgString("-debug"));
     CmdArgs.push_back(Args.MakeArgString("-incremental:no"));
-    SmallString<128> LibSanitizer(getToolChain().getDriver().ResourceDir);
-    llvm::sys::path::append(LibSanitizer, "lib", "windows");
-    if (DLL) {
-      llvm::sys::path::append(LibSanitizer, "clang_rt.asan_dll_thunk-i386.lib");
-    } else {
-      llvm::sys::path::append(LibSanitizer, "clang_rt.asan-i386.lib");
-    }
     // FIXME: Handle 64-bit.
-    CmdArgs.push_back(Args.MakeArgString(LibSanitizer));
+    if (DLL) {
+      addSanitizerRTWindows(getToolChain(), Args, CmdArgs,
+                            "asan_dll_thunk-i386");
+    } else {
+      addSanitizerRTWindows(getToolChain(), Args, CmdArgs, "asan-i386");
+      addSanitizerRTWindows(getToolChain(), Args, CmdArgs, "asan_cxx-i386");
+    }
   }
 
   Args.AddAllArgValues(CmdArgs, options::OPT_l);
   Args.AddAllArgValues(CmdArgs, options::OPT__SLASH_link);
 
   // Add filenames immediately.
-  for (InputInfoList::const_iterator
-       it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
-    if (it->isFilename())
-      CmdArgs.push_back(it->getFilename());
+  for (const auto &Input : Inputs)
+    if (Input.isFilename())
+      CmdArgs.push_back(Input.getFilename());
     else
-      it->getInputArg().renderAsInput(Args, CmdArgs);
-  }
+      Input.getInputArg().renderAsInput(Args, CmdArgs);
 
   const char *Exec =
     Args.MakeArgString(getToolChain().GetProgramPath("link.exe"));
@@ -6886,14 +7981,9 @@
   if (!OptPath.hasValue())
     return FallbackName;
 
-#ifdef LLVM_ON_WIN32
-  const StringRef PathSeparators = ";";
-#else
-  const StringRef PathSeparators = ":";
-#endif
-
+  const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
   SmallVector<StringRef, 8> PathSegments;
-  llvm::SplitString(OptPath.getValue(), PathSegments, PathSeparators);
+  llvm::SplitString(OptPath.getValue(), PathSegments, EnvPathSeparatorStr);
 
   for (size_t i = 0, e = PathSegments.size(); i != e; ++i) {
     const StringRef &PathSegment = PathSegments[i];
@@ -6943,19 +8033,31 @@
   // Flags for which clang-cl have an alias.
   // FIXME: How can we ensure this stays in sync with relevant clang-cl options?
 
-  if (Arg *A = Args.getLastArg(options::OPT_frtti, options::OPT_fno_rtti))
-    CmdArgs.push_back(A->getOption().getID() == options::OPT_frtti ? "/GR"
-                                                                   : "/GR-");
+  if (Args.hasFlag(options::OPT__SLASH_GR_, options::OPT__SLASH_GR,
+                   /*default=*/false))
+    CmdArgs.push_back("/GR-");
+  if (Arg *A = Args.getLastArg(options::OPT_ffunction_sections,
+                               options::OPT_fno_function_sections))
+    CmdArgs.push_back(A->getOption().getID() == options::OPT_ffunction_sections
+                          ? "/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))
+    CmdArgs.push_back("/Z7");
 
   std::vector<std::string> Includes = Args.getAllArgValues(options::OPT_include);
-  for (size_t I = 0, E = Includes.size(); I != E; ++I)
-    CmdArgs.push_back(Args.MakeArgString(std::string("/FI") + Includes[I]));
+  for (const auto &Include : Includes)
+    CmdArgs.push_back(Args.MakeArgString(std::string("/FI") + Include));
 
   // Flags that can simply be passed through.
   Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LD);
   Args.AddAllArgs(CmdArgs, options::OPT__SLASH_LDd);
+  Args.AddAllArgs(CmdArgs, options::OPT__SLASH_EH);
 
   // The order of these flags is relevant, so pick the last one.
   if (Arg *A = Args.getLastArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd,
@@ -6981,7 +8083,6 @@
 
   const Driver &D = getToolChain().getDriver();
   std::string Exec = FindFallback("cl.exe", D.getClangProgramPath());
-
   return new Command(JA, *this, Args.MakeArgString(Exec), CmdArgs);
 }
 
@@ -7001,21 +8102,24 @@
 
   CmdArgs.push_back("-c");
 
-  if (Args.hasArg(options::OPT_g_Group)) {
-    CmdArgs.push_back("-g");
-  }
+  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 (InputInfoList::const_iterator
-       it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
-    const InputInfo &II = *it;
+  for (const auto &II : Inputs)
     CmdArgs.push_back(II.getFilename());
-  }
 
-  const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath("xcc"));
+  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("xcc"));
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
@@ -7033,9 +8137,15 @@
     assert(Output.isNothing() && "Invalid output.");
   }
 
+  if (Args.hasArg(options::OPT_v))
+    CmdArgs.push_back("-v");
+
+  ExceptionSettings EH = exceptionSettings(Args, getToolChain().getTriple());
+  if (EH.ShouldUseExceptionTables)
+    CmdArgs.push_back("-fexceptions");
+
   AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
 
-  const char *Exec =
-    Args.MakeArgString(getToolChain().GetProgramPath("xcc"));
+  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("xcc"));
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
diff --git a/lib/Driver/Tools.h b/lib/Driver/Tools.h
index d5b2848..60683df 100644
--- a/lib/Driver/Tools.h
+++ b/lib/Driver/Tools.h
@@ -25,10 +25,15 @@
   class Driver;
 
 namespace toolchains {
-  class Darwin;
+  class MachO;
 }
 
 namespace tools {
+
+namespace visualstudio {
+  class Compile;
+}
+
 using llvm::opt::ArgStringList;
 
   /// \brief Clang compiler tool.
@@ -54,6 +59,8 @@
     void AddARMTargetArgs(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 AddR600TargetArgs(const llvm::opt::ArgList &Args,
@@ -76,18 +83,21 @@
     void AddClangCLArgs(const llvm::opt::ArgList &Args,
                         llvm::opt::ArgStringList &CmdArgs) const;
 
+    visualstudio::Compile *getCLFallback() const;
+
+    mutable std::unique_ptr<visualstudio::Compile> CLFallback;
+
   public:
     Clang(const ToolChain &TC) : Tool("clang", "clang frontend", TC) {}
 
-    virtual bool hasGoodDiagnostics() const { return true; }
-    virtual bool hasIntegratedAssembler() const { return true; }
-    virtual bool hasIntegratedCPP() const { return true; }
+    bool hasGoodDiagnostics() const override { return true; }
+    bool hasIntegratedAssembler() const override { return true; }
+    bool hasIntegratedCPP() const override { return true; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const llvm::opt::ArgList &TCArgs,
-                              const char *LinkingOutput) const;
+    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.
@@ -96,15 +106,14 @@
     ClangAs(const ToolChain &TC) : Tool("clang::as",
                                         "clang integrated assembler", TC) {}
 
-    virtual bool hasGoodDiagnostics() const { return true; }
-    virtual bool hasIntegratedAssembler() const { return false; }
-    virtual bool hasIntegratedCPP() const { return false; }
+    bool hasGoodDiagnostics() const override { return true; }
+    bool hasIntegratedAssembler() const override { return false; }
+    bool hasIntegratedCPP() const override { return false; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const llvm::opt::ArgList &TCArgs,
-                              const char *LinkingOutput) const;
+    void ConstructJob(Compilation &C, const JobAction &JA,
+                      const InputInfo &Output, const InputInfoList &Inputs,
+                      const llvm::opt::ArgList &TCArgs,
+                      const char *LinkingOutput) const override;
   };
 
   /// gcc - Generic GCC tool implementations.
@@ -114,11 +123,11 @@
     Common(const char *Name, const char *ShortName,
            const ToolChain &TC) : Tool(Name, ShortName, TC) {}
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const llvm::opt::ArgList &TCArgs,
-                              const char *LinkingOutput) const;
+    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.
@@ -132,23 +141,11 @@
     Preprocess(const ToolChain &TC) : Common("gcc::Preprocess",
                                              "gcc preprocessor", TC) {}
 
-    virtual bool hasGoodDiagnostics() const { return true; }
-    virtual bool hasIntegratedCPP() const { return false; }
+    bool hasGoodDiagnostics() const override { return true; }
+    bool hasIntegratedCPP() const override { return false; }
 
-    virtual void RenderExtraToolArgs(const JobAction &JA,
-                                     llvm::opt::ArgStringList &CmdArgs) const;
-  };
-
-  class LLVM_LIBRARY_VISIBILITY Precompile : public Common  {
-  public:
-    Precompile(const ToolChain &TC) : Common("gcc::Precompile",
-                                             "gcc precompile", TC) {}
-
-    virtual bool hasGoodDiagnostics() const { return true; }
-    virtual bool hasIntegratedCPP() const { return true; }
-
-    virtual void RenderExtraToolArgs(const JobAction &JA,
-                                     llvm::opt::ArgStringList &CmdArgs) const;
+    void RenderExtraToolArgs(const JobAction &JA,
+                             llvm::opt::ArgStringList &CmdArgs) const override;
   };
 
   class LLVM_LIBRARY_VISIBILITY Compile : public Common  {
@@ -156,22 +153,11 @@
     Compile(const ToolChain &TC) : Common("gcc::Compile",
                                           "gcc frontend", TC) {}
 
-    virtual bool hasGoodDiagnostics() const { return true; }
-    virtual bool hasIntegratedCPP() const { return true; }
+    bool hasGoodDiagnostics() const override { return true; }
+    bool hasIntegratedCPP() const override { return true; }
 
-    virtual void RenderExtraToolArgs(const JobAction &JA,
-                                     llvm::opt::ArgStringList &CmdArgs) const;
-  };
-
-  class LLVM_LIBRARY_VISIBILITY Assemble : public Common  {
-  public:
-    Assemble(const ToolChain &TC) : Common("gcc::Assemble",
-                                           "assembler (via gcc)", TC) {}
-
-    virtual bool hasIntegratedCPP() const { return false; }
-
-    virtual void RenderExtraToolArgs(const JobAction &JA,
-                                     llvm::opt::ArgStringList &CmdArgs) const;
+    void RenderExtraToolArgs(const JobAction &JA,
+                             llvm::opt::ArgStringList &CmdArgs) const override;
   };
 
   class LLVM_LIBRARY_VISIBILITY Link : public Common  {
@@ -179,11 +165,11 @@
     Link(const ToolChain &TC) : Common("gcc::Link",
                                        "linker (via gcc)", TC) {}
 
-    virtual bool hasIntegratedCPP() const { return false; }
-    virtual bool isLinkJob() const { return true; }
+    bool hasIntegratedCPP() const override { return false; }
+    bool isLinkJob() const override { return true; }
 
-    virtual void RenderExtraToolArgs(const JobAction &JA,
-                                     llvm::opt::ArgStringList &CmdArgs) const;
+    void RenderExtraToolArgs(const JobAction &JA,
+                             llvm::opt::ArgStringList &CmdArgs) const override;
   };
 } // end namespace gcc
 
@@ -195,15 +181,14 @@
     Assemble(const ToolChain &TC) : Tool("hexagon::Assemble",
       "hexagon-as", TC) {}
 
-    virtual bool hasIntegratedCPP() const { return false; }
+    bool hasIntegratedCPP() const override { return false; }
 
-    virtual void RenderExtraToolArgs(const JobAction &JA,
-                                     llvm::opt::ArgStringList &CmdArgs) const;
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const llvm::opt::ArgList &TCArgs,
-                              const char *LinkingOutput) const;
+    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 Link : public Tool {
@@ -211,111 +196,124 @@
     Link(const ToolChain &TC) : Tool("hexagon::Link",
       "hexagon-ld", TC) {}
 
-    virtual bool hasIntegratedCPP() const { return false; }
-    virtual bool isLinkJob() const { return true; }
+    bool hasIntegratedCPP() const override { return false; }
+    bool isLinkJob() const override { return true; }
 
     virtual void RenderExtraToolArgs(const JobAction &JA,
                                      llvm::opt::ArgStringList &CmdArgs) const;
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const llvm::opt::ArgList &TCArgs,
-                              const char *LinkingOutput) 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 arm {
+  StringRef getARMTargetCPU(const llvm::opt::ArgList &Args,
+                            const llvm::Triple &Triple);
+  const char* getARMCPUForMArch(const llvm::opt::ArgList &Args,
+                                const llvm::Triple &Triple);
+  const char* getLLVMArchSuffixForARM(StringRef CPU);
+}
+
+namespace mips {
+  void getMipsCPUAndABI(const llvm::opt::ArgList &Args,
+                        const llvm::Triple &Triple, StringRef &CPUName,
+                        StringRef &ABIName);
+  bool hasMipsAbiArg(const llvm::opt::ArgList &Args, const char *Value);
+  bool isNaN2008(const llvm::opt::ArgList &Args, const llvm::Triple &Triple);
+  bool isFPXXDefault(const llvm::Triple &Triple, StringRef CPUName,
+                     StringRef ABIName);
+}
 
 namespace darwin {
-  llvm::Triple::ArchType getArchTypeForDarwinArchName(StringRef Str);
+  llvm::Triple::ArchType getArchTypeForMachOArchName(StringRef Str);
+  void setTripleTypeForMachOArchName(llvm::Triple &T, StringRef Str);
 
-  class LLVM_LIBRARY_VISIBILITY DarwinTool : public Tool {
+  class LLVM_LIBRARY_VISIBILITY MachOTool : public Tool {
     virtual void anchor();
   protected:
-    void AddDarwinArch(const llvm::opt::ArgList &Args,
+    void AddMachOArch(const llvm::opt::ArgList &Args,
                        llvm::opt::ArgStringList &CmdArgs) const;
 
-    const toolchains::Darwin &getDarwinToolChain() const {
-      return reinterpret_cast<const toolchains::Darwin&>(getToolChain());
+    const toolchains::MachO &getMachOToolChain() const {
+      return reinterpret_cast<const toolchains::MachO&>(getToolChain());
     }
 
   public:
-    DarwinTool(const char *Name, const char *ShortName,
+    MachOTool(const char *Name, const char *ShortName,
                const ToolChain &TC) : Tool(Name, ShortName, TC) {}
   };
 
-  class LLVM_LIBRARY_VISIBILITY Assemble : public DarwinTool  {
+  class LLVM_LIBRARY_VISIBILITY Assemble : public MachOTool  {
   public:
-    Assemble(const ToolChain &TC) : DarwinTool("darwin::Assemble",
-                                               "assembler", TC) {}
+    Assemble(const ToolChain &TC) : MachOTool("darwin::Assemble",
+                                              "assembler", TC) {}
 
-    virtual bool hasIntegratedCPP() const { return false; }
+    bool hasIntegratedCPP() const override { return false; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const llvm::opt::ArgList &TCArgs,
-                              const char *LinkingOutput) 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 Link : public DarwinTool  {
+  class LLVM_LIBRARY_VISIBILITY Link : 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:
-    Link(const ToolChain &TC) : DarwinTool("darwin::Link", "linker", TC) {}
+    Link(const ToolChain &TC) : MachOTool("darwin::Link", "linker", TC) {}
 
-    virtual bool hasIntegratedCPP() const { return false; }
-    virtual bool isLinkJob() const { return true; }
+    bool hasIntegratedCPP() const override { return false; }
+    bool isLinkJob() const override { return true; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const llvm::opt::ArgList &TCArgs,
-                              const char *LinkingOutput) 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 Lipo : public DarwinTool  {
+  class LLVM_LIBRARY_VISIBILITY Lipo : public MachOTool  {
   public:
-    Lipo(const ToolChain &TC) : DarwinTool("darwin::Lipo", "lipo", TC) {}
+    Lipo(const ToolChain &TC) : MachOTool("darwin::Lipo", "lipo", TC) {}
 
-    virtual bool hasIntegratedCPP() const { return false; }
+    bool hasIntegratedCPP() const override { return false; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const llvm::opt::ArgList &TCArgs,
-                              const char *LinkingOutput) 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 Dsymutil : public DarwinTool  {
+  class LLVM_LIBRARY_VISIBILITY Dsymutil : public MachOTool  {
   public:
-    Dsymutil(const ToolChain &TC) : DarwinTool("darwin::Dsymutil",
-                                               "dsymutil", TC) {}
+    Dsymutil(const ToolChain &TC) : MachOTool("darwin::Dsymutil",
+                                              "dsymutil", TC) {}
 
-    virtual bool hasIntegratedCPP() const { return false; }
-    virtual bool isDsymutilJob() const { return true; }
+    bool hasIntegratedCPP() const override { return false; }
+    bool isDsymutilJob() const override { return true; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const llvm::opt::ArgList &TCArgs,
-                              const char *LinkingOutput) 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 VerifyDebug : public DarwinTool  {
+  class LLVM_LIBRARY_VISIBILITY VerifyDebug : public MachOTool  {
   public:
-    VerifyDebug(const ToolChain &TC) : DarwinTool("darwin::VerifyDebug",
-                                                  "dwarfdump", TC) {}
+    VerifyDebug(const ToolChain &TC) : MachOTool("darwin::VerifyDebug",
+                                                 "dwarfdump", TC) {}
 
-    virtual bool hasIntegratedCPP() const { return false; }
+    bool hasIntegratedCPP() const override { return false; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const llvm::opt::ArgList &TCArgs,
-                              const char *LinkingOutput) const;
+    void ConstructJob(Compilation &C, const JobAction &JA,
+                      const InputInfo &Output, const InputInfoList &Inputs,
+                      const llvm::opt::ArgList &TCArgs,
+                      const char *LinkingOutput) const override;
   };
 
 }
@@ -327,26 +325,25 @@
     Assemble(const ToolChain &TC) : Tool("openbsd::Assemble", "assembler",
                                          TC) {}
 
-    virtual bool hasIntegratedCPP() const { return false; }
+    bool hasIntegratedCPP() const override { return false; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const llvm::opt::ArgList &TCArgs,
-                              const char *LinkingOutput) 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 Link : public Tool  {
   public:
     Link(const ToolChain &TC) : Tool("openbsd::Link", "linker", TC) {}
 
-    virtual bool hasIntegratedCPP() const { return false; }
-    virtual bool isLinkJob() const { return true; }
+    bool hasIntegratedCPP() const override { return false; }
+    bool isLinkJob() const override { return true; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const llvm::opt::ArgList &TCArgs,
-                              const char *LinkingOutput) 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 openbsd
 
@@ -357,26 +354,24 @@
     Assemble(const ToolChain &TC) : Tool("bitrig::Assemble", "assembler",
                                          TC) {}
 
-    virtual bool hasIntegratedCPP() const { return false; }
+    bool hasIntegratedCPP() const override { return false; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const llvm::opt::ArgList &TCArgs,
-                              const char *LinkingOutput) 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 Link : public Tool  {
   public:
     Link(const ToolChain &TC) : Tool("bitrig::Link", "linker", TC) {}
 
-    virtual bool hasIntegratedCPP() const { return false; }
-    virtual bool isLinkJob() const { return true; }
+    bool hasIntegratedCPP() const override { return false; }
+    bool isLinkJob() const override { return true; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const llvm::opt::ArgList &TCArgs,
-                              const char *LinkingOutput) 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 bitrig
 
@@ -387,26 +382,24 @@
     Assemble(const ToolChain &TC) : Tool("freebsd::Assemble", "assembler",
                                          TC) {}
 
-    virtual bool hasIntegratedCPP() const { return false; }
+    bool hasIntegratedCPP() const override { return false; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const llvm::opt::ArgList &TCArgs,
-                              const char *LinkingOutput) 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 Link : public Tool  {
   public:
     Link(const ToolChain &TC) : Tool("freebsd::Link", "linker", TC) {}
 
-    virtual bool hasIntegratedCPP() const { return false; }
-    virtual bool isLinkJob() const { return true; }
+    bool hasIntegratedCPP() const override { return false; }
+    bool isLinkJob() const override { return true; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const llvm::opt::ArgList &TCArgs,
-                              const char *LinkingOutput) 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 freebsd
 
@@ -418,13 +411,12 @@
     Assemble(const ToolChain &TC)
       : Tool("netbsd::Assemble", "assembler", TC) {}
 
-    virtual bool hasIntegratedCPP() const { return false; }
+    bool hasIntegratedCPP() const override { return false; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const llvm::opt::ArgList &TCArgs,
-                              const char *LinkingOutput) 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 Link : public Tool  {
 
@@ -432,14 +424,13 @@
     Link(const ToolChain &TC)
       : Tool("netbsd::Link", "linker", TC) {}
 
-    virtual bool hasIntegratedCPP() const { return false; }
-    virtual bool isLinkJob() const { return true; }
+    bool hasIntegratedCPP() const override { return false; }
+    bool isLinkJob() const override { return true; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const llvm::opt::ArgList &TCArgs,
-                              const char *LinkingOutput) 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 netbsd
 
@@ -449,18 +440,36 @@
   public:
     Assemble(const ToolChain &TC) : Tool("GNU::Assemble", "assembler", TC) {}
 
-    virtual bool hasIntegratedCPP() const { return false; }
+    bool hasIntegratedCPP() const override { return false; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const llvm::opt::ArgList &TCArgs,
-                              const char *LinkingOutput) 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 Link : public Tool  {
   public:
     Link(const ToolChain &TC) : Tool("GNU::Link", "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;
+  };
+}
+
+// @LOCALMOD-BEGIN
+/// nacltools -- Directly call GNU Binutils' assembler and linker.
+namespace nacltools {
+  class LLVM_LIBRARY_VISIBILITY Link : public Tool  {
+  public:
+    Link(const ToolChain &TC) : Tool("NaCl::Link", "linker", TC) {}
+
     virtual bool hasIntegratedCPP() const { return false; }
     virtual bool isLinkJob() const { return true; }
 
@@ -471,6 +480,9 @@
                               const char *LinkingOutput) const;
   };
 }
+// @LOCALMOD-END
+
+
   /// minix -- Directly call GNU Binutils assembler and linker
 namespace minix {
   class LLVM_LIBRARY_VISIBILITY Assemble : public Tool  {
@@ -478,26 +490,26 @@
     Assemble(const ToolChain &TC) : Tool("minix::Assemble", "assembler",
                                          TC) {}
 
-    virtual bool hasIntegratedCPP() const { return false; }
+    bool hasIntegratedCPP() const override { return false; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const llvm::opt::ArgList &TCArgs,
-                              const char *LinkingOutput) 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 Link : public Tool  {
   public:
     Link(const ToolChain &TC) : Tool("minix::Link", "linker", TC) {}
 
-    virtual bool hasIntegratedCPP() const { return false; }
-    virtual bool isLinkJob() const { return true; }
+    bool hasIntegratedCPP() const override { return false; }
+    bool isLinkJob() const override { return true; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const llvm::opt::ArgList &TCArgs,
-                              const char *LinkingOutput) 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 minix
 
@@ -508,26 +520,24 @@
     Assemble(const ToolChain &TC) : Tool("solaris::Assemble", "assembler",
                                          TC) {}
 
-    virtual bool hasIntegratedCPP() const { return false; }
+    bool hasIntegratedCPP() const override { return false; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const llvm::opt::ArgList &TCArgs,
-                              const char *LinkingOutput) 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 Link : public Tool  {
   public:
     Link(const ToolChain &TC) : Tool("solaris::Link", "linker", TC) {}
 
-    virtual bool hasIntegratedCPP() const { return false; }
-    virtual bool isLinkJob() const { return true; }
+    bool hasIntegratedCPP() const override { return false; }
+    bool isLinkJob() const override { return true; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const llvm::opt::ArgList &TCArgs,
-                              const char *LinkingOutput) 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 solaris
 
@@ -538,26 +548,24 @@
     Assemble(const ToolChain &TC) : Tool("auroraux::Assemble", "assembler",
                                          TC) {}
 
-    virtual bool hasIntegratedCPP() const { return false; }
+    bool hasIntegratedCPP() const override { return false; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const llvm::opt::ArgList &TCArgs,
-                              const char *LinkingOutput) 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 Link : public Tool  {
   public:
     Link(const ToolChain &TC) : Tool("auroraux::Link", "linker", TC) {}
 
-    virtual bool hasIntegratedCPP() const { return false; }
-    virtual bool isLinkJob() const { return true; }
+    bool hasIntegratedCPP() const override { return false; }
+    bool isLinkJob() const override { return true; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const llvm::opt::ArgList &TCArgs,
-                              const char *LinkingOutput) 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 auroraux
 
@@ -568,58 +576,55 @@
     Assemble(const ToolChain &TC) : Tool("dragonfly::Assemble", "assembler",
                                          TC) {}
 
-    virtual bool hasIntegratedCPP() const { return false; }
+    bool hasIntegratedCPP() const override { return false; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const llvm::opt::ArgList &TCArgs,
-                              const char *LinkingOutput) 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 Link : public Tool  {
   public:
     Link(const ToolChain &TC) : Tool("dragonfly::Link", "linker", TC) {}
 
-    virtual bool hasIntegratedCPP() const { return false; }
-    virtual bool isLinkJob() const { return true; }
+    bool hasIntegratedCPP() const override { return false; }
+    bool isLinkJob() const override { return true; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const llvm::opt::ArgList &TCArgs,
-                              const char *LinkingOutput) 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 dragonfly
 
-  /// Visual studio tools.
+/// Visual studio tools.
 namespace visualstudio {
   class LLVM_LIBRARY_VISIBILITY Link : public Tool {
   public:
     Link(const ToolChain &TC) : Tool("visualstudio::Link", "linker", TC) {}
 
-    virtual bool hasIntegratedCPP() const { return false; }
-    virtual bool isLinkJob() const { return true; }
+    bool hasIntegratedCPP() const override { return false; }
+    bool isLinkJob() const override { return true; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const llvm::opt::ArgList &TCArgs,
-                              const char *LinkingOutput) 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 Compile : public Tool {
   public:
     Compile(const ToolChain &TC) : Tool("visualstudio::Compile", "compiler", TC) {}
 
-    virtual bool hasIntegratedAssembler() const { return true; }
-    virtual bool hasIntegratedCPP() const { return true; }
-    virtual bool isLinkJob() const { return false; }
+    bool hasIntegratedAssembler() const override { return true; }
+    bool hasIntegratedCPP() const override { return true; }
+    bool isLinkJob() const override { return false; }
 
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const llvm::opt::ArgList &TCArgs,
-                              const char *LinkingOutput) const;
+    void ConstructJob(Compilation &C, const JobAction &JA,
+                      const InputInfo &Output, const InputInfoList &Inputs,
+                      const llvm::opt::ArgList &TCArgs,
+                      const char *LinkingOutput) const override;
 
     Command *GetCommand(Compilation &C, const JobAction &JA,
                         const InputInfo &Output,
@@ -629,6 +634,10 @@
   };
 } // end namespace visualstudio
 
+namespace arm {
+  StringRef getARMFloatABI(const Driver &D, const llvm::opt::ArgList &Args,
+                         const llvm::Triple &Triple);
+}
 namespace XCore {
   // For XCore, we do not need to instantiate tools for PreProcess, PreCompile and Compile.
   // We simply use "clang -cc1" for those actions.
@@ -637,12 +646,11 @@
     Assemble(const ToolChain &TC) : Tool("XCore::Assemble",
       "XCore-as", TC) {}
 
-    virtual bool hasIntegratedCPP() const { return false; }
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const llvm::opt::ArgList &TCArgs,
-                              const char *LinkingOutput) const;
+    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 {
@@ -650,13 +658,12 @@
     Link(const ToolChain &TC) : Tool("XCore::Link",
       "XCore-ld", TC) {}
 
-    virtual bool hasIntegratedCPP() const { return false; }
-    virtual bool isLinkJob() const { return true; }
-    virtual void ConstructJob(Compilation &C, const JobAction &JA,
-                              const InputInfo &Output,
-                              const InputInfoList &Inputs,
-                              const llvm::opt::ArgList &TCArgs,
-                              const char *LinkingOutput) const;
+    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.
 
diff --git a/lib/Driver/Types.cpp b/lib/Driver/Types.cpp
index d947ae7..3538dbc 100644
--- a/lib/Driver/Types.cpp
+++ b/lib/Driver/Types.cpp
@@ -174,6 +174,8 @@
            .Case("F95", TY_Fortran)
            .Case("mii", TY_PP_ObjCXX)
            .Case("pcm", TY_ModuleFile)
+           .Case("pch", TY_PCH)
+           .Case("gch", TY_PCH)
            .Default(TY_INVALID);
 }
 
diff --git a/lib/Driver/WindowsToolChain.cpp b/lib/Driver/WindowsToolChain.cpp
index db36f1e..913425a 100644
--- a/lib/Driver/WindowsToolChain.cpp
+++ b/lib/Driver/WindowsToolChain.cpp
@@ -14,6 +14,7 @@
 #include "clang/Driver/Driver.h"
 #include "clang/Driver/DriverDiagnostic.h"
 #include "clang/Driver/Options.h"
+#include "llvm/Config/llvm-config.h"
 #include "llvm/Option/Arg.h"
 #include "llvm/Option/ArgList.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -21,11 +22,15 @@
 
 // Include the necessary headers to interface with the Windows registry and
 // environment.
-#ifdef _MSC_VER
+#if defined(LLVM_ON_WIN32)
+#define USE_WIN32
+#endif
+
+#ifdef USE_WIN32
   #define WIN32_LEAN_AND_MEAN
   #define NOGDI
   #define NOMINMAX
-  #include <Windows.h>
+  #include <windows.h>
 #endif
 
 using namespace clang::driver;
@@ -43,10 +48,10 @@
 }
 
 Tool *Windows::buildAssembler() const {
-  if (getTriple().getEnvironment() == llvm::Triple::MachO)
+  if (getTriple().isOSBinFormatMachO())
     return new tools::darwin::Assemble(*this);
-  getDriver().Diag(clang::diag::err_no_external_windows_assembler);
-  return NULL;
+  getDriver().Diag(clang::diag::err_no_external_assembler);
+  return nullptr;
 }
 
 bool Windows::IsIntegratedAssemblerDefault() const {
@@ -54,7 +59,11 @@
 }
 
 bool Windows::IsUnwindTablesDefault() const {
-  return getArch() == llvm::Triple::x86_64;
+  // FIXME: LLVM's lowering of Win64 data is broken right now.  MSVC's linker
+  // says that our object files provide invalid .pdata contributions.  Until
+  // that is fixed, don't ask for unwind tables.
+  return false;
+  //return getArch() == llvm::Triple::x86_64;
 }
 
 bool Windows::isPICDefault() const {
@@ -69,9 +78,6 @@
   return getArch() == llvm::Triple::x86_64;
 }
 
-// FIXME: This probably should goto to some platform utils place.
-#ifdef _MSC_VER
-
 /// \brief Read registry string.
 /// This also supports a means to look for high-versioned keys by use
 /// of a $VERSION placeholder in the key path.
@@ -82,6 +88,9 @@
 /// characters are compared.
 static bool getSystemRegistryString(const char *keyPath, const char *valueName,
                                     char *value, size_t maxLength) {
+#ifndef USE_WIN32
+  return false;
+#else
   HKEY hRootKey = NULL;
   HKEY hKey = NULL;
   const char* subKey = NULL;
@@ -183,6 +192,7 @@
     }
   }
   return returnValue;
+#endif // USE_WIN32
 }
 
 /// \brief Get Windows SDK installation directory.
@@ -202,7 +212,7 @@
   return false;
 }
 
-  // Get Visual Studio installation directory.
+// Get Visual Studio installation directory.
 static bool getVisualStudioDir(std::string &path) {
   // First check the environment variables that vsvars32.bat sets.
   const char* vcinstalldir = getenv("VCINSTALLDIR");
@@ -244,25 +254,11 @@
   const char *vs100comntools = getenv("VS100COMNTOOLS");
   const char *vs90comntools = getenv("VS90COMNTOOLS");
   const char *vs80comntools = getenv("VS80COMNTOOLS");
-  const char *vscomntools = NULL;
 
-  // Try to find the version that we were compiled with
-  if(false) {}
-  #if (_MSC_VER >= 1600)  // VC100
-  else if(vs100comntools) {
-    vscomntools = vs100comntools;
-  }
-  #elif (_MSC_VER == 1500) // VC80
-  else if(vs90comntools) {
-    vscomntools = vs90comntools;
-  }
-  #elif (_MSC_VER == 1400) // VC80
-  else if(vs80comntools) {
-    vscomntools = vs80comntools;
-  }
-  #endif
-  // Otherwise find any version we can
-  else if (vs100comntools)
+  const char *vscomntools = nullptr;
+
+  // Find any version we can
+  if (vs100comntools)
     vscomntools = vs100comntools;
   else if (vs90comntools)
     vscomntools = vs90comntools;
@@ -277,8 +273,6 @@
   return false;
 }
 
-#endif // _MSC_VER
-
 void Windows::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
                                         ArgStringList &CC1Args) const {
   if (DriverArgs.hasArg(options::OPT_nostdinc))
@@ -293,21 +287,15 @@
   if (DriverArgs.hasArg(options::OPT_nostdlibinc))
     return;
 
-#ifdef _MSC_VER
   // Honor %INCLUDE%. It should know essential search paths with vcvarsall.bat.
   if (const char *cl_include_dir = getenv("INCLUDE")) {
     SmallVector<StringRef, 8> Dirs;
-    StringRef(cl_include_dir).split(Dirs, ";");
-    int n = 0;
-    for (SmallVectorImpl<StringRef>::iterator I = Dirs.begin(), E = Dirs.end();
-         I != E; ++I) {
-      StringRef d = *I;
-      if (d.size() == 0)
-        continue;
-      ++n;
-      addSystemInclude(DriverArgs, CC1Args, d);
-    }
-    if (n) return;
+    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;
@@ -316,17 +304,24 @@
   // When built with access to the proper Windows APIs, try to actually find
   // the correct include paths first.
   if (getVisualStudioDir(VSDir)) {
-    addSystemInclude(DriverArgs, CC1Args, VSDir + "\\VC\\include");
-    if (getWindowsSDKDir(WindowsSDKDir))
-      addSystemInclude(DriverArgs, CC1Args, WindowsSDKDir + "\\include");
-    else
-      addSystemInclude(DriverArgs, CC1Args,
-                       VSDir + "\\VC\\PlatformSDK\\Include");
+    SmallString<128> P;
+    P = VSDir;
+    llvm::sys::path::append(P, "VC\\include");
+    addSystemInclude(DriverArgs, CC1Args, P.str());
+    if (getWindowsSDKDir(WindowsSDKDir)) {
+      P = WindowsSDKDir;
+      llvm::sys::path::append(P, "include");
+      addSystemInclude(DriverArgs, CC1Args, P.str());
+    } else {
+      P = VSDir;
+      llvm::sys::path::append(P, "VC\\PlatformSDK\\Include");
+      addSystemInclude(DriverArgs, CC1Args, P.str());
+    }
     return;
   }
-#endif // _MSC_VER
 
   // 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",
diff --git a/lib/Edit/CMakeLists.txt b/lib/Edit/CMakeLists.txt
index cce1c19..a7fa9c2 100644
--- a/lib/Edit/CMakeLists.txt
+++ b/lib/Edit/CMakeLists.txt
@@ -1,20 +1,14 @@
+set(LLVM_LINK_COMPONENTS
+  Support
+  )
+
 add_clang_library(clangEdit
   Commit.cpp
   EditedSource.cpp
   RewriteObjCFoundationAPI.cpp
-  )
 
-add_dependencies(clangEdit
-  ClangAttrClasses
-  ClangAttrList
-  ClangCommentNodes
-  ClangDeclNodes
-  ClangDiagnosticCommon
-  ClangStmtNodes
-  )
-
-target_link_libraries(clangEdit
-  clangBasic
+  LINK_LIBS
   clangAST
+  clangBasic
   clangLex
   )
diff --git a/lib/Edit/Commit.cpp b/lib/Edit/Commit.cpp
index 706c732..9c08cc2 100644
--- a/lib/Edit/Commit.cpp
+++ b/lib/Edit/Commit.cpp
@@ -38,9 +38,7 @@
 Commit::Commit(EditedSource &Editor)
   : SourceMgr(Editor.getSourceManager()), LangOpts(Editor.getLangOpts()),
     PPRec(Editor.getPPCondDirectiveRecord()),
-    Editor(&Editor),
-    ForceCommitInSystemHeader(Editor.getForceCommitInSystemHeader()),
-    IsCommitable(true) { }
+    Editor(&Editor), IsCommitable(true) { }
 
 bool Commit::insert(SourceLocation loc, StringRef text,
                     bool afterToken, bool beforePreviousInsertions) {
@@ -234,7 +232,7 @@
     if (!isAtStartOfMacroExpansion(loc, &loc))
       return false;
 
-  if (SM.isInSystemHeader(loc) && ForceCommitInSystemHeader)
+  if (SM.isInSystemHeader(loc))
     return false;
 
   std::pair<FileID, unsigned> locInfo = SM.getDecomposedLoc(loc);
@@ -265,7 +263,7 @@
     if (!isAtEndOfMacroExpansion(loc, &loc))
       return false;
 
-  if (SM.isInSystemHeader(loc) && ForceCommitInSystemHeader)
+  if (SM.isInSystemHeader(loc))
     return false;
 
   loc = Lexer::getLocForEndOfToken(loc, 0, SourceMgr, LangOpts);
@@ -303,8 +301,8 @@
   
   if (range.getBegin().isMacroID() || range.getEnd().isMacroID())
     return false;
-  if ((SM.isInSystemHeader(range.getBegin()) ||
-       SM.isInSystemHeader(range.getEnd())) && ForceCommitInSystemHeader)
+  if (SM.isInSystemHeader(range.getBegin()) ||
+      SM.isInSystemHeader(range.getEnd()))
     return false;
 
   if (PPRec && PPRec->rangeIntersectsConditionalDirective(range.getAsRange()))
diff --git a/lib/Edit/EditedSource.cpp b/lib/Edit/EditedSource.cpp
index 34b5e62..6cf6335 100644
--- a/lib/Edit/EditedSource.cpp
+++ b/lib/Edit/EditedSource.cpp
@@ -72,13 +72,11 @@
     return true;
   }
 
-  Twine concat;
   if (beforePreviousInsertions)
-    concat = Twine(text) + FA.Text;
+    FA.Text = copyString(Twine(text) + FA.Text);
   else
-    concat = Twine(FA.Text) +  text;
+    FA.Text = copyString(Twine(FA.Text) + text);
 
-  FA.Text = copyString(concat);
   return true;
 }
 
@@ -160,7 +158,7 @@
   }
 
   FileOffset TopBegin, TopEnd;
-  FileEdit *TopFA = 0;
+  FileEdit *TopFA = nullptr;
 
   if (I == FileEdits.end()) {
     FileEditsTy::iterator
diff --git a/lib/Edit/RewriteObjCFoundationAPI.cpp b/lib/Edit/RewriteObjCFoundationAPI.cpp
index f4206fb..666844c 100644
--- a/lib/Edit/RewriteObjCFoundationAPI.cpp
+++ b/lib/Edit/RewriteObjCFoundationAPI.cpp
@@ -58,7 +58,7 @@
 
 bool edit::rewriteObjCRedundantCallWithLiteral(const ObjCMessageExpr *Msg,
                                               const NSAPI &NS, Commit &commit) {
-  IdentifierInfo *II = 0;
+  IdentifierInfo *II = nullptr;
   if (!checkForLiteralCreation(Msg, II, NS.getASTContext().getLangOpts()))
     return false;
   if (Msg->getNumArgs() != 1)
@@ -339,7 +339,7 @@
 bool edit::rewriteToObjCLiteralSyntax(const ObjCMessageExpr *Msg,
                                       const NSAPI &NS, Commit &commit,
                                       const ParentMap *PMap) {
-  IdentifierInfo *II = 0;
+  IdentifierInfo *II = nullptr;
   if (!checkForLiteralCreation(Msg, II, NS.getASTContext().getLangOpts()))
     return false;
 
@@ -447,7 +447,7 @@
     return false;
 
   if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E)) {
-    IdentifierInfo *Cls = 0;
+    IdentifierInfo *Cls = nullptr;
     if (!checkForLiteralCreation(Msg, Cls, NS.getASTContext().getLangOpts()))
       return false;
 
@@ -606,7 +606,7 @@
   if (!Msg)
     return false;
 
-  IdentifierInfo *II = 0;
+  IdentifierInfo *II = nullptr;
   if (!checkForLiteralCreation(Msg, II, NS.getASTContext().getLangOpts()))
     return false;
 
@@ -1033,6 +1033,7 @@
     case CK_IntegralComplexToReal:
     case CK_IntegralComplexToBoolean:
     case CK_AtomicToNonAtomic:
+    case CK_AddressSpaceConversion:
       needsCast = true;
       break;
 
diff --git a/lib/Format/BreakableToken.cpp b/lib/Format/BreakableToken.cpp
index d720ce9..1bea0e5 100644
--- a/lib/Format/BreakableToken.cpp
+++ b/lib/Format/BreakableToken.cpp
@@ -13,8 +13,6 @@
 ///
 //===----------------------------------------------------------------------===//
 
-#define DEBUG_TYPE "format-token-breaker"
-
 #include "BreakableToken.h"
 #include "clang/Basic/CharInfo.h"
 #include "clang/Format/Format.h"
@@ -22,6 +20,8 @@
 #include "llvm/Support/Debug.h"
 #include <algorithm>
 
+#define DEBUG_TYPE "format-token-breaker"
+
 namespace clang {
 namespace format {
 
@@ -82,19 +82,15 @@
   return BreakableToken::Split(StringRef::npos, 0);
 }
 
-static BreakableToken::Split getStringSplit(StringRef Text,
-                                            unsigned UsedColumns,
-                                            unsigned ColumnLimit,
-                                            unsigned TabWidth,
-                                            encoding::Encoding Encoding) {
+static BreakableToken::Split
+getStringSplit(StringRef Text, unsigned UsedColumns, unsigned ColumnLimit,
+               unsigned TabWidth, encoding::Encoding Encoding) {
   // FIXME: Reduce unit test case.
   if (Text.empty())
     return BreakableToken::Split(StringRef::npos, 0);
   if (ColumnLimit <= UsedColumns)
     return BreakableToken::Split(StringRef::npos, 0);
-  unsigned MaxSplit = std::min<unsigned>(
-      ColumnLimit - UsedColumns,
-      encoding::columnWidthWithTabs(Text, UsedColumns, TabWidth, Encoding) - 1);
+  unsigned MaxSplit = ColumnLimit - UsedColumns;
   StringRef::size_type SpaceOffset = 0;
   StringRef::size_type SlashOffset = 0;
   StringRef::size_type WordStartOffset = 0;
@@ -110,7 +106,7 @@
           Text.substr(0, Advance), UsedColumns + Chars, TabWidth, Encoding);
     }
 
-    if (Chars > MaxSplit)
+    if (Chars > MaxSplit || Text.size() == Advance)
       break;
 
     if (IsBlank(Text[0]))
@@ -151,7 +147,7 @@
     encoding::Encoding Encoding, const FormatStyle &Style)
     : BreakableToken(Tok, IndentLevel, InPPDirective, Encoding, Style),
       StartColumn(StartColumn), Prefix(Prefix), Postfix(Postfix) {
-  assert(Tok.TokenText.startswith(Prefix) && Tok.TokenText.endswith(Postfix));
+  assert(Tok.TokenText.endswith(Postfix));
   Line = Tok.TokenText.substr(
       Prefix.size(), Tok.TokenText.size() - Prefix.size() - Postfix.size());
 }
@@ -174,24 +170,38 @@
 void BreakableStringLiteral::insertBreak(unsigned LineIndex,
                                          unsigned TailOffset, Split Split,
                                          WhitespaceManager &Whitespaces) {
+  unsigned LeadingSpaces = StartColumn;
+  // The '@' of an ObjC string literal (@"Test") does not become part of the
+  // string token.
+  // FIXME: It might be a cleaner solution to merge the tokens as a
+  // precomputation step.
+  if (Prefix.startswith("@"))
+    --LeadingSpaces;
   Whitespaces.replaceWhitespaceInToken(
       Tok, Prefix.size() + TailOffset + Split.first, Split.second, Postfix,
-      Prefix, InPPDirective, 1, IndentLevel, StartColumn);
+      Prefix, InPPDirective, 1, IndentLevel, LeadingSpaces);
 }
 
-static StringRef getLineCommentPrefix(StringRef Comment) {
-  static const char *const KnownPrefixes[] = { "/// ", "///", "// ", "//" };
-  for (size_t i = 0, e = llvm::array_lengthof(KnownPrefixes); i != e; ++i)
-    if (Comment.startswith(KnownPrefixes[i]))
-      return KnownPrefixes[i];
-  return "";
+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;
 }
 
 BreakableLineComment::BreakableLineComment(
     const FormatToken &Token, unsigned IndentLevel, unsigned StartColumn,
     bool InPPDirective, encoding::Encoding Encoding, const FormatStyle &Style)
     : BreakableSingleLineToken(Token, IndentLevel, StartColumn,
-                               getLineCommentPrefix(Token.TokenText), "",
+                               getLineCommentIndentPrefix(Token.TokenText), "",
                                InPPDirective, Encoding, Style) {
   OriginalPrefix = Prefix;
   if (Token.TokenText.size() > Prefix.size() &&
@@ -337,11 +347,10 @@
   LeadingWhitespace[LineIndex] =
       Lines[LineIndex].begin() - Lines[LineIndex - 1].end();
 
-  // Adjust the start column uniformly accross all lines.
-  StartOfLineColumn[LineIndex] = std::max<int>(
-      0,
+  // Adjust the start column uniformly across all lines.
+  StartOfLineColumn[LineIndex] =
       encoding::columnWidthWithTabs(Whitespace, 0, Style.TabWidth, Encoding) +
-          IndentDelta);
+      IndentDelta;
 }
 
 unsigned BreakableBlockComment::getLineCount() const { return Lines.size(); }
@@ -425,7 +434,6 @@
   unsigned WhitespaceOffsetInToken = Lines[LineIndex].data() -
                                      Tok.TokenText.data() -
                                      LeadingWhitespace[LineIndex];
-  assert(StartOfLineColumn[LineIndex] >= Prefix.size());
   Whitespaces.replaceWhitespaceInToken(
       Tok, WhitespaceOffsetInToken, LeadingWhitespace[LineIndex], "", Prefix,
       InPPDirective, 1, IndentLevel,
@@ -438,7 +446,7 @@
   // If we break, we always break at the predefined indent.
   if (TailOffset != 0)
     return IndentAtLineBreak;
-  return StartOfLineColumn[LineIndex];
+  return std::max(0, StartOfLineColumn[LineIndex]);
 }
 
 } // namespace format
diff --git a/lib/Format/BreakableToken.h b/lib/Format/BreakableToken.h
index b965190..72bb1e4 100644
--- a/lib/Format/BreakableToken.h
+++ b/lib/Format/BreakableToken.h
@@ -90,10 +90,9 @@
 /// \c getSplit() needs to be implemented by child classes.
 class BreakableSingleLineToken : public BreakableToken {
 public:
-  virtual unsigned getLineCount() const;
-  virtual unsigned getLineLengthAfterSplit(unsigned LineIndex,
-                                           unsigned TailOffset,
-                                           StringRef::size_type Length) const;
+  unsigned getLineCount() const override;
+  unsigned getLineLengthAfterSplit(unsigned LineIndex, unsigned TailOffset,
+                                   StringRef::size_type Length) const override;
 
 protected:
   BreakableSingleLineToken(const FormatToken &Tok, unsigned IndentLevel,
@@ -123,13 +122,12 @@
                          StringRef Postfix, bool InPPDirective,
                          encoding::Encoding Encoding, const FormatStyle &Style);
 
-  virtual Split getSplit(unsigned LineIndex, unsigned TailOffset,
-                         unsigned ColumnLimit) const;
-  virtual void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split,
-                           WhitespaceManager &Whitespaces);
-  virtual void replaceWhitespace(unsigned LineIndex, unsigned TailOffset,
-                                 Split Split,
-                                 WhitespaceManager &Whitespaces) {}
+  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 {}
 };
 
 class BreakableLineComment : public BreakableSingleLineToken {
@@ -142,15 +140,14 @@
                        unsigned StartColumn, bool InPPDirective,
                        encoding::Encoding Encoding, const FormatStyle &Style);
 
-  virtual Split getSplit(unsigned LineIndex, unsigned TailOffset,
-                         unsigned ColumnLimit) const;
-  virtual void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split,
-                           WhitespaceManager &Whitespaces);
-  virtual void replaceWhitespace(unsigned LineIndex, unsigned TailOffset,
-                                 Split Split,
-                                 WhitespaceManager &Whitespaces);
-  virtual void replaceWhitespaceBefore(unsigned LineIndex,
-                                       WhitespaceManager &Whitespaces);
+  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.
@@ -170,19 +167,17 @@
                         bool FirstInLine, bool InPPDirective,
                         encoding::Encoding Encoding, const FormatStyle &Style);
 
-  virtual unsigned getLineCount() const;
-  virtual unsigned getLineLengthAfterSplit(unsigned LineIndex,
-                                           unsigned TailOffset,
-                                           StringRef::size_type Length) const;
-  virtual Split getSplit(unsigned LineIndex, unsigned TailOffset,
-                         unsigned ColumnLimit) const;
-  virtual void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split,
-                           WhitespaceManager &Whitespaces);
-  virtual void replaceWhitespace(unsigned LineIndex, unsigned TailOffset,
-                                 Split Split,
-                                 WhitespaceManager &Whitespaces);
-  virtual void replaceWhitespaceBefore(unsigned LineIndex,
-                                       WhitespaceManager &Whitespaces);
+  unsigned getLineCount() const override;
+  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,
+                               WhitespaceManager &Whitespaces) override;
 
 private:
   // Rearranges the whitespace between Lines[LineIndex-1] and Lines[LineIndex],
@@ -217,7 +212,7 @@
   // 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.
-  SmallVector<unsigned, 16> StartOfLineColumn;
+  SmallVector<int, 16> StartOfLineColumn;
 
   // The column at which the text of a broken line should start.
   // Note that an optional decoration would go before that column.
diff --git a/lib/Format/CMakeLists.txt b/lib/Format/CMakeLists.txt
index e3ef5bd..47e15bd 100644
--- a/lib/Format/CMakeLists.txt
+++ b/lib/Format/CMakeLists.txt
@@ -8,23 +8,9 @@
   TokenAnnotator.cpp
   UnwrappedLineParser.cpp
   WhitespaceManager.cpp
-  )
 
-add_dependencies(clangFormat
-  ClangAttrClasses
-  ClangAttrList
-  ClangDeclNodes
-  ClangDiagnosticCommon
-  ClangDiagnosticFrontend
-  ClangStmtNodes
-  )
-
-target_link_libraries(clangFormat
+  LINK_LIBS
   clangBasic
-  clangFrontend
-  clangAST
-  clangASTMatchers
-  clangRewriteCore
-  clangRewriteFrontend
+  clangLex
   clangTooling
   )
diff --git a/lib/Format/ContinuationIndenter.cpp b/lib/Format/ContinuationIndenter.cpp
index 971acc2..014c30e 100644
--- a/lib/Format/ContinuationIndenter.cpp
+++ b/lib/Format/ContinuationIndenter.cpp
@@ -12,8 +12,6 @@
 ///
 //===----------------------------------------------------------------------===//
 
-#define DEBUG_TYPE "format-formatter"
-
 #include "BreakableToken.h"
 #include "ContinuationIndenter.h"
 #include "WhitespaceManager.h"
@@ -23,13 +21,15 @@
 #include "llvm/Support/Debug.h"
 #include <string>
 
+#define DEBUG_TYPE "format-formatter"
+
 namespace clang {
 namespace format {
 
 // Returns the length of everything up to the first possible line break after
 // the ), ], } or > matching \c Tok.
 static unsigned getLengthToMatchingParen(const FormatToken &Tok) {
-  if (Tok.MatchingParen == NULL)
+  if (!Tok.MatchingParen)
     return 0;
   FormatToken *End = Tok.MatchingParen;
   while (End->Next && !End->Next->CanBreakBefore) {
@@ -63,7 +63,8 @@
                                            bool BinPackInconclusiveFunctions)
     : Style(Style), SourceMgr(SourceMgr), Whitespaces(Whitespaces),
       Encoding(Encoding),
-      BinPackInconclusiveFunctions(BinPackInconclusiveFunctions) {}
+      BinPackInconclusiveFunctions(BinPackInconclusiveFunctions),
+      CommentPragmasRegex(Style.CommentPragmas) {}
 
 LineState ContinuationIndenter::getInitialState(unsigned FirstIndent,
                                                 const AnnotatedLine *Line,
@@ -77,10 +78,9 @@
                                    /*AvoidBinPacking=*/false,
                                    /*NoLineBreak=*/false));
   State.LineContainsContinuedForLoopSection = false;
-  State.ParenLevel = 0;
   State.StartOfStringLiteral = 0;
-  State.StartOfLineLevel = State.ParenLevel;
-  State.LowestLevelOnLine = State.ParenLevel;
+  State.StartOfLineLevel = 0;
+  State.LowestLevelOnLine = 0;
   State.IgnoreStackForComparison = false;
 
   // The first token has already been indented and thus consumed.
@@ -98,8 +98,8 @@
   // The opening "{" of a braced list has to be on the same line as the first
   // element if it is nested in another braced init list or function call.
   if (!Current.MustBreakBefore && Previous.is(tok::l_brace) &&
-      Previous.Type != TT_DictLiteral &&
-      Previous.BlockKind == BK_BracedInit && Previous.Previous &&
+      Previous.Type != TT_DictLiteral && Previous.BlockKind == BK_BracedInit &&
+      Previous.Previous &&
       Previous.Previous->isOneOf(tok::l_brace, tok::l_paren, tok::comma))
     return false;
   // This prevents breaks like:
@@ -107,10 +107,21 @@
   //   SomeParameter, OtherParameter).DoSomething(
   //   ...
   // As they hide "DoSomething" and are generally bad for readability.
-  if (Previous.opensScope() && State.LowestLevelOnLine < State.StartOfLineLevel)
+  if (Previous.opensScope() && Previous.isNot(tok::l_brace) &&
+      State.LowestLevelOnLine < State.StartOfLineLevel &&
+      State.LowestLevelOnLine < Current.NestingLevel)
     return false;
   if (Current.isMemberAccess() && State.Stack.back().ContainsUnwrappedBuilder)
     return false;
+
+  // Don't create a 'hanging' indent if there are multiple blocks in a single
+  // statement.
+  if (Style.Language == FormatStyle::LK_JavaScript &&
+      Previous.is(tok::l_brace) && State.Stack.size() > 1 &&
+      State.Stack[State.Stack.size() - 2].JSFunctionInlined &&
+      State.Stack[State.Stack.size() - 2].HasMultipleNestedBlocks)
+    return false;
+
   return !State.Stack.back().NoLineBreak;
 }
 
@@ -136,13 +147,21 @@
   if (Style.AlwaysBreakBeforeMultilineStrings &&
       State.Column > State.Stack.back().Indent && // Breaking saves columns.
       !Previous.isOneOf(tok::kw_return, tok::lessless, tok::at) &&
-      Previous.Type != TT_InlineASMColon && NextIsMultilineString(State))
+      Previous.Type != TT_InlineASMColon &&
+      Previous.Type != TT_ConditionalExpr && nextIsMultilineString(State))
     return true;
   if (((Previous.Type == TT_DictLiteral && Previous.is(tok::l_brace)) ||
        Previous.Type == TT_ArrayInitializerLSquare) &&
+      Style.ColumnLimit > 0 &&
       getLengthToMatchingParen(Previous) + State.Column > getColumnLimit(State))
     return true;
+  if (Current.Type == TT_CtorInitializerColon &&
+      ((Style.AllowShortFunctionsOnASingleLine != FormatStyle::SFS_All) ||
+       Style.BreakConstructorInitializersBeforeComma || Style.ColumnLimit != 0))
+    return true;
 
+  if (State.Column < getNewLineColumn(State))
+    return false;
   if (!Style.BreakBeforeBinaryOperators) {
     // If we need to break somewhere inside the LHS of a binary expression, we
     // should also break after the operator. Otherwise, the formatting would
@@ -165,38 +184,45 @@
     if (Previous.Type == TT_BinaryOperator &&
         (!IsComparison || LHSIsBinaryExpr) &&
         Current.Type != TT_BinaryOperator && // For >>.
-        !Current.isTrailingComment() &&
-        !Previous.isOneOf(tok::lessless, tok::question) &&
+        !Current.isTrailingComment() && !Previous.is(tok::lessless) &&
         Previous.getPrecedence() != prec::Assignment &&
         State.Stack.back().BreakBeforeParameter)
       return true;
   }
 
   // Same as above, but for the first "<<" operator.
-  if (Current.is(tok::lessless) && State.Stack.back().BreakBeforeParameter &&
+  if (Current.is(tok::lessless) && Current.Type != TT_OverloadedOperator &&
+      State.Stack.back().BreakBeforeParameter &&
       State.Stack.back().FirstLessLess == 0)
     return true;
 
-  // FIXME: Comparing LongestObjCSelectorName to 0 is a hacky way of finding
-  // out whether it is the first parameter. Clean this up.
-  if (Current.Type == TT_ObjCSelectorName &&
-      Current.LongestObjCSelectorName == 0 &&
+  if (Current.Type == TT_SelectorName &&
+      State.Stack.back().ObjCSelectorNameFound &&
       State.Stack.back().BreakBeforeParameter)
     return true;
-  if ((Current.Type == TT_CtorInitializerColon ||
-       (Previous.ClosesTemplateDeclaration && State.ParenLevel == 0 &&
-        !Current.isTrailingComment())))
+  if (Previous.ClosesTemplateDeclaration && Current.NestingLevel == 0 &&
+      !Current.isTrailingComment())
     return true;
 
-  if ((Current.Type == TT_StartOfName || Current.is(tok::kw_operator)) &&
-      State.Line->MightBeFunctionDecl &&
-      State.Stack.back().BreakBeforeParameter && State.ParenLevel == 0)
+  // If the return type spans multiple lines, wrap before the function name.
+  if ((Current.Type == TT_FunctionDeclarationName ||
+       Current.is(tok::kw_operator)) &&
+      State.Stack.back().BreakBeforeParameter)
     return true;
+
   if (startsSegmentOfBuilderTypeCall(Current) &&
       (State.Stack.back().CallContinuation != 0 ||
        (State.Stack.back().BreakBeforeParameter &&
         State.Stack.back().ContainsUnwrappedBuilder)))
     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.
+  if (Style.ColumnLimit != 0 && Previous.BlockKind == BK_Block &&
+      Previous.is(tok::l_brace) && !Current.isOneOf(tok::r_brace, tok::comment))
+    return true;
+
   return false;
 }
 
@@ -205,9 +231,9 @@
                                                unsigned ExtraSpaces) {
   const FormatToken &Current = *State.NextToken;
 
-  if (State.Stack.size() == 0 ||
-      (Current.Type == TT_ImplicitStringLiteral &&
-       (Current.Previous->Tok.getIdentifierInfo() == NULL ||
+  assert(!State.Stack.empty());
+  if ((Current.Type == TT_ImplicitStringLiteral &&
+       (Current.Previous->Tok.getIdentifierInfo() == nullptr ||
         Current.Previous->Tok.getIdentifierInfo()->getPPKeywordID() ==
             tok::pp_not_keyword))) {
     // FIXME: Is this correct?
@@ -215,8 +241,8 @@
                                State.NextToken->WhitespaceRange.getEnd()) -
                            SourceMgr.getSpellingColumnNumber(
                                State.NextToken->WhitespaceRange.getBegin());
-    State.Column += WhitespaceLength + State.NextToken->ColumnWidth;
-    State.NextToken = State.NextToken->Next;
+    State.Column += WhitespaceLength;
+    moveStateToNextToken(State, DryRun, /*Newline=*/false);
     return 0;
   }
 
@@ -234,7 +260,7 @@
   FormatToken &Current = *State.NextToken;
   const FormatToken &Previous = *State.NextToken->Previous;
   if (Current.is(tok::equal) &&
-      (State.Line->First->is(tok::kw_for) || State.ParenLevel == 0) &&
+      (State.Line->First->is(tok::kw_for) || Current.NestingLevel == 0) &&
       State.Stack.back().VariablePos == 0) {
     State.Stack.back().VariablePos = State.Column;
     // Move over * and & if they are bound to the variable name.
@@ -255,9 +281,12 @@
     Whitespaces.replaceWhitespace(Current, /*Newlines=*/0, /*IndentLevel=*/0,
                                   Spaces, State.Column + Spaces);
 
-  if (Current.Type == TT_ObjCSelectorName && State.Stack.back().ColonPos == 0) {
-    if (State.Stack.back().Indent + Current.LongestObjCSelectorName >
-        State.Column + Spaces + Current.ColumnWidth)
+  if (Current.Type == TT_SelectorName &&
+      !State.Stack.back().ObjCSelectorNameFound) {
+    if (Current.LongestObjCSelectorName == 0)
+      State.Stack.back().AlignColons = false;
+    else if (State.Stack.back().Indent + Current.LongestObjCSelectorName >
+             State.Column + Spaces + Current.ColumnWidth)
       State.Stack.back().ColonPos =
           State.Stack.back().Indent + Current.LongestObjCSelectorName;
     else
@@ -265,7 +294,7 @@
   }
 
   if (Previous.opensScope() && Previous.Type != TT_ObjCMethodExpr &&
-      Current.Type != TT_LineComment)
+      (Current.Type != TT_LineComment || Previous.BlockKind == BK_BracedInit))
     State.Stack.back().Indent = State.Column + Spaces;
   if (State.Stack.back().AvoidBinPacking && startsNextParameter(Current, Style))
     State.Stack.back().NoLineBreak = true;
@@ -273,17 +302,21 @@
     State.Stack.back().ContainsUnwrappedBuilder = true;
 
   State.Column += Spaces;
-  if (Current.is(tok::l_paren) && Previous.isOneOf(tok::kw_if, tok::kw_for))
+  if (Current.isNot(tok::comment) && Previous.is(tok::l_paren) &&
+      Previous.Previous && Previous.Previous->isOneOf(tok::kw_if, tok::kw_for))
     // Treat the condition inside an if as if it was a second function
     // parameter, i.e. let nested calls have a continuation indent.
-    State.Stack.back().LastSpace = State.Column + 1; // 1 is length of "(".
-  else if (Previous.is(tok::comma) || Previous.Type == TT_ObjCMethodExpr)
+    State.Stack.back().LastSpace = State.Column;
+  else if (!Current.isOneOf(tok::comment, tok::caret) &&
+           (Previous.is(tok::comma) ||
+            (Previous.is(tok::colon) && Previous.Type == TT_ObjCMethodExpr)))
     State.Stack.back().LastSpace = State.Column;
   else if ((Previous.Type == TT_BinaryOperator ||
             Previous.Type == TT_ConditionalExpr ||
-            Previous.Type == TT_UnaryOperator ||
             Previous.Type == TT_CtorInitializerColon) &&
-           (Previous.getPrecedence() != prec::Assignment ||
+           ((Previous.getPrecedence() != prec::Assignment &&
+             (Previous.isNot(tok::lessless) || Previous.OperatorIndex != 0 ||
+              !Previous.LastOperator)) ||
             Current.StartsBinaryExpression))
     // Always indent relative to the RHS of the expression unless this is a
     // simple assignment without binary expression on the RHS. Also indent
@@ -313,17 +346,16 @@
                                                  bool DryRun) {
   FormatToken &Current = *State.NextToken;
   const FormatToken &Previous = *State.NextToken->Previous;
-  // If we are continuing an expression, we want to use the continuation indent.
-  unsigned ContinuationIndent =
-      std::max(State.Stack.back().LastSpace, State.Stack.back().Indent) +
-      Style.ContinuationIndentWidth;
+
   // Extra penalty that needs to be added because of the way certain line
   // breaks are chosen.
   unsigned Penalty = 0;
 
-  const FormatToken *PreviousNonComment =
-      State.NextToken->getPreviousNonComment();
-  // The first line break on any ParenLevel causes an extra penalty in order
+  const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
+  const FormatToken *NextNonComment = Previous.getNextNonComment();
+  if (!NextNonComment)
+    NextNonComment = &Current;
+  // The first line break on any NestingLevel causes an extra penalty in order
   // prefer similar line breaks.
   if (!State.Stack.back().ContainsLineBreak)
     Penalty += 15;
@@ -332,96 +364,61 @@
   Penalty += State.NextToken->SplitPenalty;
 
   // Breaking before the first "<<" is generally not desirable if the LHS is
-  // short.
-  if (Current.is(tok::lessless) && State.Stack.back().FirstLessLess == 0 &&
-      State.Column <= Style.ColumnLimit / 2)
+  // short. Also always add the penalty if the LHS is split over mutliple lines
+  // to avoid unnecessary line breaks that just work around this penalty.
+  if (NextNonComment->is(tok::lessless) &&
+      State.Stack.back().FirstLessLess == 0 &&
+      (State.Column <= Style.ColumnLimit / 3 ||
+       State.Stack.back().BreakBeforeParameter))
     Penalty += Style.PenaltyBreakFirstLessLess;
 
-  if (Current.is(tok::l_brace) && Current.BlockKind == BK_Block) {
-    State.Column = State.FirstIndent;
-  } else if (Current.isOneOf(tok::r_brace, tok::r_square)) {
-    if (Current.closesBlockTypeList(Style) ||
-        (Current.MatchingParen &&
-         Current.MatchingParen->BlockKind == BK_BracedInit))
-      State.Column = State.Stack[State.Stack.size() - 2].LastSpace;
-    else
-      State.Column = State.FirstIndent;
-  } else if (Current.is(tok::string_literal) &&
-             State.StartOfStringLiteral != 0) {
-    State.Column = State.StartOfStringLiteral;
-    State.Stack.back().BreakBeforeParameter = true;
-  } else if (Current.is(tok::lessless) &&
-             State.Stack.back().FirstLessLess != 0) {
-    State.Column = State.Stack.back().FirstLessLess;
-  } else if (Current.isMemberAccess()) {
-    if (State.Stack.back().CallContinuation == 0) {
-      State.Column = ContinuationIndent;
+  State.Column = getNewLineColumn(State);
+  if (NextNonComment->isMemberAccess()) {
+    if (State.Stack.back().CallContinuation == 0)
       State.Stack.back().CallContinuation = State.Column;
-    } else {
-      State.Column = State.Stack.back().CallContinuation;
+  } else if (NextNonComment->Type == TT_SelectorName) {
+    if (!State.Stack.back().ObjCSelectorNameFound) {
+      if (NextNonComment->LongestObjCSelectorName == 0) {
+        State.Stack.back().AlignColons = false;
+      } else {
+        State.Stack.back().ColonPos =
+            State.Stack.back().Indent + NextNonComment->LongestObjCSelectorName;
+      }
+    } else if (State.Stack.back().AlignColons &&
+               State.Stack.back().ColonPos <= NextNonComment->ColumnWidth) {
+      State.Stack.back().ColonPos = State.Column + NextNonComment->ColumnWidth;
     }
-  } else if (State.Stack.back().QuestionColumn != 0 &&
-             (Current.Type == TT_ConditionalExpr ||
-              Previous.Type == TT_ConditionalExpr)) {
-    State.Column = State.Stack.back().QuestionColumn;
-  } else if (Previous.is(tok::comma) && State.Stack.back().VariablePos != 0) {
-    State.Column = State.Stack.back().VariablePos;
-  } else if ((PreviousNonComment &&
-              PreviousNonComment->ClosesTemplateDeclaration) ||
-             ((Current.Type == TT_StartOfName ||
-               Current.is(tok::kw_operator)) &&
-              State.ParenLevel == 0 &&
-              (!Style.IndentFunctionDeclarationAfterType ||
-               State.Line->StartsDefinition))) {
-    State.Column = State.Stack.back().Indent;
-  } else if (Current.Type == TT_ObjCSelectorName) {
-    if (State.Stack.back().ColonPos == 0) {
-      State.Stack.back().ColonPos =
-          State.Stack.back().Indent + Current.LongestObjCSelectorName;
-      State.Column = State.Stack.back().ColonPos - Current.ColumnWidth;
-    } else if (State.Stack.back().ColonPos > Current.ColumnWidth) {
-      State.Column = State.Stack.back().ColonPos - Current.ColumnWidth;
-    } else {
-      State.Column = State.Stack.back().Indent;
-      State.Stack.back().ColonPos = State.Column + Current.ColumnWidth;
-    }
-  } else if (Current.Type == TT_ArraySubscriptLSquare) {
-    if (State.Stack.back().StartOfArraySubscripts != 0)
-      State.Column = State.Stack.back().StartOfArraySubscripts;
-    else
-      State.Column = ContinuationIndent;
-  } else if (Current.Type == TT_StartOfName ||
-             Previous.isOneOf(tok::coloncolon, tok::equal) ||
-             Previous.Type == TT_ObjCMethodExpr) {
-    State.Column = ContinuationIndent;
-  } else if (Current.Type == TT_CtorInitializerColon) {
-    State.Column = State.FirstIndent + Style.ConstructorInitializerIndentWidth;
-  } else if (Current.Type == TT_CtorInitializerComma) {
-    State.Column = State.Stack.back().Indent;
-  } else {
-    State.Column = State.Stack.back().Indent;
-    // Ensure that we fall back to the continuation indent width instead of just
-    // flushing continuations left.
-    if (State.Column == State.FirstIndent &&
-        PreviousNonComment->isNot(tok::r_brace))
-      State.Column += Style.ContinuationIndentWidth;
+  } else if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
+             (PreviousNonComment->Type == TT_ObjCMethodExpr ||
+              PreviousNonComment->Type == TT_DictLiteral)) {
+    // FIXME: This is hacky, find a better way. The problem is that in an ObjC
+    // method expression, the block should be aligned to the line starting it,
+    // e.g.:
+    //   [aaaaaaaaaaaaaaa aaaaaaaaa: \\ break for some reason
+    //                        ^(int *i) {
+    //                            // ...
+    //                        }];
+    // Thus, we set LastSpace of the next higher NestingLevel, to which we move
+    // when we consume all of the "}"'s FakeRParens at the "{".
+    if (State.Stack.size() > 1)
+      State.Stack[State.Stack.size() - 2].LastSpace =
+          std::max(State.Stack.back().LastSpace, State.Stack.back().Indent) +
+          Style.ContinuationIndentWidth;
   }
 
   if ((Previous.isOneOf(tok::comma, tok::semi) &&
        !State.Stack.back().AvoidBinPacking) ||
       Previous.Type == TT_BinaryOperator)
     State.Stack.back().BreakBeforeParameter = false;
-  if (Previous.Type == TT_TemplateCloser && State.ParenLevel == 0)
+  if (Previous.Type == TT_TemplateCloser && Current.NestingLevel == 0)
     State.Stack.back().BreakBeforeParameter = false;
-  if (Current.is(tok::question) ||
+  if (NextNonComment->is(tok::question) ||
       (PreviousNonComment && PreviousNonComment->is(tok::question)))
     State.Stack.back().BreakBeforeParameter = true;
 
   if (!DryRun) {
-    unsigned Newlines = 1;
-    if (Current.is(tok::comment))
-      Newlines = std::max(Newlines, std::min(Current.NewlinesBefore,
-                                             Style.MaxEmptyLinesToKeep + 1));
+    unsigned Newlines = std::max(
+        1u, std::min(Current.NewlinesBefore, Style.MaxEmptyLinesToKeep + 1));
     Whitespaces.replaceWhitespace(Current, Newlines,
                                   State.Stack.back().IndentLevel, State.Column,
                                   State.Column, State.Line->InPPDirective);
@@ -429,51 +426,164 @@
 
   if (!Current.isTrailingComment())
     State.Stack.back().LastSpace = State.Column;
-  if (Current.isMemberAccess())
-    State.Stack.back().LastSpace += Current.ColumnWidth;
-  State.StartOfLineLevel = State.ParenLevel;
-  State.LowestLevelOnLine = State.ParenLevel;
+  State.StartOfLineLevel = Current.NestingLevel;
+  State.LowestLevelOnLine = Current.NestingLevel;
 
   // Any break on this level means that the parent level has been broken
   // and we need to avoid bin packing there.
-  for (unsigned i = 0, e = State.Stack.size() - 1; i != e; ++i) {
-    State.Stack[i].BreakBeforeParameter = true;
+  bool JavaScriptFormat = Style.Language == FormatStyle::LK_JavaScript &&
+                          Current.is(tok::r_brace) &&
+                          State.Stack.size() > 1 &&
+                          State.Stack[State.Stack.size() - 2].JSFunctionInlined;
+  if (!JavaScriptFormat) {
+    for (unsigned i = 0, e = State.Stack.size() - 1; i != e; ++i) {
+      State.Stack[i].BreakBeforeParameter = true;
+    }
   }
+
   if (PreviousNonComment &&
       !PreviousNonComment->isOneOf(tok::comma, tok::semi) &&
       PreviousNonComment->Type != TT_TemplateCloser &&
       PreviousNonComment->Type != TT_BinaryOperator &&
-      Current.Type != TT_BinaryOperator && 
-      !PreviousNonComment->opensScope())
+      Current.Type != TT_BinaryOperator && !PreviousNonComment->opensScope())
     State.Stack.back().BreakBeforeParameter = true;
 
   // If we break after { or the [ of an array initializer, we should also break
   // before the corresponding } or ].
-  if (Previous.is(tok::l_brace) || Previous.Type == TT_ArrayInitializerLSquare)
+  if (PreviousNonComment &&
+      (PreviousNonComment->is(tok::l_brace) ||
+       PreviousNonComment->Type == TT_ArrayInitializerLSquare))
     State.Stack.back().BreakBeforeClosingBrace = true;
 
   if (State.Stack.back().AvoidBinPacking) {
     // If we are breaking after '(', '{', '<', this is not bin packing
-    // unless AllowAllParametersOfDeclarationOnNextLine is false.
+    // unless AllowAllParametersOfDeclarationOnNextLine is false or this is a
+    // dict/object literal.
     if (!(Previous.isOneOf(tok::l_paren, tok::l_brace) ||
           Previous.Type == TT_BinaryOperator) ||
         (!Style.AllowAllParametersOfDeclarationOnNextLine &&
-         State.Line->MustBeDeclaration))
+         State.Line->MustBeDeclaration) ||
+        Previous.Type == TT_DictLiteral)
       State.Stack.back().BreakBeforeParameter = true;
   }
 
   return Penalty;
 }
 
+unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) {
+  if (!State.NextToken || !State.NextToken->Previous)
+    return 0;
+  FormatToken &Current = *State.NextToken;
+  const FormatToken &Previous = *State.NextToken->Previous;
+  // If we are continuing an expression, we want to use the continuation indent.
+  unsigned ContinuationIndent =
+      std::max(State.Stack.back().LastSpace, State.Stack.back().Indent) +
+      Style.ContinuationIndentWidth;
+  const FormatToken *PreviousNonComment = Current.getPreviousNonComment();
+  const FormatToken *NextNonComment = Previous.getNextNonComment();
+  if (!NextNonComment)
+    NextNonComment = &Current;
+  if (NextNonComment->is(tok::l_brace) && NextNonComment->BlockKind == BK_Block)
+    return Current.NestingLevel == 0 ? State.FirstIndent
+                                     : State.Stack.back().Indent;
+  if (Current.isOneOf(tok::r_brace, tok::r_square)) {
+    if (State.Stack.size() > 1 &&
+        State.Stack[State.Stack.size() - 2].JSFunctionInlined)
+      return State.FirstIndent;
+    if (Current.closesBlockTypeList(Style) ||
+        (Current.MatchingParen &&
+         Current.MatchingParen->BlockKind == BK_BracedInit))
+      return State.Stack[State.Stack.size() - 2].LastSpace;
+    else
+      return State.FirstIndent;
+  }
+  if (Current.is(tok::identifier) && Current.Next &&
+      Current.Next->Type == TT_DictLiteral)
+    return State.Stack.back().Indent;
+  if (NextNonComment->isStringLiteral() && State.StartOfStringLiteral != 0)
+    return State.StartOfStringLiteral;
+  if (NextNonComment->is(tok::lessless) &&
+      State.Stack.back().FirstLessLess != 0)
+    return State.Stack.back().FirstLessLess;
+  if (NextNonComment->isMemberAccess()) {
+    if (State.Stack.back().CallContinuation == 0) {
+      return ContinuationIndent;
+    } else {
+      return State.Stack.back().CallContinuation;
+    }
+  }
+  if (State.Stack.back().QuestionColumn != 0 &&
+      ((NextNonComment->is(tok::colon) &&
+        NextNonComment->Type == TT_ConditionalExpr) ||
+       Previous.Type == TT_ConditionalExpr))
+    return State.Stack.back().QuestionColumn;
+  if (Previous.is(tok::comma) && State.Stack.back().VariablePos != 0)
+    return State.Stack.back().VariablePos;
+  if ((PreviousNonComment && (PreviousNonComment->ClosesTemplateDeclaration ||
+                              PreviousNonComment->Type == TT_AttributeParen)) ||
+      (!Style.IndentWrappedFunctionNames &&
+       (NextNonComment->is(tok::kw_operator) ||
+        NextNonComment->Type == TT_FunctionDeclarationName)))
+    return std::max(State.Stack.back().LastSpace, State.Stack.back().Indent);
+  if (NextNonComment->Type == TT_SelectorName) {
+    if (!State.Stack.back().ObjCSelectorNameFound) {
+      if (NextNonComment->LongestObjCSelectorName == 0) {
+        return State.Stack.back().Indent;
+      } else {
+        return State.Stack.back().Indent +
+               NextNonComment->LongestObjCSelectorName -
+               NextNonComment->ColumnWidth;
+      }
+    } else if (!State.Stack.back().AlignColons) {
+      return State.Stack.back().Indent;
+    } else if (State.Stack.back().ColonPos > NextNonComment->ColumnWidth) {
+      return State.Stack.back().ColonPos - NextNonComment->ColumnWidth;
+    } else {
+      return State.Stack.back().Indent;
+    }
+  }
+  if (NextNonComment->Type == TT_ArraySubscriptLSquare) {
+    if (State.Stack.back().StartOfArraySubscripts != 0)
+      return State.Stack.back().StartOfArraySubscripts;
+    else
+      return ContinuationIndent;
+  }
+  if (NextNonComment->Type == TT_StartOfName ||
+      Previous.isOneOf(tok::coloncolon, tok::equal)) {
+    return ContinuationIndent;
+  }
+  if (PreviousNonComment && PreviousNonComment->is(tok::colon) &&
+      (PreviousNonComment->Type == TT_ObjCMethodExpr ||
+       PreviousNonComment->Type == TT_DictLiteral))
+    return ContinuationIndent;
+  if (NextNonComment->Type == TT_CtorInitializerColon)
+    return State.FirstIndent + Style.ConstructorInitializerIndentWidth;
+  if (NextNonComment->Type == TT_CtorInitializerComma)
+    return State.Stack.back().Indent;
+  if (State.Stack.back().Indent == State.FirstIndent && PreviousNonComment &&
+      PreviousNonComment->isNot(tok::r_brace))
+    // Ensure that we fall back to the continuation indent width instead of
+    // just flushing continuations left.
+    return State.Stack.back().Indent + Style.ContinuationIndentWidth;
+  return State.Stack.back().Indent;
+}
+
 unsigned ContinuationIndenter::moveStateToNextToken(LineState &State,
                                                     bool DryRun, bool Newline) {
-  const FormatToken &Current = *State.NextToken;
   assert(State.Stack.size());
+  const FormatToken &Current = *State.NextToken;
 
   if (Current.Type == TT_InheritanceColon)
     State.Stack.back().AvoidBinPacking = true;
-  if (Current.is(tok::lessless) && State.Stack.back().FirstLessLess == 0)
-    State.Stack.back().FirstLessLess = State.Column;
+  if (Current.is(tok::lessless) && Current.Type != TT_OverloadedOperator) {
+    if (State.Stack.back().FirstLessLess == 0)
+      State.Stack.back().FirstLessLess = State.Column;
+    else
+      State.Stack.back().LastOperatorWrapped = Newline;
+  }
+  if ((Current.Type == TT_BinaryOperator && Current.isNot(tok::lessless)) ||
+      Current.Type == TT_ConditionalExpr)
+    State.Stack.back().LastOperatorWrapped = Newline;
   if (Current.Type == TT_ArraySubscriptLSquare &&
       State.Stack.back().StartOfArraySubscripts == 0)
     State.Stack.back().StartOfArraySubscripts = State.Column;
@@ -484,10 +594,12 @@
     State.Stack.back().QuestionColumn = State.Column;
   if (!Current.opensScope() && !Current.closesScope())
     State.LowestLevelOnLine =
-        std::min(State.LowestLevelOnLine, State.ParenLevel);
+        std::min(State.LowestLevelOnLine, Current.NestingLevel);
   if (Current.isMemberAccess())
     State.Stack.back().StartOfFunctionCall =
-        Current.LastInChainOfCalls ? 0 : State.Column + Current.ColumnWidth;
+        Current.LastOperator ? 0 : State.Column + Current.ColumnWidth;
+  if (Current.Type == TT_SelectorName)
+    State.Stack.back().ObjCSelectorNameFound = true;
   if (Current.Type == TT_CtorInitializerColon) {
     // Indent 2 from the column, so:
     // SomeClass::SomeClass()
@@ -509,8 +621,67 @@
 
   // Insert scopes created by fake parenthesis.
   const FormatToken *Previous = Current.getPreviousNonComment();
+
+  // Add special behavior to support a format commonly used for JavaScript
+  // closures:
+  //   SomeFunction(function() {
+  //     foo();
+  //     bar();
+  //   }, a, b, c);
+  if (Style.Language == FormatStyle::LK_JavaScript) {
+    if (Current.isNot(tok::comment) && Previous && Previous->is(tok::l_brace) &&
+        State.Stack.size() > 1) {
+      if (State.Stack[State.Stack.size() - 2].JSFunctionInlined && Newline) {
+        for (unsigned i = 0, e = State.Stack.size() - 1; i != e; ++i) {
+          State.Stack[i].NoLineBreak = true;
+        }
+      }
+      State.Stack[State.Stack.size() - 2].JSFunctionInlined = false;
+    }
+    if (Current.TokenText == "function")
+      State.Stack.back().JSFunctionInlined = !Newline;
+  }
+
+  moveStatePastFakeLParens(State, Newline);
+  moveStatePastScopeOpener(State, Newline);
+  moveStatePastScopeCloser(State);
+  moveStatePastFakeRParens(State);
+
+  if (Current.isStringLiteral() && State.StartOfStringLiteral == 0) {
+    State.StartOfStringLiteral = State.Column;
+  } else if (!Current.isOneOf(tok::comment, tok::identifier, tok::hash) &&
+             !Current.isStringLiteral()) {
+    State.StartOfStringLiteral = 0;
+  }
+
+  State.Column += Current.ColumnWidth;
+  State.NextToken = State.NextToken->Next;
+  unsigned Penalty = breakProtrudingToken(Current, State, DryRun);
+  if (State.Column > getColumnLimit(State)) {
+    unsigned ExcessCharacters = State.Column - getColumnLimit(State);
+    Penalty += Style.PenaltyExcessCharacter * ExcessCharacters;
+  }
+
+  if (Current.Role)
+    Current.Role->formatFromToken(State, this, DryRun);
+  // If the previous has a special role, let it consume tokens as appropriate.
+  // It is necessary to start at the previous token for the only implemented
+  // role (comma separated list). That way, the decision whether or not to break
+  // after the "{" is already done and both options are tried and evaluated.
+  // FIXME: This is ugly, find a better way.
+  if (Previous && Previous->Role)
+    Penalty += Previous->Role->formatAfterToken(State, this, DryRun);
+
+  return Penalty;
+}
+
+void ContinuationIndenter::moveStatePastFakeLParens(LineState &State,
+                                                    bool Newline) {
+  const FormatToken &Current = *State.NextToken;
+  const FormatToken *Previous = Current.getPreviousNonComment();
+
   // Don't add extra indentation for the first fake parenthesis after
-  // 'return', assignements or opening <({[. The indentation for these cases
+  // 'return', assignments or opening <({[. The indentation for these cases
   // is special cased.
   bool SkipFirstExtraIndent =
       (Previous && (Previous->opensScope() || Previous->is(tok::kw_return) ||
@@ -531,6 +702,24 @@
           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->Type == TT_BinaryOperator ||
+         Previous->Type == TT_ConditionalExpr) &&
+        Previous->getPrecedence() != prec::Relational) {
+      bool BreakBeforeOperator = Previous->is(tok::lessless) ||
+                                 (Previous->Type == TT_BinaryOperator &&
+                                  Style.BreakBeforeBinaryOperators) ||
+                                 (Previous->Type == 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
@@ -539,6 +728,7 @@
     //       ParameterToInnerFunction));
     if (*I > prec::Unknown)
       NewParenState.LastSpace = std::max(NewParenState.LastSpace, State.Column);
+    NewParenState.StartOfFunctionCall = State.Column;
 
     // Always indent conditional expressions. Never indent expression where
     // the 'operator' is ',', ';' or an assignment (i.e. *I <=
@@ -553,131 +743,160 @@
     State.Stack.push_back(NewParenState);
     SkipFirstExtraIndent = false;
   }
+}
 
-  // If we encounter an opening (, [, { or <, we add a level to our stacks to
-  // prepare for the following tokens.
-  if (Current.opensScope()) {
-    unsigned NewIndent;
-    unsigned NewIndentLevel = State.Stack.back().IndentLevel;
-    bool AvoidBinPacking;
-    bool BreakBeforeParameter = false;
-    if (Current.is(tok::l_brace) ||
-        Current.Type == TT_ArrayInitializerLSquare) {
-      if (Current.MatchingParen && Current.BlockKind == BK_Block) {
-        // If this is an l_brace starting a nested block, we pretend (wrt. to
-        // indentation) that we already consumed the corresponding r_brace.
-        // Thus, we remove all ParenStates caused bake fake parentheses that end
-        // at the r_brace. The net effect of this is that we don't indent
-        // relative to the l_brace, if the nested block is the last parameter of
-        // a function. For example, this formats:
-        //
-        //   SomeFunction(a, [] {
-        //     f();  // break
-        //   });
-        //
-        // instead of:
-        //   SomeFunction(a, [] {
-        //                        f();  // break
-        //                      });
-        for (unsigned i = 0; i != Current.MatchingParen->FakeRParens; ++i)
-          State.Stack.pop_back();
-        NewIndent = State.Stack.back().LastSpace + Style.IndentWidth;
-        ++NewIndentLevel;
-        BreakBeforeParameter = true;
-      } else {
-        NewIndent = State.Stack.back().LastSpace;
-        if (Current.opensBlockTypeList(Style)) {
-          NewIndent += Style.IndentWidth;
-          ++NewIndentLevel;
-        } else {
-          NewIndent += Style.ContinuationIndentWidth;
-        }
-      }
-      const FormatToken *NextNoComment = Current.getNextNonComment();
-      AvoidBinPacking = Current.BlockKind == BK_Block ||
-                        Current.Type == TT_ArrayInitializerLSquare ||
-                        Current.Type == TT_DictLiteral ||
-                        (NextNoComment &&
-                         NextNoComment->Type == TT_DesignatedInitializerPeriod);
-    } else {
-      NewIndent = Style.ContinuationIndentWidth +
-                  std::max(State.Stack.back().LastSpace,
-                           State.Stack.back().StartOfFunctionCall);
-      AvoidBinPacking = !Style.BinPackParameters ||
-                        (Style.ExperimentalAutoDetectBinPacking &&
-                         (Current.PackingKind == PPK_OnePerLine ||
-                          (!BinPackInconclusiveFunctions &&
-                           Current.PackingKind == PPK_Inconclusive)));
-      // If this '[' opens an ObjC call, determine whether all parameters fit
-      // into one line and put one per line if they don't.
-      if (Current.Type == TT_ObjCMethodExpr &&
-          getLengthToMatchingParen(Current) + State.Column >
-              getColumnLimit(State))
-        BreakBeforeParameter = true;
+// Remove the fake r_parens after 'Tok'.
+static void consumeRParens(LineState& State, const FormatToken &Tok) {
+  for (unsigned i = 0, e = Tok.FakeRParens; i != e; ++i) {
+    unsigned VariablePos = State.Stack.back().VariablePos;
+    assert(State.Stack.size() > 1);
+    if (State.Stack.size() == 1) {
+      // Do not pop the last element.
+      break;
     }
-
-    bool NoLineBreak = State.Stack.back().NoLineBreak ||
-                       (Current.Type == TT_TemplateOpener &&
-                        State.Stack.back().ContainsUnwrappedBuilder);
-    State.Stack.push_back(ParenState(NewIndent, NewIndentLevel,
-                                     State.Stack.back().LastSpace,
-                                     AvoidBinPacking, NoLineBreak));
-    State.Stack.back().BreakBeforeParameter = BreakBeforeParameter;
-    ++State.ParenLevel;
+    State.Stack.pop_back();
+    State.Stack.back().VariablePos = VariablePos;
   }
+}
+
+// Returns whether 'Tok' opens or closes a scope requiring special handling
+// of the subsequent fake r_parens.
+//
+// For example, if this is an l_brace starting a nested block, we pretend (wrt.
+// to indentation) that we already consumed the corresponding r_brace. Thus, we
+// remove all ParenStates caused by fake parentheses that end at the r_brace.
+// The net effect of this is that we don't indent relative to the l_brace, if
+// the nested block is the last parameter of a function. This formats:
+//
+//   SomeFunction(a, [] {
+//     f();  // break
+//   });
+//
+// instead of:
+//   SomeFunction(a, [] {
+//                     f();  // break
+//                   });
+static bool fakeRParenSpecialCase(const LineState &State) {
+  const FormatToken &Tok = *State.NextToken;
+  if (!Tok.MatchingParen)
+    return false;
+  const FormatToken *Left = &Tok;
+  if (Tok.isOneOf(tok::r_brace, tok::r_square))
+    Left = Tok.MatchingParen;
+  return !State.Stack.back().HasMultipleNestedBlocks &&
+         Left->isOneOf(tok::l_brace, tok::l_square) &&
+         (Left->BlockKind == BK_Block ||
+          Left->Type == TT_ArrayInitializerLSquare ||
+          Left->Type == TT_DictLiteral);
+}
+
+void ContinuationIndenter::moveStatePastFakeRParens(LineState &State) {
+  // Don't remove FakeRParens attached to r_braces that surround nested blocks
+  // as they will have been removed early (see above).
+  if (fakeRParenSpecialCase(State))
+    return;
+
+  consumeRParens(State, *State.NextToken);
+}
+
+void ContinuationIndenter::moveStatePastScopeOpener(LineState &State,
+                                                    bool Newline) {
+  const FormatToken &Current = *State.NextToken;
+  if (!Current.opensScope())
+    return;
+
+  if (Current.MatchingParen && Current.BlockKind == BK_Block) {
+    moveStateToNewBlock(State);
+    return;
+  }
+
+  unsigned NewIndent;
+  unsigned NewIndentLevel = State.Stack.back().IndentLevel;
+  bool AvoidBinPacking;
+  bool BreakBeforeParameter = false;
+  if (Current.is(tok::l_brace) || Current.Type == TT_ArrayInitializerLSquare) {
+    if (fakeRParenSpecialCase(State))
+      consumeRParens(State, *Current.MatchingParen);
+
+    NewIndent = State.Stack.back().LastSpace;
+    if (Current.opensBlockTypeList(Style)) {
+      NewIndent += Style.IndentWidth;
+      NewIndent = std::min(State.Column + 2, NewIndent);
+      ++NewIndentLevel;
+    } else {
+      NewIndent += Style.ContinuationIndentWidth;
+      NewIndent = std::min(State.Column + 1, NewIndent);
+    }
+    const FormatToken *NextNoComment = Current.getNextNonComment();
+    AvoidBinPacking = Current.Type == TT_ArrayInitializerLSquare ||
+                      Current.Type == TT_DictLiteral ||
+                      Style.Language == FormatStyle::LK_Proto ||
+                      !Style.BinPackParameters ||
+                      (NextNoComment &&
+                       NextNoComment->Type == TT_DesignatedInitializerPeriod);
+  } else {
+    NewIndent = Style.ContinuationIndentWidth +
+                std::max(State.Stack.back().LastSpace,
+                         State.Stack.back().StartOfFunctionCall);
+    AvoidBinPacking = !Style.BinPackParameters ||
+                      (Style.ExperimentalAutoDetectBinPacking &&
+                       (Current.PackingKind == PPK_OnePerLine ||
+                        (!BinPackInconclusiveFunctions &&
+                         Current.PackingKind == PPK_Inconclusive)));
+    // If this '[' opens an ObjC call, determine whether all parameters fit
+    // into one line and put one per line if they don't.
+    if (Current.Type == TT_ObjCMethodExpr && Style.ColumnLimit != 0 &&
+        getLengthToMatchingParen(Current) + State.Column >
+            getColumnLimit(State))
+      BreakBeforeParameter = true;
+  }
+  bool NoLineBreak = State.Stack.back().NoLineBreak ||
+                     (Current.Type == TT_TemplateOpener &&
+                      State.Stack.back().ContainsUnwrappedBuilder);
+  State.Stack.push_back(ParenState(NewIndent, NewIndentLevel,
+                                   State.Stack.back().LastSpace,
+                                   AvoidBinPacking, NoLineBreak));
+  State.Stack.back().BreakBeforeParameter = BreakBeforeParameter;
+  State.Stack.back().HasMultipleNestedBlocks = Current.BlockParameterCount > 1;
+}
+
+void ContinuationIndenter::moveStatePastScopeCloser(LineState &State) {
+  const FormatToken &Current = *State.NextToken;
+  if (!Current.closesScope())
+    return;
 
   // 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.is(tok::r_brace) && State.NextToken != State.Line->First) ||
-       State.NextToken->Type == TT_TemplateCloser)) {
+       State.NextToken->Type == TT_TemplateCloser))
     State.Stack.pop_back();
-    --State.ParenLevel;
-  }
+
   if (Current.is(tok::r_square)) {
     // If this ends the array subscript expr, reset the corresponding value.
     const FormatToken *NextNonComment = Current.getNextNonComment();
     if (NextNonComment && NextNonComment->isNot(tok::l_square))
       State.Stack.back().StartOfArraySubscripts = 0;
   }
+}
 
-  // Remove scopes created by fake parenthesis.
-  if (Current.isNot(tok::r_brace) ||
-      (Current.MatchingParen && Current.MatchingParen->BlockKind != BK_Block)) {
-    // Don't remove FakeRParens attached to r_braces that surround nested blocks
-    // as they will have been removed early (see above).
-    for (unsigned i = 0, e = Current.FakeRParens; i != e; ++i) {
-      unsigned VariablePos = State.Stack.back().VariablePos;
-      State.Stack.pop_back();
-      State.Stack.back().VariablePos = VariablePos;
-    }
-  }
+void ContinuationIndenter::moveStateToNewBlock(LineState &State) {
+  // If we have already found more than one lambda introducers on this level, we
+  // opt out of this because similarity between the lambdas is more important.
+  if (fakeRParenSpecialCase(State))
+    consumeRParens(State, *State.NextToken->MatchingParen);
 
-  if (Current.is(tok::string_literal) && State.StartOfStringLiteral == 0) {
-    State.StartOfStringLiteral = State.Column;
-  } else if (!Current.isOneOf(tok::comment, tok::identifier, tok::hash,
-                              tok::string_literal)) {
-    State.StartOfStringLiteral = 0;
-  }
-
-  State.Column += Current.ColumnWidth;
-  State.NextToken = State.NextToken->Next;
-  unsigned Penalty = breakProtrudingToken(Current, State, DryRun);
-  if (State.Column > getColumnLimit(State)) {
-    unsigned ExcessCharacters = State.Column - getColumnLimit(State);
-    Penalty += Style.PenaltyExcessCharacter * ExcessCharacters;
-  }
-
-  // If the previous has a special role, let it consume tokens as appropriate.
-  // It is necessary to start at the previous token for the only implemented
-  // role (comma separated list). That way, the decision whether or not to break
-  // after the "{" is already done and both options are tried and evaluated.
-  // FIXME: This is ugly, find a better way.
-  if (Previous && Previous->Role)
-    Penalty += Previous->Role->format(State, this, DryRun);
-
-  return Penalty;
+  // For some reason, ObjC blocks are indented like continuations.
+  unsigned NewIndent = State.Stack.back().LastSpace +
+                       (State.NextToken->Type == TT_ObjCBlockLBrace
+                            ? Style.ContinuationIndentWidth
+                            : Style.IndentWidth);
+  State.Stack.push_back(ParenState(
+      NewIndent, /*NewIndentLevel=*/State.Stack.back().IndentLevel + 1,
+      State.Stack.back().LastSpace, /*AvoidBinPacking=*/true,
+      State.Stack.back().NoLineBreak));
+  State.Stack.back().BreakBeforeParameter = true;
 }
 
 unsigned ContinuationIndenter::addMultilineToken(const FormatToken &Current,
@@ -696,8 +915,7 @@
   return 0;
 }
 
-static bool getRawStringLiteralPrefixPostfix(StringRef Text,
-                                             StringRef &Prefix,
+static bool getRawStringLiteralPrefixPostfix(StringRef Text, StringRef &Prefix,
                                              StringRef &Postfix) {
   if (Text.startswith(Prefix = "R\"") || Text.startswith(Prefix = "uR\"") ||
       Text.startswith(Prefix = "UR\"") || Text.startswith(Prefix = "u8R\"") ||
@@ -727,19 +945,14 @@
   if (Current.Type == TT_ImplicitStringLiteral)
     return 0;
 
-  if (!Current.isOneOf(tok::string_literal, tok::wide_string_literal,
-                       tok::utf8_string_literal, tok::utf16_string_literal,
-                       tok::utf32_string_literal, tok::comment))
+  if (!Current.isStringLiteral() && !Current.is(tok::comment))
     return 0;
 
-  llvm::OwningPtr<BreakableToken> Token;
+  std::unique_ptr<BreakableToken> Token;
   unsigned StartColumn = State.Column - Current.ColumnWidth;
   unsigned ColumnLimit = getColumnLimit(State);
 
-  if (Current.isOneOf(tok::string_literal, tok::wide_string_literal,
-                      tok::utf8_string_literal, tok::utf16_string_literal,
-                      tok::utf32_string_literal) &&
-      Current.Type != TT_ImplicitStringLiteral) {
+  if (Current.isStringLiteral()) {
     // Don't break string literals inside preprocessor directives (except for
     // #define directives, as their contents are stored in separate lines and
     // are not affected by this check).
@@ -755,13 +968,20 @@
     StringRef Text = Current.TokenText;
     StringRef Prefix;
     StringRef Postfix;
+    bool IsNSStringLiteral = false;
     // FIXME: Handle whitespace between '_T', '(', '"..."', and ')'.
     // FIXME: Store Prefix and Suffix (or PrefixLength and SuffixLength to
     // reduce the overhead) for each FormatToken, which is a string, so that we
     // don't run multiple checks here on the hot path.
+    if (Text.startswith("\"") && Current.Previous &&
+        Current.Previous->is(tok::at)) {
+      IsNSStringLiteral = true;
+      Prefix = "@\"";
+    }
     if ((Text.endswith(Postfix = "\"") &&
-         (Text.startswith(Prefix = "\"") || Text.startswith(Prefix = "u\"") ||
-          Text.startswith(Prefix = "U\"") || Text.startswith(Prefix = "u8\"") ||
+         (IsNSStringLiteral || Text.startswith(Prefix = "\"") ||
+          Text.startswith(Prefix = "u\"") || Text.startswith(Prefix = "U\"") ||
+          Text.startswith(Prefix = "u8\"") ||
           Text.startswith(Prefix = "L\""))) ||
         (Text.startswith(Prefix = "_T(\"") && Text.endswith(Postfix = "\")")) ||
         getRawStringLiteralPrefixPostfix(Text, Prefix, Postfix)) {
@@ -772,12 +992,16 @@
       return 0;
     }
   } else if (Current.Type == TT_BlockComment && Current.isTrailingComment()) {
+    if (CommentPragmasRegex.match(Current.TokenText.substr(2)))
+      return 0;
     Token.reset(new BreakableBlockComment(
         Current, State.Line->Level, StartColumn, Current.OriginalColumn,
         !Current.Previous, State.Line->InPPDirective, Encoding, Style));
   } else if (Current.Type == TT_LineComment &&
-             (Current.Previous == NULL ||
+             (Current.Previous == nullptr ||
               Current.Previous->Type != TT_ImplicitStringLiteral)) {
+    if (CommentPragmasRegex.match(Current.TokenText.substr(2)))
+      return 0;
     Token.reset(new BreakableLineComment(Current, State.Line->Level,
                                          StartColumn, /*InPPDirective=*/false,
                                          Encoding, Style));
@@ -822,6 +1046,12 @@
         break;
       }
 
+      // 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.
+      if (NewRemainingTokenColumns == RemainingTokenColumns)
+        break;
+
       assert(NewRemainingTokenColumns < RemainingTokenColumns);
       if (!DryRun)
         Token->insertBreak(LineIndex, TailOffset, Split, Whitespaces);
@@ -848,8 +1078,8 @@
         State.Stack[i].BreakBeforeParameter = true;
     }
 
-    Penalty += Current.is(tok::string_literal) ? Style.PenaltyBreakString
-                                               : Style.PenaltyBreakComment;
+    Penalty += Current.isStringLiteral() ? Style.PenaltyBreakString
+                                         : Style.PenaltyBreakComment;
 
     State.Stack.back().LastSpace = StartColumn;
   }
@@ -861,18 +1091,19 @@
   return Style.ColumnLimit - (State.Line->InPPDirective ? 2 : 0);
 }
 
-bool ContinuationIndenter::NextIsMultilineString(const LineState &State) {
+bool ContinuationIndenter::nextIsMultilineString(const LineState &State) {
   const FormatToken &Current = *State.NextToken;
-  if (!Current.is(tok::string_literal))
+  if (!Current.isStringLiteral() || Current.Type == TT_ImplicitStringLiteral)
     return false;
   // We never consider raw string literals "multiline" for the purpose of
-  // AlwaysBreakBeforeMultilineStrings implementation.
+  // AlwaysBreakBeforeMultilineStrings implementation as they are special-cased
+  // (see TokenAnnotator::mustBreakBefore().
   if (Current.TokenText.startswith("R\""))
     return false;
   if (Current.IsMultiline)
     return true;
   if (Current.getNextNonComment() &&
-      Current.getNextNonComment()->is(tok::string_literal))
+      Current.getNextNonComment()->isStringLiteral())
     return true; // Implicit concatenation.
   if (State.Column + Current.ColumnWidth + Current.UnbreakableTailLength >
       Style.ColumnLimit)
diff --git a/lib/Format/ContinuationIndenter.h b/lib/Format/ContinuationIndenter.h
index b317565..0969a8c 100644
--- a/lib/Format/ContinuationIndenter.h
+++ b/lib/Format/ContinuationIndenter.h
@@ -18,6 +18,7 @@
 
 #include "Encoding.h"
 #include "clang/Format/Format.h"
+#include "llvm/Support/Regex.h"
 
 namespace clang {
 class SourceManager;
@@ -72,6 +73,18 @@
   /// accordingly.
   unsigned moveStateToNextToken(LineState &State, bool DryRun, bool Newline);
 
+  /// \brief Update 'State' according to the next token's fake left parentheses.
+  void moveStatePastFakeLParens(LineState &State, bool Newline);
+  /// \brief Update 'State' according to the next token's fake r_parens.
+  void moveStatePastFakeRParens(LineState &State);
+
+  /// \brief Update 'State' according to the next token being one of "(<{[".
+  void moveStatePastScopeOpener(LineState &State, bool Newline);
+  /// \brief Update 'State' according to the next token being one of ")>}]".
+  void moveStatePastScopeCloser(LineState &State);
+  /// \brief Update 'State' with the next token opening a nested block.
+  void moveStateToNewBlock(LineState &State);
+
   /// \brief If the current token sticks out over the end of the line, break
   /// it if possible.
   ///
@@ -103,6 +116,9 @@
   /// \c Replacement.
   unsigned addTokenOnNewLine(LineState &State, bool DryRun);
 
+  /// \brief Calculate the new column for a line wrap before the next token.
+  unsigned getNewLineColumn(const LineState &State);
+
   /// \brief Adds a multiline token to the \p State.
   ///
   /// \returns Extra penalty for the first line of the literal: last line is
@@ -115,13 +131,14 @@
   ///
   /// This includes implicitly concatenated strings, strings that will be broken
   /// by clang-format and string literals with escaped newlines.
-  bool NextIsMultilineString(const LineState &State);
+  bool nextIsMultilineString(const LineState &State);
 
   FormatStyle Style;
   SourceManager &SourceMgr;
   WhitespaceManager &Whitespaces;
   encoding::Encoding Encoding;
   bool BinPackInconclusiveFunctions;
+  llvm::Regex CommentPragmasRegex;
 };
 
 struct ParenState {
@@ -130,10 +147,12 @@
       : Indent(Indent), IndentLevel(IndentLevel), LastSpace(LastSpace),
         FirstLessLess(0), BreakBeforeClosingBrace(false), QuestionColumn(0),
         AvoidBinPacking(AvoidBinPacking), BreakBeforeParameter(false),
-        NoLineBreak(NoLineBreak), ColonPos(0), StartOfFunctionCall(0),
-        StartOfArraySubscripts(0), NestedNameSpecifierContinuation(0),
-        CallContinuation(0), VariablePos(0), ContainsLineBreak(false),
-        ContainsUnwrappedBuilder(0) {}
+        NoLineBreak(NoLineBreak), LastOperatorWrapped(true), ColonPos(0),
+        StartOfFunctionCall(0), StartOfArraySubscripts(0),
+        NestedNameSpecifierContinuation(0), CallContinuation(0), VariablePos(0),
+        ContainsLineBreak(false), ContainsUnwrappedBuilder(0),
+        AlignColons(true), ObjCSelectorNameFound(false),
+        HasMultipleNestedBlocks(false), JSFunctionInlined(false) {}
 
   /// \brief The position to which a specific parenthesis level needs to be
   /// indented.
@@ -176,6 +195,10 @@
   /// \brief Line breaking in this context would break a formatting rule.
   bool NoLineBreak;
 
+  /// \brief True if the last binary operator on this level was wrapped to the
+  /// next line.
+  bool LastOperatorWrapped;
+
   /// \brief The position of the colon in an ObjC method declaration/call.
   unsigned ColonPos;
 
@@ -210,6 +233,30 @@
   /// builder-type call on one line.
   bool ContainsUnwrappedBuilder;
 
+  /// \brief \c true if the colons of the curren ObjC method expression should
+  /// be aligned.
+  ///
+  /// Not considered for memoization as it will always have the same value at
+  /// the same token.
+  bool AlignColons;
+
+  /// \brief \c true if at least one selector name was found in the current
+  /// ObjC method expression.
+  ///
+  /// Not considered for memoization as it will always have the same value at
+  /// the same token.
+  bool ObjCSelectorNameFound;
+
+  /// \brief \c true if there are multiple nested blocks inside these parens.
+  ///
+  /// Not considered for memoization as it will always have the same value at
+  /// the same token.
+  bool HasMultipleNestedBlocks;
+
+  // \brief The previous JavaScript 'function' keyword is not wrapped to a new
+  // line.
+  bool JSFunctionInlined;
+
   bool operator<(const ParenState &Other) const {
     if (Indent != Other.Indent)
       return Indent < Other.Indent;
@@ -227,6 +274,8 @@
       return BreakBeforeParameter;
     if (NoLineBreak != Other.NoLineBreak)
       return NoLineBreak;
+    if (LastOperatorWrapped != Other.LastOperatorWrapped)
+      return LastOperatorWrapped;
     if (ColonPos != Other.ColonPos)
       return ColonPos < Other.ColonPos;
     if (StartOfFunctionCall != Other.StartOfFunctionCall)
@@ -241,6 +290,8 @@
       return ContainsLineBreak < Other.ContainsLineBreak;
     if (ContainsUnwrappedBuilder != Other.ContainsUnwrappedBuilder)
       return ContainsUnwrappedBuilder < Other.ContainsUnwrappedBuilder;
+    if (JSFunctionInlined != Other.JSFunctionInlined)
+      return JSFunctionInlined < Other.JSFunctionInlined;
     return false;
   }
 };
@@ -258,13 +309,10 @@
   /// \brief \c true if this line contains a continued for-loop section.
   bool LineContainsContinuedForLoopSection;
 
-  /// \brief The level of nesting inside (), [], <> and {}.
-  unsigned ParenLevel;
-
-  /// \brief The \c ParenLevel at the start of this line.
+  /// \brief The \c NestingLevel at the start of this line.
   unsigned StartOfLineLevel;
 
-  /// \brief The lowest \c ParenLevel on the current line.
+  /// \brief The lowest \c NestingLevel on the current line.
   unsigned LowestLevelOnLine;
 
   /// \brief The start column of the string literal, if we're in a string
@@ -307,8 +355,6 @@
     if (LineContainsContinuedForLoopSection !=
         Other.LineContainsContinuedForLoopSection)
       return LineContainsContinuedForLoopSection;
-    if (ParenLevel != Other.ParenLevel)
-      return ParenLevel < Other.ParenLevel;
     if (StartOfLineLevel != Other.StartOfLineLevel)
       return StartOfLineLevel < Other.StartOfLineLevel;
     if (LowestLevelOnLine != Other.LowestLevelOnLine)
diff --git a/lib/Format/Encoding.h b/lib/Format/Encoding.h
index 356334d..dba5174 100644
--- a/lib/Format/Encoding.h
+++ b/lib/Format/Encoding.h
@@ -64,6 +64,10 @@
 inline unsigned columnWidth(StringRef Text, Encoding Encoding) {
   if (Encoding == Encoding_UTF8) {
     int ContentWidth = llvm::sys::unicode::columnWidthUTF8(Text);
+    // FIXME: Figure out the correct way to handle this in the presence of both
+    // printable and unprintable multi-byte UTF-8 characters. Falling back to
+    // returning the number of bytes may cause problems, as columnWidth suddenly
+    // becomes non-additive.
     if (ContentWidth >= 0)
       return ContentWidth;
   }
@@ -81,9 +85,7 @@
     StringRef::size_type TabPos = Tail.find('\t');
     if (TabPos == StringRef::npos)
       return TotalWidth + columnWidth(Tail, Encoding);
-    int Width = columnWidth(Tail.substr(0, TabPos), Encoding);
-    assert(Width >= 0);
-    TotalWidth += Width;
+    TotalWidth += columnWidth(Tail.substr(0, TabPos), Encoding);
     TotalWidth += TabWidth - (TotalWidth + StartColumn) % TabWidth;
     Tail = Tail.substr(TabPos + 1);
   }
diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp
index 64ffe9e..58dd560 100644
--- a/lib/Format/Format.cpp
+++ b/lib/Format/Format.cpp
@@ -13,84 +13,131 @@
 ///
 //===----------------------------------------------------------------------===//
 
-#define DEBUG_TYPE "format-formatter"
-
 #include "ContinuationIndenter.h"
 #include "TokenAnnotator.h"
 #include "UnwrappedLineParser.h"
 #include "WhitespaceManager.h"
 #include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Format/Format.h"
 #include "clang/Lex/Lexer.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/Debug.h"
-#include "llvm/Support/YAMLTraits.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/YAMLTraits.h"
 #include <queue>
 #include <string>
 
+#define DEBUG_TYPE "format-formatter"
+
+using clang::format::FormatStyle;
+
+LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(std::string)
+
 namespace llvm {
 namespace yaml {
+template <> struct ScalarEnumerationTraits<FormatStyle::LanguageKind> {
+  static void enumeration(IO &IO, FormatStyle::LanguageKind &Value) {
+    IO.enumCase(Value, "Cpp", FormatStyle::LK_Cpp);
+    IO.enumCase(Value, "JavaScript", FormatStyle::LK_JavaScript);
+    IO.enumCase(Value, "Proto", FormatStyle::LK_Proto);
+  }
+};
+
+template <> struct ScalarEnumerationTraits<FormatStyle::LanguageStandard> {
+  static void enumeration(IO &IO, FormatStyle::LanguageStandard &Value) {
+    IO.enumCase(Value, "Cpp03", FormatStyle::LS_Cpp03);
+    IO.enumCase(Value, "C++03", FormatStyle::LS_Cpp03);
+    IO.enumCase(Value, "Cpp11", FormatStyle::LS_Cpp11);
+    IO.enumCase(Value, "C++11", FormatStyle::LS_Cpp11);
+    IO.enumCase(Value, "Auto", FormatStyle::LS_Auto);
+  }
+};
+
+template <> struct ScalarEnumerationTraits<FormatStyle::UseTabStyle> {
+  static void enumeration(IO &IO, FormatStyle::UseTabStyle &Value) {
+    IO.enumCase(Value, "Never", FormatStyle::UT_Never);
+    IO.enumCase(Value, "false", FormatStyle::UT_Never);
+    IO.enumCase(Value, "Always", FormatStyle::UT_Always);
+    IO.enumCase(Value, "true", FormatStyle::UT_Always);
+    IO.enumCase(Value, "ForIndentation", FormatStyle::UT_ForIndentation);
+  }
+};
+
+template <> struct ScalarEnumerationTraits<FormatStyle::ShortFunctionStyle> {
+  static void enumeration(IO &IO, FormatStyle::ShortFunctionStyle &Value) {
+    IO.enumCase(Value, "None", FormatStyle::SFS_None);
+    IO.enumCase(Value, "false", FormatStyle::SFS_None);
+    IO.enumCase(Value, "All", FormatStyle::SFS_All);
+    IO.enumCase(Value, "true", FormatStyle::SFS_All);
+    IO.enumCase(Value, "Inline", FormatStyle::SFS_Inline);
+  }
+};
+
+template <> struct ScalarEnumerationTraits<FormatStyle::BraceBreakingStyle> {
+  static void enumeration(IO &IO, FormatStyle::BraceBreakingStyle &Value) {
+    IO.enumCase(Value, "Attach", FormatStyle::BS_Attach);
+    IO.enumCase(Value, "Linux", FormatStyle::BS_Linux);
+    IO.enumCase(Value, "Stroustrup", FormatStyle::BS_Stroustrup);
+    IO.enumCase(Value, "Allman", FormatStyle::BS_Allman);
+    IO.enumCase(Value, "GNU", FormatStyle::BS_GNU);
+  }
+};
+
 template <>
-struct ScalarEnumerationTraits<clang::format::FormatStyle::LanguageStandard> {
+struct ScalarEnumerationTraits<FormatStyle::NamespaceIndentationKind> {
   static void enumeration(IO &IO,
-                          clang::format::FormatStyle::LanguageStandard &Value) {
-    IO.enumCase(Value, "Cpp03", clang::format::FormatStyle::LS_Cpp03);
-    IO.enumCase(Value, "C++03", clang::format::FormatStyle::LS_Cpp03);
-    IO.enumCase(Value, "Cpp11", clang::format::FormatStyle::LS_Cpp11);
-    IO.enumCase(Value, "C++11", clang::format::FormatStyle::LS_Cpp11);
-    IO.enumCase(Value, "Auto", clang::format::FormatStyle::LS_Auto);
+                          FormatStyle::NamespaceIndentationKind &Value) {
+    IO.enumCase(Value, "None", FormatStyle::NI_None);
+    IO.enumCase(Value, "Inner", FormatStyle::NI_Inner);
+    IO.enumCase(Value, "All", FormatStyle::NI_All);
   }
 };
 
 template <>
-struct ScalarEnumerationTraits<clang::format::FormatStyle::UseTabStyle> {
+struct ScalarEnumerationTraits<FormatStyle::PointerAlignmentStyle> {
   static void enumeration(IO &IO,
-                          clang::format::FormatStyle::UseTabStyle &Value) {
-    IO.enumCase(Value, "Never", clang::format::FormatStyle::UT_Never);
-    IO.enumCase(Value, "false", clang::format::FormatStyle::UT_Never);
-    IO.enumCase(Value, "Always", clang::format::FormatStyle::UT_Always);
-    IO.enumCase(Value, "true", clang::format::FormatStyle::UT_Always);
-    IO.enumCase(Value, "ForIndentation",
-                clang::format::FormatStyle::UT_ForIndentation);
+                          FormatStyle::PointerAlignmentStyle &Value) {
+    IO.enumCase(Value, "Middle", FormatStyle::PAS_Middle);
+    IO.enumCase(Value, "Left", FormatStyle::PAS_Left);
+    IO.enumCase(Value, "Right", FormatStyle::PAS_Right);
+
+    // For backward compatibility.
+    IO.enumCase(Value, "true", FormatStyle::PAS_Left);
+    IO.enumCase(Value, "false", FormatStyle::PAS_Right);
   }
 };
 
 template <>
-struct ScalarEnumerationTraits<clang::format::FormatStyle::BraceBreakingStyle> {
-  static void
-  enumeration(IO &IO, clang::format::FormatStyle::BraceBreakingStyle &Value) {
-    IO.enumCase(Value, "Attach", clang::format::FormatStyle::BS_Attach);
-    IO.enumCase(Value, "Linux", clang::format::FormatStyle::BS_Linux);
-    IO.enumCase(Value, "Stroustrup", clang::format::FormatStyle::BS_Stroustrup);
-    IO.enumCase(Value, "Allman", clang::format::FormatStyle::BS_Allman);
+struct ScalarEnumerationTraits<FormatStyle::SpaceBeforeParensOptions> {
+  static void enumeration(IO &IO,
+                          FormatStyle::SpaceBeforeParensOptions &Value) {
+    IO.enumCase(Value, "Never", FormatStyle::SBPO_Never);
+    IO.enumCase(Value, "ControlStatements",
+                FormatStyle::SBPO_ControlStatements);
+    IO.enumCase(Value, "Always", FormatStyle::SBPO_Always);
+
+    // For backward compatibility.
+    IO.enumCase(Value, "false", FormatStyle::SBPO_Never);
+    IO.enumCase(Value, "true", FormatStyle::SBPO_ControlStatements);
   }
 };
 
-template <>
-struct ScalarEnumerationTraits<
-    clang::format::FormatStyle::NamespaceIndentationKind> {
-  static void
-  enumeration(IO &IO,
-              clang::format::FormatStyle::NamespaceIndentationKind &Value) {
-    IO.enumCase(Value, "None", clang::format::FormatStyle::NI_None);
-    IO.enumCase(Value, "Inner", clang::format::FormatStyle::NI_Inner);
-    IO.enumCase(Value, "All", clang::format::FormatStyle::NI_All);
-  }
-};
+template <> struct MappingTraits<FormatStyle> {
+  static void mapping(IO &IO, FormatStyle &Style) {
+    // When reading, read the language first, we need it for getPredefinedStyle.
+    IO.mapOptional("Language", Style.Language);
 
-template <> struct MappingTraits<clang::format::FormatStyle> {
-  static void mapping(llvm::yaml::IO &IO, clang::format::FormatStyle &Style) {
     if (IO.outputting()) {
       StringRef StylesArray[] = { "LLVM",    "Google", "Chromium",
-                                  "Mozilla", "WebKit" };
+                                  "Mozilla", "WebKit", "GNU" };
       ArrayRef<StringRef> Styles(StylesArray);
       for (size_t i = 0, e = Styles.size(); i < e; ++i) {
         StringRef StyleName(Styles[i]);
-        clang::format::FormatStyle PredefinedStyle;
-        if (clang::format::getPredefinedStyle(StyleName, &PredefinedStyle) &&
+        FormatStyle PredefinedStyle;
+        if (getPredefinedStyle(StyleName, Style.Language, &PredefinedStyle) &&
             Style == PredefinedStyle) {
           IO.mapOptional("# BasedOnStyle", StyleName);
           break;
@@ -99,11 +146,16 @@
     } else {
       StringRef BasedOnStyle;
       IO.mapOptional("BasedOnStyle", BasedOnStyle);
-      if (!BasedOnStyle.empty())
-        if (!clang::format::getPredefinedStyle(BasedOnStyle, &Style)) {
+      if (!BasedOnStyle.empty()) {
+        FormatStyle::LanguageKind OldLanguage = Style.Language;
+        FormatStyle::LanguageKind Language =
+            ((FormatStyle *)IO.getContext())->Language;
+        if (!getPredefinedStyle(BasedOnStyle, Language, &Style)) {
           IO.setError(Twine("Unknown value for BasedOnStyle: ", BasedOnStyle));
           return;
         }
+        Style.Language = OldLanguage;
+      }
     }
 
     IO.mapOptional("AccessModifierOffset", Style.AccessModifierOffset);
@@ -113,10 +165,14 @@
     IO.mapOptional("AlignTrailingComments", Style.AlignTrailingComments);
     IO.mapOptional("AllowAllParametersOfDeclarationOnNextLine",
                    Style.AllowAllParametersOfDeclarationOnNextLine);
+    IO.mapOptional("AllowShortBlocksOnASingleLine",
+                   Style.AllowShortBlocksOnASingleLine);
     IO.mapOptional("AllowShortIfStatementsOnASingleLine",
                    Style.AllowShortIfStatementsOnASingleLine);
     IO.mapOptional("AllowShortLoopsOnASingleLine",
                    Style.AllowShortLoopsOnASingleLine);
+    IO.mapOptional("AllowShortFunctionsOnASingleLine",
+                   Style.AllowShortFunctionsOnASingleLine);
     IO.mapOptional("AlwaysBreakTemplateDeclarations",
                    Style.AlwaysBreakTemplateDeclarations);
     IO.mapOptional("AlwaysBreakBeforeMultilineStrings",
@@ -131,12 +187,19 @@
     IO.mapOptional("ColumnLimit", Style.ColumnLimit);
     IO.mapOptional("ConstructorInitializerAllOnOneLineOrOnePerLine",
                    Style.ConstructorInitializerAllOnOneLineOrOnePerLine);
-    IO.mapOptional("DerivePointerBinding", Style.DerivePointerBinding);
+    IO.mapOptional("DerivePointerAlignment", Style.DerivePointerAlignment);
     IO.mapOptional("ExperimentalAutoDetectBinPacking",
                    Style.ExperimentalAutoDetectBinPacking);
     IO.mapOptional("IndentCaseLabels", Style.IndentCaseLabels);
+    IO.mapOptional("IndentWrappedFunctionNames",
+                   Style.IndentWrappedFunctionNames);
+    IO.mapOptional("IndentFunctionDeclarationAfterType",
+                   Style.IndentWrappedFunctionNames);
     IO.mapOptional("MaxEmptyLinesToKeep", Style.MaxEmptyLinesToKeep);
+    IO.mapOptional("KeepEmptyLinesAtTheStartOfBlocks",
+                   Style.KeepEmptyLinesAtTheStartOfBlocks);
     IO.mapOptional("NamespaceIndentation", Style.NamespaceIndentation);
+    IO.mapOptional("ObjCSpaceAfterProperty", Style.ObjCSpaceAfterProperty);
     IO.mapOptional("ObjCSpaceBeforeProtocolList",
                    Style.ObjCSpaceBeforeProtocolList);
     IO.mapOptional("PenaltyBreakBeforeFirstCallParameter",
@@ -148,7 +211,7 @@
     IO.mapOptional("PenaltyExcessCharacter", Style.PenaltyExcessCharacter);
     IO.mapOptional("PenaltyReturnTypeOnItsOwnLine",
                    Style.PenaltyReturnTypeOnItsOwnLine);
-    IO.mapOptional("PointerBindsToType", Style.PointerBindsToType);
+    IO.mapOptional("PointerAlignment", Style.PointerAlignment);
     IO.mapOptional("SpacesBeforeTrailingComments",
                    Style.SpacesBeforeTrailingComments);
     IO.mapOptional("Cpp11BracedListStyle", Style.Cpp11BracedListStyle);
@@ -157,18 +220,54 @@
     IO.mapOptional("TabWidth", Style.TabWidth);
     IO.mapOptional("UseTab", Style.UseTab);
     IO.mapOptional("BreakBeforeBraces", Style.BreakBeforeBraces);
-    IO.mapOptional("IndentFunctionDeclarationAfterType",
-                   Style.IndentFunctionDeclarationAfterType);
     IO.mapOptional("SpacesInParentheses", Style.SpacesInParentheses);
     IO.mapOptional("SpacesInAngles", Style.SpacesInAngles);
     IO.mapOptional("SpaceInEmptyParentheses", Style.SpaceInEmptyParentheses);
     IO.mapOptional("SpacesInCStyleCastParentheses",
                    Style.SpacesInCStyleCastParentheses);
-    IO.mapOptional("SpaceAfterControlStatementKeyword",
-                   Style.SpaceAfterControlStatementKeyword);
+    IO.mapOptional("SpacesInContainerLiterals",
+                   Style.SpacesInContainerLiterals);
     IO.mapOptional("SpaceBeforeAssignmentOperators",
                    Style.SpaceBeforeAssignmentOperators);
     IO.mapOptional("ContinuationIndentWidth", Style.ContinuationIndentWidth);
+    IO.mapOptional("CommentPragmas", Style.CommentPragmas);
+    IO.mapOptional("ForEachMacros", Style.ForEachMacros);
+
+    // For backward compatibility.
+    if (!IO.outputting()) {
+      IO.mapOptional("SpaceAfterControlStatementKeyword",
+                     Style.SpaceBeforeParens);
+      IO.mapOptional("PointerBindsToType", Style.PointerAlignment);
+      IO.mapOptional("DerivePointerBinding", Style.DerivePointerAlignment);
+    }
+    IO.mapOptional("SpaceBeforeParens", Style.SpaceBeforeParens);
+    IO.mapOptional("DisableFormat", Style.DisableFormat);
+  }
+};
+
+// Allows to read vector<FormatStyle> while keeping default values.
+// IO.getContext() should contain a pointer to the FormatStyle structure, that
+// will be used to get default values for missing keys.
+// If the first element has no Language specified, it will be treated as the
+// default one for the following elements.
+template <> struct DocumentListTraits<std::vector<FormatStyle> > {
+  static size_t size(IO &IO, std::vector<FormatStyle> &Seq) {
+    return Seq.size();
+  }
+  static FormatStyle &element(IO &IO, std::vector<FormatStyle> &Seq,
+                              size_t Index) {
+    if (Index >= Seq.size()) {
+      assert(Index == Seq.size());
+      FormatStyle Template;
+      if (Seq.size() > 0 && Seq[0].Language == FormatStyle::LK_None) {
+        Template = Seq[0];
+      } else {
+        Template = *((const FormatStyle *)IO.getContext());
+        Template.Language = FormatStyle::LK_None;
+      }
+      Seq.resize(Index + 1, Template);
+    }
+    return Seq[Index];
   }
 };
 }
@@ -177,19 +276,39 @@
 namespace clang {
 namespace format {
 
-void setDefaultPenalties(FormatStyle &Style) {
-  Style.PenaltyBreakComment = 60;
-  Style.PenaltyBreakFirstLessLess = 120;
-  Style.PenaltyBreakString = 1000;
-  Style.PenaltyExcessCharacter = 1000000;
+const std::error_category &getParseCategory() {
+  static ParseErrorCategory C;
+  return C;
+}
+std::error_code make_error_code(ParseError e) {
+  return std::error_code(static_cast<int>(e), getParseCategory());
+}
+
+const char *ParseErrorCategory::name() const LLVM_NOEXCEPT {
+  return "clang-format.parse_error";
+}
+
+std::string ParseErrorCategory::message(int EV) const {
+  switch (static_cast<ParseError>(EV)) {
+  case ParseError::Success:
+    return "Success";
+  case ParseError::Error:
+    return "Invalid argument";
+  case ParseError::Unsuitable:
+    return "Unsuitable";
+  }
+  llvm_unreachable("unexpected parse error");
 }
 
 FormatStyle getLLVMStyle() {
   FormatStyle LLVMStyle;
+  LLVMStyle.Language = FormatStyle::LK_Cpp;
   LLVMStyle.AccessModifierOffset = -2;
   LLVMStyle.AlignEscapedNewlinesLeft = false;
   LLVMStyle.AlignTrailingComments = true;
   LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true;
+  LLVMStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
+  LLVMStyle.AllowShortBlocksOnASingleLine = false;
   LLVMStyle.AllowShortIfStatementsOnASingleLine = false;
   LLVMStyle.AllowShortLoopsOnASingleLine = false;
   LLVMStyle.AlwaysBreakBeforeMultilineStrings = false;
@@ -200,91 +319,92 @@
   LLVMStyle.BreakBeforeBraces = FormatStyle::BS_Attach;
   LLVMStyle.BreakConstructorInitializersBeforeComma = false;
   LLVMStyle.ColumnLimit = 80;
+  LLVMStyle.CommentPragmas = "^ IWYU pragma:";
   LLVMStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = false;
   LLVMStyle.ConstructorInitializerIndentWidth = 4;
-  LLVMStyle.Cpp11BracedListStyle = false;
-  LLVMStyle.DerivePointerBinding = false;
+  LLVMStyle.ContinuationIndentWidth = 4;
+  LLVMStyle.Cpp11BracedListStyle = true;
+  LLVMStyle.DerivePointerAlignment = false;
   LLVMStyle.ExperimentalAutoDetectBinPacking = false;
+  LLVMStyle.ForEachMacros.push_back("foreach");
+  LLVMStyle.ForEachMacros.push_back("Q_FOREACH");
+  LLVMStyle.ForEachMacros.push_back("BOOST_FOREACH");
   LLVMStyle.IndentCaseLabels = false;
-  LLVMStyle.IndentFunctionDeclarationAfterType = false;
+  LLVMStyle.IndentWrappedFunctionNames = false;
   LLVMStyle.IndentWidth = 2;
   LLVMStyle.TabWidth = 8;
   LLVMStyle.MaxEmptyLinesToKeep = 1;
+  LLVMStyle.KeepEmptyLinesAtTheStartOfBlocks = true;
   LLVMStyle.NamespaceIndentation = FormatStyle::NI_None;
+  LLVMStyle.ObjCSpaceAfterProperty = false;
   LLVMStyle.ObjCSpaceBeforeProtocolList = true;
-  LLVMStyle.PointerBindsToType = false;
+  LLVMStyle.PointerAlignment = FormatStyle::PAS_Right;
   LLVMStyle.SpacesBeforeTrailingComments = 1;
-  LLVMStyle.Standard = FormatStyle::LS_Cpp03;
+  LLVMStyle.Standard = FormatStyle::LS_Cpp11;
   LLVMStyle.UseTab = FormatStyle::UT_Never;
   LLVMStyle.SpacesInParentheses = false;
   LLVMStyle.SpaceInEmptyParentheses = false;
+  LLVMStyle.SpacesInContainerLiterals = true;
   LLVMStyle.SpacesInCStyleCastParentheses = false;
-  LLVMStyle.SpaceAfterControlStatementKeyword = true;
+  LLVMStyle.SpaceBeforeParens = FormatStyle::SBPO_ControlStatements;
   LLVMStyle.SpaceBeforeAssignmentOperators = true;
-  LLVMStyle.ContinuationIndentWidth = 4;
   LLVMStyle.SpacesInAngles = false;
 
-  setDefaultPenalties(LLVMStyle);
+  LLVMStyle.PenaltyBreakComment = 300;
+  LLVMStyle.PenaltyBreakFirstLessLess = 120;
+  LLVMStyle.PenaltyBreakString = 1000;
+  LLVMStyle.PenaltyExcessCharacter = 1000000;
   LLVMStyle.PenaltyReturnTypeOnItsOwnLine = 60;
   LLVMStyle.PenaltyBreakBeforeFirstCallParameter = 19;
 
+  LLVMStyle.DisableFormat = false;
+
   return LLVMStyle;
 }
 
-FormatStyle getGoogleStyle() {
-  FormatStyle GoogleStyle;
+FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
+  FormatStyle GoogleStyle = getLLVMStyle();
+  GoogleStyle.Language = Language;
+
   GoogleStyle.AccessModifierOffset = -1;
   GoogleStyle.AlignEscapedNewlinesLeft = true;
-  GoogleStyle.AlignTrailingComments = true;
-  GoogleStyle.AllowAllParametersOfDeclarationOnNextLine = true;
   GoogleStyle.AllowShortIfStatementsOnASingleLine = true;
   GoogleStyle.AllowShortLoopsOnASingleLine = true;
   GoogleStyle.AlwaysBreakBeforeMultilineStrings = true;
   GoogleStyle.AlwaysBreakTemplateDeclarations = true;
-  GoogleStyle.BinPackParameters = true;
-  GoogleStyle.BreakBeforeBinaryOperators = false;
-  GoogleStyle.BreakBeforeTernaryOperators = true;
-  GoogleStyle.BreakBeforeBraces = FormatStyle::BS_Attach;
-  GoogleStyle.BreakConstructorInitializersBeforeComma = false;
-  GoogleStyle.ColumnLimit = 80;
   GoogleStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = true;
-  GoogleStyle.ConstructorInitializerIndentWidth = 4;
-  GoogleStyle.Cpp11BracedListStyle = true;
-  GoogleStyle.DerivePointerBinding = true;
-  GoogleStyle.ExperimentalAutoDetectBinPacking = false;
+  GoogleStyle.DerivePointerAlignment = true;
   GoogleStyle.IndentCaseLabels = true;
-  GoogleStyle.IndentFunctionDeclarationAfterType = true;
-  GoogleStyle.IndentWidth = 2;
-  GoogleStyle.TabWidth = 8;
-  GoogleStyle.MaxEmptyLinesToKeep = 1;
-  GoogleStyle.NamespaceIndentation = FormatStyle::NI_None;
+  GoogleStyle.KeepEmptyLinesAtTheStartOfBlocks = false;
+  GoogleStyle.ObjCSpaceAfterProperty = false;
   GoogleStyle.ObjCSpaceBeforeProtocolList = false;
-  GoogleStyle.PointerBindsToType = true;
+  GoogleStyle.PointerAlignment = FormatStyle::PAS_Left;
   GoogleStyle.SpacesBeforeTrailingComments = 2;
   GoogleStyle.Standard = FormatStyle::LS_Auto;
-  GoogleStyle.UseTab = FormatStyle::UT_Never;
-  GoogleStyle.SpacesInParentheses = false;
-  GoogleStyle.SpaceInEmptyParentheses = false;
-  GoogleStyle.SpacesInCStyleCastParentheses = false;
-  GoogleStyle.SpaceAfterControlStatementKeyword = true;
-  GoogleStyle.SpaceBeforeAssignmentOperators = true;
-  GoogleStyle.ContinuationIndentWidth = 4;
-  GoogleStyle.SpacesInAngles = false;
 
-  setDefaultPenalties(GoogleStyle);
   GoogleStyle.PenaltyReturnTypeOnItsOwnLine = 200;
   GoogleStyle.PenaltyBreakBeforeFirstCallParameter = 1;
 
+  if (Language == FormatStyle::LK_JavaScript) {
+    GoogleStyle.BreakBeforeTernaryOperators = false;
+    GoogleStyle.MaxEmptyLinesToKeep = 3;
+    GoogleStyle.SpacesInContainerLiterals = false;
+  } else if (Language == FormatStyle::LK_Proto) {
+    GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
+    GoogleStyle.SpacesInContainerLiterals = false;
+  }
+
   return GoogleStyle;
 }
 
-FormatStyle getChromiumStyle() {
-  FormatStyle ChromiumStyle = getGoogleStyle();
+FormatStyle getChromiumStyle(FormatStyle::LanguageKind Language) {
+  FormatStyle ChromiumStyle = getGoogleStyle(Language);
   ChromiumStyle.AllowAllParametersOfDeclarationOnNextLine = false;
+  ChromiumStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
   ChromiumStyle.AllowShortIfStatementsOnASingleLine = false;
   ChromiumStyle.AllowShortLoopsOnASingleLine = false;
   ChromiumStyle.BinPackParameters = false;
-  ChromiumStyle.DerivePointerBinding = false;
+  ChromiumStyle.DerivePointerAlignment = false;
   ChromiumStyle.Standard = FormatStyle::LS_Cpp03;
   return ChromiumStyle;
 }
@@ -292,12 +412,15 @@
 FormatStyle getMozillaStyle() {
   FormatStyle MozillaStyle = getLLVMStyle();
   MozillaStyle.AllowAllParametersOfDeclarationOnNextLine = false;
+  MozillaStyle.Cpp11BracedListStyle = false;
   MozillaStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = true;
-  MozillaStyle.DerivePointerBinding = true;
+  MozillaStyle.DerivePointerAlignment = true;
   MozillaStyle.IndentCaseLabels = true;
+  MozillaStyle.ObjCSpaceAfterProperty = true;
   MozillaStyle.ObjCSpaceBeforeProtocolList = false;
   MozillaStyle.PenaltyReturnTypeOnItsOwnLine = 200;
-  MozillaStyle.PointerBindsToType = true;
+  MozillaStyle.PointerAlignment = FormatStyle::PAS_Left;
+  MozillaStyle.Standard = FormatStyle::LS_Cpp03;
   return MozillaStyle;
 }
 
@@ -308,36 +431,102 @@
   Style.BreakBeforeBinaryOperators = true;
   Style.BreakBeforeBraces = FormatStyle::BS_Stroustrup;
   Style.BreakConstructorInitializersBeforeComma = true;
+  Style.Cpp11BracedListStyle = false;
   Style.ColumnLimit = 0;
   Style.IndentWidth = 4;
   Style.NamespaceIndentation = FormatStyle::NI_Inner;
-  Style.PointerBindsToType = true;
+  Style.ObjCSpaceAfterProperty = true;
+  Style.PointerAlignment = FormatStyle::PAS_Left;
+  Style.Standard = FormatStyle::LS_Cpp03;
   return Style;
 }
 
-bool getPredefinedStyle(StringRef Name, FormatStyle *Style) {
-  if (Name.equals_lower("llvm"))
-    *Style = getLLVMStyle();
-  else if (Name.equals_lower("chromium"))
-    *Style = getChromiumStyle();
-  else if (Name.equals_lower("mozilla"))
-    *Style = getMozillaStyle();
-  else if (Name.equals_lower("google"))
-    *Style = getGoogleStyle();
-  else if (Name.equals_lower("webkit"))
-    *Style = getWebKitStyle();
-  else
-    return false;
+FormatStyle getGNUStyle() {
+  FormatStyle Style = getLLVMStyle();
+  Style.BreakBeforeBinaryOperators = true;
+  Style.BreakBeforeBraces = FormatStyle::BS_GNU;
+  Style.BreakBeforeTernaryOperators = true;
+  Style.Cpp11BracedListStyle = false;
+  Style.ColumnLimit = 79;
+  Style.SpaceBeforeParens = FormatStyle::SBPO_Always;
+  Style.Standard = FormatStyle::LS_Cpp03;
+  return Style;
+}
 
+FormatStyle getNoStyle() {
+  FormatStyle NoStyle = getLLVMStyle();
+  NoStyle.DisableFormat = true;
+  return NoStyle;
+}
+
+bool getPredefinedStyle(StringRef Name, FormatStyle::LanguageKind Language,
+                        FormatStyle *Style) {
+  if (Name.equals_lower("llvm")) {
+    *Style = getLLVMStyle();
+  } else if (Name.equals_lower("chromium")) {
+    *Style = getChromiumStyle(Language);
+  } else if (Name.equals_lower("mozilla")) {
+    *Style = getMozillaStyle();
+  } else if (Name.equals_lower("google")) {
+    *Style = getGoogleStyle(Language);
+  } else if (Name.equals_lower("webkit")) {
+    *Style = getWebKitStyle();
+  } else if (Name.equals_lower("gnu")) {
+    *Style = getGNUStyle();
+  } else if (Name.equals_lower("none")) {
+    *Style = getNoStyle();
+  } else {
+    return false;
+  }
+
+  Style->Language = Language;
   return true;
 }
 
-llvm::error_code parseConfiguration(StringRef Text, FormatStyle *Style) {
+std::error_code parseConfiguration(StringRef Text, FormatStyle *Style) {
+  assert(Style);
+  FormatStyle::LanguageKind Language = Style->Language;
+  assert(Language != FormatStyle::LK_None);
   if (Text.trim().empty())
-    return llvm::make_error_code(llvm::errc::invalid_argument);
+    return make_error_code(ParseError::Error);
+
+  std::vector<FormatStyle> Styles;
   llvm::yaml::Input Input(Text);
-  Input >> *Style;
-  return Input.error();
+  // DocumentListTraits<vector<FormatStyle>> uses the context to get default
+  // values for the fields, keys for which are missing from the configuration.
+  // Mapping also uses the context to get the language to find the correct
+  // base style.
+  Input.setContext(Style);
+  Input >> Styles;
+  if (Input.error())
+    return Input.error();
+
+  for (unsigned i = 0; i < Styles.size(); ++i) {
+    // Ensures that only the first configuration can skip the Language option.
+    if (Styles[i].Language == FormatStyle::LK_None && i != 0)
+      return make_error_code(ParseError::Error);
+    // Ensure that each language is configured at most once.
+    for (unsigned j = 0; j < i; ++j) {
+      if (Styles[i].Language == Styles[j].Language) {
+        DEBUG(llvm::dbgs()
+              << "Duplicate languages in the config file on positions " << j
+              << " and " << i << "\n");
+        return make_error_code(ParseError::Error);
+      }
+    }
+  }
+  // Look for a suitable configuration starting from the end, so we can
+  // find the configuration for the specific language first, and the default
+  // configuration (which can only be at slot 0) after it.
+  for (int i = Styles.size() - 1; i >= 0; --i) {
+    if (Styles[i].Language == Language ||
+        Styles[i].Language == FormatStyle::LK_None) {
+      *Style = Styles[i];
+      Style->Language = Language;
+      return make_error_code(ParseError::Success);
+    }
+  }
+  return make_error_code(ParseError::Unsuitable);
 }
 
 std::string configurationAsText(const FormatStyle &Style) {
@@ -362,7 +551,7 @@
   void format(unsigned FirstIndent, const AnnotatedLine *Line) {
     LineState State =
         Indenter->getInitialState(FirstIndent, Line, /*DryRun=*/false);
-    while (State.NextToken != NULL) {
+    while (State.NextToken) {
       bool Newline =
           Indenter->mustBreak(State) ||
           (Indenter->canBreak(State) && State.NextToken->NewlinesBefore > 0);
@@ -381,14 +570,14 @@
   /// \brief Calculates how many lines can be merged into 1 starting at \p I.
   unsigned
   tryFitMultipleLinesInOne(unsigned Indent,
-                           SmallVectorImpl<AnnotatedLine *>::const_iterator &I,
+                           SmallVectorImpl<AnnotatedLine *>::const_iterator I,
                            SmallVectorImpl<AnnotatedLine *>::const_iterator E) {
     // We can never merge stuff if there are trailing line comments.
-    AnnotatedLine *TheLine = *I;
+    const AnnotatedLine *TheLine = *I;
     if (TheLine->Last->Type == TT_LineComment)
       return 0;
 
-    if (Indent > Style.ColumnLimit)
+    if (Style.ColumnLimit > 0 && Indent > Style.ColumnLimit)
       return 0;
 
     unsigned Limit =
@@ -399,19 +588,54 @@
                 ? 0
                 : Limit - TheLine->Last->TotalLength;
 
-    if (I + 1 == E || (*(I + 1))->Type == LT_Invalid)
+    if (I + 1 == E || I[1]->Type == LT_Invalid || I[1]->First->MustBreakBefore)
       return 0;
 
+    // FIXME: TheLine->Level != 0 might or might not be the right check to do.
+    // If necessary, change to something smarter.
+    bool MergeShortFunctions =
+        Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_All ||
+        (Style.AllowShortFunctionsOnASingleLine == FormatStyle::SFS_Inline &&
+         TheLine->Level != 0);
+
+    if (TheLine->Last->Type == TT_FunctionLBrace &&
+        TheLine->First != TheLine->Last) {
+      return MergeShortFunctions ? tryMergeSimpleBlock(I, E, Limit) : 0;
+    }
     if (TheLine->Last->is(tok::l_brace)) {
-      return tryMergeSimpleBlock(I, E, Limit);
-    } else if (Style.AllowShortIfStatementsOnASingleLine &&
-               TheLine->First->is(tok::kw_if)) {
-      return tryMergeSimpleControlStatement(I, E, Limit);
-    } else if (Style.AllowShortLoopsOnASingleLine &&
-               TheLine->First->isOneOf(tok::kw_for, tok::kw_while)) {
-      return tryMergeSimpleControlStatement(I, E, Limit);
-    } else if (TheLine->InPPDirective && (TheLine->First->HasUnescapedNewline ||
-                                          TheLine->First->IsFirst)) {
+      return Style.BreakBeforeBraces == FormatStyle::BS_Attach
+                 ? tryMergeSimpleBlock(I, E, Limit)
+                 : 0;
+    }
+    if (I[1]->First->Type == TT_FunctionLBrace &&
+        Style.BreakBeforeBraces != FormatStyle::BS_Attach) {
+      // Check for Limit <= 2 to account for the " {".
+      if (Limit <= 2 || (Style.ColumnLimit == 0 && containsMustBreak(TheLine)))
+        return 0;
+      Limit -= 2;
+
+      unsigned MergedLines = 0;
+      if (MergeShortFunctions) {
+        MergedLines = tryMergeSimpleBlock(I + 1, E, Limit);
+        // If we managed to merge the block, count the function header, which is
+        // on a separate line.
+        if (MergedLines > 0)
+          ++MergedLines;
+      }
+      return MergedLines;
+    }
+    if (TheLine->First->is(tok::kw_if)) {
+      return Style.AllowShortIfStatementsOnASingleLine
+                 ? tryMergeSimpleControlStatement(I, E, Limit)
+                 : 0;
+    }
+    if (TheLine->First->isOneOf(tok::kw_for, tok::kw_while)) {
+      return Style.AllowShortLoopsOnASingleLine
+                 ? tryMergeSimpleControlStatement(I, E, Limit)
+                 : 0;
+    }
+    if (TheLine->InPPDirective &&
+        (TheLine->First->HasUnescapedNewline || TheLine->First->IsFirst)) {
       return tryMergeSimplePPDirective(I, E, Limit);
     }
     return 0;
@@ -419,97 +643,113 @@
 
 private:
   unsigned
-  tryMergeSimplePPDirective(SmallVectorImpl<AnnotatedLine *>::const_iterator &I,
+  tryMergeSimplePPDirective(SmallVectorImpl<AnnotatedLine *>::const_iterator I,
                             SmallVectorImpl<AnnotatedLine *>::const_iterator E,
                             unsigned Limit) {
     if (Limit == 0)
       return 0;
-    if (!(*(I + 1))->InPPDirective || (*(I + 1))->First->HasUnescapedNewline)
+    if (!I[1]->InPPDirective || I[1]->First->HasUnescapedNewline)
       return 0;
-    if (I + 2 != E && (*(I + 2))->InPPDirective &&
-        !(*(I + 2))->First->HasUnescapedNewline)
+    if (I + 2 != E && I[2]->InPPDirective && !I[2]->First->HasUnescapedNewline)
       return 0;
-    if (1 + (*(I + 1))->Last->TotalLength > Limit)
+    if (1 + I[1]->Last->TotalLength > Limit)
       return 0;
     return 1;
   }
 
   unsigned tryMergeSimpleControlStatement(
-      SmallVectorImpl<AnnotatedLine *>::const_iterator &I,
+      SmallVectorImpl<AnnotatedLine *>::const_iterator I,
       SmallVectorImpl<AnnotatedLine *>::const_iterator E, unsigned Limit) {
     if (Limit == 0)
       return 0;
-    if (Style.BreakBeforeBraces == FormatStyle::BS_Allman &&
-        (*(I + 1))->First->is(tok::l_brace))
+    if ((Style.BreakBeforeBraces == FormatStyle::BS_Allman ||
+         Style.BreakBeforeBraces == FormatStyle::BS_GNU) &&
+        (I[1]->First->is(tok::l_brace) && !Style.AllowShortBlocksOnASingleLine))
       return 0;
-    if ((*(I + 1))->InPPDirective != (*I)->InPPDirective ||
-        ((*(I + 1))->InPPDirective && (*(I + 1))->First->HasUnescapedNewline))
+    if (I[1]->InPPDirective != (*I)->InPPDirective ||
+        (I[1]->InPPDirective && I[1]->First->HasUnescapedNewline))
       return 0;
+    Limit = limitConsideringMacros(I + 1, E, Limit);
     AnnotatedLine &Line = **I;
     if (Line.Last->isNot(tok::r_paren))
       return 0;
-    if (1 + (*(I + 1))->Last->TotalLength > Limit)
+    if (1 + I[1]->Last->TotalLength > Limit)
       return 0;
-    if ((*(I + 1))->First->isOneOf(tok::semi, tok::kw_if, tok::kw_for,
-                                   tok::kw_while) ||
-        (*(I + 1))->First->Type == TT_LineComment)
+    if (I[1]->First->isOneOf(tok::semi, tok::kw_if, tok::kw_for,
+                             tok::kw_while) ||
+        I[1]->First->Type == TT_LineComment)
       return 0;
     // Only inline simple if's (no nested if or else).
     if (I + 2 != E && Line.First->is(tok::kw_if) &&
-        (*(I + 2))->First->is(tok::kw_else))
+        I[2]->First->is(tok::kw_else))
       return 0;
     return 1;
   }
 
   unsigned
-  tryMergeSimpleBlock(SmallVectorImpl<AnnotatedLine *>::const_iterator &I,
+  tryMergeSimpleBlock(SmallVectorImpl<AnnotatedLine *>::const_iterator I,
                       SmallVectorImpl<AnnotatedLine *>::const_iterator E,
                       unsigned Limit) {
-    // No merging if the brace already is on the next line.
-    if (Style.BreakBeforeBraces != FormatStyle::BS_Attach)
-      return 0;
-
-    // First, check that the current line allows merging. This is the case if
-    // we're not in a control flow statement and the last token is an opening
-    // brace.
     AnnotatedLine &Line = **I;
-    if (Line.First->isOneOf(tok::kw_if, tok::kw_while, tok::kw_do, tok::r_brace,
-                            tok::kw_else, tok::kw_try, tok::kw_catch,
-                            tok::kw_for,
-                            // This gets rid of all ObjC @ keywords and methods.
-                            tok::at, tok::minus, tok::plus))
+
+    // Don't merge ObjC @ keywords and methods.
+    if (Line.First->isOneOf(tok::at, tok::minus, tok::plus))
       return 0;
 
-    FormatToken *Tok = (*(I + 1))->First;
+    // Check that the current line allows merging. This depends on whether we
+    // are in a control flow statements as well as several style flags.
+    if (Line.First->isOneOf(tok::kw_else, tok::kw_case))
+      return 0;
+    if (Line.First->isOneOf(tok::kw_if, tok::kw_while, tok::kw_do, tok::kw_try,
+                            tok::kw_catch, tok::kw_for, tok::r_brace)) {
+      if (!Style.AllowShortBlocksOnASingleLine)
+        return 0;
+      if (!Style.AllowShortIfStatementsOnASingleLine &&
+          Line.First->is(tok::kw_if))
+        return 0;
+      if (!Style.AllowShortLoopsOnASingleLine &&
+          Line.First->isOneOf(tok::kw_while, tok::kw_do, tok::kw_for))
+        return 0;
+      // FIXME: Consider an option to allow short exception handling clauses on
+      // a single line.
+      if (Line.First->isOneOf(tok::kw_try, tok::kw_catch))
+        return 0;
+    }
+
+    FormatToken *Tok = I[1]->First;
     if (Tok->is(tok::r_brace) && !Tok->MustBreakBefore &&
-        (Tok->getNextNonComment() == NULL ||
+        (Tok->getNextNonComment() == nullptr ||
          Tok->getNextNonComment()->is(tok::semi))) {
       // We merge empty blocks even if the line exceeds the column limit.
       Tok->SpacesRequiredBefore = 0;
       Tok->CanBreakBefore = true;
       return 1;
     } else if (Limit != 0 && Line.First->isNot(tok::kw_namespace)) {
-      // Check that we still have three lines and they fit into the limit.
-      if (I + 2 == E || (*(I + 2))->Type == LT_Invalid)
+      // We don't merge short records.
+      if (Line.First->isOneOf(tok::kw_class, tok::kw_union, tok::kw_struct))
         return 0;
 
+      // Check that we still have three lines and they fit into the limit.
+      if (I + 2 == E || I[2]->Type == LT_Invalid)
+        return 0;
+      Limit = limitConsideringMacros(I + 2, E, Limit);
+
       if (!nextTwoLinesFitInto(I, Limit))
         return 0;
 
       // Second, check that the next line does not contain any braces - if it
       // does, readability declines when putting it into a single line.
-      if ((*(I + 1))->Last->Type == TT_LineComment || Tok->MustBreakBefore)
+      if (I[1]->Last->Type == TT_LineComment)
         return 0;
       do {
-        if (Tok->isOneOf(tok::l_brace, tok::r_brace))
+        if (Tok->is(tok::l_brace) && Tok->BlockKind != BK_BracedInit)
           return 0;
         Tok = Tok->Next;
-      } while (Tok != NULL);
+      } while (Tok);
 
-      // Last, check that the third line contains a single closing brace.
-      Tok = (*(I + 2))->First;
-      if (Tok->getNextNonComment() != NULL || Tok->isNot(tok::r_brace) ||
-          Tok->MustBreakBefore)
+      // Last, check that the third line starts with a closing brace.
+      Tok = I[2]->First;
+      if (Tok->isNot(tok::r_brace))
         return 0;
 
       return 2;
@@ -517,11 +757,32 @@
     return 0;
   }
 
+  /// Returns the modified column limit for \p I if it is inside a macro and
+  /// needs a trailing '\'.
+  unsigned
+  limitConsideringMacros(SmallVectorImpl<AnnotatedLine *>::const_iterator I,
+                         SmallVectorImpl<AnnotatedLine *>::const_iterator E,
+                         unsigned Limit) {
+    if (I[0]->InPPDirective && I + 1 != E &&
+        !I[1]->First->HasUnescapedNewline && !I[1]->First->is(tok::eof)) {
+      return Limit < 2 ? 0 : Limit - 2;
+    }
+    return Limit;
+  }
+
   bool nextTwoLinesFitInto(SmallVectorImpl<AnnotatedLine *>::const_iterator I,
                            unsigned Limit) {
-    return 1 + (*(I + 1))->Last->TotalLength + 1 +
-               (*(I + 2))->Last->TotalLength <=
-           Limit;
+    if (I[1]->First->MustBreakBefore || I[2]->First->MustBreakBefore)
+      return false;
+    return 1 + I[1]->Last->TotalLength + 1 + I[2]->Last->TotalLength <= Limit;
+  }
+
+  bool containsMustBreak(const AnnotatedLine *Line) {
+    for (const FormatToken *Tok = Line->First; Tok; Tok = Tok->Next) {
+      if (Tok->MustBreakBefore)
+        return true;
+    }
+    return false;
   }
 
   const FormatStyle &Style;
@@ -529,24 +790,27 @@
 
 class UnwrappedLineFormatter {
 public:
-  UnwrappedLineFormatter(SourceManager &SourceMgr,
-                         SmallVectorImpl<CharSourceRange> &Ranges,
-                         ContinuationIndenter *Indenter,
+  UnwrappedLineFormatter(ContinuationIndenter *Indenter,
                          WhitespaceManager *Whitespaces,
                          const FormatStyle &Style)
-      : SourceMgr(SourceMgr), Ranges(Ranges), Indenter(Indenter),
-        Whitespaces(Whitespaces), Style(Style), Joiner(Style) {}
+      : Indenter(Indenter), Whitespaces(Whitespaces), Style(Style),
+        Joiner(Style) {}
 
   unsigned format(const SmallVectorImpl<AnnotatedLine *> &Lines, bool DryRun,
-                  int AdditionalIndent = 0) {
+                  int AdditionalIndent = 0, bool FixBadIndentation = false) {
+    // Try to look up already computed penalty in DryRun-mode.
+    std::pair<const SmallVectorImpl<AnnotatedLine *> *, unsigned> CacheKey(
+        &Lines, AdditionalIndent);
+    auto CacheIt = PenaltyCache.find(CacheKey);
+    if (DryRun && CacheIt != PenaltyCache.end())
+      return CacheIt->second;
+
     assert(!Lines.empty());
     unsigned Penalty = 0;
     std::vector<int> IndentForLevel;
     for (unsigned i = 0, e = Lines[0]->Level; i != e; ++i)
       IndentForLevel.push_back(Style.IndentWidth * i + AdditionalIndent);
-    bool PreviousLineWasTouched = false;
-    const AnnotatedLine *PreviousLine = NULL;
-    bool FormatPPDirective = false;
+    const AnnotatedLine *PreviousLine = nullptr;
     for (SmallVectorImpl<AnnotatedLine *>::const_iterator I = Lines.begin(),
                                                           E = Lines.end();
          I != E; ++I) {
@@ -554,40 +818,49 @@
       const FormatToken *FirstTok = TheLine.First;
       int Offset = getIndentOffset(*FirstTok);
 
-      // Check whether this line is part of a formatted preprocessor directive.
-      if (FirstTok->HasUnescapedNewline)
-        FormatPPDirective = false;
-      if (!FormatPPDirective && TheLine.InPPDirective &&
-          (touchesLine(TheLine) || touchesPPDirective(I + 1, E)))
-        FormatPPDirective = true;
-
       // Determine indent and try to merge multiple unwrapped lines.
-      while (IndentForLevel.size() <= TheLine.Level)
-        IndentForLevel.push_back(-1);
-      IndentForLevel.resize(TheLine.Level + 1);
-      unsigned Indent = getIndent(IndentForLevel, TheLine.Level);
+      unsigned Indent;
+      if (TheLine.InPPDirective) {
+        Indent = TheLine.Level * Style.IndentWidth;
+      } else {
+        while (IndentForLevel.size() <= TheLine.Level)
+          IndentForLevel.push_back(-1);
+        IndentForLevel.resize(TheLine.Level + 1);
+        Indent = getIndent(IndentForLevel, TheLine.Level);
+      }
+      unsigned LevelIndent = Indent;
       if (static_cast<int>(Indent) + Offset >= 0)
         Indent += Offset;
+
+      // Merge multiple lines if possible.
       unsigned MergedLines = Joiner.tryFitMultipleLinesInOne(Indent, I, E);
+      if (MergedLines > 0 && Style.ColumnLimit == 0) {
+        // Disallow line merging if there is a break at the start of one of the
+        // input lines.
+        for (unsigned i = 0; i < MergedLines; ++i) {
+          if (I[i + 1]->First->NewlinesBefore > 0)
+            MergedLines = 0;
+        }
+      }
       if (!DryRun) {
         for (unsigned i = 0; i < MergedLines; ++i) {
-          join(**(I + i), **(I + i + 1));
+          join(*I[i], *I[i + 1]);
         }
       }
       I += MergedLines;
 
-      bool WasMoved = PreviousLineWasTouched && FirstTok->NewlinesBefore == 0;
+      bool FixIndentation =
+          FixBadIndentation && (LevelIndent != FirstTok->OriginalColumn);
       if (TheLine.First->is(tok::eof)) {
-        if (PreviousLineWasTouched && !DryRun) {
+        if (PreviousLine && PreviousLine->Affected && !DryRun) {
+          // Remove the file's trailing whitespace.
           unsigned Newlines = std::min(FirstTok->NewlinesBefore, 1u);
           Whitespaces->replaceWhitespace(*TheLine.First, Newlines,
                                          /*IndentLevel=*/0, /*Spaces=*/0,
                                          /*TargetColumn=*/0);
         }
       } else if (TheLine.Type != LT_Invalid &&
-                 (WasMoved || FormatPPDirective || touchesLine(TheLine))) {
-        unsigned LevelIndent =
-            getIndent(IndentForLevel, TheLine.Level);
+                 (TheLine.Affected || FixIndentation)) {
         if (FirstTok->WhitespaceRange.isValid()) {
           if (!DryRun)
             formatFirstToken(*TheLine.First, PreviousLine, TheLine.Level,
@@ -599,16 +872,19 @@
         // If everything fits on a single line, just put it there.
         unsigned ColumnLimit = Style.ColumnLimit;
         if (I + 1 != E) {
-          AnnotatedLine *NextLine = *(I + 1);
+          AnnotatedLine *NextLine = I[1];
           if (NextLine->InPPDirective && !NextLine->First->HasUnescapedNewline)
             ColumnLimit = getColumnLimit(TheLine.InPPDirective);
         }
 
         if (TheLine.Last->TotalLength + Indent <= ColumnLimit) {
           LineState State = Indenter->getInitialState(Indent, &TheLine, DryRun);
-          while (State.NextToken != NULL)
+          while (State.NextToken) {
+            formatChildren(State, /*Newline=*/false, /*DryRun=*/false, Penalty);
             Indenter->addTokenToState(State, /*Newline=*/false, DryRun);
+          }
         } else if (Style.ColumnLimit == 0) {
+          // FIXME: Implement nested blocks for ColumnLimit = 0.
           NoColumnLimitFormatter Formatter(Indenter);
           if (!DryRun)
             Formatter.format(Indent, &TheLine);
@@ -616,19 +892,21 @@
           Penalty += format(TheLine, Indent, DryRun);
         }
 
-        IndentForLevel[TheLine.Level] = LevelIndent;
-        PreviousLineWasTouched = true;
+        if (!TheLine.InPPDirective)
+          IndentForLevel[TheLine.Level] = LevelIndent;
+      } else if (TheLine.ChildrenAffected) {
+        format(TheLine.Children, DryRun);
       } else {
         // Format the first token if necessary, and notify the WhitespaceManager
         // about the unchanged whitespace.
-        for (FormatToken *Tok = TheLine.First; Tok != NULL; Tok = Tok->Next) {
+        for (FormatToken *Tok = TheLine.First; Tok; Tok = Tok->Next) {
           if (Tok == TheLine.First &&
               (Tok->NewlinesBefore > 0 || Tok->IsFirst)) {
             unsigned LevelIndent = Tok->OriginalColumn;
             if (!DryRun) {
-              // Remove trailing whitespace of the previous line if it was
-              // touched.
-              if (PreviousLineWasTouched || touchesEmptyLineBefore(TheLine)) {
+              // Remove trailing whitespace of the previous line.
+              if ((PreviousLine && PreviousLine->Affected) ||
+                  TheLine.LeadingEmptyLinesAffected) {
                 formatFirstToken(*Tok, PreviousLine, TheLine.Level, LevelIndent,
                                  TheLine.InPPDirective);
               } else {
@@ -638,24 +916,21 @@
 
             if (static_cast<int>(LevelIndent) - Offset >= 0)
               LevelIndent -= Offset;
-            if (Tok->isNot(tok::comment))
+            if (Tok->isNot(tok::comment) && !TheLine.InPPDirective)
               IndentForLevel[TheLine.Level] = LevelIndent;
           } else if (!DryRun) {
             Whitespaces->addUntouchableToken(*Tok, TheLine.InPPDirective);
           }
         }
-        // If we did not reformat this unwrapped line, the column at the end of
-        // the last token is unchanged - thus, we can calculate the end of the
-        // last token.
-        PreviousLineWasTouched = false;
       }
       if (!DryRun) {
-        for (FormatToken *Tok = TheLine.First; Tok != NULL; Tok = Tok->Next) {
+        for (FormatToken *Tok = TheLine.First; Tok; Tok = Tok->Next) {
           Tok->Finalized = true;
         }
       }
       PreviousLine = *I;
     }
+    PenaltyCache[CacheKey] = Penalty;
     return Penalty;
   }
 
@@ -725,6 +1000,14 @@
       Newlines = std::min(Newlines, 1u);
     if (Newlines == 0 && !RootToken.IsFirst)
       Newlines = 1;
+    if (RootToken.IsFirst && !RootToken.HasUnescapedNewline)
+      Newlines = 0;
+
+    // Remove empty lines after "{".
+    if (!Style.KeepEmptyLinesAtTheStartOfBlocks && PreviousLine &&
+        PreviousLine->Last->is(tok::l_brace) &&
+        PreviousLine->First->isNot(tok::kw_namespace))
+      Newlines = 1;
 
     // Insert extra new line before access specifiers.
     if (PreviousLine && PreviousLine->Last->isOneOf(tok::semi, tok::r_brace) &&
@@ -735,9 +1018,9 @@
     if (PreviousLine && PreviousLine->First->isAccessSpecifier())
       Newlines = std::min(1u, Newlines);
 
-    Whitespaces->replaceWhitespace(
-        RootToken, Newlines, IndentLevel, Indent, Indent,
-        InPPDirective && !RootToken.HasUnescapedNewline);
+    Whitespaces->replaceWhitespace(RootToken, Newlines, IndentLevel, Indent,
+                                   Indent, InPPDirective &&
+                                               !RootToken.HasUnescapedNewline);
   }
 
   /// \brief Get the indent of \p Level from \p IndentForLevel.
@@ -756,6 +1039,8 @@
   void join(AnnotatedLine &A, const AnnotatedLine &B) {
     assert(!A.Last->Next);
     assert(!B.First->Previous);
+    if (B.Affected)
+      A.Affected = true;
     A.Last->Next = B.First;
     B.First->Previous = A.Last;
     B.First->CanBreakBefore = true;
@@ -771,47 +1056,11 @@
     return Style.ColumnLimit - (InPPDirective ? 2 : 0);
   }
 
-  bool touchesRanges(const CharSourceRange &Range) {
-    for (SmallVectorImpl<CharSourceRange>::const_iterator I = Ranges.begin(),
-                                                          E = Ranges.end();
-         I != E; ++I) {
-      if (!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(), I->getBegin()) &&
-          !SourceMgr.isBeforeInTranslationUnit(I->getEnd(), Range.getBegin()))
-        return true;
+  struct CompareLineStatePointers {
+    bool operator()(LineState *obj1, LineState *obj2) const {
+      return *obj1 < *obj2;
     }
-    return false;
-  }
-
-  bool touchesLine(const AnnotatedLine &TheLine) {
-    const FormatToken *First = TheLine.First;
-    const FormatToken *Last = TheLine.Last;
-    CharSourceRange LineRange = CharSourceRange::getCharRange(
-        First->WhitespaceRange.getBegin().getLocWithOffset(
-            First->LastNewlineOffset),
-        Last->getStartOfNonWhitespace().getLocWithOffset(
-            Last->TokenText.size() - 1));
-    return touchesRanges(LineRange);
-  }
-
-  bool touchesPPDirective(SmallVectorImpl<AnnotatedLine *>::const_iterator I,
-                          SmallVectorImpl<AnnotatedLine *>::const_iterator E) {
-    for (; I != E; ++I) {
-      if ((*I)->First->HasUnescapedNewline)
-        return false;
-      if (touchesLine(**I))
-        return true;
-    }
-    return false;
-  }
-
-  bool touchesEmptyLineBefore(const AnnotatedLine &TheLine) {
-    const FormatToken *First = TheLine.First;
-    CharSourceRange LineRange = CharSourceRange::getCharRange(
-        First->WhitespaceRange.getBegin(),
-        First->WhitespaceRange.getBegin().getLocWithOffset(
-            First->LastNewlineOffset));
-    return touchesRanges(LineRange);
-  }
+  };
 
   /// \brief Analyze the entire solution space starting from \p InitialState.
   ///
@@ -822,7 +1071,7 @@
   ///
   /// If \p DryRun is \c false, directly applies the changes.
   unsigned analyzeSolutionSpace(LineState &InitialState, bool DryRun = false) {
-    std::set<LineState> Seen;
+    std::set<LineState *, CompareLineStatePointers> Seen;
 
     // Increasing count of \c StateNode items we have created. This is used to
     // create a deterministic order independent of the container.
@@ -831,7 +1080,7 @@
 
     // Insert start element into queue.
     StateNode *Node =
-        new (Allocator.Allocate()) StateNode(InitialState, false, NULL);
+        new (Allocator.Allocate()) StateNode(InitialState, false, nullptr);
     Queue.push(QueueItem(OrderedPenalty(0, Count), Node));
     ++Count;
 
@@ -841,7 +1090,7 @@
     while (!Queue.empty()) {
       Penalty = Queue.top().first.first;
       StateNode *Node = Queue.top().second;
-      if (Node->State.NextToken == NULL) {
+      if (!Node->State.NextToken) {
         DEBUG(llvm::dbgs() << "\n---\nPenalty for line: " << Penalty << "\n");
         break;
       }
@@ -852,7 +1101,7 @@
       if (Count > 10000)
         Node->State.IgnoreStackForComparison = true;
 
-      if (!Seen.insert(Node->State).second)
+      if (!Seen.insert(&Node->State).second)
         // State already examined with lower penalty.
         continue;
 
@@ -956,20 +1205,38 @@
       return true;
 
     if (NewLine) {
-      int AdditionalIndent = State.Stack.back().Indent -
-                             Previous.Children[0]->Level * Style.IndentWidth;
-      Penalty += format(Previous.Children, DryRun, AdditionalIndent);
+      int AdditionalIndent =
+          State.FirstIndent - State.Line->Level * Style.IndentWidth;
+      if (State.Stack.size() < 2 ||
+          !State.Stack[State.Stack.size() - 2].JSFunctionInlined) {
+        AdditionalIndent = State.Stack.back().Indent -
+                           Previous.Children[0]->Level * Style.IndentWidth;
+      }
+
+      Penalty += format(Previous.Children, DryRun, AdditionalIndent,
+                        /*FixBadIndentation=*/true);
       return true;
     }
 
     // Cannot merge multiple statements into a single line.
     if (Previous.Children.size() > 1)
-      return false; 
+      return false;
+
+    // Cannot merge into one line if this line ends on a comment.
+    if (Previous.is(tok::comment))
+      return false;
 
     // We can't put the closing "}" on a line with a trailing comment.
     if (Previous.Children[0]->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)
+      return false;
+
     if (!DryRun) {
       Whitespaces->replaceWhitespace(
           *Previous.Children[0]->First,
@@ -982,31 +1249,43 @@
     return true;
   }
 
-  SourceManager &SourceMgr;
-  SmallVectorImpl<CharSourceRange> &Ranges;
   ContinuationIndenter *Indenter;
   WhitespaceManager *Whitespaces;
   FormatStyle Style;
   LineJoiner Joiner;
 
   llvm::SpecificBumpPtrAllocator<StateNode> Allocator;
+
+  // Cache to store the penalty of formatting a vector of AnnotatedLines
+  // starting from a specific additional offset. Improves performance if there
+  // are many nested blocks.
+  std::map<std::pair<const SmallVectorImpl<AnnotatedLine *> *, unsigned>,
+           unsigned> PenaltyCache;
 };
 
 class FormatTokenLexer {
 public:
   FormatTokenLexer(Lexer &Lex, SourceManager &SourceMgr, FormatStyle &Style,
                    encoding::Encoding Encoding)
-      : FormatTok(NULL), IsFirstToken(true), GreaterStashed(false), Column(0),
-        TrailingWhitespace(0), Lex(Lex), SourceMgr(SourceMgr), Style(Style),
-        IdentTable(getFormattingLangOpts()), Encoding(Encoding) {
+      : FormatTok(nullptr), IsFirstToken(true), GreaterStashed(false),
+        Column(0), TrailingWhitespace(0), Lex(Lex), SourceMgr(SourceMgr),
+        Style(Style), IdentTable(getFormattingLangOpts()), Encoding(Encoding),
+        FirstInLineIndex(0) {
     Lex.SetKeepWhitespaceMode(true);
+
+    for (const std::string &ForEachMacro : Style.ForEachMacros)
+      ForEachMacros.push_back(&IdentTable.get(ForEachMacro));
+    std::sort(ForEachMacros.begin(), ForEachMacros.end());
   }
 
   ArrayRef<FormatToken *> lex() {
     assert(Tokens.empty());
+    assert(FirstInLineIndex == 0);
     do {
       Tokens.push_back(getNextToken());
-      maybeJoinPreviousTokens();
+      tryMergePreviousTokens();
+      if (Tokens.back()->NewlinesBefore > 0)
+        FirstInLineIndex = Tokens.size() - 1;
     } while (Tokens.back()->Tok.isNot(tok::eof));
     return Tokens;
   }
@@ -1014,23 +1293,125 @@
   IdentifierTable &getIdentTable() { return IdentTable; }
 
 private:
-  void maybeJoinPreviousTokens() {
-    if (Tokens.size() < 4)
+  void tryMergePreviousTokens() {
+    if (tryMerge_TMacro())
       return;
+    if (tryMergeConflictMarkers())
+      return;
+
+    if (Style.Language == FormatStyle::LK_JavaScript) {
+      if (tryMergeEscapeSequence())
+        return;
+      if (tryMergeJSRegexLiteral())
+        return;
+
+      static tok::TokenKind JSIdentity[] = { tok::equalequal, tok::equal };
+      static tok::TokenKind JSNotIdentity[] = { tok::exclaimequal, tok::equal };
+      static tok::TokenKind JSShiftEqual[] = { tok::greater, tok::greater,
+                                               tok::greaterequal };
+      static tok::TokenKind JSRightArrow[] = { tok::equal, tok::greater };
+      // FIXME: We probably need to change token type to mimic operator with the
+      // correct priority.
+      if (tryMergeTokens(JSIdentity))
+        return;
+      if (tryMergeTokens(JSNotIdentity))
+        return;
+      if (tryMergeTokens(JSShiftEqual))
+        return;
+      if (tryMergeTokens(JSRightArrow))
+        return;
+    }
+  }
+
+  bool tryMergeTokens(ArrayRef<tok::TokenKind> Kinds) {
+    if (Tokens.size() < Kinds.size())
+      return false;
+
+    SmallVectorImpl<FormatToken *>::const_iterator First =
+        Tokens.end() - Kinds.size();
+    if (!First[0]->is(Kinds[0]))
+      return false;
+    unsigned AddLength = 0;
+    for (unsigned i = 1; i < Kinds.size(); ++i) {
+      if (!First[i]->is(Kinds[i]) || First[i]->WhitespaceRange.getBegin() !=
+                                         First[i]->WhitespaceRange.getEnd())
+        return false;
+      AddLength += First[i]->TokenText.size();
+    }
+    Tokens.resize(Tokens.size() - Kinds.size() + 1);
+    First[0]->TokenText = StringRef(First[0]->TokenText.data(),
+                                    First[0]->TokenText.size() + AddLength);
+    First[0]->ColumnWidth += AddLength;
+    return true;
+  }
+
+  // Tries to merge an escape sequence, i.e. a "\\" and the following
+  // character. Use e.g. inside JavaScript regex literals.
+  bool tryMergeEscapeSequence() {
+    if (Tokens.size() < 2)
+      return false;
+    FormatToken *Previous = Tokens[Tokens.size() - 2];
+    if (Previous->isNot(tok::unknown) || Previous->TokenText != "\\" ||
+        Tokens.back()->NewlinesBefore != 0)
+      return false;
+    Previous->ColumnWidth += Tokens.back()->ColumnWidth;
+    StringRef Text = Previous->TokenText;
+    Previous->TokenText =
+        StringRef(Text.data(), Text.size() + Tokens.back()->TokenText.size());
+    Tokens.resize(Tokens.size() - 1);
+    return true;
+  }
+
+  // Try to determine whether the current token ends a JavaScript regex literal.
+  // We heuristically assume that this is a regex literal if we find two
+  // unescaped slashes on a line and the token before the first slash is one of
+  // "(;,{}![:?", a binary operator or 'return', as those cannot be followed by
+  // a division.
+  bool tryMergeJSRegexLiteral() {
+    if (Tokens.size() < 2 || Tokens.back()->isNot(tok::slash) ||
+        (Tokens[Tokens.size() - 2]->is(tok::unknown) &&
+         Tokens[Tokens.size() - 2]->TokenText == "\\"))
+      return false;
+    unsigned TokenCount = 0;
+    unsigned LastColumn = Tokens.back()->OriginalColumn;
+    for (auto I = Tokens.rbegin() + 1, E = Tokens.rend(); I != E; ++I) {
+      ++TokenCount;
+      if (I[0]->is(tok::slash) && I + 1 != E &&
+          (I[1]->isOneOf(tok::l_paren, tok::semi, tok::l_brace, tok::r_brace,
+                         tok::exclaim, tok::l_square, tok::colon, tok::comma,
+                         tok::question, tok::kw_return) ||
+           I[1]->isBinaryOperator())) {
+        Tokens.resize(Tokens.size() - TokenCount);
+        Tokens.back()->Tok.setKind(tok::unknown);
+        Tokens.back()->Type = TT_RegexLiteral;
+        Tokens.back()->ColumnWidth += LastColumn - I[0]->OriginalColumn;
+        return true;
+      }
+
+      // There can't be a newline inside a regex literal.
+      if (I[0]->NewlinesBefore > 0)
+        return false;
+    }
+    return false;
+  }
+
+  bool tryMerge_TMacro() {
+    if (Tokens.size() < 4)
+      return false;
     FormatToken *Last = Tokens.back();
     if (!Last->is(tok::r_paren))
-      return;
+      return false;
 
     FormatToken *String = Tokens[Tokens.size() - 2];
     if (!String->is(tok::string_literal) || String->IsMultiline)
-      return;
+      return false;
 
     if (!Tokens[Tokens.size() - 3]->is(tok::l_paren))
-      return;
+      return false;
 
     FormatToken *Macro = Tokens[Tokens.size() - 4];
     if (Macro->TokenText != "_T")
-      return;
+      return false;
 
     const char *Start = Macro->TokenText.data();
     const char *End = Last->TokenText.data() + Last->TokenText.size();
@@ -1046,6 +1427,69 @@
     Tokens.pop_back();
     Tokens.pop_back();
     Tokens.back() = String;
+    return true;
+  }
+
+  bool tryMergeConflictMarkers() {
+    if (Tokens.back()->NewlinesBefore == 0 && Tokens.back()->isNot(tok::eof))
+      return false;
+
+    // Conflict lines look like:
+    // <marker> <text from the vcs>
+    // For example:
+    // >>>>>>> /file/in/file/system at revision 1234
+    //
+    // We merge all tokens in a line that starts with a conflict marker
+    // into a single token with a special token type that the unwrapped line
+    // parser will use to correctly rebuild the underlying code.
+
+    FileID ID;
+    // Get the position of the first token in the line.
+    unsigned FirstInLineOffset;
+    std::tie(ID, FirstInLineOffset) = SourceMgr.getDecomposedLoc(
+        Tokens[FirstInLineIndex]->getStartOfNonWhitespace());
+    StringRef Buffer = SourceMgr.getBuffer(ID)->getBuffer();
+    // Calculate the offset of the start of the current line.
+    auto LineOffset = Buffer.rfind('\n', FirstInLineOffset);
+    if (LineOffset == StringRef::npos) {
+      LineOffset = 0;
+    } else {
+      ++LineOffset;
+    }
+
+    auto FirstSpace = Buffer.find_first_of(" \n", LineOffset);
+    StringRef LineStart;
+    if (FirstSpace == StringRef::npos) {
+      LineStart = Buffer.substr(LineOffset);
+    } else {
+      LineStart = Buffer.substr(LineOffset, FirstSpace - LineOffset);
+    }
+
+    TokenType Type = TT_Unknown;
+    if (LineStart == "<<<<<<<" || LineStart == ">>>>") {
+      Type = TT_ConflictStart;
+    } else if (LineStart == "|||||||" || LineStart == "=======" ||
+               LineStart == "====") {
+      Type = TT_ConflictAlternative;
+    } else if (LineStart == ">>>>>>>" || LineStart == "<<<<") {
+      Type = TT_ConflictEnd;
+    }
+
+    if (Type != TT_Unknown) {
+      FormatToken *Next = Tokens.back();
+
+      Tokens.resize(FirstInLineIndex + 1);
+      // We do not need to build a complete token here, as we will skip it
+      // during parsing anyway (as we must not touch whitespace around conflict
+      // markers).
+      Tokens.back()->Type = Type;
+      Tokens.back()->Tok.setKind(tok::kw___unknown_anytype);
+
+      Tokens.push_back(Next);
+      return true;
+    }
+
+    return false;
   }
 
   FormatToken *getNextToken() {
@@ -1125,7 +1569,7 @@
     // FIXME: Add a more explicit test.
     while (FormatTok->TokenText.size() > 1 && FormatTok->TokenText[0] == '\\' &&
            FormatTok->TokenText[1] == '\n') {
-      // FIXME: ++FormatTok->NewlinesBefore is missing...
+      ++FormatTok->NewlinesBefore;
       WhitespaceLength += 2;
       Column = 0;
       FormatTok->TokenText = FormatTok->TokenText.substr(2);
@@ -1177,6 +1621,10 @@
       Column = FormatTok->LastLineColumnWidth;
     }
 
+    FormatTok->IsForEachMacro =
+        std::binary_search(ForEachMacros.begin(), ForEachMacros.end(),
+                           FormatTok->Tok.getIdentifierInfo());
+
     return FormatTok;
   }
 
@@ -1191,7 +1639,10 @@
   IdentifierTable IdentTable;
   encoding::Encoding Encoding;
   llvm::SpecificBumpPtrAllocator<FormatToken> Allocator;
+  // Index (in 'Tokens') of the last token that starts a new line.
+  unsigned FirstInLineIndex;
   SmallVector<FormatToken *, 16> Tokens;
+  SmallVector<IdentifierInfo *, 8> ForEachMacros;
 
   void readRawToken(FormatToken &Tok) {
     Lex.LexFromRawLexer(Tok.Tok);
@@ -1199,14 +1650,31 @@
                               Tok.Tok.getLength());
     // For formatting, treat unterminated string literals like normal string
     // literals.
-    if (Tok.is(tok::unknown) && !Tok.TokenText.empty() &&
-        Tok.TokenText[0] == '"') {
-      Tok.Tok.setKind(tok::string_literal);
-      Tok.IsUnterminatedLiteral = true;
+    if (Tok.is(tok::unknown)) {
+      if (!Tok.TokenText.empty() && Tok.TokenText[0] == '"') {
+        Tok.Tok.setKind(tok::string_literal);
+        Tok.IsUnterminatedLiteral = true;
+      } else if (Style.Language == FormatStyle::LK_JavaScript &&
+                 Tok.TokenText == "''") {
+        Tok.Tok.setKind(tok::char_constant);
+      }
     }
   }
 };
 
+static StringRef getLanguageName(FormatStyle::LanguageKind Language) {
+  switch (Language) {
+  case FormatStyle::LK_Cpp:
+    return "C++";
+  case FormatStyle::LK_JavaScript:
+    return "JavaScript";
+  case FormatStyle::LK_Proto:
+    return "Proto";
+  default:
+    return "Unknown";
+  }
+}
+
 class Formatter : public UnwrappedLineConsumer {
 public:
   Formatter(const FormatStyle &Style, Lexer &Lex, SourceManager &SourceMgr,
@@ -1219,6 +1687,8 @@
                        << (Encoding == encoding::Encoding_UTF8 ? "UTF8"
                                                                : "unknown")
                        << "\n");
+    DEBUG(llvm::dbgs() << "Language: " << getLanguageName(Style.Language)
+                       << "\n");
   }
 
   tooling::Replacements format() {
@@ -1264,17 +1734,151 @@
     for (unsigned i = 0, e = AnnotatedLines.size(); i != e; ++i) {
       Annotator.calculateFormattingInformation(*AnnotatedLines[i]);
     }
+    computeAffectedLines(AnnotatedLines.begin(), AnnotatedLines.end());
 
     Annotator.setCommentLineLevels(AnnotatedLines);
     ContinuationIndenter Indenter(Style, SourceMgr, Whitespaces, Encoding,
                                   BinPackInconclusiveFunctions);
-    UnwrappedLineFormatter Formatter(SourceMgr, Ranges, &Indenter, &Whitespaces,
-                                     Style);
+    UnwrappedLineFormatter Formatter(&Indenter, &Whitespaces, Style);
     Formatter.format(AnnotatedLines, /*DryRun=*/false);
     return Whitespaces.generateReplacements();
   }
 
 private:
+  // Determines which lines are affected by the SourceRanges given as input.
+  // Returns \c true if at least one line between I and E or one of their
+  // children is affected.
+  bool computeAffectedLines(SmallVectorImpl<AnnotatedLine *>::iterator I,
+                            SmallVectorImpl<AnnotatedLine *>::iterator E) {
+    bool SomeLineAffected = false;
+    const AnnotatedLine *PreviousLine = nullptr;
+    while (I != E) {
+      AnnotatedLine *Line = *I;
+      Line->LeadingEmptyLinesAffected = affectsLeadingEmptyLines(*Line->First);
+
+      // If a line is part of a preprocessor directive, it needs to be formatted
+      // if any token within the directive is affected.
+      if (Line->InPPDirective) {
+        FormatToken *Last = Line->Last;
+        SmallVectorImpl<AnnotatedLine *>::iterator PPEnd = I + 1;
+        while (PPEnd != E && !(*PPEnd)->First->HasUnescapedNewline) {
+          Last = (*PPEnd)->Last;
+          ++PPEnd;
+        }
+
+        if (affectsTokenRange(*Line->First, *Last,
+                              /*IncludeLeadingNewlines=*/false)) {
+          SomeLineAffected = true;
+          markAllAsAffected(I, PPEnd);
+        }
+        I = PPEnd;
+        continue;
+      }
+
+      if (nonPPLineAffected(Line, PreviousLine))
+        SomeLineAffected = true;
+
+      PreviousLine = Line;
+      ++I;
+    }
+    return SomeLineAffected;
+  }
+
+  // Determines whether 'Line' is affected by the SourceRanges given as input.
+  // Returns \c true if line or one if its children is affected.
+  bool nonPPLineAffected(AnnotatedLine *Line,
+                         const AnnotatedLine *PreviousLine) {
+    bool SomeLineAffected = false;
+    Line->ChildrenAffected =
+        computeAffectedLines(Line->Children.begin(), Line->Children.end());
+    if (Line->ChildrenAffected)
+      SomeLineAffected = true;
+
+    // Stores whether one of the line's tokens is directly affected.
+    bool SomeTokenAffected = false;
+    // Stores whether we need to look at the leading newlines of the next token
+    // in order to determine whether it was affected.
+    bool IncludeLeadingNewlines = false;
+
+    // Stores whether the first child line of any of this line's tokens is
+    // affected.
+    bool SomeFirstChildAffected = false;
+
+    for (FormatToken *Tok = Line->First; Tok; Tok = Tok->Next) {
+      // Determine whether 'Tok' was affected.
+      if (affectsTokenRange(*Tok, *Tok, IncludeLeadingNewlines))
+        SomeTokenAffected = true;
+
+      // Determine whether the first child of 'Tok' was affected.
+      if (!Tok->Children.empty() && Tok->Children.front()->Affected)
+        SomeFirstChildAffected = true;
+
+      IncludeLeadingNewlines = Tok->Children.empty();
+    }
+
+    // Was this line moved, i.e. has it previously been on the same line as an
+    // affected line?
+    bool LineMoved = PreviousLine && PreviousLine->Affected &&
+                     Line->First->NewlinesBefore == 0;
+
+    bool IsContinuedComment =
+        Line->First->is(tok::comment) && Line->First->Next == nullptr &&
+        Line->First->NewlinesBefore < 2 && PreviousLine &&
+        PreviousLine->Affected && PreviousLine->Last->is(tok::comment);
+
+    if (SomeTokenAffected || SomeFirstChildAffected || LineMoved ||
+        IsContinuedComment) {
+      Line->Affected = true;
+      SomeLineAffected = true;
+    }
+    return SomeLineAffected;
+  }
+
+  // Marks all lines between I and E as well as all their children as affected.
+  void markAllAsAffected(SmallVectorImpl<AnnotatedLine *>::iterator I,
+                         SmallVectorImpl<AnnotatedLine *>::iterator E) {
+    while (I != E) {
+      (*I)->Affected = true;
+      markAllAsAffected((*I)->Children.begin(), (*I)->Children.end());
+      ++I;
+    }
+  }
+
+  // Returns true if the range from 'First' to 'Last' intersects with one of the
+  // input ranges.
+  bool affectsTokenRange(const FormatToken &First, const FormatToken &Last,
+                         bool IncludeLeadingNewlines) {
+    SourceLocation Start = First.WhitespaceRange.getBegin();
+    if (!IncludeLeadingNewlines)
+      Start = Start.getLocWithOffset(First.LastNewlineOffset);
+    SourceLocation End = Last.getStartOfNonWhitespace();
+    if (Last.TokenText.size() > 0)
+      End = End.getLocWithOffset(Last.TokenText.size() - 1);
+    CharSourceRange Range = CharSourceRange::getCharRange(Start, End);
+    return affectsCharSourceRange(Range);
+  }
+
+  // Returns true if one of the input ranges intersect the leading empty lines
+  // before 'Tok'.
+  bool affectsLeadingEmptyLines(const FormatToken &Tok) {
+    CharSourceRange EmptyLineRange = CharSourceRange::getCharRange(
+        Tok.WhitespaceRange.getBegin(),
+        Tok.WhitespaceRange.getBegin().getLocWithOffset(Tok.LastNewlineOffset));
+    return affectsCharSourceRange(EmptyLineRange);
+  }
+
+  // Returns true if 'Range' intersects with one of the input ranges.
+  bool affectsCharSourceRange(const CharSourceRange &Range) {
+    for (SmallVectorImpl<CharSourceRange>::const_iterator I = Ranges.begin(),
+                                                          E = Ranges.end();
+         I != E; ++I) {
+      if (!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(), I->getBegin()) &&
+          !SourceMgr.isBeforeInTranslationUnit(I->getEnd(), Range.getBegin()))
+        return true;
+    }
+    return false;
+  }
+
   static bool inputUsesCRLF(StringRef Text) {
     return Text.count('\r') * 2 > Text.count('\n');
   }
@@ -1319,11 +1923,11 @@
         Tok = Tok->Next;
       }
     }
-    if (Style.DerivePointerBinding) {
+    if (Style.DerivePointerAlignment) {
       if (CountBoundToType > CountBoundToVariable)
-        Style.PointerBindsToType = true;
+        Style.PointerAlignment = FormatStyle::PAS_Left;
       else if (CountBoundToType < CountBoundToVariable)
-        Style.PointerBindsToType = false;
+        Style.PointerAlignment = FormatStyle::PAS_Right;
     }
     if (Style.Standard == FormatStyle::LS_Auto) {
       Style.Standard = HasCpp03IncompatibleFormat ? FormatStyle::LS_Cpp11
@@ -1333,12 +1937,12 @@
         HasBinPackedFunction || !HasOnePerLineFunction;
   }
 
-  virtual void consumeUnwrappedLine(const UnwrappedLine &TheLine) {
+  void consumeUnwrappedLine(const UnwrappedLine &TheLine) override {
     assert(!UnwrappedLines.empty());
     UnwrappedLines.back().push_back(TheLine);
   }
 
-  virtual void finishRun() {
+  void finishRun() override {
     UnwrappedLines.push_back(SmallVector<UnwrappedLine, 16>());
   }
 
@@ -1358,6 +1962,11 @@
 tooling::Replacements reformat(const FormatStyle &Style, Lexer &Lex,
                                SourceManager &SourceMgr,
                                std::vector<CharSourceRange> Ranges) {
+  if (Style.DisableFormat) {
+    tooling::Replacements EmptyResult;
+    return EmptyResult;
+  }
+
   Formatter formatter(Style, Lex, SourceMgr, Ranges);
   return formatter.format();
 }
@@ -1392,7 +2001,9 @@
   LangOptions LangOpts;
   LangOpts.CPlusPlus = 1;
   LangOpts.CPlusPlus11 = Standard == FormatStyle::LS_Cpp03 ? 0 : 1;
+  LangOpts.CPlusPlus1y = Standard == FormatStyle::LS_Cpp03 ? 0 : 1;
   LangOpts.LineComment = 1;
+  LangOpts.CXXOperatorNames = 1;
   LangOpts.Bool = 1;
   LangOpts.ObjC1 = 1;
   LangOpts.ObjC2 = 1;
@@ -1410,15 +2021,29 @@
     "parameters, e.g.:\n"
     "  -style=\"{BasedOnStyle: llvm, IndentWidth: 8}\"";
 
-FormatStyle getStyle(StringRef StyleName, StringRef FileName) {
-  // Fallback style in case the rest of this function can't determine a style.
-  StringRef FallbackStyle = "LLVM";
-  FormatStyle Style;
-  getPredefinedStyle(FallbackStyle, &Style);
+static FormatStyle::LanguageKind getLanguageByFileName(StringRef FileName) {
+  if (FileName.endswith_lower(".js")) {
+    return FormatStyle::LK_JavaScript;
+  } else if (FileName.endswith_lower(".proto") ||
+             FileName.endswith_lower(".protodevel")) {
+    return FormatStyle::LK_Proto;
+  }
+  return FormatStyle::LK_Cpp;
+}
+
+FormatStyle getStyle(StringRef StyleName, StringRef FileName,
+                     StringRef FallbackStyle) {
+  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;
+  }
 
   if (StyleName.startswith("{")) {
     // Parse YAML/JSON style from the command line.
-    if (llvm::error_code ec = parseConfiguration(StyleName, &Style)) {
+    if (std::error_code ec = parseConfiguration(StyleName, &Style)) {
       llvm::errs() << "Error parsing -style: " << ec.message() << ", using "
                    << FallbackStyle << " style\n";
     }
@@ -1426,12 +2051,14 @@
   }
 
   if (!StyleName.equals_lower("file")) {
-    if (!getPredefinedStyle(StyleName, &Style))
+    if (!getPredefinedStyle(StyleName, Style.Language, &Style))
       llvm::errs() << "Invalid value for -style, using " << FallbackStyle
                    << " style\n";
     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);
   for (StringRef Directory = Path; !Directory.empty();
@@ -1456,16 +2083,23 @@
     }
 
     if (IsFile) {
-      OwningPtr<llvm::MemoryBuffer> Text;
-      if (llvm::error_code ec =
-              llvm::MemoryBuffer::getFile(ConfigFile.c_str(), Text)) {
-        llvm::errs() << ec.message() << "\n";
-        continue;
+      llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
+          llvm::MemoryBuffer::getFile(ConfigFile.c_str());
+      if (std::error_code EC = Text.getError()) {
+        llvm::errs() << EC.message() << "\n";
+        break;
       }
-      if (llvm::error_code ec = parseConfiguration(Text->getBuffer(), &Style)) {
+      if (std::error_code ec =
+              parseConfiguration(Text.get()->getBuffer(), &Style)) {
+        if (ec == ParseError::Unsuitable) {
+          if (!UnsuitableConfigFiles.empty())
+            UnsuitableConfigFiles.append(", ");
+          UnsuitableConfigFiles.append(ConfigFile);
+          continue;
+        }
         llvm::errs() << "Error reading " << ConfigFile << ": " << ec.message()
                      << "\n";
-        continue;
+        break;
       }
       DEBUG(llvm::dbgs() << "Using configuration file " << ConfigFile << "\n");
       return Style;
@@ -1473,6 +2107,11 @@
   }
   llvm::errs() << "Can't find usable .clang-format, using " << FallbackStyle
                << " style\n";
+  if (!UnsuitableConfigFiles.empty()) {
+    llvm::errs() << "Configuration file(s) do(es) not support "
+                 << getLanguageName(Style.Language) << ": "
+                 << UnsuitableConfigFiles << "\n";
+  }
   return Style;
 }
 
diff --git a/lib/Format/FormatToken.cpp b/lib/Format/FormatToken.cpp
index 8ac704a..c91d25f 100644
--- a/lib/Format/FormatToken.cpp
+++ b/lib/Format/FormatToken.cpp
@@ -22,34 +22,65 @@
 namespace clang {
 namespace format {
 
+// FIXME: This is copy&pasted from Sema. Put it in a common place and remove
+// duplication.
+bool FormatToken::isSimpleTypeSpecifier() const {
+  switch (Tok.getKind()) {
+  case tok::kw_short:
+  case tok::kw_long:
+  case tok::kw___int64:
+  case tok::kw___int128:
+  case tok::kw_signed:
+  case tok::kw_unsigned:
+  case tok::kw_void:
+  case tok::kw_char:
+  case tok::kw_int:
+  case tok::kw_half:
+  case tok::kw_float:
+  case tok::kw_double:
+  case tok::kw_wchar_t:
+  case tok::kw_bool:
+  case tok::kw___underlying_type:
+  case tok::annot_typename:
+  case tok::kw_char16_t:
+  case tok::kw_char32_t:
+  case tok::kw_typeof:
+  case tok::kw_decltype:
+    return true;
+  default:
+    return false;
+  }
+}
+
 TokenRole::~TokenRole() {}
 
 void TokenRole::precomputeFormattingInfos(const FormatToken *Token) {}
 
-unsigned CommaSeparatedList::format(LineState &State,
-                                    ContinuationIndenter *Indenter,
-                                    bool DryRun) {
-  if (!State.NextToken->Previous || !State.NextToken->Previous->Previous ||
-      Commas.size() <= 2)
+unsigned CommaSeparatedList::formatAfterToken(LineState &State,
+                                              ContinuationIndenter *Indenter,
+                                              bool DryRun) {
+  if (!State.NextToken->Previous || !State.NextToken->Previous->Previous)
     return 0;
 
   // Ensure that we start on the opening brace.
   const FormatToken *LBrace = State.NextToken->Previous->Previous;
-  if (LBrace->isNot(tok::l_brace) ||
-      LBrace->BlockKind == BK_Block ||
+  if (LBrace->isNot(tok::l_brace) || LBrace->BlockKind == BK_Block ||
       LBrace->Type == TT_DictLiteral ||
       LBrace->Next->Type == TT_DesignatedInitializerPeriod)
     return 0;
 
   // Calculate the number of code points we have to format this list. As the
   // first token is already placed, we have to subtract it.
-  unsigned RemainingCodePoints = Style.ColumnLimit - State.Column +
-                                 State.NextToken->Previous->ColumnWidth;
+  unsigned RemainingCodePoints =
+      Style.ColumnLimit - State.Column + State.NextToken->Previous->ColumnWidth;
 
   // 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.
   if (!Format)
-    return 0;
+    return 10000;
 
   // Format the entire list.
   unsigned Penalty = 0;
@@ -79,6 +110,14 @@
   return Penalty;
 }
 
+unsigned CommaSeparatedList::formatFromToken(LineState &State,
+                                             ContinuationIndenter *Indenter,
+                                             bool DryRun) {
+  if (HasNestedBracedList)
+    State.Stack.back().AvoidBinPacking = true;
+  return 0;
+}
+
 // Returns the lengths in code points between Begin and End (both included),
 // assuming that the entire sequence is put on a single line.
 static unsigned CodePointsBetween(const FormatToken *Begin,
@@ -92,6 +131,11 @@
   if (!Token->MatchingParen || Token->isNot(tok::l_brace))
     return;
 
+  // In C++11 braced list style, we should not format in columns unless we allow
+  // bin-packing of function parameters.
+  if (Style.Cpp11BracedListStyle && !Style.BinPackParameters)
+    return;
+
   FormatToken *ItemBegin = Token->Next;
   SmallVector<bool, 8> MustBreakBeforeItem;
 
@@ -99,7 +143,6 @@
   // trailing comments which are otherwise ignored for column alignment.
   SmallVector<unsigned, 8> EndOfLineItemLength;
 
-  bool HasNestedBracedList = false;
   for (unsigned i = 0, e = Commas.size() + 1; i != e; ++i) {
     // Skip comments on their own line.
     while (ItemBegin->HasUnescapedNewline && ItemBegin->isTrailingComment())
@@ -108,7 +151,7 @@
     MustBreakBeforeItem.push_back(ItemBegin->MustBreakBefore);
     if (ItemBegin->is(tok::l_brace))
       HasNestedBracedList = true;
-    const FormatToken *ItemEnd = NULL;
+    const FormatToken *ItemEnd = nullptr;
     if (i == Commas.size()) {
       ItemEnd = Token->MatchingParen;
       const FormatToken *NonCommentEnd = ItemEnd->getPreviousNonComment();
@@ -139,6 +182,12 @@
     ItemBegin = ItemEnd->Next;
   }
 
+  // If this doesn't have a nested list, we require at least 6 elements in order
+  // create a column layout. If it has a nested list, column layout ensures one
+  // list element per line.
+  if (HasNestedBracedList || Commas.size() < 5 || Token->NestingLevel != 0)
+    return;
+
   // We can never place more than ColumnLimit / 3 items in a row (because of the
   // spaces and the comma).
   for (unsigned Columns = 1; Columns <= Style.ColumnLimit / 3; ++Columns) {
@@ -158,8 +207,7 @@
         HasRowWithSufficientColumns = true;
       unsigned length =
           (Column == Columns - 1) ? EndOfLineItemLength[i] : ItemLengths[i];
-      Format.ColumnSizes[Column] =
-          std::max(Format.ColumnSizes[Column], length);
+      Format.ColumnSizes[Column] = std::max(Format.ColumnSizes[Column], length);
       ++Column;
     }
     // If all rows are terminated early (e.g. by trailing comments), we don't
@@ -175,18 +223,13 @@
     if (Format.TotalWidth > Style.ColumnLimit)
       continue;
 
-    // If this braced list has nested braced list, we format it either with one
-    // element per line or with all elements on one line.
-    if (HasNestedBracedList && Columns > 1 && Format.LineCount > 1)
-      continue;
-
     Formats.push_back(Format);
   }
 }
 
 const CommaSeparatedList::ColumnFormat *
 CommaSeparatedList::getColumnFormat(unsigned RemainingCharacters) const {
-  const ColumnFormat *BestFormat = NULL;
+  const ColumnFormat *BestFormat = nullptr;
   for (SmallVector<ColumnFormat, 4>::const_reverse_iterator
            I = Formats.rbegin(),
            E = Formats.rend();
diff --git a/lib/Format/FormatToken.h b/lib/Format/FormatToken.h
index 2145ee2..c376c50 100644
--- a/lib/Format/FormatToken.h
+++ b/lib/Format/FormatToken.h
@@ -19,7 +19,7 @@
 #include "clang/Basic/OperatorPrecedence.h"
 #include "clang/Format/Format.h"
 #include "clang/Lex/Lexer.h"
-#include "llvm/ADT/OwningPtr.h"
+#include <memory>
 
 namespace clang {
 namespace format {
@@ -27,36 +27,45 @@
 enum TokenType {
   TT_ArrayInitializerLSquare,
   TT_ArraySubscriptLSquare,
+  TT_AttributeParen,
   TT_BinaryOperator,
   TT_BitFieldColon,
   TT_BlockComment,
   TT_CastRParen,
   TT_ConditionalExpr,
+  TT_ConflictAlternative,
+  TT_ConflictEnd,
+  TT_ConflictStart,
   TT_CtorInitializerColon,
   TT_CtorInitializerComma,
   TT_DesignatedInitializerPeriod,
   TT_DictLiteral,
-  TT_ImplicitStringLiteral,
-  TT_InlineASMColon,
-  TT_InheritanceColon,
+  TT_FunctionDeclarationName,
+  TT_FunctionLBrace,
   TT_FunctionTypeLParen,
+  TT_ImplicitStringLiteral,
+  TT_InheritanceColon,
+  TT_InlineASMColon,
   TT_LambdaLSquare,
   TT_LineComment,
+  TT_ObjCBlockLBrace,
   TT_ObjCBlockLParen,
   TT_ObjCDecl,
   TT_ObjCForIn,
   TT_ObjCMethodExpr,
   TT_ObjCMethodSpecifier,
   TT_ObjCProperty,
-  TT_ObjCSelectorName,
   TT_OverloadedOperator,
   TT_OverloadedOperatorLParen,
   TT_PointerOrReference,
   TT_PureVirtualSpecifier,
   TT_RangeBasedForLoopColon,
+  TT_RegexLiteral,
+  TT_SelectorName,
   TT_StartOfName,
   TT_TemplateCloser,
   TT_TemplateOpener,
+  TT_TrailingAnnotation,
   TT_TrailingReturnArrow,
   TT_TrailingUnaryOperator,
   TT_UnaryOperator,
@@ -87,7 +96,7 @@
 class AnnotatedLine;
 
 /// \brief A wrapper around a \c Token storing information about the
-/// whitespace characters preceeding it.
+/// whitespace characters preceding it.
 struct FormatToken {
   FormatToken()
       : NewlinesBefore(0), HasUnescapedNewline(false), LastNewlineOffset(0),
@@ -95,12 +104,14 @@
         IsFirst(false), MustBreakBefore(false), IsUnterminatedLiteral(false),
         BlockKind(BK_Unknown), Type(TT_Unknown), SpacesRequiredBefore(0),
         CanBreakBefore(false), ClosesTemplateDeclaration(false),
-        ParameterCount(0), PackingKind(PPK_Inconclusive), TotalLength(0),
-        UnbreakableTailLength(0), BindingStrength(0), SplitPenalty(0),
+        ParameterCount(0), BlockParameterCount(0),
+        PackingKind(PPK_Inconclusive), TotalLength(0), UnbreakableTailLength(0),
+        BindingStrength(0), NestingLevel(0), SplitPenalty(0),
         LongestObjCSelectorName(0), FakeRParens(0),
         StartsBinaryExpression(false), EndsBinaryExpression(false),
-        LastInChainOfCalls(false), PartOfMultiVariableDeclStmt(false),
-        MatchingParen(NULL), Previous(NULL), Next(NULL),
+        OperatorIndex(0), LastOperator(false),
+        PartOfMultiVariableDeclStmt(false), IsForEachMacro(false),
+        MatchingParen(nullptr), Previous(nullptr), Next(nullptr),
         Decision(FD_Unformatted), Finalized(false) {}
 
   /// \brief The \c Token.
@@ -116,7 +127,7 @@
   /// Token.
   bool HasUnescapedNewline;
 
-  /// \brief The range of the whitespace immediately preceeding the \c Token.
+  /// \brief The range of the whitespace immediately preceding the \c Token.
   SourceRange WhitespaceRange;
 
   /// \brief The offset just past the last '\n' in this token's leading
@@ -182,9 +193,13 @@
   /// the number of commas.
   unsigned ParameterCount;
 
+  /// \brief Number of parameters that are nested blocks,
+  /// if this is "(", "[" or "<".
+  unsigned BlockParameterCount;
+
   /// \brief A token can have a special role that can carry extra information
   /// about the token's formatting.
-  llvm::OwningPtr<TokenRole> Role;
+  std::unique_ptr<TokenRole> Role;
 
   /// \brief If this is an opening parenthesis, how are the parameters packed?
   ParameterPackingKind PackingKind;
@@ -206,11 +221,18 @@
   /// operator precedence, parenthesis nesting, etc.
   unsigned BindingStrength;
 
+  /// \brief The nesting level of this token, i.e. the number of surrounding (),
+  /// [], {} or <>.
+  unsigned NestingLevel;
+
   /// \brief Penalty for inserting a line break before this token.
   unsigned SplitPenalty;
 
   /// \brief If this is the first ObjC selector name in an ObjC method
   /// definition or call, this contains the length of the longest name.
+  ///
+  /// This being set to 0 means that the selectors should not be colon-aligned,
+  /// e.g. because several of them are block-type.
   unsigned LongestObjCSelectorName;
 
   /// \brief Stores the number of required fake parentheses and the
@@ -228,14 +250,22 @@
   /// \brief \c true if this token ends a binary expression.
   bool EndsBinaryExpression;
 
-  /// \brief Is this the last "." or "->" in a builder-type call?
-  bool LastInChainOfCalls;
+  /// \brief Is this is an operator (or "."/"->") in a sequence of operators
+  /// with the same precedence, contains the 0-based operator index.
+  unsigned OperatorIndex;
+
+  /// \brief Is this the last operator (or "."/"->") in a sequence of operators
+  /// with the same precedence?
+  bool LastOperator;
 
   /// \brief Is this token part of a \c DeclStmt defining multiple variables?
   ///
   /// Only set if \c Type == \c TT_StartOfName.
   bool PartOfMultiVariableDeclStmt;
 
+  /// \brief Is this a foreach macro?
+  bool IsForEachMacro;
+
   bool is(tok::TokenKind Kind) const { return Tok.is(Kind); }
 
   bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const {
@@ -260,6 +290,7 @@
   }
 
   bool isNot(tok::TokenKind Kind) const { return Tok.isNot(Kind); }
+  bool isStringLiteral() const { return tok::isStringLiteral(Tok.getKind()); }
 
   bool isObjCAtKeyword(tok::ObjCKeywordKind Kind) const {
     return Tok.isObjCAtKeyword(Kind);
@@ -270,6 +301,9 @@
            (!ColonRequired || (Next && Next->is(tok::colon)));
   }
 
+  /// \brief Determine whether the token is a simple-type-specifier.
+  bool isSimpleTypeSpecifier() const;
+
   bool isObjCAccessSpecifier() const {
     return is(tok::at) && Next && (Next->isObjCAtKeyword(tok::objc_public) ||
                                    Next->isObjCAtKeyword(tok::objc_protected) ||
@@ -290,7 +324,7 @@
 
   /// \brief Returns \c true if this is a "." or "->" accessing a member.
   bool isMemberAccess() const {
-    return isOneOf(tok::arrow, tok::period) &&
+    return isOneOf(tok::arrow, tok::period, tok::arrowstar) &&
            Type != TT_DesignatedInitializerPeriod;
   }
 
@@ -326,7 +360,7 @@
   /// \brief Returns the previous token ignoring comments.
   FormatToken *getPreviousNonComment() const {
     FormatToken *Tok = Previous;
-    while (Tok != NULL && Tok->is(tok::comment))
+    while (Tok && Tok->is(tok::comment))
       Tok = Tok->Previous;
     return Tok;
   }
@@ -334,7 +368,7 @@
   /// \brief Returns the next token ignoring comments.
   const FormatToken *getNextNonComment() const {
     const FormatToken *Tok = Next;
-    while (Tok != NULL && Tok->is(tok::comment))
+    while (Tok && Tok->is(tok::comment))
       Tok = Tok->Next;
     return Tok;
   }
@@ -388,10 +422,21 @@
 
   /// \brief Apply the special formatting that the given role demands.
   ///
+  /// Assumes that the token having this role is already formatted.
+  ///
   /// Continues formatting from \p State leaving indentation to \p Indenter and
   /// returns the total penalty that this formatting incurs.
-  virtual unsigned format(LineState &State, ContinuationIndenter *Indenter,
-                          bool DryRun) {
+  virtual unsigned formatFromToken(LineState &State,
+                                   ContinuationIndenter *Indenter,
+                                   bool DryRun) {
+    return 0;
+  }
+
+  /// \brief Same as \c formatFromToken, but assumes that the first token has
+  /// already been set thereby deciding on the first line break.
+  virtual unsigned formatAfterToken(LineState &State,
+                                    ContinuationIndenter *Indenter,
+                                    bool DryRun) {
     return 0;
   }
 
@@ -404,15 +449,21 @@
 
 class CommaSeparatedList : public TokenRole {
 public:
-  CommaSeparatedList(const FormatStyle &Style) : TokenRole(Style) {}
+  CommaSeparatedList(const FormatStyle &Style)
+      : TokenRole(Style), HasNestedBracedList(false) {}
 
-  virtual void precomputeFormattingInfos(const FormatToken *Token);
+  void precomputeFormattingInfos(const FormatToken *Token) override;
 
-  virtual unsigned format(LineState &State, ContinuationIndenter *Indenter,
-                          bool DryRun);
+  unsigned formatAfterToken(LineState &State, ContinuationIndenter *Indenter,
+                            bool DryRun) override;
+
+  unsigned formatFromToken(LineState &State, ContinuationIndenter *Indenter,
+                           bool DryRun) override;
 
   /// \brief Adds \p Token as the next comma to the \c CommaSeparated list.
-  virtual void CommaFound(const FormatToken *Token) { Commas.push_back(Token); }
+  void CommaFound(const FormatToken *Token) override {
+    Commas.push_back(Token);
+  }
 
 private:
   /// \brief A struct that holds information on how to format a given list with
@@ -444,6 +495,8 @@
 
   /// \brief Precomputed formats that can be used for this list.
   SmallVector<ColumnFormat, 4> Formats;
+
+  bool HasNestedBracedList;
 };
 
 } // namespace format
diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp
index 074e1d7..017afe1 100644
--- a/lib/Format/TokenAnnotator.cpp
+++ b/lib/Format/TokenAnnotator.cpp
@@ -17,6 +17,8 @@
 #include "clang/Basic/SourceManager.h"
 #include "llvm/Support/Debug.h"
 
+#define DEBUG_TYPE "format-token-annotator"
+
 namespace clang {
 namespace format {
 
@@ -34,16 +36,22 @@
       : Style(Style), Line(Line), CurrentToken(Line.First),
         KeywordVirtualFound(false), AutoFound(false), Ident_in(Ident_in) {
     Contexts.push_back(Context(tok::unknown, 1, /*IsExpression=*/false));
+    resetTokenMetadata(CurrentToken);
   }
 
 private:
   bool parseAngle() {
-    if (CurrentToken == NULL)
+    if (!CurrentToken)
       return false;
     ScopedContextCreator ContextCreator(*this, tok::less, 10);
     FormatToken *Left = CurrentToken->Previous;
     Contexts.back().IsExpression = false;
-    while (CurrentToken != NULL) {
+    // If there's a template keyword before the opening angle bracket, this is a
+    // template parameter, not an argument.
+    Contexts.back().InTemplateArgument =
+        Left->Previous && Left->Previous->Tok.isNot(tok::kw_template);
+
+    while (CurrentToken) {
       if (CurrentToken->is(tok::greater)) {
         Left->MatchingParen = CurrentToken;
         CurrentToken->MatchingParen = Left;
@@ -61,7 +69,11 @@
       // parameters.
       // FIXME: This is getting out of hand, write a decent parser.
       if (CurrentToken->Previous->isOneOf(tok::pipepipe, tok::ampamp) &&
-          (CurrentToken->Previous->Type == TT_BinaryOperator ||
+          ((CurrentToken->Previous->Type == TT_BinaryOperator &&
+            // Toplevel bool expressions do not make lots of sense;
+            // If we're on the top level, it contains only the base context and
+            // the context for the current opening angle bracket.
+            Contexts.size() > 2) ||
            Contexts[Contexts.size() - 2].IsExpression) &&
           Line.First->isNot(tok::kw_template))
         return false;
@@ -73,7 +85,7 @@
   }
 
   bool parseParens(bool LookForDecls = false) {
-    if (CurrentToken == NULL)
+    if (!CurrentToken)
       return false;
     ScopedContextCreator ContextCreator(*this, tok::l_paren, 1);
 
@@ -84,7 +96,7 @@
     bool StartsObjCMethodExpr = false;
     FormatToken *Left = CurrentToken->Previous;
     if (CurrentToken->is(tok::caret)) {
-      // ^( starts a block.
+      // (^ can start a block type.
       Left->Type = TT_ObjCBlockLParen;
     } else if (FormatToken *MaybeSel = Left->Previous) {
       // @selector( starts a selector.
@@ -94,15 +106,31 @@
       }
     }
 
-    if (Left->Previous && Left->Previous->isOneOf(tok::kw_static_assert,
-                                                  tok::kw_if, tok::kw_while)) {
+    if (Left->Previous &&
+        (Left->Previous->isOneOf(tok::kw_static_assert, tok::kw_if,
+                                 tok::kw_while, tok::l_paren, tok::comma) ||
+         Left->Previous->Type == TT_BinaryOperator)) {
       // static_assert, if and while usually contain expressions.
       Contexts.back().IsExpression = true;
+    } else if (Line.InPPDirective &&
+               (!Left->Previous ||
+                (Left->Previous->isNot(tok::identifier) &&
+                 Left->Previous->Type != TT_OverloadedOperator))) {
+      Contexts.back().IsExpression = true;
     } else if (Left->Previous && Left->Previous->is(tok::r_square) &&
                Left->Previous->MatchingParen &&
                Left->Previous->MatchingParen->Type == TT_LambdaLSquare) {
       // This is a parameter list of a lambda expression.
       Contexts.back().IsExpression = false;
+    } else if (Contexts[Contexts.size() - 2].CaretFound) {
+      // This is the parameter list of an ObjC block.
+      Contexts.back().IsExpression = false;
+    } else if (Left->Previous && Left->Previous->is(tok::kw___attribute)) {
+      Left->Type = TT_AttributeParen;
+    } else if (Left->Previous && Left->Previous->IsForEachMacro) {
+      // The first argument to a foreach macro is a declaration.
+      Contexts.back().IsForEachMacro = true;
+      Contexts.back().IsExpression = false;
     }
 
     if (StartsObjCMethodExpr) {
@@ -113,7 +141,7 @@
     bool MightBeFunctionType = CurrentToken->is(tok::star);
     bool HasMultipleLines = false;
     bool HasMultipleParametersOnALine = false;
-    while (CurrentToken != NULL) {
+    while (CurrentToken) {
       // LookForDecls is set when "if (" has been seen. Check for
       // 'identifier' '*' 'identifier' followed by not '=' -- this
       // '*' has to be a binary operator but determineStarAmpUsage() will
@@ -136,6 +164,8 @@
           CurrentToken->Previous->Previous->isOneOf(tok::l_paren,
                                                     tok::coloncolon))
         MightBeFunctionType = true;
+      if (CurrentToken->Previous->Type == TT_BinaryOperator)
+        Contexts.back().IsExpression = true;
       if (CurrentToken->is(tok::r_paren)) {
         if (MightBeFunctionType && CurrentToken->Next &&
             (CurrentToken->Next->is(tok::l_paren) ||
@@ -147,12 +177,15 @@
 
         if (StartsObjCMethodExpr) {
           CurrentToken->Type = TT_ObjCMethodExpr;
-          if (Contexts.back().FirstObjCSelectorName != NULL) {
+          if (Contexts.back().FirstObjCSelectorName) {
             Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
                 Contexts.back().LongestObjCSelectorName;
           }
         }
 
+        if (Left->Type == TT_AttributeParen)
+          CurrentToken->Type = TT_AttributeParen;
+
         if (!HasMultipleLines)
           Left->PackingKind = PPK_Inconclusive;
         else if (HasMultipleParametersOnALine)
@@ -165,13 +198,19 @@
       }
       if (CurrentToken->isOneOf(tok::r_square, tok::r_brace))
         return false;
-      updateParameterCount(Left, CurrentToken);
+      else if (CurrentToken->is(tok::l_brace))
+        Left->Type = TT_Unknown; // Not TT_ObjCBlockLParen
       if (CurrentToken->is(tok::comma) && CurrentToken->Next &&
           !CurrentToken->Next->HasUnescapedNewline &&
           !CurrentToken->Next->isTrailingComment())
         HasMultipleParametersOnALine = true;
+      if (CurrentToken->isOneOf(tok::kw_const, tok::kw_auto) ||
+          CurrentToken->isSimpleTypeSpecifier())
+        Contexts.back().IsExpression = false;
+      FormatToken *Tok = CurrentToken;
       if (!consumeToken())
         return false;
+      updateParameterCount(Left, Tok);
       if (CurrentToken && CurrentToken->HasUnescapedNewline)
         HasMultipleLines = true;
     }
@@ -189,6 +228,7 @@
     FormatToken *Parent = Left->getPreviousNonComment();
     bool StartsObjCMethodExpr =
         Contexts.back().CanBeExpression && Left->Type != TT_LambdaLSquare &&
+        CurrentToken->isNot(tok::l_brace) &&
         (!Parent || Parent->isOneOf(tok::colon, tok::l_square, tok::l_paren,
                                     tok::kw_return, tok::kw_throw) ||
          Parent->isUnaryOperator() || Parent->Type == TT_ObjCForIn ||
@@ -207,7 +247,7 @@
       Left->Type = TT_ArraySubscriptLSquare;
     }
 
-    while (CurrentToken != NULL) {
+    while (CurrentToken) {
       if (CurrentToken->is(tok::r_square)) {
         if (CurrentToken->Next && CurrentToken->Next->is(tok::l_paren) &&
             Left->Type == TT_ObjCMethodExpr) {
@@ -216,19 +256,22 @@
           StartsObjCMethodExpr = false;
           Left->Type = TT_Unknown;
         }
-        if (StartsObjCMethodExpr) {
+        if (StartsObjCMethodExpr && CurrentToken->Previous != Left) {
           CurrentToken->Type = TT_ObjCMethodExpr;
           // determineStarAmpUsage() thinks that '*' '[' is allocating an
           // array of pointers, but if '[' starts a selector then '*' is a
           // binary operator.
-          if (Parent != NULL && Parent->Type == TT_PointerOrReference)
+          if (Parent && Parent->Type == TT_PointerOrReference)
             Parent->Type = TT_BinaryOperator;
         }
         Left->MatchingParen = CurrentToken;
         CurrentToken->MatchingParen = Left;
-        if (Contexts.back().FirstObjCSelectorName != NULL)
+        if (Contexts.back().FirstObjCSelectorName) {
           Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
               Contexts.back().LongestObjCSelectorName;
+          if (Left->BlockParameterCount > 1)
+            Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName = 0;
+        }
         next();
         return true;
       }
@@ -237,23 +280,32 @@
       if (CurrentToken->is(tok::colon))
         ColonFound = true;
       if (CurrentToken->is(tok::comma) &&
+          Style.Language != FormatStyle::LK_Proto &&
           (Left->Type == TT_ArraySubscriptLSquare ||
            (Left->Type == TT_ObjCMethodExpr && !ColonFound)))
         Left->Type = TT_ArrayInitializerLSquare;
-      updateParameterCount(Left, CurrentToken);
+      FormatToken* Tok = CurrentToken;
       if (!consumeToken())
         return false;
+      updateParameterCount(Left, Tok);
     }
     return false;
   }
 
   bool parseBrace() {
-    if (CurrentToken != NULL) {
+    if (CurrentToken) {
       FormatToken *Left = CurrentToken->Previous;
+
+      if (Contexts.back().CaretFound)
+        Left->Type = TT_ObjCBlockLBrace;
+      Contexts.back().CaretFound = false;
+
       ScopedContextCreator ContextCreator(*this, tok::l_brace, 1);
       Contexts.back().ColonIsDictLiteral = true;
+      if (Left->BlockKind == BK_BracedInit)
+        Contexts.back().IsExpression = true;
 
-      while (CurrentToken != NULL) {
+      while (CurrentToken) {
         if (CurrentToken->is(tok::r_brace)) {
           Left->MatchingParen = CurrentToken;
           CurrentToken->MatchingParen = Left;
@@ -263,18 +315,26 @@
         if (CurrentToken->isOneOf(tok::r_paren, tok::r_square))
           return false;
         updateParameterCount(Left, CurrentToken);
-        if (CurrentToken->is(tok::colon))
+        if (CurrentToken->is(tok::colon) &&
+            Style.Language != FormatStyle::LK_Proto) {
+          if (CurrentToken->getPreviousNonComment()->is(tok::identifier))
+            CurrentToken->getPreviousNonComment()->Type = TT_SelectorName;
           Left->Type = TT_DictLiteral;
+        }
         if (!consumeToken())
           return false;
       }
     }
-    // No closing "}" found, this probably starts a definition.
-    Line.StartsDefinition = true;
     return true;
   }
 
   void updateParameterCount(FormatToken *Left, FormatToken *Current) {
+    if (Current->Type == TT_LambdaLSquare ||
+        (Current->is(tok::caret) && Current->Type == TT_UnaryOperator) ||
+        (Style.Language == FormatStyle::LK_JavaScript &&
+         Current->TokenText == "function")) {
+      ++Left->BlockParameterCount;
+    }
     if (Current->is(tok::comma)) {
       ++Left->ParameterCount;
       if (!Left->Role)
@@ -286,7 +346,7 @@
   }
 
   bool parseConditional() {
-    while (CurrentToken != NULL) {
+    while (CurrentToken) {
       if (CurrentToken->is(tok::colon)) {
         CurrentToken->Type = TT_ConditionalExpr;
         next();
@@ -299,12 +359,12 @@
   }
 
   bool parseTemplateDeclaration() {
-    if (CurrentToken != NULL && CurrentToken->is(tok::less)) {
+    if (CurrentToken && CurrentToken->is(tok::less)) {
       CurrentToken->Type = TT_TemplateOpener;
       next();
       if (!parseAngle())
         return false;
-      if (CurrentToken != NULL)
+      if (CurrentToken)
         CurrentToken->Previous->ClosesTemplateDeclaration = true;
       return true;
     }
@@ -317,33 +377,34 @@
     switch (Tok->Tok.getKind()) {
     case tok::plus:
     case tok::minus:
-      if (Tok->Previous == NULL && Line.MustBeDeclaration)
+      if (!Tok->Previous && Line.MustBeDeclaration)
         Tok->Type = TT_ObjCMethodSpecifier;
       break;
     case tok::colon:
-      if (Tok->Previous == NULL)
+      if (!Tok->Previous)
         return false;
       // Colons from ?: are handled in parseConditional().
-      if (Tok->Previous->is(tok::r_paren) && Contexts.size() == 1) {
+      if (Tok->Previous->is(tok::r_paren) && Contexts.size() == 1 &&
+          Line.First->isNot(tok::kw_case)) {
         Tok->Type = TT_CtorInitializerColon;
       } else if (Contexts.back().ColonIsDictLiteral) {
         Tok->Type = TT_DictLiteral;
       } else if (Contexts.back().ColonIsObjCMethodExpr ||
                  Line.First->Type == TT_ObjCMethodSpecifier) {
         Tok->Type = TT_ObjCMethodExpr;
-        Tok->Previous->Type = TT_ObjCSelectorName;
+        Tok->Previous->Type = TT_SelectorName;
         if (Tok->Previous->ColumnWidth >
             Contexts.back().LongestObjCSelectorName) {
           Contexts.back().LongestObjCSelectorName = Tok->Previous->ColumnWidth;
         }
-        if (Contexts.back().FirstObjCSelectorName == NULL)
+        if (!Contexts.back().FirstObjCSelectorName)
           Contexts.back().FirstObjCSelectorName = Tok->Previous;
       } else if (Contexts.back().ColonIsForRangeExpr) {
         Tok->Type = TT_RangeBasedForLoopColon;
-      } else if (CurrentToken != NULL &&
-                 CurrentToken->is(tok::numeric_constant)) {
+      } else if (CurrentToken && CurrentToken->is(tok::numeric_constant)) {
         Tok->Type = TT_BitFieldColon;
-      } else if (Contexts.size() == 1 && Line.First->isNot(tok::kw_enum)) {
+      } else if (Contexts.size() == 1 &&
+                 !Line.First->isOneOf(tok::kw_enum, tok::kw_case)) {
         Tok->Type = TT_InheritanceColon;
       } else if (Contexts.back().ContextKind == tok::l_paren) {
         Tok->Type = TT_InlineASMColon;
@@ -351,7 +412,7 @@
       break;
     case tok::kw_if:
     case tok::kw_while:
-      if (CurrentToken != NULL && CurrentToken->is(tok::l_paren)) {
+      if (CurrentToken && CurrentToken->is(tok::l_paren)) {
         next();
         if (!parseParens(/*LookForDecls=*/true))
           return false;
@@ -367,7 +428,9 @@
       if (!parseParens())
         return false;
       if (Line.MustBeDeclaration && Contexts.size() == 1 &&
-          !Contexts.back().IsExpression)
+          !Contexts.back().IsExpression &&
+          Line.First->Type != TT_ObjCProperty &&
+          (!Tok->Previous || Tok->Previous->isNot(tok::kw_decltype)))
         Line.MightBeFunctionDecl = true;
       break;
     case tok::l_square:
@@ -392,7 +455,7 @@
       return false;
     case tok::r_brace:
       // Lines can start with '}'.
-      if (Tok->Previous != NULL)
+      if (Tok->Previous)
         return false;
       break;
     case tok::greater:
@@ -429,6 +492,8 @@
         Contexts.back().FirstStartOfName->PartOfMultiVariableDeclStmt = true;
       if (Contexts.back().InCtorInitializer)
         Tok->Type = TT_CtorInitializerComma;
+      if (Contexts.back().IsForEachMacro)
+        Contexts.back().IsExpression = true;
       break;
     default:
       break;
@@ -438,15 +503,15 @@
 
   void parseIncludeDirective() {
     next();
-    if (CurrentToken != NULL && CurrentToken->is(tok::less)) {
+    if (CurrentToken && CurrentToken->is(tok::less)) {
       next();
-      while (CurrentToken != NULL) {
+      while (CurrentToken) {
         if (CurrentToken->isNot(tok::comment) || CurrentToken->Next)
           CurrentToken->Type = TT_ImplicitStringLiteral;
         next();
       }
     } else {
-      while (CurrentToken != NULL) {
+      while (CurrentToken) {
         if (CurrentToken->is(tok::string_literal))
           // Mark these string literals as "implicit" literals, too, so that
           // they are not split or line-wrapped.
@@ -461,15 +526,27 @@
     // We still want to format the whitespace left of the first token of the
     // warning or error.
     next();
-    while (CurrentToken != NULL) {
+    while (CurrentToken) {
       CurrentToken->Type = TT_ImplicitStringLiteral;
       next();
     }
   }
 
+  void parsePragma() {
+    next(); // Consume "pragma".
+    if (CurrentToken && CurrentToken->TokenText == "mark") {
+      next(); // Consume "mark".
+      next(); // Consume first token (so we fix leading whitespace).
+      while (CurrentToken) {
+        CurrentToken->Type = TT_ImplicitStringLiteral;
+        next();
+      }
+    }
+  }
+
   void parsePreprocessorDirective() {
     next();
-    if (CurrentToken == NULL)
+    if (!CurrentToken)
       return;
     if (CurrentToken->Tok.is(tok::numeric_constant)) {
       CurrentToken->SpacesRequiredBefore = 1;
@@ -477,7 +554,7 @@
     }
     // Hashes in the middle of a line can lead to any strange token
     // sequence.
-    if (CurrentToken->Tok.getIdentifierInfo() == NULL)
+    if (!CurrentToken->Tok.getIdentifierInfo())
       return;
     switch (CurrentToken->Tok.getIdentifierInfo()->getPPKeywordID()) {
     case tok::pp_include:
@@ -488,14 +565,18 @@
     case tok::pp_warning:
       parseWarningOrError();
       break;
+    case tok::pp_pragma:
+      parsePragma();
+      break;
     case tok::pp_if:
     case tok::pp_elif:
+      Contexts.back().IsExpression = true;
       parseLine();
       break;
     default:
       break;
     }
-    while (CurrentToken != NULL)
+    while (CurrentToken)
       next();
   }
 
@@ -505,7 +586,16 @@
       parsePreprocessorDirective();
       return LT_PreprocessorDirective;
     }
-    while (CurrentToken != NULL) {
+
+    // Directly allow to 'import <string-literal>' to support protocol buffer
+    // definitions (code.google.com/p/protobuf) or missing "#" (either way we
+    // should not break the line).
+    IdentifierInfo *Info = CurrentToken->Tok.getIdentifierInfo();
+    if (Info && Info->getPPKeywordID() == tok::pp_import &&
+        CurrentToken->Next && CurrentToken->Next->is(tok::string_literal))
+      parseIncludeDirective();
+
+    while (CurrentToken) {
       if (CurrentToken->is(tok::kw_virtual))
         KeywordVirtualFound = true;
       if (!consumeToken())
@@ -515,7 +605,7 @@
       return LT_VirtualFunctionDecl;
 
     if (Line.First->Type == TT_ObjCMethodSpecifier) {
-      if (Contexts.back().FirstObjCSelectorName != NULL)
+      if (Contexts.back().FirstObjCSelectorName)
         Contexts.back().FirstObjCSelectorName->LongestObjCSelectorName =
             Contexts.back().LongestObjCSelectorName;
       return LT_ObjCMethodDecl;
@@ -525,26 +615,32 @@
   }
 
 private:
+  void resetTokenMetadata(FormatToken *Token) {
+    if (!Token)
+      return;
+
+    // Reset token type in case we have already looked at it and then
+    // recovered from an error (e.g. failure to find the matching >).
+    if (CurrentToken->Type != TT_LambdaLSquare &&
+        CurrentToken->Type != TT_FunctionLBrace &&
+        CurrentToken->Type != TT_ImplicitStringLiteral &&
+        CurrentToken->Type != TT_RegexLiteral &&
+        CurrentToken->Type != TT_TrailingReturnArrow)
+      CurrentToken->Type = TT_Unknown;
+    CurrentToken->Role.reset();
+    CurrentToken->FakeLParens.clear();
+    CurrentToken->FakeRParens = 0;
+  }
+
   void next() {
-    if (CurrentToken != NULL) {
+    if (CurrentToken) {
       determineTokenType(*CurrentToken);
       CurrentToken->BindingStrength = Contexts.back().BindingStrength;
-    }
-
-    if (CurrentToken != NULL)
+      CurrentToken->NestingLevel = Contexts.size() - 1;
       CurrentToken = CurrentToken->Next;
-
-    if (CurrentToken != NULL) {
-      // Reset token type in case we have already looked at it and then
-      // recovered from an error (e.g. failure to find the matching >).
-      if (CurrentToken->Type != TT_LambdaLSquare &&
-          CurrentToken->Type != TT_ImplicitStringLiteral)
-        CurrentToken->Type = TT_Unknown;
-      if (CurrentToken->Role)
-        CurrentToken->Role.reset(NULL);
-      CurrentToken->FakeLParens.clear();
-      CurrentToken->FakeRParens = 0;
     }
+
+    resetTokenMetadata(CurrentToken);
   }
 
   /// \brief A struct to hold information valid in a specific context, e.g.
@@ -555,9 +651,10 @@
         : ContextKind(ContextKind), BindingStrength(BindingStrength),
           LongestObjCSelectorName(0), ColonIsForRangeExpr(false),
           ColonIsDictLiteral(false), ColonIsObjCMethodExpr(false),
-          FirstObjCSelectorName(NULL), FirstStartOfName(NULL),
+          FirstObjCSelectorName(nullptr), FirstStartOfName(nullptr),
           IsExpression(IsExpression), CanBeExpression(true),
-          InCtorInitializer(false) {}
+          InTemplateArgument(false), InCtorInitializer(false),
+          CaretFound(false), IsForEachMacro(false) {}
 
     tok::TokenKind ContextKind;
     unsigned BindingStrength;
@@ -569,7 +666,10 @@
     FormatToken *FirstStartOfName;
     bool IsExpression;
     bool CanBeExpression;
+    bool InTemplateArgument;
     bool InCtorInitializer;
+    bool CaretFound;
+    bool IsForEachMacro;
   };
 
   /// \brief Puts a new \c Context onto the stack \c Contexts for the lifetime
@@ -596,19 +696,26 @@
       for (FormatToken *Previous = Current.Previous;
            Previous && !Previous->isOneOf(tok::comma, tok::semi);
            Previous = Previous->Previous) {
-        if (Previous->is(tok::r_square))
+        if (Previous->isOneOf(tok::r_square, tok::r_paren))
           Previous = Previous->MatchingParen;
         if (Previous->Type == TT_BinaryOperator &&
             Previous->isOneOf(tok::star, tok::amp)) {
           Previous->Type = TT_PointerOrReference;
         }
       }
-    } else if (Current.isOneOf(tok::kw_return, tok::kw_throw) ||
-               (Current.is(tok::l_paren) && !Line.MustBeDeclaration &&
-                !Line.InPPDirective &&
-                (!Current.Previous ||
-                 !Current.Previous->isOneOf(tok::kw_for, tok::kw_catch)))) {
+    } else if (Current.isOneOf(tok::kw_return, tok::kw_throw)) {
       Contexts.back().IsExpression = true;
+    } else if (Current.is(tok::l_paren) && !Line.MustBeDeclaration &&
+               !Line.InPPDirective &&
+               (!Current.Previous ||
+                Current.Previous->isNot(tok::kw_decltype))) {
+      bool ParametersOfFunctionType =
+          Current.Previous && Current.Previous->is(tok::r_paren) &&
+          Current.Previous->MatchingParen &&
+          Current.Previous->MatchingParen->Type == TT_FunctionTypeLParen;
+      bool IsForOrCatch = Current.Previous &&
+                          Current.Previous->isOneOf(tok::kw_for, tok::kw_catch);
+      Contexts.back().IsExpression = !ParametersOfFunctionType && !IsForOrCatch;
     } else if (Current.isOneOf(tok::r_paren, tok::greater, tok::comma)) {
       for (FormatToken *Previous = Current.Previous;
            Previous && Previous->isOneOf(tok::star, tok::amp);
@@ -640,13 +747,18 @@
       } else if (Current.isOneOf(tok::star, tok::amp, tok::ampamp)) {
         Current.Type =
             determineStarAmpUsage(Current, Contexts.back().CanBeExpression &&
-                                               Contexts.back().IsExpression);
+                                               Contexts.back().IsExpression,
+                                  Contexts.back().InTemplateArgument);
       } else if (Current.isOneOf(tok::minus, tok::plus, tok::caret)) {
         Current.Type = determinePlusMinusCaretUsage(Current);
+        if (Current.Type == TT_UnaryOperator && Current.is(tok::caret))
+          Contexts.back().CaretFound = true;
       } else if (Current.isOneOf(tok::minusminus, tok::plusplus)) {
         Current.Type = determineIncrementUsage(Current);
       } else if (Current.is(tok::exclaim)) {
         Current.Type = TT_UnaryOperator;
+      } else if (Current.is(tok::question)) {
+        Current.Type = TT_ConditionalExpr;
       } else if (Current.isBinaryOperator() &&
                  (!Current.Previous ||
                   Current.Previous->isNot(tok::l_square))) {
@@ -657,38 +769,7 @@
         else
           Current.Type = TT_BlockComment;
       } else if (Current.is(tok::r_paren)) {
-        FormatToken *LeftOfParens = NULL;
-        if (Current.MatchingParen)
-          LeftOfParens = Current.MatchingParen->getPreviousNonComment();
-        bool IsCast = false;
-        bool ParensAreEmpty = Current.Previous == Current.MatchingParen;
-        bool ParensAreType = !Current.Previous ||
-                             Current.Previous->Type == TT_PointerOrReference ||
-                             Current.Previous->Type == TT_TemplateCloser ||
-                             isSimpleTypeSpecifier(*Current.Previous);
-        bool ParensCouldEndDecl =
-            Current.Next &&
-            Current.Next->isOneOf(tok::equal, tok::semi, tok::l_brace);
-        bool IsSizeOfOrAlignOf =
-            LeftOfParens &&
-            LeftOfParens->isOneOf(tok::kw_sizeof, tok::kw_alignof);
-        if (ParensAreType && !ParensCouldEndDecl && !IsSizeOfOrAlignOf &&
-            (Contexts.back().IsExpression ||
-             (Current.Next && Current.Next->isBinaryOperator())))
-          IsCast = true;
-        if (Current.Next && Current.Next->isNot(tok::string_literal) &&
-            (Current.Next->Tok.isLiteral() ||
-             Current.Next->isOneOf(tok::kw_sizeof, tok::kw_alignof)))
-          IsCast = true;
-        // If there is an identifier after the (), it is likely a cast, unless
-        // there is also an identifier before the ().
-        if (LeftOfParens && (LeftOfParens->Tok.getIdentifierInfo() == NULL ||
-                             LeftOfParens->is(tok::kw_return)) &&
-            LeftOfParens->Type != TT_OverloadedOperator &&
-            LeftOfParens->Type != TT_TemplateCloser && Current.Next &&
-            Current.Next->is(tok::identifier))
-          IsCast = true;
-        if (IsCast && !ParensAreEmpty)
+        if (rParenEndsCast(Current))
           Current.Type = TT_CastRParen;
       } else if (Current.is(tok::at) && Current.Next) {
         switch (Current.Next->Tok.getObjCKeywordID()) {
@@ -708,6 +789,12 @@
         if (PreviousNoComment &&
             PreviousNoComment->isOneOf(tok::comma, tok::l_brace))
           Current.Type = TT_DesignatedInitializerPeriod;
+      } else if (Current.isOneOf(tok::identifier, tok::kw_const) &&
+                 Current.Previous && Current.Previous->isNot(tok::equal) &&
+                 Line.MightBeFunctionDecl && Contexts.size() == 1) {
+        // Line.MightBeFunctionDecl can only be true after the parentheses of a
+        // function declaration have been found.
+        Current.Type = TT_TrailingAnnotation;
       }
     }
   }
@@ -718,15 +805,15 @@
   /// This is a heuristic based on whether \p Tok is an identifier following
   /// something that is likely a type.
   bool isStartOfName(const FormatToken &Tok) {
-    if (Tok.isNot(tok::identifier) || Tok.Previous == NULL)
+    if (Tok.isNot(tok::identifier) || !Tok.Previous)
       return false;
 
     // Skip "const" as it does not have an influence on whether this is a name.
     FormatToken *PreviousNotConst = Tok.Previous;
-    while (PreviousNotConst != NULL && PreviousNotConst->is(tok::kw_const))
+    while (PreviousNotConst && PreviousNotConst->is(tok::kw_const))
       PreviousNotConst = PreviousNotConst->Previous;
 
-    if (PreviousNotConst == NULL)
+    if (!PreviousNotConst)
       return false;
 
     bool IsPPKeyword = PreviousNotConst->is(tok::identifier) &&
@@ -738,19 +825,84 @@
              PreviousNotConst->MatchingParen->Previous &&
              PreviousNotConst->MatchingParen->Previous->isNot(tok::kw_template);
 
+    if (PreviousNotConst->is(tok::r_paren) && PreviousNotConst->MatchingParen &&
+        PreviousNotConst->MatchingParen->Previous &&
+        PreviousNotConst->MatchingParen->Previous->is(tok::kw_decltype))
+      return true;
+
     return (!IsPPKeyword && PreviousNotConst->is(tok::identifier)) ||
            PreviousNotConst->Type == TT_PointerOrReference ||
-           isSimpleTypeSpecifier(*PreviousNotConst);
+           PreviousNotConst->isSimpleTypeSpecifier();
+  }
+
+  /// \brief Determine whether ')' is ending a cast.
+  bool rParenEndsCast(const FormatToken &Tok) {
+    FormatToken *LeftOfParens = nullptr;
+    if (Tok.MatchingParen)
+      LeftOfParens = Tok.MatchingParen->getPreviousNonComment();
+    if (LeftOfParens && LeftOfParens->is(tok::r_paren))
+      return false;
+    bool IsCast = false;
+    bool ParensAreEmpty = Tok.Previous == Tok.MatchingParen;
+    bool ParensAreType = !Tok.Previous ||
+                         Tok.Previous->Type == TT_PointerOrReference ||
+                         Tok.Previous->Type == TT_TemplateCloser ||
+                         Tok.Previous->isSimpleTypeSpecifier();
+    bool ParensCouldEndDecl =
+        Tok.Next && Tok.Next->isOneOf(tok::equal, tok::semi, tok::l_brace);
+    bool IsSizeOfOrAlignOf =
+        LeftOfParens && LeftOfParens->isOneOf(tok::kw_sizeof, tok::kw_alignof);
+    if (ParensAreType && !ParensCouldEndDecl && !IsSizeOfOrAlignOf &&
+        ((Contexts.size() > 1 && Contexts[Contexts.size() - 2].IsExpression) ||
+         (Tok.Next && Tok.Next->isBinaryOperator())))
+      IsCast = true;
+    else if (Tok.Next && Tok.Next->isNot(tok::string_literal) &&
+             (Tok.Next->Tok.isLiteral() ||
+              Tok.Next->isOneOf(tok::kw_sizeof, tok::kw_alignof)))
+      IsCast = true;
+    // If there is an identifier after the (), it is likely a cast, unless
+    // there is also an identifier before the ().
+    else if (LeftOfParens &&
+             (LeftOfParens->Tok.getIdentifierInfo() == nullptr ||
+              LeftOfParens->is(tok::kw_return)) &&
+             LeftOfParens->Type != TT_OverloadedOperator &&
+             LeftOfParens->isNot(tok::at) &&
+             LeftOfParens->Type != TT_TemplateCloser && Tok.Next) {
+      if (Tok.Next->isOneOf(tok::identifier, tok::numeric_constant)) {
+        IsCast = true;
+      } else {
+        // Use heuristics to recognize c style casting.
+        FormatToken *Prev = Tok.Previous;
+        if (Prev && Prev->isOneOf(tok::amp, tok::star))
+          Prev = Prev->Previous;
+
+        if (Prev && Tok.Next && Tok.Next->Next) {
+          bool NextIsUnary = Tok.Next->isUnaryOperator() ||
+                             Tok.Next->isOneOf(tok::amp, tok::star);
+          IsCast = NextIsUnary && Tok.Next->Next->isOneOf(
+                                      tok::identifier, tok::numeric_constant);
+        }
+
+        for (; Prev != Tok.MatchingParen; Prev = Prev->Previous) {
+          if (!Prev || !Prev->isOneOf(tok::kw_const, tok::identifier)) {
+            IsCast = false;
+            break;
+          }
+        }
+      }
+    }
+    return IsCast && !ParensAreEmpty;
   }
 
   /// \brief Return the type of the given token assuming it is * or &.
-  TokenType determineStarAmpUsage(const FormatToken &Tok, bool IsExpression) {
+  TokenType determineStarAmpUsage(const FormatToken &Tok, bool IsExpression,
+                                  bool InTemplateArgument) {
     const FormatToken *PrevToken = Tok.getPreviousNonComment();
-    if (PrevToken == NULL)
+    if (!PrevToken)
       return TT_UnaryOperator;
 
     const FormatToken *NextToken = Tok.getNextNonComment();
-    if (NextToken == NULL)
+    if (!NextToken || NextToken->is(tok::l_brace))
       return TT_Unknown;
 
     if (PrevToken->is(tok::coloncolon) ||
@@ -761,20 +913,37 @@
                            tok::comma, tok::semi, tok::kw_return, tok::colon,
                            tok::equal, tok::kw_delete, tok::kw_sizeof) ||
         PrevToken->Type == TT_BinaryOperator ||
+        PrevToken->Type == TT_ConditionalExpr ||
         PrevToken->Type == TT_UnaryOperator || PrevToken->Type == TT_CastRParen)
       return TT_UnaryOperator;
 
-    if (NextToken->is(tok::l_square))
+    if (NextToken->is(tok::l_square) && NextToken->Type != TT_LambdaLSquare)
+      return TT_PointerOrReference;
+    if (NextToken->is(tok::kw_operator))
       return TT_PointerOrReference;
 
     if (PrevToken->is(tok::r_paren) && PrevToken->MatchingParen &&
         PrevToken->MatchingParen->Previous &&
-        PrevToken->MatchingParen->Previous->is(tok::kw_typeof))
+        PrevToken->MatchingParen->Previous->isOneOf(tok::kw_typeof,
+                                                    tok::kw_decltype))
       return TT_PointerOrReference;
 
     if (PrevToken->Tok.isLiteral() ||
-        PrevToken->isOneOf(tok::r_paren, tok::r_square) ||
-        NextToken->Tok.isLiteral() || NextToken->isUnaryOperator())
+        PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::kw_true,
+                           tok::kw_false) ||
+        NextToken->Tok.isLiteral() ||
+        NextToken->isOneOf(tok::kw_true, tok::kw_false) ||
+        NextToken->isUnaryOperator() ||
+        // If we know we're in a template argument, there are no named
+        // declarations. Thus, having an identifier on the right-hand side
+        // indicates a binary operator.
+        (InTemplateArgument && NextToken->Tok.isAnyIdentifier()))
+      return TT_BinaryOperator;
+
+    // This catches some cases where evaluation order is used as control flow:
+    //   aaa && aaa->f();
+    const FormatToken *NextNextToken = NextToken->getNextNonComment();
+    if (NextNextToken && NextNextToken->is(tok::arrow))
       return TT_BinaryOperator;
 
     // It is very unlikely that we are going to find a pointer or reference type
@@ -787,7 +956,7 @@
 
   TokenType determinePlusMinusCaretUsage(const FormatToken &Tok) {
     const FormatToken *PrevToken = Tok.getPreviousNonComment();
-    if (PrevToken == NULL || PrevToken->Type == TT_CastRParen)
+    if (!PrevToken || PrevToken->Type == TT_CastRParen)
       return TT_UnaryOperator;
 
     // Use heuristics to recognize unary operators.
@@ -807,7 +976,7 @@
   /// \brief Determine whether ++/-- are pre- or post-increments/-decrements.
   TokenType determineIncrementUsage(const FormatToken &Tok) {
     const FormatToken *PrevToken = Tok.getPreviousNonComment();
-    if (PrevToken == NULL || PrevToken->Type == TT_CastRParen)
+    if (!PrevToken || PrevToken->Type == TT_CastRParen)
       return TT_UnaryOperator;
     if (PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::identifier))
       return TT_TrailingUnaryOperator;
@@ -815,37 +984,6 @@
     return TT_UnaryOperator;
   }
 
-  // FIXME: This is copy&pasted from Sema. Put it in a common place and remove
-  // duplication.
-  /// \brief Determine whether the token kind starts a simple-type-specifier.
-  bool isSimpleTypeSpecifier(const FormatToken &Tok) const {
-    switch (Tok.Tok.getKind()) {
-    case tok::kw_short:
-    case tok::kw_long:
-    case tok::kw___int64:
-    case tok::kw___int128:
-    case tok::kw_signed:
-    case tok::kw_unsigned:
-    case tok::kw_void:
-    case tok::kw_char:
-    case tok::kw_int:
-    case tok::kw_half:
-    case tok::kw_float:
-    case tok::kw_double:
-    case tok::kw_wchar_t:
-    case tok::kw_bool:
-    case tok::kw___underlying_type:
-    case tok::annot_typename:
-    case tok::kw_char16_t:
-    case tok::kw_char32_t:
-    case tok::kw_typeof:
-    case tok::kw_decltype:
-      return true;
-    default:
-      return false;
-    }
-  }
-
   SmallVector<Context, 8> Contexts;
 
   const FormatStyle &Style;
@@ -875,10 +1013,11 @@
     // expression.
     while (Current &&
            (Current->is(tok::kw_return) ||
-            (Current->is(tok::colon) && Current->Type == TT_ObjCMethodExpr)))
+            (Current->is(tok::colon) && (Current->Type == TT_ObjCMethodExpr ||
+                                         Current->Type == TT_DictLiteral))))
       next();
 
-    if (Current == NULL || Precedence > PrecedenceArrowAndPeriod)
+    if (!Current || Precedence > PrecedenceArrowAndPeriod)
       return;
 
     // Conditional expressions need to be parsed separately for proper nesting.
@@ -895,7 +1034,8 @@
     }
 
     FormatToken *Start = Current;
-    FormatToken *LatestOperator = NULL;
+    FormatToken *LatestOperator = nullptr;
+    unsigned OperatorIndex = 0;
 
     while (Current) {
       // Consume operators with higher precedence.
@@ -903,17 +1043,20 @@
 
       int CurrentPrecedence = getCurrentPrecedence();
 
-      if (Current && Current->Type == TT_ObjCSelectorName &&
-          Precedence == CurrentPrecedence)
+      if (Current && Current->Type == TT_SelectorName &&
+          Precedence == CurrentPrecedence) {
+        if (LatestOperator)
+          addFakeParenthesis(Start, prec::Level(Precedence));
         Start = Current;
+      }
 
       // At the end of the line or when an operator with higher precedence is
       // found, insert fake parenthesis and return.
-      if (Current == NULL || Current->closesScope() ||
+      if (!Current || Current->closesScope() ||
           (CurrentPrecedence != -1 && CurrentPrecedence < Precedence)) {
         if (LatestOperator) {
+          LatestOperator->LastOperator = true;
           if (Precedence == PrecedenceArrowAndPeriod) {
-            LatestOperator->LastInChainOfCalls = true;
             // Call expressions don't have a binary operator precedence.
             addFakeParenthesis(Start, prec::Unknown);
           } else {
@@ -932,8 +1075,11 @@
         next();
       } else {
         // Operator found.
-        if (CurrentPrecedence == Precedence)
+        if (CurrentPrecedence == Precedence) {
           LatestOperator = Current;
+          Current->OperatorIndex = OperatorIndex;
+          ++OperatorIndex;
+        }
 
         next();
       }
@@ -948,8 +1094,10 @@
       if (Current->Type == TT_ConditionalExpr)
         return prec::Conditional;
       else if (Current->is(tok::semi) || Current->Type == TT_InlineASMColon ||
-               Current->Type == TT_ObjCSelectorName)
+               Current->Type == TT_SelectorName)
         return 0;
+      else if (Current->Type == TT_RangeBasedForLoopColon)
+        return prec::Comma;
       else if (Current->Type == TT_BinaryOperator || Current->is(tok::comma))
         return Current->getPrecedence();
       else if (Current->isOneOf(tok::period, tok::arrow))
@@ -972,7 +1120,7 @@
   /// \brief Parse unary operator expressions and surround them with fake
   /// parentheses if appropriate.
   void parseUnaryOperator() {
-    if (Current == NULL || Current->Type != TT_UnaryOperator) {
+    if (!Current || Current->Type != TT_UnaryOperator) {
       parse(PrecedenceArrowAndPeriod);
       return;
     }
@@ -991,7 +1139,7 @@
     if (!Current || !Current->is(tok::question))
       return;
     next();
-    parse(prec::LogicalOr);
+    parseConditionalExpr();
     if (!Current || Current->Type != TT_ConditionalExpr)
       return;
     next();
@@ -1013,15 +1161,15 @@
 
 void
 TokenAnnotator::setCommentLineLevels(SmallVectorImpl<AnnotatedLine *> &Lines) {
-  const AnnotatedLine *NextNonCommentLine = NULL;
+  const AnnotatedLine *NextNonCommentLine = nullptr;
   for (SmallVectorImpl<AnnotatedLine *>::reverse_iterator I = Lines.rbegin(),
                                                           E = Lines.rend();
        I != E; ++I) {
     if (NextNonCommentLine && (*I)->First->is(tok::comment) &&
-        (*I)->First->Next == NULL)
+        (*I)->First->Next == nullptr)
       (*I)->Level = NextNonCommentLine->Level;
     else
-      NextNonCommentLine = (*I)->First->isNot(tok::r_brace) ? (*I) : NULL;
+      NextNonCommentLine = (*I)->First->isNot(tok::r_brace) ? (*I) : nullptr;
 
     setCommentLineLevels((*I)->Children);
   }
@@ -1052,31 +1200,108 @@
   Line.First->CanBreakBefore = Line.First->MustBreakBefore;
 }
 
+// This function heuristically determines whether 'Current' starts the name of a
+// function declaration.
+static bool isFunctionDeclarationName(const FormatToken &Current) {
+  if (Current.Type != TT_StartOfName ||
+      Current.NestingLevel != 0 ||
+      Current.Previous->Type == TT_StartOfName)
+    return false;
+  const FormatToken *Next = Current.Next;
+  for (; Next; Next = Next->Next) {
+    if (Next->Type == TT_TemplateOpener) {
+      Next = Next->MatchingParen;
+    } else if (Next->is(tok::coloncolon)) {
+      Next = Next->Next;
+      if (!Next || !Next->is(tok::identifier))
+        return false;
+    } else if (Next->is(tok::l_paren)) {
+      break;
+    } else {
+      return false;
+    }
+  }
+  if (!Next)
+    return false;
+  assert(Next->is(tok::l_paren));
+  if (Next->Next == Next->MatchingParen)
+    return true;
+  for (const FormatToken *Tok = Next->Next; Tok != Next->MatchingParen;
+       Tok = Tok->Next) {
+    if (Tok->is(tok::kw_const) || Tok->isSimpleTypeSpecifier() ||
+        Tok->Type == TT_PointerOrReference || Tok->Type == TT_StartOfName)
+      return true;
+    if (Tok->isOneOf(tok::l_brace, tok::string_literal) || Tok->Tok.isLiteral())
+      return false;
+  }
+  return false;
+}
+
 void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) {
+  for (SmallVectorImpl<AnnotatedLine *>::iterator I = Line.Children.begin(),
+                                                  E = Line.Children.end();
+       I != E; ++I) {
+    calculateFormattingInformation(**I);
+  }
+
   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 != NULL) {
-    if (Current->Type == TT_LineComment)
-      Current->SpacesRequiredBefore = Style.SpacesBeforeTrailingComments;
-    else if (Current->SpacesRequiredBefore == 0 &&
-             spaceRequiredBefore(Line, *Current))
+  while (Current) {
+    if (isFunctionDeclarationName(*Current))
+      Current->Type = TT_FunctionDeclarationName;
+    if (Current->Type == TT_LineComment) {
+      if (Current->Previous->BlockKind == BK_BracedInit &&
+          Current->Previous->opensScope())
+        Current->SpacesRequiredBefore = Style.Cpp11BracedListStyle ? 0 : 1;
+      else
+        Current->SpacesRequiredBefore = Style.SpacesBeforeTrailingComments;
+
+      // If we find a trailing comment, iterate backwards to determine whether
+      // it seems to relate to a specific parameter. If so, break before that
+      // parameter to avoid changing the comment's meaning. E.g. don't move 'b'
+      // to the previous line in:
+      //   SomeFunction(a,
+      //                b, // comment
+      //                c);
+      if (!Current->HasUnescapedNewline) {
+        for (FormatToken *Parameter = Current->Previous; Parameter;
+             Parameter = Parameter->Previous) {
+          if (Parameter->isOneOf(tok::comment, tok::r_brace))
+            break;
+          if (Parameter->Previous && Parameter->Previous->is(tok::comma)) {
+            if (Parameter->Previous->Type != TT_CtorInitializerComma &&
+                Parameter->HasUnescapedNewline)
+              Parameter->MustBreakBefore = true;
+            break;
+          }
+        }
+      }
+    } else if (Current->SpacesRequiredBefore == 0 &&
+               spaceRequiredBefore(Line, *Current)) {
       Current->SpacesRequiredBefore = 1;
+    }
 
     Current->MustBreakBefore =
         Current->MustBreakBefore || mustBreakBefore(Line, *Current);
 
     Current->CanBreakBefore =
         Current->MustBreakBefore || canBreakBefore(Line, *Current);
-    if (Current->MustBreakBefore || !Current->Children.empty() ||
+    unsigned ChildSize = 0;
+    if (Current->Previous->Children.size() == 1) {
+      FormatToken &LastOfChild = *Current->Previous->Children[0]->Last;
+      ChildSize = LastOfChild.isTrailingComment() ? Style.ColumnLimit
+                                                  : LastOfChild.TotalLength + 1;
+    }
+    if (Current->MustBreakBefore || Current->Previous->Children.size() > 1 ||
         Current->IsMultiline)
       Current->TotalLength = Current->Previous->TotalLength + Style.ColumnLimit;
     else
       Current->TotalLength = Current->Previous->TotalLength +
-                             Current->ColumnWidth +
+                             Current->ColumnWidth + ChildSize +
                              Current->SpacesRequiredBefore;
 
     if (Current->Type == TT_CtorInitializerColon)
@@ -1092,24 +1317,18 @@
   }
 
   calculateUnbreakableTailLengths(Line);
-  for (Current = Line.First; Current != NULL; Current = Current->Next) {
+  for (Current = Line.First; Current != nullptr; Current = Current->Next) {
     if (Current->Role)
       Current->Role->precomputeFormattingInfos(Current);
   }
 
   DEBUG({ printDebugInfo(Line); });
-
-  for (SmallVectorImpl<AnnotatedLine *>::iterator I = Line.Children.begin(),
-                                                  E = Line.Children.end();
-       I != E; ++I) {
-    calculateFormattingInformation(**I);
-  }
 }
 
 void TokenAnnotator::calculateUnbreakableTailLengths(AnnotatedLine &Line) {
   unsigned UnbreakableTailLength = 0;
   FormatToken *Current = Line.Last;
-  while (Current != NULL) {
+  while (Current) {
     Current->UnbreakableTailLength = UnbreakableTailLength;
     if (Current->CanBreakBefore ||
         Current->isOneOf(tok::comment, tok::string_literal)) {
@@ -1130,18 +1349,22 @@
 
   if (Left.is(tok::semi))
     return 0;
-  if (Left.is(tok::comma))
+  if (Left.is(tok::comma) || (Right.is(tok::identifier) && Right.Next &&
+                              Right.Next->Type == TT_DictLiteral))
     return 1;
-  if (Right.is(tok::l_square))
-    return 150;
-
-  if (Right.Type == TT_StartOfName || Right.is(tok::kw_operator)) {
+  if (Right.is(tok::l_square)) {
+    if (Style.Language == FormatStyle::LK_Proto)
+      return 1;
+    if (Right.Type != TT_ObjCMethodExpr && Right.Type != TT_LambdaLSquare)
+      return 500;
+  }
+  if (Right.Type == TT_StartOfName ||
+      Right.Type == TT_FunctionDeclarationName || Right.is(tok::kw_operator)) {
     if (Line.First->is(tok::kw_for) && Right.PartOfMultiVariableDeclStmt)
       return 3;
     if (Left.Type == TT_StartOfName)
       return 20;
-    if (InFunctionDecl && Right.BindingStrength == 1)
-      // FIXME: Clean up hack of using BindingStrength to find top-level names.
+    if (InFunctionDecl && Right.NestingLevel == 0)
       return Style.PenaltyReturnTypeOnItsOwnLine;
     return 200;
   }
@@ -1149,7 +1372,8 @@
     return 150;
   if (Left.Type == TT_CastRParen)
     return 100;
-  if (Left.is(tok::coloncolon))
+  if (Left.is(tok::coloncolon) ||
+      (Right.is(tok::period) && Style.Language == FormatStyle::LK_Proto))
     return 500;
   if (Left.isOneOf(tok::kw_class, tok::kw_struct))
     return 5000;
@@ -1159,17 +1383,22 @@
     return 2;
 
   if (Right.isMemberAccess()) {
-    if (Left.isOneOf(tok::r_paren, tok::r_square) && Left.MatchingParen &&
+    if (Left.is(tok::r_paren) && Left.MatchingParen &&
         Left.MatchingParen->ParameterCount > 0)
       return 20; // Should be smaller than breaking at a nested comma.
     return 150;
   }
 
-  // Breaking before a trailing 'const' or not-function-like annotation is bad.
-  if (Left.is(tok::r_paren) && Line.Type != LT_ObjCProperty &&
-      (Right.is(tok::kw_const) || (Right.is(tok::identifier) && Right.Next &&
-                                   Right.Next->isNot(tok::l_paren))))
-    return 100;
+  if (Right.Type == TT_TrailingAnnotation &&
+      (!Right.Next || Right.Next->isNot(tok::l_paren))) {
+    // Generally, breaking before a trailing annotation is bad unless it is
+    // function-like. It seems to be especially preferable to keep standard
+    // annotations (i.e. "const", "final" and "override") on the same line.
+    // Use a slightly higher penalty after ")" so that annotations like
+    // "const override" are kept together.
+    bool is_short_annotation = Right.TokenText.size() < 10;
+    return (Left.is(tok::r_paren) ? 100 : 120) + (is_short_annotation ? 50 : 0);
+  }
 
   // In for-loops, prefer breaking at ',' and ';'.
   if (Line.First->is(tok::kw_for) && Left.is(tok::equal))
@@ -1177,13 +1406,15 @@
 
   // In Objective-C method expressions, prefer breaking before "param:" over
   // breaking after it.
-  if (Right.Type == TT_ObjCSelectorName)
+  if (Right.Type == TT_SelectorName)
     return 0;
   if (Left.is(tok::colon) && Left.Type == TT_ObjCMethodExpr)
-    return 50;
+    return Line.MightBeFunctionDecl ? 50 : 500;
 
   if (Left.is(tok::l_paren) && InFunctionDecl)
     return 100;
+  if (Left.is(tok::equal) && InFunctionDecl)
+    return 110;
   if (Left.opensScope())
     return Left.ParameterCount > 1 ? Style.PenaltyBreakBeforeFirstCallParameter
                                    : 19;
@@ -1215,6 +1446,23 @@
 bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
                                           const FormatToken &Left,
                                           const FormatToken &Right) {
+  if (Style.Language == FormatStyle::LK_Proto) {
+    if (Right.is(tok::period) &&
+        (Left.TokenText == "optional" || Left.TokenText == "required" ||
+         Left.TokenText == "repeated"))
+      return true;
+    if (Right.is(tok::l_paren) &&
+        (Left.TokenText == "returns" || Left.TokenText == "option"))
+      return true;
+  } else if (Style.Language == FormatStyle::LK_JavaScript) {
+    if (Left.TokenText == "var")
+      return true;
+  }
+  if (Left.is(tok::kw_return) && Right.isNot(tok::semi))
+    return true;
+  if (Style.ObjCSpaceAfterProperty && Line.Type == LT_ObjCProperty &&
+      Left.Tok.getObjCKeywordID() == tok::objc_property)
+    return true;
   if (Right.is(tok::hashhash))
     return Left.is(tok::hash);
   if (Left.isOneOf(tok::hashhash, tok::hash))
@@ -1246,7 +1494,7 @@
     return false;
   if (Left.is(tok::coloncolon))
     return false;
-  if (Right.is(tok::coloncolon))
+  if (Right.is(tok::coloncolon) && Left.isNot(tok::l_brace))
     return (Left.is(tok::less) && Style.Standard == FormatStyle::LS_Cpp03) ||
            !Left.isOneOf(tok::identifier, tok::greater, tok::l_paren,
                          tok::r_paren, tok::less);
@@ -1259,60 +1507,64 @@
   if (Right.Type == TT_PointerOrReference)
     return Left.Tok.isLiteral() ||
            ((Left.Type != TT_PointerOrReference) && Left.isNot(tok::l_paren) &&
-            !Style.PointerBindsToType);
+            Style.PointerAlignment != FormatStyle::PAS_Left);
   if (Right.Type == TT_FunctionTypeLParen && Left.isNot(tok::l_paren) &&
-      (Left.Type != TT_PointerOrReference || Style.PointerBindsToType))
+      (Left.Type != TT_PointerOrReference || Style.PointerAlignment != FormatStyle::PAS_Right))
     return true;
   if (Left.Type == TT_PointerOrReference)
     return Right.Tok.isLiteral() || Right.Type == TT_BlockComment ||
            ((Right.Type != TT_PointerOrReference) &&
-            Right.isNot(tok::l_paren) && Style.PointerBindsToType &&
+            Right.isNot(tok::l_paren) && Style.PointerAlignment != FormatStyle::PAS_Right &&
             Left.Previous &&
             !Left.Previous->isOneOf(tok::l_paren, tok::coloncolon));
   if (Right.is(tok::star) && Left.is(tok::l_paren))
     return false;
   if (Left.is(tok::l_square))
     return Left.Type == TT_ArrayInitializerLSquare &&
-           Right.isNot(tok::r_square);
+           Style.SpacesInContainerLiterals && Right.isNot(tok::r_square);
   if (Right.is(tok::r_square))
-    return Right.MatchingParen &&
+    return Right.MatchingParen && Style.SpacesInContainerLiterals &&
            Right.MatchingParen->Type == TT_ArrayInitializerLSquare;
   if (Right.is(tok::l_square) && Right.Type != TT_ObjCMethodExpr &&
-      Right.Type != TT_LambdaLSquare && Left.isNot(tok::numeric_constant))
+      Right.Type != TT_LambdaLSquare && Left.isNot(tok::numeric_constant) &&
+      Left.Type != TT_DictLiteral)
     return false;
   if (Left.is(tok::colon))
     return Left.Type != TT_ObjCMethodExpr;
-  if (Right.is(tok::colon))
-    return Right.Type != TT_ObjCMethodExpr && !Left.is(tok::question);
+  if (Left.Type == TT_BlockComment)
+    return !Left.TokenText.endswith("=*/");
   if (Right.is(tok::l_paren)) {
-    if (Left.is(tok::r_paren) && Left.MatchingParen &&
-        Left.MatchingParen->Previous &&
-        Left.MatchingParen->Previous->is(tok::kw___attribute))
+    if (Left.is(tok::r_paren) && Left.Type == TT_AttributeParen)
       return true;
     return Line.Type == LT_ObjCDecl ||
-           Left.isOneOf(tok::kw_return, tok::kw_new, tok::kw_delete,
-                        tok::semi) ||
-           (Style.SpaceAfterControlStatementKeyword &&
-            Left.isOneOf(tok::kw_if, tok::kw_for, tok::kw_while, tok::kw_switch,
-                         tok::kw_catch));
+           Left.isOneOf(tok::kw_new, tok::kw_delete, tok::semi) ||
+           (Style.SpaceBeforeParens != FormatStyle::SBPO_Never &&
+            (Left.isOneOf(tok::kw_if, tok::kw_for, tok::kw_while,
+                          tok::kw_switch, tok::kw_catch, tok::kw_case) ||
+             Left.IsForEachMacro)) ||
+           (Style.SpaceBeforeParens == FormatStyle::SBPO_Always &&
+            Left.isOneOf(tok::identifier, tok::kw___attribute) &&
+            Line.Type != LT_PreprocessorDirective);
   }
   if (Left.is(tok::at) && Right.Tok.getObjCKeywordID() != tok::objc_not_keyword)
     return false;
   if (Left.is(tok::l_brace) && Right.is(tok::r_brace))
     return !Left.Children.empty(); // No spaces in "{}".
-  if (Left.is(tok::l_brace) || Right.is(tok::r_brace))
+  if ((Left.is(tok::l_brace) && Left.BlockKind != BK_Block) ||
+      (Right.is(tok::r_brace) && Right.MatchingParen &&
+       Right.MatchingParen->BlockKind != BK_Block))
     return !Style.Cpp11BracedListStyle;
   if (Right.Type == TT_UnaryOperator)
     return !Left.isOneOf(tok::l_paren, tok::l_square, tok::at) &&
            (Left.isNot(tok::colon) || Left.Type != TT_ObjCMethodExpr);
-  if (Left.isOneOf(tok::identifier, tok::greater, tok::r_square) &&
+  if ((Left.isOneOf(tok::identifier, tok::greater, tok::r_square,
+                    tok::r_paren) ||
+       Left.isSimpleTypeSpecifier()) &&
       Right.is(tok::l_brace) && Right.getNextNonComment() &&
       Right.BlockKind != BK_Block)
     return false;
   if (Left.is(tok::period) || Right.is(tok::period))
     return false;
-  if (Left.Type == TT_BlockComment && Left.TokenText.endswith("=*/"))
-    return false;
   if (Right.is(tok::hash) && Left.is(tok::identifier) && Left.TokenText == "L")
     return false;
   return true;
@@ -1350,11 +1602,12 @@
     return false;
   if (Tok.is(tok::colon))
     return !Line.First->isOneOf(tok::kw_case, tok::kw_default) &&
-           Tok.getNextNonComment() != NULL && Tok.Type != TT_ObjCMethodExpr &&
-           !Tok.Previous->is(tok::question);
+           Tok.getNextNonComment() && Tok.Type != TT_ObjCMethodExpr &&
+           !Tok.Previous->is(tok::question) &&
+           (Tok.Type != TT_DictLiteral || Style.SpacesInContainerLiterals);
   if (Tok.Previous->Type == TT_UnaryOperator ||
       Tok.Previous->Type == TT_CastRParen)
-    return false;
+    return Tok.Type == TT_BinaryOperator;
   if (Tok.Previous->is(tok::greater) && Tok.is(tok::greater)) {
     return Tok.Type == TT_TemplateCloser &&
            Tok.Previous->Type == TT_TemplateCloser &&
@@ -1367,7 +1620,8 @@
       Tok.getPrecedence() == prec::Assignment)
     return false;
   if ((Tok.Type == TT_BinaryOperator && !Tok.Previous->is(tok::l_paren)) ||
-      Tok.Previous->Type == TT_BinaryOperator)
+      Tok.Previous->Type == TT_BinaryOperator ||
+      Tok.Previous->Type == TT_ConditionalExpr)
     return true;
   if (Tok.Previous->Type == TT_TemplateCloser && Tok.is(tok::l_paren))
     return false;
@@ -1376,16 +1630,28 @@
     return true;
   if (Tok.Type == TT_TrailingUnaryOperator)
     return false;
+  if (Tok.Previous->Type == TT_RegexLiteral)
+    return false;
   return spaceRequiredBetween(Line, *Tok.Previous, Tok);
 }
 
+// Returns 'true' if 'Tok' is a brace we'd want to break before in Allman style.
+static bool isAllmanBrace(const FormatToken &Tok) {
+  return Tok.is(tok::l_brace) && Tok.BlockKind == BK_Block &&
+         Tok.Type != TT_ObjCBlockLBrace && Tok.Type != TT_DictLiteral;
+}
+
 bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
                                      const FormatToken &Right) {
+  const FormatToken &Left = *Right.Previous;
+  if (Right.NewlinesBefore > 1)
+    return true;
   if (Right.is(tok::comment)) {
-    return Right.NewlinesBefore > 0;
+    return Right.Previous->BlockKind != BK_BracedInit &&
+           Right.Previous->Type != TT_CtorInitializerColon &&
+           (Right.NewlinesBefore > 0 && Right.HasUnescapedNewline);
   } else if (Right.Previous->isTrailingComment() ||
-             (Right.is(tok::string_literal) &&
-              Right.Previous->is(tok::string_literal))) {
+             (Right.isStringLiteral() && Right.Previous->isStringLiteral())) {
     return true;
   } else if (Right.Previous->IsUnterminatedLiteral) {
     return true;
@@ -1395,45 +1661,83 @@
     return true;
   } else if (Right.Previous->ClosesTemplateDeclaration &&
              Right.Previous->MatchingParen &&
-             Right.Previous->MatchingParen->BindingStrength == 1 &&
+             Right.Previous->MatchingParen->NestingLevel == 0 &&
              Style.AlwaysBreakTemplateDeclarations) {
-    // FIXME: Fix horrible hack of using BindingStrength to find top-level <>.
     return true;
-  } else if (Right.Type == TT_CtorInitializerComma &&
+  } else if ((Right.Type == TT_CtorInitializerComma ||
+              Right.Type == TT_CtorInitializerColon) &&
              Style.BreakConstructorInitializersBeforeComma &&
              !Style.ConstructorInitializerAllOnOneLineOrOnePerLine) {
     return true;
-  } else if (Right.Previous->BlockKind == BK_Block &&
-             Right.Previous->isNot(tok::r_brace) && Right.isNot(tok::r_brace)) {
+  } else 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
+    // literal accordingly. Thus, we try keep existing line breaks.
+    return Right.NewlinesBefore > 0;
+  } else if (Right.Previous->is(tok::l_brace) && Right.NestingLevel == 1 &&
+             Style.Language == FormatStyle::LK_Proto) {
+    // Don't enums onto single lines in protocol buffers.
     return true;
-  } else if (Right.is(tok::l_brace) && (Right.BlockKind == BK_Block)) {
-    return Style.BreakBeforeBraces == FormatStyle::BS_Allman;
+  } else if (isAllmanBrace(Left) || isAllmanBrace(Right)) {
+    return Style.BreakBeforeBraces == FormatStyle::BS_Allman ||
+           Style.BreakBeforeBraces == FormatStyle::BS_GNU;
   }
+
+  // If the last token before a '}' is a comma or a comment, the intention is to
+  // insert a line break after it in order to make shuffling around entries
+  // easier.
+  const FormatToken *BeforeClosingBrace = nullptr;
+  if (Left.is(tok::l_brace) && Left.MatchingParen)
+    BeforeClosingBrace = Left.MatchingParen->Previous;
+  else if (Right.is(tok::r_brace))
+    BeforeClosingBrace = Right.Previous;
+  if (BeforeClosingBrace &&
+      BeforeClosingBrace->isOneOf(tok::comma, tok::comment))
+    return true;
+
+  if (Style.Language == FormatStyle::LK_JavaScript) {
+    // FIXME: This might apply to other languages and token kinds.
+    if (Right.is(tok::char_constant) && Left.is(tok::plus) && Left.Previous &&
+        Left.Previous->is(tok::char_constant))
+      return true;
+  }
+
   return false;
 }
 
 bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
                                     const FormatToken &Right) {
   const FormatToken &Left = *Right.Previous;
-  if (Right.Type == TT_StartOfName || Right.is(tok::kw_operator))
+  if (Left.is(tok::at))
+    return false;
+  if (Left.Tok.getObjCKeywordID() == tok::objc_interface)
+    return false;
+  if (Right.Type == TT_StartOfName ||
+      Right.Type == TT_FunctionDeclarationName || Right.is(tok::kw_operator))
     return true;
   if (Right.isTrailingComment())
     // We rely on MustBreakBefore being set correctly here as we should not
     // change the "binding" behavior of a comment.
-    return false;
+    // The first comment in a braced lists is always interpreted as belonging to
+    // the first list element. Otherwise, it should be placed outside of the
+    // list.
+    return Left.BlockKind == BK_BracedInit;
   if (Left.is(tok::question) && Right.is(tok::colon))
     return false;
   if (Right.Type == TT_ConditionalExpr || Right.is(tok::question))
     return Style.BreakBeforeTernaryOperators;
   if (Left.Type == TT_ConditionalExpr || Left.is(tok::question))
     return !Style.BreakBeforeTernaryOperators;
-  if (Right.is(tok::colon) &&
-      (Right.Type == TT_DictLiteral || Right.Type == TT_ObjCMethodExpr))
+  if (Right.Type == TT_InheritanceColon)
+    return true;
+  if (Right.is(tok::colon) && (Right.Type != TT_CtorInitializerColon &&
+                               Right.Type != TT_InlineASMColon))
     return false;
   if (Left.is(tok::colon) &&
       (Left.Type == TT_DictLiteral || Left.Type == TT_ObjCMethodExpr))
     return true;
-  if (Right.Type == TT_ObjCSelectorName)
+  if (Right.Type == TT_SelectorName)
     return true;
   if (Left.is(tok::r_paren) && Line.Type == LT_ObjCProperty)
     return true;
@@ -1452,14 +1756,12 @@
     return false;
   if (Left.is(tok::equal) && Line.Type == LT_VirtualFunctionDecl)
     return false;
-  if (Left.Previous) {
-    if (Left.is(tok::l_paren) && Right.is(tok::l_paren) &&
-        Left.Previous->is(tok::kw___attribute))
-      return false;
-    if (Left.is(tok::l_paren) && (Left.Previous->Type == TT_BinaryOperator ||
-                                  Left.Previous->Type == TT_CastRParen))
-      return false;
-  }
+  if (Left.is(tok::l_paren) && Left.Type == TT_AttributeParen)
+    return false;
+  if (Left.is(tok::l_paren) && Left.Previous &&
+      (Left.Previous->Type == TT_BinaryOperator ||
+       Left.Previous->Type == TT_CastRParen || Left.Previous->is(tok::kw_if)))
+    return false;
   if (Right.Type == TT_ImplicitStringLiteral)
     return false;
 
@@ -1471,11 +1773,11 @@
   if (Right.is(tok::r_brace))
     return Right.MatchingParen && Right.MatchingParen->BlockKind == BK_Block;
 
-  // Allow breaking after a trailing 'const', e.g. after a method declaration,
-  // unless it is follow by ';', '{' or '='.
-  if (Left.is(tok::kw_const) && Left.Previous != NULL &&
-      Left.Previous->is(tok::r_paren))
-    return !Right.isOneOf(tok::l_brace, tok::semi, tok::equal);
+  // Allow breaking after a trailing annotation, e.g. after a method
+  // declaration.
+  if (Left.Type == TT_TrailingAnnotation)
+    return !Right.isOneOf(tok::l_brace, tok::semi, tok::equal, tok::l_paren,
+                          tok::less, tok::coloncolon);
 
   if (Right.is(tok::kw___attribute))
     return true;
@@ -1483,27 +1785,32 @@
   if (Left.is(tok::identifier) && Right.is(tok::string_literal))
     return true;
 
+  if (Right.is(tok::identifier) && Right.Next &&
+      Right.Next->Type == TT_DictLiteral)
+    return true;
+
   if (Left.Type == TT_CtorInitializerComma &&
       Style.BreakConstructorInitializersBeforeComma)
     return false;
   if (Right.Type == TT_CtorInitializerComma &&
       Style.BreakConstructorInitializersBeforeComma)
     return true;
-  if (Right.isBinaryOperator() && Style.BreakBeforeBinaryOperators)
-    return true;
   if (Left.is(tok::greater) && Right.is(tok::greater) &&
       Left.Type != TT_TemplateCloser)
     return false;
+  if (Right.Type == TT_BinaryOperator && Style.BreakBeforeBinaryOperators)
+    return true;
   if (Left.Type == TT_ArrayInitializerLSquare)
     return true;
-  return (Left.isBinaryOperator() && Left.isNot(tok::lessless) &&
+  return (Left.isBinaryOperator() &&
+          !Left.isOneOf(tok::arrowstar, tok::lessless) &&
           !Style.BreakBeforeBinaryOperators) ||
          Left.isOneOf(tok::comma, tok::coloncolon, tok::semi, tok::l_brace,
                       tok::kw_class, tok::kw_struct) ||
-         Right.isOneOf(tok::lessless, tok::arrow, tok::period, tok::colon,
-                       tok::l_square, tok::at) ||
+         Right.isMemberAccess() ||
+         Right.isOneOf(tok::lessless, tok::colon, tok::l_square, tok::at) ||
          (Left.is(tok::r_paren) &&
-          Right.isOneOf(tok::identifier, tok::kw_const, tok::kw___attribute)) ||
+          Right.isOneOf(tok::identifier, tok::kw_const)) ||
          (Left.is(tok::l_paren) && !Right.is(tok::r_paren));
 }
 
@@ -1514,13 +1821,14 @@
     llvm::errs() << " M=" << Tok->MustBreakBefore
                  << " C=" << Tok->CanBreakBefore << " T=" << Tok->Type
                  << " S=" << Tok->SpacesRequiredBefore
+                 << " B=" << Tok->BlockParameterCount
                  << " P=" << Tok->SplitPenalty << " Name=" << Tok->Tok.getName()
                  << " L=" << Tok->TotalLength << " PPK=" << Tok->PackingKind
                  << " FakeLParens=";
     for (unsigned i = 0, e = Tok->FakeLParens.size(); i != e; ++i)
       llvm::errs() << Tok->FakeLParens[i] << "/";
     llvm::errs() << " FakeRParens=" << Tok->FakeRParens << "\n";
-    if (Tok->Next == NULL)
+    if (!Tok->Next)
       assert(Tok == Line.Last);
     Tok = Tok->Next;
   }
diff --git a/lib/Format/TokenAnnotator.h b/lib/Format/TokenAnnotator.h
index aa49b2a..36de010 100644
--- a/lib/Format/TokenAnnotator.h
+++ b/lib/Format/TokenAnnotator.h
@@ -41,13 +41,14 @@
       : First(Line.Tokens.front().Tok), Level(Line.Level),
         InPPDirective(Line.InPPDirective),
         MustBeDeclaration(Line.MustBeDeclaration), MightBeFunctionDecl(false),
-        StartsDefinition(false) {
+        Affected(false), LeadingEmptyLinesAffected(false),
+        ChildrenAffected(false) {
     assert(!Line.Tokens.empty());
 
     // Calculate Next and Previous for all tokens. Note that we must overwrite
     // Next and Previous for every token, as previous formatting runs might have
     // left them in a different state.
-    First->Previous = NULL;
+    First->Previous = nullptr;
     FormatToken *Current = First;
     for (std::list<UnwrappedLineNode>::const_iterator I = ++Line.Tokens.begin(),
                                                       E = Line.Tokens.end();
@@ -66,7 +67,7 @@
       }
     }
     Last = Current;
-    Last->Next = NULL;
+    Last->Next = nullptr;
   }
 
   ~AnnotatedLine() {
@@ -85,7 +86,17 @@
   bool InPPDirective;
   bool MustBeDeclaration;
   bool MightBeFunctionDecl;
-  bool StartsDefinition;
+
+  /// \c True if this line should be formatted, i.e. intersects directly or
+  /// indirectly with one of the input ranges.
+  bool Affected;
+
+  /// \c True if the leading empty lines of this line intersect with one of the
+  /// input ranges.
+  bool LeadingEmptyLinesAffected;
+
+  /// \c True if a one of this line's children intersects with an input range.
+  bool ChildrenAffected;
 
 private:
   // Disallow copying.
diff --git a/lib/Format/UnwrappedLineParser.cpp b/lib/Format/UnwrappedLineParser.cpp
index e0b090f..20dd573 100644
--- a/lib/Format/UnwrappedLineParser.cpp
+++ b/lib/Format/UnwrappedLineParser.cpp
@@ -13,11 +13,11 @@
 ///
 //===----------------------------------------------------------------------===//
 
-#define DEBUG_TYPE "format-parser"
-
 #include "UnwrappedLineParser.h"
 #include "llvm/Support/Debug.h"
 
+#define DEBUG_TYPE "format-parser"
+
 namespace clang {
 namespace format {
 
@@ -60,7 +60,7 @@
       : Line(Line), TokenSource(TokenSource), ResetToken(ResetToken),
         PreviousLineLevel(Line.Level), PreviousTokenSource(TokenSource),
         StructuralError(StructuralError),
-        PreviousStructuralError(StructuralError), Token(NULL) {
+        PreviousStructuralError(StructuralError), Token(nullptr) {
     TokenSource = this;
     Line.Level = 0;
     Line.InPPDirective = true;
@@ -74,7 +74,7 @@
     StructuralError = PreviousStructuralError;
   }
 
-  virtual FormatToken *getNextToken() {
+  FormatToken *getNextToken() override {
     // The \c UnwrappedLineParser guards against this by never calling
     // \c getNextToken() after it has encountered the first eof token.
     assert(!eof());
@@ -84,9 +84,9 @@
     return Token;
   }
 
-  virtual unsigned getPosition() { return PreviousTokenSource->getPosition(); }
+  unsigned getPosition() override { return PreviousTokenSource->getPosition(); }
 
-  virtual FormatToken *setPosition(unsigned Position) {
+  FormatToken *setPosition(unsigned Position) override {
     Token = PreviousTokenSource->setPosition(Position);
     return Token;
   }
@@ -128,7 +128,7 @@
       Parser.CurrentLines = &Parser.PreprocessorDirectives;
     else if (!Parser.Line->Tokens.empty())
       Parser.CurrentLines = &Parser.Line->Tokens.back().Children;
-    PreBlockLine = Parser.Line.take();
+    PreBlockLine = Parser.Line.release();
     Parser.Line.reset(new UnwrappedLine());
     Parser.Line->Level = PreBlockLine->Level;
     Parser.Line->InPPDirective = PreBlockLine->InPPDirective;
@@ -152,6 +152,25 @@
   SmallVectorImpl<UnwrappedLine> *OriginalLines;
 };
 
+class CompoundStatementIndenter {
+public:
+  CompoundStatementIndenter(UnwrappedLineParser *Parser,
+                            const FormatStyle &Style, unsigned &LineLevel)
+      : LineLevel(LineLevel), OldLineLevel(LineLevel) {
+    if (Style.BreakBeforeBraces == FormatStyle::BS_Allman) {
+      Parser->addUnwrappedLine();
+    } else if (Style.BreakBeforeBraces == FormatStyle::BS_GNU) {
+      Parser->addUnwrappedLine();
+      ++LineLevel;
+    }
+  }
+  ~CompoundStatementIndenter() { LineLevel = OldLineLevel; }
+
+private:
+  unsigned &LineLevel;
+  unsigned OldLineLevel;
+};
+
 namespace {
 
 class IndexedTokenSource : public FormatTokenSource {
@@ -159,17 +178,17 @@
   IndexedTokenSource(ArrayRef<FormatToken *> Tokens)
       : Tokens(Tokens), Position(-1) {}
 
-  virtual FormatToken *getNextToken() {
+  FormatToken *getNextToken() override {
     ++Position;
     return Tokens[Position];
   }
 
-  virtual unsigned getPosition() {
+  unsigned getPosition() override {
     assert(Position >= 0);
     return Position;
   }
 
-  virtual FormatToken *setPosition(unsigned P) {
+  FormatToken *setPosition(unsigned P) override {
     Position = P;
     return Tokens[Position];
   }
@@ -187,14 +206,15 @@
                                          ArrayRef<FormatToken *> Tokens,
                                          UnwrappedLineConsumer &Callback)
     : Line(new UnwrappedLine), MustBreakBeforeNextToken(false),
-      CurrentLines(&Lines), StructuralError(false), Style(Style), Tokens(NULL),
-      Callback(Callback), AllTokens(Tokens), PPBranchLevel(-1) {}
+      CurrentLines(&Lines), StructuralError(false), Style(Style),
+      Tokens(nullptr), Callback(Callback), AllTokens(Tokens),
+      PPBranchLevel(-1) {}
 
 void UnwrappedLineParser::reset() {
   PPBranchLevel = -1;
   Line.reset(new UnwrappedLine);
   CommentsBeforeNextToken.clear();
-  FormatTok = NULL;
+  FormatTok = nullptr;
   MustBreakBeforeNextToken = false;
   PreprocessorDirectives.clear();
   CurrentLines = &Lines;
@@ -314,18 +334,30 @@
     case tok::r_brace:
       if (!LBraceStack.empty()) {
         if (LBraceStack.back()->BlockKind == BK_Unknown) {
-          // If there is a comma, semicolon or right paren after the closing
-          // brace, we assume this is a braced initializer list.  Note that
-          // regardless how we mark inner braces here, we will overwrite the
-          // 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.
-          if (NextTok->isOneOf(tok::comma, tok::semi, tok::r_paren,
-                               tok::r_square, tok::l_brace, tok::colon) ||
-              (NextTok->isBinaryOperator() &&
-               !NextTok->isOneOf(tok::plus, tok::minus))) {
+          bool ProbablyBracedList = false;
+          if (Style.Language == FormatStyle::LK_Proto) {
+            ProbablyBracedList = NextTok->isOneOf(tok::comma, tok::r_square);
+          } else {
+            // Using OriginalColumn to distinguish between ObjC methods and
+            // binary operators is a bit hacky.
+            bool NextIsObjCMethod = NextTok->isOneOf(tok::plus, tok::minus) &&
+                                    NextTok->OriginalColumn == 0;
+
+            // If there is a comma, semicolon or right paren after the closing
+            // brace, we assume this is a braced initializer list.  Note that
+            // regardless how we mark inner braces here, we will overwrite the
+            // 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 =
+                NextTok->isOneOf(tok::comma, tok::semi, tok::period, tok::colon,
+                                 tok::r_paren, tok::r_square, tok::l_brace,
+                                 tok::l_paren) ||
+                (NextTok->isBinaryOperator() && !NextIsObjCMethod);
+          }
+          if (ProbablyBracedList) {
             Tok->BlockKind = BK_BracedInit;
             LBraceStack.back()->BlockKind = BK_BracedInit;
           } else {
@@ -336,6 +368,7 @@
         LBraceStack.pop_back();
       }
       break;
+    case tok::at:
     case tok::semi:
     case tok::kw_if:
     case tok::kw_while:
@@ -386,16 +419,34 @@
   Line->Level = InitialLevel;
 }
 
+static bool IsGoogScope(const UnwrappedLine &Line) {
+  if (Line.Tokens.size() < 4)
+    return false;
+  auto I = Line.Tokens.begin();
+  if (I->Tok->TokenText != "goog")
+    return false;
+  ++I;
+  if (I->Tok->isNot(tok::period))
+    return false;
+  ++I;
+  if (I->Tok->TokenText != "scope")
+    return false;
+  ++I;
+  return I->Tok->is(tok::l_paren);
+}
+
 void UnwrappedLineParser::parseChildBlock() {
   FormatTok->BlockKind = BK_Block;
   nextToken();
   {
+    bool GoogScope =
+        Style.Language == FormatStyle::LK_JavaScript && IsGoogScope(*Line);
     ScopedLineState LineState(*this);
     ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
                                             /*MustBeDeclaration=*/false);
-    Line->Level += 1;
+    Line->Level += GoogScope ? 0 : 1;
     parseLevel(/*HasOpeningBrace=*/true);
-    Line->Level -= 1;
+    Line->Level -= GoogScope ? 0 : 1;
   }
   nextToken();
 }
@@ -405,7 +456,7 @@
   ScopedMacroState MacroState(*Line, Tokens, FormatTok, StructuralError);
   nextToken();
 
-  if (FormatTok->Tok.getIdentifierInfo() == NULL) {
+  if (!FormatTok->Tok.getIdentifierInfo()) {
     parsePPUnknown();
     return;
   }
@@ -436,14 +487,14 @@
   }
 }
 
-void UnwrappedLineParser::pushPPConditional() {
-  if (!PPStack.empty() && PPStack.back() == PP_Unreachable)
+void UnwrappedLineParser::conditionalCompilationCondition(bool Unreachable) {
+  if (Unreachable || (!PPStack.empty() && PPStack.back() == PP_Unreachable))
     PPStack.push_back(PP_Unreachable);
   else
     PPStack.push_back(PP_Conditional);
 }
 
-void UnwrappedLineParser::parsePPIf(bool IfDef) {
+void UnwrappedLineParser::conditionalCompilationStart(bool Unreachable) {
   ++PPBranchLevel;
   assert(PPBranchLevel >= 0 && PPBranchLevel <= (int)PPLevelBranchIndex.size());
   if (PPBranchLevel == (int)PPLevelBranchIndex.size()) {
@@ -451,48 +502,56 @@
     PPLevelBranchCount.push_back(0);
   }
   PPChainBranchIndex.push(0);
-  nextToken();
-  bool IsLiteralFalse = (FormatTok->Tok.isLiteral() &&
-                         StringRef(FormatTok->Tok.getLiteralData(),
-                                   FormatTok->Tok.getLength()) == "0") ||
-                        FormatTok->Tok.is(tok::kw_false);
-  if ((!IfDef && IsLiteralFalse) || PPLevelBranchIndex[PPBranchLevel] > 0) {
-    PPStack.push_back(PP_Unreachable);
-  } else {
-    pushPPConditional();
-  }
-  parsePPUnknown();
+  bool Skip = PPLevelBranchIndex[PPBranchLevel] > 0;
+  conditionalCompilationCondition(Unreachable || Skip);
 }
 
-void UnwrappedLineParser::parsePPElse() {
+void UnwrappedLineParser::conditionalCompilationAlternative() {
   if (!PPStack.empty())
     PPStack.pop_back();
   assert(PPBranchLevel < (int)PPLevelBranchIndex.size());
   if (!PPChainBranchIndex.empty())
     ++PPChainBranchIndex.top();
-  if (PPBranchLevel >= 0 && !PPChainBranchIndex.empty() &&
-      PPLevelBranchIndex[PPBranchLevel] != PPChainBranchIndex.top()) {
-    PPStack.push_back(PP_Unreachable);
-  } else {
-    pushPPConditional();
-  }
-  parsePPUnknown();
+  conditionalCompilationCondition(
+      PPBranchLevel >= 0 && !PPChainBranchIndex.empty() &&
+      PPLevelBranchIndex[PPBranchLevel] != PPChainBranchIndex.top());
 }
 
-void UnwrappedLineParser::parsePPElIf() { parsePPElse(); }
-
-void UnwrappedLineParser::parsePPEndIf() {
+void UnwrappedLineParser::conditionalCompilationEnd() {
   assert(PPBranchLevel < (int)PPLevelBranchIndex.size());
   if (PPBranchLevel >= 0 && !PPChainBranchIndex.empty()) {
     if (PPChainBranchIndex.top() + 1 > PPLevelBranchCount[PPBranchLevel]) {
       PPLevelBranchCount[PPBranchLevel] = PPChainBranchIndex.top() + 1;
     }
   }
-  --PPBranchLevel;
+  // Guard against #endif's without #if.
+  if (PPBranchLevel > 0)
+    --PPBranchLevel;
   if (!PPChainBranchIndex.empty())
     PPChainBranchIndex.pop();
   if (!PPStack.empty())
     PPStack.pop_back();
+}
+
+void UnwrappedLineParser::parsePPIf(bool IfDef) {
+  nextToken();
+  bool IsLiteralFalse = (FormatTok->Tok.isLiteral() &&
+                         StringRef(FormatTok->Tok.getLiteralData(),
+                                   FormatTok->Tok.getLength()) == "0") ||
+                        FormatTok->Tok.is(tok::kw_false);
+  conditionalCompilationStart(!IfDef && IsLiteralFalse);
+  parsePPUnknown();
+}
+
+void UnwrappedLineParser::parsePPElse() {
+  conditionalCompilationAlternative();
+  parsePPUnknown();
+}
+
+void UnwrappedLineParser::parsePPElIf() { parsePPElse(); }
+
+void UnwrappedLineParser::parsePPEndIf() {
+  conditionalCompilationEnd();
   parsePPUnknown();
 }
 
@@ -551,7 +610,9 @@
          // Colon is used in labels, base class lists, initializer lists,
          // range-based for loops, ternary operator, but should never be the
          // first token in an unwrapped line.
-         Tok.isNot(tok::colon);
+         Tok.isNot(tok::colon) &&
+         // 'noexcept' is a trailing annotation.
+         Tok.isNot(tok::kw_noexcept);
 }
 
 void UnwrappedLineParser::parseStructuralElement() {
@@ -620,8 +681,8 @@
   case tok::kw_case:
     parseCaseLabel();
     return;
-  case tok::kw_return:
-    parseReturn();
+  case tok::kw_try:
+    parseTryCatch();
     return;
   case tok::kw_extern:
     nextToken();
@@ -633,6 +694,12 @@
         return;
       }
     }
+    break;
+  case tok::identifier:
+    if (FormatTok->IsForEachMacro) {
+      parseForOrWhileLoop();
+      return;
+    }
     // In all other cases, parse the declaration.
     break;
   default:
@@ -648,6 +715,12 @@
     case tok::kw_enum:
       parseEnum();
       break;
+    case tok::kw_typedef:
+      nextToken();
+      // FIXME: Use the IdentifierTable instead.
+      if (FormatTok->TokenText == "NS_ENUM")
+        parseEnum();
+      break;
     case tok::kw_struct:
     case tok::kw_union:
     case tok::kw_class:
@@ -667,9 +740,13 @@
       break;
     case tok::caret:
       nextToken();
-      if (FormatTok->is(tok::l_brace)) {
+      if (FormatTok->Tok.isAnyIdentifier() ||
+          FormatTok->isSimpleTypeSpecifier())
+        nextToken();
+      if (FormatTok->is(tok::l_paren))
+        parseParens();
+      if (FormatTok->is(tok::l_brace))
         parseChildBlock();
-      }
       break;
     case tok::l_brace:
       if (!tryToParseBracedList()) {
@@ -677,10 +754,9 @@
         // structural element.
         // FIXME: Figure out cases where this is not true, and add projections
         // for them (the one we know is missing are lambdas).
-        if (Style.BreakBeforeBraces == FormatStyle::BS_Linux ||
-            Style.BreakBeforeBraces == FormatStyle::BS_Stroustrup ||
-            Style.BreakBeforeBraces == FormatStyle::BS_Allman)
+        if (Style.BreakBeforeBraces != FormatStyle::BS_Attach)
           addUnwrappedLine();
+        FormatTok->Type = TT_FunctionLBrace;
         parseBlock(/*MustBeDeclaration=*/false);
         addUnwrappedLine();
         return;
@@ -688,8 +764,19 @@
       // Otherwise this was a braced init list, and the structural
       // element continues.
       break;
+    case tok::kw_try:
+      // We arrive here when parsing function-try blocks.
+      parseTryCatch();
+      return;
     case tok::identifier: {
       StringRef Text = FormatTok->TokenText;
+      // Parse function literal unless 'function' is the first token in a line
+      // in which case this should be treated as a free-standing function.
+      if (Style.Language == FormatStyle::LK_JavaScript && Text == "function" &&
+          Line->Tokens.size() > 0) {
+        tryToParseJSFunction();
+        break;
+      }
       nextToken();
       if (Line->Tokens.size() == 1) {
         if (FormatTok->Tok.is(tok::colon)) {
@@ -699,8 +786,8 @@
         // Recognize function-like macro usages without trailing semicolon.
         if (FormatTok->Tok.is(tok::l_paren)) {
           parseParens();
-          if (FormatTok->HasUnescapedNewline &&
-              tokenCanStartNewLine(FormatTok->Tok)) {
+          if (FormatTok->NewlinesBefore > 0 &&
+              tokenCanStartNewLine(FormatTok->Tok) && Text == Text.upper()) {
             addUnwrappedLine();
             return;
           }
@@ -720,7 +807,7 @@
       }
       break;
     case tok::l_square:
-      tryToParseLambda();
+      parseSquare();
       break;
     default:
       nextToken();
@@ -729,36 +816,50 @@
   } while (!eof());
 }
 
-void UnwrappedLineParser::tryToParseLambda() {
+bool UnwrappedLineParser::tryToParseLambda() {
   // FIXME: This is a dirty way to access the previous token. Find a better
   // solution.
   if (!Line->Tokens.empty() &&
-      Line->Tokens.back().Tok->isOneOf(tok::identifier, tok::kw_operator)) {
+      (Line->Tokens.back().Tok->isOneOf(tok::identifier, tok::kw_operator) ||
+       Line->Tokens.back().Tok->closesScope() ||
+       Line->Tokens.back().Tok->isSimpleTypeSpecifier())) {
     nextToken();
-    return;
+    return false;
   }
   assert(FormatTok->is(tok::l_square));
   FormatToken &LSquare = *FormatTok;
   if (!tryToParseLambdaIntroducer())
-    return;
+    return false;
 
   while (FormatTok->isNot(tok::l_brace)) {
+    if (FormatTok->isSimpleTypeSpecifier()) {
+      nextToken();
+      continue;
+    }
     switch (FormatTok->Tok.getKind()) {
     case tok::l_brace:
       break;
     case tok::l_paren:
       parseParens();
       break;
+    case tok::less:
+    case tok::greater:
     case tok::identifier:
+    case tok::coloncolon:
     case tok::kw_mutable:
       nextToken();
       break;
+    case tok::arrow:
+      FormatTok->Type = TT_TrailingReturnArrow;
+      nextToken();
+      break;
     default:
-      return;
+      return true;
     }
   }
   LSquare.Type = TT_LambdaLSquare;
   parseChildBlock();
+  return true;
 }
 
 bool UnwrappedLineParser::tryToParseLambdaIntroducer() {
@@ -793,6 +894,8 @@
     if (!FormatTok->isOneOf(tok::identifier, tok::kw_this))
       return false;
     nextToken();
+    if (FormatTok->is(tok::ellipsis))
+      nextToken();
     if (FormatTok->is(tok::comma)) {
       nextToken();
     } else if (FormatTok->is(tok::r_square)) {
@@ -805,6 +908,27 @@
   return false;
 }
 
+void UnwrappedLineParser::tryToParseJSFunction() {
+  nextToken();
+
+  // Consume function name.
+  if (FormatTok->is(tok::identifier))
+      nextToken();
+
+  if (FormatTok->isNot(tok::l_paren))
+    return;
+  nextToken();
+  while (FormatTok->isNot(tok::l_brace)) {
+    // Err on the side of caution in order to avoid consuming the full file in
+    // case of incomplete code.
+    if (!FormatTok->isOneOf(tok::identifier, tok::comma, tok::r_paren,
+                            tok::comment))
+      return;
+    nextToken();
+  }
+  parseChildBlock();
+}
+
 bool UnwrappedLineParser::tryToParseBracedList() {
   if (FormatTok->BlockKind == BK_Unknown)
     calculateBraceTypes();
@@ -822,9 +946,11 @@
   // FIXME: Once we have an expression parser in the UnwrappedLineParser,
   // replace this by using parseAssigmentExpression() inside.
   do {
-    // FIXME: When we start to support lambdas, we'll want to parse them away
-    // here, otherwise our bail-out scenarios below break. The better solution
-    // might be to just implement a more or less complete expression parser.
+    if (Style.Language == FormatStyle::LK_JavaScript &&
+        FormatTok->TokenText == "function") {
+      tryToParseJSFunction();
+      continue;
+    }
     switch (FormatTok->Tok.getKind()) {
     case tok::caret:
       nextToken();
@@ -861,40 +987,6 @@
   return false;
 }
 
-void UnwrappedLineParser::parseReturn() {
-  nextToken();
-
-  do {
-    switch (FormatTok->Tok.getKind()) {
-    case tok::l_brace:
-      parseBracedList();
-      if (FormatTok->Tok.isNot(tok::semi)) {
-        // Assume missing ';'.
-        addUnwrappedLine();
-        return;
-      }
-      break;
-    case tok::l_paren:
-      parseParens();
-      break;
-    case tok::r_brace:
-      // Assume missing ';'.
-      addUnwrappedLine();
-      return;
-    case tok::semi:
-      nextToken();
-      addUnwrappedLine();
-      return;
-    case tok::l_square:
-      tryToParseLambda();
-      break;
-    default:
-      nextToken();
-      break;
-    }
-  } while (!eof());
-}
-
 void UnwrappedLineParser::parseParens() {
   assert(FormatTok->Tok.is(tok::l_paren) && "'(' expected.");
   nextToken();
@@ -930,6 +1022,42 @@
   } while (!eof());
 }
 
+void UnwrappedLineParser::parseSquare() {
+  assert(FormatTok->Tok.is(tok::l_square) && "'[' expected.");
+  if (tryToParseLambda())
+    return;
+  do {
+    switch (FormatTok->Tok.getKind()) {
+    case tok::l_paren:
+      parseParens();
+      break;
+    case tok::r_square:
+      nextToken();
+      return;
+    case tok::r_brace:
+      // A "}" inside parenthesis is an error if there wasn't a matching "{".
+      return;
+    case tok::l_square:
+      parseSquare();
+      break;
+    case tok::l_brace: {
+      if (!tryToParseBracedList()) {
+        parseChildBlock();
+      }
+      break;
+    }
+    case tok::at:
+      nextToken();
+      if (FormatTok->Tok.is(tok::l_brace))
+        parseBracedList();
+      break;
+    default:
+      nextToken();
+      break;
+    }
+  } while (!eof());
+}
+
 void UnwrappedLineParser::parseIfThenElse() {
   assert(FormatTok->Tok.is(tok::kw_if) && "'if' expected");
   nextToken();
@@ -937,13 +1065,14 @@
     parseParens();
   bool NeedsUnwrappedLine = false;
   if (FormatTok->Tok.is(tok::l_brace)) {
-    if (Style.BreakBeforeBraces == FormatStyle::BS_Allman)
-      addUnwrappedLine();
+    CompoundStatementIndenter Indenter(this, Style, Line->Level);
     parseBlock(/*MustBeDeclaration=*/false);
-    if (Style.BreakBeforeBraces == FormatStyle::BS_Allman)
+    if (Style.BreakBeforeBraces == FormatStyle::BS_Allman ||
+        Style.BreakBeforeBraces == FormatStyle::BS_GNU) {
       addUnwrappedLine();
-    else
+    } else {
       NeedsUnwrappedLine = true;
+    }
   } else {
     addUnwrappedLine();
     ++Line->Level;
@@ -953,8 +1082,7 @@
   if (FormatTok->Tok.is(tok::kw_else)) {
     nextToken();
     if (FormatTok->Tok.is(tok::l_brace)) {
-      if (Style.BreakBeforeBraces == FormatStyle::BS_Allman)
-        addUnwrappedLine();
+      CompoundStatementIndenter Indenter(this, Style, Line->Level);
       parseBlock(/*MustBeDeclaration=*/false);
       addUnwrappedLine();
     } else if (FormatTok->Tok.is(tok::kw_if)) {
@@ -970,6 +1098,72 @@
   }
 }
 
+void UnwrappedLineParser::parseTryCatch() {
+  assert(FormatTok->is(tok::kw_try) && "'try' expected");
+  nextToken();
+  bool NeedsUnwrappedLine = false;
+  if (FormatTok->is(tok::colon)) {
+    // We are in a function try block, what comes is an initializer list.
+    nextToken();
+    while (FormatTok->is(tok::identifier)) {
+      nextToken();
+      if (FormatTok->is(tok::l_paren))
+        parseParens();
+      else
+        StructuralError = true;
+      if (FormatTok->is(tok::comma))
+        nextToken();
+    }
+  }
+  if (FormatTok->is(tok::l_brace)) {
+    CompoundStatementIndenter Indenter(this, Style, Line->Level);
+    parseBlock(/*MustBeDeclaration=*/false);
+    if (Style.BreakBeforeBraces == FormatStyle::BS_Allman ||
+        Style.BreakBeforeBraces == FormatStyle::BS_GNU ||
+        Style.BreakBeforeBraces == FormatStyle::BS_Stroustrup) {
+      addUnwrappedLine();
+    } else {
+      NeedsUnwrappedLine = true;
+    }
+  } else if (!FormatTok->is(tok::kw_catch)) {
+    // The C++ standard requires a compound-statement after a try.
+    // If there's none, we try to assume there's a structuralElement
+    // and try to continue.
+    StructuralError = true;
+    addUnwrappedLine();
+    ++Line->Level;
+    parseStructuralElement();
+    --Line->Level;
+  }
+  while (FormatTok->is(tok::kw_catch) ||
+         (Style.Language == FormatStyle::LK_JavaScript &&
+          FormatTok->TokenText == "finally")) {
+    nextToken();
+    while (FormatTok->isNot(tok::l_brace)) {
+      if (FormatTok->is(tok::l_paren)) {
+        parseParens();
+        continue;
+      }
+      if (FormatTok->isOneOf(tok::semi, tok::r_brace))
+        return;
+      nextToken();
+    }
+    NeedsUnwrappedLine = false;
+    CompoundStatementIndenter Indenter(this, Style, Line->Level);
+    parseBlock(/*MustBeDeclaration=*/false);
+    if (Style.BreakBeforeBraces == FormatStyle::BS_Allman ||
+        Style.BreakBeforeBraces == FormatStyle::BS_GNU ||
+        Style.BreakBeforeBraces == FormatStyle::BS_Stroustrup) {
+      addUnwrappedLine();
+    } else {
+      NeedsUnwrappedLine = true;
+    }
+  }
+  if (NeedsUnwrappedLine) {
+    addUnwrappedLine();
+  }
+}
+
 void UnwrappedLineParser::parseNamespace() {
   assert(FormatTok->Tok.is(tok::kw_namespace) && "'namespace' expected");
   nextToken();
@@ -977,7 +1171,8 @@
     nextToken();
   if (FormatTok->Tok.is(tok::l_brace)) {
     if (Style.BreakBeforeBraces == FormatStyle::BS_Linux ||
-        Style.BreakBeforeBraces == FormatStyle::BS_Allman)
+        Style.BreakBeforeBraces == FormatStyle::BS_Allman ||
+        Style.BreakBeforeBraces == FormatStyle::BS_GNU)
       addUnwrappedLine();
 
     bool AddLevel = Style.NamespaceIndentation == FormatStyle::NI_All ||
@@ -994,14 +1189,14 @@
 }
 
 void UnwrappedLineParser::parseForOrWhileLoop() {
-  assert((FormatTok->Tok.is(tok::kw_for) || FormatTok->Tok.is(tok::kw_while)) &&
-         "'for' or 'while' expected");
+  assert((FormatTok->Tok.is(tok::kw_for) || FormatTok->Tok.is(tok::kw_while) ||
+          FormatTok->IsForEachMacro) &&
+         "'for', 'while' or foreach macro expected");
   nextToken();
   if (FormatTok->Tok.is(tok::l_paren))
     parseParens();
   if (FormatTok->Tok.is(tok::l_brace)) {
-    if (Style.BreakBeforeBraces == FormatStyle::BS_Allman)
-      addUnwrappedLine();
+    CompoundStatementIndenter Indenter(this, Style, Line->Level);
     parseBlock(/*MustBeDeclaration=*/false);
     addUnwrappedLine();
   } else {
@@ -1016,9 +1211,10 @@
   assert(FormatTok->Tok.is(tok::kw_do) && "'do' expected");
   nextToken();
   if (FormatTok->Tok.is(tok::l_brace)) {
-    if (Style.BreakBeforeBraces == FormatStyle::BS_Allman)
-      addUnwrappedLine();
+    CompoundStatementIndenter Indenter(this, Style, Line->Level);
     parseBlock(/*MustBeDeclaration=*/false);
+    if (Style.BreakBeforeBraces == FormatStyle::BS_GNU)
+      addUnwrappedLine();
   } else {
     addUnwrappedLine();
     ++Line->Level;
@@ -1042,17 +1238,20 @@
   if (Line->Level > 1 || (!Line->InPPDirective && Line->Level > 0))
     --Line->Level;
   if (CommentsBeforeNextToken.empty() && FormatTok->Tok.is(tok::l_brace)) {
-    if (Style.BreakBeforeBraces == FormatStyle::BS_Allman)
-      addUnwrappedLine();
+    CompoundStatementIndenter Indenter(this, Style, Line->Level);
     parseBlock(/*MustBeDeclaration=*/false);
     if (FormatTok->Tok.is(tok::kw_break)) {
-      // "break;" after "}" on its own line only for BS_Allman
-      if (Style.BreakBeforeBraces == FormatStyle::BS_Allman)
+      // "break;" after "}" on its own line only for BS_Allman and BS_GNU
+      if (Style.BreakBeforeBraces == FormatStyle::BS_Allman ||
+          Style.BreakBeforeBraces == FormatStyle::BS_GNU) {
         addUnwrappedLine();
+      }
       parseStructuralElement();
     }
+    addUnwrappedLine();
+  } else {
+    addUnwrappedLine();
   }
-  addUnwrappedLine();
   Line->Level = OldLineLevel;
 }
 
@@ -1071,8 +1270,7 @@
   if (FormatTok->Tok.is(tok::l_paren))
     parseParens();
   if (FormatTok->Tok.is(tok::l_brace)) {
-    if (Style.BreakBeforeBraces == FormatStyle::BS_Allman)
-      addUnwrappedLine();
+    CompoundStatementIndenter Indenter(this, Style, Line->Level);
     parseBlock(/*MustBeDeclaration=*/false);
     addUnwrappedLine();
   } else {
@@ -1085,6 +1283,10 @@
 
 void UnwrappedLineParser::parseAccessSpecifier() {
   nextToken();
+  // Understand Qt's slots.
+  if (FormatTok->is(tok::identifier) &&
+      (FormatTok->TokenText == "slots" || FormatTok->TokenText == "Q_SLOTS"))
+    nextToken();
   // Otherwise, we don't know what it is, and we'd better keep the next token.
   if (FormatTok->Tok.is(tok::colon))
     nextToken();
@@ -1092,11 +1294,13 @@
 }
 
 void UnwrappedLineParser::parseEnum() {
-  nextToken();
+  if (FormatTok->Tok.is(tok::kw_enum)) {
+    // Won't be 'enum' for NS_ENUMs.
+    nextToken();
+  }
   // Eat up enum class ...
-  if (FormatTok->Tok.is(tok::kw_class) ||
-      FormatTok->Tok.is(tok::kw_struct))
-      nextToken();
+  if (FormatTok->Tok.is(tok::kw_class) || FormatTok->Tok.is(tok::kw_struct))
+    nextToken();
   while (FormatTok->Tok.getIdentifierInfo() ||
          FormatTok->isOneOf(tok::colon, tok::coloncolon)) {
     nextToken();
@@ -1159,10 +1363,11 @@
   }
   if (FormatTok->Tok.is(tok::l_brace)) {
     if (Style.BreakBeforeBraces == FormatStyle::BS_Linux ||
-        Style.BreakBeforeBraces == FormatStyle::BS_Allman)
+        Style.BreakBeforeBraces == FormatStyle::BS_Allman ||
+        Style.BreakBeforeBraces == FormatStyle::BS_GNU)
       addUnwrappedLine();
 
-    parseBlock(/*MustBeDeclaration=*/true, /*Addlevel=*/true,
+    parseBlock(/*MustBeDeclaration=*/true, /*AddLevel=*/true,
                /*MunchSemi=*/false);
   }
   // We fall through to parsing a structural element afterwards, so
@@ -1189,6 +1394,10 @@
       parseBlock(/*MustBeDeclaration=*/false);
       // In ObjC interfaces, nothing should be following the "}".
       addUnwrappedLine();
+    } else if (FormatTok->is(tok::r_brace)) {
+      // Ignore stray "}". parseStructuralElement doesn't consume them.
+      nextToken();
+      addUnwrappedLine();
     } else {
       parseStructuralElement();
     }
@@ -1210,9 +1419,12 @@
   if (FormatTok->Tok.is(tok::less))
     parseObjCProtocolList();
 
-  // If instance variables are present, keep the '{' on the first line too.
-  if (FormatTok->Tok.is(tok::l_brace))
+  if (FormatTok->Tok.is(tok::l_brace)) {
+    if (Style.BreakBeforeBraces == FormatStyle::BS_Allman ||
+        Style.BreakBeforeBraces == FormatStyle::BS_GNU)
+      addUnwrappedLine();
     parseBlock(/*MustBeDeclaration=*/true);
+  }
 
   // With instance variables, this puts '}' on its own line.  Without instance
   // variables, this ends the @interface line.
@@ -1283,13 +1495,18 @@
 
 bool UnwrappedLineParser::eof() const { return FormatTok->Tok.is(tok::eof); }
 
+bool UnwrappedLineParser::isOnNewLine(const FormatToken &FormatTok) {
+  return (Line->InPPDirective || FormatTok.HasUnescapedNewline) &&
+         FormatTok.NewlinesBefore > 0;
+}
+
 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 ((*I)->NewlinesBefore && JustComments) {
+    if (isOnNewLine(**I) && JustComments) {
       addUnwrappedLine();
     }
     pushToken(*I);
@@ -1303,7 +1520,7 @@
 void UnwrappedLineParser::nextToken() {
   if (eof())
     return;
-  flushComments(FormatTok->NewlinesBefore > 0);
+  flushComments(isOnNewLine(*FormatTok));
   pushToken(FormatTok);
   readToken();
 }
@@ -1312,6 +1529,7 @@
   bool CommentsInCurrentLine = true;
   do {
     FormatTok = Tokens->getNextToken();
+    assert(FormatTok);
     while (!Line->InPPDirective && FormatTok->Tok.is(tok::hash) &&
            (FormatTok->HasUnescapedNewline || FormatTok->IsFirst)) {
       // If there is an unfinished unwrapped line, we flush the preprocessor
@@ -1322,9 +1540,22 @@
       // Comments stored before the preprocessor directive need to be output
       // before the preprocessor directive, at the same level as the
       // preprocessor directive, as we consider them to apply to the directive.
-      flushComments(FormatTok->NewlinesBefore > 0);
+      flushComments(isOnNewLine(*FormatTok));
       parsePPDirective();
     }
+    while (FormatTok->Type == TT_ConflictStart ||
+           FormatTok->Type == TT_ConflictEnd ||
+           FormatTok->Type == TT_ConflictAlternative) {
+      if (FormatTok->Type == TT_ConflictStart) {
+        conditionalCompilationStart(/*Unreachable=*/false);
+      } else if (FormatTok->Type == TT_ConflictAlternative) {
+        conditionalCompilationAlternative();
+      } else if (FormatTok->Type == TT_ConflictEnd) {
+        conditionalCompilationEnd();
+      }
+      FormatTok = Tokens->getNextToken();
+      FormatTok->MustBreakBefore = true;
+    }
 
     if (!PPStack.empty() && (PPStack.back() == PP_Unreachable) &&
         !Line->InPPDirective) {
@@ -1333,7 +1564,7 @@
 
     if (!FormatTok->Tok.is(tok::comment))
       return;
-    if (FormatTok->NewlinesBefore > 0 || FormatTok->IsFirst) {
+    if (isOnNewLine(*FormatTok) || FormatTok->IsFirst) {
       CommentsInCurrentLine = false;
     }
     if (CommentsInCurrentLine) {
diff --git a/lib/Format/UnwrappedLineParser.h b/lib/Format/UnwrappedLineParser.h
index f1f4e57..c9182e9 100644
--- a/lib/Format/UnwrappedLineParser.h
+++ b/lib/Format/UnwrappedLineParser.h
@@ -16,9 +16,9 @@
 #ifndef LLVM_CLANG_FORMAT_UNWRAPPED_LINE_PARSER_H
 #define LLVM_CLANG_FORMAT_UNWRAPPED_LINE_PARSER_H
 
+#include "FormatToken.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "clang/Format/Format.h"
-#include "FormatToken.h"
 #include <list>
 
 namespace clang {
@@ -82,9 +82,10 @@
   void parseStructuralElement();
   bool tryToParseBracedList();
   bool parseBracedList(bool ContinueOnSemicolons = false);
-  void parseReturn();
   void parseParens();
+  void parseSquare();
   void parseIfThenElse();
+  void parseTryCatch();
   void parseForOrWhileLoop();
   void parseDoWhile();
   void parseLabel();
@@ -98,8 +99,9 @@
   void parseObjCUntilAtEnd();
   void parseObjCInterfaceOrImplementation();
   void parseObjCProtocol();
-  void tryToParseLambda();
+  bool tryToParseLambda();
   bool tryToParseLambdaIntroducer();
+  void tryToParseJSFunction();
   void addUnwrappedLine();
   bool eof() const;
   void nextToken();
@@ -107,12 +109,22 @@
   void flushComments(bool NewlineBeforeNext);
   void pushToken(FormatToken *Tok);
   void calculateBraceTypes();
-  void pushPPConditional();
+
+  // Marks a conditional compilation edge (for example, an '#if', '#ifdef',
+  // '#else' or merge conflict marker). If 'Unreachable' is true, assumes
+  // this branch either cannot be taken (for example '#if false'), or should
+  // not be taken in this round.
+  void conditionalCompilationCondition(bool Unreachable);
+  void conditionalCompilationStart(bool Unreachable);
+  void conditionalCompilationAlternative();
+  void conditionalCompilationEnd();
+
+  bool isOnNewLine(const FormatToken &FormatTok);
 
   // FIXME: We are constantly running into bugs where Line.Level is incorrectly
   // subtracted from beyond 0. Introduce a method to subtract from Line.Level
   // and use that everywhere in the Parser.
-  OwningPtr<UnwrappedLine> Line;
+  std::unique_ptr<UnwrappedLine> Line;
 
   // Comments are sorted into unwrapped lines by whether they are in the same
   // line as the previous token, or not. If not, they belong to the next token.
@@ -185,10 +197,11 @@
   std::stack<int> PPChainBranchIndex;
 
   friend class ScopedLineState;
+  friend class CompoundStatementIndenter;
 };
 
 struct UnwrappedLineNode {
-  UnwrappedLineNode() : Tok(NULL) {}
+  UnwrappedLineNode() : Tok(nullptr) {}
   UnwrappedLineNode(FormatToken *Tok) : Tok(Tok) {}
 
   FormatToken *Tok;
diff --git a/lib/Format/WhitespaceManager.cpp b/lib/Format/WhitespaceManager.cpp
index 26a8d41..47b94de 100644
--- a/lib/Format/WhitespaceManager.cpp
+++ b/lib/Format/WhitespaceManager.cpp
@@ -18,9 +18,8 @@
 namespace clang {
 namespace format {
 
-bool
-WhitespaceManager::Change::IsBeforeInFile::operator()(const Change &C1,
-                                                      const Change &C2) const {
+bool WhitespaceManager::Change::IsBeforeInFile::
+operator()(const Change &C1, const Change &C2) const {
   return SourceMgr.isBeforeInTranslationUnit(
       C1.OriginalWhitespaceRange.getBegin(),
       C2.OriginalWhitespaceRange.getBegin());
@@ -28,7 +27,7 @@
 
 WhitespaceManager::Change::Change(
     bool CreateReplacement, const SourceRange &OriginalWhitespaceRange,
-    unsigned IndentLevel, unsigned Spaces, unsigned StartOfTokenColumn,
+    unsigned IndentLevel, int Spaces, unsigned StartOfTokenColumn,
     unsigned NewlinesBefore, StringRef PreviousLinePostfix,
     StringRef CurrentLinePrefix, tok::TokenKind Kind, bool ContinuesPPDirective)
     : CreateReplacement(CreateReplacement),
@@ -69,14 +68,14 @@
 void WhitespaceManager::replaceWhitespaceInToken(
     const FormatToken &Tok, unsigned Offset, unsigned ReplaceChars,
     StringRef PreviousPostfix, StringRef CurrentPrefix, bool InPPDirective,
-    unsigned Newlines, unsigned IndentLevel, unsigned Spaces) {
+    unsigned Newlines, unsigned IndentLevel, int Spaces) {
   if (Tok.Finalized)
     return;
+  SourceLocation Start = Tok.getStartOfNonWhitespace().getLocWithOffset(Offset);
   Changes.push_back(Change(
-      true, SourceRange(Tok.getStartOfNonWhitespace().getLocWithOffset(Offset),
-                        Tok.getStartOfNonWhitespace().getLocWithOffset(
-                            Offset + ReplaceChars)),
-      IndentLevel, Spaces, Spaces, Newlines, PreviousPostfix, CurrentPrefix,
+      true, SourceRange(Start, Start.getLocWithOffset(ReplaceChars)),
+      IndentLevel, Spaces, std::max(0, Spaces), Newlines, PreviousPostfix,
+      CurrentPrefix,
       // If we don't add a newline this change doesn't start a comment. Thus,
       // when we align line comments, we don't need to treat this change as one.
       // FIXME: We still need to take this change in account to properly
@@ -122,6 +121,22 @@
   // cases, setting TokenLength of the last token to 0 is wrong.
   Changes.back().TokenLength = 0;
   Changes.back().IsTrailingComment = Changes.back().Kind == tok::comment;
+
+  const WhitespaceManager::Change *LastBlockComment = nullptr;
+  for (auto &Change : Changes) {
+    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;
+    } else {
+      LastBlockComment = nullptr;
+    }
+  }
 }
 
 void WhitespaceManager::alignTrailingComments() {
@@ -131,58 +146,62 @@
   bool BreakBeforeNext = false;
   unsigned Newlines = 0;
   for (unsigned i = 0, e = Changes.size(); i != e; ++i) {
-    unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn;
-    // FIXME: Correctly handle ChangeMaxColumn in PP directives.
-    unsigned ChangeMaxColumn = Style.ColumnLimit - Changes[i].TokenLength;
+    if (Changes[i].StartOfBlockComment)
+      continue;
     Newlines += Changes[i].NewlinesBefore;
-    if (Changes[i].IsTrailingComment) {
-      // 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].StartOfTokenColumn == 0;
-      bool WasAlignedWithStartOfNextLine = false;
-      if (Changes[i].NewlinesBefore == 1) { // A comment on its own line.
-        for (unsigned j = i + 1; j != e; ++j) {
-          if (Changes[j].Kind != tok::comment) { // Skip over comments.
-            // The start of the next token was previously aligned with the
-            // start of this comment.
-            WasAlignedWithStartOfNextLine =
-                (SourceMgr.getSpellingColumnNumber(
-                     Changes[i].OriginalWhitespaceRange.getEnd()) ==
-                 SourceMgr.getSpellingColumnNumber(
-                     Changes[j].OriginalWhitespaceRange.getEnd()));
-            break;
-          }
+    if (!Changes[i].IsTrailingComment)
+      continue;
+
+    unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn;
+    unsigned ChangeMaxColumn = Style.ColumnLimit - Changes[i].TokenLength;
+    if (i + 1 != e && Changes[i + 1].ContinuesPPDirective)
+      ChangeMaxColumn -= 2;
+    // 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].StartOfTokenColumn == 0;
+    bool WasAlignedWithStartOfNextLine = false;
+    if (Changes[i].NewlinesBefore == 1) { // A comment on its own line.
+      for (unsigned j = i + 1; j != e; ++j) {
+        if (Changes[j].Kind != tok::comment) { // Skip over comments.
+          // The start of the next token was previously aligned with the
+          // start of this comment.
+          WasAlignedWithStartOfNextLine =
+              (SourceMgr.getSpellingColumnNumber(
+                   Changes[i].OriginalWhitespaceRange.getEnd()) ==
+               SourceMgr.getSpellingColumnNumber(
+                   Changes[j].OriginalWhitespaceRange.getEnd()));
+          break;
         }
       }
-      if (!Style.AlignTrailingComments || FollowsRBraceInColumn0) {
-        alignTrailingComments(StartOfSequence, i, MinColumn);
-        MinColumn = ChangeMinColumn;
-        MaxColumn = ChangeMinColumn;
-        StartOfSequence = i;
-      } else if (BreakBeforeNext || Newlines > 1 ||
-                 (ChangeMinColumn > MaxColumn || ChangeMaxColumn < MinColumn) ||
-                 // Break the comment sequence if the previous line did not end
-                 // in a trailing comment.
-                 (Changes[i].NewlinesBefore == 1 && i > 0 &&
-                  !Changes[i - 1].IsTrailingComment) ||
-                 WasAlignedWithStartOfNextLine) {
-        alignTrailingComments(StartOfSequence, i, MinColumn);
-        MinColumn = ChangeMinColumn;
-        MaxColumn = ChangeMaxColumn;
-        StartOfSequence = i;
-      } else {
-        MinColumn = std::max(MinColumn, ChangeMinColumn);
-        MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
-      }
-      BreakBeforeNext =
-          (i == 0) || (Changes[i].NewlinesBefore > 1) ||
-          // Never start a sequence with a comment at the beginning of
-          // the line.
-          (Changes[i].NewlinesBefore == 1 && StartOfSequence == i);
-      Newlines = 0;
     }
+    if (!Style.AlignTrailingComments || FollowsRBraceInColumn0) {
+      alignTrailingComments(StartOfSequence, i, MinColumn);
+      MinColumn = ChangeMinColumn;
+      MaxColumn = ChangeMinColumn;
+      StartOfSequence = i;
+    } else if (BreakBeforeNext || Newlines > 1 ||
+               (ChangeMinColumn > MaxColumn || ChangeMaxColumn < MinColumn) ||
+               // Break the comment sequence if the previous line did not end
+               // in a trailing comment.
+               (Changes[i].NewlinesBefore == 1 && i > 0 &&
+                !Changes[i - 1].IsTrailingComment) ||
+               WasAlignedWithStartOfNextLine) {
+      alignTrailingComments(StartOfSequence, i, MinColumn);
+      MinColumn = ChangeMinColumn;
+      MaxColumn = ChangeMaxColumn;
+      StartOfSequence = i;
+    } else {
+      MinColumn = std::max(MinColumn, ChangeMinColumn);
+      MaxColumn = std::min(MaxColumn, ChangeMaxColumn);
+    }
+    BreakBeforeNext =
+        (i == 0) || (Changes[i].NewlinesBefore > 1) ||
+        // Never start a sequence with a comment at the beginning of
+        // the line.
+        (Changes[i].NewlinesBefore == 1 && StartOfSequence == i);
+    Newlines = 0;
   }
   alignTrailingComments(StartOfSequence, Changes.size(), MinColumn);
 }
@@ -190,11 +209,20 @@
 void WhitespaceManager::alignTrailingComments(unsigned Start, unsigned End,
                                               unsigned Column) {
   for (unsigned i = Start; i != End; ++i) {
+    int Shift = 0;
     if (Changes[i].IsTrailingComment) {
-      assert(Column >= Changes[i].StartOfTokenColumn);
-      Changes[i].Spaces += Column - Changes[i].StartOfTokenColumn;
-      Changes[i].StartOfTokenColumn = Column;
+      Shift = Column - Changes[i].StartOfTokenColumn;
     }
+    if (Changes[i].StartOfBlockComment) {
+      Shift = Changes[i].IndentationOffset +
+              Changes[i].StartOfBlockComment->StartOfTokenColumn -
+              Changes[i].StartOfTokenColumn;
+    }
+    assert(Shift >= 0);
+    Changes[i].Spaces += Shift;
+    if (i + 1 != End)
+      Changes[i + 1].PreviousEndOfTokenColumn += Shift;
+    Changes[i].StartOfTokenColumn += Shift;
   }
 }
 
@@ -241,8 +269,8 @@
                           C.PreviousEndOfTokenColumn, C.EscapedNewlineColumn);
       else
         appendNewlineText(ReplacementText, C.NewlinesBefore);
-      appendIndentText(ReplacementText, C.IndentLevel, C.Spaces,
-                       C.StartOfTokenColumn - C.Spaces);
+      appendIndentText(ReplacementText, C.IndentLevel, std::max(0, C.Spaces),
+                       C.StartOfTokenColumn - std::max(0, C.Spaces));
       ReplacementText.append(C.CurrentLinePrefix);
       storeReplacement(C.OriginalWhitespaceRange, ReplacementText);
     }
diff --git a/lib/Format/WhitespaceManager.h b/lib/Format/WhitespaceManager.h
index ae62023..189b1ae 100644
--- a/lib/Format/WhitespaceManager.h
+++ b/lib/Format/WhitespaceManager.h
@@ -51,7 +51,7 @@
                          unsigned StartOfTokenColumn,
                          bool InPPDirective = false);
 
-  /// \brief Adds information about an unchangable token's whitespace.
+  /// \brief Adds information about an unchangeable token's whitespace.
   ///
   /// Needs to be called for every token for which \c replaceWhitespace
   /// was not called.
@@ -63,6 +63,12 @@
   /// (in this order) at \p Offset inside \p Tok, replacing \p ReplaceChars
   /// characters.
   ///
+  /// Note: \p Spaces can be negative to retain information about initial
+  /// relative column offset between a line of a block comment and the start of
+  /// the comment. This negative offset may be compensated by trailing comment
+  /// alignment here. In all other cases negative \p Spaces will be truncated to
+  /// 0.
+  ///
   /// When \p InPPDirective is true, escaped newlines are inserted. \p Spaces is
   /// used to align backslashes correctly.
   void replaceWhitespaceInToken(const FormatToken &Tok, unsigned Offset,
@@ -70,7 +76,7 @@
                                 StringRef PreviousPostfix,
                                 StringRef CurrentPrefix, bool InPPDirective,
                                 unsigned Newlines, unsigned IndentLevel,
-                                unsigned Spaces);
+                                int Spaces);
 
   /// \brief Returns all the \c Replacements created during formatting.
   const tooling::Replacements &generateReplacements();
@@ -101,7 +107,7 @@
     /// \p StartOfTokenColumn and \p InPPDirective will be used to lay out
     /// trailing comments and escaped newlines.
     Change(bool CreateReplacement, const SourceRange &OriginalWhitespaceRange,
-           unsigned IndentLevel, unsigned Spaces, unsigned StartOfTokenColumn,
+           unsigned IndentLevel, int Spaces, unsigned StartOfTokenColumn,
            unsigned NewlinesBefore, StringRef PreviousLinePostfix,
            StringRef CurrentLinePrefix, tok::TokenKind Kind,
            bool ContinuesPPDirective);
@@ -128,7 +134,10 @@
 
     // The number of spaces in front of the token or broken part of the token.
     // This will be adapted when aligning tokens.
-    unsigned Spaces;
+    // Can be negative to retain information about the initial relative offset
+    // of the lines in a block comment. This is used when aligning trailing
+    // comments. Uncompensated negative offset is truncated to 0.
+    int Spaces;
 
     // \c IsTrailingComment, \c TokenLength, \c PreviousEndOfTokenColumn and
     // \c EscapedNewlineColumn will be calculated in
@@ -137,6 +146,17 @@
     unsigned TokenLength;
     unsigned PreviousEndOfTokenColumn;
     unsigned EscapedNewlineColumn;
+
+    // These fields are used to retain correct relative line indentation in a
+    // block comment when aligning trailing comments.
+    //
+    // If this Change represents a continuation of a block comment,
+    // \c StartOfBlockComment is pointer to the first Change in the block
+    // comment. \c IndentationOffset is a relative column offset to this
+    // change, so that the correct column can be reconstructed at the end of
+    // the alignment process.
+    const Change *StartOfBlockComment;
+    int IndentationOffset;
   };
 
   /// \brief Calculate \c IsTrailingComment, \c TokenLength for the last tokens
diff --git a/lib/Frontend/ASTConsumers.cpp b/lib/Frontend/ASTConsumers.cpp
index 1ef4c18..54a6d47 100644
--- a/lib/Frontend/ASTConsumers.cpp
+++ b/lib/Frontend/ASTConsumers.cpp
@@ -36,12 +36,12 @@
     typedef RecursiveASTVisitor<ASTPrinter> base;
 
   public:
-    ASTPrinter(raw_ostream *Out = NULL, bool Dump = false,
+    ASTPrinter(raw_ostream *Out = nullptr, bool Dump = false,
                StringRef FilterString = "", bool DumpLookups = false)
         : Out(Out ? *Out : llvm::outs()), Dump(Dump),
           FilterString(FilterString), DumpLookups(DumpLookups) {}
 
-    virtual void HandleTranslationUnit(ASTContext &Context) {
+    void HandleTranslationUnit(ASTContext &Context) override {
       TranslationUnitDecl *D = Context.getTranslationUnitDecl();
 
       if (FilterString.empty())
@@ -53,7 +53,7 @@
     bool shouldWalkTypesOfTypeLocs() const { return false; }
 
     bool TraverseDecl(Decl *D) {
-      if (D != NULL && filterMatches(D)) {
+      if (D && filterMatches(D)) {
         bool ShowColors = Out.has_colors();
         if (ShowColors)
           Out.changeColor(raw_ostream::BLUE);
@@ -98,16 +98,16 @@
   class ASTDeclNodeLister : public ASTConsumer,
                      public RecursiveASTVisitor<ASTDeclNodeLister> {
   public:
-    ASTDeclNodeLister(raw_ostream *Out = NULL)
+    ASTDeclNodeLister(raw_ostream *Out = nullptr)
         : Out(Out ? *Out : llvm::outs()) {}
 
-    virtual void HandleTranslationUnit(ASTContext &Context) {
+    void HandleTranslationUnit(ASTContext &Context) override {
       TraverseDecl(Context.getTranslationUnitDecl());
     }
 
     bool shouldWalkTypesOfTypeLocs() const { return false; }
 
-    virtual bool VisitNamedDecl(NamedDecl *D) {
+    bool VisitNamedDecl(NamedDecl *D) {
       D->printQualifiedName(Out);
       Out << '\n';
       return true;
@@ -124,11 +124,11 @@
 }
 
 ASTConsumer *clang::CreateASTDumper(StringRef FilterString, bool DumpLookups) {
-  return new ASTPrinter(0, /*Dump=*/ true, FilterString, DumpLookups);
+  return new ASTPrinter(nullptr, /*Dump=*/true, FilterString, DumpLookups);
 }
 
 ASTConsumer *clang::CreateASTDeclNodeLister() {
-  return new ASTDeclNodeLister(0);
+  return new ASTDeclNodeLister(nullptr);
 }
 
 //===----------------------------------------------------------------------===//
@@ -138,11 +138,11 @@
   class ASTViewer : public ASTConsumer {
     ASTContext *Context;
   public:
-    void Initialize(ASTContext &Context) {
+    void Initialize(ASTContext &Context) override {
       this->Context = &Context;
     }
 
-    virtual bool HandleTopLevelDecl(DeclGroupRef D) {
+    bool HandleTopLevelDecl(DeclGroupRef D) override {
       for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
         HandleTopLevelSingleDecl(*I);
       return true;
@@ -177,7 +177,7 @@
 public:
   DeclContextPrinter() : Out(llvm::errs()) {}
 
-  void HandleTranslationUnit(ASTContext &C) {
+  void HandleTranslationUnit(ASTContext &C) override {
     PrintDeclContext(C.getTranslationUnitDecl(), 4);
   }
 
@@ -259,13 +259,12 @@
     // Print the parameters.
     Out << "(";
     bool PrintComma = false;
-    for (FunctionDecl::param_const_iterator I = FD->param_begin(),
-           E = FD->param_end(); I != E; ++I) {
+    for (auto I : FD->params()) {
       if (PrintComma)
         Out << ", ";
       else
         PrintComma = true;
-      Out << **I;
+      Out << *I;
     }
     Out << ")";
     break;
@@ -369,8 +368,7 @@
   Out << "\n";
 
   // Print decls in the DeclContext.
-  for (DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
-       I != E; ++I) {
+  for (auto *I : DC->decls()) {
     for (unsigned i = 0; i < Indentation; ++i)
       Out << "  ";
 
@@ -394,58 +392,58 @@
     case Decl::CXXDestructor:
     case Decl::CXXConversion:
     {
-      DeclContext* DC = cast<DeclContext>(*I);
+      DeclContext* DC = cast<DeclContext>(I);
       PrintDeclContext(DC, Indentation+2);
       break;
     }
     case Decl::IndirectField: {
-      IndirectFieldDecl* IFD = cast<IndirectFieldDecl>(*I);
+      IndirectFieldDecl* IFD = cast<IndirectFieldDecl>(I);
       Out << "<IndirectField> " << *IFD << '\n';
       break;
     }
     case Decl::Label: {
-      LabelDecl *LD = cast<LabelDecl>(*I);
+      LabelDecl *LD = cast<LabelDecl>(I);
       Out << "<Label> " << *LD << '\n';
       break;
     }
     case Decl::Field: {
-      FieldDecl *FD = cast<FieldDecl>(*I);
+      FieldDecl *FD = cast<FieldDecl>(I);
       Out << "<field> " << *FD << '\n';
       break;
     }
     case Decl::Typedef:
     case Decl::TypeAlias: {
-      TypedefNameDecl* TD = cast<TypedefNameDecl>(*I);
+      TypedefNameDecl* TD = cast<TypedefNameDecl>(I);
       Out << "<typedef> " << *TD << '\n';
       break;
     }
     case Decl::EnumConstant: {
-      EnumConstantDecl* ECD = cast<EnumConstantDecl>(*I);
+      EnumConstantDecl* ECD = cast<EnumConstantDecl>(I);
       Out << "<enum constant> " << *ECD << '\n';
       break;
     }
     case Decl::Var: {
-      VarDecl* VD = cast<VarDecl>(*I);
+      VarDecl* VD = cast<VarDecl>(I);
       Out << "<var> " << *VD << '\n';
       break;
     }
     case Decl::ImplicitParam: {
-      ImplicitParamDecl* IPD = cast<ImplicitParamDecl>(*I);
+      ImplicitParamDecl* IPD = cast<ImplicitParamDecl>(I);
       Out << "<implicit parameter> " << *IPD << '\n';
       break;
     }
     case Decl::ParmVar: {
-      ParmVarDecl* PVD = cast<ParmVarDecl>(*I);
+      ParmVarDecl* PVD = cast<ParmVarDecl>(I);
       Out << "<parameter> " << *PVD << '\n';
       break;
     }
     case Decl::ObjCProperty: {
-      ObjCPropertyDecl* OPD = cast<ObjCPropertyDecl>(*I);
+      ObjCPropertyDecl* OPD = cast<ObjCPropertyDecl>(I);
       Out << "<objc property> " << *OPD << '\n';
       break;
     }
     case Decl::FunctionTemplate: {
-      FunctionTemplateDecl* FTD = cast<FunctionTemplateDecl>(*I);
+      FunctionTemplateDecl* FTD = cast<FunctionTemplateDecl>(I);
       Out << "<function template> " << *FTD << '\n';
       break;
     }
@@ -458,21 +456,21 @@
       break;
     }
     case Decl::NamespaceAlias: {
-      NamespaceAliasDecl* NAD = cast<NamespaceAliasDecl>(*I);
+      NamespaceAliasDecl* NAD = cast<NamespaceAliasDecl>(I);
       Out << "<namespace alias> " << *NAD << '\n';
       break;
     }
     case Decl::ClassTemplate: {
-      ClassTemplateDecl *CTD = cast<ClassTemplateDecl>(*I);
+      ClassTemplateDecl *CTD = cast<ClassTemplateDecl>(I);
       Out << "<class template> " << *CTD << '\n';
       break;
     }
     case Decl::OMPThreadPrivate: {
-      Out << "<omp threadprivate> " << '"' << *I << "\"\n";
+      Out << "<omp threadprivate> " << '"' << I << "\"\n";
       break;
     }
     default:
-      Out << "DeclKind: " << DK << '"' << *I << "\"\n";
+      Out << "DeclKind: " << DK << '"' << I << "\"\n";
       llvm_unreachable("decl unhandled");
     }
   }
diff --git a/lib/Frontend/ASTMerge.cpp b/lib/Frontend/ASTMerge.cpp
index b6c644e..ff6434c 100644
--- a/lib/Frontend/ASTMerge.cpp
+++ b/lib/Frontend/ASTMerge.cpp
@@ -57,16 +57,14 @@
                          /*MinimalImport=*/false);
 
     TranslationUnitDecl *TU = Unit->getASTContext().getTranslationUnitDecl();
-    for (DeclContext::decl_iterator D = TU->decls_begin(), 
-                                 DEnd = TU->decls_end();
-         D != DEnd; ++D) {
+    for (auto *D : TU->decls()) {
       // Don't re-import __va_list_tag, __builtin_va_list.
-      if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
+      if (const auto *ND = dyn_cast<NamedDecl>(D))
         if (IdentifierInfo *II = ND->getIdentifier())
           if (II->isStr("__va_list_tag") || II->isStr("__builtin_va_list"))
             continue;
       
-      Importer.Import(*D);
+      Importer.Import(D);
     }
 
     delete Unit;
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp
index a8c5876..fc44d9f 100644
--- a/lib/Frontend/ASTUnit.cpp
+++ b/lib/Frontend/ASTUnit.cpp
@@ -20,6 +20,7 @@
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/TargetOptions.h"
+#include "clang/Basic/VirtualFileSystem.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/FrontendActions.h"
 #include "clang/Frontend/FrontendDiagnostic.h"
@@ -35,9 +36,7 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringSet.h"
-#include "llvm/Support/Atomic.h"
 #include "llvm/Support/CrashRecoveryContext.h"
-#include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Host.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Mutex.h"
@@ -45,9 +44,9 @@
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Timer.h"
 #include "llvm/Support/raw_ostream.h"
+#include <atomic>
 #include <cstdio>
 #include <cstdlib>
-#include <sys/stat.h>
 using namespace clang;
 
 using llvm::TimeRecord;
@@ -191,10 +190,7 @@
 };
 
 void ASTUnit::clearFileLevelDecls() {
-  for (FileDeclsTy::iterator
-         I = FileDecls.begin(), E = FileDecls.end(); I != E; ++I)
-    delete I->second;
-  FileDecls.clear();
+  llvm::DeleteContainerSeconds(FileDecls);
 }
 
 void ASTUnit::CleanTemporaryFiles() {
@@ -214,27 +210,25 @@
 /// \brief Tracks the number of ASTUnit objects that are currently active.
 ///
 /// Used for debugging purposes only.
-static llvm::sys::cas_flag ActiveASTUnitObjects;
+static std::atomic<unsigned> ActiveASTUnitObjects;
 
 ASTUnit::ASTUnit(bool _MainFileIsAST)
-  : Reader(0), HadModuleLoaderFatalFailure(false),
+  : Reader(nullptr), HadModuleLoaderFatalFailure(false),
     OnlyLocalDecls(false), CaptureDiagnostics(false),
     MainFileIsAST(_MainFileIsAST), 
     TUKind(TU_Complete), WantTiming(getenv("LIBCLANG_TIMING")),
     OwnsRemappedFileBuffers(true),
     NumStoredDiagnosticsFromDriver(0),
-    PreambleRebuildCounter(0), SavedMainFileBuffer(0), PreambleBuffer(0),
-    NumWarningsInPreamble(0),
+    PreambleRebuildCounter(0), SavedMainFileBuffer(nullptr),
+    PreambleBuffer(nullptr), NumWarningsInPreamble(0),
     ShouldCacheCodeCompletionResults(false),
     IncludeBriefCommentsInCodeCompletion(false), UserFilesAreVolatile(false),
     CompletionCacheTopLevelHashValue(0),
     PreambleTopLevelHashValue(0),
     CurrentTopLevelHashValue(0),
     UnsafeToFree(false) { 
-  if (getenv("LIBCLANG_OBJTRACKING")) {
-    llvm::sys::AtomicIncrement(&ActiveASTUnitObjects);
-    fprintf(stderr, "+++ %d translation units\n", ActiveASTUnitObjects);
-  }    
+  if (getenv("LIBCLANG_OBJTRACKING"))
+    fprintf(stderr, "+++ %u translation units\n", ++ActiveASTUnitObjects);
 }
 
 ASTUnit::~ASTUnit() {
@@ -252,14 +246,10 @@
   // perform this operation here because we explicitly request that the
   // compiler instance *not* free these buffers for each invocation of the
   // parser.
-  if (Invocation.getPtr() && OwnsRemappedFileBuffers) {
+  if (Invocation.get() && OwnsRemappedFileBuffers) {
     PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts();
-    for (PreprocessorOptions::remapped_file_buffer_iterator
-           FB = PPOpts.remapped_file_buffer_begin(),
-           FBEnd = PPOpts.remapped_file_buffer_end();
-         FB != FBEnd;
-         ++FB)
-      delete FB->second;
+    for (const auto &RB : PPOpts.RemappedFileBuffers)
+      delete RB.second;
   }
   
   delete SavedMainFileBuffer;
@@ -267,10 +257,8 @@
 
   ClearCachedCompletionResults();  
   
-  if (getenv("LIBCLANG_OBJTRACKING")) {
-    llvm::sys::AtomicDecrement(&ActiveASTUnitObjects);
-    fprintf(stderr, "--- %d translation units\n", ActiveASTUnitObjects);
-  }    
+  if (getenv("LIBCLANG_OBJTRACKING"))
+    fprintf(stderr, "--- %u translation units\n", --ActiveASTUnitObjects);
 }
 
 void ASTUnit::setPreprocessor(Preprocessor *pp) { PP = pp; }
@@ -500,7 +488,7 @@
 void ASTUnit::ClearCachedCompletionResults() {
   CachedCompletionResults.clear();
   CachedCompletionTypes.clear();
-  CachedCompletionAllocator = 0;
+  CachedCompletionAllocator = nullptr;
 }
 
 namespace {
@@ -511,23 +499,20 @@
   Preprocessor &PP;
   ASTContext &Context;
   LangOptions &LangOpt;
-  IntrusiveRefCntPtr<TargetOptions> &TargetOpts;
+  std::shared_ptr<TargetOptions> &TargetOpts;
   IntrusiveRefCntPtr<TargetInfo> &Target;
   unsigned &Counter;
 
   bool InitializedLanguage;
 public:
-  ASTInfoCollector(Preprocessor &PP, ASTContext &Context, LangOptions &LangOpt, 
-                   IntrusiveRefCntPtr<TargetOptions> &TargetOpts,
-                   IntrusiveRefCntPtr<TargetInfo> &Target,
-                   unsigned &Counter)
-    : PP(PP), Context(Context), LangOpt(LangOpt),
-      TargetOpts(TargetOpts), Target(Target),
-      Counter(Counter),
-      InitializedLanguage(false) {}
+  ASTInfoCollector(Preprocessor &PP, ASTContext &Context, LangOptions &LangOpt,
+                   std::shared_ptr<TargetOptions> &TargetOpts,
+                   IntrusiveRefCntPtr<TargetInfo> &Target, unsigned &Counter)
+      : PP(PP), Context(Context), LangOpt(LangOpt), TargetOpts(TargetOpts),
+        Target(Target), Counter(Counter), InitializedLanguage(false) {}
 
-  virtual bool ReadLanguageOptions(const LangOptions &LangOpts,
-                                   bool Complain) {
+  bool ReadLanguageOptions(const LangOptions &LangOpts,
+                           bool Complain) override {
     if (InitializedLanguage)
       return false;
     
@@ -538,21 +523,22 @@
     return false;
   }
 
-  virtual bool ReadTargetOptions(const TargetOptions &TargetOpts,
-                                 bool Complain) {
+  bool ReadTargetOptions(const TargetOptions &TargetOpts,
+                         bool Complain) override {
     // If we've already initialized the target, don't do it again.
     if (Target)
       return false;
-    
-    this->TargetOpts = new TargetOptions(TargetOpts);
-    Target = TargetInfo::CreateTargetInfo(PP.getDiagnostics(),
-                                          &*this->TargetOpts);
+
+    this->TargetOpts = std::make_shared<TargetOptions>(TargetOpts);
+    Target =
+        TargetInfo::CreateTargetInfo(PP.getDiagnostics(), this->TargetOpts);
 
     updated();
     return false;
   }
 
-  virtual void ReadCounter(const serialization::ModuleFile &M, unsigned Value) {
+  void ReadCounter(const serialization::ModuleFile &M,
+                   unsigned Value) override {
     Counter = Value;
   }
 
@@ -565,7 +551,7 @@
     //
     // FIXME: We shouldn't need to do this, the target should be immutable once
     // created. This complexity should be lifted elsewhere.
-    Target->setForcedLangOptions(LangOpt);
+    Target->adjust(LangOpt);
 
     // Initialize the preprocessor.
     PP.Initialize(*Target);
@@ -588,16 +574,16 @@
 public:
   explicit StoredDiagnosticConsumer(
                           SmallVectorImpl<StoredDiagnostic> &StoredDiags)
-    : StoredDiags(StoredDiags), SourceMgr(0) { }
+    : StoredDiags(StoredDiags), SourceMgr(nullptr) {}
 
-  virtual void BeginSourceFile(const LangOptions &LangOpts,
-                               const Preprocessor *PP = 0) {
+  void BeginSourceFile(const LangOptions &LangOpts,
+                       const Preprocessor *PP = nullptr) override {
     if (PP)
       SourceMgr = &PP->getSourceManager();
   }
 
-  virtual void HandleDiagnostic(DiagnosticsEngine::Level Level,
-                                const Diagnostic &Info);
+  void HandleDiagnostic(DiagnosticsEngine::Level Level,
+                        const Diagnostic &Info) override;
 };
 
 /// \brief RAII object that optionally captures diagnostics, if
@@ -610,9 +596,9 @@
 public:
   CaptureDroppedDiagnostics(bool RequestCapture, DiagnosticsEngine &Diags,
                           SmallVectorImpl<StoredDiagnostic> &StoredDiags)
-    : Diags(Diags), Client(StoredDiags), PreviousClient(0)
+    : Diags(Diags), Client(StoredDiags), PreviousClient(nullptr)
   {
-    if (RequestCapture || Diags.getClient() == 0) {
+    if (RequestCapture || Diags.getClient() == nullptr) {
       PreviousClient = Diags.takeClient();
       Diags.setClient(&Client);
     }
@@ -643,13 +629,13 @@
 ASTMutationListener *ASTUnit::getASTMutationListener() {
   if (WriterData)
     return &WriterData->Writer;
-  return 0;
+  return nullptr;
 }
 
 ASTDeserializationListener *ASTUnit::getDeserializationListener() {
   if (WriterData)
     return &WriterData->Writer;
-  return 0;
+  return nullptr;
 }
 
 llvm::MemoryBuffer *ASTUnit::getBufferForFile(StringRef Filename,
@@ -662,10 +648,10 @@
 void ASTUnit::ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> &Diags,
                              const char **ArgBegin, const char **ArgEnd,
                              ASTUnit &AST, bool CaptureDiagnostics) {
-  if (!Diags.getPtr()) {
+  if (!Diags.get()) {
     // No diagnostics engine was provided, so create our own diagnostics object
     // with the default options.
-    DiagnosticConsumer *Client = 0;
+    DiagnosticConsumer *Client = nullptr;
     if (CaptureDiagnostics)
       Client = new StoredDiagnosticConsumer(AST.StoredDiagnostics);
     Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions(),
@@ -680,129 +666,74 @@
                               IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
                                   const FileSystemOptions &FileSystemOpts,
                                   bool OnlyLocalDecls,
-                                  RemappedFile *RemappedFiles,
-                                  unsigned NumRemappedFiles,
+                                  ArrayRef<RemappedFile> RemappedFiles,
                                   bool CaptureDiagnostics,
                                   bool AllowPCHWithCompilerErrors,
                                   bool UserFilesAreVolatile) {
-  OwningPtr<ASTUnit> AST(new ASTUnit(true));
+  std::unique_ptr<ASTUnit> AST(new ASTUnit(true));
 
   // Recover resources if we crash before exiting this method.
   llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
     ASTUnitCleanup(AST.get());
   llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
     llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
-    DiagCleanup(Diags.getPtr());
+    DiagCleanup(Diags.get());
 
-  ConfigureDiags(Diags, 0, 0, *AST, CaptureDiagnostics);
+  ConfigureDiags(Diags, nullptr, nullptr, *AST, CaptureDiagnostics);
 
   AST->OnlyLocalDecls = OnlyLocalDecls;
   AST->CaptureDiagnostics = CaptureDiagnostics;
   AST->Diagnostics = Diags;
-  AST->FileMgr = new FileManager(FileSystemOpts);
+  IntrusiveRefCntPtr<vfs::FileSystem> VFS = vfs::getRealFileSystem();
+  AST->FileMgr = new FileManager(FileSystemOpts, VFS);
   AST->UserFilesAreVolatile = UserFilesAreVolatile;
   AST->SourceMgr = new SourceManager(AST->getDiagnostics(),
                                      AST->getFileManager(),
                                      UserFilesAreVolatile);
   AST->HSOpts = new HeaderSearchOptions();
-  
+
   AST->HeaderInfo.reset(new HeaderSearch(AST->HSOpts,
                                          AST->getSourceManager(),
                                          AST->getDiagnostics(),
                                          AST->ASTFileLangOpts,
-                                         /*Target=*/0));
-  
-  for (unsigned I = 0; I != NumRemappedFiles; ++I) {
-    FilenameOrMemBuf fileOrBuf = RemappedFiles[I].second;
-    if (const llvm::MemoryBuffer *
-          memBuf = fileOrBuf.dyn_cast<const llvm::MemoryBuffer *>()) {
-      // Create the file entry for the file that we're mapping from.
-      const FileEntry *FromFile
-        = AST->getFileManager().getVirtualFile(RemappedFiles[I].first,
-                                               memBuf->getBufferSize(),
-                                               0);
-      if (!FromFile) {
-        AST->getDiagnostics().Report(diag::err_fe_remap_missing_from_file)
-          << RemappedFiles[I].first;
-        delete memBuf;
-        continue;
-      }
-      
-      // Override the contents of the "from" file with the contents of
-      // the "to" file.
-      AST->getSourceManager().overrideFileContents(FromFile, memBuf);
+                                         /*Target=*/nullptr));
 
-    } else {
-      const char *fname = fileOrBuf.get<const char *>();
-      const FileEntry *ToFile = AST->FileMgr->getFile(fname);
-      if (!ToFile) {
-        AST->getDiagnostics().Report(diag::err_fe_remap_missing_to_file)
-        << RemappedFiles[I].first << fname;
-        continue;
-      }
+  PreprocessorOptions *PPOpts = new PreprocessorOptions();
 
-      // Create the file entry for the file that we're mapping from.
-      const FileEntry *FromFile
-        = AST->getFileManager().getVirtualFile(RemappedFiles[I].first,
-                                               ToFile->getSize(),
-                                               0);
-      if (!FromFile) {
-        AST->getDiagnostics().Report(diag::err_fe_remap_missing_from_file)
-          << RemappedFiles[I].first;
-        delete memBuf;
-        continue;
-      }
-      
-      // Override the contents of the "from" file with the contents of
-      // the "to" file.
-      AST->getSourceManager().overrideFileContents(FromFile, ToFile);
-    }
-  }
-  
+  for (unsigned I = 0, N = RemappedFiles.size(); I != N; ++I)
+    PPOpts->addRemappedFile(RemappedFiles[I].first, RemappedFiles[I].second);
+
   // Gather Info for preprocessor construction later on.
 
   HeaderSearch &HeaderInfo = *AST->HeaderInfo.get();
   unsigned Counter;
 
-  OwningPtr<ASTReader> Reader;
-
-  AST->PP = new Preprocessor(new PreprocessorOptions(),
-                             AST->getDiagnostics(), AST->ASTFileLangOpts,
-                             /*Target=*/0, AST->getSourceManager(), HeaderInfo, 
-                             *AST, 
-                             /*IILookup=*/0,
-                             /*OwnsHeaderSearch=*/false,
-                             /*DelayInitialization=*/true);
+  AST->PP =
+      new Preprocessor(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(),
-                            /*Target=*/0,
-                            PP.getIdentifierTable(),
-                            PP.getSelectorTable(),
-                            PP.getBuiltinInfo(),
-                            /* size_reserve = */0,
-                            /*DelayInitialization=*/true);
+  AST->Ctx = new ASTContext(AST->ASTFileLangOpts, AST->getSourceManager(),
+                            PP.getIdentifierTable(), PP.getSelectorTable(),
+                            PP.getBuiltinInfo());
   ASTContext &Context = *AST->Ctx;
 
   bool disableValid = false;
   if (::getenv("LIBCLANG_DISABLE_PCH_VALIDATION"))
     disableValid = true;
-  Reader.reset(new ASTReader(PP, Context,
+  AST->Reader = new ASTReader(PP, Context,
                              /*isysroot=*/"",
                              /*DisableValidation=*/disableValid,
-                             AllowPCHWithCompilerErrors));
-  
-  // Recover resources if we crash before exiting this method.
-  llvm::CrashRecoveryContextCleanupRegistrar<ASTReader>
-    ReaderCleanup(Reader.get());
+                             AllowPCHWithCompilerErrors);
 
-  Reader->setListener(new ASTInfoCollector(*AST->PP, Context,
+  AST->Reader->setListener(new ASTInfoCollector(*AST->PP, Context,
                                            AST->ASTFileLangOpts,
                                            AST->TargetOpts, AST->Target, 
                                            Counter));
 
-  switch (Reader->ReadAST(Filename, serialization::MK_MainFile,
+  switch (AST->Reader->ReadAST(Filename, serialization::MK_MainFile,
                           SourceLocation(), ASTReader::ARR_None)) {
   case ASTReader::Success:
     break;
@@ -814,24 +745,17 @@
   case ASTReader::ConfigurationMismatch:
   case ASTReader::HadErrors:
     AST->getDiagnostics().Report(diag::err_fe_unable_to_load_pch);
-    return NULL;
+    return nullptr;
   }
 
-  AST->OriginalSourceFile = Reader->getOriginalSourceFile();
+  AST->OriginalSourceFile = AST->Reader->getOriginalSourceFile();
 
   PP.setCounterValue(Counter);
 
   // Attach the AST reader to the AST context as an external AST
   // source, so that declarations will be deserialized from the
   // AST file as needed.
-  ASTReader *ReaderPtr = Reader.get();
-  OwningPtr<ExternalASTSource> Source(Reader.take());
-
-  // Unregister the cleanup for ASTReader.  It will get cleaned up
-  // by the ASTUnit cleanup.
-  ReaderCleanup.unregister();
-
-  Context.setExternalSource(Source);
+  Context.setExternalSource(AST->Reader);
 
   // Create an AST consumer, even though it isn't used.
   AST->Consumer.reset(new ASTConsumer);
@@ -839,13 +763,12 @@
   // Create a semantic analysis object and tell the AST reader about it.
   AST->TheSema.reset(new Sema(PP, Context, *AST->Consumer));
   AST->TheSema->Initialize();
-  ReaderPtr->InitializeSema(*AST->TheSema);
-  AST->Reader = ReaderPtr;
+  AST->Reader->InitializeSema(*AST->TheSema);
 
   // Tell the diagnostic client that we have started a source file.
   AST->getDiagnostics().getClient()->BeginSourceFile(Context.getLangOpts(),&PP);
 
-  return AST.take();
+  return AST.release();
 }
 
 namespace {
@@ -857,9 +780,9 @@
   
 public:
   explicit MacroDefinitionTrackerPPCallbacks(unsigned &Hash) : Hash(Hash) { }
-  
-  virtual void MacroDefined(const Token &MacroNameTok,
-                            const MacroDirective *MD) {
+
+  void MacroDefined(const Token &MacroNameTok,
+                    const MacroDirective *MD) override {
     Hash = llvm::HashString(MacroNameTok.getIdentifierInfo()->getName(), Hash);
   }
 };
@@ -881,10 +804,9 @@
       // For an unscoped enum include the enumerators in the hash since they
       // enter the top-level namespace.
       if (!EnumD->isScoped()) {
-        for (EnumDecl::enumerator_iterator EI = EnumD->enumerator_begin(),
-               EE = EnumD->enumerator_end(); EI != EE; ++EI) {
-          if ((*EI)->getIdentifier())
-            Hash = llvm::HashString((*EI)->getIdentifier()->getName(), Hash);
+        for (const auto *EI : EnumD->enumerators()) {
+          if (EI->getIdentifier())
+            Hash = llvm::HashString(EI->getIdentifier()->getName(), Hash);
         }
       }
     }
@@ -937,31 +859,30 @@
   void handleFileLevelDecl(Decl *D) {
     Unit.addFileLevelDecl(D);
     if (NamespaceDecl *NSD = dyn_cast<NamespaceDecl>(D)) {
-      for (NamespaceDecl::decl_iterator
-             I = NSD->decls_begin(), E = NSD->decls_end(); I != E; ++I)
-        handleFileLevelDecl(*I);
+      for (auto *I : NSD->decls())
+        handleFileLevelDecl(I);
     }
   }
 
-  bool HandleTopLevelDecl(DeclGroupRef D) {
+  bool HandleTopLevelDecl(DeclGroupRef D) override {
     for (DeclGroupRef::iterator it = D.begin(), ie = D.end(); it != ie; ++it)
       handleTopLevelDecl(*it);
     return true;
   }
 
   // We're not interested in "interesting" decls.
-  void HandleInterestingDecl(DeclGroupRef) {}
+  void HandleInterestingDecl(DeclGroupRef) override {}
 
-  void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) {
+  void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override {
     for (DeclGroupRef::iterator it = D.begin(), ie = D.end(); it != ie; ++it)
       handleTopLevelDecl(*it);
   }
 
-  virtual ASTMutationListener *GetASTMutationListener() {
+  ASTMutationListener *GetASTMutationListener() override {
     return Unit.getASTMutationListener();
   }
 
-  virtual ASTDeserializationListener *GetASTDeserializationListener() {
+  ASTDeserializationListener *GetASTDeserializationListener() override {
     return Unit.getDeserializationListener();
   }
 };
@@ -970,8 +891,8 @@
 public:
   ASTUnit &Unit;
 
-  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
-                                         StringRef InFile) {
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override {
     CI.getPreprocessor().addPPCallbacks(
      new MacroDefinitionTrackerPPCallbacks(Unit.getCurrentTopLevelHashValue()));
     return new TopLevelDeclTrackerConsumer(Unit, 
@@ -981,8 +902,8 @@
 public:
   TopLevelDeclTrackerAction(ASTUnit &_Unit) : Unit(_Unit) {}
 
-  virtual bool hasCodeCompletionSupport() const { return false; }
-  virtual TranslationUnitKind getTranslationUnitKind()  { 
+  bool hasCodeCompletionSupport() const override { return false; }
+  TranslationUnitKind getTranslationUnitKind() override {
     return Unit.getTranslationUnitKind(); 
   }
 };
@@ -995,15 +916,15 @@
   explicit PrecompilePreambleAction(ASTUnit &Unit)
       : Unit(Unit), HasEmittedPreamblePCH(false) {}
 
-  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
-                                         StringRef InFile);
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override;
   bool hasEmittedPreamblePCH() const { return HasEmittedPreamblePCH; }
   void setHasEmittedPreamblePCH() { HasEmittedPreamblePCH = true; }
-  virtual bool shouldEraseOutputFiles() { return !hasEmittedPreamblePCH(); }
+  bool shouldEraseOutputFiles() override { return !hasEmittedPreamblePCH(); }
 
-  virtual bool hasCodeCompletionSupport() const { return false; }
-  virtual bool hasASTFileSupport() const { return false; }
-  virtual TranslationUnitKind getTranslationUnitKind() { return TU_Prefix; }
+  bool hasCodeCompletionSupport() const override { return false; }
+  bool hasASTFileSupport() const override { return false; }
+  TranslationUnitKind getTranslationUnitKind() override { return TU_Prefix; }
 };
 
 class PrecompilePreambleConsumer : public PCHGenerator {
@@ -1016,12 +937,12 @@
   PrecompilePreambleConsumer(ASTUnit &Unit, PrecompilePreambleAction *Action,
                              const Preprocessor &PP, StringRef isysroot,
                              raw_ostream *Out)
-    : PCHGenerator(PP, "", 0, isysroot, Out, /*AllowASTWithErrors=*/true),
+    : PCHGenerator(PP, "", nullptr, isysroot, Out, /*AllowASTWithErrors=*/true),
       Unit(Unit), Hash(Unit.getCurrentTopLevelHashValue()), Action(Action) {
     Hash = 0;
   }
 
-  virtual bool HandleTopLevelDecl(DeclGroupRef D) {
+  bool HandleTopLevelDecl(DeclGroupRef D) override {
     for (DeclGroupRef::iterator it = D.begin(), ie = D.end(); it != ie; ++it) {
       Decl *D = *it;
       // FIXME: Currently ObjC method declarations are incorrectly being
@@ -1036,7 +957,7 @@
     return true;
   }
 
-  virtual void HandleTranslationUnit(ASTContext &Ctx) {
+  void HandleTranslationUnit(ASTContext &Ctx) override {
     PCHGenerator::HandleTranslationUnit(Ctx);
     if (hasEmittedPCH()) {
       // Translate the top-level declarations we captured during
@@ -1062,10 +983,10 @@
                                                          StringRef InFile) {
   std::string Sysroot;
   std::string OutputFile;
-  raw_ostream *OS = 0;
+  raw_ostream *OS = nullptr;
   if (GeneratePCHAction::ComputeASTConsumerArguments(CI, InFile, Sysroot,
                                                      OutputFile, OS))
-    return 0;
+    return nullptr;
 
   if (!CI.getFrontendOpts().RelocatablePCH)
     Sysroot.clear();
@@ -1112,15 +1033,15 @@
 /// contain any translation-unit information, false otherwise.
 bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) {
   delete SavedMainFileBuffer;
-  SavedMainFileBuffer = 0;
-  
+  SavedMainFileBuffer = nullptr;
+
   if (!Invocation) {
     delete OverrideMainBuffer;
     return true;
   }
   
   // Create the compiler instance to use for building the AST.
-  OwningPtr<CompilerInstance> Clang(new CompilerInstance());
+  std::unique_ptr<CompilerInstance> Clang(new CompilerInstance());
 
   // Recover resources if we crash before exiting this method.
   llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
@@ -1129,7 +1050,7 @@
   IntrusiveRefCntPtr<CompilerInvocation>
     CCInvocation(new CompilerInvocation(*Invocation));
 
-  Clang->setInvocation(CCInvocation.getPtr());
+  Clang->setInvocation(CCInvocation.get());
   OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].getFile();
     
   // Set up diagnostics, capturing any diagnostics that would
@@ -1137,8 +1058,8 @@
   Clang->setDiagnostics(&getDiagnostics());
   
   // Create the target instance.
-  Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(),
-                   &Clang->getTargetOpts()));
+  Clang->setTarget(TargetInfo::CreateTargetInfo(
+      Clang->getDiagnostics(), Clang->getInvocation().TargetOpts));
   if (!Clang->hasTarget()) {
     delete OverrideMainBuffer;
     return true;
@@ -1148,7 +1069,7 @@
   //
   // FIXME: We shouldn't need to do this, the target should be immutable once
   // created. This complexity should be lifted elsewhere.
-  Clang->getTarget().setForcedLangOptions(Clang->getLangOpts());
+  Clang->getTarget().adjust(Clang->getLangOpts());
   
   assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
          "Invocation must have exactly one source file!");
@@ -1158,17 +1079,22 @@
          "IR inputs not support here!");
 
   // Configure the various subsystems.
-  // FIXME: Should we retain the previous file manager?
-  LangOpts = &Clang->getLangOpts();
+  LangOpts = Clang->getInvocation().LangOpts;
   FileSystemOpts = Clang->getFileSystemOpts();
-  FileMgr = new FileManager(FileSystemOpts);
+  IntrusiveRefCntPtr<vfs::FileSystem> VFS =
+      createVFSFromCompilerInvocation(Clang->getInvocation(), getDiagnostics());
+  if (!VFS) {
+    delete OverrideMainBuffer;
+    return true;
+  }
+  FileMgr = new FileManager(FileSystemOpts, VFS);
   SourceMgr = new SourceManager(getDiagnostics(), *FileMgr,
                                 UserFilesAreVolatile);
   TheSema.reset();
-  Ctx = 0;
-  PP = 0;
-  Reader = 0;
-  
+  Ctx = nullptr;
+  PP = nullptr;
+  Reader = nullptr;
+
   // Clear out old caches and data.
   TopLevelDecls.clear();
   clearFileLevelDecls();
@@ -1206,10 +1132,10 @@
     // Keep track of the override buffer;
     SavedMainFileBuffer = OverrideMainBuffer;
   }
-  
-  OwningPtr<TopLevelDeclTrackerAction> Act(
-    new TopLevelDeclTrackerAction(*this));
-    
+
+  std::unique_ptr<TopLevelDeclTrackerAction> Act(
+      new TopLevelDeclTrackerAction(*this));
+
   // Recover resources if we crash before exiting this method.
   llvm::CrashRecoveryContextCleanupRegistrar<TopLevelDeclTrackerAction>
     ActCleanup(Act.get());
@@ -1219,9 +1145,8 @@
 
   if (OverrideMainBuffer) {
     std::string ModName = getPreambleFile(this);
-    TranslateStoredDiagnostics(Clang->getModuleManager(), ModName,
-                               getSourceManager(), PreambleDiagnostics,
-                               StoredDiagnostics);
+    TranslateStoredDiagnostics(getFileManager(), getSourceManager(),
+                               PreambleDiagnostics, StoredDiagnostics);
   }
 
   if (!Act->Execute())
@@ -1239,7 +1164,7 @@
   // Remove the overridden buffer we used for the preamble.
   if (OverrideMainBuffer) {
     delete OverrideMainBuffer;
-    SavedMainFileBuffer = 0;
+    SavedMainFileBuffer = nullptr;
   }
 
   // Keep the ownership of the data in the ASTUnit because the client may
@@ -1279,17 +1204,13 @@
   // Try to determine if the main file has been remapped, either from the 
   // command line (to another file) or directly through the compiler invocation
   // (to a memory buffer).
-  llvm::MemoryBuffer *Buffer = 0;
+  llvm::MemoryBuffer *Buffer = nullptr;
   std::string MainFilePath(FrontendOpts.Inputs[0].getFile());
   llvm::sys::fs::UniqueID MainFileID;
   if (!llvm::sys::fs::getUniqueID(MainFilePath, MainFileID)) {
     // Check whether there is a file-file remapping of the main file
-    for (PreprocessorOptions::remapped_file_iterator
-          M = PreprocessorOpts.remapped_file_begin(),
-          E = PreprocessorOpts.remapped_file_end();
-         M != E;
-         ++M) {
-      std::string MPath(M->first);
+    for (const auto &RF : PreprocessorOpts.RemappedFiles) {
+      std::string MPath(RF.first);
       llvm::sys::fs::UniqueID MID;
       if (!llvm::sys::fs::getUniqueID(MPath, MID)) {
         if (MainFileID == MID) {
@@ -1298,11 +1219,10 @@
             delete Buffer;
             CreatedBuffer = false;
           }
-          
-          Buffer = getBufferForFile(M->second);
+
+          Buffer = getBufferForFile(RF.second);
           if (!Buffer)
-            return std::make_pair((llvm::MemoryBuffer*)0, 
-                                  std::make_pair(0, true));
+            return std::make_pair(nullptr, std::make_pair(0, true));
           CreatedBuffer = true;
         }
       }
@@ -1310,12 +1230,8 @@
     
     // Check whether there is a file-buffer remapping. It supercedes the
     // file-file remapping.
-    for (PreprocessorOptions::remapped_file_buffer_iterator
-           M = PreprocessorOpts.remapped_file_buffer_begin(),
-           E = PreprocessorOpts.remapped_file_buffer_end();
-         M != E;
-         ++M) {
-      std::string MPath(M->first);
+    for (const auto &RB : PreprocessorOpts.RemappedFileBuffers) {
+      std::string MPath(RB.first);
       llvm::sys::fs::UniqueID MID;
       if (!llvm::sys::fs::getUniqueID(MPath, MID)) {
         if (MainFileID == MID) {
@@ -1324,8 +1240,8 @@
             delete Buffer;
             CreatedBuffer = false;
           }
-          
-          Buffer = const_cast<llvm::MemoryBuffer *>(M->second);
+
+          Buffer = const_cast<llvm::MemoryBuffer *>(RB.second);
         }
       }
     }
@@ -1335,8 +1251,8 @@
   if (!Buffer) {
     Buffer = getBufferForFile(FrontendOpts.Inputs[0].getFile());
     if (!Buffer)
-      return std::make_pair((llvm::MemoryBuffer*)0, std::make_pair(0, true));    
-    
+      return std::make_pair(nullptr, std::make_pair(0, true));
+
     CreatedBuffer = true;
   }
   
@@ -1345,20 +1261,83 @@
                                                        MaxLines));
 }
 
-static llvm::MemoryBuffer *CreatePaddedMainFileBuffer(llvm::MemoryBuffer *Old,
-                                                      unsigned NewSize,
-                                                      StringRef NewName) {
-  llvm::MemoryBuffer *Result
-    = llvm::MemoryBuffer::getNewUninitMemBuffer(NewSize, NewName);
-  memcpy(const_cast<char*>(Result->getBufferStart()), 
-         Old->getBufferStart(), Old->getBufferSize());
-  memset(const_cast<char*>(Result->getBufferStart()) + Old->getBufferSize(), 
-         ' ', NewSize - Old->getBufferSize() - 1);
-  const_cast<char*>(Result->getBufferEnd())[-1] = '\n';  
-  
+ASTUnit::PreambleFileHash
+ASTUnit::PreambleFileHash::createForFile(off_t Size, time_t ModTime) {
+  PreambleFileHash Result;
+  Result.Size = Size;
+  Result.ModTime = ModTime;
+  memset(Result.MD5, 0, sizeof(Result.MD5));
   return Result;
 }
 
+ASTUnit::PreambleFileHash ASTUnit::PreambleFileHash::createForMemoryBuffer(
+    const llvm::MemoryBuffer *Buffer) {
+  PreambleFileHash Result;
+  Result.Size = Buffer->getBufferSize();
+  Result.ModTime = 0;
+
+  llvm::MD5 MD5Ctx;
+  MD5Ctx.update(Buffer->getBuffer().data());
+  MD5Ctx.final(Result.MD5);
+
+  return Result;
+}
+
+namespace clang {
+bool operator==(const ASTUnit::PreambleFileHash &LHS,
+                const ASTUnit::PreambleFileHash &RHS) {
+  return LHS.Size == RHS.Size && LHS.ModTime == RHS.ModTime &&
+         memcmp(LHS.MD5, RHS.MD5, sizeof(LHS.MD5)) == 0;
+}
+} // namespace clang
+
+static std::pair<unsigned, unsigned>
+makeStandaloneRange(CharSourceRange Range, const SourceManager &SM,
+                    const LangOptions &LangOpts) {
+  CharSourceRange FileRange = Lexer::makeFileCharRange(Range, SM, LangOpts);
+  unsigned Offset = SM.getFileOffset(FileRange.getBegin());
+  unsigned EndOffset = SM.getFileOffset(FileRange.getEnd());
+  return std::make_pair(Offset, EndOffset);
+}
+
+static void makeStandaloneFixIt(const SourceManager &SM,
+                                const LangOptions &LangOpts,
+                                const FixItHint &InFix,
+                                ASTUnit::StandaloneFixIt &OutFix) {
+  OutFix.RemoveRange = makeStandaloneRange(InFix.RemoveRange, SM, LangOpts);
+  OutFix.InsertFromRange = makeStandaloneRange(InFix.InsertFromRange, SM,
+                                               LangOpts);
+  OutFix.CodeToInsert = InFix.CodeToInsert;
+  OutFix.BeforePreviousInsertions = InFix.BeforePreviousInsertions;
+}
+
+static void makeStandaloneDiagnostic(const LangOptions &LangOpts,
+                                     const StoredDiagnostic &InDiag,
+                                     ASTUnit::StandaloneDiagnostic &OutDiag) {
+  OutDiag.ID = InDiag.getID();
+  OutDiag.Level = InDiag.getLevel();
+  OutDiag.Message = InDiag.getMessage();
+  OutDiag.LocOffset = 0;
+  if (InDiag.getLocation().isInvalid())
+    return;
+  const SourceManager &SM = InDiag.getLocation().getManager();
+  SourceLocation FileLoc = SM.getFileLoc(InDiag.getLocation());
+  OutDiag.Filename = SM.getFilename(FileLoc);
+  if (OutDiag.Filename.empty())
+    return;
+  OutDiag.LocOffset = SM.getFileOffset(FileLoc);
+  for (StoredDiagnostic::range_iterator
+         I = InDiag.range_begin(), E = InDiag.range_end(); I != E; ++I) {
+    OutDiag.Ranges.push_back(makeStandaloneRange(*I, SM, LangOpts));
+  }
+  for (StoredDiagnostic::fixit_iterator
+         I = InDiag.fixit_begin(), E = InDiag.fixit_end(); I != E; ++I) {
+    ASTUnit::StandaloneFixIt Fix;
+    makeStandaloneFixIt(SM, LangOpts, *I, Fix);
+    OutDiag.FixIts.push_back(Fix);
+  }
+}
+
 /// \brief Attempt to build or re-use a precompiled preamble when (re-)parsing
 /// the source file.
 ///
@@ -1395,7 +1374,7 @@
     = ComputePreamble(*PreambleInvocation, MaxLines, CreatedPreambleBuffer);
 
   // If ComputePreamble() Take ownership of the preamble buffer.
-  OwningPtr<llvm::MemoryBuffer> OwnedPreambleBuffer;
+  std::unique_ptr<llvm::MemoryBuffer> OwnedPreambleBuffer;
   if (CreatedPreambleBuffer)
     OwnedPreambleBuffer.reset(NewPreamble.first);
 
@@ -1407,7 +1386,7 @@
 
     // The next time we actually see a preamble, precompile it.
     PreambleRebuildCounter = 1;
-    return 0;
+    return nullptr;
   }
   
   if (!Preamble.empty()) {
@@ -1417,7 +1396,6 @@
     // new main file.
     if (Preamble.size() == NewPreamble.second.first &&
         PreambleEndsAtStartOfLine == NewPreamble.second.second &&
-        NewPreamble.first->getBufferSize() < PreambleReservedSize-2 &&
         memcmp(Preamble.getBufferStart(), NewPreamble.first->getBufferStart(),
                NewPreamble.second.first) == 0) {
       // The preamble has not changed. We may be able to re-use the precompiled
@@ -1428,40 +1406,36 @@
           
       // First, make a record of those files that have been overridden via
       // remapping or unsaved_files.
-      llvm::StringMap<std::pair<off_t, time_t> > OverriddenFiles;
-      for (PreprocessorOptions::remapped_file_iterator
-                R = PreprocessorOpts.remapped_file_begin(),
-             REnd = PreprocessorOpts.remapped_file_end();
-           !AnyFileChanged && R != REnd;
-           ++R) {
-        llvm::sys::fs::file_status Status;
-        if (FileMgr->getNoncachedStatValue(R->second, Status)) {
+      llvm::StringMap<PreambleFileHash> OverriddenFiles;
+      for (const auto &R : PreprocessorOpts.RemappedFiles) {
+        if (AnyFileChanged)
+          break;
+
+        vfs::Status Status;
+        if (FileMgr->getNoncachedStatValue(R.second, Status)) {
           // If we can't stat the file we're remapping to, assume that something
           // horrible happened.
           AnyFileChanged = true;
           break;
         }
 
-        OverriddenFiles[R->first] = std::make_pair(
+        OverriddenFiles[R.first] = PreambleFileHash::createForFile(
             Status.getSize(), Status.getLastModificationTime().toEpochTime());
       }
-      for (PreprocessorOptions::remapped_file_buffer_iterator
-                R = PreprocessorOpts.remapped_file_buffer_begin(),
-             REnd = PreprocessorOpts.remapped_file_buffer_end();
-           !AnyFileChanged && R != REnd;
-           ++R) {
-        // FIXME: Should we actually compare the contents of file->buffer
-        // remappings?
-        OverriddenFiles[R->first] = std::make_pair(R->second->getBufferSize(), 
-                                                   0);
+
+      for (const auto &RB : PreprocessorOpts.RemappedFileBuffers) {
+        if (AnyFileChanged)
+          break;
+        OverriddenFiles[RB.first] =
+            PreambleFileHash::createForMemoryBuffer(RB.second);
       }
        
       // Check whether anything has changed.
-      for (llvm::StringMap<std::pair<off_t, time_t> >::iterator 
+      for (llvm::StringMap<PreambleFileHash>::iterator 
              F = FilesInPreamble.begin(), FEnd = FilesInPreamble.end();
            !AnyFileChanged && F != FEnd; 
            ++F) {
-        llvm::StringMap<std::pair<off_t, time_t> >::iterator Overridden
+        llvm::StringMap<PreambleFileHash>::iterator Overridden
           = OverriddenFiles.find(F->first());
         if (Overridden != OverriddenFiles.end()) {
           // This file was remapped; check whether the newly-mapped file 
@@ -1472,13 +1446,13 @@
         }
         
         // The file was not remapped; check whether it has changed on disk.
-        llvm::sys::fs::file_status Status;
+        vfs::Status Status;
         if (FileMgr->getNoncachedStatValue(F->first(), Status)) {
           // If we can't stat the file, assume that something horrible happened.
           AnyFileChanged = true;
-        } else if (Status.getSize() != uint64_t(F->second.first) ||
+        } else if (Status.getSize() != uint64_t(F->second.Size) ||
                    Status.getLastModificationTime().toEpochTime() !=
-                       uint64_t(F->second.second))
+                       uint64_t(F->second.ModTime))
           AnyFileChanged = true;
       }
           
@@ -1492,18 +1466,15 @@
                               PreambleInvocation->getDiagnosticOpts());
         getDiagnostics().setNumWarnings(NumWarningsInPreamble);
 
-        // Create a version of the main file buffer that is padded to
-        // buffer size we reserved when creating the preamble.
-        return CreatePaddedMainFileBuffer(NewPreamble.first, 
-                                          PreambleReservedSize,
-                                          FrontendOpts.Inputs[0].getFile());
+        return llvm::MemoryBuffer::getMemBufferCopy(
+            NewPreamble.first->getBuffer(), FrontendOpts.Inputs[0].getFile());
       }
     }
 
     // If we aren't allowed to rebuild the precompiled preamble, just
     // return now.
     if (!AllowRebuild)
-      return 0;
+      return nullptr;
 
     // We can't reuse the previously-computed preamble. Build a new one.
     Preamble.clear();
@@ -1513,7 +1484,7 @@
   } else if (!AllowRebuild) {
     // We aren't allowed to rebuild the precompiled preamble; just
     // return now.
-    return 0;
+    return nullptr;
   }
 
   // If the preamble rebuild counter > 1, it's because we previously
@@ -1521,7 +1492,7 @@
   // again. Decrement the counter and return a failure.
   if (PreambleRebuildCounter > 1) {
     --PreambleRebuildCounter;
-    return 0;
+    return nullptr;
   }
 
   // Create a temporary file for the precompiled preamble. In rare 
@@ -1530,26 +1501,16 @@
   if (PreamblePCHPath.empty()) {
     // Try again next time.
     PreambleRebuildCounter = 1;
-    return 0;
+    return nullptr;
   }
   
   // We did not previously compute a preamble, or it can't be reused anyway.
   SimpleTimer PreambleTimer(WantTiming);
   PreambleTimer.setOutput("Precompiling preamble");
-  
-  // Create a new buffer that stores the preamble. The buffer also contains
-  // extra space for the original contents of the file (which will be present
-  // when we actually parse the file) along with more room in case the file
-  // grows.  
-  PreambleReservedSize = NewPreamble.first->getBufferSize();
-  if (PreambleReservedSize < 4096)
-    PreambleReservedSize = 8191;
-  else
-    PreambleReservedSize *= 2;
 
   // Save the preamble text for later; we'll need to compare against it for
   // subsequent reparses.
-  StringRef MainFilename = PreambleInvocation->getFrontendOpts().Inputs[0].getFile();
+  StringRef MainFilename = FrontendOpts.Inputs[0].getFile();
   Preamble.assign(FileMgr->getFile(MainFilename),
                   NewPreamble.first->getBufferStart(), 
                   NewPreamble.first->getBufferStart() 
@@ -1558,13 +1519,8 @@
 
   delete PreambleBuffer;
   PreambleBuffer
-    = llvm::MemoryBuffer::getNewUninitMemBuffer(PreambleReservedSize,
-                                                FrontendOpts.Inputs[0].getFile());
-  memcpy(const_cast<char*>(PreambleBuffer->getBufferStart()), 
-         NewPreamble.first->getBufferStart(), Preamble.size());
-  memset(const_cast<char*>(PreambleBuffer->getBufferStart()) + Preamble.size(), 
-         ' ', PreambleReservedSize - Preamble.size() - 1);
-  const_cast<char*>(PreambleBuffer->getBufferEnd())[-1] = '\n';  
+    = llvm::MemoryBuffer::getMemBufferCopy(
+        NewPreamble.first->getBuffer().slice(0, Preamble.size()), MainFilename);
 
   // Remap the main source file to the preamble buffer.
   StringRef MainFilePath = FrontendOpts.Inputs[0].getFile();
@@ -1578,7 +1534,7 @@
   PreprocessorOpts.PrecompiledPreambleBytes.second = false;
   
   // Create the compiler instance to use for building the precompiled preamble.
-  OwningPtr<CompilerInstance> Clang(new CompilerInstance());
+  std::unique_ptr<CompilerInstance> Clang(new CompilerInstance());
 
   // Recover resources if we crash before exiting this method.
   llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
@@ -1591,22 +1547,21 @@
   Clang->setDiagnostics(&getDiagnostics());
   
   // Create the target instance.
-  Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(),
-                                                &Clang->getTargetOpts()));
+  Clang->setTarget(TargetInfo::CreateTargetInfo(
+      Clang->getDiagnostics(), Clang->getInvocation().TargetOpts));
   if (!Clang->hasTarget()) {
     llvm::sys::fs::remove(FrontendOpts.OutputFile);
     Preamble.clear();
     PreambleRebuildCounter = DefaultPreambleRebuildInterval;
-    PreprocessorOpts.eraseRemappedFile(
-                               PreprocessorOpts.remapped_file_buffer_end() - 1);
-    return 0;
+    PreprocessorOpts.RemappedFileBuffers.pop_back();
+    return nullptr;
   }
   
   // Inform the target of the language options.
   //
   // FIXME: We shouldn't need to do this, the target should be immutable once
   // created. This complexity should be lifted elsewhere.
-  Clang->getTarget().setForcedLangOptions(Clang->getLangOpts());
+  Clang->getTarget().adjust(Clang->getLangOpts());
   
   assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
          "Invocation must have exactly one source file!");
@@ -1621,28 +1576,49 @@
   checkAndRemoveNonDriverDiags(StoredDiagnostics);
   TopLevelDecls.clear();
   TopLevelDeclsInPreamble.clear();
-  
+  PreambleDiagnostics.clear();
+
+  IntrusiveRefCntPtr<vfs::FileSystem> VFS =
+      createVFSFromCompilerInvocation(Clang->getInvocation(), getDiagnostics());
+  if (!VFS)
+    return nullptr;
+
   // Create a file manager object to provide access to and cache the filesystem.
-  Clang->setFileManager(new FileManager(Clang->getFileSystemOpts()));
+  Clang->setFileManager(new FileManager(Clang->getFileSystemOpts(), VFS));
   
   // Create the source manager.
   Clang->setSourceManager(new SourceManager(getDiagnostics(),
                                             Clang->getFileManager()));
-  
-  OwningPtr<PrecompilePreambleAction> Act;
+
+  auto PreambleDepCollector = std::make_shared<DependencyCollector>();
+  Clang->addDependencyCollector(PreambleDepCollector);
+
+  std::unique_ptr<PrecompilePreambleAction> Act;
   Act.reset(new PrecompilePreambleAction(*this));
   if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0])) {
     llvm::sys::fs::remove(FrontendOpts.OutputFile);
     Preamble.clear();
     PreambleRebuildCounter = DefaultPreambleRebuildInterval;
-    PreprocessorOpts.eraseRemappedFile(
-                               PreprocessorOpts.remapped_file_buffer_end() - 1);
-    return 0;
+    PreprocessorOpts.RemappedFileBuffers.pop_back();
+    return nullptr;
   }
   
   Act->Execute();
+
+  // Transfer any diagnostics generated when parsing the preamble into the set
+  // of preamble diagnostics.
+  for (stored_diag_iterator
+         I = stored_diag_afterDriver_begin(),
+         E = stored_diag_end(); I != E; ++I) {
+    StandaloneDiagnostic Diag;
+    makeStandaloneDiagnostic(Clang->getLangOpts(), *I, Diag);
+    PreambleDiagnostics.push_back(Diag);
+  }
+
   Act->EndSourceFile();
 
+  checkAndRemoveNonDriverDiags(StoredDiagnostics);
+
   if (!Act->hasEmittedPreamblePCH()) {
     // The preamble PCH failed (e.g. there was a module loading fatal error),
     // so no precompiled header was generated. Forget that we even tried.
@@ -1651,18 +1627,10 @@
     Preamble.clear();
     TopLevelDeclsInPreamble.clear();
     PreambleRebuildCounter = DefaultPreambleRebuildInterval;
-    PreprocessorOpts.eraseRemappedFile(
-                               PreprocessorOpts.remapped_file_buffer_end() - 1);
-    return 0;
+    PreprocessorOpts.RemappedFileBuffers.pop_back();
+    return nullptr;
   }
   
-  // Transfer any diagnostics generated when parsing the preamble into the set
-  // of preamble diagnostics.
-  PreambleDiagnostics.clear();
-  PreambleDiagnostics.insert(PreambleDiagnostics.end(), 
-                            stored_diag_afterDriver_begin(), stored_diag_end());
-  checkAndRemoveNonDriverDiags(StoredDiagnostics);
-  
   // Keep track of the preamble we precompiled.
   setPreambleFile(this, FrontendOpts.OutputFile);
   NumWarningsInPreamble = getDiagnostics().getNumWarnings();
@@ -1671,24 +1639,23 @@
   // so we can verify whether they have changed or not.
   FilesInPreamble.clear();
   SourceManager &SourceMgr = Clang->getSourceManager();
-  const llvm::MemoryBuffer *MainFileBuffer
-    = SourceMgr.getBuffer(SourceMgr.getMainFileID());
-  for (SourceManager::fileinfo_iterator F = SourceMgr.fileinfo_begin(),
-                                     FEnd = SourceMgr.fileinfo_end();
-       F != FEnd;
-       ++F) {
-    const FileEntry *File = F->second->OrigEntry;
-    if (!File || F->second->getRawBuffer() == MainFileBuffer)
+  for (auto &Filename : PreambleDepCollector->getDependencies()) {
+    const FileEntry *File = Clang->getFileManager().getFile(Filename);
+    if (!File || File == SourceMgr.getFileEntryForID(SourceMgr.getMainFileID()))
       continue;
-    
-    FilesInPreamble[File->getName()]
-      = std::make_pair(F->second->getSize(), File->getModificationTime());
+    if (time_t ModTime = File->getModificationTime()) {
+      FilesInPreamble[File->getName()] = PreambleFileHash::createForFile(
+          File->getSize(), ModTime);
+    } else {
+      llvm::MemoryBuffer *Buffer = SourceMgr.getMemoryBufferForFile(File);
+      FilesInPreamble[File->getName()] =
+          PreambleFileHash::createForMemoryBuffer(Buffer);
+    }
   }
-  
+
   PreambleRebuildCounter = 1;
-  PreprocessorOpts.eraseRemappedFile(
-                               PreprocessorOpts.remapped_file_buffer_end() - 1);
-  
+  PreprocessorOpts.RemappedFileBuffers.pop_back();
+
   // If the hash of top-level entities differs from the hash of the top-level
   // entities the last time we rebuilt the preamble, clear out the completion
   // cache.
@@ -1697,9 +1664,8 @@
     PreambleTopLevelHashValue = CurrentTopLevelHashValue;
   }
   
-  return CreatePaddedMainFileBuffer(NewPreamble.first, 
-                                    PreambleReservedSize,
-                                    FrontendOpts.Inputs[0].getFile());
+  return llvm::MemoryBuffer::getMemBufferCopy(NewPreamble.first->getBuffer(),
+                                              MainFilename);
 }
 
 void ASTUnit::RealizeTopLevelDeclsFromPreamble() {
@@ -1718,14 +1684,20 @@
 }
 
 void ASTUnit::transferASTDataFromCompilerInstance(CompilerInstance &CI) {
-  // Steal the created target, context, and preprocessor.
+  // Steal the created target, context, and preprocessor if they have been
+  // created.
+  assert(CI.hasInvocation() && "missing invocation");
+  LangOpts = CI.getInvocation().LangOpts;
   TheSema.reset(CI.takeSema());
   Consumer.reset(CI.takeASTConsumer());
-  Ctx = &CI.getASTContext();
-  PP = &CI.getPreprocessor();
-  CI.setSourceManager(0);
-  CI.setFileManager(0);
-  Target = &CI.getTarget();
+  if (CI.hasASTContext())
+    Ctx = &CI.getASTContext();
+  if (CI.hasPreprocessor())
+    PP = &CI.getPreprocessor();
+  CI.setSourceManager(nullptr);
+  CI.setFileManager(nullptr);
+  if (CI.hasTarget())
+    Target = &CI.getTarget();
   Reader = CI.getModuleManager();
   HadModuleLoaderFatalFailure = CI.hadModuleLoaderFatalFailure();
 }
@@ -1761,41 +1733,41 @@
                          IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
                          bool CaptureDiagnostics,
                          bool UserFilesAreVolatile) {
-  OwningPtr<ASTUnit> AST;
+  std::unique_ptr<ASTUnit> AST;
   AST.reset(new ASTUnit(false));
-  ConfigureDiags(Diags, 0, 0, *AST, CaptureDiagnostics);
+  ConfigureDiags(Diags, nullptr, nullptr, *AST, CaptureDiagnostics);
   AST->Diagnostics = Diags;
   AST->Invocation = CI;
   AST->FileSystemOpts = CI->getFileSystemOpts();
-  AST->FileMgr = new FileManager(AST->FileSystemOpts);
+  IntrusiveRefCntPtr<vfs::FileSystem> VFS =
+      createVFSFromCompilerInvocation(*CI, *Diags);
+  if (!VFS)
+    return nullptr;
+  AST->FileMgr = new FileManager(AST->FileSystemOpts, VFS);
   AST->UserFilesAreVolatile = UserFilesAreVolatile;
   AST->SourceMgr = new SourceManager(AST->getDiagnostics(), *AST->FileMgr,
                                      UserFilesAreVolatile);
 
-  return AST.take();
+  return AST.release();
 }
 
-ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(CompilerInvocation *CI,
-                              IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
-                                             ASTFrontendAction *Action,
-                                             ASTUnit *Unit,
-                                             bool Persistent,
-                                             StringRef ResourceFilesPath,
-                                             bool OnlyLocalDecls,
-                                             bool CaptureDiagnostics,
-                                             bool PrecompilePreamble,
-                                             bool CacheCodeCompletionResults,
-                                    bool IncludeBriefCommentsInCodeCompletion,
-                                             bool UserFilesAreVolatile,
-                                             OwningPtr<ASTUnit> *ErrAST) {
+ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(
+    CompilerInvocation *CI, IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
+    ASTFrontendAction *Action, ASTUnit *Unit, bool Persistent,
+    StringRef ResourceFilesPath, bool OnlyLocalDecls, bool CaptureDiagnostics,
+    bool PrecompilePreamble, bool CacheCodeCompletionResults,
+    bool IncludeBriefCommentsInCodeCompletion, bool UserFilesAreVolatile,
+    std::unique_ptr<ASTUnit> *ErrAST) {
   assert(CI && "A CompilerInvocation is required");
 
-  OwningPtr<ASTUnit> OwnAST;
+  std::unique_ptr<ASTUnit> OwnAST;
   ASTUnit *AST = Unit;
   if (!AST) {
     // Create the AST unit.
     OwnAST.reset(create(CI, Diags, CaptureDiagnostics, UserFilesAreVolatile));
     AST = OwnAST.get();
+    if (!AST)
+      return nullptr;
   }
   
   if (!ResourceFilesPath.empty()) {
@@ -1816,7 +1788,7 @@
     ASTUnitCleanup(OwnAST.get());
   llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
     llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
-    DiagCleanup(Diags.getPtr());
+    DiagCleanup(Diags.get());
 
   // We'll manage file buffers ourselves.
   CI->getPreprocessorOpts().RetainRemappedFileBuffers = true;
@@ -1824,7 +1796,7 @@
   ProcessWarningOptions(AST->getDiagnostics(), CI->getDiagnosticOpts());
 
   // Create the compiler instance to use for building the AST.
-  OwningPtr<CompilerInstance> Clang(new CompilerInstance());
+  std::unique_ptr<CompilerInstance> Clang(new CompilerInstance());
 
   // Recover resources if we crash before exiting this method.
   llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
@@ -1838,16 +1810,16 @@
   Clang->setDiagnostics(&AST->getDiagnostics());
   
   // Create the target instance.
-  Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(),
-                                                &Clang->getTargetOpts()));
+  Clang->setTarget(TargetInfo::CreateTargetInfo(
+      Clang->getDiagnostics(), Clang->getInvocation().TargetOpts));
   if (!Clang->hasTarget())
-    return 0;
+    return nullptr;
 
   // Inform the target of the language options.
   //
   // FIXME: We shouldn't need to do this, the target should be immutable once
   // created. This complexity should be lifted elsewhere.
-  Clang->getTarget().setForcedLangOptions(Clang->getLangOpts());
+  Clang->getTarget().adjust(Clang->getLangOpts());
   
   assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
          "Invocation must have exactly one source file!");
@@ -1858,10 +1830,10 @@
 
   // Configure the various subsystems.
   AST->TheSema.reset();
-  AST->Ctx = 0;
-  AST->PP = 0;
-  AST->Reader = 0;
-  
+  AST->Ctx = nullptr;
+  AST->PP = nullptr;
+  AST->Reader = nullptr;
+
   // Create a file manager object to provide access to and cache the filesystem.
   Clang->setFileManager(&AST->getFileManager());
   
@@ -1870,7 +1842,7 @@
 
   ASTFrontendAction *Act = Action;
 
-  OwningPtr<TopLevelDeclTrackerAction> TrackerAct;
+  std::unique_ptr<TopLevelDeclTrackerAction> TrackerAct;
   if (!Act) {
     TrackerAct.reset(new TopLevelDeclTrackerAction(*AST));
     Act = TrackerAct.get();
@@ -1885,7 +1857,7 @@
     if (OwnAST && ErrAST)
       ErrAST->swap(OwnAST);
 
-    return 0;
+    return nullptr;
   }
 
   if (Persistent && !TrackerAct) {
@@ -1903,7 +1875,7 @@
     if (OwnAST && ErrAST)
       ErrAST->swap(OwnAST);
 
-    return 0;
+    return nullptr;
   }
 
   // Steal the created target, context, and preprocessor.
@@ -1912,7 +1884,7 @@
   Act->EndSourceFile();
 
   if (OwnAST)
-    return OwnAST.take();
+    return OwnAST.release();
   else
     return AST;
 }
@@ -1926,7 +1898,7 @@
   Invocation->getFrontendOpts().DisableFree = false;
   ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts());
 
-  llvm::MemoryBuffer *OverrideMainBuffer = 0;
+  llvm::MemoryBuffer *OverrideMainBuffer = nullptr;
   if (PrecompilePreamble) {
     PreambleRebuildCounter = 2;
     OverrideMainBuffer
@@ -1943,19 +1915,14 @@
   return Parse(OverrideMainBuffer);
 }
 
-ASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI,
-                              IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
-                                             bool OnlyLocalDecls,
-                                             bool CaptureDiagnostics,
-                                             bool PrecompilePreamble,
-                                             TranslationUnitKind TUKind,
-                                             bool CacheCodeCompletionResults,
-                                    bool IncludeBriefCommentsInCodeCompletion,
-                                             bool UserFilesAreVolatile) {
+std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation(
+    CompilerInvocation *CI, IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
+    bool OnlyLocalDecls, bool CaptureDiagnostics, bool PrecompilePreamble,
+    TranslationUnitKind TUKind, bool CacheCodeCompletionResults,
+    bool IncludeBriefCommentsInCodeCompletion, bool UserFilesAreVolatile) {
   // Create the AST unit.
-  OwningPtr<ASTUnit> AST;
-  AST.reset(new ASTUnit(false));
-  ConfigureDiags(Diags, 0, 0, *AST, CaptureDiagnostics);
+  std::unique_ptr<ASTUnit> AST(new ASTUnit(false));
+  ConfigureDiags(Diags, nullptr, nullptr, *AST, CaptureDiagnostics);
   AST->Diagnostics = Diags;
   AST->OnlyLocalDecls = OnlyLocalDecls;
   AST->CaptureDiagnostics = CaptureDiagnostics;
@@ -1965,7 +1932,11 @@
     = IncludeBriefCommentsInCodeCompletion;
   AST->Invocation = CI;
   AST->FileSystemOpts = CI->getFileSystemOpts();
-  AST->FileMgr = new FileManager(AST->FileSystemOpts);
+  IntrusiveRefCntPtr<vfs::FileSystem> VFS =
+      createVFSFromCompilerInvocation(*CI, *Diags);
+  if (!VFS)
+    return nullptr;
+  AST->FileMgr = new FileManager(AST->FileSystemOpts, VFS);
   AST->UserFilesAreVolatile = UserFilesAreVolatile;
   
   // Recover resources if we crash before exiting this method.
@@ -1973,30 +1944,24 @@
     ASTUnitCleanup(AST.get());
   llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
     llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
-    DiagCleanup(Diags.getPtr());
+    DiagCleanup(Diags.get());
 
-  return AST->LoadFromCompilerInvocation(PrecompilePreamble)? 0 : AST.take();
+  if (AST->LoadFromCompilerInvocation(PrecompilePreamble))
+    return nullptr;
+  return AST;
 }
 
-ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin,
-                                      const char **ArgEnd,
-                                    IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
-                                      StringRef ResourceFilesPath,
-                                      bool OnlyLocalDecls,
-                                      bool CaptureDiagnostics,
-                                      RemappedFile *RemappedFiles,
-                                      unsigned NumRemappedFiles,
-                                      bool RemappedFilesKeepOriginalName,
-                                      bool PrecompilePreamble,
-                                      TranslationUnitKind TUKind,
-                                      bool CacheCodeCompletionResults,
-                                      bool IncludeBriefCommentsInCodeCompletion,
-                                      bool AllowPCHWithCompilerErrors,
-                                      bool SkipFunctionBodies,
-                                      bool UserFilesAreVolatile,
-                                      bool ForSerialization,
-                                      OwningPtr<ASTUnit> *ErrAST) {
-  if (!Diags.getPtr()) {
+ASTUnit *ASTUnit::LoadFromCommandLine(
+    const char **ArgBegin, const char **ArgEnd,
+    IntrusiveRefCntPtr<DiagnosticsEngine> Diags, StringRef ResourceFilesPath,
+    bool OnlyLocalDecls, bool CaptureDiagnostics,
+    ArrayRef<RemappedFile> RemappedFiles, bool RemappedFilesKeepOriginalName,
+    bool PrecompilePreamble, TranslationUnitKind TUKind,
+    bool CacheCodeCompletionResults, bool IncludeBriefCommentsInCodeCompletion,
+    bool AllowPCHWithCompilerErrors, bool SkipFunctionBodies,
+    bool UserFilesAreVolatile, bool ForSerialization,
+    std::unique_ptr<ASTUnit> *ErrAST) {
+  if (!Diags.get()) {
     // No diagnostics engine was provided, so create our own diagnostics object
     // with the default options.
     Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions());
@@ -2015,19 +1980,13 @@
                                            llvm::makeArrayRef(ArgBegin, ArgEnd),
                                            Diags);
     if (!CI)
-      return 0;
+      return nullptr;
   }
 
   // Override any files that need remapping
-  for (unsigned I = 0; I != NumRemappedFiles; ++I) {
-    FilenameOrMemBuf fileOrBuf = RemappedFiles[I].second;
-    if (const llvm::MemoryBuffer *
-            memBuf = fileOrBuf.dyn_cast<const llvm::MemoryBuffer *>()) {
-      CI->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first, memBuf);
-    } else {
-      const char *fname = fileOrBuf.get<const char *>();
-      CI->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first, fname);
-    }
+  for (unsigned I = 0, N = RemappedFiles.size(); I != N; ++I) {
+    CI->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first,
+                                              RemappedFiles[I].second);
   }
   PreprocessorOptions &PPOpts = CI->getPreprocessorOpts();
   PPOpts.RemappedFilesKeepOriginalName = RemappedFilesKeepOriginalName;
@@ -2039,13 +1998,17 @@
   CI->getFrontendOpts().SkipFunctionBodies = SkipFunctionBodies;
 
   // Create the AST unit.
-  OwningPtr<ASTUnit> AST;
+  std::unique_ptr<ASTUnit> AST;
   AST.reset(new ASTUnit(false));
   ConfigureDiags(Diags, ArgBegin, ArgEnd, *AST, CaptureDiagnostics);
   AST->Diagnostics = Diags;
-  Diags = 0; // Zero out now to ease cleanup during crash recovery.
+  Diags = nullptr; // Zero out now to ease cleanup during crash recovery.
   AST->FileSystemOpts = CI->getFileSystemOpts();
-  AST->FileMgr = new FileManager(AST->FileSystemOpts);
+  IntrusiveRefCntPtr<vfs::FileSystem> VFS =
+      createVFSFromCompilerInvocation(*CI, *Diags);
+  if (!VFS)
+    return nullptr;
+  AST->FileMgr = new FileManager(AST->FileSystemOpts, VFS);
   AST->OnlyLocalDecls = OnlyLocalDecls;
   AST->CaptureDiagnostics = CaptureDiagnostics;
   AST->TUKind = TUKind;
@@ -2058,8 +2021,8 @@
   AST->Invocation = CI;
   if (ForSerialization)
     AST->WriterData.reset(new ASTWriterData());
-  CI = 0; // Zero out now to ease cleanup during crash recovery.
-  
+  CI = nullptr; // Zero out now to ease cleanup during crash recovery.
+
   // Recover resources if we crash before exiting this method.
   llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
     ASTUnitCleanup(AST.get());
@@ -2071,13 +2034,13 @@
       AST->StoredDiagnostics.swap(AST->FailedParseDiagnostics);
       ErrAST->swap(AST);
     }
-    return 0;
+    return nullptr;
   }
 
-  return AST.take();
+  return AST.release();
 }
 
-bool ASTUnit::Reparse(RemappedFile *RemappedFiles, unsigned NumRemappedFiles) {
+bool ASTUnit::Reparse(ArrayRef<RemappedFile> RemappedFiles) {
   if (!Invocation)
     return true;
 
@@ -2088,30 +2051,18 @@
 
   // Remap files.
   PreprocessorOptions &PPOpts = Invocation->getPreprocessorOpts();
-  for (PreprocessorOptions::remapped_file_buffer_iterator 
-         R = PPOpts.remapped_file_buffer_begin(),
-         REnd = PPOpts.remapped_file_buffer_end();
-       R != REnd; 
-       ++R) {
-    delete R->second;
-  }
+  for (const auto &RB : PPOpts.RemappedFileBuffers)
+    delete RB.second;
+
   Invocation->getPreprocessorOpts().clearRemappedFiles();
-  for (unsigned I = 0; I != NumRemappedFiles; ++I) {
-    FilenameOrMemBuf fileOrBuf = RemappedFiles[I].second;
-    if (const llvm::MemoryBuffer *
-            memBuf = fileOrBuf.dyn_cast<const llvm::MemoryBuffer *>()) {
-      Invocation->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first,
-                                                        memBuf);
-    } else {
-      const char *fname = fileOrBuf.get<const char *>();
-      Invocation->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first,
-                                                        fname);
-    }
+  for (unsigned I = 0, N = RemappedFiles.size(); I != N; ++I) {
+    Invocation->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first,
+                                                      RemappedFiles[I].second);
   }
-  
+
   // If we have a preamble file lying around, or if we might try to
   // build a precompiled preamble, do so now.
-  llvm::MemoryBuffer *OverrideMainBuffer = 0;
+  llvm::MemoryBuffer *OverrideMainBuffer = nullptr;
   if (!getPreambleFile(this).empty() || PreambleRebuildCounter > 0)
     OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(*Invocation);
     
@@ -2178,23 +2129,22 @@
                        |  (1LL << CodeCompletionContext::CCC_UnionTag)
                        |  (1LL << CodeCompletionContext::CCC_ClassOrStructTag);
     }
-    
-    virtual void ProcessCodeCompleteResults(Sema &S, 
-                                            CodeCompletionContext Context,
-                                            CodeCompletionResult *Results,
-                                            unsigned NumResults);
-    
-    virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
-                                           OverloadCandidate *Candidates,
-                                           unsigned NumCandidates) { 
+
+    void ProcessCodeCompleteResults(Sema &S, CodeCompletionContext Context,
+                                    CodeCompletionResult *Results,
+                                    unsigned NumResults) override;
+
+    void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
+                                   OverloadCandidate *Candidates,
+                                   unsigned NumCandidates) override {
       Next.ProcessOverloadCandidates(S, CurrentArg, Candidates, NumCandidates);
     }
-    
-    virtual CodeCompletionAllocator &getAllocator() {
+
+    CodeCompletionAllocator &getAllocator() override {
       return Next.getAllocator();
     }
 
-    virtual CodeCompletionTUInfo &getCodeCompletionTUInfo() {
+    CodeCompletionTUInfo &getCodeCompletionTUInfo() override {
       return Next.getCodeCompletionTUInfo();
     }
   };
@@ -2378,8 +2328,7 @@
 
 
 void ASTUnit::CodeComplete(StringRef File, unsigned Line, unsigned Column,
-                           RemappedFile *RemappedFiles, 
-                           unsigned NumRemappedFiles,
+                           ArrayRef<RemappedFile> RemappedFiles,
                            bool IncludeMacros, 
                            bool IncludeCodePatterns,
                            bool IncludeBriefComments,
@@ -2417,7 +2366,7 @@
   // Set the language options appropriately.
   LangOpts = *CCInvocation->getLangOpts();
 
-  OwningPtr<CompilerInstance> Clang(new CompilerInstance());
+  std::unique_ptr<CompilerInstance> Clang(new CompilerInstance());
 
   // Recover resources if we crash before exiting this method.
   llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
@@ -2434,10 +2383,10 @@
   ProcessWarningOptions(Diag, CCInvocation->getDiagnosticOpts());
   
   // Create the target instance.
-  Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(),
-                                                &Clang->getTargetOpts()));
+  Clang->setTarget(TargetInfo::CreateTargetInfo(
+      Clang->getDiagnostics(), Clang->getInvocation().TargetOpts));
   if (!Clang->hasTarget()) {
-    Clang->setInvocation(0);
+    Clang->setInvocation(nullptr);
     return;
   }
   
@@ -2445,7 +2394,7 @@
   //
   // FIXME: We shouldn't need to do this, the target should be immutable once
   // created. This complexity should be lifted elsewhere.
-  Clang->getTarget().setForcedLangOptions(Clang->getLangOpts());
+  Clang->getTarget().adjust(Clang->getLangOpts());
   
   assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
          "Invocation must have exactly one source file!");
@@ -2462,18 +2411,12 @@
   // Remap files.
   PreprocessorOpts.clearRemappedFiles();
   PreprocessorOpts.RetainRemappedFileBuffers = true;
-  for (unsigned I = 0; I != NumRemappedFiles; ++I) {
-    FilenameOrMemBuf fileOrBuf = RemappedFiles[I].second;
-    if (const llvm::MemoryBuffer *
-            memBuf = fileOrBuf.dyn_cast<const llvm::MemoryBuffer *>()) {
-      PreprocessorOpts.addRemappedFile(RemappedFiles[I].first, memBuf);
-      OwnedBuffers.push_back(memBuf);
-    } else {
-      const char *fname = fileOrBuf.get<const char *>();
-      PreprocessorOpts.addRemappedFile(RemappedFiles[I].first, fname);
-    }
+  for (unsigned I = 0, N = RemappedFiles.size(); I != N; ++I) {
+    PreprocessorOpts.addRemappedFile(RemappedFiles[I].first,
+                                     RemappedFiles[I].second);
+    OwnedBuffers.push_back(RemappedFiles[I].second);
   }
-  
+
   // Use the code completion consumer we were given, but adding any cached
   // code-completion results.
   AugmentedCodeCompleteConsumer *AugmentedConsumer
@@ -2484,7 +2427,7 @@
   // the use of the precompiled preamble if we're if the completion
   // point is within the main file, after the end of the precompiled
   // preamble.
-  llvm::MemoryBuffer *OverrideMainBuffer = 0;
+  llvm::MemoryBuffer *OverrideMainBuffer = nullptr;
   if (!getPreambleFile(this).empty()) {
     std::string CompleteFilePath(File);
     llvm::sys::fs::UniqueID CompleteFileID;
@@ -2520,8 +2463,8 @@
   // Disable the preprocessing record if modules are not enabled.
   if (!Clang->getLangOpts().Modules)
     PreprocessorOpts.DetailedRecord = false;
-  
-  OwningPtr<SyntaxOnlyAction> Act;
+
+  std::unique_ptr<SyntaxOnlyAction> Act;
   Act.reset(new SyntaxOnlyAction);
   if (Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0])) {
     Act->Execute();
@@ -2554,8 +2497,7 @@
   }
 
   if (llvm::sys::fs::rename(TempPath.str(), File)) {
-    bool exists;
-    llvm::sys::fs::remove(TempPath.str(), exists);
+    llvm::sys::fs::remove(TempPath.str());
     return true;
   }
 
@@ -2567,7 +2509,7 @@
                           Sema &S,
                           bool hasErrors,
                           raw_ostream &OS) {
-  Writer.WriteAST(S, std::string(), 0, "", hasErrors);
+  Writer.WriteAST(S, std::string(), nullptr, "", hasErrors);
 
   // Write the generated bitstream to "Out".
   if (!Buffer.empty())
@@ -2591,68 +2533,57 @@
 
 typedef ContinuousRangeMap<unsigned, int, 2> SLocRemap;
 
-static void TranslateSLoc(SourceLocation &L, SLocRemap &Remap) {
-  unsigned Raw = L.getRawEncoding();
-  const unsigned MacroBit = 1U << 31;
-  L = SourceLocation::getFromRawEncoding((Raw & MacroBit) |
-      ((Raw & ~MacroBit) + Remap.find(Raw & ~MacroBit)->second));
-}
-
 void ASTUnit::TranslateStoredDiagnostics(
-                          ASTReader *MMan,
-                          StringRef ModName,
+                          FileManager &FileMgr,
                           SourceManager &SrcMgr,
-                          const SmallVectorImpl<StoredDiagnostic> &Diags,
+                          const SmallVectorImpl<StandaloneDiagnostic> &Diags,
                           SmallVectorImpl<StoredDiagnostic> &Out) {
-  // The stored diagnostic has the old source manager in it; update
-  // the locations to refer into the new source manager. We also need to remap
-  // all the locations to the new view. This includes the diag location, any
-  // associated source ranges, and the source ranges of associated fix-its.
+  // Map the standalone diagnostic into the new source manager. We also need to
+  // remap all the locations to the new view. This includes the diag location,
+  // any associated source ranges, and the source ranges of associated fix-its.
   // FIXME: There should be a cleaner way to do this.
 
   SmallVector<StoredDiagnostic, 4> Result;
   Result.reserve(Diags.size());
-  assert(MMan && "Don't have a module manager");
-  serialization::ModuleFile *Mod = MMan->ModuleMgr.lookup(ModName);
-  assert(Mod && "Don't have preamble module");
-  SLocRemap &Remap = Mod->SLocRemap;
   for (unsigned I = 0, N = Diags.size(); I != N; ++I) {
     // Rebuild the StoredDiagnostic.
-    const StoredDiagnostic &SD = Diags[I];
-    SourceLocation L = SD.getLocation();
-    TranslateSLoc(L, Remap);
+    const StandaloneDiagnostic &SD = Diags[I];
+    if (SD.Filename.empty())
+      continue;
+    const FileEntry *FE = FileMgr.getFile(SD.Filename);
+    if (!FE)
+      continue;
+    FileID FID = SrcMgr.translateFile(FE);
+    SourceLocation FileLoc = SrcMgr.getLocForStartOfFile(FID);
+    if (FileLoc.isInvalid())
+      continue;
+    SourceLocation L = FileLoc.getLocWithOffset(SD.LocOffset);
     FullSourceLoc Loc(L, SrcMgr);
 
     SmallVector<CharSourceRange, 4> Ranges;
-    Ranges.reserve(SD.range_size());
-    for (StoredDiagnostic::range_iterator I = SD.range_begin(),
-                                          E = SD.range_end();
-         I != E; ++I) {
-      SourceLocation BL = I->getBegin();
-      TranslateSLoc(BL, Remap);
-      SourceLocation EL = I->getEnd();
-      TranslateSLoc(EL, Remap);
-      Ranges.push_back(CharSourceRange(SourceRange(BL, EL), I->isTokenRange()));
+    Ranges.reserve(SD.Ranges.size());
+    for (std::vector<std::pair<unsigned, unsigned> >::const_iterator
+           I = SD.Ranges.begin(), E = SD.Ranges.end(); I != E; ++I) {
+      SourceLocation BL = FileLoc.getLocWithOffset((*I).first);
+      SourceLocation EL = FileLoc.getLocWithOffset((*I).second);
+      Ranges.push_back(CharSourceRange::getCharRange(BL, EL));
     }
 
     SmallVector<FixItHint, 2> FixIts;
-    FixIts.reserve(SD.fixit_size());
-    for (StoredDiagnostic::fixit_iterator I = SD.fixit_begin(),
-                                          E = SD.fixit_end();
+    FixIts.reserve(SD.FixIts.size());
+    for (std::vector<StandaloneFixIt>::const_iterator
+           I = SD.FixIts.begin(), E = SD.FixIts.end();
          I != E; ++I) {
       FixIts.push_back(FixItHint());
       FixItHint &FH = FixIts.back();
       FH.CodeToInsert = I->CodeToInsert;
-      SourceLocation BL = I->RemoveRange.getBegin();
-      TranslateSLoc(BL, Remap);
-      SourceLocation EL = I->RemoveRange.getEnd();
-      TranslateSLoc(EL, Remap);
-      FH.RemoveRange = CharSourceRange(SourceRange(BL, EL),
-                                       I->RemoveRange.isTokenRange());
+      SourceLocation BL = FileLoc.getLocWithOffset(I->RemoveRange.first);
+      SourceLocation EL = FileLoc.getLocWithOffset(I->RemoveRange.second);
+      FH.RemoveRange = CharSourceRange::getCharRange(BL, EL);
     }
 
-    Result.push_back(StoredDiagnostic(SD.getLevel(), SD.getID(), 
-                                      SD.getMessage(), Loc, Ranges, FixIts));
+    Result.push_back(StoredDiagnostic(SD.Level, SD.ID, 
+                                      SD.Message, Loc, Ranges, FixIts));
   }
   Result.swap(Out);
 }
@@ -2677,7 +2608,7 @@
   assert(SM.isLocalSourceLocation(FileLoc));
   FileID FID;
   unsigned Offset;
-  llvm::tie(FID, Offset) = SM.getDecomposedLoc(FileLoc);
+  std::tie(FID, Offset) = SM.getDecomposedLoc(FileLoc);
   if (FID.isInvalid())
     return;
 
@@ -2719,7 +2650,8 @@
 
   LocDeclsTy::iterator BeginIt =
       std::lower_bound(LocDecls.begin(), LocDecls.end(),
-                       std::make_pair(Offset, (Decl *)0), llvm::less_first());
+                       std::make_pair(Offset, (Decl *)nullptr),
+                       llvm::less_first());
   if (BeginIt != LocDecls.begin())
     --BeginIt;
 
@@ -2732,7 +2664,7 @@
 
   LocDeclsTy::iterator EndIt = std::upper_bound(
       LocDecls.begin(), LocDecls.end(),
-      std::make_pair(Offset + Length, (Decl *)0), llvm::less_first());
+      std::make_pair(Offset + Length, (Decl *)nullptr), llvm::less_first());
   if (EndIt != LocDecls.end())
     ++EndIt;
   
@@ -2860,7 +2792,7 @@
     serialization::ModuleFile &
       Mod = Reader->getModuleManager().getPrimaryModule();
     ASTReader::ModuleDeclIterator MDI, MDE;
-    llvm::tie(MDI, MDE) = Reader->getModuleFileLevelDecls(Mod);
+    std::tie(MDI, MDE) = Reader->getModuleFileLevelDecls(Mod);
     for (; MDI != MDE; ++MDI) {
       if (!Fn(context, *MDI))
         return false;
@@ -2882,7 +2814,7 @@
 namespace {
 struct PCHLocatorInfo {
   serialization::ModuleFile *Mod;
-  PCHLocatorInfo() : Mod(0) {}
+  PCHLocatorInfo() : Mod(nullptr) {}
 };
 }
 
@@ -2905,14 +2837,14 @@
 
 const FileEntry *ASTUnit::getPCHFile() {
   if (!Reader)
-    return 0;
+    return nullptr;
 
   PCHLocatorInfo Info;
   Reader->getModuleManager().visit(PCHLocator, &Info);
   if (Info.Mod)
     return Info.Mod->File;
 
-  return 0;
+  return nullptr;
 }
 
 bool ASTUnit::isModuleFile() {
@@ -2953,7 +2885,7 @@
 
 #else // NDEBUG
 
-ASTUnit::ConcurrencyState::ConcurrencyState() {}
+ASTUnit::ConcurrencyState::ConcurrencyState() { Mutex = 0; }
 ASTUnit::ConcurrencyState::~ConcurrencyState() {}
 void ASTUnit::ConcurrencyState::start() {}
 void ASTUnit::ConcurrencyState::finish() {}
diff --git a/lib/Frontend/CMakeLists.txt b/lib/Frontend/CMakeLists.txt
index 0566d54..403cc42 100644
--- a/lib/Frontend/CMakeLists.txt
+++ b/lib/Frontend/CMakeLists.txt
@@ -1,3 +1,10 @@
+add_subdirectory(Rewrite)
+
+set(LLVM_LINK_COMPONENTS
+  Option
+  Support
+  )
+
 add_clang_library(clangFrontend
   ASTConsumers.cpp
   ASTMerge.cpp
@@ -20,6 +27,7 @@
   LangStandards.cpp
   LayoutOverrideSource.cpp
   LogDiagnosticPrinter.cpp
+  ModuleDependencyCollector.cpp
   MultiplexConsumer.cpp
   PrintPreprocessedOutput.cpp
   SerializedDiagnosticPrinter.cpp
@@ -27,26 +35,11 @@
   TextDiagnosticBuffer.cpp
   TextDiagnosticPrinter.cpp
   VerifyDiagnosticConsumer.cpp
-  Warnings.cpp
-  )
 
-add_dependencies(clangFrontend
-  ClangAttrClasses
-  ClangAttrList
-  ClangAttrParsedAttrList
-  ClangCommentNodes
-  ClangDeclNodes
-  ClangDiagnosticAST
-  ClangDiagnosticCommon
-  ClangDiagnosticDriver
-  ClangDiagnosticFrontend
-  ClangDiagnosticLex
-  ClangDiagnosticSema
+  DEPENDS
   ClangDriverOptions
-  ClangStmtNodes
-  )
 
-target_link_libraries(clangFrontend
+  LINK_LIBS
   clangAST
   clangBasic
   clangDriver
diff --git a/lib/Frontend/CacheTokens.cpp b/lib/Frontend/CacheTokens.cpp
index 0c30b04..14f7027 100644
--- a/lib/Frontend/CacheTokens.cpp
+++ b/lib/Frontend/CacheTokens.cpp
@@ -17,14 +17,15 @@
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/FileSystemStatCache.h"
 #include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/OnDiskHashTable.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Lex/Lexer.h"
 #include "clang/Lex/Preprocessor.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringMap.h"
+#include "llvm/Support/EndianStream.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/OnDiskHashTable.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
 
@@ -34,12 +35,13 @@
 #endif
 
 using namespace clang;
-using namespace clang::io;
 
 //===----------------------------------------------------------------------===//
 // PTH-specific stuff.
 //===----------------------------------------------------------------------===//
 
+typedef uint32_t Offset;
+
 namespace {
 class PTHEntry {
   Offset TokenData, PPCondData;
@@ -61,13 +63,13 @@
   FileData *Data;
 
 public:
-  PTHEntryKeyVariant(const FileEntry *fe) : FE(fe), Kind(IsFE), Data(0) {}
+  PTHEntryKeyVariant(const FileEntry *fe) : FE(fe), Kind(IsFE), Data(nullptr) {}
 
   PTHEntryKeyVariant(FileData *Data, const char *path)
       : Path(path), Kind(IsDE), Data(new FileData(*Data)) {}
 
   explicit PTHEntryKeyVariant(const char *path)
-      : Path(path), Kind(IsNoExist), Data(0) {}
+      : Path(path), Kind(IsNoExist), Data(nullptr) {}
 
   bool isFile() const { return Kind == IsFE; }
 
@@ -78,21 +80,23 @@
   unsigned getKind() const { return (unsigned) Kind; }
 
   void EmitData(raw_ostream& Out) {
+    using namespace llvm::support;
+    endian::Writer<little> LE(Out);
     switch (Kind) {
     case IsFE: {
       // Emit stat information.
       llvm::sys::fs::UniqueID UID = FE->getUniqueID();
-      ::Emit64(Out, UID.getFile());
-      ::Emit64(Out, UID.getDevice());
-      ::Emit64(Out, FE->getModificationTime());
-      ::Emit64(Out, FE->getSize());
+      LE.write<uint64_t>(UID.getFile());
+      LE.write<uint64_t>(UID.getDevice());
+      LE.write<uint64_t>(FE->getModificationTime());
+      LE.write<uint64_t>(FE->getSize());
     } break;
     case IsDE:
       // Emit stat information.
-      ::Emit64(Out, Data->UniqueID.getFile());
-      ::Emit64(Out, Data->UniqueID.getDevice());
-      ::Emit64(Out, Data->ModTime);
-      ::Emit64(Out, Data->Size);
+      LE.write<uint64_t>(Data->UniqueID.getFile());
+      LE.write<uint64_t>(Data->UniqueID.getDevice());
+      LE.write<uint64_t>(Data->ModTime);
+      LE.write<uint64_t>(Data->Size);
       delete Data;
       break;
     default:
@@ -113,39 +117,46 @@
   typedef PTHEntry data_type;
   typedef const PTHEntry& data_type_ref;
 
-  static unsigned ComputeHash(PTHEntryKeyVariant V) {
+  typedef unsigned hash_value_type;
+  typedef unsigned offset_type;
+
+  static hash_value_type ComputeHash(PTHEntryKeyVariant V) {
     return llvm::HashString(V.getString());
   }
 
   static std::pair<unsigned,unsigned>
   EmitKeyDataLength(raw_ostream& Out, PTHEntryKeyVariant V,
                     const PTHEntry& E) {
+    using namespace llvm::support;
+    endian::Writer<little> LE(Out);
 
     unsigned n = V.getString().size() + 1 + 1;
-    ::Emit16(Out, n);
+    LE.write<uint16_t>(n);
 
     unsigned m = V.getRepresentationLength() + (V.isFile() ? 4 + 4 : 0);
-    ::Emit8(Out, m);
+    LE.write<uint8_t>(m);
 
     return std::make_pair(n, m);
   }
 
   static void EmitKey(raw_ostream& Out, PTHEntryKeyVariant V, unsigned n){
+    using namespace llvm::support;
     // Emit the entry kind.
-    ::Emit8(Out, (unsigned) V.getKind());
+    endian::Writer<little>(Out).write<uint8_t>((unsigned)V.getKind());
     // Emit the string.
     Out.write(V.getString().data(), n - 1);
   }
 
   static void EmitData(raw_ostream& Out, PTHEntryKeyVariant V,
                        const PTHEntry& E, unsigned) {
-
+    using namespace llvm::support;
+    endian::Writer<little> LE(Out);
 
     // For file entries emit the offsets into the PTH file for token data
     // and the preprocessor blocks table.
     if (V.isFile()) {
-      ::Emit32(Out, E.getTokenOffset());
-      ::Emit32(Out, E.getPPCondTableOffset());
+      LE.write<uint32_t>(E.getTokenOffset());
+      LE.write<uint32_t>(E.getPPCondTableOffset());
     }
 
     // Emit any other data associated with the key (i.e., stat information).
@@ -164,7 +175,7 @@
 };
 } // end anonymous namespace
 
-typedef OnDiskChainedHashTableGenerator<FileEntryPTHEntryInfo> PTHMap;
+typedef llvm::OnDiskChainedHashTableGenerator<FileEntryPTHEntryInfo> PTHMap;
 
 namespace {
 class PTHWriter {
@@ -186,18 +197,28 @@
   /// Emit a token to the PTH file.
   void EmitToken(const Token& T);
 
-  void Emit8(uint32_t V) { ::Emit8(Out, V); }
+  void Emit8(uint32_t V) {
+    using namespace llvm::support;
+    endian::Writer<little>(Out).write<uint8_t>(V);
+  }
 
-  void Emit16(uint32_t V) { ::Emit16(Out, V); }
+  void Emit16(uint32_t V) {
+    using namespace llvm::support;
+    endian::Writer<little>(Out).write<uint16_t>(V);
+  }
 
-  void Emit32(uint32_t V) { ::Emit32(Out, V); }
+  void Emit32(uint32_t V) {
+    using namespace llvm::support;
+    endian::Writer<little>(Out).write<uint32_t>(V);
+  }
 
   void EmitBuf(const char *Ptr, unsigned NumBytes) {
     Out.write(Ptr, NumBytes);
   }
 
   void EmitString(StringRef V) {
-    ::Emit16(Out, V.size());
+    using namespace llvm::support;
+    endian::Writer<little>(Out).write<uint16_t>(V.size());
     EmitBuf(V.data(), V.size());
   }
 
@@ -270,8 +291,11 @@
 PTHEntry PTHWriter::LexTokens(Lexer& L) {
   // Pad 0's so that we emit tokens to a 4-byte alignment.
   // This speed up reading them back in.
-  Pad(Out, 4);
-  Offset TokenOff = (Offset) Out.tell();
+  using namespace llvm::support;
+  endian::Writer<little> LE(Out);
+  uint32_t TokenOff = Out.tell();
+  for (uint64_t N = llvm::OffsetToAlignment(TokenOff, 4); N; --N, ++TokenOff)
+    LE.write<uint8_t>(0);
 
   // Keep track of matching '#if' ... '#endif'.
   typedef std::vector<std::pair<Offset, unsigned> > PPCondTable;
@@ -293,7 +317,7 @@
       Token Tmp = Tok;
       Tmp.setKind(tok::eod);
       Tmp.clearFlag(Token::StartOfLine);
-      Tmp.setIdentifierInfo(0);
+      Tmp.setIdentifierInfo(nullptr);
       EmitToken(Tmp);
       ParsingPreprocessorDirective = false;
     }
@@ -516,8 +540,9 @@
   ~StatListener() {}
 
   LookupResult getStat(const char *Path, FileData &Data, bool isFile,
-                       int *FileDescriptor) {
-    LookupResult Result = statChained(Path, Data, isFile, FileDescriptor);
+                       std::unique_ptr<vfs::File> *F,
+                       vfs::FileSystem &FS) override {
+    LookupResult Result = statChained(Path, Data, isFile, F, FS);
 
     if (Result == CacheMissing) // Failed 'stat'.
       PM.insert(PTHEntryKeyVariant(Path), PTHEntry());
@@ -578,14 +603,18 @@
   typedef uint32_t  data_type;
   typedef data_type data_type_ref;
 
-  static unsigned ComputeHash(PTHIdKey* key) {
+  typedef unsigned hash_value_type;
+  typedef unsigned offset_type;
+
+  static hash_value_type ComputeHash(PTHIdKey* key) {
     return llvm::HashString(key->II->getName());
   }
 
   static std::pair<unsigned,unsigned>
   EmitKeyDataLength(raw_ostream& Out, const PTHIdKey* key, uint32_t) {
+    using namespace llvm::support;
     unsigned n = key->II->getLength() + 1;
-    ::Emit16(Out, n);
+    endian::Writer<little>(Out).write<uint16_t>(n);
     return std::make_pair(n, sizeof(uint32_t));
   }
 
@@ -598,7 +627,8 @@
 
   static void EmitData(raw_ostream& Out, PTHIdKey*, uint32_t pID,
                        unsigned) {
-    ::Emit32(Out, pID);
+    using namespace llvm::support;
+    endian::Writer<little>(Out).write<uint32_t>(pID);
   }
 };
 } // end anonymous namespace
@@ -617,7 +647,7 @@
   PTHIdKey *IIDMap = (PTHIdKey*)calloc(idcount, sizeof(PTHIdKey));
 
   // Create the hashtable.
-  OnDiskChainedHashTableGenerator<PTHIdentifierTableTrait> IIOffMap;
+  llvm::OnDiskChainedHashTableGenerator<PTHIdentifierTableTrait> IIOffMap;
 
   // Generate mapping from persistent IDs -> IdentifierInfo*.
   for (IDMap::iterator I = IM.begin(), E = IM.end(); I != E; ++I) {
diff --git a/lib/Frontend/ChainedIncludesSource.cpp b/lib/Frontend/ChainedIncludesSource.cpp
index 442177e..e6e73ac 100644
--- a/lib/Frontend/ChainedIncludesSource.cpp
+++ b/lib/Frontend/ChainedIncludesSource.cpp
@@ -12,7 +12,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "clang/Frontend/ChainedIncludesSource.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Frontend/ASTUnit.h"
 #include "clang/Frontend/CompilerInstance.h"
@@ -25,13 +24,61 @@
 
 using namespace clang;
 
-static ASTReader *createASTReader(CompilerInstance &CI,
-                             StringRef pchFile,
-                             SmallVectorImpl<llvm::MemoryBuffer *> &memBufs,
-                             SmallVectorImpl<std::string> &bufNames,
-                             ASTDeserializationListener *deserialListener = 0) {
+namespace {
+class ChainedIncludesSource : public ExternalSemaSource {
+public:
+  virtual ~ChainedIncludesSource();
+
+  ExternalSemaSource &getFinalReader() const { return *FinalReader; }
+
+  std::vector<CompilerInstance *> CIs;
+  IntrusiveRefCntPtr<ExternalSemaSource> FinalReader;
+
+protected:
+  //===----------------------------------------------------------------------===//
+  // ExternalASTSource interface.
+  //===----------------------------------------------------------------------===//
+
+  Decl *GetExternalDecl(uint32_t ID) override;
+  Selector GetExternalSelector(uint32_t ID) override;
+  uint32_t GetNumExternalSelectors() override;
+  Stmt *GetExternalDeclStmt(uint64_t Offset) override;
+  CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset) override;
+  bool FindExternalVisibleDeclsByName(const DeclContext *DC,
+                                      DeclarationName Name) override;
+  ExternalLoadResult
+  FindExternalLexicalDecls(const DeclContext *DC,
+                           bool (*isKindWeWant)(Decl::Kind),
+                           SmallVectorImpl<Decl *> &Result) override;
+  void CompleteType(TagDecl *Tag) override;
+  void CompleteType(ObjCInterfaceDecl *Class) override;
+  void StartedDeserializing() override;
+  void FinishedDeserializing() override;
+  void StartTranslationUnit(ASTConsumer *Consumer) override;
+  void PrintStats() override;
+
+  /// Return the amount of memory used by memory buffers, breaking down
+  /// by heap-backed versus mmap'ed memory.
+  void getMemoryBufferSizes(MemoryBufferSizes &sizes) const override;
+
+  //===----------------------------------------------------------------------===//
+  // ExternalSemaSource interface.
+  //===----------------------------------------------------------------------===//
+
+  void InitializeSema(Sema &S) override;
+  void ForgetSema() override;
+  void ReadMethodPool(Selector Sel) override;
+  bool LookupUnqualified(LookupResult &R, Scope *S) override;
+};
+}
+
+static ASTReader *
+createASTReader(CompilerInstance &CI, StringRef pchFile,
+                SmallVectorImpl<llvm::MemoryBuffer *> &memBufs,
+                SmallVectorImpl<std::string> &bufNames,
+                ASTDeserializationListener *deserialListener = nullptr) {
   Preprocessor &PP = CI.getPreprocessor();
-  OwningPtr<ASTReader> Reader;
+  std::unique_ptr<ASTReader> Reader;
   Reader.reset(new ASTReader(PP, CI.getASTContext(), /*isysroot=*/"",
                              /*DisableValidation=*/true));
   for (unsigned ti = 0; ti < bufNames.size(); ++ti) {
@@ -44,7 +91,7 @@
   case ASTReader::Success:
     // Set the predefines buffer as suggested by the PCH reader.
     PP.setPredefines(Reader->getSuggestedPredefines());
-    return Reader.take();
+    return Reader.release();
 
   case ASTReader::Failure:
   case ASTReader::Missing:
@@ -54,7 +101,7 @@
   case ASTReader::HadErrors:
     break;
   }
-  return 0;
+  return nullptr;
 }
 
 ChainedIncludesSource::~ChainedIncludesSource() {
@@ -62,12 +109,13 @@
     delete CIs[i];
 }
 
-ChainedIncludesSource *ChainedIncludesSource::create(CompilerInstance &CI) {
+IntrusiveRefCntPtr<ExternalSemaSource> clang::createChainedIncludesSource(
+    CompilerInstance &CI, IntrusiveRefCntPtr<ExternalSemaSource> &Reader) {
 
   std::vector<std::string> &includes = CI.getPreprocessorOpts().ChainedIncludes;
   assert(!includes.empty() && "No '-chain-include' in options!");
 
-  OwningPtr<ChainedIncludesSource> source(new ChainedIncludesSource());
+  IntrusiveRefCntPtr<ChainedIncludesSource> source(new ChainedIncludesSource());
   InputKind IK = CI.getFrontendOpts().Inputs[0].getKind();
 
   SmallVector<llvm::MemoryBuffer *, 4> serialBufs;
@@ -75,7 +123,7 @@
 
   for (unsigned i = 0, e = includes.size(); i != e; ++i) {
     bool firstInclude = (i == 0);
-    OwningPtr<CompilerInvocation> CInvok;
+    std::unique_ptr<CompilerInvocation> CInvok;
     CInvok.reset(new CompilerInvocation(CI.getInvocation()));
     
     CInvok->getPreprocessorOpts().ChainedIncludes.clear();
@@ -96,27 +144,27 @@
     IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
         new DiagnosticsEngine(DiagID, &CI.getDiagnosticOpts(), DiagClient));
 
-    OwningPtr<CompilerInstance> Clang(new CompilerInstance());
-    Clang->setInvocation(CInvok.take());
-    Clang->setDiagnostics(Diags.getPtr());
-    Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(),
-                                                  &Clang->getTargetOpts()));
+    std::unique_ptr<CompilerInstance> Clang(new CompilerInstance());
+    Clang->setInvocation(CInvok.release());
+    Clang->setDiagnostics(Diags.get());
+    Clang->setTarget(TargetInfo::CreateTargetInfo(
+        Clang->getDiagnostics(), Clang->getInvocation().TargetOpts));
     Clang->createFileManager();
     Clang->createSourceManager(Clang->getFileManager());
-    Clang->createPreprocessor();
+    Clang->createPreprocessor(TU_Prefix);
     Clang->getDiagnosticClient().BeginSourceFile(Clang->getLangOpts(),
                                                  &Clang->getPreprocessor());
     Clang->createASTContext();
 
     SmallVector<char, 256> serialAST;
     llvm::raw_svector_ostream OS(serialAST);
-    OwningPtr<ASTConsumer> consumer;
-    consumer.reset(new PCHGenerator(Clang->getPreprocessor(), "-", 0,
+    std::unique_ptr<ASTConsumer> consumer;
+    consumer.reset(new PCHGenerator(Clang->getPreprocessor(), "-", nullptr,
                                     /*isysroot=*/"", &OS));
     Clang->getASTContext().setASTMutationListener(
                                             consumer->GetASTMutationListener());
-    Clang->setASTConsumer(consumer.take());
-    Clang->createSema(TU_Prefix, 0);
+    Clang->setASTConsumer(consumer.release());
+    Clang->createSema(TU_Prefix, nullptr);
 
     if (firstInclude) {
       Preprocessor &PP = Clang->getPreprocessor();
@@ -125,50 +173,42 @@
     } else {
       assert(!serialBufs.empty());
       SmallVector<llvm::MemoryBuffer *, 4> bufs;
-      for (unsigned si = 0, se = serialBufs.size(); si != se; ++si) {
-        bufs.push_back(llvm::MemoryBuffer::getMemBufferCopy(
-                             StringRef(serialBufs[si]->getBufferStart(),
-                                             serialBufs[si]->getBufferSize())));
-      }
+      // TODO: Pass through the existing MemoryBuffer instances instead of
+      // allocating new ones.
+      for (auto *SB : serialBufs)
+        bufs.push_back(llvm::MemoryBuffer::getMemBuffer(SB->getBuffer()));
       std::string pchName = includes[i-1];
       llvm::raw_string_ostream os(pchName);
       os << ".pch" << i-1;
-      os.flush();
-      
-      serialBufNames.push_back(pchName);
+      serialBufNames.push_back(os.str());
 
-      OwningPtr<ExternalASTSource> Reader;
-
-      Reader.reset(createASTReader(*Clang, pchName, bufs, serialBufNames, 
-        Clang->getASTConsumer().GetASTDeserializationListener()));
+      IntrusiveRefCntPtr<ASTReader> Reader;
+      Reader = createASTReader(*Clang, pchName, bufs, serialBufNames, 
+        Clang->getASTConsumer().GetASTDeserializationListener());
       if (!Reader)
-        return 0;
-      Clang->setModuleManager(static_cast<ASTReader*>(Reader.get()));
+        return nullptr;
+      Clang->setModuleManager(Reader);
       Clang->getASTContext().setExternalSource(Reader);
     }
     
     if (!Clang->InitializeSourceManager(InputFile))
-      return 0;
+      return nullptr;
 
     ParseAST(Clang->getSema());
-    OS.flush();
     Clang->getDiagnosticClient().EndSourceFile();
-    serialBufs.push_back(
-      llvm::MemoryBuffer::getMemBufferCopy(StringRef(serialAST.data(),
-                                                           serialAST.size())));
-    source->CIs.push_back(Clang.take());
+    serialBufs.push_back(llvm::MemoryBuffer::getMemBufferCopy(OS.str()));
+    source->CIs.push_back(Clang.release());
   }
 
   assert(!serialBufs.empty());
   std::string pchName = includes.back() + ".pch-final";
   serialBufNames.push_back(pchName);
-  OwningPtr<ASTReader> Reader;
-  Reader.reset(createASTReader(CI, pchName, serialBufs, serialBufNames));
+  Reader = createASTReader(CI, pchName, serialBufs, serialBufNames);
   if (!Reader)
-    return 0;
+    return nullptr;
 
-  source->FinalReader.reset(Reader.take());
-  return source.take();
+  source->FinalReader = Reader;
+  return source;
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp
index eccb94c..6af920d 100644
--- a/lib/Frontend/CompilerInstance.cpp
+++ b/lib/Frontend/CompilerInstance.cpp
@@ -16,6 +16,7 @@
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/Version.h"
+#include "clang/Config/config.h"
 #include "clang/Frontend/ChainedDiagnosticConsumer.h"
 #include "clang/Frontend/FrontendAction.h"
 #include "clang/Frontend/FrontendActions.h"
@@ -31,9 +32,10 @@
 #include "clang/Sema/CodeCompleteConsumer.h"
 #include "clang/Sema/Sema.h"
 #include "clang/Serialization/ASTReader.h"
+#include "clang/Serialization/GlobalModuleIndex.h"
 #include "llvm/ADT/Statistic.h"
-#include "llvm/Config/config.h"
 #include "llvm/Support/CrashRecoveryContext.h"
+#include "llvm/Support/Errc.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Host.h"
 #include "llvm/Support/LockFileManager.h"
@@ -43,15 +45,17 @@
 #include "llvm/Support/Signals.h"
 #include "llvm/Support/Timer.h"
 #include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/system_error.h"
 #include <sys/stat.h>
+#include <system_error>
 #include <time.h>
 
 using namespace clang;
 
-CompilerInstance::CompilerInstance()
-  : Invocation(new CompilerInvocation()), ModuleManager(0),
-    BuildGlobalModuleIndex(false), ModuleBuildFailed(false) {
+CompilerInstance::CompilerInstance(bool BuildingModule)
+  : ModuleLoader(BuildingModule),
+    Invocation(new CompilerInvocation()), ModuleManager(nullptr),
+    BuildGlobalModuleIndex(false), HaveFullGlobalModuleIndex(false),
+    ModuleBuildFailed(false) {
 }
 
 CompilerInstance::~CompilerInstance() {
@@ -79,6 +83,10 @@
 
 void CompilerInstance::setFileManager(FileManager *Value) {
   FileMgr = Value;
+  if (Value)
+    VirtualFileSystem = Value->getVirtualFileSystem();
+  else
+    VirtualFileSystem.reset();
 }
 
 void CompilerInstance::setSourceManager(SourceManager *Value) {
@@ -100,6 +108,23 @@
 void CompilerInstance::setCodeCompletionConsumer(CodeCompleteConsumer *Value) {
   CompletionConsumer.reset(Value);
 }
+ 
+IntrusiveRefCntPtr<ASTReader> CompilerInstance::getModuleManager() const {
+  return ModuleManager;
+}
+void CompilerInstance::setModuleManager(IntrusiveRefCntPtr<ASTReader> Reader) {
+  ModuleManager = Reader;
+}
+
+std::shared_ptr<ModuleDependencyCollector>
+CompilerInstance::getModuleDepCollector() const {
+  return ModuleDepCollector;
+}
+
+void CompilerInstance::setModuleDepCollector(
+    std::shared_ptr<ModuleDependencyCollector> Collector) {
+  ModuleDepCollector = Collector;
+}
 
 // Diagnostics
 static void SetUpDiagnosticLog(DiagnosticOptions *DiagOpts,
@@ -110,9 +135,9 @@
   raw_ostream *OS = &llvm::errs();
   if (DiagOpts->DiagnosticLogFile != "-") {
     // Create the output stream.
-    llvm::raw_fd_ostream *FileOS(
-        new llvm::raw_fd_ostream(DiagOpts->DiagnosticLogFile.c_str(), ErrorInfo,
-                                 llvm::sys::fs::F_Append));
+    llvm::raw_fd_ostream *FileOS(new llvm::raw_fd_ostream(
+        DiagOpts->DiagnosticLogFile.c_str(), ErrorInfo,
+        llvm::sys::fs::F_Append | llvm::sys::fs::F_Text));
     if (!ErrorInfo.empty()) {
       Diags.Report(diag::warn_fe_cc_log_diagnostics_failure)
         << DiagOpts->DiagnosticLogFile << ErrorInfo;
@@ -136,20 +161,19 @@
                                        DiagnosticsEngine &Diags,
                                        StringRef OutputFile) {
   std::string ErrorInfo;
-  OwningPtr<llvm::raw_fd_ostream> OS;
+  std::unique_ptr<llvm::raw_fd_ostream> OS;
   OS.reset(new llvm::raw_fd_ostream(OutputFile.str().c_str(), ErrorInfo,
-                                    llvm::sys::fs::F_Binary));
+                                    llvm::sys::fs::F_None));
 
   if (!ErrorInfo.empty()) {
     Diags.Report(diag::warn_fe_serialized_diag_failure)
       << OutputFile << ErrorInfo;
     return;
   }
-  
-  DiagnosticConsumer *SerializedConsumer =
-    clang::serialized_diags::create(OS.take(), DiagOpts);
 
-  
+  DiagnosticConsumer *SerializedConsumer =
+      clang::serialized_diags::create(OS.release(), DiagOpts);
+
   Diags.setClient(new ChainedDiagnosticConsumer(Diags.takeClient(),
                                                 SerializedConsumer));
 }
@@ -197,7 +221,11 @@
 // File Manager
 
 void CompilerInstance::createFileManager() {
-  FileMgr = new FileManager(getFileSystemOpts());
+  if (!hasVirtualFileSystem()) {
+    // TODO: choose the virtual file system based on the CompilerInvocation.
+    setVirtualFileSystem(vfs::getRealFileSystem());
+  }
+  FileMgr = new FileManager(getFileSystemOpts(), VirtualFileSystem);
 }
 
 // Source Manager
@@ -206,13 +234,63 @@
   SourceMgr = new SourceManager(getDiagnostics(), FileMgr);
 }
 
+// Initialize the remapping of files to alternative contents, e.g.,
+// those specified through other files.
+static void InitializeFileRemapping(DiagnosticsEngine &Diags,
+                                    SourceManager &SourceMgr,
+                                    FileManager &FileMgr,
+                                    const PreprocessorOptions &InitOpts) {
+  // Remap files in the source manager (with buffers).
+  for (const auto &RB : InitOpts.RemappedFileBuffers) {
+    // Create the file entry for the file that we're mapping from.
+    const FileEntry *FromFile =
+        FileMgr.getVirtualFile(RB.first, RB.second->getBufferSize(), 0);
+    if (!FromFile) {
+      Diags.Report(diag::err_fe_remap_missing_from_file) << RB.first;
+      if (!InitOpts.RetainRemappedFileBuffers)
+        delete RB.second;
+      continue;
+    }
+
+    // Override the contents of the "from" file with the contents of
+    // the "to" file.
+    SourceMgr.overrideFileContents(FromFile, RB.second,
+                                   InitOpts.RetainRemappedFileBuffers);
+  }
+
+  // Remap files in the source manager (with other files).
+  for (const auto &RF : InitOpts.RemappedFiles) {
+    // Find the file that we're mapping to.
+    const FileEntry *ToFile = FileMgr.getFile(RF.second);
+    if (!ToFile) {
+      Diags.Report(diag::err_fe_remap_missing_to_file) << RF.first << RF.second;
+      continue;
+    }
+
+    // Create the file entry for the file that we're mapping from.
+    const FileEntry *FromFile =
+        FileMgr.getVirtualFile(RF.first, ToFile->getSize(), 0);
+    if (!FromFile) {
+      Diags.Report(diag::err_fe_remap_missing_from_file) << RF.first;
+      continue;
+    }
+
+    // Override the contents of the "from" file with the contents of
+    // the "to" file.
+    SourceMgr.overrideFileContents(FromFile, ToFile);
+  }
+
+  SourceMgr.setOverridenFilesKeepOriginalName(
+      InitOpts.RemappedFilesKeepOriginalName);
+}
+
 // Preprocessor
 
-void CompilerInstance::createPreprocessor() {
+void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) {
   const PreprocessorOptions &PPOpts = getPreprocessorOpts();
 
   // Create a PTH manager if we are using some form of a token cache.
-  PTHManager *PTHMgr = 0;
+  PTHManager *PTHMgr = nullptr;
   if (!PPOpts.TokenCache.empty())
     PTHMgr = PTHManager::Create(PPOpts.TokenCache, getDiagnostics());
 
@@ -222,10 +300,10 @@
                                               getDiagnostics(),
                                               getLangOpts(),
                                               &getTarget());
-  PP = new Preprocessor(&getPreprocessorOpts(),
-                        getDiagnostics(), getLangOpts(), &getTarget(),
+  PP = new Preprocessor(&getPreprocessorOpts(), getDiagnostics(), getLangOpts(),
                         getSourceManager(), *HeaderInfo, *this, PTHMgr,
-                        /*OwnsHeaderSearch=*/true);
+                        /*OwnsHeaderSearch=*/true, TUKind);
+  PP->Initialize(getTarget());
 
   // Note that this is different then passing PTHMgr to Preprocessor's ctor.
   // That argument is used as the IdentifierInfoLookup argument to
@@ -238,7 +316,16 @@
   if (PPOpts.DetailedRecord)
     PP->createPreprocessingRecord();
 
-  InitializePreprocessor(*PP, PPOpts, getHeaderSearchOpts(), getFrontendOpts());
+  // Apply remappings to the source manager.
+  InitializeFileRemapping(PP->getDiagnostics(), PP->getSourceManager(),
+                          PP->getFileManager(), PPOpts);
+
+  // Predefine macros and configure the preprocessor.
+  InitializePreprocessor(*PP, PPOpts, getFrontendOpts());
+
+  // Initialize the header search object.
+  ApplyHeaderSearchOptions(PP->getHeaderSearchInfo(), getHeaderSearchOpts(),
+                           PP->getLangOpts(), PP->getTargetInfo().getTriple());
 
   PP->setPreprocessedOutput(getPreprocessorOutputOpts().ShowCPP);
 
@@ -254,11 +341,20 @@
   // Handle generating dependencies, if requested.
   const DependencyOutputOptions &DepOpts = getDependencyOutputOpts();
   if (!DepOpts.OutputFile.empty())
-    AttachDependencyFileGen(*PP, DepOpts);
+    TheDependencyFileGenerator.reset(
+        DependencyFileGenerator::CreateAndAttachToPreprocessor(*PP, DepOpts));
   if (!DepOpts.DOTOutputFile.empty())
     AttachDependencyGraphGen(*PP, DepOpts.DOTOutputFile,
                              getHeaderSearchOpts().Sysroot);
 
+  for (auto &Listener : DependencyCollectors)
+    Listener->attachToPreprocessor(*PP);
+
+  // If we don't have a collector, but we are collecting module dependencies,
+  // then we're the top level compiler instance and need to create one.
+  if (!ModuleDepCollector && !DepOpts.ModuleDependencyOutputDir.empty())
+    ModuleDepCollector = std::make_shared<ModuleDependencyCollector>(
+        DepOpts.ModuleDependencyOutputDir);
 
   // Handle generating header include information, if requested.
   if (DepOpts.ShowHeaderIncludes)
@@ -282,49 +378,46 @@
 void CompilerInstance::createASTContext() {
   Preprocessor &PP = getPreprocessor();
   Context = new ASTContext(getLangOpts(), PP.getSourceManager(),
-                           &getTarget(), PP.getIdentifierTable(),
-                           PP.getSelectorTable(), PP.getBuiltinInfo(),
-                           /*size_reserve=*/ 0);
+                           PP.getIdentifierTable(), PP.getSelectorTable(),
+                           PP.getBuiltinInfo());
+  Context->InitBuiltinTypes(getTarget());
 }
 
 // ExternalASTSource
 
-void CompilerInstance::createPCHExternalASTSource(StringRef Path,
-                                                  bool DisablePCHValidation,
-                                                bool AllowPCHWithCompilerErrors,
-                                                 void *DeserializationListener){
-  OwningPtr<ExternalASTSource> Source;
+void CompilerInstance::createPCHExternalASTSource(
+    StringRef Path, bool DisablePCHValidation, bool AllowPCHWithCompilerErrors,
+    void *DeserializationListener, bool OwnDeserializationListener) {
+  IntrusiveRefCntPtr<ExternalASTSource> Source;
   bool Preamble = getPreprocessorOpts().PrecompiledPreambleBytes.first != 0;
-  Source.reset(createPCHExternalASTSource(Path, getHeaderSearchOpts().Sysroot,
-                                          DisablePCHValidation,
-                                          AllowPCHWithCompilerErrors,
-                                          getPreprocessor(), getASTContext(),
-                                          DeserializationListener,
-                                          Preamble,
-                                       getFrontendOpts().UseGlobalModuleIndex));
+  Source = createPCHExternalASTSource(
+      Path, getHeaderSearchOpts().Sysroot, DisablePCHValidation,
+      AllowPCHWithCompilerErrors, getPreprocessor(), getASTContext(),
+      DeserializationListener, OwnDeserializationListener, Preamble,
+      getFrontendOpts().UseGlobalModuleIndex);
   ModuleManager = static_cast<ASTReader*>(Source.get());
   getASTContext().setExternalSource(Source);
 }
 
-ExternalASTSource *
-CompilerInstance::createPCHExternalASTSource(StringRef Path,
-                                             const std::string &Sysroot,
-                                             bool DisablePCHValidation,
-                                             bool AllowPCHWithCompilerErrors,
-                                             Preprocessor &PP,
-                                             ASTContext &Context,
-                                             void *DeserializationListener,
-                                             bool Preamble,
-                                             bool UseGlobalModuleIndex) {
-  OwningPtr<ASTReader> Reader;
+ExternalASTSource *CompilerInstance::createPCHExternalASTSource(
+    StringRef Path, const std::string &Sysroot, bool DisablePCHValidation,
+    bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context,
+    void *DeserializationListener, bool OwnDeserializationListener,
+    bool Preamble, bool UseGlobalModuleIndex) {
+  HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
+
+  std::unique_ptr<ASTReader> Reader;
   Reader.reset(new ASTReader(PP, Context,
                              Sysroot.empty() ? "" : Sysroot.c_str(),
                              DisablePCHValidation,
                              AllowPCHWithCompilerErrors,
+                             /*AllowConfigurationMismatch*/false,
+                             HSOpts.ModulesValidateSystemHeaders,
                              UseGlobalModuleIndex));
 
   Reader->setDeserializationListener(
-            static_cast<ASTDeserializationListener *>(DeserializationListener));
+      static_cast<ASTDeserializationListener *>(DeserializationListener),
+      /*TakeOwnership=*/OwnDeserializationListener);
   switch (Reader->ReadAST(Path,
                           Preamble ? serialization::MK_Preamble
                                    : serialization::MK_PCH,
@@ -334,7 +427,7 @@
     // Set the predefines buffer as suggested by the PCH reader. Typically, the
     // predefines buffer will be empty.
     PP.setPredefines(Reader->getSuggestedPredefines());
-    return Reader.take();
+    return Reader.release();
 
   case ASTReader::Failure:
     // Unrecoverable failure: don't even try to process the input file.
@@ -349,7 +442,7 @@
     break;
   }
 
-  return 0;
+  return nullptr;
 }
 
 // Code Completion
@@ -384,14 +477,14 @@
       return;
   } else if (EnableCodeCompletion(getPreprocessor(), Loc.FileName,
                                   Loc.Line, Loc.Column)) {
-    setCodeCompletionConsumer(0);
+    setCodeCompletionConsumer(nullptr);
     return;
   }
 
   if (CompletionConsumer->isOutputBinary() &&
       llvm::sys::ChangeStdoutToBinary()) {
     getPreprocessor().getDiagnostics().Report(diag::err_fe_stdout_binary);
-    setCodeCompletionConsumer(0);
+    setCodeCompletionConsumer(nullptr);
   }
 }
 
@@ -407,7 +500,7 @@
                                                const CodeCompleteOptions &Opts,
                                                raw_ostream &OS) {
   if (EnableCodeCompletion(PP, Filename, Line, Column))
-    return 0;
+    return nullptr;
 
   // Set up the creation routine for code-completion.
   return new PrintingCodeCompleteConsumer(Opts, OS);
@@ -432,21 +525,19 @@
     delete it->OS;
     if (!it->TempFilename.empty()) {
       if (EraseFiles) {
-        bool existed;
-        llvm::sys::fs::remove(it->TempFilename, existed);
+        llvm::sys::fs::remove(it->TempFilename);
       } else {
         SmallString<128> NewOutFile(it->Filename);
 
         // If '-working-directory' was passed, the output filename should be
         // relative to that.
         FileMgr->FixupRelativePath(NewOutFile);
-        if (llvm::error_code ec = llvm::sys::fs::rename(it->TempFilename,
-                                                        NewOutFile.str())) {
+        if (std::error_code ec =
+                llvm::sys::fs::rename(it->TempFilename, NewOutFile.str())) {
           getDiagnostics().Report(diag::err_unable_to_rename_temp)
             << it->TempFilename << it->Filename << ec.message();
 
-          bool existed;
-          llvm::sys::fs::remove(it->TempFilename, existed);
+          llvm::sys::fs::remove(it->TempFilename);
         }
       }
     } else if (!it->Filename.empty() && EraseFiles)
@@ -465,6 +556,12 @@
                           /*UseTemporary=*/true);
 }
 
+llvm::raw_null_ostream *CompilerInstance::createNullOutputFile() {
+  llvm::raw_null_ostream *OS = new llvm::raw_null_ostream();
+  addOutputFile(OutputFile("", "", OS));
+  return OS;
+}
+
 llvm::raw_fd_ostream *
 CompilerInstance::createOutputFile(StringRef OutputPath,
                                    bool Binary, bool RemoveFileOnSignal,
@@ -483,7 +580,7 @@
   if (!OS) {
     getDiagnostics().Report(diag::err_fe_unable_to_open_output)
       << OutputPath << Error;
-    return 0;
+    return nullptr;
   }
 
   // Add the output file -- but don't try to remove "-", since this means we are
@@ -521,7 +618,7 @@
     OutFile = "-";
   }
 
-  OwningPtr<llvm::raw_fd_ostream> OS;
+  std::unique_ptr<llvm::raw_fd_ostream> OS;
   std::string OSFile;
 
   if (UseTemporary) {
@@ -533,7 +630,7 @@
       if (llvm::sys::fs::exists(Status)) {
         // Fail early if we can't write to the final destination.
         if (!llvm::sys::fs::can_write(OutputPath))
-          return 0;
+          return nullptr;
 
         // Don't use a temporary if the output is a special file. This handles
         // things like '-o /dev/null'
@@ -549,7 +646,7 @@
     TempPath = OutFile;
     TempPath += "-%%%%%%%%";
     int fd;
-    llvm::error_code EC =
+    std::error_code EC =
         llvm::sys::fs::createUniqueFile(TempPath.str(), fd, TempPath);
 
     if (CreateMissingDirectories &&
@@ -574,9 +671,9 @@
     OSFile = OutFile;
     OS.reset(new llvm::raw_fd_ostream(
         OSFile.c_str(), Error,
-        (Binary ? llvm::sys::fs::F_Binary : llvm::sys::fs::F_None)));
+        (Binary ? llvm::sys::fs::F_None : llvm::sys::fs::F_Text)));
     if (!Error.empty())
-      return 0;
+      return nullptr;
   }
 
   // Make sure the out stream file gets removed if we crash.
@@ -588,7 +685,7 @@
   if (TempPathName)
     *TempPathName = TempFile;
 
-  return OS.take();
+  return OS.release();
 }
 
 // Initialization Utilities
@@ -608,7 +705,7 @@
     Kind = Input.isSystem() ? SrcMgr::C_System : SrcMgr::C_User;
 
   if (Input.isBuffer()) {
-    SourceMgr.createMainFileIDForMemBuffer(Input.getBuffer(), Kind);
+    SourceMgr.setMainFileID(SourceMgr.createFileID(Input.getBuffer(), Kind));
     assert(!SourceMgr.getMainFileID().isInvalid() &&
            "Couldn't establish MainFileID!");
     return true;
@@ -642,17 +739,22 @@
       }
     }
 
-    SourceMgr.createMainFileID(File, Kind);
+    SourceMgr.setMainFileID(
+        SourceMgr.createFileID(File, SourceLocation(), Kind));
   } else {
-    OwningPtr<llvm::MemoryBuffer> SB;
-    if (llvm::error_code ec = llvm::MemoryBuffer::getSTDIN(SB)) {
-      Diags.Report(diag::err_fe_error_reading_stdin) << ec.message();
+    llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> SBOrErr =
+        llvm::MemoryBuffer::getSTDIN();
+    if (std::error_code EC = SBOrErr.getError()) {
+      Diags.Report(diag::err_fe_error_reading_stdin) << EC.message();
       return false;
     }
+    std::unique_ptr<llvm::MemoryBuffer> SB = std::move(SBOrErr.get());
+
     const FileEntry *File = FileMgr.getVirtualFile(SB->getBufferIdentifier(),
                                                    SB->getBufferSize(), 0);
-    SourceMgr.createMainFileID(File, Kind);
-    SourceMgr.overrideFileContents(File, SB.take());
+    SourceMgr.setMainFileID(
+        SourceMgr.createFileID(File, SourceLocation(), Kind));
+    SourceMgr.overrideFileContents(File, SB.release());
   }
 
   assert(!SourceMgr.getMainFileID().isInvalid() &&
@@ -672,7 +774,8 @@
   raw_ostream &OS = llvm::errs();
 
   // Create the target instance.
-  setTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), &getTargetOpts()));
+  setTarget(TargetInfo::CreateTargetInfo(getDiagnostics(),
+                                         getInvocation().TargetOpts));
   if (!hasTarget())
     return false;
 
@@ -680,7 +783,7 @@
   //
   // FIXME: We shouldn't need to do this, the target should be immutable once
   // created. This complexity should be lifted elsewhere.
-  getTarget().setForcedLangOptions(getLangOpts());
+  getTarget().adjust(getLangOpts());
 
   // rewriter project will change target built-in bool type from its default. 
   if (getFrontendOpts().ProgramAction == frontend::RewriteObjC)
@@ -689,7 +792,7 @@
   // Validate/process some options.
   if (getHeaderSearchOpts().Verbose)
     OS << "clang -cc1 version " CLANG_VERSION_STRING
-       << " based upon " << PACKAGE_STRING
+       << " based upon " << BACKEND_PACKAGE_STRING
        << " default target " << llvm::sys::getDefaultTargetTriple() << "\n";
 
   if (getFrontendOpts().ShowTimers)
@@ -748,65 +851,13 @@
   return LangOpts.CPlusPlus? IK_CXX : IK_C;
 }
 
-namespace {
-  struct CompileModuleMapData {
-    CompilerInstance &Instance;
-    GenerateModuleAction &CreateModuleAction;
-  };
-}
-
-/// \brief Helper function that executes the module-generating action under
-/// a crash recovery context.
-static void doCompileMapModule(void *UserData) {
-  CompileModuleMapData &Data
-    = *reinterpret_cast<CompileModuleMapData *>(UserData);
-  Data.Instance.ExecuteAction(Data.CreateModuleAction);
-}
-
-namespace {
-  /// \brief Function object that checks with the given macro definition should
-  /// be removed, because it is one of the ignored macros.
-  class RemoveIgnoredMacro {
-    const HeaderSearchOptions &HSOpts;
-
-  public:
-    explicit RemoveIgnoredMacro(const HeaderSearchOptions &HSOpts)
-      : HSOpts(HSOpts) { }
-
-    bool operator()(const std::pair<std::string, bool> &def) const {
-      StringRef MacroDef = def.first;
-      return HSOpts.ModulesIgnoreMacros.count(MacroDef.split('=').first) > 0;
-    }
-  };
-}
-
 /// \brief Compile a module file for the given module, using the options 
-/// provided by the importing compiler instance.
-static void compileModule(CompilerInstance &ImportingInstance,
-                          SourceLocation ImportLoc,
-                          Module *Module,
-                          StringRef ModuleFileName) {
-  // FIXME: have LockFileManager return an error_code so that we can
-  // avoid the mkdir when the directory already exists.
-  StringRef Dir = llvm::sys::path::parent_path(ModuleFileName);
-  llvm::sys::fs::create_directories(Dir);
-
-  llvm::LockFileManager Locked(ModuleFileName);
-  switch (Locked) {
-  case llvm::LockFileManager::LFS_Error:
-    return;
-
-  case llvm::LockFileManager::LFS_Owned:
-    // We're responsible for building the module ourselves. Do so below.
-    break;
-
-  case llvm::LockFileManager::LFS_Shared:
-    // Someone else is responsible for building the module. Wait for them to
-    // finish.
-    Locked.waitForUnlock();
-    return;
-  }
-
+/// provided by the importing compiler instance. Returns true if the module
+/// was built without errors.
+static bool compileModuleImpl(CompilerInstance &ImportingInstance,
+                              SourceLocation ImportLoc,
+                              Module *Module,
+                              StringRef ModuleFileName) {
   ModuleMap &ModMap 
     = ImportingInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap();
     
@@ -824,10 +875,13 @@
   // 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();
-  PPOpts.Macros.erase(std::remove_if(PPOpts.Macros.begin(), PPOpts.Macros.end(),
-                                     RemoveIgnoredMacro(HSOpts)),
-                      PPOpts.Macros.end());
-
+  PPOpts.Macros.erase(
+      std::remove_if(PPOpts.Macros.begin(), PPOpts.Macros.end(),
+                     [&HSOpts](const std::pair<std::string, bool> &def) {
+        StringRef MacroDef = def.first;
+        return HSOpts.ModulesIgnoreMacros.count(MacroDef.split('=').first) > 0;
+      }),
+      PPOpts.Macros.end());
 
   // Note the name of the module we're building.
   Invocation->getLangOpts()->CurrentModule = Module->getTopLevelModuleName();
@@ -860,16 +914,18 @@
   
   // Construct a compiler instance that will be used to actually create the
   // module.
-  CompilerInstance Instance;
+  CompilerInstance Instance(/*BuildingModule=*/true);
   Instance.setInvocation(&*Invocation);
 
   Instance.createDiagnostics(new ForwardingDiagnosticConsumer(
                                    ImportingInstance.getDiagnosticClient()),
                              /*ShouldOwnClient=*/true);
 
+  Instance.setVirtualFileSystem(&ImportingInstance.getVirtualFileSystem());
+
   // Note that this module is part of the module build stack, so that we
   // can detect cycles in the module graph.
-  Instance.createFileManager(); // FIXME: Adopt file manager from importer?
+  Instance.setFileManager(&ImportingInstance.getFileManager());
   Instance.createSourceManager(Instance.getFileManager());
   SourceManager &SourceMgr = Instance.getSourceManager();
   SourceMgr.setModuleBuildStack(
@@ -877,6 +933,10 @@
   SourceMgr.pushModuleBuildStack(Module->getTopLevelModuleName(),
     FullSourceLoc(ImportLoc, ImportingInstance.getSourceManager()));
 
+  // If we're collecting module dependencies, we need to share a collector
+  // between all of the module CompilerInstances.
+  Instance.setModuleDepCollector(ImportingInstance.getModuleDepCollector());
+
   // Get or create the module map that we'll use to build this module.
   std::string InferredModuleMapContent;
   if (const FileEntry *ModuleMapFile =
@@ -891,24 +951,24 @@
     FrontendOpts.Inputs.push_back(
         FrontendInputFile("__inferred_module.map", IK));
 
-    const llvm::MemoryBuffer *ModuleMapBuffer =
+    llvm::MemoryBuffer *ModuleMapBuffer =
         llvm::MemoryBuffer::getMemBuffer(InferredModuleMapContent);
     ModuleMapFile = Instance.getFileManager().getVirtualFile(
         "__inferred_module.map", InferredModuleMapContent.size(), 0);
     SourceMgr.overrideFileContents(ModuleMapFile, ModuleMapBuffer);
   }
 
-  // Construct a module-generating action.
-  GenerateModuleAction CreateModuleAction(Module->IsSystem);
+  // Construct a module-generating action. Passing through Module->ModuleMap is
+  // safe because the FileManager is shared between the compiler instances.
+  GenerateModuleAction CreateModuleAction(Module->ModuleMap, Module->IsSystem);
   
   // Execute the action to actually build the module in-place. Use a separate
   // thread so that we get a stack large enough.
   const unsigned ThreadStackSize = 8 << 20;
   llvm::CrashRecoveryContext CRC;
-  CompileModuleMapData Data = { Instance, CreateModuleAction };
-  CRC.RunSafelyOnThread(&doCompileMapModule, &Data, ThreadStackSize);
+  CRC.RunSafelyOnThread([&]() { Instance.ExecuteAction(CreateModuleAction); },
+                        ThreadStackSize);
 
-  
   // Delete the temporary module map file.
   // FIXME: Even though we're executing under crash protection, it would still
   // be nice to do this with RemoveFileOnSignal when we can. However, that
@@ -920,6 +980,67 @@
   if (ImportingInstance.getFrontendOpts().GenerateGlobalModuleIndex) {
     ImportingInstance.setBuildGlobalModuleIndex(true);
   }
+
+  return !Instance.getDiagnostics().hasErrorOccurred();
+}
+
+static bool compileAndLoadModule(CompilerInstance &ImportingInstance,
+                                 SourceLocation ImportLoc,
+                                 SourceLocation ModuleNameLoc, Module *Module,
+                                 StringRef ModuleFileName) {
+  auto diagnoseBuildFailure = [&] {
+    ImportingInstance.getDiagnostics().Report(ModuleNameLoc,
+                                              diag::err_module_not_built)
+        << Module->Name << SourceRange(ImportLoc, ModuleNameLoc);
+  };
+
+  // FIXME: have LockFileManager return an error_code so that we can
+  // avoid the mkdir when the directory already exists.
+  StringRef Dir = llvm::sys::path::parent_path(ModuleFileName);
+  llvm::sys::fs::create_directories(Dir);
+
+  while (1) {
+    unsigned ModuleLoadCapabilities = ASTReader::ARR_Missing;
+    llvm::LockFileManager Locked(ModuleFileName);
+    switch (Locked) {
+    case llvm::LockFileManager::LFS_Error:
+      return false;
+
+    case llvm::LockFileManager::LFS_Owned:
+      // We're responsible for building the module ourselves.
+      if (!compileModuleImpl(ImportingInstance, ModuleNameLoc, Module,
+                             ModuleFileName)) {
+        diagnoseBuildFailure();
+        return false;
+      }
+      break;
+
+    case llvm::LockFileManager::LFS_Shared:
+      // Someone else is responsible for building the module. Wait for them to
+      // finish.
+      if (Locked.waitForUnlock() == llvm::LockFileManager::Res_OwnerDied)
+        continue; // try again to get the lock.
+      ModuleLoadCapabilities |= ASTReader::ARR_OutOfDate;
+      break;
+    }
+
+    // Try to read the module file, now that we've compiled it.
+    ASTReader::ASTReadResult ReadResult =
+        ImportingInstance.getModuleManager()->ReadAST(
+            ModuleFileName, serialization::MK_Module, ImportLoc,
+            ModuleLoadCapabilities);
+
+    if (ReadResult == ASTReader::OutOfDate &&
+        Locked == llvm::LockFileManager::LFS_Shared) {
+      // The module may be out of date in the presence of file system races,
+      // or if one of its imports depends on header search paths that are not
+      // consistent with this ImportingInstance.  Try again...
+      continue;
+    } else if (ReadResult == ASTReader::Missing) {
+      diagnoseBuildFailure();
+    }
+    return ReadResult == ASTReader::Success;
+  }
 }
 
 /// \brief Diagnose differences between the current definition of the given
@@ -1012,7 +1133,7 @@
 static void writeTimestampFile(StringRef TimestampFile) {
   std::string ErrorInfo;
   llvm::raw_fd_ostream Out(TimestampFile.str().c_str(), ErrorInfo,
-                           llvm::sys::fs::F_Binary);
+                           llvm::sys::fs::F_None);
 }
 
 /// \brief Prune the module cache of modules that haven't been accessed in
@@ -1035,7 +1156,7 @@
   // Check whether the time stamp is older than our pruning interval.
   // If not, do nothing.
   time_t TimeStampModTime = StatBuf.st_mtime;
-  time_t CurrentTime = time(0);
+  time_t CurrentTime = time(nullptr);
   if (CurrentTime - TimeStampModTime <= time_t(HSOpts.ModuleCachePruneInterval))
     return;
 
@@ -1046,7 +1167,7 @@
 
   // Walk the entire module cache, looking for unused module files and module
   // indices.
-  llvm::error_code EC;
+  std::error_code EC;
   SmallString<128> ModuleCachePathNative;
   llvm::sys::path::native(HSOpts.ModuleCachePath, ModuleCachePathNative);
   for (llvm::sys::fs::directory_iterator
@@ -1057,44 +1178,76 @@
       continue;
 
     // Walk all of the files within this directory.
-    bool RemovedAllFiles = true;
     for (llvm::sys::fs::directory_iterator File(Dir->path(), EC), FileEnd;
          File != FileEnd && !EC; File.increment(EC)) {
       // We only care about module and global module index files.
-      if (llvm::sys::path::extension(File->path()) != ".pcm" &&
-          llvm::sys::path::filename(File->path()) != "modules.idx") {
-        RemovedAllFiles = false;
+      StringRef Extension = llvm::sys::path::extension(File->path());
+      if (Extension != ".pcm" && Extension != ".timestamp" &&
+          llvm::sys::path::filename(File->path()) != "modules.idx")
         continue;
-      }
 
       // Look at this file. If we can't stat it, there's nothing interesting
       // there.
-      if (::stat(File->path().c_str(), &StatBuf)) {
-        RemovedAllFiles = false;
+      if (::stat(File->path().c_str(), &StatBuf))
         continue;
-      }
 
       // If the file has been used recently enough, leave it there.
       time_t FileAccessTime = StatBuf.st_atime;
       if (CurrentTime - FileAccessTime <=
               time_t(HSOpts.ModuleCachePruneAfter)) {
-        RemovedAllFiles = false;
         continue;
       }
 
       // Remove the file.
-      bool Existed;
-      if (llvm::sys::fs::remove(File->path(), Existed) || !Existed) {
-        RemovedAllFiles = false;
-      }
+      llvm::sys::fs::remove(File->path());
+
+      // Remove the timestamp file.
+      std::string TimpestampFilename = File->path() + ".timestamp";
+      llvm::sys::fs::remove(TimpestampFilename);
     }
 
     // If we removed all of the files in the directory, remove the directory
     // itself.
-    if (RemovedAllFiles) {
-      bool Existed;
-      llvm::sys::fs::remove(Dir->path(), Existed);
+    if (llvm::sys::fs::directory_iterator(Dir->path(), EC) ==
+            llvm::sys::fs::directory_iterator() && !EC)
+      llvm::sys::fs::remove(Dir->path());
+  }
+}
+
+void CompilerInstance::createModuleManager() {
+  if (!ModuleManager) {
+    if (!hasASTContext())
+      createASTContext();
+
+    // If we're not recursively building a module, check whether we
+    // need to prune the module cache.
+    if (getSourceManager().getModuleBuildStack().empty() &&
+        getHeaderSearchOpts().ModuleCachePruneInterval > 0 &&
+        getHeaderSearchOpts().ModuleCachePruneAfter > 0) {
+      pruneModuleCache(getHeaderSearchOpts());
     }
+
+    HeaderSearchOptions &HSOpts = getHeaderSearchOpts();
+    std::string Sysroot = HSOpts.Sysroot;
+    const PreprocessorOptions &PPOpts = getPreprocessorOpts();
+    ModuleManager = new ASTReader(getPreprocessor(), *Context,
+                                  Sysroot.empty() ? "" : Sysroot.c_str(),
+                                  PPOpts.DisablePCHValidation,
+                                  /*AllowASTWithCompilerErrors=*/false,
+                                  /*AllowConfigurationMismatch=*/false,
+                                  HSOpts.ModulesValidateSystemHeaders,
+                                  getFrontendOpts().UseGlobalModuleIndex);
+    if (hasASTConsumer()) {
+      ModuleManager->setDeserializationListener(
+        getASTConsumer().GetASTDeserializationListener());
+      getASTContext().setASTMutationListener(
+        getASTConsumer().GetASTMutationListener());
+    }
+    getASTContext().setExternalSource(ModuleManager);
+    if (hasSema())
+      ModuleManager->InitializeSema(getSema());
+    if (hasASTConsumer())
+      ModuleManager->StartTranslationUnit(&getASTConsumer());
   }
 }
 
@@ -1118,7 +1271,7 @@
     return LastModuleImportResult;
   }
 
-  clang::Module *Module = 0;
+  clang::Module *Module = nullptr;
 
   // If we don't already have information on this module, load the module now.
   llvm::DenseMap<const IdentifierInfo *, clang::Module *>::iterator Known
@@ -1128,51 +1281,34 @@
     Module = Known->second;    
   } else if (ModuleName == getLangOpts().CurrentModule) {
     // This is the module we're building. 
-    Module = PP->getHeaderSearchInfo().getModuleMap().findModule(ModuleName);
+    Module = PP->getHeaderSearchInfo().lookupModule(ModuleName);
     Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first;
   } else {
     // Search for a module with the given name.
     Module = PP->getHeaderSearchInfo().lookupModule(ModuleName);
-    std::string ModuleFileName;
-    if (Module) {
-      ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName(Module);
-    } else
-      ModuleFileName = PP->getHeaderSearchInfo().getModuleFileName(ModuleName);
+    if (!Module) {
+      getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_found)
+      << ModuleName
+      << SourceRange(ImportLoc, ModuleNameLoc);
+      ModuleBuildFailed = true;
+      return ModuleLoadResult();
+    }
+
+    std::string ModuleFileName =
+        PP->getHeaderSearchInfo().getModuleFileName(Module);
 
     // If we don't already have an ASTReader, create one now.
-    if (!ModuleManager) {
-      if (!hasASTContext())
-        createASTContext();
+    if (!ModuleManager)
+      createModuleManager();
 
-      // If we're not recursively building a module, check whether we
-      // need to prune the module cache.
-      if (getSourceManager().getModuleBuildStack().empty() &&
-          getHeaderSearchOpts().ModuleCachePruneInterval > 0 &&
-          getHeaderSearchOpts().ModuleCachePruneAfter > 0) {
-        pruneModuleCache(getHeaderSearchOpts());
-      }
+    if (TheDependencyFileGenerator)
+      TheDependencyFileGenerator->AttachToASTReader(*ModuleManager);
 
-      std::string Sysroot = getHeaderSearchOpts().Sysroot;
-      const PreprocessorOptions &PPOpts = getPreprocessorOpts();
-      ModuleManager = new ASTReader(getPreprocessor(), *Context,
-                                    Sysroot.empty() ? "" : Sysroot.c_str(),
-                                    PPOpts.DisablePCHValidation,
-                                    /*AllowASTWithCompilerErrors=*/false,
-                                    getFrontendOpts().UseGlobalModuleIndex);
-      if (hasASTConsumer()) {
-        ModuleManager->setDeserializationListener(
-          getASTConsumer().GetASTDeserializationListener());
-        getASTContext().setASTMutationListener(
-          getASTConsumer().GetASTMutationListener());
-      }
-      OwningPtr<ExternalASTSource> Source;
-      Source.reset(ModuleManager);
-      getASTContext().setExternalSource(Source);
-      if (hasSema())
-        ModuleManager->InitializeSema(getSema());
-      if (hasASTConsumer())
-        ModuleManager->StartTranslationUnit(&getASTConsumer());
-    }
+    if (ModuleDepCollector)
+      ModuleDepCollector->attachToASTReader(*ModuleManager);
+
+    for (auto &Listener : DependencyCollectors)
+      Listener->attachToASTReader(*ModuleManager);
 
     // Try to load the module file.
     unsigned ARRFlags = ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing;
@@ -1184,17 +1320,7 @@
     case ASTReader::OutOfDate:
     case ASTReader::Missing: {
       // The module file is missing or out-of-date. Build it.
-
-      // If we don't have a module, we don't know how to build the module file.
-      // Complain and return.
-      if (!Module) {
-        getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_found)
-          << ModuleName
-          << SourceRange(ImportLoc, ModuleNameLoc);
-        ModuleBuildFailed = true;
-        return ModuleLoadResult();
-      }
-
+      assert(Module && "missing module file");
       // Check whether there is a cycle in the module graph.
       ModuleBuildStack ModPath = getSourceManager().getModuleBuildStack();
       ModuleBuildStack::iterator Pos = ModPath.begin(), PosEnd = ModPath.end();
@@ -1216,6 +1342,9 @@
         return ModuleLoadResult();
       }
 
+      getDiagnostics().Report(ImportLoc, diag::remark_module_build)
+          << ModuleName << ModuleFileName;
+
       // Check whether we have already attempted to build this module (but
       // failed).
       if (getPreprocessorOpts().FailedModules &&
@@ -1227,26 +1356,12 @@
         return ModuleLoadResult();
       }
 
-      // Try to compile the module.
-      compileModule(*this, ModuleNameLoc, Module, ModuleFileName);
-
-      // Try to read the module file, now that we've compiled it.
-      ASTReader::ASTReadResult ReadResult
-        = ModuleManager->ReadAST(ModuleFileName,
-                                 serialization::MK_Module, ImportLoc,
-                                 ASTReader::ARR_Missing);
-      if (ReadResult != ASTReader::Success) {
-        if (ReadResult == ASTReader::Missing) {
-          getDiagnostics().Report(ModuleNameLoc,
-                                  Module? diag::err_module_not_built
-                                        : diag::err_module_not_found)
-            << ModuleName
-            << SourceRange(ImportLoc, ModuleNameLoc);
-        }
-
+      // Try to compile and then load the module.
+      if (!compileAndLoadModule(*this, ImportLoc, ModuleNameLoc, Module,
+                                ModuleFileName)) {
         if (getPreprocessorOpts().FailedModules)
           getPreprocessorOpts().FailedModules->addFailed(ModuleName);
-        KnownModules[Path[0].first] = 0;
+        KnownModules[Path[0].first] = nullptr;
         ModuleBuildFailed = true;
         return ModuleLoadResult();
       }
@@ -1261,23 +1376,16 @@
       ModuleLoader::HadFatalFailure = true;
       // FIXME: The ASTReader will already have complained, but can we showhorn
       // that diagnostic information into a more useful form?
-      KnownModules[Path[0].first] = 0;
+      KnownModules[Path[0].first] = nullptr;
       return ModuleLoadResult();
 
     case ASTReader::Failure:
       ModuleLoader::HadFatalFailure = true;
       // Already complained, but note now that we failed.
-      KnownModules[Path[0].first] = 0;
+      KnownModules[Path[0].first] = nullptr;
       ModuleBuildFailed = true;
       return ModuleLoadResult();
     }
-    
-    if (!Module) {
-      // If we loaded the module directly, without finding a module map first,
-      // we'll have loaded the module's information from the module itself.
-      Module = PP->getHeaderSearchInfo().getModuleMap()
-                 .findModule((Path[0].first->getName()));
-    }
 
     // Cache the result of this top-level module lookup for later.
     Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first;
@@ -1354,17 +1462,25 @@
       getDiagnostics().Report(ImportLoc, diag::warn_missing_submodule)
         << Module->getFullModuleName()
         << SourceRange(Path.front().second, Path.back().second);
-      
-      return ModuleLoadResult(0, true);
+
+      return ModuleLoadResult(nullptr, true);
     }
 
     // Check whether this module is available.
     clang::Module::Requirement Requirement;
-    if (!Module->isAvailable(getLangOpts(), getTarget(), Requirement)) {
-      getDiagnostics().Report(ImportLoc, diag::err_module_unavailable)
-        << Module->getFullModuleName()
-        << Requirement.second << Requirement.first
-        << SourceRange(Path.front().second, Path.back().second);
+    clang::Module::HeaderDirective MissingHeader;
+    if (!Module->isAvailable(getLangOpts(), getTarget(), Requirement,
+                             MissingHeader)) {
+      if (MissingHeader.FileNameLoc.isValid()) {
+        getDiagnostics().Report(MissingHeader.FileNameLoc,
+                                diag::err_module_header_missing)
+          << MissingHeader.IsUmbrella << MissingHeader.FileName;
+      } else {
+        getDiagnostics().Report(ImportLoc, diag::err_module_unavailable)
+          << Module->getFullModuleName()
+          << Requirement.second << Requirement.first
+          << SourceRange(Path.front().second, Path.back().second);
+      }
       LastModuleImportLoc = ImportLoc;
       LastModuleImportResult = ModuleLoadResult();
       return ModuleLoadResult();
@@ -1405,3 +1521,84 @@
   ModuleManager->makeModuleVisible(Mod, Visibility, ImportLoc, Complain);
 }
 
+GlobalModuleIndex *CompilerInstance::loadGlobalModuleIndex(
+    SourceLocation TriggerLoc) {
+  if (!ModuleManager)
+    createModuleManager();
+  // Can't do anything if we don't have the module manager.
+  if (!ModuleManager)
+    return nullptr;
+  // Get an existing global index.  This loads it if not already
+  // loaded.
+  ModuleManager->loadGlobalIndex();
+  GlobalModuleIndex *GlobalIndex = ModuleManager->getGlobalIndex();
+  // If the global index doesn't exist, create it.
+  if (!GlobalIndex && shouldBuildGlobalModuleIndex() && hasFileManager() &&
+      hasPreprocessor()) {
+    llvm::sys::fs::create_directories(
+      getPreprocessor().getHeaderSearchInfo().getModuleCachePath());
+    GlobalModuleIndex::writeIndex(
+      getFileManager(),
+      getPreprocessor().getHeaderSearchInfo().getModuleCachePath());
+    ModuleManager->resetForReload();
+    ModuleManager->loadGlobalIndex();
+    GlobalIndex = ModuleManager->getGlobalIndex();
+  }
+  // For finding modules needing to be imported for fixit messages,
+  // we need to make the global index cover all modules, so we do that here.
+  if (!HaveFullGlobalModuleIndex && GlobalIndex && !buildingModule()) {
+    ModuleMap &MMap = getPreprocessor().getHeaderSearchInfo().getModuleMap();
+    bool RecreateIndex = false;
+    for (ModuleMap::module_iterator I = MMap.module_begin(),
+        E = MMap.module_end(); I != E; ++I) {
+      Module *TheModule = I->second;
+      const FileEntry *Entry = TheModule->getASTFile();
+      if (!Entry) {
+        SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Path;
+        Path.push_back(std::make_pair(
+				  getPreprocessor().getIdentifierInfo(TheModule->Name), TriggerLoc));
+        std::reverse(Path.begin(), Path.end());
+		    // Load a module as hidden.  This also adds it to the global index.
+        loadModule(TheModule->DefinitionLoc, Path,
+                                             Module::Hidden, false);
+        RecreateIndex = true;
+      }
+    }
+    if (RecreateIndex) {
+      GlobalModuleIndex::writeIndex(
+        getFileManager(),
+        getPreprocessor().getHeaderSearchInfo().getModuleCachePath());
+      ModuleManager->resetForReload();
+      ModuleManager->loadGlobalIndex();
+      GlobalIndex = ModuleManager->getGlobalIndex();
+    }
+    HaveFullGlobalModuleIndex = true;
+  }
+  return GlobalIndex;
+}
+
+// Check global module index for missing imports.
+bool
+CompilerInstance::lookupMissingImports(StringRef Name,
+                                       SourceLocation TriggerLoc) {
+  // Look for the symbol in non-imported modules, but only if an error
+  // actually occurred.
+  if (!buildingModule()) {
+    // Load global module index, or retrieve a previously loaded one.
+    GlobalModuleIndex *GlobalIndex = loadGlobalModuleIndex(
+      TriggerLoc);
+
+    // Only if we have a global index.
+    if (GlobalIndex) {
+      GlobalModuleIndex::HitSet FoundModules;
+
+      // Find the modules that reference the identifier.
+      // Note that this only finds top-level modules.
+      // We'll let diagnoseTypo find the actual declaration module.
+      if (GlobalIndex->lookupIdentifier(Name, FoundModules))
+        return true;
+    }
+  }
+
+  return false;
+}
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 8db5cf1..ce61a46 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -8,19 +8,19 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Frontend/CompilerInvocation.h"
-#include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/Version.h"
 #include "clang/Driver/DriverDiagnostic.h"
 #include "clang/Driver/Options.h"
 #include "clang/Driver/Util.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
 #include "clang/Frontend/LangStandard.h"
 #include "clang/Frontend/Utils.h"
 #include "clang/Lex/HeaderSearchOptions.h"
 #include "clang/Serialization/ASTReader.h"
 #include "llvm/ADT/Hashing.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/ADT/Triple.h"
@@ -28,13 +28,16 @@
 #include "llvm/Option/ArgList.h"
 #include "llvm/Option/OptTable.h"
 #include "llvm/Option/Option.h"
+#include "llvm/Support/CodeGen.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/system_error.h"
+#include <atomic>
+#include <memory>
 #include <sys/stat.h>
+#include <system_error>
 using namespace clang;
 
 //===----------------------------------------------------------------------===//
@@ -55,6 +58,8 @@
     HeaderSearchOpts(new HeaderSearchOptions(X.getHeaderSearchOpts())),
     PreprocessorOpts(new PreprocessorOptions(X.getPreprocessorOpts())) {}
 
+CompilerInvocationBase::~CompilerInvocationBase() {}
+
 //===----------------------------------------------------------------------===//
 // Deserialization (from args)
 //===----------------------------------------------------------------------===//
@@ -106,25 +111,21 @@
   return 0;
 }
 
-static void addWarningArgs(ArgList &Args, std::vector<std::string> &Warnings) {
-  for (arg_iterator I = Args.filtered_begin(OPT_W_Group),
-         E = Args.filtered_end(); I != E; ++I) {
-    Arg *A = *I;
-    // If the argument is a pure flag, add its name (minus the "W" at the beginning)
-    // to the warning list. Else, add its value (for the OPT_W case).
+static void addDiagnosticArgs(ArgList &Args, OptSpecifier Group,
+                              OptSpecifier GroupWithValue,
+                              std::vector<std::string> &Diagnostics) {
+  for (Arg *A : Args.filtered(Group)) {
     if (A->getOption().getKind() == Option::FlagClass) {
-      Warnings.push_back(A->getOption().getName().substr(1));
+      // The argument is a pure flag (such as OPT_Wall or OPT_Wdeprecated). Add
+      // its name (minus the "W" or "R" at the beginning) to the warning list.
+      Diagnostics.push_back(A->getOption().getName().drop_front(1));
+    } else if (A->getOption().matches(GroupWithValue)) {
+      // This is -Wfoo= or -Rfoo=, where foo is the name of the diagnostic group.
+      Diagnostics.push_back(A->getOption().getName().drop_front(1).rtrim("=-"));
     } else {
-      for (unsigned Idx = 0, End = A->getNumValues();
-           Idx < End; ++Idx) {
-        StringRef V = A->getValue(Idx);
-        // "-Wl," and such are not warning options.
-        // FIXME: Should be handled by putting these in separate flags.
-        if (V.startswith("l,") || V.startswith("a,") || V.startswith("p,"))
-          continue;
-
-        Warnings.push_back(V);
-      }
+      // Otherwise, add its value (for OPT_W_Joined and similar).
+      for (const char *Arg : A->getValues())
+        Diagnostics.push_back(Arg);
     }
   }
 }
@@ -262,7 +263,7 @@
     configList.split(configVals, ",");
     for (unsigned i = 0, e = configVals.size(); i != e; ++i) {
       StringRef key, val;
-      llvm::tie(key, val) = configVals[i].split("=");
+      std::tie(key, val) = configVals[i].split("=");
       if (val.empty()) {
         Diags.Report(SourceLocation(),
                      diag::err_analyzer_config_no_value) << configVals[i];
@@ -294,8 +295,36 @@
   Opts.ParseAllComments = Args.hasArg(OPT_fparse_all_comments);
 }
 
+static StringRef getCodeModel(ArgList &Args, DiagnosticsEngine &Diags) {
+  if (Arg *A = Args.getLastArg(OPT_mcode_model)) {
+    StringRef Value = A->getValue();
+    if (Value == "small" || Value == "kernel" || Value == "medium" ||
+        Value == "large")
+      return Value;
+    Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Value;
+  }
+  return "default";
+}
+
+/// \brief Create a new Regex instance out of the string value in \p RpassArg.
+/// It returns a pointer to the newly generated Regex instance.
+static std::shared_ptr<llvm::Regex>
+GenerateOptimizationRemarkRegex(DiagnosticsEngine &Diags, ArgList &Args,
+                                Arg *RpassArg) {
+  StringRef Val = RpassArg->getValue();
+  std::string RegexError;
+  std::shared_ptr<llvm::Regex> Pattern = std::make_shared<llvm::Regex>(Val);
+  if (!Pattern->isValid(RegexError)) {
+    Diags.Report(diag::err_drv_optimization_remark_pattern)
+        << RegexError << RpassArg->getAsString(Args);
+    Pattern.reset();
+  }
+  return Pattern;
+}
+
 static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
-                             DiagnosticsEngine &Diags) {
+                             DiagnosticsEngine &Diags,
+                             const TargetOptions &TargetOpts) {
   using namespace options;
   bool Success = true;
 
@@ -322,10 +351,17 @@
     Opts.setDebugInfo(CodeGenOptions::DebugLineTablesOnly);
   } else if (Args.hasArg(OPT_g_Flag) || Args.hasArg(OPT_gdwarf_2) ||
              Args.hasArg(OPT_gdwarf_3) || Args.hasArg(OPT_gdwarf_4)) {
-    if (Args.hasFlag(OPT_flimit_debug_info, OPT_fno_limit_debug_info, true))
-      Opts.setDebugInfo(CodeGenOptions::LimitedDebugInfo);
-    else
+    bool Default = false;
+    // Until dtrace (via CTF) and LLDB can deal with distributed debug info,
+    // Darwin and FreeBSD default to standalone/full debug info.
+    if (llvm::Triple(TargetOpts.Triple).isOSDarwin() ||
+        llvm::Triple(TargetOpts.Triple).isOSFreeBSD())
+      Default = true;
+
+    if (Args.hasFlag(OPT_fstandalone_debug, OPT_fno_standalone_debug, Default))
       Opts.setDebugInfo(CodeGenOptions::FullDebugInfo);
+    else
+      Opts.setDebugInfo(CodeGenOptions::LimitedDebugInfo);
   }
   Opts.DebugColumnInfo = Args.hasArg(OPT_dwarf_column_info);
   Opts.SplitDwarfFile = Args.getLastArgValue(OPT_split_dwarf_file);
@@ -358,20 +394,22 @@
                    (Opts.OptimizationLevel > 1 && !Opts.OptimizeSize));
   Opts.RerollLoops = Args.hasArg(OPT_freroll_loops);
 
+  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.ProfileInstrGenerate = Args.hasArg(OPT_fprofile_instr_generate);
+  Opts.InstrProfileInput = Args.getLastArgValue(OPT_fprofile_instr_use_EQ);
   Opts.AsmVerbose = Args.hasArg(OPT_masm_verbose);
   Opts.ObjCAutoRefCountExceptions = Args.hasArg(OPT_fobjc_arc_exceptions);
   Opts.CUDAIsDevice = Args.hasArg(OPT_fcuda_is_device);
   Opts.CXAAtExit = !Args.hasArg(OPT_fno_use_cxa_atexit);
   Opts.CXXCtorDtorAliases = Args.hasArg(OPT_mconstructor_aliases);
-  Opts.CodeModel = Args.getLastArgValue(OPT_mcode_model);
+  Opts.CodeModel = getCodeModel(Args, Diags);
   Opts.DebugPass = Args.getLastArgValue(OPT_mdebug_pass);
   Opts.DisableFPElim = Args.hasArg(OPT_mdisable_fp_elim);
   Opts.DisableFree = Args.hasArg(OPT_disable_free);
   Opts.DisableTailCalls = Args.hasArg(OPT_mdisable_tail_calls);
   Opts.FloatABI = Args.getLastArgValue(OPT_mfloat_abi);
-  Opts.HiddenWeakVTables = Args.hasArg(OPT_fhidden_weak_vtables);
   Opts.LessPreciseFPMAD = Args.hasArg(OPT_cl_mad_enable);
   Opts.LimitFloatPrecision = Args.getLastArgValue(OPT_mlimit_float_precision);
   Opts.NoInfsFPMath = (Args.hasArg(OPT_menable_no_infinities) ||
@@ -389,7 +427,6 @@
   Opts.RelaxAll = Args.hasArg(OPT_mrelax_all);
   Opts.OmitLeafFramePointer = Args.hasArg(OPT_momit_leaf_frame_pointer);
   Opts.SaveTempLabels = Args.hasArg(OPT_msave_temp_labels);
-  Opts.NoDwarf2CFIAsm = Args.hasArg(OPT_fno_dwarf2_cfi_asm);
   Opts.NoDwarfDirectoryAsm = Args.hasArg(OPT_fno_dwarf_directory_asm);
   Opts.SoftFloat = Args.hasArg(OPT_msoft_float);
   Opts.StrictEnums = Args.hasArg(OPT_fstrict_enums);
@@ -437,15 +474,14 @@
   Opts.InstrumentFunctions = Args.hasArg(OPT_finstrument_functions);
   Opts.InstrumentForProfiling = Args.hasArg(OPT_pg);
   Opts.EmitOpenCLArgMetadata = Args.hasArg(OPT_cl_kernel_arg_info);
+  Opts.CompressDebugSections = Args.hasArg(OPT_compress_debug_sections);
   Opts.DebugCompilationDir = Args.getLastArgValue(OPT_fdebug_compilation_dir);
   Opts.LinkBitcodeFile = Args.getLastArgValue(OPT_mlink_bitcode_file);
   Opts.SanitizerBlacklistFile = Args.getLastArgValue(OPT_fsanitize_blacklist);
   Opts.SanitizeMemoryTrackOrigins =
-    Args.hasArg(OPT_fsanitize_memory_track_origins);
-  Opts.SanitizeAddressZeroBaseShadow =
-    Args.hasArg(OPT_fsanitize_address_zero_base_shadow);
+      getLastArgIntValue(Args, OPT_fsanitize_memory_track_origins_EQ, 0, Diags);
   Opts.SanitizeUndefinedTrapOnError =
-    Args.hasArg(OPT_fsanitize_undefined_trap_on_error);
+      Args.hasArg(OPT_fsanitize_undefined_trap_on_error);
   Opts.SSPBufferSize =
       getLastArgIntValue(Args, OPT_stack_protector_buffer_size, 8, Diags);
   Opts.StackRealignment = Args.hasArg(OPT_mstackrealign);
@@ -510,6 +546,30 @@
   }
 
   Opts.DependentLibraries = Args.getAllArgValues(OPT_dependent_lib);
+  bool NeedLocTracking = false;
+
+  if (Arg *A = Args.getLastArg(OPT_Rpass_EQ)) {
+    Opts.OptimizationRemarkPattern =
+        GenerateOptimizationRemarkRegex(Diags, Args, A);
+    NeedLocTracking = true;
+  }
+
+  if (Arg *A = Args.getLastArg(OPT_Rpass_missed_EQ)) {
+    Opts.OptimizationRemarkMissedPattern =
+        GenerateOptimizationRemarkRegex(Diags, Args, A);
+    NeedLocTracking = true;
+  }
+
+  if (Arg *A = Args.getLastArg(OPT_Rpass_analysis_EQ)) {
+    Opts.OptimizationRemarkAnalysisPattern =
+        GenerateOptimizationRemarkRegex(Diags, Args, A);
+    NeedLocTracking = true;
+  }
+
+  // If the user requested one of the flags in the -Rpass family, make sure
+  // that the backend tracks source location information.
+  if (NeedLocTracking && Opts.getDebugInfo() == CodeGenOptions::NoDebugInfo)
+    Opts.setDebugInfo(CodeGenOptions::LocTrackingOnly);
 
   return Success;
 }
@@ -520,12 +580,15 @@
   Opts.OutputFile = Args.getLastArgValue(OPT_dependency_file);
   Opts.Targets = Args.getAllArgValues(OPT_MT);
   Opts.IncludeSystemHeaders = Args.hasArg(OPT_sys_header_deps);
+  Opts.IncludeModuleFiles = Args.hasArg(OPT_module_file_deps);
   Opts.UsePhonyTargets = Args.hasArg(OPT_MP);
   Opts.ShowHeaderIncludes = Args.hasArg(OPT_H);
   Opts.HeaderIncludeOutputFile = Args.getLastArgValue(OPT_header_include_file);
   Opts.AddMissingHeaderDeps = Args.hasArg(OPT_MG);
   Opts.PrintShowIncludes = Args.hasArg(OPT_show_includes);
   Opts.DOTOutputFile = Args.getLastArgValue(OPT_dependency_dot);
+  Opts.ModuleDependencyOutputDir =
+      Args.getLastArgValue(OPT_module_dependency_dir);
 }
 
 bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
@@ -632,7 +695,8 @@
       << Opts.TabStop << DiagnosticOptions::DefaultTabStop;
   }
   Opts.MessageLength = getLastArgIntValue(Args, OPT_fmessage_length, 0, Diags);
-  addWarningArgs(Args, Opts.Warnings);
+  addDiagnosticArgs(Args, OPT_W_Group, OPT_W_value_Group, Opts.Warnings);
+  addDiagnosticArgs(Args, OPT_R_Group, OPT_R_value_Group, Opts.Remarks);
 
   return Success;
 }
@@ -692,6 +756,8 @@
       Opts.ProgramAction = frontend::ParseSyntaxOnly; break;
     case OPT_module_file_info:
       Opts.ProgramAction = frontend::ModuleFileInfo; break;
+    case OPT_verify_pch:
+      Opts.ProgramAction = frontend::VerifyPCH; break;
     case OPT_print_decl_contexts:
       Opts.ProgramAction = frontend::PrintDeclContext; break;
     case OPT_print_preamble:
@@ -820,10 +886,12 @@
     Opts.ObjCMTAction |= FrontendOptions::ObjCMT_AtomicProperty;
   if (Args.hasArg(OPT_objcmt_ns_nonatomic_iosonly))
     Opts.ObjCMTAction |= FrontendOptions::ObjCMT_NsAtomicIOSOnlyProperty;
+  if (Args.hasArg(OPT_objcmt_migrate_designated_init))
+    Opts.ObjCMTAction |= FrontendOptions::ObjCMT_DesignatedInitializer;
   if (Args.hasArg(OPT_objcmt_migrate_all))
     Opts.ObjCMTAction |= FrontendOptions::ObjCMT_MigrateDecls;
 
-  Opts.ObjCMTWhiteListPath = Args.getLastArgValue(OPT_objcmt_white_list_dir_path);
+  Opts.ObjCMTWhiteListPath = Args.getLastArgValue(OPT_objcmt_whitelist_dir_path);
 
   if (Opts.ARCMTAction != FrontendOptions::ARCMT_None &&
       Opts.ObjCMTAction != FrontendOptions::ObjCMT_None) {
@@ -906,6 +974,7 @@
     Opts.UseLibcxx = (strcmp(A->getValue(), "libc++") == 0);
   Opts.ResourceDir = Args.getLastArgValue(OPT_resource_dir);
   Opts.ModuleCachePath = Args.getLastArgValue(OPT_fmodules_cache_path);
+  Opts.ModuleUserBuildPath = Args.getLastArgValue(OPT_fmodules_user_build_path);
   Opts.DisableModuleHash = Args.hasArg(OPT_fdisable_module_hash);
   // -fmodules implies -fmodule-maps
   Opts.ModuleMaps = Args.hasArg(OPT_fmodule_maps) || Args.hasArg(OPT_fmodules);
@@ -913,6 +982,13 @@
       getLastArgIntValue(Args, OPT_fmodules_prune_interval, 7 * 24 * 60 * 60);
   Opts.ModuleCachePruneAfter =
       getLastArgIntValue(Args, OPT_fmodules_prune_after, 31 * 24 * 60 * 60);
+  Opts.ModulesValidateOncePerBuildSession =
+      Args.hasArg(OPT_fmodules_validate_once_per_build_session);
+  Opts.BuildSessionTimestamp =
+      getLastArgUInt64Value(Args, OPT_fbuild_session_timestamp, 0);
+  Opts.ModulesValidateSystemHeaders =
+      Args.hasArg(OPT_fmodules_validate_system_headers);
+
   for (arg_iterator it = Args.filtered_begin(OPT_fmodules_ignore_macro),
                     ie = Args.filtered_end();
        it != ie; ++it) {
@@ -998,12 +1074,16 @@
   }
 
   // Add the path prefixes which are implicitly treated as being system headers.
-  for (arg_iterator I = Args.filtered_begin(OPT_isystem_prefix,
-                                            OPT_ino_system_prefix),
+  for (arg_iterator I = Args.filtered_begin(OPT_system_header_prefix,
+                                            OPT_no_system_header_prefix),
                     E = Args.filtered_end();
        I != E; ++I)
-    Opts.AddSystemHeaderPrefix((*I)->getValue(),
-                               (*I)->getOption().matches(OPT_isystem_prefix));
+    Opts.AddSystemHeaderPrefix(
+        (*I)->getValue(), (*I)->getOption().matches(OPT_system_header_prefix));
+
+  for (arg_iterator I = Args.filtered_begin(OPT_ivfsoverlay),
+       E = Args.filtered_end(); I != E; ++I)
+    Opts.AddVFSOverlayFile((*I)->getValue());
 }
 
 void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK,
@@ -1056,6 +1136,7 @@
   Opts.CPlusPlus = Std.isCPlusPlus();
   Opts.CPlusPlus11 = Std.isCPlusPlus11();
   Opts.CPlusPlus1y = Std.isCPlusPlus1y();
+  Opts.CPlusPlus1z = Std.isCPlusPlus1z();
   Opts.Digraphs = Std.hasDigraphs();
   Opts.GNUMode = Std.isGNUMode();
   Opts.GNUInline = !Std.isC99();
@@ -1063,18 +1144,13 @@
   Opts.ImplicitInt = Std.hasImplicitInt();
 
   // Set OpenCL Version.
-  if (LangStd == LangStandard::lang_opencl) {
-    Opts.OpenCL = 1;
+  Opts.OpenCL = LangStd == LangStandard::lang_opencl || IK == IK_OpenCL;
+  if (LangStd == LangStandard::lang_opencl)
     Opts.OpenCLVersion = 100;
-  }
-  else if (LangStd == LangStandard::lang_opencl11) {
-      Opts.OpenCL = 1;
+  else if (LangStd == LangStandard::lang_opencl11)
       Opts.OpenCLVersion = 110;
-  }
-  else if (LangStd == LangStandard::lang_opencl12) {
-    Opts.OpenCL = 1;
+  else if (LangStd == LangStandard::lang_opencl12)
     Opts.OpenCLVersion = 120;
-  }
   
   // OpenCL has some additional defaults.
   if (Opts.OpenCL) {
@@ -1085,12 +1161,14 @@
     Opts.NativeHalfType = 1;
   }
 
-  if (LangStd == LangStandard::lang_cuda)
-    Opts.CUDA = 1;
+  Opts.CUDA = LangStd == LangStandard::lang_cuda || IK == IK_CUDA;
 
   // OpenCL and C++ both have bool, true, false keywords.
   Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
 
+  // OpenCL has half keyword
+  Opts.Half = Opts.OpenCL;
+
   // C++ has wchar_t keyword.
   Opts.WChar = Opts.CPlusPlus;
 
@@ -1099,7 +1177,8 @@
 
   // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs
   // is specified, or -std is set to a conforming mode.
-  Opts.Trigraphs = !Opts.GNUMode;
+  // Trigraphs are disabled by default in c++1z onwards.
+  Opts.Trigraphs = !Opts.GNUMode && !Opts.CPlusPlus1z;
 
   Opts.DollarIdents = !Opts.AsmPreprocessor;
 
@@ -1125,6 +1204,43 @@
   return DefaultVisibility;
 }
 
+static unsigned parseMSCVersion(ArgList &Args, DiagnosticsEngine &Diags) {
+  auto Arg = Args.getLastArg(OPT_fms_compatibility_version);
+  if (!Arg)
+    return 0;
+
+  // The MSC versioning scheme involves four versioning components:
+  //  - Major
+  //  - Minor
+  //  - Build
+  //  - Patch
+  //
+  // We accept either the old style (_MSC_VER) value, or a _MSC_FULL_VER value.
+  // Additionally, the value may be provided in the form of a more readable
+  // MM.mm.bbbbb.pp version.
+  //
+  // Unfortunately, due to the bit-width limitations, we cannot currently encode
+  // the value for the patch level.
+
+  unsigned VC[4] = {0};
+  StringRef Value = Arg->getValue();
+  SmallVector<StringRef, 4> Components;
+
+  Value.split(Components, ".", llvm::array_lengthof(VC));
+  for (unsigned CI = 0,
+                CE = std::min(Components.size(), llvm::array_lengthof(VC));
+       CI < CE; ++CI) {
+    if (Components[CI].getAsInteger(10, VC[CI])) {
+      Diags.Report(diag::err_drv_invalid_value)
+        << Arg->getAsString(Args) << Value;
+      return 0;
+    }
+  }
+
+  // FIXME we cannot encode the patch level
+  return VC[0] * 10000000 + VC[1] * 100000 + VC[2];
+}
+
 static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
                           DiagnosticsEngine &Diags) {
   // FIXME: Cleanup per-file based stuff.
@@ -1139,7 +1255,8 @@
       Diags.Report(diag::err_drv_invalid_value)
         << A->getAsString(Args) << A->getValue();
     else {
-      // Valid standard, check to make sure language and standard are compatable.    
+      // Valid standard, check to make sure language and standard are
+      // compatible.
       const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
       switch (IK) {
       case IK_C:
@@ -1290,11 +1407,11 @@
                                    OPT_fno_dollars_in_identifiers,
                                    Opts.DollarIdents);
   Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings);
-  Opts.MicrosoftExt
-    = Args.hasArg(OPT_fms_extensions) || Args.hasArg(OPT_fms_compatibility);
-  Opts.MicrosoftMode = Args.hasArg(OPT_fms_compatibility);
+  Opts.MSVCCompat = Args.hasArg(OPT_fms_compatibility);
+  Opts.MicrosoftExt = Opts.MSVCCompat || Args.hasArg(OPT_fms_extensions);
   Opts.AsmBlocks = Args.hasArg(OPT_fasm_blocks) || Opts.MicrosoftExt;
-  Opts.MSCVersion = getLastArgIntValue(Args, OPT_fmsc_version, 0, Diags);
+  Opts.MSCompatibilityVersion = parseMSCVersion(Args, Diags);
+  Opts.VtorDispMode = getLastArgIntValue(Args, OPT_vtordisp_mode_EQ, 1, Diags);
   Opts.Borland = Args.hasArg(OPT_fborland_extensions);
   Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
   Opts.ConstStrings = Args.hasFlag(OPT_fconst_strings, OPT_fno_const_strings,
@@ -1310,13 +1427,20 @@
   Opts.TraditionalCPP = Args.hasArg(OPT_traditional_cpp);
 
   Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
+  Opts.RTTIData = Opts.RTTI && !Args.hasArg(OPT_fno_rtti_data);
   Opts.Blocks = Args.hasArg(OPT_fblocks);
   Opts.BlocksRuntimeOptional = Args.hasArg(OPT_fblocks_runtime_optional);
   Opts.Modules = Args.hasArg(OPT_fmodules);
-  Opts.ModulesDeclUse = Args.hasArg(OPT_fmodules_decluse);
+  Opts.ModulesStrictDeclUse = Args.hasArg(OPT_fmodules_strict_decluse);
+  Opts.ModulesDeclUse =
+      Args.hasArg(OPT_fmodules_decluse) || Opts.ModulesStrictDeclUse;
+  Opts.ModulesSearchAll = Opts.Modules &&
+    !Args.hasArg(OPT_fno_modules_search_all) &&
+    Args.hasArg(OPT_fmodules_search_all);
+  Opts.ModulesErrorRecovery = !Args.hasArg(OPT_fno_modules_error_recovery);
   Opts.CharIsSigned = Opts.OpenCL || !Args.hasArg(OPT_fno_signed_char);
   Opts.WChar = Opts.CPlusPlus && !Args.hasArg(OPT_fno_wchar);
-  Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar);
+  Opts.ShortWChar = Args.hasFlag(OPT_fshort_wchar, OPT_fno_short_wchar, false);
   Opts.ShortEnums = Args.hasArg(OPT_fshort_enums);
   Opts.Freestanding = Args.hasArg(OPT_ffreestanding);
   Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
@@ -1391,8 +1515,30 @@
     }
   }
 
-  // Check if -fopenmp is specified.
-  Opts.OpenMP = Args.hasArg(OPT_fopenmp);
+  if (Arg *A = Args.getLastArg(OPT_fms_memptr_rep_EQ)) {
+    LangOptions::PragmaMSPointersToMembersKind InheritanceModel =
+        llvm::StringSwitch<LangOptions::PragmaMSPointersToMembersKind>(
+            A->getValue())
+            .Case("single",
+                  LangOptions::PPTMK_FullGeneralitySingleInheritance)
+            .Case("multiple",
+                  LangOptions::PPTMK_FullGeneralityMultipleInheritance)
+            .Case("virtual",
+                  LangOptions::PPTMK_FullGeneralityVirtualInheritance)
+            .Default(LangOptions::PPTMK_BestCase);
+    if (InheritanceModel == LangOptions::PPTMK_BestCase)
+      Diags.Report(diag::err_drv_invalid_value)
+          << "-fms-memptr-rep=" << A->getValue();
+
+    Opts.setMSPointerToMemberRepresentationMethod(InheritanceModel);
+  }
+
+  // Check if -fopenmp= is specified.
+  if (const Arg *A = Args.getLastArg(options::OPT_fopenmp_EQ)) {
+    Opts.OpenMP = llvm::StringSwitch<bool>(A->getValue())
+        .Case("libiomp5", true)
+        .Default(false);
+  }
 
   // Record whether the __DEPRECATED define was requested.
   Opts.Deprecated = Args.hasFlag(OPT_fdeprecated_macro,
@@ -1424,7 +1570,8 @@
     break;
   case 0: Opts.setStackProtector(LangOptions::SSPOff); break;
   case 1: Opts.setStackProtector(LangOptions::SSPOn);  break;
-  case 2: Opts.setStackProtector(LangOptions::SSPReq); break;
+  case 2: Opts.setStackProtector(LangOptions::SSPStrong); break;
+  case 3: Opts.setStackProtector(LangOptions::SSPReq); break;
   }
 
   // Parse -fsanitize= arguments.
@@ -1575,6 +1722,7 @@
   case frontend::GeneratePTH:
   case frontend::ParseSyntaxOnly:
   case frontend::ModuleFileInfo:
+  case frontend::VerifyPCH:
   case frontend::PluginAction:
   case frontend::PrintDeclContext:
   case frontend::RewriteObjC:
@@ -1605,7 +1753,6 @@
 static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args) {
   using namespace options;
   Opts.ABI = Args.getLastArgValue(OPT_target_abi);
-  Opts.CXXABI = Args.getLastArgValue(OPT_cxx_abi);
   Opts.CPU = Args.getLastArgValue(OPT_target_cpu);
   Opts.FPMath = Args.getLastArgValue(OPT_mfpmath);
   Opts.FeaturesAsWritten = Args.getAllArgValues(OPT_target_feature);
@@ -1617,8 +1764,6 @@
     Opts.Triple = llvm::sys::getDefaultTargetTriple();
 }
 
-//
-
 bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
                                         const char *const *ArgBegin,
                                         const char *const *ArgEnd,
@@ -1626,12 +1771,12 @@
   bool Success = true;
 
   // Parse the arguments.
-  OwningPtr<OptTable> Opts(createDriverOptTable());
+  std::unique_ptr<OptTable> Opts(createDriverOptTable());
   const unsigned IncludedFlagsBitmask = options::CC1Option;
   unsigned MissingArgIndex, MissingArgCount;
-  OwningPtr<InputArgList> Args(
-    Opts->ParseArgs(ArgBegin, ArgEnd, MissingArgIndex, MissingArgCount,
-                    IncludedFlagsBitmask));
+  std::unique_ptr<InputArgList> Args(
+      Opts->ParseArgs(ArgBegin, ArgEnd, MissingArgIndex, MissingArgCount,
+                      IncludedFlagsBitmask));
 
   // Check for missing argument error.
   if (MissingArgCount) {
@@ -1656,8 +1801,9 @@
   ParseFileSystemArgs(Res.getFileSystemOpts(), *Args);
   // FIXME: We shouldn't have to pass the DashX option around here
   InputKind DashX = ParseFrontendArgs(Res.getFrontendOpts(), *Args, Diags);
-  Success = ParseCodeGenArgs(Res.getCodeGenOpts(), *Args, DashX, Diags)
-            && Success;
+  ParseTargetArgs(Res.getTargetOpts(), *Args);
+  Success = ParseCodeGenArgs(Res.getCodeGenOpts(), *Args, DashX, Diags,
+                             Res.getTargetOpts()) && Success;
   ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), *Args);
   if (DashX != IK_AST && DashX != IK_LLVM_IR) {
     ParseLangArgs(*Res.getLangOpts(), *Args, DashX, Diags);
@@ -1672,8 +1818,6 @@
   ParsePreprocessorArgs(Res.getPreprocessorOpts(), *Args, FileMgr, Diags);
   ParsePreprocessorOutputArgs(Res.getPreprocessorOutputOpts(), *Args,
                               Res.getFrontendOpts().ProgramAction);
-  ParseTargetArgs(Res.getTargetOpts(), *Args);
-
   return Success;
 }
 
@@ -1753,8 +1897,7 @@
   
   // Extend the signature with the target options.
   code = hash_combine(code, TargetOpts->Triple, TargetOpts->CPU,
-                      TargetOpts->ABI, TargetOpts->CXXABI,
-                      TargetOpts->LinkerVersion);
+                      TargetOpts->ABI);
   for (unsigned i = 0, n = TargetOpts->FeaturesAsWritten.size(); i != n; ++i)
     code = hash_combine(code, TargetOpts->FeaturesAsWritten[i]);
 
@@ -1763,7 +1906,6 @@
   const HeaderSearchOptions &hsOpts = getHeaderSearchOpts();
   code = hash_combine(code, ppOpts.UsePredefines, ppOpts.DetailedRecord);
 
-  std::vector<StringRef> MacroDefs;
   for (std::vector<std::pair<std::string, bool/*isUndef*/> >::const_iterator 
             I = getPreprocessorOpts().Macros.begin(),
          IEnd = getPreprocessorOpts().Macros.end();
@@ -1785,20 +1927,26 @@
                       hsOpts.UseStandardSystemIncludes,
                       hsOpts.UseStandardCXXIncludes,
                       hsOpts.UseLibcxx);
+  code = hash_combine(code, hsOpts.ResourceDir);
+
+  // Extend the signature with the user build path.
+  code = hash_combine(code, hsOpts.ModuleUserBuildPath);
 
   // Darwin-specific hack: if we have a sysroot, use the contents and
   // modification time of
   //   $sysroot/System/Library/CoreServices/SystemVersion.plist
   // as part of the module hash.
   if (!hsOpts.Sysroot.empty()) {
-    llvm::OwningPtr<llvm::MemoryBuffer> buffer;
     SmallString<128> systemVersionFile;
     systemVersionFile += hsOpts.Sysroot;
     llvm::sys::path::append(systemVersionFile, "System");
     llvm::sys::path::append(systemVersionFile, "Library");
     llvm::sys::path::append(systemVersionFile, "CoreServices");
     llvm::sys::path::append(systemVersionFile, "SystemVersion.plist");
-    if (!llvm::MemoryBuffer::getFile(systemVersionFile.str(), buffer)) {
+
+    llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> buffer =
+        llvm::MemoryBuffer::getFile(systemVersionFile.str());
+    if (buffer) {
       code = hash_combine(code, buffer.get()->getBuffer());
 
       struct stat statBuf;
@@ -1812,10 +1960,11 @@
 
 namespace clang {
 
-// Declared in clang/Frontend/Utils.h.
-int getLastArgIntValue(const ArgList &Args, OptSpecifier Id, int Default,
-                       DiagnosticsEngine *Diags) {
-  int Res = Default;
+template<typename IntTy>
+static IntTy getLastArgIntValueImpl(const ArgList &Args, OptSpecifier Id,
+                                    IntTy Default,
+                                    DiagnosticsEngine *Diags) {
+  IntTy Res = Default;
   if (Arg *A = Args.getLastArg(Id)) {
     if (StringRef(A->getValue()).getAsInteger(10, Res)) {
       if (Diags)
@@ -1825,4 +1974,60 @@
   }
   return Res;
 }
+
+
+// Declared in clang/Frontend/Utils.h.
+int getLastArgIntValue(const ArgList &Args, OptSpecifier Id, int Default,
+                       DiagnosticsEngine *Diags) {
+  return getLastArgIntValueImpl<int>(Args, Id, Default, Diags);
 }
+
+uint64_t getLastArgUInt64Value(const ArgList &Args, OptSpecifier Id,
+                               uint64_t Default,
+                               DiagnosticsEngine *Diags) {
+  return getLastArgIntValueImpl<uint64_t>(Args, Id, Default, Diags);
+}
+
+void BuryPointer(const void *Ptr) {
+  // This function may be called only a small fixed amount of times per each
+  // invocation, otherwise we do actually have a leak which we want to report.
+  // If this function is called more than kGraveYardMaxSize times, the pointers
+  // will not be properly buried and a leak detector will report a leak, which
+  // is what we want in such case.
+  static const size_t kGraveYardMaxSize = 16;
+  LLVM_ATTRIBUTE_UNUSED static const void *GraveYard[kGraveYardMaxSize];
+  static std::atomic<unsigned> GraveYardSize;
+  unsigned Idx = GraveYardSize++;
+  if (Idx >= kGraveYardMaxSize)
+    return;
+  GraveYard[Idx] = Ptr;
+}
+
+IntrusiveRefCntPtr<vfs::FileSystem>
+createVFSFromCompilerInvocation(const CompilerInvocation &CI,
+                                DiagnosticsEngine &Diags) {
+  if (CI.getHeaderSearchOpts().VFSOverlayFiles.empty())
+    return vfs::getRealFileSystem();
+
+  IntrusiveRefCntPtr<vfs::OverlayFileSystem>
+    Overlay(new vfs::OverlayFileSystem(vfs::getRealFileSystem()));
+  // earlier vfs files are on the bottom
+  for (const std::string &File : CI.getHeaderSearchOpts().VFSOverlayFiles) {
+    llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buffer =
+        llvm::MemoryBuffer::getFile(File);
+    if (!Buffer) {
+      Diags.Report(diag::err_missing_vfs_overlay_file) << File;
+      return IntrusiveRefCntPtr<vfs::FileSystem>();
+    }
+
+    IntrusiveRefCntPtr<vfs::FileSystem> FS =
+        vfs::getVFSFromYAML(Buffer->release(), /*DiagHandler*/ nullptr);
+    if (!FS.get()) {
+      Diags.Report(diag::err_invalid_vfs_overlay) << File;
+      return IntrusiveRefCntPtr<vfs::FileSystem>();
+    }
+    Overlay->pushOverlay(FS);
+  }
+  return Overlay;
+}
+} // end namespace clang
diff --git a/lib/Frontend/CreateInvocationFromCommandLine.cpp b/lib/Frontend/CreateInvocationFromCommandLine.cpp
index 78f39d4..f2f36e4 100644
--- a/lib/Frontend/CreateInvocationFromCommandLine.cpp
+++ b/lib/Frontend/CreateInvocationFromCommandLine.cpp
@@ -32,7 +32,7 @@
 CompilerInvocation *
 clang::createInvocationFromCommandLine(ArrayRef<const char *> ArgList,
                             IntrusiveRefCntPtr<DiagnosticsEngine> Diags) {
-  if (!Diags.getPtr()) {
+  if (!Diags.get()) {
     // No diagnostics engine was provided, so create our own diagnostics object
     // with the default options.
     Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions);
@@ -47,17 +47,17 @@
 
   // FIXME: We shouldn't have to pass in the path info.
   driver::Driver TheDriver("clang", llvm::sys::getDefaultTargetTriple(),
-                           "a.out", *Diags);
+                           *Diags);
 
   // Don't check that inputs exist, they may have been remapped.
   TheDriver.setCheckInputsExist(false);
 
-  OwningPtr<driver::Compilation> C(TheDriver.BuildCompilation(Args));
+  std::unique_ptr<driver::Compilation> C(TheDriver.BuildCompilation(Args));
 
   // Just print the cc1 options if -### was present.
   if (C->getArgs().hasArg(driver::options::OPT__HASH_HASH_HASH)) {
     C->getJobs().Print(llvm::errs(), "\n", true);
-    return 0;
+    return nullptr;
   }
 
   // We expect to get back exactly one command job, if we didn't something
@@ -68,22 +68,22 @@
     llvm::raw_svector_ostream OS(Msg);
     Jobs.Print(OS, "; ", true);
     Diags->Report(diag::err_fe_expected_compiler_job) << OS.str();
-    return 0;
+    return nullptr;
   }
 
   const driver::Command *Cmd = cast<driver::Command>(*Jobs.begin());
   if (StringRef(Cmd->getCreator().getName()) != "clang") {
     Diags->Report(diag::err_fe_expected_clang_command);
-    return 0;
+    return nullptr;
   }
 
   const ArgStringList &CCArgs = Cmd->getArguments();
-  OwningPtr<CompilerInvocation> CI(new CompilerInvocation());
+  std::unique_ptr<CompilerInvocation> CI(new CompilerInvocation());
   if (!CompilerInvocation::CreateFromArgs(*CI,
                                      const_cast<const char **>(CCArgs.data()),
                                      const_cast<const char **>(CCArgs.data()) +
                                      CCArgs.size(),
                                      *Diags))
-    return 0;
-  return CI.take();
+    return nullptr;
+  return CI.release();
 }
diff --git a/lib/Frontend/DependencyFile.cpp b/lib/Frontend/DependencyFile.cpp
index 4037af9..0b9c0d4 100644
--- a/lib/Frontend/DependencyFile.cpp
+++ b/lib/Frontend/DependencyFile.cpp
@@ -20,6 +20,7 @@
 #include "clang/Lex/LexDiagnostic.h"
 #include "clang/Lex/PPCallbacks.h"
 #include "clang/Lex/Preprocessor.h"
+#include "clang/Serialization/ASTReader.h"
 #include "llvm/ADT/StringSet.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
@@ -28,7 +29,107 @@
 using namespace clang;
 
 namespace {
-class DependencyFileCallback : public PPCallbacks {
+struct DepCollectorPPCallbacks : public PPCallbacks {
+  DependencyCollector &DepCollector;
+  SourceManager &SM;
+  DepCollectorPPCallbacks(DependencyCollector &L, SourceManager &SM)
+      : DepCollector(L), SM(SM) { }
+
+  void FileChanged(SourceLocation Loc, FileChangeReason Reason,
+                   SrcMgr::CharacteristicKind FileType,
+                   FileID PrevFID) override {
+    if (Reason != PPCallbacks::EnterFile)
+      return;
+
+    // Dependency generation really does want to go all the way to the
+    // file entry for a source location to find out what is depended on.
+    // We do not want #line markers to affect dependency generation!
+    const FileEntry *FE =
+        SM.getFileEntryForID(SM.getFileID(SM.getExpansionLoc(Loc)));
+    if (!FE)
+      return;
+
+    StringRef Filename = FE->getName();
+
+    // Remove leading "./" (or ".//" or "././" etc.)
+    while (Filename.size() > 2 && Filename[0] == '.' &&
+           llvm::sys::path::is_separator(Filename[1])) {
+      Filename = Filename.substr(1);
+      while (llvm::sys::path::is_separator(Filename[0]))
+        Filename = Filename.substr(1);
+    }
+
+    DepCollector.maybeAddDependency(Filename, /*FromModule*/false,
+                                   FileType != SrcMgr::C_User,
+                                   /*IsModuleFile*/false, /*IsMissing*/false);
+  }
+
+  void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
+                          StringRef FileName, bool IsAngled,
+                          CharSourceRange FilenameRange, const FileEntry *File,
+                          StringRef SearchPath, StringRef RelativePath,
+                          const Module *Imported) override {
+    if (!File)
+      DepCollector.maybeAddDependency(FileName, /*FromModule*/false,
+                                     /*IsSystem*/false, /*IsModuleFile*/false,
+                                     /*IsMissing*/true);
+    // Files that actually exist are handled by FileChanged.
+  }
+
+  void EndOfMainFile() override {
+    DepCollector.finishedMainFile();
+  }
+};
+
+struct DepCollectorASTListener : public ASTReaderListener {
+  DependencyCollector &DepCollector;
+  DepCollectorASTListener(DependencyCollector &L) : DepCollector(L) { }
+  bool needsInputFileVisitation() override { return true; }
+  bool needsSystemInputFileVisitation() override {
+    return DepCollector.needSystemDependencies();
+  }
+  void visitModuleFile(StringRef Filename) override {
+    DepCollector.maybeAddDependency(Filename, /*FromModule*/true,
+                                   /*IsSystem*/false, /*IsModuleFile*/true,
+                                   /*IsMissing*/false);
+  }
+  bool visitInputFile(StringRef Filename, bool IsSystem,
+                      bool IsOverridden) override {
+    if (IsOverridden)
+      return true;
+
+    DepCollector.maybeAddDependency(Filename, /*FromModule*/true, IsSystem,
+                                   /*IsModuleFile*/false, /*IsMissing*/false);
+    return true;
+  }
+};
+} // end anonymous namespace
+
+void DependencyCollector::maybeAddDependency(StringRef Filename, bool FromModule,
+                                            bool IsSystem, bool IsModuleFile,
+                                            bool IsMissing) {
+  if (Seen.insert(Filename) &&
+      sawDependency(Filename, FromModule, IsSystem, IsModuleFile, IsMissing))
+    Dependencies.push_back(Filename);
+}
+
+bool DependencyCollector::sawDependency(StringRef Filename, bool FromModule,
+                                       bool IsSystem, bool IsModuleFile,
+                                       bool IsMissing) {
+  return Filename != "<built-in>" && (needSystemDependencies() || !IsSystem);
+}
+
+DependencyCollector::~DependencyCollector() { }
+void DependencyCollector::attachToPreprocessor(Preprocessor &PP) {
+  PP.addPPCallbacks(new DepCollectorPPCallbacks(*this, PP.getSourceManager()));
+}
+void DependencyCollector::attachToASTReader(ASTReader &R) {
+  R.addListener(new DepCollectorASTListener(*this));
+}
+
+namespace {
+/// Private implementation for DependencyFileGenerator
+class DFGImpl : public PPCallbacks {
   std::vector<std::string> Files;
   llvm::StringSet<> FilesSet;
   const Preprocessor *PP;
@@ -38,58 +139,84 @@
   bool PhonyTarget;
   bool AddMissingHeaderDeps;
   bool SeenMissingHeader;
+  bool IncludeModuleFiles;
 private:
   bool FileMatchesDepCriteria(const char *Filename,
                               SrcMgr::CharacteristicKind FileType);
-  void AddFilename(StringRef Filename);
   void OutputDependencyFile();
 
 public:
-  DependencyFileCallback(const Preprocessor *_PP,
-                         const DependencyOutputOptions &Opts)
+  DFGImpl(const Preprocessor *_PP, const DependencyOutputOptions &Opts)
     : PP(_PP), OutputFile(Opts.OutputFile), Targets(Opts.Targets),
       IncludeSystemHeaders(Opts.IncludeSystemHeaders),
       PhonyTarget(Opts.UsePhonyTargets),
       AddMissingHeaderDeps(Opts.AddMissingHeaderDeps),
-      SeenMissingHeader(false) {}
+      SeenMissingHeader(false),
+      IncludeModuleFiles(Opts.IncludeModuleFiles) {}
 
-  virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
-                           SrcMgr::CharacteristicKind FileType,
-                           FileID PrevFID);
-  virtual void InclusionDirective(SourceLocation HashLoc,
-                                  const Token &IncludeTok,
-                                  StringRef FileName,
-                                  bool IsAngled,
-                                  CharSourceRange FilenameRange,
-                                  const FileEntry *File,
-                                  StringRef SearchPath,
-                                  StringRef RelativePath,
-                                  const Module *Imported);
+  void FileChanged(SourceLocation Loc, FileChangeReason Reason,
+                   SrcMgr::CharacteristicKind FileType,
+                   FileID PrevFID) override;
+  void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
+                          StringRef FileName, bool IsAngled,
+                          CharSourceRange FilenameRange, const FileEntry *File,
+                          StringRef SearchPath, StringRef RelativePath,
+                          const Module *Imported) override;
 
-  virtual void EndOfMainFile() {
+  void EndOfMainFile() override {
     OutputDependencyFile();
   }
+
+  void AddFilename(StringRef Filename);
+  bool includeSystemHeaders() const { return IncludeSystemHeaders; }
+  bool includeModuleFiles() const { return IncludeModuleFiles; }
+};
+
+class DFGASTReaderListener : public ASTReaderListener {
+  DFGImpl &Parent;
+public:
+  DFGASTReaderListener(DFGImpl &Parent)
+  : Parent(Parent) { }
+  bool needsInputFileVisitation() override { return true; }
+  bool needsSystemInputFileVisitation() override {
+    return Parent.includeSystemHeaders();
+  }
+  void visitModuleFile(StringRef Filename) override;
+  bool visitInputFile(StringRef Filename, bool isSystem,
+                      bool isOverridden) override;
 };
 }
 
-void clang::AttachDependencyFileGen(Preprocessor &PP,
-                                    const DependencyOutputOptions &Opts) {
+DependencyFileGenerator::DependencyFileGenerator(void *Impl)
+: Impl(Impl) { }
+
+DependencyFileGenerator *DependencyFileGenerator::CreateAndAttachToPreprocessor(
+    clang::Preprocessor &PP, const clang::DependencyOutputOptions &Opts) {
+
   if (Opts.Targets.empty()) {
     PP.getDiagnostics().Report(diag::err_fe_dependency_file_requires_MT);
-    return;
+    return nullptr;
   }
 
   // Disable the "file not found" diagnostic if the -MG option was given.
   if (Opts.AddMissingHeaderDeps)
     PP.SetSuppressIncludeNotFoundError(true);
 
-  PP.addPPCallbacks(new DependencyFileCallback(&PP, Opts));
+  DFGImpl *Callback = new DFGImpl(&PP, Opts);
+  PP.addPPCallbacks(Callback); // PP owns the Callback
+  return new DependencyFileGenerator(Callback);
+}
+
+void DependencyFileGenerator::AttachToASTReader(ASTReader &R) {
+  DFGImpl *I = reinterpret_cast<DFGImpl *>(Impl);
+  assert(I && "missing implementation");
+  R.addListener(new DFGASTReaderListener(*I));
 }
 
 /// FileMatchesDepCriteria - Determine whether the given Filename should be
 /// considered as a dependency.
-bool DependencyFileCallback::FileMatchesDepCriteria(const char *Filename,
-                                          SrcMgr::CharacteristicKind FileType) {
+bool DFGImpl::FileMatchesDepCriteria(const char *Filename,
+                                     SrcMgr::CharacteristicKind FileType) {
   if (strcmp("<built-in>", Filename) == 0)
     return false;
 
@@ -99,10 +226,10 @@
   return FileType == SrcMgr::C_User;
 }
 
-void DependencyFileCallback::FileChanged(SourceLocation Loc,
-                                         FileChangeReason Reason,
-                                         SrcMgr::CharacteristicKind FileType,
-                                         FileID PrevFID) {
+void DFGImpl::FileChanged(SourceLocation Loc,
+                          FileChangeReason Reason,
+                          SrcMgr::CharacteristicKind FileType,
+                          FileID PrevFID) {
   if (Reason != PPCallbacks::EnterFile)
     return;
 
@@ -113,7 +240,7 @@
 
   const FileEntry *FE =
     SM.getFileEntryForID(SM.getFileID(SM.getExpansionLoc(Loc)));
-  if (FE == 0) return;
+  if (!FE) return;
 
   StringRef Filename = FE->getName();
   if (!FileMatchesDepCriteria(Filename.data(), FileType))
@@ -130,15 +257,15 @@
   AddFilename(Filename);
 }
 
-void DependencyFileCallback::InclusionDirective(SourceLocation HashLoc,
-                                                const Token &IncludeTok,
-                                                StringRef FileName,
-                                                bool IsAngled,
-                                                CharSourceRange FilenameRange,
-                                                const FileEntry *File,
-                                                StringRef SearchPath,
-                                                StringRef RelativePath,
-                                                const Module *Imported) {
+void DFGImpl::InclusionDirective(SourceLocation HashLoc,
+                                 const Token &IncludeTok,
+                                 StringRef FileName,
+                                 bool IsAngled,
+                                 CharSourceRange FilenameRange,
+                                 const FileEntry *File,
+                                 StringRef SearchPath,
+                                 StringRef RelativePath,
+                                 const Module *Imported) {
   if (!File) {
     if (AddMissingHeaderDeps)
       AddFilename(FileName);
@@ -147,7 +274,7 @@
   }
 }
 
-void DependencyFileCallback::AddFilename(StringRef Filename) {
+void DFGImpl::AddFilename(StringRef Filename) {
   if (FilesSet.insert(Filename))
     Files.push_back(Filename);
 }
@@ -164,15 +291,14 @@
   }
 }
 
-void DependencyFileCallback::OutputDependencyFile() {
+void DFGImpl::OutputDependencyFile() {
   if (SeenMissingHeader) {
-    bool existed;
-    llvm::sys::fs::remove(OutputFile, existed);
+    llvm::sys::fs::remove(OutputFile);
     return;
   }
 
   std::string Err;
-  llvm::raw_fd_ostream OS(OutputFile.c_str(), Err);
+  llvm::raw_fd_ostream OS(OutputFile.c_str(), Err, llvm::sys::fs::F_Text);
   if (!Err.empty()) {
     PP->getDiagnostics().Report(diag::err_fe_error_opening)
       << OutputFile << Err;
@@ -235,3 +361,17 @@
   }
 }
 
+bool DFGASTReaderListener::visitInputFile(llvm::StringRef Filename,
+                                          bool IsSystem, bool IsOverridden) {
+  assert(!IsSystem || needsSystemInputFileVisitation());
+  if (IsOverridden)
+    return true;
+
+  Parent.AddFilename(Filename);
+  return true;
+}
+
+void DFGASTReaderListener::visitModuleFile(llvm::StringRef Filename) {
+  if (Parent.includeModuleFiles())
+    Parent.AddFilename(Filename);
+}
diff --git a/lib/Frontend/DependencyGraph.cpp b/lib/Frontend/DependencyGraph.cpp
index e128d91..051b7f9 100644
--- a/lib/Frontend/DependencyGraph.cpp
+++ b/lib/Frontend/DependencyGraph.cpp
@@ -46,17 +46,13 @@
                           StringRef SysRoot)
     : PP(_PP), OutputFile(OutputFile.str()), SysRoot(SysRoot.str()) { }
 
-  virtual void InclusionDirective(SourceLocation HashLoc,
-                                  const Token &IncludeTok,
-                                  StringRef FileName,
-                                  bool IsAngled,
-                                  CharSourceRange FilenameRange,
-                                  const FileEntry *File,
-                                  StringRef SearchPath,
-                                  StringRef RelativePath,
-                                  const Module *Imported);
+  void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
+                          StringRef FileName, bool IsAngled,
+                          CharSourceRange FilenameRange, const FileEntry *File,
+                          StringRef SearchPath, StringRef RelativePath,
+                          const Module *Imported) override;
 
-  virtual void EndOfMainFile() {
+  void EndOfMainFile() override {
     OutputGraphFile();
   }
   
@@ -83,7 +79,7 @@
   SourceManager &SM = PP->getSourceManager();
   const FileEntry *FromFile
     = SM.getFileEntryForID(SM.getFileID(SM.getExpansionLoc(HashLoc)));
-  if (FromFile == 0) 
+  if (!FromFile)
     return;
 
   Dependencies[FromFile].push_back(File);
@@ -101,7 +97,7 @@
 
 void DependencyGraphCallback::OutputGraphFile() {
   std::string Err;
-  llvm::raw_fd_ostream OS(OutputFile.c_str(), Err);
+  llvm::raw_fd_ostream OS(OutputFile.c_str(), Err, llvm::sys::fs::F_Text);
   if (!Err.empty()) {
     PP->getDiagnostics().Report(diag::err_fe_error_opening)
       << OutputFile << Err;
diff --git a/lib/Frontend/DiagnosticRenderer.cpp b/lib/Frontend/DiagnosticRenderer.cpp
index 4eee595..cff32b8 100644
--- a/lib/Frontend/DiagnosticRenderer.cpp
+++ b/lib/Frontend/DiagnosticRenderer.cpp
@@ -79,10 +79,10 @@
 public:
   FixitReceiver(SmallVectorImpl<FixItHint> &MergedFixits)
     : MergedFixits(MergedFixits) { }
-  virtual void insert(SourceLocation loc, StringRef text) {
+  void insert(SourceLocation loc, StringRef text) override {
     MergedFixits.push_back(FixItHint::CreateInsertion(loc, text));
   }
-  virtual void replace(CharSourceRange range, StringRef text) {
+  void replace(CharSourceRange range, StringRef text) override {
     MergedFixits.push_back(FixItHint::CreateReplacement(range, text));
   }
 };
@@ -186,10 +186,16 @@
   emitDiagnostic(Diag.getLocation(), Diag.getLevel(), Diag.getMessage(),
                  Diag.getRanges(), Diag.getFixIts(),
                  Diag.getLocation().isValid() ? &Diag.getLocation().getManager()
-                                              : 0,
+                                              : nullptr,
                  &Diag);
 }
 
+void DiagnosticRenderer::emitBasicNote(StringRef Message) {
+  emitDiagnosticMessage(
+      SourceLocation(), PresumedLoc(), DiagnosticsEngine::Note, Message,
+      ArrayRef<CharSourceRange>(), nullptr, DiagOrStoredDiag());
+}
+
 /// \brief Prints an include stack when appropriate for a particular
 /// diagnostic level and location.
 ///
@@ -499,12 +505,10 @@
   // Generate a note indicating the include location.
   SmallString<200> MessageStorage;
   llvm::raw_svector_ostream Message(MessageStorage);
-  Message << "while building module '" << ModuleName << "' imported from "
-          << PLoc.getFilename() << ':' << PLoc.getLine() << ":";
+  if (PLoc.getFilename())
+    Message << "while building module '" << ModuleName << "' imported from "
+            << PLoc.getFilename() << ':' << PLoc.getLine() << ":";
+  else
+    Message << "while building module '" << ModuleName << ":";
   emitNote(Loc, Message.str(), &SM);
 }
-
-
-void DiagnosticNoteRenderer::emitBasicNote(StringRef Message) {
-  emitNote(SourceLocation(), Message, 0);  
-}
diff --git a/lib/Frontend/FrontendAction.cpp b/lib/Frontend/FrontendAction.cpp
index 075fe93..7910179 100644
--- a/lib/Frontend/FrontendAction.cpp
+++ b/lib/Frontend/FrontendAction.cpp
@@ -12,12 +12,12 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclGroup.h"
 #include "clang/Frontend/ASTUnit.h"
-#include "clang/Frontend/ChainedIncludesSource.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/FrontendDiagnostic.h"
 #include "clang/Frontend/FrontendPluginRegistry.h"
 #include "clang/Frontend/LayoutOverrideSource.h"
 #include "clang/Frontend/MultiplexConsumer.h"
+#include "clang/Frontend/Utils.h"
 #include "clang/Lex/HeaderSearch.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Parse/ParseAST.h"
@@ -29,42 +29,49 @@
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Timer.h"
 #include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/system_error.h"
+#include <system_error>
 using namespace clang;
 
+template class llvm::Registry<clang::PluginASTAction>;
+
 namespace {
 
 class DelegatingDeserializationListener : public ASTDeserializationListener {
   ASTDeserializationListener *Previous;
+  bool DeletePrevious;
 
 public:
   explicit DelegatingDeserializationListener(
-                                           ASTDeserializationListener *Previous)
-    : Previous(Previous) { }
+      ASTDeserializationListener *Previous, bool DeletePrevious)
+      : Previous(Previous), DeletePrevious(DeletePrevious) {}
+  virtual ~DelegatingDeserializationListener() {
+    if (DeletePrevious)
+      delete Previous;
+  }
 
-  virtual void ReaderInitialized(ASTReader *Reader) {
+  void ReaderInitialized(ASTReader *Reader) override {
     if (Previous)
       Previous->ReaderInitialized(Reader);
   }
-  virtual void IdentifierRead(serialization::IdentID ID,
-                              IdentifierInfo *II) {
+  void IdentifierRead(serialization::IdentID ID,
+                      IdentifierInfo *II) override {
     if (Previous)
       Previous->IdentifierRead(ID, II);
   }
-  virtual void TypeRead(serialization::TypeIdx Idx, QualType T) {
+  void TypeRead(serialization::TypeIdx Idx, QualType T) override {
     if (Previous)
       Previous->TypeRead(Idx, T);
   }
-  virtual void DeclRead(serialization::DeclID ID, const Decl *D) {
+  void DeclRead(serialization::DeclID ID, const Decl *D) override {
     if (Previous)
       Previous->DeclRead(ID, D);
   }
-  virtual void SelectorRead(serialization::SelectorID ID, Selector Sel) {
+  void SelectorRead(serialization::SelectorID ID, Selector Sel) override {
     if (Previous)
       Previous->SelectorRead(ID, Sel);
   }
-  virtual void MacroDefinitionRead(serialization::PreprocessedEntityID PPID, 
-                                   MacroDefinition *MD) {
+  void MacroDefinitionRead(serialization::PreprocessedEntityID PPID,
+                           MacroDefinition *MD) override {
     if (Previous)
       Previous->MacroDefinitionRead(PPID, MD);
   }
@@ -73,10 +80,11 @@
 /// \brief Dumps deserialized declarations.
 class DeserializedDeclsDumper : public DelegatingDeserializationListener {
 public:
-  explicit DeserializedDeclsDumper(ASTDeserializationListener *Previous)
-    : DelegatingDeserializationListener(Previous) { }
+  explicit DeserializedDeclsDumper(ASTDeserializationListener *Previous,
+                                   bool DeletePrevious)
+      : DelegatingDeserializationListener(Previous, DeletePrevious) {}
 
-  virtual void DeclRead(serialization::DeclID ID, const Decl *D) {
+  void DeclRead(serialization::DeclID ID, const Decl *D) override {
     llvm::outs() << "PCH DECL: " << D->getDeclKindName();
     if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
       llvm::outs() << " - " << *ND;
@@ -95,11 +103,12 @@
 public:
   DeserializedDeclsChecker(ASTContext &Ctx,
                            const std::set<std::string> &NamesToCheck,
-                           ASTDeserializationListener *Previous)
-    : DelegatingDeserializationListener(Previous),
-      Ctx(Ctx), NamesToCheck(NamesToCheck) { }
+                           ASTDeserializationListener *Previous,
+                           bool DeletePrevious)
+      : DelegatingDeserializationListener(Previous, DeletePrevious), Ctx(Ctx),
+        NamesToCheck(NamesToCheck) {}
 
-  virtual void DeclRead(serialization::DeclID ID, const Decl *D) {
+  void DeclRead(serialization::DeclID ID, const Decl *D) override {
     if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
       if (NamesToCheck.find(ND->getNameAsString()) != NamesToCheck.end()) {
         unsigned DiagID
@@ -115,7 +124,7 @@
 
 } // end anonymous namespace
 
-FrontendAction::FrontendAction() : Instance(0) {}
+FrontendAction::FrontendAction() : Instance(nullptr) {}
 
 FrontendAction::~FrontendAction() {}
 
@@ -129,7 +138,7 @@
                                                       StringRef InFile) {
   ASTConsumer* Consumer = CreateASTConsumer(CI, InFile);
   if (!Consumer)
-    return 0;
+    return nullptr;
 
   if (CI.getFrontendOpts().AddPluginActions.size() == 0)
     return Consumer;
@@ -147,7 +156,7 @@
         ie = FrontendPluginRegistry::end();
         it != ie; ++it) {
       if (it->getName() == CI.getFrontendOpts().AddPluginActions[i]) {
-        OwningPtr<PluginASTAction> P(it->instantiate());
+        std::unique_ptr<PluginASTAction> P(it->instantiate());
         FrontendAction* c = P.get();
         if (P->ParseArgs(CI, CI.getFrontendOpts().AddPluginArgs[i]))
           Consumers.push_back(c->CreateASTConsumer(CI, InFile));
@@ -158,7 +167,6 @@
   return new MultiplexConsumer(Consumers);
 }
 
-
 bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
                                      const FrontendInputFile &Input) {
   assert(!Instance && "Already processing a source file!");
@@ -180,7 +188,7 @@
            "This action does not have AST file support!");
 
     IntrusiveRefCntPtr<DiagnosticsEngine> Diags(&CI.getDiagnostics());
-    std::string Error;
+
     ASTUnit *AST = ASTUnit::LoadFromASTFile(InputFile, Diags,
                                             CI.getFileSystemOpts());
     if (!AST)
@@ -189,7 +197,7 @@
     setCurrentInput(Input, AST);
 
     // Inform the diagnostic client we are processing a source file.
-    CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), 0);
+    CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), nullptr);
     HasBegunSourceFile = true;
 
     // Set the shared objects, these are reset when we finish processing the
@@ -211,6 +219,15 @@
     return true;
   }
 
+  if (!CI.hasVirtualFileSystem()) {
+    if (IntrusiveRefCntPtr<vfs::FileSystem> VFS =
+          createVFSFromCompilerInvocation(CI.getInvocation(),
+                                          CI.getDiagnostics()))
+      CI.setVirtualFileSystem(VFS);
+    else
+      goto failure;
+  }
+
   // Set up the file and source managers, if needed.
   if (!CI.hasFileManager())
     CI.createFileManager();
@@ -223,13 +240,17 @@
            "This action does not have IR file support!");
 
     // Inform the diagnostic client we are processing a source file.
-    CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), 0);
+    CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), nullptr);
     HasBegunSourceFile = true;
 
     // Initialize the action.
     if (!BeginSourceFileAction(CI, InputFile))
       goto failure;
 
+    // Initialize the main file entry.
+    if (!CI.InitializeSourceManager(CurrentInput))
+      goto failure;
+
     return true;
   }
 
@@ -240,7 +261,7 @@
     PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();
     StringRef PCHInclude = PPOpts.ImplicitPCHInclude;
     if (const DirectoryEntry *PCHDir = FileMgr.getDirectory(PCHInclude)) {
-      llvm::error_code EC;
+      std::error_code EC;
       SmallString<128> DirNative;
       llvm::sys::path::native(PCHDir->getName(), DirNative);
       bool Found = false;
@@ -265,7 +286,7 @@
   }
 
   // Set up the preprocessor.
-  CI.createPreprocessor();
+  CI.createPreprocessor(getTranslationUnitKind());
 
   // Inform the diagnostic client we are processing a source file.
   CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(),
@@ -276,13 +297,18 @@
   if (!BeginSourceFileAction(CI, InputFile))
     goto failure;
 
+  // Initialize the main file entry. It is important that this occurs after
+  // BeginSourceFileAction, which may change CurrentInput during module builds.
+  if (!CI.InitializeSourceManager(CurrentInput))
+    goto failure;
+
   // Create the AST context and consumer unless this is a preprocessor only
   // action.
   if (!usesPreprocessorOnly()) {
     CI.createASTContext();
 
-    OwningPtr<ASTConsumer> Consumer(
-                                   CreateWrappedASTConsumer(CI, InputFile));
+    std::unique_ptr<ASTConsumer> Consumer(
+        CreateWrappedASTConsumer(CI, InputFile));
     if (!Consumer)
       goto failure;
 
@@ -290,35 +316,40 @@
     
     if (!CI.getPreprocessorOpts().ChainedIncludes.empty()) {
       // Convert headers to PCH and chain them.
-      OwningPtr<ExternalASTSource> source;
-      source.reset(ChainedIncludesSource::create(CI));
+      IntrusiveRefCntPtr<ExternalSemaSource> source, FinalReader;
+      source = createChainedIncludesSource(CI, FinalReader);
       if (!source)
         goto failure;
-      CI.setModuleManager(static_cast<ASTReader*>(
-         &static_cast<ChainedIncludesSource*>(source.get())->getFinalReader()));
+      CI.setModuleManager(static_cast<ASTReader *>(FinalReader.get()));
       CI.getASTContext().setExternalSource(source);
-
     } else if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
       // Use PCH.
       assert(hasPCHSupport() && "This action does not have PCH support!");
       ASTDeserializationListener *DeserialListener =
           Consumer->GetASTDeserializationListener();
-      if (CI.getPreprocessorOpts().DumpDeserializedPCHDecls)
-        DeserialListener = new DeserializedDeclsDumper(DeserialListener);
-      if (!CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn.empty())
-        DeserialListener = new DeserializedDeclsChecker(CI.getASTContext(),
-                         CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn,
-                                                        DeserialListener);
+      bool DeleteDeserialListener = false;
+      if (CI.getPreprocessorOpts().DumpDeserializedPCHDecls) {
+        DeserialListener = new DeserializedDeclsDumper(DeserialListener,
+                                                       DeleteDeserialListener);
+        DeleteDeserialListener = true;
+      }
+      if (!CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn.empty()) {
+        DeserialListener = new DeserializedDeclsChecker(
+            CI.getASTContext(),
+            CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn,
+            DeserialListener, DeleteDeserialListener);
+        DeleteDeserialListener = true;
+      }
       CI.createPCHExternalASTSource(
-                                CI.getPreprocessorOpts().ImplicitPCHInclude,
-                                CI.getPreprocessorOpts().DisablePCHValidation,
-                            CI.getPreprocessorOpts().AllowPCHWithCompilerErrors,
-                                DeserialListener);
+          CI.getPreprocessorOpts().ImplicitPCHInclude,
+          CI.getPreprocessorOpts().DisablePCHValidation,
+          CI.getPreprocessorOpts().AllowPCHWithCompilerErrors, DeserialListener,
+          DeleteDeserialListener);
       if (!CI.getASTContext().getExternalSource())
         goto failure;
     }
 
-    CI.setASTConsumer(Consumer.take());
+    CI.setASTConsumer(Consumer.release());
     if (!CI.hasASTConsumer())
       goto failure;
   }
@@ -327,50 +358,56 @@
   // source.
   if (!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 {
+    // FIXME: If this is a problem, recover from it by creating a multiplex
+    // source.
+    assert((!CI.getLangOpts().Modules || CI.getModuleManager()) &&
+           "modules enabled but created an external source that "
+           "doesn't support modules");
   }
 
   // If there is a layout overrides file, attach an external AST source that
   // provides the layouts from that file.
   if (!CI.getFrontendOpts().OverrideRecordLayoutsFile.empty() && 
       CI.hasASTContext() && !CI.getASTContext().getExternalSource()) {
-    OwningPtr<ExternalASTSource> 
+    IntrusiveRefCntPtr<ExternalASTSource> 
       Override(new LayoutOverrideSource(
                      CI.getFrontendOpts().OverrideRecordLayoutsFile));
     CI.getASTContext().setExternalSource(Override);
   }
-  
+
   return true;
 
   // If we failed, reset state since the client will not end up calling the
   // matching EndSourceFile().
   failure:
   if (isCurrentFileAST()) {
-    CI.setASTContext(0);
-    CI.setPreprocessor(0);
-    CI.setSourceManager(0);
-    CI.setFileManager(0);
+    CI.setASTContext(nullptr);
+    CI.setPreprocessor(nullptr);
+    CI.setSourceManager(nullptr);
+    CI.setFileManager(nullptr);
   }
 
   if (HasBegunSourceFile)
     CI.getDiagnosticClient().EndSourceFile();
   CI.clearOutputFiles(/*EraseFiles=*/true);
   setCurrentInput(FrontendInputFile());
-  setCompilerInstance(0);
+  setCompilerInstance(nullptr);
   return false;
 }
 
 bool FrontendAction::Execute() {
   CompilerInstance &CI = getCompilerInstance();
 
-  // Initialize the main file entry. This needs to be delayed until after PCH
-  // has loaded.
-  if (!isCurrentFileAST()) {
-    if (!CI.InitializeSourceManager(getCurrentInput()))
-      return false;
-  }
-
   if (CI.hasFrontendTimer()) {
     llvm::TimeRegion Timer(CI.getFrontendTimer());
     ExecuteAction();
@@ -398,22 +435,22 @@
   // Finalize the action.
   EndSourceFileAction();
 
-  // Release the consumer and the AST, in that order since the consumer may
-  // perform actions in its destructor which require the context.
+  // Sema references the ast consumer, so reset sema first.
   //
   // FIXME: There is more per-file stuff we could just drop here?
-  if (CI.getFrontendOpts().DisableFree) {
-    CI.takeASTConsumer();
+  bool DisableFree = CI.getFrontendOpts().DisableFree;
+  if (DisableFree) {
     if (!isCurrentFileAST()) {
-      CI.takeSema();
+      CI.resetAndLeakSema();
       CI.resetAndLeakASTContext();
     }
+    BuryPointer(CI.takeASTConsumer());
   } else {
     if (!isCurrentFileAST()) {
-      CI.setSema(0);
-      CI.setASTContext(0);
+      CI.setSema(nullptr);
+      CI.setASTContext(nullptr);
     }
-    CI.setASTConsumer(0);
+    CI.setASTConsumer(nullptr);
   }
 
   // Inform the preprocessor we are done.
@@ -433,15 +470,16 @@
   // FrontendAction.
   CI.clearOutputFiles(/*EraseFiles=*/shouldEraseOutputFiles());
 
+  // FIXME: Only do this if DisableFree is set.
   if (isCurrentFileAST()) {
-    CI.takeSema();
+    CI.resetAndLeakSema();
     CI.resetAndLeakASTContext();
     CI.resetAndLeakPreprocessor();
     CI.resetAndLeakSourceManager();
     CI.resetAndLeakFileManager();
   }
 
-  setCompilerInstance(0);
+  setCompilerInstance(nullptr);
   setCurrentInput(FrontendInputFile());
 }
 
@@ -465,7 +503,7 @@
     CI.createCodeCompletionConsumer();
 
   // Use a code completion consumer?
-  CodeCompleteConsumer *CompletionConsumer = 0;
+  CodeCompleteConsumer *CompletionConsumer = nullptr;
   if (CI.hasCodeCompletionConsumer())
     CompletionConsumer = &CI.getCodeCompletionConsumer();
 
diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp
index a3ab1be..6dcaf38 100644
--- a/lib/Frontend/FrontendActions.cpp
+++ b/lib/Frontend/FrontendActions.cpp
@@ -21,11 +21,11 @@
 #include "clang/Parse/Parser.h"
 #include "clang/Serialization/ASTReader.h"
 #include "clang/Serialization/ASTWriter.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/system_error.h"
+#include <memory>
+#include <system_error>
 
 using namespace clang;
 
@@ -49,7 +49,7 @@
                                                StringRef InFile) {
   if (raw_ostream *OS = CI.createDefaultOutputFile(false, InFile))
     return CreateASTPrinter(OS, CI.getFrontendOpts().ASTDumpFilter);
-  return 0;
+  return nullptr;
 }
 
 ASTConsumer *ASTDumpAction::CreateASTConsumer(CompilerInstance &CI,
@@ -77,13 +77,14 @@
                                                   StringRef InFile) {
   std::string Sysroot;
   std::string OutputFile;
-  raw_ostream *OS = 0;
+  raw_ostream *OS = nullptr;
   if (ComputeASTConsumerArguments(CI, InFile, Sysroot, OutputFile, OS))
-    return 0;
+    return nullptr;
 
   if (!CI.getFrontendOpts().RelocatablePCH)
     Sysroot.clear();
-  return new PCHGenerator(CI.getPreprocessor(), OutputFile, 0, Sysroot, OS);
+  return new PCHGenerator(CI.getPreprocessor(), OutputFile, nullptr, Sysroot,
+                          OS);
 }
 
 bool GeneratePCHAction::ComputeASTConsumerArguments(CompilerInstance &CI,
@@ -114,10 +115,10 @@
                                                      StringRef InFile) {
   std::string Sysroot;
   std::string OutputFile;
-  raw_ostream *OS = 0;
+  raw_ostream *OS = nullptr;
   if (ComputeASTConsumerArguments(CI, InFile, Sysroot, OutputFile, OS))
-    return 0;
-  
+    return nullptr;
+
   return new PCHGenerator(CI.getPreprocessor(), OutputFile, Module, 
                           Sysroot, OS);
 }
@@ -128,21 +129,38 @@
   return Includes;
 }
 
-static void addHeaderInclude(StringRef HeaderName,
-                             SmallVectorImpl<char> &Includes,
-                             const LangOptions &LangOpts) {
+static std::error_code addHeaderInclude(StringRef HeaderName,
+                                        SmallVectorImpl<char> &Includes,
+                                        const LangOptions &LangOpts,
+                                        bool IsExternC) {
+  if (IsExternC && LangOpts.CPlusPlus)
+    Includes += "extern \"C\" {\n";
   if (LangOpts.ObjC1)
     Includes += "#import \"";
   else
     Includes += "#include \"";
-  Includes += HeaderName;
+  // Use an absolute path for the include; there's no reason to think that
+  // a relative path will work (. might not be on our include path) or that
+  // it will find the same file.
+  if (llvm::sys::path::is_absolute(HeaderName)) {
+    Includes += HeaderName;
+  } else {
+    SmallString<256> Header = HeaderName;
+    if (std::error_code Err = llvm::sys::fs::make_absolute(Header))
+      return Err;
+    Includes += Header;
+  }
   Includes += "\"\n";
+  if (IsExternC && LangOpts.CPlusPlus)
+    Includes += "}\n";
+  return std::error_code();
 }
 
-static void addHeaderInclude(const FileEntry *Header,
-                             SmallVectorImpl<char> &Includes,
-                             const LangOptions &LangOpts) {
-  addHeaderInclude(Header->getName(), Includes, LangOpts);
+static std::error_code addHeaderInclude(const FileEntry *Header,
+                                        SmallVectorImpl<char> &Includes,
+                                        const LangOptions &LangOpts,
+                                        bool IsExternC) {
+  return addHeaderInclude(Header->getName(), Includes, LangOpts, IsExternC);
 }
 
 /// \brief Collect the set of header includes needed to construct the given 
@@ -152,20 +170,21 @@
 ///
 /// \param Includes Will be augmented with the set of \#includes or \#imports
 /// needed to load all of the named headers.
-static void collectModuleHeaderIncludes(const LangOptions &LangOpts,
-                                        FileManager &FileMgr,
-                                        ModuleMap &ModMap,
-                                        clang::Module *Module,
-                                        SmallVectorImpl<char> &Includes) {
+static std::error_code
+collectModuleHeaderIncludes(const LangOptions &LangOpts, FileManager &FileMgr,
+                            ModuleMap &ModMap, clang::Module *Module,
+                            SmallVectorImpl<char> &Includes) {
   // Don't collect any headers for unavailable modules.
   if (!Module->isAvailable())
-    return;
+    return std::error_code();
 
   // Add includes for each of these headers.
   for (unsigned I = 0, N = Module->NormalHeaders.size(); I != N; ++I) {
     const FileEntry *Header = Module->NormalHeaders[I];
     Module->addTopHeader(Header);
-    addHeaderInclude(Header, Includes, LangOpts);
+    if (std::error_code Err =
+            addHeaderInclude(Header, Includes, LangOpts, Module->IsExternC))
+      return Err;
   }
   // Note that Module->PrivateHeaders will not be a TopHeader.
 
@@ -173,11 +192,13 @@
     Module->addTopHeader(UmbrellaHeader);
     if (Module->Parent) {
       // Include the umbrella header for submodules.
-      addHeaderInclude(UmbrellaHeader, Includes, LangOpts);
+      if (std::error_code Err = addHeaderInclude(UmbrellaHeader, Includes,
+                                                 LangOpts, Module->IsExternC))
+        return Err;
     }
   } else if (const DirectoryEntry *UmbrellaDir = Module->getUmbrellaDir()) {
     // Add all of the headers we find in this subdirectory.
-    llvm::error_code EC;
+    std::error_code EC;
     SmallString<128> DirNative;
     llvm::sys::path::native(UmbrellaDir->getName(), DirNative);
     for (llvm::sys::fs::recursive_directory_iterator Dir(DirNative.str(), EC), 
@@ -193,21 +214,30 @@
       // If this header is marked 'unavailable' in this module, don't include 
       // it.
       if (const FileEntry *Header = FileMgr.getFile(Dir->path())) {
-        if (ModMap.isHeaderInUnavailableModule(Header))
+        if (ModMap.isHeaderUnavailableInModule(Header, Module))
           continue;
         Module->addTopHeader(Header);
       }
       
-      // Include this header umbrella header for submodules.
-      addHeaderInclude(Dir->path(), Includes, LangOpts);
+      // Include this header as part of the umbrella directory.
+      if (std::error_code Err = addHeaderInclude(Dir->path(), Includes,
+                                                 LangOpts, Module->IsExternC))
+        return Err;
     }
+
+    if (EC)
+      return EC;
   }
   
   // Recurse into submodules.
   for (clang::Module::submodule_iterator Sub = Module->submodule_begin(),
                                       SubEnd = Module->submodule_end();
        Sub != SubEnd; ++Sub)
-    collectModuleHeaderIncludes(LangOpts, FileMgr, ModMap, *Sub, Includes);
+    if (std::error_code Err = collectModuleHeaderIncludes(
+            LangOpts, FileMgr, ModMap, *Sub, Includes))
+      return Err;
+
+  return std::error_code();
 }
 
 bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI, 
@@ -234,7 +264,15 @@
     // map with a single module (the common case).
     return false;
   }
-  
+
+  // If we're being run from the command-line, the module build stack will not
+  // have been filled in yet, so complete it now in order to allow us to detect
+  // module cycles.
+  SourceManager &SourceMgr = CI.getSourceManager();
+  if (SourceMgr.getModuleBuildStack().empty())
+    SourceMgr.pushModuleBuildStack(CI.getLangOpts().CurrentModule,
+                                   FullSourceLoc(SourceLocation(), SourceMgr));
+
   // Dig out the module definition.
   Module = HS.lookupModule(CI.getLangOpts().CurrentModule, 
                            /*AllowSearch=*/false);
@@ -247,28 +285,51 @@
 
   // Check whether we can build this module at all.
   clang::Module::Requirement Requirement;
-  if (!Module->isAvailable(CI.getLangOpts(), CI.getTarget(), Requirement)) {
-    CI.getDiagnostics().Report(diag::err_module_unavailable)
-      << Module->getFullModuleName()
-      << Requirement.second << Requirement.first;
+  clang::Module::HeaderDirective MissingHeader;
+  if (!Module->isAvailable(CI.getLangOpts(), CI.getTarget(), Requirement,
+                           MissingHeader)) {
+    if (MissingHeader.FileNameLoc.isValid()) {
+      CI.getDiagnostics().Report(MissingHeader.FileNameLoc,
+                                 diag::err_module_header_missing)
+        << MissingHeader.IsUmbrella << MissingHeader.FileName;
+    } else {
+      CI.getDiagnostics().Report(diag::err_module_unavailable)
+        << Module->getFullModuleName()
+        << Requirement.second << Requirement.first;
+    }
 
     return false;
   }
 
+  if (!ModuleMapForUniquing)
+    ModuleMapForUniquing = ModuleMap;
+  Module->ModuleMap = ModuleMapForUniquing;
+  assert(Module->ModuleMap && "missing module map file");
+
   FileManager &FileMgr = CI.getFileManager();
 
   // Collect the set of #includes we need to build the module.
   SmallString<256> HeaderContents;
+  std::error_code Err = std::error_code();
   if (const FileEntry *UmbrellaHeader = Module->getUmbrellaHeader())
-    addHeaderInclude(UmbrellaHeader, HeaderContents, CI.getLangOpts());
-  collectModuleHeaderIncludes(CI.getLangOpts(), FileMgr,
-    CI.getPreprocessor().getHeaderSearchInfo().getModuleMap(),
-    Module, HeaderContents);
+    Err = addHeaderInclude(UmbrellaHeader, HeaderContents, CI.getLangOpts(),
+                           Module->IsExternC);
+  if (!Err)
+    Err = collectModuleHeaderIncludes(
+        CI.getLangOpts(), FileMgr,
+        CI.getPreprocessor().getHeaderSearchInfo().getModuleMap(), Module,
+        HeaderContents);
+
+  if (Err) {
+    CI.getDiagnostics().Report(diag::err_module_cannot_create_includes)
+      << Module->getFullModuleName() << Err.message();
+    return false;
+  }
 
   llvm::MemoryBuffer *InputBuffer =
       llvm::MemoryBuffer::getMemBufferCopy(HeaderContents,
                                            Module::getModuleInputBufferName());
-  // Ownership of InputBuffer will be transfered to the SourceManager.
+  // Ownership of InputBuffer will be transferred to the SourceManager.
   setCurrentInput(FrontendInputFile(InputBuffer, getCurrentFileKind(),
                                     Module->IsSystem));
   return true;
@@ -283,10 +344,9 @@
   // in the module cache.
   if (CI.getFrontendOpts().OutputFile.empty()) {
     HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();
-    SmallString<256> ModuleFileName(HS.getModuleCachePath());
-    llvm::sys::path::append(ModuleFileName, 
-                            CI.getLangOpts().CurrentModule + ".pcm");
-    CI.getFrontendOpts().OutputFile = ModuleFileName.str();
+    CI.getFrontendOpts().OutputFile =
+        HS.getModuleFileName(CI.getLangOpts().CurrentModule,
+                             ModuleMapForUniquing->getName());
   }
   
   // We use createOutputFile here because this is exposed via libclang, and we
@@ -313,6 +373,30 @@
   return new ASTConsumer();
 }
 
+ASTConsumer *VerifyPCHAction::CreateASTConsumer(CompilerInstance &CI,
+                                                StringRef InFile) {
+  return new ASTConsumer();
+}
+
+void VerifyPCHAction::ExecuteAction() {
+  CompilerInstance &CI = getCompilerInstance();
+  bool Preamble = CI.getPreprocessorOpts().PrecompiledPreambleBytes.first != 0;
+  const std::string &Sysroot = CI.getHeaderSearchOpts().Sysroot;
+  std::unique_ptr<ASTReader> Reader(
+      new ASTReader(CI.getPreprocessor(), CI.getASTContext(),
+                    Sysroot.empty() ? "" : Sysroot.c_str(),
+                    /*DisableValidation*/ false,
+                    /*AllowPCHWithCompilerErrors*/ false,
+                    /*AllowConfigurationMismatch*/ true,
+                    /*ValidateSystemInputs*/ true));
+
+  Reader->ReadAST(getCurrentFile(),
+                  Preamble ? serialization::MK_Preamble
+                           : serialization::MK_PCH,
+                  SourceLocation(),
+                  ASTReader::ARR_ConfigurationMismatch);
+}
+
 namespace {
   /// \brief AST reader listener that dumps module information for a module
   /// file.
@@ -325,7 +409,7 @@
 #define DUMP_BOOLEAN(Value, Text)                       \
     Out.indent(4) << Text << ": " << (Value? "Yes" : "No") << "\n"
 
-    virtual bool ReadFullVersionInformation(StringRef FullVersion) {
+    bool ReadFullVersionInformation(StringRef FullVersion) override {
       Out.indent(2)
         << "Generated by "
         << (FullVersion == getClangFullRepositoryVersion()? "this"
@@ -334,8 +418,15 @@
       return ASTReaderListener::ReadFullVersionInformation(FullVersion);
     }
 
-    virtual bool ReadLanguageOptions(const LangOptions &LangOpts,
-                                     bool Complain) {
+    void ReadModuleName(StringRef ModuleName) override {
+      Out.indent(2) << "Module name: " << ModuleName << "\n";
+    }
+    void ReadModuleMapFile(StringRef ModuleMapPath) override {
+      Out.indent(2) << "Module map file: " << ModuleMapPath << "\n";
+    }
+
+    bool ReadLanguageOptions(const LangOptions &LangOpts,
+                             bool Complain) override {
       Out.indent(2) << "Language options:\n";
 #define LANGOPT(Name, Bits, Default, Description) \
       DUMP_BOOLEAN(LangOpts.Name, Description);
@@ -350,14 +441,12 @@
       return false;
     }
 
-    virtual bool ReadTargetOptions(const TargetOptions &TargetOpts,
-                                   bool Complain) {
+    bool ReadTargetOptions(const TargetOptions &TargetOpts,
+                           bool Complain) override {
       Out.indent(2) << "Target options:\n";
       Out.indent(4) << "  Triple: " << TargetOpts.Triple << "\n";
       Out.indent(4) << "  CPU: " << TargetOpts.CPU << "\n";
       Out.indent(4) << "  ABI: " << TargetOpts.ABI << "\n";
-      Out.indent(4) << "  C++ ABI: " << TargetOpts.CXXABI << "\n";
-      Out.indent(4) << "  Linker version: " << TargetOpts.LinkerVersion << "\n";
 
       if (!TargetOpts.FeaturesAsWritten.empty()) {
         Out.indent(4) << "Target features:\n";
@@ -370,8 +459,28 @@
       return false;
     }
 
-    virtual bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
-                                         bool Complain) {
+    virtual bool
+    ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
+                          bool Complain) override {
+      Out.indent(2) << "Diagnostic options:\n";
+#define DIAGOPT(Name, Bits, Default) DUMP_BOOLEAN(DiagOpts->Name, #Name);
+#define ENUM_DIAGOPT(Name, Type, Bits, Default) \
+      Out.indent(4) << #Name << ": " << DiagOpts->get##Name() << "\n";
+#define VALUE_DIAGOPT(Name, Bits, Default) \
+      Out.indent(4) << #Name << ": " << DiagOpts->Name << "\n";
+#include "clang/Basic/DiagnosticOptions.def"
+
+      Out.indent(4) << "Diagnostic flags:\n";
+      for (const std::string &Warning : DiagOpts->Warnings)
+        Out.indent(6) << "-W" << Warning << "\n";
+      for (const std::string &Remark : DiagOpts->Remarks)
+        Out.indent(6) << "-R" << Remark << "\n";
+
+      return false;
+    }
+
+    bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
+                                 bool Complain) override {
       Out.indent(2) << "Header search options:\n";
       Out.indent(4) << "System root [-isysroot=]: '" << HSOpts.Sysroot << "'\n";
       DUMP_BOOLEAN(HSOpts.UseBuiltinIncludes,
@@ -385,9 +494,9 @@
       return false;
     }
 
-    virtual bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
-                                         bool Complain,
-                                         std::string &SuggestedPredefines) {
+    bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
+                                 bool Complain,
+                                 std::string &SuggestedPredefines) override {
       Out.indent(2) << "Preprocessor options:\n";
       DUMP_BOOLEAN(PPOpts.UsePredefines,
                    "Uses compiler/target-specific predefines [-undef]");
@@ -416,12 +525,12 @@
 
 void DumpModuleInfoAction::ExecuteAction() {
   // Set up the output file.
-  llvm::OwningPtr<llvm::raw_fd_ostream> OutFile;
+  std::unique_ptr<llvm::raw_fd_ostream> OutFile;
   StringRef OutputFileName = getCompilerInstance().getFrontendOpts().OutputFile;
   if (!OutputFileName.empty() && OutputFileName != "-") {
     std::string ErrorInfo;
     OutFile.reset(new llvm::raw_fd_ostream(OutputFileName.str().c_str(),
-                                           ErrorInfo));
+                                           ErrorInfo, llvm::sys::fs::F_Text));
   }
   llvm::raw_ostream &Out = OutFile.get()? *OutFile.get() : llvm::outs();
 
@@ -485,7 +594,7 @@
   Preprocessor &PP = getCompilerInstance().getPreprocessor();
 
   // Ignore unknown pragmas.
-  PP.AddPragmaHandler(new EmptyPragmaHandler());
+  PP.IgnorePragmas();
 
   Token Tok;
   // Start parsing the specified input file.
diff --git a/lib/Frontend/HeaderIncludeGen.cpp b/lib/Frontend/HeaderIncludeGen.cpp
index 237e5b1..a2f5896 100644
--- a/lib/Frontend/HeaderIncludeGen.cpp
+++ b/lib/Frontend/HeaderIncludeGen.cpp
@@ -40,23 +40,24 @@
       delete OutputFile;
   }
 
-  virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
-                           SrcMgr::CharacteristicKind FileType,
-                           FileID PrevFID);
+  void FileChanged(SourceLocation Loc, FileChangeReason Reason,
+                   SrcMgr::CharacteristicKind FileType,
+                   FileID PrevFID) override;
 };
 }
 
 void clang::AttachHeaderIncludeGen(Preprocessor &PP, bool ShowAllHeaders,
                                    StringRef OutputPath, bool ShowDepth,
                                    bool MSStyle) {
-  raw_ostream *OutputFile = &llvm::errs();
+  raw_ostream *OutputFile = MSStyle ? &llvm::outs() : &llvm::errs();
   bool OwnsOutputFile = false;
 
   // Open the output file, if used.
   if (!OutputPath.empty()) {
     std::string Error;
     llvm::raw_fd_ostream *OS = new llvm::raw_fd_ostream(
-        OutputPath.str().c_str(), Error, llvm::sys::fs::F_Append);
+        OutputPath.str().c_str(), Error,
+        llvm::sys::fs::F_Append | llvm::sys::fs::F_Text);
     if (!Error.empty()) {
       PP.getDiagnostics().Report(
         clang::diag::warn_fe_cc_print_header_failure) << Error;
@@ -130,5 +131,6 @@
     Msg += '\n';
 
     OutputFile->write(Msg.data(), Msg.size());
+    OutputFile->flush();
   }
 }
diff --git a/lib/Frontend/InitHeaderSearch.cpp b/lib/Frontend/InitHeaderSearch.cpp
index d144cbb..5f494aa 100644
--- a/lib/Frontend/InitHeaderSearch.cpp
+++ b/lib/Frontend/InitHeaderSearch.cpp
@@ -110,7 +110,7 @@
 }  // end anonymous namespace.
 
 static bool CanPrefixSysroot(StringRef Path) {
-#if defined(_WIN32)
+#if defined(LLVM_ON_WIN32)
   return !Path.empty() && llvm::sys::path::is_separator(Path[0]);
 #else
   return llvm::sys::path::is_absolute(Path);
@@ -231,6 +231,8 @@
     case llvm::Triple::NetBSD:
     case llvm::Triple::OpenBSD:
     case llvm::Triple::Bitrig:
+    case llvm::Triple::NaCl:    // @LOCALMOD
+
       break;
     default:
       // FIXME: temporary hack: hard-coded paths.
@@ -268,7 +270,6 @@
 
   switch (os) {
   case llvm::Triple::Linux:
-  case llvm::Triple::Win32:
     llvm_unreachable("Include management is handled in the driver.");
 
   case llvm::Triple::Haiku:
@@ -307,10 +308,13 @@
     break;
   case llvm::Triple::RTEMS:
     break;
-  case llvm::Triple::Cygwin:
-    AddPath("/usr/include/w32api", System, false);
-    break;
-  case llvm::Triple::MinGW32: { 
+  case llvm::Triple::Win32:
+    switch (triple.getEnvironment()) {
+    default: llvm_unreachable("Include management is handled in the driver.");
+    case llvm::Triple::Cygnus:
+      AddPath("/usr/include/w32api", System, false);
+      break;
+    case llvm::Triple::GNU:
       // mingw-w64 crt include paths
       // <sysroot>/i686-w64-mingw32/include
       SmallString<128> P = StringRef(HSOpts.ResourceDir);
@@ -328,17 +332,20 @@
       llvm::sys::path::append(P, "../../../include");
       AddPath(P.str(), System, false);
       AddPath("/mingw/include", System, false);
-#if defined(_WIN32)
+#if defined(LLVM_ON_WIN32)
       AddPath("c:/mingw/include", System, false); 
 #endif
+      break;
     }
     break;
-      
   default:
     break;
   }
 
-  if ( os != llvm::Triple::RTEMS )
+  // @LOCALMOD-BEGIN
+  // NaCl only uses toolchain provided headers.
+  if ( os != llvm::Triple::RTEMS && os != llvm::Triple::NaCl)
+  // @LOCALMOD-END
     AddPath("/usr/include", ExternCSystem, false);
 }
 
@@ -376,58 +383,58 @@
       AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1",
                                   "arm-apple-darwin10", "v6", "", triple);
       break;
+
+    case llvm::Triple::aarch64:
+    case llvm::Triple::arm64:
+      AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1",
+                                  "arm64-apple-darwin10", "", "", triple);
+      break;
     }
     return;
   }
 
   switch (os) {
   case llvm::Triple::Linux:
-  case llvm::Triple::Win32:
     llvm_unreachable("Include management is handled in the driver.");
 
-  case llvm::Triple::Cygwin:
-    // Cygwin-1.7
-    AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.7.3");
-    AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.5.3");
-    AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.3.4");
-    // g++-4 / Cygwin-1.5
-    AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.3.2");
-    break;
-  case llvm::Triple::MinGW32:
-    // mingw-w64 C++ include paths (i686-w64-mingw32 and x86_64-w64-mingw32)
-    AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.5.0");
-    AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.5.1");
-    AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.5.2");
-    AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.5.3");
-    AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.5.4");
-    AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.6.0");
-    AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.6.1");
-    AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.6.2");
-    AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.6.3");
-    AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.7.0");
-    // mingw.org C++ include paths
-    AddMinGWCPlusPlusIncludePaths("/mingw/lib/gcc", "mingw32", "4.5.2"); //MSYS
-#if defined(_WIN32)
-    AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.8.1");
-    AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.6.2");
-    AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.6.1");
-    AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.5.2");
-    AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.5.0");
-    AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.4.0");
-    AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.3.0");
+  case llvm::Triple::Win32:
+    switch (triple.getEnvironment()) {
+    default: llvm_unreachable("Include management is handled in the driver.");
+    case llvm::Triple::Cygnus:
+      // Cygwin-1.7
+      AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.7.3");
+      AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.5.3");
+      AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.3.4");
+      // g++-4 / Cygwin-1.5
+      AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.3.2");
+      break;
+    case llvm::Triple::GNU:
+      // mingw-w64 C++ include paths (i686-w64-mingw32 and x86_64-w64-mingw32)
+      AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.7.0");
+      AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.7.1");
+      AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.7.2");
+      AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.7.3");
+      AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.8.0");
+      AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.8.1");
+      AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.8.2");
+      // mingw.org C++ include paths
+#if defined(LLVM_ON_WIN32)
+      AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.7.0");
+      AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.7.1");
+      AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.7.2");
+      AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.7.3");
+      AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.8.0");
+      AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.8.1");
+      AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.8.2");
 #endif
-    break;
+      break;
+    }
   case llvm::Triple::DragonFly:
     if (llvm::sys::fs::exists("/usr/lib/gcc47"))
       AddPath("/usr/include/c++/4.7", CXXSystem, false);
     else
       AddPath("/usr/include/c++/4.4", CXXSystem, false);
     break;
-  case llvm::Triple::FreeBSD:
-    // FreeBSD 8.0
-    // FreeBSD 7.3
-    AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2", "", "", "", triple);
-    break;
   case llvm::Triple::OpenBSD: {
     std::string t = triple.getTriple();
     if (t.substr(0, 6) == "x86_64")
@@ -466,8 +473,14 @@
     break; // Everything else continues to use this routine's logic.
 
   case llvm::Triple::Linux:
-  case llvm::Triple::Win32:
     return;
+
+  case llvm::Triple::Win32:
+    if (triple.getEnvironment() == llvm::Triple::MSVC ||
+        triple.getEnvironment() == llvm::Triple::Itanium ||
+        triple.getObjectFormat() == llvm::Triple::MachO)
+      return;
+    break;
   }
 
   if (Lang.CPlusPlus && HSOpts.UseStandardCXXIncludes &&
diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp
index 77cf3b3..7a9d09a 100644
--- a/lib/Frontend/InitPreprocessor.cpp
+++ b/lib/Frontend/InitPreprocessor.cpp
@@ -86,7 +86,7 @@
                                   StringRef ImplicitIncludePTH) {
   PTHManager *P = PP.getPTHManager();
   // Null check 'P' in the corner case where it couldn't be created.
-  const char *OriginalFile = P ? P->getOriginalSourceFile() : 0;
+  const char *OriginalFile = P ? P->getOriginalSourceFile() : nullptr;
 
   if (!OriginalFile) {
     PP.getDiagnostics().Report(diag::err_fe_pth_file_has_no_source_header)
@@ -180,7 +180,7 @@
 /// DefineTypeSize - Emit a macro to the predefines buffer that declares a macro
 /// named MacroName with the max value for a type with width 'TypeWidth' a
 /// signedness of 'isSigned' and with a value suffix of 'ValSuffix' (e.g. LL).
-static void DefineTypeSize(StringRef MacroName, unsigned TypeWidth,
+static void DefineTypeSize(const Twine &MacroName, unsigned TypeWidth,
                            StringRef ValSuffix, bool isSigned,
                            MacroBuilder &Builder) {
   llvm::APInt MaxVal = isSigned ? llvm::APInt::getSignedMaxValue(TypeWidth)
@@ -190,12 +190,22 @@
 
 /// DefineTypeSize - An overloaded helper that uses TargetInfo to determine
 /// the width, suffix, and signedness of the given type
-static void DefineTypeSize(StringRef MacroName, TargetInfo::IntType Ty,
+static void DefineTypeSize(const Twine &MacroName, TargetInfo::IntType Ty,
                            const TargetInfo &TI, MacroBuilder &Builder) {
   DefineTypeSize(MacroName, TI.getTypeWidth(Ty), TI.getTypeConstantSuffix(Ty), 
                  TI.isTypeSigned(Ty), Builder);
 }
 
+static void DefineFmt(const Twine &Prefix, TargetInfo::IntType Ty,
+                      const TargetInfo &TI, MacroBuilder &Builder) {
+  bool IsSigned = TI.isTypeSigned(Ty);
+  StringRef FmtModifier = TI.getTypeFormatModifier(Ty);
+  for (const char *Fmt = IsSigned ? "di" : "ouxX"; *Fmt; ++Fmt) {
+    Builder.defineMacro(Prefix + "_FMT" + Twine(*Fmt) + "__",
+                        Twine("\"") + FmtModifier + Twine(*Fmt) + "\"");
+  }
+}
+
 static void DefineType(const Twine &MacroName, TargetInfo::IntType Ty,
                        MacroBuilder &Builder) {
   Builder.defineMacro(MacroName, TargetInfo::getTypeName(Ty));
@@ -212,23 +222,70 @@
                       Twine(BitWidth / TI.getCharWidth()));
 }
 
-static void DefineExactWidthIntType(TargetInfo::IntType Ty, 
-                               const TargetInfo &TI, MacroBuilder &Builder) {
+static void DefineExactWidthIntType(TargetInfo::IntType Ty,
+                                    const TargetInfo &TI,
+                                    MacroBuilder &Builder) {
   int TypeWidth = TI.getTypeWidth(Ty);
+  bool IsSigned = TI.isTypeSigned(Ty);
 
   // Use the target specified int64 type, when appropriate, so that [u]int64_t
   // ends up being defined in terms of the correct type.
   if (TypeWidth == 64)
-    Ty = TI.getInt64Type();
+    Ty = IsSigned ? TI.getInt64Type() : TI.getUInt64Type();
 
-  DefineType("__INT" + Twine(TypeWidth) + "_TYPE__", Ty, Builder);
+  const char *Prefix = IsSigned ? "__INT" : "__UINT";
 
-  StringRef ConstSuffix(TargetInfo::getTypeConstantSuffix(Ty));
-  if (!ConstSuffix.empty())
-    Builder.defineMacro("__INT" + Twine(TypeWidth) + "_C_SUFFIX__",
-                        ConstSuffix);
+  DefineType(Prefix + Twine(TypeWidth) + "_TYPE__", Ty, Builder);
+  DefineFmt(Prefix + Twine(TypeWidth), Ty, TI, Builder);
+
+  StringRef ConstSuffix(TI.getTypeConstantSuffix(Ty));
+  Builder.defineMacro(Prefix + Twine(TypeWidth) + "_C_SUFFIX__", ConstSuffix);
 }
 
+static void DefineExactWidthIntTypeSize(TargetInfo::IntType Ty,
+                                        const TargetInfo &TI,
+                                        MacroBuilder &Builder) {
+  int TypeWidth = TI.getTypeWidth(Ty);
+  bool IsSigned = TI.isTypeSigned(Ty);
+
+  // Use the target specified int64 type, when appropriate, so that [u]int64_t
+  // ends up being defined in terms of the correct type.
+  if (TypeWidth == 64)
+    Ty = IsSigned ? TI.getInt64Type() : TI.getUInt64Type();
+
+  const char *Prefix = IsSigned ? "__INT" : "__UINT";
+  DefineTypeSize(Prefix + Twine(TypeWidth) + "_MAX__", Ty, TI, Builder);
+}
+
+static void DefineLeastWidthIntType(unsigned TypeWidth, bool IsSigned,
+                                    const TargetInfo &TI,
+                                    MacroBuilder &Builder) {
+  TargetInfo::IntType Ty = TI.getLeastIntTypeByWidth(TypeWidth, IsSigned);
+  if (Ty == TargetInfo::NoInt)
+    return;
+
+  const char *Prefix = IsSigned ? "__INT_LEAST" : "__UINT_LEAST";
+  DefineType(Prefix + Twine(TypeWidth) + "_TYPE__", Ty, Builder);
+  DefineTypeSize(Prefix + Twine(TypeWidth) + "_MAX__", Ty, TI, Builder);
+  DefineFmt(Prefix + Twine(TypeWidth), Ty, TI, Builder);
+}
+
+static void DefineFastIntType(unsigned TypeWidth, bool IsSigned,
+                              const TargetInfo &TI, MacroBuilder &Builder) {
+  // stdint.h currently defines the fast int types as equivalent to the least
+  // types.
+  TargetInfo::IntType Ty = TI.getLeastIntTypeByWidth(TypeWidth, IsSigned);
+  if (Ty == TargetInfo::NoInt)
+    return;
+
+  const char *Prefix = IsSigned ? "__INT_FAST" : "__UINT_FAST";
+  DefineType(Prefix + Twine(TypeWidth) + "_TYPE__", Ty, Builder);
+  DefineTypeSize(Prefix + Twine(TypeWidth) + "_MAX__", Ty, TI, Builder);
+
+  DefineFmt(Prefix + Twine(TypeWidth), Ty, TI, Builder);
+}
+
+
 /// Get the value the ATOMIC_*_LOCK_FREE macro should have for a type with
 /// the specified properties.
 static const char *getLockFreeValue(unsigned TypeWidth, unsigned TypeAlign,
@@ -300,7 +357,7 @@
                                                const LangOptions &LangOpts,
                                                const FrontendOptions &FEOpts,
                                                MacroBuilder &Builder) {
-  if (!LangOpts.MicrosoftMode && !LangOpts.TraditionalCPP)
+  if (!LangOpts.MSVCCompat && !LangOpts.TraditionalCPP)
     Builder.defineMacro("__STDC__");
   if (LangOpts.Freestanding)
     Builder.defineMacro("__STDC_HOSTED__", "0");
@@ -315,9 +372,14 @@
     else if (!LangOpts.GNUMode && LangOpts.Digraphs)
       Builder.defineMacro("__STDC_VERSION__", "199409L");
   } else {
-    // FIXME: Use the right value for __cplusplus for C++1y once one is chosen.
-    if (LangOpts.CPlusPlus1y)
-      Builder.defineMacro("__cplusplus", "201305L");
+    // FIXME: Use correct value for C++17.
+    if (LangOpts.CPlusPlus1z)
+      Builder.defineMacro("__cplusplus", "201406L");
+    // C++1y [cpp.predefined]p1:
+    //   The name __cplusplus is defined to the value 201402L when compiling a
+    //   C++ translation unit.
+    else if (LangOpts.CPlusPlus1y)
+      Builder.defineMacro("__cplusplus", "201402L");
     // C++11 [cpp.predefined]p1:
     //   The name __cplusplus is defined to the value 201103L when compiling a
     //   C++ translation unit.
@@ -346,6 +408,38 @@
     Builder.defineMacro("__ASSEMBLER__");
 }
 
+/// Initialize the predefined C++ language feature test macros defined in
+/// ISO/IEC JTC1/SC22/WG21 (C++) SD-6: "SG10 Feature Test Recommendations".
+static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts,
+                                                 MacroBuilder &Builder) {
+  // C++11 features.
+  if (LangOpts.CPlusPlus11) {
+    Builder.defineMacro("__cpp_unicode_characters", "200704");
+    Builder.defineMacro("__cpp_raw_strings", "200710");
+    Builder.defineMacro("__cpp_unicode_literals", "200710");
+    Builder.defineMacro("__cpp_user_defined_literals", "200809");
+    Builder.defineMacro("__cpp_lambdas", "200907");
+    Builder.defineMacro("__cpp_constexpr",
+                        LangOpts.CPlusPlus1y ? "201304" : "200704");
+    Builder.defineMacro("__cpp_static_assert", "200410");
+    Builder.defineMacro("__cpp_decltype", "200707");
+    Builder.defineMacro("__cpp_attributes", "200809");
+    Builder.defineMacro("__cpp_rvalue_references", "200610");
+    Builder.defineMacro("__cpp_variadic_templates", "200704");
+  }
+
+  // C++14 features.
+  if (LangOpts.CPlusPlus1y) {
+    Builder.defineMacro("__cpp_binary_literals", "201304");
+    Builder.defineMacro("__cpp_init_captures", "201304");
+    Builder.defineMacro("__cpp_generic_lambdas", "201304");
+    Builder.defineMacro("__cpp_decltype_auto", "201304");
+    Builder.defineMacro("__cpp_return_type_deduction", "201304");
+    Builder.defineMacro("__cpp_aggregate_nsdmi", "201304");
+    Builder.defineMacro("__cpp_variable_templates", "201304");
+  }
+}
+
 static void InitializePredefinedMacros(const TargetInfo &TI,
                                        const LangOptions &LangOpts,
                                        const FrontendOptions &FEOpts,
@@ -367,7 +461,7 @@
                       + getClangFullRepositoryVersion() + "\"");
 #undef TOSTR
 #undef TOSTR2
-  if (!LangOpts.MicrosoftMode) {
+  if (!LangOpts.MSVCCompat) {
     // Currently claim to be compatible with GCC 4.2.1-5621, but only if we're
     // not compiling for MSVC compatibility
     Builder.defineMacro("__GNUC_MINOR__", "2");
@@ -396,10 +490,10 @@
   // Initialize language-specific preprocessor defines.
 
   // Standard conforming mode?
-  if (!LangOpts.GNUMode)
+  if (!LangOpts.GNUMode && !LangOpts.MSVCCompat)
     Builder.defineMacro("__STRICT_ANSI__");
 
-  if (LangOpts.CPlusPlus11)
+  if (!LangOpts.MSVCCompat && LangOpts.CPlusPlus11)
     Builder.defineMacro("__GXX_EXPERIMENTAL_CXX0X__");
 
   if (LangOpts.ObjC1) {
@@ -438,6 +532,9 @@
     Builder.defineMacro("IBAction", "void)__attribute__((ibaction)");
   }
 
+  if (LangOpts.CPlusPlus)
+    InitializeCPlusPlusFeatureTestMacros(LangOpts, Builder);
+
   // darwin_constant_cfstrings controls this. This is also dependent
   // on other things like the runtime I believe.  This is set even for C code.
   if (!LangOpts.NoConstantCFStrings)
@@ -454,9 +551,9 @@
     Builder.defineMacro("__BLOCKS__");
   }
 
-  if (LangOpts.CXXExceptions)
+  if (!LangOpts.MSVCCompat && LangOpts.CXXExceptions)
     Builder.defineMacro("__EXCEPTIONS");
-  if (LangOpts.RTTI)
+  if (!LangOpts.MSVCCompat && LangOpts.RTTI)
     Builder.defineMacro("__GXX_RTTI");
   if (LangOpts.SjLjExceptions)
     Builder.defineMacro("__USING_SJLJ_EXCEPTIONS__");
@@ -464,27 +561,18 @@
   if (LangOpts.Deprecated)
     Builder.defineMacro("__DEPRECATED");
 
-  if (LangOpts.CPlusPlus) {
+  if (!LangOpts.MSVCCompat && LangOpts.CPlusPlus) {
     Builder.defineMacro("__GNUG__", "4");
     Builder.defineMacro("__GXX_WEAK__");
     Builder.defineMacro("__private_extern__", "extern");
   }
 
   if (LangOpts.MicrosoftExt) {
-    // Both __PRETTY_FUNCTION__ and __FUNCTION__ are GCC extensions, however
-    // VC++ appears to only like __FUNCTION__.
-    Builder.defineMacro("__PRETTY_FUNCTION__", "__FUNCTION__");
-    // Work around some issues with Visual C++ headers.
     if (LangOpts.WChar) {
       // wchar_t supported as a keyword.
       Builder.defineMacro("_WCHAR_T_DEFINED");
       Builder.defineMacro("_NATIVE_WCHAR_T_DEFINED");
     }
-    if (LangOpts.CPlusPlus) {
-      // FIXME: Support Microsoft's __identifier extension in the lexer.
-      Builder.append("#define __identifier(x) x");
-      Builder.append("class type_info;");
-    }
   }
 
   if (LangOpts.Optimize)
@@ -505,11 +593,13 @@
   Builder.defineMacro("__ORDER_LITTLE_ENDIAN__", "1234");
   Builder.defineMacro("__ORDER_BIG_ENDIAN__",    "4321");
   Builder.defineMacro("__ORDER_PDP_ENDIAN__",    "3412");
-  if (TI.isBigEndian())
+  if (TI.isBigEndian()) {
     Builder.defineMacro("__BYTE_ORDER__", "__ORDER_BIG_ENDIAN__");
-  else
+    Builder.defineMacro("__BIG_ENDIAN__");
+  } else {
     Builder.defineMacro("__BYTE_ORDER__", "__ORDER_LITTLE_ENDIAN__");
-
+    Builder.defineMacro("__LITTLE_ENDIAN__");
+  }
 
   if (TI.getPointerWidth(0) == 64 && TI.getLongWidth() == 64
       && TI.getIntWidth() == 32) {
@@ -517,6 +607,12 @@
     Builder.defineMacro("__LP64__");
   }
 
+  if (TI.getPointerWidth(0) == 32 && TI.getLongWidth() == 32
+      && TI.getIntWidth() == 32) {
+    Builder.defineMacro("_ILP32");
+    Builder.defineMacro("__ILP32__");
+  }
+
   // Define type sizing macros based on the target properties.
   assert(TI.getCharWidth() == 8 && "Only support 8-bit char so far");
   Builder.defineMacro("__CHAR_BIT__", "8");
@@ -530,6 +626,13 @@
   DefineTypeSize("__INTMAX_MAX__", TI.getIntMaxType(), TI, Builder);
   DefineTypeSize("__SIZE_MAX__", TI.getSizeType(), TI, Builder);
 
+  if (!LangOpts.MSVCCompat) {
+    DefineTypeSize("__UINTMAX_MAX__", TI.getUIntMaxType(), TI, Builder);
+    DefineTypeSize("__PTRDIFF_MAX__", TI.getPtrDiffType(0), TI, Builder);
+    DefineTypeSize("__INTPTR_MAX__", TI.getIntPtrType(), TI, Builder);
+    DefineTypeSize("__UINTPTR_MAX__", TI.getUIntPtrType(), TI, Builder);
+  }
+
   DefineTypeSizeof("__SIZEOF_DOUBLE__", TI.getDoubleWidth(), TI, Builder);
   DefineTypeSizeof("__SIZEOF_FLOAT__", TI.getFloatWidth(), TI, Builder);
   DefineTypeSizeof("__SIZEOF_INT__", TI.getIntWidth(), TI, Builder);
@@ -550,22 +653,39 @@
     DefineTypeSizeof("__SIZEOF_INT128__", 128, TI, Builder);
 
   DefineType("__INTMAX_TYPE__", TI.getIntMaxType(), Builder);
+  DefineFmt("__INTMAX", TI.getIntMaxType(), TI, Builder);
+  Builder.defineMacro("__INTMAX_C_SUFFIX__",
+                      TI.getTypeConstantSuffix(TI.getIntMaxType()));
   DefineType("__UINTMAX_TYPE__", TI.getUIntMaxType(), Builder);
+  DefineFmt("__UINTMAX", TI.getUIntMaxType(), TI, Builder);
+  Builder.defineMacro("__UINTMAX_C_SUFFIX__",
+                      TI.getTypeConstantSuffix(TI.getUIntMaxType()));
   DefineTypeWidth("__INTMAX_WIDTH__",  TI.getIntMaxType(), TI, Builder);
   DefineType("__PTRDIFF_TYPE__", TI.getPtrDiffType(0), Builder);
+  DefineFmt("__PTRDIFF", TI.getPtrDiffType(0), TI, Builder);
   DefineTypeWidth("__PTRDIFF_WIDTH__", TI.getPtrDiffType(0), TI, Builder);
   DefineType("__INTPTR_TYPE__", TI.getIntPtrType(), Builder);
+  DefineFmt("__INTPTR", TI.getIntPtrType(), TI, Builder);
   DefineTypeWidth("__INTPTR_WIDTH__", TI.getIntPtrType(), TI, Builder);
   DefineType("__SIZE_TYPE__", TI.getSizeType(), Builder);
+  DefineFmt("__SIZE", TI.getSizeType(), TI, Builder);
   DefineTypeWidth("__SIZE_WIDTH__", TI.getSizeType(), TI, Builder);
   DefineType("__WCHAR_TYPE__", TI.getWCharType(), Builder);
   DefineTypeWidth("__WCHAR_WIDTH__", TI.getWCharType(), TI, Builder);
   DefineType("__WINT_TYPE__", TI.getWIntType(), Builder);
   DefineTypeWidth("__WINT_WIDTH__", TI.getWIntType(), TI, Builder);
   DefineTypeWidth("__SIG_ATOMIC_WIDTH__", TI.getSigAtomicType(), TI, Builder);
+  DefineTypeSize("__SIG_ATOMIC_MAX__", TI.getSigAtomicType(), TI, Builder);
   DefineType("__CHAR16_TYPE__", TI.getChar16Type(), Builder);
   DefineType("__CHAR32_TYPE__", TI.getChar32Type(), Builder);
 
+  if (!LangOpts.MSVCCompat) {
+    DefineTypeWidth("__UINTMAX_WIDTH__",  TI.getUIntMaxType(), TI, Builder);
+    DefineType("__UINTPTR_TYPE__", TI.getUIntPtrType(), Builder);
+    DefineFmt("__UINTPTR", TI.getUIntPtrType(), TI, Builder);
+    DefineTypeWidth("__UINTPTR_WIDTH__", TI.getUIntPtrType(), TI, Builder);
+  }
+
   DefineFloatMacros(Builder, "FLT", &TI.getFloatFormat(), "F");
   DefineFloatMacros(Builder, "DBL", &TI.getDoubleFormat(), "");
   DefineFloatMacros(Builder, "LDBL", &TI.getLongDoubleFormat(), "L");
@@ -584,8 +704,7 @@
     Builder.defineMacro("__WINT_UNSIGNED__");
 
   // Define exact-width integer types for stdint.h
-  Builder.defineMacro("__INT" + Twine(TI.getCharWidth()) + "_TYPE__",
-                      "char");
+  DefineExactWidthIntType(TargetInfo::SignedChar, TI, Builder);
 
   if (TI.getShortWidth() > TI.getCharWidth())
     DefineExactWidthIntType(TargetInfo::SignedShort, TI, Builder);
@@ -599,6 +718,54 @@
   if (TI.getLongLongWidth() > TI.getLongWidth())
     DefineExactWidthIntType(TargetInfo::SignedLongLong, TI, Builder);
 
+  if (!LangOpts.MSVCCompat) {
+    DefineExactWidthIntType(TargetInfo::UnsignedChar, TI, Builder);
+    DefineExactWidthIntTypeSize(TargetInfo::UnsignedChar, TI, Builder);
+    DefineExactWidthIntTypeSize(TargetInfo::SignedChar, TI, Builder);
+
+    if (TI.getShortWidth() > TI.getCharWidth()) {
+      DefineExactWidthIntType(TargetInfo::UnsignedShort, TI, Builder);
+      DefineExactWidthIntTypeSize(TargetInfo::UnsignedShort, TI, Builder);
+      DefineExactWidthIntTypeSize(TargetInfo::SignedShort, TI, Builder);
+    }
+
+    if (TI.getIntWidth() > TI.getShortWidth()) {
+      DefineExactWidthIntType(TargetInfo::UnsignedInt, TI, Builder);
+      DefineExactWidthIntTypeSize(TargetInfo::UnsignedInt, TI, Builder);
+      DefineExactWidthIntTypeSize(TargetInfo::SignedInt, TI, Builder);
+    }
+
+    if (TI.getLongWidth() > TI.getIntWidth()) {
+      DefineExactWidthIntType(TargetInfo::UnsignedLong, TI, Builder);
+      DefineExactWidthIntTypeSize(TargetInfo::UnsignedLong, TI, Builder);
+      DefineExactWidthIntTypeSize(TargetInfo::SignedLong, TI, Builder);
+    }
+
+    if (TI.getLongLongWidth() > TI.getLongWidth()) {
+      DefineExactWidthIntType(TargetInfo::UnsignedLongLong, TI, Builder);
+      DefineExactWidthIntTypeSize(TargetInfo::UnsignedLongLong, TI, Builder);
+      DefineExactWidthIntTypeSize(TargetInfo::SignedLongLong, TI, Builder);
+    }
+
+    DefineLeastWidthIntType(8, true, TI, Builder);
+    DefineLeastWidthIntType(8, false, TI, Builder);
+    DefineLeastWidthIntType(16, true, TI, Builder);
+    DefineLeastWidthIntType(16, false, TI, Builder);
+    DefineLeastWidthIntType(32, true, TI, Builder);
+    DefineLeastWidthIntType(32, false, TI, Builder);
+    DefineLeastWidthIntType(64, true, TI, Builder);
+    DefineLeastWidthIntType(64, false, TI, Builder);
+
+    DefineFastIntType(8, true, TI, Builder);
+    DefineFastIntType(8, false, TI, Builder);
+    DefineFastIntType(16, true, TI, Builder);
+    DefineFastIntType(16, false, TI, Builder);
+    DefineFastIntType(32, true, TI, Builder);
+    DefineFastIntType(32, false, TI, Builder);
+    DefineFastIntType(64, true, TI, Builder);
+    DefineFastIntType(64, false, TI, Builder);
+  }
+
   if (const char *Prefix = TI.getUserLabelPrefix())
     Builder.defineMacro("__USER_LABEL_PREFIX__", Prefix);
 
@@ -607,36 +774,38 @@
   else
     Builder.defineMacro("__FINITE_MATH_ONLY__", "0");
 
-  if (LangOpts.GNUInline)
-    Builder.defineMacro("__GNUC_GNU_INLINE__");
-  else
-    Builder.defineMacro("__GNUC_STDC_INLINE__");
+  if (!LangOpts.MSVCCompat) {
+    if (LangOpts.GNUInline)
+      Builder.defineMacro("__GNUC_GNU_INLINE__");
+    else
+      Builder.defineMacro("__GNUC_STDC_INLINE__");
 
-  // The value written by __atomic_test_and_set.
-  // FIXME: This is target-dependent.
-  Builder.defineMacro("__GCC_ATOMIC_TEST_AND_SET_TRUEVAL", "1");
+    // The value written by __atomic_test_and_set.
+    // FIXME: This is target-dependent.
+    Builder.defineMacro("__GCC_ATOMIC_TEST_AND_SET_TRUEVAL", "1");
 
-  // Used by libstdc++ to implement ATOMIC_<foo>_LOCK_FREE.
-  unsigned InlineWidthBits = TI.getMaxAtomicInlineWidth();
+    // Used by libstdc++ to implement ATOMIC_<foo>_LOCK_FREE.
+    unsigned InlineWidthBits = TI.getMaxAtomicInlineWidth();
 #define DEFINE_LOCK_FREE_MACRO(TYPE, Type) \
-  Builder.defineMacro("__GCC_ATOMIC_" #TYPE "_LOCK_FREE", \
-                      getLockFreeValue(TI.get##Type##Width(), \
-                                       TI.get##Type##Align(), \
-                                       InlineWidthBits));
-  DEFINE_LOCK_FREE_MACRO(BOOL, Bool);
-  DEFINE_LOCK_FREE_MACRO(CHAR, Char);
-  DEFINE_LOCK_FREE_MACRO(CHAR16_T, Char16);
-  DEFINE_LOCK_FREE_MACRO(CHAR32_T, Char32);
-  DEFINE_LOCK_FREE_MACRO(WCHAR_T, WChar);
-  DEFINE_LOCK_FREE_MACRO(SHORT, Short);
-  DEFINE_LOCK_FREE_MACRO(INT, Int);
-  DEFINE_LOCK_FREE_MACRO(LONG, Long);
-  DEFINE_LOCK_FREE_MACRO(LLONG, LongLong);
-  Builder.defineMacro("__GCC_ATOMIC_POINTER_LOCK_FREE",
-                      getLockFreeValue(TI.getPointerWidth(0),
-                                       TI.getPointerAlign(0),
-                                       InlineWidthBits));
+    Builder.defineMacro("__GCC_ATOMIC_" #TYPE "_LOCK_FREE", \
+                        getLockFreeValue(TI.get##Type##Width(), \
+                                         TI.get##Type##Align(), \
+                                         InlineWidthBits));
+    DEFINE_LOCK_FREE_MACRO(BOOL, Bool);
+    DEFINE_LOCK_FREE_MACRO(CHAR, Char);
+    DEFINE_LOCK_FREE_MACRO(CHAR16_T, Char16);
+    DEFINE_LOCK_FREE_MACRO(CHAR32_T, Char32);
+    DEFINE_LOCK_FREE_MACRO(WCHAR_T, WChar);
+    DEFINE_LOCK_FREE_MACRO(SHORT, Short);
+    DEFINE_LOCK_FREE_MACRO(INT, Int);
+    DEFINE_LOCK_FREE_MACRO(LONG, Long);
+    DEFINE_LOCK_FREE_MACRO(LLONG, LongLong);
+    Builder.defineMacro("__GCC_ATOMIC_POINTER_LOCK_FREE",
+                        getLockFreeValue(TI.getPointerWidth(0),
+                                         TI.getPointerAlign(0),
+                                         InlineWidthBits));
 #undef DEFINE_LOCK_FREE_MACRO
+  }
 
   if (LangOpts.NoInlineDefine)
     Builder.defineMacro("__NO_INLINE__");
@@ -658,8 +827,10 @@
 
   if (LangOpts.getStackProtector() == LangOptions::SSPOn)
     Builder.defineMacro("__SSP__");
+  else if (LangOpts.getStackProtector() == LangOptions::SSPStrong)
+    Builder.defineMacro("__SSP_STRONG__", "2");
   else if (LangOpts.getStackProtector() == LangOptions::SSPReq)
-    Builder.defineMacro("__SSP_ALL__", "2");
+    Builder.defineMacro("__SSP_ALL__", "3");
 
   if (FEOpts.ProgramAction == frontend::RewriteObjC)
     Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))");
@@ -682,86 +853,23 @@
 
   // OpenMP definition
   if (LangOpts.OpenMP) {
-    // OpenMP 2.2: 
+    // OpenMP 2.2:
     //   In implementations that support a preprocessor, the _OPENMP
     //   macro name is defined to have the decimal value yyyymm where
     //   yyyy and mm are the year and the month designations of the
     //   version of the OpenMP API that the implementation support.
-    Builder.defineMacro("_OPENMP", "201107");
+    Builder.defineMacro("_OPENMP", "201307");
   }
 
   // Get other target #defines.
   TI.getTargetDefines(LangOpts, Builder);
 }
 
-// Initialize the remapping of files to alternative contents, e.g.,
-// those specified through other files.
-static void InitializeFileRemapping(DiagnosticsEngine &Diags,
-                                    SourceManager &SourceMgr,
-                                    FileManager &FileMgr,
-                                    const PreprocessorOptions &InitOpts) {
-  // Remap files in the source manager (with buffers).
-  for (PreprocessorOptions::const_remapped_file_buffer_iterator
-         Remap = InitOpts.remapped_file_buffer_begin(),
-         RemapEnd = InitOpts.remapped_file_buffer_end();
-       Remap != RemapEnd;
-       ++Remap) {
-    // Create the file entry for the file that we're mapping from.
-    const FileEntry *FromFile = FileMgr.getVirtualFile(Remap->first,
-                                                Remap->second->getBufferSize(),
-                                                       0);
-    if (!FromFile) {
-      Diags.Report(diag::err_fe_remap_missing_from_file)
-        << Remap->first;
-      if (!InitOpts.RetainRemappedFileBuffers)
-        delete Remap->second;
-      continue;
-    }
-
-    // Override the contents of the "from" file with the contents of
-    // the "to" file.
-    SourceMgr.overrideFileContents(FromFile, Remap->second,
-                                   InitOpts.RetainRemappedFileBuffers);
-  }
-
-  // Remap files in the source manager (with other files).
-  for (PreprocessorOptions::const_remapped_file_iterator
-         Remap = InitOpts.remapped_file_begin(),
-         RemapEnd = InitOpts.remapped_file_end();
-       Remap != RemapEnd;
-       ++Remap) {
-    // Find the file that we're mapping to.
-    const FileEntry *ToFile = FileMgr.getFile(Remap->second);
-    if (!ToFile) {
-      Diags.Report(diag::err_fe_remap_missing_to_file)
-      << Remap->first << Remap->second;
-      continue;
-    }
-    
-    // Create the file entry for the file that we're mapping from.
-    const FileEntry *FromFile = FileMgr.getVirtualFile(Remap->first,
-                                                       ToFile->getSize(), 0);
-    if (!FromFile) {
-      Diags.Report(diag::err_fe_remap_missing_from_file)
-      << Remap->first;
-      continue;
-    }
-    
-    // Override the contents of the "from" file with the contents of
-    // the "to" file.
-    SourceMgr.overrideFileContents(FromFile, ToFile);
-  }
-
-  SourceMgr.setOverridenFilesKeepOriginalName(
-                                        InitOpts.RemappedFilesKeepOriginalName);
-}
-
 /// InitializePreprocessor - Initialize the preprocessor getting it and the
 /// environment ready to process a single file. This returns true on error.
 ///
 void clang::InitializePreprocessor(Preprocessor &PP,
                                    const PreprocessorOptions &InitOpts,
-                                   const HeaderSearchOptions &HSOpts,
                                    const FrontendOptions &FEOpts) {
   const LangOptions &LangOpts = PP.getLangOpts();
   std::string PredefineBuffer;
@@ -769,9 +877,6 @@
   llvm::raw_string_ostream Predefines(PredefineBuffer);
   MacroBuilder Builder(Predefines);
 
-  InitializeFileRemapping(PP.getDiagnostics(), PP.getSourceManager(),
-                          PP.getFileManager(), InitOpts);
-
   // Emit line markers for various builtin sections of the file.  We don't do
   // this in asm preprocessor mode, because "# 4" is not a line marker directive
   // in this mode.
@@ -845,9 +950,4 @@
                           
   // Copy PredefinedBuffer into the Preprocessor.
   PP.setPredefines(Predefines.str());
-  
-  // Initialize the header search object.
-  ApplyHeaderSearchOptions(PP.getHeaderSearchInfo(), HSOpts,
-                           PP.getLangOpts(),
-                           PP.getTargetInfo().getTriple());
 }
diff --git a/lib/Frontend/LangStandards.cpp b/lib/Frontend/LangStandards.cpp
index f86a574..f133327 100644
--- a/lib/Frontend/LangStandards.cpp
+++ b/lib/Frontend/LangStandards.cpp
@@ -35,7 +35,7 @@
 #include "clang/Frontend/LangStandards.def"
     .Default(lang_unspecified);
   if (K == lang_unspecified)
-    return 0;
+    return nullptr;
 
   return &getLangStandardForKind(K);
 }
diff --git a/lib/Frontend/LogDiagnosticPrinter.cpp b/lib/Frontend/LogDiagnosticPrinter.cpp
index 2189b86..19539e0 100644
--- a/lib/Frontend/LogDiagnosticPrinter.cpp
+++ b/lib/Frontend/LogDiagnosticPrinter.cpp
@@ -10,16 +10,18 @@
 #include "clang/Frontend/LogDiagnosticPrinter.h"
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/FileManager.h"
+#include "clang/Basic/PlistSupport.h"
 #include "clang/Basic/SourceManager.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/raw_ostream.h"
 using namespace clang;
+using namespace markup;
 
 LogDiagnosticPrinter::LogDiagnosticPrinter(raw_ostream &os,
                                            DiagnosticOptions *diags,
                                            bool _OwnsOutputStream)
-  : OS(os), LangOpts(0), DiagOpts(diags),
+  : OS(os), LangOpts(nullptr), DiagOpts(diags),
     OwnsOutputStream(_OwnsOutputStream) {
 }
 
@@ -31,6 +33,7 @@
 static StringRef getLevelName(DiagnosticsEngine::Level Level) {
   switch (Level) {
   case DiagnosticsEngine::Ignored: return "ignored";
+  case DiagnosticsEngine::Remark:  return "remark";
   case DiagnosticsEngine::Note:    return "note";
   case DiagnosticsEngine::Warning: return "warning";
   case DiagnosticsEngine::Error:   return "error";
@@ -39,19 +42,34 @@
   llvm_unreachable("Invalid DiagnosticsEngine level!");
 }
 
-// Escape XML characters inside the raw string.
-static void emitString(llvm::raw_svector_ostream &OS, const StringRef Raw) {
-  for (StringRef::iterator I = Raw.begin(), E = Raw.end(); I != E; ++I) {
-    char c = *I;
-    switch (c) {
-    default:   OS << c; break;
-    case '&':  OS << "&amp;"; break;
-    case '<':  OS << "&lt;"; break;
-    case '>':  OS << "&gt;"; break;
-    case '\'': OS << "&apos;"; break;
-    case '\"': OS << "&quot;"; break;
-    }
+void
+LogDiagnosticPrinter::EmitDiagEntry(llvm::raw_ostream &OS,
+                                    const LogDiagnosticPrinter::DiagEntry &DE) {
+  OS << "    <dict>\n";
+  OS << "      <key>level</key>\n"
+     << "      ";
+  EmitString(OS, getLevelName(DE.DiagnosticLevel)) << '\n';
+  if (!DE.Filename.empty()) {
+    OS << "      <key>filename</key>\n"
+       << "      ";
+    EmitString(OS, DE.Filename) << '\n';
   }
+  if (DE.Line != 0) {
+    OS << "      <key>line</key>\n"
+       << "      ";
+    EmitInteger(OS, DE.Line) << '\n';
+  }
+  if (DE.Column != 0) {
+    OS << "      <key>column</key>\n"
+       << "      ";
+    EmitInteger(OS, DE.Column) << '\n';
+  }
+  if (!DE.Message.empty()) {
+    OS << "      <key>message</key>\n"
+       << "      ";
+    EmitString(OS, DE.Message) << '\n';
+  }
+  OS << "    </dict>\n";
 }
 
 void LogDiagnosticPrinter::EndSourceFile() {
@@ -71,48 +89,18 @@
   OS << "<dict>\n";
   if (!MainFilename.empty()) {
     OS << "  <key>main-file</key>\n"
-       << "  <string>";
-    emitString(OS, MainFilename);
-    OS << "</string>\n";
+       << "  ";
+    EmitString(OS, MainFilename) << '\n';
   }
   if (!DwarfDebugFlags.empty()) {
     OS << "  <key>dwarf-debug-flags</key>\n"
-       << "  <string>";
-    emitString(OS, DwarfDebugFlags);
-    OS << "</string>\n";
+       << "  ";
+    EmitString(OS, DwarfDebugFlags) << '\n';
   }
   OS << "  <key>diagnostics</key>\n";
   OS << "  <array>\n";
-  for (unsigned i = 0, e = Entries.size(); i != e; ++i) {
-    DiagEntry &DE = Entries[i];
-
-    OS << "    <dict>\n";
-    OS << "      <key>level</key>\n"
-       << "      <string>";
-    emitString(OS, getLevelName(DE.DiagnosticLevel));
-    OS << "</string>\n";
-    if (!DE.Filename.empty()) {
-      OS << "      <key>filename</key>\n"
-         << "      <string>";
-      emitString(OS, DE.Filename);
-      OS << "</string>\n";
-    }
-    if (DE.Line != 0) {
-      OS << "      <key>line</key>\n"
-         << "      <integer>" << DE.Line << "</integer>\n";
-    }
-    if (DE.Column != 0) {
-      OS << "      <key>column</key>\n"
-         << "      <integer>" << DE.Column << "</integer>\n";
-    }
-    if (!DE.Message.empty()) {
-      OS << "      <key>message</key>\n"
-         << "      <string>";
-      emitString(OS, DE.Message);
-      OS << "</string>\n";
-    }
-    OS << "    </dict>\n";
-  }
+  for (auto &DE : Entries)
+    EmitDiagEntry(OS, DE);
   OS << "  </array>\n";
   OS << "</dict>\n";
 
@@ -130,7 +118,7 @@
     FileID FID = SM.getMainFileID();
     if (!FID.isInvalid()) {
       const FileEntry *FE = SM.getFileEntryForID(FID);
-      if (FE && FE->getName())
+      if (FE && FE->isValid())
         MainFilename = FE->getName();
     }
   }
@@ -157,7 +145,7 @@
       FileID FID = SM.getFileID(Info.getLocation());
       if (!FID.isInvalid()) {
         const FileEntry *FE = SM.getFileEntryForID(FID);
-        if (FE && FE->getName())
+        if (FE && FE->isValid())
           DE.Filename = FE->getName();
       }
     } else {
diff --git a/lib/Frontend/Makefile b/lib/Frontend/Makefile
index 3c13ad6..8554b76 100644
--- a/lib/Frontend/Makefile
+++ b/lib/Frontend/Makefile
@@ -8,7 +8,7 @@
 ##===----------------------------------------------------------------------===##
 
 CLANG_LEVEL := ../..
+DIRS := Rewrite
 LIBRARYNAME := clangFrontend
 
 include $(CLANG_LEVEL)/Makefile
-
diff --git a/lib/Frontend/ModuleDependencyCollector.cpp b/lib/Frontend/ModuleDependencyCollector.cpp
new file mode 100644
index 0000000..d30f921
--- /dev/null
+++ b/lib/Frontend/ModuleDependencyCollector.cpp
@@ -0,0 +1,116 @@
+//===--- ModuleDependencyCollector.cpp - Collect module dependencies ------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Collect the dependencies of a set of modules.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/Utils.h"
+#include "clang/Serialization/ASTReader.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+
+namespace {
+/// Private implementation for ModuleDependencyCollector
+class ModuleDependencyListener : public ASTReaderListener {
+  ModuleDependencyCollector &Collector;
+
+  std::error_code copyToRoot(StringRef Src);
+public:
+  ModuleDependencyListener(ModuleDependencyCollector &Collector)
+      : Collector(Collector) {}
+  bool needsInputFileVisitation() override { return true; }
+  bool needsSystemInputFileVisitation() override { return true; }
+  bool visitInputFile(StringRef Filename, bool IsSystem,
+                      bool IsOverridden) override;
+};
+}
+
+void ModuleDependencyCollector::attachToASTReader(ASTReader &R) {
+  R.addListener(new ModuleDependencyListener(*this));
+}
+
+void ModuleDependencyCollector::writeFileMap() {
+  if (Seen.empty())
+    return;
+
+  SmallString<256> Dest = getDest();
+  llvm::sys::path::append(Dest, "vfs.yaml");
+
+  std::string ErrorInfo;
+  llvm::raw_fd_ostream OS(Dest.c_str(), ErrorInfo, llvm::sys::fs::F_Text);
+  if (!ErrorInfo.empty()) {
+    setHasErrors();
+    return;
+  }
+  VFSWriter.write(OS);
+}
+
+/// Remove traversal (ie, . or ..) from the given absolute path.
+static void removePathTraversal(SmallVectorImpl<char> &Path) {
+  using namespace llvm::sys;
+  SmallVector<StringRef, 16> ComponentStack;
+  StringRef P(Path.data(), Path.size());
+
+  // Skip the root path, then look for traversal in the components.
+  StringRef Rel = path::relative_path(P);
+  for (StringRef C : llvm::make_range(path::begin(Rel), path::end(Rel))) {
+    if (C == ".")
+      continue;
+    if (C == "..") {
+      assert(ComponentStack.size() && "Path traverses out of parent");
+      ComponentStack.pop_back();
+    } else
+      ComponentStack.push_back(C);
+  }
+
+  // The stack is now the path without any directory traversal.
+  SmallString<256> Buffer = path::root_path(P);
+  for (StringRef C : ComponentStack)
+    path::append(Buffer, C);
+
+  // Put the result in Path.
+  Path.swap(Buffer);
+}
+
+std::error_code ModuleDependencyListener::copyToRoot(StringRef Src) {
+  using namespace llvm::sys;
+
+  // We need an absolute path to append to the root.
+  SmallString<256> AbsoluteSrc = Src;
+  fs::make_absolute(AbsoluteSrc);
+  removePathTraversal(AbsoluteSrc);
+
+  // Build the destination path.
+  SmallString<256> Dest = Collector.getDest();
+  path::append(Dest, path::relative_path(AbsoluteSrc));
+
+  // Copy the file into place.
+  if (std::error_code EC = fs::create_directories(path::parent_path(Dest),
+                                                   /*IgnoreExisting=*/true))
+    return EC;
+  if (std::error_code EC = fs::copy_file(AbsoluteSrc.str(), Dest.str()))
+    return EC;
+  // Use the absolute path under the root for the file mapping.
+  Collector.addFileMapping(AbsoluteSrc.str(), Dest.str());
+  return std::error_code();
+}
+
+bool ModuleDependencyListener::visitInputFile(StringRef Filename, bool IsSystem,
+                                              bool IsOverridden) {
+  if (Collector.insertSeen(Filename))
+    if (copyToRoot(Filename))
+      Collector.setHasErrors();
+  return true;
+}
diff --git a/lib/Frontend/MultiplexConsumer.cpp b/lib/Frontend/MultiplexConsumer.cpp
index 9cf68a5..0e933a3 100644
--- a/lib/Frontend/MultiplexConsumer.cpp
+++ b/lib/Frontend/MultiplexConsumer.cpp
@@ -30,14 +30,14 @@
   // Does NOT take ownership of the elements in L.
   MultiplexASTDeserializationListener(
       const std::vector<ASTDeserializationListener*>& L);
-  virtual void ReaderInitialized(ASTReader *Reader);
-  virtual void IdentifierRead(serialization::IdentID ID,
-                              IdentifierInfo *II);
-  virtual void TypeRead(serialization::TypeIdx Idx, QualType T);
-  virtual void DeclRead(serialization::DeclID ID, const Decl *D);
-  virtual void SelectorRead(serialization::SelectorID iD, Selector Sel);
-  virtual void MacroDefinitionRead(serialization::PreprocessedEntityID, 
-                                   MacroDefinition *MD);
+  void ReaderInitialized(ASTReader *Reader) override;
+  void IdentifierRead(serialization::IdentID ID,
+                      IdentifierInfo *II) override;
+  void TypeRead(serialization::TypeIdx Idx, QualType T) override;
+  void DeclRead(serialization::DeclID ID, const Decl *D) override;
+  void SelectorRead(serialization::SelectorID iD, Selector Sel) override;
+  void MacroDefinitionRead(serialization::PreprocessedEntityID,
+                           MacroDefinition *MD) override;
 private:
   std::vector<ASTDeserializationListener*> Listeners;
 };
@@ -89,25 +89,24 @@
 public:
   // Does NOT take ownership of the elements in L.
   MultiplexASTMutationListener(ArrayRef<ASTMutationListener*> L);
-  virtual void CompletedTagDefinition(const TagDecl *D);
-  virtual void AddedVisibleDecl(const DeclContext *DC, const Decl *D);
-  virtual void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D);
-  virtual void AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD,
-                                    const ClassTemplateSpecializationDecl *D);
-  virtual void
-  AddedCXXTemplateSpecialization(const VarTemplateDecl *TD,
-                                 const VarTemplateSpecializationDecl *D);
-  virtual void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD,
-                                              const FunctionDecl *D);
-  virtual void DeducedReturnType(const FunctionDecl *FD, QualType ReturnType);
-  virtual void CompletedImplicitDefinition(const FunctionDecl *D);
-  virtual void StaticDataMemberInstantiated(const VarDecl *D);
-  virtual void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
-                                            const ObjCInterfaceDecl *IFD);
-  virtual void AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop,
-                                            const ObjCPropertyDecl *OrigProp,
-                                            const ObjCCategoryDecl *ClassExt);
-  void DeclarationMarkedUsed(const Decl *D) LLVM_OVERRIDE;
+  void CompletedTagDefinition(const TagDecl *D) override;
+  void AddedVisibleDecl(const DeclContext *DC, const Decl *D) override;
+  void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) override;
+  void AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD,
+                            const ClassTemplateSpecializationDecl *D) override;
+  void AddedCXXTemplateSpecialization(const VarTemplateDecl *TD,
+                               const VarTemplateSpecializationDecl *D) override;
+  void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD,
+                                      const FunctionDecl *D) override;
+  void DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) override;
+  void CompletedImplicitDefinition(const FunctionDecl *D) override;
+  void StaticDataMemberInstantiated(const VarDecl *D) override;
+  void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
+                                    const ObjCInterfaceDecl *IFD) override;
+  void AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop,
+                                    const ObjCPropertyDecl *OrigProp,
+                                    const ObjCCategoryDecl *ClassExt) override;
+  void DeclarationMarkedUsed(const Decl *D) override;
 
 private:
   std::vector<ASTMutationListener*> Listeners;
@@ -184,10 +183,9 @@
 
 }  // end namespace clang
 
-
-MultiplexConsumer::MultiplexConsumer(ArrayRef<ASTConsumer*> C)
-    : Consumers(C.begin(), C.end()),
-      MutationListener(0), DeserializationListener(0) {
+MultiplexConsumer::MultiplexConsumer(ArrayRef<ASTConsumer *> C)
+    : Consumers(C.begin(), C.end()), MutationListener(),
+      DeserializationListener() {
   // Collect the mutation listeners and deserialization listeners of all
   // children, and create a multiplex listener each if so.
   std::vector<ASTMutationListener*> mutationListeners;
@@ -228,6 +226,11 @@
   return Continue;
 }
 
+void MultiplexConsumer::HandleInlineMethodDefinition(CXXMethodDecl *D) {
+  for (size_t i = 0, e = Consumers.size(); i != e; ++i)
+    Consumers[i]->HandleInlineMethodDefinition(D);
+}
+
 void  MultiplexConsumer::HandleCXXStaticMemberVarInstantiation(VarDecl *VD) {
   for (size_t i = 0, e = Consumers.size(); i != e; ++i)
     Consumers[i]->HandleCXXStaticMemberVarInstantiation(VD);
@@ -248,6 +251,11 @@
     Consumers[i]->HandleTagDeclDefinition(D);
 }
 
+void MultiplexConsumer::HandleTagDeclRequiredDefinition(const TagDecl *D) {
+  for (size_t i = 0, e = Consumers.size(); i != e; ++i)
+    Consumers[i]->HandleTagDeclRequiredDefinition(D);
+}
+
 void MultiplexConsumer::HandleCXXImplicitFunctionInstantiation(FunctionDecl *D){
   for (size_t i = 0, e = Consumers.size(); i != e; ++i)
     Consumers[i]->HandleCXXImplicitFunctionInstantiation(D);
@@ -258,6 +266,26 @@
     Consumers[i]->HandleTopLevelDeclInObjCContainer(D);
 }
 
+void MultiplexConsumer::HandleImplicitImportDecl(ImportDecl *D) {
+  for (size_t i = 0, e = Consumers.size(); i != e; ++i)
+    Consumers[i]->HandleImplicitImportDecl(D);
+}
+
+void MultiplexConsumer::HandleLinkerOptionPragma(llvm::StringRef Opts) {
+  for (size_t i = 0, e = Consumers.size(); i != e; ++i)
+    Consumers[i]->HandleLinkerOptionPragma(Opts);
+}
+
+void MultiplexConsumer::HandleDetectMismatch(llvm::StringRef Name, llvm::StringRef Value) {
+  for (size_t i = 0, e = Consumers.size(); i != e; ++i)
+    Consumers[i]->HandleDetectMismatch(Name, Value);
+}
+
+void MultiplexConsumer::HandleDependentLibrary(llvm::StringRef Lib) {
+  for (size_t i = 0, e = Consumers.size(); i != e; ++i)
+    Consumers[i]->HandleDependentLibrary(Lib);
+}
+
 void MultiplexConsumer::CompleteTentativeDefinition(VarDecl *D) {
   for (size_t i = 0, e = Consumers.size(); i != e; ++i)
     Consumers[i]->CompleteTentativeDefinition(D);
diff --git a/lib/Frontend/PrintPreprocessedOutput.cpp b/lib/Frontend/PrintPreprocessedOutput.cpp
index 55a66d8..4a6f8db 100644
--- a/lib/Frontend/PrintPreprocessedOutput.cpp
+++ b/lib/Frontend/PrintPreprocessedOutput.cpp
@@ -123,39 +123,27 @@
   }
 
   bool startNewLineIfNeeded(bool ShouldUpdateCurrentLine = true);
-  
-  virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
-                           SrcMgr::CharacteristicKind FileType,
-                           FileID PrevFID);
-  virtual void InclusionDirective(SourceLocation HashLoc,
-                                  const Token &IncludeTok,
-                                  StringRef FileName,
-                                  bool IsAngled,
-                                  CharSourceRange FilenameRange,
-                                  const FileEntry *File,
-                                  StringRef SearchPath,
-                                  StringRef RelativePath,
-                                  const Module *Imported);
-  virtual void Ident(SourceLocation Loc, const std::string &str);
-  virtual void PragmaCaptured(SourceLocation Loc, StringRef Str);
-  virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
-                             const std::string &Str);
-  virtual void PragmaDetectMismatch(SourceLocation Loc,
-                                    const std::string &Name,
-                                    const std::string &Value);
-  virtual void PragmaMessage(SourceLocation Loc, StringRef Namespace,
-                             PragmaMessageKind Kind, StringRef Str);
-  virtual void PragmaDebug(SourceLocation Loc, StringRef DebugType);
-  virtual void PragmaDiagnosticPush(SourceLocation Loc,
-                                    StringRef Namespace);
-  virtual void PragmaDiagnosticPop(SourceLocation Loc,
-                                   StringRef Namespace);
-  virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
-                                diag::Mapping Map, StringRef Str);
-  virtual void PragmaWarning(SourceLocation Loc, StringRef WarningSpec,
-                             ArrayRef<int> Ids);
-  virtual void PragmaWarningPush(SourceLocation Loc, int Level);
-  virtual void PragmaWarningPop(SourceLocation Loc);
+
+  void FileChanged(SourceLocation Loc, FileChangeReason Reason,
+                   SrcMgr::CharacteristicKind FileType,
+                   FileID PrevFID) override;
+  void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
+                          StringRef FileName, bool IsAngled,
+                          CharSourceRange FilenameRange, const FileEntry *File,
+                          StringRef SearchPath, StringRef RelativePath,
+                          const Module *Imported) override;
+  void Ident(SourceLocation Loc, const std::string &str) override;
+  void PragmaMessage(SourceLocation Loc, StringRef Namespace,
+                     PragmaMessageKind Kind, StringRef Str) override;
+  void PragmaDebug(SourceLocation Loc, StringRef DebugType) override;
+  void PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) override;
+  void PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace) override;
+  void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
+                        diag::Severity Map, StringRef Str) override;
+  void PragmaWarning(SourceLocation Loc, StringRef WarningSpec,
+                     ArrayRef<int> Ids) override;
+  void PragmaWarningPush(SourceLocation Loc, int Level) override;
+  void PragmaWarningPop(SourceLocation Loc) override;
 
   bool HandleFirstTokOnLine(Token &Tok);
 
@@ -174,15 +162,18 @@
                    const Token &Tok) {
     return ConcatInfo.AvoidConcat(PrevPrevTok, PrevTok, Tok);
   }
-  void WriteLineInfo(unsigned LineNo, const char *Extra=0, unsigned ExtraLen=0);
+  void WriteLineInfo(unsigned LineNo, const char *Extra=nullptr,
+                     unsigned ExtraLen=0);
   bool LineMarkersAreDisabled() const { return DisableLineMarkers; }
   void HandleNewlinesInToken(const char *TokStr, unsigned Len);
 
   /// MacroDefined - This hook is called whenever a macro definition is seen.
-  void MacroDefined(const Token &MacroNameTok, const MacroDirective *MD);
+  void MacroDefined(const Token &MacroNameTok,
+                    const MacroDirective *MD) override;
 
   /// MacroUndefined - This hook is called whenever a macro #undef is seen.
-  void MacroUndefined(const Token &MacroNameTok, const MacroDirective *MD);
+  void MacroUndefined(const Token &MacroNameTok,
+                      const MacroDirective *MD) override;
 };
 }  // end anonymous namespace
 
@@ -230,7 +221,7 @@
     }
   } else if (!DisableLineMarkers) {
     // Emit a #line or line marker.
-    WriteLineInfo(LineNo, 0, 0);
+    WriteLineInfo(LineNo, nullptr, 0);
   } else {
     // Okay, we're in -P mode, which turns off line markers.  However, we still
     // need to emit a newline between tokens on different lines.
@@ -355,15 +346,6 @@
   EmittedTokensOnThisLine = true;
 }
 
-void PrintPPOutputPPCallbacks::PragmaCaptured(SourceLocation Loc,
-                                              StringRef Str) {
-  startNewLineIfNeeded();
-  MoveToLine(Loc);
-  OS << "#pragma captured";
-
-  setEmittedDirectiveOnThisLine();
-}
-
 /// MacroDefined - This hook is called whenever a macro definition is seen.
 void PrintPPOutputPPCallbacks::MacroDefined(const Token &MacroNameTok,
                                             const MacroDirective *MD) {
@@ -402,36 +384,6 @@
     }
 }
 
-void PrintPPOutputPPCallbacks::PragmaComment(SourceLocation Loc,
-                                             const IdentifierInfo *Kind,
-                                             const std::string &Str) {
-  startNewLineIfNeeded();
-  MoveToLine(Loc);
-  OS << "#pragma comment(" << Kind->getName();
-
-  if (!Str.empty()) {
-    OS << ", \"";
-    outputPrintable(OS, Str);
-    OS << '"';
-  }
-
-  OS << ')';
-  setEmittedDirectiveOnThisLine();
-}
-
-void PrintPPOutputPPCallbacks::PragmaDetectMismatch(SourceLocation Loc,
-                                                    const std::string &Name,
-                                                    const std::string &Value) {
-  startNewLineIfNeeded();
-  MoveToLine(Loc);
-  OS << "#pragma detect_mismatch(\"" << Name << '"';
-  outputPrintable(OS, Name);
-  OS << "\", \"";
-  outputPrintable(OS, Value);
-  OS << "\")";
-  setEmittedDirectiveOnThisLine();
-}
-
 void PrintPPOutputPPCallbacks::PragmaMessage(SourceLocation Loc,
                                              StringRef Namespace,
                                              PragmaMessageKind Kind,
@@ -487,23 +439,27 @@
   setEmittedDirectiveOnThisLine();
 }
 
-void PrintPPOutputPPCallbacks::
-PragmaDiagnostic(SourceLocation Loc, StringRef Namespace,
-                 diag::Mapping Map, StringRef Str) {
+void PrintPPOutputPPCallbacks::PragmaDiagnostic(SourceLocation Loc,
+                                                StringRef Namespace,
+                                                diag::Severity Map,
+                                                StringRef Str) {
   startNewLineIfNeeded();
   MoveToLine(Loc);
   OS << "#pragma " << Namespace << " diagnostic ";
   switch (Map) {
-  case diag::MAP_WARNING:
+  case diag::Severity::Remark:
+    OS << "remark";
+    break;
+  case diag::Severity::Warning:
     OS << "warning";
     break;
-  case diag::MAP_ERROR:
+  case diag::Severity::Error:
     OS << "error";
     break;
-  case diag::MAP_IGNORE:
+  case diag::Severity::Ignored:
     OS << "ignored";
     break;
-  case diag::MAP_FATAL:
+  case diag::Severity::Fatal:
     OS << "fatal";
     break;
   }
@@ -556,6 +512,13 @@
   // indented for easy reading.
   unsigned ColNo = SM.getExpansionColumnNumber(Tok.getLocation());
 
+  // The first token on a line can have a column number of 1, yet still expect
+  // leading white space, if a macro expansion in column 1 starts with an empty
+  // macro argument, or an empty nested macro expansion. In this case, move the
+  // token to column 2.
+  if (ColNo == 1 && Tok.hasLeadingSpace())
+    ColNo = 2;
+
   // This hack prevents stuff like:
   // #define HASH #
   // HASH define foo bar
@@ -602,8 +565,8 @@
 
   UnknownPragmaHandler(const char *prefix, PrintPPOutputPPCallbacks *callbacks)
     : Prefix(prefix), Callbacks(callbacks) {}
-  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
-                            Token &PragmaTok) {
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &PragmaTok) override {
     // Figure out what line we went to and insert the appropriate number of
     // newline characters.
     Callbacks->startNewLineIfNeeded();
@@ -615,7 +578,13 @@
         Callbacks->OS << ' ';
       std::string TokSpell = PP.getSpelling(PragmaTok);
       Callbacks->OS.write(&TokSpell[0], TokSpell.size());
-      PP.LexUnexpandedToken(PragmaTok);
+
+      // Expand macros in pragmas with -fms-extensions.  The assumption is that
+      // the majority of pragmas in such a file will be Microsoft pragmas.
+      if (PP.getLangOpts().MicrosoftExt)
+        PP.Lex(PragmaTok);
+      else
+        PP.LexUnexpandedToken(PragmaTok);
     }
     Callbacks->setEmittedDirectiveOnThisLine();
   }
@@ -657,7 +626,9 @@
       // -traditional-cpp the lexer keeps /all/ whitespace, including comments.
       SourceLocation StartLoc = Tok.getLocation();
       Callbacks->MoveToLine(StartLoc.getLocWithOffset(Tok.getLength()));
-    } else if (Tok.is(tok::annot_module_include)) {
+    } else if (Tok.is(tok::annot_module_include) ||
+               Tok.is(tok::annot_module_begin) ||
+               Tok.is(tok::annot_module_end)) {
       // PrintPPOutputPPCallbacks::InclusionDirective handles producing
       // appropriate output here. Ignore this token entirely.
       PP.Lex(Tok);
@@ -702,7 +673,7 @@
 
 static void DoPrintMacros(Preprocessor &PP, raw_ostream *OS) {
   // Ignore unknown pragmas.
-  PP.AddPragmaHandler(new EmptyPragmaHandler());
+  PP.IgnorePragmas();
 
   // -dM mode just scans and ignores all tokens in the files, then dumps out
   // the macro table at the end.
diff --git a/lib/Frontend/Rewrite/CMakeLists.txt b/lib/Frontend/Rewrite/CMakeLists.txt
new file mode 100644
index 0000000..924bf5d
--- /dev/null
+++ b/lib/Frontend/Rewrite/CMakeLists.txt
@@ -0,0 +1,22 @@
+set(LLVM_LINK_COMPONENTS
+  Support
+  )
+
+add_clang_library(clangRewriteFrontend
+  FixItRewriter.cpp
+  FrontendActions.cpp
+  HTMLPrint.cpp
+  InclusionRewriter.cpp
+  RewriteMacros.cpp
+  RewriteModernObjC.cpp
+  RewriteObjC.cpp
+  RewriteTest.cpp
+
+  LINK_LIBS
+  clangAST
+  clangBasic
+  clangEdit
+  clangFrontend
+  clangLex
+  clangRewrite
+  )
diff --git a/lib/Frontend/Rewrite/FixItRewriter.cpp b/lib/Frontend/Rewrite/FixItRewriter.cpp
new file mode 100644
index 0000000..8b7af71
--- /dev/null
+++ b/lib/Frontend/Rewrite/FixItRewriter.cpp
@@ -0,0 +1,200 @@
+//===--- FixItRewriter.cpp - Fix-It Rewriter Diagnostic Client --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is a diagnostic client adaptor that performs rewrites as
+// suggested by code modification hints attached to diagnostics. It
+// then forwards any diagnostics to the adapted diagnostic client.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Rewrite/Frontend/FixItRewriter.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Edit/Commit.h"
+#include "clang/Edit/EditsReceiver.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstdio>
+#include <memory>
+
+using namespace clang;
+
+FixItRewriter::FixItRewriter(DiagnosticsEngine &Diags, SourceManager &SourceMgr,
+                             const LangOptions &LangOpts,
+                             FixItOptions *FixItOpts)
+  : Diags(Diags),
+    Editor(SourceMgr, LangOpts),
+    Rewrite(SourceMgr, LangOpts),
+    FixItOpts(FixItOpts),
+    NumFailures(0),
+    PrevDiagSilenced(false) {
+  OwnsClient = Diags.ownsClient();
+  Client = Diags.takeClient();
+  Diags.setClient(this);
+}
+
+FixItRewriter::~FixItRewriter() {
+  Diags.takeClient();
+  Diags.setClient(Client, OwnsClient);
+}
+
+bool FixItRewriter::WriteFixedFile(FileID ID, raw_ostream &OS) {
+  const RewriteBuffer *RewriteBuf = Rewrite.getRewriteBufferFor(ID);
+  if (!RewriteBuf) return true;
+  RewriteBuf->write(OS);
+  OS.flush();
+  return false;
+}
+
+namespace {
+
+class RewritesReceiver : public edit::EditsReceiver {
+  Rewriter &Rewrite;
+
+public:
+  RewritesReceiver(Rewriter &Rewrite) : Rewrite(Rewrite) { }
+
+  void insert(SourceLocation loc, StringRef text) override {
+    Rewrite.InsertText(loc, text);
+  }
+  void replace(CharSourceRange range, StringRef text) override {
+    Rewrite.ReplaceText(range.getBegin(), Rewrite.getRangeSize(range), text);
+  }
+};
+
+}
+
+bool FixItRewriter::WriteFixedFiles(
+            std::vector<std::pair<std::string, std::string> > *RewrittenFiles) {
+  if (NumFailures > 0 && !FixItOpts->FixWhatYouCan) {
+    Diag(FullSourceLoc(), diag::warn_fixit_no_changes);
+    return true;
+  }
+
+  RewritesReceiver Rec(Rewrite);
+  Editor.applyRewrites(Rec);
+
+  for (iterator I = buffer_begin(), E = buffer_end(); I != E; ++I) {
+    const FileEntry *Entry = Rewrite.getSourceMgr().getFileEntryForID(I->first);
+    int fd;
+    std::string Filename = FixItOpts->RewriteFilename(Entry->getName(), fd);
+    std::string Err;
+    std::unique_ptr<llvm::raw_fd_ostream> OS;
+    if (fd != -1) {
+      OS.reset(new llvm::raw_fd_ostream(fd, /*shouldClose=*/true));
+    } else {
+      OS.reset(new llvm::raw_fd_ostream(Filename.c_str(), Err,
+                                        llvm::sys::fs::F_None));
+    }
+    if (!Err.empty()) {
+      Diags.Report(clang::diag::err_fe_unable_to_open_output)
+          << Filename << Err;
+      continue;
+    }
+    RewriteBuffer &RewriteBuf = I->second;
+    RewriteBuf.write(*OS);
+    OS->flush();
+
+    if (RewrittenFiles)
+      RewrittenFiles->push_back(std::make_pair(Entry->getName(), Filename));
+  }
+
+  return false;
+}
+
+bool FixItRewriter::IncludeInDiagnosticCounts() const {
+  return Client ? Client->IncludeInDiagnosticCounts() : true;
+}
+
+void FixItRewriter::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+                                     const Diagnostic &Info) {
+  // Default implementation (Warnings/errors count).
+  DiagnosticConsumer::HandleDiagnostic(DiagLevel, Info);
+
+  if (!FixItOpts->Silent ||
+      DiagLevel >= DiagnosticsEngine::Error ||
+      (DiagLevel == DiagnosticsEngine::Note && !PrevDiagSilenced) ||
+      (DiagLevel > DiagnosticsEngine::Note && Info.getNumFixItHints())) {
+    Client->HandleDiagnostic(DiagLevel, Info);
+    PrevDiagSilenced = false;
+  } else {
+    PrevDiagSilenced = true;
+  }
+
+  // Skip over any diagnostics that are ignored or notes.
+  if (DiagLevel <= DiagnosticsEngine::Note)
+    return;
+  // Skip over errors if we are only fixing warnings.
+  if (DiagLevel >= DiagnosticsEngine::Error && FixItOpts->FixOnlyWarnings) {
+    ++NumFailures;
+    return;
+  }
+
+  // Make sure that we can perform all of the modifications we
+  // in this diagnostic.
+  edit::Commit commit(Editor);
+  for (unsigned Idx = 0, Last = Info.getNumFixItHints();
+       Idx < Last; ++Idx) {
+    const FixItHint &Hint = Info.getFixItHint(Idx);
+
+    if (Hint.CodeToInsert.empty()) {
+      if (Hint.InsertFromRange.isValid())
+        commit.insertFromRange(Hint.RemoveRange.getBegin(),
+                           Hint.InsertFromRange, /*afterToken=*/false,
+                           Hint.BeforePreviousInsertions);
+      else
+        commit.remove(Hint.RemoveRange);
+    } else {
+      if (Hint.RemoveRange.isTokenRange() ||
+          Hint.RemoveRange.getBegin() != Hint.RemoveRange.getEnd())
+        commit.replace(Hint.RemoveRange, Hint.CodeToInsert);
+      else
+        commit.insert(Hint.RemoveRange.getBegin(), Hint.CodeToInsert,
+                    /*afterToken=*/false, Hint.BeforePreviousInsertions);
+    }
+  }
+  bool CanRewrite = Info.getNumFixItHints() > 0 && commit.isCommitable();
+
+  if (!CanRewrite) {
+    if (Info.getNumFixItHints() > 0)
+      Diag(Info.getLocation(), diag::note_fixit_in_macro);
+
+    // If this was an error, refuse to perform any rewriting.
+    if (DiagLevel >= DiagnosticsEngine::Error) {
+      if (++NumFailures == 1)
+        Diag(Info.getLocation(), diag::note_fixit_unfixed_error);
+    }
+    return;
+  }
+  
+  if (!Editor.commit(commit)) {
+    ++NumFailures;
+    Diag(Info.getLocation(), diag::note_fixit_failed);
+    return;
+  }
+
+  Diag(Info.getLocation(), diag::note_fixit_applied);
+}
+
+/// \brief Emit a diagnostic via the adapted diagnostic client.
+void FixItRewriter::Diag(SourceLocation Loc, unsigned DiagID) {
+  // When producing this diagnostic, we temporarily bypass ourselves,
+  // clear out any current diagnostic, and let the downstream client
+  // format the diagnostic.
+  Diags.takeClient();
+  Diags.setClient(Client);
+  Diags.Clear();
+  Diags.Report(Loc, DiagID);
+  Diags.takeClient();
+  Diags.setClient(this);
+}
+
+FixItOptions::~FixItOptions() {}
diff --git a/lib/Frontend/Rewrite/FrontendActions.cpp b/lib/Frontend/Rewrite/FrontendActions.cpp
new file mode 100644
index 0000000..59fef73
--- /dev/null
+++ b/lib/Frontend/Rewrite/FrontendActions.cpp
@@ -0,0 +1,196 @@
+//===--- FrontendActions.cpp ----------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Rewrite/Frontend/FrontendActions.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/FrontendActions.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Frontend/Utils.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Parse/Parser.h"
+#include "clang/Rewrite/Frontend/ASTConsumers.h"
+#include "clang/Rewrite/Frontend/FixItRewriter.h"
+#include "clang/Rewrite/Frontend/Rewriters.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+#include <memory>
+
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// AST Consumer Actions
+//===----------------------------------------------------------------------===//
+
+ASTConsumer *HTMLPrintAction::CreateASTConsumer(CompilerInstance &CI,
+                                                StringRef InFile) {
+  if (raw_ostream *OS = CI.createDefaultOutputFile(false, InFile))
+    return CreateHTMLPrinter(OS, CI.getPreprocessor());
+  return nullptr;
+}
+
+FixItAction::FixItAction() {}
+FixItAction::~FixItAction() {}
+
+ASTConsumer *FixItAction::CreateASTConsumer(CompilerInstance &CI,
+                                            StringRef InFile) {
+  return new ASTConsumer();
+}
+
+namespace {
+class FixItRewriteInPlace : public FixItOptions {
+public:
+  std::string RewriteFilename(const std::string &Filename, int &fd) override {
+    fd = -1;
+    return Filename;
+  }
+};
+
+class FixItActionSuffixInserter : public FixItOptions {
+  std::string NewSuffix;
+
+public:
+  FixItActionSuffixInserter(std::string NewSuffix, bool FixWhatYouCan)
+    : NewSuffix(NewSuffix) {
+      this->FixWhatYouCan = FixWhatYouCan;
+  }
+
+  std::string RewriteFilename(const std::string &Filename, int &fd) override {
+    fd = -1;
+    SmallString<128> Path(Filename);
+    llvm::sys::path::replace_extension(Path,
+      NewSuffix + llvm::sys::path::extension(Path));
+    return Path.str();
+  }
+};
+
+class FixItRewriteToTemp : public FixItOptions {
+public:
+  std::string RewriteFilename(const std::string &Filename, int &fd) override {
+    SmallString<128> Path;
+    llvm::sys::fs::createTemporaryFile(llvm::sys::path::filename(Filename),
+                                       llvm::sys::path::extension(Filename), fd,
+                                       Path);
+    return Path.str();
+  }
+};
+} // end anonymous namespace
+
+bool FixItAction::BeginSourceFileAction(CompilerInstance &CI,
+                                        StringRef Filename) {
+  const FrontendOptions &FEOpts = getCompilerInstance().getFrontendOpts();
+  if (!FEOpts.FixItSuffix.empty()) {
+    FixItOpts.reset(new FixItActionSuffixInserter(FEOpts.FixItSuffix,
+                                                  FEOpts.FixWhatYouCan));
+  } else {
+    FixItOpts.reset(new FixItRewriteInPlace);
+    FixItOpts->FixWhatYouCan = FEOpts.FixWhatYouCan;
+  }
+  Rewriter.reset(new FixItRewriter(CI.getDiagnostics(), CI.getSourceManager(),
+                                   CI.getLangOpts(), FixItOpts.get()));
+  return true;
+}
+
+void FixItAction::EndSourceFileAction() {
+  // Otherwise rewrite all files.
+  Rewriter->WriteFixedFiles();
+}
+
+bool FixItRecompile::BeginInvocation(CompilerInstance &CI) {
+
+  std::vector<std::pair<std::string, std::string> > RewrittenFiles;
+  bool err = false;
+  {
+    const FrontendOptions &FEOpts = CI.getFrontendOpts();
+    std::unique_ptr<FrontendAction> FixAction(new SyntaxOnlyAction());
+    if (FixAction->BeginSourceFile(CI, FEOpts.Inputs[0])) {
+      std::unique_ptr<FixItOptions> FixItOpts;
+      if (FEOpts.FixToTemporaries)
+        FixItOpts.reset(new FixItRewriteToTemp());
+      else
+        FixItOpts.reset(new FixItRewriteInPlace());
+      FixItOpts->Silent = true;
+      FixItOpts->FixWhatYouCan = FEOpts.FixWhatYouCan;
+      FixItOpts->FixOnlyWarnings = FEOpts.FixOnlyWarnings;
+      FixItRewriter Rewriter(CI.getDiagnostics(), CI.getSourceManager(),
+                             CI.getLangOpts(), FixItOpts.get());
+      FixAction->Execute();
+  
+      err = Rewriter.WriteFixedFiles(&RewrittenFiles);
+    
+      FixAction->EndSourceFile();
+      CI.setSourceManager(nullptr);
+      CI.setFileManager(nullptr);
+    } else {
+      err = true;
+    }
+  }
+  if (err)
+    return false;
+  CI.getDiagnosticClient().clear();
+  CI.getDiagnostics().Reset();
+
+  PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();
+  PPOpts.RemappedFiles.insert(PPOpts.RemappedFiles.end(),
+                              RewrittenFiles.begin(), RewrittenFiles.end());
+  PPOpts.RemappedFilesKeepOriginalName = false;
+
+  return true;
+}
+
+#ifdef CLANG_ENABLE_OBJC_REWRITER
+
+ASTConsumer *RewriteObjCAction::CreateASTConsumer(CompilerInstance &CI,
+                                                  StringRef InFile) {
+  if (raw_ostream *OS = CI.createDefaultOutputFile(false, InFile, "cpp")) {
+    if (CI.getLangOpts().ObjCRuntime.isNonFragile())
+      return CreateModernObjCRewriter(InFile, OS,
+                                CI.getDiagnostics(), CI.getLangOpts(),
+                                CI.getDiagnosticOpts().NoRewriteMacros,
+                                (CI.getCodeGenOpts().getDebugInfo() !=
+                                 CodeGenOptions::NoDebugInfo));
+    return CreateObjCRewriter(InFile, OS,
+                              CI.getDiagnostics(), CI.getLangOpts(),
+                              CI.getDiagnosticOpts().NoRewriteMacros);
+  }
+  return nullptr;
+}
+
+#endif
+
+//===----------------------------------------------------------------------===//
+// Preprocessor Actions
+//===----------------------------------------------------------------------===//
+
+void RewriteMacrosAction::ExecuteAction() {
+  CompilerInstance &CI = getCompilerInstance();
+  raw_ostream *OS = CI.createDefaultOutputFile(true, getCurrentFile());
+  if (!OS) return;
+
+  RewriteMacrosInInput(CI.getPreprocessor(), OS);
+}
+
+void RewriteTestAction::ExecuteAction() {
+  CompilerInstance &CI = getCompilerInstance();
+  raw_ostream *OS = CI.createDefaultOutputFile(false, getCurrentFile());
+  if (!OS) return;
+
+  DoRewriteTest(CI.getPreprocessor(), OS);
+}
+
+void RewriteIncludesAction::ExecuteAction() {
+  CompilerInstance &CI = getCompilerInstance();
+  raw_ostream *OS = CI.createDefaultOutputFile(true, getCurrentFile());
+  if (!OS) return;
+
+  RewriteIncludesInInput(CI.getPreprocessor(), OS,
+                         CI.getPreprocessorOutputOpts());
+}
diff --git a/lib/Frontend/Rewrite/HTMLPrint.cpp b/lib/Frontend/Rewrite/HTMLPrint.cpp
new file mode 100644
index 0000000..64da05f
--- /dev/null
+++ b/lib/Frontend/Rewrite/HTMLPrint.cpp
@@ -0,0 +1,94 @@
+//===--- HTMLPrint.cpp - Source code -> HTML pretty-printing --------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Pretty-printing of source code to HTML.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Rewrite/Frontend/ASTConsumers.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Rewrite/Core/HTMLRewrite.h"
+#include "clang/Rewrite/Core/Rewriter.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// Functional HTML pretty-printing.
+//===----------------------------------------------------------------------===//
+
+namespace {
+  class HTMLPrinter : public ASTConsumer {
+    Rewriter R;
+    raw_ostream *Out;
+    Preprocessor &PP;
+    bool SyntaxHighlight, HighlightMacros;
+
+  public:
+    HTMLPrinter(raw_ostream *OS, Preprocessor &pp,
+                bool _SyntaxHighlight, bool _HighlightMacros)
+      : Out(OS), PP(pp), SyntaxHighlight(_SyntaxHighlight),
+        HighlightMacros(_HighlightMacros) {}
+
+    void Initialize(ASTContext &context) override;
+    void HandleTranslationUnit(ASTContext &Ctx) override;
+  };
+}
+
+ASTConsumer* clang::CreateHTMLPrinter(raw_ostream *OS,
+                                      Preprocessor &PP,
+                                      bool SyntaxHighlight,
+                                      bool HighlightMacros) {
+  return new HTMLPrinter(OS, PP, SyntaxHighlight, HighlightMacros);
+}
+
+void HTMLPrinter::Initialize(ASTContext &context) {
+  R.setSourceMgr(context.getSourceManager(), context.getLangOpts());
+}
+
+void HTMLPrinter::HandleTranslationUnit(ASTContext &Ctx) {
+  if (PP.getDiagnostics().hasErrorOccurred())
+    return;
+
+  // Format the file.
+  FileID FID = R.getSourceMgr().getMainFileID();
+  const FileEntry* Entry = R.getSourceMgr().getFileEntryForID(FID);
+  const char* Name;
+  // In some cases, in particular the case where the input is from stdin,
+  // there is no entry.  Fall back to the memory buffer for a name in those
+  // cases.
+  if (Entry)
+    Name = Entry->getName();
+  else
+    Name = R.getSourceMgr().getBuffer(FID)->getBufferIdentifier();
+
+  html::AddLineNumbers(R, FID);
+  html::AddHeaderFooterInternalBuiltinCSS(R, FID, Name);
+
+  // If we have a preprocessor, relex the file and syntax highlight.
+  // We might not have a preprocessor if we come from a deserialized AST file,
+  // for example.
+
+  if (SyntaxHighlight) html::SyntaxHighlight(R, FID, PP);
+  if (HighlightMacros) html::HighlightMacros(R, FID, PP);
+  html::EscapeText(R, FID, false, true);
+
+  // Emit the HTML.
+  const RewriteBuffer &RewriteBuf = R.getEditBuffer(FID);
+  char *Buffer = (char*)malloc(RewriteBuf.size());
+  std::copy(RewriteBuf.begin(), RewriteBuf.end(), Buffer);
+  Out->write(Buffer, RewriteBuf.size());
+  free(Buffer);
+}
diff --git a/lib/Frontend/Rewrite/InclusionRewriter.cpp b/lib/Frontend/Rewrite/InclusionRewriter.cpp
new file mode 100644
index 0000000..aa7017b
--- /dev/null
+++ b/lib/Frontend/Rewrite/InclusionRewriter.cpp
@@ -0,0 +1,547 @@
+//===--- InclusionRewriter.cpp - Rewrite includes into their expansions ---===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This code rewrites include invocations into their expansions.  This gives you
+// a file with all included files merged into it.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Rewrite/Frontend/Rewriters.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Frontend/PreprocessorOutputOptions.h"
+#include "clang/Lex/HeaderSearch.h"
+#include "clang/Lex/Pragma.h"
+#include "clang/Lex/Preprocessor.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+using namespace llvm;
+
+namespace {
+
+class InclusionRewriter : public PPCallbacks {
+  /// Information about which #includes were actually performed,
+  /// created by preprocessor callbacks.
+  struct FileChange {
+    const Module *Mod;
+    SourceLocation From;
+    FileID Id;
+    SrcMgr::CharacteristicKind FileType;
+    FileChange(SourceLocation From, const Module *Mod) : Mod(Mod), From(From) {
+    }
+  };
+  Preprocessor &PP; ///< Used to find inclusion directives.
+  SourceManager &SM; ///< Used to read and manage source files.
+  raw_ostream &OS; ///< The destination stream for rewritten contents.
+  const llvm::MemoryBuffer *PredefinesBuffer; ///< The preprocessor predefines.
+  bool ShowLineMarkers; ///< Show #line markers.
+  bool UseLineDirective; ///< Use of line directives or line markers.
+  typedef std::map<unsigned, FileChange> FileChangeMap;
+  FileChangeMap FileChanges; ///< Tracks which files were included where.
+  /// Used transitively for building up the FileChanges mapping over the
+  /// various \c PPCallbacks callbacks.
+  FileChangeMap::iterator LastInsertedFileChange;
+public:
+  InclusionRewriter(Preprocessor &PP, raw_ostream &OS, bool ShowLineMarkers);
+  bool Process(FileID FileId, SrcMgr::CharacteristicKind FileType);
+  void setPredefinesBuffer(const llvm::MemoryBuffer *Buf) {
+    PredefinesBuffer = Buf;
+  }
+private:
+  void FileChanged(SourceLocation Loc, FileChangeReason Reason,
+                   SrcMgr::CharacteristicKind FileType,
+                   FileID PrevFID) override;
+  void FileSkipped(const FileEntry &ParentFile, const Token &FilenameTok,
+                   SrcMgr::CharacteristicKind FileType) override;
+  void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
+                          StringRef FileName, bool IsAngled,
+                          CharSourceRange FilenameRange, const FileEntry *File,
+                          StringRef SearchPath, StringRef RelativePath,
+                          const Module *Imported) override;
+  void WriteLineInfo(const char *Filename, int Line,
+                     SrcMgr::CharacteristicKind FileType,
+                     StringRef EOL, StringRef Extra = StringRef());
+  void WriteImplicitModuleImport(const Module *Mod, StringRef EOL);
+  void OutputContentUpTo(const MemoryBuffer &FromFile,
+                         unsigned &WriteFrom, unsigned WriteTo,
+                         StringRef EOL, int &lines,
+                         bool EnsureNewline);
+  void CommentOutDirective(Lexer &DirectivesLex, const Token &StartToken,
+                           const MemoryBuffer &FromFile, StringRef EOL,
+                           unsigned &NextToWrite, int &Lines);
+  bool HandleHasInclude(FileID FileId, Lexer &RawLex,
+                        const DirectoryLookup *Lookup, Token &Tok,
+                        bool &FileExists);
+  const FileChange *FindFileChangeLocation(SourceLocation Loc) const;
+  StringRef NextIdentifierName(Lexer &RawLex, Token &RawToken);
+};
+
+}  // end anonymous namespace
+
+/// Initializes an InclusionRewriter with a \p PP source and \p OS destination.
+InclusionRewriter::InclusionRewriter(Preprocessor &PP, raw_ostream &OS,
+                                     bool ShowLineMarkers)
+  : PP(PP), SM(PP.getSourceManager()), OS(OS), PredefinesBuffer(nullptr),
+    ShowLineMarkers(ShowLineMarkers),
+    LastInsertedFileChange(FileChanges.end()) {
+  // If we're in microsoft mode, use normal #line instead of line markers.
+  UseLineDirective = PP.getLangOpts().MicrosoftExt;
+}
+
+/// Write appropriate line information as either #line directives or GNU line
+/// markers depending on what mode we're in, including the \p Filename and
+/// \p Line we are located at, using the specified \p EOL line separator, and
+/// any \p Extra context specifiers in GNU line directives.
+void InclusionRewriter::WriteLineInfo(const char *Filename, int Line,
+                                      SrcMgr::CharacteristicKind FileType,
+                                      StringRef EOL, StringRef Extra) {
+  if (!ShowLineMarkers)
+    return;
+  if (UseLineDirective) {
+    OS << "#line" << ' ' << Line << ' ' << '"';
+    OS.write_escaped(Filename);
+    OS << '"';
+  } else {
+    // Use GNU linemarkers as described here:
+    // http://gcc.gnu.org/onlinedocs/cpp/Preprocessor-Output.html
+    OS << '#' << ' ' << Line << ' ' << '"';
+    OS.write_escaped(Filename);
+    OS << '"';
+    if (!Extra.empty())
+      OS << Extra;
+    if (FileType == SrcMgr::C_System)
+      // "`3' This indicates that the following text comes from a system header
+      // file, so certain warnings should be suppressed."
+      OS << " 3";
+    else if (FileType == SrcMgr::C_ExternCSystem)
+      // as above for `3', plus "`4' This indicates that the following text
+      // should be treated as being wrapped in an implicit extern "C" block."
+      OS << " 3 4";
+  }
+  OS << EOL;
+}
+
+void InclusionRewriter::WriteImplicitModuleImport(const Module *Mod,
+                                                  StringRef EOL) {
+  OS << "@import " << Mod->getFullModuleName() << ";"
+     << " /* clang -frewrite-includes: implicit import */" << EOL;
+}
+
+/// FileChanged - Whenever the preprocessor enters or exits a #include file
+/// it invokes this handler.
+void InclusionRewriter::FileChanged(SourceLocation Loc,
+                                    FileChangeReason Reason,
+                                    SrcMgr::CharacteristicKind NewFileType,
+                                    FileID) {
+  if (Reason != EnterFile)
+    return;
+  if (LastInsertedFileChange == FileChanges.end())
+    // we didn't reach this file (eg: the main file) via an inclusion directive
+    return;
+  LastInsertedFileChange->second.Id = FullSourceLoc(Loc, SM).getFileID();
+  LastInsertedFileChange->second.FileType = NewFileType;
+  LastInsertedFileChange = FileChanges.end();
+}
+
+/// Called whenever an inclusion is skipped due to canonical header protection
+/// macros.
+void InclusionRewriter::FileSkipped(const FileEntry &/*ParentFile*/,
+                                    const Token &/*FilenameTok*/,
+                                    SrcMgr::CharacteristicKind /*FileType*/) {
+  assert(LastInsertedFileChange != FileChanges.end() && "A file, that wasn't "
+    "found via an inclusion directive, was skipped");
+  FileChanges.erase(LastInsertedFileChange);
+  LastInsertedFileChange = FileChanges.end();
+}
+
+/// This should be called whenever the preprocessor encounters include
+/// directives. It does not say whether the file has been included, but it
+/// provides more information about the directive (hash location instead
+/// of location inside the included file). It is assumed that the matching
+/// FileChanged() or FileSkipped() is called after this.
+void InclusionRewriter::InclusionDirective(SourceLocation HashLoc,
+                                           const Token &/*IncludeTok*/,
+                                           StringRef /*FileName*/,
+                                           bool /*IsAngled*/,
+                                           CharSourceRange /*FilenameRange*/,
+                                           const FileEntry * /*File*/,
+                                           StringRef /*SearchPath*/,
+                                           StringRef /*RelativePath*/,
+                                           const Module *Imported) {
+  assert(LastInsertedFileChange == FileChanges.end() && "Another inclusion "
+    "directive was found before the previous one was processed");
+  std::pair<FileChangeMap::iterator, bool> p = FileChanges.insert(
+    std::make_pair(HashLoc.getRawEncoding(), FileChange(HashLoc, Imported)));
+  assert(p.second && "Unexpected revisitation of the same include directive");
+  if (!Imported)
+    LastInsertedFileChange = p.first;
+}
+
+/// Simple lookup for a SourceLocation (specifically one denoting the hash in
+/// an inclusion directive) in the map of inclusion information, FileChanges.
+const InclusionRewriter::FileChange *
+InclusionRewriter::FindFileChangeLocation(SourceLocation Loc) const {
+  FileChangeMap::const_iterator I = FileChanges.find(Loc.getRawEncoding());
+  if (I != FileChanges.end())
+    return &I->second;
+  return nullptr;
+}
+
+/// Detect the likely line ending style of \p FromFile by examining the first
+/// newline found within it.
+static StringRef DetectEOL(const MemoryBuffer &FromFile) {
+  // detect what line endings the file uses, so that added content does not mix
+  // the style
+  const char *Pos = strchr(FromFile.getBufferStart(), '\n');
+  if (!Pos)
+    return "\n";
+  if (Pos + 1 < FromFile.getBufferEnd() && Pos[1] == '\r')
+    return "\n\r";
+  if (Pos - 1 >= FromFile.getBufferStart() && Pos[-1] == '\r')
+    return "\r\n";
+  return "\n";
+}
+
+/// Writes out bytes from \p FromFile, starting at \p NextToWrite and ending at
+/// \p WriteTo - 1.
+void InclusionRewriter::OutputContentUpTo(const MemoryBuffer &FromFile,
+                                          unsigned &WriteFrom, unsigned WriteTo,
+                                          StringRef EOL, int &Line,
+                                          bool EnsureNewline) {
+  if (WriteTo <= WriteFrom)
+    return;
+  if (&FromFile == PredefinesBuffer) {
+    // Ignore the #defines of the predefines buffer.
+    WriteFrom = WriteTo;
+    return;
+  }
+  OS.write(FromFile.getBufferStart() + WriteFrom, WriteTo - WriteFrom);
+  // count lines manually, it's faster than getPresumedLoc()
+  Line += std::count(FromFile.getBufferStart() + WriteFrom,
+                     FromFile.getBufferStart() + WriteTo, '\n');
+  if (EnsureNewline) {
+    char LastChar = FromFile.getBufferStart()[WriteTo - 1];
+    if (LastChar != '\n' && LastChar != '\r')
+      OS << EOL;
+  }
+  WriteFrom = WriteTo;
+}
+
+/// Print characters from \p FromFile starting at \p NextToWrite up until the
+/// inclusion directive at \p StartToken, then print out the inclusion
+/// inclusion directive disabled by a #if directive, updating \p NextToWrite
+/// and \p Line to track the number of source lines visited and the progress
+/// through the \p FromFile buffer.
+void InclusionRewriter::CommentOutDirective(Lexer &DirectiveLex,
+                                            const Token &StartToken,
+                                            const MemoryBuffer &FromFile,
+                                            StringRef EOL,
+                                            unsigned &NextToWrite, int &Line) {
+  OutputContentUpTo(FromFile, NextToWrite,
+    SM.getFileOffset(StartToken.getLocation()), EOL, Line, false);
+  Token DirectiveToken;
+  do {
+    DirectiveLex.LexFromRawLexer(DirectiveToken);
+  } while (!DirectiveToken.is(tok::eod) && DirectiveToken.isNot(tok::eof));
+  if (&FromFile == PredefinesBuffer) {
+    // OutputContentUpTo() would not output anything anyway.
+    return;
+  }
+  OS << "#if 0 /* expanded by -frewrite-includes */" << EOL;
+  OutputContentUpTo(FromFile, NextToWrite,
+    SM.getFileOffset(DirectiveToken.getLocation()) + DirectiveToken.getLength(),
+    EOL, Line, true);
+  OS << "#endif /* expanded by -frewrite-includes */" << EOL;
+}
+
+/// Find the next identifier in the pragma directive specified by \p RawToken.
+StringRef InclusionRewriter::NextIdentifierName(Lexer &RawLex,
+                                                Token &RawToken) {
+  RawLex.LexFromRawLexer(RawToken);
+  if (RawToken.is(tok::raw_identifier))
+    PP.LookUpIdentifierInfo(RawToken);
+  if (RawToken.is(tok::identifier))
+    return RawToken.getIdentifierInfo()->getName();
+  return StringRef();
+}
+
+// Expand __has_include and __has_include_next if possible. If there's no
+// definitive answer return false.
+bool InclusionRewriter::HandleHasInclude(
+    FileID FileId, Lexer &RawLex, const DirectoryLookup *Lookup, Token &Tok,
+    bool &FileExists) {
+  // Lex the opening paren.
+  RawLex.LexFromRawLexer(Tok);
+  if (Tok.isNot(tok::l_paren))
+    return false;
+
+  RawLex.LexFromRawLexer(Tok);
+
+  SmallString<128> FilenameBuffer;
+  StringRef Filename;
+  // Since the raw lexer doesn't give us angle_literals we have to parse them
+  // ourselves.
+  // FIXME: What to do if the file name is a macro?
+  if (Tok.is(tok::less)) {
+    RawLex.LexFromRawLexer(Tok);
+
+    FilenameBuffer += '<';
+    do {
+      if (Tok.is(tok::eod)) // Sanity check.
+        return false;
+
+      if (Tok.is(tok::raw_identifier))
+        PP.LookUpIdentifierInfo(Tok);
+
+      // Get the string piece.
+      SmallVector<char, 128> TmpBuffer;
+      bool Invalid = false;
+      StringRef TmpName = PP.getSpelling(Tok, TmpBuffer, &Invalid);
+      if (Invalid)
+        return false;
+
+      FilenameBuffer += TmpName;
+
+      RawLex.LexFromRawLexer(Tok);
+    } while (Tok.isNot(tok::greater));
+
+    FilenameBuffer += '>';
+    Filename = FilenameBuffer;
+  } else {
+    if (Tok.isNot(tok::string_literal))
+      return false;
+
+    bool Invalid = false;
+    Filename = PP.getSpelling(Tok, FilenameBuffer, &Invalid);
+    if (Invalid)
+      return false;
+  }
+
+  // Lex the closing paren.
+  RawLex.LexFromRawLexer(Tok);
+  if (Tok.isNot(tok::r_paren))
+    return false;
+
+  // Now ask HeaderInfo if it knows about the header.
+  // FIXME: Subframeworks aren't handled here. Do we care?
+  bool isAngled = PP.GetIncludeFilenameSpelling(Tok.getLocation(), Filename);
+  const DirectoryLookup *CurDir;
+  const FileEntry *File = PP.getHeaderSearchInfo().LookupFile(
+      Filename, SourceLocation(), isAngled, nullptr, CurDir,
+      PP.getSourceManager().getFileEntryForID(FileId), nullptr, nullptr,
+      nullptr, false);
+
+  FileExists = File != nullptr;
+  return true;
+}
+
+/// Use a raw lexer to analyze \p FileId, incrementally copying parts of it
+/// and including content of included files recursively.
+bool InclusionRewriter::Process(FileID FileId,
+                                SrcMgr::CharacteristicKind FileType)
+{
+  bool Invalid;
+  const MemoryBuffer &FromFile = *SM.getBuffer(FileId, &Invalid);
+  if (Invalid) // invalid inclusion
+    return false;
+  const char *FileName = FromFile.getBufferIdentifier();
+  Lexer RawLex(FileId, &FromFile, PP.getSourceManager(), PP.getLangOpts());
+  RawLex.SetCommentRetentionState(false);
+
+  StringRef EOL = DetectEOL(FromFile);
+
+  // Per the GNU docs: "1" indicates entering a new file.
+  if (FileId == SM.getMainFileID() || FileId == PP.getPredefinesFileID())
+    WriteLineInfo(FileName, 1, FileType, EOL, "");
+  else
+    WriteLineInfo(FileName, 1, FileType, EOL, " 1");
+
+  if (SM.getFileIDSize(FileId) == 0)
+    return false;
+
+  // The next byte to be copied from the source file, which may be non-zero if
+  // the lexer handled a BOM.
+  unsigned NextToWrite = SM.getFileOffset(RawLex.getSourceLocation());
+  assert(SM.getLineNumber(FileId, NextToWrite) == 1);
+  int Line = 1; // The current input file line number.
+
+  Token RawToken;
+  RawLex.LexFromRawLexer(RawToken);
+
+  // TODO: Consider adding a switch that strips possibly unimportant content,
+  // such as comments, to reduce the size of repro files.
+  while (RawToken.isNot(tok::eof)) {
+    if (RawToken.is(tok::hash) && RawToken.isAtStartOfLine()) {
+      RawLex.setParsingPreprocessorDirective(true);
+      Token HashToken = RawToken;
+      RawLex.LexFromRawLexer(RawToken);
+      if (RawToken.is(tok::raw_identifier))
+        PP.LookUpIdentifierInfo(RawToken);
+      if (RawToken.getIdentifierInfo() != nullptr) {
+        switch (RawToken.getIdentifierInfo()->getPPKeywordID()) {
+          case tok::pp_include:
+          case tok::pp_include_next:
+          case tok::pp_import: {
+            CommentOutDirective(RawLex, HashToken, FromFile, EOL, NextToWrite,
+              Line);
+            if (FileId != PP.getPredefinesFileID())
+              WriteLineInfo(FileName, Line - 1, FileType, EOL, "");
+            StringRef LineInfoExtra;
+            if (const FileChange *Change = FindFileChangeLocation(
+                HashToken.getLocation())) {
+              if (Change->Mod) {
+                WriteImplicitModuleImport(Change->Mod, EOL);
+
+              // else now include and recursively process the file
+              } else if (Process(Change->Id, Change->FileType)) {
+                // and set lineinfo back to this file, if the nested one was
+                // actually included
+                // `2' indicates returning to a file (after having included
+                // another file.
+                LineInfoExtra = " 2";
+              }
+            }
+            // fix up lineinfo (since commented out directive changed line
+            // numbers) for inclusions that were skipped due to header guards
+            WriteLineInfo(FileName, Line, FileType, EOL, LineInfoExtra);
+            break;
+          }
+          case tok::pp_pragma: {
+            StringRef Identifier = NextIdentifierName(RawLex, RawToken);
+            if (Identifier == "clang" || Identifier == "GCC") {
+              if (NextIdentifierName(RawLex, RawToken) == "system_header") {
+                // keep the directive in, commented out
+                CommentOutDirective(RawLex, HashToken, FromFile, EOL,
+                  NextToWrite, Line);
+                // update our own type
+                FileType = SM.getFileCharacteristic(RawToken.getLocation());
+                WriteLineInfo(FileName, Line, FileType, EOL);
+              }
+            } else if (Identifier == "once") {
+              // keep the directive in, commented out
+              CommentOutDirective(RawLex, HashToken, FromFile, EOL,
+                NextToWrite, Line);
+              WriteLineInfo(FileName, Line, FileType, EOL);
+            }
+            break;
+          }
+          case tok::pp_if:
+          case tok::pp_elif: {
+            bool elif = (RawToken.getIdentifierInfo()->getPPKeywordID() ==
+                         tok::pp_elif);
+            // Rewrite special builtin macros to avoid pulling in host details.
+            do {
+              // Walk over the directive.
+              RawLex.LexFromRawLexer(RawToken);
+              if (RawToken.is(tok::raw_identifier))
+                PP.LookUpIdentifierInfo(RawToken);
+
+              if (RawToken.is(tok::identifier)) {
+                bool HasFile;
+                SourceLocation Loc = RawToken.getLocation();
+
+                // Rewrite __has_include(x)
+                if (RawToken.getIdentifierInfo()->isStr("__has_include")) {
+                  if (!HandleHasInclude(FileId, RawLex, nullptr, RawToken,
+                                        HasFile))
+                    continue;
+                  // Rewrite __has_include_next(x)
+                } else if (RawToken.getIdentifierInfo()->isStr(
+                               "__has_include_next")) {
+                  const DirectoryLookup *Lookup = PP.GetCurDirLookup();
+                  if (Lookup)
+                    ++Lookup;
+
+                  if (!HandleHasInclude(FileId, RawLex, Lookup, RawToken,
+                                        HasFile))
+                    continue;
+                } else {
+                  continue;
+                }
+                // Replace the macro with (0) or (1), followed by the commented
+                // out macro for reference.
+                OutputContentUpTo(FromFile, NextToWrite, SM.getFileOffset(Loc),
+                                  EOL, Line, false);
+                OS << '(' << (int) HasFile << ")/*";
+                OutputContentUpTo(FromFile, NextToWrite,
+                                  SM.getFileOffset(RawToken.getLocation()) +
+                                  RawToken.getLength(),
+                                  EOL, Line, false);
+                OS << "*/";
+              }
+            } while (RawToken.isNot(tok::eod));
+            if (elif) {
+              OutputContentUpTo(FromFile, NextToWrite,
+                                SM.getFileOffset(RawToken.getLocation()) +
+                                    RawToken.getLength(),
+                                EOL, Line, /*EnsureNewLine*/ true);
+              WriteLineInfo(FileName, Line, FileType, EOL);
+            }
+            break;
+          }
+          case tok::pp_endif:
+          case tok::pp_else: {
+            // We surround every #include by #if 0 to comment it out, but that
+            // changes line numbers. These are fixed up right after that, but
+            // the whole #include could be inside a preprocessor conditional
+            // that is not processed. So it is necessary to fix the line
+            // numbers one the next line after each #else/#endif as well.
+            RawLex.SetKeepWhitespaceMode(true);
+            do {
+              RawLex.LexFromRawLexer(RawToken);
+            } while (RawToken.isNot(tok::eod) && RawToken.isNot(tok::eof));
+            OutputContentUpTo(
+                FromFile, NextToWrite,
+                SM.getFileOffset(RawToken.getLocation()) + RawToken.getLength(),
+                EOL, Line, /*EnsureNewLine*/ true);
+            WriteLineInfo(FileName, Line, FileType, EOL);
+            RawLex.SetKeepWhitespaceMode(false);
+          }
+          default:
+            break;
+        }
+      }
+      RawLex.setParsingPreprocessorDirective(false);
+    }
+    RawLex.LexFromRawLexer(RawToken);
+  }
+  OutputContentUpTo(FromFile, NextToWrite,
+    SM.getFileOffset(SM.getLocForEndOfFile(FileId)), EOL, Line,
+    /*EnsureNewline*/true);
+  return true;
+}
+
+/// InclusionRewriterInInput - Implement -frewrite-includes mode.
+void clang::RewriteIncludesInInput(Preprocessor &PP, raw_ostream *OS,
+                                   const PreprocessorOutputOptions &Opts) {
+  SourceManager &SM = PP.getSourceManager();
+  InclusionRewriter *Rewrite = new InclusionRewriter(PP, *OS,
+                                                     Opts.ShowLineMarkers);
+  PP.addPPCallbacks(Rewrite);
+  PP.IgnorePragmas();
+
+  // First let the preprocessor process the entire file and call callbacks.
+  // Callbacks will record which #include's were actually performed.
+  PP.EnterMainSourceFile();
+  Token Tok;
+  // Only preprocessor directives matter here, so disable macro expansion
+  // everywhere else as an optimization.
+  // TODO: It would be even faster if the preprocessor could be switched
+  // to a mode where it would parse only preprocessor directives and comments,
+  // nothing else matters for parsing or processing.
+  PP.SetMacroExpansionOnlyInDirectives();
+  do {
+    PP.Lex(Tok);
+  } while (Tok.isNot(tok::eof));
+  Rewrite->setPredefinesBuffer(SM.getBuffer(PP.getPredefinesFileID()));
+  Rewrite->Process(PP.getPredefinesFileID(), SrcMgr::C_User);
+  Rewrite->Process(SM.getMainFileID(), SrcMgr::C_User);
+  OS->flush();
+}
diff --git a/lib/Frontend/Rewrite/Makefile b/lib/Frontend/Rewrite/Makefile
new file mode 100644
index 0000000..1d56547
--- /dev/null
+++ b/lib/Frontend/Rewrite/Makefile
@@ -0,0 +1,22 @@
+##===- clang/lib/Rewrite/Makefile --------------------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+#
+# This implements code transformation / rewriting facilities.
+#
+##===----------------------------------------------------------------------===##
+
+CLANG_LEVEL := ../../..
+LIBRARYNAME := clangRewriteFrontend
+
+include $(CLANG_LEVEL)/Makefile
+
+ifeq ($(ENABLE_CLANG_ARCMT),1)
+  CXX.Flags += -DCLANG_ENABLE_OBJC_REWRITER
+endif
+
diff --git a/lib/Frontend/Rewrite/RewriteMacros.cpp b/lib/Frontend/Rewrite/RewriteMacros.cpp
new file mode 100644
index 0000000..0d0a991
--- /dev/null
+++ b/lib/Frontend/Rewrite/RewriteMacros.cpp
@@ -0,0 +1,217 @@
+//===--- RewriteMacros.cpp - Rewrite macros into their expansions ---------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This code rewrites macro invocations into their expansions.  This gives you
+// a macro expanded file that retains comments and #includes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Rewrite/Frontend/Rewriters.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Rewrite/Core/Rewriter.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstdio>
+#include <memory>
+
+using namespace clang;
+
+/// isSameToken - Return true if the two specified tokens start have the same
+/// content.
+static bool isSameToken(Token &RawTok, Token &PPTok) {
+  // If two tokens have the same kind and the same identifier info, they are
+  // obviously the same.
+  if (PPTok.getKind() == RawTok.getKind() &&
+      PPTok.getIdentifierInfo() == RawTok.getIdentifierInfo())
+    return true;
+
+  // Otherwise, if they are different but have the same identifier info, they
+  // are also considered to be the same.  This allows keywords and raw lexed
+  // identifiers with the same name to be treated the same.
+  if (PPTok.getIdentifierInfo() &&
+      PPTok.getIdentifierInfo() == RawTok.getIdentifierInfo())
+    return true;
+
+  return false;
+}
+
+
+/// GetNextRawTok - Return the next raw token in the stream, skipping over
+/// comments if ReturnComment is false.
+static const Token &GetNextRawTok(const std::vector<Token> &RawTokens,
+                                  unsigned &CurTok, bool ReturnComment) {
+  assert(CurTok < RawTokens.size() && "Overran eof!");
+
+  // If the client doesn't want comments and we have one, skip it.
+  if (!ReturnComment && RawTokens[CurTok].is(tok::comment))
+    ++CurTok;
+
+  return RawTokens[CurTok++];
+}
+
+
+/// LexRawTokensFromMainFile - Lets all the raw tokens from the main file into
+/// the specified vector.
+static void LexRawTokensFromMainFile(Preprocessor &PP,
+                                     std::vector<Token> &RawTokens) {
+  SourceManager &SM = PP.getSourceManager();
+
+  // Create a lexer to lex all the tokens of the main file in raw mode.  Even
+  // though it is in raw mode, it will not return comments.
+  const llvm::MemoryBuffer *FromFile = SM.getBuffer(SM.getMainFileID());
+  Lexer RawLex(SM.getMainFileID(), FromFile, SM, PP.getLangOpts());
+
+  // Switch on comment lexing because we really do want them.
+  RawLex.SetCommentRetentionState(true);
+
+  Token RawTok;
+  do {
+    RawLex.LexFromRawLexer(RawTok);
+
+    // If we have an identifier with no identifier info for our raw token, look
+    // up the indentifier info.  This is important for equality comparison of
+    // identifier tokens.
+    if (RawTok.is(tok::raw_identifier))
+      PP.LookUpIdentifierInfo(RawTok);
+
+    RawTokens.push_back(RawTok);
+  } while (RawTok.isNot(tok::eof));
+}
+
+
+/// RewriteMacrosInInput - Implement -rewrite-macros mode.
+void clang::RewriteMacrosInInput(Preprocessor &PP, raw_ostream *OS) {
+  SourceManager &SM = PP.getSourceManager();
+
+  Rewriter Rewrite;
+  Rewrite.setSourceMgr(SM, PP.getLangOpts());
+  RewriteBuffer &RB = Rewrite.getEditBuffer(SM.getMainFileID());
+
+  std::vector<Token> RawTokens;
+  LexRawTokensFromMainFile(PP, RawTokens);
+  unsigned CurRawTok = 0;
+  Token RawTok = GetNextRawTok(RawTokens, CurRawTok, false);
+
+
+  // Get the first preprocessing token.
+  PP.EnterMainSourceFile();
+  Token PPTok;
+  PP.Lex(PPTok);
+
+  // Preprocess the input file in parallel with raw lexing the main file. Ignore
+  // all tokens that are preprocessed from a file other than the main file (e.g.
+  // a header).  If we see tokens that are in the preprocessed file but not the
+  // lexed file, we have a macro expansion.  If we see tokens in the lexed file
+  // that aren't in the preprocessed view, we have macros that expand to no
+  // tokens, or macro arguments etc.
+  while (RawTok.isNot(tok::eof) || PPTok.isNot(tok::eof)) {
+    SourceLocation PPLoc = SM.getExpansionLoc(PPTok.getLocation());
+
+    // If PPTok is from a different source file, ignore it.
+    if (!SM.isWrittenInMainFile(PPLoc)) {
+      PP.Lex(PPTok);
+      continue;
+    }
+
+    // If the raw file hits a preprocessor directive, they will be extra tokens
+    // in the raw file that don't exist in the preprocsesed file.  However, we
+    // choose to preserve them in the output file and otherwise handle them
+    // specially.
+    if (RawTok.is(tok::hash) && RawTok.isAtStartOfLine()) {
+      // If this is a #warning directive or #pragma mark (GNU extensions),
+      // comment the line out.
+      if (RawTokens[CurRawTok].is(tok::identifier)) {
+        const IdentifierInfo *II = RawTokens[CurRawTok].getIdentifierInfo();
+        if (II->getName() == "warning") {
+          // Comment out #warning.
+          RB.InsertTextAfter(SM.getFileOffset(RawTok.getLocation()), "//");
+        } else if (II->getName() == "pragma" &&
+                   RawTokens[CurRawTok+1].is(tok::identifier) &&
+                   (RawTokens[CurRawTok+1].getIdentifierInfo()->getName() ==
+                    "mark")) {
+          // Comment out #pragma mark.
+          RB.InsertTextAfter(SM.getFileOffset(RawTok.getLocation()), "//");
+        }
+      }
+
+      // Otherwise, if this is a #include or some other directive, just leave it
+      // in the file by skipping over the line.
+      RawTok = GetNextRawTok(RawTokens, CurRawTok, false);
+      while (!RawTok.isAtStartOfLine() && RawTok.isNot(tok::eof))
+        RawTok = GetNextRawTok(RawTokens, CurRawTok, false);
+      continue;
+    }
+
+    // Okay, both tokens are from the same file.  Get their offsets from the
+    // start of the file.
+    unsigned PPOffs = SM.getFileOffset(PPLoc);
+    unsigned RawOffs = SM.getFileOffset(RawTok.getLocation());
+
+    // If the offsets are the same and the token kind is the same, ignore them.
+    if (PPOffs == RawOffs && isSameToken(RawTok, PPTok)) {
+      RawTok = GetNextRawTok(RawTokens, CurRawTok, false);
+      PP.Lex(PPTok);
+      continue;
+    }
+
+    // If the PP token is farther along than the raw token, something was
+    // deleted.  Comment out the raw token.
+    if (RawOffs <= PPOffs) {
+      // Comment out a whole run of tokens instead of bracketing each one with
+      // comments.  Add a leading space if RawTok didn't have one.
+      bool HasSpace = RawTok.hasLeadingSpace();
+      RB.InsertTextAfter(RawOffs, &" /*"[HasSpace]);
+      unsigned EndPos;
+
+      do {
+        EndPos = RawOffs+RawTok.getLength();
+
+        RawTok = GetNextRawTok(RawTokens, CurRawTok, true);
+        RawOffs = SM.getFileOffset(RawTok.getLocation());
+
+        if (RawTok.is(tok::comment)) {
+          // Skip past the comment.
+          RawTok = GetNextRawTok(RawTokens, CurRawTok, false);
+          break;
+        }
+
+      } while (RawOffs <= PPOffs && !RawTok.isAtStartOfLine() &&
+               (PPOffs != RawOffs || !isSameToken(RawTok, PPTok)));
+
+      RB.InsertTextBefore(EndPos, "*/");
+      continue;
+    }
+
+    // Otherwise, there was a replacement an expansion.  Insert the new token
+    // in the output buffer.  Insert the whole run of new tokens at once to get
+    // them in the right order.
+    unsigned InsertPos = PPOffs;
+    std::string Expansion;
+    while (PPOffs < RawOffs) {
+      Expansion += ' ' + PP.getSpelling(PPTok);
+      PP.Lex(PPTok);
+      PPLoc = SM.getExpansionLoc(PPTok.getLocation());
+      PPOffs = SM.getFileOffset(PPLoc);
+    }
+    Expansion += ' ';
+    RB.InsertTextBefore(InsertPos, Expansion);
+  }
+
+  // Get the buffer corresponding to MainFileID.  If we haven't changed it, then
+  // we are done.
+  if (const RewriteBuffer *RewriteBuf =
+      Rewrite.getRewriteBufferFor(SM.getMainFileID())) {
+    //printf("Changed:\n");
+    *OS << std::string(RewriteBuf->begin(), RewriteBuf->end());
+  } else {
+    fprintf(stderr, "No changes\n");
+  }
+  OS->flush();
+}
diff --git a/lib/Frontend/Rewrite/RewriteModernObjC.cpp b/lib/Frontend/Rewrite/RewriteModernObjC.cpp
new file mode 100644
index 0000000..3e18a8b
--- /dev/null
+++ b/lib/Frontend/Rewrite/RewriteModernObjC.cpp
@@ -0,0 +1,7760 @@
+//===--- RewriteObjC.cpp - Playground for the code rewriter ---------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Hacks and fun related to the code rewriter.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Rewrite/Frontend/ASTConsumers.h"
+#include "clang/AST/AST.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/Attr.h"
+#include "clang/AST/ParentMap.h"
+#include "clang/Basic/CharInfo.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Rewrite/Core/Rewriter.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+#include <memory>
+
+#ifdef CLANG_ENABLE_OBJC_REWRITER
+
+using namespace clang;
+using llvm::utostr;
+
+namespace {
+  class RewriteModernObjC : public ASTConsumer {
+  protected:
+    
+    enum {
+      BLOCK_FIELD_IS_OBJECT   =  3,  /* id, NSObject, __attribute__((NSObject)),
+                                        block, ... */
+      BLOCK_FIELD_IS_BLOCK    =  7,  /* a block variable */
+      BLOCK_FIELD_IS_BYREF    =  8,  /* the on stack structure holding the 
+                                        __block variable */
+      BLOCK_FIELD_IS_WEAK     = 16,  /* declared __weak, only used in byref copy
+                                        helpers */
+      BLOCK_BYREF_CALLER      = 128, /* called from __block (byref) copy/dispose
+                                        support routines */
+      BLOCK_BYREF_CURRENT_MAX = 256
+    };
+    
+    enum {
+      BLOCK_NEEDS_FREE =        (1 << 24),
+      BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
+      BLOCK_HAS_CXX_OBJ =       (1 << 26),
+      BLOCK_IS_GC =             (1 << 27),
+      BLOCK_IS_GLOBAL =         (1 << 28),
+      BLOCK_HAS_DESCRIPTOR =    (1 << 29)
+    };
+    
+    Rewriter Rewrite;
+    DiagnosticsEngine &Diags;
+    const LangOptions &LangOpts;
+    ASTContext *Context;
+    SourceManager *SM;
+    TranslationUnitDecl *TUDecl;
+    FileID MainFileID;
+    const char *MainFileStart, *MainFileEnd;
+    Stmt *CurrentBody;
+    ParentMap *PropParentMap; // created lazily.
+    std::string InFileName;
+    raw_ostream* OutFile;
+    std::string Preamble;
+    
+    TypeDecl *ProtocolTypeDecl;
+    VarDecl *GlobalVarDecl;
+    Expr *GlobalConstructionExp;
+    unsigned RewriteFailedDiag;
+    unsigned GlobalBlockRewriteFailedDiag;
+    // ObjC string constant support.
+    unsigned NumObjCStringLiterals;
+    VarDecl *ConstantStringClassReference;
+    RecordDecl *NSStringRecord;
+
+    // ObjC foreach break/continue generation support.
+    int BcLabelCount;
+    
+    unsigned TryFinallyContainsReturnDiag;
+    // Needed for super.
+    ObjCMethodDecl *CurMethodDef;
+    RecordDecl *SuperStructDecl;
+    RecordDecl *ConstantStringDecl;
+    
+    FunctionDecl *MsgSendFunctionDecl;
+    FunctionDecl *MsgSendSuperFunctionDecl;
+    FunctionDecl *MsgSendStretFunctionDecl;
+    FunctionDecl *MsgSendSuperStretFunctionDecl;
+    FunctionDecl *MsgSendFpretFunctionDecl;
+    FunctionDecl *GetClassFunctionDecl;
+    FunctionDecl *GetMetaClassFunctionDecl;
+    FunctionDecl *GetSuperClassFunctionDecl;
+    FunctionDecl *SelGetUidFunctionDecl;
+    FunctionDecl *CFStringFunctionDecl;
+    FunctionDecl *SuperConstructorFunctionDecl;
+    FunctionDecl *CurFunctionDef;
+
+    /* Misc. containers needed for meta-data rewrite. */
+    SmallVector<ObjCImplementationDecl *, 8> ClassImplementation;
+    SmallVector<ObjCCategoryImplDecl *, 8> CategoryImplementation;
+    llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCSynthesizedStructs;
+    llvm::SmallPtrSet<ObjCProtocolDecl*, 8> ObjCSynthesizedProtocols;
+    llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCWrittenInterfaces;
+    llvm::SmallPtrSet<TagDecl*, 32> GlobalDefinedTags;
+    SmallVector<ObjCInterfaceDecl*, 32> ObjCInterfacesSeen;
+    /// DefinedNonLazyClasses - List of defined "non-lazy" classes.
+    SmallVector<ObjCInterfaceDecl*, 8> DefinedNonLazyClasses;
+    
+    /// DefinedNonLazyCategories - List of defined "non-lazy" categories.
+    SmallVector<ObjCCategoryDecl *, 8> DefinedNonLazyCategories;
+    
+    SmallVector<Stmt *, 32> Stmts;
+    SmallVector<int, 8> ObjCBcLabelNo;
+    // Remember all the @protocol(<expr>) expressions.
+    llvm::SmallPtrSet<ObjCProtocolDecl *, 32> ProtocolExprDecls;
+    
+    llvm::DenseSet<uint64_t> CopyDestroyCache;
+
+    // Block expressions.
+    SmallVector<BlockExpr *, 32> Blocks;
+    SmallVector<int, 32> InnerDeclRefsCount;
+    SmallVector<DeclRefExpr *, 32> InnerDeclRefs;
+    
+    SmallVector<DeclRefExpr *, 32> BlockDeclRefs;
+
+    
+    // Block related declarations.
+    SmallVector<ValueDecl *, 8> BlockByCopyDecls;
+    llvm::SmallPtrSet<ValueDecl *, 8> BlockByCopyDeclsPtrSet;
+    SmallVector<ValueDecl *, 8> BlockByRefDecls;
+    llvm::SmallPtrSet<ValueDecl *, 8> BlockByRefDeclsPtrSet;
+    llvm::DenseMap<ValueDecl *, unsigned> BlockByRefDeclNo;
+    llvm::SmallPtrSet<ValueDecl *, 8> ImportedBlockDecls;
+    llvm::SmallPtrSet<VarDecl *, 8> ImportedLocalExternalDecls;
+    
+    llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs;
+    llvm::DenseMap<ObjCInterfaceDecl *, 
+                    llvm::SmallPtrSet<ObjCIvarDecl *, 8> > ReferencedIvars;
+    
+    // ivar bitfield grouping containers
+    llvm::DenseSet<const ObjCInterfaceDecl *> ObjCInterefaceHasBitfieldGroups;
+    llvm::DenseMap<const ObjCIvarDecl* , unsigned> IvarGroupNumber;
+    // This container maps an <class, group number for ivar> tuple to the type
+    // of the struct where the bitfield belongs.
+    llvm::DenseMap<std::pair<const ObjCInterfaceDecl*, unsigned>, QualType> GroupRecordType;
+    SmallVector<FunctionDecl*, 32> FunctionDefinitionsSeen;
+    
+    // This maps an original source AST to it's rewritten form. This allows
+    // us to avoid rewriting the same node twice (which is very uncommon).
+    // This is needed to support some of the exotic property rewriting.
+    llvm::DenseMap<Stmt *, Stmt *> ReplacedNodes;
+
+    // Needed for header files being rewritten
+    bool IsHeader;
+    bool SilenceRewriteMacroWarning;
+    bool GenerateLineInfo;
+    bool objc_impl_method;
+    
+    bool DisableReplaceStmt;
+    class DisableReplaceStmtScope {
+      RewriteModernObjC &R;
+      bool SavedValue;
+    
+    public:
+      DisableReplaceStmtScope(RewriteModernObjC &R)
+        : R(R), SavedValue(R.DisableReplaceStmt) {
+        R.DisableReplaceStmt = true;
+      }
+      ~DisableReplaceStmtScope() {
+        R.DisableReplaceStmt = SavedValue;
+      }
+    };
+    void InitializeCommon(ASTContext &context);
+
+  public:
+    llvm::DenseMap<ObjCMethodDecl*, std::string> MethodInternalNames;
+    // Top Level Driver code.
+    bool HandleTopLevelDecl(DeclGroupRef D) override {
+      for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) {
+        if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*I)) {
+          if (!Class->isThisDeclarationADefinition()) {
+            RewriteForwardClassDecl(D);
+            break;
+          } else {
+            // Keep track of all interface declarations seen.
+            ObjCInterfacesSeen.push_back(Class);
+            break;
+          }
+        }
+
+        if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*I)) {
+          if (!Proto->isThisDeclarationADefinition()) {
+            RewriteForwardProtocolDecl(D);
+            break;
+          }
+        }
+
+        if (FunctionDecl *FDecl = dyn_cast<FunctionDecl>(*I)) {
+          // Under modern abi, we cannot translate body of the function
+          // yet until all class extensions and its implementation is seen.
+          // This is because they may introduce new bitfields which must go
+          // into their grouping struct.
+          if (FDecl->isThisDeclarationADefinition() &&
+              // Not c functions defined inside an objc container.
+              !FDecl->isTopLevelDeclInObjCContainer()) {
+            FunctionDefinitionsSeen.push_back(FDecl);
+            break;
+          }
+        }
+        HandleTopLevelSingleDecl(*I);
+      }
+      return true;
+    }
+
+    void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override {
+      for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) {
+        if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(*I)) {
+          if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
+            RewriteBlockPointerDecl(TD);
+          else if (TD->getUnderlyingType()->isFunctionPointerType())
+            CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
+          else
+            RewriteObjCQualifiedInterfaceTypes(TD);
+        }
+      }
+      return;
+    }
+    
+    void HandleTopLevelSingleDecl(Decl *D);
+    void HandleDeclInMainFile(Decl *D);
+    RewriteModernObjC(std::string inFile, raw_ostream *OS,
+                DiagnosticsEngine &D, const LangOptions &LOpts,
+                bool silenceMacroWarn, bool LineInfo);
+    
+    ~RewriteModernObjC() {}
+
+    void HandleTranslationUnit(ASTContext &C) override;
+
+    void ReplaceStmt(Stmt *Old, Stmt *New) {
+      Stmt *ReplacingStmt = ReplacedNodes[Old];
+
+      if (ReplacingStmt)
+        return; // We can't rewrite the same node twice.
+
+      if (DisableReplaceStmt)
+        return;
+
+      // If replacement succeeded or warning disabled return with no warning.
+      if (!Rewrite.ReplaceStmt(Old, New)) {
+        ReplacedNodes[Old] = New;
+        return;
+      }
+      if (SilenceRewriteMacroWarning)
+        return;
+      Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag)
+                   << Old->getSourceRange();
+    }
+
+    void ReplaceStmtWithRange(Stmt *Old, Stmt *New, SourceRange SrcRange) {
+      assert(Old != nullptr && New != nullptr && "Expected non-null Stmt's");
+      if (DisableReplaceStmt)
+        return;
+
+      // Measure the old text.
+      int Size = Rewrite.getRangeSize(SrcRange);
+      if (Size == -1) {
+        Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag)
+                     << Old->getSourceRange();
+        return;
+      }
+      // Get the new text.
+      std::string SStr;
+      llvm::raw_string_ostream S(SStr);
+      New->printPretty(S, nullptr, PrintingPolicy(LangOpts));
+      const std::string &Str = S.str();
+
+      // If replacement succeeded or warning disabled return with no warning.
+      if (!Rewrite.ReplaceText(SrcRange.getBegin(), Size, Str)) {
+        ReplacedNodes[Old] = New;
+        return;
+      }
+      if (SilenceRewriteMacroWarning)
+        return;
+      Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag)
+                   << Old->getSourceRange();
+    }
+
+    void InsertText(SourceLocation Loc, StringRef Str,
+                    bool InsertAfter = true) {
+      // If insertion succeeded or warning disabled return with no warning.
+      if (!Rewrite.InsertText(Loc, Str, InsertAfter) ||
+          SilenceRewriteMacroWarning)
+        return;
+
+      Diags.Report(Context->getFullLoc(Loc), RewriteFailedDiag);
+    }
+
+    void ReplaceText(SourceLocation Start, unsigned OrigLength,
+                     StringRef Str) {
+      // If removal succeeded or warning disabled return with no warning.
+      if (!Rewrite.ReplaceText(Start, OrigLength, Str) ||
+          SilenceRewriteMacroWarning)
+        return;
+
+      Diags.Report(Context->getFullLoc(Start), RewriteFailedDiag);
+    }
+
+    // Syntactic Rewriting.
+    void RewriteRecordBody(RecordDecl *RD);
+    void RewriteInclude();
+    void RewriteLineDirective(const Decl *D);
+    void ConvertSourceLocationToLineDirective(SourceLocation Loc,
+                                              std::string &LineString);
+    void RewriteForwardClassDecl(DeclGroupRef D);
+    void RewriteForwardClassDecl(const SmallVectorImpl<Decl *> &DG);
+    void RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl, 
+                                     const std::string &typedefString);
+    void RewriteImplementations();
+    void RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
+                                 ObjCImplementationDecl *IMD,
+                                 ObjCCategoryImplDecl *CID);
+    void RewriteInterfaceDecl(ObjCInterfaceDecl *Dcl);
+    void RewriteImplementationDecl(Decl *Dcl);
+    void RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl,
+                               ObjCMethodDecl *MDecl, std::string &ResultStr);
+    void RewriteTypeIntoString(QualType T, std::string &ResultStr,
+                               const FunctionType *&FPRetType);
+    void RewriteByRefString(std::string &ResultStr, const std::string &Name,
+                            ValueDecl *VD, bool def=false);
+    void RewriteCategoryDecl(ObjCCategoryDecl *Dcl);
+    void RewriteProtocolDecl(ObjCProtocolDecl *Dcl);
+    void RewriteForwardProtocolDecl(DeclGroupRef D);
+    void RewriteForwardProtocolDecl(const SmallVectorImpl<Decl *> &DG);
+    void RewriteMethodDeclaration(ObjCMethodDecl *Method);
+    void RewriteProperty(ObjCPropertyDecl *prop);
+    void RewriteFunctionDecl(FunctionDecl *FD);
+    void RewriteBlockPointerType(std::string& Str, QualType Type);
+    void RewriteBlockPointerTypeVariable(std::string& Str, ValueDecl *VD);
+    void RewriteBlockLiteralFunctionDecl(FunctionDecl *FD);
+    void RewriteObjCQualifiedInterfaceTypes(Decl *Dcl);
+    void RewriteTypeOfDecl(VarDecl *VD);
+    void RewriteObjCQualifiedInterfaceTypes(Expr *E);
+    
+    std::string getIvarAccessString(ObjCIvarDecl *D);
+  
+    // Expression Rewriting.
+    Stmt *RewriteFunctionBodyOrGlobalInitializer(Stmt *S);
+    Stmt *RewriteAtEncode(ObjCEncodeExpr *Exp);
+    Stmt *RewritePropertyOrImplicitGetter(PseudoObjectExpr *Pseudo);
+    Stmt *RewritePropertyOrImplicitSetter(PseudoObjectExpr *Pseudo);
+    Stmt *RewriteAtSelector(ObjCSelectorExpr *Exp);
+    Stmt *RewriteMessageExpr(ObjCMessageExpr *Exp);
+    Stmt *RewriteObjCStringLiteral(ObjCStringLiteral *Exp);
+    Stmt *RewriteObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Exp);
+    Stmt *RewriteObjCBoxedExpr(ObjCBoxedExpr *Exp);
+    Stmt *RewriteObjCArrayLiteralExpr(ObjCArrayLiteral *Exp);
+    Stmt *RewriteObjCDictionaryLiteralExpr(ObjCDictionaryLiteral *Exp);
+    Stmt *RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp);
+    Stmt *RewriteObjCTryStmt(ObjCAtTryStmt *S);
+    Stmt *RewriteObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt  *S);
+    Stmt *RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S);
+    Stmt *RewriteObjCThrowStmt(ObjCAtThrowStmt *S);
+    Stmt *RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
+                                       SourceLocation OrigEnd);
+    Stmt *RewriteBreakStmt(BreakStmt *S);
+    Stmt *RewriteContinueStmt(ContinueStmt *S);
+    void RewriteCastExpr(CStyleCastExpr *CE);
+    void RewriteImplicitCastObjCExpr(CastExpr *IE);
+    void RewriteLinkageSpec(LinkageSpecDecl *LSD);
+    
+    // Computes ivar bitfield group no.
+    unsigned ObjCIvarBitfieldGroupNo(ObjCIvarDecl *IV);
+    // Names field decl. for ivar bitfield group.
+    void ObjCIvarBitfieldGroupDecl(ObjCIvarDecl *IV, std::string &Result);
+    // Names struct type for ivar bitfield group.
+    void ObjCIvarBitfieldGroupType(ObjCIvarDecl *IV, std::string &Result);
+    // Names symbol for ivar bitfield group field offset.
+    void ObjCIvarBitfieldGroupOffset(ObjCIvarDecl *IV, std::string &Result);
+    // Given an ivar bitfield, it builds (or finds) its group record type.
+    QualType GetGroupRecordTypeForObjCIvarBitfield(ObjCIvarDecl *IV);
+    QualType SynthesizeBitfieldGroupStructType(
+                                    ObjCIvarDecl *IV,
+                                    SmallVectorImpl<ObjCIvarDecl *> &IVars);
+    
+    // Block rewriting.
+    void RewriteBlocksInFunctionProtoType(QualType funcType, NamedDecl *D);
+    
+    // Block specific rewrite rules.
+    void RewriteBlockPointerDecl(NamedDecl *VD);
+    void RewriteByRefVar(VarDecl *VD, bool firstDecl, bool lastDecl);
+    Stmt *RewriteBlockDeclRefExpr(DeclRefExpr *VD);
+    Stmt *RewriteLocalVariableExternalStorage(DeclRefExpr *DRE);
+    void RewriteBlockPointerFunctionArgs(FunctionDecl *FD);
+    
+    void RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl,
+                                      std::string &Result);
+    
+    void RewriteObjCFieldDecl(FieldDecl *fieldDecl, std::string &Result);
+    bool IsTagDefinedInsideClass(ObjCContainerDecl *IDecl, TagDecl *Tag,
+                                 bool &IsNamedDefinition);
+    void RewriteLocallyDefinedNamedAggregates(FieldDecl *fieldDecl, 
+                                              std::string &Result);
+    
+    bool RewriteObjCFieldDeclType(QualType &Type, std::string &Result);
+    
+    void RewriteIvarOffsetSymbols(ObjCInterfaceDecl *CDecl,
+                                  std::string &Result);
+
+    void Initialize(ASTContext &context) override;
+
+    // Misc. AST transformation routines. Sometimes they end up calling
+    // rewriting routines on the new ASTs.
+    CallExpr *SynthesizeCallToFunctionDecl(FunctionDecl *FD,
+                                           Expr **args, unsigned nargs,
+                                           SourceLocation StartLoc=SourceLocation(),
+                                           SourceLocation EndLoc=SourceLocation());
+    
+    Expr *SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFlavor,
+                                        QualType returnType, 
+                                        SmallVectorImpl<QualType> &ArgTypes,
+                                        SmallVectorImpl<Expr*> &MsgExprs,
+                                        ObjCMethodDecl *Method);
+
+    Stmt *SynthMessageExpr(ObjCMessageExpr *Exp,
+                           SourceLocation StartLoc=SourceLocation(),
+                           SourceLocation EndLoc=SourceLocation());
+    
+    void SynthCountByEnumWithState(std::string &buf);
+    void SynthMsgSendFunctionDecl();
+    void SynthMsgSendSuperFunctionDecl();
+    void SynthMsgSendStretFunctionDecl();
+    void SynthMsgSendFpretFunctionDecl();
+    void SynthMsgSendSuperStretFunctionDecl();
+    void SynthGetClassFunctionDecl();
+    void SynthGetMetaClassFunctionDecl();
+    void SynthGetSuperClassFunctionDecl();
+    void SynthSelGetUidFunctionDecl();
+    void SynthSuperConstructorFunctionDecl();
+    
+    // Rewriting metadata
+    template<typename MethodIterator>
+    void RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
+                                    MethodIterator MethodEnd,
+                                    bool IsInstanceMethod,
+                                    StringRef prefix,
+                                    StringRef ClassName,
+                                    std::string &Result);
+    void RewriteObjCProtocolMetaData(ObjCProtocolDecl *Protocol,
+                                     std::string &Result);
+    void RewriteObjCProtocolListMetaData(
+                   const ObjCList<ObjCProtocolDecl> &Prots,
+                   StringRef prefix, StringRef ClassName, std::string &Result);
+    void RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
+                                          std::string &Result);
+    void RewriteClassSetupInitHook(std::string &Result);
+    
+    void RewriteMetaDataIntoBuffer(std::string &Result);
+    void WriteImageInfo(std::string &Result);
+    void RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *CDecl,
+                                             std::string &Result);
+    void RewriteCategorySetupInitHook(std::string &Result);
+    
+    // Rewriting ivar
+    void RewriteIvarOffsetComputation(ObjCIvarDecl *ivar,
+                                              std::string &Result);
+    Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV);
+
+    
+    std::string SynthesizeByrefCopyDestroyHelper(VarDecl *VD, int flag);
+    std::string SynthesizeBlockHelperFuncs(BlockExpr *CE, int i,
+                                      StringRef funcName, std::string Tag);
+    std::string SynthesizeBlockFunc(BlockExpr *CE, int i,
+                                      StringRef funcName, std::string Tag);
+    std::string SynthesizeBlockImpl(BlockExpr *CE, 
+                                    std::string Tag, std::string Desc);
+    std::string SynthesizeBlockDescriptor(std::string DescTag, 
+                                          std::string ImplTag,
+                                          int i, StringRef funcName,
+                                          unsigned hasCopy);
+    Stmt *SynthesizeBlockCall(CallExpr *Exp, const Expr* BlockExp);
+    void SynthesizeBlockLiterals(SourceLocation FunLocStart,
+                                 StringRef FunName);
+    FunctionDecl *SynthBlockInitFunctionDecl(StringRef name);
+    Stmt *SynthBlockInitExpr(BlockExpr *Exp,
+                      const SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs);
+
+    // Misc. helper routines.
+    QualType getProtocolType();
+    void WarnAboutReturnGotoStmts(Stmt *S);
+    void CheckFunctionPointerDecl(QualType dType, NamedDecl *ND);
+    void InsertBlockLiteralsWithinFunction(FunctionDecl *FD);
+    void InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD);
+
+    bool IsDeclStmtInForeachHeader(DeclStmt *DS);
+    void CollectBlockDeclRefInfo(BlockExpr *Exp);
+    void GetBlockDeclRefExprs(Stmt *S);
+    void GetInnerBlockDeclRefExprs(Stmt *S,
+                SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs,
+                llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts);
+
+    // We avoid calling Type::isBlockPointerType(), since it operates on the
+    // canonical type. We only care if the top-level type is a closure pointer.
+    bool isTopLevelBlockPointerType(QualType T) {
+      return isa<BlockPointerType>(T);
+    }
+
+    /// convertBlockPointerToFunctionPointer - Converts a block-pointer type
+    /// to a function pointer type and upon success, returns true; false
+    /// otherwise.
+    bool convertBlockPointerToFunctionPointer(QualType &T) {
+      if (isTopLevelBlockPointerType(T)) {
+        const BlockPointerType *BPT = T->getAs<BlockPointerType>();
+        T = Context->getPointerType(BPT->getPointeeType());
+        return true;
+      }
+      return false;
+    }
+    
+    bool convertObjCTypeToCStyleType(QualType &T);
+    
+    bool needToScanForQualifiers(QualType T);
+    QualType getSuperStructType();
+    QualType getConstantStringStructType();
+    QualType convertFunctionTypeOfBlocks(const FunctionType *FT);
+    bool BufferContainsPPDirectives(const char *startBuf, const char *endBuf);
+    
+    void convertToUnqualifiedObjCType(QualType &T) {
+      if (T->isObjCQualifiedIdType()) {
+        bool isConst = T.isConstQualified();
+        T = isConst ? Context->getObjCIdType().withConst() 
+                    : Context->getObjCIdType();
+      }
+      else if (T->isObjCQualifiedClassType())
+        T = Context->getObjCClassType();
+      else if (T->isObjCObjectPointerType() &&
+               T->getPointeeType()->isObjCQualifiedInterfaceType()) {
+        if (const ObjCObjectPointerType * OBJPT =
+              T->getAsObjCInterfacePointerType()) {
+          const ObjCInterfaceType *IFaceT = OBJPT->getInterfaceType();
+          T = QualType(IFaceT, 0);
+          T = Context->getPointerType(T);
+        }
+     }
+    }
+    
+    // FIXME: This predicate seems like it would be useful to add to ASTContext.
+    bool isObjCType(QualType T) {
+      if (!LangOpts.ObjC1 && !LangOpts.ObjC2)
+        return false;
+
+      QualType OCT = Context->getCanonicalType(T).getUnqualifiedType();
+
+      if (OCT == Context->getCanonicalType(Context->getObjCIdType()) ||
+          OCT == Context->getCanonicalType(Context->getObjCClassType()))
+        return true;
+
+      if (const PointerType *PT = OCT->getAs<PointerType>()) {
+        if (isa<ObjCInterfaceType>(PT->getPointeeType()) ||
+            PT->getPointeeType()->isObjCQualifiedIdType())
+          return true;
+      }
+      return false;
+    }
+    bool PointerTypeTakesAnyBlockArguments(QualType QT);
+    bool PointerTypeTakesAnyObjCQualifiedType(QualType QT);
+    void GetExtentOfArgList(const char *Name, const char *&LParen,
+                            const char *&RParen);
+    
+    void QuoteDoublequotes(std::string &From, std::string &To) {
+      for (unsigned i = 0; i < From.length(); i++) {
+        if (From[i] == '"')
+          To += "\\\"";
+        else
+          To += From[i];
+      }
+    }
+
+    QualType getSimpleFunctionType(QualType result,
+                                   ArrayRef<QualType> args,
+                                   bool variadic = false) {
+      if (result == Context->getObjCInstanceType())
+        result =  Context->getObjCIdType();
+      FunctionProtoType::ExtProtoInfo fpi;
+      fpi.Variadic = variadic;
+      return Context->getFunctionType(result, args, fpi);
+    }
+
+    // Helper function: create a CStyleCastExpr with trivial type source info.
+    CStyleCastExpr* NoTypeInfoCStyleCastExpr(ASTContext *Ctx, QualType Ty,
+                                             CastKind Kind, Expr *E) {
+      TypeSourceInfo *TInfo = Ctx->getTrivialTypeSourceInfo(Ty, SourceLocation());
+      return CStyleCastExpr::Create(*Ctx, Ty, VK_RValue, Kind, E, nullptr,
+                                    TInfo, SourceLocation(), SourceLocation());
+    }
+    
+    bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const {
+      IdentifierInfo* II = &Context->Idents.get("load");
+      Selector LoadSel = Context->Selectors.getSelector(0, &II);
+      return OD->getClassMethod(LoadSel) != nullptr;
+    }
+
+    StringLiteral *getStringLiteral(StringRef Str) {
+      QualType StrType = Context->getConstantArrayType(
+          Context->CharTy, llvm::APInt(32, Str.size() + 1), ArrayType::Normal,
+          0);
+      return StringLiteral::Create(*Context, Str, StringLiteral::Ascii,
+                                   /*Pascal=*/false, StrType, SourceLocation());
+    }
+  };
+  
+}
+
+void RewriteModernObjC::RewriteBlocksInFunctionProtoType(QualType funcType,
+                                                   NamedDecl *D) {
+  if (const FunctionProtoType *fproto
+      = dyn_cast<FunctionProtoType>(funcType.IgnoreParens())) {
+    for (const auto &I : fproto->param_types())
+      if (isTopLevelBlockPointerType(I)) {
+        // All the args are checked/rewritten. Don't call twice!
+        RewriteBlockPointerDecl(D);
+        break;
+      }
+  }
+}
+
+void RewriteModernObjC::CheckFunctionPointerDecl(QualType funcType, NamedDecl *ND) {
+  const PointerType *PT = funcType->getAs<PointerType>();
+  if (PT && PointerTypeTakesAnyBlockArguments(funcType))
+    RewriteBlocksInFunctionProtoType(PT->getPointeeType(), ND);
+}
+
+static bool IsHeaderFile(const std::string &Filename) {
+  std::string::size_type DotPos = Filename.rfind('.');
+
+  if (DotPos == std::string::npos) {
+    // no file extension
+    return false;
+  }
+
+  std::string Ext = std::string(Filename.begin()+DotPos+1, Filename.end());
+  // C header: .h
+  // C++ header: .hh or .H;
+  return Ext == "h" || Ext == "hh" || Ext == "H";
+}
+
+RewriteModernObjC::RewriteModernObjC(std::string inFile, raw_ostream* OS,
+                         DiagnosticsEngine &D, const LangOptions &LOpts,
+                         bool silenceMacroWarn,
+                         bool LineInfo)
+      : Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(OS),
+        SilenceRewriteMacroWarning(silenceMacroWarn), GenerateLineInfo(LineInfo) {
+  IsHeader = IsHeaderFile(inFile);
+  RewriteFailedDiag = Diags.getCustomDiagID(DiagnosticsEngine::Warning,
+               "rewriting sub-expression within a macro (may not be correct)");
+  // FIXME. This should be an error. But if block is not called, it is OK. And it
+  // may break including some headers.
+  GlobalBlockRewriteFailedDiag = Diags.getCustomDiagID(DiagnosticsEngine::Warning,
+    "rewriting block literal declared in global scope is not implemented");
+          
+  TryFinallyContainsReturnDiag = Diags.getCustomDiagID(
+               DiagnosticsEngine::Warning,
+               "rewriter doesn't support user-specified control flow semantics "
+               "for @try/@finally (code may not execute properly)");
+}
+
+ASTConsumer *clang::CreateModernObjCRewriter(const std::string& InFile,
+                                       raw_ostream* OS,
+                                       DiagnosticsEngine &Diags,
+                                       const LangOptions &LOpts,
+                                       bool SilenceRewriteMacroWarning,
+                                       bool LineInfo) {
+    return new RewriteModernObjC(InFile, OS, Diags, LOpts,
+                                 SilenceRewriteMacroWarning, LineInfo);
+}
+
+void RewriteModernObjC::InitializeCommon(ASTContext &context) {
+  Context = &context;
+  SM = &Context->getSourceManager();
+  TUDecl = Context->getTranslationUnitDecl();
+  MsgSendFunctionDecl = nullptr;
+  MsgSendSuperFunctionDecl = nullptr;
+  MsgSendStretFunctionDecl = nullptr;
+  MsgSendSuperStretFunctionDecl = nullptr;
+  MsgSendFpretFunctionDecl = nullptr;
+  GetClassFunctionDecl = nullptr;
+  GetMetaClassFunctionDecl = nullptr;
+  GetSuperClassFunctionDecl = nullptr;
+  SelGetUidFunctionDecl = nullptr;
+  CFStringFunctionDecl = nullptr;
+  ConstantStringClassReference = nullptr;
+  NSStringRecord = nullptr;
+  CurMethodDef = nullptr;
+  CurFunctionDef = nullptr;
+  GlobalVarDecl = nullptr;
+  GlobalConstructionExp = nullptr;
+  SuperStructDecl = nullptr;
+  ProtocolTypeDecl = nullptr;
+  ConstantStringDecl = nullptr;
+  BcLabelCount = 0;
+  SuperConstructorFunctionDecl = nullptr;
+  NumObjCStringLiterals = 0;
+  PropParentMap = nullptr;
+  CurrentBody = nullptr;
+  DisableReplaceStmt = false;
+  objc_impl_method = false;
+
+  // Get the ID and start/end of the main file.
+  MainFileID = SM->getMainFileID();
+  const llvm::MemoryBuffer *MainBuf = SM->getBuffer(MainFileID);
+  MainFileStart = MainBuf->getBufferStart();
+  MainFileEnd = MainBuf->getBufferEnd();
+
+  Rewrite.setSourceMgr(Context->getSourceManager(), Context->getLangOpts());
+}
+
+//===----------------------------------------------------------------------===//
+// Top Level Driver Code
+//===----------------------------------------------------------------------===//
+
+void RewriteModernObjC::HandleTopLevelSingleDecl(Decl *D) {
+  if (Diags.hasErrorOccurred())
+    return;
+
+  // Two cases: either the decl could be in the main file, or it could be in a
+  // #included file.  If the former, rewrite it now.  If the later, check to see
+  // if we rewrote the #include/#import.
+  SourceLocation Loc = D->getLocation();
+  Loc = SM->getExpansionLoc(Loc);
+
+  // If this is for a builtin, ignore it.
+  if (Loc.isInvalid()) return;
+
+  // Look for built-in declarations that we need to refer during the rewrite.
+  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    RewriteFunctionDecl(FD);
+  } else if (VarDecl *FVD = dyn_cast<VarDecl>(D)) {
+    // declared in <Foundation/NSString.h>
+    if (FVD->getName() == "_NSConstantStringClassReference") {
+      ConstantStringClassReference = FVD;
+      return;
+    }
+  } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(D)) {
+    RewriteCategoryDecl(CD);
+  } else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) {
+    if (PD->isThisDeclarationADefinition())
+      RewriteProtocolDecl(PD);
+  } else if (LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(D)) {
+    // FIXME. This will not work in all situations and leaving it out
+    // is harmless.
+    // RewriteLinkageSpec(LSD);
+    
+    // Recurse into linkage specifications
+    for (DeclContext::decl_iterator DI = LSD->decls_begin(),
+                                 DIEnd = LSD->decls_end();
+         DI != DIEnd; ) {
+      if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>((*DI))) {
+        if (!IFace->isThisDeclarationADefinition()) {
+          SmallVector<Decl *, 8> DG;
+          SourceLocation StartLoc = IFace->getLocStart();
+          do {
+            if (isa<ObjCInterfaceDecl>(*DI) &&
+                !cast<ObjCInterfaceDecl>(*DI)->isThisDeclarationADefinition() &&
+                StartLoc == (*DI)->getLocStart())
+              DG.push_back(*DI);
+            else
+              break;
+            
+            ++DI;
+          } while (DI != DIEnd);
+          RewriteForwardClassDecl(DG);
+          continue;
+        }
+        else {
+          // Keep track of all interface declarations seen.
+          ObjCInterfacesSeen.push_back(IFace);
+          ++DI;
+          continue;
+        }
+      }
+
+      if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>((*DI))) {
+        if (!Proto->isThisDeclarationADefinition()) {
+          SmallVector<Decl *, 8> DG;
+          SourceLocation StartLoc = Proto->getLocStart();
+          do {
+            if (isa<ObjCProtocolDecl>(*DI) &&
+                !cast<ObjCProtocolDecl>(*DI)->isThisDeclarationADefinition() &&
+                StartLoc == (*DI)->getLocStart())
+              DG.push_back(*DI);
+            else
+              break;
+            
+            ++DI;
+          } while (DI != DIEnd);
+          RewriteForwardProtocolDecl(DG);
+          continue;
+        }
+      }
+      
+      HandleTopLevelSingleDecl(*DI);
+      ++DI;
+    }
+  }
+  // If we have a decl in the main file, see if we should rewrite it.
+  if (SM->isWrittenInMainFile(Loc))
+    return HandleDeclInMainFile(D);
+}
+
+//===----------------------------------------------------------------------===//
+// Syntactic (non-AST) Rewriting Code
+//===----------------------------------------------------------------------===//
+
+void RewriteModernObjC::RewriteInclude() {
+  SourceLocation LocStart = SM->getLocForStartOfFile(MainFileID);
+  StringRef MainBuf = SM->getBufferData(MainFileID);
+  const char *MainBufStart = MainBuf.begin();
+  const char *MainBufEnd = MainBuf.end();
+  size_t ImportLen = strlen("import");
+
+  // Loop over the whole file, looking for includes.
+  for (const char *BufPtr = MainBufStart; BufPtr < MainBufEnd; ++BufPtr) {
+    if (*BufPtr == '#') {
+      if (++BufPtr == MainBufEnd)
+        return;
+      while (*BufPtr == ' ' || *BufPtr == '\t')
+        if (++BufPtr == MainBufEnd)
+          return;
+      if (!strncmp(BufPtr, "import", ImportLen)) {
+        // replace import with include
+        SourceLocation ImportLoc =
+          LocStart.getLocWithOffset(BufPtr-MainBufStart);
+        ReplaceText(ImportLoc, ImportLen, "include");
+        BufPtr += ImportLen;
+      }
+    }
+  }
+}
+
+static void WriteInternalIvarName(const ObjCInterfaceDecl *IDecl,
+                                  ObjCIvarDecl *IvarDecl, std::string &Result) {
+  Result += "OBJC_IVAR_$_";
+  Result += IDecl->getName();
+  Result += "$";
+  Result += IvarDecl->getName();
+}
+
+std::string 
+RewriteModernObjC::getIvarAccessString(ObjCIvarDecl *D) {
+  const ObjCInterfaceDecl *ClassDecl = D->getContainingInterface();
+  
+  // Build name of symbol holding ivar offset.
+  std::string IvarOffsetName;
+  if (D->isBitField())
+    ObjCIvarBitfieldGroupOffset(D, IvarOffsetName);
+  else
+    WriteInternalIvarName(ClassDecl, D, IvarOffsetName);
+  
+  
+  std::string S = "(*(";
+  QualType IvarT = D->getType();
+  if (D->isBitField())
+    IvarT = GetGroupRecordTypeForObjCIvarBitfield(D);
+  
+  if (!isa<TypedefType>(IvarT) && IvarT->isRecordType()) {
+    RecordDecl *RD = IvarT->getAs<RecordType>()->getDecl();
+    RD = RD->getDefinition();
+    if (RD && !RD->getDeclName().getAsIdentifierInfo()) {
+      // decltype(((Foo_IMPL*)0)->bar) *
+      ObjCContainerDecl *CDecl = 
+      dyn_cast<ObjCContainerDecl>(D->getDeclContext());
+      // ivar in class extensions requires special treatment.
+      if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(CDecl))
+        CDecl = CatDecl->getClassInterface();
+      std::string RecName = CDecl->getName();
+      RecName += "_IMPL";
+      RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
+                                          SourceLocation(), SourceLocation(),
+                                          &Context->Idents.get(RecName.c_str()));
+      QualType PtrStructIMPL = Context->getPointerType(Context->getTagDeclType(RD));
+      unsigned UnsignedIntSize = 
+      static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
+      Expr *Zero = IntegerLiteral::Create(*Context,
+                                          llvm::APInt(UnsignedIntSize, 0),
+                                          Context->UnsignedIntTy, SourceLocation());
+      Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL, CK_BitCast, Zero);
+      ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(),
+                                              Zero);
+      FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(),
+                                        SourceLocation(),
+                                        &Context->Idents.get(D->getNameAsString()),
+                                        IvarT, nullptr,
+                                        /*BitWidth=*/nullptr, /*Mutable=*/true,
+                                        ICIS_NoInit);
+      MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(),
+                                                FD->getType(), VK_LValue,
+                                                OK_Ordinary);
+      IvarT = Context->getDecltypeType(ME, ME->getType());
+    }
+  }
+  convertObjCTypeToCStyleType(IvarT);
+  QualType castT = Context->getPointerType(IvarT);
+  std::string TypeString(castT.getAsString(Context->getPrintingPolicy()));
+  S += TypeString;
+  S += ")";
+  
+  // ((char *)self + IVAR_OFFSET_SYMBOL_NAME)
+  S += "((char *)self + ";
+  S += IvarOffsetName;
+  S += "))";
+  if (D->isBitField()) {
+    S += ".";
+    S += D->getNameAsString();
+  }
+  ReferencedIvars[const_cast<ObjCInterfaceDecl *>(ClassDecl)].insert(D);
+  return S;
+}
+
+/// mustSynthesizeSetterGetterMethod - returns true if setter or getter has not
+/// been found in the class implementation. In this case, it must be synthesized.
+static bool mustSynthesizeSetterGetterMethod(ObjCImplementationDecl *IMP,
+                                             ObjCPropertyDecl *PD,
+                                             bool getter) {
+  return getter ? !IMP->getInstanceMethod(PD->getGetterName())
+                : !IMP->getInstanceMethod(PD->getSetterName());
+  
+}
+
+void RewriteModernObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
+                                          ObjCImplementationDecl *IMD,
+                                          ObjCCategoryImplDecl *CID) {
+  static bool objcGetPropertyDefined = false;
+  static bool objcSetPropertyDefined = false;
+  SourceLocation startGetterSetterLoc;
+  
+  if (PID->getLocStart().isValid()) {
+    SourceLocation startLoc = PID->getLocStart();
+    InsertText(startLoc, "// ");
+    const char *startBuf = SM->getCharacterData(startLoc);
+    assert((*startBuf == '@') && "bogus @synthesize location");
+    const char *semiBuf = strchr(startBuf, ';');
+    assert((*semiBuf == ';') && "@synthesize: can't find ';'");
+    startGetterSetterLoc = startLoc.getLocWithOffset(semiBuf-startBuf+1);
+  }
+  else
+    startGetterSetterLoc = IMD ? IMD->getLocEnd() : CID->getLocEnd();
+
+  if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
+    return; // FIXME: is this correct?
+
+  // Generate the 'getter' function.
+  ObjCPropertyDecl *PD = PID->getPropertyDecl();
+  ObjCIvarDecl *OID = PID->getPropertyIvarDecl();
+  assert(IMD && OID && "Synthesized ivars must be attached to @implementation");
+
+  unsigned Attributes = PD->getPropertyAttributes();
+  if (mustSynthesizeSetterGetterMethod(IMD, PD, true /*getter*/)) {
+    bool GenGetProperty = !(Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) &&
+                          (Attributes & (ObjCPropertyDecl::OBJC_PR_retain | 
+                                         ObjCPropertyDecl::OBJC_PR_copy));
+    std::string Getr;
+    if (GenGetProperty && !objcGetPropertyDefined) {
+      objcGetPropertyDefined = true;
+      // FIXME. Is this attribute correct in all cases?
+      Getr = "\nextern \"C\" __declspec(dllimport) "
+            "id objc_getProperty(id, SEL, long, bool);\n";
+    }
+    RewriteObjCMethodDecl(OID->getContainingInterface(),  
+                          PD->getGetterMethodDecl(), Getr);
+    Getr += "{ ";
+    // Synthesize an explicit cast to gain access to the ivar.
+    // See objc-act.c:objc_synthesize_new_getter() for details.
+    if (GenGetProperty) {
+      // return objc_getProperty(self, _cmd, offsetof(ClassDecl, OID), 1)
+      Getr += "typedef ";
+      const FunctionType *FPRetType = nullptr;
+      RewriteTypeIntoString(PD->getGetterMethodDecl()->getReturnType(), Getr,
+                            FPRetType);
+      Getr += " _TYPE";
+      if (FPRetType) {
+        Getr += ")"; // close the precedence "scope" for "*".
+      
+        // Now, emit the argument types (if any).
+        if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(FPRetType)){
+          Getr += "(";
+          for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
+            if (i) Getr += ", ";
+            std::string ParamStr =
+                FT->getParamType(i).getAsString(Context->getPrintingPolicy());
+            Getr += ParamStr;
+          }
+          if (FT->isVariadic()) {
+            if (FT->getNumParams())
+              Getr += ", ";
+            Getr += "...";
+          }
+          Getr += ")";
+        } else
+          Getr += "()";
+      }
+      Getr += ";\n";
+      Getr += "return (_TYPE)";
+      Getr += "objc_getProperty(self, _cmd, ";
+      RewriteIvarOffsetComputation(OID, Getr);
+      Getr += ", 1)";
+    }
+    else
+      Getr += "return " + getIvarAccessString(OID);
+    Getr += "; }";
+    InsertText(startGetterSetterLoc, Getr);
+  }
+  
+  if (PD->isReadOnly() || 
+      !mustSynthesizeSetterGetterMethod(IMD, PD, false /*setter*/))
+    return;
+
+  // Generate the 'setter' function.
+  std::string Setr;
+  bool GenSetProperty = Attributes & (ObjCPropertyDecl::OBJC_PR_retain | 
+                                      ObjCPropertyDecl::OBJC_PR_copy);
+  if (GenSetProperty && !objcSetPropertyDefined) {
+    objcSetPropertyDefined = true;
+    // FIXME. Is this attribute correct in all cases?
+    Setr = "\nextern \"C\" __declspec(dllimport) "
+    "void objc_setProperty (id, SEL, long, id, bool, bool);\n";
+  }
+  
+  RewriteObjCMethodDecl(OID->getContainingInterface(), 
+                        PD->getSetterMethodDecl(), Setr);
+  Setr += "{ ";
+  // Synthesize an explicit cast to initialize the ivar.
+  // See objc-act.c:objc_synthesize_new_setter() for details.
+  if (GenSetProperty) {
+    Setr += "objc_setProperty (self, _cmd, ";
+    RewriteIvarOffsetComputation(OID, Setr);
+    Setr += ", (id)";
+    Setr += PD->getName();
+    Setr += ", ";
+    if (Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic)
+      Setr += "0, ";
+    else
+      Setr += "1, ";
+    if (Attributes & ObjCPropertyDecl::OBJC_PR_copy)
+      Setr += "1)";
+    else
+      Setr += "0)";
+  }
+  else {
+    Setr += getIvarAccessString(OID) + " = ";
+    Setr += PD->getName();
+  }
+  Setr += "; }\n";
+  InsertText(startGetterSetterLoc, Setr);
+}
+
+static void RewriteOneForwardClassDecl(ObjCInterfaceDecl *ForwardDecl,
+                                       std::string &typedefString) {
+  typedefString += "\n#ifndef _REWRITER_typedef_";
+  typedefString += ForwardDecl->getNameAsString();
+  typedefString += "\n";
+  typedefString += "#define _REWRITER_typedef_";
+  typedefString += ForwardDecl->getNameAsString();
+  typedefString += "\n";
+  typedefString += "typedef struct objc_object ";
+  typedefString += ForwardDecl->getNameAsString();
+  // typedef struct { } _objc_exc_Classname;
+  typedefString += ";\ntypedef struct {} _objc_exc_";
+  typedefString += ForwardDecl->getNameAsString();
+  typedefString += ";\n#endif\n";
+}
+
+void RewriteModernObjC::RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl,
+                                              const std::string &typedefString) {
+    SourceLocation startLoc = ClassDecl->getLocStart();
+    const char *startBuf = SM->getCharacterData(startLoc);
+    const char *semiPtr = strchr(startBuf, ';'); 
+    // Replace the @class with typedefs corresponding to the classes.
+    ReplaceText(startLoc, semiPtr-startBuf+1, typedefString);  
+}
+
+void RewriteModernObjC::RewriteForwardClassDecl(DeclGroupRef D) {
+  std::string typedefString;
+  for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) {
+    if (ObjCInterfaceDecl *ForwardDecl = dyn_cast<ObjCInterfaceDecl>(*I)) {
+      if (I == D.begin()) {
+        // Translate to typedef's that forward reference structs with the same name
+        // as the class. As a convenience, we include the original declaration
+        // as a comment.
+        typedefString += "// @class ";
+        typedefString += ForwardDecl->getNameAsString();
+        typedefString += ";";
+      }
+      RewriteOneForwardClassDecl(ForwardDecl, typedefString);
+    }
+    else
+      HandleTopLevelSingleDecl(*I);
+  }
+  DeclGroupRef::iterator I = D.begin();
+  RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(*I), typedefString);
+}
+
+void RewriteModernObjC::RewriteForwardClassDecl(
+                                const SmallVectorImpl<Decl *> &D) {
+  std::string typedefString;
+  for (unsigned i = 0; i < D.size(); i++) {
+    ObjCInterfaceDecl *ForwardDecl = cast<ObjCInterfaceDecl>(D[i]);
+    if (i == 0) {
+      typedefString += "// @class ";
+      typedefString += ForwardDecl->getNameAsString();
+      typedefString += ";";
+    }
+    RewriteOneForwardClassDecl(ForwardDecl, typedefString);
+  }
+  RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(D[0]), typedefString);
+}
+
+void RewriteModernObjC::RewriteMethodDeclaration(ObjCMethodDecl *Method) {
+  // When method is a synthesized one, such as a getter/setter there is
+  // nothing to rewrite.
+  if (Method->isImplicit())
+    return;
+  SourceLocation LocStart = Method->getLocStart();
+  SourceLocation LocEnd = Method->getLocEnd();
+
+  if (SM->getExpansionLineNumber(LocEnd) >
+      SM->getExpansionLineNumber(LocStart)) {
+    InsertText(LocStart, "#if 0\n");
+    ReplaceText(LocEnd, 1, ";\n#endif\n");
+  } else {
+    InsertText(LocStart, "// ");
+  }
+}
+
+void RewriteModernObjC::RewriteProperty(ObjCPropertyDecl *prop) {
+  SourceLocation Loc = prop->getAtLoc();
+
+  ReplaceText(Loc, 0, "// ");
+  // FIXME: handle properties that are declared across multiple lines.
+}
+
+void RewriteModernObjC::RewriteCategoryDecl(ObjCCategoryDecl *CatDecl) {
+  SourceLocation LocStart = CatDecl->getLocStart();
+
+  // FIXME: handle category headers that are declared across multiple lines.
+  if (CatDecl->getIvarRBraceLoc().isValid()) {
+    ReplaceText(LocStart, 1, "/** ");
+    ReplaceText(CatDecl->getIvarRBraceLoc(), 1, "**/ ");
+  }
+  else {
+    ReplaceText(LocStart, 0, "// ");
+  }
+  
+  for (auto *I : CatDecl->properties())
+    RewriteProperty(I);
+  
+  for (auto *I : CatDecl->instance_methods())
+    RewriteMethodDeclaration(I);
+  for (auto *I : CatDecl->class_methods())
+    RewriteMethodDeclaration(I);
+
+  // Lastly, comment out the @end.
+  ReplaceText(CatDecl->getAtEndRange().getBegin(), 
+              strlen("@end"), "/* @end */\n");
+}
+
+void RewriteModernObjC::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) {
+  SourceLocation LocStart = PDecl->getLocStart();
+  assert(PDecl->isThisDeclarationADefinition());
+  
+  // FIXME: handle protocol headers that are declared across multiple lines.
+  ReplaceText(LocStart, 0, "// ");
+
+  for (auto *I : PDecl->instance_methods())
+    RewriteMethodDeclaration(I);
+  for (auto *I : PDecl->class_methods())
+    RewriteMethodDeclaration(I);
+  for (auto *I : PDecl->properties())
+    RewriteProperty(I);
+  
+  // Lastly, comment out the @end.
+  SourceLocation LocEnd = PDecl->getAtEndRange().getBegin();
+  ReplaceText(LocEnd, strlen("@end"), "/* @end */\n");
+
+  // Must comment out @optional/@required
+  const char *startBuf = SM->getCharacterData(LocStart);
+  const char *endBuf = SM->getCharacterData(LocEnd);
+  for (const char *p = startBuf; p < endBuf; p++) {
+    if (*p == '@' && !strncmp(p+1, "optional", strlen("optional"))) {
+      SourceLocation OptionalLoc = LocStart.getLocWithOffset(p-startBuf);
+      ReplaceText(OptionalLoc, strlen("@optional"), "/* @optional */");
+
+    }
+    else if (*p == '@' && !strncmp(p+1, "required", strlen("required"))) {
+      SourceLocation OptionalLoc = LocStart.getLocWithOffset(p-startBuf);
+      ReplaceText(OptionalLoc, strlen("@required"), "/* @required */");
+
+    }
+  }
+}
+
+void RewriteModernObjC::RewriteForwardProtocolDecl(DeclGroupRef D) {
+  SourceLocation LocStart = (*D.begin())->getLocStart();
+  if (LocStart.isInvalid())
+    llvm_unreachable("Invalid SourceLocation");
+  // FIXME: handle forward protocol that are declared across multiple lines.
+  ReplaceText(LocStart, 0, "// ");
+}
+
+void 
+RewriteModernObjC::RewriteForwardProtocolDecl(const SmallVectorImpl<Decl *> &DG) {
+  SourceLocation LocStart = DG[0]->getLocStart();
+  if (LocStart.isInvalid())
+    llvm_unreachable("Invalid SourceLocation");
+  // FIXME: handle forward protocol that are declared across multiple lines.
+  ReplaceText(LocStart, 0, "// ");
+}
+
+void 
+RewriteModernObjC::RewriteLinkageSpec(LinkageSpecDecl *LSD) {
+  SourceLocation LocStart = LSD->getExternLoc();
+  if (LocStart.isInvalid())
+    llvm_unreachable("Invalid extern SourceLocation");
+  
+  ReplaceText(LocStart, 0, "// ");
+  if (!LSD->hasBraces())
+    return;
+  // FIXME. We don't rewrite well if '{' is not on same line as 'extern'.
+  SourceLocation LocRBrace = LSD->getRBraceLoc();
+  if (LocRBrace.isInvalid())
+    llvm_unreachable("Invalid rbrace SourceLocation");
+  ReplaceText(LocRBrace, 0, "// ");
+}
+
+void RewriteModernObjC::RewriteTypeIntoString(QualType T, std::string &ResultStr,
+                                        const FunctionType *&FPRetType) {
+  if (T->isObjCQualifiedIdType())
+    ResultStr += "id";
+  else if (T->isFunctionPointerType() ||
+           T->isBlockPointerType()) {
+    // needs special handling, since pointer-to-functions have special
+    // syntax (where a decaration models use).
+    QualType retType = T;
+    QualType PointeeTy;
+    if (const PointerType* PT = retType->getAs<PointerType>())
+      PointeeTy = PT->getPointeeType();
+    else if (const BlockPointerType *BPT = retType->getAs<BlockPointerType>())
+      PointeeTy = BPT->getPointeeType();
+    if ((FPRetType = PointeeTy->getAs<FunctionType>())) {
+      ResultStr +=
+          FPRetType->getReturnType().getAsString(Context->getPrintingPolicy());
+      ResultStr += "(*";
+    }
+  } else
+    ResultStr += T.getAsString(Context->getPrintingPolicy());
+}
+
+void RewriteModernObjC::RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl,
+                                        ObjCMethodDecl *OMD,
+                                        std::string &ResultStr) {
+  //fprintf(stderr,"In RewriteObjCMethodDecl\n");
+  const FunctionType *FPRetType = nullptr;
+  ResultStr += "\nstatic ";
+  RewriteTypeIntoString(OMD->getReturnType(), ResultStr, FPRetType);
+  ResultStr += " ";
+
+  // Unique method name
+  std::string NameStr;
+
+  if (OMD->isInstanceMethod())
+    NameStr += "_I_";
+  else
+    NameStr += "_C_";
+
+  NameStr += IDecl->getNameAsString();
+  NameStr += "_";
+
+  if (ObjCCategoryImplDecl *CID =
+      dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext())) {
+    NameStr += CID->getNameAsString();
+    NameStr += "_";
+  }
+  // Append selector names, replacing ':' with '_'
+  {
+    std::string selString = OMD->getSelector().getAsString();
+    int len = selString.size();
+    for (int i = 0; i < len; i++)
+      if (selString[i] == ':')
+        selString[i] = '_';
+    NameStr += selString;
+  }
+  // Remember this name for metadata emission
+  MethodInternalNames[OMD] = NameStr;
+  ResultStr += NameStr;
+
+  // Rewrite arguments
+  ResultStr += "(";
+
+  // invisible arguments
+  if (OMD->isInstanceMethod()) {
+    QualType selfTy = Context->getObjCInterfaceType(IDecl);
+    selfTy = Context->getPointerType(selfTy);
+    if (!LangOpts.MicrosoftExt) {
+      if (ObjCSynthesizedStructs.count(const_cast<ObjCInterfaceDecl*>(IDecl)))
+        ResultStr += "struct ";
+    }
+    // When rewriting for Microsoft, explicitly omit the structure name.
+    ResultStr += IDecl->getNameAsString();
+    ResultStr += " *";
+  }
+  else
+    ResultStr += Context->getObjCClassType().getAsString(
+      Context->getPrintingPolicy());
+
+  ResultStr += " self, ";
+  ResultStr += Context->getObjCSelType().getAsString(Context->getPrintingPolicy());
+  ResultStr += " _cmd";
+
+  // Method arguments.
+  for (const auto *PDecl : OMD->params()) {
+    ResultStr += ", ";
+    if (PDecl->getType()->isObjCQualifiedIdType()) {
+      ResultStr += "id ";
+      ResultStr += PDecl->getNameAsString();
+    } else {
+      std::string Name = PDecl->getNameAsString();
+      QualType QT = PDecl->getType();
+      // Make sure we convert "t (^)(...)" to "t (*)(...)".
+      (void)convertBlockPointerToFunctionPointer(QT);
+      QT.getAsStringInternal(Name, Context->getPrintingPolicy());
+      ResultStr += Name;
+    }
+  }
+  if (OMD->isVariadic())
+    ResultStr += ", ...";
+  ResultStr += ") ";
+
+  if (FPRetType) {
+    ResultStr += ")"; // close the precedence "scope" for "*".
+
+    // Now, emit the argument types (if any).
+    if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(FPRetType)) {
+      ResultStr += "(";
+      for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
+        if (i) ResultStr += ", ";
+        std::string ParamStr =
+            FT->getParamType(i).getAsString(Context->getPrintingPolicy());
+        ResultStr += ParamStr;
+      }
+      if (FT->isVariadic()) {
+        if (FT->getNumParams())
+          ResultStr += ", ";
+        ResultStr += "...";
+      }
+      ResultStr += ")";
+    } else {
+      ResultStr += "()";
+    }
+  }
+}
+void RewriteModernObjC::RewriteImplementationDecl(Decl *OID) {
+  ObjCImplementationDecl *IMD = dyn_cast<ObjCImplementationDecl>(OID);
+  ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(OID);
+
+  if (IMD) {
+    if (IMD->getIvarRBraceLoc().isValid()) {
+      ReplaceText(IMD->getLocStart(), 1, "/** ");
+      ReplaceText(IMD->getIvarRBraceLoc(), 1, "**/ ");
+    }
+    else {
+      InsertText(IMD->getLocStart(), "// ");
+    }
+  }
+  else
+    InsertText(CID->getLocStart(), "// ");
+
+  for (auto *OMD : IMD ? IMD->instance_methods() : CID->instance_methods()) {
+    std::string ResultStr;
+    RewriteObjCMethodDecl(OMD->getClassInterface(), OMD, ResultStr);
+    SourceLocation LocStart = OMD->getLocStart();
+    SourceLocation LocEnd = OMD->getCompoundBody()->getLocStart();
+
+    const char *startBuf = SM->getCharacterData(LocStart);
+    const char *endBuf = SM->getCharacterData(LocEnd);
+    ReplaceText(LocStart, endBuf-startBuf, ResultStr);
+  }
+
+  for (auto *OMD : IMD ? IMD->class_methods() : CID->class_methods()) {
+    std::string ResultStr;
+    RewriteObjCMethodDecl(OMD->getClassInterface(), OMD, ResultStr);
+    SourceLocation LocStart = OMD->getLocStart();
+    SourceLocation LocEnd = OMD->getCompoundBody()->getLocStart();
+
+    const char *startBuf = SM->getCharacterData(LocStart);
+    const char *endBuf = SM->getCharacterData(LocEnd);
+    ReplaceText(LocStart, endBuf-startBuf, ResultStr);
+  }
+  for (auto *I : IMD ? IMD->property_impls() : CID->property_impls())
+    RewritePropertyImplDecl(I, IMD, CID);
+
+  InsertText(IMD ? IMD->getLocEnd() : CID->getLocEnd(), "// ");
+}
+
+void RewriteModernObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) {
+  // Do not synthesize more than once.
+  if (ObjCSynthesizedStructs.count(ClassDecl))
+    return;
+  // Make sure super class's are written before current class is written.
+  ObjCInterfaceDecl *SuperClass = ClassDecl->getSuperClass();
+  while (SuperClass) {
+    RewriteInterfaceDecl(SuperClass);
+    SuperClass = SuperClass->getSuperClass();
+  }
+  std::string ResultStr;
+  if (!ObjCWrittenInterfaces.count(ClassDecl->getCanonicalDecl())) {
+    // we haven't seen a forward decl - generate a typedef.
+    RewriteOneForwardClassDecl(ClassDecl, ResultStr);
+    RewriteIvarOffsetSymbols(ClassDecl, ResultStr);
+    
+    RewriteObjCInternalStruct(ClassDecl, ResultStr);
+    // Mark this typedef as having been written into its c++ equivalent.
+    ObjCWrittenInterfaces.insert(ClassDecl->getCanonicalDecl());
+  
+    for (auto *I : ClassDecl->properties())
+      RewriteProperty(I);
+    for (auto *I : ClassDecl->instance_methods())
+      RewriteMethodDeclaration(I);
+    for (auto *I : ClassDecl->class_methods())
+      RewriteMethodDeclaration(I);
+
+    // Lastly, comment out the @end.
+    ReplaceText(ClassDecl->getAtEndRange().getBegin(), strlen("@end"), 
+                "/* @end */\n");
+  }
+}
+
+Stmt *RewriteModernObjC::RewritePropertyOrImplicitSetter(PseudoObjectExpr *PseudoOp) {
+  SourceRange OldRange = PseudoOp->getSourceRange();
+
+  // We just magically know some things about the structure of this
+  // expression.
+  ObjCMessageExpr *OldMsg =
+    cast<ObjCMessageExpr>(PseudoOp->getSemanticExpr(
+                            PseudoOp->getNumSemanticExprs() - 1));
+
+  // Because the rewriter doesn't allow us to rewrite rewritten code,
+  // we need to suppress rewriting the sub-statements.
+  Expr *Base;
+  SmallVector<Expr*, 2> Args;
+  {
+    DisableReplaceStmtScope S(*this);
+
+    // Rebuild the base expression if we have one.
+    Base = nullptr;
+    if (OldMsg->getReceiverKind() == ObjCMessageExpr::Instance) {
+      Base = OldMsg->getInstanceReceiver();
+      Base = cast<OpaqueValueExpr>(Base)->getSourceExpr();
+      Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base));
+    }
+  
+    unsigned numArgs = OldMsg->getNumArgs();
+    for (unsigned i = 0; i < numArgs; i++) {
+      Expr *Arg = OldMsg->getArg(i);
+      if (isa<OpaqueValueExpr>(Arg))
+        Arg = cast<OpaqueValueExpr>(Arg)->getSourceExpr();
+      Arg = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Arg));
+      Args.push_back(Arg);
+    }
+  }
+
+  // TODO: avoid this copy.
+  SmallVector<SourceLocation, 1> SelLocs;
+  OldMsg->getSelectorLocs(SelLocs);
+
+  ObjCMessageExpr *NewMsg = nullptr;
+  switch (OldMsg->getReceiverKind()) {
+  case ObjCMessageExpr::Class:
+    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
+                                     OldMsg->getValueKind(),
+                                     OldMsg->getLeftLoc(),
+                                     OldMsg->getClassReceiverTypeInfo(),
+                                     OldMsg->getSelector(),
+                                     SelLocs,
+                                     OldMsg->getMethodDecl(),
+                                     Args,
+                                     OldMsg->getRightLoc(),
+                                     OldMsg->isImplicit());
+    break;
+
+  case ObjCMessageExpr::Instance:
+    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
+                                     OldMsg->getValueKind(),
+                                     OldMsg->getLeftLoc(),
+                                     Base,
+                                     OldMsg->getSelector(),
+                                     SelLocs,
+                                     OldMsg->getMethodDecl(),
+                                     Args,
+                                     OldMsg->getRightLoc(),
+                                     OldMsg->isImplicit());
+    break;
+
+  case ObjCMessageExpr::SuperClass:
+  case ObjCMessageExpr::SuperInstance:
+    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
+                                     OldMsg->getValueKind(),
+                                     OldMsg->getLeftLoc(),
+                                     OldMsg->getSuperLoc(),
+                 OldMsg->getReceiverKind() == ObjCMessageExpr::SuperInstance,
+                                     OldMsg->getSuperType(),
+                                     OldMsg->getSelector(),
+                                     SelLocs,
+                                     OldMsg->getMethodDecl(),
+                                     Args,
+                                     OldMsg->getRightLoc(),
+                                     OldMsg->isImplicit());
+    break;
+  }
+
+  Stmt *Replacement = SynthMessageExpr(NewMsg);
+  ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
+  return Replacement;
+}
+
+Stmt *RewriteModernObjC::RewritePropertyOrImplicitGetter(PseudoObjectExpr *PseudoOp) {
+  SourceRange OldRange = PseudoOp->getSourceRange();
+
+  // We just magically know some things about the structure of this
+  // expression.
+  ObjCMessageExpr *OldMsg =
+    cast<ObjCMessageExpr>(PseudoOp->getResultExpr()->IgnoreImplicit());
+
+  // Because the rewriter doesn't allow us to rewrite rewritten code,
+  // we need to suppress rewriting the sub-statements.
+  Expr *Base = nullptr;
+  SmallVector<Expr*, 1> Args;
+  {
+    DisableReplaceStmtScope S(*this);
+    // Rebuild the base expression if we have one.
+    if (OldMsg->getReceiverKind() == ObjCMessageExpr::Instance) {
+      Base = OldMsg->getInstanceReceiver();
+      Base = cast<OpaqueValueExpr>(Base)->getSourceExpr();
+      Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base));
+    }
+    unsigned numArgs = OldMsg->getNumArgs();
+    for (unsigned i = 0; i < numArgs; i++) {
+      Expr *Arg = OldMsg->getArg(i);
+      if (isa<OpaqueValueExpr>(Arg))
+        Arg = cast<OpaqueValueExpr>(Arg)->getSourceExpr();
+      Arg = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Arg));
+      Args.push_back(Arg);
+    }
+  }
+
+  // Intentionally empty.
+  SmallVector<SourceLocation, 1> SelLocs;
+
+  ObjCMessageExpr *NewMsg = nullptr;
+  switch (OldMsg->getReceiverKind()) {
+  case ObjCMessageExpr::Class:
+    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
+                                     OldMsg->getValueKind(),
+                                     OldMsg->getLeftLoc(),
+                                     OldMsg->getClassReceiverTypeInfo(),
+                                     OldMsg->getSelector(),
+                                     SelLocs,
+                                     OldMsg->getMethodDecl(),
+                                     Args,
+                                     OldMsg->getRightLoc(),
+                                     OldMsg->isImplicit());
+    break;
+
+  case ObjCMessageExpr::Instance:
+    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
+                                     OldMsg->getValueKind(),
+                                     OldMsg->getLeftLoc(),
+                                     Base,
+                                     OldMsg->getSelector(),
+                                     SelLocs,
+                                     OldMsg->getMethodDecl(),
+                                     Args,
+                                     OldMsg->getRightLoc(),
+                                     OldMsg->isImplicit());
+    break;
+
+  case ObjCMessageExpr::SuperClass:
+  case ObjCMessageExpr::SuperInstance:
+    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
+                                     OldMsg->getValueKind(),
+                                     OldMsg->getLeftLoc(),
+                                     OldMsg->getSuperLoc(),
+                 OldMsg->getReceiverKind() == ObjCMessageExpr::SuperInstance,
+                                     OldMsg->getSuperType(),
+                                     OldMsg->getSelector(),
+                                     SelLocs,
+                                     OldMsg->getMethodDecl(),
+                                     Args,
+                                     OldMsg->getRightLoc(),
+                                     OldMsg->isImplicit());
+    break;
+  }
+
+  Stmt *Replacement = SynthMessageExpr(NewMsg);
+  ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
+  return Replacement;
+}
+
+/// SynthCountByEnumWithState - To print:
+/// ((NSUInteger (*)
+///  (id, SEL, struct __objcFastEnumerationState *, id *, NSUInteger))
+///  (void *)objc_msgSend)((id)l_collection,
+///                        sel_registerName(
+///                          "countByEnumeratingWithState:objects:count:"),
+///                        &enumState,
+///                        (id *)__rw_items, (NSUInteger)16)
+///
+void RewriteModernObjC::SynthCountByEnumWithState(std::string &buf) {
+  buf += "((_WIN_NSUInteger (*) (id, SEL, struct __objcFastEnumerationState *, "
+  "id *, _WIN_NSUInteger))(void *)objc_msgSend)";
+  buf += "\n\t\t";
+  buf += "((id)l_collection,\n\t\t";
+  buf += "sel_registerName(\"countByEnumeratingWithState:objects:count:\"),";
+  buf += "\n\t\t";
+  buf += "&enumState, "
+         "(id *)__rw_items, (_WIN_NSUInteger)16)";
+}
+
+/// RewriteBreakStmt - Rewrite for a break-stmt inside an ObjC2's foreach
+/// statement to exit to its outer synthesized loop.
+///
+Stmt *RewriteModernObjC::RewriteBreakStmt(BreakStmt *S) {
+  if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
+    return S;
+  // replace break with goto __break_label
+  std::string buf;
+
+  SourceLocation startLoc = S->getLocStart();
+  buf = "goto __break_label_";
+  buf += utostr(ObjCBcLabelNo.back());
+  ReplaceText(startLoc, strlen("break"), buf);
+
+  return nullptr;
+}
+
+void RewriteModernObjC::ConvertSourceLocationToLineDirective(
+                                          SourceLocation Loc,
+                                          std::string &LineString) {
+  if (Loc.isFileID() && GenerateLineInfo) {
+    LineString += "\n#line ";
+    PresumedLoc PLoc = SM->getPresumedLoc(Loc);
+    LineString += utostr(PLoc.getLine());
+    LineString += " \"";
+    LineString += Lexer::Stringify(PLoc.getFilename());
+    LineString += "\"\n";
+  }
+}
+
+/// RewriteContinueStmt - Rewrite for a continue-stmt inside an ObjC2's foreach
+/// statement to continue with its inner synthesized loop.
+///
+Stmt *RewriteModernObjC::RewriteContinueStmt(ContinueStmt *S) {
+  if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
+    return S;
+  // replace continue with goto __continue_label
+  std::string buf;
+
+  SourceLocation startLoc = S->getLocStart();
+  buf = "goto __continue_label_";
+  buf += utostr(ObjCBcLabelNo.back());
+  ReplaceText(startLoc, strlen("continue"), buf);
+
+  return nullptr;
+}
+
+/// RewriteObjCForCollectionStmt - Rewriter for ObjC2's foreach statement.
+///  It rewrites:
+/// for ( type elem in collection) { stmts; }
+
+/// Into:
+/// {
+///   type elem;
+///   struct __objcFastEnumerationState enumState = { 0 };
+///   id __rw_items[16];
+///   id l_collection = (id)collection;
+///   NSUInteger limit = [l_collection countByEnumeratingWithState:&enumState
+///                                       objects:__rw_items count:16];
+/// if (limit) {
+///   unsigned long startMutations = *enumState.mutationsPtr;
+///   do {
+///        unsigned long counter = 0;
+///        do {
+///             if (startMutations != *enumState.mutationsPtr)
+///               objc_enumerationMutation(l_collection);
+///             elem = (type)enumState.itemsPtr[counter++];
+///             stmts;
+///             __continue_label: ;
+///        } while (counter < limit);
+///   } while ((limit = [l_collection countByEnumeratingWithState:&enumState
+///                                  objects:__rw_items count:16]));
+///   elem = nil;
+///   __break_label: ;
+///  }
+///  else
+///       elem = nil;
+///  }
+///
+Stmt *RewriteModernObjC::RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
+                                                SourceLocation OrigEnd) {
+  assert(!Stmts.empty() && "ObjCForCollectionStmt - Statement stack empty");
+  assert(isa<ObjCForCollectionStmt>(Stmts.back()) &&
+         "ObjCForCollectionStmt Statement stack mismatch");
+  assert(!ObjCBcLabelNo.empty() &&
+         "ObjCForCollectionStmt - Label No stack empty");
+
+  SourceLocation startLoc = S->getLocStart();
+  const char *startBuf = SM->getCharacterData(startLoc);
+  StringRef elementName;
+  std::string elementTypeAsString;
+  std::string buf;
+  // line directive first.
+  SourceLocation ForEachLoc = S->getForLoc();
+  ConvertSourceLocationToLineDirective(ForEachLoc, buf);
+  buf += "{\n\t";
+  if (DeclStmt *DS = dyn_cast<DeclStmt>(S->getElement())) {
+    // type elem;
+    NamedDecl* D = cast<NamedDecl>(DS->getSingleDecl());
+    QualType ElementType = cast<ValueDecl>(D)->getType();
+    if (ElementType->isObjCQualifiedIdType() ||
+        ElementType->isObjCQualifiedInterfaceType())
+      // Simply use 'id' for all qualified types.
+      elementTypeAsString = "id";
+    else
+      elementTypeAsString = ElementType.getAsString(Context->getPrintingPolicy());
+    buf += elementTypeAsString;
+    buf += " ";
+    elementName = D->getName();
+    buf += elementName;
+    buf += ";\n\t";
+  }
+  else {
+    DeclRefExpr *DR = cast<DeclRefExpr>(S->getElement());
+    elementName = DR->getDecl()->getName();
+    ValueDecl *VD = cast<ValueDecl>(DR->getDecl());
+    if (VD->getType()->isObjCQualifiedIdType() ||
+        VD->getType()->isObjCQualifiedInterfaceType())
+      // Simply use 'id' for all qualified types.
+      elementTypeAsString = "id";
+    else
+      elementTypeAsString = VD->getType().getAsString(Context->getPrintingPolicy());
+  }
+
+  // struct __objcFastEnumerationState enumState = { 0 };
+  buf += "struct __objcFastEnumerationState enumState = { 0 };\n\t";
+  // id __rw_items[16];
+  buf += "id __rw_items[16];\n\t";
+  // id l_collection = (id)
+  buf += "id l_collection = (id)";
+  // Find start location of 'collection' the hard way!
+  const char *startCollectionBuf = startBuf;
+  startCollectionBuf += 3;  // skip 'for'
+  startCollectionBuf = strchr(startCollectionBuf, '(');
+  startCollectionBuf++; // skip '('
+  // find 'in' and skip it.
+  while (*startCollectionBuf != ' ' ||
+         *(startCollectionBuf+1) != 'i' || *(startCollectionBuf+2) != 'n' ||
+         (*(startCollectionBuf+3) != ' ' &&
+          *(startCollectionBuf+3) != '[' && *(startCollectionBuf+3) != '('))
+    startCollectionBuf++;
+  startCollectionBuf += 3;
+
+  // Replace: "for (type element in" with string constructed thus far.
+  ReplaceText(startLoc, startCollectionBuf - startBuf, buf);
+  // Replace ')' in for '(' type elem in collection ')' with ';'
+  SourceLocation rightParenLoc = S->getRParenLoc();
+  const char *rparenBuf = SM->getCharacterData(rightParenLoc);
+  SourceLocation lparenLoc = startLoc.getLocWithOffset(rparenBuf-startBuf);
+  buf = ";\n\t";
+
+  // unsigned long limit = [l_collection countByEnumeratingWithState:&enumState
+  //                                   objects:__rw_items count:16];
+  // which is synthesized into:
+  // NSUInteger limit =
+  // ((NSUInteger (*)
+  //  (id, SEL, struct __objcFastEnumerationState *, id *, NSUInteger))
+  //  (void *)objc_msgSend)((id)l_collection,
+  //                        sel_registerName(
+  //                          "countByEnumeratingWithState:objects:count:"),
+  //                        (struct __objcFastEnumerationState *)&state,
+  //                        (id *)__rw_items, (NSUInteger)16);
+  buf += "_WIN_NSUInteger limit =\n\t\t";
+  SynthCountByEnumWithState(buf);
+  buf += ";\n\t";
+  /// if (limit) {
+  ///   unsigned long startMutations = *enumState.mutationsPtr;
+  ///   do {
+  ///        unsigned long counter = 0;
+  ///        do {
+  ///             if (startMutations != *enumState.mutationsPtr)
+  ///               objc_enumerationMutation(l_collection);
+  ///             elem = (type)enumState.itemsPtr[counter++];
+  buf += "if (limit) {\n\t";
+  buf += "unsigned long startMutations = *enumState.mutationsPtr;\n\t";
+  buf += "do {\n\t\t";
+  buf += "unsigned long counter = 0;\n\t\t";
+  buf += "do {\n\t\t\t";
+  buf += "if (startMutations != *enumState.mutationsPtr)\n\t\t\t\t";
+  buf += "objc_enumerationMutation(l_collection);\n\t\t\t";
+  buf += elementName;
+  buf += " = (";
+  buf += elementTypeAsString;
+  buf += ")enumState.itemsPtr[counter++];";
+  // Replace ')' in for '(' type elem in collection ')' with all of these.
+  ReplaceText(lparenLoc, 1, buf);
+
+  ///            __continue_label: ;
+  ///        } while (counter < limit);
+  ///   } while ((limit = [l_collection countByEnumeratingWithState:&enumState
+  ///                                  objects:__rw_items count:16]));
+  ///   elem = nil;
+  ///   __break_label: ;
+  ///  }
+  ///  else
+  ///       elem = nil;
+  ///  }
+  ///
+  buf = ";\n\t";
+  buf += "__continue_label_";
+  buf += utostr(ObjCBcLabelNo.back());
+  buf += ": ;";
+  buf += "\n\t\t";
+  buf += "} while (counter < limit);\n\t";
+  buf += "} while ((limit = ";
+  SynthCountByEnumWithState(buf);
+  buf += "));\n\t";
+  buf += elementName;
+  buf += " = ((";
+  buf += elementTypeAsString;
+  buf += ")0);\n\t";
+  buf += "__break_label_";
+  buf += utostr(ObjCBcLabelNo.back());
+  buf += ": ;\n\t";
+  buf += "}\n\t";
+  buf += "else\n\t\t";
+  buf += elementName;
+  buf += " = ((";
+  buf += elementTypeAsString;
+  buf += ")0);\n\t";
+  buf += "}\n";
+
+  // Insert all these *after* the statement body.
+  // FIXME: If this should support Obj-C++, support CXXTryStmt
+  if (isa<CompoundStmt>(S->getBody())) {
+    SourceLocation endBodyLoc = OrigEnd.getLocWithOffset(1);
+    InsertText(endBodyLoc, buf);
+  } else {
+    /* Need to treat single statements specially. For example:
+     *
+     *     for (A *a in b) if (stuff()) break;
+     *     for (A *a in b) xxxyy;
+     *
+     * The following code simply scans ahead to the semi to find the actual end.
+     */
+    const char *stmtBuf = SM->getCharacterData(OrigEnd);
+    const char *semiBuf = strchr(stmtBuf, ';');
+    assert(semiBuf && "Can't find ';'");
+    SourceLocation endBodyLoc = OrigEnd.getLocWithOffset(semiBuf-stmtBuf+1);
+    InsertText(endBodyLoc, buf);
+  }
+  Stmts.pop_back();
+  ObjCBcLabelNo.pop_back();
+  return nullptr;
+}
+
+static void Write_RethrowObject(std::string &buf) {
+  buf += "{ struct _FIN { _FIN(id reth) : rethrow(reth) {}\n";
+  buf += "\t~_FIN() { if (rethrow) objc_exception_throw(rethrow); }\n";
+  buf += "\tid rethrow;\n";
+  buf += "\t} _fin_force_rethow(_rethrow);";
+}
+
+/// RewriteObjCSynchronizedStmt -
+/// This routine rewrites @synchronized(expr) stmt;
+/// into:
+/// objc_sync_enter(expr);
+/// @try stmt @finally { objc_sync_exit(expr); }
+///
+Stmt *RewriteModernObjC::RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
+  // Get the start location and compute the semi location.
+  SourceLocation startLoc = S->getLocStart();
+  const char *startBuf = SM->getCharacterData(startLoc);
+
+  assert((*startBuf == '@') && "bogus @synchronized location");
+
+  std::string buf;
+  SourceLocation SynchLoc = S->getAtSynchronizedLoc();
+  ConvertSourceLocationToLineDirective(SynchLoc, buf);
+  buf += "{ id _rethrow = 0; id _sync_obj = (id)";
+  
+  const char *lparenBuf = startBuf;
+  while (*lparenBuf != '(') lparenBuf++;
+  ReplaceText(startLoc, lparenBuf-startBuf+1, buf);
+  
+  buf = "; objc_sync_enter(_sync_obj);\n";
+  buf += "try {\n\tstruct _SYNC_EXIT { _SYNC_EXIT(id arg) : sync_exit(arg) {}";
+  buf += "\n\t~_SYNC_EXIT() {objc_sync_exit(sync_exit);}";
+  buf += "\n\tid sync_exit;";
+  buf += "\n\t} _sync_exit(_sync_obj);\n";
+
+  // We can't use S->getSynchExpr()->getLocEnd() to find the end location, since
+  // the sync expression is typically a message expression that's already
+  // been rewritten! (which implies the SourceLocation's are invalid).
+  SourceLocation RParenExprLoc = S->getSynchBody()->getLocStart();
+  const char *RParenExprLocBuf = SM->getCharacterData(RParenExprLoc);
+  while (*RParenExprLocBuf != ')') RParenExprLocBuf--;
+  RParenExprLoc = startLoc.getLocWithOffset(RParenExprLocBuf-startBuf);
+  
+  SourceLocation LBranceLoc = S->getSynchBody()->getLocStart();
+  const char *LBraceLocBuf = SM->getCharacterData(LBranceLoc);
+  assert (*LBraceLocBuf == '{');
+  ReplaceText(RParenExprLoc, (LBraceLocBuf - SM->getCharacterData(RParenExprLoc) + 1), buf);
+  
+  SourceLocation startRBraceLoc = S->getSynchBody()->getLocEnd();
+  assert((*SM->getCharacterData(startRBraceLoc) == '}') &&
+         "bogus @synchronized block");
+  
+  buf = "} catch (id e) {_rethrow = e;}\n";
+  Write_RethrowObject(buf);
+  buf += "}\n";
+  buf += "}\n";
+
+  ReplaceText(startRBraceLoc, 1, buf);
+
+  return nullptr;
+}
+
+void RewriteModernObjC::WarnAboutReturnGotoStmts(Stmt *S)
+{
+  // Perform a bottom up traversal of all children.
+  for (Stmt::child_range CI = S->children(); CI; ++CI)
+    if (*CI)
+      WarnAboutReturnGotoStmts(*CI);
+
+  if (isa<ReturnStmt>(S) || isa<GotoStmt>(S)) {
+    Diags.Report(Context->getFullLoc(S->getLocStart()),
+                 TryFinallyContainsReturnDiag);
+  }
+  return;
+}
+
+Stmt *RewriteModernObjC::RewriteObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt  *S) {
+  SourceLocation startLoc = S->getAtLoc();
+  ReplaceText(startLoc, strlen("@autoreleasepool"), "/* @autoreleasepool */");
+  ReplaceText(S->getSubStmt()->getLocStart(), 1, 
+              "{ __AtAutoreleasePool __autoreleasepool; ");
+
+  return nullptr;
+}
+
+Stmt *RewriteModernObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
+  ObjCAtFinallyStmt *finalStmt = S->getFinallyStmt();
+  bool noCatch = S->getNumCatchStmts() == 0;
+  std::string buf;
+  SourceLocation TryLocation = S->getAtTryLoc();
+  ConvertSourceLocationToLineDirective(TryLocation, buf);
+  
+  if (finalStmt) {
+    if (noCatch)
+      buf += "{ id volatile _rethrow = 0;\n";
+    else {
+      buf += "{ id volatile _rethrow = 0;\ntry {\n";
+    }
+  }
+  // Get the start location and compute the semi location.
+  SourceLocation startLoc = S->getLocStart();
+  const char *startBuf = SM->getCharacterData(startLoc);
+
+  assert((*startBuf == '@') && "bogus @try location");
+  if (finalStmt)
+    ReplaceText(startLoc, 1, buf);
+  else
+    // @try -> try
+    ReplaceText(startLoc, 1, "");
+  
+  for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
+    ObjCAtCatchStmt *Catch = S->getCatchStmt(I);
+    VarDecl *catchDecl = Catch->getCatchParamDecl();
+    
+    startLoc = Catch->getLocStart();
+    bool AtRemoved = false;
+    if (catchDecl) {
+      QualType t = catchDecl->getType();
+      if (const ObjCObjectPointerType *Ptr = t->getAs<ObjCObjectPointerType>()) {
+        // Should be a pointer to a class.
+        ObjCInterfaceDecl *IDecl = Ptr->getObjectType()->getInterface();
+        if (IDecl) {
+          std::string Result;
+          ConvertSourceLocationToLineDirective(Catch->getLocStart(), Result);
+          
+          startBuf = SM->getCharacterData(startLoc);
+          assert((*startBuf == '@') && "bogus @catch location");
+          SourceLocation rParenLoc = Catch->getRParenLoc();
+          const char *rParenBuf = SM->getCharacterData(rParenLoc);
+          
+          // _objc_exc_Foo *_e as argument to catch.
+          Result += "catch (_objc_exc_"; Result += IDecl->getNameAsString();
+          Result += " *_"; Result += catchDecl->getNameAsString();
+          Result += ")";
+          ReplaceText(startLoc, rParenBuf-startBuf+1, Result);
+          // Foo *e = (Foo *)_e;
+          Result.clear();
+          Result = "{ ";
+          Result += IDecl->getNameAsString();
+          Result += " *"; Result += catchDecl->getNameAsString();
+          Result += " = ("; Result += IDecl->getNameAsString(); Result += "*)";
+          Result += "_"; Result += catchDecl->getNameAsString();
+          
+          Result += "; ";
+          SourceLocation lBraceLoc = Catch->getCatchBody()->getLocStart();
+          ReplaceText(lBraceLoc, 1, Result);
+          AtRemoved = true;
+        }
+      }
+    }
+    if (!AtRemoved)
+      // @catch -> catch
+      ReplaceText(startLoc, 1, "");
+      
+  }
+  if (finalStmt) {
+    buf.clear();
+    SourceLocation FinallyLoc = finalStmt->getLocStart();
+    
+    if (noCatch) {
+      ConvertSourceLocationToLineDirective(FinallyLoc, buf);
+      buf += "catch (id e) {_rethrow = e;}\n";
+    }
+    else {
+      buf += "}\n";
+      ConvertSourceLocationToLineDirective(FinallyLoc, buf);
+      buf += "catch (id e) {_rethrow = e;}\n";
+    }
+    
+    SourceLocation startFinalLoc = finalStmt->getLocStart();
+    ReplaceText(startFinalLoc, 8, buf);
+    Stmt *body = finalStmt->getFinallyBody();
+    SourceLocation startFinalBodyLoc = body->getLocStart();
+    buf.clear();
+    Write_RethrowObject(buf);
+    ReplaceText(startFinalBodyLoc, 1, buf);
+    
+    SourceLocation endFinalBodyLoc = body->getLocEnd();
+    ReplaceText(endFinalBodyLoc, 1, "}\n}");
+    // Now check for any return/continue/go statements within the @try.
+    WarnAboutReturnGotoStmts(S->getTryBody());
+  }
+
+  return nullptr;
+}
+
+// This can't be done with ReplaceStmt(S, ThrowExpr), since
+// the throw expression is typically a message expression that's already
+// been rewritten! (which implies the SourceLocation's are invalid).
+Stmt *RewriteModernObjC::RewriteObjCThrowStmt(ObjCAtThrowStmt *S) {
+  // Get the start location and compute the semi location.
+  SourceLocation startLoc = S->getLocStart();
+  const char *startBuf = SM->getCharacterData(startLoc);
+
+  assert((*startBuf == '@') && "bogus @throw location");
+
+  std::string buf;
+  /* void objc_exception_throw(id) __attribute__((noreturn)); */
+  if (S->getThrowExpr())
+    buf = "objc_exception_throw(";
+  else
+    buf = "throw";
+
+  // handle "@  throw" correctly.
+  const char *wBuf = strchr(startBuf, 'w');
+  assert((*wBuf == 'w') && "@throw: can't find 'w'");
+  ReplaceText(startLoc, wBuf-startBuf+1, buf);
+
+  SourceLocation endLoc = S->getLocEnd();
+  const char *endBuf = SM->getCharacterData(endLoc);
+  const char *semiBuf = strchr(endBuf, ';');
+  assert((*semiBuf == ';') && "@throw: can't find ';'");
+  SourceLocation semiLoc = startLoc.getLocWithOffset(semiBuf-startBuf);
+  if (S->getThrowExpr())
+    ReplaceText(semiLoc, 1, ");");
+  return nullptr;
+}
+
+Stmt *RewriteModernObjC::RewriteAtEncode(ObjCEncodeExpr *Exp) {
+  // Create a new string expression.
+  std::string StrEncoding;
+  Context->getObjCEncodingForType(Exp->getEncodedType(), StrEncoding);
+  Expr *Replacement = getStringLiteral(StrEncoding);
+  ReplaceStmt(Exp, Replacement);
+
+  // Replace this subexpr in the parent.
+  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
+  return Replacement;
+}
+
+Stmt *RewriteModernObjC::RewriteAtSelector(ObjCSelectorExpr *Exp) {
+  if (!SelGetUidFunctionDecl)
+    SynthSelGetUidFunctionDecl();
+  assert(SelGetUidFunctionDecl && "Can't find sel_registerName() decl");
+  // Create a call to sel_registerName("selName").
+  SmallVector<Expr*, 8> SelExprs;
+  SelExprs.push_back(getStringLiteral(Exp->getSelector().getAsString()));
+  CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
+                                                 &SelExprs[0], SelExprs.size());
+  ReplaceStmt(Exp, SelExp);
+  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
+  return SelExp;
+}
+
+CallExpr *RewriteModernObjC::SynthesizeCallToFunctionDecl(
+  FunctionDecl *FD, Expr **args, unsigned nargs, SourceLocation StartLoc,
+                                                    SourceLocation EndLoc) {
+  // Get the type, we will need to reference it in a couple spots.
+  QualType msgSendType = FD->getType();
+
+  // Create a reference to the objc_msgSend() declaration.
+  DeclRefExpr *DRE =
+    new (Context) DeclRefExpr(FD, false, msgSendType, VK_LValue, SourceLocation());
+
+  // Now, we cast the reference to a pointer to the objc_msgSend type.
+  QualType pToFunc = Context->getPointerType(msgSendType);
+  ImplicitCastExpr *ICE = 
+    ImplicitCastExpr::Create(*Context, pToFunc, CK_FunctionToPointerDecay,
+                             DRE, nullptr, VK_RValue);
+
+  const FunctionType *FT = msgSendType->getAs<FunctionType>();
+
+  CallExpr *Exp =  
+    new (Context) CallExpr(*Context, ICE, llvm::makeArrayRef(args, nargs),
+                           FT->getCallResultType(*Context),
+                           VK_RValue, EndLoc);
+  return Exp;
+}
+
+static bool scanForProtocolRefs(const char *startBuf, const char *endBuf,
+                                const char *&startRef, const char *&endRef) {
+  while (startBuf < endBuf) {
+    if (*startBuf == '<')
+      startRef = startBuf; // mark the start.
+    if (*startBuf == '>') {
+      if (startRef && *startRef == '<') {
+        endRef = startBuf; // mark the end.
+        return true;
+      }
+      return false;
+    }
+    startBuf++;
+  }
+  return false;
+}
+
+static void scanToNextArgument(const char *&argRef) {
+  int angle = 0;
+  while (*argRef != ')' && (*argRef != ',' || angle > 0)) {
+    if (*argRef == '<')
+      angle++;
+    else if (*argRef == '>')
+      angle--;
+    argRef++;
+  }
+  assert(angle == 0 && "scanToNextArgument - bad protocol type syntax");
+}
+
+bool RewriteModernObjC::needToScanForQualifiers(QualType T) {
+  if (T->isObjCQualifiedIdType())
+    return true;
+  if (const PointerType *PT = T->getAs<PointerType>()) {
+    if (PT->getPointeeType()->isObjCQualifiedIdType())
+      return true;
+  }
+  if (T->isObjCObjectPointerType()) {
+    T = T->getPointeeType();
+    return T->isObjCQualifiedInterfaceType();
+  }
+  if (T->isArrayType()) {
+    QualType ElemTy = Context->getBaseElementType(T);
+    return needToScanForQualifiers(ElemTy);
+  }
+  return false;
+}
+
+void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(Expr *E) {
+  QualType Type = E->getType();
+  if (needToScanForQualifiers(Type)) {
+    SourceLocation Loc, EndLoc;
+
+    if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E)) {
+      Loc = ECE->getLParenLoc();
+      EndLoc = ECE->getRParenLoc();
+    } else {
+      Loc = E->getLocStart();
+      EndLoc = E->getLocEnd();
+    }
+    // This will defend against trying to rewrite synthesized expressions.
+    if (Loc.isInvalid() || EndLoc.isInvalid())
+      return;
+
+    const char *startBuf = SM->getCharacterData(Loc);
+    const char *endBuf = SM->getCharacterData(EndLoc);
+    const char *startRef = nullptr, *endRef = nullptr;
+    if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
+      // Get the locations of the startRef, endRef.
+      SourceLocation LessLoc = Loc.getLocWithOffset(startRef-startBuf);
+      SourceLocation GreaterLoc = Loc.getLocWithOffset(endRef-startBuf+1);
+      // Comment out the protocol references.
+      InsertText(LessLoc, "/*");
+      InsertText(GreaterLoc, "*/");
+    }
+  }
+}
+
+void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(Decl *Dcl) {
+  SourceLocation Loc;
+  QualType Type;
+  const FunctionProtoType *proto = nullptr;
+  if (VarDecl *VD = dyn_cast<VarDecl>(Dcl)) {
+    Loc = VD->getLocation();
+    Type = VD->getType();
+  }
+  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(Dcl)) {
+    Loc = FD->getLocation();
+    // Check for ObjC 'id' and class types that have been adorned with protocol
+    // information (id<p>, C<p>*). The protocol references need to be rewritten!
+    const FunctionType *funcType = FD->getType()->getAs<FunctionType>();
+    assert(funcType && "missing function type");
+    proto = dyn_cast<FunctionProtoType>(funcType);
+    if (!proto)
+      return;
+    Type = proto->getReturnType();
+  }
+  else if (FieldDecl *FD = dyn_cast<FieldDecl>(Dcl)) {
+    Loc = FD->getLocation();
+    Type = FD->getType();
+  }
+  else if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(Dcl)) {
+    Loc = TD->getLocation();
+    Type = TD->getUnderlyingType();
+  }
+  else
+    return;
+
+  if (needToScanForQualifiers(Type)) {
+    // Since types are unique, we need to scan the buffer.
+
+    const char *endBuf = SM->getCharacterData(Loc);
+    const char *startBuf = endBuf;
+    while (*startBuf != ';' && *startBuf != '<' && startBuf != MainFileStart)
+      startBuf--; // scan backward (from the decl location) for return type.
+    const char *startRef = nullptr, *endRef = nullptr;
+    if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
+      // Get the locations of the startRef, endRef.
+      SourceLocation LessLoc = Loc.getLocWithOffset(startRef-endBuf);
+      SourceLocation GreaterLoc = Loc.getLocWithOffset(endRef-endBuf+1);
+      // Comment out the protocol references.
+      InsertText(LessLoc, "/*");
+      InsertText(GreaterLoc, "*/");
+    }
+  }
+  if (!proto)
+      return; // most likely, was a variable
+  // Now check arguments.
+  const char *startBuf = SM->getCharacterData(Loc);
+  const char *startFuncBuf = startBuf;
+  for (unsigned i = 0; i < proto->getNumParams(); i++) {
+    if (needToScanForQualifiers(proto->getParamType(i))) {
+      // Since types are unique, we need to scan the buffer.
+
+      const char *endBuf = startBuf;
+      // scan forward (from the decl location) for argument types.
+      scanToNextArgument(endBuf);
+      const char *startRef = nullptr, *endRef = nullptr;
+      if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
+        // Get the locations of the startRef, endRef.
+        SourceLocation LessLoc =
+          Loc.getLocWithOffset(startRef-startFuncBuf);
+        SourceLocation GreaterLoc =
+          Loc.getLocWithOffset(endRef-startFuncBuf+1);
+        // Comment out the protocol references.
+        InsertText(LessLoc, "/*");
+        InsertText(GreaterLoc, "*/");
+      }
+      startBuf = ++endBuf;
+    }
+    else {
+      // If the function name is derived from a macro expansion, then the
+      // argument buffer will not follow the name. Need to speak with Chris.
+      while (*startBuf && *startBuf != ')' && *startBuf != ',')
+        startBuf++; // scan forward (from the decl location) for argument types.
+      startBuf++;
+    }
+  }
+}
+
+void RewriteModernObjC::RewriteTypeOfDecl(VarDecl *ND) {
+  QualType QT = ND->getType();
+  const Type* TypePtr = QT->getAs<Type>();
+  if (!isa<TypeOfExprType>(TypePtr))
+    return;
+  while (isa<TypeOfExprType>(TypePtr)) {
+    const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
+    QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType();
+    TypePtr = QT->getAs<Type>();
+  }
+  // FIXME. This will not work for multiple declarators; as in:
+  // __typeof__(a) b,c,d;
+  std::string TypeAsString(QT.getAsString(Context->getPrintingPolicy()));
+  SourceLocation DeclLoc = ND->getTypeSpecStartLoc();
+  const char *startBuf = SM->getCharacterData(DeclLoc);
+  if (ND->getInit()) {
+    std::string Name(ND->getNameAsString());
+    TypeAsString += " " + Name + " = ";
+    Expr *E = ND->getInit();
+    SourceLocation startLoc;
+    if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E))
+      startLoc = ECE->getLParenLoc();
+    else
+      startLoc = E->getLocStart();
+    startLoc = SM->getExpansionLoc(startLoc);
+    const char *endBuf = SM->getCharacterData(startLoc);
+    ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
+  }
+  else {
+    SourceLocation X = ND->getLocEnd();
+    X = SM->getExpansionLoc(X);
+    const char *endBuf = SM->getCharacterData(X);
+    ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
+  }
+}
+
+// SynthSelGetUidFunctionDecl - SEL sel_registerName(const char *str);
+void RewriteModernObjC::SynthSelGetUidFunctionDecl() {
+  IdentifierInfo *SelGetUidIdent = &Context->Idents.get("sel_registerName");
+  SmallVector<QualType, 16> ArgTys;
+  ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
+  QualType getFuncType =
+    getSimpleFunctionType(Context->getObjCSelType(), ArgTys);
+  SelGetUidFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                               SourceLocation(),
+                                               SourceLocation(),
+                                               SelGetUidIdent, getFuncType,
+                                               nullptr, SC_Extern);
+}
+
+void RewriteModernObjC::RewriteFunctionDecl(FunctionDecl *FD) {
+  // declared in <objc/objc.h>
+  if (FD->getIdentifier() &&
+      FD->getName() == "sel_registerName") {
+    SelGetUidFunctionDecl = FD;
+    return;
+  }
+  RewriteObjCQualifiedInterfaceTypes(FD);
+}
+
+void RewriteModernObjC::RewriteBlockPointerType(std::string& Str, QualType Type) {
+  std::string TypeString(Type.getAsString(Context->getPrintingPolicy()));
+  const char *argPtr = TypeString.c_str();
+  if (!strchr(argPtr, '^')) {
+    Str += TypeString;
+    return;
+  }
+  while (*argPtr) {
+    Str += (*argPtr == '^' ? '*' : *argPtr);
+    argPtr++;
+  }
+}
+
+// FIXME. Consolidate this routine with RewriteBlockPointerType.
+void RewriteModernObjC::RewriteBlockPointerTypeVariable(std::string& Str,
+                                                  ValueDecl *VD) {
+  QualType Type = VD->getType();
+  std::string TypeString(Type.getAsString(Context->getPrintingPolicy()));
+  const char *argPtr = TypeString.c_str();
+  int paren = 0;
+  while (*argPtr) {
+    switch (*argPtr) {
+      case '(':
+        Str += *argPtr;
+        paren++;
+        break;
+      case ')':
+        Str += *argPtr;
+        paren--;
+        break;
+      case '^':
+        Str += '*';
+        if (paren == 1)
+          Str += VD->getNameAsString();
+        break;
+      default:
+        Str += *argPtr;
+        break;
+    }
+    argPtr++;
+  }
+}
+
+void RewriteModernObjC::RewriteBlockLiteralFunctionDecl(FunctionDecl *FD) {
+  SourceLocation FunLocStart = FD->getTypeSpecStartLoc();
+  const FunctionType *funcType = FD->getType()->getAs<FunctionType>();
+  const FunctionProtoType *proto = dyn_cast<FunctionProtoType>(funcType);
+  if (!proto)
+    return;
+  QualType Type = proto->getReturnType();
+  std::string FdStr = Type.getAsString(Context->getPrintingPolicy());
+  FdStr += " ";
+  FdStr += FD->getName();
+  FdStr +=  "(";
+  unsigned numArgs = proto->getNumParams();
+  for (unsigned i = 0; i < numArgs; i++) {
+    QualType ArgType = proto->getParamType(i);
+  RewriteBlockPointerType(FdStr, ArgType);
+  if (i+1 < numArgs)
+    FdStr += ", ";
+  }
+  if (FD->isVariadic()) {
+    FdStr +=  (numArgs > 0) ? ", ...);\n" : "...);\n";
+  }
+  else
+    FdStr +=  ");\n";
+  InsertText(FunLocStart, FdStr);
+}
+
+// SynthSuperConstructorFunctionDecl - id __rw_objc_super(id obj, id super);
+void RewriteModernObjC::SynthSuperConstructorFunctionDecl() {
+  if (SuperConstructorFunctionDecl)
+    return;
+  IdentifierInfo *msgSendIdent = &Context->Idents.get("__rw_objc_super");
+  SmallVector<QualType, 16> ArgTys;
+  QualType argT = Context->getObjCIdType();
+  assert(!argT.isNull() && "Can't find 'id' type");
+  ArgTys.push_back(argT);
+  ArgTys.push_back(argT);
+  QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
+                                               ArgTys);
+  SuperConstructorFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                                     SourceLocation(),
+                                                     SourceLocation(),
+                                                     msgSendIdent, msgSendType,
+                                                     nullptr, SC_Extern);
+}
+
+// SynthMsgSendFunctionDecl - id objc_msgSend(id self, SEL op, ...);
+void RewriteModernObjC::SynthMsgSendFunctionDecl() {
+  IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend");
+  SmallVector<QualType, 16> ArgTys;
+  QualType argT = Context->getObjCIdType();
+  assert(!argT.isNull() && "Can't find 'id' type");
+  ArgTys.push_back(argT);
+  argT = Context->getObjCSelType();
+  assert(!argT.isNull() && "Can't find 'SEL' type");
+  ArgTys.push_back(argT);
+  QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
+                                               ArgTys, /*isVariadic=*/true);
+  MsgSendFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                             SourceLocation(),
+                                             SourceLocation(),
+                                             msgSendIdent, msgSendType, nullptr,
+                                             SC_Extern);
+}
+
+// SynthMsgSendSuperFunctionDecl - id objc_msgSendSuper(void);
+void RewriteModernObjC::SynthMsgSendSuperFunctionDecl() {
+  IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSendSuper");
+  SmallVector<QualType, 2> ArgTys;
+  ArgTys.push_back(Context->VoidTy);
+  QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
+                                               ArgTys, /*isVariadic=*/true);
+  MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                                  SourceLocation(),
+                                                  SourceLocation(),
+                                                  msgSendIdent, msgSendType,
+                                                  nullptr, SC_Extern);
+}
+
+// SynthMsgSendStretFunctionDecl - id objc_msgSend_stret(id self, SEL op, ...);
+void RewriteModernObjC::SynthMsgSendStretFunctionDecl() {
+  IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_stret");
+  SmallVector<QualType, 16> ArgTys;
+  QualType argT = Context->getObjCIdType();
+  assert(!argT.isNull() && "Can't find 'id' type");
+  ArgTys.push_back(argT);
+  argT = Context->getObjCSelType();
+  assert(!argT.isNull() && "Can't find 'SEL' type");
+  ArgTys.push_back(argT);
+  QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
+                                               ArgTys, /*isVariadic=*/true);
+  MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                                  SourceLocation(),
+                                                  SourceLocation(),
+                                                  msgSendIdent, msgSendType,
+                                                  nullptr, SC_Extern);
+}
+
+// SynthMsgSendSuperStretFunctionDecl -
+// id objc_msgSendSuper_stret(void);
+void RewriteModernObjC::SynthMsgSendSuperStretFunctionDecl() {
+  IdentifierInfo *msgSendIdent =
+    &Context->Idents.get("objc_msgSendSuper_stret");
+  SmallVector<QualType, 2> ArgTys;
+  ArgTys.push_back(Context->VoidTy);
+  QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
+                                               ArgTys, /*isVariadic=*/true);
+  MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                                       SourceLocation(),
+                                                       SourceLocation(),
+                                                       msgSendIdent,
+                                                       msgSendType, nullptr,
+                                                       SC_Extern);
+}
+
+// SynthMsgSendFpretFunctionDecl - double objc_msgSend_fpret(id self, SEL op, ...);
+void RewriteModernObjC::SynthMsgSendFpretFunctionDecl() {
+  IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_fpret");
+  SmallVector<QualType, 16> ArgTys;
+  QualType argT = Context->getObjCIdType();
+  assert(!argT.isNull() && "Can't find 'id' type");
+  ArgTys.push_back(argT);
+  argT = Context->getObjCSelType();
+  assert(!argT.isNull() && "Can't find 'SEL' type");
+  ArgTys.push_back(argT);
+  QualType msgSendType = getSimpleFunctionType(Context->DoubleTy,
+                                               ArgTys, /*isVariadic=*/true);
+  MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                                  SourceLocation(),
+                                                  SourceLocation(),
+                                                  msgSendIdent, msgSendType,
+                                                  nullptr, SC_Extern);
+}
+
+// SynthGetClassFunctionDecl - Class objc_getClass(const char *name);
+void RewriteModernObjC::SynthGetClassFunctionDecl() {
+  IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getClass");
+  SmallVector<QualType, 16> ArgTys;
+  ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
+  QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(),
+                                                ArgTys);
+  GetClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                              SourceLocation(),
+                                              SourceLocation(),
+                                              getClassIdent, getClassType,
+                                              nullptr, SC_Extern);
+}
+
+// SynthGetSuperClassFunctionDecl - Class class_getSuperclass(Class cls);
+void RewriteModernObjC::SynthGetSuperClassFunctionDecl() {
+  IdentifierInfo *getSuperClassIdent = 
+    &Context->Idents.get("class_getSuperclass");
+  SmallVector<QualType, 16> ArgTys;
+  ArgTys.push_back(Context->getObjCClassType());
+  QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(),
+                                                ArgTys);
+  GetSuperClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                                   SourceLocation(),
+                                                   SourceLocation(),
+                                                   getSuperClassIdent,
+                                                   getClassType, nullptr,
+                                                   SC_Extern);
+}
+
+// SynthGetMetaClassFunctionDecl - Class objc_getMetaClass(const char *name);
+void RewriteModernObjC::SynthGetMetaClassFunctionDecl() {
+  IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getMetaClass");
+  SmallVector<QualType, 16> ArgTys;
+  ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
+  QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(),
+                                                ArgTys);
+  GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                                  SourceLocation(),
+                                                  SourceLocation(),
+                                                  getClassIdent, getClassType,
+                                                  nullptr, SC_Extern);
+}
+
+Stmt *RewriteModernObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) {
+  assert (Exp != nullptr && "Expected non-null ObjCStringLiteral");
+  QualType strType = getConstantStringStructType();
+
+  std::string S = "__NSConstantStringImpl_";
+
+  std::string tmpName = InFileName;
+  unsigned i;
+  for (i=0; i < tmpName.length(); i++) {
+    char c = tmpName.at(i);
+    // replace any non-alphanumeric characters with '_'.
+    if (!isAlphanumeric(c))
+      tmpName[i] = '_';
+  }
+  S += tmpName;
+  S += "_";
+  S += utostr(NumObjCStringLiterals++);
+
+  Preamble += "static __NSConstantStringImpl " + S;
+  Preamble += " __attribute__ ((section (\"__DATA, __cfstring\"))) = {__CFConstantStringClassReference,";
+  Preamble += "0x000007c8,"; // utf8_str
+  // The pretty printer for StringLiteral handles escape characters properly.
+  std::string prettyBufS;
+  llvm::raw_string_ostream prettyBuf(prettyBufS);
+  Exp->getString()->printPretty(prettyBuf, nullptr, PrintingPolicy(LangOpts));
+  Preamble += prettyBuf.str();
+  Preamble += ",";
+  Preamble += utostr(Exp->getString()->getByteLength()) + "};\n";
+
+  VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
+                                   SourceLocation(), &Context->Idents.get(S),
+                                   strType, nullptr, SC_Static);
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, false, strType, VK_LValue,
+                                               SourceLocation());
+  Expr *Unop = new (Context) UnaryOperator(DRE, UO_AddrOf,
+                                 Context->getPointerType(DRE->getType()),
+                                           VK_RValue, OK_Ordinary,
+                                           SourceLocation());
+  // cast to NSConstantString *
+  CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Exp->getType(),
+                                            CK_CPointerToObjCPointerCast, Unop);
+  ReplaceStmt(Exp, cast);
+  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
+  return cast;
+}
+
+Stmt *RewriteModernObjC::RewriteObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Exp) {
+  unsigned IntSize =
+    static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
+  
+  Expr *FlagExp = IntegerLiteral::Create(*Context, 
+                                         llvm::APInt(IntSize, Exp->getValue()), 
+                                         Context->IntTy, Exp->getLocation());
+  CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Context->ObjCBuiltinBoolTy,
+                                            CK_BitCast, FlagExp);
+  ParenExpr *PE = new (Context) ParenExpr(Exp->getLocation(), Exp->getExprLoc(), 
+                                          cast);
+  ReplaceStmt(Exp, PE);
+  return PE;
+}
+
+Stmt *RewriteModernObjC::RewriteObjCBoxedExpr(ObjCBoxedExpr *Exp) {
+  // synthesize declaration of helper functions needed in this routine.
+  if (!SelGetUidFunctionDecl)
+    SynthSelGetUidFunctionDecl();
+  // use objc_msgSend() for all.
+  if (!MsgSendFunctionDecl)
+    SynthMsgSendFunctionDecl();
+  if (!GetClassFunctionDecl)
+    SynthGetClassFunctionDecl();
+  
+  FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl;
+  SourceLocation StartLoc = Exp->getLocStart();
+  SourceLocation EndLoc = Exp->getLocEnd();
+  
+  // Synthesize a call to objc_msgSend().
+  SmallVector<Expr*, 4> MsgExprs;
+  SmallVector<Expr*, 4> ClsExprs;
+  
+  // Create a call to objc_getClass("<BoxingClass>"). It will be the 1st argument.
+  ObjCMethodDecl *BoxingMethod = Exp->getBoxingMethod();
+  ObjCInterfaceDecl *BoxingClass = BoxingMethod->getClassInterface();
+  
+  IdentifierInfo *clsName = BoxingClass->getIdentifier();
+  ClsExprs.push_back(getStringLiteral(clsName->getName()));
+  CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
+                                               &ClsExprs[0],
+                                               ClsExprs.size(), 
+                                               StartLoc, EndLoc);
+  MsgExprs.push_back(Cls);
+  
+  // Create a call to sel_registerName("<BoxingMethod>:"), etc.
+  // it will be the 2nd argument.
+  SmallVector<Expr*, 4> SelExprs;
+  SelExprs.push_back(
+      getStringLiteral(BoxingMethod->getSelector().getAsString()));
+  CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
+                                                  &SelExprs[0], SelExprs.size(),
+                                                  StartLoc, EndLoc);
+  MsgExprs.push_back(SelExp);
+  
+  // User provided sub-expression is the 3rd, and last, argument.
+  Expr *subExpr  = Exp->getSubExpr();
+  if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(subExpr)) {
+    QualType type = ICE->getType();
+    const Expr *SubExpr = ICE->IgnoreParenImpCasts();
+    CastKind CK = CK_BitCast;
+    if (SubExpr->getType()->isIntegralType(*Context) && type->isBooleanType())
+      CK = CK_IntegralToBoolean;
+    subExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, subExpr);
+  }
+  MsgExprs.push_back(subExpr);
+  
+  SmallVector<QualType, 4> ArgTypes;
+  ArgTypes.push_back(Context->getObjCIdType());
+  ArgTypes.push_back(Context->getObjCSelType());
+  for (const auto PI : BoxingMethod->parameters())
+    ArgTypes.push_back(PI->getType());
+  
+  QualType returnType = Exp->getType();
+  // Get the type, we will need to reference it in a couple spots.
+  QualType msgSendType = MsgSendFlavor->getType();
+  
+  // Create a reference to the objc_msgSend() declaration.
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType,
+                                               VK_LValue, SourceLocation());
+  
+  CastExpr *cast = NoTypeInfoCStyleCastExpr(Context,
+                                            Context->getPointerType(Context->VoidTy),
+                                            CK_BitCast, DRE);
+  
+  // Now do the "normal" pointer to function cast.
+  QualType castType =
+    getSimpleFunctionType(returnType, ArgTypes, BoxingMethod->isVariadic());
+  castType = Context->getPointerType(castType);
+  cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
+                                  cast);
+  
+  // Don't forget the parens to enforce the proper binding.
+  ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
+  
+  const FunctionType *FT = msgSendType->getAs<FunctionType>();
+  CallExpr *CE = new (Context)
+      CallExpr(*Context, PE, MsgExprs, FT->getReturnType(), VK_RValue, EndLoc);
+  ReplaceStmt(Exp, CE);
+  return CE;
+}
+
+Stmt *RewriteModernObjC::RewriteObjCArrayLiteralExpr(ObjCArrayLiteral *Exp) {
+  // synthesize declaration of helper functions needed in this routine.
+  if (!SelGetUidFunctionDecl)
+    SynthSelGetUidFunctionDecl();
+  // use objc_msgSend() for all.
+  if (!MsgSendFunctionDecl)
+    SynthMsgSendFunctionDecl();
+  if (!GetClassFunctionDecl)
+    SynthGetClassFunctionDecl();
+  
+  FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl;
+  SourceLocation StartLoc = Exp->getLocStart();
+  SourceLocation EndLoc = Exp->getLocEnd();
+  
+  // Build the expression: __NSContainer_literal(int, ...).arr
+  QualType IntQT = Context->IntTy;
+  QualType NSArrayFType =
+    getSimpleFunctionType(Context->VoidTy, IntQT, true);
+  std::string NSArrayFName("__NSContainer_literal");
+  FunctionDecl *NSArrayFD = SynthBlockInitFunctionDecl(NSArrayFName);
+  DeclRefExpr *NSArrayDRE = 
+    new (Context) DeclRefExpr(NSArrayFD, false, NSArrayFType, VK_RValue,
+                              SourceLocation());
+
+  SmallVector<Expr*, 16> InitExprs;
+  unsigned NumElements = Exp->getNumElements();
+  unsigned UnsignedIntSize = 
+    static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
+  Expr *count = IntegerLiteral::Create(*Context,
+                                       llvm::APInt(UnsignedIntSize, NumElements),
+                                       Context->UnsignedIntTy, SourceLocation());
+  InitExprs.push_back(count);
+  for (unsigned i = 0; i < NumElements; i++)
+    InitExprs.push_back(Exp->getElement(i));
+  Expr *NSArrayCallExpr = 
+    new (Context) CallExpr(*Context, NSArrayDRE, InitExprs,
+                           NSArrayFType, VK_LValue, SourceLocation());
+
+  FieldDecl *ARRFD = FieldDecl::Create(*Context, nullptr, SourceLocation(),
+                                    SourceLocation(),
+                                    &Context->Idents.get("arr"),
+                                    Context->getPointerType(Context->VoidPtrTy),
+                                    nullptr, /*BitWidth=*/nullptr,
+                                    /*Mutable=*/true, ICIS_NoInit);
+  MemberExpr *ArrayLiteralME = 
+    new (Context) MemberExpr(NSArrayCallExpr, false, ARRFD, 
+                             SourceLocation(),
+                             ARRFD->getType(), VK_LValue,
+                             OK_Ordinary);
+  QualType ConstIdT = Context->getObjCIdType().withConst();
+  CStyleCastExpr * ArrayLiteralObjects = 
+    NoTypeInfoCStyleCastExpr(Context, 
+                             Context->getPointerType(ConstIdT),
+                             CK_BitCast,
+                             ArrayLiteralME);
+  
+  // Synthesize a call to objc_msgSend().
+  SmallVector<Expr*, 32> MsgExprs;
+  SmallVector<Expr*, 4> ClsExprs;
+  QualType expType = Exp->getType();
+  
+  // Create a call to objc_getClass("NSArray"). It will be th 1st argument.
+  ObjCInterfaceDecl *Class = 
+    expType->getPointeeType()->getAs<ObjCObjectType>()->getInterface();
+  
+  IdentifierInfo *clsName = Class->getIdentifier();
+  ClsExprs.push_back(getStringLiteral(clsName->getName()));
+  CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
+                                               &ClsExprs[0],
+                                               ClsExprs.size(), 
+                                               StartLoc, EndLoc);
+  MsgExprs.push_back(Cls);
+  
+  // Create a call to sel_registerName("arrayWithObjects:count:").
+  // it will be the 2nd argument.
+  SmallVector<Expr*, 4> SelExprs;
+  ObjCMethodDecl *ArrayMethod = Exp->getArrayWithObjectsMethod();
+  SelExprs.push_back(
+      getStringLiteral(ArrayMethod->getSelector().getAsString()));
+  CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
+                                                  &SelExprs[0], SelExprs.size(),
+                                                  StartLoc, EndLoc);
+  MsgExprs.push_back(SelExp);
+  
+  // (const id [])objects
+  MsgExprs.push_back(ArrayLiteralObjects);
+  
+  // (NSUInteger)cnt
+  Expr *cnt = IntegerLiteral::Create(*Context,
+                                     llvm::APInt(UnsignedIntSize, NumElements),
+                                     Context->UnsignedIntTy, SourceLocation());
+  MsgExprs.push_back(cnt);
+  
+  
+  SmallVector<QualType, 4> ArgTypes;
+  ArgTypes.push_back(Context->getObjCIdType());
+  ArgTypes.push_back(Context->getObjCSelType());
+  for (const auto *PI : ArrayMethod->params())
+    ArgTypes.push_back(PI->getType());
+  
+  QualType returnType = Exp->getType();
+  // Get the type, we will need to reference it in a couple spots.
+  QualType msgSendType = MsgSendFlavor->getType();
+  
+  // Create a reference to the objc_msgSend() declaration.
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType,
+                                               VK_LValue, SourceLocation());
+  
+  CastExpr *cast = NoTypeInfoCStyleCastExpr(Context,
+                                            Context->getPointerType(Context->VoidTy),
+                                            CK_BitCast, DRE);
+  
+  // Now do the "normal" pointer to function cast.
+  QualType castType =
+  getSimpleFunctionType(returnType, ArgTypes, ArrayMethod->isVariadic());
+  castType = Context->getPointerType(castType);
+  cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
+                                  cast);
+  
+  // Don't forget the parens to enforce the proper binding.
+  ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
+  
+  const FunctionType *FT = msgSendType->getAs<FunctionType>();
+  CallExpr *CE = new (Context)
+      CallExpr(*Context, PE, MsgExprs, FT->getReturnType(), VK_RValue, EndLoc);
+  ReplaceStmt(Exp, CE);
+  return CE;
+}
+
+Stmt *RewriteModernObjC::RewriteObjCDictionaryLiteralExpr(ObjCDictionaryLiteral *Exp) {
+  // synthesize declaration of helper functions needed in this routine.
+  if (!SelGetUidFunctionDecl)
+    SynthSelGetUidFunctionDecl();
+  // use objc_msgSend() for all.
+  if (!MsgSendFunctionDecl)
+    SynthMsgSendFunctionDecl();
+  if (!GetClassFunctionDecl)
+    SynthGetClassFunctionDecl();
+  
+  FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl;
+  SourceLocation StartLoc = Exp->getLocStart();
+  SourceLocation EndLoc = Exp->getLocEnd();
+  
+  // Build the expression: __NSContainer_literal(int, ...).arr
+  QualType IntQT = Context->IntTy;
+  QualType NSDictFType =
+    getSimpleFunctionType(Context->VoidTy, IntQT, true);
+  std::string NSDictFName("__NSContainer_literal");
+  FunctionDecl *NSDictFD = SynthBlockInitFunctionDecl(NSDictFName);
+  DeclRefExpr *NSDictDRE = 
+    new (Context) DeclRefExpr(NSDictFD, false, NSDictFType, VK_RValue,
+                              SourceLocation());
+  
+  SmallVector<Expr*, 16> KeyExprs;
+  SmallVector<Expr*, 16> ValueExprs;
+  
+  unsigned NumElements = Exp->getNumElements();
+  unsigned UnsignedIntSize = 
+    static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
+  Expr *count = IntegerLiteral::Create(*Context,
+                                       llvm::APInt(UnsignedIntSize, NumElements),
+                                       Context->UnsignedIntTy, SourceLocation());
+  KeyExprs.push_back(count);
+  ValueExprs.push_back(count);
+  for (unsigned i = 0; i < NumElements; i++) {
+    ObjCDictionaryElement Element = Exp->getKeyValueElement(i);
+    KeyExprs.push_back(Element.Key);
+    ValueExprs.push_back(Element.Value);
+  }
+  
+  // (const id [])objects
+  Expr *NSValueCallExpr = 
+    new (Context) CallExpr(*Context, NSDictDRE, ValueExprs,
+                           NSDictFType, VK_LValue, SourceLocation());
+
+  FieldDecl *ARRFD = FieldDecl::Create(*Context, nullptr, SourceLocation(),
+                                       SourceLocation(),
+                                       &Context->Idents.get("arr"),
+                                       Context->getPointerType(Context->VoidPtrTy),
+                                       nullptr, /*BitWidth=*/nullptr,
+                                       /*Mutable=*/true, ICIS_NoInit);
+  MemberExpr *DictLiteralValueME = 
+    new (Context) MemberExpr(NSValueCallExpr, false, ARRFD, 
+                             SourceLocation(),
+                             ARRFD->getType(), VK_LValue,
+                             OK_Ordinary);
+  QualType ConstIdT = Context->getObjCIdType().withConst();
+  CStyleCastExpr * DictValueObjects = 
+    NoTypeInfoCStyleCastExpr(Context, 
+                             Context->getPointerType(ConstIdT),
+                             CK_BitCast,
+                             DictLiteralValueME);
+  // (const id <NSCopying> [])keys
+  Expr *NSKeyCallExpr = 
+    new (Context) CallExpr(*Context, NSDictDRE, KeyExprs,
+                           NSDictFType, VK_LValue, SourceLocation());
+  
+  MemberExpr *DictLiteralKeyME = 
+    new (Context) MemberExpr(NSKeyCallExpr, false, ARRFD, 
+                             SourceLocation(),
+                             ARRFD->getType(), VK_LValue,
+                             OK_Ordinary);
+  
+  CStyleCastExpr * DictKeyObjects = 
+    NoTypeInfoCStyleCastExpr(Context, 
+                             Context->getPointerType(ConstIdT),
+                             CK_BitCast,
+                             DictLiteralKeyME);
+  
+  
+  
+  // Synthesize a call to objc_msgSend().
+  SmallVector<Expr*, 32> MsgExprs;
+  SmallVector<Expr*, 4> ClsExprs;
+  QualType expType = Exp->getType();
+  
+  // Create a call to objc_getClass("NSArray"). It will be th 1st argument.
+  ObjCInterfaceDecl *Class = 
+  expType->getPointeeType()->getAs<ObjCObjectType>()->getInterface();
+  
+  IdentifierInfo *clsName = Class->getIdentifier();
+  ClsExprs.push_back(getStringLiteral(clsName->getName()));
+  CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
+                                               &ClsExprs[0],
+                                               ClsExprs.size(), 
+                                               StartLoc, EndLoc);
+  MsgExprs.push_back(Cls);
+  
+  // Create a call to sel_registerName("arrayWithObjects:count:").
+  // it will be the 2nd argument.
+  SmallVector<Expr*, 4> SelExprs;
+  ObjCMethodDecl *DictMethod = Exp->getDictWithObjectsMethod();
+  SelExprs.push_back(getStringLiteral(DictMethod->getSelector().getAsString()));
+  CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
+                                                  &SelExprs[0], SelExprs.size(),
+                                                  StartLoc, EndLoc);
+  MsgExprs.push_back(SelExp);
+  
+  // (const id [])objects
+  MsgExprs.push_back(DictValueObjects);
+  
+  // (const id <NSCopying> [])keys
+  MsgExprs.push_back(DictKeyObjects);
+  
+  // (NSUInteger)cnt
+  Expr *cnt = IntegerLiteral::Create(*Context,
+                                     llvm::APInt(UnsignedIntSize, NumElements),
+                                     Context->UnsignedIntTy, SourceLocation());
+  MsgExprs.push_back(cnt);
+  
+  
+  SmallVector<QualType, 8> ArgTypes;
+  ArgTypes.push_back(Context->getObjCIdType());
+  ArgTypes.push_back(Context->getObjCSelType());
+  for (const auto *PI : DictMethod->params()) {
+    QualType T = PI->getType();
+    if (const PointerType* PT = T->getAs<PointerType>()) {
+      QualType PointeeTy = PT->getPointeeType();
+      convertToUnqualifiedObjCType(PointeeTy);
+      T = Context->getPointerType(PointeeTy);
+    }
+    ArgTypes.push_back(T);
+  }
+  
+  QualType returnType = Exp->getType();
+  // Get the type, we will need to reference it in a couple spots.
+  QualType msgSendType = MsgSendFlavor->getType();
+  
+  // Create a reference to the objc_msgSend() declaration.
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType,
+                                               VK_LValue, SourceLocation());
+  
+  CastExpr *cast = NoTypeInfoCStyleCastExpr(Context,
+                                            Context->getPointerType(Context->VoidTy),
+                                            CK_BitCast, DRE);
+  
+  // Now do the "normal" pointer to function cast.
+  QualType castType =
+  getSimpleFunctionType(returnType, ArgTypes, DictMethod->isVariadic());
+  castType = Context->getPointerType(castType);
+  cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
+                                  cast);
+  
+  // Don't forget the parens to enforce the proper binding.
+  ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
+  
+  const FunctionType *FT = msgSendType->getAs<FunctionType>();
+  CallExpr *CE = new (Context)
+      CallExpr(*Context, PE, MsgExprs, FT->getReturnType(), VK_RValue, EndLoc);
+  ReplaceStmt(Exp, CE);
+  return CE;
+}
+
+// struct __rw_objc_super { 
+//   struct objc_object *object; struct objc_object *superClass; 
+// };
+QualType RewriteModernObjC::getSuperStructType() {
+  if (!SuperStructDecl) {
+    SuperStructDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
+                                         SourceLocation(), SourceLocation(),
+                                         &Context->Idents.get("__rw_objc_super"));
+    QualType FieldTypes[2];
+
+    // struct objc_object *object;
+    FieldTypes[0] = Context->getObjCIdType();
+    // struct objc_object *superClass;
+    FieldTypes[1] = Context->getObjCIdType();
+
+    // Create fields
+    for (unsigned i = 0; i < 2; ++i) {
+      SuperStructDecl->addDecl(FieldDecl::Create(*Context, SuperStructDecl,
+                                                 SourceLocation(),
+                                                 SourceLocation(), nullptr,
+                                                 FieldTypes[i], nullptr,
+                                                 /*BitWidth=*/nullptr,
+                                                 /*Mutable=*/false,
+                                                 ICIS_NoInit));
+    }
+
+    SuperStructDecl->completeDefinition();
+  }
+  return Context->getTagDeclType(SuperStructDecl);
+}
+
+QualType RewriteModernObjC::getConstantStringStructType() {
+  if (!ConstantStringDecl) {
+    ConstantStringDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
+                                            SourceLocation(), SourceLocation(),
+                         &Context->Idents.get("__NSConstantStringImpl"));
+    QualType FieldTypes[4];
+
+    // struct objc_object *receiver;
+    FieldTypes[0] = Context->getObjCIdType();
+    // int flags;
+    FieldTypes[1] = Context->IntTy;
+    // char *str;
+    FieldTypes[2] = Context->getPointerType(Context->CharTy);
+    // long length;
+    FieldTypes[3] = Context->LongTy;
+
+    // Create fields
+    for (unsigned i = 0; i < 4; ++i) {
+      ConstantStringDecl->addDecl(FieldDecl::Create(*Context,
+                                                    ConstantStringDecl,
+                                                    SourceLocation(),
+                                                    SourceLocation(), nullptr,
+                                                    FieldTypes[i], nullptr,
+                                                    /*BitWidth=*/nullptr,
+                                                    /*Mutable=*/true,
+                                                    ICIS_NoInit));
+    }
+
+    ConstantStringDecl->completeDefinition();
+  }
+  return Context->getTagDeclType(ConstantStringDecl);
+}
+
+/// getFunctionSourceLocation - returns start location of a function
+/// definition. Complication arises when function has declared as
+/// extern "C" or extern "C" {...}
+static SourceLocation getFunctionSourceLocation (RewriteModernObjC &R,
+                                                 FunctionDecl *FD) {
+  if (FD->isExternC()  && !FD->isMain()) {
+    const DeclContext *DC = FD->getDeclContext();
+    if (const LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(DC))
+      // if it is extern "C" {...}, return function decl's own location.
+      if (!LSD->getRBraceLoc().isValid())
+        return LSD->getExternLoc();
+  }
+  if (FD->getStorageClass() != SC_None)
+    R.RewriteBlockLiteralFunctionDecl(FD);
+  return FD->getTypeSpecStartLoc();
+}
+
+void RewriteModernObjC::RewriteLineDirective(const Decl *D) {
+  
+  SourceLocation Location = D->getLocation();
+  
+  if (Location.isFileID() && GenerateLineInfo) {
+    std::string LineString("\n#line ");
+    PresumedLoc PLoc = SM->getPresumedLoc(Location);
+    LineString += utostr(PLoc.getLine());
+    LineString += " \"";
+    LineString += Lexer::Stringify(PLoc.getFilename());
+    if (isa<ObjCMethodDecl>(D))
+      LineString += "\"";
+    else LineString += "\"\n";
+    
+    Location = D->getLocStart();
+    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+      if (FD->isExternC()  && !FD->isMain()) {
+        const DeclContext *DC = FD->getDeclContext();
+        if (const LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(DC))
+          // if it is extern "C" {...}, return function decl's own location.
+          if (!LSD->getRBraceLoc().isValid())
+            Location = LSD->getExternLoc();
+      }
+    }
+    InsertText(Location, LineString);
+  }
+}
+
+/// SynthMsgSendStretCallExpr - This routine translates message expression
+/// into a call to objc_msgSend_stret() entry point. Tricky part is that
+/// nil check on receiver must be performed before calling objc_msgSend_stret.
+/// MsgSendStretFlavor - function declaration objc_msgSend_stret(...)
+/// msgSendType - function type of objc_msgSend_stret(...)
+/// returnType - Result type of the method being synthesized.
+/// ArgTypes - type of the arguments passed to objc_msgSend_stret, starting with receiver type.
+/// MsgExprs - list of argument expressions being passed to objc_msgSend_stret, 
+/// starting with receiver.
+/// Method - Method being rewritten.
+Expr *RewriteModernObjC::SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFlavor,
+                                                 QualType returnType, 
+                                                 SmallVectorImpl<QualType> &ArgTypes,
+                                                 SmallVectorImpl<Expr*> &MsgExprs,
+                                                 ObjCMethodDecl *Method) {
+  // Now do the "normal" pointer to function cast.
+  QualType castType = getSimpleFunctionType(returnType, ArgTypes,
+                                            Method ? Method->isVariadic()
+                                                   : false);
+  castType = Context->getPointerType(castType);
+  
+  // build type for containing the objc_msgSend_stret object.
+  static unsigned stretCount=0;
+  std::string name = "__Stret"; name += utostr(stretCount);
+  std::string str = 
+    "extern \"C\" void * __cdecl memset(void *_Dst, int _Val, size_t _Size);\n";
+  str += "namespace {\n";
+  str += "struct "; str += name;
+  str += " {\n\t";
+  str += name;
+  str += "(id receiver, SEL sel";
+  for (unsigned i = 2; i < ArgTypes.size(); i++) {
+    std::string ArgName = "arg"; ArgName += utostr(i);
+    ArgTypes[i].getAsStringInternal(ArgName, Context->getPrintingPolicy());
+    str += ", "; str += ArgName;
+  }
+  // could be vararg.
+  for (unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
+    std::string ArgName = "arg"; ArgName += utostr(i);
+    MsgExprs[i]->getType().getAsStringInternal(ArgName,
+                                               Context->getPrintingPolicy());
+    str += ", "; str += ArgName;
+  }
+  
+  str += ") {\n";
+  str += "\t  unsigned size = sizeof(";
+  str += returnType.getAsString(Context->getPrintingPolicy()); str += ");\n";
+  
+  str += "\t  if (size == 1 || size == 2 || size == 4 || size == 8)\n";
+  
+  str += "\t    s = (("; str += castType.getAsString(Context->getPrintingPolicy());
+  str += ")(void *)objc_msgSend)(receiver, sel";
+  for (unsigned i = 2; i < ArgTypes.size(); i++) {
+    str += ", arg"; str += utostr(i);
+  }
+  // could be vararg.
+  for (unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
+    str += ", arg"; str += utostr(i);
+  }
+  str+= ");\n";
+  
+  str += "\t  else if (receiver == 0)\n";
+  str += "\t    memset((void*)&s, 0, sizeof(s));\n";
+  str += "\t  else\n";
+  
+  
+  str += "\t    s = (("; str += castType.getAsString(Context->getPrintingPolicy());
+  str += ")(void *)objc_msgSend_stret)(receiver, sel";
+  for (unsigned i = 2; i < ArgTypes.size(); i++) {
+    str += ", arg"; str += utostr(i);
+  }
+  // could be vararg.
+  for (unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
+    str += ", arg"; str += utostr(i);
+  }
+  str += ");\n";
+  
+  
+  str += "\t}\n";
+  str += "\t"; str += returnType.getAsString(Context->getPrintingPolicy());
+  str += " s;\n";
+  str += "};\n};\n\n";
+  SourceLocation FunLocStart;
+  if (CurFunctionDef)
+    FunLocStart = getFunctionSourceLocation(*this, CurFunctionDef);
+  else {
+    assert(CurMethodDef && "SynthMsgSendStretCallExpr - CurMethodDef is null");
+    FunLocStart = CurMethodDef->getLocStart();
+  }
+
+  InsertText(FunLocStart, str);
+  ++stretCount;
+  
+  // AST for __Stretn(receiver, args).s;
+  IdentifierInfo *ID = &Context->Idents.get(name);
+  FunctionDecl *FD = FunctionDecl::Create(*Context, TUDecl, SourceLocation(),
+                                          SourceLocation(), ID, castType,
+                                          nullptr, SC_Extern, false, false);
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, false, castType, VK_RValue,
+                                               SourceLocation());
+  CallExpr *STCE = new (Context) CallExpr(*Context, DRE, MsgExprs,
+                                          castType, VK_LValue, SourceLocation());
+
+  FieldDecl *FieldD = FieldDecl::Create(*Context, nullptr, SourceLocation(),
+                                    SourceLocation(),
+                                    &Context->Idents.get("s"),
+                                    returnType, nullptr,
+                                    /*BitWidth=*/nullptr,
+                                    /*Mutable=*/true, ICIS_NoInit);
+  MemberExpr *ME = new (Context) MemberExpr(STCE, false, FieldD, SourceLocation(),
+                                            FieldD->getType(), VK_LValue,
+                                            OK_Ordinary);
+
+  return ME;
+}
+
+Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
+                                    SourceLocation StartLoc,
+                                    SourceLocation EndLoc) {
+  if (!SelGetUidFunctionDecl)
+    SynthSelGetUidFunctionDecl();
+  if (!MsgSendFunctionDecl)
+    SynthMsgSendFunctionDecl();
+  if (!MsgSendSuperFunctionDecl)
+    SynthMsgSendSuperFunctionDecl();
+  if (!MsgSendStretFunctionDecl)
+    SynthMsgSendStretFunctionDecl();
+  if (!MsgSendSuperStretFunctionDecl)
+    SynthMsgSendSuperStretFunctionDecl();
+  if (!MsgSendFpretFunctionDecl)
+    SynthMsgSendFpretFunctionDecl();
+  if (!GetClassFunctionDecl)
+    SynthGetClassFunctionDecl();
+  if (!GetSuperClassFunctionDecl)
+    SynthGetSuperClassFunctionDecl();
+  if (!GetMetaClassFunctionDecl)
+    SynthGetMetaClassFunctionDecl();
+
+  // default to objc_msgSend().
+  FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl;
+  // May need to use objc_msgSend_stret() as well.
+  FunctionDecl *MsgSendStretFlavor = nullptr;
+  if (ObjCMethodDecl *mDecl = Exp->getMethodDecl()) {
+    QualType resultType = mDecl->getReturnType();
+    if (resultType->isRecordType())
+      MsgSendStretFlavor = MsgSendStretFunctionDecl;
+    else if (resultType->isRealFloatingType())
+      MsgSendFlavor = MsgSendFpretFunctionDecl;
+  }
+
+  // Synthesize a call to objc_msgSend().
+  SmallVector<Expr*, 8> MsgExprs;
+  switch (Exp->getReceiverKind()) {
+  case ObjCMessageExpr::SuperClass: {
+    MsgSendFlavor = MsgSendSuperFunctionDecl;
+    if (MsgSendStretFlavor)
+      MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
+    assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
+
+    ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface();
+
+    SmallVector<Expr*, 4> InitExprs;
+
+    // set the receiver to self, the first argument to all methods.
+    InitExprs.push_back(
+      NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+                               CK_BitCast,
+                   new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
+                                             false,
+                                             Context->getObjCIdType(),
+                                             VK_RValue,
+                                             SourceLocation()))
+                        ); // set the 'receiver'.
+
+    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
+    SmallVector<Expr*, 8> ClsExprs;
+    ClsExprs.push_back(getStringLiteral(ClassDecl->getIdentifier()->getName()));
+    // (Class)objc_getClass("CurrentClass")
+    CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
+                                                 &ClsExprs[0],
+                                                 ClsExprs.size(),
+                                                 StartLoc,
+                                                 EndLoc);
+    ClsExprs.clear();
+    ClsExprs.push_back(Cls);
+    Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
+                                       &ClsExprs[0], ClsExprs.size(),
+                                       StartLoc, EndLoc);
+    
+    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
+    // To turn off a warning, type-cast to 'id'
+    InitExprs.push_back( // set 'super class', using class_getSuperclass().
+                        NoTypeInfoCStyleCastExpr(Context,
+                                                 Context->getObjCIdType(),
+                                                 CK_BitCast, Cls));
+    // struct __rw_objc_super
+    QualType superType = getSuperStructType();
+    Expr *SuperRep;
+
+    if (LangOpts.MicrosoftExt) {
+      SynthSuperConstructorFunctionDecl();
+      // Simulate a constructor call...
+      DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperConstructorFunctionDecl,
+                                                   false, superType, VK_LValue,
+                                                   SourceLocation());
+      SuperRep = new (Context) CallExpr(*Context, DRE, InitExprs,
+                                        superType, VK_LValue,
+                                        SourceLocation());
+      // The code for super is a little tricky to prevent collision with
+      // the structure definition in the header. The rewriter has it's own
+      // internal definition (__rw_objc_super) that is uses. This is why
+      // we need the cast below. For example:
+      // (struct __rw_objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
+      //
+      SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf,
+                               Context->getPointerType(SuperRep->getType()),
+                                             VK_RValue, OK_Ordinary,
+                                             SourceLocation());
+      SuperRep = NoTypeInfoCStyleCastExpr(Context,
+                                          Context->getPointerType(superType),
+                                          CK_BitCast, SuperRep);
+    } else {
+      // (struct __rw_objc_super) { <exprs from above> }
+      InitListExpr *ILE =
+        new (Context) InitListExpr(*Context, SourceLocation(), InitExprs,
+                                   SourceLocation());
+      TypeSourceInfo *superTInfo
+        = Context->getTrivialTypeSourceInfo(superType);
+      SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
+                                                   superType, VK_LValue,
+                                                   ILE, false);
+      // struct __rw_objc_super *
+      SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf,
+                               Context->getPointerType(SuperRep->getType()),
+                                             VK_RValue, OK_Ordinary,
+                                             SourceLocation());
+    }
+    MsgExprs.push_back(SuperRep);
+    break;
+  }
+
+  case ObjCMessageExpr::Class: {
+    SmallVector<Expr*, 8> ClsExprs;
+    ObjCInterfaceDecl *Class
+      = Exp->getClassReceiver()->getAs<ObjCObjectType>()->getInterface();
+    IdentifierInfo *clsName = Class->getIdentifier();
+    ClsExprs.push_back(getStringLiteral(clsName->getName()));
+    CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
+                                                 &ClsExprs[0],
+                                                 ClsExprs.size(), 
+                                                 StartLoc, EndLoc);
+    CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
+                                                 Context->getObjCIdType(),
+                                                 CK_BitCast, Cls);
+    MsgExprs.push_back(ArgExpr);
+    break;
+  }
+
+  case ObjCMessageExpr::SuperInstance:{
+    MsgSendFlavor = MsgSendSuperFunctionDecl;
+    if (MsgSendStretFlavor)
+      MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
+    assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
+    ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface();
+    SmallVector<Expr*, 4> InitExprs;
+
+    InitExprs.push_back(
+      NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+                               CK_BitCast,
+                   new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
+                                             false,
+                                             Context->getObjCIdType(),
+                                             VK_RValue, SourceLocation()))
+                        ); // set the 'receiver'.
+    
+    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
+    SmallVector<Expr*, 8> ClsExprs;
+    ClsExprs.push_back(getStringLiteral(ClassDecl->getIdentifier()->getName()));
+    // (Class)objc_getClass("CurrentClass")
+    CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
+                                                 &ClsExprs[0],
+                                                 ClsExprs.size(), 
+                                                 StartLoc, EndLoc);
+    ClsExprs.clear();
+    ClsExprs.push_back(Cls);
+    Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
+                                       &ClsExprs[0], ClsExprs.size(),
+                                       StartLoc, EndLoc);
+    
+    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
+    // To turn off a warning, type-cast to 'id'
+    InitExprs.push_back(
+      // set 'super class', using class_getSuperclass().
+      NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+                               CK_BitCast, Cls));
+    // struct __rw_objc_super
+    QualType superType = getSuperStructType();
+    Expr *SuperRep;
+
+    if (LangOpts.MicrosoftExt) {
+      SynthSuperConstructorFunctionDecl();
+      // Simulate a constructor call...
+      DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperConstructorFunctionDecl,
+                                                   false, superType, VK_LValue,
+                                                   SourceLocation());
+      SuperRep = new (Context) CallExpr(*Context, DRE, InitExprs,
+                                        superType, VK_LValue, SourceLocation());
+      // The code for super is a little tricky to prevent collision with
+      // the structure definition in the header. The rewriter has it's own
+      // internal definition (__rw_objc_super) that is uses. This is why
+      // we need the cast below. For example:
+      // (struct __rw_objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
+      //
+      SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf,
+                               Context->getPointerType(SuperRep->getType()),
+                               VK_RValue, OK_Ordinary,
+                               SourceLocation());
+      SuperRep = NoTypeInfoCStyleCastExpr(Context,
+                               Context->getPointerType(superType),
+                               CK_BitCast, SuperRep);
+    } else {
+      // (struct __rw_objc_super) { <exprs from above> }
+      InitListExpr *ILE =
+        new (Context) InitListExpr(*Context, SourceLocation(), InitExprs,
+                                   SourceLocation());
+      TypeSourceInfo *superTInfo
+        = Context->getTrivialTypeSourceInfo(superType);
+      SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
+                                                   superType, VK_RValue, ILE,
+                                                   false);
+    }
+    MsgExprs.push_back(SuperRep);
+    break;
+  }
+
+  case ObjCMessageExpr::Instance: {
+    // Remove all type-casts because it may contain objc-style types; e.g.
+    // Foo<Proto> *.
+    Expr *recExpr = Exp->getInstanceReceiver();
+    while (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(recExpr))
+      recExpr = CE->getSubExpr();
+    CastKind CK = recExpr->getType()->isObjCObjectPointerType()
+                    ? CK_BitCast : recExpr->getType()->isBlockPointerType()
+                                     ? CK_BlockPointerToObjCPointerCast
+                                     : CK_CPointerToObjCPointerCast;
+
+    recExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+                                       CK, recExpr);
+    MsgExprs.push_back(recExpr);
+    break;
+  }
+  }
+
+  // Create a call to sel_registerName("selName"), it will be the 2nd argument.
+  SmallVector<Expr*, 8> SelExprs;
+  SelExprs.push_back(getStringLiteral(Exp->getSelector().getAsString()));
+  CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
+                                                 &SelExprs[0], SelExprs.size(),
+                                                  StartLoc,
+                                                  EndLoc);
+  MsgExprs.push_back(SelExp);
+
+  // Now push any user supplied arguments.
+  for (unsigned i = 0; i < Exp->getNumArgs(); i++) {
+    Expr *userExpr = Exp->getArg(i);
+    // Make all implicit casts explicit...ICE comes in handy:-)
+    if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(userExpr)) {
+      // Reuse the ICE type, it is exactly what the doctor ordered.
+      QualType type = ICE->getType();
+      if (needToScanForQualifiers(type))
+        type = Context->getObjCIdType();
+      // Make sure we convert "type (^)(...)" to "type (*)(...)".
+      (void)convertBlockPointerToFunctionPointer(type);
+      const Expr *SubExpr = ICE->IgnoreParenImpCasts();
+      CastKind CK;
+      if (SubExpr->getType()->isIntegralType(*Context) && 
+          type->isBooleanType()) {
+        CK = CK_IntegralToBoolean;
+      } else if (type->isObjCObjectPointerType()) {
+        if (SubExpr->getType()->isBlockPointerType()) {
+          CK = CK_BlockPointerToObjCPointerCast;
+        } else if (SubExpr->getType()->isPointerType()) {
+          CK = CK_CPointerToObjCPointerCast;
+        } else {
+          CK = CK_BitCast;
+        }
+      } else {
+        CK = CK_BitCast;
+      }
+
+      userExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, userExpr);
+    }
+    // Make id<P...> cast into an 'id' cast.
+    else if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(userExpr)) {
+      if (CE->getType()->isObjCQualifiedIdType()) {
+        while ((CE = dyn_cast<CStyleCastExpr>(userExpr)))
+          userExpr = CE->getSubExpr();
+        CastKind CK;
+        if (userExpr->getType()->isIntegralType(*Context)) {
+          CK = CK_IntegralToPointer;
+        } else if (userExpr->getType()->isBlockPointerType()) {
+          CK = CK_BlockPointerToObjCPointerCast;
+        } else if (userExpr->getType()->isPointerType()) {
+          CK = CK_CPointerToObjCPointerCast;
+        } else {
+          CK = CK_BitCast;
+        }
+        userExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+                                            CK, userExpr);
+      }
+    }
+    MsgExprs.push_back(userExpr);
+    // We've transferred the ownership to MsgExprs. For now, we *don't* null
+    // out the argument in the original expression (since we aren't deleting
+    // the ObjCMessageExpr). See RewritePropertyOrImplicitSetter() usage for more info.
+    //Exp->setArg(i, 0);
+  }
+  // Generate the funky cast.
+  CastExpr *cast;
+  SmallVector<QualType, 8> ArgTypes;
+  QualType returnType;
+
+  // Push 'id' and 'SEL', the 2 implicit arguments.
+  if (MsgSendFlavor == MsgSendSuperFunctionDecl)
+    ArgTypes.push_back(Context->getPointerType(getSuperStructType()));
+  else
+    ArgTypes.push_back(Context->getObjCIdType());
+  ArgTypes.push_back(Context->getObjCSelType());
+  if (ObjCMethodDecl *OMD = Exp->getMethodDecl()) {
+    // Push any user argument types.
+    for (const auto *PI : OMD->params()) {
+      QualType t = PI->getType()->isObjCQualifiedIdType()
+                     ? Context->getObjCIdType()
+                     : PI->getType();
+      // Make sure we convert "t (^)(...)" to "t (*)(...)".
+      (void)convertBlockPointerToFunctionPointer(t);
+      ArgTypes.push_back(t);
+    }
+    returnType = Exp->getType();
+    convertToUnqualifiedObjCType(returnType);
+    (void)convertBlockPointerToFunctionPointer(returnType);
+  } else {
+    returnType = Context->getObjCIdType();
+  }
+  // Get the type, we will need to reference it in a couple spots.
+  QualType msgSendType = MsgSendFlavor->getType();
+
+  // Create a reference to the objc_msgSend() declaration.
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType,
+                                               VK_LValue, SourceLocation());
+
+  // Need to cast objc_msgSend to "void *" (to workaround a GCC bandaid).
+  // If we don't do this cast, we get the following bizarre warning/note:
+  // xx.m:13: warning: function called through a non-compatible type
+  // xx.m:13: note: if this code is reached, the program will abort
+  cast = NoTypeInfoCStyleCastExpr(Context,
+                                  Context->getPointerType(Context->VoidTy),
+                                  CK_BitCast, DRE);
+
+  // Now do the "normal" pointer to function cast.
+  // If we don't have a method decl, force a variadic cast.
+  const ObjCMethodDecl *MD = Exp->getMethodDecl();
+  QualType castType =
+    getSimpleFunctionType(returnType, ArgTypes, MD ? MD->isVariadic() : true);
+  castType = Context->getPointerType(castType);
+  cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
+                                  cast);
+
+  // Don't forget the parens to enforce the proper binding.
+  ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
+
+  const FunctionType *FT = msgSendType->getAs<FunctionType>();
+  CallExpr *CE = new (Context)
+      CallExpr(*Context, PE, MsgExprs, FT->getReturnType(), VK_RValue, EndLoc);
+  Stmt *ReplacingStmt = CE;
+  if (MsgSendStretFlavor) {
+    // We have the method which returns a struct/union. Must also generate
+    // call to objc_msgSend_stret and hang both varieties on a conditional
+    // expression which dictate which one to envoke depending on size of
+    // method's return type.
+
+    Expr *STCE = SynthMsgSendStretCallExpr(MsgSendStretFlavor,
+                                           returnType,
+                                           ArgTypes, MsgExprs,
+                                           Exp->getMethodDecl());
+    ReplacingStmt = STCE;
+  }
+  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
+  return ReplacingStmt;
+}
+
+Stmt *RewriteModernObjC::RewriteMessageExpr(ObjCMessageExpr *Exp) {
+  Stmt *ReplacingStmt = SynthMessageExpr(Exp, Exp->getLocStart(),
+                                         Exp->getLocEnd());
+
+  // Now do the actual rewrite.
+  ReplaceStmt(Exp, ReplacingStmt);
+
+  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
+  return ReplacingStmt;
+}
+
+// typedef struct objc_object Protocol;
+QualType RewriteModernObjC::getProtocolType() {
+  if (!ProtocolTypeDecl) {
+    TypeSourceInfo *TInfo
+      = Context->getTrivialTypeSourceInfo(Context->getObjCIdType());
+    ProtocolTypeDecl = TypedefDecl::Create(*Context, TUDecl,
+                                           SourceLocation(), SourceLocation(),
+                                           &Context->Idents.get("Protocol"),
+                                           TInfo);
+  }
+  return Context->getTypeDeclType(ProtocolTypeDecl);
+}
+
+/// RewriteObjCProtocolExpr - Rewrite a protocol expression into
+/// a synthesized/forward data reference (to the protocol's metadata).
+/// The forward references (and metadata) are generated in
+/// RewriteModernObjC::HandleTranslationUnit().
+Stmt *RewriteModernObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) {
+  std::string Name = "_OBJC_PROTOCOL_REFERENCE_$_" + 
+                      Exp->getProtocol()->getNameAsString();
+  IdentifierInfo *ID = &Context->Idents.get(Name);
+  VarDecl *VD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
+                                SourceLocation(), ID, getProtocolType(),
+                                nullptr, SC_Extern);
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, false, getProtocolType(),
+                                               VK_LValue, SourceLocation());
+  CastExpr *castExpr =
+    NoTypeInfoCStyleCastExpr(
+      Context, Context->getPointerType(DRE->getType()), CK_BitCast, DRE);
+  ReplaceStmt(Exp, castExpr);
+  ProtocolExprDecls.insert(Exp->getProtocol()->getCanonicalDecl());
+  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
+  return castExpr;
+
+}
+
+bool RewriteModernObjC::BufferContainsPPDirectives(const char *startBuf,
+                                             const char *endBuf) {
+  while (startBuf < endBuf) {
+    if (*startBuf == '#') {
+      // Skip whitespace.
+      for (++startBuf; startBuf[0] == ' ' || startBuf[0] == '\t'; ++startBuf)
+        ;
+      if (!strncmp(startBuf, "if", strlen("if")) ||
+          !strncmp(startBuf, "ifdef", strlen("ifdef")) ||
+          !strncmp(startBuf, "ifndef", strlen("ifndef")) ||
+          !strncmp(startBuf, "define", strlen("define")) ||
+          !strncmp(startBuf, "undef", strlen("undef")) ||
+          !strncmp(startBuf, "else", strlen("else")) ||
+          !strncmp(startBuf, "elif", strlen("elif")) ||
+          !strncmp(startBuf, "endif", strlen("endif")) ||
+          !strncmp(startBuf, "pragma", strlen("pragma")) ||
+          !strncmp(startBuf, "include", strlen("include")) ||
+          !strncmp(startBuf, "import", strlen("import")) ||
+          !strncmp(startBuf, "include_next", strlen("include_next")))
+        return true;
+    }
+    startBuf++;
+  }
+  return false;
+}
+
+/// IsTagDefinedInsideClass - This routine checks that a named tagged type 
+/// is defined inside an objective-c class. If so, it returns true. 
+bool RewriteModernObjC::IsTagDefinedInsideClass(ObjCContainerDecl *IDecl, 
+                                                TagDecl *Tag,
+                                                bool &IsNamedDefinition) {
+  if (!IDecl)
+    return false;
+  SourceLocation TagLocation;
+  if (RecordDecl *RD = dyn_cast<RecordDecl>(Tag)) {
+    RD = RD->getDefinition();
+    if (!RD || !RD->getDeclName().getAsIdentifierInfo())
+      return false;
+    IsNamedDefinition = true;
+    TagLocation = RD->getLocation();
+    return Context->getSourceManager().isBeforeInTranslationUnit(
+                                          IDecl->getLocation(), TagLocation);
+  }
+  if (EnumDecl *ED = dyn_cast<EnumDecl>(Tag)) {
+    if (!ED || !ED->getDeclName().getAsIdentifierInfo())
+      return false;
+    IsNamedDefinition = true;
+    TagLocation = ED->getLocation();
+    return Context->getSourceManager().isBeforeInTranslationUnit(
+                                          IDecl->getLocation(), TagLocation);
+
+  }
+  return false;
+}
+
+/// RewriteObjCFieldDeclType - This routine rewrites a type into the buffer.
+/// It handles elaborated types, as well as enum types in the process.
+bool RewriteModernObjC::RewriteObjCFieldDeclType(QualType &Type, 
+                                                 std::string &Result) {
+  if (isa<TypedefType>(Type)) {
+    Result += "\t";
+    return false;
+  }
+    
+  if (Type->isArrayType()) {
+    QualType ElemTy = Context->getBaseElementType(Type);
+    return RewriteObjCFieldDeclType(ElemTy, Result);
+  }
+  else if (Type->isRecordType()) {
+    RecordDecl *RD = Type->getAs<RecordType>()->getDecl();
+    if (RD->isCompleteDefinition()) {
+      if (RD->isStruct())
+        Result += "\n\tstruct ";
+      else if (RD->isUnion())
+        Result += "\n\tunion ";
+      else
+        assert(false && "class not allowed as an ivar type");
+      
+      Result += RD->getName();
+      if (GlobalDefinedTags.count(RD)) {
+        // struct/union is defined globally, use it.
+        Result += " ";
+        return true;
+      }
+      Result += " {\n";
+      for (auto *FD : RD->fields())
+        RewriteObjCFieldDecl(FD, Result);
+      Result += "\t} "; 
+      return true;
+    }
+  }
+  else if (Type->isEnumeralType()) {
+    EnumDecl *ED = Type->getAs<EnumType>()->getDecl();
+    if (ED->isCompleteDefinition()) {
+      Result += "\n\tenum ";
+      Result += ED->getName();
+      if (GlobalDefinedTags.count(ED)) {
+        // Enum is globall defined, use it.
+        Result += " ";
+        return true;
+      }
+      
+      Result += " {\n";
+      for (const auto *EC : ED->enumerators()) {
+        Result += "\t"; Result += EC->getName(); Result += " = ";
+        llvm::APSInt Val = EC->getInitVal();
+        Result += Val.toString(10);
+        Result += ",\n";
+      }
+      Result += "\t} "; 
+      return true;
+    }
+  }
+  
+  Result += "\t";
+  convertObjCTypeToCStyleType(Type);
+  return false;
+}
+
+
+/// RewriteObjCFieldDecl - This routine rewrites a field into the buffer.
+/// It handles elaborated types, as well as enum types in the process.
+void RewriteModernObjC::RewriteObjCFieldDecl(FieldDecl *fieldDecl, 
+                                             std::string &Result) {
+  QualType Type = fieldDecl->getType();
+  std::string Name = fieldDecl->getNameAsString();
+  
+  bool EleboratedType = RewriteObjCFieldDeclType(Type, Result); 
+  if (!EleboratedType)
+    Type.getAsStringInternal(Name, Context->getPrintingPolicy());
+  Result += Name;
+  if (fieldDecl->isBitField()) {
+    Result += " : "; Result += utostr(fieldDecl->getBitWidthValue(*Context));
+  }
+  else if (EleboratedType && Type->isArrayType()) {
+    const ArrayType *AT = Context->getAsArrayType(Type);
+    do {
+      if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT)) {
+        Result += "[";
+        llvm::APInt Dim = CAT->getSize();
+        Result += utostr(Dim.getZExtValue());
+        Result += "]";
+      }
+      AT = Context->getAsArrayType(AT->getElementType());
+    } while (AT);
+  }
+  
+  Result += ";\n";
+}
+
+/// RewriteLocallyDefinedNamedAggregates - This routine rewrites locally defined
+/// named aggregate types into the input buffer.
+void RewriteModernObjC::RewriteLocallyDefinedNamedAggregates(FieldDecl *fieldDecl, 
+                                             std::string &Result) {
+  QualType Type = fieldDecl->getType();
+  if (isa<TypedefType>(Type))
+    return;
+  if (Type->isArrayType())
+    Type = Context->getBaseElementType(Type);
+  ObjCContainerDecl *IDecl = 
+    dyn_cast<ObjCContainerDecl>(fieldDecl->getDeclContext());
+
+  TagDecl *TD = nullptr;
+  if (Type->isRecordType()) {
+    TD = Type->getAs<RecordType>()->getDecl();
+  }
+  else if (Type->isEnumeralType()) {
+    TD = Type->getAs<EnumType>()->getDecl();
+  }
+  
+  if (TD) {
+    if (GlobalDefinedTags.count(TD))
+      return;
+    
+    bool IsNamedDefinition = false;
+    if (IsTagDefinedInsideClass(IDecl, TD, IsNamedDefinition)) {
+      RewriteObjCFieldDeclType(Type, Result);
+      Result += ";";
+    }
+    if (IsNamedDefinition)
+      GlobalDefinedTags.insert(TD);
+  }
+    
+}
+
+unsigned RewriteModernObjC::ObjCIvarBitfieldGroupNo(ObjCIvarDecl *IV) {
+  const ObjCInterfaceDecl *CDecl = IV->getContainingInterface();
+  if (ObjCInterefaceHasBitfieldGroups.count(CDecl)) {
+    return IvarGroupNumber[IV];
+  }
+  unsigned GroupNo = 0;
+  SmallVector<const ObjCIvarDecl *, 8> IVars;
+  for (const ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin();
+       IVD; IVD = IVD->getNextIvar())
+    IVars.push_back(IVD);
+  
+  for (unsigned i = 0, e = IVars.size(); i < e; i++)
+    if (IVars[i]->isBitField()) {
+      IvarGroupNumber[IVars[i++]] = ++GroupNo;
+      while (i < e && IVars[i]->isBitField())
+        IvarGroupNumber[IVars[i++]] = GroupNo;
+      if (i < e)
+        --i;
+    }
+
+  ObjCInterefaceHasBitfieldGroups.insert(CDecl);
+  return IvarGroupNumber[IV];
+}
+
+QualType RewriteModernObjC::SynthesizeBitfieldGroupStructType(
+                              ObjCIvarDecl *IV,
+                              SmallVectorImpl<ObjCIvarDecl *> &IVars) {
+  std::string StructTagName;
+  ObjCIvarBitfieldGroupType(IV, StructTagName);
+  RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct,
+                                      Context->getTranslationUnitDecl(),
+                                      SourceLocation(), SourceLocation(),
+                                      &Context->Idents.get(StructTagName));
+  for (unsigned i=0, e = IVars.size(); i < e; i++) {
+    ObjCIvarDecl *Ivar = IVars[i];
+    RD->addDecl(FieldDecl::Create(*Context, RD, SourceLocation(), SourceLocation(),
+                                  &Context->Idents.get(Ivar->getName()),
+                                  Ivar->getType(),
+                                  nullptr, /*Expr *BW */Ivar->getBitWidth(),
+                                  false, ICIS_NoInit));
+  }
+  RD->completeDefinition();
+  return Context->getTagDeclType(RD);
+}
+
+QualType RewriteModernObjC::GetGroupRecordTypeForObjCIvarBitfield(ObjCIvarDecl *IV) {
+  const ObjCInterfaceDecl *CDecl = IV->getContainingInterface();
+  unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
+  std::pair<const ObjCInterfaceDecl*, unsigned> tuple = std::make_pair(CDecl, GroupNo);
+  if (GroupRecordType.count(tuple))
+    return GroupRecordType[tuple];
+  
+  SmallVector<ObjCIvarDecl *, 8> IVars;
+  for (const ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin();
+       IVD; IVD = IVD->getNextIvar()) {
+    if (IVD->isBitField())
+      IVars.push_back(const_cast<ObjCIvarDecl *>(IVD));
+    else {
+      if (!IVars.empty()) {
+        unsigned GroupNo = ObjCIvarBitfieldGroupNo(IVars[0]);
+        // Generate the struct type for this group of bitfield ivars.
+        GroupRecordType[std::make_pair(CDecl, GroupNo)] =
+          SynthesizeBitfieldGroupStructType(IVars[0], IVars);
+        IVars.clear();
+      }
+    }
+  }
+  if (!IVars.empty()) {
+    // Do the last one.
+    unsigned GroupNo = ObjCIvarBitfieldGroupNo(IVars[0]);
+    GroupRecordType[std::make_pair(CDecl, GroupNo)] =
+      SynthesizeBitfieldGroupStructType(IVars[0], IVars);
+  }
+  QualType RetQT = GroupRecordType[tuple];
+  assert(!RetQT.isNull() && "GetGroupRecordTypeForObjCIvarBitfield struct type is NULL");
+  
+  return RetQT;
+}
+
+/// ObjCIvarBitfieldGroupDecl - Names field decl. for ivar bitfield group.
+/// Name would be: classname__GRBF_n where n is the group number for this ivar.
+void RewriteModernObjC::ObjCIvarBitfieldGroupDecl(ObjCIvarDecl *IV,
+                                                  std::string &Result) {
+  const ObjCInterfaceDecl *CDecl = IV->getContainingInterface();
+  Result += CDecl->getName();
+  Result += "__GRBF_";
+  unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
+  Result += utostr(GroupNo);
+  return;
+}
+
+/// ObjCIvarBitfieldGroupType - Names struct type for ivar bitfield group.
+/// Name of the struct would be: classname__T_n where n is the group number for
+/// this ivar.
+void RewriteModernObjC::ObjCIvarBitfieldGroupType(ObjCIvarDecl *IV,
+                                                  std::string &Result) {
+  const ObjCInterfaceDecl *CDecl = IV->getContainingInterface();
+  Result += CDecl->getName();
+  Result += "__T_";
+  unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
+  Result += utostr(GroupNo);
+  return;
+}
+
+/// ObjCIvarBitfieldGroupOffset - Names symbol for ivar bitfield group field offset.
+/// Name would be: OBJC_IVAR_$_classname__GRBF_n where n is the group number for
+/// this ivar.
+void RewriteModernObjC::ObjCIvarBitfieldGroupOffset(ObjCIvarDecl *IV,
+                                                    std::string &Result) {
+  Result += "OBJC_IVAR_$_";
+  ObjCIvarBitfieldGroupDecl(IV, Result);
+}
+
+#define SKIP_BITFIELDS(IX, ENDIX, VEC) { \
+      while ((IX < ENDIX) && VEC[IX]->isBitField()) \
+        ++IX; \
+      if (IX < ENDIX) \
+        --IX; \
+}
+
+/// RewriteObjCInternalStruct - Rewrite one internal struct corresponding to
+/// an objective-c class with ivars.
+void RewriteModernObjC::RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl,
+                                               std::string &Result) {
+  assert(CDecl && "Class missing in SynthesizeObjCInternalStruct");
+  assert(CDecl->getName() != "" &&
+         "Name missing in SynthesizeObjCInternalStruct");
+  ObjCInterfaceDecl *RCDecl = CDecl->getSuperClass();
+  SmallVector<ObjCIvarDecl *, 8> IVars;
+  for (ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin();
+       IVD; IVD = IVD->getNextIvar())
+    IVars.push_back(IVD);
+  
+  SourceLocation LocStart = CDecl->getLocStart();
+  SourceLocation LocEnd = CDecl->getEndOfDefinitionLoc();
+  
+  const char *startBuf = SM->getCharacterData(LocStart);
+  const char *endBuf = SM->getCharacterData(LocEnd);
+  
+  // If no ivars and no root or if its root, directly or indirectly,
+  // have no ivars (thus not synthesized) then no need to synthesize this class.
+  if ((!CDecl->isThisDeclarationADefinition() || IVars.size() == 0) &&
+      (!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) {
+    endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts);
+    ReplaceText(LocStart, endBuf-startBuf, Result);
+    return;
+  }
+  
+  // Insert named struct/union definitions inside class to
+  // outer scope. This follows semantics of locally defined
+  // struct/unions in objective-c classes.
+  for (unsigned i = 0, e = IVars.size(); i < e; i++)
+    RewriteLocallyDefinedNamedAggregates(IVars[i], Result);
+  
+  // Insert named structs which are syntheized to group ivar bitfields
+  // to outer scope as well.
+  for (unsigned i = 0, e = IVars.size(); i < e; i++)
+    if (IVars[i]->isBitField()) {
+      ObjCIvarDecl *IV = IVars[i];
+      QualType QT = GetGroupRecordTypeForObjCIvarBitfield(IV);
+      RewriteObjCFieldDeclType(QT, Result);
+      Result += ";";
+      // skip over ivar bitfields in this group.
+      SKIP_BITFIELDS(i , e, IVars);
+    }
+    
+  Result += "\nstruct ";
+  Result += CDecl->getNameAsString();
+  Result += "_IMPL {\n";
+  
+  if (RCDecl && ObjCSynthesizedStructs.count(RCDecl)) {
+    Result += "\tstruct "; Result += RCDecl->getNameAsString();
+    Result += "_IMPL "; Result += RCDecl->getNameAsString();
+    Result += "_IVARS;\n";
+  }
+  
+  for (unsigned i = 0, e = IVars.size(); i < e; i++) {
+    if (IVars[i]->isBitField()) {
+      ObjCIvarDecl *IV = IVars[i];
+      Result += "\tstruct ";
+      ObjCIvarBitfieldGroupType(IV, Result); Result += " ";
+      ObjCIvarBitfieldGroupDecl(IV, Result); Result += ";\n";
+      // skip over ivar bitfields in this group.
+      SKIP_BITFIELDS(i , e, IVars);
+    }
+    else
+      RewriteObjCFieldDecl(IVars[i], Result);
+  }
+
+  Result += "};\n";
+  endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts);
+  ReplaceText(LocStart, endBuf-startBuf, Result);
+  // Mark this struct as having been generated.
+  if (!ObjCSynthesizedStructs.insert(CDecl))
+    llvm_unreachable("struct already synthesize- RewriteObjCInternalStruct");
+}
+
+/// RewriteIvarOffsetSymbols - Rewrite ivar offset symbols of those ivars which
+/// have been referenced in an ivar access expression.
+void RewriteModernObjC::RewriteIvarOffsetSymbols(ObjCInterfaceDecl *CDecl,
+                                                  std::string &Result) {
+  // write out ivar offset symbols which have been referenced in an ivar
+  // access expression.
+  llvm::SmallPtrSet<ObjCIvarDecl *, 8> Ivars = ReferencedIvars[CDecl];
+  if (Ivars.empty())
+    return;
+  
+  llvm::DenseSet<std::pair<const ObjCInterfaceDecl*, unsigned> > GroupSymbolOutput;
+  for (llvm::SmallPtrSet<ObjCIvarDecl *, 8>::iterator i = Ivars.begin(),
+       e = Ivars.end(); i != e; i++) {
+    ObjCIvarDecl *IvarDecl = (*i);
+    const ObjCInterfaceDecl *IDecl = IvarDecl->getContainingInterface();
+    unsigned GroupNo = 0;
+    if (IvarDecl->isBitField()) {
+      GroupNo = ObjCIvarBitfieldGroupNo(IvarDecl);
+      if (GroupSymbolOutput.count(std::make_pair(IDecl, GroupNo)))
+        continue;
+    }
+    Result += "\n";
+    if (LangOpts.MicrosoftExt)
+      Result += "__declspec(allocate(\".objc_ivar$B\")) ";
+    Result += "extern \"C\" ";
+    if (LangOpts.MicrosoftExt && 
+        IvarDecl->getAccessControl() != ObjCIvarDecl::Private &&
+        IvarDecl->getAccessControl() != ObjCIvarDecl::Package)
+        Result += "__declspec(dllimport) ";
+
+    Result += "unsigned long ";
+    if (IvarDecl->isBitField()) {
+      ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
+      GroupSymbolOutput.insert(std::make_pair(IDecl, GroupNo));
+    }
+    else
+      WriteInternalIvarName(CDecl, IvarDecl, Result);
+    Result += ";";
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Meta Data Emission
+//===----------------------------------------------------------------------===//
+
+
+/// RewriteImplementations - This routine rewrites all method implementations
+/// and emits meta-data.
+
+void RewriteModernObjC::RewriteImplementations() {
+  int ClsDefCount = ClassImplementation.size();
+  int CatDefCount = CategoryImplementation.size();
+
+  // Rewrite implemented methods
+  for (int i = 0; i < ClsDefCount; i++) {
+    ObjCImplementationDecl *OIMP = ClassImplementation[i];
+    ObjCInterfaceDecl *CDecl = OIMP->getClassInterface();
+    if (CDecl->isImplicitInterfaceDecl())
+      assert(false &&
+             "Legacy implicit interface rewriting not supported in moder abi");
+    RewriteImplementationDecl(OIMP);
+  }
+
+  for (int i = 0; i < CatDefCount; i++) {
+    ObjCCategoryImplDecl *CIMP = CategoryImplementation[i];
+    ObjCInterfaceDecl *CDecl = CIMP->getClassInterface();
+    if (CDecl->isImplicitInterfaceDecl())
+      assert(false &&
+             "Legacy implicit interface rewriting not supported in moder abi");
+    RewriteImplementationDecl(CIMP);
+  }
+}
+
+void RewriteModernObjC::RewriteByRefString(std::string &ResultStr, 
+                                     const std::string &Name,
+                                     ValueDecl *VD, bool def) {
+  assert(BlockByRefDeclNo.count(VD) && 
+         "RewriteByRefString: ByRef decl missing");
+  if (def)
+    ResultStr += "struct ";
+  ResultStr += "__Block_byref_" + Name + 
+    "_" + utostr(BlockByRefDeclNo[VD]) ;
+}
+
+static bool HasLocalVariableExternalStorage(ValueDecl *VD) {
+  if (VarDecl *Var = dyn_cast<VarDecl>(VD))
+    return (Var->isFunctionOrMethodVarDecl() && !Var->hasLocalStorage());
+  return false;
+}
+
+std::string RewriteModernObjC::SynthesizeBlockFunc(BlockExpr *CE, int i,
+                                                   StringRef funcName,
+                                                   std::string Tag) {
+  const FunctionType *AFT = CE->getFunctionType();
+  QualType RT = AFT->getReturnType();
+  std::string StructRef = "struct " + Tag;
+  SourceLocation BlockLoc = CE->getExprLoc();
+  std::string S;
+  ConvertSourceLocationToLineDirective(BlockLoc, S);
+  
+  S += "static " + RT.getAsString(Context->getPrintingPolicy()) + " __" +
+         funcName.str() + "_block_func_" + utostr(i);
+
+  BlockDecl *BD = CE->getBlockDecl();
+
+  if (isa<FunctionNoProtoType>(AFT)) {
+    // No user-supplied arguments. Still need to pass in a pointer to the
+    // block (to reference imported block decl refs).
+    S += "(" + StructRef + " *__cself)";
+  } else if (BD->param_empty()) {
+    S += "(" + StructRef + " *__cself)";
+  } else {
+    const FunctionProtoType *FT = cast<FunctionProtoType>(AFT);
+    assert(FT && "SynthesizeBlockFunc: No function proto");
+    S += '(';
+    // first add the implicit argument.
+    S += StructRef + " *__cself, ";
+    std::string ParamStr;
+    for (BlockDecl::param_iterator AI = BD->param_begin(),
+         E = BD->param_end(); AI != E; ++AI) {
+      if (AI != BD->param_begin()) S += ", ";
+      ParamStr = (*AI)->getNameAsString();
+      QualType QT = (*AI)->getType();
+      (void)convertBlockPointerToFunctionPointer(QT);
+      QT.getAsStringInternal(ParamStr, Context->getPrintingPolicy());
+      S += ParamStr;
+    }
+    if (FT->isVariadic()) {
+      if (!BD->param_empty()) S += ", ";
+      S += "...";
+    }
+    S += ')';
+  }
+  S += " {\n";
+
+  // Create local declarations to avoid rewriting all closure decl ref exprs.
+  // First, emit a declaration for all "by ref" decls.
+  for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(),
+       E = BlockByRefDecls.end(); I != E; ++I) {
+    S += "  ";
+    std::string Name = (*I)->getNameAsString();
+    std::string TypeString;
+    RewriteByRefString(TypeString, Name, (*I));
+    TypeString += " *";
+    Name = TypeString + Name;
+    S += Name + " = __cself->" + (*I)->getNameAsString() + "; // bound by ref\n";
+  }
+  // Next, emit a declaration for all "by copy" declarations.
+  for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(),
+       E = BlockByCopyDecls.end(); I != E; ++I) {
+    S += "  ";
+    // Handle nested closure invocation. For example:
+    //
+    //   void (^myImportedClosure)(void);
+    //   myImportedClosure  = ^(void) { setGlobalInt(x + y); };
+    //
+    //   void (^anotherClosure)(void);
+    //   anotherClosure = ^(void) {
+    //     myImportedClosure(); // import and invoke the closure
+    //   };
+    //
+    if (isTopLevelBlockPointerType((*I)->getType())) {
+      RewriteBlockPointerTypeVariable(S, (*I));
+      S += " = (";
+      RewriteBlockPointerType(S, (*I)->getType());
+      S += ")";
+      S += "__cself->" + (*I)->getNameAsString() + "; // bound by copy\n";
+    }
+    else {
+      std::string Name = (*I)->getNameAsString();
+      QualType QT = (*I)->getType();
+      if (HasLocalVariableExternalStorage(*I))
+        QT = Context->getPointerType(QT);
+      QT.getAsStringInternal(Name, Context->getPrintingPolicy());
+      S += Name + " = __cself->" + 
+                              (*I)->getNameAsString() + "; // bound by copy\n";
+    }
+  }
+  std::string RewrittenStr = RewrittenBlockExprs[CE];
+  const char *cstr = RewrittenStr.c_str();
+  while (*cstr++ != '{') ;
+  S += cstr;
+  S += "\n";
+  return S;
+}
+
+std::string RewriteModernObjC::SynthesizeBlockHelperFuncs(BlockExpr *CE, int i,
+                                                   StringRef funcName,
+                                                   std::string Tag) {
+  std::string StructRef = "struct " + Tag;
+  std::string S = "static void __";
+
+  S += funcName;
+  S += "_block_copy_" + utostr(i);
+  S += "(" + StructRef;
+  S += "*dst, " + StructRef;
+  S += "*src) {";
+  for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = ImportedBlockDecls.begin(),
+      E = ImportedBlockDecls.end(); I != E; ++I) {
+    ValueDecl *VD = (*I);
+    S += "_Block_object_assign((void*)&dst->";
+    S += (*I)->getNameAsString();
+    S += ", (void*)src->";
+    S += (*I)->getNameAsString();
+    if (BlockByRefDeclsPtrSet.count((*I)))
+      S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);";
+    else if (VD->getType()->isBlockPointerType())
+      S += ", " + utostr(BLOCK_FIELD_IS_BLOCK) + "/*BLOCK_FIELD_IS_BLOCK*/);";
+    else
+      S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);";
+  }
+  S += "}\n";
+  
+  S += "\nstatic void __";
+  S += funcName;
+  S += "_block_dispose_" + utostr(i);
+  S += "(" + StructRef;
+  S += "*src) {";
+  for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = ImportedBlockDecls.begin(),
+      E = ImportedBlockDecls.end(); I != E; ++I) {
+    ValueDecl *VD = (*I);
+    S += "_Block_object_dispose((void*)src->";
+    S += (*I)->getNameAsString();
+    if (BlockByRefDeclsPtrSet.count((*I)))
+      S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);";
+    else if (VD->getType()->isBlockPointerType())
+      S += ", " + utostr(BLOCK_FIELD_IS_BLOCK) + "/*BLOCK_FIELD_IS_BLOCK*/);";
+    else
+      S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);";
+  }
+  S += "}\n";
+  return S;
+}
+
+std::string RewriteModernObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag, 
+                                             std::string Desc) {
+  std::string S = "\nstruct " + Tag;
+  std::string Constructor = "  " + Tag;
+
+  S += " {\n  struct __block_impl impl;\n";
+  S += "  struct " + Desc;
+  S += "* Desc;\n";
+
+  Constructor += "(void *fp, "; // Invoke function pointer.
+  Constructor += "struct " + Desc; // Descriptor pointer.
+  Constructor += " *desc";
+
+  if (BlockDeclRefs.size()) {
+    // Output all "by copy" declarations.
+    for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(),
+         E = BlockByCopyDecls.end(); I != E; ++I) {
+      S += "  ";
+      std::string FieldName = (*I)->getNameAsString();
+      std::string ArgName = "_" + FieldName;
+      // Handle nested closure invocation. For example:
+      //
+      //   void (^myImportedBlock)(void);
+      //   myImportedBlock  = ^(void) { setGlobalInt(x + y); };
+      //
+      //   void (^anotherBlock)(void);
+      //   anotherBlock = ^(void) {
+      //     myImportedBlock(); // import and invoke the closure
+      //   };
+      //
+      if (isTopLevelBlockPointerType((*I)->getType())) {
+        S += "struct __block_impl *";
+        Constructor += ", void *" + ArgName;
+      } else {
+        QualType QT = (*I)->getType();
+        if (HasLocalVariableExternalStorage(*I))
+          QT = Context->getPointerType(QT);
+        QT.getAsStringInternal(FieldName, Context->getPrintingPolicy());
+        QT.getAsStringInternal(ArgName, Context->getPrintingPolicy());
+        Constructor += ", " + ArgName;
+      }
+      S += FieldName + ";\n";
+    }
+    // Output all "by ref" declarations.
+    for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(),
+         E = BlockByRefDecls.end(); I != E; ++I) {
+      S += "  ";
+      std::string FieldName = (*I)->getNameAsString();
+      std::string ArgName = "_" + FieldName;
+      {
+        std::string TypeString;
+        RewriteByRefString(TypeString, FieldName, (*I));
+        TypeString += " *";
+        FieldName = TypeString + FieldName;
+        ArgName = TypeString + ArgName;
+        Constructor += ", " + ArgName;
+      }
+      S += FieldName + "; // by ref\n";
+    }
+    // Finish writing the constructor.
+    Constructor += ", int flags=0)";
+    // Initialize all "by copy" arguments.
+    bool firsTime = true;
+    for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(),
+         E = BlockByCopyDecls.end(); I != E; ++I) {
+      std::string Name = (*I)->getNameAsString();
+        if (firsTime) {
+          Constructor += " : ";
+          firsTime = false;
+        }
+        else
+          Constructor += ", ";
+        if (isTopLevelBlockPointerType((*I)->getType()))
+          Constructor += Name + "((struct __block_impl *)_" + Name + ")";
+        else
+          Constructor += Name + "(_" + Name + ")";
+    }
+    // Initialize all "by ref" arguments.
+    for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(),
+         E = BlockByRefDecls.end(); I != E; ++I) {
+      std::string Name = (*I)->getNameAsString();
+      if (firsTime) {
+        Constructor += " : ";
+        firsTime = false;
+      }
+      else
+        Constructor += ", ";
+      Constructor += Name + "(_" + Name + "->__forwarding)";
+    }
+    
+    Constructor += " {\n";
+    if (GlobalVarDecl)
+      Constructor += "    impl.isa = &_NSConcreteGlobalBlock;\n";
+    else
+      Constructor += "    impl.isa = &_NSConcreteStackBlock;\n";
+    Constructor += "    impl.Flags = flags;\n    impl.FuncPtr = fp;\n";
+
+    Constructor += "    Desc = desc;\n";
+  } else {
+    // Finish writing the constructor.
+    Constructor += ", int flags=0) {\n";
+    if (GlobalVarDecl)
+      Constructor += "    impl.isa = &_NSConcreteGlobalBlock;\n";
+    else
+      Constructor += "    impl.isa = &_NSConcreteStackBlock;\n";
+    Constructor += "    impl.Flags = flags;\n    impl.FuncPtr = fp;\n";
+    Constructor += "    Desc = desc;\n";
+  }
+  Constructor += "  ";
+  Constructor += "}\n";
+  S += Constructor;
+  S += "};\n";
+  return S;
+}
+
+std::string RewriteModernObjC::SynthesizeBlockDescriptor(std::string DescTag, 
+                                                   std::string ImplTag, int i,
+                                                   StringRef FunName,
+                                                   unsigned hasCopy) {
+  std::string S = "\nstatic struct " + DescTag;
+  
+  S += " {\n  size_t reserved;\n";
+  S += "  size_t Block_size;\n";
+  if (hasCopy) {
+    S += "  void (*copy)(struct ";
+    S += ImplTag; S += "*, struct ";
+    S += ImplTag; S += "*);\n";
+    
+    S += "  void (*dispose)(struct ";
+    S += ImplTag; S += "*);\n";
+  }
+  S += "} ";
+
+  S += DescTag + "_DATA = { 0, sizeof(struct ";
+  S += ImplTag + ")";
+  if (hasCopy) {
+    S += ", __" + FunName.str() + "_block_copy_" + utostr(i);
+    S += ", __" + FunName.str() + "_block_dispose_" + utostr(i);
+  }
+  S += "};\n";
+  return S;
+}
+
+void RewriteModernObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart,
+                                          StringRef FunName) {
+  bool RewriteSC = (GlobalVarDecl &&
+                    !Blocks.empty() &&
+                    GlobalVarDecl->getStorageClass() == SC_Static &&
+                    GlobalVarDecl->getType().getCVRQualifiers());
+  if (RewriteSC) {
+    std::string SC(" void __");
+    SC += GlobalVarDecl->getNameAsString();
+    SC += "() {}";
+    InsertText(FunLocStart, SC);
+  }
+  
+  // Insert closures that were part of the function.
+  for (unsigned i = 0, count=0; i < Blocks.size(); i++) {
+    CollectBlockDeclRefInfo(Blocks[i]);
+    // Need to copy-in the inner copied-in variables not actually used in this
+    // block.
+    for (int j = 0; j < InnerDeclRefsCount[i]; j++) {
+      DeclRefExpr *Exp = InnerDeclRefs[count++];
+      ValueDecl *VD = Exp->getDecl();
+      BlockDeclRefs.push_back(Exp);
+      if (!VD->hasAttr<BlocksAttr>()) {
+        if (!BlockByCopyDeclsPtrSet.count(VD)) {
+          BlockByCopyDeclsPtrSet.insert(VD);
+          BlockByCopyDecls.push_back(VD);
+        }
+        continue;
+      }
+
+      if (!BlockByRefDeclsPtrSet.count(VD)) {
+        BlockByRefDeclsPtrSet.insert(VD);
+        BlockByRefDecls.push_back(VD);
+      }
+
+      // imported objects in the inner blocks not used in the outer
+      // blocks must be copied/disposed in the outer block as well.
+      if (VD->getType()->isObjCObjectPointerType() || 
+          VD->getType()->isBlockPointerType())
+        ImportedBlockDecls.insert(VD);
+    }
+
+    std::string ImplTag = "__" + FunName.str() + "_block_impl_" + utostr(i);
+    std::string DescTag = "__" + FunName.str() + "_block_desc_" + utostr(i);
+
+    std::string CI = SynthesizeBlockImpl(Blocks[i], ImplTag, DescTag);
+
+    InsertText(FunLocStart, CI);
+
+    std::string CF = SynthesizeBlockFunc(Blocks[i], i, FunName, ImplTag);
+
+    InsertText(FunLocStart, CF);
+
+    if (ImportedBlockDecls.size()) {
+      std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, ImplTag);
+      InsertText(FunLocStart, HF);
+    }
+    std::string BD = SynthesizeBlockDescriptor(DescTag, ImplTag, i, FunName,
+                                               ImportedBlockDecls.size() > 0);
+    InsertText(FunLocStart, BD);
+
+    BlockDeclRefs.clear();
+    BlockByRefDecls.clear();
+    BlockByRefDeclsPtrSet.clear();
+    BlockByCopyDecls.clear();
+    BlockByCopyDeclsPtrSet.clear();
+    ImportedBlockDecls.clear();
+  }
+  if (RewriteSC) {
+    // Must insert any 'const/volatile/static here. Since it has been
+    // removed as result of rewriting of block literals.
+    std::string SC;
+    if (GlobalVarDecl->getStorageClass() == SC_Static)
+      SC = "static ";
+    if (GlobalVarDecl->getType().isConstQualified())
+      SC += "const ";
+    if (GlobalVarDecl->getType().isVolatileQualified())
+      SC += "volatile ";
+    if (GlobalVarDecl->getType().isRestrictQualified())
+      SC += "restrict ";
+    InsertText(FunLocStart, SC);
+  }
+  if (GlobalConstructionExp) {
+    // extra fancy dance for global literal expression.
+    
+    // Always the latest block expression on the block stack.
+    std::string Tag = "__";
+    Tag += FunName;
+    Tag += "_block_impl_";
+    Tag += utostr(Blocks.size()-1);
+    std::string globalBuf = "static ";
+    globalBuf += Tag; globalBuf += " ";
+    std::string SStr;
+  
+    llvm::raw_string_ostream constructorExprBuf(SStr);
+    GlobalConstructionExp->printPretty(constructorExprBuf, nullptr,
+                                       PrintingPolicy(LangOpts));
+    globalBuf += constructorExprBuf.str();
+    globalBuf += ";\n";
+    InsertText(FunLocStart, globalBuf);
+    GlobalConstructionExp = nullptr;
+  }
+
+  Blocks.clear();
+  InnerDeclRefsCount.clear();
+  InnerDeclRefs.clear();
+  RewrittenBlockExprs.clear();
+}
+
+void RewriteModernObjC::InsertBlockLiteralsWithinFunction(FunctionDecl *FD) {
+  SourceLocation FunLocStart = 
+    (!Blocks.empty()) ? getFunctionSourceLocation(*this, FD)
+                      : FD->getTypeSpecStartLoc();
+  StringRef FuncName = FD->getName();
+
+  SynthesizeBlockLiterals(FunLocStart, FuncName);
+}
+
+static void BuildUniqueMethodName(std::string &Name,
+                                  ObjCMethodDecl *MD) {
+  ObjCInterfaceDecl *IFace = MD->getClassInterface();
+  Name = IFace->getName();
+  Name += "__" + MD->getSelector().getAsString();
+  // Convert colons to underscores.
+  std::string::size_type loc = 0;
+  while ((loc = Name.find(":", loc)) != std::string::npos)
+    Name.replace(loc, 1, "_");
+}
+
+void RewriteModernObjC::InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD) {
+  //fprintf(stderr,"In InsertBlockLiteralsWitinMethod\n");
+  //SourceLocation FunLocStart = MD->getLocStart();
+  SourceLocation FunLocStart = MD->getLocStart();
+  std::string FuncName;
+  BuildUniqueMethodName(FuncName, MD);
+  SynthesizeBlockLiterals(FunLocStart, FuncName);
+}
+
+void RewriteModernObjC::GetBlockDeclRefExprs(Stmt *S) {
+  for (Stmt::child_range CI = S->children(); CI; ++CI)
+    if (*CI) {
+      if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI))
+        GetBlockDeclRefExprs(CBE->getBody());
+      else
+        GetBlockDeclRefExprs(*CI);
+    }
+  // Handle specific things.
+  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
+    if (DRE->refersToEnclosingLocal()) {
+      // FIXME: Handle enums.
+      if (!isa<FunctionDecl>(DRE->getDecl()))
+        BlockDeclRefs.push_back(DRE);
+      if (HasLocalVariableExternalStorage(DRE->getDecl()))
+        BlockDeclRefs.push_back(DRE);
+    }
+  }
+  
+  return;
+}
+
+void RewriteModernObjC::GetInnerBlockDeclRefExprs(Stmt *S,
+                SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs,
+                llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts) {
+  for (Stmt::child_range CI = S->children(); CI; ++CI)
+    if (*CI) {
+      if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI)) {
+        InnerContexts.insert(cast<DeclContext>(CBE->getBlockDecl()));
+        GetInnerBlockDeclRefExprs(CBE->getBody(),
+                                  InnerBlockDeclRefs,
+                                  InnerContexts);
+      }
+      else
+        GetInnerBlockDeclRefExprs(*CI,
+                                  InnerBlockDeclRefs,
+                                  InnerContexts);
+
+    }
+  // Handle specific things.
+  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
+    if (DRE->refersToEnclosingLocal()) {
+      if (!isa<FunctionDecl>(DRE->getDecl()) &&
+          !InnerContexts.count(DRE->getDecl()->getDeclContext()))
+        InnerBlockDeclRefs.push_back(DRE);
+      if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl()))
+        if (Var->isFunctionOrMethodVarDecl())
+          ImportedLocalExternalDecls.insert(Var);
+    }
+  }
+  
+  return;
+}
+
+/// convertObjCTypeToCStyleType - This routine converts such objc types
+/// as qualified objects, and blocks to their closest c/c++ types that
+/// it can. It returns true if input type was modified.
+bool RewriteModernObjC::convertObjCTypeToCStyleType(QualType &T) {
+  QualType oldT = T;
+  convertBlockPointerToFunctionPointer(T);
+  if (T->isFunctionPointerType()) {
+    QualType PointeeTy;
+    if (const PointerType* PT = T->getAs<PointerType>()) {
+      PointeeTy = PT->getPointeeType();
+      if (const FunctionType *FT = PointeeTy->getAs<FunctionType>()) {
+        T = convertFunctionTypeOfBlocks(FT);
+        T = Context->getPointerType(T);
+      }
+    }
+  }
+  
+  convertToUnqualifiedObjCType(T);
+  return T != oldT;
+}
+
+/// convertFunctionTypeOfBlocks - This routine converts a function type
+/// whose result type may be a block pointer or whose argument type(s)
+/// might be block pointers to an equivalent function type replacing
+/// all block pointers to function pointers.
+QualType RewriteModernObjC::convertFunctionTypeOfBlocks(const FunctionType *FT) {
+  const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT);
+  // FTP will be null for closures that don't take arguments.
+  // Generate a funky cast.
+  SmallVector<QualType, 8> ArgTypes;
+  QualType Res = FT->getReturnType();
+  bool modified = convertObjCTypeToCStyleType(Res);
+  
+  if (FTP) {
+    for (auto &I : FTP->param_types()) {
+      QualType t = I;
+      // Make sure we convert "t (^)(...)" to "t (*)(...)".
+      if (convertObjCTypeToCStyleType(t))
+        modified = true;
+      ArgTypes.push_back(t);
+    }
+  }
+  QualType FuncType;
+  if (modified)
+    FuncType = getSimpleFunctionType(Res, ArgTypes);
+  else FuncType = QualType(FT, 0);
+  return FuncType;
+}
+
+Stmt *RewriteModernObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp) {
+  // Navigate to relevant type information.
+  const BlockPointerType *CPT = nullptr;
+
+  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BlockExp)) {
+    CPT = DRE->getType()->getAs<BlockPointerType>();
+  } else if (const MemberExpr *MExpr = dyn_cast<MemberExpr>(BlockExp)) {
+    CPT = MExpr->getType()->getAs<BlockPointerType>();
+  } 
+  else if (const ParenExpr *PRE = dyn_cast<ParenExpr>(BlockExp)) {
+    return SynthesizeBlockCall(Exp, PRE->getSubExpr());
+  }
+  else if (const ImplicitCastExpr *IEXPR = dyn_cast<ImplicitCastExpr>(BlockExp)) 
+    CPT = IEXPR->getType()->getAs<BlockPointerType>();
+  else if (const ConditionalOperator *CEXPR = 
+            dyn_cast<ConditionalOperator>(BlockExp)) {
+    Expr *LHSExp = CEXPR->getLHS();
+    Stmt *LHSStmt = SynthesizeBlockCall(Exp, LHSExp);
+    Expr *RHSExp = CEXPR->getRHS();
+    Stmt *RHSStmt = SynthesizeBlockCall(Exp, RHSExp);
+    Expr *CONDExp = CEXPR->getCond();
+    ConditionalOperator *CondExpr =
+      new (Context) ConditionalOperator(CONDExp,
+                                      SourceLocation(), cast<Expr>(LHSStmt),
+                                      SourceLocation(), cast<Expr>(RHSStmt),
+                                      Exp->getType(), VK_RValue, OK_Ordinary);
+    return CondExpr;
+  } else if (const ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(BlockExp)) {
+    CPT = IRE->getType()->getAs<BlockPointerType>();
+  } else if (const PseudoObjectExpr *POE
+               = dyn_cast<PseudoObjectExpr>(BlockExp)) {
+    CPT = POE->getType()->castAs<BlockPointerType>();
+  } else {
+    assert(1 && "RewriteBlockClass: Bad type");
+  }
+  assert(CPT && "RewriteBlockClass: Bad type");
+  const FunctionType *FT = CPT->getPointeeType()->getAs<FunctionType>();
+  assert(FT && "RewriteBlockClass: Bad type");
+  const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT);
+  // FTP will be null for closures that don't take arguments.
+
+  RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
+                                      SourceLocation(), SourceLocation(),
+                                      &Context->Idents.get("__block_impl"));
+  QualType PtrBlock = Context->getPointerType(Context->getTagDeclType(RD));
+
+  // Generate a funky cast.
+  SmallVector<QualType, 8> ArgTypes;
+
+  // Push the block argument type.
+  ArgTypes.push_back(PtrBlock);
+  if (FTP) {
+    for (auto &I : FTP->param_types()) {
+      QualType t = I;
+      // Make sure we convert "t (^)(...)" to "t (*)(...)".
+      if (!convertBlockPointerToFunctionPointer(t))
+        convertToUnqualifiedObjCType(t);
+      ArgTypes.push_back(t);
+    }
+  }
+  // Now do the pointer to function cast.
+  QualType PtrToFuncCastType = getSimpleFunctionType(Exp->getType(), ArgTypes);
+
+  PtrToFuncCastType = Context->getPointerType(PtrToFuncCastType);
+
+  CastExpr *BlkCast = NoTypeInfoCStyleCastExpr(Context, PtrBlock,
+                                               CK_BitCast,
+                                               const_cast<Expr*>(BlockExp));
+  // Don't forget the parens to enforce the proper binding.
+  ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(),
+                                          BlkCast);
+  //PE->dump();
+
+  FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(),
+                                    SourceLocation(),
+                                    &Context->Idents.get("FuncPtr"),
+                                    Context->VoidPtrTy, nullptr,
+                                    /*BitWidth=*/nullptr, /*Mutable=*/true,
+                                    ICIS_NoInit);
+  MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(),
+                                            FD->getType(), VK_LValue,
+                                            OK_Ordinary);
+
+  
+  CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(Context, PtrToFuncCastType,
+                                                CK_BitCast, ME);
+  PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), FunkCast);
+
+  SmallVector<Expr*, 8> BlkExprs;
+  // Add the implicit argument.
+  BlkExprs.push_back(BlkCast);
+  // Add the user arguments.
+  for (CallExpr::arg_iterator I = Exp->arg_begin(),
+       E = Exp->arg_end(); I != E; ++I) {
+    BlkExprs.push_back(*I);
+  }
+  CallExpr *CE = new (Context) CallExpr(*Context, PE, BlkExprs,
+                                        Exp->getType(), VK_RValue,
+                                        SourceLocation());
+  return CE;
+}
+
+// We need to return the rewritten expression to handle cases where the
+// DeclRefExpr is embedded in another expression being rewritten.
+// For example:
+//
+// int main() {
+//    __block Foo *f;
+//    __block int i;
+//
+//    void (^myblock)() = ^() {
+//        [f test]; // f is a DeclRefExpr embedded in a message (which is being rewritten).
+//        i = 77;
+//    };
+//}
+Stmt *RewriteModernObjC::RewriteBlockDeclRefExpr(DeclRefExpr *DeclRefExp) {
+  // Rewrite the byref variable into BYREFVAR->__forwarding->BYREFVAR 
+  // for each DeclRefExp where BYREFVAR is name of the variable.
+  ValueDecl *VD = DeclRefExp->getDecl();
+  bool isArrow = DeclRefExp->refersToEnclosingLocal();
+
+  FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(),
+                                    SourceLocation(),
+                                    &Context->Idents.get("__forwarding"), 
+                                    Context->VoidPtrTy, nullptr,
+                                    /*BitWidth=*/nullptr, /*Mutable=*/true,
+                                    ICIS_NoInit);
+  MemberExpr *ME = new (Context) MemberExpr(DeclRefExp, isArrow,
+                                            FD, SourceLocation(),
+                                            FD->getType(), VK_LValue,
+                                            OK_Ordinary);
+
+  StringRef Name = VD->getName();
+  FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), SourceLocation(),
+                         &Context->Idents.get(Name), 
+                         Context->VoidPtrTy, nullptr,
+                         /*BitWidth=*/nullptr, /*Mutable=*/true,
+                         ICIS_NoInit);
+  ME = new (Context) MemberExpr(ME, true, FD, SourceLocation(),
+                                DeclRefExp->getType(), VK_LValue, OK_Ordinary);
+  
+  
+  
+  // Need parens to enforce precedence.
+  ParenExpr *PE = new (Context) ParenExpr(DeclRefExp->getExprLoc(), 
+                                          DeclRefExp->getExprLoc(), 
+                                          ME);
+  ReplaceStmt(DeclRefExp, PE);
+  return PE;
+}
+
+// Rewrites the imported local variable V with external storage 
+// (static, extern, etc.) as *V
+//
+Stmt *RewriteModernObjC::RewriteLocalVariableExternalStorage(DeclRefExpr *DRE) {
+  ValueDecl *VD = DRE->getDecl();
+  if (VarDecl *Var = dyn_cast<VarDecl>(VD))
+    if (!ImportedLocalExternalDecls.count(Var))
+      return DRE;
+  Expr *Exp = new (Context) UnaryOperator(DRE, UO_Deref, DRE->getType(),
+                                          VK_LValue, OK_Ordinary,
+                                          DRE->getLocation());
+  // Need parens to enforce precedence.
+  ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 
+                                          Exp);
+  ReplaceStmt(DRE, PE);
+  return PE;
+}
+
+void RewriteModernObjC::RewriteCastExpr(CStyleCastExpr *CE) {
+  SourceLocation LocStart = CE->getLParenLoc();
+  SourceLocation LocEnd = CE->getRParenLoc();
+
+  // Need to avoid trying to rewrite synthesized casts.
+  if (LocStart.isInvalid())
+    return;
+  // Need to avoid trying to rewrite casts contained in macros.
+  if (!Rewriter::isRewritable(LocStart) || !Rewriter::isRewritable(LocEnd))
+    return;
+
+  const char *startBuf = SM->getCharacterData(LocStart);
+  const char *endBuf = SM->getCharacterData(LocEnd);
+  QualType QT = CE->getType();
+  const Type* TypePtr = QT->getAs<Type>();
+  if (isa<TypeOfExprType>(TypePtr)) {
+    const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
+    QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType();
+    std::string TypeAsString = "(";
+    RewriteBlockPointerType(TypeAsString, QT);
+    TypeAsString += ")";
+    ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString);
+    return;
+  }
+  // advance the location to startArgList.
+  const char *argPtr = startBuf;
+
+  while (*argPtr++ && (argPtr < endBuf)) {
+    switch (*argPtr) {
+    case '^':
+      // Replace the '^' with '*'.
+      LocStart = LocStart.getLocWithOffset(argPtr-startBuf);
+      ReplaceText(LocStart, 1, "*");
+      break;
+    }
+  }
+  return;
+}
+
+void RewriteModernObjC::RewriteImplicitCastObjCExpr(CastExpr *IC) {
+  CastKind CastKind = IC->getCastKind();
+  if (CastKind != CK_BlockPointerToObjCPointerCast &&
+      CastKind != CK_AnyPointerToBlockPointerCast)
+    return;
+  
+  QualType QT = IC->getType();
+  (void)convertBlockPointerToFunctionPointer(QT);
+  std::string TypeString(QT.getAsString(Context->getPrintingPolicy()));
+  std::string Str = "(";
+  Str += TypeString;
+  Str += ")";
+  InsertText(IC->getSubExpr()->getLocStart(), &Str[0], Str.size());
+
+  return;
+}
+
+void RewriteModernObjC::RewriteBlockPointerFunctionArgs(FunctionDecl *FD) {
+  SourceLocation DeclLoc = FD->getLocation();
+  unsigned parenCount = 0;
+
+  // We have 1 or more arguments that have closure pointers.
+  const char *startBuf = SM->getCharacterData(DeclLoc);
+  const char *startArgList = strchr(startBuf, '(');
+
+  assert((*startArgList == '(') && "Rewriter fuzzy parser confused");
+
+  parenCount++;
+  // advance the location to startArgList.
+  DeclLoc = DeclLoc.getLocWithOffset(startArgList-startBuf);
+  assert((DeclLoc.isValid()) && "Invalid DeclLoc");
+
+  const char *argPtr = startArgList;
+
+  while (*argPtr++ && parenCount) {
+    switch (*argPtr) {
+    case '^':
+      // Replace the '^' with '*'.
+      DeclLoc = DeclLoc.getLocWithOffset(argPtr-startArgList);
+      ReplaceText(DeclLoc, 1, "*");
+      break;
+    case '(':
+      parenCount++;
+      break;
+    case ')':
+      parenCount--;
+      break;
+    }
+  }
+  return;
+}
+
+bool RewriteModernObjC::PointerTypeTakesAnyBlockArguments(QualType QT) {
+  const FunctionProtoType *FTP;
+  const PointerType *PT = QT->getAs<PointerType>();
+  if (PT) {
+    FTP = PT->getPointeeType()->getAs<FunctionProtoType>();
+  } else {
+    const BlockPointerType *BPT = QT->getAs<BlockPointerType>();
+    assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
+    FTP = BPT->getPointeeType()->getAs<FunctionProtoType>();
+  }
+  if (FTP) {
+    for (const auto &I : FTP->param_types())
+      if (isTopLevelBlockPointerType(I))
+        return true;
+  }
+  return false;
+}
+
+bool RewriteModernObjC::PointerTypeTakesAnyObjCQualifiedType(QualType QT) {
+  const FunctionProtoType *FTP;
+  const PointerType *PT = QT->getAs<PointerType>();
+  if (PT) {
+    FTP = PT->getPointeeType()->getAs<FunctionProtoType>();
+  } else {
+    const BlockPointerType *BPT = QT->getAs<BlockPointerType>();
+    assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
+    FTP = BPT->getPointeeType()->getAs<FunctionProtoType>();
+  }
+  if (FTP) {
+    for (const auto &I : FTP->param_types()) {
+      if (I->isObjCQualifiedIdType())
+        return true;
+      if (I->isObjCObjectPointerType() &&
+          I->getPointeeType()->isObjCQualifiedInterfaceType())
+        return true;
+    }
+        
+  }
+  return false;
+}
+
+void RewriteModernObjC::GetExtentOfArgList(const char *Name, const char *&LParen,
+                                     const char *&RParen) {
+  const char *argPtr = strchr(Name, '(');
+  assert((*argPtr == '(') && "Rewriter fuzzy parser confused");
+
+  LParen = argPtr; // output the start.
+  argPtr++; // skip past the left paren.
+  unsigned parenCount = 1;
+
+  while (*argPtr && parenCount) {
+    switch (*argPtr) {
+    case '(': parenCount++; break;
+    case ')': parenCount--; break;
+    default: break;
+    }
+    if (parenCount) argPtr++;
+  }
+  assert((*argPtr == ')') && "Rewriter fuzzy parser confused");
+  RParen = argPtr; // output the end
+}
+
+void RewriteModernObjC::RewriteBlockPointerDecl(NamedDecl *ND) {
+  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
+    RewriteBlockPointerFunctionArgs(FD);
+    return;
+  }
+  // Handle Variables and Typedefs.
+  SourceLocation DeclLoc = ND->getLocation();
+  QualType DeclT;
+  if (VarDecl *VD = dyn_cast<VarDecl>(ND))
+    DeclT = VD->getType();
+  else if (TypedefNameDecl *TDD = dyn_cast<TypedefNameDecl>(ND))
+    DeclT = TDD->getUnderlyingType();
+  else if (FieldDecl *FD = dyn_cast<FieldDecl>(ND))
+    DeclT = FD->getType();
+  else
+    llvm_unreachable("RewriteBlockPointerDecl(): Decl type not yet handled");
+
+  const char *startBuf = SM->getCharacterData(DeclLoc);
+  const char *endBuf = startBuf;
+  // scan backward (from the decl location) for the end of the previous decl.
+  while (*startBuf != '^' && *startBuf != ';' && startBuf != MainFileStart)
+    startBuf--;
+  SourceLocation Start = DeclLoc.getLocWithOffset(startBuf-endBuf);
+  std::string buf;
+  unsigned OrigLength=0;
+  // *startBuf != '^' if we are dealing with a pointer to function that
+  // may take block argument types (which will be handled below).
+  if (*startBuf == '^') {
+    // Replace the '^' with '*', computing a negative offset.
+    buf = '*';
+    startBuf++;
+    OrigLength++;
+  }
+  while (*startBuf != ')') {
+    buf += *startBuf;
+    startBuf++;
+    OrigLength++;
+  }
+  buf += ')';
+  OrigLength++;
+  
+  if (PointerTypeTakesAnyBlockArguments(DeclT) ||
+      PointerTypeTakesAnyObjCQualifiedType(DeclT)) {
+    // Replace the '^' with '*' for arguments.
+    // Replace id<P> with id/*<>*/
+    DeclLoc = ND->getLocation();
+    startBuf = SM->getCharacterData(DeclLoc);
+    const char *argListBegin, *argListEnd;
+    GetExtentOfArgList(startBuf, argListBegin, argListEnd);
+    while (argListBegin < argListEnd) {
+      if (*argListBegin == '^')
+        buf += '*';
+      else if (*argListBegin ==  '<') {
+        buf += "/*"; 
+        buf += *argListBegin++;
+        OrigLength++;
+        while (*argListBegin != '>') {
+          buf += *argListBegin++;
+          OrigLength++;
+        }
+        buf += *argListBegin;
+        buf += "*/";
+      }
+      else
+        buf += *argListBegin;
+      argListBegin++;
+      OrigLength++;
+    }
+    buf += ')';
+    OrigLength++;
+  }
+  ReplaceText(Start, OrigLength, buf);
+  
+  return;
+}
+
+
+/// SynthesizeByrefCopyDestroyHelper - This routine synthesizes:
+/// void __Block_byref_id_object_copy(struct Block_byref_id_object *dst,
+///                    struct Block_byref_id_object *src) {
+///  _Block_object_assign (&_dest->object, _src->object, 
+///                        BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT
+///                        [|BLOCK_FIELD_IS_WEAK]) // object
+///  _Block_object_assign(&_dest->object, _src->object, 
+///                       BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK
+///                       [|BLOCK_FIELD_IS_WEAK]) // block
+/// }
+/// And:
+/// void __Block_byref_id_object_dispose(struct Block_byref_id_object *_src) {
+///  _Block_object_dispose(_src->object, 
+///                        BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT
+///                        [|BLOCK_FIELD_IS_WEAK]) // object
+///  _Block_object_dispose(_src->object, 
+///                         BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK
+///                         [|BLOCK_FIELD_IS_WEAK]) // block
+/// }
+
+std::string RewriteModernObjC::SynthesizeByrefCopyDestroyHelper(VarDecl *VD,
+                                                          int flag) {
+  std::string S;
+  if (CopyDestroyCache.count(flag))
+    return S;
+  CopyDestroyCache.insert(flag);
+  S = "static void __Block_byref_id_object_copy_";
+  S += utostr(flag);
+  S += "(void *dst, void *src) {\n";
+  
+  // offset into the object pointer is computed as:
+  // void * + void* + int + int + void* + void *
+  unsigned IntSize = 
+  static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
+  unsigned VoidPtrSize = 
+  static_cast<unsigned>(Context->getTypeSize(Context->VoidPtrTy));
+  
+  unsigned offset = (VoidPtrSize*4 + IntSize + IntSize)/Context->getCharWidth();
+  S += " _Block_object_assign((char*)dst + ";
+  S += utostr(offset);
+  S += ", *(void * *) ((char*)src + ";
+  S += utostr(offset);
+  S += "), ";
+  S += utostr(flag);
+  S += ");\n}\n";
+  
+  S += "static void __Block_byref_id_object_dispose_";
+  S += utostr(flag);
+  S += "(void *src) {\n";
+  S += " _Block_object_dispose(*(void * *) ((char*)src + ";
+  S += utostr(offset);
+  S += "), ";
+  S += utostr(flag);
+  S += ");\n}\n";
+  return S;
+}
+
+/// RewriteByRefVar - For each __block typex ND variable this routine transforms
+/// the declaration into:
+/// struct __Block_byref_ND {
+/// void *__isa;                  // NULL for everything except __weak pointers
+/// struct __Block_byref_ND *__forwarding;
+/// int32_t __flags;
+/// int32_t __size;
+/// void *__Block_byref_id_object_copy; // If variable is __block ObjC object
+/// void *__Block_byref_id_object_dispose; // If variable is __block ObjC object
+/// typex ND;
+/// };
+///
+/// It then replaces declaration of ND variable with:
+/// struct __Block_byref_ND ND = {__isa=0B, __forwarding=&ND, __flags=some_flag, 
+///                               __size=sizeof(struct __Block_byref_ND), 
+///                               ND=initializer-if-any};
+///
+///
+void RewriteModernObjC::RewriteByRefVar(VarDecl *ND, bool firstDecl,
+                                        bool lastDecl) {
+  int flag = 0;
+  int isa = 0;
+  SourceLocation DeclLoc = ND->getTypeSpecStartLoc();
+  if (DeclLoc.isInvalid())
+    // If type location is missing, it is because of missing type (a warning).
+    // Use variable's location which is good for this case.
+    DeclLoc = ND->getLocation();
+  const char *startBuf = SM->getCharacterData(DeclLoc);
+  SourceLocation X = ND->getLocEnd();
+  X = SM->getExpansionLoc(X);
+  const char *endBuf = SM->getCharacterData(X);
+  std::string Name(ND->getNameAsString());
+  std::string ByrefType;
+  RewriteByRefString(ByrefType, Name, ND, true);
+  ByrefType += " {\n";
+  ByrefType += "  void *__isa;\n";
+  RewriteByRefString(ByrefType, Name, ND);
+  ByrefType += " *__forwarding;\n";
+  ByrefType += " int __flags;\n";
+  ByrefType += " int __size;\n";
+  // Add void *__Block_byref_id_object_copy; 
+  // void *__Block_byref_id_object_dispose; if needed.
+  QualType Ty = ND->getType();
+  bool HasCopyAndDispose = Context->BlockRequiresCopying(Ty, ND);
+  if (HasCopyAndDispose) {
+    ByrefType += " void (*__Block_byref_id_object_copy)(void*, void*);\n";
+    ByrefType += " void (*__Block_byref_id_object_dispose)(void*);\n";
+  }
+
+  QualType T = Ty;
+  (void)convertBlockPointerToFunctionPointer(T);
+  T.getAsStringInternal(Name, Context->getPrintingPolicy());
+    
+  ByrefType += " " + Name + ";\n";
+  ByrefType += "};\n";
+  // Insert this type in global scope. It is needed by helper function.
+  SourceLocation FunLocStart;
+  if (CurFunctionDef)
+     FunLocStart = getFunctionSourceLocation(*this, CurFunctionDef);
+  else {
+    assert(CurMethodDef && "RewriteByRefVar - CurMethodDef is null");
+    FunLocStart = CurMethodDef->getLocStart();
+  }
+  InsertText(FunLocStart, ByrefType);
+  
+  if (Ty.isObjCGCWeak()) {
+    flag |= BLOCK_FIELD_IS_WEAK;
+    isa = 1;
+  }
+  if (HasCopyAndDispose) {
+    flag = BLOCK_BYREF_CALLER;
+    QualType Ty = ND->getType();
+    // FIXME. Handle __weak variable (BLOCK_FIELD_IS_WEAK) as well.
+    if (Ty->isBlockPointerType())
+      flag |= BLOCK_FIELD_IS_BLOCK;
+    else
+      flag |= BLOCK_FIELD_IS_OBJECT;
+    std::string HF = SynthesizeByrefCopyDestroyHelper(ND, flag);
+    if (!HF.empty())
+      Preamble += HF;
+  }
+  
+  // struct __Block_byref_ND ND = 
+  // {0, &ND, some_flag, __size=sizeof(struct __Block_byref_ND), 
+  //  initializer-if-any};
+  bool hasInit = (ND->getInit() != nullptr);
+  // FIXME. rewriter does not support __block c++ objects which
+  // require construction.
+  if (hasInit)
+    if (CXXConstructExpr *CExp = dyn_cast<CXXConstructExpr>(ND->getInit())) {
+      CXXConstructorDecl *CXXDecl = CExp->getConstructor();
+      if (CXXDecl && CXXDecl->isDefaultConstructor())
+        hasInit = false;
+    }
+  
+  unsigned flags = 0;
+  if (HasCopyAndDispose)
+    flags |= BLOCK_HAS_COPY_DISPOSE;
+  Name = ND->getNameAsString();
+  ByrefType.clear();
+  RewriteByRefString(ByrefType, Name, ND);
+  std::string ForwardingCastType("(");
+  ForwardingCastType += ByrefType + " *)";
+  ByrefType += " " + Name + " = {(void*)";
+  ByrefType += utostr(isa);
+  ByrefType += "," +  ForwardingCastType + "&" + Name + ", ";
+  ByrefType += utostr(flags);
+  ByrefType += ", ";
+  ByrefType += "sizeof(";
+  RewriteByRefString(ByrefType, Name, ND);
+  ByrefType += ")";
+  if (HasCopyAndDispose) {
+    ByrefType += ", __Block_byref_id_object_copy_";
+    ByrefType += utostr(flag);
+    ByrefType += ", __Block_byref_id_object_dispose_";
+    ByrefType += utostr(flag);
+  }
+  
+  if (!firstDecl) {
+    // In multiple __block declarations, and for all but 1st declaration,
+    // find location of the separating comma. This would be start location
+    // where new text is to be inserted.
+    DeclLoc = ND->getLocation();
+    const char *startDeclBuf = SM->getCharacterData(DeclLoc);
+    const char *commaBuf = startDeclBuf;
+    while (*commaBuf != ',')
+      commaBuf--;
+    assert((*commaBuf == ',') && "RewriteByRefVar: can't find ','");
+    DeclLoc = DeclLoc.getLocWithOffset(commaBuf - startDeclBuf);
+    startBuf = commaBuf;
+  }
+  
+  if (!hasInit) {
+    ByrefType += "};\n";
+    unsigned nameSize = Name.size();
+    // for block or function pointer declaration. Name is aleady
+    // part of the declaration.
+    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType())
+      nameSize = 1;
+    ReplaceText(DeclLoc, endBuf-startBuf+nameSize, ByrefType);
+  }
+  else {
+    ByrefType += ", ";
+    SourceLocation startLoc;
+    Expr *E = ND->getInit();
+    if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E))
+      startLoc = ECE->getLParenLoc();
+    else
+      startLoc = E->getLocStart();
+    startLoc = SM->getExpansionLoc(startLoc);
+    endBuf = SM->getCharacterData(startLoc);
+    ReplaceText(DeclLoc, endBuf-startBuf, ByrefType);
+
+    const char separator = lastDecl ? ';' : ',';
+    const char *startInitializerBuf = SM->getCharacterData(startLoc);
+    const char *separatorBuf = strchr(startInitializerBuf, separator);
+    assert((*separatorBuf == separator) && 
+           "RewriteByRefVar: can't find ';' or ','");
+    SourceLocation separatorLoc =
+      startLoc.getLocWithOffset(separatorBuf-startInitializerBuf);
+    
+    InsertText(separatorLoc, lastDecl ? "}" : "};\n");
+  }
+  return;
+}
+
+void RewriteModernObjC::CollectBlockDeclRefInfo(BlockExpr *Exp) {
+  // Add initializers for any closure decl refs.
+  GetBlockDeclRefExprs(Exp->getBody());
+  if (BlockDeclRefs.size()) {
+    // Unique all "by copy" declarations.
+    for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
+      if (!BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
+        if (!BlockByCopyDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
+          BlockByCopyDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
+          BlockByCopyDecls.push_back(BlockDeclRefs[i]->getDecl());
+        }
+      }
+    // Unique all "by ref" declarations.
+    for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
+      if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
+        if (!BlockByRefDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
+          BlockByRefDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
+          BlockByRefDecls.push_back(BlockDeclRefs[i]->getDecl());
+        }
+      }
+    // Find any imported blocks...they will need special attention.
+    for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
+      if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
+          BlockDeclRefs[i]->getType()->isObjCObjectPointerType() || 
+          BlockDeclRefs[i]->getType()->isBlockPointerType())
+        ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl());
+  }
+}
+
+FunctionDecl *RewriteModernObjC::SynthBlockInitFunctionDecl(StringRef name) {
+  IdentifierInfo *ID = &Context->Idents.get(name);
+  QualType FType = Context->getFunctionNoProtoType(Context->VoidPtrTy);
+  return FunctionDecl::Create(*Context, TUDecl, SourceLocation(),
+                              SourceLocation(), ID, FType, nullptr, SC_Extern,
+                              false, false);
+}
+
+Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp,
+                     const SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs) {
+  
+  const BlockDecl *block = Exp->getBlockDecl();
+  
+  Blocks.push_back(Exp);
+
+  CollectBlockDeclRefInfo(Exp);
+  
+  // Add inner imported variables now used in current block.
+ int countOfInnerDecls = 0;
+  if (!InnerBlockDeclRefs.empty()) {
+    for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) {
+      DeclRefExpr *Exp = InnerBlockDeclRefs[i];
+      ValueDecl *VD = Exp->getDecl();
+      if (!VD->hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) {
+      // We need to save the copied-in variables in nested
+      // blocks because it is needed at the end for some of the API generations.
+      // See SynthesizeBlockLiterals routine.
+        InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
+        BlockDeclRefs.push_back(Exp);
+        BlockByCopyDeclsPtrSet.insert(VD);
+        BlockByCopyDecls.push_back(VD);
+      }
+      if (VD->hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) {
+        InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
+        BlockDeclRefs.push_back(Exp);
+        BlockByRefDeclsPtrSet.insert(VD);
+        BlockByRefDecls.push_back(VD);
+      }
+    }
+    // Find any imported blocks...they will need special attention.
+    for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++)
+      if (InnerBlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
+          InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() || 
+          InnerBlockDeclRefs[i]->getType()->isBlockPointerType())
+        ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl());
+  }
+  InnerDeclRefsCount.push_back(countOfInnerDecls);
+  
+  std::string FuncName;
+
+  if (CurFunctionDef)
+    FuncName = CurFunctionDef->getNameAsString();
+  else if (CurMethodDef)
+    BuildUniqueMethodName(FuncName, CurMethodDef);
+  else if (GlobalVarDecl)
+    FuncName = std::string(GlobalVarDecl->getNameAsString());
+
+  bool GlobalBlockExpr = 
+    block->getDeclContext()->getRedeclContext()->isFileContext();
+  
+  if (GlobalBlockExpr && !GlobalVarDecl) {
+    Diags.Report(block->getLocation(), GlobalBlockRewriteFailedDiag);
+    GlobalBlockExpr = false;
+  }
+  
+  std::string BlockNumber = utostr(Blocks.size()-1);
+
+  std::string Func = "__" + FuncName + "_block_func_" + BlockNumber;
+
+  // Get a pointer to the function type so we can cast appropriately.
+  QualType BFT = convertFunctionTypeOfBlocks(Exp->getFunctionType());
+  QualType FType = Context->getPointerType(BFT);
+
+  FunctionDecl *FD;
+  Expr *NewRep;
+
+  // Simulate a constructor call...
+  std::string Tag;
+  
+  if (GlobalBlockExpr)
+    Tag = "__global_";
+  else
+    Tag = "__";
+  Tag += FuncName + "_block_impl_" + BlockNumber;
+  
+  FD = SynthBlockInitFunctionDecl(Tag);
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, false, FType, VK_RValue,
+                                               SourceLocation());
+
+  SmallVector<Expr*, 4> InitExprs;
+
+  // Initialize the block function.
+  FD = SynthBlockInitFunctionDecl(Func);
+  DeclRefExpr *Arg = new (Context) DeclRefExpr(FD, false, FD->getType(),
+                                               VK_LValue, SourceLocation());
+  CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
+                                                CK_BitCast, Arg);
+  InitExprs.push_back(castExpr);
+
+  // Initialize the block descriptor.
+  std::string DescData = "__" + FuncName + "_block_desc_" + BlockNumber + "_DATA";
+
+  VarDecl *NewVD = VarDecl::Create(*Context, TUDecl,
+                                   SourceLocation(), SourceLocation(),
+                                   &Context->Idents.get(DescData.c_str()),
+                                   Context->VoidPtrTy, nullptr,
+                                   SC_Static);
+  UnaryOperator *DescRefExpr =
+    new (Context) UnaryOperator(new (Context) DeclRefExpr(NewVD, false,
+                                                          Context->VoidPtrTy,
+                                                          VK_LValue,
+                                                          SourceLocation()), 
+                                UO_AddrOf,
+                                Context->getPointerType(Context->VoidPtrTy), 
+                                VK_RValue, OK_Ordinary,
+                                SourceLocation());
+  InitExprs.push_back(DescRefExpr); 
+  
+  // Add initializers for any closure decl refs.
+  if (BlockDeclRefs.size()) {
+    Expr *Exp;
+    // Output all "by copy" declarations.
+    for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(),
+         E = BlockByCopyDecls.end(); I != E; ++I) {
+      if (isObjCType((*I)->getType())) {
+        // FIXME: Conform to ABI ([[obj retain] autorelease]).
+        FD = SynthBlockInitFunctionDecl((*I)->getName());
+        Exp = new (Context) DeclRefExpr(FD, false, FD->getType(),
+                                        VK_LValue, SourceLocation());
+        if (HasLocalVariableExternalStorage(*I)) {
+          QualType QT = (*I)->getType();
+          QT = Context->getPointerType(QT);
+          Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue,
+                                            OK_Ordinary, SourceLocation());
+        }
+      } else if (isTopLevelBlockPointerType((*I)->getType())) {
+        FD = SynthBlockInitFunctionDecl((*I)->getName());
+        Arg = new (Context) DeclRefExpr(FD, false, FD->getType(),
+                                        VK_LValue, SourceLocation());
+        Exp = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
+                                       CK_BitCast, Arg);
+      } else {
+        FD = SynthBlockInitFunctionDecl((*I)->getName());
+        Exp = new (Context) DeclRefExpr(FD, false, FD->getType(),
+                                        VK_LValue, SourceLocation());
+        if (HasLocalVariableExternalStorage(*I)) {
+          QualType QT = (*I)->getType();
+          QT = Context->getPointerType(QT);
+          Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue,
+                                            OK_Ordinary, SourceLocation());
+        }
+        
+      }
+      InitExprs.push_back(Exp);
+    }
+    // Output all "by ref" declarations.
+    for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(),
+         E = BlockByRefDecls.end(); I != E; ++I) {
+      ValueDecl *ND = (*I);
+      std::string Name(ND->getNameAsString());
+      std::string RecName;
+      RewriteByRefString(RecName, Name, ND, true);
+      IdentifierInfo *II = &Context->Idents.get(RecName.c_str() 
+                                                + sizeof("struct"));
+      RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
+                                          SourceLocation(), SourceLocation(),
+                                          II);
+      assert(RD && "SynthBlockInitExpr(): Can't find RecordDecl");
+      QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
+      
+      FD = SynthBlockInitFunctionDecl((*I)->getName());
+      Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue,
+                                      SourceLocation());
+      bool isNestedCapturedVar = false;
+      if (block)
+        for (const auto &CI : block->captures()) {
+          const VarDecl *variable = CI.getVariable();
+          if (variable == ND && CI.isNested()) {
+            assert (CI.isByRef() && 
+                    "SynthBlockInitExpr - captured block variable is not byref");
+            isNestedCapturedVar = true;
+            break;
+          }
+        }
+      // captured nested byref variable has its address passed. Do not take
+      // its address again.
+      if (!isNestedCapturedVar)
+          Exp = new (Context) UnaryOperator(Exp, UO_AddrOf,
+                                     Context->getPointerType(Exp->getType()),
+                                     VK_RValue, OK_Ordinary, SourceLocation());
+      Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp);
+      InitExprs.push_back(Exp);
+    }
+  }
+  if (ImportedBlockDecls.size()) {
+    // generate BLOCK_HAS_COPY_DISPOSE(have helper funcs) | BLOCK_HAS_DESCRIPTOR
+    int flag = (BLOCK_HAS_COPY_DISPOSE | BLOCK_HAS_DESCRIPTOR);
+    unsigned IntSize = 
+      static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
+    Expr *FlagExp = IntegerLiteral::Create(*Context, llvm::APInt(IntSize, flag), 
+                                           Context->IntTy, SourceLocation());
+    InitExprs.push_back(FlagExp);
+  }
+  NewRep = new (Context) CallExpr(*Context, DRE, InitExprs,
+                                  FType, VK_LValue, SourceLocation());
+  
+  if (GlobalBlockExpr) {
+    assert (!GlobalConstructionExp &&
+            "SynthBlockInitExpr - GlobalConstructionExp must be null");
+    GlobalConstructionExp = NewRep;
+    NewRep = DRE;
+  }
+  
+  NewRep = new (Context) UnaryOperator(NewRep, UO_AddrOf,
+                             Context->getPointerType(NewRep->getType()),
+                             VK_RValue, OK_Ordinary, SourceLocation());
+  NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast,
+                                    NewRep);
+  BlockDeclRefs.clear();
+  BlockByRefDecls.clear();
+  BlockByRefDeclsPtrSet.clear();
+  BlockByCopyDecls.clear();
+  BlockByCopyDeclsPtrSet.clear();
+  ImportedBlockDecls.clear();
+  return NewRep;
+}
+
+bool RewriteModernObjC::IsDeclStmtInForeachHeader(DeclStmt *DS) {
+  if (const ObjCForCollectionStmt * CS = 
+      dyn_cast<ObjCForCollectionStmt>(Stmts.back()))
+        return CS->getElement() == DS;
+  return false;
+}
+
+//===----------------------------------------------------------------------===//
+// Function Body / Expression rewriting
+//===----------------------------------------------------------------------===//
+
+Stmt *RewriteModernObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) {
+  if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
+      isa<DoStmt>(S) || isa<ForStmt>(S))
+    Stmts.push_back(S);
+  else if (isa<ObjCForCollectionStmt>(S)) {
+    Stmts.push_back(S);
+    ObjCBcLabelNo.push_back(++BcLabelCount);
+  }
+
+  // Pseudo-object operations and ivar references need special
+  // treatment because we're going to recursively rewrite them.
+  if (PseudoObjectExpr *PseudoOp = dyn_cast<PseudoObjectExpr>(S)) {
+    if (isa<BinaryOperator>(PseudoOp->getSyntacticForm())) {
+      return RewritePropertyOrImplicitSetter(PseudoOp);
+    } else {
+      return RewritePropertyOrImplicitGetter(PseudoOp);
+    }
+  } else if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) {
+    return RewriteObjCIvarRefExpr(IvarRefExpr);
+  }
+  else if (isa<OpaqueValueExpr>(S))
+    S = cast<OpaqueValueExpr>(S)->getSourceExpr();
+
+  SourceRange OrigStmtRange = S->getSourceRange();
+
+  // Perform a bottom up rewrite of all children.
+  for (Stmt::child_range CI = S->children(); CI; ++CI)
+    if (*CI) {
+      Stmt *childStmt = (*CI);
+      Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(childStmt);
+      if (newStmt) {
+        *CI = newStmt;
+      }
+    }
+
+  if (BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
+    SmallVector<DeclRefExpr *, 8> InnerBlockDeclRefs;
+    llvm::SmallPtrSet<const DeclContext *, 8> InnerContexts;
+    InnerContexts.insert(BE->getBlockDecl());
+    ImportedLocalExternalDecls.clear();
+    GetInnerBlockDeclRefExprs(BE->getBody(),
+                              InnerBlockDeclRefs, InnerContexts);
+    // Rewrite the block body in place.
+    Stmt *SaveCurrentBody = CurrentBody;
+    CurrentBody = BE->getBody();
+    PropParentMap = nullptr;
+    // block literal on rhs of a property-dot-sytax assignment
+    // must be replaced by its synthesize ast so getRewrittenText
+    // works as expected. In this case, what actually ends up on RHS
+    // is the blockTranscribed which is the helper function for the
+    // block literal; as in: self.c = ^() {[ace ARR];};
+    bool saveDisableReplaceStmt = DisableReplaceStmt;
+    DisableReplaceStmt = false;
+    RewriteFunctionBodyOrGlobalInitializer(BE->getBody());
+    DisableReplaceStmt = saveDisableReplaceStmt;
+    CurrentBody = SaveCurrentBody;
+    PropParentMap = nullptr;
+    ImportedLocalExternalDecls.clear();
+    // Now we snarf the rewritten text and stash it away for later use.
+    std::string Str = Rewrite.getRewrittenText(BE->getSourceRange());
+    RewrittenBlockExprs[BE] = Str;
+
+    Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs);
+                            
+    //blockTranscribed->dump();
+    ReplaceStmt(S, blockTranscribed);
+    return blockTranscribed;
+  }
+  // Handle specific things.
+  if (ObjCEncodeExpr *AtEncode = dyn_cast<ObjCEncodeExpr>(S))
+    return RewriteAtEncode(AtEncode);
+
+  if (ObjCSelectorExpr *AtSelector = dyn_cast<ObjCSelectorExpr>(S))
+    return RewriteAtSelector(AtSelector);
+
+  if (ObjCStringLiteral *AtString = dyn_cast<ObjCStringLiteral>(S))
+    return RewriteObjCStringLiteral(AtString);
+  
+  if (ObjCBoolLiteralExpr *BoolLitExpr = dyn_cast<ObjCBoolLiteralExpr>(S))
+    return RewriteObjCBoolLiteralExpr(BoolLitExpr);
+  
+  if (ObjCBoxedExpr *BoxedExpr = dyn_cast<ObjCBoxedExpr>(S))
+    return RewriteObjCBoxedExpr(BoxedExpr);
+  
+  if (ObjCArrayLiteral *ArrayLitExpr = dyn_cast<ObjCArrayLiteral>(S))
+    return RewriteObjCArrayLiteralExpr(ArrayLitExpr);
+  
+  if (ObjCDictionaryLiteral *DictionaryLitExpr = 
+        dyn_cast<ObjCDictionaryLiteral>(S))
+    return RewriteObjCDictionaryLiteralExpr(DictionaryLitExpr);
+
+  if (ObjCMessageExpr *MessExpr = dyn_cast<ObjCMessageExpr>(S)) {
+#if 0
+    // Before we rewrite it, put the original message expression in a comment.
+    SourceLocation startLoc = MessExpr->getLocStart();
+    SourceLocation endLoc = MessExpr->getLocEnd();
+
+    const char *startBuf = SM->getCharacterData(startLoc);
+    const char *endBuf = SM->getCharacterData(endLoc);
+
+    std::string messString;
+    messString += "// ";
+    messString.append(startBuf, endBuf-startBuf+1);
+    messString += "\n";
+
+    // FIXME: Missing definition of
+    // InsertText(clang::SourceLocation, char const*, unsigned int).
+    // InsertText(startLoc, messString.c_str(), messString.size());
+    // Tried this, but it didn't work either...
+    // ReplaceText(startLoc, 0, messString.c_str(), messString.size());
+#endif
+    return RewriteMessageExpr(MessExpr);
+  }
+
+  if (ObjCAutoreleasePoolStmt *StmtAutoRelease = 
+        dyn_cast<ObjCAutoreleasePoolStmt>(S)) {
+    return RewriteObjCAutoreleasePoolStmt(StmtAutoRelease);
+  }
+  
+  if (ObjCAtTryStmt *StmtTry = dyn_cast<ObjCAtTryStmt>(S))
+    return RewriteObjCTryStmt(StmtTry);
+
+  if (ObjCAtSynchronizedStmt *StmtTry = dyn_cast<ObjCAtSynchronizedStmt>(S))
+    return RewriteObjCSynchronizedStmt(StmtTry);
+
+  if (ObjCAtThrowStmt *StmtThrow = dyn_cast<ObjCAtThrowStmt>(S))
+    return RewriteObjCThrowStmt(StmtThrow);
+
+  if (ObjCProtocolExpr *ProtocolExp = dyn_cast<ObjCProtocolExpr>(S))
+    return RewriteObjCProtocolExpr(ProtocolExp);
+
+  if (ObjCForCollectionStmt *StmtForCollection =
+        dyn_cast<ObjCForCollectionStmt>(S))
+    return RewriteObjCForCollectionStmt(StmtForCollection,
+                                        OrigStmtRange.getEnd());
+  if (BreakStmt *StmtBreakStmt =
+      dyn_cast<BreakStmt>(S))
+    return RewriteBreakStmt(StmtBreakStmt);
+  if (ContinueStmt *StmtContinueStmt =
+      dyn_cast<ContinueStmt>(S))
+    return RewriteContinueStmt(StmtContinueStmt);
+
+  // Need to check for protocol refs (id <P>, Foo <P> *) in variable decls
+  // and cast exprs.
+  if (DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
+    // FIXME: What we're doing here is modifying the type-specifier that
+    // precedes the first Decl.  In the future the DeclGroup should have
+    // a separate type-specifier that we can rewrite.
+    // NOTE: We need to avoid rewriting the DeclStmt if it is within
+    // the context of an ObjCForCollectionStmt. For example:
+    //   NSArray *someArray;
+    //   for (id <FooProtocol> index in someArray) ;
+    // This is because RewriteObjCForCollectionStmt() does textual rewriting 
+    // and it depends on the original text locations/positions.
+    if (Stmts.empty() || !IsDeclStmtInForeachHeader(DS))
+      RewriteObjCQualifiedInterfaceTypes(*DS->decl_begin());
+
+    // Blocks rewrite rules.
+    for (DeclStmt::decl_iterator DI = DS->decl_begin(), DE = DS->decl_end();
+         DI != DE; ++DI) {
+      Decl *SD = *DI;
+      if (ValueDecl *ND = dyn_cast<ValueDecl>(SD)) {
+        if (isTopLevelBlockPointerType(ND->getType()))
+          RewriteBlockPointerDecl(ND);
+        else if (ND->getType()->isFunctionPointerType())
+          CheckFunctionPointerDecl(ND->getType(), ND);
+        if (VarDecl *VD = dyn_cast<VarDecl>(SD)) {
+          if (VD->hasAttr<BlocksAttr>()) {
+            static unsigned uniqueByrefDeclCount = 0;
+            assert(!BlockByRefDeclNo.count(ND) &&
+              "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl");
+            BlockByRefDeclNo[ND] = uniqueByrefDeclCount++;
+            RewriteByRefVar(VD, (DI == DS->decl_begin()), ((DI+1) == DE));
+          }
+          else           
+            RewriteTypeOfDecl(VD);
+        }
+      }
+      if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(SD)) {
+        if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
+          RewriteBlockPointerDecl(TD);
+        else if (TD->getUnderlyingType()->isFunctionPointerType())
+          CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
+      }
+    }
+  }
+
+  if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(S))
+    RewriteObjCQualifiedInterfaceTypes(CE);
+
+  if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
+      isa<DoStmt>(S) || isa<ForStmt>(S)) {
+    assert(!Stmts.empty() && "Statement stack is empty");
+    assert ((isa<SwitchStmt>(Stmts.back()) || isa<WhileStmt>(Stmts.back()) ||
+             isa<DoStmt>(Stmts.back()) || isa<ForStmt>(Stmts.back()))
+            && "Statement stack mismatch");
+    Stmts.pop_back();
+  }
+  // Handle blocks rewriting.
+  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
+    ValueDecl *VD = DRE->getDecl(); 
+    if (VD->hasAttr<BlocksAttr>())
+      return RewriteBlockDeclRefExpr(DRE);
+    if (HasLocalVariableExternalStorage(VD))
+      return RewriteLocalVariableExternalStorage(DRE);
+  }
+  
+  if (CallExpr *CE = dyn_cast<CallExpr>(S)) {
+    if (CE->getCallee()->getType()->isBlockPointerType()) {
+      Stmt *BlockCall = SynthesizeBlockCall(CE, CE->getCallee());
+      ReplaceStmt(S, BlockCall);
+      return BlockCall;
+    }
+  }
+  if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(S)) {
+    RewriteCastExpr(CE);
+  }
+  if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(S)) {
+    RewriteImplicitCastObjCExpr(ICE);
+  }
+#if 0
+
+  if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(S)) {
+    CastExpr *Replacement = new (Context) CastExpr(ICE->getType(),
+                                                   ICE->getSubExpr(),
+                                                   SourceLocation());
+    // Get the new text.
+    std::string SStr;
+    llvm::raw_string_ostream Buf(SStr);
+    Replacement->printPretty(Buf);
+    const std::string &Str = Buf.str();
+
+    printf("CAST = %s\n", &Str[0]);
+    InsertText(ICE->getSubExpr()->getLocStart(), &Str[0], Str.size());
+    delete S;
+    return Replacement;
+  }
+#endif
+  // Return this stmt unmodified.
+  return S;
+}
+
+void RewriteModernObjC::RewriteRecordBody(RecordDecl *RD) {
+  for (auto *FD : RD->fields()) {
+    if (isTopLevelBlockPointerType(FD->getType()))
+      RewriteBlockPointerDecl(FD);
+    if (FD->getType()->isObjCQualifiedIdType() ||
+        FD->getType()->isObjCQualifiedInterfaceType())
+      RewriteObjCQualifiedInterfaceTypes(FD);
+  }
+}
+
+/// HandleDeclInMainFile - This is called for each top-level decl defined in the
+/// main file of the input.
+void RewriteModernObjC::HandleDeclInMainFile(Decl *D) {
+  switch (D->getKind()) {
+    case Decl::Function: {
+      FunctionDecl *FD = cast<FunctionDecl>(D);
+      if (FD->isOverloadedOperator())
+        return;
+
+      // Since function prototypes don't have ParmDecl's, we check the function
+      // prototype. This enables us to rewrite function declarations and
+      // definitions using the same code.
+      RewriteBlocksInFunctionProtoType(FD->getType(), FD);
+
+      if (!FD->isThisDeclarationADefinition())
+        break;
+
+      // FIXME: If this should support Obj-C++, support CXXTryStmt
+      if (CompoundStmt *Body = dyn_cast_or_null<CompoundStmt>(FD->getBody())) {
+        CurFunctionDef = FD;
+        CurrentBody = Body;
+        Body =
+        cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
+        FD->setBody(Body);
+        CurrentBody = nullptr;
+        if (PropParentMap) {
+          delete PropParentMap;
+          PropParentMap = nullptr;
+        }
+        // This synthesizes and inserts the block "impl" struct, invoke function,
+        // and any copy/dispose helper functions.
+        InsertBlockLiteralsWithinFunction(FD);
+        RewriteLineDirective(D);
+        CurFunctionDef = nullptr;
+      }
+      break;
+    }
+    case Decl::ObjCMethod: {
+      ObjCMethodDecl *MD = cast<ObjCMethodDecl>(D);
+      if (CompoundStmt *Body = MD->getCompoundBody()) {
+        CurMethodDef = MD;
+        CurrentBody = Body;
+        Body =
+          cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
+        MD->setBody(Body);
+        CurrentBody = nullptr;
+        if (PropParentMap) {
+          delete PropParentMap;
+          PropParentMap = nullptr;
+        }
+        InsertBlockLiteralsWithinMethod(MD);
+        RewriteLineDirective(D);
+        CurMethodDef = nullptr;
+      }
+      break;
+    }
+    case Decl::ObjCImplementation: {
+      ObjCImplementationDecl *CI = cast<ObjCImplementationDecl>(D);
+      ClassImplementation.push_back(CI);
+      break;
+    }
+    case Decl::ObjCCategoryImpl: {
+      ObjCCategoryImplDecl *CI = cast<ObjCCategoryImplDecl>(D);
+      CategoryImplementation.push_back(CI);
+      break;
+    }
+    case Decl::Var: {
+      VarDecl *VD = cast<VarDecl>(D);
+      RewriteObjCQualifiedInterfaceTypes(VD);
+      if (isTopLevelBlockPointerType(VD->getType()))
+        RewriteBlockPointerDecl(VD);
+      else if (VD->getType()->isFunctionPointerType()) {
+        CheckFunctionPointerDecl(VD->getType(), VD);
+        if (VD->getInit()) {
+          if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(VD->getInit())) {
+            RewriteCastExpr(CE);
+          }
+        }
+      } else if (VD->getType()->isRecordType()) {
+        RecordDecl *RD = VD->getType()->getAs<RecordType>()->getDecl();
+        if (RD->isCompleteDefinition())
+          RewriteRecordBody(RD);
+      }
+      if (VD->getInit()) {
+        GlobalVarDecl = VD;
+        CurrentBody = VD->getInit();
+        RewriteFunctionBodyOrGlobalInitializer(VD->getInit());
+        CurrentBody = nullptr;
+        if (PropParentMap) {
+          delete PropParentMap;
+          PropParentMap = nullptr;
+        }
+        SynthesizeBlockLiterals(VD->getTypeSpecStartLoc(), VD->getName());
+        GlobalVarDecl = nullptr;
+
+        // This is needed for blocks.
+        if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(VD->getInit())) {
+            RewriteCastExpr(CE);
+        }
+      }
+      break;
+    }
+    case Decl::TypeAlias:
+    case Decl::Typedef: {
+      if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
+        if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
+          RewriteBlockPointerDecl(TD);
+        else if (TD->getUnderlyingType()->isFunctionPointerType())
+          CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
+        else
+          RewriteObjCQualifiedInterfaceTypes(TD);
+      }
+      break;
+    }
+    case Decl::CXXRecord:
+    case Decl::Record: {
+      RecordDecl *RD = cast<RecordDecl>(D);
+      if (RD->isCompleteDefinition()) 
+        RewriteRecordBody(RD);
+      break;
+    }
+    default:
+      break;
+  }
+  // Nothing yet.
+}
+
+/// Write_ProtocolExprReferencedMetadata - This routine writer out the
+/// protocol reference symbols in the for of:
+/// struct _protocol_t *PROTOCOL_REF = &PROTOCOL_METADATA.
+static void Write_ProtocolExprReferencedMetadata(ASTContext *Context, 
+                                                 ObjCProtocolDecl *PDecl,
+                                                 std::string &Result) {
+  // Also output .objc_protorefs$B section and its meta-data.
+  if (Context->getLangOpts().MicrosoftExt)
+    Result += "static ";
+  Result += "struct _protocol_t *";
+  Result += "_OBJC_PROTOCOL_REFERENCE_$_";
+  Result += PDecl->getNameAsString();
+  Result += " = &";
+  Result += "_OBJC_PROTOCOL_"; Result += PDecl->getNameAsString();
+  Result += ";\n";
+}
+
+void RewriteModernObjC::HandleTranslationUnit(ASTContext &C) {
+  if (Diags.hasErrorOccurred())
+    return;
+
+  RewriteInclude();
+
+  for (unsigned i = 0, e = FunctionDefinitionsSeen.size(); i < e; i++) {
+    // translation of function bodies were postponed until all class and
+    // their extensions and implementations are seen. This is because, we
+    // cannot build grouping structs for bitfields until they are all seen.
+    FunctionDecl *FDecl = FunctionDefinitionsSeen[i];
+    HandleTopLevelSingleDecl(FDecl);
+  }
+
+  // Here's a great place to add any extra declarations that may be needed.
+  // Write out meta data for each @protocol(<expr>).
+  for (llvm::SmallPtrSet<ObjCProtocolDecl *,8>::iterator I = ProtocolExprDecls.begin(),
+       E = ProtocolExprDecls.end(); I != E; ++I) {
+    RewriteObjCProtocolMetaData(*I, Preamble);
+    Write_ProtocolExprReferencedMetadata(Context, (*I), Preamble);
+  }
+
+  InsertText(SM->getLocForStartOfFile(MainFileID), Preamble, false);
+  
+  if (ClassImplementation.size() || CategoryImplementation.size())
+    RewriteImplementations();
+  
+  for (unsigned i = 0, e = ObjCInterfacesSeen.size(); i < e; i++) {
+    ObjCInterfaceDecl *CDecl = ObjCInterfacesSeen[i];
+    // Write struct declaration for the class matching its ivar declarations.
+    // Note that for modern abi, this is postponed until the end of TU
+    // because class extensions and the implementation might declare their own
+    // private ivars.
+    RewriteInterfaceDecl(CDecl);
+  }
+  
+  // Get the buffer corresponding to MainFileID.  If we haven't changed it, then
+  // we are done.
+  if (const RewriteBuffer *RewriteBuf =
+      Rewrite.getRewriteBufferFor(MainFileID)) {
+    //printf("Changed:\n");
+    *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end());
+  } else {
+    llvm::errs() << "No changes\n";
+  }
+
+  if (ClassImplementation.size() || CategoryImplementation.size() ||
+      ProtocolExprDecls.size()) {
+    // Rewrite Objective-c meta data*
+    std::string ResultStr;
+    RewriteMetaDataIntoBuffer(ResultStr);
+    // Emit metadata.
+    *OutFile << ResultStr;
+  }
+  // Emit ImageInfo;
+  {
+    std::string ResultStr;
+    WriteImageInfo(ResultStr);
+    *OutFile << ResultStr;
+  }
+  OutFile->flush();
+}
+
+void RewriteModernObjC::Initialize(ASTContext &context) {
+  InitializeCommon(context);
+  
+  Preamble += "#ifndef __OBJC2__\n";
+  Preamble += "#define __OBJC2__\n";
+  Preamble += "#endif\n";
+
+  // declaring objc_selector outside the parameter list removes a silly
+  // scope related warning...
+  if (IsHeader)
+    Preamble = "#pragma once\n";
+  Preamble += "struct objc_selector; struct objc_class;\n";
+  Preamble += "struct __rw_objc_super { \n\tstruct objc_object *object; ";
+  Preamble += "\n\tstruct objc_object *superClass; ";
+  // Add a constructor for creating temporary objects.
+  Preamble += "\n\t__rw_objc_super(struct objc_object *o, struct objc_object *s) ";
+  Preamble += ": object(o), superClass(s) {} ";
+  Preamble += "\n};\n";
+  
+  if (LangOpts.MicrosoftExt) {
+    // Define all sections using syntax that makes sense.
+    // These are currently generated.
+    Preamble += "\n#pragma section(\".objc_classlist$B\", long, read, write)\n";
+    Preamble += "#pragma section(\".objc_catlist$B\", long, read, write)\n";
+    Preamble += "#pragma section(\".objc_imageinfo$B\", long, read, write)\n";
+    Preamble += "#pragma section(\".objc_nlclslist$B\", long, read, write)\n";
+    Preamble += "#pragma section(\".objc_nlcatlist$B\", long, read, write)\n";
+    // These are generated but not necessary for functionality.
+    Preamble += "#pragma section(\".cat_cls_meth$B\", long, read, write)\n";
+    Preamble += "#pragma section(\".inst_meth$B\", long, read, write)\n";
+    Preamble += "#pragma section(\".cls_meth$B\", long, read, write)\n";
+    Preamble += "#pragma section(\".objc_ivar$B\", long, read, write)\n";
+    
+    // These need be generated for performance. Currently they are not,
+    // using API calls instead.
+    Preamble += "#pragma section(\".objc_selrefs$B\", long, read, write)\n";
+    Preamble += "#pragma section(\".objc_classrefs$B\", long, read, write)\n";
+    Preamble += "#pragma section(\".objc_superrefs$B\", long, read, write)\n";
+    
+  }
+  Preamble += "#ifndef _REWRITER_typedef_Protocol\n";
+  Preamble += "typedef struct objc_object Protocol;\n";
+  Preamble += "#define _REWRITER_typedef_Protocol\n";
+  Preamble += "#endif\n";
+  if (LangOpts.MicrosoftExt) {
+    Preamble += "#define __OBJC_RW_DLLIMPORT extern \"C\" __declspec(dllimport)\n";
+    Preamble += "#define __OBJC_RW_STATICIMPORT extern \"C\"\n";
+  } 
+  else
+    Preamble += "#define __OBJC_RW_DLLIMPORT extern\n";
+  
+  Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSend(void);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSendSuper(void);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSend_stret(void);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSendSuper_stret(void);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSend_fpret(void);\n";
+
+  Preamble += "__OBJC_RW_DLLIMPORT struct objc_class *objc_getClass";
+  Preamble += "(const char *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT struct objc_class *class_getSuperclass";
+  Preamble += "(struct objc_class *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT struct objc_class *objc_getMetaClass";
+  Preamble += "(const char *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_throw( struct objc_object *);\n";
+  // @synchronized hooks.
+  Preamble += "__OBJC_RW_DLLIMPORT int objc_sync_enter( struct objc_object *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT int objc_sync_exit( struct objc_object *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT Protocol *objc_getProtocol(const char *);\n";
+  Preamble += "#ifdef _WIN64\n";
+  Preamble += "typedef unsigned long long  _WIN_NSUInteger;\n";
+  Preamble += "#else\n";
+  Preamble += "typedef unsigned int _WIN_NSUInteger;\n";
+  Preamble += "#endif\n";
+  Preamble += "#ifndef __FASTENUMERATIONSTATE\n";
+  Preamble += "struct __objcFastEnumerationState {\n\t";
+  Preamble += "unsigned long state;\n\t";
+  Preamble += "void **itemsPtr;\n\t";
+  Preamble += "unsigned long *mutationsPtr;\n\t";
+  Preamble += "unsigned long extra[5];\n};\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void objc_enumerationMutation(struct objc_object *);\n";
+  Preamble += "#define __FASTENUMERATIONSTATE\n";
+  Preamble += "#endif\n";
+  Preamble += "#ifndef __NSCONSTANTSTRINGIMPL\n";
+  Preamble += "struct __NSConstantStringImpl {\n";
+  Preamble += "  int *isa;\n";
+  Preamble += "  int flags;\n";
+  Preamble += "  char *str;\n";
+  Preamble += "#if _WIN64\n";
+  Preamble += "  long long length;\n";
+  Preamble += "#else\n";
+  Preamble += "  long length;\n";
+  Preamble += "#endif\n";
+  Preamble += "};\n";
+  Preamble += "#ifdef CF_EXPORT_CONSTANT_STRING\n";
+  Preamble += "extern \"C\" __declspec(dllexport) int __CFConstantStringClassReference[];\n";
+  Preamble += "#else\n";
+  Preamble += "__OBJC_RW_DLLIMPORT int __CFConstantStringClassReference[];\n";
+  Preamble += "#endif\n";
+  Preamble += "#define __NSCONSTANTSTRINGIMPL\n";
+  Preamble += "#endif\n";
+  // Blocks preamble.
+  Preamble += "#ifndef BLOCK_IMPL\n";
+  Preamble += "#define BLOCK_IMPL\n";
+  Preamble += "struct __block_impl {\n";
+  Preamble += "  void *isa;\n";
+  Preamble += "  int Flags;\n";
+  Preamble += "  int Reserved;\n";
+  Preamble += "  void *FuncPtr;\n";
+  Preamble += "};\n";
+  Preamble += "// Runtime copy/destroy helper functions (from Block_private.h)\n";
+  Preamble += "#ifdef __OBJC_EXPORT_BLOCKS\n";
+  Preamble += "extern \"C\" __declspec(dllexport) "
+  "void _Block_object_assign(void *, const void *, const int);\n";
+  Preamble += "extern \"C\" __declspec(dllexport) void _Block_object_dispose(const void *, const int);\n";
+  Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];\n";
+  Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteStackBlock[32];\n";
+  Preamble += "#else\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void _Block_object_assign(void *, const void *, const int);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void _Block_object_dispose(const void *, const int);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void *_NSConcreteGlobalBlock[32];\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void *_NSConcreteStackBlock[32];\n";
+  Preamble += "#endif\n";
+  Preamble += "#endif\n";
+  if (LangOpts.MicrosoftExt) {
+    Preamble += "#undef __OBJC_RW_DLLIMPORT\n";
+    Preamble += "#undef __OBJC_RW_STATICIMPORT\n";
+    Preamble += "#ifndef KEEP_ATTRIBUTES\n";  // We use this for clang tests.
+    Preamble += "#define __attribute__(X)\n";
+    Preamble += "#endif\n";
+    Preamble += "#ifndef __weak\n";
+    Preamble += "#define __weak\n";
+    Preamble += "#endif\n";
+    Preamble += "#ifndef __block\n";
+    Preamble += "#define __block\n";
+    Preamble += "#endif\n";
+  }
+  else {
+    Preamble += "#define __block\n";
+    Preamble += "#define __weak\n";
+  }
+  
+  // Declarations required for modern objective-c array and dictionary literals.
+  Preamble += "\n#include <stdarg.h>\n";
+  Preamble += "struct __NSContainer_literal {\n";
+  Preamble += "  void * *arr;\n";
+  Preamble += "  __NSContainer_literal (unsigned int count, ...) {\n";
+  Preamble += "\tva_list marker;\n";
+  Preamble += "\tva_start(marker, count);\n";
+  Preamble += "\tarr = new void *[count];\n";
+  Preamble += "\tfor (unsigned i = 0; i < count; i++)\n";
+  Preamble += "\t  arr[i] = va_arg(marker, void *);\n";
+  Preamble += "\tva_end( marker );\n";
+  Preamble += "  };\n";
+  Preamble += "  ~__NSContainer_literal() {\n";
+  Preamble += "\tdelete[] arr;\n";
+  Preamble += "  }\n";
+  Preamble += "};\n";
+  
+  // Declaration required for implementation of @autoreleasepool statement.
+  Preamble += "extern \"C\" __declspec(dllimport) void * objc_autoreleasePoolPush(void);\n";
+  Preamble += "extern \"C\" __declspec(dllimport) void objc_autoreleasePoolPop(void *);\n\n";
+  Preamble += "struct __AtAutoreleasePool {\n";
+  Preamble += "  __AtAutoreleasePool() {atautoreleasepoolobj = objc_autoreleasePoolPush();}\n";
+  Preamble += "  ~__AtAutoreleasePool() {objc_autoreleasePoolPop(atautoreleasepoolobj);}\n";
+  Preamble += "  void * atautoreleasepoolobj;\n";
+  Preamble += "};\n";
+  
+  // NOTE! Windows uses LLP64 for 64bit mode. So, cast pointer to long long
+  // as this avoids warning in any 64bit/32bit compilation model.
+  Preamble += "\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n";
+}
+
+/// RewriteIvarOffsetComputation - This rutine synthesizes computation of
+/// ivar offset.
+void RewriteModernObjC::RewriteIvarOffsetComputation(ObjCIvarDecl *ivar,
+                                                         std::string &Result) {
+  Result += "__OFFSETOFIVAR__(struct ";
+  Result += ivar->getContainingInterface()->getNameAsString();
+  if (LangOpts.MicrosoftExt)
+    Result += "_IMPL";
+  Result += ", ";
+  if (ivar->isBitField())
+    ObjCIvarBitfieldGroupDecl(ivar, Result);
+  else
+    Result += ivar->getNameAsString();
+  Result += ")";
+}
+
+/// WriteModernMetadataDeclarations - Writes out metadata declarations for modern ABI.
+/// struct _prop_t {
+///   const char *name;
+///   char *attributes;
+/// }
+
+/// struct _prop_list_t {
+///   uint32_t entsize;      // sizeof(struct _prop_t)
+///   uint32_t count_of_properties;
+///   struct _prop_t prop_list[count_of_properties];
+/// }
+
+/// struct _protocol_t;
+
+/// struct _protocol_list_t {
+///   long protocol_count;   // Note, this is 32/64 bit
+///   struct _protocol_t * protocol_list[protocol_count];
+/// }
+
+/// struct _objc_method {
+///   SEL _cmd;
+///   const char *method_type;
+///   char *_imp;
+/// }
+
+/// struct _method_list_t {
+///   uint32_t entsize;  // sizeof(struct _objc_method)
+///   uint32_t method_count;
+///   struct _objc_method method_list[method_count];
+/// }
+
+/// struct _protocol_t {
+///   id isa;  // NULL
+///   const char *protocol_name;
+///   const struct _protocol_list_t * protocol_list; // super protocols
+///   const struct method_list_t *instance_methods;
+///   const struct method_list_t *class_methods;
+///   const struct method_list_t *optionalInstanceMethods;
+///   const struct method_list_t *optionalClassMethods;
+///   const struct _prop_list_t * properties;
+///   const uint32_t size;  // sizeof(struct _protocol_t)
+///   const uint32_t flags;  // = 0
+///   const char ** extendedMethodTypes;
+/// }
+
+/// struct _ivar_t {
+///   unsigned long int *offset;  // pointer to ivar offset location
+///   const char *name;
+///   const char *type;
+///   uint32_t alignment;
+///   uint32_t size;
+/// }
+
+/// struct _ivar_list_t {
+///   uint32 entsize;  // sizeof(struct _ivar_t)
+///   uint32 count;
+///   struct _ivar_t list[count];
+/// }
+
+/// struct _class_ro_t {
+///   uint32_t flags;
+///   uint32_t instanceStart;
+///   uint32_t instanceSize;
+///   uint32_t reserved;  // only when building for 64bit targets
+///   const uint8_t *ivarLayout;
+///   const char *name;
+///   const struct _method_list_t *baseMethods;
+///   const struct _protocol_list_t *baseProtocols;
+///   const struct _ivar_list_t *ivars;
+///   const uint8_t *weakIvarLayout;
+///   const struct _prop_list_t *properties;
+/// }
+
+/// struct _class_t {
+///   struct _class_t *isa;
+///   struct _class_t *superclass;
+///   void *cache;
+///   IMP *vtable;
+///   struct _class_ro_t *ro;
+/// }
+
+/// struct _category_t {
+///   const char *name;
+///   struct _class_t *cls;
+///   const struct _method_list_t *instance_methods;
+///   const struct _method_list_t *class_methods;
+///   const struct _protocol_list_t *protocols;
+///   const struct _prop_list_t *properties;
+/// }
+
+/// MessageRefTy - LLVM for:
+/// struct _message_ref_t {
+///   IMP messenger;
+///   SEL name;
+/// };
+
+/// SuperMessageRefTy - LLVM for:
+/// struct _super_message_ref_t {
+///   SUPER_IMP messenger;
+///   SEL name;
+/// };
+
+static void WriteModernMetadataDeclarations(ASTContext *Context, std::string &Result) {
+  static bool meta_data_declared = false;
+  if (meta_data_declared)
+    return;
+  
+  Result += "\nstruct _prop_t {\n";
+  Result += "\tconst char *name;\n";
+  Result += "\tconst char *attributes;\n";
+  Result += "};\n";
+  
+  Result += "\nstruct _protocol_t;\n";
+  
+  Result += "\nstruct _objc_method {\n";
+  Result += "\tstruct objc_selector * _cmd;\n";
+  Result += "\tconst char *method_type;\n";
+  Result += "\tvoid  *_imp;\n";
+  Result += "};\n";
+  
+  Result += "\nstruct _protocol_t {\n";
+  Result += "\tvoid * isa;  // NULL\n";
+  Result += "\tconst char *protocol_name;\n";
+  Result += "\tconst struct _protocol_list_t * protocol_list; // super protocols\n";
+  Result += "\tconst struct method_list_t *instance_methods;\n";
+  Result += "\tconst struct method_list_t *class_methods;\n";
+  Result += "\tconst struct method_list_t *optionalInstanceMethods;\n";
+  Result += "\tconst struct method_list_t *optionalClassMethods;\n";
+  Result += "\tconst struct _prop_list_t * properties;\n";
+  Result += "\tconst unsigned int size;  // sizeof(struct _protocol_t)\n";
+  Result += "\tconst unsigned int flags;  // = 0\n";
+  Result += "\tconst char ** extendedMethodTypes;\n";
+  Result += "};\n";
+  
+  Result += "\nstruct _ivar_t {\n";
+  Result += "\tunsigned long int *offset;  // pointer to ivar offset location\n";
+  Result += "\tconst char *name;\n";
+  Result += "\tconst char *type;\n";
+  Result += "\tunsigned int alignment;\n";
+  Result += "\tunsigned int  size;\n";
+  Result += "};\n";
+  
+  Result += "\nstruct _class_ro_t {\n";
+  Result += "\tunsigned int flags;\n";
+  Result += "\tunsigned int instanceStart;\n";
+  Result += "\tunsigned int instanceSize;\n";
+  const llvm::Triple &Triple(Context->getTargetInfo().getTriple());
+  if (Triple.getArch() == llvm::Triple::x86_64)
+    Result += "\tunsigned int reserved;\n";
+  Result += "\tconst unsigned char *ivarLayout;\n";
+  Result += "\tconst char *name;\n";
+  Result += "\tconst struct _method_list_t *baseMethods;\n";
+  Result += "\tconst struct _objc_protocol_list *baseProtocols;\n";
+  Result += "\tconst struct _ivar_list_t *ivars;\n";
+  Result += "\tconst unsigned char *weakIvarLayout;\n";
+  Result += "\tconst struct _prop_list_t *properties;\n";
+  Result += "};\n";
+  
+  Result += "\nstruct _class_t {\n";
+  Result += "\tstruct _class_t *isa;\n";
+  Result += "\tstruct _class_t *superclass;\n";
+  Result += "\tvoid *cache;\n";
+  Result += "\tvoid *vtable;\n";
+  Result += "\tstruct _class_ro_t *ro;\n";
+  Result += "};\n";
+  
+  Result += "\nstruct _category_t {\n";
+  Result += "\tconst char *name;\n";
+  Result += "\tstruct _class_t *cls;\n";
+  Result += "\tconst struct _method_list_t *instance_methods;\n";
+  Result += "\tconst struct _method_list_t *class_methods;\n";
+  Result += "\tconst struct _protocol_list_t *protocols;\n";
+  Result += "\tconst struct _prop_list_t *properties;\n";
+  Result += "};\n";
+  
+  Result += "extern \"C\" __declspec(dllimport) struct objc_cache _objc_empty_cache;\n";
+  Result += "#pragma warning(disable:4273)\n";
+  meta_data_declared = true;
+}
+
+static void Write_protocol_list_t_TypeDecl(std::string &Result,
+                                           long super_protocol_count) {
+  Result += "struct /*_protocol_list_t*/"; Result += " {\n";
+  Result += "\tlong protocol_count;  // Note, this is 32/64 bit\n";
+  Result += "\tstruct _protocol_t *super_protocols[";
+  Result += utostr(super_protocol_count); Result += "];\n";
+  Result += "}";
+}
+
+static void Write_method_list_t_TypeDecl(std::string &Result,
+                                         unsigned int method_count) {
+  Result += "struct /*_method_list_t*/"; Result += " {\n";
+  Result += "\tunsigned int entsize;  // sizeof(struct _objc_method)\n";
+  Result += "\tunsigned int method_count;\n";
+  Result += "\tstruct _objc_method method_list[";
+  Result += utostr(method_count); Result += "];\n";
+  Result += "}";
+}
+
+static void Write__prop_list_t_TypeDecl(std::string &Result,
+                                        unsigned int property_count) {
+  Result += "struct /*_prop_list_t*/"; Result += " {\n";
+  Result += "\tunsigned int entsize;  // sizeof(struct _prop_t)\n";
+  Result += "\tunsigned int count_of_properties;\n";
+  Result += "\tstruct _prop_t prop_list[";
+  Result += utostr(property_count); Result += "];\n";
+  Result += "}";
+}
+
+static void Write__ivar_list_t_TypeDecl(std::string &Result,
+                                        unsigned int ivar_count) {
+  Result += "struct /*_ivar_list_t*/"; Result += " {\n";
+  Result += "\tunsigned int entsize;  // sizeof(struct _prop_t)\n";
+  Result += "\tunsigned int count;\n";
+  Result += "\tstruct _ivar_t ivar_list[";
+  Result += utostr(ivar_count); Result += "];\n";
+  Result += "}";
+}
+
+static void Write_protocol_list_initializer(ASTContext *Context, std::string &Result,
+                                            ArrayRef<ObjCProtocolDecl *> SuperProtocols,
+                                            StringRef VarName,
+                                            StringRef ProtocolName) {
+  if (SuperProtocols.size() > 0) {
+    Result += "\nstatic ";
+    Write_protocol_list_t_TypeDecl(Result, SuperProtocols.size());
+    Result += " "; Result += VarName;
+    Result += ProtocolName; 
+    Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
+    Result += "\t"; Result += utostr(SuperProtocols.size()); Result += ",\n";
+    for (unsigned i = 0, e = SuperProtocols.size(); i < e; i++) {
+      ObjCProtocolDecl *SuperPD = SuperProtocols[i];
+      Result += "\t&"; Result += "_OBJC_PROTOCOL_"; 
+      Result += SuperPD->getNameAsString();
+      if (i == e-1)
+        Result += "\n};\n";
+      else
+        Result += ",\n";
+    }
+  }
+}
+
+static void Write_method_list_t_initializer(RewriteModernObjC &RewriteObj,
+                                            ASTContext *Context, std::string &Result,
+                                            ArrayRef<ObjCMethodDecl *> Methods,
+                                            StringRef VarName,
+                                            StringRef TopLevelDeclName,
+                                            bool MethodImpl) {
+  if (Methods.size() > 0) {
+    Result += "\nstatic ";
+    Write_method_list_t_TypeDecl(Result, Methods.size());
+    Result += " "; Result += VarName;
+    Result += TopLevelDeclName; 
+    Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
+    Result += "\t"; Result += "sizeof(_objc_method)"; Result += ",\n";
+    Result += "\t"; Result += utostr(Methods.size()); Result += ",\n";
+    for (unsigned i = 0, e = Methods.size(); i < e; i++) {
+      ObjCMethodDecl *MD = Methods[i];
+      if (i == 0)
+        Result += "\t{{(struct objc_selector *)\"";
+      else
+        Result += "\t{(struct objc_selector *)\"";
+      Result += (MD)->getSelector().getAsString(); Result += "\"";
+      Result += ", ";
+      std::string MethodTypeString;
+      Context->getObjCEncodingForMethodDecl(MD, MethodTypeString);
+      Result += "\""; Result += MethodTypeString; Result += "\"";
+      Result += ", ";
+      if (!MethodImpl)
+        Result += "0";
+      else {
+        Result += "(void *)";
+        Result += RewriteObj.MethodInternalNames[MD];
+      }
+      if (i  == e-1)
+        Result += "}}\n";
+      else
+        Result += "},\n";
+    }
+    Result += "};\n";
+  }
+}
+
+static void Write_prop_list_t_initializer(RewriteModernObjC &RewriteObj,
+                                           ASTContext *Context, std::string &Result,
+                                           ArrayRef<ObjCPropertyDecl *> Properties,
+                                           const Decl *Container,
+                                           StringRef VarName,
+                                           StringRef ProtocolName) {
+  if (Properties.size() > 0) {
+    Result += "\nstatic ";
+    Write__prop_list_t_TypeDecl(Result, Properties.size());
+    Result += " "; Result += VarName;
+    Result += ProtocolName; 
+    Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
+    Result += "\t"; Result += "sizeof(_prop_t)"; Result += ",\n";
+    Result += "\t"; Result += utostr(Properties.size()); Result += ",\n";
+    for (unsigned i = 0, e = Properties.size(); i < e; i++) {
+      ObjCPropertyDecl *PropDecl = Properties[i];
+      if (i == 0)
+        Result += "\t{{\"";
+      else
+        Result += "\t{\"";
+      Result += PropDecl->getName(); Result += "\",";
+      std::string PropertyTypeString, QuotePropertyTypeString;
+      Context->getObjCEncodingForPropertyDecl(PropDecl, Container, PropertyTypeString);
+      RewriteObj.QuoteDoublequotes(PropertyTypeString, QuotePropertyTypeString);
+      Result += "\""; Result += QuotePropertyTypeString; Result += "\"";
+      if (i  == e-1)
+        Result += "}}\n";
+      else
+        Result += "},\n";
+    }
+    Result += "};\n";
+  }
+}
+
+// Metadata flags
+enum MetaDataDlags {
+  CLS = 0x0,
+  CLS_META = 0x1,
+  CLS_ROOT = 0x2,
+  OBJC2_CLS_HIDDEN = 0x10,
+  CLS_EXCEPTION = 0x20,
+  
+  /// (Obsolete) ARC-specific: this class has a .release_ivars method
+  CLS_HAS_IVAR_RELEASER = 0x40,
+  /// class was compiled with -fobjc-arr
+  CLS_COMPILED_BY_ARC = 0x80  // (1<<7)
+};
+
+static void Write__class_ro_t_initializer(ASTContext *Context, std::string &Result, 
+                                          unsigned int flags, 
+                                          const std::string &InstanceStart, 
+                                          const std::string &InstanceSize,
+                                          ArrayRef<ObjCMethodDecl *>baseMethods,
+                                          ArrayRef<ObjCProtocolDecl *>baseProtocols,
+                                          ArrayRef<ObjCIvarDecl *>ivars,
+                                          ArrayRef<ObjCPropertyDecl *>Properties,
+                                          StringRef VarName,
+                                          StringRef ClassName) {
+  Result += "\nstatic struct _class_ro_t ";
+  Result += VarName; Result += ClassName;
+  Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
+  Result += "\t"; 
+  Result += llvm::utostr(flags); Result += ", "; 
+  Result += InstanceStart; Result += ", ";
+  Result += InstanceSize; Result += ", \n";
+  Result += "\t";
+  const llvm::Triple &Triple(Context->getTargetInfo().getTriple());
+  if (Triple.getArch() == llvm::Triple::x86_64)
+    // uint32_t const reserved; // only when building for 64bit targets
+    Result += "(unsigned int)0, \n\t";
+  // const uint8_t * const ivarLayout;
+  Result += "0, \n\t";
+  Result += "\""; Result += ClassName; Result += "\",\n\t";
+  bool metaclass = ((flags & CLS_META) != 0);
+  if (baseMethods.size() > 0) {
+    Result += "(const struct _method_list_t *)&";
+    if (metaclass)
+      Result += "_OBJC_$_CLASS_METHODS_";
+    else
+      Result += "_OBJC_$_INSTANCE_METHODS_";
+    Result += ClassName;
+    Result += ",\n\t";
+  }
+  else
+    Result += "0, \n\t";
+
+  if (!metaclass && baseProtocols.size() > 0) {
+    Result += "(const struct _objc_protocol_list *)&";
+    Result += "_OBJC_CLASS_PROTOCOLS_$_"; Result += ClassName;
+    Result += ",\n\t";
+  }
+  else
+    Result += "0, \n\t";
+
+  if (!metaclass && ivars.size() > 0) {
+    Result += "(const struct _ivar_list_t *)&";
+    Result += "_OBJC_$_INSTANCE_VARIABLES_"; Result += ClassName;
+    Result += ",\n\t";
+  }
+  else
+    Result += "0, \n\t";
+
+  // weakIvarLayout
+  Result += "0, \n\t";
+  if (!metaclass && Properties.size() > 0) {
+    Result += "(const struct _prop_list_t *)&";
+    Result += "_OBJC_$_PROP_LIST_"; Result += ClassName;
+    Result += ",\n";
+  }
+  else
+    Result += "0, \n";
+
+  Result += "};\n";
+}
+
+static void Write_class_t(ASTContext *Context, std::string &Result,
+                          StringRef VarName,
+                          const ObjCInterfaceDecl *CDecl, bool metaclass) {
+  bool rootClass = (!CDecl->getSuperClass());
+  const ObjCInterfaceDecl *RootClass = CDecl;
+  
+  if (!rootClass) {
+    // Find the Root class
+    RootClass = CDecl->getSuperClass();
+    while (RootClass->getSuperClass()) {
+      RootClass = RootClass->getSuperClass();
+    }
+  }
+
+  if (metaclass && rootClass) {
+    // Need to handle a case of use of forward declaration.
+    Result += "\n";
+    Result += "extern \"C\" ";
+    if (CDecl->getImplementation())
+      Result += "__declspec(dllexport) ";
+    else
+      Result += "__declspec(dllimport) ";
+    
+    Result += "struct _class_t OBJC_CLASS_$_";
+    Result += CDecl->getNameAsString();
+    Result += ";\n";
+  }
+  // Also, for possibility of 'super' metadata class not having been defined yet.
+  if (!rootClass) {
+    ObjCInterfaceDecl *SuperClass = CDecl->getSuperClass();
+    Result += "\n";
+    Result += "extern \"C\" ";
+    if (SuperClass->getImplementation())
+      Result += "__declspec(dllexport) ";
+    else
+      Result += "__declspec(dllimport) ";
+
+    Result += "struct _class_t "; 
+    Result += VarName;
+    Result += SuperClass->getNameAsString();
+    Result += ";\n";
+    
+    if (metaclass && RootClass != SuperClass) {
+      Result += "extern \"C\" ";
+      if (RootClass->getImplementation())
+        Result += "__declspec(dllexport) ";
+      else
+        Result += "__declspec(dllimport) ";
+
+      Result += "struct _class_t "; 
+      Result += VarName;
+      Result += RootClass->getNameAsString();
+      Result += ";\n";
+    }
+  }
+  
+  Result += "\nextern \"C\" __declspec(dllexport) struct _class_t "; 
+  Result += VarName; Result += CDecl->getNameAsString();
+  Result += " __attribute__ ((used, section (\"__DATA,__objc_data\"))) = {\n";
+  Result += "\t";
+  if (metaclass) {
+    if (!rootClass) {
+      Result += "0, // &"; Result += VarName;
+      Result += RootClass->getNameAsString();
+      Result += ",\n\t";
+      Result += "0, // &"; Result += VarName;
+      Result += CDecl->getSuperClass()->getNameAsString();
+      Result += ",\n\t";
+    }
+    else {
+      Result += "0, // &"; Result += VarName; 
+      Result += CDecl->getNameAsString();
+      Result += ",\n\t";
+      Result += "0, // &OBJC_CLASS_$_"; Result += CDecl->getNameAsString();
+      Result += ",\n\t";
+    }
+  }
+  else {
+    Result += "0, // &OBJC_METACLASS_$_"; 
+    Result += CDecl->getNameAsString();
+    Result += ",\n\t";
+    if (!rootClass) {
+      Result += "0, // &"; Result += VarName;
+      Result += CDecl->getSuperClass()->getNameAsString();
+      Result += ",\n\t";
+    }
+    else 
+      Result += "0,\n\t";
+  }
+  Result += "0, // (void *)&_objc_empty_cache,\n\t";
+  Result += "0, // unused, was (void *)&_objc_empty_vtable,\n\t";
+  if (metaclass)
+    Result += "&_OBJC_METACLASS_RO_$_";
+  else
+    Result += "&_OBJC_CLASS_RO_$_";
+  Result += CDecl->getNameAsString();
+  Result += ",\n};\n";
+  
+  // Add static function to initialize some of the meta-data fields.
+  // avoid doing it twice.
+  if (metaclass)
+    return;
+  
+  const ObjCInterfaceDecl *SuperClass = 
+    rootClass ? CDecl : CDecl->getSuperClass();
+  
+  Result += "static void OBJC_CLASS_SETUP_$_";
+  Result += CDecl->getNameAsString();
+  Result += "(void ) {\n";
+  Result += "\tOBJC_METACLASS_$_"; Result += CDecl->getNameAsString();
+  Result += ".isa = "; Result += "&OBJC_METACLASS_$_";
+  Result += RootClass->getNameAsString(); Result += ";\n";
+  
+  Result += "\tOBJC_METACLASS_$_"; Result += CDecl->getNameAsString();
+  Result += ".superclass = ";
+  if (rootClass)
+    Result += "&OBJC_CLASS_$_";
+  else
+     Result += "&OBJC_METACLASS_$_";
+
+  Result += SuperClass->getNameAsString(); Result += ";\n";
+  
+  Result += "\tOBJC_METACLASS_$_"; Result += CDecl->getNameAsString();
+  Result += ".cache = "; Result += "&_objc_empty_cache"; Result += ";\n";
+  
+  Result += "\tOBJC_CLASS_$_"; Result += CDecl->getNameAsString();
+  Result += ".isa = "; Result += "&OBJC_METACLASS_$_";
+  Result += CDecl->getNameAsString(); Result += ";\n";
+  
+  if (!rootClass) {
+    Result += "\tOBJC_CLASS_$_"; Result += CDecl->getNameAsString();
+    Result += ".superclass = "; Result += "&OBJC_CLASS_$_";
+    Result += SuperClass->getNameAsString(); Result += ";\n";
+  }
+  
+  Result += "\tOBJC_CLASS_$_"; Result += CDecl->getNameAsString();
+  Result += ".cache = "; Result += "&_objc_empty_cache"; Result += ";\n";
+  Result += "}\n";
+}
+
+static void Write_category_t(RewriteModernObjC &RewriteObj, ASTContext *Context, 
+                             std::string &Result,
+                             ObjCCategoryDecl *CatDecl,
+                             ObjCInterfaceDecl *ClassDecl,
+                             ArrayRef<ObjCMethodDecl *> InstanceMethods,
+                             ArrayRef<ObjCMethodDecl *> ClassMethods,
+                             ArrayRef<ObjCProtocolDecl *> RefedProtocols,
+                             ArrayRef<ObjCPropertyDecl *> ClassProperties) {
+  StringRef CatName = CatDecl->getName();
+  StringRef ClassName = ClassDecl->getName();
+  // must declare an extern class object in case this class is not implemented 
+  // in this TU.
+  Result += "\n";
+  Result += "extern \"C\" ";
+  if (ClassDecl->getImplementation())
+    Result += "__declspec(dllexport) ";
+  else
+    Result += "__declspec(dllimport) ";
+  
+  Result += "struct _class_t ";
+  Result += "OBJC_CLASS_$_"; Result += ClassName;
+  Result += ";\n";
+  
+  Result += "\nstatic struct _category_t ";
+  Result += "_OBJC_$_CATEGORY_";
+  Result += ClassName; Result += "_$_"; Result += CatName;
+  Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
+  Result += "{\n";
+  Result += "\t\""; Result += ClassName; Result += "\",\n";
+  Result += "\t0, // &"; Result += "OBJC_CLASS_$_"; Result += ClassName;
+  Result += ",\n";
+  if (InstanceMethods.size() > 0) {
+    Result += "\t(const struct _method_list_t *)&";  
+    Result += "_OBJC_$_CATEGORY_INSTANCE_METHODS_";
+    Result += ClassName; Result += "_$_"; Result += CatName;
+    Result += ",\n";
+  }
+  else
+    Result += "\t0,\n";
+  
+  if (ClassMethods.size() > 0) {
+    Result += "\t(const struct _method_list_t *)&";  
+    Result += "_OBJC_$_CATEGORY_CLASS_METHODS_";
+    Result += ClassName; Result += "_$_"; Result += CatName;
+    Result += ",\n";
+  }
+  else
+    Result += "\t0,\n";
+  
+  if (RefedProtocols.size() > 0) {
+    Result += "\t(const struct _protocol_list_t *)&";  
+    Result += "_OBJC_CATEGORY_PROTOCOLS_$_";
+    Result += ClassName; Result += "_$_"; Result += CatName;
+    Result += ",\n";
+  }
+  else
+    Result += "\t0,\n";
+  
+  if (ClassProperties.size() > 0) {
+    Result += "\t(const struct _prop_list_t *)&";  Result += "_OBJC_$_PROP_LIST_";
+    Result += ClassName; Result += "_$_"; Result += CatName;
+    Result += ",\n";
+  }
+  else
+    Result += "\t0,\n";
+  
+  Result += "};\n";
+  
+  // Add static function to initialize the class pointer in the category structure.
+  Result += "static void OBJC_CATEGORY_SETUP_$_";
+  Result += ClassDecl->getNameAsString();
+  Result += "_$_";
+  Result += CatName;
+  Result += "(void ) {\n";
+  Result += "\t_OBJC_$_CATEGORY_"; 
+  Result += ClassDecl->getNameAsString();
+  Result += "_$_";
+  Result += CatName;
+  Result += ".cls = "; Result += "&OBJC_CLASS_$_"; Result += ClassName;
+  Result += ";\n}\n";
+}
+
+static void Write__extendedMethodTypes_initializer(RewriteModernObjC &RewriteObj,
+                                           ASTContext *Context, std::string &Result,
+                                           ArrayRef<ObjCMethodDecl *> Methods,
+                                           StringRef VarName,
+                                           StringRef ProtocolName) {
+  if (Methods.size() == 0)
+    return;
+  
+  Result += "\nstatic const char *";
+  Result += VarName; Result += ProtocolName;
+  Result += " [] __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
+  Result += "{\n";
+  for (unsigned i = 0, e = Methods.size(); i < e; i++) {
+    ObjCMethodDecl *MD = Methods[i];
+    std::string MethodTypeString, QuoteMethodTypeString;
+    Context->getObjCEncodingForMethodDecl(MD, MethodTypeString, true);
+    RewriteObj.QuoteDoublequotes(MethodTypeString, QuoteMethodTypeString);
+    Result += "\t\""; Result += QuoteMethodTypeString; Result += "\"";
+    if (i == e-1)
+      Result += "\n};\n";
+    else {
+      Result += ",\n";
+    }
+  }
+}
+
+static void Write_IvarOffsetVar(RewriteModernObjC &RewriteObj,
+                                ASTContext *Context,
+                                std::string &Result, 
+                                ArrayRef<ObjCIvarDecl *> Ivars, 
+                                ObjCInterfaceDecl *CDecl) {
+  // FIXME. visibilty of offset symbols may have to be set; for Darwin
+  // this is what happens:
+  /**
+   if (Ivar->getAccessControl() == ObjCIvarDecl::Private ||
+       Ivar->getAccessControl() == ObjCIvarDecl::Package ||
+       Class->getVisibility() == HiddenVisibility)
+     Visibility shoud be: HiddenVisibility;
+   else
+     Visibility shoud be: DefaultVisibility;
+  */
+  
+  Result += "\n";
+  for (unsigned i =0, e = Ivars.size(); i < e; i++) {
+    ObjCIvarDecl *IvarDecl = Ivars[i];
+    if (Context->getLangOpts().MicrosoftExt)
+      Result += "__declspec(allocate(\".objc_ivar$B\")) ";
+    
+    if (!Context->getLangOpts().MicrosoftExt ||
+        IvarDecl->getAccessControl() == ObjCIvarDecl::Private ||
+        IvarDecl->getAccessControl() == ObjCIvarDecl::Package)
+      Result += "extern \"C\" unsigned long int "; 
+    else
+      Result += "extern \"C\" __declspec(dllexport) unsigned long int ";
+    if (Ivars[i]->isBitField())
+      RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
+    else
+      WriteInternalIvarName(CDecl, IvarDecl, Result);
+    Result += " __attribute__ ((used, section (\"__DATA,__objc_ivar\")))";
+    Result += " = ";
+    RewriteObj.RewriteIvarOffsetComputation(IvarDecl, Result);
+    Result += ";\n";
+    if (Ivars[i]->isBitField()) {
+      // skip over rest of the ivar bitfields.
+      SKIP_BITFIELDS(i , e, Ivars);
+    }
+  }
+}
+
+static void Write__ivar_list_t_initializer(RewriteModernObjC &RewriteObj,
+                                           ASTContext *Context, std::string &Result,
+                                           ArrayRef<ObjCIvarDecl *> OriginalIvars,
+                                           StringRef VarName,
+                                           ObjCInterfaceDecl *CDecl) {
+  if (OriginalIvars.size() > 0) {
+    Write_IvarOffsetVar(RewriteObj, Context, Result, OriginalIvars, CDecl);
+    SmallVector<ObjCIvarDecl *, 8> Ivars;
+    // strip off all but the first ivar bitfield from each group of ivars.
+    // Such ivars in the ivar list table will be replaced by their grouping struct
+    // 'ivar'.
+    for (unsigned i = 0, e = OriginalIvars.size(); i < e; i++) {
+      if (OriginalIvars[i]->isBitField()) {
+        Ivars.push_back(OriginalIvars[i]);
+        // skip over rest of the ivar bitfields.
+        SKIP_BITFIELDS(i , e, OriginalIvars);
+      }
+      else
+        Ivars.push_back(OriginalIvars[i]);
+    }
+    
+    Result += "\nstatic ";
+    Write__ivar_list_t_TypeDecl(Result, Ivars.size());
+    Result += " "; Result += VarName;
+    Result += CDecl->getNameAsString();
+    Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
+    Result += "\t"; Result += "sizeof(_ivar_t)"; Result += ",\n";
+    Result += "\t"; Result += utostr(Ivars.size()); Result += ",\n";
+    for (unsigned i =0, e = Ivars.size(); i < e; i++) {
+      ObjCIvarDecl *IvarDecl = Ivars[i];
+      if (i == 0)
+        Result += "\t{{";
+      else
+        Result += "\t {";
+      Result += "(unsigned long int *)&";
+      if (Ivars[i]->isBitField())
+        RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
+      else
+        WriteInternalIvarName(CDecl, IvarDecl, Result);
+      Result += ", ";
+      
+      Result += "\"";
+      if (Ivars[i]->isBitField())
+        RewriteObj.ObjCIvarBitfieldGroupDecl(Ivars[i], Result);
+      else
+        Result += IvarDecl->getName();
+      Result += "\", ";
+      
+      QualType IVQT = IvarDecl->getType();
+      if (IvarDecl->isBitField())
+        IVQT = RewriteObj.GetGroupRecordTypeForObjCIvarBitfield(IvarDecl);
+      
+      std::string IvarTypeString, QuoteIvarTypeString;
+      Context->getObjCEncodingForType(IVQT, IvarTypeString,
+                                      IvarDecl);
+      RewriteObj.QuoteDoublequotes(IvarTypeString, QuoteIvarTypeString);
+      Result += "\""; Result += QuoteIvarTypeString; Result += "\", ";
+      
+      // FIXME. this alignment represents the host alignment and need be changed to
+      // represent the target alignment.
+      unsigned Align = Context->getTypeAlign(IVQT)/8;
+      Align = llvm::Log2_32(Align);
+      Result += llvm::utostr(Align); Result += ", ";
+      CharUnits Size = Context->getTypeSizeInChars(IVQT);
+      Result += llvm::utostr(Size.getQuantity());
+      if (i  == e-1)
+        Result += "}}\n";
+      else
+        Result += "},\n";
+    }
+    Result += "};\n";
+  }
+}
+
+/// RewriteObjCProtocolMetaData - Rewrite protocols meta-data.
+void RewriteModernObjC::RewriteObjCProtocolMetaData(ObjCProtocolDecl *PDecl, 
+                                                    std::string &Result) {
+  
+  // Do not synthesize the protocol more than once.
+  if (ObjCSynthesizedProtocols.count(PDecl->getCanonicalDecl()))
+    return;
+  WriteModernMetadataDeclarations(Context, Result);
+  
+  if (ObjCProtocolDecl *Def = PDecl->getDefinition())
+    PDecl = Def;
+  // Must write out all protocol definitions in current qualifier list,
+  // and in their nested qualifiers before writing out current definition.
+  for (auto *I : PDecl->protocols())
+    RewriteObjCProtocolMetaData(I, Result);
+  
+  // Construct method lists.
+  std::vector<ObjCMethodDecl *> InstanceMethods, ClassMethods;
+  std::vector<ObjCMethodDecl *> OptInstanceMethods, OptClassMethods;
+  for (auto *MD : PDecl->instance_methods()) {
+    if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
+      OptInstanceMethods.push_back(MD);
+    } else {
+      InstanceMethods.push_back(MD);
+    }
+  }
+  
+  for (auto *MD : PDecl->class_methods()) {
+    if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
+      OptClassMethods.push_back(MD);
+    } else {
+      ClassMethods.push_back(MD);
+    }
+  }
+  std::vector<ObjCMethodDecl *> AllMethods;
+  for (unsigned i = 0, e = InstanceMethods.size(); i < e; i++)
+    AllMethods.push_back(InstanceMethods[i]);
+  for (unsigned i = 0, e = ClassMethods.size(); i < e; i++)
+    AllMethods.push_back(ClassMethods[i]);
+  for (unsigned i = 0, e = OptInstanceMethods.size(); i < e; i++)
+    AllMethods.push_back(OptInstanceMethods[i]);
+  for (unsigned i = 0, e = OptClassMethods.size(); i < e; i++)
+    AllMethods.push_back(OptClassMethods[i]);
+
+  Write__extendedMethodTypes_initializer(*this, Context, Result,
+                                         AllMethods,
+                                         "_OBJC_PROTOCOL_METHOD_TYPES_",
+                                         PDecl->getNameAsString());
+  // Protocol's super protocol list
+  SmallVector<ObjCProtocolDecl *, 8> SuperProtocols(PDecl->protocols());  
+  Write_protocol_list_initializer(Context, Result, SuperProtocols,
+                                  "_OBJC_PROTOCOL_REFS_",
+                                  PDecl->getNameAsString());
+  
+  Write_method_list_t_initializer(*this, Context, Result, InstanceMethods, 
+                                  "_OBJC_PROTOCOL_INSTANCE_METHODS_",
+                                  PDecl->getNameAsString(), false);
+  
+  Write_method_list_t_initializer(*this, Context, Result, ClassMethods, 
+                                  "_OBJC_PROTOCOL_CLASS_METHODS_",
+                                  PDecl->getNameAsString(), false);
+
+  Write_method_list_t_initializer(*this, Context, Result, OptInstanceMethods, 
+                                  "_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_",
+                                  PDecl->getNameAsString(), false);
+  
+  Write_method_list_t_initializer(*this, Context, Result, OptClassMethods, 
+                                  "_OBJC_PROTOCOL_OPT_CLASS_METHODS_",
+                                  PDecl->getNameAsString(), false);
+  
+  // Protocol's property metadata.
+  SmallVector<ObjCPropertyDecl *, 8> ProtocolProperties(PDecl->properties());
+  Write_prop_list_t_initializer(*this, Context, Result, ProtocolProperties,
+                                 /* Container */nullptr,
+                                 "_OBJC_PROTOCOL_PROPERTIES_",
+                                 PDecl->getNameAsString());
+
+  // Writer out root metadata for current protocol: struct _protocol_t
+  Result += "\n";
+  if (LangOpts.MicrosoftExt)
+    Result += "static ";
+  Result += "struct _protocol_t _OBJC_PROTOCOL_";
+  Result += PDecl->getNameAsString();
+  Result += " __attribute__ ((used, section (\"__DATA,__datacoal_nt,coalesced\"))) = {\n";
+  Result += "\t0,\n"; // id is; is null
+  Result += "\t\""; Result += PDecl->getNameAsString(); Result += "\",\n";
+  if (SuperProtocols.size() > 0) {
+    Result += "\t(const struct _protocol_list_t *)&"; Result += "_OBJC_PROTOCOL_REFS_";
+    Result += PDecl->getNameAsString(); Result += ",\n";
+  }
+  else
+    Result += "\t0,\n";
+  if (InstanceMethods.size() > 0) {
+    Result += "\t(const struct method_list_t *)&_OBJC_PROTOCOL_INSTANCE_METHODS_"; 
+    Result += PDecl->getNameAsString(); Result += ",\n";
+  }
+  else
+    Result += "\t0,\n";
+
+  if (ClassMethods.size() > 0) {
+    Result += "\t(const struct method_list_t *)&_OBJC_PROTOCOL_CLASS_METHODS_"; 
+    Result += PDecl->getNameAsString(); Result += ",\n";
+  }
+  else
+    Result += "\t0,\n";
+  
+  if (OptInstanceMethods.size() > 0) {
+    Result += "\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_"; 
+    Result += PDecl->getNameAsString(); Result += ",\n";
+  }
+  else
+    Result += "\t0,\n";
+  
+  if (OptClassMethods.size() > 0) {
+    Result += "\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_CLASS_METHODS_"; 
+    Result += PDecl->getNameAsString(); Result += ",\n";
+  }
+  else
+    Result += "\t0,\n";
+  
+  if (ProtocolProperties.size() > 0) {
+    Result += "\t(const struct _prop_list_t *)&_OBJC_PROTOCOL_PROPERTIES_"; 
+    Result += PDecl->getNameAsString(); Result += ",\n";
+  }
+  else
+    Result += "\t0,\n";
+  
+  Result += "\t"; Result += "sizeof(_protocol_t)"; Result += ",\n";
+  Result += "\t0,\n";
+  
+  if (AllMethods.size() > 0) {
+    Result += "\t(const char **)&"; Result += "_OBJC_PROTOCOL_METHOD_TYPES_";
+    Result += PDecl->getNameAsString();
+    Result += "\n};\n";
+  }
+  else
+    Result += "\t0\n};\n";
+  
+  if (LangOpts.MicrosoftExt)
+    Result += "static ";
+  Result += "struct _protocol_t *";
+  Result += "_OBJC_LABEL_PROTOCOL_$_"; Result += PDecl->getNameAsString();
+  Result += " = &_OBJC_PROTOCOL_"; Result += PDecl->getNameAsString();
+  Result += ";\n";
+    
+  // Mark this protocol as having been generated.
+  if (!ObjCSynthesizedProtocols.insert(PDecl->getCanonicalDecl()))
+    llvm_unreachable("protocol already synthesized");
+  
+}
+
+void RewriteModernObjC::RewriteObjCProtocolListMetaData(
+                                const ObjCList<ObjCProtocolDecl> &Protocols,
+                                StringRef prefix, StringRef ClassName,
+                                std::string &Result) {
+  if (Protocols.empty()) return;
+  
+  for (unsigned i = 0; i != Protocols.size(); i++)
+    RewriteObjCProtocolMetaData(Protocols[i], Result);
+  
+  // Output the top lovel protocol meta-data for the class.
+  /* struct _objc_protocol_list {
+   struct _objc_protocol_list *next;
+   int    protocol_count;
+   struct _objc_protocol *class_protocols[];
+   }
+   */
+  Result += "\n";
+  if (LangOpts.MicrosoftExt)
+    Result += "__declspec(allocate(\".cat_cls_meth$B\")) ";
+  Result += "static struct {\n";
+  Result += "\tstruct _objc_protocol_list *next;\n";
+  Result += "\tint    protocol_count;\n";
+  Result += "\tstruct _objc_protocol *class_protocols[";
+  Result += utostr(Protocols.size());
+  Result += "];\n} _OBJC_";
+  Result += prefix;
+  Result += "_PROTOCOLS_";
+  Result += ClassName;
+  Result += " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= "
+  "{\n\t0, ";
+  Result += utostr(Protocols.size());
+  Result += "\n";
+  
+  Result += "\t,{&_OBJC_PROTOCOL_";
+  Result += Protocols[0]->getNameAsString();
+  Result += " \n";
+  
+  for (unsigned i = 1; i != Protocols.size(); i++) {
+    Result += "\t ,&_OBJC_PROTOCOL_";
+    Result += Protocols[i]->getNameAsString();
+    Result += "\n";
+  }
+  Result += "\t }\n};\n";
+}
+
+/// hasObjCExceptionAttribute - Return true if this class or any super
+/// class has the __objc_exception__ attribute.
+/// FIXME. Move this to ASTContext.cpp as it is also used for IRGen.
+static bool hasObjCExceptionAttribute(ASTContext &Context,
+                                      const ObjCInterfaceDecl *OID) {
+  if (OID->hasAttr<ObjCExceptionAttr>())
+    return true;
+  if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
+    return hasObjCExceptionAttribute(Context, Super);
+  return false;
+}
+
+void RewriteModernObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
+                                           std::string &Result) {
+  ObjCInterfaceDecl *CDecl = IDecl->getClassInterface();
+  
+  // Explicitly declared @interface's are already synthesized.
+  if (CDecl->isImplicitInterfaceDecl())
+    assert(false && 
+           "Legacy implicit interface rewriting not supported in moder abi");
+  
+  WriteModernMetadataDeclarations(Context, Result);
+  SmallVector<ObjCIvarDecl *, 8> IVars;
+  
+  for (ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin();
+      IVD; IVD = IVD->getNextIvar()) {
+    // Ignore unnamed bit-fields.
+    if (!IVD->getDeclName())
+      continue;
+    IVars.push_back(IVD);
+  }
+  
+  Write__ivar_list_t_initializer(*this, Context, Result, IVars, 
+                                 "_OBJC_$_INSTANCE_VARIABLES_",
+                                 CDecl);
+  
+  // Build _objc_method_list for class's instance methods if needed
+  SmallVector<ObjCMethodDecl *, 32> InstanceMethods(IDecl->instance_methods());
+  
+  // If any of our property implementations have associated getters or
+  // setters, produce metadata for them as well.
+  for (const auto *Prop : IDecl->property_impls()) {
+    if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
+      continue;
+    if (!Prop->getPropertyIvarDecl())
+      continue;
+    ObjCPropertyDecl *PD = Prop->getPropertyDecl();
+    if (!PD)
+      continue;
+    if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl())
+      if (mustSynthesizeSetterGetterMethod(IDecl, PD, true /*getter*/))
+        InstanceMethods.push_back(Getter);
+    if (PD->isReadOnly())
+      continue;
+    if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl())
+      if (mustSynthesizeSetterGetterMethod(IDecl, PD, false /*setter*/))
+        InstanceMethods.push_back(Setter);
+  }
+  
+  Write_method_list_t_initializer(*this, Context, Result, InstanceMethods,
+                                  "_OBJC_$_INSTANCE_METHODS_",
+                                  IDecl->getNameAsString(), true);
+  
+  SmallVector<ObjCMethodDecl *, 32> ClassMethods(IDecl->class_methods());
+  
+  Write_method_list_t_initializer(*this, Context, Result, ClassMethods,
+                                  "_OBJC_$_CLASS_METHODS_",
+                                  IDecl->getNameAsString(), true);
+  
+  // Protocols referenced in class declaration?
+  // Protocol's super protocol list
+  std::vector<ObjCProtocolDecl *> RefedProtocols;
+  const ObjCList<ObjCProtocolDecl> &Protocols = CDecl->getReferencedProtocols();
+  for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
+       E = Protocols.end();
+       I != E; ++I) {
+    RefedProtocols.push_back(*I);
+    // Must write out all protocol definitions in current qualifier list,
+    // and in their nested qualifiers before writing out current definition.
+    RewriteObjCProtocolMetaData(*I, Result);
+  }
+  
+  Write_protocol_list_initializer(Context, Result, 
+                                  RefedProtocols,
+                                  "_OBJC_CLASS_PROTOCOLS_$_",
+                                  IDecl->getNameAsString());
+  
+  // Protocol's property metadata.
+  SmallVector<ObjCPropertyDecl *, 8> ClassProperties(CDecl->properties());
+  Write_prop_list_t_initializer(*this, Context, Result, ClassProperties,
+                                 /* Container */IDecl,
+                                 "_OBJC_$_PROP_LIST_",
+                                 CDecl->getNameAsString());
+
+  
+  // Data for initializing _class_ro_t  metaclass meta-data
+  uint32_t flags = CLS_META;
+  std::string InstanceSize;
+  std::string InstanceStart;
+  
+  
+  bool classIsHidden = CDecl->getVisibility() == HiddenVisibility;
+  if (classIsHidden)
+    flags |= OBJC2_CLS_HIDDEN;
+  
+  if (!CDecl->getSuperClass())
+    // class is root
+    flags |= CLS_ROOT;
+  InstanceSize = "sizeof(struct _class_t)";
+  InstanceStart = InstanceSize;
+  Write__class_ro_t_initializer(Context, Result, flags, 
+                                InstanceStart, InstanceSize,
+                                ClassMethods,
+                                nullptr,
+                                nullptr,
+                                nullptr,
+                                "_OBJC_METACLASS_RO_$_",
+                                CDecl->getNameAsString());
+
+  // Data for initializing _class_ro_t meta-data
+  flags = CLS;
+  if (classIsHidden)
+    flags |= OBJC2_CLS_HIDDEN;
+  
+  if (hasObjCExceptionAttribute(*Context, CDecl))
+    flags |= CLS_EXCEPTION;
+
+  if (!CDecl->getSuperClass())
+    // class is root
+    flags |= CLS_ROOT;
+  
+  InstanceSize.clear();
+  InstanceStart.clear();
+  if (!ObjCSynthesizedStructs.count(CDecl)) {
+    InstanceSize = "0";
+    InstanceStart = "0";
+  }
+  else {
+    InstanceSize = "sizeof(struct ";
+    InstanceSize += CDecl->getNameAsString();
+    InstanceSize += "_IMPL)";
+    
+    ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin();
+    if (IVD) {
+      RewriteIvarOffsetComputation(IVD, InstanceStart);
+    }
+    else 
+      InstanceStart = InstanceSize;
+  }
+  Write__class_ro_t_initializer(Context, Result, flags, 
+                                InstanceStart, InstanceSize,
+                                InstanceMethods,
+                                RefedProtocols,
+                                IVars,
+                                ClassProperties,
+                                "_OBJC_CLASS_RO_$_",
+                                CDecl->getNameAsString());
+  
+  Write_class_t(Context, Result,
+                "OBJC_METACLASS_$_",
+                CDecl, /*metaclass*/true);
+  
+  Write_class_t(Context, Result,
+                "OBJC_CLASS_$_",
+                CDecl, /*metaclass*/false);
+  
+  if (ImplementationIsNonLazy(IDecl))
+    DefinedNonLazyClasses.push_back(CDecl);
+                
+}
+
+void RewriteModernObjC::RewriteClassSetupInitHook(std::string &Result) {
+  int ClsDefCount = ClassImplementation.size();
+  if (!ClsDefCount)
+    return;
+  Result += "#pragma section(\".objc_inithooks$B\", long, read, write)\n";
+  Result += "__declspec(allocate(\".objc_inithooks$B\")) ";
+  Result += "static void *OBJC_CLASS_SETUP[] = {\n";
+  for (int i = 0; i < ClsDefCount; i++) {
+    ObjCImplementationDecl *IDecl = ClassImplementation[i];
+    ObjCInterfaceDecl *CDecl = IDecl->getClassInterface();
+    Result += "\t(void *)&OBJC_CLASS_SETUP_$_";
+    Result  += CDecl->getName(); Result += ",\n";
+  }
+  Result += "};\n";
+}
+
+void RewriteModernObjC::RewriteMetaDataIntoBuffer(std::string &Result) {
+  int ClsDefCount = ClassImplementation.size();
+  int CatDefCount = CategoryImplementation.size();
+  
+  // For each implemented class, write out all its meta data.
+  for (int i = 0; i < ClsDefCount; i++)
+    RewriteObjCClassMetaData(ClassImplementation[i], Result);
+  
+  RewriteClassSetupInitHook(Result);
+  
+  // For each implemented category, write out all its meta data.
+  for (int i = 0; i < CatDefCount; i++)
+    RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result);
+  
+  RewriteCategorySetupInitHook(Result);
+  
+  if (ClsDefCount > 0) {
+    if (LangOpts.MicrosoftExt)
+      Result += "__declspec(allocate(\".objc_classlist$B\")) ";
+    Result += "static struct _class_t *L_OBJC_LABEL_CLASS_$ [";
+    Result += llvm::utostr(ClsDefCount); Result += "]";
+    Result += 
+      " __attribute__((used, section (\"__DATA, __objc_classlist,"
+      "regular,no_dead_strip\")))= {\n";
+    for (int i = 0; i < ClsDefCount; i++) {
+      Result += "\t&OBJC_CLASS_$_";
+      Result += ClassImplementation[i]->getNameAsString();
+      Result += ",\n";
+    }
+    Result += "};\n";
+    
+    if (!DefinedNonLazyClasses.empty()) {
+      if (LangOpts.MicrosoftExt)
+        Result += "__declspec(allocate(\".objc_nlclslist$B\")) \n";
+      Result += "static struct _class_t *_OBJC_LABEL_NONLAZY_CLASS_$[] = {\n\t";
+      for (unsigned i = 0, e = DefinedNonLazyClasses.size(); i < e; i++) {
+        Result += "\t&OBJC_CLASS_$_"; Result += DefinedNonLazyClasses[i]->getNameAsString();
+        Result += ",\n";
+      }
+      Result += "};\n";
+    }
+  }
+  
+  if (CatDefCount > 0) {
+    if (LangOpts.MicrosoftExt)
+      Result += "__declspec(allocate(\".objc_catlist$B\")) ";
+    Result += "static struct _category_t *L_OBJC_LABEL_CATEGORY_$ [";
+    Result += llvm::utostr(CatDefCount); Result += "]";
+    Result += 
+    " __attribute__((used, section (\"__DATA, __objc_catlist,"
+    "regular,no_dead_strip\")))= {\n";
+    for (int i = 0; i < CatDefCount; i++) {
+      Result += "\t&_OBJC_$_CATEGORY_";
+      Result += 
+        CategoryImplementation[i]->getClassInterface()->getNameAsString(); 
+      Result += "_$_";
+      Result += CategoryImplementation[i]->getNameAsString();
+      Result += ",\n";
+    }
+    Result += "};\n";
+  }
+  
+  if (!DefinedNonLazyCategories.empty()) {
+    if (LangOpts.MicrosoftExt)
+      Result += "__declspec(allocate(\".objc_nlcatlist$B\")) \n";
+    Result += "static struct _category_t *_OBJC_LABEL_NONLAZY_CATEGORY_$[] = {\n\t";
+    for (unsigned i = 0, e = DefinedNonLazyCategories.size(); i < e; i++) {
+      Result += "\t&_OBJC_$_CATEGORY_";
+      Result += 
+        DefinedNonLazyCategories[i]->getClassInterface()->getNameAsString(); 
+      Result += "_$_";
+      Result += DefinedNonLazyCategories[i]->getNameAsString();
+      Result += ",\n";
+    }
+    Result += "};\n";
+  }
+}
+
+void RewriteModernObjC::WriteImageInfo(std::string &Result) {
+  if (LangOpts.MicrosoftExt)
+    Result += "__declspec(allocate(\".objc_imageinfo$B\")) \n";
+  
+  Result += "static struct IMAGE_INFO { unsigned version; unsigned flag; } ";
+  // version 0, ObjCABI is 2
+  Result += "_OBJC_IMAGE_INFO = { 0, 2 };\n";
+}
+
+/// RewriteObjCCategoryImplDecl - Rewrite metadata for each category
+/// implementation.
+void RewriteModernObjC::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl,
+                                              std::string &Result) {
+  WriteModernMetadataDeclarations(Context, Result);
+  ObjCInterfaceDecl *ClassDecl = IDecl->getClassInterface();
+  // Find category declaration for this implementation.
+  ObjCCategoryDecl *CDecl
+    = ClassDecl->FindCategoryDeclaration(IDecl->getIdentifier());
+  
+  std::string FullCategoryName = ClassDecl->getNameAsString();
+  FullCategoryName += "_$_";
+  FullCategoryName += CDecl->getNameAsString();
+  
+  // Build _objc_method_list for class's instance methods if needed
+  SmallVector<ObjCMethodDecl *, 32> InstanceMethods(IDecl->instance_methods());
+  
+  // If any of our property implementations have associated getters or
+  // setters, produce metadata for them as well.
+  for (const auto *Prop : IDecl->property_impls()) {
+    if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
+      continue;
+    if (!Prop->getPropertyIvarDecl())
+      continue;
+    ObjCPropertyDecl *PD = Prop->getPropertyDecl();
+    if (!PD)
+      continue;
+    if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl())
+      InstanceMethods.push_back(Getter);
+    if (PD->isReadOnly())
+      continue;
+    if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl())
+      InstanceMethods.push_back(Setter);
+  }
+  
+  Write_method_list_t_initializer(*this, Context, Result, InstanceMethods,
+                                  "_OBJC_$_CATEGORY_INSTANCE_METHODS_",
+                                  FullCategoryName, true);
+  
+  SmallVector<ObjCMethodDecl *, 32> ClassMethods(IDecl->class_methods());
+  
+  Write_method_list_t_initializer(*this, Context, Result, ClassMethods,
+                                  "_OBJC_$_CATEGORY_CLASS_METHODS_",
+                                  FullCategoryName, true);
+  
+  // Protocols referenced in class declaration?
+  // Protocol's super protocol list
+  SmallVector<ObjCProtocolDecl *, 8> RefedProtocols(CDecl->protocols());
+  for (auto *I : CDecl->protocols())
+    // Must write out all protocol definitions in current qualifier list,
+    // and in their nested qualifiers before writing out current definition.
+    RewriteObjCProtocolMetaData(I, Result);
+  
+  Write_protocol_list_initializer(Context, Result, 
+                                  RefedProtocols,
+                                  "_OBJC_CATEGORY_PROTOCOLS_$_",
+                                  FullCategoryName);
+  
+  // Protocol's property metadata.
+  SmallVector<ObjCPropertyDecl *, 8> ClassProperties(CDecl->properties());
+  Write_prop_list_t_initializer(*this, Context, Result, ClassProperties,
+                                /* Container */IDecl,
+                                "_OBJC_$_PROP_LIST_",
+                                FullCategoryName);
+  
+  Write_category_t(*this, Context, Result,
+                   CDecl,
+                   ClassDecl,
+                   InstanceMethods,
+                   ClassMethods,
+                   RefedProtocols,
+                   ClassProperties);
+  
+  // Determine if this category is also "non-lazy".
+  if (ImplementationIsNonLazy(IDecl))
+    DefinedNonLazyCategories.push_back(CDecl);
+    
+}
+
+void RewriteModernObjC::RewriteCategorySetupInitHook(std::string &Result) {
+  int CatDefCount = CategoryImplementation.size();
+  if (!CatDefCount)
+    return;
+  Result += "#pragma section(\".objc_inithooks$B\", long, read, write)\n";
+  Result += "__declspec(allocate(\".objc_inithooks$B\")) ";
+  Result += "static void *OBJC_CATEGORY_SETUP[] = {\n";
+  for (int i = 0; i < CatDefCount; i++) {
+    ObjCCategoryImplDecl *IDecl = CategoryImplementation[i];
+    ObjCCategoryDecl *CatDecl= IDecl->getCategoryDecl();
+    ObjCInterfaceDecl *ClassDecl = IDecl->getClassInterface();
+    Result += "\t(void *)&OBJC_CATEGORY_SETUP_$_";
+    Result += ClassDecl->getName();
+    Result += "_$_";
+    Result += CatDecl->getName();
+    Result += ",\n";
+  }
+  Result += "};\n";
+}
+
+// RewriteObjCMethodsMetaData - Rewrite methods metadata for instance or
+/// class methods.
+template<typename MethodIterator>
+void RewriteModernObjC::RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
+                                             MethodIterator MethodEnd,
+                                             bool IsInstanceMethod,
+                                             StringRef prefix,
+                                             StringRef ClassName,
+                                             std::string &Result) {
+  if (MethodBegin == MethodEnd) return;
+  
+  if (!objc_impl_method) {
+    /* struct _objc_method {
+     SEL _cmd;
+     char *method_types;
+     void *_imp;
+     }
+     */
+    Result += "\nstruct _objc_method {\n";
+    Result += "\tSEL _cmd;\n";
+    Result += "\tchar *method_types;\n";
+    Result += "\tvoid *_imp;\n";
+    Result += "};\n";
+    
+    objc_impl_method = true;
+  }
+  
+  // Build _objc_method_list for class's methods if needed
+  
+  /* struct  {
+   struct _objc_method_list *next_method;
+   int method_count;
+   struct _objc_method method_list[];
+   }
+   */
+  unsigned NumMethods = std::distance(MethodBegin, MethodEnd);
+  Result += "\n";
+  if (LangOpts.MicrosoftExt) {
+    if (IsInstanceMethod)
+      Result += "__declspec(allocate(\".inst_meth$B\")) ";
+    else
+      Result += "__declspec(allocate(\".cls_meth$B\")) ";
+  }
+  Result += "static struct {\n";
+  Result += "\tstruct _objc_method_list *next_method;\n";
+  Result += "\tint method_count;\n";
+  Result += "\tstruct _objc_method method_list[";
+  Result += utostr(NumMethods);
+  Result += "];\n} _OBJC_";
+  Result += prefix;
+  Result += IsInstanceMethod ? "INSTANCE" : "CLASS";
+  Result += "_METHODS_";
+  Result += ClassName;
+  Result += " __attribute__ ((used, section (\"__OBJC, __";
+  Result += IsInstanceMethod ? "inst" : "cls";
+  Result += "_meth\")))= ";
+  Result += "{\n\t0, " + utostr(NumMethods) + "\n";
+  
+  Result += "\t,{{(SEL)\"";
+  Result += (*MethodBegin)->getSelector().getAsString().c_str();
+  std::string MethodTypeString;
+  Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString);
+  Result += "\", \"";
+  Result += MethodTypeString;
+  Result += "\", (void *)";
+  Result += MethodInternalNames[*MethodBegin];
+  Result += "}\n";
+  for (++MethodBegin; MethodBegin != MethodEnd; ++MethodBegin) {
+    Result += "\t  ,{(SEL)\"";
+    Result += (*MethodBegin)->getSelector().getAsString().c_str();
+    std::string MethodTypeString;
+    Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString);
+    Result += "\", \"";
+    Result += MethodTypeString;
+    Result += "\", (void *)";
+    Result += MethodInternalNames[*MethodBegin];
+    Result += "}\n";
+  }
+  Result += "\t }\n};\n";
+}
+
+Stmt *RewriteModernObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) {
+  SourceRange OldRange = IV->getSourceRange();
+  Expr *BaseExpr = IV->getBase();
+  
+  // Rewrite the base, but without actually doing replaces.
+  {
+    DisableReplaceStmtScope S(*this);
+    BaseExpr = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(BaseExpr));
+    IV->setBase(BaseExpr);
+  }
+  
+  ObjCIvarDecl *D = IV->getDecl();
+  
+  Expr *Replacement = IV;
+  
+    if (BaseExpr->getType()->isObjCObjectPointerType()) {
+      const ObjCInterfaceType *iFaceDecl =
+        dyn_cast<ObjCInterfaceType>(BaseExpr->getType()->getPointeeType());
+      assert(iFaceDecl && "RewriteObjCIvarRefExpr - iFaceDecl is null");
+      // lookup which class implements the instance variable.
+      ObjCInterfaceDecl *clsDeclared = nullptr;
+      iFaceDecl->getDecl()->lookupInstanceVariable(D->getIdentifier(),
+                                                   clsDeclared);
+      assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class");
+      
+      // Build name of symbol holding ivar offset.
+      std::string IvarOffsetName;
+      if (D->isBitField())
+        ObjCIvarBitfieldGroupOffset(D, IvarOffsetName);
+      else
+        WriteInternalIvarName(clsDeclared, D, IvarOffsetName);
+      
+      ReferencedIvars[clsDeclared].insert(D);
+      
+      // cast offset to "char *".
+      CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, 
+                                                    Context->getPointerType(Context->CharTy),
+                                                    CK_BitCast,
+                                                    BaseExpr);
+      VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
+                                       SourceLocation(), &Context->Idents.get(IvarOffsetName),
+                                       Context->UnsignedLongTy, nullptr,
+                                       SC_Extern);
+      DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, false,
+                                                   Context->UnsignedLongTy, VK_LValue,
+                                                   SourceLocation());
+      BinaryOperator *addExpr = 
+        new (Context) BinaryOperator(castExpr, DRE, BO_Add, 
+                                     Context->getPointerType(Context->CharTy),
+                                     VK_RValue, OK_Ordinary, SourceLocation(), false);
+      // Don't forget the parens to enforce the proper binding.
+      ParenExpr *PE = new (Context) ParenExpr(SourceLocation(),
+                                              SourceLocation(),
+                                              addExpr);
+      QualType IvarT = D->getType();
+      if (D->isBitField())
+        IvarT = GetGroupRecordTypeForObjCIvarBitfield(D);
+
+      if (!isa<TypedefType>(IvarT) && IvarT->isRecordType()) {
+        RecordDecl *RD = IvarT->getAs<RecordType>()->getDecl();
+        RD = RD->getDefinition();
+        if (RD && !RD->getDeclName().getAsIdentifierInfo()) {
+          // decltype(((Foo_IMPL*)0)->bar) *
+          ObjCContainerDecl *CDecl = 
+            dyn_cast<ObjCContainerDecl>(D->getDeclContext());
+          // ivar in class extensions requires special treatment.
+          if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(CDecl))
+            CDecl = CatDecl->getClassInterface();
+          std::string RecName = CDecl->getName();
+          RecName += "_IMPL";
+          RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
+                                              SourceLocation(), SourceLocation(),
+                                              &Context->Idents.get(RecName.c_str()));
+          QualType PtrStructIMPL = Context->getPointerType(Context->getTagDeclType(RD));
+          unsigned UnsignedIntSize = 
+            static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
+          Expr *Zero = IntegerLiteral::Create(*Context,
+                                              llvm::APInt(UnsignedIntSize, 0),
+                                              Context->UnsignedIntTy, SourceLocation());
+          Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL, CK_BitCast, Zero);
+          ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(),
+                                                  Zero);
+          FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(),
+                                            SourceLocation(),
+                                            &Context->Idents.get(D->getNameAsString()),
+                                            IvarT, nullptr,
+                                            /*BitWidth=*/nullptr,
+                                            /*Mutable=*/true, ICIS_NoInit);
+          MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(),
+                                                    FD->getType(), VK_LValue,
+                                                    OK_Ordinary);
+          IvarT = Context->getDecltypeType(ME, ME->getType());
+        }
+      }
+      convertObjCTypeToCStyleType(IvarT);
+      QualType castT = Context->getPointerType(IvarT);
+          
+      castExpr = NoTypeInfoCStyleCastExpr(Context, 
+                                          castT,
+                                          CK_BitCast,
+                                          PE);
+      
+      
+      Expr *Exp = new (Context) UnaryOperator(castExpr, UO_Deref, IvarT,
+                                              VK_LValue, OK_Ordinary,
+                                              SourceLocation());
+      PE = new (Context) ParenExpr(OldRange.getBegin(),
+                                   OldRange.getEnd(),
+                                   Exp);
+      
+      if (D->isBitField()) {
+        FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(),
+                                          SourceLocation(),
+                                          &Context->Idents.get(D->getNameAsString()),
+                                          D->getType(), nullptr,
+                                          /*BitWidth=*/D->getBitWidth(),
+                                          /*Mutable=*/true, ICIS_NoInit);
+        MemberExpr *ME = new (Context) MemberExpr(PE, /*isArrow*/false, FD, SourceLocation(),
+                                                  FD->getType(), VK_LValue,
+                                                  OK_Ordinary);
+        Replacement = ME;
+
+      }
+      else
+        Replacement = PE;
+    }
+  
+    ReplaceStmtWithRange(IV, Replacement, OldRange);
+    return Replacement;  
+}
+
+#endif
diff --git a/lib/Frontend/Rewrite/RewriteObjC.cpp b/lib/Frontend/Rewrite/RewriteObjC.cpp
new file mode 100644
index 0000000..7a72177
--- /dev/null
+++ b/lib/Frontend/Rewrite/RewriteObjC.cpp
@@ -0,0 +1,5952 @@
+//===--- RewriteObjC.cpp - Playground for the code rewriter ---------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Hacks and fun related to the code rewriter.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Rewrite/Frontend/ASTConsumers.h"
+#include "clang/AST/AST.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/Attr.h"
+#include "clang/AST/ParentMap.h"
+#include "clang/Basic/CharInfo.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Rewrite/Core/Rewriter.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+#include <memory>
+
+#ifdef CLANG_ENABLE_OBJC_REWRITER
+
+using namespace clang;
+using llvm::utostr;
+
+namespace {
+  class RewriteObjC : public ASTConsumer {
+  protected:
+    
+    enum {
+      BLOCK_FIELD_IS_OBJECT   =  3,  /* id, NSObject, __attribute__((NSObject)),
+                                        block, ... */
+      BLOCK_FIELD_IS_BLOCK    =  7,  /* a block variable */
+      BLOCK_FIELD_IS_BYREF    =  8,  /* the on stack structure holding the 
+                                        __block variable */
+      BLOCK_FIELD_IS_WEAK     = 16,  /* declared __weak, only used in byref copy
+                                        helpers */
+      BLOCK_BYREF_CALLER      = 128, /* called from __block (byref) copy/dispose
+                                        support routines */
+      BLOCK_BYREF_CURRENT_MAX = 256
+    };
+    
+    enum {
+      BLOCK_NEEDS_FREE =        (1 << 24),
+      BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
+      BLOCK_HAS_CXX_OBJ =       (1 << 26),
+      BLOCK_IS_GC =             (1 << 27),
+      BLOCK_IS_GLOBAL =         (1 << 28),
+      BLOCK_HAS_DESCRIPTOR =    (1 << 29)
+    };
+    static const int OBJC_ABI_VERSION = 7;
+    
+    Rewriter Rewrite;
+    DiagnosticsEngine &Diags;
+    const LangOptions &LangOpts;
+    ASTContext *Context;
+    SourceManager *SM;
+    TranslationUnitDecl *TUDecl;
+    FileID MainFileID;
+    const char *MainFileStart, *MainFileEnd;
+    Stmt *CurrentBody;
+    ParentMap *PropParentMap; // created lazily.
+    std::string InFileName;
+    raw_ostream* OutFile;
+    std::string Preamble;
+    
+    TypeDecl *ProtocolTypeDecl;
+    VarDecl *GlobalVarDecl;
+    unsigned RewriteFailedDiag;
+    // ObjC string constant support.
+    unsigned NumObjCStringLiterals;
+    VarDecl *ConstantStringClassReference;
+    RecordDecl *NSStringRecord;
+
+    // ObjC foreach break/continue generation support.
+    int BcLabelCount;
+    
+    unsigned TryFinallyContainsReturnDiag;
+    // Needed for super.
+    ObjCMethodDecl *CurMethodDef;
+    RecordDecl *SuperStructDecl;
+    RecordDecl *ConstantStringDecl;
+    
+    FunctionDecl *MsgSendFunctionDecl;
+    FunctionDecl *MsgSendSuperFunctionDecl;
+    FunctionDecl *MsgSendStretFunctionDecl;
+    FunctionDecl *MsgSendSuperStretFunctionDecl;
+    FunctionDecl *MsgSendFpretFunctionDecl;
+    FunctionDecl *GetClassFunctionDecl;
+    FunctionDecl *GetMetaClassFunctionDecl;
+    FunctionDecl *GetSuperClassFunctionDecl;
+    FunctionDecl *SelGetUidFunctionDecl;
+    FunctionDecl *CFStringFunctionDecl;
+    FunctionDecl *SuperConstructorFunctionDecl;
+    FunctionDecl *CurFunctionDef;
+    FunctionDecl *CurFunctionDeclToDeclareForBlock;
+
+    /* Misc. containers needed for meta-data rewrite. */
+    SmallVector<ObjCImplementationDecl *, 8> ClassImplementation;
+    SmallVector<ObjCCategoryImplDecl *, 8> CategoryImplementation;
+    llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCSynthesizedStructs;
+    llvm::SmallPtrSet<ObjCProtocolDecl*, 8> ObjCSynthesizedProtocols;
+    llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCForwardDecls;
+    llvm::DenseMap<ObjCMethodDecl*, std::string> MethodInternalNames;
+    SmallVector<Stmt *, 32> Stmts;
+    SmallVector<int, 8> ObjCBcLabelNo;
+    // Remember all the @protocol(<expr>) expressions.
+    llvm::SmallPtrSet<ObjCProtocolDecl *, 32> ProtocolExprDecls;
+    
+    llvm::DenseSet<uint64_t> CopyDestroyCache;
+
+    // Block expressions.
+    SmallVector<BlockExpr *, 32> Blocks;
+    SmallVector<int, 32> InnerDeclRefsCount;
+    SmallVector<DeclRefExpr *, 32> InnerDeclRefs;
+    
+    SmallVector<DeclRefExpr *, 32> BlockDeclRefs;
+
+    // Block related declarations.
+    SmallVector<ValueDecl *, 8> BlockByCopyDecls;
+    llvm::SmallPtrSet<ValueDecl *, 8> BlockByCopyDeclsPtrSet;
+    SmallVector<ValueDecl *, 8> BlockByRefDecls;
+    llvm::SmallPtrSet<ValueDecl *, 8> BlockByRefDeclsPtrSet;
+    llvm::DenseMap<ValueDecl *, unsigned> BlockByRefDeclNo;
+    llvm::SmallPtrSet<ValueDecl *, 8> ImportedBlockDecls;
+    llvm::SmallPtrSet<VarDecl *, 8> ImportedLocalExternalDecls;
+    
+    llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs;
+
+    // This maps an original source AST to it's rewritten form. This allows
+    // us to avoid rewriting the same node twice (which is very uncommon).
+    // This is needed to support some of the exotic property rewriting.
+    llvm::DenseMap<Stmt *, Stmt *> ReplacedNodes;
+
+    // Needed for header files being rewritten
+    bool IsHeader;
+    bool SilenceRewriteMacroWarning;
+    bool objc_impl_method;
+    
+    bool DisableReplaceStmt;
+    class DisableReplaceStmtScope {
+      RewriteObjC &R;
+      bool SavedValue;
+    
+    public:
+      DisableReplaceStmtScope(RewriteObjC &R)
+        : R(R), SavedValue(R.DisableReplaceStmt) {
+        R.DisableReplaceStmt = true;
+      }
+      ~DisableReplaceStmtScope() {
+        R.DisableReplaceStmt = SavedValue;
+      }
+    };
+    void InitializeCommon(ASTContext &context);
+
+  public:
+
+    // Top Level Driver code.
+    bool HandleTopLevelDecl(DeclGroupRef D) override {
+      for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) {
+        if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*I)) {
+          if (!Class->isThisDeclarationADefinition()) {
+            RewriteForwardClassDecl(D);
+            break;
+          }
+        }
+
+        if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*I)) {
+          if (!Proto->isThisDeclarationADefinition()) {
+            RewriteForwardProtocolDecl(D);
+            break;
+          }
+        }
+
+        HandleTopLevelSingleDecl(*I);
+      }
+      return true;
+    }
+    void HandleTopLevelSingleDecl(Decl *D);
+    void HandleDeclInMainFile(Decl *D);
+    RewriteObjC(std::string inFile, raw_ostream *OS,
+                DiagnosticsEngine &D, const LangOptions &LOpts,
+                bool silenceMacroWarn);
+
+    ~RewriteObjC() {}
+
+    void HandleTranslationUnit(ASTContext &C) override;
+
+    void ReplaceStmt(Stmt *Old, Stmt *New) {
+      Stmt *ReplacingStmt = ReplacedNodes[Old];
+
+      if (ReplacingStmt)
+        return; // We can't rewrite the same node twice.
+
+      if (DisableReplaceStmt)
+        return;
+
+      // If replacement succeeded or warning disabled return with no warning.
+      if (!Rewrite.ReplaceStmt(Old, New)) {
+        ReplacedNodes[Old] = New;
+        return;
+      }
+      if (SilenceRewriteMacroWarning)
+        return;
+      Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag)
+                   << Old->getSourceRange();
+    }
+
+    void ReplaceStmtWithRange(Stmt *Old, Stmt *New, SourceRange SrcRange) {
+      assert(Old != nullptr && New != nullptr && "Expected non-null Stmt's");
+      if (DisableReplaceStmt)
+        return;
+
+      // Measure the old text.
+      int Size = Rewrite.getRangeSize(SrcRange);
+      if (Size == -1) {
+        Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag)
+                     << Old->getSourceRange();
+        return;
+      }
+      // Get the new text.
+      std::string SStr;
+      llvm::raw_string_ostream S(SStr);
+      New->printPretty(S, nullptr, PrintingPolicy(LangOpts));
+      const std::string &Str = S.str();
+
+      // If replacement succeeded or warning disabled return with no warning.
+      if (!Rewrite.ReplaceText(SrcRange.getBegin(), Size, Str)) {
+        ReplacedNodes[Old] = New;
+        return;
+      }
+      if (SilenceRewriteMacroWarning)
+        return;
+      Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag)
+                   << Old->getSourceRange();
+    }
+
+    void InsertText(SourceLocation Loc, StringRef Str,
+                    bool InsertAfter = true) {
+      // If insertion succeeded or warning disabled return with no warning.
+      if (!Rewrite.InsertText(Loc, Str, InsertAfter) ||
+          SilenceRewriteMacroWarning)
+        return;
+
+      Diags.Report(Context->getFullLoc(Loc), RewriteFailedDiag);
+    }
+
+    void ReplaceText(SourceLocation Start, unsigned OrigLength,
+                     StringRef Str) {
+      // If removal succeeded or warning disabled return with no warning.
+      if (!Rewrite.ReplaceText(Start, OrigLength, Str) ||
+          SilenceRewriteMacroWarning)
+        return;
+
+      Diags.Report(Context->getFullLoc(Start), RewriteFailedDiag);
+    }
+
+    // Syntactic Rewriting.
+    void RewriteRecordBody(RecordDecl *RD);
+    void RewriteInclude();
+    void RewriteForwardClassDecl(DeclGroupRef D);
+    void RewriteForwardClassDecl(const SmallVectorImpl<Decl *> &DG);
+    void RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl, 
+                                     const std::string &typedefString);
+    void RewriteImplementations();
+    void RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
+                                 ObjCImplementationDecl *IMD,
+                                 ObjCCategoryImplDecl *CID);
+    void RewriteInterfaceDecl(ObjCInterfaceDecl *Dcl);
+    void RewriteImplementationDecl(Decl *Dcl);
+    void RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl,
+                               ObjCMethodDecl *MDecl, std::string &ResultStr);
+    void RewriteTypeIntoString(QualType T, std::string &ResultStr,
+                               const FunctionType *&FPRetType);
+    void RewriteByRefString(std::string &ResultStr, const std::string &Name,
+                            ValueDecl *VD, bool def=false);
+    void RewriteCategoryDecl(ObjCCategoryDecl *Dcl);
+    void RewriteProtocolDecl(ObjCProtocolDecl *Dcl);
+    void RewriteForwardProtocolDecl(DeclGroupRef D);
+    void RewriteForwardProtocolDecl(const SmallVectorImpl<Decl *> &DG);
+    void RewriteMethodDeclaration(ObjCMethodDecl *Method);
+    void RewriteProperty(ObjCPropertyDecl *prop);
+    void RewriteFunctionDecl(FunctionDecl *FD);
+    void RewriteBlockPointerType(std::string& Str, QualType Type);
+    void RewriteBlockPointerTypeVariable(std::string& Str, ValueDecl *VD);
+    void RewriteBlockLiteralFunctionDecl(FunctionDecl *FD);
+    void RewriteObjCQualifiedInterfaceTypes(Decl *Dcl);
+    void RewriteTypeOfDecl(VarDecl *VD);
+    void RewriteObjCQualifiedInterfaceTypes(Expr *E);
+  
+    // Expression Rewriting.
+    Stmt *RewriteFunctionBodyOrGlobalInitializer(Stmt *S);
+    Stmt *RewriteAtEncode(ObjCEncodeExpr *Exp);
+    Stmt *RewritePropertyOrImplicitGetter(PseudoObjectExpr *Pseudo);
+    Stmt *RewritePropertyOrImplicitSetter(PseudoObjectExpr *Pseudo);
+    Stmt *RewriteAtSelector(ObjCSelectorExpr *Exp);
+    Stmt *RewriteMessageExpr(ObjCMessageExpr *Exp);
+    Stmt *RewriteObjCStringLiteral(ObjCStringLiteral *Exp);
+    Stmt *RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp);
+    void RewriteTryReturnStmts(Stmt *S);
+    void RewriteSyncReturnStmts(Stmt *S, std::string buf);
+    Stmt *RewriteObjCTryStmt(ObjCAtTryStmt *S);
+    Stmt *RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S);
+    Stmt *RewriteObjCThrowStmt(ObjCAtThrowStmt *S);
+    Stmt *RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
+                                       SourceLocation OrigEnd);
+    Stmt *RewriteBreakStmt(BreakStmt *S);
+    Stmt *RewriteContinueStmt(ContinueStmt *S);
+    void RewriteCastExpr(CStyleCastExpr *CE);
+    
+    // Block rewriting.
+    void RewriteBlocksInFunctionProtoType(QualType funcType, NamedDecl *D);
+    
+    // Block specific rewrite rules.
+    void RewriteBlockPointerDecl(NamedDecl *VD);
+    void RewriteByRefVar(VarDecl *VD);
+    Stmt *RewriteBlockDeclRefExpr(DeclRefExpr *VD);
+    Stmt *RewriteLocalVariableExternalStorage(DeclRefExpr *DRE);
+    void RewriteBlockPointerFunctionArgs(FunctionDecl *FD);
+    
+    void RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl,
+                                      std::string &Result);
+
+    virtual void Initialize(ASTContext &context) override = 0;
+
+    // Metadata Rewriting.
+    virtual void RewriteMetaDataIntoBuffer(std::string &Result) = 0;
+    virtual void RewriteObjCProtocolListMetaData(const ObjCList<ObjCProtocolDecl> &Prots,
+                                                 StringRef prefix,
+                                                 StringRef ClassName,
+                                                 std::string &Result) = 0;
+    virtual void RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *CDecl,
+                                             std::string &Result) = 0;
+    virtual void RewriteObjCProtocolMetaData(ObjCProtocolDecl *Protocol,
+                                     StringRef prefix,
+                                     StringRef ClassName,
+                                     std::string &Result) = 0;
+    virtual void RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
+                                          std::string &Result) = 0;
+    
+    // Rewriting ivar access
+    virtual Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) = 0;
+    virtual void RewriteIvarOffsetComputation(ObjCIvarDecl *ivar,
+                                         std::string &Result) = 0;
+    
+    // Misc. AST transformation routines. Sometimes they end up calling
+    // rewriting routines on the new ASTs.
+    CallExpr *SynthesizeCallToFunctionDecl(FunctionDecl *FD,
+                                           Expr **args, unsigned nargs,
+                                           SourceLocation StartLoc=SourceLocation(),
+                                           SourceLocation EndLoc=SourceLocation());
+    CallExpr *SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFlavor,
+                                        QualType msgSendType, 
+                                        QualType returnType, 
+                                        SmallVectorImpl<QualType> &ArgTypes,
+                                        SmallVectorImpl<Expr*> &MsgExprs,
+                                        ObjCMethodDecl *Method);
+    Stmt *SynthMessageExpr(ObjCMessageExpr *Exp,
+                           SourceLocation StartLoc=SourceLocation(),
+                           SourceLocation EndLoc=SourceLocation());
+    
+    void SynthCountByEnumWithState(std::string &buf);
+    void SynthMsgSendFunctionDecl();
+    void SynthMsgSendSuperFunctionDecl();
+    void SynthMsgSendStretFunctionDecl();
+    void SynthMsgSendFpretFunctionDecl();
+    void SynthMsgSendSuperStretFunctionDecl();
+    void SynthGetClassFunctionDecl();
+    void SynthGetMetaClassFunctionDecl();
+    void SynthGetSuperClassFunctionDecl();
+    void SynthSelGetUidFunctionDecl();
+    void SynthSuperConstructorFunctionDecl();
+    
+    std::string SynthesizeByrefCopyDestroyHelper(VarDecl *VD, int flag);
+    std::string SynthesizeBlockHelperFuncs(BlockExpr *CE, int i,
+                                      StringRef funcName, std::string Tag);
+    std::string SynthesizeBlockFunc(BlockExpr *CE, int i,
+                                      StringRef funcName, std::string Tag);
+    std::string SynthesizeBlockImpl(BlockExpr *CE, 
+                                    std::string Tag, std::string Desc);
+    std::string SynthesizeBlockDescriptor(std::string DescTag, 
+                                          std::string ImplTag,
+                                          int i, StringRef funcName,
+                                          unsigned hasCopy);
+    Stmt *SynthesizeBlockCall(CallExpr *Exp, const Expr* BlockExp);
+    void SynthesizeBlockLiterals(SourceLocation FunLocStart,
+                                 StringRef FunName);
+    FunctionDecl *SynthBlockInitFunctionDecl(StringRef name);
+    Stmt *SynthBlockInitExpr(BlockExpr *Exp,
+            const SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs);
+
+    // Misc. helper routines.
+    QualType getProtocolType();
+    void WarnAboutReturnGotoStmts(Stmt *S);
+    void HasReturnStmts(Stmt *S, bool &hasReturns);
+    void CheckFunctionPointerDecl(QualType dType, NamedDecl *ND);
+    void InsertBlockLiteralsWithinFunction(FunctionDecl *FD);
+    void InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD);
+
+    bool IsDeclStmtInForeachHeader(DeclStmt *DS);
+    void CollectBlockDeclRefInfo(BlockExpr *Exp);
+    void GetBlockDeclRefExprs(Stmt *S);
+    void GetInnerBlockDeclRefExprs(Stmt *S,
+                SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs,
+                llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts);
+
+    // We avoid calling Type::isBlockPointerType(), since it operates on the
+    // canonical type. We only care if the top-level type is a closure pointer.
+    bool isTopLevelBlockPointerType(QualType T) {
+      return isa<BlockPointerType>(T);
+    }
+
+    /// convertBlockPointerToFunctionPointer - Converts a block-pointer type
+    /// to a function pointer type and upon success, returns true; false
+    /// otherwise.
+    bool convertBlockPointerToFunctionPointer(QualType &T) {
+      if (isTopLevelBlockPointerType(T)) {
+        const BlockPointerType *BPT = T->getAs<BlockPointerType>();
+        T = Context->getPointerType(BPT->getPointeeType());
+        return true;
+      }
+      return false;
+    }
+    
+    bool needToScanForQualifiers(QualType T);
+    QualType getSuperStructType();
+    QualType getConstantStringStructType();
+    QualType convertFunctionTypeOfBlocks(const FunctionType *FT);
+    bool BufferContainsPPDirectives(const char *startBuf, const char *endBuf);
+    
+    void convertToUnqualifiedObjCType(QualType &T) {
+      if (T->isObjCQualifiedIdType())
+        T = Context->getObjCIdType();
+      else if (T->isObjCQualifiedClassType())
+        T = Context->getObjCClassType();
+      else if (T->isObjCObjectPointerType() &&
+               T->getPointeeType()->isObjCQualifiedInterfaceType()) {
+        if (const ObjCObjectPointerType * OBJPT =
+              T->getAsObjCInterfacePointerType()) {
+          const ObjCInterfaceType *IFaceT = OBJPT->getInterfaceType();
+          T = QualType(IFaceT, 0);
+          T = Context->getPointerType(T);
+        }
+     }
+    }
+    
+    // FIXME: This predicate seems like it would be useful to add to ASTContext.
+    bool isObjCType(QualType T) {
+      if (!LangOpts.ObjC1 && !LangOpts.ObjC2)
+        return false;
+
+      QualType OCT = Context->getCanonicalType(T).getUnqualifiedType();
+
+      if (OCT == Context->getCanonicalType(Context->getObjCIdType()) ||
+          OCT == Context->getCanonicalType(Context->getObjCClassType()))
+        return true;
+
+      if (const PointerType *PT = OCT->getAs<PointerType>()) {
+        if (isa<ObjCInterfaceType>(PT->getPointeeType()) ||
+            PT->getPointeeType()->isObjCQualifiedIdType())
+          return true;
+      }
+      return false;
+    }
+    bool PointerTypeTakesAnyBlockArguments(QualType QT);
+    bool PointerTypeTakesAnyObjCQualifiedType(QualType QT);
+    void GetExtentOfArgList(const char *Name, const char *&LParen,
+                            const char *&RParen);
+    
+    void QuoteDoublequotes(std::string &From, std::string &To) {
+      for (unsigned i = 0; i < From.length(); i++) {
+        if (From[i] == '"')
+          To += "\\\"";
+        else
+          To += From[i];
+      }
+    }
+
+    QualType getSimpleFunctionType(QualType result,
+                                   ArrayRef<QualType> args,
+                                   bool variadic = false) {
+      if (result == Context->getObjCInstanceType())
+        result =  Context->getObjCIdType();
+      FunctionProtoType::ExtProtoInfo fpi;
+      fpi.Variadic = variadic;
+      return Context->getFunctionType(result, args, fpi);
+    }
+
+    // Helper function: create a CStyleCastExpr with trivial type source info.
+    CStyleCastExpr* NoTypeInfoCStyleCastExpr(ASTContext *Ctx, QualType Ty,
+                                             CastKind Kind, Expr *E) {
+      TypeSourceInfo *TInfo = Ctx->getTrivialTypeSourceInfo(Ty, SourceLocation());
+      return CStyleCastExpr::Create(*Ctx, Ty, VK_RValue, Kind, E, nullptr,
+                                    TInfo, SourceLocation(), SourceLocation());
+    }
+
+    StringLiteral *getStringLiteral(StringRef Str) {
+      QualType StrType = Context->getConstantArrayType(
+          Context->CharTy, llvm::APInt(32, Str.size() + 1), ArrayType::Normal,
+          0);
+      return StringLiteral::Create(*Context, Str, StringLiteral::Ascii,
+                                   /*Pascal=*/false, StrType, SourceLocation());
+    }
+  };
+  
+  class RewriteObjCFragileABI : public RewriteObjC {
+  public:
+    
+    RewriteObjCFragileABI(std::string inFile, raw_ostream *OS,
+                DiagnosticsEngine &D, const LangOptions &LOpts,
+                bool silenceMacroWarn) : RewriteObjC(inFile, OS,
+                                                     D, LOpts,
+                                                     silenceMacroWarn) {}
+    
+    ~RewriteObjCFragileABI() {}
+    virtual void Initialize(ASTContext &context) override;
+
+    // Rewriting metadata
+    template<typename MethodIterator>
+    void RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
+                                    MethodIterator MethodEnd,
+                                    bool IsInstanceMethod,
+                                    StringRef prefix,
+                                    StringRef ClassName,
+                                    std::string &Result);
+    void RewriteObjCProtocolMetaData(ObjCProtocolDecl *Protocol,
+                                     StringRef prefix, StringRef ClassName,
+                                     std::string &Result) override;
+    void RewriteObjCProtocolListMetaData(
+          const ObjCList<ObjCProtocolDecl> &Prots,
+          StringRef prefix, StringRef ClassName, std::string &Result) override;
+    void RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
+                                  std::string &Result) override;
+    void RewriteMetaDataIntoBuffer(std::string &Result) override;
+    void RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *CDecl,
+                                     std::string &Result) override;
+
+    // Rewriting ivar
+    void RewriteIvarOffsetComputation(ObjCIvarDecl *ivar,
+                                      std::string &Result) override;
+    Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) override;
+  };
+}
+
+void RewriteObjC::RewriteBlocksInFunctionProtoType(QualType funcType,
+                                                   NamedDecl *D) {
+  if (const FunctionProtoType *fproto
+      = dyn_cast<FunctionProtoType>(funcType.IgnoreParens())) {
+    for (const auto &I : fproto->param_types())
+      if (isTopLevelBlockPointerType(I)) {
+        // All the args are checked/rewritten. Don't call twice!
+        RewriteBlockPointerDecl(D);
+        break;
+      }
+  }
+}
+
+void RewriteObjC::CheckFunctionPointerDecl(QualType funcType, NamedDecl *ND) {
+  const PointerType *PT = funcType->getAs<PointerType>();
+  if (PT && PointerTypeTakesAnyBlockArguments(funcType))
+    RewriteBlocksInFunctionProtoType(PT->getPointeeType(), ND);
+}
+
+static bool IsHeaderFile(const std::string &Filename) {
+  std::string::size_type DotPos = Filename.rfind('.');
+
+  if (DotPos == std::string::npos) {
+    // no file extension
+    return false;
+  }
+
+  std::string Ext = std::string(Filename.begin()+DotPos+1, Filename.end());
+  // C header: .h
+  // C++ header: .hh or .H;
+  return Ext == "h" || Ext == "hh" || Ext == "H";
+}
+
+RewriteObjC::RewriteObjC(std::string inFile, raw_ostream* OS,
+                         DiagnosticsEngine &D, const LangOptions &LOpts,
+                         bool silenceMacroWarn)
+      : Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(OS),
+        SilenceRewriteMacroWarning(silenceMacroWarn) {
+  IsHeader = IsHeaderFile(inFile);
+  RewriteFailedDiag = Diags.getCustomDiagID(DiagnosticsEngine::Warning,
+               "rewriting sub-expression within a macro (may not be correct)");
+  TryFinallyContainsReturnDiag = Diags.getCustomDiagID(
+               DiagnosticsEngine::Warning,
+               "rewriter doesn't support user-specified control flow semantics "
+               "for @try/@finally (code may not execute properly)");
+}
+
+ASTConsumer *clang::CreateObjCRewriter(const std::string& InFile,
+                                       raw_ostream* OS,
+                                       DiagnosticsEngine &Diags,
+                                       const LangOptions &LOpts,
+                                       bool SilenceRewriteMacroWarning) {
+  return new RewriteObjCFragileABI(InFile, OS, Diags, LOpts, SilenceRewriteMacroWarning);
+}
+
+void RewriteObjC::InitializeCommon(ASTContext &context) {
+  Context = &context;
+  SM = &Context->getSourceManager();
+  TUDecl = Context->getTranslationUnitDecl();
+  MsgSendFunctionDecl = nullptr;
+  MsgSendSuperFunctionDecl = nullptr;
+  MsgSendStretFunctionDecl = nullptr;
+  MsgSendSuperStretFunctionDecl = nullptr;
+  MsgSendFpretFunctionDecl = nullptr;
+  GetClassFunctionDecl = nullptr;
+  GetMetaClassFunctionDecl = nullptr;
+  GetSuperClassFunctionDecl = nullptr;
+  SelGetUidFunctionDecl = nullptr;
+  CFStringFunctionDecl = nullptr;
+  ConstantStringClassReference = nullptr;
+  NSStringRecord = nullptr;
+  CurMethodDef = nullptr;
+  CurFunctionDef = nullptr;
+  CurFunctionDeclToDeclareForBlock = nullptr;
+  GlobalVarDecl = nullptr;
+  SuperStructDecl = nullptr;
+  ProtocolTypeDecl = nullptr;
+  ConstantStringDecl = nullptr;
+  BcLabelCount = 0;
+  SuperConstructorFunctionDecl = nullptr;
+  NumObjCStringLiterals = 0;
+  PropParentMap = nullptr;
+  CurrentBody = nullptr;
+  DisableReplaceStmt = false;
+  objc_impl_method = false;
+
+  // Get the ID and start/end of the main file.
+  MainFileID = SM->getMainFileID();
+  const llvm::MemoryBuffer *MainBuf = SM->getBuffer(MainFileID);
+  MainFileStart = MainBuf->getBufferStart();
+  MainFileEnd = MainBuf->getBufferEnd();
+
+  Rewrite.setSourceMgr(Context->getSourceManager(), Context->getLangOpts());
+}
+
+//===----------------------------------------------------------------------===//
+// Top Level Driver Code
+//===----------------------------------------------------------------------===//
+
+void RewriteObjC::HandleTopLevelSingleDecl(Decl *D) {
+  if (Diags.hasErrorOccurred())
+    return;
+
+  // Two cases: either the decl could be in the main file, or it could be in a
+  // #included file.  If the former, rewrite it now.  If the later, check to see
+  // if we rewrote the #include/#import.
+  SourceLocation Loc = D->getLocation();
+  Loc = SM->getExpansionLoc(Loc);
+
+  // If this is for a builtin, ignore it.
+  if (Loc.isInvalid()) return;
+
+  // Look for built-in declarations that we need to refer during the rewrite.
+  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    RewriteFunctionDecl(FD);
+  } else if (VarDecl *FVD = dyn_cast<VarDecl>(D)) {
+    // declared in <Foundation/NSString.h>
+    if (FVD->getName() == "_NSConstantStringClassReference") {
+      ConstantStringClassReference = FVD;
+      return;
+    }
+  } else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
+    if (ID->isThisDeclarationADefinition())
+      RewriteInterfaceDecl(ID);
+  } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(D)) {
+    RewriteCategoryDecl(CD);
+  } else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) {
+    if (PD->isThisDeclarationADefinition())
+      RewriteProtocolDecl(PD);
+  } else if (LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(D)) {
+    // Recurse into linkage specifications
+    for (DeclContext::decl_iterator DI = LSD->decls_begin(),
+                                 DIEnd = LSD->decls_end();
+         DI != DIEnd; ) {
+      if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>((*DI))) {
+        if (!IFace->isThisDeclarationADefinition()) {
+          SmallVector<Decl *, 8> DG;
+          SourceLocation StartLoc = IFace->getLocStart();
+          do {
+            if (isa<ObjCInterfaceDecl>(*DI) &&
+                !cast<ObjCInterfaceDecl>(*DI)->isThisDeclarationADefinition() &&
+                StartLoc == (*DI)->getLocStart())
+              DG.push_back(*DI);
+            else
+              break;
+            
+            ++DI;
+          } while (DI != DIEnd);
+          RewriteForwardClassDecl(DG);
+          continue;
+        }
+      }
+
+      if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>((*DI))) {
+        if (!Proto->isThisDeclarationADefinition()) {
+          SmallVector<Decl *, 8> DG;
+          SourceLocation StartLoc = Proto->getLocStart();
+          do {
+            if (isa<ObjCProtocolDecl>(*DI) &&
+                !cast<ObjCProtocolDecl>(*DI)->isThisDeclarationADefinition() &&
+                StartLoc == (*DI)->getLocStart())
+              DG.push_back(*DI);
+            else
+              break;
+            
+            ++DI;
+          } while (DI != DIEnd);
+          RewriteForwardProtocolDecl(DG);
+          continue;
+        }
+      }
+      
+      HandleTopLevelSingleDecl(*DI);
+      ++DI;
+    }
+  }
+  // If we have a decl in the main file, see if we should rewrite it.
+  if (SM->isWrittenInMainFile(Loc))
+    return HandleDeclInMainFile(D);
+}
+
+//===----------------------------------------------------------------------===//
+// Syntactic (non-AST) Rewriting Code
+//===----------------------------------------------------------------------===//
+
+void RewriteObjC::RewriteInclude() {
+  SourceLocation LocStart = SM->getLocForStartOfFile(MainFileID);
+  StringRef MainBuf = SM->getBufferData(MainFileID);
+  const char *MainBufStart = MainBuf.begin();
+  const char *MainBufEnd = MainBuf.end();
+  size_t ImportLen = strlen("import");
+
+  // Loop over the whole file, looking for includes.
+  for (const char *BufPtr = MainBufStart; BufPtr < MainBufEnd; ++BufPtr) {
+    if (*BufPtr == '#') {
+      if (++BufPtr == MainBufEnd)
+        return;
+      while (*BufPtr == ' ' || *BufPtr == '\t')
+        if (++BufPtr == MainBufEnd)
+          return;
+      if (!strncmp(BufPtr, "import", ImportLen)) {
+        // replace import with include
+        SourceLocation ImportLoc =
+          LocStart.getLocWithOffset(BufPtr-MainBufStart);
+        ReplaceText(ImportLoc, ImportLen, "include");
+        BufPtr += ImportLen;
+      }
+    }
+  }
+}
+
+static std::string getIvarAccessString(ObjCIvarDecl *OID) {
+  const ObjCInterfaceDecl *ClassDecl = OID->getContainingInterface();
+  std::string S;
+  S = "((struct ";
+  S += ClassDecl->getIdentifier()->getName();
+  S += "_IMPL *)self)->";
+  S += OID->getName();
+  return S;
+}
+
+void RewriteObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
+                                          ObjCImplementationDecl *IMD,
+                                          ObjCCategoryImplDecl *CID) {
+  static bool objcGetPropertyDefined = false;
+  static bool objcSetPropertyDefined = false;
+  SourceLocation startLoc = PID->getLocStart();
+  InsertText(startLoc, "// ");
+  const char *startBuf = SM->getCharacterData(startLoc);
+  assert((*startBuf == '@') && "bogus @synthesize location");
+  const char *semiBuf = strchr(startBuf, ';');
+  assert((*semiBuf == ';') && "@synthesize: can't find ';'");
+  SourceLocation onePastSemiLoc =
+    startLoc.getLocWithOffset(semiBuf-startBuf+1);
+
+  if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
+    return; // FIXME: is this correct?
+
+  // Generate the 'getter' function.
+  ObjCPropertyDecl *PD = PID->getPropertyDecl();
+  ObjCIvarDecl *OID = PID->getPropertyIvarDecl();
+
+  if (!OID)
+    return;
+  unsigned Attributes = PD->getPropertyAttributes();
+  if (!PD->getGetterMethodDecl()->isDefined()) {
+    bool GenGetProperty = !(Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) &&
+                          (Attributes & (ObjCPropertyDecl::OBJC_PR_retain | 
+                                         ObjCPropertyDecl::OBJC_PR_copy));
+    std::string Getr;
+    if (GenGetProperty && !objcGetPropertyDefined) {
+      objcGetPropertyDefined = true;
+      // FIXME. Is this attribute correct in all cases?
+      Getr = "\nextern \"C\" __declspec(dllimport) "
+            "id objc_getProperty(id, SEL, long, bool);\n";
+    }
+    RewriteObjCMethodDecl(OID->getContainingInterface(),  
+                          PD->getGetterMethodDecl(), Getr);
+    Getr += "{ ";
+    // Synthesize an explicit cast to gain access to the ivar.
+    // See objc-act.c:objc_synthesize_new_getter() for details.
+    if (GenGetProperty) {
+      // return objc_getProperty(self, _cmd, offsetof(ClassDecl, OID), 1)
+      Getr += "typedef ";
+      const FunctionType *FPRetType = nullptr;
+      RewriteTypeIntoString(PD->getGetterMethodDecl()->getReturnType(), Getr,
+                            FPRetType);
+      Getr += " _TYPE";
+      if (FPRetType) {
+        Getr += ")"; // close the precedence "scope" for "*".
+      
+        // Now, emit the argument types (if any).
+        if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(FPRetType)){
+          Getr += "(";
+          for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
+            if (i) Getr += ", ";
+            std::string ParamStr =
+                FT->getParamType(i).getAsString(Context->getPrintingPolicy());
+            Getr += ParamStr;
+          }
+          if (FT->isVariadic()) {
+            if (FT->getNumParams())
+              Getr += ", ";
+            Getr += "...";
+          }
+          Getr += ")";
+        } else
+          Getr += "()";
+      }
+      Getr += ";\n";
+      Getr += "return (_TYPE)";
+      Getr += "objc_getProperty(self, _cmd, ";
+      RewriteIvarOffsetComputation(OID, Getr);
+      Getr += ", 1)";
+    }
+    else
+      Getr += "return " + getIvarAccessString(OID);
+    Getr += "; }";
+    InsertText(onePastSemiLoc, Getr);
+  }
+  
+  if (PD->isReadOnly() || PD->getSetterMethodDecl()->isDefined())
+    return;
+
+  // Generate the 'setter' function.
+  std::string Setr;
+  bool GenSetProperty = Attributes & (ObjCPropertyDecl::OBJC_PR_retain | 
+                                      ObjCPropertyDecl::OBJC_PR_copy);
+  if (GenSetProperty && !objcSetPropertyDefined) {
+    objcSetPropertyDefined = true;
+    // FIXME. Is this attribute correct in all cases?
+    Setr = "\nextern \"C\" __declspec(dllimport) "
+    "void objc_setProperty (id, SEL, long, id, bool, bool);\n";
+  }
+  
+  RewriteObjCMethodDecl(OID->getContainingInterface(), 
+                        PD->getSetterMethodDecl(), Setr);
+  Setr += "{ ";
+  // Synthesize an explicit cast to initialize the ivar.
+  // See objc-act.c:objc_synthesize_new_setter() for details.
+  if (GenSetProperty) {
+    Setr += "objc_setProperty (self, _cmd, ";
+    RewriteIvarOffsetComputation(OID, Setr);
+    Setr += ", (id)";
+    Setr += PD->getName();
+    Setr += ", ";
+    if (Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic)
+      Setr += "0, ";
+    else
+      Setr += "1, ";
+    if (Attributes & ObjCPropertyDecl::OBJC_PR_copy)
+      Setr += "1)";
+    else
+      Setr += "0)";
+  }
+  else {
+    Setr += getIvarAccessString(OID) + " = ";
+    Setr += PD->getName();
+  }
+  Setr += "; }";
+  InsertText(onePastSemiLoc, Setr);
+}
+
+static void RewriteOneForwardClassDecl(ObjCInterfaceDecl *ForwardDecl,
+                                       std::string &typedefString) {
+  typedefString += "#ifndef _REWRITER_typedef_";
+  typedefString += ForwardDecl->getNameAsString();
+  typedefString += "\n";
+  typedefString += "#define _REWRITER_typedef_";
+  typedefString += ForwardDecl->getNameAsString();
+  typedefString += "\n";
+  typedefString += "typedef struct objc_object ";
+  typedefString += ForwardDecl->getNameAsString();
+  typedefString += ";\n#endif\n";
+}
+
+void RewriteObjC::RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl,
+                                              const std::string &typedefString) {
+    SourceLocation startLoc = ClassDecl->getLocStart();
+    const char *startBuf = SM->getCharacterData(startLoc);
+    const char *semiPtr = strchr(startBuf, ';'); 
+    // Replace the @class with typedefs corresponding to the classes.
+    ReplaceText(startLoc, semiPtr-startBuf+1, typedefString);  
+}
+
+void RewriteObjC::RewriteForwardClassDecl(DeclGroupRef D) {
+  std::string typedefString;
+  for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) {
+    ObjCInterfaceDecl *ForwardDecl = cast<ObjCInterfaceDecl>(*I);
+    if (I == D.begin()) {
+      // Translate to typedef's that forward reference structs with the same name
+      // as the class. As a convenience, we include the original declaration
+      // as a comment.
+      typedefString += "// @class ";
+      typedefString += ForwardDecl->getNameAsString();
+      typedefString += ";\n";
+    }
+    RewriteOneForwardClassDecl(ForwardDecl, typedefString);
+  }
+  DeclGroupRef::iterator I = D.begin();
+  RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(*I), typedefString);
+}
+
+void RewriteObjC::RewriteForwardClassDecl(const SmallVectorImpl<Decl *> &D) {
+  std::string typedefString;
+  for (unsigned i = 0; i < D.size(); i++) {
+    ObjCInterfaceDecl *ForwardDecl = cast<ObjCInterfaceDecl>(D[i]);
+    if (i == 0) {
+      typedefString += "// @class ";
+      typedefString += ForwardDecl->getNameAsString();
+      typedefString += ";\n";
+    }
+    RewriteOneForwardClassDecl(ForwardDecl, typedefString);
+  }
+  RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(D[0]), typedefString);
+}
+
+void RewriteObjC::RewriteMethodDeclaration(ObjCMethodDecl *Method) {
+  // When method is a synthesized one, such as a getter/setter there is
+  // nothing to rewrite.
+  if (Method->isImplicit())
+    return;
+  SourceLocation LocStart = Method->getLocStart();
+  SourceLocation LocEnd = Method->getLocEnd();
+
+  if (SM->getExpansionLineNumber(LocEnd) >
+      SM->getExpansionLineNumber(LocStart)) {
+    InsertText(LocStart, "#if 0\n");
+    ReplaceText(LocEnd, 1, ";\n#endif\n");
+  } else {
+    InsertText(LocStart, "// ");
+  }
+}
+
+void RewriteObjC::RewriteProperty(ObjCPropertyDecl *prop) {
+  SourceLocation Loc = prop->getAtLoc();
+
+  ReplaceText(Loc, 0, "// ");
+  // FIXME: handle properties that are declared across multiple lines.
+}
+
+void RewriteObjC::RewriteCategoryDecl(ObjCCategoryDecl *CatDecl) {
+  SourceLocation LocStart = CatDecl->getLocStart();
+
+  // FIXME: handle category headers that are declared across multiple lines.
+  ReplaceText(LocStart, 0, "// ");
+
+  for (auto *I : CatDecl->properties())
+    RewriteProperty(I);  
+  for (auto *I : CatDecl->instance_methods())
+    RewriteMethodDeclaration(I);
+  for (auto *I : CatDecl->class_methods())
+    RewriteMethodDeclaration(I);
+
+  // Lastly, comment out the @end.
+  ReplaceText(CatDecl->getAtEndRange().getBegin(), 
+              strlen("@end"), "/* @end */");
+}
+
+void RewriteObjC::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) {
+  SourceLocation LocStart = PDecl->getLocStart();
+  assert(PDecl->isThisDeclarationADefinition());
+  
+  // FIXME: handle protocol headers that are declared across multiple lines.
+  ReplaceText(LocStart, 0, "// ");
+
+  for (auto *I : PDecl->instance_methods())
+    RewriteMethodDeclaration(I);
+  for (auto *I : PDecl->class_methods())
+    RewriteMethodDeclaration(I);
+  for (auto *I : PDecl->properties())
+    RewriteProperty(I);
+  
+  // Lastly, comment out the @end.
+  SourceLocation LocEnd = PDecl->getAtEndRange().getBegin();
+  ReplaceText(LocEnd, strlen("@end"), "/* @end */");
+
+  // Must comment out @optional/@required
+  const char *startBuf = SM->getCharacterData(LocStart);
+  const char *endBuf = SM->getCharacterData(LocEnd);
+  for (const char *p = startBuf; p < endBuf; p++) {
+    if (*p == '@' && !strncmp(p+1, "optional", strlen("optional"))) {
+      SourceLocation OptionalLoc = LocStart.getLocWithOffset(p-startBuf);
+      ReplaceText(OptionalLoc, strlen("@optional"), "/* @optional */");
+
+    }
+    else if (*p == '@' && !strncmp(p+1, "required", strlen("required"))) {
+      SourceLocation OptionalLoc = LocStart.getLocWithOffset(p-startBuf);
+      ReplaceText(OptionalLoc, strlen("@required"), "/* @required */");
+
+    }
+  }
+}
+
+void RewriteObjC::RewriteForwardProtocolDecl(DeclGroupRef D) {
+  SourceLocation LocStart = (*D.begin())->getLocStart();
+  if (LocStart.isInvalid())
+    llvm_unreachable("Invalid SourceLocation");
+  // FIXME: handle forward protocol that are declared across multiple lines.
+  ReplaceText(LocStart, 0, "// ");
+}
+
+void 
+RewriteObjC::RewriteForwardProtocolDecl(const SmallVectorImpl<Decl *> &DG) {
+  SourceLocation LocStart = DG[0]->getLocStart();
+  if (LocStart.isInvalid())
+    llvm_unreachable("Invalid SourceLocation");
+  // FIXME: handle forward protocol that are declared across multiple lines.
+  ReplaceText(LocStart, 0, "// ");
+}
+
+void RewriteObjC::RewriteTypeIntoString(QualType T, std::string &ResultStr,
+                                        const FunctionType *&FPRetType) {
+  if (T->isObjCQualifiedIdType())
+    ResultStr += "id";
+  else if (T->isFunctionPointerType() ||
+           T->isBlockPointerType()) {
+    // needs special handling, since pointer-to-functions have special
+    // syntax (where a decaration models use).
+    QualType retType = T;
+    QualType PointeeTy;
+    if (const PointerType* PT = retType->getAs<PointerType>())
+      PointeeTy = PT->getPointeeType();
+    else if (const BlockPointerType *BPT = retType->getAs<BlockPointerType>())
+      PointeeTy = BPT->getPointeeType();
+    if ((FPRetType = PointeeTy->getAs<FunctionType>())) {
+      ResultStr +=
+          FPRetType->getReturnType().getAsString(Context->getPrintingPolicy());
+      ResultStr += "(*";
+    }
+  } else
+    ResultStr += T.getAsString(Context->getPrintingPolicy());
+}
+
+void RewriteObjC::RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl,
+                                        ObjCMethodDecl *OMD,
+                                        std::string &ResultStr) {
+  //fprintf(stderr,"In RewriteObjCMethodDecl\n");
+  const FunctionType *FPRetType = nullptr;
+  ResultStr += "\nstatic ";
+  RewriteTypeIntoString(OMD->getReturnType(), ResultStr, FPRetType);
+  ResultStr += " ";
+
+  // Unique method name
+  std::string NameStr;
+
+  if (OMD->isInstanceMethod())
+    NameStr += "_I_";
+  else
+    NameStr += "_C_";
+
+  NameStr += IDecl->getNameAsString();
+  NameStr += "_";
+
+  if (ObjCCategoryImplDecl *CID =
+      dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext())) {
+    NameStr += CID->getNameAsString();
+    NameStr += "_";
+  }
+  // Append selector names, replacing ':' with '_'
+  {
+    std::string selString = OMD->getSelector().getAsString();
+    int len = selString.size();
+    for (int i = 0; i < len; i++)
+      if (selString[i] == ':')
+        selString[i] = '_';
+    NameStr += selString;
+  }
+  // Remember this name for metadata emission
+  MethodInternalNames[OMD] = NameStr;
+  ResultStr += NameStr;
+
+  // Rewrite arguments
+  ResultStr += "(";
+
+  // invisible arguments
+  if (OMD->isInstanceMethod()) {
+    QualType selfTy = Context->getObjCInterfaceType(IDecl);
+    selfTy = Context->getPointerType(selfTy);
+    if (!LangOpts.MicrosoftExt) {
+      if (ObjCSynthesizedStructs.count(const_cast<ObjCInterfaceDecl*>(IDecl)))
+        ResultStr += "struct ";
+    }
+    // When rewriting for Microsoft, explicitly omit the structure name.
+    ResultStr += IDecl->getNameAsString();
+    ResultStr += " *";
+  }
+  else
+    ResultStr += Context->getObjCClassType().getAsString(
+      Context->getPrintingPolicy());
+
+  ResultStr += " self, ";
+  ResultStr += Context->getObjCSelType().getAsString(Context->getPrintingPolicy());
+  ResultStr += " _cmd";
+
+  // Method arguments.
+  for (const auto *PDecl : OMD->params()) {
+    ResultStr += ", ";
+    if (PDecl->getType()->isObjCQualifiedIdType()) {
+      ResultStr += "id ";
+      ResultStr += PDecl->getNameAsString();
+    } else {
+      std::string Name = PDecl->getNameAsString();
+      QualType QT = PDecl->getType();
+      // Make sure we convert "t (^)(...)" to "t (*)(...)".
+      (void)convertBlockPointerToFunctionPointer(QT);
+      QT.getAsStringInternal(Name, Context->getPrintingPolicy());
+      ResultStr += Name;
+    }
+  }
+  if (OMD->isVariadic())
+    ResultStr += ", ...";
+  ResultStr += ") ";
+
+  if (FPRetType) {
+    ResultStr += ")"; // close the precedence "scope" for "*".
+
+    // Now, emit the argument types (if any).
+    if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(FPRetType)) {
+      ResultStr += "(";
+      for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
+        if (i) ResultStr += ", ";
+        std::string ParamStr =
+            FT->getParamType(i).getAsString(Context->getPrintingPolicy());
+        ResultStr += ParamStr;
+      }
+      if (FT->isVariadic()) {
+        if (FT->getNumParams())
+          ResultStr += ", ";
+        ResultStr += "...";
+      }
+      ResultStr += ")";
+    } else {
+      ResultStr += "()";
+    }
+  }
+}
+void RewriteObjC::RewriteImplementationDecl(Decl *OID) {
+  ObjCImplementationDecl *IMD = dyn_cast<ObjCImplementationDecl>(OID);
+  ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(OID);
+
+  InsertText(IMD ? IMD->getLocStart() : CID->getLocStart(), "// ");
+
+  for (auto *OMD : IMD ? IMD->instance_methods() : CID->instance_methods()) {
+    std::string ResultStr;
+    RewriteObjCMethodDecl(OMD->getClassInterface(), OMD, ResultStr);
+    SourceLocation LocStart = OMD->getLocStart();
+    SourceLocation LocEnd = OMD->getCompoundBody()->getLocStart();
+
+    const char *startBuf = SM->getCharacterData(LocStart);
+    const char *endBuf = SM->getCharacterData(LocEnd);
+    ReplaceText(LocStart, endBuf-startBuf, ResultStr);
+  }
+
+  for (auto *OMD : IMD ? IMD->class_methods() : CID->class_methods()) {
+    std::string ResultStr;
+    RewriteObjCMethodDecl(OMD->getClassInterface(), OMD, ResultStr);
+    SourceLocation LocStart = OMD->getLocStart();
+    SourceLocation LocEnd = OMD->getCompoundBody()->getLocStart();
+
+    const char *startBuf = SM->getCharacterData(LocStart);
+    const char *endBuf = SM->getCharacterData(LocEnd);
+    ReplaceText(LocStart, endBuf-startBuf, ResultStr);
+  }
+  for (auto *I : IMD ? IMD->property_impls() : CID->property_impls())
+    RewritePropertyImplDecl(I, IMD, CID);
+
+  InsertText(IMD ? IMD->getLocEnd() : CID->getLocEnd(), "// ");
+}
+
+void RewriteObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) {
+  std::string ResultStr;
+  if (!ObjCForwardDecls.count(ClassDecl->getCanonicalDecl())) {
+    // we haven't seen a forward decl - generate a typedef.
+    ResultStr = "#ifndef _REWRITER_typedef_";
+    ResultStr += ClassDecl->getNameAsString();
+    ResultStr += "\n";
+    ResultStr += "#define _REWRITER_typedef_";
+    ResultStr += ClassDecl->getNameAsString();
+    ResultStr += "\n";
+    ResultStr += "typedef struct objc_object ";
+    ResultStr += ClassDecl->getNameAsString();
+    ResultStr += ";\n#endif\n";
+    // Mark this typedef as having been generated.
+    ObjCForwardDecls.insert(ClassDecl->getCanonicalDecl());
+  }
+  RewriteObjCInternalStruct(ClassDecl, ResultStr);
+
+  for (auto *I : ClassDecl->properties())
+    RewriteProperty(I);
+  for (auto *I : ClassDecl->instance_methods())
+    RewriteMethodDeclaration(I);
+  for (auto *I : ClassDecl->class_methods())
+    RewriteMethodDeclaration(I);
+
+  // Lastly, comment out the @end.
+  ReplaceText(ClassDecl->getAtEndRange().getBegin(), strlen("@end"), 
+              "/* @end */");
+}
+
+Stmt *RewriteObjC::RewritePropertyOrImplicitSetter(PseudoObjectExpr *PseudoOp) {
+  SourceRange OldRange = PseudoOp->getSourceRange();
+
+  // We just magically know some things about the structure of this
+  // expression.
+  ObjCMessageExpr *OldMsg =
+    cast<ObjCMessageExpr>(PseudoOp->getSemanticExpr(
+                            PseudoOp->getNumSemanticExprs() - 1));
+
+  // Because the rewriter doesn't allow us to rewrite rewritten code,
+  // we need to suppress rewriting the sub-statements.
+  Expr *Base, *RHS;
+  {
+    DisableReplaceStmtScope S(*this);
+
+    // Rebuild the base expression if we have one.
+    Base = nullptr;
+    if (OldMsg->getReceiverKind() == ObjCMessageExpr::Instance) {
+      Base = OldMsg->getInstanceReceiver();
+      Base = cast<OpaqueValueExpr>(Base)->getSourceExpr();
+      Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base));
+    }
+
+    // Rebuild the RHS.
+    RHS = cast<BinaryOperator>(PseudoOp->getSyntacticForm())->getRHS();
+    RHS = cast<OpaqueValueExpr>(RHS)->getSourceExpr();
+    RHS = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(RHS));
+  }
+
+  // TODO: avoid this copy.
+  SmallVector<SourceLocation, 1> SelLocs;
+  OldMsg->getSelectorLocs(SelLocs);
+
+  ObjCMessageExpr *NewMsg = nullptr;
+  switch (OldMsg->getReceiverKind()) {
+  case ObjCMessageExpr::Class:
+    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
+                                     OldMsg->getValueKind(),
+                                     OldMsg->getLeftLoc(),
+                                     OldMsg->getClassReceiverTypeInfo(),
+                                     OldMsg->getSelector(),
+                                     SelLocs,
+                                     OldMsg->getMethodDecl(),
+                                     RHS,
+                                     OldMsg->getRightLoc(),
+                                     OldMsg->isImplicit());
+    break;
+
+  case ObjCMessageExpr::Instance:
+    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
+                                     OldMsg->getValueKind(),
+                                     OldMsg->getLeftLoc(),
+                                     Base,
+                                     OldMsg->getSelector(),
+                                     SelLocs,
+                                     OldMsg->getMethodDecl(),
+                                     RHS,
+                                     OldMsg->getRightLoc(),
+                                     OldMsg->isImplicit());
+    break;
+
+  case ObjCMessageExpr::SuperClass:
+  case ObjCMessageExpr::SuperInstance:
+    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
+                                     OldMsg->getValueKind(),
+                                     OldMsg->getLeftLoc(),
+                                     OldMsg->getSuperLoc(),
+                 OldMsg->getReceiverKind() == ObjCMessageExpr::SuperInstance,
+                                     OldMsg->getSuperType(),
+                                     OldMsg->getSelector(),
+                                     SelLocs,
+                                     OldMsg->getMethodDecl(),
+                                     RHS,
+                                     OldMsg->getRightLoc(),
+                                     OldMsg->isImplicit());
+    break;
+  }
+
+  Stmt *Replacement = SynthMessageExpr(NewMsg);
+  ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
+  return Replacement;
+}
+
+Stmt *RewriteObjC::RewritePropertyOrImplicitGetter(PseudoObjectExpr *PseudoOp) {
+  SourceRange OldRange = PseudoOp->getSourceRange();
+
+  // We just magically know some things about the structure of this
+  // expression.
+  ObjCMessageExpr *OldMsg =
+    cast<ObjCMessageExpr>(PseudoOp->getResultExpr()->IgnoreImplicit());
+
+  // Because the rewriter doesn't allow us to rewrite rewritten code,
+  // we need to suppress rewriting the sub-statements.
+  Expr *Base = nullptr;
+  {
+    DisableReplaceStmtScope S(*this);
+
+    // Rebuild the base expression if we have one.
+    if (OldMsg->getReceiverKind() == ObjCMessageExpr::Instance) {
+      Base = OldMsg->getInstanceReceiver();
+      Base = cast<OpaqueValueExpr>(Base)->getSourceExpr();
+      Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base));
+    }
+  }
+
+  // Intentionally empty.
+  SmallVector<SourceLocation, 1> SelLocs;
+  SmallVector<Expr*, 1> Args;
+
+  ObjCMessageExpr *NewMsg = nullptr;
+  switch (OldMsg->getReceiverKind()) {
+  case ObjCMessageExpr::Class:
+    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
+                                     OldMsg->getValueKind(),
+                                     OldMsg->getLeftLoc(),
+                                     OldMsg->getClassReceiverTypeInfo(),
+                                     OldMsg->getSelector(),
+                                     SelLocs,
+                                     OldMsg->getMethodDecl(),
+                                     Args,
+                                     OldMsg->getRightLoc(),
+                                     OldMsg->isImplicit());
+    break;
+
+  case ObjCMessageExpr::Instance:
+    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
+                                     OldMsg->getValueKind(),
+                                     OldMsg->getLeftLoc(),
+                                     Base,
+                                     OldMsg->getSelector(),
+                                     SelLocs,
+                                     OldMsg->getMethodDecl(),
+                                     Args,
+                                     OldMsg->getRightLoc(),
+                                     OldMsg->isImplicit());
+    break;
+
+  case ObjCMessageExpr::SuperClass:
+  case ObjCMessageExpr::SuperInstance:
+    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
+                                     OldMsg->getValueKind(),
+                                     OldMsg->getLeftLoc(),
+                                     OldMsg->getSuperLoc(),
+                 OldMsg->getReceiverKind() == ObjCMessageExpr::SuperInstance,
+                                     OldMsg->getSuperType(),
+                                     OldMsg->getSelector(),
+                                     SelLocs,
+                                     OldMsg->getMethodDecl(),
+                                     Args,
+                                     OldMsg->getRightLoc(),
+                                     OldMsg->isImplicit());
+    break;
+  }
+
+  Stmt *Replacement = SynthMessageExpr(NewMsg);
+  ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
+  return Replacement;
+}
+
+/// SynthCountByEnumWithState - To print:
+/// ((unsigned int (*)
+///  (id, SEL, struct __objcFastEnumerationState *, id *, unsigned int))
+///  (void *)objc_msgSend)((id)l_collection,
+///                        sel_registerName(
+///                          "countByEnumeratingWithState:objects:count:"),
+///                        &enumState,
+///                        (id *)__rw_items, (unsigned int)16)
+///
+void RewriteObjC::SynthCountByEnumWithState(std::string &buf) {
+  buf += "((unsigned int (*) (id, SEL, struct __objcFastEnumerationState *, "
+  "id *, unsigned int))(void *)objc_msgSend)";
+  buf += "\n\t\t";
+  buf += "((id)l_collection,\n\t\t";
+  buf += "sel_registerName(\"countByEnumeratingWithState:objects:count:\"),";
+  buf += "\n\t\t";
+  buf += "&enumState, "
+         "(id *)__rw_items, (unsigned int)16)";
+}
+
+/// RewriteBreakStmt - Rewrite for a break-stmt inside an ObjC2's foreach
+/// statement to exit to its outer synthesized loop.
+///
+Stmt *RewriteObjC::RewriteBreakStmt(BreakStmt *S) {
+  if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
+    return S;
+  // replace break with goto __break_label
+  std::string buf;
+
+  SourceLocation startLoc = S->getLocStart();
+  buf = "goto __break_label_";
+  buf += utostr(ObjCBcLabelNo.back());
+  ReplaceText(startLoc, strlen("break"), buf);
+
+  return nullptr;
+}
+
+/// RewriteContinueStmt - Rewrite for a continue-stmt inside an ObjC2's foreach
+/// statement to continue with its inner synthesized loop.
+///
+Stmt *RewriteObjC::RewriteContinueStmt(ContinueStmt *S) {
+  if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
+    return S;
+  // replace continue with goto __continue_label
+  std::string buf;
+
+  SourceLocation startLoc = S->getLocStart();
+  buf = "goto __continue_label_";
+  buf += utostr(ObjCBcLabelNo.back());
+  ReplaceText(startLoc, strlen("continue"), buf);
+
+  return nullptr;
+}
+
+/// RewriteObjCForCollectionStmt - Rewriter for ObjC2's foreach statement.
+///  It rewrites:
+/// for ( type elem in collection) { stmts; }
+
+/// Into:
+/// {
+///   type elem;
+///   struct __objcFastEnumerationState enumState = { 0 };
+///   id __rw_items[16];
+///   id l_collection = (id)collection;
+///   unsigned long limit = [l_collection countByEnumeratingWithState:&enumState
+///                                       objects:__rw_items count:16];
+/// if (limit) {
+///   unsigned long startMutations = *enumState.mutationsPtr;
+///   do {
+///        unsigned long counter = 0;
+///        do {
+///             if (startMutations != *enumState.mutationsPtr)
+///               objc_enumerationMutation(l_collection);
+///             elem = (type)enumState.itemsPtr[counter++];
+///             stmts;
+///             __continue_label: ;
+///        } while (counter < limit);
+///   } while (limit = [l_collection countByEnumeratingWithState:&enumState
+///                                  objects:__rw_items count:16]);
+///   elem = nil;
+///   __break_label: ;
+///  }
+///  else
+///       elem = nil;
+///  }
+///
+Stmt *RewriteObjC::RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
+                                                SourceLocation OrigEnd) {
+  assert(!Stmts.empty() && "ObjCForCollectionStmt - Statement stack empty");
+  assert(isa<ObjCForCollectionStmt>(Stmts.back()) &&
+         "ObjCForCollectionStmt Statement stack mismatch");
+  assert(!ObjCBcLabelNo.empty() &&
+         "ObjCForCollectionStmt - Label No stack empty");
+
+  SourceLocation startLoc = S->getLocStart();
+  const char *startBuf = SM->getCharacterData(startLoc);
+  StringRef elementName;
+  std::string elementTypeAsString;
+  std::string buf;
+  buf = "\n{\n\t";
+  if (DeclStmt *DS = dyn_cast<DeclStmt>(S->getElement())) {
+    // type elem;
+    NamedDecl* D = cast<NamedDecl>(DS->getSingleDecl());
+    QualType ElementType = cast<ValueDecl>(D)->getType();
+    if (ElementType->isObjCQualifiedIdType() ||
+        ElementType->isObjCQualifiedInterfaceType())
+      // Simply use 'id' for all qualified types.
+      elementTypeAsString = "id";
+    else
+      elementTypeAsString = ElementType.getAsString(Context->getPrintingPolicy());
+    buf += elementTypeAsString;
+    buf += " ";
+    elementName = D->getName();
+    buf += elementName;
+    buf += ";\n\t";
+  }
+  else {
+    DeclRefExpr *DR = cast<DeclRefExpr>(S->getElement());
+    elementName = DR->getDecl()->getName();
+    ValueDecl *VD = cast<ValueDecl>(DR->getDecl());
+    if (VD->getType()->isObjCQualifiedIdType() ||
+        VD->getType()->isObjCQualifiedInterfaceType())
+      // Simply use 'id' for all qualified types.
+      elementTypeAsString = "id";
+    else
+      elementTypeAsString = VD->getType().getAsString(Context->getPrintingPolicy());
+  }
+
+  // struct __objcFastEnumerationState enumState = { 0 };
+  buf += "struct __objcFastEnumerationState enumState = { 0 };\n\t";
+  // id __rw_items[16];
+  buf += "id __rw_items[16];\n\t";
+  // id l_collection = (id)
+  buf += "id l_collection = (id)";
+  // Find start location of 'collection' the hard way!
+  const char *startCollectionBuf = startBuf;
+  startCollectionBuf += 3;  // skip 'for'
+  startCollectionBuf = strchr(startCollectionBuf, '(');
+  startCollectionBuf++; // skip '('
+  // find 'in' and skip it.
+  while (*startCollectionBuf != ' ' ||
+         *(startCollectionBuf+1) != 'i' || *(startCollectionBuf+2) != 'n' ||
+         (*(startCollectionBuf+3) != ' ' &&
+          *(startCollectionBuf+3) != '[' && *(startCollectionBuf+3) != '('))
+    startCollectionBuf++;
+  startCollectionBuf += 3;
+
+  // Replace: "for (type element in" with string constructed thus far.
+  ReplaceText(startLoc, startCollectionBuf - startBuf, buf);
+  // Replace ')' in for '(' type elem in collection ')' with ';'
+  SourceLocation rightParenLoc = S->getRParenLoc();
+  const char *rparenBuf = SM->getCharacterData(rightParenLoc);
+  SourceLocation lparenLoc = startLoc.getLocWithOffset(rparenBuf-startBuf);
+  buf = ";\n\t";
+
+  // unsigned long limit = [l_collection countByEnumeratingWithState:&enumState
+  //                                   objects:__rw_items count:16];
+  // which is synthesized into:
+  // unsigned int limit =
+  // ((unsigned int (*)
+  //  (id, SEL, struct __objcFastEnumerationState *, id *, unsigned int))
+  //  (void *)objc_msgSend)((id)l_collection,
+  //                        sel_registerName(
+  //                          "countByEnumeratingWithState:objects:count:"),
+  //                        (struct __objcFastEnumerationState *)&state,
+  //                        (id *)__rw_items, (unsigned int)16);
+  buf += "unsigned long limit =\n\t\t";
+  SynthCountByEnumWithState(buf);
+  buf += ";\n\t";
+  /// if (limit) {
+  ///   unsigned long startMutations = *enumState.mutationsPtr;
+  ///   do {
+  ///        unsigned long counter = 0;
+  ///        do {
+  ///             if (startMutations != *enumState.mutationsPtr)
+  ///               objc_enumerationMutation(l_collection);
+  ///             elem = (type)enumState.itemsPtr[counter++];
+  buf += "if (limit) {\n\t";
+  buf += "unsigned long startMutations = *enumState.mutationsPtr;\n\t";
+  buf += "do {\n\t\t";
+  buf += "unsigned long counter = 0;\n\t\t";
+  buf += "do {\n\t\t\t";
+  buf += "if (startMutations != *enumState.mutationsPtr)\n\t\t\t\t";
+  buf += "objc_enumerationMutation(l_collection);\n\t\t\t";
+  buf += elementName;
+  buf += " = (";
+  buf += elementTypeAsString;
+  buf += ")enumState.itemsPtr[counter++];";
+  // Replace ')' in for '(' type elem in collection ')' with all of these.
+  ReplaceText(lparenLoc, 1, buf);
+
+  ///            __continue_label: ;
+  ///        } while (counter < limit);
+  ///   } while (limit = [l_collection countByEnumeratingWithState:&enumState
+  ///                                  objects:__rw_items count:16]);
+  ///   elem = nil;
+  ///   __break_label: ;
+  ///  }
+  ///  else
+  ///       elem = nil;
+  ///  }
+  ///
+  buf = ";\n\t";
+  buf += "__continue_label_";
+  buf += utostr(ObjCBcLabelNo.back());
+  buf += ": ;";
+  buf += "\n\t\t";
+  buf += "} while (counter < limit);\n\t";
+  buf += "} while (limit = ";
+  SynthCountByEnumWithState(buf);
+  buf += ");\n\t";
+  buf += elementName;
+  buf += " = ((";
+  buf += elementTypeAsString;
+  buf += ")0);\n\t";
+  buf += "__break_label_";
+  buf += utostr(ObjCBcLabelNo.back());
+  buf += ": ;\n\t";
+  buf += "}\n\t";
+  buf += "else\n\t\t";
+  buf += elementName;
+  buf += " = ((";
+  buf += elementTypeAsString;
+  buf += ")0);\n\t";
+  buf += "}\n";
+
+  // Insert all these *after* the statement body.
+  // FIXME: If this should support Obj-C++, support CXXTryStmt
+  if (isa<CompoundStmt>(S->getBody())) {
+    SourceLocation endBodyLoc = OrigEnd.getLocWithOffset(1);
+    InsertText(endBodyLoc, buf);
+  } else {
+    /* Need to treat single statements specially. For example:
+     *
+     *     for (A *a in b) if (stuff()) break;
+     *     for (A *a in b) xxxyy;
+     *
+     * The following code simply scans ahead to the semi to find the actual end.
+     */
+    const char *stmtBuf = SM->getCharacterData(OrigEnd);
+    const char *semiBuf = strchr(stmtBuf, ';');
+    assert(semiBuf && "Can't find ';'");
+    SourceLocation endBodyLoc = OrigEnd.getLocWithOffset(semiBuf-stmtBuf+1);
+    InsertText(endBodyLoc, buf);
+  }
+  Stmts.pop_back();
+  ObjCBcLabelNo.pop_back();
+  return nullptr;
+}
+
+/// RewriteObjCSynchronizedStmt -
+/// This routine rewrites @synchronized(expr) stmt;
+/// into:
+/// objc_sync_enter(expr);
+/// @try stmt @finally { objc_sync_exit(expr); }
+///
+Stmt *RewriteObjC::RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
+  // Get the start location and compute the semi location.
+  SourceLocation startLoc = S->getLocStart();
+  const char *startBuf = SM->getCharacterData(startLoc);
+
+  assert((*startBuf == '@') && "bogus @synchronized location");
+
+  std::string buf;
+  buf = "objc_sync_enter((id)";
+  const char *lparenBuf = startBuf;
+  while (*lparenBuf != '(') lparenBuf++;
+  ReplaceText(startLoc, lparenBuf-startBuf+1, buf);
+  // We can't use S->getSynchExpr()->getLocEnd() to find the end location, since
+  // the sync expression is typically a message expression that's already
+  // been rewritten! (which implies the SourceLocation's are invalid).
+  SourceLocation endLoc = S->getSynchBody()->getLocStart();
+  const char *endBuf = SM->getCharacterData(endLoc);
+  while (*endBuf != ')') endBuf--;
+  SourceLocation rparenLoc = startLoc.getLocWithOffset(endBuf-startBuf);
+  buf = ");\n";
+  // declare a new scope with two variables, _stack and _rethrow.
+  buf += "/* @try scope begin */ \n{ struct _objc_exception_data {\n";
+  buf += "int buf[18/*32-bit i386*/];\n";
+  buf += "char *pointers[4];} _stack;\n";
+  buf += "id volatile _rethrow = 0;\n";
+  buf += "objc_exception_try_enter(&_stack);\n";
+  buf += "if (!_setjmp(_stack.buf)) /* @try block continue */\n";
+  ReplaceText(rparenLoc, 1, buf);
+  startLoc = S->getSynchBody()->getLocEnd();
+  startBuf = SM->getCharacterData(startLoc);
+
+  assert((*startBuf == '}') && "bogus @synchronized block");
+  SourceLocation lastCurlyLoc = startLoc;
+  buf = "}\nelse {\n";
+  buf += "  _rethrow = objc_exception_extract(&_stack);\n";
+  buf += "}\n";
+  buf += "{ /* implicit finally clause */\n";
+  buf += "  if (!_rethrow) objc_exception_try_exit(&_stack);\n";
+  
+  std::string syncBuf;
+  syncBuf += " objc_sync_exit(";
+
+  Expr *syncExpr = S->getSynchExpr();
+  CastKind CK = syncExpr->getType()->isObjCObjectPointerType()
+                  ? CK_BitCast :
+                syncExpr->getType()->isBlockPointerType()
+                  ? CK_BlockPointerToObjCPointerCast
+                  : CK_CPointerToObjCPointerCast;
+  syncExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+                                      CK, syncExpr);
+  std::string syncExprBufS;
+  llvm::raw_string_ostream syncExprBuf(syncExprBufS);
+  assert(syncExpr != nullptr && "Expected non-null Expr");
+  syncExpr->printPretty(syncExprBuf, nullptr, PrintingPolicy(LangOpts));
+  syncBuf += syncExprBuf.str();
+  syncBuf += ");";
+  
+  buf += syncBuf;
+  buf += "\n  if (_rethrow) objc_exception_throw(_rethrow);\n";
+  buf += "}\n";
+  buf += "}";
+
+  ReplaceText(lastCurlyLoc, 1, buf);
+
+  bool hasReturns = false;
+  HasReturnStmts(S->getSynchBody(), hasReturns);
+  if (hasReturns)
+    RewriteSyncReturnStmts(S->getSynchBody(), syncBuf);
+
+  return nullptr;
+}
+
+void RewriteObjC::WarnAboutReturnGotoStmts(Stmt *S)
+{
+  // Perform a bottom up traversal of all children.
+  for (Stmt::child_range CI = S->children(); CI; ++CI)
+    if (*CI)
+      WarnAboutReturnGotoStmts(*CI);
+
+  if (isa<ReturnStmt>(S) || isa<GotoStmt>(S)) {
+    Diags.Report(Context->getFullLoc(S->getLocStart()),
+                 TryFinallyContainsReturnDiag);
+  }
+  return;
+}
+
+void RewriteObjC::HasReturnStmts(Stmt *S, bool &hasReturns) 
+{  
+  // Perform a bottom up traversal of all children.
+  for (Stmt::child_range CI = S->children(); CI; ++CI)
+   if (*CI)
+     HasReturnStmts(*CI, hasReturns);
+
+ if (isa<ReturnStmt>(S))
+   hasReturns = true;
+ return;
+}
+
+void RewriteObjC::RewriteTryReturnStmts(Stmt *S) {
+ // Perform a bottom up traversal of all children.
+ for (Stmt::child_range CI = S->children(); CI; ++CI)
+   if (*CI) {
+     RewriteTryReturnStmts(*CI);
+   }
+ if (isa<ReturnStmt>(S)) {
+   SourceLocation startLoc = S->getLocStart();
+   const char *startBuf = SM->getCharacterData(startLoc);
+
+   const char *semiBuf = strchr(startBuf, ';');
+   assert((*semiBuf == ';') && "RewriteTryReturnStmts: can't find ';'");
+   SourceLocation onePastSemiLoc = startLoc.getLocWithOffset(semiBuf-startBuf+1);
+
+   std::string buf;
+   buf = "{ objc_exception_try_exit(&_stack); return";
+   
+   ReplaceText(startLoc, 6, buf);
+   InsertText(onePastSemiLoc, "}");
+ }
+ return;
+}
+
+void RewriteObjC::RewriteSyncReturnStmts(Stmt *S, std::string syncExitBuf) {
+  // Perform a bottom up traversal of all children.
+  for (Stmt::child_range CI = S->children(); CI; ++CI)
+    if (*CI) {
+      RewriteSyncReturnStmts(*CI, syncExitBuf);
+    }
+  if (isa<ReturnStmt>(S)) {
+    SourceLocation startLoc = S->getLocStart();
+    const char *startBuf = SM->getCharacterData(startLoc);
+
+    const char *semiBuf = strchr(startBuf, ';');
+    assert((*semiBuf == ';') && "RewriteSyncReturnStmts: can't find ';'");
+    SourceLocation onePastSemiLoc = startLoc.getLocWithOffset(semiBuf-startBuf+1);
+
+    std::string buf;
+    buf = "{ objc_exception_try_exit(&_stack);";
+    buf += syncExitBuf;
+    buf += " return";
+    
+    ReplaceText(startLoc, 6, buf);
+    InsertText(onePastSemiLoc, "}");
+  }
+  return;
+}
+
+Stmt *RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
+  // Get the start location and compute the semi location.
+  SourceLocation startLoc = S->getLocStart();
+  const char *startBuf = SM->getCharacterData(startLoc);
+
+  assert((*startBuf == '@') && "bogus @try location");
+
+  std::string buf;
+  // declare a new scope with two variables, _stack and _rethrow.
+  buf = "/* @try scope begin */ { struct _objc_exception_data {\n";
+  buf += "int buf[18/*32-bit i386*/];\n";
+  buf += "char *pointers[4];} _stack;\n";
+  buf += "id volatile _rethrow = 0;\n";
+  buf += "objc_exception_try_enter(&_stack);\n";
+  buf += "if (!_setjmp(_stack.buf)) /* @try block continue */\n";
+
+  ReplaceText(startLoc, 4, buf);
+
+  startLoc = S->getTryBody()->getLocEnd();
+  startBuf = SM->getCharacterData(startLoc);
+
+  assert((*startBuf == '}') && "bogus @try block");
+
+  SourceLocation lastCurlyLoc = startLoc;
+  if (S->getNumCatchStmts()) {
+    startLoc = startLoc.getLocWithOffset(1);
+    buf = " /* @catch begin */ else {\n";
+    buf += " id _caught = objc_exception_extract(&_stack);\n";
+    buf += " objc_exception_try_enter (&_stack);\n";
+    buf += " if (_setjmp(_stack.buf))\n";
+    buf += "   _rethrow = objc_exception_extract(&_stack);\n";
+    buf += " else { /* @catch continue */";
+
+    InsertText(startLoc, buf);
+  } else { /* no catch list */
+    buf = "}\nelse {\n";
+    buf += "  _rethrow = objc_exception_extract(&_stack);\n";
+    buf += "}";
+    ReplaceText(lastCurlyLoc, 1, buf);
+  }
+  Stmt *lastCatchBody = nullptr;
+  for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
+    ObjCAtCatchStmt *Catch = S->getCatchStmt(I);
+    VarDecl *catchDecl = Catch->getCatchParamDecl();
+
+    if (I == 0)
+      buf = "if ("; // we are generating code for the first catch clause
+    else
+      buf = "else if (";
+    startLoc = Catch->getLocStart();
+    startBuf = SM->getCharacterData(startLoc);
+
+    assert((*startBuf == '@') && "bogus @catch location");
+
+    const char *lParenLoc = strchr(startBuf, '(');
+
+    if (Catch->hasEllipsis()) {
+      // Now rewrite the body...
+      lastCatchBody = Catch->getCatchBody();
+      SourceLocation bodyLoc = lastCatchBody->getLocStart();
+      const char *bodyBuf = SM->getCharacterData(bodyLoc);
+      assert(*SM->getCharacterData(Catch->getRParenLoc()) == ')' &&
+             "bogus @catch paren location");
+      assert((*bodyBuf == '{') && "bogus @catch body location");
+
+      buf += "1) { id _tmp = _caught;";
+      Rewrite.ReplaceText(startLoc, bodyBuf-startBuf+1, buf);
+    } else if (catchDecl) {
+      QualType t = catchDecl->getType();
+      if (t == Context->getObjCIdType()) {
+        buf += "1) { ";
+        ReplaceText(startLoc, lParenLoc-startBuf+1, buf);
+      } else if (const ObjCObjectPointerType *Ptr =
+                   t->getAs<ObjCObjectPointerType>()) {
+        // Should be a pointer to a class.
+        ObjCInterfaceDecl *IDecl = Ptr->getObjectType()->getInterface();
+        if (IDecl) {
+          buf += "objc_exception_match((struct objc_class *)objc_getClass(\"";
+          buf += IDecl->getNameAsString();
+          buf += "\"), (struct objc_object *)_caught)) { ";
+          ReplaceText(startLoc, lParenLoc-startBuf+1, buf);
+        }
+      }
+      // Now rewrite the body...
+      lastCatchBody = Catch->getCatchBody();
+      SourceLocation rParenLoc = Catch->getRParenLoc();
+      SourceLocation bodyLoc = lastCatchBody->getLocStart();
+      const char *bodyBuf = SM->getCharacterData(bodyLoc);
+      const char *rParenBuf = SM->getCharacterData(rParenLoc);
+      assert((*rParenBuf == ')') && "bogus @catch paren location");
+      assert((*bodyBuf == '{') && "bogus @catch body location");
+
+      // Here we replace ") {" with "= _caught;" (which initializes and
+      // declares the @catch parameter).
+      ReplaceText(rParenLoc, bodyBuf-rParenBuf+1, " = _caught;");
+    } else {
+      llvm_unreachable("@catch rewrite bug");
+    }
+  }
+  // Complete the catch list...
+  if (lastCatchBody) {
+    SourceLocation bodyLoc = lastCatchBody->getLocEnd();
+    assert(*SM->getCharacterData(bodyLoc) == '}' &&
+           "bogus @catch body location");
+
+    // Insert the last (implicit) else clause *before* the right curly brace.
+    bodyLoc = bodyLoc.getLocWithOffset(-1);
+    buf = "} /* last catch end */\n";
+    buf += "else {\n";
+    buf += " _rethrow = _caught;\n";
+    buf += " objc_exception_try_exit(&_stack);\n";
+    buf += "} } /* @catch end */\n";
+    if (!S->getFinallyStmt())
+      buf += "}\n";
+    InsertText(bodyLoc, buf);
+
+    // Set lastCurlyLoc
+    lastCurlyLoc = lastCatchBody->getLocEnd();
+  }
+  if (ObjCAtFinallyStmt *finalStmt = S->getFinallyStmt()) {
+    startLoc = finalStmt->getLocStart();
+    startBuf = SM->getCharacterData(startLoc);
+    assert((*startBuf == '@') && "bogus @finally start");
+
+    ReplaceText(startLoc, 8, "/* @finally */");
+
+    Stmt *body = finalStmt->getFinallyBody();
+    SourceLocation startLoc = body->getLocStart();
+    SourceLocation endLoc = body->getLocEnd();
+    assert(*SM->getCharacterData(startLoc) == '{' &&
+           "bogus @finally body location");
+    assert(*SM->getCharacterData(endLoc) == '}' &&
+           "bogus @finally body location");
+
+    startLoc = startLoc.getLocWithOffset(1);
+    InsertText(startLoc, " if (!_rethrow) objc_exception_try_exit(&_stack);\n");
+    endLoc = endLoc.getLocWithOffset(-1);
+    InsertText(endLoc, " if (_rethrow) objc_exception_throw(_rethrow);\n");
+
+    // Set lastCurlyLoc
+    lastCurlyLoc = body->getLocEnd();
+
+    // Now check for any return/continue/go statements within the @try.
+    WarnAboutReturnGotoStmts(S->getTryBody());
+  } else { /* no finally clause - make sure we synthesize an implicit one */
+    buf = "{ /* implicit finally clause */\n";
+    buf += " if (!_rethrow) objc_exception_try_exit(&_stack);\n";
+    buf += " if (_rethrow) objc_exception_throw(_rethrow);\n";
+    buf += "}";
+    ReplaceText(lastCurlyLoc, 1, buf);
+    
+    // Now check for any return/continue/go statements within the @try.
+    // The implicit finally clause won't called if the @try contains any
+    // jump statements.
+    bool hasReturns = false;
+    HasReturnStmts(S->getTryBody(), hasReturns);
+    if (hasReturns)
+      RewriteTryReturnStmts(S->getTryBody());
+  }
+  // Now emit the final closing curly brace...
+  lastCurlyLoc = lastCurlyLoc.getLocWithOffset(1);
+  InsertText(lastCurlyLoc, " } /* @try scope end */\n");
+  return nullptr;
+}
+
+// This can't be done with ReplaceStmt(S, ThrowExpr), since
+// the throw expression is typically a message expression that's already
+// been rewritten! (which implies the SourceLocation's are invalid).
+Stmt *RewriteObjC::RewriteObjCThrowStmt(ObjCAtThrowStmt *S) {
+  // Get the start location and compute the semi location.
+  SourceLocation startLoc = S->getLocStart();
+  const char *startBuf = SM->getCharacterData(startLoc);
+
+  assert((*startBuf == '@') && "bogus @throw location");
+
+  std::string buf;
+  /* void objc_exception_throw(id) __attribute__((noreturn)); */
+  if (S->getThrowExpr())
+    buf = "objc_exception_throw(";
+  else // add an implicit argument
+    buf = "objc_exception_throw(_caught";
+
+  // handle "@  throw" correctly.
+  const char *wBuf = strchr(startBuf, 'w');
+  assert((*wBuf == 'w') && "@throw: can't find 'w'");
+  ReplaceText(startLoc, wBuf-startBuf+1, buf);
+
+  const char *semiBuf = strchr(startBuf, ';');
+  assert((*semiBuf == ';') && "@throw: can't find ';'");
+  SourceLocation semiLoc = startLoc.getLocWithOffset(semiBuf-startBuf);
+  ReplaceText(semiLoc, 1, ");");
+  return nullptr;
+}
+
+Stmt *RewriteObjC::RewriteAtEncode(ObjCEncodeExpr *Exp) {
+  // Create a new string expression.
+  std::string StrEncoding;
+  Context->getObjCEncodingForType(Exp->getEncodedType(), StrEncoding);
+  Expr *Replacement = getStringLiteral(StrEncoding);
+  ReplaceStmt(Exp, Replacement);
+
+  // Replace this subexpr in the parent.
+  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
+  return Replacement;
+}
+
+Stmt *RewriteObjC::RewriteAtSelector(ObjCSelectorExpr *Exp) {
+  if (!SelGetUidFunctionDecl)
+    SynthSelGetUidFunctionDecl();
+  assert(SelGetUidFunctionDecl && "Can't find sel_registerName() decl");
+  // Create a call to sel_registerName("selName").
+  SmallVector<Expr*, 8> SelExprs;
+  SelExprs.push_back(getStringLiteral(Exp->getSelector().getAsString()));
+  CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
+                                                 &SelExprs[0], SelExprs.size());
+  ReplaceStmt(Exp, SelExp);
+  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
+  return SelExp;
+}
+
+CallExpr *RewriteObjC::SynthesizeCallToFunctionDecl(
+  FunctionDecl *FD, Expr **args, unsigned nargs, SourceLocation StartLoc,
+                                                    SourceLocation EndLoc) {
+  // Get the type, we will need to reference it in a couple spots.
+  QualType msgSendType = FD->getType();
+
+  // Create a reference to the objc_msgSend() declaration.
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, false, msgSendType,
+                                               VK_LValue, SourceLocation());
+
+  // Now, we cast the reference to a pointer to the objc_msgSend type.
+  QualType pToFunc = Context->getPointerType(msgSendType);
+  ImplicitCastExpr *ICE =
+    ImplicitCastExpr::Create(*Context, pToFunc, CK_FunctionToPointerDecay,
+                             DRE, nullptr, VK_RValue);
+
+  const FunctionType *FT = msgSendType->getAs<FunctionType>();
+
+  CallExpr *Exp =  
+    new (Context) CallExpr(*Context, ICE, llvm::makeArrayRef(args, nargs),
+                           FT->getCallResultType(*Context),
+                           VK_RValue, EndLoc);
+  return Exp;
+}
+
+static bool scanForProtocolRefs(const char *startBuf, const char *endBuf,
+                                const char *&startRef, const char *&endRef) {
+  while (startBuf < endBuf) {
+    if (*startBuf == '<')
+      startRef = startBuf; // mark the start.
+    if (*startBuf == '>') {
+      if (startRef && *startRef == '<') {
+        endRef = startBuf; // mark the end.
+        return true;
+      }
+      return false;
+    }
+    startBuf++;
+  }
+  return false;
+}
+
+static void scanToNextArgument(const char *&argRef) {
+  int angle = 0;
+  while (*argRef != ')' && (*argRef != ',' || angle > 0)) {
+    if (*argRef == '<')
+      angle++;
+    else if (*argRef == '>')
+      angle--;
+    argRef++;
+  }
+  assert(angle == 0 && "scanToNextArgument - bad protocol type syntax");
+}
+
+bool RewriteObjC::needToScanForQualifiers(QualType T) {
+  if (T->isObjCQualifiedIdType())
+    return true;
+  if (const PointerType *PT = T->getAs<PointerType>()) {
+    if (PT->getPointeeType()->isObjCQualifiedIdType())
+      return true;
+  }
+  if (T->isObjCObjectPointerType()) {
+    T = T->getPointeeType();
+    return T->isObjCQualifiedInterfaceType();
+  }
+  if (T->isArrayType()) {
+    QualType ElemTy = Context->getBaseElementType(T);
+    return needToScanForQualifiers(ElemTy);
+  }
+  return false;
+}
+
+void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Expr *E) {
+  QualType Type = E->getType();
+  if (needToScanForQualifiers(Type)) {
+    SourceLocation Loc, EndLoc;
+
+    if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E)) {
+      Loc = ECE->getLParenLoc();
+      EndLoc = ECE->getRParenLoc();
+    } else {
+      Loc = E->getLocStart();
+      EndLoc = E->getLocEnd();
+    }
+    // This will defend against trying to rewrite synthesized expressions.
+    if (Loc.isInvalid() || EndLoc.isInvalid())
+      return;
+
+    const char *startBuf = SM->getCharacterData(Loc);
+    const char *endBuf = SM->getCharacterData(EndLoc);
+    const char *startRef = nullptr, *endRef = nullptr;
+    if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
+      // Get the locations of the startRef, endRef.
+      SourceLocation LessLoc = Loc.getLocWithOffset(startRef-startBuf);
+      SourceLocation GreaterLoc = Loc.getLocWithOffset(endRef-startBuf+1);
+      // Comment out the protocol references.
+      InsertText(LessLoc, "/*");
+      InsertText(GreaterLoc, "*/");
+    }
+  }
+}
+
+void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Decl *Dcl) {
+  SourceLocation Loc;
+  QualType Type;
+  const FunctionProtoType *proto = nullptr;
+  if (VarDecl *VD = dyn_cast<VarDecl>(Dcl)) {
+    Loc = VD->getLocation();
+    Type = VD->getType();
+  }
+  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(Dcl)) {
+    Loc = FD->getLocation();
+    // Check for ObjC 'id' and class types that have been adorned with protocol
+    // information (id<p>, C<p>*). The protocol references need to be rewritten!
+    const FunctionType *funcType = FD->getType()->getAs<FunctionType>();
+    assert(funcType && "missing function type");
+    proto = dyn_cast<FunctionProtoType>(funcType);
+    if (!proto)
+      return;
+    Type = proto->getReturnType();
+  }
+  else if (FieldDecl *FD = dyn_cast<FieldDecl>(Dcl)) {
+    Loc = FD->getLocation();
+    Type = FD->getType();
+  }
+  else
+    return;
+
+  if (needToScanForQualifiers(Type)) {
+    // Since types are unique, we need to scan the buffer.
+
+    const char *endBuf = SM->getCharacterData(Loc);
+    const char *startBuf = endBuf;
+    while (*startBuf != ';' && *startBuf != '<' && startBuf != MainFileStart)
+      startBuf--; // scan backward (from the decl location) for return type.
+    const char *startRef = nullptr, *endRef = nullptr;
+    if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
+      // Get the locations of the startRef, endRef.
+      SourceLocation LessLoc = Loc.getLocWithOffset(startRef-endBuf);
+      SourceLocation GreaterLoc = Loc.getLocWithOffset(endRef-endBuf+1);
+      // Comment out the protocol references.
+      InsertText(LessLoc, "/*");
+      InsertText(GreaterLoc, "*/");
+    }
+  }
+  if (!proto)
+      return; // most likely, was a variable
+  // Now check arguments.
+  const char *startBuf = SM->getCharacterData(Loc);
+  const char *startFuncBuf = startBuf;
+  for (unsigned i = 0; i < proto->getNumParams(); i++) {
+    if (needToScanForQualifiers(proto->getParamType(i))) {
+      // Since types are unique, we need to scan the buffer.
+
+      const char *endBuf = startBuf;
+      // scan forward (from the decl location) for argument types.
+      scanToNextArgument(endBuf);
+      const char *startRef = nullptr, *endRef = nullptr;
+      if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
+        // Get the locations of the startRef, endRef.
+        SourceLocation LessLoc =
+          Loc.getLocWithOffset(startRef-startFuncBuf);
+        SourceLocation GreaterLoc =
+          Loc.getLocWithOffset(endRef-startFuncBuf+1);
+        // Comment out the protocol references.
+        InsertText(LessLoc, "/*");
+        InsertText(GreaterLoc, "*/");
+      }
+      startBuf = ++endBuf;
+    }
+    else {
+      // If the function name is derived from a macro expansion, then the
+      // argument buffer will not follow the name. Need to speak with Chris.
+      while (*startBuf && *startBuf != ')' && *startBuf != ',')
+        startBuf++; // scan forward (from the decl location) for argument types.
+      startBuf++;
+    }
+  }
+}
+
+void RewriteObjC::RewriteTypeOfDecl(VarDecl *ND) {
+  QualType QT = ND->getType();
+  const Type* TypePtr = QT->getAs<Type>();
+  if (!isa<TypeOfExprType>(TypePtr))
+    return;
+  while (isa<TypeOfExprType>(TypePtr)) {
+    const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
+    QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType();
+    TypePtr = QT->getAs<Type>();
+  }
+  // FIXME. This will not work for multiple declarators; as in:
+  // __typeof__(a) b,c,d;
+  std::string TypeAsString(QT.getAsString(Context->getPrintingPolicy()));
+  SourceLocation DeclLoc = ND->getTypeSpecStartLoc();
+  const char *startBuf = SM->getCharacterData(DeclLoc);
+  if (ND->getInit()) {
+    std::string Name(ND->getNameAsString());
+    TypeAsString += " " + Name + " = ";
+    Expr *E = ND->getInit();
+    SourceLocation startLoc;
+    if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E))
+      startLoc = ECE->getLParenLoc();
+    else
+      startLoc = E->getLocStart();
+    startLoc = SM->getExpansionLoc(startLoc);
+    const char *endBuf = SM->getCharacterData(startLoc);
+    ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
+  }
+  else {
+    SourceLocation X = ND->getLocEnd();
+    X = SM->getExpansionLoc(X);
+    const char *endBuf = SM->getCharacterData(X);
+    ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
+  }
+}
+
+// SynthSelGetUidFunctionDecl - SEL sel_registerName(const char *str);
+void RewriteObjC::SynthSelGetUidFunctionDecl() {
+  IdentifierInfo *SelGetUidIdent = &Context->Idents.get("sel_registerName");
+  SmallVector<QualType, 16> ArgTys;
+  ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
+  QualType getFuncType =
+    getSimpleFunctionType(Context->getObjCSelType(), ArgTys);
+  SelGetUidFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                               SourceLocation(),
+                                               SourceLocation(),
+                                               SelGetUidIdent, getFuncType,
+                                               nullptr, SC_Extern);
+}
+
+void RewriteObjC::RewriteFunctionDecl(FunctionDecl *FD) {
+  // declared in <objc/objc.h>
+  if (FD->getIdentifier() &&
+      FD->getName() == "sel_registerName") {
+    SelGetUidFunctionDecl = FD;
+    return;
+  }
+  RewriteObjCQualifiedInterfaceTypes(FD);
+}
+
+void RewriteObjC::RewriteBlockPointerType(std::string& Str, QualType Type) {
+  std::string TypeString(Type.getAsString(Context->getPrintingPolicy()));
+  const char *argPtr = TypeString.c_str();
+  if (!strchr(argPtr, '^')) {
+    Str += TypeString;
+    return;
+  }
+  while (*argPtr) {
+    Str += (*argPtr == '^' ? '*' : *argPtr);
+    argPtr++;
+  }
+}
+
+// FIXME. Consolidate this routine with RewriteBlockPointerType.
+void RewriteObjC::RewriteBlockPointerTypeVariable(std::string& Str,
+                                                  ValueDecl *VD) {
+  QualType Type = VD->getType();
+  std::string TypeString(Type.getAsString(Context->getPrintingPolicy()));
+  const char *argPtr = TypeString.c_str();
+  int paren = 0;
+  while (*argPtr) {
+    switch (*argPtr) {
+      case '(':
+        Str += *argPtr;
+        paren++;
+        break;
+      case ')':
+        Str += *argPtr;
+        paren--;
+        break;
+      case '^':
+        Str += '*';
+        if (paren == 1)
+          Str += VD->getNameAsString();
+        break;
+      default:
+        Str += *argPtr;
+        break;
+    }
+    argPtr++;
+  }
+}
+
+
+void RewriteObjC::RewriteBlockLiteralFunctionDecl(FunctionDecl *FD) {
+  SourceLocation FunLocStart = FD->getTypeSpecStartLoc();
+  const FunctionType *funcType = FD->getType()->getAs<FunctionType>();
+  const FunctionProtoType *proto = dyn_cast<FunctionProtoType>(funcType);
+  if (!proto)
+    return;
+  QualType Type = proto->getReturnType();
+  std::string FdStr = Type.getAsString(Context->getPrintingPolicy());
+  FdStr += " ";
+  FdStr += FD->getName();
+  FdStr +=  "(";
+  unsigned numArgs = proto->getNumParams();
+  for (unsigned i = 0; i < numArgs; i++) {
+    QualType ArgType = proto->getParamType(i);
+    RewriteBlockPointerType(FdStr, ArgType);
+    if (i+1 < numArgs)
+      FdStr += ", ";
+  }
+  FdStr +=  ");\n";
+  InsertText(FunLocStart, FdStr);
+  CurFunctionDeclToDeclareForBlock = nullptr;
+}
+
+// SynthSuperConstructorFunctionDecl - id objc_super(id obj, id super);
+void RewriteObjC::SynthSuperConstructorFunctionDecl() {
+  if (SuperConstructorFunctionDecl)
+    return;
+  IdentifierInfo *msgSendIdent = &Context->Idents.get("__rw_objc_super");
+  SmallVector<QualType, 16> ArgTys;
+  QualType argT = Context->getObjCIdType();
+  assert(!argT.isNull() && "Can't find 'id' type");
+  ArgTys.push_back(argT);
+  ArgTys.push_back(argT);
+  QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
+                                               ArgTys);
+  SuperConstructorFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                                     SourceLocation(),
+                                                     SourceLocation(),
+                                                     msgSendIdent, msgSendType,
+                                                     nullptr, SC_Extern);
+}
+
+// SynthMsgSendFunctionDecl - id objc_msgSend(id self, SEL op, ...);
+void RewriteObjC::SynthMsgSendFunctionDecl() {
+  IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend");
+  SmallVector<QualType, 16> ArgTys;
+  QualType argT = Context->getObjCIdType();
+  assert(!argT.isNull() && "Can't find 'id' type");
+  ArgTys.push_back(argT);
+  argT = Context->getObjCSelType();
+  assert(!argT.isNull() && "Can't find 'SEL' type");
+  ArgTys.push_back(argT);
+  QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
+                                               ArgTys, /*isVariadic=*/true);
+  MsgSendFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                             SourceLocation(),
+                                             SourceLocation(),
+                                             msgSendIdent, msgSendType,
+                                             nullptr, SC_Extern);
+}
+
+// SynthMsgSendSuperFunctionDecl - id objc_msgSendSuper(struct objc_super *, SEL op, ...);
+void RewriteObjC::SynthMsgSendSuperFunctionDecl() {
+  IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSendSuper");
+  SmallVector<QualType, 16> ArgTys;
+  RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
+                                      SourceLocation(), SourceLocation(),
+                                      &Context->Idents.get("objc_super"));
+  QualType argT = Context->getPointerType(Context->getTagDeclType(RD));
+  assert(!argT.isNull() && "Can't build 'struct objc_super *' type");
+  ArgTys.push_back(argT);
+  argT = Context->getObjCSelType();
+  assert(!argT.isNull() && "Can't find 'SEL' type");
+  ArgTys.push_back(argT);
+  QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
+                                               ArgTys, /*isVariadic=*/true);
+  MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                                  SourceLocation(),
+                                                  SourceLocation(),
+                                                  msgSendIdent, msgSendType,
+                                                  nullptr, SC_Extern);
+}
+
+// SynthMsgSendStretFunctionDecl - id objc_msgSend_stret(id self, SEL op, ...);
+void RewriteObjC::SynthMsgSendStretFunctionDecl() {
+  IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_stret");
+  SmallVector<QualType, 16> ArgTys;
+  QualType argT = Context->getObjCIdType();
+  assert(!argT.isNull() && "Can't find 'id' type");
+  ArgTys.push_back(argT);
+  argT = Context->getObjCSelType();
+  assert(!argT.isNull() && "Can't find 'SEL' type");
+  ArgTys.push_back(argT);
+  QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
+                                               ArgTys, /*isVariadic=*/true);
+  MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                                  SourceLocation(),
+                                                  SourceLocation(),
+                                                  msgSendIdent, msgSendType,
+                                                  nullptr, SC_Extern);
+}
+
+// SynthMsgSendSuperStretFunctionDecl -
+// id objc_msgSendSuper_stret(struct objc_super *, SEL op, ...);
+void RewriteObjC::SynthMsgSendSuperStretFunctionDecl() {
+  IdentifierInfo *msgSendIdent =
+    &Context->Idents.get("objc_msgSendSuper_stret");
+  SmallVector<QualType, 16> ArgTys;
+  RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
+                                      SourceLocation(), SourceLocation(),
+                                      &Context->Idents.get("objc_super"));
+  QualType argT = Context->getPointerType(Context->getTagDeclType(RD));
+  assert(!argT.isNull() && "Can't build 'struct objc_super *' type");
+  ArgTys.push_back(argT);
+  argT = Context->getObjCSelType();
+  assert(!argT.isNull() && "Can't find 'SEL' type");
+  ArgTys.push_back(argT);
+  QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
+                                               ArgTys, /*isVariadic=*/true);
+  MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                                       SourceLocation(),
+                                                       SourceLocation(),
+                                                       msgSendIdent,
+                                                       msgSendType, nullptr,
+                                                       SC_Extern);
+}
+
+// SynthMsgSendFpretFunctionDecl - double objc_msgSend_fpret(id self, SEL op, ...);
+void RewriteObjC::SynthMsgSendFpretFunctionDecl() {
+  IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_fpret");
+  SmallVector<QualType, 16> ArgTys;
+  QualType argT = Context->getObjCIdType();
+  assert(!argT.isNull() && "Can't find 'id' type");
+  ArgTys.push_back(argT);
+  argT = Context->getObjCSelType();
+  assert(!argT.isNull() && "Can't find 'SEL' type");
+  ArgTys.push_back(argT);
+  QualType msgSendType = getSimpleFunctionType(Context->DoubleTy,
+                                               ArgTys, /*isVariadic=*/true);
+  MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                                  SourceLocation(),
+                                                  SourceLocation(),
+                                                  msgSendIdent, msgSendType,
+                                                  nullptr, SC_Extern);
+}
+
+// SynthGetClassFunctionDecl - id objc_getClass(const char *name);
+void RewriteObjC::SynthGetClassFunctionDecl() {
+  IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getClass");
+  SmallVector<QualType, 16> ArgTys;
+  ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
+  QualType getClassType = getSimpleFunctionType(Context->getObjCIdType(),
+                                                ArgTys);
+  GetClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                              SourceLocation(),
+                                              SourceLocation(),
+                                              getClassIdent, getClassType,
+                                              nullptr, SC_Extern);
+}
+
+// SynthGetSuperClassFunctionDecl - Class class_getSuperclass(Class cls);
+void RewriteObjC::SynthGetSuperClassFunctionDecl() {
+  IdentifierInfo *getSuperClassIdent = 
+    &Context->Idents.get("class_getSuperclass");
+  SmallVector<QualType, 16> ArgTys;
+  ArgTys.push_back(Context->getObjCClassType());
+  QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(),
+                                                ArgTys);
+  GetSuperClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                                   SourceLocation(),
+                                                   SourceLocation(),
+                                                   getSuperClassIdent,
+                                                   getClassType, nullptr,
+                                                   SC_Extern);
+}
+
+// SynthGetMetaClassFunctionDecl - id objc_getMetaClass(const char *name);
+void RewriteObjC::SynthGetMetaClassFunctionDecl() {
+  IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getMetaClass");
+  SmallVector<QualType, 16> ArgTys;
+  ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
+  QualType getClassType = getSimpleFunctionType(Context->getObjCIdType(),
+                                                ArgTys);
+  GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                                  SourceLocation(),
+                                                  SourceLocation(),
+                                                  getClassIdent, getClassType,
+                                                  nullptr, SC_Extern);
+}
+
+Stmt *RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) {
+  assert(Exp != nullptr && "Expected non-null ObjCStringLiteral");
+  QualType strType = getConstantStringStructType();
+
+  std::string S = "__NSConstantStringImpl_";
+
+  std::string tmpName = InFileName;
+  unsigned i;
+  for (i=0; i < tmpName.length(); i++) {
+    char c = tmpName.at(i);
+    // replace any non-alphanumeric characters with '_'.
+    if (!isAlphanumeric(c))
+      tmpName[i] = '_';
+  }
+  S += tmpName;
+  S += "_";
+  S += utostr(NumObjCStringLiterals++);
+
+  Preamble += "static __NSConstantStringImpl " + S;
+  Preamble += " __attribute__ ((section (\"__DATA, __cfstring\"))) = {__CFConstantStringClassReference,";
+  Preamble += "0x000007c8,"; // utf8_str
+  // The pretty printer for StringLiteral handles escape characters properly.
+  std::string prettyBufS;
+  llvm::raw_string_ostream prettyBuf(prettyBufS);
+  Exp->getString()->printPretty(prettyBuf, nullptr, PrintingPolicy(LangOpts));
+  Preamble += prettyBuf.str();
+  Preamble += ",";
+  Preamble += utostr(Exp->getString()->getByteLength()) + "};\n";
+
+  VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
+                                   SourceLocation(), &Context->Idents.get(S),
+                                   strType, nullptr, SC_Static);
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, false, strType, VK_LValue,
+                                               SourceLocation());
+  Expr *Unop = new (Context) UnaryOperator(DRE, UO_AddrOf,
+                                 Context->getPointerType(DRE->getType()),
+                                           VK_RValue, OK_Ordinary,
+                                           SourceLocation());
+  // cast to NSConstantString *
+  CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Exp->getType(),
+                                            CK_CPointerToObjCPointerCast, Unop);
+  ReplaceStmt(Exp, cast);
+  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
+  return cast;
+}
+
+// struct objc_super { struct objc_object *receiver; struct objc_class *super; };
+QualType RewriteObjC::getSuperStructType() {
+  if (!SuperStructDecl) {
+    SuperStructDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
+                                         SourceLocation(), SourceLocation(),
+                                         &Context->Idents.get("objc_super"));
+    QualType FieldTypes[2];
+
+    // struct objc_object *receiver;
+    FieldTypes[0] = Context->getObjCIdType();
+    // struct objc_class *super;
+    FieldTypes[1] = Context->getObjCClassType();
+
+    // Create fields
+    for (unsigned i = 0; i < 2; ++i) {
+      SuperStructDecl->addDecl(FieldDecl::Create(*Context, SuperStructDecl,
+                                                 SourceLocation(),
+                                                 SourceLocation(), nullptr,
+                                                 FieldTypes[i], nullptr,
+                                                 /*BitWidth=*/nullptr,
+                                                 /*Mutable=*/false,
+                                                 ICIS_NoInit));
+    }
+
+    SuperStructDecl->completeDefinition();
+  }
+  return Context->getTagDeclType(SuperStructDecl);
+}
+
+QualType RewriteObjC::getConstantStringStructType() {
+  if (!ConstantStringDecl) {
+    ConstantStringDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
+                                            SourceLocation(), SourceLocation(),
+                         &Context->Idents.get("__NSConstantStringImpl"));
+    QualType FieldTypes[4];
+
+    // struct objc_object *receiver;
+    FieldTypes[0] = Context->getObjCIdType();
+    // int flags;
+    FieldTypes[1] = Context->IntTy;
+    // char *str;
+    FieldTypes[2] = Context->getPointerType(Context->CharTy);
+    // long length;
+    FieldTypes[3] = Context->LongTy;
+
+    // Create fields
+    for (unsigned i = 0; i < 4; ++i) {
+      ConstantStringDecl->addDecl(FieldDecl::Create(*Context,
+                                                    ConstantStringDecl,
+                                                    SourceLocation(),
+                                                    SourceLocation(), nullptr,
+                                                    FieldTypes[i], nullptr,
+                                                    /*BitWidth=*/nullptr,
+                                                    /*Mutable=*/true,
+                                                    ICIS_NoInit));
+    }
+
+    ConstantStringDecl->completeDefinition();
+  }
+  return Context->getTagDeclType(ConstantStringDecl);
+}
+
+CallExpr *RewriteObjC::SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFlavor,
+                                                QualType msgSendType, 
+                                                QualType returnType, 
+                                                SmallVectorImpl<QualType> &ArgTypes,
+                                                SmallVectorImpl<Expr*> &MsgExprs,
+                                                ObjCMethodDecl *Method) {
+  // Create a reference to the objc_msgSend_stret() declaration.
+  DeclRefExpr *STDRE = new (Context) DeclRefExpr(MsgSendStretFlavor,
+                                                 false, msgSendType,
+                                                 VK_LValue, SourceLocation());
+  // Need to cast objc_msgSend_stret to "void *" (see above comment).
+  CastExpr *cast = NoTypeInfoCStyleCastExpr(Context,
+                                  Context->getPointerType(Context->VoidTy),
+                                  CK_BitCast, STDRE);
+  // Now do the "normal" pointer to function cast.
+  QualType castType = getSimpleFunctionType(returnType, ArgTypes,
+                                            Method ? Method->isVariadic()
+                                                   : false);
+  castType = Context->getPointerType(castType);
+  cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
+                                            cast);
+  
+  // Don't forget the parens to enforce the proper binding.
+  ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), cast);
+  
+  const FunctionType *FT = msgSendType->getAs<FunctionType>();
+  CallExpr *STCE = new (Context) CallExpr(
+      *Context, PE, MsgExprs, FT->getReturnType(), VK_RValue, SourceLocation());
+  return STCE;
+  
+}
+
+
+Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
+                                    SourceLocation StartLoc,
+                                    SourceLocation EndLoc) {
+  if (!SelGetUidFunctionDecl)
+    SynthSelGetUidFunctionDecl();
+  if (!MsgSendFunctionDecl)
+    SynthMsgSendFunctionDecl();
+  if (!MsgSendSuperFunctionDecl)
+    SynthMsgSendSuperFunctionDecl();
+  if (!MsgSendStretFunctionDecl)
+    SynthMsgSendStretFunctionDecl();
+  if (!MsgSendSuperStretFunctionDecl)
+    SynthMsgSendSuperStretFunctionDecl();
+  if (!MsgSendFpretFunctionDecl)
+    SynthMsgSendFpretFunctionDecl();
+  if (!GetClassFunctionDecl)
+    SynthGetClassFunctionDecl();
+  if (!GetSuperClassFunctionDecl)
+    SynthGetSuperClassFunctionDecl();
+  if (!GetMetaClassFunctionDecl)
+    SynthGetMetaClassFunctionDecl();
+
+  // default to objc_msgSend().
+  FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl;
+  // May need to use objc_msgSend_stret() as well.
+  FunctionDecl *MsgSendStretFlavor = nullptr;
+  if (ObjCMethodDecl *mDecl = Exp->getMethodDecl()) {
+    QualType resultType = mDecl->getReturnType();
+    if (resultType->isRecordType())
+      MsgSendStretFlavor = MsgSendStretFunctionDecl;
+    else if (resultType->isRealFloatingType())
+      MsgSendFlavor = MsgSendFpretFunctionDecl;
+  }
+
+  // Synthesize a call to objc_msgSend().
+  SmallVector<Expr*, 8> MsgExprs;
+  switch (Exp->getReceiverKind()) {
+  case ObjCMessageExpr::SuperClass: {
+    MsgSendFlavor = MsgSendSuperFunctionDecl;
+    if (MsgSendStretFlavor)
+      MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
+    assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
+
+    ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface();
+
+    SmallVector<Expr*, 4> InitExprs;
+
+    // set the receiver to self, the first argument to all methods.
+    InitExprs.push_back(
+      NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+                               CK_BitCast,
+                   new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
+                                             false,
+                                             Context->getObjCIdType(),
+                                             VK_RValue,
+                                             SourceLocation()))
+                        ); // set the 'receiver'.
+
+    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
+    SmallVector<Expr*, 8> ClsExprs;
+    ClsExprs.push_back(getStringLiteral(ClassDecl->getIdentifier()->getName()));
+    CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
+                                                 &ClsExprs[0],
+                                                 ClsExprs.size(),
+                                                 StartLoc,
+                                                 EndLoc);
+    // (Class)objc_getClass("CurrentClass")
+    CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
+                                             Context->getObjCClassType(),
+                                             CK_BitCast, Cls);
+    ClsExprs.clear();
+    ClsExprs.push_back(ArgExpr);
+    Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
+                                       &ClsExprs[0], ClsExprs.size(),
+                                       StartLoc, EndLoc);
+    
+    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
+    // To turn off a warning, type-cast to 'id'
+    InitExprs.push_back( // set 'super class', using class_getSuperclass().
+                        NoTypeInfoCStyleCastExpr(Context,
+                                                 Context->getObjCIdType(),
+                                                 CK_BitCast, Cls));
+    // struct objc_super
+    QualType superType = getSuperStructType();
+    Expr *SuperRep;
+
+    if (LangOpts.MicrosoftExt) {
+      SynthSuperConstructorFunctionDecl();
+      // Simulate a constructor call...
+      DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperConstructorFunctionDecl,
+                                                   false, superType, VK_LValue,
+                                                   SourceLocation());
+      SuperRep = new (Context) CallExpr(*Context, DRE, InitExprs,
+                                        superType, VK_LValue,
+                                        SourceLocation());
+      // The code for super is a little tricky to prevent collision with
+      // the structure definition in the header. The rewriter has it's own
+      // internal definition (__rw_objc_super) that is uses. This is why
+      // we need the cast below. For example:
+      // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
+      //
+      SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf,
+                               Context->getPointerType(SuperRep->getType()),
+                                             VK_RValue, OK_Ordinary,
+                                             SourceLocation());
+      SuperRep = NoTypeInfoCStyleCastExpr(Context,
+                                          Context->getPointerType(superType),
+                                          CK_BitCast, SuperRep);
+    } else {
+      // (struct objc_super) { <exprs from above> }
+      InitListExpr *ILE =
+        new (Context) InitListExpr(*Context, SourceLocation(), InitExprs,
+                                   SourceLocation());
+      TypeSourceInfo *superTInfo
+        = Context->getTrivialTypeSourceInfo(superType);
+      SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
+                                                   superType, VK_LValue,
+                                                   ILE, false);
+      // struct objc_super *
+      SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf,
+                               Context->getPointerType(SuperRep->getType()),
+                                             VK_RValue, OK_Ordinary,
+                                             SourceLocation());
+    }
+    MsgExprs.push_back(SuperRep);
+    break;
+  }
+
+  case ObjCMessageExpr::Class: {
+    SmallVector<Expr*, 8> ClsExprs;
+    ObjCInterfaceDecl *Class
+      = Exp->getClassReceiver()->getAs<ObjCObjectType>()->getInterface();
+    IdentifierInfo *clsName = Class->getIdentifier();
+    ClsExprs.push_back(getStringLiteral(clsName->getName()));
+    CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
+                                                 &ClsExprs[0],
+                                                 ClsExprs.size(), 
+                                                 StartLoc, EndLoc);
+    MsgExprs.push_back(Cls);
+    break;
+  }
+
+  case ObjCMessageExpr::SuperInstance:{
+    MsgSendFlavor = MsgSendSuperFunctionDecl;
+    if (MsgSendStretFlavor)
+      MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
+    assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
+    ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface();
+    SmallVector<Expr*, 4> InitExprs;
+
+    InitExprs.push_back(
+      NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+                               CK_BitCast,
+                   new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
+                                             false,
+                                             Context->getObjCIdType(),
+                                             VK_RValue, SourceLocation()))
+                        ); // set the 'receiver'.
+    
+    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
+    SmallVector<Expr*, 8> ClsExprs;
+    ClsExprs.push_back(getStringLiteral(ClassDecl->getIdentifier()->getName()));
+    CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
+                                                 &ClsExprs[0],
+                                                 ClsExprs.size(), 
+                                                 StartLoc, EndLoc);
+    // (Class)objc_getClass("CurrentClass")
+    CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
+                                                 Context->getObjCClassType(),
+                                                 CK_BitCast, Cls);
+    ClsExprs.clear();
+    ClsExprs.push_back(ArgExpr);
+    Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
+                                       &ClsExprs[0], ClsExprs.size(),
+                                       StartLoc, EndLoc);
+    
+    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
+    // To turn off a warning, type-cast to 'id'
+    InitExprs.push_back(
+      // set 'super class', using class_getSuperclass().
+      NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+                               CK_BitCast, Cls));
+    // struct objc_super
+    QualType superType = getSuperStructType();
+    Expr *SuperRep;
+
+    if (LangOpts.MicrosoftExt) {
+      SynthSuperConstructorFunctionDecl();
+      // Simulate a constructor call...
+      DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperConstructorFunctionDecl,
+                                                   false, superType, VK_LValue,
+                                                   SourceLocation());
+      SuperRep = new (Context) CallExpr(*Context, DRE, InitExprs,
+                                        superType, VK_LValue, SourceLocation());
+      // The code for super is a little tricky to prevent collision with
+      // the structure definition in the header. The rewriter has it's own
+      // internal definition (__rw_objc_super) that is uses. This is why
+      // we need the cast below. For example:
+      // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
+      //
+      SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf,
+                               Context->getPointerType(SuperRep->getType()),
+                               VK_RValue, OK_Ordinary,
+                               SourceLocation());
+      SuperRep = NoTypeInfoCStyleCastExpr(Context,
+                               Context->getPointerType(superType),
+                               CK_BitCast, SuperRep);
+    } else {
+      // (struct objc_super) { <exprs from above> }
+      InitListExpr *ILE =
+        new (Context) InitListExpr(*Context, SourceLocation(), InitExprs,
+                                   SourceLocation());
+      TypeSourceInfo *superTInfo
+        = Context->getTrivialTypeSourceInfo(superType);
+      SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
+                                                   superType, VK_RValue, ILE,
+                                                   false);
+    }
+    MsgExprs.push_back(SuperRep);
+    break;
+  }
+
+  case ObjCMessageExpr::Instance: {
+    // Remove all type-casts because it may contain objc-style types; e.g.
+    // Foo<Proto> *.
+    Expr *recExpr = Exp->getInstanceReceiver();
+    while (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(recExpr))
+      recExpr = CE->getSubExpr();
+    CastKind CK = recExpr->getType()->isObjCObjectPointerType()
+                    ? CK_BitCast : recExpr->getType()->isBlockPointerType()
+                                     ? CK_BlockPointerToObjCPointerCast
+                                     : CK_CPointerToObjCPointerCast;
+
+    recExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+                                       CK, recExpr);
+    MsgExprs.push_back(recExpr);
+    break;
+  }
+  }
+
+  // Create a call to sel_registerName("selName"), it will be the 2nd argument.
+  SmallVector<Expr*, 8> SelExprs;
+  SelExprs.push_back(getStringLiteral(Exp->getSelector().getAsString()));
+  CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
+                                                 &SelExprs[0], SelExprs.size(),
+                                                  StartLoc,
+                                                  EndLoc);
+  MsgExprs.push_back(SelExp);
+
+  // Now push any user supplied arguments.
+  for (unsigned i = 0; i < Exp->getNumArgs(); i++) {
+    Expr *userExpr = Exp->getArg(i);
+    // Make all implicit casts explicit...ICE comes in handy:-)
+    if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(userExpr)) {
+      // Reuse the ICE type, it is exactly what the doctor ordered.
+      QualType type = ICE->getType();
+      if (needToScanForQualifiers(type))
+        type = Context->getObjCIdType();
+      // Make sure we convert "type (^)(...)" to "type (*)(...)".
+      (void)convertBlockPointerToFunctionPointer(type);
+      const Expr *SubExpr = ICE->IgnoreParenImpCasts();
+      CastKind CK;
+      if (SubExpr->getType()->isIntegralType(*Context) && 
+          type->isBooleanType()) {
+        CK = CK_IntegralToBoolean;
+      } else if (type->isObjCObjectPointerType()) {
+        if (SubExpr->getType()->isBlockPointerType()) {
+          CK = CK_BlockPointerToObjCPointerCast;
+        } else if (SubExpr->getType()->isPointerType()) {
+          CK = CK_CPointerToObjCPointerCast;
+        } else {
+          CK = CK_BitCast;
+        }
+      } else {
+        CK = CK_BitCast;
+      }
+
+      userExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, userExpr);
+    }
+    // Make id<P...> cast into an 'id' cast.
+    else if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(userExpr)) {
+      if (CE->getType()->isObjCQualifiedIdType()) {
+        while ((CE = dyn_cast<CStyleCastExpr>(userExpr)))
+          userExpr = CE->getSubExpr();
+        CastKind CK;
+        if (userExpr->getType()->isIntegralType(*Context)) {
+          CK = CK_IntegralToPointer;
+        } else if (userExpr->getType()->isBlockPointerType()) {
+          CK = CK_BlockPointerToObjCPointerCast;
+        } else if (userExpr->getType()->isPointerType()) {
+          CK = CK_CPointerToObjCPointerCast;
+        } else {
+          CK = CK_BitCast;
+        }
+        userExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+                                            CK, userExpr);
+      }
+    }
+    MsgExprs.push_back(userExpr);
+    // We've transferred the ownership to MsgExprs. For now, we *don't* null
+    // out the argument in the original expression (since we aren't deleting
+    // the ObjCMessageExpr). See RewritePropertyOrImplicitSetter() usage for more info.
+    //Exp->setArg(i, 0);
+  }
+  // Generate the funky cast.
+  CastExpr *cast;
+  SmallVector<QualType, 8> ArgTypes;
+  QualType returnType;
+
+  // Push 'id' and 'SEL', the 2 implicit arguments.
+  if (MsgSendFlavor == MsgSendSuperFunctionDecl)
+    ArgTypes.push_back(Context->getPointerType(getSuperStructType()));
+  else
+    ArgTypes.push_back(Context->getObjCIdType());
+  ArgTypes.push_back(Context->getObjCSelType());
+  if (ObjCMethodDecl *OMD = Exp->getMethodDecl()) {
+    // Push any user argument types.
+    for (const auto *PI : OMD->params()) {
+      QualType t = PI->getType()->isObjCQualifiedIdType()
+                     ? Context->getObjCIdType()
+                     : PI->getType();
+      // Make sure we convert "t (^)(...)" to "t (*)(...)".
+      (void)convertBlockPointerToFunctionPointer(t);
+      ArgTypes.push_back(t);
+    }
+    returnType = Exp->getType();
+    convertToUnqualifiedObjCType(returnType);
+    (void)convertBlockPointerToFunctionPointer(returnType);
+  } else {
+    returnType = Context->getObjCIdType();
+  }
+  // Get the type, we will need to reference it in a couple spots.
+  QualType msgSendType = MsgSendFlavor->getType();
+
+  // Create a reference to the objc_msgSend() declaration.
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType,
+                                               VK_LValue, SourceLocation());
+
+  // Need to cast objc_msgSend to "void *" (to workaround a GCC bandaid).
+  // If we don't do this cast, we get the following bizarre warning/note:
+  // xx.m:13: warning: function called through a non-compatible type
+  // xx.m:13: note: if this code is reached, the program will abort
+  cast = NoTypeInfoCStyleCastExpr(Context,
+                                  Context->getPointerType(Context->VoidTy),
+                                  CK_BitCast, DRE);
+
+  // Now do the "normal" pointer to function cast.
+  // If we don't have a method decl, force a variadic cast.
+  const ObjCMethodDecl *MD = Exp->getMethodDecl();
+  QualType castType =
+    getSimpleFunctionType(returnType, ArgTypes, MD ? MD->isVariadic() : true);
+  castType = Context->getPointerType(castType);
+  cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
+                                  cast);
+
+  // Don't forget the parens to enforce the proper binding.
+  ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
+
+  const FunctionType *FT = msgSendType->getAs<FunctionType>();
+  CallExpr *CE = new (Context)
+      CallExpr(*Context, PE, MsgExprs, FT->getReturnType(), VK_RValue, EndLoc);
+  Stmt *ReplacingStmt = CE;
+  if (MsgSendStretFlavor) {
+    // We have the method which returns a struct/union. Must also generate
+    // call to objc_msgSend_stret and hang both varieties on a conditional
+    // expression which dictate which one to envoke depending on size of
+    // method's return type.
+    
+    CallExpr *STCE = SynthMsgSendStretCallExpr(MsgSendStretFlavor, 
+                                               msgSendType, returnType, 
+                                               ArgTypes, MsgExprs,
+                                               Exp->getMethodDecl());
+
+    // Build sizeof(returnType)
+    UnaryExprOrTypeTraitExpr *sizeofExpr =
+       new (Context) UnaryExprOrTypeTraitExpr(UETT_SizeOf,
+                                 Context->getTrivialTypeSourceInfo(returnType),
+                                 Context->getSizeType(), SourceLocation(),
+                                 SourceLocation());
+    // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...))
+    // FIXME: Value of 8 is base on ppc32/x86 ABI for the most common cases.
+    // For X86 it is more complicated and some kind of target specific routine
+    // is needed to decide what to do.
+    unsigned IntSize =
+      static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
+    IntegerLiteral *limit = IntegerLiteral::Create(*Context,
+                                                   llvm::APInt(IntSize, 8),
+                                                   Context->IntTy,
+                                                   SourceLocation());
+    BinaryOperator *lessThanExpr = 
+      new (Context) BinaryOperator(sizeofExpr, limit, BO_LE, Context->IntTy,
+                                   VK_RValue, OK_Ordinary, SourceLocation(),
+                                   false);
+    // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...))
+    ConditionalOperator *CondExpr =
+      new (Context) ConditionalOperator(lessThanExpr,
+                                        SourceLocation(), CE,
+                                        SourceLocation(), STCE,
+                                        returnType, VK_RValue, OK_Ordinary);
+    ReplacingStmt = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 
+                                            CondExpr);
+  }
+  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
+  return ReplacingStmt;
+}
+
+Stmt *RewriteObjC::RewriteMessageExpr(ObjCMessageExpr *Exp) {
+  Stmt *ReplacingStmt = SynthMessageExpr(Exp, Exp->getLocStart(),
+                                         Exp->getLocEnd());
+
+  // Now do the actual rewrite.
+  ReplaceStmt(Exp, ReplacingStmt);
+
+  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
+  return ReplacingStmt;
+}
+
+// typedef struct objc_object Protocol;
+QualType RewriteObjC::getProtocolType() {
+  if (!ProtocolTypeDecl) {
+    TypeSourceInfo *TInfo
+      = Context->getTrivialTypeSourceInfo(Context->getObjCIdType());
+    ProtocolTypeDecl = TypedefDecl::Create(*Context, TUDecl,
+                                           SourceLocation(), SourceLocation(),
+                                           &Context->Idents.get("Protocol"),
+                                           TInfo);
+  }
+  return Context->getTypeDeclType(ProtocolTypeDecl);
+}
+
+/// RewriteObjCProtocolExpr - Rewrite a protocol expression into
+/// a synthesized/forward data reference (to the protocol's metadata).
+/// The forward references (and metadata) are generated in
+/// RewriteObjC::HandleTranslationUnit().
+Stmt *RewriteObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) {
+  std::string Name = "_OBJC_PROTOCOL_" + Exp->getProtocol()->getNameAsString();
+  IdentifierInfo *ID = &Context->Idents.get(Name);
+  VarDecl *VD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
+                                SourceLocation(), ID, getProtocolType(),
+                                nullptr, SC_Extern);
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, false, getProtocolType(),
+                                               VK_LValue, SourceLocation());
+  Expr *DerefExpr = new (Context) UnaryOperator(DRE, UO_AddrOf,
+                             Context->getPointerType(DRE->getType()),
+                             VK_RValue, OK_Ordinary, SourceLocation());
+  CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, DerefExpr->getType(),
+                                                CK_BitCast,
+                                                DerefExpr);
+  ReplaceStmt(Exp, castExpr);
+  ProtocolExprDecls.insert(Exp->getProtocol()->getCanonicalDecl());
+  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
+  return castExpr;
+
+}
+
+bool RewriteObjC::BufferContainsPPDirectives(const char *startBuf,
+                                             const char *endBuf) {
+  while (startBuf < endBuf) {
+    if (*startBuf == '#') {
+      // Skip whitespace.
+      for (++startBuf; startBuf[0] == ' ' || startBuf[0] == '\t'; ++startBuf)
+        ;
+      if (!strncmp(startBuf, "if", strlen("if")) ||
+          !strncmp(startBuf, "ifdef", strlen("ifdef")) ||
+          !strncmp(startBuf, "ifndef", strlen("ifndef")) ||
+          !strncmp(startBuf, "define", strlen("define")) ||
+          !strncmp(startBuf, "undef", strlen("undef")) ||
+          !strncmp(startBuf, "else", strlen("else")) ||
+          !strncmp(startBuf, "elif", strlen("elif")) ||
+          !strncmp(startBuf, "endif", strlen("endif")) ||
+          !strncmp(startBuf, "pragma", strlen("pragma")) ||
+          !strncmp(startBuf, "include", strlen("include")) ||
+          !strncmp(startBuf, "import", strlen("import")) ||
+          !strncmp(startBuf, "include_next", strlen("include_next")))
+        return true;
+    }
+    startBuf++;
+  }
+  return false;
+}
+
+/// RewriteObjCInternalStruct - Rewrite one internal struct corresponding to
+/// an objective-c class with ivars.
+void RewriteObjC::RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl,
+                                               std::string &Result) {
+  assert(CDecl && "Class missing in SynthesizeObjCInternalStruct");
+  assert(CDecl->getName() != "" &&
+         "Name missing in SynthesizeObjCInternalStruct");
+  // Do not synthesize more than once.
+  if (ObjCSynthesizedStructs.count(CDecl))
+    return;
+  ObjCInterfaceDecl *RCDecl = CDecl->getSuperClass();
+  int NumIvars = CDecl->ivar_size();
+  SourceLocation LocStart = CDecl->getLocStart();
+  SourceLocation LocEnd = CDecl->getEndOfDefinitionLoc();
+
+  const char *startBuf = SM->getCharacterData(LocStart);
+  const char *endBuf = SM->getCharacterData(LocEnd);
+
+  // If no ivars and no root or if its root, directly or indirectly,
+  // have no ivars (thus not synthesized) then no need to synthesize this class.
+  if ((!CDecl->isThisDeclarationADefinition() || NumIvars == 0) &&
+      (!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) {
+    endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts);
+    ReplaceText(LocStart, endBuf-startBuf, Result);
+    return;
+  }
+
+  // FIXME: This has potential of causing problem. If
+  // SynthesizeObjCInternalStruct is ever called recursively.
+  Result += "\nstruct ";
+  Result += CDecl->getNameAsString();
+  if (LangOpts.MicrosoftExt)
+    Result += "_IMPL";
+
+  if (NumIvars > 0) {
+    const char *cursor = strchr(startBuf, '{');
+    assert((cursor && endBuf)
+           && "SynthesizeObjCInternalStruct - malformed @interface");
+    // If the buffer contains preprocessor directives, we do more fine-grained
+    // rewrites. This is intended to fix code that looks like (which occurs in
+    // NSURL.h, for example):
+    //
+    // #ifdef XYZ
+    // @interface Foo : NSObject
+    // #else
+    // @interface FooBar : NSObject
+    // #endif
+    // {
+    //    int i;
+    // }
+    // @end
+    //
+    // This clause is segregated to avoid breaking the common case.
+    if (BufferContainsPPDirectives(startBuf, cursor)) {
+      SourceLocation L = RCDecl ? CDecl->getSuperClassLoc() :
+                                  CDecl->getAtStartLoc();
+      const char *endHeader = SM->getCharacterData(L);
+      endHeader += Lexer::MeasureTokenLength(L, *SM, LangOpts);
+
+      if (CDecl->protocol_begin() != CDecl->protocol_end()) {
+        // advance to the end of the referenced protocols.
+        while (endHeader < cursor && *endHeader != '>') endHeader++;
+        endHeader++;
+      }
+      // rewrite the original header
+      ReplaceText(LocStart, endHeader-startBuf, Result);
+    } else {
+      // rewrite the original header *without* disturbing the '{'
+      ReplaceText(LocStart, cursor-startBuf, Result);
+    }
+    if (RCDecl && ObjCSynthesizedStructs.count(RCDecl)) {
+      Result = "\n    struct ";
+      Result += RCDecl->getNameAsString();
+      Result += "_IMPL ";
+      Result += RCDecl->getNameAsString();
+      Result += "_IVARS;\n";
+
+      // insert the super class structure definition.
+      SourceLocation OnePastCurly =
+        LocStart.getLocWithOffset(cursor-startBuf+1);
+      InsertText(OnePastCurly, Result);
+    }
+    cursor++; // past '{'
+
+    // Now comment out any visibility specifiers.
+    while (cursor < endBuf) {
+      if (*cursor == '@') {
+        SourceLocation atLoc = LocStart.getLocWithOffset(cursor-startBuf);
+        // Skip whitespace.
+        for (++cursor; cursor[0] == ' ' || cursor[0] == '\t'; ++cursor)
+          /*scan*/;
+
+        // FIXME: presence of @public, etc. inside comment results in
+        // this transformation as well, which is still correct c-code.
+        if (!strncmp(cursor, "public", strlen("public")) ||
+            !strncmp(cursor, "private", strlen("private")) ||
+            !strncmp(cursor, "package", strlen("package")) ||
+            !strncmp(cursor, "protected", strlen("protected")))
+          InsertText(atLoc, "// ");
+      }
+      // FIXME: If there are cases where '<' is used in ivar declaration part
+      // of user code, then scan the ivar list and use needToScanForQualifiers
+      // for type checking.
+      else if (*cursor == '<') {
+        SourceLocation atLoc = LocStart.getLocWithOffset(cursor-startBuf);
+        InsertText(atLoc, "/* ");
+        cursor = strchr(cursor, '>');
+        cursor++;
+        atLoc = LocStart.getLocWithOffset(cursor-startBuf);
+        InsertText(atLoc, " */");
+      } else if (*cursor == '^') { // rewrite block specifier.
+        SourceLocation caretLoc = LocStart.getLocWithOffset(cursor-startBuf);
+        ReplaceText(caretLoc, 1, "*");
+      }
+      cursor++;
+    }
+    // Don't forget to add a ';'!!
+    InsertText(LocEnd.getLocWithOffset(1), ";");
+  } else { // we don't have any instance variables - insert super struct.
+    endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts);
+    Result += " {\n    struct ";
+    Result += RCDecl->getNameAsString();
+    Result += "_IMPL ";
+    Result += RCDecl->getNameAsString();
+    Result += "_IVARS;\n};\n";
+    ReplaceText(LocStart, endBuf-startBuf, Result);
+  }
+  // Mark this struct as having been generated.
+  if (!ObjCSynthesizedStructs.insert(CDecl))
+    llvm_unreachable("struct already synthesize- SynthesizeObjCInternalStruct");
+}
+
+//===----------------------------------------------------------------------===//
+// Meta Data Emission
+//===----------------------------------------------------------------------===//
+
+
+/// RewriteImplementations - This routine rewrites all method implementations
+/// and emits meta-data.
+
+void RewriteObjC::RewriteImplementations() {
+  int ClsDefCount = ClassImplementation.size();
+  int CatDefCount = CategoryImplementation.size();
+
+  // Rewrite implemented methods
+  for (int i = 0; i < ClsDefCount; i++)
+    RewriteImplementationDecl(ClassImplementation[i]);
+
+  for (int i = 0; i < CatDefCount; i++)
+    RewriteImplementationDecl(CategoryImplementation[i]);
+}
+
+void RewriteObjC::RewriteByRefString(std::string &ResultStr, 
+                                     const std::string &Name,
+                                     ValueDecl *VD, bool def) {
+  assert(BlockByRefDeclNo.count(VD) && 
+         "RewriteByRefString: ByRef decl missing");
+  if (def)
+    ResultStr += "struct ";
+  ResultStr += "__Block_byref_" + Name + 
+    "_" + utostr(BlockByRefDeclNo[VD]) ;
+}
+
+static bool HasLocalVariableExternalStorage(ValueDecl *VD) {
+  if (VarDecl *Var = dyn_cast<VarDecl>(VD))
+    return (Var->isFunctionOrMethodVarDecl() && !Var->hasLocalStorage());
+  return false;
+}
+
+std::string RewriteObjC::SynthesizeBlockFunc(BlockExpr *CE, int i,
+                                                   StringRef funcName,
+                                                   std::string Tag) {
+  const FunctionType *AFT = CE->getFunctionType();
+  QualType RT = AFT->getReturnType();
+  std::string StructRef = "struct " + Tag;
+  std::string S = "static " + RT.getAsString(Context->getPrintingPolicy()) + " __" +
+                  funcName.str() + "_" + "block_func_" + utostr(i);
+
+  BlockDecl *BD = CE->getBlockDecl();
+
+  if (isa<FunctionNoProtoType>(AFT)) {
+    // No user-supplied arguments. Still need to pass in a pointer to the
+    // block (to reference imported block decl refs).
+    S += "(" + StructRef + " *__cself)";
+  } else if (BD->param_empty()) {
+    S += "(" + StructRef + " *__cself)";
+  } else {
+    const FunctionProtoType *FT = cast<FunctionProtoType>(AFT);
+    assert(FT && "SynthesizeBlockFunc: No function proto");
+    S += '(';
+    // first add the implicit argument.
+    S += StructRef + " *__cself, ";
+    std::string ParamStr;
+    for (BlockDecl::param_iterator AI = BD->param_begin(),
+         E = BD->param_end(); AI != E; ++AI) {
+      if (AI != BD->param_begin()) S += ", ";
+      ParamStr = (*AI)->getNameAsString();
+      QualType QT = (*AI)->getType();
+      (void)convertBlockPointerToFunctionPointer(QT);
+      QT.getAsStringInternal(ParamStr, Context->getPrintingPolicy());
+      S += ParamStr;
+    }
+    if (FT->isVariadic()) {
+      if (!BD->param_empty()) S += ", ";
+      S += "...";
+    }
+    S += ')';
+  }
+  S += " {\n";
+
+  // Create local declarations to avoid rewriting all closure decl ref exprs.
+  // First, emit a declaration for all "by ref" decls.
+  for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(),
+       E = BlockByRefDecls.end(); I != E; ++I) {
+    S += "  ";
+    std::string Name = (*I)->getNameAsString();
+    std::string TypeString;
+    RewriteByRefString(TypeString, Name, (*I));
+    TypeString += " *";
+    Name = TypeString + Name;
+    S += Name + " = __cself->" + (*I)->getNameAsString() + "; // bound by ref\n";
+  }
+  // Next, emit a declaration for all "by copy" declarations.
+  for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(),
+       E = BlockByCopyDecls.end(); I != E; ++I) {
+    S += "  ";
+    // Handle nested closure invocation. For example:
+    //
+    //   void (^myImportedClosure)(void);
+    //   myImportedClosure  = ^(void) { setGlobalInt(x + y); };
+    //
+    //   void (^anotherClosure)(void);
+    //   anotherClosure = ^(void) {
+    //     myImportedClosure(); // import and invoke the closure
+    //   };
+    //
+    if (isTopLevelBlockPointerType((*I)->getType())) {
+      RewriteBlockPointerTypeVariable(S, (*I));
+      S += " = (";
+      RewriteBlockPointerType(S, (*I)->getType());
+      S += ")";
+      S += "__cself->" + (*I)->getNameAsString() + "; // bound by copy\n";
+    }
+    else {
+      std::string Name = (*I)->getNameAsString();
+      QualType QT = (*I)->getType();
+      if (HasLocalVariableExternalStorage(*I))
+        QT = Context->getPointerType(QT);
+      QT.getAsStringInternal(Name, Context->getPrintingPolicy());
+      S += Name + " = __cself->" + 
+                              (*I)->getNameAsString() + "; // bound by copy\n";
+    }
+  }
+  std::string RewrittenStr = RewrittenBlockExprs[CE];
+  const char *cstr = RewrittenStr.c_str();
+  while (*cstr++ != '{') ;
+  S += cstr;
+  S += "\n";
+  return S;
+}
+
+std::string RewriteObjC::SynthesizeBlockHelperFuncs(BlockExpr *CE, int i,
+                                                   StringRef funcName,
+                                                   std::string Tag) {
+  std::string StructRef = "struct " + Tag;
+  std::string S = "static void __";
+
+  S += funcName;
+  S += "_block_copy_" + utostr(i);
+  S += "(" + StructRef;
+  S += "*dst, " + StructRef;
+  S += "*src) {";
+  for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = ImportedBlockDecls.begin(),
+      E = ImportedBlockDecls.end(); I != E; ++I) {
+    ValueDecl *VD = (*I);
+    S += "_Block_object_assign((void*)&dst->";
+    S += (*I)->getNameAsString();
+    S += ", (void*)src->";
+    S += (*I)->getNameAsString();
+    if (BlockByRefDeclsPtrSet.count((*I)))
+      S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);";
+    else if (VD->getType()->isBlockPointerType())
+      S += ", " + utostr(BLOCK_FIELD_IS_BLOCK) + "/*BLOCK_FIELD_IS_BLOCK*/);";
+    else
+      S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);";
+  }
+  S += "}\n";
+  
+  S += "\nstatic void __";
+  S += funcName;
+  S += "_block_dispose_" + utostr(i);
+  S += "(" + StructRef;
+  S += "*src) {";
+  for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = ImportedBlockDecls.begin(),
+      E = ImportedBlockDecls.end(); I != E; ++I) {
+    ValueDecl *VD = (*I);
+    S += "_Block_object_dispose((void*)src->";
+    S += (*I)->getNameAsString();
+    if (BlockByRefDeclsPtrSet.count((*I)))
+      S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);";
+    else if (VD->getType()->isBlockPointerType())
+      S += ", " + utostr(BLOCK_FIELD_IS_BLOCK) + "/*BLOCK_FIELD_IS_BLOCK*/);";
+    else
+      S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);";
+  }
+  S += "}\n";
+  return S;
+}
+
+std::string RewriteObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag, 
+                                             std::string Desc) {
+  std::string S = "\nstruct " + Tag;
+  std::string Constructor = "  " + Tag;
+
+  S += " {\n  struct __block_impl impl;\n";
+  S += "  struct " + Desc;
+  S += "* Desc;\n";
+
+  Constructor += "(void *fp, "; // Invoke function pointer.
+  Constructor += "struct " + Desc; // Descriptor pointer.
+  Constructor += " *desc";
+
+  if (BlockDeclRefs.size()) {
+    // Output all "by copy" declarations.
+    for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(),
+         E = BlockByCopyDecls.end(); I != E; ++I) {
+      S += "  ";
+      std::string FieldName = (*I)->getNameAsString();
+      std::string ArgName = "_" + FieldName;
+      // Handle nested closure invocation. For example:
+      //
+      //   void (^myImportedBlock)(void);
+      //   myImportedBlock  = ^(void) { setGlobalInt(x + y); };
+      //
+      //   void (^anotherBlock)(void);
+      //   anotherBlock = ^(void) {
+      //     myImportedBlock(); // import and invoke the closure
+      //   };
+      //
+      if (isTopLevelBlockPointerType((*I)->getType())) {
+        S += "struct __block_impl *";
+        Constructor += ", void *" + ArgName;
+      } else {
+        QualType QT = (*I)->getType();
+        if (HasLocalVariableExternalStorage(*I))
+          QT = Context->getPointerType(QT);
+        QT.getAsStringInternal(FieldName, Context->getPrintingPolicy());
+        QT.getAsStringInternal(ArgName, Context->getPrintingPolicy());
+        Constructor += ", " + ArgName;
+      }
+      S += FieldName + ";\n";
+    }
+    // Output all "by ref" declarations.
+    for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(),
+         E = BlockByRefDecls.end(); I != E; ++I) {
+      S += "  ";
+      std::string FieldName = (*I)->getNameAsString();
+      std::string ArgName = "_" + FieldName;
+      {
+        std::string TypeString;
+        RewriteByRefString(TypeString, FieldName, (*I));
+        TypeString += " *";
+        FieldName = TypeString + FieldName;
+        ArgName = TypeString + ArgName;
+        Constructor += ", " + ArgName;
+      }
+      S += FieldName + "; // by ref\n";
+    }
+    // Finish writing the constructor.
+    Constructor += ", int flags=0)";
+    // Initialize all "by copy" arguments.
+    bool firsTime = true;
+    for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(),
+         E = BlockByCopyDecls.end(); I != E; ++I) {
+      std::string Name = (*I)->getNameAsString();
+        if (firsTime) {
+          Constructor += " : ";
+          firsTime = false;
+        }
+        else
+          Constructor += ", ";
+        if (isTopLevelBlockPointerType((*I)->getType()))
+          Constructor += Name + "((struct __block_impl *)_" + Name + ")";
+        else
+          Constructor += Name + "(_" + Name + ")";
+    }
+    // Initialize all "by ref" arguments.
+    for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(),
+         E = BlockByRefDecls.end(); I != E; ++I) {
+      std::string Name = (*I)->getNameAsString();
+      if (firsTime) {
+        Constructor += " : ";
+        firsTime = false;
+      }
+      else
+        Constructor += ", ";
+      Constructor += Name + "(_" + Name + "->__forwarding)";
+    }
+    
+    Constructor += " {\n";
+    if (GlobalVarDecl)
+      Constructor += "    impl.isa = &_NSConcreteGlobalBlock;\n";
+    else
+      Constructor += "    impl.isa = &_NSConcreteStackBlock;\n";
+    Constructor += "    impl.Flags = flags;\n    impl.FuncPtr = fp;\n";
+
+    Constructor += "    Desc = desc;\n";
+  } else {
+    // Finish writing the constructor.
+    Constructor += ", int flags=0) {\n";
+    if (GlobalVarDecl)
+      Constructor += "    impl.isa = &_NSConcreteGlobalBlock;\n";
+    else
+      Constructor += "    impl.isa = &_NSConcreteStackBlock;\n";
+    Constructor += "    impl.Flags = flags;\n    impl.FuncPtr = fp;\n";
+    Constructor += "    Desc = desc;\n";
+  }
+  Constructor += "  ";
+  Constructor += "}\n";
+  S += Constructor;
+  S += "};\n";
+  return S;
+}
+
+std::string RewriteObjC::SynthesizeBlockDescriptor(std::string DescTag, 
+                                                   std::string ImplTag, int i,
+                                                   StringRef FunName,
+                                                   unsigned hasCopy) {
+  std::string S = "\nstatic struct " + DescTag;
+  
+  S += " {\n  unsigned long reserved;\n";
+  S += "  unsigned long Block_size;\n";
+  if (hasCopy) {
+    S += "  void (*copy)(struct ";
+    S += ImplTag; S += "*, struct ";
+    S += ImplTag; S += "*);\n";
+    
+    S += "  void (*dispose)(struct ";
+    S += ImplTag; S += "*);\n";
+  }
+  S += "} ";
+
+  S += DescTag + "_DATA = { 0, sizeof(struct ";
+  S += ImplTag + ")";
+  if (hasCopy) {
+    S += ", __" + FunName.str() + "_block_copy_" + utostr(i);
+    S += ", __" + FunName.str() + "_block_dispose_" + utostr(i);
+  }
+  S += "};\n";
+  return S;
+}
+
+void RewriteObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart,
+                                          StringRef FunName) {
+  // Insert declaration for the function in which block literal is used.
+  if (CurFunctionDeclToDeclareForBlock && !Blocks.empty())
+    RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock);
+  bool RewriteSC = (GlobalVarDecl &&
+                    !Blocks.empty() &&
+                    GlobalVarDecl->getStorageClass() == SC_Static &&
+                    GlobalVarDecl->getType().getCVRQualifiers());
+  if (RewriteSC) {
+    std::string SC(" void __");
+    SC += GlobalVarDecl->getNameAsString();
+    SC += "() {}";
+    InsertText(FunLocStart, SC);
+  }
+  
+  // Insert closures that were part of the function.
+  for (unsigned i = 0, count=0; i < Blocks.size(); i++) {
+    CollectBlockDeclRefInfo(Blocks[i]);
+    // Need to copy-in the inner copied-in variables not actually used in this
+    // block.
+    for (int j = 0; j < InnerDeclRefsCount[i]; j++) {
+      DeclRefExpr *Exp = InnerDeclRefs[count++];
+      ValueDecl *VD = Exp->getDecl();
+      BlockDeclRefs.push_back(Exp);
+      if (!VD->hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) {
+        BlockByCopyDeclsPtrSet.insert(VD);
+        BlockByCopyDecls.push_back(VD);
+      }
+      if (VD->hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) {
+        BlockByRefDeclsPtrSet.insert(VD);
+        BlockByRefDecls.push_back(VD);
+      }
+      // imported objects in the inner blocks not used in the outer
+      // blocks must be copied/disposed in the outer block as well.
+      if (VD->hasAttr<BlocksAttr>() ||
+          VD->getType()->isObjCObjectPointerType() || 
+          VD->getType()->isBlockPointerType())
+        ImportedBlockDecls.insert(VD);
+    }
+
+    std::string ImplTag = "__" + FunName.str() + "_block_impl_" + utostr(i);
+    std::string DescTag = "__" + FunName.str() + "_block_desc_" + utostr(i);
+
+    std::string CI = SynthesizeBlockImpl(Blocks[i], ImplTag, DescTag);
+
+    InsertText(FunLocStart, CI);
+
+    std::string CF = SynthesizeBlockFunc(Blocks[i], i, FunName, ImplTag);
+
+    InsertText(FunLocStart, CF);
+
+    if (ImportedBlockDecls.size()) {
+      std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, ImplTag);
+      InsertText(FunLocStart, HF);
+    }
+    std::string BD = SynthesizeBlockDescriptor(DescTag, ImplTag, i, FunName,
+                                               ImportedBlockDecls.size() > 0);
+    InsertText(FunLocStart, BD);
+
+    BlockDeclRefs.clear();
+    BlockByRefDecls.clear();
+    BlockByRefDeclsPtrSet.clear();
+    BlockByCopyDecls.clear();
+    BlockByCopyDeclsPtrSet.clear();
+    ImportedBlockDecls.clear();
+  }
+  if (RewriteSC) {
+    // Must insert any 'const/volatile/static here. Since it has been
+    // removed as result of rewriting of block literals.
+    std::string SC;
+    if (GlobalVarDecl->getStorageClass() == SC_Static)
+      SC = "static ";
+    if (GlobalVarDecl->getType().isConstQualified())
+      SC += "const ";
+    if (GlobalVarDecl->getType().isVolatileQualified())
+      SC += "volatile ";
+    if (GlobalVarDecl->getType().isRestrictQualified())
+      SC += "restrict ";
+    InsertText(FunLocStart, SC);
+  }
+  
+  Blocks.clear();
+  InnerDeclRefsCount.clear();
+  InnerDeclRefs.clear();
+  RewrittenBlockExprs.clear();
+}
+
+void RewriteObjC::InsertBlockLiteralsWithinFunction(FunctionDecl *FD) {
+  SourceLocation FunLocStart = FD->getTypeSpecStartLoc();
+  StringRef FuncName = FD->getName();
+
+  SynthesizeBlockLiterals(FunLocStart, FuncName);
+}
+
+static void BuildUniqueMethodName(std::string &Name,
+                                  ObjCMethodDecl *MD) {
+  ObjCInterfaceDecl *IFace = MD->getClassInterface();
+  Name = IFace->getName();
+  Name += "__" + MD->getSelector().getAsString();
+  // Convert colons to underscores.
+  std::string::size_type loc = 0;
+  while ((loc = Name.find(":", loc)) != std::string::npos)
+    Name.replace(loc, 1, "_");
+}
+
+void RewriteObjC::InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD) {
+  //fprintf(stderr,"In InsertBlockLiteralsWitinMethod\n");
+  //SourceLocation FunLocStart = MD->getLocStart();
+  SourceLocation FunLocStart = MD->getLocStart();
+  std::string FuncName;
+  BuildUniqueMethodName(FuncName, MD);
+  SynthesizeBlockLiterals(FunLocStart, FuncName);
+}
+
+void RewriteObjC::GetBlockDeclRefExprs(Stmt *S) {
+  for (Stmt::child_range CI = S->children(); CI; ++CI)
+    if (*CI) {
+      if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI))
+        GetBlockDeclRefExprs(CBE->getBody());
+      else
+        GetBlockDeclRefExprs(*CI);
+    }
+  // Handle specific things.
+  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
+    if (DRE->refersToEnclosingLocal()) {
+      // FIXME: Handle enums.
+      if (!isa<FunctionDecl>(DRE->getDecl()))
+        BlockDeclRefs.push_back(DRE);
+      if (HasLocalVariableExternalStorage(DRE->getDecl()))
+        BlockDeclRefs.push_back(DRE);
+    }
+  }
+  
+  return;
+}
+
+void RewriteObjC::GetInnerBlockDeclRefExprs(Stmt *S,
+                SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs,
+                llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts) {
+  for (Stmt::child_range CI = S->children(); CI; ++CI)
+    if (*CI) {
+      if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI)) {
+        InnerContexts.insert(cast<DeclContext>(CBE->getBlockDecl()));
+        GetInnerBlockDeclRefExprs(CBE->getBody(),
+                                  InnerBlockDeclRefs,
+                                  InnerContexts);
+      }
+      else
+        GetInnerBlockDeclRefExprs(*CI,
+                                  InnerBlockDeclRefs,
+                                  InnerContexts);
+
+    }
+  // Handle specific things.
+  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
+    if (DRE->refersToEnclosingLocal()) {
+      if (!isa<FunctionDecl>(DRE->getDecl()) &&
+          !InnerContexts.count(DRE->getDecl()->getDeclContext()))
+        InnerBlockDeclRefs.push_back(DRE);
+      if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl()))
+        if (Var->isFunctionOrMethodVarDecl())
+          ImportedLocalExternalDecls.insert(Var);
+    }
+  }
+  
+  return;
+}
+
+/// convertFunctionTypeOfBlocks - This routine converts a function type
+/// whose result type may be a block pointer or whose argument type(s)
+/// might be block pointers to an equivalent function type replacing
+/// all block pointers to function pointers.
+QualType RewriteObjC::convertFunctionTypeOfBlocks(const FunctionType *FT) {
+  const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT);
+  // FTP will be null for closures that don't take arguments.
+  // Generate a funky cast.
+  SmallVector<QualType, 8> ArgTypes;
+  QualType Res = FT->getReturnType();
+  bool HasBlockType = convertBlockPointerToFunctionPointer(Res);
+  
+  if (FTP) {
+    for (auto &I : FTP->param_types()) {
+      QualType t = I;
+      // Make sure we convert "t (^)(...)" to "t (*)(...)".
+      if (convertBlockPointerToFunctionPointer(t))
+        HasBlockType = true;
+      ArgTypes.push_back(t);
+    }
+  }
+  QualType FuncType;
+  // FIXME. Does this work if block takes no argument but has a return type
+  // which is of block type?
+  if (HasBlockType)
+    FuncType = getSimpleFunctionType(Res, ArgTypes);
+  else FuncType = QualType(FT, 0);
+  return FuncType;
+}
+
+Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp) {
+  // Navigate to relevant type information.
+  const BlockPointerType *CPT = nullptr;
+
+  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BlockExp)) {
+    CPT = DRE->getType()->getAs<BlockPointerType>();
+  } else if (const MemberExpr *MExpr = dyn_cast<MemberExpr>(BlockExp)) {
+    CPT = MExpr->getType()->getAs<BlockPointerType>();
+  } 
+  else if (const ParenExpr *PRE = dyn_cast<ParenExpr>(BlockExp)) {
+    return SynthesizeBlockCall(Exp, PRE->getSubExpr());
+  }
+  else if (const ImplicitCastExpr *IEXPR = dyn_cast<ImplicitCastExpr>(BlockExp)) 
+    CPT = IEXPR->getType()->getAs<BlockPointerType>();
+  else if (const ConditionalOperator *CEXPR = 
+            dyn_cast<ConditionalOperator>(BlockExp)) {
+    Expr *LHSExp = CEXPR->getLHS();
+    Stmt *LHSStmt = SynthesizeBlockCall(Exp, LHSExp);
+    Expr *RHSExp = CEXPR->getRHS();
+    Stmt *RHSStmt = SynthesizeBlockCall(Exp, RHSExp);
+    Expr *CONDExp = CEXPR->getCond();
+    ConditionalOperator *CondExpr =
+      new (Context) ConditionalOperator(CONDExp,
+                                      SourceLocation(), cast<Expr>(LHSStmt),
+                                      SourceLocation(), cast<Expr>(RHSStmt),
+                                      Exp->getType(), VK_RValue, OK_Ordinary);
+    return CondExpr;
+  } else if (const ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(BlockExp)) {
+    CPT = IRE->getType()->getAs<BlockPointerType>();
+  } else if (const PseudoObjectExpr *POE
+               = dyn_cast<PseudoObjectExpr>(BlockExp)) {
+    CPT = POE->getType()->castAs<BlockPointerType>();
+  } else {
+    assert(1 && "RewriteBlockClass: Bad type");
+  }
+  assert(CPT && "RewriteBlockClass: Bad type");
+  const FunctionType *FT = CPT->getPointeeType()->getAs<FunctionType>();
+  assert(FT && "RewriteBlockClass: Bad type");
+  const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT);
+  // FTP will be null for closures that don't take arguments.
+
+  RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
+                                      SourceLocation(), SourceLocation(),
+                                      &Context->Idents.get("__block_impl"));
+  QualType PtrBlock = Context->getPointerType(Context->getTagDeclType(RD));
+
+  // Generate a funky cast.
+  SmallVector<QualType, 8> ArgTypes;
+
+  // Push the block argument type.
+  ArgTypes.push_back(PtrBlock);
+  if (FTP) {
+    for (auto &I : FTP->param_types()) {
+      QualType t = I;
+      // Make sure we convert "t (^)(...)" to "t (*)(...)".
+      if (!convertBlockPointerToFunctionPointer(t))
+        convertToUnqualifiedObjCType(t);
+      ArgTypes.push_back(t);
+    }
+  }
+  // Now do the pointer to function cast.
+  QualType PtrToFuncCastType = getSimpleFunctionType(Exp->getType(), ArgTypes);
+
+  PtrToFuncCastType = Context->getPointerType(PtrToFuncCastType);
+
+  CastExpr *BlkCast = NoTypeInfoCStyleCastExpr(Context, PtrBlock,
+                                               CK_BitCast,
+                                               const_cast<Expr*>(BlockExp));
+  // Don't forget the parens to enforce the proper binding.
+  ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(),
+                                          BlkCast);
+  //PE->dump();
+
+  FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(),
+                                    SourceLocation(),
+                                    &Context->Idents.get("FuncPtr"),
+                                    Context->VoidPtrTy, nullptr,
+                                    /*BitWidth=*/nullptr, /*Mutable=*/true,
+                                    ICIS_NoInit);
+  MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(),
+                                            FD->getType(), VK_LValue,
+                                            OK_Ordinary);
+
+  
+  CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(Context, PtrToFuncCastType,
+                                                CK_BitCast, ME);
+  PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), FunkCast);
+
+  SmallVector<Expr*, 8> BlkExprs;
+  // Add the implicit argument.
+  BlkExprs.push_back(BlkCast);
+  // Add the user arguments.
+  for (CallExpr::arg_iterator I = Exp->arg_begin(),
+       E = Exp->arg_end(); I != E; ++I) {
+    BlkExprs.push_back(*I);
+  }
+  CallExpr *CE = new (Context) CallExpr(*Context, PE, BlkExprs,
+                                        Exp->getType(), VK_RValue,
+                                        SourceLocation());
+  return CE;
+}
+
+// We need to return the rewritten expression to handle cases where the
+// BlockDeclRefExpr is embedded in another expression being rewritten.
+// For example:
+//
+// int main() {
+//    __block Foo *f;
+//    __block int i;
+//
+//    void (^myblock)() = ^() {
+//        [f test]; // f is a BlockDeclRefExpr embedded in a message (which is being rewritten).
+//        i = 77;
+//    };
+//}
+Stmt *RewriteObjC::RewriteBlockDeclRefExpr(DeclRefExpr *DeclRefExp) {
+  // Rewrite the byref variable into BYREFVAR->__forwarding->BYREFVAR 
+  // for each DeclRefExp where BYREFVAR is name of the variable.
+  ValueDecl *VD = DeclRefExp->getDecl();
+  bool isArrow = DeclRefExp->refersToEnclosingLocal();
+
+  FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(),
+                                    SourceLocation(),
+                                    &Context->Idents.get("__forwarding"), 
+                                    Context->VoidPtrTy, nullptr,
+                                    /*BitWidth=*/nullptr, /*Mutable=*/true,
+                                    ICIS_NoInit);
+  MemberExpr *ME = new (Context) MemberExpr(DeclRefExp, isArrow,
+                                            FD, SourceLocation(),
+                                            FD->getType(), VK_LValue,
+                                            OK_Ordinary);
+
+  StringRef Name = VD->getName();
+  FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), SourceLocation(),
+                         &Context->Idents.get(Name), 
+                         Context->VoidPtrTy, nullptr,
+                         /*BitWidth=*/nullptr, /*Mutable=*/true,
+                         ICIS_NoInit);
+  ME = new (Context) MemberExpr(ME, true, FD, SourceLocation(),
+                                DeclRefExp->getType(), VK_LValue, OK_Ordinary);
+  
+  
+  
+  // Need parens to enforce precedence.
+  ParenExpr *PE = new (Context) ParenExpr(DeclRefExp->getExprLoc(), 
+                                          DeclRefExp->getExprLoc(), 
+                                          ME);
+  ReplaceStmt(DeclRefExp, PE);
+  return PE;
+}
+
+// Rewrites the imported local variable V with external storage 
+// (static, extern, etc.) as *V
+//
+Stmt *RewriteObjC::RewriteLocalVariableExternalStorage(DeclRefExpr *DRE) {
+  ValueDecl *VD = DRE->getDecl();
+  if (VarDecl *Var = dyn_cast<VarDecl>(VD))
+    if (!ImportedLocalExternalDecls.count(Var))
+      return DRE;
+  Expr *Exp = new (Context) UnaryOperator(DRE, UO_Deref, DRE->getType(),
+                                          VK_LValue, OK_Ordinary,
+                                          DRE->getLocation());
+  // Need parens to enforce precedence.
+  ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 
+                                          Exp);
+  ReplaceStmt(DRE, PE);
+  return PE;
+}
+
+void RewriteObjC::RewriteCastExpr(CStyleCastExpr *CE) {
+  SourceLocation LocStart = CE->getLParenLoc();
+  SourceLocation LocEnd = CE->getRParenLoc();
+
+  // Need to avoid trying to rewrite synthesized casts.
+  if (LocStart.isInvalid())
+    return;
+  // Need to avoid trying to rewrite casts contained in macros.
+  if (!Rewriter::isRewritable(LocStart) || !Rewriter::isRewritable(LocEnd))
+    return;
+
+  const char *startBuf = SM->getCharacterData(LocStart);
+  const char *endBuf = SM->getCharacterData(LocEnd);
+  QualType QT = CE->getType();
+  const Type* TypePtr = QT->getAs<Type>();
+  if (isa<TypeOfExprType>(TypePtr)) {
+    const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
+    QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType();
+    std::string TypeAsString = "(";
+    RewriteBlockPointerType(TypeAsString, QT);
+    TypeAsString += ")";
+    ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString);
+    return;
+  }
+  // advance the location to startArgList.
+  const char *argPtr = startBuf;
+
+  while (*argPtr++ && (argPtr < endBuf)) {
+    switch (*argPtr) {
+    case '^':
+      // Replace the '^' with '*'.
+      LocStart = LocStart.getLocWithOffset(argPtr-startBuf);
+      ReplaceText(LocStart, 1, "*");
+      break;
+    }
+  }
+  return;
+}
+
+void RewriteObjC::RewriteBlockPointerFunctionArgs(FunctionDecl *FD) {
+  SourceLocation DeclLoc = FD->getLocation();
+  unsigned parenCount = 0;
+
+  // We have 1 or more arguments that have closure pointers.
+  const char *startBuf = SM->getCharacterData(DeclLoc);
+  const char *startArgList = strchr(startBuf, '(');
+
+  assert((*startArgList == '(') && "Rewriter fuzzy parser confused");
+
+  parenCount++;
+  // advance the location to startArgList.
+  DeclLoc = DeclLoc.getLocWithOffset(startArgList-startBuf);
+  assert((DeclLoc.isValid()) && "Invalid DeclLoc");
+
+  const char *argPtr = startArgList;
+
+  while (*argPtr++ && parenCount) {
+    switch (*argPtr) {
+    case '^':
+      // Replace the '^' with '*'.
+      DeclLoc = DeclLoc.getLocWithOffset(argPtr-startArgList);
+      ReplaceText(DeclLoc, 1, "*");
+      break;
+    case '(':
+      parenCount++;
+      break;
+    case ')':
+      parenCount--;
+      break;
+    }
+  }
+  return;
+}
+
+bool RewriteObjC::PointerTypeTakesAnyBlockArguments(QualType QT) {
+  const FunctionProtoType *FTP;
+  const PointerType *PT = QT->getAs<PointerType>();
+  if (PT) {
+    FTP = PT->getPointeeType()->getAs<FunctionProtoType>();
+  } else {
+    const BlockPointerType *BPT = QT->getAs<BlockPointerType>();
+    assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
+    FTP = BPT->getPointeeType()->getAs<FunctionProtoType>();
+  }
+  if (FTP) {
+    for (const auto &I : FTP->param_types())
+      if (isTopLevelBlockPointerType(I))
+        return true;
+  }
+  return false;
+}
+
+bool RewriteObjC::PointerTypeTakesAnyObjCQualifiedType(QualType QT) {
+  const FunctionProtoType *FTP;
+  const PointerType *PT = QT->getAs<PointerType>();
+  if (PT) {
+    FTP = PT->getPointeeType()->getAs<FunctionProtoType>();
+  } else {
+    const BlockPointerType *BPT = QT->getAs<BlockPointerType>();
+    assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
+    FTP = BPT->getPointeeType()->getAs<FunctionProtoType>();
+  }
+  if (FTP) {
+    for (const auto &I : FTP->param_types()) {
+      if (I->isObjCQualifiedIdType())
+        return true;
+      if (I->isObjCObjectPointerType() &&
+          I->getPointeeType()->isObjCQualifiedInterfaceType())
+        return true;
+    }
+        
+  }
+  return false;
+}
+
+void RewriteObjC::GetExtentOfArgList(const char *Name, const char *&LParen,
+                                     const char *&RParen) {
+  const char *argPtr = strchr(Name, '(');
+  assert((*argPtr == '(') && "Rewriter fuzzy parser confused");
+
+  LParen = argPtr; // output the start.
+  argPtr++; // skip past the left paren.
+  unsigned parenCount = 1;
+
+  while (*argPtr && parenCount) {
+    switch (*argPtr) {
+    case '(': parenCount++; break;
+    case ')': parenCount--; break;
+    default: break;
+    }
+    if (parenCount) argPtr++;
+  }
+  assert((*argPtr == ')') && "Rewriter fuzzy parser confused");
+  RParen = argPtr; // output the end
+}
+
+void RewriteObjC::RewriteBlockPointerDecl(NamedDecl *ND) {
+  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
+    RewriteBlockPointerFunctionArgs(FD);
+    return;
+  }
+  // Handle Variables and Typedefs.
+  SourceLocation DeclLoc = ND->getLocation();
+  QualType DeclT;
+  if (VarDecl *VD = dyn_cast<VarDecl>(ND))
+    DeclT = VD->getType();
+  else if (TypedefNameDecl *TDD = dyn_cast<TypedefNameDecl>(ND))
+    DeclT = TDD->getUnderlyingType();
+  else if (FieldDecl *FD = dyn_cast<FieldDecl>(ND))
+    DeclT = FD->getType();
+  else
+    llvm_unreachable("RewriteBlockPointerDecl(): Decl type not yet handled");
+
+  const char *startBuf = SM->getCharacterData(DeclLoc);
+  const char *endBuf = startBuf;
+  // scan backward (from the decl location) for the end of the previous decl.
+  while (*startBuf != '^' && *startBuf != ';' && startBuf != MainFileStart)
+    startBuf--;
+  SourceLocation Start = DeclLoc.getLocWithOffset(startBuf-endBuf);
+  std::string buf;
+  unsigned OrigLength=0;
+  // *startBuf != '^' if we are dealing with a pointer to function that
+  // may take block argument types (which will be handled below).
+  if (*startBuf == '^') {
+    // Replace the '^' with '*', computing a negative offset.
+    buf = '*';
+    startBuf++;
+    OrigLength++;
+  }
+  while (*startBuf != ')') {
+    buf += *startBuf;
+    startBuf++;
+    OrigLength++;
+  }
+  buf += ')';
+  OrigLength++;
+  
+  if (PointerTypeTakesAnyBlockArguments(DeclT) ||
+      PointerTypeTakesAnyObjCQualifiedType(DeclT)) {
+    // Replace the '^' with '*' for arguments.
+    // Replace id<P> with id/*<>*/
+    DeclLoc = ND->getLocation();
+    startBuf = SM->getCharacterData(DeclLoc);
+    const char *argListBegin, *argListEnd;
+    GetExtentOfArgList(startBuf, argListBegin, argListEnd);
+    while (argListBegin < argListEnd) {
+      if (*argListBegin == '^')
+        buf += '*';
+      else if (*argListBegin ==  '<') {
+        buf += "/*"; 
+        buf += *argListBegin++;
+        OrigLength++;
+        while (*argListBegin != '>') {
+          buf += *argListBegin++;
+          OrigLength++;
+        }
+        buf += *argListBegin;
+        buf += "*/";
+      }
+      else
+        buf += *argListBegin;
+      argListBegin++;
+      OrigLength++;
+    }
+    buf += ')';
+    OrigLength++;
+  }
+  ReplaceText(Start, OrigLength, buf);
+  
+  return;
+}
+
+
+/// SynthesizeByrefCopyDestroyHelper - This routine synthesizes:
+/// void __Block_byref_id_object_copy(struct Block_byref_id_object *dst,
+///                    struct Block_byref_id_object *src) {
+///  _Block_object_assign (&_dest->object, _src->object, 
+///                        BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT
+///                        [|BLOCK_FIELD_IS_WEAK]) // object
+///  _Block_object_assign(&_dest->object, _src->object, 
+///                       BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK
+///                       [|BLOCK_FIELD_IS_WEAK]) // block
+/// }
+/// And:
+/// void __Block_byref_id_object_dispose(struct Block_byref_id_object *_src) {
+///  _Block_object_dispose(_src->object, 
+///                        BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT
+///                        [|BLOCK_FIELD_IS_WEAK]) // object
+///  _Block_object_dispose(_src->object, 
+///                         BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK
+///                         [|BLOCK_FIELD_IS_WEAK]) // block
+/// }
+
+std::string RewriteObjC::SynthesizeByrefCopyDestroyHelper(VarDecl *VD,
+                                                          int flag) {
+  std::string S;
+  if (CopyDestroyCache.count(flag))
+    return S;
+  CopyDestroyCache.insert(flag);
+  S = "static void __Block_byref_id_object_copy_";
+  S += utostr(flag);
+  S += "(void *dst, void *src) {\n";
+  
+  // offset into the object pointer is computed as:
+  // void * + void* + int + int + void* + void *
+  unsigned IntSize = 
+  static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
+  unsigned VoidPtrSize = 
+  static_cast<unsigned>(Context->getTypeSize(Context->VoidPtrTy));
+  
+  unsigned offset = (VoidPtrSize*4 + IntSize + IntSize)/Context->getCharWidth();
+  S += " _Block_object_assign((char*)dst + ";
+  S += utostr(offset);
+  S += ", *(void * *) ((char*)src + ";
+  S += utostr(offset);
+  S += "), ";
+  S += utostr(flag);
+  S += ");\n}\n";
+  
+  S += "static void __Block_byref_id_object_dispose_";
+  S += utostr(flag);
+  S += "(void *src) {\n";
+  S += " _Block_object_dispose(*(void * *) ((char*)src + ";
+  S += utostr(offset);
+  S += "), ";
+  S += utostr(flag);
+  S += ");\n}\n";
+  return S;
+}
+
+/// RewriteByRefVar - For each __block typex ND variable this routine transforms
+/// the declaration into:
+/// struct __Block_byref_ND {
+/// void *__isa;                  // NULL for everything except __weak pointers
+/// struct __Block_byref_ND *__forwarding;
+/// int32_t __flags;
+/// int32_t __size;
+/// void *__Block_byref_id_object_copy; // If variable is __block ObjC object
+/// void *__Block_byref_id_object_dispose; // If variable is __block ObjC object
+/// typex ND;
+/// };
+///
+/// It then replaces declaration of ND variable with:
+/// struct __Block_byref_ND ND = {__isa=0B, __forwarding=&ND, __flags=some_flag, 
+///                               __size=sizeof(struct __Block_byref_ND), 
+///                               ND=initializer-if-any};
+///
+///
+void RewriteObjC::RewriteByRefVar(VarDecl *ND) {
+  // Insert declaration for the function in which block literal is
+  // used.
+  if (CurFunctionDeclToDeclareForBlock)
+    RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock);
+  int flag = 0;
+  int isa = 0;
+  SourceLocation DeclLoc = ND->getTypeSpecStartLoc();
+  if (DeclLoc.isInvalid())
+    // If type location is missing, it is because of missing type (a warning).
+    // Use variable's location which is good for this case.
+    DeclLoc = ND->getLocation();
+  const char *startBuf = SM->getCharacterData(DeclLoc);
+  SourceLocation X = ND->getLocEnd();
+  X = SM->getExpansionLoc(X);
+  const char *endBuf = SM->getCharacterData(X);
+  std::string Name(ND->getNameAsString());
+  std::string ByrefType;
+  RewriteByRefString(ByrefType, Name, ND, true);
+  ByrefType += " {\n";
+  ByrefType += "  void *__isa;\n";
+  RewriteByRefString(ByrefType, Name, ND);
+  ByrefType += " *__forwarding;\n";
+  ByrefType += " int __flags;\n";
+  ByrefType += " int __size;\n";
+  // Add void *__Block_byref_id_object_copy; 
+  // void *__Block_byref_id_object_dispose; if needed.
+  QualType Ty = ND->getType();
+  bool HasCopyAndDispose = Context->BlockRequiresCopying(Ty, ND);
+  if (HasCopyAndDispose) {
+    ByrefType += " void (*__Block_byref_id_object_copy)(void*, void*);\n";
+    ByrefType += " void (*__Block_byref_id_object_dispose)(void*);\n";
+  }
+
+  QualType T = Ty;
+  (void)convertBlockPointerToFunctionPointer(T);
+  T.getAsStringInternal(Name, Context->getPrintingPolicy());
+    
+  ByrefType += " " + Name + ";\n";
+  ByrefType += "};\n";
+  // Insert this type in global scope. It is needed by helper function.
+  SourceLocation FunLocStart;
+  if (CurFunctionDef)
+     FunLocStart = CurFunctionDef->getTypeSpecStartLoc();
+  else {
+    assert(CurMethodDef && "RewriteByRefVar - CurMethodDef is null");
+    FunLocStart = CurMethodDef->getLocStart();
+  }
+  InsertText(FunLocStart, ByrefType);
+  if (Ty.isObjCGCWeak()) {
+    flag |= BLOCK_FIELD_IS_WEAK;
+    isa = 1;
+  }
+  
+  if (HasCopyAndDispose) {
+    flag = BLOCK_BYREF_CALLER;
+    QualType Ty = ND->getType();
+    // FIXME. Handle __weak variable (BLOCK_FIELD_IS_WEAK) as well.
+    if (Ty->isBlockPointerType())
+      flag |= BLOCK_FIELD_IS_BLOCK;
+    else
+      flag |= BLOCK_FIELD_IS_OBJECT;
+    std::string HF = SynthesizeByrefCopyDestroyHelper(ND, flag);
+    if (!HF.empty())
+      InsertText(FunLocStart, HF);
+  }
+  
+  // struct __Block_byref_ND ND = 
+  // {0, &ND, some_flag, __size=sizeof(struct __Block_byref_ND), 
+  //  initializer-if-any};
+  bool hasInit = (ND->getInit() != nullptr);
+  unsigned flags = 0;
+  if (HasCopyAndDispose)
+    flags |= BLOCK_HAS_COPY_DISPOSE;
+  Name = ND->getNameAsString();
+  ByrefType.clear();
+  RewriteByRefString(ByrefType, Name, ND);
+  std::string ForwardingCastType("(");
+  ForwardingCastType += ByrefType + " *)";
+  if (!hasInit) {
+    ByrefType += " " + Name + " = {(void*)";
+    ByrefType += utostr(isa);
+    ByrefType += "," +  ForwardingCastType + "&" + Name + ", ";
+    ByrefType += utostr(flags);
+    ByrefType += ", ";
+    ByrefType += "sizeof(";
+    RewriteByRefString(ByrefType, Name, ND);
+    ByrefType += ")";
+    if (HasCopyAndDispose) {
+      ByrefType += ", __Block_byref_id_object_copy_";
+      ByrefType += utostr(flag);
+      ByrefType += ", __Block_byref_id_object_dispose_";
+      ByrefType += utostr(flag);
+    }
+    ByrefType += "};\n";
+    unsigned nameSize = Name.size();
+    // for block or function pointer declaration. Name is aleady
+    // part of the declaration.
+    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType())
+      nameSize = 1;
+    ReplaceText(DeclLoc, endBuf-startBuf+nameSize, ByrefType);
+  }
+  else {
+    SourceLocation startLoc;
+    Expr *E = ND->getInit();
+    if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E))
+      startLoc = ECE->getLParenLoc();
+    else
+      startLoc = E->getLocStart();
+    startLoc = SM->getExpansionLoc(startLoc);
+    endBuf = SM->getCharacterData(startLoc);
+    ByrefType += " " + Name;
+    ByrefType += " = {(void*)";
+    ByrefType += utostr(isa);
+    ByrefType += "," +  ForwardingCastType + "&" + Name + ", ";
+    ByrefType += utostr(flags);
+    ByrefType += ", ";
+    ByrefType += "sizeof(";
+    RewriteByRefString(ByrefType, Name, ND);
+    ByrefType += "), ";
+    if (HasCopyAndDispose) {
+      ByrefType += "__Block_byref_id_object_copy_";
+      ByrefType += utostr(flag);
+      ByrefType += ", __Block_byref_id_object_dispose_";
+      ByrefType += utostr(flag);
+      ByrefType += ", ";
+    }
+    ReplaceText(DeclLoc, endBuf-startBuf, ByrefType);
+    
+    // Complete the newly synthesized compound expression by inserting a right
+    // curly brace before the end of the declaration.
+    // FIXME: This approach avoids rewriting the initializer expression. It
+    // also assumes there is only one declarator. For example, the following
+    // isn't currently supported by this routine (in general):
+    // 
+    // double __block BYREFVAR = 1.34, BYREFVAR2 = 1.37;
+    //
+    const char *startInitializerBuf = SM->getCharacterData(startLoc);
+    const char *semiBuf = strchr(startInitializerBuf, ';');
+    assert((*semiBuf == ';') && "RewriteByRefVar: can't find ';'");
+    SourceLocation semiLoc =
+      startLoc.getLocWithOffset(semiBuf-startInitializerBuf);
+
+    InsertText(semiLoc, "}");
+  }
+  return;
+}
+
+void RewriteObjC::CollectBlockDeclRefInfo(BlockExpr *Exp) {
+  // Add initializers for any closure decl refs.
+  GetBlockDeclRefExprs(Exp->getBody());
+  if (BlockDeclRefs.size()) {
+    // Unique all "by copy" declarations.
+    for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
+      if (!BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
+        if (!BlockByCopyDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
+          BlockByCopyDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
+          BlockByCopyDecls.push_back(BlockDeclRefs[i]->getDecl());
+        }
+      }
+    // Unique all "by ref" declarations.
+    for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
+      if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
+        if (!BlockByRefDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
+          BlockByRefDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
+          BlockByRefDecls.push_back(BlockDeclRefs[i]->getDecl());
+        }
+      }
+    // Find any imported blocks...they will need special attention.
+    for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
+      if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
+          BlockDeclRefs[i]->getType()->isObjCObjectPointerType() || 
+          BlockDeclRefs[i]->getType()->isBlockPointerType())
+        ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl());
+  }
+}
+
+FunctionDecl *RewriteObjC::SynthBlockInitFunctionDecl(StringRef name) {
+  IdentifierInfo *ID = &Context->Idents.get(name);
+  QualType FType = Context->getFunctionNoProtoType(Context->VoidPtrTy);
+  return FunctionDecl::Create(*Context, TUDecl, SourceLocation(),
+                              SourceLocation(), ID, FType, nullptr, SC_Extern,
+                              false, false);
+}
+
+Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp,
+                     const SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs) {
+  const BlockDecl *block = Exp->getBlockDecl();
+  Blocks.push_back(Exp);
+
+  CollectBlockDeclRefInfo(Exp);
+  
+  // Add inner imported variables now used in current block.
+ int countOfInnerDecls = 0;
+  if (!InnerBlockDeclRefs.empty()) {
+    for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) {
+      DeclRefExpr *Exp = InnerBlockDeclRefs[i];
+      ValueDecl *VD = Exp->getDecl();
+      if (!VD->hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) {
+      // We need to save the copied-in variables in nested
+      // blocks because it is needed at the end for some of the API generations.
+      // See SynthesizeBlockLiterals routine.
+        InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
+        BlockDeclRefs.push_back(Exp);
+        BlockByCopyDeclsPtrSet.insert(VD);
+        BlockByCopyDecls.push_back(VD);
+      }
+      if (VD->hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) {
+        InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
+        BlockDeclRefs.push_back(Exp);
+        BlockByRefDeclsPtrSet.insert(VD);
+        BlockByRefDecls.push_back(VD);
+      }
+    }
+    // Find any imported blocks...they will need special attention.
+    for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++)
+      if (InnerBlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
+          InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() || 
+          InnerBlockDeclRefs[i]->getType()->isBlockPointerType())
+        ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl());
+  }
+  InnerDeclRefsCount.push_back(countOfInnerDecls);
+  
+  std::string FuncName;
+
+  if (CurFunctionDef)
+    FuncName = CurFunctionDef->getNameAsString();
+  else if (CurMethodDef)
+    BuildUniqueMethodName(FuncName, CurMethodDef);
+  else if (GlobalVarDecl)
+    FuncName = std::string(GlobalVarDecl->getNameAsString());
+
+  std::string BlockNumber = utostr(Blocks.size()-1);
+
+  std::string Tag = "__" + FuncName + "_block_impl_" + BlockNumber;
+  std::string Func = "__" + FuncName + "_block_func_" + BlockNumber;
+
+  // Get a pointer to the function type so we can cast appropriately.
+  QualType BFT = convertFunctionTypeOfBlocks(Exp->getFunctionType());
+  QualType FType = Context->getPointerType(BFT);
+
+  FunctionDecl *FD;
+  Expr *NewRep;
+
+  // Simulate a constructor call...
+  FD = SynthBlockInitFunctionDecl(Tag);
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, false, FType, VK_RValue,
+                                               SourceLocation());
+
+  SmallVector<Expr*, 4> InitExprs;
+
+  // Initialize the block function.
+  FD = SynthBlockInitFunctionDecl(Func);
+  DeclRefExpr *Arg = new (Context) DeclRefExpr(FD, false, FD->getType(),
+                                               VK_LValue, SourceLocation());
+  CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
+                                                CK_BitCast, Arg);
+  InitExprs.push_back(castExpr);
+
+  // Initialize the block descriptor.
+  std::string DescData = "__" + FuncName + "_block_desc_" + BlockNumber + "_DATA";
+
+  VarDecl *NewVD = VarDecl::Create(*Context, TUDecl,
+                                   SourceLocation(), SourceLocation(),
+                                   &Context->Idents.get(DescData.c_str()),
+                                   Context->VoidPtrTy, nullptr,
+                                   SC_Static);
+  UnaryOperator *DescRefExpr =
+    new (Context) UnaryOperator(new (Context) DeclRefExpr(NewVD, false,
+                                                          Context->VoidPtrTy,
+                                                          VK_LValue,
+                                                          SourceLocation()), 
+                                UO_AddrOf,
+                                Context->getPointerType(Context->VoidPtrTy), 
+                                VK_RValue, OK_Ordinary,
+                                SourceLocation());
+  InitExprs.push_back(DescRefExpr); 
+  
+  // Add initializers for any closure decl refs.
+  if (BlockDeclRefs.size()) {
+    Expr *Exp;
+    // Output all "by copy" declarations.
+    for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(),
+         E = BlockByCopyDecls.end(); I != E; ++I) {
+      if (isObjCType((*I)->getType())) {
+        // FIXME: Conform to ABI ([[obj retain] autorelease]).
+        FD = SynthBlockInitFunctionDecl((*I)->getName());
+        Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue,
+                                        SourceLocation());
+        if (HasLocalVariableExternalStorage(*I)) {
+          QualType QT = (*I)->getType();
+          QT = Context->getPointerType(QT);
+          Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue,
+                                            OK_Ordinary, SourceLocation());
+        }
+      } else if (isTopLevelBlockPointerType((*I)->getType())) {
+        FD = SynthBlockInitFunctionDecl((*I)->getName());
+        Arg = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue,
+                                        SourceLocation());
+        Exp = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
+                                       CK_BitCast, Arg);
+      } else {
+        FD = SynthBlockInitFunctionDecl((*I)->getName());
+        Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue,
+                                        SourceLocation());
+        if (HasLocalVariableExternalStorage(*I)) {
+          QualType QT = (*I)->getType();
+          QT = Context->getPointerType(QT);
+          Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue,
+                                            OK_Ordinary, SourceLocation());
+        }
+        
+      }
+      InitExprs.push_back(Exp);
+    }
+    // Output all "by ref" declarations.
+    for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(),
+         E = BlockByRefDecls.end(); I != E; ++I) {
+      ValueDecl *ND = (*I);
+      std::string Name(ND->getNameAsString());
+      std::string RecName;
+      RewriteByRefString(RecName, Name, ND, true);
+      IdentifierInfo *II = &Context->Idents.get(RecName.c_str() 
+                                                + sizeof("struct"));
+      RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
+                                          SourceLocation(), SourceLocation(),
+                                          II);
+      assert(RD && "SynthBlockInitExpr(): Can't find RecordDecl");
+      QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
+      
+      FD = SynthBlockInitFunctionDecl((*I)->getName());
+      Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue,
+                                      SourceLocation());
+      bool isNestedCapturedVar = false;
+      if (block)
+        for (const auto &CI : block->captures()) {
+          const VarDecl *variable = CI.getVariable();
+          if (variable == ND && CI.isNested()) {
+            assert (CI.isByRef() && 
+                    "SynthBlockInitExpr - captured block variable is not byref");
+            isNestedCapturedVar = true;
+            break;
+          }
+        }
+      // captured nested byref variable has its address passed. Do not take
+      // its address again.
+      if (!isNestedCapturedVar)
+          Exp = new (Context) UnaryOperator(Exp, UO_AddrOf,
+                                     Context->getPointerType(Exp->getType()),
+                                     VK_RValue, OK_Ordinary, SourceLocation());
+      Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp);
+      InitExprs.push_back(Exp);
+    }
+  }
+  if (ImportedBlockDecls.size()) {
+    // generate BLOCK_HAS_COPY_DISPOSE(have helper funcs) | BLOCK_HAS_DESCRIPTOR
+    int flag = (BLOCK_HAS_COPY_DISPOSE | BLOCK_HAS_DESCRIPTOR);
+    unsigned IntSize = 
+      static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
+    Expr *FlagExp = IntegerLiteral::Create(*Context, llvm::APInt(IntSize, flag), 
+                                           Context->IntTy, SourceLocation());
+    InitExprs.push_back(FlagExp);
+  }
+  NewRep = new (Context) CallExpr(*Context, DRE, InitExprs,
+                                  FType, VK_LValue, SourceLocation());
+  NewRep = new (Context) UnaryOperator(NewRep, UO_AddrOf,
+                             Context->getPointerType(NewRep->getType()),
+                             VK_RValue, OK_Ordinary, SourceLocation());
+  NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast,
+                                    NewRep);
+  BlockDeclRefs.clear();
+  BlockByRefDecls.clear();
+  BlockByRefDeclsPtrSet.clear();
+  BlockByCopyDecls.clear();
+  BlockByCopyDeclsPtrSet.clear();
+  ImportedBlockDecls.clear();
+  return NewRep;
+}
+
+bool RewriteObjC::IsDeclStmtInForeachHeader(DeclStmt *DS) {
+  if (const ObjCForCollectionStmt * CS = 
+      dyn_cast<ObjCForCollectionStmt>(Stmts.back()))
+        return CS->getElement() == DS;
+  return false;
+}
+
+//===----------------------------------------------------------------------===//
+// Function Body / Expression rewriting
+//===----------------------------------------------------------------------===//
+
+Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) {
+  if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
+      isa<DoStmt>(S) || isa<ForStmt>(S))
+    Stmts.push_back(S);
+  else if (isa<ObjCForCollectionStmt>(S)) {
+    Stmts.push_back(S);
+    ObjCBcLabelNo.push_back(++BcLabelCount);
+  }
+
+  // Pseudo-object operations and ivar references need special
+  // treatment because we're going to recursively rewrite them.
+  if (PseudoObjectExpr *PseudoOp = dyn_cast<PseudoObjectExpr>(S)) {
+    if (isa<BinaryOperator>(PseudoOp->getSyntacticForm())) {
+      return RewritePropertyOrImplicitSetter(PseudoOp);
+    } else {
+      return RewritePropertyOrImplicitGetter(PseudoOp);
+    }
+  } else if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) {
+    return RewriteObjCIvarRefExpr(IvarRefExpr);
+  }
+
+  SourceRange OrigStmtRange = S->getSourceRange();
+
+  // Perform a bottom up rewrite of all children.
+  for (Stmt::child_range CI = S->children(); CI; ++CI)
+    if (*CI) {
+      Stmt *childStmt = (*CI);
+      Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(childStmt);
+      if (newStmt) {
+        *CI = newStmt;
+      }
+    }
+
+  if (BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
+    SmallVector<DeclRefExpr *, 8> InnerBlockDeclRefs;
+    llvm::SmallPtrSet<const DeclContext *, 8> InnerContexts;
+    InnerContexts.insert(BE->getBlockDecl());
+    ImportedLocalExternalDecls.clear();
+    GetInnerBlockDeclRefExprs(BE->getBody(),
+                              InnerBlockDeclRefs, InnerContexts);
+    // Rewrite the block body in place.
+    Stmt *SaveCurrentBody = CurrentBody;
+    CurrentBody = BE->getBody();
+    PropParentMap = nullptr;
+    // block literal on rhs of a property-dot-sytax assignment
+    // must be replaced by its synthesize ast so getRewrittenText
+    // works as expected. In this case, what actually ends up on RHS
+    // is the blockTranscribed which is the helper function for the
+    // block literal; as in: self.c = ^() {[ace ARR];};
+    bool saveDisableReplaceStmt = DisableReplaceStmt;
+    DisableReplaceStmt = false;
+    RewriteFunctionBodyOrGlobalInitializer(BE->getBody());
+    DisableReplaceStmt = saveDisableReplaceStmt;
+    CurrentBody = SaveCurrentBody;
+    PropParentMap = nullptr;
+    ImportedLocalExternalDecls.clear();
+    // Now we snarf the rewritten text and stash it away for later use.
+    std::string Str = Rewrite.getRewrittenText(BE->getSourceRange());
+    RewrittenBlockExprs[BE] = Str;
+
+    Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs);
+                            
+    //blockTranscribed->dump();
+    ReplaceStmt(S, blockTranscribed);
+    return blockTranscribed;
+  }
+  // Handle specific things.
+  if (ObjCEncodeExpr *AtEncode = dyn_cast<ObjCEncodeExpr>(S))
+    return RewriteAtEncode(AtEncode);
+
+  if (ObjCSelectorExpr *AtSelector = dyn_cast<ObjCSelectorExpr>(S))
+    return RewriteAtSelector(AtSelector);
+
+  if (ObjCStringLiteral *AtString = dyn_cast<ObjCStringLiteral>(S))
+    return RewriteObjCStringLiteral(AtString);
+
+  if (ObjCMessageExpr *MessExpr = dyn_cast<ObjCMessageExpr>(S)) {
+#if 0
+    // Before we rewrite it, put the original message expression in a comment.
+    SourceLocation startLoc = MessExpr->getLocStart();
+    SourceLocation endLoc = MessExpr->getLocEnd();
+
+    const char *startBuf = SM->getCharacterData(startLoc);
+    const char *endBuf = SM->getCharacterData(endLoc);
+
+    std::string messString;
+    messString += "// ";
+    messString.append(startBuf, endBuf-startBuf+1);
+    messString += "\n";
+
+    // FIXME: Missing definition of
+    // InsertText(clang::SourceLocation, char const*, unsigned int).
+    // InsertText(startLoc, messString.c_str(), messString.size());
+    // Tried this, but it didn't work either...
+    // ReplaceText(startLoc, 0, messString.c_str(), messString.size());
+#endif
+    return RewriteMessageExpr(MessExpr);
+  }
+
+  if (ObjCAtTryStmt *StmtTry = dyn_cast<ObjCAtTryStmt>(S))
+    return RewriteObjCTryStmt(StmtTry);
+
+  if (ObjCAtSynchronizedStmt *StmtTry = dyn_cast<ObjCAtSynchronizedStmt>(S))
+    return RewriteObjCSynchronizedStmt(StmtTry);
+
+  if (ObjCAtThrowStmt *StmtThrow = dyn_cast<ObjCAtThrowStmt>(S))
+    return RewriteObjCThrowStmt(StmtThrow);
+
+  if (ObjCProtocolExpr *ProtocolExp = dyn_cast<ObjCProtocolExpr>(S))
+    return RewriteObjCProtocolExpr(ProtocolExp);
+
+  if (ObjCForCollectionStmt *StmtForCollection =
+        dyn_cast<ObjCForCollectionStmt>(S))
+    return RewriteObjCForCollectionStmt(StmtForCollection,
+                                        OrigStmtRange.getEnd());
+  if (BreakStmt *StmtBreakStmt =
+      dyn_cast<BreakStmt>(S))
+    return RewriteBreakStmt(StmtBreakStmt);
+  if (ContinueStmt *StmtContinueStmt =
+      dyn_cast<ContinueStmt>(S))
+    return RewriteContinueStmt(StmtContinueStmt);
+
+  // Need to check for protocol refs (id <P>, Foo <P> *) in variable decls
+  // and cast exprs.
+  if (DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
+    // FIXME: What we're doing here is modifying the type-specifier that
+    // precedes the first Decl.  In the future the DeclGroup should have
+    // a separate type-specifier that we can rewrite.
+    // NOTE: We need to avoid rewriting the DeclStmt if it is within
+    // the context of an ObjCForCollectionStmt. For example:
+    //   NSArray *someArray;
+    //   for (id <FooProtocol> index in someArray) ;
+    // This is because RewriteObjCForCollectionStmt() does textual rewriting 
+    // and it depends on the original text locations/positions.
+    if (Stmts.empty() || !IsDeclStmtInForeachHeader(DS))
+      RewriteObjCQualifiedInterfaceTypes(*DS->decl_begin());
+
+    // Blocks rewrite rules.
+    for (auto *SD : DS->decls()) {
+      if (ValueDecl *ND = dyn_cast<ValueDecl>(SD)) {
+        if (isTopLevelBlockPointerType(ND->getType()))
+          RewriteBlockPointerDecl(ND);
+        else if (ND->getType()->isFunctionPointerType())
+          CheckFunctionPointerDecl(ND->getType(), ND);
+        if (VarDecl *VD = dyn_cast<VarDecl>(SD)) {
+          if (VD->hasAttr<BlocksAttr>()) {
+            static unsigned uniqueByrefDeclCount = 0;
+            assert(!BlockByRefDeclNo.count(ND) &&
+              "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl");
+            BlockByRefDeclNo[ND] = uniqueByrefDeclCount++;
+            RewriteByRefVar(VD);
+          }
+          else           
+            RewriteTypeOfDecl(VD);
+        }
+      }
+      if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(SD)) {
+        if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
+          RewriteBlockPointerDecl(TD);
+        else if (TD->getUnderlyingType()->isFunctionPointerType())
+          CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
+      }
+    }
+  }
+
+  if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(S))
+    RewriteObjCQualifiedInterfaceTypes(CE);
+
+  if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
+      isa<DoStmt>(S) || isa<ForStmt>(S)) {
+    assert(!Stmts.empty() && "Statement stack is empty");
+    assert ((isa<SwitchStmt>(Stmts.back()) || isa<WhileStmt>(Stmts.back()) ||
+             isa<DoStmt>(Stmts.back()) || isa<ForStmt>(Stmts.back()))
+            && "Statement stack mismatch");
+    Stmts.pop_back();
+  }
+  // Handle blocks rewriting.
+  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
+    ValueDecl *VD = DRE->getDecl(); 
+    if (VD->hasAttr<BlocksAttr>())
+      return RewriteBlockDeclRefExpr(DRE);
+    if (HasLocalVariableExternalStorage(VD))
+      return RewriteLocalVariableExternalStorage(DRE);
+  }
+  
+  if (CallExpr *CE = dyn_cast<CallExpr>(S)) {
+    if (CE->getCallee()->getType()->isBlockPointerType()) {
+      Stmt *BlockCall = SynthesizeBlockCall(CE, CE->getCallee());
+      ReplaceStmt(S, BlockCall);
+      return BlockCall;
+    }
+  }
+  if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(S)) {
+    RewriteCastExpr(CE);
+  }
+#if 0
+  if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(S)) {
+    CastExpr *Replacement = new (Context) CastExpr(ICE->getType(),
+                                                   ICE->getSubExpr(),
+                                                   SourceLocation());
+    // Get the new text.
+    std::string SStr;
+    llvm::raw_string_ostream Buf(SStr);
+    Replacement->printPretty(Buf);
+    const std::string &Str = Buf.str();
+
+    printf("CAST = %s\n", &Str[0]);
+    InsertText(ICE->getSubExpr()->getLocStart(), &Str[0], Str.size());
+    delete S;
+    return Replacement;
+  }
+#endif
+  // Return this stmt unmodified.
+  return S;
+}
+
+void RewriteObjC::RewriteRecordBody(RecordDecl *RD) {
+  for (auto *FD : RD->fields()) {
+    if (isTopLevelBlockPointerType(FD->getType()))
+      RewriteBlockPointerDecl(FD);
+    if (FD->getType()->isObjCQualifiedIdType() ||
+        FD->getType()->isObjCQualifiedInterfaceType())
+      RewriteObjCQualifiedInterfaceTypes(FD);
+  }
+}
+
+/// HandleDeclInMainFile - This is called for each top-level decl defined in the
+/// main file of the input.
+void RewriteObjC::HandleDeclInMainFile(Decl *D) {
+  switch (D->getKind()) {
+    case Decl::Function: {
+      FunctionDecl *FD = cast<FunctionDecl>(D);
+      if (FD->isOverloadedOperator())
+        return;
+
+      // Since function prototypes don't have ParmDecl's, we check the function
+      // prototype. This enables us to rewrite function declarations and
+      // definitions using the same code.
+      RewriteBlocksInFunctionProtoType(FD->getType(), FD);
+
+      if (!FD->isThisDeclarationADefinition())
+        break;
+
+      // FIXME: If this should support Obj-C++, support CXXTryStmt
+      if (CompoundStmt *Body = dyn_cast_or_null<CompoundStmt>(FD->getBody())) {
+        CurFunctionDef = FD;
+        CurFunctionDeclToDeclareForBlock = FD;
+        CurrentBody = Body;
+        Body =
+        cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
+        FD->setBody(Body);
+        CurrentBody = nullptr;
+        if (PropParentMap) {
+          delete PropParentMap;
+          PropParentMap = nullptr;
+        }
+        // This synthesizes and inserts the block "impl" struct, invoke function,
+        // and any copy/dispose helper functions.
+        InsertBlockLiteralsWithinFunction(FD);
+        CurFunctionDef = nullptr;
+        CurFunctionDeclToDeclareForBlock = nullptr;
+      }
+      break;
+    }
+    case Decl::ObjCMethod: {
+      ObjCMethodDecl *MD = cast<ObjCMethodDecl>(D);
+      if (CompoundStmt *Body = MD->getCompoundBody()) {
+        CurMethodDef = MD;
+        CurrentBody = Body;
+        Body =
+          cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
+        MD->setBody(Body);
+        CurrentBody = nullptr;
+        if (PropParentMap) {
+          delete PropParentMap;
+          PropParentMap = nullptr;
+        }
+        InsertBlockLiteralsWithinMethod(MD);
+        CurMethodDef = nullptr;
+      }
+      break;
+    }
+    case Decl::ObjCImplementation: {
+      ObjCImplementationDecl *CI = cast<ObjCImplementationDecl>(D);
+      ClassImplementation.push_back(CI);
+      break;
+    }
+    case Decl::ObjCCategoryImpl: {
+      ObjCCategoryImplDecl *CI = cast<ObjCCategoryImplDecl>(D);
+      CategoryImplementation.push_back(CI);
+      break;
+    }
+    case Decl::Var: {
+      VarDecl *VD = cast<VarDecl>(D);
+      RewriteObjCQualifiedInterfaceTypes(VD);
+      if (isTopLevelBlockPointerType(VD->getType()))
+        RewriteBlockPointerDecl(VD);
+      else if (VD->getType()->isFunctionPointerType()) {
+        CheckFunctionPointerDecl(VD->getType(), VD);
+        if (VD->getInit()) {
+          if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(VD->getInit())) {
+            RewriteCastExpr(CE);
+          }
+        }
+      } else if (VD->getType()->isRecordType()) {
+        RecordDecl *RD = VD->getType()->getAs<RecordType>()->getDecl();
+        if (RD->isCompleteDefinition())
+          RewriteRecordBody(RD);
+      }
+      if (VD->getInit()) {
+        GlobalVarDecl = VD;
+        CurrentBody = VD->getInit();
+        RewriteFunctionBodyOrGlobalInitializer(VD->getInit());
+        CurrentBody = nullptr;
+        if (PropParentMap) {
+          delete PropParentMap;
+          PropParentMap = nullptr;
+        }
+        SynthesizeBlockLiterals(VD->getTypeSpecStartLoc(), VD->getName());
+        GlobalVarDecl = nullptr;
+
+        // This is needed for blocks.
+        if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(VD->getInit())) {
+            RewriteCastExpr(CE);
+        }
+      }
+      break;
+    }
+    case Decl::TypeAlias:
+    case Decl::Typedef: {
+      if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
+        if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
+          RewriteBlockPointerDecl(TD);
+        else if (TD->getUnderlyingType()->isFunctionPointerType())
+          CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
+      }
+      break;
+    }
+    case Decl::CXXRecord:
+    case Decl::Record: {
+      RecordDecl *RD = cast<RecordDecl>(D);
+      if (RD->isCompleteDefinition()) 
+        RewriteRecordBody(RD);
+      break;
+    }
+    default:
+      break;
+  }
+  // Nothing yet.
+}
+
+void RewriteObjC::HandleTranslationUnit(ASTContext &C) {
+  if (Diags.hasErrorOccurred())
+    return;
+
+  RewriteInclude();
+
+  // Here's a great place to add any extra declarations that may be needed.
+  // Write out meta data for each @protocol(<expr>).
+  for (llvm::SmallPtrSet<ObjCProtocolDecl *,8>::iterator I = ProtocolExprDecls.begin(),
+       E = ProtocolExprDecls.end(); I != E; ++I)
+    RewriteObjCProtocolMetaData(*I, "", "", Preamble);
+
+  InsertText(SM->getLocForStartOfFile(MainFileID), Preamble, false);
+  if (ClassImplementation.size() || CategoryImplementation.size())
+    RewriteImplementations();
+
+  // Get the buffer corresponding to MainFileID.  If we haven't changed it, then
+  // we are done.
+  if (const RewriteBuffer *RewriteBuf =
+      Rewrite.getRewriteBufferFor(MainFileID)) {
+    //printf("Changed:\n");
+    *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end());
+  } else {
+    llvm::errs() << "No changes\n";
+  }
+
+  if (ClassImplementation.size() || CategoryImplementation.size() ||
+      ProtocolExprDecls.size()) {
+    // Rewrite Objective-c meta data*
+    std::string ResultStr;
+    RewriteMetaDataIntoBuffer(ResultStr);
+    // Emit metadata.
+    *OutFile << ResultStr;
+  }
+  OutFile->flush();
+}
+
+void RewriteObjCFragileABI::Initialize(ASTContext &context) {
+  InitializeCommon(context);
+  
+  // declaring objc_selector outside the parameter list removes a silly
+  // scope related warning...
+  if (IsHeader)
+    Preamble = "#pragma once\n";
+  Preamble += "struct objc_selector; struct objc_class;\n";
+  Preamble += "struct __rw_objc_super { struct objc_object *object; ";
+  Preamble += "struct objc_object *superClass; ";
+  if (LangOpts.MicrosoftExt) {
+    // Add a constructor for creating temporary objects.
+    Preamble += "__rw_objc_super(struct objc_object *o, struct objc_object *s) "
+    ": ";
+    Preamble += "object(o), superClass(s) {} ";
+  }
+  Preamble += "};\n";
+  Preamble += "#ifndef _REWRITER_typedef_Protocol\n";
+  Preamble += "typedef struct objc_object Protocol;\n";
+  Preamble += "#define _REWRITER_typedef_Protocol\n";
+  Preamble += "#endif\n";
+  if (LangOpts.MicrosoftExt) {
+    Preamble += "#define __OBJC_RW_DLLIMPORT extern \"C\" __declspec(dllimport)\n";
+    Preamble += "#define __OBJC_RW_STATICIMPORT extern \"C\"\n";
+  } else
+    Preamble += "#define __OBJC_RW_DLLIMPORT extern\n";
+  Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSend";
+  Preamble += "(struct objc_object *, struct objc_selector *, ...);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSendSuper";
+  Preamble += "(struct objc_super *, struct objc_selector *, ...);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT struct objc_object* objc_msgSend_stret";
+  Preamble += "(struct objc_object *, struct objc_selector *, ...);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT struct objc_object* objc_msgSendSuper_stret";
+  Preamble += "(struct objc_super *, struct objc_selector *, ...);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT double objc_msgSend_fpret";
+  Preamble += "(struct objc_object *, struct objc_selector *, ...);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_getClass";
+  Preamble += "(const char *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT struct objc_class *class_getSuperclass";
+  Preamble += "(struct objc_class *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_getMetaClass";
+  Preamble += "(const char *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_throw(struct objc_object *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_try_enter(void *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_try_exit(void *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_exception_extract(void *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT int objc_exception_match";
+  Preamble += "(struct objc_class *, struct objc_object *);\n";
+  // @synchronized hooks.
+  Preamble += "__OBJC_RW_DLLIMPORT int objc_sync_enter(struct objc_object *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT int objc_sync_exit(struct objc_object *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT Protocol *objc_getProtocol(const char *);\n";
+  Preamble += "#ifndef __FASTENUMERATIONSTATE\n";
+  Preamble += "struct __objcFastEnumerationState {\n\t";
+  Preamble += "unsigned long state;\n\t";
+  Preamble += "void **itemsPtr;\n\t";
+  Preamble += "unsigned long *mutationsPtr;\n\t";
+  Preamble += "unsigned long extra[5];\n};\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void objc_enumerationMutation(struct objc_object *);\n";
+  Preamble += "#define __FASTENUMERATIONSTATE\n";
+  Preamble += "#endif\n";
+  Preamble += "#ifndef __NSCONSTANTSTRINGIMPL\n";
+  Preamble += "struct __NSConstantStringImpl {\n";
+  Preamble += "  int *isa;\n";
+  Preamble += "  int flags;\n";
+  Preamble += "  char *str;\n";
+  Preamble += "  long length;\n";
+  Preamble += "};\n";
+  Preamble += "#ifdef CF_EXPORT_CONSTANT_STRING\n";
+  Preamble += "extern \"C\" __declspec(dllexport) int __CFConstantStringClassReference[];\n";
+  Preamble += "#else\n";
+  Preamble += "__OBJC_RW_DLLIMPORT int __CFConstantStringClassReference[];\n";
+  Preamble += "#endif\n";
+  Preamble += "#define __NSCONSTANTSTRINGIMPL\n";
+  Preamble += "#endif\n";
+  // Blocks preamble.
+  Preamble += "#ifndef BLOCK_IMPL\n";
+  Preamble += "#define BLOCK_IMPL\n";
+  Preamble += "struct __block_impl {\n";
+  Preamble += "  void *isa;\n";
+  Preamble += "  int Flags;\n";
+  Preamble += "  int Reserved;\n";
+  Preamble += "  void *FuncPtr;\n";
+  Preamble += "};\n";
+  Preamble += "// Runtime copy/destroy helper functions (from Block_private.h)\n";
+  Preamble += "#ifdef __OBJC_EXPORT_BLOCKS\n";
+  Preamble += "extern \"C\" __declspec(dllexport) "
+  "void _Block_object_assign(void *, const void *, const int);\n";
+  Preamble += "extern \"C\" __declspec(dllexport) void _Block_object_dispose(const void *, const int);\n";
+  Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];\n";
+  Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteStackBlock[32];\n";
+  Preamble += "#else\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void _Block_object_assign(void *, const void *, const int);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void _Block_object_dispose(const void *, const int);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void *_NSConcreteGlobalBlock[32];\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void *_NSConcreteStackBlock[32];\n";
+  Preamble += "#endif\n";
+  Preamble += "#endif\n";
+  if (LangOpts.MicrosoftExt) {
+    Preamble += "#undef __OBJC_RW_DLLIMPORT\n";
+    Preamble += "#undef __OBJC_RW_STATICIMPORT\n";
+    Preamble += "#ifndef KEEP_ATTRIBUTES\n";  // We use this for clang tests.
+    Preamble += "#define __attribute__(X)\n";
+    Preamble += "#endif\n";
+    Preamble += "#define __weak\n";
+  }
+  else {
+    Preamble += "#define __block\n";
+    Preamble += "#define __weak\n";
+  }
+  // NOTE! Windows uses LLP64 for 64bit mode. So, cast pointer to long long
+  // as this avoids warning in any 64bit/32bit compilation model.
+  Preamble += "\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n";
+}
+
+/// RewriteIvarOffsetComputation - This rutine synthesizes computation of
+/// ivar offset.
+void RewriteObjCFragileABI::RewriteIvarOffsetComputation(ObjCIvarDecl *ivar,
+                                                         std::string &Result) {
+  if (ivar->isBitField()) {
+    // FIXME: The hack below doesn't work for bitfields. For now, we simply
+    // place all bitfields at offset 0.
+    Result += "0";
+  } else {
+    Result += "__OFFSETOFIVAR__(struct ";
+    Result += ivar->getContainingInterface()->getNameAsString();
+    if (LangOpts.MicrosoftExt)
+      Result += "_IMPL";
+    Result += ", ";
+    Result += ivar->getNameAsString();
+    Result += ")";
+  }
+}
+
+/// RewriteObjCProtocolMetaData - Rewrite protocols meta-data.
+void RewriteObjCFragileABI::RewriteObjCProtocolMetaData(
+                            ObjCProtocolDecl *PDecl, StringRef prefix,
+                            StringRef ClassName, std::string &Result) {
+  static bool objc_protocol_methods = false;
+  
+  // Output struct protocol_methods holder of method selector and type.
+  if (!objc_protocol_methods && PDecl->hasDefinition()) {
+    /* struct protocol_methods {
+     SEL _cmd;
+     char *method_types;
+     }
+     */
+    Result += "\nstruct _protocol_methods {\n";
+    Result += "\tstruct objc_selector *_cmd;\n";
+    Result += "\tchar *method_types;\n";
+    Result += "};\n";
+    
+    objc_protocol_methods = true;
+  }
+  // Do not synthesize the protocol more than once.
+  if (ObjCSynthesizedProtocols.count(PDecl->getCanonicalDecl()))
+    return;
+  
+  if (ObjCProtocolDecl *Def = PDecl->getDefinition())
+    PDecl = Def;
+  
+  if (PDecl->instmeth_begin() != PDecl->instmeth_end()) {
+    unsigned NumMethods = std::distance(PDecl->instmeth_begin(),
+                                        PDecl->instmeth_end());
+    /* struct _objc_protocol_method_list {
+     int protocol_method_count;
+     struct protocol_methods protocols[];
+     }
+     */
+    Result += "\nstatic struct {\n";
+    Result += "\tint protocol_method_count;\n";
+    Result += "\tstruct _protocol_methods protocol_methods[";
+    Result += utostr(NumMethods);
+    Result += "];\n} _OBJC_PROTOCOL_INSTANCE_METHODS_";
+    Result += PDecl->getNameAsString();
+    Result += " __attribute__ ((used, section (\"__OBJC, __cat_inst_meth\")))= "
+    "{\n\t" + utostr(NumMethods) + "\n";
+    
+    // Output instance methods declared in this protocol.
+    for (ObjCProtocolDecl::instmeth_iterator
+         I = PDecl->instmeth_begin(), E = PDecl->instmeth_end();
+         I != E; ++I) {
+      if (I == PDecl->instmeth_begin())
+        Result += "\t  ,{{(struct objc_selector *)\"";
+      else
+        Result += "\t  ,{(struct objc_selector *)\"";
+      Result += (*I)->getSelector().getAsString();
+      std::string MethodTypeString;
+      Context->getObjCEncodingForMethodDecl((*I), MethodTypeString);
+      Result += "\", \"";
+      Result += MethodTypeString;
+      Result += "\"}\n";
+    }
+    Result += "\t }\n};\n";
+  }
+  
+  // Output class methods declared in this protocol.
+  unsigned NumMethods = std::distance(PDecl->classmeth_begin(),
+                                      PDecl->classmeth_end());
+  if (NumMethods > 0) {
+    /* struct _objc_protocol_method_list {
+     int protocol_method_count;
+     struct protocol_methods protocols[];
+     }
+     */
+    Result += "\nstatic struct {\n";
+    Result += "\tint protocol_method_count;\n";
+    Result += "\tstruct _protocol_methods protocol_methods[";
+    Result += utostr(NumMethods);
+    Result += "];\n} _OBJC_PROTOCOL_CLASS_METHODS_";
+    Result += PDecl->getNameAsString();
+    Result += " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= "
+    "{\n\t";
+    Result += utostr(NumMethods);
+    Result += "\n";
+    
+    // Output instance methods declared in this protocol.
+    for (ObjCProtocolDecl::classmeth_iterator
+         I = PDecl->classmeth_begin(), E = PDecl->classmeth_end();
+         I != E; ++I) {
+      if (I == PDecl->classmeth_begin())
+        Result += "\t  ,{{(struct objc_selector *)\"";
+      else
+        Result += "\t  ,{(struct objc_selector *)\"";
+      Result += (*I)->getSelector().getAsString();
+      std::string MethodTypeString;
+      Context->getObjCEncodingForMethodDecl((*I), MethodTypeString);
+      Result += "\", \"";
+      Result += MethodTypeString;
+      Result += "\"}\n";
+    }
+    Result += "\t }\n};\n";
+  }
+  
+  // Output:
+  /* struct _objc_protocol {
+   // Objective-C 1.0 extensions
+   struct _objc_protocol_extension *isa;
+   char *protocol_name;
+   struct _objc_protocol **protocol_list;
+   struct _objc_protocol_method_list *instance_methods;
+   struct _objc_protocol_method_list *class_methods;
+   };
+   */
+  static bool objc_protocol = false;
+  if (!objc_protocol) {
+    Result += "\nstruct _objc_protocol {\n";
+    Result += "\tstruct _objc_protocol_extension *isa;\n";
+    Result += "\tchar *protocol_name;\n";
+    Result += "\tstruct _objc_protocol **protocol_list;\n";
+    Result += "\tstruct _objc_protocol_method_list *instance_methods;\n";
+    Result += "\tstruct _objc_protocol_method_list *class_methods;\n";
+    Result += "};\n";
+    
+    objc_protocol = true;
+  }
+  
+  Result += "\nstatic struct _objc_protocol _OBJC_PROTOCOL_";
+  Result += PDecl->getNameAsString();
+  Result += " __attribute__ ((used, section (\"__OBJC, __protocol\")))= "
+  "{\n\t0, \"";
+  Result += PDecl->getNameAsString();
+  Result += "\", 0, ";
+  if (PDecl->instmeth_begin() != PDecl->instmeth_end()) {
+    Result += "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_INSTANCE_METHODS_";
+    Result += PDecl->getNameAsString();
+    Result += ", ";
+  }
+  else
+    Result += "0, ";
+  if (PDecl->classmeth_begin() != PDecl->classmeth_end()) {
+    Result += "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_CLASS_METHODS_";
+    Result += PDecl->getNameAsString();
+    Result += "\n";
+  }
+  else
+    Result += "0\n";
+  Result += "};\n";
+  
+  // Mark this protocol as having been generated.
+  if (!ObjCSynthesizedProtocols.insert(PDecl->getCanonicalDecl()))
+    llvm_unreachable("protocol already synthesized");
+  
+}
+
+void RewriteObjCFragileABI::RewriteObjCProtocolListMetaData(
+                                const ObjCList<ObjCProtocolDecl> &Protocols,
+                                StringRef prefix, StringRef ClassName,
+                                std::string &Result) {
+  if (Protocols.empty()) return;
+  
+  for (unsigned i = 0; i != Protocols.size(); i++)
+    RewriteObjCProtocolMetaData(Protocols[i], prefix, ClassName, Result);
+  
+  // Output the top lovel protocol meta-data for the class.
+  /* struct _objc_protocol_list {
+   struct _objc_protocol_list *next;
+   int    protocol_count;
+   struct _objc_protocol *class_protocols[];
+   }
+   */
+  Result += "\nstatic struct {\n";
+  Result += "\tstruct _objc_protocol_list *next;\n";
+  Result += "\tint    protocol_count;\n";
+  Result += "\tstruct _objc_protocol *class_protocols[";
+  Result += utostr(Protocols.size());
+  Result += "];\n} _OBJC_";
+  Result += prefix;
+  Result += "_PROTOCOLS_";
+  Result += ClassName;
+  Result += " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= "
+  "{\n\t0, ";
+  Result += utostr(Protocols.size());
+  Result += "\n";
+  
+  Result += "\t,{&_OBJC_PROTOCOL_";
+  Result += Protocols[0]->getNameAsString();
+  Result += " \n";
+  
+  for (unsigned i = 1; i != Protocols.size(); i++) {
+    Result += "\t ,&_OBJC_PROTOCOL_";
+    Result += Protocols[i]->getNameAsString();
+    Result += "\n";
+  }
+  Result += "\t }\n};\n";
+}
+
+void RewriteObjCFragileABI::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
+                                           std::string &Result) {
+  ObjCInterfaceDecl *CDecl = IDecl->getClassInterface();
+  
+  // Explicitly declared @interface's are already synthesized.
+  if (CDecl->isImplicitInterfaceDecl()) {
+    // FIXME: Implementation of a class with no @interface (legacy) does not
+    // produce correct synthesis as yet.
+    RewriteObjCInternalStruct(CDecl, Result);
+  }
+  
+  // Build _objc_ivar_list metadata for classes ivars if needed
+  unsigned NumIvars = !IDecl->ivar_empty()
+  ? IDecl->ivar_size()
+  : (CDecl ? CDecl->ivar_size() : 0);
+  if (NumIvars > 0) {
+    static bool objc_ivar = false;
+    if (!objc_ivar) {
+      /* struct _objc_ivar {
+       char *ivar_name;
+       char *ivar_type;
+       int ivar_offset;
+       };
+       */
+      Result += "\nstruct _objc_ivar {\n";
+      Result += "\tchar *ivar_name;\n";
+      Result += "\tchar *ivar_type;\n";
+      Result += "\tint ivar_offset;\n";
+      Result += "};\n";
+      
+      objc_ivar = true;
+    }
+    
+    /* struct {
+     int ivar_count;
+     struct _objc_ivar ivar_list[nIvars];
+     };
+     */
+    Result += "\nstatic struct {\n";
+    Result += "\tint ivar_count;\n";
+    Result += "\tstruct _objc_ivar ivar_list[";
+    Result += utostr(NumIvars);
+    Result += "];\n} _OBJC_INSTANCE_VARIABLES_";
+    Result += IDecl->getNameAsString();
+    Result += " __attribute__ ((used, section (\"__OBJC, __instance_vars\")))= "
+    "{\n\t";
+    Result += utostr(NumIvars);
+    Result += "\n";
+    
+    ObjCInterfaceDecl::ivar_iterator IVI, IVE;
+    SmallVector<ObjCIvarDecl *, 8> IVars;
+    if (!IDecl->ivar_empty()) {
+      for (auto *IV : IDecl->ivars())
+        IVars.push_back(IV);
+      IVI = IDecl->ivar_begin();
+      IVE = IDecl->ivar_end();
+    } else {
+      IVI = CDecl->ivar_begin();
+      IVE = CDecl->ivar_end();
+    }
+    Result += "\t,{{\"";
+    Result += IVI->getNameAsString();
+    Result += "\", \"";
+    std::string TmpString, StrEncoding;
+    Context->getObjCEncodingForType(IVI->getType(), TmpString, *IVI);
+    QuoteDoublequotes(TmpString, StrEncoding);
+    Result += StrEncoding;
+    Result += "\", ";
+    RewriteIvarOffsetComputation(*IVI, Result);
+    Result += "}\n";
+    for (++IVI; IVI != IVE; ++IVI) {
+      Result += "\t  ,{\"";
+      Result += IVI->getNameAsString();
+      Result += "\", \"";
+      std::string TmpString, StrEncoding;
+      Context->getObjCEncodingForType(IVI->getType(), TmpString, *IVI);
+      QuoteDoublequotes(TmpString, StrEncoding);
+      Result += StrEncoding;
+      Result += "\", ";
+      RewriteIvarOffsetComputation(*IVI, Result);
+      Result += "}\n";
+    }
+    
+    Result += "\t }\n};\n";
+  }
+  
+  // Build _objc_method_list for class's instance methods if needed
+  SmallVector<ObjCMethodDecl *, 32> InstanceMethods(IDecl->instance_methods());
+  
+  // If any of our property implementations have associated getters or
+  // setters, produce metadata for them as well.
+  for (const auto *Prop : IDecl->property_impls()) {
+    if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
+      continue;
+    if (!Prop->getPropertyIvarDecl())
+      continue;
+    ObjCPropertyDecl *PD = Prop->getPropertyDecl();
+    if (!PD)
+      continue;
+    if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl())
+      if (!Getter->isDefined())
+        InstanceMethods.push_back(Getter);
+    if (PD->isReadOnly())
+      continue;
+    if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl())
+      if (!Setter->isDefined())
+        InstanceMethods.push_back(Setter);
+  }
+  RewriteObjCMethodsMetaData(InstanceMethods.begin(), InstanceMethods.end(),
+                             true, "", IDecl->getName(), Result);
+  
+  // Build _objc_method_list for class's class methods if needed
+  RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(),
+                             false, "", IDecl->getName(), Result);
+  
+  // Protocols referenced in class declaration?
+  RewriteObjCProtocolListMetaData(CDecl->getReferencedProtocols(),
+                                  "CLASS", CDecl->getName(), Result);
+  
+  // Declaration of class/meta-class metadata
+  /* struct _objc_class {
+   struct _objc_class *isa; // or const char *root_class_name when metadata
+   const char *super_class_name;
+   char *name;
+   long version;
+   long info;
+   long instance_size;
+   struct _objc_ivar_list *ivars;
+   struct _objc_method_list *methods;
+   struct objc_cache *cache;
+   struct objc_protocol_list *protocols;
+   const char *ivar_layout;
+   struct _objc_class_ext  *ext;
+   };
+   */
+  static bool objc_class = false;
+  if (!objc_class) {
+    Result += "\nstruct _objc_class {\n";
+    Result += "\tstruct _objc_class *isa;\n";
+    Result += "\tconst char *super_class_name;\n";
+    Result += "\tchar *name;\n";
+    Result += "\tlong version;\n";
+    Result += "\tlong info;\n";
+    Result += "\tlong instance_size;\n";
+    Result += "\tstruct _objc_ivar_list *ivars;\n";
+    Result += "\tstruct _objc_method_list *methods;\n";
+    Result += "\tstruct objc_cache *cache;\n";
+    Result += "\tstruct _objc_protocol_list *protocols;\n";
+    Result += "\tconst char *ivar_layout;\n";
+    Result += "\tstruct _objc_class_ext  *ext;\n";
+    Result += "};\n";
+    objc_class = true;
+  }
+  
+  // Meta-class metadata generation.
+  ObjCInterfaceDecl *RootClass = nullptr;
+  ObjCInterfaceDecl *SuperClass = CDecl->getSuperClass();
+  while (SuperClass) {
+    RootClass = SuperClass;
+    SuperClass = SuperClass->getSuperClass();
+  }
+  SuperClass = CDecl->getSuperClass();
+  
+  Result += "\nstatic struct _objc_class _OBJC_METACLASS_";
+  Result += CDecl->getNameAsString();
+  Result += " __attribute__ ((used, section (\"__OBJC, __meta_class\")))= "
+  "{\n\t(struct _objc_class *)\"";
+  Result += (RootClass ? RootClass->getNameAsString() : CDecl->getNameAsString());
+  Result += "\"";
+  
+  if (SuperClass) {
+    Result += ", \"";
+    Result += SuperClass->getNameAsString();
+    Result += "\", \"";
+    Result += CDecl->getNameAsString();
+    Result += "\"";
+  }
+  else {
+    Result += ", 0, \"";
+    Result += CDecl->getNameAsString();
+    Result += "\"";
+  }
+  // Set 'ivars' field for root class to 0. ObjC1 runtime does not use it.
+  // 'info' field is initialized to CLS_META(2) for metaclass
+  Result += ", 0,2, sizeof(struct _objc_class), 0";
+  if (IDecl->classmeth_begin() != IDecl->classmeth_end()) {
+    Result += "\n\t, (struct _objc_method_list *)&_OBJC_CLASS_METHODS_";
+    Result += IDecl->getNameAsString();
+    Result += "\n";
+  }
+  else
+    Result += ", 0\n";
+  if (CDecl->protocol_begin() != CDecl->protocol_end()) {
+    Result += "\t,0, (struct _objc_protocol_list *)&_OBJC_CLASS_PROTOCOLS_";
+    Result += CDecl->getNameAsString();
+    Result += ",0,0\n";
+  }
+  else
+    Result += "\t,0,0,0,0\n";
+  Result += "};\n";
+  
+  // class metadata generation.
+  Result += "\nstatic struct _objc_class _OBJC_CLASS_";
+  Result += CDecl->getNameAsString();
+  Result += " __attribute__ ((used, section (\"__OBJC, __class\")))= "
+  "{\n\t&_OBJC_METACLASS_";
+  Result += CDecl->getNameAsString();
+  if (SuperClass) {
+    Result += ", \"";
+    Result += SuperClass->getNameAsString();
+    Result += "\", \"";
+    Result += CDecl->getNameAsString();
+    Result += "\"";
+  }
+  else {
+    Result += ", 0, \"";
+    Result += CDecl->getNameAsString();
+    Result += "\"";
+  }
+  // 'info' field is initialized to CLS_CLASS(1) for class
+  Result += ", 0,1";
+  if (!ObjCSynthesizedStructs.count(CDecl))
+    Result += ",0";
+  else {
+    // class has size. Must synthesize its size.
+    Result += ",sizeof(struct ";
+    Result += CDecl->getNameAsString();
+    if (LangOpts.MicrosoftExt)
+      Result += "_IMPL";
+    Result += ")";
+  }
+  if (NumIvars > 0) {
+    Result += ", (struct _objc_ivar_list *)&_OBJC_INSTANCE_VARIABLES_";
+    Result += CDecl->getNameAsString();
+    Result += "\n\t";
+  }
+  else
+    Result += ",0";
+  if (IDecl->instmeth_begin() != IDecl->instmeth_end()) {
+    Result += ", (struct _objc_method_list *)&_OBJC_INSTANCE_METHODS_";
+    Result += CDecl->getNameAsString();
+    Result += ", 0\n\t";
+  }
+  else
+    Result += ",0,0";
+  if (CDecl->protocol_begin() != CDecl->protocol_end()) {
+    Result += ", (struct _objc_protocol_list*)&_OBJC_CLASS_PROTOCOLS_";
+    Result += CDecl->getNameAsString();
+    Result += ", 0,0\n";
+  }
+  else
+    Result += ",0,0,0\n";
+  Result += "};\n";
+}
+
+void RewriteObjCFragileABI::RewriteMetaDataIntoBuffer(std::string &Result) {
+  int ClsDefCount = ClassImplementation.size();
+  int CatDefCount = CategoryImplementation.size();
+  
+  // For each implemented class, write out all its meta data.
+  for (int i = 0; i < ClsDefCount; i++)
+    RewriteObjCClassMetaData(ClassImplementation[i], Result);
+  
+  // For each implemented category, write out all its meta data.
+  for (int i = 0; i < CatDefCount; i++)
+    RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result);
+  
+  // Write objc_symtab metadata
+  /*
+   struct _objc_symtab
+   {
+   long sel_ref_cnt;
+   SEL *refs;
+   short cls_def_cnt;
+   short cat_def_cnt;
+   void *defs[cls_def_cnt + cat_def_cnt];
+   };
+   */
+  
+  Result += "\nstruct _objc_symtab {\n";
+  Result += "\tlong sel_ref_cnt;\n";
+  Result += "\tSEL *refs;\n";
+  Result += "\tshort cls_def_cnt;\n";
+  Result += "\tshort cat_def_cnt;\n";
+  Result += "\tvoid *defs[" + utostr(ClsDefCount + CatDefCount)+ "];\n";
+  Result += "};\n\n";
+  
+  Result += "static struct _objc_symtab "
+  "_OBJC_SYMBOLS __attribute__((used, section (\"__OBJC, __symbols\")))= {\n";
+  Result += "\t0, 0, " + utostr(ClsDefCount)
+  + ", " + utostr(CatDefCount) + "\n";
+  for (int i = 0; i < ClsDefCount; i++) {
+    Result += "\t,&_OBJC_CLASS_";
+    Result += ClassImplementation[i]->getNameAsString();
+    Result += "\n";
+  }
+  
+  for (int i = 0; i < CatDefCount; i++) {
+    Result += "\t,&_OBJC_CATEGORY_";
+    Result += CategoryImplementation[i]->getClassInterface()->getNameAsString();
+    Result += "_";
+    Result += CategoryImplementation[i]->getNameAsString();
+    Result += "\n";
+  }
+  
+  Result += "};\n\n";
+  
+  // Write objc_module metadata
+  
+  /*
+   struct _objc_module {
+   long version;
+   long size;
+   const char *name;
+   struct _objc_symtab *symtab;
+   }
+   */
+  
+  Result += "\nstruct _objc_module {\n";
+  Result += "\tlong version;\n";
+  Result += "\tlong size;\n";
+  Result += "\tconst char *name;\n";
+  Result += "\tstruct _objc_symtab *symtab;\n";
+  Result += "};\n\n";
+  Result += "static struct _objc_module "
+  "_OBJC_MODULES __attribute__ ((used, section (\"__OBJC, __module_info\")))= {\n";
+  Result += "\t" + utostr(OBJC_ABI_VERSION) +
+  ", sizeof(struct _objc_module), \"\", &_OBJC_SYMBOLS\n";
+  Result += "};\n\n";
+  
+  if (LangOpts.MicrosoftExt) {
+    if (ProtocolExprDecls.size()) {
+      Result += "#pragma section(\".objc_protocol$B\",long,read,write)\n";
+      Result += "#pragma data_seg(push, \".objc_protocol$B\")\n";
+      for (llvm::SmallPtrSet<ObjCProtocolDecl *,8>::iterator I = ProtocolExprDecls.begin(),
+           E = ProtocolExprDecls.end(); I != E; ++I) {
+        Result += "static struct _objc_protocol *_POINTER_OBJC_PROTOCOL_";
+        Result += (*I)->getNameAsString();
+        Result += " = &_OBJC_PROTOCOL_";
+        Result += (*I)->getNameAsString();
+        Result += ";\n";
+      }
+      Result += "#pragma data_seg(pop)\n\n";
+    }
+    Result += "#pragma section(\".objc_module_info$B\",long,read,write)\n";
+    Result += "#pragma data_seg(push, \".objc_module_info$B\")\n";
+    Result += "static struct _objc_module *_POINTER_OBJC_MODULES = ";
+    Result += "&_OBJC_MODULES;\n";
+    Result += "#pragma data_seg(pop)\n\n";
+  }
+}
+
+/// RewriteObjCCategoryImplDecl - Rewrite metadata for each category
+/// implementation.
+void RewriteObjCFragileABI::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl,
+                                              std::string &Result) {
+  ObjCInterfaceDecl *ClassDecl = IDecl->getClassInterface();
+  // Find category declaration for this implementation.
+  ObjCCategoryDecl *CDecl
+    = ClassDecl->FindCategoryDeclaration(IDecl->getIdentifier());
+  
+  std::string FullCategoryName = ClassDecl->getNameAsString();
+  FullCategoryName += '_';
+  FullCategoryName += IDecl->getNameAsString();
+  
+  // Build _objc_method_list for class's instance methods if needed
+  SmallVector<ObjCMethodDecl *, 32> InstanceMethods(IDecl->instance_methods());
+  
+  // If any of our property implementations have associated getters or
+  // setters, produce metadata for them as well.
+  for (const auto *Prop : IDecl->property_impls()) {
+    if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
+      continue;
+    if (!Prop->getPropertyIvarDecl())
+      continue;
+    ObjCPropertyDecl *PD = Prop->getPropertyDecl();
+    if (!PD)
+      continue;
+    if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl())
+      InstanceMethods.push_back(Getter);
+    if (PD->isReadOnly())
+      continue;
+    if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl())
+      InstanceMethods.push_back(Setter);
+  }
+  RewriteObjCMethodsMetaData(InstanceMethods.begin(), InstanceMethods.end(),
+                             true, "CATEGORY_", FullCategoryName.c_str(),
+                             Result);
+  
+  // Build _objc_method_list for class's class methods if needed
+  RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(),
+                             false, "CATEGORY_", FullCategoryName.c_str(),
+                             Result);
+  
+  // Protocols referenced in class declaration?
+  // Null CDecl is case of a category implementation with no category interface
+  if (CDecl)
+    RewriteObjCProtocolListMetaData(CDecl->getReferencedProtocols(), "CATEGORY",
+                                    FullCategoryName, Result);
+  /* struct _objc_category {
+   char *category_name;
+   char *class_name;
+   struct _objc_method_list *instance_methods;
+   struct _objc_method_list *class_methods;
+   struct _objc_protocol_list *protocols;
+   // Objective-C 1.0 extensions
+   uint32_t size;     // sizeof (struct _objc_category)
+   struct _objc_property_list *instance_properties;  // category's own
+   // @property decl.
+   };
+   */
+  
+  static bool objc_category = false;
+  if (!objc_category) {
+    Result += "\nstruct _objc_category {\n";
+    Result += "\tchar *category_name;\n";
+    Result += "\tchar *class_name;\n";
+    Result += "\tstruct _objc_method_list *instance_methods;\n";
+    Result += "\tstruct _objc_method_list *class_methods;\n";
+    Result += "\tstruct _objc_protocol_list *protocols;\n";
+    Result += "\tunsigned int size;\n";
+    Result += "\tstruct _objc_property_list *instance_properties;\n";
+    Result += "};\n";
+    objc_category = true;
+  }
+  Result += "\nstatic struct _objc_category _OBJC_CATEGORY_";
+  Result += FullCategoryName;
+  Result += " __attribute__ ((used, section (\"__OBJC, __category\")))= {\n\t\"";
+  Result += IDecl->getNameAsString();
+  Result += "\"\n\t, \"";
+  Result += ClassDecl->getNameAsString();
+  Result += "\"\n";
+  
+  if (IDecl->instmeth_begin() != IDecl->instmeth_end()) {
+    Result += "\t, (struct _objc_method_list *)"
+    "&_OBJC_CATEGORY_INSTANCE_METHODS_";
+    Result += FullCategoryName;
+    Result += "\n";
+  }
+  else
+    Result += "\t, 0\n";
+  if (IDecl->classmeth_begin() != IDecl->classmeth_end()) {
+    Result += "\t, (struct _objc_method_list *)"
+    "&_OBJC_CATEGORY_CLASS_METHODS_";
+    Result += FullCategoryName;
+    Result += "\n";
+  }
+  else
+    Result += "\t, 0\n";
+  
+  if (CDecl && CDecl->protocol_begin() != CDecl->protocol_end()) {
+    Result += "\t, (struct _objc_protocol_list *)&_OBJC_CATEGORY_PROTOCOLS_";
+    Result += FullCategoryName;
+    Result += "\n";
+  }
+  else
+    Result += "\t, 0\n";
+  Result += "\t, sizeof(struct _objc_category), 0\n};\n";
+}
+
+// RewriteObjCMethodsMetaData - Rewrite methods metadata for instance or
+/// class methods.
+template<typename MethodIterator>
+void RewriteObjCFragileABI::RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
+                                             MethodIterator MethodEnd,
+                                             bool IsInstanceMethod,
+                                             StringRef prefix,
+                                             StringRef ClassName,
+                                             std::string &Result) {
+  if (MethodBegin == MethodEnd) return;
+  
+  if (!objc_impl_method) {
+    /* struct _objc_method {
+     SEL _cmd;
+     char *method_types;
+     void *_imp;
+     }
+     */
+    Result += "\nstruct _objc_method {\n";
+    Result += "\tSEL _cmd;\n";
+    Result += "\tchar *method_types;\n";
+    Result += "\tvoid *_imp;\n";
+    Result += "};\n";
+    
+    objc_impl_method = true;
+  }
+  
+  // Build _objc_method_list for class's methods if needed
+  
+  /* struct  {
+   struct _objc_method_list *next_method;
+   int method_count;
+   struct _objc_method method_list[];
+   }
+   */
+  unsigned NumMethods = std::distance(MethodBegin, MethodEnd);
+  Result += "\nstatic struct {\n";
+  Result += "\tstruct _objc_method_list *next_method;\n";
+  Result += "\tint method_count;\n";
+  Result += "\tstruct _objc_method method_list[";
+  Result += utostr(NumMethods);
+  Result += "];\n} _OBJC_";
+  Result += prefix;
+  Result += IsInstanceMethod ? "INSTANCE" : "CLASS";
+  Result += "_METHODS_";
+  Result += ClassName;
+  Result += " __attribute__ ((used, section (\"__OBJC, __";
+  Result += IsInstanceMethod ? "inst" : "cls";
+  Result += "_meth\")))= ";
+  Result += "{\n\t0, " + utostr(NumMethods) + "\n";
+  
+  Result += "\t,{{(SEL)\"";
+  Result += (*MethodBegin)->getSelector().getAsString().c_str();
+  std::string MethodTypeString;
+  Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString);
+  Result += "\", \"";
+  Result += MethodTypeString;
+  Result += "\", (void *)";
+  Result += MethodInternalNames[*MethodBegin];
+  Result += "}\n";
+  for (++MethodBegin; MethodBegin != MethodEnd; ++MethodBegin) {
+    Result += "\t  ,{(SEL)\"";
+    Result += (*MethodBegin)->getSelector().getAsString().c_str();
+    std::string MethodTypeString;
+    Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString);
+    Result += "\", \"";
+    Result += MethodTypeString;
+    Result += "\", (void *)";
+    Result += MethodInternalNames[*MethodBegin];
+    Result += "}\n";
+  }
+  Result += "\t }\n};\n";
+}
+
+Stmt *RewriteObjCFragileABI::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) {
+  SourceRange OldRange = IV->getSourceRange();
+  Expr *BaseExpr = IV->getBase();
+  
+  // Rewrite the base, but without actually doing replaces.
+  {
+    DisableReplaceStmtScope S(*this);
+    BaseExpr = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(BaseExpr));
+    IV->setBase(BaseExpr);
+  }
+  
+  ObjCIvarDecl *D = IV->getDecl();
+  
+  Expr *Replacement = IV;
+  if (CurMethodDef) {
+    if (BaseExpr->getType()->isObjCObjectPointerType()) {
+      const ObjCInterfaceType *iFaceDecl =
+      dyn_cast<ObjCInterfaceType>(BaseExpr->getType()->getPointeeType());
+      assert(iFaceDecl && "RewriteObjCIvarRefExpr - iFaceDecl is null");
+      // lookup which class implements the instance variable.
+      ObjCInterfaceDecl *clsDeclared = nullptr;
+      iFaceDecl->getDecl()->lookupInstanceVariable(D->getIdentifier(),
+                                                   clsDeclared);
+      assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class");
+      
+      // Synthesize an explicit cast to gain access to the ivar.
+      std::string RecName = clsDeclared->getIdentifier()->getName();
+      RecName += "_IMPL";
+      IdentifierInfo *II = &Context->Idents.get(RecName);
+      RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
+                                          SourceLocation(), SourceLocation(),
+                                          II);
+      assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl");
+      QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
+      CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, castT,
+                                                    CK_BitCast,
+                                                    IV->getBase());
+      // Don't forget the parens to enforce the proper binding.
+      ParenExpr *PE = new (Context) ParenExpr(OldRange.getBegin(),
+                                              OldRange.getEnd(),
+                                              castExpr);
+      if (IV->isFreeIvar() &&
+          declaresSameEntity(CurMethodDef->getClassInterface(), iFaceDecl->getDecl())) {
+        MemberExpr *ME = new (Context) MemberExpr(PE, true, D,
+                                                  IV->getLocation(),
+                                                  D->getType(),
+                                                  VK_LValue, OK_Ordinary);
+        Replacement = ME;
+      } else {
+        IV->setBase(PE);
+      }
+    }
+  } else { // we are outside a method.
+    assert(!IV->isFreeIvar() && "Cannot have a free standing ivar outside a method");
+    
+    // Explicit ivar refs need to have a cast inserted.
+    // FIXME: consider sharing some of this code with the code above.
+    if (BaseExpr->getType()->isObjCObjectPointerType()) {
+      const ObjCInterfaceType *iFaceDecl =
+      dyn_cast<ObjCInterfaceType>(BaseExpr->getType()->getPointeeType());
+      // lookup which class implements the instance variable.
+      ObjCInterfaceDecl *clsDeclared = nullptr;
+      iFaceDecl->getDecl()->lookupInstanceVariable(D->getIdentifier(),
+                                                   clsDeclared);
+      assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class");
+      
+      // Synthesize an explicit cast to gain access to the ivar.
+      std::string RecName = clsDeclared->getIdentifier()->getName();
+      RecName += "_IMPL";
+      IdentifierInfo *II = &Context->Idents.get(RecName);
+      RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
+                                          SourceLocation(), SourceLocation(),
+                                          II);
+      assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl");
+      QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
+      CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, castT,
+                                                    CK_BitCast,
+                                                    IV->getBase());
+      // Don't forget the parens to enforce the proper binding.
+      ParenExpr *PE = new (Context) ParenExpr(IV->getBase()->getLocStart(),
+                                              IV->getBase()->getLocEnd(), castExpr);
+      // Cannot delete IV->getBase(), since PE points to it.
+      // Replace the old base with the cast. This is important when doing
+      // embedded rewrites. For example, [newInv->_container addObject:0].
+      IV->setBase(PE);
+    }
+  }
+  
+  ReplaceStmtWithRange(IV, Replacement, OldRange);
+  return Replacement;  
+}
+
+#endif
diff --git a/lib/Rewrite/Frontend/RewriteTest.cpp b/lib/Frontend/Rewrite/RewriteTest.cpp
similarity index 100%
rename from lib/Rewrite/Frontend/RewriteTest.cpp
rename to lib/Frontend/Rewrite/RewriteTest.cpp
diff --git a/lib/Frontend/SerializedDiagnosticPrinter.cpp b/lib/Frontend/SerializedDiagnosticPrinter.cpp
index 6514321..29c58a8 100644
--- a/lib/Frontend/SerializedDiagnosticPrinter.cpp
+++ b/lib/Frontend/SerializedDiagnosticPrinter.cpp
@@ -59,32 +59,32 @@
   virtual ~SDiagsRenderer() {}
   
 protected:
-  virtual void emitDiagnosticMessage(SourceLocation Loc,
-                                     PresumedLoc PLoc,
-                                     DiagnosticsEngine::Level Level,
-                                     StringRef Message,
-                                     ArrayRef<CharSourceRange> Ranges,
-                                     const SourceManager *SM,
-                                     DiagOrStoredDiag D);
-  
-  virtual void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
-                                 DiagnosticsEngine::Level Level,
-                                 ArrayRef<CharSourceRange> Ranges,
-                                 const SourceManager &SM) {}
+  void emitDiagnosticMessage(SourceLocation Loc,
+                             PresumedLoc PLoc,
+                             DiagnosticsEngine::Level Level,
+                             StringRef Message,
+                             ArrayRef<CharSourceRange> Ranges,
+                             const SourceManager *SM,
+                             DiagOrStoredDiag D) override;
 
-  virtual void emitNote(SourceLocation Loc, StringRef Message,
-                        const SourceManager *SM);
+  void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
+                         DiagnosticsEngine::Level Level,
+                         ArrayRef<CharSourceRange> Ranges,
+                         const SourceManager &SM) override {}
 
-  virtual void emitCodeContext(SourceLocation Loc,
-                               DiagnosticsEngine::Level Level,
-                               SmallVectorImpl<CharSourceRange>& Ranges,
-                               ArrayRef<FixItHint> Hints,
-                               const SourceManager &SM);
+  void emitNote(SourceLocation Loc, StringRef Message,
+                const SourceManager *SM) override;
 
-  virtual void beginDiagnostic(DiagOrStoredDiag D,
-                               DiagnosticsEngine::Level Level);
-  virtual void endDiagnostic(DiagOrStoredDiag D,
-                             DiagnosticsEngine::Level Level);
+  void emitCodeContext(SourceLocation Loc,
+                       DiagnosticsEngine::Level Level,
+                       SmallVectorImpl<CharSourceRange>& Ranges,
+                       ArrayRef<FixItHint> Hints,
+                       const SourceManager &SM) override;
+
+  void beginDiagnostic(DiagOrStoredDiag D,
+                       DiagnosticsEngine::Level Level) override;
+  void endDiagnostic(DiagOrStoredDiag D,
+                     DiagnosticsEngine::Level Level) override;
 };
   
 class SDiagsWriter : public DiagnosticConsumer {
@@ -93,26 +93,26 @@
   struct SharedState;
 
   explicit SDiagsWriter(IntrusiveRefCntPtr<SharedState> State)
-    : LangOpts(0), OriginalInstance(false), State(State) { }
+    : LangOpts(nullptr), OriginalInstance(false), State(State) {}
 
 public:
   SDiagsWriter(raw_ostream *os, DiagnosticOptions *diags)
-    : LangOpts(0), OriginalInstance(true), State(new SharedState(os, diags))
+    : LangOpts(nullptr), OriginalInstance(true),
+      State(new SharedState(os, diags))
   {
     EmitPreamble();
   }
 
   ~SDiagsWriter() {}
-  
+
   void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
-                        const Diagnostic &Info);
-  
-  void BeginSourceFile(const LangOptions &LO,
-                       const Preprocessor *PP) {
+                        const Diagnostic &Info) override;
+
+  void BeginSourceFile(const LangOptions &LO, const Preprocessor *PP) override {
     LangOpts = &LO;
   }
 
-  virtual void finish();
+  void finish() override;
 
 private:
   /// \brief Emit the preamble for the serialized diagnostics.
@@ -174,7 +174,7 @@
                                   const SourceManager &SM);
 
   /// \brief The version of the diagnostics file.
-  enum { Version = 1 };
+  enum { Version = 2 };
 
   /// \brief Language options, which can differ from one clone of this client
   /// to another.
@@ -200,7 +200,7 @@
     llvm::BitstreamWriter Stream;
 
     /// \brief The name of the diagnostics file.
-    OwningPtr<raw_ostream> OS;
+    std::unique_ptr<raw_ostream> OS;
 
     /// \brief The set of constructed record abbreviations.
     AbbreviationMap Abbrevs;
@@ -255,7 +255,7 @@
   Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETBID, Record);
   
   // Emit the block name if present.
-  if (Name == 0 || Name[0] == 0)
+  if (!Name || Name[0] == 0)
     return;
 
   Record.clear();
@@ -546,7 +546,7 @@
       EnterDiagBlock();
 
     EmitDiagnosticMessage(SourceLocation(), PresumedLoc(), DiagLevel,
-                          State->diagBuf, 0, &Info);
+                          State->diagBuf, nullptr, &Info);
 
     if (DiagLevel == DiagnosticsEngine::Note)
       ExitDiagBlock();
@@ -560,12 +560,26 @@
   Renderer.emitDiagnostic(Info.getLocation(), DiagLevel,
                           State->diagBuf.str(),
                           Info.getRanges(),
-                          llvm::makeArrayRef(Info.getFixItHints(),
-                                             Info.getNumFixItHints()),
+                          Info.getFixItHints(),
                           &Info.getSourceManager(),
                           &Info);
 }
 
+static serialized_diags::Level getStableLevel(DiagnosticsEngine::Level Level) {
+  switch (Level) {
+#define CASE(X) case DiagnosticsEngine::X: return serialized_diags::X;
+  CASE(Ignored)
+  CASE(Note)
+  CASE(Remark)
+  CASE(Warning)
+  CASE(Error)
+  CASE(Fatal)
+#undef CASE
+  }
+
+  llvm_unreachable("invalid diagnostic level");
+}
+
 void SDiagsWriter::EmitDiagnosticMessage(SourceLocation Loc,
                                          PresumedLoc PLoc,
                                          DiagnosticsEngine::Level Level,
@@ -579,7 +593,7 @@
   // Emit the RECORD_DIAG record.
   Record.clear();
   Record.push_back(RECORD_DIAG);
-  Record.push_back(Level);
+  Record.push_back(getStableLevel(Level));
   AddLocToRecord(Loc, SM, PLoc, Record);
 
   if (const Diagnostic *Info = D.dyn_cast<const Diagnostic*>()) {
@@ -688,5 +702,5 @@
   State->OS->write((char *)&State->Buffer.front(), State->Buffer.size());
   State->OS->flush();
 
-  State->OS.reset(0);
+  State->OS.reset();
 }
diff --git a/lib/Frontend/TextDiagnostic.cpp b/lib/Frontend/TextDiagnostic.cpp
index a2dc953..6e6f3dd 100644
--- a/lib/Frontend/TextDiagnostic.cpp
+++ b/lib/Frontend/TextDiagnostic.cpp
@@ -26,6 +26,8 @@
 
 static const enum raw_ostream::Colors noteColor =
   raw_ostream::BLACK;
+static const enum raw_ostream::Colors remarkColor =
+  raw_ostream::BLUE;
 static const enum raw_ostream::Colors fixitColor =
   raw_ostream::GREEN;
 static const enum raw_ostream::Colors caretColor =
@@ -312,14 +314,6 @@
   SmallVector<int,200> m_byteToColumn;
   SmallVector<int,200> m_columnToByte;
 };
-
-// used in assert in selectInterestingSourceRegion()
-struct char_out_of_range {
-  const char lower,upper;
-  char_out_of_range(char lower, char upper) :
-    lower(lower), upper(upper) {}
-  bool operator()(char c) { return c < lower || upper < c; }
-};
 } // end anonymous namespace
 
 /// \brief When the source code line we want to print is too long for
@@ -339,7 +333,7 @@
   // No special characters are allowed in CaretLine.
   assert(CaretLine.end() ==
          std::find_if(CaretLine.begin(), CaretLine.end(),
-         char_out_of_range(' ','~')));
+                      [](char c) { return c < ' ' || '~' < c; }));
 
   // Find the slice that we need to display the full caret line
   // correctly.
@@ -695,8 +689,9 @@
   
   printDiagnosticLevel(OS, Level, DiagOpts->ShowColors,
                        DiagOpts->CLFallbackMode);
-  printDiagnosticMessage(OS, Level, Message,
-                         OS.tell() - StartOfLocationInfo,
+  printDiagnosticMessage(OS,
+                         /*IsSupplemental*/ Level == DiagnosticsEngine::Note,
+                         Message, OS.tell() - StartOfLocationInfo,
                          DiagOpts->MessageLength, DiagOpts->ShowColors);
 }
 
@@ -711,6 +706,7 @@
     case DiagnosticsEngine::Ignored:
       llvm_unreachable("Invalid diagnostic type");
     case DiagnosticsEngine::Note:    OS.changeColor(noteColor, true); break;
+    case DiagnosticsEngine::Remark:  OS.changeColor(remarkColor, true); break;
     case DiagnosticsEngine::Warning: OS.changeColor(warningColor, true); break;
     case DiagnosticsEngine::Error:   OS.changeColor(errorColor, true); break;
     case DiagnosticsEngine::Fatal:   OS.changeColor(fatalColor, true); break;
@@ -721,6 +717,7 @@
   case DiagnosticsEngine::Ignored:
     llvm_unreachable("Invalid diagnostic type");
   case DiagnosticsEngine::Note:    OS << "note"; break;
+  case DiagnosticsEngine::Remark:  OS << "remark"; break;
   case DiagnosticsEngine::Warning: OS << "warning"; break;
   case DiagnosticsEngine::Error:   OS << "error"; break;
   case DiagnosticsEngine::Fatal:   OS << "fatal error"; break;
@@ -739,24 +736,18 @@
     OS.resetColor();
 }
 
-/*static*/ void
-TextDiagnostic::printDiagnosticMessage(raw_ostream &OS,
-                                       DiagnosticsEngine::Level Level,
-                                       StringRef Message,
-                                       unsigned CurrentColumn, unsigned Columns,
-                                       bool ShowColors) {
+/*static*/
+void TextDiagnostic::printDiagnosticMessage(raw_ostream &OS,
+                                            bool IsSupplemental,
+                                            StringRef Message,
+                                            unsigned CurrentColumn,
+                                            unsigned Columns, bool ShowColors) {
   bool Bold = false;
-  if (ShowColors) {
-    // Print warnings, errors and fatal errors in bold, no color
-    switch (Level) {
-    case DiagnosticsEngine::Warning:
-    case DiagnosticsEngine::Error:
-    case DiagnosticsEngine::Fatal:
-      OS.changeColor(savedColor, true);
-      Bold = true;
-      break;
-    default: break; //don't bold notes
-    }
+  if (ShowColors && !IsSupplemental) {
+    // Print primary diagnostic messages in bold and without color, to visually
+    // indicate the transition from continuation notes and other output.
+    OS.changeColor(savedColor, true);
+    Bold = true;
   }
 
   if (Columns)
@@ -787,7 +778,7 @@
     FileID FID = SM.getFileID(Loc);
     if (!FID.isInvalid()) {
       const FileEntry* FE = SM.getFileEntryForID(FID);
-      if (FE && FE->getName()) {
+      if (FE && FE->isValid()) {
         OS << FE->getName();
         if (FE->isInPCH())
           OS << " (in PCH)";
@@ -816,7 +807,10 @@
     if (unsigned ColNo = PLoc.getColumn()) {
       if (DiagOpts->getFormat() == DiagnosticOptions::Msvc) {
         OS << ',';
-        ColNo--;
+        // Visual Studio 2010 or earlier expects column number to be off by one
+        if (LangOpts.MSCompatibilityVersion &&
+            LangOpts.MSCompatibilityVersion < 170000000)
+          ColNo--;
       } else
         OS << ':';
       OS << ColNo;
@@ -877,12 +871,6 @@
   OS << ' ';
 }
 
-void TextDiagnostic::emitBasicNote(StringRef Message) {
-  // FIXME: Emit this as a real note diagnostic.
-  // FIXME: Format an actual diagnostic rather than a hard coded string.
-  OS << "note: " << Message << "\n";
-}
-
 void TextDiagnostic::emitIncludeLocation(SourceLocation Loc,
                                          PresumedLoc PLoc,
                                          const SourceManager &SM) {
@@ -1143,7 +1131,7 @@
   std::string FixItInsertionLine = buildFixItInsertionLine(LineNo,
                                                            sourceColMap,
                                                            Hints, SM,
-                                                           DiagOpts.getPtr());
+                                                           DiagOpts.get());
 
   // If the source line is too long for our terminal, select only the
   // "interesting" source region within that line.
diff --git a/lib/Frontend/TextDiagnosticBuffer.cpp b/lib/Frontend/TextDiagnosticBuffer.cpp
index 5821436..9c6bebb 100644
--- a/lib/Frontend/TextDiagnosticBuffer.cpp
+++ b/lib/Frontend/TextDiagnosticBuffer.cpp
@@ -35,6 +35,9 @@
   case DiagnosticsEngine::Warning:
     Warnings.push_back(std::make_pair(Info.getLocation(), Buf.str()));
     break;
+  case DiagnosticsEngine::Remark:
+    Remarks.push_back(std::make_pair(Info.getLocation(), Buf.str()));
+    break;
   case DiagnosticsEngine::Error:
   case DiagnosticsEngine::Fatal:
     Errors.push_back(std::make_pair(Info.getLocation(), Buf.str()));
@@ -42,36 +45,19 @@
   }
 }
 
-/// \brief Escape diagnostic texts to avoid problems when they are fed into the
-/// diagnostic formatter a second time.
-static StringRef escapeDiag(StringRef Str, SmallVectorImpl<char> &Buf) {
-  size_t Pos = Str.find('%');
-  if (Pos == StringRef::npos)
-    return Str;
-
-  // We found a '%'. Replace this and all following '%' with '%%'.
-  Buf.clear();
-  Buf.append(Str.data(), Str.data() + Pos);
-  for (size_t I = Pos, E = Str.size(); I != E; ++I) {
-    if (Str[I] == '%')
-      Buf.push_back('%');
-    Buf.push_back(Str[I]);
-  }
-
-  return StringRef(Buf.data(), Buf.size());
-}
-
 void TextDiagnosticBuffer::FlushDiagnostics(DiagnosticsEngine &Diags) const {
-  SmallVector<char, 64> Buf;
   // FIXME: Flush the diagnostics in order.
   for (const_iterator it = err_begin(), ie = err_end(); it != ie; ++it)
-    Diags.Report(Diags.getCustomDiagID(DiagnosticsEngine::Error,
-                                       escapeDiag(it->second, Buf)));
+    Diags.Report(Diags.getCustomDiagID(DiagnosticsEngine::Error, "%0"))
+        << it->second;
   for (const_iterator it = warn_begin(), ie = warn_end(); it != ie; ++it)
-    Diags.Report(Diags.getCustomDiagID(DiagnosticsEngine::Warning,
-                                       escapeDiag(it->second, Buf)));
+    Diags.Report(Diags.getCustomDiagID(DiagnosticsEngine::Warning, "%0"))
+        << it->second;
+  for (const_iterator it = remark_begin(), ie = remark_end(); it != ie; ++it)
+    Diags.Report(Diags.getCustomDiagID(DiagnosticsEngine::Remark, "%0"))
+        << it->second;
   for (const_iterator it = note_begin(), ie = note_end(); it != ie; ++it)
-    Diags.Report(Diags.getCustomDiagID(DiagnosticsEngine::Note,
-                                       escapeDiag(it->second, Buf)));
+    Diags.Report(Diags.getCustomDiagID(DiagnosticsEngine::Note, "%0"))
+        << it->second;
 }
 
diff --git a/lib/Frontend/TextDiagnosticPrinter.cpp b/lib/Frontend/TextDiagnosticPrinter.cpp
index 994a8f7..66b46b7 100644
--- a/lib/Frontend/TextDiagnosticPrinter.cpp
+++ b/lib/Frontend/TextDiagnosticPrinter.cpp
@@ -43,7 +43,7 @@
 }
 
 void TextDiagnosticPrinter::EndSourceFile() {
-  TextDiag.reset(0);
+  TextDiag.reset();
 }
 
 /// \brief Print any diagnostic option information to a raw_ostream.
@@ -81,7 +81,11 @@
 
     StringRef Opt = DiagnosticIDs::getWarningOptionForDiag(Info.getID());
     if (!Opt.empty()) {
-      OS << (Started ? "," : " [") << "-W" << Opt;
+      OS << (Started ? "," : " [")
+         << (Level == DiagnosticsEngine::Remark ? "-R" : "-W") << Opt;
+      StringRef OptValue = Info.getDiags()->getFlagValue();
+      if (!OptValue.empty())
+        OS << "=" << OptValue;
       Started = true;
     }
   }
@@ -150,8 +154,7 @@
 
   TextDiag->emitDiagnostic(Info.getLocation(), Level, DiagMessageStream.str(),
                            Info.getRanges(),
-                           llvm::makeArrayRef(Info.getFixItHints(),
-                                              Info.getNumFixItHints()),
+                           Info.getFixItHints(),
                            &Info.getSourceManager());
 
   OS.flush();
diff --git a/lib/Frontend/VerifyDiagnosticConsumer.cpp b/lib/Frontend/VerifyDiagnosticConsumer.cpp
index 045e60a..b50950e 100644
--- a/lib/Frontend/VerifyDiagnosticConsumer.cpp
+++ b/lib/Frontend/VerifyDiagnosticConsumer.cpp
@@ -30,8 +30,9 @@
 VerifyDiagnosticConsumer::VerifyDiagnosticConsumer(DiagnosticsEngine &_Diags)
   : Diags(_Diags),
     PrimaryClient(Diags.getClient()), OwnsPrimaryClient(Diags.ownsClient()),
-    Buffer(new TextDiagnosticBuffer()), CurrentPreprocessor(0),
-    LangOpts(0), SrcManager(0), ActiveSourceFiles(0), Status(HasNoDirectives)
+    Buffer(new TextDiagnosticBuffer()), CurrentPreprocessor(nullptr),
+    LangOpts(nullptr), SrcManager(nullptr), ActiveSourceFiles(0),
+    Status(HasNoDirectives)
 {
   Diags.takeClient();
   if (Diags.hasSourceManager())
@@ -41,7 +42,7 @@
 VerifyDiagnosticConsumer::~VerifyDiagnosticConsumer() {
   assert(!ActiveSourceFiles && "Incomplete parsing of source files!");
   assert(!CurrentPreprocessor && "CurrentPreprocessor should be invalid!");
-  SrcManager = 0;
+  SrcManager = nullptr;
   CheckDiagnostics();  
   Diags.takeClient();
   if (OwnsPrimaryClient)
@@ -104,8 +105,8 @@
 
     // Check diagnostics once last file completed.
     CheckDiagnostics();
-    CurrentPreprocessor = 0;
-    LangOpts = 0;
+    CurrentPreprocessor = nullptr;
+    LangOpts = nullptr;
   }
 }
 
@@ -163,15 +164,16 @@
 class StandardDirective : public Directive {
 public:
   StandardDirective(SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc,
-                    StringRef Text, unsigned Min, unsigned Max)
-    : Directive(DirectiveLoc, DiagnosticLoc, Text, Min, Max) { }
+                    bool MatchAnyLine, StringRef Text, unsigned Min,
+                    unsigned Max)
+    : Directive(DirectiveLoc, DiagnosticLoc, MatchAnyLine, Text, Min, Max) { }
 
-  virtual bool isValid(std::string &Error) {
+  bool isValid(std::string &Error) override {
     // all strings are considered valid; even empty ones
     return true;
   }
 
-  virtual bool match(StringRef S) {
+  bool match(StringRef S) override {
     return S.find(Text) != StringRef::npos;
   }
 };
@@ -181,16 +183,18 @@
 class RegexDirective : public Directive {
 public:
   RegexDirective(SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc,
-                 StringRef Text, unsigned Min, unsigned Max)
-    : Directive(DirectiveLoc, DiagnosticLoc, Text, Min, Max), Regex(Text) { }
+                 bool MatchAnyLine, StringRef Text, unsigned Min, unsigned Max,
+                 StringRef RegexStr)
+    : Directive(DirectiveLoc, DiagnosticLoc, MatchAnyLine, Text, Min, Max),
+      Regex(RegexStr) { }
 
-  virtual bool isValid(std::string &Error) {
+  bool isValid(std::string &Error) override {
     if (Regex.isValid(Error))
       return true;
     return false;
   }
 
-  virtual bool match(StringRef S) {
+  bool match(StringRef S) override {
     return Regex.match(S);
   }
 
@@ -202,7 +206,7 @@
 {
 public:
   ParseHelper(StringRef S)
-    : Begin(S.begin()), End(S.end()), C(Begin), P(Begin), PEnd(NULL) { }
+    : Begin(S.begin()), End(S.end()), C(Begin), P(Begin), PEnd(nullptr) {}
 
   // Return true if string literal is next.
   bool Next(StringRef S) {
@@ -240,7 +244,7 @@
       if (!EnsureStartOfWord
             // Check if string literal starts a new word.
             || P == Begin || isWhitespace(P[-1])
-            // Or it could be preceeded by the start of a comment.
+            // Or it could be preceded by the start of a comment.
             || (P > (Begin + 1) && (P[-1] == '/' || P[-1] == '*')
                                 &&  P[-2] == '/'))
         return true;
@@ -249,6 +253,30 @@
     return false;
   }
 
+  // Return true if a CloseBrace that closes the OpenBrace at the current nest
+  // level is found. When true, P marks begin-position of CloseBrace.
+  bool SearchClosingBrace(StringRef OpenBrace, StringRef CloseBrace) {
+    unsigned Depth = 1;
+    P = C;
+    while (P < End) {
+      StringRef S(P, End - P);
+      if (S.startswith(OpenBrace)) {
+        ++Depth;
+        P += OpenBrace.size();
+      } else if (S.startswith(CloseBrace)) {
+        --Depth;
+        if (Depth == 0) {
+          PEnd = P + CloseBrace.size();
+          return true;
+        }
+        P += CloseBrace.size();
+      } else {
+        ++P;
+      }
+    }
+    return false;
+  }
+
   // Advance 1-past previous next/search.
   // Behavior is undefined if previous next/search failed.
   bool Advance() {
@@ -301,13 +329,15 @@
     PH.Advance();
 
     // Next token: { error | warning | note }
-    DirectiveList* DL = NULL;
+    DirectiveList *DL = nullptr;
     if (PH.Next("error"))
-      DL = ED ? &ED->Errors : NULL;
+      DL = ED ? &ED->Errors : nullptr;
     else if (PH.Next("warning"))
-      DL = ED ? &ED->Warnings : NULL;
+      DL = ED ? &ED->Warnings : nullptr;
+    else if (PH.Next("remark"))
+      DL = ED ? &ED->Remarks : nullptr;
     else if (PH.Next("note"))
-      DL = ED ? &ED->Notes : NULL;
+      DL = ED ? &ED->Notes : nullptr;
     else if (PH.Next("no-diagnostics")) {
       if (Status == VerifyDiagnosticConsumer::HasOtherExpectedDirectives)
         Diags.Report(Pos, diag::err_verify_invalid_no_diags)
@@ -344,6 +374,7 @@
 
     // Next optional token: @
     SourceLocation ExpectedLoc;
+    bool MatchAnyLine = false;
     if (!PH.Next("@")) {
       ExpectedLoc = Pos;
     } else {
@@ -371,8 +402,8 @@
 
         // Lookup file via Preprocessor, like a #include.
         const DirectoryLookup *CurDir;
-        const FileEntry *FE = PP->LookupFile(Pos, Filename, false, NULL, CurDir,
-                                             NULL, NULL, 0);
+        const FileEntry *FE = PP->LookupFile(Pos, Filename, false, nullptr,
+                                             CurDir, nullptr, nullptr, nullptr);
         if (!FE) {
           Diags.Report(Pos.getLocWithOffset(PH.C-PH.Begin),
                        diag::err_verify_missing_file) << Filename << KindStr;
@@ -384,6 +415,10 @@
 
         if (PH.Next(Line) && Line > 0)
           ExpectedLoc = SM.translateFileLineCol(FE, Line, 1);
+        else if (PH.Next("*")) {
+          MatchAnyLine = true;
+          ExpectedLoc = SM.translateFileLineCol(FE, 1, 1);
+        }
       }
 
       if (ExpectedLoc.isInvalid()) {
@@ -437,7 +472,7 @@
     const char* const ContentBegin = PH.C; // mark content begin
 
     // Search for token: }}
-    if (!PH.Search("}}")) {
+    if (!PH.SearchClosingBrace("{{", "}}")) {
       Diags.Report(Pos.getLocWithOffset(PH.C-PH.Begin),
                    diag::err_verify_missing_end) << KindStr;
       continue;
@@ -459,12 +494,21 @@
     if (Text.empty())
       Text.assign(ContentBegin, ContentEnd);
 
+    // Check that regex directives contain at least one regex.
+    if (RegexKind && Text.find("{{") == StringRef::npos) {
+      Diags.Report(Pos.getLocWithOffset(ContentBegin-PH.Begin),
+                   diag::err_verify_missing_regex) << Text;
+      return false;
+    }
+
     // Construct new directive.
-    Directive *D = Directive::create(RegexKind, Pos, ExpectedLoc, Text,
-                                     Min, Max);
+    std::unique_ptr<Directive> D(
+        Directive::create(RegexKind, Pos, ExpectedLoc, MatchAnyLine, Text,
+                          Min, Max));
+
     std::string Error;
     if (D->isValid(Error)) {
-      DL->push_back(D);
+      DL->push_back(D.release());
       FoundDirective = true;
     } else {
       Diags.Report(Pos.getLocWithOffset(ContentBegin-PH.Begin),
@@ -562,7 +606,8 @@
     if (Comment.empty()) continue;
 
     // Find first directive.
-    if (ParseDirective(Comment, 0, SM, 0, Tok.getLocation(), Status))
+    if (ParseDirective(Comment, nullptr, SM, nullptr, Tok.getLocation(),
+                       Status))
       return true;
   }
   return false;
@@ -608,8 +653,11 @@
   llvm::raw_svector_ostream OS(Fmt);
   for (DirectiveList::iterator I = DL.begin(), E = DL.end(); I != E; ++I) {
     Directive &D = **I;
-    OS << "\n  File " << SourceMgr.getFilename(D.DiagnosticLoc)
-          << " Line " << SourceMgr.getPresumedLineNumber(D.DiagnosticLoc);
+    OS << "\n  File " << SourceMgr.getFilename(D.DiagnosticLoc);
+    if (D.MatchAnyLine)
+      OS << " Line *";
+    else
+      OS << " Line " << SourceMgr.getPresumedLineNumber(D.DiagnosticLoc);
     if (D.DirectiveLoc != D.DiagnosticLoc)
       OS << " (directive at "
          << SourceMgr.getFilename(D.DirectiveLoc) << ':'
@@ -656,9 +704,11 @@
     for (unsigned i = 0; i < D.Max; ++i) {
       DiagList::iterator II, IE;
       for (II = Right.begin(), IE = Right.end(); II != IE; ++II) {
-        unsigned LineNo2 = SourceMgr.getPresumedLineNumber(II->first);
-        if (LineNo1 != LineNo2)
-          continue;
+        if (!D.MatchAnyLine) {
+          unsigned LineNo2 = SourceMgr.getPresumedLineNumber(II->first);
+          if (LineNo1 != LineNo2)
+            continue;
+        }
 
         if (!IsFromSameFile(SourceMgr, D.DiagnosticLoc, II->first))
           continue;
@@ -705,6 +755,10 @@
   NumProblems += CheckLists(Diags, SourceMgr, "warning", ED.Warnings,
                             Buffer.warn_begin(), Buffer.warn_end());
 
+  // See if there are remark mismatches.
+  NumProblems += CheckLists(Diags, SourceMgr, "remark", ED.Remarks,
+                            Buffer.remark_begin(), Buffer.remark_end());
+
   // See if there are note mismatches.
   NumProblems += CheckLists(Diags, SourceMgr, "note", ED.Notes,
                             Buffer.note_begin(), Buffer.note_end());
@@ -802,11 +856,11 @@
     // Check that the expected diagnostics occurred.
     NumErrors += CheckResults(Diags, *SrcManager, *Buffer, ED);
   } else {
-    NumErrors += (PrintUnexpected(Diags, 0, Buffer->err_begin(),
+    NumErrors += (PrintUnexpected(Diags, nullptr, Buffer->err_begin(),
                                   Buffer->err_end(), "error") +
-                  PrintUnexpected(Diags, 0, Buffer->warn_begin(),
+                  PrintUnexpected(Diags, nullptr, Buffer->warn_begin(),
                                   Buffer->warn_end(), "warn") +
-                  PrintUnexpected(Diags, 0, Buffer->note_begin(),
+                  PrintUnexpected(Diags, nullptr, Buffer->note_begin(),
                                   Buffer->note_end(), "note"));
   }
 
@@ -815,15 +869,39 @@
 
   // Reset the buffer, we have processed all the diagnostics in it.
   Buffer.reset(new TextDiagnosticBuffer());
-  ED.Errors.clear();
-  ED.Warnings.clear();
-  ED.Notes.clear();
+  ED.Reset();
 }
 
 Directive *Directive::create(bool RegexKind, SourceLocation DirectiveLoc,
-                             SourceLocation DiagnosticLoc, StringRef Text,
-                             unsigned Min, unsigned Max) {
-  if (RegexKind)
-    return new RegexDirective(DirectiveLoc, DiagnosticLoc, Text, Min, Max);
-  return new StandardDirective(DirectiveLoc, DiagnosticLoc, Text, Min, Max);
+                             SourceLocation DiagnosticLoc, bool MatchAnyLine,
+                             StringRef Text, unsigned Min, unsigned Max) {
+  if (!RegexKind)
+    return new StandardDirective(DirectiveLoc, DiagnosticLoc, MatchAnyLine,
+                                 Text, Min, Max);
+
+  // Parse the directive into a regular expression.
+  std::string RegexStr;
+  StringRef S = Text;
+  while (!S.empty()) {
+    if (S.startswith("{{")) {
+      S = S.drop_front(2);
+      size_t RegexMatchLength = S.find("}}");
+      assert(RegexMatchLength != StringRef::npos);
+      // Append the regex, enclosed in parentheses.
+      RegexStr += "(";
+      RegexStr.append(S.data(), RegexMatchLength);
+      RegexStr += ")";
+      S = S.drop_front(RegexMatchLength + 2);
+    } else {
+      size_t VerbatimMatchLength = S.find("{{");
+      if (VerbatimMatchLength == StringRef::npos)
+        VerbatimMatchLength = S.size();
+      // Escape and append the fixed string.
+      RegexStr += llvm::Regex::escape(S.substr(0, VerbatimMatchLength));
+      S = S.drop_front(VerbatimMatchLength);
+    }
+  }
+
+  return new RegexDirective(DirectiveLoc, DiagnosticLoc, MatchAnyLine, Text,
+                            Min, Max, RegexStr);
 }
diff --git a/lib/Frontend/Warnings.cpp b/lib/Frontend/Warnings.cpp
deleted file mode 100644
index 767096a..0000000
--- a/lib/Frontend/Warnings.cpp
+++ /dev/null
@@ -1,203 +0,0 @@
-//===--- Warnings.cpp - C-Language Front-end ------------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Command line warning options handler.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is responsible for handling all warning options. This includes
-// a number of -Wfoo options and their variants, which are driven by TableGen-
-// generated data, and the special cases -pedantic, -pedantic-errors, -w,
-// -Werror and -Wfatal-errors.
-//
-// Each warning option controls any number of actual warnings.
-// Given a warning option 'foo', the following are valid:
-//    -Wfoo, -Wno-foo, -Werror=foo, -Wfatal-errors=foo
-//
-#include "clang/Frontend/Utils.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/DiagnosticOptions.h"
-#include "clang/Frontend/FrontendDiagnostic.h"
-#include "clang/Lex/LexDiagnostic.h"
-#include "clang/Sema/SemaDiagnostic.h"
-#include <algorithm>
-#include <cstring>
-#include <utility>
-using namespace clang;
-
-// EmitUnknownDiagWarning - Emit a warning and typo hint for unknown warning
-// opts
-static void EmitUnknownDiagWarning(DiagnosticsEngine &Diags,
-                                  StringRef Prefix, StringRef Opt,
-                                  bool isPositive) {
-  StringRef Suggestion = DiagnosticIDs::getNearestWarningOption(Opt);
-  if (!Suggestion.empty())
-    Diags.Report(isPositive? diag::warn_unknown_warning_option_suggest :
-                             diag::warn_unknown_negative_warning_option_suggest)
-      << (Prefix.str() += Opt) << (Prefix.str() += Suggestion);
-  else
-    Diags.Report(isPositive? diag::warn_unknown_warning_option :
-                             diag::warn_unknown_negative_warning_option)
-      << (Prefix.str() += Opt);
-}
-
-void clang::ProcessWarningOptions(DiagnosticsEngine &Diags,
-                                  const DiagnosticOptions &Opts,
-                                  bool ReportDiags) {
-  Diags.setSuppressSystemWarnings(true);  // Default to -Wno-system-headers
-  Diags.setIgnoreAllWarnings(Opts.IgnoreWarnings);
-  Diags.setShowOverloads(Opts.getShowOverloads());
-
-  Diags.setElideType(Opts.ElideType);
-  Diags.setPrintTemplateTree(Opts.ShowTemplateTree);
-  Diags.setShowColors(Opts.ShowColors);
- 
-  // Handle -ferror-limit
-  if (Opts.ErrorLimit)
-    Diags.setErrorLimit(Opts.ErrorLimit);
-  if (Opts.TemplateBacktraceLimit)
-    Diags.setTemplateBacktraceLimit(Opts.TemplateBacktraceLimit);
-  if (Opts.ConstexprBacktraceLimit)
-    Diags.setConstexprBacktraceLimit(Opts.ConstexprBacktraceLimit);
-
-  // If -pedantic or -pedantic-errors was specified, then we want to map all
-  // extension diagnostics onto WARNING or ERROR unless the user has futz'd
-  // around with them explicitly.
-  if (Opts.PedanticErrors)
-    Diags.setExtensionHandlingBehavior(DiagnosticsEngine::Ext_Error);
-  else if (Opts.Pedantic)
-    Diags.setExtensionHandlingBehavior(DiagnosticsEngine::Ext_Warn);
-  else
-    Diags.setExtensionHandlingBehavior(DiagnosticsEngine::Ext_Ignore);
-
-  SmallVector<diag::kind, 10> _Diags;
-  const IntrusiveRefCntPtr< DiagnosticIDs > DiagIDs =
-    Diags.getDiagnosticIDs();
-  // We parse the warning options twice.  The first pass sets diagnostic state,
-  // while the second pass reports warnings/errors.  This has the effect that
-  // we follow the more canonical "last option wins" paradigm when there are 
-  // conflicting options.
-  for (unsigned Report = 0, ReportEnd = 2; Report != ReportEnd; ++Report) {
-    bool SetDiagnostic = (Report == 0);
-
-    // If we've set the diagnostic state and are not reporting diagnostics then
-    // we're done.
-    if (!SetDiagnostic && !ReportDiags)
-      break;
-
-    for (unsigned i = 0, e = Opts.Warnings.size(); i != e; ++i) {
-      StringRef Opt = Opts.Warnings[i];
-      StringRef OrigOpt = Opts.Warnings[i];
-
-      // Treat -Wformat=0 as an alias for -Wno-format.
-      if (Opt == "format=0")
-        Opt = "no-format";
-
-      // Check to see if this warning starts with "no-", if so, this is a
-      // negative form of the option.
-      bool isPositive = true;
-      if (Opt.startswith("no-")) {
-        isPositive = false;
-        Opt = Opt.substr(3);
-      }
-
-      // Figure out how this option affects the warning.  If -Wfoo, map the
-      // diagnostic to a warning, if -Wno-foo, map it to ignore.
-      diag::Mapping Mapping = isPositive ? diag::MAP_WARNING : diag::MAP_IGNORE;
-      
-      // -Wsystem-headers is a special case, not driven by the option table.  It
-      // cannot be controlled with -Werror.
-      if (Opt == "system-headers") {
-        if (SetDiagnostic)
-          Diags.setSuppressSystemWarnings(!isPositive);
-        continue;
-      }
-      
-      // -Weverything is a special case as well.  It implicitly enables all
-      // warnings, including ones not explicitly in a warning group.
-      if (Opt == "everything") {
-        if (SetDiagnostic) {
-          if (isPositive) {
-            Diags.setEnableAllWarnings(true);
-          } else {
-            Diags.setEnableAllWarnings(false);
-            Diags.setMappingToAllDiagnostics(diag::MAP_IGNORE);
-          }
-        }
-        continue;
-      }
-      
-      // -Werror/-Wno-error is a special case, not controlled by the option 
-      // table. It also has the "specifier" form of -Werror=foo and -Werror-foo.
-      if (Opt.startswith("error")) {
-        StringRef Specifier;
-        if (Opt.size() > 5) {  // Specifier must be present.
-          if ((Opt[5] != '=' && Opt[5] != '-') || Opt.size() == 6) {
-            if (Report)
-              Diags.Report(diag::warn_unknown_warning_specifier)
-                << "-Werror" << ("-W" + OrigOpt.str());
-            continue;
-          }
-          Specifier = Opt.substr(6);
-        }
-        
-        if (Specifier.empty()) {
-          if (SetDiagnostic)
-            Diags.setWarningsAsErrors(isPositive);
-          continue;
-        }
-        
-        if (SetDiagnostic) {
-          // Set the warning as error flag for this specifier.
-          Diags.setDiagnosticGroupWarningAsError(Specifier, isPositive);
-        } else if (DiagIDs->getDiagnosticsInGroup(Specifier, _Diags)) {
-          EmitUnknownDiagWarning(Diags, "-Werror=", Specifier, isPositive);
-        }
-        continue;
-      }
-      
-      // -Wfatal-errors is yet another special case.
-      if (Opt.startswith("fatal-errors")) {
-        StringRef Specifier;
-        if (Opt.size() != 12) {
-          if ((Opt[12] != '=' && Opt[12] != '-') || Opt.size() == 13) {
-            if (Report)
-              Diags.Report(diag::warn_unknown_warning_specifier)
-                << "-Wfatal-errors" << ("-W" + OrigOpt.str());
-            continue;
-          }
-          Specifier = Opt.substr(13);
-        }
-
-        if (Specifier.empty()) {
-          if (SetDiagnostic)
-            Diags.setErrorsAsFatal(isPositive);
-          continue;
-        }
-        
-        if (SetDiagnostic) {
-          // Set the error as fatal flag for this specifier.
-          Diags.setDiagnosticGroupErrorAsFatal(Specifier, isPositive);
-        } else if (DiagIDs->getDiagnosticsInGroup(Specifier, _Diags)) {
-          EmitUnknownDiagWarning(Diags, "-Wfatal-errors=", Specifier,
-                                 isPositive);
-        }
-        continue;
-      }
-      
-      if (Report) {
-        if (DiagIDs->getDiagnosticsInGroup(Opt, _Diags))
-          EmitUnknownDiagWarning(Diags, isPositive ? "-W" : "-Wno-", Opt,
-                                 isPositive);
-      } else {
-        Diags.setDiagnosticGroupMapping(Opt, Mapping);
-      }
-    }
-  }
-}
diff --git a/lib/FrontendTool/CMakeLists.txt b/lib/FrontendTool/CMakeLists.txt
index 28a864a..7e11be0 100644
--- a/lib/FrontendTool/CMakeLists.txt
+++ b/lib/FrontendTool/CMakeLists.txt
@@ -1,31 +1,34 @@
-add_clang_library(clangFrontendTool
-  ExecuteCompilerInvocation.cpp
+set(LLVM_LINK_COMPONENTS
+  Option
+  Support
   )
 
-add_dependencies(clangFrontendTool
-  ClangDiagnosticCommon
-  ClangDiagnosticFrontend
-  ClangDriverOptions
-  )
-
-target_link_libraries(clangFrontendTool
+set(link_libs
+  clangBasic
+  clangCodeGen
   clangDriver
   clangFrontend
-  clangRewriteCore
   clangRewriteFrontend
-  clangCodeGen
   )
 
 if(CLANG_ENABLE_ARCMT)
-  target_link_libraries(clangFrontendTool
+  list(APPEND link_libs
     clangARCMigrate
     )
 endif()
 
 if(CLANG_ENABLE_STATIC_ANALYZER)
-  target_link_libraries(clangFrontendTool
+  list(APPEND link_libs
     clangStaticAnalyzerFrontend
-    clangStaticAnalyzerCheckers
-    clangStaticAnalyzerCore
     )
 endif()
+
+add_clang_library(clangFrontendTool
+  ExecuteCompilerInvocation.cpp
+
+  DEPENDS
+  ClangDriverOptions
+
+  LINK_LIBS
+  ${link_libs}
+  )
diff --git a/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/lib/FrontendTool/ExecuteCompilerInvocation.cpp
index d755839..de864f6 100644
--- a/lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ b/lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -21,6 +21,7 @@
 #include "clang/Frontend/FrontendActions.h"
 #include "clang/Frontend/FrontendDiagnostic.h"
 #include "clang/Frontend/FrontendPluginRegistry.h"
+#include "clang/Frontend/Utils.h"
 #include "clang/Rewrite/Frontend/FrontendActions.h"
 #include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
 #include "llvm/Option/OptTable.h"
@@ -33,6 +34,7 @@
 static FrontendAction *CreateFrontendBaseAction(CompilerInstance &CI) {
   using namespace clang::frontend;
   StringRef Action("unknown");
+  (void)Action;
 
   switch (CI.getFrontendOpts().ProgramAction) {
   case ASTDeclList:            return new ASTDeclListAction();
@@ -43,66 +45,51 @@
   case DumpTokens:             return new DumpTokensAction();
   case EmitAssembly:           return new EmitAssemblyAction();
   case EmitBC:                 return new EmitBCAction();
-#ifdef CLANG_ENABLE_REWRITER
   case EmitHTML:               return new HTMLPrintAction();
-#else
-  case EmitHTML:               Action = "EmitHTML"; break;
-#endif
   case EmitLLVM:               return new EmitLLVMAction();
   case EmitLLVMOnly:           return new EmitLLVMOnlyAction();
   case EmitCodeGenOnly:        return new EmitCodeGenOnlyAction();
   case EmitObj:                return new EmitObjAction();
-#ifdef CLANG_ENABLE_REWRITER
   case FixIt:                  return new FixItAction();
-#else
-  case FixIt:                  Action = "FixIt"; break;
-#endif
   case GenerateModule:         return new GenerateModuleAction;
   case GeneratePCH:            return new GeneratePCHAction;
   case GeneratePTH:            return new GeneratePTHAction();
   case InitOnly:               return new InitOnlyAction();
   case ParseSyntaxOnly:        return new SyntaxOnlyAction();
   case ModuleFileInfo:         return new DumpModuleInfoAction();
+  case VerifyPCH:              return new VerifyPCHAction();
 
   case PluginAction: {
     for (FrontendPluginRegistry::iterator it =
            FrontendPluginRegistry::begin(), ie = FrontendPluginRegistry::end();
          it != ie; ++it) {
       if (it->getName() == CI.getFrontendOpts().ActionName) {
-        OwningPtr<PluginASTAction> P(it->instantiate());
+        std::unique_ptr<PluginASTAction> P(it->instantiate());
         if (!P->ParseArgs(CI, CI.getFrontendOpts().PluginArgs))
-          return 0;
-        return P.take();
+          return nullptr;
+        return P.release();
       }
     }
 
     CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name)
       << CI.getFrontendOpts().ActionName;
-    return 0;
+    return nullptr;
   }
 
   case PrintDeclContext:       return new DeclContextPrintAction();
   case PrintPreamble:          return new PrintPreambleAction();
   case PrintPreprocessedInput: {
-    if (CI.getPreprocessorOutputOpts().RewriteIncludes) {
-#ifdef CLANG_ENABLE_REWRITER
+    if (CI.getPreprocessorOutputOpts().RewriteIncludes)
       return new RewriteIncludesAction();
-#else
-      Action = "RewriteIncludesAction";
-      break;
-#endif
-    }
     return new PrintPreprocessedAction();
   }
 
-#ifdef CLANG_ENABLE_REWRITER
   case RewriteMacros:          return new RewriteMacrosAction();
-  case RewriteObjC:            return new RewriteObjCAction();
   case RewriteTest:            return new RewriteTestAction();
+#ifdef CLANG_ENABLE_OBJC_REWRITER
+  case RewriteObjC:            return new RewriteObjCAction();
 #else
-  case RewriteMacros:          Action = "RewriteMacros"; break;
   case RewriteObjC:            Action = "RewriteObjC"; break;
-  case RewriteTest:            Action = "RewriteTest"; break;
 #endif
 #ifdef CLANG_ENABLE_ARCMT
   case MigrateSource:          return new arcmt::MigrateSourceAction();
@@ -118,7 +105,7 @@
   }
 
 #if !defined(CLANG_ENABLE_ARCMT) || !defined(CLANG_ENABLE_STATIC_ANALYZER) \
-  || !defined(CLANG_ENABLE_REWRITER)
+  || !defined(CLANG_ENABLE_OBJC_REWRITER)
   CI.getDiagnostics().Report(diag::err_fe_action_not_available) << Action;
   return 0;
 #else
@@ -130,18 +117,17 @@
   // Create the underlying action.
   FrontendAction *Act = CreateFrontendBaseAction(CI);
   if (!Act)
-    return 0;
+    return nullptr;
 
   const FrontendOptions &FEOpts = CI.getFrontendOpts();
 
-#ifdef CLANG_ENABLE_REWRITER
   if (FEOpts.FixAndRecompile) {
     Act = new FixItRecompile(Act);
   }
-#endif
   
 #ifdef CLANG_ENABLE_ARCMT
-  if (CI.getFrontendOpts().ProgramAction != frontend::MigrateSource) {
+  if (CI.getFrontendOpts().ProgramAction != frontend::MigrateSource &&
+      CI.getFrontendOpts().ProgramAction != frontend::GeneratePCH) {
     // Potentially wrap the base FE action in an ARC Migrate Tool action.
     switch (FEOpts.ARCMTAction) {
     case FrontendOptions::ARCMT_None:
@@ -178,7 +164,7 @@
 bool clang::ExecuteCompilerInvocation(CompilerInstance *Clang) {
   // Honor -help.
   if (Clang->getFrontendOpts().ShowHelp) {
-    OwningPtr<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);
@@ -209,12 +195,12 @@
   // This should happen AFTER plugins have been loaded!
   if (!Clang->getFrontendOpts().LLVMArgs.empty()) {
     unsigned NumArgs = Clang->getFrontendOpts().LLVMArgs.size();
-    const char **Args = new const char*[NumArgs + 2];
+    auto Args = llvm::make_unique<const char*[]>(NumArgs + 2);
     Args[0] = "clang (LLVM option parsing)";
     for (unsigned i = 0; i != NumArgs; ++i)
       Args[i + 1] = Clang->getFrontendOpts().LLVMArgs[i].c_str();
-    Args[NumArgs + 1] = 0;
-    llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args);
+    Args[NumArgs + 1] = nullptr;
+    llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args.get());
   }
 
 #ifdef CLANG_ENABLE_STATIC_ANALYZER
@@ -230,11 +216,11 @@
   if (Clang->getDiagnostics().hasErrorOccurred())
     return false;
   // Create and execute the frontend action.
-  OwningPtr<FrontendAction> Act(CreateFrontendAction(*Clang));
+  std::unique_ptr<FrontendAction> Act(CreateFrontendAction(*Clang));
   if (!Act)
     return false;
   bool Success = Clang->ExecuteAction(*Act);
   if (Clang->getFrontendOpts().DisableFree)
-    Act.take();
+    BuryPointer(Act.release());
   return Success;
 }
diff --git a/lib/FrontendTool/Makefile b/lib/FrontendTool/Makefile
index 9ce4b76..dfd2820 100644
--- a/lib/FrontendTool/Makefile
+++ b/lib/FrontendTool/Makefile
@@ -15,10 +15,7 @@
 
 ifeq ($(ENABLE_CLANG_ARCMT),1)
   CXX.Flags += -DCLANG_ENABLE_ARCMT
-endif
-
-ifeq ($(ENABLE_CLANG_REWRITER),1)
-  CXX.Flags += -DCLANG_ENABLE_REWRITER
+  CXX.Flags += -DCLANG_ENABLE_OBJC_REWRITER
 endif
 
 ifeq ($(ENABLE_CLANG_STATIC_ANALYZER),1)
diff --git a/lib/Headers/CMakeLists.txt b/lib/Headers/CMakeLists.txt
index 2da1a28..edee7d7 100644
--- a/lib/Headers/CMakeLists.txt
+++ b/lib/Headers/CMakeLists.txt
@@ -1,6 +1,7 @@
 set(files
   altivec.h
   ammintrin.h
+  arm_acle.h
   avxintrin.h
   avx2intrin.h
   bmiintrin.h
@@ -10,6 +11,7 @@
   float.h
   fma4intrin.h
   fmaintrin.h
+  ia32intrin.h
   immintrin.h
   iso646.h
   Intrin.h
@@ -44,20 +46,13 @@
   xopintrin.h
   cpuid.h
   unwind.h
-  module.map
+  module.modulemap
   )
 
-set(output_dir ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/clang/${CLANG_VERSION}/include)
-
-# If we are in an IDE that has a configuration directory, we need to
-# create a second copy of the headers so that 'clang' can find them if
-# it's run from the build directory.
-if(MSVC_IDE OR XCODE)
-   set(other_output_dir ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/lib/clang/${CLANG_VERSION}/include)
-endif()
+set(output_dir ${LLVM_LIBRARY_OUTPUT_INTDIR}/clang/${CLANG_VERSION}/include)
 
 # Generate arm_neon.h
-clang_tablegen(arm_neon.h.inc -gen-arm-neon
+clang_tablegen(arm_neon.h -gen-arm-neon
   SOURCE ${CLANG_SOURCE_DIR}/include/clang/Basic/arm_neon.td)
 
 set(out_files)
@@ -69,43 +64,18 @@
     COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst}
     COMMENT "Copying clang's ${f}...")
   list(APPEND out_files ${dst})
-
-  if(other_output_dir)
-   set(other_dst ${other_output_dir}/${f})
-    add_custom_command(OUTPUT ${other_dst}
-      DEPENDS ${src}
-      COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${other_dst}
-      COMMENT "Copying clang's ${f}...")    
-    list(APPEND out_files ${other_dst})
-  endif()
 endforeach( f )
 
 add_custom_command(OUTPUT ${output_dir}/arm_neon.h 
-  DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/arm_neon.h.inc
-  COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/arm_neon.h.inc ${output_dir}/arm_neon.h
+  DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/arm_neon.h
+  COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/arm_neon.h ${output_dir}/arm_neon.h
   COMMENT "Copying clang's arm_neon.h...")
 list(APPEND out_files ${output_dir}/arm_neon.h)
 
-if (other_output_dir)
-    set(other_dst ${other_output_dir}/arm_neon.h)
-    add_custom_command(OUTPUT ${other_dst}
-      DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/arm_neon.h.inc
-      COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/arm_neon.h.inc ${other_dst}
-      COMMENT "Copying clang's arm_neon.h...")
-    list(APPEND out_files ${other_dst})
-endif ()
-
 add_custom_target(clang-headers ALL DEPENDS ${out_files})
 set_target_properties(clang-headers PROPERTIES FOLDER "Misc")
 
-if (other_output_dir)
-  if(UNIX)
-    add_custom_command(TARGET clang-headers POST_BUILD
-    COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}"
-    COMMAND ${CMAKE_COMMAND} -E create_symlink "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/lib/clang" "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/clang")
-  endif()
-endif ()
-
-install(FILES ${files} ${output_dir}/arm_neon.h
+install(
+  FILES ${files} ${CMAKE_CURRENT_BINARY_DIR}/arm_neon.h
   PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
   DESTINATION lib${LLVM_LIBDIR_SUFFIX}/clang/${CLANG_VERSION}/include)
diff --git a/lib/Headers/Intrin.h b/lib/Headers/Intrin.h
index 4376464..13e105e 100644
--- a/lib/Headers/Intrin.h
+++ b/lib/Headers/Intrin.h
@@ -30,31 +30,43 @@
 #define __INTRIN_H
 
 /* First include the standard intrinsics. */
+#if defined(__i386__) || defined(__x86_64__)
 #include <x86intrin.h>
+#endif
+
+/* For the definition of jmp_buf. */
+#if __STDC_HOSTED__
+#include <setjmp.h>
+#endif
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#if defined(__MMX__)
 /* And the random ones that aren't in those files. */
 __m64 _m_from_float(float);
 __m64 _m_from_int(int _l);
 void _m_prefetch(void *);
 float _m_to_float(__m64);
 int _m_to_int(__m64 _M);
+#endif
 
 /* Other assorted instruction intrinsics. */
 void __addfsbyte(unsigned long, unsigned char);
 void __addfsdword(unsigned long, unsigned long);
 void __addfsword(unsigned long, unsigned short);
 void __code_seg(const char *);
+static __inline__
 void __cpuid(int[4], int);
+static __inline__
 void __cpuidex(int[4], int, int);
 void __debugbreak(void);
 __int64 __emul(int, int);
 unsigned __int64 __emulu(unsigned int, unsigned int);
 void __cdecl __fastfail(unsigned int);
 unsigned int __getcallerseflags(void);
+static __inline__
 void __halt(void);
 unsigned char __inbyte(unsigned short);
 void __inbytestring(unsigned short, unsigned char *, unsigned long);
@@ -75,8 +87,11 @@
 void __lwpval32(unsigned int, unsigned int, unsigned int);
 unsigned int __lzcnt(unsigned int);
 unsigned short __lzcnt16(unsigned short);
+static __inline__
 void __movsb(unsigned char *, unsigned char const *, size_t);
+static __inline__
 void __movsd(unsigned long *, unsigned long const *, size_t);
+static __inline__
 void __movsw(unsigned short *, unsigned short const *, size_t);
 void __nop(void);
 void __nvreg_restore_fence(void);
@@ -91,26 +106,34 @@
 unsigned int __popcnt(unsigned int);
 static __inline__
 unsigned short __popcnt16(unsigned short);
-unsigned __int64 __rdtsc(void);
-unsigned __int64 __rdtscp(unsigned int *);
 unsigned long __readcr0(void);
 unsigned long __readcr2(void);
+static __inline__
 unsigned long __readcr3(void);
-unsigned long __readcr5(void);
+unsigned long __readcr4(void);
 unsigned long __readcr8(void);
 unsigned int __readdr(unsigned int);
-unsigned int __readeflags(void);
+#ifdef __i386__
+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);
+#endif
+static __inline__
 unsigned __int64 __readmsr(unsigned long);
 unsigned __int64 __readpmc(unsigned long);
 unsigned long __segmentlimit(unsigned long);
 void __sidt(void *);
 void *__slwpcb(void);
+static __inline__
 void __stosb(unsigned char *, unsigned char, size_t);
+static __inline__
 void __stosd(unsigned long *, unsigned long, size_t);
+static __inline__
 void __stosw(unsigned short *, unsigned short, size_t);
 void __svm_clgi(void);
 void __svm_invlpga(void *, int);
@@ -125,11 +148,11 @@
 void __vmx_vmptrst(unsigned __int64 *);
 void __wbinvd(void);
 void __writecr0(unsigned int);
+static __inline__
 void __writecr3(unsigned int);
 void __writecr4(unsigned int);
 void __writecr8(unsigned int);
 void __writedr(unsigned int, unsigned int);
-void __writeeflags(unsigned int);
 void __writefsbyte(unsigned long, unsigned char);
 void __writefsdword(unsigned long, unsigned long);
 void __writefsqword(unsigned long, unsigned __int64);
@@ -139,7 +162,6 @@
 void *_AddressOfReturnAddress(void);
 unsigned int _andn_u32(unsigned int, unsigned int);
 unsigned int _bextr_u32(unsigned int, unsigned int, unsigned int);
-unsigned int _bextr_u32(unsigned int, unsigned int, unsigned int);
 unsigned int _bextri_u32(unsigned int, unsigned int);
 static __inline__
 unsigned char _BitScanForward(unsigned long *_Index, unsigned long _Mask);
@@ -162,8 +184,6 @@
 unsigned int _blsi_u32(unsigned int);
 unsigned int _blsic_u32(unsigned int);
 unsigned int _blsmsk_u32(unsigned int);
-unsigned int _blsmsk_u32(unsigned int);
-unsigned int _blsr_u32(unsigned int);
 unsigned int _blsr_u32(unsigned int);
 unsigned __int64 __cdecl _byteswap_uint64(unsigned __int64);
 unsigned long __cdecl _byteswap_ulong(unsigned long);
@@ -181,6 +201,7 @@
 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,
@@ -208,8 +229,7 @@
 long __cdecl _InterlockedDecrement(long volatile *_Addend);
 static __inline__
 short _InterlockedDecrement16(short volatile *_Addend);
-static __inline__
-long __cdecl _InterlockedExchange(long volatile *_Target, long _Value);
+long _InterlockedExchange(long volatile *_Target, long _Value);
 static __inline__
 short _InterlockedExchange16(short volatile *_Target, short _Value);
 static __inline__
@@ -219,6 +239,10 @@
 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);
@@ -269,10 +293,9 @@
 static __inline__
 unsigned char _rotr8(unsigned char _Value, unsigned char _Shift);
 int _sarx_i32(int, unsigned int);
-
-/* FIXME: Need definition for jmp_buf.
-   int __cdecl _setjmp(jmp_buf); */
-
+#if __STDC_HOSTED__
+int __cdecl _setjmp(jmp_buf);
+#endif
 unsigned int _shlx_u32(unsigned int, unsigned int);
 unsigned int _shrx_u32(unsigned int, unsigned int);
 void _Store_HLERelease(long volatile *, long);
@@ -280,13 +303,13 @@
 void _StorePointer_HLERelease(void *volatile *, void *);
 unsigned int _t1mskc_u32(unsigned int);
 unsigned int _tzcnt_u32(unsigned int);
-unsigned int _tzcnt_u32(unsigned int);
 unsigned int _tzmsk_u32(unsigned int);
 static __inline__
 void _WriteBarrier(void);
 void _xabort(const unsigned int imm);
 unsigned __int32 xbegin(void);
 void _xend(void);
+static __inline__
 unsigned __int64 __cdecl _xgetbv(unsigned int);
 void __cdecl _xrstor(void const *, unsigned __int64);
 void __cdecl _xsave(void *, unsigned __int64);
@@ -300,19 +323,47 @@
 void __addgsdword(unsigned long, unsigned long);
 void __addgsqword(unsigned long, unsigned __int64);
 void __addgsword(unsigned long, unsigned short);
+static __inline__
 void __faststorefence(void);
 void __incgsbyte(unsigned long);
 void __incgsdword(unsigned long);
 void __incgsqword(unsigned long);
 void __incgsword(unsigned long);
+unsigned char __lwpins64(unsigned __int64, unsigned int, unsigned int);
+void __lwpval64(unsigned __int64, unsigned int, unsigned int);
+unsigned __int64 __lzcnt64(unsigned __int64);
+static __inline__
+void __movsq(unsigned long long *, unsigned long long const *, size_t);
+__int64 __mulh(__int64, __int64);
+static __inline__
 unsigned __int64 __popcnt64(unsigned __int64);
+static __inline__
+unsigned char __readgsbyte(unsigned long);
+static __inline__
+unsigned long __readgsdword(unsigned long);
+static __inline__
+unsigned __int64 __readgsqword(unsigned long);
+unsigned short __readgsword(unsigned long);
 unsigned __int64 __shiftleft128(unsigned __int64 _LowPart,
                                 unsigned __int64 _HighPart,
                                 unsigned char _Shift);
 unsigned __int64 __shiftright128(unsigned __int64 _LowPart,
                                  unsigned __int64 _HighPart,
                                  unsigned char _Shift);
+static __inline__
 void __stosq(unsigned __int64 *, unsigned __int64, size_t);
+unsigned __int64 __umulh(unsigned __int64, unsigned __int64);
+unsigned char __vmx_on(unsigned __int64 *);
+unsigned char __vmx_vmclear(unsigned __int64 *);
+unsigned char __vmx_vmlaunch(void);
+unsigned char __vmx_vmptrld(unsigned __int64 *);
+unsigned char __vmx_vmread(size_t, size_t *);
+unsigned char __vmx_vmresume(void);
+unsigned char __vmx_vmwrite(size_t, size_t);
+void __writegsbyte(unsigned long, unsigned char);
+void __writegsdword(unsigned long, unsigned long);
+void __writegsqword(unsigned long, unsigned __int64);
+void __writegsword(unsigned long, unsigned short);
 unsigned __int64 _andn_u64(unsigned __int64, unsigned __int64);
 unsigned __int64 _bextr_u64(unsigned __int64, unsigned int, unsigned int);
 unsigned __int64 _bextri_u64(unsigned __int64, unsigned int);
@@ -336,7 +387,7 @@
 unsigned __int64 _blsfill_u64(unsigned __int64);
 unsigned __int64 _blsi_u64(unsigned __int64);
 unsigned __int64 _blsic_u64(unsigned __int64);
-unsigned __int64 _blmsk_u64(unsigned __int64);
+unsigned __int64 _blsmsk_u64(unsigned __int64);
 unsigned __int64 _blsr_u64(unsigned __int64);
 unsigned __int64 __cdecl _byteswap_uint64(unsigned __int64);
 unsigned __int64 _bzhi_u64(unsigned __int64, unsigned int);
@@ -347,6 +398,7 @@
 __int64 _InterlockedAnd64_np(__int64 volatile *_Value, __int64 _Mask);
 char _InterlockedAnd8_np(char volatile *_Value, char _Mask);
 unsigned char _interlockedbittestandreset64(__int64 volatile *, __int64);
+static __inline__
 unsigned char _interlockedbittestandset64(__int64 volatile *, __int64);
 long _InterlockedCompareExchange_np(long volatile *_Destination, long _Exchange,
                                     long _Comparand);
@@ -360,18 +412,38 @@
                                                 __int64 *_ComparandResult);
 short _InterlockedCompareExchange16_np(short volatile *_Destination,
                                        short _Exchange, short _Comparand);
+__int64 _InterlockedCompareExchange64_HLEAcquire(__int64 volatile *, __int64,
+                                                 __int64);
+__int64 _InterlockedCompareExchange64_HLERelease(__int64 volatile *, __int64,
+                                                 __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);
+static __inline__
+__int64 _InterlockedDecrement64(__int64 volatile *_Addend);
+static __inline__
+__int64 _InterlockedExchange64(__int64 volatile *_Target, __int64 _Value);
+static __inline__
+__int64 _InterlockedExchangeAdd64(__int64 volatile *_Addend, __int64 _Value);
+void *_InterlockedExchangePointer(void *volatile *_Target, void *_Value);
+static __inline__
+__int64 _InterlockedIncrement64(__int64 volatile *_Addend);
 long _InterlockedOr_np(long volatile *_Value, long _Mask);
 short _InterlockedOr16_np(short volatile *_Value, short _Mask);
+static __inline__
+__int64 _InterlockedOr64(__int64 volatile *_Value, __int64 _Mask);
 __int64 _InterlockedOr64_np(__int64 volatile *_Value, __int64 _Mask);
 char _InterlockedOr8_np(char volatile *_Value, char _Mask);
 long _InterlockedXor_np(long volatile *_Value, long _Mask);
 short _InterlockedXor16_np(short volatile *_Value, short _Mask);
+static __inline__
+__int64 _InterlockedXor64(__int64 volatile *_Value, __int64 _Mask);
 __int64 _InterlockedXor64_np(__int64 volatile *_Value, __int64 _Mask);
 char _InterlockedXor8_np(char volatile *_Value, char _Mask);
+static __inline__
 unsigned __int64 _lzcnt_u64(unsigned __int64);
 __int64 _mul128(__int64 _Multiplier, __int64 _Multiplicand,
                 __int64 *_HighProduct);
@@ -380,6 +452,12 @@
 unsigned int __cdecl _readgsbase_u32(void);
 unsigned __int64 __cdecl _readgsbase_u64(void);
 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);
 unsigned __int64 _tzcnt_u64(unsigned __int64);
 unsigned __int64 _tzmsk_u64(unsigned __int64);
 unsigned __int64 _umul128(unsigned __int64 _Multiplier,
@@ -503,6 +581,18 @@
   *a = *a | (1 << b);
   return x;
 }
+#if defined(__i386__) || defined(__x86_64__)
+static __inline__ unsigned char __attribute__((__always_inline__, __nodebug__))
+_interlockedbittestandset(long volatile *__BitBase, long __BitPos) {
+  unsigned char __Res;
+  __asm__ ("xor %0, %0\n"
+           "lock bts %2, %1\n"
+           "setc %0\n"
+           : "=r" (__Res), "+m"(*__BitBase)
+           : "Ir"(__BitPos));
+  return __Res;
+}
+#endif
 #ifdef __x86_64__
 static __inline__ unsigned char __attribute__((__always_inline__, __nodebug__))
 _BitScanForward64(unsigned long *_Index, unsigned __int64 _Mask) {
@@ -552,6 +642,16 @@
   *a = *a | (1ll << b);
   return x;
 }
+static __inline__ unsigned char __attribute__((__always_inline__, __nodebug__))
+_interlockedbittestandset64(__int64 volatile *__BitBase, __int64 __BitPos) {
+  unsigned char __Res;
+  __asm__ ("xor %0, %0\n"
+           "lock bts %2, %1\n"
+           "setc %0\n"
+           : "=r" (__Res), "+m"(*__BitBase)
+           : "Ir"(__BitPos));
+  return __Res;
+}
 #endif
 /*----------------------------------------------------------------------------*\
 |* Interlocked Exchange Add
@@ -564,10 +664,6 @@
 _InterlockedExchangeAdd16(short volatile *_Addend, short _Value) {
   return __atomic_add_fetch(_Addend, _Value, 0) - _Value;
 }
-static __inline__ long __attribute__((__always_inline__, __nodebug__))
-_InterlockedExchangeAdd(long volatile *_Addend, long _Value) {
-  return __atomic_add_fetch(_Addend, _Value, 0) - _Value;
-}
 #ifdef __x86_64__
 static __inline__ __int64 __attribute__((__always_inline__, __nodebug__))
 _InterlockedExchangeAdd64(__int64 volatile *_Addend, __int64 _Value) {
@@ -598,12 +694,8 @@
 /*----------------------------------------------------------------------------*\
 |* Interlocked Increment
 \*----------------------------------------------------------------------------*/
-static __inline__ char __attribute__((__always_inline__, __nodebug__))
-_InterlockedIncrement16(char volatile *_Value) {
-  return __atomic_add_fetch(_Value, 1, 0);
-}
-static __inline__ long __attribute__((__always_inline__, __nodebug__))
-_InterlockedIncrement(long volatile *_Value) {
+static __inline__ short __attribute__((__always_inline__, __nodebug__))
+_InterlockedIncrement16(short volatile *_Value) {
   return __atomic_add_fetch(_Value, 1, 0);
 }
 #ifdef __x86_64__
@@ -615,12 +707,8 @@
 /*----------------------------------------------------------------------------*\
 |* Interlocked Decrement
 \*----------------------------------------------------------------------------*/
-static __inline__ char __attribute__((__always_inline__, __nodebug__))
-_InterlockedDecrement16(char volatile *_Value) {
-  return __atomic_sub_fetch(_Value, 1, 0);
-}
-static __inline__ long __attribute__((__always_inline__, __nodebug__))
-_InterlockedDecrement(long volatile *_Value) {
+static __inline__ short __attribute__((__always_inline__, __nodebug__))
+_InterlockedDecrement16(short volatile *_Value) {
   return __atomic_sub_fetch(_Value, 1, 0);
 }
 #ifdef __x86_64__
@@ -705,11 +793,6 @@
   __atomic_exchange(_Target, &_Value, &_Value, 0);
   return _Value;
 }
-static __inline__ long __attribute__((__always_inline__, __nodebug__))
-_InterlockedExchange(long volatile *_Target, long _Value) {
-  __atomic_exchange(_Target, &_Value, &_Value, 0);
-  return _Value;
-}
 #ifdef __x86_64__
 static __inline__ __int64 __attribute__((__always_inline__, __nodebug__))
 _InterlockedExchange64(__int64 volatile *_Target, __int64 _Value) {
@@ -732,23 +815,16 @@
   __atomic_compare_exchange(_Destination, &_Comparand, &_Exchange, 0, 0, 0);
   return _Comparand;
 }
-static __inline__ long __attribute__((__always_inline__, __nodebug__))
-_InterlockedCompareExchange(long volatile *_Destination,
-                            long _Exchange, long _Comparand) {
-  __atomic_compare_exchange(_Destination, &_Comparand, &_Exchange, 0, 0, 0);
-  return _Comparand;
-}
-#ifdef __x86_64__
 static __inline__ __int64 __attribute__((__always_inline__, __nodebug__))
 _InterlockedCompareExchange64(__int64 volatile *_Destination,
                               __int64 _Exchange, __int64 _Comparand) {
   __atomic_compare_exchange(_Destination, &_Comparand, &_Exchange, 0, 0, 0);
   return _Comparand;
 }
-#endif
 /*----------------------------------------------------------------------------*\
 |* Barriers
 \*----------------------------------------------------------------------------*/
+#if defined(__i386__) || defined(__x86_64__)
 static __inline__ void __attribute__((__always_inline__, __nodebug__))
 __attribute__((deprecated("use other intrinsics or C++11 atomics instead")))
 _ReadWriteBarrier(void) {
@@ -764,6 +840,107 @@
 _WriteBarrier(void) {
   __asm__ volatile ("" : : : "memory");
 }
+#endif
+#ifdef __x86_64__
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+__faststorefence(void) {
+  __asm__ volatile("lock orq $0, (%%rsp)" : : : "memory");
+}
+#endif
+/*----------------------------------------------------------------------------*\
+|* readfs, readgs
+|* (Pointers in address space #256 and #257 are relative to the GS and FS
+|* segment registers, respectively.)
+\*----------------------------------------------------------------------------*/
+#define __ptr_to_addr_space(__addr_space_nbr, __type, __offset)              \
+    ((volatile __type __attribute__((__address_space__(__addr_space_nbr)))*) \
+    (__offset))
+
+#ifdef __i386__
+static __inline__ unsigned char __attribute__((__always_inline__, __nodebug__))
+__readfsbyte(unsigned long __offset) {
+  return *__ptr_to_addr_space(257, unsigned char, __offset);
+}
+static __inline__ unsigned long __attribute__((__always_inline__, __nodebug__))
+__readfsdword(unsigned long __offset) {
+  return *__ptr_to_addr_space(257, unsigned long, __offset);
+}
+static __inline__ unsigned __int64 __attribute__((__always_inline__, __nodebug__))
+__readfsqword(unsigned long __offset) {
+  return *__ptr_to_addr_space(257, unsigned __int64, __offset);
+}
+static __inline__ unsigned short __attribute__((__always_inline__, __nodebug__))
+__readfsword(unsigned long __offset) {
+  return *__ptr_to_addr_space(257, unsigned short, __offset);
+}
+#endif
+#ifdef __x86_64__
+static __inline__ unsigned char __attribute__((__always_inline__, __nodebug__))
+__readgsbyte(unsigned long __offset) {
+  return *__ptr_to_addr_space(256, unsigned char, __offset);
+}
+static __inline__ unsigned long __attribute__((__always_inline__, __nodebug__))
+__readgsdword(unsigned long __offset) {
+  return *__ptr_to_addr_space(256, unsigned long, __offset);
+}
+static __inline__ unsigned __int64 __attribute__((__always_inline__, __nodebug__))
+__readgsqword(unsigned long __offset) {
+  return *__ptr_to_addr_space(256, unsigned __int64, __offset);
+}
+static __inline__ unsigned short __attribute__((__always_inline__, __nodebug__))
+__readgsword(unsigned long __offset) {
+  return *__ptr_to_addr_space(256, unsigned short, __offset);
+}
+#endif
+#undef __ptr_to_addr_space
+/*----------------------------------------------------------------------------*\
+|* movs, stos
+\*----------------------------------------------------------------------------*/
+#if defined(__i386__) || defined(__x86_64__)
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+__movsb(unsigned char *__dst, unsigned char const *__src, size_t __n) {
+  __asm__("rep movsb" : : "D"(__dst), "S"(__src), "c"(__n)
+                        : "%edi", "%esi", "%ecx");
+}
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+__movsd(unsigned long *__dst, unsigned long const *__src, size_t __n) {
+  __asm__("rep movsl" : : "D"(__dst), "S"(__src), "c"(__n)
+                        : "%edi", "%esi", "%ecx");
+}
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+__movsw(unsigned short *__dst, unsigned short const *__src, size_t __n) {
+  __asm__("rep movsh" : : "D"(__dst), "S"(__src), "c"(__n)
+                        : "%edi", "%esi", "%ecx");
+}
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+__stosb(unsigned char *__dst, unsigned char __x, size_t __n) {
+  __asm__("rep stosb" : : "D"(__dst), "a"(__x), "c"(__n)
+                        : "%edi", "%ecx");
+}
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+__stosd(unsigned long *__dst, unsigned long __x, size_t __n) {
+  __asm__("rep stosl" : : "D"(__dst), "a"(__x), "c"(__n)
+                        : "%edi", "%ecx");
+}
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+__stosw(unsigned short *__dst, unsigned short __x, size_t __n) {
+  __asm__("rep stosh" : : "D"(__dst), "a"(__x), "c"(__n)
+                        : "%edi", "%ecx");
+}
+#endif
+#ifdef __x86_64__
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+__movsq(unsigned long long *__dst, unsigned long long const *__src, size_t __n) {
+  __asm__("rep movsq" : : "D"(__dst), "S"(__src), "c"(__n)
+                        : "%edi", "%esi", "%ecx");
+}
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+__stosq(unsigned __int64 *__dst, unsigned __int64 __x, size_t __n) {
+  __asm__("rep stosq" : : "D"(__dst), "a"(__x), "c"(__n)
+                        : "%edi", "%ecx");
+}
+#endif
+
 /*----------------------------------------------------------------------------*\
 |* Misc
 \*----------------------------------------------------------------------------*/
@@ -775,6 +952,59 @@
 _ReturnAddress(void) {
   return __builtin_return_address(0);
 }
+#if defined(__i386__) || defined(__x86_64__)
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+__cpuid(int __info[4], int __level) {
+  __asm__ ("cpuid" : "=a"(__info[0]), "=b" (__info[1]), "=c"(__info[2]), "=d"(__info[3])
+                   : "a"(__level));
+}
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+__cpuidex(int __info[4], int __level, int __ecx) {
+  __asm__ ("cpuid" : "=a"(__info[0]), "=b" (__info[1]), "=c"(__info[2]), "=d"(__info[3])
+                   : "a"(__level), "c"(__ecx));
+}
+static __inline__ unsigned __int64 __cdecl __attribute__((__always_inline__, __nodebug__))
+_xgetbv(unsigned int __xcr_no) {
+  unsigned int __eax, __edx;
+  __asm__ ("xgetbv" : "=a" (__eax), "=d" (__edx) : "c" (__xcr_no));
+  return ((unsigned __int64)__edx << 32) | __eax;
+}
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+__halt(void) {
+  __asm__ volatile ("hlt");
+}
+#endif
+
+/*----------------------------------------------------------------------------*\
+|* Privileged intrinsics
+\*----------------------------------------------------------------------------*/
+#if defined(__i386__) || defined(__x86_64__)
+static __inline__ unsigned __int64 __attribute__((__always_inline__, __nodebug__))
+__readmsr(unsigned long __register) {
+  // Loads the contents of a 64-bit model specific register (MSR) specified in
+  // the ECX register into registers EDX:EAX. The EDX register is loaded with
+  // the high-order 32 bits of the MSR and the EAX register is loaded with the
+  // low-order 32 bits. If less than 64 bits are implemented in the MSR being
+  // read, the values returned to EDX:EAX in unimplemented bit locations are
+  // undefined.
+  unsigned long __edx;
+  unsigned long __eax;
+  __asm__ ("rdmsr" : "=d"(__edx), "=a"(__eax) : "c"(__register));
+  return (((unsigned __int64)__edx) << 32) | (unsigned __int64)__eax;
+}
+
+static __inline__ unsigned long __attribute__((always_inline, __nodebug__))
+__readcr3(void) {
+  unsigned long __cr3_val;
+  __asm__ __volatile__ ("mov %%cr3, %0" : "=q"(__cr3_val) : : "memory");
+  return __cr3_val;
+}
+
+static __inline__ void __attribute__((always_inline, __nodebug__))
+__writecr3(unsigned int __cr3_val) {
+  __asm__ ("mov %0, %%cr3" : : "q"(__cr3_val) : "memory");
+}
+#endif
 
 #ifdef __cplusplus
 }
diff --git a/lib/Headers/Makefile b/lib/Headers/Makefile
index 42219c4..903acac 100644
--- a/lib/Headers/Makefile
+++ b/lib/Headers/Makefile
@@ -32,13 +32,13 @@
 	$(Verb) cp $< $@
 	$(Echo) Copying $(notdir $<) to build dir
 
-$(HeaderDir)/module.map: $(PROJ_SRC_DIR)/module.map $(HeaderDir)/.dir
+$(HeaderDir)/module.modulemap: $(PROJ_SRC_DIR)/module.modulemap $(HeaderDir)/.dir
 	$(Verb) cp $< $@
 	$(Echo) Copying $(notdir $<) to build dir
 
 
 # Hook into the standard Makefile rules.
-all-local:: $(OBJHEADERS) $(HeaderDir)/module.map
+all-local:: $(OBJHEADERS) $(HeaderDir)/module.modulemap
 
 PROJ_headers := $(DESTDIR)$(PROJ_prefix)/lib/clang/$(CLANG_VERSION)/include
 
@@ -52,12 +52,12 @@
 	$(Verb) $(DataInstall) $< $(PROJ_headers)
 	$(Echo) Installing compiler include file: $(notdir $<)
 
-$(PROJ_headers)/module.map: $(HeaderDir)/module.map | $(PROJ_headers)
+$(PROJ_headers)/module.modulemap: $(HeaderDir)/module.modulemap | $(PROJ_headers)
 	$(Verb) $(DataInstall) $< $(PROJ_headers)
 	$(Echo) Installing compiler module map file: $(notdir $<)
 
 
-install-local:: $(INSTHEADERS) $(PROJ_headers)/module.map
+install-local:: $(INSTHEADERS) $(PROJ_headers)/module.modulemap
 
 $(ObjDir)/arm_neon.h.inc.tmp : $(CLANG_LEVEL)/include/clang/Basic/arm_neon.td $(CLANG_TBLGEN) $(ObjDir)/.dir
 	$(Echo) "Building Clang arm_neon.h.inc with tblgen"
diff --git a/lib/Headers/altivec.h b/lib/Headers/altivec.h
index 74ce08a..f9fc64a 100644
--- a/lib/Headers/altivec.h
+++ b/lib/Headers/altivec.h
@@ -73,6 +73,9 @@
 static vector float __ATTRS_o_ai
 vec_perm(vector float __a, vector float __b, vector unsigned char __c);
 
+static vector unsigned char __ATTRS_o_ai
+vec_xor(vector unsigned char __a, vector unsigned char __b);
+
 /* vec_abs */
 
 #define __builtin_altivec_abs_v16qi vec_abs
@@ -3485,30 +3488,49 @@
   __builtin_altivec_mtvscr((vector int)__a);
 }
 
+/* The vmulos* and vmules* instructions have a big endian bias, so
+   we must reverse the meaning of "even" and "odd" for little endian.  */
+
 /* vec_mule */
 
 static vector short __ATTRS_o_ai
 vec_mule(vector signed char __a, vector signed char __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmulosb(__a, __b);
+#else
   return __builtin_altivec_vmulesb(__a, __b);
+#endif
 }
 
 static vector unsigned short __ATTRS_o_ai
 vec_mule(vector unsigned char __a, vector unsigned char __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmuloub(__a, __b);
+#else
   return __builtin_altivec_vmuleub(__a, __b);
+#endif
 }
 
 static vector int __ATTRS_o_ai
 vec_mule(vector short __a, vector short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmulosh(__a, __b);
+#else
   return __builtin_altivec_vmulesh(__a, __b);
+#endif
 }
 
 static vector unsigned int __ATTRS_o_ai
 vec_mule(vector unsigned short __a, vector unsigned short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmulouh(__a, __b);
+#else
   return __builtin_altivec_vmuleuh(__a, __b);
+#endif
 }
 
 /* vec_vmulesb */
@@ -3516,7 +3538,11 @@
 static vector short __attribute__((__always_inline__))
 vec_vmulesb(vector signed char __a, vector signed char __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmulosb(__a, __b);
+#else
   return __builtin_altivec_vmulesb(__a, __b);
+#endif
 }
 
 /* vec_vmuleub */
@@ -3524,7 +3550,11 @@
 static vector unsigned short __attribute__((__always_inline__))
 vec_vmuleub(vector unsigned char __a, vector unsigned char __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmuloub(__a, __b);
+#else
   return __builtin_altivec_vmuleub(__a, __b);
+#endif
 }
 
 /* vec_vmulesh */
@@ -3532,7 +3562,11 @@
 static vector int __attribute__((__always_inline__))
 vec_vmulesh(vector short __a, vector short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmulosh(__a, __b);
+#else
   return __builtin_altivec_vmulesh(__a, __b);
+#endif
 }
 
 /* vec_vmuleuh */
@@ -3540,7 +3574,11 @@
 static vector unsigned int __attribute__((__always_inline__))
 vec_vmuleuh(vector unsigned short __a, vector unsigned short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmulouh(__a, __b);
+#else
   return __builtin_altivec_vmuleuh(__a, __b);
+#endif
 }
 
 /* vec_mulo */
@@ -3548,25 +3586,41 @@
 static vector short __ATTRS_o_ai
 vec_mulo(vector signed char __a, vector signed char __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmulesb(__a, __b);
+#else
   return __builtin_altivec_vmulosb(__a, __b);
+#endif
 }
 
 static vector unsigned short __ATTRS_o_ai
 vec_mulo(vector unsigned char __a, vector unsigned char __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmuleub(__a, __b);
+#else
   return __builtin_altivec_vmuloub(__a, __b);
+#endif
 }
 
 static vector int __ATTRS_o_ai
 vec_mulo(vector short __a, vector short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmulesh(__a, __b);
+#else
   return __builtin_altivec_vmulosh(__a, __b);
+#endif
 }
 
 static vector unsigned int __ATTRS_o_ai
 vec_mulo(vector unsigned short __a, vector unsigned short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmuleuh(__a, __b);
+#else
   return __builtin_altivec_vmulouh(__a, __b);
+#endif
 }
 
 /* vec_vmulosb */
@@ -3574,7 +3628,11 @@
 static vector short __attribute__((__always_inline__))
 vec_vmulosb(vector signed char __a, vector signed char __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmulesb(__a, __b);
+#else
   return __builtin_altivec_vmulosb(__a, __b);
+#endif
 }
 
 /* vec_vmuloub */
@@ -3582,7 +3640,11 @@
 static vector unsigned short __attribute__((__always_inline__))
 vec_vmuloub(vector unsigned char __a, vector unsigned char __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmuleub(__a, __b);
+#else
   return __builtin_altivec_vmuloub(__a, __b);
+#endif
 }
 
 /* vec_vmulosh */
@@ -3590,7 +3652,11 @@
 static vector int __attribute__((__always_inline__))
 vec_vmulosh(vector short __a, vector short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmulesh(__a, __b);
+#else
   return __builtin_altivec_vmulosh(__a, __b);
+#endif
 }
 
 /* vec_vmulouh */
@@ -3598,7 +3664,11 @@
 static vector unsigned int __attribute__((__always_inline__))
 vec_vmulouh(vector unsigned short __a, vector unsigned short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vmuleuh(__a, __b);
+#else
   return __builtin_altivec_vmulouh(__a, __b);
+#endif
 }
 
 /* vec_nmsub */
@@ -4047,52 +4117,91 @@
 
 /* vec_pack */
 
+/* The various vector pack instructions have a big-endian bias, so for
+   little endian we must handle reversed element numbering.  */
+
 static vector signed char __ATTRS_o_ai
 vec_pack(vector signed short __a, vector signed short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector signed char)vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E,
+     0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E));
+#else
   return (vector signed char)vec_perm(__a, __b, (vector unsigned char)
     (0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F,
      0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F));
+#endif
 }
 
 static vector unsigned char __ATTRS_o_ai
 vec_pack(vector unsigned short __a, vector unsigned short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector unsigned char)vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E,
+     0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E));
+#else
   return (vector unsigned char)vec_perm(__a, __b, (vector unsigned char)
     (0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F,
      0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F));
+#endif
 }
 
 static vector bool char __ATTRS_o_ai
 vec_pack(vector bool short __a, vector bool short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector bool char)vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E,
+     0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E));
+#else
   return (vector bool char)vec_perm(__a, __b, (vector unsigned char)
     (0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F,
      0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F));
+#endif
 }
 
 static vector short __ATTRS_o_ai
 vec_pack(vector int __a, vector int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector short)vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0C, 0x0D,
+     0x10, 0x11, 0x14, 0x15, 0x18, 0x19, 0x1C, 0x1D));
+#else
   return (vector short)vec_perm(__a, __b, (vector unsigned char)
     (0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F,
      0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F));
+#endif
 }
 
 static vector unsigned short __ATTRS_o_ai
 vec_pack(vector unsigned int __a, vector unsigned int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector unsigned short)vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0C, 0x0D,
+     0x10, 0x11, 0x14, 0x15, 0x18, 0x19, 0x1C, 0x1D));
+#else
   return (vector unsigned short)vec_perm(__a, __b, (vector unsigned char)
     (0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F,
      0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F));
+#endif
 }
 
 static vector bool short __ATTRS_o_ai
 vec_pack(vector bool int __a, vector bool int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector bool short)vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0C, 0x0D,
+     0x10, 0x11, 0x14, 0x15, 0x18, 0x19, 0x1C, 0x1D));
+#else
   return (vector bool short)vec_perm(__a, __b, (vector unsigned char)
     (0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F,
      0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F));
+#endif
 }
 
 /* vec_vpkuhum */
@@ -4102,25 +4211,43 @@
 static vector signed char __ATTRS_o_ai
 vec_vpkuhum(vector signed short __a, vector signed short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector signed char)vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E,
+     0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E));
+#else
   return (vector signed char)vec_perm(__a, __b, (vector unsigned char)
     (0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F,
      0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F));
+#endif
 }
 
 static vector unsigned char __ATTRS_o_ai
 vec_vpkuhum(vector unsigned short __a, vector unsigned short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector unsigned char)vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E,
+     0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E));
+#else
   return (vector unsigned char)vec_perm(__a, __b, (vector unsigned char)
     (0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F,
      0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F));
+#endif
 }
 
 static vector bool char __ATTRS_o_ai
 vec_vpkuhum(vector bool short __a, vector bool short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector bool char)vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E,
+     0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E));
+#else
   return (vector bool char)vec_perm(__a, __b, (vector unsigned char)
     (0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F,
      0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F));
+#endif
 }
 
 /* vec_vpkuwum */
@@ -4130,25 +4257,43 @@
 static vector short __ATTRS_o_ai
 vec_vpkuwum(vector int __a, vector int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector short)vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0C, 0x0D,
+     0x10, 0x11, 0x14, 0x15, 0x18, 0x19, 0x1C, 0x1D));
+#else
   return (vector short)vec_perm(__a, __b, (vector unsigned char)
     (0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F,
      0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F));
+#endif
 }
 
 static vector unsigned short __ATTRS_o_ai
 vec_vpkuwum(vector unsigned int __a, vector unsigned int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector unsigned short)vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0C, 0x0D,
+     0x10, 0x11, 0x14, 0x15, 0x18, 0x19, 0x1C, 0x1D));
+#else
   return (vector unsigned short)vec_perm(__a, __b, (vector unsigned char)
     (0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F,
      0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F));
+#endif
 }
 
 static vector bool short __ATTRS_o_ai
 vec_vpkuwum(vector bool int __a, vector bool int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector bool short)vec_perm(__a, __b, (vector unsigned char)
+    (0x00, 0x01, 0x04, 0x05, 0x08, 0x09, 0x0C, 0x0D,
+     0x10, 0x11, 0x14, 0x15, 0x18, 0x19, 0x1C, 0x1D));
+#else
   return (vector bool short)vec_perm(__a, __b, (vector unsigned char)
     (0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F,
      0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F));
+#endif
 }
 
 /* vec_packpx */
@@ -4156,7 +4301,11 @@
 static vector pixel __attribute__((__always_inline__))
 vec_packpx(vector unsigned int __a, vector unsigned int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector pixel)__builtin_altivec_vpkpx(__b, __a);
+#else
   return (vector pixel)__builtin_altivec_vpkpx(__a, __b);
+#endif
 }
 
 /* vec_vpkpx */
@@ -4164,7 +4313,11 @@
 static vector pixel __attribute__((__always_inline__))
 vec_vpkpx(vector unsigned int __a, vector unsigned int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector pixel)__builtin_altivec_vpkpx(__b, __a);
+#else
   return (vector pixel)__builtin_altivec_vpkpx(__a, __b);
+#endif
 }
 
 /* vec_packs */
@@ -4172,25 +4325,41 @@
 static vector signed char __ATTRS_o_ai
 vec_packs(vector short __a, vector short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkshss(__b, __a);
+#else
   return __builtin_altivec_vpkshss(__a, __b);
+#endif
 }
 
 static vector unsigned char __ATTRS_o_ai
 vec_packs(vector unsigned short __a, vector unsigned short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkuhus(__b, __a);
+#else
   return __builtin_altivec_vpkuhus(__a, __b);
+#endif
 }
 
 static vector signed short __ATTRS_o_ai
 vec_packs(vector int __a, vector int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkswss(__b, __a);
+#else
   return __builtin_altivec_vpkswss(__a, __b);
+#endif
 }
 
 static vector unsigned short __ATTRS_o_ai
 vec_packs(vector unsigned int __a, vector unsigned int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkuwus(__b, __a);
+#else
   return __builtin_altivec_vpkuwus(__a, __b);
+#endif
 }
 
 /* vec_vpkshss */
@@ -4198,7 +4367,11 @@
 static vector signed char __attribute__((__always_inline__))
 vec_vpkshss(vector short __a, vector short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkshss(__b, __a);
+#else
   return __builtin_altivec_vpkshss(__a, __b);
+#endif
 }
 
 /* vec_vpkuhus */
@@ -4206,7 +4379,11 @@
 static vector unsigned char __attribute__((__always_inline__))
 vec_vpkuhus(vector unsigned short __a, vector unsigned short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkuhus(__b, __a);
+#else
   return __builtin_altivec_vpkuhus(__a, __b);
+#endif
 }
 
 /* vec_vpkswss */
@@ -4214,7 +4391,11 @@
 static vector signed short __attribute__((__always_inline__))
 vec_vpkswss(vector int __a, vector int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkswss(__b, __a);
+#else
   return __builtin_altivec_vpkswss(__a, __b);
+#endif
 }
 
 /* vec_vpkuwus */
@@ -4222,7 +4403,11 @@
 static vector unsigned short __attribute__((__always_inline__))
 vec_vpkuwus(vector unsigned int __a, vector unsigned int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkuwus(__b, __a);
+#else
   return __builtin_altivec_vpkuwus(__a, __b);
+#endif
 }
 
 /* vec_packsu */
@@ -4230,25 +4415,41 @@
 static vector unsigned char __ATTRS_o_ai
 vec_packsu(vector short __a, vector short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkshus(__b, __a);
+#else
   return __builtin_altivec_vpkshus(__a, __b);
+#endif
 }
 
 static vector unsigned char __ATTRS_o_ai
 vec_packsu(vector unsigned short __a, vector unsigned short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkuhus(__b, __a);
+#else
   return __builtin_altivec_vpkuhus(__a, __b);
+#endif
 }
 
 static vector unsigned short __ATTRS_o_ai
 vec_packsu(vector int __a, vector int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkswus(__b, __a);
+#else
   return __builtin_altivec_vpkswus(__a, __b);
+#endif
 }
 
 static vector unsigned short __ATTRS_o_ai
 vec_packsu(vector unsigned int __a, vector unsigned int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkuwus(__b, __a);
+#else
   return __builtin_altivec_vpkuwus(__a, __b);
+#endif
 }
 
 /* vec_vpkshus */
@@ -4256,13 +4457,21 @@
 static vector unsigned char __ATTRS_o_ai
 vec_vpkshus(vector short __a, vector short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkshus(__b, __a);
+#else
   return __builtin_altivec_vpkshus(__a, __b);
+#endif
 }
 
 static vector unsigned char __ATTRS_o_ai
 vec_vpkshus(vector unsigned short __a, vector unsigned short __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkuhus(__b, __a);
+#else
   return __builtin_altivec_vpkuhus(__a, __b);
+#endif
 }
 
 /* vec_vpkswus */
@@ -4270,22 +4479,46 @@
 static vector unsigned short __ATTRS_o_ai
 vec_vpkswus(vector int __a, vector int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkswus(__b, __a);
+#else
   return __builtin_altivec_vpkswus(__a, __b);
+#endif
 }
 
 static vector unsigned short __ATTRS_o_ai
 vec_vpkswus(vector unsigned int __a, vector unsigned int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vpkuwus(__b, __a);
+#else
   return __builtin_altivec_vpkuwus(__a, __b);
+#endif
 }
 
 /* vec_perm */
 
+// The vperm instruction is defined architecturally with a big-endian bias.
+// For little endian, we swap the input operands and invert the permute
+// control vector.  Only the rightmost 5 bits matter, so we could use
+// a vector of all 31s instead of all 255s to perform the inversion.
+// However, when the PCV is not a constant, using 255 has an advantage
+// in that the vec_xor can be recognized as a vec_nor (and for P8 and
+// later, possibly a vec_nand).
+
 vector signed char __ATTRS_o_ai
 vec_perm(vector signed char __a, vector signed char __b, vector unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector signed char)
+           __builtin_altivec_vperm_4si((vector int)__b, (vector int)__a, __d);
+#else
   return (vector signed char)
            __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+#endif
 }
 
 vector unsigned char __ATTRS_o_ai
@@ -4293,22 +4526,46 @@
          vector unsigned char __b,
          vector unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector unsigned char)
+           __builtin_altivec_vperm_4si((vector int)__b, (vector int)__a, __d);
+#else
   return (vector unsigned char)
            __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+#endif
 }
 
 vector bool char __ATTRS_o_ai
 vec_perm(vector bool char __a, vector bool char __b, vector unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector bool char)
+           __builtin_altivec_vperm_4si((vector int)__b, (vector int)__a, __d);
+#else
   return (vector bool char)
            __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+#endif
 }
 
 vector short __ATTRS_o_ai
 vec_perm(vector short __a, vector short __b, vector unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector short)
+           __builtin_altivec_vperm_4si((vector int)__b, (vector int)__a, __d);
+#else
   return (vector short)
            __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+#endif
 }
 
 vector unsigned short __ATTRS_o_ai
@@ -4316,49 +4573,104 @@
          vector unsigned short __b,
          vector unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector unsigned short)
+           __builtin_altivec_vperm_4si((vector int)__b, (vector int)__a, __d);
+#else
   return (vector unsigned short)
            __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+#endif
 }
 
 vector bool short __ATTRS_o_ai
 vec_perm(vector bool short __a, vector bool short __b, vector unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector bool short)
+           __builtin_altivec_vperm_4si((vector int)__b, (vector int)__a, __d);
+#else
   return (vector bool short)
            __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+#endif
 }
 
 vector pixel __ATTRS_o_ai
 vec_perm(vector pixel __a, vector pixel __b, vector unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector pixel)
+           __builtin_altivec_vperm_4si((vector int)__b, (vector int)__a, __d);
+#else
   return (vector pixel)
            __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+#endif
 }
 
 vector int __ATTRS_o_ai
 vec_perm(vector int __a, vector int __b, vector unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector int)__builtin_altivec_vperm_4si(__b, __a, __d);
+#else
   return (vector int)__builtin_altivec_vperm_4si(__a, __b, __c);
+#endif
 }
 
 vector unsigned int __ATTRS_o_ai
 vec_perm(vector unsigned int __a, vector unsigned int __b, vector unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector unsigned int)
+           __builtin_altivec_vperm_4si((vector int)__b, (vector int)__a, __d);
+#else
   return (vector unsigned int)
            __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+#endif
 }
 
 vector bool int __ATTRS_o_ai
 vec_perm(vector bool int __a, vector bool int __b, vector unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector bool int)
+           __builtin_altivec_vperm_4si((vector int)__b, (vector int)__a, __d);
+#else
   return (vector bool int)
            __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+#endif
 }
 
 vector float __ATTRS_o_ai
 vec_perm(vector float __a, vector float __b, vector unsigned char __c)
 {
+#ifdef __LITTLE_ENDIAN__
+  vector unsigned char __d = {255,255,255,255,255,255,255,255,
+                              255,255,255,255,255,255,255,255};
+  __d = vec_xor(__c, __d);
+  return (vector float)
+           __builtin_altivec_vperm_4si((vector int)__b, (vector int)__a, __d);
+#else
   return (vector float)
            __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+#endif
 }
 
 /* vec_vperm */
@@ -4366,8 +4678,7 @@
 static vector signed char __ATTRS_o_ai
 vec_vperm(vector signed char __a, vector signed char __b, vector unsigned char __c)
 {
-  return (vector signed char)
-           __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+  return vec_perm(__a, __b, __c);
 }
 
 static vector unsigned char __ATTRS_o_ai
@@ -4375,22 +4686,19 @@
           vector unsigned char __b,
           vector unsigned char __c)
 {
-  return (vector unsigned char)
-           __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+  return vec_perm(__a, __b, __c);
 }
 
 static vector bool char __ATTRS_o_ai
 vec_vperm(vector bool char __a, vector bool char __b, vector unsigned char __c)
 {
-  return (vector bool char)
-           __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+  return vec_perm(__a, __b, __c);
 }
 
 static vector short __ATTRS_o_ai
 vec_vperm(vector short __a, vector short __b, vector unsigned char __c)
 {
-  return (vector short)
-           __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+  return vec_perm(__a, __b, __c);
 }
 
 static vector unsigned short __ATTRS_o_ai
@@ -4398,49 +4706,43 @@
           vector unsigned short __b,
           vector unsigned char __c)
 {
-  return (vector unsigned short)
-           __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+  return vec_perm(__a, __b, __c);
 }
 
 static vector bool short __ATTRS_o_ai
 vec_vperm(vector bool short __a, vector bool short __b, vector unsigned char __c)
 {
-  return (vector bool short)
-           __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+  return vec_perm(__a, __b, __c);
 }
 
 static vector pixel __ATTRS_o_ai
 vec_vperm(vector pixel __a, vector pixel __b, vector unsigned char __c)
 {
-  return (vector pixel)
-           __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+  return vec_perm(__a, __b, __c);
 }
 
 static vector int __ATTRS_o_ai
 vec_vperm(vector int __a, vector int __b, vector unsigned char __c)
 {
-  return (vector int)__builtin_altivec_vperm_4si(__a, __b, __c);
+  return vec_perm(__a, __b, __c);
 }
 
 static vector unsigned int __ATTRS_o_ai
 vec_vperm(vector unsigned int __a, vector unsigned int __b, vector unsigned char __c)
 {
-  return (vector unsigned int)
-           __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+  return vec_perm(__a, __b, __c);
 }
 
 static vector bool int __ATTRS_o_ai
 vec_vperm(vector bool int __a, vector bool int __b, vector unsigned char __c)
 {
-  return (vector bool int)
-           __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+  return vec_perm(__a, __b, __c);
 }
 
 static vector float __ATTRS_o_ai
 vec_vperm(vector float __a, vector float __b, vector unsigned char __c)
 {
-  return (vector float)
-           __builtin_altivec_vperm_4si((vector int)__a, (vector int)__b, __c);
+  return vec_perm(__a, __b, __c);
 }
 
 /* vec_re */
@@ -8054,10 +8356,26 @@
 
 /* vec_sum2s */
 
+/* The vsum2sws instruction has a big-endian bias, so that the second
+   input vector and the result always reference big-endian elements
+   1 and 3 (little-endian element 0 and 2).  For ease of porting the
+   programmer wants elements 1 and 3 in both cases, so for little
+   endian we must perform some permutes.  */
+
 static vector signed int __attribute__((__always_inline__))
 vec_sum2s(vector int __a, vector int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  vector int __c = (vector signed int)
+    vec_perm(__b, __b, (vector unsigned char)
+	     (4,5,6,7,0,1,2,3,12,13,14,15,8,9,10,11));
+  __c = __builtin_altivec_vsum2sws(__a, __c);
+  return (vector signed int)
+    vec_perm(__c, __c, (vector unsigned char)
+	     (4,5,6,7,0,1,2,3,12,13,14,15,8,9,10,11));
+#else
   return __builtin_altivec_vsum2sws(__a, __b);
+#endif
 }
 
 /* vec_vsum2sws */
@@ -8065,15 +8383,37 @@
 static vector signed int __attribute__((__always_inline__))
 vec_vsum2sws(vector int __a, vector int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  vector int __c = (vector signed int)
+    vec_perm(__b, __b, (vector unsigned char)
+	     (4,5,6,7,0,1,2,3,12,13,14,15,8,9,10,11));
+  __c = __builtin_altivec_vsum2sws(__a, __c);
+  return (vector signed int)
+    vec_perm(__c, __c, (vector unsigned char)
+	     (4,5,6,7,0,1,2,3,12,13,14,15,8,9,10,11));
+#else
   return __builtin_altivec_vsum2sws(__a, __b);
+#endif
 }
 
 /* vec_sums */
 
+/* The vsumsws instruction has a big-endian bias, so that the second
+   input vector and the result always reference big-endian element 3
+   (little-endian element 0).  For ease of porting the programmer
+   wants element 3 in both cases, so for little endian we must perform
+   some permutes.  */
+
 static vector signed int __attribute__((__always_inline__))
 vec_sums(vector signed int __a, vector signed int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  __b = (vector signed int)vec_splat(__b, 3);
+  __b = __builtin_altivec_vsumsws(__a, __b);
+  return (vector signed int)(0, 0, 0, __b[0]);
+#else
   return __builtin_altivec_vsumsws(__a, __b);
+#endif
 }
 
 /* vec_vsumsws */
@@ -8081,7 +8421,13 @@
 static vector signed int __attribute__((__always_inline__))
 vec_vsumsws(vector signed int __a, vector signed int __b)
 {
+#ifdef __LITTLE_ENDIAN__
+  __b = (vector signed int)vec_splat(__b, 3);
+  __b = __builtin_altivec_vsumsws(__a, __b);
+  return (vector signed int)(0, 0, 0, __b[0]);
+#else
   return __builtin_altivec_vsumsws(__a, __b);
+#endif
 }
 
 /* vec_trunc */
@@ -8102,34 +8448,57 @@
 
 /* vec_unpackh */
 
+/* The vector unpack instructions all have a big-endian bias, so for
+   little endian we must reverse the meanings of "high" and "low."  */
+
 static vector short __ATTRS_o_ai
 vec_unpackh(vector signed char __a)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vupklsb((vector char)__a);
+#else
   return __builtin_altivec_vupkhsb((vector char)__a);
+#endif
 }
 
 static vector bool short __ATTRS_o_ai
 vec_unpackh(vector bool char __a)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector bool short)__builtin_altivec_vupklsb((vector char)__a);
+#else
   return (vector bool short)__builtin_altivec_vupkhsb((vector char)__a);
+#endif
 }
 
 static vector int __ATTRS_o_ai
 vec_unpackh(vector short __a)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vupklsh(__a);
+#else
   return __builtin_altivec_vupkhsh(__a);
+#endif
 }
 
 static vector bool int __ATTRS_o_ai
 vec_unpackh(vector bool short __a)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector bool int)__builtin_altivec_vupklsh((vector short)__a);
+#else
   return (vector bool int)__builtin_altivec_vupkhsh((vector short)__a);
+#endif
 }
 
 static vector unsigned int __ATTRS_o_ai
 vec_unpackh(vector pixel __a)
 {
-  return (vector unsigned int)__builtin_altivec_vupkhsh((vector short)__a);
+#ifdef __LITTLE_ENDIAN__
+  return (vector unsigned int)__builtin_altivec_vupklpx((vector short)__a);
+#else
+  return (vector unsigned int)__builtin_altivec_vupkhpx((vector short)__a);
+#endif
 }
 
 /* vec_vupkhsb */
@@ -8137,13 +8506,21 @@
 static vector short __ATTRS_o_ai
 vec_vupkhsb(vector signed char __a)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vupklsb((vector char)__a);
+#else
   return __builtin_altivec_vupkhsb((vector char)__a);
+#endif
 }
 
 static vector bool short __ATTRS_o_ai
 vec_vupkhsb(vector bool char __a)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector bool short)__builtin_altivec_vupklsb((vector char)__a);
+#else
   return (vector bool short)__builtin_altivec_vupkhsb((vector char)__a);
+#endif
 }
 
 /* vec_vupkhsh */
@@ -8151,19 +8528,31 @@
 static vector int __ATTRS_o_ai
 vec_vupkhsh(vector short __a)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vupklsh(__a);
+#else
   return __builtin_altivec_vupkhsh(__a);
+#endif
 }
 
 static vector bool int __ATTRS_o_ai
 vec_vupkhsh(vector bool short __a)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector bool int)__builtin_altivec_vupklsh((vector short)__a);
+#else
   return (vector bool int)__builtin_altivec_vupkhsh((vector short)__a);
+#endif
 }
 
 static vector unsigned int __ATTRS_o_ai
 vec_vupkhsh(vector pixel __a)
 {
-  return (vector unsigned int)__builtin_altivec_vupkhsh((vector short)__a);
+#ifdef __LITTLE_ENDIAN__
+  return (vector unsigned int)__builtin_altivec_vupklpx((vector short)__a);
+#else
+  return (vector unsigned int)__builtin_altivec_vupkhpx((vector short)__a);
+#endif
 }
 
 /* vec_unpackl */
@@ -8171,31 +8560,51 @@
 static vector short __ATTRS_o_ai
 vec_unpackl(vector signed char __a)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vupkhsb((vector char)__a);
+#else
   return __builtin_altivec_vupklsb((vector char)__a);
+#endif
 }
 
 static vector bool short __ATTRS_o_ai
 vec_unpackl(vector bool char __a)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector bool short)__builtin_altivec_vupkhsb((vector char)__a);
+#else
   return (vector bool short)__builtin_altivec_vupklsb((vector char)__a);
+#endif
 }
 
 static vector int __ATTRS_o_ai
 vec_unpackl(vector short __a)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vupkhsh(__a);
+#else
   return __builtin_altivec_vupklsh(__a);
+#endif
 }
 
 static vector bool int __ATTRS_o_ai
 vec_unpackl(vector bool short __a)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector bool int)__builtin_altivec_vupkhsh((vector short)__a);
+#else
   return (vector bool int)__builtin_altivec_vupklsh((vector short)__a);
+#endif
 }
 
 static vector unsigned int __ATTRS_o_ai
 vec_unpackl(vector pixel __a)
 {
-  return (vector unsigned int)__builtin_altivec_vupklsh((vector short)__a);
+#ifdef __LITTLE_ENDIAN__
+  return (vector unsigned int)__builtin_altivec_vupkhpx((vector short)__a);
+#else
+  return (vector unsigned int)__builtin_altivec_vupklpx((vector short)__a);
+#endif
 }
 
 /* vec_vupklsb */
@@ -8203,13 +8612,21 @@
 static vector short __ATTRS_o_ai
 vec_vupklsb(vector signed char __a)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vupkhsb((vector char)__a);
+#else
   return __builtin_altivec_vupklsb((vector char)__a);
+#endif
 }
 
 static vector bool short __ATTRS_o_ai
 vec_vupklsb(vector bool char __a)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector bool short)__builtin_altivec_vupkhsb((vector char)__a);
+#else
   return (vector bool short)__builtin_altivec_vupklsb((vector char)__a);
+#endif
 }
 
 /* vec_vupklsh */
@@ -8217,19 +8634,31 @@
 static vector int __ATTRS_o_ai
 vec_vupklsh(vector short __a)
 {
+#ifdef __LITTLE_ENDIAN__
+  return __builtin_altivec_vupkhsh(__a);
+#else
   return __builtin_altivec_vupklsh(__a);
+#endif
 }
 
 static vector bool int __ATTRS_o_ai
 vec_vupklsh(vector bool short __a)
 {
+#ifdef __LITTLE_ENDIAN__
+  return (vector bool int)__builtin_altivec_vupkhsh((vector short)__a);
+#else
   return (vector bool int)__builtin_altivec_vupklsh((vector short)__a);
+#endif
 }
 
 static vector unsigned int __ATTRS_o_ai
 vec_vupklsh(vector pixel __a)
 {
-  return (vector unsigned int)__builtin_altivec_vupklsh((vector short)__a);
+#ifdef __LITTLE_ENDIAN__
+  return (vector unsigned int)__builtin_altivec_vupkhpx((vector short)__a);
+#else
+  return (vector unsigned int)__builtin_altivec_vupklpx((vector short)__a);
+#endif
 }
 
 /* vec_xor */
diff --git a/lib/Headers/arm_acle.h b/lib/Headers/arm_acle.h
new file mode 100644
index 0000000..a0fd689
--- /dev/null
+++ b/lib/Headers/arm_acle.h
@@ -0,0 +1,191 @@
+/*===---- arm_acle.h - ARM Non-Neon intrinsics -----------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __ARM_ACLE_H
+#define __ARM_ACLE_H
+
+#ifndef __ARM_ACLE
+#error "ACLE intrinsics support not enabled."
+#endif
+
+#include <stdint.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* 8 SYNCHRONIZATION, BARRIER AND HINT INTRINSICS */
+/* 8.3 Memory barriers */
+#if !defined(_MSC_VER)
+#define __dmb(i) __builtin_arm_dmb(i)
+#define __dsb(i) __builtin_arm_dsb(i)
+#define __isb(i) __builtin_arm_isb(i)
+#endif
+
+/* 8.4 Hints */
+
+#if !defined(_MSC_VER)
+static __inline__ void __attribute__((always_inline, nodebug)) __wfi(void) {
+  __builtin_arm_wfi();
+}
+
+static __inline__ void __attribute__((always_inline, nodebug)) __wfe(void) {
+  __builtin_arm_wfe();
+}
+
+static __inline__ void __attribute__((always_inline, nodebug)) __sev(void) {
+  __builtin_arm_sev();
+}
+
+static __inline__ void __attribute__((always_inline, nodebug)) __sevl(void) {
+  __builtin_arm_sevl();
+}
+
+static __inline__ void __attribute__((always_inline, nodebug)) __yield(void) {
+  __builtin_arm_yield();
+}
+#endif
+
+/* 8.7 NOP */
+static __inline__ void __attribute__((always_inline, nodebug)) __nop(void) {
+  __builtin_arm_nop();
+}
+
+/* 9 DATA-PROCESSING INTRINSICS */
+/* 9.2 Miscellaneous data-processing intrinsics */
+static __inline__ uint32_t __attribute__((always_inline, nodebug))
+  __clz(uint32_t t) {
+  return __builtin_clz(t);
+}
+
+static __inline__ unsigned long __attribute__((always_inline, nodebug))
+  __clzl(unsigned long t) {
+  return __builtin_clzl(t);
+}
+
+static __inline__ uint64_t __attribute__((always_inline, nodebug))
+  __clzll(uint64_t t) {
+#if __SIZEOF_LONG_LONG__ == 8
+  return __builtin_clzll(t);
+#else
+  return __builtin_clzl(t);
+#endif
+}
+
+static __inline__ uint32_t __attribute__((always_inline, nodebug))
+  __rev(uint32_t t) {
+  return __builtin_bswap32(t);
+}
+
+static __inline__ unsigned long __attribute__((always_inline, nodebug))
+  __revl(unsigned long t) {
+#if __SIZEOF_LONG__ == 4
+  return __builtin_bswap32(t);
+#else
+  return __builtin_bswap64(t);
+#endif
+}
+
+static __inline__ uint64_t __attribute__((always_inline, nodebug))
+  __revll(uint64_t t) {
+  return __builtin_bswap64(t);
+}
+
+/*
+ * 9.4 Saturating intrinsics
+ *
+ * FIXME: Change guard to their corrosponding __ARM_FEATURE flag when Q flag
+ * intrinsics are implemented and the flag is enabled.
+ */
+/* 9.4.1 Width-specified saturation intrinsics */
+#if __ARM_32BIT_STATE
+#define __ssat(x, y) __builtin_arm_ssat(x, y)
+#define __usat(x, y) __builtin_arm_usat(x, y)
+#endif
+
+/* 9.4.2 Saturating addition and subtraction intrinsics */
+#if __ARM_32BIT_STATE
+static __inline__ int32_t __attribute__((always_inline, nodebug))
+  __qadd(int32_t t, int32_t v) {
+  return __builtin_arm_qadd(t, v);
+}
+
+static __inline__ int32_t __attribute__((always_inline, nodebug))
+  __qsub(int32_t t, int32_t v) {
+  return __builtin_arm_qsub(t, v);
+}
+
+static __inline__ int32_t __attribute__((always_inline, nodebug))
+__qdbl(int32_t t) {
+  return __builtin_arm_qadd(t, t);
+}
+#endif
+
+/* 9.7 CRC32 intrinsics */
+#if __ARM_FEATURE_CRC32
+static __inline__ uint32_t __attribute__((always_inline, nodebug))
+  __crc32b(uint32_t a, uint8_t b) {
+  return __builtin_arm_crc32b(a, b);
+}
+
+static __inline__ uint32_t __attribute__((always_inline, nodebug))
+  __crc32h(uint32_t a, uint16_t b) {
+  return __builtin_arm_crc32h(a, b);
+}
+
+static __inline__ uint32_t __attribute__((always_inline, nodebug))
+  __crc32w(uint32_t a, uint32_t b) {
+  return __builtin_arm_crc32w(a, b);
+}
+
+static __inline__ uint32_t __attribute__((always_inline, nodebug))
+  __crc32d(uint32_t a, uint64_t b) {
+  return __builtin_arm_crc32d(a, b);
+}
+
+static __inline__ uint32_t __attribute__((always_inline, nodebug))
+  __crc32cb(uint32_t a, uint8_t b) {
+  return __builtin_arm_crc32cb(a, b);
+}
+
+static __inline__ uint32_t __attribute__((always_inline, nodebug))
+  __crc32ch(uint32_t a, uint16_t b) {
+  return __builtin_arm_crc32ch(a, b);
+}
+
+static __inline__ uint32_t __attribute__((always_inline, nodebug))
+  __crc32cw(uint32_t a, uint32_t b) {
+  return __builtin_arm_crc32cw(a, b);
+}
+
+static __inline__ uint32_t __attribute__((always_inline, nodebug))
+  __crc32cd(uint32_t a, uint64_t b) {
+  return __builtin_arm_crc32cd(a, b);
+}
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __ARM_ACLE_H */
diff --git a/lib/Headers/avx2intrin.h b/lib/Headers/avx2intrin.h
index 9574469..394fdfe 100644
--- a/lib/Headers/avx2intrin.h
+++ b/lib/Headers/avx2intrin.h
@@ -160,7 +160,23 @@
 #define _mm256_blend_epi16(V1, V2, M) __extension__ ({ \
   __m256i __V1 = (V1); \
   __m256i __V2 = (V2); \
-  (__m256i)__builtin_ia32_pblendw256((__v16hi)__V1, (__v16hi)__V2, (M)); })
+  (__m256d)__builtin_shufflevector((__v16hi)__V1, (__v16hi)__V2, \
+                                   (((M) & 0x01) ? 16 : 0), \
+                                   (((M) & 0x02) ? 17 : 1), \
+                                   (((M) & 0x04) ? 18 : 2), \
+                                   (((M) & 0x08) ? 19 : 3), \
+                                   (((M) & 0x10) ? 20 : 4), \
+                                   (((M) & 0x20) ? 21 : 5), \
+                                   (((M) & 0x40) ? 22 : 6), \
+                                   (((M) & 0x80) ? 23 : 7), \
+                                   (((M) & 0x01) ? 24 : 8), \
+                                   (((M) & 0x02) ? 25 : 9), \
+                                   (((M) & 0x04) ? 26 : 10), \
+                                   (((M) & 0x08) ? 27 : 11), \
+                                   (((M) & 0x10) ? 28 : 12), \
+                                   (((M) & 0x20) ? 29 : 13), \
+                                   (((M) & 0x40) ? 30 : 14), \
+                                   (((M) & 0x80) ? 31 : 15)); })
 
 static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
 _mm256_cmpeq_epi8(__m256i __a, __m256i __b)
@@ -761,12 +777,24 @@
 #define _mm_blend_epi32(V1, V2, M) __extension__ ({ \
   __m128i __V1 = (V1); \
   __m128i __V2 = (V2); \
-  (__m128i)__builtin_ia32_pblendd128((__v4si)__V1, (__v4si)__V2, (M)); })
+  (__m128i)__builtin_shufflevector((__v4si)__V1, (__v4si)__V2, \
+                                   (((M) & 0x01) ? 4 : 0), \
+                                   (((M) & 0x02) ? 5 : 1), \
+                                   (((M) & 0x04) ? 6 : 2), \
+                                   (((M) & 0x08) ? 7 : 3)); })
 
 #define _mm256_blend_epi32(V1, V2, M) __extension__ ({ \
   __m256i __V1 = (V1); \
   __m256i __V2 = (V2); \
-  (__m256i)__builtin_ia32_pblendd256((__v8si)__V1, (__v8si)__V2, (M)); })
+  (__m256i)__builtin_shufflevector((__v8si)__V1, (__v8si)__V2, \
+                                   (((M) & 0x01) ?  8 : 0), \
+                                   (((M) & 0x02) ?  9 : 1), \
+                                   (((M) & 0x04) ? 10 : 2), \
+                                   (((M) & 0x08) ? 11 : 3), \
+                                   (((M) & 0x10) ? 12 : 4), \
+                                   (((M) & 0x20) ? 13 : 5), \
+                                   (((M) & 0x40) ? 14 : 6), \
+                                   (((M) & 0x80) ? 15 : 7)); })
 
 static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
 _mm256_broadcastb_epi8(__m128i __X)
diff --git a/lib/Headers/avxintrin.h b/lib/Headers/avxintrin.h
index 141c4d9..4e1044a 100644
--- a/lib/Headers/avxintrin.h
+++ b/lib/Headers/avxintrin.h
@@ -308,12 +308,24 @@
 #define _mm256_blend_pd(V1, V2, M) __extension__ ({ \
   __m256d __V1 = (V1); \
   __m256d __V2 = (V2); \
-  (__m256d)__builtin_ia32_blendpd256((__v4df)__V1, (__v4df)__V2, (M)); })
+  (__m256d)__builtin_shufflevector((__v4df)__V1, (__v4df)__V2, \
+                                   (((M) & 0x01) ? 4 : 0), \
+                                   (((M) & 0x02) ? 5 : 1), \
+                                   (((M) & 0x04) ? 6 : 2), \
+                                   (((M) & 0x08) ? 7 : 3)); })
 
 #define _mm256_blend_ps(V1, V2, M) __extension__ ({ \
   __m256 __V1 = (V1); \
   __m256 __V2 = (V2); \
-  (__m256)__builtin_ia32_blendps256((__v8sf)__V1, (__v8sf)__V2, (M)); })
+  (__m256)__builtin_shufflevector((__v8sf)__V1, (__v8sf)__V2, \
+                                  (((M) & 0x01) ?  8 : 0), \
+                                  (((M) & 0x02) ?  9 : 1), \
+                                  (((M) & 0x04) ? 10 : 2), \
+                                  (((M) & 0x08) ? 11 : 3), \
+                                  (((M) & 0x10) ? 12 : 4), \
+                                  (((M) & 0x20) ? 13 : 5), \
+                                  (((M) & 0x40) ? 14 : 6), \
+                                  (((M) & 0x80) ? 15 : 7)); })
 
 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
 _mm256_blendv_pd(__m256d __a, __m256d __b, __m256d __c)
@@ -725,19 +737,22 @@
 static __inline __m128 __attribute__((__always_inline__, __nodebug__))
 _mm_broadcast_ss(float const *__a)
 {
-  return (__m128)__builtin_ia32_vbroadcastss(__a);
+  float __f = *__a;
+  return (__m128)(__v4sf){ __f, __f, __f, __f };
 }
 
 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
 _mm256_broadcast_sd(double const *__a)
 {
-  return (__m256d)__builtin_ia32_vbroadcastsd256(__a);
+  double __d = *__a;
+  return (__m256d)(__v4df){ __d, __d, __d, __d };
 }
 
 static __inline __m256 __attribute__((__always_inline__, __nodebug__))
 _mm256_broadcast_ss(float const *__a)
 {
-  return (__m256)__builtin_ia32_vbroadcastss256(__a);
+  float __f = *__a;
+  return (__m256)(__v8sf){ __f, __f, __f, __f, __f, __f, __f, __f };
 }
 
 static __inline __m256d __attribute__((__always_inline__, __nodebug__))
diff --git a/lib/Headers/bmiintrin.h b/lib/Headers/bmiintrin.h
index 8cb00f5..43c4a5e 100644
--- a/lib/Headers/bmiintrin.h
+++ b/lib/Headers/bmiintrin.h
@@ -32,6 +32,14 @@
 #ifndef __BMIINTRIN_H
 #define __BMIINTRIN_H
 
+#define _tzcnt_u16(a)     (__tzcnt_u16((a)))
+#define _andn_u32(a, b)   (__andn_u32((a), (b)))
+/* _bextr_u32 != __bextr_u32 */
+#define _blsi_u32(a)      (__blsi_u32((a)))
+#define _blsmsk_u32(a)    (__blsmsk_u32((a)))
+#define _blsr_u32(a)      (__blsr_u32((a)))
+#define _tzcnt_u32(a)     (__tzcnt_u32((a)))
+
 static __inline__ unsigned short __attribute__((__always_inline__, __nodebug__))
 __tzcnt_u16(unsigned short __X)
 {
@@ -44,12 +52,20 @@
   return ~__X & __Y;
 }
 
+/* AMD-specified, double-leading-underscore version of BEXTR */
 static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
 __bextr_u32(unsigned int __X, unsigned int __Y)
 {
   return __builtin_ia32_bextr_u32(__X, __Y);
 }
 
+/* Intel-specified, single-leading-underscore version of BEXTR */
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+_bextr_u32(unsigned int __X, unsigned int __Y, unsigned int __Z)
+{
+  return __builtin_ia32_bextr_u32 (__X, ((__Y & 0xff) | ((__Z & 0xff) << 8)));
+}
+
 static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
 __blsi_u32(unsigned int __X)
 {
@@ -75,18 +91,34 @@
 }
 
 #ifdef __x86_64__
+
+#define _andn_u64(a, b)   (__andn_u64((a), (b)))
+/* _bextr_u64 != __bextr_u64 */
+#define _blsi_u64(a)      (__blsi_u64((a)))
+#define _blsmsk_u64(a)    (__blsmsk_u64((a)))
+#define _blsr_u64(a)      (__blsr_u64((a)))
+#define _tzcnt_u64(a)     (__tzcnt_u64((a)))
+
 static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
 __andn_u64 (unsigned long long __X, unsigned long long __Y)
 {
   return ~__X & __Y;
 }
 
+/* AMD-specified, double-leading-underscore version of BEXTR */
 static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
 __bextr_u64(unsigned long long __X, unsigned long long __Y)
 {
   return __builtin_ia32_bextr_u64(__X, __Y);
 }
 
+/* Intel-specified, single-leading-underscore version of BEXTR */
+static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
+_bextr_u64(unsigned long long __X, unsigned int __Y, unsigned int __Z)
+{
+  return __builtin_ia32_bextr_u64 (__X, ((__Y & 0xff) | ((__Z & 0xff) << 8)));
+}
+
 static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
 __blsi_u64(unsigned long long __X)
 {
@@ -110,6 +142,7 @@
 {
   return __builtin_ctzll(__X);
 }
-#endif
+
+#endif /* __x86_64__ */
 
 #endif /* __BMIINTRIN_H */
diff --git a/lib/Headers/cpuid.h b/lib/Headers/cpuid.h
index 8f12cae..f9254e9 100644
--- a/lib/Headers/cpuid.h
+++ b/lib/Headers/cpuid.h
@@ -79,6 +79,7 @@
 #define bit_ACPI        0x00400000
 #define bit_MMX         0x00800000
 #define bit_FXSR        0x01000000
+#define bit_FXSAVE      bit_FXSR    /* for gcc compat */
 #define bit_SSE         0x02000000
 #define bit_SSE2        0x04000000
 #define bit_SS          0x08000000
diff --git a/lib/Headers/emmintrin.h b/lib/Headers/emmintrin.h
index a78eb54..b3f8569 100644
--- a/lib/Headers/emmintrin.h
+++ b/lib/Headers/emmintrin.h
@@ -1366,7 +1366,7 @@
 }
 
 static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
-_mm_movpi64_pi64(__m64 __a)
+_mm_movpi64_epi64(__m64 __a)
 {
   return (__m128i){ (long long)__a, 0 };
 }
diff --git a/lib/Headers/float.h b/lib/Headers/float.h
index 2cb13d3..02ef6bf 100644
--- a/lib/Headers/float.h
+++ b/lib/Headers/float.h
@@ -29,7 +29,7 @@
  * For more details see http://msdn.microsoft.com/en-us/library/y0ybw9fy.aspx
  */
 #if (defined(__MINGW32__) || defined(_MSC_VER)) && \
-    defined(__has_include_next) && __has_include_next(<float.h>)
+    __has_include_next(<float.h>)
 #  include_next <float.h>
 
 /* Undefine anything that we'll be redefining below. */
diff --git a/lib/Headers/ia32intrin.h b/lib/Headers/ia32intrin.h
new file mode 100644
index 0000000..5adf3f1
--- /dev/null
+++ b/lib/Headers/ia32intrin.h
@@ -0,0 +1,101 @@
+/* ===-------- ia32intrin.h ---------------------------------------------------===
+ *
+ * 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 <ia32intrin.h> directly; include <x86intrin.h> instead."
+#endif
+
+#ifndef __IA32INTRIN_H
+#define __IA32INTRIN_H
+
+#ifdef __x86_64__
+static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
+__readeflags(void)
+{
+  unsigned long long __res = 0;
+  __asm__ __volatile__ ("pushf\n\t"
+                        "popq %0\n"
+                        :"=r"(__res)
+                        :
+                        :
+                       );
+  return __res;
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+__writeeflags(unsigned long long __f)
+{
+  __asm__ __volatile__ ("pushq %0\n\t"
+                        "popf\n"
+                        :
+                        :"r"(__f)
+                        :"flags"
+                       );
+}
+
+#else /* !__x86_64__ */
+static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
+__readeflags(void)
+{
+  unsigned int __res = 0;
+  __asm__ __volatile__ ("pushf\n\t"
+                        "popl %0\n"
+                        :"=r"(__res)
+                        :
+                        :
+                       );
+  return __res;
+}
+
+static __inline__ void __attribute__((__always_inline__, __nodebug__))
+__writeeflags(unsigned int __f)
+{
+  __asm__ __volatile__ ("pushl %0\n\t"
+                        "popf\n"
+                        :
+                        :"r"(__f)
+                        :"flags"
+                       );
+}
+#endif /* !__x86_64__ */
+
+static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
+__rdpmc(int __A) {
+  return __builtin_ia32_rdpmc(__A);
+}
+
+/* __rdtsc */
+static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
+__rdtsc(void) {
+  return __builtin_ia32_rdtsc();
+}
+
+/* __rdtscp */
+static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
+__rdtscp(unsigned int *__A) {
+  return __builtin_ia32_rdtscp(__A);
+}
+
+#define _rdtsc() __rdtsc()
+
+#endif /* __IA32INTRIN_H */
diff --git a/lib/Headers/immintrin.h b/lib/Headers/immintrin.h
index 15d6e05..df4bea8 100644
--- a/lib/Headers/immintrin.h
+++ b/lib/Headers/immintrin.h
@@ -48,7 +48,7 @@
 #include <smmintrin.h>
 #endif
 
-#if defined (__AES__)
+#if defined (__AES__) || defined (__PCLMUL__)
 #include <wmmintrin.h>
 #endif
 
diff --git a/lib/Headers/limits.h b/lib/Headers/limits.h
index 91bd404..f04187c 100644
--- a/lib/Headers/limits.h
+++ b/lib/Headers/limits.h
@@ -33,8 +33,7 @@
 
 /* System headers include a number of constants from POSIX in <limits.h>.
    Include it if we're hosted. */
-#if __STDC_HOSTED__ && \
-    defined(__has_include_next) && __has_include_next(<limits.h>)
+#if __STDC_HOSTED__ && __has_include_next(<limits.h>)
 #include_next <limits.h>
 #endif
 
@@ -90,7 +89,7 @@
 /* C99 5.2.4.2.1: Added long long.
    C++11 18.3.3.2: same contents as the Standard C Library header <limits.h>.
  */
-#if __STDC_VERSION__ >= 199901 || __cplusplus >= 201103L
+#if __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L
 
 #undef  LLONG_MIN
 #undef  LLONG_MAX
diff --git a/lib/Headers/module.map b/lib/Headers/module.modulemap
similarity index 100%
rename from lib/Headers/module.map
rename to lib/Headers/module.modulemap
diff --git a/lib/Headers/smmintrin.h b/lib/Headers/smmintrin.h
index 53b3ccb..6e35734 100644
--- a/lib/Headers/smmintrin.h
+++ b/lib/Headers/smmintrin.h
@@ -79,12 +79,18 @@
 #define _mm_blend_pd(V1, V2, M) __extension__ ({ \
   __m128d __V1 = (V1); \
   __m128d __V2 = (V2); \
-  (__m128d) __builtin_ia32_blendpd ((__v2df)__V1, (__v2df)__V2, (M)); })
+  (__m128d)__builtin_shufflevector((__v2df)__V1, (__v2df)__V2, \
+                                   (((M) & 0x01) ? 2 : 0), \
+                                   (((M) & 0x02) ? 3 : 1)); })
 
 #define _mm_blend_ps(V1, V2, M) __extension__ ({ \
   __m128 __V1 = (V1); \
   __m128 __V2 = (V2); \
-  (__m128) __builtin_ia32_blendps ((__v4sf)__V1, (__v4sf)__V2, (M)); })
+  (__m128)__builtin_shufflevector((__v4sf)__V1, (__v4sf)__V2, \
+                                  (((M) & 0x01) ? 4 : 0), \
+                                  (((M) & 0x02) ? 5 : 1), \
+                                  (((M) & 0x04) ? 6 : 2), \
+                                  (((M) & 0x08) ? 7 : 3)); })
 
 static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
 _mm_blendv_pd (__m128d __V1, __m128d __V2, __m128d __M)
@@ -110,7 +116,15 @@
 #define _mm_blend_epi16(V1, V2, M) __extension__ ({ \
   __m128i __V1 = (V1); \
   __m128i __V2 = (V2); \
-  (__m128i) __builtin_ia32_pblendw128 ((__v8hi)__V1, (__v8hi)__V2, (M)); })
+  (__m128i)__builtin_shufflevector((__v8hi)__V1, (__v8hi)__V2, \
+                                   (((M) & 0x01) ?  8 : 0), \
+                                   (((M) & 0x02) ?  9 : 1), \
+                                   (((M) & 0x04) ? 10 : 2), \
+                                   (((M) & 0x08) ? 11 : 3), \
+                                   (((M) & 0x10) ? 12 : 4), \
+                                   (((M) & 0x20) ? 13 : 5), \
+                                   (((M) & 0x40) ? 14 : 6), \
+                                   (((M) & 0x80) ? 15 : 7)); })
 
 /* SSE4 Dword Multiply Instructions.  */
 static __inline__  __m128i __attribute__((__always_inline__, __nodebug__))
diff --git a/lib/Headers/stdarg.h b/lib/Headers/stdarg.h
index 2957bf0..a57e183 100644
--- a/lib/Headers/stdarg.h
+++ b/lib/Headers/stdarg.h
@@ -39,12 +39,14 @@
  */
 #define __va_copy(d,s) __builtin_va_copy(d,s)
 
-#if __STDC_VERSION__ >= 199900L || __cplusplus >= 201103L || !defined(__STRICT_ANSI__)
+#if __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L || !defined(__STRICT_ANSI__)
 #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 /* __STDARG_H */
diff --git a/lib/Headers/stddef.h b/lib/Headers/stddef.h
index 6a64d6d..2dfe0a2 100644
--- a/lib/Headers/stddef.h
+++ b/lib/Headers/stddef.h
@@ -23,9 +23,22 @@
  *===-----------------------------------------------------------------------===
  */
 
-#ifndef __STDDEF_H
-#define __STDDEF_H
+#if !defined(__STDDEF_H) || defined(__need_ptrdiff_t) ||                       \
+    defined(__need_size_t) || defined(__need_wchar_t) ||                       \
+    defined(__need_NULL) || defined(__need_wint_t)
 
+#if !defined(__need_ptrdiff_t) && !defined(__need_size_t) &&                   \
+    !defined(__need_wchar_t) && !defined(__need_NULL) &&                       \
+    !defined(__need_wint_t)
+#define __STDDEF_H
+#define __need_ptrdiff_t
+#define __need_size_t
+#define __need_wchar_t
+#define __need_NULL
+/* __need_wint_t is intentionally not defined here. */
+#endif
+
+#if defined(__need_ptrdiff_t)
 #if !defined(_PTRDIFF_T) || __has_feature(modules)
 /* Always define ptrdiff_t when modules are available. */
 #if !__has_feature(modules)
@@ -33,7 +46,10 @@
 #endif
 typedef __PTRDIFF_TYPE__ ptrdiff_t;
 #endif
+#undef __need_ptrdiff_t
+#endif /* defined(__need_ptrdiff_t) */
 
+#if defined(__need_size_t)
 #if !defined(_SIZE_T) || __has_feature(modules)
 /* Always define size_t when modules are available. */
 #if !__has_feature(modules)
@@ -41,7 +57,10 @@
 #endif
 typedef __SIZE_TYPE__ size_t;
 #endif
+#undef __need_size_t
+#endif /*defined(__need_size_t) */
 
+#if defined(__STDDEF_H)
 /* ISO9899:2011 7.20 (C11 Annex K): Define rsize_t if __STDC_WANT_LIB_EXT1__ is
  * enabled. */
 #if (defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1 && \
@@ -52,7 +71,9 @@
 #endif
 typedef __SIZE_TYPE__ rsize_t;
 #endif
+#endif /* defined(__STDDEF_H) */
 
+#if defined(__need_wchar_t)
 #ifndef __cplusplus
 /* Always define wchar_t when modules are available. */
 #if !defined(_WCHAR_T) || __has_feature(modules)
@@ -65,7 +86,10 @@
 typedef __WCHAR_TYPE__ wchar_t;
 #endif
 #endif
+#undef __need_wchar_t
+#endif /* defined(__need_wchar_t) */
 
+#if defined(__need_NULL)
 #undef NULL
 #ifdef __cplusplus
 #  if !defined(__MINGW32__) && !defined(_MSC_VER)
@@ -76,17 +100,35 @@
 #else
 #  define NULL ((void*)0)
 #endif
-
 #ifdef __cplusplus
 #if defined(_MSC_EXTENSIONS) && defined(_NATIVE_NULLPTR_SUPPORTED)
 namespace std { typedef decltype(nullptr) nullptr_t; }
 using ::std::nullptr_t;
 #endif
 #endif
+#undef __need_NULL
+#endif /* defined(__need_NULL) */
+
+#if defined(__STDDEF_H)
+
+#if __STDC_VERSION__ >= 201112L || __cplusplus >= 201103L
+#if !defined(__CLANG_MAX_ALIGN_T_DEFINED) || __has_feature(modules)
+#ifndef _MSC_VER
+typedef struct {
+  long long __clang_max_align_nonce1
+      __attribute__((__aligned__(__alignof__(long long))));
+  long double __clang_max_align_nonce2
+      __attribute__((__aligned__(__alignof__(long double))));
+} max_align_t;
+#else
+typedef double max_align_t;
+#endif
+#define __CLANG_MAX_ALIGN_T_DEFINED
+#endif
+#endif
 
 #define offsetof(t, d) __builtin_offsetof(t, d)
-
-#endif /* __STDDEF_H */
+#endif  /* __STDDEF_H */
 
 /* Some C libraries expect to see a wint_t here. Others (notably MinGW) will use
 __WINT_TYPE__ directly; accommodate both by requiring __need_wint_t */
@@ -100,3 +142,5 @@
 #endif
 #undef __need_wint_t
 #endif /* __need_wint_t */
+
+#endif
diff --git a/lib/Headers/stdint.h b/lib/Headers/stdint.h
index 11529c0..0303db9 100644
--- a/lib/Headers/stdint.h
+++ b/lib/Headers/stdint.h
@@ -28,8 +28,7 @@
 /* If we're hosted, fall back to the system's stdint.h, which might have
  * additional definitions.
  */
-#if __STDC_HOSTED__ && \
-    defined(__has_include_next) && __has_include_next(<stdint.h>)
+#if __STDC_HOSTED__ && __has_include_next(<stdint.h>)
 
 // C99 7.18.3 Limits of other integer types
 //
@@ -105,9 +104,9 @@
 
 #ifdef __INT64_TYPE__
 # ifndef __int8_t_defined /* glibc sys/types.h also defines int64_t*/
-typedef signed __INT64_TYPE__ int64_t;
+typedef __INT64_TYPE__ int64_t;
 # endif /* __int8_t_defined */
-typedef unsigned __INT64_TYPE__ uint64_t;
+typedef __UINT64_TYPE__ uint64_t;
 # define __int_least64_t int64_t
 # define __uint_least64_t uint64_t
 # define __int_least32_t int64_t
@@ -126,8 +125,8 @@
 #endif /* __int_least64_t */
 
 #ifdef __INT56_TYPE__
-typedef signed __INT56_TYPE__ int56_t;
-typedef unsigned __INT56_TYPE__ uint56_t;
+typedef __INT56_TYPE__ int56_t;
+typedef __UINT56_TYPE__ uint56_t;
 typedef int56_t int_least56_t;
 typedef uint56_t uint_least56_t;
 typedef int56_t int_fast56_t;
@@ -142,8 +141,8 @@
 
 
 #ifdef __INT48_TYPE__
-typedef signed __INT48_TYPE__ int48_t;
-typedef unsigned __INT48_TYPE__ uint48_t;
+typedef __INT48_TYPE__ int48_t;
+typedef __UINT48_TYPE__ uint48_t;
 typedef int48_t int_least48_t;
 typedef uint48_t uint_least48_t;
 typedef int48_t int_fast48_t;
@@ -158,8 +157,8 @@
 
 
 #ifdef __INT40_TYPE__
-typedef signed __INT40_TYPE__ int40_t;
-typedef unsigned __INT40_TYPE__ uint40_t;
+typedef __INT40_TYPE__ int40_t;
+typedef __UINT40_TYPE__ uint40_t;
 typedef int40_t int_least40_t;
 typedef uint40_t uint_least40_t;
 typedef int40_t int_fast40_t;
@@ -176,12 +175,12 @@
 #ifdef __INT32_TYPE__
 
 # ifndef __int8_t_defined /* glibc sys/types.h also defines int32_t*/
-typedef signed __INT32_TYPE__ int32_t;
+typedef __INT32_TYPE__ int32_t;
 # endif /* __int8_t_defined */
 
 # ifndef __uint32_t_defined  /* more glibc compatibility */
 # define __uint32_t_defined
-typedef unsigned __INT32_TYPE__ uint32_t;
+typedef __UINT32_TYPE__ uint32_t;
 # endif /* __uint32_t_defined */
 
 # define __int_least32_t int32_t
@@ -200,8 +199,8 @@
 #endif /* __int_least32_t */
 
 #ifdef __INT24_TYPE__
-typedef signed __INT24_TYPE__ int24_t;
-typedef unsigned __INT24_TYPE__ uint24_t;
+typedef __INT24_TYPE__ int24_t;
+typedef __UINT24_TYPE__ uint24_t;
 typedef int24_t int_least24_t;
 typedef uint24_t uint_least24_t;
 typedef int24_t int_fast24_t;
@@ -214,9 +213,9 @@
 
 #ifdef __INT16_TYPE__
 #ifndef __int8_t_defined /* glibc sys/types.h also defines int16_t*/
-typedef signed __INT16_TYPE__ int16_t;
+typedef __INT16_TYPE__ int16_t;
 #endif /* __int8_t_defined */
-typedef unsigned __INT16_TYPE__ uint16_t;
+typedef __UINT16_TYPE__ uint16_t;
 # define __int_least16_t int16_t
 # define __uint_least16_t uint16_t
 # define __int_least8_t int16_t
@@ -233,9 +232,9 @@
 
 #ifdef __INT8_TYPE__
 #ifndef __int8_t_defined  /* glibc sys/types.h also defines int8_t*/
-typedef signed __INT8_TYPE__ int8_t;
+typedef __INT8_TYPE__ int8_t;
 #endif /* __int8_t_defined */
-typedef unsigned __INT8_TYPE__ uint8_t;
+typedef __UINT8_TYPE__ uint8_t;
 # define __int_least8_t int8_t
 # define __uint_least8_t uint8_t
 #endif /* __INT8_TYPE__ */
diff --git a/lib/Headers/x86intrin.h b/lib/Headers/x86intrin.h
index 399016f..21a43da 100644
--- a/lib/Headers/x86intrin.h
+++ b/lib/Headers/x86intrin.h
@@ -24,6 +24,8 @@
 #ifndef __X86INTRIN_H
 #define __X86INTRIN_H
 
+#include <ia32intrin.h>
+
 #include <immintrin.h>
 
 #ifdef __3dNOW__
@@ -74,6 +76,6 @@
 #include <f16cintrin.h>
 #endif
 
-// FIXME: LWP
+/* FIXME: LWP */
 
 #endif /* __X86INTRIN_H */
diff --git a/lib/Headers/xmmintrin.h b/lib/Headers/xmmintrin.h
index c68d3ed..c9befcb 100644
--- a/lib/Headers/xmmintrin.h
+++ b/lib/Headers/xmmintrin.h
@@ -34,8 +34,8 @@
 typedef float __v4sf __attribute__((__vector_size__(16)));
 typedef float __m128 __attribute__((__vector_size__(16)));
 
-// This header should only be included in a hosted environment as it depends on
-// a standard library to provide allocation routines.
+/* This header should only be included in a hosted environment as it depends on
+ * a standard library to provide allocation routines. */
 #if __STDC_HOSTED__
 #include <mm_malloc.h>
 #endif
@@ -589,7 +589,7 @@
   return (__m128){ __w, __w, __w, __w };
 }
 
-// Microsoft specific.
+/* Microsoft specific. */
 static __inline__ __m128 __attribute__((__always_inline__, __nodebug__))
 _mm_set_ps1(float __w)
 {
@@ -672,10 +672,12 @@
 #define _MM_HINT_T2 1
 #define _MM_HINT_NTA 0
 
+#ifndef _MSC_VER
 /* FIXME: We have to #define this because "sel" must be a constant integer, and
    Sema doesn't do any form of constant propagation yet. */
 
 #define _mm_prefetch(a, sel) (__builtin_prefetch((void *)(a), 0, (sel)))
+#endif
 
 static __inline__ void __attribute__((__always_inline__, __nodebug__))
 _mm_stream_pi(__m64 *__p, __m64 __a)
@@ -903,7 +905,7 @@
   __a = _mm_movehl_ps(__a, __a);
   __c = _mm_cvtps_pi32(__a);
   
-  return _mm_packs_pi16(__b, __c);
+  return _mm_packs_pi32(__b, __c);
 }
 
 static __inline__ __m64 __attribute__((__always_inline__, __nodebug__))
diff --git a/lib/Index/CMakeLists.txt b/lib/Index/CMakeLists.txt
index c4ff5a0..1ebb636 100644
--- a/lib/Index/CMakeLists.txt
+++ b/lib/Index/CMakeLists.txt
@@ -1,11 +1,19 @@
-add_clang_library(clangIndex
-  CommentToXML.cpp
-  SimpleFormatContext.h
-  USRGeneration.cpp
+set(LLVM_LINK_COMPONENTS
+  Support
   )
 
-target_link_libraries(clangIndex
-  clangBasic
+add_clang_library(clangIndex
+  CommentToXML.cpp
+  USRGeneration.cpp
+
+  ADDITIONAL_HEADERS
+  SimpleFormatContext.h
+
+  LINK_LIBS
   clangAST
+  clangBasic
   clangFormat
+  clangLex
+  clangRewrite
+  clangTooling
   )
diff --git a/lib/Index/CommentToXML.cpp b/lib/Index/CommentToXML.cpp
index 0a9619d..a67c806 100644
--- a/lib/Index/CommentToXML.cpp
+++ b/lib/Index/CommentToXML.cpp
@@ -9,8 +9,8 @@
 
 #include "clang/Index/CommentToXML.h"
 #include "SimpleFormatContext.h"
-#include "clang/AST/Attr.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/Attr.h"
 #include "clang/AST/Comment.h"
 #include "clang/AST/CommentVisitor.h"
 #include "clang/Format/Format.h"
@@ -97,7 +97,7 @@
 
 FullCommentParts::FullCommentParts(const FullComment *C,
                                    const CommandTraits &Traits) :
-    Brief(NULL), Headerfile(NULL), FirstParagraph(NULL) {
+    Brief(nullptr), Headerfile(nullptr), FirstParagraph(nullptr) {
   for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
        I != E; ++I) {
     const Comment *Child = *I;
@@ -563,6 +563,7 @@
 
   // Helpers.
   void appendToResultWithXMLEscaping(StringRef S);
+  void appendToResultWithCDATAEscaping(StringRef S);
 
   void formatTextOfDeclaration(const DeclInfo *DI,
                                SmallString<128> &Declaration);
@@ -667,14 +668,27 @@
 
 void CommentASTToXMLConverter::visitHTMLStartTagComment(
     const HTMLStartTagComment *C) {
-  Result << "<rawHTML><![CDATA[";
-  printHTMLStartTagComment(C, Result);
-  Result << "]]></rawHTML>";
+  Result << "<rawHTML";
+  if (C->isMalformed())
+    Result << " isMalformed=\"1\"";
+  Result << ">";
+  {
+    SmallString<32> Tag;
+    {
+      llvm::raw_svector_ostream TagOS(Tag);
+      printHTMLStartTagComment(C, TagOS);
+    }
+    appendToResultWithCDATAEscaping(Tag);
+  }
+  Result << "</rawHTML>";
 }
 
 void
 CommentASTToXMLConverter::visitHTMLEndTagComment(const HTMLEndTagComment *C) {
-  Result << "<rawHTML>&lt;/" << C->getTagName() << "&gt;</rawHTML>";
+  Result << "<rawHTML";
+  if (C->isMalformed())
+    Result << " isMalformed=\"1\"";
+  Result << ">&lt;/" << C->getTagName() << "&gt;</rawHTML>";
 }
 
 void
@@ -1100,6 +1114,31 @@
   }
 }
 
+void CommentASTToXMLConverter::appendToResultWithCDATAEscaping(StringRef S) {
+  if (S.empty())
+    return;
+
+  Result << "<![CDATA[";
+  while (!S.empty()) {
+    size_t Pos = S.find("]]>");
+    if (Pos == 0) {
+      Result << "]]]]><![CDATA[>";
+      S = S.drop_front(3);
+      continue;
+    }
+    if (Pos == StringRef::npos)
+      Pos = S.size();
+
+    Result << S.substr(0, Pos);
+
+    S = S.drop_front(Pos);
+  }
+  Result << "]]>";
+}
+
+CommentToXMLConverter::CommentToXMLConverter() : FormatInMemoryUniqueId(0) {}
+CommentToXMLConverter::~CommentToXMLConverter() {}
+
 void CommentToXMLConverter::convertCommentToHTML(const FullComment *FC,
                                                  SmallVectorImpl<char> &HTML,
                                                  const ASTContext &Context) {
@@ -1111,7 +1150,7 @@
 void CommentToXMLConverter::convertHTMLTagNodeToText(
     const comments::HTMLTagComment *HTC, SmallVectorImpl<char> &Text,
     const ASTContext &Context) {
-  CommentASTToHTMLConverter Converter(0, Text,
+  CommentASTToHTMLConverter Converter(nullptr, Text,
                                       Context.getCommentCommandTraits());
   Converter.visit(HTC);
 }
@@ -1119,13 +1158,10 @@
 void CommentToXMLConverter::convertCommentToXML(const FullComment *FC,
                                                 SmallVectorImpl<char> &XML,
                                                 const ASTContext &Context) {
-  if (!FormatContext) {
-    FormatContext = new SimpleFormatContext(Context.getLangOpts());
-  } else if ((FormatInMemoryUniqueId % 1000) == 0) {
-    // Delete after some number of iterations, so the buffers don't grow
-    // too large.
-    delete FormatContext;
-    FormatContext = new SimpleFormatContext(Context.getLangOpts());
+  if (!FormatContext || (FormatInMemoryUniqueId % 1000) == 0) {
+    // Create a new format context, or re-create it after some number of
+    // iterations, so the buffers don't grow too large.
+    FormatContext.reset(new SimpleFormatContext(Context.getLangOpts()));
   }
 
   CommentASTToXMLConverter Converter(FC, XML, Context.getCommentCommandTraits(),
diff --git a/lib/Index/SimpleFormatContext.h b/lib/Index/SimpleFormatContext.h
index fde43ae..a460863 100644
--- a/lib/Index/SimpleFormatContext.h
+++ b/lib/Index/SimpleFormatContext.h
@@ -37,7 +37,7 @@
   SimpleFormatContext(LangOptions Options)
       : DiagOpts(new DiagnosticOptions()),
         Diagnostics(new DiagnosticsEngine(new DiagnosticIDs,
-                                          DiagOpts.getPtr())),
+                                          DiagOpts.get())),
         Files((FileSystemOptions())),
         Sources(*Diagnostics, Files),
         Rewrite(Sources, Options) {
@@ -47,12 +47,11 @@
   ~SimpleFormatContext() { }
 
   FileID createInMemoryFile(StringRef Name, StringRef Content) {
-    const llvm::MemoryBuffer *Source =
-        llvm::MemoryBuffer::getMemBuffer(Content);
+    llvm::MemoryBuffer *Source = llvm::MemoryBuffer::getMemBuffer(Content);
     const FileEntry *Entry =
         Files.getVirtualFile(Name, Source->getBufferSize(), 0);
-    Sources.overrideFileContents(Entry, Source, true);
-    assert(Entry != NULL);
+    Sources.overrideFileContents(Entry, Source);
+    assert(Entry != nullptr);
     return Sources.createFileID(Entry, SourceLocation(), SrcMgr::C_User);
   }
 
diff --git a/lib/Index/USRGeneration.cpp b/lib/Index/USRGeneration.cpp
index 16d89f8..e08b85e 100644
--- a/lib/Index/USRGeneration.cpp
+++ b/lib/Index/USRGeneration.cpp
@@ -11,6 +11,7 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/DeclVisitor.h"
+#include "clang/Lex/PreprocessingRecord.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
@@ -22,6 +23,30 @@
 // USR generation.
 //===----------------------------------------------------------------------===//
 
+/// \returns true on error.
+static bool printLoc(llvm::raw_ostream &OS, SourceLocation Loc,
+                     const SourceManager &SM, bool IncludeOffset) {
+  if (Loc.isInvalid()) {
+    return true;
+  }
+  Loc = SM.getExpansionLoc(Loc);
+  const std::pair<FileID, unsigned> &Decomposed = SM.getDecomposedLoc(Loc);
+  const FileEntry *FE = SM.getFileEntryForID(Decomposed.first);
+  if (FE) {
+    OS << llvm::sys::path::filename(FE->getName());
+  } else {
+    // This case really isn't interesting.
+    return true;
+  }
+  if (IncludeOffset) {
+    // Use the offest into the FileID to represent the location.  Using
+    // a line/column can cause us to look back at the original source file,
+    // which is expensive.
+    OS << '@' << Decomposed.second;
+  }
+  return false;
+}
+
 namespace {
 class USRGenerator : public ConstDeclVisitor<USRGenerator> {
   SmallVectorImpl<char> &Buf;
@@ -80,10 +105,16 @@
   void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D) {
     IgnoreResults = true;
   }
-  
+
+  bool ShouldGenerateLocation(const NamedDecl *D);
+
+  bool isLocal(const NamedDecl *D) {
+    return D->getParentFunctionOrMethod() != nullptr;
+  }
+
   /// Generate the string component containing the location of the
   ///  declaration.
-  bool GenLoc(const Decl *D);
+  bool GenLoc(const Decl *D, bool IncludeOffset);
 
   /// String generation methods used both by the visitation methods
   /// and from other clients that want to directly generate USRs.  These
@@ -99,16 +130,6 @@
   void GenObjCCategory(StringRef cls, StringRef cat) {
     generateUSRForObjCCategory(cls, cat, Out);
   }
-  /// Generate a USR fragment for an Objective-C instance variable.  The
-  /// complete USR can be created by concatenating the USR for the
-  /// encompassing class with this USR fragment.
-  void GenObjCIvar(StringRef ivar) {
-    generateUSRForObjCIvar(ivar, Out);
-  }
-  /// Generate a USR fragment for an Objective-C method.
-  void GenObjCMethod(StringRef sel, bool isInstanceMethod) {
-    generateUSRForObjCMethod(sel, isInstanceMethod, Out);
-  }
   /// Generate a USR fragment for an Objective-C property.
   void GenObjCProperty(StringRef prop) {
     generateUSRForObjCProperty(prop, Out);
@@ -143,8 +164,13 @@
   return startSize == endSize;
 }
 
-static inline bool ShouldGenerateLocation(const NamedDecl *D) {
-  return !D->isExternallyVisible();
+bool USRGenerator::ShouldGenerateLocation(const NamedDecl *D) {
+  if (D->isExternallyVisible())
+    return false;
+  if (D->getParentFunctionOrMethod())
+    return true;
+  const SourceManager &SM = Context->getSourceManager();
+  return !SM.isInSystemHeader(D->getLocation());
 }
 
 void USRGenerator::VisitDeclContext(const DeclContext *DC) {
@@ -168,7 +194,7 @@
 }
 
 void USRGenerator::VisitFunctionDecl(const FunctionDecl *D) {
-  if (ShouldGenerateLocation(D) && GenLoc(D))
+  if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
     return;
 
   VisitDeclContext(D->getDeclContext());
@@ -194,12 +220,9 @@
   }
 
   // Mangle in type information for the arguments.
-  for (FunctionDecl::param_const_iterator I = D->param_begin(),
-                                          E = D->param_end();
-       I != E; ++I) {
+  for (auto PD : D->params()) {
     Out << '#';
-    if (ParmVarDecl *PD = *I)
-      VisitType(PD->getType());
+    VisitType(PD->getType());
   }
   if (D->isVariadic())
     Out << '.';
@@ -229,7 +252,7 @@
   // VarDecls can be declared 'extern' within a function or method body,
   // but their enclosing DeclContext is the function, not the TU.  We need
   // to check the storage class to correctly generate the USR.
-  if (ShouldGenerateLocation(D) && GenLoc(D))
+  if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
     return;
 
   VisitDeclContext(D->getDeclContext());
@@ -249,13 +272,13 @@
 
 void USRGenerator::VisitNonTypeTemplateParmDecl(
                                         const NonTypeTemplateParmDecl *D) {
-  GenLoc(D);
+  GenLoc(D, /*IncludeOffset=*/true);
   return;
 }
 
 void USRGenerator::VisitTemplateTemplateParmDecl(
                                         const TemplateTemplateParmDecl *D) {
-  GenLoc(D);
+  GenLoc(D, /*IncludeOffset=*/true);
   return;
 }
 
@@ -329,7 +352,7 @@
       // We want to mangle in the location to uniquely distinguish them.
       if (CD->IsClassExtension()) {
         Out << "objc(ext)" << ID->getName() << '@';
-        GenLoc(CD);
+        GenLoc(CD, /*IncludeOffset=*/true);
       }
       else
         GenObjCCategory(ID->getName(), CD->getName());
@@ -378,7 +401,7 @@
 void USRGenerator::VisitTagDecl(const TagDecl *D) {
   // Add the location of the tag decl to handle resolution across
   // translation units.
-  if (ShouldGenerateLocation(D) && GenLoc(D))
+  if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
     return;
 
   D = D->getCanonicalDecl();
@@ -449,7 +472,7 @@
 }
 
 void USRGenerator::VisitTypedefDecl(const TypedefDecl *D) {
-  if (ShouldGenerateLocation(D) && GenLoc(D))
+  if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
     return;
   const DeclContext *DC = D->getDeclContext();
   if (const NamedDecl *DCN = dyn_cast<NamedDecl>(DC))
@@ -459,15 +482,15 @@
 }
 
 void USRGenerator::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
-  GenLoc(D);
+  GenLoc(D, /*IncludeOffset=*/true);
   return;
 }
 
-bool USRGenerator::GenLoc(const Decl *D) {
+bool USRGenerator::GenLoc(const Decl *D, bool IncludeOffset) {
   if (generatedLoc)
     return IgnoreResults;
   generatedLoc = true;
-  
+
   // Guard against null declarations in invalid code.
   if (!D) {
     IgnoreResults = true;
@@ -477,27 +500,10 @@
   // Use the location of canonical decl.
   D = D->getCanonicalDecl();
 
-  const SourceManager &SM = Context->getSourceManager();
-  SourceLocation L = D->getLocStart();
-  if (L.isInvalid()) {
-    IgnoreResults = true;
-    return true;
-  }
-  L = SM.getExpansionLoc(L);
-  const std::pair<FileID, unsigned> &Decomposed = SM.getDecomposedLoc(L);
-  const FileEntry *FE = SM.getFileEntryForID(Decomposed.first);
-  if (FE) {
-    Out << llvm::sys::path::filename(FE->getName());
-  }
-  else {
-    // This case really isn't interesting.
-    IgnoreResults = true;
-    return true;
-  }
-  // Use the offest into the FileID to represent the location.  Using
-  // a line/column can cause us to look back at the original source file,
-  // which is expensive.
-  Out << '@' << Decomposed.second;
+  IgnoreResults =
+      IgnoreResults || printLoc(Out, D->getLocStart(),
+                                Context->getSourceManager(), IncludeOffset);
+
   return IgnoreResults;
 }
 
@@ -627,11 +633,9 @@
     }
     if (const FunctionProtoType *FT = T->getAs<FunctionProtoType>()) {
       Out << 'F';
-      VisitType(FT->getResultType());
-      for (FunctionProtoType::arg_type_iterator
-            I = FT->arg_type_begin(), E = FT->arg_type_end(); I!=E; ++I) {
-        VisitType(*I);
-      }
+      VisitType(FT->getReturnType());
+      for (const auto &I : FT->param_types())
+        VisitType(I);
       if (FT->isVariadic())
         Out << '.';
       return;
@@ -743,9 +747,8 @@
       
   case TemplateArgument::Pack:
     Out << 'p' << Arg.pack_size();
-    for (TemplateArgument::pack_iterator P = Arg.pack_begin(), PEnd = Arg.pack_end();
-         P != PEnd; ++P)
-      VisitTemplateArgument(*P);
+    for (const auto &P : Arg.pack_elements())
+      VisitTemplateArgument(P);
     break;
       
   case TemplateArgument::Type:
@@ -801,3 +804,26 @@
   UG.Visit(D);
   return UG.ignoreResults();
 }
+
+bool clang::index::generateUSRForMacro(const MacroDefinition *MD,
+                                       const SourceManager &SM,
+                                       SmallVectorImpl<char> &Buf) {
+  // Don't generate USRs for things with invalid locations.
+  if (!MD || MD->getLocation().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();
+  return false;
+}
+
diff --git a/lib/Lex/CMakeLists.txt b/lib/Lex/CMakeLists.txt
index 2ee4682..38df144 100644
--- a/lib/Lex/CMakeLists.txt
+++ b/lib/Lex/CMakeLists.txt
@@ -25,14 +25,7 @@
   ScratchBuffer.cpp
   TokenConcatenation.cpp
   TokenLexer.cpp
-  )
 
-add_dependencies(clangLex
-  ClangAttrSpellings
-  ClangDiagnosticCommon
-  ClangDiagnosticLex
-  )
-
-target_link_libraries(clangLex
+  LINK_LIBS
   clangBasic
   )
diff --git a/lib/Lex/HeaderMap.cpp b/lib/Lex/HeaderMap.cpp
index 478462c..f6c658e 100644
--- a/lib/Lex/HeaderMap.cpp
+++ b/lib/Lex/HeaderMap.cpp
@@ -14,12 +14,12 @@
 #include "clang/Lex/HeaderMap.h"
 #include "clang/Basic/CharInfo.h"
 #include "clang/Basic/FileManager.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/DataTypes.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include <cstdio>
+#include <memory>
 using namespace clang;
 
 //===----------------------------------------------------------------------===//
@@ -79,10 +79,10 @@
 const HeaderMap *HeaderMap::Create(const FileEntry *FE, FileManager &FM) {
   // If the file is too small to be a header map, ignore it.
   unsigned FileSize = FE->getSize();
-  if (FileSize <= sizeof(HMapHeader)) return 0;
+  if (FileSize <= sizeof(HMapHeader)) return nullptr;
 
-  OwningPtr<const llvm::MemoryBuffer> FileBuffer(FM.getBufferForFile(FE));
-  if (!FileBuffer) return 0;  // Unreadable file?
+  std::unique_ptr<const llvm::MemoryBuffer> FileBuffer(FM.getBufferForFile(FE));
+  if (!FileBuffer) return nullptr;  // Unreadable file?
   const char *FileStart = FileBuffer->getBufferStart();
 
   // We know the file is at least as big as the header, check it now.
@@ -98,12 +98,12 @@
            Header->Version == llvm::ByteSwap_16(HMAP_HeaderVersion))
     NeedsByteSwap = true;  // Mixed endianness headermap.
   else
-    return 0;  // Not a header map.
+    return nullptr;  // Not a header map.
 
-  if (Header->Reserved != 0) return 0;
+  if (Header->Reserved != 0) return nullptr;
 
   // Okay, everything looks good, create the header map.
-  return new HeaderMap(FileBuffer.take(), NeedsByteSwap);
+  return new HeaderMap(FileBuffer.release(), NeedsByteSwap);
 }
 
 HeaderMap::~HeaderMap() {
@@ -165,7 +165,7 @@
 
   // Check for invalid index.
   if (StrTabIdx >= FileBuffer->getBufferSize())
-    return 0;
+    return nullptr;
 
   // Otherwise, we have a valid pointer into the file.  Just return it.  We know
   // that the "string" can not overrun the end of the file, because the buffer
@@ -201,18 +201,29 @@
 /// this HeaderMap.  If so, open it and return its FileEntry.
 const FileEntry *HeaderMap::LookupFile(
     StringRef Filename, FileManager &FM) const {
+
+  SmallString<1024> Path;
+  StringRef Dest = lookupFilename(Filename, Path);
+  if (Dest.empty())
+    return nullptr;
+
+  return FM.getFile(Dest);
+}
+
+StringRef HeaderMap::lookupFilename(StringRef Filename,
+                                    SmallVectorImpl<char> &DestPath) const {
   const HMapHeader &Hdr = getHeader();
   unsigned NumBuckets = getEndianAdjustedWord(Hdr.NumBuckets);
 
   // If the number of buckets is not a power of two, the headermap is corrupt.
   // Don't probe infinitely.
   if (NumBuckets & (NumBuckets-1))
-    return 0;
+    return StringRef();
 
   // Linearly probe the hash table.
   for (unsigned Bucket = HashHMapKey(Filename);; ++Bucket) {
     HMapBucket B = getBucket(Bucket & (NumBuckets-1));
-    if (B.Key == HMAP_EmptyBucketKey) return 0; // Hash miss.
+    if (B.Key == HMAP_EmptyBucketKey) return StringRef(); // Hash miss.
 
     // See if the key matches.  If not, probe on.
     if (!Filename.equals_lower(getString(B.Key)))
@@ -220,9 +231,11 @@
 
     // If so, we have a match in the hash table.  Construct the destination
     // path.
-    SmallString<1024> DestPath;
-    DestPath += getString(B.Prefix);
-    DestPath += getString(B.Suffix);
-    return FM.getFile(DestPath.str());
+    StringRef Prefix = getString(B.Prefix);
+    StringRef Suffix = getString(B.Suffix);
+    DestPath.clear();
+    DestPath.append(Prefix.begin(), Prefix.end());
+    DestPath.append(Suffix.begin(), Suffix.end());
+    return StringRef(DestPath.begin(), DestPath.size());
   }
 }
diff --git a/lib/Lex/HeaderSearch.cpp b/lib/Lex/HeaderSearch.cpp
index 9e43dda..c12d731 100644
--- a/lib/Lex/HeaderSearch.cpp
+++ b/lib/Lex/HeaderSearch.cpp
@@ -12,12 +12,14 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Lex/HeaderSearch.h"
-#include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "clang/Lex/HeaderMap.h"
 #include "clang/Lex/HeaderSearchOptions.h"
+#include "clang/Lex/LexDiagnostic.h"
 #include "clang/Lex/Lexer.h"
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/Hashing.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/Capacity.h"
 #include "llvm/Support/FileSystem.h"
@@ -35,7 +37,7 @@
     return ControllingMacro;
 
   if (!ControllingMacroID || !External)
-    return 0;
+    return nullptr;
 
   ControllingMacro = External->GetIdentifier(ControllingMacroID);
   return ControllingMacro;
@@ -45,20 +47,21 @@
 
 HeaderSearch::HeaderSearch(IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts,
                            SourceManager &SourceMgr, DiagnosticsEngine &Diags,
-                           const LangOptions &LangOpts, 
+                           const LangOptions &LangOpts,
                            const TargetInfo *Target)
-  : HSOpts(HSOpts), FileMgr(SourceMgr.getFileManager()), FrameworkMap(64),
-    ModMap(SourceMgr, *Diags.getClient(), LangOpts, Target, *this)
-{
+    : HSOpts(HSOpts), Diags(Diags), FileMgr(SourceMgr.getFileManager()),
+      FrameworkMap(64), ModMap(SourceMgr, Diags, LangOpts, Target, *this) {
   AngledDirIdx = 0;
   SystemDirIdx = 0;
   NoCurDirSearch = false;
 
-  ExternalLookup = 0;
-  ExternalSource = 0;
+  ExternalLookup = nullptr;
+  ExternalSource = nullptr;
   NumIncluded = 0;
   NumMultiIncludeFileOptzn = 0;
   NumFrameworkLookups = NumSubFrameworkLookups = 0;
+
+  EnabledModules = LangOpts.Modules;
 }
 
 HeaderSearch::~HeaderSearch() {
@@ -107,28 +110,37 @@
     return HM;
   }
 
-  return 0;
+  return nullptr;
 }
 
 std::string HeaderSearch::getModuleFileName(Module *Module) {
-  // If we don't have a module cache path, we can't do anything.
-  if (ModuleCachePath.empty()) 
-    return std::string();
-
-
-  SmallString<256> Result(ModuleCachePath);
-  llvm::sys::path::append(Result, Module->getTopLevelModule()->Name + ".pcm");
-  return Result.str().str();
+  return getModuleFileName(Module->Name, Module->ModuleMap->getName());
 }
 
-std::string HeaderSearch::getModuleFileName(StringRef ModuleName) {
+std::string HeaderSearch::getModuleFileName(StringRef ModuleName,
+                                            StringRef ModuleMapPath) {
   // If we don't have a module cache path, we can't do anything.
   if (ModuleCachePath.empty()) 
     return std::string();
-  
-  
+
   SmallString<256> Result(ModuleCachePath);
-  llvm::sys::path::append(Result, ModuleName + ".pcm");
+  llvm::sys::fs::make_absolute(Result);
+
+  if (HSOpts->DisableModuleHash) {
+    llvm::sys::path::append(Result, ModuleName + ".pcm");
+  } else {
+    // Construct the name <ModuleName>-<hash of ModuleMapPath>.pcm which should
+    // be globally unique to this particular module. To avoid false-negatives
+    // on case-insensitive filesystems, we use lower-case, which is safe because
+    // to cause a collision the modules must have the same name, which is an
+    // error if they are imported in the same translation.
+    SmallString<256> AbsModuleMapPath(ModuleMapPath);
+    llvm::sys::fs::make_absolute(AbsModuleMapPath);
+    llvm::APInt Code(64, llvm::hash_value(AbsModuleMapPath.str().lower()));
+    SmallString<128> HashStr;
+    Code.toStringUnsigned(HashStr, /*Radix*/36);
+    llvm::sys::path::append(Result, ModuleName + "-" + HashStr.str() + ".pcm");
+  }
   return Result.str().str();
 }
 
@@ -164,8 +176,8 @@
 
     bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory();
     // Search for a module map file in this directory.
-    if (loadModuleMapFile(SearchDirs[Idx].getDir(), IsSystem)
-          == LMM_NewlyLoaded) {
+    if (loadModuleMapFile(SearchDirs[Idx].getDir(), IsSystem,
+                          /*IsFramework*/false) == LMM_NewlyLoaded) {
       // We just loaded a module map file; check whether the module is
       // available now.
       Module = ModMap.findModule(ModuleName);
@@ -178,7 +190,8 @@
     SmallString<128> NestedModuleMapDirName;
     NestedModuleMapDirName = SearchDirs[Idx].getDir()->getName();
     llvm::sys::path::append(NestedModuleMapDirName, ModuleName);
-    if (loadModuleMapFile(NestedModuleMapDirName, IsSystem) == LMM_NewlyLoaded){
+    if (loadModuleMapFile(NestedModuleMapDirName, IsSystem,
+                          /*IsFramework*/false) == LMM_NewlyLoaded){
       // If we just loaded a module map file, look for the module again.
       Module = ModMap.findModule(ModuleName);
       if (Module)
@@ -218,51 +231,65 @@
   return getHeaderMap()->getFileName();
 }
 
+static const FileEntry *
+getFileAndSuggestModule(HeaderSearch &HS, StringRef FileName,
+                        const DirectoryEntry *Dir, bool IsSystemHeaderDir,
+                        ModuleMap::KnownHeader *SuggestedModule) {
+  // If we have a module map that might map this header, load it and
+  // check whether we'll have a suggestion for a module.
+  HS.hasModuleMap(FileName, Dir, IsSystemHeaderDir);
+  if (SuggestedModule) {
+    const FileEntry *File = HS.getFileMgr().getFile(FileName,
+                                                    /*OpenFile=*/false);
+    if (File) {
+      // If there is a module that corresponds to this header, suggest it.
+      *SuggestedModule = HS.findModuleForHeader(File);
+
+      // FIXME: This appears to be a no-op. We loaded the module map for this
+      // directory at the start of this function.
+      if (!SuggestedModule->getModule() &&
+          HS.hasModuleMap(FileName, Dir, IsSystemHeaderDir))
+        *SuggestedModule = HS.findModuleForHeader(File);
+    }
+
+    return File;
+  }
+
+  return HS.getFileMgr().getFile(FileName, /*openFile=*/true);
+}
 
 /// LookupFile - Lookup the specified file in this search path, returning it
 /// if it exists or returning null if not.
 const FileEntry *DirectoryLookup::LookupFile(
-    StringRef Filename,
+    StringRef &Filename,
     HeaderSearch &HS,
     SmallVectorImpl<char> *SearchPath,
     SmallVectorImpl<char> *RelativePath,
     ModuleMap::KnownHeader *SuggestedModule,
-    bool &InUserSpecifiedSystemFramework) const {
+    bool &InUserSpecifiedSystemFramework,
+    bool &HasBeenMapped,
+    SmallVectorImpl<char> &MappedName) const {
   InUserSpecifiedSystemFramework = false;
+  HasBeenMapped = false;
 
   SmallString<1024> TmpDir;
   if (isNormalDir()) {
     // Concatenate the requested file onto the directory.
     TmpDir = getDir()->getName();
     llvm::sys::path::append(TmpDir, Filename);
-    if (SearchPath != NULL) {
+    if (SearchPath) {
       StringRef SearchPathRef(getDir()->getName());
       SearchPath->clear();
       SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
     }
-    if (RelativePath != NULL) {
+    if (RelativePath) {
       RelativePath->clear();
       RelativePath->append(Filename.begin(), Filename.end());
     }
-    
-    // If we have a module map that might map this header, load it and
-    // check whether we'll have a suggestion for a module.
-    HS.hasModuleMap(TmpDir, getDir(), isSystemHeaderDirectory());
-    if (SuggestedModule) {
-      const FileEntry *File = HS.getFileMgr().getFile(TmpDir.str(),
-                                                      /*openFile=*/false);
-      if (!File)
-        return File;
-      
-      // If there is a module that corresponds to this header, suggest it.
-      *SuggestedModule = HS.findModuleForHeader(File);
-      if (!SuggestedModule->getModule() &&
-          HS.hasModuleMap(TmpDir, getDir(), isSystemHeaderDirectory()))
-        *SuggestedModule = HS.findModuleForHeader(File);
-      return File;
-    }
-    
-    return HS.getFileMgr().getFile(TmpDir.str(), /*openFile=*/true);
+
+    return getFileAndSuggestModule(HS, TmpDir.str(), getDir(),
+                                   isSystemHeaderDirectory(),
+                                   SuggestedModule);
   }
 
   if (isFramework())
@@ -270,15 +297,35 @@
                              SuggestedModule, InUserSpecifiedSystemFramework);
 
   assert(isHeaderMap() && "Unknown directory lookup");
-  const FileEntry * const Result = getHeaderMap()->LookupFile(
-      Filename, HS.getFileMgr());
+  const HeaderMap *HM = getHeaderMap();
+  SmallString<1024> Path;
+  StringRef Dest = HM->lookupFilename(Filename, Path);
+  if (Dest.empty())
+    return nullptr;
+
+  const FileEntry *Result;
+
+  // Check if the headermap maps the filename to a framework include
+  // ("Foo.h" -> "Foo/Foo.h"), in which case continue header lookup using the
+  // framework include.
+  if (llvm::sys::path::is_relative(Dest)) {
+    MappedName.clear();
+    MappedName.append(Dest.begin(), Dest.end());
+    Filename = StringRef(MappedName.begin(), MappedName.size());
+    HasBeenMapped = true;
+    Result = HM->LookupFile(Filename, HS.getFileMgr());
+
+  } else {
+    Result = HS.getFileMgr().getFile(Dest);
+  }
+
   if (Result) {
-    if (SearchPath != NULL) {
+    if (SearchPath) {
       StringRef SearchPathRef(getName());
       SearchPath->clear();
       SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
     }
-    if (RelativePath != NULL) {
+    if (RelativePath) {
       RelativePath->clear();
       RelativePath->append(Filename.begin(), Filename.end());
     }
@@ -350,7 +397,7 @@
 
   // Framework names must have a '/' in the filename.
   size_t SlashPos = Filename.find('/');
-  if (SlashPos == StringRef::npos) return 0;
+  if (SlashPos == StringRef::npos) return nullptr;
 
   // Find out if this is the home for the specified framework, by checking
   // HeaderSearch.  Possible answers are yes/no and unknown.
@@ -359,7 +406,7 @@
 
   // If it is known and in some other directory, fail.
   if (CacheEntry.Directory && CacheEntry.Directory != getFrameworkDir())
-    return 0;
+    return nullptr;
 
   // Otherwise, construct the path to this framework dir.
 
@@ -377,12 +424,12 @@
   FrameworkName += ".framework/";
 
   // If the cache entry was unresolved, populate it now.
-  if (CacheEntry.Directory == 0) {
+  if (!CacheEntry.Directory) {
     HS.IncrementFrameworkLookupCount();
 
     // If the framework dir doesn't exist, we fail.
     const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName.str());
-    if (Dir == 0) return 0;
+    if (!Dir) return nullptr;
 
     // Otherwise, if it does, remember that this is the right direntry for this
     // framework.
@@ -402,7 +449,7 @@
   // Set the 'user-specified system framework' flag.
   InUserSpecifiedSystemFramework = CacheEntry.IsUserSpecifiedSystemFramework;
 
-  if (RelativePath != NULL) {
+  if (RelativePath) {
     RelativePath->clear();
     RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
   }
@@ -412,7 +459,7 @@
 
   FrameworkName += "Headers/";
 
-  if (SearchPath != NULL) {
+  if (SearchPath) {
     SearchPath->clear();
     // Without trailing '/'.
     SearchPath->append(FrameworkName.begin(), FrameworkName.end()-1);
@@ -426,7 +473,7 @@
     const char *Private = "Private";
     FrameworkName.insert(FrameworkName.begin()+OrigSize, Private,
                          Private+strlen(Private));
-    if (SearchPath != NULL)
+    if (SearchPath)
       SearchPath->insert(SearchPath->begin()+OrigSize, Private,
                          Private+strlen(Private));
 
@@ -436,14 +483,9 @@
   // If we found the header and are allowed to suggest a module, do so now.
   if (FE && SuggestedModule) {
     // Find the framework in which this header occurs.
-    StringRef FrameworkPath = FE->getName();
+    StringRef FrameworkPath = FE->getDir()->getName();
     bool FoundFramework = false;
     do {
-      // Get the parent directory name.
-      FrameworkPath = llvm::sys::path::parent_path(FrameworkPath);
-      if (FrameworkPath.empty())
-        break;
-
       // Determine whether this directory exists.
       const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkPath);
       if (!Dir)
@@ -455,6 +497,11 @@
         FoundFramework = true;
         break;
       }
+
+      // Get the parent directory name.
+      FrameworkPath = llvm::sys::path::parent_path(FrameworkPath);
+      if (FrameworkPath.empty())
+        break;
     } while (true);
 
     if (FoundFramework) {
@@ -488,28 +535,43 @@
 // Header File Location.
 //===----------------------------------------------------------------------===//
 
+/// \brief Return true with a diagnostic if the file that MSVC would have found
+/// fails to match the one that Clang would have found with MSVC header search
+/// disabled.
+static bool checkMSVCHeaderSearch(DiagnosticsEngine &Diags,
+                                  const FileEntry *MSFE, const FileEntry *FE,
+                                  SourceLocation IncludeLoc) {
+  if (MSFE && FE != MSFE) {
+    Diags.Report(IncludeLoc, diag::ext_pp_include_search_ms) << MSFE->getName();
+    return true;
+  }
+  return false;
+}
+
+static const char *copyString(StringRef Str, llvm::BumpPtrAllocator &Alloc) {
+  assert(!Str.empty());
+  char *CopyStr = Alloc.Allocate<char>(Str.size()+1);
+  std::copy(Str.begin(), Str.end(), CopyStr);
+  CopyStr[Str.size()] = '\0';
+  return CopyStr;
+}
 
 /// LookupFile - Given a "foo" or \<foo> reference, look up the indicated file,
 /// return null on failure.  isAngled indicates whether the file reference is
-/// for system \#include's or not (i.e. using <> instead of "").  CurFileEnt, if
-/// non-null, indicates where the \#including file is, in case a relative search
-/// is needed.
+/// for system \#include's or not (i.e. using <> instead of ""). Includers, if
+/// non-empty, indicates where the \#including file(s) are, in case a relative
+/// search is needed. Microsoft mode will pass all \#including files.
 const FileEntry *HeaderSearch::LookupFile(
-    StringRef Filename,
-    bool isAngled,
-    const DirectoryLookup *FromDir,
-    const DirectoryLookup *&CurDir,
-    const FileEntry *CurFileEnt,
-    SmallVectorImpl<char> *SearchPath,
+    StringRef Filename, SourceLocation IncludeLoc, bool isAngled,
+    const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir,
+    ArrayRef<const FileEntry *> Includers, SmallVectorImpl<char> *SearchPath,
     SmallVectorImpl<char> *RelativePath,
-    ModuleMap::KnownHeader *SuggestedModule,
-    bool SkipCache)
-{
+    ModuleMap::KnownHeader *SuggestedModule, bool SkipCache) {
   if (!HSOpts->ModuleMapFiles.empty()) {
     // Preload all explicitly specified module map files. This enables modules
     // map files lying in a directory structure separate from the header files
     // that they describe. These cannot be loaded lazily upon encountering a
-    // header file, as there is no other knwon mapping from a header file to its
+    // header file, as there is no other known mapping from a header file to its
     // module map file.
     for (llvm::SetVector<std::string>::iterator
              I = HSOpts->ModuleMapFiles.begin(),
@@ -528,14 +590,14 @@
     
   // If 'Filename' is absolute, check to see if it exists and no searching.
   if (llvm::sys::path::is_absolute(Filename)) {
-    CurDir = 0;
+    CurDir = nullptr;
 
     // If this was an #include_next "/absolute/file", fail.
-    if (FromDir) return 0;
+    if (FromDir) return nullptr;
 
-    if (SearchPath != NULL)
+    if (SearchPath)
       SearchPath->clear();
-    if (RelativePath != NULL) {
+    if (RelativePath) {
       RelativePath->clear();
       RelativePath->append(Filename.begin(), Filename.end());
     }
@@ -543,49 +605,82 @@
     return FileMgr.getFile(Filename, /*openFile=*/true);
   }
 
+  // This is the header that MSVC's header search would have found.
+  const FileEntry *MSFE = nullptr;
+  ModuleMap::KnownHeader MSSuggestedModule;
+
   // Unless disabled, check to see if the file is in the #includer's
-  // directory.  This has to be based on CurFileEnt, not CurDir, because
-  // CurFileEnt could be a #include of a subdirectory (#include "foo/bar.h") and
-  // a subsequent include of "baz.h" should resolve to "whatever/foo/baz.h".
+  // directory.  This cannot be based on CurDir, because each includer could be
+  // a #include of a subdirectory (#include "foo/bar.h") and a subsequent
+  // include of "baz.h" should resolve to "whatever/foo/baz.h".
   // This search is not done for <> headers.
-  if (CurFileEnt && !isAngled && !NoCurDirSearch) {
+  if (!Includers.empty() && !isAngled && !NoCurDirSearch) {
     SmallString<1024> TmpDir;
-    // Concatenate the requested file onto the directory.
-    // FIXME: Portability.  Filename concatenation should be in sys::Path.
-    TmpDir += CurFileEnt->getDir()->getName();
-    TmpDir.push_back('/');
-    TmpDir.append(Filename.begin(), Filename.end());
-    if (const FileEntry *FE = FileMgr.getFile(TmpDir.str(),/*openFile=*/true)) {
-      // Leave CurDir unset.
-      // This file is a system header or C++ unfriendly if the old file is.
-      //
-      // Note that we only use one of FromHFI/ToHFI at once, due to potential
-      // reallocation of the underlying vector potentially making the first
-      // reference binding dangling.
-      HeaderFileInfo &FromHFI = getFileInfo(CurFileEnt);
-      unsigned DirInfo = FromHFI.DirInfo;
-      bool IndexHeaderMapHeader = FromHFI.IndexHeaderMapHeader;
-      StringRef Framework = FromHFI.Framework;
+    for (ArrayRef<const FileEntry *>::iterator I = Includers.begin(),
+                                               E = Includers.end();
+         I != E; ++I) {
+      const FileEntry *Includer = *I;
+      // Concatenate the requested file onto the directory.
+      // FIXME: Portability.  Filename concatenation should be in sys::Path.
+      TmpDir = Includer->getDir()->getName();
+      TmpDir.push_back('/');
+      TmpDir.append(Filename.begin(), Filename.end());
 
-      HeaderFileInfo &ToHFI = getFileInfo(FE);
-      ToHFI.DirInfo = DirInfo;
-      ToHFI.IndexHeaderMapHeader = IndexHeaderMapHeader;
-      ToHFI.Framework = Framework;
+      // FIXME: We don't cache the result of getFileInfo across the call to
+      // getFileAndSuggestModule, because it's a reference to an element of
+      // a container that could be reallocated across this call.
+      bool IncluderIsSystemHeader =
+          getFileInfo(Includer).DirInfo != SrcMgr::C_User;
+      if (const FileEntry *FE =
+              getFileAndSuggestModule(*this, TmpDir.str(), Includer->getDir(),
+                                      IncluderIsSystemHeader,
+                                      SuggestedModule)) {
+        // Leave CurDir unset.
+        // This file is a system header or C++ unfriendly if the old file is.
+        //
+        // Note that we only use one of FromHFI/ToHFI at once, due to potential
+        // reallocation of the underlying vector potentially making the first
+        // reference binding dangling.
+        HeaderFileInfo &FromHFI = getFileInfo(Includer);
+        unsigned DirInfo = FromHFI.DirInfo;
+        bool IndexHeaderMapHeader = FromHFI.IndexHeaderMapHeader;
+        StringRef Framework = FromHFI.Framework;
 
-      if (SearchPath != NULL) {
-        StringRef SearchPathRef(CurFileEnt->getDir()->getName());
-        SearchPath->clear();
-        SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
+        HeaderFileInfo &ToHFI = getFileInfo(FE);
+        ToHFI.DirInfo = DirInfo;
+        ToHFI.IndexHeaderMapHeader = IndexHeaderMapHeader;
+        ToHFI.Framework = Framework;
+
+        if (SearchPath) {
+          StringRef SearchPathRef(Includer->getDir()->getName());
+          SearchPath->clear();
+          SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
+        }
+        if (RelativePath) {
+          RelativePath->clear();
+          RelativePath->append(Filename.begin(), Filename.end());
+        }
+        if (I == Includers.begin())
+          return FE;
+
+        // Otherwise, we found the path via MSVC header search rules.  If
+        // -Wmsvc-include is enabled, we have to keep searching to see if we
+        // would've found this header in -I or -isystem directories.
+        if (Diags.isIgnored(diag::ext_pp_include_search_ms, IncludeLoc)) {
+          return FE;
+        } else {
+          MSFE = FE;
+          if (SuggestedModule) {
+            MSSuggestedModule = *SuggestedModule;
+            *SuggestedModule = ModuleMap::KnownHeader();
+          }
+          break;
+        }
       }
-      if (RelativePath != NULL) {
-        RelativePath->clear();
-        RelativePath->append(Filename.begin(), Filename.end());
-      }
-      return FE;
     }
   }
 
-  CurDir = 0;
+  CurDir = nullptr;
 
   // If this is a system #include, ignore the user #include locs.
   unsigned i = isAngled ? AngledDirIdx : 0;
@@ -599,28 +694,38 @@
   // multiply included, and the "pragma once" optimization prevents them from
   // being relex/pp'd, but they would still have to search through a
   // (potentially huge) series of SearchDirs to find it.
-  std::pair<unsigned, unsigned> &CacheLookup =
+  LookupFileCacheInfo &CacheLookup =
     LookupFileCache.GetOrCreateValue(Filename).getValue();
 
   // If the entry has been previously looked up, the first value will be
   // non-zero.  If the value is equal to i (the start point of our search), then
   // this is a matching hit.
-  if (!SkipCache && CacheLookup.first == i+1) {
+  if (!SkipCache && CacheLookup.StartIdx == i+1) {
     // Skip querying potentially lots of directories for this lookup.
-    i = CacheLookup.second;
+    i = CacheLookup.HitIdx;
+    if (CacheLookup.MappedName)
+      Filename = CacheLookup.MappedName;
   } else {
     // Otherwise, this is the first query, or the previous query didn't match
     // our search start.  We will fill in our found location below, so prime the
     // start point value.
-    CacheLookup.first = i+1;
+    CacheLookup.reset(/*StartIdx=*/i+1);
   }
 
+  SmallString<64> MappedName;
+
   // Check each directory in sequence to see if it contains this file.
   for (; i != SearchDirs.size(); ++i) {
     bool InUserSpecifiedSystemFramework = false;
+    bool HasBeenMapped = false;
     const FileEntry *FE =
       SearchDirs[i].LookupFile(Filename, *this, SearchPath, RelativePath,
-                               SuggestedModule, InUserSpecifiedSystemFramework);
+                               SuggestedModule, InUserSpecifiedSystemFramework,
+                               HasBeenMapped, MappedName);
+    if (HasBeenMapped) {
+      CacheLookup.MappedName =
+          copyString(Filename, LookupFileCache.getAllocator());
+    }
     if (!FE) continue;
 
     CurDir = &SearchDirs[i];
@@ -655,9 +760,15 @@
                                                          SlashPos));
       }
     }
-    
+
+    if (checkMSVCHeaderSearch(Diags, MSFE, FE, IncludeLoc)) {
+      if (SuggestedModule)
+        *SuggestedModule = MSSuggestedModule;
+      return MSFE;
+    }
+
     // Remember this location for the next lookup we do.
-    CacheLookup.second = i;
+    CacheLookup.HitIdx = i;
     return FE;
   }
 
@@ -665,29 +776,43 @@
   // a header in a framework that is currently being built, and we couldn't
   // resolve "foo.h" any other way, change the include to <Foo/foo.h>, where
   // "Foo" is the name of the framework in which the including header was found.
-  if (CurFileEnt && !isAngled && Filename.find('/') == StringRef::npos) {
-    HeaderFileInfo &IncludingHFI = getFileInfo(CurFileEnt);
+  if (!Includers.empty() && !isAngled &&
+      Filename.find('/') == StringRef::npos) {
+    HeaderFileInfo &IncludingHFI = getFileInfo(Includers.front());
     if (IncludingHFI.IndexHeaderMapHeader) {
       SmallString<128> ScratchFilename;
       ScratchFilename += IncludingHFI.Framework;
       ScratchFilename += '/';
       ScratchFilename += Filename;
-      
-      const FileEntry *Result = LookupFile(ScratchFilename, /*isAngled=*/true,
-                                           FromDir, CurDir, CurFileEnt, 
-                                           SearchPath, RelativePath,
-                                           SuggestedModule);
-      std::pair<unsigned, unsigned> &CacheLookup 
+
+      const FileEntry *FE = LookupFile(
+          ScratchFilename, IncludeLoc, /*isAngled=*/true, FromDir, CurDir,
+          Includers.front(), SearchPath, RelativePath, SuggestedModule);
+
+      if (checkMSVCHeaderSearch(Diags, MSFE, FE, IncludeLoc)) {
+        if (SuggestedModule)
+          *SuggestedModule = MSSuggestedModule;
+        return MSFE;
+      }
+
+      LookupFileCacheInfo &CacheLookup 
         = LookupFileCache.GetOrCreateValue(Filename).getValue();
-      CacheLookup.second
-        = LookupFileCache.GetOrCreateValue(ScratchFilename).getValue().second;
-      return Result;
+      CacheLookup.HitIdx
+        = LookupFileCache.GetOrCreateValue(ScratchFilename).getValue().HitIdx;
+      // FIXME: SuggestedModule.
+      return FE;
     }
   }
 
+  if (checkMSVCHeaderSearch(Diags, MSFE, nullptr, IncludeLoc)) {
+    if (SuggestedModule)
+      *SuggestedModule = MSSuggestedModule;
+    return MSFE;
+  }
+
   // Otherwise, didn't find it. Remember we didn't find this.
-  CacheLookup.second = SearchDirs.size();
-  return 0;
+  CacheLookup.HitIdx = SearchDirs.size();
+  return nullptr;
 }
 
 /// LookupSubframeworkHeader - Look up a subframework for the specified
@@ -706,7 +831,7 @@
   // Framework names must have a '/' in the filename.  Find it.
   // FIXME: Should we permit '\' on Windows?
   size_t SlashPos = Filename.find('/');
-  if (SlashPos == StringRef::npos) return 0;
+  if (SlashPos == StringRef::npos) return nullptr;
 
   // Look up the base framework name of the ContextFileEnt.
   const char *ContextName = ContextFileEnt->getName();
@@ -714,10 +839,10 @@
   // If the context info wasn't a framework, couldn't be a subframework.
   const unsigned DotFrameworkLen = 10;
   const char *FrameworkPos = strstr(ContextName, ".framework");
-  if (FrameworkPos == 0 || 
+  if (FrameworkPos == nullptr ||
       (FrameworkPos[DotFrameworkLen] != '/' && 
        FrameworkPos[DotFrameworkLen] != '\\'))
-    return 0;
+    return nullptr;
 
   SmallString<1024> FrameworkName(ContextName, FrameworkPos+DotFrameworkLen+1);
 
@@ -734,24 +859,24 @@
       CacheLookup.getKeyLength() == FrameworkName.size() &&
       memcmp(CacheLookup.getKeyData(), &FrameworkName[0],
              CacheLookup.getKeyLength()) != 0)
-    return 0;
+    return nullptr;
 
   // Cache subframework.
-  if (CacheLookup.getValue().Directory == 0) {
+  if (!CacheLookup.getValue().Directory) {
     ++NumSubFrameworkLookups;
 
     // If the framework dir doesn't exist, we fail.
     const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName.str());
-    if (Dir == 0) return 0;
+    if (!Dir) return nullptr;
 
     // Otherwise, if it does, remember that this is the right direntry for this
     // framework.
     CacheLookup.getValue().Directory = Dir;
   }
 
-  const FileEntry *FE = 0;
+  const FileEntry *FE = nullptr;
 
-  if (RelativePath != NULL) {
+  if (RelativePath) {
     RelativePath->clear();
     RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
   }
@@ -759,7 +884,7 @@
   // Check ".../Frameworks/HIToolbox.framework/Headers/HIToolbox.h"
   SmallString<1024> HeadersFilename(FrameworkName);
   HeadersFilename += "Headers/";
-  if (SearchPath != NULL) {
+  if (SearchPath) {
     SearchPath->clear();
     // Without trailing '/'.
     SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
@@ -771,7 +896,7 @@
     // Check ".../Frameworks/HIToolbox.framework/PrivateHeaders/HIToolbox.h"
     HeadersFilename = FrameworkName;
     HeadersFilename += "PrivateHeaders/";
-    if (SearchPath != NULL) {
+    if (SearchPath) {
       SearchPath->clear();
       // Without trailing '/'.
       SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
@@ -779,7 +904,7 @@
 
     HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
     if (!(FE = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true)))
-      return 0;
+      return nullptr;
   }
 
   // This file is a system header or C++ unfriendly if the old file is.
@@ -873,9 +998,21 @@
   HeaderFileInfo &HFI = FileInfo[FE->getUID()];
   if (ExternalSource && !HFI.Resolved)
     mergeHeaderFileInfo(HFI, ExternalSource->GetHeaderFileInfo(FE));
+  HFI.IsValid = 1;
   return HFI;
 }
 
+bool HeaderSearch::tryGetFileInfo(const FileEntry *FE, HeaderFileInfo &Result) const {
+  if (FE->getUID() >= FileInfo.size())
+    return false;
+  const HeaderFileInfo &HFI = FileInfo[FE->getUID()];
+  if (HFI.IsValid) {
+    Result = HFI;
+    return true;
+  }
+  return false;
+}
+
 bool HeaderSearch::isFileMultipleIncludeGuarded(const FileEntry *File) {
   // Check if we've ever seen this file as a header.
   if (File->getUID() >= FileInfo.size())
@@ -953,6 +1090,9 @@
 bool HeaderSearch::hasModuleMap(StringRef FileName, 
                                 const DirectoryEntry *Root,
                                 bool IsSystem) {
+  if (!enabledModules())
+    return false;
+
   SmallVector<const DirectoryEntry *, 2> FixUpDirectories;
   
   StringRef DirName = FileName;
@@ -967,8 +1107,8 @@
     if (!Dir)
       return false;
 
-    // Try to load the "module.map" file in this directory.
-    switch (loadModuleMapFile(Dir, IsSystem)) {
+    // Try to load the module map file in this directory.
+    switch (loadModuleMapFile(Dir, IsSystem, /*IsFramework*/false)) {
     case LMM_NewlyLoaded:
     case LMM_AlreadyLoaded:
       // Success. All of the directories we stepped through inherit this module
@@ -1002,122 +1142,127 @@
   return ModMap.findModuleForHeader(File);
 }
 
-bool HeaderSearch::loadModuleMapFile(const FileEntry *File, bool IsSystem) {
-  const DirectoryEntry *Dir = File->getDir();
-  
-  llvm::DenseMap<const DirectoryEntry *, bool>::iterator KnownDir
-    = DirectoryHasModuleMap.find(Dir);
-  if (KnownDir != DirectoryHasModuleMap.end())
-    return !KnownDir->second;
-  
-  bool Result = ModMap.parseModuleMapFile(File, IsSystem);
-  if (!Result && llvm::sys::path::filename(File->getName()) == "module.map") {
-    // If the file we loaded was a module.map, look for the corresponding
-    // module_private.map.
-    SmallString<128> PrivateFilename(Dir->getName());
+static const FileEntry *getPrivateModuleMap(StringRef ModuleMapPath,
+                                            const DirectoryEntry *Directory,
+                                            FileManager &FileMgr) {
+  StringRef Filename = llvm::sys::path::filename(ModuleMapPath);
+  SmallString<128>  PrivateFilename(Directory->getName());
+  if (Filename == "module.map")
     llvm::sys::path::append(PrivateFilename, "module_private.map");
-    if (const FileEntry *PrivateFile = FileMgr.getFile(PrivateFilename))
-      Result = ModMap.parseModuleMapFile(PrivateFile, IsSystem);
-  }
-  
-  DirectoryHasModuleMap[Dir] = !Result;  
-  return Result;
+  else if (Filename == "module.modulemap")
+    llvm::sys::path::append(PrivateFilename, "module.private.modulemap");
+  else
+    return nullptr;
+  return FileMgr.getFile(PrivateFilename);
 }
 
-Module *HeaderSearch::loadFrameworkModule(StringRef Name, 
+bool HeaderSearch::loadModuleMapFile(const FileEntry *File, bool IsSystem) {
+  switch (loadModuleMapFileImpl(File, IsSystem)) {
+  case LMM_AlreadyLoaded:
+  case LMM_NewlyLoaded:
+    return false;
+  case LMM_NoDirectory:
+  case LMM_InvalidModuleMap:
+    return true;
+  }
+  llvm_unreachable("Unknown load module map result");
+}
+
+HeaderSearch::LoadModuleMapResult
+HeaderSearch::loadModuleMapFileImpl(const FileEntry *File, bool IsSystem) {
+  assert(File && "expected FileEntry");
+
+  const DirectoryEntry *Dir = File->getDir();
+  auto KnownDir = DirectoryHasModuleMap.find(Dir);
+  if (KnownDir != DirectoryHasModuleMap.end())
+    return KnownDir->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
+
+  if (ModMap.parseModuleMapFile(File, IsSystem)) {
+    DirectoryHasModuleMap[Dir] = false;
+    return LMM_InvalidModuleMap;
+  }
+
+  // Try to load a corresponding private module map.
+  if (const FileEntry *PMMFile =
+        getPrivateModuleMap(File->getName(), Dir, FileMgr)) {
+    if (ModMap.parseModuleMapFile(PMMFile, IsSystem)) {
+      DirectoryHasModuleMap[Dir] = false;
+      return LMM_InvalidModuleMap;
+    }
+  }
+
+  // This directory has a module map.
+  DirectoryHasModuleMap[Dir] = true;
+  return LMM_NewlyLoaded;
+}
+
+const FileEntry *
+HeaderSearch::lookupModuleMapFile(const DirectoryEntry *Dir, bool IsFramework) {
+  // For frameworks, the preferred spelling is Modules/module.modulemap, but
+  // module.map at the framework root is also accepted.
+  SmallString<128> ModuleMapFileName(Dir->getName());
+  if (IsFramework)
+    llvm::sys::path::append(ModuleMapFileName, "Modules");
+  llvm::sys::path::append(ModuleMapFileName, "module.modulemap");
+  if (const FileEntry *F = FileMgr.getFile(ModuleMapFileName))
+    return F;
+
+  // Continue to allow module.map
+  ModuleMapFileName = Dir->getName();
+  llvm::sys::path::append(ModuleMapFileName, "module.map");
+  return FileMgr.getFile(ModuleMapFileName);
+}
+
+Module *HeaderSearch::loadFrameworkModule(StringRef Name,
                                           const DirectoryEntry *Dir,
                                           bool IsSystem) {
   if (Module *Module = ModMap.findModule(Name))
     return Module;
   
   // Try to load a module map file.
-  switch (loadModuleMapFile(Dir, IsSystem)) {
+  switch (loadModuleMapFile(Dir, IsSystem, /*IsFramework*/true)) {
   case LMM_InvalidModuleMap:
     break;
     
   case LMM_AlreadyLoaded:
   case LMM_NoDirectory:
-    return 0;
-    
+    return nullptr;
+
   case LMM_NewlyLoaded:
     return ModMap.findModule(Name);
   }
 
-  // Figure out the top-level framework directory and the submodule path from
-  // that top-level framework to the requested framework.
-  SmallVector<std::string, 2> SubmodulePath;
-  SubmodulePath.push_back(Name);
-  const DirectoryEntry *TopFrameworkDir
-    = ::getTopFrameworkDir(FileMgr, Dir->getName(), SubmodulePath);
 
-
-  // Try to infer a module map from the top-level framework directory.
-  Module *Result = ModMap.inferFrameworkModule(SubmodulePath.back(), 
-                                               TopFrameworkDir,
-                                               IsSystem,
-                                               /*Parent=*/0);
-  if (!Result)
-    return 0;
-  
-  // Follow the submodule path to find the requested (sub)framework module
-  // within the top-level framework module.
-  SubmodulePath.pop_back();
-  while (!SubmodulePath.empty() && Result) {
-    Result = ModMap.lookupModuleQualified(SubmodulePath.back(), Result);
-    SubmodulePath.pop_back();
-  }
-  return Result;
+  // Try to infer a module map from the framework directory.
+  return ModMap.inferFrameworkModule(Name, Dir, IsSystem, /*Parent=*/nullptr);
 }
 
 
 HeaderSearch::LoadModuleMapResult 
-HeaderSearch::loadModuleMapFile(StringRef DirName, bool IsSystem) {
+HeaderSearch::loadModuleMapFile(StringRef DirName, bool IsSystem,
+                                bool IsFramework) {
   if (const DirectoryEntry *Dir = FileMgr.getDirectory(DirName))
-    return loadModuleMapFile(Dir, IsSystem);
+    return loadModuleMapFile(Dir, IsSystem, IsFramework);
   
   return LMM_NoDirectory;
 }
 
 HeaderSearch::LoadModuleMapResult 
-HeaderSearch::loadModuleMapFile(const DirectoryEntry *Dir, bool IsSystem) {
-  llvm::DenseMap<const DirectoryEntry *, bool>::iterator KnownDir
-    = DirectoryHasModuleMap.find(Dir);
+HeaderSearch::loadModuleMapFile(const DirectoryEntry *Dir, bool IsSystem,
+                                bool IsFramework) {
+  auto KnownDir = DirectoryHasModuleMap.find(Dir);
   if (KnownDir != DirectoryHasModuleMap.end())
     return KnownDir->second? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
-  
-  SmallString<128> ModuleMapFileName;
-  ModuleMapFileName += Dir->getName();
-  unsigned ModuleMapDirNameLen = ModuleMapFileName.size();
-  llvm::sys::path::append(ModuleMapFileName, "module.map");
-  if (const FileEntry *ModuleMapFile = FileMgr.getFile(ModuleMapFileName)) {
-    // We have found a module map file. Try to parse it.
-    if (ModMap.parseModuleMapFile(ModuleMapFile, IsSystem)) {
-      // No suitable module map.
-      DirectoryHasModuleMap[Dir] = false;
-      return LMM_InvalidModuleMap;
-    }
 
-    // This directory has a module map.
-    DirectoryHasModuleMap[Dir] = true;
-    
-    // Check whether there is a private module map that we need to load as well.
-    ModuleMapFileName.erase(ModuleMapFileName.begin() + ModuleMapDirNameLen,
-                            ModuleMapFileName.end());
-    llvm::sys::path::append(ModuleMapFileName, "module_private.map");
-    if (const FileEntry *PrivateModuleMapFile
-                                        = FileMgr.getFile(ModuleMapFileName)) {
-      if (ModMap.parseModuleMapFile(PrivateModuleMapFile, IsSystem)) {
-        // No suitable module map.
-        DirectoryHasModuleMap[Dir] = false;
-        return LMM_InvalidModuleMap;
-      }      
-    }
-    
-    return LMM_NewlyLoaded;
+  if (const FileEntry *ModuleMapFile = lookupModuleMapFile(Dir, IsFramework)) {
+    LoadModuleMapResult Result = loadModuleMapFileImpl(ModuleMapFile, IsSystem);
+    // Add Dir explicitly in case ModuleMapFile is in a subdirectory.
+    // E.g. Foo.framework/Modules/module.modulemap
+    //      ^Dir                  ^ModuleMapFile
+    if (Result == LMM_NewlyLoaded)
+      DirectoryHasModuleMap[Dir] = true;
+    return Result;
   }
-  
-  // No suitable module map.
-  DirectoryHasModuleMap[Dir] = false;
   return LMM_InvalidModuleMap;
 }
 
@@ -1128,7 +1273,7 @@
   for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
     bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory();
     if (SearchDirs[Idx].isFramework()) {
-      llvm::error_code EC;
+      std::error_code EC;
       SmallString<128> DirNative;
       llvm::sys::path::native(SearchDirs[Idx].getFrameworkDir()->getName(),
                               DirNative);
@@ -1155,7 +1300,7 @@
       continue;
     
     // Try to load a module map file for the search directory.
-    loadModuleMapFile(SearchDirs[Idx].getDir(), IsSystem);
+    loadModuleMapFile(SearchDirs[Idx].getDir(), IsSystem, /*IsFramework*/false);
     
     // Try to load module map files for immediate subdirectories of this search
     // directory.
@@ -1180,20 +1325,22 @@
 
     // Try to load a module map file for the search directory.
     loadModuleMapFile(SearchDirs[Idx].getDir(),
-                      SearchDirs[Idx].isSystemHeaderDirectory());
+                      SearchDirs[Idx].isSystemHeaderDirectory(),
+                      SearchDirs[Idx].isFramework());
   }
 }
 
 void HeaderSearch::loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir) {
   if (SearchDir.haveSearchedAllModuleMaps())
     return;
-  
-  llvm::error_code EC;
+
+  std::error_code EC;
   SmallString<128> DirNative;
   llvm::sys::path::native(SearchDir.getDir()->getName(), DirNative);
   for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd;
        Dir != DirEnd && !EC; Dir.increment(EC)) {
-    loadModuleMapFile(Dir->path(), SearchDir.isSystemHeaderDirectory());
+    loadModuleMapFile(Dir->path(), SearchDir.isSystemHeaderDirectory(),
+                      SearchDir.isFramework());
   }
 
   SearchDir.setSearchedAllModuleMaps(true);
diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp
index c071455..6f6b50b 100644
--- a/lib/Lex/Lexer.cpp
+++ b/lib/Lex/Lexer.cpp
@@ -10,21 +10,9 @@
 //  This file implements the Lexer and Token interfaces.
 //
 //===----------------------------------------------------------------------===//
-//
-// TODO: GCC Diagnostics emitted by the lexer:
-// PEDWARN: (form feed|vertical tab) in preprocessing directive
-//
-// Universal characters, unicode, char mapping:
-// WARNING: `%.*s' is not in NFKC
-// WARNING: `%.*s' is not in NFC
-//
-// Other:
-// TODO: Options to support:
-//    -fexec-charset,-fwide-exec-charset
-//
-//===----------------------------------------------------------------------===//
 
 #include "clang/Lex/Lexer.h"
+#include "UnicodeCharSets.h"
 #include "clang/Basic/CharInfo.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Lex/CodeCompletionHandler.h"
@@ -37,7 +25,6 @@
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/ConvertUTF.h"
 #include "llvm/Support/MemoryBuffer.h"
-#include "UnicodeCharSets.h"
 #include <cstring>
 using namespace clang;
 
@@ -174,7 +161,7 @@
 /// expansion location that indicates where all lexed tokens should be
 /// "expanded from".
 ///
-/// FIXME: It would really be nice to make _Pragma just be a wrapper around a
+/// TODO: It would really be nice to make _Pragma just be a wrapper around a
 /// normal lexer that remaps tokens as they fly by.  This would require making
 /// Preprocessor::Lex virtual.  Given that, we could just dump in a magic lexer
 /// interface that could handle this stuff.  This would pull GetMappedTokenLoc
@@ -379,10 +366,10 @@
                             const LangOptions &LangOpts, bool *Invalid) {
   assert((int)Tok.getLength() >= 0 && "Token character range is bogus!");
 
-  const char *TokStart = 0;
+  const char *TokStart = nullptr;
   // NOTE: this has to be checked *before* testing for an IdentifierInfo.
   if (Tok.is(tok::raw_identifier))
-    TokStart = Tok.getRawIdentifierData();
+    TokStart = Tok.getRawIdentifier().data();
   else if (!Tok.hasUCN()) {
     if (const IdentifierInfo *II = Tok.getIdentifierInfo()) {
       // Just return the string from the identifier table, which is very quick.
@@ -395,7 +382,7 @@
   if (Tok.isLiteral())
     TokStart = Tok.getLiteralData();
 
-  if (TokStart == 0) {
+  if (!TokStart) {
     // Compute the start of the token in the input lexer buffer.
     bool CharDataInvalid = false;
     TokStart = SourceMgr.getCharacterData(Tok.getLocation(), &CharDataInvalid);
@@ -637,8 +624,7 @@
       // the raw identifier to recognize and categorize preprocessor directives.
       TheLexer.LexFromRawLexer(TheTok);
       if (TheTok.getKind() == tok::raw_identifier && !TheTok.needsCleaning()) {
-        StringRef Keyword(TheTok.getRawIdentifierData(),
-                                TheTok.getLength());
+        StringRef Keyword = TheTok.getRawIdentifier();
         PreambleDirectiveKind PDK
           = llvm::StringSwitch<PreambleDirectiveKind>(Keyword)
               .Case("include", PDK_Skipped)
@@ -861,7 +847,7 @@
   // Break down the source locations.
   FileID FID;
   unsigned BeginOffs;
-  llvm::tie(FID, BeginOffs) = SM.getDecomposedLoc(Begin);
+  std::tie(FID, BeginOffs) = SM.getDecomposedLoc(Begin);
   if (FID.isInvalid())
     return CharSourceRange();
 
@@ -1287,7 +1273,7 @@
   if (Ptr[0] == '?' && Ptr[1] == '?') {
     // If this is actually a legal trigraph (not something like "??x"), emit
     // a trigraph warning.  If so, and if trigraphs are enabled, return it.
-    if (char C = DecodeTrigraphChar(Ptr+2, Tok ? this : 0)) {
+    if (char C = DecodeTrigraphChar(Ptr+2, Tok ? this : nullptr)) {
       // Remember that this token needs to be cleaned.
       if (Tok) Tok->setFlag(Token::NeedsCleaning);
 
@@ -1413,8 +1399,7 @@
 static void maybeDiagnoseIDCharCompat(DiagnosticsEngine &Diags, uint32_t C,
                                       CharSourceRange Range, bool IsFirst) {
   // Check C99 compatibility.
-  if (Diags.getDiagnosticLevel(diag::warn_c99_compat_unicode_id,
-                               Range.getBegin()) > DiagnosticsEngine::Ignored) {
+  if (!Diags.isIgnored(diag::warn_c99_compat_unicode_id, Range.getBegin())) {
     enum {
       CannotAppearInIdentifier = 0,
       CannotStartIdentifier
@@ -1436,8 +1421,7 @@
   }
 
   // Check C++98 compatibility.
-  if (Diags.getDiagnosticLevel(diag::warn_cxx98_compat_unicode_id,
-                               Range.getBegin()) > DiagnosticsEngine::Ignored) {
+  if (!Diags.isIgnored(diag::warn_cxx98_compat_unicode_id, Range.getBegin())) {
     static const llvm::sys::UnicodeCharSet CXX03AllowedIDChars(
         CXX03AllowedIDCharRanges);
     if (!CXX03AllowedIDChars.contains(C)) {
@@ -1445,7 +1429,50 @@
         << Range;
     }
   }
- }
+}
+
+bool Lexer::tryConsumeIdentifierUCN(const char *&CurPtr, unsigned Size,
+                                    Token &Result) {
+  const char *UCNPtr = CurPtr + Size;
+  uint32_t CodePoint = tryReadUCN(UCNPtr, CurPtr, /*Token=*/nullptr);
+  if (CodePoint == 0 || !isAllowedIDChar(CodePoint, LangOpts))
+    return false;
+
+  if (!isLexingRawMode())
+    maybeDiagnoseIDCharCompat(PP->getDiagnostics(), CodePoint,
+                              makeCharRange(*this, CurPtr, UCNPtr),
+                              /*IsFirst=*/false);
+
+  Result.setFlag(Token::HasUCN);
+  if ((UCNPtr - CurPtr ==  6 && CurPtr[1] == 'u') ||
+      (UCNPtr - CurPtr == 10 && CurPtr[1] == 'U'))
+    CurPtr = UCNPtr;
+  else
+    while (CurPtr != UCNPtr)
+      (void)getAndAdvanceChar(CurPtr, Result);
+  return true;
+}
+
+bool Lexer::tryConsumeIdentifierUTF8Char(const char *&CurPtr) {
+  const char *UnicodePtr = CurPtr;
+  UTF32 CodePoint;
+  ConversionResult Result =
+      llvm::convertUTF8Sequence((const UTF8 **)&UnicodePtr,
+                                (const UTF8 *)BufferEnd,
+                                &CodePoint,
+                                strictConversion);
+  if (Result != conversionOK ||
+      !isAllowedIDChar(static_cast<uint32_t>(CodePoint), LangOpts))
+    return false;
+
+  if (!isLexingRawMode())
+    maybeDiagnoseIDCharCompat(PP->getDiagnostics(), CodePoint,
+                              makeCharRange(*this, CurPtr, UnicodePtr),
+                              /*IsFirst=*/false);
+
+  CurPtr = UnicodePtr;
+  return true;
+}
 
 bool Lexer::LexIdentifier(Token &Result, const char *CurPtr) {
   // Match [_A-Za-z0-9]*, we have already matched [_A-Za-z$]
@@ -1500,47 +1527,10 @@
       C = getCharAndSize(CurPtr, Size);
       continue;
 
-    } else if (C == '\\') {
-      const char *UCNPtr = CurPtr + Size;
-      uint32_t CodePoint = tryReadUCN(UCNPtr, CurPtr, /*Token=*/0);
-      if (CodePoint == 0 || !isAllowedIDChar(CodePoint, LangOpts))
-        goto FinishIdentifier;
-
-      if (!isLexingRawMode()) {
-        maybeDiagnoseIDCharCompat(PP->getDiagnostics(), CodePoint,
-                                  makeCharRange(*this, CurPtr, UCNPtr),
-                                  /*IsFirst=*/false);
-      }
-
-      Result.setFlag(Token::HasUCN);
-      if ((UCNPtr - CurPtr ==  6 && CurPtr[1] == 'u') ||
-          (UCNPtr - CurPtr == 10 && CurPtr[1] == 'U'))
-        CurPtr = UCNPtr;
-      else
-        while (CurPtr != UCNPtr)
-          (void)getAndAdvanceChar(CurPtr, Result);
-
+    } else if (C == '\\' && tryConsumeIdentifierUCN(CurPtr, Size, Result)) {
       C = getCharAndSize(CurPtr, Size);
       continue;
-    } else if (!isASCII(C)) {
-      const char *UnicodePtr = CurPtr;
-      UTF32 CodePoint;
-      ConversionResult Result =
-          llvm::convertUTF8Sequence((const UTF8 **)&UnicodePtr,
-                                    (const UTF8 *)BufferEnd,
-                                    &CodePoint,
-                                    strictConversion);
-      if (Result != conversionOK ||
-          !isAllowedIDChar(static_cast<uint32_t>(CodePoint), LangOpts))
-        goto FinishIdentifier;
-
-      if (!isLexingRawMode()) {
-        maybeDiagnoseIDCharCompat(PP->getDiagnostics(), CodePoint,
-                                  makeCharRange(*this, CurPtr, UnicodePtr),
-                                  /*IsFirst=*/false);
-      }
-
-      CurPtr = UnicodePtr;
+    } else if (!isASCII(C) && tryConsumeIdentifierUTF8Char(CurPtr)) {
       C = getCharAndSize(CurPtr, Size);
       continue;
     } else if (!isIdentifierBody(C)) {
@@ -1576,7 +1566,7 @@
   unsigned Size;
   char C = getCharAndSize(CurPtr, Size);
   char PrevCh = 0;
-  while (isPreprocessingNumberBody(C)) { // FIXME: UCNs in ud-suffix.
+  while (isPreprocessingNumberBody(C)) {
     CurPtr = ConsumeChar(CurPtr, Size, Result);
     PrevCh = C;
     C = getCharAndSize(CurPtr, Size);
@@ -1614,10 +1604,17 @@
       if (!isLexingRawMode())
         Diag(CurPtr, diag::warn_cxx11_compat_digit_separator);
       CurPtr = ConsumeChar(CurPtr, Size, Result);
+      CurPtr = ConsumeChar(CurPtr, NextSize, Result);
       return LexNumericConstant(Result, CurPtr);
     }
   }
 
+  // If we have a UCN or UTF-8 character (perhaps in a ud-suffix), continue.
+  if (C == '\\' && tryConsumeIdentifierUCN(CurPtr, Size, Result))
+    return LexNumericConstant(Result, CurPtr);
+  if (!isASCII(C) && tryConsumeIdentifierUTF8Char(CurPtr))
+    return LexNumericConstant(Result, CurPtr);
+
   // Update the location of token as well as BufferPtr.
   const char *TokStart = BufferPtr;
   FormTokenWithChars(Result, CurPtr, tok::numeric_constant);
@@ -1631,23 +1628,35 @@
                                bool IsStringLiteral) {
   assert(getLangOpts().CPlusPlus);
 
-  // Maximally munch an identifier. FIXME: UCNs.
+  // Maximally munch an identifier.
   unsigned Size;
   char C = getCharAndSize(CurPtr, Size);
-  if (isIdentifierHead(C)) {
-    if (!getLangOpts().CPlusPlus11) {
-      if (!isLexingRawMode())
-        Diag(CurPtr,
-             C == '_' ? diag::warn_cxx11_compat_user_defined_literal
-                      : diag::warn_cxx11_compat_reserved_user_defined_literal)
-          << FixItHint::CreateInsertion(getSourceLocation(CurPtr), " ");
-      return CurPtr;
-    }
+  bool Consumed = false;
 
-    // C++11 [lex.ext]p10, [usrlit.suffix]p1: A program containing a ud-suffix
-    // that does not start with an underscore is ill-formed. As a conforming
-    // extension, we treat all such suffixes as if they had whitespace before
-    // them.
+  if (!isIdentifierHead(C)) {
+    if (C == '\\' && tryConsumeIdentifierUCN(CurPtr, Size, Result))
+      Consumed = true;
+    else if (!isASCII(C) && tryConsumeIdentifierUTF8Char(CurPtr))
+      Consumed = true;
+    else
+      return CurPtr;
+  }
+
+  if (!getLangOpts().CPlusPlus11) {
+    if (!isLexingRawMode())
+      Diag(CurPtr,
+           C == '_' ? diag::warn_cxx11_compat_user_defined_literal
+                    : diag::warn_cxx11_compat_reserved_user_defined_literal)
+        << FixItHint::CreateInsertion(getSourceLocation(CurPtr), " ");
+    return CurPtr;
+  }
+
+  // C++11 [lex.ext]p10, [usrlit.suffix]p1: A program containing a ud-suffix
+  // that does not start with an underscore is ill-formed. As a conforming
+  // extension, we treat all such suffixes as if they had whitespace before
+  // them. We assume a suffix beginning with a UCN or UTF-8 character is more
+  // likely to be a ud-suffix than a macro, however, and accept that.
+  if (!Consumed) {
     bool IsUDSuffix = false;
     if (C == '_')
       IsUDSuffix = true;
@@ -1682,19 +1691,25 @@
 
     if (!IsUDSuffix) {
       if (!isLexingRawMode())
-        Diag(CurPtr, getLangOpts().MicrosoftMode ?
-            diag::ext_ms_reserved_user_defined_literal :
-            diag::ext_reserved_user_defined_literal)
+        Diag(CurPtr, getLangOpts().MSVCCompat
+                         ? diag::ext_ms_reserved_user_defined_literal
+                         : diag::ext_reserved_user_defined_literal)
           << FixItHint::CreateInsertion(getSourceLocation(CurPtr), " ");
       return CurPtr;
     }
 
-    Result.setFlag(Token::HasUDSuffix);
-    do {
-      CurPtr = ConsumeChar(CurPtr, Size, Result);
-      C = getCharAndSize(CurPtr, Size);
-    } while (isIdentifierBody(C));
+    CurPtr = ConsumeChar(CurPtr, Size, Result);
   }
+
+  Result.setFlag(Token::HasUDSuffix);
+  while (true) {
+    C = getCharAndSize(CurPtr, Size);
+    if (isIdentifierBody(C)) { CurPtr = ConsumeChar(CurPtr, Size, Result); }
+    else if (C == '\\' && tryConsumeIdentifierUCN(CurPtr, Size, Result)) {}
+    else if (!isASCII(C) && tryConsumeIdentifierUTF8Char(CurPtr)) {}
+    else break;
+  }
+
   return CurPtr;
 }
 
@@ -1702,7 +1717,8 @@
 /// either " or L" or u8" or u" or U".
 bool Lexer::LexStringLiteral(Token &Result, const char *CurPtr,
                              tok::TokenKind Kind) {
-  const char *NulCharacter = 0; // Does this string contain the \0 character?
+  // Does this string contain the \0 character?
+  const char *NulCharacter = nullptr;
 
   if (!isLexingRawMode() &&
       (Kind == tok::utf8_string_literal ||
@@ -1838,7 +1854,8 @@
 /// LexAngledStringLiteral - Lex the remainder of an angled string literal,
 /// after having lexed the '<' character.  This is used for #include filenames.
 bool Lexer::LexAngledStringLiteral(Token &Result, const char *CurPtr) {
-  const char *NulCharacter = 0; // Does this string contain the \0 character?
+  // Does this string contain the \0 character?
+  const char *NulCharacter = nullptr;
   const char *AfterLessPos = CurPtr;
   char C = getAndAdvanceChar(CurPtr, Result);
   while (C != '>') {
@@ -1875,7 +1892,8 @@
 /// lexed either ' or L' or u' or U'.
 bool Lexer::LexCharConstant(Token &Result, const char *CurPtr,
                             tok::TokenKind Kind) {
-  const char *NulCharacter = 0; // Does this character contain the \0 character?
+  // Does this character contain the \0 character?
+  const char *NulCharacter = nullptr;
 
   if (!isLexingRawMode() &&
       (Kind == tok::utf16_char_constant || Kind == tok::utf32_char_constant))
@@ -2023,8 +2041,11 @@
     if (C != 0) {
       // We found a newline, see if it's escaped.
       const char *EscapePtr = CurPtr-1;
-      while (isHorizontalWhitespace(*EscapePtr)) // Skip whitespace.
+      bool HasSpace = false;
+      while (isHorizontalWhitespace(*EscapePtr)) { // Skip whitespace.
         --EscapePtr;
+        HasSpace = true;
+      }
 
       if (*EscapePtr == '\\') // Escaped newline.
         CurPtr = EscapePtr;
@@ -2033,6 +2054,10 @@
         CurPtr = EscapePtr-2;
       else
         break; // This is a newline, we're done.
+
+      // If there was space between the backslash and newline, warn about it.
+      if (HasSpace && !isLexingRawMode())
+        Diag(EscapePtr, diag::backslash_newline_space);
     }
 
     // Otherwise, this is a hard case.  Fall back on getAndAdvanceChar to
@@ -2460,7 +2485,8 @@
     FormTokenWithChars(Result, CurPtr, tok::eod);
 
     // Restore comment saving mode, in case it was disabled for directive.
-    resetExtendedTokenMode();
+    if (PP)
+      resetExtendedTokenMode();
     return true;  // Have a token.
   }
  
@@ -2494,8 +2520,7 @@
       // C++11 [lex.phases] 2.2 p2
       // Prefer the C++98 pedantic compatibility warning over the generic,
       // non-extension, user-requested "missing newline at EOF" warning.
-      if (Diags.getDiagnosticLevel(diag::warn_cxx98_compat_no_newline_eof,
-                                   EndLoc) != DiagnosticsEngine::Ignored) {
+      if (!Diags.isIgnored(diag::warn_cxx98_compat_no_newline_eof, EndLoc)) {
         DiagID = diag::warn_cxx98_compat_no_newline_eof;
       } else {
         DiagID = diag::warn_no_newline_eof;
@@ -2568,7 +2593,7 @@
     }
     return RestOfBuffer.data()+Pos;
   }
-  return 0;
+  return nullptr;
 }
 
 /// IsStartOfConflictMarker - If the specified pointer is the start of a version
@@ -2878,7 +2903,7 @@
 LexNextToken:
   // New token, can't need cleaning yet.
   Result.clearFlag(Token::NeedsCleaning);
-  Result.setIdentifierInfo(0);
+  Result.setIdentifierInfo(nullptr);
 
   // CurPtr - Cache BufferPtr in an automatic variable.
   const char *CurPtr = BufferPtr;
@@ -3344,7 +3369,7 @@
         // We parsed a # character.  If this occurs at the start of the line,
         // it's actually the start of a preprocessing directive.  Callback to
         // the preprocessor to handle it.
-        // FIXME: -fpreprocessed mode??
+        // TODO: -fpreprocessed mode??
         if (TokAtPhysicalStartOfLine && !LexingRawMode && !Is_PragmaLexer)
           goto HandleDirective;
 
@@ -3510,7 +3535,7 @@
       // We parsed a # character.  If this occurs at the start of the line,
       // it's actually the start of a preprocessing directive.  Callback to
       // the preprocessor to handle it.
-      // FIXME: -fpreprocessed mode??
+      // TODO: -fpreprocessed mode??
       if (TokAtPhysicalStartOfLine && !LexingRawMode && !Is_PragmaLexer)
         goto HandleDirective;
 
diff --git a/lib/Lex/LiteralSupport.cpp b/lib/Lex/LiteralSupport.cpp
index 17c6bb3..6417d0f 100644
--- a/lib/Lex/LiteralSupport.cpp
+++ b/lib/Lex/LiteralSupport.cpp
@@ -195,7 +195,7 @@
         << std::string(1, ResultChar);
     break;
   default:
-    if (Diags == 0)
+    if (!Diags)
       break;
 
     if (isPrintable(ResultChar))
@@ -212,6 +212,48 @@
   return ResultChar;
 }
 
+static void appendCodePoint(unsigned Codepoint,
+                            llvm::SmallVectorImpl<char> &Str) {
+  char ResultBuf[4];
+  char *ResultPtr = ResultBuf;
+  bool Res = llvm::ConvertCodePointToUTF8(Codepoint, ResultPtr);
+  (void)Res;
+  assert(Res && "Unexpected conversion failure");
+  Str.append(ResultBuf, ResultPtr);
+}
+
+void clang::expandUCNs(SmallVectorImpl<char> &Buf, StringRef Input) {
+  for (StringRef::iterator I = Input.begin(), E = Input.end(); I != E; ++I) {
+    if (*I != '\\') {
+      Buf.push_back(*I);
+      continue;
+    }
+
+    ++I;
+    assert(*I == 'u' || *I == 'U');
+
+    unsigned NumHexDigits;
+    if (*I == 'u')
+      NumHexDigits = 4;
+    else
+      NumHexDigits = 8;
+
+    assert(I + NumHexDigits <= E);
+
+    uint32_t CodePoint = 0;
+    for (++I; NumHexDigits != 0; ++I, --NumHexDigits) {
+      unsigned Value = llvm::hexDigitValue(*I);
+      assert(Value != -1U);
+
+      CodePoint <<= 4;
+      CodePoint += Value;
+    }
+
+    appendCodePoint(CodePoint, Buf);
+    --I;
+  }
+}
+
 /// ProcessUCNEscape - Read the Universal Character Name, check constraints and
 /// return the UTF32.
 static bool ProcessUCNEscape(const char *ThisTokBegin, const char *&ThisTokBuf,
@@ -298,7 +340,7 @@
   FullSourceLoc Loc;
 
   if (!ProcessUCNEscape(ThisTokBegin, ThisTokBuf, ThisTokEnd, UcnVal,
-                        UcnLen, Loc, 0, Features, true)) {
+                        UcnLen, Loc, nullptr, Features, true)) {
     HadError = true;
     return 0;
   }
@@ -480,7 +522,7 @@
   isLongLong = false;
   isFloat = false;
   isImaginary = false;
-  isMicrosoftInteger = false;
+  MicrosoftInteger = 0;
   hadError = false;
 
   if (*s == '0') { // parse radix
@@ -529,7 +571,7 @@
   // Parse the suffix.  At this point we can classify whether we have an FP or
   // integer constant.
   bool isFPConstant = isFloatingLiteral();
-  const char *ImaginarySuffixLoc = 0;
+  const char *ImaginarySuffixLoc = nullptr;
 
   // Loop over all of the characters of the suffix.  If we see something bad,
   // we break out of the loop.
@@ -564,49 +606,53 @@
     case 'i':
     case 'I':
       if (PP.getLangOpts().MicrosoftExt) {
-        if (isFPConstant || isLong || isLongLong) break;
+        if (isLong || isLongLong || MicrosoftInteger)
+          break;
 
         // Allow i8, i16, i32, i64, and i128.
         if (s + 1 != ThisTokEnd) {
           switch (s[1]) {
             case '8':
+              if (isFPConstant) break;
               s += 2; // i8 suffix
-              isMicrosoftInteger = true;
+              MicrosoftInteger = 8;
               break;
             case '1':
+              if (isFPConstant) break;
               if (s + 2 == ThisTokEnd) break;
               if (s[2] == '6') {
                 s += 3; // i16 suffix
-                isMicrosoftInteger = true;
+                MicrosoftInteger = 16;
               }
               else if (s[2] == '2') {
                 if (s + 3 == ThisTokEnd) break;
                 if (s[3] == '8') {
                   s += 4; // i128 suffix
-                  isMicrosoftInteger = true;
+                  MicrosoftInteger = 128;
                 }
               }
               break;
             case '3':
+              if (isFPConstant) break;
               if (s + 2 == ThisTokEnd) break;
               if (s[2] == '2') {
                 s += 3; // i32 suffix
-                isLong = true;
-                isMicrosoftInteger = true;
+                MicrosoftInteger = 32;
               }
               break;
             case '6':
+              if (isFPConstant) break;
               if (s + 2 == ThisTokEnd) break;
               if (s[2] == '4') {
                 s += 3; // i64 suffix
-                isLongLong = true;
-                isMicrosoftInteger = true;
+                MicrosoftInteger = 64;
               }
               break;
             default:
               break;
           }
-          break;
+          if (MicrosoftInteger)
+            break;
         }
       }
       // "i", "if", and "il" are user-defined suffixes in C++1y.
@@ -625,8 +671,9 @@
   }
 
   if (s != ThisTokEnd) {
-    if (isValidUDSuffix(PP.getLangOpts(),
-                        StringRef(SuffixBegin, ThisTokEnd - SuffixBegin))) {
+    // FIXME: Don't bother expanding UCNs if !tok.hasUCN().
+    expandUCNs(UDSuffixBuf, StringRef(SuffixBegin, ThisTokEnd - SuffixBegin));
+    if (isValidUDSuffix(PP.getLangOpts(), UDSuffixBuf)) {
       // Any suffix pieces we might have parsed are actually part of the
       // ud-suffix.
       isLong = false;
@@ -634,7 +681,7 @@
       isLongLong = false;
       isFloat = false;
       isImaginary = false;
-      isMicrosoftInteger = false;
+      MicrosoftInteger = 0;
 
       saw_ud_suffix = true;
       return;
@@ -722,6 +769,7 @@
       s++;
       saw_period = true;
       const char *floatDigitsBegin = s;
+      checkSeparator(TokLoc, s, CSK_BeforeDigits);
       s = SkipHexDigits(s);
       noSignificand &= (floatDigitsBegin == s);
     }
@@ -736,6 +784,7 @@
     // A binary exponent can appear with or with a '.'. If dotted, the
     // binary exponent is required.
     if (*s == 'p' || *s == 'P') {
+      checkSeparator(TokLoc, s, CSK_AfterDigits);
       const char *Exponent = s;
       s++;
       saw_exponent = true;
@@ -747,6 +796,7 @@
         hadError = true;
         return;
       }
+      checkSeparator(TokLoc, s, CSK_BeforeDigits);
       s = first_non_digit;
 
       if (!PP.getLangOpts().HexFloats)
@@ -815,9 +865,11 @@
     s++;
     radix = 10;
     saw_period = true;
+    checkSeparator(TokLoc, s, CSK_BeforeDigits);
     s = SkipDigits(s); // Skip suffix.
   }
   if (*s == 'e' || *s == 'E') { // exponent
+    checkSeparator(TokLoc, s, CSK_AfterDigits);
     const char *Exponent = s;
     s++;
     radix = 10;
@@ -825,6 +877,7 @@
     if (*s == '+' || *s == '-')  s++; // sign
     const char *first_non_digit = SkipDigits(s);
     if (first_non_digit != s) {
+      checkSeparator(TokLoc, s, CSK_BeforeDigits);
       s = first_non_digit;
     } else {
       PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, Exponent-ThisTokBegin),
@@ -992,7 +1045,8 @@
     do {
       --end;
     } while (end[-1] != '\'');
-    UDSuffixBuf.assign(end, UDSuffixEnd);
+    // FIXME: Don't bother with this if !tok.hasUCN().
+    expandUCNs(UDSuffixBuf, StringRef(end, UDSuffixEnd - end));
     UDSuffixOffset = end - TokBegin;
   }
 
@@ -1201,26 +1255,26 @@
 /// \endverbatim
 ///
 StringLiteralParser::
-StringLiteralParser(const Token *StringToks, unsigned NumStringToks,
+StringLiteralParser(ArrayRef<Token> StringToks,
                     Preprocessor &PP, bool Complain)
   : SM(PP.getSourceManager()), Features(PP.getLangOpts()),
-    Target(PP.getTargetInfo()), Diags(Complain ? &PP.getDiagnostics() : 0),
+    Target(PP.getTargetInfo()), Diags(Complain ? &PP.getDiagnostics() :nullptr),
     MaxTokenLength(0), SizeBound(0), CharByteWidth(0), Kind(tok::unknown),
     ResultPtr(ResultBuf.data()), hadError(false), Pascal(false) {
-  init(StringToks, NumStringToks);
+  init(StringToks);
 }
 
-void StringLiteralParser::init(const Token *StringToks, unsigned NumStringToks){
+void StringLiteralParser::init(ArrayRef<Token> StringToks){
   // The literal token may have come from an invalid source location (e.g. due
   // to a PCH error), in which case the token length will be 0.
-  if (NumStringToks == 0 || StringToks[0].getLength() < 2)
+  if (StringToks.empty() || StringToks[0].getLength() < 2)
     return DiagnoseLexingError(SourceLocation());
 
   // Scan all of the string portions, remember the max individual token length,
   // computing a bound on the concatenated string length, and see whether any
   // piece is a wide-string.  If any of the string portions is a wide-string
   // literal, the result is a wide-string literal [C99 6.4.5p4].
-  assert(NumStringToks && "expected at least one token");
+  assert(!StringToks.empty() && "expected at least one token");
   MaxTokenLength = StringToks[0].getLength();
   assert(StringToks[0].getLength() >= 2 && "literal token is invalid!");
   SizeBound = StringToks[0].getLength()-2;  // -2 for "".
@@ -1230,7 +1284,7 @@
 
   // Implement Translation Phase #6: concatenation of string literals
   /// (C99 5.1.1.2p1).  The common case is only one string fragment.
-  for (unsigned i = 1; i != NumStringToks; ++i) {
+  for (unsigned i = 1; i != StringToks.size(); ++i) {
     if (StringToks[i].getLength() < 2)
       return DiagnoseLexingError(StringToks[i].getLocation());
 
@@ -1286,7 +1340,7 @@
 
   SourceLocation UDSuffixTokLoc;
 
-  for (unsigned i = 0, e = NumStringToks; i != e; ++i) {
+  for (unsigned i = 0, e = StringToks.size(); i != e; ++i) {
     const char *ThisTokBuf = &TokenBuf[0];
     // Get the spelling of the token, which eliminates trigraphs, etc.  We know
     // that ThisTokBuf points to a buffer that is big enough for the whole token
@@ -1311,23 +1365,34 @@
       StringRef UDSuffix(ThisTokEnd, UDSuffixEnd - ThisTokEnd);
 
       if (UDSuffixBuf.empty()) {
-        UDSuffixBuf.assign(UDSuffix);
+        if (StringToks[i].hasUCN())
+          expandUCNs(UDSuffixBuf, UDSuffix);
+        else
+          UDSuffixBuf.assign(UDSuffix);
         UDSuffixToken = i;
         UDSuffixOffset = ThisTokEnd - ThisTokBuf;
         UDSuffixTokLoc = StringToks[i].getLocation();
-      } else if (!UDSuffixBuf.equals(UDSuffix)) {
+      } else {
+        SmallString<32> ExpandedUDSuffix;
+        if (StringToks[i].hasUCN()) {
+          expandUCNs(ExpandedUDSuffix, UDSuffix);
+          UDSuffix = ExpandedUDSuffix;
+        }
+
         // C++11 [lex.ext]p8: At the end of phase 6, if a string literal is the
         // result of a concatenation involving at least one user-defined-string-
         // literal, all the participating user-defined-string-literals shall
         // have the same ud-suffix.
-        if (Diags) {
-          SourceLocation TokLoc = StringToks[i].getLocation();
-          Diags->Report(TokLoc, diag::err_string_concat_mixed_suffix)
-            << UDSuffixBuf << UDSuffix
-            << SourceRange(UDSuffixTokLoc, UDSuffixTokLoc)
-            << SourceRange(TokLoc, TokLoc);
+        if (UDSuffixBuf != UDSuffix) {
+          if (Diags) {
+            SourceLocation TokLoc = StringToks[i].getLocation();
+            Diags->Report(TokLoc, diag::err_string_concat_mixed_suffix)
+              << UDSuffixBuf << UDSuffix
+              << SourceRange(UDSuffixTokLoc, UDSuffixTokLoc)
+              << SourceRange(TokLoc, TokLoc);
+          }
+          hadError = true;
         }
-        hadError = true;
       }
     }
 
@@ -1449,10 +1514,10 @@
     // Verify that pascal strings aren't too large.
     if (GetStringLength() > 256) {
       if (Diags)
-        Diags->Report(StringToks[0].getLocation(),
+        Diags->Report(StringToks.front().getLocation(),
                       diag::err_pascal_string_too_long)
-          << SourceRange(StringToks[0].getLocation(),
-                         StringToks[NumStringToks-1].getLocation());
+          << SourceRange(StringToks.front().getLocation(),
+                         StringToks.back().getLocation());
       hadError = true;
       return;
     }
@@ -1461,12 +1526,12 @@
     unsigned MaxChars = Features.CPlusPlus? 65536 : Features.C99 ? 4095 : 509;
 
     if (GetNumStringChars() > MaxChars)
-      Diags->Report(StringToks[0].getLocation(),
+      Diags->Report(StringToks.front().getLocation(),
                     diag::ext_string_too_long)
         << GetNumStringChars() << MaxChars
         << (Features.CPlusPlus ? 2 : Features.C99 ? 1 : 0)
-        << SourceRange(StringToks[0].getLocation(),
-                       StringToks[NumStringToks-1].getLocation());
+        << SourceRange(StringToks.front().getLocation(),
+                       StringToks.back().getLocation());
   }
 }
 
@@ -1516,8 +1581,7 @@
     Dummy.reserve(Fragment.size() * CharByteWidth);
     char *Ptr = Dummy.data();
 
-    while (!Builder.hasMaxRanges() &&
-           !ConvertUTF8toWide(CharByteWidth, NextFragment, Ptr, ErrorPtrTmp)) {
+    while (!ConvertUTF8toWide(CharByteWidth, NextFragment, Ptr, ErrorPtrTmp)) {
       const char *ErrorPtr = reinterpret_cast<const char *>(ErrorPtrTmp);
       NextStart = resyncUTF8(ErrorPtr, Fragment.end());
       Builder << MakeCharSourceRange(Features, SourceLoc, TokBegin,
diff --git a/lib/Lex/MacroArgs.cpp b/lib/Lex/MacroArgs.cpp
index d2dc04b..a746fb7 100644
--- a/lib/Lex/MacroArgs.cpp
+++ b/lib/Lex/MacroArgs.cpp
@@ -1,4 +1,4 @@
-//===--- TokenLexer.cpp - Lex from a token stream -------------------------===//
+//===--- MacroArgs.cpp - Formal argument info for Macros ------------------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -7,7 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This file implements the TokenLexer interface.
+// This file implements the MacroArgs interface.
 //
 //===----------------------------------------------------------------------===//
 
@@ -27,7 +27,7 @@
                              bool VarargsElided, Preprocessor &PP) {
   assert(MI->isFunctionLike() &&
          "Can't have args for an object-like macro!");
-  MacroArgs **ResultEnt = 0;
+  MacroArgs **ResultEnt = nullptr;
   unsigned ClosestMatch = ~0U;
   
   // See if we have an entry with a big enough argument list to reuse on the
@@ -46,7 +46,7 @@
     }
   
   MacroArgs *Result;
-  if (ResultEnt == 0) {
+  if (!ResultEnt) {
     // Allocate memory for a MacroArgs object with the lexer tokens at the end.
     Result = (MacroArgs*)malloc(sizeof(MacroArgs) + 
                                 UnexpArgTokens.size() * sizeof(Token));
diff --git a/lib/Lex/MacroInfo.cpp b/lib/Lex/MacroInfo.cpp
index b61ff71..5416886 100644
--- a/lib/Lex/MacroInfo.cpp
+++ b/lib/Lex/MacroInfo.cpp
@@ -17,7 +17,7 @@
 
 MacroInfo::MacroInfo(SourceLocation DefLoc)
   : Location(DefLoc),
-    ArgumentList(0),
+    ArgumentList(nullptr),
     NumArguments(0),
     IsDefinitionLengthCached(false),
     IsFunctionLike(false),
@@ -29,7 +29,8 @@
     IsUsed(false),
     IsAllowRedefinitionsWithoutWarning(false),
     IsWarnIfUnused(false),
-    FromASTFile(false) {
+    FromASTFile(false),
+    UsedForHeaderGuard(false) {
 }
 
 unsigned MacroInfo::getDefinitionLengthSlow(SourceManager &SM) const {
@@ -125,14 +126,54 @@
   return true;
 }
 
-MacroDirective::DefInfo MacroDirective::getDefinition(bool AllowHidden) {
+void MacroInfo::dump() const {
+  llvm::raw_ostream &Out = llvm::errs();
+
+  // FIXME: Dump locations.
+  Out << "MacroInfo " << this;
+  if (IsBuiltinMacro) Out << " builtin";
+  if (IsDisabled) Out << " disabled";
+  if (IsUsed) Out << " used";
+  if (IsAllowRedefinitionsWithoutWarning)
+    Out << " allow_redefinitions_without_warning";
+  if (IsWarnIfUnused) Out << " warn_if_unused";
+  if (FromASTFile) Out << " imported";
+  if (UsedForHeaderGuard) Out << " header_guard";
+
+  Out << "\n    #define <macro>";
+  if (IsFunctionLike) {
+    Out << "(";
+    for (unsigned I = 0; I != NumArguments; ++I) {
+      if (I) Out << ", ";
+      Out << ArgumentList[I]->getName();
+    }
+    if (IsC99Varargs || IsGNUVarargs) {
+      if (NumArguments && IsC99Varargs) Out << ", ";
+      Out << "...";
+    }
+    Out << ")";
+  }
+
+  for (const Token &Tok : ReplacementTokens) {
+    Out << " ";
+    if (const char *Punc = tok::getPunctuatorSpelling(Tok.getKind()))
+      Out << Punc;
+    else if (const char *Kwd = tok::getKeywordSpelling(Tok.getKind()))
+      Out << Kwd;
+    else if (Tok.is(tok::identifier))
+      Out << Tok.getIdentifierInfo()->getName();
+    else if (Tok.isLiteral() && Tok.getLiteralData())
+      Out << StringRef(Tok.getLiteralData(), Tok.getLength());
+    else
+      Out << Tok.getName();
+  }
+}
+
+MacroDirective::DefInfo MacroDirective::getDefinition() {
   MacroDirective *MD = this;
   SourceLocation UndefLoc;
   Optional<bool> isPublic;
   for (; MD; MD = MD->getPrevious()) {
-    if (!AllowHidden && MD->isHidden())
-      continue;
-
     if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(MD))
       return DefInfo(DefMD, UndefLoc,
                      !isPublic.hasValue() || isPublic.getValue());
@@ -147,7 +188,8 @@
       isPublic = VisMD->isPublic();
   }
 
-  return DefInfo();
+  return DefInfo(nullptr, UndefLoc,
+                 !isPublic.hasValue() || isPublic.getValue());
 }
 
 const MacroDirective::DefInfo
@@ -162,3 +204,33 @@
   }
   return DefInfo();
 }
+
+void MacroDirective::dump() const {
+  llvm::raw_ostream &Out = llvm::errs();
+
+  switch (getKind()) {
+  case MD_Define: Out << "DefMacroDirective"; break;
+  case MD_Undefine: Out << "UndefMacroDirective"; break;
+  case MD_Visibility: Out << "VisibilityMacroDirective"; break;
+  }
+  Out << " " << this;
+  // FIXME: Dump SourceLocation.
+  if (auto *Prev = getPrevious())
+    Out << " prev " << Prev;
+  if (IsFromPCH) Out << " from_pch";
+  if (IsImported) Out << " imported";
+  if (IsAmbiguous) Out << " ambiguous";
+
+  if (IsPublic)
+    Out << " public";
+  else if (isa<VisibilityMacroDirective>(this))
+    Out << " private";
+
+  if (auto *DMD = dyn_cast<DefMacroDirective>(this)) {
+    if (auto *Info = DMD->getInfo()) {
+      Out << "\n  ";
+      Info->dump();
+    }
+  }
+  Out << "\n";
+}
diff --git a/lib/Lex/ModuleMap.cpp b/lib/Lex/ModuleMap.cpp
index f4dfa12..8fae9c9 100644
--- a/lib/Lex/ModuleMap.cpp
+++ b/lib/Lex/ModuleMap.cpp
@@ -42,7 +42,7 @@
   // We may have just a wildcard.
   if (Unresolved.Id.empty()) {
     assert(Unresolved.Wildcard && "Invalid unresolved export");
-    return Module::ExportDecl(0, true);
+    return Module::ExportDecl(nullptr, true);
   }
   
   // Resolve the module-id.
@@ -59,10 +59,10 @@
   Module *Context = lookupModuleUnqualified(Id[0].first, Mod);
   if (!Context) {
     if (Complain)
-      Diags->Report(Id[0].second, diag::err_mmap_missing_module_unqualified)
+      Diags.Report(Id[0].second, diag::err_mmap_missing_module_unqualified)
       << Id[0].first << Mod->getFullModuleName();
 
-    return 0;
+    return nullptr;
   }
 
   // Dig into the module path.
@@ -70,11 +70,11 @@
     Module *Sub = lookupModuleQualified(Id[I].first, Context);
     if (!Sub) {
       if (Complain)
-        Diags->Report(Id[I].second, diag::err_mmap_missing_module_qualified)
+        Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
         << Id[I].first << Context->getFullModuleName()
         << SourceRange(Id[0].second, Id[I-1].second);
 
-      return 0;
+      return nullptr;
     }
 
     Context = Sub;
@@ -83,19 +83,12 @@
   return Context;
 }
 
-ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticConsumer &DC,
+ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags,
                      const LangOptions &LangOpts, const TargetInfo *Target,
                      HeaderSearch &HeaderInfo)
-    : SourceMgr(SourceMgr), LangOpts(LangOpts), Target(Target),
-      HeaderInfo(HeaderInfo), BuiltinIncludeDir(0), CompilingModule(0),
-      SourceModule(0) {
-  IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs);
-  Diags = IntrusiveRefCntPtr<DiagnosticsEngine>(
-            new DiagnosticsEngine(DiagIDs, new DiagnosticOptions));
-  Diags->setClient(new ForwardingDiagnosticConsumer(DC),
-                   /*ShouldOwnClient=*/true);
-  Diags->setSourceManager(&SourceMgr);
-}
+    : SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target),
+      HeaderInfo(HeaderInfo), BuiltinIncludeDir(nullptr),
+      CompilingModule(nullptr), SourceModule(nullptr) {}
 
 ModuleMap::~ModuleMap() {
   for (llvm::StringMap<Module *>::iterator I = Modules.begin(), 
@@ -166,10 +159,165 @@
            .Default(false);
 }
 
+ModuleMap::HeadersMap::iterator
+ModuleMap::findKnownHeader(const FileEntry *File) {
+  HeadersMap::iterator Known = Headers.find(File);
+  if (Known == Headers.end() && File->getDir() == BuiltinIncludeDir &&
+      isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
+    HeaderInfo.loadTopLevelSystemModules();
+    return Headers.find(File);
+  }
+  return Known;
+}
+
+ModuleMap::KnownHeader
+ModuleMap::findHeaderInUmbrellaDirs(const FileEntry *File,
+                    SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs) {
+  const DirectoryEntry *Dir = File->getDir();
+  assert(Dir && "file in no directory");
+
+  // Note: as an egregious but useful hack we use the real path here, because
+  // frameworks moving from top-level frameworks to embedded frameworks tend
+  // to be symlinked from the top-level location to the embedded location,
+  // and we need to resolve lookups as if we had found the embedded location.
+  StringRef DirName = SourceMgr.getFileManager().getCanonicalName(Dir);
+
+  // Keep walking up the directory hierarchy, looking for a directory with
+  // an umbrella header.
+  do {
+    auto KnownDir = UmbrellaDirs.find(Dir);
+    if (KnownDir != UmbrellaDirs.end())
+      return KnownHeader(KnownDir->second, NormalHeader);
+
+    IntermediateDirs.push_back(Dir);
+
+    // Retrieve our parent path.
+    DirName = llvm::sys::path::parent_path(DirName);
+    if (DirName.empty())
+      break;
+
+    // Resolve the parent path to a directory entry.
+    Dir = SourceMgr.getFileManager().getDirectory(DirName);
+  } while (Dir);
+  return KnownHeader();
+}
+
+// Returns 'true' if 'RequestingModule directly uses 'RequestedModule'.
+static bool directlyUses(const Module *RequestingModule,
+                         const Module *RequestedModule) {
+  return std::find(RequestingModule->DirectUses.begin(),
+                   RequestingModule->DirectUses.end(),
+                   RequestedModule) != RequestingModule->DirectUses.end();
+}
+
+static bool violatesPrivateInclude(Module *RequestingModule,
+                                   const FileEntry *IncFileEnt,
+                                   ModuleMap::ModuleHeaderRole Role,
+                                   Module *RequestedModule) {
+  #ifndef NDEBUG
+  // Check for consistency between the module header role
+  // as obtained from the lookup and as obtained from the module.
+  // This check is not cheap, so enable it only for debugging.
+  SmallVectorImpl<const FileEntry *> &PvtHdrs
+      = RequestedModule->PrivateHeaders;
+  SmallVectorImpl<const FileEntry *>::iterator Look
+      = std::find(PvtHdrs.begin(), PvtHdrs.end(), IncFileEnt);
+  bool IsPrivate = Look != PvtHdrs.end();
+  assert((IsPrivate && Role == ModuleMap::PrivateHeader)
+               || (!IsPrivate && Role != ModuleMap::PrivateHeader));
+  #endif
+  return Role == ModuleMap::PrivateHeader &&
+         RequestedModule->getTopLevelModule() != RequestingModule;
+}
+
+static Module *getTopLevelOrNull(Module *M) {
+  return M ? M->getTopLevelModule() : nullptr;
+}
+
+void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
+                                        SourceLocation FilenameLoc,
+                                        StringRef Filename,
+                                        const FileEntry *File) {
+  // No errors for indirect modules. This may be a bit of a problem for modules
+  // with no source files.
+  if (getTopLevelOrNull(RequestingModule) != getTopLevelOrNull(SourceModule))
+    return;
+
+  if (RequestingModule)
+    resolveUses(RequestingModule, /*Complain=*/false);
+
+  bool Excluded = false;
+  Module *Private = nullptr;
+  Module *NotUsed = nullptr;
+
+  HeadersMap::iterator Known = findKnownHeader(File);
+  if (Known != Headers.end()) {
+    for (const KnownHeader &Header : Known->second) {
+      // Excluded headers don't really belong to a module.
+      if (Header.getRole() == ModuleMap::ExcludedHeader) {
+        Excluded = true;
+        continue;
+      }
+
+      // If 'File' is part of 'RequestingModule' we can definitely include it.
+      if (Header.getModule() == RequestingModule)
+        return;
+
+      // Remember private headers for later printing of a diagnostic.
+      if (violatesPrivateInclude(RequestingModule, File, Header.getRole(),
+                                 Header.getModule())) {
+        Private = Header.getModule();
+        continue;
+      }
+
+      // If uses need to be specified explicitly, we are only allowed to return
+      // modules that are explicitly used by the requesting module.
+      if (RequestingModule && LangOpts.ModulesDeclUse &&
+          !directlyUses(RequestingModule, Header.getModule())) {
+        NotUsed = Header.getModule();
+        continue;
+      }
+
+      // We have found a module that we can happily use.
+      return;
+    }
+  }
+
+  // We have found a header, but it is private.
+  if (Private) {
+    Diags.Report(FilenameLoc, diag::error_use_of_private_header_outside_module)
+        << Filename;
+    return;
+  }
+
+  // We have found a module, but we don't use it.
+  if (NotUsed) {
+    Diags.Report(FilenameLoc, diag::error_undeclared_use_of_module)
+        << RequestingModule->getFullModuleName() << Filename;
+    return;
+  }
+
+  if (Excluded || isHeaderInUmbrellaDirs(File))
+    return;
+
+  // At this point, only non-modular includes remain.
+
+  if (LangOpts.ModulesStrictDeclUse) {
+    Diags.Report(FilenameLoc, diag::error_undeclared_use_of_module)
+        << RequestingModule->getFullModuleName() << Filename;
+  } else if (RequestingModule) {
+    diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ?
+        diag::warn_non_modular_include_in_framework_module :
+        diag::warn_non_modular_include_in_module;
+    Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName();
+  }
+}
+
 ModuleMap::KnownHeader
 ModuleMap::findModuleForHeader(const FileEntry *File,
                                Module *RequestingModule) {
-  HeadersMap::iterator Known = Headers.find(File);
+  HeadersMap::iterator Known = findKnownHeader(File);
+
   if (Known != Headers.end()) {
     ModuleMap::KnownHeader Result = KnownHeader();
 
@@ -177,9 +325,12 @@
     for (SmallVectorImpl<KnownHeader>::iterator I = Known->second.begin(),
                                                 E = Known->second.end();
          I != E; ++I) {
-      // Cannot use a module if the header is excluded or unavailable in it.
-      if (I->getRole() == ModuleMap::ExcludedHeader ||
-          !I->getModule()->isAvailable())
+      // Cannot use a module if the header is excluded in it.
+      if (I->getRole() == ModuleMap::ExcludedHeader)
+        continue;
+
+      // Cannot use a module if it is unavailable.
+      if (!I->getModule()->isAvailable())
         continue;
 
       // If 'File' is part of 'RequestingModule', 'RequestingModule' is the
@@ -190,146 +341,125 @@
       // If uses need to be specified explicitly, we are only allowed to return
       // modules that are explicitly used by the requesting module.
       if (RequestingModule && LangOpts.ModulesDeclUse &&
-          std::find(RequestingModule->DirectUses.begin(),
-                    RequestingModule->DirectUses.end(),
-                    I->getModule()) == RequestingModule->DirectUses.end())
+          !directlyUses(RequestingModule, I->getModule()))
         continue;
+
       Result = *I;
       // If 'File' is a public header of this module, this is as good as we
       // are going to get.
+      // FIXME: If we have a RequestingModule, we should prefer the header from
+      // that module.
       if (I->getRole() == ModuleMap::NormalHeader)
         break;
     }
     return Result;
   }
 
-  // If we've found a builtin header within Clang's builtin include directory,
-  // load all of the module maps to see if it will get associated with a
-  // specific module (e.g., in /usr/include).
-  if (File->getDir() == BuiltinIncludeDir &&
-      isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
-    HeaderInfo.loadTopLevelSystemModules();
-
-    // Check again.
-    if (Headers.find(File) != Headers.end())
-      return findModuleForHeader(File, RequestingModule);
-  }
-  
-  const DirectoryEntry *Dir = File->getDir();
   SmallVector<const DirectoryEntry *, 2> SkippedDirs;
+  KnownHeader H = findHeaderInUmbrellaDirs(File, SkippedDirs);
+  if (H) {
+    Module *Result = H.getModule();
 
-  // Note: as an egregious but useful hack we use the real path here, because
-  // frameworks moving from top-level frameworks to embedded frameworks tend
-  // to be symlinked from the top-level location to the embedded location,
-  // and we need to resolve lookups as if we had found the embedded location.
-  StringRef DirName = SourceMgr.getFileManager().getCanonicalName(Dir);
+    // Search up the module stack until we find a module with an umbrella
+    // directory.
+    Module *UmbrellaModule = Result;
+    while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
+      UmbrellaModule = UmbrellaModule->Parent;
 
-  // Keep walking up the directory hierarchy, looking for a directory with
-  // an umbrella header.
-  do {    
-    llvm::DenseMap<const DirectoryEntry *, Module *>::iterator KnownDir
-      = UmbrellaDirs.find(Dir);
-    if (KnownDir != UmbrellaDirs.end()) {
-      Module *Result = KnownDir->second;
-      
-      // Search up the module stack until we find a module with an umbrella
-      // directory.
-      Module *UmbrellaModule = Result;
-      while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
-        UmbrellaModule = UmbrellaModule->Parent;
+    if (UmbrellaModule->InferSubmodules) {
+      // Infer submodules for each of the directories we found between
+      // the directory of the umbrella header and the directory where
+      // the actual header is located.
+      bool Explicit = UmbrellaModule->InferExplicitSubmodules;
 
-      if (UmbrellaModule->InferSubmodules) {
-        // Infer submodules for each of the directories we found between
-        // the directory of the umbrella header and the directory where 
-        // the actual header is located.
-        bool Explicit = UmbrellaModule->InferExplicitSubmodules;
-        
-        for (unsigned I = SkippedDirs.size(); I != 0; --I) {
-          // Find or create the module that corresponds to this directory name.
-          SmallString<32> NameBuf;
-          StringRef Name = sanitizeFilenameAsIdentifier(
-                             llvm::sys::path::stem(SkippedDirs[I-1]->getName()),
-                             NameBuf);
-          Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
-                                      Explicit).first;
-          
-          // Associate the module and the directory.
-          UmbrellaDirs[SkippedDirs[I-1]] = Result;
-
-          // If inferred submodules export everything they import, add a 
-          // wildcard to the set of exports.
-          if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
-            Result->Exports.push_back(Module::ExportDecl(0, true));
-        }
-        
-        // Infer a submodule with the same name as this header file.
+      for (unsigned I = SkippedDirs.size(); I != 0; --I) {
+        // Find or create the module that corresponds to this directory name.
         SmallString<32> NameBuf;
         StringRef Name = sanitizeFilenameAsIdentifier(
-                           llvm::sys::path::stem(File->getName()), NameBuf);
-        Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
-                                    Explicit).first;
-        Result->addTopHeader(File);
-        
-        // If inferred submodules export everything they import, add a 
+            llvm::sys::path::stem(SkippedDirs[I-1]->getName()), NameBuf);
+        Result = findOrCreateModule(Name, Result, UmbrellaModule->ModuleMap,
+                                    /*IsFramework=*/false, Explicit).first;
+        Result->IsInferred = true;
+
+        // Associate the module and the directory.
+        UmbrellaDirs[SkippedDirs[I-1]] = Result;
+
+        // If inferred submodules export everything they import, add a
         // wildcard to the set of exports.
         if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
-          Result->Exports.push_back(Module::ExportDecl(0, true));
-      } else {
-        // Record each of the directories we stepped through as being part of
-        // the module we found, since the umbrella header covers them all.
-        for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
-          UmbrellaDirs[SkippedDirs[I]] = Result;
+          Result->Exports.push_back(Module::ExportDecl(nullptr, true));
       }
-      
-      Headers[File].push_back(KnownHeader(Result, NormalHeader));
 
-      // If a header corresponds to an unavailable module, don't report
-      // that it maps to anything.
-      if (!Result->isAvailable())
-        return KnownHeader();
+      // Infer a submodule with the same name as this header file.
+      SmallString<32> NameBuf;
+      StringRef Name = sanitizeFilenameAsIdentifier(
+                         llvm::sys::path::stem(File->getName()), NameBuf);
+      Result = findOrCreateModule(Name, Result, UmbrellaModule->ModuleMap,
+                                  /*IsFramework=*/false, Explicit).first;
+      Result->IsInferred = true;
+      Result->addTopHeader(File);
 
-      return Headers[File].back();
+      // If inferred submodules export everything they import, add a
+      // wildcard to the set of exports.
+      if (UmbrellaModule->InferExportWildcard && Result->Exports.empty())
+        Result->Exports.push_back(Module::ExportDecl(nullptr, true));
+    } else {
+      // Record each of the directories we stepped through as being part of
+      // the module we found, since the umbrella header covers them all.
+      for (unsigned I = 0, N = SkippedDirs.size(); I != N; ++I)
+        UmbrellaDirs[SkippedDirs[I]] = Result;
     }
-    
-    SkippedDirs.push_back(Dir);
-    
-    // Retrieve our parent path.
-    DirName = llvm::sys::path::parent_path(DirName);
-    if (DirName.empty())
-      break;
-    
-    // Resolve the parent path to a directory entry.
-    Dir = SourceMgr.getFileManager().getDirectory(DirName);
-  } while (Dir);
+
+    Headers[File].push_back(KnownHeader(Result, NormalHeader));
+
+    // If a header corresponds to an unavailable module, don't report
+    // that it maps to anything.
+    if (!Result->isAvailable())
+      return KnownHeader();
+
+    return Headers[File].back();
+  }
   
   return KnownHeader();
 }
 
 bool ModuleMap::isHeaderInUnavailableModule(const FileEntry *Header) const {
+  return isHeaderUnavailableInModule(Header, nullptr);
+}
+
+bool
+ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
+                                       const Module *RequestingModule) const {
   HeadersMap::const_iterator Known = Headers.find(Header);
   if (Known != Headers.end()) {
     for (SmallVectorImpl<KnownHeader>::const_iterator
              I = Known->second.begin(),
              E = Known->second.end();
          I != E; ++I) {
-      if (I->isAvailable())
+      if (I->isAvailable() && (!RequestingModule ||
+                               I->getModule()->isSubModuleOf(RequestingModule)))
         return false;
     }
     return true;
   }
-  
+
   const DirectoryEntry *Dir = Header->getDir();
   SmallVector<const DirectoryEntry *, 2> SkippedDirs;
   StringRef DirName = Dir->getName();
 
+  auto IsUnavailable = [&](const Module *M) {
+    return !M->isAvailable() && (!RequestingModule ||
+                                 M->isSubModuleOf(RequestingModule));
+  };
+
   // Keep walking up the directory hierarchy, looking for a directory with
   // an umbrella header.
-  do {    
+  do {
     llvm::DenseMap<const DirectoryEntry *, Module *>::const_iterator KnownDir
       = UmbrellaDirs.find(Dir);
     if (KnownDir != UmbrellaDirs.end()) {
       Module *Found = KnownDir->second;
-      if (!Found->isAvailable())
+      if (IsUnavailable(Found))
         return true;
 
       // Search up the module stack until we find a module with an umbrella
@@ -348,7 +478,7 @@
           Found = lookupModuleQualified(Name, Found);
           if (!Found)
             return false;
-          if (!Found->isAvailable())
+          if (IsUnavailable(Found))
             return true;
         }
         
@@ -362,7 +492,7 @@
           return false;
       }
 
-      return !Found->isAvailable();
+      return IsUnavailable(Found);
     }
     
     SkippedDirs.push_back(Dir);
@@ -383,8 +513,8 @@
   llvm::StringMap<Module *>::const_iterator Known = Modules.find(Name);
   if (Known != Modules.end())
     return Known->getValue();
-  
-  return 0;
+
+  return nullptr;
 }
 
 Module *ModuleMap::lookupModuleUnqualified(StringRef Name,
@@ -405,15 +535,16 @@
 }
 
 std::pair<Module *, bool> 
-ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
+ModuleMap::findOrCreateModule(StringRef Name, Module *Parent,
+                              const FileEntry *ModuleMap, 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);
+  Module *Result = new Module(Name, SourceLocation(), Parent, ModuleMap,
+                              IsFramework, IsExplicit);
   if (LangOpts.CurrentModule == Name) {
     SourceModule = Result;
     SourceModuleName = Name;
@@ -482,6 +613,7 @@
 
   // If the framework has a parent path from which we're allowed to infer
   // a framework module, do so.
+  const FileEntry *ModuleMapFile = nullptr;
   if (!Parent) {
     // Determine whether we're allowed to infer a module map.
 
@@ -492,6 +624,12 @@
     StringRef FrameworkDirName
       = SourceMgr.getFileManager().getCanonicalName(FrameworkDir);
 
+    // In case this is a case-insensitive filesystem, make sure the canonical
+    // directory name matches ModuleName exactly. Modules are case-sensitive.
+    // FIXME: we should be able to give a fix-it hint for the correct spelling.
+    if (llvm::sys::path::stem(FrameworkDirName) != ModuleName)
+      return nullptr;
+
     bool canInfer = false;
     if (llvm::sys::path::has_parent_path(FrameworkDirName)) {
       // Figure out the parent path.
@@ -504,9 +642,9 @@
         if (inferred == InferredDirectories.end()) {
           // We haven't looked here before. Load a module map, if there is
           // one.
-          SmallString<128> ModMapPath = Parent;
-          llvm::sys::path::append(ModMapPath, "module.map");
-          if (const FileEntry *ModMapFile = FileMgr.getFile(ModMapPath)) {
+          bool IsFrameworkDir = Parent.endswith(".framework");
+          if (const FileEntry *ModMapFile =
+                HeaderInfo.lookupModuleMapFile(ParentDir, IsFrameworkDir)) {
             parseModuleMapFile(ModMapFile, IsSystem);
             inferred = InferredDirectories.find(ParentDir);
           }
@@ -526,14 +664,16 @@
 
           if (inferred->second.InferSystemModules)
             IsSystem = true;
+          ModuleMapFile = inferred->second.ModuleMapFile;
         }
       }
     }
 
     // If we're not allowed to infer a framework module, don't.
     if (!canInfer)
-      return 0;
-  }
+      return nullptr;
+  } else
+    ModuleMapFile = Parent->ModuleMap;
 
 
   // Look for an umbrella header.
@@ -545,9 +685,9 @@
   // framework to load *everything*. But, it's not clear that this is a good
   // idea.
   if (!UmbrellaHeader)
-    return 0;
-  
-  Module *Result = new Module(ModuleName, SourceLocation(), Parent,
+    return nullptr;
+
+  Module *Result = new Module(ModuleName, SourceLocation(), Parent, ModuleMapFile,
                               /*IsFramework=*/true, /*IsExplicit=*/false);
   if (LangOpts.CurrentModule == ModuleName) {
     SourceModule = Result;
@@ -565,14 +705,14 @@
   UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
   
   // export *
-  Result->Exports.push_back(Module::ExportDecl(0, true));
-  
+  Result->Exports.push_back(Module::ExportDecl(nullptr, true));
+
   // module * { export * }
   Result->InferSubmodules = true;
   Result->InferExportWildcard = true;
   
   // Look for subframeworks.
-  llvm::error_code EC;
+  std::error_code EC;
   SmallString<128> SubframeworksDirName
     = StringRef(FrameworkDir->getName());
   llvm::sys::path::append(SubframeworksDirName, "Frameworks");
@@ -653,7 +793,7 @@
 const FileEntry *
 ModuleMap::getContainingModuleMapFile(Module *Module) const {
   if (Module->DefinitionLoc.isInvalid())
-    return 0;
+    return nullptr;
 
   return SourceMgr.getFileEntryForID(
            SourceMgr.getFileID(Module->DefinitionLoc));
@@ -730,14 +870,13 @@
 
 Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
   if (Loc.isInvalid())
-    return 0;
-  
+    return nullptr;
+
   // Use the expansion location to determine which module we're in.
   FullSourceLoc ExpansionLoc = Loc.getExpansionLoc();
   if (!ExpansionLoc.isFileID())
-    return 0;  
-  
-  
+    return nullptr;
+
   const SourceManager &SrcMgr = Loc.getManager();
   FileID ExpansionFileID = ExpansionLoc.getFileID();
   
@@ -751,12 +890,12 @@
     // any included header has an associated module.
     SourceLocation IncludeLoc = SrcMgr.getIncludeLoc(ExpansionFileID);
     if (IncludeLoc.isInvalid())
-      return 0;
-    
+      return nullptr;
+
     ExpansionFileID = SrcMgr.getFileID(IncludeLoc);
   }
-  
-  return 0;
+
+  return nullptr;
 }
 
 //----------------------------------------------------------------------------//
@@ -802,7 +941,7 @@
       Kind = EndOfFile;
       Location = 0;
       StringLength = 0;
-      StringData = 0;
+      StringData = nullptr;
     }
     
     bool is(TokenKind K) const { return Kind == K; }
@@ -818,11 +957,14 @@
 
   /// \brief The set of attributes that can be attached to a module.
   struct Attributes {
-    Attributes() : IsSystem(), IsExhaustive() { }
+    Attributes() : IsSystem(), IsExternC(), IsExhaustive() { }
 
     /// \brief Whether this is a system module.
     unsigned IsSystem : 1;
 
+    /// \brief Whether this is an extern "C" module.
+    unsigned IsExternC : 1;
+
     /// \brief Whether this is an exhaustive set of configuration macros.
     unsigned IsExhaustive : 1;
   };
@@ -838,6 +980,9 @@
 
     DiagnosticsEngine &Diags;
     ModuleMap &Map;
+
+    /// \brief The current module map file.
+    const FileEntry *ModuleMapFile;
     
     /// \brief The directory that this module map resides in.
     const DirectoryEntry *Directory;
@@ -883,20 +1028,20 @@
     void parseConflict();
     void parseInferredModuleDecl(bool Framework, bool Explicit);
     bool parseOptionalAttributes(Attributes &Attrs);
-
-    const DirectoryEntry *getOverriddenHeaderSearchDir();
     
   public:
     explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr, 
                              const TargetInfo *Target,
                              DiagnosticsEngine &Diags,
                              ModuleMap &Map,
+                             const FileEntry *ModuleMapFile,
                              const DirectoryEntry *Directory,
                              const DirectoryEntry *BuiltinIncludeDir,
                              bool IsSystem)
       : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map), 
-        Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
-        IsSystem(IsSystem), HadError(false), ActiveModule(0)
+        ModuleMapFile(ModuleMapFile), Directory(Directory),
+        BuiltinIncludeDir(BuiltinIncludeDir), IsSystem(IsSystem),
+        HadError(false), ActiveModule(nullptr)
     {
       Tok.clear();
       consumeToken();
@@ -915,10 +1060,11 @@
   L.LexFromRawLexer(LToken);
   Tok.Location = LToken.getLocation().getRawEncoding();
   switch (LToken.getKind()) {
-  case tok::raw_identifier:
-    Tok.StringData = LToken.getRawIdentifierData();
-    Tok.StringLength = LToken.getLength();
-    Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(Tok.getString())
+  case tok::raw_identifier: {
+    StringRef RI = LToken.getRawIdentifier();
+    Tok.StringData = RI.data();
+    Tok.StringLength = RI.size();
+    Tok.Kind = llvm::StringSwitch<MMToken::TokenKind>(RI)
                  .Case("config_macros", MMToken::ConfigMacros)
                  .Case("conflict", MMToken::Conflict)
                  .Case("exclude", MMToken::ExcludeKeyword)
@@ -935,6 +1081,7 @@
                  .Case("use", MMToken::UseKeyword)
                  .Default(MMToken::Identifier);
     break;
+  }
 
   case tok::comma:
     Tok.Kind = MMToken::Comma;
@@ -981,7 +1128,7 @@
 
     // Parse the string literal.
     LangOptions LangOpts;
-    StringLiteralParser StringLiteral(&LToken, 1, SourceMgr, LangOpts, *Target);
+    StringLiteralParser StringLiteral(LToken, SourceMgr, LangOpts, *Target);
     if (StringLiteral.hadError)
       goto retry;
     
@@ -1066,7 +1213,7 @@
 bool ModuleMapParser::parseModuleId(ModuleId &Id) {
   Id.clear();
   do {
-    if (Tok.is(MMToken::Identifier)) {
+    if (Tok.is(MMToken::Identifier) || Tok.is(MMToken::StringLiteral)) {
       Id.push_back(std::make_pair(Tok.getString(), Tok.getLocation()));
       consumeToken();
     } else {
@@ -1090,6 +1237,8 @@
     AT_unknown,
     /// \brief The 'system' attribute.
     AT_system,
+    /// \brief The 'extern_c' attribute.
+    AT_extern_c,
     /// \brief The 'exhaustive' attribute.
     AT_exhaustive
   };
@@ -1178,7 +1327,7 @@
   if (Id.size() > 1) {
     // This module map defines a submodule. Go find the module of which it
     // is a submodule.
-    ActiveModule = 0;
+    ActiveModule = nullptr;
     for (unsigned I = 0, N = Id.size() - 1; I != N; ++I) {
       if (Module *Next = Map.lookupModuleQualified(Id[I].first, ActiveModule)) {
         ActiveModule = Next;
@@ -1187,7 +1336,8 @@
       
       if (ActiveModule) {
         Diags.Report(Id[I].second, diag::err_mmap_missing_module_qualified)
-          << Id[I].first << ActiveModule->getTopLevelModule();
+          << Id[I].first
+          << ActiveModule->getTopLevelModule()->getFullModuleName();
       } else {
         Diags.Report(Id[I].second, diag::err_mmap_expected_module_name);
       }
@@ -1240,13 +1390,20 @@
     return;
   }
 
+  // If this is a submodule, use the parent's module map, since we don't want
+  // the private module map file.
+  const FileEntry *ModuleMap = ActiveModule ? ActiveModule->ModuleMap
+                                            : ModuleMapFile;
+
   // Start defining this module.
-  ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
-                                        Explicit).first;
+  ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, ModuleMap,
+                                        Framework, Explicit).first;
   ActiveModule->DefinitionLoc = ModuleNameLoc;
   if (Attrs.IsSystem || IsSystem)
     ActiveModule->IsSystem = true;
-  
+  if (Attrs.IsExternC)
+    ActiveModule->IsExternC = true;
+
   bool Done = false;
   do {
     switch (Tok.Kind) {
@@ -1343,6 +1500,15 @@
     inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager());
   }
 
+  // If the module meets all requirements but is still unavailable, mark the
+  // whole tree as unavailable to prevent it from building.
+  if (!ActiveModule->IsAvailable && !ActiveModule->IsMissingRequirement &&
+      ActiveModule->Parent) {
+    ActiveModule->getTopLevelModule()->markUnavailable();
+    ActiveModule->getTopLevelModule()->MissingHeaders.append(
+      ActiveModule->MissingHeaders.begin(), ActiveModule->MissingHeaders.end());
+  }
+
   // We're done parsing this module. Pop back to the previous module.
   ActiveModule = PreviousActiveModule;
 }
@@ -1474,27 +1640,24 @@
     HadError = true;
     return;
   }
-  std::string FileName = Tok.getString();
-  SourceLocation FileNameLoc = consumeToken();
+  Module::HeaderDirective Header;
+  Header.FileName = Tok.getString();
+  Header.FileNameLoc = consumeToken();
   
   // Check whether we already have an umbrella.
   if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
-    Diags.Report(FileNameLoc, diag::err_mmap_umbrella_clash)
+    Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
       << ActiveModule->getFullModuleName();
     HadError = true;
     return;
   }
 
   // Look for this file.
-  const FileEntry *File = 0;
-  const FileEntry *BuiltinFile = 0;
+  const FileEntry *File = nullptr;
+  const FileEntry *BuiltinFile = nullptr;
   SmallString<128> PathName;
-  if (llvm::sys::path::is_absolute(FileName)) {
-    PathName = FileName;
-    File = SourceMgr.getFileManager().getFile(PathName);
-  } else if (const DirectoryEntry *Dir = getOverriddenHeaderSearchDir()) {
-    PathName = Dir->getName();
-    llvm::sys::path::append(PathName, FileName);
+  if (llvm::sys::path::is_absolute(Header.FileName)) {
+    PathName = Header.FileName;
     File = SourceMgr.getFileManager().getFile(PathName);
   } else {
     // Search for the header file within the search directory.
@@ -1505,18 +1668,18 @@
       appendSubframeworkPaths(ActiveModule, PathName);
       
       // Check whether this file is in the public headers.
-      llvm::sys::path::append(PathName, "Headers", FileName);
+      llvm::sys::path::append(PathName, "Headers", Header.FileName);
       File = SourceMgr.getFileManager().getFile(PathName);
       
       if (!File) {
         // Check whether this file is in the private headers.
         PathName.resize(PathLength);
-        llvm::sys::path::append(PathName, "PrivateHeaders", FileName);
+        llvm::sys::path::append(PathName, "PrivateHeaders", Header.FileName);
         File = SourceMgr.getFileManager().getFile(PathName);
       }
     } else {
       // Lookup for normal headers.
-      llvm::sys::path::append(PathName, FileName);
+      llvm::sys::path::append(PathName, Header.FileName);
       File = SourceMgr.getFileManager().getFile(PathName);
       
       // If this is a system module with a top-level header, this header
@@ -1524,9 +1687,9 @@
       // supplied by Clang. Find that builtin header.
       if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
           BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
-          isBuiltinHeader(FileName)) {
+          isBuiltinHeader(Header.FileName)) {
         SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
-        llvm::sys::path::append(BuiltinPathName, FileName);
+        llvm::sys::path::append(BuiltinPathName, Header.FileName);
         BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
         
         // If Clang supplies this header but the underlying system does not,
@@ -1534,7 +1697,7 @@
         // up adding both (later).
         if (!File && BuiltinFile) {
           File = BuiltinFile;
-          BuiltinFile = 0;
+          BuiltinFile = nullptr;
         }
       }
     }
@@ -1571,10 +1734,12 @@
     }
   } else if (LeadingToken != MMToken::ExcludeKeyword) {
     // Ignore excluded header files. They're optional anyway.
-    
-    Diags.Report(FileNameLoc, diag::err_mmap_header_not_found)
-      << (LeadingToken == MMToken::UmbrellaKeyword) << FileName;
-    HadError = true;
+
+    // If we find a module that has a missing header, we mark this module as
+    // unavailable and store the header directive for displaying diagnostics.
+    Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
+    ActiveModule->markUnavailable();
+    ActiveModule->MissingHeaders.push_back(Header);
   }
 }
 
@@ -1603,7 +1768,7 @@
   }
 
   // Look for this file.
-  const DirectoryEntry *Dir = 0;
+  const DirectoryEntry *Dir = nullptr;
   if (llvm::sys::path::is_absolute(DirName))
     Dir = SourceMgr.getFileManager().getDirectory(DirName);
   else {
@@ -1687,25 +1852,7 @@
   consumeToken();
   // Parse the module-id.
   ModuleId ParsedModuleId;
-
-  do {
-    if (Tok.is(MMToken::Identifier)) {
-      ParsedModuleId.push_back(
-          std::make_pair(Tok.getString(), Tok.getLocation()));
-      consumeToken();
-
-      if (Tok.is(MMToken::Period)) {
-        consumeToken();
-        continue;
-      }
-
-      break;
-    }
-
-    Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
-    HadError = true;
-    return;
-  } while (true);
+  parseModuleId(ParsedModuleId);
 
   ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
 }
@@ -1864,7 +2011,8 @@
 
   if (ActiveModule) {
     // Inferred modules must have umbrella directories.
-    if (!Failed && !ActiveModule->getUmbrellaDir()) {
+    if (!Failed && ActiveModule->IsAvailable &&
+        !ActiveModule->getUmbrellaDir()) {
       Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
       Failed = true;
     }
@@ -1913,6 +2061,8 @@
     // We'll be inferring framework modules for this directory.
     Map.InferredDirectories[Directory].InferModules = true;
     Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;
+    Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
+    // FIXME: Handle the 'framework' keyword.
   }
 
   // Parse the opening brace.
@@ -1935,7 +2085,7 @@
     case MMToken::ExcludeKeyword: {
       if (ActiveModule) {
         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
-          << (ActiveModule != 0);
+          << (ActiveModule != nullptr);
         consumeToken();
         break;
       }
@@ -1955,7 +2105,7 @@
     case MMToken::ExportKeyword:
       if (!ActiveModule) {
         Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
-          << (ActiveModule != 0);
+          << (ActiveModule != nullptr);
         consumeToken();
         break;
       }
@@ -1976,7 +2126,7 @@
     case MMToken::UmbrellaKeyword:
     default:
       Diags.Report(Tok.getLocation(), diag::err_mmap_expected_inferred_member)
-          << (ActiveModule != 0);
+          << (ActiveModule != nullptr);
       consumeToken();
       break;        
     }
@@ -2023,6 +2173,7 @@
     AttributeKind Attribute
       = llvm::StringSwitch<AttributeKind>(Tok.getString())
           .Case("exhaustive", AT_exhaustive)
+          .Case("extern_c", AT_extern_c)
           .Case("system", AT_system)
           .Default(AT_unknown);
     switch (Attribute) {
@@ -2035,6 +2186,10 @@
       Attrs.IsSystem = true;
       break;
 
+    case AT_extern_c:
+      Attrs.IsExternC = true;
+      break;
+
     case AT_exhaustive:
       Attrs.IsExhaustive = true;
       break;
@@ -2056,22 +2211,6 @@
   return HadError;
 }
 
-/// \brief If there is a specific header search directory due the presence
-/// of an umbrella directory, retrieve that directory. Otherwise, returns null.
-const DirectoryEntry *ModuleMapParser::getOverriddenHeaderSearchDir() {
-  for (Module *Mod = ActiveModule; Mod; Mod = Mod->Parent) {
-    // If we have an umbrella directory, use that.
-    if (Mod->hasUmbrellaDir())
-      return Mod->getUmbrellaDir();
-    
-    // If we have a framework directory, stop looking.
-    if (Mod->IsFramework)
-      return 0;
-  }
-  
-  return 0;
-}
-
 /// \brief Parse a module map file.
 ///
 ///   module-map-file:
@@ -2123,19 +2262,29 @@
   if (Known != ParsedModuleMap.end())
     return Known->second;
 
-  assert(Target != 0 && "Missing target information");
-  FileID ID = SourceMgr.createFileID(File, SourceLocation(), SrcMgr::C_User);
+  assert(Target && "Missing target information");
+  auto FileCharacter = IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
+  FileID ID = SourceMgr.createFileID(File, SourceLocation(), FileCharacter);
   const llvm::MemoryBuffer *Buffer = SourceMgr.getBuffer(ID);
   if (!Buffer)
     return ParsedModuleMap[File] = true;
+
+  // Find the directory for the module. For frameworks, that may require going
+  // up from the 'Modules' directory.
+  const DirectoryEntry *Dir = File->getDir();
+  StringRef DirName(Dir->getName());
+  if (llvm::sys::path::filename(DirName) == "Modules") {
+    DirName = llvm::sys::path::parent_path(DirName);
+    if (DirName.endswith(".framework"))
+      Dir = SourceMgr.getFileManager().getDirectory(DirName);
+    assert(Dir && "parent must exist");
+  }
   
   // Parse this module map file.
   Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts);
-  Diags->getClient()->BeginSourceFile(MMapLangOpts);
-  ModuleMapParser Parser(L, SourceMgr, Target, *Diags, *this, File->getDir(),
+  ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir,
                          BuiltinIncludeDir, IsSystem);
   bool Result = Parser.parseModuleMapFile();
-  Diags->getClient()->EndSourceFile();
   ParsedModuleMap[File] = Result;
   return Result;
 }
diff --git a/lib/Lex/PPCaching.cpp b/lib/Lex/PPCaching.cpp
index 6f4c189..bd48ae6 100644
--- a/lib/Lex/PPCaching.cpp
+++ b/lib/Lex/PPCaching.cpp
@@ -15,28 +15,28 @@
 #include "clang/Lex/Preprocessor.h"
 using namespace clang;
 
-/// EnableBacktrackAtThisPos - From the point that this method is called, and
-/// until CommitBacktrackedTokens() or Backtrack() is called, the Preprocessor
-/// keeps track of the lexed tokens so that a subsequent Backtrack() call will
-/// make the Preprocessor re-lex the same tokens.
-///
-/// Nested backtracks are allowed, meaning that EnableBacktrackAtThisPos can
-/// be called multiple times and CommitBacktrackedTokens/Backtrack calls will
-/// be combined with the EnableBacktrackAtThisPos calls in reverse order.
+// EnableBacktrackAtThisPos - From the point that this method is called, and
+// until CommitBacktrackedTokens() or Backtrack() is called, the Preprocessor
+// keeps track of the lexed tokens so that a subsequent Backtrack() call will
+// make the Preprocessor re-lex the same tokens.
+//
+// Nested backtracks are allowed, meaning that EnableBacktrackAtThisPos can
+// be called multiple times and CommitBacktrackedTokens/Backtrack calls will
+// be combined with the EnableBacktrackAtThisPos calls in reverse order.
 void Preprocessor::EnableBacktrackAtThisPos() {
   BacktrackPositions.push_back(CachedLexPos);
   EnterCachingLexMode();
 }
 
-/// CommitBacktrackedTokens - Disable the last EnableBacktrackAtThisPos call.
+// Disable the last EnableBacktrackAtThisPos call.
 void Preprocessor::CommitBacktrackedTokens() {
   assert(!BacktrackPositions.empty()
          && "EnableBacktrackAtThisPos was not called!");
   BacktrackPositions.pop_back();
 }
 
-/// Backtrack - Make Preprocessor re-lex the tokens that were lexed since
-/// EnableBacktrackAtThisPos() was previously called.
+// Make Preprocessor re-lex the tokens that were lexed since
+// EnableBacktrackAtThisPos() was previously called.
 void Preprocessor::Backtrack() {
   assert(!BacktrackPositions.empty()
          && "EnableBacktrackAtThisPos was not called!");
diff --git a/lib/Lex/PPConditionalDirectiveRecord.cpp b/lib/Lex/PPConditionalDirectiveRecord.cpp
index 16dc1d8..99b87a0 100644
--- a/lib/Lex/PPConditionalDirectiveRecord.cpp
+++ b/lib/Lex/PPConditionalDirectiveRecord.cpp
@@ -77,7 +77,7 @@
 
 void PPConditionalDirectiveRecord::If(SourceLocation Loc,
                                       SourceRange ConditionRange,
-                                      bool ConditionValue) {
+                                      ConditionValueKind ConditionValue) {
   addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
   CondDirectiveStack.push_back(Loc);
 }
@@ -98,7 +98,7 @@
 
 void PPConditionalDirectiveRecord::Elif(SourceLocation Loc,
                                         SourceRange ConditionRange,
-                                        bool ConditionValue,
+                                        ConditionValueKind ConditionValue,
                                         SourceLocation IfLoc) {
   addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
   CondDirectiveStack.back() = Loc;
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp
index 86c508f..1741c30 100644
--- a/lib/Lex/PPDirectives.cpp
+++ b/lib/Lex/PPDirectives.cpp
@@ -25,6 +25,7 @@
 #include "clang/Lex/Pragma.h"
 #include "llvm/ADT/APInt.h"
 #include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FileSystem.h"
 #include "llvm/Support/SaveAndRestore.h"
 using namespace clang;
 
@@ -44,7 +45,7 @@
   }
 
   MIChain->Next = MIChainHead;
-  MIChain->Prev = 0;
+  MIChain->Prev = nullptr;
   if (MIChainHead)
     MIChainHead->Prev = MIChain;
   MIChainHead = MIChain;
@@ -60,8 +61,8 @@
 
 MacroInfo *Preprocessor::AllocateDeserializedMacroInfo(SourceLocation L,
                                                        unsigned SubModuleID) {
-  LLVM_STATIC_ASSERT(llvm::AlignOf<MacroInfo>::Alignment >= sizeof(SubModuleID),
-                     "alignment for MacroInfo is less than the ID");
+  static_assert(llvm::AlignOf<MacroInfo>::Alignment >= sizeof(SubModuleID),
+                "alignment for MacroInfo is less than the ID");
   DeserializedMacroInfoChain *MIChain =
       BP.Allocate<DeserializedMacroInfoChain>();
   MIChain->Next = DeserialMIChainHead;
@@ -100,17 +101,16 @@
 /// \brief Release the specified MacroInfo to be reused for allocating
 /// new MacroInfo objects.
 void Preprocessor::ReleaseMacroInfo(MacroInfo *MI) {
-  MacroInfoChain *MIChain = (MacroInfoChain*) MI;
+  MacroInfoChain *MIChain = (MacroInfoChain *)MI;
   if (MacroInfoChain *Prev = MIChain->Prev) {
     MacroInfoChain *Next = MIChain->Next;
     Prev->Next = Next;
     if (Next)
       Next->Prev = Prev;
-  }
-  else {
+  } else {
     assert(MIChainHead == MIChain);
     MIChainHead = MIChain->Next;
-    MIChainHead->Prev = 0;
+    MIChainHead->Prev = nullptr;
   }
   MIChain->Next = MICache;
   MICache = MIChain;
@@ -128,6 +128,50 @@
   } while (Tmp.isNot(tok::eod));
 }
 
+bool Preprocessor::CheckMacroName(Token &MacroNameTok, char isDefineUndef) {
+  // Missing macro name?
+  if (MacroNameTok.is(tok::eod))
+    return Diag(MacroNameTok, diag::err_pp_missing_macro_name);
+
+  IdentifierInfo *II = MacroNameTok.getIdentifierInfo();
+  if (!II) {
+    bool Invalid = false;
+    std::string Spelling = getSpelling(MacroNameTok, &Invalid);
+    if (Invalid)
+      return Diag(MacroNameTok, diag::err_pp_macro_not_identifier);
+    II = getIdentifierInfo(Spelling);
+
+    if (!II->isCPlusPlusOperatorKeyword())
+      return Diag(MacroNameTok, diag::err_pp_macro_not_identifier);
+
+    // C++ 2.5p2: Alternative tokens behave the same as its primary token
+    // except for their spellings.
+    Diag(MacroNameTok, getLangOpts().MicrosoftExt
+                           ? diag::ext_pp_operator_used_as_macro_name
+                           : diag::err_pp_operator_used_as_macro_name)
+        << II << MacroNameTok.getKind();
+
+    // Allow #defining |and| and friends for Microsoft compatibility or
+    // recovery when legacy C headers are included in C++.
+    MacroNameTok.setIdentifierInfo(II);
+  }
+
+  if (isDefineUndef && II->getPPKeywordID() == tok::pp_defined) {
+    // Error if defining "defined": C99 6.10.8/4, C++ [cpp.predefined]p4.
+    return Diag(MacroNameTok, diag::err_defined_macro_name);
+  }
+
+  if (isDefineUndef == 2 && II->hasMacroDefinition() &&
+      getMacroInfo(II)->isBuiltinMacro()) {
+    // Warn if undefining "__LINE__" and other builtins, per C99 6.10.8/4
+    // and C++ [cpp.predefined]p4], but allow it as an extension.
+    Diag(MacroNameTok, diag::ext_pp_undef_builtin_macro);
+  }
+
+  // Okay, we got a good identifier.
+  return false;
+}
+
 /// \brief Lex and validate a macro name, which occurs after a
 /// \#define or \#undef.
 ///
@@ -145,53 +189,16 @@
     setCodeCompletionReached();
     LexUnexpandedToken(MacroNameTok);
   }
-  
-  // Missing macro name?
-  if (MacroNameTok.is(tok::eod)) {
-    Diag(MacroNameTok, diag::err_pp_missing_macro_name);
+
+  if (!CheckMacroName(MacroNameTok, isDefineUndef))
     return;
+
+  // Invalid macro name, read and discard the rest of the line and set the
+  // token kind to tok::eod if necessary.
+  if (MacroNameTok.isNot(tok::eod)) {
+    MacroNameTok.setKind(tok::eod);
+    DiscardUntilEndOfDirective();
   }
-
-  IdentifierInfo *II = MacroNameTok.getIdentifierInfo();
-  if (II == 0) {
-    bool Invalid = false;
-    std::string Spelling = getSpelling(MacroNameTok, &Invalid);
-    if (Invalid)
-      return;
-
-    const IdentifierInfo &Info = Identifiers.get(Spelling);
-
-    // Allow #defining |and| and friends in microsoft mode.
-    if (Info.isCPlusPlusOperatorKeyword() && getLangOpts().MicrosoftMode) {
-      MacroNameTok.setIdentifierInfo(getIdentifierInfo(Spelling));
-      return;
-    }
-
-    if (Info.isCPlusPlusOperatorKeyword())
-      // C++ 2.5p2: Alternative tokens behave the same as its primary token
-      // except for their spellings.
-      Diag(MacroNameTok, diag::err_pp_operator_used_as_macro_name) << Spelling;
-    else
-      Diag(MacroNameTok, diag::err_pp_macro_not_identifier);
-    // Fall through on error.
-  } else if (isDefineUndef && II->getPPKeywordID() == tok::pp_defined) {
-    // Error if defining "defined": C99 6.10.8/4, C++ [cpp.predefined]p4.
-    Diag(MacroNameTok, diag::err_defined_macro_name);
-  } else if (isDefineUndef == 2 && II->hasMacroDefinition() &&
-             getMacroInfo(II)->isBuiltinMacro()) {
-    // Warn if undefining "__LINE__" and other builtins, per C99 6.10.8/4
-    // and C++ [cpp.predefined]p4], but allow it as an extension.
-    Diag(MacroNameTok, diag::ext_pp_undef_builtin_macro);
-    return;
-  } else {
-    // Okay, we got a good identifier node.  Return it.
-    return;
-  }
-
-  // Invalid macro name, read and discard the rest of the line.  Then set the
-  // token kind to tok::eod.
-  MacroNameTok.setKind(tok::eod);
-  return DiscardUntilEndOfDirective();
 }
 
 /// \brief Ensure that the next token is a tok::eod token.
@@ -309,9 +316,9 @@
     // to spell an i/e in a strange way that is another letter.  Skipping this
     // allows us to avoid looking up the identifier info for #define/#undef and
     // other common directives.
-    const char *RawCharData = Tok.getRawIdentifierData();
+    StringRef RI = Tok.getRawIdentifier();
 
-    char FirstChar = RawCharData[0];
+    char FirstChar = RI[0];
     if (FirstChar >= 'a' && FirstChar <= 'z' &&
         FirstChar != 'i' && FirstChar != 'e') {
       CurPPLexer->ParsingPreprocessorDirective = false;
@@ -325,8 +332,8 @@
     // when skipping.
     char DirectiveBuf[20];
     StringRef Directive;
-    if (!Tok.needsCleaning() && Tok.getLength() < 20) {
-      Directive = StringRef(RawCharData, Tok.getLength());
+    if (!Tok.needsCleaning() && RI.size() < 20) {
+      Directive = RI;
     } else {
       std::string DirectiveStr = getSpelling(Tok);
       unsigned IdLen = DirectiveStr.size();
@@ -404,35 +411,33 @@
       } else if (Sub == "lif") {  // "elif".
         PPConditionalInfo &CondInfo = CurPPLexer->peekConditionalLevel();
 
-        bool ShouldEnter;
-        const SourceLocation ConditionalBegin = CurPPLexer->getSourceLocation();
+        // If this is a #elif with a #else before it, report the error.
+        if (CondInfo.FoundElse) Diag(Tok, diag::pp_err_elif_after_else);
+
         // If this is in a skipping block or if we're already handled this #if
         // block, don't bother parsing the condition.
         if (CondInfo.WasSkipping || CondInfo.FoundNonSkip) {
           DiscardUntilEndOfDirective();
-          ShouldEnter = false;
         } else {
+          const SourceLocation CondBegin = CurPPLexer->getSourceLocation();
           // Restore the value of LexingRawMode so that identifiers are
           // looked up, etc, inside the #elif expression.
           assert(CurPPLexer->LexingRawMode && "We have to be skipping here!");
           CurPPLexer->LexingRawMode = false;
-          IdentifierInfo *IfNDefMacro = 0;
-          ShouldEnter = EvaluateDirectiveExpression(IfNDefMacro);
+          IdentifierInfo *IfNDefMacro = nullptr;
+          const bool CondValue = EvaluateDirectiveExpression(IfNDefMacro);
           CurPPLexer->LexingRawMode = true;
-        }
-        const SourceLocation ConditionalEnd = CurPPLexer->getSourceLocation();
-
-        // If this is a #elif with a #else before it, report the error.
-        if (CondInfo.FoundElse) Diag(Tok, diag::pp_err_elif_after_else);
-
-        // If this condition is true, enter it!
-        if (ShouldEnter) {
-          CondInfo.FoundNonSkip = true;
-          if (Callbacks)
+          if (Callbacks) {
+            const SourceLocation CondEnd = CurPPLexer->getSourceLocation();
             Callbacks->Elif(Tok.getLocation(),
-                            SourceRange(ConditionalBegin, ConditionalEnd),
-                            ShouldEnter, CondInfo.IfLoc);
-          break;
+                            SourceRange(CondBegin, CondEnd),
+                            (CondValue ? PPCallbacks::CVK_True : PPCallbacks::CVK_False), CondInfo.IfLoc);
+          }
+          // If this condition is true, enter it!
+          if (CondValue) {
+            CondInfo.FoundNonSkip = true;
+            break;
+          }
         }
       }
     }
@@ -516,7 +521,7 @@
       continue;
 
     // Evaluate the condition of the #elif.
-    IdentifierInfo *IfNDefMacro = 0;
+    IdentifierInfo *IfNDefMacro = nullptr;
     CurPTHLexer->ParsingPreprocessorDirective = true;
     bool ShouldEnter = EvaluateDirectiveExpression(IfNDefMacro);
     CurPTHLexer->ParsingPreprocessorDirective = false;
@@ -540,7 +545,8 @@
     return HeaderInfo.getModuleMap().SourceModule; // Compiling a source.
   }
   // Try to determine the module of the include directive.
-  FileID IDOfIncl = SourceMgr.getFileID(FilenameLoc);
+  // FIXME: Look into directly passing the FileEntry from LookupFile instead.
+  FileID IDOfIncl = SourceMgr.getFileID(SourceMgr.getExpansionLoc(FilenameLoc));
   if (const FileEntry *EntryOfIncl = SourceMgr.getFileEntryForID(IDOfIncl)) {
     // The include comes from a file.
     return ModMap.findModuleForHeader(EntryOfIncl).getModule();
@@ -551,69 +557,6 @@
   }
 }
 
-bool Preprocessor::violatesPrivateInclude(
-    Module *RequestingModule,
-    const FileEntry *IncFileEnt,
-    ModuleMap::ModuleHeaderRole Role,
-    Module *RequestedModule) {
-  #ifndef NDEBUG
-  // Check for consistency between the module header role
-  // as obtained from the lookup and as obtained from the module.
-  // This check is not cheap, so enable it only for debugging.
-  SmallVectorImpl<const FileEntry *> &PvtHdrs
-      = RequestedModule->PrivateHeaders;
-  SmallVectorImpl<const FileEntry *>::iterator Look
-      = std::find(PvtHdrs.begin(), PvtHdrs.end(), IncFileEnt);
-  bool IsPrivate = Look != PvtHdrs.end();
-  assert((IsPrivate && Role == ModuleMap::PrivateHeader)
-               || (!IsPrivate && Role != ModuleMap::PrivateHeader));
-  #endif
-  return Role == ModuleMap::PrivateHeader &&
-         RequestedModule->getTopLevelModule() != RequestingModule;
-}
-
-bool Preprocessor::violatesUseDeclarations(
-    Module *RequestingModule,
-    Module *RequestedModule) {
-  ModuleMap &ModMap = HeaderInfo.getModuleMap();
-  ModMap.resolveUses(RequestingModule, /*Complain=*/false);
-  const SmallVectorImpl<Module *> &AllowedUses = RequestingModule->DirectUses;
-  SmallVectorImpl<Module *>::const_iterator Declared =
-      std::find(AllowedUses.begin(), AllowedUses.end(), RequestedModule);
-  return Declared == AllowedUses.end();
-}
-
-void Preprocessor::verifyModuleInclude(SourceLocation FilenameLoc,
-                                       StringRef Filename,
-                                       const FileEntry *IncFileEnt) {
-  Module *RequestingModule = getModuleForLocation(FilenameLoc);
-  if (RequestingModule)
-    HeaderInfo.getModuleMap().resolveUses(RequestingModule, /*Complain=*/false);
-  ModuleMap::KnownHeader RequestedModule =
-      HeaderInfo.getModuleMap().findModuleForHeader(IncFileEnt,
-                                                    RequestingModule);
-
-  if (RequestingModule == RequestedModule.getModule())
-    return; // No faults wihin a module, or between files both not in modules.
-
-  if (RequestingModule != HeaderInfo.getModuleMap().SourceModule)
-    return; // No errors for indirect modules.
-            // This may be a bit of a problem for modules with no source files.
-
-  if (RequestedModule && violatesPrivateInclude(RequestingModule, IncFileEnt,
-                                                RequestedModule.getRole(),
-                                                RequestedModule.getModule()))
-    Diag(FilenameLoc, diag::error_use_of_private_header_outside_module)
-        << Filename;
-
-  // FIXME: Add support for FixIts in module map files and offer adding the
-  // required use declaration.
-  if (RequestingModule && getLangOpts().ModulesDeclUse &&
-      violatesUseDeclarations(RequestingModule, RequestedModule.getModule()))
-    Diag(FilenameLoc, diag::error_undeclared_use_of_module)
-        << Filename;
-}
-
 const FileEntry *Preprocessor::LookupFile(
     SourceLocation FilenameLoc,
     StringRef Filename,
@@ -624,12 +567,12 @@
     SmallVectorImpl<char> *RelativePath,
     ModuleMap::KnownHeader *SuggestedModule,
     bool SkipCache) {
-  // If the header lookup mechanism may be relative to the current file, pass in
-  // info about where the current file is.
-  const FileEntry *CurFileEnt = 0;
+  // If the header lookup mechanism may be relative to the current inclusion
+  // stack, record the parent #includes.
+  SmallVector<const FileEntry *, 16> Includers;
   if (!FromDir) {
     FileID FID = getCurrentFileLexer()->getFileID();
-    CurFileEnt = SourceMgr.getFileEntryForID(FID);
+    const FileEntry *FileEnt = SourceMgr.getFileEntryForID(FID);
 
     // If there is no file entry associated with this file, it must be the
     // predefines buffer.  Any other file is not lexed with a normal lexer, so
@@ -637,48 +580,74 @@
     // predefines buffer, resolve #include references (which come from the
     // -include command line argument) as if they came from the main file, this
     // affects file lookup etc.
-    if (CurFileEnt == 0) {
-      FID = SourceMgr.getMainFileID();
-      CurFileEnt = SourceMgr.getFileEntryForID(FID);
+    if (!FileEnt)
+      FileEnt = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID());
+
+    if (FileEnt)
+      Includers.push_back(FileEnt);
+
+    // MSVC searches the current include stack from top to bottom for
+    // headers included by quoted include directives.
+    // See: http://msdn.microsoft.com/en-us/library/36k2cdd4.aspx
+    if (LangOpts.MSVCCompat && !isAngled) {
+      for (unsigned i = 0, e = IncludeMacroStack.size(); i != e; ++i) {
+        IncludeStackInfo &ISEntry = IncludeMacroStack[e - i - 1];
+        if (IsFileLexer(ISEntry))
+          if ((FileEnt = SourceMgr.getFileEntryForID(
+                   ISEntry.ThePPLexer->getFileID())))
+            Includers.push_back(FileEnt);
+      }
     }
   }
 
   // Do a standard file entry lookup.
   CurDir = CurDirLookup;
   const FileEntry *FE = HeaderInfo.LookupFile(
-      Filename, isAngled, FromDir, CurDir, CurFileEnt,
-      SearchPath, RelativePath, SuggestedModule, SkipCache);
+      Filename, FilenameLoc, isAngled, FromDir, CurDir, Includers, SearchPath,
+      RelativePath, SuggestedModule, SkipCache);
   if (FE) {
-    if (SuggestedModule)
-      verifyModuleInclude(FilenameLoc, Filename, FE);
+    if (SuggestedModule && !LangOpts.AsmPreprocessor)
+      HeaderInfo.getModuleMap().diagnoseHeaderInclusion(
+          getModuleForLocation(FilenameLoc), FilenameLoc, Filename, FE);
     return FE;
   }
 
+  const FileEntry *CurFileEnt;
   // Otherwise, see if this is a subframework header.  If so, this is relative
   // to one of the headers on the #include stack.  Walk the list of the current
   // headers on the #include stack and pass them to HeaderInfo.
   if (IsFileLexer()) {
-    if ((CurFileEnt = SourceMgr.getFileEntryForID(CurPPLexer->getFileID())))
+    if ((CurFileEnt = SourceMgr.getFileEntryForID(CurPPLexer->getFileID()))) {
       if ((FE = HeaderInfo.LookupSubframeworkHeader(Filename, CurFileEnt,
                                                     SearchPath, RelativePath,
-                                                    SuggestedModule)))
+                                                    SuggestedModule))) {
+        if (SuggestedModule && !LangOpts.AsmPreprocessor)
+          HeaderInfo.getModuleMap().diagnoseHeaderInclusion(
+              getModuleForLocation(FilenameLoc), FilenameLoc, Filename, FE);
         return FE;
+      }
+    }
   }
 
   for (unsigned i = 0, e = IncludeMacroStack.size(); i != e; ++i) {
     IncludeStackInfo &ISEntry = IncludeMacroStack[e-i-1];
     if (IsFileLexer(ISEntry)) {
       if ((CurFileEnt =
-           SourceMgr.getFileEntryForID(ISEntry.ThePPLexer->getFileID())))
+           SourceMgr.getFileEntryForID(ISEntry.ThePPLexer->getFileID()))) {
         if ((FE = HeaderInfo.LookupSubframeworkHeader(
                 Filename, CurFileEnt, SearchPath, RelativePath,
-                SuggestedModule)))
+                SuggestedModule))) {
+          if (SuggestedModule && !LangOpts.AsmPreprocessor)
+            HeaderInfo.getModuleMap().diagnoseHeaderInclusion(
+                getModuleForLocation(FilenameLoc), FilenameLoc, Filename, FE);
           return FE;
+        }
+      }
     }
   }
 
   // Otherwise, we really couldn't find the file.
-  return 0;
+  return nullptr;
 }
 
 
@@ -776,7 +745,7 @@
     return HandleDigitDirective(Result);
   default:
     IdentifierInfo *II = Result.getIdentifierInfo();
-    if (II == 0) break;  // Not an identifier.
+    if (!II) break; // Not an identifier.
 
     // Ask what the preprocessor keyword ID is.
     switch (II->getPPKeywordID()) {
@@ -986,7 +955,7 @@
     return DiscardUntilEndOfDirective();
   } else {
     // Parse and validate the string, converting it into a unique ID.
-    StringLiteralParser Literal(&StrTok, 1, *this);
+    StringLiteralParser Literal(StrTok, *this);
     assert(Literal.isAscii() && "Didn't allow wide strings in");
     if (Literal.hadError)
       return DiscardUntilEndOfDirective();
@@ -1122,7 +1091,7 @@
     return DiscardUntilEndOfDirective();
   } else {
     // Parse and validate the string, converting it into a unique ID.
-    StringLiteralParser Literal(&StrTok, 1, *this);
+    StringLiteralParser Literal(StrTok, *this);
     assert(Literal.isAscii() && "Didn't allow wide strings in");
     if (Literal.hadError)
       return DiscardUntilEndOfDirective();
@@ -1241,7 +1210,7 @@
   MacroDirective *MD = getMacroDirective(II);
   
   // If the macro is not defined, this is an error.
-  if (MD == 0) {
+  if (!MD) {
     Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
     return;
   }
@@ -1268,7 +1237,7 @@
   MacroDirective *MD = getMacroDirective(II);
   
   // If the macro is not defined, this is an error.
-  if (MD == 0) {
+  if (!MD) {
     Diag(MacroNameTok, diag::err_pp_visibility_non_macro) << II;
     return;
   }
@@ -1327,21 +1296,20 @@
   return isAngled;
 }
 
-/// \brief Handle cases where the \#include name is expanded from a macro
-/// as multiple tokens, which need to be glued together.
-///
-/// This occurs for code like:
-/// \code
-///    \#define FOO <a/b.h>
-///    \#include FOO
-/// \endcode
-/// because in this case, "<a/b.h>" is returned as 7 tokens, not one.
-///
-/// This code concatenates and consumes tokens up to the '>' token.  It returns
-/// false if the > was found, otherwise it returns true if it finds and consumes
-/// the EOD marker.
-bool Preprocessor::ConcatenateIncludeName(
-                                        SmallString<128> &FilenameBuffer,
+// \brief Handle cases where the \#include name is expanded from a macro
+// as multiple tokens, which need to be glued together.
+//
+// This occurs for code like:
+// \code
+//    \#define FOO <a/b.h>
+//    \#include FOO
+// \endcode
+// because in this case, "<a/b.h>" is returned as 7 tokens, not one.
+//
+// This code concatenates and consumes tokens up to the '>' token.  It returns
+// false if the > was found, otherwise it returns true if it finds and consumes
+// the EOD marker.
+bool Preprocessor::ConcatenateIncludeName(SmallString<128> &FilenameBuffer,
                                           SourceLocation &End) {
   Token CurTok;
 
@@ -1389,6 +1357,19 @@
   return true;
 }
 
+/// \brief Push a token onto the token stream containing an annotation.
+static void EnterAnnotationToken(Preprocessor &PP,
+                                 SourceLocation Begin, SourceLocation End,
+                                 tok::TokenKind Kind, void *AnnotationVal) {
+  Token *Tok = new Token[1];
+  Tok[0].startToken();
+  Tok[0].setKind(Kind);
+  Tok[0].setLocation(Begin);
+  Tok[0].setAnnotationEndLoc(End);
+  Tok[0].setAnnotationValue(AnnotationVal);
+  PP.EnterTokenStream(Tok, 1, true, true);
+}
+
 /// HandleIncludeDirective - The "\#include" tokens have just been read, read
 /// the file to be included from the lexer, then include it!  This is a common
 /// routine with functionality shared between \#include, \#include_next and
@@ -1485,10 +1466,16 @@
   // the path.
   ModuleMap::KnownHeader SuggestedModule;
   SourceLocation FilenameLoc = FilenameTok.getLocation();
+  SmallString<128> NormalizedPath;
+  if (LangOpts.MSVCCompat) {
+    NormalizedPath = Filename.str();
+    llvm::sys::fs::normalize_separators(NormalizedPath);
+  }
   const FileEntry *File = LookupFile(
-      FilenameLoc, Filename, isAngled, LookupFrom, CurDir,
-      Callbacks ? &SearchPath : NULL, Callbacks ? &RelativePath : NULL,
-      HeaderInfo.getHeaderSearchOpts().ModuleMaps ? &SuggestedModule : 0);
+      FilenameLoc, LangOpts.MSVCCompat ? NormalizedPath.c_str() : Filename,
+      isAngled, LookupFrom, CurDir, Callbacks ? &SearchPath : nullptr,
+      Callbacks ? &RelativePath : nullptr,
+      HeaderInfo.getHeaderSearchOpts().ModuleMaps ? &SuggestedModule : nullptr);
 
   if (Callbacks) {
     if (!File) {
@@ -1501,10 +1488,13 @@
           HeaderInfo.AddSearchPath(DL, isAngled);
           
           // Try the lookup again, skipping the cache.
-          File = LookupFile(FilenameLoc, Filename, isAngled, LookupFrom, CurDir,
-                            0, 0, HeaderInfo.getHeaderSearchOpts().ModuleMaps
+          File = LookupFile(FilenameLoc,
+                            LangOpts.MSVCCompat ? NormalizedPath.c_str()
+                                                : Filename,
+                            isAngled, LookupFrom, CurDir, nullptr, nullptr,
+                            HeaderInfo.getHeaderSearchOpts().ModuleMaps
                                       ? &SuggestedModule
-                                      : 0,
+                                      : nullptr,
                             /*SkipCache*/ true);
         }
       }
@@ -1512,23 +1502,26 @@
     
     if (!SuggestedModule || !getLangOpts().Modules) {
       // Notify the callback object that we've seen an inclusion directive.
-      Callbacks->InclusionDirective(HashLoc, IncludeTok, Filename, isAngled,
-                                    FilenameRange, File,
-                                    SearchPath, RelativePath,
-                                    /*ImportedModule=*/0);
+      Callbacks->InclusionDirective(HashLoc, IncludeTok,
+                                    LangOpts.MSVCCompat ? NormalizedPath.c_str()
+                                                        : Filename,
+                                    isAngled, FilenameRange, File, SearchPath,
+                                    RelativePath, /*ImportedModule=*/nullptr);
     }
   }
-  
-  if (File == 0) {
+
+  if (!File) {
     if (!SuppressIncludeNotFoundError) {
       // If the file could not be located and it was included via angle 
       // brackets, we can attempt a lookup as though it were a quoted path to
       // provide the user with a possible fixit.
       if (isAngled) {
         File = LookupFile(
-            FilenameLoc, Filename, false, LookupFrom, CurDir,
-            Callbacks ? &SearchPath : 0, Callbacks ? &RelativePath : 0,
-            HeaderInfo.getHeaderSearchOpts().ModuleMaps ? &SuggestedModule : 0);
+            FilenameLoc, LangOpts.MSVCCompat ? NormalizedPath.c_str() : Filename,
+            false, LookupFrom, CurDir, Callbacks ? &SearchPath : nullptr,
+            Callbacks ? &RelativePath : nullptr,
+            HeaderInfo.getHeaderSearchOpts().ModuleMaps ? &SuggestedModule
+                                                        : nullptr);
         if (File) {
           SourceRange Range(FilenameTok.getLocation(), CharEnd);
           Diag(FilenameTok, diag::err_pp_file_not_found_not_fatal) << 
@@ -1590,7 +1583,7 @@
     // include directive maps to.
     bool BuildingImportedModule
       = Path[0].first->getName() == getLangOpts().CurrentModule;
-    
+
     if (!BuildingImportedModule && getLangOpts().ObjC2) {
       // If we're not building the imported module, warn that we're going
       // to automatically turn this inclusion directive into a module import.
@@ -1609,7 +1602,7 @@
     ModuleLoadResult Imported
       = TheModuleLoader.loadModule(IncludeTok.getLocation(), Path, Visibility,
                                    /*IsIncludeDirective=*/true);
-    assert((Imported == 0 || Imported == SuggestedModule.getModule()) &&
+    assert((Imported == nullptr || Imported == SuggestedModule.getModule()) &&
            "the imported module is different than the suggested one");
 
     if (!Imported && hadModuleLoaderFatalFailure()) {
@@ -1639,13 +1632,8 @@
         // make the module visible.
         // FIXME: Produce this as the current token directly, rather than
         // allocating a new token for it.
-        Token *Tok = new Token[1];
-        Tok[0].startToken();
-        Tok[0].setKind(tok::annot_module_include);
-        Tok[0].setLocation(HashLoc);
-        Tok[0].setAnnotationEndLoc(End);
-        Tok[0].setAnnotationValue(Imported);
-        EnterTokenStream(Tok, 1, true, true);
+        EnterAnnotationToken(*this, HashLoc, End, tok::annot_module_include,
+                             Imported);
       }
       return;
     }
@@ -1665,7 +1653,7 @@
     Callbacks->InclusionDirective(HashLoc, IncludeTok, Filename, isAngled,
                                   FilenameRange, File,
                                   SearchPath, RelativePath,
-                                  /*ImportedModule=*/0);
+                                  /*ImportedModule=*/nullptr);
   }
   
   // The #included file will be considered to be a system header if either it is
@@ -1692,8 +1680,27 @@
   FileID FID = SourceMgr.createFileID(File, IncludePos, FileCharacter);
   assert(!FID.isInvalid() && "Expected valid file ID");
 
-  // Finally, if all is good, enter the new file!
-  EnterSourceFile(FID, CurDir, FilenameTok.getLocation());
+  // Determine if we're switching to building a new submodule, and which one.
+  ModuleMap::KnownHeader BuildingModule;
+  if (getLangOpts().Modules && !getLangOpts().CurrentModule.empty()) {
+    Module *RequestingModule = getModuleForLocation(FilenameLoc);
+    BuildingModule =
+        HeaderInfo.getModuleMap().findModuleForHeader(File, RequestingModule);
+  }
+
+  // If all is good, enter the new file!
+  if (EnterSourceFile(FID, CurDir, FilenameTok.getLocation()))
+    return;
+
+  // If we're walking into another part of the same module, let the parser
+  // know that any future declarations are within that other submodule.
+  if (BuildingModule) {
+    assert(!CurSubmodule && "should not have marked this as a module yet");
+    CurSubmodule = BuildingModule.getModule();
+
+    EnterAnnotationToken(*this, HashLoc, End, tok::annot_module_begin,
+                         CurSubmodule);
+  }
 }
 
 /// HandleIncludeNextDirective - Implements \#include_next.
@@ -1707,9 +1714,9 @@
   // diagnostic.
   const DirectoryLookup *Lookup = CurDirLookup;
   if (isInPrimaryFile()) {
-    Lookup = 0;
+    Lookup = nullptr;
     Diag(IncludeNextTok, diag::pp_include_next_in_primary);
-  } else if (Lookup == 0) {
+  } else if (!Lookup) {
     Diag(IncludeNextTok, diag::pp_include_next_absolute_path);
   } else {
     // Start looking up in the next directory.
@@ -1738,11 +1745,11 @@
 void Preprocessor::HandleImportDirective(SourceLocation HashLoc,
                                          Token &ImportTok) {
   if (!LangOpts.ObjC1) {  // #import is standard for ObjC.
-    if (LangOpts.MicrosoftMode)
+    if (LangOpts.MSVCCompat)
       return HandleMicrosoftImportDirective(ImportTok);
     Diag(ImportTok, diag::ext_pp_import_directive);
   }
-  return HandleIncludeDirective(HashLoc, ImportTok, 0, true);
+  return HandleIncludeDirective(HashLoc, ImportTok, nullptr, true);
 }
 
 /// HandleIncludeMacrosDirective - The -imacros command line option turns into a
@@ -1763,7 +1770,7 @@
 
   // Treat this as a normal #include for checking purposes.  If this is
   // successful, it will push a new lexer onto the include stack.
-  HandleIncludeDirective(HashLoc, IncludeMacrosTok, 0, false);
+  HandleIncludeDirective(HashLoc, IncludeMacrosTok, nullptr, false);
 
   Token TmpTok;
   do {
@@ -1823,7 +1830,7 @@
       // Handle keywords and identifiers here to accept things like
       // #define Foo(for) for.
       IdentifierInfo *II = Tok.getIdentifierInfo();
-      if (II == 0) {
+      if (!II) {
         // #define X(1
         Diag(Tok, diag::err_pp_invalid_tok_in_arg_list);
         return true;
@@ -2027,7 +2034,7 @@
       LexUnexpandedToken(Tok);
 
       // Check for a valid macro arg identifier.
-      if (Tok.getIdentifierInfo() == 0 ||
+      if (Tok.getIdentifierInfo() == nullptr ||
           MI->getArgumentNum(Tok.getIdentifierInfo()) == -1) {
 
         // If this is assembler-with-cpp mode, we accept random gibberish after
@@ -2115,8 +2122,7 @@
   // If we need warning for not using the macro, add its location in the
   // warn-because-unused-macro set. If it gets used it will be removed from set.
   if (getSourceManager().isInMainFile(MI->getDefinitionLoc()) &&
-      Diags->getDiagnosticLevel(diag::pp_macro_not_used,
-          MI->getDefinitionLoc()) != DiagnosticsEngine::Ignored) {
+      !Diags->isIgnored(diag::pp_macro_not_used, MI->getDefinitionLoc())) {
     MI->setIsWarnIfUnused(true);
     WarnUnusedMacroLocs.insert(MI->getDefinitionLoc());
   }
@@ -2143,7 +2149,7 @@
 
   // Okay, we finally have a valid identifier to undef.
   MacroDirective *MD = getMacroDirective(MacroNameTok.getIdentifierInfo());
-  const MacroInfo *MI = MD ? MD->getMacroInfo() : 0;
+  const MacroInfo *MI = MD ? MD->getMacroInfo() : nullptr;
 
   // If the callbacks want to know, tell them about the macro #undef.
   // Note: no matter if the macro was defined or not.
@@ -2151,7 +2157,8 @@
     Callbacks->MacroUndefined(MacroNameTok, MD);
 
   // If the macro is not defined, this is a noop undef, just return.
-  if (MI == 0) return;
+  if (!MI)
+    return;
 
   if (!MI->isUsed() && MI->isWarnIfUnused())
     Diag(MI->getDefinitionLoc(), diag::pp_macro_not_used);
@@ -2195,14 +2202,14 @@
 
   IdentifierInfo *MII = MacroNameTok.getIdentifierInfo();
   MacroDirective *MD = getMacroDirective(MII);
-  MacroInfo *MI = MD ? MD->getMacroInfo() : 0;
+  MacroInfo *MI = MD ? MD->getMacroInfo() : nullptr;
 
   if (CurPPLexer->getConditionalStackDepth() == 0) {
     // If the start of a top-level #ifdef and if the macro is not defined,
     // inform MIOpt that this might be the start of a proper include guard.
     // Otherwise it is some other form of unknown conditional which we can't
     // handle.
-    if (!ReadAnyTokensBeforeDirective && MI == 0) {
+    if (!ReadAnyTokensBeforeDirective && !MI) {
       assert(isIfndef && "#ifdef shouldn't reach here");
       CurPPLexer->MIOpt.EnterTopLevelIfndef(MII, MacroNameTok.getLocation());
     } else
@@ -2241,7 +2248,7 @@
   ++NumIf;
 
   // Parse and evaluate the conditional expression.
-  IdentifierInfo *IfNDefMacro = 0;
+  IdentifierInfo *IfNDefMacro = nullptr;
   const SourceLocation ConditionalBegin = CurPPLexer->getSourceLocation();
   const bool ConditionalTrue = EvaluateDirectiveExpression(IfNDefMacro);
   const SourceLocation ConditionalEnd = CurPPLexer->getSourceLocation();
@@ -2259,7 +2266,7 @@
   if (Callbacks)
     Callbacks->If(IfToken.getLocation(),
                   SourceRange(ConditionalBegin, ConditionalEnd),
-                  ConditionalTrue);
+                  (ConditionalTrue ? PPCallbacks::CVK_True : PPCallbacks::CVK_False));
 
   // Should we include the stuff contained by this directive?
   if (ConditionalTrue) {
@@ -2356,7 +2363,7 @@
   if (Callbacks)
     Callbacks->Elif(ElifToken.getLocation(),
                     SourceRange(ConditionalBegin, ConditionalEnd),
-                    true, CI.IfLoc);
+                    PPCallbacks::CVK_NotEvaluated, CI.IfLoc);
 
   // Finally, skip the rest of the contents of this block.
   SkipExcludedConditionalBlock(CI.IfLoc, /*Foundnonskip*/true,
diff --git a/lib/Lex/PPExpressions.cpp b/lib/Lex/PPExpressions.cpp
index 87c0a6a..2260bf9 100644
--- a/lib/Lex/PPExpressions.cpp
+++ b/lib/Lex/PPExpressions.cpp
@@ -81,7 +81,6 @@
 /// EvaluateDefined - Process a 'defined(sym)' expression.
 static bool EvaluateDefined(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
                             bool ValueLive, Preprocessor &PP) {
-  IdentifierInfo *II;
   SourceLocation beginLoc(PeekTok.getLocation());
   Result.setBegin(beginLoc);
 
@@ -102,18 +101,17 @@
     PP.setCodeCompletionReached();
     PP.LexUnexpandedNonComment(PeekTok);
   }
-  
+
   // If we don't have a pp-identifier now, this is an error.
-  if ((II = PeekTok.getIdentifierInfo()) == 0) {
-    PP.Diag(PeekTok, diag::err_pp_defined_requires_identifier);
+  if (PP.CheckMacroName(PeekTok, 0))
     return true;
-  }
 
   // Otherwise, we got an identifier, is it defined to something?
+  IdentifierInfo *II = PeekTok.getIdentifierInfo();
   Result.Val = II->hasMacroDefinition();
   Result.Val.setIsUnsigned(false);  // Result is signed intmax_t.
 
-  MacroDirective *Macro = 0;
+  MacroDirective *Macro = nullptr;
   // If there is a macro, mark it used.
   if (Result.Val != 0 && ValueLive) {
     Macro = PP.getMacroDirective(II);
@@ -130,8 +128,9 @@
     PP.LexUnexpandedNonComment(PeekTok);
 
     if (PeekTok.isNot(tok::r_paren)) {
-      PP.Diag(PeekTok.getLocation(), diag::err_pp_missing_rparen) << "defined";
-      PP.Diag(LParenLoc, diag::note_matching) << "(";
+      PP.Diag(PeekTok.getLocation(), diag::err_pp_expected_after)
+          << "'defined'" << tok::r_paren;
+      PP.Diag(LParenLoc, diag::note_matching) << tok::l_paren;
       return true;
     }
     // Consume the ).
@@ -257,9 +256,10 @@
       // large that it is unsigned" e.g. on 12345678901234567890 where intmax_t
       // is 64-bits.
       if (!Literal.isUnsigned && Result.Val.isNegative()) {
-        // Don't warn for a hex or octal literal: 0x8000..0 shouldn't warn.
+        // Octal, hexadecimal, and binary literals are implicitly unsigned if
+        // the value does not fit into a signed integer type.
         if (ValueLive && Literal.getRadix() == 10)
-          PP.Diag(PeekTok, diag::warn_integer_too_large_for_signed);
+          PP.Diag(PeekTok, diag::ext_integer_too_large_for_signed);
         Result.Val.setIsUnsigned(true);
       }
     }
@@ -342,7 +342,7 @@
       if (PeekTok.isNot(tok::r_paren)) {
         PP.Diag(PeekTok.getLocation(), diag::err_pp_expected_rparen)
           << Result.getRange();
-        PP.Diag(Start, diag::note_matching) << "(";
+        PP.Diag(Start, diag::note_matching) << tok::l_paren;
         return true;
       }
       DT.State = DefinedTracker::Unknown;
@@ -680,9 +680,9 @@
     case tok::question: {
       // Parse the : part of the expression.
       if (PeekTok.isNot(tok::colon)) {
-        PP.Diag(PeekTok.getLocation(), diag::err_expected_colon)
-          << LHS.getRange(), RHS.getRange();
-        PP.Diag(OpLoc, diag::note_matching) << "?";
+        PP.Diag(PeekTok.getLocation(), diag::err_expected)
+            << tok::colon << LHS.getRange() << RHS.getRange();
+        PP.Diag(OpLoc, diag::note_matching) << tok::question;
         return true;
       }
       // Consume the :.
diff --git a/lib/Lex/PPLexerChange.cpp b/lib/Lex/PPLexerChange.cpp
index 1f970a4..22ee971 100644
--- a/lib/Lex/PPLexerChange.cpp
+++ b/lib/Lex/PPLexerChange.cpp
@@ -58,7 +58,7 @@
     if (IsFileLexer(ISI))
       return ISI.ThePPLexer;
   }
-  return 0;
+  return nullptr;
 }
 
 
@@ -68,7 +68,7 @@
 
 /// EnterSourceFile - Add a source file to the top of the include stack and
 /// start lexing tokens from it instead of the current buffer.
-void Preprocessor::EnterSourceFile(FileID FID, const DirectoryLookup *CurDir,
+bool Preprocessor::EnterSourceFile(FileID FID, const DirectoryLookup *CurDir,
                                    SourceLocation Loc) {
   assert(!CurTokenLexer && "Cannot #include a file inside a macro!");
   ++NumEnteredSourceFiles;
@@ -79,7 +79,7 @@
   if (PTH) {
     if (PTHLexer *PL = PTH->CreateLexer(FID)) {
       EnterSourceFileWithPTH(PL, CurDir);
-      return;
+      return false;
     }
   }
   
@@ -91,7 +91,7 @@
     SourceLocation FileStart = SourceMgr.getLocForStartOfFile(FID);
     Diag(Loc, diag::err_pp_error_opening_file)
       << std::string(SourceMgr.getBufferName(FileStart)) << "";
-    return;
+    return true;
   }
 
   if (isCodeCompletionEnabled() &&
@@ -102,7 +102,7 @@
   }
 
   EnterSourceFileWithLexer(new Lexer(FID, InputFile, *this), CurDir);
-  return;
+  return false;
 }
 
 /// EnterSourceFileWithLexer - Add a source file to the top of the include stack
@@ -117,6 +117,7 @@
   CurLexer.reset(TheLexer);
   CurPPLexer = TheLexer;
   CurDirLookup = CurDir;
+  CurSubmodule = nullptr;
   if (CurLexerKind != CLK_LexAfterModuleImport)
     CurLexerKind = CLK_Lexer;
   
@@ -141,6 +142,7 @@
   CurDirLookup = CurDir;
   CurPTHLexer.reset(PL);
   CurPPLexer = CurPTHLexer.get();
+  CurSubmodule = nullptr;
   if (CurLexerKind != CLK_LexAfterModuleImport)
     CurLexerKind = CLK_PTHLexer;
   
@@ -167,7 +169,7 @@
   }
 
   PushIncludeMacroStack();
-  CurDirLookup = 0;
+  CurDirLookup = nullptr;
   CurTokenLexer.reset(TokLexer);
   if (CurLexerKind != CLK_LexAfterModuleImport)
     CurLexerKind = CLK_TokenLexer;
@@ -200,7 +202,7 @@
 
   // Save our current state.
   PushIncludeMacroStack();
-  CurDirLookup = 0;
+  CurDirLookup = nullptr;
   CurTokenLexer.reset(TokLexer);
   if (CurLexerKind != CLK_LexAfterModuleImport)
     CurLexerKind = CLK_TokenLexer;
@@ -244,6 +246,29 @@
   // but it might if they're empty?
 }
 
+/// \brief Determine the location to use as the end of the buffer for a lexer.
+///
+/// If the file ends with a newline, form the EOF token on the newline itself,
+/// rather than "on the line following it", which doesn't exist.  This makes
+/// diagnostics relating to the end of file include the last file that the user
+/// actually typed, which is goodness.
+const char *Preprocessor::getCurLexerEndPos() {
+  const char *EndPos = CurLexer->BufferEnd;
+  if (EndPos != CurLexer->BufferStart &&
+      (EndPos[-1] == '\n' || EndPos[-1] == '\r')) {
+    --EndPos;
+
+    // Handle \n\r and \r\n:
+    if (EndPos != CurLexer->BufferStart &&
+        (EndPos[-1] == '\n' || EndPos[-1] == '\r') &&
+        EndPos[-1] != EndPos[0])
+      --EndPos;
+  }
+
+  return EndPos;
+}
+
+
 /// HandleEndOfFile - This callback is invoked when the lexer hits the end of
 /// the current file.  This either returns the EOF token or pops a level off
 /// the include stack and keeps going.
@@ -259,6 +284,10 @@
       if (const FileEntry *FE =
             SourceMgr.getFileEntryForID(CurPPLexer->getFileID())) {
         HeaderInfo.SetFileControllingMacro(FE, ControllingMacro);
+        if (MacroInfo *MI =
+              getMacroInfo(const_cast<IdentifierInfo*>(ControllingMacro))) {
+          MI->UsedForHeaderGuard = true;
+        }
         if (const IdentifierInfo *DefinedMacro =
               CurPPLexer->MIOpt.GetDefinedMacro()) {
           if (!ControllingMacro->hasMacroDefinition() &&
@@ -325,7 +354,7 @@
         CurPTHLexer.reset();
       }
 
-      CurPPLexer = 0;
+      CurPPLexer = nullptr;
       return true;
     }
 
@@ -342,7 +371,18 @@
     FileID ExitedFID;
     if (Callbacks && !isEndOfMacro && CurPPLexer)
       ExitedFID = CurPPLexer->getFileID();
-    
+
+    bool LeavingSubmodule = CurSubmodule && CurLexer;
+    if (LeavingSubmodule) {
+      // Notify the parser that we've left the module.
+      const char *EndPos = getCurLexerEndPos();
+      Result.startToken();
+      CurLexer->BufferPtr = EndPos;
+      CurLexer->FormTokenWithChars(Result, EndPos, tok::annot_module_end);
+      Result.setAnnotationEndLoc(Result.getLocation());
+      Result.setAnnotationValue(CurSubmodule);
+    }
+
     // We're done with the #included file.
     RemoveTopOfLexerStack();
 
@@ -357,27 +397,13 @@
                              PPCallbacks::ExitFile, FileType, ExitedFID);
     }
 
-    // Client should lex another token.
-    return false;
+    // Client should lex another token unless we generated an EOM.
+    return LeavingSubmodule;
   }
 
-  // If the file ends with a newline, form the EOF token on the newline itself,
-  // rather than "on the line following it", which doesn't exist.  This makes
-  // diagnostics relating to the end of file include the last file that the user
-  // actually typed, which is goodness.
+  // If this is the end of the main file, form an EOF token.
   if (CurLexer) {
-    const char *EndPos = CurLexer->BufferEnd;
-    if (EndPos != CurLexer->BufferStart &&
-        (EndPos[-1] == '\n' || EndPos[-1] == '\r')) {
-      --EndPos;
-
-      // Handle \n\r and \r\n:
-      if (EndPos != CurLexer->BufferStart &&
-          (EndPos[-1] == '\n' || EndPos[-1] == '\r') &&
-          EndPos[-1] != EndPos[0])
-        --EndPos;
-    }
-
+    const char *EndPos = getCurLexerEndPos();
     Result.startToken();
     CurLexer->BufferPtr = EndPos;
     CurLexer->FormTokenWithChars(Result, EndPos, tok::eof);
@@ -403,13 +429,17 @@
   }
   
   if (!isIncrementalProcessingEnabled())
-    CurPPLexer = 0;
+    CurPPLexer = nullptr;
 
-  // This is the end of the top-level file. 'WarnUnusedMacroLocs' has collected
-  // all macro locations that we need to warn because they are not used.
-  for (WarnUnusedMacroLocsTy::iterator
-         I=WarnUnusedMacroLocs.begin(), E=WarnUnusedMacroLocs.end(); I!=E; ++I)
-    Diag(*I, diag::pp_macro_not_used);
+  if (TUKind == TU_Complete) {
+    // This is the end of the top-level file. 'WarnUnusedMacroLocs' has
+    // collected all macro locations that we need to warn because they are not
+    // used.
+    for (WarnUnusedMacroLocsTy::iterator
+           I=WarnUnusedMacroLocs.begin(), E=WarnUnusedMacroLocs.end();
+           I!=E; ++I)
+      Diag(*I, diag::pp_macro_not_used);
+  }
 
   // If we are building a module that has an umbrella header, make sure that
   // each of the headers within the directory covered by the umbrella header
@@ -419,26 +449,25 @@
       SourceLocation StartLoc
         = SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
 
-      if (getDiagnostics().getDiagnosticLevel(
-            diag::warn_uncovered_module_header, 
-            StartLoc) != DiagnosticsEngine::Ignored) {
+      if (!getDiagnostics().isIgnored(diag::warn_uncovered_module_header,
+                                      StartLoc)) {
         ModuleMap &ModMap = getHeaderSearchInfo().getModuleMap();
-        typedef llvm::sys::fs::recursive_directory_iterator
-          recursive_directory_iterator;
         const DirectoryEntry *Dir = Mod->getUmbrellaDir();
-        llvm::error_code EC;
-        for (recursive_directory_iterator Entry(Dir->getName(), EC), End;
+        vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem();
+        std::error_code EC;
+        for (vfs::recursive_directory_iterator Entry(FS, Dir->getName(), EC), End;
              Entry != End && !EC; Entry.increment(EC)) {
           using llvm::StringSwitch;
           
           // Check whether this entry has an extension typically associated with
           // headers.
-          if (!StringSwitch<bool>(llvm::sys::path::extension(Entry->path()))
+          if (!StringSwitch<bool>(llvm::sys::path::extension(Entry->getName()))
                  .Cases(".h", ".H", ".hh", ".hpp", true)
                  .Default(false))
             continue;
 
-          if (const FileEntry *Header = getFileManager().getFile(Entry->path()))
+          if (const FileEntry *Header =
+                  getFileManager().getFile(Entry->getName()))
             if (!getSourceManager().hasFileInfo(Header)) {
               if (!ModMap.isHeaderInUnavailableModule(Header)) {
                 // Find the relative path that would access this header.
@@ -456,9 +485,8 @@
     // mentioned at all in the module map. Such headers 
     SourceLocation StartLoc
       = SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
-    if (getDiagnostics().getDiagnosticLevel(diag::warn_forgotten_module_header,
-                                            StartLoc)
-          != DiagnosticsEngine::Ignored) {
+    if (!getDiagnostics().isIgnored(diag::warn_forgotten_module_header,
+                                    StartLoc)) {
       ModuleMap &ModMap = getHeaderSearchInfo().getModuleMap();
       for (unsigned I = 0, N = SourceMgr.local_sloc_entry_size(); I != N; ++I) {
         // We only care about file entries.
@@ -498,7 +526,7 @@
   if (NumCachedTokenLexers == TokenLexerCacheSize)
     CurTokenLexer.reset();
   else
-    TokenLexerCache[NumCachedTokenLexers++] = CurTokenLexer.take();
+    TokenLexerCache[NumCachedTokenLexers++] = CurTokenLexer.release();
 
   // Handle this like a #include file being popped off the stack.
   return HandleEndOfFile(Result, true);
@@ -515,7 +543,7 @@
     if (NumCachedTokenLexers == TokenLexerCacheSize)
       CurTokenLexer.reset();
     else
-      TokenLexerCache[NumCachedTokenLexers++] = CurTokenLexer.take();
+      TokenLexerCache[NumCachedTokenLexers++] = CurTokenLexer.release();
   }
 
   PopIncludeMacroStack();
@@ -531,11 +559,11 @@
   // We handle this by scanning for the closest real lexer, switching it to
   // raw mode and preprocessor mode.  This will cause it to return \n as an
   // explicit EOD token.
-  PreprocessorLexer *FoundLexer = 0;
+  PreprocessorLexer *FoundLexer = nullptr;
   bool LexerWasInPPMode = false;
   for (unsigned i = 0, e = IncludeMacroStack.size(); i != e; ++i) {
     IncludeStackInfo &ISI = *(IncludeMacroStack.end()-i-1);
-    if (ISI.ThePPLexer == 0) continue;  // Scan for a real lexer.
+    if (ISI.ThePPLexer == nullptr) continue;  // Scan for a real lexer.
 
     // Once we find a real lexer, mark it as raw mode (disabling macro
     // expansions) and preprocessor mode (return EOD).  We know that the lexer
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index f20633f..2d7c6d4 100644
--- a/lib/Lex/PPMacroExpansion.cpp
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -7,19 +7,20 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This file implements the top level handling of macro expasion for the
+// This file implements the top level handling of macro expansion for the
 // preprocessor.
 //
 //===----------------------------------------------------------------------===//
 
 #include "clang/Lex/Preprocessor.h"
-#include "clang/Lex/MacroArgs.h"
+#include "clang/Basic/Attributes.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Lex/CodeCompletionHandler.h"
 #include "clang/Lex/ExternalPreprocessorSource.h"
 #include "clang/Lex/LexDiagnostic.h"
+#include "clang/Lex/MacroArgs.h"
 #include "clang/Lex/MacroInfo.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallString.h"
@@ -97,6 +98,15 @@
   Ident__INCLUDE_LEVEL__ = RegisterBuiltinMacro(*this, "__INCLUDE_LEVEL__");
   Ident__TIMESTAMP__     = RegisterBuiltinMacro(*this, "__TIMESTAMP__");
 
+  // Microsoft Extensions.
+  if (LangOpts.MicrosoftExt) {
+    Ident__identifier = RegisterBuiltinMacro(*this, "__identifier");
+    Ident__pragma = RegisterBuiltinMacro(*this, "__pragma");
+  } else {
+    Ident__identifier = nullptr;
+    Ident__pragma = nullptr;
+  }
+
   // Clang Extensions.
   Ident__has_feature      = RegisterBuiltinMacro(*this, "__has_feature");
   Ident__has_extension    = RegisterBuiltinMacro(*this, "__has_extension");
@@ -105,6 +115,7 @@
   Ident__has_include      = RegisterBuiltinMacro(*this, "__has_include");
   Ident__has_include_next = RegisterBuiltinMacro(*this, "__has_include_next");
   Ident__has_warning      = RegisterBuiltinMacro(*this, "__has_warning");
+  Ident__is_identifier    = RegisterBuiltinMacro(*this, "__is_identifier");
 
   // Modules.
   if (LangOpts.Modules) {
@@ -114,17 +125,11 @@
     if (!LangOpts.CurrentModule.empty())
       Ident__MODULE__ = RegisterBuiltinMacro(*this, "__MODULE__");
     else
-      Ident__MODULE__ = 0;
+      Ident__MODULE__ = nullptr;
   } else {
-    Ident__building_module = 0;
-    Ident__MODULE__ = 0;
+    Ident__building_module = nullptr;
+    Ident__MODULE__ = nullptr;
   }
-  
-  // Microsoft Extensions.
-  if (LangOpts.MicrosoftExt) 
-    Ident__pragma = RegisterBuiltinMacro(*this, "__pragma");
-  else
-    Ident__pragma = 0;
 }
 
 /// isTrivialSingleTokenExpansion - Return true if MI, which has a single token
@@ -135,7 +140,7 @@
   IdentifierInfo *II = MI->getReplacementToken(0).getIdentifierInfo();
 
   // If the token isn't an identifier, it's always literally expanded.
-  if (II == 0) return true;
+  if (!II) return true;
 
   // If the information about this identifier is out of date, update it from
   // the external source.
@@ -223,7 +228,8 @@
   // If this is a builtin macro, like __LINE__ or _Pragma, handle it specially.
   if (MI->isBuiltinMacro()) {
     if (Callbacks) Callbacks->MacroExpands(Identifier, MD,
-                                           Identifier.getLocation(),/*Args=*/0);
+                                           Identifier.getLocation(),
+                                           /*Args=*/nullptr);
     ExpandBuiltinMacro(Identifier);
     return true;
   }
@@ -231,7 +237,7 @@
   /// Args - If this is a function-like macro expansion, this contains,
   /// for each macro argument, the list of tokens that were provided to the
   /// invocation.
-  MacroArgs *Args = 0;
+  MacroArgs *Args = nullptr;
 
   // Remember where the end of the expansion occurred.  For an object-like
   // macro, this is the identifier.  For a function-like macro, this is the ')'.
@@ -249,7 +255,7 @@
     InMacroArgs = false;
 
     // If there was an error parsing the arguments, bail out.
-    if (Args == 0) return true;
+    if (!Args) return true;
 
     ++NumFnMacroExpanded;
   } else {
@@ -277,7 +283,8 @@
         for (unsigned i=0, e = DelayedMacroExpandsCallbacks.size(); i!=e; ++i) {
           MacroExpandsInfo &Info = DelayedMacroExpandsCallbacks[i];
           // FIXME: We lose macro args info with delayed callback.
-          Callbacks->MacroExpands(Info.Tok, Info.MD, Info.Range, /*Args=*/0);
+          Callbacks->MacroExpands(Info.Tok, Info.MD, Info.Range,
+                                  /*Args=*/nullptr);
         }
         DelayedMacroExpandsCallbacks.clear();
       }
@@ -293,11 +300,11 @@
     for (MacroDirective::DefInfo PrevDef = Def.getPreviousDefinition();
          PrevDef && !PrevDef.isUndefined();
          PrevDef = PrevDef.getPreviousDefinition()) {
-      if (PrevDef.getDirective()->isAmbiguous()) {
-        Diag(PrevDef.getMacroInfo()->getDefinitionLoc(),
-             diag::note_pp_ambiguous_macro_other)
-          << Identifier.getIdentifierInfo();
-      }
+      Diag(PrevDef.getMacroInfo()->getDefinitionLoc(),
+           diag::note_pp_ambiguous_macro_other)
+        << Identifier.getIdentifierInfo();
+      if (!PrevDef.getDirective()->isAmbiguous())
+        break;
     }
   }
 
@@ -552,7 +559,7 @@
             << MacroName.getIdentifierInfo();
           // Do not lose the EOF/EOD.  Return it to the client.
           MacroName = Tok;
-          return 0;
+          return nullptr;
         } else {
           // Do not lose the EOF/EOD.
           Token *Toks = new Token[1];
@@ -584,7 +591,7 @@
         // If this is a comment token in the argument list and we're just in
         // -C mode (not -CC mode), discard the comment.
         continue;
-      } else if (Tok.getIdentifierInfo() != 0) {
+      } else if (Tok.getIdentifierInfo() != nullptr) {
         // Reading macro arguments can cause macros that we are currently
         // expanding from to be popped off the expansion stack.  Doing so causes
         // them to be reenabled for expansion.  Here we record whether any
@@ -668,29 +675,18 @@
         DiagnosticBuilder DB =
             Diag(MacroName,
                  diag::note_init_list_at_beginning_of_macro_argument);
-        for (SmallVector<SourceRange, 4>::iterator
-                 Range = InitLists.begin(), RangeEnd = InitLists.end();
-                 Range != RangeEnd; ++Range) {
-          if (DB.hasMaxRanges())
-            break;
-          DB << *Range;
-        }
+        for (const SourceRange &Range : InitLists)
+          DB << Range;
       }
-      return 0;
+      return nullptr;
     }
     if (FixedNumArgs != MinArgsExpected)
-      return 0;
+      return nullptr;
 
     DiagnosticBuilder DB = Diag(MacroName, diag::note_suggest_parens_for_macro);
-    for (SmallVector<SourceRange, 4>::iterator
-             ParenLocation = ParenHints.begin(), ParenEnd = ParenHints.end();
-         ParenLocation != ParenEnd; ++ParenLocation) {
-      if (DB.hasMaxFixItHints())
-        break;
-      DB << FixItHint::CreateInsertion(ParenLocation->getBegin(), "(");
-      if (DB.hasMaxFixItHints())
-        break;
-      DB << FixItHint::CreateInsertion(ParenLocation->getEnd(), ")");
+    for (const SourceRange &ParenLocation : ParenHints) {
+      DB << FixItHint::CreateInsertion(ParenLocation.getBegin(), "(");
+      DB << FixItHint::CreateInsertion(ParenLocation.getEnd(), ")");
     }
     ArgTokens.swap(FixedArgTokens);
     NumActuals = FixedNumArgs;
@@ -746,7 +742,7 @@
       Diag(Tok, diag::err_too_few_args_in_macro_invoc);
       Diag(MI->getDefinitionLoc(), diag::note_macro_here)
         << MacroName.getIdentifierInfo();
-      return 0;
+      return nullptr;
     }
 
     // Add a marker EOF token to the end of the token list for this argument.
@@ -768,7 +764,7 @@
     Diag(MacroName, diag::err_too_many_args_in_macro_invoc);
     Diag(MI->getDefinitionLoc(), diag::note_macro_here)
       << MacroName.getIdentifierInfo();
-    return 0;
+    return nullptr;
   }
 
   return MacroArgs::create(MI, ArgTokens, isVarargsElided, *this);
@@ -783,7 +779,7 @@
                                               ArrayRef<Token> tokens) {
   assert(tokLexer);
   if (tokens.empty())
-    return 0;
+    return nullptr;
 
   size_t newIndex = MacroExpandedTokens.size();
   bool cacheNeedsToGrow = tokens.size() >
@@ -796,7 +792,7 @@
     for (unsigned i = 0, e = MacroExpandingLexersStack.size(); i != e; ++i) {
       TokenLexer *prevLexer;
       size_t tokIndex;
-      llvm::tie(prevLexer, tokIndex) = MacroExpandingLexersStack[i];
+      std::tie(prevLexer, tokIndex) = MacroExpandingLexersStack[i];
       prevLexer->Tokens = MacroExpandedTokens.data() + tokIndex;
     }
   }
@@ -819,7 +815,7 @@
 /// the identifier tokens inserted.
 static void ComputeDATE_TIME(SourceLocation &DATELoc, SourceLocation &TIMELoc,
                              Preprocessor &PP) {
-  time_t TT = time(0);
+  time_t TT = time(nullptr);
   struct tm *TM = localtime(&TT);
 
   static const char * const Months[] = {
@@ -881,7 +877,7 @@
            .Case("attribute_unused_on_fields", true)
            .Case("blocks", LangOpts.Blocks)
            .Case("c_thread_safety_attributes", true)
-           .Case("cxx_exceptions", LangOpts.Exceptions)
+           .Case("cxx_exceptions", LangOpts.CXXExceptions)
            .Case("cxx_rtti", LangOpts.RTTI)
            .Case("enumerator_attributes", true)
            .Case("memory_sanitizer", LangOpts.Sanitize.Memory)
@@ -913,7 +909,7 @@
            .Case("c_atomic", LangOpts.C11)
            .Case("c_generic_selections", LangOpts.C11)
            .Case("c_static_assert", LangOpts.C11)
-           .Case("c_thread_local", 
+           .Case("c_thread_local",
                  LangOpts.C11 && PP.getTargetInfo().isTLSSupported())
            // C++11 features
            .Case("cxx_access_control_sfinae", LangOpts.CPlusPlus11)
@@ -957,12 +953,17 @@
            .Case("cxx_aggregate_nsdmi", LangOpts.CPlusPlus1y)
            .Case("cxx_binary_literals", LangOpts.CPlusPlus1y)
            .Case("cxx_contextual_conversions", LangOpts.CPlusPlus1y)
-           //.Case("cxx_generic_lambdas", LangOpts.CPlusPlus1y)
+           .Case("cxx_decltype_auto", LangOpts.CPlusPlus1y)
+           .Case("cxx_generic_lambdas", LangOpts.CPlusPlus1y)
            .Case("cxx_init_captures", LangOpts.CPlusPlus1y)
            .Case("cxx_relaxed_constexpr", LangOpts.CPlusPlus1y)
            .Case("cxx_return_type_deduction", LangOpts.CPlusPlus1y)
-           //.Case("cxx_runtime_arrays", LangOpts.CPlusPlus1y)
            .Case("cxx_variable_templates", LangOpts.CPlusPlus1y)
+           // C++ TSes
+           //.Case("cxx_runtime_arrays", LangOpts.CPlusPlusTSArrays)
+           //.Case("cxx_concepts", LangOpts.CPlusPlusTSConcepts)
+           // FIXME: Should this be __has_feature or __has_extension?
+           //.Case("raw_invocation_type", LangOpts.CPlusPlus)
            // Type traits
            .Case("has_nothrow_assign", LangOpts.CPlusPlus)
            .Case("has_nothrow_copy", LangOpts.CPlusPlus)
@@ -975,6 +976,7 @@
            .Case("is_abstract", LangOpts.CPlusPlus)
            .Case("is_base_of", LangOpts.CPlusPlus)
            .Case("is_class", LangOpts.CPlusPlus)
+           .Case("is_constructible", LangOpts.CPlusPlus)
            .Case("is_convertible_to", LangOpts.CPlusPlus)
            .Case("is_empty", LangOpts.CPlusPlus)
            .Case("is_enum", LangOpts.CPlusPlus)
@@ -1004,8 +1006,8 @@
 
   // If the use of an extension results in an error diagnostic, extensions are
   // effectively unavailable, so just return false here.
-  if (PP.getDiagnostics().getExtensionHandlingBehavior() ==
-      DiagnosticsEngine::Ext_Error)
+  if (PP.getDiagnostics().getExtensionHandlingBehavior() >=
+      diag::Severity::Error)
     return false;
 
   const LangOptions &LangOpts = PP.getLangOpts();
@@ -1039,24 +1041,10 @@
            // C++1y features supported by other languages as extensions.
            .Case("cxx_binary_literals", true)
            .Case("cxx_init_captures", LangOpts.CPlusPlus11)
-           .Case("cxx_variable_templates", true)
+           .Case("cxx_variable_templates", LangOpts.CPlusPlus)
            .Default(false);
 }
 
-/// HasAttribute -  Return true if we recognize and implement the attribute
-/// specified by the given identifier.
-static bool HasAttribute(const IdentifierInfo *II) {
-  StringRef Name = II->getName();
-  // Normalize the attribute name, __foo__ becomes foo.
-  if (Name.startswith("__") && Name.endswith("__") && Name.size() >= 4)
-    Name = Name.substr(2, Name.size() - 4);
-
-  // FIXME: Do we need to handle namespaces here?
-  return llvm::StringSwitch<bool>(Name)
-#include "clang/Lex/AttrSpellings.inc"
-        .Default(false);
-}
-
 /// EvaluateHasIncludeCommon - Process a '__has_include("path")'
 /// or '__has_include_next("path")' expression.
 /// Returns true if successful.
@@ -1080,7 +1068,7 @@
   if (Tok.isNot(tok::l_paren)) {
     // No '(', use end of last token.
     LParenLoc = PP.getLocForEndOfToken(LParenLoc);
-    PP.Diag(LParenLoc, diag::err_pp_missing_lparen) << II->getName();
+    PP.Diag(LParenLoc, diag::err_pp_expected_after) << II << tok::l_paren;
     // If the next token looks like a filename or the start of one,
     // assume it is and process it as such.
     if (!Tok.is(tok::angle_string_literal) && !Tok.is(tok::string_literal) &&
@@ -1142,9 +1130,9 @@
 
   // Ensure we have a trailing ).
   if (Tok.isNot(tok::r_paren)) {
-    PP.Diag(PP.getLocForEndOfToken(FilenameLoc), diag::err_pp_missing_rparen)
-        << II->getName();
-    PP.Diag(LParenLoc, diag::note_matching) << "(";
+    PP.Diag(PP.getLocForEndOfToken(FilenameLoc), diag::err_pp_expected_after)
+        << II << tok::r_paren;
+    PP.Diag(LParenLoc, diag::note_matching) << tok::l_paren;
     return false;
   }
 
@@ -1157,18 +1145,18 @@
   // Search include directories.
   const DirectoryLookup *CurDir;
   const FileEntry *File =
-      PP.LookupFile(FilenameLoc, Filename, isAngled, LookupFrom, CurDir, NULL,
-                    NULL, NULL);
+      PP.LookupFile(FilenameLoc, Filename, isAngled, LookupFrom, CurDir,
+                    nullptr, nullptr, nullptr);
 
   // Get the result value.  A result of true means the file exists.
-  return File != 0;
+  return File != nullptr;
 }
 
 /// EvaluateHasInclude - Process a '__has_include("path")' expression.
 /// Returns true if successful.
 static bool EvaluateHasInclude(Token &Tok, IdentifierInfo *II,
                                Preprocessor &PP) {
-  return EvaluateHasIncludeCommon(Tok, II, PP, NULL);
+  return EvaluateHasIncludeCommon(Tok, II, PP, nullptr);
 }
 
 /// EvaluateHasIncludeNext - Process '__has_include_next("path")' expression.
@@ -1180,9 +1168,9 @@
   // issue a diagnostic.
   const DirectoryLookup *Lookup = PP.GetCurDirLookup();
   if (PP.isInPrimaryFile()) {
-    Lookup = 0;
+    Lookup = nullptr;
     PP.Diag(Tok, diag::pp_include_next_in_primary);
-  } else if (Lookup == 0) {
+  } else if (!Lookup) {
     PP.Diag(Tok, diag::pp_include_next_absolute_path);
   } else {
     // Start looking up in the next directory.
@@ -1201,7 +1189,8 @@
 
   // Ensure we have a '('.
   if (Tok.isNot(tok::l_paren)) {
-    PP.Diag(Tok.getLocation(), diag::err_pp_missing_lparen) << II->getName();
+    PP.Diag(Tok.getLocation(), diag::err_pp_expected_after) << II
+                                                            << tok::l_paren;
     return false;
   }
 
@@ -1225,8 +1214,9 @@
 
   // Ensure we have a trailing ).
   if (Tok.isNot(tok::r_paren)) {
-    PP.Diag(Tok.getLocation(), diag::err_pp_missing_rparen) << II->getName();
-    PP.Diag(LParenLoc, diag::note_matching) << "(";
+    PP.Diag(Tok.getLocation(), diag::err_pp_expected_after) << II
+                                                            << tok::r_paren;
+    PP.Diag(LParenLoc, diag::note_matching) << tok::l_paren;
     return false;
   }
 
@@ -1253,7 +1243,7 @@
   llvm::raw_svector_ostream OS(TmpBuffer);
 
   // Set up the return result.
-  Tok.setIdentifierInfo(0);
+  Tok.setIdentifierInfo(nullptr);
   Tok.clearFlag(Token::NeedsCleaning);
 
   if (II == Ident__LINE__) {
@@ -1304,6 +1294,7 @@
     }
     Tok.setKind(tok::string_literal);
   } else if (II == Ident__DATE__) {
+    Diag(Tok.getLocation(), diag::warn_pp_date_time);
     if (!DATELoc.isValid())
       ComputeDATE_TIME(DATELoc, TIMELoc, *this);
     Tok.setKind(tok::string_literal);
@@ -1313,6 +1304,7 @@
                                                  Tok.getLength()));
     return;
   } else if (II == Ident__TIME__) {
+    Diag(Tok.getLocation(), diag::warn_pp_date_time);
     if (!TIMELoc.isValid())
       ComputeDATE_TIME(DATELoc, TIMELoc, *this);
     Tok.setKind(tok::string_literal);
@@ -1337,12 +1329,13 @@
     OS << Depth;
     Tok.setKind(tok::numeric_constant);
   } else if (II == Ident__TIMESTAMP__) {
+    Diag(Tok.getLocation(), diag::warn_pp_date_time);
     // MSVC, ICC, GCC, VisualAge C++ extension.  The generated string should be
     // of the form "Ddd Mmm dd hh::mm::ss yyyy", which is returned by asctime.
 
     // Get the file that we are lexing out of.  If we're currently lexing from
     // a macro, dig into the include stack.
-    const FileEntry *CurFile = 0;
+    const FileEntry *CurFile = nullptr;
     PreprocessorLexer *TheLexer = getCurrentFileLexer();
 
     if (TheLexer)
@@ -1357,7 +1350,7 @@
       Result = "??? ??? ?? ??:??:?? ????\n";
     }
     // Surround the string with " and strip the trailing newline.
-    OS << '"' << StringRef(Result, strlen(Result)-1) << '"';
+    OS << '"' << StringRef(Result).drop_back() << '"';
     Tok.setKind(tok::string_literal);
   } else if (II == Ident__COUNTER__) {
     // __COUNTER__ expands to a simple numeric value.
@@ -1366,12 +1359,13 @@
   } else if (II == Ident__has_feature   ||
              II == Ident__has_extension ||
              II == Ident__has_builtin   ||
+             II == Ident__is_identifier ||
              II == Ident__has_attribute) {
     // The argument to these builtins should be a parenthesized identifier.
     SourceLocation StartLoc = Tok.getLocation();
 
     bool IsValid = false;
-    IdentifierInfo *FeatureII = 0;
+    IdentifierInfo *FeatureII = nullptr;
 
     // Read the '('.
     LexUnexpandedToken(Tok);
@@ -1389,11 +1383,14 @@
     bool Value = false;
     if (!IsValid)
       Diag(StartLoc, diag::err_feature_check_malformed);
+    else if (II == Ident__is_identifier)
+      Value = FeatureII->getTokenID() == tok::identifier;
     else if (II == Ident__has_builtin) {
       // Check for a builtin is trivial.
       Value = FeatureII->getBuiltinID() != 0;
     } else if (II == Ident__has_attribute)
-      Value = HasAttribute(FeatureII);
+      Value = hasAttribute(AttrSyntax::Generic, nullptr, FeatureII,
+                           getTargetInfo().getTriple(), getLangOpts());
     else if (II == Ident__has_extension)
       Value = HasExtension(*this, FeatureII);
     else {
@@ -1449,6 +1446,8 @@
         break;
       }
 
+      // FIXME: Should we accept "-R..." flags here, or should that be handled
+      // by a separate __has_remark?
       if (WarningName.size() < 3 || WarningName[0] != '-' ||
           WarningName[1] != 'W') {
         Diag(StrStartLoc, diag::warn_has_warning_invalid_option);
@@ -1461,7 +1460,8 @@
       // worth special casing.
       SmallVector<diag::kind, 10> Diags;
       Value = !getDiagnostics().getDiagnosticIDs()->
-        getDiagnosticsInGroup(WarningName.substr(2), Diags);
+        getDiagnosticsInGroup(diag::Flavor::WarningOrError,
+                              WarningName.substr(2), Diags);
     } while (false);
 
     OS << (int)Value;
@@ -1479,6 +1479,44 @@
     IdentifierInfo *ModuleII = getIdentifierInfo(getLangOpts().CurrentModule);
     Tok.setIdentifierInfo(ModuleII);
     Tok.setKind(ModuleII->getTokenID());
+  } else if (II == Ident__identifier) {
+    SourceLocation Loc = Tok.getLocation();
+
+    // We're expecting '__identifier' '(' identifier ')'. Try to recover
+    // if the parens are missing.
+    LexNonComment(Tok);
+    if (Tok.isNot(tok::l_paren)) {
+      // No '(', use end of last token.
+      Diag(getLocForEndOfToken(Loc), diag::err_pp_expected_after)
+        << II << tok::l_paren;
+      // If the next token isn't valid as our argument, we can't recover.
+      if (!Tok.isAnnotation() && Tok.getIdentifierInfo())
+        Tok.setKind(tok::identifier);
+      return;
+    }
+
+    SourceLocation LParenLoc = Tok.getLocation();
+    LexNonComment(Tok);
+
+    if (!Tok.isAnnotation() && Tok.getIdentifierInfo())
+      Tok.setKind(tok::identifier);
+    else {
+      Diag(Tok.getLocation(), diag::err_pp_identifier_arg_not_identifier)
+        << Tok.getKind();
+      // Don't walk past anything that's not a real token.
+      if (Tok.is(tok::eof) || Tok.is(tok::eod) || Tok.isAnnotation())
+        return;
+    }
+
+    // Discard the ')', preserving 'Tok' as our result.
+    Token RParen;
+    LexNonComment(RParen);
+    if (RParen.isNot(tok::r_paren)) {
+      Diag(getLocForEndOfToken(Tok.getLocation()), diag::err_pp_expected_after)
+        << Tok.getKind() << tok::r_paren;
+      Diag(LParenLoc, diag::note_matching) << tok::l_paren;
+    }
+    return;
   } else {
     llvm_unreachable("Unknown identifier!");
   }
diff --git a/lib/Lex/PTHLexer.cpp b/lib/Lex/PTHLexer.cpp
index e2629a3..fce31c4 100644
--- a/lib/Lex/PTHLexer.cpp
+++ b/lib/Lex/PTHLexer.cpp
@@ -15,21 +15,21 @@
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/FileSystemStatCache.h"
 #include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/OnDiskHashTable.h"
 #include "clang/Basic/TokenKinds.h"
 #include "clang/Lex/LexDiagnostic.h"
 #include "clang/Lex/PTHManager.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Lex/Token.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringMap.h"
+#include "llvm/Support/EndianStream.h"
 #include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/system_error.h"
+#include "llvm/Support/OnDiskHashTable.h"
+#include <memory>
+#include <system_error>
 using namespace clang;
-using namespace clang::io;
 
-#define DISK_TOKEN_SIZE (1+1+2+4+4)
+static const unsigned StoredTokenSize = 1 + 1 + 2 + 4 + 4;
 
 //===----------------------------------------------------------------------===//
 // PTHLexer methods.
@@ -37,7 +37,7 @@
 
 PTHLexer::PTHLexer(Preprocessor &PP, FileID FID, const unsigned char *D,
                    const unsigned char *ppcond, PTHManager &PM)
-  : PreprocessorLexer(&PP, FID), TokBuf(D), CurPtr(D), LastHashTokPtr(0),
+  : PreprocessorLexer(&PP, FID), TokBuf(D), CurPtr(D), LastHashTokPtr(nullptr),
     PPCond(ppcond), CurPPCondPtr(ppcond), PTHMgr(PM) {
 
   FileStartLoc = PP.getSourceManager().getLocForStartOfFile(FID);
@@ -47,14 +47,17 @@
   //===--------------------------------------==//
   // Read the raw token data.
   //===--------------------------------------==//
+  using namespace llvm::support;
 
   // Shadow CurPtr into an automatic variable.
   const unsigned char *CurPtrShadow = CurPtr;
 
   // Read in the data for the token.
-  unsigned Word0 = ReadLE32(CurPtrShadow);
-  uint32_t IdentifierID = ReadLE32(CurPtrShadow);
-  uint32_t FileOffset = ReadLE32(CurPtrShadow);
+  unsigned Word0 = endian::readNext<uint32_t, little, aligned>(CurPtrShadow);
+  uint32_t IdentifierID =
+      endian::readNext<uint32_t, little, aligned>(CurPtrShadow);
+  uint32_t FileOffset =
+      endian::readNext<uint32_t, little, aligned>(CurPtrShadow);
 
   tok::TokenKind TKind = (tok::TokenKind) (Word0 & 0xFF);
   Token::TokenFlags TFlags = (Token::TokenFlags) ((Word0 >> 8) & 0xFF);
@@ -107,7 +110,7 @@
   }
 
   if (TKind == tok::hash && Tok.isAtStartOfLine()) {
-    LastHashTokPtr = CurPtr - DISK_TOKEN_SIZE;
+    LastHashTokPtr = CurPtr - StoredTokenSize;
     assert(!LexingRawMode);
     PP->HandleDirective(Tok);
 
@@ -176,7 +179,7 @@
     if (y & Token::StartOfLine) break;
 
     // Skip to the next token.
-    p += DISK_TOKEN_SIZE;
+    p += StoredTokenSize;
   }
 
   CurPtr = p;
@@ -184,18 +187,19 @@
 
 /// SkipBlock - Used by Preprocessor to skip the current conditional block.
 bool PTHLexer::SkipBlock() {
+  using namespace llvm::support;
   assert(CurPPCondPtr && "No cached PP conditional information.");
   assert(LastHashTokPtr && "No known '#' token.");
 
-  const unsigned char* HashEntryI = 0;
+  const unsigned char *HashEntryI = nullptr;
   uint32_t TableIdx;
 
   do {
     // Read the token offset from the side-table.
-    uint32_t Offset = ReadLE32(CurPPCondPtr);
+    uint32_t Offset = endian::readNext<uint32_t, little, aligned>(CurPPCondPtr);
 
     // Read the target table index from the side-table.
-    TableIdx = ReadLE32(CurPPCondPtr);
+    TableIdx = endian::readNext<uint32_t, little, aligned>(CurPPCondPtr);
 
     // Compute the actual memory address of the '#' token data for this entry.
     HashEntryI = TokBuf + Offset;
@@ -212,12 +216,13 @@
         PPCond + TableIdx*(sizeof(uint32_t)*2);
       assert(NextPPCondPtr >= CurPPCondPtr);
       // Read where we should jump to.
-      const unsigned char* HashEntryJ = TokBuf + ReadLE32(NextPPCondPtr);
+      const unsigned char *HashEntryJ =
+          TokBuf + endian::readNext<uint32_t, little, aligned>(NextPPCondPtr);
 
       if (HashEntryJ <= LastHashTokPtr) {
         // Jump directly to the next entry in the side table.
         HashEntryI = HashEntryJ;
-        TableIdx = ReadLE32(NextPPCondPtr);
+        TableIdx = endian::readNext<uint32_t, little, aligned>(NextPPCondPtr);
         CurPPCondPtr = NextPPCondPtr;
       }
     }
@@ -232,8 +237,9 @@
   CurPPCondPtr = NextPPCondPtr;
 
   // Read where we should jump to.
-  HashEntryI = TokBuf + ReadLE32(NextPPCondPtr);
-  uint32_t NextIdx = ReadLE32(NextPPCondPtr);
+  HashEntryI =
+      TokBuf + endian::readNext<uint32_t, little, aligned>(NextPPCondPtr);
+  uint32_t NextIdx = endian::readNext<uint32_t, little, aligned>(NextPPCondPtr);
 
   // By construction NextIdx will be zero if this is a #endif.  This is useful
   // to know to obviate lexing another token.
@@ -249,10 +255,10 @@
   // already points 'elif'.  Just return.
 
   if (CurPtr > HashEntryI) {
-    assert(CurPtr == HashEntryI + DISK_TOKEN_SIZE);
+    assert(CurPtr == HashEntryI + StoredTokenSize);
     // Did we reach a #endif?  If so, go ahead and consume that token as well.
     if (isEndif)
-      CurPtr += DISK_TOKEN_SIZE*2;
+      CurPtr += StoredTokenSize * 2;
     else
       LastHashTokPtr = HashEntryI;
 
@@ -268,10 +274,12 @@
 
   // Skip the '#' token.
   assert(((tok::TokenKind)*CurPtr) == tok::hash);
-  CurPtr += DISK_TOKEN_SIZE;
+  CurPtr += StoredTokenSize;
 
   // Did we reach a #endif?  If so, go ahead and consume that token as well.
-  if (isEndif) { CurPtr += DISK_TOKEN_SIZE*2; }
+  if (isEndif) {
+    CurPtr += StoredTokenSize * 2;
+  }
 
   return isEndif;
 }
@@ -282,8 +290,10 @@
   // handling a #included file.  Just read the necessary data from the token
   // data buffer to construct the SourceLocation object.
   // NOTE: This is a virtual function; hence it is defined out-of-line.
-  const unsigned char *OffsetPtr = CurPtr + (DISK_TOKEN_SIZE - 4);
-  uint32_t Offset = ReadLE32(OffsetPtr);
+  using namespace llvm::support;
+
+  const unsigned char *OffsetPtr = CurPtr + (StoredTokenSize - 4);
+  uint32_t Offset = endian::readNext<uint32_t, little, aligned>(OffsetPtr);
   return FileStartLoc.getLocWithOffset(Offset);
 }
 
@@ -310,14 +320,18 @@
 class PTHFileLookupCommonTrait {
 public:
   typedef std::pair<unsigned char, const char*> internal_key_type;
+  typedef unsigned hash_value_type;
+  typedef unsigned offset_type;
 
-  static unsigned ComputeHash(internal_key_type x) {
+  static hash_value_type ComputeHash(internal_key_type x) {
     return llvm::HashString(x.second);
   }
 
   static std::pair<unsigned, unsigned>
   ReadKeyDataLength(const unsigned char*& d) {
-    unsigned keyLen = (unsigned) ReadUnalignedLE16(d);
+    using namespace llvm::support;
+    unsigned keyLen =
+        (unsigned)endian::readNext<uint16_t, little, unaligned>(d);
     unsigned dataLen = (unsigned) *(d++);
     return std::make_pair(keyLen, dataLen);
   }
@@ -344,21 +358,20 @@
   static PTHFileData ReadData(const internal_key_type& k,
                               const unsigned char* d, unsigned) {
     assert(k.first == 0x1 && "Only file lookups can match!");
-    uint32_t x = ::ReadUnalignedLE32(d);
-    uint32_t y = ::ReadUnalignedLE32(d);
+    using namespace llvm::support;
+    uint32_t x = endian::readNext<uint32_t, little, unaligned>(d);
+    uint32_t y = endian::readNext<uint32_t, little, unaligned>(d);
     return PTHFileData(x, y);
   }
 };
 
 class PTHStringLookupTrait {
 public:
-  typedef uint32_t
-          data_type;
-
-  typedef const std::pair<const char*, unsigned>
-          external_key_type;
-
+  typedef uint32_t data_type;
+  typedef const std::pair<const char*, unsigned> external_key_type;
   typedef external_key_type internal_key_type;
+  typedef uint32_t hash_value_type;
+  typedef unsigned offset_type;
 
   static bool EqualKey(const internal_key_type& a,
                        const internal_key_type& b) {
@@ -366,7 +379,7 @@
                                   : false;
   }
 
-  static unsigned ComputeHash(const internal_key_type& a) {
+  static hash_value_type ComputeHash(const internal_key_type& a) {
     return llvm::HashString(StringRef(a.first, a.second));
   }
 
@@ -376,7 +389,10 @@
 
   static std::pair<unsigned, unsigned>
   ReadKeyDataLength(const unsigned char*& d) {
-    return std::make_pair((unsigned) ReadUnalignedLE16(d), sizeof(uint32_t));
+    using namespace llvm::support;
+    return std::make_pair(
+        (unsigned)endian::readNext<uint16_t, little, unaligned>(d),
+        sizeof(uint32_t));
   }
 
   static std::pair<const char*, unsigned>
@@ -387,14 +403,15 @@
 
   static uint32_t ReadData(const internal_key_type& k, const unsigned char* d,
                            unsigned) {
-    return ::ReadUnalignedLE32(d);
+    using namespace llvm::support;
+    return endian::readNext<uint32_t, little, unaligned>(d);
   }
 };
 
 } // end anonymous namespace
 
-typedef OnDiskChainedHashTable<PTHFileLookupTrait>   PTHFileLookup;
-typedef OnDiskChainedHashTable<PTHStringLookupTrait> PTHStringIdLookup;
+typedef llvm::OnDiskChainedHashTable<PTHFileLookupTrait>   PTHFileLookup;
+typedef llvm::OnDiskChainedHashTable<PTHStringLookupTrait> PTHStringIdLookup;
 
 //===----------------------------------------------------------------------===//
 // PTHManager methods.
@@ -408,7 +425,7 @@
                        const char* originalSourceFile)
 : Buf(buf), PerIDCache(perIDCache), FileLookup(fileLookup),
   IdDataTable(idDataTable), StringIdLookup(stringIdLookup),
-  NumIds(numIds), PP(0), SpellingBase(spellingBase),
+  NumIds(numIds), PP(nullptr), SpellingBase(spellingBase),
   OriginalSourceFile(originalSourceFile) {}
 
 PTHManager::~PTHManager() {
@@ -419,19 +436,23 @@
 }
 
 static void InvalidPTH(DiagnosticsEngine &Diags, const char *Msg) {
-  Diags.Report(Diags.getCustomDiagID(DiagnosticsEngine::Error, Msg));
+  Diags.Report(Diags.getCustomDiagID(DiagnosticsEngine::Error, "%0")) << Msg;
 }
 
 PTHManager *PTHManager::Create(const std::string &file,
                                DiagnosticsEngine &Diags) {
   // Memory map the PTH file.
-  OwningPtr<llvm::MemoryBuffer> File;
+  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileOrErr =
+      llvm::MemoryBuffer::getFile(file);
 
-  if (llvm::MemoryBuffer::getFile(file, File)) {
+  if (!FileOrErr) {
     // FIXME: Add ec.message() to this diag.
     Diags.Report(diag::err_invalid_pth_file) << file;
-    return 0;
+    return nullptr;
   }
+  std::unique_ptr<llvm::MemoryBuffer> File = std::move(FileOrErr.get());
+
+  using namespace llvm::support;
 
   // Get the buffer ranges and check if there are at least three 32-bit
   // words at the end of the file.
@@ -442,19 +463,19 @@
   if ((BufEnd - BufBeg) < (signed)(sizeof("cfe-pth") + 4 + 4) ||
       memcmp(BufBeg, "cfe-pth", sizeof("cfe-pth")) != 0) {
     Diags.Report(diag::err_invalid_pth_file) << file;
-    return 0;
+    return nullptr;
   }
 
   // Read the PTH version.
   const unsigned char *p = BufBeg + (sizeof("cfe-pth"));
-  unsigned Version = ReadLE32(p);
+  unsigned Version = endian::readNext<uint32_t, little, aligned>(p);
 
   if (Version < PTHManager::Version) {
     InvalidPTH(Diags,
         Version < PTHManager::Version
         ? "PTH file uses an older PTH format that is no longer supported"
         : "PTH file uses a newer PTH format that cannot be read");
-    return 0;
+    return nullptr;
   }
 
   // Compute the address of the index table at the end of the PTH file.
@@ -462,20 +483,21 @@
 
   if (PrologueOffset >= BufEnd) {
     Diags.Report(diag::err_invalid_pth_file) << file;
-    return 0;
+    return nullptr;
   }
 
   // Construct the file lookup table.  This will be used for mapping from
   // FileEntry*'s to cached tokens.
   const unsigned char* FileTableOffset = PrologueOffset + sizeof(uint32_t)*2;
-  const unsigned char* FileTable = BufBeg + ReadLE32(FileTableOffset);
+  const unsigned char *FileTable =
+      BufBeg + endian::readNext<uint32_t, little, aligned>(FileTableOffset);
 
   if (!(FileTable > BufBeg && FileTable < BufEnd)) {
     Diags.Report(diag::err_invalid_pth_file) << file;
-    return 0; // FIXME: Proper error diagnostic?
+    return nullptr; // FIXME: Proper error diagnostic?
   }
 
-  OwningPtr<PTHFileLookup> FL(PTHFileLookup::Create(FileTable, BufBeg));
+  std::unique_ptr<PTHFileLookup> FL(PTHFileLookup::Create(FileTable, BufBeg));
 
   // Warn if the PTH file is empty.  We still want to create a PTHManager
   // as the PTH could be used with -include-pth.
@@ -485,65 +507,71 @@
   // Get the location of the table mapping from persistent ids to the
   // data needed to reconstruct identifiers.
   const unsigned char* IDTableOffset = PrologueOffset + sizeof(uint32_t)*0;
-  const unsigned char* IData = BufBeg + ReadLE32(IDTableOffset);
+  const unsigned char *IData =
+      BufBeg + endian::readNext<uint32_t, little, aligned>(IDTableOffset);
 
   if (!(IData >= BufBeg && IData < BufEnd)) {
     Diags.Report(diag::err_invalid_pth_file) << file;
-    return 0;
+    return nullptr;
   }
 
   // Get the location of the hashtable mapping between strings and
   // persistent IDs.
   const unsigned char* StringIdTableOffset = PrologueOffset + sizeof(uint32_t)*1;
-  const unsigned char* StringIdTable = BufBeg + ReadLE32(StringIdTableOffset);
+  const unsigned char *StringIdTable =
+      BufBeg + endian::readNext<uint32_t, little, aligned>(StringIdTableOffset);
   if (!(StringIdTable >= BufBeg && StringIdTable < BufEnd)) {
     Diags.Report(diag::err_invalid_pth_file) << file;
-    return 0;
+    return nullptr;
   }
 
-  OwningPtr<PTHStringIdLookup> SL(PTHStringIdLookup::Create(StringIdTable,
-                                                                  BufBeg));
+  std::unique_ptr<PTHStringIdLookup> SL(
+      PTHStringIdLookup::Create(StringIdTable, BufBeg));
 
   // Get the location of the spelling cache.
   const unsigned char* spellingBaseOffset = PrologueOffset + sizeof(uint32_t)*3;
-  const unsigned char* spellingBase = BufBeg + ReadLE32(spellingBaseOffset);
+  const unsigned char *spellingBase =
+      BufBeg + endian::readNext<uint32_t, little, aligned>(spellingBaseOffset);
   if (!(spellingBase >= BufBeg && spellingBase < BufEnd)) {
     Diags.Report(diag::err_invalid_pth_file) << file;
-    return 0;
+    return nullptr;
   }
 
   // Get the number of IdentifierInfos and pre-allocate the identifier cache.
-  uint32_t NumIds = ReadLE32(IData);
+  uint32_t NumIds = endian::readNext<uint32_t, little, aligned>(IData);
 
   // Pre-allocate the persistent ID -> IdentifierInfo* cache.  We use calloc()
   // so that we in the best case only zero out memory once when the OS returns
   // us new pages.
-  IdentifierInfo** PerIDCache = 0;
+  IdentifierInfo **PerIDCache = nullptr;
 
   if (NumIds) {
     PerIDCache = (IdentifierInfo**)calloc(NumIds, sizeof(*PerIDCache));
     if (!PerIDCache) {
       InvalidPTH(Diags, "Could not allocate memory for processing PTH file");
-      return 0;
+      return nullptr;
     }
   }
 
   // Compute the address of the original source file.
   const unsigned char* originalSourceBase = PrologueOffset + sizeof(uint32_t)*4;
-  unsigned len = ReadUnalignedLE16(originalSourceBase);
-  if (!len) originalSourceBase = 0;
+  unsigned len =
+      endian::readNext<uint16_t, little, unaligned>(originalSourceBase);
+  if (!len) originalSourceBase = nullptr;
 
   // Create the new PTHManager.
-  return new PTHManager(File.take(), FL.take(), IData, PerIDCache,
-                        SL.take(), NumIds, spellingBase,
-                        (const char*) originalSourceBase);
+  return new PTHManager(File.release(), FL.release(), IData, PerIDCache,
+                        SL.release(), NumIds, spellingBase,
+                        (const char *)originalSourceBase);
 }
 
 IdentifierInfo* PTHManager::LazilyCreateIdentifierInfo(unsigned PersistentID) {
+  using namespace llvm::support;
   // Look in the PTH file for the string data for the IdentifierInfo object.
   const unsigned char* TableEntry = IdDataTable + sizeof(uint32_t)*PersistentID;
-  const unsigned char* IDData =
-    (const unsigned char*)Buf->getBufferStart() + ReadLE32(TableEntry);
+  const unsigned char *IDData =
+      (const unsigned char *)Buf->getBufferStart() +
+      endian::readNext<uint32_t, little, aligned>(TableEntry);
   assert(IDData < (const unsigned char*)Buf->getBufferEnd());
 
   // Allocate the object.
@@ -567,7 +595,7 @@
   PTHStringIdLookup::iterator I = SL.find(std::make_pair(Name.data(),
                                                          Name.size()));
   if (I == SL.end()) // No identifier found?
-    return 0;
+    return nullptr;
 
   // Match found.  Return the identifier!
   assert(*I > 0);
@@ -577,7 +605,9 @@
 PTHLexer *PTHManager::CreateLexer(FileID FID) {
   const FileEntry *FE = PP->getSourceManager().getFileEntryForID(FID);
   if (!FE)
-    return 0;
+    return nullptr;
+
+  using namespace llvm::support;
 
   // Lookup the FileEntry object in our file lookup data structure.  It will
   // return a variant that indicates whether or not there is an offset within
@@ -586,7 +616,7 @@
   PTHFileLookup::iterator I = PFL.find(FE);
 
   if (I == PFL.end()) // No tokens available?
-    return 0;
+    return nullptr;
 
   const PTHFileData& FileData = *I;
 
@@ -596,8 +626,8 @@
 
   // Get the location of pp-conditional table.
   const unsigned char* ppcond = BufStart + FileData.getPPCondOffset();
-  uint32_t Len = ReadLE32(ppcond);
-  if (Len == 0) ppcond = 0;
+  uint32_t Len = endian::readNext<uint32_t, little, aligned>(ppcond);
+  if (Len == 0) ppcond = nullptr;
 
   assert(PP && "No preprocessor set yet!");
   return new PTHLexer(*PP, FID, data, ppcond, *this);
@@ -650,11 +680,13 @@
         d += 4 * 2; // Skip the first 2 words.
       }
 
-      uint64_t File = ReadUnalignedLE64(d);
-      uint64_t Device = ReadUnalignedLE64(d);
+      using namespace llvm::support;
+
+      uint64_t File = endian::readNext<uint64_t, little, unaligned>(d);
+      uint64_t Device = endian::readNext<uint64_t, little, unaligned>(d);
       llvm::sys::fs::UniqueID UniqueID(File, Device);
-      time_t ModTime = ReadUnalignedLE64(d);
-      uint64_t Size = ReadUnalignedLE64(d);
+      time_t ModTime = endian::readNext<uint64_t, little, unaligned>(d);
+      uint64_t Size = endian::readNext<uint64_t, little, unaligned>(d);
       return data_type(Size, ModTime, UniqueID, IsDirectory);
     }
 
@@ -664,7 +696,7 @@
 };
 
 class PTHStatCache : public FileSystemStatCache {
-  typedef OnDiskChainedHashTable<PTHStatLookupTrait> CacheTy;
+  typedef llvm::OnDiskChainedHashTable<PTHStatLookupTrait> CacheTy;
   CacheTy Cache;
 
 public:
@@ -672,22 +704,22 @@
     Cache(FL.getNumBuckets(), FL.getNumEntries(), FL.getBuckets(),
           FL.getBase()) {}
 
-  ~PTHStatCache() {}
-
   LookupResult getStat(const char *Path, FileData &Data, bool isFile,
-                       int *FileDescriptor) {
+                       std::unique_ptr<vfs::File> *F,
+                       vfs::FileSystem &FS) override {
     // Do the lookup for the file's data in the PTH file.
     CacheTy::iterator I = Cache.find(Path);
 
     // If we don't get a hit in the PTH file just forward to 'stat'.
     if (I == Cache.end())
-      return statChained(Path, Data, isFile, FileDescriptor);
+      return statChained(Path, Data, isFile, F, FS);
 
     const PTHStatData &D = *I;
 
     if (!D.HasData)
       return CacheMissing;
 
+    Data.Name = Path;
     Data.Size = D.Size;
     Data.ModTime = D.ModTime;
     Data.UniqueID = D.UniqueID;
diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp
index e4059ee..cf76bdb 100644
--- a/lib/Lex/Pragma.cpp
+++ b/lib/Lex/Pragma.cpp
@@ -48,9 +48,7 @@
 //===----------------------------------------------------------------------===//
 
 PragmaNamespace::~PragmaNamespace() {
-  for (llvm::StringMap<PragmaHandler*>::iterator
-         I = Handlers.begin(), E = Handlers.end(); I != E; ++I)
-    delete I->second;
+  llvm::DeleteContainerSeconds(Handlers);
 }
 
 /// FindHandler - Check to see if there is already a handler for the
@@ -61,7 +59,7 @@
                                             bool IgnoreNull) const {
   if (PragmaHandler *Handler = Handlers.lookup(Name))
     return Handler;
-  return IgnoreNull ? 0 : Handlers.lookup(StringRef());
+  return IgnoreNull ? nullptr : Handlers.lookup(StringRef());
 }
 
 void PragmaNamespace::AddPragma(PragmaHandler *Handler) {
@@ -90,7 +88,7 @@
     = FindHandler(Tok.getIdentifierInfo() ? Tok.getIdentifierInfo()->getName()
                                           : StringRef(),
                   /*IgnoreNull=*/false);
-  if (Handler == 0) {
+  if (!Handler) {
     PP.Diag(Tok, diag::warn_pragma_ignored);
     return;
   }
@@ -292,7 +290,7 @@
   Lexer *TL = Lexer::Create_PragmaLexer(TokLoc, PragmaLoc, RParenLoc,
                                         StrVal.size(), *this);
 
-  EnterSourceFileWithLexer(TL, 0);
+  EnterSourceFileWithLexer(TL, nullptr);
 
   // With everything set up, lex this as a #pragma directive.
   HandlePragmaDirective(PragmaLoc, PIK__Pragma);
@@ -475,8 +473,9 @@
   // Search include directories for this file.
   const DirectoryLookup *CurDir;
   const FileEntry *File = LookupFile(FilenameTok.getLocation(), Filename,
-                                     isAngled, 0, CurDir, NULL, NULL, NULL);
-  if (File == 0) {
+                                     isAngled, nullptr, CurDir, nullptr,
+                                     nullptr, nullptr);
+  if (!File) {
     if (!SuppressIncludeNotFoundError)
       Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
     return;
@@ -512,7 +511,7 @@
   if (Tok.isNot(tok::l_paren)) {
     Diag(PragmaTok.getLocation(), diag::err_pragma_push_pop_macro_malformed)
       << getSpelling(PragmaTok);
-    return 0;
+    return nullptr;
   }
 
   // Read the macro name string.
@@ -520,12 +519,12 @@
   if (Tok.isNot(tok::string_literal)) {
     Diag(PragmaTok.getLocation(), diag::err_pragma_push_pop_macro_malformed)
       << getSpelling(PragmaTok);
-    return 0;
+    return nullptr;
   }
 
   if (Tok.hasUDSuffix()) {
     Diag(Tok, diag::err_invalid_string_udl);
-    return 0;
+    return nullptr;
   }
 
   // Remember the macro string.
@@ -536,7 +535,7 @@
   if (Tok.isNot(tok::r_paren)) {
     Diag(PragmaTok.getLocation(), diag::err_pragma_push_pop_macro_malformed)
       << getSpelling(PragmaTok);
-    return 0;
+    return nullptr;
   }
 
   assert(StrVal[0] == '"' && StrVal[StrVal.size()-1] == '"' &&
@@ -738,7 +737,7 @@
     // we already have the namespace to insert into.
     if (PragmaHandler *Existing = PragmaHandlers->FindHandler(Namespace)) {
       InsertNS = Existing->getIfNamespace();
-      assert(InsertNS != 0 && "Cannot have a pragma namespace and pragma"
+      assert(InsertNS != nullptr && "Cannot have a pragma namespace and pragma"
              " handler with the same name!");
     } else {
       // Otherwise, this namespace doesn't exist yet, create and insert the
@@ -812,8 +811,8 @@
 /// PragmaOnceHandler - "\#pragma once" marks the file as atomically included.
 struct PragmaOnceHandler : public PragmaHandler {
   PragmaOnceHandler() : PragmaHandler("once") {}
-  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
-                            Token &OnceTok) {
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &OnceTok) override {
     PP.CheckEndOfDirective("pragma once");
     PP.HandlePragmaOnce(OnceTok);
   }
@@ -823,8 +822,8 @@
 /// rest of the line is not lexed.
 struct PragmaMarkHandler : public PragmaHandler {
   PragmaMarkHandler() : PragmaHandler("mark") {}
-  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
-                            Token &MarkTok) {
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &MarkTok) override {
     PP.HandlePragmaMark();
   }
 };
@@ -832,8 +831,8 @@
 /// PragmaPoisonHandler - "\#pragma poison x" marks x as not usable.
 struct PragmaPoisonHandler : public PragmaHandler {
   PragmaPoisonHandler() : PragmaHandler("poison") {}
-  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
-                            Token &PoisonTok) {
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &PoisonTok) override {
     PP.HandlePragmaPoison(PoisonTok);
   }
 };
@@ -842,24 +841,24 @@
 /// as a system header, which silences warnings in it.
 struct PragmaSystemHeaderHandler : public PragmaHandler {
   PragmaSystemHeaderHandler() : PragmaHandler("system_header") {}
-  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
-                            Token &SHToken) {
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &SHToken) override {
     PP.HandlePragmaSystemHeader(SHToken);
     PP.CheckEndOfDirective("pragma");
   }
 };
 struct PragmaDependencyHandler : public PragmaHandler {
   PragmaDependencyHandler() : PragmaHandler("dependency") {}
-  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
-                            Token &DepToken) {
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &DepToken) override {
     PP.HandlePragmaDependency(DepToken);
   }
 };
 
 struct PragmaDebugHandler : public PragmaHandler {
   PragmaDebugHandler() : PragmaHandler("__debug") {}
-  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
-                            Token &DepToken) {
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &DepToken) override {
     Token Tok;
     PP.LexUnexpandedToken(Tok);
     if (Tok.isNot(tok::identifier)) {
@@ -926,8 +925,9 @@
 #ifdef _MSC_VER
     #pragma warning(disable : 4717)
 #endif
-  void DebugOverflowStack() {
-    DebugOverflowStack();
+  static void DebugOverflowStack() {
+    void (*volatile Self)() = DebugOverflowStack;
+    Self();
   }
 #ifdef _MSC_VER
     #pragma warning(default : 4717)
@@ -942,8 +942,8 @@
 public:
   explicit PragmaDiagnosticHandler(const char *NS) :
     PragmaHandler("diagnostic"), Namespace(NS) {}
-  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
-                            Token &DiagToken) {
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &DiagToken) override {
     SourceLocation DiagLoc = DiagToken.getLocation();
     Token Tok;
     PP.LexUnexpandedToken(Tok);
@@ -954,16 +954,7 @@
     IdentifierInfo *II = Tok.getIdentifierInfo();
     PPCallbacks *Callbacks = PP.getPPCallbacks();
 
-    diag::Mapping Map;
-    if (II->isStr("warning"))
-      Map = diag::MAP_WARNING;
-    else if (II->isStr("error"))
-      Map = diag::MAP_ERROR;
-    else if (II->isStr("ignored"))
-      Map = diag::MAP_IGNORE;
-    else if (II->isStr("fatal"))
-      Map = diag::MAP_FATAL;
-    else if (II->isStr("pop")) {
+    if (II->isStr("pop")) {
       if (!PP.getDiagnostics().popMappings(DiagLoc))
         PP.Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop);
       else if (Callbacks)
@@ -974,7 +965,16 @@
       if (Callbacks)
         Callbacks->PragmaDiagnosticPush(DiagLoc, Namespace);
       return;
-    } else {
+    }
+
+    diag::Severity SV = llvm::StringSwitch<diag::Severity>(II->getName())
+                            .Case("ignored", diag::Severity::Ignored)
+                            .Case("warning", diag::Severity::Warning)
+                            .Case("error", diag::Severity::Error)
+                            .Case("fatal", diag::Severity::Fatal)
+                            .Default(diag::Severity());
+
+    if (SV == diag::Severity()) {
       PP.Diag(Tok, diag::warn_pragma_diagnostic_invalid);
       return;
     }
@@ -993,46 +993,30 @@
     }
 
     if (WarningName.size() < 3 || WarningName[0] != '-' ||
-        WarningName[1] != 'W') {
+        (WarningName[1] != 'W' && WarningName[1] != 'R')) {
       PP.Diag(StringLoc, diag::warn_pragma_diagnostic_invalid_option);
       return;
     }
 
-    if (PP.getDiagnostics().setDiagnosticGroupMapping(WarningName.substr(2),
-                                                      Map, DiagLoc))
+    if (PP.getDiagnostics().setSeverityForGroup(
+            WarningName[1] == 'W' ? diag::Flavor::WarningOrError
+                                  : diag::Flavor::Remark,
+            WarningName.substr(2), SV, DiagLoc))
       PP.Diag(StringLoc, diag::warn_pragma_diagnostic_unknown_warning)
         << WarningName;
     else if (Callbacks)
-      Callbacks->PragmaDiagnostic(DiagLoc, Namespace, Map, WarningName);
+      Callbacks->PragmaDiagnostic(DiagLoc, Namespace, SV, WarningName);
   }
 };
 
-// Returns -1 on failure.
-static int LexSimpleInt(Preprocessor &PP, Token &Tok) {
-  assert(Tok.is(tok::numeric_constant));
-  SmallString<8> IntegerBuffer;
-  bool NumberInvalid = false;
-  StringRef Spelling = PP.getSpelling(Tok, IntegerBuffer, &NumberInvalid);
-  if (NumberInvalid)
-    return -1;
-  NumericLiteralParser Literal(Spelling, Tok.getLocation(), PP);
-  if (Literal.hadError || !Literal.isIntegerLiteral() || Literal.hasUDSuffix())
-    return -1;
-  llvm::APInt APVal(32, 0);
-  if (Literal.GetIntegerValue(APVal))
-    return -1;
-  PP.Lex(Tok);
-  return int(APVal.getLimitedValue(INT_MAX));
-}
-
 /// "\#pragma warning(...)".  MSVC's diagnostics do not map cleanly to clang's
 /// diagnostics, so we don't really implement this pragma.  We parse it and
 /// ignore it to avoid -Wunknown-pragma warnings.
 struct PragmaWarningHandler : public PragmaHandler {
   PragmaWarningHandler() : PragmaHandler("warning") {}
 
-  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
-                            Token &Tok) {
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &Tok) override {
     // Parse things like:
     // warning(push, 1)
     // warning(pop)
@@ -1059,8 +1043,10 @@
       PP.Lex(Tok);
       if (Tok.is(tok::comma)) {
         PP.Lex(Tok);
-        if (Tok.is(tok::numeric_constant))
-          Level = LexSimpleInt(PP, Tok);
+        uint64_t Value;
+        if (Tok.is(tok::numeric_constant) &&
+            PP.parseSimpleIntegerLiteral(Tok, Value))
+          Level = int(Value);
         if (Level < 0 || Level > 4) {
           PP.Diag(Tok, diag::warn_pragma_warning_push_level);
           return;
@@ -1104,12 +1090,13 @@
         SmallVector<int, 4> Ids;
         PP.Lex(Tok);
         while (Tok.is(tok::numeric_constant)) {
-          int Id = LexSimpleInt(PP, Tok);
-          if (Id <= 0) {
+          uint64_t Value;
+          if (!PP.parseSimpleIntegerLiteral(Tok, Value) || Value == 0 ||
+              Value > INT_MAX) {
             PP.Diag(Tok, diag::warn_pragma_warning_expected_number);
             return;
           }
-          Ids.push_back(Id);
+          Ids.push_back(int(Value));
         }
         if (Callbacks)
           Callbacks->PragmaWarning(DiagLoc, Specifier, Ids);
@@ -1135,8 +1122,8 @@
 /// PragmaIncludeAliasHandler - "\#pragma include_alias("...")".
 struct PragmaIncludeAliasHandler : public PragmaHandler {
   PragmaIncludeAliasHandler() : PragmaHandler("include_alias") {}
-  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
-                            Token &IncludeAliasTok) {
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &IncludeAliasTok) override {
     PP.HandlePragmaIncludeAlias(IncludeAliasTok);
   }
 };
@@ -1177,8 +1164,8 @@
                        StringRef Namespace = StringRef())
     : PragmaHandler(PragmaKind(Kind, true)), Kind(Kind), Namespace(Namespace) {}
 
-  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
-                            Token &Tok) {
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &Tok) override {
     SourceLocation MessageLoc = Tok.getLocation();
     PP.Lex(Tok);
     bool ExpectClosingParen = false;
@@ -1230,8 +1217,8 @@
 /// macro on the top of the stack.
 struct PragmaPushMacroHandler : public PragmaHandler {
   PragmaPushMacroHandler() : PragmaHandler("push_macro") {}
-  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
-                            Token &PushMacroTok) {
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &PushMacroTok) override {
     PP.HandlePragmaPushMacro(PushMacroTok);
   }
 };
@@ -1241,8 +1228,8 @@
 /// macro to the value on the top of the stack.
 struct PragmaPopMacroHandler : public PragmaHandler {
   PragmaPopMacroHandler() : PragmaHandler("pop_macro") {}
-  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
-                            Token &PopMacroTok) {
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &PopMacroTok) override {
     PP.HandlePragmaPopMacro(PopMacroTok);
   }
 };
@@ -1252,8 +1239,8 @@
 /// PragmaSTDC_FENV_ACCESSHandler - "\#pragma STDC FENV_ACCESS ...".
 struct PragmaSTDC_FENV_ACCESSHandler : public PragmaHandler {
   PragmaSTDC_FENV_ACCESSHandler() : PragmaHandler("FENV_ACCESS") {}
-  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
-                            Token &Tok) {
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &Tok) override {
     tok::OnOffSwitch OOS;
     if (PP.LexOnOffSwitch(OOS))
      return;
@@ -1266,8 +1253,8 @@
 struct PragmaSTDC_CX_LIMITED_RANGEHandler : public PragmaHandler {
   PragmaSTDC_CX_LIMITED_RANGEHandler()
     : PragmaHandler("CX_LIMITED_RANGE") {}
-  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
-                            Token &Tok) {
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &Tok) override {
     tok::OnOffSwitch OOS;
     PP.LexOnOffSwitch(OOS);
   }
@@ -1276,8 +1263,8 @@
 /// PragmaSTDC_UnknownHandler - "\#pragma STDC ...".
 struct PragmaSTDC_UnknownHandler : public PragmaHandler {
   PragmaSTDC_UnknownHandler() {}
-  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
-                            Token &UnknownTok) {
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &UnknownTok) override {
     // C99 6.10.6p2, unknown forms are not allowed.
     PP.Diag(UnknownTok, diag::ext_stdc_pragma_ignored);
   }
@@ -1287,8 +1274,8 @@
 ///   \#pragma clang arc_cf_code_audited begin/end
 struct PragmaARCCFCodeAuditedHandler : public PragmaHandler {
   PragmaARCCFCodeAuditedHandler() : PragmaHandler("arc_cf_code_audited") {}
-  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
-                            Token &NameTok) {
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &NameTok) override {
     SourceLocation Loc = NameTok.getLocation();
     bool IsBegin;
 
@@ -1351,8 +1338,8 @@
 struct PragmaRegionHandler : public PragmaHandler {
   PragmaRegionHandler(const char *pragma) : PragmaHandler(pragma) { }
 
-  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
-                            Token &NameTok) {
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &NameTok) override {
     // #pragma region: endregion matches can be verified
     // __pragma(region): no sense, but ignored by msvc
     // _Pragma is not valid for MSVC, but there isn't any point
@@ -1401,3 +1388,26 @@
     AddPragmaHandler(new PragmaRegionHandler("endregion"));
   }
 }
+
+/// Ignore all pragmas, useful for modes such as -Eonly which would otherwise
+/// warn about those pragmas being unknown.
+void Preprocessor::IgnorePragmas() {
+  AddPragmaHandler(new EmptyPragmaHandler());
+  // Also ignore all pragmas in all namespaces created
+  // in Preprocessor::RegisterBuiltinPragmas().
+  AddPragmaHandler("GCC", new EmptyPragmaHandler());
+  AddPragmaHandler("clang", new EmptyPragmaHandler());
+  if (PragmaHandler *NS = PragmaHandlers->FindHandler("STDC")) {
+    // Preprocessor::RegisterBuiltinPragmas() already registers
+    // PragmaSTDC_UnknownHandler as the empty handler, so remove it first,
+    // otherwise there will be an assert about a duplicate handler.
+    PragmaNamespace *STDCNamespace = NS->getIfNamespace();
+    assert(STDCNamespace &&
+           "Invalid namespace, registered as a regular pragma handler!");
+    if (PragmaHandler *Existing = STDCNamespace->FindHandler("", false)) {
+      RemovePragmaHandler("STDC", Existing);
+      delete Existing;
+    }
+  }
+  AddPragmaHandler("STDC", new EmptyPragmaHandler());
+}
diff --git a/lib/Lex/PreprocessingRecord.cpp b/lib/Lex/PreprocessingRecord.cpp
index 090aeed..41bb581 100644
--- a/lib/Lex/PreprocessingRecord.cpp
+++ b/lib/Lex/PreprocessingRecord.cpp
@@ -40,7 +40,7 @@
 
 PreprocessingRecord::PreprocessingRecord(SourceManager &SM)
   : SourceMgr(SM),
-    ExternalSource(0) {
+    ExternalSource(nullptr) {
 }
 
 /// \brief Returns a pair of [Begin, End) iterators of preprocessed entities
@@ -334,7 +334,7 @@
   }
 
   if (PPID.ID == 0)
-    return 0;
+    return nullptr;
   unsigned Index = PPID.ID - 1;
   assert(Index < PreprocessedEntities.size() &&
          "Out-of bounds local preprocessed entity");
@@ -361,7 +361,7 @@
   llvm::DenseMap<const MacroInfo *, MacroDefinition *>::iterator Pos
     = MacroDefinitions.find(MI);
   if (Pos == MacroDefinitions.end())
-    return 0;
+    return nullptr;
 
   return Pos->second;
 }
@@ -406,6 +406,10 @@
                       MacroNameTok.getLocation());
 }
 
+void PreprocessingRecord::SourceRangeSkipped(SourceRange Range) {
+  SkippedRanges.push_back(Range);
+}
+
 void PreprocessingRecord::MacroExpands(const Token &Id,const MacroDirective *MD,
                                        SourceRange Range,
                                        const MacroArgs *Args) {
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index b500efe..4a11803 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -26,7 +26,6 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Lex/Preprocessor.h"
-#include "clang/Lex/MacroArgs.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
@@ -35,6 +34,7 @@
 #include "clang/Lex/HeaderSearch.h"
 #include "clang/Lex/LexDiagnostic.h"
 #include "clang/Lex/LiteralSupport.h"
+#include "clang/Lex/MacroArgs.h"
 #include "clang/Lex/MacroInfo.h"
 #include "clang/Lex/ModuleLoader.h"
 #include "clang/Lex/Pragma.h"
@@ -42,8 +42,8 @@
 #include "clang/Lex/PreprocessorOptions.h"
 #include "clang/Lex/ScratchBuffer.h"
 #include "llvm/ADT/APFloat.h"
-#include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/Capacity.h"
 #include "llvm/Support/ConvertUTF.h"
@@ -56,20 +56,21 @@
 
 Preprocessor::Preprocessor(IntrusiveRefCntPtr<PreprocessorOptions> PPOpts,
                            DiagnosticsEngine &diags, LangOptions &opts,
-                           const TargetInfo *target, SourceManager &SM,
-                           HeaderSearch &Headers, ModuleLoader &TheModuleLoader,
+                           SourceManager &SM, HeaderSearch &Headers,
+                           ModuleLoader &TheModuleLoader,
                            IdentifierInfoLookup *IILookup, bool OwnsHeaders,
-                           bool DelayInitialization, bool IncrProcessing)
-    : PPOpts(PPOpts), Diags(&diags), LangOpts(opts), Target(target),
+                           TranslationUnitKind TUKind)
+    : PPOpts(PPOpts), Diags(&diags), LangOpts(opts), Target(nullptr),
       FileMgr(Headers.getFileMgr()), SourceMgr(SM), HeaderInfo(Headers),
-      TheModuleLoader(TheModuleLoader), ExternalSource(0),
-      Identifiers(opts, IILookup), IncrementalProcessing(IncrProcessing),
-      CodeComplete(0), CodeCompletionFile(0), CodeCompletionOffset(0),
-      LastTokenWasAt(false), ModuleImportExpectsIdentifier(false),
-      CodeCompletionReached(0), SkipMainFilePreamble(0, true), CurPPLexer(0),
-      CurDirLookup(0), CurLexerKind(CLK_Lexer), Callbacks(0),
-      MacroArgCache(0), Record(0), MIChainHead(0), MICache(0),
-      DeserialMIChainHead(0) {
+      TheModuleLoader(TheModuleLoader), ExternalSource(nullptr),
+      Identifiers(opts, IILookup), IncrementalProcessing(false), TUKind(TUKind),
+      CodeComplete(nullptr), CodeCompletionFile(nullptr),
+      CodeCompletionOffset(0), LastTokenWasAt(false),
+      ModuleImportExpectsIdentifier(false), CodeCompletionReached(0),
+      SkipMainFilePreamble(0, true), CurPPLexer(nullptr),
+      CurDirLookup(nullptr), CurLexerKind(CLK_Lexer), CurSubmodule(nullptr),
+      Callbacks(nullptr), MacroArgCache(nullptr), Record(nullptr),
+      MIChainHead(nullptr), MICache(nullptr), DeserialMIChainHead(nullptr) {
   OwnsHeaderSearch = OwnsHeaders;
   
   ScratchBuf = new ScratchBuffer(SourceMgr);
@@ -127,39 +128,35 @@
     Ident___abnormal_termination = getIdentifierInfo("__abnormal_termination");
     Ident_AbnormalTermination    = getIdentifierInfo("AbnormalTermination");
   } else {
-    Ident__exception_info = Ident__exception_code = Ident__abnormal_termination = 0;
-    Ident___exception_info = Ident___exception_code = Ident___abnormal_termination = 0;
-    Ident_GetExceptionInfo = Ident_GetExceptionCode = Ident_AbnormalTermination = 0;
-  }
-
-  if (!DelayInitialization) {
-    assert(Target && "Must provide target information for PP initialization");
-    Initialize(*Target);
+    Ident__exception_info = Ident__exception_code = nullptr;
+    Ident__abnormal_termination = Ident___exception_info = nullptr;
+    Ident___exception_code = Ident___abnormal_termination = nullptr;
+    Ident_GetExceptionInfo = Ident_GetExceptionCode = nullptr;
+    Ident_AbnormalTermination = nullptr;
   }
 }
 
 Preprocessor::~Preprocessor() {
   assert(BacktrackPositions.empty() && "EnableBacktrack/Backtrack imbalance!");
 
-  while (!IncludeMacroStack.empty()) {
-    delete IncludeMacroStack.back().TheLexer;
-    delete IncludeMacroStack.back().TheTokenLexer;
-    IncludeMacroStack.pop_back();
-  }
+  IncludeMacroStack.clear();
 
   // Free any macro definitions.
   for (MacroInfoChain *I = MIChainHead ; I ; I = I->Next)
     I->MI.Destroy();
 
   // Free any cached macro expanders.
+  // This populates MacroArgCache, so all TokenLexers need to be destroyed
+  // before the code below that frees up the MacroArgCache list.
   for (unsigned i = 0, e = NumCachedTokenLexers; i != e; ++i)
     delete TokenLexerCache[i];
+  CurTokenLexer.reset();
 
   for (DeserializedMacroInfoChain *I = DeserialMIChainHead ; I ; I = I->Next)
     I->MI.Destroy();
 
   // Free any cached MacroArgs.
-  for (MacroArgs *ArgList = MacroArgCache; ArgList; )
+  for (MacroArgs *ArgList = MacroArgCache; ArgList;)
     ArgList = ArgList->deallocate();
 
   // Release pragma information.
@@ -444,8 +441,8 @@
 
 Module *Preprocessor::getCurrentModule() {
   if (getLangOpts().CurrentModule.empty())
-    return 0;
-  
+    return nullptr;
+
   return getHeaderSearchInfo().lookupModule(getLangOpts().CurrentModule);
 }
 
@@ -467,8 +464,8 @@
   // a main file.
   if (!SourceMgr.isLoadedFileID(MainFileID)) {
     // Enter the main file source buffer.
-    EnterSourceFile(MainFileID, 0, SourceLocation());
-  
+    EnterSourceFile(MainFileID, nullptr, SourceLocation());
+
     // If we've been asked to skip bytes in the main file (e.g., as part of a
     // precompiled preamble), do so now.
     if (SkipMainFilePreamble.first > 0)
@@ -485,12 +482,12 @@
   llvm::MemoryBuffer *SB =
     llvm::MemoryBuffer::getMemBufferCopy(Predefines, "<built-in>");
   assert(SB && "Cannot create predefined source buffer");
-  FileID FID = SourceMgr.createFileIDForMemBuffer(SB);
+  FileID FID = SourceMgr.createFileID(SB);
   assert(!FID.isInvalid() && "Could not create FileID for predefines?");
   setPredefinesFileID(FID);
 
   // Start parsing the predefines.
-  EnterSourceFile(FID, 0, SourceLocation());
+  EnterSourceFile(FID, nullptr, SourceLocation());
 }
 
 void Preprocessor::EndSourceFile() {
@@ -503,60 +500,17 @@
 // Lexer Event Handling.
 //===----------------------------------------------------------------------===//
 
-static void appendCodePoint(unsigned Codepoint,
-                            llvm::SmallVectorImpl<char> &Str) {
-  char ResultBuf[4];
-  char *ResultPtr = ResultBuf;
-  bool Res = llvm::ConvertCodePointToUTF8(Codepoint, ResultPtr);
-  (void)Res;
-  assert(Res && "Unexpected conversion failure");
-  Str.append(ResultBuf, ResultPtr);
-}
-
-static void expandUCNs(SmallVectorImpl<char> &Buf, StringRef Input) {
-  for (StringRef::iterator I = Input.begin(), E = Input.end(); I != E; ++I) {
-    if (*I != '\\') {
-      Buf.push_back(*I);
-      continue;
-    }
-
-    ++I;
-    assert(*I == 'u' || *I == 'U');
-
-    unsigned NumHexDigits;
-    if (*I == 'u')
-      NumHexDigits = 4;
-    else
-      NumHexDigits = 8;
-
-    assert(I + NumHexDigits <= E);
-
-    uint32_t CodePoint = 0;
-    for (++I; NumHexDigits != 0; ++I, --NumHexDigits) {
-      unsigned Value = llvm::hexDigitValue(*I);
-      assert(Value != -1U);
-
-      CodePoint <<= 4;
-      CodePoint += Value;
-    }
-
-    appendCodePoint(CodePoint, Buf);
-    --I;
-  }
-}
-
 /// LookUpIdentifierInfo - Given a tok::raw_identifier token, look up the
 /// identifier information for the token and install it into the token,
 /// updating the token kind accordingly.
 IdentifierInfo *Preprocessor::LookUpIdentifierInfo(Token &Identifier) const {
-  assert(Identifier.getRawIdentifierData() != 0 && "No raw identifier data!");
+  assert(!Identifier.getRawIdentifier().empty() && "No raw identifier data!");
 
   // Look up this token, see if it is a macro, or if it is a language keyword.
   IdentifierInfo *II;
   if (!Identifier.needsCleaning() && !Identifier.hasUCN()) {
     // No cleaning needed, just use the characters from the lexed buffer.
-    II = getIdentifierInfo(StringRef(Identifier.getRawIdentifierData(),
-                                     Identifier.getLength()));
+    II = getIdentifierInfo(Identifier.getRawIdentifier());
   } else {
     // Cleaning needed, alloca a buffer, clean into it, then use the buffer.
     SmallString<64> IdentifierBuffer;
@@ -669,7 +623,7 @@
   // name of a macro.
   // FIXME: This warning is disabled in cases where it shouldn't be, like
   //   "#define constexpr constexpr", "int constexpr;"
-  if (II.isCXX11CompatKeyword() & !DisableMacroExpansion) {
+  if (II.isCXX11CompatKeyword() && !DisableMacroExpansion) {
     Diag(Identifier, diag::warn_cxx11_keyword) << II.getName();
     // Don't diagnose this keyword again in this translation unit.
     II.setIsCXX11CompatKeyword(false);
@@ -679,7 +633,7 @@
   // then we act as if it is the actual operator and not the textual
   // representation of it.
   if (II.isCPlusPlusOperatorKeyword())
-    Identifier.setIdentifierInfo(0);
+    Identifier.setIdentifierInfo(nullptr);
 
   // If this is an extension token, diagnose its use.
   // We avoid diagnosing tokens that originate from macro definitions.
@@ -803,7 +757,7 @@
   } while (Result.is(tok::string_literal));
 
   // Concatenate and parse the strings.
-  StringLiteralParser Literal(&StrToks[0], StrToks.size(), *this);
+  StringLiteralParser Literal(StrToks, *this);
   assert(Literal.isAscii() && "Didn't allow wide strings in");
 
   if (Literal.hadError)
@@ -819,6 +773,24 @@
   return true;
 }
 
+bool Preprocessor::parseSimpleIntegerLiteral(Token &Tok, uint64_t &Value) {
+  assert(Tok.is(tok::numeric_constant));
+  SmallString<8> IntegerBuffer;
+  bool NumberInvalid = false;
+  StringRef Spelling = getSpelling(Tok, IntegerBuffer, &NumberInvalid);
+  if (NumberInvalid)
+    return false;
+  NumericLiteralParser Literal(Spelling, Tok.getLocation(), *this);
+  if (Literal.hadError || !Literal.isIntegerLiteral() || Literal.hasUDSuffix())
+    return false;
+  llvm::APInt APVal(64, 0);
+  if (Literal.GetIntegerValue(APVal))
+    return false;
+  Lex(Tok);
+  Value = APVal.getLimitedValue();
+  return true;
+}
+
 void Preprocessor::addCommentHandler(CommentHandler *Handler) {
   assert(Handler && "NULL comment handler");
   assert(std::find(CommentHandlers.begin(), CommentHandlers.end(), Handler) ==
diff --git a/lib/Lex/ScratchBuffer.cpp b/lib/Lex/ScratchBuffer.cpp
index 3d363fa..d7104b1 100644
--- a/lib/Lex/ScratchBuffer.cpp
+++ b/lib/Lex/ScratchBuffer.cpp
@@ -21,7 +21,8 @@
 //than a page, almost certainly enough for anything. :)
 static const unsigned ScratchBufSize = 4060;
 
-ScratchBuffer::ScratchBuffer(SourceManager &SM) : SourceMgr(SM), CurBuffer(0) {
+ScratchBuffer::ScratchBuffer(SourceManager &SM)
+    : SourceMgr(SM), CurBuffer(nullptr) {
   // Set BytesUsed so that the first call to getToken will require an alloc.
   BytesUsed = ScratchBufSize;
 }
@@ -65,7 +66,7 @@
 
   llvm::MemoryBuffer *Buf =
     llvm::MemoryBuffer::getNewMemBuffer(RequestLen, "<scratch space>");
-  FileID FID = SourceMgr.createFileIDForMemBuffer(Buf);
+  FileID FID = SourceMgr.createFileID(Buf);
   BufferStartLoc = SourceMgr.getLocForStartOfFile(FID);
   CurBuffer = const_cast<char*>(Buf->getBufferStart());
   BytesUsed = 1;
diff --git a/lib/Lex/TokenLexer.cpp b/lib/Lex/TokenLexer.cpp
index 0213afc..9d03e8d 100644
--- a/lib/Lex/TokenLexer.cpp
+++ b/lib/Lex/TokenLexer.cpp
@@ -12,9 +12,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Lex/TokenLexer.h"
-#include "clang/Lex/MacroArgs.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Lex/LexDiagnostic.h"
+#include "clang/Lex/MacroArgs.h"
 #include "clang/Lex/MacroInfo.h"
 #include "clang/Lex/Preprocessor.h"
 #include "llvm/ADT/SmallString.h"
@@ -37,6 +37,7 @@
   ExpandLocEnd = ELEnd;
   AtStartOfLine = Tok.isAtStartOfLine();
   HasLeadingSpace = Tok.hasLeadingSpace();
+  NextTokGetsSpace = false;
   Tokens = &*Macro->tokens_begin();
   OwnsTokens = false;
   DisableMacroExpansion = false;
@@ -85,8 +86,8 @@
   // associated with it.
   destroy();
 
-  Macro = 0;
-  ActualArgs = 0;
+  Macro = nullptr;
+  ActualArgs = nullptr;
   Tokens = TokArray;
   OwnsTokens = ownsTokens;
   DisableMacroExpansion = disableMacroExpansion;
@@ -95,6 +96,7 @@
   ExpandLocStart = ExpandLocEnd = SourceLocation();
   AtStartOfLine = false;
   HasLeadingSpace = false;
+  NextTokGetsSpace = false;
   MacroExpansionStart = SourceLocation();
 
   // Set HasLeadingSpace/AtStartOfLine so that the first token will be
@@ -111,7 +113,7 @@
   // the expanded tokens.
   if (OwnsTokens) {
     delete [] Tokens;
-    Tokens = 0;
+    Tokens = nullptr;
     OwnsTokens = false;
   }
 
@@ -119,13 +121,9 @@
   if (ActualArgs) ActualArgs->destroy(PP);
 }
 
-/// Remove comma ahead of __VA_ARGS__, if present, according to compiler dialect
-/// settings.  Returns true if the comma is removed.
-static bool MaybeRemoveCommaBeforeVaArgs(SmallVectorImpl<Token> &ResultToks,
-                                         bool &NextTokGetsSpace,
-                                         bool HasPasteOperator,
-                                         MacroInfo *Macro, unsigned MacroArgNo,
-                                         Preprocessor &PP) {
+bool TokenLexer::MaybeRemoveCommaBeforeVaArgs(
+    SmallVectorImpl<Token> &ResultToks, bool HasPasteOperator, MacroInfo *Macro,
+    unsigned MacroArgNo, Preprocessor &PP) {
   // Is the macro argument __VA_ARGS__?
   if (!Macro->isVariadic() || MacroArgNo != Macro->getNumArgs()-1)
     return false;
@@ -133,7 +131,7 @@
   // In Microsoft-compatibility mode, a comma is removed in the expansion
   // of " ... , __VA_ARGS__ " if __VA_ARGS__ is empty.  This extension is
   // not supported by gcc.
-  if (!HasPasteOperator && !PP.getLangOpts().MicrosoftMode)
+  if (!HasPasteOperator && !PP.getLangOpts().MSVCCompat)
     return false;
 
   // GCC removes the comma in the expansion of " ... , ## __VA_ARGS__ " if
@@ -179,16 +177,14 @@
   // we install the newly expanded sequence as the new 'Tokens' list.
   bool MadeChange = false;
 
-  // NextTokGetsSpace - When this is true, the next token appended to the
-  // output list will get a leading space, regardless of whether it had one to
-  // begin with or not.  This is used for placemarker support.
-  bool NextTokGetsSpace = false;
-
   for (unsigned i = 0, e = NumTokens; i != e; ++i) {
     // If we found the stringify operator, get the argument stringified.  The
     // preprocessor already verified that the following token is a macro name
     // when the #define was parsed.
     const Token &CurTok = Tokens[i];
+    if (i != 0 && !Tokens[i-1].is(tok::hashhash) && CurTok.hasLeadingSpace())
+      NextTokGetsSpace = true;
+
     if (CurTok.is(tok::hash) || CurTok.is(tok::hashat)) {
       int ArgNo = Macro->getArgumentNum(Tokens[i+1].getIdentifierInfo());
       assert(ArgNo != -1 && "Token following # is not an argument?");
@@ -213,7 +209,7 @@
 
       // The stringified/charified string leading space flag gets set to match
       // the #/#@ operator.
-      if (CurTok.hasLeadingSpace() || NextTokGetsSpace)
+      if (NextTokGetsSpace)
         Res.setFlag(Token::LeadingSpace);
 
       ResultToks.push_back(Res);
@@ -223,6 +219,13 @@
       continue;
     }
 
+    // Find out if there is a paste (##) operator before or after the token.
+    bool NonEmptyPasteBefore =
+      !ResultToks.empty() && ResultToks.back().is(tok::hashhash);
+    bool PasteBefore = i != 0 && Tokens[i-1].is(tok::hashhash);
+    bool PasteAfter = i+1 != e && Tokens[i+1].is(tok::hashhash);
+    assert(!NonEmptyPasteBefore || PasteBefore);
+
     // Otherwise, if this is not an argument token, just add the token to the
     // output buffer.
     IdentifierInfo *II = CurTok.getIdentifierInfo();
@@ -234,7 +237,9 @@
       if (NextTokGetsSpace) {
         ResultToks.back().setFlag(Token::LeadingSpace);
         NextTokGetsSpace = false;
-      }
+      } else if (PasteBefore && !NonEmptyPasteBefore)
+        ResultToks.back().clearFlag(Token::LeadingSpace);
+
       continue;
     }
 
@@ -242,18 +247,12 @@
     // input.
     MadeChange = true;
 
-    // Otherwise, this is a use of the argument.  Find out if there is a paste
-    // (##) operator before or after the argument.
-    bool NonEmptyPasteBefore =
-      !ResultToks.empty() && ResultToks.back().is(tok::hashhash);
-    bool PasteBefore = i != 0 && Tokens[i-1].is(tok::hashhash);
-    bool PasteAfter = i+1 != e && Tokens[i+1].is(tok::hashhash);
-    assert(!NonEmptyPasteBefore || PasteBefore);
+    // Otherwise, this is a use of the argument.
 
     // In Microsoft mode, remove the comma before __VA_ARGS__ to ensure there
     // are no trailing commas if __VA_ARGS__ is empty.
     if (!PasteBefore && ActualArgs->isVarargsElidedUse() &&
-        MaybeRemoveCommaBeforeVaArgs(ResultToks, NextTokGetsSpace,
+        MaybeRemoveCommaBeforeVaArgs(ResultToks,
                                      /*HasPasteOperator=*/false,
                                      Macro, ArgNo, PP))
       continue;
@@ -282,7 +281,7 @@
         // behavior by not considering single commas from nested macro
         // expansions as argument separators. Set a flag on the token so we can
         // test for this later when the macro expansion is processed.
-        if (PP.getLangOpts().MicrosoftMode && NumToks == 1 &&
+        if (PP.getLangOpts().MSVCCompat && NumToks == 1 &&
             ResultToks.back().is(tok::comma))
           ResultToks.back().setFlag(Token::IgnoredComma);
 
@@ -304,13 +303,8 @@
         // before the first token should match the whitespace of the arg
         // identifier.
         ResultToks[FirstResult].setFlagValue(Token::LeadingSpace,
-                                             CurTok.hasLeadingSpace() ||
                                              NextTokGetsSpace);
         NextTokGetsSpace = false;
-      } else {
-        // If this is an empty argument, and if there was whitespace before the
-        // formal token, make sure the next token gets whitespace before it.
-        NextTokGetsSpace = CurTok.hasLeadingSpace();
       }
       continue;
     }
@@ -358,8 +352,7 @@
       // assembler-with-cpp mode, invalid pastes are allowed through: in this
       // case, we do not want the extra whitespace to be added.  For example,
       // we want ". ## foo" -> ".foo" not ". foo".
-      if ((CurTok.hasLeadingSpace() || NextTokGetsSpace) &&
-          !NonEmptyPasteBefore)
+      if (NextTokGetsSpace)
         ResultToks[ResultToks.size()-NumToks].setFlag(Token::LeadingSpace);
 
       NextTokGetsSpace = false;
@@ -370,11 +363,9 @@
     // 6.10.3.3p2,3) calls for a bunch of placemarker stuff to occur.  We
     // implement this by eating ## operators when a LHS or RHS expands to
     // empty.
-    NextTokGetsSpace |= CurTok.hasLeadingSpace();
     if (PasteAfter) {
       // Discard the argument token and skip (don't copy to the expansion
       // buffer) the paste operator after it.
-      NextTokGetsSpace |= Tokens[i+1].hasLeadingSpace();
       ++i;
       continue;
     }
@@ -385,7 +376,7 @@
     assert(PasteBefore);
     if (NonEmptyPasteBefore) {
       assert(ResultToks.back().is(tok::hashhash));
-      NextTokGetsSpace |= ResultToks.pop_back_val().hasLeadingSpace();
+      ResultToks.pop_back();
     }
 
     // If this is the __VA_ARGS__ token, and if the argument wasn't provided,
@@ -393,7 +384,7 @@
     // the ## was a comma, remove the comma.  This is a GCC extension which is
     // disabled when using -std=c99.
     if (ActualArgs->isVarargsElidedUse())
-      MaybeRemoveCommaBeforeVaArgs(ResultToks, NextTokGetsSpace,
+      MaybeRemoveCommaBeforeVaArgs(ResultToks,
                                    /*HasPasteOperator=*/true,
                                    Macro, ArgNo, PP);
 
@@ -425,7 +416,7 @@
 
     Tok.startToken();
     Tok.setFlagValue(Token::StartOfLine , AtStartOfLine);
-    Tok.setFlagValue(Token::LeadingSpace, HasLeadingSpace);
+    Tok.setFlagValue(Token::LeadingSpace, HasLeadingSpace || NextTokGetsSpace);
     if (CurToken == 0)
       Tok.setFlag(Token::LeadingEmptyMacro);
     return PP.HandleEndOfTokenLexer(Tok);
@@ -479,12 +470,17 @@
   if (isFirstToken) {
     Tok.setFlagValue(Token::StartOfLine , AtStartOfLine);
     Tok.setFlagValue(Token::LeadingSpace, HasLeadingSpace);
-    AtStartOfLine = false;
-    HasLeadingSpace = false;
+  } else {
+    // If this is not the first token, we may still need to pass through
+    // leading whitespace if we've expanded a macro.
+    if (AtStartOfLine) Tok.setFlag(Token::StartOfLine);
+    if (HasLeadingSpace) Tok.setFlag(Token::LeadingSpace);
   }
+  AtStartOfLine = false;
+  HasLeadingSpace = false;
 
   // Handle recursive expansion!
-  if (!Tok.isAnnotation() && Tok.getIdentifierInfo() != 0) {
+  if (!Tok.isAnnotation() && Tok.getIdentifierInfo() != nullptr) {
     // Change the kind of this identifier to the appropriate token kind, e.g.
     // turning "for" into a keyword.
     IdentifierInfo *II = Tok.getIdentifierInfo();
@@ -511,7 +507,7 @@
 /// If this returns true, the caller should immediately return the token.
 bool TokenLexer::PasteTokens(Token &Tok) {
   SmallString<128> Buffer;
-  const char *ResultTokStrPtr = 0;
+  const char *ResultTokStrPtr = nullptr;
   SourceLocation StartLoc = Tok.getLocation();
   SourceLocation PasteOpLoc;
   do {
@@ -620,12 +616,11 @@
           SourceLocation Loc =
             SM.createExpansionLoc(PasteOpLoc, ExpandLocStart, ExpandLocEnd, 2);
           // If we're in microsoft extensions mode, downgrade this from a hard
-          // error to a warning that defaults to an error.  This allows
+          // error to an extension that defaults to an error.  This allows
           // disabling it.
-          PP.Diag(Loc,
-                  PP.getLangOpts().MicrosoftExt ? diag::err_pp_bad_paste_ms 
-                                                   : diag::err_pp_bad_paste)
-            << Buffer.str();
+          PP.Diag(Loc, PP.getLangOpts().MicrosoftExt ? diag::ext_pp_bad_paste_ms
+                                                     : diag::err_pp_bad_paste)
+              << Buffer.str();
         }
 
         // An error has occurred so exit loop.
diff --git a/lib/Lex/UnicodeCharSets.h b/lib/Lex/UnicodeCharSets.h
index 01ae7e8..12b2456 100644
--- a/lib/Lex/UnicodeCharSets.h
+++ b/lib/Lex/UnicodeCharSets.h
@@ -298,7 +298,7 @@
   // Malayam
   { 0x0D02, 0x0D03 }, { 0x0D05, 0x0D0C }, { 0x0D0E, 0x0D10 },
   { 0x0D12, 0x0D28 }, { 0x0D2A, 0x0D39 }, { 0x0D3E, 0x0D43 },
-  { 0x0D46, 0x0D48 }, { 0x0D4A, 0x0D4D }, { 0x0D60, 0x0D60 },
+  { 0x0D46, 0x0D48 }, { 0x0D4A, 0x0D4D }, { 0x0D60, 0x0D61 },
 
   // Digits (11)
   { 0x0D66, 0x0D6F },
diff --git a/lib/Makefile b/lib/Makefile
index 6663268..acf8089 100755
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -11,14 +11,10 @@
 # ARCMigrate and Rewrite are always needed because of libclang.
 PARALLEL_DIRS = Headers Basic Lex Parse AST Sema CodeGen Analysis Frontend \
                 FrontendTool Tooling Driver Format Edit Rewrite Serialization \
-                Index
+                Index ASTMatchers
 
 include $(CLANG_LEVEL)/../../Makefile.config
 
-ifeq ($(ENABLE_CLANG_REWRITER),1)
-PARALLEL_DIRS += ASTMatchers
-endif
-
 ifeq ($(ENABLE_CLANG_STATIC_ANALYZER),1)
 PARALLEL_DIRS += StaticAnalyzer
 endif
diff --git a/lib/Parse/CMakeLists.txt b/lib/Parse/CMakeLists.txt
index 08bf4e1..b868696 100644
--- a/lib/Parse/CMakeLists.txt
+++ b/lib/Parse/CMakeLists.txt
@@ -1,3 +1,9 @@
+set(LLVM_LINK_COMPONENTS
+  MC
+  MCParser
+  Support
+  )
+
 add_clang_library(clangParse
   ParseAST.cpp
   ParseCXXInlineMethods.cpp
@@ -10,28 +16,14 @@
   ParseOpenMP.cpp
   ParsePragma.cpp
   ParseStmt.cpp
+  ParseStmtAsm.cpp
   ParseTemplate.cpp
   ParseTentative.cpp
   Parser.cpp
-  )
 
-add_dependencies(clangParse
-  ClangAttrClasses
-  ClangAttrIdentifierArg
-  ClangAttrLateParsed
-  ClangAttrList
-  ClangAttrParsedAttrList
-  ClangAttrTypeArg
-  ClangCommentNodes
-  ClangDeclNodes
-  ClangDiagnosticCommon
-  ClangDiagnosticParse
-  ClangStmtNodes
-  )
-
-target_link_libraries(clangParse
-  clangBasic
+  LINK_LIBS
   clangAST
+  clangBasic
   clangLex
   clangSema
   )
diff --git a/lib/Parse/ParseAST.cpp b/lib/Parse/ParseAST.cpp
index 5678ece..0f5a1b3 100644
--- a/lib/Parse/ParseAST.cpp
+++ b/lib/Parse/ParseAST.cpp
@@ -23,9 +23,9 @@
 #include "clang/Sema/ExternalSemaSource.h"
 #include "clang/Sema/Sema.h"
 #include "clang/Sema/SemaConsumer.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/Support/CrashRecoveryContext.h"
 #include <cstdio>
+#include <memory>
 
 using namespace clang;
 
@@ -36,7 +36,7 @@
   const Parser &P;
 public:
   PrettyStackTraceParserEntry(const Parser &p) : P(p) {}
-  virtual void print(raw_ostream &OS) const;
+  void print(raw_ostream &OS) const override;
 };
 
 /// If a crash happens while the parser is active, print out a line indicating
@@ -88,7 +88,8 @@
                      CodeCompleteConsumer *CompletionConsumer,
                      bool SkipFunctionBodies) {
 
-  OwningPtr<Sema> S(new Sema(PP, Ctx, *Consumer, TUKind, CompletionConsumer));
+  std::unique_ptr<Sema> S(
+      new Sema(PP, Ctx, *Consumer, TUKind, CompletionConsumer));
 
   // Recover resources if we crash before exiting this method.
   llvm::CrashRecoveryContextCleanupRegistrar<Sema> CleanupSema(S.get());
@@ -109,8 +110,8 @@
 
   ASTConsumer *Consumer = &S.getASTConsumer();
 
-  OwningPtr<Parser> ParseOP(new Parser(S.getPreprocessor(), S,
-                                       SkipFunctionBodies));
+  std::unique_ptr<Parser> ParseOP(
+      new Parser(S.getPreprocessor(), S, SkipFunctionBodies));
   Parser &P = *ParseOP.get();
 
   PrettyStackTraceParserEntry CrashInfo(P);
diff --git a/lib/Parse/ParseCXXInlineMethods.cpp b/lib/Parse/ParseCXXInlineMethods.cpp
index 7792305..30a9120 100644
--- a/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/lib/Parse/ParseCXXInlineMethods.cpp
@@ -19,13 +19,6 @@
 #include "clang/Sema/Scope.h"
 using namespace clang;
 
-/// Get the FunctionDecl for a function or function template decl.
-static FunctionDecl *getFunctionDecl(Decl *D) {
-  if (FunctionDecl *fn = dyn_cast<FunctionDecl>(D))
-    return fn;
-  return cast<FunctionTemplateDecl>(D)->getTemplatedDecl();
-}
-
 /// ParseCXXInlineMethodDef - We parsed and verified that the specified
 /// Declarator is a well formed C++ inline method definition. Now lex its body
 /// and store its tokens for parsing after the C++ class is complete.
@@ -42,8 +35,9 @@
          "Current token not a '{', ':', '=', or 'try'!");
 
   MultiTemplateParamsArg TemplateParams(
-          TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->data() : 0,
-          TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->size() : 0);
+      TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->data()
+                                  : nullptr,
+      TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->size() : 0);
 
   NamedDecl *FnD;
   D.setFunctionDefinitionKind(DefinitionKind);
@@ -52,7 +46,7 @@
                                           TemplateParams);
   else {
     FnD = Actions.ActOnCXXMemberDeclarator(getCurScope(), AS, D,
-                                           TemplateParams, 0,
+                                           TemplateParams, nullptr,
                                            VS, ICIS_NoInit);
     if (FnD) {
       Actions.ProcessDeclAttributeList(getCurScope(), FnD, AccessAttrs);
@@ -69,30 +63,24 @@
 
   D.complete(FnD);
 
-  if (Tok.is(tok::equal)) {
-    ConsumeToken();
-
+  if (TryConsumeToken(tok::equal)) {
     if (!FnD) {
       SkipUntil(tok::semi);
-      return 0;
+      return nullptr;
     }
 
     bool Delete = false;
     SourceLocation KWLoc;
-    if (Tok.is(tok::kw_delete)) {
-      Diag(Tok, getLangOpts().CPlusPlus11 ?
-           diag::warn_cxx98_compat_deleted_function :
-           diag::ext_deleted_function);
-
-      KWLoc = ConsumeToken();
+    if (TryConsumeToken(tok::kw_delete, KWLoc)) {
+      Diag(KWLoc, getLangOpts().CPlusPlus11
+                      ? diag::warn_cxx98_compat_deleted_function
+                      : diag::ext_deleted_function);
       Actions.SetDeclDeleted(FnD, KWLoc);
       Delete = true;
-    } else if (Tok.is(tok::kw_default)) {
-      Diag(Tok, getLangOpts().CPlusPlus11 ?
-           diag::warn_cxx98_compat_defaulted_function :
-           diag::ext_defaulted_function);
-
-      KWLoc = ConsumeToken();
+    } else if (TryConsumeToken(tok::kw_default, KWLoc)) {
+      Diag(KWLoc, getLangOpts().CPlusPlus11
+                      ? diag::warn_cxx98_compat_defaulted_function
+                      : diag::ext_defaulted_function);
       Actions.SetDeclDefaulted(FnD, KWLoc);
     } else {
       llvm_unreachable("function definition after = not 'delete' or 'default'");
@@ -102,9 +90,9 @@
       Diag(KWLoc, diag::err_default_delete_in_multiple_declaration)
         << Delete;
       SkipUntil(tok::semi);
-    } else {
-      ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
-                       Delete ? "delete" : "default", tok::semi);
+    } else if (ExpectAndConsume(tok::semi, diag::err_expected_after,
+                                Delete ? "delete" : "default")) {
+      SkipUntil(tok::semi);
     }
 
     return FnD;
@@ -115,9 +103,9 @@
   // the tokens and store them for parsing at the end of the translation unit.
   if (getLangOpts().DelayedTemplateParsing &&
       DefinitionKind == FDK_Definition &&
-      !D.getDeclSpec().isConstexprSpecified() && 
-      !(FnD && getFunctionDecl(FnD) && 
-          getFunctionDecl(FnD)->getResultType()->getContainedAutoType()) &&
+      !D.getDeclSpec().isConstexprSpecified() &&
+      !(FnD && FnD->getAsFunction() &&
+        FnD->getAsFunction()->getReturnType()->getContainedAutoType()) &&
       ((Actions.CurContext->isDependentContext() ||
         (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
          TemplateInfo.Kind != ParsedTemplateInfo::ExplicitSpecialization)) &&
@@ -127,7 +115,7 @@
     LexTemplateFunctionForLateParsing(Toks);
 
     if (FnD) {
-      FunctionDecl *FD = getFunctionDecl(FnD);
+      FunctionDecl *FD = FnD->getAsFunction();
       Actions.CheckForFunctionRedefinition(FD);
       Actions.MarkAsLateParsedTemplate(FD, FnD, Toks);
     }
@@ -179,7 +167,7 @@
     // If you remove this, you can remove the code that clears the flag
     // after parsing the member.
     if (D.getDeclSpec().isFriendSpecified()) {
-      FunctionDecl *FD = getFunctionDecl(FnD);
+      FunctionDecl *FD = FnD->getAsFunction();
       Actions.CheckForFunctionRedefinition(FD);
       FD->setLateTemplateParsed(true);
     }
@@ -275,7 +263,8 @@
 /// delayed (such as default arguments) and parse them.
 void Parser::ParseLexedMethodDeclarations(ParsingClass &Class) {
   bool HasTemplateScope = !Class.TopLevelClass && Class.TemplateScope;
-  ParseScope ClassTemplateScope(this, Scope::TemplateParamScope, HasTemplateScope);
+  ParseScope ClassTemplateScope(this, Scope::TemplateParamScope,
+                                HasTemplateScope);
   TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
   if (HasTemplateScope) {
     Actions.ActOnReenterTemplateScope(getCurScope(), Class.TagOrTemplate);
@@ -288,14 +277,16 @@
   ParseScope ClassScope(this, Scope::ClassScope|Scope::DeclScope,
                         HasClassScope);
   if (HasClassScope)
-    Actions.ActOnStartDelayedMemberDeclarations(getCurScope(), Class.TagOrTemplate);
+    Actions.ActOnStartDelayedMemberDeclarations(getCurScope(),
+                                                Class.TagOrTemplate);
 
   for (size_t i = 0; i < Class.LateParsedDeclarations.size(); ++i) {
     Class.LateParsedDeclarations[i]->ParseLexedMethodDeclarations();
   }
 
   if (HasClassScope)
-    Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(), Class.TagOrTemplate);
+    Actions.ActOnFinishDelayedMemberDeclarations(getCurScope(),
+                                                 Class.TagOrTemplate);
 }
 
 void Parser::ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM) {
@@ -315,7 +306,7 @@
                             Scope::FunctionDeclarationScope | Scope::DeclScope);
   for (unsigned I = 0, N = LM.DefaultArgs.size(); I != N; ++I) {
     // Introduce the parameter into scope.
-    Actions.ActOnDelayedCXXMethodParameter(getCurScope(), 
+    Actions.ActOnDelayedCXXMethodParameter(getCurScope(),
                                            LM.DefaultArgs[I].Param);
 
     if (CachedTokens *Toks = LM.DefaultArgs[I].Toks) {
@@ -346,11 +337,10 @@
       } else
         DefArgResult = ParseAssignmentExpression();
       if (DefArgResult.isInvalid())
-        Actions.ActOnParamDefaultArgumentError(LM.DefaultArgs[I].Param);
+        Actions.ActOnParamDefaultArgumentError(LM.DefaultArgs[I].Param,
+                                               EqualLoc);
       else {
-        if (Tok.is(tok::cxx_defaultarg_end))
-          ConsumeToken();
-        else {
+        if (!TryConsumeToken(tok::cxx_defaultarg_end)) {
           // The last two tokens are the terminator and the saved value of
           // Tok; the last token in the default argument is the one before
           // those.
@@ -360,7 +350,7 @@
                            (*Toks)[Toks->size() - 3].getLocation());
         }
         Actions.ActOnParamDefaultArgument(LM.DefaultArgs[I].Param, EqualLoc,
-                                          DefArgResult.take());
+                                          DefArgResult.get());
       }
 
       assert(!PP.getSourceManager().isBeforeInTranslationUnit(origLoc,
@@ -372,7 +362,7 @@
         ConsumeAnyToken();
 
       delete Toks;
-      LM.DefaultArgs[I].Toks = 0;
+      LM.DefaultArgs[I].Toks = nullptr;
     }
   }
 
@@ -446,7 +436,7 @@
     // Error recovery.
     if (!Tok.is(tok::l_brace)) {
       FnScope.Exit();
-      Actions.ActOnFinishFunctionBody(LM.D, 0);
+      Actions.ActOnFinishFunctionBody(LM.D, nullptr);
       while (Tok.getLocation() != origLoc && Tok.isNot(tok::eof))
         ConsumeAnyToken();
       return;
@@ -464,7 +454,8 @@
   ParseFunctionStatementBody(LM.D, FnScope);
 
   // Clear the late-template-parsed bit if we set it before.
-  if (LM.D) getFunctionDecl(LM.D)->setLateTemplateParsed(false);
+  if (LM.D)
+    LM.D->getAsFunction()->setLateTemplateParsed(false);
 
   if (Tok.getLocation() != origLoc) {
     // Due to parsing error, we either went over the cached tokens or
@@ -477,6 +468,9 @@
       while (Tok.getLocation() != origLoc && Tok.isNot(tok::eof))
         ConsumeAnyToken();
   }
+
+  if (CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(LM.D))
+    Actions.ActOnFinishInlineMethodDef(MD);
 }
 
 /// ParseLexedMemberInitializers - We finished parsing the member specification
@@ -536,10 +530,13 @@
 
   SourceLocation EqualLoc;
 
+  Actions.ActOnStartCXXInClassMemberInitializer();
+
   ExprResult Init = ParseCXXMemberInitializer(MI.Field, /*IsFunction=*/false, 
                                               EqualLoc);
 
-  Actions.ActOnCXXInClassMemberInitializer(MI.Field, EqualLoc, Init.release());
+  Actions.ActOnFinishCXXInClassMemberInitializer(MI.Field, EqualLoc,
+                                                 Init.get());
 
   // The next token should be our artificial terminating EOF token.
   if (Tok.isNot(tok::eof)) {
@@ -580,6 +577,9 @@
 
     switch (Tok.getKind()) {
     case tok::eof:
+    case tok::annot_module_begin:
+    case tok::annot_module_end:
+    case tok::annot_module_include:
       // Ran out of tokens.
       return false;
 
@@ -675,7 +675,7 @@
                          /*StopAtSemi=*/true,
                          /*ConsumeFinalToken=*/false);
     if (Tok.isNot(tok::l_brace))
-      return Diag(Tok.getLocation(), diag::err_expected_lbrace);
+      return Diag(Tok.getLocation(), diag::err_expected) << tok::l_brace;
 
     Toks.push_back(Tok);
     ConsumeBrace();
@@ -708,8 +708,8 @@
       Toks.push_back(Tok);
       ConsumeParen();
       if (!ConsumeAndStoreUntil(tok::r_paren, Toks, /*StopAtSemi=*/true)) {
-        Diag(Tok.getLocation(), diag::err_expected_rparen);
-        Diag(OpenLoc, diag::note_matching) << "(";
+        Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
+        Diag(OpenLoc, diag::note_matching) << tok::l_paren;
         return true;
       }
     }
@@ -756,13 +756,15 @@
                                 /*ConsumeFinalToken=*/false)) {
         // We're not just missing the initializer, we're also missing the
         // function body!
-        return Diag(Tok.getLocation(), diag::err_expected_lbrace);
+        return Diag(Tok.getLocation(), diag::err_expected) << tok::l_brace;
       }
     } else if (Tok.isNot(tok::l_paren) && Tok.isNot(tok::l_brace)) {
       // We found something weird in a mem-initializer-id.
-      return Diag(Tok.getLocation(), getLangOpts().CPlusPlus11
-                                         ? diag::err_expected_lparen_or_lbrace
-                                         : diag::err_expected_lparen);
+      if (getLangOpts().CPlusPlus11)
+        return Diag(Tok.getLocation(), diag::err_expected_either)
+               << tok::l_paren << tok::l_brace;
+      else
+        return Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
     }
 
     tok::TokenKind kind = Tok.getKind();
@@ -784,11 +786,10 @@
     // Grab the initializer (or the subexpression of the template argument).
     // FIXME: If we support lambdas here, we'll need to set StopAtSemi to false
     //        if we might be inside the braces of a lambda-expression.
-    if (!ConsumeAndStoreUntil(IsLParen ? tok::r_paren : tok::r_brace,
-                              Toks, /*StopAtSemi=*/true)) {
-      Diag(Tok, IsLParen ? diag::err_expected_rparen :
-                           diag::err_expected_rbrace);
-      Diag(OpenLoc, diag::note_matching) << (IsLParen ? "(" : "{");
+    tok::TokenKind CloseKind = IsLParen ? tok::r_paren : tok::r_brace;
+    if (!ConsumeAndStoreUntil(CloseKind, Toks, /*StopAtSemi=*/true)) {
+      Diag(Tok, diag::err_expected) << CloseKind;
+      Diag(OpenLoc, diag::note_matching) << kind;
       return true;
     }
 
@@ -822,7 +823,8 @@
       ConsumeBrace();
       return false;
     } else if (!MightBeTemplateArgument) {
-      return Diag(Tok.getLocation(), diag::err_expected_lbrace_or_comma);
+      return Diag(Tok.getLocation(), diag::err_expected_either) << tok::l_brace
+                                                                << tok::comma;
     }
   }
 }
@@ -836,8 +838,9 @@
   ConsumeToken();
 
   while (Tok.isNot(tok::colon)) {
-    if (!ConsumeAndStoreUntil(tok::question, tok::colon, Toks, /*StopAtSemi*/true,
-                              /*ConsumeFinalToken*/false))
+    if (!ConsumeAndStoreUntil(tok::question, tok::colon, Toks,
+                              /*StopAtSemi=*/true,
+                              /*ConsumeFinalToken=*/false))
       return false;
 
     // If we found a nested conditional, consume it.
@@ -925,15 +928,15 @@
                                                ? tok::semi : tok::r_paren);
         Sema::TentativeAnalysisScope Scope(Actions);
 
-        TPResult Result = TPResult::Error();
+        TPResult Result = TPResult::Error;
         ConsumeToken();
         switch (CIK) {
         case CIK_DefaultInitializer:
           Result = TryParseInitDeclaratorList();
           // If we parsed a complete, ambiguous init-declarator-list, this
           // is only syntactically-valid if it's followed by a semicolon.
-          if (Result == TPResult::Ambiguous() && Tok.isNot(tok::semi))
-            Result = TPResult::False();
+          if (Result == TPResult::Ambiguous && Tok.isNot(tok::semi))
+            Result = TPResult::False;
           break;
 
         case CIK_DefaultArgument:
@@ -942,13 +945,13 @@
               &InvalidAsDeclaration, /*VersusTemplateArgument*/true);
           // If this is an expression or a declaration with a missing
           // 'typename', assume it's not a declaration.
-          if (Result == TPResult::Ambiguous() && InvalidAsDeclaration)
-            Result = TPResult::False();
+          if (Result == TPResult::Ambiguous && InvalidAsDeclaration)
+            Result = TPResult::False;
           break;
         }
 
         // If what follows could be a declaration, it is a declaration.
-        if (Result != TPResult::False() && Result != TPResult::Error()) {
+        if (Result != TPResult::False && Result != TPResult::Error) {
           PA.Revert();
           return true;
         }
@@ -965,6 +968,9 @@
       goto consume_token;
 
     case tok::eof:
+    case tok::annot_module_begin:
+    case tok::annot_module_end:
+    case tok::annot_module_include:
       // Ran out of tokens.
       return false;
 
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 77c1fe9..62d4376 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -13,10 +13,12 @@
 
 #include "clang/Parse/Parser.h"
 #include "RAIIObjectsForParser.h"
+#include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/Basic/AddressSpaces.h"
+#include "clang/Basic/Attributes.h"
 #include "clang/Basic/CharInfo.h"
-#include "clang/Basic/OpenCL.h"
+#include "clang/Basic/TargetInfo.h"
 #include "clang/Parse/ParseDiagnostic.h"
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/ParsedTemplate.h"
@@ -51,7 +53,7 @@
     DS.addAttributes(Attrs->getList());
   ParseSpecifierQualifierList(DS, AS, DSC);
   if (OwnedType)
-    *OwnedType = DS.isTypeSpecOwned() ? DS.getRepAsDecl() : 0;
+    *OwnedType = DS.isTypeSpecOwned() ? DS.getRepAsDecl() : nullptr;
 
   // Parse the abstract-declarator, if present.
   Declarator DeclaratorInfo(DS, Context);
@@ -69,9 +71,11 @@
 /// isAttributeLateParsed - Return true if the attribute has arguments that
 /// require late parsing.
 static bool isAttributeLateParsed(const IdentifierInfo &II) {
+#define CLANG_ATTR_LATE_PARSED_LIST
     return llvm::StringSwitch<bool>(II.getName())
-#include "clang/Parse/AttrLateParsed.inc"
+#include "clang/Parse/AttrParserStringSwitches.inc"
         .Default(false);
+#undef CLANG_ATTR_LATE_PARSED_LIST
 }
 
 /// ParseGNUAttributes - Parse a non-empty attributes list.
@@ -117,7 +121,8 @@
 /// We follow the C++ model, but don't allow junk after the identifier.
 void Parser::ParseGNUAttributes(ParsedAttributes &attrs,
                                 SourceLocation *endLoc,
-                                LateParsedAttrList *LateAttrs) {
+                                LateParsedAttrList *LateAttrs,
+                                Declarator *D) {
   assert(Tok.is(tok::kw___attribute) && "Not a GNU attribute list!");
 
   while (Tok.is(tok::kw___attribute)) {
@@ -132,49 +137,54 @@
       return;
     }
     // Parse the attribute-list. e.g. __attribute__(( weak, alias("__f") ))
-    while (Tok.is(tok::identifier) || isDeclarationSpecifier() ||
-           Tok.is(tok::comma)) {
-      if (Tok.is(tok::comma)) {
-        // allows for empty/non-empty attributes. ((__vector_size__(16),,,,))
-        ConsumeToken();
+    while (true) {
+      // Allow empty/non-empty attributes. ((__vector_size__(16),,,,))
+      if (TryConsumeToken(tok::comma))
         continue;
-      }
-      // we have an identifier or declaration specifier (const, int, etc.)
+
+      // Expect an identifier or declaration specifier (const, int, etc.)
+      if (Tok.isNot(tok::identifier) && !isDeclarationSpecifier())
+        break;
+
       IdentifierInfo *AttrName = Tok.getIdentifierInfo();
       SourceLocation AttrNameLoc = ConsumeToken();
 
-      if (Tok.is(tok::l_paren)) {
-        // handle "parameterized" attributes
-        if (LateAttrs && isAttributeLateParsed(*AttrName)) {
-          LateParsedAttribute *LA =
-            new LateParsedAttribute(this, *AttrName, AttrNameLoc);
-          LateAttrs->push_back(LA);
-
-          // Attributes in a class are parsed at the end of the class, along
-          // with other late-parsed declarations.
-          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);
-
-          Token Eof;
-          Eof.startToken();
-          Eof.setLocation(Tok.getLocation());
-          LA->Toks.push_back(Eof);
-        } else {
-          ParseGNUAttributeArgs(AttrName, AttrNameLoc, attrs, endLoc,
-                                0, SourceLocation(), AttributeList::AS_GNU);
-        }
-      } else {
-        attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0,
+      if (Tok.isNot(tok::l_paren)) {
+        attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
                      AttributeList::AS_GNU);
+        continue;
       }
+
+      // Handle "parameterized" attributes
+      if (!LateAttrs || !isAttributeLateParsed(*AttrName)) {
+        ParseGNUAttributeArgs(AttrName, AttrNameLoc, attrs, endLoc, nullptr,
+                              SourceLocation(), AttributeList::AS_GNU, D);
+        continue;
+      }
+
+      // Handle attributes with arguments that require late parsing.
+      LateParsedAttribute *LA =
+          new LateParsedAttribute(this, *AttrName, AttrNameLoc);
+      LateAttrs->push_back(LA);
+
+      // Attributes in a class are parsed at the end of the class, along
+      // with other late-parsed declarations.
+      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);
+
+      Token Eof;
+      Eof.startToken();
+      Eof.setLocation(Tok.getLocation());
+      LA->Toks.push_back(Eof);
     }
-    if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
+
+    if (ExpectAndConsume(tok::r_paren))
       SkipUntil(tok::r_paren, StopAtSemi);
     SourceLocation Loc = Tok.getLocation();
-    if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
+    if (ExpectAndConsume(tok::r_paren))
       SkipUntil(tok::r_paren, StopAtSemi);
     if (endLoc)
       *endLoc = Loc;
@@ -190,16 +200,30 @@
 
 /// \brief Determine whether the given attribute has an identifier argument.
 static bool attributeHasIdentifierArg(const IdentifierInfo &II) {
+#define CLANG_ATTR_IDENTIFIER_ARG_LIST
   return llvm::StringSwitch<bool>(normalizeAttrName(II.getName()))
-#include "clang/Parse/AttrIdentifierArg.inc"
+#include "clang/Parse/AttrParserStringSwitches.inc"
            .Default(false);
+#undef CLANG_ATTR_IDENTIFIER_ARG_LIST
 }
 
 /// \brief Determine whether the given attribute parses a type argument.
 static bool attributeIsTypeArgAttr(const IdentifierInfo &II) {
+#define CLANG_ATTR_TYPE_ARG_LIST
   return llvm::StringSwitch<bool>(normalizeAttrName(II.getName()))
-#include "clang/Parse/AttrTypeArg.inc"
+#include "clang/Parse/AttrParserStringSwitches.inc"
            .Default(false);
+#undef CLANG_ATTR_TYPE_ARG_LIST
+}
+
+/// \brief Determine whether the given attribute requires parsing its arguments
+/// in an unevaluated context or not.
+static bool attributeParsedArgsUnevaluated(const IdentifierInfo &II) {
+#define CLANG_ATTR_ARG_CONTEXT_LIST
+  return llvm::StringSwitch<bool>(normalizeAttrName(II.getName()))
+#include "clang/Parse/AttrParserStringSwitches.inc"
+           .Default(false);
+#undef CLANG_ATTR_ARG_CONTEXT_LIST
 }
 
 IdentifierLoc *Parser::ParseIdentifierLoc() {
@@ -214,7 +238,10 @@
 void Parser::ParseAttributeWithTypeArg(IdentifierInfo &AttrName,
                                        SourceLocation AttrNameLoc,
                                        ParsedAttributes &Attrs,
-                                       SourceLocation *EndLoc) {
+                                       SourceLocation *EndLoc,
+                                       IdentifierInfo *ScopeName,
+                                       SourceLocation ScopeLoc,
+                                       AttributeList::Syntax Syntax) {
   BalancedDelimiterTracker Parens(*this, tok::l_paren);
   Parens.consumeOpen();
 
@@ -230,65 +257,31 @@
 
   if (T.isUsable())
     Attrs.addNewTypeAttr(&AttrName,
-                         SourceRange(AttrNameLoc, Parens.getCloseLocation()), 0,
-                         AttrNameLoc, T.get(), AttributeList::AS_GNU);
+                         SourceRange(AttrNameLoc, Parens.getCloseLocation()),
+                         ScopeName, ScopeLoc, T.get(), Syntax);
   else
     Attrs.addNew(&AttrName, SourceRange(AttrNameLoc, Parens.getCloseLocation()),
-                 0, AttrNameLoc, 0, 0, AttributeList::AS_GNU);
+                 ScopeName, ScopeLoc, nullptr, 0, Syntax);
 }
 
-/// Parse the arguments to a parameterized GNU attribute or
-/// a C++11 attribute in "gnu" namespace.
-void Parser::ParseGNUAttributeArgs(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);
-
-  // Availability attributes have their own grammar.
-  // FIXME: All these cases fail to pass in the syntax and scope, and might be
-  // written as C++11 gnu:: attributes.
-  if (AttrKind == AttributeList::AT_Availability) {
-    ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc);
-    return;
-  }
-  // Thread safety attributes are parsed in an unevaluated context.
-  // FIXME: Share the bulk of the parsing code here and just pull out
-  // the unevaluated context.
-  if (IsThreadSafetyAttribute(AttrName->getName())) {
-    ParseThreadSafetyAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc);
-    return;
-  }
-  // Type safety attributes have their own grammar.
-  if (AttrKind == AttributeList::AT_TypeTagForDatatype) {
-    ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc);
-    return;
-  }
-  // Some attributes expect solely a type parameter.
-  if (attributeIsTypeArgAttr(*AttrName)) {
-    ParseAttributeWithTypeArg(*AttrName, AttrNameLoc, Attrs, EndLoc);
-    return;
-  }
-
+unsigned Parser::ParseAttributeArgsCommon(
+    IdentifierInfo *AttrName, SourceLocation AttrNameLoc,
+    ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName,
+    SourceLocation ScopeLoc, AttributeList::Syntax Syntax) {
   // Ignore the left paren location for now.
   ConsumeParen();
 
   ArgsVector ArgExprs;
-
   if (Tok.is(tok::identifier)) {
     // If this attribute wants an 'identifier' argument, make it so.
     bool IsIdentifierArg = attributeHasIdentifierArg(*AttrName);
+    AttributeList::Kind AttrKind =
+        AttributeList::getKind(AttrName, ScopeName, Syntax);
 
     // If we don't know how to parse this attribute, but this is the only
     // token in this argument, assume it's meant to be an identifier.
-    if (AttrKind == AttributeList::UnknownAttribute) {
+    if (AttrKind == AttributeList::UnknownAttribute ||
+        AttrKind == AttributeList::IgnoredAttribute) {
       const Token &Next = NextToken();
       IsIdentifierArg = Next.is(tok::r_paren) || Next.is(tok::comma);
     }
@@ -303,112 +296,117 @@
       ConsumeToken();
 
     // Parse the non-empty comma-separated list of expressions.
-    while (1) {
+    do {
+      std::unique_ptr<EnterExpressionEvaluationContext> Unevaluated;
+      if (attributeParsedArgsUnevaluated(*AttrName))
+        Unevaluated.reset(
+            new EnterExpressionEvaluationContext(Actions, Sema::Unevaluated));
+
       ExprResult ArgExpr(ParseAssignmentExpression());
       if (ArgExpr.isInvalid()) {
         SkipUntil(tok::r_paren, StopAtSemi);
-        return;
+        return 0;
       }
-      ArgExprs.push_back(ArgExpr.release());
-      if (Tok.isNot(tok::comma))
-        break;
-      ConsumeToken(); // Eat the comma, move to the next argument
-    }
+      ArgExprs.push_back(ArgExpr.get());
+      // Eat the comma, move to the next argument
+    } while (TryConsumeToken(tok::comma));
   }
 
   SourceLocation RParen = Tok.getLocation();
-  if (!ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) {
+  if (!ExpectAndConsume(tok::r_paren)) {
     SourceLocation AttrLoc = ScopeLoc.isValid() ? ScopeLoc : AttrNameLoc;
     Attrs.addNew(AttrName, SourceRange(AttrLoc, RParen), ScopeName, ScopeLoc,
                  ArgExprs.data(), ArgExprs.size(), Syntax);
   }
+
+  if (EndLoc)
+    *EndLoc = RParen;
+
+  return static_cast<unsigned>(ArgExprs.size());
 }
 
-/// \brief Parses a single argument for a declspec, including the
-/// surrounding parens.
-void Parser::ParseMicrosoftDeclSpecWithSingleArg(IdentifierInfo *AttrName,
-                                                 SourceLocation AttrNameLoc,
-                                                 ParsedAttributes &Attrs)
-{
-  BalancedDelimiterTracker T(*this, tok::l_paren);
-  if (T.expectAndConsume(diag::err_expected_lparen_after,
-                         AttrName->getNameStart(), tok::r_paren))
-    return;
+/// Parse the arguments to a parameterized GNU attribute or
+/// a C++11 attribute in "gnu" namespace.
+void Parser::ParseGNUAttributeArgs(IdentifierInfo *AttrName,
+                                   SourceLocation AttrNameLoc,
+                                   ParsedAttributes &Attrs,
+                                   SourceLocation *EndLoc,
+                                   IdentifierInfo *ScopeName,
+                                   SourceLocation ScopeLoc,
+                                   AttributeList::Syntax Syntax,
+                                   Declarator *D) {
 
-  ExprResult ArgExpr(ParseConstantExpression());
-  if (ArgExpr.isInvalid()) {
-    T.skipToEnd();
+  assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
+
+  AttributeList::Kind AttrKind =
+      AttributeList::getKind(AttrName, ScopeName, Syntax);
+
+  if (AttrKind == AttributeList::AT_Availability) {
+    ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
+                               ScopeLoc, Syntax);
+    return;
+  } else if (AttrKind == AttributeList::AT_ObjCBridgeRelated) {
+    ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
+                                    ScopeName, ScopeLoc, Syntax);
+    return;
+  } else if (AttrKind == AttributeList::AT_TypeTagForDatatype) {
+    ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
+                                     ScopeName, ScopeLoc, Syntax);
+    return;
+  } else if (attributeIsTypeArgAttr(*AttrName)) {
+    ParseAttributeWithTypeArg(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
+                              ScopeLoc, Syntax);
     return;
   }
-  ArgsUnion ExprList = ArgExpr.take();
-  Attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, &ExprList, 1,
-               AttributeList::AS_Declspec);
 
-  T.consumeClose();
+  // These may refer to the function arguments, but need to be parsed early to
+  // participate in determining whether it's a redeclaration.
+  std::unique_ptr<ParseScope> PrototypeScope;
+  if (AttrName->isStr("enable_if") && D && D->isFunctionDeclarator()) {
+    DeclaratorChunk::FunctionTypeInfo FTI = D->getFunctionTypeInfo();
+    PrototypeScope.reset(new ParseScope(this, Scope::FunctionPrototypeScope |
+                                        Scope::FunctionDeclarationScope |
+                                        Scope::DeclScope));
+    for (unsigned i = 0; i != FTI.NumParams; ++i) {
+      ParmVarDecl *Param = cast<ParmVarDecl>(FTI.Params[i].Param);
+      Actions.ActOnReenterCXXMethodParameter(getCurScope(), Param);
+    }
+  }
+
+  ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
+                           ScopeLoc, Syntax);
 }
 
-/// \brief Determines whether a declspec is a "simple" one requiring no
-/// arguments.
-bool Parser::IsSimpleMicrosoftDeclSpec(IdentifierInfo *Ident) {
-  return llvm::StringSwitch<bool>(Ident->getName())
-    .Case("dllimport", true)
-    .Case("dllexport", true)
-    .Case("noreturn", true)
-    .Case("nothrow", true)
-    .Case("noinline", true)
-    .Case("naked", true)
-    .Case("appdomain", true)
-    .Case("process", true)
-    .Case("jitintrinsic", true)
-    .Case("noalias", true)
-    .Case("restrict", true)
-    .Case("novtable", true)
-    .Case("selectany", true)
-    .Case("thread", true)
-    .Case("safebuffers", true )
-    .Default(false);
-}
+bool Parser::ParseMicrosoftDeclSpecArgs(IdentifierInfo *AttrName,
+                                        SourceLocation AttrNameLoc,
+                                        ParsedAttributes &Attrs) {
+  // If the attribute isn't known, we will not attempt to parse any
+  // arguments.
+  if (!hasAttribute(AttrSyntax::Declspec, nullptr, AttrName,
+                    getTargetInfo().getTriple(), getLangOpts())) {
+    // Eat the left paren, then skip to the ending right paren.
+    ConsumeParen();
+    SkipUntil(tok::r_paren);
+    return false;
+  }
 
-/// \brief Attempts to parse a declspec which is not simple (one that takes
-/// parameters).  Will return false if we properly handled the declspec, or
-/// true if it is an unknown declspec.
-void Parser::ParseComplexMicrosoftDeclSpec(IdentifierInfo *Ident,
-                                           SourceLocation Loc,
-                                           ParsedAttributes &Attrs) {
-  // Try to handle the easy case first -- these declspecs all take a single
-  // parameter as their argument.
-  if (llvm::StringSwitch<bool>(Ident->getName())
-      .Case("uuid", true)
-      .Case("align", true)
-      .Case("allocate", true)
-      .Default(false)) {
-    ParseMicrosoftDeclSpecWithSingleArg(Ident, Loc, Attrs);
-  } else if (Ident->getName() == "deprecated") {
-    // The deprecated declspec has an optional single argument, so we will
-    // check for a l-paren to decide whether we should parse an argument or
-    // not.
-    if (Tok.getKind() == tok::l_paren)
-      ParseMicrosoftDeclSpecWithSingleArg(Ident, Loc, Attrs);
-    else
-      Attrs.addNew(Ident, Loc, 0, Loc, 0, 0, AttributeList::AS_Declspec);
-  } else if (Ident->getName() == "property") {
+  SourceLocation OpenParenLoc = Tok.getLocation();
+
+  if (AttrName->getName() == "property") {
     // The property declspec is more complex in that it can take one or two
     // assignment expressions as a parameter, but the lhs of the assignment
     // must be named get or put.
-    if (Tok.isNot(tok::l_paren)) {
-      Diag(Tok.getLocation(), diag::err_expected_lparen_after)
-        << Ident->getNameStart();
-      return;
-    }
+
     BalancedDelimiterTracker T(*this, tok::l_paren);
     T.expectAndConsume(diag::err_expected_lparen_after,
-                       Ident->getNameStart(), tok::r_paren);
+                       AttrName->getNameStart(), tok::r_paren);
 
     enum AccessorKind {
       AK_Invalid = -1,
-      AK_Put = 0, AK_Get = 1 // indices into AccessorNames
+      AK_Put = 0,
+      AK_Get = 1 // indices into AccessorNames
     };
-    IdentifierInfo *AccessorNames[] = { 0, 0 };
+    IdentifierInfo *AccessorNames[] = {nullptr, nullptr};
     bool HasInvalidAccessor = false;
 
     // Parse the accessor specifications.
@@ -417,8 +415,9 @@
       if (!Tok.is(tok::identifier)) {
         // If the user wrote a completely empty list, use a special diagnostic.
         if (Tok.is(tok::r_paren) && !HasInvalidAccessor &&
-            AccessorNames[AK_Put] == 0 && AccessorNames[AK_Get] == 0) {
-          Diag(Loc, diag::err_ms_property_no_getter_or_putter);
+            AccessorNames[AK_Put] == nullptr &&
+            AccessorNames[AK_Get] == nullptr) {
+          Diag(AttrNameLoc, diag::err_ms_property_no_getter_or_putter);
           break;
         }
 
@@ -434,39 +433,38 @@
       } else if (KindStr == "put") {
         Kind = AK_Put;
 
-      // Recover from the common mistake of using 'set' instead of 'put'.
+        // Recover from the common mistake of using 'set' instead of 'put'.
       } else if (KindStr == "set") {
         Diag(KindLoc, diag::err_ms_property_has_set_accessor)
-          << FixItHint::CreateReplacement(KindLoc, "put");
+            << FixItHint::CreateReplacement(KindLoc, "put");
         Kind = AK_Put;
 
-      // Handle the mistake of forgetting the accessor kind by skipping
-      // this accessor.
+        // Handle the mistake of forgetting the accessor kind by skipping
+        // this accessor.
       } else if (NextToken().is(tok::comma) || NextToken().is(tok::r_paren)) {
         Diag(KindLoc, diag::err_ms_property_missing_accessor_kind);
         ConsumeToken();
         HasInvalidAccessor = true;
         goto next_property_accessor;
 
-      // Otherwise, complain about the unknown accessor kind.
+        // Otherwise, complain about the unknown accessor kind.
       } else {
         Diag(KindLoc, diag::err_ms_property_unknown_accessor);
         HasInvalidAccessor = true;
         Kind = AK_Invalid;
 
         // Try to keep parsing unless it doesn't look like an accessor spec.
-        if (!NextToken().is(tok::equal)) break;
+        if (!NextToken().is(tok::equal))
+          break;
       }
 
       // Consume the identifier.
       ConsumeToken();
 
       // Consume the '='.
-      if (Tok.is(tok::equal)) {
-        ConsumeToken();
-      } else {
+      if (!TryConsumeToken(tok::equal)) {
         Diag(Tok.getLocation(), diag::err_ms_property_expected_equal)
-          << KindStr;
+            << KindStr;
         break;
       }
 
@@ -478,7 +476,7 @@
 
       if (Kind == AK_Invalid) {
         // Just drop invalid accessors.
-      } else if (AccessorNames[Kind] != NULL) {
+      } else if (AccessorNames[Kind] != nullptr) {
         // Complain about the repeated accessor, ignore it, and keep parsing.
         Diag(KindLoc, diag::err_ms_property_duplicate_accessor) << KindStr;
       } else {
@@ -488,41 +486,38 @@
 
     next_property_accessor:
       // Keep processing accessors until we run out.
-      if (Tok.is(tok::comma)) {
-        ConsumeAnyToken();
+      if (TryConsumeToken(tok::comma))
         continue;
 
       // If we run into the ')', stop without consuming it.
-      } else if (Tok.is(tok::r_paren)) {
+      if (Tok.is(tok::r_paren))
         break;
-      } else {
-        Diag(Tok.getLocation(), diag::err_ms_property_expected_comma_or_rparen);
-        break;
-      }
+
+      Diag(Tok.getLocation(), diag::err_ms_property_expected_comma_or_rparen);
+      break;
     }
 
     // Only add the property attribute if it was well-formed.
-    if (!HasInvalidAccessor) {
-      Attrs.addNewPropertyAttr(Ident, Loc, 0, SourceLocation(),
+    if (!HasInvalidAccessor)
+      Attrs.addNewPropertyAttr(AttrName, AttrNameLoc, nullptr, SourceLocation(),
                                AccessorNames[AK_Get], AccessorNames[AK_Put],
                                AttributeList::AS_Declspec);
-    }
     T.skipToEnd();
-  } else {
-    // We don't recognize this as a valid declspec, but instead of creating the
-    // attribute and allowing sema to warn about it, we will warn here instead.
-    // This is because some attributes have multiple spellings, but we need to
-    // disallow that for declspecs (such as align vs aligned).  If we made the
-    // attribute, we'd have to split the valid declspec spelling logic into
-    // both locations.
-    Diag(Loc, diag::warn_ms_declspec_unknown) << Ident;
-
-    // If there's an open paren, we should eat the open and close parens under
-    // the assumption that this unknown declspec has parameters.
-    BalancedDelimiterTracker T(*this, tok::l_paren);
-    if (!T.consumeOpen())
-      T.skipToEnd();
+    return !HasInvalidAccessor;
   }
+
+  unsigned NumArgs =
+      ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, nullptr, nullptr,
+                               SourceLocation(), AttributeList::AS_Declspec);
+
+  // If this attribute's args were parsed, and it was expected to have
+  // arguments but none were provided, emit a diagnostic.
+  const AttributeList *Attr = Attrs.getList();
+  if (Attr && Attr->getMaxArgs() && !NumArgs) {
+    Diag(OpenParenLoc, diag::err_attribute_requires_arguments) << AttrName;
+    return false;
+  }
+  return true;
 }
 
 /// [MS] decl-specifier:
@@ -542,7 +537,11 @@
 
   // An empty declspec is perfectly legal and should not warn.  Additionally,
   // you can specify multiple attributes per declspec.
-  while (Tok.getKind() != tok::r_paren) {
+  while (Tok.isNot(tok::r_paren)) {
+    // Attribute not present.
+    if (TryConsumeToken(tok::comma))
+      continue;
+
     // We expect either a well-known identifier or a generic string.  Anything
     // else is a malformed declspec.
     bool IsString = Tok.getKind() == tok::string_literal ? true : false;
@@ -570,17 +569,19 @@
       AttrNameLoc = ConsumeToken();
     }
 
-    if (IsString || IsSimpleMicrosoftDeclSpec(AttrName))
-      // If we have a generic string, we will allow it because there is no
-      // documented list of allowable string declspecs, but we know they exist
-      // (for instance, SAL declspecs in older versions of MSVC).
-      //
-      // Alternatively, if the identifier is a simple one, then it requires no
-      // arguments and can be turned into an attribute directly.
-      Attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0,
+    bool AttrHandled = false;
+
+    // Parse attribute arguments.
+    if (Tok.is(tok::l_paren))
+      AttrHandled = ParseMicrosoftDeclSpecArgs(AttrName, AttrNameLoc, Attrs);
+    else if (AttrName->getName() == "property")
+      // The property attribute must have an argument list.
+      Diag(Tok.getLocation(), diag::err_expected_lparen_after)
+          << AttrName->getName();
+
+    if (!AttrHandled)
+      Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
                    AttributeList::AS_Declspec);
-    else
-      ParseComplexMicrosoftDeclSpec(AttrName, AttrNameLoc, Attrs);
   }
   T.consumeClose();
 }
@@ -594,7 +595,7 @@
          Tok.is(tok::kw___sptr) || Tok.is(tok::kw___uptr)) {
     IdentifierInfo *AttrName = Tok.getIdentifierInfo();
     SourceLocation AttrNameLoc = ConsumeToken();
-    attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0,
+    attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
                  AttributeList::AS_Keyword);
   }
 }
@@ -604,7 +605,7 @@
   while (Tok.is(tok::kw___pascal)) {
     IdentifierInfo *AttrName = Tok.getIdentifierInfo();
     SourceLocation AttrNameLoc = ConsumeToken();
-    attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0,
+    attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
                  AttributeList::AS_Keyword);
   }
 }
@@ -614,61 +615,16 @@
   while (Tok.is(tok::kw___kernel)) {
     IdentifierInfo *AttrName = Tok.getIdentifierInfo();
     SourceLocation AttrNameLoc = ConsumeToken();
-    attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0,
+    attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
                  AttributeList::AS_Keyword);
   }
 }
 
-void Parser::ParseOpenCLQualifiers(DeclSpec &DS) {
-  // FIXME: The mapping from attribute spelling to semantics should be
-  //        performed in Sema, not here.
-  SourceLocation Loc = Tok.getLocation();
-  switch(Tok.getKind()) {
-    // OpenCL qualifiers:
-    case tok::kw___private:
-    case tok::kw_private:
-      DS.getAttributes().addNewInteger(
-          Actions.getASTContext(),
-          PP.getIdentifierInfo("address_space"), Loc, 0);
-      break;
-
-    case tok::kw___global:
-      DS.getAttributes().addNewInteger(
-          Actions.getASTContext(),
-          PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_global);
-      break;
-
-    case tok::kw___local:
-      DS.getAttributes().addNewInteger(
-          Actions.getASTContext(),
-          PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_local);
-      break;
-
-    case tok::kw___constant:
-      DS.getAttributes().addNewInteger(
-          Actions.getASTContext(),
-          PP.getIdentifierInfo("address_space"), Loc, LangAS::opencl_constant);
-      break;
-
-    case tok::kw___read_only:
-      DS.getAttributes().addNewInteger(
-          Actions.getASTContext(),
-          PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_only);
-      break;
-
-    case tok::kw___write_only:
-      DS.getAttributes().addNewInteger(
-          Actions.getASTContext(),
-          PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_write_only);
-      break;
-
-    case tok::kw___read_write:
-      DS.getAttributes().addNewInteger(
-          Actions.getASTContext(),
-          PP.getIdentifierInfo("opencl_image_access"), Loc, CLIA_read_write);
-      break;
-    default: break;
-  }
+void Parser::ParseOpenCLQualifiers(ParsedAttributes &Attrs) {
+  IdentifierInfo *AttrName = Tok.getIdentifierInfo();
+  SourceLocation AttrNameLoc = Tok.getLocation();
+  Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
+               AttributeList::AS_Keyword);
 }
 
 /// \brief Parse a version number.
@@ -803,7 +759,10 @@
 void Parser::ParseAvailabilityAttribute(IdentifierInfo &Availability,
                                         SourceLocation AvailabilityLoc,
                                         ParsedAttributes &attrs,
-                                        SourceLocation *endLoc) {
+                                        SourceLocation *endLoc,
+                                        IdentifierInfo *ScopeName,
+                                        SourceLocation ScopeLoc,
+                                        AttributeList::Syntax Syntax) {
   enum { Introduced, Deprecated, Obsoleted, Unknown };
   AvailabilityChange Changes[Unknown];
   ExprResult MessageExpr;
@@ -811,7 +770,7 @@
   // Opening '('.
   BalancedDelimiterTracker T(*this, tok::l_paren);
   if (T.consumeOpen()) {
-    Diag(Tok, diag::err_expected_lparen);
+    Diag(Tok, diag::err_expected) << tok::l_paren;
     return;
   }
 
@@ -824,8 +783,10 @@
   IdentifierLoc *Platform = ParseIdentifierLoc();
 
   // Parse the ',' following the platform name.
-  if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::r_paren))
+  if (ExpectAndConsume(tok::comma)) {
+    SkipUntil(tok::r_paren, StopAtSemi);
     return;
+  }
 
   // If we haven't grabbed the pointers for the identifiers
   // "introduced", "deprecated", and "obsoleted", do so now.
@@ -854,29 +815,34 @@
           << Keyword << SourceRange(UnavailableLoc);
       }
       UnavailableLoc = KeywordLoc;
-
-      if (Tok.isNot(tok::comma))
-        break;
-
-      ConsumeToken();
       continue;
     }
 
     if (Tok.isNot(tok::equal)) {
-      Diag(Tok, diag::err_expected_equal_after)
-        << Keyword;
+      Diag(Tok, diag::err_expected_after) << Keyword << tok::equal;
       SkipUntil(tok::r_paren, StopAtSemi);
       return;
     }
     ConsumeToken();
     if (Keyword == Ident_message) {
-      if (Tok.isNot(tok::string_literal)) { // Also reject wide string literals.
+      if (Tok.isNot(tok::string_literal)) {
         Diag(Tok, diag::err_expected_string_literal)
           << /*Source='availability attribute'*/2;
         SkipUntil(tok::r_paren, StopAtSemi);
         return;
       }
       MessageExpr = ParseStringLiteralExpression();
+      // Also reject wide string literals.
+      if (StringLiteral *MessageStringLiteral =
+              cast_or_null<StringLiteral>(MessageExpr.get())) {
+        if (MessageStringLiteral->getCharByteWidth() != 1) {
+          Diag(MessageStringLiteral->getSourceRange().getBegin(),
+               diag::err_expected_string_literal)
+            << /*Source='availability attribute'*/ 2;
+          SkipUntil(tok::r_paren, StopAtSemi);
+          return;
+        }
+      }
       break;
     }
 
@@ -914,11 +880,7 @@
         << Keyword << VersionRange;
     }
 
-    if (Tok.isNot(tok::comma))
-      break;
-
-    ConsumeToken();
-  } while (true);
+  } while (TryConsumeToken(tok::comma));
 
   // Closing ')'.
   if (T.consumeClose())
@@ -949,15 +911,97 @@
   // Record this attribute
   attrs.addNew(&Availability,
                SourceRange(AvailabilityLoc, T.getCloseLocation()),
-               0, AvailabilityLoc,
+               ScopeName, ScopeLoc,
                Platform,
                Changes[Introduced],
                Changes[Deprecated],
                Changes[Obsoleted],
-               UnavailableLoc, MessageExpr.take(),
-               AttributeList::AS_GNU);
+               UnavailableLoc, MessageExpr.get(),
+               Syntax);
 }
 
+/// \brief Parse the contents of the "objc_bridge_related" attribute.
+/// objc_bridge_related '(' related_class ',' opt-class_method ',' opt-instance_method ')'
+/// related_class:
+///     Identifier
+///
+/// opt-class_method:
+///     Identifier: | <empty>
+///
+/// opt-instance_method:
+///     Identifier | <empty>
+///
+void Parser::ParseObjCBridgeRelatedAttribute(IdentifierInfo &ObjCBridgeRelated,
+                                SourceLocation ObjCBridgeRelatedLoc,
+                                ParsedAttributes &attrs,
+                                SourceLocation *endLoc,
+                                IdentifierInfo *ScopeName,
+                                SourceLocation ScopeLoc,
+                                AttributeList::Syntax Syntax) {
+  // Opening '('.
+  BalancedDelimiterTracker T(*this, tok::l_paren);
+  if (T.consumeOpen()) {
+    Diag(Tok, diag::err_expected) << tok::l_paren;
+    return;
+  }
+  
+  // Parse the related class name.
+  if (Tok.isNot(tok::identifier)) {
+    Diag(Tok, diag::err_objcbridge_related_expected_related_class);
+    SkipUntil(tok::r_paren, StopAtSemi);
+    return;
+  }
+  IdentifierLoc *RelatedClass = ParseIdentifierLoc();
+  if (ExpectAndConsume(tok::comma)) {
+    SkipUntil(tok::r_paren, StopAtSemi);
+    return;
+  }
+
+  // Parse optional class method name.
+  IdentifierLoc *ClassMethod = nullptr;
+  if (Tok.is(tok::identifier)) {
+    ClassMethod = ParseIdentifierLoc();
+    if (!TryConsumeToken(tok::colon)) {
+      Diag(Tok, diag::err_objcbridge_related_selector_name);
+      SkipUntil(tok::r_paren, StopAtSemi);
+      return;
+    }
+  }
+  if (!TryConsumeToken(tok::comma)) {
+    if (Tok.is(tok::colon))
+      Diag(Tok, diag::err_objcbridge_related_selector_name);
+    else
+      Diag(Tok, diag::err_expected) << tok::comma;
+    SkipUntil(tok::r_paren, StopAtSemi);
+    return;
+  }
+  
+  // Parse optional instance method name.
+  IdentifierLoc *InstanceMethod = nullptr;
+  if (Tok.is(tok::identifier))
+    InstanceMethod = ParseIdentifierLoc();
+  else if (Tok.isNot(tok::r_paren)) {
+    Diag(Tok, diag::err_expected) << tok::r_paren;
+    SkipUntil(tok::r_paren, StopAtSemi);
+    return;
+  }
+  
+  // Closing ')'.
+  if (T.consumeClose())
+    return;
+  
+  if (endLoc)
+    *endLoc = T.getCloseLocation();
+  
+  // Record this attribute
+  attrs.addNew(&ObjCBridgeRelated,
+               SourceRange(ObjCBridgeRelatedLoc, T.getCloseLocation()),
+               ScopeName, ScopeLoc,
+               RelatedClass,
+               ClassMethod,
+               InstanceMethod,
+               Syntax);
+}
 
 // Late Parsed Attributes:
 // See other examples of late parsing in lib/Parse/ParseCXXInlineMethods
@@ -1037,13 +1081,6 @@
   // Consume the previously pushed token.
   ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
 
-  if (OnDefinition && !IsThreadSafetyAttribute(LA.AttrName.getName())) {
-    // FIXME: Do not warn on C++11 attributes, once we start supporting
-    // them here.
-    Diag(Tok, diag::warn_attribute_on_function_definition)
-      << LA.AttrName.getName();
-  }
-
   ParsedAttributes Attrs(AttrFactory);
   SourceLocation endLoc;
 
@@ -1070,7 +1107,8 @@
         Actions.ActOnReenterFunctionContext(Actions.CurScope, D);
 
       ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc,
-                            0, SourceLocation(), AttributeList::AS_GNU);
+                            nullptr, SourceLocation(), AttributeList::AS_GNU,
+                            nullptr);
 
       if (HasFunScope) {
         Actions.ActOnExitFunctionContext();
@@ -1083,15 +1121,21 @@
       // If there are multiple decls, then the decl cannot be within the
       // function scope.
       ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc,
-                            0, SourceLocation(), AttributeList::AS_GNU);
+                            nullptr, SourceLocation(), AttributeList::AS_GNU,
+                            nullptr);
     }
   } else {
     Diag(Tok, diag::warn_attribute_no_decl) << LA.AttrName.getName();
   }
 
-  for (unsigned i = 0, ni = LA.Decls.size(); i < ni; ++i) {
+  const AttributeList *AL = Attrs.getList();
+  if (OnDefinition && AL && !AL->isCXX11Attribute() &&
+      AL->isKnownToGCC())
+    Diag(Tok, diag::warn_attribute_on_function_definition)
+      << &LA.AttrName;
+
+  for (unsigned i = 0, ni = LA.Decls.size(); i < ni; ++i)
     Actions.ActOnFinishDelayedAttribute(getCurScope(), LA.Decls[i], Attrs);
-  }
 
   if (Tok.getLocation() != OrigLoc) {
     // Due to a parsing error, we either went over the cached tokens or
@@ -1105,101 +1149,29 @@
   }
 }
 
-/// \brief Wrapper around a case statement checking if AttrName is
-/// one of the thread safety attributes
-bool Parser::IsThreadSafetyAttribute(StringRef AttrName) {
-  return llvm::StringSwitch<bool>(AttrName)
-      .Case("guarded_by", true)
-      .Case("guarded_var", true)
-      .Case("pt_guarded_by", true)
-      .Case("pt_guarded_var", true)
-      .Case("lockable", true)
-      .Case("scoped_lockable", true)
-      .Case("no_thread_safety_analysis", true)
-      .Case("acquired_after", true)
-      .Case("acquired_before", true)
-      .Case("exclusive_lock_function", true)
-      .Case("shared_lock_function", true)
-      .Case("exclusive_trylock_function", true)
-      .Case("shared_trylock_function", true)
-      .Case("unlock_function", true)
-      .Case("lock_returned", true)
-      .Case("locks_excluded", true)
-      .Case("exclusive_locks_required", true)
-      .Case("shared_locks_required", true)
-      .Default(false);
-}
-
-/// \brief Parse the contents of thread safety attributes. These
-/// should always be parsed as an expression list.
-///
-/// We need to special case the parsing due to the fact that if the first token
-/// of the first argument is an identifier, the main parse loop will store
-/// that token as a "parameter" and the rest of
-/// the arguments will be added to a list of "arguments". However,
-/// subsequent tokens in the first argument are lost. We instead parse each
-/// argument as an expression and add all arguments to the list of "arguments".
-/// In future, we will take advantage of this special case to also
-/// deal with some argument scoping issues here (for example, referring to a
-/// function parameter in the attribute on that function).
-void Parser::ParseThreadSafetyAttribute(IdentifierInfo &AttrName,
-                                        SourceLocation AttrNameLoc,
-                                        ParsedAttributes &Attrs,
-                                        SourceLocation *EndLoc) {
-  assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
-
-  BalancedDelimiterTracker T(*this, tok::l_paren);
-  T.consumeOpen();
-
-  ArgsVector ArgExprs;
-  bool ArgExprsOk = true;
-
-  // now parse the list of expressions
-  while (Tok.isNot(tok::r_paren)) {
-    EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated);
-    ExprResult ArgExpr(ParseAssignmentExpression());
-    if (ArgExpr.isInvalid()) {
-      ArgExprsOk = false;
-      T.consumeClose();
-      break;
-    } else {
-      ArgExprs.push_back(ArgExpr.release());
-    }
-    if (Tok.isNot(tok::comma))
-      break;
-    ConsumeToken(); // Eat the comma, move to the next argument
-  }
-  // Match the ')'.
-  if (ArgExprsOk && !T.consumeClose()) {
-    Attrs.addNew(&AttrName, AttrNameLoc, 0, AttrNameLoc, ArgExprs.data(),
-                 ArgExprs.size(), AttributeList::AS_GNU);
-  }
-  if (EndLoc)
-    *EndLoc = T.getCloseLocation();
-}
-
 void Parser::ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName,
                                               SourceLocation AttrNameLoc,
                                               ParsedAttributes &Attrs,
-                                              SourceLocation *EndLoc) {
+                                              SourceLocation *EndLoc,
+                                              IdentifierInfo *ScopeName,
+                                              SourceLocation ScopeLoc,
+                                              AttributeList::Syntax Syntax) {
   assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
 
   BalancedDelimiterTracker T(*this, tok::l_paren);
   T.consumeOpen();
 
   if (Tok.isNot(tok::identifier)) {
-    Diag(Tok, diag::err_expected_ident);
+    Diag(Tok, diag::err_expected) << tok::identifier;
     T.skipToEnd();
     return;
   }
   IdentifierLoc *ArgumentKind = ParseIdentifierLoc();
 
-  if (Tok.isNot(tok::comma)) {
-    Diag(Tok, diag::err_expected_comma);
+  if (ExpectAndConsume(tok::comma)) {
     T.skipToEnd();
     return;
   }
-  ConsumeToken();
 
   SourceRange MatchingCTypeRange;
   TypeResult MatchingCType = ParseTypeName(&MatchingCTypeRange);
@@ -1210,10 +1182,9 @@
 
   bool LayoutCompatible = false;
   bool MustBeNull = false;
-  while (Tok.is(tok::comma)) {
-    ConsumeToken();
+  while (TryConsumeToken(tok::comma)) {
     if (Tok.isNot(tok::identifier)) {
-      Diag(Tok, diag::err_expected_ident);
+      Diag(Tok, diag::err_expected) << tok::identifier;
       T.skipToEnd();
       return;
     }
@@ -1231,10 +1202,9 @@
   }
 
   if (!T.consumeClose()) {
-    Attrs.addNewTypeTagForDatatype(&AttrName, AttrNameLoc, 0, AttrNameLoc,
-                                   ArgumentKind, MatchingCType.release(),
-                                   LayoutCompatible, MustBeNull,
-                                   AttributeList::AS_GNU);
+    Attrs.addNewTypeTagForDatatype(&AttrName, AttrNameLoc, ScopeName, ScopeLoc,
+                                   ArgumentKind, MatchingCType.get(),
+                                   LayoutCompatible, MustBeNull, Syntax);
   }
 
   if (EndLoc)
@@ -1336,8 +1306,8 @@
   // parsing c none objective-c decls.
   ObjCDeclContextSwitch ObjCDC(*this);
 
-  Decl *SingleDecl = 0;
-  Decl *OwnedType = 0;
+  Decl *SingleDecl = nullptr;
+  Decl *OwnedType = nullptr;
   switch (Tok.getKind()) {
   case tok::kw_template:
   case tok::kw_export:
@@ -1401,8 +1371,14 @@
   // Parse the common declaration-specifiers piece.
   ParsingDeclSpec DS(*this);
 
-  ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS_none,
-                             getDeclSpecContextFromDeclaratorContext(Context));
+  DeclSpecContext DSContext = getDeclSpecContextFromDeclaratorContext(Context);
+  ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS_none, DSContext);
+
+  // If we had a free-standing type definition with a missing semicolon, we
+  // may get this far before the problem becomes obvious.
+  if (DS.hasTagDefinition() &&
+      DiagnoseMissingSemiAfterTagDefinition(DS, AS_none, DSContext))
+    return DeclGroupPtrTy();
 
   // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
   // declaration-specifiers init-declarator-list[opt] ';'
@@ -1501,8 +1477,7 @@
         // This declaration isn't over yet. Keep skipping.
         continue;
       }
-      if (Tok.is(tok::semi))
-        ConsumeToken();
+      TryConsumeToken(tok::semi);
       return;
 
     case tok::l_square:
@@ -1555,6 +1530,9 @@
       break;
 
     case tok::eof:
+    case tok::annot_module_begin:
+    case tok::annot_module_end:
+    case tok::annot_module_include:
       return;
 
     default:
@@ -1625,7 +1603,8 @@
     } else {
       if (Tok.is(tok::l_brace)) {
         Diag(Tok, diag::err_function_definition_not_allowed);
-        SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
+        SkipMalformedDecl();
+        return DeclGroupPtrTy();
       }
     }
   }
@@ -1641,9 +1620,8 @@
   // don't need to parse the container in advance.
   if (FRI && (Tok.is(tok::colon) || isTokIdentifier_in())) {
     bool IsForRangeLoop = false;
-    if (Tok.is(tok::colon)) {
+    if (TryConsumeToken(tok::colon, FRI->ColonLoc)) {
       IsForRangeLoop = true;
-      FRI->ColonLoc = ConsumeToken();
       if (Tok.is(tok::l_brace))
         FRI->RangeExpr = ParseBraceInitializer();
       else
@@ -1659,7 +1637,8 @@
   }
 
   SmallVector<Decl *, 8> DeclsInGroup;
-  Decl *FirstDecl = ParseDeclarationAfterDeclaratorAndAttributes(D);
+  Decl *FirstDecl = ParseDeclarationAfterDeclaratorAndAttributes(
+      D, ParsedTemplateInfo(), FRI);
   if (LateParsedAttrs.size() > 0)
     ParseLexedAttributeList(LateParsedAttrs, FirstDecl, true, false);
   D.complete(FirstDecl);
@@ -1670,9 +1649,8 @@
   
   // If we don't have a comma, it is either the end of the list (a ';') or an
   // error, bail out.
-  while (Tok.is(tok::comma)) {
-    SourceLocation CommaLoc = ConsumeToken();
-
+  SourceLocation CommaLoc;
+  while (TryConsumeToken(tok::comma, CommaLoc)) {
     if (Tok.isAtStartOfLine() && ExpectSemi && !MightBeDeclarator(Context)) {
       // This comma was followed by a line-break and something which can't be
       // the start of a declarator. The comma was probably a typo for a
@@ -1717,8 +1695,7 @@
     // Otherwise things are very confused and we skip to recover.
     if (!isDeclarationSpecifier()) {
       SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
-      if (Tok.is(tok::semi))
-        ConsumeToken();
+      TryConsumeToken(tok::semi);
     }
   }
 
@@ -1737,7 +1714,7 @@
       return true;
     }
 
-    D.setAsmLabel(AsmLabel.release());
+    D.setAsmLabel(AsmLabel.get());
     D.SetRangeEnd(Loc);
   }
 
@@ -1767,18 +1744,18 @@
 /// According to the standard grammar, =default and =delete are function
 /// definitions, but that definitely doesn't fit with the parser here.
 ///
-Decl *Parser::ParseDeclarationAfterDeclarator(Declarator &D,
-                                     const ParsedTemplateInfo &TemplateInfo) {
+Decl *Parser::ParseDeclarationAfterDeclarator(
+    Declarator &D, const ParsedTemplateInfo &TemplateInfo) {
   if (ParseAsmAttributesAfterDeclarator(D))
-    return 0;
+    return nullptr;
 
   return ParseDeclarationAfterDeclaratorAndAttributes(D, TemplateInfo);
 }
 
-Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(Declarator &D,
-                                     const ParsedTemplateInfo &TemplateInfo) {
+Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
+    Declarator &D, const ParsedTemplateInfo &TemplateInfo, ForRangeInit *FRI) {
   // Inform the current actions module that we just parsed this declarator.
-  Decl *ThisDecl = 0;
+  Decl *ThisDecl = nullptr;
   switch (TemplateInfo.Kind) {
   case ParsedTemplateInfo::NonTemplate:
     ThisDecl = Actions.ActOnDeclarator(getCurScope(), D);
@@ -1801,7 +1778,7 @@
           getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc, D);
       if (ThisRes.isInvalid()) {
         SkipUntil(tok::semi, StopBeforeMatch);
-        return 0;
+        return nullptr;
       }
       ThisDecl = ThisRes.get();
     } else {
@@ -1825,8 +1802,8 @@
         // Recover as if it were an explicit specialization.
         TemplateParameterLists FakedParamLists;
         FakedParamLists.push_back(Actions.ActOnTemplateParameterList(
-            0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, 0, 0,
-            LAngleLoc));
+            0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, nullptr,
+            0, LAngleLoc));
 
         ThisDecl =
             Actions.ActOnTemplateDeclarator(getCurScope(), FakedParamLists, D);
@@ -1841,7 +1818,7 @@
   // Parse declarator '=' initializer.
   // If a '==' or '+=' is found, suggest a fixit to '='.
   if (isTokenEqualOrEqualTypo()) {
-    ConsumeToken();
+    SourceLocation EqualLoc = ConsumeToken();
 
     if (Tok.is(tok::kw_delete)) {
       if (D.isFunctionDeclarator())
@@ -1865,21 +1842,37 @@
         Actions.CodeCompleteInitializer(getCurScope(), ThisDecl);
         Actions.FinalizeDeclaration(ThisDecl);
         cutOffParsing();
-        return 0;
+        return nullptr;
       }
 
       ExprResult Init(ParseInitializer());
 
+      // If this is the only decl in (possibly) range based for statement,
+      // our best guess is that the user meant ':' instead of '='.
+      if (Tok.is(tok::r_paren) && FRI && D.isFirstDeclarator()) {
+        Diag(EqualLoc, diag::err_single_decl_assign_in_for_range)
+            << FixItHint::CreateReplacement(EqualLoc, ":");
+        // We are trying to stop parser from looking for ';' in this for
+        // statement, therefore preventing spurious errors to be issued.
+        FRI->ColonLoc = EqualLoc;
+        Init = ExprError();
+        FRI->RangeExpr = Init;
+      }
+
       if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
         Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
         ExitScope();
       }
 
       if (Init.isInvalid()) {
-        SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch);
+        SmallVector<tok::TokenKind, 2> StopTokens;
+        StopTokens.push_back(tok::comma);
+        if (D.getContext() == Declarator::ForContext)
+          StopTokens.push_back(tok::r_paren);
+        SkipUntil(StopTokens, StopAtSemi | StopBeforeMatch);
         Actions.ActOnInitializerError(ThisDecl);
       } else
-        Actions.AddInitializerToDecl(ThisDecl, Init.take(),
+        Actions.AddInitializerToDecl(ThisDecl, Init.get(),
                                      /*DirectInit=*/false, TypeContainsAuto);
     }
   } else if (Tok.is(tok::l_paren)) {
@@ -1918,7 +1911,7 @@
       ExprResult Initializer = Actions.ActOnParenListExpr(T.getOpenLocation(),
                                                           T.getCloseLocation(),
                                                           Exprs);
-      Actions.AddInitializerToDecl(ThisDecl, Initializer.take(),
+      Actions.AddInitializerToDecl(ThisDecl, Initializer.get(),
                                    /*DirectInit=*/true, TypeContainsAuto);
     }
   } else if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace) &&
@@ -1941,7 +1934,7 @@
     if (Init.isInvalid()) {
       Actions.ActOnInitializerError(ThisDecl);
     } else
-      Actions.AddInitializerToDecl(ThisDecl, Init.take(),
+      Actions.AddInitializerToDecl(ThisDecl, Init.get(),
                                    /*DirectInit=*/true, TypeContainsAuto);
 
   } else {
@@ -1968,8 +1961,7 @@
 
   // Validate declspec for type-name.
   unsigned Specs = DS.getParsedSpecifiers();
-  if ((DSC == DSC_type_specifier || DSC == DSC_trailing) &&
-      !DS.hasTypeSpecifier()) {
+  if (isTypeSpecifier(DSC) && !DS.hasTypeSpecifier()) {
     Diag(Tok, diag::err_expected_type);
     DS.SetTypeSpecError();
   } else if (Specs == DeclSpec::PQ_None && !DS.getNumProtocolQualifiers() &&
@@ -2043,7 +2035,7 @@
 ///
 bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
                               const ParsedTemplateInfo &TemplateInfo,
-                              AccessSpecifier AS, DeclSpecContext DSC, 
+                              AccessSpecifier AS, DeclSpecContext DSC,
                               ParsedAttributesWithRange &Attrs) {
   assert(Tok.is(tok::identifier) && "should have identifier");
 
@@ -2067,8 +2059,7 @@
   // within a type specifier. Outside of C++, we allow this even if the
   // language doesn't "officially" support implicit int -- we support
   // implicit int as an extension in C99 and C11.
-  if (DSC != DSC_type_specifier && DSC != DSC_trailing &&
-      !getLangOpts().CPlusPlus &&
+  if (!isTypeSpecifier(DSC) && !getLangOpts().CPlusPlus &&
       isValidAfterIdentifierInDeclarator(NextToken())) {
     // If this token is valid for implicit int, e.g. "static x = 4", then
     // we just avoid eating the identifier, so it will be parsed as the
@@ -2091,8 +2082,8 @@
   // This is a common problem in C (saying 'foo' instead of 'struct foo').
   //
   // C++ doesn't need this, and isTagName doesn't take SS.
-  if (SS == 0) {
-    const char *TagName = 0, *FixitTagName = 0;
+  if (SS == nullptr) {
+    const char *TagName = nullptr, *FixitTagName = nullptr;
     tok::TokenKind TagKind = tok::unknown;
 
     switch (Actions.isTagName(*Tok.getIdentifierInfo(), getCurScope())) {
@@ -2138,7 +2129,7 @@
 
   // Determine whether this identifier could plausibly be the name of something
   // being declared (with a missing type).
-  if (DSC != DSC_type_specifier && DSC != DSC_trailing &&
+  if (!isTypeSpecifier(DSC) &&
       (!SS || DSC == DSC_top_level || DSC == DSC_class)) {
     // Look ahead to the next token to try to figure out what this declaration
     // was supposed to be.
@@ -2148,15 +2139,14 @@
       // x(int n);    // 'x' is not a type
       // x (*p)[];    // 'x' is a type
       //
-      // Since we're in an error case (or the rare 'implicit int in C++' MS
-      // extension), we can afford to perform a tentative parse to determine
-      // which case we're in.
+      // Since we're in an error case, we can afford to perform a tentative
+      // parse to determine which case we're in.
       TentativeParsingAction PA(*this);
       ConsumeToken();
       TPResult TPR = TryParseDeclarator(/*mayBeAbstract*/false);
       PA.Revert();
 
-      if (TPR != TPResult::False()) {
+      if (TPR != TPResult::False) {
         // The identifier is followed by a parenthesized declarator.
         // It's supposed to be a type.
         break;
@@ -2195,39 +2185,33 @@
     }
   }
 
-  // This is almost certainly an invalid type name. Let the action emit a
-  // diagnostic and attempt to recover.
+  // This is almost certainly an invalid type name. Let Sema emit a diagnostic
+  // and attempt to recover.
   ParsedType T;
   IdentifierInfo *II = Tok.getIdentifierInfo();
-  if (Actions.DiagnoseUnknownTypeName(II, Loc, getCurScope(), SS, T)) {
-    // The action emitted a diagnostic, so we don't have to.
-    if (T) {
-      // The action has suggested that the type T could be used. Set that as
-      // the type in the declaration specifiers, consume the would-be type
-      // name token, and we're done.
-      const char *PrevSpec;
-      unsigned DiagID;
-      DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, T);
-      DS.SetRangeEnd(Tok.getLocation());
-      ConsumeToken();
-      // There may be other declaration specifiers after this.
-      return true;
-    } else if (II != Tok.getIdentifierInfo()) {
-      // If no type was suggested, the correction is to a keyword
-      Tok.setKind(II->getTokenID());
-      // There may be other declaration specifiers after this.
-      return true;
-    }
-
-    // Fall through; the action had no suggestion for us.
-  } else {
-    // The action did not emit a diagnostic, so emit one now.
-    SourceRange R;
-    if (SS) R = SS->getRange();
-    Diag(Loc, diag::err_unknown_typename) << Tok.getIdentifierInfo() << R;
+  Actions.DiagnoseUnknownTypeName(II, Loc, getCurScope(), SS, T,
+                                  getLangOpts().CPlusPlus &&
+                                      NextToken().is(tok::less));
+  if (T) {
+    // The action has suggested that the type T could be used. Set that as
+    // the type in the declaration specifiers, consume the would-be type
+    // name token, and we're done.
+    const char *PrevSpec;
+    unsigned DiagID;
+    DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, T,
+                       Actions.getASTContext().getPrintingPolicy());
+    DS.SetRangeEnd(Tok.getLocation());
+    ConsumeToken();
+    // There may be other declaration specifiers after this.
+    return true;
+  } else if (II != Tok.getIdentifierInfo()) {
+    // If no type was suggested, the correction is to a keyword
+    Tok.setKind(II->getTokenID());
+    // There may be other declaration specifiers after this.
+    return true;
   }
 
-  // Mark this as an error.
+  // Otherwise, the action had no suggestion for us.  Mark this as an error.
   DS.SetTypeSpecError();
   DS.SetRangeEnd(Tok.getLocation());
   ConsumeToken();
@@ -2249,8 +2233,13 @@
     return DSC_class;
   if (Context == Declarator::FileContext)
     return DSC_top_level;
+  if (Context == Declarator::TemplateTypeArgContext)
+    return DSC_template_type_arg;
   if (Context == Declarator::TrailingReturnContext)
     return DSC_trailing;
+  if (Context == Declarator::AliasDeclContext ||
+      Context == Declarator::AliasTemplateContext)
+    return DSC_alias_declaration;
   return DSC_normal;
 }
 
@@ -2275,8 +2264,8 @@
   } else
     ER = ParseConstantExpression();
 
-  if (getLangOpts().CPlusPlus11 && Tok.is(tok::ellipsis))
-    EllipsisLoc = ConsumeToken();
+  if (getLangOpts().CPlusPlus11)
+    TryConsumeToken(tok::ellipsis, EllipsisLoc);
 
   return ER;
 }
@@ -2298,7 +2287,7 @@
   SourceLocation KWLoc = ConsumeToken();
 
   BalancedDelimiterTracker T(*this, tok::l_paren);
-  if (T.expectAndConsume(diag::err_expected_lparen))
+  if (T.expectAndConsume())
     return;
 
   SourceLocation EllipsisLoc;
@@ -2313,11 +2302,119 @@
     *EndLoc = T.getCloseLocation();
 
   ArgsVector ArgExprs;
-  ArgExprs.push_back(ArgExpr.release());
-  Attrs.addNew(KWName, KWLoc, 0, KWLoc, ArgExprs.data(), 1,
+  ArgExprs.push_back(ArgExpr.get());
+  Attrs.addNew(KWName, KWLoc, nullptr, KWLoc, ArgExprs.data(), 1,
                AttributeList::AS_Keyword, EllipsisLoc);
 }
 
+/// Determine whether we're looking at something that might be a declarator
+/// in a simple-declaration. If it can't possibly be a declarator, maybe
+/// diagnose a missing semicolon after a prior tag definition in the decl
+/// specifier.
+///
+/// \return \c true if an error occurred and this can't be any kind of
+/// declaration.
+bool
+Parser::DiagnoseMissingSemiAfterTagDefinition(DeclSpec &DS, AccessSpecifier AS,
+                                              DeclSpecContext DSContext,
+                                              LateParsedAttrList *LateAttrs) {
+  assert(DS.hasTagDefinition() && "shouldn't call this");
+
+  bool EnteringContext = (DSContext == DSC_class || DSContext == DSC_top_level);
+
+  if (getLangOpts().CPlusPlus &&
+      (Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||
+       Tok.is(tok::kw_decltype) || Tok.is(tok::annot_template_id)) &&
+      TryAnnotateCXXScopeToken(EnteringContext)) {
+    SkipMalformedDecl();
+    return true;
+  }
+
+  bool HasScope = Tok.is(tok::annot_cxxscope);
+  // Make a copy in case GetLookAheadToken invalidates the result of NextToken.
+  Token AfterScope = HasScope ? NextToken() : Tok;
+
+  // Determine whether the following tokens could possibly be a
+  // declarator.
+  bool MightBeDeclarator = true;
+  if (Tok.is(tok::kw_typename) || Tok.is(tok::annot_typename)) {
+    // A declarator-id can't start with 'typename'.
+    MightBeDeclarator = false;
+  } else if (AfterScope.is(tok::annot_template_id)) {
+    // If we have a type expressed as a template-id, this cannot be a
+    // declarator-id (such a type cannot be redeclared in a simple-declaration).
+    TemplateIdAnnotation *Annot =
+        static_cast<TemplateIdAnnotation *>(AfterScope.getAnnotationValue());
+    if (Annot->Kind == TNK_Type_template)
+      MightBeDeclarator = false;
+  } else if (AfterScope.is(tok::identifier)) {
+    const Token &Next = HasScope ? GetLookAheadToken(2) : NextToken();
+
+    // These tokens cannot come after the declarator-id in a
+    // simple-declaration, and are likely to come after a type-specifier.
+    if (Next.is(tok::star) || Next.is(tok::amp) || Next.is(tok::ampamp) ||
+        Next.is(tok::identifier) || Next.is(tok::annot_cxxscope) ||
+        Next.is(tok::coloncolon)) {
+      // Missing a semicolon.
+      MightBeDeclarator = false;
+    } else if (HasScope) {
+      // If the declarator-id has a scope specifier, it must redeclare a
+      // previously-declared entity. If that's a type (and this is not a
+      // typedef), that's an error.
+      CXXScopeSpec SS;
+      Actions.RestoreNestedNameSpecifierAnnotation(
+          Tok.getAnnotationValue(), Tok.getAnnotationRange(), SS);
+      IdentifierInfo *Name = AfterScope.getIdentifierInfo();
+      Sema::NameClassification Classification = Actions.ClassifyName(
+          getCurScope(), SS, Name, AfterScope.getLocation(), Next,
+          /*IsAddressOfOperand*/false);
+      switch (Classification.getKind()) {
+      case Sema::NC_Error:
+        SkipMalformedDecl();
+        return true;
+
+      case Sema::NC_Keyword:
+      case Sema::NC_NestedNameSpecifier:
+        llvm_unreachable("typo correction and nested name specifiers not "
+                         "possible here");
+
+      case Sema::NC_Type:
+      case Sema::NC_TypeTemplate:
+        // Not a previously-declared non-type entity.
+        MightBeDeclarator = false;
+        break;
+
+      case Sema::NC_Unknown:
+      case Sema::NC_Expression:
+      case Sema::NC_VarTemplate:
+      case Sema::NC_FunctionTemplate:
+        // Might be a redeclaration of a prior entity.
+        break;
+      }
+    }
+  }
+
+  if (MightBeDeclarator)
+    return false;
+
+  const PrintingPolicy &PPol = Actions.getASTContext().getPrintingPolicy();
+  Diag(PP.getLocForEndOfToken(DS.getRepAsDecl()->getLocEnd()),
+       diag::err_expected_after)
+      << DeclSpec::getSpecifierName(DS.getTypeSpecType(), PPol) << tok::semi;
+
+  // Try to recover from the typo, by dropping the tag definition and parsing
+  // the problematic tokens as a type.
+  //
+  // FIXME: Split the DeclSpec into pieces for the standalone
+  // declaration and pieces for the following declaration, instead
+  // of assuming that all the other pieces attach to new declaration,
+  // and call ParsedFreeStandingDeclSpec as appropriate.
+  DS.ClearTypeSpecType();
+  ParsedTemplateInfo NotATemplate;
+  ParseDeclarationSpecifiers(DS, NotATemplate, AS, DSContext, LateAttrs);
+  return false;
+}
+
 /// ParseDeclarationSpecifiers
 ///       declaration-specifiers: [C99 6.7]
 ///         storage-class-specifier declaration-specifiers[opt]
@@ -2359,9 +2456,10 @@
   bool EnteringContext = (DSContext == DSC_class || DSContext == DSC_top_level);
   bool AttrsLastTime = false;
   ParsedAttributesWithRange attrs(AttrFactory);
+  const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
   while (1) {
     bool isInvalid = false;
-    const char *PrevSpec = 0;
+    const char *PrevSpec = nullptr;
     unsigned DiagID = 0;
 
     SourceLocation Loc = Tok.getLocation();
@@ -2382,7 +2480,7 @@
 
       // If this is not a declaration specifier token, we're done reading decl
       // specifiers.  First verify that DeclSpec's are consistent.
-      DS.Finish(Diags, PP);
+      DS.Finish(Diags, PP, Policy);
       return;
 
     case tok::l_square:
@@ -2484,7 +2582,7 @@
         if ((DSContext == DSC_top_level || DSContext == DSC_class) &&
             TemplateId->Name &&
             Actions.isCurrentClassName(*TemplateId->Name, getCurScope(), &SS)) {
-          if (isConstructorDeclarator()) {
+          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
@@ -2516,7 +2614,7 @@
           ParsedType T = getTypeAnnotation(Tok);
           isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename,
                                          Tok.getAnnotationEndLoc(),
-                                         PrevSpec, DiagID, T);
+                                         PrevSpec, DiagID, T, Policy);
           if (isInvalid)
             break;
         }
@@ -2534,7 +2632,7 @@
       if ((DSContext == DSC_top_level || DSContext == DSC_class) &&
           Actions.isCurrentClassName(*Next.getIdentifierInfo(), getCurScope(),
                                      &SS)) {
-        if (isConstructorDeclarator())
+        if (isConstructorDeclarator(/*Unqualified*/false))
           goto DoneWithDeclSpec;
 
         // As noted in C++ [class.qual]p2 (cited above), when the name
@@ -2575,7 +2673,7 @@
       ConsumeToken(); // The C++ scope.
 
       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
-                                     DiagID, TypeRep);
+                                     DiagID, TypeRep, Policy);
       if (isInvalid)
         break;
 
@@ -2586,10 +2684,15 @@
     }
 
     case tok::annot_typename: {
+      // If we've previously seen a tag definition, we were almost surely
+      // missing a semicolon after it.
+      if (DS.hasTypeSpecifier() && DS.hasTagDefinition())
+        goto DoneWithDeclSpec;
+
       if (Tok.getAnnotationValue()) {
         ParsedType T = getTypeAnnotation(Tok);
         isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
-                                       DiagID, T);
+                                       DiagID, T, Policy);
       } else
         DS.SetTypeSpecError();
 
@@ -2618,10 +2721,8 @@
       // then treat __is_signed as an identifier rather than as a keyword.
       if (DS.getTypeSpecType() == TST_bool &&
           DS.getTypeQualifiers() == DeclSpec::TQ_const &&
-          DS.getStorageClassSpec() == DeclSpec::SCS_static) {
-        Tok.getIdentifierInfo()->RevertTokenIDToIdentifier();
-        Tok.setKind(tok::identifier);
-      }
+          DS.getStorageClassSpec() == DeclSpec::SCS_static)
+        TryKeywordIdentFallback(true);
 
       // We're done with the declaration-specifiers.
       goto DoneWithDeclSpec;
@@ -2629,24 +2730,23 @@
       // typedef-name
     case tok::kw_decltype:
     case tok::identifier: {
-      // 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) {
-        if (TryAnnotateCXXScopeToken(EnteringContext)) {
-          if (!DS.hasTypeSpecifier())
-            DS.SetTypeSpecError();
-          goto DoneWithDeclSpec;
-        }
-        if (!Tok.is(tok::identifier))
-          continue;
-      }
-
       // This identifier can only be a typedef name if we haven't already seen
       // a type-specifier.  Without this check we misparse:
       //  typedef int X; struct Y { short X; };  as 'short int'.
       if (DS.hasTypeSpecifier())
         goto DoneWithDeclSpec;
 
+      // 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) {
+        if (TryAnnotateCXXScopeToken(EnteringContext)) {
+          DS.SetTypeSpecError();
+          goto DoneWithDeclSpec;
+        }
+        if (!Tok.is(tok::identifier))
+          continue;
+      }
+
       // Check for need to substitute AltiVec keyword tokens.
       if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID, isInvalid))
         break;
@@ -2660,11 +2760,21 @@
         Actions.getTypeName(*Tok.getIdentifierInfo(),
                             Tok.getLocation(), getCurScope());
 
+      // MSVC: If we weren't able to parse a default template argument, and it's
+      // just a simple identifier, create a DependentNameType.  This will allow us
+      // to defer the name lookup to template instantiation time, as long we forge a
+      // NestedNameSpecifier for the current context.
+      if (!TypeRep && DSContext == DSC_template_type_arg &&
+          getLangOpts().MSVCCompat && getCurScope()->isTemplateParamScope()) {
+        TypeRep = Actions.ActOnDelayedDefaultTemplateArg(
+            *Tok.getIdentifierInfo(), Tok.getLocation());
+      }
+
       // If this is not a typedef name, don't parse it as part of the declspec,
       // it must be an implicit int or an error.
       if (!TypeRep) {
         ParsedAttributesWithRange Attrs(AttrFactory);
-        if (ParseImplicitInt(DS, 0, TemplateInfo, AS, DSContext, Attrs)) {
+        if (ParseImplicitInt(DS, nullptr, TemplateInfo, AS, DSContext, Attrs)) {
           if (!Attrs.empty()) {
             AttrsLastTime = true;
             attrs.takeAllFrom(Attrs);
@@ -2678,11 +2788,11 @@
       // check whether this is a constructor declaration.
       if (getLangOpts().CPlusPlus && DSContext == DSC_class &&
           Actions.isCurrentClassName(*Tok.getIdentifierInfo(), getCurScope()) &&
-          isConstructorDeclarator())
+          isConstructorDeclarator(/*Unqualified*/true))
         goto DoneWithDeclSpec;
 
       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
-                                     DiagID, TypeRep);
+                                     DiagID, TypeRep, Policy);
       if (isInvalid)
         break;
 
@@ -2714,7 +2824,7 @@
       // constructor declaration.
       if (getLangOpts().CPlusPlus && DSContext == DSC_class &&
           Actions.isCurrentClassName(*TemplateId->Name, getCurScope()) &&
-          isConstructorDeclarator())
+          isConstructorDeclarator(TemplateId->SS.isEmpty()))
         goto DoneWithDeclSpec;
 
       // Turn the template-id annotation token into a type annotation
@@ -2725,7 +2835,7 @@
 
     // GNU attributes support.
     case tok::kw___attribute:
-      ParseGNUAttributes(DS.getAttributes(), 0, LateAttrs);
+      ParseGNUAttributes(DS.getAttributes(), nullptr, LateAttrs);
       continue;
 
     // Microsoft declspec support.
@@ -2738,10 +2848,8 @@
       isInvalid = DS.setFunctionSpecForceInline(Loc, PrevSpec, DiagID);
       IdentifierInfo *AttrName = Tok.getIdentifierInfo();
       SourceLocation AttrNameLoc = Tok.getLocation();
-      // FIXME: This does not work correctly if it is set to be a declspec
-      //        attribute, and a GNU attribute is simply incorrect.
-      DS.getAttributes().addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0,
-                                AttributeList::AS_GNU);
+      DS.getAttributes().addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc,
+                                nullptr, 0, AttributeList::AS_Keyword);
       break;
     }
 
@@ -2771,46 +2879,46 @@
     // storage-class-specifier
     case tok::kw_typedef:
       isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_typedef, Loc,
-                                         PrevSpec, DiagID);
+                                         PrevSpec, DiagID, Policy);
       break;
     case tok::kw_extern:
       if (DS.getThreadStorageClassSpec() == DeclSpec::TSCS___thread)
         Diag(Tok, diag::ext_thread_before) << "extern";
       isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_extern, Loc,
-                                         PrevSpec, DiagID);
+                                         PrevSpec, DiagID, Policy);
       break;
     case tok::kw___private_extern__:
       isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_private_extern,
-                                         Loc, PrevSpec, DiagID);
+                                         Loc, PrevSpec, DiagID, Policy);
       break;
     case tok::kw_static:
       if (DS.getThreadStorageClassSpec() == DeclSpec::TSCS___thread)
         Diag(Tok, diag::ext_thread_before) << "static";
       isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_static, Loc,
-                                         PrevSpec, DiagID);
+                                         PrevSpec, DiagID, Policy);
       break;
     case tok::kw_auto:
       if (getLangOpts().CPlusPlus11) {
         if (isKnownToBeTypeSpecifier(GetLookAheadToken(1))) {
           isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,
-                                             PrevSpec, DiagID);
+                                             PrevSpec, DiagID, Policy);
           if (!isInvalid)
             Diag(Tok, diag::ext_auto_storage_class)
               << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc());
         } else
           isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec,
-                                         DiagID);
+                                         DiagID, Policy);
       } else
         isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,
-                                           PrevSpec, DiagID);
+                                           PrevSpec, DiagID, Policy);
       break;
     case tok::kw_register:
       isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_register, Loc,
-                                         PrevSpec, DiagID);
+                                         PrevSpec, DiagID, Policy);
       break;
     case tok::kw_mutable:
       isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_mutable, Loc,
-                                         PrevSpec, DiagID);
+                                         PrevSpec, DiagID, Policy);
       break;
     case tok::kw___thread:
       isInvalid = DS.SetStorageClassSpecThread(DeclSpec::TSCS___thread, Loc,
@@ -2872,19 +2980,19 @@
     // type-specifier
     case tok::kw_short:
       isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec,
-                                      DiagID);
+                                      DiagID, Policy);
       break;
     case tok::kw_long:
       if (DS.getTypeSpecWidth() != DeclSpec::TSW_long)
         isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec,
-                                        DiagID);
+                                        DiagID, Policy);
       else
         isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec,
-                                        DiagID);
+                                        DiagID, Policy);
       break;
     case tok::kw___int64:
         isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec,
-                                        DiagID);
+                                        DiagID, Policy);
       break;
     case tok::kw_signed:
       isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec,
@@ -2904,43 +3012,43 @@
       break;
     case tok::kw_void:
       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec,
-                                     DiagID);
+                                     DiagID, Policy);
       break;
     case tok::kw_char:
       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec,
-                                     DiagID);
+                                     DiagID, Policy);
       break;
     case tok::kw_int:
       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec,
-                                     DiagID);
+                                     DiagID, Policy);
       break;
     case tok::kw___int128:
       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int128, Loc, PrevSpec,
-                                     DiagID);
+                                     DiagID, Policy);
       break;
     case tok::kw_half:
       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_half, Loc, PrevSpec,
-                                     DiagID);
+                                     DiagID, Policy);
       break;
     case tok::kw_float:
       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec,
-                                     DiagID);
+                                     DiagID, Policy);
       break;
     case tok::kw_double:
       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec,
-                                     DiagID);
+                                     DiagID, Policy);
       break;
     case tok::kw_wchar_t:
       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec,
-                                     DiagID);
+                                     DiagID, Policy);
       break;
     case tok::kw_char16_t:
       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec,
-                                     DiagID);
+                                     DiagID, Policy);
       break;
     case tok::kw_char32_t:
       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec,
-                                     DiagID);
+                                     DiagID, Policy);
       break;
     case tok::kw_bool:
     case tok::kw__Bool:
@@ -2954,62 +3062,30 @@
         isInvalid = true;
       } else {
         isInvalid = DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec,
-                                       DiagID);
+                                       DiagID, Policy);
       }
       break;
     case tok::kw__Decimal32:
       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal32, Loc, PrevSpec,
-                                     DiagID);
+                                     DiagID, Policy);
       break;
     case tok::kw__Decimal64:
       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal64, Loc, PrevSpec,
-                                     DiagID);
+                                     DiagID, Policy);
       break;
     case tok::kw__Decimal128:
       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec,
-                                     DiagID);
+                                     DiagID, Policy);
       break;
     case tok::kw___vector:
-      isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
+      isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID, Policy);
       break;
     case tok::kw___pixel:
-      isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID);
-      break;
-    case tok::kw_image1d_t:
-       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image1d_t, Loc,
-                                      PrevSpec, DiagID);
-      break;
-    case tok::kw_image1d_array_t:
-       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image1d_array_t, Loc,
-                                      PrevSpec, DiagID);
-      break;
-    case tok::kw_image1d_buffer_t:
-       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image1d_buffer_t, Loc,
-                                      PrevSpec, DiagID);
-      break;
-    case tok::kw_image2d_t:
-       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image2d_t, Loc,
-                                      PrevSpec, DiagID);
-      break;
-    case tok::kw_image2d_array_t:
-       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image2d_array_t, Loc,
-                                      PrevSpec, DiagID);
-      break;
-    case tok::kw_image3d_t:
-      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image3d_t, Loc,
-                                     PrevSpec, DiagID);
-      break;
-    case tok::kw_sampler_t:
-      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_sampler_t, Loc,
-                                     PrevSpec, DiagID);
-      break;
-    case tok::kw_event_t:
-      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_event_t, Loc,
-                                     PrevSpec, DiagID);
+      isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID, Policy);
       break;
     case tok::kw___unknown_anytype:
       isInvalid = DS.SetTypeSpecType(TST_unknown_anytype, Loc,
-                                     PrevSpec, DiagID);
+                                     PrevSpec, DiagID, Policy);
       break;
 
     // class-specifier:
@@ -3093,9 +3169,6 @@
       break;
 
     // OpenCL qualifiers:
-    case tok::kw_private:
-      if (!getLangOpts().OpenCL)
-        goto DoneWithDeclSpec;
     case tok::kw___private:
     case tok::kw___global:
     case tok::kw___local:
@@ -3103,7 +3176,7 @@
     case tok::kw___read_only:
     case tok::kw___write_only:
     case tok::kw___read_write:
-      ParseOpenCLQualifiers(DS);
+      ParseOpenCLQualifiers(DS.getAttributes());
       break;
 
     case tok::less:
@@ -3200,13 +3273,12 @@
       ParseDeclarator(DeclaratorInfo.D);
     }
 
-    if (Tok.is(tok::colon)) {
-      ConsumeToken();
+    if (TryConsumeToken(tok::colon)) {
       ExprResult Res(ParseConstantExpression());
       if (Res.isInvalid())
         SkipUntil(tok::semi, StopBeforeMatch);
       else
-        DeclaratorInfo.BitfieldSize = Res.release();
+        DeclaratorInfo.BitfieldSize = Res.get();
     }
 
     // If attributes exist after the declarator, parse them.
@@ -3217,12 +3289,9 @@
 
     // If we don't have a comma, it is either the end of the list (a ';')
     // or an error, bail out.
-    if (Tok.isNot(tok::comma))
+    if (!TryConsumeToken(tok::comma, CommaLoc))
       return;
 
-    // Consume the comma.
-    CommaLoc = ConsumeToken();
-
     FirstDeclarator = false;
   }
 }
@@ -3253,7 +3322,7 @@
   SmallVector<Decl *, 32> FieldDecls;
 
   // While we still have something to read, read the declarations in the struct.
-  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
+  while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
     // Each iteration of this loop reads one struct-declaration.
 
     // Check for extraneous top-level semicolon.
@@ -3289,7 +3358,7 @@
                        SmallVectorImpl<Decl *> &FieldDecls) :
           P(P), TagDecl(TagDecl), FieldDecls(FieldDecls) {}
 
-        void invoke(ParsingFieldDeclarator &FD) {
+        void invoke(ParsingFieldDeclarator &FD) override {
           // Install the declarator into the current TagDecl.
           Decl *Field = P.Actions.ActOnField(P.getCurScope(), TagDecl,
                               FD.D.getDeclSpec().getSourceRange().getBegin(),
@@ -3310,9 +3379,9 @@
         continue;
       }
       ConsumeToken();
-      ExpectAndConsume(tok::l_paren, diag::err_expected_lparen);
+      ExpectAndConsume(tok::l_paren);
       if (!Tok.is(tok::identifier)) {
-        Diag(Tok, diag::err_expected_ident);
+        Diag(Tok, diag::err_expected) << tok::identifier;
         SkipUntil(tok::semi);
         continue;
       }
@@ -3321,21 +3390,22 @@
                         Tok.getIdentifierInfo(), Fields);
       FieldDecls.insert(FieldDecls.end(), Fields.begin(), Fields.end());
       ConsumeToken();
-      ExpectAndConsume(tok::r_paren, diag::err_expected_rparen);
+      ExpectAndConsume(tok::r_paren);
     }
 
-    if (Tok.is(tok::semi)) {
-      ConsumeToken();
-    } else if (Tok.is(tok::r_brace)) {
+    if (TryConsumeToken(tok::semi))
+      continue;
+
+    if (Tok.is(tok::r_brace)) {
       ExpectAndConsume(tok::semi, diag::ext_expected_semi_decl_list);
       break;
-    } else {
-      ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
-      // Skip to end of block or statement to avoid ext-warning on extra ';'.
-      SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
-      // If we stopped at a ';', eat it.
-      if (Tok.is(tok::semi)) ConsumeToken();
     }
+
+    ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
+    // Skip to end of block or statement to avoid ext-warning on extra ';'.
+    SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
+    // If we stopped at a ';', eat it.
+    TryConsumeToken(tok::semi);
   }
 
   T.consumeClose();
@@ -3452,7 +3522,7 @@
       return;
 
     if (SS.isSet() && Tok.isNot(tok::identifier)) {
-      Diag(Tok, diag::err_expected_ident);
+      Diag(Tok, diag::err_expected) << tok::identifier;
       if (Tok.isNot(tok::l_brace)) {
         // Has no name and is not a definition.
         // Skip the rest of this declarator, up until the comma or semicolon.
@@ -3465,7 +3535,7 @@
   // Must have either 'enum name' or 'enum {...}'.
   if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace) &&
       !(AllowFixedUnderlyingType && Tok.is(tok::colon))) {
-    Diag(Tok, diag::err_expected_ident_lbrace);
+    Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace;
 
     // Skip the rest of this declarator, up until the comma or semicolon.
     SkipUntil(tok::comma, StopAtSemi);
@@ -3473,7 +3543,7 @@
   }
 
   // If an identifier is present, consume and remember it.
-  IdentifierInfo *Name = 0;
+  IdentifierInfo *Name = nullptr;
   SourceLocation NameLoc;
   if (Tok.is(tok::identifier)) {
     Name = Tok.getIdentifierInfo();
@@ -3512,13 +3582,13 @@
       TPResult TPR = isExpressionOrTypeSpecifierSimple(NextToken().getKind());
       // If the next token starts an expression, we know we're parsing a
       // bit-field. This is the common case.
-      if (TPR == TPResult::True())
+      if (TPR == TPResult::True)
         PossibleBitfield = true;
       // If the next token starts a type-specifier-seq, it may be either a
       // a fixed underlying type or the start of a function-style cast in C++;
       // lookahead one more token to see if it's obvious that we have a
       // fixed underlying type.
-      else if (TPR == TPResult::False() &&
+      else if (TPR == TPResult::False &&
                GetLookAheadToken(2).getKind() == tok::semi) {
         // Consume the ':'.
         ConsumeToken();
@@ -3538,7 +3608,7 @@
         // FIXME: The standard is not entirely clear on how to disambiguate in
         // this case.
         if ((getLangOpts().CPlusPlus &&
-             isCXXDeclarationSpecifier(TPResult::True()) != TPResult::True()) ||
+             isCXXDeclarationSpecifier(TPResult::True) != TPResult::True) ||
             (!getLangOpts().CPlusPlus && !isDeclarationSpecifier(true))) {
           // We'll parse this as a bitfield later.
           PossibleBitfield = true;
@@ -3591,15 +3661,14 @@
     } else {
       TUK = Sema::TUK_Definition;
     }
-  } else if (DSC != DSC_type_specifier &&
+  } else if (!isTypeSpecifier(DSC) &&
              (Tok.is(tok::semi) ||
               (Tok.isAtStartOfLine() &&
                !isValidAfterTypeSpecifier(CanBeBitfield)))) {
     TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration;
     if (Tok.isNot(tok::semi)) {
       // A semicolon was missing after this declaration. Diagnose and recover.
-      ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl,
-                       "enum");
+      ExpectAndConsume(tok::semi, diag::err_expected_after, "enum");
       PP.EnterToken(Tok);
       Tok.setKind(tok::semi);
     }
@@ -3648,13 +3717,14 @@
 
   bool Owned = false;
   bool IsDependent = false;
-  const char *PrevSpec = 0;
+  const char *PrevSpec = nullptr;
   unsigned DiagID;
   Decl *TagDecl = Actions.ActOnTag(getCurScope(), DeclSpec::TST_enum, TUK,
                                    StartLoc, SS, Name, NameLoc, attrs.getList(),
                                    AS, DS.getModulePrivateSpecLoc(), TParams,
                                    Owned, IsDependent, ScopedEnumKWLoc,
-                                   IsScopedUsingClassTag, BaseType);
+                                   IsScopedUsingClassTag, BaseType,
+                                   DSC == DSC_type_specifier);
 
   if (IsDependent) {
     // This enum has a dependent nested-name-specifier. Handle it as a
@@ -3665,9 +3735,8 @@
       return;
     }
 
-    TypeResult Type = Actions.ActOnDependentTag(getCurScope(), DeclSpec::TST_enum,
-                                                TUK, SS, Name, StartLoc,
-                                                NameLoc);
+    TypeResult Type = Actions.ActOnDependentTag(
+        getCurScope(), DeclSpec::TST_enum, TUK, SS, Name, StartLoc, NameLoc);
     if (Type.isInvalid()) {
       DS.SetTypeSpecError();
       return;
@@ -3675,7 +3744,8 @@
 
     if (DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc,
                            NameLoc.isValid() ? NameLoc : StartLoc,
-                           PrevSpec, DiagID, Type.get()))
+                           PrevSpec, DiagID, Type.get(),
+                           Actions.getASTContext().getPrintingPolicy()))
       Diag(StartLoc, DiagID) << PrevSpec;
 
     return;
@@ -3698,7 +3768,8 @@
 
   if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc,
                          NameLoc.isValid() ? NameLoc : StartLoc,
-                         PrevSpec, DiagID, TagDecl, Owned))
+                         PrevSpec, DiagID, TagDecl, Owned,
+                         Actions.getASTContext().getPrintingPolicy()))
     Diag(StartLoc, DiagID) << PrevSpec;
 }
 
@@ -3714,7 +3785,7 @@
 ///
 void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
   // Enter the scope of the enum body and start the definition.
-  ParseScope EnumScope(this, Scope::DeclScope);
+  ParseScope EnumScope(this, Scope::DeclScope | Scope::EnumScope);
   Actions.ActOnTagStartDefinition(getCurScope(), EnumDecl);
 
   BalancedDelimiterTracker T(*this, tok::l_brace);
@@ -3726,10 +3797,19 @@
 
   SmallVector<Decl *, 32> EnumConstantDecls;
 
-  Decl *LastEnumConstDecl = 0;
+  Decl *LastEnumConstDecl = nullptr;
 
   // Parse the enumerator-list.
-  while (Tok.is(tok::identifier)) {
+  while (Tok.isNot(tok::r_brace)) {
+    // Parse enumerator. If failed, try skipping till the start of the next
+    // enumerator definition.
+    if (Tok.isNot(tok::identifier)) {
+      Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
+      if (SkipUntil(tok::comma, tok::r_brace, StopBeforeMatch) &&
+          TryConsumeToken(tok::comma))
+        continue;
+      break;
+    }
     IdentifierInfo *Ident = Tok.getIdentifierInfo();
     SourceLocation IdentLoc = ConsumeToken();
 
@@ -3743,11 +3823,10 @@
     ExprResult AssignedVal;
     ParsingDeclRAIIObject PD(*this, ParsingDeclRAIIObject::NoParent);
 
-    if (Tok.is(tok::equal)) {
-      EqualLoc = ConsumeToken();
+    if (TryConsumeToken(tok::equal, EqualLoc)) {
       AssignedVal = ParseConstantExpression();
       if (AssignedVal.isInvalid())
-        SkipUntil(tok::comma, tok::r_brace, StopAtSemi | StopBeforeMatch);
+        SkipUntil(tok::comma, tok::r_brace, StopBeforeMatch);
     }
 
     // Install the enumerator constant into EnumDecl.
@@ -3755,7 +3834,7 @@
                                                     LastEnumConstDecl,
                                                     IdentLoc, Ident,
                                                     attrs.getList(), EqualLoc,
-                                                    AssignedVal.release());
+                                                    AssignedVal.get());
     PD.complete(EnumConstDecl);
 
     EnumConstantDecls.push_back(EnumConstDecl);
@@ -3769,11 +3848,25 @@
       continue;
     }
 
-    if (Tok.isNot(tok::comma))
-      break;
-    SourceLocation CommaLoc = ConsumeToken();
+    // Emumerator definition must be finished, only comma or r_brace are
+    // allowed here.
+    SourceLocation CommaLoc;
+    if (Tok.isNot(tok::r_brace) && !TryConsumeToken(tok::comma, CommaLoc)) {
+      if (EqualLoc.isValid())
+        Diag(Tok.getLocation(), diag::err_expected_either) << tok::r_brace
+                                                           << tok::comma;
+      else
+        Diag(Tok.getLocation(), diag::err_expected_end_of_enumerator);
+      if (SkipUntil(tok::comma, tok::r_brace, StopBeforeMatch)) {
+        if (TryConsumeToken(tok::comma, CommaLoc))
+          continue;
+      } else {
+        break;
+      }
+    }
 
-    if (Tok.isNot(tok::identifier)) {
+    // If comma is followed by r_brace, emit appropriate warning.
+    if (Tok.is(tok::r_brace) && CommaLoc.isValid()) {
       if (!getLangOpts().C99 && !getLangOpts().CPlusPlus11)
         Diag(CommaLoc, getLangOpts().CPlusPlus ?
                diag::ext_enumerator_list_comma_cxx :
@@ -3782,6 +3875,7 @@
       else if (getLangOpts().CPlusPlus11)
         Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)
           << FixItHint::CreateRemoval(CommaLoc);
+      break;
     }
   }
 
@@ -3805,7 +3899,7 @@
   // was probably forgotten.
   bool CanBeBitfield = getCurScope()->getFlags() & Scope::ClassScope;
   if (!isValidAfterTypeSpecifier(CanBeBitfield)) {
-    ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl, "enum");
+    ExpectAndConsume(tok::semi, diag::err_expected_after, "enum");
     // Push this token back into the preprocessor and change our current token
     // to ';' so that the rest of the code recovers as though there were an
     // ';' after the definition.
@@ -3819,12 +3913,7 @@
 bool Parser::isTypeQualifier() const {
   switch (Tok.getKind()) {
   default: return false;
-
-    // type-qualifier only in OpenCL
-  case tok::kw_private:
-    return getLangOpts().OpenCL;
-
-    // type-qualifier
+  // type-qualifier
   case tok::kw_const:
   case tok::kw_volatile:
   case tok::kw_restrict:
@@ -3870,16 +3959,6 @@
   case tok::kw__Decimal128:
   case tok::kw___vector:
 
-    // OpenCL specific types:
-  case tok::kw_image1d_t:
-  case tok::kw_image1d_array_t:
-  case tok::kw_image1d_buffer_t:
-  case tok::kw_image2d_t:
-  case tok::kw_image2d_array_t:
-  case tok::kw_image3d_t:
-  case tok::kw_sampler_t:
-  case tok::kw_event_t:
-
     // struct-or-union-specifier (C99) or class-specifier (C++)
   case tok::kw_class:
   case tok::kw_struct:
@@ -3952,16 +4031,6 @@
   case tok::kw__Decimal128:
   case tok::kw___vector:
 
-    // OpenCL specific types:
-  case tok::kw_image1d_t:
-  case tok::kw_image1d_array_t:
-  case tok::kw_image1d_buffer_t:
-  case tok::kw_image2d_t:
-  case tok::kw_image2d_array_t:
-  case tok::kw_image3d_t:
-  case tok::kw_sampler_t:
-  case tok::kw_event_t:
-
     // struct-or-union-specifier (C99) or class-specifier (C++)
   case tok::kw_class:
   case tok::kw_struct:
@@ -4006,9 +4075,6 @@
 
     return true;
 
-  case tok::kw_private:
-    return getLangOpts().OpenCL;
-
   // C11 _Atomic
   case tok::kw__Atomic:
     return true;
@@ -4024,9 +4090,6 @@
   switch (Tok.getKind()) {
   default: return false;
 
-  case tok::kw_private:
-    return getLangOpts().OpenCL;
-
   case tok::identifier:   // foo::bar
     // Unfortunate hack to support "Class.factoryMethod" notation.
     if (getLangOpts().ObjC1 && NextToken().is(tok::period))
@@ -4108,16 +4171,6 @@
   case tok::kw__Decimal128:
   case tok::kw___vector:
 
-    // OpenCL specific types:
-  case tok::kw_image1d_t:
-  case tok::kw_image1d_array_t:
-  case tok::kw_image1d_buffer_t:
-  case tok::kw_image2d_t:
-  case tok::kw_image2d_array_t:
-  case tok::kw_image3d_t:
-  case tok::kw_sampler_t:
-  case tok::kw_event_t:
-
     // struct-or-union-specifier (C99) or class-specifier (C++)
   case tok::kw_class:
   case tok::kw_struct:
@@ -4195,7 +4248,7 @@
   }
 }
 
-bool Parser::isConstructorDeclarator() {
+bool Parser::isConstructorDeclarator(bool IsUnqualified) {
   TentativeParsingAction TPA(*this);
 
   // Parse the C++ scope specifier.
@@ -4277,12 +4330,35 @@
     case tok::coloncolon:
       // C(X   ::   Y);
       // C(X   ::   *p);
-    case tok::r_paren:
-      // C(X   )
       // Assume this isn't a constructor, rather than assuming it's a
       // constructor with an unnamed parameter of an ill-formed type.
       break;
 
+    case tok::r_paren:
+      // C(X   )
+      if (NextToken().is(tok::colon) || NextToken().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 we have a constructor name within the class definition,
+        // assume these were meant to be constructors:
+        //   C(X)   {
+        //   C(X)   ;
+        // ... because otherwise we would be declaring a non-static data
+        // member that is ill-formed because it's of the same type as its
+        // surrounding class.
+        //
+        // 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
+        // currently, so we're somewhat conservative here.
+        IsConstructor = IsUnqualified;
+      }
+      break;
+
     default:
       IsConstructor = true;
       break;
@@ -4308,7 +4384,8 @@
 void Parser::ParseTypeQualifierListOpt(DeclSpec &DS,
                                        bool VendorAttributesAllowed,
                                        bool CXX11AttributesAllowed,
-                                       bool AtomicAllowed) {
+                                       bool AtomicAllowed,
+                                       bool IdentifierRequired) {
   if (getLangOpts().CPlusPlus11 && CXX11AttributesAllowed &&
       isCXX11AttributeSpecifier()) {
     ParsedAttributesWithRange attrs(AttrFactory);
@@ -4320,7 +4397,7 @@
 
   while (1) {
     bool isInvalid = false;
-    const char *PrevSpec = 0;
+    const char *PrevSpec = nullptr;
     unsigned DiagID = 0;
     SourceLocation Loc = Tok.getLocation();
 
@@ -4349,9 +4426,6 @@
       break;
 
     // OpenCL qualifiers:
-    case tok::kw_private:
-      if (!getLangOpts().OpenCL)
-        goto DoneWithTypeQuals;
     case tok::kw___private:
     case tok::kw___global:
     case tok::kw___local:
@@ -4359,11 +4433,18 @@
     case tok::kw___read_only:
     case tok::kw___write_only:
     case tok::kw___read_write:
-      ParseOpenCLQualifiers(DS);
+      ParseOpenCLQualifiers(DS.getAttributes());
       break;
 
-    case tok::kw___sptr:
     case tok::kw___uptr:
+      // GNU libc headers in C mode use '__uptr' as an identifer which conflicts
+      // with the MS modifier keyword.
+      if (VendorAttributesAllowed && !getLangOpts().CPlusPlus &&
+          IdentifierRequired && DS.isEmpty() && NextToken().is(tok::semi)) {
+        if (TryKeywordIdentFallback(false))
+          continue;
+      }
+    case tok::kw___sptr:
     case tok::kw___w64:
     case tok::kw___ptr64:
     case tok::kw___ptr32:
@@ -4393,7 +4474,7 @@
       DoneWithTypeQuals:
       // If this is not a type-qualifier token, we're done reading type
       // qualifiers.  First verify that DeclSpec's are consistent.
-      DS.Finish(Diags, PP);
+      DS.Finish(Diags, PP, Actions.getASTContext().getPrintingPolicy());
       if (EndLoc.isValid())
         DS.SetRangeEnd(EndLoc);
       return;
@@ -4462,7 +4543,9 @@
   // Member pointers get special handling, since there's no place for the
   // scope spec in the generic path below.
   if (getLangOpts().CPlusPlus &&
-      (Tok.is(tok::coloncolon) || Tok.is(tok::identifier) ||
+      (Tok.is(tok::coloncolon) ||
+       (Tok.is(tok::identifier) &&
+        (NextToken().is(tok::coloncolon) || NextToken().is(tok::less))) ||
        Tok.is(tok::annot_cxxscope))) {
     bool EnteringContext = D.getContext() == Declarator::FileContext ||
                            D.getContext() == Declarator::MemberContext;
@@ -4519,7 +4602,7 @@
     DeclSpec DS(AttrFactory);
 
     // FIXME: GNU attributes are not allowed here in a new-type-id.
-    ParseTypeQualifierListOpt(DS);
+    ParseTypeQualifierListOpt(DS, true, true, true, !D.mayOmitIdentifier());
     D.ExtendWithDeclSpec(DS);
 
     // Recursively parse the declarator.
@@ -4597,17 +4680,17 @@
   }
 }
 
-static void diagnoseMisplacedEllipsis(Parser &P, Declarator &D,
-                                      SourceLocation EllipsisLoc) {
-  if (EllipsisLoc.isValid()) {
-    FixItHint Insertion;
-    if (!D.getEllipsisLoc().isValid()) {
-      Insertion = FixItHint::CreateInsertion(D.getIdentifierLoc(), "...");
-      D.setEllipsisLoc(EllipsisLoc);
-    }
-    P.Diag(EllipsisLoc, diag::err_misplaced_ellipsis_in_declaration)
-      << FixItHint::CreateRemoval(EllipsisLoc) << Insertion << !D.hasName();
-  }
+// When correcting from misplaced brackets before the identifier, the location
+// is saved inside the declarator so that other diagnostic messages can use
+// them.  This extracts and returns that location, or returns the provided
+// location if a stored location does not exist.
+static SourceLocation getMissingDeclaratorIdLoc(Declarator &D,
+                                                SourceLocation Loc) {
+  if (D.getName().StartLocation.isInvalid() &&
+      D.getName().EndLocation.isValid())
+    return D.getName().EndLocation;
+
+  return Loc;
 }
 
 /// ParseDirectDeclarator
@@ -4655,6 +4738,14 @@
   DeclaratorScopeObj DeclScopeObj(*this, D.getCXXScopeSpec());
 
   if (getLangOpts().CPlusPlus && D.mayHaveIdentifier()) {
+    // Don't parse FOO:BAR as if it were a typo for FOO::BAR inside a class, in
+    // this context it is a bitfield. Also in range-based for statement colon
+    // may delimit for-range-declaration.
+    ColonProtectionRAIIObject X(*this,
+                                D.getContext() == Declarator::MemberContext ||
+                                    (D.getContext() == Declarator::ForContext &&
+                                     getLangOpts().CPlusPlus11));
+
     // ParseDeclaratorInternal might already have parsed the scope.
     if (D.getCXXScopeSpec().isEmpty()) {
       bool EnteringContext = D.getContext() == Declarator::FileContext ||
@@ -4689,7 +4780,8 @@
         // The ellipsis was put in the wrong place. Recover, and explain to
         // the user what they should have done.
         ParseDeclarator(D);
-        diagnoseMisplacedEllipsis(*this, D, EllipsisLoc);
+        if (EllipsisLoc.isValid())
+          DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
         return;
       } else
         D.setEllipsisLoc(EllipsisLoc);
@@ -4724,7 +4816,7 @@
           // Once we're past the identifier, if the scope was bad, mark the
           // whole declarator bad.
           D.getCXXScopeSpec().isInvalid()) {
-        D.SetIdentifier(0, Tok.getLocation());
+        D.SetIdentifier(nullptr, Tok.getLocation());
         D.setInvalidType(true);
       } else {
         // Parsed the unqualified-id; update range information and move along.
@@ -4739,6 +4831,7 @@
            "There's a C++-specific check for tok::identifier above");
     assert(Tok.getIdentifierInfo() && "Not an identifier?");
     D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
+    D.SetRangeEnd(Tok.getLocation());
     ConsumeToken();
     goto PastIdentifier;
   } else if (Tok.is(tok::identifier) && D.diagnoseIdentifier()) {
@@ -4748,7 +4841,7 @@
         !isCXX11VirtSpecifier(Tok)) {
       Diag(Tok.getLocation(), diag::err_unexpected_unqualified_id)
         << FixItHint::CreateRemoval(Tok.getLocation());
-      D.SetIdentifier(0, Tok.getLocation());
+      D.SetIdentifier(nullptr, Tok.getLocation());
       ConsumeToken();
       goto PastIdentifier;
     }
@@ -4775,7 +4868,7 @@
   } else if (D.mayOmitIdentifier()) {
     // This could be something simple like "int" (in which case the declarator
     // portion is empty), if an abstract-declarator is allowed.
-    D.SetIdentifier(0, Tok.getLocation());
+    D.SetIdentifier(nullptr, Tok.getLocation());
 
     // The grammar for abstract-pack-declarator does not allow grouping parens.
     // FIXME: Revisit this once core issue 1488 is resolved.
@@ -4785,10 +4878,14 @@
   } else {
     if (Tok.getKind() == tok::annot_pragma_parser_crash)
       LLVM_BUILTIN_TRAP;
-    if (D.getContext() == Declarator::MemberContext)
-      Diag(Tok, diag::err_expected_member_name_or_semi)
-        << D.getDeclSpec().getSourceRange();
-    else if (getLangOpts().CPlusPlus) {
+    if (Tok.is(tok::l_square))
+      return ParseMisplacedBracketDeclarator(D);
+    if (D.getContext() == Declarator::MemberContext) {
+      Diag(getMissingDeclaratorIdLoc(D, Tok.getLocation()),
+           diag::err_expected_member_name_or_semi)
+          << (D.getDeclSpec().isEmpty() ? SourceRange()
+                                        : D.getDeclSpec().getSourceRange());
+    } else if (getLangOpts().CPlusPlus) {
       if (Tok.is(tok::period) || Tok.is(tok::arrow))
         Diag(Tok, diag::err_invalid_operator_on_type) << Tok.is(tok::arrow);
       else {
@@ -4797,12 +4894,16 @@
           Diag(PP.getLocForEndOfToken(Loc), diag::err_expected_unqualified_id)
               << getLangOpts().CPlusPlus;
         else
-          Diag(Tok, diag::err_expected_unqualified_id)
+          Diag(getMissingDeclaratorIdLoc(D, Tok.getLocation()),
+               diag::err_expected_unqualified_id)
               << getLangOpts().CPlusPlus;
       }
-    } else
-      Diag(Tok, diag::err_expected_ident_lparen);
-    D.SetIdentifier(0, Tok.getLocation());
+    } else {
+      Diag(getMissingDeclaratorIdLoc(D, Tok.getLocation()),
+           diag::err_expected_either)
+          << tok::identifier << tok::l_paren;
+    }
+    D.SetIdentifier(nullptr, Tok.getLocation());
     D.setInvalidType(true);
   }
 
@@ -4938,7 +5039,7 @@
 
     // An ellipsis cannot be placed outside parentheses.
     if (EllipsisLoc.isValid())
-      diagnoseMisplacedEllipsis(*this, D, EllipsisLoc);
+      DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, D);
 
     return;
   }
@@ -4947,7 +5048,7 @@
   // argument list.  Recognize that this declarator will never have an
   // identifier (and remember where it would have been), then call into
   // ParseFunctionDeclarator to handle of argument list.
-  D.SetIdentifier(0, Tok.getLocation());
+  D.SetIdentifier(nullptr, Tok.getLocation());
 
   // Enter function-declaration scope, limiting any declarators to the
   // function prototype scope, including parameter declarators.
@@ -5009,7 +5110,6 @@
   ParsedAttributes FnAttrs(AttrFactory);
   TypeResult TrailingReturnType;
 
-  Actions.ActOnStartFunctionDeclarator();
   /* LocalEndLoc is the end location for the local FunctionTypeLoc.
      EndLoc is the end location for the function declarator.
      They differ for trailing return types. */
@@ -5078,6 +5178,7 @@
       // FIXME: currently, "static" case isn't handled correctly.
       bool IsCXX11MemberFunction =
         getLangOpts().CPlusPlus11 &&
+        D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef &&
         (D.getContext() == Declarator::MemberContext
          ? !D.getDeclSpec().isFriendSpecified()
          : D.getContext() == Declarator::FileContext &&
@@ -5133,12 +5234,10 @@
                                              DynamicExceptionRanges.data(),
                                              DynamicExceptions.size(),
                                              NoexceptExpr.isUsable() ?
-                                               NoexceptExpr.get() : 0,
+                                               NoexceptExpr.get() : nullptr,
                                              StartLoc, LocalEndLoc, D,
                                              TrailingReturnType),
                 FnAttrs, EndLoc);
-
-  Actions.ActOnEndFunctionDeclarator();
 }
 
 /// isFunctionDeclaratorIdentifierList - This parameter list may have an
@@ -5190,10 +5289,10 @@
   // Maintain an efficient lookup of params we have seen so far.
   llvm::SmallSet<const IdentifierInfo*, 16> ParamsSoFar;
 
-  while (1) {
+  do {
     // If this isn't an identifier, report the error and skip until ')'.
     if (Tok.isNot(tok::identifier)) {
-      Diag(Tok, diag::err_expected_ident);
+      Diag(Tok, diag::err_expected) << tok::identifier;
       SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch);
       // Forget we parsed anything.
       ParamInfo.clear();
@@ -5213,17 +5312,13 @@
       // Remember this identifier in ParamInfo.
       ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
                                                      Tok.getLocation(),
-                                                     0));
+                                                     nullptr));
     }
 
     // Eat the identifier.
     ConsumeToken();
-
     // The list continues if we see a comma.
-    if (Tok.isNot(tok::comma))
-      break;
-    ConsumeToken();
-  }
+  } while (TryConsumeToken(tok::comma));
 }
 
 /// ParseParameterDeclarationClause - Parse a (possibly empty) parameter-list
@@ -5262,13 +5357,11 @@
        ParsedAttributes &FirstArgAttrs,
        SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo,
        SourceLocation &EllipsisLoc) {
-  while (1) {
-    if (Tok.is(tok::ellipsis)) {
-      // FIXME: Issue a diagnostic if we parsed an attribute-specifier-seq
-      // before deciding this was a parameter-declaration-clause.
-      EllipsisLoc = ConsumeToken();     // Consume the ellipsis.
+  do {
+    // FIXME: Issue a diagnostic if we parsed an attribute-specifier-seq
+    // before deciding this was a parameter-declaration-clause.
+    if (TryConsumeToken(tok::ellipsis, EllipsisLoc))
       break;
-    }
 
     // Parse the declaration-specifiers.
     // Just use the ParsingDeclaration "scope" of the declarator.
@@ -5309,11 +5402,11 @@
 
     // DefArgToks is used when the parsing of default arguments needs
     // to be delayed.
-    CachedTokens *DefArgToks = 0;
+    CachedTokens *DefArgToks = nullptr;
 
     // If no parameter was specified, verify that *something* was specified,
     // otherwise we have a missing type and identifier.
-    if (DS.isEmpty() && ParmDeclarator.getIdentifier() == 0 &&
+    if (DS.isEmpty() && ParmDeclarator.getIdentifier() == nullptr &&
         ParmDeclarator.getNumTypeObjects() == 0) {
       // Completely missing, emit error.
       Diag(DSStart, diag::err_missing_param);
@@ -5342,8 +5435,8 @@
 
           if (!ConsumeAndStoreInitializer(*DefArgToks, CIK_DefaultArgument)) {
             delete DefArgToks;
-            DefArgToks = 0;
-            Actions.ActOnParamDefaultArgumentError(Param);
+            DefArgToks = nullptr;
+            Actions.ActOnParamDefaultArgumentError(Param, EqualLoc);
           } else {
             // Mark the end of the default argument so that we know when to
             // stop when we parse it later on.
@@ -5372,12 +5465,12 @@
           } else
             DefArgResult = ParseAssignmentExpression();
           if (DefArgResult.isInvalid()) {
-            Actions.ActOnParamDefaultArgumentError(Param);
+            Actions.ActOnParamDefaultArgumentError(Param, EqualLoc);
             SkipUntil(tok::comma, tok::r_paren, StopAtSemi | StopBeforeMatch);
           } else {
             // Inform the actions module about the default argument
             Actions.ActOnParamDefaultArgument(Param, EqualLoc,
-                                              DefArgResult.take());
+                                              DefArgResult.get());
           }
         }
       }
@@ -5387,26 +5480,17 @@
                                           Param, DefArgToks));
     }
 
-    // If the next token is a comma, consume it and keep reading arguments.
-    if (Tok.isNot(tok::comma)) {
-      if (Tok.is(tok::ellipsis)) {
-        EllipsisLoc = ConsumeToken();     // Consume the ellipsis.
-
-        if (!getLangOpts().CPlusPlus) {
-          // We have ellipsis without a preceding ',', which is ill-formed
-          // in C. Complain and provide the fix.
-          Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
-            << FixItHint::CreateInsertion(EllipsisLoc, ", ");
-        }
-      }
-
+    if (TryConsumeToken(tok::ellipsis, EllipsisLoc) &&
+        !getLangOpts().CPlusPlus) {
+      // We have ellipsis without a preceding ',', which is ill-formed
+      // in C. Complain and provide the fix.
+      Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
+          << FixItHint::CreateInsertion(EllipsisLoc, ", ");
       break;
     }
 
-    // Consume the comma.
-    ConsumeToken();
-  }
-
+    // If the next token is a comma, consume it and keep reading arguments.
+  } while (TryConsumeToken(tok::comma));
 }
 
 /// [C90]   direct-declarator '[' constant-expression[opt] ']'
@@ -5431,8 +5515,7 @@
     MaybeParseCXX11Attributes(attrs);
 
     // Remember that we parsed the empty array type.
-    ExprResult NumElements;
-    D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, 0,
+    D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, nullptr,
                                             T.getOpenLocation(),
                                             T.getCloseLocation()),
                   attrs, T.getCloseLocation());
@@ -5449,7 +5532,7 @@
 
     // Remember that we parsed a array type, and remember its features.
     D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false,
-                                            ExprRes.release(),
+                                            ExprRes.get(),
                                             T.getOpenLocation(),
                                             T.getCloseLocation()),
                   attrs, T.getCloseLocation());
@@ -5458,8 +5541,7 @@
 
   // If valid, this location is the position where we read the 'static' keyword.
   SourceLocation StaticLoc;
-  if (Tok.is(tok::kw_static))
-    StaticLoc = ConsumeToken();
+  TryConsumeToken(tok::kw_static, StaticLoc);
 
   // If there is a type-qualifier-list, read it now.
   // Type qualifiers in an array subscript are a C99 feature.
@@ -5468,8 +5550,8 @@
 
   // If we haven't already read 'static', check to see if there is one after the
   // type-qualifier-list.
-  if (!StaticLoc.isValid() && Tok.is(tok::kw_static))
-    StaticLoc = ConsumeToken();
+  if (!StaticLoc.isValid())
+    TryConsumeToken(tok::kw_static, StaticLoc);
 
   // Handle "direct-declarator [ type-qual-list[opt] * ]".
   bool isStar = false;
@@ -5520,12 +5602,102 @@
   // Remember that we parsed a array type, and remember its features.
   D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(),
                                           StaticLoc.isValid(), isStar,
-                                          NumElements.release(),
+                                          NumElements.get(),
                                           T.getOpenLocation(),
                                           T.getCloseLocation()),
                 attrs, T.getCloseLocation());
 }
 
+/// Diagnose brackets before an identifier.
+void Parser::ParseMisplacedBracketDeclarator(Declarator &D) {
+  assert(Tok.is(tok::l_square) && "Missing opening bracket");
+  assert(!D.mayOmitIdentifier() && "Declarator cannot omit identifier");
+
+  SourceLocation StartBracketLoc = Tok.getLocation();
+  Declarator TempDeclarator(D.getDeclSpec(), D.getContext());
+
+  while (Tok.is(tok::l_square)) {
+    ParseBracketDeclarator(TempDeclarator);
+  }
+
+  // Stuff the location of the start of the brackets into the Declarator.
+  // The diagnostics from ParseDirectDeclarator will make more sense if
+  // they use this location instead.
+  if (Tok.is(tok::semi))
+    D.getName().EndLocation = StartBracketLoc;
+
+  SourceLocation SuggestParenLoc = Tok.getLocation();
+
+  // Now that the brackets are removed, try parsing the declarator again.
+  ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
+
+  // Something went wrong parsing the brackets, in which case,
+  // ParseBracketDeclarator has emitted an error, and we don't need to emit
+  // one here.
+  if (TempDeclarator.getNumTypeObjects() == 0)
+    return;
+
+  // Determine if parens will need to be suggested in the diagnostic.
+  bool NeedParens = false;
+  if (D.getNumTypeObjects() != 0) {
+    switch (D.getTypeObject(D.getNumTypeObjects() - 1).Kind) {
+    case DeclaratorChunk::Pointer:
+    case DeclaratorChunk::Reference:
+    case DeclaratorChunk::BlockPointer:
+    case DeclaratorChunk::MemberPointer:
+      NeedParens = true;
+      break;
+    case DeclaratorChunk::Array:
+    case DeclaratorChunk::Function:
+    case DeclaratorChunk::Paren:
+      break;
+    }
+  }
+
+  if (NeedParens) {
+    // Create a DeclaratorChunk for the inserted parens.
+    ParsedAttributes attrs(AttrFactory);
+    SourceLocation EndLoc = PP.getLocForEndOfToken(D.getLocEnd());
+    D.AddTypeInfo(DeclaratorChunk::getParen(SuggestParenLoc, EndLoc), attrs,
+                  SourceLocation());
+  }
+
+  // Adding back the bracket info to the end of the Declarator.
+  for (unsigned i = 0, e = TempDeclarator.getNumTypeObjects(); i < e; ++i) {
+    const DeclaratorChunk &Chunk = TempDeclarator.getTypeObject(i);
+    ParsedAttributes attrs(AttrFactory);
+    attrs.set(Chunk.Common.AttrList);
+    D.AddTypeInfo(Chunk, attrs, SourceLocation());
+  }
+
+  // The missing identifier would have been diagnosed in ParseDirectDeclarator.
+  // If parentheses are required, always suggest them.
+  if (!D.getIdentifier() && !NeedParens)
+    return;
+
+  SourceLocation EndBracketLoc = TempDeclarator.getLocEnd();
+
+  // Generate the move bracket error message.
+  SourceRange BracketRange(StartBracketLoc, EndBracketLoc);
+  SourceLocation EndLoc = PP.getLocForEndOfToken(D.getLocEnd());
+
+  if (NeedParens) {
+    Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
+        << getLangOpts().CPlusPlus
+        << FixItHint::CreateInsertion(SuggestParenLoc, "(")
+        << FixItHint::CreateInsertion(EndLoc, ")")
+        << FixItHint::CreateInsertionFromRange(
+               EndLoc, CharSourceRange(BracketRange, true))
+        << FixItHint::CreateRemoval(BracketRange);
+  } else {
+    Diag(EndLoc, diag::err_brackets_go_after_unqualified_id)
+        << getLangOpts().CPlusPlus
+        << FixItHint::CreateInsertionFromRange(
+               EndLoc, CharSourceRange(BracketRange, true))
+        << FixItHint::CreateRemoval(BracketRange);
+  }
+}
+
 /// [GNU]   typeof-specifier:
 ///           typeof ( expressions )
 ///           typeof ( type-name )
@@ -5561,11 +5733,12 @@
       return;
     }
 
-    const char *PrevSpec = 0;
+    const char *PrevSpec = nullptr;
     unsigned DiagID;
     // Check for duplicate type specifiers (e.g. "int typeof(int)").
     if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec,
-                           DiagID, CastTy))
+                           DiagID, CastTy,
+                           Actions.getASTContext().getPrintingPolicy()))
       Diag(StartLoc, DiagID) << PrevSpec;
     return;
   }
@@ -5583,11 +5756,12 @@
     return;
   }
 
-  const char *PrevSpec = 0;
+  const char *PrevSpec = nullptr;
   unsigned DiagID;
   // Check for duplicate type specifiers (e.g. "int typeof(int)").
   if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec,
-                         DiagID, Operand.get()))
+                         DiagID, Operand.get(),
+                         Actions.getASTContext().getPrintingPolicy()))
     Diag(StartLoc, DiagID) << PrevSpec;
 }
 
@@ -5618,10 +5792,11 @@
   DS.setTypeofParensRange(T.getRange());
   DS.SetRangeEnd(T.getCloseLocation());
 
-  const char *PrevSpec = 0;
+  const char *PrevSpec = nullptr;
   unsigned DiagID;
   if (DS.SetTypeSpecType(DeclSpec::TST_atomic, StartLoc, PrevSpec,
-                         DiagID, Result.release()))
+                         DiagID, Result.get(),
+                         Actions.getASTContext().getPrintingPolicy()))
     Diag(StartLoc, DiagID) << PrevSpec;
 }
 
@@ -5661,6 +5836,7 @@
 bool Parser::TryAltiVecTokenOutOfLine(DeclSpec &DS, SourceLocation Loc,
                                       const char *&PrevSpec, unsigned &DiagID,
                                       bool &isInvalid) {
+  const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
   if (Tok.getIdentifierInfo() == Ident_vector) {
     Token Next = NextToken();
     switch (Next.getKind()) {
@@ -5675,15 +5851,15 @@
     case tok::kw_double:
     case tok::kw_bool:
     case tok::kw___pixel:
-      isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
+      isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID, Policy);
       return true;
     case tok::identifier:
       if (Next.getIdentifierInfo() == Ident_pixel) {
-        isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
+        isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID,Policy);
         return true;
       }
       if (Next.getIdentifierInfo() == Ident_bool) {
-        isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
+        isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID,Policy);
         return true;
       }
       break;
@@ -5692,11 +5868,11 @@
     }
   } else if ((Tok.getIdentifierInfo() == Ident_pixel) &&
              DS.isTypeAltiVecVector()) {
-    isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID);
+    isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID, Policy);
     return true;
   } else if ((Tok.getIdentifierInfo() == Ident_bool) &&
              DS.isTypeAltiVecVector()) {
-    isInvalid = DS.SetTypeAltiVecBool(true, Loc, PrevSpec, DiagID);
+    isInvalid = DS.SetTypeAltiVecBool(true, Loc, PrevSpec, DiagID, Policy);
     return true;
   }
   return false;
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index bf615f0..6200363 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -13,9 +13,12 @@
 
 #include "clang/Parse/Parser.h"
 #include "RAIIObjectsForParser.h"
-#include "clang/Basic/CharInfo.h"
-#include "clang/Basic/OperatorKinds.h"
+#include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclTemplate.h"
+#include "clang/Basic/Attributes.h"
+#include "clang/Basic/CharInfo.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/OperatorKinds.h"
 #include "clang/Parse/ParseDiagnostic.h"
 #include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/ParsedTemplate.h"
@@ -61,11 +64,11 @@
   if (Tok.is(tok::code_completion)) {
     Actions.CodeCompleteNamespaceDecl(getCurScope());
     cutOffParsing();
-    return 0;
+    return nullptr;
   }
 
   SourceLocation IdentLoc;
-  IdentifierInfo *Ident = 0;
+  IdentifierInfo *Ident = nullptr;
   std::vector<SourceLocation> ExtraIdentLoc;
   std::vector<IdentifierInfo*> ExtraIdent;
   std::vector<SourceLocation> ExtraNamespaceLoc;
@@ -90,11 +93,11 @@
   }
 
   if (Tok.is(tok::equal)) {
-    if (Ident == 0) {
-      Diag(Tok, diag::err_expected_ident);
+    if (!Ident) {
+      Diag(Tok, diag::err_expected) << tok::identifier;
       // Skip to end of the definition and eat the ';'.
       SkipUntil(tok::semi);
-      return 0;
+      return nullptr;
     }
     if (!attrs.empty())
       Diag(attrTok, diag::err_unexpected_namespace_attributes_alias);
@@ -111,9 +114,13 @@
       Diag(ExtraNamespaceLoc[0], diag::err_nested_namespaces_with_double_colon)
           << SourceRange(ExtraNamespaceLoc.front(), ExtraIdentLoc.back());
     }
-    Diag(Tok, Ident ? diag::err_expected_lbrace :
-         diag::err_expected_ident_lbrace);
-    return 0;
+
+    if (Ident)
+      Diag(Tok, diag::err_expected) << tok::l_brace;
+    else
+      Diag(Tok, diag::err_expected_either) << tok::identifier << tok::l_brace;
+
+    return nullptr;
   }
 
   if (getCurScope()->isClassScope() || getCurScope()->isTemplateParamScope() || 
@@ -125,7 +132,7 @@
     }
     Diag(T.getOpenLocation(), diag::err_namespace_nonnamespace_scope);
     SkipUntil(tok::r_brace);
-    return 0;
+    return nullptr;
   }
 
   if (!ExtraIdent.empty()) {
@@ -195,7 +202,7 @@
                                  ParsedAttributes& attrs,
                                  BalancedDelimiterTracker &Tracker) {
   if (index == Ident.size()) {
-    while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
+    while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
       ParsedAttributesWithRange attrs(AttrFactory);
       MaybeParseCXX11Attributes(attrs);
       MaybeParseMicrosoftAttributes(attrs);
@@ -239,7 +246,7 @@
   if (Tok.is(tok::code_completion)) {
     Actions.CodeCompleteNamespaceAliasDecl(getCurScope());
     cutOffParsing();
-    return 0;
+    return nullptr;
   }
 
   CXXScopeSpec SS;
@@ -250,7 +257,7 @@
     Diag(Tok, diag::err_expected_namespace_name);
     // Skip to end of the definition and eat the ';'.
     SkipUntil(tok::semi);
-    return 0;
+    return nullptr;
   }
 
   // Parse identifier.
@@ -259,8 +266,8 @@
 
   // Eat the ';'.
   DeclEnd = Tok.getLocation();
-  ExpectAndConsume(tok::semi, diag::err_expected_semi_after_namespace_name,
-                   "", tok::semi);
+  if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after_namespace_name))
+    SkipUntil(tok::semi);
 
   return Actions.ActOnNamespaceAliasDef(getCurScope(), NamespaceLoc, AliasLoc, Alias,
                                         SS, IdentLoc, Ident);
@@ -274,27 +281,16 @@
 ///         'extern' string-literal declaration
 ///
 Decl *Parser::ParseLinkage(ParsingDeclSpec &DS, unsigned Context) {
-  assert(Tok.is(tok::string_literal) && "Not a string literal!");
-  SmallString<8> LangBuffer;
-  bool Invalid = false;
-  StringRef Lang = PP.getSpelling(Tok, LangBuffer, &Invalid);
-  if (Invalid)
-    return 0;
-
-  // FIXME: This is incorrect: linkage-specifiers are parsed in translation
-  // phase 7, so string-literal concatenation is supposed to occur.
-  //   extern "" "C" "" "+" "+" { } is legal.
-  if (Tok.hasUDSuffix())
-    Diag(Tok, diag::err_invalid_string_udl);
-  SourceLocation Loc = ConsumeStringToken();
+  assert(isTokenStringLiteral() && "Not a string literal!");
+  ExprResult Lang = ParseStringLiteralExpression(false);
 
   ParseScope LinkageScope(this, Scope::DeclScope);
-  Decl *LinkageSpec
-    = Actions.ActOnStartLinkageSpecification(getCurScope(),
-                                             DS.getSourceRange().getBegin(),
-                                             Loc, Lang,
-                                      Tok.is(tok::l_brace) ? Tok.getLocation()
-                                                           : SourceLocation());
+  Decl *LinkageSpec =
+      Lang.isInvalid()
+          ? nullptr
+          : Actions.ActOnStartLinkageSpecification(
+                getCurScope(), DS.getSourceRange().getBegin(), Lang.get(),
+                Tok.is(tok::l_brace) ? Tok.getLocation() : SourceLocation());
 
   ParsedAttributesWithRange attrs(AttrFactory);
   MaybeParseCXX11Attributes(attrs);
@@ -308,8 +304,9 @@
     // ... but anyway remember that such an "extern" was seen.
     DS.setExternInLinkageSpec(true);
     ParseExternalDeclaration(attrs, &DS);
-    return Actions.ActOnFinishLinkageSpecification(getCurScope(), LinkageSpec,
-                                                   SourceLocation());
+    return LinkageSpec ? Actions.ActOnFinishLinkageSpecification(
+                             getCurScope(), LinkageSpec, SourceLocation())
+                       : nullptr;
   }
 
   DS.abort();
@@ -318,16 +315,48 @@
 
   BalancedDelimiterTracker T(*this, tok::l_brace);
   T.consumeOpen();
-  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
-    ParsedAttributesWithRange attrs(AttrFactory);
-    MaybeParseCXX11Attributes(attrs);
-    MaybeParseMicrosoftAttributes(attrs);
-    ParseExternalDeclaration(attrs);
+
+  unsigned NestedModules = 0;
+  while (true) {
+    switch (Tok.getKind()) {
+    case tok::annot_module_begin:
+      ++NestedModules;
+      ParseTopLevelDecl();
+      continue;
+
+    case tok::annot_module_end:
+      if (!NestedModules)
+        break;
+      --NestedModules;
+      ParseTopLevelDecl();
+      continue;
+
+    case tok::annot_module_include:
+      ParseTopLevelDecl();
+      continue;
+
+    case tok::eof:
+      break;
+
+    case tok::r_brace:
+      if (!NestedModules)
+        break;
+      // Fall through.
+    default:
+      ParsedAttributesWithRange attrs(AttrFactory);
+      MaybeParseCXX11Attributes(attrs);
+      MaybeParseMicrosoftAttributes(attrs);
+      ParseExternalDeclaration(attrs);
+      continue;
+    }
+
+    break;
   }
 
   T.consumeClose();
-  return Actions.ActOnFinishLinkageSpecification(getCurScope(), LinkageSpec,
-                                                 T.getCloseLocation());
+  return LinkageSpec ? Actions.ActOnFinishLinkageSpecification(
+                           getCurScope(), LinkageSpec, T.getCloseLocation())
+                     : nullptr;
 }
 
 /// ParseUsingDirectiveOrDeclaration - Parse C++ using using-declaration or
@@ -346,7 +375,7 @@
   if (Tok.is(tok::code_completion)) {
     Actions.CodeCompleteUsing(getCurScope());
     cutOffParsing();
-    return 0;
+    return nullptr;
   }
 
   // 'using namespace' means this is a using-directive.
@@ -392,14 +421,14 @@
   if (Tok.is(tok::code_completion)) {
     Actions.CodeCompleteUsingDirective(getCurScope());
     cutOffParsing();
-    return 0;
+    return nullptr;
   }
 
   CXXScopeSpec SS;
   // Parse (optional) nested-name-specifier.
   ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false);
 
-  IdentifierInfo *NamespcName = 0;
+  IdentifierInfo *NamespcName = nullptr;
   SourceLocation IdentLoc = SourceLocation();
 
   // Parse namespace-name.
@@ -408,7 +437,7 @@
     // If there was invalid namespace name, skip to end of decl, and eat ';'.
     SkipUntil(tok::semi);
     // FIXME: Are there cases, when we would like to call ActOnUsingDirective?
-    return 0;
+    return nullptr;
   }
 
   // Parse identifier.
@@ -424,10 +453,10 @@
 
   // Eat ';'.
   DeclEnd = Tok.getLocation();
-  ExpectAndConsume(tok::semi,
-                   GNUAttr ? diag::err_expected_semi_after_attribute_list
-                           : diag::err_expected_semi_after_namespace_name, 
-                   "", tok::semi);
+  if (ExpectAndConsume(tok::semi,
+                       GNUAttr ? diag::err_expected_semi_after_attribute_list
+                               : diag::err_expected_semi_after_namespace_name))
+    SkipUntil(tok::semi);
 
   return Actions.ActOnUsingDirective(getCurScope(), UsingLoc, NamespcLoc, SS,
                                      IdentLoc, NamespcName, attrs.getList());
@@ -461,21 +490,20 @@
 
   // Ignore optional 'typename'.
   // FIXME: This is wrong; we should parse this as a typename-specifier.
-  if (Tok.is(tok::kw_typename)) {
-    TypenameLoc = ConsumeToken();
+  if (TryConsumeToken(tok::kw_typename, TypenameLoc))
     HasTypenameKeyword = true;
-  }
 
   // Parse nested-name-specifier.
-  IdentifierInfo *LastII = 0;
+  IdentifierInfo *LastII = nullptr;
   ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false,
-                                 /*MayBePseudoDtor=*/0, /*IsTypename=*/false,
+                                 /*MayBePseudoDtor=*/nullptr,
+                                 /*IsTypename=*/false,
                                  /*LastII=*/&LastII);
 
   // Check nested-name specifier.
   if (SS.isInvalid()) {
     SkipUntil(tok::semi);
-    return 0;
+    return nullptr;
   }
 
   SourceLocation TemplateKWLoc;
@@ -504,7 +532,7 @@
                                 /*AllowConstructorName=*/ true, ParsedType(),
                                 TemplateKWLoc, Name)) {
     SkipUntil(tok::semi);
-    return 0;
+    return nullptr;
   }
 
   ParsedAttributesWithRange Attrs(AttrFactory);
@@ -551,7 +579,7 @@
       Diag(Range.getBegin(), diag::err_alias_declaration_specialization)
         << SpecKind << Range;
       SkipUntil(tok::semi);
-      return 0;
+      return nullptr;
     }
 
     // Name must be an identifier.
@@ -559,7 +587,7 @@
       Diag(Name.StartLocation, diag::err_alias_declaration_not_identifier);
       // No removal fixit: can't recover from this.
       SkipUntil(tok::semi);
-      return 0;
+      return nullptr;
     } else if (HasTypenameKeyword)
       Diag(TypenameLoc, diag::err_alias_declaration_not_identifier)
         << FixItHint::CreateRemoval(SourceRange(TypenameLoc,
@@ -568,7 +596,7 @@
       Diag(SS.getBeginLoc(), diag::err_alias_declaration_not_identifier)
         << FixItHint::CreateRemoval(SS.getRange());
 
-    TypeAlias = ParseTypeName(0, TemplateInfo.Kind ?
+    TypeAlias = ParseTypeName(nullptr, TemplateInfo.Kind ?
                               Declarator::AliasTemplateContext :
                               Declarator::AliasDeclContext, AS, OwnedType,
                               &Attrs);
@@ -584,10 +612,11 @@
 
   // Eat ';'.
   DeclEnd = Tok.getLocation();
-  ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
-                   !Attrs.empty() ? "attributes list" :
-                   IsAliasDecl ? "alias declaration" : "using declaration",
-                   tok::semi);
+  if (ExpectAndConsume(tok::semi, diag::err_expected_after,
+                       !Attrs.empty() ? "attributes list"
+                                      : IsAliasDecl ? "alias declaration"
+                                                    : "using declaration"))
+    SkipUntil(tok::semi);
 
   // Diagnose an attempt to declare a templated using-declaration.
   // In C++11, alias-declarations can be templates:
@@ -600,7 +629,7 @@
     // Unfortunately, we have to bail out instead of recovering by
     // ignoring the parameters, just in case the nested name specifier
     // depends on the parameters.
-    return 0;
+    return nullptr;
   }
 
   // "typename" keyword is allowed for identifiers only,
@@ -615,7 +644,7 @@
   if (IsAliasDecl) {
     TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams;
     MultiTemplateParamsArg TemplateParamsArg(
-      TemplateParams ? TemplateParams->data() : 0,
+      TemplateParams ? TemplateParams->data() : nullptr,
       TemplateParams ? TemplateParams->size() : 0);
     return Actions.ActOnAliasDeclaration(getCurScope(), AS, TemplateParamsArg,
                                          UsingLoc, Name, Attrs.getList(),
@@ -649,31 +678,43 @@
 
   BalancedDelimiterTracker T(*this, tok::l_paren);
   if (T.consumeOpen()) {
-    Diag(Tok, diag::err_expected_lparen);
+    Diag(Tok, diag::err_expected) << tok::l_paren;
     SkipMalformedDecl();
-    return 0;
+    return nullptr;
   }
 
   ExprResult AssertExpr(ParseConstantExpression());
   if (AssertExpr.isInvalid()) {
     SkipMalformedDecl();
-    return 0;
+    return nullptr;
   }
 
-  if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::semi))
-    return 0;
+  ExprResult AssertMessage;
+  if (Tok.is(tok::r_paren)) {
+    Diag(Tok, getLangOpts().CPlusPlus1z
+                  ? diag::warn_cxx1y_compat_static_assert_no_message
+                  : diag::ext_static_assert_no_message)
+      << (getLangOpts().CPlusPlus1z
+              ? FixItHint()
+              : FixItHint::CreateInsertion(Tok.getLocation(), ", \"\""));
+  } else {
+    if (ExpectAndConsume(tok::comma)) {
+      SkipUntil(tok::semi);
+      return nullptr;
+    }
 
-  if (!isTokenStringLiteral()) {
-    Diag(Tok, diag::err_expected_string_literal)
-      << /*Source='static_assert'*/1;
-    SkipMalformedDecl();
-    return 0;
-  }
+    if (!isTokenStringLiteral()) {
+      Diag(Tok, diag::err_expected_string_literal)
+        << /*Source='static_assert'*/1;
+      SkipMalformedDecl();
+      return nullptr;
+    }
 
-  ExprResult AssertMessage(ParseStringLiteralExpression());
-  if (AssertMessage.isInvalid()) {
-    SkipMalformedDecl();
-    return 0;
+    AssertMessage = ParseStringLiteralExpression();
+    if (AssertMessage.isInvalid()) {
+      SkipMalformedDecl();
+      return nullptr;
+    }
   }
 
   T.consumeClose();
@@ -682,8 +723,8 @@
   ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert);
 
   return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc,
-                                              AssertExpr.take(),
-                                              AssertMessage.take(),
+                                              AssertExpr.get(),
+                                              AssertMessage.get(),
                                               T.getCloseLocation());
 }
 
@@ -738,7 +779,7 @@
       // C++11 [dcl.type.simple]p4:
       //   The operand of the decltype specifier is an unevaluated operand.
       EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated,
-                                                   0, /*IsDecltype=*/true);
+                                                   nullptr,/*IsDecltype=*/true);
       Result = ParseExpression();
       if (Result.isInvalid()) {
         DS.SetTypeSpecError();
@@ -758,7 +799,7 @@
         return EndLoc;
       }
 
-      Result = Actions.ActOnDecltypeExpression(Result.take());
+      Result = Actions.ActOnDecltypeExpression(Result.get());
     }
 
     // Match the ')'
@@ -779,14 +820,15 @@
   }
   assert(!Result.isInvalid());
 
-  const char *PrevSpec = 0;
+  const char *PrevSpec = nullptr;
   unsigned DiagID;
+  const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
   // Check for duplicate type specifiers (e.g. "int decltype(a)").
   if (Result.get()
         ? DS.SetTypeSpecType(DeclSpec::TST_decltype, StartLoc, PrevSpec,
-                             DiagID, Result.release())
+                             DiagID, Result.get(), Policy)
         : DS.SetTypeSpecType(DeclSpec::TST_decltype_auto, StartLoc, PrevSpec,
-                             DiagID)) {
+                             DiagID, Policy)) {
     Diag(StartLoc, DiagID) << PrevSpec;
     DS.SetTypeSpecError();
   }
@@ -834,10 +876,11 @@
   if (T.getCloseLocation().isInvalid())
     return;
 
-  const char *PrevSpec = 0;
+  const char *PrevSpec = nullptr;
   unsigned DiagID;
   if (DS.SetTypeSpecType(DeclSpec::TST_underlyingType, StartLoc, PrevSpec,
-                         DiagID, Result.release()))
+                         DiagID, Result.get(),
+                         Actions.getASTContext().getPrintingPolicy()))
     Diag(StartLoc, DiagID) << PrevSpec;
   DS.setTypeofParensRange(T.getRange());
 }
@@ -963,7 +1006,7 @@
   }
 
   // We have an identifier; check whether it is actually a type.
-  IdentifierInfo *CorrectedII = 0;
+  IdentifierInfo *CorrectedII = nullptr;
   ParsedType Type = Actions.getTypeName(*Id, IdLoc, getCurScope(), &SS, true,
                                         false, ParsedType(),
                                         /*IsCtorOrDtorName=*/false,
@@ -983,9 +1026,10 @@
   DS.SetRangeEnd(EndLocation);
   DS.getTypeSpecScope() = SS;
 
-  const char *PrevSpec = 0;
+  const char *PrevSpec = nullptr;
   unsigned DiagID;
-  DS.SetTypeSpecType(TST_typename, IdLoc, PrevSpec, DiagID, Type);
+  DS.SetTypeSpecType(TST_typename, IdLoc, PrevSpec, DiagID, Type,
+                     Actions.getASTContext().getPrintingPolicy());
 
   Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
   return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
@@ -997,8 +1041,8 @@
          Tok.is(tok::kw___virtual_inheritance)) {
     IdentifierInfo *AttrName = Tok.getIdentifierInfo();
     SourceLocation AttrNameLoc = ConsumeToken();
-    attrs.addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, 0,
-                 AttributeList::AS_GNU);
+    attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
+                 AttributeList::AS_Keyword);
   }
 }
 
@@ -1021,6 +1065,7 @@
   case tok::l_paren:            // struct foo {...} (         x);
   case tok::comma:              // __builtin_offsetof(struct foo{...} ,
   case tok::kw_operator:        // struct foo       operator  ++() {...}
+  case tok::kw___declspec:      // struct foo {...} __declspec(...)
     return true;
   case tok::colon:
     return CouldBeBitfield;     // enum E { ... }   :         2;
@@ -1179,53 +1224,38 @@
   // C++11 attributes
   SourceLocation AttrFixitLoc = Tok.getLocation();
 
-  if (TagType == DeclSpec::TST_struct &&
-      !Tok.is(tok::identifier) &&
-      Tok.getIdentifierInfo() &&
-      (Tok.is(tok::kw___is_arithmetic) ||
-       Tok.is(tok::kw___is_convertible) ||
-       Tok.is(tok::kw___is_empty) ||
-       Tok.is(tok::kw___is_floating_point) ||
-       Tok.is(tok::kw___is_function) ||
-       Tok.is(tok::kw___is_fundamental) ||
-       Tok.is(tok::kw___is_integral) ||
-       Tok.is(tok::kw___is_member_function_pointer) ||
-       Tok.is(tok::kw___is_member_pointer) ||
-       Tok.is(tok::kw___is_pod) ||
-       Tok.is(tok::kw___is_pointer) ||
-       Tok.is(tok::kw___is_same) ||
-       Tok.is(tok::kw___is_scalar) ||
-       Tok.is(tok::kw___is_signed) ||
-       Tok.is(tok::kw___is_unsigned) ||
-       Tok.is(tok::kw___is_void))) {
-    // GNU libstdc++ 4.2 and libc++ use certain intrinsic names as the
-    // name of struct templates, but some are keywords in GCC >= 4.3
-    // and Clang. Therefore, when we see the token sequence "struct
-    // X", make X into a normal identifier rather than a keyword, to
-    // allow libstdc++ 4.2 and libc++ to work properly.
-    Tok.getIdentifierInfo()->RevertTokenIDToIdentifier();
-    Tok.setKind(tok::identifier);
+  // GNU libstdc++ and libc++ use certain intrinsic names as the
+  // name of struct templates, but some are keywords in GCC >= 4.3
+  // MSVC and Clang. For compatibility, convert the token to an identifier
+  // and issue a warning diagnostic.
+  if (TagType == DeclSpec::TST_struct && !Tok.is(tok::identifier) &&
+      !Tok.isAnnotation()) {
+    const IdentifierInfo *II = Tok.getIdentifierInfo();
+    // We rarely end up here so the following check is efficient.
+    if (II && II->getName().startswith("__is_"))
+      TryKeywordIdentFallback(true);
   }
 
   // Parse the (optional) nested-name-specifier.
   CXXScopeSpec &SS = DS.getTypeSpecScope();
   if (getLangOpts().CPlusPlus) {
-    // "FOO : BAR" is not a potential typo for "FOO::BAR".
+    // "FOO : BAR" is not a potential typo for "FOO::BAR".  In this context it
+    // is a base-specifier-list.
     ColonProtectionRAIIObject X(*this);
 
     if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), EnteringContext))
       DS.SetTypeSpecError();
     if (SS.isSet())
       if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
-        Diag(Tok, diag::err_expected_ident);
+        Diag(Tok, diag::err_expected) << tok::identifier;
   }
 
   TemplateParameterLists *TemplateParams = TemplateInfo.TemplateParams;
 
   // Parse the (optional) class name or simple-template-id.
-  IdentifierInfo *Name = 0;
+  IdentifierInfo *Name = nullptr;
   SourceLocation NameLoc;
-  TemplateIdAnnotation *TemplateId = 0;
+  TemplateIdAnnotation *TemplateId = nullptr;
   if (Tok.is(tok::identifier)) {
     Name = Tok.getIdentifierInfo();
     NameLoc = ConsumeToken();
@@ -1245,13 +1275,8 @@
       }
 
       Diag(NameLoc, diag::err_explicit_spec_non_template)
-        << (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation)
-        << (TagType == DeclSpec::TST_class? 0
-            : TagType == DeclSpec::TST_struct? 1
-            : TagType == DeclSpec::TST_union? 2
-            : 3)
-        << Name
-        << SourceRange(LAngleLoc, RAngleLoc);
+          << (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation)
+          << TagTokKind << Name << SourceRange(LAngleLoc, RAngleLoc);
 
       // Strip off the last template parameter list if it was empty, since
       // we've removed its template argument list.
@@ -1259,14 +1284,14 @@
         if (TemplateParams && TemplateParams->size() > 1) {
           TemplateParams->pop_back();
         } else {
-          TemplateParams = 0;
+          TemplateParams = nullptr;
           const_cast<ParsedTemplateInfo&>(TemplateInfo).Kind
             = ParsedTemplateInfo::NonTemplate;
         }
       } else if (TemplateInfo.Kind
                                 == ParsedTemplateInfo::ExplicitInstantiation) {
         // Pretend this is just a forward declaration.
-        TemplateParams = 0;
+        TemplateParams = nullptr;
         const_cast<ParsedTemplateInfo&>(TemplateInfo).Kind
           = ParsedTemplateInfo::NonTemplate;
         const_cast<ParsedTemplateInfo&>(TemplateInfo).TemplateLoc
@@ -1288,6 +1313,7 @@
       if (SS.isNotEmpty())
         Range.setBegin(SS.getBeginLoc());
 
+      // FIXME: Name may be null here.
       Diag(TemplateId->LAngleLoc, diag::err_template_spec_syntax_non_template)
         << TemplateId->Name << static_cast<int>(TemplateId->Kind) << Range;
 
@@ -1320,11 +1346,12 @@
   //   new struct s;
   // or
   //   &T::operator struct s;
-  // For these, DSC is DSC_type_specifier.
+  // For these, DSC is DSC_type_specifier or DSC_alias_declaration.
 
   // If there are attributes after class name, parse them.
   MaybeParseCXX11Attributes(Attributes);
 
+  const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
   Sema::TagUseKind TUK;
   if (DSC == DSC_trailing)
     TUK = Sema::TUK_Reference;
@@ -1377,14 +1404,15 @@
       TUK = Sema::TUK_Reference;
 
     PA.Revert();
-  } else if (DSC != DSC_type_specifier &&
+  } else if (!isTypeSpecifier(DSC) &&
              (Tok.is(tok::semi) ||
               (Tok.isAtStartOfLine() && !isValidAfterTypeSpecifier(false)))) {
     TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration;
     if (Tok.isNot(tok::semi)) {
+      const PrintingPolicy &PPol = Actions.getASTContext().getPrintingPolicy();
       // A semicolon was missing after this declaration. Diagnose and recover.
-      ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl,
-        DeclSpec::getSpecifierName(TagType));
+      ExpectAndConsume(tok::semi, diag::err_expected_after,
+                       DeclSpec::getSpecifierName(TagType, PPol));
       PP.EnterToken(Tok);
       Tok.setKind(tok::semi);
     }
@@ -1426,10 +1454,16 @@
     if (DS.getTypeSpecType() != DeclSpec::TST_error) {
       // We have a declaration or reference to an anonymous class.
       Diag(StartLoc, diag::err_anon_type_definition)
-        << DeclSpec::getSpecifierName(TagType);
+        << DeclSpec::getSpecifierName(TagType, Policy);
     }
 
-    SkipUntil(tok::comma, StopAtSemi);
+    // If we are parsing a definition and stop at a base-clause, continue on
+    // until the semicolon.  Continuing from the comma will just trick us into
+    // thinking we are seeing a variable declaration.
+    if (TUK == Sema::TUK_Definition && Tok.is(tok::colon))
+      SkipUntil(tok::semi, StopBeforeMatch);
+    else
+      SkipUntil(tok::comma, StopAtSemi);
     return;
   }
 
@@ -1499,7 +1533,7 @@
 
         if (TUK == Sema::TUK_Friend) {
           Diag(DS.getFriendSpecLoc(), diag::err_friend_explicit_instantiation);
-          TemplateParams = 0;
+          TemplateParams = nullptr;
         } else {
           SourceLocation LAngleLoc =
               PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
@@ -1512,25 +1546,19 @@
           // "template<>", so that we treat this construct as a class
           // template specialization.
           FakedParamLists.push_back(Actions.ActOnTemplateParameterList(
-              0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, 0, 0,
-              LAngleLoc));
+              0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, nullptr,
+              0, LAngleLoc));
           TemplateParams = &FakedParamLists;
         }
       }
 
       // Build the class template specialization.
-      TagOrTempResult
-        = Actions.ActOnClassTemplateSpecialization(getCurScope(), TagType, TUK,
-                       StartLoc, DS.getModulePrivateSpecLoc(), SS,
-                       TemplateId->Template,
-                       TemplateId->TemplateNameLoc,
-                       TemplateId->LAngleLoc,
-                       TemplateArgsPtr,
-                       TemplateId->RAngleLoc,
-                       attrs.getList(),
-                       MultiTemplateParamsArg(
-                                    TemplateParams? &(*TemplateParams)[0] : 0,
-                                 TemplateParams? TemplateParams->size() : 0));
+      TagOrTempResult = Actions.ActOnClassTemplateSpecialization(
+          getCurScope(), TagType, TUK, StartLoc, DS.getModulePrivateSpecLoc(),
+          *TemplateId, attrs.getList(),
+          MultiTemplateParamsArg(TemplateParams ? &(*TemplateParams)[0]
+                                                : nullptr,
+                                 TemplateParams ? TemplateParams->size() : 0));
     }
   } else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation &&
              TUK == Sema::TUK_Declaration) {
@@ -1556,7 +1584,8 @@
                                       TagType, StartLoc, SS,
                                       Name, NameLoc, attrs.getList(),
                                       MultiTemplateParamsArg(
-                                    TemplateParams? &(*TemplateParams)[0] : 0,
+                                    TemplateParams? &(*TemplateParams)[0]
+                                                  : nullptr,
                                  TemplateParams? TemplateParams->size() : 0));
   } else {
     if (TUK != Sema::TUK_Declaration && TUK != Sema::TUK_Definition)
@@ -1568,7 +1597,7 @@
       // recover by ignoring the 'template' keyword.
       Diag(Tok, diag::err_template_defn_explicit_instantiation)
         << 1 << FixItHint::CreateRemoval(TemplateInfo.TemplateLoc);
-      TemplateParams = 0;
+      TemplateParams = nullptr;
     }
 
     bool IsDependent = false;
@@ -1587,7 +1616,8 @@
                                        DS.getModulePrivateSpecLoc(),
                                        TParams, Owned, IsDependent,
                                        SourceLocation(), false,
-                                       clang::TypeResult());
+                                       clang::TypeResult(),
+                                       DSC == DSC_type_specifier);
 
     // If ActOnTag said the type was dependent, try again with the
     // less common call.
@@ -1610,17 +1640,18 @@
       ParseStructUnionBody(StartLoc, TagType, TagOrTempResult.get());
   }
 
-  const char *PrevSpec = 0;
+  const char *PrevSpec = nullptr;
   unsigned DiagID;
   bool Result;
   if (!TypeResult.isInvalid()) {
     Result = DS.SetTypeSpecType(DeclSpec::TST_typename, StartLoc,
                                 NameLoc.isValid() ? NameLoc : StartLoc,
-                                PrevSpec, DiagID, TypeResult.get());
+                                PrevSpec, DiagID, TypeResult.get(), Policy);
   } else if (!TagOrTempResult.isInvalid()) {
     Result = DS.SetTypeSpecType(TagType, StartLoc,
                                 NameLoc.isValid() ? NameLoc : StartLoc,
-                                PrevSpec, DiagID, TagOrTempResult.get(), Owned);
+                                PrevSpec, DiagID, TagOrTempResult.get(), Owned,
+                                Policy);
   } else {
     DS.SetTypeSpecError();
     return;
@@ -1641,8 +1672,9 @@
   if (TUK == Sema::TUK_Definition &&
       (TemplateInfo.Kind || !isValidAfterTypeSpecifier(false))) {
     if (Tok.isNot(tok::semi)) {
-      ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl,
-        DeclSpec::getSpecifierName(TagType));
+      const PrintingPolicy &PPol = Actions.getASTContext().getPrintingPolicy();
+      ExpectAndConsume(tok::semi, diag::err_expected_after,
+                       DeclSpec::getSpecifierName(TagType, PPol));
       // Push this token back into the preprocessor and change our current token
       // to ';' so that the rest of the code recovers as though there were an
       // ';' after the definition.
@@ -1680,10 +1712,8 @@
 
     // If the next token is a comma, consume it and keep reading
     // base-specifiers.
-    if (Tok.isNot(tok::comma)) break;
-
-    // Consume the comma.
-    ConsumeToken();
+    if (!TryConsumeToken(tok::comma))
+      break;
   }
 
   // Attach the base specifiers
@@ -1709,10 +1739,8 @@
   MaybeParseCXX11Attributes(Attributes);
 
   // Parse the 'virtual' keyword.
-  if (Tok.is(tok::kw_virtual))  {
-    ConsumeToken();
+  if (TryConsumeToken(tok::kw_virtual))
     IsVirtual = true;
-  }
 
   CheckMisplacedCXX11Attribute(Attributes, StartLoc);
 
@@ -1749,9 +1777,8 @@
   // actually part of the base-specifier-list grammar productions, but we
   // parse it here for convenience.
   SourceLocation EllipsisLoc;
-  if (Tok.is(tok::ellipsis))
-    EllipsisLoc = ConsumeToken();
-  
+  TryConsumeToken(tok::ellipsis, EllipsisLoc);
+
   // Find the complete source range for the base-specifier.
   SourceRange Range(StartLoc, EndLocation);
 
@@ -1785,12 +1812,12 @@
                                             Decl *ThisDecl) {
   // We just declared a member function. If this member function
   // has any default arguments, we'll need to parse them later.
-  LateParsedMethodDeclaration *LateMethod = 0;
+  LateParsedMethodDeclaration *LateMethod = nullptr;
   DeclaratorChunk::FunctionTypeInfo &FTI
     = DeclaratorInfo.getFunctionTypeInfo();
 
-  for (unsigned ParamIdx = 0; ParamIdx < FTI.NumArgs; ++ParamIdx) {
-    if (LateMethod || FTI.ArgInfo[ParamIdx].DefaultArgTokens) {
+  for (unsigned ParamIdx = 0; ParamIdx < FTI.NumParams; ++ParamIdx) {
+    if (LateMethod || FTI.Params[ParamIdx].DefaultArgTokens) {
       if (!LateMethod) {
         // Push this method onto the stack of late-parsed method
         // declarations.
@@ -1800,17 +1827,16 @@
 
         // Add all of the parameters prior to this one (they don't
         // have default arguments).
-        LateMethod->DefaultArgs.reserve(FTI.NumArgs);
+        LateMethod->DefaultArgs.reserve(FTI.NumParams);
         for (unsigned I = 0; I < ParamIdx; ++I)
           LateMethod->DefaultArgs.push_back(
-                             LateParsedDefaultArgument(FTI.ArgInfo[I].Param));
+              LateParsedDefaultArgument(FTI.Params[I].Param));
       }
 
       // Add this parameter to the list of parameters (it may or may
       // not have a default argument).
-      LateMethod->DefaultArgs.push_back(
-        LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param,
-                                  FTI.ArgInfo[ParamIdx].DefaultArgTokens));
+      LateMethod->DefaultArgs.push_back(LateParsedDefaultArgument(
+          FTI.Params[ParamIdx].Param, FTI.Params[ParamIdx].DefaultArgTokens));
     }
   }
 }
@@ -1822,30 +1848,28 @@
 ///         override
 ///         final
 VirtSpecifiers::Specifier Parser::isCXX11VirtSpecifier(const Token &Tok) const {
-  if (!getLangOpts().CPlusPlus)
+  if (!getLangOpts().CPlusPlus || Tok.isNot(tok::identifier))
     return VirtSpecifiers::VS_None;
 
-  if (Tok.is(tok::identifier)) {
-    IdentifierInfo *II = Tok.getIdentifierInfo();
+  IdentifierInfo *II = Tok.getIdentifierInfo();
 
-    // Initialize the contextual keywords.
-    if (!Ident_final) {
-      Ident_final = &PP.getIdentifierTable().get("final");
-      if (getLangOpts().MicrosoftExt)
-        Ident_sealed = &PP.getIdentifierTable().get("sealed");
-      Ident_override = &PP.getIdentifierTable().get("override");
-    }
-
-    if (II == Ident_override)
-      return VirtSpecifiers::VS_Override;
-
-    if (II == Ident_sealed)
-      return VirtSpecifiers::VS_Sealed;
-
-    if (II == Ident_final)
-      return VirtSpecifiers::VS_Final;
+  // Initialize the contextual keywords.
+  if (!Ident_final) {
+    Ident_final = &PP.getIdentifierTable().get("final");
+    if (getLangOpts().MicrosoftExt)
+      Ident_sealed = &PP.getIdentifierTable().get("sealed");
+    Ident_override = &PP.getIdentifierTable().get("override");
   }
 
+  if (II == Ident_override)
+    return VirtSpecifiers::VS_Override;
+
+  if (II == Ident_sealed)
+    return VirtSpecifiers::VS_Sealed;
+
+  if (II == Ident_final)
+    return VirtSpecifiers::VS_Final;
+
   return VirtSpecifiers::VS_None;
 }
 
@@ -1863,7 +1887,7 @@
 
     // C++ [class.mem]p8:
     //   A virt-specifier-seq shall contain at most one of each virt-specifier.
-    const char *PrevSpec = 0;
+    const char *PrevSpec = nullptr;
     if (VS.SetSpecifier(Specifier, Tok.getLocation(), PrevSpec))
       Diag(Tok.getLocation(), diag::err_duplicate_virt_specifier)
         << PrevSpec
@@ -1887,24 +1911,52 @@
 }
 
 /// isCXX11FinalKeyword - Determine whether the next token is a C++11
-/// contextual 'final' keyword.
+/// 'final' or Microsoft 'sealed' contextual keyword.
 bool Parser::isCXX11FinalKeyword() const {
-  if (!getLangOpts().CPlusPlus)
-    return false;
+  VirtSpecifiers::Specifier Specifier = isCXX11VirtSpecifier();
+  return Specifier == VirtSpecifiers::VS_Final ||
+         Specifier == VirtSpecifiers::VS_Sealed;
+}
 
-  if (!Tok.is(tok::identifier))
-    return false;
+/// \brief Parse a C++ member-declarator up to, but not including, the optional
+/// brace-or-equal-initializer or pure-specifier.
+void Parser::ParseCXXMemberDeclaratorBeforeInitializer(
+    Declarator &DeclaratorInfo, VirtSpecifiers &VS, ExprResult &BitfieldSize,
+    LateParsedAttrList &LateParsedAttrs) {
+  // member-declarator:
+  //   declarator pure-specifier[opt]
+  //   declarator brace-or-equal-initializer[opt]
+  //   identifier[opt] ':' constant-expression
+  if (Tok.isNot(tok::colon))
+    ParseDeclarator(DeclaratorInfo);
 
-  // Initialize the contextual keywords.
-  if (!Ident_final) {
-    Ident_final = &PP.getIdentifierTable().get("final");
-    if (getLangOpts().MicrosoftExt)
-      Ident_sealed = &PP.getIdentifierTable().get("sealed");
-    Ident_override = &PP.getIdentifierTable().get("override");
+  if (!DeclaratorInfo.isFunctionDeclarator() && TryConsumeToken(tok::colon)) {
+    BitfieldSize = ParseConstantExpression();
+    if (BitfieldSize.isInvalid())
+      SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch);
+  } else
+    ParseOptionalCXX11VirtSpecifierSeq(VS, getCurrentClass().IsInterface);
+
+  // If a simple-asm-expr is present, parse it.
+  if (Tok.is(tok::kw_asm)) {
+    SourceLocation Loc;
+    ExprResult AsmLabel(ParseSimpleAsm(&Loc));
+    if (AsmLabel.isInvalid())
+      SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch);
+
+    DeclaratorInfo.setAsmLabel(AsmLabel.get());
+    DeclaratorInfo.SetRangeEnd(Loc);
   }
 
-  return Tok.getIdentifierInfo() == Ident_final ||
-         Tok.getIdentifierInfo() == Ident_sealed;
+  // If attributes exist after the declarator, but before an '{', parse them.
+  MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs);
+
+  // For compatibility with code written to older Clang, also accept a
+  // virt-specifier *after* the GNU attributes.
+  // FIXME: If we saw any attributes that are known to GCC followed by a
+  // virt-specifier, issue a GCC-compat warning.
+  if (BitfieldSize.isUnset() && VS.isUnset())
+    ParseOptionalCXX11VirtSpecifierSeq(VS, getCurrentClass().IsInterface);
 }
 
 /// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration.
@@ -1958,6 +2010,14 @@
     return;
   }
 
+  // Turn on colon protection early, while parsing declspec, although there is
+  // nothing to protect there. It prevents from false errors if error recovery
+  // incorrectly determines where the declspec ends, as in the example:
+  //   struct A { enum class B { C }; };
+  //   const int C = 4;
+  //   struct D { A::B : C; };
+  ColonProtectionRAIIObject X(*this);
+
   // Access declarations.
   bool MalformedTypeSpec = false;
   if (!TemplateInfo.Kind &&
@@ -1989,17 +2049,17 @@
       }
 
       // TODO: recover from mistakenly-qualified operator declarations.
-      if (ExpectAndConsume(tok::semi,
-                           diag::err_expected_semi_after,
-                           "access declaration",
-                           tok::semi))
+      if (ExpectAndConsume(tok::semi, diag::err_expected_after,
+                           "access declaration")) {
+        SkipUntil(tok::semi);
         return;
+      }
 
       Actions.ActOnUsingDeclaration(getCurScope(), AS,
                                     /* HasUsingKeyword */ false,
                                     SourceLocation(),
                                     SS, Name,
-                                    /* AttrList */ 0,
+                                    /* AttrList */ nullptr,
                                     /* HasTypenameKeyword */ false,
                                     SourceLocation());
       return;
@@ -2032,10 +2092,6 @@
                                           TemplateInfo, TemplateDiags);
   }
 
-  // Don't parse FOO:BAR as if it were a typo for FOO::BAR, in this context it
-  // is a bitfield.
-  ColonProtectionRAIIObject X(*this);
-
   ParsedAttributesWithRange attrs(AttrFactory);
   ParsedAttributesWithRange FnAttrs(AttrFactory);
   // Optional C++11 attribute-specifier
@@ -2074,16 +2130,27 @@
   DS.takeAttributesFrom(attrs);
   if (MalformedTypeSpec)
     DS.SetTypeSpecError();
+
   ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC_class,
                              &CommonLateParsedAttrs);
 
+  // Turn off colon protection that was set for declspec.
+  X.restore();
+
+  // If we had a free-standing type definition with a missing semicolon, we
+  // may get this far before the problem becomes obvious.
+  if (DS.hasTagDefinition() &&
+      TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate &&
+      DiagnoseMissingSemiAfterTagDefinition(DS, AS, DSC_class,
+                                            &CommonLateParsedAttrs))
+    return;
+
   MultiTemplateParamsArg TemplateParams(
-      TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->data() : 0,
+      TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->data()
+                                 : nullptr,
       TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->size() : 0);
 
-  if (Tok.is(tok::semi)) {
-    ConsumeToken();
-
+  if (TryConsumeToken(tok::semi)) {
     if (DS.isFriendSpecified())
       ProhibitAttributes(FnAttrs);
 
@@ -2102,30 +2169,30 @@
   SourceLocation EqualLoc;
   bool HasInitializer = false;
   ExprResult Init;
-  if (Tok.isNot(tok::colon)) {
-    // Don't parse FOO:BAR as if it were a typo for FOO::BAR.
-    ColonProtectionRAIIObject X(*this);
 
-    // Parse the first declarator.
-    ParseDeclarator(DeclaratorInfo);
-    // Error parsing the declarator?
-    if (!DeclaratorInfo.hasName()) {
-      // If so, skip until the semi-colon or a }.
-      SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
-      if (Tok.is(tok::semi))
-        ConsumeToken();
-      return;
-    }
+  SmallVector<Decl *, 8> DeclsInGroup;
+  ExprResult BitfieldSize;
+  bool ExpectSemi = true;
 
-    ParseOptionalCXX11VirtSpecifierSeq(VS, getCurrentClass().IsInterface);
+  // Parse the first declarator.
+  ParseCXXMemberDeclaratorBeforeInitializer(DeclaratorInfo, VS, BitfieldSize,
+                                            LateParsedAttrs);
 
-    // If attributes exist after the declarator, but before an '{', parse them.
-    MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs);
+  // If this has neither a name nor a bit width, something has gone seriously
+  // wrong. Skip until the semi-colon or }.
+  if (!DeclaratorInfo.hasName() && BitfieldSize.isUnset()) {
+    // If so, skip until the semi-colon or a }.
+    SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
+    TryConsumeToken(tok::semi);
+    return;
+  }
 
-    // MSVC permits pure specifier on inline functions declared at class scope.
+  // Check for a member function definition.
+  if (BitfieldSize.isUnset()) {
+    // MSVC permits pure specifier on inline functions defined at class scope.
     // Hence check for =0 before checking for function definition.
     if (getLangOpts().MicrosoftExt && Tok.is(tok::equal) &&
-        DeclaratorInfo.isFunctionDeclarator() && 
+        DeclaratorInfo.isFunctionDeclarator() &&
         NextToken().is(tok::numeric_constant)) {
       EqualLoc = ConsumeToken();
       Init = ParseInitializer();
@@ -2171,8 +2238,8 @@
         SkipUntil(tok::r_brace);
 
         // Consume the optional ';'
-        if (Tok.is(tok::semi))
-          ConsumeToken();
+        TryConsumeToken(tok::semi);
+
         return;
       }
 
@@ -2210,40 +2277,7 @@
   //   member-declarator
   //   member-declarator-list ',' member-declarator
 
-  SmallVector<Decl *, 8> DeclsInGroup;
-  ExprResult BitfieldSize;
-  bool ExpectSemi = true;
-
   while (1) {
-    // member-declarator:
-    //   declarator pure-specifier[opt]
-    //   declarator brace-or-equal-initializer[opt]
-    //   identifier[opt] ':' constant-expression
-    if (Tok.is(tok::colon)) {
-      ConsumeToken();
-      BitfieldSize = ParseConstantExpression();
-      if (BitfieldSize.isInvalid())
-        SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch);
-    }
-
-    // If a simple-asm-expr is present, parse it.
-    if (Tok.is(tok::kw_asm)) {
-      SourceLocation Loc;
-      ExprResult AsmLabel(ParseSimpleAsm(&Loc));
-      if (AsmLabel.isInvalid())
-        SkipUntil(tok::comma, StopAtSemi | StopBeforeMatch);
- 
-      DeclaratorInfo.setAsmLabel(AsmLabel.release());
-      DeclaratorInfo.SetRangeEnd(Loc);
-    }
-
-    // If attributes exist after the declarator, parse them.
-    MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs);
-
-    // FIXME: When g++ adds support for this, we'll need to check whether it
-    // goes before or after the GNU attributes and __asm__.
-    ParseOptionalCXX11VirtSpecifierSeq(VS, getCurrentClass().IsInterface);
-
     InClassInitStyle HasInClassInit = ICIS_NoInit;
     if ((Tok.is(tok::equal) || Tok.is(tok::l_brace)) && !HasInitializer) {
       if (BitfieldSize.get()) {
@@ -2262,35 +2296,31 @@
     // this call will *not* return the created decl; It will return null.
     // See Sema::ActOnCXXMemberDeclarator for details.
 
-    NamedDecl *ThisDecl = 0;
+    NamedDecl *ThisDecl = nullptr;
     if (DS.isFriendSpecified()) {
-      // C++11 [dcl.attr.grammar] p4: If an attribute-specifier-seq appertains 
+      // C++11 [dcl.attr.grammar] p4: If an attribute-specifier-seq appertains
       // to a friend declaration, that declaration shall be a definition.
       //
-      // Diagnose attributes appear after friend member function declarator:
-      // foo [[]] ();
+      // Diagnose attributes that appear in a friend member function declarator:
+      //   friend int foo [[]] ();
       SmallVector<SourceRange, 4> Ranges;
       DeclaratorInfo.getCXX11AttributeRanges(Ranges);
-      if (!Ranges.empty()) {
-        for (SmallVectorImpl<SourceRange>::iterator I = Ranges.begin(),
-             E = Ranges.end(); I != E; ++I) {
-          Diag((*I).getBegin(), diag::err_attributes_not_allowed) 
-            << *I;
-        }
-      }
+      for (SmallVectorImpl<SourceRange>::iterator I = Ranges.begin(),
+           E = Ranges.end(); I != E; ++I)
+        Diag((*I).getBegin(), diag::err_attributes_not_allowed) << *I;
 
-      // TODO: handle initializers, bitfields, 'delete'
+      // TODO: handle initializers, VS, bitfields, 'delete'
       ThisDecl = Actions.ActOnFriendFunctionDecl(getCurScope(), DeclaratorInfo,
                                                  TemplateParams);
     } else {
       ThisDecl = Actions.ActOnCXXMemberDeclarator(getCurScope(), AS,
                                                   DeclaratorInfo,
                                                   TemplateParams,
-                                                  BitfieldSize.release(),
+                                                  BitfieldSize.get(),
                                                   VS, HasInClassInit);
 
       if (VarTemplateDecl *VT =
-              ThisDecl ? dyn_cast<VarTemplateDecl>(ThisDecl) : 0)
+              ThisDecl ? dyn_cast<VarTemplateDecl>(ThisDecl) : nullptr)
         // Re-direct this decl to refer to the templated decl so that we can
         // initialize it.
         ThisDecl = VT->getTemplatedDecl();
@@ -2360,12 +2390,10 @@
 
     // If we don't have a comma, it is either the end of the list (a ';')
     // or an error, bail out.
-    if (Tok.isNot(tok::comma))
+    SourceLocation CommaLoc;
+    if (!TryConsumeToken(tok::comma, CommaLoc))
       break;
 
-    // Consume the comma.
-    SourceLocation CommaLoc = ConsumeToken();
-
     if (Tok.isAtStartOfLine() &&
         !MightBeDeclarator(Declarator::MemberContext)) {
       // This comma was followed by a line-break and something which can't be
@@ -2385,11 +2413,11 @@
     HasInitializer = false;
     DeclaratorInfo.setCommaLoc(CommaLoc);
 
-    // Attributes are only allowed on the second declarator.
+    // GNU attributes are allowed before the second and subsequent declarator.
     MaybeParseGNUAttributes(DeclaratorInfo);
 
-    if (Tok.isNot(tok::colon))
-      ParseDeclarator(DeclaratorInfo);
+    ParseCXXMemberDeclaratorBeforeInitializer(DeclaratorInfo, VS, BitfieldSize,
+                                              LateParsedAttrs);
   }
 
   if (ExpectSemi &&
@@ -2397,7 +2425,7 @@
     // Skip to end of block or statement.
     SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
     // If we stopped at a ';', eat it.
-    if (Tok.is(tok::semi)) ConsumeToken();
+    TryConsumeToken(tok::semi);
     return;
   }
 
@@ -2434,8 +2462,7 @@
   EnterExpressionEvaluationContext Context(Actions, 
                                            Sema::PotentiallyEvaluated,
                                            D);
-  if (Tok.is(tok::equal)) {
-    EqualLoc = ConsumeToken();
+  if (TryConsumeToken(tok::equal, EqualLoc)) {
     if (Tok.is(tok::kw_delete)) {
       // In principle, an initializer of '= delete p;' is legal, but it will
       // never type-check. It's better to diagnose it as an ill-formed expression
@@ -2444,13 +2471,13 @@
       // a top-level comma always ends the initializer expression.
       const Token &Next = NextToken();
       if (IsFunction || Next.is(tok::semi) || Next.is(tok::comma) ||
-           Next.is(tok::eof)) {
+          Next.is(tok::eof)) {
         if (IsFunction)
           Diag(ConsumeToken(), diag::err_default_delete_in_multiple_declaration)
             << 1 /* delete */;
         else
           Diag(ConsumeToken(), diag::err_deleted_non_function);
-        return ExprResult();
+        return ExprError();
       }
     } else if (Tok.is(tok::kw_default)) {
       if (IsFunction)
@@ -2458,7 +2485,7 @@
           << 0 /* default */;
       else
         Diag(ConsumeToken(), diag::err_default_special_members);
-      return ExprResult();
+      return ExprError();
     }
 
   }
@@ -2498,7 +2525,7 @@
             << /*ErrorType=*/6
             << (isa<NamedDecl>(TagDecl)
                   ? cast<NamedDecl>(TagDecl)->getQualifiedNameAsString()
-                  : "<anonymous>");
+                  : "(anonymous)");
         }
         break;
       }
@@ -2589,7 +2616,7 @@
 
   if (TagDecl) {
     // While we still have something to read, read the member-declarations.
-    while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
+    while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
       // Each iteration of this loop reads one member-declaration.
 
       if (getLangOpts().MicrosoftExt && (Tok.is(tok::kw___if_exists) ||
@@ -2624,6 +2651,16 @@
         continue;
       }
 
+      if (Tok.is(tok::annot_pragma_ms_pointers_to_members)) {
+        HandlePragmaMSPointersToMembers();
+        continue;
+      }
+
+      if (Tok.is(tok::annot_pragma_ms_pragma)) {
+        HandlePragmaMSPragma();
+        continue;
+      }
+
       // If we see a namespace here, a close brace was missing somewhere.
       if (Tok.is(tok::kw_namespace)) {
         DiagnoseUnexpectedNamespace(cast<NamedDecl>(TagDecl));
@@ -2641,18 +2678,14 @@
         MaybeParseGNUAttributes(AccessAttrs);
 
         SourceLocation EndLoc;
-        if (Tok.is(tok::colon)) {
-          EndLoc = Tok.getLocation();
-          ConsumeToken();
-        } else if (Tok.is(tok::semi)) {
-          EndLoc = Tok.getLocation();
-          ConsumeToken();
-          Diag(EndLoc, diag::err_expected_colon) 
-            << FixItHint::CreateReplacement(EndLoc, ":");
+        if (TryConsumeToken(tok::colon, EndLoc)) {
+        } else if (TryConsumeToken(tok::semi, EndLoc)) {
+          Diag(EndLoc, diag::err_expected)
+              << tok::colon << FixItHint::CreateReplacement(EndLoc, ":");
         } else {
           EndLoc = ASLoc.getLocWithOffset(TokLength);
-          Diag(EndLoc, diag::err_expected_colon) 
-            << FixItHint::CreateInsertion(EndLoc, ":");
+          Diag(EndLoc, diag::err_expected)
+              << tok::colon << FixItHint::CreateInsertion(EndLoc, ":");
         }
 
         // The Microsoft extension __interface does not permit non-public
@@ -2798,7 +2831,8 @@
         << FixItHint::CreateInsertion(Loc, ", ");
     } else {
       // Skip over garbage, until we get to '{'.  Don't eat the '{'.
-      Diag(Tok.getLocation(), diag::err_expected_lbrace_or_comma);
+      Diag(Tok.getLocation(), diag::err_expected_either) << tok::l_brace
+                                                         << tok::comma;
       SkipUntil(tok::l_brace, StopAtSemi | StopBeforeMatch);
       break;
     }
@@ -2842,7 +2876,7 @@
     return true;
   }
 
-  IdentifierInfo *II = 0;
+  IdentifierInfo *II = nullptr;
   DeclSpec DS(AttrFactory);
   SourceLocation IdLoc = Tok.getLocation();
   if (Tok.is(tok::annot_decltype)) {
@@ -2866,12 +2900,11 @@
       return true;
 
     SourceLocation EllipsisLoc;
-    if (Tok.is(tok::ellipsis))
-      EllipsisLoc = ConsumeToken();
+    TryConsumeToken(tok::ellipsis, EllipsisLoc);
 
     return Actions.ActOnMemInitializer(ConstructorDecl, getCurScope(), SS, II,
                                        TemplateTypeTy, DS, IdLoc, 
-                                       InitList.take(), EllipsisLoc);
+                                       InitList.get(), EllipsisLoc);
   } else if(Tok.is(tok::l_paren)) {
     BalancedDelimiterTracker T(*this, tok::l_paren);
     T.consumeOpen();
@@ -2887,8 +2920,7 @@
     T.consumeClose();
 
     SourceLocation EllipsisLoc;
-    if (Tok.is(tok::ellipsis))
-      EllipsisLoc = ConsumeToken();
+    TryConsumeToken(tok::ellipsis, EllipsisLoc);
 
     return Actions.ActOnMemInitializer(ConstructorDecl, getCurScope(), SS, II,
                                        TemplateTypeTy, DS, IdLoc,
@@ -2896,9 +2928,10 @@
                                        T.getCloseLocation(), EllipsisLoc);
   }
 
-  Diag(Tok, getLangOpts().CPlusPlus11 ? diag::err_expected_lparen_or_lbrace
-                                  : diag::err_expected_lparen);
-  return true;
+  if (getLangOpts().CPlusPlus11)
+    return Diag(Tok, diag::err_expected_either) << tok::l_paren << tok::l_brace;
+  else
+    return Diag(Tok, diag::err_expected) << tok::l_paren;
 }
 
 /// \brief Parse a C++ exception-specification if present (C++0x [except.spec]).
@@ -3042,10 +3075,8 @@
       Exceptions.push_back(Res.get());
       Ranges.push_back(Range);
     }
-    
-    if (Tok.is(tok::comma))
-      ConsumeToken();
-    else
+
+    if (!TryConsumeToken(tok::comma))
       break;
   }
 
@@ -3141,7 +3172,7 @@
       Loc = ConsumeToken();
       return II;
     }
-    return 0;
+    return nullptr;
 
   case tok::ampamp:       // 'and'
   case tok::pipe:         // 'bitor'
@@ -3162,7 +3193,7 @@
       Loc = ConsumeToken();
       return &PP.getIdentifierTable().get(Spelling);
     }
-    return 0;
+    return nullptr;
   }
 }
 
@@ -3171,6 +3202,7 @@
   switch (AttributeList::getKind(AttrName, ScopeName,
                                  AttributeList::AS_CXX11)) {
   case AttributeList::AT_CarriesDependency:
+  case AttributeList::AT_Deprecated:
   case AttributeList::AT_FallThrough:
   case AttributeList::AT_CXX11NoReturn: {
     return true;
@@ -3181,8 +3213,75 @@
   }
 }
 
-/// ParseCXX11AttributeSpecifier - Parse a C++11 attribute-specifier. Currently
-/// only parses standard attributes.
+/// ParseCXX11AttributeArgs -- Parse a C++11 attribute-argument-clause.
+///
+/// [C++11] attribute-argument-clause:
+///         '(' balanced-token-seq ')'
+///
+/// [C++11] balanced-token-seq:
+///         balanced-token
+///         balanced-token-seq balanced-token
+///
+/// [C++11] balanced-token:
+///         '(' balanced-token-seq ')'
+///         '[' balanced-token-seq ']'
+///         '{' balanced-token-seq '}'
+///         any token but '(', ')', '[', ']', '{', or '}'
+bool Parser::ParseCXX11AttributeArgs(IdentifierInfo *AttrName,
+                                     SourceLocation AttrNameLoc,
+                                     ParsedAttributes &Attrs,
+                                     SourceLocation *EndLoc,
+                                     IdentifierInfo *ScopeName,
+                                     SourceLocation ScopeLoc) {
+  assert(Tok.is(tok::l_paren) && "Not a C++11 attribute argument list");
+  SourceLocation LParenLoc = Tok.getLocation();
+
+  // If the attribute isn't known, we will not attempt to parse any
+  // arguments.
+  if (!hasAttribute(AttrSyntax::CXX, ScopeName, AttrName,
+                    getTargetInfo().getTriple(), getLangOpts())) {
+    // Eat the left paren, then skip to the ending right paren.
+    ConsumeParen();
+    SkipUntil(tok::r_paren);
+    return false;
+  }
+
+  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 =
+        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.
+        // FIXME: This is a good place for a fixit which removes the parens.
+        Diag(LParenLoc, diag::err_attribute_requires_arguments) << AttrName;
+        return false;
+      } else if (!Attr->getMaxArgs()) {
+        // The attribute parsed successfully, but was not allowed to have any
+        // arguments. It doesn't matter whether any were provided -- the
+        // presence of the argument list (even if empty) is diagnosed.
+        Diag(LParenLoc, diag::err_cxx11_attribute_forbids_arguments)
+            << AttrName;
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
+/// ParseCXX11AttributeSpecifier - Parse a C++11 attribute-specifier.
 ///
 /// [C++11] attribute-specifier:
 ///         '[' '[' attribute-list ']' ']'
@@ -3206,19 +3305,6 @@
 ///
 /// [C++11] attribute-namespace:
 ///         identifier
-///
-/// [C++11] attribute-argument-clause:
-///         '(' balanced-token-seq ')'
-///
-/// [C++11] balanced-token-seq:
-///         balanced-token
-///         balanced-token-seq balanced-token
-///
-/// [C++11] balanced-token:
-///         '(' balanced-token-seq ')'
-///         '[' balanced-token-seq ']'
-///         '{' balanced-token-seq '}'
-///         any token but '(', ')', '[', ']', '{', or '}'
 void Parser::ParseCXX11AttributeSpecifier(ParsedAttributes &attrs,
                                           SourceLocation *endLoc) {
   if (Tok.is(tok::kw_alignas)) {
@@ -3239,13 +3325,11 @@
 
   while (Tok.isNot(tok::r_square)) {
     // attribute not present
-    if (Tok.is(tok::comma)) {
-      ConsumeToken();
+    if (TryConsumeToken(tok::comma))
       continue;
-    }
 
     SourceLocation ScopeLoc, AttrLoc;
-    IdentifierInfo *ScopeName = 0, *AttrName = 0;
+    IdentifierInfo *ScopeName = nullptr, *AttrName = nullptr;
 
     AttrName = TryParseCXX11AttributeIdentifier(AttrLoc);
     if (!AttrName)
@@ -3253,64 +3337,47 @@
       break;
 
     // scoped attribute
-    if (Tok.is(tok::coloncolon)) {
-      ConsumeToken();
-
+    if (TryConsumeToken(tok::coloncolon)) {
       ScopeName = AttrName;
       ScopeLoc = AttrLoc;
 
       AttrName = TryParseCXX11AttributeIdentifier(AttrLoc);
       if (!AttrName) {
-        Diag(Tok.getLocation(), diag::err_expected_ident);
+        Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
         SkipUntil(tok::r_square, tok::comma, StopAtSemi | StopBeforeMatch);
         continue;
       }
     }
 
-    bool StandardAttr = IsBuiltInOrStandardCXX11Attribute(AttrName,ScopeName);
+    bool StandardAttr = IsBuiltInOrStandardCXX11Attribute(AttrName, ScopeName);
     bool AttrParsed = false;
 
     if (StandardAttr &&
         !SeenAttrs.insert(std::make_pair(AttrName, AttrLoc)).second)
       Diag(AttrLoc, diag::err_cxx11_attribute_repeated)
-        << AttrName << SourceRange(SeenAttrs[AttrName]);
+          << AttrName << SourceRange(SeenAttrs[AttrName]);
 
     // Parse attribute arguments
-    if (Tok.is(tok::l_paren)) {
-      if (ScopeName && ScopeName->getName() == "gnu") {
-        ParseGNUAttributeArgs(AttrName, AttrLoc, attrs, endLoc,
-                              ScopeName, ScopeLoc, AttributeList::AS_CXX11);
-        AttrParsed = true;
-      } else {
-        if (StandardAttr)
-          Diag(Tok.getLocation(), diag::err_cxx11_attribute_forbids_arguments)
-            << AttrName->getName();
-
-        // FIXME: handle other formats of c++11 attribute arguments
-        ConsumeParen();
-        SkipUntil(tok::r_paren);
-      }
-    }
+    if (Tok.is(tok::l_paren))
+      AttrParsed = ParseCXX11AttributeArgs(AttrName, AttrLoc, attrs, endLoc,
+                                           ScopeName, ScopeLoc);
 
     if (!AttrParsed)
       attrs.addNew(AttrName,
                    SourceRange(ScopeLoc.isValid() ? ScopeLoc : AttrLoc,
                                AttrLoc),
-                   ScopeName, ScopeLoc, 0, 0, AttributeList::AS_CXX11);
+                   ScopeName, ScopeLoc, nullptr, 0, AttributeList::AS_CXX11);
 
-    if (Tok.is(tok::ellipsis)) {
-      ConsumeToken();
-
+    if (TryConsumeToken(tok::ellipsis))
       Diag(Tok, diag::err_cxx11_attribute_forbids_ellipsis)
         << AttrName->getName();
-    }
   }
 
-  if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare))
+  if (ExpectAndConsume(tok::r_square))
     SkipUntil(tok::r_square);
   if (endLoc)
     *endLoc = Tok.getLocation();
-  if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare))
+  if (ExpectAndConsume(tok::r_square))
     SkipUntil(tok::r_square);
 }
 
@@ -3334,13 +3401,23 @@
 }
 
 void Parser::DiagnoseAndSkipCXX11Attributes() {
-  if (!isCXX11AttributeSpecifier())
-    return;
-
   // Start and end location of an attribute or an attribute list.
   SourceLocation StartLoc = Tok.getLocation();
+  SourceLocation EndLoc = SkipCXX11Attributes();
+
+  if (EndLoc.isValid()) {
+    SourceRange Range(StartLoc, EndLoc);
+    Diag(StartLoc, diag::err_attributes_not_allowed)
+      << Range;
+  }
+}
+
+SourceLocation Parser::SkipCXX11Attributes() {
   SourceLocation EndLoc;
 
+  if (!isCXX11AttributeSpecifier())
+    return EndLoc;
+
   do {
     if (Tok.is(tok::l_square)) {
       BalancedDelimiterTracker T(*this, tok::l_square);
@@ -3357,11 +3434,7 @@
     }
   } while (isCXX11AttributeSpecifier());
 
-  if (EndLoc.isValid()) {
-    SourceRange Range(StartLoc, EndLoc);
-    Diag(StartLoc, diag::err_attributes_not_allowed)
-      << Range;
-  }
+  return EndLoc;
 }
 
 /// ParseMicrosoftAttributes - Parse a Microsoft attribute [Attr]
@@ -3381,7 +3454,7 @@
     ConsumeBracket();
     SkipUntil(tok::r_square, StopAtSemi | StopBeforeMatch);
     if (endLoc) *endLoc = Tok.getLocation();
-    ExpectAndConsume(tok::r_square, diag::err_expected_rsquare);
+    ExpectAndConsume(tok::r_square);
   }
 }
 
@@ -3393,7 +3466,7 @@
   
   BalancedDelimiterTracker Braces(*this, tok::l_brace);
   if (Braces.consumeOpen()) {
-    Diag(Tok, diag::err_expected_lbrace);
+    Diag(Tok, diag::err_expected) << tok::l_brace;
     return;
   }
 
@@ -3412,7 +3485,7 @@
     return;
   }
 
-  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
+  while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
     // __if_exists, __if_not_exists can nest.
     if ((Tok.is(tok::kw___if_exists) || Tok.is(tok::kw___if_not_exists))) {
       ParseMicrosoftIfExistsClassDeclaration((DeclSpec::TST)TagType, CurAS);
@@ -3434,13 +3507,13 @@
       if (Tok.is(tok::colon))
         Actions.ActOnAccessSpecifier(AS, ASLoc, Tok.getLocation());
       else
-        Diag(Tok, diag::err_expected_colon);
+        Diag(Tok, diag::err_expected) << tok::colon;
       ConsumeToken();
       continue;
     }
 
     // Parse all the comma separated declarators.
-    ParseCXXClassMemberDeclaration(CurAS, 0);
+    ParseCXXClassMemberDeclaration(CurAS, nullptr);
   }
   
   Braces.consumeClose();
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 45f1b1d..0e4dfb9 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -23,6 +23,7 @@
 
 #include "clang/Parse/Parser.h"
 #include "RAIIObjectsForParser.h"
+#include "clang/AST/ASTContext.h"
 #include "clang/Basic/PrettyStackTrace.h"
 #include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/ParsedTemplate.h"
@@ -147,7 +148,7 @@
 
   if (!LHS.isInvalid())
     LHS = Actions.ActOnUnaryOp(getCurScope(), ExtLoc, tok::kw___extension__,
-                               LHS.take());
+                               LHS.get());
 
   return ParseRHSOfBinaryExpression(LHS, prec::Comma);
 }
@@ -260,19 +261,16 @@
         TernaryMiddle = ParseExpression();
         if (TernaryMiddle.isInvalid()) {
           LHS = ExprError();
-          TernaryMiddle = 0;
+          TernaryMiddle = nullptr;
         }
       } else {
         // Special case handling of "X ? Y : Z" where Y is empty:
         //   logical-OR-expression '?' ':' conditional-expression   [GNU]
-        TernaryMiddle = 0;
+        TernaryMiddle = nullptr;
         Diag(Tok, diag::ext_gnu_conditional_expr);
       }
 
-      if (Tok.is(tok::colon)) {
-        // Eat the colon.
-        ColonLoc = ConsumeToken();
-      } else {
+      if (!TryConsumeToken(tok::colon, ColonLoc)) {
         // Otherwise, we're missing a ':'.  Assume that this was a typo that
         // the user forgot. If we're not in a macro expansion, we can suggest
         // a fixit hint. If there were two spaces before the current token,
@@ -294,10 +292,10 @@
             }
           }
         }
-        
-        Diag(Tok, diag::err_expected_colon)
-          << FixItHint::CreateInsertion(FILoc, FIText);
-        Diag(OpToken, diag::note_matching) << "?";
+
+        Diag(Tok, diag::err_expected)
+            << tok::colon << FixItHint::CreateInsertion(FILoc, FIText);
+        Diag(OpToken, diag::note_matching) << tok::question;
         ColonLoc = Tok.getLocation();
       }
     }
@@ -394,11 +392,11 @@
                                      Actions.getExprRange(RHS.get()).getEnd()));
 
         LHS = Actions.ActOnBinOp(getCurScope(), OpToken.getLocation(),
-                                 OpToken.getKind(), LHS.take(), RHS.take());
+                                 OpToken.getKind(), LHS.get(), RHS.get());
       } else
         LHS = Actions.ActOnConditionalOp(OpToken.getLocation(), ColonLoc,
-                                         LHS.take(), TernaryMiddle.take(),
-                                         RHS.take());
+                                         LHS.get(), TernaryMiddle.get(),
+                                         RHS.get());
     }
   }
 }
@@ -430,14 +428,15 @@
     WantTypeSpecifiers = AllowTypes;
   }
 
-  virtual bool ValidateCandidate(const TypoCorrection &candidate) {
+  bool ValidateCandidate(const TypoCorrection &candidate) override {
     NamedDecl *ND = candidate.getCorrectionDecl();
     if (!ND)
       return candidate.isKeyword();
 
     if (isa<TypeDecl>(ND))
       return WantTypeSpecifiers;
-    return AllowNonTypes;
+    return AllowNonTypes &&
+           CorrectionCandidateCallback::ValidateCandidate(candidate);
   }
 
  private:
@@ -639,18 +638,12 @@
     // If this expression is limited to being a unary-expression, the parent can
     // not start a cast expression.
     ParenParseOption ParenExprType =
-      (isUnaryExpression && !getLangOpts().CPlusPlus)? CompoundLiteral : CastExpr;
+        (isUnaryExpression && !getLangOpts().CPlusPlus) ? CompoundLiteral
+                                                        : CastExpr;
     ParsedType CastTy;
     SourceLocation RParenLoc;
-    
-    {
-      // The inside of the parens don't need to be a colon protected scope, and
-      // isn't immediately a message send.
-      ColonProtectionRAIIObject X(*this, false);
-
-      Res = ParseParenExpression(ParenExprType, false/*stopIfCastExr*/,
-                                 isTypeCast == IsTypeCast, CastTy, RParenLoc);
-    }
+    Res = ParseParenExpression(ParenExprType, false/*stopIfCastExr*/,
+                               isTypeCast == IsTypeCast, CastTy, RParenLoc);
 
     switch (ParenExprType) {
     case SimpleExpr:   break;    // Nothing else to do.
@@ -690,7 +683,7 @@
     return Actions.ActOnCXXNullPtrLiteral(ConsumeToken());
 
   case tok::annot_primary_expr:
-    assert(Res.get() == 0 && "Stray primary-expression annotation?");
+    assert(Res.get() == nullptr && "Stray primary-expression annotation?");
     Res = getExprAnnotation(Tok);
     ConsumeToken();
     break;
@@ -715,48 +708,11 @@
       // If this identifier was reverted from a token ID, and the next token
       // is a parenthesis, this is likely to be a use of a type trait. Check
       // those tokens.
-      if (Next.is(tok::l_paren) &&
-          Tok.is(tok::identifier) &&
-          Tok.getIdentifierInfo()->hasRevertedTokenIDToIdentifier()) {
-        IdentifierInfo *II = Tok.getIdentifierInfo();
-        // Build up the mapping of revertable type traits, for future use.
-        if (RevertableTypeTraits.empty()) {
-#define RTT_JOIN(X,Y) X##Y
-#define REVERTABLE_TYPE_TRAIT(Name)                         \
-          RevertableTypeTraits[PP.getIdentifierInfo(#Name)] \
-            = RTT_JOIN(tok::kw_,Name)
-
-          REVERTABLE_TYPE_TRAIT(__is_arithmetic);
-          REVERTABLE_TYPE_TRAIT(__is_convertible);
-          REVERTABLE_TYPE_TRAIT(__is_empty);
-          REVERTABLE_TYPE_TRAIT(__is_floating_point);
-          REVERTABLE_TYPE_TRAIT(__is_function);
-          REVERTABLE_TYPE_TRAIT(__is_fundamental);
-          REVERTABLE_TYPE_TRAIT(__is_integral);
-          REVERTABLE_TYPE_TRAIT(__is_member_function_pointer);
-          REVERTABLE_TYPE_TRAIT(__is_member_pointer);
-          REVERTABLE_TYPE_TRAIT(__is_pod);
-          REVERTABLE_TYPE_TRAIT(__is_pointer);
-          REVERTABLE_TYPE_TRAIT(__is_same);
-          REVERTABLE_TYPE_TRAIT(__is_scalar);
-          REVERTABLE_TYPE_TRAIT(__is_signed);
-          REVERTABLE_TYPE_TRAIT(__is_unsigned);
-          REVERTABLE_TYPE_TRAIT(__is_void);
-#undef REVERTABLE_TYPE_TRAIT
-#undef RTT_JOIN
-        }
-
-        // If we find that this is in fact the name of a type trait,
-        // update the token kind in place and parse again to treat it as
-        // the appropriate kind of type trait.
-        llvm::SmallDenseMap<IdentifierInfo *, tok::TokenKind>::iterator Known
-          = RevertableTypeTraits.find(II);
-        if (Known != RevertableTypeTraits.end()) {
-          Tok.setKind(Known->second);
-          return ParseCastExpression(isUnaryExpression, isAddressOfOperand,
-                                     NotCastExpr, isTypeCast);
-        }
-      }
+      if (Next.is(tok::l_paren) && Tok.is(tok::identifier) &&
+          Tok.getIdentifierInfo()->hasRevertedTokenIDToIdentifier() &&
+          TryIdentKeywordUpgrade())
+        return ParseCastExpression(isUnaryExpression, isAddressOfOperand,
+                                   NotCastExpr, isTypeCast);
 
       if (Next.is(tok::coloncolon) ||
           (!ColonIsSacred && Next.is(tok::colon)) ||
@@ -806,8 +762,8 @@
         ((Tok.is(tok::identifier) &&
          (NextToken().is(tok::colon) || NextToken().is(tok::r_square))) ||
          Tok.is(tok::code_completion))) {
-      Res = ParseObjCMessageExpressionBody(SourceLocation(), ILoc, ParsedType(), 
-                                           0);
+      Res = ParseObjCMessageExpressionBody(SourceLocation(), ILoc, ParsedType(),
+                                           nullptr);
       break;
     }
     
@@ -828,19 +784,20 @@
             DeclSpec DS(AttrFactory);
             DS.SetRangeStart(ILoc);
             DS.SetRangeEnd(ILoc);
-            const char *PrevSpec = 0;
+            const char *PrevSpec = nullptr;
             unsigned DiagID;
-            DS.SetTypeSpecType(TST_typename, ILoc, PrevSpec, DiagID, Typ);
+            DS.SetTypeSpecType(TST_typename, ILoc, PrevSpec, DiagID, Typ,
+                               Actions.getASTContext().getPrintingPolicy());
             
             Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
             TypeResult Ty = Actions.ActOnTypeName(getCurScope(), 
                                                   DeclaratorInfo);
             if (Ty.isInvalid())
               break;
-            
+
             Res = ParseObjCMessageExpressionBody(SourceLocation(), 
                                                  SourceLocation(), 
-                                                 Ty.get(), 0);
+                                                 Ty.get(), nullptr);
             break;
           }
     }
@@ -857,6 +814,7 @@
     SourceLocation TemplateKWLoc;
     CastExpressionIdValidator Validator(isTypeCast != NotTypeCast,
                                         isTypeCast != IsTypeCast);
+    Validator.IsAddressOfOperand = isAddressOfOperand;
     Name.setIdentifier(&II, ILoc);
     Res = Actions.ActOnIdExpression(getCurScope(), ScopeSpec, TemplateKWLoc,
                                     Name, Tok.is(tok::l_paren),
@@ -873,6 +831,7 @@
   case tok::kw___func__:       // primary-expression: __func__ [C99 6.4.2.2]
   case tok::kw___FUNCTION__:   // primary-expression: __FUNCTION__ [GNU]
   case tok::kw___FUNCDNAME__:   // primary-expression: __FUNCDNAME__ [MS]
+  case tok::kw___FUNCSIG__:     // primary-expression: __FUNCSIG__ [MS]
   case tok::kw_L__FUNCTION__:   // primary-expression: L__FUNCTION__ [MS]
   case tok::kw___PRETTY_FUNCTION__:  // primary-expression: __P..Y_F..N__ [GNU]
     Res = Actions.ActOnPredefinedExpr(Tok.getLocation(), SavedKind);
@@ -904,7 +863,12 @@
     //     ++ cast-expression
     //     -- cast-expression
     SourceLocation SavedLoc = ConsumeToken();
-    Res = ParseCastExpression(!getLangOpts().CPlusPlus);
+    // One special case is implicitly handled here: if the preceding tokens are
+    // an ambiguous cast expression, such as "(T())++", then we recurse to
+    // determine whether the '++' is prefix or postfix.
+    Res = ParseCastExpression(!getLangOpts().CPlusPlus,
+                              /*isAddressOfOperand*/false, NotCastExpr,
+                              NotTypeCast);
     if (!Res.isInvalid())
       Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get());
     return Res;
@@ -955,9 +919,9 @@
   case tok::ampamp: {      // unary-expression: '&&' identifier
     SourceLocation AmpAmpLoc = ConsumeToken();
     if (Tok.isNot(tok::identifier))
-      return ExprError(Diag(Tok, diag::err_expected_ident));
+      return ExprError(Diag(Tok, diag::err_expected) << tok::identifier);
 
-    if (getCurScope()->getFnParent() == 0)
+    if (getCurScope()->getFnParent() == nullptr)
       return ExprError(Diag(Tok, diag::err_address_of_label_outside_fn));
     
     Diag(AmpAmpLoc, diag::ext_gnu_address_of_label);
@@ -992,10 +956,11 @@
       DS.SetRangeStart(Tok.getLocation());
       DS.SetRangeEnd(Tok.getLastLoc());
 
-      const char *PrevSpec = 0;
+      const char *PrevSpec = nullptr;
       unsigned DiagID;
       DS.SetTypeSpecType(TST_typename, Tok.getAnnotationEndLoc(),
-                         PrevSpec, DiagID, Type);
+                         PrevSpec, DiagID, Type,
+                         Actions.getASTContext().getPrintingPolicy());
 
       Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
       TypeResult Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
@@ -1004,7 +969,7 @@
 
       ConsumeToken();
       Res = ParseObjCMessageExpressionBody(SourceLocation(), SourceLocation(),
-                                           Ty.get(), 0);
+                                           Ty.get(), nullptr);
       break;
     }
     // Fall through
@@ -1028,15 +993,7 @@
   case tok::kw_void:
   case tok::kw_typename:
   case tok::kw_typeof:
-  case tok::kw___vector:
-  case tok::kw_image1d_t:
-  case tok::kw_image1d_array_t:
-  case tok::kw_image1d_buffer_t:
-  case tok::kw_image2d_t:
-  case tok::kw_image2d_array_t:
-  case tok::kw_image3d_t:
-  case tok::kw_sampler_t:
-  case tok::kw_event_t: {
+  case tok::kw___vector: {
     if (!getLangOpts().CPlusPlus) {
       Diag(Tok, diag::err_expected_expression);
       return ExprError();
@@ -1164,69 +1121,13 @@
 
     if (!Result.isInvalid())
       Result = Actions.ActOnNoexceptExpr(KeyLoc, T.getOpenLocation(), 
-                                         Result.take(), T.getCloseLocation());
+                                         Result.get(), T.getCloseLocation());
     return Result;
   }
 
-  case tok::kw___is_abstract: // [GNU] unary-type-trait
-  case tok::kw___is_class:
-  case tok::kw___is_empty:
-  case tok::kw___is_enum:
-  case tok::kw___is_interface_class:
-  case tok::kw___is_literal:
-  case tok::kw___is_arithmetic:
-  case tok::kw___is_integral:
-  case tok::kw___is_floating_point:
-  case tok::kw___is_complete_type:
-  case tok::kw___is_void:
-  case tok::kw___is_array:
-  case tok::kw___is_function:
-  case tok::kw___is_reference:
-  case tok::kw___is_lvalue_reference:
-  case tok::kw___is_rvalue_reference:
-  case tok::kw___is_fundamental:
-  case tok::kw___is_object:
-  case tok::kw___is_scalar:
-  case tok::kw___is_compound:
-  case tok::kw___is_pointer:
-  case tok::kw___is_member_object_pointer:
-  case tok::kw___is_member_function_pointer:
-  case tok::kw___is_member_pointer:
-  case tok::kw___is_const:
-  case tok::kw___is_volatile:
-  case tok::kw___is_standard_layout:
-  case tok::kw___is_signed:
-  case tok::kw___is_unsigned:
-  case tok::kw___is_literal_type:
-  case tok::kw___is_pod:
-  case tok::kw___is_polymorphic:
-  case tok::kw___is_trivial:
-  case tok::kw___is_trivially_copyable:
-  case tok::kw___is_union:
-  case tok::kw___is_final:
-  case tok::kw___is_sealed:
-  case tok::kw___has_trivial_constructor:
-  case tok::kw___has_trivial_move_constructor:
-  case tok::kw___has_trivial_copy:
-  case tok::kw___has_trivial_assign:
-  case tok::kw___has_trivial_move_assign:
-  case tok::kw___has_trivial_destructor:
-  case tok::kw___has_nothrow_assign:
-  case tok::kw___has_nothrow_move_assign:
-  case tok::kw___has_nothrow_copy:
-  case tok::kw___has_nothrow_constructor:
-  case tok::kw___has_virtual_destructor:
-    return ParseUnaryTypeTrait();
-
-  case tok::kw___builtin_types_compatible_p:
-  case tok::kw___is_base_of:
-  case tok::kw___is_same:
-  case tok::kw___is_convertible:
-  case tok::kw___is_convertible_to:
-  case tok::kw___is_trivially_assignable:
-    return ParseBinaryTypeTrait();
-
-  case tok::kw___is_trivially_constructible:
+#define TYPE_TRAIT(N,Spelling,K) \
+  case tok::kw_##Spelling:
+#include "clang/Basic/TokenKinds.def"
     return ParseTypeTrait();
       
   case tok::kw___array_rank:
@@ -1358,8 +1259,8 @@
       SourceLocation RLoc = Tok.getLocation();
 
       if (!LHS.isInvalid() && !Idx.isInvalid() && Tok.is(tok::r_square)) {
-        LHS = Actions.ActOnArraySubscriptExpr(getCurScope(), LHS.take(), Loc,
-                                              Idx.take(), RLoc);
+        LHS = Actions.ActOnArraySubscriptExpr(getCurScope(), LHS.get(), Loc,
+                                              Idx.get(), RLoc);
       } else
         LHS = ExprError();
 
@@ -1373,8 +1274,8 @@
                                //   '(' argument-expression-list[opt] ')'
       tok::TokenKind OpKind = Tok.getKind();
       InMessageExpressionRAIIObject InMessage(*this, false);
-      
-      Expr *ExecConfig = 0;
+
+      Expr *ExecConfig = nullptr;
 
       BalancedDelimiterTracker PT(*this, tok::l_paren);
 
@@ -1387,21 +1288,20 @@
           LHS = ExprError();
         }
 
-        SourceLocation CloseLoc = Tok.getLocation();
-        if (Tok.is(tok::greatergreatergreater)) {
-          ConsumeToken();
+        SourceLocation CloseLoc;
+        if (TryConsumeToken(tok::greatergreatergreater, CloseLoc)) {
         } else if (LHS.isInvalid()) {
           SkipUntil(tok::greatergreatergreater, StopAtSemi);
         } else {
           // There was an error closing the brackets
-          Diag(Tok, diag::err_expected_ggg);
-          Diag(OpenLoc, diag::note_matching) << "<<<";
+          Diag(Tok, diag::err_expected) << tok::greatergreatergreater;
+          Diag(OpenLoc, diag::note_matching) << tok::lesslessless;
           SkipUntil(tok::greatergreatergreater, StopAtSemi);
           LHS = ExprError();
         }
 
         if (!LHS.isInvalid()) {
-          if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen, ""))
+          if (ExpectAndConsume(tok::l_paren))
             LHS = ExprError();
           else
             Loc = PrevTokLocation;
@@ -1450,7 +1350,7 @@
         assert((ArgExprs.size() == 0 || 
                 ArgExprs.size()-1 == CommaLocs.size())&&
                "Unexpected number of commas!");
-        LHS = Actions.ActOnCallExpr(getCurScope(), LHS.take(), Loc,
+        LHS = Actions.ActOnCallExpr(getCurScope(), LHS.get(), Loc,
                                     ArgExprs, Tok.getLocation(),
                                     ExecConfig);
         PT.consumeClose();
@@ -1469,14 +1369,14 @@
       ParsedType ObjectType;
       bool MayBePseudoDestructor = false;
       if (getLangOpts().CPlusPlus && !LHS.isInvalid()) {
-        Expr *Base = LHS.take();
+        Expr *Base = LHS.get();
         const Type* BaseType = Base->getType().getTypePtrOrNull();
         if (BaseType && Tok.is(tok::l_paren) &&
             (BaseType->isFunctionType() ||
              BaseType->isSpecificPlaceholderType(BuiltinType::BoundMember))) {
           Diag(OpLoc, diag::err_function_is_not_record)
-            << (OpKind == tok::arrow) << Base->getSourceRange()
-            << FixItHint::CreateRemoval(OpLoc);
+              << OpKind << Base->getSourceRange()
+              << FixItHint::CreateRemoval(OpLoc);
           return ParsePostfixExpressionSuffix(Base);
         }
 
@@ -1503,7 +1403,7 @@
       }
       
       if (MayBePseudoDestructor && !LHS.isInvalid()) {
-        LHS = ParseCXXPseudoDestructor(LHS.take(), OpLoc, OpKind, SS, 
+        LHS = ParseCXXPseudoDestructor(LHS.get(), OpLoc, OpKind, SS, 
                                        ObjectType);
         break;
       }
@@ -1537,9 +1437,10 @@
         LHS = ExprError();
       
       if (!LHS.isInvalid())
-        LHS = Actions.ActOnMemberAccessExpr(getCurScope(), LHS.take(), OpLoc, 
+        LHS = Actions.ActOnMemberAccessExpr(getCurScope(), LHS.get(), OpLoc, 
                                             OpKind, SS, TemplateKWLoc, Name,
-                                 CurParsedObjCImpl ? CurParsedObjCImpl->Dcl : 0,
+                                 CurParsedObjCImpl ? CurParsedObjCImpl->Dcl
+                                                   : nullptr,
                                             Tok.is(tok::l_paren));
       break;
     }
@@ -1547,7 +1448,7 @@
     case tok::minusminus:  // postfix-expression: postfix-expression '--'
       if (!LHS.isInvalid()) {
         LHS = Actions.ActOnPostfixUnaryOp(getCurScope(), Tok.getLocation(),
-                                          Tok.getKind(), LHS.take());
+                                          Tok.getKind(), LHS.get());
       }
       ConsumeToken();
       break;
@@ -1597,8 +1498,7 @@
     // pathenthesis around type name.
     if (OpTok.is(tok::kw_sizeof)  || OpTok.is(tok::kw___alignof) ||
         OpTok.is(tok::kw_alignof) || OpTok.is(tok::kw__Alignof)) {
-      bool isAmbiguousTypeId;
-      if (isTypeIdInParens(isAmbiguousTypeId)) {
+      if (isTypeIdUnambiguously()) {
         DeclSpec DS(AttrFactory);
         ParseSpecifierQualifierList(DS);
         Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
@@ -1617,7 +1517,8 @@
 
     isCastExpr = false;
     if (OpTok.is(tok::kw_typeof) && !getLangOpts().CPlusPlus) {
-      Diag(Tok,diag::err_expected_lparen_after_id) << OpTok.getIdentifierInfo();
+      Diag(Tok, diag::err_expected_after) << OpTok.getIdentifierInfo()
+                                          << tok::l_paren;
       return ExprError();
     }
 
@@ -1681,7 +1582,7 @@
   if (Tok.is(tok::ellipsis) && OpTok.is(tok::kw_sizeof)) {
     SourceLocation EllipsisLoc = ConsumeToken();
     SourceLocation LParenLoc, RParenLoc;
-    IdentifierInfo *Name = 0;
+    IdentifierInfo *Name = nullptr;
     SourceLocation NameLoc;
     if (Tok.is(tok::l_paren)) {
       BalancedDelimiterTracker T(*this, tok::l_paren);
@@ -1759,7 +1660,7 @@
     Operand = Actions.ActOnUnaryExprOrTypeTraitExpr(OpTok.getLocation(),
                                                     ExprKind,
                                                     /*isType=*/false,
-                                                    Operand.release(),
+                                                    Operand.get(),
                                                     CastRange);
   return Operand;
 }
@@ -1789,8 +1690,8 @@
 
   // All of these start with an open paren.
   if (Tok.isNot(tok::l_paren))
-    return ExprError(Diag(Tok, diag::err_expected_lparen_after_id)
-                       << BuiltinII);
+    return ExprError(Diag(Tok, diag::err_expected_after) << BuiltinII
+                                                         << tok::l_paren);
 
   BalancedDelimiterTracker PT(*this, tok::l_paren);
   PT.consumeOpen();
@@ -1802,20 +1703,22 @@
   case tok::kw___builtin_va_arg: {
     ExprResult Expr(ParseAssignmentExpression());
 
-    if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
+    if (ExpectAndConsume(tok::comma)) {
+      SkipUntil(tok::r_paren, StopAtSemi);
       Expr = ExprError();
+    }
 
     TypeResult Ty = ParseTypeName();
 
     if (Tok.isNot(tok::r_paren)) {
-      Diag(Tok, diag::err_expected_rparen);
+      Diag(Tok, diag::err_expected) << tok::r_paren;
       Expr = ExprError();
     }
 
     if (Expr.isInvalid() || Ty.isInvalid())
       Res = ExprError();
     else
-      Res = Actions.ActOnVAArg(StartLoc, Expr.take(), Ty.get(), ConsumeParen());
+      Res = Actions.ActOnVAArg(StartLoc, Expr.get(), Ty.get(), ConsumeParen());
     break;
   }
   case tok::kw___builtin_offsetof: {
@@ -1826,12 +1729,14 @@
       return ExprError();
     }
 
-    if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
+    if (ExpectAndConsume(tok::comma)) {
+      SkipUntil(tok::r_paren, StopAtSemi);
       return ExprError();
+    }
 
     // We must have at least one identifier here.
     if (Tok.isNot(tok::identifier)) {
-      Diag(Tok, diag::err_expected_ident);
+      Diag(Tok, diag::err_expected) << tok::identifier;
       SkipUntil(tok::r_paren, StopAtSemi);
       return ExprError();
     }
@@ -1853,7 +1758,7 @@
         Comps.back().LocStart = ConsumeToken();
 
         if (Tok.isNot(tok::identifier)) {
-          Diag(Tok, diag::err_expected_ident);
+          Diag(Tok, diag::err_expected) << tok::identifier;
           SkipUntil(tok::r_paren, StopAtSemi);
           return ExprError();
         }
@@ -1875,7 +1780,7 @@
           SkipUntil(tok::r_paren, StopAtSemi);
           return Res;
         }
-        Comps.back().U.E = Res.release();
+        Comps.back().U.E = Res.get();
 
         ST.consumeClose();
         Comps.back().LocEnd = ST.getCloseLocation();
@@ -1902,16 +1807,20 @@
       SkipUntil(tok::r_paren, StopAtSemi);
       return Cond;
     }
-    if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
+    if (ExpectAndConsume(tok::comma)) {
+      SkipUntil(tok::r_paren, StopAtSemi);
       return ExprError();
+    }
 
     ExprResult Expr1(ParseAssignmentExpression());
     if (Expr1.isInvalid()) {
       SkipUntil(tok::r_paren, StopAtSemi);
       return Expr1;
     }
-    if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
+    if (ExpectAndConsume(tok::comma)) {
+      SkipUntil(tok::r_paren, StopAtSemi);
       return ExprError();
+    }
 
     ExprResult Expr2(ParseAssignmentExpression());
     if (Expr2.isInvalid()) {
@@ -1919,11 +1828,11 @@
       return Expr2;
     }
     if (Tok.isNot(tok::r_paren)) {
-      Diag(Tok, diag::err_expected_rparen);
+      Diag(Tok, diag::err_expected) << tok::r_paren;
       return ExprError();
     }
-    Res = Actions.ActOnChooseExpr(StartLoc, Cond.take(), Expr1.take(),
-                                  Expr2.take(), ConsumeParen());
+    Res = Actions.ActOnChooseExpr(StartLoc, Cond.get(), Expr1.get(),
+                                  Expr2.get(), ConsumeParen());
     break;
   }
   case tok::kw___builtin_astype: {
@@ -1933,11 +1842,12 @@
       SkipUntil(tok::r_paren, StopAtSemi);
       return ExprError();
     }
-    
-    if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", 
-                         tok::r_paren))
+
+    if (ExpectAndConsume(tok::comma)) {
+      SkipUntil(tok::r_paren, StopAtSemi);
       return ExprError();
-    
+    }
+
     // Second argument is the type to bitcast to.
     TypeResult DestTy = ParseTypeName();
     if (DestTy.isInvalid())
@@ -1945,12 +1855,12 @@
     
     // Attempt to consume the r-paren.
     if (Tok.isNot(tok::r_paren)) {
-      Diag(Tok, diag::err_expected_rparen);
+      Diag(Tok, diag::err_expected) << tok::r_paren;
       SkipUntil(tok::r_paren, StopAtSemi);
       return ExprError();
     }
     
-    Res = Actions.ActOnAsTypeExpr(Expr.take(), DestTy.get(), StartLoc, 
+    Res = Actions.ActOnAsTypeExpr(Expr.get(), DestTy.get(), StartLoc, 
                                   ConsumeParen());
     break;
   }
@@ -1961,11 +1871,12 @@
       SkipUntil(tok::r_paren, StopAtSemi);
       return ExprError();
     }
-    
-    if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", 
-                         tok::r_paren))
+
+    if (ExpectAndConsume(tok::comma)) {
+      SkipUntil(tok::r_paren, StopAtSemi);
       return ExprError();
-    
+    }
+
     // Second argument is the type to bitcast to.
     TypeResult DestTy = ParseTypeName();
     if (DestTy.isInvalid())
@@ -1973,12 +1884,12 @@
     
     // Attempt to consume the r-paren.
     if (Tok.isNot(tok::r_paren)) {
-      Diag(Tok, diag::err_expected_rparen);
+      Diag(Tok, diag::err_expected) << tok::r_paren;
       SkipUntil(tok::r_paren, StopAtSemi);
       return ExprError();
     }
     
-    Res = Actions.ActOnConvertVectorExpr(Expr.take(), DestTy.get(), StartLoc, 
+    Res = Actions.ActOnConvertVectorExpr(Expr.get(), DestTy.get(), StartLoc, 
                                          ConsumeParen());
     break;
   }
@@ -1989,7 +1900,7 @@
 
   // These can be followed by postfix-expr pieces because they are
   // primary-expressions.
-  return ParsePostfixExpressionSuffix(Res.take());
+  return ParsePostfixExpressionSuffix(Res.get());
 }
 
 /// ParseParenExpression - This parses the unit that starts with a '(' token,
@@ -2018,6 +1929,7 @@
                              bool isTypeCast, ParsedType &CastTy,
                              SourceLocation &RParenLoc) {
   assert(Tok.is(tok::l_paren) && "Not a paren expr!");
+  ColonProtectionRAIIObject ColonProtection(*this, false);
   BalancedDelimiterTracker T(*this, tok::l_paren);
   if (T.consumeOpen())
     return ExprError();
@@ -2042,7 +1954,7 @@
                       Tok.is(tok::kw___bridge_retained) ||
                       Tok.is(tok::kw___bridge_retain)));
   if (BridgeCast && !getLangOpts().ObjCAutoRefCount) {
-    if (Tok.isNot(tok::kw___bridge)) {
+    if (!TryConsumeToken(tok::kw___bridge)) {
       StringRef BridgeCastName = Tok.getName();
       SourceLocation BridgeKeywordLoc = ConsumeToken();
       if (!PP.getSourceManager().isInSystemHeader(BridgeKeywordLoc))
@@ -2050,8 +1962,6 @@
           << BridgeCastName
           << FixItHint::CreateReplacement(BridgeKeywordLoc, "");
     }
-    else
-      ConsumeToken(); // consume __bridge
     BridgeCast = false;
   }
   
@@ -2066,7 +1976,7 @@
 
     // If the substmt parsed correctly, build the AST node.
     if (!Stmt.isInvalid()) {
-      Result = Actions.ActOnStmtExpr(OpenLoc, Stmt.take(), Tok.getLocation());
+      Result = Actions.ActOnStmtExpr(OpenLoc, Stmt.get(), Tok.getLocation());
     } else {
       Actions.ActOnStmtExprError();
     }
@@ -2095,6 +2005,7 @@
              
     TypeResult Ty = ParseTypeName();
     T.consumeClose();
+    ColonProtection.restore();
     RParenLoc = T.getCloseLocation();
     ExprResult SubExpr = ParseCastExpression(/*isUnaryExpression=*/false);
     
@@ -2115,7 +2026,8 @@
     // if stopIfCastExpr is false, we need to determine the context past the
     // parens, so we defer to ParseCXXAmbiguousParenExpression for that.
     if (isAmbiguousTypeId && !stopIfCastExpr) {
-      ExprResult res = ParseCXXAmbiguousParenExpression(ExprType, CastTy, T);
+      ExprResult res = ParseCXXAmbiguousParenExpression(ExprType, CastTy, T,
+                                                        ColonProtection);
       RParenLoc = T.getCloseLocation();
       return res;
     }
@@ -2139,10 +2051,11 @@
       }
       Result = ParseObjCMessageExpressionBody(SourceLocation(), 
                                               SourceLocation(), 
-                                              Ty.get(), 0);
+                                              Ty.get(), nullptr);
     } else {          
       // Match the ')'.
       T.consumeClose();
+      ColonProtection.restore();
       RParenLoc = T.getCloseLocation();
       if (Tok.is(tok::l_brace)) {
         ExprType = CompoundLiteral;
@@ -2171,7 +2084,7 @@
           CastTy = Ty.get();
           return ExprResult();
         }
-        
+
         // Reject the cast of super idiom in ObjC.
         if (Tok.is(tok::identifier) && getLangOpts().ObjC1 &&
             Tok.getIdentifierInfo() == Ident_super && 
@@ -2190,7 +2103,7 @@
         if (!Result.isInvalid()) {
           Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc,
                                          DeclaratorInfo, CastTy, 
-                                         RParenLoc, Result.take());
+                                         RParenLoc, Result.get());
         }
         return Result;
       }
@@ -2218,7 +2131,8 @@
 
     // Don't build a paren expression unless we actually match a ')'.
     if (!Result.isInvalid() && Tok.is(tok::r_paren))
-      Result = Actions.ActOnParenExpr(OpenLoc, Tok.getLocation(), Result.take());
+      Result =
+          Actions.ActOnParenExpr(OpenLoc, Tok.getLocation(), Result.get());
   }
 
   // Match the ')'.
@@ -2249,7 +2163,7 @@
     Diag(LParenLoc, diag::ext_c99_compound_literal);
   ExprResult Result = ParseInitializer();
   if (!Result.isInvalid() && Ty)
-    return Actions.ActOnCompoundLiteral(LParenLoc, Ty, RParenLoc, Result.take());
+    return Actions.ActOnCompoundLiteral(LParenLoc, Ty, RParenLoc, Result.get());
   return Result;
 }
 
@@ -2274,8 +2188,9 @@
   } while (isTokenStringLiteral());
 
   // Pass the set of string tokens, ready for concatenation, to the actions.
-  return Actions.ActOnStringLiteral(&StringToks[0], StringToks.size(),
-                                   AllowUserDefinedLiteral ? getCurScope() : 0);
+  return Actions.ActOnStringLiteral(StringToks,
+                                    AllowUserDefinedLiteral ? getCurScope()
+                                                            : nullptr);
 }
 
 /// ParseGenericSelectionExpression - Parse a C11 generic-selection
@@ -2299,7 +2214,7 @@
     Diag(KeyLoc, diag::ext_c11_generic_selection);
 
   BalancedDelimiterTracker T(*this, tok::l_paren);
-  if (T.expectAndConsume(diag::err_expected_lparen))
+  if (T.expectAndConsume())
     return ExprError();
 
   ExprResult ControllingExpr;
@@ -2314,7 +2229,7 @@
     }
   }
 
-  if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "")) {
+  if (ExpectAndConsume(tok::comma)) {
     SkipUntil(tok::r_paren, StopAtSemi);
     return ExprError();
   }
@@ -2322,7 +2237,7 @@
   SourceLocation DefaultLoc;
   TypeVector Types;
   ExprVector Exprs;
-  while (1) {
+  do {
     ParsedType Ty;
     if (Tok.is(tok::kw_default)) {
       // C11 6.5.1.1p2 "A generic selection shall have no more than one default
@@ -2342,11 +2257,11 @@
         SkipUntil(tok::r_paren, StopAtSemi);
         return ExprError();
       }
-      Ty = TR.release();
+      Ty = TR.get();
     }
     Types.push_back(Ty);
 
-    if (ExpectAndConsume(tok::colon, diag::err_expected_colon, "")) {
+    if (ExpectAndConsume(tok::colon)) {
       SkipUntil(tok::r_paren, StopAtSemi);
       return ExprError();
     }
@@ -2358,12 +2273,8 @@
       SkipUntil(tok::r_paren, StopAtSemi);
       return ExprError();
     }
-    Exprs.push_back(ER.release());
-
-    if (Tok.isNot(tok::comma))
-      break;
-    ConsumeToken();
-  }
+    Exprs.push_back(ER.get());
+  } while (TryConsumeToken(tok::comma));
 
   T.consumeClose();
   if (T.getCloseLocation().isInvalid())
@@ -2371,7 +2282,7 @@
 
   return Actions.ActOnGenericSelectionExpr(KeyLoc, DefaultLoc, 
                                            T.getCloseLocation(),
-                                           ControllingExpr.release(),
+                                           ControllingExpr.get(),
                                            Types, Exprs);
 }
 
@@ -2403,6 +2314,7 @@
                                                          Expr *Data,
                                                          ArrayRef<Expr *> Args),
                                  Expr *Data) {
+  bool SawError = false;
   while (1) {
     if (Tok.is(tok::code_completion)) {
       if (Completer)
@@ -2422,13 +2334,15 @@
 
     if (Tok.is(tok::ellipsis))
       Expr = Actions.ActOnPackExpansion(Expr.get(), ConsumeToken());    
-    if (Expr.isInvalid())
-      return true;
-
-    Exprs.push_back(Expr.release());
+    if (Expr.isInvalid()) {
+      SkipUntil(tok::comma, tok::r_paren, StopBeforeMatch);
+      SawError = true;
+    } else {
+      Exprs.push_back(Expr.get());
+    }
 
     if (Tok.isNot(tok::comma))
-      return false;
+      return SawError;
     // Move to the next argument, remember where the comma was.
     CommaLocs.push_back(ConsumeToken());
   }
@@ -2450,7 +2364,7 @@
     if (Expr.isInvalid())
       return true;
 
-    Exprs.push_back(Expr.release());
+    Exprs.push_back(Expr.get());
 
     if (Tok.isNot(tok::comma))
       return false;
@@ -2531,7 +2445,7 @@
     // SetIdentifier sets the source range end, but in this case we're past
     // that location.
     SourceLocation Tmp = ParamInfo.getSourceRange().getEnd();
-    ParamInfo.SetIdentifier(0, CaretLoc);
+    ParamInfo.SetIdentifier(nullptr, CaretLoc);
     ParamInfo.SetRangeEnd(Tmp);
     if (ParamInfo.isInvalidType()) {
       // If there was an error parsing the arguments, they may have
@@ -2554,7 +2468,7 @@
     ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(/*HasProto=*/true,
                                              /*IsAmbiguous=*/false,
                                              /*RParenLoc=*/NoLoc,
-                                             /*ArgInfo=*/0,
+                                             /*ArgInfo=*/nullptr,
                                              /*NumArgs=*/0,
                                              /*EllipsisLoc=*/NoLoc,
                                              /*RParenLoc=*/NoLoc,
@@ -2566,10 +2480,10 @@
                                              /*MutableLoc=*/NoLoc,
                                              EST_None,
                                              /*ESpecLoc=*/NoLoc,
-                                             /*Exceptions=*/0,
-                                             /*ExceptionRanges=*/0,
+                                             /*Exceptions=*/nullptr,
+                                             /*ExceptionRanges=*/nullptr,
                                              /*NumExceptions=*/0,
-                                             /*NoexceptExpr=*/0,
+                                             /*NoexceptExpr=*/nullptr,
                                              CaretLoc, CaretLoc,
                                              ParamInfo),
                           attrs, CaretLoc);
@@ -2592,7 +2506,7 @@
   StmtResult Stmt(ParseCompoundStatementBody());
   BlockScope.Exit();
   if (!Stmt.isInvalid())
-    Result = Actions.ActOnBlockStmtExpr(CaretLoc, Stmt.take(), getCurScope());
+    Result = Actions.ActOnBlockStmtExpr(CaretLoc, Stmt.get(), getCurScope());
   else
     Actions.ActOnBlockError(CaretLoc, getCurScope());
   return Result;
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index fe357cf..83121a8 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -10,12 +10,13 @@
 // This file implements the Expression parsing implementation for C++.
 //
 //===----------------------------------------------------------------------===//
-#include "clang/AST/DeclTemplate.h"
-#include "clang/Parse/Parser.h"
+#include "clang/AST/ASTContext.h"
 #include "RAIIObjectsForParser.h"
+#include "clang/AST/DeclTemplate.h"
 #include "clang/Basic/PrettyStackTrace.h"
 #include "clang/Lex/LiteralSupport.h"
 #include "clang/Parse/ParseDiagnostic.h"
+#include "clang/Parse/Parser.h"
 #include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/ParsedTemplate.h"
 #include "clang/Sema/Scope.h"
@@ -26,7 +27,9 @@
 
 static int SelectDigraphErrorMessage(tok::TokenKind Kind) {
   switch (Kind) {
-    case tok::kw_template:         return 0;
+    // template name
+    case tok::unknown:             return 0;
+    // casts
     case tok::kw_const_cast:       return 1;
     case tok::kw_dynamic_cast:     return 2;
     case tok::kw_reinterpret_cast: return 3;
@@ -93,7 +96,7 @@
                               Template, MemberOfUnknownSpecialization))
     return;
 
-  FixDigraph(*this, PP, Next, SecondToken, tok::kw_template,
+  FixDigraph(*this, PP, Next, SecondToken, tok::unknown,
              /*AtDigraph*/false);
 }
 
@@ -204,7 +207,7 @@
   }
 
   if (LastII)
-    *LastII = 0;
+    *LastII = nullptr;
 
   bool HasScopeSpecifier = false;
 
@@ -233,12 +236,13 @@
     DeclSpec DS(AttrFactory);
     SourceLocation DeclLoc = Tok.getLocation();
     SourceLocation EndLoc  = ParseDecltypeSpecifier(DS);
-    if (Tok.isNot(tok::coloncolon)) {
+
+    SourceLocation CCLoc;
+    if (!TryConsumeToken(tok::coloncolon, CCLoc)) {
       AnnotateExistingDecltypeSpecifier(DS, DeclLoc, EndLoc);
       return false;
     }
-    
-    SourceLocation CCLoc = ConsumeToken();
+
     if (Actions.ActOnCXXNestedNameSpecifierDecltype(SS, DS, CCLoc))
       SS.SetInvalid(SourceRange(DeclLoc, CCLoc));
 
@@ -287,19 +291,23 @@
 
       TentativeParsingAction TPA(*this);
       SourceLocation TemplateKWLoc = ConsumeToken();
-      
+
       UnqualifiedId TemplateName;
       if (Tok.is(tok::identifier)) {
         // Consume the identifier.
         TemplateName.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
         ConsumeToken();
       } else if (Tok.is(tok::kw_operator)) {
-        if (ParseUnqualifiedIdOperator(SS, EnteringContext, ObjectType, 
+        // We don't need to actually parse the unqualified-id in this case,
+        // because a simple-template-id cannot start with 'operator', but
+        // go ahead and parse it anyway for consistency with the case where
+        // we already annotated the template-id.
+        if (ParseUnqualifiedIdOperator(SS, EnteringContext, ObjectType,
                                        TemplateName)) {
           TPA.Commit();
           break;
         }
-        
+
         if (TemplateName.getKind() != UnqualifiedId::IK_OperatorFunctionId &&
             TemplateName.getKind() != UnqualifiedId::IK_LiteralOperatorId) {
           Diag(TemplateName.getSourceRange().getBegin(),
@@ -341,10 +349,10 @@
     if (Tok.is(tok::annot_template_id) && NextToken().is(tok::coloncolon)) {
       // We have
       //
-      //   simple-template-id '::'
+      //   template-id '::'
       //
-      // So we need to check whether the simple-template-id is of the
-      // right kind (it should name a type or be dependent), and then
+      // So we need to check whether the template-id is a simple-template-id of
+      // the right kind (it should name a type or be dependent), and then
       // convert it into a type within the nested-name-specifier.
       TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
       if (CheckForDestructor && GetLookAheadToken(2).is(tok::tilde)) {
@@ -357,15 +365,15 @@
 
       // Consume the template-id token.
       ConsumeToken();
-      
+
       assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!");
       SourceLocation CCLoc = ConsumeToken();
 
       HasScopeSpecifier = true;
-      
+
       ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),
                                          TemplateId->NumArgs);
-      
+
       if (Actions.ActOnCXXNestedNameSpecifier(getCurScope(),
                                               SS,
                                               TemplateId->TemplateKWLoc,
@@ -385,7 +393,6 @@
       continue;
     }
 
-
     // The rest of the nested-name-specifier possibilities start with
     // tok::identifier.
     if (Tok.isNot(tok::identifier))
@@ -410,9 +417,8 @@
           // error, but they probably meant something else strange so don't
           // recover like this.
           PP.LookAhead(1).is(tok::identifier)) {
-        Diag(Next, diag::err_unexected_colon_in_nested_name_spec)
+        Diag(Next, diag::err_unexpected_colon_in_nested_name_spec)
           << FixItHint::CreateReplacement(Next.getLocation(), "::");
-        
         // Recover as if the user wrote '::'.
         Next.setKind(tok::coloncolon);
       }
@@ -426,23 +432,52 @@
         return false;
       }
 
+      if (ColonIsSacred) {
+        const Token &Next2 = GetLookAheadToken(2);
+        if (Next2.is(tok::kw_private) || Next2.is(tok::kw_protected) ||
+            Next2.is(tok::kw_public) || Next2.is(tok::kw_virtual)) {
+          Diag(Next2, diag::err_unexpected_token_in_nested_name_spec)
+              << Next2.getName()
+              << FixItHint::CreateReplacement(Next.getLocation(), ":");
+          Token ColonColon;
+          PP.Lex(ColonColon);
+          ColonColon.setKind(tok::colon);
+          PP.EnterToken(ColonColon);
+          break;
+        }
+      }
+
       if (LastII)
         *LastII = &II;
 
       // We have an identifier followed by a '::'. Lookup this name
       // as the name in a nested-name-specifier.
+      Token Identifier = Tok;
       SourceLocation IdLoc = ConsumeToken();
       assert((Tok.is(tok::coloncolon) || Tok.is(tok::colon)) &&
              "NextToken() not working properly!");
+      Token ColonColon = Tok;
       SourceLocation CCLoc = ConsumeToken();
 
       CheckForLParenAfterColonColon();
 
-      HasScopeSpecifier = true;
+      bool IsCorrectedToColon = false;
+      bool *CorrectionFlagPtr = ColonIsSacred ? &IsCorrectedToColon : nullptr;
       if (Actions.ActOnCXXNestedNameSpecifier(getCurScope(), II, IdLoc, CCLoc,
-                                              ObjectType, EnteringContext, SS))
+                                              ObjectType, EnteringContext, SS,
+                                              false, CorrectionFlagPtr)) {
+        // Identifier is not recognized as a nested name, but we can have
+        // mistyped '::' instead of ':'.
+        if (CorrectionFlagPtr && IsCorrectedToColon) {
+          ColonColon.setKind(tok::colon);
+          PP.EnterToken(Tok);
+          PP.EnterToken(ColonColon);
+          Tok = Identifier;
+          break;
+        }
         SS.SetInvalid(SourceRange(IdLoc, CCLoc));
-      
+      }
+      HasScopeSpecifier = true;
       continue;
     }
 
@@ -633,8 +668,7 @@
 ExprResult Parser::ParseLambdaExpression() {
   // Parse lambda-introducer.
   LambdaIntroducer Intro;
-
-  Optional<unsigned> DiagID(ParseLambdaIntroducer(Intro));
+  Optional<unsigned> DiagID = ParseLambdaIntroducer(Intro);
   if (DiagID) {
     Diag(Tok, DiagID.getValue());
     SkipUntil(tok::r_square, StopAtSemi);
@@ -674,7 +708,7 @@
   if (Next.is(tok::identifier) && After.is(tok::identifier)) {
     return ExprEmpty();
   }
-
+ 
   // Here, we're stuck: lambda introducers and Objective-C message sends are
   // unambiguous, but it requires arbitrary lookhead.  [a,b,c,d,e,f,g] is a
   // lambda, and [a,b,c,d,e,f,g h] is a Objective-C message send.  Instead of
@@ -684,6 +718,7 @@
   LambdaIntroducer Intro;
   if (TryParseLambdaIntroducer(Intro))
     return ExprEmpty();
+
   return ParseLambdaExpressionAfterIntroducer(Intro);
 }
 
@@ -732,7 +767,7 @@
               !Intro.Captures.empty())) {
           Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro, 
                                                /*AfterAmpersand=*/false);
-          ConsumeCodeCompletionToken();
+          cutOffParsing();
           break;
         }
 
@@ -749,7 +784,7 @@
       else
         Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro, 
                                              /*AfterAmpersand=*/false);
-      ConsumeCodeCompletionToken();
+      cutOffParsing();
       break;
     }
 
@@ -758,7 +793,7 @@
     // Parse capture.
     LambdaCaptureKind Kind = LCK_ByCopy;
     SourceLocation Loc;
-    IdentifierInfo* Id = 0;
+    IdentifierInfo *Id = nullptr;
     SourceLocation EllipsisLoc;
     ExprResult Init;
     
@@ -773,7 +808,7 @@
         if (Tok.is(tok::code_completion)) {
           Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro, 
                                                /*AfterAmpersand=*/true);
-          ConsumeCodeCompletionToken();
+          cutOffParsing();
           break;
         }
       }
@@ -809,8 +844,12 @@
                                             Exprs);
         }
       } else if (Tok.is(tok::l_brace) || Tok.is(tok::equal)) {
-        if (Tok.is(tok::equal))
-          ConsumeToken();
+        // Each lambda init-capture forms its own full expression, which clears
+        // Actions.MaybeODRUseExprs. So create an expression evaluation context
+        // to save the necessary state, and restore it later.
+        EnterExpressionEvaluationContext EC(Actions,
+                                            Sema::PotentiallyEvaluated);
+        TryConsumeToken(tok::equal);
 
         if (!SkippedInits)
           Init = ParseInitializer();
@@ -825,8 +864,8 @@
           //   [..., x = expr
           //
           // We need to find the end of the following expression in order to
-          // determine whether this is an Obj-C message send's receiver, or a
-          // lambda init-capture.
+          // determine whether this is an Obj-C message send's receiver, a
+          // C99 designator, or a lambda init-capture.
           //
           // Parse the expression to find where it ends, and annotate it back
           // onto the tokens. We would have parsed this expression the same way
@@ -859,16 +898,64 @@
             ConsumeToken();
           }
         }
-      } else if (Tok.is(tok::ellipsis))
-        EllipsisLoc = ConsumeToken();
+      } else
+        TryConsumeToken(tok::ellipsis, EllipsisLoc);
     }
+    // If this is an init capture, process the initialization expression
+    // right away.  For lambda init-captures such as the following:
+    // const int x = 10;
+    //  auto L = [i = x+1](int a) {
+    //    return [j = x+2,
+    //           &k = x](char b) { };
+    //  };
+    // keep in mind that each lambda init-capture has to have:
+    //  - its initialization expression executed in the context
+    //    of the enclosing/parent decl-context.
+    //  - but the variable itself has to be 'injected' into the
+    //    decl-context of its lambda's call-operator (which has
+    //    not yet been created).
+    // Each init-expression is a full-expression that has to get
+    // Sema-analyzed (for capturing etc.) before its lambda's
+    // call-operator's decl-context, scope & scopeinfo are pushed on their
+    // respective stacks.  Thus if any variable is odr-used in the init-capture
+    // it will correctly get captured in the enclosing lambda, if one exists.
+    // The init-variables above are created later once the lambdascope and
+    // call-operators decl-context is pushed onto its respective stack.
 
-    Intro.addCapture(Kind, Loc, Id, EllipsisLoc, Init);
+    // Since the lambda init-capture's initializer expression occurs in the
+    // context of the enclosing function or lambda, therefore we can not wait
+    // till a lambda scope has been pushed on before deciding whether the
+    // variable needs to be captured.  We also need to process all
+    // lvalue-to-rvalue conversions and discarded-value conversions,
+    // so that we can avoid capturing certain constant variables.
+    // For e.g.,
+    //  void test() {
+    //   const int x = 10;
+    //   auto L = [&z = x](char a) { <-- don't capture by the current lambda
+    //     return [y = x](int i) { <-- don't capture by enclosing lambda
+    //          return y;
+    //     }
+    //   };
+    // If x was not const, the second use would require 'L' to capture, and
+    // that would be an error.
+
+    ParsedType InitCaptureParsedType;
+    if (Init.isUsable()) {
+      // Get the pointer and store it in an lvalue, so we can use it as an
+      // out argument.
+      Expr *InitExpr = Init.get();
+      // This performs any lvalue-to-rvalue conversions if necessary, which
+      // can affect what gets captured in the containing decl-context.
+      QualType InitCaptureType = Actions.performLambdaInitCaptureInitialization(
+        Loc, Kind == LCK_ByRef, Id, InitExpr);
+      Init = InitExpr;
+      InitCaptureParsedType.set(InitCaptureType);
+    }
+    Intro.addCapture(Kind, Loc, Id, EllipsisLoc, Init, InitCaptureParsedType);
   }
 
   T.consumeClose();
   Intro.Range.setEnd(T.getCloseLocation());
-
   return DiagResult();
 }
 
@@ -935,7 +1022,6 @@
     ParsedAttributes Attr(AttrFactory);
     SmallVector<DeclaratorChunk::ParamInfo, 16> ParamInfo;
     SourceLocation EllipsisLoc;
-
     
     if (Tok.isNot(tok::r_paren)) {
       Actions.RecordParsingTemplateParameterDepth(TemplateParameterDepth);
@@ -949,12 +1035,14 @@
     SourceLocation RParenLoc = T.getCloseLocation();
     DeclEndLoc = RParenLoc;
 
+    // GNU-style attributes must be parsed before the mutable specifier to be
+    // compatible with GCC.
+    MaybeParseGNUAttributes(Attr, &DeclEndLoc);
+
     // Parse 'mutable'[opt].
     SourceLocation MutableLoc;
-    if (Tok.is(tok::kw_mutable)) {
-      MutableLoc = ConsumeToken();
+    if (TryConsumeToken(tok::kw_mutable, MutableLoc))
       DeclEndLoc = MutableLoc;
-    }
 
     // Parse exception-specification[opt].
     ExceptionSpecificationType ESpecType = EST_None;
@@ -1004,26 +1092,45 @@
                                            DynamicExceptionRanges.data(),
                                            DynamicExceptions.size(),
                                            NoexceptExpr.isUsable() ?
-                                             NoexceptExpr.get() : 0,
+                                             NoexceptExpr.get() : nullptr,
                                            LParenLoc, FunLocalRangeEnd, D,
                                            TrailingReturnType),
                   Attr, DeclEndLoc);
-  } else if (Tok.is(tok::kw_mutable) || Tok.is(tok::arrow)) {
-    // It's common to forget that one needs '()' before 'mutable' or the 
-    // result type. Deal with this.
+  } else if (Tok.is(tok::kw_mutable) || Tok.is(tok::arrow) ||
+             Tok.is(tok::kw___attribute) ||
+             (Tok.is(tok::l_square) && NextToken().is(tok::l_square))) {
+    // It's common to forget that one needs '()' before 'mutable', an attribute
+    // specifier, or the result type. Deal with this.
+    unsigned TokKind = 0;
+    switch (Tok.getKind()) {
+    case tok::kw_mutable: TokKind = 0; break;
+    case tok::arrow: TokKind = 1; break;
+    case tok::kw___attribute:
+    case tok::l_square: TokKind = 2; break;
+    default: llvm_unreachable("Unknown token kind");
+    }
+
     Diag(Tok, diag::err_lambda_missing_parens)
-      << Tok.is(tok::arrow)
+      << TokKind
       << FixItHint::CreateInsertion(Tok.getLocation(), "() ");
     SourceLocation DeclLoc = Tok.getLocation();
     SourceLocation DeclEndLoc = DeclLoc;
-    
+
+    // GNU-style attributes must be parsed before the mutable specifier to be
+    // compatible with GCC.
+    ParsedAttributes Attr(AttrFactory);
+    MaybeParseGNUAttributes(Attr, &DeclEndLoc);
+
     // Parse 'mutable', if it's there.
     SourceLocation MutableLoc;
     if (Tok.is(tok::kw_mutable)) {
       MutableLoc = ConsumeToken();
       DeclEndLoc = MutableLoc;
     }
-    
+
+    // Parse attribute-specifier[opt].
+    MaybeParseCXX11Attributes(Attr, &DeclEndLoc);
+
     // Parse the return type, if there is one.
     TypeResult TrailingReturnType;
     if (Tok.is(tok::arrow)) {
@@ -1033,12 +1140,11 @@
         DeclEndLoc = Range.getEnd();      
     }
 
-    ParsedAttributes Attr(AttrFactory);
     SourceLocation NoLoc;
     D.AddTypeInfo(DeclaratorChunk::getFunction(/*hasProto=*/true,
                                                /*isAmbiguous=*/false,
                                                /*LParenLoc=*/NoLoc,
-                                               /*Params=*/0,
+                                               /*Params=*/nullptr,
                                                /*NumParams=*/0,
                                                /*EllipsisLoc=*/NoLoc,
                                                /*RParenLoc=*/NoLoc,
@@ -1050,10 +1156,10 @@
                                                MutableLoc,
                                                EST_None,
                                                /*ESpecLoc=*/NoLoc,
-                                               /*Exceptions=*/0,
-                                               /*ExceptionRanges=*/0,
+                                               /*Exceptions=*/nullptr,
+                                               /*ExceptionRanges=*/nullptr,
                                                /*NumExceptions=*/0,
-                                               /*NoexceptExpr=*/0,
+                                               /*NoexceptExpr=*/nullptr,
                                                DeclLoc, DeclEndLoc, D,
                                                TrailingReturnType),
                   Attr, DeclEndLoc);
@@ -1078,7 +1184,7 @@
   BodyScope.Exit();
 
   if (!Stmt.isInvalid())
-    return Actions.ActOnLambdaExpr(LambdaBeginLoc, Stmt.take(), getCurScope());
+    return Actions.ActOnLambdaExpr(LambdaBeginLoc, Stmt.get(), getCurScope());
  
   Actions.ActOnLambdaError(LambdaBeginLoc, getCurScope());
   return ExprError();
@@ -1095,7 +1201,7 @@
 ///
 ExprResult Parser::ParseCXXCasts() {
   tok::TokenKind Kind = Tok.getKind();
-  const char *CastName = 0;     // For error messages
+  const char *CastName = nullptr; // For error messages
 
   switch (Kind) {
   default: llvm_unreachable("Unknown C++ cast!");
@@ -1129,8 +1235,8 @@
 
   SourceLocation RAngleBracketLoc = Tok.getLocation();
 
-  if (ExpectAndConsume(tok::greater, diag::err_expected_greater))
-    return ExprError(Diag(LAngleBracketLoc, diag::note_matching) << "<");
+  if (ExpectAndConsume(tok::greater))
+    return ExprError(Diag(LAngleBracketLoc, diag::note_matching) << tok::less);
 
   SourceLocation LParenLoc, RParenLoc;
   BalancedDelimiterTracker T(*this, tok::l_paren);
@@ -1147,7 +1253,7 @@
     Result = Actions.ActOnCXXNamedCast(OpLoc, Kind,
                                        LAngleBracketLoc, DeclaratorInfo,
                                        RAngleBracketLoc,
-                                       T.getOpenLocation(), Result.take(), 
+                                       T.getOpenLocation(), Result.get(), 
                                        T.getCloseLocation());
 
   return Result;
@@ -1213,7 +1319,7 @@
         return ExprError();
 
       Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/false,
-                                      Result.release(), RParenLoc);
+                                      Result.get(), RParenLoc);
     }
   }
 
@@ -1261,7 +1367,7 @@
 
       Result = Actions.ActOnCXXUuidof(OpLoc, T.getOpenLocation(),
                                       /*isType=*/false,
-                                      Result.release(), T.getCloseLocation());
+                                      Result.get(), T.getCloseLocation());
     }
   }
 
@@ -1311,7 +1417,7 @@
     assert(Tok.is(tok::coloncolon) &&"ParseOptionalCXXScopeSpecifier fail");
     CCLoc = ConsumeToken();
   } else {
-    FirstTypeName.setIdentifier(0, SourceLocation());
+    FirstTypeName.setIdentifier(nullptr, SourceLocation());
   }
 
   // Parse the tilde.
@@ -1383,12 +1489,12 @@
   case tok::r_brace:
   case tok::colon:
   case tok::comma:
-    return Actions.ActOnCXXThrow(getCurScope(), ThrowLoc, 0);
+    return Actions.ActOnCXXThrow(getCurScope(), ThrowLoc, nullptr);
 
   default:
     ExprResult Expr(ParseAssignmentExpression());
     if (Expr.isInvalid()) return Expr;
-    return Actions.ActOnCXXThrow(getCurScope(), ThrowLoc, Expr.take());
+    return Actions.ActOnCXXThrow(getCurScope(), ThrowLoc, Expr.get());
   }
 }
 
@@ -1428,7 +1534,7 @@
     ExprResult Init = ParseBraceInitializer();
     if (Init.isInvalid())
       return Init;
-    Expr *InitList = Init.take();
+    Expr *InitList = Init.get();
     return Actions.ActOnCXXTypeConstructExpr(TypeRep, SourceLocation(),
                                              MultiExprArg(&InitList, 1),
                                              SourceLocation());
@@ -1502,7 +1608,7 @@
 
     // Parse the expression.
     ExprOut = ParseExpression(); // expression
-    DeclOut = 0;
+    DeclOut = nullptr;
     if (ExprOut.isInvalid())
       return true;
 
@@ -1530,7 +1636,7 @@
       SkipUntil(tok::semi, StopAtSemi);
       return true;
     }
-    DeclaratorInfo.setAsmLabel(AsmLabel.release());
+    DeclaratorInfo.setAsmLabel(AsmLabel.get());
     DeclaratorInfo.SetRangeEnd(Loc);
   }
 
@@ -1570,7 +1676,7 @@
   }
 
   if (!InitExpr.isInvalid())
-    Actions.AddInitializerToDecl(DeclOut, InitExpr.take(), !CopyInitialization,
+    Actions.AddInitializerToDecl(DeclOut, InitExpr.get(), !CopyInitialization,
                                  DS.containsPlaceholderType());
   else
     Actions.ActOnInitializerError(DeclOut);
@@ -1614,6 +1720,8 @@
   const char *PrevSpec;
   unsigned DiagID;
   SourceLocation Loc = Tok.getLocation();
+  const clang::PrintingPolicy &Policy =
+      Actions.getASTContext().getPrintingPolicy();
 
   switch (Tok.getKind()) {
   case tok::identifier:   // foo::bar
@@ -1626,7 +1734,7 @@
   case tok::annot_typename: {
     if (getTypeAnnotation(Tok))
       DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID,
-                         getTypeAnnotation(Tok));
+                         getTypeAnnotation(Tok), Policy);
     else
       DS.SetTypeSpecError();
     
@@ -1640,19 +1748,19 @@
     if (Tok.is(tok::less) && getLangOpts().ObjC1)
       ParseObjCProtocolQualifiers(DS);
     
-    DS.Finish(Diags, PP);
+    DS.Finish(Diags, PP, Policy);
     return;
   }
 
   // builtin types
   case tok::kw_short:
-    DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec, DiagID);
+    DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec, DiagID, Policy);
     break;
   case tok::kw_long:
-    DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec, DiagID);
+    DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec, DiagID, Policy);
     break;
   case tok::kw___int64:
-    DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec, DiagID);
+    DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec, DiagID, Policy);
     break;
   case tok::kw_signed:
     DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec, DiagID);
@@ -1661,47 +1769,47 @@
     DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec, DiagID);
     break;
   case tok::kw_void:
-    DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec, DiagID);
+    DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec, DiagID, Policy);
     break;
   case tok::kw_char:
-    DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec, DiagID);
+    DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec, DiagID, Policy);
     break;
   case tok::kw_int:
-    DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec, DiagID);
+    DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec, DiagID, Policy);
     break;
   case tok::kw___int128:
-    DS.SetTypeSpecType(DeclSpec::TST_int128, Loc, PrevSpec, DiagID);
+    DS.SetTypeSpecType(DeclSpec::TST_int128, Loc, PrevSpec, DiagID, Policy);
     break;
   case tok::kw_half:
-    DS.SetTypeSpecType(DeclSpec::TST_half, Loc, PrevSpec, DiagID);
+    DS.SetTypeSpecType(DeclSpec::TST_half, Loc, PrevSpec, DiagID, Policy);
     break;
   case tok::kw_float:
-    DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec, DiagID);
+    DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec, DiagID, Policy);
     break;
   case tok::kw_double:
-    DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec, DiagID);
+    DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec, DiagID, Policy);
     break;
   case tok::kw_wchar_t:
-    DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec, DiagID);
+    DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec, DiagID, Policy);
     break;
   case tok::kw_char16_t:
-    DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec, DiagID);
+    DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec, DiagID, Policy);
     break;
   case tok::kw_char32_t:
-    DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec, DiagID);
+    DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec, DiagID, Policy);
     break;
   case tok::kw_bool:
-    DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec, DiagID);
+    DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec, DiagID, Policy);
     break;
   case tok::annot_decltype:
   case tok::kw_decltype:
     DS.SetRangeEnd(ParseDecltypeSpecifier(DS));
-    return DS.Finish(Diags, PP);
+    return DS.Finish(Diags, PP, Policy);
 
   // GNU typeof support.
   case tok::kw_typeof:
     ParseTypeofSpecifier(DS);
-    DS.Finish(Diags, PP);
+    DS.Finish(Diags, PP, Policy);
     return;
   }
   if (Tok.is(tok::annot_typename))
@@ -1709,7 +1817,7 @@
   else
     DS.SetRangeEnd(Tok.getLocation());
   ConsumeToken();
-  DS.Finish(Diags, PP);
+  DS.Finish(Diags, PP, Policy);
 }
 
 /// ParseCXXTypeSpecifierSeq - Parse a C++ type-specifier-seq (C++
@@ -1725,7 +1833,7 @@
 ///
 bool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) {
   ParseSpecifierQualifierList(DS, AS_none, DSC_type_specifier);
-  DS.Finish(Diags, PP);
+  DS.Finish(Diags, PP, Actions.getASTContext().getPrintingPolicy());
   return false;
 }
 
@@ -1882,12 +1990,13 @@
     TemplateIdAnnotation *TemplateId
       = TemplateIdAnnotation::Allocate(TemplateArgs.size(), TemplateIds);
 
+    // FIXME: Store name for literal operator too.
     if (Id.getKind() == UnqualifiedId::IK_Identifier) {
       TemplateId->Name = Id.Identifier;
       TemplateId->Operator = OO_None;
       TemplateId->TemplateNameLoc = Id.StartLocation;
     } else {
-      TemplateId->Name = 0;
+      TemplateId->Name = nullptr;
       TemplateId->Operator = Id.OperatorFunctionId.Operator;
       TemplateId->TemplateNameLoc = Id.StartLocation;
     }
@@ -2086,13 +2195,13 @@
       TokLocs.push_back(ConsumeStringToken());
     }
 
-    StringLiteralParser Literal(Toks.data(), Toks.size(), PP);
+    StringLiteralParser Literal(Toks, PP);
     if (Literal.hadError)
       return true;
 
     // Grab the literal operator's suffix, which will be either the next token
     // or a ud-suffix from the string literal.
-    IdentifierInfo *II = 0;
+    IdentifierInfo *II = nullptr;
     SourceLocation SuffixLoc;
     if (!Literal.getUDSuffix().empty()) {
       II = &PP.getIdentifierTable().get(Literal.getUDSuffix());
@@ -2105,7 +2214,7 @@
       SuffixLoc = ConsumeToken();
       TokLocs.push_back(SuffixLoc);
     } else {
-      Diag(Tok.getLocation(), diag::err_expected_ident);
+      Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
       return true;
     }
 
@@ -2130,9 +2239,10 @@
     }
 
     Result.setLiteralOperatorId(II, KeywordLoc, SuffixLoc);
-    return false;
+
+    return Actions.checkLiteralOperatorId(SS, Result);
   }
-  
+
   // Parse a conversion-function-id.
   //
   //   conversion-function-id: [C++ 12.3.2]
@@ -2152,8 +2262,8 @@
   // Parse the conversion-declarator, which is merely a sequence of
   // ptr-operators.
   Declarator D(DS, Declarator::ConversionIdContext);
-  ParseDeclaratorInternal(D, /*DirectDeclParser=*/0);
-  
+  ParseDeclaratorInternal(D, /*DirectDeclParser=*/nullptr);
+
   // Finish up the type.
   TypeResult Ty = Actions.ActOnTypeName(getCurScope(), D);
   if (Ty.isInvalid())
@@ -2309,10 +2419,10 @@
          Result.getKind() == UnqualifiedId::IK_LiteralOperatorId) &&
         (TemplateSpecified || Tok.is(tok::less)))
       return ParseUnqualifiedIdTemplateId(SS, TemplateKWLoc,
-                                          0, SourceLocation(),
+                                          nullptr, SourceLocation(),
                                           EnteringContext, ObjectType,
                                           Result, TemplateSpecified);
-    
+
     return false;
   }
   
@@ -2507,7 +2617,7 @@
 
   return Actions.ActOnCXXNew(Start, UseGlobal, PlacementLParen,
                              PlacementArgs, PlacementRParen,
-                             TypeIdParens, DeclaratorInfo, Initializer.take());
+                             TypeIdParens, DeclaratorInfo, Initializer.get());
 }
 
 /// ParseDirectNewDeclarator - Parses a direct-new-declarator. Intended to be
@@ -2545,7 +2655,7 @@
 
     D.AddTypeInfo(DeclaratorChunk::getArray(0,
                                             /*static=*/false, /*star=*/false,
-                                            Size.release(),
+                                            Size.get(),
                                             T.getOpenLocation(),
                                             T.getCloseLocation()),
                   Attrs, T.getCloseLocation());
@@ -2622,82 +2732,20 @@
   if (Operand.isInvalid())
     return Operand;
 
-  return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, Operand.take());
-}
-
-static UnaryTypeTrait UnaryTypeTraitFromTokKind(tok::TokenKind kind) {
-  switch(kind) {
-  default: llvm_unreachable("Not a known unary type trait.");
-  case tok::kw___has_nothrow_assign:      return UTT_HasNothrowAssign;
-  case tok::kw___has_nothrow_move_assign: return UTT_HasNothrowMoveAssign;
-  case tok::kw___has_nothrow_constructor: return UTT_HasNothrowConstructor;
-  case tok::kw___has_nothrow_copy:           return UTT_HasNothrowCopy;
-  case tok::kw___has_trivial_assign:      return UTT_HasTrivialAssign;
-  case tok::kw___has_trivial_move_assign: return UTT_HasTrivialMoveAssign;
-  case tok::kw___has_trivial_constructor:
-                                    return UTT_HasTrivialDefaultConstructor;
-  case tok::kw___has_trivial_move_constructor:
-                                    return UTT_HasTrivialMoveConstructor;
-  case tok::kw___has_trivial_copy:           return UTT_HasTrivialCopy;
-  case tok::kw___has_trivial_destructor:  return UTT_HasTrivialDestructor;
-  case tok::kw___has_virtual_destructor:  return UTT_HasVirtualDestructor;
-  case tok::kw___is_abstract:             return UTT_IsAbstract;
-  case tok::kw___is_arithmetic:              return UTT_IsArithmetic;
-  case tok::kw___is_array:                   return UTT_IsArray;
-  case tok::kw___is_class:                return UTT_IsClass;
-  case tok::kw___is_complete_type:           return UTT_IsCompleteType;
-  case tok::kw___is_compound:                return UTT_IsCompound;
-  case tok::kw___is_const:                   return UTT_IsConst;
-  case tok::kw___is_empty:                return UTT_IsEmpty;
-  case tok::kw___is_enum:                 return UTT_IsEnum;
-  case tok::kw___is_final:                 return UTT_IsFinal;
-  case tok::kw___is_floating_point:          return UTT_IsFloatingPoint;
-  case tok::kw___is_function:                return UTT_IsFunction;
-  case tok::kw___is_fundamental:             return UTT_IsFundamental;
-  case tok::kw___is_integral:                return UTT_IsIntegral;
-  case tok::kw___is_interface_class:         return UTT_IsInterfaceClass;
-  case tok::kw___is_lvalue_reference:        return UTT_IsLvalueReference;
-  case tok::kw___is_member_function_pointer: return UTT_IsMemberFunctionPointer;
-  case tok::kw___is_member_object_pointer:   return UTT_IsMemberObjectPointer;
-  case tok::kw___is_member_pointer:          return UTT_IsMemberPointer;
-  case tok::kw___is_object:                  return UTT_IsObject;
-  case tok::kw___is_literal:              return UTT_IsLiteral;
-  case tok::kw___is_literal_type:         return UTT_IsLiteral;
-  case tok::kw___is_pod:                  return UTT_IsPOD;
-  case tok::kw___is_pointer:                 return UTT_IsPointer;
-  case tok::kw___is_polymorphic:          return UTT_IsPolymorphic;
-  case tok::kw___is_reference:               return UTT_IsReference;
-  case tok::kw___is_rvalue_reference:        return UTT_IsRvalueReference;
-  case tok::kw___is_scalar:                  return UTT_IsScalar;
-  case tok::kw___is_sealed:                  return UTT_IsSealed;
-  case tok::kw___is_signed:                  return UTT_IsSigned;
-  case tok::kw___is_standard_layout:         return UTT_IsStandardLayout;
-  case tok::kw___is_trivial:                 return UTT_IsTrivial;
-  case tok::kw___is_trivially_copyable:      return UTT_IsTriviallyCopyable;
-  case tok::kw___is_union:                return UTT_IsUnion;
-  case tok::kw___is_unsigned:                return UTT_IsUnsigned;
-  case tok::kw___is_void:                    return UTT_IsVoid;
-  case tok::kw___is_volatile:                return UTT_IsVolatile;
-  }
-}
-
-static BinaryTypeTrait BinaryTypeTraitFromTokKind(tok::TokenKind kind) {
-  switch(kind) {
-  default: llvm_unreachable("Not a known binary type trait");
-  case tok::kw___is_base_of:                 return BTT_IsBaseOf;
-  case tok::kw___is_convertible:             return BTT_IsConvertible;
-  case tok::kw___is_same:                    return BTT_IsSame;
-  case tok::kw___builtin_types_compatible_p: return BTT_TypeCompatible;
-  case tok::kw___is_convertible_to:          return BTT_IsConvertibleTo;
-  case tok::kw___is_trivially_assignable:    return BTT_IsTriviallyAssignable;
-  }
+  return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, Operand.get());
 }
 
 static TypeTrait TypeTraitFromTokKind(tok::TokenKind kind) {
   switch (kind) {
   default: llvm_unreachable("Not a known type trait");
-  case tok::kw___is_trivially_constructible: 
-    return TT_IsTriviallyConstructible;
+#define TYPE_TRAIT_1(Spelling, Name, Key) \
+case tok::kw_ ## Spelling: return UTT_ ## Name;
+#define TYPE_TRAIT_2(Spelling, Name, Key) \
+case tok::kw_ ## Spelling: return BTT_ ## Name;
+#include "clang/Basic/TokenKinds.def"
+#define TYPE_TRAIT_N(Spelling, Name, Key) \
+  case tok::kw_ ## Spelling: return TT_ ## Name;
+#include "clang/Basic/TokenKinds.def"
   }
 }
 
@@ -2717,87 +2765,33 @@
   }
 }
 
-/// ParseUnaryTypeTrait - Parse the built-in unary type-trait
-/// pseudo-functions that allow implementation of the TR1/C++0x type traits
-/// templates.
-///
-///       primary-expression:
-/// [GNU]             unary-type-trait '(' type-id ')'
-///
-ExprResult Parser::ParseUnaryTypeTrait() {
-  UnaryTypeTrait UTT = UnaryTypeTraitFromTokKind(Tok.getKind());
-  SourceLocation Loc = ConsumeToken();
-
-  BalancedDelimiterTracker T(*this, tok::l_paren);
-  if (T.expectAndConsume(diag::err_expected_lparen))
-    return ExprError();
-
-  // FIXME: Error reporting absolutely sucks! If the this fails to parse a type
-  // there will be cryptic errors about mismatched parentheses and missing
-  // specifiers.
-  TypeResult Ty = ParseTypeName();
-
-  T.consumeClose();
-
-  if (Ty.isInvalid())
-    return ExprError();
-
-  return Actions.ActOnUnaryTypeTrait(UTT, Loc, Ty.get(), T.getCloseLocation());
-}
-
-/// ParseBinaryTypeTrait - Parse the built-in binary type-trait
-/// pseudo-functions that allow implementation of the TR1/C++0x type traits
-/// templates.
-///
-///       primary-expression:
-/// [GNU]             binary-type-trait '(' type-id ',' type-id ')'
-///
-ExprResult Parser::ParseBinaryTypeTrait() {
-  BinaryTypeTrait BTT = BinaryTypeTraitFromTokKind(Tok.getKind());
-  SourceLocation Loc = ConsumeToken();
-
-  BalancedDelimiterTracker T(*this, tok::l_paren);
-  if (T.expectAndConsume(diag::err_expected_lparen))
-    return ExprError();
-
-  TypeResult LhsTy = ParseTypeName();
-  if (LhsTy.isInvalid()) {
-    SkipUntil(tok::r_paren, StopAtSemi);
-    return ExprError();
+static unsigned TypeTraitArity(tok::TokenKind kind) {
+  switch (kind) {
+    default: llvm_unreachable("Not a known type trait");
+#define TYPE_TRAIT(N,Spelling,K) case tok::kw_##Spelling: return N;
+#include "clang/Basic/TokenKinds.def"
   }
-
-  if (ExpectAndConsume(tok::comma, diag::err_expected_comma)) {
-    SkipUntil(tok::r_paren, StopAtSemi);
-    return ExprError();
-  }
-
-  TypeResult RhsTy = ParseTypeName();
-  if (RhsTy.isInvalid()) {
-    SkipUntil(tok::r_paren, StopAtSemi);
-    return ExprError();
-  }
-
-  T.consumeClose();
-
-  return Actions.ActOnBinaryTypeTrait(BTT, Loc, LhsTy.get(), RhsTy.get(),
-                                      T.getCloseLocation());
 }
 
 /// \brief Parse the built-in type-trait pseudo-functions that allow 
 /// implementation of the TR1/C++11 type traits templates.
 ///
 ///       primary-expression:
+///          unary-type-trait '(' type-id ')'
+///          binary-type-trait '(' type-id ',' type-id ')'
 ///          type-trait '(' type-id-seq ')'
 ///
 ///       type-id-seq:
 ///          type-id ...[opt] type-id-seq[opt]
 ///
 ExprResult Parser::ParseTypeTrait() {
-  TypeTrait Kind = TypeTraitFromTokKind(Tok.getKind());
+  tok::TokenKind Kind = Tok.getKind();
+  unsigned Arity = TypeTraitArity(Kind);
+
   SourceLocation Loc = ConsumeToken();
   
   BalancedDelimiterTracker Parens(*this, tok::l_paren);
-  if (Parens.expectAndConsume(diag::err_expected_lparen))
+  if (Parens.expectAndConsume())
     return ExprError();
 
   SmallVector<ParsedType, 2> Args;
@@ -2820,19 +2814,26 @@
     
     // Add this type to the list of arguments.
     Args.push_back(Ty.get());
-    
-    if (Tok.is(tok::comma)) {
-      ConsumeToken();
-      continue;
-    }
-    
-    break;
-  } while (true);
-  
+  } while (TryConsumeToken(tok::comma));
+
   if (Parens.consumeClose())
     return ExprError();
-  
-  return Actions.ActOnTypeTrait(Kind, Loc, Args, Parens.getCloseLocation());
+
+  SourceLocation EndLoc = Parens.getCloseLocation();
+
+  if (Arity && Args.size() != Arity) {
+    Diag(EndLoc, diag::err_type_trait_arity)
+      << Arity << 0 << (Arity > 1) << (int)Args.size() << SourceRange(Loc);
+    return ExprError();
+  }
+
+  if (!Arity && Args.empty()) {
+    Diag(EndLoc, diag::err_type_trait_arity)
+      << 1 << 1 << 1 << (int)Args.size() << SourceRange(Loc);
+    return ExprError();
+  }
+
+  return Actions.ActOnTypeTrait(TypeTraitFromTokKind(Kind), Loc, Args, EndLoc);
 }
 
 /// ParseArrayTypeTrait - Parse the built-in array type-trait
@@ -2847,7 +2848,7 @@
   SourceLocation Loc = ConsumeToken();
 
   BalancedDelimiterTracker T(*this, tok::l_paren);
-  if (T.expectAndConsume(diag::err_expected_lparen))
+  if (T.expectAndConsume())
     return ExprError();
 
   TypeResult Ty = ParseTypeName();
@@ -2860,11 +2861,11 @@
   switch (ATT) {
   case ATT_ArrayRank: {
     T.consumeClose();
-    return Actions.ActOnArrayTypeTrait(ATT, Loc, Ty.get(), NULL,
+    return Actions.ActOnArrayTypeTrait(ATT, Loc, Ty.get(), nullptr,
                                        T.getCloseLocation());
   }
   case ATT_ArrayExtent: {
-    if (ExpectAndConsume(tok::comma, diag::err_expected_comma)) {
+    if (ExpectAndConsume(tok::comma)) {
       SkipUntil(tok::r_paren, StopAtSemi);
       return ExprError();
     }
@@ -2890,7 +2891,7 @@
   SourceLocation Loc = ConsumeToken();
 
   BalancedDelimiterTracker T(*this, tok::l_paren);
-  if (T.expectAndConsume(diag::err_expected_lparen))
+  if (T.expectAndConsume())
     return ExprError();
 
   ExprResult Expr = ParseExpression();
@@ -2908,7 +2909,8 @@
 ExprResult
 Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType,
                                          ParsedType &CastTy,
-                                         BalancedDelimiterTracker &Tracker) {
+                                         BalancedDelimiterTracker &Tracker,
+                                         ColonProtectionRAIIObject &ColonProt) {
   assert(getLangOpts().CPlusPlus && "Should only be called for C++!");
   assert(ExprType == CastExpr && "Compound literals are not ambiguous!");
   assert(isTypeIdInParens() && "Not a type-id!");
@@ -2950,13 +2952,13 @@
     ParseAs = CompoundLiteral;
   } else {
     bool NotCastExpr;
-    // FIXME: Special-case ++ and --: "(S())++;" is not a cast-expression
     if (Tok.is(tok::l_paren) && NextToken().is(tok::r_paren)) {
       NotCastExpr = true;
     } else {
       // Try parsing the cast-expression that may follow.
       // If it is not a cast-expression, NotCastExpr will be true and no token
       // will be consumed.
+      ColonProt.restore();
       Result = ParseCastExpression(false/*isUnaryExpression*/,
                                    false/*isAddressofOperand*/,
                                    NotCastExpr,
@@ -2982,17 +2984,24 @@
   if (ParseAs >= CompoundLiteral) {
     // Parse the type declarator.
     DeclSpec DS(AttrFactory);
-    ParseSpecifierQualifierList(DS);
     Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
-    ParseDeclarator(DeclaratorInfo);
+    {
+      ColonProtectionRAIIObject InnerColonProtection(*this);
+      ParseSpecifierQualifierList(DS);
+      ParseDeclarator(DeclaratorInfo);
+    }
 
     // Match the ')'.
     Tracker.consumeClose();
+    ColonProt.restore();
 
     if (ParseAs == CompoundLiteral) {
       ExprType = CompoundLiteral;
-      TypeResult Ty = ParseTypeName();
-       return ParseCompoundLiteralExpression(Ty.get(),
+      if (DeclaratorInfo.isInvalidType())
+        return ExprError();
+
+      TypeResult Ty = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo);
+      return ParseCompoundLiteralExpression(Ty.get(),
                                             Tracker.getOpenLocation(),
                                             Tracker.getCloseLocation());
     }
@@ -3007,7 +3016,7 @@
     if (!Result.isInvalid())
       Result = Actions.ActOnCastExpr(getCurScope(), Tracker.getOpenLocation(),
                                     DeclaratorInfo, CastTy,
-                                    Tracker.getCloseLocation(), Result.take());
+                                    Tracker.getCloseLocation(), Result.get());
     return Result;
   }
 
@@ -3018,7 +3027,7 @@
   Result = ParseExpression();
   if (!Result.isInvalid() && Tok.is(tok::r_paren))
     Result = Actions.ActOnParenExpr(Tracker.getOpenLocation(), 
-                                    Tok.getLocation(), Result.take());
+                                    Tok.getLocation(), Result.get());
 
   // Match the ')'.
   if (Result.isInvalid()) {
diff --git a/lib/Parse/ParseInit.cpp b/lib/Parse/ParseInit.cpp
index 37f74bb..8536420 100644
--- a/lib/Parse/ParseInit.cpp
+++ b/lib/Parse/ParseInit.cpp
@@ -66,47 +66,29 @@
   }
   
   // Parse up to (at most) the token after the closing ']' to determine 
-  // whether this is a C99 designator or a lambda.
+  // whether this is a C99 designator or a lambda.
   TentativeParsingAction Tentative(*this);
-  ConsumeBracket();
-  while (true) {
-    switch (Tok.getKind()) {
-    case tok::equal:
-    case tok::amp:
-    case tok::identifier:
-    case tok::kw_this:
-      // These tokens can occur in a capture list or a constant-expression.
-      // Keep looking.
-      ConsumeToken();
-      continue;
-      
-    case tok::comma:
-      // Since a comma cannot occur in a constant-expression, this must
-      // be a lambda.
-      Tentative.Revert();
-      return false;
-      
-    case tok::r_square: {
-      // Once we hit the closing square bracket, we look at the next
-      // token. If it's an '=', this is a designator. Otherwise, it's a
-      // lambda expression. This decision favors lambdas over the older
-      // GNU designator syntax, which allows one to omit the '=', but is
-      // consistent with GCC.
-      ConsumeBracket();
-      tok::TokenKind Kind = Tok.getKind();
-      Tentative.Revert();
-      return Kind == tok::equal;
-    }
-      
-    default:
-      // Anything else cannot occur in a lambda capture list, so it
-      // must be a designator.
-      Tentative.Revert();
-      return true;
-    }
+
+  LambdaIntroducer Intro;
+  bool SkippedInits = false;
+  Optional<unsigned> DiagID(ParseLambdaIntroducer(Intro, &SkippedInits));
+
+  if (DiagID) {
+    // If this can't be a lambda capture list, it's a designator.
+    Tentative.Revert();
+    return true;
   }
-  
-  return true;
+
+  // Once we hit the closing square bracket, we look at the next
+  // token. If it's an '=', this is a designator. Otherwise, it's a
+  // lambda expression. This decision favors lambdas over the older
+  // GNU designator syntax, which allows one to omit the '=', but is
+  // consistent with GCC.
+  tok::TokenKind Kind = Tok.getKind();
+  // FIXME: If we didn't skip any inits, parse the lambda from here
+  // rather than throwing away then reparsing the LambdaIntroducer.
+  Tentative.Revert();
+  return Kind == tok::equal;
 }
 
 static void CheckArrayDesignatorSyntax(Parser &P, SourceLocation Loc,
@@ -237,7 +219,7 @@
         return ParseAssignmentExprWithObjCMessageExprStart(StartLoc,
                                                            ConsumeToken(),
                                                            ParsedType(), 
-                                                           0);
+                                                           nullptr);
       }
 
       // Parse the receiver, which is either a type or an expression.
@@ -255,7 +237,7 @@
         return ParseAssignmentExprWithObjCMessageExprStart(StartLoc, 
                                                            SourceLocation(), 
                                    ParsedType::getFromOpaquePtr(TypeOrExpr),
-                                                           0);
+                                                           nullptr);
       }
 
       // If the receiver was an expression, we still don't know
@@ -282,7 +264,7 @@
           return ParseAssignmentExprWithObjCMessageExprStart(StartLoc,
                                                              ConsumeToken(),
                                                              ParsedType(),
-                                                             0);
+                                                             nullptr);
         ConsumeToken(); // the identifier
         if (!ReceiverType) {
           SkipUntil(tok::r_square, StopAtSemi);
@@ -292,7 +274,7 @@
         return ParseAssignmentExprWithObjCMessageExprStart(StartLoc, 
                                                            SourceLocation(), 
                                                            ReceiverType, 
-                                                           0);
+                                                           nullptr);
 
       case Sema::ObjCInstanceMessage:
         // Fall through; we'll just parse the expression and
@@ -327,12 +309,12 @@
       return ParseAssignmentExprWithObjCMessageExprStart(StartLoc,
                                                          SourceLocation(),
                                                          ParsedType(),
-                                                         Idx.take());
+                                                         Idx.get());
     }
 
     // If this is a normal array designator, remember it.
     if (Tok.isNot(tok::ellipsis)) {
-      Desig.AddDesignator(Designator::getArray(Idx.release(), StartLoc));
+      Desig.AddDesignator(Designator::getArray(Idx.get(), StartLoc));
     } else {
       // Handle the gnu array range extension.
       Diag(Tok, diag::ext_gnu_array_range);
@@ -343,8 +325,8 @@
         SkipUntil(tok::r_square, StopAtSemi);
         return RHS;
       }
-      Desig.AddDesignator(Designator::getArrayRange(Idx.release(),
-                                                    RHS.release(),
+      Desig.AddDesignator(Designator::getArrayRange(Idx.get(),
+                                                    RHS.get(),
                                                     StartLoc, EllipsisLoc));
     }
 
@@ -444,7 +426,7 @@
     
     // If we couldn't parse the subelement, bail out.
     if (!SubElt.isInvalid()) {
-      InitExprs.push_back(SubElt.release());
+      InitExprs.push_back(SubElt.get());
     } else {
       InitExprsOk = false;
 
@@ -493,7 +475,7 @@
   
   BalancedDelimiterTracker Braces(*this, tok::l_brace);
   if (Braces.consumeOpen()) {
-    Diag(Tok, diag::err_expected_lbrace);
+    Diag(Tok, diag::err_expected) << tok::l_brace;
     return false;
   }
 
@@ -512,7 +494,7 @@
     return false;
   }
 
-  while (Tok.isNot(tok::eof)) {
+  while (!isEofOrEom()) {
     trailingComma = false;
     // If we know that this cannot be a designation, just parse the nested
     // initializer directly.
@@ -527,7 +509,7 @@
     
     // If we couldn't parse the subelement, bail out.
     if (!SubElt.isInvalid())
-      InitExprs.push_back(SubElt.release());
+      InitExprs.push_back(SubElt.get());
     else
       InitExprsOk = false;
 
diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp
index 86f38cf..7fe72ec 100644
--- a/lib/Parse/ParseObjc.cpp
+++ b/lib/Parse/ParseObjc.cpp
@@ -51,8 +51,8 @@
     cutOffParsing();
     return DeclGroupPtrTy();
   }
-    
-  Decl *SingleDecl = 0;
+
+  Decl *SingleDecl = nullptr;
   switch (Tok.getObjCKeywordID()) {
   case tok::objc_class:
     return ParseObjCAtClassDeclaration(AtLoc);
@@ -81,13 +81,13 @@
   case tok::objc_import:
     if (getLangOpts().Modules)
       return ParseModuleImport(AtLoc);
-      
-    // Fall through
-      
+    Diag(AtLoc, diag::err_atimport);
+    SkipUntil(tok::semi);
+    return Actions.ConvertDeclToDeclGroup(nullptr);
   default:
     Diag(AtLoc, diag::err_unexpected_at);
     SkipUntil(tok::semi);
-    SingleDecl = 0;
+    SingleDecl = nullptr;
     break;
   }
   return Actions.ConvertDeclToDeclGroup(SingleDecl);
@@ -107,23 +107,21 @@
   while (1) {
     MaybeSkipAttributes(tok::objc_class);
     if (Tok.isNot(tok::identifier)) {
-      Diag(Tok, diag::err_expected_ident);
+      Diag(Tok, diag::err_expected) << tok::identifier;
       SkipUntil(tok::semi);
-      return Actions.ConvertDeclToDeclGroup(0);
+      return Actions.ConvertDeclToDeclGroup(nullptr);
     }
     ClassNames.push_back(Tok.getIdentifierInfo());
     ClassLocs.push_back(Tok.getLocation());
     ConsumeToken();
 
-    if (Tok.isNot(tok::comma))
+    if (!TryConsumeToken(tok::comma))
       break;
-
-    ConsumeToken();
   }
 
   // Consume the ';'.
-  if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@class"))
-    return Actions.ConvertDeclToDeclGroup(0);
+  if (ExpectAndConsume(tok::semi, diag::err_expected_after, "@class"))
+    return Actions.ConvertDeclToDeclGroup(nullptr);
 
   return Actions.ActOnForwardClassDeclaration(atLoc, ClassNames.data(),
                                               ClassLocs.data(),
@@ -189,14 +187,15 @@
   if (Tok.is(tok::code_completion)) {
     Actions.CodeCompleteObjCInterfaceDecl(getCurScope());
     cutOffParsing();
-    return 0;
+    return nullptr;
   }
 
   MaybeSkipAttributes(tok::objc_interface);
 
   if (Tok.isNot(tok::identifier)) {
-    Diag(Tok, diag::err_expected_ident); // missing class or category name.
-    return 0;
+    Diag(Tok, diag::err_expected)
+        << tok::identifier; // missing class or category name.
+    return nullptr;
   }
 
   // We have a class or category name - consume it.
@@ -209,11 +208,11 @@
     T.consumeOpen();
 
     SourceLocation categoryLoc;
-    IdentifierInfo *categoryId = 0;
+    IdentifierInfo *categoryId = nullptr;
     if (Tok.is(tok::code_completion)) {
       Actions.CodeCompleteObjCInterfaceCategory(getCurScope(), nameId, nameLoc);
       cutOffParsing();
-      return 0;
+      return nullptr;
     }
     
     // For ObjC2, the category name is optional (not an error).
@@ -222,14 +221,15 @@
       categoryLoc = ConsumeToken();
     }
     else if (!getLangOpts().ObjC2) {
-      Diag(Tok, diag::err_expected_ident); // missing category name.
-      return 0;
+      Diag(Tok, diag::err_expected)
+          << tok::identifier; // missing category name.
+      return nullptr;
     }
    
     T.consumeClose();
     if (T.getCloseLocation().isInvalid())
-      return 0;
-    
+      return nullptr;
+
     if (!attrs.empty()) { // categories don't support attributes.
       Diag(nameLoc, diag::err_objc_no_attributes_on_category);
       attrs.clear();
@@ -242,7 +242,7 @@
     if (Tok.is(tok::less) &&
         ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, true,
                                     LAngleLoc, EndProtoLoc))
-      return 0;
+      return nullptr;
 
     Decl *CategoryType =
     Actions.ActOnStartCategoryInterface(AtLoc,
@@ -260,7 +260,7 @@
     return CategoryType;
   }
   // Parse a class interface.
-  IdentifierInfo *superClassId = 0;
+  IdentifierInfo *superClassId = nullptr;
   SourceLocation superClassLoc;
 
   if (Tok.is(tok::colon)) { // a super class is specified.
@@ -270,12 +270,13 @@
     if (Tok.is(tok::code_completion)) {
       Actions.CodeCompleteObjCSuperclass(getCurScope(), nameId, nameLoc);
       cutOffParsing();
-      return 0;
+      return nullptr;
     }
 
     if (Tok.isNot(tok::identifier)) {
-      Diag(Tok, diag::err_expected_ident); // missing super class name.
-      return 0;
+      Diag(Tok, diag::err_expected)
+          << tok::identifier; // missing super class name.
+      return nullptr;
     }
     superClassId = Tok.getIdentifierInfo();
     superClassLoc = ConsumeToken();
@@ -287,7 +288,7 @@
   if (Tok.is(tok::less) &&
       ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, true,
                                   LAngleLoc, EndProtoLoc))
-    return 0;
+    return nullptr;
 
   if (Tok.isNot(tok::less))
     Actions.ActOnTypedefedProtocols(ProtocolRefs, superClassId, superClassLoc);
@@ -328,8 +329,8 @@
     MethodImplKind(MethodImplKind) {
   }
 
-  void invoke(ParsingFieldDeclarator &FD) {
-    if (FD.D.getIdentifier() == 0) {
+  void invoke(ParsingFieldDeclarator &FD) override {
+    if (FD.D.getIdentifier() == nullptr) {
       P.Diag(AtLoc, diag::err_objc_property_requires_field_name)
         << FD.D.getSourceRange();
       return;
@@ -423,7 +424,7 @@
     }
 
     // If we got to the end of the file, exit the loop.
-    if (Tok.is(tok::eof))
+    if (isEofOrEom())
       break;
 
     // Code completion within an Objective-C interface.
@@ -576,7 +577,7 @@
     const IdentifierInfo *II = Tok.getIdentifierInfo();
 
     // If this is not an identifier at all, bail out early.
-    if (II == 0) {
+    if (!II) {
       T.consumeClose();
       return;
     }
@@ -610,8 +611,10 @@
       unsigned DiagID = IsSetter ? diag::err_objc_expected_equal_for_setter :
         diag::err_objc_expected_equal_for_getter;
 
-      if (ExpectAndConsume(tok::equal, DiagID, "", tok::r_paren))
+      if (ExpectAndConsume(tok::equal, DiagID)) {
+        SkipUntil(tok::r_paren, StopAtSemi);
         return;
+      }
 
       if (Tok.is(tok::code_completion)) {
         if (IsSetter)
@@ -636,10 +639,11 @@
         DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_setter);
         DS.setSetterName(SelIdent);
 
-        if (ExpectAndConsume(tok::colon, 
-                             diag::err_expected_colon_after_setter_name, "",
-                             tok::r_paren))
+        if (ExpectAndConsume(tok::colon,
+                             diag::err_expected_colon_after_setter_name)) {
+          SkipUntil(tok::r_paren, StopAtSemi);
           return;
+        }
       } else {
         DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_getter);
         DS.setGetterName(SelIdent);
@@ -694,7 +698,7 @@
 
   switch (Tok.getKind()) {
   default:
-    return 0;
+    return nullptr;
   case tok::ampamp:
   case tok::ampequal:
   case tok::amp:
@@ -713,7 +717,7 @@
       SelectorLoc = ConsumeToken();
       return II;
     }
-    return 0; 
+    return nullptr;
   }
       
   case tok::identifier:
@@ -841,7 +845,7 @@
       }
       DS.setObjCDeclQualifier(Qual);
       ConsumeToken();
-      II = 0;
+      II = nullptr;
       break;
     }
 
@@ -862,7 +866,7 @@
       // Clear out the next pointer.  We're really completely
       // destroying the internal invariants of the declarator here,
       // but it doesn't matter because we're done with it.
-      cur->setNext(0);
+      cur->setNext(nullptr);
       attrs.add(cur);
     }
   }
@@ -893,7 +897,8 @@
                                      ParsedAttributes *paramAttrs) {
   assert(context == Declarator::ObjCParameterContext ||
          context == Declarator::ObjCResultContext);
-  assert((paramAttrs != 0) == (context == Declarator::ObjCParameterContext));
+  assert((paramAttrs != nullptr) ==
+         (context == Declarator::ObjCParameterContext));
 
   assert(Tok.is(tok::l_paren) && "expected (");
 
@@ -990,14 +995,15 @@
     Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus, 
                                        /*ReturnType=*/ ParsedType());
     cutOffParsing();
-    return 0;
+    return nullptr;
   }
 
   // Parse the return type if present.
   ParsedType ReturnType;
   ObjCDeclSpec DSRet;
   if (Tok.is(tok::l_paren))
-    ReturnType = ParseObjCTypeName(DSRet, Declarator::ObjCResultContext, 0);
+    ReturnType = ParseObjCTypeName(DSRet, Declarator::ObjCResultContext,
+                                   nullptr);
 
   // If attributes exist before the method, parse them.
   ParsedAttributes methodAttrs(AttrFactory);
@@ -1008,7 +1014,7 @@
     Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus, 
                                        ReturnType);
     cutOffParsing();
-    return 0;
+    return nullptr;
   }
 
   // Now parse the selector.
@@ -1021,7 +1027,7 @@
       << SourceRange(mLoc, Tok.getLocation());
     // Skip until we get a ; or @.
     SkipUntil(tok::at, StopAtSemi | StopBeforeMatch);
-    return 0;
+    return nullptr;
   }
 
   SmallVector<DeclaratorChunk::ParamInfo, 8> CParamInfo;
@@ -1034,7 +1040,7 @@
     Decl *Result
          = Actions.ActOnMethodDeclaration(getCurScope(), mLoc, Tok.getLocation(),
                                           mType, DSRet, ReturnType, 
-                                          selLoc, Sel, 0, 
+                                          selLoc, Sel, nullptr,
                                           CParamInfo.data(), CParamInfo.size(),
                                           methodAttrs.getList(), MethodImplKind,
                                           false, MethodDefinition);
@@ -1054,11 +1060,8 @@
     Sema::ObjCArgInfo ArgInfo;
 
     // Each iteration parses a single keyword argument.
-    if (Tok.isNot(tok::colon)) {
-      Diag(Tok, diag::err_expected_colon);
+    if (ExpectAndConsume(tok::colon))
       break;
-    }
-    ConsumeToken(); // Eat the ':'.
 
     ArgInfo.Type = ParsedType();
     if (Tok.is(tok::l_paren)) // Parse the argument type if present.
@@ -1068,7 +1071,7 @@
 
     // If attributes exist before the argument name, parse them.
     // Regardless, collect all the attributes we've parsed so far.
-    ArgInfo.ArgAttrs = 0;
+    ArgInfo.ArgAttrs = nullptr;
     if (getLangOpts().ObjC2) {
       MaybeParseGNUAttributes(paramAttrs);
       ArgInfo.ArgAttrs = paramAttrs.getList();
@@ -1082,11 +1085,12 @@
                                                  /*AtParameterName=*/true,
                                                  ReturnType, KeyIdents);
       cutOffParsing();
-      return 0;
+      return nullptr;
     }
     
     if (Tok.isNot(tok::identifier)) {
-      Diag(Tok, diag::err_expected_ident); // missing argument name.
+      Diag(Tok, diag::err_expected)
+          << tok::identifier; // missing argument name.
       break;
     }
 
@@ -1108,7 +1112,7 @@
                                                  /*AtParameterName=*/false,
                                                  ReturnType, KeyIdents);
       cutOffParsing();
-      return 0;
+      return nullptr;
     }
     
     // Check for another keyword selector.
@@ -1150,7 +1154,7 @@
     CParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
                                                     ParmDecl.getIdentifierLoc(), 
                                                     Param,
-                                                   0));
+                                                    nullptr));
   }
 
   // FIXME: Add support for optional parameter list...
@@ -1159,8 +1163,8 @@
     MaybeParseGNUAttributes(methodAttrs);
   
   if (KeyIdents.size() == 0)
-    return 0;
-  
+    return nullptr;
+
   Selector Sel = PP.getSelectorTable().getSelector(KeyIdents.size(),
                                                    &KeyIdents[0]);
   Decl *Result
@@ -1198,7 +1202,7 @@
     }
 
     if (Tok.isNot(tok::identifier)) {
-      Diag(Tok, diag::err_expected_ident);
+      Diag(Tok, diag::err_expected) << tok::identifier;
       SkipUntil(tok::greater, StopAtSemi);
       return true;
     }
@@ -1207,9 +1211,8 @@
     ProtocolLocs.push_back(Tok.getLocation());
     ConsumeToken();
 
-    if (Tok.isNot(tok::comma))
+    if (!TryConsumeToken(tok::comma))
       break;
-    ConsumeToken();
   }
 
   // Consume the '>'.
@@ -1254,7 +1257,7 @@
   // for code rewriting tools that need to be aware of the empty list.
   Actions.ActOnFields(getCurScope(), atLoc, interfaceDecl,
                       AllIvarDecls,
-                      T.getOpenLocation(), T.getCloseLocation(), 0);
+                      T.getOpenLocation(), T.getCloseLocation(), nullptr);
 }
 
 ///   objc-class-instance-variables:
@@ -1289,7 +1292,7 @@
   BalancedDelimiterTracker T(*this, tok::l_brace);
   T.consumeOpen();
   // While we still have something to read, read the instance variables.
-  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
+  while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
     // Each iteration of this loop reads one objc-instance-variable-decl.
 
     // Check for extraneous top-level semicolon.
@@ -1299,9 +1302,7 @@
     }
 
     // Set the default visibility to private.
-    if (Tok.is(tok::at)) { // parse objc-visibility-spec
-      ConsumeToken(); // eat the @ sign
-      
+    if (TryConsumeToken(tok::at)) { // parse objc-visibility-spec
       if (Tok.is(tok::code_completion)) {
         Actions.CodeCompleteObjCAtVisibility(getCurScope());
         return cutOffParsing();
@@ -1349,7 +1350,7 @@
         P(P), IDecl(IDecl), visibility(V), AllIvarDecls(AllIvarDecls) {
       }
 
-      void invoke(ParsingFieldDeclarator &FD) {
+      void invoke(ParsingFieldDeclarator &FD) override {
         P.Actions.ActOnObjCContainerStartDefinition(IDecl);
         // Install the declarator into the interface decl.
         Decl *Field
@@ -1412,16 +1413,15 @@
   MaybeSkipAttributes(tok::objc_protocol);
 
   if (Tok.isNot(tok::identifier)) {
-    Diag(Tok, diag::err_expected_ident); // missing protocol name.
+    Diag(Tok, diag::err_expected) << tok::identifier; // missing protocol name.
     return DeclGroupPtrTy();
   }
   // Save the protocol name, then consume it.
   IdentifierInfo *protocolName = Tok.getIdentifierInfo();
   SourceLocation nameLoc = ConsumeToken();
 
-  if (Tok.is(tok::semi)) { // forward declaration of one protocol.
+  if (TryConsumeToken(tok::semi)) { // forward declaration of one protocol.
     IdentifierLocPair ProtoInfo(protocolName, nameLoc);
-    ConsumeToken();
     return Actions.ActOnForwardProtocolDeclaration(AtLoc, &ProtoInfo, 1,
                                                    attrs.getList());
   }
@@ -1436,7 +1436,7 @@
     while (1) {
       ConsumeToken(); // the ','
       if (Tok.isNot(tok::identifier)) {
-        Diag(Tok, diag::err_expected_ident);
+        Diag(Tok, diag::err_expected) << tok::identifier;
         SkipUntil(tok::semi);
         return DeclGroupPtrTy();
       }
@@ -1448,7 +1448,7 @@
         break;
     }
     // Consume the ';'.
-    if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@protocol"))
+    if (ExpectAndConsume(tok::semi, diag::err_expected_after, "@protocol"))
       return DeclGroupPtrTy();
 
     return Actions.ActOnForwardProtocolDeclaration(AtLoc,
@@ -1505,19 +1505,20 @@
   MaybeSkipAttributes(tok::objc_implementation);
 
   if (Tok.isNot(tok::identifier)) {
-    Diag(Tok, diag::err_expected_ident); // missing class or category name.
+    Diag(Tok, diag::err_expected)
+        << tok::identifier; // missing class or category name.
     return DeclGroupPtrTy();
   }
   // We have a class or category name - consume it.
   IdentifierInfo *nameId = Tok.getIdentifierInfo();
   SourceLocation nameLoc = ConsumeToken(); // consume class or category name
-  Decl *ObjCImpDecl = 0;
+  Decl *ObjCImpDecl = nullptr;
 
   if (Tok.is(tok::l_paren)) {
     // we have a category implementation.
     ConsumeParen();
     SourceLocation categoryLoc, rparenLoc;
-    IdentifierInfo *categoryId = 0;
+    IdentifierInfo *categoryId = nullptr;
 
     if (Tok.is(tok::code_completion)) {
       Actions.CodeCompleteObjCImplementationCategory(getCurScope(), nameId, nameLoc);
@@ -1529,11 +1530,12 @@
       categoryId = Tok.getIdentifierInfo();
       categoryLoc = ConsumeToken();
     } else {
-      Diag(Tok, diag::err_expected_ident); // missing category name.
+      Diag(Tok, diag::err_expected)
+          << tok::identifier; // missing category name.
       return DeclGroupPtrTy();
     }
     if (Tok.isNot(tok::r_paren)) {
-      Diag(Tok, diag::err_expected_rparen);
+      Diag(Tok, diag::err_expected) << tok::r_paren;
       SkipUntil(tok::r_paren); // don't stop at ';'
       return DeclGroupPtrTy();
     }
@@ -1551,12 +1553,12 @@
   } else {
     // We have a class implementation
     SourceLocation superClassLoc;
-    IdentifierInfo *superClassId = 0;
-    if (Tok.is(tok::colon)) {
+    IdentifierInfo *superClassId = nullptr;
+    if (TryConsumeToken(tok::colon)) {
       // We have a super class
-      ConsumeToken();
       if (Tok.isNot(tok::identifier)) {
-        Diag(Tok, diag::err_expected_ident); // missing super class name.
+        Diag(Tok, diag::err_expected)
+            << tok::identifier; // missing super class name.
         return DeclGroupPtrTy();
       }
       superClassId = Tok.getIdentifierInfo();
@@ -1582,7 +1584,7 @@
 
   {
     ObjCImplParsingDataRAII ObjCImplParsing(*this, ObjCImpDecl);
-    while (!ObjCImplParsing.isFinished() && Tok.isNot(tok::eof)) {
+    while (!ObjCImplParsing.isFinished() && !isEofOrEom()) {
       ParsedAttributesWithRange attrs(AttrFactory);
       MaybeParseCXX11Attributes(attrs);
       MaybeParseMicrosoftAttributes(attrs);
@@ -1612,14 +1614,14 @@
 Parser::ObjCImplParsingDataRAII::~ObjCImplParsingDataRAII() {
   if (!Finished) {
     finish(P.Tok.getLocation());
-    if (P.Tok.is(tok::eof)) {
+    if (P.isEofOrEom()) {
       P.Diag(P.Tok, diag::err_objc_missing_end)
           << FixItHint::CreateInsertion(P.Tok.getLocation(), "\n@end\n");
       P.Diag(Dcl->getLocStart(), diag::note_objc_container_start)
           << Sema::OCK_Implementation;
     }
   }
-  P.CurParsedObjCImpl = 0;
+  P.CurParsedObjCImpl = nullptr;
   assert(LateParsedObjCMethods.empty());
 }
 
@@ -1655,19 +1657,18 @@
          "ParseObjCAtAliasDeclaration(): Expected @compatibility_alias");
   ConsumeToken(); // consume compatibility_alias
   if (Tok.isNot(tok::identifier)) {
-    Diag(Tok, diag::err_expected_ident);
-    return 0;
+    Diag(Tok, diag::err_expected) << tok::identifier;
+    return nullptr;
   }
   IdentifierInfo *aliasId = Tok.getIdentifierInfo();
   SourceLocation aliasLoc = ConsumeToken(); // consume alias-name
   if (Tok.isNot(tok::identifier)) {
-    Diag(Tok, diag::err_expected_ident);
-    return 0;
+    Diag(Tok, diag::err_expected) << tok::identifier;
+    return nullptr;
   }
   IdentifierInfo *classId = Tok.getIdentifierInfo();
   SourceLocation classLoc = ConsumeToken(); // consume class-name;
-  ExpectAndConsume(tok::semi, diag::err_expected_semi_after, 
-                   "@compatibility_alias");
+  ExpectAndConsume(tok::semi, diag::err_expected_after, "@compatibility_alias");
   return Actions.ActOnCompatibilityAlias(atLoc, aliasId, aliasLoc,
                                          classId, classLoc);
 }
@@ -1692,31 +1693,29 @@
     if (Tok.is(tok::code_completion)) {
       Actions.CodeCompleteObjCPropertyDefinition(getCurScope());
       cutOffParsing();
-      return 0;
+      return nullptr;
     }
     
     if (Tok.isNot(tok::identifier)) {
       Diag(Tok, diag::err_synthesized_property_name);
       SkipUntil(tok::semi);
-      return 0;
+      return nullptr;
     }
-    
-    IdentifierInfo *propertyIvar = 0;
+
+    IdentifierInfo *propertyIvar = nullptr;
     IdentifierInfo *propertyId = Tok.getIdentifierInfo();
     SourceLocation propertyLoc = ConsumeToken(); // consume property name
     SourceLocation propertyIvarLoc;
-    if (Tok.is(tok::equal)) {
+    if (TryConsumeToken(tok::equal)) {
       // property '=' ivar-name
-      ConsumeToken(); // consume '='
-      
       if (Tok.is(tok::code_completion)) {
         Actions.CodeCompleteObjCPropertySynthesizeIvar(getCurScope(), propertyId);
         cutOffParsing();
-        return 0;
+        return nullptr;
       }
       
       if (Tok.isNot(tok::identifier)) {
-        Diag(Tok, diag::err_expected_ident);
+        Diag(Tok, diag::err_expected) << tok::identifier;
         break;
       }
       propertyIvar = Tok.getIdentifierInfo();
@@ -1728,8 +1727,8 @@
       break;
     ConsumeToken(); // consume ','
   }
-  ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@synthesize");
-  return 0;
+  ExpectAndConsume(tok::semi, diag::err_expected_after, "@synthesize");
+  return nullptr;
 }
 
 ///   property-dynamic:
@@ -1747,26 +1746,26 @@
     if (Tok.is(tok::code_completion)) {
       Actions.CodeCompleteObjCPropertyDefinition(getCurScope());
       cutOffParsing();
-      return 0;
+      return nullptr;
     }
     
     if (Tok.isNot(tok::identifier)) {
-      Diag(Tok, diag::err_expected_ident);
+      Diag(Tok, diag::err_expected) << tok::identifier;
       SkipUntil(tok::semi);
-      return 0;
+      return nullptr;
     }
     
     IdentifierInfo *propertyId = Tok.getIdentifierInfo();
     SourceLocation propertyLoc = ConsumeToken(); // consume property name
     Actions.ActOnPropertyImplDecl(getCurScope(), atLoc, propertyLoc, false,
-                                  propertyId, 0, SourceLocation());
+                                  propertyId, nullptr, SourceLocation());
 
     if (Tok.isNot(tok::comma))
       break;
     ConsumeToken(); // consume ','
   }
-  ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@dynamic");
-  return 0;
+  ExpectAndConsume(tok::semi, diag::err_expected_after, "@dynamic");
+  return nullptr;
 }
 
 ///  objc-throw-statement:
@@ -1783,8 +1782,8 @@
     }
   }
   // consume ';'
-  ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@throw");
-  return Actions.ActOnObjCAtThrowStmt(atLoc, Res.take(), getCurScope());
+  ExpectAndConsume(tok::semi, diag::err_expected_after, "@throw");
+  return Actions.ActOnObjCAtThrowStmt(atLoc, Res.get(), getCurScope());
 }
 
 /// objc-synchronized-statement:
@@ -1806,7 +1805,7 @@
     ConsumeParen();  // ')'
   } else {
     if (!operand.isInvalid())
-      Diag(Tok, diag::err_expected_rparen);
+      Diag(Tok, diag::err_expected) << tok::r_paren;
 
     // Skip forward until we see a left brace, but don't consume it.
     SkipUntil(tok::l_brace, StopAtSemi | StopBeforeMatch);
@@ -1815,13 +1814,13 @@
   // Require a compound statement.
   if (Tok.isNot(tok::l_brace)) {
     if (!operand.isInvalid())
-      Diag(Tok, diag::err_expected_lbrace);
+      Diag(Tok, diag::err_expected) << tok::l_brace;
     return StmtError();
   }
 
   // Check the @synchronized operand now.
   if (!operand.isInvalid())
-    operand = Actions.ActOnObjCAtSynchronizedOperand(atLoc, operand.take());
+    operand = Actions.ActOnObjCAtSynchronizedOperand(atLoc, operand.get());
 
   // Parse the compound statement within a new scope.
   ParseScope bodyScope(this, Scope::DeclScope);
@@ -1855,7 +1854,7 @@
 
   ConsumeToken(); // consume try
   if (Tok.isNot(tok::l_brace)) {
-    Diag(Tok, diag::err_expected_lbrace);
+    Diag(Tok, diag::err_expected) << tok::l_brace;
     return StmtError();
   }
   StmtVector CatchStmts;
@@ -1877,7 +1876,7 @@
 
     SourceLocation AtCatchFinallyLoc = ConsumeToken();
     if (Tok.isObjCAtKeyword(tok::objc_catch)) {
-      Decl *FirstPart = 0;
+      Decl *FirstPart = nullptr;
       ConsumeToken(); // consume catch
       if (Tok.is(tok::l_paren)) {
         ConsumeParen();
@@ -1905,16 +1904,16 @@
         if (Tok.is(tok::l_brace))
           CatchBody = ParseCompoundStatementBody();
         else
-          Diag(Tok, diag::err_expected_lbrace);
+          Diag(Tok, diag::err_expected) << tok::l_brace;
         if (CatchBody.isInvalid())
           CatchBody = Actions.ActOnNullStmt(Tok.getLocation());
         
         StmtResult Catch = Actions.ActOnObjCAtCatchStmt(AtCatchFinallyLoc,
                                                               RParenLoc, 
                                                               FirstPart, 
-                                                              CatchBody.take());
+                                                              CatchBody.get());
         if (!Catch.isInvalid())
-          CatchStmts.push_back(Catch.release());
+          CatchStmts.push_back(Catch.get());
         
       } else {
         Diag(AtCatchFinallyLoc, diag::err_expected_lparen_after)
@@ -1931,11 +1930,11 @@
       if (Tok.is(tok::l_brace))
         FinallyBody = ParseCompoundStatementBody();
       else
-        Diag(Tok, diag::err_expected_lbrace);
+        Diag(Tok, diag::err_expected) << tok::l_brace;
       if (FinallyBody.isInvalid())
         FinallyBody = Actions.ActOnNullStmt(Tok.getLocation());
       FinallyStmt = Actions.ActOnObjCAtFinallyStmt(AtCatchFinallyLoc,
-                                                   FinallyBody.take());
+                                                   FinallyBody.get());
       catch_or_finally_seen = true;
       break;
     }
@@ -1945,9 +1944,9 @@
     return StmtError();
   }
   
-  return Actions.ActOnObjCAtTryStmt(atLoc, TryBody.take(), 
+  return Actions.ActOnObjCAtTryStmt(atLoc, TryBody.get(), 
                                     CatchStmts,
-                                    FinallyStmt.take());
+                                    FinallyStmt.get());
 }
 
 /// objc-autoreleasepool-statement:
@@ -1957,7 +1956,7 @@
 Parser::ParseObjCAutoreleasePoolStmt(SourceLocation atLoc) {
   ConsumeToken(); // consume autoreleasepool
   if (Tok.isNot(tok::l_brace)) {
-    Diag(Tok, diag::err_expected_lbrace);
+    Diag(Tok, diag::err_expected) << tok::l_brace;
     return StmtError();
   }
   // Enter a scope to hold everything within the compound stmt.  Compound
@@ -1970,7 +1969,7 @@
   if (AutoreleasePoolBody.isInvalid())
     AutoreleasePoolBody = Actions.ActOnNullStmt(Tok.getLocation());
   return Actions.ActOnObjCAutoreleasePoolStmt(atLoc, 
-                                                AutoreleasePoolBody.take());
+                                                AutoreleasePoolBody.get());
 }
 
 /// StashAwayMethodOrFunctionBodyTokens -  Consume the tokens and store them 
@@ -2036,13 +2035,13 @@
 
     // If we didn't find the '{', bail out.
     if (Tok.isNot(tok::l_brace))
-      return 0;
+      return nullptr;
   }
 
   if (!MDecl) {
     ConsumeBrace();
     SkipUntil(tok::r_brace);
-    return 0;
+    return nullptr;
   }
 
   // Allow the rest of sema to find private method decl implementations.
@@ -2100,7 +2099,7 @@
     SourceLocation OpLoc = ConsumeToken();
 
     if (!Tok.is(tok::numeric_constant)) {
-      const char *Symbol = 0;
+      const char *Symbol = nullptr;
       switch (Kind) {
       case tok::minus: Symbol = "-"; break;
       case tok::plus: Symbol = "+"; break;
@@ -2117,12 +2116,12 @@
     }
     ConsumeToken(); // Consume the literal token.
 
-    Lit = Actions.ActOnUnaryOp(getCurScope(), OpLoc, Kind, Lit.take());
+    Lit = Actions.ActOnUnaryOp(getCurScope(), OpLoc, Kind, Lit.get());
     if (Lit.isInvalid())
       return Lit;
 
     return ParsePostfixExpressionSuffix(
-             Actions.BuildObjCNumericLiteral(AtLoc, Lit.take()));
+             Actions.BuildObjCNumericLiteral(AtLoc, Lit.get()));
   }
 
   case tok::string_literal:    // primary-expression: string-literal
@@ -2155,7 +2154,7 @@
     return ParsePostfixExpressionSuffix(ParseObjCBoxedExpr(AtLoc));
           
   default:
-    if (Tok.getIdentifierInfo() == 0)
+    if (Tok.getIdentifierInfo() == nullptr)
       return ExprError(Diag(AtLoc, diag::err_unexpected_at));
 
     switch (Tok.getIdentifierInfo()->getObjCKeywordID()) {
@@ -2166,13 +2165,13 @@
     case tok::objc_selector:
       return ParsePostfixExpressionSuffix(ParseObjCSelectorExpression(AtLoc));
       default: {
-        const char *str = 0;
+        const char *str = nullptr;
         if (GetLookAheadToken(1).is(tok::l_brace)) {
           char ch = Tok.getIdentifierInfo()->getNameStart()[0];
           str =  
             ch == 't' ? "try" 
                       : (ch == 'f' ? "finally" 
-                                   : (ch == 'a' ? "autoreleasepool" : 0));
+                                   : (ch == 'a' ? "autoreleasepool" : nullptr));
         }
         if (str) {
           SourceLocation kwLoc = Tok.getLocation();
@@ -2223,7 +2222,7 @@
       return true;
 
     IsExpr = true;
-    TypeOrExpr = Receiver.take();
+    TypeOrExpr = Receiver.get();
     return false;
   }
 
@@ -2249,14 +2248,14 @@
     // instance method.
     ExprResult Receiver = ParseCXXTypeConstructExpression(DS);
     if (!Receiver.isInvalid())
-      Receiver = ParsePostfixExpressionSuffix(Receiver.take());
+      Receiver = ParsePostfixExpressionSuffix(Receiver.get());
     if (!Receiver.isInvalid())
-      Receiver = ParseRHSOfBinaryExpression(Receiver.take(), prec::Comma);
+      Receiver = ParseRHSOfBinaryExpression(Receiver.get(), prec::Comma);
     if (Receiver.isInvalid())
       return true;
 
     IsExpr = true;
-    TypeOrExpr = Receiver.take();
+    TypeOrExpr = Receiver.get();
     return false;
   }
   
@@ -2345,11 +2344,11 @@
     if (Tok.is(tok::identifier) && Tok.getIdentifierInfo() == Ident_super &&
         NextToken().isNot(tok::period) && getCurScope()->isInObjcMethodScope())
       return ParseObjCMessageExpressionBody(LBracLoc, ConsumeToken(),
-                                            ParsedType(), 0);
+                                            ParsedType(), nullptr);
 
     // Parse the receiver, which is either a type or an expression.
     bool IsExpr;
-    void *TypeOrExpr = NULL;
+    void *TypeOrExpr = nullptr;
     if (ParseObjCXXMessageReceiver(IsExpr, TypeOrExpr)) {
       SkipUntil(tok::r_square, StopAtSemi);
       return ExprError();
@@ -2362,7 +2361,7 @@
 
     return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), 
                               ParsedType::getFromOpaquePtr(TypeOrExpr),
-                                          0);
+                                          nullptr);
   }
   
   if (Tok.is(tok::identifier)) {
@@ -2375,7 +2374,7 @@
                                        ReceiverType)) {
     case Sema::ObjCSuperMessage:
       return ParseObjCMessageExpressionBody(LBracLoc, ConsumeToken(),
-                                            ParsedType(), 0);
+                                            ParsedType(), nullptr);
 
     case Sema::ObjCClassMessage:
       if (!ReceiverType) {
@@ -2386,8 +2385,8 @@
       ConsumeToken(); // the type name
 
       return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), 
-                                            ReceiverType, 0);
-        
+                                            ReceiverType, nullptr);
+
     case Sema::ObjCInstanceMessage:
       // Fall through to parse an expression.
       break;
@@ -2402,7 +2401,7 @@
   }
 
   return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(),
-                                        ParsedType(), Res.take());
+                                        ParsedType(), Res.get());
 }
 
 /// \brief Parse the remainder of an Objective-C message following the
@@ -2478,8 +2477,7 @@
       KeyIdents.push_back(selIdent);
       KeyLocs.push_back(Loc);
 
-      if (Tok.isNot(tok::colon)) {
-        Diag(Tok, diag::err_expected_colon);
+      if (ExpectAndConsume(tok::colon)) {
         // We must manually skip to a ']', otherwise the expression skipper will
         // stop at the ']' when it skips to the ';'.  We want it to skip beyond
         // the enclosing expression.
@@ -2487,7 +2485,6 @@
         return ExprError();
       }
 
-      ConsumeToken(); // Eat the ':'.
       ///  Parse the expression after ':'
       
       if (Tok.is(tok::code_completion)) {
@@ -2525,7 +2522,7 @@
       }
 
       // We have a valid expression.
-      KeyExprs.push_back(Res.release());
+      KeyExprs.push_back(Res.get());
 
       // Code completion after each argument.
       if (Tok.is(tok::code_completion)) {
@@ -2569,10 +2566,10 @@
       }
 
       // We have a valid expression.
-      KeyExprs.push_back(Res.release());
+      KeyExprs.push_back(Res.get());
     }
   } else if (!selIdent) {
-    Diag(Tok, diag::err_expected_ident); // missing selector name.
+    Diag(Tok, diag::err_expected) << tok::identifier; // missing selector name.
 
     // We must manually skip to a ']', otherwise the expression skipper will
     // stop at the ']' when it skips to the ';'.  We want it to skip beyond
@@ -2582,10 +2579,8 @@
   }
     
   if (Tok.isNot(tok::r_square)) {
-    if (Tok.is(tok::identifier))
-      Diag(Tok, diag::err_expected_colon);
-    else
-      Diag(Tok, diag::err_expected_rsquare);
+    Diag(Tok, diag::err_expected)
+        << (Tok.is(tok::identifier) ? tok::colon : tok::r_square);
     // We must manually skip to a ']', otherwise the expression skipper will
     // stop at the ']' when it skips to the ';'.  We want it to skip beyond
     // the enclosing expression.
@@ -2622,7 +2617,7 @@
   SmallVector<SourceLocation, 4> AtLocs;
   ExprVector AtStrings;
   AtLocs.push_back(AtLoc);
-  AtStrings.push_back(Res.release());
+  AtStrings.push_back(Res.get());
 
   while (Tok.is(tok::at)) {
     AtLocs.push_back(ConsumeToken()); // eat the @.
@@ -2635,7 +2630,7 @@
     if (Lit.isInvalid())
       return Lit;
 
-    AtStrings.push_back(Lit.release());
+    AtStrings.push_back(Lit.get());
   }
 
   return Actions.ParseObjCStringLiteral(&AtLocs[0], AtStrings.data(),
@@ -2662,7 +2657,7 @@
     return Lit;
   }
   ConsumeToken(); // Consume the literal token.
-  return Actions.BuildObjCNumericLiteral(AtLoc, Lit.take());
+  return Actions.BuildObjCNumericLiteral(AtLoc, Lit.get());
 }
 
 /// ParseObjCNumericLiteral -
@@ -2676,7 +2671,7 @@
     return Lit;
   }
   ConsumeToken(); // Consume the literal token.
-  return Actions.BuildObjCNumericLiteral(AtLoc, Lit.take());
+  return Actions.BuildObjCNumericLiteral(AtLoc, Lit.get());
 }
 
 /// ParseObjCBoxedExpr -
@@ -2699,9 +2694,9 @@
   // Wrap the sub-expression in a parenthesized expression, to distinguish
   // a boxed expression from a literal.
   SourceLocation LPLoc = T.getOpenLocation(), RPLoc = T.getCloseLocation();
-  ValueExpr = Actions.ActOnParenExpr(LPLoc, RPLoc, ValueExpr.take());
+  ValueExpr = Actions.ActOnParenExpr(LPLoc, RPLoc, ValueExpr.get());
   return Actions.BuildObjCBoxedExpr(SourceRange(AtLoc, RPLoc),
-                                    ValueExpr.take());
+                                    ValueExpr.get());
 }
 
 ExprResult Parser::ParseObjCArrayLiteral(SourceLocation AtLoc) {
@@ -2725,12 +2720,13 @@
     if (Res.isInvalid())
       return true;
 
-    ElementExprs.push_back(Res.release());
+    ElementExprs.push_back(Res.get());
 
     if (Tok.is(tok::comma))
       ConsumeToken(); // Eat the ','.
     else if (Tok.isNot(tok::r_square))
-     return ExprError(Diag(Tok, diag::err_expected_rsquare_or_comma));
+      return ExprError(Diag(Tok, diag::err_expected_either) << tok::r_square
+                                                            << tok::comma);
   }
   SourceLocation EndLoc = ConsumeBracket(); // location of ']'
   MultiExprArg Args(ElementExprs);
@@ -2755,10 +2751,7 @@
       }
     }
 
-    if (Tok.is(tok::colon)) {
-      ConsumeToken();
-    } else {
-      Diag(Tok, diag::err_expected_colon);
+    if (ExpectAndConsume(tok::colon)) {
       SkipUntil(tok::r_brace, StopAtSemi);
       return ExprError();
     }
@@ -2774,20 +2767,19 @@
     
     // Parse the ellipsis that designates this as a pack expansion.
     SourceLocation EllipsisLoc;
-    if (Tok.is(tok::ellipsis) && getLangOpts().CPlusPlus)
-      EllipsisLoc = ConsumeToken();
-    
+    if (getLangOpts().CPlusPlus)
+      TryConsumeToken(tok::ellipsis, EllipsisLoc);
+
     // We have a valid expression. Collect it in a vector so we can
     // build the argument list.
     ObjCDictionaryElement Element = { 
       KeyExpr.get(), ValueExpr.get(), EllipsisLoc, None 
     };
     Elements.push_back(Element);
-    
-    if (Tok.is(tok::comma))
-      ConsumeToken(); // Eat the ','.
-    else if (Tok.isNot(tok::r_brace))
-      return ExprError(Diag(Tok, diag::err_expected_rbrace_or_comma));
+
+    if (!TryConsumeToken(tok::comma) && Tok.isNot(tok::r_brace))
+      return ExprError(Diag(Tok, diag::err_expected_either) << tok::r_brace
+                                                            << tok::comma);
   }
   SourceLocation EndLoc = ConsumeBrace();
   
@@ -2834,7 +2826,7 @@
   T.consumeOpen();
 
   if (Tok.isNot(tok::identifier))
-    return ExprError(Diag(Tok, diag::err_expected_ident));
+    return ExprError(Diag(Tok, diag::err_expected) << tok::identifier);
 
   IdentifierInfo *protocolId = Tok.getIdentifierInfo();
   SourceLocation ProtoIdLoc = ConsumeToken();
@@ -2847,7 +2839,7 @@
 }
 
 ///     objc-selector-expression
-///       @selector '(' objc-keyword-selector ')'
+///       @selector '(' '('[opt] objc-keyword-selector ')'[opt] ')'
 ExprResult Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) {
   SourceLocation SelectorLoc = ConsumeToken();
 
@@ -2859,7 +2851,10 @@
   
   BalancedDelimiterTracker T(*this, tok::l_paren);
   T.consumeOpen();
-
+  bool HasOptionalParen = Tok.is(tok::l_paren);
+  if (HasOptionalParen)
+    ConsumeParen();
+  
   if (Tok.is(tok::code_completion)) {
     Actions.CodeCompleteObjCSelector(getCurScope(), KeyIdents);
     cutOffParsing();
@@ -2869,20 +2864,20 @@
   IdentifierInfo *SelIdent = ParseObjCSelectorPiece(sLoc);
   if (!SelIdent &&  // missing selector name.
       Tok.isNot(tok::colon) && Tok.isNot(tok::coloncolon))
-    return ExprError(Diag(Tok, diag::err_expected_ident));
+    return ExprError(Diag(Tok, diag::err_expected) << tok::identifier);
 
   KeyIdents.push_back(SelIdent);
+  
   unsigned nColons = 0;
   if (Tok.isNot(tok::r_paren)) {
     while (1) {
-      if (Tok.is(tok::coloncolon)) { // Handle :: in C++.
+      if (TryConsumeToken(tok::coloncolon)) { // Handle :: in C++.
         ++nColons;
-        KeyIdents.push_back(0);
-      } else if (Tok.isNot(tok::colon))
-        return ExprError(Diag(Tok, diag::err_expected_colon));
-
+        KeyIdents.push_back(nullptr);
+      } else if (ExpectAndConsume(tok::colon)) // Otherwise expect ':'.
+        return ExprError();
       ++nColons;
-      ConsumeToken(); // Eat the ':' or '::'.
+
       if (Tok.is(tok::r_paren))
         break;
       
@@ -2900,11 +2895,14 @@
         break;
     }
   }
+  if (HasOptionalParen && Tok.is(tok::r_paren))
+    ConsumeParen(); // ')'
   T.consumeClose();
   Selector Sel = PP.getSelectorTable().getSelector(nColons, &KeyIdents[0]);
   return Actions.ParseObjCSelectorExpression(Sel, AtLoc, SelectorLoc,
                                              T.getOpenLocation(),
-                                             T.getCloseLocation());
+                                             T.getCloseLocation(),
+                                             !HasOptionalParen);
  }
 
 void Parser::ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod) {
@@ -2931,7 +2929,7 @@
   assert((Tok.is(tok::l_brace) || Tok.is(tok::kw_try) ||
           Tok.is(tok::colon)) && 
           "Inline objective-c method not starting with '{' or 'try' or ':'");
-  // Enter a scope for the method or c-fucntion body.
+  // Enter a scope for the method or c-function body.
   ParseScope BodyScope(this,
                        parseMethod
                        ? Scope::ObjCMethodScope|Scope::FnScope|Scope::DeclScope
@@ -2944,11 +2942,11 @@
   else
     Actions.ActOnStartOfFunctionDef(getCurScope(), MCDecl);
   if (Tok.is(tok::kw_try))
-    MCDecl = ParseFunctionTryBlock(MCDecl, BodyScope);
+    ParseFunctionTryBlock(MCDecl, BodyScope);
   else {
     if (Tok.is(tok::colon))
       ParseConstructorInitializer(MCDecl);
-    MCDecl = ParseFunctionStatementBody(MCDecl, BodyScope);
+    ParseFunctionStatementBody(MCDecl, BodyScope);
   }
   
   if (Tok.getLocation() != OrigLoc) {
diff --git a/lib/Parse/ParseOpenMP.cpp b/lib/Parse/ParseOpenMP.cpp
index 89e4147..d1544e6 100644
--- a/lib/Parse/ParseOpenMP.cpp
+++ b/lib/Parse/ParseOpenMP.cpp
@@ -11,19 +11,43 @@
 ///
 //===----------------------------------------------------------------------===//
 
+#include "RAIIObjectsForParser.h"
 #include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
 #include "clang/AST/StmtOpenMP.h"
 #include "clang/Parse/ParseDiagnostic.h"
 #include "clang/Parse/Parser.h"
 #include "clang/Sema/Scope.h"
 #include "llvm/ADT/PointerIntPair.h"
-#include "RAIIObjectsForParser.h"
 using namespace clang;
 
 //===----------------------------------------------------------------------===//
 // OpenMP declarative directives.
 //===----------------------------------------------------------------------===//
 
+static OpenMPDirectiveKind ParseOpenMPDirectiveKind(Parser &P) {
+  auto Tok = P.getCurToken();
+  auto DKind =
+      Tok.isAnnotation()
+          ? OMPD_unknown
+          : getOpenMPDirectiveKind(P.getPreprocessor().getSpelling(Tok));
+  if (DKind == OMPD_parallel) {
+    Tok = P.getPreprocessor().LookAhead(0);
+    auto SDKind =
+        Tok.isAnnotation()
+            ? OMPD_unknown
+            : getOpenMPDirectiveKind(P.getPreprocessor().getSpelling(Tok));
+    if (SDKind == OMPD_for) {
+      P.ConsumeToken();
+      DKind = OMPD_parallel_for;
+    } else if (SDKind == OMPD_sections) {
+      P.ConsumeToken();
+      DKind = OMPD_parallel_sections;
+    }
+  }
+  return DKind;
+}
+
 /// \brief Parsing of declarative OpenMP directives.
 ///
 ///       threadprivate-directive:
@@ -35,9 +59,7 @@
 
   SourceLocation Loc = ConsumeToken();
   SmallVector<Expr *, 5> Identifiers;
-  OpenMPDirectiveKind DKind = Tok.isAnnotation() ?
-                                  OMPD_unknown :
-                                  getOpenMPDirectiveKind(PP.getSpelling(Tok));
+  auto DKind = ParseOpenMPDirectiveKind(*this);
 
   switch (DKind) {
   case OMPD_threadprivate:
@@ -47,23 +69,34 @@
       // extra tokens.
       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
         Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
-          << getOpenMPDirectiveName(OMPD_threadprivate);
+            << getOpenMPDirectiveName(OMPD_threadprivate);
         SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
       }
       // Skip the last annot_pragma_openmp_end.
       ConsumeToken();
-      return Actions.ActOnOpenMPThreadprivateDirective(Loc,
-                                                       Identifiers);
+      return Actions.ActOnOpenMPThreadprivateDirective(Loc, Identifiers);
     }
     break;
   case OMPD_unknown:
     Diag(Tok, diag::err_omp_unknown_directive);
     break;
   case OMPD_parallel:
+  case OMPD_simd:
   case OMPD_task:
-  case NUM_OPENMP_DIRECTIVES:
+  case OMPD_taskyield:
+  case OMPD_barrier:
+  case OMPD_taskwait:
+  case OMPD_flush:
+  case OMPD_for:
+  case OMPD_sections:
+  case OMPD_section:
+  case OMPD_single:
+  case OMPD_master:
+  case OMPD_critical:
+  case OMPD_parallel_for:
+  case OMPD_parallel_sections:
     Diag(Tok, diag::err_omp_unexpected_directive)
-      << getOpenMPDirectiveName(DKind);
+        << getOpenMPDirectiveName(DKind);
     break;
   }
   SkipUntil(tok::annot_pragma_openmp_end);
@@ -76,25 +109,29 @@
 ///         annot_pragma_openmp 'threadprivate' simple-variable-list
 ///         annot_pragma_openmp_end
 ///
-///       parallel-directive:
-///         annot_pragma_openmp 'parallel' {clause} annot_pragma_openmp_end
+///       executable-directive:
+///         annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
+///         'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
+///         'parallel for' | 'parallel sections' | 'task' | 'taskyield' |
+///         'barrier' | 'taskwait' | 'flush' {clause} annot_pragma_openmp_end
 ///
-StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective() {
+StmtResult
+Parser::ParseOpenMPDeclarativeOrExecutableDirective(bool StandAloneAllowed) {
   assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
   ParenBraceBracketBalancer BalancerRAIIObj(*this);
   SmallVector<Expr *, 5> Identifiers;
   SmallVector<OMPClause *, 5> Clauses;
-  SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, NUM_OPENMP_CLAUSES>
-                                               FirstClauses(NUM_OPENMP_CLAUSES);
-  const unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
-                              Scope::OpenMPDirectiveScope;
+  SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1>
+  FirstClauses(OMPC_unknown + 1);
+  unsigned ScopeFlags =
+      Scope::FnScope | Scope::DeclScope | Scope::OpenMPDirectiveScope;
   SourceLocation Loc = ConsumeToken(), EndLoc;
-  OpenMPDirectiveKind DKind = Tok.isAnnotation() ?
-                                  OMPD_unknown :
-                                  getOpenMPDirectiveKind(PP.getSpelling(Tok));
+  auto DKind = ParseOpenMPDirectiveKind(*this);
   // Name of critical directive.
   DeclarationNameInfo DirName;
   StmtResult Directive = StmtError();
+  bool HasAssociatedStatement = true;
+  bool FlushHasClause = false;
 
   switch (DKind) {
   case OMPD_threadprivate:
@@ -104,27 +141,75 @@
       // extra tokens.
       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
         Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
-          << getOpenMPDirectiveName(OMPD_threadprivate);
+            << getOpenMPDirectiveName(OMPD_threadprivate);
         SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
       }
       DeclGroupPtrTy Res =
-        Actions.ActOnOpenMPThreadprivateDirective(Loc,
-                                                  Identifiers);
+          Actions.ActOnOpenMPThreadprivateDirective(Loc, Identifiers);
       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
     }
     SkipUntil(tok::annot_pragma_openmp_end);
     break;
-  case OMPD_parallel: {
+  case OMPD_flush:
+    if (PP.LookAhead(0).is(tok::l_paren)) {
+      FlushHasClause = true;
+      // Push copy of the current token back to stream to properly parse
+      // pseudo-clause OMPFlushClause.
+      PP.EnterToken(Tok);
+    }
+  case OMPD_taskyield:
+  case OMPD_barrier:
+  case OMPD_taskwait:
+    if (!StandAloneAllowed) {
+      Diag(Tok, diag::err_omp_immediate_directive)
+          << getOpenMPDirectiveName(DKind);
+    }
+    HasAssociatedStatement = false;
+    // Fall through for further analysis.
+  case OMPD_parallel:
+  case OMPD_simd:
+  case OMPD_for:
+  case OMPD_sections:
+  case OMPD_single:
+  case OMPD_section:
+  case OMPD_master:
+  case OMPD_critical:
+  case OMPD_parallel_for:
+  case OMPD_parallel_sections:
+  case OMPD_task: {
     ConsumeToken();
+    // Parse directive name of the 'critical' directive if any.
+    if (DKind == OMPD_critical) {
+      BalancedDelimiterTracker T(*this, tok::l_paren,
+                                 tok::annot_pragma_openmp_end);
+      if (!T.consumeOpen()) {
+        if (Tok.isAnyIdentifier()) {
+          DirName =
+              DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
+          ConsumeAnyToken();
+        } else {
+          Diag(Tok, diag::err_omp_expected_identifier_for_critical);
+        }
+        T.consumeClose();
+      }
+    }
 
-    Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope());
+    if (isOpenMPLoopDirective(DKind))
+      ScopeFlags |= Scope::OpenMPLoopDirectiveScope;
+    if (isOpenMPSimdDirective(DKind))
+      ScopeFlags |= Scope::OpenMPSimdDirectiveScope;
+    ParseScope OMPDirectiveScope(this, ScopeFlags);
+    Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);
 
     while (Tok.isNot(tok::annot_pragma_openmp_end)) {
-      OpenMPClauseKind CKind = Tok.isAnnotation() ?
-                                  OMPC_unknown :
-                                  getOpenMPClauseKind(PP.getSpelling(Tok));
-      OMPClause *Clause = ParseOpenMPClause(DKind, CKind,
-                                            !FirstClauses[CKind].getInt());
+      OpenMPClauseKind CKind =
+          Tok.isAnnotation()
+              ? OMPC_unknown
+              : FlushHasClause ? OMPC_flush
+                               : getOpenMPClauseKind(PP.getSpelling(Tok));
+      FlushHasClause = false;
+      OMPClause *Clause =
+          ParseOpenMPClause(DKind, CKind, !FirstClauses[CKind].getInt());
       FirstClauses[CKind].setInt(true);
       if (Clause) {
         FirstClauses[CKind].setPointer(Clause);
@@ -142,11 +227,10 @@
 
     StmtResult AssociatedStmt;
     bool CreateDirective = true;
-    ParseScope OMPDirectiveScope(this, ScopeFlags);
-    {
+    if (HasAssociatedStatement) {
       // The body is a block scope like in Lambdas and Blocks.
       Sema::CompoundScopeRAII CompoundScope(Actions);
-      Actions.ActOnCapturedRegionStart(Loc, getCurScope(), CR_OpenMP, 1);
+      Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
       Actions.ActOnStartOfCompoundStmt();
       // Parse statement
       AssociatedStmt = ParseStatement();
@@ -155,30 +239,23 @@
         Actions.ActOnCapturedRegionError();
         CreateDirective = false;
       } else {
-        AssociatedStmt = Actions.ActOnCapturedRegionEnd(AssociatedStmt.take());
+        AssociatedStmt = Actions.ActOnCapturedRegionEnd(AssociatedStmt.get());
         CreateDirective = AssociatedStmt.isUsable();
       }
     }
     if (CreateDirective)
-      Directive = Actions.ActOnOpenMPExecutableDirective(DKind, Clauses,
-                                                         AssociatedStmt.take(),
-                                                         Loc, EndLoc);
+      Directive = Actions.ActOnOpenMPExecutableDirective(
+          DKind, DirName, Clauses, AssociatedStmt.get(), Loc, EndLoc);
 
     // Exit scope.
     Actions.EndOpenMPDSABlock(Directive.get());
     OMPDirectiveScope.Exit();
-    }
     break;
+  }
   case OMPD_unknown:
     Diag(Tok, diag::err_omp_unknown_directive);
     SkipUntil(tok::annot_pragma_openmp_end);
     break;
-  case OMPD_task:
-  case NUM_OPENMP_DIRECTIVES:
-    Diag(Tok, diag::err_omp_unexpected_directive)
-      << getOpenMPDirectiveName(DKind);
-    SkipUntil(tok::annot_pragma_openmp_end);
-    break;
   }
   return Directive;
 }
@@ -225,14 +302,15 @@
       IsCorrect = false;
       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
                 StopBeforeMatch);
-      Diag(PrevTok.getLocation(), diag::err_expected_ident)
-        << SourceRange(PrevTok.getLocation(), PrevTokLocation);
+      Diag(PrevTok.getLocation(), diag::err_expected)
+          << tok::identifier
+          << SourceRange(PrevTok.getLocation(), PrevTokLocation);
     } else {
       DeclarationNameInfo NameInfo = Actions.GetNameFromUnqualifiedId(Name);
-      ExprResult Res = Actions.ActOnOpenMPIdExpression(getCurScope(), SS,
-                                                       NameInfo);
+      ExprResult Res =
+          Actions.ActOnOpenMPIdExpression(getCurScope(), SS, NameInfo);
       if (Res.isUsable())
-        VarList.push_back(Res.take());
+        VarList.push_back(Res.get());
     }
     // Consume ','.
     if (Tok.is(tok::comma)) {
@@ -241,7 +319,7 @@
   }
 
   if (NoIdentIsFound) {
-    Diag(Tok, diag::err_expected_ident);
+    Diag(Tok, diag::err_expected) << tok::identifier;
     IsCorrect = false;
   }
 
@@ -254,56 +332,159 @@
 /// \brief Parsing of OpenMP clauses.
 ///
 ///    clause:
-///       default-clause|private-clause|firstprivate-clause|shared-clause
+///       if-clause | final-clause | num_threads-clause | safelen-clause |
+///       default-clause | private-clause | firstprivate-clause | shared-clause
+///       | linear-clause | aligned-clause | collapse-clause |
+///       lastprivate-clause | reduction-clause | proc_bind-clause |
+///       schedule-clause | copyin-clause | copyprivate-clause | untied-clause |
+///       mergeable-clause | flush-clause
 ///
 OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
                                      OpenMPClauseKind CKind, bool FirstClause) {
-  OMPClause *Clause = 0;
+  OMPClause *Clause = nullptr;
   bool ErrorFound = false;
   // Check if clause is allowed for the given directive.
   if (CKind != OMPC_unknown && !isAllowedClauseForDirective(DKind, CKind)) {
-    Diag(Tok, diag::err_omp_unexpected_clause)
-      << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
+    Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
+                                               << getOpenMPDirectiveName(DKind);
     ErrorFound = true;
   }
 
   switch (CKind) {
-  case OMPC_default:
-    // OpenMP [2.9.3.1, Restrictions]
-    //  Only a single default clause may be specified on a parallel or task
-    //  directive.
+  case OMPC_if:
+  case OMPC_final:
+  case OMPC_num_threads:
+  case OMPC_safelen:
+  case OMPC_collapse:
+    // OpenMP [2.5, Restrictions]
+    //  At most one if clause can appear on the directive.
+    //  At most one num_threads clause can appear on the directive.
+    // OpenMP [2.8.1, simd construct, Restrictions]
+    //  Only one safelen  clause can appear on a simd directive.
+    //  Only one collapse clause can appear on a simd directive.
+    // OpenMP [2.11.1, task Construct, Restrictions]
+    //  At most one if clause can appear on the directive.
+    //  At most one final clause can appear on the directive.
     if (!FirstClause) {
-      Diag(Tok, diag::err_omp_more_one_clause)
-           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind);
+      Diag(Tok, diag::err_omp_more_one_clause) << getOpenMPDirectiveName(DKind)
+                                               << getOpenMPClauseName(CKind);
+    }
+
+    Clause = ParseOpenMPSingleExprClause(CKind);
+    break;
+  case OMPC_default:
+  case OMPC_proc_bind:
+    // OpenMP [2.14.3.1, Restrictions]
+    //  Only a single default clause may be specified on a parallel, task or
+    //  teams directive.
+    // OpenMP [2.5, parallel Construct, Restrictions]
+    //  At most one proc_bind clause can appear on the directive.
+    if (!FirstClause) {
+      Diag(Tok, diag::err_omp_more_one_clause) << getOpenMPDirectiveName(DKind)
+                                               << getOpenMPClauseName(CKind);
     }
 
     Clause = ParseOpenMPSimpleClause(CKind);
     break;
+  case OMPC_schedule:
+    // OpenMP [2.7.1, Restrictions, p. 3]
+    //  Only one schedule clause can appear on a loop directive.
+    if (!FirstClause) {
+      Diag(Tok, diag::err_omp_more_one_clause) << getOpenMPDirectiveName(DKind)
+                                               << getOpenMPClauseName(CKind);
+    }
+
+    Clause = ParseOpenMPSingleExprWithArgClause(CKind);
+    break;
+  case OMPC_ordered:
+  case OMPC_nowait:
+  case OMPC_untied:
+  case OMPC_mergeable:
+    // OpenMP [2.7.1, Restrictions, p. 9]
+    //  Only one ordered clause can appear on a loop directive.
+    // OpenMP [2.7.1, Restrictions, C/C++, p. 4]
+    //  Only one nowait clause can appear on a for directive.
+    if (!FirstClause) {
+      Diag(Tok, diag::err_omp_more_one_clause) << getOpenMPDirectiveName(DKind)
+                                               << getOpenMPClauseName(CKind);
+    }
+
+    Clause = ParseOpenMPClause(CKind);
+    break;
   case OMPC_private:
   case OMPC_firstprivate:
+  case OMPC_lastprivate:
   case OMPC_shared:
+  case OMPC_reduction:
+  case OMPC_linear:
+  case OMPC_aligned:
+  case OMPC_copyin:
+  case OMPC_copyprivate:
+  case OMPC_flush:
     Clause = ParseOpenMPVarListClause(CKind);
     break;
   case OMPC_unknown:
     Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
-      << getOpenMPDirectiveName(DKind);
+        << getOpenMPDirectiveName(DKind);
     SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
     break;
   case OMPC_threadprivate:
-  case NUM_OPENMP_CLAUSES:
-    Diag(Tok, diag::err_omp_unexpected_clause)
-      << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
+    Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
+                                               << getOpenMPDirectiveName(DKind);
     SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
     break;
   }
-  return ErrorFound ? 0 : Clause;
+  return ErrorFound ? nullptr : Clause;
 }
 
-/// \brief Parsing of simple OpenMP clauses like 'default'.
+/// \brief Parsing of OpenMP clauses with single expressions like 'if',
+/// 'final', 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams' or
+/// 'thread_limit'.
+///
+///    if-clause:
+///      'if' '(' expression ')'
+///
+///    final-clause:
+///      'final' '(' expression ')'
+///
+///    num_threads-clause:
+///      'num_threads' '(' expression ')'
+///
+///    safelen-clause:
+///      'safelen' '(' expression ')'
+///
+///    collapse-clause:
+///      'collapse' '(' expression ')'
+///
+OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind) {
+  SourceLocation Loc = ConsumeToken();
+
+  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
+  if (T.expectAndConsume(diag::err_expected_lparen_after,
+                         getOpenMPClauseName(Kind)))
+    return nullptr;
+
+  ExprResult LHS(ParseCastExpression(false, false, NotTypeCast));
+  ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
+
+  // Parse ')'.
+  T.consumeClose();
+
+  if (Val.isInvalid())
+    return nullptr;
+
+  return Actions.ActOnOpenMPSingleExprClause(
+      Kind, Val.get(), Loc, T.getOpenLocation(), T.getCloseLocation());
+}
+
+/// \brief Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
 ///
 ///    default-clause:
 ///         'default' '(' 'none' | 'shared' ')
 ///
+///    proc_bind-clause:
+///         'proc_bind' '(' 'master' | 'close' | 'spread' ')
+///
 OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind) {
   SourceLocation Loc = Tok.getLocation();
   SourceLocation LOpen = ConsumeToken();
@@ -311,11 +492,10 @@
   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
   if (T.expectAndConsume(diag::err_expected_lparen_after,
                          getOpenMPClauseName(Kind)))
-    return 0;
+    return nullptr;
 
-  unsigned Type = Tok.isAnnotation() ?
-                     unsigned(OMPC_DEFAULT_unknown) :
-                     getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok));
+  unsigned Type = getOpenMPSimpleClauseType(
+      Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
   SourceLocation TypeLoc = Tok.getLocation();
   if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
       Tok.isNot(tok::annot_pragma_openmp_end))
@@ -328,54 +508,221 @@
                                          Tok.getLocation());
 }
 
-/// \brief Parsing of OpenMP clause 'private', 'firstprivate',
-/// 'shared', 'copyin', or 'reduction'.
+/// \brief Parsing of OpenMP clauses like 'ordered'.
+///
+///    ordered-clause:
+///         'ordered'
+///
+///    nowait-clause:
+///         'nowait'
+///
+///    untied-clause:
+///         'untied'
+///
+///    mergeable-clause:
+///         'mergeable'
+///
+OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind) {
+  SourceLocation Loc = Tok.getLocation();
+  ConsumeAnyToken();
+
+  return Actions.ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
+}
+
+
+/// \brief Parsing of OpenMP clauses with single expressions and some additional
+/// argument like 'schedule' or 'dist_schedule'.
+///
+///    schedule-clause:
+///      'schedule' '(' kind [',' expression ] ')'
+///
+OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind) {
+  SourceLocation Loc = ConsumeToken();
+  SourceLocation CommaLoc;
+  // Parse '('.
+  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
+  if (T.expectAndConsume(diag::err_expected_lparen_after,
+                         getOpenMPClauseName(Kind)))
+    return nullptr;
+
+  ExprResult Val;
+  unsigned Type = getOpenMPSimpleClauseType(
+      Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
+  SourceLocation KLoc = Tok.getLocation();
+  if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
+      Tok.isNot(tok::annot_pragma_openmp_end))
+    ConsumeAnyToken();
+
+  if (Kind == OMPC_schedule &&
+      (Type == OMPC_SCHEDULE_static || Type == OMPC_SCHEDULE_dynamic ||
+       Type == OMPC_SCHEDULE_guided) &&
+      Tok.is(tok::comma)) {
+    CommaLoc = ConsumeAnyToken();
+    ExprResult LHS(ParseCastExpression(false, false, NotTypeCast));
+    Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
+    if (Val.isInvalid())
+      return nullptr;
+  }
+
+  // Parse ')'.
+  T.consumeClose();
+
+  return Actions.ActOnOpenMPSingleExprWithArgClause(
+      Kind, Type, Val.get(), Loc, T.getOpenLocation(), KLoc, CommaLoc,
+      T.getCloseLocation());
+}
+
+static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec,
+                             UnqualifiedId &ReductionId) {
+  SourceLocation TemplateKWLoc;
+  if (ReductionIdScopeSpec.isEmpty()) {
+    auto OOK = OO_None;
+    switch (P.getCurToken().getKind()) {
+    case tok::plus:
+      OOK = OO_Plus;
+      break;
+    case tok::minus:
+      OOK = OO_Minus;
+      break;
+    case tok::star:
+      OOK = OO_Star;
+      break;
+    case tok::amp:
+      OOK = OO_Amp;
+      break;
+    case tok::pipe:
+      OOK = OO_Pipe;
+      break;
+    case tok::caret:
+      OOK = OO_Caret;
+      break;
+    case tok::ampamp:
+      OOK = OO_AmpAmp;
+      break;
+    case tok::pipepipe:
+      OOK = OO_PipePipe;
+      break;
+    default:
+      break;
+    }
+    if (OOK != OO_None) {
+      SourceLocation OpLoc = P.ConsumeToken();
+      SourceLocation SymbolLocations[] = {OpLoc, OpLoc, SourceLocation()};
+      ReductionId.setOperatorFunctionId(OpLoc, OOK, SymbolLocations);
+      return false;
+    }
+  }
+  return P.ParseUnqualifiedId(ReductionIdScopeSpec, /*EnteringContext*/ false,
+                              /*AllowDestructorName*/ false,
+                              /*AllowConstructorName*/ false, ParsedType(),
+                              TemplateKWLoc, ReductionId);
+}
+
+/// \brief Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
+/// 'shared', 'copyin', 'copyprivate', 'flush' or 'reduction'.
 ///
 ///    private-clause:
 ///       'private' '(' list ')'
 ///    firstprivate-clause:
 ///       'firstprivate' '(' list ')'
+///    lastprivate-clause:
+///       'lastprivate' '(' list ')'
 ///    shared-clause:
 ///       'shared' '(' list ')'
+///    linear-clause:
+///       'linear' '(' list [ ':' linear-step ] ')'
+///    aligned-clause:
+///       'aligned' '(' list [ ':' alignment ] ')'
+///    reduction-clause:
+///       'reduction' '(' reduction-identifier ':' list ')'
+///    copyprivate-clause:
+///       'copyprivate' '(' list ')'
+///    flush-clause:
+///       'flush' '(' list ')'
 ///
 OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) {
   SourceLocation Loc = Tok.getLocation();
   SourceLocation LOpen = ConsumeToken();
+  SourceLocation ColonLoc = SourceLocation();
+  // Optional scope specifier and unqualified id for reduction identifier.
+  CXXScopeSpec ReductionIdScopeSpec;
+  UnqualifiedId ReductionId;
+  bool InvalidReductionId = false;
   // Parse '('.
   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
   if (T.expectAndConsume(diag::err_expected_lparen_after,
                          getOpenMPClauseName(Kind)))
-    return 0;
+    return nullptr;
+
+  // Handle reduction-identifier for reduction clause.
+  if (Kind == OMPC_reduction) {
+    ColonProtectionRAIIObject ColonRAII(*this);
+    if (getLangOpts().CPlusPlus) {
+      ParseOptionalCXXScopeSpecifier(ReductionIdScopeSpec, ParsedType(), false);
+    }
+    InvalidReductionId =
+        ParseReductionId(*this, ReductionIdScopeSpec, ReductionId);
+    if (InvalidReductionId) {
+      SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
+                StopBeforeMatch);
+    }
+    if (Tok.is(tok::colon)) {
+      ColonLoc = ConsumeToken();
+    } else {
+      Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier";
+    }
+  }
 
   SmallVector<Expr *, 5> Vars;
-  bool IsComma = true;
-  while (IsComma || (Tok.isNot(tok::r_paren) &&
+  bool IsComma = !InvalidReductionId;
+  const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
+  while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
                      Tok.isNot(tok::annot_pragma_openmp_end))) {
+    ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail);
     // Parse variable
     ExprResult VarExpr = ParseAssignmentExpression();
     if (VarExpr.isUsable()) {
-      Vars.push_back(VarExpr.take());
+      Vars.push_back(VarExpr.get());
     } else {
       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
                 StopBeforeMatch);
     }
     // Skip ',' if any
     IsComma = Tok.is(tok::comma);
-    if (IsComma) {
+    if (IsComma)
       ConsumeToken();
-    } else if (Tok.isNot(tok::r_paren) &&
-               Tok.isNot(tok::annot_pragma_openmp_end)) {
+    else if (Tok.isNot(tok::r_paren) &&
+             Tok.isNot(tok::annot_pragma_openmp_end) &&
+             (!MayHaveTail || Tok.isNot(tok::colon)))
       Diag(Tok, diag::err_omp_expected_punc)
-        << 1 << getOpenMPClauseName(Kind);
-    }
+          << ((Kind == OMPC_flush) ? getOpenMPDirectiveName(OMPD_flush)
+                                   : getOpenMPClauseName(Kind))
+          << (Kind == OMPC_flush);
+  }
+
+  // Parse ':' linear-step (or ':' alignment).
+  Expr *TailExpr = nullptr;
+  const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
+  if (MustHaveTail) {
+    ColonLoc = Tok.getLocation();
+    ConsumeToken();
+    ExprResult Tail = ParseAssignmentExpression();
+    if (Tail.isUsable())
+      TailExpr = Tail.get();
+    else
+      SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
+                StopBeforeMatch);
   }
 
   // Parse ')'.
   T.consumeClose();
-  if (Vars.empty())
-    return 0;
+  if (Vars.empty() || (MustHaveTail && !TailExpr) || InvalidReductionId)
+    return nullptr;
 
-  return Actions.ActOnOpenMPVarListClause(Kind, Vars, Loc, LOpen,
-                                          Tok.getLocation());
+  return Actions.ActOnOpenMPVarListClause(
+      Kind, Vars, TailExpr, Loc, LOpen, ColonLoc, Tok.getLocation(),
+      ReductionIdScopeSpec,
+      ReductionId.isValid() ? Actions.GetNameFromUnqualifiedId(ReductionId)
+                            : DeclarationNameInfo());
 }
 
diff --git a/lib/Parse/ParsePragma.cpp b/lib/Parse/ParsePragma.cpp
index 8a374e0..d3777f3 100644
--- a/lib/Parse/ParsePragma.cpp
+++ b/lib/Parse/ParsePragma.cpp
@@ -11,14 +11,288 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "ParsePragma.h"
+#include "RAIIObjectsForParser.h"
+#include "clang/Basic/TargetInfo.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Parse/ParseDiagnostic.h"
 #include "clang/Parse/Parser.h"
+#include "clang/Sema/LoopHint.h"
 #include "clang/Sema/Scope.h"
 #include "llvm/ADT/StringSwitch.h"
 using namespace clang;
 
+namespace {
+
+struct PragmaAlignHandler : public PragmaHandler {
+  explicit PragmaAlignHandler() : PragmaHandler("align") {}
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &FirstToken) override;
+};
+
+struct PragmaGCCVisibilityHandler : public PragmaHandler {
+  explicit PragmaGCCVisibilityHandler() : PragmaHandler("visibility") {}
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &FirstToken) override;
+};
+
+struct PragmaOptionsHandler : public PragmaHandler {
+  explicit PragmaOptionsHandler() : PragmaHandler("options") {}
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &FirstToken) override;
+};
+
+struct PragmaPackHandler : public PragmaHandler {
+  explicit PragmaPackHandler() : PragmaHandler("pack") {}
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &FirstToken) override;
+};
+
+struct PragmaMSStructHandler : public PragmaHandler {
+  explicit PragmaMSStructHandler() : PragmaHandler("ms_struct") {}
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &FirstToken) override;
+};
+
+struct PragmaUnusedHandler : public PragmaHandler {
+  PragmaUnusedHandler() : PragmaHandler("unused") {}
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &FirstToken) override;
+};
+
+struct PragmaWeakHandler : public PragmaHandler {
+  explicit PragmaWeakHandler() : PragmaHandler("weak") {}
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &FirstToken) override;
+};
+
+struct PragmaRedefineExtnameHandler : public PragmaHandler {
+  explicit PragmaRedefineExtnameHandler() : PragmaHandler("redefine_extname") {}
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &FirstToken) override;
+};
+
+struct PragmaOpenCLExtensionHandler : public PragmaHandler {
+  PragmaOpenCLExtensionHandler() : PragmaHandler("EXTENSION") {}
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &FirstToken) override;
+};
+
+
+struct PragmaFPContractHandler : public PragmaHandler {
+  PragmaFPContractHandler() : PragmaHandler("FP_CONTRACT") {}
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &FirstToken) override;
+};
+
+struct PragmaNoOpenMPHandler : public PragmaHandler {
+  PragmaNoOpenMPHandler() : PragmaHandler("omp") { }
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &FirstToken) override;
+};
+
+struct PragmaOpenMPHandler : public PragmaHandler {
+  PragmaOpenMPHandler() : PragmaHandler("omp") { }
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &FirstToken) override;
+};
+
+/// PragmaCommentHandler - "\#pragma comment ...".
+struct PragmaCommentHandler : public PragmaHandler {
+  PragmaCommentHandler(Sema &Actions)
+    : PragmaHandler("comment"), Actions(Actions) {}
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &FirstToken) override;
+private:
+  Sema &Actions;
+};
+
+struct PragmaDetectMismatchHandler : public PragmaHandler {
+  PragmaDetectMismatchHandler(Sema &Actions)
+    : PragmaHandler("detect_mismatch"), Actions(Actions) {}
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &FirstToken) override;
+private:
+  Sema &Actions;
+};
+
+struct PragmaMSPointersToMembers : public PragmaHandler {
+  explicit PragmaMSPointersToMembers() : PragmaHandler("pointers_to_members") {}
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &FirstToken) override;
+};
+
+struct PragmaMSVtorDisp : public PragmaHandler {
+  explicit PragmaMSVtorDisp() : PragmaHandler("vtordisp") {}
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &FirstToken) override;
+};
+
+struct PragmaMSPragma : public PragmaHandler {
+  explicit PragmaMSPragma(const char *name) : PragmaHandler(name) {}
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &FirstToken) override;
+};
+
+/// PragmaOptimizeHandler - "\#pragma clang optimize on/off".
+struct PragmaOptimizeHandler : public PragmaHandler {
+  PragmaOptimizeHandler(Sema &S)
+    : PragmaHandler("optimize"), Actions(S) {}
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &FirstToken) override;
+private:
+  Sema &Actions;
+};
+
+struct PragmaLoopHintHandler : public PragmaHandler {
+  PragmaLoopHintHandler() : PragmaHandler("loop") {}
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &FirstToken) override;
+};
+
+struct PragmaUnrollHintHandler : public PragmaHandler {
+  PragmaUnrollHintHandler(const char *name) : PragmaHandler(name) {}
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &FirstToken) override;
+};
+
+}  // end namespace
+
+void Parser::initializePragmaHandlers() {
+  AlignHandler.reset(new PragmaAlignHandler());
+  PP.AddPragmaHandler(AlignHandler.get());
+
+  GCCVisibilityHandler.reset(new PragmaGCCVisibilityHandler());
+  PP.AddPragmaHandler("GCC", GCCVisibilityHandler.get());
+
+  OptionsHandler.reset(new PragmaOptionsHandler());
+  PP.AddPragmaHandler(OptionsHandler.get());
+
+  PackHandler.reset(new PragmaPackHandler());
+  PP.AddPragmaHandler(PackHandler.get());
+
+  MSStructHandler.reset(new PragmaMSStructHandler());
+  PP.AddPragmaHandler(MSStructHandler.get());
+
+  UnusedHandler.reset(new PragmaUnusedHandler());
+  PP.AddPragmaHandler(UnusedHandler.get());
+
+  WeakHandler.reset(new PragmaWeakHandler());
+  PP.AddPragmaHandler(WeakHandler.get());
+
+  RedefineExtnameHandler.reset(new PragmaRedefineExtnameHandler());
+  PP.AddPragmaHandler(RedefineExtnameHandler.get());
+
+  FPContractHandler.reset(new PragmaFPContractHandler());
+  PP.AddPragmaHandler("STDC", FPContractHandler.get());
+
+  if (getLangOpts().OpenCL) {
+    OpenCLExtensionHandler.reset(new PragmaOpenCLExtensionHandler());
+    PP.AddPragmaHandler("OPENCL", OpenCLExtensionHandler.get());
+
+    PP.AddPragmaHandler("OPENCL", FPContractHandler.get());
+  }
+  if (getLangOpts().OpenMP)
+    OpenMPHandler.reset(new PragmaOpenMPHandler());
+  else
+    OpenMPHandler.reset(new PragmaNoOpenMPHandler());
+  PP.AddPragmaHandler(OpenMPHandler.get());
+
+  if (getLangOpts().MicrosoftExt) {
+    MSCommentHandler.reset(new PragmaCommentHandler(Actions));
+    PP.AddPragmaHandler(MSCommentHandler.get());
+    MSDetectMismatchHandler.reset(new PragmaDetectMismatchHandler(Actions));
+    PP.AddPragmaHandler(MSDetectMismatchHandler.get());
+    MSPointersToMembers.reset(new PragmaMSPointersToMembers());
+    PP.AddPragmaHandler(MSPointersToMembers.get());
+    MSVtorDisp.reset(new PragmaMSVtorDisp());
+    PP.AddPragmaHandler(MSVtorDisp.get());
+    MSInitSeg.reset(new PragmaMSPragma("init_seg"));
+    PP.AddPragmaHandler(MSInitSeg.get());
+    MSDataSeg.reset(new PragmaMSPragma("data_seg"));
+    PP.AddPragmaHandler(MSDataSeg.get());
+    MSBSSSeg.reset(new PragmaMSPragma("bss_seg"));
+    PP.AddPragmaHandler(MSBSSSeg.get());
+    MSConstSeg.reset(new PragmaMSPragma("const_seg"));
+    PP.AddPragmaHandler(MSConstSeg.get());
+    MSCodeSeg.reset(new PragmaMSPragma("code_seg"));
+    PP.AddPragmaHandler(MSCodeSeg.get());
+    MSSection.reset(new PragmaMSPragma("section"));
+    PP.AddPragmaHandler(MSSection.get());
+  }
+
+  OptimizeHandler.reset(new PragmaOptimizeHandler(Actions));
+  PP.AddPragmaHandler("clang", OptimizeHandler.get());
+
+  LoopHintHandler.reset(new PragmaLoopHintHandler());
+  PP.AddPragmaHandler("clang", LoopHintHandler.get());
+
+  UnrollHintHandler.reset(new PragmaUnrollHintHandler("unroll"));
+  PP.AddPragmaHandler(UnrollHintHandler.get());
+}
+
+void Parser::resetPragmaHandlers() {
+  // Remove the pragma handlers we installed.
+  PP.RemovePragmaHandler(AlignHandler.get());
+  AlignHandler.reset();
+  PP.RemovePragmaHandler("GCC", GCCVisibilityHandler.get());
+  GCCVisibilityHandler.reset();
+  PP.RemovePragmaHandler(OptionsHandler.get());
+  OptionsHandler.reset();
+  PP.RemovePragmaHandler(PackHandler.get());
+  PackHandler.reset();
+  PP.RemovePragmaHandler(MSStructHandler.get());
+  MSStructHandler.reset();
+  PP.RemovePragmaHandler(UnusedHandler.get());
+  UnusedHandler.reset();
+  PP.RemovePragmaHandler(WeakHandler.get());
+  WeakHandler.reset();
+  PP.RemovePragmaHandler(RedefineExtnameHandler.get());
+  RedefineExtnameHandler.reset();
+
+  if (getLangOpts().OpenCL) {
+    PP.RemovePragmaHandler("OPENCL", OpenCLExtensionHandler.get());
+    OpenCLExtensionHandler.reset();
+    PP.RemovePragmaHandler("OPENCL", FPContractHandler.get());
+  }
+  PP.RemovePragmaHandler(OpenMPHandler.get());
+  OpenMPHandler.reset();
+
+  if (getLangOpts().MicrosoftExt) {
+    PP.RemovePragmaHandler(MSCommentHandler.get());
+    MSCommentHandler.reset();
+    PP.RemovePragmaHandler(MSDetectMismatchHandler.get());
+    MSDetectMismatchHandler.reset();
+    PP.RemovePragmaHandler(MSPointersToMembers.get());
+    MSPointersToMembers.reset();
+    PP.RemovePragmaHandler(MSVtorDisp.get());
+    MSVtorDisp.reset();
+    PP.RemovePragmaHandler(MSInitSeg.get());
+    MSInitSeg.reset();
+    PP.RemovePragmaHandler(MSDataSeg.get());
+    MSDataSeg.reset();
+    PP.RemovePragmaHandler(MSBSSSeg.get());
+    MSBSSSeg.reset();
+    PP.RemovePragmaHandler(MSConstSeg.get());
+    MSConstSeg.reset();
+    PP.RemovePragmaHandler(MSCodeSeg.get());
+    MSCodeSeg.reset();
+    PP.RemovePragmaHandler(MSSection.get());
+    MSSection.reset();
+  }
+
+  PP.RemovePragmaHandler("STDC", FPContractHandler.get());
+  FPContractHandler.reset();
+
+  PP.RemovePragmaHandler("clang", OptimizeHandler.get());
+  OptimizeHandler.reset();
+
+  PP.RemovePragmaHandler("clang", LoopHintHandler.get());
+  LoopHintHandler.reset();
+
+  PP.RemovePragmaHandler(UnrollHintHandler.get());
+  UnrollHintHandler.reset();
+}
+
 /// \brief Handle the annotation token produced for #pragma unused(...)
 ///
 /// Each annot_pragma_unused is followed by the argument token so e.g.
@@ -130,7 +404,7 @@
   ConsumeToken();
 
   if (Tok.isNot(tok::l_brace)) {
-    PP.Diag(Tok, diag::err_expected_lbrace);
+    PP.Diag(Tok, diag::err_expected) << tok::l_brace;
     return StmtError();
   }
 
@@ -180,7 +454,307 @@
   }
 }
 
+void Parser::HandlePragmaMSPointersToMembers() {
+  assert(Tok.is(tok::annot_pragma_ms_pointers_to_members));
+  LangOptions::PragmaMSPointersToMembersKind RepresentationMethod =
+      static_cast<LangOptions::PragmaMSPointersToMembersKind>(
+          reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
+  SourceLocation PragmaLoc = ConsumeToken(); // The annotation token.
+  Actions.ActOnPragmaMSPointersToMembers(RepresentationMethod, PragmaLoc);
+}
 
+void Parser::HandlePragmaMSVtorDisp() {
+  assert(Tok.is(tok::annot_pragma_ms_vtordisp));
+  uintptr_t Value = reinterpret_cast<uintptr_t>(Tok.getAnnotationValue());
+  Sema::PragmaVtorDispKind Kind =
+      static_cast<Sema::PragmaVtorDispKind>((Value >> 16) & 0xFFFF);
+  MSVtorDispAttr::Mode Mode = MSVtorDispAttr::Mode(Value & 0xFFFF);
+  SourceLocation PragmaLoc = ConsumeToken(); // The annotation token.
+  Actions.ActOnPragmaMSVtorDisp(Kind, PragmaLoc, Mode);
+}
+
+void Parser::HandlePragmaMSPragma() {
+  assert(Tok.is(tok::annot_pragma_ms_pragma));
+  // Grab the tokens out of the annotation and enter them into the stream.
+  auto TheTokens = (std::pair<Token*, size_t> *)Tok.getAnnotationValue();
+  PP.EnterTokenStream(TheTokens->first, TheTokens->second, true, true);
+  SourceLocation PragmaLocation = ConsumeToken(); // The annotation token.
+  assert(Tok.isAnyIdentifier());
+  StringRef PragmaName = Tok.getIdentifierInfo()->getName();
+  PP.Lex(Tok); // pragma kind
+
+  // Figure out which #pragma we're dealing with.  The switch has no default
+  // because lex shouldn't emit the annotation token for unrecognized pragmas.
+  typedef bool (Parser::*PragmaHandler)(StringRef, SourceLocation);
+  PragmaHandler Handler = llvm::StringSwitch<PragmaHandler>(PragmaName)
+    .Case("data_seg", &Parser::HandlePragmaMSSegment)
+    .Case("bss_seg", &Parser::HandlePragmaMSSegment)
+    .Case("const_seg", &Parser::HandlePragmaMSSegment)
+    .Case("code_seg", &Parser::HandlePragmaMSSegment)
+    .Case("section", &Parser::HandlePragmaMSSection)
+    .Case("init_seg", &Parser::HandlePragmaMSInitSeg);
+
+  if (!(this->*Handler)(PragmaName, PragmaLocation)) {
+    // Pragma handling failed, and has been diagnosed.  Slurp up the tokens
+    // until eof (really end of line) to prevent follow-on errors.
+    while (Tok.isNot(tok::eof))
+      PP.Lex(Tok);
+    PP.Lex(Tok);
+  }
+}
+
+bool Parser::HandlePragmaMSSection(StringRef PragmaName,
+                                   SourceLocation PragmaLocation) {
+  if (Tok.isNot(tok::l_paren)) {
+    PP.Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
+    return false;
+  }
+  PP.Lex(Tok); // (
+  // Parsing code for pragma section
+  if (Tok.isNot(tok::string_literal)) {
+    PP.Diag(PragmaLocation, diag::warn_pragma_expected_section_name)
+        << PragmaName;
+    return false;
+  }
+  ExprResult StringResult = ParseStringLiteralExpression();
+  if (StringResult.isInvalid())
+    return false; // Already diagnosed.
+  StringLiteral *SegmentName = cast<StringLiteral>(StringResult.get());
+  if (SegmentName->getCharByteWidth() != 1) {
+    PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
+        << PragmaName;
+    return false;
+  }
+  int SectionFlags = 0;
+  while (Tok.is(tok::comma)) {
+    PP.Lex(Tok); // ,
+    if (!Tok.isAnyIdentifier()) {
+      PP.Diag(PragmaLocation, diag::warn_pragma_expected_action_or_r_paren)
+          << PragmaName;
+      return false;
+    }
+    Sema::PragmaSectionFlag Flag =
+      llvm::StringSwitch<Sema::PragmaSectionFlag>(
+      Tok.getIdentifierInfo()->getName())
+      .Case("read", Sema::PSF_Read)
+      .Case("write", Sema::PSF_Write)
+      .Case("execute", Sema::PSF_Execute)
+      .Case("shared", Sema::PSF_Invalid)
+      .Case("nopage", Sema::PSF_Invalid)
+      .Case("nocache", Sema::PSF_Invalid)
+      .Case("discard", Sema::PSF_Invalid)
+      .Case("remove", Sema::PSF_Invalid)
+      .Default(Sema::PSF_None);
+    if (Flag == Sema::PSF_None || Flag == Sema::PSF_Invalid) {
+      PP.Diag(PragmaLocation, Flag == Sema::PSF_None
+                                  ? diag::warn_pragma_invalid_specific_action
+                                  : diag::warn_pragma_unsupported_action)
+          << PragmaName << Tok.getIdentifierInfo()->getName();
+      return false;
+    }
+    SectionFlags |= Flag;
+    PP.Lex(Tok); // Identifier
+  }
+  if (Tok.isNot(tok::r_paren)) {
+    PP.Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
+    return false;
+  }
+  PP.Lex(Tok); // )
+  if (Tok.isNot(tok::eof)) {
+    PP.Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
+        << PragmaName;
+    return false;
+  }
+  PP.Lex(Tok); // eof
+  Actions.ActOnPragmaMSSection(PragmaLocation, SectionFlags, SegmentName);
+  return true;
+}
+
+bool Parser::HandlePragmaMSSegment(StringRef PragmaName,
+                                   SourceLocation PragmaLocation) {
+  if (Tok.isNot(tok::l_paren)) {
+    PP.Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
+    return false;
+  }
+  PP.Lex(Tok); // (
+  Sema::PragmaMsStackAction Action = Sema::PSK_Reset;
+  StringRef SlotLabel;
+  if (Tok.isAnyIdentifier()) {
+    StringRef PushPop = Tok.getIdentifierInfo()->getName();
+    if (PushPop == "push")
+      Action = Sema::PSK_Push;
+    else if (PushPop == "pop")
+      Action = Sema::PSK_Pop;
+    else {
+      PP.Diag(PragmaLocation,
+              diag::warn_pragma_expected_section_push_pop_or_name)
+          << PragmaName;
+      return false;
+    }
+    if (Action != Sema::PSK_Reset) {
+      PP.Lex(Tok); // push | pop
+      if (Tok.is(tok::comma)) {
+        PP.Lex(Tok); // ,
+        // If we've got a comma, we either need a label or a string.
+        if (Tok.isAnyIdentifier()) {
+          SlotLabel = Tok.getIdentifierInfo()->getName();
+          PP.Lex(Tok); // identifier
+          if (Tok.is(tok::comma))
+            PP.Lex(Tok);
+          else if (Tok.isNot(tok::r_paren)) {
+            PP.Diag(PragmaLocation, diag::warn_pragma_expected_punc)
+                << PragmaName;
+            return false;
+          }
+        }
+      } else if (Tok.isNot(tok::r_paren)) {
+        PP.Diag(PragmaLocation, diag::warn_pragma_expected_punc) << PragmaName;
+        return false;
+      }
+    }
+  }
+  // Grab the string literal for our section name.
+  StringLiteral *SegmentName = nullptr;
+  if (Tok.isNot(tok::r_paren)) {
+    if (Tok.isNot(tok::string_literal)) {
+      unsigned DiagID = Action != Sema::PSK_Reset ? !SlotLabel.empty() ?
+          diag::warn_pragma_expected_section_name :
+          diag::warn_pragma_expected_section_label_or_name :
+          diag::warn_pragma_expected_section_push_pop_or_name;
+      PP.Diag(PragmaLocation, DiagID) << PragmaName;
+      return false;
+    }
+    ExprResult StringResult = ParseStringLiteralExpression();
+    if (StringResult.isInvalid())
+      return false; // Already diagnosed.
+    SegmentName = cast<StringLiteral>(StringResult.get());
+    if (SegmentName->getCharByteWidth() != 1) {
+      PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
+          << PragmaName;
+      return false;
+    }
+    // Setting section "" has no effect
+    if (SegmentName->getLength())
+      Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set);
+  }
+  if (Tok.isNot(tok::r_paren)) {
+    PP.Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
+    return false;
+  }
+  PP.Lex(Tok); // )
+  if (Tok.isNot(tok::eof)) {
+    PP.Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
+        << PragmaName;
+    return false;
+  }
+  PP.Lex(Tok); // eof
+  Actions.ActOnPragmaMSSeg(PragmaLocation, Action, SlotLabel,
+                           SegmentName, PragmaName);
+  return true;
+}
+
+// #pragma init_seg({ compiler | lib | user | "section-name" [, func-name]} )
+bool Parser::HandlePragmaMSInitSeg(StringRef PragmaName,
+                                   SourceLocation PragmaLocation) {
+  if (getTargetInfo().getTriple().getEnvironment() != llvm::Triple::MSVC) {
+    PP.Diag(PragmaLocation, diag::warn_pragma_init_seg_unsupported_target);
+    return false;
+  }
+
+  if (ExpectAndConsume(tok::l_paren, diag::warn_pragma_expected_lparen,
+                       PragmaName))
+    return false;
+
+  // Parse either the known section names or the string section name.
+  StringLiteral *SegmentName = nullptr;
+  if (Tok.isAnyIdentifier()) {
+    auto *II = Tok.getIdentifierInfo();
+    StringRef Section = llvm::StringSwitch<StringRef>(II->getName())
+                            .Case("compiler", "\".CRT$XCC\"")
+                            .Case("lib", "\".CRT$XCL\"")
+                            .Case("user", "\".CRT$XCU\"")
+                            .Default("");
+
+    if (!Section.empty()) {
+      // Pretend the user wrote the appropriate string literal here.
+      Token Toks[1];
+      Toks[0].startToken();
+      Toks[0].setKind(tok::string_literal);
+      Toks[0].setLocation(Tok.getLocation());
+      Toks[0].setLiteralData(Section.data());
+      Toks[0].setLength(Section.size());
+      SegmentName =
+          cast<StringLiteral>(Actions.ActOnStringLiteral(Toks, nullptr).get());
+      PP.Lex(Tok);
+    }
+  } else if (Tok.is(tok::string_literal)) {
+    ExprResult StringResult = ParseStringLiteralExpression();
+    if (StringResult.isInvalid())
+      return false;
+    SegmentName = cast<StringLiteral>(StringResult.get());
+    if (SegmentName->getCharByteWidth() != 1) {
+      PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
+          << PragmaName;
+      return false;
+    }
+    // FIXME: Add support for the '[, func-name]' part of the pragma.
+  }
+
+  if (!SegmentName) {
+    PP.Diag(PragmaLocation, diag::warn_pragma_expected_init_seg) << PragmaName;
+    return false;
+  }
+
+  if (ExpectAndConsume(tok::r_paren, diag::warn_pragma_expected_rparen,
+                       PragmaName) ||
+      ExpectAndConsume(tok::eof, diag::warn_pragma_extra_tokens_at_eol,
+                       PragmaName))
+    return false;
+
+  Actions.ActOnPragmaMSInitSeg(PragmaLocation, SegmentName);
+  return true;
+}
+
+struct PragmaLoopHintInfo {
+  Token PragmaName;
+  Token Option;
+  Token Value;
+  bool HasValue;
+};
+
+LoopHint Parser::HandlePragmaLoopHint() {
+  assert(Tok.is(tok::annot_pragma_loop_hint));
+  PragmaLoopHintInfo *Info =
+      static_cast<PragmaLoopHintInfo *>(Tok.getAnnotationValue());
+
+  LoopHint Hint;
+  Hint.PragmaNameLoc =
+      IdentifierLoc::create(Actions.Context, Info->PragmaName.getLocation(),
+                            Info->PragmaName.getIdentifierInfo());
+  Hint.OptionLoc =
+      IdentifierLoc::create(Actions.Context, Info->Option.getLocation(),
+                            Info->Option.getIdentifierInfo());
+  if (Info->HasValue) {
+    Hint.Range =
+        SourceRange(Info->Option.getLocation(), Info->Value.getLocation());
+    Hint.ValueLoc =
+        IdentifierLoc::create(Actions.Context, Info->Value.getLocation(),
+                              Info->Value.getIdentifierInfo());
+
+    // FIXME: We should allow non-type template parameters for the loop hint
+    // value. See bug report #19610
+    if (Info->Value.is(tok::numeric_constant))
+      Hint.ValueExpr = Actions.ActOnNumericConstant(Info->Value).get();
+    else
+      Hint.ValueExpr = nullptr;
+  } else {
+    Hint.Range = SourceRange(Info->PragmaName.getLocation());
+    Hint.ValueLoc = nullptr;
+    Hint.ValueExpr = nullptr;
+  }
+
+  return Hint;
+}
 
 // #pragma GCC visibility comes in two variants:
 //   'push' '(' [visibility] ')'
@@ -197,7 +771,7 @@
 
   const IdentifierInfo *VisType;
   if (PushPop && PushPop->isStr("pop")) {
-    VisType = 0;
+    VisType = nullptr;
   } else if (PushPop && PushPop->isStr("push")) {
     PP.LexUnexpandedToken(Tok);
     if (Tok.isNot(tok::l_paren)) {
@@ -257,7 +831,7 @@
   }
 
   Sema::PragmaPackKind Kind = Sema::PPK_Default;
-  IdentifierInfo *Name = 0;
+  IdentifierInfo *Name = nullptr;
   Token Alignment;
   Alignment.startToken();
   SourceLocation LParenLoc = Tok.getLocation();
@@ -283,7 +857,7 @@
       } else if (II->isStr("pop")) {
         Kind = Sema::PPK_Pop;
       } else {
-        PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_invalid_action);
+        PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action) << "pack";
         return;
       }
       PP.Lex(Tok);
@@ -530,7 +1104,7 @@
     }
 
     // Illegal token!
-    PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_punc);
+    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_punc) << "unused";
     return;
   }
 
@@ -760,13 +1334,11 @@
 PragmaNoOpenMPHandler::HandlePragma(Preprocessor &PP,
                                     PragmaIntroducerKind Introducer,
                                     Token &FirstTok) {
-  if (PP.getDiagnostics().getDiagnosticLevel(diag::warn_pragma_omp_ignored,
-                                             FirstTok.getLocation()) !=
-      DiagnosticsEngine::Ignored) {
+  if (!PP.getDiagnostics().isIgnored(diag::warn_pragma_omp_ignored,
+                                     FirstTok.getLocation())) {
     PP.Diag(FirstTok, diag::warn_pragma_omp_ignored);
-    PP.getDiagnostics().setDiagnosticMapping(diag::warn_pragma_omp_ignored,
-                                             diag::MAP_IGNORE,
-                                             SourceLocation());
+    PP.getDiagnostics().setSeverity(diag::warn_pragma_omp_ignored,
+                                    diag::Severity::Ignored, SourceLocation());
   }
   PP.DiscardUntilEndOfDirective();
 }
@@ -799,6 +1371,220 @@
                       /*DisableMacroExpansion=*/true, /*OwnsTokens=*/true);
 }
 
+/// \brief Handle '#pragma pointers_to_members'
+// The grammar for this pragma is as follows:
+//
+// <inheritance model> ::= ('single' | 'multiple' | 'virtual') '_inheritance'
+//
+// #pragma pointers_to_members '(' 'best_case' ')'
+// #pragma pointers_to_members '(' 'full_generality' [',' inheritance-model] ')'
+// #pragma pointers_to_members '(' inheritance-model ')'
+void PragmaMSPointersToMembers::HandlePragma(Preprocessor &PP,
+                                             PragmaIntroducerKind Introducer,
+                                             Token &Tok) {
+  SourceLocation PointersToMembersLoc = Tok.getLocation();
+  PP.Lex(Tok);
+  if (Tok.isNot(tok::l_paren)) {
+    PP.Diag(PointersToMembersLoc, diag::warn_pragma_expected_lparen)
+      << "pointers_to_members";
+    return;
+  }
+  PP.Lex(Tok);
+  const IdentifierInfo *Arg = Tok.getIdentifierInfo();
+  if (!Arg) {
+    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
+      << "pointers_to_members";
+    return;
+  }
+  PP.Lex(Tok);
+
+  LangOptions::PragmaMSPointersToMembersKind RepresentationMethod;
+  if (Arg->isStr("best_case")) {
+    RepresentationMethod = LangOptions::PPTMK_BestCase;
+  } else {
+    if (Arg->isStr("full_generality")) {
+      if (Tok.is(tok::comma)) {
+        PP.Lex(Tok);
+
+        Arg = Tok.getIdentifierInfo();
+        if (!Arg) {
+          PP.Diag(Tok.getLocation(),
+                  diag::err_pragma_pointers_to_members_unknown_kind)
+              << Tok.getKind() << /*OnlyInheritanceModels*/ 0;
+          return;
+        }
+        PP.Lex(Tok);
+      } else if (Tok.is(tok::r_paren)) {
+        // #pragma pointers_to_members(full_generality) implicitly specifies
+        // virtual_inheritance.
+        Arg = nullptr;
+        RepresentationMethod = LangOptions::PPTMK_FullGeneralityVirtualInheritance;
+      } else {
+        PP.Diag(Tok.getLocation(), diag::err_expected_punc)
+            << "full_generality";
+        return;
+      }
+    }
+
+    if (Arg) {
+      if (Arg->isStr("single_inheritance")) {
+        RepresentationMethod =
+            LangOptions::PPTMK_FullGeneralitySingleInheritance;
+      } else if (Arg->isStr("multiple_inheritance")) {
+        RepresentationMethod =
+            LangOptions::PPTMK_FullGeneralityMultipleInheritance;
+      } else if (Arg->isStr("virtual_inheritance")) {
+        RepresentationMethod =
+            LangOptions::PPTMK_FullGeneralityVirtualInheritance;
+      } else {
+        PP.Diag(Tok.getLocation(),
+                diag::err_pragma_pointers_to_members_unknown_kind)
+            << Arg << /*HasPointerDeclaration*/ 1;
+        return;
+      }
+    }
+  }
+
+  if (Tok.isNot(tok::r_paren)) {
+    PP.Diag(Tok.getLocation(), diag::err_expected_rparen_after)
+        << (Arg ? Arg->getName() : "full_generality");
+    return;
+  }
+
+  PP.Lex(Tok);
+  if (Tok.isNot(tok::eod)) {
+    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
+      << "pointers_to_members";
+    return;
+  }
+
+  Token AnnotTok;
+  AnnotTok.startToken();
+  AnnotTok.setKind(tok::annot_pragma_ms_pointers_to_members);
+  AnnotTok.setLocation(PointersToMembersLoc);
+  AnnotTok.setAnnotationValue(
+      reinterpret_cast<void *>(static_cast<uintptr_t>(RepresentationMethod)));
+  PP.EnterToken(AnnotTok);
+}
+
+/// \brief Handle '#pragma vtordisp'
+// The grammar for this pragma is as follows:
+//
+// <vtordisp-mode> ::= ('off' | 'on' | '0' | '1' | '2' )
+//
+// #pragma vtordisp '(' ['push' ','] vtordisp-mode ')'
+// #pragma vtordisp '(' 'pop' ')'
+// #pragma vtordisp '(' ')'
+void PragmaMSVtorDisp::HandlePragma(Preprocessor &PP,
+                                    PragmaIntroducerKind Introducer,
+                                    Token &Tok) {
+  SourceLocation VtorDispLoc = Tok.getLocation();
+  PP.Lex(Tok);
+  if (Tok.isNot(tok::l_paren)) {
+    PP.Diag(VtorDispLoc, diag::warn_pragma_expected_lparen) << "vtordisp";
+    return;
+  }
+  PP.Lex(Tok);
+
+  Sema::PragmaVtorDispKind Kind = Sema::PVDK_Set;
+  const IdentifierInfo *II = Tok.getIdentifierInfo();
+  if (II) {
+    if (II->isStr("push")) {
+      // #pragma vtordisp(push, mode)
+      PP.Lex(Tok);
+      if (Tok.isNot(tok::comma)) {
+        PP.Diag(VtorDispLoc, diag::warn_pragma_expected_punc) << "vtordisp";
+        return;
+      }
+      PP.Lex(Tok);
+      Kind = Sema::PVDK_Push;
+      // not push, could be on/off
+    } else if (II->isStr("pop")) {
+      // #pragma vtordisp(pop)
+      PP.Lex(Tok);
+      Kind = Sema::PVDK_Pop;
+    }
+    // not push or pop, could be on/off
+  } else {
+    if (Tok.is(tok::r_paren)) {
+      // #pragma vtordisp()
+      Kind = Sema::PVDK_Reset;
+    }
+  }
+
+
+  uint64_t Value = 0;
+  if (Kind == Sema::PVDK_Push || Kind == Sema::PVDK_Set) {
+    const IdentifierInfo *II = Tok.getIdentifierInfo();
+    if (II && II->isStr("off")) {
+      PP.Lex(Tok);
+      Value = 0;
+    } else if (II && II->isStr("on")) {
+      PP.Lex(Tok);
+      Value = 1;
+    } else if (Tok.is(tok::numeric_constant) &&
+               PP.parseSimpleIntegerLiteral(Tok, Value)) {
+      if (Value > 2) {
+        PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_integer)
+            << 0 << 2 << "vtordisp";
+        return;
+      }
+    } else {
+      PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action)
+          << "vtordisp";
+      return;
+    }
+  }
+
+  // Finish the pragma: ')' $
+  if (Tok.isNot(tok::r_paren)) {
+    PP.Diag(VtorDispLoc, diag::warn_pragma_expected_rparen) << "vtordisp";
+    return;
+  }
+  PP.Lex(Tok);
+  if (Tok.isNot(tok::eod)) {
+    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
+        << "vtordisp";
+    return;
+  }
+
+  // Enter the annotation.
+  Token AnnotTok;
+  AnnotTok.startToken();
+  AnnotTok.setKind(tok::annot_pragma_ms_vtordisp);
+  AnnotTok.setLocation(VtorDispLoc);
+  AnnotTok.setAnnotationValue(reinterpret_cast<void *>(
+      static_cast<uintptr_t>((Kind << 16) | (Value & 0xFFFF))));
+  PP.EnterToken(AnnotTok);
+}
+
+/// \brief Handle all MS pragmas.  Simply forwards the tokens after inserting
+/// an annotation token.
+void PragmaMSPragma::HandlePragma(Preprocessor &PP,
+                                  PragmaIntroducerKind Introducer,
+                                  Token &Tok) {
+  Token EoF, AnnotTok;
+  EoF.startToken();
+  EoF.setKind(tok::eof);
+  AnnotTok.startToken();
+  AnnotTok.setKind(tok::annot_pragma_ms_pragma);
+  AnnotTok.setLocation(Tok.getLocation());
+  SmallVector<Token, 8> TokenVector;
+  // Suck up all of the tokens before the eod.
+  for (; Tok.isNot(tok::eod); PP.Lex(Tok))
+    TokenVector.push_back(Tok);
+  // Add a sentinal EoF token to the end of the list.
+  TokenVector.push_back(EoF);
+  // We must allocate this array with new because EnterTokenStream is going to
+  // delete it later.
+  Token *TokenArray = new Token[TokenVector.size()];
+  std::copy(TokenVector.begin(), TokenVector.end(), TokenArray);
+  auto Value = new (PP.getPreprocessorAllocator())
+      std::pair<Token*, size_t>(std::make_pair(TokenArray, TokenVector.size()));
+  AnnotTok.setAnnotationValue(Value);
+  PP.EnterToken(AnnotTok);
+}
+
 /// \brief Handle the Microsoft \#pragma detect_mismatch extension.
 ///
 /// The syntax is:
@@ -815,7 +1601,7 @@
   SourceLocation CommentLoc = Tok.getLocation();
   PP.Lex(Tok);
   if (Tok.isNot(tok::l_paren)) {
-    PP.Diag(CommentLoc, diag::err_expected_lparen);
+    PP.Diag(CommentLoc, diag::err_expected) << tok::l_paren;
     return;
   }
 
@@ -838,7 +1624,7 @@
     return;
 
   if (Tok.isNot(tok::r_paren)) {
-    PP.Diag(Tok.getLocation(), diag::err_expected_rparen);
+    PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
     return;
   }
   PP.Lex(Tok);  // Eat the r_paren.
@@ -929,3 +1715,251 @@
 
   Actions.ActOnPragmaMSComment(Kind, ArgumentString);
 }
+
+// #pragma clang optimize off
+// #pragma clang optimize on
+void PragmaOptimizeHandler::HandlePragma(Preprocessor &PP, 
+                                        PragmaIntroducerKind Introducer,
+                                        Token &FirstToken) {
+  Token Tok;
+  PP.Lex(Tok);
+  if (Tok.is(tok::eod)) {
+    PP.Diag(Tok.getLocation(), diag::err_pragma_missing_argument)
+        << "clang optimize"
+        << "'on' or 'off'";
+    return;
+  }
+  if (Tok.isNot(tok::identifier)) {
+    PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument)
+      << PP.getSpelling(Tok);
+    return;
+  }
+  const IdentifierInfo *II = Tok.getIdentifierInfo();
+  // The only accepted values are 'on' or 'off'.
+  bool IsOn = false;
+  if (II->isStr("on")) {
+    IsOn = true;
+  } else if (!II->isStr("off")) {
+    PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument)
+      << PP.getSpelling(Tok);
+    return;
+  }
+  PP.Lex(Tok);
+  
+  if (Tok.isNot(tok::eod)) {
+    PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_extra_argument)
+      << PP.getSpelling(Tok);
+    return;
+  }
+
+  Actions.ActOnPragmaOptimize(IsOn, FirstToken.getLocation());
+}
+
+/// \brief Parses loop or unroll pragma hint value and fills in Info.
+static bool ParseLoopHintValue(Preprocessor &PP, Token Tok, Token &PragmaName,
+                               Token &Option, bool &ValueInParens,
+                               PragmaLoopHintInfo &Info) {
+  ValueInParens = Tok.is(tok::l_paren);
+  if (ValueInParens) {
+    PP.Lex(Tok);
+    if (Tok.is(tok::r_paren)) {
+      // Nothing between the parentheses.
+      std::string PragmaString;
+      if (PragmaName.getIdentifierInfo()->getName() == "loop") {
+        PragmaString = "clang loop ";
+        PragmaString += Option.getIdentifierInfo()->getName();
+      } else {
+        assert(PragmaName.getIdentifierInfo()->getName() == "unroll" &&
+               "Unexpected pragma name");
+        PragmaString = "unroll";
+      }
+      PP.Diag(Tok.getLocation(), diag::err_pragma_missing_argument)
+          << PragmaString << "a positive integer value";
+      return true;
+    }
+  }
+
+  // FIXME: Value should be stored and parsed as a constant expression.
+  Token Value = Tok;
+
+  if (ValueInParens) {
+    PP.Lex(Tok);
+    if (Tok.isNot(tok::r_paren)) {
+      PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
+      return true;
+    }
+  }
+
+  Info.PragmaName = PragmaName;
+  Info.Option = Option;
+  Info.Value = Value;
+  Info.HasValue = true;
+  return false;
+}
+
+/// \brief Handle the \#pragma clang loop directive.
+///  #pragma clang 'loop' loop-hints
+///
+///  loop-hints:
+///    loop-hint loop-hints[opt]
+///
+///  loop-hint:
+///    'vectorize' '(' loop-hint-keyword ')'
+///    'interleave' '(' loop-hint-keyword ')'
+///    'unroll' '(' loop-hint-keyword ')'
+///    'vectorize_width' '(' loop-hint-value ')'
+///    'interleave_count' '(' loop-hint-value ')'
+///    'unroll_count' '(' loop-hint-value ')'
+///
+///  loop-hint-keyword:
+///    'enable'
+///    'disable'
+///
+///  loop-hint-value:
+///    constant-expression
+///
+/// Specifying vectorize(enable) or vectorize_width(_value_) instructs llvm to
+/// try vectorizing the instructions of the loop it precedes. Specifying
+/// interleave(enable) or interleave_count(_value_) instructs llvm to try
+/// interleaving multiple iterations of the loop it precedes. The width of the
+/// vector instructions is specified by vectorize_width() and the number of
+/// interleaved loop iterations is specified by interleave_count(). Specifying a
+/// value of 1 effectively disables vectorization/interleaving, even if it is
+/// possible and profitable, and 0 is invalid. The loop vectorizer currently
+/// only works on inner loops.
+///
+/// The unroll and unroll_count directives control the concatenation
+/// unroller. Specifying unroll(enable) instructs llvm to try to
+/// unroll the loop completely, and unroll(disable) disables unrolling
+/// for the loop. Specifying unroll_count(_value_) instructs llvm to
+/// try to unroll the loop the number of times indicated by the value.
+/// If unroll(enable) and unroll_count are both specified only
+/// unroll_count takes effect.
+void PragmaLoopHintHandler::HandlePragma(Preprocessor &PP,
+                                         PragmaIntroducerKind Introducer,
+                                         Token &Tok) {
+  // Incoming token is "loop" from "#pragma clang loop".
+  Token PragmaName = Tok;
+  SmallVector<Token, 1> TokenList;
+
+  // Lex the optimization option and verify it is an identifier.
+  PP.Lex(Tok);
+  if (Tok.isNot(tok::identifier)) {
+    PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
+        << /*MissingOption=*/true << "";
+    return;
+  }
+
+  while (Tok.is(tok::identifier)) {
+    Token Option = Tok;
+    IdentifierInfo *OptionInfo = Tok.getIdentifierInfo();
+
+    bool OptionValid = llvm::StringSwitch<bool>(OptionInfo->getName())
+                           .Case("vectorize", true)
+                           .Case("interleave", true)
+                           .Case("unroll", true)
+                           .Case("vectorize_width", true)
+                           .Case("interleave_count", true)
+                           .Case("unroll_count", true)
+                           .Default(false);
+    if (!OptionValid) {
+      PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
+          << /*MissingOption=*/false << OptionInfo;
+      return;
+    }
+
+    auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo;
+    PP.Lex(Tok);
+    bool ValueInParens;
+    if (ParseLoopHintValue(PP, Tok, PragmaName, Option, ValueInParens, *Info))
+      return;
+
+    if (!ValueInParens) {
+      PP.Diag(Info->Value.getLocation(), diag::err_expected) << tok::l_paren;
+      return;
+    }
+
+    // Generate the loop hint token.
+    Token LoopHintTok;
+    LoopHintTok.startToken();
+    LoopHintTok.setKind(tok::annot_pragma_loop_hint);
+    LoopHintTok.setLocation(PragmaName.getLocation());
+    LoopHintTok.setAnnotationValue(static_cast<void *>(Info));
+    TokenList.push_back(LoopHintTok);
+
+    // Get next optimization option.
+    PP.Lex(Tok);
+  }
+
+  if (Tok.isNot(tok::eod)) {
+    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
+        << "clang loop";
+    return;
+  }
+
+  Token *TokenArray = new Token[TokenList.size()];
+  std::copy(TokenList.begin(), TokenList.end(), TokenArray);
+
+  PP.EnterTokenStream(TokenArray, TokenList.size(),
+                      /*DisableMacroExpansion=*/false,
+                      /*OwnsTokens=*/true);
+}
+
+/// \brief Handle the loop unroll optimization pragmas.
+///  #pragma unroll
+///  #pragma unroll unroll-hint-value
+///  #pragma unroll '(' unroll-hint-value ')'
+///
+///  unroll-hint-value:
+///    constant-expression
+///
+/// Loop unrolling hints are specified with '#pragma unroll'. '#pragma unroll'
+/// can take a numeric argument optionally contained in parentheses. With no
+/// argument the directive instructs llvm to try to unroll the loop
+/// completely. A positive integer argument can be specified to indicate the
+/// number of times the loop should be unrolled.  To maximize compatibility with
+/// other compilers the unroll count argument can be specified with or without
+/// parentheses.
+void PragmaUnrollHintHandler::HandlePragma(Preprocessor &PP,
+                                           PragmaIntroducerKind Introducer,
+                                           Token &Tok) {
+  // Incoming token is "unroll" of "#pragma unroll".
+  Token PragmaName = Tok;
+  PP.Lex(Tok);
+  auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo;
+  if (Tok.is(tok::eod)) {
+    // Unroll pragma without an argument.
+    Info->PragmaName = PragmaName;
+    Info->Option = PragmaName;
+    Info->HasValue = false;
+  } else {
+    // Unroll pragma with an argument: "#pragma unroll N" or
+    // "#pragma unroll(N)".
+    bool ValueInParens;
+    if (ParseLoopHintValue(PP, Tok, PragmaName, PragmaName, ValueInParens,
+                           *Info))
+      return;
+
+    // In CUDA, the argument to '#pragma unroll' should not be contained in
+    // parentheses.
+    if (PP.getLangOpts().CUDA && ValueInParens)
+      PP.Diag(Info->Value.getLocation(),
+              diag::warn_pragma_unroll_cuda_value_in_parens);
+
+    PP.Lex(Tok);
+    if (Tok.isNot(tok::eod)) {
+      PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
+          << "unroll";
+      return;
+    }
+  }
+
+  // Generate the hint token.
+  Token *TokenArray = new Token[1];
+  TokenArray[0].startToken();
+  TokenArray[0].setKind(tok::annot_pragma_loop_hint);
+  TokenArray[0].setLocation(PragmaName.getLocation());
+  TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
+  PP.EnterTokenStream(TokenArray, 1, /*DisableMacroExpansion=*/false,
+                      /*OwnsTokens=*/true);
+}
diff --git a/lib/Parse/ParsePragma.h b/lib/Parse/ParsePragma.h
deleted file mode 100644
index b41450f..0000000
--- a/lib/Parse/ParsePragma.h
+++ /dev/null
@@ -1,139 +0,0 @@
-//===---- ParserPragmas.h - Language specific pragmas -----------*- 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 #pragma handlers for language specific pragmas.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_PARSE_PARSEPRAGMA_H
-#define LLVM_CLANG_PARSE_PARSEPRAGMA_H
-
-#include "clang/Lex/Pragma.h"
-
-namespace clang {
-  class Sema;
-  class Parser;
-
-class PragmaAlignHandler : public PragmaHandler {
-public:
-  explicit PragmaAlignHandler() : PragmaHandler("align") {}
-
-  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
-                            Token &FirstToken);
-};
-
-class PragmaGCCVisibilityHandler : public PragmaHandler {
-public:
-  explicit PragmaGCCVisibilityHandler() : PragmaHandler("visibility") {}
-
-  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
-                            Token &FirstToken);
-};
-
-class PragmaOptionsHandler : public PragmaHandler {
-public:
-  explicit PragmaOptionsHandler() : PragmaHandler("options") {}
-
-  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
-                            Token &FirstToken);
-};
-
-class PragmaPackHandler : public PragmaHandler {
-public:
-  explicit PragmaPackHandler() : PragmaHandler("pack") {}
-
-  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
-                            Token &FirstToken);
-};
-  
-class PragmaMSStructHandler : public PragmaHandler {
-public:
-  explicit PragmaMSStructHandler() : PragmaHandler("ms_struct") {}
-    
-  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
-                            Token &FirstToken);
-};
-
-class PragmaUnusedHandler : public PragmaHandler {
-public:
-  PragmaUnusedHandler() : PragmaHandler("unused") {}
-
-  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
-                            Token &FirstToken);
-};
-
-class PragmaWeakHandler : public PragmaHandler {
-public:
-  explicit PragmaWeakHandler() : PragmaHandler("weak") {}
-
-  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
-                            Token &FirstToken);
-};
-
-class PragmaRedefineExtnameHandler : public PragmaHandler {
-public:
-  explicit PragmaRedefineExtnameHandler() : PragmaHandler("redefine_extname") {}
-
-  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
-                            Token &FirstToken);
-};
-
-class PragmaOpenCLExtensionHandler : public PragmaHandler {
-public:
-  PragmaOpenCLExtensionHandler() : PragmaHandler("EXTENSION") {}
-  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
-                            Token &FirstToken);
-};
-  
-
-class PragmaFPContractHandler : public PragmaHandler {
-public:
-  PragmaFPContractHandler() : PragmaHandler("FP_CONTRACT") {}
-  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
-                            Token &FirstToken);
-};
-
-class PragmaNoOpenMPHandler : public PragmaHandler {
-public:
-  PragmaNoOpenMPHandler() : PragmaHandler("omp") { }
-  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
-                            Token &FirstToken);
-};
-
-class PragmaOpenMPHandler : public PragmaHandler {
-public:
-  PragmaOpenMPHandler() : PragmaHandler("omp") { }
-  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
-                            Token &FirstToken);
-};
-
-/// PragmaCommentHandler - "\#pragma comment ...".
-class PragmaCommentHandler : public PragmaHandler {
-public:
-  PragmaCommentHandler(Sema &Actions)
-    : PragmaHandler("comment"), Actions(Actions) {}
-  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
-                            Token &FirstToken);
-private:
-  Sema &Actions;
-};
-
-class PragmaDetectMismatchHandler : public PragmaHandler {
-public:
-  PragmaDetectMismatchHandler(Sema &Actions)
-    : PragmaHandler("detect_mismatch"), Actions(Actions) {}
-  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
-                            Token &FirstToken);
-private:
-  Sema &Actions;
-};
-
-}  // end namespace clang
-
-#endif
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index d1f2138..ec0ca6b 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -15,25 +15,14 @@
 #include "clang/Parse/Parser.h"
 #include "RAIIObjectsForParser.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/Basic/Attributes.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/PrettyStackTrace.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/TargetInfo.h"
 #include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/LoopHint.h"
 #include "clang/Sema/PrettyDeclStackTrace.h"
 #include "clang/Sema/Scope.h"
 #include "clang/Sema/TypoCorrection.h"
-#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCObjectFileInfo.h"
-#include "llvm/MC/MCParser/MCAsmParser.h"
-#include "llvm/MC/MCRegisterInfo.h"
-#include "llvm/MC/MCStreamer.h"
-#include "llvm/MC/MCSubtargetInfo.h"
-#include "llvm/MC/MCTargetAsmParser.h"
-#include "llvm/Support/SourceMgr.h"
-#include "llvm/Support/TargetRegistry.h"
-#include "llvm/Support/TargetSelect.h"
 #include "llvm/ADT/SmallString.h"
 using namespace clang;
 
@@ -112,7 +101,7 @@
   ParenBraceBracketBalancer BalancerRAIIObj(*this);
 
   ParsedAttributesWithRange Attrs(AttrFactory);
-  MaybeParseCXX11Attributes(Attrs, 0, /*MightBeObjCMessageSend*/ true);
+  MaybeParseCXX11Attributes(Attrs, nullptr, /*MightBeObjCMessageSend*/ true);
 
   StmtResult Res = ParseStatementOrDeclarationAfterAttributes(Stmts,
                                  OnlyStatement, TrailingElseLoc, Attrs);
@@ -142,7 +131,7 @@
     WantCXXNamedCasts = false;
   }
 
-  virtual bool ValidateCandidate(const TypoCorrection &candidate) {
+  bool ValidateCandidate(const TypoCorrection &candidate) override {
     if (FieldDecl *FD = candidate.getCorrectionDeclAs<FieldDecl>())
       return !candidate.getCorrectionSpecifier() || isa<ObjCIvarDecl>(FD);
     if (NextToken.is(tok::equal))
@@ -162,7 +151,7 @@
 Parser::ParseStatementOrDeclarationAfterAttributes(StmtVector &Stmts,
           bool OnlyStatement, SourceLocation *TrailingElseLoc,
           ParsedAttributesWithRange &Attrs) {
-  const char *SemiError = 0;
+  const char *SemiError = nullptr;
   StmtResult Res;
 
   // Cases in this switch statement should fall through if the parser expects
@@ -284,6 +273,14 @@
     break;
   }
 
+  case tok::kw___if_exists:
+  case tok::kw___if_not_exists:
+    ProhibitAttributes(Attrs);
+    ParseMicrosoftIfExistsStatement(Stmts);
+    // An __if_exists block is like a compound statement, but it doesn't create
+    // a new scope.
+    return StmtEmpty();
+
   case tok::kw_try:                 // C++ 15: try-block
     return ParseCXXTryBlock();
 
@@ -291,6 +288,11 @@
     ProhibitAttributes(Attrs); // TODO: is it correct?
     return ParseSEHTryBlock();
 
+  case tok::kw___leave:
+    Res = ParseSEHLeaveStatement();
+    SemiError = "__leave";
+    break;
+
   case tok::annot_pragma_vis:
     ProhibitAttributes(Attrs);
     HandlePragmaVisibility();
@@ -343,14 +345,25 @@
 
   case tok::annot_pragma_openmp:
     ProhibitAttributes(Attrs);
-    return ParseOpenMPDeclarativeOrExecutableDirective();
+    return ParseOpenMPDeclarativeOrExecutableDirective(!OnlyStatement);
 
+  case tok::annot_pragma_ms_pointers_to_members:
+    ProhibitAttributes(Attrs);
+    HandlePragmaMSPointersToMembers();
+    return StmtEmpty();
+
+  case tok::annot_pragma_ms_pragma:
+    ProhibitAttributes(Attrs);
+    HandlePragmaMSPragma();
+    return StmtEmpty();
+
+  case tok::annot_pragma_loop_hint:
+    ProhibitAttributes(Attrs);
+    return ParsePragmaLoopHint(Stmts, OnlyStatement, TrailingElseLoc, Attrs);
   }
 
   // If we reached this code, the statement must end in a semicolon.
-  if (Tok.is(tok::semi)) {
-    ConsumeToken();
-  } else if (!Res.isInvalid()) {
+  if (!TryConsumeToken(tok::semi) && !Res.isInvalid()) {
     // If the result was valid, then we do want to diagnose this.  Use
     // ExpectAndConsume to emit the diagnostic, even though we know it won't
     // succeed.
@@ -411,10 +424,27 @@
 ///   seh-finally-block
 ///
 StmtResult Parser::ParseSEHTryBlockCommon(SourceLocation TryLoc) {
-  if(Tok.isNot(tok::l_brace))
-    return StmtError(Diag(Tok,diag::err_expected_lbrace));
+  if (Tok.isNot(tok::l_brace))
+    return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);
 
-  StmtResult TryBlock(ParseCompoundStatement());
+  int SEHTryIndex, SEHTryParentIndex;
+  StmtResult TryBlock;
+  {
+    assert(Tok.is(tok::l_brace) && "Not a compount stmt!");
+
+    // Enter a scope to hold everything within the compound stmt.  Compound
+    // statements can always hold declarations.
+    ParseScope CompoundScope(this, Scope::DeclScope | Scope::SEHTryScope);
+    SEHTryIndex = getCurScope()->getSEHTryIndex();
+    SEHTryParentIndex = getCurScope()->getSEHTryParentIndex();
+
+    // Parse the statements in the body.
+    TryBlock = ParseCompoundStatementBody();
+  }
+
+  //StmtResult TryBlock(ParseCompoundStatement(/*isStmtExpr=*/false,
+  //                    Scope::DeclScope | Scope::SEHTryScope));
+
   if(TryBlock.isInvalid())
     return TryBlock;
 
@@ -435,8 +465,10 @@
 
   return Actions.ActOnSEHTryBlock(false /* IsCXXTry */,
                                   TryLoc,
-                                  TryBlock.take(),
-                                  Handler.take());
+                                  TryBlock.get(),
+                                  Handler.get(),
+                                  SEHTryIndex,
+                                  SEHTryParentIndex);
 }
 
 /// ParseSEHExceptBlock - Handle __except
@@ -449,7 +481,7 @@
     raii2(Ident___exception_code, false),
     raii3(Ident_GetExceptionCode, false);
 
-  if(ExpectAndConsume(tok::l_paren,diag::err_expected_lparen))
+  if (ExpectAndConsume(tok::l_paren))
     return StmtError();
 
   ParseScope ExpectScope(this, Scope::DeclScope | Scope::ControlScope);
@@ -470,7 +502,7 @@
   if(FilterExpr.isInvalid())
     return StmtError();
 
-  if(ExpectAndConsume(tok::r_paren,diag::err_expected_rparen))
+  if (ExpectAndConsume(tok::r_paren))
     return StmtError();
 
   StmtResult Block(ParseCompoundStatement());
@@ -478,7 +510,7 @@
   if(Block.isInvalid())
     return Block;
 
-  return Actions.ActOnSEHExceptBlock(ExceptLoc, FilterExpr.take(), Block.take());
+  return Actions.ActOnSEHExceptBlock(ExceptLoc, FilterExpr.get(), Block.get());
 }
 
 /// ParseSEHFinallyBlock - Handle __finally
@@ -495,7 +527,17 @@
   if(Block.isInvalid())
     return Block;
 
-  return Actions.ActOnSEHFinallyBlock(FinallyBlock,Block.take());
+  return Actions.ActOnSEHFinallyBlock(FinallyBlock,Block.get());
+}
+
+/// Handle __leave
+///
+/// seh-leave-statement:
+///   '__leave' ';'
+///
+StmtResult Parser::ParseSEHLeaveStatement() {
+  SourceLocation LeaveLoc = ConsumeToken();  // eat the '__leave'.
+  return Actions.ActOnSEHLeaveStmt(LeaveLoc, getCurScope());
 }
 
 /// ParseLabeledStatement - We have an identifier and a ':' after it.
@@ -538,12 +580,12 @@
       // can't handle GNU attributes), so only call it in the one case where
       // GNU attributes are allowed.
       SubStmt = ParseStatementOrDeclarationAfterAttributes(
-          Stmts, /*OnlyStmts*/ true, 0, TempAttrs);
+          Stmts, /*OnlyStmts*/ true, nullptr, TempAttrs);
       if (!TempAttrs.empty() && !SubStmt.isInvalid())
         SubStmt = Actions.ProcessStmtAttributes(
             SubStmt.get(), TempAttrs.getList(), TempAttrs.Range);
     } else {
-      Diag(Tok, diag::err_expected_semi_after) << "__attribute__";
+      Diag(Tok, diag::err_expected_after) << "__attribute__" << tok::semi;
     }
   }
 
@@ -595,13 +637,14 @@
   // DeepestParsedCaseStmt - This is the deepest statement we have parsed, which
   // gets updated each time a new case is parsed, and whose body is unset so
   // far.  When parsing 'case 4', this is the 'case 3' node.
-  Stmt *DeepestParsedCaseStmt = 0;
+  Stmt *DeepestParsedCaseStmt = nullptr;
 
   // While we have case statements, eat and stack them.
   SourceLocation ColonLoc;
   do {
     SourceLocation CaseLoc = MissingCase ? Expr.get()->getExprLoc() :
                                            ConsumeToken();  // eat the 'case'.
+    ColonLoc = SourceLocation();
 
     if (Tok.is(tok::code_completion)) {
       Actions.CodeCompleteCase(getCurScope());
@@ -614,41 +657,52 @@
     /// expression.
     ColonProtectionRAIIObject ColonProtection(*this);
 
-    ExprResult LHS(MissingCase ? Expr : ParseConstantExpression());
-    MissingCase = false;
-    if (LHS.isInvalid()) {
-      SkipUntil(tok::colon, StopAtSemi);
-      return StmtError();
+    ExprResult LHS;
+    if (!MissingCase) {
+      LHS = ParseConstantExpression();
+      if (LHS.isInvalid()) {
+        // If constant-expression is parsed unsuccessfully, recover by skipping
+        // current case statement (moving to the colon that ends it).
+        if (SkipUntil(tok::colon, tok::r_brace, StopAtSemi | StopBeforeMatch)) {
+          TryConsumeToken(tok::colon, ColonLoc);
+          continue;
+        }
+        return StmtError();
+      }
+    } else {
+      LHS = Expr;
+      MissingCase = false;
     }
 
     // GNU case range extension.
     SourceLocation DotDotDotLoc;
     ExprResult RHS;
-    if (Tok.is(tok::ellipsis)) {
-      Diag(Tok, diag::ext_gnu_case_range);
-      DotDotDotLoc = ConsumeToken();
-
+    if (TryConsumeToken(tok::ellipsis, DotDotDotLoc)) {
+      Diag(DotDotDotLoc, diag::ext_gnu_case_range);
       RHS = ParseConstantExpression();
       if (RHS.isInvalid()) {
-        SkipUntil(tok::colon, StopAtSemi);
+        if (SkipUntil(tok::colon, tok::r_brace, StopAtSemi | StopBeforeMatch)) {
+          TryConsumeToken(tok::colon, ColonLoc);
+          continue;
+        }
         return StmtError();
       }
     }
 
     ColonProtection.restore();
 
-    if (Tok.is(tok::colon)) {
-      ColonLoc = ConsumeToken();
-
-    // Treat "case blah;" as a typo for "case blah:".
-    } else if (Tok.is(tok::semi)) {
-      ColonLoc = ConsumeToken();
-      Diag(ColonLoc, diag::err_expected_colon_after) << "'case'"
-        << FixItHint::CreateReplacement(ColonLoc, ":");
+    if (TryConsumeToken(tok::colon, ColonLoc)) {
+    } else if (TryConsumeToken(tok::semi, ColonLoc) ||
+               TryConsumeToken(tok::coloncolon, ColonLoc)) {
+      // Treat "case blah;" or "case blah::" as a typo for "case blah:".
+      Diag(ColonLoc, diag::err_expected_after)
+          << "'case'" << tok::colon
+          << FixItHint::CreateReplacement(ColonLoc, ":");
     } else {
       SourceLocation ExpectedLoc = PP.getLocForEndOfToken(PrevTokLocation);
-      Diag(ExpectedLoc, diag::err_expected_colon_after) << "'case'"
-        << FixItHint::CreateInsertion(ExpectedLoc, ":");
+      Diag(ExpectedLoc, diag::err_expected_after)
+          << "'case'" << tok::colon
+          << FixItHint::CreateInsertion(ExpectedLoc, ":");
       ColonLoc = ExpectedLoc;
     }
 
@@ -676,8 +730,6 @@
     // Handle all case statements.
   } while (Tok.is(tok::kw_case));
 
-  assert(!TopLevelCase.isInvalid() && "Should have parsed at least one case!");
-
   // If we found a non-case statement, start by parsing it.
   StmtResult SubStmt;
 
@@ -685,19 +737,23 @@
     SubStmt = ParseStatement();
   } else {
     // Nicely diagnose the common error "switch (X) { case 4: }", which is
-    // not valid.
-    SourceLocation AfterColonLoc = PP.getLocForEndOfToken(ColonLoc);
-    Diag(AfterColonLoc, diag::err_label_end_of_compound_statement)
-      << FixItHint::CreateInsertion(AfterColonLoc, " ;");
-    SubStmt = true;
+    // not valid.  If ColonLoc doesn't point to a valid text location, there was
+    // another parsing error, so avoid producing extra diagnostics.
+    if (ColonLoc.isValid()) {
+      SourceLocation AfterColonLoc = PP.getLocForEndOfToken(ColonLoc);
+      Diag(AfterColonLoc, diag::err_label_end_of_compound_statement)
+        << FixItHint::CreateInsertion(AfterColonLoc, " ;");
+    }
+    SubStmt = StmtError();
   }
 
-  // Broken sub-stmt shouldn't prevent forming the case statement properly.
-  if (SubStmt.isInvalid())
-    SubStmt = Actions.ActOnNullStmt(SourceLocation());
-
   // Install the body into the most deeply-nested case.
-  Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, SubStmt.get());
+  if (DeepestParsedCaseStmt) {
+    // Broken sub-stmt shouldn't prevent forming the case statement properly.
+    if (SubStmt.isInvalid())
+      SubStmt = Actions.ActOnNullStmt(SourceLocation());
+    Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, SubStmt.get());
+  }
 
   // Return the top level parsed statement tree.
   return TopLevelCase;
@@ -713,18 +769,17 @@
   SourceLocation DefaultLoc = ConsumeToken();  // eat the 'default'.
 
   SourceLocation ColonLoc;
-  if (Tok.is(tok::colon)) {
-    ColonLoc = ConsumeToken();
-
-  // Treat "default;" as a typo for "default:".
-  } else if (Tok.is(tok::semi)) {
-    ColonLoc = ConsumeToken();
-    Diag(ColonLoc, diag::err_expected_colon_after) << "'default'"
-      << FixItHint::CreateReplacement(ColonLoc, ":");
+  if (TryConsumeToken(tok::colon, ColonLoc)) {
+  } else if (TryConsumeToken(tok::semi, ColonLoc)) {
+    // Treat "default;" as a typo for "default:".
+    Diag(ColonLoc, diag::err_expected_after)
+        << "'default'" << tok::colon
+        << FixItHint::CreateReplacement(ColonLoc, ":");
   } else {
     SourceLocation ExpectedLoc = PP.getLocForEndOfToken(PrevTokLocation);
-    Diag(ExpectedLoc, diag::err_expected_colon_after) << "'default'"
-      << FixItHint::CreateInsertion(ExpectedLoc, ":");
+    Diag(ExpectedLoc, diag::err_expected_after)
+        << "'default'" << tok::colon
+        << FixItHint::CreateInsertion(ExpectedLoc, ":");
     ColonLoc = ExpectedLoc;
   }
 
@@ -767,7 +822,6 @@
 ///         declaration
 /// [GNU]   '__extension__' declaration
 ///         statement
-/// [OMP]   openmp-directive            [TODO]
 ///
 /// [GNU] label-declarations:
 /// [GNU]   label-declaration
@@ -776,10 +830,6 @@
 /// [GNU] label-declaration:
 /// [GNU]   '__label__' identifier-list ';'
 ///
-/// [OMP] openmp-directive:             [TODO]
-/// [OMP]   barrier-directive
-/// [OMP]   flush-directive
-///
 StmtResult Parser::ParseCompoundStatement(bool isStmtExpr,
                                           unsigned ScopeFlags) {
   assert(Tok.is(tok::l_brace) && "Not a compount stmt!");
@@ -826,6 +876,12 @@
     case tok::annot_pragma_fp_contract:
       HandlePragmaFPContract();
       break;
+    case tok::annot_pragma_ms_pointers_to_members:
+      HandlePragmaMSPointersToMembers();
+      break;
+    case tok::annot_pragma_ms_pragma:
+      HandlePragmaMSPragma();
+      break;
     default:
       checkForPragmas = false;
       break;
@@ -867,7 +923,7 @@
     SmallVector<Decl *, 8> DeclsInGroup;
     while (1) {
       if (Tok.isNot(tok::identifier)) {
-        Diag(Tok, diag::err_expected_ident);
+        Diag(Tok, diag::err_expected) << tok::identifier;
         break;
       }
 
@@ -875,9 +931,8 @@
       SourceLocation IdLoc = ConsumeToken();
       DeclsInGroup.push_back(Actions.LookupOrCreateLabel(II, IdLoc, LabelLoc));
 
-      if (!Tok.is(tok::comma))
+      if (!TryConsumeToken(tok::comma))
         break;
-      ConsumeToken();
     }
 
     DeclSpec DS(AttrFactory);
@@ -887,21 +942,15 @@
 
     ExpectAndConsumeSemi(diag::err_expected_semi_declaration);
     if (R.isUsable())
-      Stmts.push_back(R.release());
+      Stmts.push_back(R.get());
   }
 
-  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
+  while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
     if (Tok.is(tok::annot_pragma_unused)) {
       HandlePragmaUnused();
       continue;
     }
 
-    if (getLangOpts().MicrosoftExt && (Tok.is(tok::kw___if_exists) ||
-        Tok.is(tok::kw___if_not_exists))) {
-      ParseMicrosoftIfExistsStatement(Stmts);
-      continue;
-    }
-
     StmtResult R;
     if (Tok.isNot(tok::kw___extension__)) {
       R = ParseStatementOrDeclaration(Stmts, false);
@@ -915,7 +964,8 @@
         ConsumeToken();
 
       ParsedAttributesWithRange attrs(AttrFactory);
-      MaybeParseCXX11Attributes(attrs, 0, /*MightBeObjCMessageSend*/ true);
+      MaybeParseCXX11Attributes(attrs, nullptr,
+                                /*MightBeObjCMessageSend*/ true);
 
       // If this is the start of a declaration, parse it as such.
       if (isDeclarationStatement()) {
@@ -946,7 +996,7 @@
     }
 
     if (R.isUsable())
-      Stmts.push_back(R.release());
+      Stmts.push_back(R.get());
   }
 
   SourceLocation CloseLoc = Tok.getLocation();
@@ -983,7 +1033,7 @@
     ParseCXXCondition(ExprResult, DeclResult, Loc, ConvertToBoolean);
   else {
     ExprResult = ParseExpression();
-    DeclResult = 0;
+    DeclResult = nullptr;
 
     // If required, convert to a boolean value.
     if (!ExprResult.isInvalid() && ConvertToBoolean)
@@ -1053,7 +1103,7 @@
 
   // Parse the condition.
   ExprResult CondExp;
-  Decl *CondVar = 0;
+  Decl *CondVar = nullptr;
   if (ParseParenExprOrCondition(CondExp, CondVar, IfLoc, true))
     return StmtError();
 
@@ -1077,8 +1127,7 @@
   //    would have to notify ParseStatement not to create a new scope. It's
   //    simpler to let it create a new scope.
   //
-  ParseScope InnerScope(this, Scope::DeclScope,
-                        C99orCXX && Tok.isNot(tok::l_brace));
+  ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(tok::l_brace));
 
   // Read the 'then' stmt.
   SourceLocation ThenStmtLoc = Tok.getLocation();
@@ -1110,8 +1159,7 @@
     // The substatement in a selection-statement (each substatement, in the else
     // form of the if statement) implicitly defines a local scope.
     //
-    ParseScope InnerScope(this, Scope::DeclScope,
-                          C99orCXX && Tok.isNot(tok::l_brace));
+    ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(tok::l_brace));
 
     ElseStmt = ParseStatement();
 
@@ -1131,8 +1179,8 @@
   // make turn the invalid one into a null stmt to avoid dropping the other
   // part.  If both are invalid, return error.
   if ((ThenStmt.isInvalid() && ElseStmt.isInvalid()) ||
-      (ThenStmt.isInvalid() && ElseStmt.get() == 0) ||
-      (ThenStmt.get() == 0  && ElseStmt.isInvalid())) {
+      (ThenStmt.isInvalid() && ElseStmt.get() == nullptr) ||
+      (ThenStmt.get() == nullptr && ElseStmt.isInvalid())) {
     // Both invalid, or one is invalid and other is non-present: return error.
     return StmtError();
   }
@@ -1175,14 +1223,14 @@
   // while, for, and switch statements are local to the if, while, for, or
   // switch statement (including the controlled statement).
   //
-  unsigned ScopeFlags = Scope::BreakScope | Scope::SwitchScope;
+  unsigned ScopeFlags = Scope::SwitchScope;
   if (C99orCXX)
     ScopeFlags |= Scope::DeclScope | Scope::ControlScope;
   ParseScope SwitchScope(this, ScopeFlags);
 
   // Parse the condition.
   ExprResult Cond;
-  Decl *CondVar = 0;
+  Decl *CondVar = nullptr;
   if (ParseParenExprOrCondition(Cond, CondVar, SwitchLoc, false))
     return StmtError();
 
@@ -1213,8 +1261,13 @@
   // See comments in ParseIfStatement for why we create a scope for the
   // condition and a new scope for substatement in C++.
   //
-  ParseScope InnerScope(this, Scope::DeclScope,
-                        C99orCXX && Tok.isNot(tok::l_brace));
+  getCurScope()->AddFlags(Scope::BreakScope);
+  ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(tok::l_brace));
+
+  // We have incremented the mangling number for the SwitchScope and the
+  // InnerScope, which is one too many.
+  if (C99orCXX)
+    getCurScope()->decrementMSLocalManglingNumber();
 
   // Read the body statement.
   StmtResult Body(ParseStatement(TrailingElseLoc));
@@ -1223,15 +1276,6 @@
   InnerScope.Exit();
   SwitchScope.Exit();
 
-  if (Body.isInvalid()) {
-    // FIXME: Remove the case statement list from the Switch statement.
-
-    // Put the synthesized null statement on the same line as the end of switch
-    // condition.
-    SourceLocation SynthesizedNullStmtLocation = Cond.get()->getLocEnd();
-    Body = Actions.ActOnNullStmt(SynthesizedNullStmtLocation);
-  }
-
   return Actions.ActOnFinishSwitchStmt(SwitchLoc, Switch.get(), Body.get());
 }
 
@@ -1274,13 +1318,13 @@
 
   // Parse the condition.
   ExprResult Cond;
-  Decl *CondVar = 0;
+  Decl *CondVar = nullptr;
   if (ParseParenExprOrCondition(Cond, CondVar, WhileLoc, true))
     return StmtError();
 
   FullExprArg FullCond(Actions.MakeFullExpr(Cond.get(), WhileLoc));
 
-  // C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if
+  // C99 6.8.5p5 - In C99, the body of the while statement is a scope, even if
   // there is no compound stmt.  C90 does not have this clause.  We only do this
   // if the body isn't a compound statement to avoid push/pop in common cases.
   //
@@ -1291,8 +1335,7 @@
   // See comments in ParseIfStatement for why we create a scope for the
   // condition and a new scope for substatement in C++.
   //
-  ParseScope InnerScope(this, Scope::DeclScope,
-                        C99orCXX && Tok.isNot(tok::l_brace));
+  ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(tok::l_brace));
 
   // Read the body statement.
   StmtResult Body(ParseStatement(TrailingElseLoc));
@@ -1325,7 +1368,7 @@
 
   ParseScope DoScope(this, ScopeFlags);
 
-  // C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if
+  // C99 6.8.5p5 - In C99, the body of the do statement is a scope, even if
   // there is no compound stmt.  C90 does not have this clause. We only do this
   // if the body isn't a compound statement to avoid push/pop in common cases.
   //
@@ -1333,9 +1376,8 @@
   // The substatement in an iteration-statement implicitly defines a local scope
   // which is entered and exited each time through the loop.
   //
-  ParseScope InnerScope(this, Scope::DeclScope,
-                        (getLangOpts().C99 || getLangOpts().CPlusPlus) &&
-                        Tok.isNot(tok::l_brace));
+  bool C99orCXX = getLangOpts().C99 || getLangOpts().CPlusPlus;
+  ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(tok::l_brace));
 
   // Read the body statement.
   StmtResult Body(ParseStatement());
@@ -1346,7 +1388,7 @@
   if (Tok.isNot(tok::kw_while)) {
     if (!Body.isInvalid()) {
       Diag(Tok, diag::err_expected_while);
-      Diag(DoLoc, diag::note_matching) << "do";
+      Diag(DoLoc, diag::note_matching) << "'do'";
       SkipUntil(tok::semi, StopBeforeMatch);
     }
     return StmtError();
@@ -1377,6 +1419,25 @@
                              Cond.get(), T.getCloseLocation());
 }
 
+bool Parser::isForRangeIdentifier() {
+  assert(Tok.is(tok::identifier));
+
+  const Token &Next = NextToken();
+  if (Next.is(tok::colon))
+    return true;
+
+  if (Next.is(tok::l_square) || Next.is(tok::kw_alignas)) {
+    TentativeParsingAction PA(*this);
+    ConsumeToken();
+    SkipCXX11Attributes();
+    bool Result = Tok.is(tok::colon);
+    PA.Revert();
+    return Result;
+  }
+
+  return false;
+}
+
 /// ParseForStatement
 ///       for-statement: [C99 6.8.5.3]
 ///         'for' '(' expr[opt] ';' expr[opt] ';' expr[opt] ')' statement
@@ -1424,12 +1485,9 @@
   // Names declared in the for-init-statement are in the same declarative-region
   // as those declared in the condition.
   //
-  unsigned ScopeFlags;
+  unsigned ScopeFlags = 0;
   if (C99orCXXorObjC)
-    ScopeFlags = Scope::BreakScope | Scope::ContinueScope |
-                 Scope::DeclScope  | Scope::ControlScope;
-  else
-    ScopeFlags = Scope::BreakScope | Scope::ContinueScope;
+    ScopeFlags = Scope::DeclScope | Scope::ControlScope;
 
   ParseScope ForScope(this, ScopeFlags);
 
@@ -1445,7 +1503,7 @@
   ExprResult Collection;
   ForRangeInit ForRangeInit;
   FullExprArg ThirdPart(Actions);
-  Decl *SecondVar = 0;
+  Decl *SecondVar = nullptr;
 
   if (Tok.is(tok::code_completion)) {
     Actions.CodeCompleteOrdinaryName(getCurScope(),
@@ -1463,6 +1521,29 @@
     ProhibitAttributes(attrs);
     // no first part, eat the ';'.
     ConsumeToken();
+  } else if (getLangOpts().CPlusPlus && Tok.is(tok::identifier) &&
+             isForRangeIdentifier()) {
+    ProhibitAttributes(attrs);
+    IdentifierInfo *Name = Tok.getIdentifierInfo();
+    SourceLocation Loc = ConsumeToken();
+    MaybeParseCXX11Attributes(attrs);
+
+    ForRangeInit.ColonLoc = ConsumeToken();
+    if (Tok.is(tok::l_brace))
+      ForRangeInit.RangeExpr = ParseBraceInitializer();
+    else
+      ForRangeInit.RangeExpr = ParseExpression();
+
+    Diag(Loc, getLangOpts().CPlusPlus1z
+                  ? diag::warn_cxx1y_compat_for_range_identifier
+                  : diag::ext_for_range_identifier)
+      << ((getLangOpts().CPlusPlus11 && !getLangOpts().CPlusPlus1z)
+              ? FixItHint::CreateInsertion(Loc, "auto &&")
+              : FixItHint());
+
+    FirstPart = Actions.ActOnCXXForRangeIdentifier(getCurScope(), Loc, Name,
+                                                   attrs, attrs.Range.getEnd());
+    ForRange = true;
   } else if (isForInitDeclaration()) {  // for (int X = 4;
     // Parse declaration, which eats the ';'.
     if (!C99orCXXorObjC)   // Use of C99-style for loops in C90 mode?
@@ -1474,12 +1555,10 @@
 
     SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
     StmtVector Stmts;
-    DeclGroupPtrTy DG = ParseSimpleDeclaration(Stmts, Declarator::ForContext,
-                                               DeclEnd, attrs, false,
-                                               MightBeForRangeStmt ?
-                                                 &ForRangeInit : 0);
+    DeclGroupPtrTy DG = ParseSimpleDeclaration(
+        Stmts, Declarator::ForContext, DeclEnd, attrs, false,
+        MightBeForRangeStmt ? &ForRangeInit : nullptr);
     FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
-
     if (ForRangeInit.ParsedForRangeDecl()) {
       Diag(ForRangeInit.ColonLoc, getLangOpts().CPlusPlus11 ?
            diag::warn_cxx98_compat_for_range : diag::ext_for_range);
@@ -1544,6 +1623,9 @@
       }
     }
   }
+
+  // Parse the second part of the for specifier.
+  getCurScope()->AddFlags(Scope::BreakScope | Scope::ContinueScope);
   if (!ForEach && !ForRange) {
     assert(!SecondPart.get() && "Shouldn't have a second expression yet.");
     // Parse the second part of the for specifier.
@@ -1582,7 +1664,7 @@
       ExprResult Third = ParseExpression();
       // FIXME: The C++11 standard doesn't actually say that this is a
       // discarded-value expression, but it clearly should be.
-      ThirdPart = Actions.MakeFullDiscardedValueExpr(Third.take());
+      ThirdPart = Actions.MakeFullDiscardedValueExpr(Third.get());
     }
   }
   // Match the ')'.
@@ -1595,7 +1677,7 @@
   StmtResult ForEachStmt;
 
   if (ForRange) {
-    ForRangeStmt = Actions.ActOnCXXForRangeStmt(ForLoc, FirstPart.take(),
+    ForRangeStmt = Actions.ActOnCXXForRangeStmt(ForLoc, FirstPart.get(),
                                                 ForRangeInit.ColonLoc,
                                                 ForRangeInit.RangeExpr.get(),
                                                 T.getCloseLocation(),
@@ -1606,12 +1688,12 @@
   // statement immediately in order to close over temporaries correctly.
   } else if (ForEach) {
     ForEachStmt = Actions.ActOnObjCForCollectionStmt(ForLoc,
-                                                     FirstPart.take(),
-                                                     Collection.take(),
+                                                     FirstPart.get(),
+                                                     Collection.get(),
                                                      T.getCloseLocation());
   }
 
-  // C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if
+  // C99 6.8.5p5 - In C99, the body of the for statement is a scope, even if
   // there is no compound stmt.  C90 does not have this clause.  We only do this
   // if the body isn't a compound statement to avoid push/pop in common cases.
   //
@@ -1622,8 +1704,15 @@
   // See comments in ParseIfStatement for why we create a scope for
   // for-init-statement/condition and a new scope for substatement in C++.
   //
-  ParseScope InnerScope(this, Scope::DeclScope,
-                        C99orCXXorObjC && Tok.isNot(tok::l_brace));
+  ParseScope InnerScope(this, Scope::DeclScope, C99orCXXorObjC,
+                        Tok.is(tok::l_brace));
+
+  // The body of the for loop has the same local mangling number as the
+  // for-init-statement.
+  // It will only be incremented if the body contains other things that would
+  // normally increment the mangling number (like a compound statement).
+  if (C99orCXXorObjC)
+    getCurScope()->decrementMSLocalManglingNumber();
 
   // Read the body statement.
   StmtResult Body(ParseStatement(TrailingElseLoc));
@@ -1638,15 +1727,15 @@
     return StmtError();
 
   if (ForEach)
-   return Actions.FinishObjCForCollectionStmt(ForEachStmt.take(),
-                                              Body.take());
+   return Actions.FinishObjCForCollectionStmt(ForEachStmt.get(),
+                                              Body.get());
 
   if (ForRange)
-    return Actions.FinishCXXForRangeStmt(ForRangeStmt.take(), Body.take());
+    return Actions.FinishCXXForRangeStmt(ForRangeStmt.get(), Body.get());
 
-  return Actions.ActOnForStmt(ForLoc, T.getOpenLocation(), FirstPart.take(),
+  return Actions.ActOnForStmt(ForLoc, T.getOpenLocation(), FirstPart.get(),
                               SecondPart, SecondVar, ThirdPart,
-                              T.getCloseLocation(), Body.take());
+                              T.getCloseLocation(), Body.get());
 }
 
 /// ParseGotoStatement
@@ -1675,9 +1764,9 @@
       SkipUntil(tok::semi, StopBeforeMatch);
       return StmtError();
     }
-    Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, R.take());
+    Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, R.get());
   } else {
-    Diag(Tok, diag::err_expected_ident);
+    Diag(Tok, diag::err_expected) << tok::identifier;
     return StmtError();
   }
 
@@ -1730,713 +1819,40 @@
           << R.get()->getSourceRange();
     } else
         R = ParseExpression();
-    if (R.isInvalid()) {  // Skip to the semicolon, but don't consume it.
-      SkipUntil(tok::semi, StopBeforeMatch);
+    if (R.isInvalid()) {
+      SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
       return StmtError();
     }
   }
-  return Actions.ActOnReturnStmt(ReturnLoc, R.take());
+  return Actions.ActOnReturnStmt(ReturnLoc, R.get(), getCurScope());
 }
 
-namespace {
-  class ClangAsmParserCallback : public llvm::MCAsmParserSemaCallback {
-    Parser &TheParser;
-    SourceLocation AsmLoc;
-    StringRef AsmString;
+StmtResult Parser::ParsePragmaLoopHint(StmtVector &Stmts, bool OnlyStatement,
+                                       SourceLocation *TrailingElseLoc,
+                                       ParsedAttributesWithRange &Attrs) {
+  // Create temporary attribute list.
+  ParsedAttributesWithRange TempAttrs(AttrFactory);
 
-    /// The tokens we streamed into AsmString and handed off to MC.
-    ArrayRef<Token> AsmToks;
-
-    /// The offset of each token in AsmToks within AsmString.
-    ArrayRef<unsigned> AsmTokOffsets;
-
-  public:
-    ClangAsmParserCallback(Parser &P, SourceLocation Loc,
-                           StringRef AsmString,
-                           ArrayRef<Token> Toks,
-                           ArrayRef<unsigned> Offsets)
-      : TheParser(P), AsmLoc(Loc), AsmString(AsmString),
-        AsmToks(Toks), AsmTokOffsets(Offsets) {
-      assert(AsmToks.size() == AsmTokOffsets.size());
-    }
-
-    void *LookupInlineAsmIdentifier(StringRef &LineBuf,
-                                    InlineAsmIdentifierInfo &Info,
-                                    bool IsUnevaluatedContext) {
-      // Collect the desired tokens.
-      SmallVector<Token, 16> LineToks;
-      const Token *FirstOrigToken = 0;
-      findTokensForString(LineBuf, LineToks, FirstOrigToken);
-
-      unsigned NumConsumedToks;
-      ExprResult Result =
-        TheParser.ParseMSAsmIdentifier(LineToks, NumConsumedToks, &Info,
-                                       IsUnevaluatedContext);
-
-      // If we consumed the entire line, tell MC that.
-      // Also do this if we consumed nothing as a way of reporting failure.
-      if (NumConsumedToks == 0 || NumConsumedToks == LineToks.size()) {
-        // By not modifying LineBuf, we're implicitly consuming it all.
-
-      // Otherwise, consume up to the original tokens.
-      } else {
-        assert(FirstOrigToken && "not using original tokens?");
-
-        // Since we're using original tokens, apply that offset.
-        assert(FirstOrigToken[NumConsumedToks].getLocation()
-                  == LineToks[NumConsumedToks].getLocation());
-        unsigned FirstIndex = FirstOrigToken - AsmToks.begin();
-        unsigned LastIndex = FirstIndex + NumConsumedToks - 1;
-
-        // The total length we've consumed is the relative offset
-        // of the last token we consumed plus its length.
-        unsigned TotalOffset = (AsmTokOffsets[LastIndex]
-                                + AsmToks[LastIndex].getLength()
-                                - AsmTokOffsets[FirstIndex]);
-        LineBuf = LineBuf.substr(0, TotalOffset);
-      }
-
-      // Initialize the "decl" with the lookup result.
-      Info.OpDecl = static_cast<void*>(Result.take());
-      return Info.OpDecl;
-    }
-
-    bool LookupInlineAsmField(StringRef Base, StringRef Member,
-                              unsigned &Offset) {
-      return TheParser.getActions().LookupInlineAsmField(Base, Member,
-                                                         Offset, AsmLoc);
-    }
-
-    static void DiagHandlerCallback(const llvm::SMDiagnostic &D,
-                                    void *Context) {
-      ((ClangAsmParserCallback*) Context)->handleDiagnostic(D);
-    }
-
-  private:
-    /// Collect the appropriate tokens for the given string.
-    void findTokensForString(StringRef Str, SmallVectorImpl<Token> &TempToks,
-                             const Token *&FirstOrigToken) const {
-      // For now, assert that the string we're working with is a substring
-      // of what we gave to MC.  This lets us use the original tokens.
-      assert(!std::less<const char*>()(Str.begin(), AsmString.begin()) &&
-             !std::less<const char*>()(AsmString.end(), Str.end()));
-
-      // Try to find a token whose offset matches the first token.
-      unsigned FirstCharOffset = Str.begin() - AsmString.begin();
-      const unsigned *FirstTokOffset
-        = std::lower_bound(AsmTokOffsets.begin(), AsmTokOffsets.end(),
-                           FirstCharOffset);
-
-      // For now, assert that the start of the string exactly
-      // corresponds to the start of a token.
-      assert(*FirstTokOffset == FirstCharOffset);
-
-      // Use all the original tokens for this line.  (We assume the
-      // end of the line corresponds cleanly to a token break.)
-      unsigned FirstTokIndex = FirstTokOffset - AsmTokOffsets.begin();
-      FirstOrigToken = &AsmToks[FirstTokIndex];
-      unsigned LastCharOffset = Str.end() - AsmString.begin();
-      for (unsigned i = FirstTokIndex, e = AsmTokOffsets.size(); i != e; ++i) {
-        if (AsmTokOffsets[i] >= LastCharOffset) break;
-        TempToks.push_back(AsmToks[i]);
-      }
-    }
-
-    void handleDiagnostic(const llvm::SMDiagnostic &D) {
-      // Compute an offset into the inline asm buffer.
-      // FIXME: This isn't right if .macro is involved (but hopefully, no
-      // real-world code does that).
-      const llvm::SourceMgr &LSM = *D.getSourceMgr();
-      const llvm::MemoryBuffer *LBuf =
-        LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc()));
-      unsigned Offset = D.getLoc().getPointer() - LBuf->getBufferStart();
-
-      // Figure out which token that offset points into.
-      const unsigned *TokOffsetPtr =
-        std::lower_bound(AsmTokOffsets.begin(), AsmTokOffsets.end(), Offset);
-      unsigned TokIndex = TokOffsetPtr - AsmTokOffsets.begin();
-      unsigned TokOffset = *TokOffsetPtr;
-
-      // If we come up with an answer which seems sane, use it; otherwise,
-      // just point at the __asm keyword.
-      // FIXME: Assert the answer is sane once we handle .macro correctly.
-      SourceLocation Loc = AsmLoc;
-      if (TokIndex < AsmToks.size()) {
-        const Token &Tok = AsmToks[TokIndex];
-        Loc = Tok.getLocation();
-        Loc = Loc.getLocWithOffset(Offset - TokOffset);
-      }
-      TheParser.Diag(Loc, diag::err_inline_ms_asm_parsing)
-        << D.getMessage();
-    }
-  };
-}
-
-/// Parse an identifier in an MS-style inline assembly block.
-///
-/// \param CastInfo - a void* so that we don't have to teach Parser.h
-///   about the actual type.
-ExprResult Parser::ParseMSAsmIdentifier(llvm::SmallVectorImpl<Token> &LineToks,
-                                        unsigned &NumLineToksConsumed,
-                                        void *CastInfo,
-                                        bool IsUnevaluatedContext) {
-  llvm::InlineAsmIdentifierInfo &Info =
-    *(llvm::InlineAsmIdentifierInfo *) CastInfo;
-
-  // Push a fake token on the end so that we don't overrun the token
-  // stream.  We use ';' because it expression-parsing should never
-  // overrun it.
-  const tok::TokenKind EndOfStream = tok::semi;
-  Token EndOfStreamTok;
-  EndOfStreamTok.startToken();
-  EndOfStreamTok.setKind(EndOfStream);
-  LineToks.push_back(EndOfStreamTok);
-
-  // Also copy the current token over.
-  LineToks.push_back(Tok);
-
-  PP.EnterTokenStream(LineToks.begin(),
-                      LineToks.size(),
-                      /*disable macros*/ true,
-                      /*owns tokens*/ false);
-
-  // Clear the current token and advance to the first token in LineToks.
-  ConsumeAnyToken();
-
-  // Parse an optional scope-specifier if we're in C++.
-  CXXScopeSpec SS;
-  if (getLangOpts().CPlusPlus) {
-    ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false);
-  }
-
-  // Require an identifier here.
-  SourceLocation TemplateKWLoc;
-  UnqualifiedId Id;
-  bool Invalid = ParseUnqualifiedId(SS,
-                                    /*EnteringContext=*/false,
-                                    /*AllowDestructorName=*/false,
-                                    /*AllowConstructorName=*/false,
-                                    /*ObjectType=*/ ParsedType(),
-                                    TemplateKWLoc,
-                                    Id);
-
-  // If we've run into the poison token we inserted before, or there
-  // was a parsing error, then claim the entire line.
-  if (Invalid || Tok.is(EndOfStream)) {
-    NumLineToksConsumed = LineToks.size() - 2;
-
-    // Otherwise, claim up to the start of the next token.
-  } else {
-    // Figure out how many tokens we are into LineToks.
-    unsigned LineIndex = 0;
-    while (LineToks[LineIndex].getLocation() != Tok.getLocation()) {
-      LineIndex++;
-      assert(LineIndex < LineToks.size() - 2); // we added two extra tokens
-    }
-
-    NumLineToksConsumed = LineIndex;
-  }
-      
-  // Finally, restore the old parsing state by consuming all the
-  // tokens we staged before, implicitly killing off the
-  // token-lexer we pushed.
-  for (unsigned n = LineToks.size() - 2 - NumLineToksConsumed; n != 0; --n) {
-    ConsumeAnyToken();
-  }
-  ConsumeToken(EndOfStream);
-
-  // Leave LineToks in its original state.
-  LineToks.pop_back();
-  LineToks.pop_back();
-
-  // Perform the lookup.
-  return Actions.LookupInlineAsmIdentifier(SS, TemplateKWLoc, Id, Info,
-                                           IsUnevaluatedContext);
-}
-
-/// Turn a sequence of our tokens back into a string that we can hand
-/// to the MC asm parser.
-static bool buildMSAsmString(Preprocessor &PP,
-                             SourceLocation AsmLoc,
-                             ArrayRef<Token> AsmToks,
-                             SmallVectorImpl<unsigned> &TokOffsets,
-                             SmallString<512> &Asm) {
-  assert (!AsmToks.empty() && "Didn't expect an empty AsmToks!");
-
-  // Is this the start of a new assembly statement?
-  bool isNewStatement = true;
-
-  for (unsigned i = 0, e = AsmToks.size(); i < e; ++i) {
-    const Token &Tok = AsmToks[i];
-
-    // Start each new statement with a newline and a tab.
-    if (!isNewStatement &&
-        (Tok.is(tok::kw_asm) || Tok.isAtStartOfLine())) {
-      Asm += "\n\t";
-      isNewStatement = true;
-    }
-
-    // Preserve the existence of leading whitespace except at the
-    // start of a statement.
-    if (!isNewStatement && Tok.hasLeadingSpace())
-      Asm += ' ';
-
-    // Remember the offset of this token.
-    TokOffsets.push_back(Asm.size());
-
-    // Don't actually write '__asm' into the assembly stream.
-    if (Tok.is(tok::kw_asm)) {
-      // Complain about __asm at the end of the stream.
-      if (i + 1 == e) {
-        PP.Diag(AsmLoc, diag::err_asm_empty);
-        return true;
-      }
-
-      continue;
-    }
-
-    // Append the spelling of the token.
-    SmallString<32> SpellingBuffer;
-    bool SpellingInvalid = false;
-    Asm += PP.getSpelling(Tok, SpellingBuffer, &SpellingInvalid);
-    assert(!SpellingInvalid && "spelling was invalid after correct parse?");
-
-    // We are no longer at the start of a statement.
-    isNewStatement = false;
-  }
-
-  // Ensure that the buffer is null-terminated.
-  Asm.push_back('\0');
-  Asm.pop_back();
-
-  assert(TokOffsets.size() == AsmToks.size());
-  return false;
-}
-
-/// ParseMicrosoftAsmStatement. When -fms-extensions/-fasm-blocks is enabled,
-/// this routine is called to collect the tokens for an MS asm statement.
-///
-/// [MS]  ms-asm-statement:
-///         ms-asm-block
-///         ms-asm-block ms-asm-statement
-///
-/// [MS]  ms-asm-block:
-///         '__asm' ms-asm-line '\n'
-///         '__asm' '{' ms-asm-instruction-block[opt] '}' ';'[opt]
-///
-/// [MS]  ms-asm-instruction-block
-///         ms-asm-line
-///         ms-asm-line '\n' ms-asm-instruction-block
-///
-StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) {
-  SourceManager &SrcMgr = PP.getSourceManager();
-  SourceLocation EndLoc = AsmLoc;
-  SmallVector<Token, 4> AsmToks;
-
-  bool InBraces = false;
-  unsigned short savedBraceCount = 0;
-  bool InAsmComment = false;
-  FileID FID;
-  unsigned LineNo = 0;
-  unsigned NumTokensRead = 0;
-  SourceLocation LBraceLoc;
-
-  if (Tok.is(tok::l_brace)) {
-    // Braced inline asm: consume the opening brace.
-    InBraces = true;
-    savedBraceCount = BraceCount;
-    EndLoc = LBraceLoc = ConsumeBrace();
-    ++NumTokensRead;
-  } else {
-    // Single-line inline asm; compute which line it is on.
-    std::pair<FileID, unsigned> ExpAsmLoc =
-      SrcMgr.getDecomposedExpansionLoc(EndLoc);
-    FID = ExpAsmLoc.first;
-    LineNo = SrcMgr.getLineNumber(FID, ExpAsmLoc.second);
-  }
-
-  SourceLocation TokLoc = Tok.getLocation();
-  do {
-    // If we hit EOF, we're done, period.
-    if (Tok.is(tok::eof))
-      break;
-
-    if (!InAsmComment && Tok.is(tok::semi)) {
-      // A semicolon in an asm is the start of a comment.
-      InAsmComment = true;
-      if (InBraces) {
-        // Compute which line the comment is on.
-        std::pair<FileID, unsigned> ExpSemiLoc =
-          SrcMgr.getDecomposedExpansionLoc(TokLoc);
-        FID = ExpSemiLoc.first;
-        LineNo = SrcMgr.getLineNumber(FID, ExpSemiLoc.second);
-      }
-    } else if (!InBraces || InAsmComment) {
-      // If end-of-line is significant, check whether this token is on a
-      // new line.
-      std::pair<FileID, unsigned> ExpLoc =
-        SrcMgr.getDecomposedExpansionLoc(TokLoc);
-      if (ExpLoc.first != FID ||
-          SrcMgr.getLineNumber(ExpLoc.first, ExpLoc.second) != LineNo) {
-        // If this is a single-line __asm, we're done.
-        if (!InBraces)
-          break;
-        // We're no longer in a comment.
-        InAsmComment = false;
-      } else if (!InAsmComment && Tok.is(tok::r_brace)) {
-        // Single-line asm always ends when a closing brace is seen.
-        // FIXME: This is compatible with Apple gcc's -fasm-blocks; what
-        // does MSVC do here?
-        break;
-      }
-    }
-    if (!InAsmComment && InBraces && Tok.is(tok::r_brace) &&
-        BraceCount == (savedBraceCount + 1)) {
-      // Consume the closing brace, and finish
-      EndLoc = ConsumeBrace();
-      break;
-    }
-
-    // Consume the next token; make sure we don't modify the brace count etc.
-    // if we are in a comment.
-    EndLoc = TokLoc;
-    if (InAsmComment)
-      PP.Lex(Tok);
-    else {
-      AsmToks.push_back(Tok);
-      ConsumeAnyToken();
-    }
-    TokLoc = Tok.getLocation();
-    ++NumTokensRead;
-  } while (1);
-
-  if (InBraces && BraceCount != savedBraceCount) {
-    // __asm without closing brace (this can happen at EOF).
-    Diag(Tok, diag::err_expected_rbrace);
-    Diag(LBraceLoc, diag::note_matching) << "{";
-    return StmtError();
-  } else if (NumTokensRead == 0) {
-    // Empty __asm.
-    Diag(Tok, diag::err_expected_lbrace);
-    return StmtError();
-  }
-
-  // Okay, prepare to use MC to parse the assembly.
-  SmallVector<StringRef, 4> ConstraintRefs;
-  SmallVector<Expr*, 4> Exprs;
-  SmallVector<StringRef, 4> ClobberRefs;
-
-  // We need an actual supported target.
-  llvm::Triple TheTriple = Actions.Context.getTargetInfo().getTriple();
-  llvm::Triple::ArchType ArchTy = TheTriple.getArch();
-  const std::string &TT = TheTriple.getTriple();
-  const llvm::Target *TheTarget = 0;
-  bool UnsupportedArch = (ArchTy != llvm::Triple::x86 &&
-                          ArchTy != llvm::Triple::x86_64);
-  if (UnsupportedArch) {
-    Diag(AsmLoc, diag::err_msasm_unsupported_arch) << TheTriple.getArchName();
-  } else {
-    std::string Error;
-    TheTarget = llvm::TargetRegistry::lookupTarget(TT, Error);
-    if (!TheTarget)
-      Diag(AsmLoc, diag::err_msasm_unable_to_create_target) << Error;
-  }
-
-  // If we don't support assembly, or the assembly is empty, we don't
-  // need to instantiate the AsmParser, etc.
-  if (!TheTarget || AsmToks.empty()) {
-    return Actions.ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, StringRef(),
-                                  /*NumOutputs*/ 0, /*NumInputs*/ 0,
-                                  ConstraintRefs, ClobberRefs, Exprs, EndLoc);
-  }
-
-  // Expand the tokens into a string buffer.
-  SmallString<512> AsmString;
-  SmallVector<unsigned, 8> TokOffsets;
-  if (buildMSAsmString(PP, AsmLoc, AsmToks, TokOffsets, AsmString))
-    return StmtError();
-
-  OwningPtr<llvm::MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TT));
-  OwningPtr<llvm::MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, TT));
-  // Get the instruction descriptor.
-  const llvm::MCInstrInfo *MII = TheTarget->createMCInstrInfo(); 
-  OwningPtr<llvm::MCObjectFileInfo> MOFI(new llvm::MCObjectFileInfo());
-  OwningPtr<llvm::MCSubtargetInfo>
-    STI(TheTarget->createMCSubtargetInfo(TT, "", ""));
-
-  llvm::SourceMgr TempSrcMgr;
-  llvm::MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &TempSrcMgr);
-  llvm::MemoryBuffer *Buffer =
-    llvm::MemoryBuffer::getMemBuffer(AsmString, "<MS inline asm>");
-
-  // Tell SrcMgr about this buffer, which is what the parser will pick up.
-  TempSrcMgr.AddNewSourceBuffer(Buffer, llvm::SMLoc());
-
-  OwningPtr<llvm::MCStreamer> Str(createNullStreamer(Ctx));
-  OwningPtr<llvm::MCAsmParser>
-    Parser(createMCAsmParser(TempSrcMgr, Ctx, *Str.get(), *MAI));
-  OwningPtr<llvm::MCTargetAsmParser>
-    TargetParser(TheTarget->createMCAsmParser(*STI, *Parser, *MII));
-
-  llvm::MCInstPrinter *IP =
-    TheTarget->createMCInstPrinter(1, *MAI, *MII, *MRI, *STI);
-
-  // Change to the Intel dialect.
-  Parser->setAssemblerDialect(1);
-  Parser->setTargetParser(*TargetParser.get());
-  Parser->setParsingInlineAsm(true);
-  TargetParser->setParsingInlineAsm(true);
-
-  ClangAsmParserCallback Callback(*this, AsmLoc, AsmString,
-                                  AsmToks, TokOffsets);
-  TargetParser->setSemaCallback(&Callback);
-  TempSrcMgr.setDiagHandler(ClangAsmParserCallback::DiagHandlerCallback,
-                            &Callback);
-
-  unsigned NumOutputs;
-  unsigned NumInputs;
-  std::string AsmStringIR;
-  SmallVector<std::pair<void *, bool>, 4> OpExprs;
-  SmallVector<std::string, 4> Constraints;
-  SmallVector<std::string, 4> Clobbers;
-  if (Parser->parseMSInlineAsm(AsmLoc.getPtrEncoding(), AsmStringIR,
-                               NumOutputs, NumInputs, OpExprs, Constraints,
-                               Clobbers, MII, IP, Callback))
-    return StmtError();
-
-  // Build the vector of clobber StringRefs.
-  unsigned NumClobbers = Clobbers.size();
-  ClobberRefs.resize(NumClobbers);
-  for (unsigned i = 0; i != NumClobbers; ++i)
-    ClobberRefs[i] = StringRef(Clobbers[i]);
-
-  // Recast the void pointers and build the vector of constraint StringRefs.
-  unsigned NumExprs = NumOutputs + NumInputs;
-  ConstraintRefs.resize(NumExprs);
-  Exprs.resize(NumExprs);
-  for (unsigned i = 0, e = NumExprs; i != e; ++i) {
-    Expr *OpExpr = static_cast<Expr *>(OpExprs[i].first);
-    if (!OpExpr)
-      return StmtError();
-
-    // Need address of variable.
-    if (OpExprs[i].second)
-      OpExpr = Actions.BuildUnaryOp(getCurScope(), AsmLoc, UO_AddrOf, OpExpr)
-        .take();
-
-    ConstraintRefs[i] = StringRef(Constraints[i]);
-    Exprs[i] = OpExpr;
-  }
-
-  // FIXME: We should be passing source locations for better diagnostics.
-  return Actions.ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, AsmStringIR,
-                                NumOutputs, NumInputs,
-                                ConstraintRefs, ClobberRefs, Exprs, EndLoc);
-}
-
-/// ParseAsmStatement - Parse a GNU extended asm statement.
-///       asm-statement:
-///         gnu-asm-statement
-///         ms-asm-statement
-///
-/// [GNU] gnu-asm-statement:
-///         'asm' type-qualifier[opt] '(' asm-argument ')' ';'
-///
-/// [GNU] asm-argument:
-///         asm-string-literal
-///         asm-string-literal ':' asm-operands[opt]
-///         asm-string-literal ':' asm-operands[opt] ':' asm-operands[opt]
-///         asm-string-literal ':' asm-operands[opt] ':' asm-operands[opt]
-///                 ':' asm-clobbers
-///
-/// [GNU] asm-clobbers:
-///         asm-string-literal
-///         asm-clobbers ',' asm-string-literal
-///
-StmtResult Parser::ParseAsmStatement(bool &msAsm) {
-  assert(Tok.is(tok::kw_asm) && "Not an asm stmt");
-  SourceLocation AsmLoc = ConsumeToken();
-
-  if (getLangOpts().AsmBlocks && Tok.isNot(tok::l_paren) &&
-      !isTypeQualifier()) {
-    msAsm = true;
-    return ParseMicrosoftAsmStatement(AsmLoc);
-  }
-  DeclSpec DS(AttrFactory);
-  SourceLocation Loc = Tok.getLocation();
-  ParseTypeQualifierListOpt(DS, true, false);
-
-  // GNU asms accept, but warn, about type-qualifiers other than volatile.
-  if (DS.getTypeQualifiers() & DeclSpec::TQ_const)
-    Diag(Loc, diag::w_asm_qualifier_ignored) << "const";
-  if (DS.getTypeQualifiers() & DeclSpec::TQ_restrict)
-    Diag(Loc, diag::w_asm_qualifier_ignored) << "restrict";
-  // FIXME: Once GCC supports _Atomic, check whether it permits it here.
-  if (DS.getTypeQualifiers() & DeclSpec::TQ_atomic)
-    Diag(Loc, diag::w_asm_qualifier_ignored) << "_Atomic";
-
-  // Remember if this was a volatile asm.
-  bool isVolatile = DS.getTypeQualifiers() & DeclSpec::TQ_volatile;
-  if (Tok.isNot(tok::l_paren)) {
-    Diag(Tok, diag::err_expected_lparen_after) << "asm";
-    SkipUntil(tok::r_paren, StopAtSemi);
-    return StmtError();
-  }
-  BalancedDelimiterTracker T(*this, tok::l_paren);
-  T.consumeOpen();
-
-  ExprResult AsmString(ParseAsmStringLiteral());
-  if (AsmString.isInvalid()) {
-    // Consume up to and including the closing paren.
-    T.skipToEnd();
-    return StmtError();
-  }
-
-  SmallVector<IdentifierInfo *, 4> Names;
-  ExprVector Constraints;
-  ExprVector Exprs;
-  ExprVector Clobbers;
-
-  if (Tok.is(tok::r_paren)) {
-    // We have a simple asm expression like 'asm("foo")'.
-    T.consumeClose();
-    return Actions.ActOnGCCAsmStmt(AsmLoc, /*isSimple*/ true, isVolatile,
-                                   /*NumOutputs*/ 0, /*NumInputs*/ 0, 0,
-                                   Constraints, Exprs, AsmString.take(),
-                                   Clobbers, T.getCloseLocation());
-  }
-
-  // Parse Outputs, if present.
-  bool AteExtraColon = false;
-  if (Tok.is(tok::colon) || Tok.is(tok::coloncolon)) {
-    // In C++ mode, parse "::" like ": :".
-    AteExtraColon = Tok.is(tok::coloncolon);
+  // Get loop hints and consume annotated token.
+  while (Tok.is(tok::annot_pragma_loop_hint)) {
+    LoopHint Hint = HandlePragmaLoopHint();
     ConsumeToken();
 
-    if (!AteExtraColon &&
-        ParseAsmOperandsOpt(Names, Constraints, Exprs))
-      return StmtError();
+    ArgsUnion ArgHints[] = {Hint.PragmaNameLoc, Hint.OptionLoc, Hint.ValueLoc,
+                            ArgsUnion(Hint.ValueExpr)};
+    TempAttrs.addNew(Hint.PragmaNameLoc->Ident, Hint.Range, nullptr,
+                     Hint.PragmaNameLoc->Loc, ArgHints, 4,
+                     AttributeList::AS_Pragma);
   }
 
-  unsigned NumOutputs = Names.size();
+  // Get the next statement.
+  MaybeParseCXX11Attributes(Attrs);
 
-  // Parse Inputs, if present.
-  if (AteExtraColon ||
-      Tok.is(tok::colon) || Tok.is(tok::coloncolon)) {
-    // In C++ mode, parse "::" like ": :".
-    if (AteExtraColon)
-      AteExtraColon = false;
-    else {
-      AteExtraColon = Tok.is(tok::coloncolon);
-      ConsumeToken();
-    }
+  StmtResult S = ParseStatementOrDeclarationAfterAttributes(
+      Stmts, OnlyStatement, TrailingElseLoc, Attrs);
 
-    if (!AteExtraColon &&
-        ParseAsmOperandsOpt(Names, Constraints, Exprs))
-      return StmtError();
-  }
-
-  assert(Names.size() == Constraints.size() &&
-         Constraints.size() == Exprs.size() &&
-         "Input operand size mismatch!");
-
-  unsigned NumInputs = Names.size() - NumOutputs;
-
-  // Parse the clobbers, if present.
-  if (AteExtraColon || Tok.is(tok::colon)) {
-    if (!AteExtraColon)
-      ConsumeToken();
-
-    // Parse the asm-string list for clobbers if present.
-    if (Tok.isNot(tok::r_paren)) {
-      while (1) {
-        ExprResult Clobber(ParseAsmStringLiteral());
-
-        if (Clobber.isInvalid())
-          break;
-
-        Clobbers.push_back(Clobber.release());
-
-        if (Tok.isNot(tok::comma)) break;
-        ConsumeToken();
-      }
-    }
-  }
-
-  T.consumeClose();
-  return Actions.ActOnGCCAsmStmt(AsmLoc, false, isVolatile, NumOutputs,
-                                 NumInputs, Names.data(), Constraints, Exprs,
-                                 AsmString.take(), Clobbers,
-                                 T.getCloseLocation());
-}
-
-/// ParseAsmOperands - Parse the asm-operands production as used by
-/// asm-statement, assuming the leading ':' token was eaten.
-///
-/// [GNU] asm-operands:
-///         asm-operand
-///         asm-operands ',' asm-operand
-///
-/// [GNU] asm-operand:
-///         asm-string-literal '(' expression ')'
-///         '[' identifier ']' asm-string-literal '(' expression ')'
-///
-//
-// FIXME: Avoid unnecessary std::string trashing.
-bool Parser::ParseAsmOperandsOpt(SmallVectorImpl<IdentifierInfo *> &Names,
-                                 SmallVectorImpl<Expr *> &Constraints,
-                                 SmallVectorImpl<Expr *> &Exprs) {
-  // 'asm-operands' isn't present?
-  if (!isTokenStringLiteral() && Tok.isNot(tok::l_square))
-    return false;
-
-  while (1) {
-    // Read the [id] if present.
-    if (Tok.is(tok::l_square)) {
-      BalancedDelimiterTracker T(*this, tok::l_square);
-      T.consumeOpen();
-
-      if (Tok.isNot(tok::identifier)) {
-        Diag(Tok, diag::err_expected_ident);
-        SkipUntil(tok::r_paren, StopAtSemi);
-        return true;
-      }
-
-      IdentifierInfo *II = Tok.getIdentifierInfo();
-      ConsumeToken();
-
-      Names.push_back(II);
-      T.consumeClose();
-    } else
-      Names.push_back(0);
-
-    ExprResult Constraint(ParseAsmStringLiteral());
-    if (Constraint.isInvalid()) {
-        SkipUntil(tok::r_paren, StopAtSemi);
-        return true;
-    }
-    Constraints.push_back(Constraint.release());
-
-    if (Tok.isNot(tok::l_paren)) {
-      Diag(Tok, diag::err_expected_lparen_after) << "asm operand";
-      SkipUntil(tok::r_paren, StopAtSemi);
-      return true;
-    }
-
-    // Read the parenthesized expression.
-    BalancedDelimiterTracker T(*this, tok::l_paren);
-    T.consumeOpen();
-    ExprResult Res(ParseExpression());
-    T.consumeClose();
-    if (Res.isInvalid()) {
-      SkipUntil(tok::r_paren, StopAtSemi);
-      return true;
-    }
-    Exprs.push_back(Res.release());
-    // Eat the comma and continue parsing if it exists.
-    if (Tok.isNot(tok::comma)) return false;
-    ConsumeToken();
-  }
+  Attrs.takeAllFrom(TempAttrs);
+  return S;
 }
 
 Decl *Parser::ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope) {
@@ -2464,7 +1880,7 @@
   }
 
   BodyScope.Exit();
-  return Actions.ActOnFinishFunctionBody(Decl, FnBody.take());
+  return Actions.ActOnFinishFunctionBody(Decl, FnBody.get());
 }
 
 /// ParseFunctionTryBlock - Parse a C++ function-try-block.
@@ -2501,7 +1917,7 @@
   }
 
   BodyScope.Exit();
-  return Actions.ActOnFinishFunctionBody(Decl, FnBody.take());
+  return Actions.ActOnFinishFunctionBody(Decl, FnBody.get());
 }
 
 bool Parser::trySkippingFunctionBody() {
@@ -2554,16 +1970,28 @@
 ///
 ///       [Borland] try-block:
 ///         'try' compound-statement seh-except-block
-///         'try' compound-statment  seh-finally-block
+///         'try' compound-statement seh-finally-block
 ///
 StmtResult Parser::ParseCXXTryBlockCommon(SourceLocation TryLoc, bool FnTry) {
   if (Tok.isNot(tok::l_brace))
-    return StmtError(Diag(Tok, diag::err_expected_lbrace));
+    return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);
   // FIXME: Possible draft standard bug: attribute-specifier should be allowed?
 
-  StmtResult TryBlock(ParseCompoundStatement(/*isStmtExpr=*/false,
-                      Scope::DeclScope | Scope::TryScope |
-                        (FnTry ? Scope::FnTryCatchScope : 0)));
+  int SEHTryIndex, SEHTryParentIndex;
+  StmtResult TryBlock;
+  {
+    assert(Tok.is(tok::l_brace) && "Not a compount stmt!");
+
+    // Enter a scope to hold everything within the compound stmt.  Compound
+    // statements can always hold declarations.
+    ParseScope CompoundScope(this, Scope::DeclScope | Scope::TryScope |
+                                       (FnTry ? Scope::FnTryCatchScope : 0));
+    SEHTryIndex = getCurScope()->getSEHTryIndex();
+    SEHTryParentIndex = getCurScope()->getSEHTryParentIndex();
+
+    // Parse the statements in the body.
+    TryBlock = ParseCompoundStatementBody();
+  }
   if (TryBlock.isInvalid())
     return TryBlock;
 
@@ -2587,8 +2015,10 @@
 
     return Actions.ActOnSEHTryBlock(true /* IsCXXTry */,
                                     TryLoc,
-                                    TryBlock.take(),
-                                    Handler.take());
+                                    TryBlock.get(),
+                                    Handler.get(),
+                                    SEHTryIndex,
+                                    SEHTryParentIndex);
   }
   else {
     StmtVector Handlers;
@@ -2602,14 +2032,14 @@
     while (Tok.is(tok::kw_catch)) {
       StmtResult Handler(ParseCXXCatchBlock(FnTry));
       if (!Handler.isInvalid())
-        Handlers.push_back(Handler.release());
+        Handlers.push_back(Handler.get());
     }
     // Don't bother creating the full statement if we don't have any usable
     // handlers.
     if (Handlers.empty())
       return StmtError();
 
-    return Actions.ActOnCXXTryBlock(TryLoc, TryBlock.take(), Handlers);
+    return Actions.ActOnCXXTryBlock(TryLoc, TryBlock.get(), Handlers);
   }
 }
 
@@ -2629,7 +2059,7 @@
   SourceLocation CatchLoc = ConsumeToken();
 
   BalancedDelimiterTracker T(*this, tok::l_paren);
-  if (T.expectAndConsume(diag::err_expected_lparen))
+  if (T.expectAndConsume())
     return StmtError();
 
   // C++ 3.3.2p3:
@@ -2640,7 +2070,7 @@
 
   // exception-declaration is equivalent to '...' or a parameter-declaration
   // without default arguments.
-  Decl *ExceptionDecl = 0;
+  Decl *ExceptionDecl = nullptr;
   if (Tok.isNot(tok::ellipsis)) {
     ParsedAttributesWithRange Attributes(AttrFactory);
     MaybeParseCXX11Attributes(Attributes);
@@ -2662,14 +2092,14 @@
     return StmtError();
 
   if (Tok.isNot(tok::l_brace))
-    return StmtError(Diag(Tok, diag::err_expected_lbrace));
+    return StmtError(Diag(Tok, diag::err_expected) << tok::l_brace);
 
   // FIXME: Possible draft standard bug: attribute-specifier should be allowed?
   StmtResult Block(ParseCompoundStatement());
   if (Block.isInvalid())
     return Block;
 
-  return Actions.ActOnCXXCatchBlock(CatchLoc, ExceptionDecl, Block.take());
+  return Actions.ActOnCXXCatchBlock(CatchLoc, ExceptionDecl, Block.get());
 }
 
 void Parser::ParseMicrosoftIfExistsStatement(StmtVector &Stmts) {
@@ -2683,7 +2113,7 @@
   // inside these braces escaping to the surrounding code.
   if (Result.Behavior == IEB_Dependent) {
     if (!Tok.is(tok::l_brace)) {
-      Diag(Tok, diag::err_expected_lbrace);
+      Diag(Tok, diag::err_expected) << tok::l_brace;
       return;
     }
 
@@ -2703,7 +2133,7 @@
 
   BalancedDelimiterTracker Braces(*this, tok::l_brace);
   if (Braces.consumeOpen()) {
-    Diag(Tok, diag::err_expected_lbrace);
+    Diag(Tok, diag::err_expected) << tok::l_brace;
     return;
   }
 
@@ -2724,7 +2154,7 @@
   while (Tok.isNot(tok::r_brace)) {
     StmtResult R = ParseStatementOrDeclaration(Stmts, false);
     if (R.isUsable())
-      Stmts.push_back(R.release());
+      Stmts.push_back(R.get());
   }
   Braces.consumeClose();
 }
diff --git a/lib/Parse/ParseStmtAsm.cpp b/lib/Parse/ParseStmtAsm.cpp
new file mode 100644
index 0000000..f7e8307
--- /dev/null
+++ b/lib/Parse/ParseStmtAsm.cpp
@@ -0,0 +1,761 @@
+//===---- ParseStmtAsm.cpp - Assembly Statement Parser --------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements parsing for GCC and Microsoft inline assembly. 
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Parse/Parser.h"
+#include "RAIIObjectsForParser.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCInstPrinter.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCObjectFileInfo.h"
+#include "llvm/MC/MCParser/MCAsmParser.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/MC/MCTargetAsmParser.h"
+#include "llvm/MC/MCTargetOptions.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
+using namespace clang;
+
+namespace {
+class ClangAsmParserCallback : public llvm::MCAsmParserSemaCallback {
+  Parser &TheParser;
+  SourceLocation AsmLoc;
+  StringRef AsmString;
+
+  /// The tokens we streamed into AsmString and handed off to MC.
+  ArrayRef<Token> AsmToks;
+
+  /// The offset of each token in AsmToks within AsmString.
+  ArrayRef<unsigned> AsmTokOffsets;
+
+public:
+  ClangAsmParserCallback(Parser &P, SourceLocation Loc, StringRef AsmString,
+                         ArrayRef<Token> Toks, ArrayRef<unsigned> Offsets)
+      : TheParser(P), AsmLoc(Loc), AsmString(AsmString), AsmToks(Toks),
+        AsmTokOffsets(Offsets) {
+    assert(AsmToks.size() == AsmTokOffsets.size());
+  }
+
+  void *LookupInlineAsmIdentifier(StringRef &LineBuf,
+                                  llvm::InlineAsmIdentifierInfo &Info,
+                                  bool IsUnevaluatedContext) override {
+    // Collect the desired tokens.
+    SmallVector<Token, 16> LineToks;
+    const Token *FirstOrigToken = nullptr;
+    findTokensForString(LineBuf, LineToks, FirstOrigToken);
+
+    unsigned NumConsumedToks;
+    ExprResult Result = TheParser.ParseMSAsmIdentifier(
+        LineToks, NumConsumedToks, &Info, IsUnevaluatedContext);
+
+    // If we consumed the entire line, tell MC that.
+    // Also do this if we consumed nothing as a way of reporting failure.
+    if (NumConsumedToks == 0 || NumConsumedToks == LineToks.size()) {
+      // By not modifying LineBuf, we're implicitly consuming it all.
+
+      // Otherwise, consume up to the original tokens.
+    } else {
+      assert(FirstOrigToken && "not using original tokens?");
+
+      // Since we're using original tokens, apply that offset.
+      assert(FirstOrigToken[NumConsumedToks].getLocation() ==
+             LineToks[NumConsumedToks].getLocation());
+      unsigned FirstIndex = FirstOrigToken - AsmToks.begin();
+      unsigned LastIndex = FirstIndex + NumConsumedToks - 1;
+
+      // The total length we've consumed is the relative offset
+      // of the last token we consumed plus its length.
+      unsigned TotalOffset =
+          (AsmTokOffsets[LastIndex] + AsmToks[LastIndex].getLength() -
+           AsmTokOffsets[FirstIndex]);
+      LineBuf = LineBuf.substr(0, TotalOffset);
+    }
+
+    // Initialize the "decl" with the lookup result.
+    Info.OpDecl = static_cast<void *>(Result.get());
+    return Info.OpDecl;
+  }
+
+  bool LookupInlineAsmField(StringRef Base, StringRef Member,
+                            unsigned &Offset) override {
+    return TheParser.getActions().LookupInlineAsmField(Base, Member, Offset,
+                                                       AsmLoc);
+  }
+
+  static void DiagHandlerCallback(const llvm::SMDiagnostic &D, void *Context) {
+    ((ClangAsmParserCallback *)Context)->handleDiagnostic(D);
+  }
+
+private:
+  /// Collect the appropriate tokens for the given string.
+  void findTokensForString(StringRef Str, SmallVectorImpl<Token> &TempToks,
+                           const Token *&FirstOrigToken) const {
+    // For now, assert that the string we're working with is a substring
+    // of what we gave to MC.  This lets us use the original tokens.
+    assert(!std::less<const char *>()(Str.begin(), AsmString.begin()) &&
+           !std::less<const char *>()(AsmString.end(), Str.end()));
+
+    // Try to find a token whose offset matches the first token.
+    unsigned FirstCharOffset = Str.begin() - AsmString.begin();
+    const unsigned *FirstTokOffset = std::lower_bound(
+        AsmTokOffsets.begin(), AsmTokOffsets.end(), FirstCharOffset);
+
+    // For now, assert that the start of the string exactly
+    // corresponds to the start of a token.
+    assert(*FirstTokOffset == FirstCharOffset);
+
+    // Use all the original tokens for this line.  (We assume the
+    // end of the line corresponds cleanly to a token break.)
+    unsigned FirstTokIndex = FirstTokOffset - AsmTokOffsets.begin();
+    FirstOrigToken = &AsmToks[FirstTokIndex];
+    unsigned LastCharOffset = Str.end() - AsmString.begin();
+    for (unsigned i = FirstTokIndex, e = AsmTokOffsets.size(); i != e; ++i) {
+      if (AsmTokOffsets[i] >= LastCharOffset)
+        break;
+      TempToks.push_back(AsmToks[i]);
+    }
+  }
+
+  void handleDiagnostic(const llvm::SMDiagnostic &D) {
+    // Compute an offset into the inline asm buffer.
+    // FIXME: This isn't right if .macro is involved (but hopefully, no
+    // real-world code does that).
+    const llvm::SourceMgr &LSM = *D.getSourceMgr();
+    const llvm::MemoryBuffer *LBuf =
+        LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc()));
+    unsigned Offset = D.getLoc().getPointer() - LBuf->getBufferStart();
+
+    // Figure out which token that offset points into.
+    const unsigned *TokOffsetPtr =
+        std::lower_bound(AsmTokOffsets.begin(), AsmTokOffsets.end(), Offset);
+    unsigned TokIndex = TokOffsetPtr - AsmTokOffsets.begin();
+    unsigned TokOffset = *TokOffsetPtr;
+
+    // If we come up with an answer which seems sane, use it; otherwise,
+    // just point at the __asm keyword.
+    // FIXME: Assert the answer is sane once we handle .macro correctly.
+    SourceLocation Loc = AsmLoc;
+    if (TokIndex < AsmToks.size()) {
+      const Token &Tok = AsmToks[TokIndex];
+      Loc = Tok.getLocation();
+      Loc = Loc.getLocWithOffset(Offset - TokOffset);
+    }
+    TheParser.Diag(Loc, diag::err_inline_ms_asm_parsing) << D.getMessage();
+  }
+};
+}
+
+/// Parse an identifier in an MS-style inline assembly block.
+///
+/// \param CastInfo - a void* so that we don't have to teach Parser.h
+///   about the actual type.
+ExprResult Parser::ParseMSAsmIdentifier(llvm::SmallVectorImpl<Token> &LineToks,
+                                        unsigned &NumLineToksConsumed,
+                                        void *CastInfo,
+                                        bool IsUnevaluatedContext) {
+  llvm::InlineAsmIdentifierInfo &Info =
+      *(llvm::InlineAsmIdentifierInfo *)CastInfo;
+
+  // Push a fake token on the end so that we don't overrun the token
+  // stream.  We use ';' because it expression-parsing should never
+  // overrun it.
+  const tok::TokenKind EndOfStream = tok::semi;
+  Token EndOfStreamTok;
+  EndOfStreamTok.startToken();
+  EndOfStreamTok.setKind(EndOfStream);
+  LineToks.push_back(EndOfStreamTok);
+
+  // Also copy the current token over.
+  LineToks.push_back(Tok);
+
+  PP.EnterTokenStream(LineToks.begin(), LineToks.size(),
+                      /*disable macros*/ true,
+                      /*owns tokens*/ false);
+
+  // Clear the current token and advance to the first token in LineToks.
+  ConsumeAnyToken();
+
+  // Parse an optional scope-specifier if we're in C++.
+  CXXScopeSpec SS;
+  if (getLangOpts().CPlusPlus) {
+    ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false);
+  }
+
+  // Require an identifier here.
+  SourceLocation TemplateKWLoc;
+  UnqualifiedId Id;
+  bool Invalid =
+      ParseUnqualifiedId(SS,
+                         /*EnteringContext=*/false,
+                         /*AllowDestructorName=*/false,
+                         /*AllowConstructorName=*/false,
+                         /*ObjectType=*/ParsedType(), TemplateKWLoc, Id);
+
+  // Figure out how many tokens we are into LineToks.
+  unsigned LineIndex = 0;
+  if (Tok.is(EndOfStream)) {
+    LineIndex = LineToks.size() - 2;
+  } else {
+    while (LineToks[LineIndex].getLocation() != Tok.getLocation()) {
+      LineIndex++;
+      assert(LineIndex < LineToks.size() - 2); // we added two extra tokens
+    }
+  }
+
+  // If we've run into the poison token we inserted before, or there
+  // was a parsing error, then claim the entire line.
+  if (Invalid || Tok.is(EndOfStream)) {
+    NumLineToksConsumed = LineToks.size() - 2;
+  } else {
+    // Otherwise, claim up to the start of the next token.
+    NumLineToksConsumed = LineIndex;
+  }
+
+  // Finally, restore the old parsing state by consuming all the tokens we
+  // staged before, implicitly killing off the token-lexer we pushed.
+  for (unsigned i = 0, e = LineToks.size() - LineIndex - 2; i != e; ++i) {
+    ConsumeAnyToken();
+  }
+  assert(Tok.is(EndOfStream));
+  ConsumeToken();
+
+  // Leave LineToks in its original state.
+  LineToks.pop_back();
+  LineToks.pop_back();
+
+  // Perform the lookup.
+  return Actions.LookupInlineAsmIdentifier(SS, TemplateKWLoc, Id, Info,
+                                           IsUnevaluatedContext);
+}
+
+/// Turn a sequence of our tokens back into a string that we can hand
+/// to the MC asm parser.
+static bool buildMSAsmString(Preprocessor &PP, SourceLocation AsmLoc,
+                             ArrayRef<Token> AsmToks,
+                             SmallVectorImpl<unsigned> &TokOffsets,
+                             SmallString<512> &Asm) {
+  assert(!AsmToks.empty() && "Didn't expect an empty AsmToks!");
+
+  // Is this the start of a new assembly statement?
+  bool isNewStatement = true;
+
+  for (unsigned i = 0, e = AsmToks.size(); i < e; ++i) {
+    const Token &Tok = AsmToks[i];
+
+    // Start each new statement with a newline and a tab.
+    if (!isNewStatement && (Tok.is(tok::kw_asm) || Tok.isAtStartOfLine())) {
+      Asm += "\n\t";
+      isNewStatement = true;
+    }
+
+    // Preserve the existence of leading whitespace except at the
+    // start of a statement.
+    if (!isNewStatement && Tok.hasLeadingSpace())
+      Asm += ' ';
+
+    // Remember the offset of this token.
+    TokOffsets.push_back(Asm.size());
+
+    // Don't actually write '__asm' into the assembly stream.
+    if (Tok.is(tok::kw_asm)) {
+      // Complain about __asm at the end of the stream.
+      if (i + 1 == e) {
+        PP.Diag(AsmLoc, diag::err_asm_empty);
+        return true;
+      }
+
+      continue;
+    }
+
+    // Append the spelling of the token.
+    SmallString<32> SpellingBuffer;
+    bool SpellingInvalid = false;
+    Asm += PP.getSpelling(Tok, SpellingBuffer, &SpellingInvalid);
+    assert(!SpellingInvalid && "spelling was invalid after correct parse?");
+
+    // We are no longer at the start of a statement.
+    isNewStatement = false;
+  }
+
+  // Ensure that the buffer is null-terminated.
+  Asm.push_back('\0');
+  Asm.pop_back();
+
+  assert(TokOffsets.size() == AsmToks.size());
+  return false;
+}
+
+/// ParseMicrosoftAsmStatement. When -fms-extensions/-fasm-blocks is enabled,
+/// this routine is called to collect the tokens for an MS asm statement.
+///
+/// [MS]  ms-asm-statement:
+///         ms-asm-block
+///         ms-asm-block ms-asm-statement
+///
+/// [MS]  ms-asm-block:
+///         '__asm' ms-asm-line '\n'
+///         '__asm' '{' ms-asm-instruction-block[opt] '}' ';'[opt]
+///
+/// [MS]  ms-asm-instruction-block
+///         ms-asm-line
+///         ms-asm-line '\n' ms-asm-instruction-block
+///
+StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) {
+  SourceManager &SrcMgr = PP.getSourceManager();
+  SourceLocation EndLoc = AsmLoc;
+  SmallVector<Token, 4> AsmToks;
+
+  unsigned BraceNesting = 0;
+  unsigned short savedBraceCount = BraceCount;
+  bool InAsmComment = false;
+  FileID FID;
+  unsigned LineNo = 0;
+  unsigned NumTokensRead = 0;
+  SmallVector<SourceLocation, 4> LBraceLocs;
+  bool SkippedStartOfLine = false;
+
+  if (Tok.is(tok::l_brace)) {
+    // Braced inline asm: consume the opening brace.
+    BraceNesting = 1;
+    EndLoc = ConsumeBrace();
+    LBraceLocs.push_back(EndLoc);
+    ++NumTokensRead;
+  } else {
+    // Single-line inline asm; compute which line it is on.
+    std::pair<FileID, unsigned> ExpAsmLoc =
+        SrcMgr.getDecomposedExpansionLoc(EndLoc);
+    FID = ExpAsmLoc.first;
+    LineNo = SrcMgr.getLineNumber(FID, ExpAsmLoc.second);
+    LBraceLocs.push_back(SourceLocation());
+  }
+
+  SourceLocation TokLoc = Tok.getLocation();
+  do {
+    // If we hit EOF, we're done, period.
+    if (isEofOrEom())
+      break;
+
+    if (!InAsmComment && Tok.is(tok::l_brace)) {
+      // Consume the opening brace.
+      SkippedStartOfLine = Tok.isAtStartOfLine();
+      EndLoc = ConsumeBrace();
+      BraceNesting++;
+      LBraceLocs.push_back(EndLoc);
+      TokLoc = Tok.getLocation();
+      ++NumTokensRead;
+      continue;
+    } else if (!InAsmComment && Tok.is(tok::semi)) {
+      // A semicolon in an asm is the start of a comment.
+      InAsmComment = true;
+      if (BraceNesting) {
+        // Compute which line the comment is on.
+        std::pair<FileID, unsigned> ExpSemiLoc =
+            SrcMgr.getDecomposedExpansionLoc(TokLoc);
+        FID = ExpSemiLoc.first;
+        LineNo = SrcMgr.getLineNumber(FID, ExpSemiLoc.second);
+      }
+    } else if (!BraceNesting || InAsmComment) {
+      // If end-of-line is significant, check whether this token is on a
+      // new line.
+      std::pair<FileID, unsigned> ExpLoc =
+          SrcMgr.getDecomposedExpansionLoc(TokLoc);
+      if (ExpLoc.first != FID ||
+          SrcMgr.getLineNumber(ExpLoc.first, ExpLoc.second) != LineNo) {
+        // If this is a single-line __asm, we're done.
+        if (!BraceNesting)
+          break;
+        // We're no longer in a comment.
+        InAsmComment = false;
+      } else if (!InAsmComment && Tok.is(tok::r_brace)) {
+        // Single-line asm always ends when a closing brace is seen.
+        // FIXME: This is compatible with Apple gcc's -fasm-blocks; what
+        // does MSVC do here?
+        break;
+      }
+    }
+    if (!InAsmComment && BraceNesting && Tok.is(tok::r_brace) &&
+        BraceCount == (savedBraceCount + BraceNesting)) {
+      // Consume the closing brace.
+      SkippedStartOfLine = Tok.isAtStartOfLine();
+      EndLoc = ConsumeBrace();
+      BraceNesting--;
+      // Finish if all of the opened braces in the inline asm section were
+      // consumed.
+      if (BraceNesting == 0)
+        break;
+      else {
+        LBraceLocs.pop_back();
+        TokLoc = Tok.getLocation();
+        ++NumTokensRead;
+        continue;
+      }
+    }
+
+    // Consume the next token; make sure we don't modify the brace count etc.
+    // if we are in a comment.
+    EndLoc = TokLoc;
+    if (InAsmComment)
+      PP.Lex(Tok);
+    else {
+      // Set the token as the start of line if we skipped the original start
+      // of line token in case it was a nested brace.
+      if (SkippedStartOfLine)
+        Tok.setFlag(Token::StartOfLine);
+      AsmToks.push_back(Tok);
+      ConsumeAnyToken();
+    }
+    TokLoc = Tok.getLocation();
+    ++NumTokensRead;
+    SkippedStartOfLine = false;
+  } while (1);
+
+  if (BraceNesting && BraceCount != savedBraceCount) {
+    // __asm without closing brace (this can happen at EOF).
+    for (unsigned i = 0; i < BraceNesting; ++i) {
+      Diag(Tok, diag::err_expected) << tok::r_brace;
+      Diag(LBraceLocs.back(), diag::note_matching) << tok::l_brace;
+      LBraceLocs.pop_back();
+    }
+    return StmtError();
+  } else if (NumTokensRead == 0) {
+    // Empty __asm.
+    Diag(Tok, diag::err_expected) << tok::l_brace;
+    return StmtError();
+  }
+
+  // Okay, prepare to use MC to parse the assembly.
+  SmallVector<StringRef, 4> ConstraintRefs;
+  SmallVector<Expr *, 4> Exprs;
+  SmallVector<StringRef, 4> ClobberRefs;
+
+  // We need an actual supported target.
+  const llvm::Triple &TheTriple = Actions.Context.getTargetInfo().getTriple();
+  llvm::Triple::ArchType ArchTy = TheTriple.getArch();
+  const std::string &TT = TheTriple.getTriple();
+  const llvm::Target *TheTarget = nullptr;
+  bool UnsupportedArch =
+      (ArchTy != llvm::Triple::x86 && ArchTy != llvm::Triple::x86_64);
+  if (UnsupportedArch) {
+    Diag(AsmLoc, diag::err_msasm_unsupported_arch) << TheTriple.getArchName();
+  } else {
+    std::string Error;
+    TheTarget = llvm::TargetRegistry::lookupTarget(TT, Error);
+    if (!TheTarget)
+      Diag(AsmLoc, diag::err_msasm_unable_to_create_target) << Error;
+  }
+
+  assert(!LBraceLocs.empty() && "Should have at least one location here");
+
+  // If we don't support assembly, or the assembly is empty, we don't
+  // need to instantiate the AsmParser, etc.
+  if (!TheTarget || AsmToks.empty()) {
+    return Actions.ActOnMSAsmStmt(AsmLoc, LBraceLocs[0], AsmToks, StringRef(),
+                                  /*NumOutputs*/ 0, /*NumInputs*/ 0,
+                                  ConstraintRefs, ClobberRefs, Exprs, EndLoc);
+  }
+
+  // Expand the tokens into a string buffer.
+  SmallString<512> AsmString;
+  SmallVector<unsigned, 8> TokOffsets;
+  if (buildMSAsmString(PP, AsmLoc, AsmToks, TokOffsets, AsmString))
+    return StmtError();
+
+  std::unique_ptr<llvm::MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TT));
+  std::unique_ptr<llvm::MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, TT));
+  // Get the instruction descriptor.
+  std::unique_ptr<llvm::MCInstrInfo> MII(TheTarget->createMCInstrInfo());
+  std::unique_ptr<llvm::MCObjectFileInfo> MOFI(new llvm::MCObjectFileInfo());
+  std::unique_ptr<llvm::MCSubtargetInfo> STI(
+      TheTarget->createMCSubtargetInfo(TT, "", ""));
+
+  llvm::SourceMgr TempSrcMgr;
+  llvm::MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &TempSrcMgr);
+  llvm::MemoryBuffer *Buffer =
+      llvm::MemoryBuffer::getMemBuffer(AsmString, "<MS inline asm>");
+
+  // Tell SrcMgr about this buffer, which is what the parser will pick up.
+  TempSrcMgr.AddNewSourceBuffer(Buffer, llvm::SMLoc());
+
+  std::unique_ptr<llvm::MCStreamer> Str(createNullStreamer(Ctx));
+  std::unique_ptr<llvm::MCAsmParser> Parser(
+      createMCAsmParser(TempSrcMgr, Ctx, *Str.get(), *MAI));
+
+  // FIXME: init MCOptions from sanitizer flags here.
+  llvm::MCTargetOptions MCOptions;
+  std::unique_ptr<llvm::MCTargetAsmParser> TargetParser(
+      TheTarget->createMCAsmParser(*STI, *Parser, *MII, MCOptions));
+
+  std::unique_ptr<llvm::MCInstPrinter> IP(
+      TheTarget->createMCInstPrinter(1, *MAI, *MII, *MRI, *STI));
+
+  // Change to the Intel dialect.
+  Parser->setAssemblerDialect(1);
+  Parser->setTargetParser(*TargetParser.get());
+  Parser->setParsingInlineAsm(true);
+  TargetParser->setParsingInlineAsm(true);
+
+  ClangAsmParserCallback Callback(*this, AsmLoc, AsmString, AsmToks,
+                                  TokOffsets);
+  TargetParser->setSemaCallback(&Callback);
+  TempSrcMgr.setDiagHandler(ClangAsmParserCallback::DiagHandlerCallback,
+                            &Callback);
+
+  unsigned NumOutputs;
+  unsigned NumInputs;
+  std::string AsmStringIR;
+  SmallVector<std::pair<void *, bool>, 4> OpExprs;
+  SmallVector<std::string, 4> Constraints;
+  SmallVector<std::string, 4> Clobbers;
+  if (Parser->parseMSInlineAsm(AsmLoc.getPtrEncoding(), AsmStringIR, NumOutputs,
+                               NumInputs, OpExprs, Constraints, Clobbers,
+                               MII.get(), IP.get(), Callback))
+    return StmtError();
+
+  // Filter out "fpsw".  Clang doesn't accept it, and it always lists flags and
+  // fpsr as clobbers.
+  auto End = std::remove(Clobbers.begin(), Clobbers.end(), "fpsw");
+  Clobbers.erase(End, Clobbers.end());
+
+  // Build the vector of clobber StringRefs.
+  ClobberRefs.insert(ClobberRefs.end(), Clobbers.begin(), Clobbers.end());
+
+  // Recast the void pointers and build the vector of constraint StringRefs.
+  unsigned NumExprs = NumOutputs + NumInputs;
+  ConstraintRefs.resize(NumExprs);
+  Exprs.resize(NumExprs);
+  for (unsigned i = 0, e = NumExprs; i != e; ++i) {
+    Expr *OpExpr = static_cast<Expr *>(OpExprs[i].first);
+    if (!OpExpr)
+      return StmtError();
+
+    // Need address of variable.
+    if (OpExprs[i].second)
+      OpExpr =
+          Actions.BuildUnaryOp(getCurScope(), AsmLoc, UO_AddrOf, OpExpr).get();
+
+    ConstraintRefs[i] = StringRef(Constraints[i]);
+    Exprs[i] = OpExpr;
+  }
+
+  // FIXME: We should be passing source locations for better diagnostics.
+  return Actions.ActOnMSAsmStmt(AsmLoc, LBraceLocs[0], AsmToks, AsmStringIR,
+                                NumOutputs, NumInputs, ConstraintRefs,
+                                ClobberRefs, Exprs, EndLoc);
+}
+
+/// ParseAsmStatement - Parse a GNU extended asm statement.
+///       asm-statement:
+///         gnu-asm-statement
+///         ms-asm-statement
+///
+/// [GNU] gnu-asm-statement:
+///         'asm' type-qualifier[opt] '(' asm-argument ')' ';'
+///
+/// [GNU] asm-argument:
+///         asm-string-literal
+///         asm-string-literal ':' asm-operands[opt]
+///         asm-string-literal ':' asm-operands[opt] ':' asm-operands[opt]
+///         asm-string-literal ':' asm-operands[opt] ':' asm-operands[opt]
+///                 ':' asm-clobbers
+///
+/// [GNU] asm-clobbers:
+///         asm-string-literal
+///         asm-clobbers ',' asm-string-literal
+///
+StmtResult Parser::ParseAsmStatement(bool &msAsm) {
+  assert(Tok.is(tok::kw_asm) && "Not an asm stmt");
+  SourceLocation AsmLoc = ConsumeToken();
+
+  if (getLangOpts().AsmBlocks && Tok.isNot(tok::l_paren) &&
+      !isTypeQualifier()) {
+    msAsm = true;
+    return ParseMicrosoftAsmStatement(AsmLoc);
+  }
+  DeclSpec DS(AttrFactory);
+  SourceLocation Loc = Tok.getLocation();
+  ParseTypeQualifierListOpt(DS, true, false);
+
+  // GNU asms accept, but warn, about type-qualifiers other than volatile.
+  if (DS.getTypeQualifiers() & DeclSpec::TQ_const)
+    Diag(Loc, diag::w_asm_qualifier_ignored) << "const";
+  if (DS.getTypeQualifiers() & DeclSpec::TQ_restrict)
+    Diag(Loc, diag::w_asm_qualifier_ignored) << "restrict";
+  // FIXME: Once GCC supports _Atomic, check whether it permits it here.
+  if (DS.getTypeQualifiers() & DeclSpec::TQ_atomic)
+    Diag(Loc, diag::w_asm_qualifier_ignored) << "_Atomic";
+
+  // Remember if this was a volatile asm.
+  bool isVolatile = DS.getTypeQualifiers() & DeclSpec::TQ_volatile;
+  if (Tok.isNot(tok::l_paren)) {
+    Diag(Tok, diag::err_expected_lparen_after) << "asm";
+    SkipUntil(tok::r_paren, StopAtSemi);
+    return StmtError();
+  }
+  BalancedDelimiterTracker T(*this, tok::l_paren);
+  T.consumeOpen();
+
+  ExprResult AsmString(ParseAsmStringLiteral());
+  if (AsmString.isInvalid()) {
+    // Consume up to and including the closing paren.
+    T.skipToEnd();
+    return StmtError();
+  }
+
+  SmallVector<IdentifierInfo *, 4> Names;
+  ExprVector Constraints;
+  ExprVector Exprs;
+  ExprVector Clobbers;
+
+  if (Tok.is(tok::r_paren)) {
+    // We have a simple asm expression like 'asm("foo")'.
+    T.consumeClose();
+    return Actions.ActOnGCCAsmStmt(AsmLoc, /*isSimple*/ true, isVolatile,
+                                   /*NumOutputs*/ 0, /*NumInputs*/ 0, nullptr,
+                                   Constraints, Exprs, AsmString.get(),
+                                   Clobbers, T.getCloseLocation());
+  }
+
+  // Parse Outputs, if present.
+  bool AteExtraColon = false;
+  if (Tok.is(tok::colon) || Tok.is(tok::coloncolon)) {
+    // In C++ mode, parse "::" like ": :".
+    AteExtraColon = Tok.is(tok::coloncolon);
+    ConsumeToken();
+
+    if (!AteExtraColon && ParseAsmOperandsOpt(Names, Constraints, Exprs))
+      return StmtError();
+  }
+
+  unsigned NumOutputs = Names.size();
+
+  // Parse Inputs, if present.
+  if (AteExtraColon || Tok.is(tok::colon) || Tok.is(tok::coloncolon)) {
+    // In C++ mode, parse "::" like ": :".
+    if (AteExtraColon)
+      AteExtraColon = false;
+    else {
+      AteExtraColon = Tok.is(tok::coloncolon);
+      ConsumeToken();
+    }
+
+    if (!AteExtraColon && ParseAsmOperandsOpt(Names, Constraints, Exprs))
+      return StmtError();
+  }
+
+  assert(Names.size() == Constraints.size() &&
+         Constraints.size() == Exprs.size() && "Input operand size mismatch!");
+
+  unsigned NumInputs = Names.size() - NumOutputs;
+
+  // Parse the clobbers, if present.
+  if (AteExtraColon || Tok.is(tok::colon)) {
+    if (!AteExtraColon)
+      ConsumeToken();
+
+    // Parse the asm-string list for clobbers if present.
+    if (Tok.isNot(tok::r_paren)) {
+      while (1) {
+        ExprResult Clobber(ParseAsmStringLiteral());
+
+        if (Clobber.isInvalid())
+          break;
+
+        Clobbers.push_back(Clobber.get());
+
+        if (!TryConsumeToken(tok::comma))
+          break;
+      }
+    }
+  }
+
+  T.consumeClose();
+  return Actions.ActOnGCCAsmStmt(
+      AsmLoc, false, isVolatile, NumOutputs, NumInputs, Names.data(),
+      Constraints, Exprs, AsmString.get(), Clobbers, T.getCloseLocation());
+}
+
+/// ParseAsmOperands - Parse the asm-operands production as used by
+/// asm-statement, assuming the leading ':' token was eaten.
+///
+/// [GNU] asm-operands:
+///         asm-operand
+///         asm-operands ',' asm-operand
+///
+/// [GNU] asm-operand:
+///         asm-string-literal '(' expression ')'
+///         '[' identifier ']' asm-string-literal '(' expression ')'
+///
+//
+// FIXME: Avoid unnecessary std::string trashing.
+bool Parser::ParseAsmOperandsOpt(SmallVectorImpl<IdentifierInfo *> &Names,
+                                 SmallVectorImpl<Expr *> &Constraints,
+                                 SmallVectorImpl<Expr *> &Exprs) {
+  // 'asm-operands' isn't present?
+  if (!isTokenStringLiteral() && Tok.isNot(tok::l_square))
+    return false;
+
+  while (1) {
+    // Read the [id] if present.
+    if (Tok.is(tok::l_square)) {
+      BalancedDelimiterTracker T(*this, tok::l_square);
+      T.consumeOpen();
+
+      if (Tok.isNot(tok::identifier)) {
+        Diag(Tok, diag::err_expected) << tok::identifier;
+        SkipUntil(tok::r_paren, StopAtSemi);
+        return true;
+      }
+
+      IdentifierInfo *II = Tok.getIdentifierInfo();
+      ConsumeToken();
+
+      Names.push_back(II);
+      T.consumeClose();
+    } else
+      Names.push_back(nullptr);
+
+    ExprResult Constraint(ParseAsmStringLiteral());
+    if (Constraint.isInvalid()) {
+      SkipUntil(tok::r_paren, StopAtSemi);
+      return true;
+    }
+    Constraints.push_back(Constraint.get());
+
+    if (Tok.isNot(tok::l_paren)) {
+      Diag(Tok, diag::err_expected_lparen_after) << "asm operand";
+      SkipUntil(tok::r_paren, StopAtSemi);
+      return true;
+    }
+
+    // Read the parenthesized expression.
+    BalancedDelimiterTracker T(*this, tok::l_paren);
+    T.consumeOpen();
+    ExprResult Res(ParseExpression());
+    T.consumeClose();
+    if (Res.isInvalid()) {
+      SkipUntil(tok::r_paren, StopAtSemi);
+      return true;
+    }
+    Exprs.push_back(Res.get());
+    // Eat the comma and continue parsing if it exists.
+    if (!TryConsumeToken(tok::comma))
+      return false;
+  }
+}
diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp
index 076edb9..fa6401f 100644
--- a/lib/Parse/ParseTemplate.cpp
+++ b/lib/Parse/ParseTemplate.cpp
@@ -101,17 +101,13 @@
   do {
     // Consume the 'export', if any.
     SourceLocation ExportLoc;
-    if (Tok.is(tok::kw_export)) {
-      ExportLoc = ConsumeToken();
-    }
+    TryConsumeToken(tok::kw_export, ExportLoc);
 
     // Consume the 'template', which should be here.
     SourceLocation TemplateLoc;
-    if (Tok.is(tok::kw_template)) {
-      TemplateLoc = ConsumeToken();
-    } else {
+    if (!TryConsumeToken(tok::kw_template, TemplateLoc)) {
       Diag(Tok.getLocation(), diag::err_expected_template);
-      return 0;
+      return nullptr;
     }
 
     // Parse the '<' template-parameter-list '>'
@@ -121,9 +117,8 @@
                                 TemplateParams, LAngleLoc, RAngleLoc)) {
       // Skip until the semi-colon or a }.
       SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
-      if (Tok.is(tok::semi))
-        ConsumeToken();
-      return 0;
+      TryConsumeToken(tok::semi);
+      return nullptr;
     }
 
     ParamLists.push_back(
@@ -175,7 +170,7 @@
     // We are parsing a member template.
     ParseCXXClassMemberDeclaration(AS, AccessAttrs, TemplateInfo,
                                    &DiagsFromTParams);
-    return 0;
+    return nullptr;
   }
 
   ParsedAttributesWithRange prefixAttrs(AttrFactory);
@@ -219,7 +214,7 @@
     SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
     if (Tok.is(tok::semi))
       ConsumeToken();
-    return 0;
+    return nullptr;
   }
 
   LateParsedAttrList LateParsedAttrs(true);
@@ -255,8 +250,8 @@
         // Recover as if it were an explicit specialization.
         TemplateParameterLists FakedParamLists;
         FakedParamLists.push_back(Actions.ActOnTemplateParameterList(
-            0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, 0, 0,
-            LAngleLoc));
+            0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, nullptr,
+            0, LAngleLoc));
 
         return ParseFunctionDefinition(
             DeclaratorInfo, ParsedTemplateInfo(&FakedParamLists,
@@ -302,11 +297,10 @@
                                      SourceLocation &LAngleLoc,
                                      SourceLocation &RAngleLoc) {
   // Get the template parameter list.
-  if (!Tok.is(tok::less)) {
+  if (!TryConsumeToken(tok::less, LAngleLoc)) {
     Diag(Tok.getLocation(), diag::err_expected_less_after) << "template";
     return true;
   }
-  LAngleLoc = ConsumeToken();
 
   // Try to parse the template parameter list.
   bool Failed = false;
@@ -322,10 +316,8 @@
     Tok.setKind(tok::greater);
     RAngleLoc = Tok.getLocation();
     Tok.setLocation(Tok.getLocation().getLocWithOffset(1));
-  } else if (Tok.is(tok::greater))
-    RAngleLoc = ConsumeToken();
-  else if (Failed) {
-    Diag(Tok.getLocation(), diag::err_expected_greater);
+  } else if (!TryConsumeToken(tok::greater, RAngleLoc) && Failed) {
+    Diag(Tok.getLocation(), diag::err_expected) << tok::greater;
     return true;
   }
   return false;
@@ -481,12 +473,8 @@
   SourceLocation KeyLoc = ConsumeToken();
 
   // Grab the ellipsis (if given).
-  bool Ellipsis = false;
   SourceLocation EllipsisLoc;
-  if (Tok.is(tok::ellipsis)) {
-    Ellipsis = true;
-    EllipsisLoc = ConsumeToken();
-
+  if (TryConsumeToken(tok::ellipsis, EllipsisLoc)) {
     Diag(EllipsisLoc,
          getLangOpts().CPlusPlus11
            ? diag::warn_cxx98_compat_variadic_templates
@@ -495,7 +483,7 @@
 
   // Grab the template parameter name (if given)
   SourceLocation NameLoc;
-  IdentifierInfo* ParamName = 0;
+  IdentifierInfo *ParamName = nullptr;
   if (Tok.is(tok::identifier)) {
     ParamName = Tok.getIdentifierInfo();
     NameLoc = ConsumeToken();
@@ -504,34 +492,40 @@
     // Unnamed template parameter. Don't have to do anything here, just
     // don't consume this token.
   } else {
-    Diag(Tok.getLocation(), diag::err_expected_ident);
-    return 0;
+    Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
+    return nullptr;
   }
 
+  // Recover from misplaced ellipsis.
+  bool AlreadyHasEllipsis = EllipsisLoc.isValid();
+  if (TryConsumeToken(tok::ellipsis, EllipsisLoc))
+    DiagnoseMisplacedEllipsis(EllipsisLoc, NameLoc, AlreadyHasEllipsis, true);
+
   // Grab a default argument (if available).
   // Per C++0x [basic.scope.pdecl]p9, we parse the default argument before
   // we introduce the type parameter into the local scope.
   SourceLocation EqualLoc;
   ParsedType DefaultArg;
-  if (Tok.is(tok::equal)) {
-    EqualLoc = ConsumeToken();
-    DefaultArg = ParseTypeName(/*Range=*/0,
+  if (TryConsumeToken(tok::equal, EqualLoc))
+    DefaultArg = ParseTypeName(/*Range=*/nullptr,
                                Declarator::TemplateTypeArgContext).get();
-  }
 
-  return Actions.ActOnTypeParameter(getCurScope(), TypenameKeyword, Ellipsis, 
-                                    EllipsisLoc, KeyLoc, ParamName, NameLoc,
-                                    Depth, Position, EqualLoc, DefaultArg);
+  return Actions.ActOnTypeParameter(getCurScope(), TypenameKeyword, EllipsisLoc,
+                                    KeyLoc, ParamName, NameLoc, Depth, Position,
+                                    EqualLoc, DefaultArg);
 }
 
 /// ParseTemplateTemplateParameter - Handle the parsing of template
 /// template parameters.
 ///
 ///       type-parameter:    [C++ temp.param]
-///         'template' '<' template-parameter-list '>' 'class' 
+///         'template' '<' template-parameter-list '>' type-parameter-key
 ///                  ...[opt] identifier[opt]
-///         'template' '<' template-parameter-list '>' 'class' identifier[opt] 
-///                  = id-expression
+///         'template' '<' template-parameter-list '>' type-parameter-key
+///                  identifier[opt] = id-expression
+///       type-parameter-key:
+///         'class'
+///         'typename'       [C++1z]
 Decl *
 Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) {
   assert(Tok.is(tok::kw_template) && "Expected 'template' keyword");
@@ -544,45 +538,50 @@
     ParseScope TemplateParmScope(this, Scope::TemplateParamScope);
     if (ParseTemplateParameters(Depth + 1, TemplateParams, LAngleLoc,
                                RAngleLoc)) {
-      return 0;
+      return nullptr;
     }
   }
 
+  // Provide an ExtWarn if the C++1z feature of using 'typename' here is used.
   // Generate a meaningful error if the user forgot to put class before the
   // identifier, comma, or greater. Provide a fixit if the identifier, comma,
-  // or greater appear immediately or after 'typename' or 'struct'. In the
-  // latter case, replace the keyword with 'class'.
-  if (!Tok.is(tok::kw_class)) {
+  // or greater appear immediately or after 'struct'. In the latter case,
+  // replace the keyword with 'class'.
+  if (!TryConsumeToken(tok::kw_class)) {
     bool Replace = Tok.is(tok::kw_typename) || Tok.is(tok::kw_struct);
-    const Token& Next = Replace ? NextToken() : Tok;
-    if (Next.is(tok::identifier) || Next.is(tok::comma) ||
-        Next.is(tok::greater) || Next.is(tok::greatergreater) ||
-        Next.is(tok::ellipsis))
+    const Token &Next = Tok.is(tok::kw_struct) ? NextToken() : Tok;
+    if (Tok.is(tok::kw_typename)) {
+      Diag(Tok.getLocation(),
+           getLangOpts().CPlusPlus1z
+               ? diag::warn_cxx1y_compat_template_template_param_typename
+               : diag::ext_template_template_param_typename)
+        << (!getLangOpts().CPlusPlus1z
+                ? FixItHint::CreateReplacement(Tok.getLocation(), "class")
+                : FixItHint());
+    } else if (Next.is(tok::identifier) || Next.is(tok::comma) ||
+               Next.is(tok::greater) || Next.is(tok::greatergreater) ||
+               Next.is(tok::ellipsis)) {
       Diag(Tok.getLocation(), diag::err_class_on_template_template_param)
         << (Replace ? FixItHint::CreateReplacement(Tok.getLocation(), "class")
                     : FixItHint::CreateInsertion(Tok.getLocation(), "class "));
-    else
+    } else
       Diag(Tok.getLocation(), diag::err_class_on_template_template_param);
 
     if (Replace)
       ConsumeToken();
-  } else
-    ConsumeToken();
+  }
 
   // Parse the ellipsis, if given.
   SourceLocation EllipsisLoc;
-  if (Tok.is(tok::ellipsis)) {
-    EllipsisLoc = ConsumeToken();
-    
+  if (TryConsumeToken(tok::ellipsis, EllipsisLoc))
     Diag(EllipsisLoc,
          getLangOpts().CPlusPlus11
            ? diag::warn_cxx98_compat_variadic_templates
            : diag::ext_variadic_templates);
-  }
       
   // Get the identifier, if given.
   SourceLocation NameLoc;
-  IdentifierInfo* ParamName = 0;
+  IdentifierInfo *ParamName = nullptr;
   if (Tok.is(tok::identifier)) {
     ParamName = Tok.getIdentifierInfo();
     NameLoc = ConsumeToken();
@@ -591,10 +590,15 @@
     // Unnamed template parameter. Don't have to do anything here, just
     // don't consume this token.
   } else {
-    Diag(Tok.getLocation(), diag::err_expected_ident);
-    return 0;
+    Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
+    return nullptr;
   }
 
+  // Recover from misplaced ellipsis.
+  bool AlreadyHasEllipsis = EllipsisLoc.isValid();
+  if (TryConsumeToken(tok::ellipsis, EllipsisLoc))
+    DiagnoseMisplacedEllipsis(EllipsisLoc, NameLoc, AlreadyHasEllipsis, true);
+
   TemplateParameterList *ParamList =
     Actions.ActOnTemplateParameterList(Depth, SourceLocation(),
                                        TemplateLoc, LAngleLoc,
@@ -607,8 +611,7 @@
   // we introduce the template parameter into the local scope.
   SourceLocation EqualLoc;
   ParsedTemplateArgument DefaultArg;
-  if (Tok.is(tok::equal)) {
-    EqualLoc = ConsumeToken();
+  if (TryConsumeToken(tok::equal, EqualLoc)) {
     DefaultArg = ParseTemplateTemplateArgument();
     if (DefaultArg.isInvalid()) {
       Diag(Tok.getLocation(), 
@@ -643,17 +646,20 @@
   ParseDeclarator(ParamDecl);
   if (DS.getTypeSpecType() == DeclSpec::TST_unspecified) {
     Diag(Tok.getLocation(), diag::err_expected_template_parameter);
-    return 0;
+    return nullptr;
   }
 
+  // Recover from misplaced ellipsis.
+  SourceLocation EllipsisLoc;
+  if (TryConsumeToken(tok::ellipsis, EllipsisLoc))
+    DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, ParamDecl);
+
   // If there is a default value, parse it.
   // Per C++0x [basic.scope.pdecl]p9, we parse the default argument before
   // we introduce the template parameter into the local scope.
   SourceLocation EqualLoc;
   ExprResult DefaultArg;
-  if (Tok.is(tok::equal)) {
-    EqualLoc = ConsumeToken();
-
+  if (TryConsumeToken(tok::equal, EqualLoc)) {
     // C++ [temp.param]p15:
     //   When parsing a default template-argument for a non-type
     //   template-parameter, the first non-nested > is taken as the
@@ -670,7 +676,29 @@
   // Create the parameter.
   return Actions.ActOnNonTypeTemplateParameter(getCurScope(), ParamDecl, 
                                                Depth, Position, EqualLoc, 
-                                               DefaultArg.take());
+                                               DefaultArg.get());
+}
+
+void Parser::DiagnoseMisplacedEllipsis(SourceLocation EllipsisLoc,
+                                       SourceLocation CorrectLoc,
+                                       bool AlreadyHasEllipsis,
+                                       bool IdentifierHasName) {
+  FixItHint Insertion;
+  if (!AlreadyHasEllipsis)
+    Insertion = FixItHint::CreateInsertion(CorrectLoc, "...");
+  Diag(EllipsisLoc, diag::err_misplaced_ellipsis_in_declaration)
+      << FixItHint::CreateRemoval(EllipsisLoc) << Insertion
+      << !IdentifierHasName;
+}
+
+void Parser::DiagnoseMisplacedEllipsisInDeclarator(SourceLocation EllipsisLoc,
+                                                   Declarator &D) {
+  assert(EllipsisLoc.isValid());
+  bool AlreadyHasEllipsis = D.getEllipsisLoc().isValid();
+  if (!AlreadyHasEllipsis)
+    D.setEllipsisLoc(EllipsisLoc);
+  DiagnoseMisplacedEllipsis(EllipsisLoc, D.getIdentifierLoc(),
+                            AlreadyHasEllipsis, D.hasName());
 }
 
 /// \brief Parses a '>' at the end of a template list.
@@ -692,7 +720,7 @@
 
   switch (Tok.getKind()) {
   default:
-    Diag(Tok.getLocation(), diag::err_expected_greater);
+    Diag(Tok.getLocation(), diag::err_expected) << tok::greater;
     return true;
 
   case tok::greater:
@@ -723,7 +751,9 @@
 
   // This template-id is terminated by a token which starts with a '>'. Outside
   // C++11, this is now error recovery, and in C++11, this is error recovery if
-  // the token isn't '>>'.
+  // the token isn't '>>' or '>>>'.
+  // '>>>' is for CUDA, where this sequence of characters is parsed into
+  // tok::greatergreatergreater, rather than two separate tokens.
 
   RAngleLoc = Tok.getLocation();
 
@@ -753,7 +783,8 @@
     Hint2 = FixItHint::CreateInsertion(Next.getLocation(), " ");
 
   unsigned DiagId = diag::err_two_right_angle_brackets_need_space;
-  if (getLangOpts().CPlusPlus11 && Tok.is(tok::greatergreater))
+  if (getLangOpts().CPlusPlus11 &&
+      (Tok.is(tok::greatergreater) || Tok.is(tok::greatergreatergreater)))
     DiagId = diag::warn_cxx98_compat_two_right_angle_brackets;
   else if (Tok.is(tok::greaterequal))
     DiagId = diag::err_right_angle_bracket_equal_needs_space;
@@ -900,8 +931,7 @@
   if (Invalid) {
     // 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 (Tok.is(tok::greater))
-      ConsumeToken();
+    TryConsumeToken(tok::greater);
     return true;
   }
 
@@ -916,8 +946,7 @@
     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 (Tok.is(tok::greater))
-        ConsumeToken();
+      TryConsumeToken(tok::greater);
       return true;
     }
 
@@ -940,7 +969,7 @@
       TemplateId->Name = TemplateName.Identifier;
       TemplateId->Operator = OO_None;
     } else {
-      TemplateId->Name = 0;
+      TemplateId->Name = nullptr;
       TemplateId->Operator = TemplateName.OperatorFunctionId.Operator;
     }
     TemplateId->SS = SS;
@@ -1044,11 +1073,9 @@
       UnqualifiedId Name;
       Name.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
       ConsumeToken(); // the identifier
-      
-      // Parse the ellipsis.
-      if (Tok.is(tok::ellipsis))
-        EllipsisLoc = ConsumeToken();
-      
+
+      TryConsumeToken(tok::ellipsis, EllipsisLoc);
+
       // If the next token signals the end of a template argument,
       // then we have a dependent template name that could be a template
       // template argument.
@@ -1067,10 +1094,8 @@
     UnqualifiedId Name;
     Name.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
     ConsumeToken(); // the identifier
-    
-    // Parse the ellipsis.
-    if (Tok.is(tok::ellipsis))
-      EllipsisLoc = ConsumeToken();
+
+    TryConsumeToken(tok::ellipsis, EllipsisLoc);
 
     if (isEndOfTemplateArgument(Tok)) {
       bool MemberOfUnknownSpecialization;
@@ -1111,7 +1136,7 @@
   // Therefore, we initially try to parse a type-id.  
   if (isCXXTypeId(TypeIdAsTemplateArgument)) {
     SourceLocation Loc = Tok.getLocation();
-    TypeResult TypeArg = ParseTypeName(/*Range=*/0, 
+    TypeResult TypeArg = ParseTypeName(/*Range=*/nullptr,
                                        Declarator::TemplateTypeArgContext);
     if (TypeArg.isInvalid())
       return ParsedTemplateArgument();
@@ -1143,7 +1168,7 @@
     return ParsedTemplateArgument();
 
   return ParsedTemplateArgument(ParsedTemplateArgument::NonType, 
-                                ExprArg.release(), Loc);
+                                ExprArg.get(), Loc);
 }
 
 /// \brief Determine whether the current tokens can only be parsed as a 
@@ -1161,16 +1186,15 @@
   }
   
   // '<'
-  if (!Tok.is(tok::less))
+  if (!TryConsumeToken(tok::less))
     return false;
-  ConsumeToken();
 
   // An empty template argument list.
   if (Tok.is(tok::greater))
     return true;
   
   // See whether we have declaration specifiers, which indicate a type.
-  while (isCXXDeclarationSpecifier() == TPResult::True())
+  while (isCXXDeclarationSpecifier() == TPResult::True)
     ConsumeToken();
   
   // If we have a '>' or a ',' then this is a template argument list.
@@ -1187,13 +1211,13 @@
 Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs) {
   // Template argument lists are constant-evaluation contexts.
   EnterExpressionEvaluationContext EvalContext(Actions,Sema::ConstantEvaluated);
+  ColonProtectionRAIIObject ColonProtection(*this, false);
 
-  while (true) {
+  do {
     ParsedTemplateArgument Arg = ParseTemplateArgument();
-    if (Tok.is(tok::ellipsis)) {
-      SourceLocation EllipsisLoc  = ConsumeToken();
+    SourceLocation EllipsisLoc;
+    if (TryConsumeToken(tok::ellipsis, EllipsisLoc))
       Arg = Actions.ActOnPackExpansion(Arg, EllipsisLoc);
-    }
 
     if (Arg.isInvalid()) {
       SkipUntil(tok::comma, tok::greater, StopAtSemi | StopBeforeMatch);
@@ -1205,11 +1229,7 @@
       
     // If the next token is a comma, consume it and keep reading
     // arguments.
-    if (Tok.isNot(tok::comma)) break;
-
-    // Consume the comma.
-    ConsumeToken();
-  }
+  } while (TryConsumeToken(tok::comma));
 
   return false;
 }
@@ -1258,9 +1278,7 @@
      return;
 
   // Get the FunctionDecl.
-  FunctionTemplateDecl *FunTmplD = dyn_cast<FunctionTemplateDecl>(LPT.D);
-  FunctionDecl *FunD =
-      FunTmplD ? FunTmplD->getTemplatedDecl() : cast<FunctionDecl>(LPT.D);
+  FunctionDecl *FunD = LPT.D->getAsFunction();
   // Track template parameter depth.
   TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
 
@@ -1271,7 +1289,7 @@
 
   // Get the list of DeclContexts to reenter.
   SmallVector<DeclContext*, 4> DeclContextsToReenter;
-  DeclContext *DD = FunD->getLexicalParent();
+  DeclContext *DD = FunD;
   while (DD && !DD->isTranslationUnit()) {
     DeclContextsToReenter.push_back(DD);
     DD = DD->getLexicalParent();
@@ -1281,35 +1299,16 @@
   SmallVectorImpl<DeclContext *>::reverse_iterator II =
       DeclContextsToReenter.rbegin();
   for (; II != DeclContextsToReenter.rend(); ++II) {
-    if (ClassTemplatePartialSpecializationDecl *MD =
-            dyn_cast_or_null<ClassTemplatePartialSpecializationDecl>(*II)) {
-      TemplateParamScopeStack.push_back(
-          new ParseScope(this, Scope::TemplateParamScope));
-      Actions.ActOnReenterTemplateScope(getCurScope(), MD);
-      ++CurTemplateDepthTracker;
-    } else if (CXXRecordDecl *MD = dyn_cast_or_null<CXXRecordDecl>(*II)) {
-      bool IsClassTemplate = MD->getDescribedClassTemplate() != 0;
-      TemplateParamScopeStack.push_back(
-          new ParseScope(this, Scope::TemplateParamScope, 
-                        /*ManageScope*/IsClassTemplate));
-      Actions.ActOnReenterTemplateScope(getCurScope(),
-                                        MD->getDescribedClassTemplate());
-      if (IsClassTemplate) 
-        ++CurTemplateDepthTracker;
+    TemplateParamScopeStack.push_back(new ParseScope(this,
+          Scope::TemplateParamScope));
+    unsigned NumParamLists =
+      Actions.ActOnReenterTemplateScope(getCurScope(), cast<Decl>(*II));
+    CurTemplateDepthTracker.addDepth(NumParamLists);
+    if (*II != FunD) {
+      TemplateParamScopeStack.push_back(new ParseScope(this, Scope::DeclScope));
+      Actions.PushDeclContext(Actions.getCurScope(), *II);
     }
-    TemplateParamScopeStack.push_back(new ParseScope(this, Scope::DeclScope));
-    Actions.PushDeclContext(Actions.getCurScope(), *II);
   }
-  TemplateParamScopeStack.push_back(
-      new ParseScope(this, Scope::TemplateParamScope));
-
-  DeclaratorDecl *Declarator = dyn_cast<DeclaratorDecl>(FunD);
-  if (Declarator && Declarator->getNumTemplateParameterLists() != 0) {
-    Actions.ActOnReenterDeclaratorTemplateScope(getCurScope(), Declarator);
-    ++CurTemplateDepthTracker;
-  }
-  Actions.ActOnReenterTemplateScope(getCurScope(), LPT.D);
-  ++CurTemplateDepthTracker;
 
   assert(!LPT.Toks.empty() && "Empty body!");
 
@@ -1341,14 +1340,16 @@
       Actions.ActOnDefaultCtorInitializers(LPT.D);
 
     if (Tok.is(tok::l_brace)) {
-      assert((!FunTmplD || FunTmplD->getTemplateParameters()->getDepth() <
-                               TemplateParameterDepth) &&
+      assert((!isa<FunctionTemplateDecl>(LPT.D) ||
+              cast<FunctionTemplateDecl>(LPT.D)
+                      ->getTemplateParameters()
+                      ->getDepth() == TemplateParameterDepth - 1) &&
              "TemplateParameterDepth should be greater than the depth of "
              "current template being instantiated!");
       ParseFunctionStatementBody(LPT.D, FnScope);
       Actions.UnmarkAsLateParsedTemplate(FunD);
     } else
-      Actions.ActOnFinishFunctionBody(LPT.D, 0);
+      Actions.ActOnFinishFunctionBody(LPT.D, nullptr);
   }
 
   // Exit scopes.
diff --git a/lib/Parse/ParseTentative.cpp b/lib/Parse/ParseTentative.cpp
index a1d6b13..8514af2 100644
--- a/lib/Parse/ParseTentative.cpp
+++ b/lib/Parse/ParseTentative.cpp
@@ -101,15 +101,15 @@
   // an ambiguity if the first decl-specifier is
   // simple-type-specifier/typename-specifier followed by a '(', which may
   // indicate a function-style cast expression.
-  // isCXXDeclarationSpecifier will return TPResult::Ambiguous() only in such
+  // isCXXDeclarationSpecifier will return TPResult::Ambiguous only in such
   // a case.
 
   bool InvalidAsDeclaration = false;
-  TPResult TPR = isCXXDeclarationSpecifier(TPResult::False(),
+  TPResult TPR = isCXXDeclarationSpecifier(TPResult::False,
                                            &InvalidAsDeclaration);
-  if (TPR != TPResult::Ambiguous())
-    return TPR != TPResult::False(); // Returns true for TPResult::True() or
-                                     // TPResult::Error().
+  if (TPR != TPResult::Ambiguous)
+    return TPR != TPResult::False; // Returns true for TPResult::True or
+                                   // TPResult::Error.
 
   // FIXME: TryParseSimpleDeclaration doesn't look past the first initializer,
   // and so gets some cases wrong. We can't carry on if we've already seen
@@ -131,15 +131,15 @@
   PA.Revert();
 
   // In case of an error, let the declaration parsing code handle it.
-  if (TPR == TPResult::Error())
+  if (TPR == TPResult::Error)
     return true;
 
   // Declarations take precedence over expressions.
-  if (TPR == TPResult::Ambiguous())
-    TPR = TPResult::True();
+  if (TPR == TPResult::Ambiguous)
+    TPR = TPResult::True;
 
-  assert(TPR == TPResult::True() || TPR == TPResult::False());
-  return TPR == TPResult::True();
+  assert(TPR == TPResult::True || TPR == TPResult::False);
+  return TPR == TPResult::True;
 }
 
 /// Try to consume a token sequence that we've already identified as
@@ -157,10 +157,10 @@
   case tok::kw___underlying_type: {
     ConsumeToken();
     if (Tok.isNot(tok::l_paren))
-      return TPResult::Error();
+      return TPResult::Error;
     ConsumeParen();
     if (!SkipUntil(tok::r_paren))
-      return TPResult::Error();
+      return TPResult::Error;
     break;
   }
 
@@ -184,23 +184,23 @@
       if (Tok.is(tok::l_square)) {
         ConsumeBracket();
         if (!SkipUntil(tok::r_square))
-          return TPResult::Error();
+          return TPResult::Error;
       } else {
         ConsumeToken();
         if (Tok.isNot(tok::l_paren))
-          return TPResult::Error();
+          return TPResult::Error;
         ConsumeParen();
         if (!SkipUntil(tok::r_paren))
-          return TPResult::Error();
+          return TPResult::Error;
       }
     }
 
     if (TryAnnotateCXXScopeToken())
-      return TPResult::Error();
+      return TPResult::Error;
     if (Tok.is(tok::annot_cxxscope))
       ConsumeToken();
     if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
-      return TPResult::Error();
+      return TPResult::Error;
     ConsumeToken();
     break;
 
@@ -215,7 +215,7 @@
     break;
   }
 
-  return TPResult::Ambiguous();
+  return TPResult::Ambiguous;
 }
 
 /// simple-declaration:
@@ -227,29 +227,29 @@
 ///    attribute-specifier-seqopt type-specifier-seq declarator
 ///
 Parser::TPResult Parser::TryParseSimpleDeclaration(bool AllowForRangeDecl) {
-  if (TryConsumeDeclarationSpecifier() == TPResult::Error())
-    return TPResult::Error();
+  if (TryConsumeDeclarationSpecifier() == TPResult::Error)
+    return TPResult::Error;
 
   // Two decl-specifiers in a row conclusively disambiguate this as being a
   // simple-declaration. Don't bother calling isCXXDeclarationSpecifier in the
   // overwhelmingly common case that the next token is a '('.
   if (Tok.isNot(tok::l_paren)) {
     TPResult TPR = isCXXDeclarationSpecifier();
-    if (TPR == TPResult::Ambiguous())
-      return TPResult::True();
-    if (TPR == TPResult::True() || TPR == TPResult::Error())
+    if (TPR == TPResult::Ambiguous)
+      return TPResult::True;
+    if (TPR == TPResult::True || TPR == TPResult::Error)
       return TPR;
-    assert(TPR == TPResult::False());
+    assert(TPR == TPResult::False);
   }
 
   TPResult TPR = TryParseInitDeclaratorList();
-  if (TPR != TPResult::Ambiguous())
+  if (TPR != TPResult::Ambiguous)
     return TPR;
 
   if (Tok.isNot(tok::semi) && (!AllowForRangeDecl || Tok.isNot(tok::colon)))
-    return TPResult::False();
+    return TPResult::False;
 
-  return TPResult::Ambiguous();
+  return TPResult::Ambiguous;
 }
 
 /// Tentatively parse an init-declarator-list in order to disambiguate it from
@@ -283,23 +283,23 @@
   while (1) {
     // declarator
     TPResult TPR = TryParseDeclarator(false/*mayBeAbstract*/);
-    if (TPR != TPResult::Ambiguous())
+    if (TPR != TPResult::Ambiguous)
       return TPR;
 
     // [GNU] simple-asm-expr[opt] attributes[opt]
     if (Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute))
-      return TPResult::True();
+      return TPResult::True;
 
     // initializer[opt]
     if (Tok.is(tok::l_paren)) {
       // Parse through the parens.
       ConsumeParen();
       if (!SkipUntil(tok::r_paren, StopAtSemi))
-        return TPResult::Error();
+        return TPResult::Error;
     } else if (Tok.is(tok::l_brace)) {
       // A left-brace here is sufficient to disambiguate the parse; an
       // expression can never be followed directly by a braced-init-list.
-      return TPResult::True();
+      return TPResult::True;
     } else if (Tok.is(tok::equal) || isTokIdentifier_in()) {
       // MSVC and g++ won't examine the rest of declarators if '=' is
       // encountered; they just conclude that we have a declaration.
@@ -317,15 +317,14 @@
       // in any other context 'in' is invalid after a declaration and parser
       // issues the error regardless of outcome of this decision.
       // FIXME: Change if above assumption does not hold.
-      return TPResult::True();
+      return TPResult::True;
     }
 
-    if (Tok.isNot(tok::comma))
+    if (!TryConsumeToken(tok::comma))
       break;
-    ConsumeToken(); // the comma.
   }
 
-  return TPResult::Ambiguous();
+  return TPResult::Ambiguous;
 }
 
 /// isCXXConditionDeclaration - Disambiguates between a declaration or an
@@ -343,9 +342,9 @@
 ///
 bool Parser::isCXXConditionDeclaration() {
   TPResult TPR = isCXXDeclarationSpecifier();
-  if (TPR != TPResult::Ambiguous())
-    return TPR != TPResult::False(); // Returns true for TPResult::True() or
-                                     // TPResult::Error().
+  if (TPR != TPResult::Ambiguous)
+    return TPR != TPResult::False; // Returns true for TPResult::True or
+                                   // TPResult::Error.
 
   // FIXME: Add statistics about the number of ambiguous statements encountered
   // and how they were resolved (number of declarations+number of expressions).
@@ -363,25 +362,25 @@
   TPR = TryParseDeclarator(false/*mayBeAbstract*/);
 
   // In case of an error, let the declaration parsing code handle it.
-  if (TPR == TPResult::Error())
-    TPR = TPResult::True();
+  if (TPR == TPResult::Error)
+    TPR = TPResult::True;
 
-  if (TPR == TPResult::Ambiguous()) {
+  if (TPR == TPResult::Ambiguous) {
     // '='
     // [GNU] simple-asm-expr[opt] attributes[opt]
     if (Tok.is(tok::equal)  ||
         Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute))
-      TPR = TPResult::True();
+      TPR = TPResult::True;
     else if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace))
-      TPR = TPResult::True();
+      TPR = TPResult::True;
     else
-      TPR = TPResult::False();
+      TPR = TPResult::False;
   }
 
   PA.Revert();
 
-  assert(TPR == TPResult::True() || TPR == TPResult::False());
-  return TPR == TPResult::True();
+  assert(TPR == TPResult::True || TPR == TPResult::False);
+  return TPR == TPResult::True;
 }
 
   /// \brief Determine whether the next set of tokens contains a type-id.
@@ -413,9 +412,9 @@
   // in its syntactic context shall be considered a type-id.
 
   TPResult TPR = isCXXDeclarationSpecifier();
-  if (TPR != TPResult::Ambiguous())
-    return TPR != TPResult::False(); // Returns true for TPResult::True() or
-                                     // TPResult::Error().
+  if (TPR != TPResult::Ambiguous)
+    return TPR != TPResult::False; // Returns true for TPResult::True or
+                                     // TPResult::Error.
 
   // FIXME: Add statistics about the number of ambiguous statements encountered
   // and how they were resolved (number of declarations+number of expressions).
@@ -433,14 +432,14 @@
   TPR = TryParseDeclarator(true/*mayBeAbstract*/, false/*mayHaveIdentifier*/);
 
   // In case of an error, let the declaration parsing code handle it.
-  if (TPR == TPResult::Error())
-    TPR = TPResult::True();
+  if (TPR == TPResult::Error)
+    TPR = TPResult::True;
 
-  if (TPR == TPResult::Ambiguous()) {
+  if (TPR == TPResult::Ambiguous) {
     // We are supposed to be inside parens, so if after the abstract declarator
     // we encounter a ')' this is a type-id, otherwise it's an expression.
     if (Context == TypeIdInParens && Tok.is(tok::r_paren)) {
-      TPR = TPResult::True();
+      TPR = TPResult::True;
       isAmbiguous = true;
 
     // We are supposed to be inside a template argument, so if after
@@ -449,17 +448,17 @@
     } else if (Context == TypeIdAsTemplateArgument &&
                (Tok.is(tok::greater) || Tok.is(tok::comma) ||
                 (getLangOpts().CPlusPlus11 && Tok.is(tok::greatergreater)))) {
-      TPR = TPResult::True();
+      TPR = TPResult::True;
       isAmbiguous = true;
 
     } else
-      TPR = TPResult::False();
+      TPR = TPResult::False;
   }
 
   PA.Revert();
 
-  assert(TPR == TPResult::True() || TPR == TPResult::False());
-  return TPR == TPResult::True();
+  assert(TPR == TPResult::True || TPR == TPResult::False);
+  return TPR == TPResult::True;
 }
 
 /// \brief Returns true if this is a C++11 attribute-specifier. Per
@@ -595,13 +594,10 @@
       }
     }
 
-    if (Tok.is(tok::ellipsis))
-      ConsumeToken();
+    TryConsumeToken(tok::ellipsis);
 
-    if (Tok.isNot(tok::comma))
+    if (!TryConsumeToken(tok::comma))
       break;
-
-    ConsumeToken();
   }
 
   // An attribute must end ']]'.
@@ -628,7 +624,7 @@
   while (true) {
     if (Tok.is(tok::coloncolon) || Tok.is(tok::identifier))
       if (TryAnnotateCXXScopeToken(true))
-        return TPResult::Error();
+        return TPResult::Error;
 
     if (Tok.is(tok::star) || Tok.is(tok::amp) || Tok.is(tok::caret) ||
         Tok.is(tok::ampamp) ||
@@ -640,7 +636,7 @@
              Tok.is(tok::kw_restrict))
         ConsumeToken();
     } else {
-      return TPResult::True();
+      return TPResult::True;
     }
   }
 }
@@ -675,20 +671,20 @@
       ConsumeBracket();
       ConsumeBracket();
     }
-    return TPResult::True();
+    return TPResult::True;
 
 #define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemOnly) \
   case tok::Token:
 #define OVERLOADED_OPERATOR_MULTI(Name, Spelling, Unary, Binary, MemOnly)
 #include "clang/Basic/OperatorKinds.def"
     ConsumeToken();
-    return TPResult::True();
+    return TPResult::True;
 
   case tok::l_square:
     if (NextToken().is(tok::r_square)) {
       ConsumeBracket();
       ConsumeBracket();
-      return TPResult::True();
+      return TPResult::True;
     }
     break;
 
@@ -696,7 +692,7 @@
     if (NextToken().is(tok::r_paren)) {
       ConsumeParen();
       ConsumeParen();
-      return TPResult::True();
+      return TPResult::True;
     }
     break;
 
@@ -716,24 +712,24 @@
       if (Tok.is(tok::identifier))
         ConsumeToken();
       else
-        return TPResult::Error();
+        return TPResult::Error;
     }
-    return TPResult::True();
+    return TPResult::True;
   }
 
   // Maybe this is a conversion-function-id.
   bool AnyDeclSpecifiers = false;
   while (true) {
     TPResult TPR = isCXXDeclarationSpecifier();
-    if (TPR == TPResult::Error())
+    if (TPR == TPResult::Error)
       return TPR;
-    if (TPR == TPResult::False()) {
+    if (TPR == TPResult::False) {
       if (!AnyDeclSpecifiers)
-        return TPResult::Error();
+        return TPResult::Error;
       break;
     }
-    if (TryConsumeDeclarationSpecifier() == TPResult::Error())
-      return TPResult::Error();
+    if (TryConsumeDeclarationSpecifier() == TPResult::Error)
+      return TPResult::Error;
     AnyDeclSpecifiers = true;
   }
   return TryParsePtrOperatorSeq();
@@ -797,8 +793,8 @@
   // declarator:
   //   direct-declarator
   //   ptr-operator declarator
-  if (TryParsePtrOperatorSeq() == TPResult::Error())
-    return TPResult::Error();
+  if (TryParsePtrOperatorSeq() == TPResult::Error)
+    return TPResult::Error;
 
   // direct-declarator:
   // direct-abstract-declarator:
@@ -815,8 +811,8 @@
     else if (Tok.is(tok::identifier))
       TentativelyDeclaredIdentifiers.push_back(Tok.getIdentifierInfo());
     if (Tok.is(tok::kw_operator)) {
-      if (TryParseOperatorId() == TPResult::Error())
-        return TPResult::Error();
+      if (TryParseOperatorId() == TPResult::Error)
+        return TPResult::Error;
     } else
       ConsumeToken();
   } else if (Tok.is(tok::l_paren)) {
@@ -829,7 +825,7 @@
       // '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
       //        exception-specification[opt]
       TPResult TPR = TryParseFunctionDeclarator();
-      if (TPR != TPResult::Ambiguous())
+      if (TPR != TPResult::Ambiguous)
         return TPR;
     } else {
       // '(' declarator ')'
@@ -842,20 +838,20 @@
           Tok.is(tok::kw___fastcall) ||
           Tok.is(tok::kw___thiscall) ||
           Tok.is(tok::kw___unaligned))
-        return TPResult::True(); // attributes indicate declaration
+        return TPResult::True; // attributes indicate declaration
       TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier);
-      if (TPR != TPResult::Ambiguous())
+      if (TPR != TPResult::Ambiguous)
         return TPR;
       if (Tok.isNot(tok::r_paren))
-        return TPResult::False();
+        return TPResult::False;
       ConsumeParen();
     }
   } else if (!mayBeAbstract) {
-    return TPResult::False();
+    return TPResult::False;
   }
 
   while (1) {
-    TPResult TPR(TPResult::Ambiguous());
+    TPResult TPR(TPResult::Ambiguous);
 
     // abstract-declarator: ...
     if (Tok.is(tok::ellipsis))
@@ -881,11 +877,11 @@
       break;
     }
 
-    if (TPR != TPResult::Ambiguous())
+    if (TPR != TPResult::Ambiguous)
       return TPR;
   }
 
-  return TPResult::Ambiguous();
+  return TPResult::Ambiguous;
 }
 
 Parser::TPResult 
@@ -935,42 +931,19 @@
   case tok::kw___alignof:
   case tok::kw___builtin_choose_expr:
   case tok::kw___builtin_offsetof:
-  case tok::kw___builtin_types_compatible_p:
   case tok::kw___builtin_va_arg:
   case tok::kw___imag:
   case tok::kw___real:
   case tok::kw___FUNCTION__:
   case tok::kw___FUNCDNAME__:
+  case tok::kw___FUNCSIG__:
   case tok::kw_L__FUNCTION__:
   case tok::kw___PRETTY_FUNCTION__:
-  case tok::kw___has_nothrow_assign:
-  case tok::kw___has_nothrow_copy:
-  case tok::kw___has_nothrow_constructor:
-  case tok::kw___has_trivial_assign:
-  case tok::kw___has_trivial_copy:
-  case tok::kw___has_trivial_constructor:
-  case tok::kw___has_trivial_destructor:
-  case tok::kw___has_virtual_destructor:
-  case tok::kw___is_abstract:
-  case tok::kw___is_base_of:
-  case tok::kw___is_class:
-  case tok::kw___is_convertible_to:
-  case tok::kw___is_empty:
-  case tok::kw___is_enum:
-  case tok::kw___is_interface_class:
-  case tok::kw___is_final:
-  case tok::kw___is_literal:
-  case tok::kw___is_literal_type:
-  case tok::kw___is_pod:
-  case tok::kw___is_polymorphic:
-  case tok::kw___is_sealed:
-  case tok::kw___is_trivial:
-  case tok::kw___is_trivially_assignable:
-  case tok::kw___is_trivially_constructible:
-  case tok::kw___is_trivially_copyable:
-  case tok::kw___is_union:
   case tok::kw___uuidof:
-    return TPResult::True();
+#define TYPE_TRAIT(N,Spelling,K) \
+  case tok::kw_##Spelling:
+#include "clang/Basic/TokenKinds.def"
+    return TPResult::True;
       
   // Obviously starts a type-specifier-seq:
   case tok::kw_char:
@@ -1015,22 +988,14 @@
   case tok::kw___vector:
   case tok::kw___pixel:
   case tok::kw__Atomic:
-  case tok::kw_image1d_t:
-  case tok::kw_image1d_array_t:
-  case tok::kw_image1d_buffer_t:
-  case tok::kw_image2d_t:
-  case tok::kw_image2d_array_t:
-  case tok::kw_image3d_t:
-  case tok::kw_sampler_t:
-  case tok::kw_event_t:
   case tok::kw___unknown_anytype:
-    return TPResult::False();
+    return TPResult::False;
 
   default:
     break;
   }
   
-  return TPResult::Ambiguous();
+  return TPResult::Ambiguous;
 }
 
 bool Parser::isTentativelyDeclared(IdentifierInfo *II) {
@@ -1039,16 +1004,16 @@
       != TentativelyDeclaredIdentifiers.end();
 }
 
-/// isCXXDeclarationSpecifier - Returns TPResult::True() if it is a declaration
-/// specifier, TPResult::False() if it is not, TPResult::Ambiguous() if it could
-/// be either a decl-specifier or a function-style cast, and TPResult::Error()
+/// isCXXDeclarationSpecifier - Returns TPResult::True if it is a declaration
+/// specifier, TPResult::False if it is not, TPResult::Ambiguous if it could
+/// be either a decl-specifier or a function-style cast, and TPResult::Error
 /// if a parsing error was found and reported.
 ///
 /// If HasMissingTypename is provided, a name with a dependent scope specifier
 /// will be treated as ambiguous if the 'typename' keyword is missing. If this
 /// happens, *HasMissingTypename will be set to 'true'. This will also be used
 /// as an indicator that undeclared identifiers (which will trigger a later
-/// parse error) should be treated as types. Returns TPResult::Ambiguous() in
+/// parse error) should be treated as types. Returns TPResult::Ambiguous in
 /// such cases.
 ///
 ///         decl-specifier:
@@ -1152,12 +1117,12 @@
     // Check for need to substitute AltiVec __vector keyword
     // for "vector" identifier.
     if (TryAltiVecVectorToken())
-      return TPResult::True();
+      return TPResult::True;
 
     const Token &Next = NextToken();
     // In 'foo bar', 'foo' is always a type name outside of Objective-C.
     if (!getLangOpts().ObjC1 && Next.is(tok::identifier))
-      return TPResult::True();
+      return TPResult::True;
 
     if (Next.isNot(tok::coloncolon) && Next.isNot(tok::less)) {
       // Determine whether this is a valid expression. If not, we will hit
@@ -1170,15 +1135,15 @@
       switch (TryAnnotateName(false /* no nested name specifier */,
                               &TypoCorrection)) {
       case ANK_Error:
-        return TPResult::Error();
+        return TPResult::Error;
       case ANK_TentativeDecl:
-        return TPResult::False();
+        return TPResult::False;
       case ANK_TemplateName:
         // A bare type template-name which can't be a template template
         // argument is an error, and was probably intended to be a type.
-        return GreaterThanIsOperator ? TPResult::True() : TPResult::False();
+        return GreaterThanIsOperator ? TPResult::True : TPResult::False;
       case ANK_Unresolved:
-        return HasMissingTypename ? TPResult::Ambiguous() : TPResult::False();
+        return HasMissingTypename ? TPResult::Ambiguous : TPResult::False;
       case ANK_Success:
         break;
       }
@@ -1190,12 +1155,12 @@
       // since it will annotate as a primary expression, and we want to use the
       // "missing 'typename'" logic.
       if (TryAnnotateTypeOrScopeToken())
-        return TPResult::Error();
+        return TPResult::Error;
       // If annotation failed, assume it's a non-type.
       // FIXME: If this happens due to an undeclared identifier, treat it as
       // ambiguous.
       if (Tok.is(tok::identifier))
-        return TPResult::False();
+        return TPResult::False;
     }
 
     // We annotated this token as something. Recurse to handle whatever we got.
@@ -1206,21 +1171,21 @@
     // Annotate typenames and C++ scope specifiers.  If we get one, just
     // recurse to handle whatever we get.
     if (TryAnnotateTypeOrScopeToken())
-      return TPResult::Error();
+      return TPResult::Error;
     return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
 
   case tok::coloncolon: {    // ::foo::bar
     const Token &Next = NextToken();
     if (Next.is(tok::kw_new) ||    // ::new
         Next.is(tok::kw_delete))   // ::delete
-      return TPResult::False();
+      return TPResult::False;
   }
     // Fall through.
   case tok::kw_decltype:
     // Annotate typenames and C++ scope specifiers.  If we get one, just
     // recurse to handle whatever we get.
     if (TryAnnotateTypeOrScopeToken())
-      return TPResult::Error();
+      return TPResult::Error;
     return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
 
     // decl-specifier:
@@ -1277,7 +1242,7 @@
   case tok::kw_restrict:
   case tok::kw__Complex:
   case tok::kw___attribute:
-    return TPResult::True();
+    return TPResult::True;
 
     // Microsoft
   case tok::kw___declspec:
@@ -1292,20 +1257,20 @@
   case tok::kw___ptr32:
   case tok::kw___forceinline:
   case tok::kw___unaligned:
-    return TPResult::True();
+    return TPResult::True;
 
     // Borland
   case tok::kw___pascal:
-    return TPResult::True();
+    return TPResult::True;
   
     // AltiVec
   case tok::kw___vector:
-    return TPResult::True();
+    return TPResult::True;
 
   case tok::annot_template_id: {
     TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
     if (TemplateId->Kind != TNK_Type_template)
-      return TPResult::False();
+      return TPResult::False;
     CXXScopeSpec SS;
     AnnotateTemplateIdTokenAsType();
     assert(Tok.is(tok::annot_typename));
@@ -1315,7 +1280,7 @@
   case tok::annot_cxxscope: // foo::bar or ::foo::bar, but already parsed
     // We've already annotated a scope; try to annotate a type.
     if (TryAnnotateTypeOrScopeToken())
-      return TPResult::Error();
+      return TPResult::Error;
     if (!Tok.is(tok::annot_typename)) {
       // If the next token is an identifier or a type qualifier, then this
       // can't possibly be a valid expression either.
@@ -1329,37 +1294,37 @@
           ConsumeToken();
           ConsumeToken();
           bool isIdentifier = Tok.is(tok::identifier);
-          TPResult TPR = TPResult::False();
+          TPResult TPR = TPResult::False;
           if (!isIdentifier)
             TPR = isCXXDeclarationSpecifier(BracedCastResult,
                                             HasMissingTypename);
           PA.Revert();
 
           if (isIdentifier ||
-              TPR == TPResult::True() || TPR == TPResult::Error())
-            return TPResult::Error();
+              TPR == TPResult::True || TPR == TPResult::Error)
+            return TPResult::Error;
 
           if (HasMissingTypename) {
             // We can't tell whether this is a missing 'typename' or a valid
             // expression.
             *HasMissingTypename = true;
-            return TPResult::Ambiguous();
+            return TPResult::Ambiguous;
           }
         } else {
           // Try to resolve the name. If it doesn't exist, assume it was
           // intended to name a type and keep disambiguating.
           switch (TryAnnotateName(false /* SS is not dependent */)) {
           case ANK_Error:
-            return TPResult::Error();
+            return TPResult::Error;
           case ANK_TentativeDecl:
-            return TPResult::False();
+            return TPResult::False;
           case ANK_TemplateName:
             // A bare type template-name which can't be a template template
             // argument is an error, and was probably intended to be a type.
-            return GreaterThanIsOperator ? TPResult::True() : TPResult::False();
+            return GreaterThanIsOperator ? TPResult::True : TPResult::False;
           case ANK_Unresolved:
-            return HasMissingTypename ? TPResult::Ambiguous()
-                                      : TPResult::False();
+            return HasMissingTypename ? TPResult::Ambiguous
+                                      : TPResult::False;
           case ANK_Success:
             // Annotated it, check again.
             assert(Tok.isNot(tok::annot_cxxscope) ||
@@ -1369,7 +1334,7 @@
           }
         }
       }
-      return TPResult::False();
+      return TPResult::False;
     }
     // If that succeeded, fallthrough into the generic simple-type-id case.
 
@@ -1405,16 +1370,16 @@
       
       PA.Revert();
       
-      if (TPR == TPResult::Error())
-        return TPResult::Error();
+      if (TPR == TPResult::Error)
+        return TPResult::Error;
       
       if (isFollowedByParen)
-        return TPResult::Ambiguous();
+        return TPResult::Ambiguous;
 
       if (getLangOpts().CPlusPlus11 && isFollowedByBrace)
         return BracedCastResult;
       
-      return TPResult::True();
+      return TPResult::True;
     }
       
   case tok::kw_char:
@@ -1435,7 +1400,7 @@
   case tok::kw_void:
   case tok::annot_decltype:
     if (NextToken().is(tok::l_paren))
-      return TPResult::Ambiguous();
+      return TPResult::Ambiguous;
 
     // This is a function-style cast in all cases we disambiguate other than
     // one:
@@ -1447,14 +1412,14 @@
       return BracedCastResult;
 
     if (isStartOfObjCClassMessageMissingOpenBracket())
-      return TPResult::False();
+      return TPResult::False;
       
-    return TPResult::True();
+    return TPResult::True;
 
   // GNU typeof support.
   case tok::kw_typeof: {
     if (NextToken().isNot(tok::l_paren))
-      return TPResult::True();
+      return TPResult::True;
 
     TentativeParsingAction PA(*this);
 
@@ -1464,28 +1429,28 @@
 
     PA.Revert();
 
-    if (TPR == TPResult::Error())
-      return TPResult::Error();
+    if (TPR == TPResult::Error)
+      return TPResult::Error;
 
     if (isFollowedByParen)
-      return TPResult::Ambiguous();
+      return TPResult::Ambiguous;
 
     if (getLangOpts().CPlusPlus11 && isFollowedByBrace)
       return BracedCastResult;
 
-    return TPResult::True();
+    return TPResult::True;
   }
 
   // C++0x type traits support
   case tok::kw___underlying_type:
-    return TPResult::True();
+    return TPResult::True;
 
   // C11 _Atomic
   case tok::kw__Atomic:
-    return TPResult::True();
+    return TPResult::True;
 
   default:
-    return TPResult::False();
+    return TPResult::False;
   }
 }
 
@@ -1551,9 +1516,9 @@
   // Parse through the parens after 'typeof'.
   ConsumeParen();
   if (!SkipUntil(tok::r_paren, StopAtSemi))
-    return TPResult::Error();
+    return TPResult::Error;
 
-  return TPResult::Ambiguous();
+  return TPResult::Ambiguous;
 }
 
 /// [ObjC] protocol-qualifiers:
@@ -1563,7 +1528,7 @@
   ConsumeToken();
   do {
     if (Tok.isNot(tok::identifier))
-      return TPResult::Error();
+      return TPResult::Error;
     ConsumeToken();
     
     if (Tok.is(tok::comma)) {
@@ -1573,11 +1538,11 @@
     
     if (Tok.is(tok::greater)) {
       ConsumeToken();
-      return TPResult::Ambiguous();
+      return TPResult::Ambiguous;
     }
   } while (false);
   
-  return TPResult::Error();
+  return TPResult::Error;
 }
 
 /// isCXXFunctionDeclarator - Disambiguates between a function declarator or
@@ -1606,9 +1571,9 @@
   ConsumeParen();
   bool InvalidAsDeclaration = false;
   TPResult TPR = TryParseParameterDeclarationClause(&InvalidAsDeclaration);
-  if (TPR == TPResult::Ambiguous()) {
+  if (TPR == TPResult::Ambiguous) {
     if (Tok.isNot(tok::r_paren))
-      TPR = TPResult::False();
+      TPR = TPResult::False;
     else {
       const Token &Next = NextToken();
       if (Next.is(tok::amp) || Next.is(tok::ampamp) ||
@@ -1620,20 +1585,20 @@
         // The next token cannot appear after a constructor-style initializer,
         // and can appear next in a function definition. This must be a function
         // declarator.
-        TPR = TPResult::True();
+        TPR = TPResult::True;
       else if (InvalidAsDeclaration)
         // Use the absence of 'typename' as a tie-breaker.
-        TPR = TPResult::False();
+        TPR = TPResult::False;
     }
   }
 
   PA.Revert();
 
-  if (IsAmbiguous && TPR == TPResult::Ambiguous())
+  if (IsAmbiguous && TPR == TPResult::Ambiguous)
     *IsAmbiguous = true;
 
   // In case of an error, let the declaration parsing code handle it.
-  return TPR != TPResult::False();
+  return TPR != TPResult::False;
 }
 
 /// parameter-declaration-clause:
@@ -1658,7 +1623,7 @@
                                            bool VersusTemplateArgument) {
 
   if (Tok.is(tok::r_paren))
-    return TPResult::Ambiguous();
+    return TPResult::Ambiguous;
 
   //   parameter-declaration-list[opt] '...'[opt]
   //   parameter-declaration-list ',' '...'
@@ -1672,15 +1637,15 @@
     if (Tok.is(tok::ellipsis)) {
       ConsumeToken();
       if (Tok.is(tok::r_paren))
-        return TPResult::True(); // '...)' is a sign of a function declarator.
+        return TPResult::True; // '...)' is a sign of a function declarator.
       else
-        return TPResult::False();
+        return TPResult::False;
     }
 
     // An attribute-specifier-seq here is a sign of a function declarator.
     if (isCXX11AttributeSpecifier(/*Disambiguate*/false,
                                   /*OuterMightBeMessageSend*/true))
-      return TPResult::True();
+      return TPResult::True;
 
     ParsedAttributes attrs(AttrFactory);
     MaybeParseMicrosoftAttributes(attrs);
@@ -1688,43 +1653,43 @@
     // decl-specifier-seq
     // A parameter-declaration's initializer must be preceded by an '=', so
     // decl-specifier-seq '{' is not a parameter in C++11.
-    TPResult TPR = isCXXDeclarationSpecifier(TPResult::False(),
+    TPResult TPR = isCXXDeclarationSpecifier(TPResult::False,
                                              InvalidAsDeclaration);
 
-    if (VersusTemplateArgument && TPR == TPResult::True()) {
+    if (VersusTemplateArgument && TPR == TPResult::True) {
       // Consume the decl-specifier-seq. We have to look past it, since a
       // type-id might appear here in a template argument.
       bool SeenType = false;
       do {
         SeenType |= isCXXDeclarationSpecifierAType();
-        if (TryConsumeDeclarationSpecifier() == TPResult::Error())
-          return TPResult::Error();
+        if (TryConsumeDeclarationSpecifier() == TPResult::Error)
+          return TPResult::Error;
 
         // If we see a parameter name, this can't be a template argument.
         if (SeenType && Tok.is(tok::identifier))
-          return TPResult::True();
+          return TPResult::True;
 
-        TPR = isCXXDeclarationSpecifier(TPResult::False(),
+        TPR = isCXXDeclarationSpecifier(TPResult::False,
                                         InvalidAsDeclaration);
-        if (TPR == TPResult::Error())
+        if (TPR == TPResult::Error)
           return TPR;
-      } while (TPR != TPResult::False());
-    } else if (TPR == TPResult::Ambiguous()) {
+      } while (TPR != TPResult::False);
+    } else if (TPR == TPResult::Ambiguous) {
       // Disambiguate what follows the decl-specifier.
-      if (TryConsumeDeclarationSpecifier() == TPResult::Error())
-        return TPResult::Error();
+      if (TryConsumeDeclarationSpecifier() == TPResult::Error)
+        return TPResult::Error;
     } else
       return TPR;
 
     // declarator
     // abstract-declarator[opt]
     TPR = TryParseDeclarator(true/*mayBeAbstract*/);
-    if (TPR != TPResult::Ambiguous())
+    if (TPR != TPResult::Ambiguous)
       return TPR;
 
     // [GNU] attributes[opt]
     if (Tok.is(tok::kw___attribute))
-      return TPResult::True();
+      return TPResult::True;
 
     // If we're disambiguating a template argument in a default argument in
     // a class definition versus a parameter declaration, an '=' here
@@ -1737,37 +1702,36 @@
     // parameter-declaration-clause, and the last param is missing its default
     // argument.
     if (VersusTemplateArgument)
-      return (Tok.is(tok::equal) || Tok.is(tok::r_paren)) ? TPResult::True()
-                                                          : TPResult::False();
+      return (Tok.is(tok::equal) || Tok.is(tok::r_paren)) ? TPResult::True
+                                                          : TPResult::False;
 
     if (Tok.is(tok::equal)) {
       // '=' assignment-expression
       // Parse through assignment-expression.
       // FIXME: assignment-expression may contain an unparenthesized comma.
       if (!SkipUntil(tok::comma, tok::r_paren, StopAtSemi | StopBeforeMatch))
-        return TPResult::Error();
+        return TPResult::Error;
     }
 
     if (Tok.is(tok::ellipsis)) {
       ConsumeToken();
       if (Tok.is(tok::r_paren))
-        return TPResult::True(); // '...)' is a sign of a function declarator.
+        return TPResult::True; // '...)' is a sign of a function declarator.
       else
-        return TPResult::False();
+        return TPResult::False;
     }
 
-    if (Tok.isNot(tok::comma))
+    if (!TryConsumeToken(tok::comma))
       break;
-    ConsumeToken(); // the comma.
   }
 
-  return TPResult::Ambiguous();
+  return TPResult::Ambiguous;
 }
 
 /// TryParseFunctionDeclarator - We parsed a '(' and we want to try to continue
 /// parsing as a function declarator.
 /// If TryParseFunctionDeclarator fully parsed the function declarator, it will
-/// return TPResult::Ambiguous(), otherwise it will return either False() or
+/// return TPResult::Ambiguous, otherwise it will return either False() or
 /// Error().
 ///
 /// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
@@ -1781,15 +1745,15 @@
   // The '(' is already parsed.
 
   TPResult TPR = TryParseParameterDeclarationClause();
-  if (TPR == TPResult::Ambiguous() && Tok.isNot(tok::r_paren))
-    TPR = TPResult::False();
+  if (TPR == TPResult::Ambiguous && Tok.isNot(tok::r_paren))
+    TPR = TPResult::False;
 
-  if (TPR == TPResult::False() || TPR == TPResult::Error())
+  if (TPR == TPResult::False || TPR == TPResult::Error)
     return TPR;
 
   // Parse through the parens.
   if (!SkipUntil(tok::r_paren, StopAtSemi))
-    return TPResult::Error();
+    return TPResult::Error;
 
   // cv-qualifier-seq
   while (Tok.is(tok::kw_const)    ||
@@ -1805,12 +1769,12 @@
   if (Tok.is(tok::kw_throw)) {
     ConsumeToken();
     if (Tok.isNot(tok::l_paren))
-      return TPResult::Error();
+      return TPResult::Error;
 
     // Parse through the parens after 'throw'.
     ConsumeParen();
     if (!SkipUntil(tok::r_paren, StopAtSemi))
-      return TPResult::Error();
+      return TPResult::Error;
   }
   if (Tok.is(tok::kw_noexcept)) {
     ConsumeToken();
@@ -1819,11 +1783,11 @@
       // Find the matching rparen.
       ConsumeParen();
       if (!SkipUntil(tok::r_paren, StopAtSemi))
-        return TPResult::Error();
+        return TPResult::Error;
     }
   }
 
-  return TPResult::Ambiguous();
+  return TPResult::Ambiguous;
 }
 
 /// '[' constant-expression[opt] ']'
@@ -1831,7 +1795,7 @@
 Parser::TPResult Parser::TryParseBracketDeclarator() {
   ConsumeBracket();
   if (!SkipUntil(tok::r_square, StopAtSemi))
-    return TPResult::Error();
+    return TPResult::Error;
 
-  return TPResult::Ambiguous();
+  return TPResult::Ambiguous;
 }
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index beae8f0..37ce157 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -12,9 +12,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Parse/Parser.h"
-#include "ParsePragma.h"
 #include "RAIIObjectsForParser.h"
 #include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/Parse/ParseDiagnostic.h"
 #include "clang/Sema/DeclSpec.h"
@@ -33,7 +33,7 @@
 public:
   explicit ActionCommentHandler(Sema &S) : S(S) { }
 
-  virtual bool HandleComment(Preprocessor &PP, SourceRange Comment) {
+  bool HandleComment(Preprocessor &PP, SourceRange Comment) override {
     S.ActOnComment(Comment);
     return false;
   }
@@ -56,58 +56,14 @@
   SkipFunctionBodies = pp.isCodeCompletionEnabled() || skipFunctionBodies;
   Tok.startToken();
   Tok.setKind(tok::eof);
-  Actions.CurScope = 0;
+  Actions.CurScope = nullptr;
   NumCachedScopes = 0;
   ParenCount = BracketCount = BraceCount = 0;
-  CurParsedObjCImpl = 0;
+  CurParsedObjCImpl = nullptr;
 
   // Add #pragma handlers. These are removed and destroyed in the
   // destructor.
-  AlignHandler.reset(new PragmaAlignHandler());
-  PP.AddPragmaHandler(AlignHandler.get());
-
-  GCCVisibilityHandler.reset(new PragmaGCCVisibilityHandler());
-  PP.AddPragmaHandler("GCC", GCCVisibilityHandler.get());
-
-  OptionsHandler.reset(new PragmaOptionsHandler());
-  PP.AddPragmaHandler(OptionsHandler.get());
-
-  PackHandler.reset(new PragmaPackHandler());
-  PP.AddPragmaHandler(PackHandler.get());
-    
-  MSStructHandler.reset(new PragmaMSStructHandler());
-  PP.AddPragmaHandler(MSStructHandler.get());
-
-  UnusedHandler.reset(new PragmaUnusedHandler());
-  PP.AddPragmaHandler(UnusedHandler.get());
-
-  WeakHandler.reset(new PragmaWeakHandler());
-  PP.AddPragmaHandler(WeakHandler.get());
-
-  RedefineExtnameHandler.reset(new PragmaRedefineExtnameHandler());
-  PP.AddPragmaHandler(RedefineExtnameHandler.get());
-
-  FPContractHandler.reset(new PragmaFPContractHandler());
-  PP.AddPragmaHandler("STDC", FPContractHandler.get());
-
-  if (getLangOpts().OpenCL) {
-    OpenCLExtensionHandler.reset(new PragmaOpenCLExtensionHandler());
-    PP.AddPragmaHandler("OPENCL", OpenCLExtensionHandler.get());
-
-    PP.AddPragmaHandler("OPENCL", FPContractHandler.get());
-  }
-  if (getLangOpts().OpenMP)
-    OpenMPHandler.reset(new PragmaOpenMPHandler());
-  else
-    OpenMPHandler.reset(new PragmaNoOpenMPHandler());
-  PP.AddPragmaHandler(OpenMPHandler.get());
-
-  if (getLangOpts().MicrosoftExt) {
-    MSCommentHandler.reset(new PragmaCommentHandler(actions));
-    PP.AddPragmaHandler(MSCommentHandler.get());
-    MSDetectMismatchHandler.reset(new PragmaDetectMismatchHandler(actions));
-    PP.AddPragmaHandler(MSDetectMismatchHandler.get());
-  }
+  initializePragmaHandlers();
 
   CommentSemaHandler.reset(new ActionCommentHandler(actions));
   PP.addCommentHandler(CommentSemaHandler.get());
@@ -152,14 +108,8 @@
   }
 }
 
-/// ExpectAndConsume - The parser expects that 'ExpectedTok' is next in the
-/// input.  If so, it is consumed and false is returned.
-///
-/// If the input is malformed, this emits the specified diagnostic.  Next, if
-/// SkipToTok is specified, it calls SkipUntil(SkipToTok).  Finally, true is
-/// returned.
 bool Parser::ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned DiagID,
-                              const char *Msg, tok::TokenKind SkipToTok) {
+                              StringRef Msg) {
   if (Tok.is(ExpectedTok) || Tok.is(tok::code_completion)) {
     ConsumeAnyToken();
     return false;
@@ -168,35 +118,48 @@
   // Detect common single-character typos and resume.
   if (IsCommonTypo(ExpectedTok, Tok)) {
     SourceLocation Loc = Tok.getLocation();
-    Diag(Loc, DiagID)
-      << Msg
-      << FixItHint::CreateReplacement(SourceRange(Loc),
-                                      getTokenSimpleSpelling(ExpectedTok));
-    ConsumeAnyToken();
+    {
+      DiagnosticBuilder DB = Diag(Loc, DiagID);
+      DB << FixItHint::CreateReplacement(
+                SourceRange(Loc), tok::getPunctuatorSpelling(ExpectedTok));
+      if (DiagID == diag::err_expected)
+        DB << ExpectedTok;
+      else if (DiagID == diag::err_expected_after)
+        DB << Msg << ExpectedTok;
+      else
+        DB << Msg;
+    }
 
     // Pretend there wasn't a problem.
+    ConsumeAnyToken();
     return false;
   }
 
-  const char *Spelling = 0;
   SourceLocation EndLoc = PP.getLocForEndOfToken(PrevTokLocation);
-  if (EndLoc.isValid() &&
-      (Spelling = tok::getTokenSimpleSpelling(ExpectedTok))) {
-    // Show what code to insert to fix this problem.
-    Diag(EndLoc, DiagID)
-      << Msg
-      << FixItHint::CreateInsertion(EndLoc, Spelling);
-  } else
-    Diag(Tok, DiagID) << Msg;
+  const char *Spelling = nullptr;
+  if (EndLoc.isValid())
+    Spelling = tok::getPunctuatorSpelling(ExpectedTok);
 
-  if (SkipToTok != tok::unknown)
-    SkipUntil(SkipToTok, StopAtSemi);
+  DiagnosticBuilder DB =
+      Spelling
+          ? Diag(EndLoc, DiagID) << FixItHint::CreateInsertion(EndLoc, Spelling)
+          : Diag(Tok, DiagID);
+  if (DiagID == diag::err_expected)
+    DB << ExpectedTok;
+  else if (DiagID == diag::err_expected_after)
+    DB << Msg << ExpectedTok;
+  else
+    DB << Msg;
+
   return true;
 }
 
 bool Parser::ExpectAndConsumeSemi(unsigned DiagID) {
-  if (Tok.is(tok::semi) || Tok.is(tok::code_completion)) {
-    ConsumeToken();
+  if (TryConsumeToken(tok::semi))
+    return false;
+
+  if (Tok.is(tok::code_completion)) {
+    handleUnexpectedCodeCompletionToken();
     return false;
   }
   
@@ -241,7 +204,8 @@
 
   if (Kind != AfterMemberFunctionDefinition || HadMultipleSemis)
     Diag(StartLoc, diag::ext_extra_semi)
-        << Kind << DeclSpec::getSpecifierName((DeclSpec::TST)TST)
+        << Kind << DeclSpec::getSpecifierName((DeclSpec::TST)TST,
+                                    Actions.getASTContext().getPrintingPolicy())
         << FixItHint::CreateRemoval(SourceRange(StartLoc, EndLoc));
   else
     // A single semicolon is valid after a member function definition.
@@ -288,7 +252,7 @@
     if (Toks.size() == 1 && Toks[0] == tok::eof &&
         !HasFlagsSet(Flags, StopAtSemi) &&
         !HasFlagsSet(Flags, StopAtCodeCompletion)) {
-      while (Tok.getKind() != tok::eof)
+      while (Tok.isNot(tok::eof))
         ConsumeAnyToken();
       return true;
     }
@@ -297,10 +261,20 @@
     case tok::eof:
       // Ran out of tokens.
       return false;
-        
+
+    case tok::annot_pragma_openmp_end:
+      // Stop before an OpenMP pragma boundary.
+    case tok::annot_module_begin:
+    case tok::annot_module_end:
+    case tok::annot_module_include:
+      // Stop before we change submodules. They generally indicate a "good"
+      // place to pick up parsing again (except in the special case where
+      // we're trying to skip to EOF).
+      return false;
+
     case tok::code_completion:
       if (!HasFlagsSet(Flags, StopAtCodeCompletion))
-        ConsumeToken();
+        handleUnexpectedCodeCompletionToken();
       return false;
         
     case tok::l_paren:
@@ -391,8 +365,7 @@
 
   // Inform the actions module that this scope is going away if there are any
   // decls in it.
-  if (!getCurScope()->decl_empty())
-    Actions.ActOnPopScope(Tok.getLocation(), getCurScope());
+  Actions.ActOnPopScope(Tok.getLocation(), getCurScope());
 
   Scope *OldScope = getCurScope();
   Actions.CurScope = OldScope->getParent();
@@ -407,7 +380,7 @@
 /// this object does nothing.
 Parser::ParseScopeFlags::ParseScopeFlags(Parser *Self, unsigned ScopeFlags,
                                  bool ManageFlags)
-  : CurScope(ManageFlags ? Self->getCurScope() : 0) {
+  : CurScope(ManageFlags ? Self->getCurScope() : nullptr) {
   if (CurScope) {
     OldFlags = CurScope->getFlags();
     CurScope->setFlags(ScopeFlags);
@@ -429,47 +402,13 @@
 Parser::~Parser() {
   // If we still have scopes active, delete the scope tree.
   delete getCurScope();
-  Actions.CurScope = 0;
-  
+  Actions.CurScope = nullptr;
+
   // Free the scope cache.
   for (unsigned i = 0, e = NumCachedScopes; i != e; ++i)
     delete ScopeCache[i];
 
-  // Remove the pragma handlers we installed.
-  PP.RemovePragmaHandler(AlignHandler.get());
-  AlignHandler.reset();
-  PP.RemovePragmaHandler("GCC", GCCVisibilityHandler.get());
-  GCCVisibilityHandler.reset();
-  PP.RemovePragmaHandler(OptionsHandler.get());
-  OptionsHandler.reset();
-  PP.RemovePragmaHandler(PackHandler.get());
-  PackHandler.reset();
-  PP.RemovePragmaHandler(MSStructHandler.get());
-  MSStructHandler.reset();
-  PP.RemovePragmaHandler(UnusedHandler.get());
-  UnusedHandler.reset();
-  PP.RemovePragmaHandler(WeakHandler.get());
-  WeakHandler.reset();
-  PP.RemovePragmaHandler(RedefineExtnameHandler.get());
-  RedefineExtnameHandler.reset();
-
-  if (getLangOpts().OpenCL) {
-    PP.RemovePragmaHandler("OPENCL", OpenCLExtensionHandler.get());
-    OpenCLExtensionHandler.reset();
-    PP.RemovePragmaHandler("OPENCL", FPContractHandler.get());
-  }
-  PP.RemovePragmaHandler(OpenMPHandler.get());
-  OpenMPHandler.reset();
-
-  if (getLangOpts().MicrosoftExt) {
-    PP.RemovePragmaHandler(MSCommentHandler.get());
-    MSCommentHandler.reset();
-    PP.RemovePragmaHandler(MSDetectMismatchHandler.get());
-    MSDetectMismatchHandler.reset();
-  }
-
-  PP.RemovePragmaHandler("STDC", FPContractHandler.get());
-  FPContractHandler.reset();
+  resetPragmaHandlers();
 
   PP.removeCommentHandler(CommentSemaHandler.get());
 
@@ -482,7 +421,7 @@
 ///
 void Parser::Initialize() {
   // Create the translation unit scope.  Install it as the current scope.
-  assert(getCurScope() == 0 && "A scope is already active?");
+  assert(getCurScope() == nullptr && "A scope is already active?");
   EnterScope(Scope::DeclScope);
   Actions.ActOnTranslationUnitScope(getCurScope());
 
@@ -497,10 +436,10 @@
     ObjCTypeQuals[objc_byref] = &PP.getIdentifierTable().get("byref");
   }
 
-  Ident_instancetype = 0;
-  Ident_final = 0;
-  Ident_sealed = 0;
-  Ident_override = 0;
+  Ident_instancetype = nullptr;
+  Ident_final = nullptr;
+  Ident_sealed = nullptr;
+  Ident_override = nullptr;
 
   Ident_super = &PP.getIdentifierTable().get("super");
 
@@ -510,16 +449,18 @@
     Ident_bool = &PP.getIdentifierTable().get("bool");
   }
 
-  Ident_introduced = 0;
-  Ident_deprecated = 0;
-  Ident_obsoleted = 0;
-  Ident_unavailable = 0;
+  Ident_introduced = nullptr;
+  Ident_deprecated = nullptr;
+  Ident_obsoleted = nullptr;
+  Ident_unavailable = nullptr;
 
-  Ident__except = 0;
-  
-  Ident__exception_code = Ident__exception_info = Ident__abnormal_termination = 0;
-  Ident___exception_code = Ident___exception_info = Ident___abnormal_termination = 0;
-  Ident_GetExceptionCode = Ident_GetExceptionInfo = Ident_AbnormalTermination = 0;
+  Ident__except = nullptr;
+
+  Ident__exception_code = Ident__exception_info = nullptr;
+  Ident__abnormal_termination = Ident___exception_code = nullptr;
+  Ident___exception_info = Ident___abnormal_termination = nullptr;
+  Ident_GetExceptionCode = Ident_GetExceptionInfo = nullptr;
+  Ident_AbnormalTermination = nullptr;
 
   if(getLangOpts().Borland) {
     Ident__exception_info        = PP.getIdentifierInfo("_exception_info");
@@ -574,7 +515,7 @@
 bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result) {
   DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(TemplateIds);
 
-  // Skip over the EOF token, flagging end of previous input for incremental 
+  // Skip over the EOF token, flagging end of previous input for incremental
   // processing
   if (PP.isIncrementalProcessingEnabled() && Tok.is(tok::eof))
     ConsumeToken();
@@ -592,6 +533,12 @@
     ConsumeToken();
     return false;
 
+  case tok::annot_module_begin:
+  case tok::annot_module_end:
+    // FIXME: Update visibility based on the submodule we're in.
+    ConsumeToken();
+    return false;
+
   case tok::eof:
     // Late template parsing can begin.
     if (getLangOpts().DelayedTemplateParsing)
@@ -647,7 +594,7 @@
     return DeclGroupPtrTy();
   }
 
-  Decl *SingleDecl = 0;
+  Decl *SingleDecl = nullptr;
   switch (Tok.getKind()) {
   case tok::annot_pragma_vis:
     HandlePragmaVisibility();
@@ -679,6 +626,15 @@
   case tok::annot_pragma_openmp:
     ParseOpenMPDeclarativeDirective();
     return DeclGroupPtrTy();
+  case tok::annot_pragma_ms_pointers_to_members:
+    HandlePragmaMSPointersToMembers();
+    return DeclGroupPtrTy();
+  case tok::annot_pragma_ms_vtordisp:
+    HandlePragmaMSVtorDisp();
+    return DeclGroupPtrTy();
+  case tok::annot_pragma_ms_pragma:
+    HandlePragmaMSPragma();
+    return DeclGroupPtrTy();
   case tok::semi:
     // Either a C++11 empty-declaration or attribute-declaration.
     SingleDecl = Actions.ActOnEmptyDeclaration(getCurScope(),
@@ -706,7 +662,7 @@
     SourceLocation EndLoc;
     ExprResult Result(ParseSimpleAsm(&EndLoc));
 
-    ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
+    ExpectAndConsume(tok::semi, diag::err_expected_after,
                      "top-level asm block");
 
     if (Result.isInvalid())
@@ -793,7 +749,6 @@
                   ParseExplicitInstantiation(Declarator::FileContext,
                                              ExternLoc, TemplateLoc, DeclEnd));
     }
-    // FIXME: Detect C++ linkage specifications here?
     goto dont_know;
 
   case tok::kw___if_exists:
@@ -875,6 +830,12 @@
   // Parse the common declaration-specifiers piece.
   ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS, DSC_top_level);
 
+  // If we had a free-standing type definition with a missing semicolon, we
+  // may get this far before the problem becomes obvious.
+  if (DS.hasTagDefinition() &&
+      DiagnoseMissingSemiAfterTagDefinition(DS, AS, DSC_top_level))
+    return DeclGroupPtrTy();
+
   // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
   // declaration-specifiers init-declarator-list[opt] ';'
   if (Tok.is(tok::semi)) {
@@ -901,9 +862,10 @@
 
     DS.abort();
 
-    const char *PrevSpec = 0;
+    const char *PrevSpec = nullptr;
     unsigned DiagID;
-    if (DS.SetTypeSpecType(DeclSpec::TST_unspecified, AtLoc, PrevSpec, DiagID))
+    if (DS.SetTypeSpecType(DeclSpec::TST_unspecified, AtLoc, PrevSpec, DiagID,
+                           Actions.getASTContext().getPrintingPolicy()))
       Diag(AtLoc, DiagID) << PrevSpec;
 
     if (Tok.isObjCAtKeyword(tok::objc_protocol))
@@ -916,7 +878,7 @@
   // If the declspec consisted only of 'extern' and we have a string
   // literal following it, this must be a C++ linkage specifier like
   // 'extern "C"'.
-  if (Tok.is(tok::string_literal) && getLangOpts().CPlusPlus &&
+  if (getLangOpts().CPlusPlus && isTokenStringLiteral() &&
       DS.getStorageClassSpec() == DeclSpec::SCS_extern &&
       DS.getParsedSpecifiers() == DeclSpec::PQ_StorageClassSpecifier) {
     Decl *TheDecl = ParseLinkage(DS, Declarator::FileContext);
@@ -943,26 +905,6 @@
   }
 }
 
-
-static inline bool isFunctionDeclaratorRequiringReturnTypeDeduction(
-    const Declarator &D) {
-  if (!D.isFunctionDeclarator() || !D.getDeclSpec().containsPlaceholderType()) 
-    return false;
-  for (unsigned I = 0, E = D.getNumTypeObjects(); I != E; ++I) {
-    unsigned chunkIndex = E - I - 1;
-    const DeclaratorChunk &DeclType = D.getTypeObject(chunkIndex);
-    if (DeclType.Kind == DeclaratorChunk::Function) {
-      const DeclaratorChunk::FunctionTypeInfo &FTI = DeclType.Fun;
-      if (!FTI.hasTrailingReturnType()) 
-        return true;
-      QualType TrailingRetType = FTI.getTrailingReturnType().get();
-      return TrailingRetType->getCanonicalTypeInternal()
-        ->getContainedAutoType();
-    }
-  } 
-  return false;
-}
-
 /// ParseFunctionDefinition - We parsed and verified that the specified
 /// Declarator is well formed.  If this is a K&R-style function, read the
 /// parameters declaration-list, then start the compound-statement.
@@ -990,9 +932,11 @@
   if (getLangOpts().ImplicitInt && D.getDeclSpec().isEmpty()) {
     const char *PrevSpec;
     unsigned DiagID;
+    const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
     D.getMutableDeclSpec().SetTypeSpecType(DeclSpec::TST_int,
                                            D.getIdentifierLoc(),
-                                           PrevSpec, DiagID);
+                                           PrevSpec, DiagID,
+                                           Policy);
     D.SetRangeBegin(D.getDeclSpec().getSourceRange().getBegin());
   }
 
@@ -1015,7 +959,7 @@
 
     // If we didn't find the '{', bail out.
     if (Tok.isNot(tok::l_brace))
-      return 0;
+      return nullptr;
   }
 
   // Check to make sure that any normal attributes are allowed to be on
@@ -1023,10 +967,10 @@
   if (Tok.isNot(tok::equal)) {
     AttributeList *DtorAttrs = D.getAttributes();
     while (DtorAttrs) {
-      if (!IsThreadSafetyAttribute(DtorAttrs->getName()->getName()) &&
+      if (DtorAttrs->isKnownToGCC() &&
           !DtorAttrs->isCXX11Attribute()) {
         Diag(DtorAttrs->getLoc(), diag::warn_attribute_on_function_definition)
-          << DtorAttrs->getName()->getName();
+          << DtorAttrs->getName();
       }
       DtorAttrs = DtorAttrs->getNext();
     }
@@ -1036,8 +980,7 @@
   // tokens and store them for late parsing at the end of the translation unit.
   if (getLangOpts().DelayedTemplateParsing && Tok.isNot(tok::equal) &&
       TemplateInfo.Kind == ParsedTemplateInfo::Template &&
-      !D.getDeclSpec().isConstexprSpecified() && 
-      !isFunctionDeclaratorRequiringReturnTypeDeduction(D)) {
+      Actions.canDelayFunctionBody(D)) {
     MultiTemplateParamsArg TemplateParameterLists(*TemplateInfo.TemplateParams);
     
     ParseScope BodyScope(this, Scope::FnScope|Scope::DeclScope);
@@ -1053,12 +996,7 @@
     LexTemplateFunctionForLateParsing(Toks);
 
     if (DP) {
-      FunctionDecl *FnD = 0;
-      if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(DP))
-        FnD = FunTmpl->getTemplatedDecl();
-      else
-        FnD = cast<FunctionDecl>(DP);
-
+      FunctionDecl *FnD = DP->getAsFunction();
       Actions.CheckForFunctionRedefinition(FnD);
       Actions.MarkAsLateParsedTemplate(FnD, DP, Toks);
     }
@@ -1071,7 +1009,7 @@
       Actions.CurContext->isTranslationUnit()) {
     ParseScope BodyScope(this, Scope::FnScope|Scope::DeclScope);
     Scope *ParentScope = getCurScope()->getParent();
-    
+
     D.setFunctionDefinitionKind(FDK_Definition);
     Decl *FuncDecl = Actions.HandleDeclarator(ParentScope, D,
                                               MultiTemplateParamsArg());
@@ -1083,8 +1021,9 @@
       CurParsedObjCImpl->HasCFunction = true;
       return FuncDecl;
     }
+    // FIXME: Should we really fall through here?
   }
-      
+
   // Enter a scope for the function body.
   ParseScope BodyScope(this, Scope::FnScope|Scope::DeclScope);
 
@@ -1102,28 +1041,22 @@
   // safe because we're always the sole owner.
   D.getMutableDeclSpec().abort();
 
-  if (Tok.is(tok::equal)) {
+  if (TryConsumeToken(tok::equal)) {
     assert(getLangOpts().CPlusPlus && "Only C++ function definitions have '='");
-    ConsumeToken();
+    Actions.ActOnFinishFunctionBody(Res, nullptr, false);
 
-    Actions.ActOnFinishFunctionBody(Res, 0, false);
- 
     bool Delete = false;
     SourceLocation KWLoc;
-    if (Tok.is(tok::kw_delete)) {
-      Diag(Tok, getLangOpts().CPlusPlus11 ?
-           diag::warn_cxx98_compat_deleted_function :
-           diag::ext_deleted_function);
-
-      KWLoc = ConsumeToken();
+    if (TryConsumeToken(tok::kw_delete, KWLoc)) {
+      Diag(KWLoc, getLangOpts().CPlusPlus11
+                      ? diag::warn_cxx98_compat_deleted_function
+                      : diag::ext_deleted_function);
       Actions.SetDeclDeleted(Res, KWLoc);
       Delete = true;
-    } else if (Tok.is(tok::kw_default)) {
-      Diag(Tok, getLangOpts().CPlusPlus11 ?
-           diag::warn_cxx98_compat_defaulted_function :
-           diag::ext_defaulted_function);
-
-      KWLoc = ConsumeToken();
+    } else if (TryConsumeToken(tok::kw_default, KWLoc)) {
+      Diag(KWLoc, getLangOpts().CPlusPlus11
+                      ? diag::warn_cxx98_compat_defaulted_function
+                      : diag::ext_defaulted_function);
       Actions.SetDeclDefaulted(Res, KWLoc);
     } else {
       llvm_unreachable("function definition after = not 'delete' or 'default'");
@@ -1133,9 +1066,9 @@
       Diag(KWLoc, diag::err_default_delete_in_multiple_declaration)
         << Delete;
       SkipUntil(tok::semi);
-    } else {
-      ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
-                       Delete ? "delete" : "default", tok::semi);
+    } else if (ExpectAndConsume(tok::semi, diag::err_expected_after,
+                                Delete ? "delete" : "default")) {
+      SkipUntil(tok::semi);
     }
 
     return Res;
@@ -1152,7 +1085,7 @@
     // Recover from error.
     if (!Tok.is(tok::l_brace)) {
       BodyScope.Exit();
-      Actions.ActOnFinishFunctionBody(Res, 0);
+      Actions.ActOnFinishFunctionBody(Res, nullptr);
       return Res;
     }
   } else
@@ -1189,9 +1122,8 @@
     // NOTE: GCC just makes this an ext-warn.  It's not clear what it does with
     // the declarations though.  It's trivial to ignore them, really hard to do
     // anything else with them.
-    if (Tok.is(tok::semi)) {
+    if (TryConsumeToken(tok::semi)) {
       Diag(DSStart, diag::err_declaration_does_not_declare_param);
-      ConsumeToken();
       continue;
     }
 
@@ -1231,20 +1163,20 @@
         for (unsigned i = 0; ; ++i) {
           // C99 6.9.1p6: those declarators shall declare only identifiers from
           // the identifier list.
-          if (i == FTI.NumArgs) {
+          if (i == FTI.NumParams) {
             Diag(ParmDeclarator.getIdentifierLoc(), diag::err_no_matching_param)
               << ParmDeclarator.getIdentifier();
             break;
           }
 
-          if (FTI.ArgInfo[i].Ident == ParmDeclarator.getIdentifier()) {
+          if (FTI.Params[i].Ident == ParmDeclarator.getIdentifier()) {
             // Reject redefinitions of parameters.
-            if (FTI.ArgInfo[i].Param) {
+            if (FTI.Params[i].Param) {
               Diag(ParmDeclarator.getIdentifierLoc(),
                    diag::err_param_redefinition)
                  << ParmDeclarator.getIdentifier();
             } else {
-              FTI.ArgInfo[i].Param = Param;
+              FTI.Params[i].Param = Param;
             }
             break;
           }
@@ -1265,12 +1197,14 @@
       ParseDeclarator(ParmDeclarator);
     }
 
-    if (ExpectAndConsumeSemi(diag::err_expected_semi_declaration)) {
-      // Skip to end of block or statement
-      SkipUntil(tok::semi);
-      if (Tok.is(tok::semi))
-        ConsumeToken();
-    }
+    // Consume ';' and continue parsing.
+    if (!ExpectAndConsumeSemi(diag::err_expected_semi_declaration))
+      continue;
+
+    // Otherwise recover by skipping to next semi or mandatory function body.
+    if (SkipUntil(tok::l_brace, StopAtSemi | StopBeforeMatch))
+      break;
+    TryConsumeToken(tok::semi);
   }
 
   // The actions module must verify that all arguments were declared.
@@ -1334,16 +1268,15 @@
 
   ExprResult Result(ParseAsmStringLiteral());
 
-  if (Result.isInvalid()) {
-    SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch);
-    if (EndLoc)
-      *EndLoc = Tok.getLocation();
-    ConsumeAnyToken();
-  } else {
+  if (!Result.isInvalid()) {
     // Close the paren and get the location of the end bracket
     T.consumeClose();
     if (EndLoc)
       *EndLoc = T.getCloseLocation();
+  } else if (SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch)) {
+    if (EndLoc)
+      *EndLoc = Tok.getLocation();
+    ConsumeParen();
   }
 
   return Result;
@@ -1424,11 +1357,11 @@
 
   // Look up and classify the identifier. We don't perform any typo-correction
   // after a scope specifier, because in general we can't recover from typos
-  // there (eg, after correcting 'A::tempalte B<X>::C', we would need to jump
-  // back into scope specifier parsing).
+  // there (eg, after correcting 'A::tempalte B<X>::C' [sic], we would need to
+  // jump back into scope specifier parsing).
   Sema::NameClassification Classification
     = Actions.ClassifyName(getCurScope(), SS, Name, NameLoc, Next,
-                           IsAddressOfOperand, SS.isEmpty() ? CCC : 0);
+                           IsAddressOfOperand, SS.isEmpty() ? CCC : nullptr);
 
   switch (Classification.getKind()) {
   case Sema::NC_Error:
@@ -1497,6 +1430,35 @@
   return ANK_Unresolved;
 }
 
+bool Parser::TryKeywordIdentFallback(bool DisableKeyword) {
+  assert(!Tok.is(tok::identifier) && !Tok.isAnnotation());
+  Diag(Tok, diag::ext_keyword_as_ident)
+    << PP.getSpelling(Tok)
+    << DisableKeyword;
+  if (DisableKeyword) {
+    IdentifierInfo *II = Tok.getIdentifierInfo();
+    ContextualKeywords[II] = Tok.getKind();
+    II->RevertTokenIDToIdentifier();
+  }
+  Tok.setKind(tok::identifier);
+  return true;
+}
+
+bool Parser::TryIdentKeywordUpgrade() {
+  assert(Tok.is(tok::identifier));
+  const IdentifierInfo *II = Tok.getIdentifierInfo();
+  assert(II->hasRevertedTokenIDToIdentifier());
+  // If we find that this is in fact the name of a type trait,
+  // update the token kind in place and parse again to treat it as
+  // the appropriate kind of type trait.
+  llvm::SmallDenseMap<const IdentifierInfo *, tok::TokenKind>::iterator Known =
+      ContextualKeywords.find(II);
+  if (Known == ContextualKeywords.end())
+    return false;
+  Tok.setKind(Known->second);
+  return true;
+}
+
 /// TryAnnotateTypeOrScopeToken - If the current token position is on a
 /// typename (possibly qualified in C++) or a C++ scope specifier not followed
 /// by a typename, TryAnnotateTypeOrScopeToken will replace one or more tokens
@@ -1532,7 +1494,7 @@
     // We will consume the typedef token here and put it back after we have
     // parsed the first identifier, transforming it into something more like:
     //   typename T_::D typedef D;
-    if (getLangOpts().MicrosoftMode && NextToken().is(tok::kw_typedef)) {
+    if (getLangOpts().MSVCCompat && NextToken().is(tok::kw_typedef)) {
       Token TypedefToken;
       PP.Lex(TypedefToken);
       bool Result = TryAnnotateTypeOrScopeToken(EnteringContext, NeedType);
@@ -1553,7 +1515,7 @@
     CXXScopeSpec SS;
     if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/ParsedType(), 
                                        /*EnteringContext=*/false,
-                                       0, /*IsTypename*/true))
+                                       nullptr, /*IsTypename*/ true))
       return true;
     if (!SS.isSet()) {
       if (Tok.is(tok::identifier) || Tok.is(tok::annot_template_id) ||
@@ -1584,7 +1546,8 @@
                                      Tok.getLocation());
     } else if (Tok.is(tok::annot_template_id)) {
       TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
-      if (TemplateId->Kind == TNK_Function_template) {
+      if (TemplateId->Kind != TNK_Type_template &&
+          TemplateId->Kind != TNK_Dependent_template_name) {
         Diag(Tok, diag::err_typename_refers_to_non_type_template)
           << Tok.getAnnotationRange();
         return true;
@@ -1635,7 +1598,7 @@
                                                        CXXScopeSpec &SS,
                                                        bool IsNewScope) {
   if (Tok.is(tok::identifier)) {
-    IdentifierInfo *CorrectedII = 0;
+    IdentifierInfo *CorrectedII = nullptr;
     // Determine whether the identifier is a type name.
     if (ParsedType Ty = Actions.getTypeName(*Tok.getIdentifierInfo(),
                                             Tok.getLocation(), getCurScope(),
@@ -1643,8 +1606,9 @@
                                             NextToken().is(tok::period),
                                             ParsedType(),
                                             /*IsCtorOrDtorName=*/false,
-                                            /*NonTrivialTypeSourceInfo*/true,
-                                            NeedType ? &CorrectedII : NULL)) {
+                                            /*NonTrivialTypeSourceInfo*/ true,
+                                            NeedType ? &CorrectedII
+                                                     : nullptr)) {
       // A FixIt was applied as a result of typo correction
       if (CorrectedII)
         Tok.setIdentifierInfo(CorrectedII);
@@ -1708,8 +1672,7 @@
       // annotation token to a type annotation token now.
       AnnotateTemplateIdTokenAsType();
       return false;
-    } else if (TemplateId->Kind == TNK_Var_template)
-      return false;
+    }
   }
 
   if (SS.isEmpty())
@@ -1763,8 +1726,8 @@
   case tok::pipeequal:           // |=
   case tok::equalequal:          // ==
     Diag(Tok, diag::err_invalid_token_after_declarator_suggest_equal)
-      << getTokenSimpleSpelling(Kind)
-      << FixItHint::CreateReplacement(SourceRange(Tok.getLocation()), "=");
+        << Kind
+        << FixItHint::CreateReplacement(SourceRange(Tok.getLocation()), "=");
   case tok::equal:
     return true;
   }
@@ -1893,7 +1856,7 @@
   
   BalancedDelimiterTracker Braces(*this, tok::l_brace);
   if (Braces.consumeOpen()) {
-    Diag(Tok, diag::err_expected_lbrace);
+    Diag(Tok, diag::err_expected) << tok::l_brace;
     return;
   }
 
@@ -1911,14 +1874,15 @@
   }
 
   // Parse the declarations.
-  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
+  // FIXME: Support module import within __if_exists?
+  while (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
     ParsedAttributesWithRange attrs(AttrFactory);
     MaybeParseCXX11Attributes(attrs);
     MaybeParseMicrosoftAttributes(attrs);
     DeclGroupPtrTy Result = ParseExternalDeclaration(attrs);
     if (Result && !getCurScope()->getParent())
       Actions.getASTConsumer().HandleTopLevelDecl(Result.get());
-  }     
+  }
   Braces.consumeClose();
 }
 
@@ -1934,8 +1898,7 @@
     if (!Tok.is(tok::identifier)) {
       if (Tok.is(tok::code_completion)) {
         Actions.CodeCompleteModuleImport(ImportLoc, Path);
-        ConsumeCodeCompletionToken();
-        SkipUntil(tok::semi);
+        cutOffParsing();
         return DeclGroupPtrTy();
       }
       
@@ -1974,17 +1937,20 @@
   P.Diag(P.Tok, diag::err_bracket_depth_exceeded)
     << P.getLangOpts().BracketDepth;
   P.Diag(P.Tok, diag::note_bracket_depth);
-  P.SkipUntil(tok::eof);
-  return true;  
+  P.cutOffParsing();
+  return true;
 }
 
 bool BalancedDelimiterTracker::expectAndConsume(unsigned DiagID,
-                                            const char *Msg,
-                                            tok::TokenKind SkipToToc ) {
+                                                const char *Msg,
+                                                tok::TokenKind SkipToTok) {
   LOpen = P.Tok.getLocation();
-  if (P.ExpectAndConsume(Kind, DiagID, Msg, SkipToToc))
+  if (P.ExpectAndConsume(Kind, DiagID, Msg)) {
+    if (SkipToTok != tok::unknown)
+      P.SkipUntil(SkipToTok, Parser::StopAtSemi);
     return true;
-  
+  }
+
   if (getDepth() < MaxDepth)
     return false;
     
@@ -1993,17 +1959,9 @@
 
 bool BalancedDelimiterTracker::diagnoseMissingClose() {
   assert(!P.Tok.is(Close) && "Should have consumed closing delimiter");
-  
-  const char *LHSName = "unknown";
-  diag::kind DID;
-  switch (Close) {
-  default: llvm_unreachable("Unexpected balanced token");
-  case tok::r_paren : LHSName = "("; DID = diag::err_expected_rparen; break;
-  case tok::r_brace : LHSName = "{"; DID = diag::err_expected_rbrace; break;
-  case tok::r_square: LHSName = "["; DID = diag::err_expected_rsquare; break;
-  }
-  P.Diag(P.Tok, DID);
-  P.Diag(LOpen, diag::note_matching) << LHSName;
+
+  P.Diag(P.Tok, diag::err_expected) << Close;
+  P.Diag(LOpen, diag::note_matching) << Kind;
 
   // If we're not already at some kind of closing bracket, skip to our closing
   // token.
diff --git a/lib/Parse/RAIIObjectsForParser.h b/lib/Parse/RAIIObjectsForParser.h
index f68a2e0..4f5f3ab 100644
--- a/lib/Parse/RAIIObjectsForParser.h
+++ b/lib/Parse/RAIIObjectsForParser.h
@@ -50,7 +50,7 @@
   public:
     /// Begin suppressing access-like checks 
     SuppressAccessChecks(Parser &P, bool activate = true)
-        : S(P.getActions()), DiagnosticPool(NULL) {
+        : S(P.getActions()), DiagnosticPool(nullptr) {
       if (activate) {
         State = S.PushParsingDeclaration(DiagnosticPool);
         Active = true;
@@ -61,7 +61,7 @@
 
     void done() {
       assert(Active && "trying to end an inactive suppression");
-      S.PopParsingDeclaration(State, NULL);
+      S.PopParsingDeclaration(State, nullptr);
       Active = false;
     }
 
@@ -93,7 +93,7 @@
   public:
     enum NoParent_t { NoParent };
     ParsingDeclRAIIObject(Parser &P, NoParent_t _)
-        : Actions(P.getActions()), DiagnosticPool(NULL) {
+        : Actions(P.getActions()), DiagnosticPool(nullptr) {
       push();
     }
 
@@ -109,7 +109,7 @@
     /// RAII object (which is assumed to be the current top pool).
     ParsingDeclRAIIObject(Parser &P, ParsingDeclRAIIObject *other)
         : Actions(P.getActions()),
-          DiagnosticPool(other ? other->DiagnosticPool.getParent() : NULL) {
+          DiagnosticPool(other ? other->DiagnosticPool.getParent() : nullptr) {
       if (other) {
         DiagnosticPool.steal(other->DiagnosticPool);
         other->abort();
@@ -137,7 +137,7 @@
     /// Signals that the context was completed without an appropriate
     /// declaration being parsed.
     void abort() {
-      pop(0);
+      pop(nullptr);
     }
 
     void complete(Decl *D) {
@@ -148,7 +148,7 @@
     /// Unregister this object from Sema, but remember all the
     /// diagnostics that were emitted into it.
     void abortAndRemember() {
-      pop(0);
+      pop(nullptr);
     }
 
   private:
@@ -415,8 +415,8 @@
       
       return diagnoseOverflow();
     }
-    
-    bool expectAndConsume(unsigned DiagID,
+
+    bool expectAndConsume(unsigned DiagID = diag::err_expected,
                           const char *Msg = "",
                           tok::TokenKind SkipToTok = tok::unknown);
     bool consumeClose() {
diff --git a/lib/Rewrite/CMakeLists.txt b/lib/Rewrite/CMakeLists.txt
index d3d7543..0c77536 100644
--- a/lib/Rewrite/CMakeLists.txt
+++ b/lib/Rewrite/CMakeLists.txt
@@ -1,2 +1,16 @@
-add_subdirectory(Core)
-add_subdirectory(Frontend)
+set(LLVM_LINK_COMPONENTS
+  Support
+  )
+
+add_clang_library(clangRewrite
+  DeltaTree.cpp
+  HTMLRewrite.cpp
+  RewriteRope.cpp
+  Rewriter.cpp
+  TokenRewriter.cpp
+
+  LINK_LIBS
+  clangAST
+  clangBasic
+  clangLex
+  )
diff --git a/lib/Rewrite/Core/CMakeLists.txt b/lib/Rewrite/Core/CMakeLists.txt
deleted file mode 100644
index 0797818..0000000
--- a/lib/Rewrite/Core/CMakeLists.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-add_clang_library(clangRewriteCore
-  DeltaTree.cpp
-  HTMLRewrite.cpp
-  RewriteRope.cpp
-  Rewriter.cpp
-  TokenRewriter.cpp
-  )
-
-add_dependencies(clangRewriteCore
-  ClangAttrClasses
-  ClangAttrList
-  ClangAttrParsedAttrList
-  ClangCommentNodes
-  ClangDeclNodes
-  ClangDiagnosticCommon
-  ClangDiagnosticFrontend
-  ClangStmtNodes
-  )
-
-target_link_libraries(clangRewriteCore
-  clangBasic
-  clangAST
-  clangParse
-  )
diff --git a/lib/Rewrite/Core/DeltaTree.cpp b/lib/Rewrite/Core/DeltaTree.cpp
deleted file mode 100644
index 7a7f15b..0000000
--- a/lib/Rewrite/Core/DeltaTree.cpp
+++ /dev/null
@@ -1,464 +0,0 @@
-//===--- DeltaTree.cpp - B-Tree for Rewrite Delta tracking ----------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the DeltaTree and related classes.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Rewrite/Core/DeltaTree.h"
-#include "clang/Basic/LLVM.h"
-#include <cstdio>
-#include <cstring>
-using namespace clang;
-
-/// The DeltaTree class is a multiway search tree (BTree) structure with some
-/// fancy features.  B-Trees are generally more memory and cache efficient
-/// than binary trees, because they store multiple keys/values in each node.
-///
-/// DeltaTree implements a key/value mapping from FileIndex to Delta, allowing
-/// fast lookup by FileIndex.  However, an added (important) bonus is that it
-/// can also efficiently tell us the full accumulated delta for a specific
-/// file offset as well, without traversing the whole tree.
-///
-/// The nodes of the tree are made up of instances of two classes:
-/// DeltaTreeNode and DeltaTreeInteriorNode.  The later subclasses the
-/// former and adds children pointers.  Each node knows the full delta of all
-/// entries (recursively) contained inside of it, which allows us to get the
-/// full delta implied by a whole subtree in constant time.
-
-namespace {
-  /// SourceDelta - As code in the original input buffer is added and deleted,
-  /// SourceDelta records are used to keep track of how the input SourceLocation
-  /// object is mapped into the output buffer.
-  struct SourceDelta {
-    unsigned FileLoc;
-    int Delta;
-
-    static SourceDelta get(unsigned Loc, int D) {
-      SourceDelta Delta;
-      Delta.FileLoc = Loc;
-      Delta.Delta = D;
-      return Delta;
-    }
-  };
-  
-  /// DeltaTreeNode - The common part of all nodes.
-  ///
-  class DeltaTreeNode {
-  public:
-    struct InsertResult {
-      DeltaTreeNode *LHS, *RHS;
-      SourceDelta Split;
-    };
-    
-  private:
-    friend class DeltaTreeInteriorNode;
-
-    /// WidthFactor - This controls the number of K/V slots held in the BTree:
-    /// how wide it is.  Each level of the BTree is guaranteed to have at least
-    /// WidthFactor-1 K/V pairs (except the root) and may have at most
-    /// 2*WidthFactor-1 K/V pairs.
-    enum { WidthFactor = 8 };
-
-    /// Values - This tracks the SourceDelta's currently in this node.
-    ///
-    SourceDelta Values[2*WidthFactor-1];
-
-    /// NumValuesUsed - This tracks the number of values this node currently
-    /// holds.
-    unsigned char NumValuesUsed;
-
-    /// IsLeaf - This is true if this is a leaf of the btree.  If false, this is
-    /// an interior node, and is actually an instance of DeltaTreeInteriorNode.
-    bool IsLeaf;
-
-    /// FullDelta - This is the full delta of all the values in this node and
-    /// all children nodes.
-    int FullDelta;
-  public:
-    DeltaTreeNode(bool isLeaf = true)
-      : NumValuesUsed(0), IsLeaf(isLeaf), FullDelta(0) {}
-
-    bool isLeaf() const { return IsLeaf; }
-    int getFullDelta() const { return FullDelta; }
-    bool isFull() const { return NumValuesUsed == 2*WidthFactor-1; }
-
-    unsigned getNumValuesUsed() const { return NumValuesUsed; }
-    const SourceDelta &getValue(unsigned i) const {
-      assert(i < NumValuesUsed && "Invalid value #");
-      return Values[i];
-    }
-    SourceDelta &getValue(unsigned i) {
-      assert(i < NumValuesUsed && "Invalid value #");
-      return Values[i];
-    }
-
-    /// DoInsertion - Do an insertion of the specified FileIndex/Delta pair into
-    /// this node.  If insertion is easy, do it and return false.  Otherwise,
-    /// split the node, populate InsertRes with info about the split, and return
-    /// true.
-    bool DoInsertion(unsigned FileIndex, int Delta, InsertResult *InsertRes);
-
-    void DoSplit(InsertResult &InsertRes);
-
-
-    /// RecomputeFullDeltaLocally - Recompute the FullDelta field by doing a
-    /// local walk over our contained deltas.
-    void RecomputeFullDeltaLocally();
-
-    void Destroy();
-  };
-} // end anonymous namespace
-
-namespace {
-  /// DeltaTreeInteriorNode - When isLeaf = false, a node has child pointers.
-  /// This class tracks them.
-  class DeltaTreeInteriorNode : public DeltaTreeNode {
-    DeltaTreeNode *Children[2*WidthFactor];
-    ~DeltaTreeInteriorNode() {
-      for (unsigned i = 0, e = NumValuesUsed+1; i != e; ++i)
-        Children[i]->Destroy();
-    }
-    friend class DeltaTreeNode;
-  public:
-    DeltaTreeInteriorNode() : DeltaTreeNode(false /*nonleaf*/) {}
-
-    DeltaTreeInteriorNode(const InsertResult &IR)
-      : DeltaTreeNode(false /*nonleaf*/) {
-      Children[0] = IR.LHS;
-      Children[1] = IR.RHS;
-      Values[0] = IR.Split;
-      FullDelta = IR.LHS->getFullDelta()+IR.RHS->getFullDelta()+IR.Split.Delta;
-      NumValuesUsed = 1;
-    }
-
-    const DeltaTreeNode *getChild(unsigned i) const {
-      assert(i < getNumValuesUsed()+1 && "Invalid child");
-      return Children[i];
-    }
-    DeltaTreeNode *getChild(unsigned i) {
-      assert(i < getNumValuesUsed()+1 && "Invalid child");
-      return Children[i];
-    }
-
-    static inline bool classof(const DeltaTreeNode *N) { return !N->isLeaf(); }
-  };
-}
-
-
-/// Destroy - A 'virtual' destructor.
-void DeltaTreeNode::Destroy() {
-  if (isLeaf())
-    delete this;
-  else
-    delete cast<DeltaTreeInteriorNode>(this);
-}
-
-/// RecomputeFullDeltaLocally - Recompute the FullDelta field by doing a
-/// local walk over our contained deltas.
-void DeltaTreeNode::RecomputeFullDeltaLocally() {
-  int NewFullDelta = 0;
-  for (unsigned i = 0, e = getNumValuesUsed(); i != e; ++i)
-    NewFullDelta += Values[i].Delta;
-  if (DeltaTreeInteriorNode *IN = dyn_cast<DeltaTreeInteriorNode>(this))
-    for (unsigned i = 0, e = getNumValuesUsed()+1; i != e; ++i)
-      NewFullDelta += IN->getChild(i)->getFullDelta();
-  FullDelta = NewFullDelta;
-}
-
-/// DoInsertion - Do an insertion of the specified FileIndex/Delta pair into
-/// this node.  If insertion is easy, do it and return false.  Otherwise,
-/// split the node, populate InsertRes with info about the split, and return
-/// true.
-bool DeltaTreeNode::DoInsertion(unsigned FileIndex, int Delta,
-                                InsertResult *InsertRes) {
-  // Maintain full delta for this node.
-  FullDelta += Delta;
-
-  // Find the insertion point, the first delta whose index is >= FileIndex.
-  unsigned i = 0, e = getNumValuesUsed();
-  while (i != e && FileIndex > getValue(i).FileLoc)
-    ++i;
-
-  // If we found an a record for exactly this file index, just merge this
-  // value into the pre-existing record and finish early.
-  if (i != e && getValue(i).FileLoc == FileIndex) {
-    // NOTE: Delta could drop to zero here.  This means that the delta entry is
-    // useless and could be removed.  Supporting erases is more complex than
-    // leaving an entry with Delta=0, so we just leave an entry with Delta=0 in
-    // the tree.
-    Values[i].Delta += Delta;
-    return false;
-  }
-
-  // Otherwise, we found an insertion point, and we know that the value at the
-  // specified index is > FileIndex.  Handle the leaf case first.
-  if (isLeaf()) {
-    if (!isFull()) {
-      // For an insertion into a non-full leaf node, just insert the value in
-      // its sorted position.  This requires moving later values over.
-      if (i != e)
-        memmove(&Values[i+1], &Values[i], sizeof(Values[0])*(e-i));
-      Values[i] = SourceDelta::get(FileIndex, Delta);
-      ++NumValuesUsed;
-      return false;
-    }
-
-    // Otherwise, if this is leaf is full, split the node at its median, insert
-    // the value into one of the children, and return the result.
-    assert(InsertRes && "No result location specified");
-    DoSplit(*InsertRes);
-
-    if (InsertRes->Split.FileLoc > FileIndex)
-      InsertRes->LHS->DoInsertion(FileIndex, Delta, 0 /*can't fail*/);
-    else
-      InsertRes->RHS->DoInsertion(FileIndex, Delta, 0 /*can't fail*/);
-    return true;
-  }
-
-  // Otherwise, this is an interior node.  Send the request down the tree.
-  DeltaTreeInteriorNode *IN = cast<DeltaTreeInteriorNode>(this);
-  if (!IN->Children[i]->DoInsertion(FileIndex, Delta, InsertRes))
-    return false; // If there was space in the child, just return.
-
-  // Okay, this split the subtree, producing a new value and two children to
-  // insert here.  If this node is non-full, we can just insert it directly.
-  if (!isFull()) {
-    // Now that we have two nodes and a new element, insert the perclated value
-    // into ourself by moving all the later values/children down, then inserting
-    // the new one.
-    if (i != e)
-      memmove(&IN->Children[i+2], &IN->Children[i+1],
-              (e-i)*sizeof(IN->Children[0]));
-    IN->Children[i] = InsertRes->LHS;
-    IN->Children[i+1] = InsertRes->RHS;
-
-    if (e != i)
-      memmove(&Values[i+1], &Values[i], (e-i)*sizeof(Values[0]));
-    Values[i] = InsertRes->Split;
-    ++NumValuesUsed;
-    return false;
-  }
-
-  // Finally, if this interior node was full and a node is percolated up, split
-  // ourself and return that up the chain.  Start by saving all our info to
-  // avoid having the split clobber it.
-  IN->Children[i] = InsertRes->LHS;
-  DeltaTreeNode *SubRHS = InsertRes->RHS;
-  SourceDelta SubSplit = InsertRes->Split;
-
-  // Do the split.
-  DoSplit(*InsertRes);
-
-  // Figure out where to insert SubRHS/NewSplit.
-  DeltaTreeInteriorNode *InsertSide;
-  if (SubSplit.FileLoc < InsertRes->Split.FileLoc)
-    InsertSide = cast<DeltaTreeInteriorNode>(InsertRes->LHS);
-  else
-    InsertSide = cast<DeltaTreeInteriorNode>(InsertRes->RHS);
-
-  // We now have a non-empty interior node 'InsertSide' to insert
-  // SubRHS/SubSplit into.  Find out where to insert SubSplit.
-
-  // Find the insertion point, the first delta whose index is >SubSplit.FileLoc.
-  i = 0; e = InsertSide->getNumValuesUsed();
-  while (i != e && SubSplit.FileLoc > InsertSide->getValue(i).FileLoc)
-    ++i;
-
-  // Now we know that i is the place to insert the split value into.  Insert it
-  // and the child right after it.
-  if (i != e)
-    memmove(&InsertSide->Children[i+2], &InsertSide->Children[i+1],
-            (e-i)*sizeof(IN->Children[0]));
-  InsertSide->Children[i+1] = SubRHS;
-
-  if (e != i)
-    memmove(&InsertSide->Values[i+1], &InsertSide->Values[i],
-            (e-i)*sizeof(Values[0]));
-  InsertSide->Values[i] = SubSplit;
-  ++InsertSide->NumValuesUsed;
-  InsertSide->FullDelta += SubSplit.Delta + SubRHS->getFullDelta();
-  return true;
-}
-
-/// DoSplit - Split the currently full node (which has 2*WidthFactor-1 values)
-/// into two subtrees each with "WidthFactor-1" values and a pivot value.
-/// Return the pieces in InsertRes.
-void DeltaTreeNode::DoSplit(InsertResult &InsertRes) {
-  assert(isFull() && "Why split a non-full node?");
-
-  // Since this node is full, it contains 2*WidthFactor-1 values.  We move
-  // the first 'WidthFactor-1' values to the LHS child (which we leave in this
-  // node), propagate one value up, and move the last 'WidthFactor-1' values
-  // into the RHS child.
-
-  // Create the new child node.
-  DeltaTreeNode *NewNode;
-  if (DeltaTreeInteriorNode *IN = dyn_cast<DeltaTreeInteriorNode>(this)) {
-    // If this is an interior node, also move over 'WidthFactor' children
-    // into the new node.
-    DeltaTreeInteriorNode *New = new DeltaTreeInteriorNode();
-    memcpy(&New->Children[0], &IN->Children[WidthFactor],
-           WidthFactor*sizeof(IN->Children[0]));
-    NewNode = New;
-  } else {
-    // Just create the new leaf node.
-    NewNode = new DeltaTreeNode();
-  }
-
-  // Move over the last 'WidthFactor-1' values from here to NewNode.
-  memcpy(&NewNode->Values[0], &Values[WidthFactor],
-         (WidthFactor-1)*sizeof(Values[0]));
-
-  // Decrease the number of values in the two nodes.
-  NewNode->NumValuesUsed = NumValuesUsed = WidthFactor-1;
-
-  // Recompute the two nodes' full delta.
-  NewNode->RecomputeFullDeltaLocally();
-  RecomputeFullDeltaLocally();
-
-  InsertRes.LHS = this;
-  InsertRes.RHS = NewNode;
-  InsertRes.Split = Values[WidthFactor-1];
-}
-
-
-
-//===----------------------------------------------------------------------===//
-//                        DeltaTree Implementation
-//===----------------------------------------------------------------------===//
-
-//#define VERIFY_TREE
-
-#ifdef VERIFY_TREE
-/// VerifyTree - Walk the btree performing assertions on various properties to
-/// verify consistency.  This is useful for debugging new changes to the tree.
-static void VerifyTree(const DeltaTreeNode *N) {
-  const DeltaTreeInteriorNode *IN = dyn_cast<DeltaTreeInteriorNode>(N);
-  if (IN == 0) {
-    // Verify leaves, just ensure that FullDelta matches up and the elements
-    // are in proper order.
-    int FullDelta = 0;
-    for (unsigned i = 0, e = N->getNumValuesUsed(); i != e; ++i) {
-      if (i)
-        assert(N->getValue(i-1).FileLoc < N->getValue(i).FileLoc);
-      FullDelta += N->getValue(i).Delta;
-    }
-    assert(FullDelta == N->getFullDelta());
-    return;
-  }
-
-  // Verify interior nodes: Ensure that FullDelta matches up and the
-  // elements are in proper order and the children are in proper order.
-  int FullDelta = 0;
-  for (unsigned i = 0, e = IN->getNumValuesUsed(); i != e; ++i) {
-    const SourceDelta &IVal = N->getValue(i);
-    const DeltaTreeNode *IChild = IN->getChild(i);
-    if (i)
-      assert(IN->getValue(i-1).FileLoc < IVal.FileLoc);
-    FullDelta += IVal.Delta;
-    FullDelta += IChild->getFullDelta();
-
-    // The largest value in child #i should be smaller than FileLoc.
-    assert(IChild->getValue(IChild->getNumValuesUsed()-1).FileLoc <
-           IVal.FileLoc);
-
-    // The smallest value in child #i+1 should be larger than FileLoc.
-    assert(IN->getChild(i+1)->getValue(0).FileLoc > IVal.FileLoc);
-    VerifyTree(IChild);
-  }
-
-  FullDelta += IN->getChild(IN->getNumValuesUsed())->getFullDelta();
-
-  assert(FullDelta == N->getFullDelta());
-}
-#endif  // VERIFY_TREE
-
-static DeltaTreeNode *getRoot(void *Root) {
-  return (DeltaTreeNode*)Root;
-}
-
-DeltaTree::DeltaTree() {
-  Root = new DeltaTreeNode();
-}
-DeltaTree::DeltaTree(const DeltaTree &RHS) {
-  // Currently we only support copying when the RHS is empty.
-  assert(getRoot(RHS.Root)->getNumValuesUsed() == 0 &&
-         "Can only copy empty tree");
-  Root = new DeltaTreeNode();
-}
-
-DeltaTree::~DeltaTree() {
-  getRoot(Root)->Destroy();
-}
-
-/// getDeltaAt - Return the accumulated delta at the specified file offset.
-/// This includes all insertions or delections that occurred *before* the
-/// specified file index.
-int DeltaTree::getDeltaAt(unsigned FileIndex) const {
-  const DeltaTreeNode *Node = getRoot(Root);
-
-  int Result = 0;
-
-  // Walk down the tree.
-  while (1) {
-    // For all nodes, include any local deltas before the specified file
-    // index by summing them up directly.  Keep track of how many were
-    // included.
-    unsigned NumValsGreater = 0;
-    for (unsigned e = Node->getNumValuesUsed(); NumValsGreater != e;
-         ++NumValsGreater) {
-      const SourceDelta &Val = Node->getValue(NumValsGreater);
-
-      if (Val.FileLoc >= FileIndex)
-        break;
-      Result += Val.Delta;
-    }
-
-    // If we have an interior node, include information about children and
-    // recurse.  Otherwise, if we have a leaf, we're done.
-    const DeltaTreeInteriorNode *IN = dyn_cast<DeltaTreeInteriorNode>(Node);
-    if (!IN) return Result;
-
-    // Include any children to the left of the values we skipped, all of
-    // their deltas should be included as well.
-    for (unsigned i = 0; i != NumValsGreater; ++i)
-      Result += IN->getChild(i)->getFullDelta();
-
-    // If we found exactly the value we were looking for, break off the
-    // search early.  There is no need to search the RHS of the value for
-    // partial results.
-    if (NumValsGreater != Node->getNumValuesUsed() &&
-        Node->getValue(NumValsGreater).FileLoc == FileIndex)
-      return Result+IN->getChild(NumValsGreater)->getFullDelta();
-
-    // Otherwise, traverse down the tree.  The selected subtree may be
-    // partially included in the range.
-    Node = IN->getChild(NumValsGreater);
-  }
-  // NOT REACHED.
-}
-
-/// AddDelta - When a change is made that shifts around the text buffer,
-/// this method is used to record that info.  It inserts a delta of 'Delta'
-/// into the current DeltaTree at offset FileIndex.
-void DeltaTree::AddDelta(unsigned FileIndex, int Delta) {
-  assert(Delta && "Adding a noop?");
-  DeltaTreeNode *MyRoot = getRoot(Root);
-
-  DeltaTreeNode::InsertResult InsertRes;
-  if (MyRoot->DoInsertion(FileIndex, Delta, &InsertRes)) {
-    Root = MyRoot = new DeltaTreeInteriorNode(InsertRes);
-  }
-
-#ifdef VERIFY_TREE
-  VerifyTree(MyRoot);
-#endif
-}
-
diff --git a/lib/Rewrite/Core/HTMLRewrite.cpp b/lib/Rewrite/Core/HTMLRewrite.cpp
deleted file mode 100644
index 4da00a8..0000000
--- a/lib/Rewrite/Core/HTMLRewrite.cpp
+++ /dev/null
@@ -1,582 +0,0 @@
-//== HTMLRewrite.cpp - Translate source code into prettified HTML --*- C++ -*-//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-//  This file defines the HTMLRewriter clas, which is used to translate the
-//  text of a source file into prettified HTML.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Rewrite/Core/HTMLRewrite.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Lex/TokenConcatenation.h"
-#include "clang/Rewrite/Core/Rewriter.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/raw_ostream.h"
-using namespace clang;
-
-
-/// HighlightRange - Highlight a range in the source code with the specified
-/// start/end tags.  B/E must be in the same file.  This ensures that
-/// start/end tags are placed at the start/end of each line if the range is
-/// multiline.
-void html::HighlightRange(Rewriter &R, SourceLocation B, SourceLocation E,
-                          const char *StartTag, const char *EndTag) {
-  SourceManager &SM = R.getSourceMgr();
-  B = SM.getExpansionLoc(B);
-  E = SM.getExpansionLoc(E);
-  FileID FID = SM.getFileID(B);
-  assert(SM.getFileID(E) == FID && "B/E not in the same file!");
-
-  unsigned BOffset = SM.getFileOffset(B);
-  unsigned EOffset = SM.getFileOffset(E);
-
-  // Include the whole end token in the range.
-  EOffset += Lexer::MeasureTokenLength(E, R.getSourceMgr(), R.getLangOpts());
-
-  bool Invalid = false;
-  const char *BufferStart = SM.getBufferData(FID, &Invalid).data();
-  if (Invalid)
-    return;
-  
-  HighlightRange(R.getEditBuffer(FID), BOffset, EOffset,
-                 BufferStart, StartTag, EndTag);
-}
-
-/// HighlightRange - This is the same as the above method, but takes
-/// decomposed file locations.
-void html::HighlightRange(RewriteBuffer &RB, unsigned B, unsigned E,
-                          const char *BufferStart,
-                          const char *StartTag, const char *EndTag) {
-  // Insert the tag at the absolute start/end of the range.
-  RB.InsertTextAfter(B, StartTag);
-  RB.InsertTextBefore(E, EndTag);
-
-  // Scan the range to see if there is a \r or \n.  If so, and if the line is
-  // not blank, insert tags on that line as well.
-  bool HadOpenTag = true;
-
-  unsigned LastNonWhiteSpace = B;
-  for (unsigned i = B; i != E; ++i) {
-    switch (BufferStart[i]) {
-    case '\r':
-    case '\n':
-      // Okay, we found a newline in the range.  If we have an open tag, we need
-      // to insert a close tag at the first non-whitespace before the newline.
-      if (HadOpenTag)
-        RB.InsertTextBefore(LastNonWhiteSpace+1, EndTag);
-
-      // Instead of inserting an open tag immediately after the newline, we
-      // wait until we see a non-whitespace character.  This prevents us from
-      // inserting tags around blank lines, and also allows the open tag to
-      // be put *after* whitespace on a non-blank line.
-      HadOpenTag = false;
-      break;
-    case '\0':
-    case ' ':
-    case '\t':
-    case '\f':
-    case '\v':
-      // Ignore whitespace.
-      break;
-
-    default:
-      // If there is no tag open, do it now.
-      if (!HadOpenTag) {
-        RB.InsertTextAfter(i, StartTag);
-        HadOpenTag = true;
-      }
-
-      // Remember this character.
-      LastNonWhiteSpace = i;
-      break;
-    }
-  }
-}
-
-void html::EscapeText(Rewriter &R, FileID FID,
-                      bool EscapeSpaces, bool ReplaceTabs) {
-
-  const llvm::MemoryBuffer *Buf = R.getSourceMgr().getBuffer(FID);
-  const char* C = Buf->getBufferStart();
-  const char* FileEnd = Buf->getBufferEnd();
-
-  assert (C <= FileEnd);
-
-  RewriteBuffer &RB = R.getEditBuffer(FID);
-
-  unsigned ColNo = 0;
-  for (unsigned FilePos = 0; C != FileEnd ; ++C, ++FilePos) {
-    switch (*C) {
-    default: ++ColNo; break;
-    case '\n':
-    case '\r':
-      ColNo = 0;
-      break;
-
-    case ' ':
-      if (EscapeSpaces)
-        RB.ReplaceText(FilePos, 1, "&nbsp;");
-      ++ColNo;
-      break;
-    case '\f':
-      RB.ReplaceText(FilePos, 1, "<hr>");
-      ColNo = 0;
-      break;
-
-    case '\t': {
-      if (!ReplaceTabs)
-        break;
-      unsigned NumSpaces = 8-(ColNo&7);
-      if (EscapeSpaces)
-        RB.ReplaceText(FilePos, 1,
-                       StringRef("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"
-                                       "&nbsp;&nbsp;&nbsp;", 6*NumSpaces));
-      else
-        RB.ReplaceText(FilePos, 1, StringRef("        ", NumSpaces));
-      ColNo += NumSpaces;
-      break;
-    }
-    case '<':
-      RB.ReplaceText(FilePos, 1, "&lt;");
-      ++ColNo;
-      break;
-
-    case '>':
-      RB.ReplaceText(FilePos, 1, "&gt;");
-      ++ColNo;
-      break;
-
-    case '&':
-      RB.ReplaceText(FilePos, 1, "&amp;");
-      ++ColNo;
-      break;
-    }
-  }
-}
-
-std::string html::EscapeText(StringRef s, bool EscapeSpaces, bool ReplaceTabs) {
-
-  unsigned len = s.size();
-  std::string Str;
-  llvm::raw_string_ostream os(Str);
-
-  for (unsigned i = 0 ; i < len; ++i) {
-
-    char c = s[i];
-    switch (c) {
-    default:
-      os << c; break;
-
-    case ' ':
-      if (EscapeSpaces) os << "&nbsp;";
-      else os << ' ';
-      break;
-
-    case '\t':
-      if (ReplaceTabs) {
-        if (EscapeSpaces)
-          for (unsigned i = 0; i < 4; ++i)
-            os << "&nbsp;";
-        else
-          for (unsigned i = 0; i < 4; ++i)
-            os << " ";
-      }
-      else
-        os << c;
-
-      break;
-
-    case '<': os << "&lt;"; break;
-    case '>': os << "&gt;"; break;
-    case '&': os << "&amp;"; break;
-    }
-  }
-
-  return os.str();
-}
-
-static void AddLineNumber(RewriteBuffer &RB, unsigned LineNo,
-                          unsigned B, unsigned E) {
-  SmallString<256> Str;
-  llvm::raw_svector_ostream OS(Str);
-
-  OS << "<tr><td class=\"num\" id=\"LN"
-     << LineNo << "\">"
-     << LineNo << "</td><td class=\"line\">";
-
-  if (B == E) { // Handle empty lines.
-    OS << " </td></tr>";
-    RB.InsertTextBefore(B, OS.str());
-  } else {
-    RB.InsertTextBefore(B, OS.str());
-    RB.InsertTextBefore(E, "</td></tr>");
-  }
-}
-
-void html::AddLineNumbers(Rewriter& R, FileID FID) {
-
-  const llvm::MemoryBuffer *Buf = R.getSourceMgr().getBuffer(FID);
-  const char* FileBeg = Buf->getBufferStart();
-  const char* FileEnd = Buf->getBufferEnd();
-  const char* C = FileBeg;
-  RewriteBuffer &RB = R.getEditBuffer(FID);
-
-  assert (C <= FileEnd);
-
-  unsigned LineNo = 0;
-  unsigned FilePos = 0;
-
-  while (C != FileEnd) {
-
-    ++LineNo;
-    unsigned LineStartPos = FilePos;
-    unsigned LineEndPos = FileEnd - FileBeg;
-
-    assert (FilePos <= LineEndPos);
-    assert (C < FileEnd);
-
-    // Scan until the newline (or end-of-file).
-
-    while (C != FileEnd) {
-      char c = *C;
-      ++C;
-
-      if (c == '\n') {
-        LineEndPos = FilePos++;
-        break;
-      }
-
-      ++FilePos;
-    }
-
-    AddLineNumber(RB, LineNo, LineStartPos, LineEndPos);
-  }
-
-  // Add one big table tag that surrounds all of the code.
-  RB.InsertTextBefore(0, "<table class=\"code\">\n");
-  RB.InsertTextAfter(FileEnd - FileBeg, "</table>");
-}
-
-void html::AddHeaderFooterInternalBuiltinCSS(Rewriter& R, FileID FID,
-                                             const char *title) {
-
-  const llvm::MemoryBuffer *Buf = R.getSourceMgr().getBuffer(FID);
-  const char* FileStart = Buf->getBufferStart();
-  const char* FileEnd = Buf->getBufferEnd();
-
-  SourceLocation StartLoc = R.getSourceMgr().getLocForStartOfFile(FID);
-  SourceLocation EndLoc = StartLoc.getLocWithOffset(FileEnd-FileStart);
-
-  std::string s;
-  llvm::raw_string_ostream os(s);
-  os << "<!doctype html>\n" // Use HTML 5 doctype
-        "<html>\n<head>\n";
-
-  if (title)
-    os << "<title>" << html::EscapeText(title) << "</title>\n";
-
-  os << "<style type=\"text/css\">\n"
-      " body { color:#000000; background-color:#ffffff }\n"
-      " body { font-family:Helvetica, sans-serif; font-size:10pt }\n"
-      " h1 { font-size:14pt }\n"
-      " .code { border-collapse:collapse; width:100%; }\n"
-      " .code { font-family: \"Monospace\", monospace; font-size:10pt }\n"
-      " .code { line-height: 1.2em }\n"
-      " .comment { color: green; font-style: oblique }\n"
-      " .keyword { color: blue }\n"
-      " .string_literal { color: red }\n"
-      " .directive { color: darkmagenta }\n"
-      // Macro expansions.
-      " .expansion { display: none; }\n"
-      " .macro:hover .expansion { display: block; border: 2px solid #FF0000; "
-          "padding: 2px; background-color:#FFF0F0; font-weight: normal; "
-          "  -webkit-border-radius:5px;  -webkit-box-shadow:1px 1px 7px #000; "
-          "position: absolute; top: -1em; left:10em; z-index: 1 } \n"
-      " .macro { color: darkmagenta; background-color:LemonChiffon;"
-             // Macros are position: relative to provide base for expansions.
-             " position: relative }\n"
-      " .num { width:2.5em; padding-right:2ex; background-color:#eeeeee }\n"
-      " .num { text-align:right; font-size:8pt }\n"
-      " .num { color:#444444 }\n"
-      " .line { padding-left: 1ex; border-left: 3px solid #ccc }\n"
-      " .line { white-space: pre }\n"
-      " .msg { -webkit-box-shadow:1px 1px 7px #000 }\n"
-      " .msg { -webkit-border-radius:5px }\n"
-      " .msg { font-family:Helvetica, sans-serif; font-size:8pt }\n"
-      " .msg { float:left }\n"
-      " .msg { padding:0.25em 1ex 0.25em 1ex }\n"
-      " .msg { margin-top:10px; margin-bottom:10px }\n"
-      " .msg { font-weight:bold }\n"
-      " .msg { max-width:60em; word-wrap: break-word; white-space: pre-wrap }\n"
-      " .msgT { padding:0x; spacing:0x }\n"
-      " .msgEvent { background-color:#fff8b4; color:#000000 }\n"
-      " .msgControl { background-color:#bbbbbb; color:#000000 }\n"
-      " .mrange { background-color:#dfddf3 }\n"
-      " .mrange { border-bottom:1px solid #6F9DBE }\n"
-      " .PathIndex { font-weight: bold; padding:0px 5px; "
-        "margin-right:5px; }\n"
-      " .PathIndex { -webkit-border-radius:8px }\n"
-      " .PathIndexEvent { background-color:#bfba87 }\n"
-      " .PathIndexControl { background-color:#8c8c8c }\n"
-      " .PathNav a { text-decoration:none; font-size: larger }\n"
-      " .CodeInsertionHint { font-weight: bold; background-color: #10dd10 }\n"
-      " .CodeRemovalHint { background-color:#de1010 }\n"
-      " .CodeRemovalHint { border-bottom:1px solid #6F9DBE }\n"
-      " table.simpletable {\n"
-      "   padding: 5px;\n"
-      "   font-size:12pt;\n"
-      "   margin:20px;\n"
-      "   border-collapse: collapse; border-spacing: 0px;\n"
-      " }\n"
-      " td.rowname {\n"
-      "   text-align:right; font-weight:bold; color:#444444;\n"
-      "   padding-right:2ex; }\n"
-      "</style>\n</head>\n<body>";
-
-  // Generate header
-  R.InsertTextBefore(StartLoc, os.str());
-  // Generate footer
-
-  R.InsertTextAfter(EndLoc, "</body></html>\n");
-}
-
-/// SyntaxHighlight - Relex the specified FileID and annotate the HTML with
-/// information about keywords, macro expansions etc.  This uses the macro
-/// table state from the end of the file, so it won't be perfectly perfect,
-/// but it will be reasonably close.
-void html::SyntaxHighlight(Rewriter &R, FileID FID, const Preprocessor &PP) {
-  RewriteBuffer &RB = R.getEditBuffer(FID);
-
-  const SourceManager &SM = PP.getSourceManager();
-  const llvm::MemoryBuffer *FromFile = SM.getBuffer(FID);
-  Lexer L(FID, FromFile, SM, PP.getLangOpts());
-  const char *BufferStart = L.getBuffer().data();
-
-  // Inform the preprocessor that we want to retain comments as tokens, so we
-  // can highlight them.
-  L.SetCommentRetentionState(true);
-
-  // Lex all the tokens in raw mode, to avoid entering #includes or expanding
-  // macros.
-  Token Tok;
-  L.LexFromRawLexer(Tok);
-
-  while (Tok.isNot(tok::eof)) {
-    // Since we are lexing unexpanded tokens, all tokens are from the main
-    // FileID.
-    unsigned TokOffs = SM.getFileOffset(Tok.getLocation());
-    unsigned TokLen = Tok.getLength();
-    switch (Tok.getKind()) {
-    default: break;
-    case tok::identifier:
-      llvm_unreachable("tok::identifier in raw lexing mode!");
-    case tok::raw_identifier: {
-      // Fill in Result.IdentifierInfo and update the token kind,
-      // looking up the identifier in the identifier table.
-      PP.LookUpIdentifierInfo(Tok);
-
-      // If this is a pp-identifier, for a keyword, highlight it as such.
-      if (Tok.isNot(tok::identifier))
-        HighlightRange(RB, TokOffs, TokOffs+TokLen, BufferStart,
-                       "<span class='keyword'>", "</span>");
-      break;
-    }
-    case tok::comment:
-      HighlightRange(RB, TokOffs, TokOffs+TokLen, BufferStart,
-                     "<span class='comment'>", "</span>");
-      break;
-    case tok::utf8_string_literal:
-      // Chop off the u part of u8 prefix
-      ++TokOffs;
-      --TokLen;
-      // FALL THROUGH to chop the 8
-    case tok::wide_string_literal:
-    case tok::utf16_string_literal:
-    case tok::utf32_string_literal:
-      // Chop off the L, u, U or 8 prefix
-      ++TokOffs;
-      --TokLen;
-      // FALL THROUGH.
-    case tok::string_literal:
-      // FIXME: Exclude the optional ud-suffix from the highlighted range.
-      HighlightRange(RB, TokOffs, TokOffs+TokLen, BufferStart,
-                     "<span class='string_literal'>", "</span>");
-      break;
-    case tok::hash: {
-      // If this is a preprocessor directive, all tokens to end of line are too.
-      if (!Tok.isAtStartOfLine())
-        break;
-
-      // Eat all of the tokens until we get to the next one at the start of
-      // line.
-      unsigned TokEnd = TokOffs+TokLen;
-      L.LexFromRawLexer(Tok);
-      while (!Tok.isAtStartOfLine() && Tok.isNot(tok::eof)) {
-        TokEnd = SM.getFileOffset(Tok.getLocation())+Tok.getLength();
-        L.LexFromRawLexer(Tok);
-      }
-
-      // Find end of line.  This is a hack.
-      HighlightRange(RB, TokOffs, TokEnd, BufferStart,
-                     "<span class='directive'>", "</span>");
-
-      // Don't skip the next token.
-      continue;
-    }
-    }
-
-    L.LexFromRawLexer(Tok);
-  }
-}
-
-/// HighlightMacros - This uses the macro table state from the end of the
-/// file, to re-expand macros and insert (into the HTML) information about the
-/// macro expansions.  This won't be perfectly perfect, but it will be
-/// reasonably close.
-void html::HighlightMacros(Rewriter &R, FileID FID, const Preprocessor& PP) {
-  // Re-lex the raw token stream into a token buffer.
-  const SourceManager &SM = PP.getSourceManager();
-  std::vector<Token> TokenStream;
-
-  const llvm::MemoryBuffer *FromFile = SM.getBuffer(FID);
-  Lexer L(FID, FromFile, SM, PP.getLangOpts());
-
-  // Lex all the tokens in raw mode, to avoid entering #includes or expanding
-  // macros.
-  while (1) {
-    Token Tok;
-    L.LexFromRawLexer(Tok);
-
-    // If this is a # at the start of a line, discard it from the token stream.
-    // We don't want the re-preprocess step to see #defines, #includes or other
-    // preprocessor directives.
-    if (Tok.is(tok::hash) && Tok.isAtStartOfLine())
-      continue;
-
-    // If this is a ## token, change its kind to unknown so that repreprocessing
-    // it will not produce an error.
-    if (Tok.is(tok::hashhash))
-      Tok.setKind(tok::unknown);
-
-    // If this raw token is an identifier, the raw lexer won't have looked up
-    // the corresponding identifier info for it.  Do this now so that it will be
-    // macro expanded when we re-preprocess it.
-    if (Tok.is(tok::raw_identifier))
-      PP.LookUpIdentifierInfo(Tok);
-
-    TokenStream.push_back(Tok);
-
-    if (Tok.is(tok::eof)) break;
-  }
-
-  // Temporarily change the diagnostics object so that we ignore any generated
-  // diagnostics from this pass.
-  DiagnosticsEngine TmpDiags(PP.getDiagnostics().getDiagnosticIDs(),
-                             &PP.getDiagnostics().getDiagnosticOptions(),
-                      new IgnoringDiagConsumer);
-
-  // FIXME: This is a huge hack; we reuse the input preprocessor because we want
-  // its state, but we aren't actually changing it (we hope). This should really
-  // construct a copy of the preprocessor.
-  Preprocessor &TmpPP = const_cast<Preprocessor&>(PP);
-  DiagnosticsEngine *OldDiags = &TmpPP.getDiagnostics();
-  TmpPP.setDiagnostics(TmpDiags);
-
-  // Inform the preprocessor that we don't want comments.
-  TmpPP.SetCommentRetentionState(false, false);
-
-  // We don't want pragmas either. Although we filtered out #pragma, removing
-  // _Pragma and __pragma is much harder.
-  bool PragmasPreviouslyEnabled = TmpPP.getPragmasEnabled();
-  TmpPP.setPragmasEnabled(false);
-
-  // Enter the tokens we just lexed.  This will cause them to be macro expanded
-  // but won't enter sub-files (because we removed #'s).
-  TmpPP.EnterTokenStream(&TokenStream[0], TokenStream.size(), false, false);
-
-  TokenConcatenation ConcatInfo(TmpPP);
-
-  // Lex all the tokens.
-  Token Tok;
-  TmpPP.Lex(Tok);
-  while (Tok.isNot(tok::eof)) {
-    // Ignore non-macro tokens.
-    if (!Tok.getLocation().isMacroID()) {
-      TmpPP.Lex(Tok);
-      continue;
-    }
-
-    // Okay, we have the first token of a macro expansion: highlight the
-    // expansion by inserting a start tag before the macro expansion and
-    // end tag after it.
-    std::pair<SourceLocation, SourceLocation> LLoc =
-      SM.getExpansionRange(Tok.getLocation());
-
-    // Ignore tokens whose instantiation location was not the main file.
-    if (SM.getFileID(LLoc.first) != FID) {
-      TmpPP.Lex(Tok);
-      continue;
-    }
-
-    assert(SM.getFileID(LLoc.second) == FID &&
-           "Start and end of expansion must be in the same ultimate file!");
-
-    std::string Expansion = EscapeText(TmpPP.getSpelling(Tok));
-    unsigned LineLen = Expansion.size();
-
-    Token PrevPrevTok;
-    Token PrevTok = Tok;
-    // Okay, eat this token, getting the next one.
-    TmpPP.Lex(Tok);
-
-    // Skip all the rest of the tokens that are part of this macro
-    // instantiation.  It would be really nice to pop up a window with all the
-    // spelling of the tokens or something.
-    while (!Tok.is(tok::eof) &&
-           SM.getExpansionLoc(Tok.getLocation()) == LLoc.first) {
-      // Insert a newline if the macro expansion is getting large.
-      if (LineLen > 60) {
-        Expansion += "<br>";
-        LineLen = 0;
-      }
-
-      LineLen -= Expansion.size();
-
-      // If the tokens were already space separated, or if they must be to avoid
-      // them being implicitly pasted, add a space between them.
-      if (Tok.hasLeadingSpace() ||
-          ConcatInfo.AvoidConcat(PrevPrevTok, PrevTok, Tok))
-        Expansion += ' ';
-
-      // Escape any special characters in the token text.
-      Expansion += EscapeText(TmpPP.getSpelling(Tok));
-      LineLen += Expansion.size();
-
-      PrevPrevTok = PrevTok;
-      PrevTok = Tok;
-      TmpPP.Lex(Tok);
-    }
-
-
-    // Insert the expansion as the end tag, so that multi-line macros all get
-    // highlighted.
-    Expansion = "<span class='expansion'>" + Expansion + "</span></span>";
-
-    HighlightRange(R, LLoc.first, LLoc.second,
-                   "<span class='macro'>", Expansion.c_str());
-  }
-
-  // Restore the preprocessor's old state.
-  TmpPP.setDiagnostics(*OldDiags);
-  TmpPP.setPragmasEnabled(PragmasPreviouslyEnabled);
-}
diff --git a/lib/Rewrite/Core/Makefile b/lib/Rewrite/Core/Makefile
deleted file mode 100644
index 8c8d2e4..0000000
--- a/lib/Rewrite/Core/Makefile
+++ /dev/null
@@ -1,18 +0,0 @@
-##===- clang/lib/Rewrite/Makefile --------------------------*- Makefile -*-===##
-# 
-#                     The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-# 
-##===----------------------------------------------------------------------===##
-#
-# This implements code transformation / rewriting facilities.
-#
-##===----------------------------------------------------------------------===##
-
-CLANG_LEVEL := ../../..
-LIBRARYNAME := clangRewriteCore
-
-include $(CLANG_LEVEL)/Makefile
-
diff --git a/lib/Rewrite/Core/RewriteRope.cpp b/lib/Rewrite/Core/RewriteRope.cpp
deleted file mode 100644
index fe7aa2d..0000000
--- a/lib/Rewrite/Core/RewriteRope.cpp
+++ /dev/null
@@ -1,807 +0,0 @@
-//===--- RewriteRope.cpp - Rope specialized for rewriter --------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-//  This file implements the RewriteRope class, which is a powerful string.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Rewrite/Core/RewriteRope.h"
-#include "clang/Basic/LLVM.h"
-#include <algorithm>
-using namespace clang;
-
-/// RewriteRope is a "strong" string class, designed to make insertions and
-/// deletions in the middle of the string nearly constant time (really, they are
-/// O(log N), but with a very low constant factor).
-///
-/// The implementation of this datastructure is a conceptual linear sequence of
-/// RopePiece elements.  Each RopePiece represents a view on a separately
-/// allocated and reference counted string.  This means that splitting a very
-/// long string can be done in constant time by splitting a RopePiece that
-/// references the whole string into two rope pieces that reference each half.
-/// Once split, another string can be inserted in between the two halves by
-/// inserting a RopePiece in between the two others.  All of this is very
-/// inexpensive: it takes time proportional to the number of RopePieces, not the
-/// length of the strings they represent.
-///
-/// While a linear sequences of RopePieces is the conceptual model, the actual
-/// implementation captures them in an adapted B+ Tree.  Using a B+ tree (which
-/// is a tree that keeps the values in the leaves and has where each node
-/// contains a reasonable number of pointers to children/values) allows us to
-/// maintain efficient operation when the RewriteRope contains a *huge* number
-/// of RopePieces.  The basic idea of the B+ Tree is that it allows us to find
-/// the RopePiece corresponding to some offset very efficiently, and it
-/// automatically balances itself on insertions of RopePieces (which can happen
-/// for both insertions and erases of string ranges).
-///
-/// The one wrinkle on the theory is that we don't attempt to keep the tree
-/// properly balanced when erases happen.  Erases of string data can both insert
-/// new RopePieces (e.g. when the middle of some other rope piece is deleted,
-/// which results in two rope pieces, which is just like an insert) or it can
-/// reduce the number of RopePieces maintained by the B+Tree.  In the case when
-/// the number of RopePieces is reduced, we don't attempt to maintain the
-/// standard 'invariant' that each node in the tree contains at least
-/// 'WidthFactor' children/values.  For our use cases, this doesn't seem to
-/// matter.
-///
-/// The implementation below is primarily implemented in terms of three classes:
-///   RopePieceBTreeNode - Common base class for:
-///
-///     RopePieceBTreeLeaf - Directly manages up to '2*WidthFactor' RopePiece
-///          nodes.  This directly represents a chunk of the string with those
-///          RopePieces contatenated.
-///     RopePieceBTreeInterior - An interior node in the B+ Tree, which manages
-///          up to '2*WidthFactor' other nodes in the tree.
-
-
-//===----------------------------------------------------------------------===//
-// RopePieceBTreeNode Class
-//===----------------------------------------------------------------------===//
-
-namespace {
-  /// RopePieceBTreeNode - Common base class of RopePieceBTreeLeaf and
-  /// RopePieceBTreeInterior.  This provides some 'virtual' dispatching methods
-  /// and a flag that determines which subclass the instance is.  Also
-  /// important, this node knows the full extend of the node, including any
-  /// children that it has.  This allows efficient skipping over entire subtrees
-  /// when looking for an offset in the BTree.
-  class RopePieceBTreeNode {
-  protected:
-    /// WidthFactor - This controls the number of K/V slots held in the BTree:
-    /// how wide it is.  Each level of the BTree is guaranteed to have at least
-    /// 'WidthFactor' elements in it (either ropepieces or children), (except
-    /// the root, which may have less) and may have at most 2*WidthFactor
-    /// elements.
-    enum { WidthFactor = 8 };
-
-    /// Size - This is the number of bytes of file this node (including any
-    /// potential children) covers.
-    unsigned Size;
-
-    /// IsLeaf - True if this is an instance of RopePieceBTreeLeaf, false if it
-    /// is an instance of RopePieceBTreeInterior.
-    bool IsLeaf;
-
-    RopePieceBTreeNode(bool isLeaf) : Size(0), IsLeaf(isLeaf) {}
-    ~RopePieceBTreeNode() {}
-  public:
-
-    bool isLeaf() const { return IsLeaf; }
-    unsigned size() const { return Size; }
-
-    void Destroy();
-
-    /// split - Split the range containing the specified offset so that we are
-    /// guaranteed that there is a place to do an insertion at the specified
-    /// offset.  The offset is relative, so "0" is the start of the node.
-    ///
-    /// If there is no space in this subtree for the extra piece, the extra tree
-    /// node is returned and must be inserted into a parent.
-    RopePieceBTreeNode *split(unsigned Offset);
-
-    /// insert - Insert the specified ropepiece into this tree node at the
-    /// specified offset.  The offset is relative, so "0" is the start of the
-    /// node.
-    ///
-    /// If there is no space in this subtree for the extra piece, the extra tree
-    /// node is returned and must be inserted into a parent.
-    RopePieceBTreeNode *insert(unsigned Offset, const RopePiece &R);
-
-    /// erase - Remove NumBytes from this node at the specified offset.  We are
-    /// guaranteed that there is a split at Offset.
-    void erase(unsigned Offset, unsigned NumBytes);
-
-  };
-} // end anonymous namespace
-
-//===----------------------------------------------------------------------===//
-// RopePieceBTreeLeaf Class
-//===----------------------------------------------------------------------===//
-
-namespace {
-  /// RopePieceBTreeLeaf - Directly manages up to '2*WidthFactor' RopePiece
-  /// nodes.  This directly represents a chunk of the string with those
-  /// RopePieces contatenated.  Since this is a B+Tree, all values (in this case
-  /// instances of RopePiece) are stored in leaves like this.  To make iteration
-  /// over the leaves efficient, they maintain a singly linked list through the
-  /// NextLeaf field.  This allows the B+Tree forward iterator to be constant
-  /// time for all increments.
-  class RopePieceBTreeLeaf : public RopePieceBTreeNode {
-    /// NumPieces - This holds the number of rope pieces currently active in the
-    /// Pieces array.
-    unsigned char NumPieces;
-
-    /// Pieces - This tracks the file chunks currently in this leaf.
-    ///
-    RopePiece Pieces[2*WidthFactor];
-
-    /// NextLeaf - This is a pointer to the next leaf in the tree, allowing
-    /// efficient in-order forward iteration of the tree without traversal.
-    RopePieceBTreeLeaf **PrevLeaf, *NextLeaf;
-  public:
-    RopePieceBTreeLeaf() : RopePieceBTreeNode(true), NumPieces(0),
-                           PrevLeaf(0), NextLeaf(0) {}
-    ~RopePieceBTreeLeaf() {
-      if (PrevLeaf || NextLeaf)
-        removeFromLeafInOrder();
-      clear();
-    }
-
-    bool isFull() const { return NumPieces == 2*WidthFactor; }
-
-    /// clear - Remove all rope pieces from this leaf.
-    void clear() {
-      while (NumPieces)
-        Pieces[--NumPieces] = RopePiece();
-      Size = 0;
-    }
-
-    unsigned getNumPieces() const { return NumPieces; }
-
-    const RopePiece &getPiece(unsigned i) const {
-      assert(i < getNumPieces() && "Invalid piece ID");
-      return Pieces[i];
-    }
-
-    const RopePieceBTreeLeaf *getNextLeafInOrder() const { return NextLeaf; }
-    void insertAfterLeafInOrder(RopePieceBTreeLeaf *Node) {
-      assert(PrevLeaf == 0 && NextLeaf == 0 && "Already in ordering");
-
-      NextLeaf = Node->NextLeaf;
-      if (NextLeaf)
-        NextLeaf->PrevLeaf = &NextLeaf;
-      PrevLeaf = &Node->NextLeaf;
-      Node->NextLeaf = this;
-    }
-
-    void removeFromLeafInOrder() {
-      if (PrevLeaf) {
-        *PrevLeaf = NextLeaf;
-        if (NextLeaf)
-          NextLeaf->PrevLeaf = PrevLeaf;
-      } else if (NextLeaf) {
-        NextLeaf->PrevLeaf = 0;
-      }
-    }
-
-    /// FullRecomputeSizeLocally - This method recomputes the 'Size' field by
-    /// summing the size of all RopePieces.
-    void FullRecomputeSizeLocally() {
-      Size = 0;
-      for (unsigned i = 0, e = getNumPieces(); i != e; ++i)
-        Size += getPiece(i).size();
-    }
-
-    /// split - Split the range containing the specified offset so that we are
-    /// guaranteed that there is a place to do an insertion at the specified
-    /// offset.  The offset is relative, so "0" is the start of the node.
-    ///
-    /// If there is no space in this subtree for the extra piece, the extra tree
-    /// node is returned and must be inserted into a parent.
-    RopePieceBTreeNode *split(unsigned Offset);
-
-    /// insert - Insert the specified ropepiece into this tree node at the
-    /// specified offset.  The offset is relative, so "0" is the start of the
-    /// node.
-    ///
-    /// If there is no space in this subtree for the extra piece, the extra tree
-    /// node is returned and must be inserted into a parent.
-    RopePieceBTreeNode *insert(unsigned Offset, const RopePiece &R);
-
-
-    /// erase - Remove NumBytes from this node at the specified offset.  We are
-    /// guaranteed that there is a split at Offset.
-    void erase(unsigned Offset, unsigned NumBytes);
-
-    static inline bool classof(const RopePieceBTreeNode *N) {
-      return N->isLeaf();
-    }
-  };
-} // end anonymous namespace
-
-/// split - Split the range containing the specified offset so that we are
-/// guaranteed that there is a place to do an insertion at the specified
-/// offset.  The offset is relative, so "0" is the start of the node.
-///
-/// If there is no space in this subtree for the extra piece, the extra tree
-/// node is returned and must be inserted into a parent.
-RopePieceBTreeNode *RopePieceBTreeLeaf::split(unsigned Offset) {
-  // Find the insertion point.  We are guaranteed that there is a split at the
-  // specified offset so find it.
-  if (Offset == 0 || Offset == size()) {
-    // Fastpath for a common case.  There is already a splitpoint at the end.
-    return 0;
-  }
-
-  // Find the piece that this offset lands in.
-  unsigned PieceOffs = 0;
-  unsigned i = 0;
-  while (Offset >= PieceOffs+Pieces[i].size()) {
-    PieceOffs += Pieces[i].size();
-    ++i;
-  }
-
-  // If there is already a split point at the specified offset, just return
-  // success.
-  if (PieceOffs == Offset)
-    return 0;
-
-  // Otherwise, we need to split piece 'i' at Offset-PieceOffs.  Convert Offset
-  // to being Piece relative.
-  unsigned IntraPieceOffset = Offset-PieceOffs;
-
-  // We do this by shrinking the RopePiece and then doing an insert of the tail.
-  RopePiece Tail(Pieces[i].StrData, Pieces[i].StartOffs+IntraPieceOffset,
-                 Pieces[i].EndOffs);
-  Size -= Pieces[i].size();
-  Pieces[i].EndOffs = Pieces[i].StartOffs+IntraPieceOffset;
-  Size += Pieces[i].size();
-
-  return insert(Offset, Tail);
-}
-
-
-/// insert - Insert the specified RopePiece into this tree node at the
-/// specified offset.  The offset is relative, so "0" is the start of the node.
-///
-/// If there is no space in this subtree for the extra piece, the extra tree
-/// node is returned and must be inserted into a parent.
-RopePieceBTreeNode *RopePieceBTreeLeaf::insert(unsigned Offset,
-                                               const RopePiece &R) {
-  // If this node is not full, insert the piece.
-  if (!isFull()) {
-    // Find the insertion point.  We are guaranteed that there is a split at the
-    // specified offset so find it.
-    unsigned i = 0, e = getNumPieces();
-    if (Offset == size()) {
-      // Fastpath for a common case.
-      i = e;
-    } else {
-      unsigned SlotOffs = 0;
-      for (; Offset > SlotOffs; ++i)
-        SlotOffs += getPiece(i).size();
-      assert(SlotOffs == Offset && "Split didn't occur before insertion!");
-    }
-
-    // For an insertion into a non-full leaf node, just insert the value in
-    // its sorted position.  This requires moving later values over.
-    for (; i != e; --e)
-      Pieces[e] = Pieces[e-1];
-    Pieces[i] = R;
-    ++NumPieces;
-    Size += R.size();
-    return 0;
-  }
-
-  // Otherwise, if this is leaf is full, split it in two halves.  Since this
-  // node is full, it contains 2*WidthFactor values.  We move the first
-  // 'WidthFactor' values to the LHS child (which we leave in this node) and
-  // move the last 'WidthFactor' values into the RHS child.
-
-  // Create the new node.
-  RopePieceBTreeLeaf *NewNode = new RopePieceBTreeLeaf();
-
-  // Move over the last 'WidthFactor' values from here to NewNode.
-  std::copy(&Pieces[WidthFactor], &Pieces[2*WidthFactor],
-            &NewNode->Pieces[0]);
-  // Replace old pieces with null RopePieces to drop refcounts.
-  std::fill(&Pieces[WidthFactor], &Pieces[2*WidthFactor], RopePiece());
-
-  // Decrease the number of values in the two nodes.
-  NewNode->NumPieces = NumPieces = WidthFactor;
-
-  // Recompute the two nodes' size.
-  NewNode->FullRecomputeSizeLocally();
-  FullRecomputeSizeLocally();
-
-  // Update the list of leaves.
-  NewNode->insertAfterLeafInOrder(this);
-
-  // These insertions can't fail.
-  if (this->size() >= Offset)
-    this->insert(Offset, R);
-  else
-    NewNode->insert(Offset - this->size(), R);
-  return NewNode;
-}
-
-/// erase - Remove NumBytes from this node at the specified offset.  We are
-/// guaranteed that there is a split at Offset.
-void RopePieceBTreeLeaf::erase(unsigned Offset, unsigned NumBytes) {
-  // Since we are guaranteed that there is a split at Offset, we start by
-  // finding the Piece that starts there.
-  unsigned PieceOffs = 0;
-  unsigned i = 0;
-  for (; Offset > PieceOffs; ++i)
-    PieceOffs += getPiece(i).size();
-  assert(PieceOffs == Offset && "Split didn't occur before erase!");
-
-  unsigned StartPiece = i;
-
-  // Figure out how many pieces completely cover 'NumBytes'.  We want to remove
-  // all of them.
-  for (; Offset+NumBytes > PieceOffs+getPiece(i).size(); ++i)
-    PieceOffs += getPiece(i).size();
-
-  // If we exactly include the last one, include it in the region to delete.
-  if (Offset+NumBytes == PieceOffs+getPiece(i).size())
-    PieceOffs += getPiece(i).size(), ++i;
-
-  // If we completely cover some RopePieces, erase them now.
-  if (i != StartPiece) {
-    unsigned NumDeleted = i-StartPiece;
-    for (; i != getNumPieces(); ++i)
-      Pieces[i-NumDeleted] = Pieces[i];
-
-    // Drop references to dead rope pieces.
-    std::fill(&Pieces[getNumPieces()-NumDeleted], &Pieces[getNumPieces()],
-              RopePiece());
-    NumPieces -= NumDeleted;
-
-    unsigned CoverBytes = PieceOffs-Offset;
-    NumBytes -= CoverBytes;
-    Size -= CoverBytes;
-  }
-
-  // If we completely removed some stuff, we could be done.
-  if (NumBytes == 0) return;
-
-  // Okay, now might be erasing part of some Piece.  If this is the case, then
-  // move the start point of the piece.
-  assert(getPiece(StartPiece).size() > NumBytes);
-  Pieces[StartPiece].StartOffs += NumBytes;
-
-  // The size of this node just shrunk by NumBytes.
-  Size -= NumBytes;
-}
-
-//===----------------------------------------------------------------------===//
-// RopePieceBTreeInterior Class
-//===----------------------------------------------------------------------===//
-
-namespace {
-  /// RopePieceBTreeInterior - This represents an interior node in the B+Tree,
-  /// which holds up to 2*WidthFactor pointers to child nodes.
-  class RopePieceBTreeInterior : public RopePieceBTreeNode {
-    /// NumChildren - This holds the number of children currently active in the
-    /// Children array.
-    unsigned char NumChildren;
-    RopePieceBTreeNode *Children[2*WidthFactor];
-  public:
-    RopePieceBTreeInterior() : RopePieceBTreeNode(false), NumChildren(0) {}
-
-    RopePieceBTreeInterior(RopePieceBTreeNode *LHS, RopePieceBTreeNode *RHS)
-    : RopePieceBTreeNode(false) {
-      Children[0] = LHS;
-      Children[1] = RHS;
-      NumChildren = 2;
-      Size = LHS->size() + RHS->size();
-    }
-
-    ~RopePieceBTreeInterior() {
-      for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
-        Children[i]->Destroy();
-    }
-
-    bool isFull() const { return NumChildren == 2*WidthFactor; }
-
-    unsigned getNumChildren() const { return NumChildren; }
-    const RopePieceBTreeNode *getChild(unsigned i) const {
-      assert(i < NumChildren && "invalid child #");
-      return Children[i];
-    }
-    RopePieceBTreeNode *getChild(unsigned i) {
-      assert(i < NumChildren && "invalid child #");
-      return Children[i];
-    }
-
-    /// FullRecomputeSizeLocally - Recompute the Size field of this node by
-    /// summing up the sizes of the child nodes.
-    void FullRecomputeSizeLocally() {
-      Size = 0;
-      for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
-        Size += getChild(i)->size();
-    }
-
-
-    /// split - Split the range containing the specified offset so that we are
-    /// guaranteed that there is a place to do an insertion at the specified
-    /// offset.  The offset is relative, so "0" is the start of the node.
-    ///
-    /// If there is no space in this subtree for the extra piece, the extra tree
-    /// node is returned and must be inserted into a parent.
-    RopePieceBTreeNode *split(unsigned Offset);
-
-
-    /// insert - Insert the specified ropepiece into this tree node at the
-    /// specified offset.  The offset is relative, so "0" is the start of the
-    /// node.
-    ///
-    /// If there is no space in this subtree for the extra piece, the extra tree
-    /// node is returned and must be inserted into a parent.
-    RopePieceBTreeNode *insert(unsigned Offset, const RopePiece &R);
-
-    /// HandleChildPiece - A child propagated an insertion result up to us.
-    /// Insert the new child, and/or propagate the result further up the tree.
-    RopePieceBTreeNode *HandleChildPiece(unsigned i, RopePieceBTreeNode *RHS);
-
-    /// erase - Remove NumBytes from this node at the specified offset.  We are
-    /// guaranteed that there is a split at Offset.
-    void erase(unsigned Offset, unsigned NumBytes);
-
-    static inline bool classof(const RopePieceBTreeNode *N) {
-      return !N->isLeaf();
-    }
-  };
-} // end anonymous namespace
-
-/// split - Split the range containing the specified offset so that we are
-/// guaranteed that there is a place to do an insertion at the specified
-/// offset.  The offset is relative, so "0" is the start of the node.
-///
-/// If there is no space in this subtree for the extra piece, the extra tree
-/// node is returned and must be inserted into a parent.
-RopePieceBTreeNode *RopePieceBTreeInterior::split(unsigned Offset) {
-  // Figure out which child to split.
-  if (Offset == 0 || Offset == size())
-    return 0;  // If we have an exact offset, we're already split.
-
-  unsigned ChildOffset = 0;
-  unsigned i = 0;
-  for (; Offset >= ChildOffset+getChild(i)->size(); ++i)
-    ChildOffset += getChild(i)->size();
-
-  // If already split there, we're done.
-  if (ChildOffset == Offset)
-    return 0;
-
-  // Otherwise, recursively split the child.
-  if (RopePieceBTreeNode *RHS = getChild(i)->split(Offset-ChildOffset))
-    return HandleChildPiece(i, RHS);
-  return 0;  // Done!
-}
-
-/// insert - Insert the specified ropepiece into this tree node at the
-/// specified offset.  The offset is relative, so "0" is the start of the
-/// node.
-///
-/// If there is no space in this subtree for the extra piece, the extra tree
-/// node is returned and must be inserted into a parent.
-RopePieceBTreeNode *RopePieceBTreeInterior::insert(unsigned Offset,
-                                                   const RopePiece &R) {
-  // Find the insertion point.  We are guaranteed that there is a split at the
-  // specified offset so find it.
-  unsigned i = 0, e = getNumChildren();
-
-  unsigned ChildOffs = 0;
-  if (Offset == size()) {
-    // Fastpath for a common case.  Insert at end of last child.
-    i = e-1;
-    ChildOffs = size()-getChild(i)->size();
-  } else {
-    for (; Offset > ChildOffs+getChild(i)->size(); ++i)
-      ChildOffs += getChild(i)->size();
-  }
-
-  Size += R.size();
-
-  // Insert at the end of this child.
-  if (RopePieceBTreeNode *RHS = getChild(i)->insert(Offset-ChildOffs, R))
-    return HandleChildPiece(i, RHS);
-
-  return 0;
-}
-
-/// HandleChildPiece - A child propagated an insertion result up to us.
-/// Insert the new child, and/or propagate the result further up the tree.
-RopePieceBTreeNode *
-RopePieceBTreeInterior::HandleChildPiece(unsigned i, RopePieceBTreeNode *RHS) {
-  // Otherwise the child propagated a subtree up to us as a new child.  See if
-  // we have space for it here.
-  if (!isFull()) {
-    // Insert RHS after child 'i'.
-    if (i + 1 != getNumChildren())
-      memmove(&Children[i+2], &Children[i+1],
-              (getNumChildren()-i-1)*sizeof(Children[0]));
-    Children[i+1] = RHS;
-    ++NumChildren;
-    return 0;
-  }
-
-  // Okay, this node is full.  Split it in half, moving WidthFactor children to
-  // a newly allocated interior node.
-
-  // Create the new node.
-  RopePieceBTreeInterior *NewNode = new RopePieceBTreeInterior();
-
-  // Move over the last 'WidthFactor' values from here to NewNode.
-  memcpy(&NewNode->Children[0], &Children[WidthFactor],
-         WidthFactor*sizeof(Children[0]));
-
-  // Decrease the number of values in the two nodes.
-  NewNode->NumChildren = NumChildren = WidthFactor;
-
-  // Finally, insert the two new children in the side the can (now) hold them.
-  // These insertions can't fail.
-  if (i < WidthFactor)
-    this->HandleChildPiece(i, RHS);
-  else
-    NewNode->HandleChildPiece(i-WidthFactor, RHS);
-
-  // Recompute the two nodes' size.
-  NewNode->FullRecomputeSizeLocally();
-  FullRecomputeSizeLocally();
-  return NewNode;
-}
-
-/// erase - Remove NumBytes from this node at the specified offset.  We are
-/// guaranteed that there is a split at Offset.
-void RopePieceBTreeInterior::erase(unsigned Offset, unsigned NumBytes) {
-  // This will shrink this node by NumBytes.
-  Size -= NumBytes;
-
-  // Find the first child that overlaps with Offset.
-  unsigned i = 0;
-  for (; Offset >= getChild(i)->size(); ++i)
-    Offset -= getChild(i)->size();
-
-  // Propagate the delete request into overlapping children, or completely
-  // delete the children as appropriate.
-  while (NumBytes) {
-    RopePieceBTreeNode *CurChild = getChild(i);
-
-    // If we are deleting something contained entirely in the child, pass on the
-    // request.
-    if (Offset+NumBytes < CurChild->size()) {
-      CurChild->erase(Offset, NumBytes);
-      return;
-    }
-
-    // If this deletion request starts somewhere in the middle of the child, it
-    // must be deleting to the end of the child.
-    if (Offset) {
-      unsigned BytesFromChild = CurChild->size()-Offset;
-      CurChild->erase(Offset, BytesFromChild);
-      NumBytes -= BytesFromChild;
-      // Start at the beginning of the next child.
-      Offset = 0;
-      ++i;
-      continue;
-    }
-
-    // If the deletion request completely covers the child, delete it and move
-    // the rest down.
-    NumBytes -= CurChild->size();
-    CurChild->Destroy();
-    --NumChildren;
-    if (i != getNumChildren())
-      memmove(&Children[i], &Children[i+1],
-              (getNumChildren()-i)*sizeof(Children[0]));
-  }
-}
-
-//===----------------------------------------------------------------------===//
-// RopePieceBTreeNode Implementation
-//===----------------------------------------------------------------------===//
-
-void RopePieceBTreeNode::Destroy() {
-  if (RopePieceBTreeLeaf *Leaf = dyn_cast<RopePieceBTreeLeaf>(this))
-    delete Leaf;
-  else
-    delete cast<RopePieceBTreeInterior>(this);
-}
-
-/// split - Split the range containing the specified offset so that we are
-/// guaranteed that there is a place to do an insertion at the specified
-/// offset.  The offset is relative, so "0" is the start of the node.
-///
-/// If there is no space in this subtree for the extra piece, the extra tree
-/// node is returned and must be inserted into a parent.
-RopePieceBTreeNode *RopePieceBTreeNode::split(unsigned Offset) {
-  assert(Offset <= size() && "Invalid offset to split!");
-  if (RopePieceBTreeLeaf *Leaf = dyn_cast<RopePieceBTreeLeaf>(this))
-    return Leaf->split(Offset);
-  return cast<RopePieceBTreeInterior>(this)->split(Offset);
-}
-
-/// insert - Insert the specified ropepiece into this tree node at the
-/// specified offset.  The offset is relative, so "0" is the start of the
-/// node.
-///
-/// If there is no space in this subtree for the extra piece, the extra tree
-/// node is returned and must be inserted into a parent.
-RopePieceBTreeNode *RopePieceBTreeNode::insert(unsigned Offset,
-                                               const RopePiece &R) {
-  assert(Offset <= size() && "Invalid offset to insert!");
-  if (RopePieceBTreeLeaf *Leaf = dyn_cast<RopePieceBTreeLeaf>(this))
-    return Leaf->insert(Offset, R);
-  return cast<RopePieceBTreeInterior>(this)->insert(Offset, R);
-}
-
-/// erase - Remove NumBytes from this node at the specified offset.  We are
-/// guaranteed that there is a split at Offset.
-void RopePieceBTreeNode::erase(unsigned Offset, unsigned NumBytes) {
-  assert(Offset+NumBytes <= size() && "Invalid offset to erase!");
-  if (RopePieceBTreeLeaf *Leaf = dyn_cast<RopePieceBTreeLeaf>(this))
-    return Leaf->erase(Offset, NumBytes);
-  return cast<RopePieceBTreeInterior>(this)->erase(Offset, NumBytes);
-}
-
-
-//===----------------------------------------------------------------------===//
-// RopePieceBTreeIterator Implementation
-//===----------------------------------------------------------------------===//
-
-static const RopePieceBTreeLeaf *getCN(const void *P) {
-  return static_cast<const RopePieceBTreeLeaf*>(P);
-}
-
-// begin iterator.
-RopePieceBTreeIterator::RopePieceBTreeIterator(const void *n) {
-  const RopePieceBTreeNode *N = static_cast<const RopePieceBTreeNode*>(n);
-
-  // Walk down the left side of the tree until we get to a leaf.
-  while (const RopePieceBTreeInterior *IN = dyn_cast<RopePieceBTreeInterior>(N))
-    N = IN->getChild(0);
-
-  // We must have at least one leaf.
-  CurNode = cast<RopePieceBTreeLeaf>(N);
-
-  // If we found a leaf that happens to be empty, skip over it until we get
-  // to something full.
-  while (CurNode && getCN(CurNode)->getNumPieces() == 0)
-    CurNode = getCN(CurNode)->getNextLeafInOrder();
-
-  if (CurNode != 0)
-    CurPiece = &getCN(CurNode)->getPiece(0);
-  else  // Empty tree, this is an end() iterator.
-    CurPiece = 0;
-  CurChar = 0;
-}
-
-void RopePieceBTreeIterator::MoveToNextPiece() {
-  if (CurPiece != &getCN(CurNode)->getPiece(getCN(CurNode)->getNumPieces()-1)) {
-    CurChar = 0;
-    ++CurPiece;
-    return;
-  }
-
-  // Find the next non-empty leaf node.
-  do
-    CurNode = getCN(CurNode)->getNextLeafInOrder();
-  while (CurNode && getCN(CurNode)->getNumPieces() == 0);
-
-  if (CurNode != 0)
-    CurPiece = &getCN(CurNode)->getPiece(0);
-  else // Hit end().
-    CurPiece = 0;
-  CurChar = 0;
-}
-
-//===----------------------------------------------------------------------===//
-// RopePieceBTree Implementation
-//===----------------------------------------------------------------------===//
-
-static RopePieceBTreeNode *getRoot(void *P) {
-  return static_cast<RopePieceBTreeNode*>(P);
-}
-
-RopePieceBTree::RopePieceBTree() {
-  Root = new RopePieceBTreeLeaf();
-}
-RopePieceBTree::RopePieceBTree(const RopePieceBTree &RHS) {
-  assert(RHS.empty() && "Can't copy non-empty tree yet");
-  Root = new RopePieceBTreeLeaf();
-}
-RopePieceBTree::~RopePieceBTree() {
-  getRoot(Root)->Destroy();
-}
-
-unsigned RopePieceBTree::size() const {
-  return getRoot(Root)->size();
-}
-
-void RopePieceBTree::clear() {
-  if (RopePieceBTreeLeaf *Leaf = dyn_cast<RopePieceBTreeLeaf>(getRoot(Root)))
-    Leaf->clear();
-  else {
-    getRoot(Root)->Destroy();
-    Root = new RopePieceBTreeLeaf();
-  }
-}
-
-void RopePieceBTree::insert(unsigned Offset, const RopePiece &R) {
-  // #1. Split at Offset.
-  if (RopePieceBTreeNode *RHS = getRoot(Root)->split(Offset))
-    Root = new RopePieceBTreeInterior(getRoot(Root), RHS);
-
-  // #2. Do the insertion.
-  if (RopePieceBTreeNode *RHS = getRoot(Root)->insert(Offset, R))
-    Root = new RopePieceBTreeInterior(getRoot(Root), RHS);
-}
-
-void RopePieceBTree::erase(unsigned Offset, unsigned NumBytes) {
-  // #1. Split at Offset.
-  if (RopePieceBTreeNode *RHS = getRoot(Root)->split(Offset))
-    Root = new RopePieceBTreeInterior(getRoot(Root), RHS);
-
-  // #2. Do the erasing.
-  getRoot(Root)->erase(Offset, NumBytes);
-}
-
-//===----------------------------------------------------------------------===//
-// RewriteRope Implementation
-//===----------------------------------------------------------------------===//
-
-/// MakeRopeString - This copies the specified byte range into some instance of
-/// RopeRefCountString, and return a RopePiece that represents it.  This uses
-/// the AllocBuffer object to aggregate requests for small strings into one
-/// allocation instead of doing tons of tiny allocations.
-RopePiece RewriteRope::MakeRopeString(const char *Start, const char *End) {
-  unsigned Len = End-Start;
-  assert(Len && "Zero length RopePiece is invalid!");
-
-  // If we have space for this string in the current alloc buffer, use it.
-  if (AllocOffs+Len <= AllocChunkSize) {
-    memcpy(AllocBuffer->Data+AllocOffs, Start, Len);
-    AllocOffs += Len;
-    return RopePiece(AllocBuffer, AllocOffs-Len, AllocOffs);
-  }
-
-  // If we don't have enough room because this specific allocation is huge,
-  // just allocate a new rope piece for it alone.
-  if (Len > AllocChunkSize) {
-    unsigned Size = End-Start+sizeof(RopeRefCountString)-1;
-    RopeRefCountString *Res =
-      reinterpret_cast<RopeRefCountString *>(new char[Size]);
-    Res->RefCount = 0;
-    memcpy(Res->Data, Start, End-Start);
-    return RopePiece(Res, 0, End-Start);
-  }
-
-  // Otherwise, this was a small request but we just don't have space for it
-  // Make a new chunk and share it with later allocations.
-
-  // If we had an old allocation, drop our reference to it.
-  if (AllocBuffer && --AllocBuffer->RefCount == 0)
-    delete [] (char*)AllocBuffer;
-
-  unsigned AllocSize = offsetof(RopeRefCountString, Data) + AllocChunkSize;
-  AllocBuffer = reinterpret_cast<RopeRefCountString *>(new char[AllocSize]);
-  AllocBuffer->RefCount = 0;
-  memcpy(AllocBuffer->Data, Start, Len);
-  AllocOffs = Len;
-
-  // Start out the new allocation with a refcount of 1, since we have an
-  // internal reference to it.
-  AllocBuffer->addRef();
-  return RopePiece(AllocBuffer, 0, Len);
-}
-
-
diff --git a/lib/Rewrite/Core/Rewriter.cpp b/lib/Rewrite/Core/Rewriter.cpp
deleted file mode 100644
index afb1080..0000000
--- a/lib/Rewrite/Core/Rewriter.cpp
+++ /dev/null
@@ -1,489 +0,0 @@
-//===--- Rewriter.cpp - Code rewriting interface --------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-//  This file defines the Rewriter class, which is used for code
-//  transformations.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Rewrite/Core/Rewriter.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/PrettyPrinter.h"
-#include "clang/AST/Stmt.h"
-#include "clang/Basic/DiagnosticIDs.h"
-#include "clang/Basic/FileManager.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Lex/Lexer.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/raw_ostream.h"
-using namespace clang;
-
-raw_ostream &RewriteBuffer::write(raw_ostream &os) const {
-  // FIXME: eliminate the copy by writing out each chunk at a time
-  os << std::string(begin(), end());
-  return os;
-}
-
-/// \brief Return true if this character is non-new-line whitespace:
-/// ' ', '\\t', '\\f', '\\v', '\\r'.
-static inline bool isWhitespace(unsigned char c) {
-  switch (c) {
-  case ' ':
-  case '\t':
-  case '\f':
-  case '\v':
-  case '\r':
-    return true;
-  default:
-    return false;
-  }
-}
-
-void RewriteBuffer::RemoveText(unsigned OrigOffset, unsigned Size,
-                               bool removeLineIfEmpty) {
-  // Nothing to remove, exit early.
-  if (Size == 0) return;
-
-  unsigned RealOffset = getMappedOffset(OrigOffset, true);
-  assert(RealOffset+Size < Buffer.size() && "Invalid location");
-
-  // Remove the dead characters.
-  Buffer.erase(RealOffset, Size);
-
-  // Add a delta so that future changes are offset correctly.
-  AddReplaceDelta(OrigOffset, -Size);
-
-  if (removeLineIfEmpty) {
-    // Find the line that the remove occurred and if it is completely empty
-    // remove the line as well.
-
-    iterator curLineStart = begin();
-    unsigned curLineStartOffs = 0;
-    iterator posI = begin();
-    for (unsigned i = 0; i != RealOffset; ++i) {
-      if (*posI == '\n') {
-        curLineStart = posI;
-        ++curLineStart;
-        curLineStartOffs = i + 1;
-      }
-      ++posI;
-    }
-  
-    unsigned lineSize = 0;
-    posI = curLineStart;
-    while (posI != end() && isWhitespace(*posI)) {
-      ++posI;
-      ++lineSize;
-    }
-    if (posI != end() && *posI == '\n') {
-      Buffer.erase(curLineStartOffs, lineSize + 1/* + '\n'*/);
-      AddReplaceDelta(curLineStartOffs, -(lineSize + 1/* + '\n'*/));
-    }
-  }
-}
-
-void RewriteBuffer::InsertText(unsigned OrigOffset, StringRef Str,
-                               bool InsertAfter) {
-
-  // Nothing to insert, exit early.
-  if (Str.empty()) return;
-
-  unsigned RealOffset = getMappedOffset(OrigOffset, InsertAfter);
-  Buffer.insert(RealOffset, Str.begin(), Str.end());
-
-  // Add a delta so that future changes are offset correctly.
-  AddInsertDelta(OrigOffset, Str.size());
-}
-
-/// ReplaceText - This method replaces a range of characters in the input
-/// buffer with a new string.  This is effectively a combined "remove+insert"
-/// operation.
-void RewriteBuffer::ReplaceText(unsigned OrigOffset, unsigned OrigLength,
-                                StringRef NewStr) {
-  unsigned RealOffset = getMappedOffset(OrigOffset, true);
-  Buffer.erase(RealOffset, OrigLength);
-  Buffer.insert(RealOffset, NewStr.begin(), NewStr.end());
-  if (OrigLength != NewStr.size())
-    AddReplaceDelta(OrigOffset, NewStr.size() - OrigLength);
-}
-
-
-//===----------------------------------------------------------------------===//
-// Rewriter class
-//===----------------------------------------------------------------------===//
-
-/// getRangeSize - Return the size in bytes of the specified range if they
-/// are in the same file.  If not, this returns -1.
-int Rewriter::getRangeSize(const CharSourceRange &Range,
-                           RewriteOptions opts) const {
-  if (!isRewritable(Range.getBegin()) ||
-      !isRewritable(Range.getEnd())) return -1;
-
-  FileID StartFileID, EndFileID;
-  unsigned StartOff, EndOff;
-
-  StartOff = getLocationOffsetAndFileID(Range.getBegin(), StartFileID);
-  EndOff   = getLocationOffsetAndFileID(Range.getEnd(), EndFileID);
-
-  if (StartFileID != EndFileID)
-    return -1;
-
-  // If edits have been made to this buffer, the delta between the range may
-  // have changed.
-  std::map<FileID, RewriteBuffer>::const_iterator I =
-    RewriteBuffers.find(StartFileID);
-  if (I != RewriteBuffers.end()) {
-    const RewriteBuffer &RB = I->second;
-    EndOff = RB.getMappedOffset(EndOff, opts.IncludeInsertsAtEndOfRange);
-    StartOff = RB.getMappedOffset(StartOff, !opts.IncludeInsertsAtBeginOfRange);
-  }
-
-
-  // Adjust the end offset to the end of the last token, instead of being the
-  // start of the last token if this is a token range.
-  if (Range.isTokenRange())
-    EndOff += Lexer::MeasureTokenLength(Range.getEnd(), *SourceMgr, *LangOpts);
-
-  return EndOff-StartOff;
-}
-
-int Rewriter::getRangeSize(SourceRange Range, RewriteOptions opts) const {
-  return getRangeSize(CharSourceRange::getTokenRange(Range), opts);
-}
-
-
-/// getRewrittenText - Return the rewritten form of the text in the specified
-/// range.  If the start or end of the range was unrewritable or if they are
-/// in different buffers, this returns an empty string.
-///
-/// Note that this method is not particularly efficient.
-///
-std::string Rewriter::getRewrittenText(SourceRange Range) const {
-  if (!isRewritable(Range.getBegin()) ||
-      !isRewritable(Range.getEnd()))
-    return "";
-
-  FileID StartFileID, EndFileID;
-  unsigned StartOff, EndOff;
-  StartOff = getLocationOffsetAndFileID(Range.getBegin(), StartFileID);
-  EndOff   = getLocationOffsetAndFileID(Range.getEnd(), EndFileID);
-
-  if (StartFileID != EndFileID)
-    return ""; // Start and end in different buffers.
-
-  // If edits have been made to this buffer, the delta between the range may
-  // have changed.
-  std::map<FileID, RewriteBuffer>::const_iterator I =
-    RewriteBuffers.find(StartFileID);
-  if (I == RewriteBuffers.end()) {
-    // If the buffer hasn't been rewritten, just return the text from the input.
-    const char *Ptr = SourceMgr->getCharacterData(Range.getBegin());
-
-    // Adjust the end offset to the end of the last token, instead of being the
-    // start of the last token.
-    EndOff += Lexer::MeasureTokenLength(Range.getEnd(), *SourceMgr, *LangOpts);
-    return std::string(Ptr, Ptr+EndOff-StartOff);
-  }
-
-  const RewriteBuffer &RB = I->second;
-  EndOff = RB.getMappedOffset(EndOff, true);
-  StartOff = RB.getMappedOffset(StartOff);
-
-  // Adjust the end offset to the end of the last token, instead of being the
-  // start of the last token.
-  EndOff += Lexer::MeasureTokenLength(Range.getEnd(), *SourceMgr, *LangOpts);
-
-  // Advance the iterators to the right spot, yay for linear time algorithms.
-  RewriteBuffer::iterator Start = RB.begin();
-  std::advance(Start, StartOff);
-  RewriteBuffer::iterator End = Start;
-  std::advance(End, EndOff-StartOff);
-
-  return std::string(Start, End);
-}
-
-unsigned Rewriter::getLocationOffsetAndFileID(SourceLocation Loc,
-                                              FileID &FID) const {
-  assert(Loc.isValid() && "Invalid location");
-  std::pair<FileID,unsigned> V = SourceMgr->getDecomposedLoc(Loc);
-  FID = V.first;
-  return V.second;
-}
-
-
-/// getEditBuffer - Get or create a RewriteBuffer for the specified FileID.
-///
-RewriteBuffer &Rewriter::getEditBuffer(FileID FID) {
-  std::map<FileID, RewriteBuffer>::iterator I =
-    RewriteBuffers.lower_bound(FID);
-  if (I != RewriteBuffers.end() && I->first == FID)
-    return I->second;
-  I = RewriteBuffers.insert(I, std::make_pair(FID, RewriteBuffer()));
-
-  StringRef MB = SourceMgr->getBufferData(FID);
-  I->second.Initialize(MB.begin(), MB.end());
-
-  return I->second;
-}
-
-/// InsertText - Insert the specified string at the specified location in the
-/// original buffer.
-bool Rewriter::InsertText(SourceLocation Loc, StringRef Str,
-                          bool InsertAfter, bool indentNewLines) {
-  if (!isRewritable(Loc)) return true;
-  FileID FID;
-  unsigned StartOffs = getLocationOffsetAndFileID(Loc, FID);
-
-  SmallString<128> indentedStr;
-  if (indentNewLines && Str.find('\n') != StringRef::npos) {
-    StringRef MB = SourceMgr->getBufferData(FID);
-
-    unsigned lineNo = SourceMgr->getLineNumber(FID, StartOffs) - 1;
-    const SrcMgr::ContentCache *
-        Content = SourceMgr->getSLocEntry(FID).getFile().getContentCache();
-    unsigned lineOffs = Content->SourceLineCache[lineNo];
-
-    // Find the whitespace at the start of the line.
-    StringRef indentSpace;
-    {
-      unsigned i = lineOffs;
-      while (isWhitespace(MB[i]))
-        ++i;
-      indentSpace = MB.substr(lineOffs, i-lineOffs);
-    }
-
-    SmallVector<StringRef, 4> lines;
-    Str.split(lines, "\n");
-
-    for (unsigned i = 0, e = lines.size(); i != e; ++i) {
-      indentedStr += lines[i];
-      if (i < e-1) {
-        indentedStr += '\n';
-        indentedStr += indentSpace;
-      }
-    }
-    Str = indentedStr.str();
-  }
-
-  getEditBuffer(FID).InsertText(StartOffs, Str, InsertAfter);
-  return false;
-}
-
-bool Rewriter::InsertTextAfterToken(SourceLocation Loc, StringRef Str) {
-  if (!isRewritable(Loc)) return true;
-  FileID FID;
-  unsigned StartOffs = getLocationOffsetAndFileID(Loc, FID);
-  RewriteOptions rangeOpts;
-  rangeOpts.IncludeInsertsAtBeginOfRange = false;
-  StartOffs += getRangeSize(SourceRange(Loc, Loc), rangeOpts);
-  getEditBuffer(FID).InsertText(StartOffs, Str, /*InsertAfter*/true);
-  return false;
-}
-
-/// RemoveText - Remove the specified text region.
-bool Rewriter::RemoveText(SourceLocation Start, unsigned Length,
-                          RewriteOptions opts) {
-  if (!isRewritable(Start)) return true;
-  FileID FID;
-  unsigned StartOffs = getLocationOffsetAndFileID(Start, FID);
-  getEditBuffer(FID).RemoveText(StartOffs, Length, opts.RemoveLineIfEmpty);
-  return false;
-}
-
-/// ReplaceText - This method replaces a range of characters in the input
-/// buffer with a new string.  This is effectively a combined "remove/insert"
-/// operation.
-bool Rewriter::ReplaceText(SourceLocation Start, unsigned OrigLength,
-                           StringRef NewStr) {
-  if (!isRewritable(Start)) return true;
-  FileID StartFileID;
-  unsigned StartOffs = getLocationOffsetAndFileID(Start, StartFileID);
-
-  getEditBuffer(StartFileID).ReplaceText(StartOffs, OrigLength, NewStr);
-  return false;
-}
-
-bool Rewriter::ReplaceText(SourceRange range, SourceRange replacementRange) {
-  if (!isRewritable(range.getBegin())) return true;
-  if (!isRewritable(range.getEnd())) return true;
-  if (replacementRange.isInvalid()) return true;
-  SourceLocation start = range.getBegin();
-  unsigned origLength = getRangeSize(range);
-  unsigned newLength = getRangeSize(replacementRange);
-  FileID FID;
-  unsigned newOffs = getLocationOffsetAndFileID(replacementRange.getBegin(),
-                                                FID);
-  StringRef MB = SourceMgr->getBufferData(FID);
-  return ReplaceText(start, origLength, MB.substr(newOffs, newLength));
-}
-
-/// ReplaceStmt - This replaces a Stmt/Expr with another, using the pretty
-/// printer to generate the replacement code.  This returns true if the input
-/// could not be rewritten, or false if successful.
-bool Rewriter::ReplaceStmt(Stmt *From, Stmt *To) {
-  // Measaure the old text.
-  int Size = getRangeSize(From->getSourceRange());
-  if (Size == -1)
-    return true;
-
-  // Get the new text.
-  std::string SStr;
-  llvm::raw_string_ostream S(SStr);
-  To->printPretty(S, 0, PrintingPolicy(*LangOpts));
-  const std::string &Str = S.str();
-
-  ReplaceText(From->getLocStart(), Size, Str);
-  return false;
-}
-
-std::string Rewriter::ConvertToString(Stmt *From) {
-  std::string SStr;
-  llvm::raw_string_ostream S(SStr);
-  From->printPretty(S, 0, PrintingPolicy(*LangOpts));
-  return S.str();
-}
-
-bool Rewriter::IncreaseIndentation(CharSourceRange range,
-                                   SourceLocation parentIndent) {
-  if (range.isInvalid()) return true;
-  if (!isRewritable(range.getBegin())) return true;
-  if (!isRewritable(range.getEnd())) return true;
-  if (!isRewritable(parentIndent)) return true;
-
-  FileID StartFileID, EndFileID, parentFileID;
-  unsigned StartOff, EndOff, parentOff;
-
-  StartOff = getLocationOffsetAndFileID(range.getBegin(), StartFileID);
-  EndOff   = getLocationOffsetAndFileID(range.getEnd(), EndFileID);
-  parentOff = getLocationOffsetAndFileID(parentIndent, parentFileID);
-
-  if (StartFileID != EndFileID || StartFileID != parentFileID)
-    return true;
-  if (StartOff > EndOff)
-    return true;
-
-  FileID FID = StartFileID;
-  StringRef MB = SourceMgr->getBufferData(FID);
-
-  unsigned parentLineNo = SourceMgr->getLineNumber(FID, parentOff) - 1;
-  unsigned startLineNo = SourceMgr->getLineNumber(FID, StartOff) - 1;
-  unsigned endLineNo = SourceMgr->getLineNumber(FID, EndOff) - 1;
-  
-  const SrcMgr::ContentCache *
-      Content = SourceMgr->getSLocEntry(FID).getFile().getContentCache();
-  
-  // Find where the lines start.
-  unsigned parentLineOffs = Content->SourceLineCache[parentLineNo];
-  unsigned startLineOffs = Content->SourceLineCache[startLineNo];
-
-  // Find the whitespace at the start of each line.
-  StringRef parentSpace, startSpace;
-  {
-    unsigned i = parentLineOffs;
-    while (isWhitespace(MB[i]))
-      ++i;
-    parentSpace = MB.substr(parentLineOffs, i-parentLineOffs);
-
-    i = startLineOffs;
-    while (isWhitespace(MB[i]))
-      ++i;
-    startSpace = MB.substr(startLineOffs, i-startLineOffs);
-  }
-  if (parentSpace.size() >= startSpace.size())
-    return true;
-  if (!startSpace.startswith(parentSpace))
-    return true;
-
-  StringRef indent = startSpace.substr(parentSpace.size());
-
-  // Indent the lines between start/end offsets.
-  RewriteBuffer &RB = getEditBuffer(FID);
-  for (unsigned lineNo = startLineNo; lineNo <= endLineNo; ++lineNo) {
-    unsigned offs = Content->SourceLineCache[lineNo];
-    unsigned i = offs;
-    while (isWhitespace(MB[i]))
-      ++i;
-    StringRef origIndent = MB.substr(offs, i-offs);
-    if (origIndent.startswith(startSpace))
-      RB.InsertText(offs, indent, /*InsertAfter=*/false);
-  }
-
-  return false;
-}
-
-namespace {
-// A wrapper for a file stream that atomically overwrites the target.
-//
-// Creates a file output stream for a temporary file in the constructor,
-// which is later accessible via getStream() if ok() return true.
-// Flushes the stream and moves the temporary file to the target location
-// in the destructor.
-class AtomicallyMovedFile {
-public:
-  AtomicallyMovedFile(DiagnosticsEngine &Diagnostics, StringRef Filename,
-                      bool &AllWritten)
-    : Diagnostics(Diagnostics), Filename(Filename), AllWritten(AllWritten) {
-    TempFilename = Filename;
-    TempFilename += "-%%%%%%%%";
-    int FD;
-    if (llvm::sys::fs::createUniqueFile(TempFilename.str(), FD, TempFilename)) {
-      AllWritten = false;
-      Diagnostics.Report(clang::diag::err_unable_to_make_temp)
-        << TempFilename;
-    } else {
-      FileStream.reset(new llvm::raw_fd_ostream(FD, /*shouldClose=*/true));
-    }
-  }
-
-  ~AtomicallyMovedFile() {
-    if (!ok()) return;
-
-    FileStream->flush();
-#ifdef _WIN32
-    // Win32 does not allow rename/removing opened files.
-    FileStream.reset();
-#endif
-    if (llvm::error_code ec =
-          llvm::sys::fs::rename(TempFilename.str(), Filename)) {
-      AllWritten = false;
-      Diagnostics.Report(clang::diag::err_unable_to_rename_temp)
-        << TempFilename << Filename << ec.message();
-      bool existed;
-      // If the remove fails, there's not a lot we can do - this is already an
-      // error.
-      llvm::sys::fs::remove(TempFilename.str(), existed);
-    }
-  }
-
-  bool ok() { return FileStream.isValid(); }
-  raw_ostream &getStream() { return *FileStream; }
-
-private:
-  DiagnosticsEngine &Diagnostics;
-  StringRef Filename;
-  SmallString<128> TempFilename;
-  OwningPtr<llvm::raw_fd_ostream> FileStream;
-  bool &AllWritten;
-};
-} // end anonymous namespace
-
-bool Rewriter::overwriteChangedFiles() {
-  bool AllWritten = true;
-  for (buffer_iterator I = buffer_begin(), E = buffer_end(); I != E; ++I) {
-    const FileEntry *Entry =
-        getSourceMgr().getFileEntryForID(I->first);
-    AtomicallyMovedFile File(getSourceMgr().getDiagnostics(), Entry->getName(),
-                             AllWritten);
-    if (File.ok()) {
-      I->second.write(File.getStream());
-    }
-  }
-  return !AllWritten;
-}
diff --git a/lib/Rewrite/DeltaTree.cpp b/lib/Rewrite/DeltaTree.cpp
new file mode 100644
index 0000000..352fab0
--- /dev/null
+++ b/lib/Rewrite/DeltaTree.cpp
@@ -0,0 +1,464 @@
+//===--- DeltaTree.cpp - B-Tree for Rewrite Delta tracking ----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the DeltaTree and related classes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Rewrite/Core/DeltaTree.h"
+#include "clang/Basic/LLVM.h"
+#include <cstdio>
+#include <cstring>
+using namespace clang;
+
+/// The DeltaTree class is a multiway search tree (BTree) structure with some
+/// fancy features.  B-Trees are generally more memory and cache efficient
+/// than binary trees, because they store multiple keys/values in each node.
+///
+/// DeltaTree implements a key/value mapping from FileIndex to Delta, allowing
+/// fast lookup by FileIndex.  However, an added (important) bonus is that it
+/// can also efficiently tell us the full accumulated delta for a specific
+/// file offset as well, without traversing the whole tree.
+///
+/// The nodes of the tree are made up of instances of two classes:
+/// DeltaTreeNode and DeltaTreeInteriorNode.  The later subclasses the
+/// former and adds children pointers.  Each node knows the full delta of all
+/// entries (recursively) contained inside of it, which allows us to get the
+/// full delta implied by a whole subtree in constant time.
+
+namespace {
+  /// SourceDelta - As code in the original input buffer is added and deleted,
+  /// SourceDelta records are used to keep track of how the input SourceLocation
+  /// object is mapped into the output buffer.
+  struct SourceDelta {
+    unsigned FileLoc;
+    int Delta;
+
+    static SourceDelta get(unsigned Loc, int D) {
+      SourceDelta Delta;
+      Delta.FileLoc = Loc;
+      Delta.Delta = D;
+      return Delta;
+    }
+  };
+  
+  /// DeltaTreeNode - The common part of all nodes.
+  ///
+  class DeltaTreeNode {
+  public:
+    struct InsertResult {
+      DeltaTreeNode *LHS, *RHS;
+      SourceDelta Split;
+    };
+    
+  private:
+    friend class DeltaTreeInteriorNode;
+
+    /// WidthFactor - This controls the number of K/V slots held in the BTree:
+    /// how wide it is.  Each level of the BTree is guaranteed to have at least
+    /// WidthFactor-1 K/V pairs (except the root) and may have at most
+    /// 2*WidthFactor-1 K/V pairs.
+    enum { WidthFactor = 8 };
+
+    /// Values - This tracks the SourceDelta's currently in this node.
+    ///
+    SourceDelta Values[2*WidthFactor-1];
+
+    /// NumValuesUsed - This tracks the number of values this node currently
+    /// holds.
+    unsigned char NumValuesUsed;
+
+    /// IsLeaf - This is true if this is a leaf of the btree.  If false, this is
+    /// an interior node, and is actually an instance of DeltaTreeInteriorNode.
+    bool IsLeaf;
+
+    /// FullDelta - This is the full delta of all the values in this node and
+    /// all children nodes.
+    int FullDelta;
+  public:
+    DeltaTreeNode(bool isLeaf = true)
+      : NumValuesUsed(0), IsLeaf(isLeaf), FullDelta(0) {}
+
+    bool isLeaf() const { return IsLeaf; }
+    int getFullDelta() const { return FullDelta; }
+    bool isFull() const { return NumValuesUsed == 2*WidthFactor-1; }
+
+    unsigned getNumValuesUsed() const { return NumValuesUsed; }
+    const SourceDelta &getValue(unsigned i) const {
+      assert(i < NumValuesUsed && "Invalid value #");
+      return Values[i];
+    }
+    SourceDelta &getValue(unsigned i) {
+      assert(i < NumValuesUsed && "Invalid value #");
+      return Values[i];
+    }
+
+    /// DoInsertion - Do an insertion of the specified FileIndex/Delta pair into
+    /// this node.  If insertion is easy, do it and return false.  Otherwise,
+    /// split the node, populate InsertRes with info about the split, and return
+    /// true.
+    bool DoInsertion(unsigned FileIndex, int Delta, InsertResult *InsertRes);
+
+    void DoSplit(InsertResult &InsertRes);
+
+
+    /// RecomputeFullDeltaLocally - Recompute the FullDelta field by doing a
+    /// local walk over our contained deltas.
+    void RecomputeFullDeltaLocally();
+
+    void Destroy();
+  };
+} // end anonymous namespace
+
+namespace {
+  /// DeltaTreeInteriorNode - When isLeaf = false, a node has child pointers.
+  /// This class tracks them.
+  class DeltaTreeInteriorNode : public DeltaTreeNode {
+    DeltaTreeNode *Children[2*WidthFactor];
+    ~DeltaTreeInteriorNode() {
+      for (unsigned i = 0, e = NumValuesUsed+1; i != e; ++i)
+        Children[i]->Destroy();
+    }
+    friend class DeltaTreeNode;
+  public:
+    DeltaTreeInteriorNode() : DeltaTreeNode(false /*nonleaf*/) {}
+
+    DeltaTreeInteriorNode(const InsertResult &IR)
+      : DeltaTreeNode(false /*nonleaf*/) {
+      Children[0] = IR.LHS;
+      Children[1] = IR.RHS;
+      Values[0] = IR.Split;
+      FullDelta = IR.LHS->getFullDelta()+IR.RHS->getFullDelta()+IR.Split.Delta;
+      NumValuesUsed = 1;
+    }
+
+    const DeltaTreeNode *getChild(unsigned i) const {
+      assert(i < getNumValuesUsed()+1 && "Invalid child");
+      return Children[i];
+    }
+    DeltaTreeNode *getChild(unsigned i) {
+      assert(i < getNumValuesUsed()+1 && "Invalid child");
+      return Children[i];
+    }
+
+    static inline bool classof(const DeltaTreeNode *N) { return !N->isLeaf(); }
+  };
+}
+
+
+/// Destroy - A 'virtual' destructor.
+void DeltaTreeNode::Destroy() {
+  if (isLeaf())
+    delete this;
+  else
+    delete cast<DeltaTreeInteriorNode>(this);
+}
+
+/// RecomputeFullDeltaLocally - Recompute the FullDelta field by doing a
+/// local walk over our contained deltas.
+void DeltaTreeNode::RecomputeFullDeltaLocally() {
+  int NewFullDelta = 0;
+  for (unsigned i = 0, e = getNumValuesUsed(); i != e; ++i)
+    NewFullDelta += Values[i].Delta;
+  if (DeltaTreeInteriorNode *IN = dyn_cast<DeltaTreeInteriorNode>(this))
+    for (unsigned i = 0, e = getNumValuesUsed()+1; i != e; ++i)
+      NewFullDelta += IN->getChild(i)->getFullDelta();
+  FullDelta = NewFullDelta;
+}
+
+/// DoInsertion - Do an insertion of the specified FileIndex/Delta pair into
+/// this node.  If insertion is easy, do it and return false.  Otherwise,
+/// split the node, populate InsertRes with info about the split, and return
+/// true.
+bool DeltaTreeNode::DoInsertion(unsigned FileIndex, int Delta,
+                                InsertResult *InsertRes) {
+  // Maintain full delta for this node.
+  FullDelta += Delta;
+
+  // Find the insertion point, the first delta whose index is >= FileIndex.
+  unsigned i = 0, e = getNumValuesUsed();
+  while (i != e && FileIndex > getValue(i).FileLoc)
+    ++i;
+
+  // If we found an a record for exactly this file index, just merge this
+  // value into the pre-existing record and finish early.
+  if (i != e && getValue(i).FileLoc == FileIndex) {
+    // NOTE: Delta could drop to zero here.  This means that the delta entry is
+    // useless and could be removed.  Supporting erases is more complex than
+    // leaving an entry with Delta=0, so we just leave an entry with Delta=0 in
+    // the tree.
+    Values[i].Delta += Delta;
+    return false;
+  }
+
+  // Otherwise, we found an insertion point, and we know that the value at the
+  // specified index is > FileIndex.  Handle the leaf case first.
+  if (isLeaf()) {
+    if (!isFull()) {
+      // For an insertion into a non-full leaf node, just insert the value in
+      // its sorted position.  This requires moving later values over.
+      if (i != e)
+        memmove(&Values[i+1], &Values[i], sizeof(Values[0])*(e-i));
+      Values[i] = SourceDelta::get(FileIndex, Delta);
+      ++NumValuesUsed;
+      return false;
+    }
+
+    // Otherwise, if this is leaf is full, split the node at its median, insert
+    // the value into one of the children, and return the result.
+    assert(InsertRes && "No result location specified");
+    DoSplit(*InsertRes);
+
+    if (InsertRes->Split.FileLoc > FileIndex)
+      InsertRes->LHS->DoInsertion(FileIndex, Delta, nullptr /*can't fail*/);
+    else
+      InsertRes->RHS->DoInsertion(FileIndex, Delta, nullptr /*can't fail*/);
+    return true;
+  }
+
+  // Otherwise, this is an interior node.  Send the request down the tree.
+  DeltaTreeInteriorNode *IN = cast<DeltaTreeInteriorNode>(this);
+  if (!IN->Children[i]->DoInsertion(FileIndex, Delta, InsertRes))
+    return false; // If there was space in the child, just return.
+
+  // Okay, this split the subtree, producing a new value and two children to
+  // insert here.  If this node is non-full, we can just insert it directly.
+  if (!isFull()) {
+    // Now that we have two nodes and a new element, insert the perclated value
+    // into ourself by moving all the later values/children down, then inserting
+    // the new one.
+    if (i != e)
+      memmove(&IN->Children[i+2], &IN->Children[i+1],
+              (e-i)*sizeof(IN->Children[0]));
+    IN->Children[i] = InsertRes->LHS;
+    IN->Children[i+1] = InsertRes->RHS;
+
+    if (e != i)
+      memmove(&Values[i+1], &Values[i], (e-i)*sizeof(Values[0]));
+    Values[i] = InsertRes->Split;
+    ++NumValuesUsed;
+    return false;
+  }
+
+  // Finally, if this interior node was full and a node is percolated up, split
+  // ourself and return that up the chain.  Start by saving all our info to
+  // avoid having the split clobber it.
+  IN->Children[i] = InsertRes->LHS;
+  DeltaTreeNode *SubRHS = InsertRes->RHS;
+  SourceDelta SubSplit = InsertRes->Split;
+
+  // Do the split.
+  DoSplit(*InsertRes);
+
+  // Figure out where to insert SubRHS/NewSplit.
+  DeltaTreeInteriorNode *InsertSide;
+  if (SubSplit.FileLoc < InsertRes->Split.FileLoc)
+    InsertSide = cast<DeltaTreeInteriorNode>(InsertRes->LHS);
+  else
+    InsertSide = cast<DeltaTreeInteriorNode>(InsertRes->RHS);
+
+  // We now have a non-empty interior node 'InsertSide' to insert
+  // SubRHS/SubSplit into.  Find out where to insert SubSplit.
+
+  // Find the insertion point, the first delta whose index is >SubSplit.FileLoc.
+  i = 0; e = InsertSide->getNumValuesUsed();
+  while (i != e && SubSplit.FileLoc > InsertSide->getValue(i).FileLoc)
+    ++i;
+
+  // Now we know that i is the place to insert the split value into.  Insert it
+  // and the child right after it.
+  if (i != e)
+    memmove(&InsertSide->Children[i+2], &InsertSide->Children[i+1],
+            (e-i)*sizeof(IN->Children[0]));
+  InsertSide->Children[i+1] = SubRHS;
+
+  if (e != i)
+    memmove(&InsertSide->Values[i+1], &InsertSide->Values[i],
+            (e-i)*sizeof(Values[0]));
+  InsertSide->Values[i] = SubSplit;
+  ++InsertSide->NumValuesUsed;
+  InsertSide->FullDelta += SubSplit.Delta + SubRHS->getFullDelta();
+  return true;
+}
+
+/// DoSplit - Split the currently full node (which has 2*WidthFactor-1 values)
+/// into two subtrees each with "WidthFactor-1" values and a pivot value.
+/// Return the pieces in InsertRes.
+void DeltaTreeNode::DoSplit(InsertResult &InsertRes) {
+  assert(isFull() && "Why split a non-full node?");
+
+  // Since this node is full, it contains 2*WidthFactor-1 values.  We move
+  // the first 'WidthFactor-1' values to the LHS child (which we leave in this
+  // node), propagate one value up, and move the last 'WidthFactor-1' values
+  // into the RHS child.
+
+  // Create the new child node.
+  DeltaTreeNode *NewNode;
+  if (DeltaTreeInteriorNode *IN = dyn_cast<DeltaTreeInteriorNode>(this)) {
+    // If this is an interior node, also move over 'WidthFactor' children
+    // into the new node.
+    DeltaTreeInteriorNode *New = new DeltaTreeInteriorNode();
+    memcpy(&New->Children[0], &IN->Children[WidthFactor],
+           WidthFactor*sizeof(IN->Children[0]));
+    NewNode = New;
+  } else {
+    // Just create the new leaf node.
+    NewNode = new DeltaTreeNode();
+  }
+
+  // Move over the last 'WidthFactor-1' values from here to NewNode.
+  memcpy(&NewNode->Values[0], &Values[WidthFactor],
+         (WidthFactor-1)*sizeof(Values[0]));
+
+  // Decrease the number of values in the two nodes.
+  NewNode->NumValuesUsed = NumValuesUsed = WidthFactor-1;
+
+  // Recompute the two nodes' full delta.
+  NewNode->RecomputeFullDeltaLocally();
+  RecomputeFullDeltaLocally();
+
+  InsertRes.LHS = this;
+  InsertRes.RHS = NewNode;
+  InsertRes.Split = Values[WidthFactor-1];
+}
+
+
+
+//===----------------------------------------------------------------------===//
+//                        DeltaTree Implementation
+//===----------------------------------------------------------------------===//
+
+//#define VERIFY_TREE
+
+#ifdef VERIFY_TREE
+/// VerifyTree - Walk the btree performing assertions on various properties to
+/// verify consistency.  This is useful for debugging new changes to the tree.
+static void VerifyTree(const DeltaTreeNode *N) {
+  const DeltaTreeInteriorNode *IN = dyn_cast<DeltaTreeInteriorNode>(N);
+  if (IN == 0) {
+    // Verify leaves, just ensure that FullDelta matches up and the elements
+    // are in proper order.
+    int FullDelta = 0;
+    for (unsigned i = 0, e = N->getNumValuesUsed(); i != e; ++i) {
+      if (i)
+        assert(N->getValue(i-1).FileLoc < N->getValue(i).FileLoc);
+      FullDelta += N->getValue(i).Delta;
+    }
+    assert(FullDelta == N->getFullDelta());
+    return;
+  }
+
+  // Verify interior nodes: Ensure that FullDelta matches up and the
+  // elements are in proper order and the children are in proper order.
+  int FullDelta = 0;
+  for (unsigned i = 0, e = IN->getNumValuesUsed(); i != e; ++i) {
+    const SourceDelta &IVal = N->getValue(i);
+    const DeltaTreeNode *IChild = IN->getChild(i);
+    if (i)
+      assert(IN->getValue(i-1).FileLoc < IVal.FileLoc);
+    FullDelta += IVal.Delta;
+    FullDelta += IChild->getFullDelta();
+
+    // The largest value in child #i should be smaller than FileLoc.
+    assert(IChild->getValue(IChild->getNumValuesUsed()-1).FileLoc <
+           IVal.FileLoc);
+
+    // The smallest value in child #i+1 should be larger than FileLoc.
+    assert(IN->getChild(i+1)->getValue(0).FileLoc > IVal.FileLoc);
+    VerifyTree(IChild);
+  }
+
+  FullDelta += IN->getChild(IN->getNumValuesUsed())->getFullDelta();
+
+  assert(FullDelta == N->getFullDelta());
+}
+#endif  // VERIFY_TREE
+
+static DeltaTreeNode *getRoot(void *Root) {
+  return (DeltaTreeNode*)Root;
+}
+
+DeltaTree::DeltaTree() {
+  Root = new DeltaTreeNode();
+}
+DeltaTree::DeltaTree(const DeltaTree &RHS) {
+  // Currently we only support copying when the RHS is empty.
+  assert(getRoot(RHS.Root)->getNumValuesUsed() == 0 &&
+         "Can only copy empty tree");
+  Root = new DeltaTreeNode();
+}
+
+DeltaTree::~DeltaTree() {
+  getRoot(Root)->Destroy();
+}
+
+/// getDeltaAt - Return the accumulated delta at the specified file offset.
+/// This includes all insertions or delections that occurred *before* the
+/// specified file index.
+int DeltaTree::getDeltaAt(unsigned FileIndex) const {
+  const DeltaTreeNode *Node = getRoot(Root);
+
+  int Result = 0;
+
+  // Walk down the tree.
+  while (1) {
+    // For all nodes, include any local deltas before the specified file
+    // index by summing them up directly.  Keep track of how many were
+    // included.
+    unsigned NumValsGreater = 0;
+    for (unsigned e = Node->getNumValuesUsed(); NumValsGreater != e;
+         ++NumValsGreater) {
+      const SourceDelta &Val = Node->getValue(NumValsGreater);
+
+      if (Val.FileLoc >= FileIndex)
+        break;
+      Result += Val.Delta;
+    }
+
+    // If we have an interior node, include information about children and
+    // recurse.  Otherwise, if we have a leaf, we're done.
+    const DeltaTreeInteriorNode *IN = dyn_cast<DeltaTreeInteriorNode>(Node);
+    if (!IN) return Result;
+
+    // Include any children to the left of the values we skipped, all of
+    // their deltas should be included as well.
+    for (unsigned i = 0; i != NumValsGreater; ++i)
+      Result += IN->getChild(i)->getFullDelta();
+
+    // If we found exactly the value we were looking for, break off the
+    // search early.  There is no need to search the RHS of the value for
+    // partial results.
+    if (NumValsGreater != Node->getNumValuesUsed() &&
+        Node->getValue(NumValsGreater).FileLoc == FileIndex)
+      return Result+IN->getChild(NumValsGreater)->getFullDelta();
+
+    // Otherwise, traverse down the tree.  The selected subtree may be
+    // partially included in the range.
+    Node = IN->getChild(NumValsGreater);
+  }
+  // NOT REACHED.
+}
+
+/// AddDelta - When a change is made that shifts around the text buffer,
+/// this method is used to record that info.  It inserts a delta of 'Delta'
+/// into the current DeltaTree at offset FileIndex.
+void DeltaTree::AddDelta(unsigned FileIndex, int Delta) {
+  assert(Delta && "Adding a noop?");
+  DeltaTreeNode *MyRoot = getRoot(Root);
+
+  DeltaTreeNode::InsertResult InsertRes;
+  if (MyRoot->DoInsertion(FileIndex, Delta, &InsertRes)) {
+    Root = MyRoot = new DeltaTreeInteriorNode(InsertRes);
+  }
+
+#ifdef VERIFY_TREE
+  VerifyTree(MyRoot);
+#endif
+}
+
diff --git a/lib/Rewrite/Frontend/CMakeLists.txt b/lib/Rewrite/Frontend/CMakeLists.txt
deleted file mode 100644
index 903a3ef..0000000
--- a/lib/Rewrite/Frontend/CMakeLists.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-add_clang_library(clangRewriteFrontend
-  FixItRewriter.cpp
-  FrontendActions.cpp
-  HTMLPrint.cpp
-  InclusionRewriter.cpp
-  RewriteMacros.cpp
-  RewriteModernObjC.cpp
-  RewriteObjC.cpp
-  RewriteTest.cpp
-  )
-
-add_dependencies(clangRewriteFrontend
-  ClangAttrClasses
-  ClangAttrList
-  ClangAttrParsedAttrList
-  ClangCommentNodes
-  ClangDeclNodes
-  ClangDiagnosticCommon
-  ClangDiagnosticFrontend
-  ClangStmtNodes
-  )
-
-target_link_libraries(clangRewriteFrontend
-  clangBasic
-  clangAST
-  clangParse
-  clangFrontend
-  clangRewriteCore
-  )
diff --git a/lib/Rewrite/Frontend/FixItRewriter.cpp b/lib/Rewrite/Frontend/FixItRewriter.cpp
deleted file mode 100644
index 8930c35..0000000
--- a/lib/Rewrite/Frontend/FixItRewriter.cpp
+++ /dev/null
@@ -1,200 +0,0 @@
-//===--- FixItRewriter.cpp - Fix-It Rewriter Diagnostic Client --*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This is a diagnostic client adaptor that performs rewrites as
-// suggested by code modification hints attached to diagnostics. It
-// then forwards any diagnostics to the adapted diagnostic client.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Rewrite/Frontend/FixItRewriter.h"
-#include "clang/Basic/FileManager.h"
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Edit/Commit.h"
-#include "clang/Edit/EditsReceiver.h"
-#include "clang/Frontend/FrontendDiagnostic.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/raw_ostream.h"
-#include <cstdio>
-
-using namespace clang;
-
-FixItRewriter::FixItRewriter(DiagnosticsEngine &Diags, SourceManager &SourceMgr,
-                             const LangOptions &LangOpts,
-                             FixItOptions *FixItOpts)
-  : Diags(Diags),
-    Editor(SourceMgr, LangOpts),
-    Rewrite(SourceMgr, LangOpts),
-    FixItOpts(FixItOpts),
-    NumFailures(0),
-    PrevDiagSilenced(false) {
-  OwnsClient = Diags.ownsClient();
-  Client = Diags.takeClient();
-  Diags.setClient(this);
-}
-
-FixItRewriter::~FixItRewriter() {
-  Diags.takeClient();
-  Diags.setClient(Client, OwnsClient);
-}
-
-bool FixItRewriter::WriteFixedFile(FileID ID, raw_ostream &OS) {
-  const RewriteBuffer *RewriteBuf = Rewrite.getRewriteBufferFor(ID);
-  if (!RewriteBuf) return true;
-  RewriteBuf->write(OS);
-  OS.flush();
-  return false;
-}
-
-namespace {
-
-class RewritesReceiver : public edit::EditsReceiver {
-  Rewriter &Rewrite;
-
-public:
-  RewritesReceiver(Rewriter &Rewrite) : Rewrite(Rewrite) { }
-
-  virtual void insert(SourceLocation loc, StringRef text) {
-    Rewrite.InsertText(loc, text);
-  }
-  virtual void replace(CharSourceRange range, StringRef text) {
-    Rewrite.ReplaceText(range.getBegin(), Rewrite.getRangeSize(range), text);
-  }
-};
-
-}
-
-bool FixItRewriter::WriteFixedFiles(
-            std::vector<std::pair<std::string, std::string> > *RewrittenFiles) {
-  if (NumFailures > 0 && !FixItOpts->FixWhatYouCan) {
-    Diag(FullSourceLoc(), diag::warn_fixit_no_changes);
-    return true;
-  }
-
-  RewritesReceiver Rec(Rewrite);
-  Editor.applyRewrites(Rec);
-
-  for (iterator I = buffer_begin(), E = buffer_end(); I != E; ++I) {
-    const FileEntry *Entry = Rewrite.getSourceMgr().getFileEntryForID(I->first);
-    int fd;
-    std::string Filename = FixItOpts->RewriteFilename(Entry->getName(), fd);
-    std::string Err;
-    OwningPtr<llvm::raw_fd_ostream> OS;
-    if (fd != -1) {
-      OS.reset(new llvm::raw_fd_ostream(fd, /*shouldClose=*/true));
-    } else {
-      OS.reset(new llvm::raw_fd_ostream(Filename.c_str(), Err,
-                                        llvm::sys::fs::F_Binary));
-    }
-    if (!Err.empty()) {
-      Diags.Report(clang::diag::err_fe_unable_to_open_output)
-          << Filename << Err;
-      continue;
-    }
-    RewriteBuffer &RewriteBuf = I->second;
-    RewriteBuf.write(*OS);
-    OS->flush();
-
-    if (RewrittenFiles)
-      RewrittenFiles->push_back(std::make_pair(Entry->getName(), Filename));
-  }
-
-  return false;
-}
-
-bool FixItRewriter::IncludeInDiagnosticCounts() const {
-  return Client ? Client->IncludeInDiagnosticCounts() : true;
-}
-
-void FixItRewriter::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
-                                     const Diagnostic &Info) {
-  // Default implementation (Warnings/errors count).
-  DiagnosticConsumer::HandleDiagnostic(DiagLevel, Info);
-
-  if (!FixItOpts->Silent ||
-      DiagLevel >= DiagnosticsEngine::Error ||
-      (DiagLevel == DiagnosticsEngine::Note && !PrevDiagSilenced) ||
-      (DiagLevel > DiagnosticsEngine::Note && Info.getNumFixItHints())) {
-    Client->HandleDiagnostic(DiagLevel, Info);
-    PrevDiagSilenced = false;
-  } else {
-    PrevDiagSilenced = true;
-  }
-
-  // Skip over any diagnostics that are ignored or notes.
-  if (DiagLevel <= DiagnosticsEngine::Note)
-    return;
-  // Skip over errors if we are only fixing warnings.
-  if (DiagLevel >= DiagnosticsEngine::Error && FixItOpts->FixOnlyWarnings) {
-    ++NumFailures;
-    return;
-  }
-
-  // Make sure that we can perform all of the modifications we
-  // in this diagnostic.
-  edit::Commit commit(Editor);
-  for (unsigned Idx = 0, Last = Info.getNumFixItHints();
-       Idx < Last; ++Idx) {
-    const FixItHint &Hint = Info.getFixItHint(Idx);
-
-    if (Hint.CodeToInsert.empty()) {
-      if (Hint.InsertFromRange.isValid())
-        commit.insertFromRange(Hint.RemoveRange.getBegin(),
-                           Hint.InsertFromRange, /*afterToken=*/false,
-                           Hint.BeforePreviousInsertions);
-      else
-        commit.remove(Hint.RemoveRange);
-    } else {
-      if (Hint.RemoveRange.isTokenRange() ||
-          Hint.RemoveRange.getBegin() != Hint.RemoveRange.getEnd())
-        commit.replace(Hint.RemoveRange, Hint.CodeToInsert);
-      else
-        commit.insert(Hint.RemoveRange.getBegin(), Hint.CodeToInsert,
-                    /*afterToken=*/false, Hint.BeforePreviousInsertions);
-    }
-  }
-  bool CanRewrite = Info.getNumFixItHints() > 0 && commit.isCommitable();
-
-  if (!CanRewrite) {
-    if (Info.getNumFixItHints() > 0)
-      Diag(Info.getLocation(), diag::note_fixit_in_macro);
-
-    // If this was an error, refuse to perform any rewriting.
-    if (DiagLevel >= DiagnosticsEngine::Error) {
-      if (++NumFailures == 1)
-        Diag(Info.getLocation(), diag::note_fixit_unfixed_error);
-    }
-    return;
-  }
-  
-  if (!Editor.commit(commit)) {
-    ++NumFailures;
-    Diag(Info.getLocation(), diag::note_fixit_failed);
-    return;
-  }
-
-  Diag(Info.getLocation(), diag::note_fixit_applied);
-}
-
-/// \brief Emit a diagnostic via the adapted diagnostic client.
-void FixItRewriter::Diag(SourceLocation Loc, unsigned DiagID) {
-  // When producing this diagnostic, we temporarily bypass ourselves,
-  // clear out any current diagnostic, and let the downstream client
-  // format the diagnostic.
-  Diags.takeClient();
-  Diags.setClient(Client);
-  Diags.Clear();
-  Diags.Report(Loc, DiagID);
-  Diags.takeClient();
-  Diags.setClient(this);
-}
-
-FixItOptions::~FixItOptions() {}
diff --git a/lib/Rewrite/Frontend/FrontendActions.cpp b/lib/Rewrite/Frontend/FrontendActions.cpp
deleted file mode 100644
index e9ec388..0000000
--- a/lib/Rewrite/Frontend/FrontendActions.cpp
+++ /dev/null
@@ -1,192 +0,0 @@
-//===--- FrontendActions.cpp ----------------------------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Rewrite/Frontend/FrontendActions.h"
-#include "clang/AST/ASTConsumer.h"
-#include "clang/Basic/FileManager.h"
-#include "clang/Frontend/CompilerInstance.h"
-#include "clang/Frontend/FrontendActions.h"
-#include "clang/Frontend/FrontendDiagnostic.h"
-#include "clang/Frontend/Utils.h"
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Parse/Parser.h"
-#include "clang/Rewrite/Frontend/ASTConsumers.h"
-#include "clang/Rewrite/Frontend/FixItRewriter.h"
-#include "clang/Rewrite/Frontend/Rewriters.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// AST Consumer Actions
-//===----------------------------------------------------------------------===//
-
-ASTConsumer *HTMLPrintAction::CreateASTConsumer(CompilerInstance &CI,
-                                                StringRef InFile) {
-  if (raw_ostream *OS = CI.createDefaultOutputFile(false, InFile))
-    return CreateHTMLPrinter(OS, CI.getPreprocessor());
-  return 0;
-}
-
-FixItAction::FixItAction() {}
-FixItAction::~FixItAction() {}
-
-ASTConsumer *FixItAction::CreateASTConsumer(CompilerInstance &CI,
-                                            StringRef InFile) {
-  return new ASTConsumer();
-}
-
-namespace {
-class FixItRewriteInPlace : public FixItOptions {
-public:
-  std::string RewriteFilename(const std::string &Filename, int &fd) {
-    fd = -1;
-    return Filename;
-  }
-};
-
-class FixItActionSuffixInserter : public FixItOptions {
-  std::string NewSuffix;
-
-public:
-  FixItActionSuffixInserter(std::string NewSuffix, bool FixWhatYouCan)
-    : NewSuffix(NewSuffix) {
-      this->FixWhatYouCan = FixWhatYouCan;
-  }
-
-  std::string RewriteFilename(const std::string &Filename, int &fd) {
-    fd = -1;
-    SmallString<128> Path(Filename);
-    llvm::sys::path::replace_extension(Path,
-      NewSuffix + llvm::sys::path::extension(Path));
-    return Path.str();
-  }
-};
-
-class FixItRewriteToTemp : public FixItOptions {
-public:
-  std::string RewriteFilename(const std::string &Filename, int &fd) {
-    SmallString<128> Path;
-    llvm::sys::fs::createTemporaryFile(llvm::sys::path::filename(Filename),
-                                       llvm::sys::path::extension(Filename), fd,
-                                       Path);
-    return Path.str();
-  }
-};
-} // end anonymous namespace
-
-bool FixItAction::BeginSourceFileAction(CompilerInstance &CI,
-                                        StringRef Filename) {
-  const FrontendOptions &FEOpts = getCompilerInstance().getFrontendOpts();
-  if (!FEOpts.FixItSuffix.empty()) {
-    FixItOpts.reset(new FixItActionSuffixInserter(FEOpts.FixItSuffix,
-                                                  FEOpts.FixWhatYouCan));
-  } else {
-    FixItOpts.reset(new FixItRewriteInPlace);
-    FixItOpts->FixWhatYouCan = FEOpts.FixWhatYouCan;
-  }
-  Rewriter.reset(new FixItRewriter(CI.getDiagnostics(), CI.getSourceManager(),
-                                   CI.getLangOpts(), FixItOpts.get()));
-  return true;
-}
-
-void FixItAction::EndSourceFileAction() {
-  // Otherwise rewrite all files.
-  Rewriter->WriteFixedFiles();
-}
-
-bool FixItRecompile::BeginInvocation(CompilerInstance &CI) {
-
-  std::vector<std::pair<std::string, std::string> > RewrittenFiles;
-  bool err = false;
-  {
-    const FrontendOptions &FEOpts = CI.getFrontendOpts();
-    OwningPtr<FrontendAction> FixAction(new SyntaxOnlyAction());
-    if (FixAction->BeginSourceFile(CI, FEOpts.Inputs[0])) {
-      OwningPtr<FixItOptions> FixItOpts;
-      if (FEOpts.FixToTemporaries)
-        FixItOpts.reset(new FixItRewriteToTemp());
-      else
-        FixItOpts.reset(new FixItRewriteInPlace());
-      FixItOpts->Silent = true;
-      FixItOpts->FixWhatYouCan = FEOpts.FixWhatYouCan;
-      FixItOpts->FixOnlyWarnings = FEOpts.FixOnlyWarnings;
-      FixItRewriter Rewriter(CI.getDiagnostics(), CI.getSourceManager(),
-                             CI.getLangOpts(), FixItOpts.get());
-      FixAction->Execute();
-  
-      err = Rewriter.WriteFixedFiles(&RewrittenFiles);
-    
-      FixAction->EndSourceFile();
-      CI.setSourceManager(0);
-      CI.setFileManager(0);
-    } else {
-      err = true;
-    }
-  }
-  if (err)
-    return false;
-  CI.getDiagnosticClient().clear();
-  CI.getDiagnostics().Reset();
-
-  PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();
-  PPOpts.RemappedFiles.insert(PPOpts.RemappedFiles.end(),
-                              RewrittenFiles.begin(), RewrittenFiles.end());
-  PPOpts.RemappedFilesKeepOriginalName = false;
-
-  return true;
-}
-
-//===----------------------------------------------------------------------===//
-// Preprocessor Actions
-//===----------------------------------------------------------------------===//
-
-ASTConsumer *RewriteObjCAction::CreateASTConsumer(CompilerInstance &CI,
-                                                  StringRef InFile) {
-  if (raw_ostream *OS = CI.createDefaultOutputFile(false, InFile, "cpp")) {
-    if (CI.getLangOpts().ObjCRuntime.isNonFragile())
-      return CreateModernObjCRewriter(InFile, OS,
-                                CI.getDiagnostics(), CI.getLangOpts(),
-                                CI.getDiagnosticOpts().NoRewriteMacros,
-                                (CI.getCodeGenOpts().getDebugInfo() !=
-                                 CodeGenOptions::NoDebugInfo));
-    return CreateObjCRewriter(InFile, OS,
-                              CI.getDiagnostics(), CI.getLangOpts(),
-                              CI.getDiagnosticOpts().NoRewriteMacros);
-  }
-  return 0;
-}
-
-void RewriteMacrosAction::ExecuteAction() {
-  CompilerInstance &CI = getCompilerInstance();
-  raw_ostream *OS = CI.createDefaultOutputFile(true, getCurrentFile());
-  if (!OS) return;
-
-  RewriteMacrosInInput(CI.getPreprocessor(), OS);
-}
-
-void RewriteTestAction::ExecuteAction() {
-  CompilerInstance &CI = getCompilerInstance();
-  raw_ostream *OS = CI.createDefaultOutputFile(false, getCurrentFile());
-  if (!OS) return;
-
-  DoRewriteTest(CI.getPreprocessor(), OS);
-}
-
-void RewriteIncludesAction::ExecuteAction() {
-  CompilerInstance &CI = getCompilerInstance();
-  raw_ostream *OS = CI.createDefaultOutputFile(true, getCurrentFile());
-  if (!OS) return;
-
-  RewriteIncludesInInput(CI.getPreprocessor(), OS,
-                         CI.getPreprocessorOutputOpts());
-}
diff --git a/lib/Rewrite/Frontend/HTMLPrint.cpp b/lib/Rewrite/Frontend/HTMLPrint.cpp
deleted file mode 100644
index 79e4447..0000000
--- a/lib/Rewrite/Frontend/HTMLPrint.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-//===--- HTMLPrint.cpp - Source code -> HTML pretty-printing --------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Pretty-printing of source code to HTML.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Rewrite/Frontend/ASTConsumers.h"
-#include "clang/AST/ASTConsumer.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Decl.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/FileManager.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Rewrite/Core/HTMLRewrite.h"
-#include "clang/Rewrite/Core/Rewriter.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/raw_ostream.h"
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// Functional HTML pretty-printing.
-//===----------------------------------------------------------------------===//
-
-namespace {
-  class HTMLPrinter : public ASTConsumer {
-    Rewriter R;
-    raw_ostream *Out;
-    Preprocessor &PP;
-    bool SyntaxHighlight, HighlightMacros;
-
-  public:
-    HTMLPrinter(raw_ostream *OS, Preprocessor &pp,
-                bool _SyntaxHighlight, bool _HighlightMacros)
-      : Out(OS), PP(pp), SyntaxHighlight(_SyntaxHighlight),
-        HighlightMacros(_HighlightMacros) {}
-
-    void Initialize(ASTContext &context);
-    void HandleTranslationUnit(ASTContext &Ctx);
-  };
-}
-
-ASTConsumer* clang::CreateHTMLPrinter(raw_ostream *OS,
-                                      Preprocessor &PP,
-                                      bool SyntaxHighlight,
-                                      bool HighlightMacros) {
-  return new HTMLPrinter(OS, PP, SyntaxHighlight, HighlightMacros);
-}
-
-void HTMLPrinter::Initialize(ASTContext &context) {
-  R.setSourceMgr(context.getSourceManager(), context.getLangOpts());
-}
-
-void HTMLPrinter::HandleTranslationUnit(ASTContext &Ctx) {
-  if (PP.getDiagnostics().hasErrorOccurred())
-    return;
-
-  // Format the file.
-  FileID FID = R.getSourceMgr().getMainFileID();
-  const FileEntry* Entry = R.getSourceMgr().getFileEntryForID(FID);
-  const char* Name;
-  // In some cases, in particular the case where the input is from stdin,
-  // there is no entry.  Fall back to the memory buffer for a name in those
-  // cases.
-  if (Entry)
-    Name = Entry->getName();
-  else
-    Name = R.getSourceMgr().getBuffer(FID)->getBufferIdentifier();
-
-  html::AddLineNumbers(R, FID);
-  html::AddHeaderFooterInternalBuiltinCSS(R, FID, Name);
-
-  // If we have a preprocessor, relex the file and syntax highlight.
-  // We might not have a preprocessor if we come from a deserialized AST file,
-  // for example.
-
-  if (SyntaxHighlight) html::SyntaxHighlight(R, FID, PP);
-  if (HighlightMacros) html::HighlightMacros(R, FID, PP);
-  html::EscapeText(R, FID, false, true);
-
-  // Emit the HTML.
-  const RewriteBuffer &RewriteBuf = R.getEditBuffer(FID);
-  char *Buffer = (char*)malloc(RewriteBuf.size());
-  std::copy(RewriteBuf.begin(), RewriteBuf.end(), Buffer);
-  Out->write(Buffer, RewriteBuf.size());
-  free(Buffer);
-}
diff --git a/lib/Rewrite/Frontend/InclusionRewriter.cpp b/lib/Rewrite/Frontend/InclusionRewriter.cpp
deleted file mode 100644
index bd4250a..0000000
--- a/lib/Rewrite/Frontend/InclusionRewriter.cpp
+++ /dev/null
@@ -1,545 +0,0 @@
-//===--- InclusionRewriter.cpp - Rewrite includes into their expansions ---===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This code rewrites include invocations into their expansions.  This gives you
-// a file with all included files merged into it.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Rewrite/Frontend/Rewriters.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Frontend/PreprocessorOutputOptions.h"
-#include "clang/Lex/HeaderSearch.h"
-#include "clang/Lex/Pragma.h"
-#include "clang/Lex/Preprocessor.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace clang;
-using namespace llvm;
-
-namespace {
-
-class InclusionRewriter : public PPCallbacks {
-  /// Information about which #includes were actually performed,
-  /// created by preprocessor callbacks.
-  struct FileChange {
-    const Module *Mod;
-    SourceLocation From;
-    FileID Id;
-    SrcMgr::CharacteristicKind FileType;
-    FileChange(SourceLocation From, const Module *Mod) : Mod(Mod), From(From) {
-    }
-  };
-  Preprocessor &PP; ///< Used to find inclusion directives.
-  SourceManager &SM; ///< Used to read and manage source files.
-  raw_ostream &OS; ///< The destination stream for rewritten contents.
-  const llvm::MemoryBuffer *PredefinesBuffer; ///< The preprocessor predefines.
-  bool ShowLineMarkers; ///< Show #line markers.
-  bool UseLineDirective; ///< Use of line directives or line markers.
-  typedef std::map<unsigned, FileChange> FileChangeMap;
-  FileChangeMap FileChanges; ///< Tracks which files were included where.
-  /// Used transitively for building up the FileChanges mapping over the
-  /// various \c PPCallbacks callbacks.
-  FileChangeMap::iterator LastInsertedFileChange;
-public:
-  InclusionRewriter(Preprocessor &PP, raw_ostream &OS, bool ShowLineMarkers);
-  bool Process(FileID FileId, SrcMgr::CharacteristicKind FileType);
-  void setPredefinesBuffer(const llvm::MemoryBuffer *Buf) {
-    PredefinesBuffer = Buf;
-  }
-private:
-  virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
-                           SrcMgr::CharacteristicKind FileType,
-                           FileID PrevFID);
-  virtual void FileSkipped(const FileEntry &ParentFile,
-                           const Token &FilenameTok,
-                           SrcMgr::CharacteristicKind FileType);
-  virtual void InclusionDirective(SourceLocation HashLoc,
-                                  const Token &IncludeTok,
-                                  StringRef FileName,
-                                  bool IsAngled,
-                                  CharSourceRange FilenameRange,
-                                  const FileEntry *File,
-                                  StringRef SearchPath,
-                                  StringRef RelativePath,
-                                  const Module *Imported);
-  void WriteLineInfo(const char *Filename, int Line,
-                     SrcMgr::CharacteristicKind FileType,
-                     StringRef EOL, StringRef Extra = StringRef());
-  void WriteImplicitModuleImport(const Module *Mod, StringRef EOL);
-  void OutputContentUpTo(const MemoryBuffer &FromFile,
-                         unsigned &WriteFrom, unsigned WriteTo,
-                         StringRef EOL, int &lines,
-                         bool EnsureNewline = false);
-  void CommentOutDirective(Lexer &DirectivesLex, const Token &StartToken,
-                           const MemoryBuffer &FromFile, StringRef EOL,
-                           unsigned &NextToWrite, int &Lines);
-  bool HandleHasInclude(FileID FileId, Lexer &RawLex,
-                        const DirectoryLookup *Lookup, Token &Tok,
-                        bool &FileExists);
-  const FileChange *FindFileChangeLocation(SourceLocation Loc) const;
-  StringRef NextIdentifierName(Lexer &RawLex, Token &RawToken);
-};
-
-}  // end anonymous namespace
-
-/// Initializes an InclusionRewriter with a \p PP source and \p OS destination.
-InclusionRewriter::InclusionRewriter(Preprocessor &PP, raw_ostream &OS,
-                                     bool ShowLineMarkers)
-    : PP(PP), SM(PP.getSourceManager()), OS(OS), PredefinesBuffer(0),
-    ShowLineMarkers(ShowLineMarkers),
-    LastInsertedFileChange(FileChanges.end()) {
-  // If we're in microsoft mode, use normal #line instead of line markers.
-  UseLineDirective = PP.getLangOpts().MicrosoftExt;
-}
-
-/// Write appropriate line information as either #line directives or GNU line
-/// markers depending on what mode we're in, including the \p Filename and
-/// \p Line we are located at, using the specified \p EOL line separator, and
-/// any \p Extra context specifiers in GNU line directives.
-void InclusionRewriter::WriteLineInfo(const char *Filename, int Line,
-                                      SrcMgr::CharacteristicKind FileType,
-                                      StringRef EOL, StringRef Extra) {
-  if (!ShowLineMarkers)
-    return;
-  if (UseLineDirective) {
-    OS << "#line" << ' ' << Line << ' ' << '"';
-    OS.write_escaped(Filename);
-    OS << '"';
-  } else {
-    // Use GNU linemarkers as described here:
-    // http://gcc.gnu.org/onlinedocs/cpp/Preprocessor-Output.html
-    OS << '#' << ' ' << Line << ' ' << '"';
-    OS.write_escaped(Filename);
-    OS << '"';
-    if (!Extra.empty())
-      OS << Extra;
-    if (FileType == SrcMgr::C_System)
-      // "`3' This indicates that the following text comes from a system header
-      // file, so certain warnings should be suppressed."
-      OS << " 3";
-    else if (FileType == SrcMgr::C_ExternCSystem)
-      // as above for `3', plus "`4' This indicates that the following text
-      // should be treated as being wrapped in an implicit extern "C" block."
-      OS << " 3 4";
-  }
-  OS << EOL;
-}
-
-void InclusionRewriter::WriteImplicitModuleImport(const Module *Mod,
-                                                  StringRef EOL) {
-  OS << "@import " << Mod->getFullModuleName() << ";"
-     << " /* clang -frewrite-includes: implicit import */" << EOL;
-}
-
-/// FileChanged - Whenever the preprocessor enters or exits a #include file
-/// it invokes this handler.
-void InclusionRewriter::FileChanged(SourceLocation Loc,
-                                    FileChangeReason Reason,
-                                    SrcMgr::CharacteristicKind NewFileType,
-                                    FileID) {
-  if (Reason != EnterFile)
-    return;
-  if (LastInsertedFileChange == FileChanges.end())
-    // we didn't reach this file (eg: the main file) via an inclusion directive
-    return;
-  LastInsertedFileChange->second.Id = FullSourceLoc(Loc, SM).getFileID();
-  LastInsertedFileChange->second.FileType = NewFileType;
-  LastInsertedFileChange = FileChanges.end();
-}
-
-/// Called whenever an inclusion is skipped due to canonical header protection
-/// macros.
-void InclusionRewriter::FileSkipped(const FileEntry &/*ParentFile*/,
-                                    const Token &/*FilenameTok*/,
-                                    SrcMgr::CharacteristicKind /*FileType*/) {
-  assert(LastInsertedFileChange != FileChanges.end() && "A file, that wasn't "
-    "found via an inclusion directive, was skipped");
-  FileChanges.erase(LastInsertedFileChange);
-  LastInsertedFileChange = FileChanges.end();
-}
-
-/// This should be called whenever the preprocessor encounters include
-/// directives. It does not say whether the file has been included, but it
-/// provides more information about the directive (hash location instead
-/// of location inside the included file). It is assumed that the matching
-/// FileChanged() or FileSkipped() is called after this.
-void InclusionRewriter::InclusionDirective(SourceLocation HashLoc,
-                                           const Token &/*IncludeTok*/,
-                                           StringRef /*FileName*/,
-                                           bool /*IsAngled*/,
-                                           CharSourceRange /*FilenameRange*/,
-                                           const FileEntry * /*File*/,
-                                           StringRef /*SearchPath*/,
-                                           StringRef /*RelativePath*/,
-                                           const Module *Imported) {
-  assert(LastInsertedFileChange == FileChanges.end() && "Another inclusion "
-    "directive was found before the previous one was processed");
-  std::pair<FileChangeMap::iterator, bool> p = FileChanges.insert(
-    std::make_pair(HashLoc.getRawEncoding(), FileChange(HashLoc, Imported)));
-  assert(p.second && "Unexpected revisitation of the same include directive");
-  if (!Imported)
-    LastInsertedFileChange = p.first;
-}
-
-/// Simple lookup for a SourceLocation (specifically one denoting the hash in
-/// an inclusion directive) in the map of inclusion information, FileChanges.
-const InclusionRewriter::FileChange *
-InclusionRewriter::FindFileChangeLocation(SourceLocation Loc) const {
-  FileChangeMap::const_iterator I = FileChanges.find(Loc.getRawEncoding());
-  if (I != FileChanges.end())
-    return &I->second;
-  return NULL;
-}
-
-/// Detect the likely line ending style of \p FromFile by examining the first
-/// newline found within it.
-static StringRef DetectEOL(const MemoryBuffer &FromFile) {
-  // detect what line endings the file uses, so that added content does not mix
-  // the style
-  const char *Pos = strchr(FromFile.getBufferStart(), '\n');
-  if (Pos == NULL)
-    return "\n";
-  if (Pos + 1 < FromFile.getBufferEnd() && Pos[1] == '\r')
-    return "\n\r";
-  if (Pos - 1 >= FromFile.getBufferStart() && Pos[-1] == '\r')
-    return "\r\n";
-  return "\n";
-}
-
-/// Writes out bytes from \p FromFile, starting at \p NextToWrite and ending at
-/// \p WriteTo - 1.
-void InclusionRewriter::OutputContentUpTo(const MemoryBuffer &FromFile,
-                                          unsigned &WriteFrom, unsigned WriteTo,
-                                          StringRef EOL, int &Line,
-                                          bool EnsureNewline) {
-  if (WriteTo <= WriteFrom)
-    return;
-  if (&FromFile == PredefinesBuffer) {
-    // Ignore the #defines of the predefines buffer.
-    WriteFrom = WriteTo;
-    return;
-  }
-  OS.write(FromFile.getBufferStart() + WriteFrom, WriteTo - WriteFrom);
-  // count lines manually, it's faster than getPresumedLoc()
-  Line += std::count(FromFile.getBufferStart() + WriteFrom,
-                     FromFile.getBufferStart() + WriteTo, '\n');
-  if (EnsureNewline) {
-    char LastChar = FromFile.getBufferStart()[WriteTo - 1];
-    if (LastChar != '\n' && LastChar != '\r')
-      OS << EOL;
-  }
-  WriteFrom = WriteTo;
-}
-
-/// Print characters from \p FromFile starting at \p NextToWrite up until the
-/// inclusion directive at \p StartToken, then print out the inclusion
-/// inclusion directive disabled by a #if directive, updating \p NextToWrite
-/// and \p Line to track the number of source lines visited and the progress
-/// through the \p FromFile buffer.
-void InclusionRewriter::CommentOutDirective(Lexer &DirectiveLex,
-                                            const Token &StartToken,
-                                            const MemoryBuffer &FromFile,
-                                            StringRef EOL,
-                                            unsigned &NextToWrite, int &Line) {
-  OutputContentUpTo(FromFile, NextToWrite,
-    SM.getFileOffset(StartToken.getLocation()), EOL, Line);
-  Token DirectiveToken;
-  do {
-    DirectiveLex.LexFromRawLexer(DirectiveToken);
-  } while (!DirectiveToken.is(tok::eod) && DirectiveToken.isNot(tok::eof));
-  OS << "#if 0 /* expanded by -frewrite-includes */" << EOL;
-  OutputContentUpTo(FromFile, NextToWrite,
-    SM.getFileOffset(DirectiveToken.getLocation()) + DirectiveToken.getLength(),
-    EOL, Line);
-  OS << "#endif /* expanded by -frewrite-includes */" << EOL;
-}
-
-/// Find the next identifier in the pragma directive specified by \p RawToken.
-StringRef InclusionRewriter::NextIdentifierName(Lexer &RawLex,
-                                                Token &RawToken) {
-  RawLex.LexFromRawLexer(RawToken);
-  if (RawToken.is(tok::raw_identifier))
-    PP.LookUpIdentifierInfo(RawToken);
-  if (RawToken.is(tok::identifier))
-    return RawToken.getIdentifierInfo()->getName();
-  return StringRef();
-}
-
-// Expand __has_include and __has_include_next if possible. If there's no
-// definitive answer return false.
-bool InclusionRewriter::HandleHasInclude(
-    FileID FileId, Lexer &RawLex, const DirectoryLookup *Lookup, Token &Tok,
-    bool &FileExists) {
-  // Lex the opening paren.
-  RawLex.LexFromRawLexer(Tok);
-  if (Tok.isNot(tok::l_paren))
-    return false;
-
-  RawLex.LexFromRawLexer(Tok);
-
-  SmallString<128> FilenameBuffer;
-  StringRef Filename;
-  // Since the raw lexer doesn't give us angle_literals we have to parse them
-  // ourselves.
-  // FIXME: What to do if the file name is a macro?
-  if (Tok.is(tok::less)) {
-    RawLex.LexFromRawLexer(Tok);
-
-    FilenameBuffer += '<';
-    do {
-      if (Tok.is(tok::eod)) // Sanity check.
-        return false;
-
-      if (Tok.is(tok::raw_identifier))
-        PP.LookUpIdentifierInfo(Tok);
-
-      // Get the string piece.
-      SmallVector<char, 128> TmpBuffer;
-      bool Invalid = false;
-      StringRef TmpName = PP.getSpelling(Tok, TmpBuffer, &Invalid);
-      if (Invalid)
-        return false;
-
-      FilenameBuffer += TmpName;
-
-      RawLex.LexFromRawLexer(Tok);
-    } while (Tok.isNot(tok::greater));
-
-    FilenameBuffer += '>';
-    Filename = FilenameBuffer;
-  } else {
-    if (Tok.isNot(tok::string_literal))
-      return false;
-
-    bool Invalid = false;
-    Filename = PP.getSpelling(Tok, FilenameBuffer, &Invalid);
-    if (Invalid)
-      return false;
-  }
-
-  // Lex the closing paren.
-  RawLex.LexFromRawLexer(Tok);
-  if (Tok.isNot(tok::r_paren))
-    return false;
-
-  // Now ask HeaderInfo if it knows about the header.
-  // FIXME: Subframeworks aren't handled here. Do we care?
-  bool isAngled = PP.GetIncludeFilenameSpelling(Tok.getLocation(), Filename);
-  const DirectoryLookup *CurDir;
-  const FileEntry *File = PP.getHeaderSearchInfo().LookupFile(
-      Filename, isAngled, 0, CurDir,
-      PP.getSourceManager().getFileEntryForID(FileId), 0, 0, 0, false);
-
-  FileExists = File != 0;
-  return true;
-}
-
-/// Use a raw lexer to analyze \p FileId, incrementally copying parts of it
-/// and including content of included files recursively.
-bool InclusionRewriter::Process(FileID FileId,
-                                SrcMgr::CharacteristicKind FileType)
-{
-  bool Invalid;
-  const MemoryBuffer &FromFile = *SM.getBuffer(FileId, &Invalid);
-  if (Invalid) // invalid inclusion
-    return false;
-  const char *FileName = FromFile.getBufferIdentifier();
-  Lexer RawLex(FileId, &FromFile, PP.getSourceManager(), PP.getLangOpts());
-  RawLex.SetCommentRetentionState(false);
-
-  StringRef EOL = DetectEOL(FromFile);
-
-  // Per the GNU docs: "1" indicates the start of a new file.
-  WriteLineInfo(FileName, 1, FileType, EOL, " 1");
-
-  if (SM.getFileIDSize(FileId) == 0)
-    return false;
-
-  // The next byte to be copied from the source file
-  unsigned NextToWrite = 0;
-  int Line = 1; // The current input file line number.
-
-  Token RawToken;
-  RawLex.LexFromRawLexer(RawToken);
-
-  // TODO: Consider adding a switch that strips possibly unimportant content,
-  // such as comments, to reduce the size of repro files.
-  while (RawToken.isNot(tok::eof)) {
-    if (RawToken.is(tok::hash) && RawToken.isAtStartOfLine()) {
-      RawLex.setParsingPreprocessorDirective(true);
-      Token HashToken = RawToken;
-      RawLex.LexFromRawLexer(RawToken);
-      if (RawToken.is(tok::raw_identifier))
-        PP.LookUpIdentifierInfo(RawToken);
-      if (RawToken.getIdentifierInfo() != NULL) {
-        switch (RawToken.getIdentifierInfo()->getPPKeywordID()) {
-          case tok::pp_include:
-          case tok::pp_include_next:
-          case tok::pp_import: {
-            CommentOutDirective(RawLex, HashToken, FromFile, EOL, NextToWrite,
-              Line);
-            StringRef LineInfoExtra;
-            if (const FileChange *Change = FindFileChangeLocation(
-                HashToken.getLocation())) {
-              if (Change->Mod) {
-                WriteImplicitModuleImport(Change->Mod, EOL);
-
-              // else now include and recursively process the file
-              } else if (Process(Change->Id, Change->FileType)) {
-                // and set lineinfo back to this file, if the nested one was
-                // actually included
-                // `2' indicates returning to a file (after having included
-                // another file.
-                LineInfoExtra = " 2";
-              }
-            }
-            // fix up lineinfo (since commented out directive changed line
-            // numbers) for inclusions that were skipped due to header guards
-            WriteLineInfo(FileName, Line, FileType, EOL, LineInfoExtra);
-            break;
-          }
-          case tok::pp_pragma: {
-            StringRef Identifier = NextIdentifierName(RawLex, RawToken);
-            if (Identifier == "clang" || Identifier == "GCC") {
-              if (NextIdentifierName(RawLex, RawToken) == "system_header") {
-                // keep the directive in, commented out
-                CommentOutDirective(RawLex, HashToken, FromFile, EOL,
-                  NextToWrite, Line);
-                // update our own type
-                FileType = SM.getFileCharacteristic(RawToken.getLocation());
-                WriteLineInfo(FileName, Line, FileType, EOL);
-              }
-            } else if (Identifier == "once") {
-              // keep the directive in, commented out
-              CommentOutDirective(RawLex, HashToken, FromFile, EOL,
-                NextToWrite, Line);
-              WriteLineInfo(FileName, Line, FileType, EOL);
-            }
-            break;
-          }
-          case tok::pp_if:
-          case tok::pp_elif: {
-            bool elif = (RawToken.getIdentifierInfo()->getPPKeywordID() ==
-                         tok::pp_elif);
-            // Rewrite special builtin macros to avoid pulling in host details.
-            do {
-              // Walk over the directive.
-              RawLex.LexFromRawLexer(RawToken);
-              if (RawToken.is(tok::raw_identifier))
-                PP.LookUpIdentifierInfo(RawToken);
-
-              if (RawToken.is(tok::identifier)) {
-                bool HasFile;
-                SourceLocation Loc = RawToken.getLocation();
-
-                // Rewrite __has_include(x)
-                if (RawToken.getIdentifierInfo()->isStr("__has_include")) {
-                  if (!HandleHasInclude(FileId, RawLex, 0, RawToken, HasFile))
-                    continue;
-                  // Rewrite __has_include_next(x)
-                } else if (RawToken.getIdentifierInfo()->isStr(
-                               "__has_include_next")) {
-                  const DirectoryLookup *Lookup = PP.GetCurDirLookup();
-                  if (Lookup)
-                    ++Lookup;
-
-                  if (!HandleHasInclude(FileId, RawLex, Lookup, RawToken,
-                                        HasFile))
-                    continue;
-                } else {
-                  continue;
-                }
-                // Replace the macro with (0) or (1), followed by the commented
-                // out macro for reference.
-                OutputContentUpTo(FromFile, NextToWrite, SM.getFileOffset(Loc),
-                                  EOL, Line);
-                OS << '(' << (int) HasFile << ")/*";
-                OutputContentUpTo(FromFile, NextToWrite,
-                                  SM.getFileOffset(RawToken.getLocation()) +
-                                  RawToken.getLength(),
-                                  EOL, Line);
-                OS << "*/";
-              }
-            } while (RawToken.isNot(tok::eod));
-            if (elif) {
-              OutputContentUpTo(FromFile, NextToWrite,
-                                SM.getFileOffset(RawToken.getLocation()) +
-                                    RawToken.getLength(),
-                                EOL, Line, /*EnsureNewLine*/ true);
-              WriteLineInfo(FileName, Line, FileType, EOL);
-            }
-            break;
-          }
-          case tok::pp_endif:
-          case tok::pp_else: {
-            // We surround every #include by #if 0 to comment it out, but that
-            // changes line numbers. These are fixed up right after that, but
-            // the whole #include could be inside a preprocessor conditional
-            // that is not processed. So it is necessary to fix the line
-            // numbers one the next line after each #else/#endif as well.
-            RawLex.SetKeepWhitespaceMode(true);
-            do {
-              RawLex.LexFromRawLexer(RawToken);
-            } while (RawToken.isNot(tok::eod) && RawToken.isNot(tok::eof));
-            OutputContentUpTo(
-                FromFile, NextToWrite,
-                SM.getFileOffset(RawToken.getLocation()) + RawToken.getLength(),
-                EOL, Line, /*EnsureNewLine*/ true);
-            WriteLineInfo(FileName, Line, FileType, EOL);
-            RawLex.SetKeepWhitespaceMode(false);
-          }
-          default:
-            break;
-        }
-      }
-      RawLex.setParsingPreprocessorDirective(false);
-    }
-    RawLex.LexFromRawLexer(RawToken);
-  }
-  OutputContentUpTo(FromFile, NextToWrite,
-    SM.getFileOffset(SM.getLocForEndOfFile(FileId)), EOL, Line,
-    /*EnsureNewline*/true);
-  return true;
-}
-
-/// InclusionRewriterInInput - Implement -frewrite-includes mode.
-void clang::RewriteIncludesInInput(Preprocessor &PP, raw_ostream *OS,
-                                   const PreprocessorOutputOptions &Opts) {
-  SourceManager &SM = PP.getSourceManager();
-  InclusionRewriter *Rewrite = new InclusionRewriter(PP, *OS,
-                                                     Opts.ShowLineMarkers);
-  PP.addPPCallbacks(Rewrite);
-  // Ignore all pragmas, otherwise there will be warnings about unknown pragmas
-  // (because there's nothing to handle them).
-  PP.AddPragmaHandler(new EmptyPragmaHandler());
-  // Ignore also all pragma in all namespaces created
-  // in Preprocessor::RegisterBuiltinPragmas().
-  PP.AddPragmaHandler("GCC", new EmptyPragmaHandler());
-  PP.AddPragmaHandler("clang", new EmptyPragmaHandler());
-
-  // First let the preprocessor process the entire file and call callbacks.
-  // Callbacks will record which #include's were actually performed.
-  PP.EnterMainSourceFile();
-  Token Tok;
-  // Only preprocessor directives matter here, so disable macro expansion
-  // everywhere else as an optimization.
-  // TODO: It would be even faster if the preprocessor could be switched
-  // to a mode where it would parse only preprocessor directives and comments,
-  // nothing else matters for parsing or processing.
-  PP.SetMacroExpansionOnlyInDirectives();
-  do {
-    PP.Lex(Tok);
-  } while (Tok.isNot(tok::eof));
-  Rewrite->setPredefinesBuffer(SM.getBuffer(PP.getPredefinesFileID()));
-  Rewrite->Process(PP.getPredefinesFileID(), SrcMgr::C_User);
-  Rewrite->Process(SM.getMainFileID(), SrcMgr::C_User);
-  OS->flush();
-}
diff --git a/lib/Rewrite/Frontend/Makefile b/lib/Rewrite/Frontend/Makefile
deleted file mode 100644
index ac97d40..0000000
--- a/lib/Rewrite/Frontend/Makefile
+++ /dev/null
@@ -1,18 +0,0 @@
-##===- clang/lib/Rewrite/Makefile --------------------------*- Makefile -*-===##
-# 
-#                     The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-# 
-##===----------------------------------------------------------------------===##
-#
-# This implements code transformation / rewriting facilities.
-#
-##===----------------------------------------------------------------------===##
-
-CLANG_LEVEL := ../../..
-LIBRARYNAME := clangRewriteFrontend
-
-include $(CLANG_LEVEL)/Makefile
-
diff --git a/lib/Rewrite/Frontend/RewriteMacros.cpp b/lib/Rewrite/Frontend/RewriteMacros.cpp
deleted file mode 100644
index 4f6a93f..0000000
--- a/lib/Rewrite/Frontend/RewriteMacros.cpp
+++ /dev/null
@@ -1,217 +0,0 @@
-//===--- RewriteMacros.cpp - Rewrite macros into their expansions ---------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This code rewrites macro invocations into their expansions.  This gives you
-// a macro expanded file that retains comments and #includes.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Rewrite/Frontend/Rewriters.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Rewrite/Core/Rewriter.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/raw_ostream.h"
-#include <cstdio>
-
-using namespace clang;
-
-/// isSameToken - Return true if the two specified tokens start have the same
-/// content.
-static bool isSameToken(Token &RawTok, Token &PPTok) {
-  // If two tokens have the same kind and the same identifier info, they are
-  // obviously the same.
-  if (PPTok.getKind() == RawTok.getKind() &&
-      PPTok.getIdentifierInfo() == RawTok.getIdentifierInfo())
-    return true;
-
-  // Otherwise, if they are different but have the same identifier info, they
-  // are also considered to be the same.  This allows keywords and raw lexed
-  // identifiers with the same name to be treated the same.
-  if (PPTok.getIdentifierInfo() &&
-      PPTok.getIdentifierInfo() == RawTok.getIdentifierInfo())
-    return true;
-
-  return false;
-}
-
-
-/// GetNextRawTok - Return the next raw token in the stream, skipping over
-/// comments if ReturnComment is false.
-static const Token &GetNextRawTok(const std::vector<Token> &RawTokens,
-                                  unsigned &CurTok, bool ReturnComment) {
-  assert(CurTok < RawTokens.size() && "Overran eof!");
-
-  // If the client doesn't want comments and we have one, skip it.
-  if (!ReturnComment && RawTokens[CurTok].is(tok::comment))
-    ++CurTok;
-
-  return RawTokens[CurTok++];
-}
-
-
-/// LexRawTokensFromMainFile - Lets all the raw tokens from the main file into
-/// the specified vector.
-static void LexRawTokensFromMainFile(Preprocessor &PP,
-                                     std::vector<Token> &RawTokens) {
-  SourceManager &SM = PP.getSourceManager();
-
-  // Create a lexer to lex all the tokens of the main file in raw mode.  Even
-  // though it is in raw mode, it will not return comments.
-  const llvm::MemoryBuffer *FromFile = SM.getBuffer(SM.getMainFileID());
-  Lexer RawLex(SM.getMainFileID(), FromFile, SM, PP.getLangOpts());
-
-  // Switch on comment lexing because we really do want them.
-  RawLex.SetCommentRetentionState(true);
-
-  Token RawTok;
-  do {
-    RawLex.LexFromRawLexer(RawTok);
-
-    // If we have an identifier with no identifier info for our raw token, look
-    // up the indentifier info.  This is important for equality comparison of
-    // identifier tokens.
-    if (RawTok.is(tok::raw_identifier))
-      PP.LookUpIdentifierInfo(RawTok);
-
-    RawTokens.push_back(RawTok);
-  } while (RawTok.isNot(tok::eof));
-}
-
-
-/// RewriteMacrosInInput - Implement -rewrite-macros mode.
-void clang::RewriteMacrosInInput(Preprocessor &PP, raw_ostream *OS) {
-  SourceManager &SM = PP.getSourceManager();
-
-  Rewriter Rewrite;
-  Rewrite.setSourceMgr(SM, PP.getLangOpts());
-  RewriteBuffer &RB = Rewrite.getEditBuffer(SM.getMainFileID());
-
-  std::vector<Token> RawTokens;
-  LexRawTokensFromMainFile(PP, RawTokens);
-  unsigned CurRawTok = 0;
-  Token RawTok = GetNextRawTok(RawTokens, CurRawTok, false);
-
-
-  // Get the first preprocessing token.
-  PP.EnterMainSourceFile();
-  Token PPTok;
-  PP.Lex(PPTok);
-
-  // Preprocess the input file in parallel with raw lexing the main file. Ignore
-  // all tokens that are preprocessed from a file other than the main file (e.g.
-  // a header).  If we see tokens that are in the preprocessed file but not the
-  // lexed file, we have a macro expansion.  If we see tokens in the lexed file
-  // that aren't in the preprocessed view, we have macros that expand to no
-  // tokens, or macro arguments etc.
-  while (RawTok.isNot(tok::eof) || PPTok.isNot(tok::eof)) {
-    SourceLocation PPLoc = SM.getExpansionLoc(PPTok.getLocation());
-
-    // If PPTok is from a different source file, ignore it.
-    if (!SM.isWrittenInMainFile(PPLoc)) {
-      PP.Lex(PPTok);
-      continue;
-    }
-
-    // If the raw file hits a preprocessor directive, they will be extra tokens
-    // in the raw file that don't exist in the preprocsesed file.  However, we
-    // choose to preserve them in the output file and otherwise handle them
-    // specially.
-    if (RawTok.is(tok::hash) && RawTok.isAtStartOfLine()) {
-      // If this is a #warning directive or #pragma mark (GNU extensions),
-      // comment the line out.
-      if (RawTokens[CurRawTok].is(tok::identifier)) {
-        const IdentifierInfo *II = RawTokens[CurRawTok].getIdentifierInfo();
-        if (II->getName() == "warning") {
-          // Comment out #warning.
-          RB.InsertTextAfter(SM.getFileOffset(RawTok.getLocation()), "//");
-        } else if (II->getName() == "pragma" &&
-                   RawTokens[CurRawTok+1].is(tok::identifier) &&
-                   (RawTokens[CurRawTok+1].getIdentifierInfo()->getName() ==
-                    "mark")) {
-          // Comment out #pragma mark.
-          RB.InsertTextAfter(SM.getFileOffset(RawTok.getLocation()), "//");
-        }
-      }
-
-      // Otherwise, if this is a #include or some other directive, just leave it
-      // in the file by skipping over the line.
-      RawTok = GetNextRawTok(RawTokens, CurRawTok, false);
-      while (!RawTok.isAtStartOfLine() && RawTok.isNot(tok::eof))
-        RawTok = GetNextRawTok(RawTokens, CurRawTok, false);
-      continue;
-    }
-
-    // Okay, both tokens are from the same file.  Get their offsets from the
-    // start of the file.
-    unsigned PPOffs = SM.getFileOffset(PPLoc);
-    unsigned RawOffs = SM.getFileOffset(RawTok.getLocation());
-
-    // If the offsets are the same and the token kind is the same, ignore them.
-    if (PPOffs == RawOffs && isSameToken(RawTok, PPTok)) {
-      RawTok = GetNextRawTok(RawTokens, CurRawTok, false);
-      PP.Lex(PPTok);
-      continue;
-    }
-
-    // If the PP token is farther along than the raw token, something was
-    // deleted.  Comment out the raw token.
-    if (RawOffs <= PPOffs) {
-      // Comment out a whole run of tokens instead of bracketing each one with
-      // comments.  Add a leading space if RawTok didn't have one.
-      bool HasSpace = RawTok.hasLeadingSpace();
-      RB.InsertTextAfter(RawOffs, &" /*"[HasSpace]);
-      unsigned EndPos;
-
-      do {
-        EndPos = RawOffs+RawTok.getLength();
-
-        RawTok = GetNextRawTok(RawTokens, CurRawTok, true);
-        RawOffs = SM.getFileOffset(RawTok.getLocation());
-
-        if (RawTok.is(tok::comment)) {
-          // Skip past the comment.
-          RawTok = GetNextRawTok(RawTokens, CurRawTok, false);
-          break;
-        }
-
-      } while (RawOffs <= PPOffs && !RawTok.isAtStartOfLine() &&
-               (PPOffs != RawOffs || !isSameToken(RawTok, PPTok)));
-
-      RB.InsertTextBefore(EndPos, "*/");
-      continue;
-    }
-
-    // Otherwise, there was a replacement an expansion.  Insert the new token
-    // in the output buffer.  Insert the whole run of new tokens at once to get
-    // them in the right order.
-    unsigned InsertPos = PPOffs;
-    std::string Expansion;
-    while (PPOffs < RawOffs) {
-      Expansion += ' ' + PP.getSpelling(PPTok);
-      PP.Lex(PPTok);
-      PPLoc = SM.getExpansionLoc(PPTok.getLocation());
-      PPOffs = SM.getFileOffset(PPLoc);
-    }
-    Expansion += ' ';
-    RB.InsertTextBefore(InsertPos, Expansion);
-  }
-
-  // Get the buffer corresponding to MainFileID.  If we haven't changed it, then
-  // we are done.
-  if (const RewriteBuffer *RewriteBuf =
-      Rewrite.getRewriteBufferFor(SM.getMainFileID())) {
-    //printf("Changed:\n");
-    *OS << std::string(RewriteBuf->begin(), RewriteBuf->end());
-  } else {
-    fprintf(stderr, "No changes\n");
-  }
-  OS->flush();
-}
diff --git a/lib/Rewrite/Frontend/RewriteModernObjC.cpp b/lib/Rewrite/Frontend/RewriteModernObjC.cpp
deleted file mode 100644
index ae33ac8..0000000
--- a/lib/Rewrite/Frontend/RewriteModernObjC.cpp
+++ /dev/null
@@ -1,7871 +0,0 @@
-//===--- RewriteObjC.cpp - Playground for the code rewriter ---------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Hacks and fun related to the code rewriter.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Rewrite/Frontend/ASTConsumers.h"
-#include "clang/AST/AST.h"
-#include "clang/AST/ASTConsumer.h"
-#include "clang/AST/Attr.h"
-#include "clang/AST/ParentMap.h"
-#include "clang/Basic/CharInfo.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/TargetInfo.h"
-#include "clang/Lex/Lexer.h"
-#include "clang/Rewrite/Core/Rewriter.h"
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace clang;
-using llvm::utostr;
-
-namespace {
-  class RewriteModernObjC : public ASTConsumer {
-  protected:
-    
-    enum {
-      BLOCK_FIELD_IS_OBJECT   =  3,  /* id, NSObject, __attribute__((NSObject)),
-                                        block, ... */
-      BLOCK_FIELD_IS_BLOCK    =  7,  /* a block variable */
-      BLOCK_FIELD_IS_BYREF    =  8,  /* the on stack structure holding the 
-                                        __block variable */
-      BLOCK_FIELD_IS_WEAK     = 16,  /* declared __weak, only used in byref copy
-                                        helpers */
-      BLOCK_BYREF_CALLER      = 128, /* called from __block (byref) copy/dispose
-                                        support routines */
-      BLOCK_BYREF_CURRENT_MAX = 256
-    };
-    
-    enum {
-      BLOCK_NEEDS_FREE =        (1 << 24),
-      BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
-      BLOCK_HAS_CXX_OBJ =       (1 << 26),
-      BLOCK_IS_GC =             (1 << 27),
-      BLOCK_IS_GLOBAL =         (1 << 28),
-      BLOCK_HAS_DESCRIPTOR =    (1 << 29)
-    };
-    
-    Rewriter Rewrite;
-    DiagnosticsEngine &Diags;
-    const LangOptions &LangOpts;
-    ASTContext *Context;
-    SourceManager *SM;
-    TranslationUnitDecl *TUDecl;
-    FileID MainFileID;
-    const char *MainFileStart, *MainFileEnd;
-    Stmt *CurrentBody;
-    ParentMap *PropParentMap; // created lazily.
-    std::string InFileName;
-    raw_ostream* OutFile;
-    std::string Preamble;
-    
-    TypeDecl *ProtocolTypeDecl;
-    VarDecl *GlobalVarDecl;
-    Expr *GlobalConstructionExp;
-    unsigned RewriteFailedDiag;
-    unsigned GlobalBlockRewriteFailedDiag;
-    // ObjC string constant support.
-    unsigned NumObjCStringLiterals;
-    VarDecl *ConstantStringClassReference;
-    RecordDecl *NSStringRecord;
-
-    // ObjC foreach break/continue generation support.
-    int BcLabelCount;
-    
-    unsigned TryFinallyContainsReturnDiag;
-    // Needed for super.
-    ObjCMethodDecl *CurMethodDef;
-    RecordDecl *SuperStructDecl;
-    RecordDecl *ConstantStringDecl;
-    
-    FunctionDecl *MsgSendFunctionDecl;
-    FunctionDecl *MsgSendSuperFunctionDecl;
-    FunctionDecl *MsgSendStretFunctionDecl;
-    FunctionDecl *MsgSendSuperStretFunctionDecl;
-    FunctionDecl *MsgSendFpretFunctionDecl;
-    FunctionDecl *GetClassFunctionDecl;
-    FunctionDecl *GetMetaClassFunctionDecl;
-    FunctionDecl *GetSuperClassFunctionDecl;
-    FunctionDecl *SelGetUidFunctionDecl;
-    FunctionDecl *CFStringFunctionDecl;
-    FunctionDecl *SuperConstructorFunctionDecl;
-    FunctionDecl *CurFunctionDef;
-
-    /* Misc. containers needed for meta-data rewrite. */
-    SmallVector<ObjCImplementationDecl *, 8> ClassImplementation;
-    SmallVector<ObjCCategoryImplDecl *, 8> CategoryImplementation;
-    llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCSynthesizedStructs;
-    llvm::SmallPtrSet<ObjCProtocolDecl*, 8> ObjCSynthesizedProtocols;
-    llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCWrittenInterfaces;
-    llvm::SmallPtrSet<TagDecl*, 32> GlobalDefinedTags;
-    SmallVector<ObjCInterfaceDecl*, 32> ObjCInterfacesSeen;
-    /// DefinedNonLazyClasses - List of defined "non-lazy" classes.
-    SmallVector<ObjCInterfaceDecl*, 8> DefinedNonLazyClasses;
-    
-    /// DefinedNonLazyCategories - List of defined "non-lazy" categories.
-    SmallVector<ObjCCategoryDecl *, 8> DefinedNonLazyCategories;
-    
-    SmallVector<Stmt *, 32> Stmts;
-    SmallVector<int, 8> ObjCBcLabelNo;
-    // Remember all the @protocol(<expr>) expressions.
-    llvm::SmallPtrSet<ObjCProtocolDecl *, 32> ProtocolExprDecls;
-    
-    llvm::DenseSet<uint64_t> CopyDestroyCache;
-
-    // Block expressions.
-    SmallVector<BlockExpr *, 32> Blocks;
-    SmallVector<int, 32> InnerDeclRefsCount;
-    SmallVector<DeclRefExpr *, 32> InnerDeclRefs;
-    
-    SmallVector<DeclRefExpr *, 32> BlockDeclRefs;
-
-    
-    // Block related declarations.
-    SmallVector<ValueDecl *, 8> BlockByCopyDecls;
-    llvm::SmallPtrSet<ValueDecl *, 8> BlockByCopyDeclsPtrSet;
-    SmallVector<ValueDecl *, 8> BlockByRefDecls;
-    llvm::SmallPtrSet<ValueDecl *, 8> BlockByRefDeclsPtrSet;
-    llvm::DenseMap<ValueDecl *, unsigned> BlockByRefDeclNo;
-    llvm::SmallPtrSet<ValueDecl *, 8> ImportedBlockDecls;
-    llvm::SmallPtrSet<VarDecl *, 8> ImportedLocalExternalDecls;
-    
-    llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs;
-    llvm::DenseMap<ObjCInterfaceDecl *, 
-                    llvm::SmallPtrSet<ObjCIvarDecl *, 8> > ReferencedIvars;
-    
-    // ivar bitfield grouping containers
-    llvm::DenseSet<const ObjCInterfaceDecl *> ObjCInterefaceHasBitfieldGroups;
-    llvm::DenseMap<const ObjCIvarDecl* , unsigned> IvarGroupNumber;
-    // This container maps an <class, group number for ivar> tuple to the type
-    // of the struct where the bitfield belongs.
-    llvm::DenseMap<std::pair<const ObjCInterfaceDecl*, unsigned>, QualType> GroupRecordType;
-    SmallVector<FunctionDecl*, 32> FunctionDefinitionsSeen;
-    
-    // This maps an original source AST to it's rewritten form. This allows
-    // us to avoid rewriting the same node twice (which is very uncommon).
-    // This is needed to support some of the exotic property rewriting.
-    llvm::DenseMap<Stmt *, Stmt *> ReplacedNodes;
-
-    // Needed for header files being rewritten
-    bool IsHeader;
-    bool SilenceRewriteMacroWarning;
-    bool GenerateLineInfo;
-    bool objc_impl_method;
-    
-    bool DisableReplaceStmt;
-    class DisableReplaceStmtScope {
-      RewriteModernObjC &R;
-      bool SavedValue;
-    
-    public:
-      DisableReplaceStmtScope(RewriteModernObjC &R)
-        : R(R), SavedValue(R.DisableReplaceStmt) {
-        R.DisableReplaceStmt = true;
-      }
-      ~DisableReplaceStmtScope() {
-        R.DisableReplaceStmt = SavedValue;
-      }
-    };
-    void InitializeCommon(ASTContext &context);
-
-  public:
-    llvm::DenseMap<ObjCMethodDecl*, std::string> MethodInternalNames;
-    // Top Level Driver code.
-    virtual bool HandleTopLevelDecl(DeclGroupRef D) {
-      for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) {
-        if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*I)) {
-          if (!Class->isThisDeclarationADefinition()) {
-            RewriteForwardClassDecl(D);
-            break;
-          } else {
-            // Keep track of all interface declarations seen.
-            ObjCInterfacesSeen.push_back(Class);
-            break;
-          }
-        }
-
-        if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*I)) {
-          if (!Proto->isThisDeclarationADefinition()) {
-            RewriteForwardProtocolDecl(D);
-            break;
-          }
-        }
-
-        if (FunctionDecl *FDecl = dyn_cast<FunctionDecl>(*I)) {
-          // Under modern abi, we cannot translate body of the function
-          // yet until all class extensions and its implementation is seen.
-          // This is because they may introduce new bitfields which must go
-          // into their grouping struct.
-          if (FDecl->isThisDeclarationADefinition() &&
-              // Not c functions defined inside an objc container.
-              !FDecl->isTopLevelDeclInObjCContainer()) {
-            FunctionDefinitionsSeen.push_back(FDecl);
-            break;
-          }
-        }
-        HandleTopLevelSingleDecl(*I);
-      }
-      return true;
-    }
-    
-    virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) {
-      for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) {
-        if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(*I)) {
-          if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
-            RewriteBlockPointerDecl(TD);
-          else if (TD->getUnderlyingType()->isFunctionPointerType())
-            CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
-          else
-            RewriteObjCQualifiedInterfaceTypes(TD);
-        }
-      }
-      return;
-    }
-    
-    void HandleTopLevelSingleDecl(Decl *D);
-    void HandleDeclInMainFile(Decl *D);
-    RewriteModernObjC(std::string inFile, raw_ostream *OS,
-                DiagnosticsEngine &D, const LangOptions &LOpts,
-                bool silenceMacroWarn, bool LineInfo);
-    
-    ~RewriteModernObjC() {}
-    
-    virtual void HandleTranslationUnit(ASTContext &C);
-
-    void ReplaceStmt(Stmt *Old, Stmt *New) {
-      Stmt *ReplacingStmt = ReplacedNodes[Old];
-
-      if (ReplacingStmt)
-        return; // We can't rewrite the same node twice.
-
-      if (DisableReplaceStmt)
-        return;
-
-      // If replacement succeeded or warning disabled return with no warning.
-      if (!Rewrite.ReplaceStmt(Old, New)) {
-        ReplacedNodes[Old] = New;
-        return;
-      }
-      if (SilenceRewriteMacroWarning)
-        return;
-      Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag)
-                   << Old->getSourceRange();
-    }
-
-    void ReplaceStmtWithRange(Stmt *Old, Stmt *New, SourceRange SrcRange) {
-      if (DisableReplaceStmt)
-        return;
-
-      // Measure the old text.
-      int Size = Rewrite.getRangeSize(SrcRange);
-      if (Size == -1) {
-        Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag)
-                     << Old->getSourceRange();
-        return;
-      }
-      // Get the new text.
-      std::string SStr;
-      llvm::raw_string_ostream S(SStr);
-      New->printPretty(S, 0, PrintingPolicy(LangOpts));
-      const std::string &Str = S.str();
-
-      // If replacement succeeded or warning disabled return with no warning.
-      if (!Rewrite.ReplaceText(SrcRange.getBegin(), Size, Str)) {
-        ReplacedNodes[Old] = New;
-        return;
-      }
-      if (SilenceRewriteMacroWarning)
-        return;
-      Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag)
-                   << Old->getSourceRange();
-    }
-
-    void InsertText(SourceLocation Loc, StringRef Str,
-                    bool InsertAfter = true) {
-      // If insertion succeeded or warning disabled return with no warning.
-      if (!Rewrite.InsertText(Loc, Str, InsertAfter) ||
-          SilenceRewriteMacroWarning)
-        return;
-
-      Diags.Report(Context->getFullLoc(Loc), RewriteFailedDiag);
-    }
-
-    void ReplaceText(SourceLocation Start, unsigned OrigLength,
-                     StringRef Str) {
-      // If removal succeeded or warning disabled return with no warning.
-      if (!Rewrite.ReplaceText(Start, OrigLength, Str) ||
-          SilenceRewriteMacroWarning)
-        return;
-
-      Diags.Report(Context->getFullLoc(Start), RewriteFailedDiag);
-    }
-
-    // Syntactic Rewriting.
-    void RewriteRecordBody(RecordDecl *RD);
-    void RewriteInclude();
-    void RewriteLineDirective(const Decl *D);
-    void ConvertSourceLocationToLineDirective(SourceLocation Loc,
-                                              std::string &LineString);
-    void RewriteForwardClassDecl(DeclGroupRef D);
-    void RewriteForwardClassDecl(const SmallVectorImpl<Decl *> &DG);
-    void RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl, 
-                                     const std::string &typedefString);
-    void RewriteImplementations();
-    void RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
-                                 ObjCImplementationDecl *IMD,
-                                 ObjCCategoryImplDecl *CID);
-    void RewriteInterfaceDecl(ObjCInterfaceDecl *Dcl);
-    void RewriteImplementationDecl(Decl *Dcl);
-    void RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl,
-                               ObjCMethodDecl *MDecl, std::string &ResultStr);
-    void RewriteTypeIntoString(QualType T, std::string &ResultStr,
-                               const FunctionType *&FPRetType);
-    void RewriteByRefString(std::string &ResultStr, const std::string &Name,
-                            ValueDecl *VD, bool def=false);
-    void RewriteCategoryDecl(ObjCCategoryDecl *Dcl);
-    void RewriteProtocolDecl(ObjCProtocolDecl *Dcl);
-    void RewriteForwardProtocolDecl(DeclGroupRef D);
-    void RewriteForwardProtocolDecl(const SmallVectorImpl<Decl *> &DG);
-    void RewriteMethodDeclaration(ObjCMethodDecl *Method);
-    void RewriteProperty(ObjCPropertyDecl *prop);
-    void RewriteFunctionDecl(FunctionDecl *FD);
-    void RewriteBlockPointerType(std::string& Str, QualType Type);
-    void RewriteBlockPointerTypeVariable(std::string& Str, ValueDecl *VD);
-    void RewriteBlockLiteralFunctionDecl(FunctionDecl *FD);
-    void RewriteObjCQualifiedInterfaceTypes(Decl *Dcl);
-    void RewriteTypeOfDecl(VarDecl *VD);
-    void RewriteObjCQualifiedInterfaceTypes(Expr *E);
-    
-    std::string getIvarAccessString(ObjCIvarDecl *D);
-  
-    // Expression Rewriting.
-    Stmt *RewriteFunctionBodyOrGlobalInitializer(Stmt *S);
-    Stmt *RewriteAtEncode(ObjCEncodeExpr *Exp);
-    Stmt *RewritePropertyOrImplicitGetter(PseudoObjectExpr *Pseudo);
-    Stmt *RewritePropertyOrImplicitSetter(PseudoObjectExpr *Pseudo);
-    Stmt *RewriteAtSelector(ObjCSelectorExpr *Exp);
-    Stmt *RewriteMessageExpr(ObjCMessageExpr *Exp);
-    Stmt *RewriteObjCStringLiteral(ObjCStringLiteral *Exp);
-    Stmt *RewriteObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Exp);
-    Stmt *RewriteObjCBoxedExpr(ObjCBoxedExpr *Exp);
-    Stmt *RewriteObjCArrayLiteralExpr(ObjCArrayLiteral *Exp);
-    Stmt *RewriteObjCDictionaryLiteralExpr(ObjCDictionaryLiteral *Exp);
-    Stmt *RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp);
-    Stmt *RewriteObjCTryStmt(ObjCAtTryStmt *S);
-    Stmt *RewriteObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt  *S);
-    Stmt *RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S);
-    Stmt *RewriteObjCThrowStmt(ObjCAtThrowStmt *S);
-    Stmt *RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
-                                       SourceLocation OrigEnd);
-    Stmt *RewriteBreakStmt(BreakStmt *S);
-    Stmt *RewriteContinueStmt(ContinueStmt *S);
-    void RewriteCastExpr(CStyleCastExpr *CE);
-    void RewriteImplicitCastObjCExpr(CastExpr *IE);
-    void RewriteLinkageSpec(LinkageSpecDecl *LSD);
-    
-    // Computes ivar bitfield group no.
-    unsigned ObjCIvarBitfieldGroupNo(ObjCIvarDecl *IV);
-    // Names field decl. for ivar bitfield group.
-    void ObjCIvarBitfieldGroupDecl(ObjCIvarDecl *IV, std::string &Result);
-    // Names struct type for ivar bitfield group.
-    void ObjCIvarBitfieldGroupType(ObjCIvarDecl *IV, std::string &Result);
-    // Names symbol for ivar bitfield group field offset.
-    void ObjCIvarBitfieldGroupOffset(ObjCIvarDecl *IV, std::string &Result);
-    // Given an ivar bitfield, it builds (or finds) its group record type.
-    QualType GetGroupRecordTypeForObjCIvarBitfield(ObjCIvarDecl *IV);
-    QualType SynthesizeBitfieldGroupStructType(
-                                    ObjCIvarDecl *IV,
-                                    SmallVectorImpl<ObjCIvarDecl *> &IVars);
-    
-    // Block rewriting.
-    void RewriteBlocksInFunctionProtoType(QualType funcType, NamedDecl *D);
-    
-    // Block specific rewrite rules.
-    void RewriteBlockPointerDecl(NamedDecl *VD);
-    void RewriteByRefVar(VarDecl *VD, bool firstDecl, bool lastDecl);
-    Stmt *RewriteBlockDeclRefExpr(DeclRefExpr *VD);
-    Stmt *RewriteLocalVariableExternalStorage(DeclRefExpr *DRE);
-    void RewriteBlockPointerFunctionArgs(FunctionDecl *FD);
-    
-    void RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl,
-                                      std::string &Result);
-    
-    void RewriteObjCFieldDecl(FieldDecl *fieldDecl, std::string &Result);
-    bool IsTagDefinedInsideClass(ObjCContainerDecl *IDecl, TagDecl *Tag,
-                                 bool &IsNamedDefinition);
-    void RewriteLocallyDefinedNamedAggregates(FieldDecl *fieldDecl, 
-                                              std::string &Result);
-    
-    bool RewriteObjCFieldDeclType(QualType &Type, std::string &Result);
-    
-    void RewriteIvarOffsetSymbols(ObjCInterfaceDecl *CDecl,
-                                  std::string &Result);
-    
-    virtual void Initialize(ASTContext &context);
-    
-    // Misc. AST transformation routines. Sometimes they end up calling
-    // rewriting routines on the new ASTs.
-    CallExpr *SynthesizeCallToFunctionDecl(FunctionDecl *FD,
-                                           Expr **args, unsigned nargs,
-                                           SourceLocation StartLoc=SourceLocation(),
-                                           SourceLocation EndLoc=SourceLocation());
-    
-    Expr *SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFlavor,
-                                        QualType returnType, 
-                                        SmallVectorImpl<QualType> &ArgTypes,
-                                        SmallVectorImpl<Expr*> &MsgExprs,
-                                        ObjCMethodDecl *Method);
-
-    Stmt *SynthMessageExpr(ObjCMessageExpr *Exp,
-                           SourceLocation StartLoc=SourceLocation(),
-                           SourceLocation EndLoc=SourceLocation());
-    
-    void SynthCountByEnumWithState(std::string &buf);
-    void SynthMsgSendFunctionDecl();
-    void SynthMsgSendSuperFunctionDecl();
-    void SynthMsgSendStretFunctionDecl();
-    void SynthMsgSendFpretFunctionDecl();
-    void SynthMsgSendSuperStretFunctionDecl();
-    void SynthGetClassFunctionDecl();
-    void SynthGetMetaClassFunctionDecl();
-    void SynthGetSuperClassFunctionDecl();
-    void SynthSelGetUidFunctionDecl();
-    void SynthSuperConstructorFunctionDecl();
-    
-    // Rewriting metadata
-    template<typename MethodIterator>
-    void RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
-                                    MethodIterator MethodEnd,
-                                    bool IsInstanceMethod,
-                                    StringRef prefix,
-                                    StringRef ClassName,
-                                    std::string &Result);
-    void RewriteObjCProtocolMetaData(ObjCProtocolDecl *Protocol,
-                                     std::string &Result);
-    void RewriteObjCProtocolListMetaData(
-                   const ObjCList<ObjCProtocolDecl> &Prots,
-                   StringRef prefix, StringRef ClassName, std::string &Result);
-    void RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
-                                          std::string &Result);
-    void RewriteClassSetupInitHook(std::string &Result);
-    
-    void RewriteMetaDataIntoBuffer(std::string &Result);
-    void WriteImageInfo(std::string &Result);
-    void RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *CDecl,
-                                             std::string &Result);
-    void RewriteCategorySetupInitHook(std::string &Result);
-    
-    // Rewriting ivar
-    void RewriteIvarOffsetComputation(ObjCIvarDecl *ivar,
-                                              std::string &Result);
-    Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV);
-
-    
-    std::string SynthesizeByrefCopyDestroyHelper(VarDecl *VD, int flag);
-    std::string SynthesizeBlockHelperFuncs(BlockExpr *CE, int i,
-                                      StringRef funcName, std::string Tag);
-    std::string SynthesizeBlockFunc(BlockExpr *CE, int i,
-                                      StringRef funcName, std::string Tag);
-    std::string SynthesizeBlockImpl(BlockExpr *CE, 
-                                    std::string Tag, std::string Desc);
-    std::string SynthesizeBlockDescriptor(std::string DescTag, 
-                                          std::string ImplTag,
-                                          int i, StringRef funcName,
-                                          unsigned hasCopy);
-    Stmt *SynthesizeBlockCall(CallExpr *Exp, const Expr* BlockExp);
-    void SynthesizeBlockLiterals(SourceLocation FunLocStart,
-                                 StringRef FunName);
-    FunctionDecl *SynthBlockInitFunctionDecl(StringRef name);
-    Stmt *SynthBlockInitExpr(BlockExpr *Exp,
-                      const SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs);
-
-    // Misc. helper routines.
-    QualType getProtocolType();
-    void WarnAboutReturnGotoStmts(Stmt *S);
-    void CheckFunctionPointerDecl(QualType dType, NamedDecl *ND);
-    void InsertBlockLiteralsWithinFunction(FunctionDecl *FD);
-    void InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD);
-
-    bool IsDeclStmtInForeachHeader(DeclStmt *DS);
-    void CollectBlockDeclRefInfo(BlockExpr *Exp);
-    void GetBlockDeclRefExprs(Stmt *S);
-    void GetInnerBlockDeclRefExprs(Stmt *S,
-                SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs,
-                llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts);
-
-    // We avoid calling Type::isBlockPointerType(), since it operates on the
-    // canonical type. We only care if the top-level type is a closure pointer.
-    bool isTopLevelBlockPointerType(QualType T) {
-      return isa<BlockPointerType>(T);
-    }
-
-    /// convertBlockPointerToFunctionPointer - Converts a block-pointer type
-    /// to a function pointer type and upon success, returns true; false
-    /// otherwise.
-    bool convertBlockPointerToFunctionPointer(QualType &T) {
-      if (isTopLevelBlockPointerType(T)) {
-        const BlockPointerType *BPT = T->getAs<BlockPointerType>();
-        T = Context->getPointerType(BPT->getPointeeType());
-        return true;
-      }
-      return false;
-    }
-    
-    bool convertObjCTypeToCStyleType(QualType &T);
-    
-    bool needToScanForQualifiers(QualType T);
-    QualType getSuperStructType();
-    QualType getConstantStringStructType();
-    QualType convertFunctionTypeOfBlocks(const FunctionType *FT);
-    bool BufferContainsPPDirectives(const char *startBuf, const char *endBuf);
-    
-    void convertToUnqualifiedObjCType(QualType &T) {
-      if (T->isObjCQualifiedIdType()) {
-        bool isConst = T.isConstQualified();
-        T = isConst ? Context->getObjCIdType().withConst() 
-                    : Context->getObjCIdType();
-      }
-      else if (T->isObjCQualifiedClassType())
-        T = Context->getObjCClassType();
-      else if (T->isObjCObjectPointerType() &&
-               T->getPointeeType()->isObjCQualifiedInterfaceType()) {
-        if (const ObjCObjectPointerType * OBJPT =
-              T->getAsObjCInterfacePointerType()) {
-          const ObjCInterfaceType *IFaceT = OBJPT->getInterfaceType();
-          T = QualType(IFaceT, 0);
-          T = Context->getPointerType(T);
-        }
-     }
-    }
-    
-    // FIXME: This predicate seems like it would be useful to add to ASTContext.
-    bool isObjCType(QualType T) {
-      if (!LangOpts.ObjC1 && !LangOpts.ObjC2)
-        return false;
-
-      QualType OCT = Context->getCanonicalType(T).getUnqualifiedType();
-
-      if (OCT == Context->getCanonicalType(Context->getObjCIdType()) ||
-          OCT == Context->getCanonicalType(Context->getObjCClassType()))
-        return true;
-
-      if (const PointerType *PT = OCT->getAs<PointerType>()) {
-        if (isa<ObjCInterfaceType>(PT->getPointeeType()) ||
-            PT->getPointeeType()->isObjCQualifiedIdType())
-          return true;
-      }
-      return false;
-    }
-    bool PointerTypeTakesAnyBlockArguments(QualType QT);
-    bool PointerTypeTakesAnyObjCQualifiedType(QualType QT);
-    void GetExtentOfArgList(const char *Name, const char *&LParen,
-                            const char *&RParen);
-    
-    void QuoteDoublequotes(std::string &From, std::string &To) {
-      for (unsigned i = 0; i < From.length(); i++) {
-        if (From[i] == '"')
-          To += "\\\"";
-        else
-          To += From[i];
-      }
-    }
-
-    QualType getSimpleFunctionType(QualType result,
-                                   ArrayRef<QualType> args,
-                                   bool variadic = false) {
-      if (result == Context->getObjCInstanceType())
-        result =  Context->getObjCIdType();
-      FunctionProtoType::ExtProtoInfo fpi;
-      fpi.Variadic = variadic;
-      return Context->getFunctionType(result, args, fpi);
-    }
-
-    // Helper function: create a CStyleCastExpr with trivial type source info.
-    CStyleCastExpr* NoTypeInfoCStyleCastExpr(ASTContext *Ctx, QualType Ty,
-                                             CastKind Kind, Expr *E) {
-      TypeSourceInfo *TInfo = Ctx->getTrivialTypeSourceInfo(Ty, SourceLocation());
-      return CStyleCastExpr::Create(*Ctx, Ty, VK_RValue, Kind, E, 0, TInfo,
-                                    SourceLocation(), SourceLocation());
-    }
-    
-    bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const {
-      IdentifierInfo* II = &Context->Idents.get("load");
-      Selector LoadSel = Context->Selectors.getSelector(0, &II);
-      return OD->getClassMethod(LoadSel) != 0;
-    }
-  };
-  
-}
-
-void RewriteModernObjC::RewriteBlocksInFunctionProtoType(QualType funcType,
-                                                   NamedDecl *D) {
-  if (const FunctionProtoType *fproto
-      = dyn_cast<FunctionProtoType>(funcType.IgnoreParens())) {
-    for (FunctionProtoType::arg_type_iterator I = fproto->arg_type_begin(),
-         E = fproto->arg_type_end(); I && (I != E); ++I)
-      if (isTopLevelBlockPointerType(*I)) {
-        // All the args are checked/rewritten. Don't call twice!
-        RewriteBlockPointerDecl(D);
-        break;
-      }
-  }
-}
-
-void RewriteModernObjC::CheckFunctionPointerDecl(QualType funcType, NamedDecl *ND) {
-  const PointerType *PT = funcType->getAs<PointerType>();
-  if (PT && PointerTypeTakesAnyBlockArguments(funcType))
-    RewriteBlocksInFunctionProtoType(PT->getPointeeType(), ND);
-}
-
-static bool IsHeaderFile(const std::string &Filename) {
-  std::string::size_type DotPos = Filename.rfind('.');
-
-  if (DotPos == std::string::npos) {
-    // no file extension
-    return false;
-  }
-
-  std::string Ext = std::string(Filename.begin()+DotPos+1, Filename.end());
-  // C header: .h
-  // C++ header: .hh or .H;
-  return Ext == "h" || Ext == "hh" || Ext == "H";
-}
-
-RewriteModernObjC::RewriteModernObjC(std::string inFile, raw_ostream* OS,
-                         DiagnosticsEngine &D, const LangOptions &LOpts,
-                         bool silenceMacroWarn,
-                         bool LineInfo)
-      : Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(OS),
-        SilenceRewriteMacroWarning(silenceMacroWarn), GenerateLineInfo(LineInfo) {
-  IsHeader = IsHeaderFile(inFile);
-  RewriteFailedDiag = Diags.getCustomDiagID(DiagnosticsEngine::Warning,
-               "rewriting sub-expression within a macro (may not be correct)");
-  // FIXME. This should be an error. But if block is not called, it is OK. And it
-  // may break including some headers.
-  GlobalBlockRewriteFailedDiag = Diags.getCustomDiagID(DiagnosticsEngine::Warning,
-    "rewriting block literal declared in global scope is not implemented");
-          
-  TryFinallyContainsReturnDiag = Diags.getCustomDiagID(
-               DiagnosticsEngine::Warning,
-               "rewriter doesn't support user-specified control flow semantics "
-               "for @try/@finally (code may not execute properly)");
-}
-
-ASTConsumer *clang::CreateModernObjCRewriter(const std::string& InFile,
-                                       raw_ostream* OS,
-                                       DiagnosticsEngine &Diags,
-                                       const LangOptions &LOpts,
-                                       bool SilenceRewriteMacroWarning,
-                                       bool LineInfo) {
-    return new RewriteModernObjC(InFile, OS, Diags, LOpts,
-                                 SilenceRewriteMacroWarning, LineInfo);
-}
-
-void RewriteModernObjC::InitializeCommon(ASTContext &context) {
-  Context = &context;
-  SM = &Context->getSourceManager();
-  TUDecl = Context->getTranslationUnitDecl();
-  MsgSendFunctionDecl = 0;
-  MsgSendSuperFunctionDecl = 0;
-  MsgSendStretFunctionDecl = 0;
-  MsgSendSuperStretFunctionDecl = 0;
-  MsgSendFpretFunctionDecl = 0;
-  GetClassFunctionDecl = 0;
-  GetMetaClassFunctionDecl = 0;
-  GetSuperClassFunctionDecl = 0;
-  SelGetUidFunctionDecl = 0;
-  CFStringFunctionDecl = 0;
-  ConstantStringClassReference = 0;
-  NSStringRecord = 0;
-  CurMethodDef = 0;
-  CurFunctionDef = 0;
-  GlobalVarDecl = 0;
-  GlobalConstructionExp = 0;
-  SuperStructDecl = 0;
-  ProtocolTypeDecl = 0;
-  ConstantStringDecl = 0;
-  BcLabelCount = 0;
-  SuperConstructorFunctionDecl = 0;
-  NumObjCStringLiterals = 0;
-  PropParentMap = 0;
-  CurrentBody = 0;
-  DisableReplaceStmt = false;
-  objc_impl_method = false;
-
-  // Get the ID and start/end of the main file.
-  MainFileID = SM->getMainFileID();
-  const llvm::MemoryBuffer *MainBuf = SM->getBuffer(MainFileID);
-  MainFileStart = MainBuf->getBufferStart();
-  MainFileEnd = MainBuf->getBufferEnd();
-
-  Rewrite.setSourceMgr(Context->getSourceManager(), Context->getLangOpts());
-}
-
-//===----------------------------------------------------------------------===//
-// Top Level Driver Code
-//===----------------------------------------------------------------------===//
-
-void RewriteModernObjC::HandleTopLevelSingleDecl(Decl *D) {
-  if (Diags.hasErrorOccurred())
-    return;
-
-  // Two cases: either the decl could be in the main file, or it could be in a
-  // #included file.  If the former, rewrite it now.  If the later, check to see
-  // if we rewrote the #include/#import.
-  SourceLocation Loc = D->getLocation();
-  Loc = SM->getExpansionLoc(Loc);
-
-  // If this is for a builtin, ignore it.
-  if (Loc.isInvalid()) return;
-
-  // Look for built-in declarations that we need to refer during the rewrite.
-  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
-    RewriteFunctionDecl(FD);
-  } else if (VarDecl *FVD = dyn_cast<VarDecl>(D)) {
-    // declared in <Foundation/NSString.h>
-    if (FVD->getName() == "_NSConstantStringClassReference") {
-      ConstantStringClassReference = FVD;
-      return;
-    }
-  } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(D)) {
-    RewriteCategoryDecl(CD);
-  } else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) {
-    if (PD->isThisDeclarationADefinition())
-      RewriteProtocolDecl(PD);
-  } else if (LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(D)) {
-    // FIXME. This will not work in all situations and leaving it out
-    // is harmless.
-    // RewriteLinkageSpec(LSD);
-    
-    // Recurse into linkage specifications
-    for (DeclContext::decl_iterator DI = LSD->decls_begin(),
-                                 DIEnd = LSD->decls_end();
-         DI != DIEnd; ) {
-      if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>((*DI))) {
-        if (!IFace->isThisDeclarationADefinition()) {
-          SmallVector<Decl *, 8> DG;
-          SourceLocation StartLoc = IFace->getLocStart();
-          do {
-            if (isa<ObjCInterfaceDecl>(*DI) &&
-                !cast<ObjCInterfaceDecl>(*DI)->isThisDeclarationADefinition() &&
-                StartLoc == (*DI)->getLocStart())
-              DG.push_back(*DI);
-            else
-              break;
-            
-            ++DI;
-          } while (DI != DIEnd);
-          RewriteForwardClassDecl(DG);
-          continue;
-        }
-        else {
-          // Keep track of all interface declarations seen.
-          ObjCInterfacesSeen.push_back(IFace);
-          ++DI;
-          continue;
-        }
-      }
-
-      if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>((*DI))) {
-        if (!Proto->isThisDeclarationADefinition()) {
-          SmallVector<Decl *, 8> DG;
-          SourceLocation StartLoc = Proto->getLocStart();
-          do {
-            if (isa<ObjCProtocolDecl>(*DI) &&
-                !cast<ObjCProtocolDecl>(*DI)->isThisDeclarationADefinition() &&
-                StartLoc == (*DI)->getLocStart())
-              DG.push_back(*DI);
-            else
-              break;
-            
-            ++DI;
-          } while (DI != DIEnd);
-          RewriteForwardProtocolDecl(DG);
-          continue;
-        }
-      }
-      
-      HandleTopLevelSingleDecl(*DI);
-      ++DI;
-    }
-  }
-  // If we have a decl in the main file, see if we should rewrite it.
-  if (SM->isWrittenInMainFile(Loc))
-    return HandleDeclInMainFile(D);
-}
-
-//===----------------------------------------------------------------------===//
-// Syntactic (non-AST) Rewriting Code
-//===----------------------------------------------------------------------===//
-
-void RewriteModernObjC::RewriteInclude() {
-  SourceLocation LocStart = SM->getLocForStartOfFile(MainFileID);
-  StringRef MainBuf = SM->getBufferData(MainFileID);
-  const char *MainBufStart = MainBuf.begin();
-  const char *MainBufEnd = MainBuf.end();
-  size_t ImportLen = strlen("import");
-
-  // Loop over the whole file, looking for includes.
-  for (const char *BufPtr = MainBufStart; BufPtr < MainBufEnd; ++BufPtr) {
-    if (*BufPtr == '#') {
-      if (++BufPtr == MainBufEnd)
-        return;
-      while (*BufPtr == ' ' || *BufPtr == '\t')
-        if (++BufPtr == MainBufEnd)
-          return;
-      if (!strncmp(BufPtr, "import", ImportLen)) {
-        // replace import with include
-        SourceLocation ImportLoc =
-          LocStart.getLocWithOffset(BufPtr-MainBufStart);
-        ReplaceText(ImportLoc, ImportLen, "include");
-        BufPtr += ImportLen;
-      }
-    }
-  }
-}
-
-static void WriteInternalIvarName(const ObjCInterfaceDecl *IDecl,
-                                  ObjCIvarDecl *IvarDecl, std::string &Result) {
-  Result += "OBJC_IVAR_$_";
-  Result += IDecl->getName();
-  Result += "$";
-  Result += IvarDecl->getName();
-}
-
-std::string 
-RewriteModernObjC::getIvarAccessString(ObjCIvarDecl *D) {
-  const ObjCInterfaceDecl *ClassDecl = D->getContainingInterface();
-  
-  // Build name of symbol holding ivar offset.
-  std::string IvarOffsetName;
-  if (D->isBitField())
-    ObjCIvarBitfieldGroupOffset(D, IvarOffsetName);
-  else
-    WriteInternalIvarName(ClassDecl, D, IvarOffsetName);
-  
-  
-  std::string S = "(*(";
-  QualType IvarT = D->getType();
-  if (D->isBitField())
-    IvarT = GetGroupRecordTypeForObjCIvarBitfield(D);
-  
-  if (!isa<TypedefType>(IvarT) && IvarT->isRecordType()) {
-    RecordDecl *RD = IvarT->getAs<RecordType>()->getDecl();
-    RD = RD->getDefinition();
-    if (RD && !RD->getDeclName().getAsIdentifierInfo()) {
-      // decltype(((Foo_IMPL*)0)->bar) *
-      ObjCContainerDecl *CDecl = 
-      dyn_cast<ObjCContainerDecl>(D->getDeclContext());
-      // ivar in class extensions requires special treatment.
-      if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(CDecl))
-        CDecl = CatDecl->getClassInterface();
-      std::string RecName = CDecl->getName();
-      RecName += "_IMPL";
-      RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
-                                          SourceLocation(), SourceLocation(),
-                                          &Context->Idents.get(RecName.c_str()));
-      QualType PtrStructIMPL = Context->getPointerType(Context->getTagDeclType(RD));
-      unsigned UnsignedIntSize = 
-      static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
-      Expr *Zero = IntegerLiteral::Create(*Context,
-                                          llvm::APInt(UnsignedIntSize, 0),
-                                          Context->UnsignedIntTy, SourceLocation());
-      Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL, CK_BitCast, Zero);
-      ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(),
-                                              Zero);
-      FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(),
-                                        SourceLocation(),
-                                        &Context->Idents.get(D->getNameAsString()),
-                                        IvarT, 0,
-                                        /*BitWidth=*/0, /*Mutable=*/true,
-                                        ICIS_NoInit);
-      MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(),
-                                                FD->getType(), VK_LValue,
-                                                OK_Ordinary);
-      IvarT = Context->getDecltypeType(ME, ME->getType());
-    }
-  }
-  convertObjCTypeToCStyleType(IvarT);
-  QualType castT = Context->getPointerType(IvarT);
-  std::string TypeString(castT.getAsString(Context->getPrintingPolicy()));
-  S += TypeString;
-  S += ")";
-  
-  // ((char *)self + IVAR_OFFSET_SYMBOL_NAME)
-  S += "((char *)self + ";
-  S += IvarOffsetName;
-  S += "))";
-  if (D->isBitField()) {
-    S += ".";
-    S += D->getNameAsString();
-  }
-  ReferencedIvars[const_cast<ObjCInterfaceDecl *>(ClassDecl)].insert(D);
-  return S;
-}
-
-/// mustSynthesizeSetterGetterMethod - returns true if setter or getter has not
-/// been found in the class implementation. In this case, it must be synthesized.
-static bool mustSynthesizeSetterGetterMethod(ObjCImplementationDecl *IMP,
-                                             ObjCPropertyDecl *PD,
-                                             bool getter) {
-  return getter ? !IMP->getInstanceMethod(PD->getGetterName())
-                : !IMP->getInstanceMethod(PD->getSetterName());
-  
-}
-
-void RewriteModernObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
-                                          ObjCImplementationDecl *IMD,
-                                          ObjCCategoryImplDecl *CID) {
-  static bool objcGetPropertyDefined = false;
-  static bool objcSetPropertyDefined = false;
-  SourceLocation startGetterSetterLoc;
-  
-  if (PID->getLocStart().isValid()) {
-    SourceLocation startLoc = PID->getLocStart();
-    InsertText(startLoc, "// ");
-    const char *startBuf = SM->getCharacterData(startLoc);
-    assert((*startBuf == '@') && "bogus @synthesize location");
-    const char *semiBuf = strchr(startBuf, ';');
-    assert((*semiBuf == ';') && "@synthesize: can't find ';'");
-    startGetterSetterLoc = startLoc.getLocWithOffset(semiBuf-startBuf+1);
-  }
-  else
-    startGetterSetterLoc = IMD ? IMD->getLocEnd() : CID->getLocEnd();
-
-  if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
-    return; // FIXME: is this correct?
-
-  // Generate the 'getter' function.
-  ObjCPropertyDecl *PD = PID->getPropertyDecl();
-  ObjCIvarDecl *OID = PID->getPropertyIvarDecl();
-  assert(IMD && OID && "Synthesized ivars must be attached to @implementation");
-
-  unsigned Attributes = PD->getPropertyAttributes();
-  if (mustSynthesizeSetterGetterMethod(IMD, PD, true /*getter*/)) {
-    bool GenGetProperty = !(Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) &&
-                          (Attributes & (ObjCPropertyDecl::OBJC_PR_retain | 
-                                         ObjCPropertyDecl::OBJC_PR_copy));
-    std::string Getr;
-    if (GenGetProperty && !objcGetPropertyDefined) {
-      objcGetPropertyDefined = true;
-      // FIXME. Is this attribute correct in all cases?
-      Getr = "\nextern \"C\" __declspec(dllimport) "
-            "id objc_getProperty(id, SEL, long, bool);\n";
-    }
-    RewriteObjCMethodDecl(OID->getContainingInterface(),  
-                          PD->getGetterMethodDecl(), Getr);
-    Getr += "{ ";
-    // Synthesize an explicit cast to gain access to the ivar.
-    // See objc-act.c:objc_synthesize_new_getter() for details.
-    if (GenGetProperty) {
-      // return objc_getProperty(self, _cmd, offsetof(ClassDecl, OID), 1)
-      Getr += "typedef ";
-      const FunctionType *FPRetType = 0;
-      RewriteTypeIntoString(PD->getGetterMethodDecl()->getResultType(), Getr, 
-                            FPRetType);
-      Getr += " _TYPE";
-      if (FPRetType) {
-        Getr += ")"; // close the precedence "scope" for "*".
-      
-        // Now, emit the argument types (if any).
-        if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(FPRetType)){
-          Getr += "(";
-          for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i) {
-            if (i) Getr += ", ";
-            std::string ParamStr = FT->getArgType(i).getAsString(
-                                                          Context->getPrintingPolicy());
-            Getr += ParamStr;
-          }
-          if (FT->isVariadic()) {
-            if (FT->getNumArgs()) Getr += ", ";
-            Getr += "...";
-          }
-          Getr += ")";
-        } else
-          Getr += "()";
-      }
-      Getr += ";\n";
-      Getr += "return (_TYPE)";
-      Getr += "objc_getProperty(self, _cmd, ";
-      RewriteIvarOffsetComputation(OID, Getr);
-      Getr += ", 1)";
-    }
-    else
-      Getr += "return " + getIvarAccessString(OID);
-    Getr += "; }";
-    InsertText(startGetterSetterLoc, Getr);
-  }
-  
-  if (PD->isReadOnly() || 
-      !mustSynthesizeSetterGetterMethod(IMD, PD, false /*setter*/))
-    return;
-
-  // Generate the 'setter' function.
-  std::string Setr;
-  bool GenSetProperty = Attributes & (ObjCPropertyDecl::OBJC_PR_retain | 
-                                      ObjCPropertyDecl::OBJC_PR_copy);
-  if (GenSetProperty && !objcSetPropertyDefined) {
-    objcSetPropertyDefined = true;
-    // FIXME. Is this attribute correct in all cases?
-    Setr = "\nextern \"C\" __declspec(dllimport) "
-    "void objc_setProperty (id, SEL, long, id, bool, bool);\n";
-  }
-  
-  RewriteObjCMethodDecl(OID->getContainingInterface(), 
-                        PD->getSetterMethodDecl(), Setr);
-  Setr += "{ ";
-  // Synthesize an explicit cast to initialize the ivar.
-  // See objc-act.c:objc_synthesize_new_setter() for details.
-  if (GenSetProperty) {
-    Setr += "objc_setProperty (self, _cmd, ";
-    RewriteIvarOffsetComputation(OID, Setr);
-    Setr += ", (id)";
-    Setr += PD->getName();
-    Setr += ", ";
-    if (Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic)
-      Setr += "0, ";
-    else
-      Setr += "1, ";
-    if (Attributes & ObjCPropertyDecl::OBJC_PR_copy)
-      Setr += "1)";
-    else
-      Setr += "0)";
-  }
-  else {
-    Setr += getIvarAccessString(OID) + " = ";
-    Setr += PD->getName();
-  }
-  Setr += "; }\n";
-  InsertText(startGetterSetterLoc, Setr);
-}
-
-static void RewriteOneForwardClassDecl(ObjCInterfaceDecl *ForwardDecl,
-                                       std::string &typedefString) {
-  typedefString += "\n#ifndef _REWRITER_typedef_";
-  typedefString += ForwardDecl->getNameAsString();
-  typedefString += "\n";
-  typedefString += "#define _REWRITER_typedef_";
-  typedefString += ForwardDecl->getNameAsString();
-  typedefString += "\n";
-  typedefString += "typedef struct objc_object ";
-  typedefString += ForwardDecl->getNameAsString();
-  // typedef struct { } _objc_exc_Classname;
-  typedefString += ";\ntypedef struct {} _objc_exc_";
-  typedefString += ForwardDecl->getNameAsString();
-  typedefString += ";\n#endif\n";
-}
-
-void RewriteModernObjC::RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl,
-                                              const std::string &typedefString) {
-    SourceLocation startLoc = ClassDecl->getLocStart();
-    const char *startBuf = SM->getCharacterData(startLoc);
-    const char *semiPtr = strchr(startBuf, ';'); 
-    // Replace the @class with typedefs corresponding to the classes.
-    ReplaceText(startLoc, semiPtr-startBuf+1, typedefString);  
-}
-
-void RewriteModernObjC::RewriteForwardClassDecl(DeclGroupRef D) {
-  std::string typedefString;
-  for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) {
-    if (ObjCInterfaceDecl *ForwardDecl = dyn_cast<ObjCInterfaceDecl>(*I)) {
-      if (I == D.begin()) {
-        // Translate to typedef's that forward reference structs with the same name
-        // as the class. As a convenience, we include the original declaration
-        // as a comment.
-        typedefString += "// @class ";
-        typedefString += ForwardDecl->getNameAsString();
-        typedefString += ";";
-      }
-      RewriteOneForwardClassDecl(ForwardDecl, typedefString);
-    }
-    else
-      HandleTopLevelSingleDecl(*I);
-  }
-  DeclGroupRef::iterator I = D.begin();
-  RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(*I), typedefString);
-}
-
-void RewriteModernObjC::RewriteForwardClassDecl(
-                                const SmallVectorImpl<Decl *> &D) {
-  std::string typedefString;
-  for (unsigned i = 0; i < D.size(); i++) {
-    ObjCInterfaceDecl *ForwardDecl = cast<ObjCInterfaceDecl>(D[i]);
-    if (i == 0) {
-      typedefString += "// @class ";
-      typedefString += ForwardDecl->getNameAsString();
-      typedefString += ";";
-    }
-    RewriteOneForwardClassDecl(ForwardDecl, typedefString);
-  }
-  RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(D[0]), typedefString);
-}
-
-void RewriteModernObjC::RewriteMethodDeclaration(ObjCMethodDecl *Method) {
-  // When method is a synthesized one, such as a getter/setter there is
-  // nothing to rewrite.
-  if (Method->isImplicit())
-    return;
-  SourceLocation LocStart = Method->getLocStart();
-  SourceLocation LocEnd = Method->getLocEnd();
-
-  if (SM->getExpansionLineNumber(LocEnd) >
-      SM->getExpansionLineNumber(LocStart)) {
-    InsertText(LocStart, "#if 0\n");
-    ReplaceText(LocEnd, 1, ";\n#endif\n");
-  } else {
-    InsertText(LocStart, "// ");
-  }
-}
-
-void RewriteModernObjC::RewriteProperty(ObjCPropertyDecl *prop) {
-  SourceLocation Loc = prop->getAtLoc();
-
-  ReplaceText(Loc, 0, "// ");
-  // FIXME: handle properties that are declared across multiple lines.
-}
-
-void RewriteModernObjC::RewriteCategoryDecl(ObjCCategoryDecl *CatDecl) {
-  SourceLocation LocStart = CatDecl->getLocStart();
-
-  // FIXME: handle category headers that are declared across multiple lines.
-  if (CatDecl->getIvarRBraceLoc().isValid()) {
-    ReplaceText(LocStart, 1, "/** ");
-    ReplaceText(CatDecl->getIvarRBraceLoc(), 1, "**/ ");
-  }
-  else {
-    ReplaceText(LocStart, 0, "// ");
-  }
-  
-  for (ObjCCategoryDecl::prop_iterator I = CatDecl->prop_begin(),
-       E = CatDecl->prop_end(); I != E; ++I)
-    RewriteProperty(*I);
-  
-  for (ObjCCategoryDecl::instmeth_iterator
-         I = CatDecl->instmeth_begin(), E = CatDecl->instmeth_end();
-       I != E; ++I)
-    RewriteMethodDeclaration(*I);
-  for (ObjCCategoryDecl::classmeth_iterator
-         I = CatDecl->classmeth_begin(), E = CatDecl->classmeth_end();
-       I != E; ++I)
-    RewriteMethodDeclaration(*I);
-
-  // Lastly, comment out the @end.
-  ReplaceText(CatDecl->getAtEndRange().getBegin(), 
-              strlen("@end"), "/* @end */\n");
-}
-
-void RewriteModernObjC::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) {
-  SourceLocation LocStart = PDecl->getLocStart();
-  assert(PDecl->isThisDeclarationADefinition());
-  
-  // FIXME: handle protocol headers that are declared across multiple lines.
-  ReplaceText(LocStart, 0, "// ");
-
-  for (ObjCProtocolDecl::instmeth_iterator
-         I = PDecl->instmeth_begin(), E = PDecl->instmeth_end();
-       I != E; ++I)
-    RewriteMethodDeclaration(*I);
-  for (ObjCProtocolDecl::classmeth_iterator
-         I = PDecl->classmeth_begin(), E = PDecl->classmeth_end();
-       I != E; ++I)
-    RewriteMethodDeclaration(*I);
-
-  for (ObjCInterfaceDecl::prop_iterator I = PDecl->prop_begin(),
-       E = PDecl->prop_end(); I != E; ++I)
-    RewriteProperty(*I);
-  
-  // Lastly, comment out the @end.
-  SourceLocation LocEnd = PDecl->getAtEndRange().getBegin();
-  ReplaceText(LocEnd, strlen("@end"), "/* @end */\n");
-
-  // Must comment out @optional/@required
-  const char *startBuf = SM->getCharacterData(LocStart);
-  const char *endBuf = SM->getCharacterData(LocEnd);
-  for (const char *p = startBuf; p < endBuf; p++) {
-    if (*p == '@' && !strncmp(p+1, "optional", strlen("optional"))) {
-      SourceLocation OptionalLoc = LocStart.getLocWithOffset(p-startBuf);
-      ReplaceText(OptionalLoc, strlen("@optional"), "/* @optional */");
-
-    }
-    else if (*p == '@' && !strncmp(p+1, "required", strlen("required"))) {
-      SourceLocation OptionalLoc = LocStart.getLocWithOffset(p-startBuf);
-      ReplaceText(OptionalLoc, strlen("@required"), "/* @required */");
-
-    }
-  }
-}
-
-void RewriteModernObjC::RewriteForwardProtocolDecl(DeclGroupRef D) {
-  SourceLocation LocStart = (*D.begin())->getLocStart();
-  if (LocStart.isInvalid())
-    llvm_unreachable("Invalid SourceLocation");
-  // FIXME: handle forward protocol that are declared across multiple lines.
-  ReplaceText(LocStart, 0, "// ");
-}
-
-void 
-RewriteModernObjC::RewriteForwardProtocolDecl(const SmallVectorImpl<Decl *> &DG) {
-  SourceLocation LocStart = DG[0]->getLocStart();
-  if (LocStart.isInvalid())
-    llvm_unreachable("Invalid SourceLocation");
-  // FIXME: handle forward protocol that are declared across multiple lines.
-  ReplaceText(LocStart, 0, "// ");
-}
-
-void 
-RewriteModernObjC::RewriteLinkageSpec(LinkageSpecDecl *LSD) {
-  SourceLocation LocStart = LSD->getExternLoc();
-  if (LocStart.isInvalid())
-    llvm_unreachable("Invalid extern SourceLocation");
-  
-  ReplaceText(LocStart, 0, "// ");
-  if (!LSD->hasBraces())
-    return;
-  // FIXME. We don't rewrite well if '{' is not on same line as 'extern'.
-  SourceLocation LocRBrace = LSD->getRBraceLoc();
-  if (LocRBrace.isInvalid())
-    llvm_unreachable("Invalid rbrace SourceLocation");
-  ReplaceText(LocRBrace, 0, "// ");
-}
-
-void RewriteModernObjC::RewriteTypeIntoString(QualType T, std::string &ResultStr,
-                                        const FunctionType *&FPRetType) {
-  if (T->isObjCQualifiedIdType())
-    ResultStr += "id";
-  else if (T->isFunctionPointerType() ||
-           T->isBlockPointerType()) {
-    // needs special handling, since pointer-to-functions have special
-    // syntax (where a decaration models use).
-    QualType retType = T;
-    QualType PointeeTy;
-    if (const PointerType* PT = retType->getAs<PointerType>())
-      PointeeTy = PT->getPointeeType();
-    else if (const BlockPointerType *BPT = retType->getAs<BlockPointerType>())
-      PointeeTy = BPT->getPointeeType();
-    if ((FPRetType = PointeeTy->getAs<FunctionType>())) {
-      ResultStr += FPRetType->getResultType().getAsString(
-        Context->getPrintingPolicy());
-      ResultStr += "(*";
-    }
-  } else
-    ResultStr += T.getAsString(Context->getPrintingPolicy());
-}
-
-void RewriteModernObjC::RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl,
-                                        ObjCMethodDecl *OMD,
-                                        std::string &ResultStr) {
-  //fprintf(stderr,"In RewriteObjCMethodDecl\n");
-  const FunctionType *FPRetType = 0;
-  ResultStr += "\nstatic ";
-  RewriteTypeIntoString(OMD->getResultType(), ResultStr, FPRetType);
-  ResultStr += " ";
-
-  // Unique method name
-  std::string NameStr;
-
-  if (OMD->isInstanceMethod())
-    NameStr += "_I_";
-  else
-    NameStr += "_C_";
-
-  NameStr += IDecl->getNameAsString();
-  NameStr += "_";
-
-  if (ObjCCategoryImplDecl *CID =
-      dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext())) {
-    NameStr += CID->getNameAsString();
-    NameStr += "_";
-  }
-  // Append selector names, replacing ':' with '_'
-  {
-    std::string selString = OMD->getSelector().getAsString();
-    int len = selString.size();
-    for (int i = 0; i < len; i++)
-      if (selString[i] == ':')
-        selString[i] = '_';
-    NameStr += selString;
-  }
-  // Remember this name for metadata emission
-  MethodInternalNames[OMD] = NameStr;
-  ResultStr += NameStr;
-
-  // Rewrite arguments
-  ResultStr += "(";
-
-  // invisible arguments
-  if (OMD->isInstanceMethod()) {
-    QualType selfTy = Context->getObjCInterfaceType(IDecl);
-    selfTy = Context->getPointerType(selfTy);
-    if (!LangOpts.MicrosoftExt) {
-      if (ObjCSynthesizedStructs.count(const_cast<ObjCInterfaceDecl*>(IDecl)))
-        ResultStr += "struct ";
-    }
-    // When rewriting for Microsoft, explicitly omit the structure name.
-    ResultStr += IDecl->getNameAsString();
-    ResultStr += " *";
-  }
-  else
-    ResultStr += Context->getObjCClassType().getAsString(
-      Context->getPrintingPolicy());
-
-  ResultStr += " self, ";
-  ResultStr += Context->getObjCSelType().getAsString(Context->getPrintingPolicy());
-  ResultStr += " _cmd";
-
-  // Method arguments.
-  for (ObjCMethodDecl::param_iterator PI = OMD->param_begin(),
-       E = OMD->param_end(); PI != E; ++PI) {
-    ParmVarDecl *PDecl = *PI;
-    ResultStr += ", ";
-    if (PDecl->getType()->isObjCQualifiedIdType()) {
-      ResultStr += "id ";
-      ResultStr += PDecl->getNameAsString();
-    } else {
-      std::string Name = PDecl->getNameAsString();
-      QualType QT = PDecl->getType();
-      // Make sure we convert "t (^)(...)" to "t (*)(...)".
-      (void)convertBlockPointerToFunctionPointer(QT);
-      QT.getAsStringInternal(Name, Context->getPrintingPolicy());
-      ResultStr += Name;
-    }
-  }
-  if (OMD->isVariadic())
-    ResultStr += ", ...";
-  ResultStr += ") ";
-
-  if (FPRetType) {
-    ResultStr += ")"; // close the precedence "scope" for "*".
-
-    // Now, emit the argument types (if any).
-    if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(FPRetType)) {
-      ResultStr += "(";
-      for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i) {
-        if (i) ResultStr += ", ";
-        std::string ParamStr = FT->getArgType(i).getAsString(
-          Context->getPrintingPolicy());
-        ResultStr += ParamStr;
-      }
-      if (FT->isVariadic()) {
-        if (FT->getNumArgs()) ResultStr += ", ";
-        ResultStr += "...";
-      }
-      ResultStr += ")";
-    } else {
-      ResultStr += "()";
-    }
-  }
-}
-void RewriteModernObjC::RewriteImplementationDecl(Decl *OID) {
-  ObjCImplementationDecl *IMD = dyn_cast<ObjCImplementationDecl>(OID);
-  ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(OID);
-
-  if (IMD) {
-    if (IMD->getIvarRBraceLoc().isValid()) {
-      ReplaceText(IMD->getLocStart(), 1, "/** ");
-      ReplaceText(IMD->getIvarRBraceLoc(), 1, "**/ ");
-    }
-    else {
-      InsertText(IMD->getLocStart(), "// ");
-    }
-  }
-  else
-    InsertText(CID->getLocStart(), "// ");
-
-  for (ObjCCategoryImplDecl::instmeth_iterator
-       I = IMD ? IMD->instmeth_begin() : CID->instmeth_begin(),
-       E = IMD ? IMD->instmeth_end() : CID->instmeth_end();
-       I != E; ++I) {
-    std::string ResultStr;
-    ObjCMethodDecl *OMD = *I;
-    RewriteObjCMethodDecl(OMD->getClassInterface(), OMD, ResultStr);
-    SourceLocation LocStart = OMD->getLocStart();
-    SourceLocation LocEnd = OMD->getCompoundBody()->getLocStart();
-
-    const char *startBuf = SM->getCharacterData(LocStart);
-    const char *endBuf = SM->getCharacterData(LocEnd);
-    ReplaceText(LocStart, endBuf-startBuf, ResultStr);
-  }
-
-  for (ObjCCategoryImplDecl::classmeth_iterator
-       I = IMD ? IMD->classmeth_begin() : CID->classmeth_begin(),
-       E = IMD ? IMD->classmeth_end() : CID->classmeth_end();
-       I != E; ++I) {
-    std::string ResultStr;
-    ObjCMethodDecl *OMD = *I;
-    RewriteObjCMethodDecl(OMD->getClassInterface(), OMD, ResultStr);
-    SourceLocation LocStart = OMD->getLocStart();
-    SourceLocation LocEnd = OMD->getCompoundBody()->getLocStart();
-
-    const char *startBuf = SM->getCharacterData(LocStart);
-    const char *endBuf = SM->getCharacterData(LocEnd);
-    ReplaceText(LocStart, endBuf-startBuf, ResultStr);
-  }
-  for (ObjCCategoryImplDecl::propimpl_iterator
-       I = IMD ? IMD->propimpl_begin() : CID->propimpl_begin(),
-       E = IMD ? IMD->propimpl_end() : CID->propimpl_end();
-       I != E; ++I) {
-    RewritePropertyImplDecl(*I, IMD, CID);
-  }
-
-  InsertText(IMD ? IMD->getLocEnd() : CID->getLocEnd(), "// ");
-}
-
-void RewriteModernObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) {
-  // Do not synthesize more than once.
-  if (ObjCSynthesizedStructs.count(ClassDecl))
-    return;
-  // Make sure super class's are written before current class is written.
-  ObjCInterfaceDecl *SuperClass = ClassDecl->getSuperClass();
-  while (SuperClass) {
-    RewriteInterfaceDecl(SuperClass);
-    SuperClass = SuperClass->getSuperClass();
-  }
-  std::string ResultStr;
-  if (!ObjCWrittenInterfaces.count(ClassDecl->getCanonicalDecl())) {
-    // we haven't seen a forward decl - generate a typedef.
-    RewriteOneForwardClassDecl(ClassDecl, ResultStr);
-    RewriteIvarOffsetSymbols(ClassDecl, ResultStr);
-    
-    RewriteObjCInternalStruct(ClassDecl, ResultStr);
-    // Mark this typedef as having been written into its c++ equivalent.
-    ObjCWrittenInterfaces.insert(ClassDecl->getCanonicalDecl());
-  
-    for (ObjCInterfaceDecl::prop_iterator I = ClassDecl->prop_begin(),
-         E = ClassDecl->prop_end(); I != E; ++I)
-      RewriteProperty(*I);
-    for (ObjCInterfaceDecl::instmeth_iterator
-         I = ClassDecl->instmeth_begin(), E = ClassDecl->instmeth_end();
-         I != E; ++I)
-      RewriteMethodDeclaration(*I);
-    for (ObjCInterfaceDecl::classmeth_iterator
-         I = ClassDecl->classmeth_begin(), E = ClassDecl->classmeth_end();
-         I != E; ++I)
-      RewriteMethodDeclaration(*I);
-
-    // Lastly, comment out the @end.
-    ReplaceText(ClassDecl->getAtEndRange().getBegin(), strlen("@end"), 
-                "/* @end */\n");
-  }
-}
-
-Stmt *RewriteModernObjC::RewritePropertyOrImplicitSetter(PseudoObjectExpr *PseudoOp) {
-  SourceRange OldRange = PseudoOp->getSourceRange();
-
-  // We just magically know some things about the structure of this
-  // expression.
-  ObjCMessageExpr *OldMsg =
-    cast<ObjCMessageExpr>(PseudoOp->getSemanticExpr(
-                            PseudoOp->getNumSemanticExprs() - 1));
-
-  // Because the rewriter doesn't allow us to rewrite rewritten code,
-  // we need to suppress rewriting the sub-statements.
-  Expr *Base;
-  SmallVector<Expr*, 2> Args;
-  {
-    DisableReplaceStmtScope S(*this);
-
-    // Rebuild the base expression if we have one.
-    Base = 0;
-    if (OldMsg->getReceiverKind() == ObjCMessageExpr::Instance) {
-      Base = OldMsg->getInstanceReceiver();
-      Base = cast<OpaqueValueExpr>(Base)->getSourceExpr();
-      Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base));
-    }
-  
-    unsigned numArgs = OldMsg->getNumArgs();
-    for (unsigned i = 0; i < numArgs; i++) {
-      Expr *Arg = OldMsg->getArg(i);
-      if (isa<OpaqueValueExpr>(Arg))
-        Arg = cast<OpaqueValueExpr>(Arg)->getSourceExpr();
-      Arg = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Arg));
-      Args.push_back(Arg);
-    }
-  }
-
-  // TODO: avoid this copy.
-  SmallVector<SourceLocation, 1> SelLocs;
-  OldMsg->getSelectorLocs(SelLocs);
-
-  ObjCMessageExpr *NewMsg = 0;
-  switch (OldMsg->getReceiverKind()) {
-  case ObjCMessageExpr::Class:
-    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
-                                     OldMsg->getValueKind(),
-                                     OldMsg->getLeftLoc(),
-                                     OldMsg->getClassReceiverTypeInfo(),
-                                     OldMsg->getSelector(),
-                                     SelLocs,
-                                     OldMsg->getMethodDecl(),
-                                     Args,
-                                     OldMsg->getRightLoc(),
-                                     OldMsg->isImplicit());
-    break;
-
-  case ObjCMessageExpr::Instance:
-    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
-                                     OldMsg->getValueKind(),
-                                     OldMsg->getLeftLoc(),
-                                     Base,
-                                     OldMsg->getSelector(),
-                                     SelLocs,
-                                     OldMsg->getMethodDecl(),
-                                     Args,
-                                     OldMsg->getRightLoc(),
-                                     OldMsg->isImplicit());
-    break;
-
-  case ObjCMessageExpr::SuperClass:
-  case ObjCMessageExpr::SuperInstance:
-    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
-                                     OldMsg->getValueKind(),
-                                     OldMsg->getLeftLoc(),
-                                     OldMsg->getSuperLoc(),
-                 OldMsg->getReceiverKind() == ObjCMessageExpr::SuperInstance,
-                                     OldMsg->getSuperType(),
-                                     OldMsg->getSelector(),
-                                     SelLocs,
-                                     OldMsg->getMethodDecl(),
-                                     Args,
-                                     OldMsg->getRightLoc(),
-                                     OldMsg->isImplicit());
-    break;
-  }
-
-  Stmt *Replacement = SynthMessageExpr(NewMsg);
-  ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
-  return Replacement;
-}
-
-Stmt *RewriteModernObjC::RewritePropertyOrImplicitGetter(PseudoObjectExpr *PseudoOp) {
-  SourceRange OldRange = PseudoOp->getSourceRange();
-
-  // We just magically know some things about the structure of this
-  // expression.
-  ObjCMessageExpr *OldMsg =
-    cast<ObjCMessageExpr>(PseudoOp->getResultExpr()->IgnoreImplicit());
-
-  // Because the rewriter doesn't allow us to rewrite rewritten code,
-  // we need to suppress rewriting the sub-statements.
-  Expr *Base = 0;
-  SmallVector<Expr*, 1> Args;
-  {
-    DisableReplaceStmtScope S(*this);
-    // Rebuild the base expression if we have one.
-    if (OldMsg->getReceiverKind() == ObjCMessageExpr::Instance) {
-      Base = OldMsg->getInstanceReceiver();
-      Base = cast<OpaqueValueExpr>(Base)->getSourceExpr();
-      Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base));
-    }
-    unsigned numArgs = OldMsg->getNumArgs();
-    for (unsigned i = 0; i < numArgs; i++) {
-      Expr *Arg = OldMsg->getArg(i);
-      if (isa<OpaqueValueExpr>(Arg))
-        Arg = cast<OpaqueValueExpr>(Arg)->getSourceExpr();
-      Arg = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Arg));
-      Args.push_back(Arg);
-    }
-  }
-
-  // Intentionally empty.
-  SmallVector<SourceLocation, 1> SelLocs;
-
-  ObjCMessageExpr *NewMsg = 0;
-  switch (OldMsg->getReceiverKind()) {
-  case ObjCMessageExpr::Class:
-    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
-                                     OldMsg->getValueKind(),
-                                     OldMsg->getLeftLoc(),
-                                     OldMsg->getClassReceiverTypeInfo(),
-                                     OldMsg->getSelector(),
-                                     SelLocs,
-                                     OldMsg->getMethodDecl(),
-                                     Args,
-                                     OldMsg->getRightLoc(),
-                                     OldMsg->isImplicit());
-    break;
-
-  case ObjCMessageExpr::Instance:
-    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
-                                     OldMsg->getValueKind(),
-                                     OldMsg->getLeftLoc(),
-                                     Base,
-                                     OldMsg->getSelector(),
-                                     SelLocs,
-                                     OldMsg->getMethodDecl(),
-                                     Args,
-                                     OldMsg->getRightLoc(),
-                                     OldMsg->isImplicit());
-    break;
-
-  case ObjCMessageExpr::SuperClass:
-  case ObjCMessageExpr::SuperInstance:
-    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
-                                     OldMsg->getValueKind(),
-                                     OldMsg->getLeftLoc(),
-                                     OldMsg->getSuperLoc(),
-                 OldMsg->getReceiverKind() == ObjCMessageExpr::SuperInstance,
-                                     OldMsg->getSuperType(),
-                                     OldMsg->getSelector(),
-                                     SelLocs,
-                                     OldMsg->getMethodDecl(),
-                                     Args,
-                                     OldMsg->getRightLoc(),
-                                     OldMsg->isImplicit());
-    break;
-  }
-
-  Stmt *Replacement = SynthMessageExpr(NewMsg);
-  ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
-  return Replacement;
-}
-
-/// SynthCountByEnumWithState - To print:
-/// ((NSUInteger (*)
-///  (id, SEL, struct __objcFastEnumerationState *, id *, NSUInteger))
-///  (void *)objc_msgSend)((id)l_collection,
-///                        sel_registerName(
-///                          "countByEnumeratingWithState:objects:count:"),
-///                        &enumState,
-///                        (id *)__rw_items, (NSUInteger)16)
-///
-void RewriteModernObjC::SynthCountByEnumWithState(std::string &buf) {
-  buf += "((_WIN_NSUInteger (*) (id, SEL, struct __objcFastEnumerationState *, "
-  "id *, _WIN_NSUInteger))(void *)objc_msgSend)";
-  buf += "\n\t\t";
-  buf += "((id)l_collection,\n\t\t";
-  buf += "sel_registerName(\"countByEnumeratingWithState:objects:count:\"),";
-  buf += "\n\t\t";
-  buf += "&enumState, "
-         "(id *)__rw_items, (_WIN_NSUInteger)16)";
-}
-
-/// RewriteBreakStmt - Rewrite for a break-stmt inside an ObjC2's foreach
-/// statement to exit to its outer synthesized loop.
-///
-Stmt *RewriteModernObjC::RewriteBreakStmt(BreakStmt *S) {
-  if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
-    return S;
-  // replace break with goto __break_label
-  std::string buf;
-
-  SourceLocation startLoc = S->getLocStart();
-  buf = "goto __break_label_";
-  buf += utostr(ObjCBcLabelNo.back());
-  ReplaceText(startLoc, strlen("break"), buf);
-
-  return 0;
-}
-
-void RewriteModernObjC::ConvertSourceLocationToLineDirective(
-                                          SourceLocation Loc,
-                                          std::string &LineString) {
-  if (Loc.isFileID() && GenerateLineInfo) {
-    LineString += "\n#line ";
-    PresumedLoc PLoc = SM->getPresumedLoc(Loc);
-    LineString += utostr(PLoc.getLine());
-    LineString += " \"";
-    LineString += Lexer::Stringify(PLoc.getFilename());
-    LineString += "\"\n";
-  }
-}
-
-/// RewriteContinueStmt - Rewrite for a continue-stmt inside an ObjC2's foreach
-/// statement to continue with its inner synthesized loop.
-///
-Stmt *RewriteModernObjC::RewriteContinueStmt(ContinueStmt *S) {
-  if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
-    return S;
-  // replace continue with goto __continue_label
-  std::string buf;
-
-  SourceLocation startLoc = S->getLocStart();
-  buf = "goto __continue_label_";
-  buf += utostr(ObjCBcLabelNo.back());
-  ReplaceText(startLoc, strlen("continue"), buf);
-
-  return 0;
-}
-
-/// RewriteObjCForCollectionStmt - Rewriter for ObjC2's foreach statement.
-///  It rewrites:
-/// for ( type elem in collection) { stmts; }
-
-/// Into:
-/// {
-///   type elem;
-///   struct __objcFastEnumerationState enumState = { 0 };
-///   id __rw_items[16];
-///   id l_collection = (id)collection;
-///   NSUInteger limit = [l_collection countByEnumeratingWithState:&enumState
-///                                       objects:__rw_items count:16];
-/// if (limit) {
-///   unsigned long startMutations = *enumState.mutationsPtr;
-///   do {
-///        unsigned long counter = 0;
-///        do {
-///             if (startMutations != *enumState.mutationsPtr)
-///               objc_enumerationMutation(l_collection);
-///             elem = (type)enumState.itemsPtr[counter++];
-///             stmts;
-///             __continue_label: ;
-///        } while (counter < limit);
-///   } while ((limit = [l_collection countByEnumeratingWithState:&enumState
-///                                  objects:__rw_items count:16]));
-///   elem = nil;
-///   __break_label: ;
-///  }
-///  else
-///       elem = nil;
-///  }
-///
-Stmt *RewriteModernObjC::RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
-                                                SourceLocation OrigEnd) {
-  assert(!Stmts.empty() && "ObjCForCollectionStmt - Statement stack empty");
-  assert(isa<ObjCForCollectionStmt>(Stmts.back()) &&
-         "ObjCForCollectionStmt Statement stack mismatch");
-  assert(!ObjCBcLabelNo.empty() &&
-         "ObjCForCollectionStmt - Label No stack empty");
-
-  SourceLocation startLoc = S->getLocStart();
-  const char *startBuf = SM->getCharacterData(startLoc);
-  StringRef elementName;
-  std::string elementTypeAsString;
-  std::string buf;
-  // line directive first.
-  SourceLocation ForEachLoc = S->getForLoc();
-  ConvertSourceLocationToLineDirective(ForEachLoc, buf);
-  buf += "{\n\t";
-  if (DeclStmt *DS = dyn_cast<DeclStmt>(S->getElement())) {
-    // type elem;
-    NamedDecl* D = cast<NamedDecl>(DS->getSingleDecl());
-    QualType ElementType = cast<ValueDecl>(D)->getType();
-    if (ElementType->isObjCQualifiedIdType() ||
-        ElementType->isObjCQualifiedInterfaceType())
-      // Simply use 'id' for all qualified types.
-      elementTypeAsString = "id";
-    else
-      elementTypeAsString = ElementType.getAsString(Context->getPrintingPolicy());
-    buf += elementTypeAsString;
-    buf += " ";
-    elementName = D->getName();
-    buf += elementName;
-    buf += ";\n\t";
-  }
-  else {
-    DeclRefExpr *DR = cast<DeclRefExpr>(S->getElement());
-    elementName = DR->getDecl()->getName();
-    ValueDecl *VD = cast<ValueDecl>(DR->getDecl());
-    if (VD->getType()->isObjCQualifiedIdType() ||
-        VD->getType()->isObjCQualifiedInterfaceType())
-      // Simply use 'id' for all qualified types.
-      elementTypeAsString = "id";
-    else
-      elementTypeAsString = VD->getType().getAsString(Context->getPrintingPolicy());
-  }
-
-  // struct __objcFastEnumerationState enumState = { 0 };
-  buf += "struct __objcFastEnumerationState enumState = { 0 };\n\t";
-  // id __rw_items[16];
-  buf += "id __rw_items[16];\n\t";
-  // id l_collection = (id)
-  buf += "id l_collection = (id)";
-  // Find start location of 'collection' the hard way!
-  const char *startCollectionBuf = startBuf;
-  startCollectionBuf += 3;  // skip 'for'
-  startCollectionBuf = strchr(startCollectionBuf, '(');
-  startCollectionBuf++; // skip '('
-  // find 'in' and skip it.
-  while (*startCollectionBuf != ' ' ||
-         *(startCollectionBuf+1) != 'i' || *(startCollectionBuf+2) != 'n' ||
-         (*(startCollectionBuf+3) != ' ' &&
-          *(startCollectionBuf+3) != '[' && *(startCollectionBuf+3) != '('))
-    startCollectionBuf++;
-  startCollectionBuf += 3;
-
-  // Replace: "for (type element in" with string constructed thus far.
-  ReplaceText(startLoc, startCollectionBuf - startBuf, buf);
-  // Replace ')' in for '(' type elem in collection ')' with ';'
-  SourceLocation rightParenLoc = S->getRParenLoc();
-  const char *rparenBuf = SM->getCharacterData(rightParenLoc);
-  SourceLocation lparenLoc = startLoc.getLocWithOffset(rparenBuf-startBuf);
-  buf = ";\n\t";
-
-  // unsigned long limit = [l_collection countByEnumeratingWithState:&enumState
-  //                                   objects:__rw_items count:16];
-  // which is synthesized into:
-  // NSUInteger limit =
-  // ((NSUInteger (*)
-  //  (id, SEL, struct __objcFastEnumerationState *, id *, NSUInteger))
-  //  (void *)objc_msgSend)((id)l_collection,
-  //                        sel_registerName(
-  //                          "countByEnumeratingWithState:objects:count:"),
-  //                        (struct __objcFastEnumerationState *)&state,
-  //                        (id *)__rw_items, (NSUInteger)16);
-  buf += "_WIN_NSUInteger limit =\n\t\t";
-  SynthCountByEnumWithState(buf);
-  buf += ";\n\t";
-  /// if (limit) {
-  ///   unsigned long startMutations = *enumState.mutationsPtr;
-  ///   do {
-  ///        unsigned long counter = 0;
-  ///        do {
-  ///             if (startMutations != *enumState.mutationsPtr)
-  ///               objc_enumerationMutation(l_collection);
-  ///             elem = (type)enumState.itemsPtr[counter++];
-  buf += "if (limit) {\n\t";
-  buf += "unsigned long startMutations = *enumState.mutationsPtr;\n\t";
-  buf += "do {\n\t\t";
-  buf += "unsigned long counter = 0;\n\t\t";
-  buf += "do {\n\t\t\t";
-  buf += "if (startMutations != *enumState.mutationsPtr)\n\t\t\t\t";
-  buf += "objc_enumerationMutation(l_collection);\n\t\t\t";
-  buf += elementName;
-  buf += " = (";
-  buf += elementTypeAsString;
-  buf += ")enumState.itemsPtr[counter++];";
-  // Replace ')' in for '(' type elem in collection ')' with all of these.
-  ReplaceText(lparenLoc, 1, buf);
-
-  ///            __continue_label: ;
-  ///        } while (counter < limit);
-  ///   } while ((limit = [l_collection countByEnumeratingWithState:&enumState
-  ///                                  objects:__rw_items count:16]));
-  ///   elem = nil;
-  ///   __break_label: ;
-  ///  }
-  ///  else
-  ///       elem = nil;
-  ///  }
-  ///
-  buf = ";\n\t";
-  buf += "__continue_label_";
-  buf += utostr(ObjCBcLabelNo.back());
-  buf += ": ;";
-  buf += "\n\t\t";
-  buf += "} while (counter < limit);\n\t";
-  buf += "} while ((limit = ";
-  SynthCountByEnumWithState(buf);
-  buf += "));\n\t";
-  buf += elementName;
-  buf += " = ((";
-  buf += elementTypeAsString;
-  buf += ")0);\n\t";
-  buf += "__break_label_";
-  buf += utostr(ObjCBcLabelNo.back());
-  buf += ": ;\n\t";
-  buf += "}\n\t";
-  buf += "else\n\t\t";
-  buf += elementName;
-  buf += " = ((";
-  buf += elementTypeAsString;
-  buf += ")0);\n\t";
-  buf += "}\n";
-
-  // Insert all these *after* the statement body.
-  // FIXME: If this should support Obj-C++, support CXXTryStmt
-  if (isa<CompoundStmt>(S->getBody())) {
-    SourceLocation endBodyLoc = OrigEnd.getLocWithOffset(1);
-    InsertText(endBodyLoc, buf);
-  } else {
-    /* Need to treat single statements specially. For example:
-     *
-     *     for (A *a in b) if (stuff()) break;
-     *     for (A *a in b) xxxyy;
-     *
-     * The following code simply scans ahead to the semi to find the actual end.
-     */
-    const char *stmtBuf = SM->getCharacterData(OrigEnd);
-    const char *semiBuf = strchr(stmtBuf, ';');
-    assert(semiBuf && "Can't find ';'");
-    SourceLocation endBodyLoc = OrigEnd.getLocWithOffset(semiBuf-stmtBuf+1);
-    InsertText(endBodyLoc, buf);
-  }
-  Stmts.pop_back();
-  ObjCBcLabelNo.pop_back();
-  return 0;
-}
-
-static void Write_RethrowObject(std::string &buf) {
-  buf += "{ struct _FIN { _FIN(id reth) : rethrow(reth) {}\n";
-  buf += "\t~_FIN() { if (rethrow) objc_exception_throw(rethrow); }\n";
-  buf += "\tid rethrow;\n";
-  buf += "\t} _fin_force_rethow(_rethrow);";
-}
-
-/// RewriteObjCSynchronizedStmt -
-/// This routine rewrites @synchronized(expr) stmt;
-/// into:
-/// objc_sync_enter(expr);
-/// @try stmt @finally { objc_sync_exit(expr); }
-///
-Stmt *RewriteModernObjC::RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
-  // Get the start location and compute the semi location.
-  SourceLocation startLoc = S->getLocStart();
-  const char *startBuf = SM->getCharacterData(startLoc);
-
-  assert((*startBuf == '@') && "bogus @synchronized location");
-
-  std::string buf;
-  SourceLocation SynchLoc = S->getAtSynchronizedLoc();
-  ConvertSourceLocationToLineDirective(SynchLoc, buf);
-  buf += "{ id _rethrow = 0; id _sync_obj = (id)";
-  
-  const char *lparenBuf = startBuf;
-  while (*lparenBuf != '(') lparenBuf++;
-  ReplaceText(startLoc, lparenBuf-startBuf+1, buf);
-  
-  buf = "; objc_sync_enter(_sync_obj);\n";
-  buf += "try {\n\tstruct _SYNC_EXIT { _SYNC_EXIT(id arg) : sync_exit(arg) {}";
-  buf += "\n\t~_SYNC_EXIT() {objc_sync_exit(sync_exit);}";
-  buf += "\n\tid sync_exit;";
-  buf += "\n\t} _sync_exit(_sync_obj);\n";
-
-  // We can't use S->getSynchExpr()->getLocEnd() to find the end location, since
-  // the sync expression is typically a message expression that's already
-  // been rewritten! (which implies the SourceLocation's are invalid).
-  SourceLocation RParenExprLoc = S->getSynchBody()->getLocStart();
-  const char *RParenExprLocBuf = SM->getCharacterData(RParenExprLoc);
-  while (*RParenExprLocBuf != ')') RParenExprLocBuf--;
-  RParenExprLoc = startLoc.getLocWithOffset(RParenExprLocBuf-startBuf);
-  
-  SourceLocation LBranceLoc = S->getSynchBody()->getLocStart();
-  const char *LBraceLocBuf = SM->getCharacterData(LBranceLoc);
-  assert (*LBraceLocBuf == '{');
-  ReplaceText(RParenExprLoc, (LBraceLocBuf - SM->getCharacterData(RParenExprLoc) + 1), buf);
-  
-  SourceLocation startRBraceLoc = S->getSynchBody()->getLocEnd();
-  assert((*SM->getCharacterData(startRBraceLoc) == '}') &&
-         "bogus @synchronized block");
-  
-  buf = "} catch (id e) {_rethrow = e;}\n";
-  Write_RethrowObject(buf);
-  buf += "}\n";
-  buf += "}\n";
-
-  ReplaceText(startRBraceLoc, 1, buf);
-
-  return 0;
-}
-
-void RewriteModernObjC::WarnAboutReturnGotoStmts(Stmt *S)
-{
-  // Perform a bottom up traversal of all children.
-  for (Stmt::child_range CI = S->children(); CI; ++CI)
-    if (*CI)
-      WarnAboutReturnGotoStmts(*CI);
-
-  if (isa<ReturnStmt>(S) || isa<GotoStmt>(S)) {
-    Diags.Report(Context->getFullLoc(S->getLocStart()),
-                 TryFinallyContainsReturnDiag);
-  }
-  return;
-}
-
-Stmt *RewriteModernObjC::RewriteObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt  *S) {
-  SourceLocation startLoc = S->getAtLoc();
-  ReplaceText(startLoc, strlen("@autoreleasepool"), "/* @autoreleasepool */");
-  ReplaceText(S->getSubStmt()->getLocStart(), 1, 
-              "{ __AtAutoreleasePool __autoreleasepool; ");
-  
-  return 0;
-}
-
-Stmt *RewriteModernObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
-  ObjCAtFinallyStmt *finalStmt = S->getFinallyStmt();
-  bool noCatch = S->getNumCatchStmts() == 0;
-  std::string buf;
-  SourceLocation TryLocation = S->getAtTryLoc();
-  ConvertSourceLocationToLineDirective(TryLocation, buf);
-  
-  if (finalStmt) {
-    if (noCatch)
-      buf += "{ id volatile _rethrow = 0;\n";
-    else {
-      buf += "{ id volatile _rethrow = 0;\ntry {\n";
-    }
-  }
-  // Get the start location and compute the semi location.
-  SourceLocation startLoc = S->getLocStart();
-  const char *startBuf = SM->getCharacterData(startLoc);
-
-  assert((*startBuf == '@') && "bogus @try location");
-  if (finalStmt)
-    ReplaceText(startLoc, 1, buf);
-  else
-    // @try -> try
-    ReplaceText(startLoc, 1, "");
-  
-  for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
-    ObjCAtCatchStmt *Catch = S->getCatchStmt(I);
-    VarDecl *catchDecl = Catch->getCatchParamDecl();
-    
-    startLoc = Catch->getLocStart();
-    bool AtRemoved = false;
-    if (catchDecl) {
-      QualType t = catchDecl->getType();
-      if (const ObjCObjectPointerType *Ptr = t->getAs<ObjCObjectPointerType>()) {
-        // Should be a pointer to a class.
-        ObjCInterfaceDecl *IDecl = Ptr->getObjectType()->getInterface();
-        if (IDecl) {
-          std::string Result;
-          ConvertSourceLocationToLineDirective(Catch->getLocStart(), Result);
-          
-          startBuf = SM->getCharacterData(startLoc);
-          assert((*startBuf == '@') && "bogus @catch location");
-          SourceLocation rParenLoc = Catch->getRParenLoc();
-          const char *rParenBuf = SM->getCharacterData(rParenLoc);
-          
-          // _objc_exc_Foo *_e as argument to catch.
-          Result += "catch (_objc_exc_"; Result += IDecl->getNameAsString();
-          Result += " *_"; Result += catchDecl->getNameAsString();
-          Result += ")";
-          ReplaceText(startLoc, rParenBuf-startBuf+1, Result);
-          // Foo *e = (Foo *)_e;
-          Result.clear();
-          Result = "{ ";
-          Result += IDecl->getNameAsString();
-          Result += " *"; Result += catchDecl->getNameAsString();
-          Result += " = ("; Result += IDecl->getNameAsString(); Result += "*)";
-          Result += "_"; Result += catchDecl->getNameAsString();
-          
-          Result += "; ";
-          SourceLocation lBraceLoc = Catch->getCatchBody()->getLocStart();
-          ReplaceText(lBraceLoc, 1, Result);
-          AtRemoved = true;
-        }
-      }
-    }
-    if (!AtRemoved)
-      // @catch -> catch
-      ReplaceText(startLoc, 1, "");
-      
-  }
-  if (finalStmt) {
-    buf.clear();
-    SourceLocation FinallyLoc = finalStmt->getLocStart();
-    
-    if (noCatch) {
-      ConvertSourceLocationToLineDirective(FinallyLoc, buf);
-      buf += "catch (id e) {_rethrow = e;}\n";
-    }
-    else {
-      buf += "}\n";
-      ConvertSourceLocationToLineDirective(FinallyLoc, buf);
-      buf += "catch (id e) {_rethrow = e;}\n";
-    }
-    
-    SourceLocation startFinalLoc = finalStmt->getLocStart();
-    ReplaceText(startFinalLoc, 8, buf);
-    Stmt *body = finalStmt->getFinallyBody();
-    SourceLocation startFinalBodyLoc = body->getLocStart();
-    buf.clear();
-    Write_RethrowObject(buf);
-    ReplaceText(startFinalBodyLoc, 1, buf);
-    
-    SourceLocation endFinalBodyLoc = body->getLocEnd();
-    ReplaceText(endFinalBodyLoc, 1, "}\n}");
-    // Now check for any return/continue/go statements within the @try.
-    WarnAboutReturnGotoStmts(S->getTryBody());
-  }
-
-  return 0;
-}
-
-// This can't be done with ReplaceStmt(S, ThrowExpr), since
-// the throw expression is typically a message expression that's already
-// been rewritten! (which implies the SourceLocation's are invalid).
-Stmt *RewriteModernObjC::RewriteObjCThrowStmt(ObjCAtThrowStmt *S) {
-  // Get the start location and compute the semi location.
-  SourceLocation startLoc = S->getLocStart();
-  const char *startBuf = SM->getCharacterData(startLoc);
-
-  assert((*startBuf == '@') && "bogus @throw location");
-
-  std::string buf;
-  /* void objc_exception_throw(id) __attribute__((noreturn)); */
-  if (S->getThrowExpr())
-    buf = "objc_exception_throw(";
-  else
-    buf = "throw";
-
-  // handle "@  throw" correctly.
-  const char *wBuf = strchr(startBuf, 'w');
-  assert((*wBuf == 'w') && "@throw: can't find 'w'");
-  ReplaceText(startLoc, wBuf-startBuf+1, buf);
-
-  SourceLocation endLoc = S->getLocEnd();
-  const char *endBuf = SM->getCharacterData(endLoc);
-  const char *semiBuf = strchr(endBuf, ';');
-  assert((*semiBuf == ';') && "@throw: can't find ';'");
-  SourceLocation semiLoc = startLoc.getLocWithOffset(semiBuf-startBuf);
-  if (S->getThrowExpr())
-    ReplaceText(semiLoc, 1, ");");
-  return 0;
-}
-
-Stmt *RewriteModernObjC::RewriteAtEncode(ObjCEncodeExpr *Exp) {
-  // Create a new string expression.
-  QualType StrType = Context->getPointerType(Context->CharTy);
-  std::string StrEncoding;
-  Context->getObjCEncodingForType(Exp->getEncodedType(), StrEncoding);
-  Expr *Replacement = StringLiteral::Create(*Context, StrEncoding,
-                                            StringLiteral::Ascii, false,
-                                            StrType, SourceLocation());
-  ReplaceStmt(Exp, Replacement);
-
-  // Replace this subexpr in the parent.
-  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
-  return Replacement;
-}
-
-Stmt *RewriteModernObjC::RewriteAtSelector(ObjCSelectorExpr *Exp) {
-  if (!SelGetUidFunctionDecl)
-    SynthSelGetUidFunctionDecl();
-  assert(SelGetUidFunctionDecl && "Can't find sel_registerName() decl");
-  // Create a call to sel_registerName("selName").
-  SmallVector<Expr*, 8> SelExprs;
-  QualType argType = Context->getPointerType(Context->CharTy);
-  SelExprs.push_back(StringLiteral::Create(*Context,
-                                           Exp->getSelector().getAsString(),
-                                           StringLiteral::Ascii, false,
-                                           argType, SourceLocation()));
-  CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
-                                                 &SelExprs[0], SelExprs.size());
-  ReplaceStmt(Exp, SelExp);
-  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
-  return SelExp;
-}
-
-CallExpr *RewriteModernObjC::SynthesizeCallToFunctionDecl(
-  FunctionDecl *FD, Expr **args, unsigned nargs, SourceLocation StartLoc,
-                                                    SourceLocation EndLoc) {
-  // Get the type, we will need to reference it in a couple spots.
-  QualType msgSendType = FD->getType();
-
-  // Create a reference to the objc_msgSend() declaration.
-  DeclRefExpr *DRE =
-    new (Context) DeclRefExpr(FD, false, msgSendType, VK_LValue, SourceLocation());
-
-  // Now, we cast the reference to a pointer to the objc_msgSend type.
-  QualType pToFunc = Context->getPointerType(msgSendType);
-  ImplicitCastExpr *ICE = 
-    ImplicitCastExpr::Create(*Context, pToFunc, CK_FunctionToPointerDecay,
-                             DRE, 0, VK_RValue);
-
-  const FunctionType *FT = msgSendType->getAs<FunctionType>();
-
-  CallExpr *Exp =  
-    new (Context) CallExpr(*Context, ICE, llvm::makeArrayRef(args, nargs),
-                           FT->getCallResultType(*Context),
-                           VK_RValue, EndLoc);
-  return Exp;
-}
-
-static bool scanForProtocolRefs(const char *startBuf, const char *endBuf,
-                                const char *&startRef, const char *&endRef) {
-  while (startBuf < endBuf) {
-    if (*startBuf == '<')
-      startRef = startBuf; // mark the start.
-    if (*startBuf == '>') {
-      if (startRef && *startRef == '<') {
-        endRef = startBuf; // mark the end.
-        return true;
-      }
-      return false;
-    }
-    startBuf++;
-  }
-  return false;
-}
-
-static void scanToNextArgument(const char *&argRef) {
-  int angle = 0;
-  while (*argRef != ')' && (*argRef != ',' || angle > 0)) {
-    if (*argRef == '<')
-      angle++;
-    else if (*argRef == '>')
-      angle--;
-    argRef++;
-  }
-  assert(angle == 0 && "scanToNextArgument - bad protocol type syntax");
-}
-
-bool RewriteModernObjC::needToScanForQualifiers(QualType T) {
-  if (T->isObjCQualifiedIdType())
-    return true;
-  if (const PointerType *PT = T->getAs<PointerType>()) {
-    if (PT->getPointeeType()->isObjCQualifiedIdType())
-      return true;
-  }
-  if (T->isObjCObjectPointerType()) {
-    T = T->getPointeeType();
-    return T->isObjCQualifiedInterfaceType();
-  }
-  if (T->isArrayType()) {
-    QualType ElemTy = Context->getBaseElementType(T);
-    return needToScanForQualifiers(ElemTy);
-  }
-  return false;
-}
-
-void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(Expr *E) {
-  QualType Type = E->getType();
-  if (needToScanForQualifiers(Type)) {
-    SourceLocation Loc, EndLoc;
-
-    if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E)) {
-      Loc = ECE->getLParenLoc();
-      EndLoc = ECE->getRParenLoc();
-    } else {
-      Loc = E->getLocStart();
-      EndLoc = E->getLocEnd();
-    }
-    // This will defend against trying to rewrite synthesized expressions.
-    if (Loc.isInvalid() || EndLoc.isInvalid())
-      return;
-
-    const char *startBuf = SM->getCharacterData(Loc);
-    const char *endBuf = SM->getCharacterData(EndLoc);
-    const char *startRef = 0, *endRef = 0;
-    if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
-      // Get the locations of the startRef, endRef.
-      SourceLocation LessLoc = Loc.getLocWithOffset(startRef-startBuf);
-      SourceLocation GreaterLoc = Loc.getLocWithOffset(endRef-startBuf+1);
-      // Comment out the protocol references.
-      InsertText(LessLoc, "/*");
-      InsertText(GreaterLoc, "*/");
-    }
-  }
-}
-
-void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(Decl *Dcl) {
-  SourceLocation Loc;
-  QualType Type;
-  const FunctionProtoType *proto = 0;
-  if (VarDecl *VD = dyn_cast<VarDecl>(Dcl)) {
-    Loc = VD->getLocation();
-    Type = VD->getType();
-  }
-  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(Dcl)) {
-    Loc = FD->getLocation();
-    // Check for ObjC 'id' and class types that have been adorned with protocol
-    // information (id<p>, C<p>*). The protocol references need to be rewritten!
-    const FunctionType *funcType = FD->getType()->getAs<FunctionType>();
-    assert(funcType && "missing function type");
-    proto = dyn_cast<FunctionProtoType>(funcType);
-    if (!proto)
-      return;
-    Type = proto->getResultType();
-  }
-  else if (FieldDecl *FD = dyn_cast<FieldDecl>(Dcl)) {
-    Loc = FD->getLocation();
-    Type = FD->getType();
-  }
-  else if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(Dcl)) {
-    Loc = TD->getLocation();
-    Type = TD->getUnderlyingType();
-  }
-  else
-    return;
-
-  if (needToScanForQualifiers(Type)) {
-    // Since types are unique, we need to scan the buffer.
-
-    const char *endBuf = SM->getCharacterData(Loc);
-    const char *startBuf = endBuf;
-    while (*startBuf != ';' && *startBuf != '<' && startBuf != MainFileStart)
-      startBuf--; // scan backward (from the decl location) for return type.
-    const char *startRef = 0, *endRef = 0;
-    if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
-      // Get the locations of the startRef, endRef.
-      SourceLocation LessLoc = Loc.getLocWithOffset(startRef-endBuf);
-      SourceLocation GreaterLoc = Loc.getLocWithOffset(endRef-endBuf+1);
-      // Comment out the protocol references.
-      InsertText(LessLoc, "/*");
-      InsertText(GreaterLoc, "*/");
-    }
-  }
-  if (!proto)
-      return; // most likely, was a variable
-  // Now check arguments.
-  const char *startBuf = SM->getCharacterData(Loc);
-  const char *startFuncBuf = startBuf;
-  for (unsigned i = 0; i < proto->getNumArgs(); i++) {
-    if (needToScanForQualifiers(proto->getArgType(i))) {
-      // Since types are unique, we need to scan the buffer.
-
-      const char *endBuf = startBuf;
-      // scan forward (from the decl location) for argument types.
-      scanToNextArgument(endBuf);
-      const char *startRef = 0, *endRef = 0;
-      if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
-        // Get the locations of the startRef, endRef.
-        SourceLocation LessLoc =
-          Loc.getLocWithOffset(startRef-startFuncBuf);
-        SourceLocation GreaterLoc =
-          Loc.getLocWithOffset(endRef-startFuncBuf+1);
-        // Comment out the protocol references.
-        InsertText(LessLoc, "/*");
-        InsertText(GreaterLoc, "*/");
-      }
-      startBuf = ++endBuf;
-    }
-    else {
-      // If the function name is derived from a macro expansion, then the
-      // argument buffer will not follow the name. Need to speak with Chris.
-      while (*startBuf && *startBuf != ')' && *startBuf != ',')
-        startBuf++; // scan forward (from the decl location) for argument types.
-      startBuf++;
-    }
-  }
-}
-
-void RewriteModernObjC::RewriteTypeOfDecl(VarDecl *ND) {
-  QualType QT = ND->getType();
-  const Type* TypePtr = QT->getAs<Type>();
-  if (!isa<TypeOfExprType>(TypePtr))
-    return;
-  while (isa<TypeOfExprType>(TypePtr)) {
-    const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
-    QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType();
-    TypePtr = QT->getAs<Type>();
-  }
-  // FIXME. This will not work for multiple declarators; as in:
-  // __typeof__(a) b,c,d;
-  std::string TypeAsString(QT.getAsString(Context->getPrintingPolicy()));
-  SourceLocation DeclLoc = ND->getTypeSpecStartLoc();
-  const char *startBuf = SM->getCharacterData(DeclLoc);
-  if (ND->getInit()) {
-    std::string Name(ND->getNameAsString());
-    TypeAsString += " " + Name + " = ";
-    Expr *E = ND->getInit();
-    SourceLocation startLoc;
-    if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E))
-      startLoc = ECE->getLParenLoc();
-    else
-      startLoc = E->getLocStart();
-    startLoc = SM->getExpansionLoc(startLoc);
-    const char *endBuf = SM->getCharacterData(startLoc);
-    ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
-  }
-  else {
-    SourceLocation X = ND->getLocEnd();
-    X = SM->getExpansionLoc(X);
-    const char *endBuf = SM->getCharacterData(X);
-    ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
-  }
-}
-
-// SynthSelGetUidFunctionDecl - SEL sel_registerName(const char *str);
-void RewriteModernObjC::SynthSelGetUidFunctionDecl() {
-  IdentifierInfo *SelGetUidIdent = &Context->Idents.get("sel_registerName");
-  SmallVector<QualType, 16> ArgTys;
-  ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
-  QualType getFuncType =
-    getSimpleFunctionType(Context->getObjCSelType(), ArgTys);
-  SelGetUidFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
-                                               SourceLocation(),
-                                               SourceLocation(),
-                                               SelGetUidIdent, getFuncType, 0,
-                                               SC_Extern);
-}
-
-void RewriteModernObjC::RewriteFunctionDecl(FunctionDecl *FD) {
-  // declared in <objc/objc.h>
-  if (FD->getIdentifier() &&
-      FD->getName() == "sel_registerName") {
-    SelGetUidFunctionDecl = FD;
-    return;
-  }
-  RewriteObjCQualifiedInterfaceTypes(FD);
-}
-
-void RewriteModernObjC::RewriteBlockPointerType(std::string& Str, QualType Type) {
-  std::string TypeString(Type.getAsString(Context->getPrintingPolicy()));
-  const char *argPtr = TypeString.c_str();
-  if (!strchr(argPtr, '^')) {
-    Str += TypeString;
-    return;
-  }
-  while (*argPtr) {
-    Str += (*argPtr == '^' ? '*' : *argPtr);
-    argPtr++;
-  }
-}
-
-// FIXME. Consolidate this routine with RewriteBlockPointerType.
-void RewriteModernObjC::RewriteBlockPointerTypeVariable(std::string& Str,
-                                                  ValueDecl *VD) {
-  QualType Type = VD->getType();
-  std::string TypeString(Type.getAsString(Context->getPrintingPolicy()));
-  const char *argPtr = TypeString.c_str();
-  int paren = 0;
-  while (*argPtr) {
-    switch (*argPtr) {
-      case '(':
-        Str += *argPtr;
-        paren++;
-        break;
-      case ')':
-        Str += *argPtr;
-        paren--;
-        break;
-      case '^':
-        Str += '*';
-        if (paren == 1)
-          Str += VD->getNameAsString();
-        break;
-      default:
-        Str += *argPtr;
-        break;
-    }
-    argPtr++;
-  }
-}
-
-void RewriteModernObjC::RewriteBlockLiteralFunctionDecl(FunctionDecl *FD) {
-  SourceLocation FunLocStart = FD->getTypeSpecStartLoc();
-  const FunctionType *funcType = FD->getType()->getAs<FunctionType>();
-  const FunctionProtoType *proto = dyn_cast<FunctionProtoType>(funcType);
-  if (!proto)
-    return;
-  QualType Type = proto->getResultType();
-  std::string FdStr = Type.getAsString(Context->getPrintingPolicy());
-  FdStr += " ";
-  FdStr += FD->getName();
-  FdStr +=  "(";
-  unsigned numArgs = proto->getNumArgs();
-  for (unsigned i = 0; i < numArgs; i++) {
-  QualType ArgType = proto->getArgType(i);
-  RewriteBlockPointerType(FdStr, ArgType);
-  if (i+1 < numArgs)
-    FdStr += ", ";
-  }
-  if (FD->isVariadic()) {
-    FdStr +=  (numArgs > 0) ? ", ...);\n" : "...);\n";
-  }
-  else
-    FdStr +=  ");\n";
-  InsertText(FunLocStart, FdStr);
-}
-
-// SynthSuperConstructorFunctionDecl - id __rw_objc_super(id obj, id super);
-void RewriteModernObjC::SynthSuperConstructorFunctionDecl() {
-  if (SuperConstructorFunctionDecl)
-    return;
-  IdentifierInfo *msgSendIdent = &Context->Idents.get("__rw_objc_super");
-  SmallVector<QualType, 16> ArgTys;
-  QualType argT = Context->getObjCIdType();
-  assert(!argT.isNull() && "Can't find 'id' type");
-  ArgTys.push_back(argT);
-  ArgTys.push_back(argT);
-  QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
-                                               ArgTys);
-  SuperConstructorFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
-                                                     SourceLocation(),
-                                                     SourceLocation(),
-                                                     msgSendIdent, msgSendType,
-                                                     0, SC_Extern);
-}
-
-// SynthMsgSendFunctionDecl - id objc_msgSend(id self, SEL op, ...);
-void RewriteModernObjC::SynthMsgSendFunctionDecl() {
-  IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend");
-  SmallVector<QualType, 16> ArgTys;
-  QualType argT = Context->getObjCIdType();
-  assert(!argT.isNull() && "Can't find 'id' type");
-  ArgTys.push_back(argT);
-  argT = Context->getObjCSelType();
-  assert(!argT.isNull() && "Can't find 'SEL' type");
-  ArgTys.push_back(argT);
-  QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
-                                               ArgTys, /*isVariadic=*/true);
-  MsgSendFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
-                                             SourceLocation(),
-                                             SourceLocation(),
-                                             msgSendIdent, msgSendType, 0,
-                                             SC_Extern);
-}
-
-// SynthMsgSendSuperFunctionDecl - id objc_msgSendSuper(void);
-void RewriteModernObjC::SynthMsgSendSuperFunctionDecl() {
-  IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSendSuper");
-  SmallVector<QualType, 2> ArgTys;
-  ArgTys.push_back(Context->VoidTy);
-  QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
-                                               ArgTys, /*isVariadic=*/true);
-  MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
-                                                  SourceLocation(),
-                                                  SourceLocation(),
-                                                  msgSendIdent, msgSendType, 0,
-                                                  SC_Extern);
-}
-
-// SynthMsgSendStretFunctionDecl - id objc_msgSend_stret(id self, SEL op, ...);
-void RewriteModernObjC::SynthMsgSendStretFunctionDecl() {
-  IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_stret");
-  SmallVector<QualType, 16> ArgTys;
-  QualType argT = Context->getObjCIdType();
-  assert(!argT.isNull() && "Can't find 'id' type");
-  ArgTys.push_back(argT);
-  argT = Context->getObjCSelType();
-  assert(!argT.isNull() && "Can't find 'SEL' type");
-  ArgTys.push_back(argT);
-  QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
-                                               ArgTys, /*isVariadic=*/true);
-  MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
-                                                  SourceLocation(),
-                                                  SourceLocation(),
-                                                  msgSendIdent, msgSendType, 0,
-                                                  SC_Extern);
-}
-
-// SynthMsgSendSuperStretFunctionDecl -
-// id objc_msgSendSuper_stret(void);
-void RewriteModernObjC::SynthMsgSendSuperStretFunctionDecl() {
-  IdentifierInfo *msgSendIdent =
-    &Context->Idents.get("objc_msgSendSuper_stret");
-  SmallVector<QualType, 2> ArgTys;
-  ArgTys.push_back(Context->VoidTy);
-  QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
-                                               ArgTys, /*isVariadic=*/true);
-  MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
-                                                       SourceLocation(),
-                                                       SourceLocation(),
-                                                       msgSendIdent,
-                                                       msgSendType, 0,
-                                                       SC_Extern);
-}
-
-// SynthMsgSendFpretFunctionDecl - double objc_msgSend_fpret(id self, SEL op, ...);
-void RewriteModernObjC::SynthMsgSendFpretFunctionDecl() {
-  IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_fpret");
-  SmallVector<QualType, 16> ArgTys;
-  QualType argT = Context->getObjCIdType();
-  assert(!argT.isNull() && "Can't find 'id' type");
-  ArgTys.push_back(argT);
-  argT = Context->getObjCSelType();
-  assert(!argT.isNull() && "Can't find 'SEL' type");
-  ArgTys.push_back(argT);
-  QualType msgSendType = getSimpleFunctionType(Context->DoubleTy,
-                                               ArgTys, /*isVariadic=*/true);
-  MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
-                                                  SourceLocation(),
-                                                  SourceLocation(),
-                                                  msgSendIdent, msgSendType, 0,
-                                                  SC_Extern);
-}
-
-// SynthGetClassFunctionDecl - Class objc_getClass(const char *name);
-void RewriteModernObjC::SynthGetClassFunctionDecl() {
-  IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getClass");
-  SmallVector<QualType, 16> ArgTys;
-  ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
-  QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(),
-                                                ArgTys);
-  GetClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
-                                              SourceLocation(),
-                                              SourceLocation(),
-                                              getClassIdent, getClassType, 0,
-                                              SC_Extern);
-}
-
-// SynthGetSuperClassFunctionDecl - Class class_getSuperclass(Class cls);
-void RewriteModernObjC::SynthGetSuperClassFunctionDecl() {
-  IdentifierInfo *getSuperClassIdent = 
-    &Context->Idents.get("class_getSuperclass");
-  SmallVector<QualType, 16> ArgTys;
-  ArgTys.push_back(Context->getObjCClassType());
-  QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(),
-                                                ArgTys);
-  GetSuperClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
-                                                   SourceLocation(),
-                                                   SourceLocation(),
-                                                   getSuperClassIdent,
-                                                   getClassType, 0,
-                                                   SC_Extern);
-}
-
-// SynthGetMetaClassFunctionDecl - Class objc_getMetaClass(const char *name);
-void RewriteModernObjC::SynthGetMetaClassFunctionDecl() {
-  IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getMetaClass");
-  SmallVector<QualType, 16> ArgTys;
-  ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
-  QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(),
-                                                ArgTys);
-  GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
-                                                  SourceLocation(),
-                                                  SourceLocation(),
-                                                  getClassIdent, getClassType,
-                                                  0, SC_Extern);
-}
-
-Stmt *RewriteModernObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) {
-  QualType strType = getConstantStringStructType();
-
-  std::string S = "__NSConstantStringImpl_";
-
-  std::string tmpName = InFileName;
-  unsigned i;
-  for (i=0; i < tmpName.length(); i++) {
-    char c = tmpName.at(i);
-    // replace any non alphanumeric characters with '_'.
-    if (!isAlphanumeric(c))
-      tmpName[i] = '_';
-  }
-  S += tmpName;
-  S += "_";
-  S += utostr(NumObjCStringLiterals++);
-
-  Preamble += "static __NSConstantStringImpl " + S;
-  Preamble += " __attribute__ ((section (\"__DATA, __cfstring\"))) = {__CFConstantStringClassReference,";
-  Preamble += "0x000007c8,"; // utf8_str
-  // The pretty printer for StringLiteral handles escape characters properly.
-  std::string prettyBufS;
-  llvm::raw_string_ostream prettyBuf(prettyBufS);
-  Exp->getString()->printPretty(prettyBuf, 0, PrintingPolicy(LangOpts));
-  Preamble += prettyBuf.str();
-  Preamble += ",";
-  Preamble += utostr(Exp->getString()->getByteLength()) + "};\n";
-
-  VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
-                                   SourceLocation(), &Context->Idents.get(S),
-                                   strType, 0, SC_Static);
-  DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, false, strType, VK_LValue,
-                                               SourceLocation());
-  Expr *Unop = new (Context) UnaryOperator(DRE, UO_AddrOf,
-                                 Context->getPointerType(DRE->getType()),
-                                           VK_RValue, OK_Ordinary,
-                                           SourceLocation());
-  // cast to NSConstantString *
-  CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Exp->getType(),
-                                            CK_CPointerToObjCPointerCast, Unop);
-  ReplaceStmt(Exp, cast);
-  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
-  return cast;
-}
-
-Stmt *RewriteModernObjC::RewriteObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Exp) {
-  unsigned IntSize =
-    static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
-  
-  Expr *FlagExp = IntegerLiteral::Create(*Context, 
-                                         llvm::APInt(IntSize, Exp->getValue()), 
-                                         Context->IntTy, Exp->getLocation());
-  CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Context->ObjCBuiltinBoolTy,
-                                            CK_BitCast, FlagExp);
-  ParenExpr *PE = new (Context) ParenExpr(Exp->getLocation(), Exp->getExprLoc(), 
-                                          cast);
-  ReplaceStmt(Exp, PE);
-  return PE;
-}
-
-Stmt *RewriteModernObjC::RewriteObjCBoxedExpr(ObjCBoxedExpr *Exp) {
-  // synthesize declaration of helper functions needed in this routine.
-  if (!SelGetUidFunctionDecl)
-    SynthSelGetUidFunctionDecl();
-  // use objc_msgSend() for all.
-  if (!MsgSendFunctionDecl)
-    SynthMsgSendFunctionDecl();
-  if (!GetClassFunctionDecl)
-    SynthGetClassFunctionDecl();
-  
-  FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl;
-  SourceLocation StartLoc = Exp->getLocStart();
-  SourceLocation EndLoc = Exp->getLocEnd();
-  
-  // Synthesize a call to objc_msgSend().
-  SmallVector<Expr*, 4> MsgExprs;
-  SmallVector<Expr*, 4> ClsExprs;
-  QualType argType = Context->getPointerType(Context->CharTy);
-  
-  // Create a call to objc_getClass("<BoxingClass>"). It will be the 1st argument.
-  ObjCMethodDecl *BoxingMethod = Exp->getBoxingMethod();
-  ObjCInterfaceDecl *BoxingClass = BoxingMethod->getClassInterface();
-  
-  IdentifierInfo *clsName = BoxingClass->getIdentifier();
-  ClsExprs.push_back(StringLiteral::Create(*Context,
-                                           clsName->getName(),
-                                           StringLiteral::Ascii, false,
-                                           argType, SourceLocation()));
-  CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
-                                               &ClsExprs[0],
-                                               ClsExprs.size(), 
-                                               StartLoc, EndLoc);
-  MsgExprs.push_back(Cls);
-  
-  // Create a call to sel_registerName("<BoxingMethod>:"), etc.
-  // it will be the 2nd argument.
-  SmallVector<Expr*, 4> SelExprs;
-  SelExprs.push_back(StringLiteral::Create(*Context,
-                                           BoxingMethod->getSelector().getAsString(),
-                                           StringLiteral::Ascii, false,
-                                           argType, SourceLocation()));
-  CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
-                                                  &SelExprs[0], SelExprs.size(),
-                                                  StartLoc, EndLoc);
-  MsgExprs.push_back(SelExp);
-  
-  // User provided sub-expression is the 3rd, and last, argument.
-  Expr *subExpr  = Exp->getSubExpr();
-  if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(subExpr)) {
-    QualType type = ICE->getType();
-    const Expr *SubExpr = ICE->IgnoreParenImpCasts();
-    CastKind CK = CK_BitCast;
-    if (SubExpr->getType()->isIntegralType(*Context) && type->isBooleanType())
-      CK = CK_IntegralToBoolean;
-    subExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, subExpr);
-  }
-  MsgExprs.push_back(subExpr);
-  
-  SmallVector<QualType, 4> ArgTypes;
-  ArgTypes.push_back(Context->getObjCIdType());
-  ArgTypes.push_back(Context->getObjCSelType());
-  for (ObjCMethodDecl::param_iterator PI = BoxingMethod->param_begin(),
-       E = BoxingMethod->param_end(); PI != E; ++PI)
-    ArgTypes.push_back((*PI)->getType());
-  
-  QualType returnType = Exp->getType();
-  // Get the type, we will need to reference it in a couple spots.
-  QualType msgSendType = MsgSendFlavor->getType();
-  
-  // Create a reference to the objc_msgSend() declaration.
-  DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType,
-                                               VK_LValue, SourceLocation());
-  
-  CastExpr *cast = NoTypeInfoCStyleCastExpr(Context,
-                                            Context->getPointerType(Context->VoidTy),
-                                            CK_BitCast, DRE);
-  
-  // Now do the "normal" pointer to function cast.
-  QualType castType =
-    getSimpleFunctionType(returnType, ArgTypes, BoxingMethod->isVariadic());
-  castType = Context->getPointerType(castType);
-  cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
-                                  cast);
-  
-  // Don't forget the parens to enforce the proper binding.
-  ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
-  
-  const FunctionType *FT = msgSendType->getAs<FunctionType>();
-  CallExpr *CE = new (Context) CallExpr(*Context, PE, MsgExprs,
-                                        FT->getResultType(), VK_RValue,
-                                        EndLoc);
-  ReplaceStmt(Exp, CE);
-  return CE;
-}
-
-Stmt *RewriteModernObjC::RewriteObjCArrayLiteralExpr(ObjCArrayLiteral *Exp) {
-  // synthesize declaration of helper functions needed in this routine.
-  if (!SelGetUidFunctionDecl)
-    SynthSelGetUidFunctionDecl();
-  // use objc_msgSend() for all.
-  if (!MsgSendFunctionDecl)
-    SynthMsgSendFunctionDecl();
-  if (!GetClassFunctionDecl)
-    SynthGetClassFunctionDecl();
-  
-  FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl;
-  SourceLocation StartLoc = Exp->getLocStart();
-  SourceLocation EndLoc = Exp->getLocEnd();
-  
-  // Build the expression: __NSContainer_literal(int, ...).arr
-  QualType IntQT = Context->IntTy;
-  QualType NSArrayFType =
-    getSimpleFunctionType(Context->VoidTy, IntQT, true);
-  std::string NSArrayFName("__NSContainer_literal");
-  FunctionDecl *NSArrayFD = SynthBlockInitFunctionDecl(NSArrayFName);
-  DeclRefExpr *NSArrayDRE = 
-    new (Context) DeclRefExpr(NSArrayFD, false, NSArrayFType, VK_RValue,
-                              SourceLocation());
-
-  SmallVector<Expr*, 16> InitExprs;
-  unsigned NumElements = Exp->getNumElements();
-  unsigned UnsignedIntSize = 
-    static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
-  Expr *count = IntegerLiteral::Create(*Context,
-                                       llvm::APInt(UnsignedIntSize, NumElements),
-                                       Context->UnsignedIntTy, SourceLocation());
-  InitExprs.push_back(count);
-  for (unsigned i = 0; i < NumElements; i++)
-    InitExprs.push_back(Exp->getElement(i));
-  Expr *NSArrayCallExpr = 
-    new (Context) CallExpr(*Context, NSArrayDRE, InitExprs,
-                           NSArrayFType, VK_LValue, SourceLocation());
-  
-  FieldDecl *ARRFD = FieldDecl::Create(*Context, 0, SourceLocation(),
-                                    SourceLocation(),
-                                    &Context->Idents.get("arr"),
-                                    Context->getPointerType(Context->VoidPtrTy), 0,
-                                    /*BitWidth=*/0, /*Mutable=*/true,
-                                    ICIS_NoInit);
-  MemberExpr *ArrayLiteralME = 
-    new (Context) MemberExpr(NSArrayCallExpr, false, ARRFD, 
-                             SourceLocation(),
-                             ARRFD->getType(), VK_LValue,
-                             OK_Ordinary);
-  QualType ConstIdT = Context->getObjCIdType().withConst();
-  CStyleCastExpr * ArrayLiteralObjects = 
-    NoTypeInfoCStyleCastExpr(Context, 
-                             Context->getPointerType(ConstIdT),
-                             CK_BitCast,
-                             ArrayLiteralME);
-  
-  // Synthesize a call to objc_msgSend().
-  SmallVector<Expr*, 32> MsgExprs;
-  SmallVector<Expr*, 4> ClsExprs;
-  QualType argType = Context->getPointerType(Context->CharTy);
-  QualType expType = Exp->getType();
-  
-  // Create a call to objc_getClass("NSArray"). It will be th 1st argument.
-  ObjCInterfaceDecl *Class = 
-    expType->getPointeeType()->getAs<ObjCObjectType>()->getInterface();
-  
-  IdentifierInfo *clsName = Class->getIdentifier();
-  ClsExprs.push_back(StringLiteral::Create(*Context,
-                                           clsName->getName(),
-                                           StringLiteral::Ascii, false,
-                                           argType, SourceLocation()));
-  CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
-                                               &ClsExprs[0],
-                                               ClsExprs.size(), 
-                                               StartLoc, EndLoc);
-  MsgExprs.push_back(Cls);
-  
-  // Create a call to sel_registerName("arrayWithObjects:count:").
-  // it will be the 2nd argument.
-  SmallVector<Expr*, 4> SelExprs;
-  ObjCMethodDecl *ArrayMethod = Exp->getArrayWithObjectsMethod();
-  SelExprs.push_back(StringLiteral::Create(*Context,
-                                           ArrayMethod->getSelector().getAsString(),
-                                           StringLiteral::Ascii, false,
-                                           argType, SourceLocation()));
-  CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
-                                                  &SelExprs[0], SelExprs.size(),
-                                                  StartLoc, EndLoc);
-  MsgExprs.push_back(SelExp);
-  
-  // (const id [])objects
-  MsgExprs.push_back(ArrayLiteralObjects);
-  
-  // (NSUInteger)cnt
-  Expr *cnt = IntegerLiteral::Create(*Context,
-                                     llvm::APInt(UnsignedIntSize, NumElements),
-                                     Context->UnsignedIntTy, SourceLocation());
-  MsgExprs.push_back(cnt);
-  
-  
-  SmallVector<QualType, 4> ArgTypes;
-  ArgTypes.push_back(Context->getObjCIdType());
-  ArgTypes.push_back(Context->getObjCSelType());
-  for (ObjCMethodDecl::param_iterator PI = ArrayMethod->param_begin(),
-       E = ArrayMethod->param_end(); PI != E; ++PI)
-    ArgTypes.push_back((*PI)->getType());
-  
-  QualType returnType = Exp->getType();
-  // Get the type, we will need to reference it in a couple spots.
-  QualType msgSendType = MsgSendFlavor->getType();
-  
-  // Create a reference to the objc_msgSend() declaration.
-  DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType,
-                                               VK_LValue, SourceLocation());
-  
-  CastExpr *cast = NoTypeInfoCStyleCastExpr(Context,
-                                            Context->getPointerType(Context->VoidTy),
-                                            CK_BitCast, DRE);
-  
-  // Now do the "normal" pointer to function cast.
-  QualType castType =
-  getSimpleFunctionType(returnType, ArgTypes, ArrayMethod->isVariadic());
-  castType = Context->getPointerType(castType);
-  cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
-                                  cast);
-  
-  // Don't forget the parens to enforce the proper binding.
-  ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
-  
-  const FunctionType *FT = msgSendType->getAs<FunctionType>();
-  CallExpr *CE = new (Context) CallExpr(*Context, PE, MsgExprs,
-                                        FT->getResultType(), VK_RValue,
-                                        EndLoc);
-  ReplaceStmt(Exp, CE);
-  return CE;
-}
-
-Stmt *RewriteModernObjC::RewriteObjCDictionaryLiteralExpr(ObjCDictionaryLiteral *Exp) {
-  // synthesize declaration of helper functions needed in this routine.
-  if (!SelGetUidFunctionDecl)
-    SynthSelGetUidFunctionDecl();
-  // use objc_msgSend() for all.
-  if (!MsgSendFunctionDecl)
-    SynthMsgSendFunctionDecl();
-  if (!GetClassFunctionDecl)
-    SynthGetClassFunctionDecl();
-  
-  FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl;
-  SourceLocation StartLoc = Exp->getLocStart();
-  SourceLocation EndLoc = Exp->getLocEnd();
-  
-  // Build the expression: __NSContainer_literal(int, ...).arr
-  QualType IntQT = Context->IntTy;
-  QualType NSDictFType =
-    getSimpleFunctionType(Context->VoidTy, IntQT, true);
-  std::string NSDictFName("__NSContainer_literal");
-  FunctionDecl *NSDictFD = SynthBlockInitFunctionDecl(NSDictFName);
-  DeclRefExpr *NSDictDRE = 
-    new (Context) DeclRefExpr(NSDictFD, false, NSDictFType, VK_RValue,
-                              SourceLocation());
-  
-  SmallVector<Expr*, 16> KeyExprs;
-  SmallVector<Expr*, 16> ValueExprs;
-  
-  unsigned NumElements = Exp->getNumElements();
-  unsigned UnsignedIntSize = 
-    static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
-  Expr *count = IntegerLiteral::Create(*Context,
-                                       llvm::APInt(UnsignedIntSize, NumElements),
-                                       Context->UnsignedIntTy, SourceLocation());
-  KeyExprs.push_back(count);
-  ValueExprs.push_back(count);
-  for (unsigned i = 0; i < NumElements; i++) {
-    ObjCDictionaryElement Element = Exp->getKeyValueElement(i);
-    KeyExprs.push_back(Element.Key);
-    ValueExprs.push_back(Element.Value);
-  }
-  
-  // (const id [])objects
-  Expr *NSValueCallExpr = 
-    new (Context) CallExpr(*Context, NSDictDRE, ValueExprs,
-                           NSDictFType, VK_LValue, SourceLocation());
-  
-  FieldDecl *ARRFD = FieldDecl::Create(*Context, 0, SourceLocation(),
-                                       SourceLocation(),
-                                       &Context->Idents.get("arr"),
-                                       Context->getPointerType(Context->VoidPtrTy), 0,
-                                       /*BitWidth=*/0, /*Mutable=*/true,
-                                       ICIS_NoInit);
-  MemberExpr *DictLiteralValueME = 
-    new (Context) MemberExpr(NSValueCallExpr, false, ARRFD, 
-                             SourceLocation(),
-                             ARRFD->getType(), VK_LValue,
-                             OK_Ordinary);
-  QualType ConstIdT = Context->getObjCIdType().withConst();
-  CStyleCastExpr * DictValueObjects = 
-    NoTypeInfoCStyleCastExpr(Context, 
-                             Context->getPointerType(ConstIdT),
-                             CK_BitCast,
-                             DictLiteralValueME);
-  // (const id <NSCopying> [])keys
-  Expr *NSKeyCallExpr = 
-    new (Context) CallExpr(*Context, NSDictDRE, KeyExprs,
-                           NSDictFType, VK_LValue, SourceLocation());
-  
-  MemberExpr *DictLiteralKeyME = 
-    new (Context) MemberExpr(NSKeyCallExpr, false, ARRFD, 
-                             SourceLocation(),
-                             ARRFD->getType(), VK_LValue,
-                             OK_Ordinary);
-  
-  CStyleCastExpr * DictKeyObjects = 
-    NoTypeInfoCStyleCastExpr(Context, 
-                             Context->getPointerType(ConstIdT),
-                             CK_BitCast,
-                             DictLiteralKeyME);
-  
-  
-  
-  // Synthesize a call to objc_msgSend().
-  SmallVector<Expr*, 32> MsgExprs;
-  SmallVector<Expr*, 4> ClsExprs;
-  QualType argType = Context->getPointerType(Context->CharTy);
-  QualType expType = Exp->getType();
-  
-  // Create a call to objc_getClass("NSArray"). It will be th 1st argument.
-  ObjCInterfaceDecl *Class = 
-  expType->getPointeeType()->getAs<ObjCObjectType>()->getInterface();
-  
-  IdentifierInfo *clsName = Class->getIdentifier();
-  ClsExprs.push_back(StringLiteral::Create(*Context,
-                                           clsName->getName(),
-                                           StringLiteral::Ascii, false,
-                                           argType, SourceLocation()));
-  CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
-                                               &ClsExprs[0],
-                                               ClsExprs.size(), 
-                                               StartLoc, EndLoc);
-  MsgExprs.push_back(Cls);
-  
-  // Create a call to sel_registerName("arrayWithObjects:count:").
-  // it will be the 2nd argument.
-  SmallVector<Expr*, 4> SelExprs;
-  ObjCMethodDecl *DictMethod = Exp->getDictWithObjectsMethod();
-  SelExprs.push_back(StringLiteral::Create(*Context,
-                                           DictMethod->getSelector().getAsString(),
-                                           StringLiteral::Ascii, false,
-                                           argType, SourceLocation()));
-  CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
-                                                  &SelExprs[0], SelExprs.size(),
-                                                  StartLoc, EndLoc);
-  MsgExprs.push_back(SelExp);
-  
-  // (const id [])objects
-  MsgExprs.push_back(DictValueObjects);
-  
-  // (const id <NSCopying> [])keys
-  MsgExprs.push_back(DictKeyObjects);
-  
-  // (NSUInteger)cnt
-  Expr *cnt = IntegerLiteral::Create(*Context,
-                                     llvm::APInt(UnsignedIntSize, NumElements),
-                                     Context->UnsignedIntTy, SourceLocation());
-  MsgExprs.push_back(cnt);
-  
-  
-  SmallVector<QualType, 8> ArgTypes;
-  ArgTypes.push_back(Context->getObjCIdType());
-  ArgTypes.push_back(Context->getObjCSelType());
-  for (ObjCMethodDecl::param_iterator PI = DictMethod->param_begin(),
-       E = DictMethod->param_end(); PI != E; ++PI) {
-    QualType T = (*PI)->getType();
-    if (const PointerType* PT = T->getAs<PointerType>()) {
-      QualType PointeeTy = PT->getPointeeType();
-      convertToUnqualifiedObjCType(PointeeTy);
-      T = Context->getPointerType(PointeeTy);
-    }
-    ArgTypes.push_back(T);
-  }
-  
-  QualType returnType = Exp->getType();
-  // Get the type, we will need to reference it in a couple spots.
-  QualType msgSendType = MsgSendFlavor->getType();
-  
-  // Create a reference to the objc_msgSend() declaration.
-  DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType,
-                                               VK_LValue, SourceLocation());
-  
-  CastExpr *cast = NoTypeInfoCStyleCastExpr(Context,
-                                            Context->getPointerType(Context->VoidTy),
-                                            CK_BitCast, DRE);
-  
-  // Now do the "normal" pointer to function cast.
-  QualType castType =
-  getSimpleFunctionType(returnType, ArgTypes, DictMethod->isVariadic());
-  castType = Context->getPointerType(castType);
-  cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
-                                  cast);
-  
-  // Don't forget the parens to enforce the proper binding.
-  ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
-  
-  const FunctionType *FT = msgSendType->getAs<FunctionType>();
-  CallExpr *CE = new (Context) CallExpr(*Context, PE, MsgExprs,
-                                        FT->getResultType(), VK_RValue,
-                                        EndLoc);
-  ReplaceStmt(Exp, CE);
-  return CE;
-}
-
-// struct __rw_objc_super { 
-//   struct objc_object *object; struct objc_object *superClass; 
-// };
-QualType RewriteModernObjC::getSuperStructType() {
-  if (!SuperStructDecl) {
-    SuperStructDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
-                                         SourceLocation(), SourceLocation(),
-                                         &Context->Idents.get("__rw_objc_super"));
-    QualType FieldTypes[2];
-
-    // struct objc_object *object;
-    FieldTypes[0] = Context->getObjCIdType();
-    // struct objc_object *superClass;
-    FieldTypes[1] = Context->getObjCIdType();
-
-    // Create fields
-    for (unsigned i = 0; i < 2; ++i) {
-      SuperStructDecl->addDecl(FieldDecl::Create(*Context, SuperStructDecl,
-                                                 SourceLocation(),
-                                                 SourceLocation(), 0,
-                                                 FieldTypes[i], 0,
-                                                 /*BitWidth=*/0,
-                                                 /*Mutable=*/false,
-                                                 ICIS_NoInit));
-    }
-
-    SuperStructDecl->completeDefinition();
-  }
-  return Context->getTagDeclType(SuperStructDecl);
-}
-
-QualType RewriteModernObjC::getConstantStringStructType() {
-  if (!ConstantStringDecl) {
-    ConstantStringDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
-                                            SourceLocation(), SourceLocation(),
-                         &Context->Idents.get("__NSConstantStringImpl"));
-    QualType FieldTypes[4];
-
-    // struct objc_object *receiver;
-    FieldTypes[0] = Context->getObjCIdType();
-    // int flags;
-    FieldTypes[1] = Context->IntTy;
-    // char *str;
-    FieldTypes[2] = Context->getPointerType(Context->CharTy);
-    // long length;
-    FieldTypes[3] = Context->LongTy;
-
-    // Create fields
-    for (unsigned i = 0; i < 4; ++i) {
-      ConstantStringDecl->addDecl(FieldDecl::Create(*Context,
-                                                    ConstantStringDecl,
-                                                    SourceLocation(),
-                                                    SourceLocation(), 0,
-                                                    FieldTypes[i], 0,
-                                                    /*BitWidth=*/0,
-                                                    /*Mutable=*/true,
-                                                    ICIS_NoInit));
-    }
-
-    ConstantStringDecl->completeDefinition();
-  }
-  return Context->getTagDeclType(ConstantStringDecl);
-}
-
-/// getFunctionSourceLocation - returns start location of a function
-/// definition. Complication arises when function has declared as
-/// extern "C" or extern "C" {...}
-static SourceLocation getFunctionSourceLocation (RewriteModernObjC &R,
-                                                 FunctionDecl *FD) {
-  if (FD->isExternC()  && !FD->isMain()) {
-    const DeclContext *DC = FD->getDeclContext();
-    if (const LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(DC))
-      // if it is extern "C" {...}, return function decl's own location.
-      if (!LSD->getRBraceLoc().isValid())
-        return LSD->getExternLoc();
-  }
-  if (FD->getStorageClass() != SC_None)
-    R.RewriteBlockLiteralFunctionDecl(FD);
-  return FD->getTypeSpecStartLoc();
-}
-
-void RewriteModernObjC::RewriteLineDirective(const Decl *D) {
-  
-  SourceLocation Location = D->getLocation();
-  
-  if (Location.isFileID() && GenerateLineInfo) {
-    std::string LineString("\n#line ");
-    PresumedLoc PLoc = SM->getPresumedLoc(Location);
-    LineString += utostr(PLoc.getLine());
-    LineString += " \"";
-    LineString += Lexer::Stringify(PLoc.getFilename());
-    if (isa<ObjCMethodDecl>(D))
-      LineString += "\"";
-    else LineString += "\"\n";
-    
-    Location = D->getLocStart();
-    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
-      if (FD->isExternC()  && !FD->isMain()) {
-        const DeclContext *DC = FD->getDeclContext();
-        if (const LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(DC))
-          // if it is extern "C" {...}, return function decl's own location.
-          if (!LSD->getRBraceLoc().isValid())
-            Location = LSD->getExternLoc();
-      }
-    }
-    InsertText(Location, LineString);
-  }
-}
-
-/// SynthMsgSendStretCallExpr - This routine translates message expression
-/// into a call to objc_msgSend_stret() entry point. Tricky part is that
-/// nil check on receiver must be performed before calling objc_msgSend_stret.
-/// MsgSendStretFlavor - function declaration objc_msgSend_stret(...)
-/// msgSendType - function type of objc_msgSend_stret(...)
-/// returnType - Result type of the method being synthesized.
-/// ArgTypes - type of the arguments passed to objc_msgSend_stret, starting with receiver type.
-/// MsgExprs - list of argument expressions being passed to objc_msgSend_stret, 
-/// starting with receiver.
-/// Method - Method being rewritten.
-Expr *RewriteModernObjC::SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFlavor,
-                                                 QualType returnType, 
-                                                 SmallVectorImpl<QualType> &ArgTypes,
-                                                 SmallVectorImpl<Expr*> &MsgExprs,
-                                                 ObjCMethodDecl *Method) {
-  // Now do the "normal" pointer to function cast.
-  QualType castType = getSimpleFunctionType(returnType, ArgTypes,
-                                            Method ? Method->isVariadic()
-                                                   : false);
-  castType = Context->getPointerType(castType);
-  
-  // build type for containing the objc_msgSend_stret object.
-  static unsigned stretCount=0;
-  std::string name = "__Stret"; name += utostr(stretCount);
-  std::string str = 
-    "extern \"C\" void * __cdecl memset(void *_Dst, int _Val, size_t _Size);\n";
-  str += "namespace {\n";
-  str += "struct "; str += name;
-  str += " {\n\t";
-  str += name;
-  str += "(id receiver, SEL sel";
-  for (unsigned i = 2; i < ArgTypes.size(); i++) {
-    std::string ArgName = "arg"; ArgName += utostr(i);
-    ArgTypes[i].getAsStringInternal(ArgName, Context->getPrintingPolicy());
-    str += ", "; str += ArgName;
-  }
-  // could be vararg.
-  for (unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
-    std::string ArgName = "arg"; ArgName += utostr(i);
-    MsgExprs[i]->getType().getAsStringInternal(ArgName,
-                                               Context->getPrintingPolicy());
-    str += ", "; str += ArgName;
-  }
-  
-  str += ") {\n";
-  str += "\t  unsigned size = sizeof(";
-  str += returnType.getAsString(Context->getPrintingPolicy()); str += ");\n";
-  
-  str += "\t  if (size == 1 || size == 2 || size == 4 || size == 8)\n";
-  
-  str += "\t    s = (("; str += castType.getAsString(Context->getPrintingPolicy());
-  str += ")(void *)objc_msgSend)(receiver, sel";
-  for (unsigned i = 2; i < ArgTypes.size(); i++) {
-    str += ", arg"; str += utostr(i);
-  }
-  // could be vararg.
-  for (unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
-    str += ", arg"; str += utostr(i);
-  }
-  str+= ");\n";
-  
-  str += "\t  else if (receiver == 0)\n";
-  str += "\t    memset((void*)&s, 0, sizeof(s));\n";
-  str += "\t  else\n";
-  
-  
-  str += "\t    s = (("; str += castType.getAsString(Context->getPrintingPolicy());
-  str += ")(void *)objc_msgSend_stret)(receiver, sel";
-  for (unsigned i = 2; i < ArgTypes.size(); i++) {
-    str += ", arg"; str += utostr(i);
-  }
-  // could be vararg.
-  for (unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
-    str += ", arg"; str += utostr(i);
-  }
-  str += ");\n";
-  
-  
-  str += "\t}\n";
-  str += "\t"; str += returnType.getAsString(Context->getPrintingPolicy());
-  str += " s;\n";
-  str += "};\n};\n\n";
-  SourceLocation FunLocStart;
-  if (CurFunctionDef)
-    FunLocStart = getFunctionSourceLocation(*this, CurFunctionDef);
-  else {
-    assert(CurMethodDef && "SynthMsgSendStretCallExpr - CurMethodDef is null");
-    FunLocStart = CurMethodDef->getLocStart();
-  }
-
-  InsertText(FunLocStart, str);
-  ++stretCount;
-  
-  // AST for __Stretn(receiver, args).s;
-  IdentifierInfo *ID = &Context->Idents.get(name);
-  FunctionDecl *FD = FunctionDecl::Create(*Context, TUDecl, SourceLocation(),
-                                          SourceLocation(), ID, castType, 0,
-                                          SC_Extern, false, false);
-  DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, false, castType, VK_RValue,
-                                               SourceLocation());
-  CallExpr *STCE = new (Context) CallExpr(*Context, DRE, MsgExprs,
-                                          castType, VK_LValue, SourceLocation());
-  
-  FieldDecl *FieldD = FieldDecl::Create(*Context, 0, SourceLocation(),
-                                    SourceLocation(),
-                                    &Context->Idents.get("s"),
-                                    returnType, 0,
-                                    /*BitWidth=*/0, /*Mutable=*/true,
-                                    ICIS_NoInit);
-  MemberExpr *ME = new (Context) MemberExpr(STCE, false, FieldD, SourceLocation(),
-                                            FieldD->getType(), VK_LValue,
-                                            OK_Ordinary);
-
-  return ME;
-}
-
-Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
-                                    SourceLocation StartLoc,
-                                    SourceLocation EndLoc) {
-  if (!SelGetUidFunctionDecl)
-    SynthSelGetUidFunctionDecl();
-  if (!MsgSendFunctionDecl)
-    SynthMsgSendFunctionDecl();
-  if (!MsgSendSuperFunctionDecl)
-    SynthMsgSendSuperFunctionDecl();
-  if (!MsgSendStretFunctionDecl)
-    SynthMsgSendStretFunctionDecl();
-  if (!MsgSendSuperStretFunctionDecl)
-    SynthMsgSendSuperStretFunctionDecl();
-  if (!MsgSendFpretFunctionDecl)
-    SynthMsgSendFpretFunctionDecl();
-  if (!GetClassFunctionDecl)
-    SynthGetClassFunctionDecl();
-  if (!GetSuperClassFunctionDecl)
-    SynthGetSuperClassFunctionDecl();
-  if (!GetMetaClassFunctionDecl)
-    SynthGetMetaClassFunctionDecl();
-
-  // default to objc_msgSend().
-  FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl;
-  // May need to use objc_msgSend_stret() as well.
-  FunctionDecl *MsgSendStretFlavor = 0;
-  if (ObjCMethodDecl *mDecl = Exp->getMethodDecl()) {
-    QualType resultType = mDecl->getResultType();
-    if (resultType->isRecordType())
-      MsgSendStretFlavor = MsgSendStretFunctionDecl;
-    else if (resultType->isRealFloatingType())
-      MsgSendFlavor = MsgSendFpretFunctionDecl;
-  }
-
-  // Synthesize a call to objc_msgSend().
-  SmallVector<Expr*, 8> MsgExprs;
-  switch (Exp->getReceiverKind()) {
-  case ObjCMessageExpr::SuperClass: {
-    MsgSendFlavor = MsgSendSuperFunctionDecl;
-    if (MsgSendStretFlavor)
-      MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
-    assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
-
-    ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface();
-
-    SmallVector<Expr*, 4> InitExprs;
-
-    // set the receiver to self, the first argument to all methods.
-    InitExprs.push_back(
-      NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
-                               CK_BitCast,
-                   new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
-                                             false,
-                                             Context->getObjCIdType(),
-                                             VK_RValue,
-                                             SourceLocation()))
-                        ); // set the 'receiver'.
-
-    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
-    SmallVector<Expr*, 8> ClsExprs;
-    QualType argType = Context->getPointerType(Context->CharTy);
-    ClsExprs.push_back(StringLiteral::Create(*Context,
-                                   ClassDecl->getIdentifier()->getName(),
-                                   StringLiteral::Ascii, false,
-                                   argType, SourceLocation()));
-    // (Class)objc_getClass("CurrentClass")
-    CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
-                                                 &ClsExprs[0],
-                                                 ClsExprs.size(),
-                                                 StartLoc,
-                                                 EndLoc);
-    ClsExprs.clear();
-    ClsExprs.push_back(Cls);
-    Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
-                                       &ClsExprs[0], ClsExprs.size(),
-                                       StartLoc, EndLoc);
-    
-    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
-    // To turn off a warning, type-cast to 'id'
-    InitExprs.push_back( // set 'super class', using class_getSuperclass().
-                        NoTypeInfoCStyleCastExpr(Context,
-                                                 Context->getObjCIdType(),
-                                                 CK_BitCast, Cls));
-    // struct __rw_objc_super
-    QualType superType = getSuperStructType();
-    Expr *SuperRep;
-
-    if (LangOpts.MicrosoftExt) {
-      SynthSuperConstructorFunctionDecl();
-      // Simulate a constructor call...
-      DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperConstructorFunctionDecl,
-                                                   false, superType, VK_LValue,
-                                                   SourceLocation());
-      SuperRep = new (Context) CallExpr(*Context, DRE, InitExprs,
-                                        superType, VK_LValue,
-                                        SourceLocation());
-      // The code for super is a little tricky to prevent collision with
-      // the structure definition in the header. The rewriter has it's own
-      // internal definition (__rw_objc_super) that is uses. This is why
-      // we need the cast below. For example:
-      // (struct __rw_objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
-      //
-      SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf,
-                               Context->getPointerType(SuperRep->getType()),
-                                             VK_RValue, OK_Ordinary,
-                                             SourceLocation());
-      SuperRep = NoTypeInfoCStyleCastExpr(Context,
-                                          Context->getPointerType(superType),
-                                          CK_BitCast, SuperRep);
-    } else {
-      // (struct __rw_objc_super) { <exprs from above> }
-      InitListExpr *ILE =
-        new (Context) InitListExpr(*Context, SourceLocation(), InitExprs,
-                                   SourceLocation());
-      TypeSourceInfo *superTInfo
-        = Context->getTrivialTypeSourceInfo(superType);
-      SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
-                                                   superType, VK_LValue,
-                                                   ILE, false);
-      // struct __rw_objc_super *
-      SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf,
-                               Context->getPointerType(SuperRep->getType()),
-                                             VK_RValue, OK_Ordinary,
-                                             SourceLocation());
-    }
-    MsgExprs.push_back(SuperRep);
-    break;
-  }
-
-  case ObjCMessageExpr::Class: {
-    SmallVector<Expr*, 8> ClsExprs;
-    QualType argType = Context->getPointerType(Context->CharTy);
-    ObjCInterfaceDecl *Class
-      = Exp->getClassReceiver()->getAs<ObjCObjectType>()->getInterface();
-    IdentifierInfo *clsName = Class->getIdentifier();
-    ClsExprs.push_back(StringLiteral::Create(*Context,
-                                             clsName->getName(),
-                                             StringLiteral::Ascii, false,
-                                             argType, SourceLocation()));
-    CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
-                                                 &ClsExprs[0],
-                                                 ClsExprs.size(), 
-                                                 StartLoc, EndLoc);
-    CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
-                                                 Context->getObjCIdType(),
-                                                 CK_BitCast, Cls);
-    MsgExprs.push_back(ArgExpr);
-    break;
-  }
-
-  case ObjCMessageExpr::SuperInstance:{
-    MsgSendFlavor = MsgSendSuperFunctionDecl;
-    if (MsgSendStretFlavor)
-      MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
-    assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
-    ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface();
-    SmallVector<Expr*, 4> InitExprs;
-
-    InitExprs.push_back(
-      NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
-                               CK_BitCast,
-                   new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
-                                             false,
-                                             Context->getObjCIdType(),
-                                             VK_RValue, SourceLocation()))
-                        ); // set the 'receiver'.
-    
-    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
-    SmallVector<Expr*, 8> ClsExprs;
-    QualType argType = Context->getPointerType(Context->CharTy);
-    ClsExprs.push_back(StringLiteral::Create(*Context,
-                                   ClassDecl->getIdentifier()->getName(),
-                                   StringLiteral::Ascii, false, argType,
-                                   SourceLocation()));
-    // (Class)objc_getClass("CurrentClass")
-    CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
-                                                 &ClsExprs[0],
-                                                 ClsExprs.size(), 
-                                                 StartLoc, EndLoc);
-    ClsExprs.clear();
-    ClsExprs.push_back(Cls);
-    Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
-                                       &ClsExprs[0], ClsExprs.size(),
-                                       StartLoc, EndLoc);
-    
-    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
-    // To turn off a warning, type-cast to 'id'
-    InitExprs.push_back(
-      // set 'super class', using class_getSuperclass().
-      NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
-                               CK_BitCast, Cls));
-    // struct __rw_objc_super
-    QualType superType = getSuperStructType();
-    Expr *SuperRep;
-
-    if (LangOpts.MicrosoftExt) {
-      SynthSuperConstructorFunctionDecl();
-      // Simulate a constructor call...
-      DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperConstructorFunctionDecl,
-                                                   false, superType, VK_LValue,
-                                                   SourceLocation());
-      SuperRep = new (Context) CallExpr(*Context, DRE, InitExprs,
-                                        superType, VK_LValue, SourceLocation());
-      // The code for super is a little tricky to prevent collision with
-      // the structure definition in the header. The rewriter has it's own
-      // internal definition (__rw_objc_super) that is uses. This is why
-      // we need the cast below. For example:
-      // (struct __rw_objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
-      //
-      SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf,
-                               Context->getPointerType(SuperRep->getType()),
-                               VK_RValue, OK_Ordinary,
-                               SourceLocation());
-      SuperRep = NoTypeInfoCStyleCastExpr(Context,
-                               Context->getPointerType(superType),
-                               CK_BitCast, SuperRep);
-    } else {
-      // (struct __rw_objc_super) { <exprs from above> }
-      InitListExpr *ILE =
-        new (Context) InitListExpr(*Context, SourceLocation(), InitExprs,
-                                   SourceLocation());
-      TypeSourceInfo *superTInfo
-        = Context->getTrivialTypeSourceInfo(superType);
-      SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
-                                                   superType, VK_RValue, ILE,
-                                                   false);
-    }
-    MsgExprs.push_back(SuperRep);
-    break;
-  }
-
-  case ObjCMessageExpr::Instance: {
-    // Remove all type-casts because it may contain objc-style types; e.g.
-    // Foo<Proto> *.
-    Expr *recExpr = Exp->getInstanceReceiver();
-    while (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(recExpr))
-      recExpr = CE->getSubExpr();
-    CastKind CK = recExpr->getType()->isObjCObjectPointerType()
-                    ? CK_BitCast : recExpr->getType()->isBlockPointerType()
-                                     ? CK_BlockPointerToObjCPointerCast
-                                     : CK_CPointerToObjCPointerCast;
-
-    recExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
-                                       CK, recExpr);
-    MsgExprs.push_back(recExpr);
-    break;
-  }
-  }
-
-  // Create a call to sel_registerName("selName"), it will be the 2nd argument.
-  SmallVector<Expr*, 8> SelExprs;
-  QualType argType = Context->getPointerType(Context->CharTy);
-  SelExprs.push_back(StringLiteral::Create(*Context,
-                                       Exp->getSelector().getAsString(),
-                                       StringLiteral::Ascii, false,
-                                       argType, SourceLocation()));
-  CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
-                                                 &SelExprs[0], SelExprs.size(),
-                                                  StartLoc,
-                                                  EndLoc);
-  MsgExprs.push_back(SelExp);
-
-  // Now push any user supplied arguments.
-  for (unsigned i = 0; i < Exp->getNumArgs(); i++) {
-    Expr *userExpr = Exp->getArg(i);
-    // Make all implicit casts explicit...ICE comes in handy:-)
-    if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(userExpr)) {
-      // Reuse the ICE type, it is exactly what the doctor ordered.
-      QualType type = ICE->getType();
-      if (needToScanForQualifiers(type))
-        type = Context->getObjCIdType();
-      // Make sure we convert "type (^)(...)" to "type (*)(...)".
-      (void)convertBlockPointerToFunctionPointer(type);
-      const Expr *SubExpr = ICE->IgnoreParenImpCasts();
-      CastKind CK;
-      if (SubExpr->getType()->isIntegralType(*Context) && 
-          type->isBooleanType()) {
-        CK = CK_IntegralToBoolean;
-      } else if (type->isObjCObjectPointerType()) {
-        if (SubExpr->getType()->isBlockPointerType()) {
-          CK = CK_BlockPointerToObjCPointerCast;
-        } else if (SubExpr->getType()->isPointerType()) {
-          CK = CK_CPointerToObjCPointerCast;
-        } else {
-          CK = CK_BitCast;
-        }
-      } else {
-        CK = CK_BitCast;
-      }
-
-      userExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, userExpr);
-    }
-    // Make id<P...> cast into an 'id' cast.
-    else if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(userExpr)) {
-      if (CE->getType()->isObjCQualifiedIdType()) {
-        while ((CE = dyn_cast<CStyleCastExpr>(userExpr)))
-          userExpr = CE->getSubExpr();
-        CastKind CK;
-        if (userExpr->getType()->isIntegralType(*Context)) {
-          CK = CK_IntegralToPointer;
-        } else if (userExpr->getType()->isBlockPointerType()) {
-          CK = CK_BlockPointerToObjCPointerCast;
-        } else if (userExpr->getType()->isPointerType()) {
-          CK = CK_CPointerToObjCPointerCast;
-        } else {
-          CK = CK_BitCast;
-        }
-        userExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
-                                            CK, userExpr);
-      }
-    }
-    MsgExprs.push_back(userExpr);
-    // We've transferred the ownership to MsgExprs. For now, we *don't* null
-    // out the argument in the original expression (since we aren't deleting
-    // the ObjCMessageExpr). See RewritePropertyOrImplicitSetter() usage for more info.
-    //Exp->setArg(i, 0);
-  }
-  // Generate the funky cast.
-  CastExpr *cast;
-  SmallVector<QualType, 8> ArgTypes;
-  QualType returnType;
-
-  // Push 'id' and 'SEL', the 2 implicit arguments.
-  if (MsgSendFlavor == MsgSendSuperFunctionDecl)
-    ArgTypes.push_back(Context->getPointerType(getSuperStructType()));
-  else
-    ArgTypes.push_back(Context->getObjCIdType());
-  ArgTypes.push_back(Context->getObjCSelType());
-  if (ObjCMethodDecl *OMD = Exp->getMethodDecl()) {
-    // Push any user argument types.
-    for (ObjCMethodDecl::param_iterator PI = OMD->param_begin(),
-         E = OMD->param_end(); PI != E; ++PI) {
-      QualType t = (*PI)->getType()->isObjCQualifiedIdType()
-                     ? Context->getObjCIdType()
-                     : (*PI)->getType();
-      // Make sure we convert "t (^)(...)" to "t (*)(...)".
-      (void)convertBlockPointerToFunctionPointer(t);
-      ArgTypes.push_back(t);
-    }
-    returnType = Exp->getType();
-    convertToUnqualifiedObjCType(returnType);
-    (void)convertBlockPointerToFunctionPointer(returnType);
-  } else {
-    returnType = Context->getObjCIdType();
-  }
-  // Get the type, we will need to reference it in a couple spots.
-  QualType msgSendType = MsgSendFlavor->getType();
-
-  // Create a reference to the objc_msgSend() declaration.
-  DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType,
-                                               VK_LValue, SourceLocation());
-
-  // Need to cast objc_msgSend to "void *" (to workaround a GCC bandaid).
-  // If we don't do this cast, we get the following bizarre warning/note:
-  // xx.m:13: warning: function called through a non-compatible type
-  // xx.m:13: note: if this code is reached, the program will abort
-  cast = NoTypeInfoCStyleCastExpr(Context,
-                                  Context->getPointerType(Context->VoidTy),
-                                  CK_BitCast, DRE);
-
-  // Now do the "normal" pointer to function cast.
-  // If we don't have a method decl, force a variadic cast.
-  const ObjCMethodDecl *MD = Exp->getMethodDecl();
-  QualType castType =
-    getSimpleFunctionType(returnType, ArgTypes, MD ? MD->isVariadic() : true);
-  castType = Context->getPointerType(castType);
-  cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
-                                  cast);
-
-  // Don't forget the parens to enforce the proper binding.
-  ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
-
-  const FunctionType *FT = msgSendType->getAs<FunctionType>();
-  CallExpr *CE = new (Context) CallExpr(*Context, PE, MsgExprs,
-                                        FT->getResultType(), VK_RValue, EndLoc);
-  Stmt *ReplacingStmt = CE;
-  if (MsgSendStretFlavor) {
-    // We have the method which returns a struct/union. Must also generate
-    // call to objc_msgSend_stret and hang both varieties on a conditional
-    // expression which dictate which one to envoke depending on size of
-    // method's return type.
-
-    Expr *STCE = SynthMsgSendStretCallExpr(MsgSendStretFlavor,
-                                           returnType,
-                                           ArgTypes, MsgExprs,
-                                           Exp->getMethodDecl());
-    ReplacingStmt = STCE;
-  }
-  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
-  return ReplacingStmt;
-}
-
-Stmt *RewriteModernObjC::RewriteMessageExpr(ObjCMessageExpr *Exp) {
-  Stmt *ReplacingStmt = SynthMessageExpr(Exp, Exp->getLocStart(),
-                                         Exp->getLocEnd());
-
-  // Now do the actual rewrite.
-  ReplaceStmt(Exp, ReplacingStmt);
-
-  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
-  return ReplacingStmt;
-}
-
-// typedef struct objc_object Protocol;
-QualType RewriteModernObjC::getProtocolType() {
-  if (!ProtocolTypeDecl) {
-    TypeSourceInfo *TInfo
-      = Context->getTrivialTypeSourceInfo(Context->getObjCIdType());
-    ProtocolTypeDecl = TypedefDecl::Create(*Context, TUDecl,
-                                           SourceLocation(), SourceLocation(),
-                                           &Context->Idents.get("Protocol"),
-                                           TInfo);
-  }
-  return Context->getTypeDeclType(ProtocolTypeDecl);
-}
-
-/// RewriteObjCProtocolExpr - Rewrite a protocol expression into
-/// a synthesized/forward data reference (to the protocol's metadata).
-/// The forward references (and metadata) are generated in
-/// RewriteModernObjC::HandleTranslationUnit().
-Stmt *RewriteModernObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) {
-  std::string Name = "_OBJC_PROTOCOL_REFERENCE_$_" + 
-                      Exp->getProtocol()->getNameAsString();
-  IdentifierInfo *ID = &Context->Idents.get(Name);
-  VarDecl *VD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
-                                SourceLocation(), ID, getProtocolType(), 0,
-                                SC_Extern);
-  DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, false, getProtocolType(),
-                                               VK_LValue, SourceLocation());
-  Expr *DerefExpr = new (Context) UnaryOperator(DRE, UO_AddrOf,
-                             Context->getPointerType(DRE->getType()),
-                             VK_RValue, OK_Ordinary, SourceLocation());
-  CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, DerefExpr->getType(),
-                                                CK_BitCast,
-                                                DerefExpr);
-  ReplaceStmt(Exp, castExpr);
-  ProtocolExprDecls.insert(Exp->getProtocol()->getCanonicalDecl());
-  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
-  return castExpr;
-
-}
-
-bool RewriteModernObjC::BufferContainsPPDirectives(const char *startBuf,
-                                             const char *endBuf) {
-  while (startBuf < endBuf) {
-    if (*startBuf == '#') {
-      // Skip whitespace.
-      for (++startBuf; startBuf[0] == ' ' || startBuf[0] == '\t'; ++startBuf)
-        ;
-      if (!strncmp(startBuf, "if", strlen("if")) ||
-          !strncmp(startBuf, "ifdef", strlen("ifdef")) ||
-          !strncmp(startBuf, "ifndef", strlen("ifndef")) ||
-          !strncmp(startBuf, "define", strlen("define")) ||
-          !strncmp(startBuf, "undef", strlen("undef")) ||
-          !strncmp(startBuf, "else", strlen("else")) ||
-          !strncmp(startBuf, "elif", strlen("elif")) ||
-          !strncmp(startBuf, "endif", strlen("endif")) ||
-          !strncmp(startBuf, "pragma", strlen("pragma")) ||
-          !strncmp(startBuf, "include", strlen("include")) ||
-          !strncmp(startBuf, "import", strlen("import")) ||
-          !strncmp(startBuf, "include_next", strlen("include_next")))
-        return true;
-    }
-    startBuf++;
-  }
-  return false;
-}
-
-/// IsTagDefinedInsideClass - This routine checks that a named tagged type 
-/// is defined inside an objective-c class. If so, it returns true. 
-bool RewriteModernObjC::IsTagDefinedInsideClass(ObjCContainerDecl *IDecl, 
-                                                TagDecl *Tag,
-                                                bool &IsNamedDefinition) {
-  if (!IDecl)
-    return false;
-  SourceLocation TagLocation;
-  if (RecordDecl *RD = dyn_cast<RecordDecl>(Tag)) {
-    RD = RD->getDefinition();
-    if (!RD || !RD->getDeclName().getAsIdentifierInfo())
-      return false;
-    IsNamedDefinition = true;
-    TagLocation = RD->getLocation();
-    return Context->getSourceManager().isBeforeInTranslationUnit(
-                                          IDecl->getLocation(), TagLocation);
-  }
-  if (EnumDecl *ED = dyn_cast<EnumDecl>(Tag)) {
-    if (!ED || !ED->getDeclName().getAsIdentifierInfo())
-      return false;
-    IsNamedDefinition = true;
-    TagLocation = ED->getLocation();
-    return Context->getSourceManager().isBeforeInTranslationUnit(
-                                          IDecl->getLocation(), TagLocation);
-
-  }
-  return false;
-}
-
-/// RewriteObjCFieldDeclType - This routine rewrites a type into the buffer.
-/// It handles elaborated types, as well as enum types in the process.
-bool RewriteModernObjC::RewriteObjCFieldDeclType(QualType &Type, 
-                                                 std::string &Result) {
-  if (isa<TypedefType>(Type)) {
-    Result += "\t";
-    return false;
-  }
-    
-  if (Type->isArrayType()) {
-    QualType ElemTy = Context->getBaseElementType(Type);
-    return RewriteObjCFieldDeclType(ElemTy, Result);
-  }
-  else if (Type->isRecordType()) {
-    RecordDecl *RD = Type->getAs<RecordType>()->getDecl();
-    if (RD->isCompleteDefinition()) {
-      if (RD->isStruct())
-        Result += "\n\tstruct ";
-      else if (RD->isUnion())
-        Result += "\n\tunion ";
-      else
-        assert(false && "class not allowed as an ivar type");
-      
-      Result += RD->getName();
-      if (GlobalDefinedTags.count(RD)) {
-        // struct/union is defined globally, use it.
-        Result += " ";
-        return true;
-      }
-      Result += " {\n";
-      for (RecordDecl::field_iterator i = RD->field_begin(), 
-           e = RD->field_end(); i != e; ++i) {
-        FieldDecl *FD = *i;
-        RewriteObjCFieldDecl(FD, Result);
-      }
-      Result += "\t} "; 
-      return true;
-    }
-  }
-  else if (Type->isEnumeralType()) {
-    EnumDecl *ED = Type->getAs<EnumType>()->getDecl();
-    if (ED->isCompleteDefinition()) {
-      Result += "\n\tenum ";
-      Result += ED->getName();
-      if (GlobalDefinedTags.count(ED)) {
-        // Enum is globall defined, use it.
-        Result += " ";
-        return true;
-      }
-      
-      Result += " {\n";
-      for (EnumDecl::enumerator_iterator EC = ED->enumerator_begin(),
-           ECEnd = ED->enumerator_end(); EC != ECEnd; ++EC) {
-        Result += "\t"; Result += EC->getName(); Result += " = ";
-        llvm::APSInt Val = EC->getInitVal();
-        Result += Val.toString(10);
-        Result += ",\n";
-      }
-      Result += "\t} "; 
-      return true;
-    }
-  }
-  
-  Result += "\t";
-  convertObjCTypeToCStyleType(Type);
-  return false;
-}
-
-
-/// RewriteObjCFieldDecl - This routine rewrites a field into the buffer.
-/// It handles elaborated types, as well as enum types in the process.
-void RewriteModernObjC::RewriteObjCFieldDecl(FieldDecl *fieldDecl, 
-                                             std::string &Result) {
-  QualType Type = fieldDecl->getType();
-  std::string Name = fieldDecl->getNameAsString();
-  
-  bool EleboratedType = RewriteObjCFieldDeclType(Type, Result); 
-  if (!EleboratedType)
-    Type.getAsStringInternal(Name, Context->getPrintingPolicy());
-  Result += Name;
-  if (fieldDecl->isBitField()) {
-    Result += " : "; Result += utostr(fieldDecl->getBitWidthValue(*Context));
-  }
-  else if (EleboratedType && Type->isArrayType()) {
-    const ArrayType *AT = Context->getAsArrayType(Type);
-    do {
-      if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT)) {
-        Result += "[";
-        llvm::APInt Dim = CAT->getSize();
-        Result += utostr(Dim.getZExtValue());
-        Result += "]";
-      }
-      AT = Context->getAsArrayType(AT->getElementType());
-    } while (AT);
-  }
-  
-  Result += ";\n";
-}
-
-/// RewriteLocallyDefinedNamedAggregates - This routine rewrites locally defined
-/// named aggregate types into the input buffer.
-void RewriteModernObjC::RewriteLocallyDefinedNamedAggregates(FieldDecl *fieldDecl, 
-                                             std::string &Result) {
-  QualType Type = fieldDecl->getType();
-  if (isa<TypedefType>(Type))
-    return;
-  if (Type->isArrayType())
-    Type = Context->getBaseElementType(Type);
-  ObjCContainerDecl *IDecl = 
-    dyn_cast<ObjCContainerDecl>(fieldDecl->getDeclContext());
-  
-  TagDecl *TD = 0;
-  if (Type->isRecordType()) {
-    TD = Type->getAs<RecordType>()->getDecl();
-  }
-  else if (Type->isEnumeralType()) {
-    TD = Type->getAs<EnumType>()->getDecl();
-  }
-  
-  if (TD) {
-    if (GlobalDefinedTags.count(TD))
-      return;
-    
-    bool IsNamedDefinition = false;
-    if (IsTagDefinedInsideClass(IDecl, TD, IsNamedDefinition)) {
-      RewriteObjCFieldDeclType(Type, Result);
-      Result += ";";
-    }
-    if (IsNamedDefinition)
-      GlobalDefinedTags.insert(TD);
-  }
-    
-}
-
-unsigned RewriteModernObjC::ObjCIvarBitfieldGroupNo(ObjCIvarDecl *IV) {
-  const ObjCInterfaceDecl *CDecl = IV->getContainingInterface();
-  if (ObjCInterefaceHasBitfieldGroups.count(CDecl)) {
-    return IvarGroupNumber[IV];
-  }
-  unsigned GroupNo = 0;
-  SmallVector<const ObjCIvarDecl *, 8> IVars;
-  for (const ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin();
-       IVD; IVD = IVD->getNextIvar())
-    IVars.push_back(IVD);
-  
-  for (unsigned i = 0, e = IVars.size(); i < e; i++)
-    if (IVars[i]->isBitField()) {
-      IvarGroupNumber[IVars[i++]] = ++GroupNo;
-      while (i < e && IVars[i]->isBitField())
-        IvarGroupNumber[IVars[i++]] = GroupNo;
-      if (i < e)
-        --i;
-    }
-
-  ObjCInterefaceHasBitfieldGroups.insert(CDecl);
-  return IvarGroupNumber[IV];
-}
-
-QualType RewriteModernObjC::SynthesizeBitfieldGroupStructType(
-                              ObjCIvarDecl *IV,
-                              SmallVectorImpl<ObjCIvarDecl *> &IVars) {
-  std::string StructTagName;
-  ObjCIvarBitfieldGroupType(IV, StructTagName);
-  RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct,
-                                      Context->getTranslationUnitDecl(),
-                                      SourceLocation(), SourceLocation(),
-                                      &Context->Idents.get(StructTagName));
-  for (unsigned i=0, e = IVars.size(); i < e; i++) {
-    ObjCIvarDecl *Ivar = IVars[i];
-    RD->addDecl(FieldDecl::Create(*Context, RD, SourceLocation(), SourceLocation(),
-                                  &Context->Idents.get(Ivar->getName()),
-                                  Ivar->getType(),
-                                  0, /*Expr *BW */Ivar->getBitWidth(), false,
-                                  ICIS_NoInit));
-  }
-  RD->completeDefinition();
-  return Context->getTagDeclType(RD);
-}
-
-QualType RewriteModernObjC::GetGroupRecordTypeForObjCIvarBitfield(ObjCIvarDecl *IV) {
-  const ObjCInterfaceDecl *CDecl = IV->getContainingInterface();
-  unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
-  std::pair<const ObjCInterfaceDecl*, unsigned> tuple = std::make_pair(CDecl, GroupNo);
-  if (GroupRecordType.count(tuple))
-    return GroupRecordType[tuple];
-  
-  SmallVector<ObjCIvarDecl *, 8> IVars;
-  for (const ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin();
-       IVD; IVD = IVD->getNextIvar()) {
-    if (IVD->isBitField())
-      IVars.push_back(const_cast<ObjCIvarDecl *>(IVD));
-    else {
-      if (!IVars.empty()) {
-        unsigned GroupNo = ObjCIvarBitfieldGroupNo(IVars[0]);
-        // Generate the struct type for this group of bitfield ivars.
-        GroupRecordType[std::make_pair(CDecl, GroupNo)] =
-          SynthesizeBitfieldGroupStructType(IVars[0], IVars);
-        IVars.clear();
-      }
-    }
-  }
-  if (!IVars.empty()) {
-    // Do the last one.
-    unsigned GroupNo = ObjCIvarBitfieldGroupNo(IVars[0]);
-    GroupRecordType[std::make_pair(CDecl, GroupNo)] =
-      SynthesizeBitfieldGroupStructType(IVars[0], IVars);
-  }
-  QualType RetQT = GroupRecordType[tuple];
-  assert(!RetQT.isNull() && "GetGroupRecordTypeForObjCIvarBitfield struct type is NULL");
-  
-  return RetQT;
-}
-
-/// ObjCIvarBitfieldGroupDecl - Names field decl. for ivar bitfield group.
-/// Name would be: classname__GRBF_n where n is the group number for this ivar.
-void RewriteModernObjC::ObjCIvarBitfieldGroupDecl(ObjCIvarDecl *IV,
-                                                  std::string &Result) {
-  const ObjCInterfaceDecl *CDecl = IV->getContainingInterface();
-  Result += CDecl->getName();
-  Result += "__GRBF_";
-  unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
-  Result += utostr(GroupNo);
-  return;
-}
-
-/// ObjCIvarBitfieldGroupType - Names struct type for ivar bitfield group.
-/// Name of the struct would be: classname__T_n where n is the group number for
-/// this ivar.
-void RewriteModernObjC::ObjCIvarBitfieldGroupType(ObjCIvarDecl *IV,
-                                                  std::string &Result) {
-  const ObjCInterfaceDecl *CDecl = IV->getContainingInterface();
-  Result += CDecl->getName();
-  Result += "__T_";
-  unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
-  Result += utostr(GroupNo);
-  return;
-}
-
-/// ObjCIvarBitfieldGroupOffset - Names symbol for ivar bitfield group field offset.
-/// Name would be: OBJC_IVAR_$_classname__GRBF_n where n is the group number for
-/// this ivar.
-void RewriteModernObjC::ObjCIvarBitfieldGroupOffset(ObjCIvarDecl *IV,
-                                                    std::string &Result) {
-  Result += "OBJC_IVAR_$_";
-  ObjCIvarBitfieldGroupDecl(IV, Result);
-}
-
-#define SKIP_BITFIELDS(IX, ENDIX, VEC) { \
-      while ((IX < ENDIX) && VEC[IX]->isBitField()) \
-        ++IX; \
-      if (IX < ENDIX) \
-        --IX; \
-}
-
-/// RewriteObjCInternalStruct - Rewrite one internal struct corresponding to
-/// an objective-c class with ivars.
-void RewriteModernObjC::RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl,
-                                               std::string &Result) {
-  assert(CDecl && "Class missing in SynthesizeObjCInternalStruct");
-  assert(CDecl->getName() != "" &&
-         "Name missing in SynthesizeObjCInternalStruct");
-  ObjCInterfaceDecl *RCDecl = CDecl->getSuperClass();
-  SmallVector<ObjCIvarDecl *, 8> IVars;
-  for (ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin();
-       IVD; IVD = IVD->getNextIvar())
-    IVars.push_back(IVD);
-  
-  SourceLocation LocStart = CDecl->getLocStart();
-  SourceLocation LocEnd = CDecl->getEndOfDefinitionLoc();
-  
-  const char *startBuf = SM->getCharacterData(LocStart);
-  const char *endBuf = SM->getCharacterData(LocEnd);
-  
-  // If no ivars and no root or if its root, directly or indirectly,
-  // have no ivars (thus not synthesized) then no need to synthesize this class.
-  if ((!CDecl->isThisDeclarationADefinition() || IVars.size() == 0) &&
-      (!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) {
-    endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts);
-    ReplaceText(LocStart, endBuf-startBuf, Result);
-    return;
-  }
-  
-  // Insert named struct/union definitions inside class to
-  // outer scope. This follows semantics of locally defined
-  // struct/unions in objective-c classes.
-  for (unsigned i = 0, e = IVars.size(); i < e; i++)
-    RewriteLocallyDefinedNamedAggregates(IVars[i], Result);
-  
-  // Insert named structs which are syntheized to group ivar bitfields
-  // to outer scope as well.
-  for (unsigned i = 0, e = IVars.size(); i < e; i++)
-    if (IVars[i]->isBitField()) {
-      ObjCIvarDecl *IV = IVars[i];
-      QualType QT = GetGroupRecordTypeForObjCIvarBitfield(IV);
-      RewriteObjCFieldDeclType(QT, Result);
-      Result += ";";
-      // skip over ivar bitfields in this group.
-      SKIP_BITFIELDS(i , e, IVars);
-    }
-    
-  Result += "\nstruct ";
-  Result += CDecl->getNameAsString();
-  Result += "_IMPL {\n";
-  
-  if (RCDecl && ObjCSynthesizedStructs.count(RCDecl)) {
-    Result += "\tstruct "; Result += RCDecl->getNameAsString();
-    Result += "_IMPL "; Result += RCDecl->getNameAsString();
-    Result += "_IVARS;\n";
-  }
-  
-  for (unsigned i = 0, e = IVars.size(); i < e; i++) {
-    if (IVars[i]->isBitField()) {
-      ObjCIvarDecl *IV = IVars[i];
-      Result += "\tstruct ";
-      ObjCIvarBitfieldGroupType(IV, Result); Result += " ";
-      ObjCIvarBitfieldGroupDecl(IV, Result); Result += ";\n";
-      // skip over ivar bitfields in this group.
-      SKIP_BITFIELDS(i , e, IVars);
-    }
-    else
-      RewriteObjCFieldDecl(IVars[i], Result);
-  }
-
-  Result += "};\n";
-  endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts);
-  ReplaceText(LocStart, endBuf-startBuf, Result);
-  // Mark this struct as having been generated.
-  if (!ObjCSynthesizedStructs.insert(CDecl))
-    llvm_unreachable("struct already synthesize- RewriteObjCInternalStruct");
-}
-
-/// RewriteIvarOffsetSymbols - Rewrite ivar offset symbols of those ivars which
-/// have been referenced in an ivar access expression.
-void RewriteModernObjC::RewriteIvarOffsetSymbols(ObjCInterfaceDecl *CDecl,
-                                                  std::string &Result) {
-  // write out ivar offset symbols which have been referenced in an ivar
-  // access expression.
-  llvm::SmallPtrSet<ObjCIvarDecl *, 8> Ivars = ReferencedIvars[CDecl];
-  if (Ivars.empty())
-    return;
-  
-  llvm::DenseSet<std::pair<const ObjCInterfaceDecl*, unsigned> > GroupSymbolOutput;
-  for (llvm::SmallPtrSet<ObjCIvarDecl *, 8>::iterator i = Ivars.begin(),
-       e = Ivars.end(); i != e; i++) {
-    ObjCIvarDecl *IvarDecl = (*i);
-    const ObjCInterfaceDecl *IDecl = IvarDecl->getContainingInterface();
-    unsigned GroupNo = 0;
-    if (IvarDecl->isBitField()) {
-      GroupNo = ObjCIvarBitfieldGroupNo(IvarDecl);
-      if (GroupSymbolOutput.count(std::make_pair(IDecl, GroupNo)))
-        continue;
-    }
-    Result += "\n";
-    if (LangOpts.MicrosoftExt)
-      Result += "__declspec(allocate(\".objc_ivar$B\")) ";
-    Result += "extern \"C\" ";
-    if (LangOpts.MicrosoftExt && 
-        IvarDecl->getAccessControl() != ObjCIvarDecl::Private &&
-        IvarDecl->getAccessControl() != ObjCIvarDecl::Package)
-        Result += "__declspec(dllimport) ";
-
-    Result += "unsigned long ";
-    if (IvarDecl->isBitField()) {
-      ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
-      GroupSymbolOutput.insert(std::make_pair(IDecl, GroupNo));
-    }
-    else
-      WriteInternalIvarName(CDecl, IvarDecl, Result);
-    Result += ";";
-  }
-}
-
-//===----------------------------------------------------------------------===//
-// Meta Data Emission
-//===----------------------------------------------------------------------===//
-
-
-/// RewriteImplementations - This routine rewrites all method implementations
-/// and emits meta-data.
-
-void RewriteModernObjC::RewriteImplementations() {
-  int ClsDefCount = ClassImplementation.size();
-  int CatDefCount = CategoryImplementation.size();
-
-  // Rewrite implemented methods
-  for (int i = 0; i < ClsDefCount; i++) {
-    ObjCImplementationDecl *OIMP = ClassImplementation[i];
-    ObjCInterfaceDecl *CDecl = OIMP->getClassInterface();
-    if (CDecl->isImplicitInterfaceDecl())
-      assert(false &&
-             "Legacy implicit interface rewriting not supported in moder abi");
-    RewriteImplementationDecl(OIMP);
-  }
-
-  for (int i = 0; i < CatDefCount; i++) {
-    ObjCCategoryImplDecl *CIMP = CategoryImplementation[i];
-    ObjCInterfaceDecl *CDecl = CIMP->getClassInterface();
-    if (CDecl->isImplicitInterfaceDecl())
-      assert(false &&
-             "Legacy implicit interface rewriting not supported in moder abi");
-    RewriteImplementationDecl(CIMP);
-  }
-}
-
-void RewriteModernObjC::RewriteByRefString(std::string &ResultStr, 
-                                     const std::string &Name,
-                                     ValueDecl *VD, bool def) {
-  assert(BlockByRefDeclNo.count(VD) && 
-         "RewriteByRefString: ByRef decl missing");
-  if (def)
-    ResultStr += "struct ";
-  ResultStr += "__Block_byref_" + Name + 
-    "_" + utostr(BlockByRefDeclNo[VD]) ;
-}
-
-static bool HasLocalVariableExternalStorage(ValueDecl *VD) {
-  if (VarDecl *Var = dyn_cast<VarDecl>(VD))
-    return (Var->isFunctionOrMethodVarDecl() && !Var->hasLocalStorage());
-  return false;
-}
-
-std::string RewriteModernObjC::SynthesizeBlockFunc(BlockExpr *CE, int i,
-                                                   StringRef funcName,
-                                                   std::string Tag) {
-  const FunctionType *AFT = CE->getFunctionType();
-  QualType RT = AFT->getResultType();
-  std::string StructRef = "struct " + Tag;
-  SourceLocation BlockLoc = CE->getExprLoc();
-  std::string S;
-  ConvertSourceLocationToLineDirective(BlockLoc, S);
-  
-  S += "static " + RT.getAsString(Context->getPrintingPolicy()) + " __" +
-         funcName.str() + "_block_func_" + utostr(i);
-
-  BlockDecl *BD = CE->getBlockDecl();
-
-  if (isa<FunctionNoProtoType>(AFT)) {
-    // No user-supplied arguments. Still need to pass in a pointer to the
-    // block (to reference imported block decl refs).
-    S += "(" + StructRef + " *__cself)";
-  } else if (BD->param_empty()) {
-    S += "(" + StructRef + " *__cself)";
-  } else {
-    const FunctionProtoType *FT = cast<FunctionProtoType>(AFT);
-    assert(FT && "SynthesizeBlockFunc: No function proto");
-    S += '(';
-    // first add the implicit argument.
-    S += StructRef + " *__cself, ";
-    std::string ParamStr;
-    for (BlockDecl::param_iterator AI = BD->param_begin(),
-         E = BD->param_end(); AI != E; ++AI) {
-      if (AI != BD->param_begin()) S += ", ";
-      ParamStr = (*AI)->getNameAsString();
-      QualType QT = (*AI)->getType();
-      (void)convertBlockPointerToFunctionPointer(QT);
-      QT.getAsStringInternal(ParamStr, Context->getPrintingPolicy());
-      S += ParamStr;
-    }
-    if (FT->isVariadic()) {
-      if (!BD->param_empty()) S += ", ";
-      S += "...";
-    }
-    S += ')';
-  }
-  S += " {\n";
-
-  // Create local declarations to avoid rewriting all closure decl ref exprs.
-  // First, emit a declaration for all "by ref" decls.
-  for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(),
-       E = BlockByRefDecls.end(); I != E; ++I) {
-    S += "  ";
-    std::string Name = (*I)->getNameAsString();
-    std::string TypeString;
-    RewriteByRefString(TypeString, Name, (*I));
-    TypeString += " *";
-    Name = TypeString + Name;
-    S += Name + " = __cself->" + (*I)->getNameAsString() + "; // bound by ref\n";
-  }
-  // Next, emit a declaration for all "by copy" declarations.
-  for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(),
-       E = BlockByCopyDecls.end(); I != E; ++I) {
-    S += "  ";
-    // Handle nested closure invocation. For example:
-    //
-    //   void (^myImportedClosure)(void);
-    //   myImportedClosure  = ^(void) { setGlobalInt(x + y); };
-    //
-    //   void (^anotherClosure)(void);
-    //   anotherClosure = ^(void) {
-    //     myImportedClosure(); // import and invoke the closure
-    //   };
-    //
-    if (isTopLevelBlockPointerType((*I)->getType())) {
-      RewriteBlockPointerTypeVariable(S, (*I));
-      S += " = (";
-      RewriteBlockPointerType(S, (*I)->getType());
-      S += ")";
-      S += "__cself->" + (*I)->getNameAsString() + "; // bound by copy\n";
-    }
-    else {
-      std::string Name = (*I)->getNameAsString();
-      QualType QT = (*I)->getType();
-      if (HasLocalVariableExternalStorage(*I))
-        QT = Context->getPointerType(QT);
-      QT.getAsStringInternal(Name, Context->getPrintingPolicy());
-      S += Name + " = __cself->" + 
-                              (*I)->getNameAsString() + "; // bound by copy\n";
-    }
-  }
-  std::string RewrittenStr = RewrittenBlockExprs[CE];
-  const char *cstr = RewrittenStr.c_str();
-  while (*cstr++ != '{') ;
-  S += cstr;
-  S += "\n";
-  return S;
-}
-
-std::string RewriteModernObjC::SynthesizeBlockHelperFuncs(BlockExpr *CE, int i,
-                                                   StringRef funcName,
-                                                   std::string Tag) {
-  std::string StructRef = "struct " + Tag;
-  std::string S = "static void __";
-
-  S += funcName;
-  S += "_block_copy_" + utostr(i);
-  S += "(" + StructRef;
-  S += "*dst, " + StructRef;
-  S += "*src) {";
-  for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = ImportedBlockDecls.begin(),
-      E = ImportedBlockDecls.end(); I != E; ++I) {
-    ValueDecl *VD = (*I);
-    S += "_Block_object_assign((void*)&dst->";
-    S += (*I)->getNameAsString();
-    S += ", (void*)src->";
-    S += (*I)->getNameAsString();
-    if (BlockByRefDeclsPtrSet.count((*I)))
-      S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);";
-    else if (VD->getType()->isBlockPointerType())
-      S += ", " + utostr(BLOCK_FIELD_IS_BLOCK) + "/*BLOCK_FIELD_IS_BLOCK*/);";
-    else
-      S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);";
-  }
-  S += "}\n";
-  
-  S += "\nstatic void __";
-  S += funcName;
-  S += "_block_dispose_" + utostr(i);
-  S += "(" + StructRef;
-  S += "*src) {";
-  for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = ImportedBlockDecls.begin(),
-      E = ImportedBlockDecls.end(); I != E; ++I) {
-    ValueDecl *VD = (*I);
-    S += "_Block_object_dispose((void*)src->";
-    S += (*I)->getNameAsString();
-    if (BlockByRefDeclsPtrSet.count((*I)))
-      S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);";
-    else if (VD->getType()->isBlockPointerType())
-      S += ", " + utostr(BLOCK_FIELD_IS_BLOCK) + "/*BLOCK_FIELD_IS_BLOCK*/);";
-    else
-      S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);";
-  }
-  S += "}\n";
-  return S;
-}
-
-std::string RewriteModernObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag, 
-                                             std::string Desc) {
-  std::string S = "\nstruct " + Tag;
-  std::string Constructor = "  " + Tag;
-
-  S += " {\n  struct __block_impl impl;\n";
-  S += "  struct " + Desc;
-  S += "* Desc;\n";
-
-  Constructor += "(void *fp, "; // Invoke function pointer.
-  Constructor += "struct " + Desc; // Descriptor pointer.
-  Constructor += " *desc";
-
-  if (BlockDeclRefs.size()) {
-    // Output all "by copy" declarations.
-    for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(),
-         E = BlockByCopyDecls.end(); I != E; ++I) {
-      S += "  ";
-      std::string FieldName = (*I)->getNameAsString();
-      std::string ArgName = "_" + FieldName;
-      // Handle nested closure invocation. For example:
-      //
-      //   void (^myImportedBlock)(void);
-      //   myImportedBlock  = ^(void) { setGlobalInt(x + y); };
-      //
-      //   void (^anotherBlock)(void);
-      //   anotherBlock = ^(void) {
-      //     myImportedBlock(); // import and invoke the closure
-      //   };
-      //
-      if (isTopLevelBlockPointerType((*I)->getType())) {
-        S += "struct __block_impl *";
-        Constructor += ", void *" + ArgName;
-      } else {
-        QualType QT = (*I)->getType();
-        if (HasLocalVariableExternalStorage(*I))
-          QT = Context->getPointerType(QT);
-        QT.getAsStringInternal(FieldName, Context->getPrintingPolicy());
-        QT.getAsStringInternal(ArgName, Context->getPrintingPolicy());
-        Constructor += ", " + ArgName;
-      }
-      S += FieldName + ";\n";
-    }
-    // Output all "by ref" declarations.
-    for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(),
-         E = BlockByRefDecls.end(); I != E; ++I) {
-      S += "  ";
-      std::string FieldName = (*I)->getNameAsString();
-      std::string ArgName = "_" + FieldName;
-      {
-        std::string TypeString;
-        RewriteByRefString(TypeString, FieldName, (*I));
-        TypeString += " *";
-        FieldName = TypeString + FieldName;
-        ArgName = TypeString + ArgName;
-        Constructor += ", " + ArgName;
-      }
-      S += FieldName + "; // by ref\n";
-    }
-    // Finish writing the constructor.
-    Constructor += ", int flags=0)";
-    // Initialize all "by copy" arguments.
-    bool firsTime = true;
-    for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(),
-         E = BlockByCopyDecls.end(); I != E; ++I) {
-      std::string Name = (*I)->getNameAsString();
-        if (firsTime) {
-          Constructor += " : ";
-          firsTime = false;
-        }
-        else
-          Constructor += ", ";
-        if (isTopLevelBlockPointerType((*I)->getType()))
-          Constructor += Name + "((struct __block_impl *)_" + Name + ")";
-        else
-          Constructor += Name + "(_" + Name + ")";
-    }
-    // Initialize all "by ref" arguments.
-    for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(),
-         E = BlockByRefDecls.end(); I != E; ++I) {
-      std::string Name = (*I)->getNameAsString();
-      if (firsTime) {
-        Constructor += " : ";
-        firsTime = false;
-      }
-      else
-        Constructor += ", ";
-      Constructor += Name + "(_" + Name + "->__forwarding)";
-    }
-    
-    Constructor += " {\n";
-    if (GlobalVarDecl)
-      Constructor += "    impl.isa = &_NSConcreteGlobalBlock;\n";
-    else
-      Constructor += "    impl.isa = &_NSConcreteStackBlock;\n";
-    Constructor += "    impl.Flags = flags;\n    impl.FuncPtr = fp;\n";
-
-    Constructor += "    Desc = desc;\n";
-  } else {
-    // Finish writing the constructor.
-    Constructor += ", int flags=0) {\n";
-    if (GlobalVarDecl)
-      Constructor += "    impl.isa = &_NSConcreteGlobalBlock;\n";
-    else
-      Constructor += "    impl.isa = &_NSConcreteStackBlock;\n";
-    Constructor += "    impl.Flags = flags;\n    impl.FuncPtr = fp;\n";
-    Constructor += "    Desc = desc;\n";
-  }
-  Constructor += "  ";
-  Constructor += "}\n";
-  S += Constructor;
-  S += "};\n";
-  return S;
-}
-
-std::string RewriteModernObjC::SynthesizeBlockDescriptor(std::string DescTag, 
-                                                   std::string ImplTag, int i,
-                                                   StringRef FunName,
-                                                   unsigned hasCopy) {
-  std::string S = "\nstatic struct " + DescTag;
-  
-  S += " {\n  size_t reserved;\n";
-  S += "  size_t Block_size;\n";
-  if (hasCopy) {
-    S += "  void (*copy)(struct ";
-    S += ImplTag; S += "*, struct ";
-    S += ImplTag; S += "*);\n";
-    
-    S += "  void (*dispose)(struct ";
-    S += ImplTag; S += "*);\n";
-  }
-  S += "} ";
-
-  S += DescTag + "_DATA = { 0, sizeof(struct ";
-  S += ImplTag + ")";
-  if (hasCopy) {
-    S += ", __" + FunName.str() + "_block_copy_" + utostr(i);
-    S += ", __" + FunName.str() + "_block_dispose_" + utostr(i);
-  }
-  S += "};\n";
-  return S;
-}
-
-void RewriteModernObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart,
-                                          StringRef FunName) {
-  bool RewriteSC = (GlobalVarDecl &&
-                    !Blocks.empty() &&
-                    GlobalVarDecl->getStorageClass() == SC_Static &&
-                    GlobalVarDecl->getType().getCVRQualifiers());
-  if (RewriteSC) {
-    std::string SC(" void __");
-    SC += GlobalVarDecl->getNameAsString();
-    SC += "() {}";
-    InsertText(FunLocStart, SC);
-  }
-  
-  // Insert closures that were part of the function.
-  for (unsigned i = 0, count=0; i < Blocks.size(); i++) {
-    CollectBlockDeclRefInfo(Blocks[i]);
-    // Need to copy-in the inner copied-in variables not actually used in this
-    // block.
-    for (int j = 0; j < InnerDeclRefsCount[i]; j++) {
-      DeclRefExpr *Exp = InnerDeclRefs[count++];
-      ValueDecl *VD = Exp->getDecl();
-      BlockDeclRefs.push_back(Exp);
-      if (!VD->hasAttr<BlocksAttr>()) {
-        if (!BlockByCopyDeclsPtrSet.count(VD)) {
-          BlockByCopyDeclsPtrSet.insert(VD);
-          BlockByCopyDecls.push_back(VD);
-        }
-        continue;
-      }
-
-      if (!BlockByRefDeclsPtrSet.count(VD)) {
-        BlockByRefDeclsPtrSet.insert(VD);
-        BlockByRefDecls.push_back(VD);
-      }
-
-      // imported objects in the inner blocks not used in the outer
-      // blocks must be copied/disposed in the outer block as well.
-      if (VD->getType()->isObjCObjectPointerType() || 
-          VD->getType()->isBlockPointerType())
-        ImportedBlockDecls.insert(VD);
-    }
-
-    std::string ImplTag = "__" + FunName.str() + "_block_impl_" + utostr(i);
-    std::string DescTag = "__" + FunName.str() + "_block_desc_" + utostr(i);
-
-    std::string CI = SynthesizeBlockImpl(Blocks[i], ImplTag, DescTag);
-
-    InsertText(FunLocStart, CI);
-
-    std::string CF = SynthesizeBlockFunc(Blocks[i], i, FunName, ImplTag);
-
-    InsertText(FunLocStart, CF);
-
-    if (ImportedBlockDecls.size()) {
-      std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, ImplTag);
-      InsertText(FunLocStart, HF);
-    }
-    std::string BD = SynthesizeBlockDescriptor(DescTag, ImplTag, i, FunName,
-                                               ImportedBlockDecls.size() > 0);
-    InsertText(FunLocStart, BD);
-
-    BlockDeclRefs.clear();
-    BlockByRefDecls.clear();
-    BlockByRefDeclsPtrSet.clear();
-    BlockByCopyDecls.clear();
-    BlockByCopyDeclsPtrSet.clear();
-    ImportedBlockDecls.clear();
-  }
-  if (RewriteSC) {
-    // Must insert any 'const/volatile/static here. Since it has been
-    // removed as result of rewriting of block literals.
-    std::string SC;
-    if (GlobalVarDecl->getStorageClass() == SC_Static)
-      SC = "static ";
-    if (GlobalVarDecl->getType().isConstQualified())
-      SC += "const ";
-    if (GlobalVarDecl->getType().isVolatileQualified())
-      SC += "volatile ";
-    if (GlobalVarDecl->getType().isRestrictQualified())
-      SC += "restrict ";
-    InsertText(FunLocStart, SC);
-  }
-  if (GlobalConstructionExp) {
-    // extra fancy dance for global literal expression.
-    
-    // Always the latest block expression on the block stack.
-    std::string Tag = "__";
-    Tag += FunName;
-    Tag += "_block_impl_";
-    Tag += utostr(Blocks.size()-1);
-    std::string globalBuf = "static ";
-    globalBuf += Tag; globalBuf += " ";
-    std::string SStr;
-  
-    llvm::raw_string_ostream constructorExprBuf(SStr);
-    GlobalConstructionExp->printPretty(constructorExprBuf, 0,
-                                         PrintingPolicy(LangOpts));
-    globalBuf += constructorExprBuf.str();
-    globalBuf += ";\n";
-    InsertText(FunLocStart, globalBuf);
-    GlobalConstructionExp = 0;
-  }
-
-  Blocks.clear();
-  InnerDeclRefsCount.clear();
-  InnerDeclRefs.clear();
-  RewrittenBlockExprs.clear();
-}
-
-void RewriteModernObjC::InsertBlockLiteralsWithinFunction(FunctionDecl *FD) {
-  SourceLocation FunLocStart = 
-    (!Blocks.empty()) ? getFunctionSourceLocation(*this, FD)
-                      : FD->getTypeSpecStartLoc();
-  StringRef FuncName = FD->getName();
-
-  SynthesizeBlockLiterals(FunLocStart, FuncName);
-}
-
-static void BuildUniqueMethodName(std::string &Name,
-                                  ObjCMethodDecl *MD) {
-  ObjCInterfaceDecl *IFace = MD->getClassInterface();
-  Name = IFace->getName();
-  Name += "__" + MD->getSelector().getAsString();
-  // Convert colons to underscores.
-  std::string::size_type loc = 0;
-  while ((loc = Name.find(":", loc)) != std::string::npos)
-    Name.replace(loc, 1, "_");
-}
-
-void RewriteModernObjC::InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD) {
-  //fprintf(stderr,"In InsertBlockLiteralsWitinMethod\n");
-  //SourceLocation FunLocStart = MD->getLocStart();
-  SourceLocation FunLocStart = MD->getLocStart();
-  std::string FuncName;
-  BuildUniqueMethodName(FuncName, MD);
-  SynthesizeBlockLiterals(FunLocStart, FuncName);
-}
-
-void RewriteModernObjC::GetBlockDeclRefExprs(Stmt *S) {
-  for (Stmt::child_range CI = S->children(); CI; ++CI)
-    if (*CI) {
-      if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI))
-        GetBlockDeclRefExprs(CBE->getBody());
-      else
-        GetBlockDeclRefExprs(*CI);
-    }
-  // Handle specific things.
-  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
-    if (DRE->refersToEnclosingLocal()) {
-      // FIXME: Handle enums.
-      if (!isa<FunctionDecl>(DRE->getDecl()))
-        BlockDeclRefs.push_back(DRE);
-      if (HasLocalVariableExternalStorage(DRE->getDecl()))
-        BlockDeclRefs.push_back(DRE);
-    }
-  }
-  
-  return;
-}
-
-void RewriteModernObjC::GetInnerBlockDeclRefExprs(Stmt *S,
-                SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs,
-                llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts) {
-  for (Stmt::child_range CI = S->children(); CI; ++CI)
-    if (*CI) {
-      if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI)) {
-        InnerContexts.insert(cast<DeclContext>(CBE->getBlockDecl()));
-        GetInnerBlockDeclRefExprs(CBE->getBody(),
-                                  InnerBlockDeclRefs,
-                                  InnerContexts);
-      }
-      else
-        GetInnerBlockDeclRefExprs(*CI,
-                                  InnerBlockDeclRefs,
-                                  InnerContexts);
-
-    }
-  // Handle specific things.
-  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
-    if (DRE->refersToEnclosingLocal()) {
-      if (!isa<FunctionDecl>(DRE->getDecl()) &&
-          !InnerContexts.count(DRE->getDecl()->getDeclContext()))
-        InnerBlockDeclRefs.push_back(DRE);
-      if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl()))
-        if (Var->isFunctionOrMethodVarDecl())
-          ImportedLocalExternalDecls.insert(Var);
-    }
-  }
-  
-  return;
-}
-
-/// convertObjCTypeToCStyleType - This routine converts such objc types
-/// as qualified objects, and blocks to their closest c/c++ types that
-/// it can. It returns true if input type was modified.
-bool RewriteModernObjC::convertObjCTypeToCStyleType(QualType &T) {
-  QualType oldT = T;
-  convertBlockPointerToFunctionPointer(T);
-  if (T->isFunctionPointerType()) {
-    QualType PointeeTy;
-    if (const PointerType* PT = T->getAs<PointerType>()) {
-      PointeeTy = PT->getPointeeType();
-      if (const FunctionType *FT = PointeeTy->getAs<FunctionType>()) {
-        T = convertFunctionTypeOfBlocks(FT);
-        T = Context->getPointerType(T);
-      }
-    }
-  }
-  
-  convertToUnqualifiedObjCType(T);
-  return T != oldT;
-}
-
-/// convertFunctionTypeOfBlocks - This routine converts a function type
-/// whose result type may be a block pointer or whose argument type(s)
-/// might be block pointers to an equivalent function type replacing
-/// all block pointers to function pointers.
-QualType RewriteModernObjC::convertFunctionTypeOfBlocks(const FunctionType *FT) {
-  const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT);
-  // FTP will be null for closures that don't take arguments.
-  // Generate a funky cast.
-  SmallVector<QualType, 8> ArgTypes;
-  QualType Res = FT->getResultType();
-  bool modified = convertObjCTypeToCStyleType(Res);
-  
-  if (FTP) {
-    for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(),
-         E = FTP->arg_type_end(); I && (I != E); ++I) {
-      QualType t = *I;
-      // Make sure we convert "t (^)(...)" to "t (*)(...)".
-      if (convertObjCTypeToCStyleType(t))
-        modified = true;
-      ArgTypes.push_back(t);
-    }
-  }
-  QualType FuncType;
-  if (modified)
-    FuncType = getSimpleFunctionType(Res, ArgTypes);
-  else FuncType = QualType(FT, 0);
-  return FuncType;
-}
-
-Stmt *RewriteModernObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp) {
-  // Navigate to relevant type information.
-  const BlockPointerType *CPT = 0;
-
-  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BlockExp)) {
-    CPT = DRE->getType()->getAs<BlockPointerType>();
-  } else if (const MemberExpr *MExpr = dyn_cast<MemberExpr>(BlockExp)) {
-    CPT = MExpr->getType()->getAs<BlockPointerType>();
-  } 
-  else if (const ParenExpr *PRE = dyn_cast<ParenExpr>(BlockExp)) {
-    return SynthesizeBlockCall(Exp, PRE->getSubExpr());
-  }
-  else if (const ImplicitCastExpr *IEXPR = dyn_cast<ImplicitCastExpr>(BlockExp)) 
-    CPT = IEXPR->getType()->getAs<BlockPointerType>();
-  else if (const ConditionalOperator *CEXPR = 
-            dyn_cast<ConditionalOperator>(BlockExp)) {
-    Expr *LHSExp = CEXPR->getLHS();
-    Stmt *LHSStmt = SynthesizeBlockCall(Exp, LHSExp);
-    Expr *RHSExp = CEXPR->getRHS();
-    Stmt *RHSStmt = SynthesizeBlockCall(Exp, RHSExp);
-    Expr *CONDExp = CEXPR->getCond();
-    ConditionalOperator *CondExpr =
-      new (Context) ConditionalOperator(CONDExp,
-                                      SourceLocation(), cast<Expr>(LHSStmt),
-                                      SourceLocation(), cast<Expr>(RHSStmt),
-                                      Exp->getType(), VK_RValue, OK_Ordinary);
-    return CondExpr;
-  } else if (const ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(BlockExp)) {
-    CPT = IRE->getType()->getAs<BlockPointerType>();
-  } else if (const PseudoObjectExpr *POE
-               = dyn_cast<PseudoObjectExpr>(BlockExp)) {
-    CPT = POE->getType()->castAs<BlockPointerType>();
-  } else {
-    assert(1 && "RewriteBlockClass: Bad type");
-  }
-  assert(CPT && "RewriteBlockClass: Bad type");
-  const FunctionType *FT = CPT->getPointeeType()->getAs<FunctionType>();
-  assert(FT && "RewriteBlockClass: Bad type");
-  const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT);
-  // FTP will be null for closures that don't take arguments.
-
-  RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
-                                      SourceLocation(), SourceLocation(),
-                                      &Context->Idents.get("__block_impl"));
-  QualType PtrBlock = Context->getPointerType(Context->getTagDeclType(RD));
-
-  // Generate a funky cast.
-  SmallVector<QualType, 8> ArgTypes;
-
-  // Push the block argument type.
-  ArgTypes.push_back(PtrBlock);
-  if (FTP) {
-    for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(),
-         E = FTP->arg_type_end(); I && (I != E); ++I) {
-      QualType t = *I;
-      // Make sure we convert "t (^)(...)" to "t (*)(...)".
-      if (!convertBlockPointerToFunctionPointer(t))
-        convertToUnqualifiedObjCType(t);
-      ArgTypes.push_back(t);
-    }
-  }
-  // Now do the pointer to function cast.
-  QualType PtrToFuncCastType = getSimpleFunctionType(Exp->getType(), ArgTypes);
-
-  PtrToFuncCastType = Context->getPointerType(PtrToFuncCastType);
-
-  CastExpr *BlkCast = NoTypeInfoCStyleCastExpr(Context, PtrBlock,
-                                               CK_BitCast,
-                                               const_cast<Expr*>(BlockExp));
-  // Don't forget the parens to enforce the proper binding.
-  ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(),
-                                          BlkCast);
-  //PE->dump();
-
-  FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(),
-                                    SourceLocation(),
-                                    &Context->Idents.get("FuncPtr"),
-                                    Context->VoidPtrTy, 0,
-                                    /*BitWidth=*/0, /*Mutable=*/true,
-                                    ICIS_NoInit);
-  MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(),
-                                            FD->getType(), VK_LValue,
-                                            OK_Ordinary);
-
-  
-  CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(Context, PtrToFuncCastType,
-                                                CK_BitCast, ME);
-  PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), FunkCast);
-
-  SmallVector<Expr*, 8> BlkExprs;
-  // Add the implicit argument.
-  BlkExprs.push_back(BlkCast);
-  // Add the user arguments.
-  for (CallExpr::arg_iterator I = Exp->arg_begin(),
-       E = Exp->arg_end(); I != E; ++I) {
-    BlkExprs.push_back(*I);
-  }
-  CallExpr *CE = new (Context) CallExpr(*Context, PE, BlkExprs,
-                                        Exp->getType(), VK_RValue,
-                                        SourceLocation());
-  return CE;
-}
-
-// We need to return the rewritten expression to handle cases where the
-// DeclRefExpr is embedded in another expression being rewritten.
-// For example:
-//
-// int main() {
-//    __block Foo *f;
-//    __block int i;
-//
-//    void (^myblock)() = ^() {
-//        [f test]; // f is a DeclRefExpr embedded in a message (which is being rewritten).
-//        i = 77;
-//    };
-//}
-Stmt *RewriteModernObjC::RewriteBlockDeclRefExpr(DeclRefExpr *DeclRefExp) {
-  // Rewrite the byref variable into BYREFVAR->__forwarding->BYREFVAR 
-  // for each DeclRefExp where BYREFVAR is name of the variable.
-  ValueDecl *VD = DeclRefExp->getDecl();
-  bool isArrow = DeclRefExp->refersToEnclosingLocal();
-  
-  FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(),
-                                    SourceLocation(),
-                                    &Context->Idents.get("__forwarding"), 
-                                    Context->VoidPtrTy, 0,
-                                    /*BitWidth=*/0, /*Mutable=*/true,
-                                    ICIS_NoInit);
-  MemberExpr *ME = new (Context) MemberExpr(DeclRefExp, isArrow,
-                                            FD, SourceLocation(),
-                                            FD->getType(), VK_LValue,
-                                            OK_Ordinary);
-
-  StringRef Name = VD->getName();
-  FD = FieldDecl::Create(*Context, 0, SourceLocation(), SourceLocation(),
-                         &Context->Idents.get(Name), 
-                         Context->VoidPtrTy, 0,
-                         /*BitWidth=*/0, /*Mutable=*/true,
-                         ICIS_NoInit);
-  ME = new (Context) MemberExpr(ME, true, FD, SourceLocation(),
-                                DeclRefExp->getType(), VK_LValue, OK_Ordinary);
-  
-  
-  
-  // Need parens to enforce precedence.
-  ParenExpr *PE = new (Context) ParenExpr(DeclRefExp->getExprLoc(), 
-                                          DeclRefExp->getExprLoc(), 
-                                          ME);
-  ReplaceStmt(DeclRefExp, PE);
-  return PE;
-}
-
-// Rewrites the imported local variable V with external storage 
-// (static, extern, etc.) as *V
-//
-Stmt *RewriteModernObjC::RewriteLocalVariableExternalStorage(DeclRefExpr *DRE) {
-  ValueDecl *VD = DRE->getDecl();
-  if (VarDecl *Var = dyn_cast<VarDecl>(VD))
-    if (!ImportedLocalExternalDecls.count(Var))
-      return DRE;
-  Expr *Exp = new (Context) UnaryOperator(DRE, UO_Deref, DRE->getType(),
-                                          VK_LValue, OK_Ordinary,
-                                          DRE->getLocation());
-  // Need parens to enforce precedence.
-  ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 
-                                          Exp);
-  ReplaceStmt(DRE, PE);
-  return PE;
-}
-
-void RewriteModernObjC::RewriteCastExpr(CStyleCastExpr *CE) {
-  SourceLocation LocStart = CE->getLParenLoc();
-  SourceLocation LocEnd = CE->getRParenLoc();
-
-  // Need to avoid trying to rewrite synthesized casts.
-  if (LocStart.isInvalid())
-    return;
-  // Need to avoid trying to rewrite casts contained in macros.
-  if (!Rewriter::isRewritable(LocStart) || !Rewriter::isRewritable(LocEnd))
-    return;
-
-  const char *startBuf = SM->getCharacterData(LocStart);
-  const char *endBuf = SM->getCharacterData(LocEnd);
-  QualType QT = CE->getType();
-  const Type* TypePtr = QT->getAs<Type>();
-  if (isa<TypeOfExprType>(TypePtr)) {
-    const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
-    QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType();
-    std::string TypeAsString = "(";
-    RewriteBlockPointerType(TypeAsString, QT);
-    TypeAsString += ")";
-    ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString);
-    return;
-  }
-  // advance the location to startArgList.
-  const char *argPtr = startBuf;
-
-  while (*argPtr++ && (argPtr < endBuf)) {
-    switch (*argPtr) {
-    case '^':
-      // Replace the '^' with '*'.
-      LocStart = LocStart.getLocWithOffset(argPtr-startBuf);
-      ReplaceText(LocStart, 1, "*");
-      break;
-    }
-  }
-  return;
-}
-
-void RewriteModernObjC::RewriteImplicitCastObjCExpr(CastExpr *IC) {
-  CastKind CastKind = IC->getCastKind();
-  if (CastKind != CK_BlockPointerToObjCPointerCast &&
-      CastKind != CK_AnyPointerToBlockPointerCast)
-    return;
-  
-  QualType QT = IC->getType();
-  (void)convertBlockPointerToFunctionPointer(QT);
-  std::string TypeString(QT.getAsString(Context->getPrintingPolicy()));
-  std::string Str = "(";
-  Str += TypeString;
-  Str += ")";
-  InsertText(IC->getSubExpr()->getLocStart(), &Str[0], Str.size());
-
-  return;
-}
-
-void RewriteModernObjC::RewriteBlockPointerFunctionArgs(FunctionDecl *FD) {
-  SourceLocation DeclLoc = FD->getLocation();
-  unsigned parenCount = 0;
-
-  // We have 1 or more arguments that have closure pointers.
-  const char *startBuf = SM->getCharacterData(DeclLoc);
-  const char *startArgList = strchr(startBuf, '(');
-
-  assert((*startArgList == '(') && "Rewriter fuzzy parser confused");
-
-  parenCount++;
-  // advance the location to startArgList.
-  DeclLoc = DeclLoc.getLocWithOffset(startArgList-startBuf);
-  assert((DeclLoc.isValid()) && "Invalid DeclLoc");
-
-  const char *argPtr = startArgList;
-
-  while (*argPtr++ && parenCount) {
-    switch (*argPtr) {
-    case '^':
-      // Replace the '^' with '*'.
-      DeclLoc = DeclLoc.getLocWithOffset(argPtr-startArgList);
-      ReplaceText(DeclLoc, 1, "*");
-      break;
-    case '(':
-      parenCount++;
-      break;
-    case ')':
-      parenCount--;
-      break;
-    }
-  }
-  return;
-}
-
-bool RewriteModernObjC::PointerTypeTakesAnyBlockArguments(QualType QT) {
-  const FunctionProtoType *FTP;
-  const PointerType *PT = QT->getAs<PointerType>();
-  if (PT) {
-    FTP = PT->getPointeeType()->getAs<FunctionProtoType>();
-  } else {
-    const BlockPointerType *BPT = QT->getAs<BlockPointerType>();
-    assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
-    FTP = BPT->getPointeeType()->getAs<FunctionProtoType>();
-  }
-  if (FTP) {
-    for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(),
-         E = FTP->arg_type_end(); I != E; ++I)
-      if (isTopLevelBlockPointerType(*I))
-        return true;
-  }
-  return false;
-}
-
-bool RewriteModernObjC::PointerTypeTakesAnyObjCQualifiedType(QualType QT) {
-  const FunctionProtoType *FTP;
-  const PointerType *PT = QT->getAs<PointerType>();
-  if (PT) {
-    FTP = PT->getPointeeType()->getAs<FunctionProtoType>();
-  } else {
-    const BlockPointerType *BPT = QT->getAs<BlockPointerType>();
-    assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
-    FTP = BPT->getPointeeType()->getAs<FunctionProtoType>();
-  }
-  if (FTP) {
-    for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(),
-         E = FTP->arg_type_end(); I != E; ++I) {
-      if ((*I)->isObjCQualifiedIdType())
-        return true;
-      if ((*I)->isObjCObjectPointerType() &&
-          (*I)->getPointeeType()->isObjCQualifiedInterfaceType())
-        return true;
-    }
-        
-  }
-  return false;
-}
-
-void RewriteModernObjC::GetExtentOfArgList(const char *Name, const char *&LParen,
-                                     const char *&RParen) {
-  const char *argPtr = strchr(Name, '(');
-  assert((*argPtr == '(') && "Rewriter fuzzy parser confused");
-
-  LParen = argPtr; // output the start.
-  argPtr++; // skip past the left paren.
-  unsigned parenCount = 1;
-
-  while (*argPtr && parenCount) {
-    switch (*argPtr) {
-    case '(': parenCount++; break;
-    case ')': parenCount--; break;
-    default: break;
-    }
-    if (parenCount) argPtr++;
-  }
-  assert((*argPtr == ')') && "Rewriter fuzzy parser confused");
-  RParen = argPtr; // output the end
-}
-
-void RewriteModernObjC::RewriteBlockPointerDecl(NamedDecl *ND) {
-  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
-    RewriteBlockPointerFunctionArgs(FD);
-    return;
-  }
-  // Handle Variables and Typedefs.
-  SourceLocation DeclLoc = ND->getLocation();
-  QualType DeclT;
-  if (VarDecl *VD = dyn_cast<VarDecl>(ND))
-    DeclT = VD->getType();
-  else if (TypedefNameDecl *TDD = dyn_cast<TypedefNameDecl>(ND))
-    DeclT = TDD->getUnderlyingType();
-  else if (FieldDecl *FD = dyn_cast<FieldDecl>(ND))
-    DeclT = FD->getType();
-  else
-    llvm_unreachable("RewriteBlockPointerDecl(): Decl type not yet handled");
-
-  const char *startBuf = SM->getCharacterData(DeclLoc);
-  const char *endBuf = startBuf;
-  // scan backward (from the decl location) for the end of the previous decl.
-  while (*startBuf != '^' && *startBuf != ';' && startBuf != MainFileStart)
-    startBuf--;
-  SourceLocation Start = DeclLoc.getLocWithOffset(startBuf-endBuf);
-  std::string buf;
-  unsigned OrigLength=0;
-  // *startBuf != '^' if we are dealing with a pointer to function that
-  // may take block argument types (which will be handled below).
-  if (*startBuf == '^') {
-    // Replace the '^' with '*', computing a negative offset.
-    buf = '*';
-    startBuf++;
-    OrigLength++;
-  }
-  while (*startBuf != ')') {
-    buf += *startBuf;
-    startBuf++;
-    OrigLength++;
-  }
-  buf += ')';
-  OrigLength++;
-  
-  if (PointerTypeTakesAnyBlockArguments(DeclT) ||
-      PointerTypeTakesAnyObjCQualifiedType(DeclT)) {
-    // Replace the '^' with '*' for arguments.
-    // Replace id<P> with id/*<>*/
-    DeclLoc = ND->getLocation();
-    startBuf = SM->getCharacterData(DeclLoc);
-    const char *argListBegin, *argListEnd;
-    GetExtentOfArgList(startBuf, argListBegin, argListEnd);
-    while (argListBegin < argListEnd) {
-      if (*argListBegin == '^')
-        buf += '*';
-      else if (*argListBegin ==  '<') {
-        buf += "/*"; 
-        buf += *argListBegin++;
-        OrigLength++;
-        while (*argListBegin != '>') {
-          buf += *argListBegin++;
-          OrigLength++;
-        }
-        buf += *argListBegin;
-        buf += "*/";
-      }
-      else
-        buf += *argListBegin;
-      argListBegin++;
-      OrigLength++;
-    }
-    buf += ')';
-    OrigLength++;
-  }
-  ReplaceText(Start, OrigLength, buf);
-  
-  return;
-}
-
-
-/// SynthesizeByrefCopyDestroyHelper - This routine synthesizes:
-/// void __Block_byref_id_object_copy(struct Block_byref_id_object *dst,
-///                    struct Block_byref_id_object *src) {
-///  _Block_object_assign (&_dest->object, _src->object, 
-///                        BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT
-///                        [|BLOCK_FIELD_IS_WEAK]) // object
-///  _Block_object_assign(&_dest->object, _src->object, 
-///                       BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK
-///                       [|BLOCK_FIELD_IS_WEAK]) // block
-/// }
-/// And:
-/// void __Block_byref_id_object_dispose(struct Block_byref_id_object *_src) {
-///  _Block_object_dispose(_src->object, 
-///                        BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT
-///                        [|BLOCK_FIELD_IS_WEAK]) // object
-///  _Block_object_dispose(_src->object, 
-///                         BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK
-///                         [|BLOCK_FIELD_IS_WEAK]) // block
-/// }
-
-std::string RewriteModernObjC::SynthesizeByrefCopyDestroyHelper(VarDecl *VD,
-                                                          int flag) {
-  std::string S;
-  if (CopyDestroyCache.count(flag))
-    return S;
-  CopyDestroyCache.insert(flag);
-  S = "static void __Block_byref_id_object_copy_";
-  S += utostr(flag);
-  S += "(void *dst, void *src) {\n";
-  
-  // offset into the object pointer is computed as:
-  // void * + void* + int + int + void* + void *
-  unsigned IntSize = 
-  static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
-  unsigned VoidPtrSize = 
-  static_cast<unsigned>(Context->getTypeSize(Context->VoidPtrTy));
-  
-  unsigned offset = (VoidPtrSize*4 + IntSize + IntSize)/Context->getCharWidth();
-  S += " _Block_object_assign((char*)dst + ";
-  S += utostr(offset);
-  S += ", *(void * *) ((char*)src + ";
-  S += utostr(offset);
-  S += "), ";
-  S += utostr(flag);
-  S += ");\n}\n";
-  
-  S += "static void __Block_byref_id_object_dispose_";
-  S += utostr(flag);
-  S += "(void *src) {\n";
-  S += " _Block_object_dispose(*(void * *) ((char*)src + ";
-  S += utostr(offset);
-  S += "), ";
-  S += utostr(flag);
-  S += ");\n}\n";
-  return S;
-}
-
-/// RewriteByRefVar - For each __block typex ND variable this routine transforms
-/// the declaration into:
-/// struct __Block_byref_ND {
-/// void *__isa;                  // NULL for everything except __weak pointers
-/// struct __Block_byref_ND *__forwarding;
-/// int32_t __flags;
-/// int32_t __size;
-/// void *__Block_byref_id_object_copy; // If variable is __block ObjC object
-/// void *__Block_byref_id_object_dispose; // If variable is __block ObjC object
-/// typex ND;
-/// };
-///
-/// It then replaces declaration of ND variable with:
-/// struct __Block_byref_ND ND = {__isa=0B, __forwarding=&ND, __flags=some_flag, 
-///                               __size=sizeof(struct __Block_byref_ND), 
-///                               ND=initializer-if-any};
-///
-///
-void RewriteModernObjC::RewriteByRefVar(VarDecl *ND, bool firstDecl,
-                                        bool lastDecl) {
-  int flag = 0;
-  int isa = 0;
-  SourceLocation DeclLoc = ND->getTypeSpecStartLoc();
-  if (DeclLoc.isInvalid())
-    // If type location is missing, it is because of missing type (a warning).
-    // Use variable's location which is good for this case.
-    DeclLoc = ND->getLocation();
-  const char *startBuf = SM->getCharacterData(DeclLoc);
-  SourceLocation X = ND->getLocEnd();
-  X = SM->getExpansionLoc(X);
-  const char *endBuf = SM->getCharacterData(X);
-  std::string Name(ND->getNameAsString());
-  std::string ByrefType;
-  RewriteByRefString(ByrefType, Name, ND, true);
-  ByrefType += " {\n";
-  ByrefType += "  void *__isa;\n";
-  RewriteByRefString(ByrefType, Name, ND);
-  ByrefType += " *__forwarding;\n";
-  ByrefType += " int __flags;\n";
-  ByrefType += " int __size;\n";
-  // Add void *__Block_byref_id_object_copy; 
-  // void *__Block_byref_id_object_dispose; if needed.
-  QualType Ty = ND->getType();
-  bool HasCopyAndDispose = Context->BlockRequiresCopying(Ty, ND);
-  if (HasCopyAndDispose) {
-    ByrefType += " void (*__Block_byref_id_object_copy)(void*, void*);\n";
-    ByrefType += " void (*__Block_byref_id_object_dispose)(void*);\n";
-  }
-
-  QualType T = Ty;
-  (void)convertBlockPointerToFunctionPointer(T);
-  T.getAsStringInternal(Name, Context->getPrintingPolicy());
-    
-  ByrefType += " " + Name + ";\n";
-  ByrefType += "};\n";
-  // Insert this type in global scope. It is needed by helper function.
-  SourceLocation FunLocStart;
-  if (CurFunctionDef)
-     FunLocStart = getFunctionSourceLocation(*this, CurFunctionDef);
-  else {
-    assert(CurMethodDef && "RewriteByRefVar - CurMethodDef is null");
-    FunLocStart = CurMethodDef->getLocStart();
-  }
-  InsertText(FunLocStart, ByrefType);
-  
-  if (Ty.isObjCGCWeak()) {
-    flag |= BLOCK_FIELD_IS_WEAK;
-    isa = 1;
-  }
-  if (HasCopyAndDispose) {
-    flag = BLOCK_BYREF_CALLER;
-    QualType Ty = ND->getType();
-    // FIXME. Handle __weak variable (BLOCK_FIELD_IS_WEAK) as well.
-    if (Ty->isBlockPointerType())
-      flag |= BLOCK_FIELD_IS_BLOCK;
-    else
-      flag |= BLOCK_FIELD_IS_OBJECT;
-    std::string HF = SynthesizeByrefCopyDestroyHelper(ND, flag);
-    if (!HF.empty())
-      Preamble += HF;
-  }
-  
-  // struct __Block_byref_ND ND = 
-  // {0, &ND, some_flag, __size=sizeof(struct __Block_byref_ND), 
-  //  initializer-if-any};
-  bool hasInit = (ND->getInit() != 0);
-  // FIXME. rewriter does not support __block c++ objects which
-  // require construction.
-  if (hasInit)
-    if (CXXConstructExpr *CExp = dyn_cast<CXXConstructExpr>(ND->getInit())) {
-      CXXConstructorDecl *CXXDecl = CExp->getConstructor();
-      if (CXXDecl && CXXDecl->isDefaultConstructor())
-        hasInit = false;
-    }
-  
-  unsigned flags = 0;
-  if (HasCopyAndDispose)
-    flags |= BLOCK_HAS_COPY_DISPOSE;
-  Name = ND->getNameAsString();
-  ByrefType.clear();
-  RewriteByRefString(ByrefType, Name, ND);
-  std::string ForwardingCastType("(");
-  ForwardingCastType += ByrefType + " *)";
-  ByrefType += " " + Name + " = {(void*)";
-  ByrefType += utostr(isa);
-  ByrefType += "," +  ForwardingCastType + "&" + Name + ", ";
-  ByrefType += utostr(flags);
-  ByrefType += ", ";
-  ByrefType += "sizeof(";
-  RewriteByRefString(ByrefType, Name, ND);
-  ByrefType += ")";
-  if (HasCopyAndDispose) {
-    ByrefType += ", __Block_byref_id_object_copy_";
-    ByrefType += utostr(flag);
-    ByrefType += ", __Block_byref_id_object_dispose_";
-    ByrefType += utostr(flag);
-  }
-  
-  if (!firstDecl) {
-    // In multiple __block declarations, and for all but 1st declaration,
-    // find location of the separating comma. This would be start location
-    // where new text is to be inserted.
-    DeclLoc = ND->getLocation();
-    const char *startDeclBuf = SM->getCharacterData(DeclLoc);
-    const char *commaBuf = startDeclBuf;
-    while (*commaBuf != ',')
-      commaBuf--;
-    assert((*commaBuf == ',') && "RewriteByRefVar: can't find ','");
-    DeclLoc = DeclLoc.getLocWithOffset(commaBuf - startDeclBuf);
-    startBuf = commaBuf;
-  }
-  
-  if (!hasInit) {
-    ByrefType += "};\n";
-    unsigned nameSize = Name.size();
-    // for block or function pointer declaration. Name is aleady
-    // part of the declaration.
-    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType())
-      nameSize = 1;
-    ReplaceText(DeclLoc, endBuf-startBuf+nameSize, ByrefType);
-  }
-  else {
-    ByrefType += ", ";
-    SourceLocation startLoc;
-    Expr *E = ND->getInit();
-    if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E))
-      startLoc = ECE->getLParenLoc();
-    else
-      startLoc = E->getLocStart();
-    startLoc = SM->getExpansionLoc(startLoc);
-    endBuf = SM->getCharacterData(startLoc);
-    ReplaceText(DeclLoc, endBuf-startBuf, ByrefType);
-
-    const char separator = lastDecl ? ';' : ',';
-    const char *startInitializerBuf = SM->getCharacterData(startLoc);
-    const char *separatorBuf = strchr(startInitializerBuf, separator);
-    assert((*separatorBuf == separator) && 
-           "RewriteByRefVar: can't find ';' or ','");
-    SourceLocation separatorLoc =
-      startLoc.getLocWithOffset(separatorBuf-startInitializerBuf);
-    
-    InsertText(separatorLoc, lastDecl ? "}" : "};\n");
-  }
-  return;
-}
-
-void RewriteModernObjC::CollectBlockDeclRefInfo(BlockExpr *Exp) {
-  // Add initializers for any closure decl refs.
-  GetBlockDeclRefExprs(Exp->getBody());
-  if (BlockDeclRefs.size()) {
-    // Unique all "by copy" declarations.
-    for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
-      if (!BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
-        if (!BlockByCopyDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
-          BlockByCopyDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
-          BlockByCopyDecls.push_back(BlockDeclRefs[i]->getDecl());
-        }
-      }
-    // Unique all "by ref" declarations.
-    for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
-      if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
-        if (!BlockByRefDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
-          BlockByRefDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
-          BlockByRefDecls.push_back(BlockDeclRefs[i]->getDecl());
-        }
-      }
-    // Find any imported blocks...they will need special attention.
-    for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
-      if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
-          BlockDeclRefs[i]->getType()->isObjCObjectPointerType() || 
-          BlockDeclRefs[i]->getType()->isBlockPointerType())
-        ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl());
-  }
-}
-
-FunctionDecl *RewriteModernObjC::SynthBlockInitFunctionDecl(StringRef name) {
-  IdentifierInfo *ID = &Context->Idents.get(name);
-  QualType FType = Context->getFunctionNoProtoType(Context->VoidPtrTy);
-  return FunctionDecl::Create(*Context, TUDecl, SourceLocation(),
-                              SourceLocation(), ID, FType, 0, SC_Extern,
-                              false, false);
-}
-
-Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp,
-                     const SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs) {
-  
-  const BlockDecl *block = Exp->getBlockDecl();
-  
-  Blocks.push_back(Exp);
-
-  CollectBlockDeclRefInfo(Exp);
-  
-  // Add inner imported variables now used in current block.
- int countOfInnerDecls = 0;
-  if (!InnerBlockDeclRefs.empty()) {
-    for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) {
-      DeclRefExpr *Exp = InnerBlockDeclRefs[i];
-      ValueDecl *VD = Exp->getDecl();
-      if (!VD->hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) {
-      // We need to save the copied-in variables in nested
-      // blocks because it is needed at the end for some of the API generations.
-      // See SynthesizeBlockLiterals routine.
-        InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
-        BlockDeclRefs.push_back(Exp);
-        BlockByCopyDeclsPtrSet.insert(VD);
-        BlockByCopyDecls.push_back(VD);
-      }
-      if (VD->hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) {
-        InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
-        BlockDeclRefs.push_back(Exp);
-        BlockByRefDeclsPtrSet.insert(VD);
-        BlockByRefDecls.push_back(VD);
-      }
-    }
-    // Find any imported blocks...they will need special attention.
-    for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++)
-      if (InnerBlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
-          InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() || 
-          InnerBlockDeclRefs[i]->getType()->isBlockPointerType())
-        ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl());
-  }
-  InnerDeclRefsCount.push_back(countOfInnerDecls);
-  
-  std::string FuncName;
-
-  if (CurFunctionDef)
-    FuncName = CurFunctionDef->getNameAsString();
-  else if (CurMethodDef)
-    BuildUniqueMethodName(FuncName, CurMethodDef);
-  else if (GlobalVarDecl)
-    FuncName = std::string(GlobalVarDecl->getNameAsString());
-
-  bool GlobalBlockExpr = 
-    block->getDeclContext()->getRedeclContext()->isFileContext();
-  
-  if (GlobalBlockExpr && !GlobalVarDecl) {
-    Diags.Report(block->getLocation(), GlobalBlockRewriteFailedDiag);
-    GlobalBlockExpr = false;
-  }
-  
-  std::string BlockNumber = utostr(Blocks.size()-1);
-
-  std::string Func = "__" + FuncName + "_block_func_" + BlockNumber;
-
-  // Get a pointer to the function type so we can cast appropriately.
-  QualType BFT = convertFunctionTypeOfBlocks(Exp->getFunctionType());
-  QualType FType = Context->getPointerType(BFT);
-
-  FunctionDecl *FD;
-  Expr *NewRep;
-
-  // Simulate a constructor call...
-  std::string Tag;
-  
-  if (GlobalBlockExpr)
-    Tag = "__global_";
-  else
-    Tag = "__";
-  Tag += FuncName + "_block_impl_" + BlockNumber;
-  
-  FD = SynthBlockInitFunctionDecl(Tag);
-  DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, false, FType, VK_RValue,
-                                               SourceLocation());
-
-  SmallVector<Expr*, 4> InitExprs;
-
-  // Initialize the block function.
-  FD = SynthBlockInitFunctionDecl(Func);
-  DeclRefExpr *Arg = new (Context) DeclRefExpr(FD, false, FD->getType(),
-                                               VK_LValue, SourceLocation());
-  CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
-                                                CK_BitCast, Arg);
-  InitExprs.push_back(castExpr);
-
-  // Initialize the block descriptor.
-  std::string DescData = "__" + FuncName + "_block_desc_" + BlockNumber + "_DATA";
-
-  VarDecl *NewVD = VarDecl::Create(*Context, TUDecl,
-                                   SourceLocation(), SourceLocation(),
-                                   &Context->Idents.get(DescData.c_str()),
-                                   Context->VoidPtrTy, 0,
-                                   SC_Static);
-  UnaryOperator *DescRefExpr =
-    new (Context) UnaryOperator(new (Context) DeclRefExpr(NewVD, false,
-                                                          Context->VoidPtrTy,
-                                                          VK_LValue,
-                                                          SourceLocation()), 
-                                UO_AddrOf,
-                                Context->getPointerType(Context->VoidPtrTy), 
-                                VK_RValue, OK_Ordinary,
-                                SourceLocation());
-  InitExprs.push_back(DescRefExpr); 
-  
-  // Add initializers for any closure decl refs.
-  if (BlockDeclRefs.size()) {
-    Expr *Exp;
-    // Output all "by copy" declarations.
-    for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(),
-         E = BlockByCopyDecls.end(); I != E; ++I) {
-      if (isObjCType((*I)->getType())) {
-        // FIXME: Conform to ABI ([[obj retain] autorelease]).
-        FD = SynthBlockInitFunctionDecl((*I)->getName());
-        Exp = new (Context) DeclRefExpr(FD, false, FD->getType(),
-                                        VK_LValue, SourceLocation());
-        if (HasLocalVariableExternalStorage(*I)) {
-          QualType QT = (*I)->getType();
-          QT = Context->getPointerType(QT);
-          Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue,
-                                            OK_Ordinary, SourceLocation());
-        }
-      } else if (isTopLevelBlockPointerType((*I)->getType())) {
-        FD = SynthBlockInitFunctionDecl((*I)->getName());
-        Arg = new (Context) DeclRefExpr(FD, false, FD->getType(),
-                                        VK_LValue, SourceLocation());
-        Exp = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
-                                       CK_BitCast, Arg);
-      } else {
-        FD = SynthBlockInitFunctionDecl((*I)->getName());
-        Exp = new (Context) DeclRefExpr(FD, false, FD->getType(),
-                                        VK_LValue, SourceLocation());
-        if (HasLocalVariableExternalStorage(*I)) {
-          QualType QT = (*I)->getType();
-          QT = Context->getPointerType(QT);
-          Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue,
-                                            OK_Ordinary, SourceLocation());
-        }
-        
-      }
-      InitExprs.push_back(Exp);
-    }
-    // Output all "by ref" declarations.
-    for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(),
-         E = BlockByRefDecls.end(); I != E; ++I) {
-      ValueDecl *ND = (*I);
-      std::string Name(ND->getNameAsString());
-      std::string RecName;
-      RewriteByRefString(RecName, Name, ND, true);
-      IdentifierInfo *II = &Context->Idents.get(RecName.c_str() 
-                                                + sizeof("struct"));
-      RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
-                                          SourceLocation(), SourceLocation(),
-                                          II);
-      assert(RD && "SynthBlockInitExpr(): Can't find RecordDecl");
-      QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
-      
-      FD = SynthBlockInitFunctionDecl((*I)->getName());
-      Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue,
-                                      SourceLocation());
-      bool isNestedCapturedVar = false;
-      if (block)
-        for (BlockDecl::capture_const_iterator ci = block->capture_begin(),
-             ce = block->capture_end(); ci != ce; ++ci) {
-          const VarDecl *variable = ci->getVariable();
-          if (variable == ND && ci->isNested()) {
-            assert (ci->isByRef() && 
-                    "SynthBlockInitExpr - captured block variable is not byref");
-            isNestedCapturedVar = true;
-            break;
-          }
-        }
-      // captured nested byref variable has its address passed. Do not take
-      // its address again.
-      if (!isNestedCapturedVar)
-          Exp = new (Context) UnaryOperator(Exp, UO_AddrOf,
-                                     Context->getPointerType(Exp->getType()),
-                                     VK_RValue, OK_Ordinary, SourceLocation());
-      Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp);
-      InitExprs.push_back(Exp);
-    }
-  }
-  if (ImportedBlockDecls.size()) {
-    // generate BLOCK_HAS_COPY_DISPOSE(have helper funcs) | BLOCK_HAS_DESCRIPTOR
-    int flag = (BLOCK_HAS_COPY_DISPOSE | BLOCK_HAS_DESCRIPTOR);
-    unsigned IntSize = 
-      static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
-    Expr *FlagExp = IntegerLiteral::Create(*Context, llvm::APInt(IntSize, flag), 
-                                           Context->IntTy, SourceLocation());
-    InitExprs.push_back(FlagExp);
-  }
-  NewRep = new (Context) CallExpr(*Context, DRE, InitExprs,
-                                  FType, VK_LValue, SourceLocation());
-  
-  if (GlobalBlockExpr) {
-    assert (GlobalConstructionExp == 0 && 
-            "SynthBlockInitExpr - GlobalConstructionExp must be null");
-    GlobalConstructionExp = NewRep;
-    NewRep = DRE;
-  }
-  
-  NewRep = new (Context) UnaryOperator(NewRep, UO_AddrOf,
-                             Context->getPointerType(NewRep->getType()),
-                             VK_RValue, OK_Ordinary, SourceLocation());
-  NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast,
-                                    NewRep);
-  BlockDeclRefs.clear();
-  BlockByRefDecls.clear();
-  BlockByRefDeclsPtrSet.clear();
-  BlockByCopyDecls.clear();
-  BlockByCopyDeclsPtrSet.clear();
-  ImportedBlockDecls.clear();
-  return NewRep;
-}
-
-bool RewriteModernObjC::IsDeclStmtInForeachHeader(DeclStmt *DS) {
-  if (const ObjCForCollectionStmt * CS = 
-      dyn_cast<ObjCForCollectionStmt>(Stmts.back()))
-        return CS->getElement() == DS;
-  return false;
-}
-
-//===----------------------------------------------------------------------===//
-// Function Body / Expression rewriting
-//===----------------------------------------------------------------------===//
-
-Stmt *RewriteModernObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) {
-  if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
-      isa<DoStmt>(S) || isa<ForStmt>(S))
-    Stmts.push_back(S);
-  else if (isa<ObjCForCollectionStmt>(S)) {
-    Stmts.push_back(S);
-    ObjCBcLabelNo.push_back(++BcLabelCount);
-  }
-
-  // Pseudo-object operations and ivar references need special
-  // treatment because we're going to recursively rewrite them.
-  if (PseudoObjectExpr *PseudoOp = dyn_cast<PseudoObjectExpr>(S)) {
-    if (isa<BinaryOperator>(PseudoOp->getSyntacticForm())) {
-      return RewritePropertyOrImplicitSetter(PseudoOp);
-    } else {
-      return RewritePropertyOrImplicitGetter(PseudoOp);
-    }
-  } else if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) {
-    return RewriteObjCIvarRefExpr(IvarRefExpr);
-  }
-  else if (isa<OpaqueValueExpr>(S))
-    S = cast<OpaqueValueExpr>(S)->getSourceExpr();
-
-  SourceRange OrigStmtRange = S->getSourceRange();
-
-  // Perform a bottom up rewrite of all children.
-  for (Stmt::child_range CI = S->children(); CI; ++CI)
-    if (*CI) {
-      Stmt *childStmt = (*CI);
-      Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(childStmt);
-      if (newStmt) {
-        *CI = newStmt;
-      }
-    }
-
-  if (BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
-    SmallVector<DeclRefExpr *, 8> InnerBlockDeclRefs;
-    llvm::SmallPtrSet<const DeclContext *, 8> InnerContexts;
-    InnerContexts.insert(BE->getBlockDecl());
-    ImportedLocalExternalDecls.clear();
-    GetInnerBlockDeclRefExprs(BE->getBody(),
-                              InnerBlockDeclRefs, InnerContexts);
-    // Rewrite the block body in place.
-    Stmt *SaveCurrentBody = CurrentBody;
-    CurrentBody = BE->getBody();
-    PropParentMap = 0;
-    // block literal on rhs of a property-dot-sytax assignment
-    // must be replaced by its synthesize ast so getRewrittenText
-    // works as expected. In this case, what actually ends up on RHS
-    // is the blockTranscribed which is the helper function for the
-    // block literal; as in: self.c = ^() {[ace ARR];};
-    bool saveDisableReplaceStmt = DisableReplaceStmt;
-    DisableReplaceStmt = false;
-    RewriteFunctionBodyOrGlobalInitializer(BE->getBody());
-    DisableReplaceStmt = saveDisableReplaceStmt;
-    CurrentBody = SaveCurrentBody;
-    PropParentMap = 0;
-    ImportedLocalExternalDecls.clear();
-    // Now we snarf the rewritten text and stash it away for later use.
-    std::string Str = Rewrite.getRewrittenText(BE->getSourceRange());
-    RewrittenBlockExprs[BE] = Str;
-
-    Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs);
-                            
-    //blockTranscribed->dump();
-    ReplaceStmt(S, blockTranscribed);
-    return blockTranscribed;
-  }
-  // Handle specific things.
-  if (ObjCEncodeExpr *AtEncode = dyn_cast<ObjCEncodeExpr>(S))
-    return RewriteAtEncode(AtEncode);
-
-  if (ObjCSelectorExpr *AtSelector = dyn_cast<ObjCSelectorExpr>(S))
-    return RewriteAtSelector(AtSelector);
-
-  if (ObjCStringLiteral *AtString = dyn_cast<ObjCStringLiteral>(S))
-    return RewriteObjCStringLiteral(AtString);
-  
-  if (ObjCBoolLiteralExpr *BoolLitExpr = dyn_cast<ObjCBoolLiteralExpr>(S))
-    return RewriteObjCBoolLiteralExpr(BoolLitExpr);
-  
-  if (ObjCBoxedExpr *BoxedExpr = dyn_cast<ObjCBoxedExpr>(S))
-    return RewriteObjCBoxedExpr(BoxedExpr);
-  
-  if (ObjCArrayLiteral *ArrayLitExpr = dyn_cast<ObjCArrayLiteral>(S))
-    return RewriteObjCArrayLiteralExpr(ArrayLitExpr);
-  
-  if (ObjCDictionaryLiteral *DictionaryLitExpr = 
-        dyn_cast<ObjCDictionaryLiteral>(S))
-    return RewriteObjCDictionaryLiteralExpr(DictionaryLitExpr);
-
-  if (ObjCMessageExpr *MessExpr = dyn_cast<ObjCMessageExpr>(S)) {
-#if 0
-    // Before we rewrite it, put the original message expression in a comment.
-    SourceLocation startLoc = MessExpr->getLocStart();
-    SourceLocation endLoc = MessExpr->getLocEnd();
-
-    const char *startBuf = SM->getCharacterData(startLoc);
-    const char *endBuf = SM->getCharacterData(endLoc);
-
-    std::string messString;
-    messString += "// ";
-    messString.append(startBuf, endBuf-startBuf+1);
-    messString += "\n";
-
-    // FIXME: Missing definition of
-    // InsertText(clang::SourceLocation, char const*, unsigned int).
-    // InsertText(startLoc, messString.c_str(), messString.size());
-    // Tried this, but it didn't work either...
-    // ReplaceText(startLoc, 0, messString.c_str(), messString.size());
-#endif
-    return RewriteMessageExpr(MessExpr);
-  }
-
-  if (ObjCAutoreleasePoolStmt *StmtAutoRelease = 
-        dyn_cast<ObjCAutoreleasePoolStmt>(S)) {
-    return RewriteObjCAutoreleasePoolStmt(StmtAutoRelease);
-  }
-  
-  if (ObjCAtTryStmt *StmtTry = dyn_cast<ObjCAtTryStmt>(S))
-    return RewriteObjCTryStmt(StmtTry);
-
-  if (ObjCAtSynchronizedStmt *StmtTry = dyn_cast<ObjCAtSynchronizedStmt>(S))
-    return RewriteObjCSynchronizedStmt(StmtTry);
-
-  if (ObjCAtThrowStmt *StmtThrow = dyn_cast<ObjCAtThrowStmt>(S))
-    return RewriteObjCThrowStmt(StmtThrow);
-
-  if (ObjCProtocolExpr *ProtocolExp = dyn_cast<ObjCProtocolExpr>(S))
-    return RewriteObjCProtocolExpr(ProtocolExp);
-
-  if (ObjCForCollectionStmt *StmtForCollection =
-        dyn_cast<ObjCForCollectionStmt>(S))
-    return RewriteObjCForCollectionStmt(StmtForCollection,
-                                        OrigStmtRange.getEnd());
-  if (BreakStmt *StmtBreakStmt =
-      dyn_cast<BreakStmt>(S))
-    return RewriteBreakStmt(StmtBreakStmt);
-  if (ContinueStmt *StmtContinueStmt =
-      dyn_cast<ContinueStmt>(S))
-    return RewriteContinueStmt(StmtContinueStmt);
-
-  // Need to check for protocol refs (id <P>, Foo <P> *) in variable decls
-  // and cast exprs.
-  if (DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
-    // FIXME: What we're doing here is modifying the type-specifier that
-    // precedes the first Decl.  In the future the DeclGroup should have
-    // a separate type-specifier that we can rewrite.
-    // NOTE: We need to avoid rewriting the DeclStmt if it is within
-    // the context of an ObjCForCollectionStmt. For example:
-    //   NSArray *someArray;
-    //   for (id <FooProtocol> index in someArray) ;
-    // This is because RewriteObjCForCollectionStmt() does textual rewriting 
-    // and it depends on the original text locations/positions.
-    if (Stmts.empty() || !IsDeclStmtInForeachHeader(DS))
-      RewriteObjCQualifiedInterfaceTypes(*DS->decl_begin());
-
-    // Blocks rewrite rules.
-    for (DeclStmt::decl_iterator DI = DS->decl_begin(), DE = DS->decl_end();
-         DI != DE; ++DI) {
-      Decl *SD = *DI;
-      if (ValueDecl *ND = dyn_cast<ValueDecl>(SD)) {
-        if (isTopLevelBlockPointerType(ND->getType()))
-          RewriteBlockPointerDecl(ND);
-        else if (ND->getType()->isFunctionPointerType())
-          CheckFunctionPointerDecl(ND->getType(), ND);
-        if (VarDecl *VD = dyn_cast<VarDecl>(SD)) {
-          if (VD->hasAttr<BlocksAttr>()) {
-            static unsigned uniqueByrefDeclCount = 0;
-            assert(!BlockByRefDeclNo.count(ND) &&
-              "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl");
-            BlockByRefDeclNo[ND] = uniqueByrefDeclCount++;
-            RewriteByRefVar(VD, (DI == DS->decl_begin()), ((DI+1) == DE));
-          }
-          else           
-            RewriteTypeOfDecl(VD);
-        }
-      }
-      if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(SD)) {
-        if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
-          RewriteBlockPointerDecl(TD);
-        else if (TD->getUnderlyingType()->isFunctionPointerType())
-          CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
-      }
-    }
-  }
-
-  if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(S))
-    RewriteObjCQualifiedInterfaceTypes(CE);
-
-  if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
-      isa<DoStmt>(S) || isa<ForStmt>(S)) {
-    assert(!Stmts.empty() && "Statement stack is empty");
-    assert ((isa<SwitchStmt>(Stmts.back()) || isa<WhileStmt>(Stmts.back()) ||
-             isa<DoStmt>(Stmts.back()) || isa<ForStmt>(Stmts.back()))
-            && "Statement stack mismatch");
-    Stmts.pop_back();
-  }
-  // Handle blocks rewriting.
-  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
-    ValueDecl *VD = DRE->getDecl(); 
-    if (VD->hasAttr<BlocksAttr>())
-      return RewriteBlockDeclRefExpr(DRE);
-    if (HasLocalVariableExternalStorage(VD))
-      return RewriteLocalVariableExternalStorage(DRE);
-  }
-  
-  if (CallExpr *CE = dyn_cast<CallExpr>(S)) {
-    if (CE->getCallee()->getType()->isBlockPointerType()) {
-      Stmt *BlockCall = SynthesizeBlockCall(CE, CE->getCallee());
-      ReplaceStmt(S, BlockCall);
-      return BlockCall;
-    }
-  }
-  if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(S)) {
-    RewriteCastExpr(CE);
-  }
-  if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(S)) {
-    RewriteImplicitCastObjCExpr(ICE);
-  }
-#if 0
-
-  if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(S)) {
-    CastExpr *Replacement = new (Context) CastExpr(ICE->getType(),
-                                                   ICE->getSubExpr(),
-                                                   SourceLocation());
-    // Get the new text.
-    std::string SStr;
-    llvm::raw_string_ostream Buf(SStr);
-    Replacement->printPretty(Buf);
-    const std::string &Str = Buf.str();
-
-    printf("CAST = %s\n", &Str[0]);
-    InsertText(ICE->getSubExpr()->getLocStart(), &Str[0], Str.size());
-    delete S;
-    return Replacement;
-  }
-#endif
-  // Return this stmt unmodified.
-  return S;
-}
-
-void RewriteModernObjC::RewriteRecordBody(RecordDecl *RD) {
-  for (RecordDecl::field_iterator i = RD->field_begin(), 
-                                  e = RD->field_end(); i != e; ++i) {
-    FieldDecl *FD = *i;
-    if (isTopLevelBlockPointerType(FD->getType()))
-      RewriteBlockPointerDecl(FD);
-    if (FD->getType()->isObjCQualifiedIdType() ||
-        FD->getType()->isObjCQualifiedInterfaceType())
-      RewriteObjCQualifiedInterfaceTypes(FD);
-  }
-}
-
-/// HandleDeclInMainFile - This is called for each top-level decl defined in the
-/// main file of the input.
-void RewriteModernObjC::HandleDeclInMainFile(Decl *D) {
-  switch (D->getKind()) {
-    case Decl::Function: {
-      FunctionDecl *FD = cast<FunctionDecl>(D);
-      if (FD->isOverloadedOperator())
-        return;
-
-      // Since function prototypes don't have ParmDecl's, we check the function
-      // prototype. This enables us to rewrite function declarations and
-      // definitions using the same code.
-      RewriteBlocksInFunctionProtoType(FD->getType(), FD);
-
-      if (!FD->isThisDeclarationADefinition())
-        break;
-
-      // FIXME: If this should support Obj-C++, support CXXTryStmt
-      if (CompoundStmt *Body = dyn_cast_or_null<CompoundStmt>(FD->getBody())) {
-        CurFunctionDef = FD;
-        CurrentBody = Body;
-        Body =
-        cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
-        FD->setBody(Body);
-        CurrentBody = 0;
-        if (PropParentMap) {
-          delete PropParentMap;
-          PropParentMap = 0;
-        }
-        // This synthesizes and inserts the block "impl" struct, invoke function,
-        // and any copy/dispose helper functions.
-        InsertBlockLiteralsWithinFunction(FD);
-        RewriteLineDirective(D);
-        CurFunctionDef = 0;
-      }
-      break;
-    }
-    case Decl::ObjCMethod: {
-      ObjCMethodDecl *MD = cast<ObjCMethodDecl>(D);
-      if (CompoundStmt *Body = MD->getCompoundBody()) {
-        CurMethodDef = MD;
-        CurrentBody = Body;
-        Body =
-          cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
-        MD->setBody(Body);
-        CurrentBody = 0;
-        if (PropParentMap) {
-          delete PropParentMap;
-          PropParentMap = 0;
-        }
-        InsertBlockLiteralsWithinMethod(MD);
-        RewriteLineDirective(D);
-        CurMethodDef = 0;
-      }
-      break;
-    }
-    case Decl::ObjCImplementation: {
-      ObjCImplementationDecl *CI = cast<ObjCImplementationDecl>(D);
-      ClassImplementation.push_back(CI);
-      break;
-    }
-    case Decl::ObjCCategoryImpl: {
-      ObjCCategoryImplDecl *CI = cast<ObjCCategoryImplDecl>(D);
-      CategoryImplementation.push_back(CI);
-      break;
-    }
-    case Decl::Var: {
-      VarDecl *VD = cast<VarDecl>(D);
-      RewriteObjCQualifiedInterfaceTypes(VD);
-      if (isTopLevelBlockPointerType(VD->getType()))
-        RewriteBlockPointerDecl(VD);
-      else if (VD->getType()->isFunctionPointerType()) {
-        CheckFunctionPointerDecl(VD->getType(), VD);
-        if (VD->getInit()) {
-          if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(VD->getInit())) {
-            RewriteCastExpr(CE);
-          }
-        }
-      } else if (VD->getType()->isRecordType()) {
-        RecordDecl *RD = VD->getType()->getAs<RecordType>()->getDecl();
-        if (RD->isCompleteDefinition())
-          RewriteRecordBody(RD);
-      }
-      if (VD->getInit()) {
-        GlobalVarDecl = VD;
-        CurrentBody = VD->getInit();
-        RewriteFunctionBodyOrGlobalInitializer(VD->getInit());
-        CurrentBody = 0;
-        if (PropParentMap) {
-          delete PropParentMap;
-          PropParentMap = 0;
-        }
-        SynthesizeBlockLiterals(VD->getTypeSpecStartLoc(), VD->getName());
-        GlobalVarDecl = 0;
-          
-        // This is needed for blocks.
-        if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(VD->getInit())) {
-            RewriteCastExpr(CE);
-        }
-      }
-      break;
-    }
-    case Decl::TypeAlias:
-    case Decl::Typedef: {
-      if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
-        if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
-          RewriteBlockPointerDecl(TD);
-        else if (TD->getUnderlyingType()->isFunctionPointerType())
-          CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
-        else
-          RewriteObjCQualifiedInterfaceTypes(TD);
-      }
-      break;
-    }
-    case Decl::CXXRecord:
-    case Decl::Record: {
-      RecordDecl *RD = cast<RecordDecl>(D);
-      if (RD->isCompleteDefinition()) 
-        RewriteRecordBody(RD);
-      break;
-    }
-    default:
-      break;
-  }
-  // Nothing yet.
-}
-
-/// Write_ProtocolExprReferencedMetadata - This routine writer out the
-/// protocol reference symbols in the for of:
-/// struct _protocol_t *PROTOCOL_REF = &PROTOCOL_METADATA.
-static void Write_ProtocolExprReferencedMetadata(ASTContext *Context, 
-                                                 ObjCProtocolDecl *PDecl,
-                                                 std::string &Result) {
-  // Also output .objc_protorefs$B section and its meta-data.
-  if (Context->getLangOpts().MicrosoftExt)
-    Result += "static ";
-  Result += "struct _protocol_t *";
-  Result += "_OBJC_PROTOCOL_REFERENCE_$_";
-  Result += PDecl->getNameAsString();
-  Result += " = &";
-  Result += "_OBJC_PROTOCOL_"; Result += PDecl->getNameAsString();
-  Result += ";\n";
-}
-
-void RewriteModernObjC::HandleTranslationUnit(ASTContext &C) {
-  if (Diags.hasErrorOccurred())
-    return;
-
-  RewriteInclude();
-
-  for (unsigned i = 0, e = FunctionDefinitionsSeen.size(); i < e; i++) {
-    // translation of function bodies were postponed untill all class and
-    // their extensions and implementations are seen. This is because, we
-    // cannot build grouping structs for bitfields untill they are all seen.
-    FunctionDecl *FDecl = FunctionDefinitionsSeen[i];
-    HandleTopLevelSingleDecl(FDecl);
-  }
-
-  // Here's a great place to add any extra declarations that may be needed.
-  // Write out meta data for each @protocol(<expr>).
-  for (llvm::SmallPtrSet<ObjCProtocolDecl *,8>::iterator I = ProtocolExprDecls.begin(),
-       E = ProtocolExprDecls.end(); I != E; ++I) {
-    RewriteObjCProtocolMetaData(*I, Preamble);
-    Write_ProtocolExprReferencedMetadata(Context, (*I), Preamble);
-  }
-
-  InsertText(SM->getLocForStartOfFile(MainFileID), Preamble, false);
-  
-  if (ClassImplementation.size() || CategoryImplementation.size())
-    RewriteImplementations();
-  
-  for (unsigned i = 0, e = ObjCInterfacesSeen.size(); i < e; i++) {
-    ObjCInterfaceDecl *CDecl = ObjCInterfacesSeen[i];
-    // Write struct declaration for the class matching its ivar declarations.
-    // Note that for modern abi, this is postponed until the end of TU
-    // because class extensions and the implementation might declare their own
-    // private ivars.
-    RewriteInterfaceDecl(CDecl);
-  }
-  
-  // Get the buffer corresponding to MainFileID.  If we haven't changed it, then
-  // we are done.
-  if (const RewriteBuffer *RewriteBuf =
-      Rewrite.getRewriteBufferFor(MainFileID)) {
-    //printf("Changed:\n");
-    *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end());
-  } else {
-    llvm::errs() << "No changes\n";
-  }
-
-  if (ClassImplementation.size() || CategoryImplementation.size() ||
-      ProtocolExprDecls.size()) {
-    // Rewrite Objective-c meta data*
-    std::string ResultStr;
-    RewriteMetaDataIntoBuffer(ResultStr);
-    // Emit metadata.
-    *OutFile << ResultStr;
-  }
-  // Emit ImageInfo;
-  {
-    std::string ResultStr;
-    WriteImageInfo(ResultStr);
-    *OutFile << ResultStr;
-  }
-  OutFile->flush();
-}
-
-void RewriteModernObjC::Initialize(ASTContext &context) {
-  InitializeCommon(context);
-  
-  Preamble += "#ifndef __OBJC2__\n";
-  Preamble += "#define __OBJC2__\n";
-  Preamble += "#endif\n";
-
-  // declaring objc_selector outside the parameter list removes a silly
-  // scope related warning...
-  if (IsHeader)
-    Preamble = "#pragma once\n";
-  Preamble += "struct objc_selector; struct objc_class;\n";
-  Preamble += "struct __rw_objc_super { \n\tstruct objc_object *object; ";
-  Preamble += "\n\tstruct objc_object *superClass; ";
-  // Add a constructor for creating temporary objects.
-  Preamble += "\n\t__rw_objc_super(struct objc_object *o, struct objc_object *s) ";
-  Preamble += ": object(o), superClass(s) {} ";
-  Preamble += "\n};\n";
-  
-  if (LangOpts.MicrosoftExt) {
-    // Define all sections using syntax that makes sense.
-    // These are currently generated.
-    Preamble += "\n#pragma section(\".objc_classlist$B\", long, read, write)\n";
-    Preamble += "#pragma section(\".objc_catlist$B\", long, read, write)\n";
-    Preamble += "#pragma section(\".objc_imageinfo$B\", long, read, write)\n";
-    Preamble += "#pragma section(\".objc_nlclslist$B\", long, read, write)\n";
-    Preamble += "#pragma section(\".objc_nlcatlist$B\", long, read, write)\n";
-    // These are generated but not necessary for functionality.
-    Preamble += "#pragma section(\".cat_cls_meth$B\", long, read, write)\n";
-    Preamble += "#pragma section(\".inst_meth$B\", long, read, write)\n";
-    Preamble += "#pragma section(\".cls_meth$B\", long, read, write)\n";
-    Preamble += "#pragma section(\".objc_ivar$B\", long, read, write)\n";
-    
-    // These need be generated for performance. Currently they are not,
-    // using API calls instead.
-    Preamble += "#pragma section(\".objc_selrefs$B\", long, read, write)\n";
-    Preamble += "#pragma section(\".objc_classrefs$B\", long, read, write)\n";
-    Preamble += "#pragma section(\".objc_superrefs$B\", long, read, write)\n";
-    
-  }
-  Preamble += "#ifndef _REWRITER_typedef_Protocol\n";
-  Preamble += "typedef struct objc_object Protocol;\n";
-  Preamble += "#define _REWRITER_typedef_Protocol\n";
-  Preamble += "#endif\n";
-  if (LangOpts.MicrosoftExt) {
-    Preamble += "#define __OBJC_RW_DLLIMPORT extern \"C\" __declspec(dllimport)\n";
-    Preamble += "#define __OBJC_RW_STATICIMPORT extern \"C\"\n";
-  } 
-  else
-    Preamble += "#define __OBJC_RW_DLLIMPORT extern\n";
-  
-  Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSend(void);\n";
-  Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSendSuper(void);\n";
-  Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSend_stret(void);\n";
-  Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSendSuper_stret(void);\n";
-  Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSend_fpret(void);\n";
-
-  Preamble += "__OBJC_RW_DLLIMPORT struct objc_class *objc_getClass";
-  Preamble += "(const char *);\n";
-  Preamble += "__OBJC_RW_DLLIMPORT struct objc_class *class_getSuperclass";
-  Preamble += "(struct objc_class *);\n";
-  Preamble += "__OBJC_RW_DLLIMPORT struct objc_class *objc_getMetaClass";
-  Preamble += "(const char *);\n";
-  Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_throw( struct objc_object *);\n";
-  // @synchronized hooks.
-  Preamble += "__OBJC_RW_DLLIMPORT int objc_sync_enter( struct objc_object *);\n";
-  Preamble += "__OBJC_RW_DLLIMPORT int objc_sync_exit( struct objc_object *);\n";
-  Preamble += "__OBJC_RW_DLLIMPORT Protocol *objc_getProtocol(const char *);\n";
-  Preamble += "#ifdef _WIN64\n";
-  Preamble += "typedef unsigned long long  _WIN_NSUInteger;\n";
-  Preamble += "#else\n";
-  Preamble += "typedef unsigned int _WIN_NSUInteger;\n";
-  Preamble += "#endif\n";
-  Preamble += "#ifndef __FASTENUMERATIONSTATE\n";
-  Preamble += "struct __objcFastEnumerationState {\n\t";
-  Preamble += "unsigned long state;\n\t";
-  Preamble += "void **itemsPtr;\n\t";
-  Preamble += "unsigned long *mutationsPtr;\n\t";
-  Preamble += "unsigned long extra[5];\n};\n";
-  Preamble += "__OBJC_RW_DLLIMPORT void objc_enumerationMutation(struct objc_object *);\n";
-  Preamble += "#define __FASTENUMERATIONSTATE\n";
-  Preamble += "#endif\n";
-  Preamble += "#ifndef __NSCONSTANTSTRINGIMPL\n";
-  Preamble += "struct __NSConstantStringImpl {\n";
-  Preamble += "  int *isa;\n";
-  Preamble += "  int flags;\n";
-  Preamble += "  char *str;\n";
-  Preamble += "  long length;\n";
-  Preamble += "};\n";
-  Preamble += "#ifdef CF_EXPORT_CONSTANT_STRING\n";
-  Preamble += "extern \"C\" __declspec(dllexport) int __CFConstantStringClassReference[];\n";
-  Preamble += "#else\n";
-  Preamble += "__OBJC_RW_DLLIMPORT int __CFConstantStringClassReference[];\n";
-  Preamble += "#endif\n";
-  Preamble += "#define __NSCONSTANTSTRINGIMPL\n";
-  Preamble += "#endif\n";
-  // Blocks preamble.
-  Preamble += "#ifndef BLOCK_IMPL\n";
-  Preamble += "#define BLOCK_IMPL\n";
-  Preamble += "struct __block_impl {\n";
-  Preamble += "  void *isa;\n";
-  Preamble += "  int Flags;\n";
-  Preamble += "  int Reserved;\n";
-  Preamble += "  void *FuncPtr;\n";
-  Preamble += "};\n";
-  Preamble += "// Runtime copy/destroy helper functions (from Block_private.h)\n";
-  Preamble += "#ifdef __OBJC_EXPORT_BLOCKS\n";
-  Preamble += "extern \"C\" __declspec(dllexport) "
-  "void _Block_object_assign(void *, const void *, const int);\n";
-  Preamble += "extern \"C\" __declspec(dllexport) void _Block_object_dispose(const void *, const int);\n";
-  Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];\n";
-  Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteStackBlock[32];\n";
-  Preamble += "#else\n";
-  Preamble += "__OBJC_RW_DLLIMPORT void _Block_object_assign(void *, const void *, const int);\n";
-  Preamble += "__OBJC_RW_DLLIMPORT void _Block_object_dispose(const void *, const int);\n";
-  Preamble += "__OBJC_RW_DLLIMPORT void *_NSConcreteGlobalBlock[32];\n";
-  Preamble += "__OBJC_RW_DLLIMPORT void *_NSConcreteStackBlock[32];\n";
-  Preamble += "#endif\n";
-  Preamble += "#endif\n";
-  if (LangOpts.MicrosoftExt) {
-    Preamble += "#undef __OBJC_RW_DLLIMPORT\n";
-    Preamble += "#undef __OBJC_RW_STATICIMPORT\n";
-    Preamble += "#ifndef KEEP_ATTRIBUTES\n";  // We use this for clang tests.
-    Preamble += "#define __attribute__(X)\n";
-    Preamble += "#endif\n";
-    Preamble += "#ifndef __weak\n";
-    Preamble += "#define __weak\n";
-    Preamble += "#endif\n";
-    Preamble += "#ifndef __block\n";
-    Preamble += "#define __block\n";
-    Preamble += "#endif\n";
-  }
-  else {
-    Preamble += "#define __block\n";
-    Preamble += "#define __weak\n";
-  }
-  
-  // Declarations required for modern objective-c array and dictionary literals.
-  Preamble += "\n#include <stdarg.h>\n";
-  Preamble += "struct __NSContainer_literal {\n";
-  Preamble += "  void * *arr;\n";
-  Preamble += "  __NSContainer_literal (unsigned int count, ...) {\n";
-  Preamble += "\tva_list marker;\n";
-  Preamble += "\tva_start(marker, count);\n";
-  Preamble += "\tarr = new void *[count];\n";
-  Preamble += "\tfor (unsigned i = 0; i < count; i++)\n";
-  Preamble += "\t  arr[i] = va_arg(marker, void *);\n";
-  Preamble += "\tva_end( marker );\n";
-  Preamble += "  };\n";
-  Preamble += "  ~__NSContainer_literal() {\n";
-  Preamble += "\tdelete[] arr;\n";
-  Preamble += "  }\n";
-  Preamble += "};\n";
-  
-  // Declaration required for implementation of @autoreleasepool statement.
-  Preamble += "extern \"C\" __declspec(dllimport) void * objc_autoreleasePoolPush(void);\n";
-  Preamble += "extern \"C\" __declspec(dllimport) void objc_autoreleasePoolPop(void *);\n\n";
-  Preamble += "struct __AtAutoreleasePool {\n";
-  Preamble += "  __AtAutoreleasePool() {atautoreleasepoolobj = objc_autoreleasePoolPush();}\n";
-  Preamble += "  ~__AtAutoreleasePool() {objc_autoreleasePoolPop(atautoreleasepoolobj);}\n";
-  Preamble += "  void * atautoreleasepoolobj;\n";
-  Preamble += "};\n";
-  
-  // NOTE! Windows uses LLP64 for 64bit mode. So, cast pointer to long long
-  // as this avoids warning in any 64bit/32bit compilation model.
-  Preamble += "\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n";
-}
-
-/// RewriteIvarOffsetComputation - This rutine synthesizes computation of
-/// ivar offset.
-void RewriteModernObjC::RewriteIvarOffsetComputation(ObjCIvarDecl *ivar,
-                                                         std::string &Result) {
-  Result += "__OFFSETOFIVAR__(struct ";
-  Result += ivar->getContainingInterface()->getNameAsString();
-  if (LangOpts.MicrosoftExt)
-    Result += "_IMPL";
-  Result += ", ";
-  if (ivar->isBitField())
-    ObjCIvarBitfieldGroupDecl(ivar, Result);
-  else
-    Result += ivar->getNameAsString();
-  Result += ")";
-}
-
-/// WriteModernMetadataDeclarations - Writes out metadata declarations for modern ABI.
-/// struct _prop_t {
-///   const char *name;
-///   char *attributes;
-/// }
-
-/// struct _prop_list_t {
-///   uint32_t entsize;      // sizeof(struct _prop_t)
-///   uint32_t count_of_properties;
-///   struct _prop_t prop_list[count_of_properties];
-/// }
-
-/// struct _protocol_t;
-
-/// struct _protocol_list_t {
-///   long protocol_count;   // Note, this is 32/64 bit
-///   struct _protocol_t * protocol_list[protocol_count];
-/// }
-
-/// struct _objc_method {
-///   SEL _cmd;
-///   const char *method_type;
-///   char *_imp;
-/// }
-
-/// struct _method_list_t {
-///   uint32_t entsize;  // sizeof(struct _objc_method)
-///   uint32_t method_count;
-///   struct _objc_method method_list[method_count];
-/// }
-
-/// struct _protocol_t {
-///   id isa;  // NULL
-///   const char *protocol_name;
-///   const struct _protocol_list_t * protocol_list; // super protocols
-///   const struct method_list_t *instance_methods;
-///   const struct method_list_t *class_methods;
-///   const struct method_list_t *optionalInstanceMethods;
-///   const struct method_list_t *optionalClassMethods;
-///   const struct _prop_list_t * properties;
-///   const uint32_t size;  // sizeof(struct _protocol_t)
-///   const uint32_t flags;  // = 0
-///   const char ** extendedMethodTypes;
-/// }
-
-/// struct _ivar_t {
-///   unsigned long int *offset;  // pointer to ivar offset location
-///   const char *name;
-///   const char *type;
-///   uint32_t alignment;
-///   uint32_t size;
-/// }
-
-/// struct _ivar_list_t {
-///   uint32 entsize;  // sizeof(struct _ivar_t)
-///   uint32 count;
-///   struct _ivar_t list[count];
-/// }
-
-/// struct _class_ro_t {
-///   uint32_t flags;
-///   uint32_t instanceStart;
-///   uint32_t instanceSize;
-///   uint32_t reserved;  // only when building for 64bit targets
-///   const uint8_t *ivarLayout;
-///   const char *name;
-///   const struct _method_list_t *baseMethods;
-///   const struct _protocol_list_t *baseProtocols;
-///   const struct _ivar_list_t *ivars;
-///   const uint8_t *weakIvarLayout;
-///   const struct _prop_list_t *properties;
-/// }
-
-/// struct _class_t {
-///   struct _class_t *isa;
-///   struct _class_t *superclass;
-///   void *cache;
-///   IMP *vtable;
-///   struct _class_ro_t *ro;
-/// }
-
-/// struct _category_t {
-///   const char *name;
-///   struct _class_t *cls;
-///   const struct _method_list_t *instance_methods;
-///   const struct _method_list_t *class_methods;
-///   const struct _protocol_list_t *protocols;
-///   const struct _prop_list_t *properties;
-/// }
-
-/// MessageRefTy - LLVM for:
-/// struct _message_ref_t {
-///   IMP messenger;
-///   SEL name;
-/// };
-
-/// SuperMessageRefTy - LLVM for:
-/// struct _super_message_ref_t {
-///   SUPER_IMP messenger;
-///   SEL name;
-/// };
-
-static void WriteModernMetadataDeclarations(ASTContext *Context, std::string &Result) {
-  static bool meta_data_declared = false;
-  if (meta_data_declared)
-    return;
-  
-  Result += "\nstruct _prop_t {\n";
-  Result += "\tconst char *name;\n";
-  Result += "\tconst char *attributes;\n";
-  Result += "};\n";
-  
-  Result += "\nstruct _protocol_t;\n";
-  
-  Result += "\nstruct _objc_method {\n";
-  Result += "\tstruct objc_selector * _cmd;\n";
-  Result += "\tconst char *method_type;\n";
-  Result += "\tvoid  *_imp;\n";
-  Result += "};\n";
-  
-  Result += "\nstruct _protocol_t {\n";
-  Result += "\tvoid * isa;  // NULL\n";
-  Result += "\tconst char *protocol_name;\n";
-  Result += "\tconst struct _protocol_list_t * protocol_list; // super protocols\n";
-  Result += "\tconst struct method_list_t *instance_methods;\n";
-  Result += "\tconst struct method_list_t *class_methods;\n";
-  Result += "\tconst struct method_list_t *optionalInstanceMethods;\n";
-  Result += "\tconst struct method_list_t *optionalClassMethods;\n";
-  Result += "\tconst struct _prop_list_t * properties;\n";
-  Result += "\tconst unsigned int size;  // sizeof(struct _protocol_t)\n";
-  Result += "\tconst unsigned int flags;  // = 0\n";
-  Result += "\tconst char ** extendedMethodTypes;\n";
-  Result += "};\n";
-  
-  Result += "\nstruct _ivar_t {\n";
-  Result += "\tunsigned long int *offset;  // pointer to ivar offset location\n";
-  Result += "\tconst char *name;\n";
-  Result += "\tconst char *type;\n";
-  Result += "\tunsigned int alignment;\n";
-  Result += "\tunsigned int  size;\n";
-  Result += "};\n";
-  
-  Result += "\nstruct _class_ro_t {\n";
-  Result += "\tunsigned int flags;\n";
-  Result += "\tunsigned int instanceStart;\n";
-  Result += "\tunsigned int instanceSize;\n";
-  const llvm::Triple &Triple(Context->getTargetInfo().getTriple());
-  if (Triple.getArch() == llvm::Triple::x86_64)
-    Result += "\tunsigned int reserved;\n";
-  Result += "\tconst unsigned char *ivarLayout;\n";
-  Result += "\tconst char *name;\n";
-  Result += "\tconst struct _method_list_t *baseMethods;\n";
-  Result += "\tconst struct _objc_protocol_list *baseProtocols;\n";
-  Result += "\tconst struct _ivar_list_t *ivars;\n";
-  Result += "\tconst unsigned char *weakIvarLayout;\n";
-  Result += "\tconst struct _prop_list_t *properties;\n";
-  Result += "};\n";
-  
-  Result += "\nstruct _class_t {\n";
-  Result += "\tstruct _class_t *isa;\n";
-  Result += "\tstruct _class_t *superclass;\n";
-  Result += "\tvoid *cache;\n";
-  Result += "\tvoid *vtable;\n";
-  Result += "\tstruct _class_ro_t *ro;\n";
-  Result += "};\n";
-  
-  Result += "\nstruct _category_t {\n";
-  Result += "\tconst char *name;\n";
-  Result += "\tstruct _class_t *cls;\n";
-  Result += "\tconst struct _method_list_t *instance_methods;\n";
-  Result += "\tconst struct _method_list_t *class_methods;\n";
-  Result += "\tconst struct _protocol_list_t *protocols;\n";
-  Result += "\tconst struct _prop_list_t *properties;\n";
-  Result += "};\n";
-  
-  Result += "extern \"C\" __declspec(dllimport) struct objc_cache _objc_empty_cache;\n";
-  Result += "#pragma warning(disable:4273)\n";
-  meta_data_declared = true;
-}
-
-static void Write_protocol_list_t_TypeDecl(std::string &Result,
-                                           long super_protocol_count) {
-  Result += "struct /*_protocol_list_t*/"; Result += " {\n";
-  Result += "\tlong protocol_count;  // Note, this is 32/64 bit\n";
-  Result += "\tstruct _protocol_t *super_protocols[";
-  Result += utostr(super_protocol_count); Result += "];\n";
-  Result += "}";
-}
-
-static void Write_method_list_t_TypeDecl(std::string &Result,
-                                         unsigned int method_count) {
-  Result += "struct /*_method_list_t*/"; Result += " {\n";
-  Result += "\tunsigned int entsize;  // sizeof(struct _objc_method)\n";
-  Result += "\tunsigned int method_count;\n";
-  Result += "\tstruct _objc_method method_list[";
-  Result += utostr(method_count); Result += "];\n";
-  Result += "}";
-}
-
-static void Write__prop_list_t_TypeDecl(std::string &Result,
-                                        unsigned int property_count) {
-  Result += "struct /*_prop_list_t*/"; Result += " {\n";
-  Result += "\tunsigned int entsize;  // sizeof(struct _prop_t)\n";
-  Result += "\tunsigned int count_of_properties;\n";
-  Result += "\tstruct _prop_t prop_list[";
-  Result += utostr(property_count); Result += "];\n";
-  Result += "}";
-}
-
-static void Write__ivar_list_t_TypeDecl(std::string &Result,
-                                        unsigned int ivar_count) {
-  Result += "struct /*_ivar_list_t*/"; Result += " {\n";
-  Result += "\tunsigned int entsize;  // sizeof(struct _prop_t)\n";
-  Result += "\tunsigned int count;\n";
-  Result += "\tstruct _ivar_t ivar_list[";
-  Result += utostr(ivar_count); Result += "];\n";
-  Result += "}";
-}
-
-static void Write_protocol_list_initializer(ASTContext *Context, std::string &Result,
-                                            ArrayRef<ObjCProtocolDecl *> SuperProtocols,
-                                            StringRef VarName,
-                                            StringRef ProtocolName) {
-  if (SuperProtocols.size() > 0) {
-    Result += "\nstatic ";
-    Write_protocol_list_t_TypeDecl(Result, SuperProtocols.size());
-    Result += " "; Result += VarName;
-    Result += ProtocolName; 
-    Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
-    Result += "\t"; Result += utostr(SuperProtocols.size()); Result += ",\n";
-    for (unsigned i = 0, e = SuperProtocols.size(); i < e; i++) {
-      ObjCProtocolDecl *SuperPD = SuperProtocols[i];
-      Result += "\t&"; Result += "_OBJC_PROTOCOL_"; 
-      Result += SuperPD->getNameAsString();
-      if (i == e-1)
-        Result += "\n};\n";
-      else
-        Result += ",\n";
-    }
-  }
-}
-
-static void Write_method_list_t_initializer(RewriteModernObjC &RewriteObj,
-                                            ASTContext *Context, std::string &Result,
-                                            ArrayRef<ObjCMethodDecl *> Methods,
-                                            StringRef VarName,
-                                            StringRef TopLevelDeclName,
-                                            bool MethodImpl) {
-  if (Methods.size() > 0) {
-    Result += "\nstatic ";
-    Write_method_list_t_TypeDecl(Result, Methods.size());
-    Result += " "; Result += VarName;
-    Result += TopLevelDeclName; 
-    Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
-    Result += "\t"; Result += "sizeof(_objc_method)"; Result += ",\n";
-    Result += "\t"; Result += utostr(Methods.size()); Result += ",\n";
-    for (unsigned i = 0, e = Methods.size(); i < e; i++) {
-      ObjCMethodDecl *MD = Methods[i];
-      if (i == 0)
-        Result += "\t{{(struct objc_selector *)\"";
-      else
-        Result += "\t{(struct objc_selector *)\"";
-      Result += (MD)->getSelector().getAsString(); Result += "\"";
-      Result += ", ";
-      std::string MethodTypeString;
-      Context->getObjCEncodingForMethodDecl(MD, MethodTypeString);
-      Result += "\""; Result += MethodTypeString; Result += "\"";
-      Result += ", ";
-      if (!MethodImpl)
-        Result += "0";
-      else {
-        Result += "(void *)";
-        Result += RewriteObj.MethodInternalNames[MD];
-      }
-      if (i  == e-1)
-        Result += "}}\n";
-      else
-        Result += "},\n";
-    }
-    Result += "};\n";
-  }
-}
-
-static void Write_prop_list_t_initializer(RewriteModernObjC &RewriteObj,
-                                           ASTContext *Context, std::string &Result,
-                                           ArrayRef<ObjCPropertyDecl *> Properties,
-                                           const Decl *Container,
-                                           StringRef VarName,
-                                           StringRef ProtocolName) {
-  if (Properties.size() > 0) {
-    Result += "\nstatic ";
-    Write__prop_list_t_TypeDecl(Result, Properties.size());
-    Result += " "; Result += VarName;
-    Result += ProtocolName; 
-    Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
-    Result += "\t"; Result += "sizeof(_prop_t)"; Result += ",\n";
-    Result += "\t"; Result += utostr(Properties.size()); Result += ",\n";
-    for (unsigned i = 0, e = Properties.size(); i < e; i++) {
-      ObjCPropertyDecl *PropDecl = Properties[i];
-      if (i == 0)
-        Result += "\t{{\"";
-      else
-        Result += "\t{\"";
-      Result += PropDecl->getName(); Result += "\",";
-      std::string PropertyTypeString, QuotePropertyTypeString;
-      Context->getObjCEncodingForPropertyDecl(PropDecl, Container, PropertyTypeString);
-      RewriteObj.QuoteDoublequotes(PropertyTypeString, QuotePropertyTypeString);
-      Result += "\""; Result += QuotePropertyTypeString; Result += "\"";
-      if (i  == e-1)
-        Result += "}}\n";
-      else
-        Result += "},\n";
-    }
-    Result += "};\n";
-  }
-}
-
-// Metadata flags
-enum MetaDataDlags {
-  CLS = 0x0,
-  CLS_META = 0x1,
-  CLS_ROOT = 0x2,
-  OBJC2_CLS_HIDDEN = 0x10,
-  CLS_EXCEPTION = 0x20,
-  
-  /// (Obsolete) ARC-specific: this class has a .release_ivars method
-  CLS_HAS_IVAR_RELEASER = 0x40,
-  /// class was compiled with -fobjc-arr
-  CLS_COMPILED_BY_ARC = 0x80  // (1<<7)
-};
-
-static void Write__class_ro_t_initializer(ASTContext *Context, std::string &Result, 
-                                          unsigned int flags, 
-                                          const std::string &InstanceStart, 
-                                          const std::string &InstanceSize,
-                                          ArrayRef<ObjCMethodDecl *>baseMethods,
-                                          ArrayRef<ObjCProtocolDecl *>baseProtocols,
-                                          ArrayRef<ObjCIvarDecl *>ivars,
-                                          ArrayRef<ObjCPropertyDecl *>Properties,
-                                          StringRef VarName,
-                                          StringRef ClassName) {
-  Result += "\nstatic struct _class_ro_t ";
-  Result += VarName; Result += ClassName;
-  Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
-  Result += "\t"; 
-  Result += llvm::utostr(flags); Result += ", "; 
-  Result += InstanceStart; Result += ", ";
-  Result += InstanceSize; Result += ", \n";
-  Result += "\t";
-  const llvm::Triple &Triple(Context->getTargetInfo().getTriple());
-  if (Triple.getArch() == llvm::Triple::x86_64)
-    // uint32_t const reserved; // only when building for 64bit targets
-    Result += "(unsigned int)0, \n\t";
-  // const uint8_t * const ivarLayout;
-  Result += "0, \n\t";
-  Result += "\""; Result += ClassName; Result += "\",\n\t";
-  bool metaclass = ((flags & CLS_META) != 0);
-  if (baseMethods.size() > 0) {
-    Result += "(const struct _method_list_t *)&";
-    if (metaclass)
-      Result += "_OBJC_$_CLASS_METHODS_";
-    else
-      Result += "_OBJC_$_INSTANCE_METHODS_";
-    Result += ClassName;
-    Result += ",\n\t";
-  }
-  else
-    Result += "0, \n\t";
-
-  if (!metaclass && baseProtocols.size() > 0) {
-    Result += "(const struct _objc_protocol_list *)&";
-    Result += "_OBJC_CLASS_PROTOCOLS_$_"; Result += ClassName;
-    Result += ",\n\t";
-  }
-  else
-    Result += "0, \n\t";
-
-  if (!metaclass && ivars.size() > 0) {
-    Result += "(const struct _ivar_list_t *)&";
-    Result += "_OBJC_$_INSTANCE_VARIABLES_"; Result += ClassName;
-    Result += ",\n\t";
-  }
-  else
-    Result += "0, \n\t";
-
-  // weakIvarLayout
-  Result += "0, \n\t";
-  if (!metaclass && Properties.size() > 0) {
-    Result += "(const struct _prop_list_t *)&";
-    Result += "_OBJC_$_PROP_LIST_"; Result += ClassName;
-    Result += ",\n";
-  }
-  else
-    Result += "0, \n";
-
-  Result += "};\n";
-}
-
-static void Write_class_t(ASTContext *Context, std::string &Result,
-                          StringRef VarName,
-                          const ObjCInterfaceDecl *CDecl, bool metaclass) {
-  bool rootClass = (!CDecl->getSuperClass());
-  const ObjCInterfaceDecl *RootClass = CDecl;
-  
-  if (!rootClass) {
-    // Find the Root class
-    RootClass = CDecl->getSuperClass();
-    while (RootClass->getSuperClass()) {
-      RootClass = RootClass->getSuperClass();
-    }
-  }
-
-  if (metaclass && rootClass) {
-    // Need to handle a case of use of forward declaration.
-    Result += "\n";
-    Result += "extern \"C\" ";
-    if (CDecl->getImplementation())
-      Result += "__declspec(dllexport) ";
-    else
-      Result += "__declspec(dllimport) ";
-    
-    Result += "struct _class_t OBJC_CLASS_$_";
-    Result += CDecl->getNameAsString();
-    Result += ";\n";
-  }
-  // Also, for possibility of 'super' metadata class not having been defined yet.
-  if (!rootClass) {
-    ObjCInterfaceDecl *SuperClass = CDecl->getSuperClass();
-    Result += "\n";
-    Result += "extern \"C\" ";
-    if (SuperClass->getImplementation())
-      Result += "__declspec(dllexport) ";
-    else
-      Result += "__declspec(dllimport) ";
-
-    Result += "struct _class_t "; 
-    Result += VarName;
-    Result += SuperClass->getNameAsString();
-    Result += ";\n";
-    
-    if (metaclass && RootClass != SuperClass) {
-      Result += "extern \"C\" ";
-      if (RootClass->getImplementation())
-        Result += "__declspec(dllexport) ";
-      else
-        Result += "__declspec(dllimport) ";
-
-      Result += "struct _class_t "; 
-      Result += VarName;
-      Result += RootClass->getNameAsString();
-      Result += ";\n";
-    }
-  }
-  
-  Result += "\nextern \"C\" __declspec(dllexport) struct _class_t "; 
-  Result += VarName; Result += CDecl->getNameAsString();
-  Result += " __attribute__ ((used, section (\"__DATA,__objc_data\"))) = {\n";
-  Result += "\t";
-  if (metaclass) {
-    if (!rootClass) {
-      Result += "0, // &"; Result += VarName;
-      Result += RootClass->getNameAsString();
-      Result += ",\n\t";
-      Result += "0, // &"; Result += VarName;
-      Result += CDecl->getSuperClass()->getNameAsString();
-      Result += ",\n\t";
-    }
-    else {
-      Result += "0, // &"; Result += VarName; 
-      Result += CDecl->getNameAsString();
-      Result += ",\n\t";
-      Result += "0, // &OBJC_CLASS_$_"; Result += CDecl->getNameAsString();
-      Result += ",\n\t";
-    }
-  }
-  else {
-    Result += "0, // &OBJC_METACLASS_$_"; 
-    Result += CDecl->getNameAsString();
-    Result += ",\n\t";
-    if (!rootClass) {
-      Result += "0, // &"; Result += VarName;
-      Result += CDecl->getSuperClass()->getNameAsString();
-      Result += ",\n\t";
-    }
-    else 
-      Result += "0,\n\t";
-  }
-  Result += "0, // (void *)&_objc_empty_cache,\n\t";
-  Result += "0, // unused, was (void *)&_objc_empty_vtable,\n\t";
-  if (metaclass)
-    Result += "&_OBJC_METACLASS_RO_$_";
-  else
-    Result += "&_OBJC_CLASS_RO_$_";
-  Result += CDecl->getNameAsString();
-  Result += ",\n};\n";
-  
-  // Add static function to initialize some of the meta-data fields.
-  // avoid doing it twice.
-  if (metaclass)
-    return;
-  
-  const ObjCInterfaceDecl *SuperClass = 
-    rootClass ? CDecl : CDecl->getSuperClass();
-  
-  Result += "static void OBJC_CLASS_SETUP_$_";
-  Result += CDecl->getNameAsString();
-  Result += "(void ) {\n";
-  Result += "\tOBJC_METACLASS_$_"; Result += CDecl->getNameAsString();
-  Result += ".isa = "; Result += "&OBJC_METACLASS_$_";
-  Result += RootClass->getNameAsString(); Result += ";\n";
-  
-  Result += "\tOBJC_METACLASS_$_"; Result += CDecl->getNameAsString();
-  Result += ".superclass = ";
-  if (rootClass)
-    Result += "&OBJC_CLASS_$_";
-  else
-     Result += "&OBJC_METACLASS_$_";
-
-  Result += SuperClass->getNameAsString(); Result += ";\n";
-  
-  Result += "\tOBJC_METACLASS_$_"; Result += CDecl->getNameAsString();
-  Result += ".cache = "; Result += "&_objc_empty_cache"; Result += ";\n";
-  
-  Result += "\tOBJC_CLASS_$_"; Result += CDecl->getNameAsString();
-  Result += ".isa = "; Result += "&OBJC_METACLASS_$_";
-  Result += CDecl->getNameAsString(); Result += ";\n";
-  
-  if (!rootClass) {
-    Result += "\tOBJC_CLASS_$_"; Result += CDecl->getNameAsString();
-    Result += ".superclass = "; Result += "&OBJC_CLASS_$_";
-    Result += SuperClass->getNameAsString(); Result += ";\n";
-  }
-  
-  Result += "\tOBJC_CLASS_$_"; Result += CDecl->getNameAsString();
-  Result += ".cache = "; Result += "&_objc_empty_cache"; Result += ";\n";
-  Result += "}\n";
-}
-
-static void Write_category_t(RewriteModernObjC &RewriteObj, ASTContext *Context, 
-                             std::string &Result,
-                             ObjCCategoryDecl *CatDecl,
-                             ObjCInterfaceDecl *ClassDecl,
-                             ArrayRef<ObjCMethodDecl *> InstanceMethods,
-                             ArrayRef<ObjCMethodDecl *> ClassMethods,
-                             ArrayRef<ObjCProtocolDecl *> RefedProtocols,
-                             ArrayRef<ObjCPropertyDecl *> ClassProperties) {
-  StringRef CatName = CatDecl->getName();
-  StringRef ClassName = ClassDecl->getName();
-  // must declare an extern class object in case this class is not implemented 
-  // in this TU.
-  Result += "\n";
-  Result += "extern \"C\" ";
-  if (ClassDecl->getImplementation())
-    Result += "__declspec(dllexport) ";
-  else
-    Result += "__declspec(dllimport) ";
-  
-  Result += "struct _class_t ";
-  Result += "OBJC_CLASS_$_"; Result += ClassName;
-  Result += ";\n";
-  
-  Result += "\nstatic struct _category_t ";
-  Result += "_OBJC_$_CATEGORY_";
-  Result += ClassName; Result += "_$_"; Result += CatName;
-  Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
-  Result += "{\n";
-  Result += "\t\""; Result += ClassName; Result += "\",\n";
-  Result += "\t0, // &"; Result += "OBJC_CLASS_$_"; Result += ClassName;
-  Result += ",\n";
-  if (InstanceMethods.size() > 0) {
-    Result += "\t(const struct _method_list_t *)&";  
-    Result += "_OBJC_$_CATEGORY_INSTANCE_METHODS_";
-    Result += ClassName; Result += "_$_"; Result += CatName;
-    Result += ",\n";
-  }
-  else
-    Result += "\t0,\n";
-  
-  if (ClassMethods.size() > 0) {
-    Result += "\t(const struct _method_list_t *)&";  
-    Result += "_OBJC_$_CATEGORY_CLASS_METHODS_";
-    Result += ClassName; Result += "_$_"; Result += CatName;
-    Result += ",\n";
-  }
-  else
-    Result += "\t0,\n";
-  
-  if (RefedProtocols.size() > 0) {
-    Result += "\t(const struct _protocol_list_t *)&";  
-    Result += "_OBJC_CATEGORY_PROTOCOLS_$_";
-    Result += ClassName; Result += "_$_"; Result += CatName;
-    Result += ",\n";
-  }
-  else
-    Result += "\t0,\n";
-  
-  if (ClassProperties.size() > 0) {
-    Result += "\t(const struct _prop_list_t *)&";  Result += "_OBJC_$_PROP_LIST_";
-    Result += ClassName; Result += "_$_"; Result += CatName;
-    Result += ",\n";
-  }
-  else
-    Result += "\t0,\n";
-  
-  Result += "};\n";
-  
-  // Add static function to initialize the class pointer in the category structure.
-  Result += "static void OBJC_CATEGORY_SETUP_$_";
-  Result += ClassDecl->getNameAsString();
-  Result += "_$_";
-  Result += CatName;
-  Result += "(void ) {\n";
-  Result += "\t_OBJC_$_CATEGORY_"; 
-  Result += ClassDecl->getNameAsString();
-  Result += "_$_";
-  Result += CatName;
-  Result += ".cls = "; Result += "&OBJC_CLASS_$_"; Result += ClassName;
-  Result += ";\n}\n";
-}
-
-static void Write__extendedMethodTypes_initializer(RewriteModernObjC &RewriteObj,
-                                           ASTContext *Context, std::string &Result,
-                                           ArrayRef<ObjCMethodDecl *> Methods,
-                                           StringRef VarName,
-                                           StringRef ProtocolName) {
-  if (Methods.size() == 0)
-    return;
-  
-  Result += "\nstatic const char *";
-  Result += VarName; Result += ProtocolName;
-  Result += " [] __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
-  Result += "{\n";
-  for (unsigned i = 0, e = Methods.size(); i < e; i++) {
-    ObjCMethodDecl *MD = Methods[i];
-    std::string MethodTypeString, QuoteMethodTypeString;
-    Context->getObjCEncodingForMethodDecl(MD, MethodTypeString, true);
-    RewriteObj.QuoteDoublequotes(MethodTypeString, QuoteMethodTypeString);
-    Result += "\t\""; Result += QuoteMethodTypeString; Result += "\"";
-    if (i == e-1)
-      Result += "\n};\n";
-    else {
-      Result += ",\n";
-    }
-  }
-}
-
-static void Write_IvarOffsetVar(RewriteModernObjC &RewriteObj,
-                                ASTContext *Context,
-                                std::string &Result, 
-                                ArrayRef<ObjCIvarDecl *> Ivars, 
-                                ObjCInterfaceDecl *CDecl) {
-  // FIXME. visibilty of offset symbols may have to be set; for Darwin
-  // this is what happens:
-  /**
-   if (Ivar->getAccessControl() == ObjCIvarDecl::Private ||
-       Ivar->getAccessControl() == ObjCIvarDecl::Package ||
-       Class->getVisibility() == HiddenVisibility)
-     Visibility shoud be: HiddenVisibility;
-   else
-     Visibility shoud be: DefaultVisibility;
-  */
-  
-  Result += "\n";
-  for (unsigned i =0, e = Ivars.size(); i < e; i++) {
-    ObjCIvarDecl *IvarDecl = Ivars[i];
-    if (Context->getLangOpts().MicrosoftExt)
-      Result += "__declspec(allocate(\".objc_ivar$B\")) ";
-    
-    if (!Context->getLangOpts().MicrosoftExt ||
-        IvarDecl->getAccessControl() == ObjCIvarDecl::Private ||
-        IvarDecl->getAccessControl() == ObjCIvarDecl::Package)
-      Result += "extern \"C\" unsigned long int "; 
-    else
-      Result += "extern \"C\" __declspec(dllexport) unsigned long int ";
-    if (Ivars[i]->isBitField())
-      RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
-    else
-      WriteInternalIvarName(CDecl, IvarDecl, Result);
-    Result += " __attribute__ ((used, section (\"__DATA,__objc_ivar\")))";
-    Result += " = ";
-    RewriteObj.RewriteIvarOffsetComputation(IvarDecl, Result);
-    Result += ";\n";
-    if (Ivars[i]->isBitField()) {
-      // skip over rest of the ivar bitfields.
-      SKIP_BITFIELDS(i , e, Ivars);
-    }
-  }
-}
-
-static void Write__ivar_list_t_initializer(RewriteModernObjC &RewriteObj,
-                                           ASTContext *Context, std::string &Result,
-                                           ArrayRef<ObjCIvarDecl *> OriginalIvars,
-                                           StringRef VarName,
-                                           ObjCInterfaceDecl *CDecl) {
-  if (OriginalIvars.size() > 0) {
-    Write_IvarOffsetVar(RewriteObj, Context, Result, OriginalIvars, CDecl);
-    SmallVector<ObjCIvarDecl *, 8> Ivars;
-    // strip off all but the first ivar bitfield from each group of ivars.
-    // Such ivars in the ivar list table will be replaced by their grouping struct
-    // 'ivar'.
-    for (unsigned i = 0, e = OriginalIvars.size(); i < e; i++) {
-      if (OriginalIvars[i]->isBitField()) {
-        Ivars.push_back(OriginalIvars[i]);
-        // skip over rest of the ivar bitfields.
-        SKIP_BITFIELDS(i , e, OriginalIvars);
-      }
-      else
-        Ivars.push_back(OriginalIvars[i]);
-    }
-    
-    Result += "\nstatic ";
-    Write__ivar_list_t_TypeDecl(Result, Ivars.size());
-    Result += " "; Result += VarName;
-    Result += CDecl->getNameAsString();
-    Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
-    Result += "\t"; Result += "sizeof(_ivar_t)"; Result += ",\n";
-    Result += "\t"; Result += utostr(Ivars.size()); Result += ",\n";
-    for (unsigned i =0, e = Ivars.size(); i < e; i++) {
-      ObjCIvarDecl *IvarDecl = Ivars[i];
-      if (i == 0)
-        Result += "\t{{";
-      else
-        Result += "\t {";
-      Result += "(unsigned long int *)&";
-      if (Ivars[i]->isBitField())
-        RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
-      else
-        WriteInternalIvarName(CDecl, IvarDecl, Result);
-      Result += ", ";
-      
-      Result += "\"";
-      if (Ivars[i]->isBitField())
-        RewriteObj.ObjCIvarBitfieldGroupDecl(Ivars[i], Result);
-      else
-        Result += IvarDecl->getName();
-      Result += "\", ";
-      
-      QualType IVQT = IvarDecl->getType();
-      if (IvarDecl->isBitField())
-        IVQT = RewriteObj.GetGroupRecordTypeForObjCIvarBitfield(IvarDecl);
-      
-      std::string IvarTypeString, QuoteIvarTypeString;
-      Context->getObjCEncodingForType(IVQT, IvarTypeString,
-                                      IvarDecl);
-      RewriteObj.QuoteDoublequotes(IvarTypeString, QuoteIvarTypeString);
-      Result += "\""; Result += QuoteIvarTypeString; Result += "\", ";
-      
-      // FIXME. this alignment represents the host alignment and need be changed to
-      // represent the target alignment.
-      unsigned Align = Context->getTypeAlign(IVQT)/8;
-      Align = llvm::Log2_32(Align);
-      Result += llvm::utostr(Align); Result += ", ";
-      CharUnits Size = Context->getTypeSizeInChars(IVQT);
-      Result += llvm::utostr(Size.getQuantity());
-      if (i  == e-1)
-        Result += "}}\n";
-      else
-        Result += "},\n";
-    }
-    Result += "};\n";
-  }
-}
-
-/// RewriteObjCProtocolMetaData - Rewrite protocols meta-data.
-void RewriteModernObjC::RewriteObjCProtocolMetaData(ObjCProtocolDecl *PDecl, 
-                                                    std::string &Result) {
-  
-  // Do not synthesize the protocol more than once.
-  if (ObjCSynthesizedProtocols.count(PDecl->getCanonicalDecl()))
-    return;
-  WriteModernMetadataDeclarations(Context, Result);
-  
-  if (ObjCProtocolDecl *Def = PDecl->getDefinition())
-    PDecl = Def;
-  // Must write out all protocol definitions in current qualifier list,
-  // and in their nested qualifiers before writing out current definition.
-  for (ObjCProtocolDecl::protocol_iterator I = PDecl->protocol_begin(),
-       E = PDecl->protocol_end(); I != E; ++I)
-    RewriteObjCProtocolMetaData(*I, Result);
-  
-  // Construct method lists.
-  std::vector<ObjCMethodDecl *> InstanceMethods, ClassMethods;
-  std::vector<ObjCMethodDecl *> OptInstanceMethods, OptClassMethods;
-  for (ObjCProtocolDecl::instmeth_iterator
-       I = PDecl->instmeth_begin(), E = PDecl->instmeth_end();
-       I != E; ++I) {
-    ObjCMethodDecl *MD = *I;
-    if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
-      OptInstanceMethods.push_back(MD);
-    } else {
-      InstanceMethods.push_back(MD);
-    }
-  }
-  
-  for (ObjCProtocolDecl::classmeth_iterator
-       I = PDecl->classmeth_begin(), E = PDecl->classmeth_end();
-       I != E; ++I) {
-    ObjCMethodDecl *MD = *I;
-    if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
-      OptClassMethods.push_back(MD);
-    } else {
-      ClassMethods.push_back(MD);
-    }
-  }
-  std::vector<ObjCMethodDecl *> AllMethods;
-  for (unsigned i = 0, e = InstanceMethods.size(); i < e; i++)
-    AllMethods.push_back(InstanceMethods[i]);
-  for (unsigned i = 0, e = ClassMethods.size(); i < e; i++)
-    AllMethods.push_back(ClassMethods[i]);
-  for (unsigned i = 0, e = OptInstanceMethods.size(); i < e; i++)
-    AllMethods.push_back(OptInstanceMethods[i]);
-  for (unsigned i = 0, e = OptClassMethods.size(); i < e; i++)
-    AllMethods.push_back(OptClassMethods[i]);
-
-  Write__extendedMethodTypes_initializer(*this, Context, Result,
-                                         AllMethods,
-                                         "_OBJC_PROTOCOL_METHOD_TYPES_",
-                                         PDecl->getNameAsString());
-  // Protocol's super protocol list
-  std::vector<ObjCProtocolDecl *> SuperProtocols;
-  for (ObjCProtocolDecl::protocol_iterator I = PDecl->protocol_begin(),
-       E = PDecl->protocol_end(); I != E; ++I)
-    SuperProtocols.push_back(*I);
-  
-  Write_protocol_list_initializer(Context, Result, SuperProtocols,
-                                  "_OBJC_PROTOCOL_REFS_",
-                                  PDecl->getNameAsString());
-  
-  Write_method_list_t_initializer(*this, Context, Result, InstanceMethods, 
-                                  "_OBJC_PROTOCOL_INSTANCE_METHODS_",
-                                  PDecl->getNameAsString(), false);
-  
-  Write_method_list_t_initializer(*this, Context, Result, ClassMethods, 
-                                  "_OBJC_PROTOCOL_CLASS_METHODS_",
-                                  PDecl->getNameAsString(), false);
-
-  Write_method_list_t_initializer(*this, Context, Result, OptInstanceMethods, 
-                                  "_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_",
-                                  PDecl->getNameAsString(), false);
-  
-  Write_method_list_t_initializer(*this, Context, Result, OptClassMethods, 
-                                  "_OBJC_PROTOCOL_OPT_CLASS_METHODS_",
-                                  PDecl->getNameAsString(), false);
-  
-  // Protocol's property metadata.
-  std::vector<ObjCPropertyDecl *> ProtocolProperties;
-  for (ObjCContainerDecl::prop_iterator I = PDecl->prop_begin(),
-       E = PDecl->prop_end(); I != E; ++I)
-    ProtocolProperties.push_back(*I);
-  
-  Write_prop_list_t_initializer(*this, Context, Result, ProtocolProperties,
-                                 /* Container */0,
-                                 "_OBJC_PROTOCOL_PROPERTIES_",
-                                 PDecl->getNameAsString());
-  
-  // Writer out root metadata for current protocol: struct _protocol_t
-  Result += "\n";
-  if (LangOpts.MicrosoftExt)
-    Result += "static ";
-  Result += "struct _protocol_t _OBJC_PROTOCOL_";
-  Result += PDecl->getNameAsString();
-  Result += " __attribute__ ((used, section (\"__DATA,__datacoal_nt,coalesced\"))) = {\n";
-  Result += "\t0,\n"; // id is; is null
-  Result += "\t\""; Result += PDecl->getNameAsString(); Result += "\",\n";
-  if (SuperProtocols.size() > 0) {
-    Result += "\t(const struct _protocol_list_t *)&"; Result += "_OBJC_PROTOCOL_REFS_";
-    Result += PDecl->getNameAsString(); Result += ",\n";
-  }
-  else
-    Result += "\t0,\n";
-  if (InstanceMethods.size() > 0) {
-    Result += "\t(const struct method_list_t *)&_OBJC_PROTOCOL_INSTANCE_METHODS_"; 
-    Result += PDecl->getNameAsString(); Result += ",\n";
-  }
-  else
-    Result += "\t0,\n";
-
-  if (ClassMethods.size() > 0) {
-    Result += "\t(const struct method_list_t *)&_OBJC_PROTOCOL_CLASS_METHODS_"; 
-    Result += PDecl->getNameAsString(); Result += ",\n";
-  }
-  else
-    Result += "\t0,\n";
-  
-  if (OptInstanceMethods.size() > 0) {
-    Result += "\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_"; 
-    Result += PDecl->getNameAsString(); Result += ",\n";
-  }
-  else
-    Result += "\t0,\n";
-  
-  if (OptClassMethods.size() > 0) {
-    Result += "\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_CLASS_METHODS_"; 
-    Result += PDecl->getNameAsString(); Result += ",\n";
-  }
-  else
-    Result += "\t0,\n";
-  
-  if (ProtocolProperties.size() > 0) {
-    Result += "\t(const struct _prop_list_t *)&_OBJC_PROTOCOL_PROPERTIES_"; 
-    Result += PDecl->getNameAsString(); Result += ",\n";
-  }
-  else
-    Result += "\t0,\n";
-  
-  Result += "\t"; Result += "sizeof(_protocol_t)"; Result += ",\n";
-  Result += "\t0,\n";
-  
-  if (AllMethods.size() > 0) {
-    Result += "\t(const char **)&"; Result += "_OBJC_PROTOCOL_METHOD_TYPES_";
-    Result += PDecl->getNameAsString();
-    Result += "\n};\n";
-  }
-  else
-    Result += "\t0\n};\n";
-  
-  if (LangOpts.MicrosoftExt)
-    Result += "static ";
-  Result += "struct _protocol_t *";
-  Result += "_OBJC_LABEL_PROTOCOL_$_"; Result += PDecl->getNameAsString();
-  Result += " = &_OBJC_PROTOCOL_"; Result += PDecl->getNameAsString();
-  Result += ";\n";
-    
-  // Mark this protocol as having been generated.
-  if (!ObjCSynthesizedProtocols.insert(PDecl->getCanonicalDecl()))
-    llvm_unreachable("protocol already synthesized");
-  
-}
-
-void RewriteModernObjC::RewriteObjCProtocolListMetaData(
-                                const ObjCList<ObjCProtocolDecl> &Protocols,
-                                StringRef prefix, StringRef ClassName,
-                                std::string &Result) {
-  if (Protocols.empty()) return;
-  
-  for (unsigned i = 0; i != Protocols.size(); i++)
-    RewriteObjCProtocolMetaData(Protocols[i], Result);
-  
-  // Output the top lovel protocol meta-data for the class.
-  /* struct _objc_protocol_list {
-   struct _objc_protocol_list *next;
-   int    protocol_count;
-   struct _objc_protocol *class_protocols[];
-   }
-   */
-  Result += "\n";
-  if (LangOpts.MicrosoftExt)
-    Result += "__declspec(allocate(\".cat_cls_meth$B\")) ";
-  Result += "static struct {\n";
-  Result += "\tstruct _objc_protocol_list *next;\n";
-  Result += "\tint    protocol_count;\n";
-  Result += "\tstruct _objc_protocol *class_protocols[";
-  Result += utostr(Protocols.size());
-  Result += "];\n} _OBJC_";
-  Result += prefix;
-  Result += "_PROTOCOLS_";
-  Result += ClassName;
-  Result += " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= "
-  "{\n\t0, ";
-  Result += utostr(Protocols.size());
-  Result += "\n";
-  
-  Result += "\t,{&_OBJC_PROTOCOL_";
-  Result += Protocols[0]->getNameAsString();
-  Result += " \n";
-  
-  for (unsigned i = 1; i != Protocols.size(); i++) {
-    Result += "\t ,&_OBJC_PROTOCOL_";
-    Result += Protocols[i]->getNameAsString();
-    Result += "\n";
-  }
-  Result += "\t }\n};\n";
-}
-
-/// hasObjCExceptionAttribute - Return true if this class or any super
-/// class has the __objc_exception__ attribute.
-/// FIXME. Move this to ASTContext.cpp as it is also used for IRGen.
-static bool hasObjCExceptionAttribute(ASTContext &Context,
-                                      const ObjCInterfaceDecl *OID) {
-  if (OID->hasAttr<ObjCExceptionAttr>())
-    return true;
-  if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
-    return hasObjCExceptionAttribute(Context, Super);
-  return false;
-}
-
-void RewriteModernObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
-                                           std::string &Result) {
-  ObjCInterfaceDecl *CDecl = IDecl->getClassInterface();
-  
-  // Explicitly declared @interface's are already synthesized.
-  if (CDecl->isImplicitInterfaceDecl())
-    assert(false && 
-           "Legacy implicit interface rewriting not supported in moder abi");
-  
-  WriteModernMetadataDeclarations(Context, Result);
-  SmallVector<ObjCIvarDecl *, 8> IVars;
-  
-  for (ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin();
-      IVD; IVD = IVD->getNextIvar()) {
-    // Ignore unnamed bit-fields.
-    if (!IVD->getDeclName())
-      continue;
-    IVars.push_back(IVD);
-  }
-  
-  Write__ivar_list_t_initializer(*this, Context, Result, IVars, 
-                                 "_OBJC_$_INSTANCE_VARIABLES_",
-                                 CDecl);
-  
-  // Build _objc_method_list for class's instance methods if needed
-  SmallVector<ObjCMethodDecl *, 32>
-    InstanceMethods(IDecl->instmeth_begin(), IDecl->instmeth_end());
-  
-  // If any of our property implementations have associated getters or
-  // setters, produce metadata for them as well.
-  for (ObjCImplDecl::propimpl_iterator Prop = IDecl->propimpl_begin(),
-       PropEnd = IDecl->propimpl_end();
-       Prop != PropEnd; ++Prop) {
-    if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
-      continue;
-    if (!Prop->getPropertyIvarDecl())
-      continue;
-    ObjCPropertyDecl *PD = Prop->getPropertyDecl();
-    if (!PD)
-      continue;
-    if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl())
-      if (mustSynthesizeSetterGetterMethod(IDecl, PD, true /*getter*/))
-        InstanceMethods.push_back(Getter);
-    if (PD->isReadOnly())
-      continue;
-    if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl())
-      if (mustSynthesizeSetterGetterMethod(IDecl, PD, false /*setter*/))
-        InstanceMethods.push_back(Setter);
-  }
-  
-  Write_method_list_t_initializer(*this, Context, Result, InstanceMethods,
-                                  "_OBJC_$_INSTANCE_METHODS_",
-                                  IDecl->getNameAsString(), true);
-  
-  SmallVector<ObjCMethodDecl *, 32>
-    ClassMethods(IDecl->classmeth_begin(), IDecl->classmeth_end());
-  
-  Write_method_list_t_initializer(*this, Context, Result, ClassMethods,
-                                  "_OBJC_$_CLASS_METHODS_",
-                                  IDecl->getNameAsString(), true);
-  
-  // Protocols referenced in class declaration?
-  // Protocol's super protocol list
-  std::vector<ObjCProtocolDecl *> RefedProtocols;
-  const ObjCList<ObjCProtocolDecl> &Protocols = CDecl->getReferencedProtocols();
-  for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
-       E = Protocols.end();
-       I != E; ++I) {
-    RefedProtocols.push_back(*I);
-    // Must write out all protocol definitions in current qualifier list,
-    // and in their nested qualifiers before writing out current definition.
-    RewriteObjCProtocolMetaData(*I, Result);
-  }
-  
-  Write_protocol_list_initializer(Context, Result, 
-                                  RefedProtocols,
-                                  "_OBJC_CLASS_PROTOCOLS_$_",
-                                  IDecl->getNameAsString());
-  
-  // Protocol's property metadata.
-  std::vector<ObjCPropertyDecl *> ClassProperties;
-  for (ObjCContainerDecl::prop_iterator I = CDecl->prop_begin(),
-       E = CDecl->prop_end(); I != E; ++I)
-    ClassProperties.push_back(*I);
-  
-  Write_prop_list_t_initializer(*this, Context, Result, ClassProperties,
-                                 /* Container */IDecl,
-                                 "_OBJC_$_PROP_LIST_",
-                                 CDecl->getNameAsString());
-
-  
-  // Data for initializing _class_ro_t  metaclass meta-data
-  uint32_t flags = CLS_META;
-  std::string InstanceSize;
-  std::string InstanceStart;
-  
-  
-  bool classIsHidden = CDecl->getVisibility() == HiddenVisibility;
-  if (classIsHidden)
-    flags |= OBJC2_CLS_HIDDEN;
-  
-  if (!CDecl->getSuperClass())
-    // class is root
-    flags |= CLS_ROOT;
-  InstanceSize = "sizeof(struct _class_t)";
-  InstanceStart = InstanceSize;
-  Write__class_ro_t_initializer(Context, Result, flags, 
-                                InstanceStart, InstanceSize,
-                                ClassMethods,
-                                0,
-                                0,
-                                0,
-                                "_OBJC_METACLASS_RO_$_",
-                                CDecl->getNameAsString());
-
-  
-  // Data for initializing _class_ro_t meta-data
-  flags = CLS;
-  if (classIsHidden)
-    flags |= OBJC2_CLS_HIDDEN;
-  
-  if (hasObjCExceptionAttribute(*Context, CDecl))
-    flags |= CLS_EXCEPTION;
-
-  if (!CDecl->getSuperClass())
-    // class is root
-    flags |= CLS_ROOT;
-  
-  InstanceSize.clear();
-  InstanceStart.clear();
-  if (!ObjCSynthesizedStructs.count(CDecl)) {
-    InstanceSize = "0";
-    InstanceStart = "0";
-  }
-  else {
-    InstanceSize = "sizeof(struct ";
-    InstanceSize += CDecl->getNameAsString();
-    InstanceSize += "_IMPL)";
-    
-    ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin();
-    if (IVD) {
-      RewriteIvarOffsetComputation(IVD, InstanceStart);
-    }
-    else 
-      InstanceStart = InstanceSize;
-  }
-  Write__class_ro_t_initializer(Context, Result, flags, 
-                                InstanceStart, InstanceSize,
-                                InstanceMethods,
-                                RefedProtocols,
-                                IVars,
-                                ClassProperties,
-                                "_OBJC_CLASS_RO_$_",
-                                CDecl->getNameAsString());
-  
-  Write_class_t(Context, Result,
-                "OBJC_METACLASS_$_",
-                CDecl, /*metaclass*/true);
-  
-  Write_class_t(Context, Result,
-                "OBJC_CLASS_$_",
-                CDecl, /*metaclass*/false);
-  
-  if (ImplementationIsNonLazy(IDecl))
-    DefinedNonLazyClasses.push_back(CDecl);
-                
-}
-
-void RewriteModernObjC::RewriteClassSetupInitHook(std::string &Result) {
-  int ClsDefCount = ClassImplementation.size();
-  if (!ClsDefCount)
-    return;
-  Result += "#pragma section(\".objc_inithooks$B\", long, read, write)\n";
-  Result += "__declspec(allocate(\".objc_inithooks$B\")) ";
-  Result += "static void *OBJC_CLASS_SETUP[] = {\n";
-  for (int i = 0; i < ClsDefCount; i++) {
-    ObjCImplementationDecl *IDecl = ClassImplementation[i];
-    ObjCInterfaceDecl *CDecl = IDecl->getClassInterface();
-    Result += "\t(void *)&OBJC_CLASS_SETUP_$_";
-    Result  += CDecl->getName(); Result += ",\n";
-  }
-  Result += "};\n";
-}
-
-void RewriteModernObjC::RewriteMetaDataIntoBuffer(std::string &Result) {
-  int ClsDefCount = ClassImplementation.size();
-  int CatDefCount = CategoryImplementation.size();
-  
-  // For each implemented class, write out all its meta data.
-  for (int i = 0; i < ClsDefCount; i++)
-    RewriteObjCClassMetaData(ClassImplementation[i], Result);
-  
-  RewriteClassSetupInitHook(Result);
-  
-  // For each implemented category, write out all its meta data.
-  for (int i = 0; i < CatDefCount; i++)
-    RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result);
-  
-  RewriteCategorySetupInitHook(Result);
-  
-  if (ClsDefCount > 0) {
-    if (LangOpts.MicrosoftExt)
-      Result += "__declspec(allocate(\".objc_classlist$B\")) ";
-    Result += "static struct _class_t *L_OBJC_LABEL_CLASS_$ [";
-    Result += llvm::utostr(ClsDefCount); Result += "]";
-    Result += 
-      " __attribute__((used, section (\"__DATA, __objc_classlist,"
-      "regular,no_dead_strip\")))= {\n";
-    for (int i = 0; i < ClsDefCount; i++) {
-      Result += "\t&OBJC_CLASS_$_";
-      Result += ClassImplementation[i]->getNameAsString();
-      Result += ",\n";
-    }
-    Result += "};\n";
-    
-    if (!DefinedNonLazyClasses.empty()) {
-      if (LangOpts.MicrosoftExt)
-        Result += "__declspec(allocate(\".objc_nlclslist$B\")) \n";
-      Result += "static struct _class_t *_OBJC_LABEL_NONLAZY_CLASS_$[] = {\n\t";
-      for (unsigned i = 0, e = DefinedNonLazyClasses.size(); i < e; i++) {
-        Result += "\t&OBJC_CLASS_$_"; Result += DefinedNonLazyClasses[i]->getNameAsString();
-        Result += ",\n";
-      }
-      Result += "};\n";
-    }
-  }
-  
-  if (CatDefCount > 0) {
-    if (LangOpts.MicrosoftExt)
-      Result += "__declspec(allocate(\".objc_catlist$B\")) ";
-    Result += "static struct _category_t *L_OBJC_LABEL_CATEGORY_$ [";
-    Result += llvm::utostr(CatDefCount); Result += "]";
-    Result += 
-    " __attribute__((used, section (\"__DATA, __objc_catlist,"
-    "regular,no_dead_strip\")))= {\n";
-    for (int i = 0; i < CatDefCount; i++) {
-      Result += "\t&_OBJC_$_CATEGORY_";
-      Result += 
-        CategoryImplementation[i]->getClassInterface()->getNameAsString(); 
-      Result += "_$_";
-      Result += CategoryImplementation[i]->getNameAsString();
-      Result += ",\n";
-    }
-    Result += "};\n";
-  }
-  
-  if (!DefinedNonLazyCategories.empty()) {
-    if (LangOpts.MicrosoftExt)
-      Result += "__declspec(allocate(\".objc_nlcatlist$B\")) \n";
-    Result += "static struct _category_t *_OBJC_LABEL_NONLAZY_CATEGORY_$[] = {\n\t";
-    for (unsigned i = 0, e = DefinedNonLazyCategories.size(); i < e; i++) {
-      Result += "\t&_OBJC_$_CATEGORY_";
-      Result += 
-        DefinedNonLazyCategories[i]->getClassInterface()->getNameAsString(); 
-      Result += "_$_";
-      Result += DefinedNonLazyCategories[i]->getNameAsString();
-      Result += ",\n";
-    }
-    Result += "};\n";
-  }
-}
-
-void RewriteModernObjC::WriteImageInfo(std::string &Result) {
-  if (LangOpts.MicrosoftExt)
-    Result += "__declspec(allocate(\".objc_imageinfo$B\")) \n";
-  
-  Result += "static struct IMAGE_INFO { unsigned version; unsigned flag; } ";
-  // version 0, ObjCABI is 2
-  Result += "_OBJC_IMAGE_INFO = { 0, 2 };\n";
-}
-
-/// RewriteObjCCategoryImplDecl - Rewrite metadata for each category
-/// implementation.
-void RewriteModernObjC::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl,
-                                              std::string &Result) {
-  WriteModernMetadataDeclarations(Context, Result);
-  ObjCInterfaceDecl *ClassDecl = IDecl->getClassInterface();
-  // Find category declaration for this implementation.
-  ObjCCategoryDecl *CDecl
-    = ClassDecl->FindCategoryDeclaration(IDecl->getIdentifier());
-  
-  std::string FullCategoryName = ClassDecl->getNameAsString();
-  FullCategoryName += "_$_";
-  FullCategoryName += CDecl->getNameAsString();
-  
-  // Build _objc_method_list for class's instance methods if needed
-  SmallVector<ObjCMethodDecl *, 32>
-  InstanceMethods(IDecl->instmeth_begin(), IDecl->instmeth_end());
-  
-  // If any of our property implementations have associated getters or
-  // setters, produce metadata for them as well.
-  for (ObjCImplDecl::propimpl_iterator Prop = IDecl->propimpl_begin(),
-       PropEnd = IDecl->propimpl_end();
-       Prop != PropEnd; ++Prop) {
-    if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
-      continue;
-    if (!Prop->getPropertyIvarDecl())
-      continue;
-    ObjCPropertyDecl *PD = Prop->getPropertyDecl();
-    if (!PD)
-      continue;
-    if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl())
-      InstanceMethods.push_back(Getter);
-    if (PD->isReadOnly())
-      continue;
-    if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl())
-      InstanceMethods.push_back(Setter);
-  }
-  
-  Write_method_list_t_initializer(*this, Context, Result, InstanceMethods,
-                                  "_OBJC_$_CATEGORY_INSTANCE_METHODS_",
-                                  FullCategoryName, true);
-  
-  SmallVector<ObjCMethodDecl *, 32>
-    ClassMethods(IDecl->classmeth_begin(), IDecl->classmeth_end());
-  
-  Write_method_list_t_initializer(*this, Context, Result, ClassMethods,
-                                  "_OBJC_$_CATEGORY_CLASS_METHODS_",
-                                  FullCategoryName, true);
-  
-  // Protocols referenced in class declaration?
-  // Protocol's super protocol list
-  std::vector<ObjCProtocolDecl *> RefedProtocols;
-  for (ObjCInterfaceDecl::protocol_iterator I = CDecl->protocol_begin(),
-                                            E = CDecl->protocol_end();
-
-         I != E; ++I) {
-    RefedProtocols.push_back(*I);
-    // Must write out all protocol definitions in current qualifier list,
-    // and in their nested qualifiers before writing out current definition.
-    RewriteObjCProtocolMetaData(*I, Result);
-  }
-  
-  Write_protocol_list_initializer(Context, Result, 
-                                  RefedProtocols,
-                                  "_OBJC_CATEGORY_PROTOCOLS_$_",
-                                  FullCategoryName);
-  
-  // Protocol's property metadata.
-  std::vector<ObjCPropertyDecl *> ClassProperties;
-  for (ObjCContainerDecl::prop_iterator I = CDecl->prop_begin(),
-       E = CDecl->prop_end(); I != E; ++I)
-    ClassProperties.push_back(*I);
-  
-  Write_prop_list_t_initializer(*this, Context, Result, ClassProperties,
-                                /* Container */IDecl,
-                                "_OBJC_$_PROP_LIST_",
-                                FullCategoryName);
-  
-  Write_category_t(*this, Context, Result,
-                   CDecl,
-                   ClassDecl,
-                   InstanceMethods,
-                   ClassMethods,
-                   RefedProtocols,
-                   ClassProperties);
-  
-  // Determine if this category is also "non-lazy".
-  if (ImplementationIsNonLazy(IDecl))
-    DefinedNonLazyCategories.push_back(CDecl);
-    
-}
-
-void RewriteModernObjC::RewriteCategorySetupInitHook(std::string &Result) {
-  int CatDefCount = CategoryImplementation.size();
-  if (!CatDefCount)
-    return;
-  Result += "#pragma section(\".objc_inithooks$B\", long, read, write)\n";
-  Result += "__declspec(allocate(\".objc_inithooks$B\")) ";
-  Result += "static void *OBJC_CATEGORY_SETUP[] = {\n";
-  for (int i = 0; i < CatDefCount; i++) {
-    ObjCCategoryImplDecl *IDecl = CategoryImplementation[i];
-    ObjCCategoryDecl *CatDecl= IDecl->getCategoryDecl();
-    ObjCInterfaceDecl *ClassDecl = IDecl->getClassInterface();
-    Result += "\t(void *)&OBJC_CATEGORY_SETUP_$_";
-    Result += ClassDecl->getName();
-    Result += "_$_";
-    Result += CatDecl->getName();
-    Result += ",\n";
-  }
-  Result += "};\n";
-}
-
-// RewriteObjCMethodsMetaData - Rewrite methods metadata for instance or
-/// class methods.
-template<typename MethodIterator>
-void RewriteModernObjC::RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
-                                             MethodIterator MethodEnd,
-                                             bool IsInstanceMethod,
-                                             StringRef prefix,
-                                             StringRef ClassName,
-                                             std::string &Result) {
-  if (MethodBegin == MethodEnd) return;
-  
-  if (!objc_impl_method) {
-    /* struct _objc_method {
-     SEL _cmd;
-     char *method_types;
-     void *_imp;
-     }
-     */
-    Result += "\nstruct _objc_method {\n";
-    Result += "\tSEL _cmd;\n";
-    Result += "\tchar *method_types;\n";
-    Result += "\tvoid *_imp;\n";
-    Result += "};\n";
-    
-    objc_impl_method = true;
-  }
-  
-  // Build _objc_method_list for class's methods if needed
-  
-  /* struct  {
-   struct _objc_method_list *next_method;
-   int method_count;
-   struct _objc_method method_list[];
-   }
-   */
-  unsigned NumMethods = std::distance(MethodBegin, MethodEnd);
-  Result += "\n";
-  if (LangOpts.MicrosoftExt) {
-    if (IsInstanceMethod)
-      Result += "__declspec(allocate(\".inst_meth$B\")) ";
-    else
-      Result += "__declspec(allocate(\".cls_meth$B\")) ";
-  }
-  Result += "static struct {\n";
-  Result += "\tstruct _objc_method_list *next_method;\n";
-  Result += "\tint method_count;\n";
-  Result += "\tstruct _objc_method method_list[";
-  Result += utostr(NumMethods);
-  Result += "];\n} _OBJC_";
-  Result += prefix;
-  Result += IsInstanceMethod ? "INSTANCE" : "CLASS";
-  Result += "_METHODS_";
-  Result += ClassName;
-  Result += " __attribute__ ((used, section (\"__OBJC, __";
-  Result += IsInstanceMethod ? "inst" : "cls";
-  Result += "_meth\")))= ";
-  Result += "{\n\t0, " + utostr(NumMethods) + "\n";
-  
-  Result += "\t,{{(SEL)\"";
-  Result += (*MethodBegin)->getSelector().getAsString().c_str();
-  std::string MethodTypeString;
-  Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString);
-  Result += "\", \"";
-  Result += MethodTypeString;
-  Result += "\", (void *)";
-  Result += MethodInternalNames[*MethodBegin];
-  Result += "}\n";
-  for (++MethodBegin; MethodBegin != MethodEnd; ++MethodBegin) {
-    Result += "\t  ,{(SEL)\"";
-    Result += (*MethodBegin)->getSelector().getAsString().c_str();
-    std::string MethodTypeString;
-    Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString);
-    Result += "\", \"";
-    Result += MethodTypeString;
-    Result += "\", (void *)";
-    Result += MethodInternalNames[*MethodBegin];
-    Result += "}\n";
-  }
-  Result += "\t }\n};\n";
-}
-
-Stmt *RewriteModernObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) {
-  SourceRange OldRange = IV->getSourceRange();
-  Expr *BaseExpr = IV->getBase();
-  
-  // Rewrite the base, but without actually doing replaces.
-  {
-    DisableReplaceStmtScope S(*this);
-    BaseExpr = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(BaseExpr));
-    IV->setBase(BaseExpr);
-  }
-  
-  ObjCIvarDecl *D = IV->getDecl();
-  
-  Expr *Replacement = IV;
-  
-    if (BaseExpr->getType()->isObjCObjectPointerType()) {
-      const ObjCInterfaceType *iFaceDecl =
-        dyn_cast<ObjCInterfaceType>(BaseExpr->getType()->getPointeeType());
-      assert(iFaceDecl && "RewriteObjCIvarRefExpr - iFaceDecl is null");
-      // lookup which class implements the instance variable.
-      ObjCInterfaceDecl *clsDeclared = 0;
-      iFaceDecl->getDecl()->lookupInstanceVariable(D->getIdentifier(),
-                                                   clsDeclared);
-      assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class");
-      
-      // Build name of symbol holding ivar offset.
-      std::string IvarOffsetName;
-      if (D->isBitField())
-        ObjCIvarBitfieldGroupOffset(D, IvarOffsetName);
-      else
-        WriteInternalIvarName(clsDeclared, D, IvarOffsetName);
-      
-      ReferencedIvars[clsDeclared].insert(D);
-      
-      // cast offset to "char *".
-      CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, 
-                                                    Context->getPointerType(Context->CharTy),
-                                                    CK_BitCast,
-                                                    BaseExpr);
-      VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
-                                       SourceLocation(), &Context->Idents.get(IvarOffsetName),
-                                       Context->UnsignedLongTy, 0, SC_Extern);
-      DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, false,
-                                                   Context->UnsignedLongTy, VK_LValue,
-                                                   SourceLocation());
-      BinaryOperator *addExpr = 
-        new (Context) BinaryOperator(castExpr, DRE, BO_Add, 
-                                     Context->getPointerType(Context->CharTy),
-                                     VK_RValue, OK_Ordinary, SourceLocation(), false);
-      // Don't forget the parens to enforce the proper binding.
-      ParenExpr *PE = new (Context) ParenExpr(SourceLocation(),
-                                              SourceLocation(),
-                                              addExpr);
-      QualType IvarT = D->getType();
-      if (D->isBitField())
-        IvarT = GetGroupRecordTypeForObjCIvarBitfield(D);
-
-      if (!isa<TypedefType>(IvarT) && IvarT->isRecordType()) {
-        RecordDecl *RD = IvarT->getAs<RecordType>()->getDecl();
-        RD = RD->getDefinition();
-        if (RD && !RD->getDeclName().getAsIdentifierInfo()) {
-          // decltype(((Foo_IMPL*)0)->bar) *
-          ObjCContainerDecl *CDecl = 
-            dyn_cast<ObjCContainerDecl>(D->getDeclContext());
-          // ivar in class extensions requires special treatment.
-          if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(CDecl))
-            CDecl = CatDecl->getClassInterface();
-          std::string RecName = CDecl->getName();
-          RecName += "_IMPL";
-          RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
-                                              SourceLocation(), SourceLocation(),
-                                              &Context->Idents.get(RecName.c_str()));
-          QualType PtrStructIMPL = Context->getPointerType(Context->getTagDeclType(RD));
-          unsigned UnsignedIntSize = 
-            static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
-          Expr *Zero = IntegerLiteral::Create(*Context,
-                                              llvm::APInt(UnsignedIntSize, 0),
-                                              Context->UnsignedIntTy, SourceLocation());
-          Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL, CK_BitCast, Zero);
-          ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(),
-                                                  Zero);
-          FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(),
-                                            SourceLocation(),
-                                            &Context->Idents.get(D->getNameAsString()),
-                                            IvarT, 0,
-                                            /*BitWidth=*/0, /*Mutable=*/true,
-                                            ICIS_NoInit);
-          MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(),
-                                                    FD->getType(), VK_LValue,
-                                                    OK_Ordinary);
-          IvarT = Context->getDecltypeType(ME, ME->getType());
-        }
-      }
-      convertObjCTypeToCStyleType(IvarT);
-      QualType castT = Context->getPointerType(IvarT);
-          
-      castExpr = NoTypeInfoCStyleCastExpr(Context, 
-                                          castT,
-                                          CK_BitCast,
-                                          PE);
-      
-      
-      Expr *Exp = new (Context) UnaryOperator(castExpr, UO_Deref, IvarT,
-                                              VK_LValue, OK_Ordinary,
-                                              SourceLocation());
-      PE = new (Context) ParenExpr(OldRange.getBegin(),
-                                   OldRange.getEnd(),
-                                   Exp);
-      
-      if (D->isBitField()) {
-        FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(),
-                                          SourceLocation(),
-                                          &Context->Idents.get(D->getNameAsString()),
-                                          D->getType(), 0,
-                                          /*BitWidth=*/D->getBitWidth(),
-                                          /*Mutable=*/true,
-                                          ICIS_NoInit);
-        MemberExpr *ME = new (Context) MemberExpr(PE, /*isArrow*/false, FD, SourceLocation(),
-                                                  FD->getType(), VK_LValue,
-                                                  OK_Ordinary);
-        Replacement = ME;
-
-      }
-      else
-        Replacement = PE;
-    }
-  
-    ReplaceStmtWithRange(IV, Replacement, OldRange);
-    return Replacement;  
-}
diff --git a/lib/Rewrite/Frontend/RewriteObjC.cpp b/lib/Rewrite/Frontend/RewriteObjC.cpp
deleted file mode 100644
index 3dda2c5..0000000
--- a/lib/Rewrite/Frontend/RewriteObjC.cpp
+++ /dev/null
@@ -1,6011 +0,0 @@
-//===--- RewriteObjC.cpp - Playground for the code rewriter ---------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Hacks and fun related to the code rewriter.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Rewrite/Frontend/ASTConsumers.h"
-#include "clang/AST/AST.h"
-#include "clang/AST/ASTConsumer.h"
-#include "clang/AST/Attr.h"
-#include "clang/AST/ParentMap.h"
-#include "clang/Basic/CharInfo.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Lex/Lexer.h"
-#include "clang/Rewrite/Core/Rewriter.h"
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace clang;
-using llvm::utostr;
-
-namespace {
-  class RewriteObjC : public ASTConsumer {
-  protected:
-    
-    enum {
-      BLOCK_FIELD_IS_OBJECT   =  3,  /* id, NSObject, __attribute__((NSObject)),
-                                        block, ... */
-      BLOCK_FIELD_IS_BLOCK    =  7,  /* a block variable */
-      BLOCK_FIELD_IS_BYREF    =  8,  /* the on stack structure holding the 
-                                        __block variable */
-      BLOCK_FIELD_IS_WEAK     = 16,  /* declared __weak, only used in byref copy
-                                        helpers */
-      BLOCK_BYREF_CALLER      = 128, /* called from __block (byref) copy/dispose
-                                        support routines */
-      BLOCK_BYREF_CURRENT_MAX = 256
-    };
-    
-    enum {
-      BLOCK_NEEDS_FREE =        (1 << 24),
-      BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
-      BLOCK_HAS_CXX_OBJ =       (1 << 26),
-      BLOCK_IS_GC =             (1 << 27),
-      BLOCK_IS_GLOBAL =         (1 << 28),
-      BLOCK_HAS_DESCRIPTOR =    (1 << 29)
-    };
-    static const int OBJC_ABI_VERSION = 7;
-    
-    Rewriter Rewrite;
-    DiagnosticsEngine &Diags;
-    const LangOptions &LangOpts;
-    ASTContext *Context;
-    SourceManager *SM;
-    TranslationUnitDecl *TUDecl;
-    FileID MainFileID;
-    const char *MainFileStart, *MainFileEnd;
-    Stmt *CurrentBody;
-    ParentMap *PropParentMap; // created lazily.
-    std::string InFileName;
-    raw_ostream* OutFile;
-    std::string Preamble;
-    
-    TypeDecl *ProtocolTypeDecl;
-    VarDecl *GlobalVarDecl;
-    unsigned RewriteFailedDiag;
-    // ObjC string constant support.
-    unsigned NumObjCStringLiterals;
-    VarDecl *ConstantStringClassReference;
-    RecordDecl *NSStringRecord;
-
-    // ObjC foreach break/continue generation support.
-    int BcLabelCount;
-    
-    unsigned TryFinallyContainsReturnDiag;
-    // Needed for super.
-    ObjCMethodDecl *CurMethodDef;
-    RecordDecl *SuperStructDecl;
-    RecordDecl *ConstantStringDecl;
-    
-    FunctionDecl *MsgSendFunctionDecl;
-    FunctionDecl *MsgSendSuperFunctionDecl;
-    FunctionDecl *MsgSendStretFunctionDecl;
-    FunctionDecl *MsgSendSuperStretFunctionDecl;
-    FunctionDecl *MsgSendFpretFunctionDecl;
-    FunctionDecl *GetClassFunctionDecl;
-    FunctionDecl *GetMetaClassFunctionDecl;
-    FunctionDecl *GetSuperClassFunctionDecl;
-    FunctionDecl *SelGetUidFunctionDecl;
-    FunctionDecl *CFStringFunctionDecl;
-    FunctionDecl *SuperConstructorFunctionDecl;
-    FunctionDecl *CurFunctionDef;
-    FunctionDecl *CurFunctionDeclToDeclareForBlock;
-
-    /* Misc. containers needed for meta-data rewrite. */
-    SmallVector<ObjCImplementationDecl *, 8> ClassImplementation;
-    SmallVector<ObjCCategoryImplDecl *, 8> CategoryImplementation;
-    llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCSynthesizedStructs;
-    llvm::SmallPtrSet<ObjCProtocolDecl*, 8> ObjCSynthesizedProtocols;
-    llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCForwardDecls;
-    llvm::DenseMap<ObjCMethodDecl*, std::string> MethodInternalNames;
-    SmallVector<Stmt *, 32> Stmts;
-    SmallVector<int, 8> ObjCBcLabelNo;
-    // Remember all the @protocol(<expr>) expressions.
-    llvm::SmallPtrSet<ObjCProtocolDecl *, 32> ProtocolExprDecls;
-    
-    llvm::DenseSet<uint64_t> CopyDestroyCache;
-
-    // Block expressions.
-    SmallVector<BlockExpr *, 32> Blocks;
-    SmallVector<int, 32> InnerDeclRefsCount;
-    SmallVector<DeclRefExpr *, 32> InnerDeclRefs;
-    
-    SmallVector<DeclRefExpr *, 32> BlockDeclRefs;
-
-    // Block related declarations.
-    SmallVector<ValueDecl *, 8> BlockByCopyDecls;
-    llvm::SmallPtrSet<ValueDecl *, 8> BlockByCopyDeclsPtrSet;
-    SmallVector<ValueDecl *, 8> BlockByRefDecls;
-    llvm::SmallPtrSet<ValueDecl *, 8> BlockByRefDeclsPtrSet;
-    llvm::DenseMap<ValueDecl *, unsigned> BlockByRefDeclNo;
-    llvm::SmallPtrSet<ValueDecl *, 8> ImportedBlockDecls;
-    llvm::SmallPtrSet<VarDecl *, 8> ImportedLocalExternalDecls;
-    
-    llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs;
-
-    // This maps an original source AST to it's rewritten form. This allows
-    // us to avoid rewriting the same node twice (which is very uncommon).
-    // This is needed to support some of the exotic property rewriting.
-    llvm::DenseMap<Stmt *, Stmt *> ReplacedNodes;
-
-    // Needed for header files being rewritten
-    bool IsHeader;
-    bool SilenceRewriteMacroWarning;
-    bool objc_impl_method;
-    
-    bool DisableReplaceStmt;
-    class DisableReplaceStmtScope {
-      RewriteObjC &R;
-      bool SavedValue;
-    
-    public:
-      DisableReplaceStmtScope(RewriteObjC &R)
-        : R(R), SavedValue(R.DisableReplaceStmt) {
-        R.DisableReplaceStmt = true;
-      }
-      ~DisableReplaceStmtScope() {
-        R.DisableReplaceStmt = SavedValue;
-      }
-    };
-    void InitializeCommon(ASTContext &context);
-
-  public:
-
-    // Top Level Driver code.
-    virtual bool HandleTopLevelDecl(DeclGroupRef D) {
-      for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) {
-        if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*I)) {
-          if (!Class->isThisDeclarationADefinition()) {
-            RewriteForwardClassDecl(D);
-            break;
-          }
-        }
-
-        if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*I)) {
-          if (!Proto->isThisDeclarationADefinition()) {
-            RewriteForwardProtocolDecl(D);
-            break;
-          }
-        }
-
-        HandleTopLevelSingleDecl(*I);
-      }
-      return true;
-    }
-    void HandleTopLevelSingleDecl(Decl *D);
-    void HandleDeclInMainFile(Decl *D);
-    RewriteObjC(std::string inFile, raw_ostream *OS,
-                DiagnosticsEngine &D, const LangOptions &LOpts,
-                bool silenceMacroWarn);
-
-    ~RewriteObjC() {}
-
-    virtual void HandleTranslationUnit(ASTContext &C);
-
-    void ReplaceStmt(Stmt *Old, Stmt *New) {
-      Stmt *ReplacingStmt = ReplacedNodes[Old];
-
-      if (ReplacingStmt)
-        return; // We can't rewrite the same node twice.
-
-      if (DisableReplaceStmt)
-        return;
-
-      // If replacement succeeded or warning disabled return with no warning.
-      if (!Rewrite.ReplaceStmt(Old, New)) {
-        ReplacedNodes[Old] = New;
-        return;
-      }
-      if (SilenceRewriteMacroWarning)
-        return;
-      Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag)
-                   << Old->getSourceRange();
-    }
-
-    void ReplaceStmtWithRange(Stmt *Old, Stmt *New, SourceRange SrcRange) {
-      if (DisableReplaceStmt)
-        return;
-
-      // Measure the old text.
-      int Size = Rewrite.getRangeSize(SrcRange);
-      if (Size == -1) {
-        Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag)
-                     << Old->getSourceRange();
-        return;
-      }
-      // Get the new text.
-      std::string SStr;
-      llvm::raw_string_ostream S(SStr);
-      New->printPretty(S, 0, PrintingPolicy(LangOpts));
-      const std::string &Str = S.str();
-
-      // If replacement succeeded or warning disabled return with no warning.
-      if (!Rewrite.ReplaceText(SrcRange.getBegin(), Size, Str)) {
-        ReplacedNodes[Old] = New;
-        return;
-      }
-      if (SilenceRewriteMacroWarning)
-        return;
-      Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag)
-                   << Old->getSourceRange();
-    }
-
-    void InsertText(SourceLocation Loc, StringRef Str,
-                    bool InsertAfter = true) {
-      // If insertion succeeded or warning disabled return with no warning.
-      if (!Rewrite.InsertText(Loc, Str, InsertAfter) ||
-          SilenceRewriteMacroWarning)
-        return;
-
-      Diags.Report(Context->getFullLoc(Loc), RewriteFailedDiag);
-    }
-
-    void ReplaceText(SourceLocation Start, unsigned OrigLength,
-                     StringRef Str) {
-      // If removal succeeded or warning disabled return with no warning.
-      if (!Rewrite.ReplaceText(Start, OrigLength, Str) ||
-          SilenceRewriteMacroWarning)
-        return;
-
-      Diags.Report(Context->getFullLoc(Start), RewriteFailedDiag);
-    }
-
-    // Syntactic Rewriting.
-    void RewriteRecordBody(RecordDecl *RD);
-    void RewriteInclude();
-    void RewriteForwardClassDecl(DeclGroupRef D);
-    void RewriteForwardClassDecl(const SmallVectorImpl<Decl *> &DG);
-    void RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl, 
-                                     const std::string &typedefString);
-    void RewriteImplementations();
-    void RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
-                                 ObjCImplementationDecl *IMD,
-                                 ObjCCategoryImplDecl *CID);
-    void RewriteInterfaceDecl(ObjCInterfaceDecl *Dcl);
-    void RewriteImplementationDecl(Decl *Dcl);
-    void RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl,
-                               ObjCMethodDecl *MDecl, std::string &ResultStr);
-    void RewriteTypeIntoString(QualType T, std::string &ResultStr,
-                               const FunctionType *&FPRetType);
-    void RewriteByRefString(std::string &ResultStr, const std::string &Name,
-                            ValueDecl *VD, bool def=false);
-    void RewriteCategoryDecl(ObjCCategoryDecl *Dcl);
-    void RewriteProtocolDecl(ObjCProtocolDecl *Dcl);
-    void RewriteForwardProtocolDecl(DeclGroupRef D);
-    void RewriteForwardProtocolDecl(const SmallVectorImpl<Decl *> &DG);
-    void RewriteMethodDeclaration(ObjCMethodDecl *Method);
-    void RewriteProperty(ObjCPropertyDecl *prop);
-    void RewriteFunctionDecl(FunctionDecl *FD);
-    void RewriteBlockPointerType(std::string& Str, QualType Type);
-    void RewriteBlockPointerTypeVariable(std::string& Str, ValueDecl *VD);
-    void RewriteBlockLiteralFunctionDecl(FunctionDecl *FD);
-    void RewriteObjCQualifiedInterfaceTypes(Decl *Dcl);
-    void RewriteTypeOfDecl(VarDecl *VD);
-    void RewriteObjCQualifiedInterfaceTypes(Expr *E);
-  
-    // Expression Rewriting.
-    Stmt *RewriteFunctionBodyOrGlobalInitializer(Stmt *S);
-    Stmt *RewriteAtEncode(ObjCEncodeExpr *Exp);
-    Stmt *RewritePropertyOrImplicitGetter(PseudoObjectExpr *Pseudo);
-    Stmt *RewritePropertyOrImplicitSetter(PseudoObjectExpr *Pseudo);
-    Stmt *RewriteAtSelector(ObjCSelectorExpr *Exp);
-    Stmt *RewriteMessageExpr(ObjCMessageExpr *Exp);
-    Stmt *RewriteObjCStringLiteral(ObjCStringLiteral *Exp);
-    Stmt *RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp);
-    void RewriteTryReturnStmts(Stmt *S);
-    void RewriteSyncReturnStmts(Stmt *S, std::string buf);
-    Stmt *RewriteObjCTryStmt(ObjCAtTryStmt *S);
-    Stmt *RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S);
-    Stmt *RewriteObjCThrowStmt(ObjCAtThrowStmt *S);
-    Stmt *RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
-                                       SourceLocation OrigEnd);
-    Stmt *RewriteBreakStmt(BreakStmt *S);
-    Stmt *RewriteContinueStmt(ContinueStmt *S);
-    void RewriteCastExpr(CStyleCastExpr *CE);
-    
-    // Block rewriting.
-    void RewriteBlocksInFunctionProtoType(QualType funcType, NamedDecl *D);
-    
-    // Block specific rewrite rules.
-    void RewriteBlockPointerDecl(NamedDecl *VD);
-    void RewriteByRefVar(VarDecl *VD);
-    Stmt *RewriteBlockDeclRefExpr(DeclRefExpr *VD);
-    Stmt *RewriteLocalVariableExternalStorage(DeclRefExpr *DRE);
-    void RewriteBlockPointerFunctionArgs(FunctionDecl *FD);
-    
-    void RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl,
-                                      std::string &Result);
-    
-    virtual void Initialize(ASTContext &context) = 0;
-    
-    // Metadata Rewriting.
-    virtual void RewriteMetaDataIntoBuffer(std::string &Result) = 0;
-    virtual void RewriteObjCProtocolListMetaData(const ObjCList<ObjCProtocolDecl> &Prots,
-                                                 StringRef prefix,
-                                                 StringRef ClassName,
-                                                 std::string &Result) = 0;
-    virtual void RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *CDecl,
-                                             std::string &Result) = 0;
-    virtual void RewriteObjCProtocolMetaData(ObjCProtocolDecl *Protocol,
-                                     StringRef prefix,
-                                     StringRef ClassName,
-                                     std::string &Result) = 0;
-    virtual void RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
-                                          std::string &Result) = 0;
-    
-    // Rewriting ivar access
-    virtual Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) = 0;
-    virtual void RewriteIvarOffsetComputation(ObjCIvarDecl *ivar,
-                                         std::string &Result) = 0;
-    
-    // Misc. AST transformation routines. Sometimes they end up calling
-    // rewriting routines on the new ASTs.
-    CallExpr *SynthesizeCallToFunctionDecl(FunctionDecl *FD,
-                                           Expr **args, unsigned nargs,
-                                           SourceLocation StartLoc=SourceLocation(),
-                                           SourceLocation EndLoc=SourceLocation());
-    CallExpr *SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFlavor,
-                                        QualType msgSendType, 
-                                        QualType returnType, 
-                                        SmallVectorImpl<QualType> &ArgTypes,
-                                        SmallVectorImpl<Expr*> &MsgExprs,
-                                        ObjCMethodDecl *Method);
-    Stmt *SynthMessageExpr(ObjCMessageExpr *Exp,
-                           SourceLocation StartLoc=SourceLocation(),
-                           SourceLocation EndLoc=SourceLocation());
-    
-    void SynthCountByEnumWithState(std::string &buf);
-    void SynthMsgSendFunctionDecl();
-    void SynthMsgSendSuperFunctionDecl();
-    void SynthMsgSendStretFunctionDecl();
-    void SynthMsgSendFpretFunctionDecl();
-    void SynthMsgSendSuperStretFunctionDecl();
-    void SynthGetClassFunctionDecl();
-    void SynthGetMetaClassFunctionDecl();
-    void SynthGetSuperClassFunctionDecl();
-    void SynthSelGetUidFunctionDecl();
-    void SynthSuperConstructorFunctionDecl();
-    
-    std::string SynthesizeByrefCopyDestroyHelper(VarDecl *VD, int flag);
-    std::string SynthesizeBlockHelperFuncs(BlockExpr *CE, int i,
-                                      StringRef funcName, std::string Tag);
-    std::string SynthesizeBlockFunc(BlockExpr *CE, int i,
-                                      StringRef funcName, std::string Tag);
-    std::string SynthesizeBlockImpl(BlockExpr *CE, 
-                                    std::string Tag, std::string Desc);
-    std::string SynthesizeBlockDescriptor(std::string DescTag, 
-                                          std::string ImplTag,
-                                          int i, StringRef funcName,
-                                          unsigned hasCopy);
-    Stmt *SynthesizeBlockCall(CallExpr *Exp, const Expr* BlockExp);
-    void SynthesizeBlockLiterals(SourceLocation FunLocStart,
-                                 StringRef FunName);
-    FunctionDecl *SynthBlockInitFunctionDecl(StringRef name);
-    Stmt *SynthBlockInitExpr(BlockExpr *Exp,
-            const SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs);
-
-    // Misc. helper routines.
-    QualType getProtocolType();
-    void WarnAboutReturnGotoStmts(Stmt *S);
-    void HasReturnStmts(Stmt *S, bool &hasReturns);
-    void CheckFunctionPointerDecl(QualType dType, NamedDecl *ND);
-    void InsertBlockLiteralsWithinFunction(FunctionDecl *FD);
-    void InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD);
-
-    bool IsDeclStmtInForeachHeader(DeclStmt *DS);
-    void CollectBlockDeclRefInfo(BlockExpr *Exp);
-    void GetBlockDeclRefExprs(Stmt *S);
-    void GetInnerBlockDeclRefExprs(Stmt *S,
-                SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs,
-                llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts);
-
-    // We avoid calling Type::isBlockPointerType(), since it operates on the
-    // canonical type. We only care if the top-level type is a closure pointer.
-    bool isTopLevelBlockPointerType(QualType T) {
-      return isa<BlockPointerType>(T);
-    }
-
-    /// convertBlockPointerToFunctionPointer - Converts a block-pointer type
-    /// to a function pointer type and upon success, returns true; false
-    /// otherwise.
-    bool convertBlockPointerToFunctionPointer(QualType &T) {
-      if (isTopLevelBlockPointerType(T)) {
-        const BlockPointerType *BPT = T->getAs<BlockPointerType>();
-        T = Context->getPointerType(BPT->getPointeeType());
-        return true;
-      }
-      return false;
-    }
-    
-    bool needToScanForQualifiers(QualType T);
-    QualType getSuperStructType();
-    QualType getConstantStringStructType();
-    QualType convertFunctionTypeOfBlocks(const FunctionType *FT);
-    bool BufferContainsPPDirectives(const char *startBuf, const char *endBuf);
-    
-    void convertToUnqualifiedObjCType(QualType &T) {
-      if (T->isObjCQualifiedIdType())
-        T = Context->getObjCIdType();
-      else if (T->isObjCQualifiedClassType())
-        T = Context->getObjCClassType();
-      else if (T->isObjCObjectPointerType() &&
-               T->getPointeeType()->isObjCQualifiedInterfaceType()) {
-        if (const ObjCObjectPointerType * OBJPT =
-              T->getAsObjCInterfacePointerType()) {
-          const ObjCInterfaceType *IFaceT = OBJPT->getInterfaceType();
-          T = QualType(IFaceT, 0);
-          T = Context->getPointerType(T);
-        }
-     }
-    }
-    
-    // FIXME: This predicate seems like it would be useful to add to ASTContext.
-    bool isObjCType(QualType T) {
-      if (!LangOpts.ObjC1 && !LangOpts.ObjC2)
-        return false;
-
-      QualType OCT = Context->getCanonicalType(T).getUnqualifiedType();
-
-      if (OCT == Context->getCanonicalType(Context->getObjCIdType()) ||
-          OCT == Context->getCanonicalType(Context->getObjCClassType()))
-        return true;
-
-      if (const PointerType *PT = OCT->getAs<PointerType>()) {
-        if (isa<ObjCInterfaceType>(PT->getPointeeType()) ||
-            PT->getPointeeType()->isObjCQualifiedIdType())
-          return true;
-      }
-      return false;
-    }
-    bool PointerTypeTakesAnyBlockArguments(QualType QT);
-    bool PointerTypeTakesAnyObjCQualifiedType(QualType QT);
-    void GetExtentOfArgList(const char *Name, const char *&LParen,
-                            const char *&RParen);
-    
-    void QuoteDoublequotes(std::string &From, std::string &To) {
-      for (unsigned i = 0; i < From.length(); i++) {
-        if (From[i] == '"')
-          To += "\\\"";
-        else
-          To += From[i];
-      }
-    }
-
-    QualType getSimpleFunctionType(QualType result,
-                                   ArrayRef<QualType> args,
-                                   bool variadic = false) {
-      if (result == Context->getObjCInstanceType())
-        result =  Context->getObjCIdType();
-      FunctionProtoType::ExtProtoInfo fpi;
-      fpi.Variadic = variadic;
-      return Context->getFunctionType(result, args, fpi);
-    }
-
-    // Helper function: create a CStyleCastExpr with trivial type source info.
-    CStyleCastExpr* NoTypeInfoCStyleCastExpr(ASTContext *Ctx, QualType Ty,
-                                             CastKind Kind, Expr *E) {
-      TypeSourceInfo *TInfo = Ctx->getTrivialTypeSourceInfo(Ty, SourceLocation());
-      return CStyleCastExpr::Create(*Ctx, Ty, VK_RValue, Kind, E, 0, TInfo,
-                                    SourceLocation(), SourceLocation());
-    }
-  };
-  
-  class RewriteObjCFragileABI : public RewriteObjC {
-  public:
-    
-    RewriteObjCFragileABI(std::string inFile, raw_ostream *OS,
-                DiagnosticsEngine &D, const LangOptions &LOpts,
-                bool silenceMacroWarn) : RewriteObjC(inFile, OS,
-                                                     D, LOpts,
-                                                     silenceMacroWarn) {}
-    
-    ~RewriteObjCFragileABI() {}
-    virtual void Initialize(ASTContext &context);
-    
-    // Rewriting metadata
-    template<typename MethodIterator>
-    void RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
-                                    MethodIterator MethodEnd,
-                                    bool IsInstanceMethod,
-                                    StringRef prefix,
-                                    StringRef ClassName,
-                                    std::string &Result);
-    virtual void RewriteObjCProtocolMetaData(ObjCProtocolDecl *Protocol,
-                                             StringRef prefix,
-                                             StringRef ClassName,
-                                             std::string &Result);
-    virtual void RewriteObjCProtocolListMetaData(
-                  const ObjCList<ObjCProtocolDecl> &Prots,
-                  StringRef prefix, StringRef ClassName, std::string &Result);
-    virtual void RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
-                                          std::string &Result);
-    virtual void RewriteMetaDataIntoBuffer(std::string &Result);
-    virtual void RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *CDecl,
-                                             std::string &Result);
-    
-    // Rewriting ivar
-    virtual void RewriteIvarOffsetComputation(ObjCIvarDecl *ivar,
-                                              std::string &Result);
-    virtual Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV);
-  };
-}
-
-void RewriteObjC::RewriteBlocksInFunctionProtoType(QualType funcType,
-                                                   NamedDecl *D) {
-  if (const FunctionProtoType *fproto
-      = dyn_cast<FunctionProtoType>(funcType.IgnoreParens())) {
-    for (FunctionProtoType::arg_type_iterator I = fproto->arg_type_begin(),
-         E = fproto->arg_type_end(); I && (I != E); ++I)
-      if (isTopLevelBlockPointerType(*I)) {
-        // All the args are checked/rewritten. Don't call twice!
-        RewriteBlockPointerDecl(D);
-        break;
-      }
-  }
-}
-
-void RewriteObjC::CheckFunctionPointerDecl(QualType funcType, NamedDecl *ND) {
-  const PointerType *PT = funcType->getAs<PointerType>();
-  if (PT && PointerTypeTakesAnyBlockArguments(funcType))
-    RewriteBlocksInFunctionProtoType(PT->getPointeeType(), ND);
-}
-
-static bool IsHeaderFile(const std::string &Filename) {
-  std::string::size_type DotPos = Filename.rfind('.');
-
-  if (DotPos == std::string::npos) {
-    // no file extension
-    return false;
-  }
-
-  std::string Ext = std::string(Filename.begin()+DotPos+1, Filename.end());
-  // C header: .h
-  // C++ header: .hh or .H;
-  return Ext == "h" || Ext == "hh" || Ext == "H";
-}
-
-RewriteObjC::RewriteObjC(std::string inFile, raw_ostream* OS,
-                         DiagnosticsEngine &D, const LangOptions &LOpts,
-                         bool silenceMacroWarn)
-      : Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(OS),
-        SilenceRewriteMacroWarning(silenceMacroWarn) {
-  IsHeader = IsHeaderFile(inFile);
-  RewriteFailedDiag = Diags.getCustomDiagID(DiagnosticsEngine::Warning,
-               "rewriting sub-expression within a macro (may not be correct)");
-  TryFinallyContainsReturnDiag = Diags.getCustomDiagID(
-               DiagnosticsEngine::Warning,
-               "rewriter doesn't support user-specified control flow semantics "
-               "for @try/@finally (code may not execute properly)");
-}
-
-ASTConsumer *clang::CreateObjCRewriter(const std::string& InFile,
-                                       raw_ostream* OS,
-                                       DiagnosticsEngine &Diags,
-                                       const LangOptions &LOpts,
-                                       bool SilenceRewriteMacroWarning) {
-  return new RewriteObjCFragileABI(InFile, OS, Diags, LOpts, SilenceRewriteMacroWarning);
-}
-
-void RewriteObjC::InitializeCommon(ASTContext &context) {
-  Context = &context;
-  SM = &Context->getSourceManager();
-  TUDecl = Context->getTranslationUnitDecl();
-  MsgSendFunctionDecl = 0;
-  MsgSendSuperFunctionDecl = 0;
-  MsgSendStretFunctionDecl = 0;
-  MsgSendSuperStretFunctionDecl = 0;
-  MsgSendFpretFunctionDecl = 0;
-  GetClassFunctionDecl = 0;
-  GetMetaClassFunctionDecl = 0;
-  GetSuperClassFunctionDecl = 0;
-  SelGetUidFunctionDecl = 0;
-  CFStringFunctionDecl = 0;
-  ConstantStringClassReference = 0;
-  NSStringRecord = 0;
-  CurMethodDef = 0;
-  CurFunctionDef = 0;
-  CurFunctionDeclToDeclareForBlock = 0;
-  GlobalVarDecl = 0;
-  SuperStructDecl = 0;
-  ProtocolTypeDecl = 0;
-  ConstantStringDecl = 0;
-  BcLabelCount = 0;
-  SuperConstructorFunctionDecl = 0;
-  NumObjCStringLiterals = 0;
-  PropParentMap = 0;
-  CurrentBody = 0;
-  DisableReplaceStmt = false;
-  objc_impl_method = false;
-
-  // Get the ID and start/end of the main file.
-  MainFileID = SM->getMainFileID();
-  const llvm::MemoryBuffer *MainBuf = SM->getBuffer(MainFileID);
-  MainFileStart = MainBuf->getBufferStart();
-  MainFileEnd = MainBuf->getBufferEnd();
-
-  Rewrite.setSourceMgr(Context->getSourceManager(), Context->getLangOpts());
-}
-
-//===----------------------------------------------------------------------===//
-// Top Level Driver Code
-//===----------------------------------------------------------------------===//
-
-void RewriteObjC::HandleTopLevelSingleDecl(Decl *D) {
-  if (Diags.hasErrorOccurred())
-    return;
-
-  // Two cases: either the decl could be in the main file, or it could be in a
-  // #included file.  If the former, rewrite it now.  If the later, check to see
-  // if we rewrote the #include/#import.
-  SourceLocation Loc = D->getLocation();
-  Loc = SM->getExpansionLoc(Loc);
-
-  // If this is for a builtin, ignore it.
-  if (Loc.isInvalid()) return;
-
-  // Look for built-in declarations that we need to refer during the rewrite.
-  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
-    RewriteFunctionDecl(FD);
-  } else if (VarDecl *FVD = dyn_cast<VarDecl>(D)) {
-    // declared in <Foundation/NSString.h>
-    if (FVD->getName() == "_NSConstantStringClassReference") {
-      ConstantStringClassReference = FVD;
-      return;
-    }
-  } else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
-    if (ID->isThisDeclarationADefinition())
-      RewriteInterfaceDecl(ID);
-  } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(D)) {
-    RewriteCategoryDecl(CD);
-  } else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) {
-    if (PD->isThisDeclarationADefinition())
-      RewriteProtocolDecl(PD);
-  } else if (LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(D)) {
-    // Recurse into linkage specifications
-    for (DeclContext::decl_iterator DI = LSD->decls_begin(),
-                                 DIEnd = LSD->decls_end();
-         DI != DIEnd; ) {
-      if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>((*DI))) {
-        if (!IFace->isThisDeclarationADefinition()) {
-          SmallVector<Decl *, 8> DG;
-          SourceLocation StartLoc = IFace->getLocStart();
-          do {
-            if (isa<ObjCInterfaceDecl>(*DI) &&
-                !cast<ObjCInterfaceDecl>(*DI)->isThisDeclarationADefinition() &&
-                StartLoc == (*DI)->getLocStart())
-              DG.push_back(*DI);
-            else
-              break;
-            
-            ++DI;
-          } while (DI != DIEnd);
-          RewriteForwardClassDecl(DG);
-          continue;
-        }
-      }
-
-      if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>((*DI))) {
-        if (!Proto->isThisDeclarationADefinition()) {
-          SmallVector<Decl *, 8> DG;
-          SourceLocation StartLoc = Proto->getLocStart();
-          do {
-            if (isa<ObjCProtocolDecl>(*DI) &&
-                !cast<ObjCProtocolDecl>(*DI)->isThisDeclarationADefinition() &&
-                StartLoc == (*DI)->getLocStart())
-              DG.push_back(*DI);
-            else
-              break;
-            
-            ++DI;
-          } while (DI != DIEnd);
-          RewriteForwardProtocolDecl(DG);
-          continue;
-        }
-      }
-      
-      HandleTopLevelSingleDecl(*DI);
-      ++DI;
-    }
-  }
-  // If we have a decl in the main file, see if we should rewrite it.
-  if (SM->isWrittenInMainFile(Loc))
-    return HandleDeclInMainFile(D);
-}
-
-//===----------------------------------------------------------------------===//
-// Syntactic (non-AST) Rewriting Code
-//===----------------------------------------------------------------------===//
-
-void RewriteObjC::RewriteInclude() {
-  SourceLocation LocStart = SM->getLocForStartOfFile(MainFileID);
-  StringRef MainBuf = SM->getBufferData(MainFileID);
-  const char *MainBufStart = MainBuf.begin();
-  const char *MainBufEnd = MainBuf.end();
-  size_t ImportLen = strlen("import");
-
-  // Loop over the whole file, looking for includes.
-  for (const char *BufPtr = MainBufStart; BufPtr < MainBufEnd; ++BufPtr) {
-    if (*BufPtr == '#') {
-      if (++BufPtr == MainBufEnd)
-        return;
-      while (*BufPtr == ' ' || *BufPtr == '\t')
-        if (++BufPtr == MainBufEnd)
-          return;
-      if (!strncmp(BufPtr, "import", ImportLen)) {
-        // replace import with include
-        SourceLocation ImportLoc =
-          LocStart.getLocWithOffset(BufPtr-MainBufStart);
-        ReplaceText(ImportLoc, ImportLen, "include");
-        BufPtr += ImportLen;
-      }
-    }
-  }
-}
-
-static std::string getIvarAccessString(ObjCIvarDecl *OID) {
-  const ObjCInterfaceDecl *ClassDecl = OID->getContainingInterface();
-  std::string S;
-  S = "((struct ";
-  S += ClassDecl->getIdentifier()->getName();
-  S += "_IMPL *)self)->";
-  S += OID->getName();
-  return S;
-}
-
-void RewriteObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
-                                          ObjCImplementationDecl *IMD,
-                                          ObjCCategoryImplDecl *CID) {
-  static bool objcGetPropertyDefined = false;
-  static bool objcSetPropertyDefined = false;
-  SourceLocation startLoc = PID->getLocStart();
-  InsertText(startLoc, "// ");
-  const char *startBuf = SM->getCharacterData(startLoc);
-  assert((*startBuf == '@') && "bogus @synthesize location");
-  const char *semiBuf = strchr(startBuf, ';');
-  assert((*semiBuf == ';') && "@synthesize: can't find ';'");
-  SourceLocation onePastSemiLoc =
-    startLoc.getLocWithOffset(semiBuf-startBuf+1);
-
-  if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
-    return; // FIXME: is this correct?
-
-  // Generate the 'getter' function.
-  ObjCPropertyDecl *PD = PID->getPropertyDecl();
-  ObjCIvarDecl *OID = PID->getPropertyIvarDecl();
-
-  if (!OID)
-    return;
-  unsigned Attributes = PD->getPropertyAttributes();
-  if (!PD->getGetterMethodDecl()->isDefined()) {
-    bool GenGetProperty = !(Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) &&
-                          (Attributes & (ObjCPropertyDecl::OBJC_PR_retain | 
-                                         ObjCPropertyDecl::OBJC_PR_copy));
-    std::string Getr;
-    if (GenGetProperty && !objcGetPropertyDefined) {
-      objcGetPropertyDefined = true;
-      // FIXME. Is this attribute correct in all cases?
-      Getr = "\nextern \"C\" __declspec(dllimport) "
-            "id objc_getProperty(id, SEL, long, bool);\n";
-    }
-    RewriteObjCMethodDecl(OID->getContainingInterface(),  
-                          PD->getGetterMethodDecl(), Getr);
-    Getr += "{ ";
-    // Synthesize an explicit cast to gain access to the ivar.
-    // See objc-act.c:objc_synthesize_new_getter() for details.
-    if (GenGetProperty) {
-      // return objc_getProperty(self, _cmd, offsetof(ClassDecl, OID), 1)
-      Getr += "typedef ";
-      const FunctionType *FPRetType = 0;
-      RewriteTypeIntoString(PD->getGetterMethodDecl()->getResultType(), Getr, 
-                            FPRetType);
-      Getr += " _TYPE";
-      if (FPRetType) {
-        Getr += ")"; // close the precedence "scope" for "*".
-      
-        // Now, emit the argument types (if any).
-        if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(FPRetType)){
-          Getr += "(";
-          for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i) {
-            if (i) Getr += ", ";
-            std::string ParamStr = FT->getArgType(i).getAsString(
-                                                          Context->getPrintingPolicy());
-            Getr += ParamStr;
-          }
-          if (FT->isVariadic()) {
-            if (FT->getNumArgs()) Getr += ", ";
-            Getr += "...";
-          }
-          Getr += ")";
-        } else
-          Getr += "()";
-      }
-      Getr += ";\n";
-      Getr += "return (_TYPE)";
-      Getr += "objc_getProperty(self, _cmd, ";
-      RewriteIvarOffsetComputation(OID, Getr);
-      Getr += ", 1)";
-    }
-    else
-      Getr += "return " + getIvarAccessString(OID);
-    Getr += "; }";
-    InsertText(onePastSemiLoc, Getr);
-  }
-  
-  if (PD->isReadOnly() || PD->getSetterMethodDecl()->isDefined())
-    return;
-
-  // Generate the 'setter' function.
-  std::string Setr;
-  bool GenSetProperty = Attributes & (ObjCPropertyDecl::OBJC_PR_retain | 
-                                      ObjCPropertyDecl::OBJC_PR_copy);
-  if (GenSetProperty && !objcSetPropertyDefined) {
-    objcSetPropertyDefined = true;
-    // FIXME. Is this attribute correct in all cases?
-    Setr = "\nextern \"C\" __declspec(dllimport) "
-    "void objc_setProperty (id, SEL, long, id, bool, bool);\n";
-  }
-  
-  RewriteObjCMethodDecl(OID->getContainingInterface(), 
-                        PD->getSetterMethodDecl(), Setr);
-  Setr += "{ ";
-  // Synthesize an explicit cast to initialize the ivar.
-  // See objc-act.c:objc_synthesize_new_setter() for details.
-  if (GenSetProperty) {
-    Setr += "objc_setProperty (self, _cmd, ";
-    RewriteIvarOffsetComputation(OID, Setr);
-    Setr += ", (id)";
-    Setr += PD->getName();
-    Setr += ", ";
-    if (Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic)
-      Setr += "0, ";
-    else
-      Setr += "1, ";
-    if (Attributes & ObjCPropertyDecl::OBJC_PR_copy)
-      Setr += "1)";
-    else
-      Setr += "0)";
-  }
-  else {
-    Setr += getIvarAccessString(OID) + " = ";
-    Setr += PD->getName();
-  }
-  Setr += "; }";
-  InsertText(onePastSemiLoc, Setr);
-}
-
-static void RewriteOneForwardClassDecl(ObjCInterfaceDecl *ForwardDecl,
-                                       std::string &typedefString) {
-  typedefString += "#ifndef _REWRITER_typedef_";
-  typedefString += ForwardDecl->getNameAsString();
-  typedefString += "\n";
-  typedefString += "#define _REWRITER_typedef_";
-  typedefString += ForwardDecl->getNameAsString();
-  typedefString += "\n";
-  typedefString += "typedef struct objc_object ";
-  typedefString += ForwardDecl->getNameAsString();
-  typedefString += ";\n#endif\n";
-}
-
-void RewriteObjC::RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl,
-                                              const std::string &typedefString) {
-    SourceLocation startLoc = ClassDecl->getLocStart();
-    const char *startBuf = SM->getCharacterData(startLoc);
-    const char *semiPtr = strchr(startBuf, ';'); 
-    // Replace the @class with typedefs corresponding to the classes.
-    ReplaceText(startLoc, semiPtr-startBuf+1, typedefString);  
-}
-
-void RewriteObjC::RewriteForwardClassDecl(DeclGroupRef D) {
-  std::string typedefString;
-  for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) {
-    ObjCInterfaceDecl *ForwardDecl = cast<ObjCInterfaceDecl>(*I);
-    if (I == D.begin()) {
-      // Translate to typedef's that forward reference structs with the same name
-      // as the class. As a convenience, we include the original declaration
-      // as a comment.
-      typedefString += "// @class ";
-      typedefString += ForwardDecl->getNameAsString();
-      typedefString += ";\n";
-    }
-    RewriteOneForwardClassDecl(ForwardDecl, typedefString);
-  }
-  DeclGroupRef::iterator I = D.begin();
-  RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(*I), typedefString);
-}
-
-void RewriteObjC::RewriteForwardClassDecl(const SmallVectorImpl<Decl *> &D) {
-  std::string typedefString;
-  for (unsigned i = 0; i < D.size(); i++) {
-    ObjCInterfaceDecl *ForwardDecl = cast<ObjCInterfaceDecl>(D[i]);
-    if (i == 0) {
-      typedefString += "// @class ";
-      typedefString += ForwardDecl->getNameAsString();
-      typedefString += ";\n";
-    }
-    RewriteOneForwardClassDecl(ForwardDecl, typedefString);
-  }
-  RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(D[0]), typedefString);
-}
-
-void RewriteObjC::RewriteMethodDeclaration(ObjCMethodDecl *Method) {
-  // When method is a synthesized one, such as a getter/setter there is
-  // nothing to rewrite.
-  if (Method->isImplicit())
-    return;
-  SourceLocation LocStart = Method->getLocStart();
-  SourceLocation LocEnd = Method->getLocEnd();
-
-  if (SM->getExpansionLineNumber(LocEnd) >
-      SM->getExpansionLineNumber(LocStart)) {
-    InsertText(LocStart, "#if 0\n");
-    ReplaceText(LocEnd, 1, ";\n#endif\n");
-  } else {
-    InsertText(LocStart, "// ");
-  }
-}
-
-void RewriteObjC::RewriteProperty(ObjCPropertyDecl *prop) {
-  SourceLocation Loc = prop->getAtLoc();
-
-  ReplaceText(Loc, 0, "// ");
-  // FIXME: handle properties that are declared across multiple lines.
-}
-
-void RewriteObjC::RewriteCategoryDecl(ObjCCategoryDecl *CatDecl) {
-  SourceLocation LocStart = CatDecl->getLocStart();
-
-  // FIXME: handle category headers that are declared across multiple lines.
-  ReplaceText(LocStart, 0, "// ");
-
-  for (ObjCCategoryDecl::prop_iterator I = CatDecl->prop_begin(),
-       E = CatDecl->prop_end(); I != E; ++I)
-    RewriteProperty(*I);
-  
-  for (ObjCCategoryDecl::instmeth_iterator
-         I = CatDecl->instmeth_begin(), E = CatDecl->instmeth_end();
-       I != E; ++I)
-    RewriteMethodDeclaration(*I);
-  for (ObjCCategoryDecl::classmeth_iterator
-         I = CatDecl->classmeth_begin(), E = CatDecl->classmeth_end();
-       I != E; ++I)
-    RewriteMethodDeclaration(*I);
-
-  // Lastly, comment out the @end.
-  ReplaceText(CatDecl->getAtEndRange().getBegin(), 
-              strlen("@end"), "/* @end */");
-}
-
-void RewriteObjC::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) {
-  SourceLocation LocStart = PDecl->getLocStart();
-  assert(PDecl->isThisDeclarationADefinition());
-  
-  // FIXME: handle protocol headers that are declared across multiple lines.
-  ReplaceText(LocStart, 0, "// ");
-
-  for (ObjCProtocolDecl::instmeth_iterator
-         I = PDecl->instmeth_begin(), E = PDecl->instmeth_end();
-       I != E; ++I)
-    RewriteMethodDeclaration(*I);
-  for (ObjCProtocolDecl::classmeth_iterator
-         I = PDecl->classmeth_begin(), E = PDecl->classmeth_end();
-       I != E; ++I)
-    RewriteMethodDeclaration(*I);
-
-  for (ObjCInterfaceDecl::prop_iterator I = PDecl->prop_begin(),
-       E = PDecl->prop_end(); I != E; ++I)
-    RewriteProperty(*I);
-  
-  // Lastly, comment out the @end.
-  SourceLocation LocEnd = PDecl->getAtEndRange().getBegin();
-  ReplaceText(LocEnd, strlen("@end"), "/* @end */");
-
-  // Must comment out @optional/@required
-  const char *startBuf = SM->getCharacterData(LocStart);
-  const char *endBuf = SM->getCharacterData(LocEnd);
-  for (const char *p = startBuf; p < endBuf; p++) {
-    if (*p == '@' && !strncmp(p+1, "optional", strlen("optional"))) {
-      SourceLocation OptionalLoc = LocStart.getLocWithOffset(p-startBuf);
-      ReplaceText(OptionalLoc, strlen("@optional"), "/* @optional */");
-
-    }
-    else if (*p == '@' && !strncmp(p+1, "required", strlen("required"))) {
-      SourceLocation OptionalLoc = LocStart.getLocWithOffset(p-startBuf);
-      ReplaceText(OptionalLoc, strlen("@required"), "/* @required */");
-
-    }
-  }
-}
-
-void RewriteObjC::RewriteForwardProtocolDecl(DeclGroupRef D) {
-  SourceLocation LocStart = (*D.begin())->getLocStart();
-  if (LocStart.isInvalid())
-    llvm_unreachable("Invalid SourceLocation");
-  // FIXME: handle forward protocol that are declared across multiple lines.
-  ReplaceText(LocStart, 0, "// ");
-}
-
-void 
-RewriteObjC::RewriteForwardProtocolDecl(const SmallVectorImpl<Decl *> &DG) {
-  SourceLocation LocStart = DG[0]->getLocStart();
-  if (LocStart.isInvalid())
-    llvm_unreachable("Invalid SourceLocation");
-  // FIXME: handle forward protocol that are declared across multiple lines.
-  ReplaceText(LocStart, 0, "// ");
-}
-
-void RewriteObjC::RewriteTypeIntoString(QualType T, std::string &ResultStr,
-                                        const FunctionType *&FPRetType) {
-  if (T->isObjCQualifiedIdType())
-    ResultStr += "id";
-  else if (T->isFunctionPointerType() ||
-           T->isBlockPointerType()) {
-    // needs special handling, since pointer-to-functions have special
-    // syntax (where a decaration models use).
-    QualType retType = T;
-    QualType PointeeTy;
-    if (const PointerType* PT = retType->getAs<PointerType>())
-      PointeeTy = PT->getPointeeType();
-    else if (const BlockPointerType *BPT = retType->getAs<BlockPointerType>())
-      PointeeTy = BPT->getPointeeType();
-    if ((FPRetType = PointeeTy->getAs<FunctionType>())) {
-      ResultStr += FPRetType->getResultType().getAsString(
-        Context->getPrintingPolicy());
-      ResultStr += "(*";
-    }
-  } else
-    ResultStr += T.getAsString(Context->getPrintingPolicy());
-}
-
-void RewriteObjC::RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl,
-                                        ObjCMethodDecl *OMD,
-                                        std::string &ResultStr) {
-  //fprintf(stderr,"In RewriteObjCMethodDecl\n");
-  const FunctionType *FPRetType = 0;
-  ResultStr += "\nstatic ";
-  RewriteTypeIntoString(OMD->getResultType(), ResultStr, FPRetType);
-  ResultStr += " ";
-
-  // Unique method name
-  std::string NameStr;
-
-  if (OMD->isInstanceMethod())
-    NameStr += "_I_";
-  else
-    NameStr += "_C_";
-
-  NameStr += IDecl->getNameAsString();
-  NameStr += "_";
-
-  if (ObjCCategoryImplDecl *CID =
-      dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext())) {
-    NameStr += CID->getNameAsString();
-    NameStr += "_";
-  }
-  // Append selector names, replacing ':' with '_'
-  {
-    std::string selString = OMD->getSelector().getAsString();
-    int len = selString.size();
-    for (int i = 0; i < len; i++)
-      if (selString[i] == ':')
-        selString[i] = '_';
-    NameStr += selString;
-  }
-  // Remember this name for metadata emission
-  MethodInternalNames[OMD] = NameStr;
-  ResultStr += NameStr;
-
-  // Rewrite arguments
-  ResultStr += "(";
-
-  // invisible arguments
-  if (OMD->isInstanceMethod()) {
-    QualType selfTy = Context->getObjCInterfaceType(IDecl);
-    selfTy = Context->getPointerType(selfTy);
-    if (!LangOpts.MicrosoftExt) {
-      if (ObjCSynthesizedStructs.count(const_cast<ObjCInterfaceDecl*>(IDecl)))
-        ResultStr += "struct ";
-    }
-    // When rewriting for Microsoft, explicitly omit the structure name.
-    ResultStr += IDecl->getNameAsString();
-    ResultStr += " *";
-  }
-  else
-    ResultStr += Context->getObjCClassType().getAsString(
-      Context->getPrintingPolicy());
-
-  ResultStr += " self, ";
-  ResultStr += Context->getObjCSelType().getAsString(Context->getPrintingPolicy());
-  ResultStr += " _cmd";
-
-  // Method arguments.
-  for (ObjCMethodDecl::param_iterator PI = OMD->param_begin(),
-       E = OMD->param_end(); PI != E; ++PI) {
-    ParmVarDecl *PDecl = *PI;
-    ResultStr += ", ";
-    if (PDecl->getType()->isObjCQualifiedIdType()) {
-      ResultStr += "id ";
-      ResultStr += PDecl->getNameAsString();
-    } else {
-      std::string Name = PDecl->getNameAsString();
-      QualType QT = PDecl->getType();
-      // Make sure we convert "t (^)(...)" to "t (*)(...)".
-      (void)convertBlockPointerToFunctionPointer(QT);
-      QT.getAsStringInternal(Name, Context->getPrintingPolicy());
-      ResultStr += Name;
-    }
-  }
-  if (OMD->isVariadic())
-    ResultStr += ", ...";
-  ResultStr += ") ";
-
-  if (FPRetType) {
-    ResultStr += ")"; // close the precedence "scope" for "*".
-
-    // Now, emit the argument types (if any).
-    if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(FPRetType)) {
-      ResultStr += "(";
-      for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i) {
-        if (i) ResultStr += ", ";
-        std::string ParamStr = FT->getArgType(i).getAsString(
-          Context->getPrintingPolicy());
-        ResultStr += ParamStr;
-      }
-      if (FT->isVariadic()) {
-        if (FT->getNumArgs()) ResultStr += ", ";
-        ResultStr += "...";
-      }
-      ResultStr += ")";
-    } else {
-      ResultStr += "()";
-    }
-  }
-}
-void RewriteObjC::RewriteImplementationDecl(Decl *OID) {
-  ObjCImplementationDecl *IMD = dyn_cast<ObjCImplementationDecl>(OID);
-  ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(OID);
-
-  InsertText(IMD ? IMD->getLocStart() : CID->getLocStart(), "// ");
-
-  for (ObjCCategoryImplDecl::instmeth_iterator
-       I = IMD ? IMD->instmeth_begin() : CID->instmeth_begin(),
-       E = IMD ? IMD->instmeth_end() : CID->instmeth_end();
-       I != E; ++I) {
-    std::string ResultStr;
-    ObjCMethodDecl *OMD = *I;
-    RewriteObjCMethodDecl(OMD->getClassInterface(), OMD, ResultStr);
-    SourceLocation LocStart = OMD->getLocStart();
-    SourceLocation LocEnd = OMD->getCompoundBody()->getLocStart();
-
-    const char *startBuf = SM->getCharacterData(LocStart);
-    const char *endBuf = SM->getCharacterData(LocEnd);
-    ReplaceText(LocStart, endBuf-startBuf, ResultStr);
-  }
-
-  for (ObjCCategoryImplDecl::classmeth_iterator
-       I = IMD ? IMD->classmeth_begin() : CID->classmeth_begin(),
-       E = IMD ? IMD->classmeth_end() : CID->classmeth_end();
-       I != E; ++I) {
-    std::string ResultStr;
-    ObjCMethodDecl *OMD = *I;
-    RewriteObjCMethodDecl(OMD->getClassInterface(), OMD, ResultStr);
-    SourceLocation LocStart = OMD->getLocStart();
-    SourceLocation LocEnd = OMD->getCompoundBody()->getLocStart();
-
-    const char *startBuf = SM->getCharacterData(LocStart);
-    const char *endBuf = SM->getCharacterData(LocEnd);
-    ReplaceText(LocStart, endBuf-startBuf, ResultStr);
-  }
-  for (ObjCCategoryImplDecl::propimpl_iterator
-       I = IMD ? IMD->propimpl_begin() : CID->propimpl_begin(),
-       E = IMD ? IMD->propimpl_end() : CID->propimpl_end();
-       I != E; ++I) {
-    RewritePropertyImplDecl(*I, IMD, CID);
-  }
-
-  InsertText(IMD ? IMD->getLocEnd() : CID->getLocEnd(), "// ");
-}
-
-void RewriteObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) {
-  std::string ResultStr;
-  if (!ObjCForwardDecls.count(ClassDecl->getCanonicalDecl())) {
-    // we haven't seen a forward decl - generate a typedef.
-    ResultStr = "#ifndef _REWRITER_typedef_";
-    ResultStr += ClassDecl->getNameAsString();
-    ResultStr += "\n";
-    ResultStr += "#define _REWRITER_typedef_";
-    ResultStr += ClassDecl->getNameAsString();
-    ResultStr += "\n";
-    ResultStr += "typedef struct objc_object ";
-    ResultStr += ClassDecl->getNameAsString();
-    ResultStr += ";\n#endif\n";
-    // Mark this typedef as having been generated.
-    ObjCForwardDecls.insert(ClassDecl->getCanonicalDecl());
-  }
-  RewriteObjCInternalStruct(ClassDecl, ResultStr);
-
-  for (ObjCInterfaceDecl::prop_iterator I = ClassDecl->prop_begin(),
-         E = ClassDecl->prop_end(); I != E; ++I)
-    RewriteProperty(*I);
-  for (ObjCInterfaceDecl::instmeth_iterator
-         I = ClassDecl->instmeth_begin(), E = ClassDecl->instmeth_end();
-       I != E; ++I)
-    RewriteMethodDeclaration(*I);
-  for (ObjCInterfaceDecl::classmeth_iterator
-         I = ClassDecl->classmeth_begin(), E = ClassDecl->classmeth_end();
-       I != E; ++I)
-    RewriteMethodDeclaration(*I);
-
-  // Lastly, comment out the @end.
-  ReplaceText(ClassDecl->getAtEndRange().getBegin(), strlen("@end"), 
-              "/* @end */");
-}
-
-Stmt *RewriteObjC::RewritePropertyOrImplicitSetter(PseudoObjectExpr *PseudoOp) {
-  SourceRange OldRange = PseudoOp->getSourceRange();
-
-  // We just magically know some things about the structure of this
-  // expression.
-  ObjCMessageExpr *OldMsg =
-    cast<ObjCMessageExpr>(PseudoOp->getSemanticExpr(
-                            PseudoOp->getNumSemanticExprs() - 1));
-
-  // Because the rewriter doesn't allow us to rewrite rewritten code,
-  // we need to suppress rewriting the sub-statements.
-  Expr *Base, *RHS;
-  {
-    DisableReplaceStmtScope S(*this);
-
-    // Rebuild the base expression if we have one.
-    Base = 0;
-    if (OldMsg->getReceiverKind() == ObjCMessageExpr::Instance) {
-      Base = OldMsg->getInstanceReceiver();
-      Base = cast<OpaqueValueExpr>(Base)->getSourceExpr();
-      Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base));
-    }
-
-    // Rebuild the RHS.
-    RHS = cast<BinaryOperator>(PseudoOp->getSyntacticForm())->getRHS();
-    RHS = cast<OpaqueValueExpr>(RHS)->getSourceExpr();
-    RHS = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(RHS));
-  }
-
-  // TODO: avoid this copy.
-  SmallVector<SourceLocation, 1> SelLocs;
-  OldMsg->getSelectorLocs(SelLocs);
-
-  ObjCMessageExpr *NewMsg = 0;
-  switch (OldMsg->getReceiverKind()) {
-  case ObjCMessageExpr::Class:
-    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
-                                     OldMsg->getValueKind(),
-                                     OldMsg->getLeftLoc(),
-                                     OldMsg->getClassReceiverTypeInfo(),
-                                     OldMsg->getSelector(),
-                                     SelLocs,
-                                     OldMsg->getMethodDecl(),
-                                     RHS,
-                                     OldMsg->getRightLoc(),
-                                     OldMsg->isImplicit());
-    break;
-
-  case ObjCMessageExpr::Instance:
-    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
-                                     OldMsg->getValueKind(),
-                                     OldMsg->getLeftLoc(),
-                                     Base,
-                                     OldMsg->getSelector(),
-                                     SelLocs,
-                                     OldMsg->getMethodDecl(),
-                                     RHS,
-                                     OldMsg->getRightLoc(),
-                                     OldMsg->isImplicit());
-    break;
-
-  case ObjCMessageExpr::SuperClass:
-  case ObjCMessageExpr::SuperInstance:
-    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
-                                     OldMsg->getValueKind(),
-                                     OldMsg->getLeftLoc(),
-                                     OldMsg->getSuperLoc(),
-                 OldMsg->getReceiverKind() == ObjCMessageExpr::SuperInstance,
-                                     OldMsg->getSuperType(),
-                                     OldMsg->getSelector(),
-                                     SelLocs,
-                                     OldMsg->getMethodDecl(),
-                                     RHS,
-                                     OldMsg->getRightLoc(),
-                                     OldMsg->isImplicit());
-    break;
-  }
-
-  Stmt *Replacement = SynthMessageExpr(NewMsg);
-  ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
-  return Replacement;
-}
-
-Stmt *RewriteObjC::RewritePropertyOrImplicitGetter(PseudoObjectExpr *PseudoOp) {
-  SourceRange OldRange = PseudoOp->getSourceRange();
-
-  // We just magically know some things about the structure of this
-  // expression.
-  ObjCMessageExpr *OldMsg =
-    cast<ObjCMessageExpr>(PseudoOp->getResultExpr()->IgnoreImplicit());
-
-  // Because the rewriter doesn't allow us to rewrite rewritten code,
-  // we need to suppress rewriting the sub-statements.
-  Expr *Base = 0;
-  {
-    DisableReplaceStmtScope S(*this);
-
-    // Rebuild the base expression if we have one.
-    if (OldMsg->getReceiverKind() == ObjCMessageExpr::Instance) {
-      Base = OldMsg->getInstanceReceiver();
-      Base = cast<OpaqueValueExpr>(Base)->getSourceExpr();
-      Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base));
-    }
-  }
-
-  // Intentionally empty.
-  SmallVector<SourceLocation, 1> SelLocs;
-  SmallVector<Expr*, 1> Args;
-
-  ObjCMessageExpr *NewMsg = 0;
-  switch (OldMsg->getReceiverKind()) {
-  case ObjCMessageExpr::Class:
-    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
-                                     OldMsg->getValueKind(),
-                                     OldMsg->getLeftLoc(),
-                                     OldMsg->getClassReceiverTypeInfo(),
-                                     OldMsg->getSelector(),
-                                     SelLocs,
-                                     OldMsg->getMethodDecl(),
-                                     Args,
-                                     OldMsg->getRightLoc(),
-                                     OldMsg->isImplicit());
-    break;
-
-  case ObjCMessageExpr::Instance:
-    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
-                                     OldMsg->getValueKind(),
-                                     OldMsg->getLeftLoc(),
-                                     Base,
-                                     OldMsg->getSelector(),
-                                     SelLocs,
-                                     OldMsg->getMethodDecl(),
-                                     Args,
-                                     OldMsg->getRightLoc(),
-                                     OldMsg->isImplicit());
-    break;
-
-  case ObjCMessageExpr::SuperClass:
-  case ObjCMessageExpr::SuperInstance:
-    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
-                                     OldMsg->getValueKind(),
-                                     OldMsg->getLeftLoc(),
-                                     OldMsg->getSuperLoc(),
-                 OldMsg->getReceiverKind() == ObjCMessageExpr::SuperInstance,
-                                     OldMsg->getSuperType(),
-                                     OldMsg->getSelector(),
-                                     SelLocs,
-                                     OldMsg->getMethodDecl(),
-                                     Args,
-                                     OldMsg->getRightLoc(),
-                                     OldMsg->isImplicit());
-    break;
-  }
-
-  Stmt *Replacement = SynthMessageExpr(NewMsg);
-  ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
-  return Replacement;
-}
-
-/// SynthCountByEnumWithState - To print:
-/// ((unsigned int (*)
-///  (id, SEL, struct __objcFastEnumerationState *, id *, unsigned int))
-///  (void *)objc_msgSend)((id)l_collection,
-///                        sel_registerName(
-///                          "countByEnumeratingWithState:objects:count:"),
-///                        &enumState,
-///                        (id *)__rw_items, (unsigned int)16)
-///
-void RewriteObjC::SynthCountByEnumWithState(std::string &buf) {
-  buf += "((unsigned int (*) (id, SEL, struct __objcFastEnumerationState *, "
-  "id *, unsigned int))(void *)objc_msgSend)";
-  buf += "\n\t\t";
-  buf += "((id)l_collection,\n\t\t";
-  buf += "sel_registerName(\"countByEnumeratingWithState:objects:count:\"),";
-  buf += "\n\t\t";
-  buf += "&enumState, "
-         "(id *)__rw_items, (unsigned int)16)";
-}
-
-/// RewriteBreakStmt - Rewrite for a break-stmt inside an ObjC2's foreach
-/// statement to exit to its outer synthesized loop.
-///
-Stmt *RewriteObjC::RewriteBreakStmt(BreakStmt *S) {
-  if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
-    return S;
-  // replace break with goto __break_label
-  std::string buf;
-
-  SourceLocation startLoc = S->getLocStart();
-  buf = "goto __break_label_";
-  buf += utostr(ObjCBcLabelNo.back());
-  ReplaceText(startLoc, strlen("break"), buf);
-
-  return 0;
-}
-
-/// RewriteContinueStmt - Rewrite for a continue-stmt inside an ObjC2's foreach
-/// statement to continue with its inner synthesized loop.
-///
-Stmt *RewriteObjC::RewriteContinueStmt(ContinueStmt *S) {
-  if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
-    return S;
-  // replace continue with goto __continue_label
-  std::string buf;
-
-  SourceLocation startLoc = S->getLocStart();
-  buf = "goto __continue_label_";
-  buf += utostr(ObjCBcLabelNo.back());
-  ReplaceText(startLoc, strlen("continue"), buf);
-
-  return 0;
-}
-
-/// RewriteObjCForCollectionStmt - Rewriter for ObjC2's foreach statement.
-///  It rewrites:
-/// for ( type elem in collection) { stmts; }
-
-/// Into:
-/// {
-///   type elem;
-///   struct __objcFastEnumerationState enumState = { 0 };
-///   id __rw_items[16];
-///   id l_collection = (id)collection;
-///   unsigned long limit = [l_collection countByEnumeratingWithState:&enumState
-///                                       objects:__rw_items count:16];
-/// if (limit) {
-///   unsigned long startMutations = *enumState.mutationsPtr;
-///   do {
-///        unsigned long counter = 0;
-///        do {
-///             if (startMutations != *enumState.mutationsPtr)
-///               objc_enumerationMutation(l_collection);
-///             elem = (type)enumState.itemsPtr[counter++];
-///             stmts;
-///             __continue_label: ;
-///        } while (counter < limit);
-///   } while (limit = [l_collection countByEnumeratingWithState:&enumState
-///                                  objects:__rw_items count:16]);
-///   elem = nil;
-///   __break_label: ;
-///  }
-///  else
-///       elem = nil;
-///  }
-///
-Stmt *RewriteObjC::RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
-                                                SourceLocation OrigEnd) {
-  assert(!Stmts.empty() && "ObjCForCollectionStmt - Statement stack empty");
-  assert(isa<ObjCForCollectionStmt>(Stmts.back()) &&
-         "ObjCForCollectionStmt Statement stack mismatch");
-  assert(!ObjCBcLabelNo.empty() &&
-         "ObjCForCollectionStmt - Label No stack empty");
-
-  SourceLocation startLoc = S->getLocStart();
-  const char *startBuf = SM->getCharacterData(startLoc);
-  StringRef elementName;
-  std::string elementTypeAsString;
-  std::string buf;
-  buf = "\n{\n\t";
-  if (DeclStmt *DS = dyn_cast<DeclStmt>(S->getElement())) {
-    // type elem;
-    NamedDecl* D = cast<NamedDecl>(DS->getSingleDecl());
-    QualType ElementType = cast<ValueDecl>(D)->getType();
-    if (ElementType->isObjCQualifiedIdType() ||
-        ElementType->isObjCQualifiedInterfaceType())
-      // Simply use 'id' for all qualified types.
-      elementTypeAsString = "id";
-    else
-      elementTypeAsString = ElementType.getAsString(Context->getPrintingPolicy());
-    buf += elementTypeAsString;
-    buf += " ";
-    elementName = D->getName();
-    buf += elementName;
-    buf += ";\n\t";
-  }
-  else {
-    DeclRefExpr *DR = cast<DeclRefExpr>(S->getElement());
-    elementName = DR->getDecl()->getName();
-    ValueDecl *VD = cast<ValueDecl>(DR->getDecl());
-    if (VD->getType()->isObjCQualifiedIdType() ||
-        VD->getType()->isObjCQualifiedInterfaceType())
-      // Simply use 'id' for all qualified types.
-      elementTypeAsString = "id";
-    else
-      elementTypeAsString = VD->getType().getAsString(Context->getPrintingPolicy());
-  }
-
-  // struct __objcFastEnumerationState enumState = { 0 };
-  buf += "struct __objcFastEnumerationState enumState = { 0 };\n\t";
-  // id __rw_items[16];
-  buf += "id __rw_items[16];\n\t";
-  // id l_collection = (id)
-  buf += "id l_collection = (id)";
-  // Find start location of 'collection' the hard way!
-  const char *startCollectionBuf = startBuf;
-  startCollectionBuf += 3;  // skip 'for'
-  startCollectionBuf = strchr(startCollectionBuf, '(');
-  startCollectionBuf++; // skip '('
-  // find 'in' and skip it.
-  while (*startCollectionBuf != ' ' ||
-         *(startCollectionBuf+1) != 'i' || *(startCollectionBuf+2) != 'n' ||
-         (*(startCollectionBuf+3) != ' ' &&
-          *(startCollectionBuf+3) != '[' && *(startCollectionBuf+3) != '('))
-    startCollectionBuf++;
-  startCollectionBuf += 3;
-
-  // Replace: "for (type element in" with string constructed thus far.
-  ReplaceText(startLoc, startCollectionBuf - startBuf, buf);
-  // Replace ')' in for '(' type elem in collection ')' with ';'
-  SourceLocation rightParenLoc = S->getRParenLoc();
-  const char *rparenBuf = SM->getCharacterData(rightParenLoc);
-  SourceLocation lparenLoc = startLoc.getLocWithOffset(rparenBuf-startBuf);
-  buf = ";\n\t";
-
-  // unsigned long limit = [l_collection countByEnumeratingWithState:&enumState
-  //                                   objects:__rw_items count:16];
-  // which is synthesized into:
-  // unsigned int limit =
-  // ((unsigned int (*)
-  //  (id, SEL, struct __objcFastEnumerationState *, id *, unsigned int))
-  //  (void *)objc_msgSend)((id)l_collection,
-  //                        sel_registerName(
-  //                          "countByEnumeratingWithState:objects:count:"),
-  //                        (struct __objcFastEnumerationState *)&state,
-  //                        (id *)__rw_items, (unsigned int)16);
-  buf += "unsigned long limit =\n\t\t";
-  SynthCountByEnumWithState(buf);
-  buf += ";\n\t";
-  /// if (limit) {
-  ///   unsigned long startMutations = *enumState.mutationsPtr;
-  ///   do {
-  ///        unsigned long counter = 0;
-  ///        do {
-  ///             if (startMutations != *enumState.mutationsPtr)
-  ///               objc_enumerationMutation(l_collection);
-  ///             elem = (type)enumState.itemsPtr[counter++];
-  buf += "if (limit) {\n\t";
-  buf += "unsigned long startMutations = *enumState.mutationsPtr;\n\t";
-  buf += "do {\n\t\t";
-  buf += "unsigned long counter = 0;\n\t\t";
-  buf += "do {\n\t\t\t";
-  buf += "if (startMutations != *enumState.mutationsPtr)\n\t\t\t\t";
-  buf += "objc_enumerationMutation(l_collection);\n\t\t\t";
-  buf += elementName;
-  buf += " = (";
-  buf += elementTypeAsString;
-  buf += ")enumState.itemsPtr[counter++];";
-  // Replace ')' in for '(' type elem in collection ')' with all of these.
-  ReplaceText(lparenLoc, 1, buf);
-
-  ///            __continue_label: ;
-  ///        } while (counter < limit);
-  ///   } while (limit = [l_collection countByEnumeratingWithState:&enumState
-  ///                                  objects:__rw_items count:16]);
-  ///   elem = nil;
-  ///   __break_label: ;
-  ///  }
-  ///  else
-  ///       elem = nil;
-  ///  }
-  ///
-  buf = ";\n\t";
-  buf += "__continue_label_";
-  buf += utostr(ObjCBcLabelNo.back());
-  buf += ": ;";
-  buf += "\n\t\t";
-  buf += "} while (counter < limit);\n\t";
-  buf += "} while (limit = ";
-  SynthCountByEnumWithState(buf);
-  buf += ");\n\t";
-  buf += elementName;
-  buf += " = ((";
-  buf += elementTypeAsString;
-  buf += ")0);\n\t";
-  buf += "__break_label_";
-  buf += utostr(ObjCBcLabelNo.back());
-  buf += ": ;\n\t";
-  buf += "}\n\t";
-  buf += "else\n\t\t";
-  buf += elementName;
-  buf += " = ((";
-  buf += elementTypeAsString;
-  buf += ")0);\n\t";
-  buf += "}\n";
-
-  // Insert all these *after* the statement body.
-  // FIXME: If this should support Obj-C++, support CXXTryStmt
-  if (isa<CompoundStmt>(S->getBody())) {
-    SourceLocation endBodyLoc = OrigEnd.getLocWithOffset(1);
-    InsertText(endBodyLoc, buf);
-  } else {
-    /* Need to treat single statements specially. For example:
-     *
-     *     for (A *a in b) if (stuff()) break;
-     *     for (A *a in b) xxxyy;
-     *
-     * The following code simply scans ahead to the semi to find the actual end.
-     */
-    const char *stmtBuf = SM->getCharacterData(OrigEnd);
-    const char *semiBuf = strchr(stmtBuf, ';');
-    assert(semiBuf && "Can't find ';'");
-    SourceLocation endBodyLoc = OrigEnd.getLocWithOffset(semiBuf-stmtBuf+1);
-    InsertText(endBodyLoc, buf);
-  }
-  Stmts.pop_back();
-  ObjCBcLabelNo.pop_back();
-  return 0;
-}
-
-/// RewriteObjCSynchronizedStmt -
-/// This routine rewrites @synchronized(expr) stmt;
-/// into:
-/// objc_sync_enter(expr);
-/// @try stmt @finally { objc_sync_exit(expr); }
-///
-Stmt *RewriteObjC::RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
-  // Get the start location and compute the semi location.
-  SourceLocation startLoc = S->getLocStart();
-  const char *startBuf = SM->getCharacterData(startLoc);
-
-  assert((*startBuf == '@') && "bogus @synchronized location");
-
-  std::string buf;
-  buf = "objc_sync_enter((id)";
-  const char *lparenBuf = startBuf;
-  while (*lparenBuf != '(') lparenBuf++;
-  ReplaceText(startLoc, lparenBuf-startBuf+1, buf);
-  // We can't use S->getSynchExpr()->getLocEnd() to find the end location, since
-  // the sync expression is typically a message expression that's already
-  // been rewritten! (which implies the SourceLocation's are invalid).
-  SourceLocation endLoc = S->getSynchBody()->getLocStart();
-  const char *endBuf = SM->getCharacterData(endLoc);
-  while (*endBuf != ')') endBuf--;
-  SourceLocation rparenLoc = startLoc.getLocWithOffset(endBuf-startBuf);
-  buf = ");\n";
-  // declare a new scope with two variables, _stack and _rethrow.
-  buf += "/* @try scope begin */ \n{ struct _objc_exception_data {\n";
-  buf += "int buf[18/*32-bit i386*/];\n";
-  buf += "char *pointers[4];} _stack;\n";
-  buf += "id volatile _rethrow = 0;\n";
-  buf += "objc_exception_try_enter(&_stack);\n";
-  buf += "if (!_setjmp(_stack.buf)) /* @try block continue */\n";
-  ReplaceText(rparenLoc, 1, buf);
-  startLoc = S->getSynchBody()->getLocEnd();
-  startBuf = SM->getCharacterData(startLoc);
-
-  assert((*startBuf == '}') && "bogus @synchronized block");
-  SourceLocation lastCurlyLoc = startLoc;
-  buf = "}\nelse {\n";
-  buf += "  _rethrow = objc_exception_extract(&_stack);\n";
-  buf += "}\n";
-  buf += "{ /* implicit finally clause */\n";
-  buf += "  if (!_rethrow) objc_exception_try_exit(&_stack);\n";
-  
-  std::string syncBuf;
-  syncBuf += " objc_sync_exit(";
-
-  Expr *syncExpr = S->getSynchExpr();
-  CastKind CK = syncExpr->getType()->isObjCObjectPointerType()
-                  ? CK_BitCast :
-                syncExpr->getType()->isBlockPointerType()
-                  ? CK_BlockPointerToObjCPointerCast
-                  : CK_CPointerToObjCPointerCast;
-  syncExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
-                                      CK, syncExpr);
-  std::string syncExprBufS;
-  llvm::raw_string_ostream syncExprBuf(syncExprBufS);
-  syncExpr->printPretty(syncExprBuf, 0, PrintingPolicy(LangOpts));
-  syncBuf += syncExprBuf.str();
-  syncBuf += ");";
-  
-  buf += syncBuf;
-  buf += "\n  if (_rethrow) objc_exception_throw(_rethrow);\n";
-  buf += "}\n";
-  buf += "}";
-
-  ReplaceText(lastCurlyLoc, 1, buf);
-
-  bool hasReturns = false;
-  HasReturnStmts(S->getSynchBody(), hasReturns);
-  if (hasReturns)
-    RewriteSyncReturnStmts(S->getSynchBody(), syncBuf);
-
-  return 0;
-}
-
-void RewriteObjC::WarnAboutReturnGotoStmts(Stmt *S)
-{
-  // Perform a bottom up traversal of all children.
-  for (Stmt::child_range CI = S->children(); CI; ++CI)
-    if (*CI)
-      WarnAboutReturnGotoStmts(*CI);
-
-  if (isa<ReturnStmt>(S) || isa<GotoStmt>(S)) {
-    Diags.Report(Context->getFullLoc(S->getLocStart()),
-                 TryFinallyContainsReturnDiag);
-  }
-  return;
-}
-
-void RewriteObjC::HasReturnStmts(Stmt *S, bool &hasReturns) 
-{  
-  // Perform a bottom up traversal of all children.
-  for (Stmt::child_range CI = S->children(); CI; ++CI)
-   if (*CI)
-     HasReturnStmts(*CI, hasReturns);
-
- if (isa<ReturnStmt>(S))
-   hasReturns = true;
- return;
-}
-
-void RewriteObjC::RewriteTryReturnStmts(Stmt *S) {
- // Perform a bottom up traversal of all children.
- for (Stmt::child_range CI = S->children(); CI; ++CI)
-   if (*CI) {
-     RewriteTryReturnStmts(*CI);
-   }
- if (isa<ReturnStmt>(S)) {
-   SourceLocation startLoc = S->getLocStart();
-   const char *startBuf = SM->getCharacterData(startLoc);
-
-   const char *semiBuf = strchr(startBuf, ';');
-   assert((*semiBuf == ';') && "RewriteTryReturnStmts: can't find ';'");
-   SourceLocation onePastSemiLoc = startLoc.getLocWithOffset(semiBuf-startBuf+1);
-
-   std::string buf;
-   buf = "{ objc_exception_try_exit(&_stack); return";
-   
-   ReplaceText(startLoc, 6, buf);
-   InsertText(onePastSemiLoc, "}");
- }
- return;
-}
-
-void RewriteObjC::RewriteSyncReturnStmts(Stmt *S, std::string syncExitBuf) {
-  // Perform a bottom up traversal of all children.
-  for (Stmt::child_range CI = S->children(); CI; ++CI)
-    if (*CI) {
-      RewriteSyncReturnStmts(*CI, syncExitBuf);
-    }
-  if (isa<ReturnStmt>(S)) {
-    SourceLocation startLoc = S->getLocStart();
-    const char *startBuf = SM->getCharacterData(startLoc);
-
-    const char *semiBuf = strchr(startBuf, ';');
-    assert((*semiBuf == ';') && "RewriteSyncReturnStmts: can't find ';'");
-    SourceLocation onePastSemiLoc = startLoc.getLocWithOffset(semiBuf-startBuf+1);
-
-    std::string buf;
-    buf = "{ objc_exception_try_exit(&_stack);";
-    buf += syncExitBuf;
-    buf += " return";
-    
-    ReplaceText(startLoc, 6, buf);
-    InsertText(onePastSemiLoc, "}");
-  }
-  return;
-}
-
-Stmt *RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
-  // Get the start location and compute the semi location.
-  SourceLocation startLoc = S->getLocStart();
-  const char *startBuf = SM->getCharacterData(startLoc);
-
-  assert((*startBuf == '@') && "bogus @try location");
-
-  std::string buf;
-  // declare a new scope with two variables, _stack and _rethrow.
-  buf = "/* @try scope begin */ { struct _objc_exception_data {\n";
-  buf += "int buf[18/*32-bit i386*/];\n";
-  buf += "char *pointers[4];} _stack;\n";
-  buf += "id volatile _rethrow = 0;\n";
-  buf += "objc_exception_try_enter(&_stack);\n";
-  buf += "if (!_setjmp(_stack.buf)) /* @try block continue */\n";
-
-  ReplaceText(startLoc, 4, buf);
-
-  startLoc = S->getTryBody()->getLocEnd();
-  startBuf = SM->getCharacterData(startLoc);
-
-  assert((*startBuf == '}') && "bogus @try block");
-
-  SourceLocation lastCurlyLoc = startLoc;
-  if (S->getNumCatchStmts()) {
-    startLoc = startLoc.getLocWithOffset(1);
-    buf = " /* @catch begin */ else {\n";
-    buf += " id _caught = objc_exception_extract(&_stack);\n";
-    buf += " objc_exception_try_enter (&_stack);\n";
-    buf += " if (_setjmp(_stack.buf))\n";
-    buf += "   _rethrow = objc_exception_extract(&_stack);\n";
-    buf += " else { /* @catch continue */";
-
-    InsertText(startLoc, buf);
-  } else { /* no catch list */
-    buf = "}\nelse {\n";
-    buf += "  _rethrow = objc_exception_extract(&_stack);\n";
-    buf += "}";
-    ReplaceText(lastCurlyLoc, 1, buf);
-  }
-  Stmt *lastCatchBody = 0;
-  for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
-    ObjCAtCatchStmt *Catch = S->getCatchStmt(I);
-    VarDecl *catchDecl = Catch->getCatchParamDecl();
-
-    if (I == 0)
-      buf = "if ("; // we are generating code for the first catch clause
-    else
-      buf = "else if (";
-    startLoc = Catch->getLocStart();
-    startBuf = SM->getCharacterData(startLoc);
-
-    assert((*startBuf == '@') && "bogus @catch location");
-
-    const char *lParenLoc = strchr(startBuf, '(');
-
-    if (Catch->hasEllipsis()) {
-      // Now rewrite the body...
-      lastCatchBody = Catch->getCatchBody();
-      SourceLocation bodyLoc = lastCatchBody->getLocStart();
-      const char *bodyBuf = SM->getCharacterData(bodyLoc);
-      assert(*SM->getCharacterData(Catch->getRParenLoc()) == ')' &&
-             "bogus @catch paren location");
-      assert((*bodyBuf == '{') && "bogus @catch body location");
-
-      buf += "1) { id _tmp = _caught;";
-      Rewrite.ReplaceText(startLoc, bodyBuf-startBuf+1, buf);
-    } else if (catchDecl) {
-      QualType t = catchDecl->getType();
-      if (t == Context->getObjCIdType()) {
-        buf += "1) { ";
-        ReplaceText(startLoc, lParenLoc-startBuf+1, buf);
-      } else if (const ObjCObjectPointerType *Ptr =
-                   t->getAs<ObjCObjectPointerType>()) {
-        // Should be a pointer to a class.
-        ObjCInterfaceDecl *IDecl = Ptr->getObjectType()->getInterface();
-        if (IDecl) {
-          buf += "objc_exception_match((struct objc_class *)objc_getClass(\"";
-          buf += IDecl->getNameAsString();
-          buf += "\"), (struct objc_object *)_caught)) { ";
-          ReplaceText(startLoc, lParenLoc-startBuf+1, buf);
-        }
-      }
-      // Now rewrite the body...
-      lastCatchBody = Catch->getCatchBody();
-      SourceLocation rParenLoc = Catch->getRParenLoc();
-      SourceLocation bodyLoc = lastCatchBody->getLocStart();
-      const char *bodyBuf = SM->getCharacterData(bodyLoc);
-      const char *rParenBuf = SM->getCharacterData(rParenLoc);
-      assert((*rParenBuf == ')') && "bogus @catch paren location");
-      assert((*bodyBuf == '{') && "bogus @catch body location");
-
-      // Here we replace ") {" with "= _caught;" (which initializes and
-      // declares the @catch parameter).
-      ReplaceText(rParenLoc, bodyBuf-rParenBuf+1, " = _caught;");
-    } else {
-      llvm_unreachable("@catch rewrite bug");
-    }
-  }
-  // Complete the catch list...
-  if (lastCatchBody) {
-    SourceLocation bodyLoc = lastCatchBody->getLocEnd();
-    assert(*SM->getCharacterData(bodyLoc) == '}' &&
-           "bogus @catch body location");
-
-    // Insert the last (implicit) else clause *before* the right curly brace.
-    bodyLoc = bodyLoc.getLocWithOffset(-1);
-    buf = "} /* last catch end */\n";
-    buf += "else {\n";
-    buf += " _rethrow = _caught;\n";
-    buf += " objc_exception_try_exit(&_stack);\n";
-    buf += "} } /* @catch end */\n";
-    if (!S->getFinallyStmt())
-      buf += "}\n";
-    InsertText(bodyLoc, buf);
-
-    // Set lastCurlyLoc
-    lastCurlyLoc = lastCatchBody->getLocEnd();
-  }
-  if (ObjCAtFinallyStmt *finalStmt = S->getFinallyStmt()) {
-    startLoc = finalStmt->getLocStart();
-    startBuf = SM->getCharacterData(startLoc);
-    assert((*startBuf == '@') && "bogus @finally start");
-
-    ReplaceText(startLoc, 8, "/* @finally */");
-
-    Stmt *body = finalStmt->getFinallyBody();
-    SourceLocation startLoc = body->getLocStart();
-    SourceLocation endLoc = body->getLocEnd();
-    assert(*SM->getCharacterData(startLoc) == '{' &&
-           "bogus @finally body location");
-    assert(*SM->getCharacterData(endLoc) == '}' &&
-           "bogus @finally body location");
-
-    startLoc = startLoc.getLocWithOffset(1);
-    InsertText(startLoc, " if (!_rethrow) objc_exception_try_exit(&_stack);\n");
-    endLoc = endLoc.getLocWithOffset(-1);
-    InsertText(endLoc, " if (_rethrow) objc_exception_throw(_rethrow);\n");
-
-    // Set lastCurlyLoc
-    lastCurlyLoc = body->getLocEnd();
-
-    // Now check for any return/continue/go statements within the @try.
-    WarnAboutReturnGotoStmts(S->getTryBody());
-  } else { /* no finally clause - make sure we synthesize an implicit one */
-    buf = "{ /* implicit finally clause */\n";
-    buf += " if (!_rethrow) objc_exception_try_exit(&_stack);\n";
-    buf += " if (_rethrow) objc_exception_throw(_rethrow);\n";
-    buf += "}";
-    ReplaceText(lastCurlyLoc, 1, buf);
-    
-    // Now check for any return/continue/go statements within the @try.
-    // The implicit finally clause won't called if the @try contains any
-    // jump statements.
-    bool hasReturns = false;
-    HasReturnStmts(S->getTryBody(), hasReturns);
-    if (hasReturns)
-      RewriteTryReturnStmts(S->getTryBody());
-  }
-  // Now emit the final closing curly brace...
-  lastCurlyLoc = lastCurlyLoc.getLocWithOffset(1);
-  InsertText(lastCurlyLoc, " } /* @try scope end */\n");
-  return 0;
-}
-
-// This can't be done with ReplaceStmt(S, ThrowExpr), since
-// the throw expression is typically a message expression that's already
-// been rewritten! (which implies the SourceLocation's are invalid).
-Stmt *RewriteObjC::RewriteObjCThrowStmt(ObjCAtThrowStmt *S) {
-  // Get the start location and compute the semi location.
-  SourceLocation startLoc = S->getLocStart();
-  const char *startBuf = SM->getCharacterData(startLoc);
-
-  assert((*startBuf == '@') && "bogus @throw location");
-
-  std::string buf;
-  /* void objc_exception_throw(id) __attribute__((noreturn)); */
-  if (S->getThrowExpr())
-    buf = "objc_exception_throw(";
-  else // add an implicit argument
-    buf = "objc_exception_throw(_caught";
-
-  // handle "@  throw" correctly.
-  const char *wBuf = strchr(startBuf, 'w');
-  assert((*wBuf == 'w') && "@throw: can't find 'w'");
-  ReplaceText(startLoc, wBuf-startBuf+1, buf);
-
-  const char *semiBuf = strchr(startBuf, ';');
-  assert((*semiBuf == ';') && "@throw: can't find ';'");
-  SourceLocation semiLoc = startLoc.getLocWithOffset(semiBuf-startBuf);
-  ReplaceText(semiLoc, 1, ");");
-  return 0;
-}
-
-Stmt *RewriteObjC::RewriteAtEncode(ObjCEncodeExpr *Exp) {
-  // Create a new string expression.
-  QualType StrType = Context->getPointerType(Context->CharTy);
-  std::string StrEncoding;
-  Context->getObjCEncodingForType(Exp->getEncodedType(), StrEncoding);
-  Expr *Replacement = StringLiteral::Create(*Context, StrEncoding,
-                                            StringLiteral::Ascii, false,
-                                            StrType, SourceLocation());
-  ReplaceStmt(Exp, Replacement);
-
-  // Replace this subexpr in the parent.
-  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
-  return Replacement;
-}
-
-Stmt *RewriteObjC::RewriteAtSelector(ObjCSelectorExpr *Exp) {
-  if (!SelGetUidFunctionDecl)
-    SynthSelGetUidFunctionDecl();
-  assert(SelGetUidFunctionDecl && "Can't find sel_registerName() decl");
-  // Create a call to sel_registerName("selName").
-  SmallVector<Expr*, 8> SelExprs;
-  QualType argType = Context->getPointerType(Context->CharTy);
-  SelExprs.push_back(StringLiteral::Create(*Context,
-                                           Exp->getSelector().getAsString(),
-                                           StringLiteral::Ascii, false,
-                                           argType, SourceLocation()));
-  CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
-                                                 &SelExprs[0], SelExprs.size());
-  ReplaceStmt(Exp, SelExp);
-  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
-  return SelExp;
-}
-
-CallExpr *RewriteObjC::SynthesizeCallToFunctionDecl(
-  FunctionDecl *FD, Expr **args, unsigned nargs, SourceLocation StartLoc,
-                                                    SourceLocation EndLoc) {
-  // Get the type, we will need to reference it in a couple spots.
-  QualType msgSendType = FD->getType();
-
-  // Create a reference to the objc_msgSend() declaration.
-  DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, false, msgSendType,
-                                               VK_LValue, SourceLocation());
-
-  // Now, we cast the reference to a pointer to the objc_msgSend type.
-  QualType pToFunc = Context->getPointerType(msgSendType);
-  ImplicitCastExpr *ICE = 
-    ImplicitCastExpr::Create(*Context, pToFunc, CK_FunctionToPointerDecay,
-                             DRE, 0, VK_RValue);
-
-  const FunctionType *FT = msgSendType->getAs<FunctionType>();
-
-  CallExpr *Exp =  
-    new (Context) CallExpr(*Context, ICE, llvm::makeArrayRef(args, nargs),
-                           FT->getCallResultType(*Context),
-                           VK_RValue, EndLoc);
-  return Exp;
-}
-
-static bool scanForProtocolRefs(const char *startBuf, const char *endBuf,
-                                const char *&startRef, const char *&endRef) {
-  while (startBuf < endBuf) {
-    if (*startBuf == '<')
-      startRef = startBuf; // mark the start.
-    if (*startBuf == '>') {
-      if (startRef && *startRef == '<') {
-        endRef = startBuf; // mark the end.
-        return true;
-      }
-      return false;
-    }
-    startBuf++;
-  }
-  return false;
-}
-
-static void scanToNextArgument(const char *&argRef) {
-  int angle = 0;
-  while (*argRef != ')' && (*argRef != ',' || angle > 0)) {
-    if (*argRef == '<')
-      angle++;
-    else if (*argRef == '>')
-      angle--;
-    argRef++;
-  }
-  assert(angle == 0 && "scanToNextArgument - bad protocol type syntax");
-}
-
-bool RewriteObjC::needToScanForQualifiers(QualType T) {
-  if (T->isObjCQualifiedIdType())
-    return true;
-  if (const PointerType *PT = T->getAs<PointerType>()) {
-    if (PT->getPointeeType()->isObjCQualifiedIdType())
-      return true;
-  }
-  if (T->isObjCObjectPointerType()) {
-    T = T->getPointeeType();
-    return T->isObjCQualifiedInterfaceType();
-  }
-  if (T->isArrayType()) {
-    QualType ElemTy = Context->getBaseElementType(T);
-    return needToScanForQualifiers(ElemTy);
-  }
-  return false;
-}
-
-void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Expr *E) {
-  QualType Type = E->getType();
-  if (needToScanForQualifiers(Type)) {
-    SourceLocation Loc, EndLoc;
-
-    if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E)) {
-      Loc = ECE->getLParenLoc();
-      EndLoc = ECE->getRParenLoc();
-    } else {
-      Loc = E->getLocStart();
-      EndLoc = E->getLocEnd();
-    }
-    // This will defend against trying to rewrite synthesized expressions.
-    if (Loc.isInvalid() || EndLoc.isInvalid())
-      return;
-
-    const char *startBuf = SM->getCharacterData(Loc);
-    const char *endBuf = SM->getCharacterData(EndLoc);
-    const char *startRef = 0, *endRef = 0;
-    if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
-      // Get the locations of the startRef, endRef.
-      SourceLocation LessLoc = Loc.getLocWithOffset(startRef-startBuf);
-      SourceLocation GreaterLoc = Loc.getLocWithOffset(endRef-startBuf+1);
-      // Comment out the protocol references.
-      InsertText(LessLoc, "/*");
-      InsertText(GreaterLoc, "*/");
-    }
-  }
-}
-
-void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Decl *Dcl) {
-  SourceLocation Loc;
-  QualType Type;
-  const FunctionProtoType *proto = 0;
-  if (VarDecl *VD = dyn_cast<VarDecl>(Dcl)) {
-    Loc = VD->getLocation();
-    Type = VD->getType();
-  }
-  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(Dcl)) {
-    Loc = FD->getLocation();
-    // Check for ObjC 'id' and class types that have been adorned with protocol
-    // information (id<p>, C<p>*). The protocol references need to be rewritten!
-    const FunctionType *funcType = FD->getType()->getAs<FunctionType>();
-    assert(funcType && "missing function type");
-    proto = dyn_cast<FunctionProtoType>(funcType);
-    if (!proto)
-      return;
-    Type = proto->getResultType();
-  }
-  else if (FieldDecl *FD = dyn_cast<FieldDecl>(Dcl)) {
-    Loc = FD->getLocation();
-    Type = FD->getType();
-  }
-  else
-    return;
-
-  if (needToScanForQualifiers(Type)) {
-    // Since types are unique, we need to scan the buffer.
-
-    const char *endBuf = SM->getCharacterData(Loc);
-    const char *startBuf = endBuf;
-    while (*startBuf != ';' && *startBuf != '<' && startBuf != MainFileStart)
-      startBuf--; // scan backward (from the decl location) for return type.
-    const char *startRef = 0, *endRef = 0;
-    if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
-      // Get the locations of the startRef, endRef.
-      SourceLocation LessLoc = Loc.getLocWithOffset(startRef-endBuf);
-      SourceLocation GreaterLoc = Loc.getLocWithOffset(endRef-endBuf+1);
-      // Comment out the protocol references.
-      InsertText(LessLoc, "/*");
-      InsertText(GreaterLoc, "*/");
-    }
-  }
-  if (!proto)
-      return; // most likely, was a variable
-  // Now check arguments.
-  const char *startBuf = SM->getCharacterData(Loc);
-  const char *startFuncBuf = startBuf;
-  for (unsigned i = 0; i < proto->getNumArgs(); i++) {
-    if (needToScanForQualifiers(proto->getArgType(i))) {
-      // Since types are unique, we need to scan the buffer.
-
-      const char *endBuf = startBuf;
-      // scan forward (from the decl location) for argument types.
-      scanToNextArgument(endBuf);
-      const char *startRef = 0, *endRef = 0;
-      if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
-        // Get the locations of the startRef, endRef.
-        SourceLocation LessLoc =
-          Loc.getLocWithOffset(startRef-startFuncBuf);
-        SourceLocation GreaterLoc =
-          Loc.getLocWithOffset(endRef-startFuncBuf+1);
-        // Comment out the protocol references.
-        InsertText(LessLoc, "/*");
-        InsertText(GreaterLoc, "*/");
-      }
-      startBuf = ++endBuf;
-    }
-    else {
-      // If the function name is derived from a macro expansion, then the
-      // argument buffer will not follow the name. Need to speak with Chris.
-      while (*startBuf && *startBuf != ')' && *startBuf != ',')
-        startBuf++; // scan forward (from the decl location) for argument types.
-      startBuf++;
-    }
-  }
-}
-
-void RewriteObjC::RewriteTypeOfDecl(VarDecl *ND) {
-  QualType QT = ND->getType();
-  const Type* TypePtr = QT->getAs<Type>();
-  if (!isa<TypeOfExprType>(TypePtr))
-    return;
-  while (isa<TypeOfExprType>(TypePtr)) {
-    const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
-    QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType();
-    TypePtr = QT->getAs<Type>();
-  }
-  // FIXME. This will not work for multiple declarators; as in:
-  // __typeof__(a) b,c,d;
-  std::string TypeAsString(QT.getAsString(Context->getPrintingPolicy()));
-  SourceLocation DeclLoc = ND->getTypeSpecStartLoc();
-  const char *startBuf = SM->getCharacterData(DeclLoc);
-  if (ND->getInit()) {
-    std::string Name(ND->getNameAsString());
-    TypeAsString += " " + Name + " = ";
-    Expr *E = ND->getInit();
-    SourceLocation startLoc;
-    if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E))
-      startLoc = ECE->getLParenLoc();
-    else
-      startLoc = E->getLocStart();
-    startLoc = SM->getExpansionLoc(startLoc);
-    const char *endBuf = SM->getCharacterData(startLoc);
-    ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
-  }
-  else {
-    SourceLocation X = ND->getLocEnd();
-    X = SM->getExpansionLoc(X);
-    const char *endBuf = SM->getCharacterData(X);
-    ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
-  }
-}
-
-// SynthSelGetUidFunctionDecl - SEL sel_registerName(const char *str);
-void RewriteObjC::SynthSelGetUidFunctionDecl() {
-  IdentifierInfo *SelGetUidIdent = &Context->Idents.get("sel_registerName");
-  SmallVector<QualType, 16> ArgTys;
-  ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
-  QualType getFuncType =
-    getSimpleFunctionType(Context->getObjCSelType(), ArgTys);
-  SelGetUidFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
-                                               SourceLocation(),
-                                               SourceLocation(),
-                                               SelGetUidIdent, getFuncType, 0,
-                                               SC_Extern);
-}
-
-void RewriteObjC::RewriteFunctionDecl(FunctionDecl *FD) {
-  // declared in <objc/objc.h>
-  if (FD->getIdentifier() &&
-      FD->getName() == "sel_registerName") {
-    SelGetUidFunctionDecl = FD;
-    return;
-  }
-  RewriteObjCQualifiedInterfaceTypes(FD);
-}
-
-void RewriteObjC::RewriteBlockPointerType(std::string& Str, QualType Type) {
-  std::string TypeString(Type.getAsString(Context->getPrintingPolicy()));
-  const char *argPtr = TypeString.c_str();
-  if (!strchr(argPtr, '^')) {
-    Str += TypeString;
-    return;
-  }
-  while (*argPtr) {
-    Str += (*argPtr == '^' ? '*' : *argPtr);
-    argPtr++;
-  }
-}
-
-// FIXME. Consolidate this routine with RewriteBlockPointerType.
-void RewriteObjC::RewriteBlockPointerTypeVariable(std::string& Str,
-                                                  ValueDecl *VD) {
-  QualType Type = VD->getType();
-  std::string TypeString(Type.getAsString(Context->getPrintingPolicy()));
-  const char *argPtr = TypeString.c_str();
-  int paren = 0;
-  while (*argPtr) {
-    switch (*argPtr) {
-      case '(':
-        Str += *argPtr;
-        paren++;
-        break;
-      case ')':
-        Str += *argPtr;
-        paren--;
-        break;
-      case '^':
-        Str += '*';
-        if (paren == 1)
-          Str += VD->getNameAsString();
-        break;
-      default:
-        Str += *argPtr;
-        break;
-    }
-    argPtr++;
-  }
-}
-
-
-void RewriteObjC::RewriteBlockLiteralFunctionDecl(FunctionDecl *FD) {
-  SourceLocation FunLocStart = FD->getTypeSpecStartLoc();
-  const FunctionType *funcType = FD->getType()->getAs<FunctionType>();
-  const FunctionProtoType *proto = dyn_cast<FunctionProtoType>(funcType);
-  if (!proto)
-    return;
-  QualType Type = proto->getResultType();
-  std::string FdStr = Type.getAsString(Context->getPrintingPolicy());
-  FdStr += " ";
-  FdStr += FD->getName();
-  FdStr +=  "(";
-  unsigned numArgs = proto->getNumArgs();
-  for (unsigned i = 0; i < numArgs; i++) {
-    QualType ArgType = proto->getArgType(i);
-    RewriteBlockPointerType(FdStr, ArgType);
-    if (i+1 < numArgs)
-      FdStr += ", ";
-  }
-  FdStr +=  ");\n";
-  InsertText(FunLocStart, FdStr);
-  CurFunctionDeclToDeclareForBlock = 0;
-}
-
-// SynthSuperConstructorFunctionDecl - id objc_super(id obj, id super);
-void RewriteObjC::SynthSuperConstructorFunctionDecl() {
-  if (SuperConstructorFunctionDecl)
-    return;
-  IdentifierInfo *msgSendIdent = &Context->Idents.get("__rw_objc_super");
-  SmallVector<QualType, 16> ArgTys;
-  QualType argT = Context->getObjCIdType();
-  assert(!argT.isNull() && "Can't find 'id' type");
-  ArgTys.push_back(argT);
-  ArgTys.push_back(argT);
-  QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
-                                               ArgTys);
-  SuperConstructorFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
-                                                     SourceLocation(),
-                                                     SourceLocation(),
-                                                     msgSendIdent, msgSendType,
-                                                     0, SC_Extern);
-}
-
-// SynthMsgSendFunctionDecl - id objc_msgSend(id self, SEL op, ...);
-void RewriteObjC::SynthMsgSendFunctionDecl() {
-  IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend");
-  SmallVector<QualType, 16> ArgTys;
-  QualType argT = Context->getObjCIdType();
-  assert(!argT.isNull() && "Can't find 'id' type");
-  ArgTys.push_back(argT);
-  argT = Context->getObjCSelType();
-  assert(!argT.isNull() && "Can't find 'SEL' type");
-  ArgTys.push_back(argT);
-  QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
-                                               ArgTys, /*isVariadic=*/true);
-  MsgSendFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
-                                             SourceLocation(),
-                                             SourceLocation(),
-                                             msgSendIdent, msgSendType, 0,
-                                             SC_Extern);
-}
-
-// SynthMsgSendSuperFunctionDecl - id objc_msgSendSuper(struct objc_super *, SEL op, ...);
-void RewriteObjC::SynthMsgSendSuperFunctionDecl() {
-  IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSendSuper");
-  SmallVector<QualType, 16> ArgTys;
-  RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
-                                      SourceLocation(), SourceLocation(),
-                                      &Context->Idents.get("objc_super"));
-  QualType argT = Context->getPointerType(Context->getTagDeclType(RD));
-  assert(!argT.isNull() && "Can't build 'struct objc_super *' type");
-  ArgTys.push_back(argT);
-  argT = Context->getObjCSelType();
-  assert(!argT.isNull() && "Can't find 'SEL' type");
-  ArgTys.push_back(argT);
-  QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
-                                               ArgTys, /*isVariadic=*/true);
-  MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
-                                                  SourceLocation(),
-                                                  SourceLocation(),
-                                                  msgSendIdent, msgSendType, 0,
-                                                  SC_Extern);
-}
-
-// SynthMsgSendStretFunctionDecl - id objc_msgSend_stret(id self, SEL op, ...);
-void RewriteObjC::SynthMsgSendStretFunctionDecl() {
-  IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_stret");
-  SmallVector<QualType, 16> ArgTys;
-  QualType argT = Context->getObjCIdType();
-  assert(!argT.isNull() && "Can't find 'id' type");
-  ArgTys.push_back(argT);
-  argT = Context->getObjCSelType();
-  assert(!argT.isNull() && "Can't find 'SEL' type");
-  ArgTys.push_back(argT);
-  QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
-                                               ArgTys, /*isVariadic=*/true);
-  MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
-                                                  SourceLocation(),
-                                                  SourceLocation(),
-                                                  msgSendIdent, msgSendType, 0,
-                                                  SC_Extern);
-}
-
-// SynthMsgSendSuperStretFunctionDecl -
-// id objc_msgSendSuper_stret(struct objc_super *, SEL op, ...);
-void RewriteObjC::SynthMsgSendSuperStretFunctionDecl() {
-  IdentifierInfo *msgSendIdent =
-    &Context->Idents.get("objc_msgSendSuper_stret");
-  SmallVector<QualType, 16> ArgTys;
-  RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
-                                      SourceLocation(), SourceLocation(),
-                                      &Context->Idents.get("objc_super"));
-  QualType argT = Context->getPointerType(Context->getTagDeclType(RD));
-  assert(!argT.isNull() && "Can't build 'struct objc_super *' type");
-  ArgTys.push_back(argT);
-  argT = Context->getObjCSelType();
-  assert(!argT.isNull() && "Can't find 'SEL' type");
-  ArgTys.push_back(argT);
-  QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
-                                               ArgTys, /*isVariadic=*/true);
-  MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
-                                                       SourceLocation(),
-                                                       SourceLocation(),
-                                                       msgSendIdent,
-                                                       msgSendType, 0,
-                                                       SC_Extern);
-}
-
-// SynthMsgSendFpretFunctionDecl - double objc_msgSend_fpret(id self, SEL op, ...);
-void RewriteObjC::SynthMsgSendFpretFunctionDecl() {
-  IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_fpret");
-  SmallVector<QualType, 16> ArgTys;
-  QualType argT = Context->getObjCIdType();
-  assert(!argT.isNull() && "Can't find 'id' type");
-  ArgTys.push_back(argT);
-  argT = Context->getObjCSelType();
-  assert(!argT.isNull() && "Can't find 'SEL' type");
-  ArgTys.push_back(argT);
-  QualType msgSendType = getSimpleFunctionType(Context->DoubleTy,
-                                               ArgTys, /*isVariadic=*/true);
-  MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
-                                                  SourceLocation(),
-                                                  SourceLocation(),
-                                                  msgSendIdent, msgSendType, 0,
-                                                  SC_Extern);
-}
-
-// SynthGetClassFunctionDecl - id objc_getClass(const char *name);
-void RewriteObjC::SynthGetClassFunctionDecl() {
-  IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getClass");
-  SmallVector<QualType, 16> ArgTys;
-  ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
-  QualType getClassType = getSimpleFunctionType(Context->getObjCIdType(),
-                                                ArgTys);
-  GetClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
-                                              SourceLocation(),
-                                              SourceLocation(),
-                                              getClassIdent, getClassType, 0,
-                                              SC_Extern);
-}
-
-// SynthGetSuperClassFunctionDecl - Class class_getSuperclass(Class cls);
-void RewriteObjC::SynthGetSuperClassFunctionDecl() {
-  IdentifierInfo *getSuperClassIdent = 
-    &Context->Idents.get("class_getSuperclass");
-  SmallVector<QualType, 16> ArgTys;
-  ArgTys.push_back(Context->getObjCClassType());
-  QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(),
-                                                ArgTys);
-  GetSuperClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
-                                                   SourceLocation(),
-                                                   SourceLocation(),
-                                                   getSuperClassIdent,
-                                                   getClassType, 0,
-                                                   SC_Extern);
-}
-
-// SynthGetMetaClassFunctionDecl - id objc_getMetaClass(const char *name);
-void RewriteObjC::SynthGetMetaClassFunctionDecl() {
-  IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getMetaClass");
-  SmallVector<QualType, 16> ArgTys;
-  ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
-  QualType getClassType = getSimpleFunctionType(Context->getObjCIdType(),
-                                                ArgTys);
-  GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
-                                                  SourceLocation(),
-                                                  SourceLocation(),
-                                                  getClassIdent, getClassType,
-                                                  0, SC_Extern);
-}
-
-Stmt *RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) {
-  QualType strType = getConstantStringStructType();
-
-  std::string S = "__NSConstantStringImpl_";
-
-  std::string tmpName = InFileName;
-  unsigned i;
-  for (i=0; i < tmpName.length(); i++) {
-    char c = tmpName.at(i);
-    // replace any non alphanumeric characters with '_'.
-    if (!isAlphanumeric(c))
-      tmpName[i] = '_';
-  }
-  S += tmpName;
-  S += "_";
-  S += utostr(NumObjCStringLiterals++);
-
-  Preamble += "static __NSConstantStringImpl " + S;
-  Preamble += " __attribute__ ((section (\"__DATA, __cfstring\"))) = {__CFConstantStringClassReference,";
-  Preamble += "0x000007c8,"; // utf8_str
-  // The pretty printer for StringLiteral handles escape characters properly.
-  std::string prettyBufS;
-  llvm::raw_string_ostream prettyBuf(prettyBufS);
-  Exp->getString()->printPretty(prettyBuf, 0, PrintingPolicy(LangOpts));
-  Preamble += prettyBuf.str();
-  Preamble += ",";
-  Preamble += utostr(Exp->getString()->getByteLength()) + "};\n";
-
-  VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
-                                   SourceLocation(), &Context->Idents.get(S),
-                                   strType, 0, SC_Static);
-  DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, false, strType, VK_LValue,
-                                               SourceLocation());
-  Expr *Unop = new (Context) UnaryOperator(DRE, UO_AddrOf,
-                                 Context->getPointerType(DRE->getType()),
-                                           VK_RValue, OK_Ordinary,
-                                           SourceLocation());
-  // cast to NSConstantString *
-  CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Exp->getType(),
-                                            CK_CPointerToObjCPointerCast, Unop);
-  ReplaceStmt(Exp, cast);
-  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
-  return cast;
-}
-
-// struct objc_super { struct objc_object *receiver; struct objc_class *super; };
-QualType RewriteObjC::getSuperStructType() {
-  if (!SuperStructDecl) {
-    SuperStructDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
-                                         SourceLocation(), SourceLocation(),
-                                         &Context->Idents.get("objc_super"));
-    QualType FieldTypes[2];
-
-    // struct objc_object *receiver;
-    FieldTypes[0] = Context->getObjCIdType();
-    // struct objc_class *super;
-    FieldTypes[1] = Context->getObjCClassType();
-
-    // Create fields
-    for (unsigned i = 0; i < 2; ++i) {
-      SuperStructDecl->addDecl(FieldDecl::Create(*Context, SuperStructDecl,
-                                                 SourceLocation(),
-                                                 SourceLocation(), 0,
-                                                 FieldTypes[i], 0,
-                                                 /*BitWidth=*/0,
-                                                 /*Mutable=*/false,
-                                                 ICIS_NoInit));
-    }
-
-    SuperStructDecl->completeDefinition();
-  }
-  return Context->getTagDeclType(SuperStructDecl);
-}
-
-QualType RewriteObjC::getConstantStringStructType() {
-  if (!ConstantStringDecl) {
-    ConstantStringDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
-                                            SourceLocation(), SourceLocation(),
-                         &Context->Idents.get("__NSConstantStringImpl"));
-    QualType FieldTypes[4];
-
-    // struct objc_object *receiver;
-    FieldTypes[0] = Context->getObjCIdType();
-    // int flags;
-    FieldTypes[1] = Context->IntTy;
-    // char *str;
-    FieldTypes[2] = Context->getPointerType(Context->CharTy);
-    // long length;
-    FieldTypes[3] = Context->LongTy;
-
-    // Create fields
-    for (unsigned i = 0; i < 4; ++i) {
-      ConstantStringDecl->addDecl(FieldDecl::Create(*Context,
-                                                    ConstantStringDecl,
-                                                    SourceLocation(),
-                                                    SourceLocation(), 0,
-                                                    FieldTypes[i], 0,
-                                                    /*BitWidth=*/0,
-                                                    /*Mutable=*/true,
-                                                    ICIS_NoInit));
-    }
-
-    ConstantStringDecl->completeDefinition();
-  }
-  return Context->getTagDeclType(ConstantStringDecl);
-}
-
-CallExpr *RewriteObjC::SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFlavor,
-                                                QualType msgSendType, 
-                                                QualType returnType, 
-                                                SmallVectorImpl<QualType> &ArgTypes,
-                                                SmallVectorImpl<Expr*> &MsgExprs,
-                                                ObjCMethodDecl *Method) {
-  // Create a reference to the objc_msgSend_stret() declaration.
-  DeclRefExpr *STDRE = new (Context) DeclRefExpr(MsgSendStretFlavor,
-                                                 false, msgSendType,
-                                                 VK_LValue, SourceLocation());
-  // Need to cast objc_msgSend_stret to "void *" (see above comment).
-  CastExpr *cast = NoTypeInfoCStyleCastExpr(Context,
-                                  Context->getPointerType(Context->VoidTy),
-                                  CK_BitCast, STDRE);
-  // Now do the "normal" pointer to function cast.
-  QualType castType = getSimpleFunctionType(returnType, ArgTypes,
-                                            Method ? Method->isVariadic()
-                                                   : false);
-  castType = Context->getPointerType(castType);
-  cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
-                                            cast);
-  
-  // Don't forget the parens to enforce the proper binding.
-  ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), cast);
-  
-  const FunctionType *FT = msgSendType->getAs<FunctionType>();
-  CallExpr *STCE = new (Context) CallExpr(*Context, PE, MsgExprs,
-                                          FT->getResultType(), VK_RValue,
-                                          SourceLocation());
-  return STCE;
-  
-}
-
-
-Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
-                                    SourceLocation StartLoc,
-                                    SourceLocation EndLoc) {
-  if (!SelGetUidFunctionDecl)
-    SynthSelGetUidFunctionDecl();
-  if (!MsgSendFunctionDecl)
-    SynthMsgSendFunctionDecl();
-  if (!MsgSendSuperFunctionDecl)
-    SynthMsgSendSuperFunctionDecl();
-  if (!MsgSendStretFunctionDecl)
-    SynthMsgSendStretFunctionDecl();
-  if (!MsgSendSuperStretFunctionDecl)
-    SynthMsgSendSuperStretFunctionDecl();
-  if (!MsgSendFpretFunctionDecl)
-    SynthMsgSendFpretFunctionDecl();
-  if (!GetClassFunctionDecl)
-    SynthGetClassFunctionDecl();
-  if (!GetSuperClassFunctionDecl)
-    SynthGetSuperClassFunctionDecl();
-  if (!GetMetaClassFunctionDecl)
-    SynthGetMetaClassFunctionDecl();
-
-  // default to objc_msgSend().
-  FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl;
-  // May need to use objc_msgSend_stret() as well.
-  FunctionDecl *MsgSendStretFlavor = 0;
-  if (ObjCMethodDecl *mDecl = Exp->getMethodDecl()) {
-    QualType resultType = mDecl->getResultType();
-    if (resultType->isRecordType())
-      MsgSendStretFlavor = MsgSendStretFunctionDecl;
-    else if (resultType->isRealFloatingType())
-      MsgSendFlavor = MsgSendFpretFunctionDecl;
-  }
-
-  // Synthesize a call to objc_msgSend().
-  SmallVector<Expr*, 8> MsgExprs;
-  switch (Exp->getReceiverKind()) {
-  case ObjCMessageExpr::SuperClass: {
-    MsgSendFlavor = MsgSendSuperFunctionDecl;
-    if (MsgSendStretFlavor)
-      MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
-    assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
-
-    ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface();
-
-    SmallVector<Expr*, 4> InitExprs;
-
-    // set the receiver to self, the first argument to all methods.
-    InitExprs.push_back(
-      NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
-                               CK_BitCast,
-                   new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
-                                             false,
-                                             Context->getObjCIdType(),
-                                             VK_RValue,
-                                             SourceLocation()))
-                        ); // set the 'receiver'.
-
-    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
-    SmallVector<Expr*, 8> ClsExprs;
-    QualType argType = Context->getPointerType(Context->CharTy);
-    ClsExprs.push_back(StringLiteral::Create(*Context,
-                                   ClassDecl->getIdentifier()->getName(),
-                                   StringLiteral::Ascii, false,
-                                   argType, SourceLocation()));
-    CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
-                                                 &ClsExprs[0],
-                                                 ClsExprs.size(),
-                                                 StartLoc,
-                                                 EndLoc);
-    // (Class)objc_getClass("CurrentClass")
-    CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
-                                             Context->getObjCClassType(),
-                                             CK_BitCast, Cls);
-    ClsExprs.clear();
-    ClsExprs.push_back(ArgExpr);
-    Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
-                                       &ClsExprs[0], ClsExprs.size(),
-                                       StartLoc, EndLoc);
-    
-    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
-    // To turn off a warning, type-cast to 'id'
-    InitExprs.push_back( // set 'super class', using class_getSuperclass().
-                        NoTypeInfoCStyleCastExpr(Context,
-                                                 Context->getObjCIdType(),
-                                                 CK_BitCast, Cls));
-    // struct objc_super
-    QualType superType = getSuperStructType();
-    Expr *SuperRep;
-
-    if (LangOpts.MicrosoftExt) {
-      SynthSuperConstructorFunctionDecl();
-      // Simulate a constructor call...
-      DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperConstructorFunctionDecl,
-                                                   false, superType, VK_LValue,
-                                                   SourceLocation());
-      SuperRep = new (Context) CallExpr(*Context, DRE, InitExprs,
-                                        superType, VK_LValue,
-                                        SourceLocation());
-      // The code for super is a little tricky to prevent collision with
-      // the structure definition in the header. The rewriter has it's own
-      // internal definition (__rw_objc_super) that is uses. This is why
-      // we need the cast below. For example:
-      // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
-      //
-      SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf,
-                               Context->getPointerType(SuperRep->getType()),
-                                             VK_RValue, OK_Ordinary,
-                                             SourceLocation());
-      SuperRep = NoTypeInfoCStyleCastExpr(Context,
-                                          Context->getPointerType(superType),
-                                          CK_BitCast, SuperRep);
-    } else {
-      // (struct objc_super) { <exprs from above> }
-      InitListExpr *ILE =
-        new (Context) InitListExpr(*Context, SourceLocation(), InitExprs,
-                                   SourceLocation());
-      TypeSourceInfo *superTInfo
-        = Context->getTrivialTypeSourceInfo(superType);
-      SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
-                                                   superType, VK_LValue,
-                                                   ILE, false);
-      // struct objc_super *
-      SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf,
-                               Context->getPointerType(SuperRep->getType()),
-                                             VK_RValue, OK_Ordinary,
-                                             SourceLocation());
-    }
-    MsgExprs.push_back(SuperRep);
-    break;
-  }
-
-  case ObjCMessageExpr::Class: {
-    SmallVector<Expr*, 8> ClsExprs;
-    QualType argType = Context->getPointerType(Context->CharTy);
-    ObjCInterfaceDecl *Class
-      = Exp->getClassReceiver()->getAs<ObjCObjectType>()->getInterface();
-    IdentifierInfo *clsName = Class->getIdentifier();
-    ClsExprs.push_back(StringLiteral::Create(*Context,
-                                             clsName->getName(),
-                                             StringLiteral::Ascii, false,
-                                             argType, SourceLocation()));
-    CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
-                                                 &ClsExprs[0],
-                                                 ClsExprs.size(), 
-                                                 StartLoc, EndLoc);
-    MsgExprs.push_back(Cls);
-    break;
-  }
-
-  case ObjCMessageExpr::SuperInstance:{
-    MsgSendFlavor = MsgSendSuperFunctionDecl;
-    if (MsgSendStretFlavor)
-      MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
-    assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
-    ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface();
-    SmallVector<Expr*, 4> InitExprs;
-
-    InitExprs.push_back(
-      NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
-                               CK_BitCast,
-                   new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
-                                             false,
-                                             Context->getObjCIdType(),
-                                             VK_RValue, SourceLocation()))
-                        ); // set the 'receiver'.
-    
-    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
-    SmallVector<Expr*, 8> ClsExprs;
-    QualType argType = Context->getPointerType(Context->CharTy);
-    ClsExprs.push_back(StringLiteral::Create(*Context,
-                                   ClassDecl->getIdentifier()->getName(),
-                                   StringLiteral::Ascii, false, argType,
-                                   SourceLocation()));
-    CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
-                                                 &ClsExprs[0],
-                                                 ClsExprs.size(), 
-                                                 StartLoc, EndLoc);
-    // (Class)objc_getClass("CurrentClass")
-    CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
-                                                 Context->getObjCClassType(),
-                                                 CK_BitCast, Cls);
-    ClsExprs.clear();
-    ClsExprs.push_back(ArgExpr);
-    Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
-                                       &ClsExprs[0], ClsExprs.size(),
-                                       StartLoc, EndLoc);
-    
-    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
-    // To turn off a warning, type-cast to 'id'
-    InitExprs.push_back(
-      // set 'super class', using class_getSuperclass().
-      NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
-                               CK_BitCast, Cls));
-    // struct objc_super
-    QualType superType = getSuperStructType();
-    Expr *SuperRep;
-
-    if (LangOpts.MicrosoftExt) {
-      SynthSuperConstructorFunctionDecl();
-      // Simulate a constructor call...
-      DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperConstructorFunctionDecl,
-                                                   false, superType, VK_LValue,
-                                                   SourceLocation());
-      SuperRep = new (Context) CallExpr(*Context, DRE, InitExprs,
-                                        superType, VK_LValue, SourceLocation());
-      // The code for super is a little tricky to prevent collision with
-      // the structure definition in the header. The rewriter has it's own
-      // internal definition (__rw_objc_super) that is uses. This is why
-      // we need the cast below. For example:
-      // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
-      //
-      SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf,
-                               Context->getPointerType(SuperRep->getType()),
-                               VK_RValue, OK_Ordinary,
-                               SourceLocation());
-      SuperRep = NoTypeInfoCStyleCastExpr(Context,
-                               Context->getPointerType(superType),
-                               CK_BitCast, SuperRep);
-    } else {
-      // (struct objc_super) { <exprs from above> }
-      InitListExpr *ILE =
-        new (Context) InitListExpr(*Context, SourceLocation(), InitExprs,
-                                   SourceLocation());
-      TypeSourceInfo *superTInfo
-        = Context->getTrivialTypeSourceInfo(superType);
-      SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
-                                                   superType, VK_RValue, ILE,
-                                                   false);
-    }
-    MsgExprs.push_back(SuperRep);
-    break;
-  }
-
-  case ObjCMessageExpr::Instance: {
-    // Remove all type-casts because it may contain objc-style types; e.g.
-    // Foo<Proto> *.
-    Expr *recExpr = Exp->getInstanceReceiver();
-    while (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(recExpr))
-      recExpr = CE->getSubExpr();
-    CastKind CK = recExpr->getType()->isObjCObjectPointerType()
-                    ? CK_BitCast : recExpr->getType()->isBlockPointerType()
-                                     ? CK_BlockPointerToObjCPointerCast
-                                     : CK_CPointerToObjCPointerCast;
-
-    recExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
-                                       CK, recExpr);
-    MsgExprs.push_back(recExpr);
-    break;
-  }
-  }
-
-  // Create a call to sel_registerName("selName"), it will be the 2nd argument.
-  SmallVector<Expr*, 8> SelExprs;
-  QualType argType = Context->getPointerType(Context->CharTy);
-  SelExprs.push_back(StringLiteral::Create(*Context,
-                                       Exp->getSelector().getAsString(),
-                                       StringLiteral::Ascii, false,
-                                       argType, SourceLocation()));
-  CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
-                                                 &SelExprs[0], SelExprs.size(),
-                                                  StartLoc,
-                                                  EndLoc);
-  MsgExprs.push_back(SelExp);
-
-  // Now push any user supplied arguments.
-  for (unsigned i = 0; i < Exp->getNumArgs(); i++) {
-    Expr *userExpr = Exp->getArg(i);
-    // Make all implicit casts explicit...ICE comes in handy:-)
-    if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(userExpr)) {
-      // Reuse the ICE type, it is exactly what the doctor ordered.
-      QualType type = ICE->getType();
-      if (needToScanForQualifiers(type))
-        type = Context->getObjCIdType();
-      // Make sure we convert "type (^)(...)" to "type (*)(...)".
-      (void)convertBlockPointerToFunctionPointer(type);
-      const Expr *SubExpr = ICE->IgnoreParenImpCasts();
-      CastKind CK;
-      if (SubExpr->getType()->isIntegralType(*Context) && 
-          type->isBooleanType()) {
-        CK = CK_IntegralToBoolean;
-      } else if (type->isObjCObjectPointerType()) {
-        if (SubExpr->getType()->isBlockPointerType()) {
-          CK = CK_BlockPointerToObjCPointerCast;
-        } else if (SubExpr->getType()->isPointerType()) {
-          CK = CK_CPointerToObjCPointerCast;
-        } else {
-          CK = CK_BitCast;
-        }
-      } else {
-        CK = CK_BitCast;
-      }
-
-      userExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, userExpr);
-    }
-    // Make id<P...> cast into an 'id' cast.
-    else if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(userExpr)) {
-      if (CE->getType()->isObjCQualifiedIdType()) {
-        while ((CE = dyn_cast<CStyleCastExpr>(userExpr)))
-          userExpr = CE->getSubExpr();
-        CastKind CK;
-        if (userExpr->getType()->isIntegralType(*Context)) {
-          CK = CK_IntegralToPointer;
-        } else if (userExpr->getType()->isBlockPointerType()) {
-          CK = CK_BlockPointerToObjCPointerCast;
-        } else if (userExpr->getType()->isPointerType()) {
-          CK = CK_CPointerToObjCPointerCast;
-        } else {
-          CK = CK_BitCast;
-        }
-        userExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
-                                            CK, userExpr);
-      }
-    }
-    MsgExprs.push_back(userExpr);
-    // We've transferred the ownership to MsgExprs. For now, we *don't* null
-    // out the argument in the original expression (since we aren't deleting
-    // the ObjCMessageExpr). See RewritePropertyOrImplicitSetter() usage for more info.
-    //Exp->setArg(i, 0);
-  }
-  // Generate the funky cast.
-  CastExpr *cast;
-  SmallVector<QualType, 8> ArgTypes;
-  QualType returnType;
-
-  // Push 'id' and 'SEL', the 2 implicit arguments.
-  if (MsgSendFlavor == MsgSendSuperFunctionDecl)
-    ArgTypes.push_back(Context->getPointerType(getSuperStructType()));
-  else
-    ArgTypes.push_back(Context->getObjCIdType());
-  ArgTypes.push_back(Context->getObjCSelType());
-  if (ObjCMethodDecl *OMD = Exp->getMethodDecl()) {
-    // Push any user argument types.
-    for (ObjCMethodDecl::param_iterator PI = OMD->param_begin(),
-         E = OMD->param_end(); PI != E; ++PI) {
-      QualType t = (*PI)->getType()->isObjCQualifiedIdType()
-                     ? Context->getObjCIdType()
-                     : (*PI)->getType();
-      // Make sure we convert "t (^)(...)" to "t (*)(...)".
-      (void)convertBlockPointerToFunctionPointer(t);
-      ArgTypes.push_back(t);
-    }
-    returnType = Exp->getType();
-    convertToUnqualifiedObjCType(returnType);
-    (void)convertBlockPointerToFunctionPointer(returnType);
-  } else {
-    returnType = Context->getObjCIdType();
-  }
-  // Get the type, we will need to reference it in a couple spots.
-  QualType msgSendType = MsgSendFlavor->getType();
-
-  // Create a reference to the objc_msgSend() declaration.
-  DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType,
-                                               VK_LValue, SourceLocation());
-
-  // Need to cast objc_msgSend to "void *" (to workaround a GCC bandaid).
-  // If we don't do this cast, we get the following bizarre warning/note:
-  // xx.m:13: warning: function called through a non-compatible type
-  // xx.m:13: note: if this code is reached, the program will abort
-  cast = NoTypeInfoCStyleCastExpr(Context,
-                                  Context->getPointerType(Context->VoidTy),
-                                  CK_BitCast, DRE);
-
-  // Now do the "normal" pointer to function cast.
-  // If we don't have a method decl, force a variadic cast.
-  const ObjCMethodDecl *MD = Exp->getMethodDecl();
-  QualType castType =
-    getSimpleFunctionType(returnType, ArgTypes, MD ? MD->isVariadic() : true);
-  castType = Context->getPointerType(castType);
-  cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
-                                  cast);
-
-  // Don't forget the parens to enforce the proper binding.
-  ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
-
-  const FunctionType *FT = msgSendType->getAs<FunctionType>();
-  CallExpr *CE = new (Context) CallExpr(*Context, PE, MsgExprs,
-                                        FT->getResultType(), VK_RValue,
-                                        EndLoc);
-  Stmt *ReplacingStmt = CE;
-  if (MsgSendStretFlavor) {
-    // We have the method which returns a struct/union. Must also generate
-    // call to objc_msgSend_stret and hang both varieties on a conditional
-    // expression which dictate which one to envoke depending on size of
-    // method's return type.
-    
-    CallExpr *STCE = SynthMsgSendStretCallExpr(MsgSendStretFlavor, 
-                                               msgSendType, returnType, 
-                                               ArgTypes, MsgExprs,
-                                               Exp->getMethodDecl());
-
-    // Build sizeof(returnType)
-    UnaryExprOrTypeTraitExpr *sizeofExpr =
-       new (Context) UnaryExprOrTypeTraitExpr(UETT_SizeOf,
-                                 Context->getTrivialTypeSourceInfo(returnType),
-                                 Context->getSizeType(), SourceLocation(),
-                                 SourceLocation());
-    // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...))
-    // FIXME: Value of 8 is base on ppc32/x86 ABI for the most common cases.
-    // For X86 it is more complicated and some kind of target specific routine
-    // is needed to decide what to do.
-    unsigned IntSize =
-      static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
-    IntegerLiteral *limit = IntegerLiteral::Create(*Context,
-                                                   llvm::APInt(IntSize, 8),
-                                                   Context->IntTy,
-                                                   SourceLocation());
-    BinaryOperator *lessThanExpr = 
-      new (Context) BinaryOperator(sizeofExpr, limit, BO_LE, Context->IntTy,
-                                   VK_RValue, OK_Ordinary, SourceLocation(),
-                                   false);
-    // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...))
-    ConditionalOperator *CondExpr =
-      new (Context) ConditionalOperator(lessThanExpr,
-                                        SourceLocation(), CE,
-                                        SourceLocation(), STCE,
-                                        returnType, VK_RValue, OK_Ordinary);
-    ReplacingStmt = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 
-                                            CondExpr);
-  }
-  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
-  return ReplacingStmt;
-}
-
-Stmt *RewriteObjC::RewriteMessageExpr(ObjCMessageExpr *Exp) {
-  Stmt *ReplacingStmt = SynthMessageExpr(Exp, Exp->getLocStart(),
-                                         Exp->getLocEnd());
-
-  // Now do the actual rewrite.
-  ReplaceStmt(Exp, ReplacingStmt);
-
-  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
-  return ReplacingStmt;
-}
-
-// typedef struct objc_object Protocol;
-QualType RewriteObjC::getProtocolType() {
-  if (!ProtocolTypeDecl) {
-    TypeSourceInfo *TInfo
-      = Context->getTrivialTypeSourceInfo(Context->getObjCIdType());
-    ProtocolTypeDecl = TypedefDecl::Create(*Context, TUDecl,
-                                           SourceLocation(), SourceLocation(),
-                                           &Context->Idents.get("Protocol"),
-                                           TInfo);
-  }
-  return Context->getTypeDeclType(ProtocolTypeDecl);
-}
-
-/// RewriteObjCProtocolExpr - Rewrite a protocol expression into
-/// a synthesized/forward data reference (to the protocol's metadata).
-/// The forward references (and metadata) are generated in
-/// RewriteObjC::HandleTranslationUnit().
-Stmt *RewriteObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) {
-  std::string Name = "_OBJC_PROTOCOL_" + Exp->getProtocol()->getNameAsString();
-  IdentifierInfo *ID = &Context->Idents.get(Name);
-  VarDecl *VD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
-                                SourceLocation(), ID, getProtocolType(), 0,
-                                SC_Extern);
-  DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, false, getProtocolType(),
-                                               VK_LValue, SourceLocation());
-  Expr *DerefExpr = new (Context) UnaryOperator(DRE, UO_AddrOf,
-                             Context->getPointerType(DRE->getType()),
-                             VK_RValue, OK_Ordinary, SourceLocation());
-  CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, DerefExpr->getType(),
-                                                CK_BitCast,
-                                                DerefExpr);
-  ReplaceStmt(Exp, castExpr);
-  ProtocolExprDecls.insert(Exp->getProtocol()->getCanonicalDecl());
-  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
-  return castExpr;
-
-}
-
-bool RewriteObjC::BufferContainsPPDirectives(const char *startBuf,
-                                             const char *endBuf) {
-  while (startBuf < endBuf) {
-    if (*startBuf == '#') {
-      // Skip whitespace.
-      for (++startBuf; startBuf[0] == ' ' || startBuf[0] == '\t'; ++startBuf)
-        ;
-      if (!strncmp(startBuf, "if", strlen("if")) ||
-          !strncmp(startBuf, "ifdef", strlen("ifdef")) ||
-          !strncmp(startBuf, "ifndef", strlen("ifndef")) ||
-          !strncmp(startBuf, "define", strlen("define")) ||
-          !strncmp(startBuf, "undef", strlen("undef")) ||
-          !strncmp(startBuf, "else", strlen("else")) ||
-          !strncmp(startBuf, "elif", strlen("elif")) ||
-          !strncmp(startBuf, "endif", strlen("endif")) ||
-          !strncmp(startBuf, "pragma", strlen("pragma")) ||
-          !strncmp(startBuf, "include", strlen("include")) ||
-          !strncmp(startBuf, "import", strlen("import")) ||
-          !strncmp(startBuf, "include_next", strlen("include_next")))
-        return true;
-    }
-    startBuf++;
-  }
-  return false;
-}
-
-/// RewriteObjCInternalStruct - Rewrite one internal struct corresponding to
-/// an objective-c class with ivars.
-void RewriteObjC::RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl,
-                                               std::string &Result) {
-  assert(CDecl && "Class missing in SynthesizeObjCInternalStruct");
-  assert(CDecl->getName() != "" &&
-         "Name missing in SynthesizeObjCInternalStruct");
-  // Do not synthesize more than once.
-  if (ObjCSynthesizedStructs.count(CDecl))
-    return;
-  ObjCInterfaceDecl *RCDecl = CDecl->getSuperClass();
-  int NumIvars = CDecl->ivar_size();
-  SourceLocation LocStart = CDecl->getLocStart();
-  SourceLocation LocEnd = CDecl->getEndOfDefinitionLoc();
-
-  const char *startBuf = SM->getCharacterData(LocStart);
-  const char *endBuf = SM->getCharacterData(LocEnd);
-
-  // If no ivars and no root or if its root, directly or indirectly,
-  // have no ivars (thus not synthesized) then no need to synthesize this class.
-  if ((!CDecl->isThisDeclarationADefinition() || NumIvars == 0) &&
-      (!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) {
-    endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts);
-    ReplaceText(LocStart, endBuf-startBuf, Result);
-    return;
-  }
-
-  // FIXME: This has potential of causing problem. If
-  // SynthesizeObjCInternalStruct is ever called recursively.
-  Result += "\nstruct ";
-  Result += CDecl->getNameAsString();
-  if (LangOpts.MicrosoftExt)
-    Result += "_IMPL";
-
-  if (NumIvars > 0) {
-    const char *cursor = strchr(startBuf, '{');
-    assert((cursor && endBuf)
-           && "SynthesizeObjCInternalStruct - malformed @interface");
-    // If the buffer contains preprocessor directives, we do more fine-grained
-    // rewrites. This is intended to fix code that looks like (which occurs in
-    // NSURL.h, for example):
-    //
-    // #ifdef XYZ
-    // @interface Foo : NSObject
-    // #else
-    // @interface FooBar : NSObject
-    // #endif
-    // {
-    //    int i;
-    // }
-    // @end
-    //
-    // This clause is segregated to avoid breaking the common case.
-    if (BufferContainsPPDirectives(startBuf, cursor)) {
-      SourceLocation L = RCDecl ? CDecl->getSuperClassLoc() :
-                                  CDecl->getAtStartLoc();
-      const char *endHeader = SM->getCharacterData(L);
-      endHeader += Lexer::MeasureTokenLength(L, *SM, LangOpts);
-
-      if (CDecl->protocol_begin() != CDecl->protocol_end()) {
-        // advance to the end of the referenced protocols.
-        while (endHeader < cursor && *endHeader != '>') endHeader++;
-        endHeader++;
-      }
-      // rewrite the original header
-      ReplaceText(LocStart, endHeader-startBuf, Result);
-    } else {
-      // rewrite the original header *without* disturbing the '{'
-      ReplaceText(LocStart, cursor-startBuf, Result);
-    }
-    if (RCDecl && ObjCSynthesizedStructs.count(RCDecl)) {
-      Result = "\n    struct ";
-      Result += RCDecl->getNameAsString();
-      Result += "_IMPL ";
-      Result += RCDecl->getNameAsString();
-      Result += "_IVARS;\n";
-
-      // insert the super class structure definition.
-      SourceLocation OnePastCurly =
-        LocStart.getLocWithOffset(cursor-startBuf+1);
-      InsertText(OnePastCurly, Result);
-    }
-    cursor++; // past '{'
-
-    // Now comment out any visibility specifiers.
-    while (cursor < endBuf) {
-      if (*cursor == '@') {
-        SourceLocation atLoc = LocStart.getLocWithOffset(cursor-startBuf);
-        // Skip whitespace.
-        for (++cursor; cursor[0] == ' ' || cursor[0] == '\t'; ++cursor)
-          /*scan*/;
-
-        // FIXME: presence of @public, etc. inside comment results in
-        // this transformation as well, which is still correct c-code.
-        if (!strncmp(cursor, "public", strlen("public")) ||
-            !strncmp(cursor, "private", strlen("private")) ||
-            !strncmp(cursor, "package", strlen("package")) ||
-            !strncmp(cursor, "protected", strlen("protected")))
-          InsertText(atLoc, "// ");
-      }
-      // FIXME: If there are cases where '<' is used in ivar declaration part
-      // of user code, then scan the ivar list and use needToScanForQualifiers
-      // for type checking.
-      else if (*cursor == '<') {
-        SourceLocation atLoc = LocStart.getLocWithOffset(cursor-startBuf);
-        InsertText(atLoc, "/* ");
-        cursor = strchr(cursor, '>');
-        cursor++;
-        atLoc = LocStart.getLocWithOffset(cursor-startBuf);
-        InsertText(atLoc, " */");
-      } else if (*cursor == '^') { // rewrite block specifier.
-        SourceLocation caretLoc = LocStart.getLocWithOffset(cursor-startBuf);
-        ReplaceText(caretLoc, 1, "*");
-      }
-      cursor++;
-    }
-    // Don't forget to add a ';'!!
-    InsertText(LocEnd.getLocWithOffset(1), ";");
-  } else { // we don't have any instance variables - insert super struct.
-    endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts);
-    Result += " {\n    struct ";
-    Result += RCDecl->getNameAsString();
-    Result += "_IMPL ";
-    Result += RCDecl->getNameAsString();
-    Result += "_IVARS;\n};\n";
-    ReplaceText(LocStart, endBuf-startBuf, Result);
-  }
-  // Mark this struct as having been generated.
-  if (!ObjCSynthesizedStructs.insert(CDecl))
-    llvm_unreachable("struct already synthesize- SynthesizeObjCInternalStruct");
-}
-
-//===----------------------------------------------------------------------===//
-// Meta Data Emission
-//===----------------------------------------------------------------------===//
-
-
-/// RewriteImplementations - This routine rewrites all method implementations
-/// and emits meta-data.
-
-void RewriteObjC::RewriteImplementations() {
-  int ClsDefCount = ClassImplementation.size();
-  int CatDefCount = CategoryImplementation.size();
-
-  // Rewrite implemented methods
-  for (int i = 0; i < ClsDefCount; i++)
-    RewriteImplementationDecl(ClassImplementation[i]);
-
-  for (int i = 0; i < CatDefCount; i++)
-    RewriteImplementationDecl(CategoryImplementation[i]);
-}
-
-void RewriteObjC::RewriteByRefString(std::string &ResultStr, 
-                                     const std::string &Name,
-                                     ValueDecl *VD, bool def) {
-  assert(BlockByRefDeclNo.count(VD) && 
-         "RewriteByRefString: ByRef decl missing");
-  if (def)
-    ResultStr += "struct ";
-  ResultStr += "__Block_byref_" + Name + 
-    "_" + utostr(BlockByRefDeclNo[VD]) ;
-}
-
-static bool HasLocalVariableExternalStorage(ValueDecl *VD) {
-  if (VarDecl *Var = dyn_cast<VarDecl>(VD))
-    return (Var->isFunctionOrMethodVarDecl() && !Var->hasLocalStorage());
-  return false;
-}
-
-std::string RewriteObjC::SynthesizeBlockFunc(BlockExpr *CE, int i,
-                                                   StringRef funcName,
-                                                   std::string Tag) {
-  const FunctionType *AFT = CE->getFunctionType();
-  QualType RT = AFT->getResultType();
-  std::string StructRef = "struct " + Tag;
-  std::string S = "static " + RT.getAsString(Context->getPrintingPolicy()) + " __" +
-                  funcName.str() + "_" + "block_func_" + utostr(i);
-
-  BlockDecl *BD = CE->getBlockDecl();
-
-  if (isa<FunctionNoProtoType>(AFT)) {
-    // No user-supplied arguments. Still need to pass in a pointer to the
-    // block (to reference imported block decl refs).
-    S += "(" + StructRef + " *__cself)";
-  } else if (BD->param_empty()) {
-    S += "(" + StructRef + " *__cself)";
-  } else {
-    const FunctionProtoType *FT = cast<FunctionProtoType>(AFT);
-    assert(FT && "SynthesizeBlockFunc: No function proto");
-    S += '(';
-    // first add the implicit argument.
-    S += StructRef + " *__cself, ";
-    std::string ParamStr;
-    for (BlockDecl::param_iterator AI = BD->param_begin(),
-         E = BD->param_end(); AI != E; ++AI) {
-      if (AI != BD->param_begin()) S += ", ";
-      ParamStr = (*AI)->getNameAsString();
-      QualType QT = (*AI)->getType();
-      (void)convertBlockPointerToFunctionPointer(QT);
-      QT.getAsStringInternal(ParamStr, Context->getPrintingPolicy());
-      S += ParamStr;
-    }
-    if (FT->isVariadic()) {
-      if (!BD->param_empty()) S += ", ";
-      S += "...";
-    }
-    S += ')';
-  }
-  S += " {\n";
-
-  // Create local declarations to avoid rewriting all closure decl ref exprs.
-  // First, emit a declaration for all "by ref" decls.
-  for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(),
-       E = BlockByRefDecls.end(); I != E; ++I) {
-    S += "  ";
-    std::string Name = (*I)->getNameAsString();
-    std::string TypeString;
-    RewriteByRefString(TypeString, Name, (*I));
-    TypeString += " *";
-    Name = TypeString + Name;
-    S += Name + " = __cself->" + (*I)->getNameAsString() + "; // bound by ref\n";
-  }
-  // Next, emit a declaration for all "by copy" declarations.
-  for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(),
-       E = BlockByCopyDecls.end(); I != E; ++I) {
-    S += "  ";
-    // Handle nested closure invocation. For example:
-    //
-    //   void (^myImportedClosure)(void);
-    //   myImportedClosure  = ^(void) { setGlobalInt(x + y); };
-    //
-    //   void (^anotherClosure)(void);
-    //   anotherClosure = ^(void) {
-    //     myImportedClosure(); // import and invoke the closure
-    //   };
-    //
-    if (isTopLevelBlockPointerType((*I)->getType())) {
-      RewriteBlockPointerTypeVariable(S, (*I));
-      S += " = (";
-      RewriteBlockPointerType(S, (*I)->getType());
-      S += ")";
-      S += "__cself->" + (*I)->getNameAsString() + "; // bound by copy\n";
-    }
-    else {
-      std::string Name = (*I)->getNameAsString();
-      QualType QT = (*I)->getType();
-      if (HasLocalVariableExternalStorage(*I))
-        QT = Context->getPointerType(QT);
-      QT.getAsStringInternal(Name, Context->getPrintingPolicy());
-      S += Name + " = __cself->" + 
-                              (*I)->getNameAsString() + "; // bound by copy\n";
-    }
-  }
-  std::string RewrittenStr = RewrittenBlockExprs[CE];
-  const char *cstr = RewrittenStr.c_str();
-  while (*cstr++ != '{') ;
-  S += cstr;
-  S += "\n";
-  return S;
-}
-
-std::string RewriteObjC::SynthesizeBlockHelperFuncs(BlockExpr *CE, int i,
-                                                   StringRef funcName,
-                                                   std::string Tag) {
-  std::string StructRef = "struct " + Tag;
-  std::string S = "static void __";
-
-  S += funcName;
-  S += "_block_copy_" + utostr(i);
-  S += "(" + StructRef;
-  S += "*dst, " + StructRef;
-  S += "*src) {";
-  for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = ImportedBlockDecls.begin(),
-      E = ImportedBlockDecls.end(); I != E; ++I) {
-    ValueDecl *VD = (*I);
-    S += "_Block_object_assign((void*)&dst->";
-    S += (*I)->getNameAsString();
-    S += ", (void*)src->";
-    S += (*I)->getNameAsString();
-    if (BlockByRefDeclsPtrSet.count((*I)))
-      S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);";
-    else if (VD->getType()->isBlockPointerType())
-      S += ", " + utostr(BLOCK_FIELD_IS_BLOCK) + "/*BLOCK_FIELD_IS_BLOCK*/);";
-    else
-      S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);";
-  }
-  S += "}\n";
-  
-  S += "\nstatic void __";
-  S += funcName;
-  S += "_block_dispose_" + utostr(i);
-  S += "(" + StructRef;
-  S += "*src) {";
-  for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = ImportedBlockDecls.begin(),
-      E = ImportedBlockDecls.end(); I != E; ++I) {
-    ValueDecl *VD = (*I);
-    S += "_Block_object_dispose((void*)src->";
-    S += (*I)->getNameAsString();
-    if (BlockByRefDeclsPtrSet.count((*I)))
-      S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);";
-    else if (VD->getType()->isBlockPointerType())
-      S += ", " + utostr(BLOCK_FIELD_IS_BLOCK) + "/*BLOCK_FIELD_IS_BLOCK*/);";
-    else
-      S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);";
-  }
-  S += "}\n";
-  return S;
-}
-
-std::string RewriteObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag, 
-                                             std::string Desc) {
-  std::string S = "\nstruct " + Tag;
-  std::string Constructor = "  " + Tag;
-
-  S += " {\n  struct __block_impl impl;\n";
-  S += "  struct " + Desc;
-  S += "* Desc;\n";
-
-  Constructor += "(void *fp, "; // Invoke function pointer.
-  Constructor += "struct " + Desc; // Descriptor pointer.
-  Constructor += " *desc";
-
-  if (BlockDeclRefs.size()) {
-    // Output all "by copy" declarations.
-    for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(),
-         E = BlockByCopyDecls.end(); I != E; ++I) {
-      S += "  ";
-      std::string FieldName = (*I)->getNameAsString();
-      std::string ArgName = "_" + FieldName;
-      // Handle nested closure invocation. For example:
-      //
-      //   void (^myImportedBlock)(void);
-      //   myImportedBlock  = ^(void) { setGlobalInt(x + y); };
-      //
-      //   void (^anotherBlock)(void);
-      //   anotherBlock = ^(void) {
-      //     myImportedBlock(); // import and invoke the closure
-      //   };
-      //
-      if (isTopLevelBlockPointerType((*I)->getType())) {
-        S += "struct __block_impl *";
-        Constructor += ", void *" + ArgName;
-      } else {
-        QualType QT = (*I)->getType();
-        if (HasLocalVariableExternalStorage(*I))
-          QT = Context->getPointerType(QT);
-        QT.getAsStringInternal(FieldName, Context->getPrintingPolicy());
-        QT.getAsStringInternal(ArgName, Context->getPrintingPolicy());
-        Constructor += ", " + ArgName;
-      }
-      S += FieldName + ";\n";
-    }
-    // Output all "by ref" declarations.
-    for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(),
-         E = BlockByRefDecls.end(); I != E; ++I) {
-      S += "  ";
-      std::string FieldName = (*I)->getNameAsString();
-      std::string ArgName = "_" + FieldName;
-      {
-        std::string TypeString;
-        RewriteByRefString(TypeString, FieldName, (*I));
-        TypeString += " *";
-        FieldName = TypeString + FieldName;
-        ArgName = TypeString + ArgName;
-        Constructor += ", " + ArgName;
-      }
-      S += FieldName + "; // by ref\n";
-    }
-    // Finish writing the constructor.
-    Constructor += ", int flags=0)";
-    // Initialize all "by copy" arguments.
-    bool firsTime = true;
-    for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(),
-         E = BlockByCopyDecls.end(); I != E; ++I) {
-      std::string Name = (*I)->getNameAsString();
-        if (firsTime) {
-          Constructor += " : ";
-          firsTime = false;
-        }
-        else
-          Constructor += ", ";
-        if (isTopLevelBlockPointerType((*I)->getType()))
-          Constructor += Name + "((struct __block_impl *)_" + Name + ")";
-        else
-          Constructor += Name + "(_" + Name + ")";
-    }
-    // Initialize all "by ref" arguments.
-    for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(),
-         E = BlockByRefDecls.end(); I != E; ++I) {
-      std::string Name = (*I)->getNameAsString();
-      if (firsTime) {
-        Constructor += " : ";
-        firsTime = false;
-      }
-      else
-        Constructor += ", ";
-      Constructor += Name + "(_" + Name + "->__forwarding)";
-    }
-    
-    Constructor += " {\n";
-    if (GlobalVarDecl)
-      Constructor += "    impl.isa = &_NSConcreteGlobalBlock;\n";
-    else
-      Constructor += "    impl.isa = &_NSConcreteStackBlock;\n";
-    Constructor += "    impl.Flags = flags;\n    impl.FuncPtr = fp;\n";
-
-    Constructor += "    Desc = desc;\n";
-  } else {
-    // Finish writing the constructor.
-    Constructor += ", int flags=0) {\n";
-    if (GlobalVarDecl)
-      Constructor += "    impl.isa = &_NSConcreteGlobalBlock;\n";
-    else
-      Constructor += "    impl.isa = &_NSConcreteStackBlock;\n";
-    Constructor += "    impl.Flags = flags;\n    impl.FuncPtr = fp;\n";
-    Constructor += "    Desc = desc;\n";
-  }
-  Constructor += "  ";
-  Constructor += "}\n";
-  S += Constructor;
-  S += "};\n";
-  return S;
-}
-
-std::string RewriteObjC::SynthesizeBlockDescriptor(std::string DescTag, 
-                                                   std::string ImplTag, int i,
-                                                   StringRef FunName,
-                                                   unsigned hasCopy) {
-  std::string S = "\nstatic struct " + DescTag;
-  
-  S += " {\n  unsigned long reserved;\n";
-  S += "  unsigned long Block_size;\n";
-  if (hasCopy) {
-    S += "  void (*copy)(struct ";
-    S += ImplTag; S += "*, struct ";
-    S += ImplTag; S += "*);\n";
-    
-    S += "  void (*dispose)(struct ";
-    S += ImplTag; S += "*);\n";
-  }
-  S += "} ";
-
-  S += DescTag + "_DATA = { 0, sizeof(struct ";
-  S += ImplTag + ")";
-  if (hasCopy) {
-    S += ", __" + FunName.str() + "_block_copy_" + utostr(i);
-    S += ", __" + FunName.str() + "_block_dispose_" + utostr(i);
-  }
-  S += "};\n";
-  return S;
-}
-
-void RewriteObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart,
-                                          StringRef FunName) {
-  // Insert declaration for the function in which block literal is used.
-  if (CurFunctionDeclToDeclareForBlock && !Blocks.empty())
-    RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock);
-  bool RewriteSC = (GlobalVarDecl &&
-                    !Blocks.empty() &&
-                    GlobalVarDecl->getStorageClass() == SC_Static &&
-                    GlobalVarDecl->getType().getCVRQualifiers());
-  if (RewriteSC) {
-    std::string SC(" void __");
-    SC += GlobalVarDecl->getNameAsString();
-    SC += "() {}";
-    InsertText(FunLocStart, SC);
-  }
-  
-  // Insert closures that were part of the function.
-  for (unsigned i = 0, count=0; i < Blocks.size(); i++) {
-    CollectBlockDeclRefInfo(Blocks[i]);
-    // Need to copy-in the inner copied-in variables not actually used in this
-    // block.
-    for (int j = 0; j < InnerDeclRefsCount[i]; j++) {
-      DeclRefExpr *Exp = InnerDeclRefs[count++];
-      ValueDecl *VD = Exp->getDecl();
-      BlockDeclRefs.push_back(Exp);
-      if (!VD->hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) {
-        BlockByCopyDeclsPtrSet.insert(VD);
-        BlockByCopyDecls.push_back(VD);
-      }
-      if (VD->hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) {
-        BlockByRefDeclsPtrSet.insert(VD);
-        BlockByRefDecls.push_back(VD);
-      }
-      // imported objects in the inner blocks not used in the outer
-      // blocks must be copied/disposed in the outer block as well.
-      if (VD->hasAttr<BlocksAttr>() ||
-          VD->getType()->isObjCObjectPointerType() || 
-          VD->getType()->isBlockPointerType())
-        ImportedBlockDecls.insert(VD);
-    }
-
-    std::string ImplTag = "__" + FunName.str() + "_block_impl_" + utostr(i);
-    std::string DescTag = "__" + FunName.str() + "_block_desc_" + utostr(i);
-
-    std::string CI = SynthesizeBlockImpl(Blocks[i], ImplTag, DescTag);
-
-    InsertText(FunLocStart, CI);
-
-    std::string CF = SynthesizeBlockFunc(Blocks[i], i, FunName, ImplTag);
-
-    InsertText(FunLocStart, CF);
-
-    if (ImportedBlockDecls.size()) {
-      std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, ImplTag);
-      InsertText(FunLocStart, HF);
-    }
-    std::string BD = SynthesizeBlockDescriptor(DescTag, ImplTag, i, FunName,
-                                               ImportedBlockDecls.size() > 0);
-    InsertText(FunLocStart, BD);
-
-    BlockDeclRefs.clear();
-    BlockByRefDecls.clear();
-    BlockByRefDeclsPtrSet.clear();
-    BlockByCopyDecls.clear();
-    BlockByCopyDeclsPtrSet.clear();
-    ImportedBlockDecls.clear();
-  }
-  if (RewriteSC) {
-    // Must insert any 'const/volatile/static here. Since it has been
-    // removed as result of rewriting of block literals.
-    std::string SC;
-    if (GlobalVarDecl->getStorageClass() == SC_Static)
-      SC = "static ";
-    if (GlobalVarDecl->getType().isConstQualified())
-      SC += "const ";
-    if (GlobalVarDecl->getType().isVolatileQualified())
-      SC += "volatile ";
-    if (GlobalVarDecl->getType().isRestrictQualified())
-      SC += "restrict ";
-    InsertText(FunLocStart, SC);
-  }
-  
-  Blocks.clear();
-  InnerDeclRefsCount.clear();
-  InnerDeclRefs.clear();
-  RewrittenBlockExprs.clear();
-}
-
-void RewriteObjC::InsertBlockLiteralsWithinFunction(FunctionDecl *FD) {
-  SourceLocation FunLocStart = FD->getTypeSpecStartLoc();
-  StringRef FuncName = FD->getName();
-
-  SynthesizeBlockLiterals(FunLocStart, FuncName);
-}
-
-static void BuildUniqueMethodName(std::string &Name,
-                                  ObjCMethodDecl *MD) {
-  ObjCInterfaceDecl *IFace = MD->getClassInterface();
-  Name = IFace->getName();
-  Name += "__" + MD->getSelector().getAsString();
-  // Convert colons to underscores.
-  std::string::size_type loc = 0;
-  while ((loc = Name.find(":", loc)) != std::string::npos)
-    Name.replace(loc, 1, "_");
-}
-
-void RewriteObjC::InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD) {
-  //fprintf(stderr,"In InsertBlockLiteralsWitinMethod\n");
-  //SourceLocation FunLocStart = MD->getLocStart();
-  SourceLocation FunLocStart = MD->getLocStart();
-  std::string FuncName;
-  BuildUniqueMethodName(FuncName, MD);
-  SynthesizeBlockLiterals(FunLocStart, FuncName);
-}
-
-void RewriteObjC::GetBlockDeclRefExprs(Stmt *S) {
-  for (Stmt::child_range CI = S->children(); CI; ++CI)
-    if (*CI) {
-      if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI))
-        GetBlockDeclRefExprs(CBE->getBody());
-      else
-        GetBlockDeclRefExprs(*CI);
-    }
-  // Handle specific things.
-  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
-    if (DRE->refersToEnclosingLocal()) {
-      // FIXME: Handle enums.
-      if (!isa<FunctionDecl>(DRE->getDecl()))
-        BlockDeclRefs.push_back(DRE);
-      if (HasLocalVariableExternalStorage(DRE->getDecl()))
-        BlockDeclRefs.push_back(DRE);
-    }
-  }
-  
-  return;
-}
-
-void RewriteObjC::GetInnerBlockDeclRefExprs(Stmt *S,
-                SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs,
-                llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts) {
-  for (Stmt::child_range CI = S->children(); CI; ++CI)
-    if (*CI) {
-      if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI)) {
-        InnerContexts.insert(cast<DeclContext>(CBE->getBlockDecl()));
-        GetInnerBlockDeclRefExprs(CBE->getBody(),
-                                  InnerBlockDeclRefs,
-                                  InnerContexts);
-      }
-      else
-        GetInnerBlockDeclRefExprs(*CI,
-                                  InnerBlockDeclRefs,
-                                  InnerContexts);
-
-    }
-  // Handle specific things.
-  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
-    if (DRE->refersToEnclosingLocal()) {
-      if (!isa<FunctionDecl>(DRE->getDecl()) &&
-          !InnerContexts.count(DRE->getDecl()->getDeclContext()))
-        InnerBlockDeclRefs.push_back(DRE);
-      if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl()))
-        if (Var->isFunctionOrMethodVarDecl())
-          ImportedLocalExternalDecls.insert(Var);
-    }
-  }
-  
-  return;
-}
-
-/// convertFunctionTypeOfBlocks - This routine converts a function type
-/// whose result type may be a block pointer or whose argument type(s)
-/// might be block pointers to an equivalent function type replacing
-/// all block pointers to function pointers.
-QualType RewriteObjC::convertFunctionTypeOfBlocks(const FunctionType *FT) {
-  const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT);
-  // FTP will be null for closures that don't take arguments.
-  // Generate a funky cast.
-  SmallVector<QualType, 8> ArgTypes;
-  QualType Res = FT->getResultType();
-  bool HasBlockType = convertBlockPointerToFunctionPointer(Res);
-  
-  if (FTP) {
-    for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(),
-         E = FTP->arg_type_end(); I && (I != E); ++I) {
-      QualType t = *I;
-      // Make sure we convert "t (^)(...)" to "t (*)(...)".
-      if (convertBlockPointerToFunctionPointer(t))
-        HasBlockType = true;
-      ArgTypes.push_back(t);
-    }
-  }
-  QualType FuncType;
-  // FIXME. Does this work if block takes no argument but has a return type
-  // which is of block type?
-  if (HasBlockType)
-    FuncType = getSimpleFunctionType(Res, ArgTypes);
-  else FuncType = QualType(FT, 0);
-  return FuncType;
-}
-
-Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp) {
-  // Navigate to relevant type information.
-  const BlockPointerType *CPT = 0;
-
-  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BlockExp)) {
-    CPT = DRE->getType()->getAs<BlockPointerType>();
-  } else if (const MemberExpr *MExpr = dyn_cast<MemberExpr>(BlockExp)) {
-    CPT = MExpr->getType()->getAs<BlockPointerType>();
-  } 
-  else if (const ParenExpr *PRE = dyn_cast<ParenExpr>(BlockExp)) {
-    return SynthesizeBlockCall(Exp, PRE->getSubExpr());
-  }
-  else if (const ImplicitCastExpr *IEXPR = dyn_cast<ImplicitCastExpr>(BlockExp)) 
-    CPT = IEXPR->getType()->getAs<BlockPointerType>();
-  else if (const ConditionalOperator *CEXPR = 
-            dyn_cast<ConditionalOperator>(BlockExp)) {
-    Expr *LHSExp = CEXPR->getLHS();
-    Stmt *LHSStmt = SynthesizeBlockCall(Exp, LHSExp);
-    Expr *RHSExp = CEXPR->getRHS();
-    Stmt *RHSStmt = SynthesizeBlockCall(Exp, RHSExp);
-    Expr *CONDExp = CEXPR->getCond();
-    ConditionalOperator *CondExpr =
-      new (Context) ConditionalOperator(CONDExp,
-                                      SourceLocation(), cast<Expr>(LHSStmt),
-                                      SourceLocation(), cast<Expr>(RHSStmt),
-                                      Exp->getType(), VK_RValue, OK_Ordinary);
-    return CondExpr;
-  } else if (const ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(BlockExp)) {
-    CPT = IRE->getType()->getAs<BlockPointerType>();
-  } else if (const PseudoObjectExpr *POE
-               = dyn_cast<PseudoObjectExpr>(BlockExp)) {
-    CPT = POE->getType()->castAs<BlockPointerType>();
-  } else {
-    assert(1 && "RewriteBlockClass: Bad type");
-  }
-  assert(CPT && "RewriteBlockClass: Bad type");
-  const FunctionType *FT = CPT->getPointeeType()->getAs<FunctionType>();
-  assert(FT && "RewriteBlockClass: Bad type");
-  const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT);
-  // FTP will be null for closures that don't take arguments.
-
-  RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
-                                      SourceLocation(), SourceLocation(),
-                                      &Context->Idents.get("__block_impl"));
-  QualType PtrBlock = Context->getPointerType(Context->getTagDeclType(RD));
-
-  // Generate a funky cast.
-  SmallVector<QualType, 8> ArgTypes;
-
-  // Push the block argument type.
-  ArgTypes.push_back(PtrBlock);
-  if (FTP) {
-    for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(),
-         E = FTP->arg_type_end(); I && (I != E); ++I) {
-      QualType t = *I;
-      // Make sure we convert "t (^)(...)" to "t (*)(...)".
-      if (!convertBlockPointerToFunctionPointer(t))
-        convertToUnqualifiedObjCType(t);
-      ArgTypes.push_back(t);
-    }
-  }
-  // Now do the pointer to function cast.
-  QualType PtrToFuncCastType = getSimpleFunctionType(Exp->getType(), ArgTypes);
-
-  PtrToFuncCastType = Context->getPointerType(PtrToFuncCastType);
-
-  CastExpr *BlkCast = NoTypeInfoCStyleCastExpr(Context, PtrBlock,
-                                               CK_BitCast,
-                                               const_cast<Expr*>(BlockExp));
-  // Don't forget the parens to enforce the proper binding.
-  ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(),
-                                          BlkCast);
-  //PE->dump();
-
-  FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(),
-                                    SourceLocation(),
-                                    &Context->Idents.get("FuncPtr"),
-                                    Context->VoidPtrTy, 0,
-                                    /*BitWidth=*/0, /*Mutable=*/true,
-                                    ICIS_NoInit);
-  MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(),
-                                            FD->getType(), VK_LValue,
-                                            OK_Ordinary);
-
-  
-  CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(Context, PtrToFuncCastType,
-                                                CK_BitCast, ME);
-  PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), FunkCast);
-
-  SmallVector<Expr*, 8> BlkExprs;
-  // Add the implicit argument.
-  BlkExprs.push_back(BlkCast);
-  // Add the user arguments.
-  for (CallExpr::arg_iterator I = Exp->arg_begin(),
-       E = Exp->arg_end(); I != E; ++I) {
-    BlkExprs.push_back(*I);
-  }
-  CallExpr *CE = new (Context) CallExpr(*Context, PE, BlkExprs,
-                                        Exp->getType(), VK_RValue,
-                                        SourceLocation());
-  return CE;
-}
-
-// We need to return the rewritten expression to handle cases where the
-// BlockDeclRefExpr is embedded in another expression being rewritten.
-// For example:
-//
-// int main() {
-//    __block Foo *f;
-//    __block int i;
-//
-//    void (^myblock)() = ^() {
-//        [f test]; // f is a BlockDeclRefExpr embedded in a message (which is being rewritten).
-//        i = 77;
-//    };
-//}
-Stmt *RewriteObjC::RewriteBlockDeclRefExpr(DeclRefExpr *DeclRefExp) {
-  // Rewrite the byref variable into BYREFVAR->__forwarding->BYREFVAR 
-  // for each DeclRefExp where BYREFVAR is name of the variable.
-  ValueDecl *VD = DeclRefExp->getDecl();
-  bool isArrow = DeclRefExp->refersToEnclosingLocal();
-  
-  FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(),
-                                    SourceLocation(),
-                                    &Context->Idents.get("__forwarding"), 
-                                    Context->VoidPtrTy, 0,
-                                    /*BitWidth=*/0, /*Mutable=*/true,
-                                    ICIS_NoInit);
-  MemberExpr *ME = new (Context) MemberExpr(DeclRefExp, isArrow,
-                                            FD, SourceLocation(),
-                                            FD->getType(), VK_LValue,
-                                            OK_Ordinary);
-
-  StringRef Name = VD->getName();
-  FD = FieldDecl::Create(*Context, 0, SourceLocation(), SourceLocation(),
-                         &Context->Idents.get(Name), 
-                         Context->VoidPtrTy, 0,
-                         /*BitWidth=*/0, /*Mutable=*/true,
-                         ICIS_NoInit);
-  ME = new (Context) MemberExpr(ME, true, FD, SourceLocation(),
-                                DeclRefExp->getType(), VK_LValue, OK_Ordinary);
-  
-  
-  
-  // Need parens to enforce precedence.
-  ParenExpr *PE = new (Context) ParenExpr(DeclRefExp->getExprLoc(), 
-                                          DeclRefExp->getExprLoc(), 
-                                          ME);
-  ReplaceStmt(DeclRefExp, PE);
-  return PE;
-}
-
-// Rewrites the imported local variable V with external storage 
-// (static, extern, etc.) as *V
-//
-Stmt *RewriteObjC::RewriteLocalVariableExternalStorage(DeclRefExpr *DRE) {
-  ValueDecl *VD = DRE->getDecl();
-  if (VarDecl *Var = dyn_cast<VarDecl>(VD))
-    if (!ImportedLocalExternalDecls.count(Var))
-      return DRE;
-  Expr *Exp = new (Context) UnaryOperator(DRE, UO_Deref, DRE->getType(),
-                                          VK_LValue, OK_Ordinary,
-                                          DRE->getLocation());
-  // Need parens to enforce precedence.
-  ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 
-                                          Exp);
-  ReplaceStmt(DRE, PE);
-  return PE;
-}
-
-void RewriteObjC::RewriteCastExpr(CStyleCastExpr *CE) {
-  SourceLocation LocStart = CE->getLParenLoc();
-  SourceLocation LocEnd = CE->getRParenLoc();
-
-  // Need to avoid trying to rewrite synthesized casts.
-  if (LocStart.isInvalid())
-    return;
-  // Need to avoid trying to rewrite casts contained in macros.
-  if (!Rewriter::isRewritable(LocStart) || !Rewriter::isRewritable(LocEnd))
-    return;
-
-  const char *startBuf = SM->getCharacterData(LocStart);
-  const char *endBuf = SM->getCharacterData(LocEnd);
-  QualType QT = CE->getType();
-  const Type* TypePtr = QT->getAs<Type>();
-  if (isa<TypeOfExprType>(TypePtr)) {
-    const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
-    QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType();
-    std::string TypeAsString = "(";
-    RewriteBlockPointerType(TypeAsString, QT);
-    TypeAsString += ")";
-    ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString);
-    return;
-  }
-  // advance the location to startArgList.
-  const char *argPtr = startBuf;
-
-  while (*argPtr++ && (argPtr < endBuf)) {
-    switch (*argPtr) {
-    case '^':
-      // Replace the '^' with '*'.
-      LocStart = LocStart.getLocWithOffset(argPtr-startBuf);
-      ReplaceText(LocStart, 1, "*");
-      break;
-    }
-  }
-  return;
-}
-
-void RewriteObjC::RewriteBlockPointerFunctionArgs(FunctionDecl *FD) {
-  SourceLocation DeclLoc = FD->getLocation();
-  unsigned parenCount = 0;
-
-  // We have 1 or more arguments that have closure pointers.
-  const char *startBuf = SM->getCharacterData(DeclLoc);
-  const char *startArgList = strchr(startBuf, '(');
-
-  assert((*startArgList == '(') && "Rewriter fuzzy parser confused");
-
-  parenCount++;
-  // advance the location to startArgList.
-  DeclLoc = DeclLoc.getLocWithOffset(startArgList-startBuf);
-  assert((DeclLoc.isValid()) && "Invalid DeclLoc");
-
-  const char *argPtr = startArgList;
-
-  while (*argPtr++ && parenCount) {
-    switch (*argPtr) {
-    case '^':
-      // Replace the '^' with '*'.
-      DeclLoc = DeclLoc.getLocWithOffset(argPtr-startArgList);
-      ReplaceText(DeclLoc, 1, "*");
-      break;
-    case '(':
-      parenCount++;
-      break;
-    case ')':
-      parenCount--;
-      break;
-    }
-  }
-  return;
-}
-
-bool RewriteObjC::PointerTypeTakesAnyBlockArguments(QualType QT) {
-  const FunctionProtoType *FTP;
-  const PointerType *PT = QT->getAs<PointerType>();
-  if (PT) {
-    FTP = PT->getPointeeType()->getAs<FunctionProtoType>();
-  } else {
-    const BlockPointerType *BPT = QT->getAs<BlockPointerType>();
-    assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
-    FTP = BPT->getPointeeType()->getAs<FunctionProtoType>();
-  }
-  if (FTP) {
-    for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(),
-         E = FTP->arg_type_end(); I != E; ++I)
-      if (isTopLevelBlockPointerType(*I))
-        return true;
-  }
-  return false;
-}
-
-bool RewriteObjC::PointerTypeTakesAnyObjCQualifiedType(QualType QT) {
-  const FunctionProtoType *FTP;
-  const PointerType *PT = QT->getAs<PointerType>();
-  if (PT) {
-    FTP = PT->getPointeeType()->getAs<FunctionProtoType>();
-  } else {
-    const BlockPointerType *BPT = QT->getAs<BlockPointerType>();
-    assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
-    FTP = BPT->getPointeeType()->getAs<FunctionProtoType>();
-  }
-  if (FTP) {
-    for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(),
-         E = FTP->arg_type_end(); I != E; ++I) {
-      if ((*I)->isObjCQualifiedIdType())
-        return true;
-      if ((*I)->isObjCObjectPointerType() &&
-          (*I)->getPointeeType()->isObjCQualifiedInterfaceType())
-        return true;
-    }
-        
-  }
-  return false;
-}
-
-void RewriteObjC::GetExtentOfArgList(const char *Name, const char *&LParen,
-                                     const char *&RParen) {
-  const char *argPtr = strchr(Name, '(');
-  assert((*argPtr == '(') && "Rewriter fuzzy parser confused");
-
-  LParen = argPtr; // output the start.
-  argPtr++; // skip past the left paren.
-  unsigned parenCount = 1;
-
-  while (*argPtr && parenCount) {
-    switch (*argPtr) {
-    case '(': parenCount++; break;
-    case ')': parenCount--; break;
-    default: break;
-    }
-    if (parenCount) argPtr++;
-  }
-  assert((*argPtr == ')') && "Rewriter fuzzy parser confused");
-  RParen = argPtr; // output the end
-}
-
-void RewriteObjC::RewriteBlockPointerDecl(NamedDecl *ND) {
-  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
-    RewriteBlockPointerFunctionArgs(FD);
-    return;
-  }
-  // Handle Variables and Typedefs.
-  SourceLocation DeclLoc = ND->getLocation();
-  QualType DeclT;
-  if (VarDecl *VD = dyn_cast<VarDecl>(ND))
-    DeclT = VD->getType();
-  else if (TypedefNameDecl *TDD = dyn_cast<TypedefNameDecl>(ND))
-    DeclT = TDD->getUnderlyingType();
-  else if (FieldDecl *FD = dyn_cast<FieldDecl>(ND))
-    DeclT = FD->getType();
-  else
-    llvm_unreachable("RewriteBlockPointerDecl(): Decl type not yet handled");
-
-  const char *startBuf = SM->getCharacterData(DeclLoc);
-  const char *endBuf = startBuf;
-  // scan backward (from the decl location) for the end of the previous decl.
-  while (*startBuf != '^' && *startBuf != ';' && startBuf != MainFileStart)
-    startBuf--;
-  SourceLocation Start = DeclLoc.getLocWithOffset(startBuf-endBuf);
-  std::string buf;
-  unsigned OrigLength=0;
-  // *startBuf != '^' if we are dealing with a pointer to function that
-  // may take block argument types (which will be handled below).
-  if (*startBuf == '^') {
-    // Replace the '^' with '*', computing a negative offset.
-    buf = '*';
-    startBuf++;
-    OrigLength++;
-  }
-  while (*startBuf != ')') {
-    buf += *startBuf;
-    startBuf++;
-    OrigLength++;
-  }
-  buf += ')';
-  OrigLength++;
-  
-  if (PointerTypeTakesAnyBlockArguments(DeclT) ||
-      PointerTypeTakesAnyObjCQualifiedType(DeclT)) {
-    // Replace the '^' with '*' for arguments.
-    // Replace id<P> with id/*<>*/
-    DeclLoc = ND->getLocation();
-    startBuf = SM->getCharacterData(DeclLoc);
-    const char *argListBegin, *argListEnd;
-    GetExtentOfArgList(startBuf, argListBegin, argListEnd);
-    while (argListBegin < argListEnd) {
-      if (*argListBegin == '^')
-        buf += '*';
-      else if (*argListBegin ==  '<') {
-        buf += "/*"; 
-        buf += *argListBegin++;
-        OrigLength++;
-        while (*argListBegin != '>') {
-          buf += *argListBegin++;
-          OrigLength++;
-        }
-        buf += *argListBegin;
-        buf += "*/";
-      }
-      else
-        buf += *argListBegin;
-      argListBegin++;
-      OrigLength++;
-    }
-    buf += ')';
-    OrigLength++;
-  }
-  ReplaceText(Start, OrigLength, buf);
-  
-  return;
-}
-
-
-/// SynthesizeByrefCopyDestroyHelper - This routine synthesizes:
-/// void __Block_byref_id_object_copy(struct Block_byref_id_object *dst,
-///                    struct Block_byref_id_object *src) {
-///  _Block_object_assign (&_dest->object, _src->object, 
-///                        BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT
-///                        [|BLOCK_FIELD_IS_WEAK]) // object
-///  _Block_object_assign(&_dest->object, _src->object, 
-///                       BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK
-///                       [|BLOCK_FIELD_IS_WEAK]) // block
-/// }
-/// And:
-/// void __Block_byref_id_object_dispose(struct Block_byref_id_object *_src) {
-///  _Block_object_dispose(_src->object, 
-///                        BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT
-///                        [|BLOCK_FIELD_IS_WEAK]) // object
-///  _Block_object_dispose(_src->object, 
-///                         BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK
-///                         [|BLOCK_FIELD_IS_WEAK]) // block
-/// }
-
-std::string RewriteObjC::SynthesizeByrefCopyDestroyHelper(VarDecl *VD,
-                                                          int flag) {
-  std::string S;
-  if (CopyDestroyCache.count(flag))
-    return S;
-  CopyDestroyCache.insert(flag);
-  S = "static void __Block_byref_id_object_copy_";
-  S += utostr(flag);
-  S += "(void *dst, void *src) {\n";
-  
-  // offset into the object pointer is computed as:
-  // void * + void* + int + int + void* + void *
-  unsigned IntSize = 
-  static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
-  unsigned VoidPtrSize = 
-  static_cast<unsigned>(Context->getTypeSize(Context->VoidPtrTy));
-  
-  unsigned offset = (VoidPtrSize*4 + IntSize + IntSize)/Context->getCharWidth();
-  S += " _Block_object_assign((char*)dst + ";
-  S += utostr(offset);
-  S += ", *(void * *) ((char*)src + ";
-  S += utostr(offset);
-  S += "), ";
-  S += utostr(flag);
-  S += ");\n}\n";
-  
-  S += "static void __Block_byref_id_object_dispose_";
-  S += utostr(flag);
-  S += "(void *src) {\n";
-  S += " _Block_object_dispose(*(void * *) ((char*)src + ";
-  S += utostr(offset);
-  S += "), ";
-  S += utostr(flag);
-  S += ");\n}\n";
-  return S;
-}
-
-/// RewriteByRefVar - For each __block typex ND variable this routine transforms
-/// the declaration into:
-/// struct __Block_byref_ND {
-/// void *__isa;                  // NULL for everything except __weak pointers
-/// struct __Block_byref_ND *__forwarding;
-/// int32_t __flags;
-/// int32_t __size;
-/// void *__Block_byref_id_object_copy; // If variable is __block ObjC object
-/// void *__Block_byref_id_object_dispose; // If variable is __block ObjC object
-/// typex ND;
-/// };
-///
-/// It then replaces declaration of ND variable with:
-/// struct __Block_byref_ND ND = {__isa=0B, __forwarding=&ND, __flags=some_flag, 
-///                               __size=sizeof(struct __Block_byref_ND), 
-///                               ND=initializer-if-any};
-///
-///
-void RewriteObjC::RewriteByRefVar(VarDecl *ND) {
-  // Insert declaration for the function in which block literal is
-  // used.
-  if (CurFunctionDeclToDeclareForBlock)
-    RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock);
-  int flag = 0;
-  int isa = 0;
-  SourceLocation DeclLoc = ND->getTypeSpecStartLoc();
-  if (DeclLoc.isInvalid())
-    // If type location is missing, it is because of missing type (a warning).
-    // Use variable's location which is good for this case.
-    DeclLoc = ND->getLocation();
-  const char *startBuf = SM->getCharacterData(DeclLoc);
-  SourceLocation X = ND->getLocEnd();
-  X = SM->getExpansionLoc(X);
-  const char *endBuf = SM->getCharacterData(X);
-  std::string Name(ND->getNameAsString());
-  std::string ByrefType;
-  RewriteByRefString(ByrefType, Name, ND, true);
-  ByrefType += " {\n";
-  ByrefType += "  void *__isa;\n";
-  RewriteByRefString(ByrefType, Name, ND);
-  ByrefType += " *__forwarding;\n";
-  ByrefType += " int __flags;\n";
-  ByrefType += " int __size;\n";
-  // Add void *__Block_byref_id_object_copy; 
-  // void *__Block_byref_id_object_dispose; if needed.
-  QualType Ty = ND->getType();
-  bool HasCopyAndDispose = Context->BlockRequiresCopying(Ty, ND);
-  if (HasCopyAndDispose) {
-    ByrefType += " void (*__Block_byref_id_object_copy)(void*, void*);\n";
-    ByrefType += " void (*__Block_byref_id_object_dispose)(void*);\n";
-  }
-
-  QualType T = Ty;
-  (void)convertBlockPointerToFunctionPointer(T);
-  T.getAsStringInternal(Name, Context->getPrintingPolicy());
-    
-  ByrefType += " " + Name + ";\n";
-  ByrefType += "};\n";
-  // Insert this type in global scope. It is needed by helper function.
-  SourceLocation FunLocStart;
-  if (CurFunctionDef)
-     FunLocStart = CurFunctionDef->getTypeSpecStartLoc();
-  else {
-    assert(CurMethodDef && "RewriteByRefVar - CurMethodDef is null");
-    FunLocStart = CurMethodDef->getLocStart();
-  }
-  InsertText(FunLocStart, ByrefType);
-  if (Ty.isObjCGCWeak()) {
-    flag |= BLOCK_FIELD_IS_WEAK;
-    isa = 1;
-  }
-  
-  if (HasCopyAndDispose) {
-    flag = BLOCK_BYREF_CALLER;
-    QualType Ty = ND->getType();
-    // FIXME. Handle __weak variable (BLOCK_FIELD_IS_WEAK) as well.
-    if (Ty->isBlockPointerType())
-      flag |= BLOCK_FIELD_IS_BLOCK;
-    else
-      flag |= BLOCK_FIELD_IS_OBJECT;
-    std::string HF = SynthesizeByrefCopyDestroyHelper(ND, flag);
-    if (!HF.empty())
-      InsertText(FunLocStart, HF);
-  }
-  
-  // struct __Block_byref_ND ND = 
-  // {0, &ND, some_flag, __size=sizeof(struct __Block_byref_ND), 
-  //  initializer-if-any};
-  bool hasInit = (ND->getInit() != 0);
-  unsigned flags = 0;
-  if (HasCopyAndDispose)
-    flags |= BLOCK_HAS_COPY_DISPOSE;
-  Name = ND->getNameAsString();
-  ByrefType.clear();
-  RewriteByRefString(ByrefType, Name, ND);
-  std::string ForwardingCastType("(");
-  ForwardingCastType += ByrefType + " *)";
-  if (!hasInit) {
-    ByrefType += " " + Name + " = {(void*)";
-    ByrefType += utostr(isa);
-    ByrefType += "," +  ForwardingCastType + "&" + Name + ", ";
-    ByrefType += utostr(flags);
-    ByrefType += ", ";
-    ByrefType += "sizeof(";
-    RewriteByRefString(ByrefType, Name, ND);
-    ByrefType += ")";
-    if (HasCopyAndDispose) {
-      ByrefType += ", __Block_byref_id_object_copy_";
-      ByrefType += utostr(flag);
-      ByrefType += ", __Block_byref_id_object_dispose_";
-      ByrefType += utostr(flag);
-    }
-    ByrefType += "};\n";
-    unsigned nameSize = Name.size();
-    // for block or function pointer declaration. Name is aleady
-    // part of the declaration.
-    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType())
-      nameSize = 1;
-    ReplaceText(DeclLoc, endBuf-startBuf+nameSize, ByrefType);
-  }
-  else {
-    SourceLocation startLoc;
-    Expr *E = ND->getInit();
-    if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E))
-      startLoc = ECE->getLParenLoc();
-    else
-      startLoc = E->getLocStart();
-    startLoc = SM->getExpansionLoc(startLoc);
-    endBuf = SM->getCharacterData(startLoc);
-    ByrefType += " " + Name;
-    ByrefType += " = {(void*)";
-    ByrefType += utostr(isa);
-    ByrefType += "," +  ForwardingCastType + "&" + Name + ", ";
-    ByrefType += utostr(flags);
-    ByrefType += ", ";
-    ByrefType += "sizeof(";
-    RewriteByRefString(ByrefType, Name, ND);
-    ByrefType += "), ";
-    if (HasCopyAndDispose) {
-      ByrefType += "__Block_byref_id_object_copy_";
-      ByrefType += utostr(flag);
-      ByrefType += ", __Block_byref_id_object_dispose_";
-      ByrefType += utostr(flag);
-      ByrefType += ", ";
-    }
-    ReplaceText(DeclLoc, endBuf-startBuf, ByrefType);
-    
-    // Complete the newly synthesized compound expression by inserting a right
-    // curly brace before the end of the declaration.
-    // FIXME: This approach avoids rewriting the initializer expression. It
-    // also assumes there is only one declarator. For example, the following
-    // isn't currently supported by this routine (in general):
-    // 
-    // double __block BYREFVAR = 1.34, BYREFVAR2 = 1.37;
-    //
-    const char *startInitializerBuf = SM->getCharacterData(startLoc);
-    const char *semiBuf = strchr(startInitializerBuf, ';');
-    assert((*semiBuf == ';') && "RewriteByRefVar: can't find ';'");
-    SourceLocation semiLoc =
-      startLoc.getLocWithOffset(semiBuf-startInitializerBuf);
-
-    InsertText(semiLoc, "}");
-  }
-  return;
-}
-
-void RewriteObjC::CollectBlockDeclRefInfo(BlockExpr *Exp) {
-  // Add initializers for any closure decl refs.
-  GetBlockDeclRefExprs(Exp->getBody());
-  if (BlockDeclRefs.size()) {
-    // Unique all "by copy" declarations.
-    for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
-      if (!BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
-        if (!BlockByCopyDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
-          BlockByCopyDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
-          BlockByCopyDecls.push_back(BlockDeclRefs[i]->getDecl());
-        }
-      }
-    // Unique all "by ref" declarations.
-    for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
-      if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
-        if (!BlockByRefDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
-          BlockByRefDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
-          BlockByRefDecls.push_back(BlockDeclRefs[i]->getDecl());
-        }
-      }
-    // Find any imported blocks...they will need special attention.
-    for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
-      if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
-          BlockDeclRefs[i]->getType()->isObjCObjectPointerType() || 
-          BlockDeclRefs[i]->getType()->isBlockPointerType())
-        ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl());
-  }
-}
-
-FunctionDecl *RewriteObjC::SynthBlockInitFunctionDecl(StringRef name) {
-  IdentifierInfo *ID = &Context->Idents.get(name);
-  QualType FType = Context->getFunctionNoProtoType(Context->VoidPtrTy);
-  return FunctionDecl::Create(*Context, TUDecl, SourceLocation(),
-                              SourceLocation(), ID, FType, 0, SC_Extern,
-                              false, false);
-}
-
-Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp,
-                     const SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs) {
-  const BlockDecl *block = Exp->getBlockDecl();
-  Blocks.push_back(Exp);
-
-  CollectBlockDeclRefInfo(Exp);
-  
-  // Add inner imported variables now used in current block.
- int countOfInnerDecls = 0;
-  if (!InnerBlockDeclRefs.empty()) {
-    for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) {
-      DeclRefExpr *Exp = InnerBlockDeclRefs[i];
-      ValueDecl *VD = Exp->getDecl();
-      if (!VD->hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) {
-      // We need to save the copied-in variables in nested
-      // blocks because it is needed at the end for some of the API generations.
-      // See SynthesizeBlockLiterals routine.
-        InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
-        BlockDeclRefs.push_back(Exp);
-        BlockByCopyDeclsPtrSet.insert(VD);
-        BlockByCopyDecls.push_back(VD);
-      }
-      if (VD->hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) {
-        InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
-        BlockDeclRefs.push_back(Exp);
-        BlockByRefDeclsPtrSet.insert(VD);
-        BlockByRefDecls.push_back(VD);
-      }
-    }
-    // Find any imported blocks...they will need special attention.
-    for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++)
-      if (InnerBlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
-          InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() || 
-          InnerBlockDeclRefs[i]->getType()->isBlockPointerType())
-        ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl());
-  }
-  InnerDeclRefsCount.push_back(countOfInnerDecls);
-  
-  std::string FuncName;
-
-  if (CurFunctionDef)
-    FuncName = CurFunctionDef->getNameAsString();
-  else if (CurMethodDef)
-    BuildUniqueMethodName(FuncName, CurMethodDef);
-  else if (GlobalVarDecl)
-    FuncName = std::string(GlobalVarDecl->getNameAsString());
-
-  std::string BlockNumber = utostr(Blocks.size()-1);
-
-  std::string Tag = "__" + FuncName + "_block_impl_" + BlockNumber;
-  std::string Func = "__" + FuncName + "_block_func_" + BlockNumber;
-
-  // Get a pointer to the function type so we can cast appropriately.
-  QualType BFT = convertFunctionTypeOfBlocks(Exp->getFunctionType());
-  QualType FType = Context->getPointerType(BFT);
-
-  FunctionDecl *FD;
-  Expr *NewRep;
-
-  // Simulate a constructor call...
-  FD = SynthBlockInitFunctionDecl(Tag);
-  DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, false, FType, VK_RValue,
-                                               SourceLocation());
-
-  SmallVector<Expr*, 4> InitExprs;
-
-  // Initialize the block function.
-  FD = SynthBlockInitFunctionDecl(Func);
-  DeclRefExpr *Arg = new (Context) DeclRefExpr(FD, false, FD->getType(),
-                                               VK_LValue, SourceLocation());
-  CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
-                                                CK_BitCast, Arg);
-  InitExprs.push_back(castExpr);
-
-  // Initialize the block descriptor.
-  std::string DescData = "__" + FuncName + "_block_desc_" + BlockNumber + "_DATA";
-
-  VarDecl *NewVD = VarDecl::Create(*Context, TUDecl,
-                                   SourceLocation(), SourceLocation(),
-                                   &Context->Idents.get(DescData.c_str()),
-                                   Context->VoidPtrTy, 0,
-                                   SC_Static);
-  UnaryOperator *DescRefExpr =
-    new (Context) UnaryOperator(new (Context) DeclRefExpr(NewVD, false,
-                                                          Context->VoidPtrTy,
-                                                          VK_LValue,
-                                                          SourceLocation()), 
-                                UO_AddrOf,
-                                Context->getPointerType(Context->VoidPtrTy), 
-                                VK_RValue, OK_Ordinary,
-                                SourceLocation());
-  InitExprs.push_back(DescRefExpr); 
-  
-  // Add initializers for any closure decl refs.
-  if (BlockDeclRefs.size()) {
-    Expr *Exp;
-    // Output all "by copy" declarations.
-    for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(),
-         E = BlockByCopyDecls.end(); I != E; ++I) {
-      if (isObjCType((*I)->getType())) {
-        // FIXME: Conform to ABI ([[obj retain] autorelease]).
-        FD = SynthBlockInitFunctionDecl((*I)->getName());
-        Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue,
-                                        SourceLocation());
-        if (HasLocalVariableExternalStorage(*I)) {
-          QualType QT = (*I)->getType();
-          QT = Context->getPointerType(QT);
-          Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue,
-                                            OK_Ordinary, SourceLocation());
-        }
-      } else if (isTopLevelBlockPointerType((*I)->getType())) {
-        FD = SynthBlockInitFunctionDecl((*I)->getName());
-        Arg = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue,
-                                        SourceLocation());
-        Exp = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
-                                       CK_BitCast, Arg);
-      } else {
-        FD = SynthBlockInitFunctionDecl((*I)->getName());
-        Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue,
-                                        SourceLocation());
-        if (HasLocalVariableExternalStorage(*I)) {
-          QualType QT = (*I)->getType();
-          QT = Context->getPointerType(QT);
-          Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue,
-                                            OK_Ordinary, SourceLocation());
-        }
-        
-      }
-      InitExprs.push_back(Exp);
-    }
-    // Output all "by ref" declarations.
-    for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(),
-         E = BlockByRefDecls.end(); I != E; ++I) {
-      ValueDecl *ND = (*I);
-      std::string Name(ND->getNameAsString());
-      std::string RecName;
-      RewriteByRefString(RecName, Name, ND, true);
-      IdentifierInfo *II = &Context->Idents.get(RecName.c_str() 
-                                                + sizeof("struct"));
-      RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
-                                          SourceLocation(), SourceLocation(),
-                                          II);
-      assert(RD && "SynthBlockInitExpr(): Can't find RecordDecl");
-      QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
-      
-      FD = SynthBlockInitFunctionDecl((*I)->getName());
-      Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue,
-                                      SourceLocation());
-      bool isNestedCapturedVar = false;
-      if (block)
-        for (BlockDecl::capture_const_iterator ci = block->capture_begin(),
-             ce = block->capture_end(); ci != ce; ++ci) {
-          const VarDecl *variable = ci->getVariable();
-          if (variable == ND && ci->isNested()) {
-            assert (ci->isByRef() && 
-                    "SynthBlockInitExpr - captured block variable is not byref");
-            isNestedCapturedVar = true;
-            break;
-          }
-        }
-      // captured nested byref variable has its address passed. Do not take
-      // its address again.
-      if (!isNestedCapturedVar)
-          Exp = new (Context) UnaryOperator(Exp, UO_AddrOf,
-                                     Context->getPointerType(Exp->getType()),
-                                     VK_RValue, OK_Ordinary, SourceLocation());
-      Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp);
-      InitExprs.push_back(Exp);
-    }
-  }
-  if (ImportedBlockDecls.size()) {
-    // generate BLOCK_HAS_COPY_DISPOSE(have helper funcs) | BLOCK_HAS_DESCRIPTOR
-    int flag = (BLOCK_HAS_COPY_DISPOSE | BLOCK_HAS_DESCRIPTOR);
-    unsigned IntSize = 
-      static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
-    Expr *FlagExp = IntegerLiteral::Create(*Context, llvm::APInt(IntSize, flag), 
-                                           Context->IntTy, SourceLocation());
-    InitExprs.push_back(FlagExp);
-  }
-  NewRep = new (Context) CallExpr(*Context, DRE, InitExprs,
-                                  FType, VK_LValue, SourceLocation());
-  NewRep = new (Context) UnaryOperator(NewRep, UO_AddrOf,
-                             Context->getPointerType(NewRep->getType()),
-                             VK_RValue, OK_Ordinary, SourceLocation());
-  NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast,
-                                    NewRep);
-  BlockDeclRefs.clear();
-  BlockByRefDecls.clear();
-  BlockByRefDeclsPtrSet.clear();
-  BlockByCopyDecls.clear();
-  BlockByCopyDeclsPtrSet.clear();
-  ImportedBlockDecls.clear();
-  return NewRep;
-}
-
-bool RewriteObjC::IsDeclStmtInForeachHeader(DeclStmt *DS) {
-  if (const ObjCForCollectionStmt * CS = 
-      dyn_cast<ObjCForCollectionStmt>(Stmts.back()))
-        return CS->getElement() == DS;
-  return false;
-}
-
-//===----------------------------------------------------------------------===//
-// Function Body / Expression rewriting
-//===----------------------------------------------------------------------===//
-
-Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) {
-  if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
-      isa<DoStmt>(S) || isa<ForStmt>(S))
-    Stmts.push_back(S);
-  else if (isa<ObjCForCollectionStmt>(S)) {
-    Stmts.push_back(S);
-    ObjCBcLabelNo.push_back(++BcLabelCount);
-  }
-
-  // Pseudo-object operations and ivar references need special
-  // treatment because we're going to recursively rewrite them.
-  if (PseudoObjectExpr *PseudoOp = dyn_cast<PseudoObjectExpr>(S)) {
-    if (isa<BinaryOperator>(PseudoOp->getSyntacticForm())) {
-      return RewritePropertyOrImplicitSetter(PseudoOp);
-    } else {
-      return RewritePropertyOrImplicitGetter(PseudoOp);
-    }
-  } else if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) {
-    return RewriteObjCIvarRefExpr(IvarRefExpr);
-  }
-
-  SourceRange OrigStmtRange = S->getSourceRange();
-
-  // Perform a bottom up rewrite of all children.
-  for (Stmt::child_range CI = S->children(); CI; ++CI)
-    if (*CI) {
-      Stmt *childStmt = (*CI);
-      Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(childStmt);
-      if (newStmt) {
-        *CI = newStmt;
-      }
-    }
-
-  if (BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
-    SmallVector<DeclRefExpr *, 8> InnerBlockDeclRefs;
-    llvm::SmallPtrSet<const DeclContext *, 8> InnerContexts;
-    InnerContexts.insert(BE->getBlockDecl());
-    ImportedLocalExternalDecls.clear();
-    GetInnerBlockDeclRefExprs(BE->getBody(),
-                              InnerBlockDeclRefs, InnerContexts);
-    // Rewrite the block body in place.
-    Stmt *SaveCurrentBody = CurrentBody;
-    CurrentBody = BE->getBody();
-    PropParentMap = 0;
-    // block literal on rhs of a property-dot-sytax assignment
-    // must be replaced by its synthesize ast so getRewrittenText
-    // works as expected. In this case, what actually ends up on RHS
-    // is the blockTranscribed which is the helper function for the
-    // block literal; as in: self.c = ^() {[ace ARR];};
-    bool saveDisableReplaceStmt = DisableReplaceStmt;
-    DisableReplaceStmt = false;
-    RewriteFunctionBodyOrGlobalInitializer(BE->getBody());
-    DisableReplaceStmt = saveDisableReplaceStmt;
-    CurrentBody = SaveCurrentBody;
-    PropParentMap = 0;
-    ImportedLocalExternalDecls.clear();
-    // Now we snarf the rewritten text and stash it away for later use.
-    std::string Str = Rewrite.getRewrittenText(BE->getSourceRange());
-    RewrittenBlockExprs[BE] = Str;
-
-    Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs);
-                            
-    //blockTranscribed->dump();
-    ReplaceStmt(S, blockTranscribed);
-    return blockTranscribed;
-  }
-  // Handle specific things.
-  if (ObjCEncodeExpr *AtEncode = dyn_cast<ObjCEncodeExpr>(S))
-    return RewriteAtEncode(AtEncode);
-
-  if (ObjCSelectorExpr *AtSelector = dyn_cast<ObjCSelectorExpr>(S))
-    return RewriteAtSelector(AtSelector);
-
-  if (ObjCStringLiteral *AtString = dyn_cast<ObjCStringLiteral>(S))
-    return RewriteObjCStringLiteral(AtString);
-
-  if (ObjCMessageExpr *MessExpr = dyn_cast<ObjCMessageExpr>(S)) {
-#if 0
-    // Before we rewrite it, put the original message expression in a comment.
-    SourceLocation startLoc = MessExpr->getLocStart();
-    SourceLocation endLoc = MessExpr->getLocEnd();
-
-    const char *startBuf = SM->getCharacterData(startLoc);
-    const char *endBuf = SM->getCharacterData(endLoc);
-
-    std::string messString;
-    messString += "// ";
-    messString.append(startBuf, endBuf-startBuf+1);
-    messString += "\n";
-
-    // FIXME: Missing definition of
-    // InsertText(clang::SourceLocation, char const*, unsigned int).
-    // InsertText(startLoc, messString.c_str(), messString.size());
-    // Tried this, but it didn't work either...
-    // ReplaceText(startLoc, 0, messString.c_str(), messString.size());
-#endif
-    return RewriteMessageExpr(MessExpr);
-  }
-
-  if (ObjCAtTryStmt *StmtTry = dyn_cast<ObjCAtTryStmt>(S))
-    return RewriteObjCTryStmt(StmtTry);
-
-  if (ObjCAtSynchronizedStmt *StmtTry = dyn_cast<ObjCAtSynchronizedStmt>(S))
-    return RewriteObjCSynchronizedStmt(StmtTry);
-
-  if (ObjCAtThrowStmt *StmtThrow = dyn_cast<ObjCAtThrowStmt>(S))
-    return RewriteObjCThrowStmt(StmtThrow);
-
-  if (ObjCProtocolExpr *ProtocolExp = dyn_cast<ObjCProtocolExpr>(S))
-    return RewriteObjCProtocolExpr(ProtocolExp);
-
-  if (ObjCForCollectionStmt *StmtForCollection =
-        dyn_cast<ObjCForCollectionStmt>(S))
-    return RewriteObjCForCollectionStmt(StmtForCollection,
-                                        OrigStmtRange.getEnd());
-  if (BreakStmt *StmtBreakStmt =
-      dyn_cast<BreakStmt>(S))
-    return RewriteBreakStmt(StmtBreakStmt);
-  if (ContinueStmt *StmtContinueStmt =
-      dyn_cast<ContinueStmt>(S))
-    return RewriteContinueStmt(StmtContinueStmt);
-
-  // Need to check for protocol refs (id <P>, Foo <P> *) in variable decls
-  // and cast exprs.
-  if (DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
-    // FIXME: What we're doing here is modifying the type-specifier that
-    // precedes the first Decl.  In the future the DeclGroup should have
-    // a separate type-specifier that we can rewrite.
-    // NOTE: We need to avoid rewriting the DeclStmt if it is within
-    // the context of an ObjCForCollectionStmt. For example:
-    //   NSArray *someArray;
-    //   for (id <FooProtocol> index in someArray) ;
-    // This is because RewriteObjCForCollectionStmt() does textual rewriting 
-    // and it depends on the original text locations/positions.
-    if (Stmts.empty() || !IsDeclStmtInForeachHeader(DS))
-      RewriteObjCQualifiedInterfaceTypes(*DS->decl_begin());
-
-    // Blocks rewrite rules.
-    for (DeclStmt::decl_iterator DI = DS->decl_begin(), DE = DS->decl_end();
-         DI != DE; ++DI) {
-      Decl *SD = *DI;
-      if (ValueDecl *ND = dyn_cast<ValueDecl>(SD)) {
-        if (isTopLevelBlockPointerType(ND->getType()))
-          RewriteBlockPointerDecl(ND);
-        else if (ND->getType()->isFunctionPointerType())
-          CheckFunctionPointerDecl(ND->getType(), ND);
-        if (VarDecl *VD = dyn_cast<VarDecl>(SD)) {
-          if (VD->hasAttr<BlocksAttr>()) {
-            static unsigned uniqueByrefDeclCount = 0;
-            assert(!BlockByRefDeclNo.count(ND) &&
-              "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl");
-            BlockByRefDeclNo[ND] = uniqueByrefDeclCount++;
-            RewriteByRefVar(VD);
-          }
-          else           
-            RewriteTypeOfDecl(VD);
-        }
-      }
-      if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(SD)) {
-        if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
-          RewriteBlockPointerDecl(TD);
-        else if (TD->getUnderlyingType()->isFunctionPointerType())
-          CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
-      }
-    }
-  }
-
-  if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(S))
-    RewriteObjCQualifiedInterfaceTypes(CE);
-
-  if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
-      isa<DoStmt>(S) || isa<ForStmt>(S)) {
-    assert(!Stmts.empty() && "Statement stack is empty");
-    assert ((isa<SwitchStmt>(Stmts.back()) || isa<WhileStmt>(Stmts.back()) ||
-             isa<DoStmt>(Stmts.back()) || isa<ForStmt>(Stmts.back()))
-            && "Statement stack mismatch");
-    Stmts.pop_back();
-  }
-  // Handle blocks rewriting.
-  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
-    ValueDecl *VD = DRE->getDecl(); 
-    if (VD->hasAttr<BlocksAttr>())
-      return RewriteBlockDeclRefExpr(DRE);
-    if (HasLocalVariableExternalStorage(VD))
-      return RewriteLocalVariableExternalStorage(DRE);
-  }
-  
-  if (CallExpr *CE = dyn_cast<CallExpr>(S)) {
-    if (CE->getCallee()->getType()->isBlockPointerType()) {
-      Stmt *BlockCall = SynthesizeBlockCall(CE, CE->getCallee());
-      ReplaceStmt(S, BlockCall);
-      return BlockCall;
-    }
-  }
-  if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(S)) {
-    RewriteCastExpr(CE);
-  }
-#if 0
-  if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(S)) {
-    CastExpr *Replacement = new (Context) CastExpr(ICE->getType(),
-                                                   ICE->getSubExpr(),
-                                                   SourceLocation());
-    // Get the new text.
-    std::string SStr;
-    llvm::raw_string_ostream Buf(SStr);
-    Replacement->printPretty(Buf);
-    const std::string &Str = Buf.str();
-
-    printf("CAST = %s\n", &Str[0]);
-    InsertText(ICE->getSubExpr()->getLocStart(), &Str[0], Str.size());
-    delete S;
-    return Replacement;
-  }
-#endif
-  // Return this stmt unmodified.
-  return S;
-}
-
-void RewriteObjC::RewriteRecordBody(RecordDecl *RD) {
-  for (RecordDecl::field_iterator i = RD->field_begin(), 
-                                  e = RD->field_end(); i != e; ++i) {
-    FieldDecl *FD = *i;
-    if (isTopLevelBlockPointerType(FD->getType()))
-      RewriteBlockPointerDecl(FD);
-    if (FD->getType()->isObjCQualifiedIdType() ||
-        FD->getType()->isObjCQualifiedInterfaceType())
-      RewriteObjCQualifiedInterfaceTypes(FD);
-  }
-}
-
-/// HandleDeclInMainFile - This is called for each top-level decl defined in the
-/// main file of the input.
-void RewriteObjC::HandleDeclInMainFile(Decl *D) {
-  switch (D->getKind()) {
-    case Decl::Function: {
-      FunctionDecl *FD = cast<FunctionDecl>(D);
-      if (FD->isOverloadedOperator())
-        return;
-
-      // Since function prototypes don't have ParmDecl's, we check the function
-      // prototype. This enables us to rewrite function declarations and
-      // definitions using the same code.
-      RewriteBlocksInFunctionProtoType(FD->getType(), FD);
-
-      if (!FD->isThisDeclarationADefinition())
-        break;
-
-      // FIXME: If this should support Obj-C++, support CXXTryStmt
-      if (CompoundStmt *Body = dyn_cast_or_null<CompoundStmt>(FD->getBody())) {
-        CurFunctionDef = FD;
-        CurFunctionDeclToDeclareForBlock = FD;
-        CurrentBody = Body;
-        Body =
-        cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
-        FD->setBody(Body);
-        CurrentBody = 0;
-        if (PropParentMap) {
-          delete PropParentMap;
-          PropParentMap = 0;
-        }
-        // This synthesizes and inserts the block "impl" struct, invoke function,
-        // and any copy/dispose helper functions.
-        InsertBlockLiteralsWithinFunction(FD);
-        CurFunctionDef = 0;
-        CurFunctionDeclToDeclareForBlock = 0;
-      }
-      break;
-    }
-    case Decl::ObjCMethod: {
-      ObjCMethodDecl *MD = cast<ObjCMethodDecl>(D);
-      if (CompoundStmt *Body = MD->getCompoundBody()) {
-        CurMethodDef = MD;
-        CurrentBody = Body;
-        Body =
-          cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
-        MD->setBody(Body);
-        CurrentBody = 0;
-        if (PropParentMap) {
-          delete PropParentMap;
-          PropParentMap = 0;
-        }
-        InsertBlockLiteralsWithinMethod(MD);
-        CurMethodDef = 0;
-      }
-      break;
-    }
-    case Decl::ObjCImplementation: {
-      ObjCImplementationDecl *CI = cast<ObjCImplementationDecl>(D);
-      ClassImplementation.push_back(CI);
-      break;
-    }
-    case Decl::ObjCCategoryImpl: {
-      ObjCCategoryImplDecl *CI = cast<ObjCCategoryImplDecl>(D);
-      CategoryImplementation.push_back(CI);
-      break;
-    }
-    case Decl::Var: {
-      VarDecl *VD = cast<VarDecl>(D);
-      RewriteObjCQualifiedInterfaceTypes(VD);
-      if (isTopLevelBlockPointerType(VD->getType()))
-        RewriteBlockPointerDecl(VD);
-      else if (VD->getType()->isFunctionPointerType()) {
-        CheckFunctionPointerDecl(VD->getType(), VD);
-        if (VD->getInit()) {
-          if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(VD->getInit())) {
-            RewriteCastExpr(CE);
-          }
-        }
-      } else if (VD->getType()->isRecordType()) {
-        RecordDecl *RD = VD->getType()->getAs<RecordType>()->getDecl();
-        if (RD->isCompleteDefinition())
-          RewriteRecordBody(RD);
-      }
-      if (VD->getInit()) {
-        GlobalVarDecl = VD;
-        CurrentBody = VD->getInit();
-        RewriteFunctionBodyOrGlobalInitializer(VD->getInit());
-        CurrentBody = 0;
-        if (PropParentMap) {
-          delete PropParentMap;
-          PropParentMap = 0;
-        }
-        SynthesizeBlockLiterals(VD->getTypeSpecStartLoc(), VD->getName());
-        GlobalVarDecl = 0;
-          
-        // This is needed for blocks.
-        if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(VD->getInit())) {
-            RewriteCastExpr(CE);
-        }
-      }
-      break;
-    }
-    case Decl::TypeAlias:
-    case Decl::Typedef: {
-      if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
-        if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
-          RewriteBlockPointerDecl(TD);
-        else if (TD->getUnderlyingType()->isFunctionPointerType())
-          CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
-      }
-      break;
-    }
-    case Decl::CXXRecord:
-    case Decl::Record: {
-      RecordDecl *RD = cast<RecordDecl>(D);
-      if (RD->isCompleteDefinition()) 
-        RewriteRecordBody(RD);
-      break;
-    }
-    default:
-      break;
-  }
-  // Nothing yet.
-}
-
-void RewriteObjC::HandleTranslationUnit(ASTContext &C) {
-  if (Diags.hasErrorOccurred())
-    return;
-
-  RewriteInclude();
-
-  // Here's a great place to add any extra declarations that may be needed.
-  // Write out meta data for each @protocol(<expr>).
-  for (llvm::SmallPtrSet<ObjCProtocolDecl *,8>::iterator I = ProtocolExprDecls.begin(),
-       E = ProtocolExprDecls.end(); I != E; ++I)
-    RewriteObjCProtocolMetaData(*I, "", "", Preamble);
-
-  InsertText(SM->getLocForStartOfFile(MainFileID), Preamble, false);
-  if (ClassImplementation.size() || CategoryImplementation.size())
-    RewriteImplementations();
-
-  // Get the buffer corresponding to MainFileID.  If we haven't changed it, then
-  // we are done.
-  if (const RewriteBuffer *RewriteBuf =
-      Rewrite.getRewriteBufferFor(MainFileID)) {
-    //printf("Changed:\n");
-    *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end());
-  } else {
-    llvm::errs() << "No changes\n";
-  }
-
-  if (ClassImplementation.size() || CategoryImplementation.size() ||
-      ProtocolExprDecls.size()) {
-    // Rewrite Objective-c meta data*
-    std::string ResultStr;
-    RewriteMetaDataIntoBuffer(ResultStr);
-    // Emit metadata.
-    *OutFile << ResultStr;
-  }
-  OutFile->flush();
-}
-
-void RewriteObjCFragileABI::Initialize(ASTContext &context) {
-  InitializeCommon(context);
-  
-  // declaring objc_selector outside the parameter list removes a silly
-  // scope related warning...
-  if (IsHeader)
-    Preamble = "#pragma once\n";
-  Preamble += "struct objc_selector; struct objc_class;\n";
-  Preamble += "struct __rw_objc_super { struct objc_object *object; ";
-  Preamble += "struct objc_object *superClass; ";
-  if (LangOpts.MicrosoftExt) {
-    // Add a constructor for creating temporary objects.
-    Preamble += "__rw_objc_super(struct objc_object *o, struct objc_object *s) "
-    ": ";
-    Preamble += "object(o), superClass(s) {} ";
-  }
-  Preamble += "};\n";
-  Preamble += "#ifndef _REWRITER_typedef_Protocol\n";
-  Preamble += "typedef struct objc_object Protocol;\n";
-  Preamble += "#define _REWRITER_typedef_Protocol\n";
-  Preamble += "#endif\n";
-  if (LangOpts.MicrosoftExt) {
-    Preamble += "#define __OBJC_RW_DLLIMPORT extern \"C\" __declspec(dllimport)\n";
-    Preamble += "#define __OBJC_RW_STATICIMPORT extern \"C\"\n";
-  } else
-    Preamble += "#define __OBJC_RW_DLLIMPORT extern\n";
-  Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSend";
-  Preamble += "(struct objc_object *, struct objc_selector *, ...);\n";
-  Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSendSuper";
-  Preamble += "(struct objc_super *, struct objc_selector *, ...);\n";
-  Preamble += "__OBJC_RW_DLLIMPORT struct objc_object* objc_msgSend_stret";
-  Preamble += "(struct objc_object *, struct objc_selector *, ...);\n";
-  Preamble += "__OBJC_RW_DLLIMPORT struct objc_object* objc_msgSendSuper_stret";
-  Preamble += "(struct objc_super *, struct objc_selector *, ...);\n";
-  Preamble += "__OBJC_RW_DLLIMPORT double objc_msgSend_fpret";
-  Preamble += "(struct objc_object *, struct objc_selector *, ...);\n";
-  Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_getClass";
-  Preamble += "(const char *);\n";
-  Preamble += "__OBJC_RW_DLLIMPORT struct objc_class *class_getSuperclass";
-  Preamble += "(struct objc_class *);\n";
-  Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_getMetaClass";
-  Preamble += "(const char *);\n";
-  Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_throw(struct objc_object *);\n";
-  Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_try_enter(void *);\n";
-  Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_try_exit(void *);\n";
-  Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_exception_extract(void *);\n";
-  Preamble += "__OBJC_RW_DLLIMPORT int objc_exception_match";
-  Preamble += "(struct objc_class *, struct objc_object *);\n";
-  // @synchronized hooks.
-  Preamble += "__OBJC_RW_DLLIMPORT int objc_sync_enter(struct objc_object *);\n";
-  Preamble += "__OBJC_RW_DLLIMPORT int objc_sync_exit(struct objc_object *);\n";
-  Preamble += "__OBJC_RW_DLLIMPORT Protocol *objc_getProtocol(const char *);\n";
-  Preamble += "#ifndef __FASTENUMERATIONSTATE\n";
-  Preamble += "struct __objcFastEnumerationState {\n\t";
-  Preamble += "unsigned long state;\n\t";
-  Preamble += "void **itemsPtr;\n\t";
-  Preamble += "unsigned long *mutationsPtr;\n\t";
-  Preamble += "unsigned long extra[5];\n};\n";
-  Preamble += "__OBJC_RW_DLLIMPORT void objc_enumerationMutation(struct objc_object *);\n";
-  Preamble += "#define __FASTENUMERATIONSTATE\n";
-  Preamble += "#endif\n";
-  Preamble += "#ifndef __NSCONSTANTSTRINGIMPL\n";
-  Preamble += "struct __NSConstantStringImpl {\n";
-  Preamble += "  int *isa;\n";
-  Preamble += "  int flags;\n";
-  Preamble += "  char *str;\n";
-  Preamble += "  long length;\n";
-  Preamble += "};\n";
-  Preamble += "#ifdef CF_EXPORT_CONSTANT_STRING\n";
-  Preamble += "extern \"C\" __declspec(dllexport) int __CFConstantStringClassReference[];\n";
-  Preamble += "#else\n";
-  Preamble += "__OBJC_RW_DLLIMPORT int __CFConstantStringClassReference[];\n";
-  Preamble += "#endif\n";
-  Preamble += "#define __NSCONSTANTSTRINGIMPL\n";
-  Preamble += "#endif\n";
-  // Blocks preamble.
-  Preamble += "#ifndef BLOCK_IMPL\n";
-  Preamble += "#define BLOCK_IMPL\n";
-  Preamble += "struct __block_impl {\n";
-  Preamble += "  void *isa;\n";
-  Preamble += "  int Flags;\n";
-  Preamble += "  int Reserved;\n";
-  Preamble += "  void *FuncPtr;\n";
-  Preamble += "};\n";
-  Preamble += "// Runtime copy/destroy helper functions (from Block_private.h)\n";
-  Preamble += "#ifdef __OBJC_EXPORT_BLOCKS\n";
-  Preamble += "extern \"C\" __declspec(dllexport) "
-  "void _Block_object_assign(void *, const void *, const int);\n";
-  Preamble += "extern \"C\" __declspec(dllexport) void _Block_object_dispose(const void *, const int);\n";
-  Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];\n";
-  Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteStackBlock[32];\n";
-  Preamble += "#else\n";
-  Preamble += "__OBJC_RW_DLLIMPORT void _Block_object_assign(void *, const void *, const int);\n";
-  Preamble += "__OBJC_RW_DLLIMPORT void _Block_object_dispose(const void *, const int);\n";
-  Preamble += "__OBJC_RW_DLLIMPORT void *_NSConcreteGlobalBlock[32];\n";
-  Preamble += "__OBJC_RW_DLLIMPORT void *_NSConcreteStackBlock[32];\n";
-  Preamble += "#endif\n";
-  Preamble += "#endif\n";
-  if (LangOpts.MicrosoftExt) {
-    Preamble += "#undef __OBJC_RW_DLLIMPORT\n";
-    Preamble += "#undef __OBJC_RW_STATICIMPORT\n";
-    Preamble += "#ifndef KEEP_ATTRIBUTES\n";  // We use this for clang tests.
-    Preamble += "#define __attribute__(X)\n";
-    Preamble += "#endif\n";
-    Preamble += "#define __weak\n";
-  }
-  else {
-    Preamble += "#define __block\n";
-    Preamble += "#define __weak\n";
-  }
-  // NOTE! Windows uses LLP64 for 64bit mode. So, cast pointer to long long
-  // as this avoids warning in any 64bit/32bit compilation model.
-  Preamble += "\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n";
-}
-
-/// RewriteIvarOffsetComputation - This rutine synthesizes computation of
-/// ivar offset.
-void RewriteObjCFragileABI::RewriteIvarOffsetComputation(ObjCIvarDecl *ivar,
-                                                         std::string &Result) {
-  if (ivar->isBitField()) {
-    // FIXME: The hack below doesn't work for bitfields. For now, we simply
-    // place all bitfields at offset 0.
-    Result += "0";
-  } else {
-    Result += "__OFFSETOFIVAR__(struct ";
-    Result += ivar->getContainingInterface()->getNameAsString();
-    if (LangOpts.MicrosoftExt)
-      Result += "_IMPL";
-    Result += ", ";
-    Result += ivar->getNameAsString();
-    Result += ")";
-  }
-}
-
-/// RewriteObjCProtocolMetaData - Rewrite protocols meta-data.
-void RewriteObjCFragileABI::RewriteObjCProtocolMetaData(
-                            ObjCProtocolDecl *PDecl, StringRef prefix,
-                            StringRef ClassName, std::string &Result) {
-  static bool objc_protocol_methods = false;
-  
-  // Output struct protocol_methods holder of method selector and type.
-  if (!objc_protocol_methods && PDecl->hasDefinition()) {
-    /* struct protocol_methods {
-     SEL _cmd;
-     char *method_types;
-     }
-     */
-    Result += "\nstruct _protocol_methods {\n";
-    Result += "\tstruct objc_selector *_cmd;\n";
-    Result += "\tchar *method_types;\n";
-    Result += "};\n";
-    
-    objc_protocol_methods = true;
-  }
-  // Do not synthesize the protocol more than once.
-  if (ObjCSynthesizedProtocols.count(PDecl->getCanonicalDecl()))
-    return;
-  
-  if (ObjCProtocolDecl *Def = PDecl->getDefinition())
-    PDecl = Def;
-  
-  if (PDecl->instmeth_begin() != PDecl->instmeth_end()) {
-    unsigned NumMethods = std::distance(PDecl->instmeth_begin(),
-                                        PDecl->instmeth_end());
-    /* struct _objc_protocol_method_list {
-     int protocol_method_count;
-     struct protocol_methods protocols[];
-     }
-     */
-    Result += "\nstatic struct {\n";
-    Result += "\tint protocol_method_count;\n";
-    Result += "\tstruct _protocol_methods protocol_methods[";
-    Result += utostr(NumMethods);
-    Result += "];\n} _OBJC_PROTOCOL_INSTANCE_METHODS_";
-    Result += PDecl->getNameAsString();
-    Result += " __attribute__ ((used, section (\"__OBJC, __cat_inst_meth\")))= "
-    "{\n\t" + utostr(NumMethods) + "\n";
-    
-    // Output instance methods declared in this protocol.
-    for (ObjCProtocolDecl::instmeth_iterator
-         I = PDecl->instmeth_begin(), E = PDecl->instmeth_end();
-         I != E; ++I) {
-      if (I == PDecl->instmeth_begin())
-        Result += "\t  ,{{(struct objc_selector *)\"";
-      else
-        Result += "\t  ,{(struct objc_selector *)\"";
-      Result += (*I)->getSelector().getAsString();
-      std::string MethodTypeString;
-      Context->getObjCEncodingForMethodDecl((*I), MethodTypeString);
-      Result += "\", \"";
-      Result += MethodTypeString;
-      Result += "\"}\n";
-    }
-    Result += "\t }\n};\n";
-  }
-  
-  // Output class methods declared in this protocol.
-  unsigned NumMethods = std::distance(PDecl->classmeth_begin(),
-                                      PDecl->classmeth_end());
-  if (NumMethods > 0) {
-    /* struct _objc_protocol_method_list {
-     int protocol_method_count;
-     struct protocol_methods protocols[];
-     }
-     */
-    Result += "\nstatic struct {\n";
-    Result += "\tint protocol_method_count;\n";
-    Result += "\tstruct _protocol_methods protocol_methods[";
-    Result += utostr(NumMethods);
-    Result += "];\n} _OBJC_PROTOCOL_CLASS_METHODS_";
-    Result += PDecl->getNameAsString();
-    Result += " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= "
-    "{\n\t";
-    Result += utostr(NumMethods);
-    Result += "\n";
-    
-    // Output instance methods declared in this protocol.
-    for (ObjCProtocolDecl::classmeth_iterator
-         I = PDecl->classmeth_begin(), E = PDecl->classmeth_end();
-         I != E; ++I) {
-      if (I == PDecl->classmeth_begin())
-        Result += "\t  ,{{(struct objc_selector *)\"";
-      else
-        Result += "\t  ,{(struct objc_selector *)\"";
-      Result += (*I)->getSelector().getAsString();
-      std::string MethodTypeString;
-      Context->getObjCEncodingForMethodDecl((*I), MethodTypeString);
-      Result += "\", \"";
-      Result += MethodTypeString;
-      Result += "\"}\n";
-    }
-    Result += "\t }\n};\n";
-  }
-  
-  // Output:
-  /* struct _objc_protocol {
-   // Objective-C 1.0 extensions
-   struct _objc_protocol_extension *isa;
-   char *protocol_name;
-   struct _objc_protocol **protocol_list;
-   struct _objc_protocol_method_list *instance_methods;
-   struct _objc_protocol_method_list *class_methods;
-   };
-   */
-  static bool objc_protocol = false;
-  if (!objc_protocol) {
-    Result += "\nstruct _objc_protocol {\n";
-    Result += "\tstruct _objc_protocol_extension *isa;\n";
-    Result += "\tchar *protocol_name;\n";
-    Result += "\tstruct _objc_protocol **protocol_list;\n";
-    Result += "\tstruct _objc_protocol_method_list *instance_methods;\n";
-    Result += "\tstruct _objc_protocol_method_list *class_methods;\n";
-    Result += "};\n";
-    
-    objc_protocol = true;
-  }
-  
-  Result += "\nstatic struct _objc_protocol _OBJC_PROTOCOL_";
-  Result += PDecl->getNameAsString();
-  Result += " __attribute__ ((used, section (\"__OBJC, __protocol\")))= "
-  "{\n\t0, \"";
-  Result += PDecl->getNameAsString();
-  Result += "\", 0, ";
-  if (PDecl->instmeth_begin() != PDecl->instmeth_end()) {
-    Result += "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_INSTANCE_METHODS_";
-    Result += PDecl->getNameAsString();
-    Result += ", ";
-  }
-  else
-    Result += "0, ";
-  if (PDecl->classmeth_begin() != PDecl->classmeth_end()) {
-    Result += "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_CLASS_METHODS_";
-    Result += PDecl->getNameAsString();
-    Result += "\n";
-  }
-  else
-    Result += "0\n";
-  Result += "};\n";
-  
-  // Mark this protocol as having been generated.
-  if (!ObjCSynthesizedProtocols.insert(PDecl->getCanonicalDecl()))
-    llvm_unreachable("protocol already synthesized");
-  
-}
-
-void RewriteObjCFragileABI::RewriteObjCProtocolListMetaData(
-                                const ObjCList<ObjCProtocolDecl> &Protocols,
-                                StringRef prefix, StringRef ClassName,
-                                std::string &Result) {
-  if (Protocols.empty()) return;
-  
-  for (unsigned i = 0; i != Protocols.size(); i++)
-    RewriteObjCProtocolMetaData(Protocols[i], prefix, ClassName, Result);
-  
-  // Output the top lovel protocol meta-data for the class.
-  /* struct _objc_protocol_list {
-   struct _objc_protocol_list *next;
-   int    protocol_count;
-   struct _objc_protocol *class_protocols[];
-   }
-   */
-  Result += "\nstatic struct {\n";
-  Result += "\tstruct _objc_protocol_list *next;\n";
-  Result += "\tint    protocol_count;\n";
-  Result += "\tstruct _objc_protocol *class_protocols[";
-  Result += utostr(Protocols.size());
-  Result += "];\n} _OBJC_";
-  Result += prefix;
-  Result += "_PROTOCOLS_";
-  Result += ClassName;
-  Result += " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= "
-  "{\n\t0, ";
-  Result += utostr(Protocols.size());
-  Result += "\n";
-  
-  Result += "\t,{&_OBJC_PROTOCOL_";
-  Result += Protocols[0]->getNameAsString();
-  Result += " \n";
-  
-  for (unsigned i = 1; i != Protocols.size(); i++) {
-    Result += "\t ,&_OBJC_PROTOCOL_";
-    Result += Protocols[i]->getNameAsString();
-    Result += "\n";
-  }
-  Result += "\t }\n};\n";
-}
-
-void RewriteObjCFragileABI::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
-                                           std::string &Result) {
-  ObjCInterfaceDecl *CDecl = IDecl->getClassInterface();
-  
-  // Explicitly declared @interface's are already synthesized.
-  if (CDecl->isImplicitInterfaceDecl()) {
-    // FIXME: Implementation of a class with no @interface (legacy) does not
-    // produce correct synthesis as yet.
-    RewriteObjCInternalStruct(CDecl, Result);
-  }
-  
-  // Build _objc_ivar_list metadata for classes ivars if needed
-  unsigned NumIvars = !IDecl->ivar_empty()
-  ? IDecl->ivar_size()
-  : (CDecl ? CDecl->ivar_size() : 0);
-  if (NumIvars > 0) {
-    static bool objc_ivar = false;
-    if (!objc_ivar) {
-      /* struct _objc_ivar {
-       char *ivar_name;
-       char *ivar_type;
-       int ivar_offset;
-       };
-       */
-      Result += "\nstruct _objc_ivar {\n";
-      Result += "\tchar *ivar_name;\n";
-      Result += "\tchar *ivar_type;\n";
-      Result += "\tint ivar_offset;\n";
-      Result += "};\n";
-      
-      objc_ivar = true;
-    }
-    
-    /* struct {
-     int ivar_count;
-     struct _objc_ivar ivar_list[nIvars];
-     };
-     */
-    Result += "\nstatic struct {\n";
-    Result += "\tint ivar_count;\n";
-    Result += "\tstruct _objc_ivar ivar_list[";
-    Result += utostr(NumIvars);
-    Result += "];\n} _OBJC_INSTANCE_VARIABLES_";
-    Result += IDecl->getNameAsString();
-    Result += " __attribute__ ((used, section (\"__OBJC, __instance_vars\")))= "
-    "{\n\t";
-    Result += utostr(NumIvars);
-    Result += "\n";
-    
-    ObjCInterfaceDecl::ivar_iterator IVI, IVE;
-    SmallVector<ObjCIvarDecl *, 8> IVars;
-    if (!IDecl->ivar_empty()) {
-      for (ObjCInterfaceDecl::ivar_iterator
-           IV = IDecl->ivar_begin(), IVEnd = IDecl->ivar_end();
-           IV != IVEnd; ++IV)
-        IVars.push_back(*IV);
-      IVI = IDecl->ivar_begin();
-      IVE = IDecl->ivar_end();
-    } else {
-      IVI = CDecl->ivar_begin();
-      IVE = CDecl->ivar_end();
-    }
-    Result += "\t,{{\"";
-    Result += IVI->getNameAsString();
-    Result += "\", \"";
-    std::string TmpString, StrEncoding;
-    Context->getObjCEncodingForType(IVI->getType(), TmpString, *IVI);
-    QuoteDoublequotes(TmpString, StrEncoding);
-    Result += StrEncoding;
-    Result += "\", ";
-    RewriteIvarOffsetComputation(*IVI, Result);
-    Result += "}\n";
-    for (++IVI; IVI != IVE; ++IVI) {
-      Result += "\t  ,{\"";
-      Result += IVI->getNameAsString();
-      Result += "\", \"";
-      std::string TmpString, StrEncoding;
-      Context->getObjCEncodingForType(IVI->getType(), TmpString, *IVI);
-      QuoteDoublequotes(TmpString, StrEncoding);
-      Result += StrEncoding;
-      Result += "\", ";
-      RewriteIvarOffsetComputation(*IVI, Result);
-      Result += "}\n";
-    }
-    
-    Result += "\t }\n};\n";
-  }
-  
-  // Build _objc_method_list for class's instance methods if needed
-  SmallVector<ObjCMethodDecl *, 32>
-  InstanceMethods(IDecl->instmeth_begin(), IDecl->instmeth_end());
-  
-  // If any of our property implementations have associated getters or
-  // setters, produce metadata for them as well.
-  for (ObjCImplDecl::propimpl_iterator Prop = IDecl->propimpl_begin(),
-       PropEnd = IDecl->propimpl_end();
-       Prop != PropEnd; ++Prop) {
-    if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
-      continue;
-    if (!Prop->getPropertyIvarDecl())
-      continue;
-    ObjCPropertyDecl *PD = Prop->getPropertyDecl();
-    if (!PD)
-      continue;
-    if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl())
-      if (!Getter->isDefined())
-        InstanceMethods.push_back(Getter);
-    if (PD->isReadOnly())
-      continue;
-    if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl())
-      if (!Setter->isDefined())
-        InstanceMethods.push_back(Setter);
-  }
-  RewriteObjCMethodsMetaData(InstanceMethods.begin(), InstanceMethods.end(),
-                             true, "", IDecl->getName(), Result);
-  
-  // Build _objc_method_list for class's class methods if needed
-  RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(),
-                             false, "", IDecl->getName(), Result);
-  
-  // Protocols referenced in class declaration?
-  RewriteObjCProtocolListMetaData(CDecl->getReferencedProtocols(),
-                                  "CLASS", CDecl->getName(), Result);
-  
-  // Declaration of class/meta-class metadata
-  /* struct _objc_class {
-   struct _objc_class *isa; // or const char *root_class_name when metadata
-   const char *super_class_name;
-   char *name;
-   long version;
-   long info;
-   long instance_size;
-   struct _objc_ivar_list *ivars;
-   struct _objc_method_list *methods;
-   struct objc_cache *cache;
-   struct objc_protocol_list *protocols;
-   const char *ivar_layout;
-   struct _objc_class_ext  *ext;
-   };
-   */
-  static bool objc_class = false;
-  if (!objc_class) {
-    Result += "\nstruct _objc_class {\n";
-    Result += "\tstruct _objc_class *isa;\n";
-    Result += "\tconst char *super_class_name;\n";
-    Result += "\tchar *name;\n";
-    Result += "\tlong version;\n";
-    Result += "\tlong info;\n";
-    Result += "\tlong instance_size;\n";
-    Result += "\tstruct _objc_ivar_list *ivars;\n";
-    Result += "\tstruct _objc_method_list *methods;\n";
-    Result += "\tstruct objc_cache *cache;\n";
-    Result += "\tstruct _objc_protocol_list *protocols;\n";
-    Result += "\tconst char *ivar_layout;\n";
-    Result += "\tstruct _objc_class_ext  *ext;\n";
-    Result += "};\n";
-    objc_class = true;
-  }
-  
-  // Meta-class metadata generation.
-  ObjCInterfaceDecl *RootClass = 0;
-  ObjCInterfaceDecl *SuperClass = CDecl->getSuperClass();
-  while (SuperClass) {
-    RootClass = SuperClass;
-    SuperClass = SuperClass->getSuperClass();
-  }
-  SuperClass = CDecl->getSuperClass();
-  
-  Result += "\nstatic struct _objc_class _OBJC_METACLASS_";
-  Result += CDecl->getNameAsString();
-  Result += " __attribute__ ((used, section (\"__OBJC, __meta_class\")))= "
-  "{\n\t(struct _objc_class *)\"";
-  Result += (RootClass ? RootClass->getNameAsString() : CDecl->getNameAsString());
-  Result += "\"";
-  
-  if (SuperClass) {
-    Result += ", \"";
-    Result += SuperClass->getNameAsString();
-    Result += "\", \"";
-    Result += CDecl->getNameAsString();
-    Result += "\"";
-  }
-  else {
-    Result += ", 0, \"";
-    Result += CDecl->getNameAsString();
-    Result += "\"";
-  }
-  // Set 'ivars' field for root class to 0. ObjC1 runtime does not use it.
-  // 'info' field is initialized to CLS_META(2) for metaclass
-  Result += ", 0,2, sizeof(struct _objc_class), 0";
-  if (IDecl->classmeth_begin() != IDecl->classmeth_end()) {
-    Result += "\n\t, (struct _objc_method_list *)&_OBJC_CLASS_METHODS_";
-    Result += IDecl->getNameAsString();
-    Result += "\n";
-  }
-  else
-    Result += ", 0\n";
-  if (CDecl->protocol_begin() != CDecl->protocol_end()) {
-    Result += "\t,0, (struct _objc_protocol_list *)&_OBJC_CLASS_PROTOCOLS_";
-    Result += CDecl->getNameAsString();
-    Result += ",0,0\n";
-  }
-  else
-    Result += "\t,0,0,0,0\n";
-  Result += "};\n";
-  
-  // class metadata generation.
-  Result += "\nstatic struct _objc_class _OBJC_CLASS_";
-  Result += CDecl->getNameAsString();
-  Result += " __attribute__ ((used, section (\"__OBJC, __class\")))= "
-  "{\n\t&_OBJC_METACLASS_";
-  Result += CDecl->getNameAsString();
-  if (SuperClass) {
-    Result += ", \"";
-    Result += SuperClass->getNameAsString();
-    Result += "\", \"";
-    Result += CDecl->getNameAsString();
-    Result += "\"";
-  }
-  else {
-    Result += ", 0, \"";
-    Result += CDecl->getNameAsString();
-    Result += "\"";
-  }
-  // 'info' field is initialized to CLS_CLASS(1) for class
-  Result += ", 0,1";
-  if (!ObjCSynthesizedStructs.count(CDecl))
-    Result += ",0";
-  else {
-    // class has size. Must synthesize its size.
-    Result += ",sizeof(struct ";
-    Result += CDecl->getNameAsString();
-    if (LangOpts.MicrosoftExt)
-      Result += "_IMPL";
-    Result += ")";
-  }
-  if (NumIvars > 0) {
-    Result += ", (struct _objc_ivar_list *)&_OBJC_INSTANCE_VARIABLES_";
-    Result += CDecl->getNameAsString();
-    Result += "\n\t";
-  }
-  else
-    Result += ",0";
-  if (IDecl->instmeth_begin() != IDecl->instmeth_end()) {
-    Result += ", (struct _objc_method_list *)&_OBJC_INSTANCE_METHODS_";
-    Result += CDecl->getNameAsString();
-    Result += ", 0\n\t";
-  }
-  else
-    Result += ",0,0";
-  if (CDecl->protocol_begin() != CDecl->protocol_end()) {
-    Result += ", (struct _objc_protocol_list*)&_OBJC_CLASS_PROTOCOLS_";
-    Result += CDecl->getNameAsString();
-    Result += ", 0,0\n";
-  }
-  else
-    Result += ",0,0,0\n";
-  Result += "};\n";
-}
-
-void RewriteObjCFragileABI::RewriteMetaDataIntoBuffer(std::string &Result) {
-  int ClsDefCount = ClassImplementation.size();
-  int CatDefCount = CategoryImplementation.size();
-  
-  // For each implemented class, write out all its meta data.
-  for (int i = 0; i < ClsDefCount; i++)
-    RewriteObjCClassMetaData(ClassImplementation[i], Result);
-  
-  // For each implemented category, write out all its meta data.
-  for (int i = 0; i < CatDefCount; i++)
-    RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result);
-  
-  // Write objc_symtab metadata
-  /*
-   struct _objc_symtab
-   {
-   long sel_ref_cnt;
-   SEL *refs;
-   short cls_def_cnt;
-   short cat_def_cnt;
-   void *defs[cls_def_cnt + cat_def_cnt];
-   };
-   */
-  
-  Result += "\nstruct _objc_symtab {\n";
-  Result += "\tlong sel_ref_cnt;\n";
-  Result += "\tSEL *refs;\n";
-  Result += "\tshort cls_def_cnt;\n";
-  Result += "\tshort cat_def_cnt;\n";
-  Result += "\tvoid *defs[" + utostr(ClsDefCount + CatDefCount)+ "];\n";
-  Result += "};\n\n";
-  
-  Result += "static struct _objc_symtab "
-  "_OBJC_SYMBOLS __attribute__((used, section (\"__OBJC, __symbols\")))= {\n";
-  Result += "\t0, 0, " + utostr(ClsDefCount)
-  + ", " + utostr(CatDefCount) + "\n";
-  for (int i = 0; i < ClsDefCount; i++) {
-    Result += "\t,&_OBJC_CLASS_";
-    Result += ClassImplementation[i]->getNameAsString();
-    Result += "\n";
-  }
-  
-  for (int i = 0; i < CatDefCount; i++) {
-    Result += "\t,&_OBJC_CATEGORY_";
-    Result += CategoryImplementation[i]->getClassInterface()->getNameAsString();
-    Result += "_";
-    Result += CategoryImplementation[i]->getNameAsString();
-    Result += "\n";
-  }
-  
-  Result += "};\n\n";
-  
-  // Write objc_module metadata
-  
-  /*
-   struct _objc_module {
-   long version;
-   long size;
-   const char *name;
-   struct _objc_symtab *symtab;
-   }
-   */
-  
-  Result += "\nstruct _objc_module {\n";
-  Result += "\tlong version;\n";
-  Result += "\tlong size;\n";
-  Result += "\tconst char *name;\n";
-  Result += "\tstruct _objc_symtab *symtab;\n";
-  Result += "};\n\n";
-  Result += "static struct _objc_module "
-  "_OBJC_MODULES __attribute__ ((used, section (\"__OBJC, __module_info\")))= {\n";
-  Result += "\t" + utostr(OBJC_ABI_VERSION) +
-  ", sizeof(struct _objc_module), \"\", &_OBJC_SYMBOLS\n";
-  Result += "};\n\n";
-  
-  if (LangOpts.MicrosoftExt) {
-    if (ProtocolExprDecls.size()) {
-      Result += "#pragma section(\".objc_protocol$B\",long,read,write)\n";
-      Result += "#pragma data_seg(push, \".objc_protocol$B\")\n";
-      for (llvm::SmallPtrSet<ObjCProtocolDecl *,8>::iterator I = ProtocolExprDecls.begin(),
-           E = ProtocolExprDecls.end(); I != E; ++I) {
-        Result += "static struct _objc_protocol *_POINTER_OBJC_PROTOCOL_";
-        Result += (*I)->getNameAsString();
-        Result += " = &_OBJC_PROTOCOL_";
-        Result += (*I)->getNameAsString();
-        Result += ";\n";
-      }
-      Result += "#pragma data_seg(pop)\n\n";
-    }
-    Result += "#pragma section(\".objc_module_info$B\",long,read,write)\n";
-    Result += "#pragma data_seg(push, \".objc_module_info$B\")\n";
-    Result += "static struct _objc_module *_POINTER_OBJC_MODULES = ";
-    Result += "&_OBJC_MODULES;\n";
-    Result += "#pragma data_seg(pop)\n\n";
-  }
-}
-
-/// RewriteObjCCategoryImplDecl - Rewrite metadata for each category
-/// implementation.
-void RewriteObjCFragileABI::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl,
-                                              std::string &Result) {
-  ObjCInterfaceDecl *ClassDecl = IDecl->getClassInterface();
-  // Find category declaration for this implementation.
-  ObjCCategoryDecl *CDecl
-    = ClassDecl->FindCategoryDeclaration(IDecl->getIdentifier());
-  
-  std::string FullCategoryName = ClassDecl->getNameAsString();
-  FullCategoryName += '_';
-  FullCategoryName += IDecl->getNameAsString();
-  
-  // Build _objc_method_list for class's instance methods if needed
-  SmallVector<ObjCMethodDecl *, 32>
-  InstanceMethods(IDecl->instmeth_begin(), IDecl->instmeth_end());
-  
-  // If any of our property implementations have associated getters or
-  // setters, produce metadata for them as well.
-  for (ObjCImplDecl::propimpl_iterator Prop = IDecl->propimpl_begin(),
-       PropEnd = IDecl->propimpl_end();
-       Prop != PropEnd; ++Prop) {
-    if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
-      continue;
-    if (!Prop->getPropertyIvarDecl())
-      continue;
-    ObjCPropertyDecl *PD = Prop->getPropertyDecl();
-    if (!PD)
-      continue;
-    if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl())
-      InstanceMethods.push_back(Getter);
-    if (PD->isReadOnly())
-      continue;
-    if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl())
-      InstanceMethods.push_back(Setter);
-  }
-  RewriteObjCMethodsMetaData(InstanceMethods.begin(), InstanceMethods.end(),
-                             true, "CATEGORY_", FullCategoryName.c_str(),
-                             Result);
-  
-  // Build _objc_method_list for class's class methods if needed
-  RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(),
-                             false, "CATEGORY_", FullCategoryName.c_str(),
-                             Result);
-  
-  // Protocols referenced in class declaration?
-  // Null CDecl is case of a category implementation with no category interface
-  if (CDecl)
-    RewriteObjCProtocolListMetaData(CDecl->getReferencedProtocols(), "CATEGORY",
-                                    FullCategoryName, Result);
-  /* struct _objc_category {
-   char *category_name;
-   char *class_name;
-   struct _objc_method_list *instance_methods;
-   struct _objc_method_list *class_methods;
-   struct _objc_protocol_list *protocols;
-   // Objective-C 1.0 extensions
-   uint32_t size;     // sizeof (struct _objc_category)
-   struct _objc_property_list *instance_properties;  // category's own
-   // @property decl.
-   };
-   */
-  
-  static bool objc_category = false;
-  if (!objc_category) {
-    Result += "\nstruct _objc_category {\n";
-    Result += "\tchar *category_name;\n";
-    Result += "\tchar *class_name;\n";
-    Result += "\tstruct _objc_method_list *instance_methods;\n";
-    Result += "\tstruct _objc_method_list *class_methods;\n";
-    Result += "\tstruct _objc_protocol_list *protocols;\n";
-    Result += "\tunsigned int size;\n";
-    Result += "\tstruct _objc_property_list *instance_properties;\n";
-    Result += "};\n";
-    objc_category = true;
-  }
-  Result += "\nstatic struct _objc_category _OBJC_CATEGORY_";
-  Result += FullCategoryName;
-  Result += " __attribute__ ((used, section (\"__OBJC, __category\")))= {\n\t\"";
-  Result += IDecl->getNameAsString();
-  Result += "\"\n\t, \"";
-  Result += ClassDecl->getNameAsString();
-  Result += "\"\n";
-  
-  if (IDecl->instmeth_begin() != IDecl->instmeth_end()) {
-    Result += "\t, (struct _objc_method_list *)"
-    "&_OBJC_CATEGORY_INSTANCE_METHODS_";
-    Result += FullCategoryName;
-    Result += "\n";
-  }
-  else
-    Result += "\t, 0\n";
-  if (IDecl->classmeth_begin() != IDecl->classmeth_end()) {
-    Result += "\t, (struct _objc_method_list *)"
-    "&_OBJC_CATEGORY_CLASS_METHODS_";
-    Result += FullCategoryName;
-    Result += "\n";
-  }
-  else
-    Result += "\t, 0\n";
-  
-  if (CDecl && CDecl->protocol_begin() != CDecl->protocol_end()) {
-    Result += "\t, (struct _objc_protocol_list *)&_OBJC_CATEGORY_PROTOCOLS_";
-    Result += FullCategoryName;
-    Result += "\n";
-  }
-  else
-    Result += "\t, 0\n";
-  Result += "\t, sizeof(struct _objc_category), 0\n};\n";
-}
-
-// RewriteObjCMethodsMetaData - Rewrite methods metadata for instance or
-/// class methods.
-template<typename MethodIterator>
-void RewriteObjCFragileABI::RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
-                                             MethodIterator MethodEnd,
-                                             bool IsInstanceMethod,
-                                             StringRef prefix,
-                                             StringRef ClassName,
-                                             std::string &Result) {
-  if (MethodBegin == MethodEnd) return;
-  
-  if (!objc_impl_method) {
-    /* struct _objc_method {
-     SEL _cmd;
-     char *method_types;
-     void *_imp;
-     }
-     */
-    Result += "\nstruct _objc_method {\n";
-    Result += "\tSEL _cmd;\n";
-    Result += "\tchar *method_types;\n";
-    Result += "\tvoid *_imp;\n";
-    Result += "};\n";
-    
-    objc_impl_method = true;
-  }
-  
-  // Build _objc_method_list for class's methods if needed
-  
-  /* struct  {
-   struct _objc_method_list *next_method;
-   int method_count;
-   struct _objc_method method_list[];
-   }
-   */
-  unsigned NumMethods = std::distance(MethodBegin, MethodEnd);
-  Result += "\nstatic struct {\n";
-  Result += "\tstruct _objc_method_list *next_method;\n";
-  Result += "\tint method_count;\n";
-  Result += "\tstruct _objc_method method_list[";
-  Result += utostr(NumMethods);
-  Result += "];\n} _OBJC_";
-  Result += prefix;
-  Result += IsInstanceMethod ? "INSTANCE" : "CLASS";
-  Result += "_METHODS_";
-  Result += ClassName;
-  Result += " __attribute__ ((used, section (\"__OBJC, __";
-  Result += IsInstanceMethod ? "inst" : "cls";
-  Result += "_meth\")))= ";
-  Result += "{\n\t0, " + utostr(NumMethods) + "\n";
-  
-  Result += "\t,{{(SEL)\"";
-  Result += (*MethodBegin)->getSelector().getAsString().c_str();
-  std::string MethodTypeString;
-  Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString);
-  Result += "\", \"";
-  Result += MethodTypeString;
-  Result += "\", (void *)";
-  Result += MethodInternalNames[*MethodBegin];
-  Result += "}\n";
-  for (++MethodBegin; MethodBegin != MethodEnd; ++MethodBegin) {
-    Result += "\t  ,{(SEL)\"";
-    Result += (*MethodBegin)->getSelector().getAsString().c_str();
-    std::string MethodTypeString;
-    Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString);
-    Result += "\", \"";
-    Result += MethodTypeString;
-    Result += "\", (void *)";
-    Result += MethodInternalNames[*MethodBegin];
-    Result += "}\n";
-  }
-  Result += "\t }\n};\n";
-}
-
-Stmt *RewriteObjCFragileABI::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) {
-  SourceRange OldRange = IV->getSourceRange();
-  Expr *BaseExpr = IV->getBase();
-  
-  // Rewrite the base, but without actually doing replaces.
-  {
-    DisableReplaceStmtScope S(*this);
-    BaseExpr = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(BaseExpr));
-    IV->setBase(BaseExpr);
-  }
-  
-  ObjCIvarDecl *D = IV->getDecl();
-  
-  Expr *Replacement = IV;
-  if (CurMethodDef) {
-    if (BaseExpr->getType()->isObjCObjectPointerType()) {
-      const ObjCInterfaceType *iFaceDecl =
-      dyn_cast<ObjCInterfaceType>(BaseExpr->getType()->getPointeeType());
-      assert(iFaceDecl && "RewriteObjCIvarRefExpr - iFaceDecl is null");
-      // lookup which class implements the instance variable.
-      ObjCInterfaceDecl *clsDeclared = 0;
-      iFaceDecl->getDecl()->lookupInstanceVariable(D->getIdentifier(),
-                                                   clsDeclared);
-      assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class");
-      
-      // Synthesize an explicit cast to gain access to the ivar.
-      std::string RecName = clsDeclared->getIdentifier()->getName();
-      RecName += "_IMPL";
-      IdentifierInfo *II = &Context->Idents.get(RecName);
-      RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
-                                          SourceLocation(), SourceLocation(),
-                                          II);
-      assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl");
-      QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
-      CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, castT,
-                                                    CK_BitCast,
-                                                    IV->getBase());
-      // Don't forget the parens to enforce the proper binding.
-      ParenExpr *PE = new (Context) ParenExpr(OldRange.getBegin(),
-                                              OldRange.getEnd(),
-                                              castExpr);
-      if (IV->isFreeIvar() &&
-          declaresSameEntity(CurMethodDef->getClassInterface(), iFaceDecl->getDecl())) {
-        MemberExpr *ME = new (Context) MemberExpr(PE, true, D,
-                                                  IV->getLocation(),
-                                                  D->getType(),
-                                                  VK_LValue, OK_Ordinary);
-        Replacement = ME;
-      } else {
-        IV->setBase(PE);
-      }
-    }
-  } else { // we are outside a method.
-    assert(!IV->isFreeIvar() && "Cannot have a free standing ivar outside a method");
-    
-    // Explicit ivar refs need to have a cast inserted.
-    // FIXME: consider sharing some of this code with the code above.
-    if (BaseExpr->getType()->isObjCObjectPointerType()) {
-      const ObjCInterfaceType *iFaceDecl =
-      dyn_cast<ObjCInterfaceType>(BaseExpr->getType()->getPointeeType());
-      // lookup which class implements the instance variable.
-      ObjCInterfaceDecl *clsDeclared = 0;
-      iFaceDecl->getDecl()->lookupInstanceVariable(D->getIdentifier(),
-                                                   clsDeclared);
-      assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class");
-      
-      // Synthesize an explicit cast to gain access to the ivar.
-      std::string RecName = clsDeclared->getIdentifier()->getName();
-      RecName += "_IMPL";
-      IdentifierInfo *II = &Context->Idents.get(RecName);
-      RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
-                                          SourceLocation(), SourceLocation(),
-                                          II);
-      assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl");
-      QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
-      CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, castT,
-                                                    CK_BitCast,
-                                                    IV->getBase());
-      // Don't forget the parens to enforce the proper binding.
-      ParenExpr *PE = new (Context) ParenExpr(IV->getBase()->getLocStart(),
-                                              IV->getBase()->getLocEnd(), castExpr);
-      // Cannot delete IV->getBase(), since PE points to it.
-      // Replace the old base with the cast. This is important when doing
-      // embedded rewrites. For example, [newInv->_container addObject:0].
-      IV->setBase(PE);
-    }
-  }
-  
-  ReplaceStmtWithRange(IV, Replacement, OldRange);
-  return Replacement;  
-}
diff --git a/lib/Rewrite/HTMLRewrite.cpp b/lib/Rewrite/HTMLRewrite.cpp
new file mode 100644
index 0000000..275fbd0
--- /dev/null
+++ b/lib/Rewrite/HTMLRewrite.cpp
@@ -0,0 +1,582 @@
+//== HTMLRewrite.cpp - Translate source code into prettified HTML --*- C++ -*-//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the HTMLRewriter class, which is used to translate the
+//  text of a source file into prettified HTML.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Rewrite/Core/HTMLRewrite.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/TokenConcatenation.h"
+#include "clang/Rewrite/Core/Rewriter.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+#include <memory>
+using namespace clang;
+
+
+/// HighlightRange - Highlight a range in the source code with the specified
+/// start/end tags.  B/E must be in the same file.  This ensures that
+/// start/end tags are placed at the start/end of each line if the range is
+/// multiline.
+void html::HighlightRange(Rewriter &R, SourceLocation B, SourceLocation E,
+                          const char *StartTag, const char *EndTag) {
+  SourceManager &SM = R.getSourceMgr();
+  B = SM.getExpansionLoc(B);
+  E = SM.getExpansionLoc(E);
+  FileID FID = SM.getFileID(B);
+  assert(SM.getFileID(E) == FID && "B/E not in the same file!");
+
+  unsigned BOffset = SM.getFileOffset(B);
+  unsigned EOffset = SM.getFileOffset(E);
+
+  // Include the whole end token in the range.
+  EOffset += Lexer::MeasureTokenLength(E, R.getSourceMgr(), R.getLangOpts());
+
+  bool Invalid = false;
+  const char *BufferStart = SM.getBufferData(FID, &Invalid).data();
+  if (Invalid)
+    return;
+  
+  HighlightRange(R.getEditBuffer(FID), BOffset, EOffset,
+                 BufferStart, StartTag, EndTag);
+}
+
+/// HighlightRange - This is the same as the above method, but takes
+/// decomposed file locations.
+void html::HighlightRange(RewriteBuffer &RB, unsigned B, unsigned E,
+                          const char *BufferStart,
+                          const char *StartTag, const char *EndTag) {
+  // Insert the tag at the absolute start/end of the range.
+  RB.InsertTextAfter(B, StartTag);
+  RB.InsertTextBefore(E, EndTag);
+
+  // Scan the range to see if there is a \r or \n.  If so, and if the line is
+  // not blank, insert tags on that line as well.
+  bool HadOpenTag = true;
+
+  unsigned LastNonWhiteSpace = B;
+  for (unsigned i = B; i != E; ++i) {
+    switch (BufferStart[i]) {
+    case '\r':
+    case '\n':
+      // Okay, we found a newline in the range.  If we have an open tag, we need
+      // to insert a close tag at the first non-whitespace before the newline.
+      if (HadOpenTag)
+        RB.InsertTextBefore(LastNonWhiteSpace+1, EndTag);
+
+      // Instead of inserting an open tag immediately after the newline, we
+      // wait until we see a non-whitespace character.  This prevents us from
+      // inserting tags around blank lines, and also allows the open tag to
+      // be put *after* whitespace on a non-blank line.
+      HadOpenTag = false;
+      break;
+    case '\0':
+    case ' ':
+    case '\t':
+    case '\f':
+    case '\v':
+      // Ignore whitespace.
+      break;
+
+    default:
+      // If there is no tag open, do it now.
+      if (!HadOpenTag) {
+        RB.InsertTextAfter(i, StartTag);
+        HadOpenTag = true;
+      }
+
+      // Remember this character.
+      LastNonWhiteSpace = i;
+      break;
+    }
+  }
+}
+
+void html::EscapeText(Rewriter &R, FileID FID,
+                      bool EscapeSpaces, bool ReplaceTabs) {
+
+  const llvm::MemoryBuffer *Buf = R.getSourceMgr().getBuffer(FID);
+  const char* C = Buf->getBufferStart();
+  const char* FileEnd = Buf->getBufferEnd();
+
+  assert (C <= FileEnd);
+
+  RewriteBuffer &RB = R.getEditBuffer(FID);
+
+  unsigned ColNo = 0;
+  for (unsigned FilePos = 0; C != FileEnd ; ++C, ++FilePos) {
+    switch (*C) {
+    default: ++ColNo; break;
+    case '\n':
+    case '\r':
+      ColNo = 0;
+      break;
+
+    case ' ':
+      if (EscapeSpaces)
+        RB.ReplaceText(FilePos, 1, "&nbsp;");
+      ++ColNo;
+      break;
+    case '\f':
+      RB.ReplaceText(FilePos, 1, "<hr>");
+      ColNo = 0;
+      break;
+
+    case '\t': {
+      if (!ReplaceTabs)
+        break;
+      unsigned NumSpaces = 8-(ColNo&7);
+      if (EscapeSpaces)
+        RB.ReplaceText(FilePos, 1,
+                       StringRef("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"
+                                       "&nbsp;&nbsp;&nbsp;", 6*NumSpaces));
+      else
+        RB.ReplaceText(FilePos, 1, StringRef("        ", NumSpaces));
+      ColNo += NumSpaces;
+      break;
+    }
+    case '<':
+      RB.ReplaceText(FilePos, 1, "&lt;");
+      ++ColNo;
+      break;
+
+    case '>':
+      RB.ReplaceText(FilePos, 1, "&gt;");
+      ++ColNo;
+      break;
+
+    case '&':
+      RB.ReplaceText(FilePos, 1, "&amp;");
+      ++ColNo;
+      break;
+    }
+  }
+}
+
+std::string html::EscapeText(StringRef s, bool EscapeSpaces, bool ReplaceTabs) {
+
+  unsigned len = s.size();
+  std::string Str;
+  llvm::raw_string_ostream os(Str);
+
+  for (unsigned i = 0 ; i < len; ++i) {
+
+    char c = s[i];
+    switch (c) {
+    default:
+      os << c; break;
+
+    case ' ':
+      if (EscapeSpaces) os << "&nbsp;";
+      else os << ' ';
+      break;
+
+    case '\t':
+      if (ReplaceTabs) {
+        if (EscapeSpaces)
+          for (unsigned i = 0; i < 4; ++i)
+            os << "&nbsp;";
+        else
+          for (unsigned i = 0; i < 4; ++i)
+            os << " ";
+      }
+      else
+        os << c;
+
+      break;
+
+    case '<': os << "&lt;"; break;
+    case '>': os << "&gt;"; break;
+    case '&': os << "&amp;"; break;
+    }
+  }
+
+  return os.str();
+}
+
+static void AddLineNumber(RewriteBuffer &RB, unsigned LineNo,
+                          unsigned B, unsigned E) {
+  SmallString<256> Str;
+  llvm::raw_svector_ostream OS(Str);
+
+  OS << "<tr><td class=\"num\" id=\"LN"
+     << LineNo << "\">"
+     << LineNo << "</td><td class=\"line\">";
+
+  if (B == E) { // Handle empty lines.
+    OS << " </td></tr>";
+    RB.InsertTextBefore(B, OS.str());
+  } else {
+    RB.InsertTextBefore(B, OS.str());
+    RB.InsertTextBefore(E, "</td></tr>");
+  }
+}
+
+void html::AddLineNumbers(Rewriter& R, FileID FID) {
+
+  const llvm::MemoryBuffer *Buf = R.getSourceMgr().getBuffer(FID);
+  const char* FileBeg = Buf->getBufferStart();
+  const char* FileEnd = Buf->getBufferEnd();
+  const char* C = FileBeg;
+  RewriteBuffer &RB = R.getEditBuffer(FID);
+
+  assert (C <= FileEnd);
+
+  unsigned LineNo = 0;
+  unsigned FilePos = 0;
+
+  while (C != FileEnd) {
+
+    ++LineNo;
+    unsigned LineStartPos = FilePos;
+    unsigned LineEndPos = FileEnd - FileBeg;
+
+    assert (FilePos <= LineEndPos);
+    assert (C < FileEnd);
+
+    // Scan until the newline (or end-of-file).
+
+    while (C != FileEnd) {
+      char c = *C;
+      ++C;
+
+      if (c == '\n') {
+        LineEndPos = FilePos++;
+        break;
+      }
+
+      ++FilePos;
+    }
+
+    AddLineNumber(RB, LineNo, LineStartPos, LineEndPos);
+  }
+
+  // Add one big table tag that surrounds all of the code.
+  RB.InsertTextBefore(0, "<table class=\"code\">\n");
+  RB.InsertTextAfter(FileEnd - FileBeg, "</table>");
+}
+
+void html::AddHeaderFooterInternalBuiltinCSS(Rewriter& R, FileID FID,
+                                             const char *title) {
+
+  const llvm::MemoryBuffer *Buf = R.getSourceMgr().getBuffer(FID);
+  const char* FileStart = Buf->getBufferStart();
+  const char* FileEnd = Buf->getBufferEnd();
+
+  SourceLocation StartLoc = R.getSourceMgr().getLocForStartOfFile(FID);
+  SourceLocation EndLoc = StartLoc.getLocWithOffset(FileEnd-FileStart);
+
+  std::string s;
+  llvm::raw_string_ostream os(s);
+  os << "<!doctype html>\n" // Use HTML 5 doctype
+        "<html>\n<head>\n";
+
+  if (title)
+    os << "<title>" << html::EscapeText(title) << "</title>\n";
+
+  os << "<style type=\"text/css\">\n"
+      " body { color:#000000; background-color:#ffffff }\n"
+      " body { font-family:Helvetica, sans-serif; font-size:10pt }\n"
+      " h1 { font-size:14pt }\n"
+      " .code { border-collapse:collapse; width:100%; }\n"
+      " .code { font-family: \"Monospace\", monospace; font-size:10pt }\n"
+      " .code { line-height: 1.2em }\n"
+      " .comment { color: green; font-style: oblique }\n"
+      " .keyword { color: blue }\n"
+      " .string_literal { color: red }\n"
+      " .directive { color: darkmagenta }\n"
+      // Macro expansions.
+      " .expansion { display: none; }\n"
+      " .macro:hover .expansion { display: block; border: 2px solid #FF0000; "
+          "padding: 2px; background-color:#FFF0F0; font-weight: normal; "
+          "  -webkit-border-radius:5px;  -webkit-box-shadow:1px 1px 7px #000; "
+          "position: absolute; top: -1em; left:10em; z-index: 1 } \n"
+      " .macro { color: darkmagenta; background-color:LemonChiffon;"
+             // Macros are position: relative to provide base for expansions.
+             " position: relative }\n"
+      " .num { width:2.5em; padding-right:2ex; background-color:#eeeeee }\n"
+      " .num { text-align:right; font-size:8pt }\n"
+      " .num { color:#444444 }\n"
+      " .line { padding-left: 1ex; border-left: 3px solid #ccc }\n"
+      " .line { white-space: pre }\n"
+      " .msg { -webkit-box-shadow:1px 1px 7px #000 }\n"
+      " .msg { -webkit-border-radius:5px }\n"
+      " .msg { font-family:Helvetica, sans-serif; font-size:8pt }\n"
+      " .msg { float:left }\n"
+      " .msg { padding:0.25em 1ex 0.25em 1ex }\n"
+      " .msg { margin-top:10px; margin-bottom:10px }\n"
+      " .msg { font-weight:bold }\n"
+      " .msg { max-width:60em; word-wrap: break-word; white-space: pre-wrap }\n"
+      " .msgT { padding:0x; spacing:0x }\n"
+      " .msgEvent { background-color:#fff8b4; color:#000000 }\n"
+      " .msgControl { background-color:#bbbbbb; color:#000000 }\n"
+      " .mrange { background-color:#dfddf3 }\n"
+      " .mrange { border-bottom:1px solid #6F9DBE }\n"
+      " .PathIndex { font-weight: bold; padding:0px 5px; "
+        "margin-right:5px; }\n"
+      " .PathIndex { -webkit-border-radius:8px }\n"
+      " .PathIndexEvent { background-color:#bfba87 }\n"
+      " .PathIndexControl { background-color:#8c8c8c }\n"
+      " .PathNav a { text-decoration:none; font-size: larger }\n"
+      " .CodeInsertionHint { font-weight: bold; background-color: #10dd10 }\n"
+      " .CodeRemovalHint { background-color:#de1010 }\n"
+      " .CodeRemovalHint { border-bottom:1px solid #6F9DBE }\n"
+      " table.simpletable {\n"
+      "   padding: 5px;\n"
+      "   font-size:12pt;\n"
+      "   margin:20px;\n"
+      "   border-collapse: collapse; border-spacing: 0px;\n"
+      " }\n"
+      " td.rowname {\n"
+      "   text-align:right; font-weight:bold; color:#444444;\n"
+      "   padding-right:2ex; }\n"
+      "</style>\n</head>\n<body>";
+
+  // Generate header
+  R.InsertTextBefore(StartLoc, os.str());
+  // Generate footer
+
+  R.InsertTextAfter(EndLoc, "</body></html>\n");
+}
+
+/// SyntaxHighlight - Relex the specified FileID and annotate the HTML with
+/// information about keywords, macro expansions etc.  This uses the macro
+/// table state from the end of the file, so it won't be perfectly perfect,
+/// but it will be reasonably close.
+void html::SyntaxHighlight(Rewriter &R, FileID FID, const Preprocessor &PP) {
+  RewriteBuffer &RB = R.getEditBuffer(FID);
+
+  const SourceManager &SM = PP.getSourceManager();
+  const llvm::MemoryBuffer *FromFile = SM.getBuffer(FID);
+  Lexer L(FID, FromFile, SM, PP.getLangOpts());
+  const char *BufferStart = L.getBuffer().data();
+
+  // Inform the preprocessor that we want to retain comments as tokens, so we
+  // can highlight them.
+  L.SetCommentRetentionState(true);
+
+  // Lex all the tokens in raw mode, to avoid entering #includes or expanding
+  // macros.
+  Token Tok;
+  L.LexFromRawLexer(Tok);
+
+  while (Tok.isNot(tok::eof)) {
+    // Since we are lexing unexpanded tokens, all tokens are from the main
+    // FileID.
+    unsigned TokOffs = SM.getFileOffset(Tok.getLocation());
+    unsigned TokLen = Tok.getLength();
+    switch (Tok.getKind()) {
+    default: break;
+    case tok::identifier:
+      llvm_unreachable("tok::identifier in raw lexing mode!");
+    case tok::raw_identifier: {
+      // Fill in Result.IdentifierInfo and update the token kind,
+      // looking up the identifier in the identifier table.
+      PP.LookUpIdentifierInfo(Tok);
+
+      // If this is a pp-identifier, for a keyword, highlight it as such.
+      if (Tok.isNot(tok::identifier))
+        HighlightRange(RB, TokOffs, TokOffs+TokLen, BufferStart,
+                       "<span class='keyword'>", "</span>");
+      break;
+    }
+    case tok::comment:
+      HighlightRange(RB, TokOffs, TokOffs+TokLen, BufferStart,
+                     "<span class='comment'>", "</span>");
+      break;
+    case tok::utf8_string_literal:
+      // Chop off the u part of u8 prefix
+      ++TokOffs;
+      --TokLen;
+      // FALL THROUGH to chop the 8
+    case tok::wide_string_literal:
+    case tok::utf16_string_literal:
+    case tok::utf32_string_literal:
+      // Chop off the L, u, U or 8 prefix
+      ++TokOffs;
+      --TokLen;
+      // FALL THROUGH.
+    case tok::string_literal:
+      // FIXME: Exclude the optional ud-suffix from the highlighted range.
+      HighlightRange(RB, TokOffs, TokOffs+TokLen, BufferStart,
+                     "<span class='string_literal'>", "</span>");
+      break;
+    case tok::hash: {
+      // If this is a preprocessor directive, all tokens to end of line are too.
+      if (!Tok.isAtStartOfLine())
+        break;
+
+      // Eat all of the tokens until we get to the next one at the start of
+      // line.
+      unsigned TokEnd = TokOffs+TokLen;
+      L.LexFromRawLexer(Tok);
+      while (!Tok.isAtStartOfLine() && Tok.isNot(tok::eof)) {
+        TokEnd = SM.getFileOffset(Tok.getLocation())+Tok.getLength();
+        L.LexFromRawLexer(Tok);
+      }
+
+      // Find end of line.  This is a hack.
+      HighlightRange(RB, TokOffs, TokEnd, BufferStart,
+                     "<span class='directive'>", "</span>");
+
+      // Don't skip the next token.
+      continue;
+    }
+    }
+
+    L.LexFromRawLexer(Tok);
+  }
+}
+
+/// HighlightMacros - This uses the macro table state from the end of the
+/// file, to re-expand macros and insert (into the HTML) information about the
+/// macro expansions.  This won't be perfectly perfect, but it will be
+/// reasonably close.
+void html::HighlightMacros(Rewriter &R, FileID FID, const Preprocessor& PP) {
+  // Re-lex the raw token stream into a token buffer.
+  const SourceManager &SM = PP.getSourceManager();
+  std::vector<Token> TokenStream;
+
+  const llvm::MemoryBuffer *FromFile = SM.getBuffer(FID);
+  Lexer L(FID, FromFile, SM, PP.getLangOpts());
+
+  // Lex all the tokens in raw mode, to avoid entering #includes or expanding
+  // macros.
+  while (1) {
+    Token Tok;
+    L.LexFromRawLexer(Tok);
+
+    // If this is a # at the start of a line, discard it from the token stream.
+    // We don't want the re-preprocess step to see #defines, #includes or other
+    // preprocessor directives.
+    if (Tok.is(tok::hash) && Tok.isAtStartOfLine())
+      continue;
+
+    // If this is a ## token, change its kind to unknown so that repreprocessing
+    // it will not produce an error.
+    if (Tok.is(tok::hashhash))
+      Tok.setKind(tok::unknown);
+
+    // If this raw token is an identifier, the raw lexer won't have looked up
+    // the corresponding identifier info for it.  Do this now so that it will be
+    // macro expanded when we re-preprocess it.
+    if (Tok.is(tok::raw_identifier))
+      PP.LookUpIdentifierInfo(Tok);
+
+    TokenStream.push_back(Tok);
+
+    if (Tok.is(tok::eof)) break;
+  }
+
+  // Temporarily change the diagnostics object so that we ignore any generated
+  // diagnostics from this pass.
+  DiagnosticsEngine TmpDiags(PP.getDiagnostics().getDiagnosticIDs(),
+                             &PP.getDiagnostics().getDiagnosticOptions(),
+                      new IgnoringDiagConsumer);
+
+  // FIXME: This is a huge hack; we reuse the input preprocessor because we want
+  // its state, but we aren't actually changing it (we hope). This should really
+  // construct a copy of the preprocessor.
+  Preprocessor &TmpPP = const_cast<Preprocessor&>(PP);
+  DiagnosticsEngine *OldDiags = &TmpPP.getDiagnostics();
+  TmpPP.setDiagnostics(TmpDiags);
+
+  // Inform the preprocessor that we don't want comments.
+  TmpPP.SetCommentRetentionState(false, false);
+
+  // We don't want pragmas either. Although we filtered out #pragma, removing
+  // _Pragma and __pragma is much harder.
+  bool PragmasPreviouslyEnabled = TmpPP.getPragmasEnabled();
+  TmpPP.setPragmasEnabled(false);
+
+  // Enter the tokens we just lexed.  This will cause them to be macro expanded
+  // but won't enter sub-files (because we removed #'s).
+  TmpPP.EnterTokenStream(&TokenStream[0], TokenStream.size(), false, false);
+
+  TokenConcatenation ConcatInfo(TmpPP);
+
+  // Lex all the tokens.
+  Token Tok;
+  TmpPP.Lex(Tok);
+  while (Tok.isNot(tok::eof)) {
+    // Ignore non-macro tokens.
+    if (!Tok.getLocation().isMacroID()) {
+      TmpPP.Lex(Tok);
+      continue;
+    }
+
+    // Okay, we have the first token of a macro expansion: highlight the
+    // expansion by inserting a start tag before the macro expansion and
+    // end tag after it.
+    std::pair<SourceLocation, SourceLocation> LLoc =
+      SM.getExpansionRange(Tok.getLocation());
+
+    // Ignore tokens whose instantiation location was not the main file.
+    if (SM.getFileID(LLoc.first) != FID) {
+      TmpPP.Lex(Tok);
+      continue;
+    }
+
+    assert(SM.getFileID(LLoc.second) == FID &&
+           "Start and end of expansion must be in the same ultimate file!");
+
+    std::string Expansion = EscapeText(TmpPP.getSpelling(Tok));
+    unsigned LineLen = Expansion.size();
+
+    Token PrevPrevTok;
+    Token PrevTok = Tok;
+    // Okay, eat this token, getting the next one.
+    TmpPP.Lex(Tok);
+
+    // Skip all the rest of the tokens that are part of this macro
+    // instantiation.  It would be really nice to pop up a window with all the
+    // spelling of the tokens or something.
+    while (!Tok.is(tok::eof) &&
+           SM.getExpansionLoc(Tok.getLocation()) == LLoc.first) {
+      // Insert a newline if the macro expansion is getting large.
+      if (LineLen > 60) {
+        Expansion += "<br>";
+        LineLen = 0;
+      }
+
+      LineLen -= Expansion.size();
+
+      // If the tokens were already space separated, or if they must be to avoid
+      // them being implicitly pasted, add a space between them.
+      if (Tok.hasLeadingSpace() ||
+          ConcatInfo.AvoidConcat(PrevPrevTok, PrevTok, Tok))
+        Expansion += ' ';
+
+      // Escape any special characters in the token text.
+      Expansion += EscapeText(TmpPP.getSpelling(Tok));
+      LineLen += Expansion.size();
+
+      PrevPrevTok = PrevTok;
+      PrevTok = Tok;
+      TmpPP.Lex(Tok);
+    }
+
+
+    // Insert the expansion as the end tag, so that multi-line macros all get
+    // highlighted.
+    Expansion = "<span class='expansion'>" + Expansion + "</span></span>";
+
+    HighlightRange(R, LLoc.first, LLoc.second,
+                   "<span class='macro'>", Expansion.c_str());
+  }
+
+  // Restore the preprocessor's old state.
+  TmpPP.setDiagnostics(*OldDiags);
+  TmpPP.setPragmasEnabled(PragmasPreviouslyEnabled);
+}
diff --git a/lib/Rewrite/Makefile b/lib/Rewrite/Makefile
index 0be84d4..5fef9b2 100644
--- a/lib/Rewrite/Makefile
+++ b/lib/Rewrite/Makefile
@@ -1,4 +1,4 @@
-##===- clang/lib/StaticAnalyzer/Makefile -------------------*- Makefile -*-===##
+##===- clang/lib/Rewrite/Makefile --------------------------*- Makefile -*-===##
 # 
 #                     The LLVM Compiler Infrastructure
 #
@@ -6,9 +6,13 @@
 # License. See LICENSE.TXT for details.
 # 
 ##===----------------------------------------------------------------------===##
+#
+# This implements code transformation / rewriting facilities.
+#
+##===----------------------------------------------------------------------===##
 
 CLANG_LEVEL := ../..
-DIRS := Frontend
-PARALLEL_DIRS := Core
+LIBRARYNAME := clangRewrite
 
 include $(CLANG_LEVEL)/Makefile
+
diff --git a/lib/Rewrite/RewriteRope.cpp b/lib/Rewrite/RewriteRope.cpp
new file mode 100644
index 0000000..ef8abfc
--- /dev/null
+++ b/lib/Rewrite/RewriteRope.cpp
@@ -0,0 +1,806 @@
+//===--- RewriteRope.cpp - Rope specialized for rewriter --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements the RewriteRope class, which is a powerful string.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Rewrite/Core/RewriteRope.h"
+#include "clang/Basic/LLVM.h"
+#include <algorithm>
+using namespace clang;
+
+/// RewriteRope is a "strong" string class, designed to make insertions and
+/// deletions in the middle of the string nearly constant time (really, they are
+/// O(log N), but with a very low constant factor).
+///
+/// The implementation of this datastructure is a conceptual linear sequence of
+/// RopePiece elements.  Each RopePiece represents a view on a separately
+/// allocated and reference counted string.  This means that splitting a very
+/// long string can be done in constant time by splitting a RopePiece that
+/// references the whole string into two rope pieces that reference each half.
+/// Once split, another string can be inserted in between the two halves by
+/// inserting a RopePiece in between the two others.  All of this is very
+/// inexpensive: it takes time proportional to the number of RopePieces, not the
+/// length of the strings they represent.
+///
+/// While a linear sequences of RopePieces is the conceptual model, the actual
+/// implementation captures them in an adapted B+ Tree.  Using a B+ tree (which
+/// is a tree that keeps the values in the leaves and has where each node
+/// contains a reasonable number of pointers to children/values) allows us to
+/// maintain efficient operation when the RewriteRope contains a *huge* number
+/// of RopePieces.  The basic idea of the B+ Tree is that it allows us to find
+/// the RopePiece corresponding to some offset very efficiently, and it
+/// automatically balances itself on insertions of RopePieces (which can happen
+/// for both insertions and erases of string ranges).
+///
+/// The one wrinkle on the theory is that we don't attempt to keep the tree
+/// properly balanced when erases happen.  Erases of string data can both insert
+/// new RopePieces (e.g. when the middle of some other rope piece is deleted,
+/// which results in two rope pieces, which is just like an insert) or it can
+/// reduce the number of RopePieces maintained by the B+Tree.  In the case when
+/// the number of RopePieces is reduced, we don't attempt to maintain the
+/// standard 'invariant' that each node in the tree contains at least
+/// 'WidthFactor' children/values.  For our use cases, this doesn't seem to
+/// matter.
+///
+/// The implementation below is primarily implemented in terms of three classes:
+///   RopePieceBTreeNode - Common base class for:
+///
+///     RopePieceBTreeLeaf - Directly manages up to '2*WidthFactor' RopePiece
+///          nodes.  This directly represents a chunk of the string with those
+///          RopePieces contatenated.
+///     RopePieceBTreeInterior - An interior node in the B+ Tree, which manages
+///          up to '2*WidthFactor' other nodes in the tree.
+
+
+//===----------------------------------------------------------------------===//
+// RopePieceBTreeNode Class
+//===----------------------------------------------------------------------===//
+
+namespace {
+  /// RopePieceBTreeNode - Common base class of RopePieceBTreeLeaf and
+  /// RopePieceBTreeInterior.  This provides some 'virtual' dispatching methods
+  /// and a flag that determines which subclass the instance is.  Also
+  /// important, this node knows the full extend of the node, including any
+  /// children that it has.  This allows efficient skipping over entire subtrees
+  /// when looking for an offset in the BTree.
+  class RopePieceBTreeNode {
+  protected:
+    /// WidthFactor - This controls the number of K/V slots held in the BTree:
+    /// how wide it is.  Each level of the BTree is guaranteed to have at least
+    /// 'WidthFactor' elements in it (either ropepieces or children), (except
+    /// the root, which may have less) and may have at most 2*WidthFactor
+    /// elements.
+    enum { WidthFactor = 8 };
+
+    /// Size - This is the number of bytes of file this node (including any
+    /// potential children) covers.
+    unsigned Size;
+
+    /// IsLeaf - True if this is an instance of RopePieceBTreeLeaf, false if it
+    /// is an instance of RopePieceBTreeInterior.
+    bool IsLeaf;
+
+    RopePieceBTreeNode(bool isLeaf) : Size(0), IsLeaf(isLeaf) {}
+    ~RopePieceBTreeNode() {}
+  public:
+
+    bool isLeaf() const { return IsLeaf; }
+    unsigned size() const { return Size; }
+
+    void Destroy();
+
+    /// split - Split the range containing the specified offset so that we are
+    /// guaranteed that there is a place to do an insertion at the specified
+    /// offset.  The offset is relative, so "0" is the start of the node.
+    ///
+    /// If there is no space in this subtree for the extra piece, the extra tree
+    /// node is returned and must be inserted into a parent.
+    RopePieceBTreeNode *split(unsigned Offset);
+
+    /// insert - Insert the specified ropepiece into this tree node at the
+    /// specified offset.  The offset is relative, so "0" is the start of the
+    /// node.
+    ///
+    /// If there is no space in this subtree for the extra piece, the extra tree
+    /// node is returned and must be inserted into a parent.
+    RopePieceBTreeNode *insert(unsigned Offset, const RopePiece &R);
+
+    /// erase - Remove NumBytes from this node at the specified offset.  We are
+    /// guaranteed that there is a split at Offset.
+    void erase(unsigned Offset, unsigned NumBytes);
+
+  };
+} // end anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// RopePieceBTreeLeaf Class
+//===----------------------------------------------------------------------===//
+
+namespace {
+  /// RopePieceBTreeLeaf - Directly manages up to '2*WidthFactor' RopePiece
+  /// nodes.  This directly represents a chunk of the string with those
+  /// RopePieces contatenated.  Since this is a B+Tree, all values (in this case
+  /// instances of RopePiece) are stored in leaves like this.  To make iteration
+  /// over the leaves efficient, they maintain a singly linked list through the
+  /// NextLeaf field.  This allows the B+Tree forward iterator to be constant
+  /// time for all increments.
+  class RopePieceBTreeLeaf : public RopePieceBTreeNode {
+    /// NumPieces - This holds the number of rope pieces currently active in the
+    /// Pieces array.
+    unsigned char NumPieces;
+
+    /// Pieces - This tracks the file chunks currently in this leaf.
+    ///
+    RopePiece Pieces[2*WidthFactor];
+
+    /// NextLeaf - This is a pointer to the next leaf in the tree, allowing
+    /// efficient in-order forward iteration of the tree without traversal.
+    RopePieceBTreeLeaf **PrevLeaf, *NextLeaf;
+  public:
+    RopePieceBTreeLeaf() : RopePieceBTreeNode(true), NumPieces(0),
+                           PrevLeaf(nullptr), NextLeaf(nullptr) {}
+    ~RopePieceBTreeLeaf() {
+      if (PrevLeaf || NextLeaf)
+        removeFromLeafInOrder();
+      clear();
+    }
+
+    bool isFull() const { return NumPieces == 2*WidthFactor; }
+
+    /// clear - Remove all rope pieces from this leaf.
+    void clear() {
+      while (NumPieces)
+        Pieces[--NumPieces] = RopePiece();
+      Size = 0;
+    }
+
+    unsigned getNumPieces() const { return NumPieces; }
+
+    const RopePiece &getPiece(unsigned i) const {
+      assert(i < getNumPieces() && "Invalid piece ID");
+      return Pieces[i];
+    }
+
+    const RopePieceBTreeLeaf *getNextLeafInOrder() const { return NextLeaf; }
+    void insertAfterLeafInOrder(RopePieceBTreeLeaf *Node) {
+      assert(!PrevLeaf && !NextLeaf && "Already in ordering");
+
+      NextLeaf = Node->NextLeaf;
+      if (NextLeaf)
+        NextLeaf->PrevLeaf = &NextLeaf;
+      PrevLeaf = &Node->NextLeaf;
+      Node->NextLeaf = this;
+    }
+
+    void removeFromLeafInOrder() {
+      if (PrevLeaf) {
+        *PrevLeaf = NextLeaf;
+        if (NextLeaf)
+          NextLeaf->PrevLeaf = PrevLeaf;
+      } else if (NextLeaf) {
+        NextLeaf->PrevLeaf = nullptr;
+      }
+    }
+
+    /// FullRecomputeSizeLocally - This method recomputes the 'Size' field by
+    /// summing the size of all RopePieces.
+    void FullRecomputeSizeLocally() {
+      Size = 0;
+      for (unsigned i = 0, e = getNumPieces(); i != e; ++i)
+        Size += getPiece(i).size();
+    }
+
+    /// split - Split the range containing the specified offset so that we are
+    /// guaranteed that there is a place to do an insertion at the specified
+    /// offset.  The offset is relative, so "0" is the start of the node.
+    ///
+    /// If there is no space in this subtree for the extra piece, the extra tree
+    /// node is returned and must be inserted into a parent.
+    RopePieceBTreeNode *split(unsigned Offset);
+
+    /// insert - Insert the specified ropepiece into this tree node at the
+    /// specified offset.  The offset is relative, so "0" is the start of the
+    /// node.
+    ///
+    /// If there is no space in this subtree for the extra piece, the extra tree
+    /// node is returned and must be inserted into a parent.
+    RopePieceBTreeNode *insert(unsigned Offset, const RopePiece &R);
+
+
+    /// erase - Remove NumBytes from this node at the specified offset.  We are
+    /// guaranteed that there is a split at Offset.
+    void erase(unsigned Offset, unsigned NumBytes);
+
+    static inline bool classof(const RopePieceBTreeNode *N) {
+      return N->isLeaf();
+    }
+  };
+} // end anonymous namespace
+
+/// split - Split the range containing the specified offset so that we are
+/// guaranteed that there is a place to do an insertion at the specified
+/// offset.  The offset is relative, so "0" is the start of the node.
+///
+/// If there is no space in this subtree for the extra piece, the extra tree
+/// node is returned and must be inserted into a parent.
+RopePieceBTreeNode *RopePieceBTreeLeaf::split(unsigned Offset) {
+  // Find the insertion point.  We are guaranteed that there is a split at the
+  // specified offset so find it.
+  if (Offset == 0 || Offset == size()) {
+    // Fastpath for a common case.  There is already a splitpoint at the end.
+    return nullptr;
+  }
+
+  // Find the piece that this offset lands in.
+  unsigned PieceOffs = 0;
+  unsigned i = 0;
+  while (Offset >= PieceOffs+Pieces[i].size()) {
+    PieceOffs += Pieces[i].size();
+    ++i;
+  }
+
+  // If there is already a split point at the specified offset, just return
+  // success.
+  if (PieceOffs == Offset)
+    return nullptr;
+
+  // Otherwise, we need to split piece 'i' at Offset-PieceOffs.  Convert Offset
+  // to being Piece relative.
+  unsigned IntraPieceOffset = Offset-PieceOffs;
+
+  // We do this by shrinking the RopePiece and then doing an insert of the tail.
+  RopePiece Tail(Pieces[i].StrData, Pieces[i].StartOffs+IntraPieceOffset,
+                 Pieces[i].EndOffs);
+  Size -= Pieces[i].size();
+  Pieces[i].EndOffs = Pieces[i].StartOffs+IntraPieceOffset;
+  Size += Pieces[i].size();
+
+  return insert(Offset, Tail);
+}
+
+
+/// insert - Insert the specified RopePiece into this tree node at the
+/// specified offset.  The offset is relative, so "0" is the start of the node.
+///
+/// If there is no space in this subtree for the extra piece, the extra tree
+/// node is returned and must be inserted into a parent.
+RopePieceBTreeNode *RopePieceBTreeLeaf::insert(unsigned Offset,
+                                               const RopePiece &R) {
+  // If this node is not full, insert the piece.
+  if (!isFull()) {
+    // Find the insertion point.  We are guaranteed that there is a split at the
+    // specified offset so find it.
+    unsigned i = 0, e = getNumPieces();
+    if (Offset == size()) {
+      // Fastpath for a common case.
+      i = e;
+    } else {
+      unsigned SlotOffs = 0;
+      for (; Offset > SlotOffs; ++i)
+        SlotOffs += getPiece(i).size();
+      assert(SlotOffs == Offset && "Split didn't occur before insertion!");
+    }
+
+    // For an insertion into a non-full leaf node, just insert the value in
+    // its sorted position.  This requires moving later values over.
+    for (; i != e; --e)
+      Pieces[e] = Pieces[e-1];
+    Pieces[i] = R;
+    ++NumPieces;
+    Size += R.size();
+    return nullptr;
+  }
+
+  // Otherwise, if this is leaf is full, split it in two halves.  Since this
+  // node is full, it contains 2*WidthFactor values.  We move the first
+  // 'WidthFactor' values to the LHS child (which we leave in this node) and
+  // move the last 'WidthFactor' values into the RHS child.
+
+  // Create the new node.
+  RopePieceBTreeLeaf *NewNode = new RopePieceBTreeLeaf();
+
+  // Move over the last 'WidthFactor' values from here to NewNode.
+  std::copy(&Pieces[WidthFactor], &Pieces[2*WidthFactor],
+            &NewNode->Pieces[0]);
+  // Replace old pieces with null RopePieces to drop refcounts.
+  std::fill(&Pieces[WidthFactor], &Pieces[2*WidthFactor], RopePiece());
+
+  // Decrease the number of values in the two nodes.
+  NewNode->NumPieces = NumPieces = WidthFactor;
+
+  // Recompute the two nodes' size.
+  NewNode->FullRecomputeSizeLocally();
+  FullRecomputeSizeLocally();
+
+  // Update the list of leaves.
+  NewNode->insertAfterLeafInOrder(this);
+
+  // These insertions can't fail.
+  if (this->size() >= Offset)
+    this->insert(Offset, R);
+  else
+    NewNode->insert(Offset - this->size(), R);
+  return NewNode;
+}
+
+/// erase - Remove NumBytes from this node at the specified offset.  We are
+/// guaranteed that there is a split at Offset.
+void RopePieceBTreeLeaf::erase(unsigned Offset, unsigned NumBytes) {
+  // Since we are guaranteed that there is a split at Offset, we start by
+  // finding the Piece that starts there.
+  unsigned PieceOffs = 0;
+  unsigned i = 0;
+  for (; Offset > PieceOffs; ++i)
+    PieceOffs += getPiece(i).size();
+  assert(PieceOffs == Offset && "Split didn't occur before erase!");
+
+  unsigned StartPiece = i;
+
+  // Figure out how many pieces completely cover 'NumBytes'.  We want to remove
+  // all of them.
+  for (; Offset+NumBytes > PieceOffs+getPiece(i).size(); ++i)
+    PieceOffs += getPiece(i).size();
+
+  // If we exactly include the last one, include it in the region to delete.
+  if (Offset+NumBytes == PieceOffs+getPiece(i).size())
+    PieceOffs += getPiece(i).size(), ++i;
+
+  // If we completely cover some RopePieces, erase them now.
+  if (i != StartPiece) {
+    unsigned NumDeleted = i-StartPiece;
+    for (; i != getNumPieces(); ++i)
+      Pieces[i-NumDeleted] = Pieces[i];
+
+    // Drop references to dead rope pieces.
+    std::fill(&Pieces[getNumPieces()-NumDeleted], &Pieces[getNumPieces()],
+              RopePiece());
+    NumPieces -= NumDeleted;
+
+    unsigned CoverBytes = PieceOffs-Offset;
+    NumBytes -= CoverBytes;
+    Size -= CoverBytes;
+  }
+
+  // If we completely removed some stuff, we could be done.
+  if (NumBytes == 0) return;
+
+  // Okay, now might be erasing part of some Piece.  If this is the case, then
+  // move the start point of the piece.
+  assert(getPiece(StartPiece).size() > NumBytes);
+  Pieces[StartPiece].StartOffs += NumBytes;
+
+  // The size of this node just shrunk by NumBytes.
+  Size -= NumBytes;
+}
+
+//===----------------------------------------------------------------------===//
+// RopePieceBTreeInterior Class
+//===----------------------------------------------------------------------===//
+
+namespace {
+  /// RopePieceBTreeInterior - This represents an interior node in the B+Tree,
+  /// which holds up to 2*WidthFactor pointers to child nodes.
+  class RopePieceBTreeInterior : public RopePieceBTreeNode {
+    /// NumChildren - This holds the number of children currently active in the
+    /// Children array.
+    unsigned char NumChildren;
+    RopePieceBTreeNode *Children[2*WidthFactor];
+  public:
+    RopePieceBTreeInterior() : RopePieceBTreeNode(false), NumChildren(0) {}
+
+    RopePieceBTreeInterior(RopePieceBTreeNode *LHS, RopePieceBTreeNode *RHS)
+    : RopePieceBTreeNode(false) {
+      Children[0] = LHS;
+      Children[1] = RHS;
+      NumChildren = 2;
+      Size = LHS->size() + RHS->size();
+    }
+
+    ~RopePieceBTreeInterior() {
+      for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
+        Children[i]->Destroy();
+    }
+
+    bool isFull() const { return NumChildren == 2*WidthFactor; }
+
+    unsigned getNumChildren() const { return NumChildren; }
+    const RopePieceBTreeNode *getChild(unsigned i) const {
+      assert(i < NumChildren && "invalid child #");
+      return Children[i];
+    }
+    RopePieceBTreeNode *getChild(unsigned i) {
+      assert(i < NumChildren && "invalid child #");
+      return Children[i];
+    }
+
+    /// FullRecomputeSizeLocally - Recompute the Size field of this node by
+    /// summing up the sizes of the child nodes.
+    void FullRecomputeSizeLocally() {
+      Size = 0;
+      for (unsigned i = 0, e = getNumChildren(); i != e; ++i)
+        Size += getChild(i)->size();
+    }
+
+
+    /// split - Split the range containing the specified offset so that we are
+    /// guaranteed that there is a place to do an insertion at the specified
+    /// offset.  The offset is relative, so "0" is the start of the node.
+    ///
+    /// If there is no space in this subtree for the extra piece, the extra tree
+    /// node is returned and must be inserted into a parent.
+    RopePieceBTreeNode *split(unsigned Offset);
+
+
+    /// insert - Insert the specified ropepiece into this tree node at the
+    /// specified offset.  The offset is relative, so "0" is the start of the
+    /// node.
+    ///
+    /// If there is no space in this subtree for the extra piece, the extra tree
+    /// node is returned and must be inserted into a parent.
+    RopePieceBTreeNode *insert(unsigned Offset, const RopePiece &R);
+
+    /// HandleChildPiece - A child propagated an insertion result up to us.
+    /// Insert the new child, and/or propagate the result further up the tree.
+    RopePieceBTreeNode *HandleChildPiece(unsigned i, RopePieceBTreeNode *RHS);
+
+    /// erase - Remove NumBytes from this node at the specified offset.  We are
+    /// guaranteed that there is a split at Offset.
+    void erase(unsigned Offset, unsigned NumBytes);
+
+    static inline bool classof(const RopePieceBTreeNode *N) {
+      return !N->isLeaf();
+    }
+  };
+} // end anonymous namespace
+
+/// split - Split the range containing the specified offset so that we are
+/// guaranteed that there is a place to do an insertion at the specified
+/// offset.  The offset is relative, so "0" is the start of the node.
+///
+/// If there is no space in this subtree for the extra piece, the extra tree
+/// node is returned and must be inserted into a parent.
+RopePieceBTreeNode *RopePieceBTreeInterior::split(unsigned Offset) {
+  // Figure out which child to split.
+  if (Offset == 0 || Offset == size())
+    return nullptr; // If we have an exact offset, we're already split.
+
+  unsigned ChildOffset = 0;
+  unsigned i = 0;
+  for (; Offset >= ChildOffset+getChild(i)->size(); ++i)
+    ChildOffset += getChild(i)->size();
+
+  // If already split there, we're done.
+  if (ChildOffset == Offset)
+    return nullptr;
+
+  // Otherwise, recursively split the child.
+  if (RopePieceBTreeNode *RHS = getChild(i)->split(Offset-ChildOffset))
+    return HandleChildPiece(i, RHS);
+  return nullptr; // Done!
+}
+
+/// insert - Insert the specified ropepiece into this tree node at the
+/// specified offset.  The offset is relative, so "0" is the start of the
+/// node.
+///
+/// If there is no space in this subtree for the extra piece, the extra tree
+/// node is returned and must be inserted into a parent.
+RopePieceBTreeNode *RopePieceBTreeInterior::insert(unsigned Offset,
+                                                   const RopePiece &R) {
+  // Find the insertion point.  We are guaranteed that there is a split at the
+  // specified offset so find it.
+  unsigned i = 0, e = getNumChildren();
+
+  unsigned ChildOffs = 0;
+  if (Offset == size()) {
+    // Fastpath for a common case.  Insert at end of last child.
+    i = e-1;
+    ChildOffs = size()-getChild(i)->size();
+  } else {
+    for (; Offset > ChildOffs+getChild(i)->size(); ++i)
+      ChildOffs += getChild(i)->size();
+  }
+
+  Size += R.size();
+
+  // Insert at the end of this child.
+  if (RopePieceBTreeNode *RHS = getChild(i)->insert(Offset-ChildOffs, R))
+    return HandleChildPiece(i, RHS);
+
+  return nullptr;
+}
+
+/// HandleChildPiece - A child propagated an insertion result up to us.
+/// Insert the new child, and/or propagate the result further up the tree.
+RopePieceBTreeNode *
+RopePieceBTreeInterior::HandleChildPiece(unsigned i, RopePieceBTreeNode *RHS) {
+  // Otherwise the child propagated a subtree up to us as a new child.  See if
+  // we have space for it here.
+  if (!isFull()) {
+    // Insert RHS after child 'i'.
+    if (i + 1 != getNumChildren())
+      memmove(&Children[i+2], &Children[i+1],
+              (getNumChildren()-i-1)*sizeof(Children[0]));
+    Children[i+1] = RHS;
+    ++NumChildren;
+    return nullptr;
+  }
+
+  // Okay, this node is full.  Split it in half, moving WidthFactor children to
+  // a newly allocated interior node.
+
+  // Create the new node.
+  RopePieceBTreeInterior *NewNode = new RopePieceBTreeInterior();
+
+  // Move over the last 'WidthFactor' values from here to NewNode.
+  memcpy(&NewNode->Children[0], &Children[WidthFactor],
+         WidthFactor*sizeof(Children[0]));
+
+  // Decrease the number of values in the two nodes.
+  NewNode->NumChildren = NumChildren = WidthFactor;
+
+  // Finally, insert the two new children in the side the can (now) hold them.
+  // These insertions can't fail.
+  if (i < WidthFactor)
+    this->HandleChildPiece(i, RHS);
+  else
+    NewNode->HandleChildPiece(i-WidthFactor, RHS);
+
+  // Recompute the two nodes' size.
+  NewNode->FullRecomputeSizeLocally();
+  FullRecomputeSizeLocally();
+  return NewNode;
+}
+
+/// erase - Remove NumBytes from this node at the specified offset.  We are
+/// guaranteed that there is a split at Offset.
+void RopePieceBTreeInterior::erase(unsigned Offset, unsigned NumBytes) {
+  // This will shrink this node by NumBytes.
+  Size -= NumBytes;
+
+  // Find the first child that overlaps with Offset.
+  unsigned i = 0;
+  for (; Offset >= getChild(i)->size(); ++i)
+    Offset -= getChild(i)->size();
+
+  // Propagate the delete request into overlapping children, or completely
+  // delete the children as appropriate.
+  while (NumBytes) {
+    RopePieceBTreeNode *CurChild = getChild(i);
+
+    // If we are deleting something contained entirely in the child, pass on the
+    // request.
+    if (Offset+NumBytes < CurChild->size()) {
+      CurChild->erase(Offset, NumBytes);
+      return;
+    }
+
+    // If this deletion request starts somewhere in the middle of the child, it
+    // must be deleting to the end of the child.
+    if (Offset) {
+      unsigned BytesFromChild = CurChild->size()-Offset;
+      CurChild->erase(Offset, BytesFromChild);
+      NumBytes -= BytesFromChild;
+      // Start at the beginning of the next child.
+      Offset = 0;
+      ++i;
+      continue;
+    }
+
+    // If the deletion request completely covers the child, delete it and move
+    // the rest down.
+    NumBytes -= CurChild->size();
+    CurChild->Destroy();
+    --NumChildren;
+    if (i != getNumChildren())
+      memmove(&Children[i], &Children[i+1],
+              (getNumChildren()-i)*sizeof(Children[0]));
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// RopePieceBTreeNode Implementation
+//===----------------------------------------------------------------------===//
+
+void RopePieceBTreeNode::Destroy() {
+  if (RopePieceBTreeLeaf *Leaf = dyn_cast<RopePieceBTreeLeaf>(this))
+    delete Leaf;
+  else
+    delete cast<RopePieceBTreeInterior>(this);
+}
+
+/// split - Split the range containing the specified offset so that we are
+/// guaranteed that there is a place to do an insertion at the specified
+/// offset.  The offset is relative, so "0" is the start of the node.
+///
+/// If there is no space in this subtree for the extra piece, the extra tree
+/// node is returned and must be inserted into a parent.
+RopePieceBTreeNode *RopePieceBTreeNode::split(unsigned Offset) {
+  assert(Offset <= size() && "Invalid offset to split!");
+  if (RopePieceBTreeLeaf *Leaf = dyn_cast<RopePieceBTreeLeaf>(this))
+    return Leaf->split(Offset);
+  return cast<RopePieceBTreeInterior>(this)->split(Offset);
+}
+
+/// insert - Insert the specified ropepiece into this tree node at the
+/// specified offset.  The offset is relative, so "0" is the start of the
+/// node.
+///
+/// If there is no space in this subtree for the extra piece, the extra tree
+/// node is returned and must be inserted into a parent.
+RopePieceBTreeNode *RopePieceBTreeNode::insert(unsigned Offset,
+                                               const RopePiece &R) {
+  assert(Offset <= size() && "Invalid offset to insert!");
+  if (RopePieceBTreeLeaf *Leaf = dyn_cast<RopePieceBTreeLeaf>(this))
+    return Leaf->insert(Offset, R);
+  return cast<RopePieceBTreeInterior>(this)->insert(Offset, R);
+}
+
+/// erase - Remove NumBytes from this node at the specified offset.  We are
+/// guaranteed that there is a split at Offset.
+void RopePieceBTreeNode::erase(unsigned Offset, unsigned NumBytes) {
+  assert(Offset+NumBytes <= size() && "Invalid offset to erase!");
+  if (RopePieceBTreeLeaf *Leaf = dyn_cast<RopePieceBTreeLeaf>(this))
+    return Leaf->erase(Offset, NumBytes);
+  return cast<RopePieceBTreeInterior>(this)->erase(Offset, NumBytes);
+}
+
+
+//===----------------------------------------------------------------------===//
+// RopePieceBTreeIterator Implementation
+//===----------------------------------------------------------------------===//
+
+static const RopePieceBTreeLeaf *getCN(const void *P) {
+  return static_cast<const RopePieceBTreeLeaf*>(P);
+}
+
+// begin iterator.
+RopePieceBTreeIterator::RopePieceBTreeIterator(const void *n) {
+  const RopePieceBTreeNode *N = static_cast<const RopePieceBTreeNode*>(n);
+
+  // Walk down the left side of the tree until we get to a leaf.
+  while (const RopePieceBTreeInterior *IN = dyn_cast<RopePieceBTreeInterior>(N))
+    N = IN->getChild(0);
+
+  // We must have at least one leaf.
+  CurNode = cast<RopePieceBTreeLeaf>(N);
+
+  // If we found a leaf that happens to be empty, skip over it until we get
+  // to something full.
+  while (CurNode && getCN(CurNode)->getNumPieces() == 0)
+    CurNode = getCN(CurNode)->getNextLeafInOrder();
+
+  if (CurNode)
+    CurPiece = &getCN(CurNode)->getPiece(0);
+  else  // Empty tree, this is an end() iterator.
+    CurPiece = nullptr;
+  CurChar = 0;
+}
+
+void RopePieceBTreeIterator::MoveToNextPiece() {
+  if (CurPiece != &getCN(CurNode)->getPiece(getCN(CurNode)->getNumPieces()-1)) {
+    CurChar = 0;
+    ++CurPiece;
+    return;
+  }
+
+  // Find the next non-empty leaf node.
+  do
+    CurNode = getCN(CurNode)->getNextLeafInOrder();
+  while (CurNode && getCN(CurNode)->getNumPieces() == 0);
+
+  if (CurNode)
+    CurPiece = &getCN(CurNode)->getPiece(0);
+  else // Hit end().
+    CurPiece = nullptr;
+  CurChar = 0;
+}
+
+//===----------------------------------------------------------------------===//
+// RopePieceBTree Implementation
+//===----------------------------------------------------------------------===//
+
+static RopePieceBTreeNode *getRoot(void *P) {
+  return static_cast<RopePieceBTreeNode*>(P);
+}
+
+RopePieceBTree::RopePieceBTree() {
+  Root = new RopePieceBTreeLeaf();
+}
+RopePieceBTree::RopePieceBTree(const RopePieceBTree &RHS) {
+  assert(RHS.empty() && "Can't copy non-empty tree yet");
+  Root = new RopePieceBTreeLeaf();
+}
+RopePieceBTree::~RopePieceBTree() {
+  getRoot(Root)->Destroy();
+}
+
+unsigned RopePieceBTree::size() const {
+  return getRoot(Root)->size();
+}
+
+void RopePieceBTree::clear() {
+  if (RopePieceBTreeLeaf *Leaf = dyn_cast<RopePieceBTreeLeaf>(getRoot(Root)))
+    Leaf->clear();
+  else {
+    getRoot(Root)->Destroy();
+    Root = new RopePieceBTreeLeaf();
+  }
+}
+
+void RopePieceBTree::insert(unsigned Offset, const RopePiece &R) {
+  // #1. Split at Offset.
+  if (RopePieceBTreeNode *RHS = getRoot(Root)->split(Offset))
+    Root = new RopePieceBTreeInterior(getRoot(Root), RHS);
+
+  // #2. Do the insertion.
+  if (RopePieceBTreeNode *RHS = getRoot(Root)->insert(Offset, R))
+    Root = new RopePieceBTreeInterior(getRoot(Root), RHS);
+}
+
+void RopePieceBTree::erase(unsigned Offset, unsigned NumBytes) {
+  // #1. Split at Offset.
+  if (RopePieceBTreeNode *RHS = getRoot(Root)->split(Offset))
+    Root = new RopePieceBTreeInterior(getRoot(Root), RHS);
+
+  // #2. Do the erasing.
+  getRoot(Root)->erase(Offset, NumBytes);
+}
+
+//===----------------------------------------------------------------------===//
+// RewriteRope Implementation
+//===----------------------------------------------------------------------===//
+
+/// MakeRopeString - This copies the specified byte range into some instance of
+/// RopeRefCountString, and return a RopePiece that represents it.  This uses
+/// the AllocBuffer object to aggregate requests for small strings into one
+/// allocation instead of doing tons of tiny allocations.
+RopePiece RewriteRope::MakeRopeString(const char *Start, const char *End) {
+  unsigned Len = End-Start;
+  assert(Len && "Zero length RopePiece is invalid!");
+
+  // If we have space for this string in the current alloc buffer, use it.
+  if (AllocOffs+Len <= AllocChunkSize) {
+    memcpy(AllocBuffer->Data+AllocOffs, Start, Len);
+    AllocOffs += Len;
+    return RopePiece(AllocBuffer, AllocOffs-Len, AllocOffs);
+  }
+
+  // If we don't have enough room because this specific allocation is huge,
+  // just allocate a new rope piece for it alone.
+  if (Len > AllocChunkSize) {
+    unsigned Size = End-Start+sizeof(RopeRefCountString)-1;
+    RopeRefCountString *Res =
+      reinterpret_cast<RopeRefCountString *>(new char[Size]);
+    Res->RefCount = 0;
+    memcpy(Res->Data, Start, End-Start);
+    return RopePiece(Res, 0, End-Start);
+  }
+
+  // Otherwise, this was a small request but we just don't have space for it
+  // Make a new chunk and share it with later allocations.
+
+  if (AllocBuffer)
+    AllocBuffer->dropRef();
+
+  unsigned AllocSize = offsetof(RopeRefCountString, Data) + AllocChunkSize;
+  AllocBuffer = reinterpret_cast<RopeRefCountString *>(new char[AllocSize]);
+  AllocBuffer->RefCount = 0;
+  memcpy(AllocBuffer->Data, Start, Len);
+  AllocOffs = Len;
+
+  // Start out the new allocation with a refcount of 1, since we have an
+  // internal reference to it.
+  AllocBuffer->addRef();
+  return RopePiece(AllocBuffer, 0, Len);
+}
+
+
diff --git a/lib/Rewrite/Rewriter.cpp b/lib/Rewrite/Rewriter.cpp
new file mode 100644
index 0000000..eab4ccf
--- /dev/null
+++ b/lib/Rewrite/Rewriter.cpp
@@ -0,0 +1,495 @@
+//===--- Rewriter.cpp - Code rewriting interface --------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the Rewriter class, which is used for code
+//  transformations.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Rewrite/Core/Rewriter.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/PrettyPrinter.h"
+#include "clang/AST/Stmt.h"
+#include "clang/Basic/DiagnosticIDs.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/Lexer.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Config/llvm-config.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace clang;
+
+raw_ostream &RewriteBuffer::write(raw_ostream &os) const {
+  // Walk RewriteRope chunks efficiently using MoveToNextPiece() instead of the
+  // character iterator.
+  for (RopePieceBTreeIterator I = begin(), E = end(); I != E;
+       I.MoveToNextPiece())
+    os << I.piece();
+  return os;
+}
+
+/// \brief Return true if this character is non-new-line whitespace:
+/// ' ', '\\t', '\\f', '\\v', '\\r'.
+static inline bool isWhitespace(unsigned char c) {
+  switch (c) {
+  case ' ':
+  case '\t':
+  case '\f':
+  case '\v':
+  case '\r':
+    return true;
+  default:
+    return false;
+  }
+}
+
+void RewriteBuffer::RemoveText(unsigned OrigOffset, unsigned Size,
+                               bool removeLineIfEmpty) {
+  // Nothing to remove, exit early.
+  if (Size == 0) return;
+
+  unsigned RealOffset = getMappedOffset(OrigOffset, true);
+  assert(RealOffset+Size < Buffer.size() && "Invalid location");
+
+  // Remove the dead characters.
+  Buffer.erase(RealOffset, Size);
+
+  // Add a delta so that future changes are offset correctly.
+  AddReplaceDelta(OrigOffset, -Size);
+
+  if (removeLineIfEmpty) {
+    // Find the line that the remove occurred and if it is completely empty
+    // remove the line as well.
+
+    iterator curLineStart = begin();
+    unsigned curLineStartOffs = 0;
+    iterator posI = begin();
+    for (unsigned i = 0; i != RealOffset; ++i) {
+      if (*posI == '\n') {
+        curLineStart = posI;
+        ++curLineStart;
+        curLineStartOffs = i + 1;
+      }
+      ++posI;
+    }
+  
+    unsigned lineSize = 0;
+    posI = curLineStart;
+    while (posI != end() && isWhitespace(*posI)) {
+      ++posI;
+      ++lineSize;
+    }
+    if (posI != end() && *posI == '\n') {
+      Buffer.erase(curLineStartOffs, lineSize + 1/* + '\n'*/);
+      AddReplaceDelta(curLineStartOffs, -(lineSize + 1/* + '\n'*/));
+    }
+  }
+}
+
+void RewriteBuffer::InsertText(unsigned OrigOffset, StringRef Str,
+                               bool InsertAfter) {
+
+  // Nothing to insert, exit early.
+  if (Str.empty()) return;
+
+  unsigned RealOffset = getMappedOffset(OrigOffset, InsertAfter);
+  Buffer.insert(RealOffset, Str.begin(), Str.end());
+
+  // Add a delta so that future changes are offset correctly.
+  AddInsertDelta(OrigOffset, Str.size());
+}
+
+/// ReplaceText - This method replaces a range of characters in the input
+/// buffer with a new string.  This is effectively a combined "remove+insert"
+/// operation.
+void RewriteBuffer::ReplaceText(unsigned OrigOffset, unsigned OrigLength,
+                                StringRef NewStr) {
+  unsigned RealOffset = getMappedOffset(OrigOffset, true);
+  Buffer.erase(RealOffset, OrigLength);
+  Buffer.insert(RealOffset, NewStr.begin(), NewStr.end());
+  if (OrigLength != NewStr.size())
+    AddReplaceDelta(OrigOffset, NewStr.size() - OrigLength);
+}
+
+
+//===----------------------------------------------------------------------===//
+// Rewriter class
+//===----------------------------------------------------------------------===//
+
+/// getRangeSize - Return the size in bytes of the specified range if they
+/// are in the same file.  If not, this returns -1.
+int Rewriter::getRangeSize(const CharSourceRange &Range,
+                           RewriteOptions opts) const {
+  if (!isRewritable(Range.getBegin()) ||
+      !isRewritable(Range.getEnd())) return -1;
+
+  FileID StartFileID, EndFileID;
+  unsigned StartOff, EndOff;
+
+  StartOff = getLocationOffsetAndFileID(Range.getBegin(), StartFileID);
+  EndOff   = getLocationOffsetAndFileID(Range.getEnd(), EndFileID);
+
+  if (StartFileID != EndFileID)
+    return -1;
+
+  // If edits have been made to this buffer, the delta between the range may
+  // have changed.
+  std::map<FileID, RewriteBuffer>::const_iterator I =
+    RewriteBuffers.find(StartFileID);
+  if (I != RewriteBuffers.end()) {
+    const RewriteBuffer &RB = I->second;
+    EndOff = RB.getMappedOffset(EndOff, opts.IncludeInsertsAtEndOfRange);
+    StartOff = RB.getMappedOffset(StartOff, !opts.IncludeInsertsAtBeginOfRange);
+  }
+
+
+  // Adjust the end offset to the end of the last token, instead of being the
+  // start of the last token if this is a token range.
+  if (Range.isTokenRange())
+    EndOff += Lexer::MeasureTokenLength(Range.getEnd(), *SourceMgr, *LangOpts);
+
+  return EndOff-StartOff;
+}
+
+int Rewriter::getRangeSize(SourceRange Range, RewriteOptions opts) const {
+  return getRangeSize(CharSourceRange::getTokenRange(Range), opts);
+}
+
+
+/// getRewrittenText - Return the rewritten form of the text in the specified
+/// range.  If the start or end of the range was unrewritable or if they are
+/// in different buffers, this returns an empty string.
+///
+/// Note that this method is not particularly efficient.
+///
+std::string Rewriter::getRewrittenText(SourceRange Range) const {
+  if (!isRewritable(Range.getBegin()) ||
+      !isRewritable(Range.getEnd()))
+    return "";
+
+  FileID StartFileID, EndFileID;
+  unsigned StartOff, EndOff;
+  StartOff = getLocationOffsetAndFileID(Range.getBegin(), StartFileID);
+  EndOff   = getLocationOffsetAndFileID(Range.getEnd(), EndFileID);
+
+  if (StartFileID != EndFileID)
+    return ""; // Start and end in different buffers.
+
+  // If edits have been made to this buffer, the delta between the range may
+  // have changed.
+  std::map<FileID, RewriteBuffer>::const_iterator I =
+    RewriteBuffers.find(StartFileID);
+  if (I == RewriteBuffers.end()) {
+    // If the buffer hasn't been rewritten, just return the text from the input.
+    const char *Ptr = SourceMgr->getCharacterData(Range.getBegin());
+
+    // Adjust the end offset to the end of the last token, instead of being the
+    // start of the last token.
+    EndOff += Lexer::MeasureTokenLength(Range.getEnd(), *SourceMgr, *LangOpts);
+    return std::string(Ptr, Ptr+EndOff-StartOff);
+  }
+
+  const RewriteBuffer &RB = I->second;
+  EndOff = RB.getMappedOffset(EndOff, true);
+  StartOff = RB.getMappedOffset(StartOff);
+
+  // Adjust the end offset to the end of the last token, instead of being the
+  // start of the last token.
+  EndOff += Lexer::MeasureTokenLength(Range.getEnd(), *SourceMgr, *LangOpts);
+
+  // Advance the iterators to the right spot, yay for linear time algorithms.
+  RewriteBuffer::iterator Start = RB.begin();
+  std::advance(Start, StartOff);
+  RewriteBuffer::iterator End = Start;
+  std::advance(End, EndOff-StartOff);
+
+  return std::string(Start, End);
+}
+
+unsigned Rewriter::getLocationOffsetAndFileID(SourceLocation Loc,
+                                              FileID &FID) const {
+  assert(Loc.isValid() && "Invalid location");
+  std::pair<FileID,unsigned> V = SourceMgr->getDecomposedLoc(Loc);
+  FID = V.first;
+  return V.second;
+}
+
+
+/// getEditBuffer - Get or create a RewriteBuffer for the specified FileID.
+///
+RewriteBuffer &Rewriter::getEditBuffer(FileID FID) {
+  std::map<FileID, RewriteBuffer>::iterator I =
+    RewriteBuffers.lower_bound(FID);
+  if (I != RewriteBuffers.end() && I->first == FID)
+    return I->second;
+  I = RewriteBuffers.insert(I, std::make_pair(FID, RewriteBuffer()));
+
+  StringRef MB = SourceMgr->getBufferData(FID);
+  I->second.Initialize(MB.begin(), MB.end());
+
+  return I->second;
+}
+
+/// InsertText - Insert the specified string at the specified location in the
+/// original buffer.
+bool Rewriter::InsertText(SourceLocation Loc, StringRef Str,
+                          bool InsertAfter, bool indentNewLines) {
+  if (!isRewritable(Loc)) return true;
+  FileID FID;
+  unsigned StartOffs = getLocationOffsetAndFileID(Loc, FID);
+
+  SmallString<128> indentedStr;
+  if (indentNewLines && Str.find('\n') != StringRef::npos) {
+    StringRef MB = SourceMgr->getBufferData(FID);
+
+    unsigned lineNo = SourceMgr->getLineNumber(FID, StartOffs) - 1;
+    const SrcMgr::ContentCache *
+        Content = SourceMgr->getSLocEntry(FID).getFile().getContentCache();
+    unsigned lineOffs = Content->SourceLineCache[lineNo];
+
+    // Find the whitespace at the start of the line.
+    StringRef indentSpace;
+    {
+      unsigned i = lineOffs;
+      while (isWhitespace(MB[i]))
+        ++i;
+      indentSpace = MB.substr(lineOffs, i-lineOffs);
+    }
+
+    SmallVector<StringRef, 4> lines;
+    Str.split(lines, "\n");
+
+    for (unsigned i = 0, e = lines.size(); i != e; ++i) {
+      indentedStr += lines[i];
+      if (i < e-1) {
+        indentedStr += '\n';
+        indentedStr += indentSpace;
+      }
+    }
+    Str = indentedStr.str();
+  }
+
+  getEditBuffer(FID).InsertText(StartOffs, Str, InsertAfter);
+  return false;
+}
+
+bool Rewriter::InsertTextAfterToken(SourceLocation Loc, StringRef Str) {
+  if (!isRewritable(Loc)) return true;
+  FileID FID;
+  unsigned StartOffs = getLocationOffsetAndFileID(Loc, FID);
+  RewriteOptions rangeOpts;
+  rangeOpts.IncludeInsertsAtBeginOfRange = false;
+  StartOffs += getRangeSize(SourceRange(Loc, Loc), rangeOpts);
+  getEditBuffer(FID).InsertText(StartOffs, Str, /*InsertAfter*/true);
+  return false;
+}
+
+/// RemoveText - Remove the specified text region.
+bool Rewriter::RemoveText(SourceLocation Start, unsigned Length,
+                          RewriteOptions opts) {
+  if (!isRewritable(Start)) return true;
+  FileID FID;
+  unsigned StartOffs = getLocationOffsetAndFileID(Start, FID);
+  getEditBuffer(FID).RemoveText(StartOffs, Length, opts.RemoveLineIfEmpty);
+  return false;
+}
+
+/// ReplaceText - This method replaces a range of characters in the input
+/// buffer with a new string.  This is effectively a combined "remove/insert"
+/// operation.
+bool Rewriter::ReplaceText(SourceLocation Start, unsigned OrigLength,
+                           StringRef NewStr) {
+  if (!isRewritable(Start)) return true;
+  FileID StartFileID;
+  unsigned StartOffs = getLocationOffsetAndFileID(Start, StartFileID);
+
+  getEditBuffer(StartFileID).ReplaceText(StartOffs, OrigLength, NewStr);
+  return false;
+}
+
+bool Rewriter::ReplaceText(SourceRange range, SourceRange replacementRange) {
+  if (!isRewritable(range.getBegin())) return true;
+  if (!isRewritable(range.getEnd())) return true;
+  if (replacementRange.isInvalid()) return true;
+  SourceLocation start = range.getBegin();
+  unsigned origLength = getRangeSize(range);
+  unsigned newLength = getRangeSize(replacementRange);
+  FileID FID;
+  unsigned newOffs = getLocationOffsetAndFileID(replacementRange.getBegin(),
+                                                FID);
+  StringRef MB = SourceMgr->getBufferData(FID);
+  return ReplaceText(start, origLength, MB.substr(newOffs, newLength));
+}
+
+/// ReplaceStmt - This replaces a Stmt/Expr with another, using the pretty
+/// printer to generate the replacement code.  This returns true if the input
+/// could not be rewritten, or false if successful.
+bool Rewriter::ReplaceStmt(Stmt *From, Stmt *To) {
+  assert(From != nullptr && To != nullptr && "Expected non-null Stmt's");
+
+  // Measaure the old text.
+  int Size = getRangeSize(From->getSourceRange());
+  if (Size == -1)
+    return true;
+
+  // Get the new text.
+  std::string SStr;
+  llvm::raw_string_ostream S(SStr);
+  To->printPretty(S, nullptr, PrintingPolicy(*LangOpts));
+  const std::string &Str = S.str();
+
+  ReplaceText(From->getLocStart(), Size, Str);
+  return false;
+}
+
+std::string Rewriter::ConvertToString(Stmt *From) {
+  assert(From != nullptr && "Expected non-null Stmt");
+  std::string SStr;
+  llvm::raw_string_ostream S(SStr);
+  From->printPretty(S, nullptr, PrintingPolicy(*LangOpts));
+  return S.str();
+}
+
+bool Rewriter::IncreaseIndentation(CharSourceRange range,
+                                   SourceLocation parentIndent) {
+  if (range.isInvalid()) return true;
+  if (!isRewritable(range.getBegin())) return true;
+  if (!isRewritable(range.getEnd())) return true;
+  if (!isRewritable(parentIndent)) return true;
+
+  FileID StartFileID, EndFileID, parentFileID;
+  unsigned StartOff, EndOff, parentOff;
+
+  StartOff = getLocationOffsetAndFileID(range.getBegin(), StartFileID);
+  EndOff   = getLocationOffsetAndFileID(range.getEnd(), EndFileID);
+  parentOff = getLocationOffsetAndFileID(parentIndent, parentFileID);
+
+  if (StartFileID != EndFileID || StartFileID != parentFileID)
+    return true;
+  if (StartOff > EndOff)
+    return true;
+
+  FileID FID = StartFileID;
+  StringRef MB = SourceMgr->getBufferData(FID);
+
+  unsigned parentLineNo = SourceMgr->getLineNumber(FID, parentOff) - 1;
+  unsigned startLineNo = SourceMgr->getLineNumber(FID, StartOff) - 1;
+  unsigned endLineNo = SourceMgr->getLineNumber(FID, EndOff) - 1;
+  
+  const SrcMgr::ContentCache *
+      Content = SourceMgr->getSLocEntry(FID).getFile().getContentCache();
+  
+  // Find where the lines start.
+  unsigned parentLineOffs = Content->SourceLineCache[parentLineNo];
+  unsigned startLineOffs = Content->SourceLineCache[startLineNo];
+
+  // Find the whitespace at the start of each line.
+  StringRef parentSpace, startSpace;
+  {
+    unsigned i = parentLineOffs;
+    while (isWhitespace(MB[i]))
+      ++i;
+    parentSpace = MB.substr(parentLineOffs, i-parentLineOffs);
+
+    i = startLineOffs;
+    while (isWhitespace(MB[i]))
+      ++i;
+    startSpace = MB.substr(startLineOffs, i-startLineOffs);
+  }
+  if (parentSpace.size() >= startSpace.size())
+    return true;
+  if (!startSpace.startswith(parentSpace))
+    return true;
+
+  StringRef indent = startSpace.substr(parentSpace.size());
+
+  // Indent the lines between start/end offsets.
+  RewriteBuffer &RB = getEditBuffer(FID);
+  for (unsigned lineNo = startLineNo; lineNo <= endLineNo; ++lineNo) {
+    unsigned offs = Content->SourceLineCache[lineNo];
+    unsigned i = offs;
+    while (isWhitespace(MB[i]))
+      ++i;
+    StringRef origIndent = MB.substr(offs, i-offs);
+    if (origIndent.startswith(startSpace))
+      RB.InsertText(offs, indent, /*InsertAfter=*/false);
+  }
+
+  return false;
+}
+
+namespace {
+// A wrapper for a file stream that atomically overwrites the target.
+//
+// Creates a file output stream for a temporary file in the constructor,
+// which is later accessible via getStream() if ok() return true.
+// Flushes the stream and moves the temporary file to the target location
+// in the destructor.
+class AtomicallyMovedFile {
+public:
+  AtomicallyMovedFile(DiagnosticsEngine &Diagnostics, StringRef Filename,
+                      bool &AllWritten)
+    : Diagnostics(Diagnostics), Filename(Filename), AllWritten(AllWritten) {
+    TempFilename = Filename;
+    TempFilename += "-%%%%%%%%";
+    int FD;
+    if (llvm::sys::fs::createUniqueFile(TempFilename.str(), FD, TempFilename)) {
+      AllWritten = false;
+      Diagnostics.Report(clang::diag::err_unable_to_make_temp)
+        << TempFilename;
+    } else {
+      FileStream.reset(new llvm::raw_fd_ostream(FD, /*shouldClose=*/true));
+    }
+  }
+
+  ~AtomicallyMovedFile() {
+    if (!ok()) return;
+
+    FileStream->flush();
+#ifdef LLVM_ON_WIN32
+    // Win32 does not allow rename/removing opened files.
+    FileStream.reset();
+#endif
+    if (std::error_code ec =
+            llvm::sys::fs::rename(TempFilename.str(), Filename)) {
+      AllWritten = false;
+      Diagnostics.Report(clang::diag::err_unable_to_rename_temp)
+        << TempFilename << Filename << ec.message();
+      // If the remove fails, there's not a lot we can do - this is already an
+      // error.
+      llvm::sys::fs::remove(TempFilename.str());
+    }
+  }
+
+  bool ok() { return (bool)FileStream; }
+  raw_ostream &getStream() { return *FileStream; }
+
+private:
+  DiagnosticsEngine &Diagnostics;
+  StringRef Filename;
+  SmallString<128> TempFilename;
+  std::unique_ptr<llvm::raw_fd_ostream> FileStream;
+  bool &AllWritten;
+};
+} // end anonymous namespace
+
+bool Rewriter::overwriteChangedFiles() {
+  bool AllWritten = true;
+  for (buffer_iterator I = buffer_begin(), E = buffer_end(); I != E; ++I) {
+    const FileEntry *Entry =
+        getSourceMgr().getFileEntryForID(I->first);
+    AtomicallyMovedFile File(getSourceMgr().getDiagnostics(), Entry->getName(),
+                             AllWritten);
+    if (File.ok()) {
+      I->second.write(File.getStream());
+    }
+  }
+  return !AllWritten;
+}
diff --git a/lib/Rewrite/Core/TokenRewriter.cpp b/lib/Rewrite/TokenRewriter.cpp
similarity index 100%
rename from lib/Rewrite/Core/TokenRewriter.cpp
rename to lib/Rewrite/TokenRewriter.cpp
diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp
index 93e3ecf..213d6fb 100644
--- a/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/lib/Sema/AnalysisBasedWarnings.cpp
@@ -65,16 +65,198 @@
   public:
     UnreachableCodeHandler(Sema &s) : S(s) {}
 
-    void HandleUnreachable(SourceLocation L, SourceRange R1, SourceRange R2) {
-      S.Diag(L, diag::warn_unreachable) << R1 << R2;
+    void HandleUnreachable(reachable_code::UnreachableKind UK,
+                           SourceLocation L,
+                           SourceRange SilenceableCondVal,
+                           SourceRange R1,
+                           SourceRange R2) override {
+      unsigned diag = diag::warn_unreachable;
+      switch (UK) {
+        case reachable_code::UK_Break:
+          diag = diag::warn_unreachable_break;
+          break;
+        case reachable_code::UK_Return:
+          diag = diag::warn_unreachable_return;
+          break;
+        case reachable_code::UK_Loop_Increment:
+          diag = diag::warn_unreachable_loop_increment;
+          break;
+        case reachable_code::UK_Other:
+          break;
+      }
+
+      S.Diag(L, diag) << R1 << R2;
+      
+      SourceLocation Open = SilenceableCondVal.getBegin();
+      if (Open.isValid()) {
+        SourceLocation Close = SilenceableCondVal.getEnd();
+        Close = S.getLocForEndOfToken(Close);
+        if (Close.isValid()) {
+          S.Diag(Open, diag::note_unreachable_silence)
+            << FixItHint::CreateInsertion(Open, "/* DISABLES CODE */ (")
+            << FixItHint::CreateInsertion(Close, ")");
+        }
+      }
     }
   };
 }
 
 /// CheckUnreachable - Check for unreachable code.
 static void CheckUnreachable(Sema &S, AnalysisDeclContext &AC) {
+  // As a heuristic prune all diagnostics not in the main file.  Currently
+  // the majority of warnings in headers are false positives.  These
+  // are largely caused by configuration state, e.g. preprocessor
+  // defined code, etc.
+  //
+  // Note that this is also a performance optimization.  Analyzing
+  // headers many times can be expensive.
+  if (!S.getSourceManager().isInMainFile(AC.getDecl()->getLocStart()))
+    return;
+
   UnreachableCodeHandler UC(S);
-  reachable_code::FindUnreachableCode(AC, UC);
+  reachable_code::FindUnreachableCode(AC, S.getPreprocessor(), UC);
+}
+
+/// \brief Warn on logical operator errors in CFGBuilder
+class LogicalErrorHandler : public CFGCallback {
+  Sema &S;
+
+public:
+  LogicalErrorHandler(Sema &S) : CFGCallback(), S(S) {}
+
+  static bool HasMacroID(const Expr *E) {
+    if (E->getExprLoc().isMacroID())
+      return true;
+
+    // Recurse to children.
+    for (ConstStmtRange SubStmts = E->children(); SubStmts; ++SubStmts)
+      if (*SubStmts)
+        if (const Expr *SubExpr = dyn_cast<Expr>(*SubStmts))
+          if (HasMacroID(SubExpr))
+            return true;
+
+    return false;
+  }
+
+  void compareAlwaysTrue(const BinaryOperator *B, bool isAlwaysTrue) {
+    if (HasMacroID(B))
+      return;
+
+    SourceRange DiagRange = B->getSourceRange();
+    S.Diag(B->getExprLoc(), diag::warn_tautological_overlap_comparison)
+        << DiagRange << isAlwaysTrue;
+  }
+
+  void compareBitwiseEquality(const BinaryOperator *B, bool isAlwaysTrue) {
+    if (HasMacroID(B))
+      return;
+
+    SourceRange DiagRange = B->getSourceRange();
+    S.Diag(B->getExprLoc(), diag::warn_comparison_bitwise_always)
+        << DiagRange << isAlwaysTrue;
+  }
+};
+
+
+//===----------------------------------------------------------------------===//
+// Check for infinite self-recursion in functions
+//===----------------------------------------------------------------------===//
+
+// All blocks are in one of three states.  States are ordered so that blocks
+// can only move to higher states.
+enum RecursiveState {
+  FoundNoPath,
+  FoundPath,
+  FoundPathWithNoRecursiveCall
+};
+
+static void checkForFunctionCall(Sema &S, const FunctionDecl *FD,
+                                 CFGBlock &Block, unsigned ExitID,
+                                 llvm::SmallVectorImpl<RecursiveState> &States,
+                                 RecursiveState State) {
+  unsigned ID = Block.getBlockID();
+
+  // A block's state can only move to a higher state.
+  if (States[ID] >= State)
+    return;
+
+  States[ID] = State;
+
+  // Found a path to the exit node without a recursive call.
+  if (ID == ExitID && State == FoundPathWithNoRecursiveCall)
+    return;
+
+  if (State == FoundPathWithNoRecursiveCall) {
+    // If the current state is FoundPathWithNoRecursiveCall, the successors
+    // will be either FoundPathWithNoRecursiveCall or FoundPath.  To determine
+    // which, process all the Stmt's in this block to find any recursive calls.
+    for (const auto &B : Block) {
+      if (B.getKind() != CFGElement::Statement)
+        continue;
+
+      const CallExpr *CE = dyn_cast<CallExpr>(B.getAs<CFGStmt>()->getStmt());
+      if (CE && CE->getCalleeDecl() &&
+          CE->getCalleeDecl()->getCanonicalDecl() == FD) {
+
+        // Skip function calls which are qualified with a templated class.
+        if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(
+                CE->getCallee()->IgnoreParenImpCasts())) {
+          if (NestedNameSpecifier *NNS = DRE->getQualifier()) {
+            if (NNS->getKind() == NestedNameSpecifier::TypeSpec &&
+                isa<TemplateSpecializationType>(NNS->getAsType())) {
+               continue;
+            }
+          }
+        }
+
+        if (const CXXMemberCallExpr *MCE = dyn_cast<CXXMemberCallExpr>(CE)) {
+          if (isa<CXXThisExpr>(MCE->getImplicitObjectArgument()) ||
+              !MCE->getMethodDecl()->isVirtual()) {
+            State = FoundPath;
+            break;
+          }
+        } else {
+          State = FoundPath;
+          break;
+        }
+      }
+    }
+  }
+
+  for (CFGBlock::succ_iterator I = Block.succ_begin(), E = Block.succ_end();
+       I != E; ++I)
+    if (*I)
+      checkForFunctionCall(S, FD, **I, ExitID, States, State);
+}
+
+static void checkRecursiveFunction(Sema &S, const FunctionDecl *FD,
+                                   const Stmt *Body,
+                                   AnalysisDeclContext &AC) {
+  FD = FD->getCanonicalDecl();
+
+  // Only run on non-templated functions and non-templated members of
+  // templated classes.
+  if (FD->getTemplatedKind() != FunctionDecl::TK_NonTemplate &&
+      FD->getTemplatedKind() != FunctionDecl::TK_MemberSpecialization)
+    return;
+
+  CFG *cfg = AC.getCFG();
+  if (!cfg) return;
+
+  // If the exit block is unreachable, skip processing the function.
+  if (cfg->getExit().pred_empty())
+    return;
+
+  // Mark all nodes as FoundNoPath, then begin processing the entry block.
+  llvm::SmallVector<RecursiveState, 16> states(cfg->getNumBlockIDs(),
+                                               FoundNoPath);
+  checkForFunctionCall(S, FD, cfg->getEntry(), cfg->getExit().getBlockID(),
+                       states, FoundPathWithNoRecursiveCall);
+
+  // Check that the exit block is reachable.  This prevents triggering the
+  // warning on functions that do not terminate.
+  if (states[cfg->getExit().getBlockID()] == FoundPath)
+    S.Diag(Body->getLocStart(), diag::warn_infinite_recursive_function);
 }
 
 //===----------------------------------------------------------------------===//
@@ -100,7 +282,7 @@
 /// will return.
 static ControlFlowKind CheckFallThrough(AnalysisDeclContext &AC) {
   CFG *cfg = AC.getCFG();
-  if (cfg == 0) return UnknownFallThrough;
+  if (!cfg) return UnknownFallThrough;
 
   // The CFG leaves in dead things, and we don't want the dead code paths to
   // confuse us, so we mark all live things first.
@@ -113,14 +295,13 @@
     // When there are things remaining dead, and we didn't add EH edges
     // from CallExprs to the catch clauses, we have to go back and
     // mark them as live.
-    for (CFG::iterator I = cfg->begin(), E = cfg->end(); I != E; ++I) {
-      CFGBlock &b = **I;
-      if (!live[b.getBlockID()]) {
-        if (b.pred_begin() == b.pred_end()) {
-          if (b.getTerminator() && isa<CXXTryStmt>(b.getTerminator()))
+    for (const auto *B : *cfg) {
+      if (!live[B->getBlockID()]) {
+        if (B->pred_begin() == B->pred_end()) {
+          if (B->getTerminator() && isa<CXXTryStmt>(B->getTerminator()))
             // When not adding EH edges from calls, catch clauses
             // can otherwise seem dead.  Avoid noting them as dead.
-            count += reachable_code::ScanReachableFromBlock(&b, live);
+            count += reachable_code::ScanReachableFromBlock(B, live);
           continue;
         }
       }
@@ -272,8 +453,7 @@
       diag::err_noreturn_block_has_return_expr;
     D.diag_AlwaysFallThrough_ReturnsNonVoid =
       diag::err_falloff_nonvoid_block;
-    D.diag_NeverFallThroughOrReturn =
-      diag::warn_suggest_noreturn_block;
+    D.diag_NeverFallThroughOrReturn = 0;
     D.funMode = Block;
     return D;
   }
@@ -297,21 +477,17 @@
                         bool HasNoReturn) const {
     if (funMode == Function) {
       return (ReturnsVoid ||
-              D.getDiagnosticLevel(diag::warn_maybe_falloff_nonvoid_function,
-                                   FuncLoc) == DiagnosticsEngine::Ignored)
-        && (!HasNoReturn ||
-            D.getDiagnosticLevel(diag::warn_noreturn_function_has_return_expr,
-                                 FuncLoc) == DiagnosticsEngine::Ignored)
-        && (!ReturnsVoid ||
-            D.getDiagnosticLevel(diag::warn_suggest_noreturn_block, FuncLoc)
-              == DiagnosticsEngine::Ignored);
+              D.isIgnored(diag::warn_maybe_falloff_nonvoid_function,
+                          FuncLoc)) &&
+             (!HasNoReturn ||
+              D.isIgnored(diag::warn_noreturn_function_has_return_expr,
+                          FuncLoc)) &&
+             (!ReturnsVoid ||
+              D.isIgnored(diag::warn_suggest_noreturn_block, FuncLoc));
     }
 
     // For blocks / lambdas.
-    return ReturnsVoid && !HasNoReturn
-            && ((funMode == Lambda) ||
-                D.getDiagnosticLevel(diag::warn_suggest_noreturn_block, FuncLoc)
-                  == DiagnosticsEngine::Ignored);
+    return ReturnsVoid && !HasNoReturn;
   }
 };
 
@@ -330,18 +506,18 @@
   bool HasNoReturn = false;
 
   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
-    ReturnsVoid = FD->getResultType()->isVoidType();
+    ReturnsVoid = FD->getReturnType()->isVoidType();
     HasNoReturn = FD->isNoReturn();
   }
   else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
-    ReturnsVoid = MD->getResultType()->isVoidType();
+    ReturnsVoid = MD->getReturnType()->isVoidType();
     HasNoReturn = MD->hasAttr<NoReturnAttr>();
   }
   else if (isa<BlockDecl>(D)) {
     QualType BlockTy = blkExpr->getType();
     if (const FunctionType *FT =
           BlockTy->getPointeeType()->getAs<FunctionType>()) {
-      if (FT->getResultType()->isVoidType())
+      if (FT->getReturnType()->isVoidType())
         ReturnsVoid = true;
       if (FT->getNoReturnAttr())
         HasNoReturn = true;
@@ -435,8 +611,9 @@
   QualType VariableTy = VD->getType().getCanonicalType();
   if (VariableTy->isBlockPointerType() &&
       !VD->hasAttr<BlocksAttr>()) {
-    S.Diag(VD->getLocation(), diag::note_block_var_fixit_add_initialization) << VD->getDeclName()
-    << FixItHint::CreateInsertion(VD->getLocation(), "__block ");
+    S.Diag(VD->getLocation(), diag::note_block_var_fixit_add_initialization)
+        << VD->getDeclName()
+        << FixItHint::CreateInsertion(VD->getLocation(), "__block ");
     return true;
   }
 
@@ -448,7 +625,7 @@
   if (VD->getLocEnd().isMacroID())
     return false;
 
-  SourceLocation Loc = S.PP.getLocForEndOfToken(VD->getLocEnd());
+  SourceLocation Loc = S.getLocForEndOfToken(VD->getLocEnd());
 
   // Suggest possible initialization (if any).
   std::string Init = S.getFixItZeroInitializerForType(VariableTy, Loc);
@@ -744,8 +921,7 @@
       // constants, covered enums, etc.
       // These blocks can contain fall-through annotations, and we don't want to
       // issue a warn_fallthrough_attr_unreachable for them.
-      for (CFG::iterator I = Cfg->begin(), E = Cfg->end(); I != E; ++I) {
-        const CFGBlock *B = *I;
+      for (const auto *B : *Cfg) {
         const Stmt *L = B->getLabel();
         if (L && isa<SwitchCase>(L) && ReachableBlocks.insert(B))
           BlockQueue.push_back(B);
@@ -769,13 +945,11 @@
       int UnannotatedCnt = 0;
       AnnotatedCnt = 0;
 
-      std::deque<const CFGBlock*> BlockQueue;
-
-      std::copy(B.pred_begin(), B.pred_end(), std::back_inserter(BlockQueue));
-
+      std::deque<const CFGBlock*> BlockQueue(B.pred_begin(), B.pred_end());
       while (!BlockQueue.empty()) {
         const CFGBlock *P = BlockQueue.front();
         BlockQueue.pop_front();
+        if (!P) continue;
 
         const Stmt *Term = P->getTerminator();
         if (Term && isa<SwitchStmt>(Term))
@@ -852,6 +1026,9 @@
     // methods separately.
     bool TraverseDecl(Decl *D) { return true; }
 
+    // We analyze lambda bodies separately. Skip them here.
+    bool TraverseLambdaBody(LambdaExpr *LE) { return true; }
+
   private:
 
     static const AttributedStmt *asFallThroughAttr(const Stmt *S) {
@@ -859,7 +1036,7 @@
         if (hasSpecificAttr<FallThroughAttr>(AS->getAttrs()))
           return AS;
       }
-      return 0;
+      return nullptr;
     }
 
     static const Stmt *getLastStmt(const CFGBlock &B) {
@@ -878,7 +1055,7 @@
         if (!isa<SwitchCase>(SW->getSubStmt()))
           return SW->getSubStmt();
 
-      return 0;
+      return nullptr;
     }
 
     bool FoundSwitchStatements;
@@ -968,31 +1145,8 @@
     }
   }
 
-  const FallthroughMapper::AttrStmts &Fallthroughs = FM.getFallthroughStmts();
-  for (FallthroughMapper::AttrStmts::const_iterator I = Fallthroughs.begin(),
-                                                    E = Fallthroughs.end();
-                                                    I != E; ++I) {
-    S.Diag((*I)->getLocStart(), diag::warn_fallthrough_attr_invalid_placement);
-  }
-
-}
-
-namespace {
-typedef std::pair<const Stmt *,
-                  sema::FunctionScopeInfo::WeakObjectUseMap::const_iterator>
-        StmtUsesPair;
-
-class StmtUseSorter {
-  const SourceManager &SM;
-
-public:
-  explicit StmtUseSorter(const SourceManager &SM) : SM(SM) { }
-
-  bool operator()(const StmtUsesPair &LHS, const StmtUsesPair &RHS) {
-    return SM.isBeforeInTranslationUnit(LHS.first->getLocStart(),
-                                        RHS.first->getLocStart());
-  }
-};
+  for (const auto *F : FM.getFallthroughStmts())
+    S.Diag(F->getLocStart(), diag::warn_fallthrough_attr_invalid_placement);
 }
 
 static bool isInLoop(const ASTContext &Ctx, const ParentMap &PM,
@@ -1029,6 +1183,8 @@
   typedef sema::FunctionScopeInfo::WeakObjectProfileTy WeakObjectProfileTy;
   typedef sema::FunctionScopeInfo::WeakObjectUseMap WeakObjectUseMap;
   typedef sema::FunctionScopeInfo::WeakUseVector WeakUseVector;
+  typedef std::pair<const Stmt *, WeakObjectUseMap::const_iterator>
+  StmtUsesPair;
 
   ASTContext &Ctx = S.getASTContext();
 
@@ -1087,8 +1243,12 @@
     return;
 
   // Sort by first use so that we emit the warnings in a deterministic order.
+  SourceManager &SM = S.getSourceManager();
   std::sort(UsesByStmt.begin(), UsesByStmt.end(),
-            StmtUseSorter(S.getSourceManager()));
+            [&SM](const StmtUsesPair &LHS, const StmtUsesPair &RHS) {
+    return SM.isBeforeInTranslationUnit(LHS.first->getLocStart(),
+                                        RHS.first->getLocStart());
+  });
 
   // Classify the current code body for better warning text.
   // This enum should stay in sync with the cases in
@@ -1112,12 +1272,10 @@
     FunctionKind = Function;
 
   // Iterate through the sorted problems and emit warnings for each.
-  for (SmallVectorImpl<StmtUsesPair>::const_iterator I = UsesByStmt.begin(),
-                                                     E = UsesByStmt.end();
-       I != E; ++I) {
-    const Stmt *FirstRead = I->first;
-    const WeakObjectProfileTy &Key = I->second->first;
-    const WeakUseVector &Uses = I->second->second;
+  for (const auto &P : UsesByStmt) {
+    const Stmt *FirstRead = P.first;
+    const WeakObjectProfileTy &Key = P.second->first;
+    const WeakUseVector &Uses = P.second->second;
 
     // For complicated expressions like 'a.b.c' and 'x.b.c', WeakObjectProfileTy
     // may not contain enough information to determine that these are different
@@ -1158,30 +1316,17 @@
       << FirstRead->getSourceRange();
 
     // Print all the other accesses as notes.
-    for (WeakUseVector::const_iterator UI = Uses.begin(), UE = Uses.end();
-         UI != UE; ++UI) {
-      if (UI->getUseExpr() == FirstRead)
+    for (const auto &Use : Uses) {
+      if (Use.getUseExpr() == FirstRead)
         continue;
-      S.Diag(UI->getUseExpr()->getLocStart(),
+      S.Diag(Use.getUseExpr()->getLocStart(),
              diag::note_arc_weak_also_accessed_here)
-        << UI->getUseExpr()->getSourceRange();
+          << Use.getUseExpr()->getSourceRange();
     }
   }
 }
 
-
 namespace {
-struct SLocSort {
-  bool operator()(const UninitUse &a, const UninitUse &b) {
-    // Prefer a more confident report over a less confident one.
-    if (a.getKind() != b.getKind())
-      return a.getKind() > b.getKind();
-    SourceLocation aLoc = a.getUser()->getLocStart();
-    SourceLocation bLoc = b.getUser()->getLocStart();
-    return aLoc.getRawEncoding() < bLoc.getRawEncoding();
-  }
-};
-
 class UninitValsDiagReporter : public UninitVariablesHandler {
   Sema &S;
   typedef SmallVector<UninitUse, 2> UsesVec;
@@ -1193,7 +1338,7 @@
   UsesMap *uses;
   
 public:
-  UninitValsDiagReporter(Sema &S) : S(S), uses(0) {}
+  UninitValsDiagReporter(Sema &S) : S(S), uses(nullptr) {}
   ~UninitValsDiagReporter() { 
     flushDiagnostics();
   }
@@ -1208,12 +1353,13 @@
     
     return V;
   }
-  
-  void handleUseOfUninitVariable(const VarDecl *vd, const UninitUse &use) {
+
+  void handleUseOfUninitVariable(const VarDecl *vd,
+                                 const UninitUse &use) override {
     getUses(vd).getPointer()->push_back(use);
   }
   
-  void handleSelfInit(const VarDecl *vd) {
+  void handleSelfInit(const VarDecl *vd) override {
     getUses(vd).setInt(true);
   }
   
@@ -1221,9 +1367,9 @@
     if (!uses)
       return;
 
-    for (UsesMap::iterator i = uses->begin(), e = uses->end(); i != e; ++i) {
-      const VarDecl *vd = i->first;
-      const MappedType &V = i->second;
+    for (const auto &P : *uses) {
+      const VarDecl *vd = P.first;
+      const MappedType &V = P.second;
 
       UsesVec *vec = V.getPointer();
       bool hasSelfInit = V.getInt();
@@ -1240,12 +1386,17 @@
         // Sort the uses by their SourceLocations.  While not strictly
         // guaranteed to produce them in line/column order, this will provide
         // a stable ordering.
-        std::sort(vec->begin(), vec->end(), SLocSort());
-        
-        for (UsesVec::iterator vi = vec->begin(), ve = vec->end(); vi != ve;
-             ++vi) {
+        std::sort(vec->begin(), vec->end(),
+                  [](const UninitUse &a, const UninitUse &b) {
+          // Prefer a more confident report over a less confident one.
+          if (a.getKind() != b.getKind())
+            return a.getKind() > b.getKind();
+          return a.getUser()->getLocStart() < b.getUser()->getLocStart();
+        });
+
+        for (const auto &U : *vec) {
           // If we have self-init, downgrade all uses to 'may be uninitialized'.
-          UninitUse Use = hasSelfInit ? UninitUse(vi->getUser(), false) : *vi;
+          UninitUse Use = hasSelfInit ? UninitUse(U.getUser(), false) : U;
 
           if (DiagnoseUninitializedUse(S, vd, Use))
             // Skip further diagnostics for this variable. We try to warn only
@@ -1262,15 +1413,12 @@
 
 private:
   static bool hasAlwaysUninitializedUse(const UsesVec* vec) {
-  for (UsesVec::const_iterator i = vec->begin(), e = vec->end(); i != e; ++i) {
-    if (i->getKind() == UninitUse::Always ||
-        i->getKind() == UninitUse::AfterCall ||
-        i->getKind() == UninitUse::AfterDecl) {
-      return true;
-    }
+    return std::any_of(vec->begin(), vec->end(), [](const UninitUse &U) {
+      return U.getKind() == UninitUse::Always ||
+             U.getKind() == UninitUse::AfterCall ||
+             U.getKind() == UninitUse::AfterDecl;
+    });
   }
-  return false;
-}
 };
 }
 
@@ -1304,12 +1452,13 @@
   SourceLocation FunLocation, FunEndLocation;
 
   // Helper functions
-  void warnLockMismatch(unsigned DiagID, Name LockName, SourceLocation Loc) {
+  void warnLockMismatch(unsigned DiagID, StringRef Kind, Name LockName,
+                        SourceLocation Loc) {
     // Gracefully handle rare cases when the analysis can't get a more
     // precise source location.
     if (!Loc.isValid())
       Loc = FunLocation;
-    PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << LockName);
+    PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << Kind << LockName);
     Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
   }
 
@@ -1323,31 +1472,40 @@
   /// and outputs them.
   void emitDiagnostics() {
     Warnings.sort(SortDiagBySourceLocation(S.getSourceManager()));
-    for (DiagList::iterator I = Warnings.begin(), E = Warnings.end();
-         I != E; ++I) {
-      S.Diag(I->first.first, I->first.second);
-      const OptionalNotes &Notes = I->second;
-      for (unsigned NoteI = 0, NoteN = Notes.size(); NoteI != NoteN; ++NoteI)
-        S.Diag(Notes[NoteI].first, Notes[NoteI].second);
+    for (const auto &Diag : Warnings) {
+      S.Diag(Diag.first.first, Diag.first.second);
+      for (const auto &Note : Diag.second)
+        S.Diag(Note.first, Note.second);
     }
   }
 
-  void handleInvalidLockExp(SourceLocation Loc) {
-    PartialDiagnosticAt Warning(Loc,
-                                S.PDiag(diag::warn_cannot_resolve_lock) << Loc);
+  void handleInvalidLockExp(StringRef Kind, SourceLocation Loc) override {
+    PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_cannot_resolve_lock)
+                                         << Loc);
     Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
   }
-  void handleUnmatchedUnlock(Name LockName, SourceLocation Loc) {
-    warnLockMismatch(diag::warn_unlock_but_no_lock, LockName, Loc);
+  void handleUnmatchedUnlock(StringRef Kind, Name LockName,
+                             SourceLocation Loc) override {
+    warnLockMismatch(diag::warn_unlock_but_no_lock, Kind, LockName, Loc);
+  }
+  void handleIncorrectUnlockKind(StringRef Kind, Name LockName,
+                                 LockKind Expected, LockKind Received,
+                                 SourceLocation Loc) override {
+    if (Loc.isInvalid())
+      Loc = FunLocation;
+    PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_unlock_kind_mismatch)
+                                         << Kind << LockName << Received
+                                         << Expected);
+    Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
+  }
+  void handleDoubleLock(StringRef Kind, Name LockName, SourceLocation Loc) override {
+    warnLockMismatch(diag::warn_double_lock, Kind, LockName, Loc);
   }
 
-  void handleDoubleLock(Name LockName, SourceLocation Loc) {
-    warnLockMismatch(diag::warn_double_lock, LockName, Loc);
-  }
-
-  void handleMutexHeldEndOfScope(Name LockName, SourceLocation LocLocked,
+  void handleMutexHeldEndOfScope(StringRef Kind, Name LockName,
+                                 SourceLocation LocLocked,
                                  SourceLocation LocEndOfScope,
-                                 LockErrorKind LEK){
+                                 LockErrorKind LEK) override {
     unsigned DiagID = 0;
     switch (LEK) {
       case LEK_LockedSomePredecessors:
@@ -1366,29 +1524,33 @@
     if (LocEndOfScope.isInvalid())
       LocEndOfScope = FunEndLocation;
 
-    PartialDiagnosticAt Warning(LocEndOfScope, S.PDiag(DiagID) << LockName);
+    PartialDiagnosticAt Warning(LocEndOfScope, S.PDiag(DiagID) << Kind
+                                                               << LockName);
     if (LocLocked.isValid()) {
-      PartialDiagnosticAt Note(LocLocked, S.PDiag(diag::note_locked_here));
+      PartialDiagnosticAt Note(LocLocked, S.PDiag(diag::note_locked_here)
+                                              << Kind);
       Warnings.push_back(DelayedDiag(Warning, OptionalNotes(1, Note)));
       return;
     }
     Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
   }
 
-
-  void handleExclusiveAndShared(Name LockName, SourceLocation Loc1,
-                                SourceLocation Loc2) {
-    PartialDiagnosticAt Warning(
-      Loc1, S.PDiag(diag::warn_lock_exclusive_and_shared) << LockName);
-    PartialDiagnosticAt Note(
-      Loc2, S.PDiag(diag::note_lock_exclusive_and_shared) << LockName);
+  void handleExclusiveAndShared(StringRef Kind, Name LockName,
+                                SourceLocation Loc1,
+                                SourceLocation Loc2) override {
+    PartialDiagnosticAt Warning(Loc1,
+                                S.PDiag(diag::warn_lock_exclusive_and_shared)
+                                    << Kind << LockName);
+    PartialDiagnosticAt Note(Loc2, S.PDiag(diag::note_lock_exclusive_and_shared)
+                                       << Kind << LockName);
     Warnings.push_back(DelayedDiag(Warning, OptionalNotes(1, Note)));
   }
 
-  void handleNoMutexHeld(const NamedDecl *D, ProtectedOperationKind POK,
-                         AccessKind AK, SourceLocation Loc) {
-    assert((POK == POK_VarAccess || POK == POK_VarDereference)
-             && "Only works for variables");
+  void handleNoMutexHeld(StringRef Kind, const NamedDecl *D,
+                         ProtectedOperationKind POK, AccessKind AK,
+                         SourceLocation Loc) override {
+    assert((POK == POK_VarAccess || POK == POK_VarDereference) &&
+           "Only works for variables");
     unsigned DiagID = POK == POK_VarAccess?
                         diag::warn_variable_requires_any_lock:
                         diag::warn_var_deref_requires_any_lock;
@@ -1397,9 +1559,10 @@
     Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
   }
 
-  void handleMutexNotHeld(const NamedDecl *D, ProtectedOperationKind POK,
-                          Name LockName, LockKind LK, SourceLocation Loc,
-                          Name *PossibleMatch) {
+  void handleMutexNotHeld(StringRef Kind, const NamedDecl *D,
+                          ProtectedOperationKind POK, Name LockName,
+                          LockKind LK, SourceLocation Loc,
+                          Name *PossibleMatch) override {
     unsigned DiagID = 0;
     if (PossibleMatch) {
       switch (POK) {
@@ -1413,10 +1576,11 @@
           DiagID = diag::warn_fun_requires_lock_precise;
           break;
       }
-      PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID)
-        << D->getNameAsString() << LockName << LK);
+      PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << Kind
+                                                       << D->getNameAsString()
+                                                       << LockName << LK);
       PartialDiagnosticAt Note(Loc, S.PDiag(diag::note_found_mutex_near_match)
-                               << *PossibleMatch);
+                                        << *PossibleMatch);
       Warnings.push_back(DelayedDiag(Warning, OptionalNotes(1, Note)));
     } else {
       switch (POK) {
@@ -1430,15 +1594,17 @@
           DiagID = diag::warn_fun_requires_lock;
           break;
       }
-      PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID)
-        << D->getNameAsString() << LockName << LK);
+      PartialDiagnosticAt Warning(Loc, S.PDiag(DiagID) << Kind
+                                                       << D->getNameAsString()
+                                                       << LockName << LK);
       Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
     }
   }
 
-  void handleFunExcludesLock(Name FunName, Name LockName, SourceLocation Loc) {
-    PartialDiagnosticAt Warning(Loc,
-      S.PDiag(diag::warn_fun_excludes_mutex) << FunName << LockName);
+  void handleFunExcludesLock(StringRef Kind, Name FunName, Name LockName,
+                             SourceLocation Loc) override {
+    PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_fun_excludes_mutex)
+                                         << Kind << FunName << LockName);
     Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
   }
 };
@@ -1461,23 +1627,18 @@
 public:
   
   ConsumedWarningsHandler(Sema &S) : S(S) {}
-  
-  void emitDiagnostics() {
+
+  void emitDiagnostics() override {
     Warnings.sort(SortDiagBySourceLocation(S.getSourceManager()));
-    
-    for (DiagList::iterator I = Warnings.begin(), E = Warnings.end();
-         I != E; ++I) {
-      
-      const OptionalNotes &Notes = I->second;
-      S.Diag(I->first.first, I->first.second);
-      
-      for (unsigned NoteI = 0, NoteN = Notes.size(); NoteI != NoteN; ++NoteI) {
-        S.Diag(Notes[NoteI].first, Notes[NoteI].second);
-      }
+    for (const auto &Diag : Warnings) {
+      S.Diag(Diag.first.first, Diag.first.second);
+      for (const auto &Note : Diag.second)
+        S.Diag(Note.first, Note.second);
     }
   }
-  
-  void warnLoopStateMismatch(SourceLocation Loc, StringRef VariableName) {
+
+  void warnLoopStateMismatch(SourceLocation Loc,
+                             StringRef VariableName) override {
     PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_loop_state_mismatch) <<
       VariableName);
     
@@ -1487,7 +1648,7 @@
   void warnParamReturnTypestateMismatch(SourceLocation Loc,
                                         StringRef VariableName,
                                         StringRef ExpectedState,
-                                        StringRef ObservedState) {
+                                        StringRef ObservedState) override {
     
     PartialDiagnosticAt Warning(Loc, S.PDiag(
       diag::warn_param_return_typestate_mismatch) << VariableName <<
@@ -1497,7 +1658,7 @@
   }
   
   void warnParamTypestateMismatch(SourceLocation Loc, StringRef ExpectedState,
-                                  StringRef ObservedState) {
+                                  StringRef ObservedState) override {
     
     PartialDiagnosticAt Warning(Loc, S.PDiag(
       diag::warn_param_typestate_mismatch) << ExpectedState << ObservedState);
@@ -1506,7 +1667,7 @@
   }
   
   void warnReturnTypestateForUnconsumableType(SourceLocation Loc,
-                                              StringRef TypeName) {
+                                              StringRef TypeName) override {
     PartialDiagnosticAt Warning(Loc, S.PDiag(
       diag::warn_return_typestate_for_unconsumable_type) << TypeName);
     
@@ -1514,7 +1675,7 @@
   }
   
   void warnReturnTypestateMismatch(SourceLocation Loc, StringRef ExpectedState,
-                                   StringRef ObservedState) {
+                                   StringRef ObservedState) override {
                                     
     PartialDiagnosticAt Warning(Loc, S.PDiag(
       diag::warn_return_typestate_mismatch) << ExpectedState << ObservedState);
@@ -1523,7 +1684,7 @@
   }
   
   void warnUseOfTempInInvalidState(StringRef MethodName, StringRef State,
-                                   SourceLocation Loc) {
+                                   SourceLocation Loc) override {
                                                     
     PartialDiagnosticAt Warning(Loc, S.PDiag(
       diag::warn_use_of_temp_in_invalid_state) << MethodName << State);
@@ -1532,7 +1693,7 @@
   }
   
   void warnUseInInvalidState(StringRef MethodName, StringRef VariableName,
-                                  StringRef State, SourceLocation Loc) {
+                             StringRef State, SourceLocation Loc) override {
   
     PartialDiagnosticAt Warning(Loc, S.PDiag(diag::warn_use_in_invalid_state) <<
                                 MethodName << VariableName << State);
@@ -1554,6 +1715,10 @@
   enableConsumedAnalysis = 0;
 }
 
+static unsigned isEnabled(DiagnosticsEngine &D, unsigned diag) {
+  return (unsigned)!D.isIgnored(diag, SourceLocation());
+}
+
 clang::sema::AnalysisBasedWarnings::AnalysisBasedWarnings(Sema &s)
   : S(s),
     NumFunctionsAnalyzed(0),
@@ -1565,26 +1730,26 @@
     MaxUninitAnalysisVariablesPerFunction(0),
     NumUninitAnalysisBlockVisits(0),
     MaxUninitAnalysisBlockVisitsPerFunction(0) {
+
+  using namespace diag;
   DiagnosticsEngine &D = S.getDiagnostics();
-  DefaultPolicy.enableCheckUnreachable = (unsigned)
-    (D.getDiagnosticLevel(diag::warn_unreachable, SourceLocation()) !=
-        DiagnosticsEngine::Ignored);
-  DefaultPolicy.enableThreadSafetyAnalysis = (unsigned)
-    (D.getDiagnosticLevel(diag::warn_double_lock, SourceLocation()) !=
-     DiagnosticsEngine::Ignored);
-  DefaultPolicy.enableConsumedAnalysis = (unsigned)
-    (D.getDiagnosticLevel(diag::warn_use_in_invalid_state, SourceLocation()) !=
-     DiagnosticsEngine::Ignored);
+
+  DefaultPolicy.enableCheckUnreachable =
+    isEnabled(D, warn_unreachable) ||
+    isEnabled(D, warn_unreachable_break) ||
+    isEnabled(D, warn_unreachable_return) ||
+    isEnabled(D, warn_unreachable_loop_increment);
+
+  DefaultPolicy.enableThreadSafetyAnalysis =
+    isEnabled(D, warn_double_lock);
+
+  DefaultPolicy.enableConsumedAnalysis =
+    isEnabled(D, warn_use_in_invalid_state);
 }
 
-static void flushDiagnostics(Sema &S, sema::FunctionScopeInfo *fscope) {
-  for (SmallVectorImpl<sema::PossiblyUnreachableDiag>::iterator
-       i = fscope->PossiblyUnreachableDiags.begin(),
-       e = fscope->PossiblyUnreachableDiags.end();
-       i != e; ++i) {
-    const sema::PossiblyUnreachableDiag &D = *i;
+static void flushDiagnostics(Sema &S, const sema::FunctionScopeInfo *fscope) {
+  for (const auto &D : fscope->PossiblyUnreachableDiags)
     S.Diag(D.Loc, D.PD);
-  }
 }
 
 void clang::sema::
@@ -1620,7 +1785,7 @@
   assert(Body);
 
   // Construct the analysis context with the specified CFG build options.
-  AnalysisDeclContext AC(/* AnalysisDeclContextManager */ 0, D);
+  AnalysisDeclContext AC(/* AnalysisDeclContextManager */ nullptr, D);
 
   // Don't generate EH edges for CallExprs as we'd like to avoid the n^2
   // explosion for destructors that can result and the compile time hit.
@@ -1629,6 +1794,7 @@
   AC.getCFGBuildOptions().AddInitializers = true;
   AC.getCFGBuildOptions().AddImplicitDtors = true;
   AC.getCFGBuildOptions().AddTemporaryDtors = true;
+  AC.getCFGBuildOptions().AddCXXNewAllocator = false;
 
   // Force that certain expressions appear as CFGElements in the CFG.  This
   // is used to speed up various analyses.
@@ -1653,31 +1819,30 @@
       .setAlwaysAdd(Stmt::AttributedStmtClass);
   }
 
+  // Install the logical handler for -Wtautological-overlap-compare
+  std::unique_ptr<LogicalErrorHandler> LEH;
+  if (!Diags.isIgnored(diag::warn_tautological_overlap_comparison,
+                       D->getLocStart())) {
+    LEH.reset(new LogicalErrorHandler(S));
+    AC.getCFGBuildOptions().Observer = LEH.get();
+  }
 
   // Emit delayed diagnostics.
   if (!fscope->PossiblyUnreachableDiags.empty()) {
     bool analyzed = false;
 
     // Register the expressions with the CFGBuilder.
-    for (SmallVectorImpl<sema::PossiblyUnreachableDiag>::iterator
-         i = fscope->PossiblyUnreachableDiags.begin(),
-         e = fscope->PossiblyUnreachableDiags.end();
-         i != e; ++i) {
-      if (const Stmt *stmt = i->stmt)
-        AC.registerForcedBlockExpression(stmt);
+    for (const auto &D : fscope->PossiblyUnreachableDiags) {
+      if (D.stmt)
+        AC.registerForcedBlockExpression(D.stmt);
     }
 
     if (AC.getCFG()) {
       analyzed = true;
-      for (SmallVectorImpl<sema::PossiblyUnreachableDiag>::iterator
-            i = fscope->PossiblyUnreachableDiags.begin(),
-            e = fscope->PossiblyUnreachableDiags.end();
-            i != e; ++i)
-      {
-        const sema::PossiblyUnreachableDiag &D = *i;
+      for (const auto &D : fscope->PossiblyUnreachableDiags) {
         bool processed = false;
-        if (const Stmt *stmt = i->stmt) {
-          const CFGBlock *block = AC.getBlockForRegisteredExpression(stmt);
+        if (D.stmt) {
+          const CFGBlock *block = AC.getBlockForRegisteredExpression(D.stmt);
           CFGReverseBlockReachabilityAnalysis *cra =
               AC.getCFGReachablityAnalysis();
           // FIXME: We should be able to assert that block is non-null, but
@@ -1732,8 +1897,7 @@
     SourceLocation FL = AC.getDecl()->getLocation();
     SourceLocation FEL = AC.getDecl()->getLocEnd();
     thread_safety::ThreadSafetyReporter Reporter(S, FL, FEL);
-    if (Diags.getDiagnosticLevel(diag::warn_thread_safety_beta,D->getLocStart())
-        != DiagnosticsEngine::Ignored)
+    if (!Diags.isIgnored(diag::warn_thread_safety_beta, D->getLocStart()))
       Reporter.setIssueBetaWarnings(true);
 
     thread_safety::runThreadSafetyAnalysis(AC, Reporter);
@@ -1747,12 +1911,9 @@
     Analyzer.run(AC);
   }
 
-  if (Diags.getDiagnosticLevel(diag::warn_uninit_var, D->getLocStart())
-      != DiagnosticsEngine::Ignored ||
-      Diags.getDiagnosticLevel(diag::warn_sometimes_uninit_var,D->getLocStart())
-      != DiagnosticsEngine::Ignored ||
-      Diags.getDiagnosticLevel(diag::warn_maybe_uninit_var, D->getLocStart())
-      != DiagnosticsEngine::Ignored) {
+  if (!Diags.isIgnored(diag::warn_uninit_var, D->getLocStart()) ||
+      !Diags.isIgnored(diag::warn_sometimes_uninit_var, D->getLocStart()) ||
+      !Diags.isIgnored(diag::warn_maybe_uninit_var, D->getLocStart())) {
     if (CFG *cfg = AC.getCFG()) {
       UninitValsDiagReporter reporter(S);
       UninitVariablesAnalysisStats stats;
@@ -1775,20 +1936,33 @@
   }
 
   bool FallThroughDiagFull =
-      Diags.getDiagnosticLevel(diag::warn_unannotated_fallthrough,
-                               D->getLocStart()) != DiagnosticsEngine::Ignored;
-  bool FallThroughDiagPerFunction =
-      Diags.getDiagnosticLevel(diag::warn_unannotated_fallthrough_per_function,
-                               D->getLocStart()) != DiagnosticsEngine::Ignored;
+      !Diags.isIgnored(diag::warn_unannotated_fallthrough, D->getLocStart());
+  bool FallThroughDiagPerFunction = !Diags.isIgnored(
+      diag::warn_unannotated_fallthrough_per_function, D->getLocStart());
   if (FallThroughDiagFull || FallThroughDiagPerFunction) {
     DiagnoseSwitchLabelsFallthrough(S, AC, !FallThroughDiagFull);
   }
 
   if (S.getLangOpts().ObjCARCWeak &&
-      Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak,
-                               D->getLocStart()) != DiagnosticsEngine::Ignored)
+      !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, D->getLocStart()))
     diagnoseRepeatedUseOfWeak(S, fscope, D, AC.getParentMap());
 
+
+  // Check for infinite self-recursion in functions
+  if (!Diags.isIgnored(diag::warn_infinite_recursive_function,
+                       D->getLocStart())) {
+    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+      checkRecursiveFunction(S, FD, Body, AC);
+    }
+  }
+
+  // If none of the previous checks caused a CFG build, trigger one here
+  // for -Wtautological-overlap-compare
+  if (!Diags.isIgnored(diag::warn_tautological_overlap_comparison,
+                               D->getLocStart())) {
+    AC.getCFG();
+  }
+
   // Collect statistics about the CFG if it was built.
   if (S.CollectStats && AC.isCFGBuilt()) {
     ++NumFunctionsAnalyzed;
diff --git a/lib/Sema/AttributeList.cpp b/lib/Sema/AttributeList.cpp
index c980772..476a22b 100644
--- a/lib/Sema/AttributeList.cpp
+++ b/lib/Sema/AttributeList.cpp
@@ -13,8 +13,11 @@
 
 #include "clang/Sema/AttributeList.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
 #include "clang/Basic/IdentifierTable.h"
+#include "clang/Sema/SemaInternal.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringSwitch.h"
 using namespace clang;
@@ -103,14 +106,6 @@
   } while (pool);
 }
 
-AttributeList *
-AttributePool::createIntegerAttribute(ASTContext &C, IdentifierInfo *Name,
-                                      SourceLocation TokLoc, int Arg) {
-  ArgsUnion IArg = IntegerLiteral::Create(C, llvm::APInt(32, (uint64_t) Arg),
-                                      C.IntTy, TokLoc);
-  return create(Name, TokLoc, 0, TokLoc, &IArg, 1, AttributeList::AS_GNU);
-}
-
 #include "clang/Sema/AttrParsedAttrKinds.inc"
 
 AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name,
@@ -118,21 +113,25 @@
                                            Syntax SyntaxUsed) {
   StringRef AttrName = Name->getName();
 
-  // Normalize the attribute name, __foo__ becomes foo.
-  if (AttrName.startswith("__") && AttrName.endswith("__") &&
-      AttrName.size() >= 4)
-    AttrName = AttrName.substr(2, AttrName.size() - 4);
-
-  SmallString<64> Buf;
+  SmallString<64> FullName;
   if (ScopeName)
-    Buf += ScopeName->getName();
+    FullName += ScopeName->getName();
+
+  // Normalize the attribute name, __foo__ becomes foo. This is only allowable
+  // for GNU attributes.
+  bool IsGNU = SyntaxUsed == AS_GNU || (SyntaxUsed == AS_CXX11 &&
+                                        FullName == "gnu");
+  if (IsGNU && AttrName.size() >= 4 && AttrName.startswith("__") &&
+      AttrName.endswith("__"))
+    AttrName = AttrName.slice(2, AttrName.size() - 2);
+
   // Ensure that in the case of C++11 attributes, we look for '::foo' if it is
   // unscoped.
   if (ScopeName || SyntaxUsed == AS_CXX11)
-    Buf += "::";
-  Buf += AttrName;
+    FullName += "::";
+  FullName += AttrName;
 
-  return ::getAttrKind(Buf);
+  return ::getAttrKind(FullName, SyntaxUsed);
 }
 
 unsigned AttributeList::getAttributeSpellingListIndex() const {
@@ -149,6 +148,15 @@
   unsigned NumArgs : 4;
   unsigned OptArgs : 4;
   unsigned HasCustomParsing : 1;
+  unsigned IsTargetSpecific : 1;
+  unsigned IsType : 1;
+  unsigned IsKnownToGCC : 1;
+
+  bool (*DiagAppertainsToDecl)(Sema &S, const AttributeList &Attr,
+                               const Decl *);
+  bool (*DiagLangOpts)(Sema &S, const AttributeList &Attr);
+  bool (*ExistsInTarget)(const llvm::Triple &T);
+  unsigned (*SpellingIndexToSemanticSpelling)(const AttributeList &Attr);
 };
 
 namespace {
@@ -170,3 +178,31 @@
 bool AttributeList::hasCustomParsing() const {
   return getInfo(*this).HasCustomParsing;
 }
+
+bool AttributeList::diagnoseAppertainsTo(Sema &S, const Decl *D) const {
+  return getInfo(*this).DiagAppertainsToDecl(S, *this, D);
+}
+
+bool AttributeList::diagnoseLangOpts(Sema &S) const {
+  return getInfo(*this).DiagLangOpts(S, *this);
+}
+
+bool AttributeList::isTargetSpecificAttr() const {
+  return getInfo(*this).IsTargetSpecific;
+}
+
+bool AttributeList::isTypeAttr() const {
+  return getInfo(*this).IsType;
+}
+
+bool AttributeList::existsInTarget(const llvm::Triple &T) const {
+  return getInfo(*this).ExistsInTarget(T);
+}
+
+bool AttributeList::isKnownToGCC() const {
+  return getInfo(*this).IsKnownToGCC;
+}
+
+unsigned AttributeList::getSemanticSpelling() const {
+  return getInfo(*this).SpellingIndexToSemanticSpelling(*this);
+}
diff --git a/lib/Sema/CMakeLists.txt b/lib/Sema/CMakeLists.txt
index 5e09140..7847d2c 100644
--- a/lib/Sema/CMakeLists.txt
+++ b/lib/Sema/CMakeLists.txt
@@ -1,8 +1,5 @@
 set(LLVM_LINK_COMPONENTS
-  ${LLVM_TARGETS_TO_BUILD}
-  asmparser
-  support
-  mc
+  Support
   )
 
 add_clang_library(clangSema
@@ -50,30 +47,9 @@
   SemaTemplateInstantiateDecl.cpp
   SemaTemplateVariadic.cpp
   SemaType.cpp
-  TargetAttributesSema.cpp
   TypeLocBuilder.cpp
-  )
 
-add_dependencies(clangSema
-  ClangARMNeon
-  ClangAttrClasses
-  ClangAttrList
-  ClangAttrParsedAttrList
-  ClangAttrParsedAttrKinds
-  ClangAttrParsedAttrImpl
-  ClangAttrSpellingListIndex
-  ClangAttrTemplateInstantiate
-  ClangCommentNodes
-  ClangDeclNodes
-  ClangDiagnosticAST
-  ClangDiagnosticComment
-  ClangDiagnosticCommon
-  ClangDiagnosticParse
-  ClangDiagnosticSema
-  ClangStmtNodes
-  )
-
-target_link_libraries(clangSema
+  LINK_LIBS
   clangAST
   clangAnalysis
   clangBasic
diff --git a/lib/Sema/CodeCompleteConsumer.cpp b/lib/Sema/CodeCompleteConsumer.cpp
index 19be1cb..b2dc2d7 100644
--- a/lib/Sema/CodeCompleteConsumer.cpp
+++ b/lib/Sema/CodeCompleteConsumer.cpp
@@ -15,7 +15,6 @@
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
-#include "clang/Lex/Preprocessor.h"
 #include "clang/Sema/Scope.h"
 #include "clang/Sema/Sema.h"
 #include "llvm/ADT/STLExtras.h"
@@ -219,7 +218,7 @@
   if (AnnotationNr < NumAnnotations)
     return reinterpret_cast<const char * const*>(end())[AnnotationNr];
   else
-    return 0;
+    return nullptr;
 }
 
 
@@ -248,8 +247,8 @@
   for (iterator C = begin(), CEnd = end(); C != CEnd; ++C)
     if (C->Kind == CK_TypedText)
       return C->Text;
-  
-  return 0;
+
+  return nullptr;
 }
 
 const char *CodeCompletionAllocator::CopyString(StringRef String) {
@@ -279,7 +278,7 @@
 
   // If we already processed this DeclContext and assigned empty to it, the
   // data pointer will be non-null.
-  if (CachedParentName.data() != 0)
+  if (CachedParentName.data() != nullptr)
     return StringRef();
 
   // Find the interesting names.
@@ -406,7 +405,7 @@
   else if (getKind() == CK_FunctionTemplate)
     return FunctionTemplate->getTemplatedDecl();
   else
-    return 0;
+    return nullptr;
 }
 
 const FunctionType *
diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp
index 538c16e..d7372b7 100644
--- a/lib/Sema/DeclSpec.cpp
+++ b/lib/Sema/DeclSpec.cpp
@@ -149,8 +149,8 @@
 DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto,
                                              bool isAmbiguous,
                                              SourceLocation LParenLoc,
-                                             ParamInfo *ArgInfo,
-                                             unsigned NumArgs,
+                                             ParamInfo *Params,
+                                             unsigned NumParams,
                                              SourceLocation EllipsisLoc,
                                              SourceLocation RParenLoc,
                                              unsigned TypeQuals,
@@ -178,17 +178,17 @@
   I.Kind                        = Function;
   I.Loc                         = LocalRangeBegin;
   I.EndLoc                      = LocalRangeEnd;
-  I.Fun.AttrList                = 0;
+  I.Fun.AttrList                = nullptr;
   I.Fun.hasPrototype            = hasProto;
   I.Fun.isVariadic              = EllipsisLoc.isValid();
   I.Fun.isAmbiguous             = isAmbiguous;
   I.Fun.LParenLoc               = LParenLoc.getRawEncoding();
   I.Fun.EllipsisLoc             = EllipsisLoc.getRawEncoding();
   I.Fun.RParenLoc               = RParenLoc.getRawEncoding();
-  I.Fun.DeleteArgInfo           = false;
+  I.Fun.DeleteParams            = false;
   I.Fun.TypeQuals               = TypeQuals;
-  I.Fun.NumArgs                 = NumArgs;
-  I.Fun.ArgInfo                 = 0;
+  I.Fun.NumParams               = NumParams;
+  I.Fun.Params                  = nullptr;
   I.Fun.RefQualifierIsLValueRef = RefQualifierIsLvalueRef;
   I.Fun.RefQualifierLoc         = RefQualifierLoc.getRawEncoding();
   I.Fun.ConstQualifierLoc       = ConstQualifierLoc.getRawEncoding();
@@ -197,28 +197,28 @@
   I.Fun.ExceptionSpecType       = ESpecType;
   I.Fun.ExceptionSpecLoc        = ESpecLoc.getRawEncoding();
   I.Fun.NumExceptions           = 0;
-  I.Fun.Exceptions              = 0;
-  I.Fun.NoexceptExpr            = 0;
+  I.Fun.Exceptions              = nullptr;
+  I.Fun.NoexceptExpr            = nullptr;
   I.Fun.HasTrailingReturnType   = TrailingReturnType.isUsable() ||
                                   TrailingReturnType.isInvalid();
   I.Fun.TrailingReturnType      = TrailingReturnType.get();
 
-  // new[] an argument array if needed.
-  if (NumArgs) {
+  // new[] a parameter array if needed.
+  if (NumParams) {
     // If the 'InlineParams' in Declarator is unused and big enough, put our
     // parameter list there (in an effort to avoid new/delete traffic).  If it
     // is already used (consider a function returning a function pointer) or too
-    // small (function taking too many arguments), go to the heap.
+    // small (function with too many parameters), go to the heap.
     if (!TheDeclarator.InlineParamsUsed &&
-        NumArgs <= llvm::array_lengthof(TheDeclarator.InlineParams)) {
-      I.Fun.ArgInfo = TheDeclarator.InlineParams;
-      I.Fun.DeleteArgInfo = false;
+        NumParams <= llvm::array_lengthof(TheDeclarator.InlineParams)) {
+      I.Fun.Params = TheDeclarator.InlineParams;
+      I.Fun.DeleteParams = false;
       TheDeclarator.InlineParamsUsed = true;
     } else {
-      I.Fun.ArgInfo = new DeclaratorChunk::ParamInfo[NumArgs];
-      I.Fun.DeleteArgInfo = true;
+      I.Fun.Params = new DeclaratorChunk::ParamInfo[NumParams];
+      I.Fun.DeleteParams = true;
     }
-    memcpy(I.Fun.ArgInfo, ArgInfo, sizeof(ArgInfo[0])*NumArgs);
+    memcpy(I.Fun.Params, Params, sizeof(Params[0]) * NumParams);
   }
 
   // Check what exception specification information we should actually store.
@@ -285,14 +285,6 @@
     case TST_unspecified:
     case TST_void:
     case TST_wchar:
-    case TST_image1d_t:
-    case TST_image1d_array_t:
-    case TST_image1d_buffer_t:
-    case TST_image2d_t:
-    case TST_image2d_array_t:
-    case TST_image3d_t:
-    case TST_sampler_t:
-    case TST_event_t:
       return false;
 
     case TST_decltype_auto:
@@ -333,6 +325,12 @@
              getName().OperatorFunctionId.Operator);
 }
 
+bool DeclSpec::hasTagDefinition() const {
+  if (!TypeSpecOwned)
+    return false;
+  return cast<TagDecl>(getRepAsDecl())->isCompleteDefinition();
+}
+
 /// getParsedSpecifiers - Return a bitmask of which flavors of specifiers this
 /// declaration specifier includes.
 ///
@@ -420,12 +418,13 @@
   llvm_unreachable("Unknown typespec!");
 }
 
-const char *DeclSpec::getSpecifierName(DeclSpec::TST T) {
+const char *DeclSpec::getSpecifierName(DeclSpec::TST T,
+                                       const PrintingPolicy &Policy) {
   switch (T) {
   case DeclSpec::TST_unspecified: return "unspecified";
   case DeclSpec::TST_void:        return "void";
   case DeclSpec::TST_char:        return "char";
-  case DeclSpec::TST_wchar:       return "wchar_t";
+  case DeclSpec::TST_wchar:       return Policy.MSWChar ? "__wchar_t" : "wchar_t";
   case DeclSpec::TST_char16:      return "char16_t";
   case DeclSpec::TST_char32:      return "char32_t";
   case DeclSpec::TST_int:         return "int";
@@ -433,7 +432,7 @@
   case DeclSpec::TST_half:        return "half";
   case DeclSpec::TST_float:       return "float";
   case DeclSpec::TST_double:      return "double";
-  case DeclSpec::TST_bool:        return "_Bool";
+  case DeclSpec::TST_bool:        return Policy.Bool ? "bool" : "_Bool";
   case DeclSpec::TST_decimal32:   return "_Decimal32";
   case DeclSpec::TST_decimal64:   return "_Decimal64";
   case DeclSpec::TST_decimal128:  return "_Decimal128";
@@ -451,14 +450,6 @@
   case DeclSpec::TST_underlyingType: return "__underlying_type";
   case DeclSpec::TST_unknown_anytype: return "__unknown_anytype";
   case DeclSpec::TST_atomic: return "_Atomic";
-  case DeclSpec::TST_image1d_t:   return "image1d_t";
-  case DeclSpec::TST_image1d_array_t: return "image1d_array_t";
-  case DeclSpec::TST_image1d_buffer_t: return "image1d_buffer_t";
-  case DeclSpec::TST_image2d_t:   return "image2d_t";
-  case DeclSpec::TST_image2d_array_t: return "image2d_array_t";
-  case DeclSpec::TST_image3d_t:   return "image3d_t";
-  case DeclSpec::TST_sampler_t:   return "sampler_t";
-  case DeclSpec::TST_event_t:     return "event_t";
   case DeclSpec::TST_error:       return "(error)";
   }
   llvm_unreachable("Unknown typespec!");
@@ -477,7 +468,8 @@
 
 bool DeclSpec::SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc,
                                    const char *&PrevSpec,
-                                   unsigned &DiagID) {
+                                   unsigned &DiagID,
+                                   const PrintingPolicy &Policy) {
   // OpenCL v1.1 s6.8g: "The extern, static, auto and register storage-class
   // specifiers are not supported.
   // It seems sensible to prohibit private_extern too
@@ -512,10 +504,10 @@
     bool isInvalid = true;
     if (TypeSpecType == TST_unspecified && S.getLangOpts().CPlusPlus) {
       if (SC == SCS_auto)
-        return SetTypeSpecType(TST_auto, Loc, PrevSpec, DiagID);
+        return SetTypeSpecType(TST_auto, Loc, PrevSpec, DiagID, Policy);
       if (StorageClassSpec == SCS_auto) {
         isInvalid = SetTypeSpecType(TST_auto, StorageClassSpecLoc,
-                                    PrevSpec, DiagID);
+                                    PrevSpec, DiagID, Policy);
         assert(!isInvalid && "auto SCS -> TST recovery failed");
       }
     }
@@ -551,7 +543,8 @@
 /// specified).
 bool DeclSpec::SetTypeSpecWidth(TSW W, SourceLocation Loc,
                                 const char *&PrevSpec,
-                                unsigned &DiagID) {
+                                unsigned &DiagID,
+                                const PrintingPolicy &Policy) {
   // Overwrite TSWLoc only if TypeSpecWidth was unspecified, so that
   // for 'long long' we will keep the source location of the first 'long'.
   if (TypeSpecWidth == TSW_unspecified)
@@ -562,7 +555,7 @@
   TypeSpecWidth = W;
   if (TypeAltiVecVector && !TypeAltiVecBool &&
       ((TypeSpecWidth == TSW_long) || (TypeSpecWidth == TSW_longlong))) {
-    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
     DiagID = diag::warn_vector_long_decl_spec_combination;
     return true;
   }
@@ -592,19 +585,21 @@
 bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
                                const char *&PrevSpec,
                                unsigned &DiagID,
-                               ParsedType Rep) {
-  return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep);
+                               ParsedType Rep,
+                               const PrintingPolicy &Policy) {
+  return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep, Policy);
 }
 
 bool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc,
                                SourceLocation TagNameLoc,
                                const char *&PrevSpec,
                                unsigned &DiagID,
-                               ParsedType Rep) {
+                               ParsedType Rep,
+                               const PrintingPolicy &Policy) {
   assert(isTypeRep(T) && "T does not store a type");
   assert(Rep && "no type provided!");
   if (TypeSpecType != TST_unspecified) {
-    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
     DiagID = diag::err_invalid_decl_spec_combination;
     return true;
   }
@@ -619,11 +614,12 @@
 bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
                                const char *&PrevSpec,
                                unsigned &DiagID,
-                               Expr *Rep) {
+                               Expr *Rep,
+                               const PrintingPolicy &Policy) {
   assert(isExprRep(T) && "T does not store an expr");
   assert(Rep && "no expression provided!");
   if (TypeSpecType != TST_unspecified) {
-    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
     DiagID = diag::err_invalid_decl_spec_combination;
     return true;
   }
@@ -638,20 +634,22 @@
 bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
                                const char *&PrevSpec,
                                unsigned &DiagID,
-                               Decl *Rep, bool Owned) {
-  return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep, Owned);
+                               Decl *Rep, bool Owned,
+                               const PrintingPolicy &Policy) {
+  return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep, Owned, Policy);
 }
 
 bool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc,
                                SourceLocation TagNameLoc,
                                const char *&PrevSpec,
                                unsigned &DiagID,
-                               Decl *Rep, bool Owned) {
+                               Decl *Rep, bool Owned,
+                               const PrintingPolicy &Policy) {
   assert(isDeclRep(T) && "T does not store a decl");
   // Unlike the other cases, we don't assert that we actually get a decl.
 
   if (TypeSpecType != TST_unspecified) {
-    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
     DiagID = diag::err_invalid_decl_spec_combination;
     return true;
   }
@@ -659,17 +657,18 @@
   DeclRep = Rep;
   TSTLoc = TagKwLoc;
   TSTNameLoc = TagNameLoc;
-  TypeSpecOwned = Owned && Rep != 0;
+  TypeSpecOwned = Owned && Rep != nullptr;
   return false;
 }
 
 bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
                                const char *&PrevSpec,
-                               unsigned &DiagID) {
+                               unsigned &DiagID,
+                               const PrintingPolicy &Policy) {
   assert(!isDeclRep(T) && !isTypeRep(T) && !isExprRep(T) &&
          "rep required for these type-spec kinds!");
   if (TypeSpecType != TST_unspecified) {
-    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
     DiagID = diag::err_invalid_decl_spec_combination;
     return true;
   }
@@ -682,7 +681,7 @@
   TypeSpecType = T;
   TypeSpecOwned = false;
   if (TypeAltiVecVector && !TypeAltiVecBool && (TypeSpecType == TST_double)) {
-    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
     DiagID = diag::err_invalid_vector_decl_spec;
     return true;
   }
@@ -690,9 +689,10 @@
 }
 
 bool DeclSpec::SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc,
-                          const char *&PrevSpec, unsigned &DiagID) {
+                          const char *&PrevSpec, unsigned &DiagID,
+                          const PrintingPolicy &Policy) {
   if (TypeSpecType != TST_unspecified) {
-    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
     DiagID = diag::err_invalid_vector_decl_spec_combination;
     return true;
   }
@@ -702,10 +702,11 @@
 }
 
 bool DeclSpec::SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc,
-                          const char *&PrevSpec, unsigned &DiagID) {
+                          const char *&PrevSpec, unsigned &DiagID,
+                          const PrintingPolicy &Policy) {
   if (!TypeAltiVecVector || TypeAltiVecPixel ||
       (TypeSpecType != TST_unspecified)) {
-    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
     DiagID = diag::err_invalid_pixel_decl_spec_combination;
     return true;
   }
@@ -716,10 +717,11 @@
 }
 
 bool DeclSpec::SetTypeAltiVecBool(bool isAltiVecBool, SourceLocation Loc,
-                          const char *&PrevSpec, unsigned &DiagID) {
+                                  const char *&PrevSpec, unsigned &DiagID,
+                                  const PrintingPolicy &Policy) {
   if (!TypeAltiVecVector || TypeAltiVecBool ||
       (TypeSpecType != TST_unspecified)) {
-    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType, Policy);
     DiagID = diag::err_invalid_vector_bool_decl_spec;
     return true;
   }
@@ -837,7 +839,12 @@
                              unsigned &DiagID) {
   if (Friend_specified) {
     PrevSpec = "friend";
-    DiagID = diag::ext_duplicate_declspec;
+    // Keep the later location, so that we can later diagnose ill-formed
+    // declarations like 'friend class X friend;'. Per [class.friend]p3,
+    // 'friend' must be the first token in a friend declaration that is
+    // not a function declaration.
+    FriendLoc = Loc;
+    DiagID = diag::warn_duplicate_declspec;
     return true;
   }
 
@@ -860,7 +867,13 @@
 
 bool DeclSpec::SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec,
                                 unsigned &DiagID) {
-  // 'constexpr constexpr' is ok.
+  // 'constexpr constexpr' is ok, but warn as this is likely not what the user
+  // intended.
+  if (Constexpr_specified) {
+    DiagID = diag::warn_duplicate_declspec;
+    PrevSpec = "constexpr";
+    return true;
+  }
   Constexpr_specified = true;
   ConstexprLoc = Loc;
   return false;
@@ -900,7 +913,7 @@
 /// "_Imaginary" (lacking an FP type).  This returns a diagnostic to issue or
 /// diag::NUM_DIAGNOSTICS if there is no error.  After calling this method,
 /// DeclSpec is guaranteed self-consistent, even if an error occurred.
-void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP) {
+void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP, const PrintingPolicy &Policy) {
   // Before possibly changing their values, save specs as written.
   SaveWrittenBuiltinSpecs();
 
@@ -953,7 +966,7 @@
            (TypeSpecType != TST_int)) || TypeAltiVecPixel) {
         Diag(D, TSTLoc, diag::err_invalid_vector_bool_decl_spec)
           << (TypeAltiVecPixel ? "__pixel" :
-                                 getSpecifierName((TST)TypeSpecType));
+                                 getSpecifierName((TST)TypeSpecType, Policy));
       }
 
       // Only 'short' is valid with vector bool. (PIM 2.1)
@@ -983,7 +996,7 @@
     else if (TypeSpecType != TST_int  && TypeSpecType != TST_int128 &&
              TypeSpecType != TST_char && TypeSpecType != TST_wchar) {
       Diag(D, TSSLoc, diag::err_invalid_sign_spec)
-        << getSpecifierName((TST)TypeSpecType);
+        << getSpecifierName((TST)TypeSpecType, Policy);
       // signed double -> double.
       TypeSpecSign = TSS_unspecified;
     }
@@ -1000,7 +1013,7 @@
       Diag(D, TSWLoc,
            TypeSpecWidth == TSW_short ? diag::err_invalid_short_spec
                                       : diag::err_invalid_longlong_spec)
-        <<  getSpecifierName((TST)TypeSpecType);
+        <<  getSpecifierName((TST)TypeSpecType, Policy);
       TypeSpecType = TST_int;
       TypeSpecOwned = false;
     }
@@ -1010,7 +1023,7 @@
       TypeSpecType = TST_int;  // long -> long int.
     else if (TypeSpecType != TST_int && TypeSpecType != TST_double) {
       Diag(D, TSWLoc, diag::err_invalid_long_spec)
-        << getSpecifierName((TST)TypeSpecType);
+        << getSpecifierName((TST)TypeSpecType, Policy);
       TypeSpecType = TST_int;
       TypeSpecOwned = false;
     }
@@ -1032,7 +1045,7 @@
         Diag(D, TSTLoc, diag::ext_integer_complex);
     } else if (TypeSpecType != TST_float && TypeSpecType != TST_double) {
       Diag(D, TSCLoc, diag::err_invalid_complex_spec)
-        << getSpecifierName((TST)TypeSpecType);
+        << getSpecifierName((TST)TypeSpecType, Policy);
       TypeSpecComplex = TSC_unspecified;
     }
   }
@@ -1112,14 +1125,41 @@
       ThreadHint = FixItHint::CreateRemoval(SCLoc);
     }
 
-    Diag(D, SCLoc, diag::err_friend_storage_spec)
+    Diag(D, SCLoc, diag::err_friend_decl_spec)
       << SpecName << StorageHint << ThreadHint;
 
     ClearStorageClassSpecs();
   }
 
+  // C++11 [dcl.fct.spec]p5:
+  //   The virtual specifier shall be used only in the initial
+  //   declaration of a non-static class member function;
+  // C++11 [dcl.fct.spec]p6:
+  //   The explicit specifier shall be used only in the declaration of
+  //   a constructor or conversion function within its class
+  //   definition;
+  if (isFriendSpecified() && (isVirtualSpecified() || isExplicitSpecified())) {
+    StringRef Keyword;
+    SourceLocation SCLoc;
+
+    if (isVirtualSpecified()) {
+      Keyword = "virtual";
+      SCLoc = getVirtualSpecLoc();
+    } else {
+      Keyword = "explicit";
+      SCLoc = getExplicitSpecLoc();
+    }
+
+    FixItHint Hint = FixItHint::CreateRemoval(SCLoc);
+    Diag(D, SCLoc, diag::err_friend_decl_spec)
+      << Keyword << Hint;
+
+    FS_virtual_specified = FS_explicit_specified = false;
+    FS_virtualLoc = FS_explicitLoc = SourceLocation();
+  }
+
   assert(!TypeSpecOwned || isDeclRep((TST) TypeSpecType));
- 
+
   // Okay, now we can infer the real type.
 
   // TODO: return "auto function" and other bad things based on the real type.
@@ -1129,7 +1169,7 @@
 
 bool DeclSpec::isMissingDeclaratorOk() {
   TST tst = getTypeSpecType();
-  return isDeclRep(tst) && getRepAsDecl() != 0 &&
+  return isDeclRep(tst) && getRepAsDecl() != nullptr &&
     StorageClassSpec != DeclSpec::SCS_typedef;
 }
 
diff --git a/lib/Sema/DelayedDiagnostic.cpp b/lib/Sema/DelayedDiagnostic.cpp
index 3100432..664a6b1 100644
--- a/lib/Sema/DelayedDiagnostic.cpp
+++ b/lib/Sema/DelayedDiagnostic.cpp
@@ -19,19 +19,29 @@
 using namespace clang;
 using namespace sema;
 
-DelayedDiagnostic DelayedDiagnostic::makeDeprecation(SourceLocation Loc,
+DelayedDiagnostic
+DelayedDiagnostic::makeAvailability(Sema::AvailabilityDiagnostic AD,
+                                    SourceLocation Loc,
                                     const NamedDecl *D,
                                     const ObjCInterfaceDecl *UnknownObjCClass,
                                     const ObjCPropertyDecl  *ObjCProperty,
-                                    StringRef Msg) {
+                                    StringRef Msg,
+                                    bool ObjCPropertyAccess) {
   DelayedDiagnostic DD;
-  DD.Kind = Deprecation;
+  switch (AD) {
+    case Sema::AD_Deprecation:
+      DD.Kind = Deprecation;
+      break;
+    case Sema::AD_Unavailable:
+      DD.Kind = Unavailable;
+      break;
+  }
   DD.Triggered = false;
   DD.Loc = Loc;
   DD.DeprecationData.Decl = D;
   DD.DeprecationData.UnknownObjCClass = UnknownObjCClass;
   DD.DeprecationData.ObjCProperty = ObjCProperty;
-  char *MessageData = 0;
+  char *MessageData = nullptr;
   if (Msg.size()) {
     MessageData = new char [Msg.size()];
     memcpy(MessageData, Msg.data(), Msg.size());
@@ -39,16 +49,18 @@
 
   DD.DeprecationData.Message = MessageData;
   DD.DeprecationData.MessageLen = Msg.size();
+  DD.DeprecationData.ObjCPropertyAccess = ObjCPropertyAccess;
   return DD;
 }
 
 void DelayedDiagnostic::Destroy() {
-  switch (Kind) {
+  switch (static_cast<DDKind>(Kind)) {
   case Access: 
     getAccessData().~AccessedEntity(); 
     break;
 
-  case Deprecation: 
+  case Deprecation:
+  case Unavailable:
     delete [] DeprecationData.Message;
     break;
 
diff --git a/lib/Sema/IdentifierResolver.cpp b/lib/Sema/IdentifierResolver.cpp
index 6e354b9..2a5bacf 100644
--- a/lib/Sema/IdentifierResolver.cpp
+++ b/lib/Sema/IdentifierResolver.cpp
@@ -45,7 +45,7 @@
   unsigned int CurIndex;
 
 public:
-  IdDeclInfoMap() : CurPool(0), CurIndex(POOL_SIZE) {}
+  IdDeclInfoMap() : CurPool(nullptr), CurIndex(POOL_SIZE) {}
 
   ~IdDeclInfoMap() {
     IdDeclInfoPool *Cur = CurPool;
@@ -95,7 +95,7 @@
 /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
 /// true if 'D' belongs to the given declaration context.
 bool IdentifierResolver::isDeclInScope(Decl *D, DeclContext *Ctx, Scope *S,
-                             bool ExplicitInstantiationOrSpecialization) const {
+                                       bool AllowInlineNamespace) const {
   Ctx = Ctx->getRedeclContext();
 
   if (Ctx->isFunctionOrMethod() || S->isFunctionPrototypeScope()) {
@@ -131,9 +131,8 @@
   }
 
   DeclContext *DCtx = D->getDeclContext()->getRedeclContext();
-  return ExplicitInstantiationOrSpecialization
-           ? Ctx->InEnclosingNamespaceSetOf(DCtx)
-           : Ctx->Equals(DCtx);
+  return AllowInlineNamespace ? Ctx->InEnclosingNamespaceSetOf(DCtx)
+                              : Ctx->Equals(DCtx);
 }
 
 /// AddDecl - Link the decl to its shadowed decl chain.
@@ -152,7 +151,7 @@
   IdDeclInfo *IDI;
 
   if (isDeclPtr(Ptr)) {
-    Name.setFETokenInfo(NULL);
+    Name.setFETokenInfo(nullptr);
     IDI = &(*IdDeclInfos)[Name];
     NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr);
     IDI->AddDecl(PrevD);
@@ -214,7 +213,7 @@
 
   if (isDeclPtr(Ptr)) {
     assert(D == Ptr && "Didn't find this decl on its identifier's chain!");
-    Name.setFETokenInfo(NULL);
+    Name.setFETokenInfo(nullptr);
     return;
   }
 
@@ -274,10 +273,8 @@
 
     // If the existing declaration is somewhere in the previous declaration
     // chain of the new declaration, then prefer the new declaration.
-    for (Decl::redecl_iterator RD = New->redecls_begin(), 
-                            RDEnd = New->redecls_end();
-         RD != RDEnd; ++RD) {
-      if (*RD == Existing)
+    for (auto RD : New->redecls()) {
+      if (RD == Existing)
         return DMK_Replace;
         
       if (RD->isCanonicalDecl())
@@ -317,8 +314,8 @@
       Name.setFETokenInfo(D);
       return true;
     }
-    
-    Name.setFETokenInfo(NULL);
+
+    Name.setFETokenInfo(nullptr);
     IDI = &(*IdDeclInfos)[Name];
     
     // If the existing declaration is not visible in translation unit scope,
diff --git a/lib/Sema/JumpDiagnostics.cpp b/lib/Sema/JumpDiagnostics.cpp
index d3de173..2558452 100644
--- a/lib/Sema/JumpDiagnostics.cpp
+++ b/lib/Sema/JumpDiagnostics.cpp
@@ -32,6 +32,10 @@
 class JumpScopeChecker {
   Sema &S;
 
+  /// Permissive - True when recovering from errors, in which case precautions
+  /// are taken to handle incomplete scope information.
+  const bool Permissive;
+
   /// GotoScope - This is a record that we use to keep track of all of the
   /// scopes that are introduced by VLAs and other things that scope jumps like
   /// gotos.  This scope tree has nothing to do with the source scope tree,
@@ -85,8 +89,10 @@
 };
 } // end anonymous namespace
 
+#define CHECK_PERMISSIVE(x) (assert(Permissive || !(x)), (Permissive && (x)))
 
-JumpScopeChecker::JumpScopeChecker(Stmt *Body, Sema &s) : S(s) {
+JumpScopeChecker::JumpScopeChecker(Stmt *Body, Sema &s)
+    : S(s), Permissive(s.hasAnyUnrecoverableErrorsInThisFunction()) {
   // Add a scope entry for function scope.
   Scopes.push_back(GotoScope(~0U, ~0U, ~0U, SourceLocation()));
 
@@ -121,9 +127,11 @@
 
 /// GetDiagForGotoScopeDecl - If this decl induces a new goto scope, return a
 /// diagnostic that should be emitted if control goes over it. If not, return 0.
-static ScopePair GetDiagForGotoScopeDecl(ASTContext &Context, const Decl *D) {
+static ScopePair GetDiagForGotoScopeDecl(Sema &S, const Decl *D) {
   if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
     unsigned InDiag = 0;
+    unsigned OutDiag = 0;
+
     if (VD->getType()->isVariablyModifiedType())
       InDiag = diag::note_protected_by_vla;
 
@@ -135,21 +143,24 @@
       return ScopePair(diag::note_protected_by_cleanup,
                        diag::note_exits_cleanup);
 
-    if (Context.getLangOpts().ObjCAutoRefCount && VD->hasLocalStorage()) {
-      switch (VD->getType().getObjCLifetime()) {
-      case Qualifiers::OCL_None:
-      case Qualifiers::OCL_ExplicitNone:
-      case Qualifiers::OCL_Autoreleasing:
-        break;
-
-      case Qualifiers::OCL_Strong:
-      case Qualifiers::OCL_Weak:
+    if (VD->hasLocalStorage()) {
+      switch (VD->getType().isDestructedType()) {
+      case QualType::DK_objc_strong_lifetime:
+      case QualType::DK_objc_weak_lifetime:
         return ScopePair(diag::note_protected_by_objc_ownership,
                          diag::note_exits_objc_ownership);
+
+      case QualType::DK_cxx_destructor:
+        OutDiag = diag::note_exits_dtor;
+        break;
+
+      case QualType::DK_none:
+        break;
       }
     }
 
-    if (Context.getLangOpts().CPlusPlus && VD->hasLocalStorage()) {
+    const Expr *Init = VD->getInit();
+    if (S.Context.getLangOpts().CPlusPlus && VD->hasLocalStorage() && Init) {
       // C++11 [stmt.dcl]p3:
       //   A program that jumps from a point where a variable with automatic
       //   storage duration is not in scope to a point where it is in scope
@@ -164,68 +175,34 @@
       //   where it is in scope is ill-formed unless the variable has
       //   POD type and is declared without an initializer.
 
-      const Expr *Init = VD->getInit();
-      if (!Init)
-        return ScopePair(InDiag, 0);
+      InDiag = diag::note_protected_by_variable_init;
 
-      const ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(Init);
-      if (EWC)
-        Init = EWC->getSubExpr();
-
-      const MaterializeTemporaryExpr *M = NULL;
-      Init = Init->findMaterializedTemporary(M);
-
-      SmallVector<const Expr *, 2> CommaLHSs;
-      SmallVector<SubobjectAdjustment, 2> Adjustments;
-      Init = Init->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments);
-
-      QualType QT = Init->getType();
-      if (QT.isNull())
-        return ScopePair(diag::note_protected_by_variable_init, 0);
-
-      const Type *T = QT.getTypePtr();
-      if (T->isArrayType())
-        T = T->getBaseElementTypeUnsafe();
-
-      const CXXRecordDecl *Record = T->getAsCXXRecordDecl();
-      if (!Record)
-        return ScopePair(diag::note_protected_by_variable_init, 0);
-
-      // If we need to call a non trivial destructor for this variable,
-      // record an out diagnostic.
-      unsigned OutDiag = 0;
-      if (!Init->isGLValue() && !Record->hasTrivialDestructor())
-        OutDiag = diag::note_exits_dtor;
-
-      if (const CXXConstructExpr *cce = dyn_cast<CXXConstructExpr>(Init)) {
-        const CXXConstructorDecl *ctor = cce->getConstructor();
-        // For a variable declared without an initializer, we will have
-        // call-style initialization and the initializer will be the
-        // CXXConstructExpr with no intervening nodes.
-        if (ctor->isTrivial() && ctor->isDefaultConstructor() &&
-            VD->getInit() == Init && VD->getInitStyle() == VarDecl::CallInit) {
+      // For a variable of (array of) class type declared without an
+      // initializer, we will have call-style initialization and the initializer
+      // will be the CXXConstructExpr with no intervening nodes.
+      if (const CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(Init)) {
+        const CXXConstructorDecl *Ctor = CCE->getConstructor();
+        if (Ctor->isTrivial() && Ctor->isDefaultConstructor() &&
+            VD->getInitStyle() == VarDecl::CallInit) {
           if (OutDiag)
             InDiag = diag::note_protected_by_variable_nontriv_destructor;
-          else if (!Record->isPOD())
+          else if (!Ctor->getParent()->isPOD())
             InDiag = diag::note_protected_by_variable_non_pod;
-          return ScopePair(InDiag, OutDiag);
+          else
+            InDiag = 0;
         }
       }
-
-      return ScopePair(diag::note_protected_by_variable_init, OutDiag);
     }
 
-    return ScopePair(InDiag, 0);
+    return ScopePair(InDiag, OutDiag);
   }
 
-  if (const TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
+  if (const TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
     if (TD->getUnderlyingType()->isVariablyModifiedType())
-      return ScopePair(diag::note_protected_by_vla_typedef, 0);
-  }
-
-  if (const TypeAliasDecl *TD = dyn_cast<TypeAliasDecl>(D)) {
-    if (TD->getUnderlyingType()->isVariablyModifiedType())
-      return ScopePair(diag::note_protected_by_vla_type_alias, 0);
+      return ScopePair(isa<TypedefDecl>(TD)
+                           ? diag::note_protected_by_vla_typedef
+                           : diag::note_protected_by_vla_type_alias,
+                       0);
   }
 
   return ScopePair(0U, 0U);
@@ -234,7 +211,7 @@
 /// \brief Build scope information for a declaration that is part of a DeclStmt.
 void JumpScopeChecker::BuildScopeInformation(Decl *D, unsigned &ParentScope) {
   // If this decl causes a new scope, push and switch to it.
-  std::pair<unsigned,unsigned> Diags = GetDiagForGotoScopeDecl(S.Context, D);
+  std::pair<unsigned,unsigned> Diags = GetDiagForGotoScopeDecl(S, D);
   if (Diags.first || Diags.second) {
     Scopes.push_back(GotoScope(ParentScope, Diags.first, Diags.second,
                                D->getLocation()));
@@ -371,7 +348,7 @@
     }
     
     Stmt *SubStmt = *CI;
-    if (SubStmt == 0) continue;
+    if (!SubStmt) continue;
 
     // Cases, labels, and defaults aren't "scope parents".  It's also
     // important to handle these iteratively instead of recursively in
@@ -396,9 +373,8 @@
     if (DeclStmt *DS = dyn_cast<DeclStmt>(SubStmt)) {
       // The decl statement creates a scope if any of the decls in it are VLAs
       // or have the cleanup attribute.
-      for (DeclStmt::decl_iterator I = DS->decl_begin(), E = DS->decl_end();
-           I != E; ++I)
-        BuildScopeInformation(*I, ParentScope);
+      for (auto *I : DS->decls())
+        BuildScopeInformation(I, ParentScope);
       continue;
     }
     // Disallow jumps into any part of an @try statement by pushing a scope and
@@ -474,14 +450,32 @@
     if (ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(SubStmt)) {
       for (unsigned i = 0, e = EWC->getNumObjects(); i != e; ++i) {
         const BlockDecl *BDecl = EWC->getObject(i);
-        for (BlockDecl::capture_const_iterator ci = BDecl->capture_begin(),
-             ce = BDecl->capture_end(); ci != ce; ++ci) {
-          VarDecl *variable = ci->getVariable();
+        for (const auto &CI : BDecl->captures()) {
+          VarDecl *variable = CI.getVariable();
           BuildScopeInformation(variable, BDecl, ParentScope);
         }
       }
     }
-    
+
+    // Disallow jumps out of scopes containing temporaries lifetime-extended to
+    // automatic storage duration.
+    if (MaterializeTemporaryExpr *MTE =
+            dyn_cast<MaterializeTemporaryExpr>(SubStmt)) {
+      if (MTE->getStorageDuration() == SD_Automatic) {
+        SmallVector<const Expr *, 4> CommaLHS;
+        SmallVector<SubobjectAdjustment, 4> Adjustments;
+        const Expr *ExtendedObject =
+            MTE->GetTemporaryExpr()->skipRValueSubobjectAdjustments(
+                CommaLHS, Adjustments);
+        if (ExtendedObject->getType().isDestructedType()) {
+          Scopes.push_back(GotoScope(ParentScope, 0,
+                                     diag::note_exits_temporary_dtor,
+                                     ExtendedObject->getExprLoc()));
+          ParentScope = Scopes.size()-1;
+        }
+      }
+    }
+
     // Recursively walk the AST.
     BuildScopeInformation(SubStmt, ParentScope);
   }
@@ -497,7 +491,7 @@
     if (GotoStmt *GS = dyn_cast<GotoStmt>(Jump)) {
       CheckJump(GS, GS->getLabel()->getStmt(), GS->getGotoLoc(),
                 diag::err_goto_into_protected_scope,
-                diag::warn_goto_into_protected_scope,
+                diag::ext_goto_into_protected_scope,
                 diag::warn_cxx98_compat_goto_into_protected_scope);
       continue;
     }
@@ -507,7 +501,7 @@
       LabelDecl *Target = IGS->getConstantTarget();
       CheckJump(IGS, Target->getStmt(), IGS->getGotoLoc(),
                 diag::err_goto_into_protected_scope,
-                diag::warn_goto_into_protected_scope,
+                diag::ext_goto_into_protected_scope,
                 diag::warn_cxx98_compat_goto_into_protected_scope);
       continue;
     }
@@ -515,7 +509,8 @@
     SwitchStmt *SS = cast<SwitchStmt>(Jump);
     for (SwitchCase *SC = SS->getSwitchCaseList(); SC;
          SC = SC->getNextSwitchCase()) {
-      assert(LabelAndGotoScopes.count(SC) && "Case not visited?");
+      if (CHECK_PERMISSIVE(!LabelAndGotoScopes.count(SC)))
+        continue;
       SourceLocation Loc;
       if (CaseStmt *CS = dyn_cast<CaseStmt>(SC))
         Loc = CS->getLocStart();
@@ -569,8 +564,8 @@
     for (SmallVectorImpl<IndirectGotoStmt*>::iterator
            I = IndirectJumps.begin(), E = IndirectJumps.end(); I != E; ++I) {
       IndirectGotoStmt *IG = *I;
-      assert(LabelAndGotoScopes.count(IG) &&
-             "indirect jump didn't get added to scopes?");
+      if (CHECK_PERMISSIVE(!LabelAndGotoScopes.count(IG)))
+        continue;
       unsigned IGScope = LabelAndGotoScopes[IG];
       IndirectGotoStmt *&Entry = JumpScopesMap[IGScope];
       if (!Entry) Entry = IG;
@@ -589,8 +584,8 @@
          I = IndirectJumpTargets.begin(), E = IndirectJumpTargets.end();
        I != E; ++I) {
     LabelDecl *TheLabel = *I;
-    assert(LabelAndGotoScopes.count(TheLabel->getStmt()) &&
-           "Referenced label didn't get added to scopes?");
+    if (CHECK_PERMISSIVE(!LabelAndGotoScopes.count(TheLabel->getStmt())))
+      continue;
     unsigned LabelScope = LabelAndGotoScopes[TheLabel->getStmt()];
     LabelDecl *&Target = TargetScopes[LabelScope];
     if (!Target) Target = TheLabel;
@@ -695,7 +690,8 @@
 
 /// Produce note diagnostics for a jump into a protected scope.
 void JumpScopeChecker::NoteJumpIntoScopes(ArrayRef<unsigned> ToScopes) {
-  assert(!ToScopes.empty());
+  if (CHECK_PERMISSIVE(ToScopes.empty()))
+    return;
   for (unsigned I = 0, E = ToScopes.size(); I != E; ++I)
     if (Scopes[ToScopes[I]].InDiag)
       S.Diag(Scopes[ToScopes[I]].Loc, Scopes[ToScopes[I]].InDiag);
@@ -706,7 +702,8 @@
                                             unsigned JumpScope,
                                             LabelDecl *Target,
                                             unsigned TargetScope) {
-  assert(JumpScope != TargetScope);
+  if (CHECK_PERMISSIVE(JumpScope == TargetScope))
+    return;
 
   unsigned Common = GetDeepestCommonScope(JumpScope, TargetScope);
   bool Diagnosed = false;
@@ -743,10 +740,12 @@
 void JumpScopeChecker::CheckJump(Stmt *From, Stmt *To, SourceLocation DiagLoc,
                                unsigned JumpDiagError, unsigned JumpDiagWarning,
                                  unsigned JumpDiagCXX98Compat) {
-  assert(LabelAndGotoScopes.count(From) && "Jump didn't get added to scopes?");
-  unsigned FromScope = LabelAndGotoScopes[From];
+  if (CHECK_PERMISSIVE(!LabelAndGotoScopes.count(From)))
+    return;
+  if (CHECK_PERMISSIVE(!LabelAndGotoScopes.count(To)))
+    return;
 
-  assert(LabelAndGotoScopes.count(To) && "Jump didn't get added to scopes?");
+  unsigned FromScope = LabelAndGotoScopes[From];
   unsigned ToScope = LabelAndGotoScopes[To];
 
   // Common case: exactly the same scope, which is fine.
@@ -762,7 +761,7 @@
   SmallVector<unsigned, 10> ToScopesError;
   SmallVector<unsigned, 10> ToScopesWarning;
   for (unsigned I = ToScope; I != CommonScope; I = Scopes[I].ParentScope) {
-    if (S.getLangOpts().MicrosoftMode && JumpDiagWarning != 0 &&
+    if (S.getLangOpts().MSVCCompat && JumpDiagWarning != 0 &&
         IsMicrosoftJumpWarning(JumpDiagError, Scopes[I].InDiag))
       ToScopesWarning.push_back(I);
     else if (IsCXX98CompatWarning(S, Scopes[I].InDiag))
diff --git a/lib/Sema/MultiplexExternalSemaSource.cpp b/lib/Sema/MultiplexExternalSemaSource.cpp
index ad7627a..97237db 100644
--- a/lib/Sema/MultiplexExternalSemaSource.cpp
+++ b/lib/Sema/MultiplexExternalSemaSource.cpp
@@ -46,7 +46,12 @@
   for(size_t i = 0; i < Sources.size(); ++i)
     if (Decl *Result = Sources[i]->GetExternalDecl(ID))
       return Result;
-  return 0;
+  return nullptr;
+}
+
+void MultiplexExternalSemaSource::CompleteRedeclChain(const Decl *D) {
+  for (size_t i = 0; i < Sources.size(); ++i)
+    Sources[i]->CompleteRedeclChain(D);
 }
 
 Selector MultiplexExternalSemaSource::GetExternalSelector(uint32_t ID) {
@@ -70,7 +75,7 @@
   for(size_t i = 0; i < Sources.size(); ++i)
     if (Stmt *Result = Sources[i]->GetExternalDeclStmt(Offset))
       return Result;
-  return 0;
+  return nullptr;
 }
 
 CXXBaseSpecifier *MultiplexExternalSemaSource::GetExternalCXXBaseSpecifiers(
@@ -78,7 +83,7 @@
   for(size_t i = 0; i < Sources.size(); ++i)
     if (CXXBaseSpecifier *R = Sources[i]->GetExternalCXXBaseSpecifiers(Offset))
       return R;
-  return 0; 
+  return nullptr;
 }
 
 bool MultiplexExternalSemaSource::
diff --git a/lib/Sema/Scope.cpp b/lib/Sema/Scope.cpp
index 10f12ce..35e2075 100644
--- a/lib/Sema/Scope.cpp
+++ b/lib/Sema/Scope.cpp
@@ -13,6 +13,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Sema/Scope.h"
+#include "clang/AST/Decl.h"
+#include "llvm/Support/raw_ostream.h"
 
 using namespace clang;
 
@@ -26,7 +28,7 @@
   } else {
     // Control scopes do not contain the contents of nested function scopes for
     // control flow purposes.
-    BreakParent = ContinueParent = 0;
+    BreakParent = ContinueParent = nullptr;
   }
 
   if (parent) {
@@ -36,16 +38,35 @@
     FnParent       = parent->FnParent;
     BlockParent    = parent->BlockParent;
     TemplateParamParent = parent->TemplateParamParent;
+    MSLocalManglingParent = parent->MSLocalManglingParent;
+    SEHTryParent = parent->SEHTryParent;
+    if (parent->Flags & SEHTryScope)
+      SEHTryParent = parent;
+    if ((Flags & (FnScope | ClassScope | BlockScope | TemplateParamScope |
+                  FunctionPrototypeScope | AtCatchScope | ObjCMethodScope)) ==
+        0)
+      Flags |= parent->getFlags() & OpenMPSimdDirectiveScope;
   } else {
     Depth = 0;
     PrototypeDepth = 0;
     PrototypeIndex = 0;
-    FnParent = BlockParent = 0;
-    TemplateParamParent = 0;
+    SEHTryParent = MSLocalManglingParent = FnParent = BlockParent = nullptr;
+    TemplateParamParent = nullptr;
+    MSLocalManglingNumber = 1;
   }
 
   // If this scope is a function or contains breaks/continues, remember it.
   if (flags & FnScope)            FnParent = this;
+  SEHTryIndexPool = 0;
+  SEHTryIndex = -1;
+  if (flags & SEHTryScope)
+    SEHTryIndex = FnParent ? FnParent->SEHTryIndexPool++ : -1;
+  // The MS mangler uses the number of scopes that can hold declarations as
+  // part of an external name.
+  if (Flags & (ClassScope | FnScope)) {
+    MSLocalManglingNumber = getMSLocalManglingNumber();
+    MSLocalManglingParent = this;
+  }
   if (flags & BreakScope)         BreakParent = this;
   if (flags & ContinueScope)      ContinueParent = this;
   if (flags & BlockScope)         BlockParent = this;
@@ -54,10 +75,24 @@
   // If this is a prototype scope, record that.
   if (flags & FunctionPrototypeScope) PrototypeDepth++;
 
+  if (flags & DeclScope) {
+    if (flags & FunctionPrototypeScope)
+      ; // Prototype scopes are uninteresting.
+    else if ((flags & ClassScope) && getParent()->isClassScope())
+      ; // Nested class scopes aren't ambiguous.
+    else if ((flags & ClassScope) && getParent()->getFlags() == DeclScope)
+      ; // Classes inside of namespaces aren't ambiguous.
+    else if ((flags & EnumScope))
+      ; // Don't increment for enum scopes.
+    else
+      incrementMSLocalManglingNumber();
+  }
+
   DeclsInScope.clear();
   UsingDirectives.clear();
-  Entity = 0;
+  Entity = nullptr;
   ErrorTrap.reset();
+  NRVO.setPointerAndInt(nullptr, 0);
 }
 
 bool Scope::containedInPrototypeScope() const {
@@ -69,3 +104,121 @@
   }
   return false;
 }
+
+void Scope::AddFlags(unsigned FlagsToSet) {
+  assert((FlagsToSet & ~(BreakScope | ContinueScope)) == 0 &&
+         "Unsupported scope flags");
+  if (FlagsToSet & BreakScope) {
+    assert((Flags & BreakScope) == 0 && "Already set");
+    BreakParent = this;
+  }
+  if (FlagsToSet & ContinueScope) {
+    assert((Flags & ContinueScope) == 0 && "Already set");
+    ContinueParent = this;
+  }
+  Flags |= FlagsToSet;
+}
+
+void Scope::mergeNRVOIntoParent() {
+  if (VarDecl *Candidate = NRVO.getPointer()) {
+    if (isDeclScope(Candidate))
+      Candidate->setNRVOVariable(true);
+  }
+
+  if (getEntity())
+    return;
+
+  if (NRVO.getInt())
+    getParent()->setNoNRVO();
+  else if (NRVO.getPointer())
+    getParent()->addNRVOCandidate(NRVO.getPointer());
+}
+
+void Scope::dump() const { dumpImpl(llvm::errs()); }
+
+void Scope::dumpImpl(raw_ostream &OS) const {
+  unsigned Flags = getFlags();
+  bool HasFlags = Flags != 0;
+
+  if (HasFlags)
+    OS << "Flags: ";
+
+  while (Flags) {
+    if (Flags & FnScope) {
+      OS << "FnScope";
+      Flags &= ~FnScope;
+    } else if (Flags & BreakScope) {
+      OS << "BreakScope";
+      Flags &= ~BreakScope;
+    } else if (Flags & ContinueScope) {
+      OS << "ContinueScope";
+      Flags &= ~ContinueScope;
+    } else if (Flags & DeclScope) {
+      OS << "DeclScope";
+      Flags &= ~DeclScope;
+    } else if (Flags & ControlScope) {
+      OS << "ControlScope";
+      Flags &= ~ControlScope;
+    } else if (Flags & ClassScope) {
+      OS << "ClassScope";
+      Flags &= ~ClassScope;
+    } else if (Flags & BlockScope) {
+      OS << "BlockScope";
+      Flags &= ~BlockScope;
+    } else if (Flags & TemplateParamScope) {
+      OS << "TemplateParamScope";
+      Flags &= ~TemplateParamScope;
+    } else if (Flags & FunctionPrototypeScope) {
+      OS << "FunctionPrototypeScope";
+      Flags &= ~FunctionPrototypeScope;
+    } else if (Flags & FunctionDeclarationScope) {
+      OS << "FunctionDeclarationScope";
+      Flags &= ~FunctionDeclarationScope;
+    } else if (Flags & AtCatchScope) {
+      OS << "AtCatchScope";
+      Flags &= ~AtCatchScope;
+    } else if (Flags & ObjCMethodScope) {
+      OS << "ObjCMethodScope";
+      Flags &= ~ObjCMethodScope;
+    } else if (Flags & SwitchScope) {
+      OS << "SwitchScope";
+      Flags &= ~SwitchScope;
+    } else if (Flags & TryScope) {
+      OS << "TryScope";
+      Flags &= ~TryScope;
+    } else if (Flags & FnTryCatchScope) {
+      OS << "FnTryCatchScope";
+      Flags &= ~FnTryCatchScope;
+    } else if (Flags & SEHTryScope) {
+      OS << "SEHTryScope";
+      Flags &= ~SEHTryScope;
+    } else if (Flags & OpenMPDirectiveScope) {
+      OS << "OpenMPDirectiveScope";
+      Flags &= ~OpenMPDirectiveScope;
+    } else if (Flags & OpenMPLoopDirectiveScope) {
+      OS << "OpenMPLoopDirectiveScope";
+      Flags &= ~OpenMPLoopDirectiveScope;
+    } else if (Flags & OpenMPSimdDirectiveScope) {
+      OS << "OpenMPSimdDirectiveScope";
+      Flags &= ~OpenMPSimdDirectiveScope;
+    }
+
+    if (Flags)
+      OS << " | ";
+  }
+  if (HasFlags)
+    OS << '\n';
+
+  if (const Scope *Parent = getParent())
+    OS << "Parent: (clang::Scope*)" << Parent << '\n';
+
+  OS << "Depth: " << Depth << '\n';
+  OS << "MSLocalManglingNumber: " << getMSLocalManglingNumber() << '\n';
+  if (const DeclContext *DC = getEntity())
+    OS << "Entity : (clang::DeclContext*)" << DC << '\n';
+
+  if (NRVO.getInt())
+    OS << "NRVO not allowed";
+  else if (NRVO.getPointer())
+    OS << "NRVO candidate : (clang::VarDecl*)" << NRVO.getPointer() << '\n';
+}
diff --git a/lib/Sema/ScopeInfo.cpp b/lib/Sema/ScopeInfo.cpp
index 8b3493e..4d079e7 100644
--- a/lib/Sema/ScopeInfo.cpp
+++ b/lib/Sema/ScopeInfo.cpp
@@ -26,6 +26,12 @@
   HasBranchProtectedScope = false;
   HasBranchIntoScope = false;
   HasIndirectGoto = false;
+  HasDroppedStmt = false;
+  ObjCShouldCallSuper = false;
+  ObjCIsDesignatedInit = false;
+  ObjCWarnForNoDesignatedInitChain = false;
+  ObjCIsSecondaryInit = false;
+  ObjCWarnForNoInitDelegation = false;
 
   SwitchStack.clear();
   Returns.clear();
@@ -45,7 +51,7 @@
 FunctionScopeInfo::WeakObjectProfileTy::getBaseInfo(const Expr *E) {
   E = E->IgnoreParenCasts();
 
-  const NamedDecl *D = 0;
+  const NamedDecl *D = nullptr;
   bool IsExact = false;
 
   switch (E->getStmtClass()) {
@@ -87,10 +93,9 @@
   return BaseInfoTy(D, IsExact);
 }
 
-
 FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(
                                           const ObjCPropertyRefExpr *PropE)
-    : Base(0, true), Property(getBestPropertyDecl(PropE)) {
+    : Base(nullptr, true), Property(getBestPropertyDecl(PropE)) {
 
   if (PropE->isObjectReceiver()) {
     const OpaqueValueExpr *OVE = cast<OpaqueValueExpr>(PropE->getBase());
@@ -105,7 +110,7 @@
 
 FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(const Expr *BaseE,
                                                 const ObjCPropertyDecl *Prop)
-    : Base(0, true), Property(Prop) {
+    : Base(nullptr, true), Property(Prop) {
   if (BaseE)
     Base = getBaseInfo(BaseE);
   // else, this is a message accessing a property on super.
@@ -113,7 +118,7 @@
 
 FunctionScopeInfo::WeakObjectProfileTy::WeakObjectProfileTy(
                                                       const DeclRefExpr *DRE)
-  : Base(0, true), Property(DRE->getDecl()) {
+  : Base(nullptr, true), Property(DRE->getDecl()) {
   assert(isa<VarDecl>(Property));
 }
 
@@ -153,8 +158,14 @@
 
   // Has this weak object been seen before?
   FunctionScopeInfo::WeakObjectUseMap::iterator Uses;
-  if (const ObjCPropertyRefExpr *RefExpr = dyn_cast<ObjCPropertyRefExpr>(E))
-    Uses = WeakObjectUses.find(WeakObjectProfileTy(RefExpr));
+  if (const ObjCPropertyRefExpr *RefExpr = dyn_cast<ObjCPropertyRefExpr>(E)) {
+    if (isa<OpaqueValueExpr>(RefExpr->getBase()))
+     Uses = WeakObjectUses.find(WeakObjectProfileTy(RefExpr));
+    else {
+      markSafeWeakUse(RefExpr->getBase());
+      return;
+    }
+  }
   else if (const ObjCIvarRefExpr *IvarE = dyn_cast<ObjCIvarRefExpr>(E))
     Uses = WeakObjectUses.find(WeakObjectProfileTy(IvarE));
   else if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
@@ -184,10 +195,11 @@
   ThisUse->markSafe();
 }
 
-void LambdaScopeInfo::getPotentialVariableCapture(unsigned Idx, VarDecl *&VD, Expr *&E) {
+void LambdaScopeInfo::getPotentialVariableCapture(unsigned Idx, VarDecl *&VD,
+                                                  Expr *&E) const {
   assert(Idx < getNumPotentialVariableCaptures() &&
-    "Index of potential capture must be within 0 to less than the "
-    "number of captures!");
+         "Index of potential capture must be within 0 to less than the "
+         "number of captures!");
   E = PotentiallyCapturingExprs[Idx];
   if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
     VD = dyn_cast<VarDecl>(DRE->getFoundDecl());
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index 4d01fb0..2c65332 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -13,7 +13,6 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Sema/SemaInternal.h"
-#include "TargetAttributesSema.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTDiagnostic.h"
 #include "clang/AST/DeclCXX.h"
@@ -22,6 +21,7 @@
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/StmtCXX.h"
+#include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/PartialDiagnostic.h"
 #include "clang/Basic/TargetInfo.h"
@@ -44,6 +44,12 @@
 using namespace clang;
 using namespace sema;
 
+SourceLocation Sema::getLocForEndOfToken(SourceLocation Loc, unsigned Offset) {
+  return Lexer::getLocForEndOfToken(Loc, Offset, SourceMgr, LangOpts);
+}
+
+ModuleLoader &Sema::getModuleLoader() const { return PP.getModuleLoader(); }
+
 PrintingPolicy Sema::getPrintingPolicy(const ASTContext &Context,
                                        const Preprocessor &PP) {
   PrintingPolicy Policy = Context.getPrintingPolicy();
@@ -70,35 +76,41 @@
 Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
            TranslationUnitKind TUKind,
            CodeCompleteConsumer *CodeCompleter)
-  : TheTargetAttributesSema(0), ExternalSource(0),
+  : ExternalSource(nullptr),
     isMultiplexExternalSource(false), FPFeatures(pp.getLangOpts()),
     LangOpts(pp.getLangOpts()), PP(pp), Context(ctxt), Consumer(consumer),
     Diags(PP.getDiagnostics()), SourceMgr(PP.getSourceManager()),
     CollectStats(false), CodeCompleter(CodeCompleter),
-    CurContext(0), OriginalLexicalContext(0),
-    PackContext(0), MSStructPragmaOn(false), VisContext(0),
+    CurContext(nullptr), OriginalLexicalContext(nullptr),
+    PackContext(nullptr), MSStructPragmaOn(false),
+    MSPointerToMemberRepresentationMethod(
+        LangOpts.getMSPointerToMemberRepresentationMethod()),
+    VtorDispModeStack(1, MSVtorDispAttr::Mode(LangOpts.VtorDispMode)),
+    DataSegStack(nullptr), BSSSegStack(nullptr), ConstSegStack(nullptr),
+    CodeSegStack(nullptr), CurInitSeg(nullptr), VisContext(nullptr),
     IsBuildingRecoveryCallExpr(false),
-    ExprNeedsCleanups(false), LateTemplateParser(0), OpaqueParser(0),
-    IdResolver(pp), StdInitializerList(0), CXXTypeInfoDecl(0), MSVCGuidDecl(0),
-    NSNumberDecl(0),
-    NSStringDecl(0), StringWithUTF8StringMethod(0),
-    NSArrayDecl(0), ArrayWithObjectsMethod(0),
-    NSDictionaryDecl(0), DictionaryWithObjectsMethod(0),
+    ExprNeedsCleanups(false), LateTemplateParser(nullptr),
+    OpaqueParser(nullptr), IdResolver(pp), StdInitializerList(nullptr),
+    CXXTypeInfoDecl(nullptr), MSVCGuidDecl(nullptr),
+    NSNumberDecl(nullptr),
+    NSStringDecl(nullptr), StringWithUTF8StringMethod(nullptr),
+    NSArrayDecl(nullptr), ArrayWithObjectsMethod(nullptr),
+    NSDictionaryDecl(nullptr), DictionaryWithObjectsMethod(nullptr),
     GlobalNewDeleteDeclared(false),
     TUKind(TUKind),
-    NumSFINAEErrors(0), InFunctionDeclarator(0),
+    NumSFINAEErrors(0),
     AccessCheckingSFINAE(false), InNonInstantiationSFINAEContext(false),
     NonInstantiationEntries(0), ArgumentPackSubstitutionIndex(-1),
-    CurrentInstantiationScope(0), DisableTypoCorrection(false),
+    CurrentInstantiationScope(nullptr), DisableTypoCorrection(false),
     TyposCorrected(0), AnalysisWarnings(*this),
-    VarDataSharingAttributesStack(0), CurScope(0),
-    Ident_super(0), Ident___float128(0)
+    VarDataSharingAttributesStack(nullptr), CurScope(nullptr),
+    Ident_super(nullptr), Ident___float128(nullptr)
 {
-  TUScope = 0;
+  TUScope = nullptr;
 
   LoadedExternalKnownNamespaces = false;
   for (unsigned I = 0; I != NSAPI::NumNSNumberLiteralMethods; ++I)
-    NSNumberLiteralMethods[I] = 0;
+    NSNumberLiteralMethods[I] = nullptr;
 
   if (getLangOpts().ObjC1)
     NSAPIObj.reset(new NSAPI(Context));
@@ -112,7 +124,7 @@
 
   ExprEvalContexts.push_back(
         ExpressionEvaluationContextRecord(PotentiallyEvaluated, 0,
-                                          false, 0, false));
+                                          false, nullptr, false));
 
   FunctionScopes.push_back(new FunctionScopeInfo(Diags));
 
@@ -120,6 +132,12 @@
   InitDataSharingAttributesStack();
 }
 
+void Sema::addImplicitTypedef(StringRef Name, QualType T) {
+  DeclarationName DN = &Context.Idents.get(Name);
+  if (IdResolver.begin(DN) == IdResolver.end())
+    PushOnScopeChains(Context.buildImplicitTypedef(T, Name), TUScope);
+}
+
 void Sema::Initialize() {
   // Tell the AST consumer about this Sema object.
   Consumer.Initialize(Context);
@@ -134,7 +152,7 @@
     ExternalSema->InitializeSema(*this);
 
   // Initialize predefined 128-bit integer types, if needed.
-  if (PP.getTargetInfo().hasInt128Type()) {
+  if (Context.getTargetInfo().hasInt128Type()) {
     // If either of the 128-bit integer types are unavailable to name lookup,
     // define them now.
     DeclarationName Int128 = &Context.Idents.get("__int128_t");
@@ -172,20 +190,36 @@
       PushOnScopeChains(Context.getObjCProtocolDecl(), TUScope);
   }
 
+  // Initialize Microsoft "predefined C++ types".
+  if (PP.getLangOpts().MSVCCompat && PP.getLangOpts().CPlusPlus) {
+    if (IdResolver.begin(&Context.Idents.get("type_info")) == IdResolver.end())
+      PushOnScopeChains(Context.buildImplicitRecord("type_info", TTK_Class),
+                        TUScope);
+
+    addImplicitTypedef("size_t", Context.getSizeType());
+  }
+
+  // Initialize predefined OpenCL types.
+  if (PP.getLangOpts().OpenCL) {
+    addImplicitTypedef("image1d_t", Context.OCLImage1dTy);
+    addImplicitTypedef("image1d_array_t", Context.OCLImage1dArrayTy);
+    addImplicitTypedef("image1d_buffer_t", Context.OCLImage1dBufferTy);
+    addImplicitTypedef("image2d_t", Context.OCLImage2dTy);
+    addImplicitTypedef("image2d_array_t", Context.OCLImage2dArrayTy);
+    addImplicitTypedef("image3d_t", Context.OCLImage3dTy);
+    addImplicitTypedef("sampler_t", Context.OCLSamplerTy);
+    addImplicitTypedef("event_t", Context.OCLEventTy);
+  }
+
   DeclarationName BuiltinVaList = &Context.Idents.get("__builtin_va_list");
   if (IdResolver.begin(BuiltinVaList) == IdResolver.end())
     PushOnScopeChains(Context.getBuiltinVaListDecl(), TUScope);
 }
 
 Sema::~Sema() {
-  for (LateParsedTemplateMapT::iterator I = LateParsedTemplateMap.begin(),
-                                        E = LateParsedTemplateMap.end();
-       I != E; ++I)
-    delete I->second;
+  llvm::DeleteContainerSeconds(LateParsedTemplateMap);
   if (PackContext) FreePackedContext();
   if (VisContext) FreeVisContext();
-  delete TheTargetAttributesSema;
-  MSStructPragmaOn = false;
   // Kill all the active scopes.
   for (unsigned I = 1, E = FunctionScopes.size(); I != E; ++I)
     delete FunctionScopes[I];
@@ -230,7 +264,7 @@
   // If the function is already unavailable, it's not an error.
   if (fn->hasAttr<UnavailableAttr>()) return true;
 
-  fn->addAttr(new (Context) UnavailableAttr(loc, Context, msg));
+  fn->addAttr(UnavailableAttr::CreateImplicit(Context, msg, loc));
   return true;
 }
 
@@ -279,7 +313,8 @@
   if (VK == VK_RValue && !E->isRValue()) {
     switch (Kind) {
     default:
-      assert(0 && "can't implicitly cast lvalue to rvalue with this cast kind");
+      llvm_unreachable("can't implicitly cast lvalue to rvalue with this cast "
+                       "kind");
     case CK_LValueToRValue:
     case CK_ArrayToPointerDecay:
     case CK_FunctionToPointerDecay:
@@ -294,7 +329,7 @@
   QualType TypeTy = Context.getCanonicalType(Ty);
 
   if (ExprTy == TypeTy)
-    return Owned(E);
+    return E;
 
   // If this is a derived-to-base cast to a through a virtual base, we
   // need a vtable.
@@ -312,11 +347,11 @@
     if (ImpCast->getCastKind() == Kind && (!BasePath || BasePath->empty())) {
       ImpCast->setType(Ty);
       ImpCast->setValueKind(VK);
-      return Owned(E);
+      return E;
     }
   }
 
-  return Owned(ImplicitCastExpr::Create(Context, Ty, Kind, E, BasePath, VK));
+  return ImplicitCastExpr::Create(Context, Ty, Kind, E, BasePath, VK);
 }
 
 /// ScalarTypeToBooleanCastKind - Returns the cast kind corresponding
@@ -384,25 +419,6 @@
   return false;
 }
 
-namespace {
-  struct SortUndefinedButUsed {
-    const SourceManager &SM;
-    explicit SortUndefinedButUsed(SourceManager &SM) : SM(SM) {}
-
-    bool operator()(const std::pair<NamedDecl *, SourceLocation> &l,
-                    const std::pair<NamedDecl *, SourceLocation> &r) const {
-      if (l.second.isValid() && !r.second.isValid())
-        return true;
-      if (!l.second.isValid() && r.second.isValid())
-        return false;
-      if (l.second != r.second)
-        return SM.isBeforeInTranslationUnit(l.second, r.second);
-      return SM.isBeforeInTranslationUnit(l.first->getLocation(),
-                                          r.first->getLocation());
-    }
-  };
-}
-
 /// Obtains a sorted list of functions that are undefined but ODR-used.
 void Sema::getUndefinedButUsed(
     SmallVectorImpl<std::pair<NamedDecl *, SourceLocation> > &Undefined) {
@@ -435,8 +451,19 @@
 
   // Sort (in order of use site) so that we're not dependent on the iteration
   // order through an llvm::DenseMap.
+  SourceManager &SM = Context.getSourceManager();
   std::sort(Undefined.begin(), Undefined.end(),
-            SortUndefinedButUsed(Context.getSourceManager()));
+            [&SM](const std::pair<NamedDecl *, SourceLocation> &l,
+                  const std::pair<NamedDecl *, SourceLocation> &r) {
+    if (l.second.isValid() && !r.second.isValid())
+      return true;
+    if (!l.second.isValid() && r.second.isValid())
+      return false;
+    if (l.second != r.second)
+      return SM.isBeforeInTranslationUnit(l.second, r.second);
+    return SM.isBeforeInTranslationUnit(l.first->getLocation(),
+                                        r.first->getLocation());
+  });
 }
 
 /// checkUndefinedButUsed - Check for undefined objects with internal linkage
@@ -453,6 +480,13 @@
          I = Undefined.begin(), E = Undefined.end(); I != E; ++I) {
     NamedDecl *ND = I->first;
 
+    if (ND->hasAttr<DLLImportAttr>() || ND->hasAttr<DLLExportAttr>()) {
+      // An exported function will always be emitted when defined, so even if
+      // the function is inline, it doesn't have to be emitted in this TU. An
+      // imported function implies that it has been exported somewhere else.
+      continue;
+    }
+
     if (!ND->isExternallyVisible()) {
       S.Diag(ND->getLocation(), diag::warn_undefined_internal)
         << isa<VarDecl>(ND) << ND;
@@ -561,7 +595,7 @@
 /// translation unit when EOF is reached and all but the top-level scope is
 /// popped.
 void Sema::ActOnEndOfTranslationUnit() {
-  assert(DelayedDiagnostics.getCurrentPool() == NULL
+  assert(DelayedDiagnostics.getCurrentPool() == nullptr
          && "reached end of translation unit with a pool attached?");
 
   // If code completion is enabled, don't perform any end-of-translation-unit
@@ -582,8 +616,9 @@
          I != E; ++I) {
       assert(!(*I)->isDependentType() &&
              "Should not see dependent types here!");
-      if (const CXXMethodDecl *KeyFunction = Context.getCurrentKeyFunction(*I)) {
-        const FunctionDecl *Definition = 0;
+      if (const CXXMethodDecl *KeyFunction =
+              Context.getCurrentKeyFunction(*I)) {
+        const FunctionDecl *Definition = nullptr;
         if (KeyFunction->hasBody(Definition))
           MarkVTableUsed(Definition->getLocation(), *I, true);
       }
@@ -603,7 +638,15 @@
     // so it will find some names that are not required to be found. This is
     // valid, but we could do better by diagnosing if an instantiation uses a
     // name that was not visible at its first point of instantiation.
+    if (ExternalSource) {
+      // Load pending instantiations from the external source.
+      SmallVector<PendingImplicitInstantiation, 4> Pending;
+      ExternalSource->ReadPendingInstantiations(Pending);
+      PendingInstantiations.insert(PendingInstantiations.begin(),
+                                   Pending.begin(), Pending.end());
+    }
     PerformPendingInstantiations();
+
     CheckDelayedMemberExceptionSpecs();
   }
 
@@ -614,14 +657,14 @@
 
   // Remove file scoped decls that turned out to be used.
   UnusedFileScopedDecls.erase(
-      std::remove_if(UnusedFileScopedDecls.begin(0, true),
+      std::remove_if(UnusedFileScopedDecls.begin(nullptr, true),
                      UnusedFileScopedDecls.end(),
                      std::bind1st(std::ptr_fun(ShouldRemoveFromUnused), this)),
       UnusedFileScopedDecls.end());
 
   if (TUKind == TU_Prefix) {
     // Translation unit prefixes don't need any of the checking below.
-    TUScope = 0;
+    TUScope = nullptr;
     return;
   }
 
@@ -639,9 +682,7 @@
   }
 
   if (LangOpts.CPlusPlus11 &&
-      Diags.getDiagnosticLevel(diag::warn_delegating_ctor_cycle,
-                               SourceLocation())
-        != DiagnosticsEngine::Ignored)
+      !Diags.isIgnored(diag::warn_delegating_ctor_cycle, SourceLocation()))
     CheckDelegatingCtorCycles();
 
   if (TUKind == TU_Module) {
@@ -673,7 +714,7 @@
     }
 
     // Modules don't need any of the checking below.
-    TUScope = 0;
+    TUScope = nullptr;
     return;
   }
 
@@ -699,7 +740,7 @@
     // If the tentative definition was completed, getActingDefinition() returns
     // null. If we've already seen this variable before, insert()'s second
     // return value is false.
-    if (VD == 0 || VD->isInvalidDecl() || !Seen.insert(VD))
+    if (!VD || VD->isInvalidDecl() || !Seen.insert(VD))
       continue;
 
     if (const IncompleteArrayType *ArrayT
@@ -781,9 +822,7 @@
     checkUndefinedButUsed(*this);
   }
 
-  if (Diags.getDiagnosticLevel(diag::warn_unused_private_field,
-                               SourceLocation())
-        != DiagnosticsEngine::Ignored) {
+  if (!Diags.isIgnored(diag::warn_unused_private_field, SourceLocation())) {
     RecordCompleteMap RecordsComplete;
     RecordCompleteMap MNCComplete;
     for (NamedDeclSetType::iterator I = UnusedPrivateFields.begin(),
@@ -804,7 +843,7 @@
   assert(ParsingInitForAutoVars.empty() &&
          "Didn't unmark var as having its initializer parsed");
 
-  TUScope = 0;
+  TUScope = nullptr;
 }
 
 
@@ -848,7 +887,7 @@
   DeclContext *DC = getFunctionLevelDeclContext();
   if (isa<ObjCMethodDecl>(DC) || isa<FunctionDecl>(DC))
     return cast<NamedDecl>(DC);
-  return 0;
+  return nullptr;
 }
 
 void Sema::EmitCurrentDiagnostic(unsigned DiagID) {
@@ -996,7 +1035,7 @@
 Scope *Sema::getScopeForContext(DeclContext *Ctx) {
 
   if (!Ctx)
-    return 0;
+    return nullptr;
 
   Ctx = Ctx->getPrimaryContext();
   for (Scope *S = getCurScope(); S; S = S->getParent()) {
@@ -1008,7 +1047,7 @@
           return S;
   }
 
-  return 0;
+  return nullptr;
 }
 
 /// \brief Enter a new function scope
@@ -1052,19 +1091,12 @@
   // Issue any analysis-based warnings.
   if (WP && D)
     AnalysisWarnings.IssueWarnings(*WP, Scope, D, blkExpr);
-  else {
-    for (SmallVectorImpl<sema::PossiblyUnreachableDiag>::iterator
-         i = Scope->PossiblyUnreachableDiags.begin(),
-         e = Scope->PossiblyUnreachableDiags.end();
-         i != e; ++i) {
-      const sema::PossiblyUnreachableDiag &D = *i;
-      Diag(D.Loc, D.PD);
-    }
-  }
+  else
+    for (const auto &PUD : Scope->PossiblyUnreachableDiags)
+      Diag(PUD.Loc, PUD.PD);
 
-  if (FunctionScopes.back() != Scope) {
+  if (FunctionScopes.back() != Scope)
     delete Scope;
-  }
 }
 
 void Sema::PushCompoundScope() {
@@ -1086,25 +1118,41 @@
 
 BlockScopeInfo *Sema::getCurBlock() {
   if (FunctionScopes.empty())
-    return 0;
+    return nullptr;
 
-  return dyn_cast<BlockScopeInfo>(FunctionScopes.back());
+  auto CurBSI = dyn_cast<BlockScopeInfo>(FunctionScopes.back());
+  if (CurBSI && CurBSI->TheDecl &&
+      !CurBSI->TheDecl->Encloses(CurContext)) {
+    // We have switched contexts due to template instantiation.
+    assert(!ActiveTemplateInstantiations.empty());
+    return nullptr;
+  }
+
+  return CurBSI;
 }
 
 LambdaScopeInfo *Sema::getCurLambda() {
   if (FunctionScopes.empty())
-    return 0;
+    return nullptr;
 
-  return dyn_cast<LambdaScopeInfo>(FunctionScopes.back());
+  auto CurLSI = dyn_cast<LambdaScopeInfo>(FunctionScopes.back());
+  if (CurLSI && CurLSI->Lambda &&
+      !CurLSI->Lambda->Encloses(CurContext)) {
+    // We have switched contexts due to template instantiation.
+    assert(!ActiveTemplateInstantiations.empty());
+    return nullptr;
+  }
+
+  return CurLSI;
 }
 // We have a generic lambda if we parsed auto parameters, or we have 
 // an associated template parameter list.
 LambdaScopeInfo *Sema::getCurGenericLambda() {
   if (LambdaScopeInfo *LSI =  getCurLambda()) {
     return (LSI->AutoTemplateParams.size() ||
-                    LSI->GLTemplateParameterList) ? LSI : 0;
+                    LSI->GLTemplateParameterList) ? LSI : nullptr;
   }
-  return 0;
+  return nullptr;
 }
 
 
@@ -1182,7 +1230,7 @@
   ZeroArgCallReturnTy = QualType();
   OverloadSet.clear();
 
-  const OverloadExpr *Overloads = NULL;
+  const OverloadExpr *Overloads = nullptr;
   bool IsMemExpr = false;
   if (E.getType() == Context.OverloadTy) {
     OverloadExpr::FindResult FR = OverloadExpr::find(const_cast<Expr*>(&E));
@@ -1215,7 +1263,7 @@
             ZeroArgCallReturnTy = QualType();
             Ambiguous = true;
           } else
-            ZeroArgCallReturnTy = OverloadDecl->getResultType();
+            ZeroArgCallReturnTy = OverloadDecl->getReturnType();
         }
       }
     }
@@ -1231,8 +1279,8 @@
   if (IsMemExpr && !E.isTypeDependent()) {
     bool Suppress = getDiagnostics().getSuppressAllDiagnostics();
     getDiagnostics().setSuppressAllDiagnostics(true);
-    ExprResult R = BuildCallToMemberFunction(NULL, &E, SourceLocation(), None,
-                                             SourceLocation());
+    ExprResult R = BuildCallToMemberFunction(nullptr, &E, SourceLocation(),
+                                             None, SourceLocation());
     getDiagnostics().setSuppressAllDiagnostics(Suppress);
     if (R.isUsable()) {
       ZeroArgCallReturnTy = R.get()->getType();
@@ -1244,7 +1292,7 @@
   if (const DeclRefExpr *DeclRef = dyn_cast<DeclRefExpr>(E.IgnoreParens())) {
     if (const FunctionDecl *Fun = dyn_cast<FunctionDecl>(DeclRef->getDecl())) {
       if (Fun->getMinRequiredArguments() == 0)
-        ZeroArgCallReturnTy = Fun->getResultType();
+        ZeroArgCallReturnTy = Fun->getReturnType();
       return true;
     }
   }
@@ -1252,7 +1300,7 @@
   // We don't have an expression that's convenient to get a FunctionDecl from,
   // but we can at least check if the type is "function of 0 arguments".
   QualType ExprTy = E.getType();
-  const FunctionType *FunTy = NULL;
+  const FunctionType *FunTy = nullptr;
   QualType PointeeTy = ExprTy->getPointeeType();
   if (!PointeeTy.isNull())
     FunTy = PointeeTy->getAs<FunctionType>();
@@ -1261,8 +1309,8 @@
 
   if (const FunctionProtoType *FPT =
       dyn_cast_or_null<FunctionProtoType>(FunTy)) {
-    if (FPT->getNumArgs() == 0)
-      ZeroArgCallReturnTy = FunTy->getResultType();
+    if (FPT->getNumParams() == 0)
+      ZeroArgCallReturnTy = FunTy->getReturnType();
     return true;
   }
   return false;
@@ -1313,7 +1361,7 @@
   for (OverloadExpr::decls_iterator It = Overloads.begin(),
          DeclsEnd = Overloads.end(); It != DeclsEnd; ++It) {
     const FunctionDecl *OverloadDecl = cast<FunctionDecl>(*It);
-    QualType OverloadResultTy = OverloadDecl->getResultType();
+    QualType OverloadResultTy = OverloadDecl->getReturnType();
     if (IsPlausibleResult(OverloadResultTy))
       PlausibleOverloads.addDecl(It.getDecl());
   }
@@ -1357,7 +1405,7 @@
 
     // FIXME: Try this before emitting the fixit, and suppress diagnostics
     // while doing so.
-    E = ActOnCallExpr(0, E.take(), Range.getEnd(), None,
+    E = ActOnCallExpr(nullptr, E.get(), Range.getEnd(), None,
                       Range.getEnd().getLocWithOffset(1));
     return true;
   }
@@ -1392,7 +1440,7 @@
 
 CapturedRegionScopeInfo *Sema::getCurCapturedRegion() {
   if (FunctionScopes.empty())
-    return 0;
+    return nullptr;
 
   return dyn_cast<CapturedRegionScopeInfo>(FunctionScopes.back());
 }
diff --git a/lib/Sema/SemaAccess.cpp b/lib/Sema/SemaAccess.cpp
index 974f3b4..ffdb0aa 100644
--- a/lib/Sema/SemaAccess.cpp
+++ b/lib/Sema/SemaAccess.cpp
@@ -78,7 +78,7 @@
 
 namespace {
 struct EffectiveContext {
-  EffectiveContext() : Inner(0), Dependent(false) {}
+  EffectiveContext() : Inner(nullptr), Dependent(false) {}
 
   explicit EffectiveContext(DeclContext *DC)
     : Inner(DC),
@@ -209,7 +209,8 @@
 
     CalculatedInstanceContext = true;
     DeclContext *IC = S.computeDeclContext(getBaseObjectType());
-    InstanceContext = (IC ? cast<CXXRecordDecl>(IC)->getCanonicalDecl() : 0);
+    InstanceContext = (IC ? cast<CXXRecordDecl>(IC)->getCanonicalDecl()
+                          : nullptr);
     return InstanceContext;
   }
 
@@ -232,7 +233,7 @@
                           !getBaseObjectType().isNull() &&
                           getTargetDecl()->isCXXInstanceMember());
     CalculatedInstanceContext = false;
-    InstanceContext = 0;
+    InstanceContext = nullptr;
 
     if (isMemberAccess())
       DeclaringClass = FindDeclaringClass(getTargetDecl());
@@ -288,12 +289,10 @@
     if (Derived->isDependentContext() && !Derived->hasDefinition())
       return AR_dependent;
     
-    for (CXXRecordDecl::base_class_const_iterator
-           I = Derived->bases_begin(), E = Derived->bases_end(); I != E; ++I) {
-
+    for (const auto &I : Derived->bases()) {
       const CXXRecordDecl *RD;
 
-      QualType T = I->getType();
+      QualType T = I.getType();
       if (const RecordType *RT = T->getAs<RecordType>()) {
         RD = cast<CXXRecordDecl>(RT->getDecl());
       } else if (const InjectedClassNameType *IT
@@ -376,18 +375,16 @@
   if (FriendTy.getQualifiers() != ContextTy.getQualifiers())
     return false;
 
-  if (FriendTy->getNumArgs() != ContextTy->getNumArgs())
+  if (FriendTy->getNumParams() != ContextTy->getNumParams())
     return false;
 
-  if (!MightInstantiateTo(S,
-                          ContextTy->getResultType(),
-                          FriendTy->getResultType()))
+  if (!MightInstantiateTo(S, ContextTy->getReturnType(),
+                          FriendTy->getReturnType()))
     return false;
 
-  for (unsigned I = 0, E = FriendTy->getNumArgs(); I != E; ++I)
-    if (!MightInstantiateTo(S,
-                            ContextTy->getArgType(I),
-                            FriendTy->getArgType(I)))
+  for (unsigned I = 0, E = FriendTy->getNumParams(); I != E; ++I)
+    if (!MightInstantiateTo(S, ContextTy->getParamType(I),
+                            FriendTy->getParamType(I)))
       return false;
 
   return true;
@@ -575,10 +572,7 @@
   AccessResult OnFailure = AR_inaccessible;
 
   // Okay, check friends.
-  for (CXXRecordDecl::friend_iterator I = Class->friend_begin(),
-         E = Class->friend_end(); I != E; ++I) {
-    FriendDecl *Friend = *I;
-
+  for (auto *Friend : Class->friends()) {
     switch (MatchesFriend(S, EC, Friend)) {
     case AR_accessible:
       return AR_accessible;
@@ -648,18 +642,16 @@
       EverDependent = true;
 
     // Recurse into the base classes.
-    for (CXXRecordDecl::base_class_const_iterator
-           I = Cur->bases_begin(), E = Cur->bases_end(); I != E; ++I) {
-
+    for (const auto &I : Cur->bases()) {
       // If this is private inheritance, then a public member of the
       // base will not have any access in classes derived from Cur.
       unsigned BasePrivateDepth = PrivateDepth;
-      if (I->getAccessSpecifier() == AS_private)
+      if (I.getAccessSpecifier() == AS_private)
         BasePrivateDepth = CurPath.size() - 1;
 
       const CXXRecordDecl *RD;
 
-      QualType T = I->getType();
+      QualType T = I.getType();
       if (const RecordType *RT = T->getAs<RecordType>()) {
         RD = cast<CXXRecordDecl>(RT->getDecl());
       } else if (const InjectedClassNameType *IT
@@ -718,7 +710,7 @@
 static AccessResult GetProtectedFriendKind(Sema &S, const EffectiveContext &EC,
                                            const CXXRecordDecl *InstanceContext,
                                            const CXXRecordDecl *NamingClass) {
-  assert(InstanceContext == 0 ||
+  assert(InstanceContext == nullptr ||
          InstanceContext->getCanonicalDecl() == InstanceContext);
   assert(NamingClass->getCanonicalDecl() == NamingClass);
 
@@ -797,7 +789,7 @@
         // Emulate a MSVC bug where the creation of pointer-to-member
         // to protected member of base class is allowed but only from
         // static member functions.
-        if (S.getLangOpts().MicrosoftMode && !EC.Functions.empty())
+        if (S.getLangOpts().MSVCCompat && !EC.Functions.empty())
           if (CXXMethodDecl* MD = dyn_cast<CXXMethodDecl>(EC.Functions.front()))
             if (MD->isStatic()) return AR_accessible;
 
@@ -851,7 +843,7 @@
   // and instead rely on whether any potential P is a friend.
   if (Access == AS_protected && Target.isInstanceMember()) {
     // Compute the instance context if possible.
-    const CXXRecordDecl *InstanceContext = 0;
+    const CXXRecordDecl *InstanceContext = nullptr;
     if (Target.hasInstanceContext()) {
       InstanceContext = Target.resolveInstanceContext(S);
       if (!InstanceContext) return AR_dependent;
@@ -946,7 +938,7 @@
   assert(isDerived && "derived class not actually derived from base");
   (void) isDerived;
 
-  CXXBasePath *BestPath = 0;
+  CXXBasePath *BestPath = nullptr;
 
   assert(FinalAccess != AS_none && "forbidden access after declaring class");
 
@@ -995,7 +987,7 @@
 
     // Note that we modify the path's Access field to the
     // friend-modified access.
-    if (BestPath == 0 || PathAccess < BestPath->Access) {
+    if (BestPath == nullptr || PathAccess < BestPath->Access) {
       BestPath = &*PI;
       BestPath->Access = PathAccess;
 
@@ -1013,7 +1005,7 @@
   // We didn't find a public path, but at least one path was subject
   // to dependent friendship, so delay the check.
   if (AnyDependent)
-    return 0;
+    return nullptr;
 
   return BestPath;
 }
@@ -1082,15 +1074,15 @@
         (isa<FunctionTemplateDecl>(D) &&
          isa<CXXConstructorDecl>(
                 cast<FunctionTemplateDecl>(D)->getTemplatedDecl()))) {
-      S.Diag(D->getLocation(), diag::note_access_protected_restricted_ctordtor)
-        << isa<CXXDestructorDecl>(D);
-      return true;
+      return S.Diag(D->getLocation(),
+                    diag::note_access_protected_restricted_ctordtor)
+             << isa<CXXDestructorDecl>(D->getAsFunction());
     }
 
     // Otherwise, use the generic diagnostic.
-    S.Diag(D->getLocation(), diag::note_access_protected_restricted_object)
-      << S.Context.getTypeDeclType(ECRecord);
-    return true;
+    return S.Diag(D->getLocation(),
+                  diag::note_access_protected_restricted_object)
+           << S.Context.getTypeDeclType(ECRecord);
   }
 
   return false;
@@ -1110,7 +1102,7 @@
 
   // Find an original declaration.
   while (D->isOutOfLine()) {
-    NamedDecl *PrevDecl = 0;
+    NamedDecl *PrevDecl = nullptr;
     if (VarDecl *VD = dyn_cast<VarDecl>(D))
       PrevDecl = VD->getPreviousDecl();
     else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
@@ -1140,11 +1132,9 @@
   // Check whether there's an AccessSpecDecl preceding this in the
   // chain of the DeclContext.
   bool isImplicit = true;
-  for (CXXRecordDecl::decl_iterator
-         I = DeclaringClass->decls_begin(), E = DeclaringClass->decls_end();
-       I != E; ++I) {
-    if (*I == ImmediateChild) break;
-    if (isa<AccessSpecDecl>(*I)) {
+  for (const auto *I : DeclaringClass->decls()) {
+    if (I == ImmediateChild) break;
+    if (isa<AccessSpecDecl>(I)) {
       isImplicit = false;
       break;
     }
@@ -1223,7 +1213,7 @@
     case AR_accessible:
       accessSoFar = AS_public;
       entity.suppressInstanceContext();
-      constrainingBase = 0;
+      constrainingBase = nullptr;
       break;
     case AR_dependent:
       llvm_unreachable("cannot diagnose dependent access");
@@ -1262,7 +1252,8 @@
     << (base->getAccessSpecifierAsWritten() == AS_none);
 
   if (entity.isMemberAccess())
-    S.Diag(entity.getTargetDecl()->getLocation(), diag::note_field_decl);
+    S.Diag(entity.getTargetDecl()->getLocation(),
+           diag::note_member_declared_at);
 }
 
 static void DiagnoseBadAccess(Sema &S, SourceLocation Loc,
@@ -1270,7 +1261,7 @@
                               AccessTarget &Entity) {
   const CXXRecordDecl *NamingClass = Entity.getNamingClass();
   const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
-  NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() : 0);
+  NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() : nullptr);
 
   S.Diag(Loc, Entity.getDiag())
     << (Entity.getAccess() == AS_protected)
@@ -1422,16 +1413,15 @@
                                          AccessTarget &Entity) {
   assert(Entity.getAccess() != AS_public && "called for public access!");
 
-  if (S.getLangOpts().MicrosoftMode &&
-      IsMicrosoftUsingDeclarationAccessBug(S, Loc, Entity))
-    return AR_accessible;
-
   switch (IsAccessible(S, EC, Entity)) {
   case AR_dependent:
     DelayDependentAccess(S, EC, Loc, Entity);
     return AR_dependent;
 
   case AR_inaccessible:
+    if (S.getLangOpts().MSVCCompat &&
+        IsMicrosoftUsingDeclarationAccessBug(S, Loc, Entity))
+      return AR_accessible;
     if (!Entity.isQuiet())
       DiagnoseBadAccess(S, Loc, EC, Entity);
     return AR_inaccessible;
@@ -1482,11 +1472,10 @@
   // However, this does not apply to local extern declarations.
 
   DeclContext *DC = D->getDeclContext();
-  if (FunctionDecl *FN = dyn_cast<FunctionDecl>(D)) {
-    if (D->getLexicalDeclContext()->isFunctionOrMethod())
-      DC = D->getLexicalDeclContext();
-    else
-      DC = FN;
+  if (D->isLocalExternDecl()) {
+    DC = D->getLexicalDeclContext();
+  } else if (FunctionDecl *FN = dyn_cast<FunctionDecl>(D)) {
+    DC = FN;
   } else if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D)) {
     DC = cast<DeclContext>(TD->getTemplatedDecl());
   }
@@ -1650,9 +1639,9 @@
   }
 
   case InitializedEntity::EK_LambdaCapture: {
-    const VarDecl *Var = Entity.getCapturedVar();
+    StringRef VarName = Entity.getCapturedVarName();
     PD = PDiag(diag::err_access_lambda_capture);
-    PD << Var->getName() << Entity.getType() << getSpecialMember(Constructor);
+    PD << VarName << Entity.getType() << getSpecialMember(Constructor);
     break;
   }
 
@@ -1750,10 +1739,7 @@
 
 /// Checks access to the target of a friend declaration.
 Sema::AccessResult Sema::CheckFriendAccess(NamedDecl *target) {
-  assert(isa<CXXMethodDecl>(target) ||
-         (isa<FunctionTemplateDecl>(target) &&
-          isa<CXXMethodDecl>(cast<FunctionTemplateDecl>(target)
-                               ->getTemplatedDecl())));
+  assert(isa<CXXMethodDecl>(target->getAsFunction()));
 
   // Friendship lookup is a redeclaration lookup, so there's never an
   // inheritance path modifying access.
@@ -1762,10 +1748,7 @@
   if (!getLangOpts().AccessControl || access == AS_public)
     return AR_accessible;
 
-  CXXMethodDecl *method = dyn_cast<CXXMethodDecl>(target);
-  if (!method)
-    method = cast<CXXMethodDecl>(
-                     cast<FunctionTemplateDecl>(target)->getTemplatedDecl());
+  CXXMethodDecl *method = cast<CXXMethodDecl>(target->getAsFunction());
   assert(method->getQualifier());
 
   AccessTarget entity(Context, AccessTarget::Member,
@@ -1891,7 +1874,7 @@
 
     // If we are inside a class or category implementation, determine the
     // interface we're in.
-    ObjCInterfaceDecl *ClassOfMethodDecl = 0;
+    ObjCInterfaceDecl *ClassOfMethodDecl = nullptr;
     if (ObjCMethodDecl *MD = getCurMethodDecl())
       ClassOfMethodDecl =  MD->getClassInterface();
     else if (FunctionDecl *FD = getCurFunctionDecl()) {
diff --git a/lib/Sema/SemaAttr.cpp b/lib/Sema/SemaAttr.cpp
index 8f9ab32..a7d606d 100644
--- a/lib/Sema/SemaAttr.cpp
+++ b/lib/Sema/SemaAttr.cpp
@@ -109,7 +109,7 @@
 /// FreePackedContext - Deallocate and null out PackContext.
 void Sema::FreePackedContext() {
   delete static_cast<PragmaPackStack*>(PackContext);
-  PackContext = 0;
+  PackContext = nullptr;
 }
 
 void Sema::AddAlignmentAttributesForRecord(RecordDecl *RD) {
@@ -122,23 +122,28 @@
   // Otherwise, check to see if we need a max field alignment attribute.
   if (unsigned Alignment = Stack->getAlignment()) {
     if (Alignment == PackStackEntry::kMac68kAlignmentSentinel)
-      RD->addAttr(::new (Context) AlignMac68kAttr(SourceLocation(), Context));
+      RD->addAttr(AlignMac68kAttr::CreateImplicit(Context));
     else
-      RD->addAttr(::new (Context) MaxFieldAlignmentAttr(SourceLocation(),
-                                                        Context,
+      RD->addAttr(MaxFieldAlignmentAttr::CreateImplicit(Context,
                                                         Alignment * 8));
   }
 }
 
 void Sema::AddMsStructLayoutForRecord(RecordDecl *RD) {
-  if (!MSStructPragmaOn)
-    return;
-  RD->addAttr(::new (Context) MsStructAttr(SourceLocation(), Context));
+  if (MSStructPragmaOn)
+    RD->addAttr(MsStructAttr::CreateImplicit(Context));
+
+  // FIXME: We should merge AddAlignmentAttributesForRecord with
+  // AddMsStructLayoutForRecord into AddPragmaAttributesForRecord, which takes
+  // all active pragmas and applies them as attributes to class definitions.
+  if (VtorDispModeStack.back() != getLangOpts().VtorDispMode)
+    RD->addAttr(
+        MSVtorDispAttr::CreateImplicit(Context, VtorDispModeStack.back()));
 }
 
 void Sema::ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind,
                                    SourceLocation PragmaLoc) {
-  if (PackContext == 0)
+  if (!PackContext)
     PackContext = new PragmaPackStack();
 
   PragmaPackStack *Context = static_cast<PragmaPackStack*>(PackContext);
@@ -150,31 +155,31 @@
   case POAK_Native:
   case POAK_Power:
   case POAK_Natural:
-    Context->push(0);
+    Context->push(nullptr);
     Context->setAlignment(0);
     break;
 
     // Note that '#pragma options align=packed' is not equivalent to attribute
     // packed, it has a different precedence relative to attribute aligned.
   case POAK_Packed:
-    Context->push(0);
+    Context->push(nullptr);
     Context->setAlignment(1);
     break;
 
   case POAK_Mac68k:
     // Check if the target supports this.
-    if (!PP.getTargetInfo().hasAlignMac68kSupport()) {
+    if (!this->Context.getTargetInfo().hasAlignMac68kSupport()) {
       Diag(PragmaLoc, diag::err_pragma_options_align_mac68k_target_unsupported);
       return;
     }
-    Context->push(0);
+    Context->push(nullptr);
     Context->setAlignment(PackStackEntry::kMac68kAlignmentSentinel);
     break;
 
   case POAK_Reset:
     // Reset just pops the top of the stack, or resets the current alignment to
     // default.
-    if (!Context->pop(0, /*IsReset=*/true)) {
+    if (!Context->pop(nullptr, /*IsReset=*/true)) {
       Diag(PragmaLoc, diag::warn_pragma_options_align_reset_failed)
         << "stack empty";
     }
@@ -206,7 +211,7 @@
     AlignmentVal = (unsigned) Val.getZExtValue();
   }
 
-  if (PackContext == 0)
+  if (!PackContext)
     PackContext = new PragmaPackStack();
 
   PragmaPackStack *Context = static_cast<PragmaPackStack*>(PackContext);
@@ -247,8 +252,8 @@
       // If a name was specified then failure indicates the name
       // wasn't found. Otherwise failure indicates the stack was
       // empty.
-      Diag(PragmaLoc, diag::warn_pragma_pack_pop_failed)
-        << (Name ? "no record matching name" : "stack empty");
+      Diag(PragmaLoc, diag::warn_pragma_pop_failed)
+          << "pack" << (Name ? "no record matching name" : "stack empty");
 
       // FIXME: Warn about popping named records as MSVC does.
     } else {
@@ -288,12 +293,159 @@
   Consumer.HandleDetectMismatch(Name, Value);
 }
 
+void Sema::ActOnPragmaMSPointersToMembers(
+    LangOptions::PragmaMSPointersToMembersKind RepresentationMethod,
+    SourceLocation PragmaLoc) {
+  MSPointerToMemberRepresentationMethod = RepresentationMethod;
+  ImplicitMSInheritanceAttrLoc = PragmaLoc;
+}
+
+void Sema::ActOnPragmaMSVtorDisp(PragmaVtorDispKind Kind,
+                                 SourceLocation PragmaLoc,
+                                 MSVtorDispAttr::Mode Mode) {
+  switch (Kind) {
+  case PVDK_Set:
+    VtorDispModeStack.back() = Mode;
+    break;
+  case PVDK_Push:
+    VtorDispModeStack.push_back(Mode);
+    break;
+  case PVDK_Reset:
+    VtorDispModeStack.clear();
+    VtorDispModeStack.push_back(MSVtorDispAttr::Mode(LangOpts.VtorDispMode));
+    break;
+  case PVDK_Pop:
+    VtorDispModeStack.pop_back();
+    if (VtorDispModeStack.empty()) {
+      Diag(PragmaLoc, diag::warn_pragma_pop_failed) << "vtordisp"
+                                                    << "stack empty";
+      VtorDispModeStack.push_back(MSVtorDispAttr::Mode(LangOpts.VtorDispMode));
+    }
+    break;
+  }
+}
+
+template<typename ValueType>
+void Sema::PragmaStack<ValueType>::Act(SourceLocation PragmaLocation,
+                                       PragmaMsStackAction Action,
+                                       llvm::StringRef StackSlotLabel,
+                                       ValueType Value) {
+  if (Action == PSK_Reset) {
+    CurrentValue = nullptr;
+    return;
+  }
+  if (Action & PSK_Push)
+    Stack.push_back(Slot(StackSlotLabel, CurrentValue, CurrentPragmaLocation));
+  else if (Action & PSK_Pop) {
+    if (!StackSlotLabel.empty()) {
+      // If we've got a label, try to find it and jump there.
+      auto I = std::find_if(Stack.rbegin(), Stack.rend(),
+        [&](const Slot &x) { return x.StackSlotLabel == StackSlotLabel; });
+      // If we found the label so pop from there.
+      if (I != Stack.rend()) {
+        CurrentValue = I->Value;
+        CurrentPragmaLocation = I->PragmaLocation;
+        Stack.erase(std::prev(I.base()), Stack.end());
+      }
+    } else if (!Stack.empty()) {
+      // We don't have a label, just pop the last entry.
+      CurrentValue = Stack.back().Value;
+      CurrentPragmaLocation = Stack.back().PragmaLocation;
+      Stack.pop_back();
+    }
+  }
+  if (Action & PSK_Set) {
+    CurrentValue = Value;
+    CurrentPragmaLocation = PragmaLocation;
+  }
+}
+
+bool Sema::UnifySection(const StringRef &SectionName,
+                        int SectionFlags,
+                        DeclaratorDecl *Decl) {
+  auto Section = SectionInfos.find(SectionName);
+  if (Section == SectionInfos.end()) {
+    SectionInfos[SectionName] =
+        SectionInfo(Decl, SourceLocation(), SectionFlags);
+    return false;
+  }
+  // A pre-declared section takes precedence w/o diagnostic.
+  if (Section->second.SectionFlags == SectionFlags ||
+      !(Section->second.SectionFlags & PSF_Implicit))
+    return false;
+  auto OtherDecl = Section->second.Decl;
+  Diag(Decl->getLocation(), diag::err_section_conflict)
+      << Decl << OtherDecl;
+  Diag(OtherDecl->getLocation(), diag::note_declared_at)
+      << OtherDecl->getName();
+  if (auto A = Decl->getAttr<SectionAttr>())
+    if (A->isImplicit())
+      Diag(A->getLocation(), diag::note_pragma_entered_here);
+  if (auto A = OtherDecl->getAttr<SectionAttr>())
+    if (A->isImplicit())
+      Diag(A->getLocation(), diag::note_pragma_entered_here);
+  return false;
+}
+
+bool Sema::UnifySection(const StringRef &SectionName,
+                        int SectionFlags,
+                        SourceLocation PragmaSectionLocation) {
+  auto Section = SectionInfos.find(SectionName);
+  if (Section != SectionInfos.end()) {
+    if (Section->second.SectionFlags == SectionFlags)
+      return false;
+    if (!(Section->second.SectionFlags & PSF_Implicit)) {
+      Diag(PragmaSectionLocation, diag::err_section_conflict)
+          << "this" << "a prior #pragma section";
+      Diag(Section->second.PragmaSectionLocation,
+           diag::note_pragma_entered_here);
+      return true;
+    }
+  }
+  SectionInfos[SectionName] =
+      SectionInfo(nullptr, PragmaSectionLocation, SectionFlags);
+  return false;
+}
+
+/// \brief Called on well formed \#pragma bss_seg().
+void Sema::ActOnPragmaMSSeg(SourceLocation PragmaLocation,
+                            PragmaMsStackAction Action,
+                            llvm::StringRef StackSlotLabel,
+                            StringLiteral *SegmentName,
+                            llvm::StringRef PragmaName) {
+  PragmaStack<StringLiteral *> *Stack =
+    llvm::StringSwitch<PragmaStack<StringLiteral *> *>(PragmaName)
+        .Case("data_seg", &DataSegStack)
+        .Case("bss_seg", &BSSSegStack)
+        .Case("const_seg", &ConstSegStack)
+        .Case("code_seg", &CodeSegStack);
+  if (Action & PSK_Pop && Stack->Stack.empty())
+    Diag(PragmaLocation, diag::warn_pragma_pop_failed) << PragmaName
+        << "stack empty";
+  Stack->Act(PragmaLocation, Action, StackSlotLabel, SegmentName);
+}
+
+/// \brief Called on well formed \#pragma bss_seg().
+void Sema::ActOnPragmaMSSection(SourceLocation PragmaLocation,
+                                int SectionFlags, StringLiteral *SegmentName) {
+  UnifySection(SegmentName->getString(), SectionFlags, PragmaLocation);
+}
+
+void Sema::ActOnPragmaMSInitSeg(SourceLocation PragmaLocation,
+                                StringLiteral *SegmentName) {
+  // There's no stack to maintain, so we just have a current section.  When we
+  // see the default section, reset our current section back to null so we stop
+  // tacking on unnecessary attributes.
+  CurInitSeg = SegmentName->getString() == ".CRT$XCU" ? nullptr : SegmentName;
+  CurInitSegLoc = PragmaLocation;
+}
+
 void Sema::ActOnPragmaUnused(const Token &IdTok, Scope *curScope,
                              SourceLocation PragmaLoc) {
 
   IdentifierInfo *Name = IdTok.getIdentifierInfo();
   LookupResult Lookup(*this, Name, IdTok.getLocation(), LookupOrdinaryName);
-  LookupParsedName(Lookup, curScope, NULL, true);
+  LookupParsedName(Lookup, curScope, nullptr, true);
 
   if (Lookup.empty()) {
     Diag(PragmaLoc, diag::warn_pragma_unused_undeclared_var)
@@ -312,7 +464,7 @@
   if (VD->isUsed())
     Diag(PragmaLoc, diag::warn_used_but_marked_unused) << Name;
 
-  VD->addAttr(::new (Context) UnusedAttr(IdTok.getLocation(), Context));
+  VD->addAttr(UnusedAttr::CreateImplicit(Context, IdTok.getLocation()));
 }
 
 void Sema::AddCFAuditedAttribute(Decl *D) {
@@ -324,11 +476,39 @@
       D->hasAttr<CFUnknownTransferAttr>())
     return;
 
-  D->addAttr(::new (Context) CFAuditedTransferAttr(Loc, Context));
+  D->addAttr(CFAuditedTransferAttr::CreateImplicit(Context, Loc));
+}
+
+void Sema::ActOnPragmaOptimize(bool On, SourceLocation PragmaLoc) {
+  if(On)
+    OptimizeOffPragmaLocation = SourceLocation();
+  else
+    OptimizeOffPragmaLocation = PragmaLoc;
+}
+
+void Sema::AddRangeBasedOptnone(FunctionDecl *FD) {
+  // In the future, check other pragmas if they're implemented (e.g. pragma
+  // optimize 0 will probably map to this functionality too).
+  if(OptimizeOffPragmaLocation.isValid())
+    AddOptnoneAttributeIfNoConflicts(FD, OptimizeOffPragmaLocation);
+}
+
+void Sema::AddOptnoneAttributeIfNoConflicts(FunctionDecl *FD, 
+                                            SourceLocation Loc) {
+  // Don't add a conflicting attribute. No diagnostic is needed.
+  if (FD->hasAttr<MinSizeAttr>() || FD->hasAttr<AlwaysInlineAttr>())
+    return;
+
+  // Add attributes only if required. Optnone requires noinline as well, but if
+  // either is already present then don't bother adding them.
+  if (!FD->hasAttr<OptimizeNoneAttr>())
+    FD->addAttr(OptimizeNoneAttr::CreateImplicit(Context, Loc));
+  if (!FD->hasAttr<NoInlineAttr>())
+    FD->addAttr(NoInlineAttr::CreateImplicit(Context, Loc));
 }
 
 typedef std::vector<std::pair<unsigned, SourceLocation> > VisStack;
-enum { NoVisibility = (unsigned) -1 };
+enum : unsigned { NoVisibility = ~0U };
 
 void Sema::AddPushedVisibilityAttribute(Decl *D) {
   if (!VisContext)
@@ -346,13 +526,13 @@
     = (VisibilityAttr::VisibilityType) rawType;
   SourceLocation loc = Stack->back().second;
 
-  D->addAttr(::new (Context) VisibilityAttr(loc, Context, type));
+  D->addAttr(VisibilityAttr::CreateImplicit(Context, type, loc));
 }
 
 /// FreeVisContext - Deallocate and null out VisContext.
 void Sema::FreeVisContext() {
   delete static_cast<VisStack*>(VisContext);
-  VisContext = 0;
+  VisContext = nullptr;
 }
 
 static void PushPragmaVisibility(Sema &S, unsigned type, SourceLocation loc) {
diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp
index 674411e..a70aca2 100644
--- a/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/lib/Sema/SemaCXXScopeSpec.cpp
@@ -29,7 +29,7 @@
 static CXXRecordDecl *getCurrentInstantiationOf(QualType T,
                                                 DeclContext *CurContext) {
   if (T.isNull())
-    return 0;
+    return nullptr;
 
   const Type *Ty = T->getCanonicalTypeInternal().getTypePtr();
   if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
@@ -38,11 +38,11 @@
         Record->isCurrentInstantiation(CurContext))
       return Record;
 
-    return 0;
+    return nullptr;
   } else if (isa<InjectedClassNameType>(Ty))
     return cast<InjectedClassNameType>(Ty)->getDecl();
   else
-    return 0;
+    return nullptr;
 }
 
 /// \brief Compute the DeclContext that is associated with the given type.
@@ -76,7 +76,7 @@
 DeclContext *Sema::computeDeclContext(const CXXScopeSpec &SS,
                                       bool EnteringContext) {
   if (!SS.isSet() || SS.isInvalid())
-    return 0;
+    return nullptr;
 
   NestedNameSpecifier *NNS = SS.getScopeRep();
   if (NNS->isDependent()) {
@@ -88,7 +88,7 @@
     if (EnteringContext) {
       const Type *NNSType = NNS->getAsType();
       if (!NNSType) {
-        return 0;
+        return nullptr;
       }
 
       // Look through type alias templates, per C++0x [temp.dep.type]p1.
@@ -126,7 +126,7 @@
       }
     }
 
-    return 0;
+    return nullptr;
   }
 
   switch (NNS->getKind()) {
@@ -170,7 +170,7 @@
   assert(NNS->isDependent() && "Only dependent nested-name-specifier allowed");
 
   if (!NNS->getAsType())
-    return 0;
+    return nullptr;
 
   QualType T = QualType(NNS->getAsType(), 0);
   return ::getCurrentInstantiationOf(T, CurContext);
@@ -187,7 +187,7 @@
 /// will attempt to instantiate that class template.
 bool Sema::RequireCompleteDeclContext(CXXScopeSpec &SS,
                                       DeclContext *DC) {
-  assert(DC != 0 && "given null context");
+  assert(DC && "given null context");
 
   TagDecl *tag = dyn_cast<TagDecl>(DC);
 
@@ -282,13 +282,13 @@
 /// name lookup.
 NamedDecl *Sema::FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS) {
   if (!S || !NNS)
-    return 0;
+    return nullptr;
 
   while (NNS->getPrefix())
     NNS = NNS->getPrefix();
 
   if (NNS->getKind() != NestedNameSpecifier::Identifier)
-    return 0;
+    return nullptr;
 
   LookupResult Found(*this, NNS->getAsIdentifier(), SourceLocation(),
                      LookupNestedNameSpecifierName);
@@ -296,13 +296,13 @@
   assert(!Found.isAmbiguous() && "Cannot handle ambiguities here yet");
 
   if (!Found.isSingleResult())
-    return 0;
+    return nullptr;
 
   NamedDecl *Result = Found.getFoundDecl();
   if (isAcceptableNestedNameSpecifier(Result))
     return Result;
 
-  return 0;
+  return nullptr;
 }
 
 bool Sema::isNonTypeNestedNameSpecifier(Scope *S, CXXScopeSpec &SS,
@@ -313,7 +313,7 @@
   LookupResult Found(*this, &II, IdLoc, LookupNestedNameSpecifierName);
   
   // Determine where to perform name lookup
-  DeclContext *LookupCtx = 0;
+  DeclContext *LookupCtx = nullptr;
   bool isDependent = false;
   if (!ObjectType.isNull()) {
     // This nested-name-specifier occurs in a member access expression, e.g.,
@@ -363,7 +363,7 @@
   explicit NestedNameSpecifierValidatorCCC(Sema &SRef)
       : SRef(SRef) {}
 
-  virtual bool ValidateCandidate(const TypoCorrection &candidate) {
+  bool ValidateCandidate(const TypoCorrection &candidate) override {
     return SRef.isAcceptableNestedNameSpecifier(candidate.getCorrectionDecl());
   }
 
@@ -377,6 +377,28 @@
 /// by ActOnCXXNestedNameSpecifier.
 ///
 /// This routine differs only slightly from ActOnCXXNestedNameSpecifier, in
+/// that it contains an extra parameter \p ScopeLookupResult.
+///
+/// \param S Scope in which the nested-name-specifier occurs.
+/// \param Identifier Identifier in the sequence "identifier" "::".
+/// \param IdentifierLoc Location of the \p Identifier.
+/// \param CCLoc Location of "::" following Identifier.
+/// \param ObjectType Type of postfix expression if the nested-name-specifier
+///        occurs in construct like: <tt>ptr->nns::f</tt>.
+/// \param EnteringContext If true, enter the context specified by the
+///        nested-name-specifier.
+/// \param SS Optional nested name specifier preceding the identifier.
+/// \param ScopeLookupResult Provides the result of name lookup within the
+///        scope of the nested-name-specifier that was computed at template
+///        definition time.
+/// \param ErrorRecoveryLookup Specifies if the method is called to improve
+///        error recovery and what kind of recovery is performed.
+/// \param IsCorrectedToColon If not null, suggestion of replace '::' -> ':'
+///        are allowed.  The bool value pointed by this parameter is set to
+///       'true' if the identifier is treated as if it was followed by ':',
+///        not '::'.
+///
+/// This routine differs only slightly from ActOnCXXNestedNameSpecifier, in
 /// that it contains an extra parameter \p ScopeLookupResult, which provides
 /// the result of name lookup within the scope of the nested-name-specifier
 /// that was computed at template definition time.
@@ -395,13 +417,16 @@
                                        bool EnteringContext,
                                        CXXScopeSpec &SS,
                                        NamedDecl *ScopeLookupResult,
-                                       bool ErrorRecoveryLookup) {
+                                       bool ErrorRecoveryLookup,
+                                       bool *IsCorrectedToColon) {
   LookupResult Found(*this, &Identifier, IdentifierLoc, 
                      LookupNestedNameSpecifierName);
 
   // Determine where to perform name lookup
-  DeclContext *LookupCtx = 0;
+  DeclContext *LookupCtx = nullptr;
   bool isDependent = false;
+  if (IsCorrectedToColon)
+    *IsCorrectedToColon = false;
   if (!ObjectType.isNull()) {
     // This nested-name-specifier occurs in a member access expression, e.g.,
     // x->B::f, and we are looking into the type of the object.
@@ -416,7 +441,6 @@
     Found.setContextRange(SS.getRange());
   }
 
-
   bool ObjectTypeSearchedInScope = false;
   if (LookupCtx) {
     // Perform "qualified" name lookup into the declaration context we
@@ -473,18 +497,47 @@
     // Don't speculate if we're just trying to improve error recovery.
     if (ErrorRecoveryLookup)
       return true;
-    
+
     // We were not able to compute the declaration context for a dependent
     // base object type or prior nested-name-specifier, so this
     // nested-name-specifier refers to an unknown specialization. Just build
     // a dependent nested-name-specifier.
     SS.Extend(Context, &Identifier, IdentifierLoc, CCLoc);
     return false;
-  } 
-  
+  }
+
   // FIXME: Deal with ambiguities cleanly.
 
-  if (Found.empty() && !ErrorRecoveryLookup && !getLangOpts().MicrosoftMode) {
+  if (Found.empty() && !ErrorRecoveryLookup) {
+    // If identifier is not found as class-name-or-namespace-name, but is found
+    // as other entity, don't look for typos.
+    LookupResult R(*this, Found.getLookupNameInfo(), LookupOrdinaryName);
+    if (LookupCtx)
+      LookupQualifiedName(R, LookupCtx);
+    else if (S && !isDependent)
+      LookupName(R, S);
+    if (!R.empty()) {
+      // The identifier is found in ordinary lookup. If correction to colon is
+      // allowed, suggest replacement to ':'.
+      if (IsCorrectedToColon) {
+        *IsCorrectedToColon = true;
+        Diag(CCLoc, diag::err_nested_name_spec_is_not_class)
+            << &Identifier << getLangOpts().CPlusPlus
+            << FixItHint::CreateReplacement(CCLoc, ":");
+        if (NamedDecl *ND = R.getAsSingle<NamedDecl>())
+          Diag(ND->getLocation(), diag::note_declared_at);
+        return true;
+      }
+      // Replacement '::' -> ':' is not allowed, just issue respective error.
+      Diag(R.getNameLoc(), diag::err_expected_class_or_namespace)
+          << &Identifier << getLangOpts().CPlusPlus;
+      if (NamedDecl *ND = R.getAsSingle<NamedDecl>())
+        Diag(ND->getLocation(), diag::note_entity_declared_at) << &Identifier;
+      return true;
+    }
+  }
+
+  if (Found.empty() && !ErrorRecoveryLookup && !getLangOpts().MSVCCompat) {
     // We haven't found anything, and we're not recovering from a
     // different kind of error, so look for typos.
     DeclarationName Name = Found.getLookupName();
@@ -492,11 +545,14 @@
     Found.clear();
     if (TypoCorrection Corrected =
             CorrectTypo(Found.getLookupNameInfo(), Found.getLookupKind(), S,
-                        &SS, Validator, LookupCtx, EnteringContext)) {
+                        &SS, Validator, CTK_ErrorRecovery, LookupCtx,
+                        EnteringContext)) {
       if (LookupCtx) {
         bool DroppedSpecifier =
             Corrected.WillReplaceSpecifier() &&
             Name.getAsString() == Corrected.getAsString(getLangOpts());
+        if (DroppedSpecifier)
+          SS.clear();
         diagnoseTypo(Corrected, PDiag(diag::err_no_member_suggest)
                                   << Name << LookupCtx << DroppedSpecifier
                                   << SS.getRange());
@@ -541,8 +597,8 @@
            !Context.hasSameType(
                             Context.getTypeDeclType(cast<TypeDecl>(OuterDecl)),
                                Context.getTypeDeclType(cast<TypeDecl>(SD))))) {
-         if (ErrorRecoveryLookup)
-           return true;
+        if (ErrorRecoveryLookup)
+          return true;
 
          Diag(IdentifierLoc, 
               diag::err_nested_name_member_ref_lookup_ambiguous)
@@ -556,7 +612,7 @@
        }
     }
 
-    // If we're just performing this lookup for error-recovery purposes, 
+    // If we're just performing this lookup for error-recovery purposes,
     // don't extend the nested-name-specifier. Just return now.
     if (ErrorRecoveryLookup)
       return false;
@@ -644,7 +700,7 @@
   // public:
   //   void foo() { D::foo2(); }
   // };
-  if (getLangOpts().MicrosoftMode) {
+  if (getLangOpts().MSVCCompat) {
     DeclContext *DC = LookupCtx ? LookupCtx : CurContext;
     if (DC->isDependentContext() && DC->isFunctionOrMethod()) {
       SS.Extend(Context, &Identifier, IdentifierLoc, CCLoc);
@@ -652,20 +708,21 @@
     }
   }
 
-  unsigned DiagID;
-  if (!Found.empty())
-    DiagID = diag::err_expected_class_or_namespace;
-  else if (SS.isSet()) {
-    Diag(IdentifierLoc, diag::err_no_member) 
-      << &Identifier << LookupCtx << SS.getRange();
-    return true;
-  } else
-    DiagID = diag::err_undeclared_var_use;
-
-  if (SS.isSet())
-    Diag(IdentifierLoc, DiagID) << &Identifier << SS.getRange();
+  if (!Found.empty()) {
+    if (TypeDecl *TD = Found.getAsSingle<TypeDecl>())
+      Diag(IdentifierLoc, diag::err_expected_class_or_namespace)
+          << QualType(TD->getTypeForDecl(), 0) << getLangOpts().CPlusPlus;
+    else {
+      Diag(IdentifierLoc, diag::err_expected_class_or_namespace)
+          << &Identifier << getLangOpts().CPlusPlus;
+      if (NamedDecl *ND = Found.getAsSingle<NamedDecl>())
+        Diag(ND->getLocation(), diag::note_entity_declared_at) << &Identifier;
+    }
+  } else if (SS.isSet())
+    Diag(IdentifierLoc, diag::err_no_member) << &Identifier << LookupCtx
+                                             << SS.getRange();
   else
-    Diag(IdentifierLoc, DiagID) << &Identifier;
+    Diag(IdentifierLoc, diag::err_undeclared_var_use) << &Identifier;
 
   return true;
 }
@@ -676,14 +733,17 @@
                                        SourceLocation CCLoc,
                                        ParsedType ObjectType,
                                        bool EnteringContext,
-                                       CXXScopeSpec &SS) {
+                                       CXXScopeSpec &SS,
+                                       bool ErrorRecoveryLookup,
+                                       bool *IsCorrectedToColon) {
   if (SS.isInvalid())
     return true;
-  
+
   return BuildCXXNestedNameSpecifier(S, Identifier, IdentifierLoc, CCLoc,
                                      GetTypeFromParser(ObjectType),
                                      EnteringContext, SS, 
-                                     /*ScopeLookupResult=*/0, false);
+                                     /*ScopeLookupResult=*/nullptr, false,
+                                     IsCorrectedToColon);
 }
 
 bool Sema::ActOnCXXNestedNameSpecifierDecltype(CXXScopeSpec &SS,
@@ -696,7 +756,7 @@
 
   QualType T = BuildDecltypeType(DS.getRepAsExpr(), DS.getTypeSpecTypeLoc());
   if (!T->isDependentType() && !T->getAs<TagType>()) {
-    Diag(DS.getTypeSpecTypeLoc(), diag::err_expected_class) 
+    Diag(DS.getTypeSpecTypeLoc(), diag::err_expected_class_or_namespace) 
       << T << getLangOpts().CPlusPlus;
     return true;
   }
@@ -723,11 +783,11 @@
                                      bool EnteringContext) {
   if (SS.isInvalid())
     return false;
-  
+
   return !BuildCXXNestedNameSpecifier(S, Identifier, IdentifierLoc, ColonLoc,
                                       GetTypeFromParser(ObjectType),
                                       EnteringContext, SS, 
-                                      /*ScopeLookupResult=*/0, true);
+                                      /*ScopeLookupResult=*/nullptr, true);
 }
 
 bool Sema::ActOnCXXNestedNameSpecifier(Scope *S,
@@ -747,7 +807,8 @@
   TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc);
   translateTemplateArguments(TemplateArgsIn, TemplateArgs);
 
-  if (DependentTemplateName *DTN = Template.get().getAsDependentTemplateName()){
+  DependentTemplateName *DTN = Template.get().getAsDependentTemplateName();
+  if (DTN && DTN->isIdentifier()) {
     // Handle a dependent template specialization for which we cannot resolve
     // the template name.
     assert(DTN->getQualifier() == SS.getScopeRep());
@@ -773,20 +834,20 @@
               CCLoc);
     return false;
   }
-  
-  
-  if (Template.get().getAsOverloadedTemplate() ||
-      isa<FunctionTemplateDecl>(Template.get().getAsTemplateDecl())) {
+
+  TemplateDecl *TD = Template.get().getAsTemplateDecl();
+  if (Template.get().getAsOverloadedTemplate() || DTN ||
+      isa<FunctionTemplateDecl>(TD) || isa<VarTemplateDecl>(TD)) {
     SourceRange R(TemplateNameLoc, RAngleLoc);
     if (SS.getRange().isValid())
       R.setBegin(SS.getRange().getBegin());
-      
+
     Diag(CCLoc, diag::err_non_type_template_in_nested_name_specifier)
-      << Template.get() << R;
+      << (TD && isa<VarTemplateDecl>(TD)) << Template.get() << R;
     NoteAllFoundTemplates(Template.get());
     return true;
   }
-                                
+
   // We were able to resolve the template name to an actual template. 
   // Build an appropriate nested-name-specifier.
   QualType T = CheckTemplateIdType(Template.get(), TemplateNameLoc, 
@@ -829,8 +890,8 @@
 
 void *Sema::SaveNestedNameSpecifierAnnotation(CXXScopeSpec &SS) {
   if (SS.isEmpty() || SS.isInvalid())
-    return 0;
-  
+    return nullptr;
+
   void *Mem = Context.Allocate((sizeof(NestedNameSpecifierAnnotation) +
                                                         SS.location_size()),
                                llvm::alignOf<NestedNameSpecifierAnnotation>());
diff --git a/lib/Sema/SemaCast.cpp b/lib/Sema/SemaCast.cpp
index ba00b71..ae5436c 100644
--- a/lib/Sema/SemaCast.cpp
+++ b/lib/Sema/SemaCast.cpp
@@ -21,6 +21,7 @@
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/RecordLayout.h"
 #include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/TargetInfo.h"
 #include "clang/Sema/Initialization.h"
 #include "llvm/ADT/SmallVector.h"
 #include <set>
@@ -89,10 +90,10 @@
       if (IsARCUnbridgedCast) {
         castExpr = ImplicitCastExpr::Create(Self.Context,
                                             Self.Context.ARCUnbridgedCastTy,
-                                            CK_Dependent, castExpr, 0,
+                                            CK_Dependent, castExpr, nullptr,
                                             castExpr->getValueKind());
       }
-      return Self.Owned(castExpr);
+      return castExpr;
     }
 
     // Internal convenience methods.
@@ -133,7 +134,7 @@
       if (!isPlaceholder() || isPlaceholder(BuiltinType::Overload))
         return;
 
-      SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.take());
+      SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.get());
       if (SrcExpr.isInvalid())
         return;
       PlaceholderKind = (BuiltinType::Kind) 0;
@@ -238,7 +239,7 @@
 Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
                         TypeSourceInfo *DestTInfo, Expr *E,
                         SourceRange AngleBrackets, SourceRange Parens) {
-  ExprResult Ex = Owned(E);
+  ExprResult Ex = E;
   QualType DestType = DestTInfo->getType();
 
   // If the type is dependent, we won't do the semantic analysis now.
@@ -261,7 +262,7 @@
         return ExprError();
     }
     return Op.complete(CXXConstCastExpr::Create(Context, Op.ResultType,
-                                  Op.ValueKind, Op.SrcExpr.take(), DestTInfo,
+                                  Op.ValueKind, Op.SrcExpr.get(), DestTInfo,
                                                 OpLoc, Parens.getEnd(),
                                                 AngleBrackets));
 
@@ -272,7 +273,7 @@
         return ExprError();
     }
     return Op.complete(CXXDynamicCastExpr::Create(Context, Op.ResultType,
-                                    Op.ValueKind, Op.Kind, Op.SrcExpr.take(),
+                                    Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
                                                   &Op.BasePath, DestTInfo,
                                                   OpLoc, Parens.getEnd(),
                                                   AngleBrackets));
@@ -284,8 +285,8 @@
         return ExprError();
     }
     return Op.complete(CXXReinterpretCastExpr::Create(Context, Op.ResultType,
-                                    Op.ValueKind, Op.Kind, Op.SrcExpr.take(),
-                                                      0, DestTInfo, OpLoc,
+                                    Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
+                                                      nullptr, DestTInfo, OpLoc,
                                                       Parens.getEnd(),
                                                       AngleBrackets));
   }
@@ -297,7 +298,7 @@
     }
     
     return Op.complete(CXXStaticCastExpr::Create(Context, Op.ResultType,
-                                   Op.ValueKind, Op.Kind, Op.SrcExpr.take(),
+                                   Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
                                                  &Op.BasePath, DestTInfo,
                                                  OpLoc, Parens.getEnd(),
                                                  AngleBrackets));
@@ -534,9 +535,9 @@
 /// checked downcasts in class hierarchies.
 void CastOperation::CheckDynamicCast() {
   if (ValueKind == VK_RValue)
-    SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take());
+    SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
   else if (isPlaceholder())
-    SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.take());
+    SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.get());
   if (SrcExpr.isInvalid()) // if conversion failed, don't report another error
     return;
 
@@ -548,7 +549,7 @@
 
   QualType DestPointee;
   const PointerType *DestPointer = DestType->getAs<PointerType>();
-  const ReferenceType *DestReference = 0;
+  const ReferenceType *DestReference = nullptr;
   if (DestPointer) {
     DestPointee = DestPointer->getPointeeType();
   } else if ((DestReference = DestType->getAs<ReferenceType>())) {
@@ -599,6 +600,11 @@
     }
     SrcPointee = SrcType;
   } else {
+    // If we're dynamic_casting from a prvalue to an rvalue reference, we need
+    // to materialize the prvalue before we bind the reference to it.
+    if (SrcExpr.get()->isRValue())
+      SrcExpr = new (Self.Context) MaterializeTemporaryExpr(
+          SrcType, SrcExpr.get(), /*IsLValueReference*/false);
     SrcPointee = SrcType;
   }
 
@@ -647,7 +653,7 @@
       SrcExpr = ExprError();
       return;
     }
-        
+
     Kind = CK_DerivedToBase;
 
     // If we are casting to or through a virtual base class, we need a
@@ -689,9 +695,9 @@
 /// legacy_function(const_cast\<char*\>(str));
 void CastOperation::CheckConstCast() {
   if (ValueKind == VK_RValue)
-    SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take());
+    SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
   else if (isPlaceholder())
-    SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.take());
+    SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.get());
   if (SrcExpr.isInvalid()) // if conversion failed, don't report another error
     return;
 
@@ -804,7 +810,7 @@
 /// char *bytes = reinterpret_cast\<char*\>(int_ptr);
 void CastOperation::CheckReinterpretCast() {
   if (ValueKind == VK_RValue && !isPlaceholder(BuiltinType::Overload))
-    SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take());
+    SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
   else
     checkNonOverloadPlaceholders();
   if (SrcExpr.isInvalid()) // if conversion failed, don't report another error
@@ -863,13 +869,13 @@
         return;
     }
 
-    SrcExpr = Self.IgnoredValueConversions(SrcExpr.take());
+    SrcExpr = Self.IgnoredValueConversions(SrcExpr.get());
     return;
   }
 
   if (ValueKind == VK_RValue && !DestType->isRecordType() &&
       !isPlaceholder(BuiltinType::Overload)) {
-    SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take());
+    SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
     if (SrcExpr.isInvalid()) // if conversion failed, don't report another error
       return;
   }
@@ -1066,6 +1072,11 @@
     Kind = CK_BitCast;
     return TC_Success;
   }
+  // Allow ns-pointer to cf-pointer conversion in either direction
+  // with static casts.
+  if (!CStyle &&
+      Self.CheckTollFreeBridgeStaticCast(DestType, SrcExpr.get(), Kind))
+    return TC_Success;
   
   // We tried everything. Everything! Nothing works! :-(
   return TC_NotApplicable;
@@ -1150,6 +1161,9 @@
 
   QualType DestPointee = DestReference->getPointeeType();
 
+  // FIXME: If the source is a prvalue, we should issue a warning (because the
+  // cast always has undefined behavior), and for AST consistency, we should
+  // materialize a temporary.
   return TryStaticDowncast(Self, 
                            Self.Context.getCanonicalType(SrcExpr->getType()), 
                            Self.Context.getCanonicalType(DestPointee), CStyle,
@@ -1271,7 +1285,7 @@
     return TC_Failed;
   }
 
-  if (Paths.getDetectedVirtual() != 0) {
+  if (Paths.getDetectedVirtual() != nullptr) {
     QualType VirtualBase(Paths.getDetectedVirtual(), 0);
     Self.Diag(OpRange.getBegin(), diag::err_static_downcast_via_virtual)
       << OrigSrcType << OrigDestType << VirtualBase << OpRange;
@@ -1346,7 +1360,8 @@
   QualType DestClass(DestMemPtr->getClass(), 0);
   CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
                   /*DetectVirtual=*/true);
-  if (!Self.IsDerivedFrom(SrcClass, DestClass, Paths)) {
+  if (Self.RequireCompleteType(OpRange.getBegin(), SrcClass, 0) ||
+      !Self.IsDerivedFrom(SrcClass, DestClass, Paths)) {
     return TC_NotApplicable;
   }
 
@@ -1431,6 +1446,10 @@
       msg = 0;
       return TC_Failed;
     }
+  } else if (DestType->isMemberPointerType()) {
+    if (Self.Context.getTargetInfo().getCXXABI().isMicrosoft()) {
+      Self.RequireCompleteType(OpRange.getBegin(), DestType, 0);
+    }
   }
 
   InitializedEntity Entity = InitializedEntity::InitializeTemporary(DestType);
@@ -1578,8 +1597,7 @@
     // This is a const_cast from a class prvalue to an rvalue reference type.
     // Materialize a temporary to store the result of the conversion.
     SrcExpr = new (Self.Context) MaterializeTemporaryExpr(
-        SrcType, SrcExpr.take(), /*IsLValueReference*/ false,
-        /*ExtendingDecl*/ 0);
+        SrcType, SrcExpr.get(), /*IsLValueReference*/ false);
 
   return TC_Success;
 }
@@ -1596,10 +1614,8 @@
                         diag::warn_pointer_indirection_from_incompatible_type :
                         diag::warn_undefined_reinterpret_cast;
 
-  if (Diags.getDiagnosticLevel(DiagID, Range.getBegin()) ==
-          DiagnosticsEngine::Ignored) {
+  if (Diags.isIgnored(DiagID, Range.getBegin()))
     return;
-  }
 
   QualType SrcTy, DestTy;
   if (IsDereference) {
@@ -1729,7 +1745,7 @@
     //   same effect as the conversion *reinterpret_cast<T*>(&x) with the
     //   built-in & and * operators.
 
-    const char *inappropriate = 0;
+    const char *inappropriate = nullptr;
     switch (SrcExpr.get()->getObjectKind()) {
     case OK_Ordinary:
       break;
@@ -1778,6 +1794,13 @@
       return TC_Failed;
     }
 
+    if (Self.Context.getTargetInfo().getCXXABI().isMicrosoft()) {
+      // We need to determine the inheritance model that the class will use if
+      // haven't yet.
+      Self.RequireCompleteType(OpRange.getBegin(), SrcType, 0);
+      Self.RequireCompleteType(OpRange.getBegin(), DestType, 0);
+    }
+
     // Don't allow casting between member pointers of different sizes.
     if (Self.Context.getTypeSize(DestMemPtr) !=
         Self.Context.getTypeSize(SrcMemPtr)) {
@@ -2007,7 +2030,7 @@
         return;
     }
 
-    SrcExpr = Self.IgnoredValueConversions(SrcExpr.take());
+    SrcExpr = Self.IgnoredValueConversions(SrcExpr.get());
     return;
   }
 
@@ -2020,7 +2043,7 @@
 
   if (ValueKind == VK_RValue && !DestType->isRecordType() &&
       !isPlaceholder(BuiltinType::Overload)) {
-    SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take());
+    SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
     if (SrcExpr.isInvalid())
       return;
   }
@@ -2082,10 +2105,16 @@
                                 DestType,
                                 /*Complain*/ true,
                                 Found);
-      
-      assert(!Fn && "cast failed but able to resolve overload expression!!");
-      (void)Fn;
-
+      if (Fn) {
+        // If DestType is a function type (not to be confused with the function
+        // pointer type), it will be possible to resolve the function address,
+        // but the type cast should be considered as failure.
+        OverloadExpr *OE = OverloadExpr::find(SrcExpr.get()).Expression;
+        Self.Diag(OpRange.getBegin(), diag::err_bad_cstyle_cast_overload)
+          << OE->getName() << DestType << OpRange
+          << OE->getQualifierLoc().getSourceRange();
+        Self.NoteAllOverloadCandidates(SrcExpr.get());
+      }
     } else {
       diagnoseBadCast(Self, msg, (FunctionalStyle ? CT_Functional : CT_CStyle),
                       OpRange, SrcExpr.get(), DestType, ListInitialization);
@@ -2104,9 +2133,8 @@
 /// pointer; etc. Cast to 'void' is an exception.
 static void DiagnoseBadFunctionCast(Sema &Self, const ExprResult &SrcExpr,
                                   QualType DestType) {
-  if (Self.Diags.getDiagnosticLevel(diag::warn_bad_function_cast,
-                                    SrcExpr.get()->getExprLoc()) 
-        == DiagnosticsEngine::Ignored)
+  if (Self.Diags.isIgnored(diag::warn_bad_function_cast,
+                           SrcExpr.get()->getExprLoc()))
     return;
   
   if (!isa<CallExpr>(SrcExpr.get()))
@@ -2152,7 +2180,7 @@
   // type needs to be scalar.
   if (DestType->isVoidType()) {
     // We don't necessarily do lvalue-to-rvalue conversions on this.
-    SrcExpr = Self.IgnoredValueConversions(SrcExpr.take());
+    SrcExpr = Self.IgnoredValueConversions(SrcExpr.get());
     if (SrcExpr.isInvalid())
       return;
 
@@ -2161,13 +2189,28 @@
     return;
   }
 
-  SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take());
+  SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
   if (SrcExpr.isInvalid())
     return;
   QualType SrcType = SrcExpr.get()->getType();
 
   assert(!SrcType->isPlaceholderType());
 
+  // OpenCL v1 s6.5: Casting a pointer to address space A to a pointer to
+  // address space B is illegal.
+  if (Self.getLangOpts().OpenCL && DestType->isPointerType() &&
+      SrcType->isPointerType()) {
+    if (DestType->getPointeeType().getAddressSpace() !=
+        SrcType->getPointeeType().getAddressSpace()) {
+      Self.Diag(OpRange.getBegin(),
+                diag::err_typecheck_incompatible_address_space)
+          << SrcType << DestType << Sema::AA_Casting
+          << SrcExpr.get()->getSourceRange();
+      SrcExpr = ExprError();
+      return;
+    }
+  }
+
   if (Self.RequireCompleteType(OpRange.getBegin(), DestType,
                                diag::err_typecheck_cast_to_incomplete)) {
     SrcExpr = ExprError();
@@ -2227,7 +2270,7 @@
   }
 
   if (DestType->isExtVectorType()) {
-    SrcExpr = Self.CheckExtVectorCast(OpRange, DestType, SrcExpr.take(), Kind);
+    SrcExpr = Self.CheckExtVectorCast(OpRange, DestType, SrcExpr.get(), Kind);
     return;
   }
 
@@ -2319,6 +2362,7 @@
       return;
     }
   }
+  
   DiagnoseCastOfObjCSEL(Self, SrcExpr, DestType);
   DiagnoseBadFunctionCast(Self, SrcExpr, DestType);
   Kind = Self.PrepareScalarCast(SrcExpr, DestType);
@@ -2348,7 +2392,7 @@
     return ExprError();
 
   return Op.complete(CStyleCastExpr::Create(Context, Op.ResultType,
-                              Op.ValueKind, Op.Kind, Op.SrcExpr.take(),
+                              Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
                               &Op.BasePath, CastTypeInfo, LPLoc, RPLoc));
 }
 
@@ -2370,5 +2414,5 @@
 
   return Op.complete(CXXFunctionalCastExpr::Create(Context, Op.ResultType,
                          Op.ValueKind, CastTypeInfo, Op.Kind,
-                         Op.SrcExpr.take(), &Op.BasePath, LPLoc, RPLoc));
+                         Op.SrcExpr.get(), &Op.BasePath, LPLoc, RPLoc));
 }
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 0b95c48..66be962 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -27,14 +27,14 @@
 #include "clang/Basic/CharInfo.h"
 #include "clang/Basic/TargetBuiltins.h"
 #include "clang/Basic/TargetInfo.h"
-#include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/Lexer.h" // TODO: Extract static functions to fix layering.
 #include "clang/Sema/Initialization.h"
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/ScopeInfo.h"
 #include "clang/Sema/Sema.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallBitVector.h"
 #include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/ConvertUTF.h"
 #include "llvm/Support/raw_ostream.h"
 #include <limits>
@@ -43,8 +43,8 @@
 
 SourceLocation Sema::getLocationOfStringLiteralByte(const StringLiteral *SL,
                                                     unsigned ByteNo) const {
-  return SL->getLocationOfByte(ByteNo, PP.getSourceManager(),
-                               PP.getLangOpts(), PP.getTargetInfo());
+  return SL->getLocationOfByte(ByteNo, getSourceManager(), LangOpts,
+                               Context.getTargetInfo());
 }
 
 /// Checks that a call expression's argument count is the desired number.
@@ -101,19 +101,19 @@
   if (checkArgCount(S, TheCall, 1))
     return true;
 
-  ExprResult Arg(S.Owned(TheCall->getArg(0)));
+  ExprResult Arg(TheCall->getArg(0));
   QualType ResultType = S.CheckAddressOfOperand(Arg, TheCall->getLocStart());
   if (ResultType.isNull())
     return true;
 
-  TheCall->setArg(0, Arg.take());
+  TheCall->setArg(0, Arg.get());
   TheCall->setType(ResultType);
   return false;
 }
 
 ExprResult
 Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
-  ExprResult TheCallResult(Owned(TheCall));
+  ExprResult TheCallResult(TheCall);
 
   // Find out if any arguments are required to be integer constant expressions.
   unsigned ICEArguments = 0;
@@ -145,6 +145,20 @@
     if (SemaBuiltinVAStart(TheCall))
       return ExprError();
     break;
+  case Builtin::BI__va_start: {
+    switch (Context.getTargetInfo().getTriple().getArch()) {
+    case llvm::Triple::arm:
+    case llvm::Triple::thumb:
+      if (SemaBuiltinVAStartARM(TheCall))
+        return ExprError();
+      break;
+    default:
+      if (SemaBuiltinVAStart(TheCall))
+        return ExprError();
+      break;
+    }
+    break;
+  }
   case Builtin::BI__builtin_isgreater:
   case Builtin::BI__builtin_isgreaterequal:
   case Builtin::BI__builtin_isless:
@@ -174,8 +188,12 @@
     if (SemaBuiltinPrefetch(TheCall))
       return ExprError();
     break;
+  case Builtin::BI__assume:
+    if (SemaBuiltinAssume(TheCall))
+      return ExprError();
+    break;
   case Builtin::BI__builtin_object_size:
-    if (SemaBuiltinObjectSize(TheCall))
+    if (SemaBuiltinConstantArgRange(TheCall, 1, 0, 3))
       return ExprError();
     break;
   case Builtin::BI__builtin_longjmp:
@@ -295,18 +313,37 @@
     if (SemaBuiltinAddressof(*this, TheCall))
       return ExprError();
     break;
+  case Builtin::BI__builtin_operator_new:
+  case Builtin::BI__builtin_operator_delete:
+    if (!getLangOpts().CPlusPlus) {
+      Diag(TheCall->getExprLoc(), diag::err_builtin_requires_language)
+        << (BuiltinID == Builtin::BI__builtin_operator_new
+                ? "__builtin_operator_new"
+                : "__builtin_operator_delete")
+        << "C++";
+      return ExprError();
+    }
+    // CodeGen assumes it can find the global new and delete to call,
+    // so ensure that they are declared.
+    DeclareGlobalNewDelete();
+    break;
   }
-  
+
   // Since the target specific builtins for each arch overlap, only check those
   // of the arch we are compiling for.
   if (BuiltinID >= Builtin::FirstTSBuiltin) {
     switch (Context.getTargetInfo().getTriple().getArch()) {
       case llvm::Triple::arm:
+      case llvm::Triple::armeb:
       case llvm::Triple::thumb:
+      case llvm::Triple::thumbeb:
         if (CheckARMBuiltinFunctionCall(BuiltinID, TheCall))
           return ExprError();
         break;
       case llvm::Triple::aarch64:
+      case llvm::Triple::aarch64_be:
+      case llvm::Triple::arm64:
+      case llvm::Triple::arm64_be:
         if (CheckAArch64BuiltinFunctionCall(BuiltinID, TheCall))
           return ExprError();
         break;
@@ -317,6 +354,11 @@
         if (CheckMipsBuiltinFunctionCall(BuiltinID, TheCall))
           return ExprError();
         break;
+      case llvm::Triple::x86:
+      case llvm::Triple::x86_64:
+        if (CheckX86BuiltinFunctionCall(BuiltinID, TheCall))
+          return ExprError();
+        break;
       default:
         break;
     }
@@ -326,9 +368,9 @@
 }
 
 // Get the valid immediate range for the specified NEON type code.
-static unsigned RFT(unsigned t, bool shift = false) {
+static unsigned RFT(unsigned t, bool shift = false, bool ForceQuad = false) {
   NeonTypeFlags Type(t);
-  int IsQuad = Type.isQuad();
+  int IsQuad = ForceQuad ? true : Type.isQuad();
   switch (Type.getEltType()) {
   case NeonTypeFlags::Int8:
   case NeonTypeFlags::Poly8:
@@ -341,6 +383,8 @@
   case NeonTypeFlags::Int64:
   case NeonTypeFlags::Poly64:
     return shift ? 63 : (1 << IsQuad) - 1;
+  case NeonTypeFlags::Poly128:
+    return shift ? 127 : (1 << IsQuad) - 1;
   case NeonTypeFlags::Float16:
     assert(!shift && "cannot shift float types!");
     return (4 << IsQuad) - 1;
@@ -358,7 +402,7 @@
 /// the vector type specified by the NeonTypeFlags.  This is used to check
 /// the pointer arguments for Neon load/store intrinsics.
 static QualType getNeonEltType(NeonTypeFlags Flags, ASTContext &Context,
-                               bool IsAArch64) {
+                               bool IsPolyUnsigned, bool IsInt64Long) {
   switch (Flags.getEltType()) {
   case NeonTypeFlags::Int8:
     return Flags.isUnsigned() ? Context.UnsignedCharTy : Context.SignedCharTy;
@@ -367,13 +411,19 @@
   case NeonTypeFlags::Int32:
     return Flags.isUnsigned() ? Context.UnsignedIntTy : Context.IntTy;
   case NeonTypeFlags::Int64:
-    return Flags.isUnsigned() ? Context.UnsignedLongLongTy : Context.LongLongTy;
+    if (IsInt64Long)
+      return Flags.isUnsigned() ? Context.UnsignedLongTy : Context.LongTy;
+    else
+      return Flags.isUnsigned() ? Context.UnsignedLongLongTy
+                                : Context.LongLongTy;
   case NeonTypeFlags::Poly8:
-    return IsAArch64 ? Context.UnsignedCharTy : Context.SignedCharTy;
+    return IsPolyUnsigned ? Context.UnsignedCharTy : Context.SignedCharTy;
   case NeonTypeFlags::Poly16:
-    return IsAArch64 ? Context.UnsignedShortTy : Context.ShortTy;
+    return IsPolyUnsigned ? Context.UnsignedShortTy : Context.ShortTy;
   case NeonTypeFlags::Poly64:
-    return Context.UnsignedLongLongTy;
+    return Context.UnsignedLongTy;
+  case NeonTypeFlags::Poly128:
+    break;
   case NeonTypeFlags::Float16:
     return Context.HalfTy;
   case NeonTypeFlags::Float32:
@@ -384,24 +434,21 @@
   llvm_unreachable("Invalid NeonTypeFlag!");
 }
 
-bool Sema::CheckAArch64BuiltinFunctionCall(unsigned BuiltinID,
-                                           CallExpr *TheCall) {
-
+bool Sema::CheckNeonBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
   llvm::APSInt Result;
-
   uint64_t mask = 0;
   unsigned TV = 0;
   int PtrArgNum = -1;
   bool HasConstPtr = false;
   switch (BuiltinID) {
-#define GET_NEON_AARCH64_OVERLOAD_CHECK
+#define GET_NEON_OVERLOAD_CHECK
 #include "clang/Basic/arm_neon.inc"
-#undef GET_NEON_AARCH64_OVERLOAD_CHECK
+#undef GET_NEON_OVERLOAD_CHECK
   }
 
   // For NEON intrinsics which are overloaded on vector element type, validate
   // the immediate which specifies which variant to emit.
-  unsigned ImmArg = TheCall->getNumArgs() - 1;
+  unsigned ImmArg = TheCall->getNumArgs()-1;
   if (mask) {
     if (SemaBuiltinConstantArg(TheCall, ImmArg, Result))
       return true;
@@ -409,7 +456,7 @@
     TV = Result.getLimitedValue(64);
     if ((TV > 63) || (mask & (1ULL << TV)) == 0)
       return Diag(TheCall->getLocStart(), diag::err_invalid_neon_type_code)
-             << TheCall->getArg(ImmArg)->getSourceRange();
+        << TheCall->getArg(ImmArg)->getSourceRange();
   }
 
   if (PtrArgNum >= 0) {
@@ -419,7 +466,14 @@
       Arg = ICE->getSubExpr();
     ExprResult RHS = DefaultFunctionArrayLvalueConversion(Arg);
     QualType RHSTy = RHS.get()->getType();
-    QualType EltTy = getNeonEltType(NeonTypeFlags(TV), Context, true);
+
+    llvm::Triple::ArchType Arch = Context.getTargetInfo().getTriple().getArch();
+    bool IsPolyUnsigned =
+        Arch == llvm::Triple::aarch64 || Arch == llvm::Triple::arm64;
+    bool IsInt64Long =
+        Context.getTargetInfo().getInt64Type() == TargetInfo::SignedLong;
+    QualType EltTy =
+        getNeonEltType(NeonTypeFlags(TV), Context, IsPolyUnsigned, IsInt64Long);
     if (HasConstPtr)
       EltTy = EltTy.withConst();
     QualType LHSTy = Context.getPointerType(EltTy);
@@ -438,35 +492,29 @@
   switch (BuiltinID) {
   default:
     return false;
-#define GET_NEON_AARCH64_IMMEDIATE_CHECK
+#define GET_NEON_IMMEDIATE_CHECK
 #include "clang/Basic/arm_neon.inc"
-#undef GET_NEON_AARCH64_IMMEDIATE_CHECK
+#undef GET_NEON_IMMEDIATE_CHECK
   }
-  ;
 
-  // We can't check the value of a dependent argument.
-  if (TheCall->getArg(i)->isTypeDependent() ||
-      TheCall->getArg(i)->isValueDependent())
-    return false;
-
-  // Check that the immediate argument is actually a constant.
-  if (SemaBuiltinConstantArg(TheCall, i, Result))
-    return true;
-
-  // Range check against the upper/lower values for this isntruction.
-  unsigned Val = Result.getZExtValue();
-  if (Val < l || Val > (u + l))
-    return Diag(TheCall->getLocStart(), diag::err_argument_invalid_range)
-           << l << u + l << TheCall->getArg(i)->getSourceRange();
-
-  return false;
+  return SemaBuiltinConstantArgRange(TheCall, i, l, u + l);
 }
 
-bool Sema::CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall) {
+bool Sema::CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall,
+                                        unsigned MaxWidth) {
   assert((BuiltinID == ARM::BI__builtin_arm_ldrex ||
-          BuiltinID == ARM::BI__builtin_arm_strex) &&
+          BuiltinID == ARM::BI__builtin_arm_ldaex ||
+          BuiltinID == ARM::BI__builtin_arm_strex ||
+          BuiltinID == ARM::BI__builtin_arm_stlex ||
+          BuiltinID == AArch64::BI__builtin_arm_ldrex ||
+          BuiltinID == AArch64::BI__builtin_arm_ldaex ||
+          BuiltinID == AArch64::BI__builtin_arm_strex ||
+          BuiltinID == AArch64::BI__builtin_arm_stlex) &&
          "unexpected ARM builtin");
-  bool IsLdrex = BuiltinID == ARM::BI__builtin_arm_ldrex;
+  bool IsLdrex = BuiltinID == ARM::BI__builtin_arm_ldrex ||
+                 BuiltinID == ARM::BI__builtin_arm_ldaex ||
+                 BuiltinID == AArch64::BI__builtin_arm_ldrex ||
+                 BuiltinID == AArch64::BI__builtin_arm_ldaex;
 
   DeclRefExpr *DRE =cast<DeclRefExpr>(TheCall->getCallee()->IgnoreParenCasts());
 
@@ -482,7 +530,7 @@
   ExprResult PointerArgRes = DefaultFunctionArrayLvalueConversion(PointerArg);
   if (PointerArgRes.isInvalid())
     return true;
-  PointerArg = PointerArgRes.take();
+  PointerArg = PointerArgRes.get();
 
   const PointerType *pointerType = PointerArg->getType()->getAs<PointerType>();
   if (!pointerType) {
@@ -514,7 +562,7 @@
   PointerArgRes = ImpCastExprToType(PointerArg, AddrType, CastNeeded);
   if (PointerArgRes.isInvalid())
     return true;
-  PointerArg = PointerArgRes.take();
+  PointerArg = PointerArgRes.get();
 
   TheCall->setArg(IsLdrex ? 0 : 1, PointerArg);
 
@@ -527,7 +575,8 @@
   }
 
   // But ARM doesn't have instructions to deal with 128-bit versions.
-  if (Context.getTypeSize(ValType) > 64) {
+  if (Context.getTypeSize(ValType) > MaxWidth) {
+    assert(MaxWidth == 64 && "Diagnostic unexpectedly inaccurate");
     Diag(DRE->getLocStart(), diag::err_atomic_exclusive_builtin_pointer_size)
       << PointerArg->getType() << PointerArg->getSourceRange();
     return true;
@@ -572,55 +621,17 @@
   llvm::APSInt Result;
 
   if (BuiltinID == ARM::BI__builtin_arm_ldrex ||
-      BuiltinID == ARM::BI__builtin_arm_strex) {
-    return CheckARMBuiltinExclusiveCall(BuiltinID, TheCall);
+      BuiltinID == ARM::BI__builtin_arm_ldaex ||
+      BuiltinID == ARM::BI__builtin_arm_strex ||
+      BuiltinID == ARM::BI__builtin_arm_stlex) {
+    return CheckARMBuiltinExclusiveCall(BuiltinID, TheCall, 64);
   }
 
-  uint64_t mask = 0;
-  unsigned TV = 0;
-  int PtrArgNum = -1;
-  bool HasConstPtr = false;
-  switch (BuiltinID) {
-#define GET_NEON_OVERLOAD_CHECK
-#include "clang/Basic/arm_neon.inc"
-#undef GET_NEON_OVERLOAD_CHECK
-  }
-  
-  // For NEON intrinsics which are overloaded on vector element type, validate
-  // the immediate which specifies which variant to emit.
-  unsigned ImmArg = TheCall->getNumArgs()-1;
-  if (mask) {
-    if (SemaBuiltinConstantArg(TheCall, ImmArg, Result))
-      return true;
-    
-    TV = Result.getLimitedValue(64);
-    if ((TV > 63) || (mask & (1ULL << TV)) == 0)
-      return Diag(TheCall->getLocStart(), diag::err_invalid_neon_type_code)
-        << TheCall->getArg(ImmArg)->getSourceRange();
-  }
+  if (CheckNeonBuiltinFunctionCall(BuiltinID, TheCall))
+    return true;
 
-  if (PtrArgNum >= 0) {
-    // Check that pointer arguments have the specified type.
-    Expr *Arg = TheCall->getArg(PtrArgNum);
-    if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Arg))
-      Arg = ICE->getSubExpr();
-    ExprResult RHS = DefaultFunctionArrayLvalueConversion(Arg);
-    QualType RHSTy = RHS.get()->getType();
-    QualType EltTy = getNeonEltType(NeonTypeFlags(TV), Context, false);
-    if (HasConstPtr)
-      EltTy = EltTy.withConst();
-    QualType LHSTy = Context.getPointerType(EltTy);
-    AssignConvertType ConvTy;
-    ConvTy = CheckSingleAssignmentConstraints(LHSTy, RHS);
-    if (RHS.isInvalid())
-      return true;
-    if (DiagnoseAssignmentResult(ConvTy, Arg->getLocStart(), LHSTy, RHSTy,
-                                 RHS.get(), AA_Assigning))
-      return true;
-  }
-  
-  // For NEON intrinsics which take an immediate value as part of the 
-  // instruction, range check them here.
+  // For intrinsics which take an immediate value as part of the instruction,
+  // range check them here.
   unsigned i = 0, l = 0, u = 0;
   switch (BuiltinID) {
   default: return false;
@@ -629,29 +640,40 @@
   case ARM::BI__builtin_arm_vcvtr_f:
   case ARM::BI__builtin_arm_vcvtr_d: i = 1; u = 1; break;
   case ARM::BI__builtin_arm_dmb:
-  case ARM::BI__builtin_arm_dsb: l = 0; u = 15; break;
-#define GET_NEON_IMMEDIATE_CHECK
-#include "clang/Basic/arm_neon.inc"
-#undef GET_NEON_IMMEDIATE_CHECK
-  };
-
-  // We can't check the value of a dependent argument.
-  if (TheCall->getArg(i)->isTypeDependent() ||
-      TheCall->getArg(i)->isValueDependent())
-    return false;
-
-  // Check that the immediate argument is actually a constant.
-  if (SemaBuiltinConstantArg(TheCall, i, Result))
-    return true;
-
-  // Range check against the upper/lower values for this isntruction.
-  unsigned Val = Result.getZExtValue();
-  if (Val < l || Val > (u + l))
-    return Diag(TheCall->getLocStart(), diag::err_argument_invalid_range)
-      << l << u+l << TheCall->getArg(i)->getSourceRange();
+  case ARM::BI__builtin_arm_dsb:
+  case ARM::BI__builtin_arm_isb: l = 0; u = 15; break;
+  }
 
   // FIXME: VFP Intrinsics should error if VFP not present.
-  return false;
+  return SemaBuiltinConstantArgRange(TheCall, i, l, u + l);
+}
+
+bool Sema::CheckAArch64BuiltinFunctionCall(unsigned BuiltinID,
+                                         CallExpr *TheCall) {
+  llvm::APSInt Result;
+
+  if (BuiltinID == AArch64::BI__builtin_arm_ldrex ||
+      BuiltinID == AArch64::BI__builtin_arm_ldaex ||
+      BuiltinID == AArch64::BI__builtin_arm_strex ||
+      BuiltinID == AArch64::BI__builtin_arm_stlex) {
+    return CheckARMBuiltinExclusiveCall(BuiltinID, TheCall, 128);
+  }
+
+  if (CheckNeonBuiltinFunctionCall(BuiltinID, TheCall))
+    return true;
+
+  // For intrinsics which take an immediate value as part of the instruction,
+  // range check them here.
+  unsigned i = 0, l = 0, u = 0;
+  switch (BuiltinID) {
+  default: return false;
+  case AArch64::BI__builtin_arm_dmb:
+  case AArch64::BI__builtin_arm_dsb:
+  case AArch64::BI__builtin_arm_isb: l = 0; u = 15; break;
+  }
+
+  // FIXME: VFP Intrinsics should error if VFP not present.
+  return SemaBuiltinConstantArgRange(TheCall, i, l, u + l);
 }
 
 bool Sema::CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
@@ -665,24 +687,17 @@
   case Mips::BI__builtin_mips_precr_sra_ph_w: i = 2; l = 0; u = 31; break;
   case Mips::BI__builtin_mips_precr_sra_r_ph_w: i = 2; l = 0; u = 31; break;
   case Mips::BI__builtin_mips_prepend: i = 2; l = 0; u = 31; break;
-  };
+  }
 
-  // We can't check the value of a dependent argument.
-  if (TheCall->getArg(i)->isTypeDependent() ||
-      TheCall->getArg(i)->isValueDependent())
-    return false;
+  return SemaBuiltinConstantArgRange(TheCall, i, l, u);
+}
 
-  // Check that the immediate argument is actually a constant.
-  llvm::APSInt Result;
-  if (SemaBuiltinConstantArg(TheCall, i, Result))
-    return true;
-
-  // Range check against the upper/lower values for this instruction.
-  unsigned Val = Result.getZExtValue();
-  if (Val < l || Val > u)
-    return Diag(TheCall->getLocStart(), diag::err_argument_invalid_range)
-      << l << u << TheCall->getArg(i)->getSourceRange();
-
+bool Sema::CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
+  switch (BuiltinID) {
+  case X86::BI_mm_prefetch:
+    // This is declared to take (const char*, int)
+    return SemaBuiltinConstantArgRange(TheCall, 1, 0, 3);
+  }
   return false;
 }
 
@@ -709,14 +724,66 @@
   return true;
 }
 
+/// Checks if a the given expression evaluates to null.
+///
+/// \brief Returns true if the value evaluates to null.
+static bool CheckNonNullExpr(Sema &S,
+                             const Expr *Expr) {
+  // As a special case, transparent unions initialized with zero are
+  // considered null for the purposes of the nonnull attribute.
+  if (const RecordType *UT = Expr->getType()->getAsUnionType()) {
+    if (UT->getDecl()->hasAttr<TransparentUnionAttr>())
+      if (const CompoundLiteralExpr *CLE =
+          dyn_cast<CompoundLiteralExpr>(Expr))
+        if (const InitListExpr *ILE =
+            dyn_cast<InitListExpr>(CLE->getInitializer()))
+          Expr = ILE->getInit(0);
+  }
+
+  bool Result;
+  return (!Expr->isValueDependent() &&
+          Expr->EvaluateAsBooleanCondition(Result, S.Context) &&
+          !Result);
+}
+
+static void CheckNonNullArgument(Sema &S,
+                                 const Expr *ArgExpr,
+                                 SourceLocation CallSiteLoc) {
+  if (CheckNonNullExpr(S, ArgExpr))
+    S.Diag(CallSiteLoc, diag::warn_null_arg) << ArgExpr->getSourceRange();
+}
+
+static void CheckNonNullArguments(Sema &S,
+                                  const NamedDecl *FDecl,
+                                  const Expr * const *ExprArgs,
+                                  SourceLocation CallSiteLoc) {
+  // Check the attributes attached to the method/function itself.
+  for (const auto *NonNull : FDecl->specific_attrs<NonNullAttr>()) {
+    for (const auto &Val : NonNull->args())
+      CheckNonNullArgument(S, ExprArgs[Val], CallSiteLoc);
+  }
+
+  // Check the attributes on the parameters.
+  ArrayRef<ParmVarDecl*> parms;
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(FDecl))
+    parms = FD->parameters();
+  else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(FDecl))
+    parms = MD->parameters();
+
+  unsigned argIndex = 0;
+  for (ArrayRef<ParmVarDecl*>::iterator I = parms.begin(), E = parms.end();
+       I != E; ++I, ++argIndex) {
+    const ParmVarDecl *PVD = *I;
+    if (PVD->hasAttr<NonNullAttr>())
+      CheckNonNullArgument(S, ExprArgs[argIndex], CallSiteLoc);
+  }
+}
+
 /// Handles the checks for format strings, non-POD arguments to vararg
 /// functions, and NULL arguments passed to non-NULL parameters.
-void Sema::checkCall(NamedDecl *FDecl,
-                     ArrayRef<const Expr *> Args,
-                     unsigned NumProtoArgs,
-                     bool IsMemberFunction,
-                     SourceLocation Loc,
-                     SourceRange Range,
+void Sema::checkCall(NamedDecl *FDecl, ArrayRef<const Expr *> Args,
+                     unsigned NumParams, bool IsMemberFunction,
+                     SourceLocation Loc, SourceRange Range,
                      VariadicCallType CallType) {
   // FIXME: We should check as much as we can in the template definition.
   if (CurContext->isDependentContext())
@@ -725,14 +792,11 @@
   // Printf and scanf checking.
   llvm::SmallBitVector CheckedVarArgs;
   if (FDecl) {
-    for (specific_attr_iterator<FormatAttr>
-             I = FDecl->specific_attr_begin<FormatAttr>(),
-             E = FDecl->specific_attr_end<FormatAttr>();
-         I != E; ++I) {
+    for (const auto *I : FDecl->specific_attrs<FormatAttr>()) {
       // Only create vector if there are format attributes.
       CheckedVarArgs.resize(Args.size());
 
-      CheckFormatArguments(*I, Args, IsMemberFunction, CallType, Loc, Range,
+      CheckFormatArguments(I, Args, IsMemberFunction, CallType, Loc, Range,
                            CheckedVarArgs);
     }
   }
@@ -740,7 +804,7 @@
   // Refuse POD arguments that weren't caught by the format string
   // checks above.
   if (CallType != VariadicDoesNotApply) {
-    for (unsigned ArgIdx = NumProtoArgs; ArgIdx < Args.size(); ++ArgIdx) {
+    for (unsigned ArgIdx = NumParams; ArgIdx < Args.size(); ++ArgIdx) {
       // Args[ArgIdx] can be null in malformed code.
       if (const Expr *Arg = Args[ArgIdx]) {
         if (CheckedVarArgs.empty() || !CheckedVarArgs[ArgIdx])
@@ -750,18 +814,11 @@
   }
 
   if (FDecl) {
-    for (specific_attr_iterator<NonNullAttr>
-           I = FDecl->specific_attr_begin<NonNullAttr>(),
-           E = FDecl->specific_attr_end<NonNullAttr>(); I != E; ++I)
-      CheckNonNullArguments(*I, Args.data(), Loc);
+    CheckNonNullArguments(*this, FDecl, Args.data(), Loc);
 
     // Type safety checking.
-    for (specific_attr_iterator<ArgumentWithTypeTagAttr>
-           i = FDecl->specific_attr_begin<ArgumentWithTypeTagAttr>(),
-           e = FDecl->specific_attr_end<ArgumentWithTypeTagAttr>();
-         i != e; ++i) {
-      CheckArgumentWithTypeTag(*i, Args.data());
-    }
+    for (const auto *I : FDecl->specific_attrs<ArgumentWithTypeTagAttr>())
+      CheckArgumentWithTypeTag(I, Args.data());
   }
 }
 
@@ -773,7 +830,7 @@
                                 SourceLocation Loc) {
   VariadicCallType CallType =
     Proto->isVariadic() ? VariadicConstructor : VariadicDoesNotApply;
-  checkCall(FDecl, Args, Proto->getNumArgs(),
+  checkCall(FDecl, Args, Proto->getNumParams(),
             /*IsMemberFunction=*/true, Loc, SourceRange(), CallType);
 }
 
@@ -787,7 +844,7 @@
                           IsMemberOperatorCall;
   VariadicCallType CallType = getVariadicCallType(FDecl, Proto,
                                                   TheCall->getCallee());
-  unsigned NumProtoArgs = Proto ? Proto->getNumArgs() : 0;
+  unsigned NumParams = Proto ? Proto->getNumParams() : 0;
   Expr** Args = TheCall->getArgs();
   unsigned NumArgs = TheCall->getNumArgs();
   if (IsMemberOperatorCall) {
@@ -797,8 +854,7 @@
     ++Args;
     --NumArgs;
   }
-  checkCall(FDecl, llvm::makeArrayRef<const Expr *>(Args, NumArgs),
-            NumProtoArgs,
+  checkCall(FDecl, llvm::makeArrayRef<const Expr *>(Args, NumArgs), NumParams,
             IsMemberFunction, TheCall->getRParenLoc(),
             TheCall->getCallee()->getSourceRange(), CallType);
 
@@ -808,6 +864,8 @@
   if (!FnInfo)
     return false;
 
+  CheckAbsoluteValueFunction(TheCall, FDecl, FnInfo);
+
   unsigned CMId = FDecl->getMemoryFunctionKind();
   if (CMId == 0)
     return false;
@@ -853,35 +911,59 @@
   } else { // Ty->isFunctionPointerType()
     CallType = VariadicFunction;
   }
-  unsigned NumProtoArgs = Proto ? Proto->getNumArgs() : 0;
+  unsigned NumParams = Proto ? Proto->getNumParams() : 0;
 
-  checkCall(NDecl,
-            llvm::makeArrayRef<const Expr *>(TheCall->getArgs(),
-                                             TheCall->getNumArgs()),
-            NumProtoArgs, /*IsMemberFunction=*/false,
-            TheCall->getRParenLoc(),
+  checkCall(NDecl, llvm::makeArrayRef<const Expr *>(TheCall->getArgs(),
+                                                    TheCall->getNumArgs()),
+            NumParams, /*IsMemberFunction=*/false, TheCall->getRParenLoc(),
             TheCall->getCallee()->getSourceRange(), CallType);
-  
+
   return false;
 }
 
 /// Checks function calls when a FunctionDecl or a NamedDecl is not available,
 /// such as function pointers returned from functions.
 bool Sema::CheckOtherCall(CallExpr *TheCall, const FunctionProtoType *Proto) {
-  VariadicCallType CallType = getVariadicCallType(/*FDecl=*/0, Proto,
+  VariadicCallType CallType = getVariadicCallType(/*FDecl=*/nullptr, Proto,
                                                   TheCall->getCallee());
-  unsigned NumProtoArgs = Proto ? Proto->getNumArgs() : 0;
+  unsigned NumParams = Proto ? Proto->getNumParams() : 0;
 
-  checkCall(/*FDecl=*/0,
+  checkCall(/*FDecl=*/nullptr,
             llvm::makeArrayRef<const Expr *>(TheCall->getArgs(),
                                              TheCall->getNumArgs()),
-            NumProtoArgs, /*IsMemberFunction=*/false,
-            TheCall->getRParenLoc(),
+            NumParams, /*IsMemberFunction=*/false, TheCall->getRParenLoc(),
             TheCall->getCallee()->getSourceRange(), CallType);
 
   return false;
 }
 
+static bool isValidOrderingForOp(int64_t Ordering, AtomicExpr::AtomicOp Op) {
+  if (Ordering < AtomicExpr::AO_ABI_memory_order_relaxed ||
+      Ordering > AtomicExpr::AO_ABI_memory_order_seq_cst)
+    return false;
+
+  switch (Op) {
+  case AtomicExpr::AO__c11_atomic_init:
+    llvm_unreachable("There is no ordering argument for an init");
+
+  case AtomicExpr::AO__c11_atomic_load:
+  case AtomicExpr::AO__atomic_load_n:
+  case AtomicExpr::AO__atomic_load:
+    return Ordering != AtomicExpr::AO_ABI_memory_order_release &&
+           Ordering != AtomicExpr::AO_ABI_memory_order_acq_rel;
+
+  case AtomicExpr::AO__c11_atomic_store:
+  case AtomicExpr::AO__atomic_store:
+  case AtomicExpr::AO__atomic_store_n:
+    return Ordering != AtomicExpr::AO_ABI_memory_order_consume &&
+           Ordering != AtomicExpr::AO_ABI_memory_order_acquire &&
+           Ordering != AtomicExpr::AO_ABI_memory_order_acq_rel;
+
+  default:
+    return true;
+  }
+}
+
 ExprResult Sema::SemaAtomicOpsOverloaded(ExprResult TheCallResult,
                                          AtomicExpr::AtomicOp Op) {
   CallExpr *TheCall = cast<CallExpr>(TheCallResult.get());
@@ -1170,7 +1252,16 @@
     SubExprs.push_back(TheCall->getArg(3)); // Weak
     break;
   }
-  
+
+  if (SubExprs.size() >= 2 && Form != Init) {
+    llvm::APSInt Result(32);
+    if (SubExprs[1]->isIntegerConstantExpr(Result, Context) &&
+        !isValidOrderingForOp(Result.getSExtValue(), Op))
+      Diag(SubExprs[1]->getLocStart(),
+           diag::warn_atomic_op_has_invalid_memory_order)
+          << SubExprs[1]->getSourceRange();
+  }
+
   AtomicExpr *AE = new (Context) AtomicExpr(TheCall->getCallee()->getLocStart(),
                                             SubExprs, ResultType, Op,
                                             TheCall->getRParenLoc());
@@ -1181,7 +1272,7 @@
     Diag(AE->getLocStart(), diag::err_atomic_load_store_uses_lib) <<
     ((Op == AtomicExpr::AO__c11_atomic_load) ? 0 : 1);
 
-  return Owned(AE);
+  return AE;
 }
 
 
@@ -1205,7 +1296,7 @@
   if (Arg.isInvalid())
     return true;
 
-  E->setArg(ArgIndex, Arg.take());
+  E->setArg(ArgIndex, Arg.get());
   return false;
 }
 
@@ -1240,7 +1331,7 @@
   ExprResult FirstArgResult = DefaultFunctionArrayLvalueConversion(FirstArg);
   if (FirstArgResult.isInvalid())
     return ExprError();
-  FirstArg = FirstArgResult.take();
+  FirstArg = FirstArgResult.get();
   TheCall->setArg(0, FirstArg);
 
   const PointerType *pointerType = FirstArg->getType()->getAs<PointerType>();
@@ -1493,7 +1584,7 @@
     LookupName(Res, TUScope, /*AllowBuiltinCreation=*/true);
     assert(Res.getFoundDecl());
     NewBuiltinDecl = dyn_cast<FunctionDecl>(Res.getFoundDecl());
-    if (NewBuiltinDecl == 0)
+    if (!NewBuiltinDecl)
       return ExprError();
   }
 
@@ -1518,7 +1609,7 @@
     // pass in 42.  The 42 gets converted to char.  This is even more strange
     // for things like 45.123 -> char, etc.
     // FIXME: Do this check.
-    TheCall->setArg(i+1, Arg.take());
+    TheCall->setArg(i+1, Arg.get());
   }
 
   ASTContext& Context = this->getASTContext();
@@ -1539,7 +1630,7 @@
   QualType CalleePtrTy = Context.getPointerType(NewBuiltinDecl->getType());
   ExprResult PromotedCall = ImpCastExprToType(NewDRE, CalleePtrTy,
                                               CK_BuiltinFnToFnPtr);
-  TheCall->setCallee(PromotedCall.take());
+  TheCall->setCallee(PromotedCall.get());
 
   // Change the result type of the call to match the original value type. This
   // is arbitrary, but the codegen for these builtins ins design to handle it
@@ -1661,6 +1752,58 @@
   return false;
 }
 
+bool Sema::SemaBuiltinVAStartARM(CallExpr *Call) {
+  // void __va_start(va_list *ap, const char *named_addr, size_t slot_size,
+  //                 const char *named_addr);
+
+  Expr *Func = Call->getCallee();
+
+  if (Call->getNumArgs() < 3)
+    return Diag(Call->getLocEnd(),
+                diag::err_typecheck_call_too_few_args_at_least)
+           << 0 /*function call*/ << 3 << Call->getNumArgs();
+
+  // Determine whether the current function is variadic or not.
+  bool IsVariadic;
+  if (BlockScopeInfo *CurBlock = getCurBlock())
+    IsVariadic = CurBlock->TheDecl->isVariadic();
+  else if (FunctionDecl *FD = getCurFunctionDecl())
+    IsVariadic = FD->isVariadic();
+  else if (ObjCMethodDecl *MD = getCurMethodDecl())
+    IsVariadic = MD->isVariadic();
+  else
+    llvm_unreachable("unexpected statement type");
+
+  if (!IsVariadic) {
+    Diag(Func->getLocStart(), diag::err_va_start_used_in_non_variadic_function);
+    return true;
+  }
+
+  // Type-check the first argument normally.
+  if (checkBuiltinArgument(*this, Call, 0))
+    return true;
+
+  static const struct {
+    unsigned ArgNo;
+    QualType Type;
+  } ArgumentTypes[] = {
+    { 1, Context.getPointerType(Context.CharTy.withConst()) },
+    { 2, Context.getSizeType() },
+  };
+
+  for (const auto &AT : ArgumentTypes) {
+    const Expr *Arg = Call->getArg(AT.ArgNo)->IgnoreParens();
+    if (Arg->getType().getCanonicalType() == AT.Type.getCanonicalType())
+      continue;
+    Diag(Arg->getLocStart(), diag::err_typecheck_convert_incompatible)
+      << Arg->getType() << AT.Type << 1 /* different class */
+      << 0 /* qualifier difference */ << 3 /* parameter mismatch */
+      << AT.ArgNo + 1 << Arg->getType() << AT.Type;
+  }
+
+  return false;
+}
+
 /// SemaBuiltinUnorderedCompare - Handle functions like __builtin_isgreater and
 /// friends.  This is declared to take (...), so we have to check everything.
 bool Sema::SemaBuiltinUnorderedCompare(CallExpr *TheCall) {
@@ -1735,7 +1878,7 @@
     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(0);
+      Cast->setSubExpr(nullptr);
       TheCall->setArg(NumArgs-1, CastArg);
     }
   }
@@ -1820,12 +1963,12 @@
 
   for (unsigned i = 0, e = TheCall->getNumArgs(); i != e; i++) {
     exprs.push_back(TheCall->getArg(i));
-    TheCall->setArg(i, 0);
+    TheCall->setArg(i, nullptr);
   }
 
-  return Owned(new (Context) ShuffleVectorExpr(Context, exprs, resType,
-                                            TheCall->getCallee()->getLocStart(),
-                                            TheCall->getRParenLoc()));
+  return new (Context) ShuffleVectorExpr(Context, exprs, resType,
+                                         TheCall->getCallee()->getLocStart(),
+                                         TheCall->getRParenLoc());
 }
 
 /// SemaConvertVectorExpr - Handle __builtin_convertvector
@@ -1854,9 +1997,8 @@
                        << E->getSourceRange());
   }
 
-  return Owned(new (Context) ConvertVectorExpr(E, TInfo, DstTy, VK, OK,
-               BuiltinLoc, RParenLoc));
-
+  return new (Context)
+      ConvertVectorExpr(E, TInfo, DstTy, VK, OK, BuiltinLoc, RParenLoc);
 }
 
 /// SemaBuiltinPrefetch - Handle __builtin_prefetch.
@@ -1873,30 +2015,23 @@
 
   // Argument 0 is checked for us and the remaining arguments must be
   // constant integers.
-  for (unsigned i = 1; i != NumArgs; ++i) {
-    Expr *Arg = TheCall->getArg(i);
-
-    // We can't check the value of a dependent argument.
-    if (Arg->isTypeDependent() || Arg->isValueDependent())
-      continue;
-
-    llvm::APSInt Result;
-    if (SemaBuiltinConstantArg(TheCall, i, Result))
+  for (unsigned i = 1; i != NumArgs; ++i)
+    if (SemaBuiltinConstantArgRange(TheCall, i, 0, i == 1 ? 1 : 3))
       return true;
 
-    // FIXME: gcc issues a warning and rewrites these to 0. These
-    // seems especially odd for the third argument since the default
-    // is 3.
-    if (i == 1) {
-      if (Result.getLimitedValue() > 1)
-        return Diag(TheCall->getLocStart(), diag::err_argument_invalid_range)
-             << "0" << "1" << Arg->getSourceRange();
-    } else {
-      if (Result.getLimitedValue() > 3)
-        return Diag(TheCall->getLocStart(), diag::err_argument_invalid_range)
-            << "0" << "3" << Arg->getSourceRange();
-    }
-  }
+  return false;
+}
+
+/// SemaBuiltinAssume - Handle __assume (MS Extension).
+// __assume does not evaluate its arguments, and should warn if its argument
+// has side effects.
+bool Sema::SemaBuiltinAssume(CallExpr *TheCall) {
+  Expr *Arg = TheCall->getArg(0);
+  if (Arg->isInstantiationDependent()) return false;
+
+  if (Arg->HasSideEffects(Context))
+    return Diag(Arg->getLocStart(), diag::warn_assume_side_effects)
+      << Arg->getSourceRange();
 
   return false;
 }
@@ -1918,27 +2053,24 @@
   return false;
 }
 
-/// SemaBuiltinObjectSize - Handle __builtin_object_size(void *ptr,
-/// int type). This simply type checks that type is one of the defined
-/// constants (0-3).
-// For compatibility check 0-3, llvm only handles 0 and 2.
-bool Sema::SemaBuiltinObjectSize(CallExpr *TheCall) {
+/// SemaBuiltinConstantArgRange - Handle a check if argument ArgNum of CallExpr
+/// TheCall is a constant expression in the range [Low, High].
+bool Sema::SemaBuiltinConstantArgRange(CallExpr *TheCall, int ArgNum,
+                                       int Low, int High) {
   llvm::APSInt Result;
 
   // We can't check the value of a dependent argument.
-  if (TheCall->getArg(1)->isTypeDependent() ||
-      TheCall->getArg(1)->isValueDependent())
+  Expr *Arg = TheCall->getArg(ArgNum);
+  if (Arg->isTypeDependent() || Arg->isValueDependent())
     return false;
 
   // Check constant-ness first.
-  if (SemaBuiltinConstantArg(TheCall, 1, Result))
+  if (SemaBuiltinConstantArg(TheCall, ArgNum, Result))
     return true;
 
-  Expr *Arg = TheCall->getArg(1);
-  if (Result.getSExtValue() < 0 || Result.getSExtValue() > 3) {
+  if (Result.getSExtValue() < Low || Result.getSExtValue() > High)
     return Diag(TheCall->getLocStart(), diag::err_argument_invalid_range)
-             << "0" << "3" << SourceRange(Arg->getLocStart(), Arg->getLocEnd());
-  }
+      << Low << High << Arg->getSourceRange();
 
   return false;
 }
@@ -2081,10 +2213,7 @@
         if (const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(VD)) {
           if (const NamedDecl *ND = dyn_cast<NamedDecl>(PV->getDeclContext())) {
             int PVIndex = PV->getFunctionScopeIndex() + 1;
-            for (specific_attr_iterator<FormatAttr>
-                 i = ND->specific_attr_begin<FormatAttr>(),
-                 e = ND->specific_attr_end<FormatAttr>(); i != e ; ++i) {
-              FormatAttr *PVFormat = *i;
+            for (const auto *PVFormat : ND->specific_attrs<FormatAttr>()) {
               // adjust for implicit parameter
               if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(ND))
                 if (MD->isInstance())
@@ -2133,30 +2262,9 @@
 
     return SLCT_NotALiteral;
   }
-      
-  case Stmt::ObjCMessageExprClass: {
-    const ObjCMessageExpr *ME = cast<ObjCMessageExpr>(E);
-    if (const ObjCMethodDecl *MDecl = ME->getMethodDecl()) {
-      if (const NamedDecl *ND = dyn_cast<NamedDecl>(MDecl)) {
-        if (const FormatArgAttr *FA = ND->getAttr<FormatArgAttr>()) {
-          unsigned ArgIndex = FA->getFormatIdx();
-          if (ArgIndex <= ME->getNumArgs()) {
-            const Expr *Arg = ME->getArg(ArgIndex-1);
-            return checkFormatStringExpr(S, Arg, Args,
-                                         HasVAListArg, format_idx,
-                                         firstDataArg, Type, CallType,
-                                         InFunctionCall, CheckedVarArgs);
-          }
-        }
-      }
-    }
-
-    return SLCT_NotALiteral;
-  }
-      
   case Stmt::ObjCStringLiteralClass:
   case Stmt::StringLiteralClass: {
-    const StringLiteral *StrE = NULL;
+    const StringLiteral *StrE = nullptr;
 
     if (const ObjCStringLiteral *ObjCFExpr = dyn_cast<ObjCStringLiteral>(E))
       StrE = ObjCFExpr->getString();
@@ -2177,32 +2285,6 @@
   }
 }
 
-void
-Sema::CheckNonNullArguments(const NonNullAttr *NonNull,
-                            const Expr * const *ExprArgs,
-                            SourceLocation CallSiteLoc) {
-  for (NonNullAttr::args_iterator i = NonNull->args_begin(),
-                                  e = NonNull->args_end();
-       i != e; ++i) {
-    const Expr *ArgExpr = ExprArgs[*i];
-
-    // As a special case, transparent unions initialized with zero are
-    // considered null for the purposes of the nonnull attribute.
-    if (const RecordType *UT = ArgExpr->getType()->getAsUnionType()) {
-      if (UT->getDecl()->hasAttr<TransparentUnionAttr>())
-        if (const CompoundLiteralExpr *CLE =
-            dyn_cast<CompoundLiteralExpr>(ArgExpr))
-          if (const InitListExpr *ILE =
-              dyn_cast<InitListExpr>(CLE->getInitializer()))
-            ArgExpr = ILE->getInit(0);
-    }
-
-    bool Result;
-    if (ArgExpr->EvaluateAsBooleanCondition(Result, Context) && !Result)
-      Diag(CallSiteLoc, diag::warn_null_arg) << ArgExpr->getSourceRange();
-  }
-}
-
 Sema::FormatStringType Sema::GetFormatStringType(const FormatAttr *Format) {
   return llvm::StringSwitch<FormatStringType>(Format->getType()->getName())
   .Case("scanf", FST_Scanf)
@@ -2331,30 +2413,31 @@
   void DoneProcessing();
 
   void HandleIncompleteSpecifier(const char *startSpecifier,
-                                 unsigned specifierLen);
+                                 unsigned specifierLen) override;
 
   void HandleInvalidLengthModifier(
-      const analyze_format_string::FormatSpecifier &FS,
-      const analyze_format_string::ConversionSpecifier &CS,
-      const char *startSpecifier, unsigned specifierLen, unsigned DiagID);
+                           const analyze_format_string::FormatSpecifier &FS,
+                           const analyze_format_string::ConversionSpecifier &CS,
+                           const char *startSpecifier, unsigned specifierLen,
+                           unsigned DiagID);
 
   void HandleNonStandardLengthModifier(
-      const analyze_format_string::FormatSpecifier &FS,
-      const char *startSpecifier, unsigned specifierLen);
+                    const analyze_format_string::FormatSpecifier &FS,
+                    const char *startSpecifier, unsigned specifierLen);
 
   void HandleNonStandardConversionSpecifier(
-      const analyze_format_string::ConversionSpecifier &CS,
-      const char *startSpecifier, unsigned specifierLen);
+                    const analyze_format_string::ConversionSpecifier &CS,
+                    const char *startSpecifier, unsigned specifierLen);
 
-  virtual void HandlePosition(const char *startPos, unsigned posLen);
+  void HandlePosition(const char *startPos, unsigned posLen) override;
 
-  virtual void HandleInvalidPosition(const char *startSpecifier,
-                                     unsigned specifierLen,
-                                     analyze_format_string::PositionContext p);
+  void HandleInvalidPosition(const char *startSpecifier,
+                             unsigned specifierLen,
+                             analyze_format_string::PositionContext p) override;
 
-  virtual void HandleZeroPosition(const char *startPos, unsigned posLen);
+  void HandleZeroPosition(const char *startPos, unsigned posLen) override;
 
-  void HandleNullChar(const char *nullCharacter);
+  void HandleNullChar(const char *nullCharacter) override;
 
   template <typename Range>
   static void EmitFormatDiagnostic(Sema &S, bool inFunctionCall,
@@ -2390,9 +2473,6 @@
   void EmitFormatDiagnostic(PartialDiagnostic PDiag, SourceLocation StringLoc,
                             bool IsStringLocation, Range StringRange,
                             ArrayRef<FixItHint> Fixit = None);
-
-  void CheckPositionalAndNonpositionalArgs(
-      const analyze_format_string::FormatSpecifier *FS);
 };
 }
 
@@ -2723,15 +2803,15 @@
       ObjCContext(isObjC)
   {}
 
-  
+
   bool HandleInvalidPrintfConversionSpecifier(
                                       const analyze_printf::PrintfSpecifier &FS,
                                       const char *startSpecifier,
-                                      unsigned specifierLen);
-  
+                                      unsigned specifierLen) override;
+
   bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier &FS,
                              const char *startSpecifier,
-                             unsigned specifierLen);
+                             unsigned specifierLen) override;
   bool checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
                        const char *StartSpecifier,
                        unsigned SpecifierLen,
@@ -2751,7 +2831,7 @@
                          const analyze_printf::OptionalFlag &flag,
                          const char *startSpecifier, unsigned specifierLen);
   bool checkForCStrMembers(const analyze_printf::ArgType &AT,
-                           const Expr *E, const CharSourceRange &CSR);
+                           const Expr *E);
 
 };  
 }
@@ -2885,11 +2965,12 @@
   if (!RT)
     return Results;
   const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
-  if (!RD)
+  if (!RD || !RD->getDefinition())
     return Results;
 
-  LookupResult R(S, &S.PP.getIdentifierTable().get(Name), SourceLocation(),
+  LookupResult R(S, &S.Context.Idents.get(Name), SourceLocation(),
                  Sema::LookupMemberName);
+  R.suppressDiagnostics();
 
   // We just need to include all members of the right kind turned up by the
   // filter, at this point.
@@ -2902,12 +2983,26 @@
   return Results;
 }
 
+/// Check if we could call '.c_str()' on an object.
+///
+/// FIXME: This returns the wrong results in some cases (if cv-qualifiers don't
+/// allow the call, or if it would be ambiguous).
+bool Sema::hasCStrMethod(const Expr *E) {
+  typedef llvm::SmallPtrSet<CXXMethodDecl*, 1> MethodSet;
+  MethodSet Results =
+      CXXRecordMembersNamed<CXXMethodDecl>("c_str", *this, E->getType());
+  for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
+       MI != ME; ++MI)
+    if ((*MI)->getMinRequiredArguments() == 0)
+      return true;
+  return false;
+}
+
 // Check if a (w)string was passed when a (w)char* was needed, and offer a
 // better diagnostic if so. AT is assumed to be valid.
 // Returns true when a c_str() conversion method is found.
 bool CheckPrintfHandler::checkForCStrMembers(
-    const analyze_printf::ArgType &AT, const Expr *E,
-    const CharSourceRange &CSR) {
+    const analyze_printf::ArgType &AT, const Expr *E) {
   typedef llvm::SmallPtrSet<CXXMethodDecl*, 1> MethodSet;
 
   MethodSet Results =
@@ -2916,11 +3011,10 @@
   for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
        MI != ME; ++MI) {
     const CXXMethodDecl *Method = *MI;
-    if (Method->getNumParams() == 0 &&
-          AT.matchesType(S.Context, Method->getResultType())) {
+    if (Method->getMinRequiredArguments() == 0 &&
+        AT.matchesType(S.Context, Method->getReturnType())) {
       // FIXME: Suggest parens if the expression needs them.
-      SourceLocation EndLoc =
-          S.getPreprocessor().getLocForEndOfToken(E->getLocEnd());
+      SourceLocation EndLoc = S.getLocForEndOfToken(E->getLocEnd());
       S.Diag(E->getLocStart(), diag::note_printf_c_str)
           << "c_str()"
           << FixItHint::CreateInsertion(EndLoc, ".c_str()");
@@ -3135,6 +3229,13 @@
         ExprTy = S.Context.CharTy;
   }
 
+  // Look through enums to their underlying type.
+  bool IsEnum = false;
+  if (auto EnumTy = ExprTy->getAs<EnumType>()) {
+    ExprTy = EnumTy->getDecl()->getIntegerType();
+    IsEnum = true;
+  }
+
   // %C in an Objective-C context prints a unichar, not a wchar_t.
   // If the argument is an integer of some kind, believe the %C and suggest
   // a cast instead of changing the conversion specifier.
@@ -3207,8 +3308,8 @@
       // In this case, the specifier is wrong and should be changed to match
       // the argument.
       EmitFormatDiagnostic(
-        S.PDiag(diag::warn_printf_conversion_argument_type_mismatch)
-          << AT.getRepresentativeTypeName(S.Context) << IntendedTy
+        S.PDiag(diag::warn_format_conversion_argument_type_mismatch)
+          << AT.getRepresentativeTypeName(S.Context) << IntendedTy << IsEnum
           << E->getSourceRange(),
         E->getLocStart(),
         /*IsStringLocation*/false,
@@ -3249,7 +3350,7 @@
         Hints.push_back(FixItHint::CreateInsertion(E->getLocStart(),
                                                    CastFix.str()));
 
-        SourceLocation After = S.PP.getLocForEndOfToken(E->getLocEnd());
+        SourceLocation After = S.getLocForEndOfToken(E->getLocEnd());
         Hints.push_back(FixItHint::CreateInsertion(After, ")"));
       }
 
@@ -3260,7 +3361,7 @@
         StringRef Name = cast<TypedefType>(ExprTy)->getDecl()->getName();
 
         EmitFormatDiagnostic(S.PDiag(diag::warn_format_argument_needs_cast)
-                               << Name << IntendedTy
+                               << Name << IntendedTy << IsEnum
                                << E->getSourceRange(),
                              E->getLocStart(), /*IsStringLocation=*/false,
                              SpecRange, Hints);
@@ -3269,8 +3370,8 @@
         // specifier, but we've decided that the specifier is probably correct 
         // and we should cast instead. Just use the normal warning message.
         EmitFormatDiagnostic(
-          S.PDiag(diag::warn_printf_conversion_argument_type_mismatch)
-            << AT.getRepresentativeTypeName(S.Context) << ExprTy
+          S.PDiag(diag::warn_format_conversion_argument_type_mismatch)
+            << AT.getRepresentativeTypeName(S.Context) << ExprTy << IsEnum
             << E->getSourceRange(),
           E->getLocStart(), /*IsStringLocation*/false,
           SpecRange, Hints);
@@ -3286,8 +3387,8 @@
     case Sema::VAK_Valid:
     case Sema::VAK_ValidInCXX11:
       EmitFormatDiagnostic(
-        S.PDiag(diag::warn_printf_conversion_argument_type_mismatch)
-          << AT.getRepresentativeTypeName(S.Context) << ExprTy
+        S.PDiag(diag::warn_format_conversion_argument_type_mismatch)
+          << AT.getRepresentativeTypeName(S.Context) << ExprTy << IsEnum
           << CSR
           << E->getSourceRange(),
         E->getLocStart(), /*IsStringLocation*/false, CSR);
@@ -3303,7 +3404,7 @@
           << CSR
           << E->getSourceRange(),
         E->getLocStart(), /*IsStringLocation*/false, CSR);
-      checkForCStrMembers(AT, E, CSR);
+      checkForCStrMembers(AT, E);
       break;
 
     case Sema::VAK_Invalid:
@@ -3355,14 +3456,14 @@
   
   bool HandleScanfSpecifier(const analyze_scanf::ScanfSpecifier &FS,
                             const char *startSpecifier,
-                            unsigned specifierLen);
+                            unsigned specifierLen) override;
   
   bool HandleInvalidScanfConversionSpecifier(
           const analyze_scanf::ScanfSpecifier &FS,
           const char *startSpecifier,
-          unsigned specifierLen);
+          unsigned specifierLen) override;
 
-  void HandleIncompleteScanList(const char *start, const char *end);
+  void HandleIncompleteScanList(const char *start, const char *end) override;
 };
 }
 
@@ -3467,8 +3568,9 @@
   const analyze_format_string::ArgType &AT = FS.getArgType(S.Context);
   if (AT.isValid() && !AT.matchesType(S.Context, Ex->getType())) {
     ScanfSpecifier fixedFS = FS;
-    bool success = fixedFS.fixType(Ex->getType(), S.getLangOpts(),
-                                   S.Context);
+    bool success = fixedFS.fixType(Ex->getType(),
+                                   Ex->IgnoreImpCasts()->getType(),
+                                   S.getLangOpts(), S.Context);
 
     if (success) {
       // Get the fix string from the fixed format specifier.
@@ -3477,8 +3579,8 @@
       fixedFS.toString(os);
 
       EmitFormatDiagnostic(
-        S.PDiag(diag::warn_printf_conversion_argument_type_mismatch)
-          << AT.getRepresentativeTypeName(S.Context) << Ex->getType()
+        S.PDiag(diag::warn_format_conversion_argument_type_mismatch)
+          << AT.getRepresentativeTypeName(S.Context) << Ex->getType() << false
           << Ex->getSourceRange(),
         Ex->getLocStart(),
         /*IsStringLocation*/false,
@@ -3488,8 +3590,8 @@
           os.str()));
     } else {
       EmitFormatDiagnostic(
-        S.PDiag(diag::warn_printf_conversion_argument_type_mismatch)
-          << AT.getRepresentativeTypeName(S.Context) << Ex->getType()
+        S.PDiag(diag::warn_format_conversion_argument_type_mismatch)
+          << AT.getRepresentativeTypeName(S.Context) << Ex->getType() << false
           << Ex->getSourceRange(),
         Ex->getLocStart(),
         /*IsStringLocation*/false,
@@ -3520,9 +3622,25 @@
   // Str - The format string.  NOTE: this is NOT null-terminated!
   StringRef StrRef = FExpr->getString();
   const char *Str = StrRef.data();
-  unsigned StrLen = StrRef.size();
+  // Account for cases where the string literal is truncated in a declaration.
+  const ConstantArrayType *T = Context.getAsConstantArrayType(FExpr->getType());
+  assert(T && "String literal not of constant array type!");
+  size_t TypeSize = T->getSize().getZExtValue();
+  size_t StrLen = std::min(std::max(TypeSize, size_t(1)) - 1, StrRef.size());
   const unsigned numDataArgs = Args.size() - firstDataArg;
-  
+
+  // Emit a warning if the string literal is truncated and does not contain an
+  // embedded null character.
+  if (TypeSize <= StrRef.size() &&
+      StrRef.substr(0, TypeSize).find('\0') == StringRef::npos) {
+    CheckFormatHandler::EmitFormatDiagnostic(
+        *this, inFunctionCall, Args[format_idx],
+        PDiag(diag::warn_printf_format_string_not_null_terminated),
+        FExpr->getLocStart(),
+        /*IsStringLocation=*/true, OrigFormatExpr->getSourceRange());
+    return;
+  }
+
   // CHECK: empty format string?
   if (StrLen == 0 && numDataArgs > 0) {
     CheckFormatHandler::EmitFormatDiagnostic(
@@ -3554,17 +3672,452 @@
   } // TODO: handle other formats
 }
 
+//===--- CHECK: Warn on use of wrong absolute value function. -------------===//
+
+// Returns the related absolute value function that is larger, of 0 if one
+// does not exist.
+static unsigned getLargerAbsoluteValueFunction(unsigned AbsFunction) {
+  switch (AbsFunction) {
+  default:
+    return 0;
+
+  case Builtin::BI__builtin_abs:
+    return Builtin::BI__builtin_labs;
+  case Builtin::BI__builtin_labs:
+    return Builtin::BI__builtin_llabs;
+  case Builtin::BI__builtin_llabs:
+    return 0;
+
+  case Builtin::BI__builtin_fabsf:
+    return Builtin::BI__builtin_fabs;
+  case Builtin::BI__builtin_fabs:
+    return Builtin::BI__builtin_fabsl;
+  case Builtin::BI__builtin_fabsl:
+    return 0;
+
+  case Builtin::BI__builtin_cabsf:
+    return Builtin::BI__builtin_cabs;
+  case Builtin::BI__builtin_cabs:
+    return Builtin::BI__builtin_cabsl;
+  case Builtin::BI__builtin_cabsl:
+    return 0;
+
+  case Builtin::BIabs:
+    return Builtin::BIlabs;
+  case Builtin::BIlabs:
+    return Builtin::BIllabs;
+  case Builtin::BIllabs:
+    return 0;
+
+  case Builtin::BIfabsf:
+    return Builtin::BIfabs;
+  case Builtin::BIfabs:
+    return Builtin::BIfabsl;
+  case Builtin::BIfabsl:
+    return 0;
+
+  case Builtin::BIcabsf:
+   return Builtin::BIcabs;
+  case Builtin::BIcabs:
+    return Builtin::BIcabsl;
+  case Builtin::BIcabsl:
+    return 0;
+  }
+}
+
+// Returns the argument type of the absolute value function.
+static QualType getAbsoluteValueArgumentType(ASTContext &Context,
+                                             unsigned AbsType) {
+  if (AbsType == 0)
+    return QualType();
+
+  ASTContext::GetBuiltinTypeError Error = ASTContext::GE_None;
+  QualType BuiltinType = Context.GetBuiltinType(AbsType, Error);
+  if (Error != ASTContext::GE_None)
+    return QualType();
+
+  const FunctionProtoType *FT = BuiltinType->getAs<FunctionProtoType>();
+  if (!FT)
+    return QualType();
+
+  if (FT->getNumParams() != 1)
+    return QualType();
+
+  return FT->getParamType(0);
+}
+
+// Returns the best absolute value function, or zero, based on type and
+// current absolute value function.
+static unsigned getBestAbsFunction(ASTContext &Context, QualType ArgType,
+                                   unsigned AbsFunctionKind) {
+  unsigned BestKind = 0;
+  uint64_t ArgSize = Context.getTypeSize(ArgType);
+  for (unsigned Kind = AbsFunctionKind; Kind != 0;
+       Kind = getLargerAbsoluteValueFunction(Kind)) {
+    QualType ParamType = getAbsoluteValueArgumentType(Context, Kind);
+    if (Context.getTypeSize(ParamType) >= ArgSize) {
+      if (BestKind == 0)
+        BestKind = Kind;
+      else if (Context.hasSameType(ParamType, ArgType)) {
+        BestKind = Kind;
+        break;
+      }
+    }
+  }
+  return BestKind;
+}
+
+enum AbsoluteValueKind {
+  AVK_Integer,
+  AVK_Floating,
+  AVK_Complex
+};
+
+static AbsoluteValueKind getAbsoluteValueKind(QualType T) {
+  if (T->isIntegralOrEnumerationType())
+    return AVK_Integer;
+  if (T->isRealFloatingType())
+    return AVK_Floating;
+  if (T->isAnyComplexType())
+    return AVK_Complex;
+
+  llvm_unreachable("Type not integer, floating, or complex");
+}
+
+// Changes the absolute value function to a different type.  Preserves whether
+// the function is a builtin.
+static unsigned changeAbsFunction(unsigned AbsKind,
+                                  AbsoluteValueKind ValueKind) {
+  switch (ValueKind) {
+  case AVK_Integer:
+    switch (AbsKind) {
+    default:
+      return 0;
+    case Builtin::BI__builtin_fabsf:
+    case Builtin::BI__builtin_fabs:
+    case Builtin::BI__builtin_fabsl:
+    case Builtin::BI__builtin_cabsf:
+    case Builtin::BI__builtin_cabs:
+    case Builtin::BI__builtin_cabsl:
+      return Builtin::BI__builtin_abs;
+    case Builtin::BIfabsf:
+    case Builtin::BIfabs:
+    case Builtin::BIfabsl:
+    case Builtin::BIcabsf:
+    case Builtin::BIcabs:
+    case Builtin::BIcabsl:
+      return Builtin::BIabs;
+    }
+  case AVK_Floating:
+    switch (AbsKind) {
+    default:
+      return 0;
+    case Builtin::BI__builtin_abs:
+    case Builtin::BI__builtin_labs:
+    case Builtin::BI__builtin_llabs:
+    case Builtin::BI__builtin_cabsf:
+    case Builtin::BI__builtin_cabs:
+    case Builtin::BI__builtin_cabsl:
+      return Builtin::BI__builtin_fabsf;
+    case Builtin::BIabs:
+    case Builtin::BIlabs:
+    case Builtin::BIllabs:
+    case Builtin::BIcabsf:
+    case Builtin::BIcabs:
+    case Builtin::BIcabsl:
+      return Builtin::BIfabsf;
+    }
+  case AVK_Complex:
+    switch (AbsKind) {
+    default:
+      return 0;
+    case Builtin::BI__builtin_abs:
+    case Builtin::BI__builtin_labs:
+    case Builtin::BI__builtin_llabs:
+    case Builtin::BI__builtin_fabsf:
+    case Builtin::BI__builtin_fabs:
+    case Builtin::BI__builtin_fabsl:
+      return Builtin::BI__builtin_cabsf;
+    case Builtin::BIabs:
+    case Builtin::BIlabs:
+    case Builtin::BIllabs:
+    case Builtin::BIfabsf:
+    case Builtin::BIfabs:
+    case Builtin::BIfabsl:
+      return Builtin::BIcabsf;
+    }
+  }
+  llvm_unreachable("Unable to convert function");
+}
+
+static unsigned getAbsoluteValueFunctionKind(const FunctionDecl *FDecl) {
+  const IdentifierInfo *FnInfo = FDecl->getIdentifier();
+  if (!FnInfo)
+    return 0;
+
+  switch (FDecl->getBuiltinID()) {
+  default:
+    return 0;
+  case Builtin::BI__builtin_abs:
+  case Builtin::BI__builtin_fabs:
+  case Builtin::BI__builtin_fabsf:
+  case Builtin::BI__builtin_fabsl:
+  case Builtin::BI__builtin_labs:
+  case Builtin::BI__builtin_llabs:
+  case Builtin::BI__builtin_cabs:
+  case Builtin::BI__builtin_cabsf:
+  case Builtin::BI__builtin_cabsl:
+  case Builtin::BIabs:
+  case Builtin::BIlabs:
+  case Builtin::BIllabs:
+  case Builtin::BIfabs:
+  case Builtin::BIfabsf:
+  case Builtin::BIfabsl:
+  case Builtin::BIcabs:
+  case Builtin::BIcabsf:
+  case Builtin::BIcabsl:
+    return FDecl->getBuiltinID();
+  }
+  llvm_unreachable("Unknown Builtin type");
+}
+
+// If the replacement is valid, emit a note with replacement function.
+// Additionally, suggest including the proper header if not already included.
+static void emitReplacement(Sema &S, SourceLocation Loc, SourceRange Range,
+                            unsigned AbsKind, QualType ArgType) {
+  bool EmitHeaderHint = true;
+  const char *HeaderName = nullptr;
+  const char *FunctionName = nullptr;
+  if (S.getLangOpts().CPlusPlus && !ArgType->isAnyComplexType()) {
+    FunctionName = "std::abs";
+    if (ArgType->isIntegralOrEnumerationType()) {
+      HeaderName = "cstdlib";
+    } else if (ArgType->isRealFloatingType()) {
+      HeaderName = "cmath";
+    } else {
+      llvm_unreachable("Invalid Type");
+    }
+
+    // Lookup all std::abs
+    if (NamespaceDecl *Std = S.getStdNamespace()) {
+      LookupResult R(S, &S.Context.Idents.get("abs"), Loc, Sema::LookupAnyName);
+      R.suppressDiagnostics();
+      S.LookupQualifiedName(R, Std);
+
+      for (const auto *I : R) {
+        const FunctionDecl *FDecl = nullptr;
+        if (const UsingShadowDecl *UsingD = dyn_cast<UsingShadowDecl>(I)) {
+          FDecl = dyn_cast<FunctionDecl>(UsingD->getTargetDecl());
+        } else {
+          FDecl = dyn_cast<FunctionDecl>(I);
+        }
+        if (!FDecl)
+          continue;
+
+        // Found std::abs(), check that they are the right ones.
+        if (FDecl->getNumParams() != 1)
+          continue;
+
+        // Check that the parameter type can handle the argument.
+        QualType ParamType = FDecl->getParamDecl(0)->getType();
+        if (getAbsoluteValueKind(ArgType) == getAbsoluteValueKind(ParamType) &&
+            S.Context.getTypeSize(ArgType) <=
+                S.Context.getTypeSize(ParamType)) {
+          // Found a function, don't need the header hint.
+          EmitHeaderHint = false;
+          break;
+        }
+      }
+    }
+  } else {
+    FunctionName = S.Context.BuiltinInfo.GetName(AbsKind);
+    HeaderName = S.Context.BuiltinInfo.getHeaderName(AbsKind);
+
+    if (HeaderName) {
+      DeclarationName DN(&S.Context.Idents.get(FunctionName));
+      LookupResult R(S, DN, Loc, Sema::LookupAnyName);
+      R.suppressDiagnostics();
+      S.LookupName(R, S.getCurScope());
+
+      if (R.isSingleResult()) {
+        FunctionDecl *FD = dyn_cast<FunctionDecl>(R.getFoundDecl());
+        if (FD && FD->getBuiltinID() == AbsKind) {
+          EmitHeaderHint = false;
+        } else {
+          return;
+        }
+      } else if (!R.empty()) {
+        return;
+      }
+    }
+  }
+
+  S.Diag(Loc, diag::note_replace_abs_function)
+      << FunctionName << FixItHint::CreateReplacement(Range, FunctionName);
+
+  if (!HeaderName)
+    return;
+
+  if (!EmitHeaderHint)
+    return;
+
+  S.Diag(Loc, diag::note_include_header_or_declare) << HeaderName
+                                                    << FunctionName;
+}
+
+static bool IsFunctionStdAbs(const FunctionDecl *FDecl) {
+  if (!FDecl)
+    return false;
+
+  if (!FDecl->getIdentifier() || !FDecl->getIdentifier()->isStr("abs"))
+    return false;
+
+  const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(FDecl->getDeclContext());
+
+  while (ND && ND->isInlineNamespace()) {
+    ND = dyn_cast<NamespaceDecl>(ND->getDeclContext());
+  }
+
+  if (!ND || !ND->getIdentifier() || !ND->getIdentifier()->isStr("std"))
+    return false;
+
+  if (!isa<TranslationUnitDecl>(ND->getDeclContext()))
+    return false;
+
+  return true;
+}
+
+// Warn when using the wrong abs() function.
+void Sema::CheckAbsoluteValueFunction(const CallExpr *Call,
+                                      const FunctionDecl *FDecl,
+                                      IdentifierInfo *FnInfo) {
+  if (Call->getNumArgs() != 1)
+    return;
+
+  unsigned AbsKind = getAbsoluteValueFunctionKind(FDecl);
+  bool IsStdAbs = IsFunctionStdAbs(FDecl);
+  if (AbsKind == 0 && !IsStdAbs)
+    return;
+
+  QualType ArgType = Call->getArg(0)->IgnoreParenImpCasts()->getType();
+  QualType ParamType = Call->getArg(0)->getType();
+
+  // Unsigned types cannot be negative.  Suggest removing the absolute value
+  // function call.
+  if (ArgType->isUnsignedIntegerType()) {
+    const char *FunctionName =
+        IsStdAbs ? "std::abs" : Context.BuiltinInfo.GetName(AbsKind);
+    Diag(Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;
+    Diag(Call->getExprLoc(), diag::note_remove_abs)
+        << FunctionName
+        << FixItHint::CreateRemoval(Call->getCallee()->getSourceRange());
+    return;
+  }
+
+  // std::abs has overloads which prevent most of the absolute value problems
+  // from occurring.
+  if (IsStdAbs)
+    return;
+
+  AbsoluteValueKind ArgValueKind = getAbsoluteValueKind(ArgType);
+  AbsoluteValueKind ParamValueKind = getAbsoluteValueKind(ParamType);
+
+  // The argument and parameter are the same kind.  Check if they are the right
+  // size.
+  if (ArgValueKind == ParamValueKind) {
+    if (Context.getTypeSize(ArgType) <= Context.getTypeSize(ParamType))
+      return;
+
+    unsigned NewAbsKind = getBestAbsFunction(Context, ArgType, AbsKind);
+    Diag(Call->getExprLoc(), diag::warn_abs_too_small)
+        << FDecl << ArgType << ParamType;
+
+    if (NewAbsKind == 0)
+      return;
+
+    emitReplacement(*this, Call->getExprLoc(),
+                    Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
+    return;
+  }
+
+  // ArgValueKind != ParamValueKind
+  // The wrong type of absolute value function was used.  Attempt to find the
+  // proper one.
+  unsigned NewAbsKind = changeAbsFunction(AbsKind, ArgValueKind);
+  NewAbsKind = getBestAbsFunction(Context, ArgType, NewAbsKind);
+  if (NewAbsKind == 0)
+    return;
+
+  Diag(Call->getExprLoc(), diag::warn_wrong_absolute_value_type)
+      << FDecl << ParamValueKind << ArgValueKind;
+
+  emitReplacement(*this, Call->getExprLoc(),
+                  Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
+  return;
+}
+
 //===--- CHECK: Standard memory functions ---------------------------------===//
 
-/// \brief Determine whether the given type is a dynamic class type (e.g.,
-/// whether it has a vtable).
-static bool isDynamicClassType(QualType T) {
-  if (CXXRecordDecl *Record = T->getAsCXXRecordDecl())
-    if (CXXRecordDecl *Definition = Record->getDefinition())
-      if (Definition->isDynamicClass())
-        return true;
-  
-  return false;
+/// \brief Takes the expression passed to the size_t parameter of functions
+/// such as memcmp, strncat, etc and warns if it's a comparison.
+///
+/// This is to catch typos like `if (memcmp(&a, &b, sizeof(a) > 0))`.
+static bool CheckMemorySizeofForComparison(Sema &S, const Expr *E,
+                                           IdentifierInfo *FnName,
+                                           SourceLocation FnLoc,
+                                           SourceLocation RParenLoc) {
+  const BinaryOperator *Size = dyn_cast<BinaryOperator>(E);
+  if (!Size)
+    return false;
+
+  // if E is binop and op is >, <, >=, <=, ==, &&, ||:
+  if (!Size->isComparisonOp() && !Size->isEqualityOp() && !Size->isLogicalOp())
+    return false;
+
+  SourceRange SizeRange = Size->getSourceRange();
+  S.Diag(Size->getOperatorLoc(), diag::warn_memsize_comparison)
+      << SizeRange << FnName;
+  S.Diag(FnLoc, diag::note_memsize_comparison_paren)
+      << FnName << FixItHint::CreateInsertion(
+                       S.getLocForEndOfToken(Size->getLHS()->getLocEnd()), ")")
+      << FixItHint::CreateRemoval(RParenLoc);
+  S.Diag(SizeRange.getBegin(), diag::note_memsize_comparison_cast_silence)
+      << FixItHint::CreateInsertion(SizeRange.getBegin(), "(size_t)(")
+      << FixItHint::CreateInsertion(S.getLocForEndOfToken(SizeRange.getEnd()),
+                                    ")");
+
+  return true;
+}
+
+/// \brief Determine whether the given type is or contains a dynamic class type
+/// (e.g., whether it has a vtable).
+static const CXXRecordDecl *getContainedDynamicClass(QualType T,
+                                                     bool &IsContained) {
+  // Look through array types while ignoring qualifiers.
+  const Type *Ty = T->getBaseElementTypeUnsafe();
+  IsContained = false;
+
+  const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();
+  RD = RD ? RD->getDefinition() : nullptr;
+  if (!RD)
+    return nullptr;
+
+  if (RD->isDynamicClass())
+    return RD;
+
+  // Check all the fields.  If any bases were dynamic, the class is dynamic.
+  // It's impossible for a class to transitively contain itself by value, so
+  // infinite recursion is impossible.
+  for (auto *FD : RD->fields()) {
+    bool SubContained;
+    if (const CXXRecordDecl *ContainedRD =
+            getContainedDynamicClass(FD->getType(), SubContained)) {
+      IsContained = true;
+      return ContainedRD;
+    }
+  }
+
+  return nullptr;
 }
 
 /// \brief If E is a sizeof expression, returns its argument expression,
@@ -3575,7 +4128,7 @@
     if (SizeOf->getKind() == clang::UETT_SizeOf && !SizeOf->isArgumentType())
       return SizeOf->getArgumentExpr()->IgnoreParenImpCasts();
 
-  return 0;
+  return nullptr;
 }
 
 /// \brief If E is a sizeof expression, returns its argument type.
@@ -3611,6 +4164,10 @@
   unsigned LenArg = (BId == Builtin::BIstrndup ? 1 : 2);
   const Expr *LenExpr = Call->getArg(LenArg)->IgnoreParenImpCasts();
 
+  if (CheckMemorySizeofForComparison(*this, LenExpr, FnName,
+                                     Call->getLocStart(), Call->getRParenLoc()))
+    return;
+
   // We have special checking when the length is a sizeof expression.
   QualType SizeOfArgTy = getSizeOfArgType(LenExpr);
   const Expr *SizeOfArg = getSizeOfExprArg(LenExpr);
@@ -3634,8 +4191,8 @@
       // expression IDs can be expensive, we only do this if the diagnostic is
       // enabled.
       if (SizeOfArg &&
-          Diags.getDiagnosticLevel(diag::warn_sizeof_pointer_expr_memaccess,
-                                   SizeOfArg->getExprLoc())) {
+          !Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess,
+                           SizeOfArg->getExprLoc())) {
         // We only compute IDs for expressions if the warning is enabled, and
         // cache the sizeof arg's ID.
         if (SizeOfArgID == llvm::FoldingSetNodeID())
@@ -3661,7 +4218,7 @@
           SourceLocation SL = SizeOfArg->getExprLoc();
           SourceRange DSR = Dest->getSourceRange();
           SourceRange SSR = SizeOfArg->getSourceRange();
-          SourceManager &SM  = PP.getSourceManager();
+          SourceManager &SM = getSourceManager();
 
           if (SM.isMacroArgExpansion(SL)) {
             ReadableName = Lexer::getImmediateMacroName(SL, SM, LangOpts);
@@ -3704,7 +4261,9 @@
       }
 
       // Always complain about dynamic classes.
-      if (isDynamicClassType(PointeeTy)) {
+      bool IsContained;
+      if (const CXXRecordDecl *ContainedRD =
+              getContainedDynamicClass(PointeeTy, IsContained)) {
 
         unsigned OperationType = 0;
         // "overwritten" if we're warning about the destination for any call
@@ -3722,8 +4281,7 @@
           Dest->getExprLoc(), Dest,
           PDiag(diag::warn_dyn_class_memaccess)
             << (BId == Builtin::BImemcmp ? ArgIdx + 2 : ArgIdx)
-            << FnName << PointeeTy
-            << OperationType
+            << FnName << IsContained << ContainedRD << OperationType
             << Call->getCallee()->getSourceRange());
       } else if (PointeeTy.hasNonTrivialObjCLifetime() &&
                BId != Builtin::BImemset)
@@ -3793,7 +4351,11 @@
 
   const Expr *SrcArg = ignoreLiteralAdditions(Call->getArg(1), Context);
   const Expr *SizeArg = ignoreLiteralAdditions(Call->getArg(2), Context);
-  const Expr *CompareWithSrc = NULL;
+  const Expr *CompareWithSrc = nullptr;
+
+  if (CheckMemorySizeofForComparison(*this, SizeArg, FnName,
+                                     Call->getLocStart(), Call->getRParenLoc()))
+    return;
   
   // Look for 'strlcpy(dst, x, sizeof(x))'
   if (const Expr *Ex = getSizeOfExprArg(SizeArg))
@@ -3801,8 +4363,8 @@
   else {
     // Look for 'strlcpy(dst, x, strlen(x))'
     if (const CallExpr *SizeCall = dyn_cast<CallExpr>(SizeArg)) {
-      if (SizeCall->isBuiltinCall() == Builtin::BIstrlen
-          && SizeCall->getNumArgs() == 1)
+      if (SizeCall->getBuiltinCallee() == Builtin::BIstrlen &&
+          SizeCall->getNumArgs() == 1)
         CompareWithSrc = ignoreLiteralAdditions(SizeCall->getArg(0), Context);
     }
   }
@@ -3838,7 +4400,7 @@
   SmallString<128> sizeString;
   llvm::raw_svector_ostream OS(sizeString);
   OS << "sizeof(";
-  DstArg->printPretty(OS, 0, getPrintingPolicy());
+  DstArg->printPretty(OS, nullptr, getPrintingPolicy());
   OS << ")";
   
   Diag(OriginalSizeArg->getLocStart(), diag::note_strlcpycat_wrong_size)
@@ -3858,10 +4420,10 @@
   if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
     const FunctionDecl *FD = CE->getDirectCallee();
     if (!FD || FD->getMemoryFunctionKind() != Builtin::BIstrlen)
-      return 0;
+      return nullptr;
     return CE->getArg(0)->IgnoreParenCasts();
   }
-  return 0;
+  return nullptr;
 }
 
 // Warn on anti-patterns as the 'size' argument to strncat.
@@ -3876,6 +4438,10 @@
   const Expr *SrcArg = CE->getArg(1)->IgnoreParenCasts();
   const Expr *LenArg = CE->getArg(2)->IgnoreParenCasts();
 
+  if (CheckMemorySizeofForComparison(*this, LenArg, FnName, CE->getLocStart(),
+                                     CE->getRParenLoc()))
+    return;
+
   // Identify common expressions, which are wrongly used as the size argument
   // to strncat and may lead to buffer overflows.
   unsigned PatternType = 0;
@@ -3906,7 +4472,7 @@
   // Generate the diagnostic.
   SourceLocation SL = LenArg->getLocStart();
   SourceRange SR = LenArg->getSourceRange();
-  SourceManager &SM  = PP.getSourceManager();
+  SourceManager &SM = getSourceManager();
 
   // If the function is defined as a builtin macro, do not show macro expansion.
   if (SM.isMacroArgExpansion(SL)) {
@@ -3935,10 +4501,10 @@
   SmallString<128> sizeString;
   llvm::raw_svector_ostream OS(sizeString);
   OS << "sizeof(";
-  DstArg->printPretty(OS, 0, getPrintingPolicy());
+  DstArg->printPretty(OS, nullptr, getPrintingPolicy());
   OS << ") - ";
   OS << "strlen(";
-  DstArg->printPretty(OS, 0, getPrintingPolicy());
+  DstArg->printPretty(OS, nullptr, getPrintingPolicy());
   OS << ") - 1";
 
   Diag(SL, diag::note_strncat_wrong_size)
@@ -3954,23 +4520,23 @@
 
 /// CheckReturnStackAddr - Check if a return statement returns the address
 ///   of a stack variable.
-void
-Sema::CheckReturnStackAddr(Expr *RetValExp, QualType lhsType,
-                           SourceLocation ReturnLoc) {
+static void
+CheckReturnStackAddr(Sema &S, Expr *RetValExp, QualType lhsType,
+                     SourceLocation ReturnLoc) {
 
-  Expr *stackE = 0;
+  Expr *stackE = nullptr;
   SmallVector<DeclRefExpr *, 8> refVars;
 
   // Perform checking for returned stack addresses, local blocks,
   // label addresses or references to temporaries.
   if (lhsType->isPointerType() ||
-      (!getLangOpts().ObjCAutoRefCount && lhsType->isBlockPointerType())) {
-    stackE = EvalAddr(RetValExp, refVars, /*ParentDecl=*/0);
+      (!S.getLangOpts().ObjCAutoRefCount && lhsType->isBlockPointerType())) {
+    stackE = EvalAddr(RetValExp, refVars, /*ParentDecl=*/nullptr);
   } else if (lhsType->isReferenceType()) {
-    stackE = EvalVal(RetValExp, refVars, /*ParentDecl=*/0);
+    stackE = EvalVal(RetValExp, refVars, /*ParentDecl=*/nullptr);
   }
 
-  if (stackE == 0)
+  if (!stackE)
     return; // Nothing suspicious was found.
 
   SourceLocation diagLoc;
@@ -3988,16 +4554,16 @@
   }
 
   if (DeclRefExpr *DR = dyn_cast<DeclRefExpr>(stackE)) { //address of local var.
-    Diag(diagLoc, lhsType->isReferenceType() ? diag::warn_ret_stack_ref
+    S.Diag(diagLoc, lhsType->isReferenceType() ? diag::warn_ret_stack_ref
                                              : diag::warn_ret_stack_addr)
      << DR->getDecl()->getDeclName() << diagRange;
   } else if (isa<BlockExpr>(stackE)) { // local block.
-    Diag(diagLoc, diag::err_ret_local_block) << diagRange;
+    S.Diag(diagLoc, diag::err_ret_local_block) << diagRange;
   } else if (isa<AddrLabelExpr>(stackE)) { // address of label.
-    Diag(diagLoc, diag::warn_ret_addr_label) << diagRange;
+    S.Diag(diagLoc, diag::warn_ret_addr_label) << diagRange;
   } else { // local temporary.
-    Diag(diagLoc, lhsType->isReferenceType() ? diag::warn_ret_local_temp_ref
-                                             : diag::warn_ret_local_temp_addr)
+    S.Diag(diagLoc, lhsType->isReferenceType() ? diag::warn_ret_local_temp_ref
+                                               : diag::warn_ret_local_temp_addr)
      << diagRange;
   }
 
@@ -4010,8 +4576,8 @@
     // show the range of the expression.
     SourceRange range = (i < e-1) ? refVars[i+1]->getSourceRange()
                                   : stackE->getSourceRange();
-    Diag(VD->getLocation(), diag::note_ref_var_local_bind)
-      << VD->getDeclName() << range;
+    S.Diag(VD->getLocation(), diag::note_ref_var_local_bind)
+        << VD->getDeclName() << range;
   }
 }
 
@@ -4044,7 +4610,7 @@
 static Expr *EvalAddr(Expr *E, SmallVectorImpl<DeclRefExpr *> &refVars,
                       Decl *ParentDecl) {
   if (E->isTypeDependent())
-    return NULL;
+    return nullptr;
 
   // We should only be called for evaluating pointer expressions.
   assert((E->getType()->isAnyPointerType() ||
@@ -4061,6 +4627,10 @@
   case Stmt::DeclRefExprClass: {
     DeclRefExpr *DR = cast<DeclRefExpr>(E);
 
+    // If we leave the immediate function, the lifetime isn't about to end.
+    if (DR->refersToEnclosingLocal())
+      return nullptr;
+
     if (VarDecl *V = dyn_cast<VarDecl>(DR->getDecl()))
       // If this is a reference variable, follow through to the expression that
       // it points to.
@@ -4071,7 +4641,7 @@
         return EvalAddr(V->getInit(), refVars, ParentDecl);
       }
 
-    return NULL;
+    return nullptr;
   }
 
   case Stmt::UnaryOperatorClass: {
@@ -4082,7 +4652,7 @@
     if (U->getOpcode() == UO_AddrOf)
       return EvalVal(U->getSubExpr(), refVars, ParentDecl);
     else
-      return NULL;
+      return nullptr;
   }
 
   case Stmt::BinaryOperatorClass: {
@@ -4092,7 +4662,7 @@
     BinaryOperatorKind op = B->getOpcode();
 
     if (op != BO_Add && op != BO_Sub)
-      return NULL;
+      return nullptr;
 
     Expr *Base = B->getLHS();
 
@@ -4110,24 +4680,25 @@
     ConditionalOperator *C = cast<ConditionalOperator>(E);
 
     // Handle the GNU extension for missing LHS.
-    if (Expr *lhsExpr = C->getLHS()) {
-    // In C++, we can have a throw-expression, which has 'void' type.
-      if (!lhsExpr->getType()->isVoidType())
-        if (Expr* LHS = EvalAddr(lhsExpr, refVars, ParentDecl))
+    // FIXME: That isn't a ConditionalOperator, so doesn't get here.
+    if (Expr *LHSExpr = C->getLHS()) {
+      // In C++, we can have a throw-expression, which has 'void' type.
+      if (!LHSExpr->getType()->isVoidType())
+        if (Expr *LHS = EvalAddr(LHSExpr, refVars, ParentDecl))
           return LHS;
     }
 
     // In C++, we can have a throw-expression, which has 'void' type.
     if (C->getRHS()->getType()->isVoidType())
-      return NULL;
+      return nullptr;
 
     return EvalAddr(C->getRHS(), refVars, ParentDecl);
   }
-  
+
   case Stmt::BlockExprClass:
     if (cast<BlockExpr>(E)->getBlockDecl()->hasCaptures())
       return E; // local block.
-    return NULL;
+    return nullptr;
 
   case Stmt::AddrLabelExprClass:
     return E; // address of label.
@@ -4148,7 +4719,6 @@
   case Stmt::CXXReinterpretCastExprClass: {
     Expr* SubExpr = cast<CastExpr>(E)->getSubExpr();
     switch (cast<CastExpr>(E)->getCastKind()) {
-    case CK_BitCast:
     case CK_LValueToRValue:
     case CK_NoOp:
     case CK_BaseToDerived:
@@ -4163,8 +4733,16 @@
     case CK_ArrayToPointerDecay:
       return EvalVal(SubExpr, refVars, ParentDecl);
 
+    case CK_BitCast:
+      if (SubExpr->getType()->isAnyPointerType() ||
+          SubExpr->getType()->isBlockPointerType() ||
+          SubExpr->getType()->isObjCQualifiedIdType())
+        return EvalAddr(SubExpr, refVars, ParentDecl);
+      else
+        return nullptr;
+
     default:
-      return 0;
+      return nullptr;
     }
   }
 
@@ -4178,7 +4756,7 @@
       
   // Everything else: we simply don't reason about them.
   default:
-    return NULL;
+    return nullptr;
   }
 }
 
@@ -4204,7 +4782,7 @@
       E = IE->getSubExpr();
       continue;
     }
-    return NULL;
+    return nullptr;
   }
 
   case Stmt::ExprWithCleanupsClass:
@@ -4216,6 +4794,10 @@
     // local storage within the function, and if so, return the expression.
     DeclRefExpr *DR = cast<DeclRefExpr>(E);
 
+    // If we leave the immediate function, the lifetime isn't about to end.
+    if (DR->refersToEnclosingLocal())
+      return nullptr;
+
     if (VarDecl *V = dyn_cast<VarDecl>(DR->getDecl())) {
       // Check if it refers to itself, e.g. "int& i = i;".
       if (V == ParentDecl)
@@ -4235,7 +4817,7 @@
       }
     }
 
-    return NULL;
+    return nullptr;
   }
 
   case Stmt::UnaryOperatorClass: {
@@ -4247,7 +4829,7 @@
     if (U->getOpcode() == UO_Deref)
       return EvalAddr(U->getSubExpr(), refVars, ParentDecl);
 
-    return NULL;
+    return nullptr;
   }
 
   case Stmt::ArraySubscriptExprClass: {
@@ -4263,9 +4845,16 @@
     ConditionalOperator *C = cast<ConditionalOperator>(E);
 
     // Handle the GNU extension for missing LHS.
-    if (Expr *lhsExpr = C->getLHS())
-      if (Expr *LHS = EvalVal(lhsExpr, refVars, ParentDecl))
-        return LHS;
+    if (Expr *LHSExpr = C->getLHS()) {
+      // In C++, we can have a throw-expression, which has 'void' type.
+      if (!LHSExpr->getType()->isVoidType())
+        if (Expr *LHS = EvalVal(LHSExpr, refVars, ParentDecl))
+          return LHS;
+    }
+
+    // In C++, we can have a throw-expression, which has 'void' type.
+    if (C->getRHS()->getType()->isVoidType())
+      return nullptr;
 
     return EvalVal(C->getRHS(), refVars, ParentDecl);
   }
@@ -4276,12 +4865,12 @@
 
     // Check for indirect access.  We only want direct field accesses.
     if (M->isArrow())
-      return NULL;
+      return nullptr;
 
     // Check whether the member type is itself a reference, in which case
     // we're not going to refer to the member, but to what the member refers to.
     if (M->getMemberDecl()->getType()->isReferenceType())
-      return NULL;
+      return nullptr;
 
     return EvalVal(M->getBase(), refVars, ParentDecl);
   }
@@ -4301,11 +4890,43 @@
       return E;
 
     // Everything else: we simply don't reason about them.
-    return NULL;
+    return nullptr;
   }
 } while (true);
 }
 
+void
+Sema::CheckReturnValExpr(Expr *RetValExp, QualType lhsType,
+                         SourceLocation ReturnLoc,
+                         bool isObjCMethod,
+                         const AttrVec *Attrs,
+                         const FunctionDecl *FD) {
+  CheckReturnStackAddr(*this, RetValExp, lhsType, ReturnLoc);
+
+  // Check if the return value is null but should not be.
+  if (Attrs && hasSpecificAttr<ReturnsNonNullAttr>(*Attrs) &&
+      CheckNonNullExpr(*this, RetValExp))
+    Diag(ReturnLoc, diag::warn_null_ret)
+      << (isObjCMethod ? 1 : 0) << RetValExp->getSourceRange();
+
+  // C++11 [basic.stc.dynamic.allocation]p4:
+  //   If an allocation function declared with a non-throwing
+  //   exception-specification fails to allocate storage, it shall return
+  //   a null pointer. Any other allocation function that fails to allocate
+  //   storage shall indicate failure only by throwing an exception [...]
+  if (FD) {
+    OverloadedOperatorKind Op = FD->getOverloadedOperator();
+    if (Op == OO_New || Op == OO_Array_New) {
+      const FunctionProtoType *Proto
+        = FD->getType()->castAs<FunctionProtoType>();
+      if (!Proto->isNothrow(Context, /*ResultIfDependent*/true) &&
+          CheckNonNullExpr(*this, RetValExp))
+        Diag(ReturnLoc, diag::warn_operator_new_returns_null)
+          << FD << getLangOpts().CPlusPlus11;
+    }
+  }
+}
+
 //===--- CHECK: Floating-Point comparisons (-Wfloat-equal) ---------------===//
 
 /// Check for comparisons of floating point operands using != and ==.
@@ -4338,11 +4959,11 @@
 
   // Check for comparisons with builtin types.
   if (CallExpr* CL = dyn_cast<CallExpr>(LeftExprSansParen))
-    if (CL->isBuiltinCall())
+    if (CL->getBuiltinCallee())
       return;
 
   if (CallExpr* CR = dyn_cast<CallExpr>(RightExprSansParen))
-    if (CR->isBuiltinCall())
+    if (CR->getBuiltinCallee())
       return;
 
   // Emit the diagnostic.
@@ -4387,6 +5008,8 @@
       T = VT->getElementType().getTypePtr();
     if (const ComplexType *CT = dyn_cast<ComplexType>(T))
       T = CT->getElementType().getTypePtr();
+    if (const AtomicType *AT = dyn_cast<AtomicType>(T))
+      T = AT->getValueType().getTypePtr();
 
     // For enum types, use the known bit width of the enumerators.
     if (const EnumType *ET = dyn_cast<EnumType>(T)) {
@@ -4422,6 +5045,8 @@
       T = VT->getElementType().getTypePtr();
     if (const ComplexType *CT = dyn_cast<ComplexType>(T))
       T = CT->getElementType().getTypePtr();
+    if (const AtomicType *AT = dyn_cast<AtomicType>(T))
+      T = AT->getValueType().getTypePtr();
     if (const EnumType *ET = dyn_cast<EnumType>(T))
       T = C.getCanonicalType(ET->getDecl()->getIntegerType()).getTypePtr();
 
@@ -4821,95 +5446,189 @@
   if (!S.ActiveTemplateInstantiations.empty())
     return;
 
+  // TODO: Investigate using GetExprRange() to get tighter bounds
+  // on the bit ranges.
+  QualType OtherT = Other->getType();
+  if (const AtomicType *AT = dyn_cast<AtomicType>(OtherT))
+    OtherT = AT->getValueType();
+  IntRange OtherRange = IntRange::forValueOfType(S.Context, OtherT);
+  unsigned OtherWidth = OtherRange.Width;
+
+  bool OtherIsBooleanType = Other->isKnownToHaveBooleanValue();
+
   // 0 values are handled later by CheckTrivialUnsignedComparison().
-  if (Value == 0)
+  if ((Value == 0) && (!OtherIsBooleanType))
     return;
 
   BinaryOperatorKind op = E->getOpcode();
-  QualType OtherT = Other->getType();
-  QualType ConstantT = Constant->getType();
-  QualType CommonT = E->getLHS()->getType();
-  if (S.Context.hasSameUnqualifiedType(OtherT, ConstantT))
-    return;
-  assert((OtherT->isIntegerType() && ConstantT->isIntegerType())
-         && "comparison with non-integer type");
+  bool IsTrue = true;
 
-  bool ConstantSigned = ConstantT->isSignedIntegerType();
-  bool CommonSigned = CommonT->isSignedIntegerType();
+  // Used for diagnostic printout.
+  enum {
+    LiteralConstant = 0,
+    CXXBoolLiteralTrue,
+    CXXBoolLiteralFalse
+  } LiteralOrBoolConstant = LiteralConstant;
 
-  bool EqualityOnly = false;
+  if (!OtherIsBooleanType) {
+    QualType ConstantT = Constant->getType();
+    QualType CommonT = E->getLHS()->getType();
 
-  // TODO: Investigate using GetExprRange() to get tighter bounds on
-  // on the bit ranges.
-  IntRange OtherRange = IntRange::forValueOfType(S.Context, OtherT);
-  unsigned OtherWidth = OtherRange.Width;
-  
-  if (CommonSigned) {
-    // The common type is signed, therefore no signed to unsigned conversion.
-    if (!OtherRange.NonNegative) {
-      // Check that the constant is representable in type OtherT.
-      if (ConstantSigned) {
-        if (OtherWidth >= Value.getMinSignedBits())
-          return;
-      } else { // !ConstantSigned
-        if (OtherWidth >= Value.getActiveBits() + 1)
-          return;
+    if (S.Context.hasSameUnqualifiedType(OtherT, ConstantT))
+      return;
+    assert((OtherT->isIntegerType() && ConstantT->isIntegerType()) &&
+           "comparison with non-integer type");
+
+    bool ConstantSigned = ConstantT->isSignedIntegerType();
+    bool CommonSigned = CommonT->isSignedIntegerType();
+
+    bool EqualityOnly = false;
+
+    if (CommonSigned) {
+      // The common type is signed, therefore no signed to unsigned conversion.
+      if (!OtherRange.NonNegative) {
+        // Check that the constant is representable in type OtherT.
+        if (ConstantSigned) {
+          if (OtherWidth >= Value.getMinSignedBits())
+            return;
+        } else { // !ConstantSigned
+          if (OtherWidth >= Value.getActiveBits() + 1)
+            return;
+        }
+      } else { // !OtherSigned
+               // Check that the constant is representable in type OtherT.
+        // Negative values are out of range.
+        if (ConstantSigned) {
+          if (Value.isNonNegative() && OtherWidth >= Value.getActiveBits())
+            return;
+        } else { // !ConstantSigned
+          if (OtherWidth >= Value.getActiveBits())
+            return;
+        }
       }
-    } else { // !OtherSigned
-      // Check that the constant is representable in type OtherT.
-      // Negative values are out of range.
-      if (ConstantSigned) {
-        if (Value.isNonNegative() && OtherWidth >= Value.getActiveBits())
-          return;
-      } else { // !ConstantSigned
+    } else { // !CommonSigned
+      if (OtherRange.NonNegative) {
         if (OtherWidth >= Value.getActiveBits())
           return;
+      } else { // OtherSigned
+        assert(!ConstantSigned &&
+               "Two signed types converted to unsigned types.");
+        // Check to see if the constant is representable in OtherT.
+        if (OtherWidth > Value.getActiveBits())
+          return;
+        // Check to see if the constant is equivalent to a negative value
+        // cast to CommonT.
+        if (S.Context.getIntWidth(ConstantT) ==
+                S.Context.getIntWidth(CommonT) &&
+            Value.isNegative() && Value.getMinSignedBits() <= OtherWidth)
+          return;
+        // The constant value rests between values that OtherT can represent
+        // after conversion.  Relational comparison still works, but equality
+        // comparisons will be tautological.
+        EqualityOnly = true;
       }
     }
-  } else {  // !CommonSigned
-    if (OtherRange.NonNegative) {
-      if (OtherWidth >= Value.getActiveBits())
-        return;
-    } else if (!OtherRange.NonNegative && !ConstantSigned) {
-      // Check to see if the constant is representable in OtherT.
-      if (OtherWidth > Value.getActiveBits())
-        return;
-      // Check to see if the constant is equivalent to a negative value
-      // cast to CommonT.
-      if (S.Context.getIntWidth(ConstantT) == S.Context.getIntWidth(CommonT) &&
-          Value.isNegative() && Value.getMinSignedBits() <= OtherWidth)
-        return;
-      // The constant value rests between values that OtherT can represent after
-      // conversion.  Relational comparison still works, but equality
-      // comparisons will be tautological.
-      EqualityOnly = true;
-    } else { // OtherSigned && ConstantSigned
-      assert(0 && "Two signed types converted to unsigned types.");
+
+    bool PositiveConstant = !ConstantSigned || Value.isNonNegative();
+
+    if (op == BO_EQ || op == BO_NE) {
+      IsTrue = op == BO_NE;
+    } else if (EqualityOnly) {
+      return;
+    } else if (RhsConstant) {
+      if (op == BO_GT || op == BO_GE)
+        IsTrue = !PositiveConstant;
+      else // op == BO_LT || op == BO_LE
+        IsTrue = PositiveConstant;
+    } else {
+      if (op == BO_LT || op == BO_LE)
+        IsTrue = !PositiveConstant;
+      else // op == BO_GT || op == BO_GE
+        IsTrue = PositiveConstant;
     }
-  }
-
-  bool PositiveConstant = !ConstantSigned || Value.isNonNegative();
-
-  bool IsTrue = true;
-  if (op == BO_EQ || op == BO_NE) {
-    IsTrue = op == BO_NE;
-  } else if (EqualityOnly) {
-    return;
-  } else if (RhsConstant) {
-    if (op == BO_GT || op == BO_GE)
-      IsTrue = !PositiveConstant;
-    else // op == BO_LT || op == BO_LE
-      IsTrue = PositiveConstant;
   } else {
-    if (op == BO_LT || op == BO_LE)
-      IsTrue = !PositiveConstant;
-    else // op == BO_GT || op == BO_GE
-      IsTrue = PositiveConstant;
+    // Other isKnownToHaveBooleanValue
+    enum CompareBoolWithConstantResult { AFals, ATrue, Unkwn };
+    enum ConstantValue { LT_Zero, Zero, One, GT_One, SizeOfConstVal };
+    enum ConstantSide { Lhs, Rhs, SizeOfConstSides };
+
+    static const struct LinkedConditions {
+      CompareBoolWithConstantResult BO_LT_OP[SizeOfConstSides][SizeOfConstVal];
+      CompareBoolWithConstantResult BO_GT_OP[SizeOfConstSides][SizeOfConstVal];
+      CompareBoolWithConstantResult BO_LE_OP[SizeOfConstSides][SizeOfConstVal];
+      CompareBoolWithConstantResult BO_GE_OP[SizeOfConstSides][SizeOfConstVal];
+      CompareBoolWithConstantResult BO_EQ_OP[SizeOfConstSides][SizeOfConstVal];
+      CompareBoolWithConstantResult BO_NE_OP[SizeOfConstSides][SizeOfConstVal];
+
+    } TruthTable = {
+        // Constant on LHS.              | Constant on RHS.              |
+        // LT_Zero| Zero  | One   |GT_One| LT_Zero| Zero  | One   |GT_One|
+        { { ATrue, Unkwn, AFals, AFals }, { AFals, AFals, Unkwn, ATrue } },
+        { { AFals, AFals, Unkwn, ATrue }, { ATrue, Unkwn, AFals, AFals } },
+        { { ATrue, ATrue, Unkwn, AFals }, { AFals, Unkwn, ATrue, ATrue } },
+        { { AFals, Unkwn, ATrue, ATrue }, { ATrue, ATrue, Unkwn, AFals } },
+        { { AFals, Unkwn, Unkwn, AFals }, { AFals, Unkwn, Unkwn, AFals } },
+        { { ATrue, Unkwn, Unkwn, ATrue }, { ATrue, Unkwn, Unkwn, ATrue } }
+      };
+
+    bool ConstantIsBoolLiteral = isa<CXXBoolLiteralExpr>(Constant);
+
+    enum ConstantValue ConstVal = Zero;
+    if (Value.isUnsigned() || Value.isNonNegative()) {
+      if (Value == 0) {
+        LiteralOrBoolConstant =
+            ConstantIsBoolLiteral ? CXXBoolLiteralFalse : LiteralConstant;
+        ConstVal = Zero;
+      } else if (Value == 1) {
+        LiteralOrBoolConstant =
+            ConstantIsBoolLiteral ? CXXBoolLiteralTrue : LiteralConstant;
+        ConstVal = One;
+      } else {
+        LiteralOrBoolConstant = LiteralConstant;
+        ConstVal = GT_One;
+      }
+    } else {
+      ConstVal = LT_Zero;
+    }
+
+    CompareBoolWithConstantResult CmpRes;
+
+    switch (op) {
+    case BO_LT:
+      CmpRes = TruthTable.BO_LT_OP[RhsConstant][ConstVal];
+      break;
+    case BO_GT:
+      CmpRes = TruthTable.BO_GT_OP[RhsConstant][ConstVal];
+      break;
+    case BO_LE:
+      CmpRes = TruthTable.BO_LE_OP[RhsConstant][ConstVal];
+      break;
+    case BO_GE:
+      CmpRes = TruthTable.BO_GE_OP[RhsConstant][ConstVal];
+      break;
+    case BO_EQ:
+      CmpRes = TruthTable.BO_EQ_OP[RhsConstant][ConstVal];
+      break;
+    case BO_NE:
+      CmpRes = TruthTable.BO_NE_OP[RhsConstant][ConstVal];
+      break;
+    default:
+      CmpRes = Unkwn;
+      break;
+    }
+
+    if (CmpRes == AFals) {
+      IsTrue = false;
+    } else if (CmpRes == ATrue) {
+      IsTrue = true;
+    } else {
+      return;
+    }
   }
 
   // If this is a comparison to an enum constant, include that
   // constant in the diagnostic.
-  const EnumConstantDecl *ED = 0;
+  const EnumConstantDecl *ED = nullptr;
   if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Constant))
     ED = dyn_cast<EnumConstantDecl>(DR->getDecl());
 
@@ -4920,9 +5639,12 @@
   else
     OS << Value;
 
-  S.Diag(E->getOperatorLoc(), diag::warn_out_of_range_compare)
-      << OS.str() << OtherT << IsTrue
-      << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
+  S.DiagRuntimeBehavior(
+    E->getOperatorLoc(), E,
+    S.PDiag(diag::warn_out_of_range_compare)
+        << OS.str() << LiteralOrBoolConstant
+        << OtherT << (OtherIsBooleanType && !OtherT->isBooleanType()) << IsTrue
+        << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange());
 }
 
 /// Analyze the operands of the given comparison.  Implements the
@@ -5211,7 +5933,7 @@
 }
 
 void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
-                             SourceLocation CC, bool *ICContext = 0) {
+                             SourceLocation CC, bool *ICContext = nullptr) {
   if (E->isTypeDependent() || E->isValueDependent()) return;
 
   const Type *Source = S.Context.getCanonicalType(E->getType()).getTypePtr();
@@ -5231,39 +5953,21 @@
   if (Target->isSpecificBuiltinType(BuiltinType::Bool)) {
     if (isa<StringLiteral>(E))
       // Warn on string literal to bool.  Checks for string literals in logical
-      // expressions, for instances, assert(0 && "error here"), is prevented
-      // by a check in AnalyzeImplicitConversions().
+      // and expressions, for instance, assert(0 && "error here"), are
+      // prevented by a check in AnalyzeImplicitConversions().
       return DiagnoseImpCast(S, E, T, CC,
                              diag::warn_impcast_string_literal_to_bool);
-    if (Source->isFunctionType()) {
-      // Warn on function to bool. Checks free functions and static member
-      // functions. Weakly imported functions are excluded from the check,
-      // since it's common to test their value to check whether the linker
-      // found a definition for them.
-      ValueDecl *D = 0;
-      if (DeclRefExpr* R = dyn_cast<DeclRefExpr>(E)) {
-        D = R->getDecl();
-      } else if (MemberExpr *M = dyn_cast<MemberExpr>(E)) {
-        D = M->getMemberDecl();
-      }
-
-      if (D && !D->isWeak()) {
-        if (FunctionDecl* F = dyn_cast<FunctionDecl>(D)) {
-          S.Diag(E->getExprLoc(), diag::warn_impcast_function_to_bool)
-            << F << E->getSourceRange() << SourceRange(CC);
-          S.Diag(E->getExprLoc(), diag::note_function_to_bool_silence)
-            << FixItHint::CreateInsertion(E->getExprLoc(), "&");
-          QualType ReturnType;
-          UnresolvedSet<4> NonTemplateOverloads;
-          S.tryExprAsCall(*E, ReturnType, NonTemplateOverloads);
-          if (!ReturnType.isNull() 
-              && ReturnType->isSpecificBuiltinType(BuiltinType::Bool))
-            S.Diag(E->getExprLoc(), diag::note_function_to_bool_call)
-              << FixItHint::CreateInsertion(
-                 S.getPreprocessor().getLocForEndOfToken(E->getLocEnd()), "()");
-          return;
-        }
-      }
+    if (isa<ObjCStringLiteral>(E) || isa<ObjCArrayLiteral>(E) ||
+        isa<ObjCDictionaryLiteral>(E) || isa<ObjCBoxedExpr>(E)) {
+      // This covers the literal expressions that evaluate to Objective-C
+      // objects.
+      return DiagnoseImpCast(S, E, T, CC,
+                             diag::warn_impcast_objective_c_literal_to_bool);
+    }
+    if (Source->isPointerType() || Source->canDecayToPointerType()) {
+      // Warn on pointer to bool conversion that is always true.
+      S.DiagnoseAlwaysNonNullPointer(E, Expr::NPCK_NotNull, /*IsEqual*/ false,
+                                     SourceRange(CC));
     }
   }
 
@@ -5283,6 +5987,8 @@
     Source = cast<VectorType>(Source)->getElementType().getTypePtr();
     Target = cast<VectorType>(Target)->getElementType().getTypePtr();
   }
+  if (auto VecTy = dyn_cast<VectorType>(Target))
+    Target = VecTy->getElementType().getTypePtr();
 
   // Strip complex types.
   if (isa<ComplexType>(Source)) {
@@ -5501,8 +6207,7 @@
   if (!Suspicious) return;
 
   // ...but it's currently ignored...
-  if (S.Diags.getDiagnosticLevel(diag::warn_impcast_integer_sign_conditional,
-                                 CC))
+  if (!S.Diags.isIgnored(diag::warn_impcast_integer_sign_conditional, CC))
     return;
 
   // ...then check whether it would have warned about either of the
@@ -5526,7 +6231,7 @@
 
   if (E->isTypeDependent() || E->isValueDependent())
     return;
-
+  
   // For conditional operators, we analyze the arguments as if they
   // were being fed directly into the output.
   if (isa<ConditionalOperator>(E)) {
@@ -5583,15 +6288,16 @@
   // Now just recurse over the expression's children.
   CC = E->getExprLoc();
   BinaryOperator *BO = dyn_cast<BinaryOperator>(E);
-  bool IsLogicalOperator = BO && BO->isLogicalOp();
+  bool IsLogicalAndOperator = BO && BO->getOpcode() == BO_LAnd;
   for (Stmt::child_range I = E->children(); I; ++I) {
     Expr *ChildExpr = dyn_cast_or_null<Expr>(*I);
     if (!ChildExpr)
       continue;
 
-    if (IsLogicalOperator &&
+    if (IsLogicalAndOperator &&
         isa<StringLiteral>(ChildExpr->IgnoreParenImpCasts()))
-      // Ignore checking string literals that are in logical operators.
+      // Ignore checking string literals that are in logical and operators.
+      // This is a common pattern for asserts.
       continue;
     AnalyzeImplicitConversions(S, ChildExpr, CC);
   }
@@ -5599,6 +6305,172 @@
 
 } // end anonymous namespace
 
+enum {
+  AddressOf,
+  FunctionPointer,
+  ArrayPointer
+};
+
+// Helper function for Sema::DiagnoseAlwaysNonNullPointer.
+// Returns true when emitting a warning about taking the address of a reference.
+static bool CheckForReference(Sema &SemaRef, const Expr *E,
+                              PartialDiagnostic PD) {
+  E = E->IgnoreParenImpCasts();
+
+  const FunctionDecl *FD = nullptr;
+
+  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
+    if (!DRE->getDecl()->getType()->isReferenceType())
+      return false;
+  } else if (const MemberExpr *M = dyn_cast<MemberExpr>(E)) {
+    if (!M->getMemberDecl()->getType()->isReferenceType())
+      return false;
+  } else if (const CallExpr *Call = dyn_cast<CallExpr>(E)) {
+    if (!Call->getCallReturnType()->isReferenceType())
+      return false;
+    FD = Call->getDirectCallee();
+  } else {
+    return false;
+  }
+
+  SemaRef.Diag(E->getExprLoc(), PD);
+
+  // If possible, point to location of function.
+  if (FD) {
+    SemaRef.Diag(FD->getLocation(), diag::note_reference_is_return_value) << FD;
+  }
+
+  return true;
+}
+
+/// \brief Diagnose pointers that are always non-null.
+/// \param E the expression containing the pointer
+/// \param NullKind NPCK_NotNull if E is a cast to bool, otherwise, E is
+/// compared to a null pointer
+/// \param IsEqual True when the comparison is equal to a null pointer
+/// \param Range Extra SourceRange to highlight in the diagnostic
+void Sema::DiagnoseAlwaysNonNullPointer(Expr *E,
+                                        Expr::NullPointerConstantKind NullKind,
+                                        bool IsEqual, SourceRange Range) {
+  if (!E)
+    return;
+
+  // Don't warn inside macros.
+  if (E->getExprLoc().isMacroID())
+      return;
+  E = E->IgnoreImpCasts();
+
+  const bool IsCompare = NullKind != Expr::NPCK_NotNull;
+
+  if (isa<CXXThisExpr>(E)) {
+    unsigned DiagID = IsCompare ? diag::warn_this_null_compare
+                                : diag::warn_this_bool_conversion;
+    Diag(E->getExprLoc(), DiagID) << E->getSourceRange() << Range << IsEqual;
+    return;
+  }
+
+  bool IsAddressOf = false;
+
+  if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
+    if (UO->getOpcode() != UO_AddrOf)
+      return;
+    IsAddressOf = true;
+    E = UO->getSubExpr();
+  }
+
+  if (IsAddressOf) {
+    unsigned DiagID = IsCompare
+                          ? diag::warn_address_of_reference_null_compare
+                          : diag::warn_address_of_reference_bool_conversion;
+    PartialDiagnostic PD = PDiag(DiagID) << E->getSourceRange() << Range
+                                         << IsEqual;
+    if (CheckForReference(*this, E, PD)) {
+      return;
+    }
+  }
+
+  // Expect to find a single Decl.  Skip anything more complicated.
+  ValueDecl *D = nullptr;
+  if (DeclRefExpr *R = dyn_cast<DeclRefExpr>(E)) {
+    D = R->getDecl();
+  } else if (MemberExpr *M = dyn_cast<MemberExpr>(E)) {
+    D = M->getMemberDecl();
+  }
+
+  // Weak Decls can be null.
+  if (!D || D->isWeak())
+    return;
+
+  QualType T = D->getType();
+  const bool IsArray = T->isArrayType();
+  const bool IsFunction = T->isFunctionType();
+
+  // Address of function is used to silence the function warning.
+  if (IsAddressOf && IsFunction) {
+    return;
+  }
+
+  // Found nothing.
+  if (!IsAddressOf && !IsFunction && !IsArray)
+    return;
+
+  // Pretty print the expression for the diagnostic.
+  std::string Str;
+  llvm::raw_string_ostream S(Str);
+  E->printPretty(S, nullptr, getPrintingPolicy());
+
+  unsigned DiagID = IsCompare ? diag::warn_null_pointer_compare
+                              : diag::warn_impcast_pointer_to_bool;
+  unsigned DiagType;
+  if (IsAddressOf)
+    DiagType = AddressOf;
+  else if (IsFunction)
+    DiagType = FunctionPointer;
+  else if (IsArray)
+    DiagType = ArrayPointer;
+  else
+    llvm_unreachable("Could not determine diagnostic.");
+  Diag(E->getExprLoc(), DiagID) << DiagType << S.str() << E->getSourceRange()
+                                << Range << IsEqual;
+
+  if (!IsFunction)
+    return;
+
+  // Suggest '&' to silence the function warning.
+  Diag(E->getExprLoc(), diag::note_function_warning_silence)
+      << FixItHint::CreateInsertion(E->getLocStart(), "&");
+
+  // Check to see if '()' fixit should be emitted.
+  QualType ReturnType;
+  UnresolvedSet<4> NonTemplateOverloads;
+  tryExprAsCall(*E, ReturnType, NonTemplateOverloads);
+  if (ReturnType.isNull())
+    return;
+
+  if (IsCompare) {
+    // There are two cases here.  If there is null constant, the only suggest
+    // for a pointer return type.  If the null is 0, then suggest if the return
+    // type is a pointer or an integer type.
+    if (!ReturnType->isPointerType()) {
+      if (NullKind == Expr::NPCK_ZeroExpression ||
+          NullKind == Expr::NPCK_ZeroLiteral) {
+        if (!ReturnType->isIntegerType())
+          return;
+      } else {
+        return;
+      }
+    }
+  } else { // !IsCompare
+    // For function to bool, only suggest if the function pointer has bool
+    // return type.
+    if (!ReturnType->isSpecificBuiltinType(BuiltinType::Bool))
+      return;
+  }
+  Diag(E->getExprLoc(), diag::note_function_to_function_call)
+      << FixItHint::CreateInsertion(getLocForEndOfToken(E->getLocEnd()), "()");
+}
+
+
 /// Diagnoses "dangerous" implicit conversions within the given
 /// expression (which is a full expression).  Implements -Wconversion
 /// and -Wsign-compare.
@@ -5720,7 +6592,7 @@
   };
 
   struct Usage {
-    Usage() : Use(0), Seq() {}
+    Usage() : Use(nullptr), Seq() {}
     Expr *Use;
     SequenceTree::Seq Seq;
   };
@@ -5820,7 +6692,7 @@
     } else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
       // FIXME: If this is a reference, map through to its value.
       return DRE->getDecl();
-    return 0;
+    return nullptr;
   }
 
   /// \brief Note that an object was modified or used by an expression.
@@ -5880,8 +6752,8 @@
 
 public:
   SequenceChecker(Sema &S, Expr *E, SmallVectorImpl<Expr *> &WorkList)
-      : Base(S.Context), SemaRef(S), Region(Tree.root()), ModAsSideEffect(0),
-        WorkList(WorkList), EvalTracker(0) {
+      : Base(S.Context), SemaRef(S), Region(Tree.root()),
+        ModAsSideEffect(nullptr), WorkList(WorkList), EvalTracker(nullptr) {
     Visit(E);
   }
 
@@ -6166,7 +7038,7 @@
     // C99 6.9.1p5: If the declarator includes a parameter type list, the
     // declaration of each parameter shall include an identifier.
     if (CheckParameterNames &&
-        Param->getIdentifier() == 0 &&
+        Param->getIdentifier() == nullptr &&
         !Param->isImplicit() &&
         !getLangOpts().CPlusPlus)
       Diag(Param->getLocation(), diag::err_parameter_name_omitted);
@@ -6189,11 +7061,23 @@
 
     // MSVC destroys objects passed by value in the callee.  Therefore a
     // function definition which takes such a parameter must be able to call the
-    // object's destructor.
-    if (getLangOpts().CPlusPlus &&
-        Context.getTargetInfo().getCXXABI().isArgumentDestroyedByCallee()) {
-      if (const RecordType *RT = Param->getType()->getAs<RecordType>())
-        FinalizeVarWithDestructor(Param, RT);
+    // object's destructor.  However, we don't perform any direct access check
+    // on the dtor.
+    if (getLangOpts().CPlusPlus && Context.getTargetInfo()
+                                       .getCXXABI()
+                                       .areArgsDestroyedLeftToRightInCallee()) {
+      if (!Param->isInvalidDecl()) {
+        if (const RecordType *RT = Param->getType()->getAs<RecordType>()) {
+          CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(RT->getDecl());
+          if (!ClassDecl->isInvalidDecl() &&
+              !ClassDecl->hasIrrelevantDestructor() &&
+              !ClassDecl->isDependentContext()) {
+            CXXDestructorDecl *Destructor = LookupDestructor(ClassDecl);
+            MarkFunctionReferenced(Param->getLocation(), Destructor);
+            DiagnoseUseOfDecl(Destructor, Param->getLocation());
+          }
+        }
+      }
     }
   }
 
@@ -6205,9 +7089,7 @@
 void Sema::CheckCastAlign(Expr *Op, QualType T, SourceRange TRange) {
   // This is actually a lot of work to potentially be doing on every
   // cast; don't do it if we're ignoring -Wcast_align (as is the default).
-  if (getDiagnostics().getDiagnosticLevel(diag::warn_cast_align,
-                                          TRange.getBegin())
-        == DiagnosticsEngine::Ignored)
+  if (getDiagnostics().isIgnored(diag::warn_cast_align, TRange.getBegin()))
     return;
 
   // Ignore dependent types.
@@ -6321,7 +7203,7 @@
   if (IndexNegated)
     index = -index;
 
-  const NamedDecl *ND = NULL;
+  const NamedDecl *ND = nullptr;
   if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
     ND = dyn_cast<NamedDecl>(DRE->getDecl());
   if (const MemberExpr *ME = dyn_cast<MemberExpr>(BaseExpr))
@@ -6464,7 +7346,7 @@
 
 namespace {
   struct RetainCycleOwner {
-    RetainCycleOwner() : Variable(0), Indirect(false) {}
+    RetainCycleOwner() : Variable(nullptr), Indirect(false) {}
     VarDecl *Variable;
     SourceRange Range;
     SourceLocation Loc;
@@ -6575,10 +7457,12 @@
   struct FindCaptureVisitor : EvaluatedExprVisitor<FindCaptureVisitor> {
     FindCaptureVisitor(ASTContext &Context, VarDecl *variable)
       : EvaluatedExprVisitor<FindCaptureVisitor>(Context),
-        Variable(variable), Capturer(0) {}
-
+        Context(Context), Variable(variable), Capturer(nullptr),
+        VarWillBeReased(false) {}
+    ASTContext &Context;
     VarDecl *Variable;
     Expr *Capturer;
+    bool VarWillBeReased;
 
     void VisitDeclRefExpr(DeclRefExpr *ref) {
       if (ref->getDecl() == Variable && !Capturer)
@@ -6603,6 +7487,21 @@
       if (OVE->getSourceExpr())
         Visit(OVE->getSourceExpr());
     }
+    void VisitBinaryOperator(BinaryOperator *BinOp) {
+      if (!Variable || VarWillBeReased || BinOp->getOpcode() != BO_Assign)
+        return;
+      Expr *LHS = BinOp->getLHS();
+      if (const DeclRefExpr *DRE = dyn_cast_or_null<DeclRefExpr>(LHS)) {
+        if (DRE->getDecl() != Variable)
+          return;
+        if (Expr *RHS = BinOp->getRHS()) {
+          RHS = RHS->IgnoreParenCasts();
+          llvm::APSInt Value;
+          VarWillBeReased =
+            (RHS && RHS->isIntegerConstantExpr(Value, Context) && Value == 0);
+        }
+      }
+    }
   };
 }
 
@@ -6619,7 +7518,7 @@
     if (Cmd.isUnarySelector() && Cmd.getNameForSlot(0) == "copy") {
       e = ME->getInstanceReceiver();
       if (!e)
-        return 0;
+        return nullptr;
       e = e->IgnoreParenCasts();
     }
   } else if (CallExpr *CE = dyn_cast<CallExpr>(e)) {
@@ -6636,11 +7535,11 @@
   
   BlockExpr *block = dyn_cast<BlockExpr>(e);
   if (!block || !block->getBlockDecl()->capturesVariable(owner.Variable))
-    return 0;
+    return nullptr;
 
   FindCaptureVisitor visitor(S.Context, owner.Variable);
   visitor.Visit(block->getBlockDecl()->getBody());
-  return visitor.Capturer;
+  return visitor.VarWillBeReased ? nullptr : visitor.Capturer;
 }
 
 static void diagnoseRetainCycle(Sema &S, Expr *capturer,
@@ -6712,7 +7611,7 @@
 
 void Sema::checkRetainCycles(VarDecl *Var, Expr *Init) {
   RetainCycleOwner Owner;
-  if (!considerVariable(Var, /*DeclRefExpr=*/0, Owner))
+  if (!considerVariable(Var, /*DeclRefExpr=*/nullptr, Owner))
     return;
   
   // Because we don't have an expression for the variable, we have to set the
@@ -6784,7 +7683,7 @@
                               Expr *LHS, Expr *RHS) {
   QualType LHSType;
   // PropertyRef on LHS type need be directly obtained from
-  // its declaration as it has a PsuedoType.
+  // its declaration as it has a PseudoType.
   ObjCPropertyRefExpr *PRE
     = dyn_cast<ObjCPropertyRefExpr>(LHS->IgnoreParens());
   if (PRE && !PRE->isImplicitProperty()) {
@@ -6799,9 +7698,7 @@
   Qualifiers::ObjCLifetime LT = LHSType.getObjCLifetime();
 
   if (LT == Qualifiers::OCL_Weak) {
-    DiagnosticsEngine::Level Level =
-      Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak, Loc);
-    if (Level != DiagnosticsEngine::Ignored)
+    if (!Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
       getCurFunction()->markSafeWeakUse(LHS);
   }
 
@@ -6926,8 +7823,7 @@
     return;
 
   // Skip expensive checks if diagnostic is disabled.
-  if (Diags.getDiagnosticLevel(DiagID, NBody->getSemiLoc()) ==
-          DiagnosticsEngine::Ignored)
+  if (Diags.isIgnored(DiagID, NBody->getSemiLoc()))
     return;
 
   // Do the usual checks.
@@ -7057,21 +7953,16 @@
                              RecordDecl *RD1,
                              RecordDecl *RD2) {
   llvm::SmallPtrSet<FieldDecl *, 8> UnmatchedFields;
-  for (RecordDecl::field_iterator Field2 = RD2->field_begin(),
-                                  Field2End = RD2->field_end();
-       Field2 != Field2End; ++Field2) {
-    UnmatchedFields.insert(*Field2);
-  }
+  for (auto *Field2 : RD2->fields())
+    UnmatchedFields.insert(Field2);
 
-  for (RecordDecl::field_iterator Field1 = RD1->field_begin(),
-                                  Field1End = RD1->field_end();
-       Field1 != Field1End; ++Field1) {
+  for (auto *Field1 : RD1->fields()) {
     llvm::SmallPtrSet<FieldDecl *, 8>::iterator
         I = UnmatchedFields.begin(),
         E = UnmatchedFields.end();
 
     for ( ; I != E; ++I) {
-      if (isLayoutCompatible(C, *Field1, *I)) {
+      if (isLayoutCompatible(C, Field1, *I)) {
         bool Result = UnmatchedFields.erase(*I);
         (void) Result;
         assert(Result);
@@ -7228,7 +8119,7 @@
   FoundWrongKind = false;
 
   // Variable declaration that has type_tag_for_datatype attribute.
-  const ValueDecl *VD = NULL;
+  const ValueDecl *VD = nullptr;
 
   uint64_t MagicValue;
 
@@ -7236,10 +8127,7 @@
     return false;
 
   if (VD) {
-    for (specific_attr_iterator<TypeTagForDatatypeAttr>
-             I = VD->specific_attr_begin<TypeTagForDatatypeAttr>(),
-             E = VD->specific_attr_end<TypeTagForDatatypeAttr>();
-         I != E; ++I) {
+    if (TypeTagForDatatypeAttr *I = VD->getAttr<TypeTagForDatatypeAttr>()) {
       if (I->getArgumentKind() != ArgumentKind) {
         FoundWrongKind = true;
         return false;
@@ -7372,8 +8260,9 @@
 
   if (mismatch)
     Diag(ArgumentExpr->getExprLoc(), diag::warn_type_safety_type_mismatch)
-        << ArgumentType << ArgumentKind->getName()
+        << ArgumentType << ArgumentKind
         << TypeInfo.LayoutCompatible << RequiredType
         << ArgumentExpr->getSourceRange()
         << TypeTagExpr->getSourceRange();
 }
+
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index 7a1b36b..3d250e3 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -104,7 +104,7 @@
         if (DeclIndexPairVector *Vec
               = DeclOrVector.dyn_cast<DeclIndexPairVector *>()) {
           delete Vec;
-          DeclOrVector = ((NamedDecl *)0);
+          DeclOrVector = ((NamedDecl *)nullptr);
         }
       }
 
@@ -172,12 +172,12 @@
     explicit ResultBuilder(Sema &SemaRef, CodeCompletionAllocator &Allocator,
                            CodeCompletionTUInfo &CCTUInfo,
                            const CodeCompletionContext &CompletionContext,
-                           LookupFilter Filter = 0)
+                           LookupFilter Filter = nullptr)
       : SemaRef(SemaRef), Allocator(Allocator), CCTUInfo(CCTUInfo),
         Filter(Filter), 
         AllowNestedNameSpecifiers(false), HasObjectTypeQualifiers(false), 
         CompletionContext(CompletionContext),
-        ObjCImplementation(0) 
+        ObjCImplementation(nullptr)
     { 
       // If this is an Objective-C instance method definition, dig out the 
       // corresponding implementation.
@@ -212,8 +212,8 @@
     void setFilter(LookupFilter Filter) {
       this->Filter = Filter;
     }
-    
-    Result *data() { return Results.empty()? 0 : &Results.front(); }
+
+    Result *data() { return Results.empty()? nullptr : &Results.front(); }
     unsigned size() const { return Results.size(); }
     bool empty() const { return Results.empty(); }
     
@@ -289,8 +289,8 @@
     /// \param R the result to add (if it is unique).
     ///
     /// \param CurContext the context in which this result will be named.
-    void MaybeAddResult(Result R, DeclContext *CurContext = 0);
-    
+    void MaybeAddResult(Result R, DeclContext *CurContext = nullptr);
+
     /// \brief Add a new result to this result set, where we already know
     /// the hiding declation (if any).
     ///
@@ -364,8 +364,8 @@
       return &Value;
     }
   };
-        
-  iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { }
+
+  iterator() : DeclOrIterator((NamedDecl *)nullptr), SingleDeclIndex(0) {}
 
   iterator(const NamedDecl *SingleDecl, unsigned Index)
     : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
@@ -375,7 +375,7 @@
 
   iterator &operator++() {
     if (DeclOrIterator.is<const NamedDecl *>()) {
-      DeclOrIterator = (NamedDecl *)0;
+      DeclOrIterator = (NamedDecl *)nullptr;
       SingleDeclIndex = 0;
       return *this;
     }
@@ -461,8 +461,8 @@
     
     TargetParents.push_back(CommonAncestor);
   }
-  
-  NestedNameSpecifier *Result = 0;
+
+  NestedNameSpecifier *Result = nullptr;
   while (!TargetParents.empty()) {
     const DeclContext *Parent = TargetParents.pop_back_val();
 
@@ -480,6 +480,16 @@
   return Result;
 }
 
+/// Determine whether \p Id is a name reserved for the implementation (C99
+/// 7.1.3, C++ [lib.global.names]).
+static bool isReservedName(const IdentifierInfo *Id) {
+  if (Id->getLength() < 2)
+    return false;
+  const char *Name = Id->getNameStart();
+  return Name[0] == '_' &&
+         (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z'));
+}
+
 bool ResultBuilder::isInterestingDecl(const NamedDecl *ND,
                                       bool &AsNestedNameSpecifier) const {
   AsNestedNameSpecifier = false;
@@ -506,31 +516,21 @@
     return false;
   
   // Some declarations have reserved names that we don't want to ever show.
-  if (const IdentifierInfo *Id = ND->getIdentifier()) {
-    // __va_list_tag is a freak of nature. Find it and skip it.
-    if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
-      return false;
-    
-    // Filter out names reserved for the implementation (C99 7.1.3, 
-    // C++ [lib.global.names]) if they come from a system header.
-    //
-    // FIXME: Add predicate for this.
-    if (Id->getLength() >= 2) {
-      const char *Name = Id->getNameStart();
-      if (Name[0] == '_' &&
-          (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')) &&
-          (ND->getLocation().isInvalid() ||
-           SemaRef.SourceMgr.isInSystemHeader(
-                          SemaRef.SourceMgr.getSpellingLoc(ND->getLocation()))))
+  // Filter out names reserved for the implementation if they come from a
+  // system header.
+  // TODO: Add a predicate for this.
+  if (const IdentifierInfo *Id = ND->getIdentifier())
+    if (isReservedName(Id) &&
+        (ND->getLocation().isInvalid() ||
+         SemaRef.SourceMgr.isInSystemHeader(
+             SemaRef.SourceMgr.getSpellingLoc(ND->getLocation()))))
         return false;
-    }
-  }
 
   if (Filter == &ResultBuilder::IsNestedNameSpecifier ||
       ((isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) &&
        Filter != &ResultBuilder::IsNamespace &&
        Filter != &ResultBuilder::IsNamespaceOrAlias &&
-       Filter != 0))
+       Filter != nullptr))
     AsNestedNameSpecifier = true;
 
   // Filter out any unwanted results.
@@ -660,13 +660,10 @@
     return C.getObjCInterfaceType(Iface);
   
   QualType T;
-  if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
+  if (const FunctionDecl *Function = ND->getAsFunction())
     T = Function->getCallResultType();
   else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
     T = Method->getSendResultType();
-  else if (const FunctionTemplateDecl *FunTmpl =
-               dyn_cast<FunctionTemplateDecl>(ND))
-    T = FunTmpl->getTemplatedDecl()->getCallResultType();
   else if (const EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
     T = C.getTypeDeclType(cast<EnumDecl>(Enumerator->getDeclContext()));
   else if (const ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
@@ -700,7 +697,7 @@
     }
 
     if (const FunctionType *Function = T->getAs<FunctionType>()) {
-      T = Function->getResultType();
+      T = Function->getReturnType();
       continue;
     }
 
@@ -782,7 +779,7 @@
   
   ASTContext &Context = SemaRef.Context;
   const NamedDecl *D = R.Declaration;
-  const CXXRecordDecl *Record = 0;
+  const CXXRecordDecl *Record = nullptr;
   if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D))
     Record = ClassTemplate->getTemplatedDecl();
   else if ((Record = dyn_cast<CXXRecordDecl>(D))) {
@@ -913,10 +910,11 @@
       !R.StartsNestedNameSpecifier) {
     const DeclContext *Ctx = R.Declaration->getDeclContext();
     if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
-      R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
+      R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, nullptr,
+                                                Namespace);
     else if (const TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
-      R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false, 
-                             SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
+      R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, nullptr,
+                      false, SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
     else
       R.QualifierIsInformative = false;
   }
@@ -978,9 +976,10 @@
       !R.StartsNestedNameSpecifier) {
     const DeclContext *Ctx = R.Declaration->getDeclContext();
     if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
-      R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
+      R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, nullptr,
+                                                Namespace);
     else if (const TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
-      R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false, 
+      R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, nullptr, false,
                             SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
     else
       R.QualifierIsInformative = false;
@@ -1256,15 +1255,15 @@
   public:
     CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
       : Results(Results), CurContext(CurContext) { }
-    
-    virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx,
-                           bool InBaseClass) {
+
+    void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx,
+                   bool InBaseClass) override {
       bool Accessible = true;
       if (Ctx)
         Accessible = Results.getSema().IsSimplyAccessible(ND, Ctx);
-      
-      ResultBuilder::Result Result(ND, Results.getBasePriority(ND), 0, false,
-                                   Accessible);
+
+      ResultBuilder::Result Result(ND, Results.getBasePriority(ND), nullptr,
+                                   false, Accessible);
       Results.AddResult(Result, CurContext, Hiding, InBaseClass);
     }
   };
@@ -1784,10 +1783,10 @@
     // know the function is void or not.
     bool isVoid = false;
     if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
-      isVoid = Function->getResultType()->isVoidType();
+      isVoid = Function->getReturnType()->isVoidType();
     else if (ObjCMethodDecl *Method
                                  = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
-      isVoid = Method->getResultType()->isVoidType();
+      isVoid = Method->getReturnType()->isVoidType();
     else if (SemaRef.getCurBlock() && 
              !SemaRef.getCurBlock()->ReturnType.isNull())
       isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
@@ -2066,14 +2065,11 @@
     return;
 
   // Determine the type of the declaration (if it has a type).
-  QualType T;  
-  if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
-    T = Function->getResultType();
+  QualType T;
+  if (const FunctionDecl *Function = ND->getAsFunction())
+    T = Function->getReturnType();
   else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
-    T = Method->getResultType();
-  else if (const FunctionTemplateDecl *FunTmpl =
-               dyn_cast<FunctionTemplateDecl>(ND))
-    T = FunTmpl->getTemplatedDecl()->getResultType();
+    T = Method->getReturnType();
   else if (const EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
     T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
   else if (isa<UnresolvedUsingValueDecl>(ND)) {
@@ -2206,26 +2202,26 @@
   // We have the function prototype behind the block pointer type, as it was
   // written in the source.
   std::string Result;
-  QualType ResultType = Block.getTypePtr()->getResultType();
+  QualType ResultType = Block.getTypePtr()->getReturnType();
   if (!ResultType->isVoidType() || SuppressBlock)
     ResultType.getAsStringInternal(Result, Policy);
 
   // Format the parameter list.
   std::string Params;
-  if (!BlockProto || Block.getNumArgs() == 0) {
+  if (!BlockProto || Block.getNumParams() == 0) {
     if (BlockProto && BlockProto.getTypePtr()->isVariadic())
       Params = "(...)";
     else
       Params = "(void)";
   } else {
     Params += "(";
-    for (unsigned I = 0, N = Block.getNumArgs(); I != N; ++I) {
+    for (unsigned I = 0, N = Block.getNumParams(); I != N; ++I) {
       if (I)
         Params += ", ";
-      Params += FormatFunctionParameter(Context, Policy, Block.getArg(I),
-                                        /*SuppressName=*/false, 
+      Params += FormatFunctionParameter(Context, Policy, Block.getParam(I),
+                                        /*SuppressName=*/false,
                                         /*SuppressBlock=*/true);
-      
+
       if (I == N - 1 && BlockProto.getTypePtr()->isVariadic())
         Params += ", ...";
     }
@@ -2297,7 +2293,7 @@
   if (const FunctionProtoType *Proto 
         = Function->getType()->getAs<FunctionProtoType>())
     if (Proto->isVariadic()) {
-      if (Proto->getNumArgs() == 0)
+      if (Proto->getNumParams() == 0)
         Result.AddPlaceholderChunk("...");
 
       MaybeAddSentinel(Context, Function, Result);
@@ -2450,7 +2446,7 @@
   
   switch (Name.getNameKind()) {
     case DeclarationName::CXXOperatorName: {
-      const char *OperatorName = 0;
+      const char *OperatorName = nullptr;
       switch (Name.getCXXOverloadedOperator()) {
       case OO_None: 
       case OO_Conditional:
@@ -2489,7 +2485,7 @@
     break;
       
   case DeclarationName::CXXConstructorName: {
-    CXXRecordDecl *Record = 0;
+    CXXRecordDecl *Record = nullptr;
     QualType Ty = Name.getCXXNameType();
     if (const RecordType *RecordTy = Ty->getAs<RecordType>())
       Record = cast<CXXRecordDecl>(RecordTy->getDecl());
@@ -2644,12 +2640,9 @@
     return Result.TakeString();
   }
 
-  for (Decl::attr_iterator i = ND->attr_begin(); i != ND->attr_end(); ++i) {
-    if (AnnotateAttr *Attr = dyn_cast_or_null<AnnotateAttr>(*i)) {
-      Result.AddAnnotation(Result.getAllocator().CopyString(Attr->getAnnotation()));
-    }
-  }
-  
+  for (const auto *I : ND->specific_attrs<AnnotateAttr>())
+    Result.AddAnnotation(Result.getAllocator().CopyString(I->getAnnotation()));
+
   AddResultTypeChunk(Ctx, Policy, ND, Result);
   
   if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
@@ -2836,9 +2829,8 @@
     // Function without a prototype. Just give the return type and a 
     // highlighted ellipsis.
     const FunctionType *FT = getFunctionType();
-    Result.AddTextChunk(GetCompletionTypeString(FT->getResultType(),
-                                                S.Context, Policy, 
-                                                Result.getAllocator()));
+    Result.AddTextChunk(GetCompletionTypeString(FT->getReturnType(), S.Context,
+                                                Policy, Result.getAllocator()));
     Result.AddChunk(CodeCompletionString::CK_LeftParen);
     Result.AddChunk(CodeCompletionString::CK_CurrentParameter, "...");
     Result.AddChunk(CodeCompletionString::CK_RightParen);
@@ -2849,12 +2841,11 @@
     Result.AddTextChunk(
                     Result.getAllocator().CopyString(FDecl->getNameAsString()));
   else
-    Result.AddTextChunk(
-         Result.getAllocator().CopyString(
-                                  Proto->getResultType().getAsString(Policy)));
-  
+    Result.AddTextChunk(Result.getAllocator().CopyString(
+        Proto->getReturnType().getAsString(Policy)));
+
   Result.AddChunk(CodeCompletionString::CK_LeftParen);
-  unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
+  unsigned NumParams = FDecl ? FDecl->getNumParams() : Proto->getNumParams();
   for (unsigned I = 0; I != NumParams; ++I) {
     if (I)
       Result.AddChunk(CodeCompletionString::CK_Comma);
@@ -2866,7 +2857,7 @@
       ArgString = FDecl->getParamDecl(I)->getNameAsString();
       ArgType = FDecl->getParamDecl(I)->getOriginalType();
     } else {
-      ArgType = Proto->getArgType(I);
+      ArgType = Proto->getParamType(I);
     }
     
     ArgType.getAsStringInternal(ArgString, Policy);
@@ -2998,11 +2989,16 @@
   for (Preprocessor::macro_iterator M = PP.macro_begin(), 
                                  MEnd = PP.macro_end();
        M != MEnd; ++M) {
-    if (IncludeUndefined || M->first->hasMacroDefinition())
+    if (IncludeUndefined || M->first->hasMacroDefinition()) {
+      if (MacroInfo *MI = M->second->getMacroInfo())
+        if (MI->isUsedForHeaderGuard())
+          continue;
+
       Results.AddResult(Result(M->first,
                              getMacroUsagePriority(M->first->getName(),
                                                    PP.getLangOpts(),
                                                    TargetTypeIsPointer)));
+    }
   }
   
   Results.ExitScope();
@@ -3109,13 +3105,9 @@
   
   // We need to have names for all of the parameters, if we're going to 
   // generate a forwarding call.
-  for (CXXMethodDecl::param_iterator P = Method->param_begin(),
-                                  PEnd = Method->param_end();
-       P != PEnd;
-       ++P) {
-    if (!(*P)->getDeclName())
+  for (auto P : Method->params())
+    if (!P->getDeclName())
       return;
-  }
 
   PrintingPolicy Policy = getCompletionPrintingPolicy(S);
   for (CXXMethodDecl::method_iterator M = Method->begin_overridden_methods(),
@@ -3145,16 +3137,14 @@
                                          Overridden->getNameAsString()));
     Builder.AddChunk(CodeCompletionString::CK_LeftParen);
     bool FirstParam = true;
-    for (CXXMethodDecl::param_iterator P = Method->param_begin(),
-                                    PEnd = Method->param_end();
-         P != PEnd; ++P) {
+    for (auto P : Method->params()) {
       if (FirstParam)
         FirstParam = false;
       else
         Builder.AddChunk(CodeCompletionString::CK_Comma);
 
-      Builder.AddPlaceholderChunk(Results.getAllocator().CopyString( 
-                                        (*P)->getIdentifier()->getName()));
+      Builder.AddPlaceholderChunk(
+          Results.getAllocator().CopyString(P->getIdentifier()->getName()));
     }
     Builder.AddChunk(CodeCompletionString::CK_RightParen);
     Results.AddResult(CodeCompletionResult(Builder.TakeString(),
@@ -3252,7 +3242,7 @@
       Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
       
     if (getLangOpts().CPlusPlus)
-      MaybeAddOverrideCalls(*this, /*InContext=*/0, Results);
+      MaybeAddOverrideCalls(*this, /*InContext=*/nullptr, Results);
     break;
       
   case PCC_RecoveryInFunction:
@@ -3340,7 +3330,7 @@
       CodeCompletionDeclConsumer Consumer(Results, CurContext);
       LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer,
                          CodeCompleter->includeGlobals());
-      Results.setFilter(0);
+      Results.setFilter(nullptr);
     }
   }
   Results.ExitScope();
@@ -3438,7 +3428,7 @@
   if (E.isInvalid())
     CodeCompleteOrdinaryName(S, PCC_RecoveryInFunction);
   else if (getLangOpts().ObjC1)
-    CodeCompleteObjCInstanceMessage(S, E.take(), None, false);
+    CodeCompleteObjCInstanceMessage(S, E.get(), None, false);
 }
 
 /// \brief The set of properties that have already been added, referenced by
@@ -3475,32 +3465,26 @@
   Container = getContainerDef(Container);
   
   // Add properties in this container.
-  for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
-                                     PEnd = Container->prop_end();
-       P != PEnd;
-       ++P) {
+  for (const auto *P : Container->properties())
     if (AddedProperties.insert(P->getIdentifier()))
-      Results.MaybeAddResult(Result(*P, Results.getBasePriority(*P), 0),
+      Results.MaybeAddResult(Result(P, Results.getBasePriority(P), nullptr),
                              CurContext);
-  }
-  
+
   // Add nullary methods
   if (AllowNullaryMethods) {
     ASTContext &Context = Container->getASTContext();
     PrintingPolicy Policy = getCompletionPrintingPolicy(Results.getSema());
-    for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
-                                         MEnd = Container->meth_end();
-         M != MEnd; ++M) {
+    for (auto *M : Container->methods()) {
       if (M->getSelector().isUnarySelector())
         if (IdentifierInfo *Name = M->getSelector().getIdentifierInfoForSlot(0))
           if (AddedProperties.insert(Name)) {
             CodeCompletionBuilder Builder(Results.getAllocator(),
                                           Results.getCodeCompletionTUInfo());
-            AddResultTypeChunk(Context, Policy, *M, Builder);
+            AddResultTypeChunk(Context, Policy, M, Builder);
             Builder.AddTypedTextChunk(
                             Results.getAllocator().CopyString(Name->getName()));
             
-            Results.MaybeAddResult(Result(Builder.TakeString(), *M,
+            Results.MaybeAddResult(Result(Builder.TakeString(), M,
                                   CCP_MemberDeclaration + CCD_MethodAsProperty),
                                           CurContext);
           }
@@ -3510,27 +3494,20 @@
   
   // Add properties in referenced protocols.
   if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
-    for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
-                                          PEnd = Protocol->protocol_end();
-         P != PEnd; ++P)
-      AddObjCProperties(*P, AllowCategories, AllowNullaryMethods, CurContext, 
+    for (auto *P : Protocol->protocols())
+      AddObjCProperties(P, AllowCategories, AllowNullaryMethods, CurContext, 
                         AddedProperties, Results);
   } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
     if (AllowCategories) {
       // Look through categories.
-      for (ObjCInterfaceDecl::known_categories_iterator
-             Cat = IFace->known_categories_begin(),
-             CatEnd = IFace->known_categories_end();
-           Cat != CatEnd; ++Cat)
-        AddObjCProperties(*Cat, AllowCategories, AllowNullaryMethods,
-                          CurContext, AddedProperties, Results);
+      for (auto *Cat : IFace->known_categories())
+        AddObjCProperties(Cat, AllowCategories, AllowNullaryMethods, CurContext,
+                          AddedProperties, Results);
     }
-    
+
     // Look through protocols.
-    for (ObjCInterfaceDecl::all_protocol_iterator
-         I = IFace->all_referenced_protocol_begin(),
-         E = IFace->all_referenced_protocol_end(); I != E; ++I)
-      AddObjCProperties(*I, AllowCategories, AllowNullaryMethods, CurContext,
+    for (auto *I : IFace->all_referenced_protocols())
+      AddObjCProperties(I, AllowCategories, AllowNullaryMethods, CurContext,
                         AddedProperties, Results);
     
     // Look in the superclass.
@@ -3541,10 +3518,8 @@
   } else if (const ObjCCategoryDecl *Category
                                     = dyn_cast<ObjCCategoryDecl>(Container)) {
     // Look through protocols.
-    for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
-                                          PEnd = Category->protocol_end(); 
-         P != PEnd; ++P)
-      AddObjCProperties(*P, AllowCategories, AllowNullaryMethods, CurContext,
+    for (auto *P : Category->protocols())
+      AddObjCProperties(P, AllowCategories, AllowNullaryMethods, CurContext,
                         AddedProperties, Results);
   }
 }
@@ -3636,15 +3611,13 @@
                       AddedProperties, Results);
     
     // Add properties from the protocols in a qualified interface.
-    for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
-                                              E = ObjCPtr->qual_end();
-         I != E; ++I)
-      AddObjCProperties(*I, true, /*AllowNullaryMethods=*/true, CurContext, 
+    for (auto *I : ObjCPtr->quals())
+      AddObjCProperties(I, true, /*AllowNullaryMethods=*/true, CurContext, 
                         AddedProperties, Results);
   } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
              (!IsArrow && BaseType->isObjCObjectType())) {
     // Objective-C instance variable access.
-    ObjCInterfaceDecl *Class = 0;
+    ObjCInterfaceDecl *Class = nullptr;
     if (const ObjCObjectPointerType *ObjCPtr
                                     = BaseType->getAs<ObjCObjectPointerType>())
       Class = ObjCPtr->getInterfaceDecl();
@@ -3673,8 +3646,8 @@
 void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
   if (!CodeCompleter)
     return;
-  
-  ResultBuilder::LookupFilter Filter = 0;
+
+  ResultBuilder::LookupFilter Filter = nullptr;
   enum CodeCompletionContext::Kind ContextKind
     = CodeCompletionContext::CCC_Other;
   switch ((DeclSpec::TST)TagSpec) {
@@ -3763,7 +3736,7 @@
   // token, in case we are code-completing in the middle of the switch and not
   // at the end. However, we aren't able to do so at the moment.
   llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
-  NestedNameSpecifier *Qualifier = 0;
+  NestedNameSpecifier *Qualifier = nullptr;
   for (SwitchCase *SC = Switch->getSwitchCaseList(); SC; 
        SC = SC->getNextSwitchCase()) {
     CaseStmt *Case = dyn_cast<CaseStmt>(SC);
@@ -3809,14 +3782,12 @@
                         CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_Expression);
   Results.EnterNewScope();
-  for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
-                                  EEnd = Enum->enumerator_end();
-       E != EEnd; ++E) {
-    if (EnumeratorsSeen.count(*E))
+  for (auto *E : Enum->enumerators()) {
+    if (EnumeratorsSeen.count(E))
       continue;
     
-    CodeCompletionResult R(*E, CCP_EnumInCase, Qualifier);
-    Results.AddResult(R, CurContext, 0, false);
+    CodeCompletionResult R(E, CCP_EnumInCase, Qualifier);
+    Results.AddResult(R, CurContext, nullptr, false);
   }
   Results.ExitScope();
 
@@ -3833,22 +3804,6 @@
                             Results.data(),Results.size());
 }
 
-namespace {
-  struct IsBetterOverloadCandidate {
-    Sema &S;
-    SourceLocation Loc;
-    
-  public:
-    explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
-      : S(S), Loc(Loc) { }
-    
-    bool 
-    operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
-      return isBetterOverloadCandidate(S, X, Y, Loc);
-    }
-  };
-}
-
 static bool anyNullArguments(ArrayRef<Expr *> Args) {
   if (Args.size() && !Args.data())
     return true;
@@ -3880,7 +3835,7 @@
 
   // Build an overload candidate set based on the functions we find.
   SourceLocation Loc = Fn->getExprLoc();
-  OverloadCandidateSet CandidateSet(Loc);
+  OverloadCandidateSet CandidateSet(Loc, OverloadCandidateSet::CSK_Normal);
 
   // FIXME: What if we're calling something that isn't a function declaration?
   // FIXME: What if we're calling a pseudo-destructor?
@@ -3910,9 +3865,12 @@
   
   if (!CandidateSet.empty()) {
     // Sort the overload candidate set by placing the best overloads first.
-    std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
-                     IsBetterOverloadCandidate(*this, Loc));
-  
+    std::stable_sort(
+        CandidateSet.begin(), CandidateSet.end(),
+        [&](const OverloadCandidate &X, const OverloadCandidate &Y) {
+          return isBetterOverloadCandidate(*this, X, Y, Loc);
+        });
+
     // Add the remaining viable overload candidates as code-completion reslults.
     for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
                                      CandEnd = CandidateSet.end();
@@ -3925,12 +3883,13 @@
     for (unsigned I = 0, N = Results.size(); I != N; ++I) {
       if (const FunctionType *FType = Results[I].getFunctionType())
         if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FType))
-          if (Args.size() < Proto->getNumArgs()) {
+          if (Args.size() < Proto->getNumParams()) {
             if (ParamType.isNull())
-              ParamType = Proto->getArgType(Args.size());
+              ParamType = Proto->getParamType(Args.size());
             else if (!Context.hasSameUnqualifiedType(
-                                            ParamType.getNonReferenceType(),
-                       Proto->getArgType(Args.size()).getNonReferenceType())) {
+                          ParamType.getNonReferenceType(),
+                          Proto->getParamType(Args.size())
+                              .getNonReferenceType())) {
               ParamType = QualType();
               break;
             }
@@ -3951,8 +3910,8 @@
     
     if (const FunctionProtoType *Proto
                                   = FunctionType->getAs<FunctionProtoType>()) {
-      if (Args.size() < Proto->getNumArgs())
-        ParamType = Proto->getArgType(Args.size());
+      if (Args.size() < Proto->getNumParams())
+        ParamType = Proto->getParamType(Args.size());
     }
   }
 
@@ -3982,10 +3941,10 @@
     if (BlockScopeInfo *BSI = getCurBlock())
       ResultType = BSI->ReturnType;
   } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(CurContext))
-    ResultType = Function->getResultType();
+    ResultType = Function->getReturnType();
   else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
-    ResultType = Method->getResultType();
-  
+    ResultType = Method->getReturnType();
+
   if (ResultType.isNull())
     CodeCompleteOrdinaryName(S, PCC_Expression);
   else
@@ -4080,7 +4039,7 @@
   
   // The "template" keyword can follow "::" in the grammar, but only
   // put it into the grammar if the nested-name-specifier is dependent.
-  NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
+  NestedNameSpecifier *NNS = SS.getScopeRep();
   if (!Results.empty() && NNS->isDependent())
     Results.AddResult("template");
 
@@ -4184,8 +4143,9 @@
            NSEnd = OrigToLatest.end();
          NS != NSEnd; ++NS)
       Results.AddResult(CodeCompletionResult(
-                          NS->second, Results.getBasePriority(NS->second), 0),
-                        CurContext, 0, false);
+                          NS->second, Results.getBasePriority(NS->second),
+                          nullptr),
+                        CurContext, nullptr, false);
     Results.ExitScope();
   }
   
@@ -4274,21 +4234,19 @@
                                 Results.getCodeCompletionTUInfo());
   bool SawLastInitializer = Initializers.empty();
   CXXRecordDecl *ClassDecl = Constructor->getParent();
-  for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
-                                       BaseEnd = ClassDecl->bases_end();
-       Base != BaseEnd; ++Base) {
-    if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
+  for (const auto &Base : ClassDecl->bases()) {
+    if (!InitializedBases.insert(Context.getCanonicalType(Base.getType()))) {
       SawLastInitializer
         = !Initializers.empty() && 
           Initializers.back()->isBaseInitializer() &&
-          Context.hasSameUnqualifiedType(Base->getType(),
+          Context.hasSameUnqualifiedType(Base.getType(),
                QualType(Initializers.back()->getBaseClass(), 0));
       continue;
     }
     
     Builder.AddTypedTextChunk(
                Results.getAllocator().CopyString(
-                          Base->getType().getAsString(Policy)));
+                          Base.getType().getAsString(Policy)));
     Builder.AddChunk(CodeCompletionString::CK_LeftParen);
     Builder.AddPlaceholderChunk("args");
     Builder.AddChunk(CodeCompletionString::CK_RightParen);
@@ -4299,21 +4257,19 @@
   }
   
   // Add completions for virtual base classes.
-  for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
-                                       BaseEnd = ClassDecl->vbases_end();
-       Base != BaseEnd; ++Base) {
-    if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
+  for (const auto &Base : ClassDecl->vbases()) {
+    if (!InitializedBases.insert(Context.getCanonicalType(Base.getType()))) {
       SawLastInitializer
         = !Initializers.empty() && 
           Initializers.back()->isBaseInitializer() &&
-          Context.hasSameUnqualifiedType(Base->getType(),
+          Context.hasSameUnqualifiedType(Base.getType(),
                QualType(Initializers.back()->getBaseClass(), 0));
       continue;
     }
     
     Builder.AddTypedTextChunk(
                Builder.getAllocator().CopyString(
-                          Base->getType().getAsString(Policy)));
+                          Base.getType().getAsString(Policy)));
     Builder.AddChunk(CodeCompletionString::CK_LeftParen);
     Builder.AddPlaceholderChunk("args");
     Builder.AddChunk(CodeCompletionString::CK_RightParen);
@@ -4324,14 +4280,12 @@
   }
   
   // Add completions for members.
-  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
-                                  FieldEnd = ClassDecl->field_end();
-       Field != FieldEnd; ++Field) {
+  for (auto *Field : ClassDecl->fields()) {
     if (!InitializedFields.insert(cast<FieldDecl>(Field->getCanonicalDecl()))) {
       SawLastInitializer
         = !Initializers.empty() && 
           Initializers.back()->isAnyMemberInitializer() &&
-          Initializers.back()->getAnyMember() == *Field;
+          Initializers.back()->getAnyMember() == Field;
       continue;
     }
     
@@ -4348,7 +4302,7 @@
                                                      : CCP_MemberDeclaration,
                                            CXCursor_MemberRef,
                                            CXAvailability_Available,
-                                           *Field));
+                                           Field));
     SawLastInitializer = false;
   }
   Results.ExitScope();
@@ -4376,22 +4330,19 @@
   // Note what has already been captured.
   llvm::SmallPtrSet<IdentifierInfo *, 4> Known;
   bool IncludedThis = false;
-  for (SmallVectorImpl<LambdaCapture>::iterator C = Intro.Captures.begin(),
-                                             CEnd = Intro.Captures.end();
-       C != CEnd; ++C) {
-    if (C->Kind == LCK_This) {
+  for (const auto &C : Intro.Captures) {
+    if (C.Kind == LCK_This) {
       IncludedThis = true;
       continue;
     }
     
-    Known.insert(C->Id);
+    Known.insert(C.Id);
   }
   
   // Look for other capturable variables.
   for (; S && !isNamespaceScope(S); S = S->getParent()) {
-    for (Scope::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
-         D != DEnd; ++D) {
-      VarDecl *Var = dyn_cast<VarDecl>(*D);
+    for (const auto *D : S->decls()) {
+      const auto *Var = dyn_cast<VarDecl>(D);
       if (!Var ||
           !Var->hasLocalStorage() ||
           Var->hasAttr<BlocksAttr>())
@@ -4399,7 +4350,7 @@
       
       if (Known.insert(Var->getIdentifier()))
         Results.AddResult(CodeCompletionResult(Var, CCP_LocalDeclaration),
-                          CurContext, 0, false);
+                          CurContext, nullptr, false);
     }
   }
 
@@ -4759,7 +4710,7 @@
     CodeCompletionBuilder Setter(Results.getAllocator(),
                                  Results.getCodeCompletionTUInfo());
     Setter.AddTypedTextChunk("setter");
-    Setter.AddTextChunk(" = ");
+    Setter.AddTextChunk("=");
     Setter.AddPlaceholderChunk("method");
     Results.AddResult(CodeCompletionResult(Setter.TakeString()));
   }
@@ -4767,7 +4718,7 @@
     CodeCompletionBuilder Getter(Results.getAllocator(),
                                  Results.getCodeCompletionTUInfo());
     Getter.AddTypedTextChunk("getter");
-    Getter.AddTextChunk(" = ");
+    Getter.AddTextChunk("=");
     Getter.AddPlaceholderChunk("method");
     Results.AddResult(CodeCompletionResult(Getter.TakeString()));
   }
@@ -4856,22 +4807,20 @@
   Container = getContainerDef(Container);
   ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
   bool isRootClass = IFace && !IFace->getSuperClass();
-  for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
-                                       MEnd = Container->meth_end();
-       M != MEnd; ++M) {
+  for (auto *M : Container->methods()) {
     // The instance methods on the root class can be messaged via the
     // metaclass.
     if (M->isInstanceMethod() == 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))
+      if (!isAcceptableObjCMethod(M, WantKind, SelIdents, AllowSameLength))
         continue;
 
       if (!Selectors.insert(M->getSelector()))
         continue;
-      
-      Result R = Result(*M, Results.getBasePriority(*M), 0);
+
+      Result R = Result(M, Results.getBasePriority(M), nullptr);
       R.StartParameter = SelIdents.size();
       R.AllParametersAreInformative = (WantKind != MK_Any);
       if (!InOriginalClass)
@@ -4897,19 +4846,12 @@
     return;
   
   // Add methods in protocols.
-  for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
-                                            E = IFace->protocol_end();
-       I != E; ++I)
-    AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
+  for (auto *I : IFace->protocols())
+    AddObjCMethods(I, WantInstanceMethods, WantKind, SelIdents,
                    CurContext, Selectors, AllowSameLength, Results, false);
   
   // Add methods in categories.
-  for (ObjCInterfaceDecl::known_categories_iterator
-         Cat = IFace->known_categories_begin(),
-         CatEnd = IFace->known_categories_end();
-       Cat != CatEnd; ++Cat) {
-    ObjCCategoryDecl *CatDecl = *Cat;
-    
+  for (auto *CatDecl : IFace->known_categories()) {
     AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
                    CurContext, Selectors, AllowSameLength,
                    Results, InOriginalClass);
@@ -5080,22 +5022,22 @@
 static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
   ObjCMessageExpr *Msg = dyn_cast_or_null<ObjCMessageExpr>(E);
   if (!Msg)
-    return 0;
+    return nullptr;
 
   Selector Sel = Msg->getSelector();
   if (Sel.isNull())
-    return 0;
+    return nullptr;
 
   IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
   if (!Id)
-    return 0;
+    return nullptr;
 
   ObjCMethodDecl *Method = Msg->getMethodDecl();
   if (!Method)
-    return 0;
+    return nullptr;
 
   // Determine the class that we're sending the message to.
-  ObjCInterfaceDecl *IFace = 0;
+  ObjCInterfaceDecl *IFace = nullptr;
   switch (Msg->getReceiverKind()) {
   case ObjCMessageExpr::Class:
     if (const ObjCObjectType *ObjType
@@ -5116,7 +5058,7 @@
   }
 
   if (!IFace)
-    return 0;
+    return nullptr;
 
   ObjCInterfaceDecl *Super = IFace->getSuperClass();
   if (Method->isInstanceMethod())
@@ -5133,7 +5075,7 @@
       .Case("class", IFace)
       .Case("classForCoder", IFace)
       .Case("superclass", Super)
-      .Default(0);
+      .Default(nullptr);
 
   return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
     .Case("new", IFace)
@@ -5141,7 +5083,7 @@
     .Case("allocWithZone", IFace)
     .Case("class", IFace)
     .Case("superclass", Super)
-    .Default(0);
+    .Default(nullptr);
 }
 
 // Add a special completion for a message send to "super", which fills in the
@@ -5166,14 +5108,14 @@
                                           ResultBuilder &Results) {
   ObjCMethodDecl *CurMethod = S.getCurMethodDecl();
   if (!CurMethod)
-    return 0;
-  
+    return nullptr;
+
   ObjCInterfaceDecl *Class = CurMethod->getClassInterface();
   if (!Class)
-    return 0;
-  
+    return nullptr;
+
   // Try to find a superclass method with the same selector.
-  ObjCMethodDecl *SuperMethod = 0;
+  ObjCMethodDecl *SuperMethod = nullptr;
   while ((Class = Class->getSuperClass()) && !SuperMethod) {
     // Check in the class
     SuperMethod = Class->getMethod(CurMethod->getSelector(), 
@@ -5181,10 +5123,7 @@
 
     // Check in categories or class extensions.
     if (!SuperMethod) {
-      for (ObjCInterfaceDecl::known_categories_iterator
-             Cat = Class->known_categories_begin(),
-             CatEnd = Class->known_categories_end();
-           Cat != CatEnd; ++Cat) {
+      for (const auto *Cat : Class->known_categories()) {
         if ((SuperMethod = Cat->getMethod(CurMethod->getSelector(),
                                                CurMethod->isInstanceMethod())))
           break;
@@ -5193,13 +5132,13 @@
   }
 
   if (!SuperMethod)
-    return 0;
-  
+    return nullptr;
+
   // Check whether the superclass method has the same signature.
   if (CurMethod->param_size() != SuperMethod->param_size() ||
       CurMethod->isVariadic() != SuperMethod->isVariadic())
-    return 0;
-      
+    return nullptr;
+
   for (ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin(),
                                    CurPEnd = CurMethod->param_end(),
                                     SuperP = SuperMethod->param_begin();
@@ -5207,11 +5146,11 @@
     // Make sure the parameter types are compatible.
     if (!S.Context.hasSameUnqualifiedType((*CurP)->getType(), 
                                           (*SuperP)->getType()))
-      return 0;
-    
+      return nullptr;
+
     // Make sure we have a parameter name to forward!
     if (!(*CurP)->getIdentifier())
-      return 0;
+      return nullptr;
   }
   
   // We have a superclass method. Now, form the send-to-super completion.
@@ -5306,7 +5245,7 @@
 void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
                                         ArrayRef<IdentifierInfo *> SelIdents,
                                         bool AtArgumentExpression) {
-  ObjCInterfaceDecl *CDecl = 0;
+  ObjCInterfaceDecl *CDecl = nullptr;
   if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
     // Figure out which interface we're in.
     CDecl = CurMethod->getClassInterface();
@@ -5322,7 +5261,7 @@
       // We are inside an instance method, which means that the message
       // send [super ...] is actually calling an instance method on the
       // current object.
-      return CodeCompleteObjCInstanceMessage(S, 0, SelIdents,
+      return CodeCompleteObjCInstanceMessage(S, nullptr, SelIdents,
                                              AtArgumentExpression,
                                              CDecl);
     }
@@ -5383,7 +5322,7 @@
       if (R.Priority <= BestPriority) {
         const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(R.Declaration);
         if (NumSelIdents <= Method->param_size()) {
-          QualType MyPreferredType = Method->param_begin()[NumSelIdents - 1]
+          QualType MyPreferredType = Method->parameters()[NumSelIdents - 1]
                                        ->getType();
           if (R.Priority < BestPriority || PreferredType.isNull()) {
             BestPriority = R.Priority;
@@ -5407,12 +5346,12 @@
                                        bool IsSuper,
                                        ResultBuilder &Results) {
   typedef CodeCompletionResult Result;
-  ObjCInterfaceDecl *CDecl = 0;
-  
+  ObjCInterfaceDecl *CDecl = nullptr;
+
   // If the given name refers to an interface type, retrieve the
   // corresponding declaration.
   if (Receiver) {
-    QualType T = SemaRef.GetTypeFromParser(Receiver, 0);
+    QualType T = SemaRef.GetTypeFromParser(Receiver, nullptr);
     if (!T.isNull()) 
       if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
         CDecl = Interface->getInterface();
@@ -5465,8 +5404,9 @@
            MethList = MethList->getNext()) {
         if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents))
           continue;
-        
-        Result R(MethList->Method, Results.getBasePriority(MethList->Method),0);
+
+        Result R(MethList->Method, Results.getBasePriority(MethList->Method),
+                 nullptr);
         R.StartParameter = SelIdents.size();
         R.AllParametersAreInformative = false;
         Results.MaybeAddResult(R, SemaRef.CurContext);
@@ -5526,7 +5466,7 @@
     ExprResult Conv = DefaultFunctionArrayLvalueConversion(RecExpr);
     if (Conv.isInvalid()) // conversion failed. bail.
       return;
-    RecExpr = Conv.take();
+    RecExpr = Conv.get();
   }
   QualType ReceiverType = RecExpr? RecExpr->getType() 
                           : Super? Context.getObjCObjectPointerType(
@@ -5536,7 +5476,7 @@
   // If we're messaging an expression with type "id" or "Class", check
   // whether we know something special about the receiver that allows
   // us to assume a more-specific receiver type.
-  if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
+  if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType()) {
     if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr)) {
       if (ReceiverType->isObjCClassType())
         return CodeCompleteObjCClassMessage(S, 
@@ -5547,6 +5487,13 @@
       ReceiverType = Context.getObjCObjectPointerType(
                                           Context.getObjCInterfaceType(IFace));
     }
+  } else if (RecExpr && getLangOpts().CPlusPlus) {
+    ExprResult Conv = PerformContextuallyConvertToObjCPointer(RecExpr);
+    if (Conv.isUsable()) {
+      RecExpr = Conv.get();
+      ReceiverType = RecExpr->getType();
+    }
+  }
 
   // Build the set of methods we can see.
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
@@ -5587,10 +5534,8 @@
   else if (const ObjCObjectPointerType *QualID
              = ReceiverType->getAsObjCQualifiedIdType()) {
     // Search protocols for instance methods.
-    for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
-                                              E = QualID->qual_end(); 
-         I != E; ++I)
-      AddObjCMethods(*I, true, MK_Any, SelIdents, CurContext,
+    for (auto *I : QualID->quals())
+      AddObjCMethods(I, true, MK_Any, SelIdents, CurContext,
                      Selectors, AtArgumentExpression, Results);
   }
   // Handle messages to a pointer to interface type.
@@ -5602,10 +5547,8 @@
                    Results);
     
     // Search protocols for instance methods.
-    for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
-         E = IFacePtr->qual_end(); 
-         I != E; ++I)
-      AddObjCMethods(*I, true, MK_Any, SelIdents, CurContext,
+    for (auto *I : IFacePtr->quals())
+      AddObjCMethods(I, true, MK_Any, SelIdents, CurContext,
                      Selectors, AtArgumentExpression, Results);
   }
   // Handle messages to "id".
@@ -5637,8 +5580,9 @@
         
         if (!Selectors.insert(MethList->Method->getSelector()))
           continue;
-        
-        Result R(MethList->Method, Results.getBasePriority(MethList->Method),0);
+
+        Result R(MethList->Method, Results.getBasePriority(MethList->Method),
+                 nullptr);
         R.StartParameter = SelIdents.size();
         R.AllParametersAreInformative = false;
         Results.MaybeAddResult(R, CurContext);
@@ -5750,14 +5694,12 @@
                                ResultBuilder &Results) {
   typedef CodeCompletionResult Result;
   
-  for (DeclContext::decl_iterator D = Ctx->decls_begin(), 
-                               DEnd = Ctx->decls_end();
-       D != DEnd; ++D) {
+  for (const auto *D : Ctx->decls()) {
     // Record any protocols we find.
-    if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
+    if (const auto *Proto = dyn_cast<ObjCProtocolDecl>(D))
       if (!OnlyForwardDeclarations || !Proto->hasDefinition())
-        Results.AddResult(Result(Proto, Results.getBasePriority(Proto), 0),
-                          CurContext, 0, false);
+        Results.AddResult(Result(Proto, Results.getBasePriority(Proto),nullptr),
+                          CurContext, nullptr, false);
   }
 }
 
@@ -5818,15 +5760,13 @@
                                 ResultBuilder &Results) {
   typedef CodeCompletionResult Result;
   
-  for (DeclContext::decl_iterator D = Ctx->decls_begin(), 
-                               DEnd = Ctx->decls_end();
-       D != DEnd; ++D) {
+  for (const auto *D : Ctx->decls()) {
     // Record any interfaces we find.
-    if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
+    if (const auto *Class = dyn_cast<ObjCInterfaceDecl>(D))
       if ((!OnlyForwardDeclarations || !Class->hasDefinition()) &&
           (!OnlyUnimplemented || !Class->getImplementation()))
-        Results.AddResult(Result(Class, Results.getBasePriority(Class), 0),
-                          CurContext, 0, false);
+        Results.AddResult(Result(Class, Results.getBasePriority(Class),nullptr),
+                          CurContext, nullptr, false);
   }
 }
 
@@ -5909,24 +5849,19 @@
   NamedDecl *CurClass
     = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
   if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass)){
-    for (ObjCInterfaceDecl::visible_categories_iterator
-           Cat = Class->visible_categories_begin(),
-           CatEnd = Class->visible_categories_end();
-         Cat != CatEnd; ++Cat) {
+    for (const auto *Cat : Class->visible_categories())
       CategoryNames.insert(Cat->getIdentifier());
-    }
   }
 
   // Add all of the categories we know about.
   Results.EnterNewScope();
   TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
-  for (DeclContext::decl_iterator D = TU->decls_begin(), 
-                               DEnd = TU->decls_end();
-       D != DEnd; ++D) 
-    if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
+  for (const auto *D : TU->decls()) 
+    if (const auto *Category = dyn_cast<ObjCCategoryDecl>(D))
       if (CategoryNames.insert(Category->getIdentifier()))
-        Results.AddResult(Result(Category, Results.getBasePriority(Category),0),
-                          CurContext, 0, false);
+        Results.AddResult(Result(Category, Results.getBasePriority(Category),
+                                 nullptr),
+                          CurContext, nullptr, false);
   Results.ExitScope();
   
   HandleCodeCompleteResults(this, CodeCompleter, 
@@ -5959,14 +5894,11 @@
   Results.EnterNewScope();
   bool IgnoreImplemented = true;
   while (Class) {
-    for (ObjCInterfaceDecl::visible_categories_iterator
-           Cat = Class->visible_categories_begin(),
-           CatEnd = Class->visible_categories_end();
-         Cat != CatEnd; ++Cat) {
+    for (const auto *Cat : Class->visible_categories()) {
       if ((!IgnoreImplemented || !Cat->getImplementation()) &&
           CategoryNames.insert(Cat->getIdentifier()))
-        Results.AddResult(Result(*Cat, Results.getBasePriority(*Cat), 0),
-                          CurContext, 0, false);
+        Results.AddResult(Result(Cat, Results.getBasePriority(Cat), nullptr),
+                          CurContext, nullptr, false);
     }
     
     Class = Class->getSuperClass();
@@ -5994,10 +5926,8 @@
 
   // Ignore any properties that have already been implemented.
   Container = getContainerDef(Container);
-  for (DeclContext::decl_iterator D = Container->decls_begin(),
-                               DEnd = Container->decls_end();
-       D != DEnd; ++D)
-    if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
+  for (const auto *D : Container->decls())
+    if (const auto *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(D))
       Results.Ignore(PropertyImpl->getPropertyDecl());
   
   // Add any properties that we find.
@@ -6035,7 +5965,7 @@
     return; 
   
   // Figure out which interface we're looking into.
-  ObjCInterfaceDecl *Class = 0;
+  ObjCInterfaceDecl *Class = nullptr;
   if (ObjCImplementationDecl *ClassImpl
                                  = dyn_cast<ObjCImplementationDecl>(Container))  
     Class = ClassImpl->getClassInterface();
@@ -6067,9 +5997,9 @@
   for(; Class; Class = Class->getSuperClass()) {
     for (ObjCIvarDecl *Ivar = Class->all_declared_ivar_begin(); Ivar; 
          Ivar = Ivar->getNextIvar()) {
-      Results.AddResult(Result(Ivar, Results.getBasePriority(Ivar), 0),
-                        CurContext, 0, false);
-      
+      Results.AddResult(Result(Ivar, Results.getBasePriority(Ivar), nullptr),
+                        CurContext, nullptr, false);
+
       // Determine whether we've seen an ivar with a name similar to the 
       // property.
       if ((PropertyName == Ivar->getIdentifier() ||
@@ -6144,11 +6074,8 @@
                                KnownMethods, InOriginalClass);
 
     // Add methods from any class extensions and categories.
-    for (ObjCInterfaceDecl::visible_categories_iterator
-           Cat = IFace->visible_categories_begin(),
-           CatEnd = IFace->visible_categories_end();
-         Cat != CatEnd; ++Cat) {
-      FindImplementableMethods(Context, *Cat, WantInstanceMethods, ReturnType,
+    for (auto *Cat : IFace->visible_categories()) {
+      FindImplementableMethods(Context, Cat, WantInstanceMethods, ReturnType,
                                KnownMethods, false);      
     }
 
@@ -6196,16 +6123,14 @@
   // Add methods in this container. This operation occurs last because
   // we want the methods from this container to override any methods
   // we've previously seen with the same selector.
-  for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
-                                       MEnd = Container->meth_end();
-       M != MEnd; ++M) {
+  for (auto *M : Container->methods()) {
     if (M->isInstanceMethod() == WantInstanceMethods) {
       if (!ReturnType.isNull() &&
-          !Context.hasSameUnqualifiedType(ReturnType, M->getResultType()))
+          !Context.hasSameUnqualifiedType(ReturnType, M->getReturnType()))
         continue;
 
       KnownMethods[M->getSelector()] =
-          KnownMethodsMap::mapped_type(*M, InOriginalClass);
+          KnownMethodsMap::mapped_type(M, InOriginalClass);
     }
   }
 }
@@ -6267,10 +6192,10 @@
     CodeCompletionAllocator &Allocator;
     StringRef Key;
     const char *CopiedKey;
-    
+
     KeyHolder(CodeCompletionAllocator &Allocator, StringRef Key)
-    : Allocator(Allocator), Key(Key), CopiedKey(0) { }
-    
+    : Allocator(Allocator), Key(Key), CopiedKey(nullptr) {}
+
     operator const char *() {
       if (CopiedKey)
         return CopiedKey;
@@ -6872,13 +6797,13 @@
   // Determine the return type of the method we're declaring, if
   // provided.
   QualType ReturnType = GetTypeFromParser(ReturnTy);
-  Decl *IDecl = 0;
+  Decl *IDecl = nullptr;
   if (CurContext->isObjCContainer()) {
       ObjCContainerDecl *OCD = dyn_cast<ObjCContainerDecl>(CurContext);
       IDecl = cast<Decl>(OCD);
   }
   // Determine where we should start searching for methods.
-  ObjCContainerDecl *SearchDecl = 0;
+  ObjCContainerDecl *SearchDecl = nullptr;
   bool IsInImplementation = false;
   if (Decl *D = IDecl) {
     if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
@@ -6900,7 +6825,7 @@
   if (!SearchDecl) {
     HandleCodeCompleteResults(this, CodeCompleter, 
                               CodeCompletionContext::CCC_Other,
-                              0, 0);
+                              nullptr, 0);
     return;
   }
     
@@ -6926,10 +6851,9 @@
     // If the result type was not already provided, add it to the
     // pattern as (type).
     if (ReturnType.isNull())
-      AddObjCPassingTypeChunk(Method->getResultType(),
-                              Method->getObjCDeclQualifier(),
-                              Context, Policy,
-                              Builder); 
+      AddObjCPassingTypeChunk(Method->getReturnType(),
+                              Method->getObjCDeclQualifier(), Context, Policy,
+                              Builder);
 
     Selector Sel = Method->getSelector();
 
@@ -6973,7 +6897,7 @@
       Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
       Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
       Builder.AddChunk(CodeCompletionString::CK_VerticalSpace);
-      if (!Method->getResultType()->isVoidType()) {
+      if (!Method->getReturnType()->isVoidType()) {
         // If the result type is not void, add a return clause.
         Builder.AddTextChunk("return");
         Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
@@ -7011,23 +6935,14 @@
       if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(SearchDecl))
         IFace = Category->getClassInterface();
     
-    if (IFace) {
-      for (ObjCInterfaceDecl::visible_categories_iterator
-             Cat = IFace->visible_categories_begin(),
-             CatEnd = IFace->visible_categories_end();
-           Cat != CatEnd; ++Cat) {
-        Containers.push_back(*Cat);
-      }
-    }
+    if (IFace)
+      for (auto *Cat : IFace->visible_categories())
+        Containers.push_back(Cat);
     
-    for (unsigned I = 0, N = Containers.size(); I != N; ++I) {
-      for (ObjCContainerDecl::prop_iterator P = Containers[I]->prop_begin(),
-                                         PEnd = Containers[I]->prop_end(); 
-           P != PEnd; ++P) {
-        AddObjCKeyValueCompletions(*P, IsInstanceMethod, ReturnType, Context, 
+    for (unsigned I = 0, N = Containers.size(); I != N; ++I)
+      for (auto *P : Containers[I]->properties())
+        AddObjCKeyValueCompletions(P, IsInstanceMethod, ReturnType, Context, 
                                    KnownSelectors, Results);
-      }
-    }
   }
   
   Results.ExitScope();
@@ -7079,7 +6994,7 @@
         // Suggest parameter names we've seen before.
         unsigned NumSelIdents = SelIdents.size();
         if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) {
-          ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1];
+          ParmVarDecl *Param = MethList->Method->parameters()[NumSelIdents-1];
           if (Param->getIdentifier()) {
             CodeCompletionBuilder Builder(Results.getAllocator(),
                                           Results.getCodeCompletionTUInfo());
@@ -7091,8 +7006,9 @@
         
         continue;
       }
-      
-      Result R(MethList->Method, Results.getBasePriority(MethList->Method), 0);
+
+      Result R(MethList->Method, Results.getBasePriority(MethList->Method),
+               nullptr);
       R.StartParameter = SelIdents.size();
       R.AllParametersAreInformative = false;
       R.DeclaringEntity = true;
@@ -7338,7 +7254,7 @@
 void Sema::CodeCompleteNaturalLanguage() {
   HandleCodeCompleteResults(this, CodeCompleter,
                             CodeCompletionContext::CCC_NaturalLanguage,
-                            0, 0);
+                            nullptr, 0);
 }
 
 void Sema::GatherGlobalCodeCompletions(CodeCompletionAllocator &Allocator,
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 1892809..f225865 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -25,12 +25,14 @@
 #include "clang/AST/EvaluatedExprVisitor.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/StmtCXX.h"
+#include "clang/Basic/Builtins.h"
 #include "clang/Basic/PartialDiagnostic.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
-#include "clang/Lex/HeaderSearch.h" // FIXME: Sema shouldn't depend on Lex
-#include "clang/Lex/ModuleLoader.h" // FIXME: Sema shouldn't depend on Lex
-#include "clang/Lex/Preprocessor.h" // FIXME: Sema shouldn't depend on Lex
+#include "clang/Lex/HeaderSearch.h" // TODO: Sema shouldn't depend on Lex
+#include "clang/Lex/Lexer.h" // TODO: Extract static functions to fix layering.
+#include "clang/Lex/ModuleLoader.h" // TODO: Sema shouldn't depend on Lex
+#include "clang/Lex/Preprocessor.h" // Included for isCodeCompletionEnabled()
 #include "clang/Parse/ParseDiagnostic.h"
 #include "clang/Sema/CXXFieldCollector.h"
 #include "clang/Sema/DeclSpec.h"
@@ -62,24 +64,29 @@
 
 class TypeNameValidatorCCC : public CorrectionCandidateCallback {
  public:
-  TypeNameValidatorCCC(bool AllowInvalid, bool WantClass=false)
-      : AllowInvalidDecl(AllowInvalid), WantClassName(WantClass) {
+  TypeNameValidatorCCC(bool AllowInvalid, bool WantClass=false,
+                       bool AllowTemplates=false)
+      : AllowInvalidDecl(AllowInvalid), WantClassName(WantClass),
+        AllowClassTemplates(AllowTemplates) {
     WantExpressionKeywords = false;
     WantCXXNamedCasts = false;
     WantRemainingKeywords = false;
   }
 
-  virtual bool ValidateCandidate(const TypoCorrection &candidate) {
-    if (NamedDecl *ND = candidate.getCorrectionDecl())
-      return (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND)) &&
-          (AllowInvalidDecl || !ND->isInvalidDecl());
-    else
-      return !WantClassName && candidate.isKeyword();
+  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);
+      return (IsType || AllowedTemplate) &&
+             (AllowInvalidDecl || !ND->isInvalidDecl());
+    }
+    return !WantClassName && candidate.isKeyword();
   }
 
  private:
   bool AllowInvalidDecl;
   bool WantClassName;
+  bool AllowClassTemplates;
 };
 
 }
@@ -121,6 +128,65 @@
   return false;
 }
 
+static ParsedType recoverFromTypeInKnownDependentBase(Sema &S,
+                                                      const IdentifierInfo &II,
+                                                      SourceLocation NameLoc) {
+  // Find the first parent class template context, if any.
+  // FIXME: Perform the lookup in all enclosing class templates.
+  const CXXRecordDecl *RD = nullptr;
+  for (DeclContext *DC = S.CurContext; DC; DC = DC->getParent()) {
+    RD = dyn_cast<CXXRecordDecl>(DC);
+    if (RD && RD->getDescribedClassTemplate())
+      break;
+  }
+  if (!RD)
+    return ParsedType();
+
+  // Look for type decls in dependent base classes that have known primary
+  // templates.
+  bool FoundTypeDecl = false;
+  for (const auto &Base : RD->bases()) {
+    auto *TST = Base.getType()->getAs<TemplateSpecializationType>();
+    if (!TST || !TST->isDependentType())
+      continue;
+    auto *TD = TST->getTemplateName().getAsTemplateDecl();
+    if (!TD)
+      continue;
+    auto *BasePrimaryTemplate = cast<CXXRecordDecl>(TD->getTemplatedDecl());
+    // FIXME: Allow lookup into non-dependent bases of dependent bases, possibly
+    // by calling or integrating with the main LookupQualifiedName mechanism.
+    for (NamedDecl *ND : BasePrimaryTemplate->lookup(&II)) {
+      if (FoundTypeDecl)
+        return ParsedType();
+      FoundTypeDecl = isa<TypeDecl>(ND);
+      if (!FoundTypeDecl)
+        return ParsedType();
+    }
+  }
+  if (!FoundTypeDecl)
+    return ParsedType();
+
+  // We found some types in dependent base classes.  Recover as if the user
+  // wrote 'typename MyClass::II' instead of 'II'.  We'll fully resolve the
+  // lookup during template instantiation.
+  S.Diag(NameLoc, diag::ext_found_via_dependent_bases_lookup) << &II;
+
+  ASTContext &Context = S.Context;
+  auto *NNS = NestedNameSpecifier::Create(Context, nullptr, false,
+                                          cast<Type>(Context.getRecordType(RD)));
+  QualType T = Context.getDependentNameType(ETK_Typename, NNS, &II);
+
+  CXXScopeSpec SS;
+  SS.MakeTrivial(Context, NNS, SourceRange(NameLoc));
+
+  TypeLocBuilder Builder;
+  DependentNameTypeLoc DepTL = Builder.push<DependentNameTypeLoc>(T);
+  DepTL.setNameLoc(NameLoc);
+  DepTL.setElaboratedKeywordLoc(SourceLocation());
+  DepTL.setQualifierLoc(SS.getWithLocInContext(Context));
+  return S.CreateParsedType(T, Builder.getTypeSourceInfo(Context, T));
+}
+
 /// \brief If the identifier refers to a type name within this scope,
 /// return the declaration of that type.
 ///
@@ -137,7 +203,7 @@
                              bool WantNontrivialTypeSourceInfo,
                              IdentifierInfo **CorrectedII) {
   // Determine where we will perform name lookup.
-  DeclContext *LookupCtx = 0;
+  DeclContext *LookupCtx = nullptr;
   if (ObjectTypePtr) {
     QualType ObjectType = ObjectTypePtr.get();
     if (ObjectType->isRecordType())
@@ -165,11 +231,9 @@
           return ActOnTypenameType(S, SourceLocation(), *SS, II, NameLoc).get();
         
         NestedNameSpecifierLoc QualifierLoc = SS->getWithLocInContext(Context);
-        QualType T =
-          CheckTypenameType(ETK_None, SourceLocation(), QualifierLoc,
-                            II, NameLoc);
-        
-          return ParsedType::make(T);
+        QualType T = CheckTypenameType(ETK_None, SourceLocation(), QualifierLoc,
+                                       II, NameLoc);
+        return ParsedType::make(T);
       }
       
       return ParsedType();
@@ -204,16 +268,25 @@
   } else {
     // Perform unqualified name lookup.
     LookupName(Result, S);
+
+    // For unqualified lookup in a class template in MSVC mode, look into
+    // dependent base classes where the primary class template is known.
+    if (Result.empty() && getLangOpts().MSVCCompat && (!SS || SS->isEmpty())) {
+      if (ParsedType TypeInBase =
+              recoverFromTypeInKnownDependentBase(*this, II, NameLoc))
+        return TypeInBase;
+    }
   }
-  
-  NamedDecl *IIDecl = 0;
+
+  NamedDecl *IIDecl = nullptr;
   switch (Result.getResultKind()) {
   case LookupResult::NotFound:
   case LookupResult::NotFoundInCurrentInstantiation:
     if (CorrectedII) {
       TypeNameValidatorCCC Validator(true, isClassName);
       TypoCorrection Correction = CorrectTypo(Result.getLookupNameInfo(),
-                                              Kind, S, SS, Validator);
+                                              Kind, S, SS, Validator,
+                                              CTK_ErrorRecovery);
       IdentifierInfo *NewII = Correction.getCorrectionAsIdentifierInfo();
       TemplateTy Template;
       bool MemberOfUnknownSpecialization;
@@ -303,8 +376,7 @@
   if (TypeDecl *TD = dyn_cast<TypeDecl>(IIDecl)) {
     DiagnoseUseOfDecl(IIDecl, NameLoc);
 
-    if (T.isNull())
-      T = Context.getTypeDeclType(TD);
+    T = Context.getTypeDeclType(TD);
 
     // NOTE: avoid constructing an ElaboratedType(Loc) if this is a
     // constructor or destructor name (in such a case, the scope specifier
@@ -338,6 +410,50 @@
   return ParsedType::make(T);
 }
 
+// Builds a fake NNS for the given decl context.
+static NestedNameSpecifier *
+synthesizeCurrentNestedNameSpecifier(ASTContext &Context, DeclContext *DC) {
+  for (;; DC = DC->getLookupParent()) {
+    DC = DC->getPrimaryContext();
+    auto *ND = dyn_cast<NamespaceDecl>(DC);
+    if (ND && !ND->isInline() && !ND->isAnonymousNamespace())
+      return NestedNameSpecifier::Create(Context, nullptr, ND);
+    else if (auto *RD = dyn_cast<CXXRecordDecl>(DC))
+      return NestedNameSpecifier::Create(Context, nullptr, RD->isTemplateDecl(),
+                                         RD->getTypeForDecl());
+    else if (isa<TranslationUnitDecl>(DC))
+      return NestedNameSpecifier::GlobalSpecifier(Context);
+  }
+  llvm_unreachable("something isn't in TU scope?");
+}
+
+ParsedType Sema::ActOnDelayedDefaultTemplateArg(const IdentifierInfo &II,
+                                                SourceLocation NameLoc) {
+  // Accepting an undeclared identifier as a default argument for a template
+  // type parameter is a Microsoft extension.
+  Diag(NameLoc, diag::ext_ms_delayed_template_argument) << &II;
+
+  // Build a fake DependentNameType that will perform lookup into CurContext at
+  // instantiation time.  The name specifier isn't dependent, so template
+  // instantiation won't transform it.  It will retry the lookup, however.
+  NestedNameSpecifier *NNS =
+      synthesizeCurrentNestedNameSpecifier(Context, CurContext);
+  QualType T = Context.getDependentNameType(ETK_None, NNS, &II);
+
+  // Build type location information.  We synthesized the qualifier, so we have
+  // to build a fake NestedNameSpecifierLoc.
+  NestedNameSpecifierLocBuilder NNSLocBuilder;
+  NNSLocBuilder.MakeTrivial(Context, NNS, SourceRange(NameLoc));
+  NestedNameSpecifierLoc QualifierLoc = NNSLocBuilder.getWithLocInContext(Context);
+
+  TypeLocBuilder Builder;
+  DependentNameTypeLoc DepTL = Builder.push<DependentNameTypeLoc>(T);
+  DepTL.setNameLoc(NameLoc);
+  DepTL.setElaboratedKeywordLoc(SourceLocation());
+  DepTL.setQualifierLoc(QualifierLoc);
+  return CreateParsedType(T, Builder.getTypeSourceInfo(Context, T));
+}
+
 /// isTagName() - This method is called *for error recovery purposes only*
 /// to determine if the specified name is a valid tag name ("struct foo").  If
 /// so, this returns the TST for the tag corresponding to it (TST_enum,
@@ -381,29 +497,29 @@
     const Type *Ty = SS->getScopeRep()->getAsType();
 
     CXXRecordDecl *RD = cast<CXXRecordDecl>(CurContext);
-    for (CXXRecordDecl::base_class_const_iterator Base = RD->bases_begin(),
-          BaseEnd = RD->bases_end(); Base != BaseEnd; ++Base)
-      if (Context.hasSameUnqualifiedType(QualType(Ty, 1), Base->getType()))
+    for (const auto &Base : RD->bases())
+      if (Context.hasSameUnqualifiedType(QualType(Ty, 1), Base.getType()))
         return true;
     return S->isFunctionPrototypeScope();
   } 
   return CurContext->isFunctionOrMethod() || S->isFunctionPrototypeScope();
 }
 
-bool Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II,
+void Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II,
                                    SourceLocation IILoc,
                                    Scope *S,
                                    CXXScopeSpec *SS,
-                                   ParsedType &SuggestedType) {
+                                   ParsedType &SuggestedType,
+                                   bool AllowClassTemplates) {
   // We don't have anything to suggest (yet).
   SuggestedType = ParsedType();
   
   // There may have been a typo in the name of the type. Look up typo
   // results, in case we have something that we can suggest.
-  TypeNameValidatorCCC Validator(false);
+  TypeNameValidatorCCC Validator(false, false, AllowClassTemplates);
   if (TypoCorrection Corrected = CorrectTypo(DeclarationNameInfo(II, IILoc),
                                              LookupOrdinaryName, S, SS,
-                                             Validator)) {
+                                             Validator, CTK_ErrorRecovery)) {
     if (Corrected.isKeyword()) {
       // We corrected to a keyword.
       diagnoseTypo(Corrected, PDiag(diag::err_unknown_typename_suggest) << II);
@@ -434,7 +550,7 @@
                                   /*IsCtorOrDtorName=*/false,
                                   /*NonTrivialTypeSourceInfo=*/true);
     }
-    return true;
+    return;
   }
 
   if (getLangOpts().CPlusPlus) {
@@ -453,7 +569,7 @@
         Diag(TplDecl->getLocation(), diag::note_template_decl_here)
           << TplDecl->getTemplateParameters()->getSourceRange();
       }
-      return true;
+      return;
     }
   }
 
@@ -467,11 +583,11 @@
       << II << DC << SS->getRange();
   else if (isDependentScopeSpecifier(*SS)) {
     unsigned DiagID = diag::err_typename_missing;
-    if (getLangOpts().MicrosoftMode && isMicrosoftMissingTypename(SS, S))
-      DiagID = diag::warn_typename_missing;
+    if (getLangOpts().MSVCCompat && isMicrosoftMissingTypename(SS, S))
+      DiagID = diag::ext_typename_missing;
 
     Diag(SS->getRange().getBegin(), DiagID)
-      << (NestedNameSpecifier *)SS->getScopeRep() << II->getName()
+      << SS->getScopeRep() << II->getName()
       << SourceRange(SS->getRange().getBegin(), IILoc)
       << FixItHint::CreateInsertion(SS->getRange().getBegin(), "typename ");
     SuggestedType = ActOnTypenameType(S, SourceLocation(),
@@ -480,8 +596,6 @@
     assert(SS && SS->isInvalid() && 
            "Invalid scope specifier has already been diagnosed");
   }
-  
-  return true;
 }
 
 /// \brief Determine whether the given result set contains either a type name
@@ -508,35 +622,30 @@
   LookupResult R(SemaRef, Name, NameLoc, Sema::LookupTagName);
   SemaRef.LookupParsedName(R, S, &SS);
   if (TagDecl *Tag = R.getAsSingle<TagDecl>()) {
-    const char *TagName = 0;
-    const char *FixItTagName = 0;
+    StringRef FixItTagName;
     switch (Tag->getTagKind()) {
       case TTK_Class:
-        TagName = "class";
         FixItTagName = "class ";
         break;
 
       case TTK_Enum:
-        TagName = "enum";
         FixItTagName = "enum ";
         break;
 
       case TTK_Struct:
-        TagName = "struct";
         FixItTagName = "struct ";
         break;
 
       case TTK_Interface:
-        TagName = "__interface";
         FixItTagName = "__interface ";
         break;
 
       case TTK_Union:
-        TagName = "union";
         FixItTagName = "union ";
         break;
     }
 
+    StringRef TagName = FixItTagName.drop_back();
     SemaRef.Diag(NameLoc, diag::err_use_of_tag_name_without_tag)
       << Name << TagName << SemaRef.getLangOpts().CPlusPlus
       << FixItHint::CreateInsertion(NameLoc, FixItTagName);
@@ -579,16 +688,23 @@
                                             CorrectionCandidateCallback *CCC) {
   DeclarationNameInfo NameInfo(Name, NameLoc);
   ObjCMethodDecl *CurMethod = getCurMethodDecl();
-  
+
   if (NextToken.is(tok::coloncolon)) {
     BuildCXXNestedNameSpecifier(S, *Name, NameLoc, NextToken.getLocation(),
-                                QualType(), false, SS, 0, false);
-    
+                                QualType(), false, SS, nullptr, false);
   }
-      
+
   LookupResult Result(*this, Name, NameLoc, LookupOrdinaryName);
   LookupParsedName(Result, S, &SS, !CurMethod);
-  
+
+  // For unqualified lookup in a class template in MSVC mode, look into
+  // dependent base classes where the primary class template is known.
+  if (Result.empty() && SS.isEmpty() && getLangOpts().MSVCCompat) {
+    if (ParsedType TypeInBase =
+            recoverFromTypeInKnownDependentBase(*this, *Name, NameLoc))
+      return TypeInBase;
+  }
+
   // Perform lookup for Objective-C instance variables (including automatically 
   // synthesized instance variables), if we're in an Objective-C method.
   // FIXME: This lookup really, really needs to be folded in to the normal
@@ -646,13 +762,14 @@
       SecondTry = true;
       if (TypoCorrection Corrected = CorrectTypo(Result.getLookupNameInfo(),
                                                  Result.getLookupKind(), S, 
-                                                 &SS, *CCC)) {
+                                                 &SS, *CCC,
+                                                 CTK_ErrorRecovery)) {
         unsigned UnqualifiedDiag = diag::err_undeclared_var_use_suggest;
         unsigned QualifiedDiag = diag::err_no_member_suggest;
 
         NamedDecl *FirstDecl = Corrected.getCorrectionDecl();
         NamedDecl *UnderlyingFirstDecl
-          = FirstDecl? FirstDecl->getUnderlyingDecl() : 0;
+          = FirstDecl? FirstDecl->getUnderlyingDecl() : nullptr;
         if (getLangOpts().CPlusPlus && NextToken.is(tok::less) &&
             UnderlyingFirstDecl && isa<TemplateDecl>(UnderlyingFirstDecl)) {
           UnqualifiedDiag = diag::err_no_template_suggest;
@@ -725,7 +842,7 @@
     // keyword here.
     return ActOnDependentIdExpression(SS, /*TemplateKWLoc=*/SourceLocation(),
                                       NameInfo, IsAddressOfOperand,
-                                      /*TemplateArgs=*/0);
+                                      /*TemplateArgs=*/nullptr);
   }
 
   case LookupResult::Found:
@@ -817,8 +934,8 @@
   ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(FirstDecl);
   if (!Class) {
     // FIXME: It's unfortunate that we don't have a Type node for handling this.
-    if (ObjCCompatibleAliasDecl *Alias 
-                                = dyn_cast<ObjCCompatibleAliasDecl>(FirstDecl))
+    if (ObjCCompatibleAliasDecl *Alias =
+            dyn_cast<ObjCCompatibleAliasDecl>(FirstDecl))
       Class = Alias->getClassInterface();
   }
   
@@ -845,7 +962,8 @@
   // seems likely a type is wanted instead of the non-type that was found.
   bool NextIsOp = NextToken.is(tok::amp) || NextToken.is(tok::star);
   if ((NextToken.is(tok::identifier) ||
-       (NextIsOp && FirstDecl->isFunctionOrFunctionTemplate())) &&
+       (NextIsOp &&
+        FirstDecl->getUnderlyingDecl()->isFunctionOrFunctionTemplate())) &&
       isTagTypeWithMissingTag(*this, Result, S, SS, Name, NameLoc)) {
     TypeDecl *Type = Result.getAsSingle<TypeDecl>();
     DiagnoseUseOfDecl(Type, NameLoc);
@@ -856,7 +974,8 @@
   }
   
   if (FirstDecl->isCXXClassMember())
-    return BuildPossibleImplicitMemberExpr(SS, SourceLocation(), Result, 0);
+    return BuildPossibleImplicitMemberExpr(SS, SourceLocation(), Result,
+                                           nullptr);
 
   bool ADL = UseArgumentDependentLookup(SS, Result, NextToken.is(tok::l_paren));
   return BuildDeclarationNameExpr(SS, Result, ADL);
@@ -870,7 +989,16 @@
   // Functions defined inline within classes aren't parsed until we've
   // finished parsing the top-level class, so the top-level class is
   // the context we'll need to return to.
-  if (isa<FunctionDecl>(DC)) {
+  // A Lambda call operator whose parent is a class must not be treated 
+  // as an inline member function.  A Lambda can be used legally
+  // either as an in-class member initializer or a default argument.  These
+  // are parsed once the class has been marked complete and so the containing
+  // context would be the nested class (when the lambda is defined in one);
+  // If the class is not complete, then the lambda is being used in an 
+  // ill-formed fashion (such as to specify the width of a bit-field, or
+  // in an array-bound) - in which case we still want to return the 
+  // lexically containing DC (which could be a nested class). 
+  if (isa<FunctionDecl>(DC) && !isLambdaCallOperator(DC)) {
     DC = DC->getLexicalParent();
 
     // A function not defined within a class will always return to its
@@ -953,12 +1081,9 @@
 
 
 void Sema::ActOnReenterFunctionContext(Scope* S, Decl *D) {
-  FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
-  if (FunctionTemplateDecl *TFD = dyn_cast_or_null<FunctionTemplateDecl>(D)) {
-    // We assume that the caller has already called
-    // ActOnReenterTemplateScope
-    FD = TFD->getTemplatedDecl();
-  }
+  // We assume that the caller has already called
+  // ActOnReenterTemplateScope so getTemplatedDecl() works.
+  FunctionDecl *FD = D->getAsFunction();
   if (!FD)
     return;
 
@@ -1077,9 +1202,8 @@
 }
 
 bool Sema::isDeclInScope(NamedDecl *D, DeclContext *Ctx, Scope *S,
-                         bool ExplicitInstantiationOrSpecialization) {
-  return IdResolver.isDeclInScope(D, Ctx, S,
-                                  ExplicitInstantiationOrSpecialization);
+                         bool AllowInlineNamespace) {
+  return IdResolver.isDeclInScope(D, Ctx, S, AllowInlineNamespace);
 }
 
 Scope *Sema::getScopeForDeclContext(Scope *S, DeclContext *DC) {
@@ -1090,7 +1214,7 @@
         return S;
   } while ((S = S->getParent()));
 
-  return 0;
+  return nullptr;
 }
 
 static bool isOutOfScopePreviousDeclaration(NamedDecl *,
@@ -1099,21 +1223,19 @@
 
 /// Filters out lookup results that don't fall within the given scope
 /// as determined by isDeclInScope.
-void Sema::FilterLookupForScope(LookupResult &R,
-                                DeclContext *Ctx, Scope *S,
+void Sema::FilterLookupForScope(LookupResult &R, DeclContext *Ctx, Scope *S,
                                 bool ConsiderLinkage,
-                                bool ExplicitInstantiationOrSpecialization) {
+                                bool AllowInlineNamespace) {
   LookupResult::Filter F = R.makeFilter();
   while (F.hasNext()) {
     NamedDecl *D = F.next();
 
-    if (isDeclInScope(D, Ctx, S, ExplicitInstantiationOrSpecialization))
+    if (isDeclInScope(D, Ctx, S, AllowInlineNamespace))
       continue;
 
-    if (ConsiderLinkage &&
-        isOutOfScopePreviousDeclaration(D, Ctx, Context))
+    if (ConsiderLinkage && isOutOfScopePreviousDeclaration(D, Ctx, Context))
       continue;
-    
+
     F.erase();
   }
 
@@ -1164,8 +1286,8 @@
 //
 // When we see foo we don't know if after the typedef we will get 'A' or '*A'
 // for example. If 'A', foo will have external linkage. If we have '*A',
-// foo will have no linkage. Since we can't know untill we get to the end
-// of the typedef, this function finds out if D might have non external linkage.
+// foo will have no linkage. Since we can't know until we get to the end
+// of the typedef, this function finds out if D might have non-external linkage.
 // Callers should verify at the end of the TU if it D has external linkage or
 // not.
 bool Sema::mightHaveNonExternalLinkage(const DeclaratorDecl *D) {
@@ -1195,7 +1317,8 @@
   if (D->isInvalidDecl() || D->isUsed() || D->hasAttr<UnusedAttr>())
     return false;
 
-  // Ignore class templates.
+  // Ignore all entities declared within templates, and out-of-line definitions
+  // of members of class templates.
   if (D->getDeclContext()->isDependentContext() ||
       D->getLexicalDeclContext()->isDependentContext())
     return false;
@@ -1209,8 +1332,7 @@
         return false;
     } else {
       // 'static inline' functions are defined in headers; don't warn.
-      if (FD->isInlineSpecified() &&
-          !isMainFileLoc(*this, FD->getLocation()))
+      if (FD->isInlined() && !isMainFileLoc(*this, FD->getLocation()))
         return false;
     }
 
@@ -1235,6 +1357,8 @@
   }
 
   // Only warn for unused decls internal to the translation unit.
+  // FIXME: This seems like a bogus check; it suppresses -Wunused-function
+  // for inline functions defined in the main source file, for instance.
   return mightHaveNonExternalLinkage(D);
 }
 
@@ -1262,7 +1386,8 @@
   if (D->isInvalidDecl())
     return false;
 
-  if (D->isReferenced() || D->isUsed() || D->hasAttr<UnusedAttr>())
+  if (D->isReferenced() || D->isUsed() || D->hasAttr<UnusedAttr>() ||
+      D->hasAttr<ObjCPreciseLifetimeAttr>())
     return false;
 
   if (isa<LabelDecl>(D))
@@ -1300,7 +1425,8 @@
           return false;
 
         if (const Expr *Init = VD->getInit()) {
-          if (const ExprWithCleanups *Cleanups = dyn_cast<ExprWithCleanups>(Init))
+          if (const ExprWithCleanups *Cleanups =
+                  dyn_cast<ExprWithCleanups>(Init))
             Init = Cleanups->getSubExpr();
           const CXXConstructExpr *Construct =
             dyn_cast<CXXConstructExpr>(Init);
@@ -1335,10 +1461,10 @@
 /// DiagnoseUnusedDecl - Emit warnings about declarations that are not used
 /// unless they are marked attr(unused).
 void Sema::DiagnoseUnusedDecl(const NamedDecl *D) {
-  FixItHint Hint;
   if (!ShouldDiagnoseUnusedDecl(D))
     return;
   
+  FixItHint Hint;
   GenerateFixForUnusedDecl(D, Context, Hint);
 
   unsigned DiagID;
@@ -1356,18 +1482,18 @@
   // Verify that we have no forward references left.  If so, there was a goto
   // or address of a label taken, but no definition of it.  Label fwd
   // definitions are indicated with a null substmt.
-  if (L->getStmt() == 0)
+  if (L->getStmt() == nullptr)
     S.Diag(L->getLocation(), diag::err_undeclared_label_use) <<L->getDeclName();
 }
 
 void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
+  S->mergeNRVOIntoParent();
+
   if (S->decl_empty()) return;
   assert((S->getFlags() & (Scope::DeclScope | Scope::TemplateParamScope)) &&
          "Scope shouldn't contain decls!");
 
-  for (Scope::decl_iterator I = S->decl_begin(), E = S->decl_end();
-       I != E; ++I) {
-    Decl *TmpD = (*I);
+  for (auto *TmpD : S->decls()) {
     assert(TmpD && "This decl didn't get pushed??");
 
     assert(isa<NamedDecl>(TmpD) && "Decl isn't NamedDecl?");
@@ -1386,16 +1512,6 @@
     // Remove this name from our lexical scope.
     IdResolver.RemoveDecl(D);
   }
-  DiagnoseUnusedBackingIvarInAccessor(S);
-}
-
-void Sema::ActOnStartFunctionDeclarator() {
-  ++InFunctionDeclarator;
-}
-
-void Sema::ActOnEndFunctionDeclarator() {
-  assert(InFunctionDeclarator);
-  --InFunctionDeclarator;
 }
 
 /// \brief Look for an Objective-C class in the translation unit.
@@ -1423,8 +1539,8 @@
     // find an Objective-C class name.
     DeclFilterCCC<ObjCInterfaceDecl> Validator;
     if (TypoCorrection C = CorrectTypo(DeclarationNameInfo(Id, IdLoc),
-                                       LookupOrdinaryName, TUScope, NULL,
-                                       Validator)) {
+                                       LookupOrdinaryName, TUScope, nullptr,
+                                       Validator, CTK_ErrorRecovery)) {
       diagnoseTypo(C, PDiag(diag::err_undef_interface_suggest) << Id);
       IDecl = C.getCorrectionDeclAs<ObjCInterfaceDecl>();
       Id = IDecl->getIdentifier();
@@ -1486,6 +1602,20 @@
       Context.setObjCSuperType(Context.getTagDeclType(TD));
 }
 
+static StringRef getHeaderName(ASTContext::GetBuiltinTypeError Error) {
+  switch (Error) {
+  case ASTContext::GE_None:
+    return "";
+  case ASTContext::GE_Missing_stdio:
+    return "stdio.h";
+  case ASTContext::GE_Missing_setjmp:
+    return "setjmp.h";
+  case ASTContext::GE_Missing_ucontext:
+    return "ucontext.h";
+  }
+  llvm_unreachable("unhandled error kind");
+}
+
 /// LazilyCreateBuiltin - The specified Builtin-ID was first used at
 /// file scope.  lazily create a decl for it. ForRedeclaration is true
 /// if we're creating this built-in in anticipation of redeclaring the
@@ -1499,28 +1629,12 @@
 
   ASTContext::GetBuiltinTypeError Error;
   QualType R = Context.GetBuiltinType(BID, Error);
-  switch (Error) {
-  case ASTContext::GE_None:
-    // Okay
-    break;
-
-  case ASTContext::GE_Missing_stdio:
+  if (Error) {
     if (ForRedeclaration)
-      Diag(Loc, diag::warn_implicit_decl_requires_stdio)
-        << Context.BuiltinInfo.GetName(BID);
-    return 0;
-
-  case ASTContext::GE_Missing_setjmp:
-    if (ForRedeclaration)
-      Diag(Loc, diag::warn_implicit_decl_requires_setjmp)
-        << Context.BuiltinInfo.GetName(BID);
-    return 0;
-
-  case ASTContext::GE_Missing_ucontext:
-    if (ForRedeclaration)
-      Diag(Loc, diag::warn_implicit_decl_requires_ucontext)
-        << Context.BuiltinInfo.GetName(BID);
-    return 0;
+      Diag(Loc, diag::warn_implicit_decl_requires_sysheader)
+          << getHeaderName(Error)
+          << Context.BuiltinInfo.GetName(BID);
+    return nullptr;
   }
 
   if (!ForRedeclaration && Context.BuiltinInfo.isPredefinedLibFunction(BID)) {
@@ -1528,11 +1642,10 @@
       << Context.BuiltinInfo.GetName(BID)
       << R;
     if (Context.BuiltinInfo.getHeaderName(BID) &&
-        Diags.getDiagnosticLevel(diag::ext_implicit_lib_function_decl, Loc)
-          != DiagnosticsEngine::Ignored)
-      Diag(Loc, diag::note_please_include_header)
-        << Context.BuiltinInfo.getHeaderName(BID)
-        << Context.BuiltinInfo.GetName(BID);
+        !Diags.isIgnored(diag::ext_implicit_lib_function_decl, Loc))
+      Diag(Loc, diag::note_include_header_or_declare)
+          << Context.BuiltinInfo.getHeaderName(BID)
+          << Context.BuiltinInfo.GetName(BID);
   }
 
   DeclContext *Parent = Context.getTranslationUnitDecl();
@@ -1540,13 +1653,14 @@
     LinkageSpecDecl *CLinkageDecl =
         LinkageSpecDecl::Create(Context, Parent, Loc, Loc,
                                 LinkageSpecDecl::lang_c, false);
+    CLinkageDecl->setImplicit();
     Parent->addDecl(CLinkageDecl);
     Parent = CLinkageDecl;
   }
 
   FunctionDecl *New = FunctionDecl::Create(Context,
                                            Parent,
-                                           Loc, Loc, II, R, /*TInfo=*/0,
+                                           Loc, Loc, II, R, /*TInfo=*/nullptr,
                                            SC_Extern,
                                            false,
                                            /*hasPrototype=*/true);
@@ -1556,12 +1670,11 @@
   // FunctionDecl.
   if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(R)) {
     SmallVector<ParmVarDecl*, 16> Params;
-    for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i) {
+    for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
       ParmVarDecl *parm =
-        ParmVarDecl::Create(Context, New, SourceLocation(),
-                            SourceLocation(), 0,
-                            FT->getArgType(i), /*TInfo=*/0,
-                            SC_None, 0);
+          ParmVarDecl::Create(Context, New, SourceLocation(), SourceLocation(),
+                              nullptr, FT->getParamType(i), /*TInfo=*/nullptr,
+                              SC_None, nullptr);
       parm->setScopeInfo(0, i);
       Params.push_back(parm);
     }
@@ -1780,7 +1893,7 @@
        Context.getSourceManager().isInSystemHeader(New->getLocation())))
     return;
 
-  Diag(New->getLocation(), diag::warn_redefinition_of_typedef)
+  Diag(New->getLocation(), diag::ext_redefinition_of_typedef)
     << New->getDeclName();
   Diag(Old->getLocation(), diag::note_previous_definition);
   return;
@@ -1788,46 +1901,19 @@
 
 /// DeclhasAttr - returns true if decl Declaration already has the target
 /// attribute.
-static bool
-DeclHasAttr(const Decl *D, const Attr *A) {
-  // There can be multiple AvailabilityAttr in a Decl. Make sure we copy
-  // all of them. It is mergeAvailabilityAttr in SemaDeclAttr.cpp that is
-  // responsible for making sure they are consistent.
-  const AvailabilityAttr *AA = dyn_cast<AvailabilityAttr>(A);
-  if (AA)
-    return false;
-
-  // The following thread safety attributes can also be duplicated.
-  switch (A->getKind()) {
-    case attr::ExclusiveLocksRequired:
-    case attr::SharedLocksRequired:
-    case attr::LocksExcluded:
-    case attr::ExclusiveLockFunction:
-    case attr::SharedLockFunction:
-    case attr::UnlockFunction:
-    case attr::ExclusiveTrylockFunction:
-    case attr::SharedTrylockFunction:
-    case attr::GuardedBy:
-    case attr::PtGuardedBy:
-    case attr::AcquiredBefore:
-    case attr::AcquiredAfter:
-      return false;
-    default:
-      ;
-  }
-
+static bool DeclHasAttr(const Decl *D, const Attr *A) {
   const OwnershipAttr *OA = dyn_cast<OwnershipAttr>(A);
   const AnnotateAttr *Ann = dyn_cast<AnnotateAttr>(A);
-  for (Decl::attr_iterator i = D->attr_begin(), e = D->attr_end(); i != e; ++i)
-    if ((*i)->getKind() == A->getKind()) {
+  for (const auto *i : D->attrs())
+    if (i->getKind() == A->getKind()) {
       if (Ann) {
-        if (Ann->getAnnotation() == cast<AnnotateAttr>(*i)->getAnnotation())
+        if (Ann->getAnnotation() == cast<AnnotateAttr>(i)->getAnnotation())
           return true;
         continue;
       }
       // FIXME: Don't hardcode this check
-      if (OA && isa<OwnershipAttr>(*i))
-        return OA->getOwnKind() == cast<OwnershipAttr>(*i)->getOwnKind();
+      if (OA && isa<OwnershipAttr>(i))
+        return OA->getOwnKind() == cast<OwnershipAttr>(i)->getOwnKind();
       return true;
     }
 
@@ -1849,12 +1935,10 @@
 static bool mergeAlignedAttrs(Sema &S, NamedDecl *New, Decl *Old) {
   // Look for alignas attributes on Old, and pick out whichever attribute
   // specifies the strictest alignment requirement.
-  AlignedAttr *OldAlignasAttr = 0;
-  AlignedAttr *OldStrictestAlignAttr = 0;
+  AlignedAttr *OldAlignasAttr = nullptr;
+  AlignedAttr *OldStrictestAlignAttr = nullptr;
   unsigned OldAlign = 0;
-  for (specific_attr_iterator<AlignedAttr>
-         I = Old->specific_attr_begin<AlignedAttr>(),
-         E = Old->specific_attr_end<AlignedAttr>(); I != E; ++I) {
+  for (auto *I : Old->specific_attrs<AlignedAttr>()) {
     // FIXME: We have no way of representing inherited dependent alignments
     // in a case like:
     //   template<int A, int B> struct alignas(A) X;
@@ -1865,26 +1949,24 @@
       return false;
 
     if (I->isAlignas())
-      OldAlignasAttr = *I;
+      OldAlignasAttr = I;
 
     unsigned Align = I->getAlignment(S.Context);
     if (Align > OldAlign) {
       OldAlign = Align;
-      OldStrictestAlignAttr = *I;
+      OldStrictestAlignAttr = I;
     }
   }
 
   // Look for alignas attributes on New.
-  AlignedAttr *NewAlignasAttr = 0;
+  AlignedAttr *NewAlignasAttr = nullptr;
   unsigned NewAlign = 0;
-  for (specific_attr_iterator<AlignedAttr>
-         I = New->specific_attr_begin<AlignedAttr>(),
-         E = New->specific_attr_end<AlignedAttr>(); I != E; ++I) {
+  for (auto *I : New->specific_attrs<AlignedAttr>()) {
     if (I->isAlignmentDependent())
       return false;
 
     if (I->isAlignas())
-      NewAlignasAttr = *I;
+      NewAlignasAttr = I;
 
     unsigned Align = I->getAlignment(S.Context);
     if (Align > NewAlign)
@@ -1930,9 +2012,9 @@
     //   specifier, any other declaration of that object shall also
     //   have no alignment specifier.
     S.Diag(New->getLocation(), diag::err_alignas_missing_on_definition)
-      << OldAlignasAttr->isC11();
+      << OldAlignasAttr;
     S.Diag(OldAlignasAttr->getLocation(), diag::note_alignas_on_declaration)
-      << OldAlignasAttr->isC11();
+      << OldAlignasAttr;
   }
 
   bool AnyAdded = false;
@@ -1957,40 +2039,46 @@
   return AnyAdded;
 }
 
-static bool mergeDeclAttribute(Sema &S, NamedDecl *D, InheritableAttr *Attr,
-                               bool Override) {
-  InheritableAttr *NewAttr = NULL;
+static bool mergeDeclAttribute(Sema &S, NamedDecl *D,
+                               const InheritableAttr *Attr, bool Override) {
+  InheritableAttr *NewAttr = nullptr;
   unsigned AttrSpellingListIndex = Attr->getSpellingListIndex();
-  if (AvailabilityAttr *AA = dyn_cast<AvailabilityAttr>(Attr))
+  if (const auto *AA = dyn_cast<AvailabilityAttr>(Attr))
     NewAttr = S.mergeAvailabilityAttr(D, AA->getRange(), AA->getPlatform(),
                                       AA->getIntroduced(), AA->getDeprecated(),
                                       AA->getObsoleted(), AA->getUnavailable(),
                                       AA->getMessage(), Override,
                                       AttrSpellingListIndex);
-  else if (VisibilityAttr *VA = dyn_cast<VisibilityAttr>(Attr))
+  else if (const auto *VA = dyn_cast<VisibilityAttr>(Attr))
     NewAttr = S.mergeVisibilityAttr(D, VA->getRange(), VA->getVisibility(),
                                     AttrSpellingListIndex);
-  else if (TypeVisibilityAttr *VA = dyn_cast<TypeVisibilityAttr>(Attr))
+  else if (const auto *VA = dyn_cast<TypeVisibilityAttr>(Attr))
     NewAttr = S.mergeTypeVisibilityAttr(D, VA->getRange(), VA->getVisibility(),
                                         AttrSpellingListIndex);
-  else if (DLLImportAttr *ImportA = dyn_cast<DLLImportAttr>(Attr))
+  else if (const auto *ImportA = dyn_cast<DLLImportAttr>(Attr))
     NewAttr = S.mergeDLLImportAttr(D, ImportA->getRange(),
                                    AttrSpellingListIndex);
-  else if (DLLExportAttr *ExportA = dyn_cast<DLLExportAttr>(Attr))
+  else if (const auto *ExportA = dyn_cast<DLLExportAttr>(Attr))
     NewAttr = S.mergeDLLExportAttr(D, ExportA->getRange(),
                                    AttrSpellingListIndex);
-  else if (FormatAttr *FA = dyn_cast<FormatAttr>(Attr))
+  else if (const auto *FA = dyn_cast<FormatAttr>(Attr))
     NewAttr = S.mergeFormatAttr(D, FA->getRange(), FA->getType(),
                                 FA->getFormatIdx(), FA->getFirstArg(),
                                 AttrSpellingListIndex);
-  else if (SectionAttr *SA = dyn_cast<SectionAttr>(Attr))
+  else if (const auto *SA = dyn_cast<SectionAttr>(Attr))
     NewAttr = S.mergeSectionAttr(D, SA->getRange(), SA->getName(),
                                  AttrSpellingListIndex);
+  else if (const auto *IA = dyn_cast<MSInheritanceAttr>(Attr))
+    NewAttr = S.mergeMSInheritanceAttr(D, IA->getRange(), IA->getBestCase(),
+                                       AttrSpellingListIndex,
+                                       IA->getSemanticSpelling());
   else if (isa<AlignedAttr>(Attr))
     // AlignedAttrs are handled separately, because we need to handle all
     // such attributes on a declaration at the same time.
-    NewAttr = 0;
-  else if (!DeclHasAttr(D, Attr))
+    NewAttr = nullptr;
+  else if (isa<DeprecatedAttr>(Attr) && Override)
+    NewAttr = nullptr;
+  else if (Attr->duplicatesAllowed() || !DeclHasAttr(D, Attr))
     NewAttr = cast<InheritableAttr>(Attr->clone(S.Context));
 
   if (NewAttr) {
@@ -2016,16 +2104,13 @@
     if (FD->isDefined(Def))
       return Def;
   }
-  return NULL;
+  return nullptr;
 }
 
 static bool hasAttribute(const Decl *D, attr::Kind Kind) {
-  for (Decl::attr_iterator I = D->attr_begin(), E = D->attr_end();
-       I != E; ++I) {
-    Attr *Attribute = *I;
+  for (const auto *Attribute : D->attrs())
     if (Attribute->getKind() == Kind)
       return true;
-  }
   return false;
 }
 
@@ -2088,9 +2173,9 @@
         //   specifier, any other declaration of that object shall also
         //   have no alignment specifier.
         S.Diag(Def->getLocation(), diag::err_alignas_missing_on_definition)
-          << AA->isC11();
+          << AA;
         S.Diag(NewAttribute->getLocation(), diag::note_alignas_on_declaration)
-          << AA->isC11();
+          << AA;
         NewAttributes.erase(NewAttributes.begin() + I);
         --E;
         continue;
@@ -2129,15 +2214,12 @@
   // we process them.
   if (!foundAny) New->setAttrs(AttrVec());
 
-  for (specific_attr_iterator<InheritableAttr>
-         i = Old->specific_attr_begin<InheritableAttr>(),
-         e = Old->specific_attr_end<InheritableAttr>(); 
-       i != e; ++i) {
+  for (auto *I : Old->specific_attrs<InheritableAttr>()) {
     bool Override = false;
     // Ignore deprecated/unavailable/availability attributes if requested.
-    if (isa<DeprecatedAttr>(*i) ||
-        isa<UnavailableAttr>(*i) ||
-        isa<AvailabilityAttr>(*i)) {
+    if (isa<DeprecatedAttr>(I) ||
+        isa<UnavailableAttr>(I) ||
+        isa<AvailabilityAttr>(I)) {
       switch (AMK) {
       case AMK_None:
         continue;
@@ -2152,10 +2234,10 @@
     }
 
     // Already handled.
-    if (isa<UsedAttr>(*i))
+    if (isa<UsedAttr>(I))
       continue;
 
-    if (mergeDeclAttribute(*this, New, *i, Override))
+    if (mergeDeclAttribute(*this, New, I, Override))
       foundAny = true;
   }
 
@@ -2174,9 +2256,9 @@
   //   The first declaration of a function shall specify the
   //   carries_dependency attribute for its declarator-id if any declaration
   //   of the function specifies the carries_dependency attribute.
-  if (newDecl->hasAttr<CarriesDependencyAttr>() &&
-      !oldDecl->hasAttr<CarriesDependencyAttr>()) {
-    S.Diag(newDecl->getAttr<CarriesDependencyAttr>()->getLocation(),
+  const CarriesDependencyAttr *CDA = newDecl->getAttr<CarriesDependencyAttr>();
+  if (CDA && !oldDecl->hasAttr<CarriesDependencyAttr>()) {
+    S.Diag(CDA->getLocation(),
            diag::err_carries_dependency_missing_on_first_decl) << 1/*Param*/;
     // Find the first declaration of the parameter.
     // FIXME: Should we build redeclaration chains for function parameters?
@@ -2197,12 +2279,10 @@
   // done before we process them.
   if (!foundAny) newDecl->setAttrs(AttrVec());
 
-  for (specific_attr_iterator<InheritableParamAttr>
-       i = oldDecl->specific_attr_begin<InheritableParamAttr>(),
-       e = oldDecl->specific_attr_end<InheritableParamAttr>(); i != e; ++i) {
-    if (!DeclHasAttr(newDecl, *i)) {
+  for (const auto *I : oldDecl->specific_attrs<InheritableParamAttr>()) {
+    if (!DeclHasAttr(newDecl, I)) {
       InheritableAttr *newAttr =
-        cast<InheritableParamAttr>((*i)->clone(S.Context));
+        cast<InheritableParamAttr>(I->clone(S.Context));
       newAttr->setInherited(true);
       newDecl->addAttr(newAttr);
       foundAny = true;
@@ -2246,6 +2326,24 @@
   return Sema::CXXInvalid;
 }
 
+// Determine whether the previous declaration was a definition, implicit
+// declaration, or a declaration.
+template <typename T>
+static std::pair<diag::kind, SourceLocation>
+getNoteDiagForInvalidRedeclaration(const T *Old, const T *New) {
+  diag::kind PrevDiag;
+  SourceLocation OldLocation = Old->getLocation();
+  if (Old->isThisDeclarationADefinition())
+    PrevDiag = diag::note_previous_definition;
+  else if (Old->isImplicit()) {
+    PrevDiag = diag::note_previous_implicit_declaration;
+    if (OldLocation.isInvalid())
+      OldLocation = New->getLocation();
+  } else
+    PrevDiag = diag::note_previous_declaration;
+  return std::make_pair(PrevDiag, OldLocation);
+}
+
 /// canRedefineFunction - checks if a function can be redefined. Currently,
 /// only extern inline functions can be redefined, and even then only in
 /// GNU89 mode.
@@ -2289,15 +2387,10 @@
 /// merged with.
 ///
 /// Returns true if there was an error, false otherwise.
-bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S,
-                             bool MergeTypeWithOld) {
+bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD,
+                             Scope *S, bool MergeTypeWithOld) {
   // Verify the old decl was also a function.
-  FunctionDecl *Old = 0;
-  if (FunctionTemplateDecl *OldFunctionTemplate
-        = dyn_cast<FunctionTemplateDecl>(OldD))
-    Old = OldFunctionTemplate->getTemplatedDecl();
-  else
-    Old = dyn_cast<FunctionDecl>(OldD);
+  FunctionDecl *Old = OldD->getAsFunction();
   if (!Old) {
     if (UsingShadowDecl *Shadow = dyn_cast<UsingShadowDecl>(OldD)) {
       if (New->getFriendObjectKind()) {
@@ -2309,33 +2402,44 @@
         return true;
       }
 
-      Diag(New->getLocation(), diag::err_using_decl_conflict_reverse);
-      Diag(Shadow->getTargetDecl()->getLocation(),
-           diag::note_using_decl_target);
-      Diag(Shadow->getUsingDecl()->getLocation(),
-           diag::note_using_decl) << 0;
+      // C++11 [namespace.udecl]p14:
+      //   If a function declaration in namespace scope or block scope has the
+      //   same name and the same parameter-type-list as a function introduced
+      //   by a using-declaration, and the declarations do not declare the same
+      //   function, the program is ill-formed.
+
+      // Check whether the two declarations might declare the same function.
+      Old = dyn_cast<FunctionDecl>(Shadow->getTargetDecl());
+      if (Old &&
+          !Old->getDeclContext()->getRedeclContext()->Equals(
+              New->getDeclContext()->getRedeclContext()) &&
+          !(Old->isExternC() && New->isExternC()))
+        Old = nullptr;
+
+      if (!Old) {
+        Diag(New->getLocation(), diag::err_using_decl_conflict_reverse);
+        Diag(Shadow->getTargetDecl()->getLocation(),
+             diag::note_using_decl_target);
+        Diag(Shadow->getUsingDecl()->getLocation(), diag::note_using_decl) << 0;
+        return true;
+      }
+      OldD = Old;
+    } else {
+      Diag(New->getLocation(), diag::err_redefinition_different_kind)
+        << New->getDeclName();
+      Diag(OldD->getLocation(), diag::note_previous_definition);
       return true;
     }
-
-    Diag(New->getLocation(), diag::err_redefinition_different_kind)
-      << New->getDeclName();
-    Diag(OldD->getLocation(), diag::note_previous_definition);
-    return true;
   }
 
   // If the old declaration is invalid, just give up here.
   if (Old->isInvalidDecl())
     return true;
 
-  // Determine whether the previous declaration was a definition,
-  // implicit declaration, or a declaration.
   diag::kind PrevDiag;
-  if (Old->isThisDeclarationADefinition())
-    PrevDiag = diag::note_previous_definition;
-  else if (Old->isImplicit())
-    PrevDiag = diag::note_previous_implicit_declaration;
-  else
-    PrevDiag = diag::note_previous_declaration;
+  SourceLocation OldLocation;
+  std::tie(PrevDiag, OldLocation) =
+      getNoteDiagForInvalidRedeclaration(Old, New);
 
   // Don't complain about this if we're in GNU89 mode and the old function
   // is an extern inline function.
@@ -2347,11 +2451,11 @@
       !New->getTemplateSpecializationInfo() &&
       !canRedefineFunction(Old, getLangOpts())) {
     if (getLangOpts().MicrosoftExt) {
-      Diag(New->getLocation(), diag::warn_static_non_static) << New;
-      Diag(Old->getLocation(), PrevDiag);
+      Diag(New->getLocation(), diag::ext_static_non_static) << New;
+      Diag(OldLocation, PrevDiag);
     } else {
       Diag(New->getLocation(), diag::err_static_non_static) << New;
-      Diag(Old->getLocation(), PrevDiag);
+      Diag(OldLocation, PrevDiag);
       return true;
     }
   }
@@ -2417,7 +2521,7 @@
       Diag(New->getLocation(), diag::err_regparm_mismatch)
         << NewType->getRegParmType()
         << OldType->getRegParmType();
-      Diag(Old->getLocation(), diag::note_previous_declaration);      
+      Diag(OldLocation, diag::note_previous_declaration);
       return true;
     }
 
@@ -2429,7 +2533,7 @@
   if (OldTypeInfo.getProducesResult() != NewTypeInfo.getProducesResult()) {
     if (NewTypeInfo.getProducesResult()) {
       Diag(New->getLocation(), diag::err_returns_retained_mismatch);
-      Diag(Old->getLocation(), diag::note_previous_declaration);      
+      Diag(OldLocation, diag::note_previous_declaration);
       return true;
     }
     
@@ -2473,12 +2577,14 @@
     //   Redeclarations or specializations of a function or function template
     //   with a declared return type that uses a placeholder type shall also
     //   use that placeholder, not a deduced type.
-    QualType OldDeclaredReturnType = (Old->getTypeSourceInfo()
-      ? Old->getTypeSourceInfo()->getType()->castAs<FunctionType>()
-      : OldType)->getResultType();
-    QualType NewDeclaredReturnType = (New->getTypeSourceInfo()
-      ? New->getTypeSourceInfo()->getType()->castAs<FunctionType>()
-      : NewType)->getResultType();
+    QualType OldDeclaredReturnType =
+        (Old->getTypeSourceInfo()
+             ? Old->getTypeSourceInfo()->getType()->castAs<FunctionType>()
+             : OldType)->getReturnType();
+    QualType NewDeclaredReturnType =
+        (New->getTypeSourceInfo()
+             ? New->getTypeSourceInfo()->getType()->castAs<FunctionType>()
+             : NewType)->getReturnType();
     QualType ResQT;
     if (!Context.hasSameType(OldDeclaredReturnType, NewDeclaredReturnType) &&
         !((NewQType->isDependentType() || OldQType->isDependentType()) &&
@@ -2488,23 +2594,25 @@
         ResQT = Context.mergeObjCGCQualifiers(NewQType, OldQType);
       if (ResQT.isNull()) {
         if (New->isCXXClassMember() && New->isOutOfLine())
-          Diag(New->getLocation(),
-               diag::err_member_def_does_not_match_ret_type) << New;
+          Diag(New->getLocation(), diag::err_member_def_does_not_match_ret_type)
+              << New << New->getReturnTypeSourceRange();
         else
-          Diag(New->getLocation(), diag::err_ovl_diff_return_type);
-        Diag(Old->getLocation(), PrevDiag) << Old << Old->getType();
+          Diag(New->getLocation(), diag::err_ovl_diff_return_type)
+              << New->getReturnTypeSourceRange();
+        Diag(OldLocation, PrevDiag) << Old << Old->getType()
+                                    << Old->getReturnTypeSourceRange();
         return true;
       }
       else
         NewQType = ResQT;
     }
 
-    QualType OldReturnType = OldType->getResultType();
-    QualType NewReturnType = cast<FunctionType>(NewQType)->getResultType();
+    QualType OldReturnType = OldType->getReturnType();
+    QualType NewReturnType = cast<FunctionType>(NewQType)->getReturnType();
     if (OldReturnType != NewReturnType) {
       // If this function has a deduced return type and has already been
       // defined, copy the deduced value from the old declaration.
-      AutoType *OldAT = Old->getResultType()->getContainedAutoType();
+      AutoType *OldAT = Old->getReturnType()->getContainedAutoType();
       if (OldAT && OldAT->isDeduced()) {
         New->setType(
             SubstAutoType(New->getType(),
@@ -2524,8 +2632,8 @@
       NewMethod->setTrivial(OldMethod->isTrivial());
 
       // MSVC allows explicit template specialization at class scope:
-      // 2 CXMethodDecls referring to the same function will be injected.
-      // We don't want a redeclartion error.
+      // 2 CXXMethodDecls referring to the same function will be injected.
+      // We don't want a redeclaration error.
       bool IsClassScopeExplicitSpecialization =
                               OldMethod->isFunctionTemplateSpecialization() &&
                               NewMethod->isFunctionTemplateSpecialization();
@@ -2538,7 +2646,7 @@
         //       is a static member function declaration.
         if (OldMethod->isStatic() != NewMethod->isStatic()) {
           Diag(New->getLocation(), diag::err_ovl_static_nonstatic_member);
-          Diag(Old->getLocation(), PrevDiag) << Old << Old->getType();
+          Diag(OldLocation, PrevDiag) << Old << Old->getType();
           return true;
         }
 
@@ -2562,7 +2670,7 @@
           Diag(New->getLocation(), diag::err_member_redeclared_in_instantiation)
             << New << New->getType();
         }
-        Diag(Old->getLocation(), PrevDiag) << Old << Old->getType();
+        Diag(OldLocation, PrevDiag) << Old << Old->getType();
 
       // Complain if this is an explicit declaration of a special
       // member that was initially declared implicitly.
@@ -2590,10 +2698,9 @@
     //   The first declaration of a function shall specify the noreturn
     //   attribute if any declaration of that function specifies the noreturn
     //   attribute.
-    if (New->hasAttr<CXX11NoReturnAttr>() &&
-        !Old->hasAttr<CXX11NoReturnAttr>()) {
-      Diag(New->getAttr<CXX11NoReturnAttr>()->getLocation(),
-           diag::err_noreturn_missing_on_first_decl);
+    const CXX11NoReturnAttr *NRA = New->getAttr<CXX11NoReturnAttr>();
+    if (NRA && !Old->hasAttr<CXX11NoReturnAttr>()) {
+      Diag(NRA->getLocation(), diag::err_noreturn_missing_on_first_decl);
       Diag(Old->getFirstDecl()->getLocation(),
            diag::note_noreturn_missing_first_decl);
     }
@@ -2602,9 +2709,9 @@
     //   The first declaration of a function shall specify the
     //   carries_dependency attribute for its declarator-id if any declaration
     //   of the function specifies the carries_dependency attribute.
-    if (New->hasAttr<CarriesDependencyAttr>() &&
-        !Old->hasAttr<CarriesDependencyAttr>()) {
-      Diag(New->getAttr<CarriesDependencyAttr>()->getLocation(),
+    const CarriesDependencyAttr *CDA = New->getAttr<CarriesDependencyAttr>();
+    if (CDA && !Old->hasAttr<CarriesDependencyAttr>()) {
+      Diag(CDA->getLocation(),
            diag::err_carries_dependency_missing_on_first_decl) << 0/*Function*/;
       Diag(Old->getFirstDecl()->getLocation(),
            diag::note_carries_dependency_missing_first_decl) << 0/*Function*/;
@@ -2636,10 +2743,10 @@
       // Check cautiously as the friend object kind isn't yet complete.
       if (New->getFriendObjectKind() != Decl::FOK_None) {
         Diag(New->getLocation(), diag::ext_retained_language_linkage) << New;
-        Diag(Old->getLocation(), PrevDiag);
+        Diag(OldLocation, PrevDiag);
       } else {
         Diag(New->getLocation(), diag::err_different_language_linkage) << New;
-        Diag(Old->getLocation(), PrevDiag);
+        Diag(OldLocation, PrevDiag);
         return true;
       }
     }
@@ -2664,32 +2771,26 @@
       Context.typesAreCompatible(OldQType, NewQType)) {
     const FunctionType *OldFuncType = OldQType->getAs<FunctionType>();
     const FunctionType *NewFuncType = NewQType->getAs<FunctionType>();
-    const FunctionProtoType *OldProto = 0;
+    const FunctionProtoType *OldProto = nullptr;
     if (MergeTypeWithOld && isa<FunctionNoProtoType>(NewFuncType) &&
         (OldProto = dyn_cast<FunctionProtoType>(OldFuncType))) {
       // The old declaration provided a function prototype, but the
       // new declaration does not. Merge in the prototype.
       assert(!OldProto->hasExceptionSpec() && "Exception spec in C");
-      SmallVector<QualType, 16> ParamTypes(OldProto->arg_type_begin(),
-                                                 OldProto->arg_type_end());
-      NewQType = Context.getFunctionType(NewFuncType->getResultType(),
-                                         ParamTypes,
-                                         OldProto->getExtProtoInfo());
+      SmallVector<QualType, 16> ParamTypes(OldProto->param_types());
+      NewQType =
+          Context.getFunctionType(NewFuncType->getReturnType(), ParamTypes,
+                                  OldProto->getExtProtoInfo());
       New->setType(NewQType);
       New->setHasInheritedPrototype();
 
-      // Synthesize a parameter for each argument type.
+      // Synthesize parameters with the same types.
       SmallVector<ParmVarDecl*, 16> Params;
-      for (FunctionProtoType::arg_type_iterator
-             ParamType = OldProto->arg_type_begin(),
-             ParamEnd = OldProto->arg_type_end();
-           ParamType != ParamEnd; ++ParamType) {
-        ParmVarDecl *Param = ParmVarDecl::Create(Context, New,
-                                                 SourceLocation(),
-                                                 SourceLocation(), 0,
-                                                 *ParamType, /*TInfo=*/0,
-                                                 SC_None,
-                                                 0);
+      for (const auto &ParamType : OldProto->param_types()) {
+        ParmVarDecl *Param = ParmVarDecl::Create(Context, New, SourceLocation(),
+                                                 SourceLocation(), nullptr,
+                                                 ParamType, /*TInfo=*/nullptr,
+                                                 SC_None, nullptr);
         Param->setScopeInfo(0, Params.size());
         Param->setImplicit();
         Params.push_back(Param);
@@ -2724,21 +2825,21 @@
       = New->getType()->getAs<FunctionProtoType>();
 
     // Determine whether this is the GNU C extension.
-    QualType MergedReturn = Context.mergeTypes(OldProto->getResultType(),
-                                               NewProto->getResultType());
+    QualType MergedReturn = Context.mergeTypes(OldProto->getReturnType(),
+                                               NewProto->getReturnType());
     bool LooseCompatible = !MergedReturn.isNull();
     for (unsigned Idx = 0, End = Old->getNumParams();
          LooseCompatible && Idx != End; ++Idx) {
       ParmVarDecl *OldParm = Old->getParamDecl(Idx);
       ParmVarDecl *NewParm = New->getParamDecl(Idx);
       if (Context.typesAreCompatible(OldParm->getType(),
-                                     NewProto->getArgType(Idx))) {
+                                     NewProto->getParamType(Idx))) {
         ArgTypes.push_back(NewParm->getType());
       } else if (Context.typesAreCompatible(OldParm->getType(),
                                             NewParm->getType(),
                                             /*CompareUnqualified=*/true)) {
-        GNUCompatibleParamWarning Warn
-          = { OldParm, NewParm, NewProto->getArgType(Idx) };
+        GNUCompatibleParamWarning Warn = { OldParm, NewParm,
+                                           NewProto->getParamType(Idx) };
         Warnings.push_back(Warn);
         ArgTypes.push_back(NewParm->getType());
       } else
@@ -2776,7 +2877,7 @@
     // or 'printf', just warn about the incompatible redeclaration.
     if (Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) {
       Diag(New->getLocation(), diag::warn_redecl_library_builtin) << New;
-      Diag(Old->getLocation(), diag::note_previous_builtin_declaration)
+      Diag(OldLocation, diag::note_previous_builtin_declaration)
         << Old << Old->getType();
 
       // If this is a global redeclaration, just forget hereafter
@@ -2797,7 +2898,7 @@
   }
 
   Diag(New->getLocation(), diag::err_conflicting_types) << New->getDeclName();
-  Diag(Old->getLocation(), PrevDiag) << Old << Old->getType();
+  Diag(OldLocation, PrevDiag) << Old << Old->getType();
   return true;
 }
 
@@ -2994,14 +3095,17 @@
   if (New->isInvalidDecl())
     return;
 
+  VarTemplateDecl *NewTemplate = New->getDescribedVarTemplate();
+
   // Verify the old decl was also a variable or variable template.
-  VarDecl *Old = 0;
-  if (Previous.isSingleResult() &&
-      (Old = dyn_cast<VarDecl>(Previous.getFoundDecl()))) {
-    if (New->getDescribedVarTemplate())
-      Old = Old->getDescribedVarTemplate() ? Old : 0;
-    else
-      Old = Old->getDescribedVarTemplate() ? 0 : Old;
+  VarDecl *Old = nullptr;
+  VarTemplateDecl *OldTemplate = nullptr;
+  if (Previous.isSingleResult()) {
+    if (NewTemplate) {
+      OldTemplate = dyn_cast<VarTemplateDecl>(Previous.getFoundDecl());
+      Old = OldTemplate ? OldTemplate->getTemplatedDecl() : nullptr;
+    } else
+      Old = dyn_cast<VarDecl>(Previous.getFoundDecl());
   }
   if (!Old) {
     Diag(New->getLocation(), diag::err_redefinition_different_kind)
@@ -3014,6 +3118,13 @@
   if (!shouldLinkPossiblyHiddenDecl(Old, New))
     return;
 
+  // Ensure the template parameters are compatible.
+  if (NewTemplate &&
+      !TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(),
+                                      OldTemplate->getTemplateParameters(),
+                                      /*Complain=*/true, TPL_TemplateMatch))
+    return;
+
   // C++ [class.mem]p1:
   //   A member shall not be declared twice in the member-specification [...]
   // 
@@ -3028,9 +3139,9 @@
   mergeDeclAttributes(New, Old);
   // Warn if an already-declared variable is made a weak_import in a subsequent 
   // declaration
-  if (New->getAttr<WeakImportAttr>() &&
+  if (New->hasAttr<WeakImportAttr>() &&
       Old->getStorageClass() == SC_None &&
-      !Old->getAttr<WeakImportAttr>()) {
+      !Old->hasAttr<WeakImportAttr>()) {
     Diag(New->getLocation(), diag::warn_weak_import) << New->getDeclName();
     Diag(Old->getLocation(), diag::note_previous_definition);
     // Remove weak_import attribute on new declaration.
@@ -3043,13 +3154,25 @@
   if (New->isInvalidDecl())
     return;
 
+  diag::kind PrevDiag;
+  SourceLocation OldLocation;
+  std::tie(PrevDiag, OldLocation) =
+      getNoteDiagForInvalidRedeclaration(Old, New);
+
   // [dcl.stc]p8: Check if we have a non-static decl followed by a static.
   if (New->getStorageClass() == SC_Static &&
       !New->isStaticDataMember() &&
       Old->hasExternalFormalLinkage()) {
-    Diag(New->getLocation(), diag::err_static_non_static) << New->getDeclName();
-    Diag(Old->getLocation(), diag::note_previous_definition);
-    return New->setInvalidDecl();
+    if (getLangOpts().MicrosoftExt) {
+      Diag(New->getLocation(), diag::ext_static_non_static)
+          << New->getDeclName();
+      Diag(OldLocation, PrevDiag);
+    } else {
+      Diag(New->getLocation(), diag::err_static_non_static)
+          << New->getDeclName();
+      Diag(OldLocation, PrevDiag);
+      return New->setInvalidDecl();
+    }
   }
   // C99 6.2.2p4:
   //   For an identifier declared with the storage-class specifier
@@ -3066,7 +3189,7 @@
            !New->isStaticDataMember() &&
            Old->getCanonicalDecl()->getStorageClass() == SC_Static) {
     Diag(New->getLocation(), diag::err_non_static_static) << New->getDeclName();
-    Diag(Old->getLocation(), diag::note_previous_definition);
+    Diag(OldLocation, PrevDiag);
     return New->setInvalidDecl();
   }
 
@@ -3074,13 +3197,13 @@
   if (New->hasExternalStorage() &&
       !Old->hasLinkage() && Old->isLocalVarDecl()) {
     Diag(New->getLocation(), diag::err_extern_non_extern) << New->getDeclName();
-    Diag(Old->getLocation(), diag::note_previous_definition);
+    Diag(OldLocation, PrevDiag);
     return New->setInvalidDecl();
   }
   if (Old->hasLinkage() && New->isLocalVarDecl() &&
       !New->hasExternalStorage()) {
     Diag(New->getLocation(), diag::err_non_extern_extern) << New->getDeclName();
-    Diag(Old->getLocation(), diag::note_previous_definition);
+    Diag(OldLocation, PrevDiag);
     return New->setInvalidDecl();
   }
 
@@ -3093,17 +3216,17 @@
       !(Old->getLexicalDeclContext()->isRecord() &&
         !New->getLexicalDeclContext()->isRecord())) {
     Diag(New->getLocation(), diag::err_redefinition) << New->getDeclName();
-    Diag(Old->getLocation(), diag::note_previous_definition);
+    Diag(OldLocation, PrevDiag);
     return New->setInvalidDecl();
   }
 
   if (New->getTLSKind() != Old->getTLSKind()) {
     if (!Old->getTLSKind()) {
       Diag(New->getLocation(), diag::err_thread_non_thread) << New->getDeclName();
-      Diag(Old->getLocation(), diag::note_previous_declaration);
+      Diag(OldLocation, PrevDiag);
     } else if (!New->getTLSKind()) {
       Diag(New->getLocation(), diag::err_non_thread_thread) << New->getDeclName();
-      Diag(Old->getLocation(), diag::note_previous_declaration);
+      Diag(OldLocation, PrevDiag);
     } else {
       // Do not allow redeclaration to change the variable between requiring
       // static and dynamic initialization.
@@ -3111,7 +3234,7 @@
       // declaration to determine the kind. Do we need to be compatible here?
       Diag(New->getLocation(), diag::err_thread_thread_different_kind)
         << New->getDeclName() << (New->getTLSKind() == VarDecl::TLS_Dynamic);
-      Diag(Old->getLocation(), diag::note_previous_declaration);
+      Diag(OldLocation, PrevDiag);
     }
   }
 
@@ -3128,7 +3251,7 @@
 
   if (haveIncompatibleLanguageLinkages(Old, New)) {
     Diag(New->getLocation(), diag::err_different_language_linkage) << New;
-    Diag(Old->getLocation(), diag::note_previous_definition);
+    Diag(OldLocation, PrevDiag);
     New->setInvalidDecl();
     return;
   }
@@ -3139,14 +3262,13 @@
 
   // Keep a chain of previous declarations.
   New->setPreviousDecl(Old);
+  if (NewTemplate)
+    NewTemplate->setPreviousDecl(OldTemplate);
 
   // Inherit access appropriately.
   New->setAccess(Old->getAccess());
-
-  if (VarTemplateDecl *VTD = New->getDescribedVarTemplate()) {
-    if (New->isStaticDataMember() && New->isOutOfLine())
-      VTD->setAccess(New->getAccess());
-  }
+  if (NewTemplate)
+    NewTemplate->setAccess(New->getAccess());
 }
 
 /// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
@@ -3156,7 +3278,7 @@
   return ParsedFreeStandingDeclSpec(S, AS, DS, MultiTemplateParamsArg());
 }
 
-static void HandleTagNumbering(Sema &S, const TagDecl *Tag) {
+static void HandleTagNumbering(Sema &S, const TagDecl *Tag, Scope *TagScope) {
   if (!S.Context.getLangOpts().CPlusPlus)
     return;
 
@@ -3167,7 +3289,8 @@
       return;
     MangleNumberingContext &MCtx =
         S.Context.getManglingNumberContext(Tag->getParent());
-    S.Context.setManglingNumber(Tag, MCtx.getManglingNumber(Tag));
+    S.Context.setManglingNumber(
+        Tag, MCtx.getManglingNumber(Tag, TagScope->getMSLocalManglingNumber()));
     return;
   }
 
@@ -3176,7 +3299,9 @@
   if (MangleNumberingContext *MCtx =
           S.getCurrentMangleNumberContext(Tag->getDeclContext(),
                                           ManglingContextDecl)) {
-    S.Context.setManglingNumber(Tag, MCtx->getManglingNumber(Tag));
+    S.Context.setManglingNumber(
+        Tag,
+        MCtx->getManglingNumber(Tag, TagScope->getMSLocalManglingNumber()));
   }
 }
 
@@ -3187,8 +3312,8 @@
                                        DeclSpec &DS,
                                        MultiTemplateParamsArg TemplateParams,
                                        bool IsExplicitInstantiation) {
-  Decl *TagD = 0;
-  TagDecl *Tag = 0;
+  Decl *TagD = nullptr;
+  TagDecl *Tag = nullptr;
   if (DS.getTypeSpecType() == DeclSpec::TST_class ||
       DS.getTypeSpecType() == DeclSpec::TST_struct ||
       DS.getTypeSpecType() == DeclSpec::TST_interface ||
@@ -3197,7 +3322,7 @@
     TagD = DS.getRepAsDecl();
 
     if (!TagD) // We probably had an error
-      return 0;
+      return nullptr;
 
     // Note that the above type specs guarantee that the
     // type rep is a Decl, whereas in many of the others
@@ -3209,7 +3334,7 @@
   }
 
   if (Tag) {
-    HandleTagNumbering(*this, Tag);
+    HandleTagNumbering(*this, Tag, S);
     Tag->setFreeStanding();
     if (Tag->isInvalidDecl())
       return Tag;
@@ -3245,7 +3370,7 @@
     // If we're dealing with a decl but not a TagDecl, assume that
     // whatever routines created it handled the friendship aspect.
     if (TagD && !Tag)
-      return 0;
+      return nullptr;
     return ActOnFriendTypeDecl(S, DS, TemplateParams);
   }
 
@@ -3264,7 +3389,7 @@
           DS.getTypeSpecType() == DeclSpec::TST_interface ? 2 :
           DS.getTypeSpecType() == DeclSpec::TST_union ? 3 : 4)
       << SS.getRange();
-    return 0;
+    return nullptr;
   }
 
   // Track whether this decl-specifier declares anything.
@@ -3276,7 +3401,7 @@
         DS.getStorageClassSpec() != DeclSpec::SCS_typedef) {
       if (getLangOpts().CPlusPlus ||
           Record->getDeclContext()->isRecord())
-        return BuildAnonymousStructOrUnion(S, DS, AS, Record);
+        return BuildAnonymousStructOrUnion(S, DS, AS, Record, Context.getPrintingPolicy());
 
       DeclaresAnything = false;
     }
@@ -3359,10 +3484,15 @@
   // Note that a linkage-specification sets a storage class, but
   // 'extern "C" struct foo;' is actually valid and not theoretically
   // useless.
-  if (DeclSpec::SCS SCS = DS.getStorageClassSpec())
-    if (!DS.isExternInLinkageSpec() && SCS != DeclSpec::SCS_typedef)
+  if (DeclSpec::SCS SCS = DS.getStorageClassSpec()) {
+    if (SCS == DeclSpec::SCS_mutable)
+      // Since mutable is not a viable storage class specifier in C, there is
+      // no reason to treat it as an extension. Instead, diagnose as an error.
+      Diag(DS.getStorageClassSpecLoc(), diag::err_mutable_nonmember);
+    else if (!DS.isExternInLinkageSpec() && SCS != DeclSpec::SCS_typedef)
       Diag(DS.getStorageClassSpecLoc(), DiagID)
         << DeclSpec::getSpecifierName(SCS);
+  }
 
   if (DeclSpec::TSCS TSCS = DS.getThreadStorageClassSpec())
     Diag(DS.getThreadStorageClassSpecLoc(), DiagID)
@@ -3462,12 +3592,10 @@
   bool Invalid = false;
 
   // Look every FieldDecl and IndirectFieldDecl with a name.
-  for (RecordDecl::decl_iterator D = AnonRecord->decls_begin(),
-                               DEnd = AnonRecord->decls_end();
-       D != DEnd; ++D) {
-    if ((isa<FieldDecl>(*D) || isa<IndirectFieldDecl>(*D)) &&
-        cast<NamedDecl>(*D)->getDeclName()) {
-      ValueDecl *VD = cast<ValueDecl>(*D);
+  for (auto *D : AnonRecord->decls()) {
+    if ((isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D)) &&
+        cast<NamedDecl>(D)->getDeclName()) {
+      ValueDecl *VD = cast<ValueDecl>(D);
       if (CheckAnonMemberRedeclaration(SemaRef, S, Owner, VD->getDeclName(),
                                        VD->getLocation(), diagKind)) {
         // C++ [class.union]p2:
@@ -3483,9 +3611,8 @@
         //   anonymous union is declared.
         unsigned OldChainingSize = Chaining.size();
         if (IndirectFieldDecl *IF = dyn_cast<IndirectFieldDecl>(VD))
-          for (IndirectFieldDecl::chain_iterator PI = IF->chain_begin(),
-               PE = IF->chain_end(); PI != PE; ++PI)
-            Chaining.push_back(*PI);
+          for (auto *PI : IF->chain())
+            Chaining.push_back(PI);
         else
           Chaining.push_back(VD);
 
@@ -3540,13 +3667,45 @@
   llvm_unreachable("unknown storage class specifier");
 }
 
+static SourceLocation findDefaultInitializer(const CXXRecordDecl *Record) {
+  assert(Record->hasInClassInitializer());
+
+  for (const auto *I : Record->decls()) {
+    const auto *FD = dyn_cast<FieldDecl>(I);
+    if (const auto *IFD = dyn_cast<IndirectFieldDecl>(I))
+      FD = IFD->getAnonField();
+    if (FD && FD->hasInClassInitializer())
+      return FD->getLocation();
+  }
+
+  llvm_unreachable("couldn't find in-class initializer");
+}
+
+static void checkDuplicateDefaultInit(Sema &S, CXXRecordDecl *Parent,
+                                      SourceLocation DefaultInitLoc) {
+  if (!Parent->isUnion() || !Parent->hasInClassInitializer())
+    return;
+
+  S.Diag(DefaultInitLoc, diag::err_multiple_mem_union_initialization);
+  S.Diag(findDefaultInitializer(Parent), diag::note_previous_initializer) << 0;
+}
+
+static void checkDuplicateDefaultInit(Sema &S, CXXRecordDecl *Parent,
+                                      CXXRecordDecl *AnonUnion) {
+  if (!Parent->isUnion() || !Parent->hasInClassInitializer())
+    return;
+
+  checkDuplicateDefaultInit(S, Parent, findDefaultInitializer(AnonUnion));
+}
+
 /// BuildAnonymousStructOrUnion - Handle the declaration of an
 /// anonymous structure or union. Anonymous unions are a C++ feature
 /// (C++ [class.union]) and a C11 feature; anonymous structures
 /// are a C11 feature and GNU C++ extension.
 Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
-                                             AccessSpecifier AS,
-                                             RecordDecl *Record) {
+                                        AccessSpecifier AS,
+                                        RecordDecl *Record,
+                                        const PrintingPolicy &Policy) {
   DeclContext *Owner = Record->getDeclContext();
 
   // Diagnose whether this anonymous struct/union is an extension.
@@ -3561,7 +3720,7 @@
   // structs/unions.
   bool Invalid = false;
   if (getLangOpts().CPlusPlus) {
-    const char* PrevSpec = 0;
+    const char *PrevSpec = nullptr;
     unsigned DiagID;
     if (Record->isUnion()) {
       // C++ [class.union]p6:
@@ -3576,7 +3735,7 @@
   
         // Recover by adding 'static'.
         DS.SetStorageClassSpec(*this, DeclSpec::SCS_static, SourceLocation(),
-                               PrevSpec, DiagID);
+                               PrevSpec, DiagID, Policy);
       }
       // C++ [class.union]p6:
       //   A storage class is not allowed in a declaration of an
@@ -3590,7 +3749,7 @@
         // Recover by removing the storage specifier.
         DS.SetStorageClassSpec(*this, DeclSpec::SCS_unspecified, 
                                SourceLocation(),
-                               PrevSpec, DiagID);
+                               PrevSpec, DiagID, Context.getPrintingPolicy());
       }
     }
 
@@ -3623,10 +3782,8 @@
     //   The member-specification of an anonymous union shall only
     //   define non-static data members. [Note: nested types and
     //   functions cannot be declared within an anonymous union. ]
-    for (DeclContext::decl_iterator Mem = Record->decls_begin(),
-                                 MemEnd = Record->decls_end();
-         Mem != MemEnd; ++Mem) {
-      if (FieldDecl *FD = dyn_cast<FieldDecl>(*Mem)) {
+    for (auto *Mem : Record->decls()) {
+      if (auto *FD = dyn_cast<FieldDecl>(Mem)) {
         // C++ [class.union]p3:
         //   An anonymous union shall not have private or protected
         //   members (clause 11).
@@ -3644,14 +3801,14 @@
         //   array of such objects.
         if (CheckNontrivialField(FD))
           Invalid = true;
-      } else if ((*Mem)->isImplicit()) {
+      } else if (Mem->isImplicit()) {
         // Any implicit members are fine.
-      } else if (isa<TagDecl>(*Mem) && (*Mem)->getDeclContext() != Record) {
+      } else if (isa<TagDecl>(Mem) && Mem->getDeclContext() != Record) {
         // This is a type that showed up in an
         // elaborated-type-specifier inside the anonymous struct or
         // union, but which actually declares a type outside of the
         // anonymous struct or union. It's okay.
-      } else if (RecordDecl *MemRecord = dyn_cast<RecordDecl>(*Mem)) {
+      } else if (auto *MemRecord = dyn_cast<RecordDecl>(Mem)) {
         if (!MemRecord->isAnonymousStructOrUnion() &&
             MemRecord->getDeclName()) {
           // Visual C++ allows type definition in anonymous struct or union.
@@ -3672,31 +3829,41 @@
                diag::ext_anonymous_record_with_anonymous_type)
             << (int)Record->isUnion();
         }
-      } else if (isa<AccessSpecDecl>(*Mem)) {
+      } else if (isa<AccessSpecDecl>(Mem)) {
         // Any access specifier is fine.
+      } else if (isa<StaticAssertDecl>(Mem)) {
+        // In C++1z, static_assert declarations are also fine.
       } else {
         // We have something that isn't a non-static data
         // member. Complain about it.
         unsigned DK = diag::err_anonymous_record_bad_member;
-        if (isa<TypeDecl>(*Mem))
+        if (isa<TypeDecl>(Mem))
           DK = diag::err_anonymous_record_with_type;
-        else if (isa<FunctionDecl>(*Mem))
+        else if (isa<FunctionDecl>(Mem))
           DK = diag::err_anonymous_record_with_function;
-        else if (isa<VarDecl>(*Mem))
+        else if (isa<VarDecl>(Mem))
           DK = diag::err_anonymous_record_with_static;
         
         // Visual C++ allows type definition in anonymous struct or union.
         if (getLangOpts().MicrosoftExt &&
             DK == diag::err_anonymous_record_with_type)
-          Diag((*Mem)->getLocation(), diag::ext_anonymous_record_with_type)
+          Diag(Mem->getLocation(), diag::ext_anonymous_record_with_type)
             << (int)Record->isUnion();
         else {
-          Diag((*Mem)->getLocation(), DK)
+          Diag(Mem->getLocation(), DK)
               << (int)Record->isUnion();
           Invalid = true;
         }
       }
     }
+
+    // C++11 [class.union]p8 (DR1460):
+    //   At most one variant member of a union may have a
+    //   brace-or-equal-initializer.
+    if (cast<CXXRecordDecl>(Record)->hasInClassInitializer() &&
+        Owner->isRecord())
+      checkDuplicateDefaultInit(*this, cast<CXXRecordDecl>(Owner),
+                                cast<CXXRecordDecl>(Record));
   }
 
   if (!Record->isUnion() && !Owner->isRecord()) {
@@ -3711,15 +3878,15 @@
   assert(TInfo && "couldn't build declarator info for anonymous struct/union");
 
   // Create a declaration for this anonymous struct/union.
-  NamedDecl *Anon = 0;
+  NamedDecl *Anon = nullptr;
   if (RecordDecl *OwningClass = dyn_cast<RecordDecl>(Owner)) {
     Anon = FieldDecl::Create(Context, OwningClass,
                              DS.getLocStart(),
                              Record->getLocation(),
-                             /*IdentifierInfo=*/0,
+                             /*IdentifierInfo=*/nullptr,
                              Context.getTypeDeclType(Record),
                              TInfo,
-                             /*BitWidth=*/0, /*Mutable=*/false,
+                             /*BitWidth=*/nullptr, /*Mutable=*/false,
                              /*InitStyle=*/ICIS_NoInit);
     Anon->setAccess(AS);
     if (getLangOpts().CPlusPlus)
@@ -3737,7 +3904,7 @@
 
     Anon = VarDecl::Create(Context, Owner,
                            DS.getLocStart(),
-                           Record->getLocation(), /*IdentifierInfo=*/0,
+                           Record->getLocation(), /*IdentifierInfo=*/nullptr,
                            Context.getTypeDeclType(Record),
                            TInfo, SC);
 
@@ -3749,11 +3916,14 @@
   }
   Anon->setImplicit();
 
+  // Mark this as an anonymous struct/union type.
+  Record->setAnonymousStructOrUnion(true);
+
   // Add the anonymous struct/union object to the current
   // context. We'll be referencing this object when we refer to one of
   // its members.
   Owner->addDecl(Anon);
-  
+
   // Inject the members of the anonymous struct/union into the owning
   // context and into the identifier resolver chain for name lookup
   // purposes.
@@ -3764,13 +3934,17 @@
                                           Chain, false))
     Invalid = true;
 
-  // Mark this as an anonymous struct/union type. Note that we do not
-  // do this until after we have already checked and injected the
-  // members of this anonymous struct/union type, because otherwise
-  // the members could be injected twice: once by DeclContext when it
-  // builds its lookup table, and once by
-  // InjectAnonymousStructOrUnionMembers.
-  Record->setAnonymousStructOrUnion(true);
+  if (VarDecl *NewVD = dyn_cast<VarDecl>(Anon)) {
+    if (getLangOpts().CPlusPlus && NewVD->isStaticLocal()) {
+      Decl *ManglingContextDecl;
+      if (MangleNumberingContext *MCtx =
+              getCurrentMangleNumberContext(NewVD->getDeclContext(),
+                                            ManglingContextDecl)) {
+        Context.setManglingNumber(NewVD, MCtx->getManglingNumber(NewVD, S->getMSLocalManglingNumber()));
+        Context.setStaticLocalNumber(NewVD, MCtx->getStaticLocalNumber(NewVD));
+      }
+    }
+  }
 
   if (Invalid)
     Anon->setInvalidDecl();
@@ -3804,14 +3978,14 @@
   assert(TInfo && "couldn't build declarator info for anonymous struct");
 
   // Create a declaration for this anonymous struct.
-  NamedDecl* Anon = FieldDecl::Create(Context,
+  NamedDecl *Anon = FieldDecl::Create(Context,
                              cast<RecordDecl>(CurContext),
                              DS.getLocStart(),
                              DS.getLocStart(),
-                             /*IdentifierInfo=*/0,
+                             /*IdentifierInfo=*/nullptr,
                              Context.getTypeDeclType(Record),
                              TInfo,
-                             /*BitWidth=*/0, /*Mutable=*/false,
+                             /*BitWidth=*/nullptr, /*Mutable=*/false,
                              /*InitStyle=*/ICIS_NoInit);
   Anon->setImplicit();
 
@@ -3913,7 +4087,7 @@
                                     Context.getCanonicalType(CurClassType)));
     NameInfo.setLoc(Name.StartLocation);
     // FIXME: should we retrieve TypeSourceInfo?
-    NameInfo.setNamedTypeInfo(0);
+    NameInfo.setNamedTypeInfo(nullptr);
     return NameInfo;
   }
 
@@ -4009,7 +4183,7 @@
   case DeclSpec::TST_underlyingType:
   case DeclSpec::TST_atomic: {
     // Grab the type from the parser.
-    TypeSourceInfo *TSI = 0;
+    TypeSourceInfo *TSI = nullptr;
     QualType T = S.GetTypeFromParser(DS.getRepAsType(), &TSI);
     if (T.isNull() || !T->isDependentType()) break;
 
@@ -4108,33 +4282,31 @@
 /// \returns true if we cannot safely recover from this error, false otherwise.
 bool Sema::diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC,
                                         DeclarationName Name,
-                                      SourceLocation Loc) {
+                                        SourceLocation Loc) {
   DeclContext *Cur = CurContext;
   while (isa<LinkageSpecDecl>(Cur) || isa<CapturedDecl>(Cur))
     Cur = Cur->getParent();
-  
-  // C++ [dcl.meaning]p1:
-  //   A declarator-id shall not be qualified except for the definition
-  //   of a member function (9.3) or static data member (9.4) outside of
-  //   its class, the definition or explicit instantiation of a function 
-  //   or variable member of a namespace outside of its namespace, or the
-  //   definition of an explicit specialization outside of its namespace,
-  //   or the declaration of a friend function that is a member of 
-  //   another class or namespace (11.3). [...]
-    
-  // The user provided a superfluous scope specifier that refers back to the
-  // class or namespaces in which the entity is already declared.
+
+  // If the user provided a superfluous scope specifier that refers back to the
+  // class in which the entity is already declared, diagnose and ignore it.
   //
   // class X {
   //   void X::f();
   // };
+  //
+  // Note, it was once ill-formed to give redundant qualification in all
+  // contexts, but that rule was removed by DR482.
   if (Cur->Equals(DC)) {
-    Diag(Loc, LangOpts.MicrosoftExt? diag::warn_member_extra_qualification
-                                   : diag::err_member_extra_qualification)
-      << Name << FixItHint::CreateRemoval(SS.getRange());
-    SS.clear();
+    if (Cur->isRecord()) {
+      Diag(Loc, LangOpts.MicrosoftExt ? diag::warn_member_extra_qualification
+                                      : diag::err_member_extra_qualification)
+        << Name << FixItHint::CreateRemoval(SS.getRange());
+      SS.clear();
+    } else {
+      Diag(Loc, diag::warn_namespace_member_extra_qualification) << Name;
+    }
     return false;
-  } 
+  }
 
   // Check whether the qualifying scope encloses the scope of the original
   // declaration.
@@ -4203,9 +4375,9 @@
       Diag(D.getDeclSpec().getLocStart(),
            diag::err_declarator_need_ident)
         << D.getDeclSpec().getSourceRange() << D.getSourceRange();
-    return 0;
+    return nullptr;
   } else if (DiagnoseUnexpandedParameterPack(NameInfo, UPPC_DeclarationType))
-    return 0;
+    return nullptr;
 
   // The scope passed in may not be a decl scope.  Zip up the scope tree until
   // we find one that is.
@@ -4219,26 +4391,26 @@
   else if (D.getCXXScopeSpec().isSet()) {
     if (DiagnoseUnexpandedParameterPack(D.getCXXScopeSpec(), 
                                         UPPC_DeclarationQualifier))
-      return 0;
+      return nullptr;
 
     bool EnteringContext = !D.getDeclSpec().isFriendSpecified();
     DC = computeDeclContext(D.getCXXScopeSpec(), EnteringContext);
-    if (!DC) {
+    if (!DC || isa<EnumDecl>(DC)) {
       // If we could not compute the declaration context, it's because the
       // declaration context is dependent but does not refer to a class,
       // class template, or class template partial specialization. Complain
       // and return early, to avoid the coming semantic disaster.
       Diag(D.getIdentifierLoc(),
            diag::err_template_qualified_declarator_no_match)
-        << (NestedNameSpecifier*)D.getCXXScopeSpec().getScopeRep()
+        << D.getCXXScopeSpec().getScopeRep()
         << D.getCXXScopeSpec().getRange();
-      return 0;
+      return nullptr;
     }
     bool IsDependentContext = DC->isDependentContext();
 
     if (!IsDependentContext && 
         RequireCompleteDeclContext(D.getCXXScopeSpec(), DC))
-      return 0;
+      return nullptr;
 
     if (isa<CXXRecordDecl>(DC) && !cast<CXXRecordDecl>(DC)->hasDefinition()) {
       Diag(D.getIdentifierLoc(),
@@ -4249,8 +4421,8 @@
       if (diagnoseQualifiedDeclaration(D.getCXXScopeSpec(), DC,
                                       Name, D.getIdentifierLoc())) {
         if (DC->isRecord())
-          return 0;
-        
+          return nullptr;
+
         D.setInvalidType();
       }
     }
@@ -4269,8 +4441,8 @@
     // If this is a typedef, we'll end up spewing multiple diagnostics.
     // Just return early; it's safer.
     if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef)
-      return 0;
-  
+      return nullptr;
+
   TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
   QualType R = TInfo->getType();
 
@@ -4371,7 +4543,7 @@
   if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) {
     if (TemplateParamLists.size()) {
       Diag(D.getIdentifierLoc(), diag::err_template_typedef);
-      return 0;
+      return nullptr;
     }
 
     New = ActOnTypedefDeclarator(S, D, DC, TInfo, Previous);
@@ -4384,8 +4556,8 @@
                                   AddToScope);
   }
 
-  if (New == 0)
-    return 0;
+  if (!New)
+    return nullptr;
 
   // If this has an identifier and is not an invalid redeclaration or 
   // function template specialization, add it to the scope stack.
@@ -4512,7 +4684,7 @@
     = TryToFixInvalidVariablyModifiedType(TInfo->getType(), Context,
                                           SizeIsNegative, Oversized);
   if (FixedTy.isNull())
-    return 0;
+    return nullptr;
   TypeSourceInfo *FixedTInfo = Context.getTrivialTypeSourceInfo(FixedTy);
   FixInvalidVariablyModifiedTypeLoc(TInfo->getTypeLoc(),
                                     FixedTInfo->getTypeLoc());
@@ -4551,7 +4723,7 @@
   }
 
   NamedDecl *D = LocallyScopedExternCDecls.lookup(Name);
-  return D ? D->getMostRecentDecl() : 0;
+  return D ? D->getMostRecentDecl() : nullptr;
 }
 
 /// \brief Diagnose function specifiers on a declaration of an identifier that
@@ -4598,11 +4770,11 @@
   if (D.getName().Kind != UnqualifiedId::IK_Identifier) {
     Diag(D.getName().StartLocation, diag::err_typedef_not_identifier)
       << D.getName().getSourceRange();
-    return 0;
+    return nullptr;
   }
 
   TypedefDecl *NewTD = ParseTypedefDecl(S, D, TInfo->getType(), TInfo);
-  if (!NewTD) return 0;
+  if (!NewTD) return nullptr;
 
   // Handle attributes prior to checking for duplicates in MergeVarDecl
   ProcessDeclAttributes(S, NewTD, D);
@@ -4626,7 +4798,7 @@
   if (T->isVariablyModifiedType()) {
     getCurFunction()->setHasBranchProtectedScope();
 
-    if (S->getFnParent() == 0) {
+    if (S->getFnParent() == nullptr) {
       bool SizeIsNegative;
       llvm::APSInt Oversized;
       TypeSourceInfo *FixedTInfo =
@@ -4661,8 +4833,8 @@
                            LookupResult &Previous, bool &Redeclaration) {
   // Merge the decl with the existing one if appropriate. If the decl is
   // in an outer scope, it isn't the same thing.
-  FilterLookupForScope(Previous, DC, S, /*ConsiderLinkage*/ false,
-                       /*ExplicitInstantiationOrSpecialization=*/false);
+  FilterLookupForScope(Previous, DC, S, /*ConsiderLinkage*/false,
+                       /*AllowInlineNamespace*/false);
   filterNonConflictingPreviousDecls(Context, NewTD, Previous);
   if (!Previous.empty()) {
     Redeclaration = true;
@@ -4795,6 +4967,10 @@
 }
 
 static void checkAttributesAfterMerging(Sema &S, NamedDecl &ND) {
+  // Ensure that an auto decl is deduced otherwise the checks below might cache
+  // the wrong linkage.
+  assert(S.ParsingInitForAutoVars.count(&ND) == 0);
+
   // 'weak' only applies to declarations with external linkage.
   if (WeakAttr *Attr = ND.getAttr<WeakAttr>()) {
     if (!ND.isExternallyVisible()) {
@@ -4817,6 +4993,96 @@
       ND.dropAttr<SelectAnyAttr>();
     }
   }
+
+  // dll attributes require external linkage.
+  if (const DLLImportAttr *Attr = ND.getAttr<DLLImportAttr>()) {
+    if (!ND.isExternallyVisible()) {
+      S.Diag(ND.getLocation(), diag::err_attribute_dll_not_extern)
+        << &ND << Attr;
+      ND.setInvalidDecl();
+    }
+  }
+  if (const DLLExportAttr *Attr = ND.getAttr<DLLExportAttr>()) {
+    if (!ND.isExternallyVisible()) {
+      S.Diag(ND.getLocation(), diag::err_attribute_dll_not_extern)
+        << &ND << Attr;
+      ND.setInvalidDecl();
+    }
+  }
+}
+
+static void checkDLLAttributeRedeclaration(Sema &S, NamedDecl *OldDecl,
+                                           NamedDecl *NewDecl,
+                                           bool IsSpecialization) {
+  if (TemplateDecl *OldTD = dyn_cast<TemplateDecl>(OldDecl))
+    OldDecl = OldTD->getTemplatedDecl();
+  if (TemplateDecl *NewTD = dyn_cast<TemplateDecl>(NewDecl))
+    NewDecl = NewTD->getTemplatedDecl();
+
+  if (!OldDecl || !NewDecl)
+    return;
+
+  const DLLImportAttr *OldImportAttr = OldDecl->getAttr<DLLImportAttr>();
+  const DLLExportAttr *OldExportAttr = OldDecl->getAttr<DLLExportAttr>();
+  const DLLImportAttr *NewImportAttr = NewDecl->getAttr<DLLImportAttr>();
+  const DLLExportAttr *NewExportAttr = NewDecl->getAttr<DLLExportAttr>();
+
+  // dllimport and dllexport are inheritable attributes so we have to exclude
+  // inherited attribute instances.
+  bool HasNewAttr = (NewImportAttr && !NewImportAttr->isInherited()) ||
+                    (NewExportAttr && !NewExportAttr->isInherited());
+
+  // A redeclaration is not allowed to add a dllimport or dllexport attribute,
+  // the only exception being explicit specializations.
+  // Implicitly generated declarations are also excluded for now because there
+  // is no other way to switch these to use dllimport or dllexport.
+  bool AddsAttr = !(OldImportAttr || OldExportAttr) && HasNewAttr;
+
+  if (AddsAttr && !IsSpecialization && !OldDecl->isImplicit()) {
+    // If the declaration hasn't been used yet, allow with a warning for
+    // free functions and global variables.
+    bool JustWarn = false;
+    if (!OldDecl->isUsed() && OldDecl->getDeclContext()->isFileContext()) {
+      auto *VD = dyn_cast<VarDecl>(OldDecl);
+      if (VD && !VD->getDescribedVarTemplate())
+        JustWarn = true;
+      auto *FD = dyn_cast<FunctionDecl>(OldDecl);
+      if (FD && FD->getTemplatedKind() == FunctionDecl::TK_NonTemplate)
+        JustWarn = true;
+    }
+
+    unsigned DiagID = JustWarn ? diag::warn_attribute_dll_redeclaration
+                               : diag::err_attribute_dll_redeclaration;
+    S.Diag(NewDecl->getLocation(), DiagID)
+        << NewDecl
+        << (NewImportAttr ? (const Attr *)NewImportAttr : NewExportAttr);
+    S.Diag(OldDecl->getLocation(), diag::note_previous_declaration);
+    if (!JustWarn) {
+      NewDecl->setInvalidDecl();
+      return;
+    }
+  }
+
+  // A redeclaration is not allowed to drop a dllimport attribute, the only
+  // exception being inline function definitions.
+  // NB: MSVC converts such a declaration to dllexport.
+  bool IsInline = false, IsStaticDataMember = false;
+  if (const auto *VD = dyn_cast<VarDecl>(NewDecl))
+    // Ignore static data because out-of-line definitions are diagnosed
+    // separately.
+    IsStaticDataMember = VD->isStaticDataMember();
+  else if (const auto *FD = dyn_cast<FunctionDecl>(NewDecl))
+    IsInline = FD->isInlined();
+
+  if (OldImportAttr && !HasNewAttr && !IsInline && !IsStaticDataMember) {
+    S.Diag(NewDecl->getLocation(),
+           diag::warn_redeclaration_without_attribute_prev_attribute_ignored)
+      << NewDecl << OldImportAttr;
+    S.Diag(OldDecl->getLocation(), diag::note_previous_declaration);
+    S.Diag(OldImportAttr->getLocation(), diag::note_previous_attribute);
+    OldDecl->dropAttr<DLLImportAttr>();
+    NewDecl->dropAttr<DLLImportAttr>();
+  }
 }
 
 /// Given that we are within the definition of the given function,
@@ -4842,7 +5108,8 @@
   FD->setLazyBody(1);
 #endif
 
-  bool isC99Inline = (S.Context.GetGVALinkageForFunction(FD) == GVA_C99Inline);
+  bool isC99Inline =
+      S.Context.GetGVALinkageForFunction(FD) == GVA_AvailableExternally;
 
 #ifndef NDEBUG
   FD->setLazyBody(0);
@@ -4897,6 +5164,31 @@
   llvm_unreachable("Unexpected context");
 }
 
+static bool hasParsedAttr(Scope *S, const AttributeList *AttrList,
+                          AttributeList::Kind Kind) {
+  for (const AttributeList *L = AttrList; L; L = L->getNext())
+    if (L->getKind() == Kind)
+      return true;
+  return false;
+}
+
+static bool hasParsedAttr(Scope *S, const Declarator &PD,
+                          AttributeList::Kind Kind) {
+  // Check decl attributes on the DeclSpec.
+  if (hasParsedAttr(S, PD.getDeclSpec().getAttributes().getList(), Kind))
+    return true;
+
+  // Walk the declarator structure, checking decl attributes that were in a type
+  // position to the decl itself.
+  for (unsigned I = 0, E = PD.getNumTypeObjects(); I != E; ++I) {
+    if (hasParsedAttr(S, PD.getTypeObject(I).getAttrs(), Kind))
+      return true;
+  }
+
+  // Finally, check attributes on the decl itself.
+  return hasParsedAttr(S, PD.getAttributes(), Kind);
+}
+
 /// Adjust the \c DeclContext for a function or variable that might be a
 /// function-local external declaration.
 bool Sema::adjustContextForLocalExternDecl(DeclContext *&DC) {
@@ -4933,16 +5225,36 @@
   VarDecl::StorageClass SC =
     StorageClassSpecToVarDeclStorageClass(D.getDeclSpec());
 
+  // dllimport globals without explicit storage class are treated as extern. We
+  // have to change the storage class this early to get the right DeclContext.
+  if (SC == SC_None && !DC->isRecord() &&
+      hasParsedAttr(S, D, AttributeList::AT_DLLImport) &&
+      !hasParsedAttr(S, D, AttributeList::AT_DLLExport))
+    SC = SC_Extern;
+
   DeclContext *OriginalDC = DC;
   bool IsLocalExternDecl = SC == SC_Extern &&
                            adjustContextForLocalExternDecl(DC);
 
-  if (getLangOpts().OpenCL && !getOpenCLOptions().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()) {
-      Diag(D.getIdentifierLoc(), diag::err_opencl_half_declaration) << R;
-      D.setInvalidType();
+  if (getLangOpts().OpenCL) {
+    // OpenCL v1.0 s6.8.a.3: Pointers to functions are not allowed.
+    QualType NR = R;
+    while (NR->isPointerType()) {
+      if (NR->isFunctionPointerType()) {
+        Diag(D.getIdentifierLoc(), diag::err_opencl_function_pointer_variable);
+        D.setInvalidType();
+        break;
+      }
+      NR = NR->getPointeeType();
+    }
+
+    if (!getOpenCLOptions().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()) {
+        Diag(D.getIdentifierLoc(), diag::err_opencl_half_declaration) << R;
+        D.setInvalidType();
+      }
     }
   }
 
@@ -4969,21 +5281,17 @@
   if (!II) {
     Diag(D.getIdentifierLoc(), diag::err_bad_variable_name)
       << Name;
-    return 0;
+    return nullptr;
   }
 
   DiagnoseFunctionSpecifiers(D.getDeclSpec());
 
-  if (!DC->isRecord() && S->getFnParent() == 0) {
+  if (!DC->isRecord() && S->getFnParent() == nullptr) {
     // C99 6.9p2: The storage-class specifiers auto and register shall not
     // appear in the declaration specifiers in an external declaration.
-    if (SC == SC_Auto || SC == SC_Register) {
-      // If this is a register variable with an asm label specified, then this
-      // is a GNU extension.
-      if (SC == SC_Register && D.getAsmLabel())
-        Diag(D.getIdentifierLoc(), diag::err_unsupported_global_register);
-      else
-        Diag(D.getIdentifierLoc(), diag::err_typecheck_sclass_fscope);
+    // Global Register+Asm is a GNU extension we support.
+    if (SC == SC_Auto || (SC == SC_Register && !D.getAsmLabel())) {
+      Diag(D.getIdentifierLoc(), diag::err_typecheck_sclass_fscope);
       D.setInvalidType();
     }
   }
@@ -5008,7 +5316,7 @@
     // The event type cannot be used with the __local, __constant and __global
     // address space qualifiers.
     if (R->isEventT()) {
-      if (S->getParent() == 0) {
+      if (S->getParent() == nullptr) {
         Diag(D.getLocStart(), diag::err_event_t_global_var);
         D.setInvalidType();
       }
@@ -5024,9 +5332,9 @@
   bool IsVariableTemplateSpecialization = false;
   bool IsPartialSpecialization = false;
   bool IsVariableTemplate = false;
-  VarTemplateDecl *PrevVarTemplate = 0;
-  VarDecl *NewVD = 0;
-  VarTemplateDecl *NewTemplate = 0;
+  VarDecl *NewVD = nullptr;
+  VarTemplateDecl *NewTemplate = nullptr;
+  TemplateParameterList *TemplateParams = nullptr;
   if (!getLangOpts().CPlusPlus) {
     NewVD = VarDecl::Create(Context, DC, D.getLocStart(),
                             D.getIdentifierLoc(), II,
@@ -5088,18 +5396,17 @@
       }
     }
 
-    NamedDecl *PrevDecl = 0;
-    if (Previous.begin() != Previous.end())
-      PrevDecl = (*Previous.begin())->getUnderlyingDecl();
-    PrevVarTemplate = dyn_cast_or_null<VarTemplateDecl>(PrevDecl);
-
     // Match up the template parameter lists with the scope specifier, then
     // determine whether we have a template or a template specialization.
-    TemplateParameterList *TemplateParams =
-        MatchTemplateParametersToScopeSpecifier(
-            D.getDeclSpec().getLocStart(), D.getIdentifierLoc(),
-            D.getCXXScopeSpec(), TemplateParamLists,
-            /*never a friend*/ false, IsExplicitSpecialization, Invalid);
+    TemplateParams = MatchTemplateParametersToScopeSpecifier(
+        D.getDeclSpec().getLocStart(), D.getIdentifierLoc(),
+        D.getCXXScopeSpec(),
+        D.getName().getKind() == UnqualifiedId::IK_TemplateId
+            ? D.getName().TemplateId
+            : nullptr,
+        TemplateParamLists,
+        /*never a friend*/ false, IsExplicitSpecialization, Invalid);
+
     if (TemplateParams) {
       if (!TemplateParams->size() &&
           D.getName().getKind() != UnqualifiedId::IK_TemplateId) {
@@ -5110,113 +5417,43 @@
           << II
           << SourceRange(TemplateParams->getTemplateLoc(),
                          TemplateParams->getRAngleLoc());
+        TemplateParams = nullptr;
       } else {
-        // Only C++1y supports variable templates (N3651).
-        Diag(D.getIdentifierLoc(),
-             getLangOpts().CPlusPlus1y
-                 ? diag::warn_cxx11_compat_variable_template
-                 : diag::ext_variable_template);
-
         if (D.getName().getKind() == UnqualifiedId::IK_TemplateId) {
           // This is an explicit specialization or a partial specialization.
-          // Check that we can declare a specialization here
-
+          // FIXME: Check that we can declare a specialization here.
           IsVariableTemplateSpecialization = true;
           IsPartialSpecialization = TemplateParams->size() > 0;
-
         } else { // if (TemplateParams->size() > 0)
           // This is a template declaration.
           IsVariableTemplate = true;
 
           // Check that we can declare a template here.
           if (CheckTemplateDeclScope(S, TemplateParams))
-            return 0;
+            return nullptr;
 
-          // If there is a previous declaration with the same name, check
-          // whether this is a valid redeclaration.
-          if (PrevDecl && !isDeclInScope(PrevDecl, DC, S))
-            PrevDecl = PrevVarTemplate = 0;
-
-          if (PrevVarTemplate) {
-            // Ensure that the template parameter lists are compatible.
-            if (!TemplateParameterListsAreEqual(
-                    TemplateParams, PrevVarTemplate->getTemplateParameters(),
-                    /*Complain=*/true, TPL_TemplateMatch))
-              return 0;
-          } else if (PrevDecl && PrevDecl->isTemplateParameter()) {
-            // Maybe we will complain about the shadowed template parameter.
-            DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl);
-
-            // Just pretend that we didn't see the previous declaration.
-            PrevDecl = 0;
-          } else if (PrevDecl) {
-            // C++ [temp]p5:
-            // ... a template name declared in namespace scope or in class
-            // scope shall be unique in that scope.
-            Diag(D.getIdentifierLoc(), diag::err_redefinition_different_kind)
-                << Name;
-            Diag(PrevDecl->getLocation(), diag::note_previous_definition);
-            return 0;
-          }
-
-          // Check the template parameter list of this declaration, possibly
-          // merging in the template parameter list from the previous variable
-          // template declaration.
-          if (CheckTemplateParameterList(
-                  TemplateParams,
-                  PrevVarTemplate ? PrevVarTemplate->getTemplateParameters()
-                                  : 0,
-                  (D.getCXXScopeSpec().isSet() && DC && DC->isRecord() &&
-                   DC->isDependentContext())
-                      ? TPC_ClassTemplateMember
-                      : TPC_VarTemplate))
-            Invalid = true;
-
-          if (D.getCXXScopeSpec().isSet()) {
-            // If the name of the template was qualified, we must be defining
-            // the template out-of-line.
-            if (!D.getCXXScopeSpec().isInvalid() && !Invalid &&
-                !PrevVarTemplate) {
-              Diag(D.getIdentifierLoc(), diag::err_member_decl_does_not_match)
-                  << Name << DC << /*IsDefinition*/true
-                  << D.getCXXScopeSpec().getRange();
-              Invalid = true;
-            }
-          }
+          // Only C++1y supports variable templates (N3651).
+          Diag(D.getIdentifierLoc(),
+               getLangOpts().CPlusPlus1y
+                   ? diag::warn_cxx11_compat_variable_template
+                   : diag::ext_variable_template);
         }
       }
-    } else if (D.getName().getKind() == UnqualifiedId::IK_TemplateId) {
-      TemplateIdAnnotation *TemplateId = D.getName().TemplateId;
-
-      // We have encountered something that the user meant to be a
-      // specialization (because it has explicitly-specified template
-      // arguments) but that was not introduced with a "template<>" (or had
-      // too few of them).
-      // FIXME: Differentiate between attempts for explicit instantiations
-      // (starting with "template") and the rest.
-      Diag(D.getIdentifierLoc(), diag::err_template_spec_needs_header)
-          << SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc)
-          << FixItHint::CreateInsertion(D.getDeclSpec().getLocStart(),
-                                        "template<> ");
-      IsVariableTemplateSpecialization = true;
+    } else {
+      assert(D.getName().getKind() != UnqualifiedId::IK_TemplateId &&
+             "should have a 'template<>' for this decl");
     }
 
     if (IsVariableTemplateSpecialization) {
-      if (!PrevVarTemplate) {
-        Diag(D.getIdentifierLoc(), diag::err_var_spec_no_template)
-            << IsPartialSpecialization;
-        return 0;
-      }
-
       SourceLocation TemplateKWLoc =
           TemplateParamLists.size() > 0
               ? TemplateParamLists[0]->getTemplateLoc()
               : SourceLocation();
       DeclResult Res = ActOnVarTemplateSpecialization(
-          S, PrevVarTemplate, D, TInfo, TemplateKWLoc, TemplateParams, SC,
+          S, D, TInfo, TemplateKWLoc, TemplateParams, SC,
           IsPartialSpecialization);
       if (Res.isInvalid())
-        return 0;
+        return nullptr;
       NewVD = cast<VarDecl>(Res.get());
       AddToScope = false;
     } else
@@ -5227,7 +5464,7 @@
     if (IsVariableTemplate) {
       NewTemplate =
           VarTemplateDecl::Create(Context, DC, D.getIdentifierLoc(), Name,
-                                  TemplateParams, NewVD, PrevVarTemplate);
+                                  TemplateParams, NewVD);
       NewVD->setDescribedVarTemplate(NewTemplate);
     }
 
@@ -5244,18 +5481,13 @@
 
     SetNestedNameSpecifier(NewVD, D);
 
-    // FIXME: Do we need D.getCXXScopeSpec().isSet()?
-    if (TemplateParams && TemplateParamLists.size() > 1 &&
-        (!IsVariableTemplateSpecialization || D.getCXXScopeSpec().isSet())) {
+    // If we have any template parameter lists that don't directly belong to
+    // the variable (matching the scope specifier), store them.
+    unsigned VDTemplateParamLists = TemplateParams ? 1 : 0;
+    if (TemplateParamLists.size() > VDTemplateParamLists)
       NewVD->setTemplateParameterListsInfo(
-          Context, TemplateParamLists.size() - 1, TemplateParamLists.data());
-    } else if (IsVariableTemplateSpecialization ||
-               (!TemplateParams && TemplateParamLists.size() > 0 &&
-                (D.getCXXScopeSpec().isSet()))) {
-      NewVD->setTemplateParameterListsInfo(Context,
-                                           TemplateParamLists.size(),
-                                           TemplateParamLists.data());
-    }
+          Context, TemplateParamLists.size() - VDTemplateParamLists,
+          TemplateParamLists.data());
 
     if (D.getDeclSpec().isConstexprSpecified())
       NewVD->setConstexpr(true);
@@ -5302,7 +5534,7 @@
   // that a local variable with thread storage duration still has to
   // be marked 'static'.  Also note that it's possible to get these
   // semantics in C++ using __attribute__((gnu_inline)).
-  if (SC == SC_Static && S->getFnParent() != 0 &&
+  if (SC == SC_Static && S->getFnParent() != nullptr &&
       !NewVD->getType().isConstQualified()) {
     FunctionDecl *CurFD = getCurFunctionDecl();
     if (CurFD && isFunctionDefinitionDiscarded(*this, CurFD)) {
@@ -5337,19 +5569,23 @@
   // Handle attributes prior to checking for duplicates in MergeVarDecl
   ProcessDeclAttributes(S, NewVD, D);
 
-  if (NewVD->hasAttrs())
-    CheckAlignasUnderalignment(NewVD);
-
   if (getLangOpts().CUDA) {
     // CUDA B.2.5: "__shared__ and __constant__ variables have implied static
     // storage [duration]."
-    if (SC == SC_None && S->getFnParent() != 0 &&
+    if (SC == SC_None && S->getFnParent() != nullptr &&
         (NewVD->hasAttr<CUDASharedAttr>() ||
          NewVD->hasAttr<CUDAConstantAttr>())) {
       NewVD->setStorageClass(SC_Static);
     }
   }
 
+  // Ensure that dllimport globals without explicit storage class are treated as
+  // extern. The storage class is set above using parsed attributes. Now we can
+  // check the VarDecl itself.
+  assert(!NewVD->hasAttr<DLLImportAttr>() ||
+         NewVD->getAttr<DLLImportAttr>()->isInherited() ||
+         NewVD->isStaticDataMember() || NewVD->getStorageClass() != SC_None);
+
   // In auto-retain/release, infer strong retension for variables of
   // retainable type.
   if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(NewVD))
@@ -5360,13 +5596,14 @@
     // The parser guarantees this is a string.
     StringLiteral *SE = cast<StringLiteral>(E);
     StringRef Label = SE->getString();
-    if (S->getFnParent() != 0) {
+    if (S->getFnParent() != nullptr) {
       switch (SC) {
       case SC_None:
       case SC_Auto:
         Diag(E->getExprLoc(), diag::warn_asm_label_on_auto_decl) << Label;
         break;
       case SC_Register:
+        // Local Named register
         if (!Context.getTargetInfo().isValidGCCRegisterName(Label))
           Diag(E->getExprLoc(), diag::err_asm_unknown_register_name) << Label;
         break;
@@ -5376,10 +5613,18 @@
       case SC_OpenCLWorkGroupLocal:
         break;
       }
+    } else if (SC == SC_Register) {
+      // Global Named register
+      if (!Context.getTargetInfo().isValidGCCRegisterName(Label))
+        Diag(E->getExprLoc(), diag::err_asm_unknown_register_name) << Label;
+      if (!R->isIntegralType(Context) && !R->isPointerType()) {
+        Diag(D.getLocStart(), diag::err_asm_bad_register_type);
+        NewVD->setInvalidDecl(true);
+      }
     }
 
     NewVD->addAttr(::new (Context) AsmLabelAttr(SE->getStrTokenLoc(0),
-                                                Context, Label));
+                                                Context, Label, 0));
   } else if (!ExtnameUndeclaredIdentifiers.empty()) {
     llvm::DenseMap<IdentifierInfo*,AsmLabelAttr*>::iterator I =
       ExtnameUndeclaredIdentifiers.find(NewVD->getIdentifier());
@@ -5390,15 +5635,16 @@
   }
 
   // Diagnose shadowed variables before filtering for scope.
-  if (!D.getCXXScopeSpec().isSet())
+  if (D.getCXXScopeSpec().isEmpty())
     CheckShadow(S, NewVD, Previous);
 
   // 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),
-      IsExplicitSpecialization || IsVariableTemplateSpecialization);
+  FilterLookupForScope(Previous, OriginalDC, S, shouldConsiderLinkage(NewVD),
+                       D.getCXXScopeSpec().isNotEmpty() ||
+                       IsExplicitSpecialization ||
+                       IsVariableTemplateSpecialization);
 
   // Check whether the previous declaration is in the same block scope. This
   // affects whether we merge types with it, per C++11 [dcl.array]p3.
@@ -5411,6 +5657,11 @@
   if (!getLangOpts().CPlusPlus) {
     D.setRedeclaration(CheckVariableDeclaration(NewVD, Previous));
   } else {
+    // If this is an explicit specialization of a static data member, check it.
+    if (IsExplicitSpecialization && !NewVD->isInvalidDecl() &&
+        CheckMemberSpecialization(NewVD, Previous))
+      NewVD->setInvalidDecl();
+
     // Merge the decl with the existing one if appropriate.
     if (!Previous.empty()) {
       if (Previous.isSingleResult() &&
@@ -5431,24 +5682,37 @@
       NewVD->setInvalidDecl();
     }
 
-    if (!IsVariableTemplateSpecialization) {
-      if (PrevVarTemplate) {
-        LookupResult PrevDecl(*this, GetNameForDeclarator(D),
-                              LookupOrdinaryName, ForRedeclaration);
-        PrevDecl.addDecl(PrevVarTemplate->getTemplatedDecl());
-        D.setRedeclaration(CheckVariableDeclaration(NewVD, PrevDecl));
-      } else
-        D.setRedeclaration(CheckVariableDeclaration(NewVD, Previous));
-    }
+    if (!IsVariableTemplateSpecialization)
+      D.setRedeclaration(CheckVariableDeclaration(NewVD, Previous));
 
-    // This is an explicit specialization of a static data member. Check it.
-    if (IsExplicitSpecialization && !NewVD->isInvalidDecl() &&
-        CheckMemberSpecialization(NewVD, Previous))
-      NewVD->setInvalidDecl();
+    if (NewTemplate) {
+      VarTemplateDecl *PrevVarTemplate =
+          NewVD->getPreviousDecl()
+              ? NewVD->getPreviousDecl()->getDescribedVarTemplate()
+              : nullptr;
+
+      // Check the template parameter list of this declaration, possibly
+      // merging in the template parameter list from the previous variable
+      // template declaration.
+      if (CheckTemplateParameterList(
+              TemplateParams,
+              PrevVarTemplate ? PrevVarTemplate->getTemplateParameters()
+                              : nullptr,
+              (D.getCXXScopeSpec().isSet() && DC && DC->isRecord() &&
+               DC->isDependentContext())
+                  ? TPC_ClassTemplateMember
+                  : TPC_VarTemplate))
+        NewVD->setInvalidDecl();
+
+      // If we are providing an explicit specialization of a static variable
+      // template, make a note of that.
+      if (PrevVarTemplate &&
+          PrevVarTemplate->getInstantiatedFromMemberTemplate())
+        PrevVarTemplate->setMemberSpecialization();
+    }
   }
 
   ProcessPragmaWeak(S, NewVD);
-  checkAttributesAfterMerging(*this, *NewVD);
 
   // If this is the first declaration of an extern C variable, update
   // the map of such variables.
@@ -5461,16 +5725,21 @@
     if (MangleNumberingContext *MCtx =
             getCurrentMangleNumberContext(NewVD->getDeclContext(),
                                           ManglingContextDecl)) {
-      Context.setManglingNumber(NewVD, MCtx->getManglingNumber(NewVD));
+      Context.setManglingNumber(
+          NewVD, MCtx->getManglingNumber(NewVD, S->getMSLocalManglingNumber()));
+      Context.setStaticLocalNumber(NewVD, MCtx->getStaticLocalNumber(NewVD));
     }
   }
 
-  // If we are providing an explicit specialization of a static variable
-  // template, make a note of that.
-  if (PrevVarTemplate && PrevVarTemplate->getInstantiatedFromMemberTemplate())
-    PrevVarTemplate->setMemberSpecialization();
+  if (D.isRedeclaration() && !Previous.empty()) {
+    checkDLLAttributeRedeclaration(
+        *this, dyn_cast<NamedDecl>(Previous.getRepresentativeDecl()), NewVD,
+        IsExplicitSpecialization);
+  }
 
   if (NewTemplate) {
+    if (NewVD->isInvalidDecl())
+      NewTemplate->setInvalidDecl();
     ActOnDocumentableDecl(NewTemplate);
     return NewTemplate;
   }
@@ -5489,8 +5758,7 @@
 ///
 void Sema::CheckShadow(Scope *S, VarDecl *D, const LookupResult& R) {
   // Return if warning is ignored.
-  if (Diags.getDiagnosticLevel(diag::warn_decl_shadow, R.getNameLoc()) ==
-        DiagnosticsEngine::Ignored)
+  if (Diags.isIgnored(diag::warn_decl_shadow, R.getNameLoc()))
     return;
 
   // Don't diagnose declarations at file scope.
@@ -5517,11 +5785,9 @@
     if (shadowedVar->isExternC()) {
       // For shadowing external vars, make sure that we point to the global
       // declaration, not a locally scoped extern declaration.
-      for (VarDecl::redecl_iterator
-             I = shadowedVar->redecls_begin(), E = shadowedVar->redecls_end();
-           I != E; ++I)
+      for (auto I : shadowedVar->redecls())
         if (I->isFileVarDecl()) {
-          ShadowedDecl = *I;
+          ShadowedDecl = I;
           break;
         }
     }
@@ -5557,14 +5823,15 @@
   DeclarationName Name = R.getLookupName();
 
   // Emit warning and note.
+  if (getSourceManager().isInSystemMacro(R.getNameLoc()))
+    return;
   Diag(R.getNameLoc(), diag::warn_decl_shadow) << Name << Kind << OldDC;
   Diag(ShadowedDecl->getLocation(), diag::note_previous_declaration);
 }
 
 /// \brief Check -Wshadow without the advantage of a previous lookup.
 void Sema::CheckShadow(Scope *S, VarDecl *D) {
-  if (Diags.getDiagnosticLevel(diag::warn_decl_shadow, D->getLocation()) ==
-        DiagnosticsEngine::Ignored)
+  if (Diags.isIgnored(diag::warn_decl_shadow, D->getLocation()))
     return;
 
   LookupResult R(*this, D->getDeclName(), D->getLocation(),
@@ -5702,6 +5969,9 @@
   if (T->isUndeducedType())
     return;
 
+  if (NewVD->hasAttrs())
+    CheckAlignasUnderalignment(NewVD);
+
   if (T->isObjCObjectType()) {
     Diag(NewVD->getLocation(), diag::err_statically_allocated_object)
       << FixItHint::CreateInsertion(NewVD->getLocation(), "*");
@@ -5760,7 +6030,7 @@
     TypeSourceInfo *FixedTInfo =
       TryToFixInvalidVariablyModifiedTypeSourceInfo(TInfo, Context,
                                                     SizeIsNegative, Oversized);
-    if (FixedTInfo == 0 && T->isVariableArrayType()) {
+    if (!FixedTInfo && T->isVariableArrayType()) {
       const VariableArrayType *VAT = Context.getAsVariableArrayType(T);
       // FIXME: This won't give the correct result for
       // int a[10][n];
@@ -5779,7 +6049,7 @@
       return;
     }
 
-    if (FixedTInfo == 0) {
+    if (!FixedTInfo) {
       if (NewVD->isFileVarDecl())
         Diag(NewVD->getLocation(), diag::err_vm_decl_in_file_scope);
       else
@@ -5819,7 +6089,6 @@
   if (NewVD->isConstexpr() && !T->isDependentType() &&
       RequireLiteralType(NewVD->getLocation(), T,
                          diag::err_constexpr_var_non_literal)) {
-    // Can't perform this check until the type is deduced.
     NewVD->setInvalidDecl();
     return;
   }
@@ -5938,9 +6207,8 @@
   bool hasNonDeletedOverridenMethods = false;
   bool AddedAny = false;
   if (DC->lookupInBases(&FindOverriddenMethod, &Data, Paths)) {
-    for (CXXBasePaths::decl_iterator I = Paths.found_decls_begin(),
-         E = Paths.found_decls_end(); I != E; ++I) {
-      if (CXXMethodDecl *OldMD = dyn_cast<CXXMethodDecl>(*I)) {
+    for (auto *I : Paths.found_decls()) {
+      if (CXXMethodDecl *OldMD = dyn_cast<CXXMethodDecl>(I)) {
         MD->addOverriddenMethod(OldMD->getCanonicalDecl());
         if (!CheckOverridingFunctionReturnType(MD, OldMD) &&
             !CheckOverridingFunctionAttributes(MD, OldMD) &&
@@ -5984,9 +6252,9 @@
   DifferentNameValidatorCCC(ASTContext &Context, FunctionDecl *TypoFD,
                             CXXRecordDecl *Parent)
       : Context(Context), OriginalFD(TypoFD),
-        ExpectedParent(Parent ? Parent->getCanonicalDecl() : 0) {}
+        ExpectedParent(Parent ? Parent->getCanonicalDecl() : nullptr) {}
 
-  virtual bool ValidateCandidate(const TypoCorrection &candidate) {
+  bool ValidateCandidate(const TypoCorrection &candidate) override {
     if (candidate.getEditDistance() == 0)
       return false;
 
@@ -6053,7 +6321,7 @@
          "Cannot have an ambiguity in previous-declaration lookup");
   CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewFD);
   DifferentNameValidatorCCC Validator(SemaRef.Context, NewFD,
-                                      MD ? MD->getParent() : 0);
+                                      MD ? MD->getParent() : nullptr);
   if (!Prev.empty()) {
     for (LookupResult::iterator Func = Prev.begin(), FuncEnd = Prev.end();
          Func != FuncEnd; ++Func) {
@@ -6071,7 +6339,7 @@
   } else if ((Correction = SemaRef.CorrectTypo(
                  Prev.getLookupNameInfo(), Prev.getLookupKind(), S,
                  &ExtraArgs.D.getCXXScopeSpec(), Validator,
-                 IsLocalFriend ? 0 : NewDC))) {
+                 Sema::CTK_ErrorRecovery, IsLocalFriend ? nullptr : NewDC))) {
     // Set up everything for the call to ActOnFunctionDeclarator
     ExtraArgs.D.SetIdentifier(Correction.getCorrectionAsIdentifierInfo(),
                               ExtraArgs.D.getIdentifierLoc());
@@ -6105,7 +6373,7 @@
           ExtraArgs.AddToScope);
 
       if (Trap.hasErrorOccurred())
-        Result = 0;
+        Result = nullptr;
     }
 
     if (Result) {
@@ -6165,7 +6433,7 @@
                    IsMember ? diag::note_member_def_close_match
                             : diag::note_local_decl_close_match);
   }
-  return 0;
+  return nullptr;
 }
 
 static FunctionDecl::StorageClass getFunctionStorageClass(Sema &SemaRef, 
@@ -6212,7 +6480,7 @@
   DeclarationNameInfo NameInfo = SemaRef.GetNameForDeclarator(D);
   DeclarationName Name = NameInfo.getName();
 
-  FunctionDecl *NewFD = 0;
+  FunctionDecl *NewFD = nullptr;
   bool isInline = D.getDeclSpec().isInlineSpecified();
 
   if (!SemaRef.getLangOpts().CPlusPlus) {
@@ -6245,10 +6513,9 @@
   // For record types, this is done by the AbstractClassUsageDiagnoser once
   // the class has been completely parsed.
   if (!DC->isRecord() &&
-      SemaRef.RequireNonAbstractType(D.getIdentifierLoc(),
-                                     R->getAs<FunctionType>()->getResultType(),
-                                     diag::err_abstract_type_in_decl,
-                                     SemaRef.AbstractReturnType))
+      SemaRef.RequireNonAbstractType(
+          D.getIdentifierLoc(), R->getAs<FunctionType>()->getReturnType(),
+          diag::err_abstract_type_in_decl, SemaRef.AbstractReturnType))
     D.setInvalidType();
 
   if (Name.getNameKind() == DeclarationName::CXXConstructorName) {
@@ -6283,15 +6550,6 @@
         SemaRef.AdjustDestructorExceptionSpec(Record, NewDD);
       }
 
-      // The Microsoft ABI requires that we perform the destructor body
-      // checks (i.e. operator delete() lookup) at every declaration, as
-      // any translation unit may need to emit a deleting destructor.
-      if (SemaRef.Context.getTargetInfo().getCXXABI().isMicrosoft() &&
-          !Record->isDependentType() && Record->getDefinition() &&
-          !Record->isBeingDefined()) {
-        SemaRef.CheckDestructor(NewDD);
-      }
-
       IsVirtualOkay = true;
       return NewDD;
 
@@ -6312,7 +6570,7 @@
     if (!DC->isRecord()) {
       SemaRef.Diag(D.getIdentifierLoc(),
            diag::err_conv_function_not_member);
-      return 0;
+      return nullptr;
     }
 
     SemaRef.CheckConversionDeclarator(D, R, SC);
@@ -6332,7 +6590,7 @@
       SemaRef.Diag(D.getIdentifierLoc(), diag::err_constructor_return_type)
         << SourceRange(D.getDeclSpec().getTypeSpecTypeLoc())
         << SourceRange(D.getIdentifierLoc());
-      return 0;
+      return nullptr;
     }
 
     // This is a C++ method declaration.
@@ -6354,26 +6612,11 @@
   }
 }
 
-void Sema::checkVoidParamDecl(ParmVarDecl *Param) {
-  // In C++, the empty parameter-type-list must be spelled "void"; a
-  // typedef of void is not permitted.
-  if (getLangOpts().CPlusPlus &&
-      Param->getType().getUnqualifiedType() != Context.VoidTy) {
-    bool IsTypeAlias = false;
-    if (const TypedefType *TT = Param->getType()->getAs<TypedefType>())
-      IsTypeAlias = isa<TypeAliasDecl>(TT->getDecl());
-    else if (const TemplateSpecializationType *TST =
-               Param->getType()->getAs<TemplateSpecializationType>())
-      IsTypeAlias = TST->isTypeAlias();
-    Diag(Param->getLocation(), diag::err_param_typedef_of_void)
-      << IsTypeAlias;
-  }
-}
-
 enum OpenCLParamType {
   ValidKernelParam,
   PtrPtrKernelParam,
   PtrKernelParam,
+  PrivatePtrKernelParam,
   InvalidKernelParam,
   RecordKernelParam
 };
@@ -6381,7 +6624,10 @@
 static OpenCLParamType getOpenCLKernelParameterType(QualType PT) {
   if (PT->isPointerType()) {
     QualType PointeeType = PT->getPointeeType();
-    return PointeeType->isPointerType() ? PtrPtrKernelParam : PtrKernelParam;
+    if (PointeeType->isPointerType())
+      return PtrPtrKernelParam;
+    return PointeeType.getAddressSpace() == 0 ? PrivatePtrKernelParam
+                                              : PtrKernelParam;
   }
 
   // TODO: Forbid the other integer types (size_t, ptrdiff_t...) when they can
@@ -6426,6 +6672,14 @@
     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);
+    D.setInvalidType();
+    return;
+
     // OpenCL v1.2 s6.9.k:
     // Arguments to kernel functions in a program cannot be declared with the
     // built-in scalar types bool, half, size_t, ptrdiff_t, intptr_t, and
@@ -6455,7 +6709,7 @@
   // Track where we are in the nested structs. Items will migrate from
   // VisitStack to HistoryStack as we do the DFS for bad field.
   SmallVector<const FieldDecl *, 4> HistoryStack;
-  HistoryStack.push_back((const FieldDecl *) 0);
+  HistoryStack.push_back(nullptr);
 
   const RecordDecl *PD = PT->castAs<RecordType>()->getDecl();
   VisitStack.push_back(PD);
@@ -6484,11 +6738,9 @@
     }
 
     // Add a null marker so we know when we've gone back up a level
-    VisitStack.push_back((const Decl *) 0);
+    VisitStack.push_back(nullptr);
 
-    for (RecordDecl::field_iterator I = RD->field_begin(),
-           E = RD->field_end(); I != E; ++I) {
-      const FieldDecl *FD = *I;
+    for (const auto *FD : RD->fields()) {
       QualType QT = FD->getType();
 
       if (ValidTypes.count(QT.getTypePtr()))
@@ -6507,7 +6759,8 @@
       // Arguments to kernel functions that are declared to be a struct or union
       // do not allow OpenCL objects to be passed as elements of the struct or
       // union.
-      if (ParamType == PtrKernelParam || ParamType == PtrPtrKernelParam) {
+      if (ParamType == PtrKernelParam || ParamType == PtrPtrKernelParam ||
+          ParamType == PrivatePtrKernelParam) {
         S.Diag(Param->getLocation(),
                diag::err_record_with_pointers_kernel_param)
           << PT->isUnionType()
@@ -6560,7 +6813,7 @@
     adjustMemberFunctionCC(R, D.isStaticMember());
 
   bool isFriend = false;
-  FunctionTemplateDecl *FunctionTemplate = 0;
+  FunctionTemplateDecl *FunctionTemplate = nullptr;
   bool isExplicitSpecialization = false;
   bool isFunctionTemplateSpecialization = false;
 
@@ -6575,7 +6828,7 @@
 
   FunctionDecl *NewFD = CreateNewFunctionDecl(*this, D, DC, R, TInfo, SC,
                                               isVirtualOkay);
-  if (!NewFD) return 0;
+  if (!NewFD) return nullptr;
 
   if (OriginalLexicalContext && OriginalLexicalContext->isObjCContainer())
     NewFD->setTopLevelDeclInObjCContainer();
@@ -6622,19 +6875,23 @@
     if (TemplateParameterList *TemplateParams =
             MatchTemplateParametersToScopeSpecifier(
                 D.getDeclSpec().getLocStart(), D.getIdentifierLoc(),
-                D.getCXXScopeSpec(), TemplateParamLists, isFriend,
-                isExplicitSpecialization, Invalid)) {
+                D.getCXXScopeSpec(),
+                D.getName().getKind() == UnqualifiedId::IK_TemplateId
+                    ? D.getName().TemplateId
+                    : nullptr,
+                TemplateParamLists, isFriend, isExplicitSpecialization,
+                Invalid)) {
       if (TemplateParams->size() > 0) {
         // This is a function template
 
         // Check that we can declare a template here.
         if (CheckTemplateDeclScope(S, TemplateParams))
-          return 0;
+          return nullptr;
 
         // A destructor cannot be a template.
         if (Name.getNameKind() == DeclarationName::CXXDestructorName) {
           Diag(NewFD->getLocation(), diag::err_destructor_template);
-          return 0;
+          return nullptr;
         }
         
         // If we're adding a template to a dependent context, we may need to 
@@ -6664,9 +6921,10 @@
         // This is a function template specialization.
         isFunctionTemplateSpecialization = true;
         // For source fidelity, store all the template param lists.
-        NewFD->setTemplateParameterListsInfo(Context,
-                                             TemplateParamLists.size(),
-                                             TemplateParamLists.data());
+        if (TemplateParamLists.size() > 0)
+          NewFD->setTemplateParameterListsInfo(Context,
+                                               TemplateParamLists.size(),
+                                               TemplateParamLists.data());
 
         // C++0x [temp.expl.spec]p20 forbids "template<> friend void foo(int);".
         if (isFriend) {
@@ -6681,7 +6939,7 @@
           SourceLocation InsertLoc;
           if (D.getName().getKind() != UnqualifiedId::IK_TemplateId) {
             InsertLoc = D.getName().getSourceRange().getEnd();
-            InsertLoc = PP.getLocForEndOfToken(InsertLoc);
+            InsertLoc = getLocForEndOfToken(InsertLoc);
           }
 
           Diag(D.getIdentifierLoc(), diag::err_template_spec_decl_friend)
@@ -6733,14 +6991,14 @@
       }
 
       if (getLangOpts().CPlusPlus1y &&
-          NewFD->getResultType()->isUndeducedType())
+          NewFD->getReturnType()->isUndeducedType())
         Diag(D.getDeclSpec().getVirtualSpecLoc(), diag::err_auto_fn_virtual);
     }
 
     if (getLangOpts().CPlusPlus1y &&
         (NewFD->isDependentContext() ||
          (isFriend && CurContext->isDependentContext())) &&
-        NewFD->getResultType()->isUndeducedType()) {
+        NewFD->getReturnType()->isUndeducedType()) {
       // If the function template is referenced directly (for instance, as a
       // member of the current instantiation), pretend it has a dependent type.
       // This is not really justified by the standard, but is the only sane
@@ -6749,9 +7007,9 @@
       // a friend yet, so 'isDependentContext' on the FD doesn't work.
       const FunctionProtoType *FPT =
           NewFD->getType()->castAs<FunctionProtoType>();
-      QualType Result = SubstAutoType(FPT->getResultType(),
-                                       Context.DependentTy);
-      NewFD->setType(Context.getFunctionType(Result, FPT->getArgTypes(),
+      QualType Result =
+          SubstAutoType(FPT->getReturnType(), Context.DependentTy);
+      NewFD->setType(Context.getFunctionType(Result, FPT->getParamTypes(),
                                              FPT->getExtProtoInfo()));
     }
 
@@ -6824,6 +7082,8 @@
     }
 
     // If a function is defined as defaulted or deleted, mark it as such now.
+    // FIXME: Does this ever happen? ActOnStartOfFunctionDef forces the function
+    // definition kind to FDK_Definition.
     switch (D.getFunctionDefinitionKind()) {
       case FDK_Declaration:
       case FDK_Definition:
@@ -6869,13 +7129,14 @@
         getLangOpts().CPlusPlus11 && FPT && !FPT->hasExceptionSpec()) {
       FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
       EPI.ExceptionSpecType = EST_BasicNoexcept;
-      NewFD->setType(Context.getFunctionType(FPT->getResultType(),
-                                             FPT->getArgTypes(), EPI));
+      NewFD->setType(Context.getFunctionType(FPT->getReturnType(),
+                                             FPT->getParamTypes(), EPI));
     }
   }
 
   // Filter out previous declarations that don't match the scope.
   FilterLookupForScope(Previous, OriginalDC, S, shouldConsiderLinkage(NewFD),
+                       D.getCXXScopeSpec().isNotEmpty() ||
                        isExplicitSpecialization ||
                        isFunctionTemplateSpecialization);
 
@@ -6884,7 +7145,7 @@
     // The parser guarantees this is a string.
     StringLiteral *SE = cast<StringLiteral>(E);
     NewFD->addAttr(::new (Context) AsmLabelAttr(SE->getStrTokenLoc(0), Context,
-                                                SE->getString()));
+                                                SE->getString(), 0));
   } else if (!ExtnameUndeclaredIdentifiers.empty()) {
     llvm::DenseMap<IdentifierInfo*,AsmLabelAttr*>::iterator I =
       ExtnameUndeclaredIdentifiers.find(NewFD->getIdentifier());
@@ -6905,14 +7166,9 @@
     // single void argument.
     // We let through "const void" here because Sema::GetTypeForDeclarator
     // already checks for that case.
-    if (FTI.NumArgs == 1 && !FTI.isVariadic && FTI.ArgInfo[0].Ident == 0 &&
-        FTI.ArgInfo[0].Param &&
-        cast<ParmVarDecl>(FTI.ArgInfo[0].Param)->getType()->isVoidType()) {
-      // Empty arg list, don't push any params.
-      checkVoidParamDecl(cast<ParmVarDecl>(FTI.ArgInfo[0].Param));
-    } else if (FTI.NumArgs > 0 && FTI.ArgInfo[0].Param != 0) {
-      for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i) {
-        ParmVarDecl *Param = cast<ParmVarDecl>(FTI.ArgInfo[i].Param);
+    if (FTIHasNonVoidParameters(FTI) && FTI.Params[0].Param) {
+      for (unsigned i = 0, e = FTI.NumParams; i != e; ++i) {
+        ParmVarDecl *Param = cast<ParmVarDecl>(FTI.Params[i].Param);
         assert(Param->getDeclContext() != NewFD && "Was set before ?");
         Param->setDeclContext(NewFD);
         Params.push_back(Param);
@@ -6933,10 +7189,9 @@
     // @endcode
 
     // Synthesize a parameter for each argument type.
-    for (FunctionProtoType::arg_type_iterator AI = FT->arg_type_begin(),
-         AE = FT->arg_type_end(); AI != AE; ++AI) {
+    for (const auto &AI : FT->param_types()) {
       ParmVarDecl *Param =
-        BuildParmVarDeclForTypedef(NewFD, D.getIdentifierLoc(), *AI);
+          BuildParmVarDeclForTypedef(NewFD, D.getIdentifierLoc(), AI);
       Param->setScopeInfo(0, Params.size());
       Params.push_back(Param);
     }
@@ -6960,30 +7215,53 @@
   if (D.getDeclSpec().isNoreturnSpecified())
     NewFD->addAttr(
         ::new(Context) C11NoReturnAttr(D.getDeclSpec().getNoreturnSpecLoc(),
-                                       Context));
+                                       Context, 0));
 
   // Functions returning a variably modified type violate C99 6.7.5.2p2
   // because all functions have linkage.
   if (!NewFD->isInvalidDecl() &&
-      NewFD->getResultType()->isVariablyModifiedType()) {
+      NewFD->getReturnType()->isVariablyModifiedType()) {
     Diag(NewFD->getLocation(), diag::err_vm_func_decl);
     NewFD->setInvalidDecl();
   }
 
+  if (D.isFunctionDefinition() && CodeSegStack.CurrentValue &&
+      !NewFD->hasAttr<SectionAttr>()) {
+    NewFD->addAttr(
+        SectionAttr::CreateImplicit(Context, SectionAttr::Declspec_allocate,
+                                    CodeSegStack.CurrentValue->getString(),
+                                    CodeSegStack.CurrentPragmaLocation));
+    if (UnifySection(CodeSegStack.CurrentValue->getString(),
+                     PSF_Implicit | PSF_Execute | PSF_Read, NewFD))
+      NewFD->dropAttr<SectionAttr>();
+  }
+
   // Handle attributes.
   ProcessDeclAttributes(S, NewFD, D);
 
-  QualType RetType = NewFD->getResultType();
+  QualType RetType = NewFD->getReturnType();
   const CXXRecordDecl *Ret = RetType->isRecordType() ?
       RetType->getAsCXXRecordDecl() : RetType->getPointeeCXXRecordDecl();
   if (!NewFD->isInvalidDecl() && !NewFD->hasAttr<WarnUnusedResultAttr>() &&
       Ret && Ret->hasAttr<WarnUnusedResultAttr>()) {
     const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewFD);
-    // Attach the attribute to the new decl. Don't apply the attribute if it
-    // returns an instance of the class (e.g. assignment operators).
-    if (!MD || MD->getParent() != Ret) {
-      NewFD->addAttr(new (Context) WarnUnusedResultAttr(SourceRange(),
-                                                        Context));
+    // Attach WarnUnusedResult to functions returning types with that attribute.
+    // Don't apply the attribute to that type's own non-static member functions
+    // (to avoid warning on things like assignment operators)
+    if (!MD || MD->getParent() != Ret)
+      NewFD->addAttr(WarnUnusedResultAttr::CreateImplicit(Context));
+  }
+
+  if (getLangOpts().OpenCL) {
+    // OpenCL v1.1 s6.5: Using an address space qualifier in a function return
+    // type declaration will generate a compilation error.
+    unsigned AddressSpace = RetType.getAddressSpace();
+    if (AddressSpace == LangAS::opencl_local ||
+        AddressSpace == LangAS::opencl_global ||
+        AddressSpace == LangAS::opencl_constant) {
+      Diag(NewFD->getLocation(),
+           diag::err_opencl_return_value_with_address_space);
+      NewFD->setInvalidDecl();
     }
   }
 
@@ -7041,21 +7319,10 @@
           << SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc);
 
         HasExplicitTemplateArgs = false;
-      } else if (!isFunctionTemplateSpecialization && 
-                 !D.getDeclSpec().isFriendSpecified()) {
-        // We have encountered something that the user meant to be a 
-        // specialization (because it has explicitly-specified template
-        // arguments) but that was not introduced with a "template<>" (or had
-        // too few of them).
-        // FIXME: Differentiate between attempts for explicit instantiations
-        // (starting with "template") and the rest.
-        Diag(D.getIdentifierLoc(), diag::err_template_spec_needs_header)
-          << SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc)
-          << FixItHint::CreateInsertion(
-                                    D.getDeclSpec().getLocStart(),
-                                        "template<> ");
-        isFunctionTemplateSpecialization = true;
       } else {
+        assert((isFunctionTemplateSpecialization ||
+                D.getDeclSpec().isFriendSpecified()) &&
+               "should have a 'template<>' for this decl");
         // "friend void foo<>(int);" is an implicit specialization decl.
         isFunctionTemplateSpecialization = true;
       }
@@ -7067,7 +7334,7 @@
       //   friend void foo<>(int);
       // Go ahead and fake up a template id.
       HasExplicitTemplateArgs = true;
-        TemplateArgs.setLAngleLoc(D.getIdentifierLoc());
+      TemplateArgs.setLAngleLoc(D.getIdentifierLoc());
       TemplateArgs.setRAngleLoc(D.getIdentifierLoc());
     }
 
@@ -7095,7 +7362,8 @@
           diag::err_function_specialization_in_class)
           << NewFD->getDeclName();
       } else if (CheckFunctionTemplateSpecialization(NewFD,
-                                  (HasExplicitTemplateArgs ? &TemplateArgs : 0),
+                                  (HasExplicitTemplateArgs ? &TemplateArgs
+                                                           : nullptr),
                                                      Previous))
         NewFD->setInvalidDecl();
       
@@ -7132,12 +7400,7 @@
       if (!NewFD->isInvalidDecl() && NewFD->isMSVCRTEntryPoint())
         CheckMSVCRTEntryPoint(NewFD);
 
-      if (NewFD->isInvalidDecl()) {
-        // If this is a class member, mark the class invalid immediately.
-        // This avoids some consistency errors later.
-        if (CXXMethodDecl* methodDecl = dyn_cast<CXXMethodDecl>(NewFD))
-          methodDecl->getParent()->setInvalidDecl();
-      } else
+      if (!NewFD->isInvalidDecl())
         D.setRedeclaration(CheckFunctionDeclaration(S, NewFD, Previous,
                                                     isExplicitSpecialization));
     }
@@ -7169,7 +7432,8 @@
       FunctionTemplateDecl *PrevTemplate = 
                                      FunctionTemplate->getPreviousDecl();
       CheckTemplateParameterList(FunctionTemplate->getTemplateParameters(),
-                       PrevTemplate ? PrevTemplate->getTemplateParameters() : 0,
+                       PrevTemplate ? PrevTemplate->getTemplateParameters()
+                                    : nullptr,
                             D.getDeclSpec().isFriendSpecified()
                               ? (D.isFunctionDefinition()
                                    ? TPC_FriendFunctionTemplateDefinition
@@ -7223,7 +7487,7 @@
           // whether the parameter types are references).
 
           if (NamedDecl *Result = DiagnoseInvalidRedeclaration(
-                  *this, Previous, NewFD, ExtraArgs, false, 0)) {
+                  *this, Previous, NewFD, ExtraArgs, false, nullptr)) {
             AddToScope = ExtraArgs.AddToScope;
             return Result;
           }
@@ -7239,11 +7503,12 @@
         }
       }
 
-    } else if (!D.isFunctionDefinition() && D.getCXXScopeSpec().isSet() &&
+    } else if (!D.isFunctionDefinition() &&
+               isa<CXXMethodDecl>(NewFD) && NewFD->isOutOfLine() &&
                !isFriend && !isFunctionTemplateSpecialization &&
                !isExplicitSpecialization) {
       // An out-of-line member function declaration must also be a
-      // definition (C++ [dcl.meaning]p1).
+      // definition (C++ [class.mfct]p2).
       // Note that this is not the case for explicit specializations of
       // function templates or member functions of class templates, per
       // C++ [temp.expl.spec]p2. We also allow these declarations as an 
@@ -7272,7 +7537,7 @@
     EPI.Variadic = true;
     EPI.ExtInfo = FT->getExtInfo();
 
-    QualType R = Context.getFunctionType(FT->getResultType(), None, EPI);
+    QualType R = Context.getFunctionType(FT->getReturnType(), None, EPI);
     NewFD->setType(R);
   }
 
@@ -7285,6 +7550,11 @@
   // marking the function.
   AddCFAuditedAttribute(NewFD);
 
+  // If this is a function definition, check if we have to apply optnone due to
+  // a pragma.
+  if(D.isFunctionDefinition())
+    AddRangeBasedOptnone(NewFD);
+
   // If this is the first declaration of an extern C variable, update
   // the map of such variables.
   if (NewFD->isFirstDecl() && !NewFD->isInvalidDecl() &&
@@ -7294,6 +7564,12 @@
   // Set this FunctionDecl's range up to the right paren.
   NewFD->setRangeEnd(D.getSourceRange().getEnd());
 
+  if (D.isRedeclaration() && !Previous.empty()) {
+    checkDLLAttributeRedeclaration(
+        *this, dyn_cast<NamedDecl>(Previous.getRepresentativeDecl()), NewFD,
+        isExplicitSpecialization || isFunctionTemplateSpecialization);
+  }
+
   if (getLangOpts().CPlusPlus) {
     if (FunctionTemplate) {
       if (NewFD->isInvalidDecl())
@@ -7311,18 +7587,17 @@
     }
     
     // OpenCL v1.2, s6.9 -- Kernels can only have return type void.
-    if (!NewFD->getResultType()->isVoidType()) {
-      Diag(D.getIdentifierLoc(),
-           diag::err_expected_kernel_void_return_type);
+    if (!NewFD->getReturnType()->isVoidType()) {
+      SourceRange RTRange = NewFD->getReturnTypeSourceRange();
+      Diag(D.getIdentifierLoc(), diag::err_expected_kernel_void_return_type)
+          << (RTRange.isValid() ? FixItHint::CreateReplacement(RTRange, "void")
+                                : FixItHint());
       D.setInvalidType();
     }
 
     llvm::SmallPtrSet<const Type *, 16> ValidTypes;
-    for (FunctionDecl::param_iterator PI = NewFD->param_begin(),
-         PE = NewFD->param_end(); PI != PE; ++PI) {
-      ParmVarDecl *Param = *PI;
+    for (auto Param : NewFD->params())
       checkIsValidOpenCLKernelParameter(*this, D, Param, ValidTypes);
-    }
   }
 
   MarkUnusedFileScopedDecl(NewFD);
@@ -7332,7 +7607,7 @@
       if (!NewFD->isInvalidDecl() &&
           NewFD->getDeclContext()->getRedeclContext()->isTranslationUnit()) {
         if (II->isStr("cudaConfigureCall")) {
-          if (!R->getAs<FunctionType>()->getResultType()->isScalarType())
+          if (!R->getAs<FunctionType>()->getReturnType()->isScalarType())
             Diag(NewFD->getLocation(), diag::err_config_scalar_return);
 
           Context.setcudaConfigureCallDecl(NewFD);
@@ -7374,8 +7649,8 @@
 bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
                                     LookupResult &Previous,
                                     bool IsExplicitSpecialization) {
-  assert(!NewFD->getResultType()->isVariablyModifiedType() 
-         && "Variably modified return types are not handled here");
+  assert(!NewFD->getReturnType()->isVariablyModifiedType() &&
+         "Variably modified return types are not handled here");
 
   // Determine whether the type of this function should be merged with
   // a previous visible declaration. This never happens for functions in C++,
@@ -7387,7 +7662,7 @@
   filterNonConflictingPreviousDecls(Context, NewFD, Previous);
 
   bool Redeclaration = false;
-  NamedDecl *OldDecl = 0;
+  NamedDecl *OldDecl = nullptr;
 
   // Merge or overload the declaration with an existing declaration of
   // the same name, if appropriate.
@@ -7423,7 +7698,7 @@
         // with that name must be marked "overloadable".
         Diag(NewFD->getLocation(), diag::err_attribute_overloadable_missing)
           << Redeclaration << NewFD;
-        NamedDecl *OverloadedDecl = 0;
+        NamedDecl *OverloadedDecl = nullptr;
         if (Redeclaration)
           OverloadedDecl = OldDecl;
         else if (!Previous.empty())
@@ -7431,8 +7706,7 @@
         if (OverloadedDecl)
           Diag(OverloadedDecl->getLocation(),
                diag::note_attribute_overloadable_prev_overload);
-        NewFD->addAttr(::new (Context) OverloadableAttr(SourceLocation(),
-                                                        Context));
+        NewFD->addAttr(OverloadableAttr::CreateImplicit(Context));
       }
     }
   }
@@ -7455,12 +7729,11 @@
             << Redeclaration << NewFD;
           Diag(Previous.getFoundDecl()->getLocation(),
                diag::note_attribute_overloadable_prev_overload);
-          NewFD->addAttr(::new (Context) OverloadableAttr(SourceLocation(),
-                                                          Context));
+          NewFD->addAttr(OverloadableAttr::CreateImplicit(Context));
         }
         if (IsOverload(NewFD, cast<FunctionDecl>(OldDecl), false)) {
           Redeclaration = false;
-          OldDecl = 0;
+          OldDecl = nullptr;
         }
       }
     }
@@ -7479,17 +7752,16 @@
   if (!getLangOpts().CPlusPlus1y && MD && MD->isConstexpr() &&
       !MD->isStatic() && !isa<CXXConstructorDecl>(MD) &&
       (MD->getTypeQualifiers() & Qualifiers::Const) == 0) {
-    CXXMethodDecl *OldMD = dyn_cast_or_null<CXXMethodDecl>(OldDecl);
-    if (FunctionTemplateDecl *OldTD =
-          dyn_cast_or_null<FunctionTemplateDecl>(OldDecl))
-      OldMD = dyn_cast<CXXMethodDecl>(OldTD->getTemplatedDecl());
+    CXXMethodDecl *OldMD = nullptr;
+    if (OldDecl)
+      OldMD = dyn_cast<CXXMethodDecl>(OldDecl->getAsFunction());
     if (!OldMD || !OldMD->isStatic()) {
       const FunctionProtoType *FPT =
         MD->getType()->castAs<FunctionProtoType>();
       FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
       EPI.TypeQuals |= Qualifiers::Const;
-      MD->setType(Context.getFunctionType(FPT->getResultType(),
-                                          FPT->getArgTypes(), EPI));
+      MD->setType(Context.getFunctionType(FPT->getReturnType(),
+                                          FPT->getParamTypes(), EPI));
 
       // 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.
@@ -7497,7 +7769,7 @@
         SourceLocation AddConstLoc;
         if (FunctionTypeLoc FTL = MD->getTypeSourceInfo()->getTypeLoc()
                 .IgnoreParens().getAs<FunctionTypeLoc>())
-          AddConstLoc = PP.getLocForEndOfToken(FTL.getRParenLoc());
+          AddConstLoc = getLocForEndOfToken(FTL.getRParenLoc());
 
         Diag(MD->getLocation(), diag::warn_cxx1y_compat_constexpr_not_const)
           << FixItHint::CreateInsertion(AddConstLoc, " const");
@@ -7647,7 +7919,7 @@
     // compatible, and if it does, warn the user.
     // But, issue any diagnostic on the first declaration only.
     if (NewFD->isExternC() && Previous.empty()) {
-      QualType R = NewFD->getResultType();
+      QualType R = NewFD->getReturnType();
       if (R->isIncompleteType() && !R->isVoidType())
         Diag(NewFD->getLocation(), diag::warn_return_value_udt_incomplete)
             << NewFD << R;
@@ -7659,26 +7931,10 @@
   return Redeclaration;
 }
 
-static SourceRange getResultSourceRange(const FunctionDecl *FD) {
-  const TypeSourceInfo *TSI = FD->getTypeSourceInfo();
-  if (!TSI)
-    return SourceRange();
-
-  TypeLoc TL = TSI->getTypeLoc();
-  FunctionTypeLoc FunctionTL = TL.getAs<FunctionTypeLoc>();
-  if (!FunctionTL)
-    return SourceRange();
-
-  TypeLoc ResultTL = FunctionTL.getResultLoc();
-  if (ResultTL.getUnqualifiedLoc().getAs<BuiltinTypeLoc>())
-    return ResultTL.getSourceRange();
-
-  return SourceRange();
-}
-
 void Sema::CheckMain(FunctionDecl* FD, const DeclSpec& DS) {
-  // C++11 [basic.start.main]p3:  A program that declares main to be inline,
-  //   static or constexpr is ill-formed.
+  // C++11 [basic.start.main]p3:
+  //   A program that [...] declares main to be inline, static or
+  //   constexpr is ill-formed.
   // C11 6.7.4p4:  In a hosted environment, no function specifier(s) shall
   //   appear in a declaration of main.
   // static main is not an error under C99, but we should warn about it.
@@ -7692,8 +7948,7 @@
       << FixItHint::CreateRemoval(DS.getInlineSpecLoc());
   if (DS.isNoreturnSpecified()) {
     SourceLocation NoreturnLoc = DS.getNoreturnSpecLoc();
-    SourceRange NoreturnRange(NoreturnLoc,
-                              PP.getLocForEndOfToken(NoreturnLoc));
+    SourceRange NoreturnRange(NoreturnLoc, getLocForEndOfToken(NoreturnLoc));
     Diag(NoreturnLoc, diag::ext_noreturn_main);
     Diag(NoreturnLoc, diag::note_main_remove_noreturn)
       << FixItHint::CreateRemoval(NoreturnRange);
@@ -7715,41 +7970,44 @@
   assert(T->isFunctionType() && "function decl is not of function type");
   const FunctionType* FT = T->castAs<FunctionType>();
 
-  // All the standards say that main() should should return 'int'.
-  if (Context.hasSameUnqualifiedType(FT->getResultType(), Context.IntTy)) {
+  if (getLangOpts().GNUMode && !getLangOpts().CPlusPlus) {
+    // In C with GNU extensions we allow main() to have non-integer return
+    // type, but we should warn about the extension, and we disable the
+    // implicit-return-zero rule.
+
+    // GCC in C mode accepts qualified 'int'.
+    if (Context.hasSameUnqualifiedType(FT->getReturnType(), Context.IntTy))
+      FD->setHasImplicitReturnZero(true);
+    else {
+      Diag(FD->getTypeSpecStartLoc(), diag::ext_main_returns_nonint);
+      SourceRange RTRange = FD->getReturnTypeSourceRange();
+      if (RTRange.isValid())
+        Diag(RTRange.getBegin(), diag::note_main_change_return_type)
+            << FixItHint::CreateReplacement(RTRange, "int");
+    }
+  } else {
     // In C and C++, main magically returns 0 if you fall off the end;
     // set the flag which tells us that.
     // This is C++ [basic.start.main]p5 and C99 5.1.2.2.3.
-    FD->setHasImplicitReturnZero(true);
 
-  // In C with GNU extensions we allow main() to have non-integer return
-  // type, but we should warn about the extension, and we disable the
-  // implicit-return-zero rule.
-  } else if (getLangOpts().GNUMode && !getLangOpts().CPlusPlus) {
-    Diag(FD->getTypeSpecStartLoc(), diag::ext_main_returns_nonint);
-
-    SourceRange ResultRange = getResultSourceRange(FD);
-    if (ResultRange.isValid())
-      Diag(ResultRange.getBegin(), diag::note_main_change_return_type)
-          << FixItHint::CreateReplacement(ResultRange, "int");
-
-  // Otherwise, this is just a flat-out error.
-  } else {
-    SourceRange ResultRange = getResultSourceRange(FD);
-    if (ResultRange.isValid())
+    // All the standards say that main() should return 'int'.
+    if (Context.hasSameType(FT->getReturnType(), Context.IntTy))
+      FD->setHasImplicitReturnZero(true);
+    else {
+      // Otherwise, this is just a flat-out error.
+      SourceRange RTRange = FD->getReturnTypeSourceRange();
       Diag(FD->getTypeSpecStartLoc(), diag::err_main_returns_nonint)
-          << FixItHint::CreateReplacement(ResultRange, "int");
-    else
-      Diag(FD->getTypeSpecStartLoc(), diag::err_main_returns_nonint);
-
-    FD->setInvalidDecl(true);
+          << (RTRange.isValid() ? FixItHint::CreateReplacement(RTRange, "int")
+                                : FixItHint());
+      FD->setInvalidDecl(true);
+    }
   }
 
   // Treat protoless main() as nullary.
   if (isa<FunctionNoProtoType>(FT)) return;
 
   const FunctionProtoType* FTP = cast<const FunctionProtoType>(FT);
-  unsigned nparams = FTP->getNumArgs();
+  unsigned nparams = FTP->getNumParams();
   assert(FD->getNumParams() == nparams);
 
   bool HasExtraParameters = (nparams > 3);
@@ -7774,7 +8032,7 @@
   QualType Expected[] = { Context.IntTy, CharPP, CharPP, CharPP };
 
   for (unsigned i = 0; i < nparams; ++i) {
-    QualType AT = FTP->getArgType(i);
+    QualType AT = FTP->getParamType(i);
 
     bool mismatch = true;
 
@@ -7809,7 +8067,7 @@
   }
   
   if (!FD->isInvalidDecl() && FD->getDescribedFunctionTemplate()) {
-    Diag(FD->getLocation(), diag::err_mainlike_template_decl) << FD->getName();
+    Diag(FD->getLocation(), diag::err_mainlike_template_decl) << FD;
     FD->setInvalidDecl();
   }
 }
@@ -7821,15 +8079,15 @@
 
   // Set an implicit return of 'zero' if the function can return some integral,
   // enumeration, pointer or nullptr type.
-  if (FT->getResultType()->isIntegralOrEnumerationType() ||
-      FT->getResultType()->isAnyPointerType() ||
-      FT->getResultType()->isNullPtrType())
+  if (FT->getReturnType()->isIntegralOrEnumerationType() ||
+      FT->getReturnType()->isAnyPointerType() ||
+      FT->getReturnType()->isNullPtrType())
     // DllMain is exempt because a return value of zero means it failed.
     if (FD->getName() != "DllMain")
       FD->setHasImplicitReturnZero(true);
 
   if (!FD->isInvalidDecl() && FD->getDescribedFunctionTemplate()) {
-    Diag(FD->getLocation(), diag::err_mainlike_template_decl) << FD->getName();
+    Diag(FD->getLocation(), diag::err_mainlike_template_decl) << FD;
     FD->setInvalidDecl();
   }
 }
@@ -7843,10 +8101,11 @@
   // "may accept other forms of constant expressions" exception.
   // (We never end up here for C++, so the constant expression
   // rules there don't matter.)
-  if (Init->isConstantInitializer(Context, false))
+  const Expr *Culprit;
+  if (Init->isConstantInitializer(Context, false, &Culprit))
     return false;
-  Diag(Init->getExprLoc(), diag::err_init_element_not_constant)
-    << Init->getSourceRange();
+  Diag(Culprit->getExprLoc(), diag::err_init_element_not_constant)
+    << Culprit->getSourceRange();
   return true;
 }
 
@@ -8020,7 +8279,7 @@
                                 bool DirectInit, bool TypeMayContainAuto) {
   // If there is no declaration, there was an error parsing it.  Just ignore
   // the initializer.
-  if (RealDecl == 0 || RealDecl->isInvalidDecl())
+  if (!RealDecl || RealDecl->isInvalidDecl())
     return;
 
   if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(RealDecl)) {
@@ -8075,6 +8334,11 @@
         return;
       } else {
         DeduceInit = CXXDirectInit->getExpr(0);
+        if (isa<InitListExpr>(DeduceInit))
+          Diag(CXXDirectInit->getLocStart(),
+               diag::err_auto_var_init_paren_braces)
+            << VDecl->getDeclName() << VDecl->getType()
+            << VDecl->getSourceRange();
       }
     }
 
@@ -8087,7 +8351,7 @@
         VDecl->setInvalidDecl();
         return;
       }
-      Init = Result.take();
+      Init = Result.get();
       DefaultedToAuto = true;
     }
 
@@ -8132,6 +8396,13 @@
       return;
   }
 
+  // dllimport cannot be used on variable definitions.
+  if (VDecl->hasAttr<DLLImportAttr>() && !VDecl->isStaticDataMember()) {
+    Diag(VDecl->getLocation(), diag::err_attribute_dllimport_data_definition);
+    VDecl->setInvalidDecl();
+    return;
+  }
+
   if (VDecl->isLocalVarDecl() && VDecl->hasExternalStorage()) {
     // C99 6.7.8p5. C++ has no such restriction, but that is a defect.
     Diag(VDecl->getLocation(), diag::err_block_extern_cant_init);
@@ -8167,8 +8438,8 @@
     VDecl->setInvalidDecl();
     return;
   }
-  
-  const VarDecl* PrevInit = 0;
+
+  const VarDecl *PrevInit = nullptr;
   if (getLangOpts().CPlusPlus) {
     // C++ [class.static.data]p4
     //   If a static data member is of const integral or const
@@ -8183,9 +8454,9 @@
     // data members we also need to check whether there was an in-class
     // declaration with an initializer.
     if (VDecl->isStaticDataMember() && VDecl->getAnyInitializer(PrevInit)) {
-      Diag(VDecl->getLocation(), diag::err_redefinition) 
-        << VDecl->getDeclName();
-      Diag(PrevInit->getLocation(), diag::note_previous_definition);
+      Diag(Init->getExprLoc(), diag::err_static_data_member_reinitialization)
+          << VDecl->getDeclName();
+      Diag(PrevInit->getInit()->getExprLoc(), diag::note_previous_initializer) << 0;
       return;
     }  
 
@@ -8219,7 +8490,7 @@
       VDecl->setInvalidDecl();
       return;
     }
-    Init = Result.take();
+    Init = Result.get();
   }
 
   // Perform the initialization.
@@ -8247,7 +8518,7 @@
       return;
     }
 
-    Init = Result.takeAs<Expr>();
+    Init = Result.getAs<Expr>();
   }
 
   // Check for self-references within variable initializers.
@@ -8278,13 +8549,10 @@
     // we do not warn to warn spuriously when 'x' and 'y' are on separate
     // paths through the function. This should be revisited if
     // -Wrepeated-use-of-weak is made flow-sensitive.
-    if (VDecl->getType().getObjCLifetime() == Qualifiers::OCL_Strong) {
-      DiagnosticsEngine::Level Level =
-        Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak,
-                                 Init->getLocStart());
-      if (Level != DiagnosticsEngine::Ignored)
+    if (VDecl->getType().getObjCLifetime() == Qualifiers::OCL_Strong &&
+        !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak,
+                         Init->getLocStart()))
         getCurFunction()->markSafeWeakUse(Init);
-    }
   }
 
   // The initialization is usually a full-expression.
@@ -8305,7 +8573,7 @@
     VDecl->setInvalidDecl();
     return;
   }
-  Init = Result.take();
+  Init = Result.get();
 
   // Attach the initializer to the decl.
   VDecl->setInit(Init);
@@ -8315,6 +8583,7 @@
     // static storage duration shall be constant expressions or string literals.
     // C++ does not have this restriction.
     if (!getLangOpts().CPlusPlus && !VDecl->isInvalidDecl()) {
+      const Expr *Culprit;
       if (VDecl->getStorageClass() == SC_Static)
         CheckForConstantInitializer(Init, DclT);
       // C89 is stricter than C99 for non-static aggregate types.
@@ -8323,10 +8592,10 @@
       // constant expressions.
       else if (!getLangOpts().C99 && VDecl->getType()->isAggregateType() &&
                isa<InitListExpr>(Init) &&
-               !Init->isConstantInitializer(Context, false))
-        Diag(Init->getExprLoc(),
+               !Init->isConstantInitializer(Context, false, &Culprit))
+        Diag(Culprit->getExprLoc(),
              diag::ext_aggregate_init_not_constant)
-          << Init->getSourceRange();
+          << Culprit->getSourceRange();
     }
   } else if (VDecl->isStaticDataMember() &&
              VDecl->getLexicalDeclContext()->isRecord()) {
@@ -8435,19 +8704,6 @@
     // C99 6.7.8p4. All file scoped initializers need to be constant.
     if (!getLangOpts().CPlusPlus && !VDecl->isInvalidDecl())
       CheckForConstantInitializer(Init, DclT);
-    else if (VDecl->getTLSKind() == VarDecl::TLS_Static &&
-             !VDecl->isInvalidDecl() && !DclT->isDependentType() &&
-             !Init->isValueDependent() && !VDecl->isConstexpr() &&
-             !Init->isConstantInitializer(
-                 Context, VDecl->getType()->isReferenceType())) {
-      // GNU C++98 edits for __thread, [basic.start.init]p4:
-      //   An object of thread storage duration shall not require dynamic
-      //   initialization.
-      // FIXME: Need strict checking here.
-      Diag(VDecl->getLocation(), diag::err_thread_dynamic_init);
-      if (getLangOpts().CPlusPlus11)
-        Diag(VDecl->getLocation(), diag::note_use_thread_local);
-    }
   }
 
   // We will represent direct-initialization similarly to copy-initialization:
@@ -8503,7 +8759,7 @@
     return;
   }
 
-  // Require an abstract type.
+  // Require a non-abstract type.
   if (RequireNonAbstractType(VD->getLocation(), Ty,
                              diag::err_abstract_type_in_decl,
                              AbstractVariableType)) {
@@ -8518,7 +8774,7 @@
 void Sema::ActOnUninitializedDecl(Decl *RealDecl,
                                   bool TypeMayContainAuto) {
   // If there is no declaration, there was an error parsing it. Just ignore it.
-  if (RealDecl == 0)
+  if (!RealDecl)
     return;
 
   if (VarDecl *Var = dyn_cast<VarDecl>(RealDecl)) {
@@ -8549,6 +8805,16 @@
       return;
     }
 
+    // OpenCL v1.1 s6.5.3: variables declared in the constant address space must
+    // be initialized.
+    if (!Var->isInvalidDecl() &&
+        Var->getType().getAddressSpace() == LangAS::opencl_constant &&
+        Var->getStorageClass() != SC_Extern && !Var->getInit()) {
+      Diag(Var->getLocation(), diag::err_opencl_constant_no_init);
+      Var->setInvalidDecl();
+      return;
+    }
+
     switch (Var->isThisDeclarationADefinition()) {
     case VarDecl::Definition:
       if (!Var->isStaticDataMember() || !Var->getAnyInitializer())
@@ -8648,11 +8914,13 @@
     if (Var->isInvalidDecl())
       return;
 
-    if (RequireCompleteType(Var->getLocation(), 
-                            Context.getBaseElementType(Type),
-                            diag::err_typecheck_decl_incomplete_type)) {
-      Var->setInvalidDecl();
-      return;
+    if (!Var->hasAttr<AliasAttr>()) {
+      if (RequireCompleteType(Var->getLocation(),
+                              Context.getBaseElementType(Type),
+                              diag::err_typecheck_decl_incomplete_type)) {
+        Var->setInvalidDecl();
+        return;
+      }
     }
 
     // The variable can not have an abstract class type.
@@ -8759,6 +9027,37 @@
   }
 }
 
+StmtResult
+Sema::ActOnCXXForRangeIdentifier(Scope *S, SourceLocation IdentLoc,
+                                 IdentifierInfo *Ident,
+                                 ParsedAttributes &Attrs,
+                                 SourceLocation AttrEnd) {
+  // C++1y [stmt.iter]p1:
+  //   A range-based for statement of the form
+  //      for ( for-range-identifier : for-range-initializer ) statement
+  //   is equivalent to
+  //      for ( auto&& for-range-identifier : for-range-initializer ) statement
+  DeclSpec DS(Attrs.getPool().getFactory());
+
+  const char *PrevSpec;
+  unsigned DiagID;
+  DS.SetTypeSpecType(DeclSpec::TST_auto, IdentLoc, PrevSpec, DiagID,
+                     getPrintingPolicy());
+
+  Declarator D(DS, Declarator::ForContext);
+  D.SetIdentifier(Ident, IdentLoc);
+  D.takeAttributes(Attrs, AttrEnd);
+
+  ParsedAttributes EmptyAttrs(Attrs.getPool().getFactory());
+  D.AddTypeInfo(DeclaratorChunk::getReference(0, IdentLoc, /*lvalue*/false),
+                EmptyAttrs, IdentLoc);
+  Decl *Var = ActOnDeclarator(S, D);
+  cast<VarDecl>(Var)->setCXXForRangeDecl(true);
+  FinalizeDeclaration(Var);
+  return ActOnDeclStmt(FinalizeDeclaratorGroup(S, DS, Var), IdentLoc,
+                       AttrEnd.isValid() ? AttrEnd : IdentLoc);
+}
+
 void Sema::CheckCompleteVariableDeclaration(VarDecl *var) {
   if (var->isInvalidDecl()) return;
 
@@ -8779,11 +9078,16 @@
     }
   }
 
+  // Warn about externally-visible variables being defined without a
+  // prior declaration.  We only want to do this for global
+  // declarations, but we also specifically need to avoid doing it for
+  // class members because the linkage of an anonymous class can
+  // change if it's later given a typedef name.
   if (var->isThisDeclarationADefinition() &&
+      var->getDeclContext()->getRedeclContext()->isFileContext() &&
       var->isExternallyVisible() && var->hasLinkage() &&
-      getDiagnostics().getDiagnosticLevel(
-                       diag::warn_missing_variable_declarations,
-                       var->getLocation())) {
+      !getDiagnostics().isIgnored(diag::warn_missing_variable_declarations,
+                                  var->getLocation())) {
     // Find a previous declaration that's not a definition.
     VarDecl *prev = var->getPreviousDecl();
     while (prev && prev->isThisDeclarationADefinition())
@@ -8793,14 +9097,58 @@
       Diag(var->getLocation(), diag::warn_missing_variable_declarations) << var;
   }
 
-  if (var->getTLSKind() == VarDecl::TLS_Static &&
-      var->getType().isDestructedType()) {
-    // GNU C++98 edits for __thread, [basic.start.term]p3:
-    //   The type of an object with thread storage duration shall not
-    //   have a non-trivial destructor.
-    Diag(var->getLocation(), diag::err_thread_nontrivial_dtor);
-    if (getLangOpts().CPlusPlus11)
-      Diag(var->getLocation(), diag::note_use_thread_local);
+  if (var->getTLSKind() == VarDecl::TLS_Static) {
+    const Expr *Culprit;
+    if (var->getType().isDestructedType()) {
+      // GNU C++98 edits for __thread, [basic.start.term]p3:
+      //   The type of an object with thread storage duration shall not
+      //   have a non-trivial destructor.
+      Diag(var->getLocation(), diag::err_thread_nontrivial_dtor);
+      if (getLangOpts().CPlusPlus11)
+        Diag(var->getLocation(), diag::note_use_thread_local);
+    } else if (getLangOpts().CPlusPlus && var->hasInit() &&
+               !var->getInit()->isConstantInitializer(
+                   Context, var->getType()->isReferenceType(), &Culprit)) {
+      // GNU C++98 edits for __thread, [basic.start.init]p4:
+      //   An object of thread storage duration shall not require dynamic
+      //   initialization.
+      // FIXME: Need strict checking here.
+      Diag(Culprit->getExprLoc(), diag::err_thread_dynamic_init)
+        << Culprit->getSourceRange();
+      if (getLangOpts().CPlusPlus11)
+        Diag(var->getLocation(), diag::note_use_thread_local);
+    }
+
+  }
+
+  if (var->isThisDeclarationADefinition() &&
+      ActiveTemplateInstantiations.empty()) {
+    PragmaStack<StringLiteral *> *Stack = nullptr;
+    int SectionFlags = PSF_Implicit | PSF_Read;
+    if (var->getType().isConstQualified())
+      Stack = &ConstSegStack;
+    else if (!var->getInit()) {
+      Stack = &BSSSegStack;
+      SectionFlags |= PSF_Write;
+    } else {
+      Stack = &DataSegStack;
+      SectionFlags |= PSF_Write;
+    }
+    if (!var->hasAttr<SectionAttr>() && Stack->CurrentValue)
+      var->addAttr(
+          SectionAttr::CreateImplicit(Context, SectionAttr::Declspec_allocate,
+                                      Stack->CurrentValue->getString(),
+                                      Stack->CurrentPragmaLocation));
+    if (const SectionAttr *SA = var->getAttr<SectionAttr>())
+      if (UnifySection(SA->getName(), SectionFlags, var))
+        var->dropAttr<SectionAttr>();
+
+    // Apply the init_seg attribute if this has an initializer.  If the
+    // initializer turns out to not be dynamic, we'll end up ignoring this
+    // attribute.
+    if (CurInitSeg && var->getInit())
+      var->addAttr(InitSegAttr::CreateImplicit(Context, CurInitSeg->getString(),
+                                               CurInitSegLoc));
   }
 
   // All the following checks are C++ only.
@@ -8826,7 +9174,7 @@
             var, var->getType(), varRef, /*AllowNRVO=*/true);
       if (!result.isInvalid()) {
         result = MaybeCreateExprWithCleanups(result);
-        Expr *init = result.takeAs<Expr>();
+        Expr *init = result.getAs<Expr>();
         Context.setBlockVarCopyInits(var, init);
       }
     }
@@ -8839,9 +9187,8 @@
   if (!var->getDeclContext()->isDependentContext() &&
       Init && !Init->isValueDependent()) {
     if (IsGlobal && !var->isConstexpr() &&
-        getDiagnostics().getDiagnosticLevel(diag::warn_global_constructor,
-                                            var->getLocation())
-          != DiagnosticsEngine::Ignored) {
+        !getDiagnostics().isIgnored(diag::warn_global_constructor,
+                                    var->getLocation())) {
       // Warn about globals which don't have a constant initializer.  Don't
       // warn about globals with a non-trivial destructor because we already
       // warned about them.
@@ -8892,9 +9239,45 @@
   if (!VD)
     return;
 
+  checkAttributesAfterMerging(*this, *VD);
+
+  // Static locals inherit dll attributes from their function.
+  if (VD->isStaticLocal()) {
+    if (FunctionDecl *FD =
+            dyn_cast<FunctionDecl>(VD->getParentFunctionOrMethod())) {
+      if (Attr *A = getDLLAttr(FD)) {
+        auto *NewAttr = cast<InheritableAttr>(A->clone(getASTContext()));
+        NewAttr->setInherited(true);
+        VD->addAttr(NewAttr);
+      }
+    }
+  }
+
+  // Imported static data members cannot be defined out-of-line.
+  if (const DLLImportAttr *IA = VD->getAttr<DLLImportAttr>()) {
+    if (VD->isStaticDataMember() && VD->isOutOfLine() &&
+        VD->isThisDeclarationADefinition()) {
+      // We allow definitions of dllimport class template static data members
+      // with a warning.
+      CXXRecordDecl *Context =
+        cast<CXXRecordDecl>(VD->getFirstDecl()->getDeclContext());
+      bool IsClassTemplateMember =
+          isa<ClassTemplatePartialSpecializationDecl>(Context) ||
+          Context->getDescribedClassTemplate();
+
+      Diag(VD->getLocation(),
+           IsClassTemplateMember
+               ? diag::warn_attribute_dllimport_static_field_definition
+               : diag::err_attribute_dllimport_static_field_definition);
+      Diag(IA->getLocation(), diag::note_attribute);
+      if (!IsClassTemplateMember)
+        VD->setInvalidDecl();
+    }
+  }
+
   if (UsedAttr *Attr = VD->getAttr<UsedAttr>()) {
     if (!Attr->isInherited() && !VD->isThisDeclarationADefinition()) {
-      Diag(Attr->getLocation(), diag::warn_attribute_ignored) << "used";
+      Diag(Attr->getLocation(), diag::warn_attribute_ignored) << Attr;
       VD->dropAttr<UsedAttr>();
     }
   }
@@ -8914,10 +9297,12 @@
   const DeclContext *DC = VD->getDeclContext();
   // If there's a #pragma GCC visibility in scope, and this isn't a class
   // member, set the visibility of this variable.
-  if (!DC->isRecord() && VD->isExternallyVisible())
+  if (DC->getRedeclContext()->isFileContext() && VD->isExternallyVisible())
     AddPushedVisibilityAttribute(VD);
 
-  if (VD->isFileVarDecl())
+  // FIXME: Warn on unused templates.
+  if (VD->isFileVarDecl() && !VD->getDescribedVarTemplate() &&
+      !isa<VarTemplatePartialSpecializationDecl>(VD))
     MarkUnusedFileScopedDecl(VD);
 
   // Now we have parsed the initializer and can update the table of magic
@@ -8926,10 +9311,7 @@
       !VD->getType()->isIntegralOrEnumerationType())
     return;
 
-  for (specific_attr_iterator<TypeTagForDatatypeAttr>
-         I = ThisDecl->specific_attr_begin<TypeTagForDatatypeAttr>(),
-         E = ThisDecl->specific_attr_end<TypeTagForDatatypeAttr>();
-       I != E; ++I) {
+  for (const auto *I : ThisDecl->specific_attrs<TypeTagForDatatypeAttr>()) {
     const Expr *MagicValueExpr = VD->getInit();
     if (!MagicValueExpr) {
       continue;
@@ -8963,7 +9345,7 @@
   if (DS.isTypeSpecOwned())
     Decls.push_back(DS.getRepAsDecl());
 
-  DeclaratorDecl *FirstDeclaratorInGroup = 0;
+  DeclaratorDecl *FirstDeclaratorInGroup = nullptr;
   for (unsigned i = 0, e = Group.size(); i != e; ++i)
     if (Decl *D = Group[i]) {
       if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D))
@@ -8974,7 +9356,7 @@
 
   if (DeclSpec::isDeclRep(DS.getTypeSpecType())) {
     if (TagDecl *Tag = dyn_cast_or_null<TagDecl>(DS.getRepAsDecl())) {
-      HandleTagNumbering(*this, Tag);
+      HandleTagNumbering(*this, Tag, S);
       if (!Tag->hasNameForLinkage() && !Tag->hasDeclaratorForAnonDecl())
         Tag->setDeclaratorForAnonDecl(FirstDeclaratorInGroup);
     }
@@ -8986,7 +9368,7 @@
 /// BuildDeclaratorGroup - convert a list of declarations into a declaration
 /// group, performing any necessary semantic checking.
 Sema::DeclGroupPtrTy
-Sema::BuildDeclaratorGroup(llvm::MutableArrayRef<Decl *> Group,
+Sema::BuildDeclaratorGroup(MutableArrayRef<Decl *> Group,
                            bool TypeMayContainAuto) {
   // C++0x [dcl.spec.auto]p7:
   //   If the type deduced for the template parameter U is not the same in each
@@ -8998,7 +9380,7 @@
   if (TypeMayContainAuto && Group.size() > 1) {
     QualType Deduced;
     CanQualType DeducedCanon;
-    VarDecl *DeducedDecl = 0;
+    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();
@@ -9043,9 +9425,7 @@
   if (Group.empty() || !Group[0])
    return;
 
-  if (Diags.getDiagnosticLevel(diag::warn_doc_param_not_found,
-                               Group[0]->getLocation())
-        == DiagnosticsEngine::Ignored)
+  if (Diags.isIgnored(diag::warn_doc_param_not_found, Group[0]->getLocation()))
     return;
 
   if (Group.size() >= 2) {
@@ -9124,12 +9504,12 @@
   }
 
   // Ensure we have a valid name
-  IdentifierInfo *II = 0;
+  IdentifierInfo *II = nullptr;
   if (D.hasName()) {
     II = D.getIdentifier();
     if (!II) {
       Diag(D.getIdentifierLoc(), diag::err_bad_parameter_name)
-        << GetNameForDeclarator(D).getName().getAsString();
+        << GetNameForDeclarator(D).getName();
       D.setInvalidType(true);
     }
   }
@@ -9145,14 +9525,14 @@
         // Maybe we will complain about the shadowed template parameter.
         DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl);
         // Just pretend that we didn't see the previous declaration.
-        PrevDecl = 0;
+        PrevDecl = nullptr;
       } else if (S->isDeclScope(PrevDecl)) {
         Diag(D.getIdentifierLoc(), diag::err_param_redefinition) << II;
         Diag(PrevDecl->getLocation(), diag::note_previous_declaration);
 
         // Recover by removing the name
-        II = 0;
-        D.SetIdentifier(0, D.getIdentifierLoc());
+        II = nullptr;
+        D.SetIdentifier(nullptr, D.getIdentifierLoc());
         D.setInvalidType(true);
       }
     }
@@ -9202,9 +9582,9 @@
   /* FIXME: setting StartLoc == Loc.
      Would it be worth to modify callers so as to provide proper source
      location for the unnamed parameters, embedding the parameter's type? */
-  ParmVarDecl *Param = ParmVarDecl::Create(Context, DC, Loc, Loc, 0,
+  ParmVarDecl *Param = ParmVarDecl::Create(Context, DC, Loc, Loc, nullptr,
                                 T, Context.getTrivialTypeSourceInfo(T, Loc),
-                                           SC_None, 0);
+                                           SC_None, nullptr);
   Param->setImplicit();
   return Param;
 }
@@ -9284,7 +9664,7 @@
   ParmVarDecl *New = ParmVarDecl::Create(Context, DC, StartLoc, NameLoc, Name,
                                          Context.getAdjustedParameterType(T), 
                                          TSInfo,
-                                         StorageClass, 0);
+                                         StorageClass, nullptr);
 
   // Parameters can not be abstract class types.
   // For record types, this is done by the AbstractClassUsageDiagnoser once
@@ -9310,8 +9690,12 @@
   // Since all parameters have automatic store duration, they can not have
   // an address space.
   if (T.getAddressSpace() != 0) {
-    Diag(NameLoc, diag::err_arg_with_address_space);
-    New->setInvalidDecl();
+    // OpenCL allows function arguments declared to be an array of a type
+    // to be qualified with an address space.
+    if (!(getLangOpts().OpenCL && T->isArrayType())) {
+      Diag(NameLoc, diag::err_arg_with_address_space);
+      New->setInvalidDecl();
+    }
   }   
 
   return New;
@@ -9324,16 +9708,15 @@
   // Verify 6.9.1p6: 'every identifier in the identifier list shall be declared'
   // for a K&R function.
   if (!FTI.hasPrototype) {
-    for (int i = FTI.NumArgs; i != 0; /* decrement in loop */) {
+    for (int i = FTI.NumParams; i != 0; /* decrement in loop */) {
       --i;
-      if (FTI.ArgInfo[i].Param == 0) {
+      if (FTI.Params[i].Param == nullptr) {
         SmallString<256> Code;
-        llvm::raw_svector_ostream(Code) << "  int "
-                                        << FTI.ArgInfo[i].Ident->getName()
-                                        << ";\n";
-        Diag(FTI.ArgInfo[i].IdentLoc, diag::ext_param_not_declared)
-          << FTI.ArgInfo[i].Ident
-          << FixItHint::CreateInsertion(LocAfterDecls, Code.str());
+        llvm::raw_svector_ostream(Code)
+            << "  int " << FTI.Params[i].Ident->getName() << ";\n";
+        Diag(FTI.Params[i].IdentLoc, diag::ext_param_not_declared)
+            << FTI.Params[i].Ident
+            << FixItHint::CreateInsertion(LocAfterDecls, Code.str());
 
         // Implicitly declare the argument as type 'int' for lack of a better
         // type.
@@ -9341,21 +9724,21 @@
         DeclSpec DS(attrs);
         const char* PrevSpec; // unused
         unsigned DiagID; // unused
-        DS.SetTypeSpecType(DeclSpec::TST_int, FTI.ArgInfo[i].IdentLoc,
-                           PrevSpec, DiagID);
+        DS.SetTypeSpecType(DeclSpec::TST_int, FTI.Params[i].IdentLoc, PrevSpec,
+                           DiagID, Context.getPrintingPolicy());
         // Use the identifier location for the type source range.
-        DS.SetRangeStart(FTI.ArgInfo[i].IdentLoc);
-        DS.SetRangeEnd(FTI.ArgInfo[i].IdentLoc);
+        DS.SetRangeStart(FTI.Params[i].IdentLoc);
+        DS.SetRangeEnd(FTI.Params[i].IdentLoc);
         Declarator ParamD(DS, Declarator::KNRTypeListContext);
-        ParamD.SetIdentifier(FTI.ArgInfo[i].Ident, FTI.ArgInfo[i].IdentLoc);
-        FTI.ArgInfo[i].Param = ActOnParamDeclarator(S, ParamD);
+        ParamD.SetIdentifier(FTI.Params[i].Ident, FTI.Params[i].IdentLoc);
+        FTI.Params[i].Param = ActOnParamDeclarator(S, ParamD);
       }
     }
   }
 }
 
 Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) {
-  assert(getCurFunctionDecl() == 0 && "Function parsing confused");
+  assert(getCurFunctionDecl() == nullptr && "Function parsing confused");
   assert(D.isFunctionDeclarator() && "Not a function declarator!");
   Scope *ParentScope = FnBodyScope->getParent();
 
@@ -9364,6 +9747,10 @@
   return ActOnStartOfFunctionDef(FnBodyScope, DP);
 }
 
+void Sema::ActOnFinishInlineMethodDef(CXXMethodDecl *D) {
+  Consumer.HandleInlineMethodDefinition(D);
+}
+
 static bool ShouldWarnAboutMissingPrototype(const FunctionDecl *FD, 
                              const FunctionDecl*& PossibleZeroParamPrototype) {
   // Don't warn about invalid declarations.
@@ -9447,7 +9834,7 @@
   LambdaScopeInfo *LSI = S.PushLambdaScope();
   LSI->CallOperator = CallOperator;
   LSI->Lambda = LambdaClass;
-  LSI->ReturnType = CallOperator->getResultType();
+  LSI->ReturnType = CallOperator->getReturnType();
   const LambdaCaptureDefault LCD = LambdaClass->getLambdaCaptureDefault();
 
   if (LCD == LCD_None)
@@ -9463,23 +9850,22 @@
 
   // Add the captures to the LSI so they can be noted as already
   // captured within tryCaptureVar. 
-  for (LambdaExpr::capture_iterator C = LambdaClass->captures_begin(),
-      CEnd = LambdaClass->captures_end(); C != CEnd; ++C) {
-    if (C->capturesVariable()) {
-      VarDecl *VD = C->getCapturedVar();
+  for (const auto &C : LambdaClass->captures()) {
+    if (C.capturesVariable()) {
+      VarDecl *VD = C.getCapturedVar();
       if (VD->isInitCapture())
         S.CurrentInstantiationScope->InstantiatedLocal(VD, VD);
       QualType CaptureType = VD->getType();
-      const bool ByRef = C->getCaptureKind() == LCK_ByRef;
+      const bool ByRef = C.getCaptureKind() == LCK_ByRef;
       LSI->addCapture(VD, /*IsBlock*/false, ByRef, 
-          /*RefersToEnclosingLocal*/true, C->getLocation(),
-          /*EllipsisLoc*/C->isPackExpansion() 
-                         ? C->getEllipsisLoc() : SourceLocation(),
-          CaptureType, /*Expr*/ 0);
-      
-    } else if (C->capturesThis()) {
-      LSI->addThisCapture(/*Nested*/ false, C->getLocation(), 
-                              S.getCurrentThisType(), /*Expr*/ 0);
+          /*RefersToEnclosingLocal*/true, C.getLocation(),
+          /*EllipsisLoc*/C.isPackExpansion() 
+                         ? C.getEllipsisLoc() : SourceLocation(),
+          CaptureType, /*Expr*/ nullptr);
+
+    } else if (C.capturesThis()) {
+      LSI->addThisCapture(/*Nested*/ false, C.getLocation(), 
+                              S.getCurrentThisType(), /*Expr*/ nullptr);
     }
   }
 }
@@ -9490,7 +9876,7 @@
   
   if (!D)
     return D;
-  FunctionDecl *FD = 0;
+  FunctionDecl *FD = nullptr;
 
   if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
     FD = FunTmpl->getTemplatedDecl();
@@ -9530,7 +9916,7 @@
 
   // The return type of a function definition must be complete
   // (C99 6.9.1p3, C++ [dcl.fct]p6).
-  QualType ResultType = FD->getResultType();
+  QualType ResultType = FD->getReturnType();
   if (!ResultType->isDependentType() && !ResultType->isVoidType() &&
       !FD->isInvalidDecl() &&
       RequireCompleteType(FD->getLocation(), ResultType,
@@ -9542,7 +9928,7 @@
   //   prototype declaration. This warning is issued even if the
   //   definition itself provides a prototype. The aim is to detect
   //   global functions that fail to be declared in header files.
-  const FunctionDecl *PossibleZeroParamPrototype = 0;
+  const FunctionDecl *PossibleZeroParamPrototype = nullptr;
   if (ShouldWarnAboutMissingPrototype(FD, PossibleZeroParamPrototype)) {
     Diag(FD->getLocation(), diag::warn_missing_prototype) << FD;
 
@@ -9569,8 +9955,7 @@
                            /*CheckParameterNames=*/true);
 
   // Introduce our parameters into the function scope
-  for (unsigned p = 0, NumParams = FD->getNumParams(); p < NumParams; ++p) {
-    ParmVarDecl *Param = FD->getParamDecl(p);
+  for (auto Param : FD->params()) {
     Param->setOwningFunction(FD);
 
     // If this has an identifier, add it to the scope stack.
@@ -9595,9 +9980,8 @@
       // and reattach to the current context.
       if (D->getLexicalDeclContext() == Context.getTranslationUnitDecl()) {
         // Is the decl actually in the context?
-        for (DeclContext::decl_iterator DI = Context.getTranslationUnitDecl()->decls_begin(),
-               DE = Context.getTranslationUnitDecl()->decls_end(); DI != DE; ++DI) {
-          if (*DI == D) {  
+        for (const auto *DI : Context.getTranslationUnitDecl()->decls()) {
+          if (DI == D) {  
             Context.getTranslationUnitDecl()->removeDecl(D);
             break;
           }
@@ -9612,10 +9996,9 @@
 
       // Similarly, dive into enums and fish their constants out, making them
       // accessible in this scope.
-      if (EnumDecl *ED = dyn_cast<EnumDecl>(D)) {
-        for (EnumDecl::enumerator_iterator EI = ED->enumerator_begin(),
-               EE = ED->enumerator_end(); EI != EE; ++EI)
-          PushOnScopeChains(*EI, FnBodyScope, /*AddToContext=*/false);
+      if (auto *ED = dyn_cast<EnumDecl>(D)) {
+        for (auto *EI : ED->enumerators())
+          PushOnScopeChains(EI, FnBodyScope, /*AddToContext=*/false);
       }
     }
   }
@@ -9624,35 +10007,22 @@
   if (const FunctionProtoType *FPT = FD->getType()->getAs<FunctionProtoType>())
     ResolveExceptionSpec(D->getLocation(), FPT);
 
-  // Checking attributes of current function definition
-  // dllimport attribute.
-  DLLImportAttr *DA = FD->getAttr<DLLImportAttr>();
-  if (DA && (!FD->getAttr<DLLExportAttr>())) {
-    // dllimport attribute cannot be directly applied to definition.
-    // Microsoft accepts dllimport for functions defined within class scope. 
-    if (!DA->isInherited() &&
-        !(LangOpts.MicrosoftExt && FD->getLexicalDeclContext()->isRecord())) {
-      Diag(FD->getLocation(),
-           diag::err_attribute_can_be_applied_only_to_symbol_declaration)
-        << "dllimport";
-      FD->setInvalidDecl();
-      return D;
-    }
-
-    // Visual C++ appears to not think this is an issue, so only issue
-    // a warning when Microsoft extensions are disabled.
-    if (!LangOpts.MicrosoftExt) {
-      // If a symbol previously declared dllimport is later defined, the
-      // attribute is ignored in subsequent references, and a warning is
-      // emitted.
-      Diag(FD->getLocation(),
-           diag::warn_redeclaration_without_attribute_prev_attribute_ignored)
-        << FD->getName() << "dllimport";
-    }
+  // dllimport cannot be applied to non-inline function definitions.
+  if (FD->hasAttr<DLLImportAttr>() && !FD->isInlined() &&
+      !FD->isTemplateInstantiation()) {
+    assert(!FD->hasAttr<DLLExportAttr>());
+    Diag(FD->getLocation(), diag::err_attribute_dllimport_function_definition);
+    FD->setInvalidDecl();
+    return D;
   }
   // We want to attach documentation to original Decl (which might be
   // a function template).
   ActOnDocumentableDecl(D);
+  if (getCurLexicalContext()->isObjCContainer() &&
+      getCurLexicalContext()->getDeclKind() != Decl::ObjCCategoryImpl &&
+      getCurLexicalContext()->getDeclKind() != Decl::ObjCImplementation)
+    Diag(FD->getLocation(), diag::warn_function_def_in_objc_container);
+    
   return D;
 }
 
@@ -9666,49 +10036,53 @@
 /// use the named return value optimization.
 ///
 /// This function applies a very simplistic algorithm for NRVO: if every return
-/// statement in the function has the same NRVO candidate, that candidate is
-/// the NRVO variable.
-///
-/// FIXME: Employ a smarter algorithm that accounts for multiple return 
-/// statements and the lifetimes of the NRVO candidates. We should be able to
-/// find a maximal set of NRVO variables.
+/// statement in the scope of a variable has the same NRVO candidate, that
+/// candidate is an NRVO variable.
 void Sema::computeNRVO(Stmt *Body, FunctionScopeInfo *Scope) {
   ReturnStmt **Returns = Scope->Returns.data();
 
-  const VarDecl *NRVOCandidate = 0;
   for (unsigned I = 0, E = Scope->Returns.size(); I != E; ++I) {
-    if (!Returns[I]->getNRVOCandidate())
-      return;
-    
-    if (!NRVOCandidate)
-      NRVOCandidate = Returns[I]->getNRVOCandidate();
-    else if (NRVOCandidate != Returns[I]->getNRVOCandidate())
-      return;
+    if (const VarDecl *NRVOCandidate = Returns[I]->getNRVOCandidate()) {
+      if (!NRVOCandidate->isNRVOVariable())
+        Returns[I]->setNRVOCandidate(nullptr);
+    }
   }
-  
-  if (NRVOCandidate)
-    const_cast<VarDecl*>(NRVOCandidate)->setNRVOVariable(true);
+}
+
+bool Sema::canDelayFunctionBody(const Declarator &D) {
+  // We can't delay parsing the body of a constexpr function template (yet).
+  if (D.getDeclSpec().isConstexprSpecified())
+    return false;
+
+  // We can't delay parsing the body of a function template with a deduced
+  // return type (yet).
+  if (D.getDeclSpec().containsPlaceholderType()) {
+    // If the placeholder introduces a non-deduced trailing return type,
+    // we can still delay parsing it.
+    if (D.getNumTypeObjects()) {
+      const auto &Outer = D.getTypeObject(D.getNumTypeObjects() - 1);
+      if (Outer.Kind == DeclaratorChunk::Function &&
+          Outer.Fun.hasTrailingReturnType()) {
+        QualType Ty = GetTypeFromParser(Outer.Fun.getTrailingReturnType());
+        return Ty.isNull() || !Ty->isUndeducedType();
+      }
+    }
+    return false;
+  }
+
+  return true;
 }
 
 bool Sema::canSkipFunctionBody(Decl *D) {
-  if (!Consumer.shouldSkipFunctionBody(D))
-    return false;
-
-  if (isa<ObjCMethodDecl>(D))
-    return true;
-
-  FunctionDecl *FD = 0;
-  if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(D))
-    FD = FTD->getTemplatedDecl();
-  else
-    FD = cast<FunctionDecl>(D);
-
   // We cannot skip the body of a function (or function template) which is
   // constexpr, since we may need to evaluate its body in order to parse the
   // rest of the file.
   // We cannot skip the body of a function with an undeduced return type,
   // because any callers of that function need to know the type.
-  return !FD->isConstexpr() && !FD->getResultType()->isUndeducedType();
+  if (const FunctionDecl *FD = D->getAsFunction())
+    if (FD->isConstexpr() || FD->getReturnType()->isUndeducedType())
+      return false;
+  return Consumer.shouldSkipFunctionBody(D);
 }
 
 Decl *Sema::ActOnSkippedFunctionBody(Decl *Decl) {
@@ -9716,7 +10090,7 @@
     FD->setHasSkippedBody();
   else if (ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(Decl))
     MD->setHasSkippedBody();
-  return ActOnFinishFunctionBody(Decl, 0);
+  return ActOnFinishFunctionBody(Decl, nullptr);
 }
 
 Decl *Sema::ActOnFinishFunctionBody(Decl *D, Stmt *BodyArg) {
@@ -9725,32 +10099,27 @@
 
 Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
                                     bool IsInstantiation) {
-  FunctionDecl *FD = 0;
-  FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(dcl);
-  if (FunTmpl)
-    FD = FunTmpl->getTemplatedDecl();
-  else
-    FD = dyn_cast_or_null<FunctionDecl>(dcl);
+  FunctionDecl *FD = dcl ? dcl->getAsFunction() : nullptr;
 
   sema::AnalysisBasedWarnings::Policy WP = AnalysisWarnings.getDefaultPolicy();
-  sema::AnalysisBasedWarnings::Policy *ActivePolicy = 0;
+  sema::AnalysisBasedWarnings::Policy *ActivePolicy = nullptr;
 
   if (FD) {
     FD->setBody(Body);
 
     if (getLangOpts().CPlusPlus1y && !FD->isInvalidDecl() && Body &&
-        !FD->isDependentContext() && FD->getResultType()->isUndeducedType()) {
+        !FD->isDependentContext() && FD->getReturnType()->isUndeducedType()) {
       // If the function has a deduced result type but contains no 'return'
       // statements, the result type as written must be exactly 'auto', and
       // the deduced result type is 'void'.
-      if (!FD->getResultType()->getAs<AutoType>()) {
+      if (!FD->getReturnType()->getAs<AutoType>()) {
         Diag(dcl->getLocation(), diag::err_auto_fn_no_return_but_not_auto)
-          << FD->getResultType();
+            << FD->getReturnType();
         FD->setInvalidDecl();
       } else {
         // Substitute 'void' for the 'auto' in the type.
         TypeLoc ResultType = FD->getTypeSourceInfo()->getTypeLoc().
-            IgnoreParens().castAs<FunctionProtoTypeLoc>().getResultLoc();
+            IgnoreParens().castAs<FunctionProtoTypeLoc>().getReturnLoc();
         Context.adjustDeducedFunctionResultType(
             FD, SubstAutoType(ResultType.getType(), Context.VoidTy));
       }
@@ -9774,15 +10143,17 @@
       WP.disableCheckFallThrough();
 
     // MSVC permits the use of pure specifier (=0) on function definition,
-    // defined at class scope, warn about this non standard construct.
+    // defined at class scope, warn about this non-standard construct.
     if (getLangOpts().MicrosoftExt && FD->isPure() && FD->isCanonicalDecl())
-      Diag(FD->getLocation(), diag::warn_pure_function_definition);
+      Diag(FD->getLocation(), diag::ext_pure_function_definition);
 
     if (!FD->isInvalidDecl()) {
-      DiagnoseUnusedParameters(FD->param_begin(), FD->param_end());
+      // Don't diagnose unused parameters of defaulted or deleted functions.
+      if (Body)
+        DiagnoseUnusedParameters(FD->param_begin(), FD->param_end());
       DiagnoseSizeOfParametersAndReturnValue(FD->param_begin(), FD->param_end(),
-                                             FD->getResultType(), FD);
-      
+                                             FD->getReturnType(), FD);
+
       // If this is a constructor, we need a vtable.
       if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(FD))
         MarkVTableUsed(FD->getLocation(), Constructor->getParent());
@@ -9790,7 +10161,7 @@
       // Try to apply the named return value optimization. We have to check
       // if we can do this here because lambdas keep return statements around
       // to deduce an implicit return type.
-      if (getLangOpts().CPlusPlus && FD->getResultType()->isRecordType() &&
+      if (getLangOpts().CPlusPlus && FD->getReturnType()->isRecordType() &&
           !FD->isDependentContext())
         computeNRVO(Body, getCurFunction());
     }
@@ -9803,8 +10174,8 @@
     if (!MD->isInvalidDecl()) {
       DiagnoseUnusedParameters(MD->param_begin(), MD->param_end());
       DiagnoseSizeOfParametersAndReturnValue(MD->param_begin(), MD->param_end(),
-                                             MD->getResultType(), MD);
-      
+                                             MD->getReturnType(), MD);
+
       if (Body)
         computeNRVO(Body, getCurFunction());
     }
@@ -9813,8 +10184,41 @@
         << MD->getSelector().getAsString();
       getCurFunction()->ObjCShouldCallSuper = false;
     }
+    if (getCurFunction()->ObjCWarnForNoDesignatedInitChain) {
+      const ObjCMethodDecl *InitMethod = nullptr;
+      bool isDesignated =
+          MD->isDesignatedInitializerForTheInterface(&InitMethod);
+      assert(isDesignated && InitMethod);
+      (void)isDesignated;
+
+      auto superIsNSObject = [&](const ObjCMethodDecl *MD) {
+        auto IFace = MD->getClassInterface();
+        if (!IFace)
+          return false;
+        auto SuperD = IFace->getSuperClass();
+        if (!SuperD)
+          return false;
+        return SuperD->getIdentifier() ==
+            NSAPIObj->getNSClassId(NSAPI::ClassId_NSObject);
+      };
+      // Don't issue this warning for unavailable inits or direct subclasses
+      // of NSObject.
+      if (!MD->isUnavailable() && !superIsNSObject(MD)) {
+        Diag(MD->getLocation(),
+             diag::warn_objc_designated_init_missing_super_call);
+        Diag(InitMethod->getLocation(),
+             diag::note_objc_designated_init_marked_here);
+      }
+      getCurFunction()->ObjCWarnForNoDesignatedInitChain = false;
+    }
+    if (getCurFunction()->ObjCWarnForNoInitDelegation) {
+      // Don't issue this warning for unavaialable inits.
+      if (!MD->isUnavailable())
+        Diag(MD->getLocation(), diag::warn_objc_secondary_init_missing_init_call);
+      getCurFunction()->ObjCWarnForNoInitDelegation = false;
+    }
   } else {
-    return 0;
+    return nullptr;
   }
 
   assert(!getCurFunction()->ObjCShouldCallSuper &&
@@ -9831,8 +10235,6 @@
     
     // Verify that gotos and switch cases don't jump into scopes illegally.
     if (getCurFunction()->NeedsScopeChecking() &&
-        !dcl->isInvalidDecl() &&
-        !hasAnyUnrecoverableErrorsInThisFunction() &&
         !PP.isCodeCompletionEnabled())
       DiagnoseInvalidJumps(Body);
 
@@ -9847,11 +10249,11 @@
     // If any errors have occurred, clear out any temporaries that may have
     // been leftover. This ensures that these temporaries won't be picked up for
     // deletion in some later function.
-    if (PP.getDiagnostics().hasErrorOccurred() ||
-        PP.getDiagnostics().getSuppressAllDiagnostics()) {
+    if (getDiagnostics().hasErrorOccurred() ||
+        getDiagnostics().getSuppressAllDiagnostics()) {
       DiscardCleanupsInEvaluationContext();
     }
-    if (!PP.getDiagnostics().hasUncompilableErrorOccurred() &&
+    if (!getDiagnostics().hasUncompilableErrorOccurred() &&
         !isa<FunctionTemplateDecl>(dcl)) {
       // Since the body is valid, issue any analysis-based warnings that are
       // enabled.
@@ -9929,7 +10331,8 @@
     TypoCorrection Corrected;
     DeclFilterCCC<FunctionDecl> Validator;
     if (S && (Corrected = CorrectTypo(DeclarationNameInfo(&II, Loc),
-                                      LookupOrdinaryName, S, 0, Validator)))
+                                      LookupOrdinaryName, S, nullptr, Validator,
+                                      CTK_NonError)))
       diagnoseTypo(Corrected, PDiag(diag::note_function_suggestion),
                    /*ErrorRecovery*/false);
   }
@@ -9939,16 +10342,17 @@
   AttributeFactory attrFactory;
   DeclSpec DS(attrFactory);
   unsigned DiagID;
-  bool Error = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, Dummy, DiagID);
+  bool Error = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, Dummy, DiagID,
+                                  Context.getPrintingPolicy());
   (void)Error; // Silence warning.
   assert(!Error && "Error setting up implicit decl!");
   SourceLocation NoLoc;
   Declarator D(DS, Declarator::BlockContext);
   D.AddTypeInfo(DeclaratorChunk::getFunction(/*HasProto=*/false,
                                              /*IsAmbiguous=*/false,
-                                             /*RParenLoc=*/NoLoc,
-                                             /*ArgInfo=*/0,
-                                             /*NumArgs=*/0,
+                                             /*LParenLoc=*/NoLoc,
+                                             /*Params=*/nullptr,
+                                             /*NumParams=*/0,
                                              /*EllipsisLoc=*/NoLoc,
                                              /*RParenLoc=*/NoLoc,
                                              /*TypeQuals=*/0,
@@ -9959,10 +10363,10 @@
                                              /*MutableLoc=*/NoLoc,
                                              EST_None,
                                              /*ESpecLoc=*/NoLoc,
-                                             /*Exceptions=*/0,
-                                             /*ExceptionRanges=*/0,
+                                             /*Exceptions=*/nullptr,
+                                             /*ExceptionRanges=*/nullptr,
                                              /*NumExceptions=*/0,
-                                             /*NoexceptExpr=*/0,
+                                             /*NoexceptExpr=*/nullptr,
                                              Loc, Loc, D),
                 DS.getAttributes(),
                 SourceLocation());
@@ -10003,25 +10407,27 @@
     unsigned FormatIdx;
     bool HasVAListArg;
     if (Context.BuiltinInfo.isPrintfLike(BuiltinID, FormatIdx, HasVAListArg)) {
-      if (!FD->getAttr<FormatAttr>()) {
+      if (!FD->hasAttr<FormatAttr>()) {
         const char *fmt = "printf";
         unsigned int NumParams = FD->getNumParams();
         if (FormatIdx < NumParams && // NumParams may be 0 (e.g. vfprintf)
             FD->getParamDecl(FormatIdx)->getType()->isObjCObjectPointerType())
           fmt = "NSString";
-        FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context,
+        FD->addAttr(FormatAttr::CreateImplicit(Context,
                                                &Context.Idents.get(fmt),
                                                FormatIdx+1,
-                                               HasVAListArg ? 0 : FormatIdx+2));
+                                               HasVAListArg ? 0 : FormatIdx+2,
+                                               FD->getLocation()));
       }
     }
     if (Context.BuiltinInfo.isScanfLike(BuiltinID, FormatIdx,
                                              HasVAListArg)) {
-     if (!FD->getAttr<FormatAttr>())
-       FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context,
+     if (!FD->hasAttr<FormatAttr>())
+       FD->addAttr(FormatAttr::CreateImplicit(Context,
                                               &Context.Idents.get("scanf"),
                                               FormatIdx+1,
-                                              HasVAListArg ? 0 : FormatIdx+2));
+                                              HasVAListArg ? 0 : FormatIdx+2,
+                                              FD->getLocation()));
     }
 
     // Mark const if we don't care about errno and that is the only
@@ -10029,17 +10435,18 @@
     // IRgen to use LLVM intrinsics for such functions.
     if (!getLangOpts().MathErrno &&
         Context.BuiltinInfo.isConstWithoutErrno(BuiltinID)) {
-      if (!FD->getAttr<ConstAttr>())
-        FD->addAttr(::new (Context) ConstAttr(FD->getLocation(), Context));
+      if (!FD->hasAttr<ConstAttr>())
+        FD->addAttr(ConstAttr::CreateImplicit(Context, FD->getLocation()));
     }
 
     if (Context.BuiltinInfo.isReturnsTwice(BuiltinID) &&
-        !FD->getAttr<ReturnsTwiceAttr>())
-      FD->addAttr(::new (Context) ReturnsTwiceAttr(FD->getLocation(), Context));
-    if (Context.BuiltinInfo.isNoThrow(BuiltinID) && !FD->getAttr<NoThrowAttr>())
-      FD->addAttr(::new (Context) NoThrowAttr(FD->getLocation(), Context));
-    if (Context.BuiltinInfo.isConst(BuiltinID) && !FD->getAttr<ConstAttr>())
-      FD->addAttr(::new (Context) ConstAttr(FD->getLocation(), Context));
+        !FD->hasAttr<ReturnsTwiceAttr>())
+      FD->addAttr(ReturnsTwiceAttr::CreateImplicit(Context,
+                                         FD->getLocation()));
+    if (Context.BuiltinInfo.isNoThrow(BuiltinID) && !FD->hasAttr<NoThrowAttr>())
+      FD->addAttr(NoThrowAttr::CreateImplicit(Context, FD->getLocation()));
+    if (Context.BuiltinInfo.isConst(BuiltinID) && !FD->hasAttr<ConstAttr>())
+      FD->addAttr(ConstAttr::CreateImplicit(Context, FD->getLocation()));
   }
 
   IdentifierInfo *Name = FD->getIdentifier();
@@ -10058,17 +10465,19 @@
   if (Name->isStr("asprintf") || Name->isStr("vasprintf")) {
     // FIXME: asprintf and vasprintf aren't C99 functions. Should they be
     // target-specific builtins, perhaps?
-    if (!FD->getAttr<FormatAttr>())
-      FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context,
+    if (!FD->hasAttr<FormatAttr>())
+      FD->addAttr(FormatAttr::CreateImplicit(Context,
                                              &Context.Idents.get("printf"), 2,
-                                             Name->isStr("vasprintf") ? 0 : 3));
+                                             Name->isStr("vasprintf") ? 0 : 3,
+                                             FD->getLocation()));
   }
 
   if (Name->isStr("__CFStringMakeConstantString")) {
     // We already have a __builtin___CFStringMakeConstantString,
     // but builds that use -fno-constant-cfstrings don't go through that.
-    if (!FD->getAttr<FormatArgAttr>())
-      FD->addAttr(::new (Context) FormatArgAttr(FD->getLocation(), Context, 1));
+    if (!FD->hasAttr<FormatArgAttr>())
+      FD->addAttr(FormatArgAttr::CreateImplicit(Context, 1,
+                                                FD->getLocation()));
   }
 }
 
@@ -10131,6 +10540,26 @@
     if (!Context.hasSameType(T, Context.getTagDeclType(tagFromDeclSpec)))
       break;
 
+    // If we've already computed linkage for the anonymous tag, then
+    // adding a typedef name for the anonymous decl can change that
+    // linkage, which might be a serious problem.  Diagnose this as
+    // unsupported and ignore the typedef name.  TODO: we should
+    // pursue this as a language defect and establish a formal rule
+    // for how to handle it.
+    if (tagFromDeclSpec->hasLinkageBeenComputed()) {
+      Diag(D.getIdentifierLoc(), diag::err_typedef_changes_linkage);
+
+      SourceLocation tagLoc = D.getDeclSpec().getTypeSpecTypeLoc();
+      tagLoc = getLocForEndOfToken(tagLoc);
+
+      llvm::SmallString<40> textToInsert;
+      textToInsert += ' ';
+      textToInsert += D.getIdentifier()->getName();
+      Diag(tagLoc, diag::note_typedef_changes_linkage)
+        << FixItHint::CreateInsertion(tagLoc, textToInsert);
+      break;
+    }
+
     // Otherwise, set this is the anon-decl typedef for the tag.
     tagFromDeclSpec->setTypedefNameForAnonDecl(NewTD);
     break;
@@ -10170,7 +10599,7 @@
   if (IsScoped != Prev->isScoped()) {
     Diag(EnumLoc, diag::err_enum_redeclare_scoped_mismatch)
       << Prev->isScoped();
-    Diag(Prev->getLocation(), diag::note_previous_use);
+    Diag(Prev->getLocation(), diag::note_previous_declaration);
     return true;
   }
 
@@ -10179,15 +10608,17 @@
         !Prev->getIntegerType()->isDependentType() &&
         !Context.hasSameUnqualifiedType(EnumUnderlyingTy,
                                         Prev->getIntegerType())) {
+      // TODO: Highlight the underlying type of the redeclaration.
       Diag(EnumLoc, diag::err_enum_redeclare_type_mismatch)
         << EnumUnderlyingTy << Prev->getIntegerType();
-      Diag(Prev->getLocation(), diag::note_previous_use);
+      Diag(Prev->getLocation(), diag::note_previous_declaration)
+          << Prev->getIntegerTypeRange();
       return true;
     }
   } else if (IsFixed != Prev->isFixed()) {
     Diag(EnumLoc, diag::err_enum_redeclare_fixed_mismatch)
       << Prev->isFixed();
-    Diag(Prev->getLocation(), diag::note_previous_use);
+    Diag(Prev->getLocation(), diag::note_previous_declaration);
     return true;
   }
 
@@ -10267,8 +10698,7 @@
       }
 
       bool previousMismatch = false;
-      for (TagDecl::redecl_iterator I(Previous->redecls_begin()),
-           E(Previous->redecls_end()); I != E; ++I) {
+      for (auto I : Previous->redecls()) {
         if (I->getTagKind() != NewTag) {
           if (!previousMismatch) {
             previousMismatch = true;
@@ -10299,7 +10729,7 @@
       << getRedeclDiagFromTagKind(OldTag);
     Diag(Redecl->getLocation(), diag::note_previous_use);
 
-    // If there is a previous defintion, suggest a fix-it.
+    // If there is a previous definition, suggest a fix-it.
     if (Previous->getDefinition()) {
         Diag(NewTagLoc, diag::note_struct_class_suggestion)
           << getRedeclDiagFromTagKind(Redecl->getTagKind())
@@ -10312,10 +10742,56 @@
   return false;
 }
 
+/// Add a minimal nested name specifier fixit hint to allow lookup of a tag name
+/// from an outer enclosing namespace or file scope inside a friend declaration.
+/// This should provide the commented out code in the following snippet:
+///   namespace N {
+///     struct X;
+///     namespace M {
+///       struct Y { friend struct /*N::*/ X; };
+///     }
+///   }
+static FixItHint createFriendTagNNSFixIt(Sema &SemaRef, NamedDecl *ND, Scope *S,
+                                         SourceLocation NameLoc) {
+  // While the decl is in a namespace, do repeated lookup of that name and see
+  // if we get the same namespace back.  If we do not, continue until
+  // translation unit scope, at which point we have a fully qualified NNS.
+  SmallVector<IdentifierInfo *, 4> Namespaces;
+  DeclContext *DC = ND->getDeclContext()->getRedeclContext();
+  for (; !DC->isTranslationUnit(); DC = DC->getParent()) {
+    // This tag should be declared in a namespace, which can only be enclosed by
+    // other namespaces.  Bail if there's an anonymous namespace in the chain.
+    NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(DC);
+    if (!Namespace || Namespace->isAnonymousNamespace())
+      return FixItHint();
+    IdentifierInfo *II = Namespace->getIdentifier();
+    Namespaces.push_back(II);
+    NamedDecl *Lookup = SemaRef.LookupSingleName(
+        S, II, NameLoc, Sema::LookupNestedNameSpecifierName);
+    if (Lookup == Namespace)
+      break;
+  }
+
+  // Once we have all the namespaces, reverse them to go outermost first, and
+  // build an NNS.
+  SmallString<64> Insertion;
+  llvm::raw_svector_ostream OS(Insertion);
+  if (DC->isTranslationUnit())
+    OS << "::";
+  std::reverse(Namespaces.begin(), Namespaces.end());
+  for (auto *II : Namespaces)
+    OS << II->getName() << "::";
+  OS.flush();
+  return FixItHint::CreateInsertion(NameLoc, Insertion);
+}
+
 /// ActOnTag - 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
 /// reference/declaration/definition of a tag.
+///
+/// IsTypeSpecifier is true if this is a type-specifier (or
+/// trailing-type-specifier) other than one in an alias-declaration.
 Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
                      SourceLocation KWLoc, CXXScopeSpec &SS,
                      IdentifierInfo *Name, SourceLocation NameLoc,
@@ -10325,10 +10801,11 @@
                      bool &OwnedDecl, bool &IsDependent,
                      SourceLocation ScopedEnumKWLoc,
                      bool ScopedEnumUsesClassTag,
-                     TypeResult UnderlyingType) {
+                     TypeResult UnderlyingType,
+                     bool IsTypeSpecifier) {
   // If this is not a definition, it must have a name.
   IdentifierInfo *OrigName = Name;
-  assert((Name != 0 || TUK == TUK_Definition) &&
+  assert((Name != nullptr || TUK == TUK_Definition) &&
          "Nameless record must be a definition!");
   assert(TemplateParameterLists.size() == 0 || TUK != TUK_Reference);
 
@@ -10347,11 +10824,11 @@
       (SS.isNotEmpty() && TUK != TUK_Reference)) {
     if (TemplateParameterList *TemplateParams =
             MatchTemplateParametersToScopeSpecifier(
-                KWLoc, NameLoc, SS, TemplateParameterLists, TUK == TUK_Friend,
-                isExplicitSpecialization, Invalid)) {
+                KWLoc, NameLoc, SS, nullptr, TemplateParameterLists,
+                TUK == TUK_Friend, isExplicitSpecialization, Invalid)) {
       if (Kind == TTK_Enum) {
         Diag(KWLoc, diag::err_enum_template);
-        return 0;
+        return nullptr;
       }
 
       if (TemplateParams->size() > 0) {
@@ -10359,13 +10836,14 @@
         // be a member of another template).
 
         if (Invalid)
-          return 0;
+          return nullptr;
 
         OwnedDecl = false;
         DeclResult Result = CheckClassTemplate(S, TagSpec, TUK, KWLoc,
                                                SS, Name, NameLoc, Attr,
                                                TemplateParams, AS,
                                                ModulePrivateLoc,
+                                               /*FriendLoc*/SourceLocation(),
                                                TemplateParameterLists.size()-1,
                                                TemplateParameterLists.data());
         return Result.get();
@@ -10391,7 +10869,7 @@
     else if (UnderlyingType.get()) {
       // C++0x 7.2p2: The type-specifier-seq of an enum-base shall name an
       // integral type; any cv-qualification is ignored.
-      TypeSourceInfo *TI = 0;
+      TypeSourceInfo *TI = nullptr;
       GetTypeFromParser(UnderlyingType.get(), &TI);
       EnumUnderlying = TI;
 
@@ -10403,7 +10881,7 @@
                                           UPPC_FixedUnderlyingType))
         EnumUnderlying = Context.IntTy.getTypePtr();
 
-    } else if (getLangOpts().MicrosoftMode)
+    } else if (getLangOpts().MSVCCompat)
       // Microsoft enums are always of int type.
       EnumUnderlying = Context.IntTy.getTypePtr();
   }
@@ -10417,13 +10895,12 @@
     Redecl = NotForRedeclaration;
 
   LookupResult Previous(*this, Name, NameLoc, LookupTagName, Redecl);
-  bool FriendSawTagOutsideEnclosingNamespace = false;
   if (Name && SS.isNotEmpty()) {
     // We have a nested-name tag ('struct foo::bar').
 
     // Check for invalid 'foo::'.
     if (SS.isInvalid()) {
-      Name = 0;
+      Name = nullptr;
       goto CreateNewDecl;
     }
 
@@ -10433,26 +10910,26 @@
       DC = computeDeclContext(SS, false);
       if (!DC) {
         IsDependent = true;
-        return 0;
+        return nullptr;
       }
     } else {
       DC = computeDeclContext(SS, true);
       if (!DC) {
         Diag(SS.getRange().getBegin(), diag::err_dependent_nested_name_spec)
           << SS.getRange();
-        return 0;
+        return nullptr;
       }
     }
 
     if (RequireCompleteDeclContext(SS, DC))
-      return 0;
+      return nullptr;
 
     SearchDC = DC;
     // Look-up name inside 'foo::'.
     LookupQualifiedName(Previous, DC);
 
     if (Previous.isAmbiguous())
-      return 0;
+      return nullptr;
 
     if (Previous.empty()) {
       // Name lookup did not find anything. However, if the
@@ -10464,13 +10941,13 @@
       if (Previous.wasNotFoundInCurrentInstantiation() &&
           (TUK == TUK_Reference || TUK == TUK_Friend)) {
         IsDependent = true;
-        return 0;
+        return nullptr;
       }
 
       // A tag 'foo::bar' must already exist.
       Diag(NameLoc, diag::err_not_tag_in_scope) 
         << Kind << Name << DC << SS.getRange();
-      Name = 0;
+      Name = nullptr;
       Invalid = true;
       goto CreateNewDecl;
     }
@@ -10502,26 +10979,41 @@
     //   the entity has been previously declared shall not consider
     //   any scopes outside the innermost enclosing namespace.
     //
+    // MSVC doesn't implement the above rule for types, so a friend tag
+    // declaration may be a redeclaration of a type declared in an enclosing
+    // scope.  They do implement this rule for friend functions.
+    //
     // Does it matter that this should be by scope instead of by
     // semantic context?
     if (!Previous.empty() && TUK == TUK_Friend) {
       DeclContext *EnclosingNS = SearchDC->getEnclosingNamespaceContext();
       LookupResult::Filter F = Previous.makeFilter();
+      bool FriendSawTagOutsideEnclosingNamespace = false;
       while (F.hasNext()) {
         NamedDecl *ND = F.next();
         DeclContext *DC = ND->getDeclContext()->getRedeclContext();
         if (DC->isFileContext() &&
             !EnclosingNS->Encloses(ND->getDeclContext())) {
-          F.erase();
-          FriendSawTagOutsideEnclosingNamespace = true;
+          if (getLangOpts().MSVCCompat)
+            FriendSawTagOutsideEnclosingNamespace = true;
+          else
+            F.erase();
         }
       }
       F.done();
+
+      // Diagnose this MSVC extension in the easy case where lookup would have
+      // unambiguously found something outside the enclosing namespace.
+      if (Previous.isSingleResult() && FriendSawTagOutsideEnclosingNamespace) {
+        NamedDecl *ND = Previous.getFoundDecl();
+        Diag(NameLoc, diag::ext_friend_tag_redecl_outside_namespace)
+            << createFriendTagNNSFixIt(*this, ND, S, NameLoc);
+      }
     }
-    
+
     // Note:  there used to be some attempt at recovery here.
     if (Previous.isAmbiguous())
-      return 0;
+      return nullptr;
 
     if (!getLangOpts().CPlusPlus && TUK != TUK_Reference) {
       // FIXME: This makes sure that we ignore the contexts associated
@@ -10531,11 +11023,6 @@
       while (isa<RecordDecl>(SearchDC) || isa<EnumDecl>(SearchDC))
         SearchDC = SearchDC->getParent();
     }
-  } else if (S->isFunctionPrototypeScope()) {
-    // If this is an enum declaration in function prototype scope, set its
-    // initial context to the translation unit.
-    // FIXME: [citation needed]
-    SearchDC = Context.getTranslationUnitDecl();
   }
 
   if (Previous.isSingleResult() &&
@@ -10625,7 +11112,9 @@
   }
 
   if (!Previous.empty()) {
-    NamedDecl *PrevDecl = (*Previous.begin())->getUnderlyingDecl();
+    NamedDecl *PrevDecl = Previous.getFoundDecl();
+    NamedDecl *DirectPrevDecl =
+        getLangOpts().MSVCCompat ? *Previous.begin() : PrevDecl;
 
     // It's okay to have a tag decl in the same scope as a typedef
     // which hides a tag decl in the same scope.  Finding this
@@ -10657,7 +11146,8 @@
       // in the same scope (so that the definition/declaration completes or
       // rementions the tag), reuse the decl.
       if (TUK == TUK_Reference || TUK == TUK_Friend ||
-          isDeclInScope(PrevDecl, SearchDC, S, isExplicitSpecialization)) {
+          isDeclInScope(DirectPrevDecl, SearchDC, S,
+                        SS.isNotEmpty() || isExplicitSpecialization)) {
         // Make sure that this wasn't declared as an enum and now used as a
         // struct or something similar.
         if (!isAcceptableTagRedeclaration(PrevTagDecl, Kind,
@@ -10679,7 +11169,7 @@
             Kind = PrevTagDecl->getTagKind();
           else {
             // Recover by making this an anonymous redefinition.
-            Name = 0;
+            Name = nullptr;
             Previous.clear();
             Invalid = true;
           }
@@ -10700,7 +11190,7 @@
 
           QualType EnumUnderlyingTy;
           if (TypeSourceInfo *TI = EnumUnderlying.dyn_cast<TypeSourceInfo*>())
-            EnumUnderlyingTy = TI->getType();
+            EnumUnderlyingTy = TI->getType().getUnqualifiedType();
           else if (const Type *T = EnumUnderlying.dyn_cast<const Type*>())
             EnumUnderlyingTy = QualType(T, 0);
 
@@ -10709,7 +11199,7 @@
           // in which case we want the caller to bail out.
           if (CheckEnumRedeclaration(NameLoc.isValid() ? NameLoc : KWLoc,
                                      ScopedEnum, EnumUnderlyingTy, PrevEnum))
-            return TUK == TUK_Declaration ? PrevTagDecl : 0;
+            return TUK == TUK_Declaration ? PrevTagDecl : nullptr;
         }
 
         // C++11 [class.mem]p1:
@@ -10723,14 +11213,17 @@
         }
 
         if (!Invalid) {
-          // If this is a use, just return the declaration we found.
+          // If this is a use, just return the declaration we found, unless
+          // we have attributes.
 
           // FIXME: In the future, return a variant or some other clue
           // for the consumer of this Decl to know it doesn't own it.
           // For our current ASTs this shouldn't be a problem, but will
           // need to be changed with DeclGroups.
-          if ((TUK == TUK_Reference && (!PrevTagDecl->getFriendObjectKind() ||
-               getLangOpts().MicrosoftExt)) || TUK == TUK_Friend)
+          if (!Attr &&
+              ((TUK == TUK_Reference &&
+                (!PrevTagDecl->getFriendObjectKind() || getLangOpts().MicrosoftExt))
+               || TUK == TUK_Friend))
             return PrevTagDecl;
 
           // Diagnose attempts to redefine a tag.
@@ -10762,7 +11255,7 @@
                 // If this is a redefinition, recover by making this
                 // struct be anonymous, which will make any later
                 // references get the previous definition.
-                Name = 0;
+                Name = nullptr;
                 Previous.clear();
                 Invalid = true;
               }
@@ -10775,14 +11268,22 @@
                 Diag(NameLoc, diag::err_nested_redefinition) << Name;
                 Diag(PrevTagDecl->getLocation(),
                      diag::note_previous_definition);
-                Name = 0;
+                Name = nullptr;
                 Previous.clear();
                 Invalid = true;
               }
             }
 
             // Okay, this is definition of a previously declared or referenced
-            // tag PrevDecl. We're going to create a new Decl for it.
+            // tag. We're going to create a new Decl for it.
+          }
+
+          // Okay, we're going to make a redeclaration.  If this is some kind
+          // of reference, make sure we build the redeclaration in the same DC
+          // as the original, and ignore the current access specifier.
+          if (TUK == TUK_Friend || TUK == TUK_Reference) {
+            SearchDC = PrevTagDecl->getDeclContext();
+            AS = AS_none;
           }
         }
         // If we get here we have (another) forward declaration or we
@@ -10818,8 +11319,8 @@
         Invalid = true;
 
       // Otherwise, only diagnose if the declaration is in scope.
-      } else if (!isDeclInScope(PrevDecl, SearchDC, S, 
-                                isExplicitSpecialization)) {
+      } else if (!isDeclInScope(PrevDecl, SearchDC, S,
+                                SS.isNotEmpty() || isExplicitSpecialization)) {
         // do nothing
 
       // Diagnose implicit declarations introduced by elaborated types.
@@ -10848,7 +11349,7 @@
         // issue an error and recover by making this tag be anonymous.
         Diag(NameLoc, diag::err_redefinition_different_kind) << Name;
         Diag(PrevDecl->getLocation(), diag::note_previous_definition);
-        Name = 0;
+        Name = nullptr;
         Invalid = true;
       }
 
@@ -10860,7 +11361,7 @@
 
 CreateNewDecl:
 
-  TagDecl *PrevDecl = 0;
+  TagDecl *PrevDecl = nullptr;
   if (Previous.isSingleResult())
     PrevDecl = cast<TagDecl>(Previous.getFoundDecl());
 
@@ -10895,7 +11396,7 @@
         Diag(Def->getLocation(), diag::note_previous_definition);
       } else {
         unsigned DiagID = diag::ext_forward_ref_enum;
-        if (getLangOpts().MicrosoftMode)
+        if (getLangOpts().MSVCCompat)
           DiagID = diag::ext_ms_forward_ref_enum;
         else if (getLangOpts().CPlusPlus)
           DiagID = diag::err_forward_ref_enum;
@@ -10935,6 +11436,14 @@
                                cast_or_null<RecordDecl>(PrevDecl));
   }
 
+  // C++11 [dcl.type]p3:
+  //   A type-specifier-seq shall not define a class or enumeration [...].
+  if (getLangOpts().CPlusPlus && IsTypeSpecifier && TUK == TUK_Definition) {
+    Diag(New->getLocation(), diag::err_type_defined_in_type_specifier)
+      << Context.getTagDeclType(New);
+    Invalid = true;
+  }
+
   // Maybe add qualifier info.
   if (SS.isNotEmpty()) {
     if (SS.isSet()) {
@@ -10986,23 +11495,37 @@
     else if (!SearchDC->isFunctionOrMethod())
       New->setModulePrivate();
   }
-  
+
   // If this is a specialization of a member class (of a class template),
   // check the specialization.
   if (isExplicitSpecialization && CheckMemberSpecialization(New, Previous))
     Invalid = true;
-           
+
+  // If we're declaring or defining a tag in function prototype scope in C,
+  // note that this type can only be used within the function and add it to
+  // the list of decls to inject into the function definition scope.
+  if ((Name || Kind == TTK_Enum) &&
+      getNonFieldDeclScope(S)->isFunctionPrototypeScope()) {
+    if (getLangOpts().CPlusPlus) {
+      // C++ [dcl.fct]p6:
+      //   Types shall not be defined in return or parameter types.
+      if (TUK == TUK_Definition && !IsTypeSpecifier) {
+        Diag(Loc, diag::err_type_defined_in_param_type)
+            << Name;
+        Invalid = true;
+      }
+    } else {
+      Diag(Loc, diag::warn_decl_in_param_list) << Context.getTagDeclType(New);
+    }
+    DeclsInPrototypeScope.push_back(New);
+  }
+
   if (Invalid)
     New->setInvalidDecl();
 
   if (Attr)
     ProcessDeclAttributeList(S, New, Attr);
 
-  // If we're declaring or defining a tag in function prototype scope
-  // in C, note that this type can only be used within the function.
-  if (Name && S->isFunctionPrototypeScope() && !getLangOpts().CPlusPlus)
-    Diag(Loc, diag::warn_decl_in_param_list) << Context.getTagDeclType(New);
-
   // Set the lexical context. If the tag has a C++ scope specifier, the
   // lexical context will be different from the semantic context.
   New->setLexicalDeclContext(CurContext);
@@ -11012,8 +11535,7 @@
   // declaration so we always pass true to setObjectOfFriendDecl to make
   // the tag name visible.
   if (TUK == TUK_Friend)
-    New->setObjectOfFriendDecl(!FriendSawTagOutsideEnclosingNamespace &&
-                               getLangOpts().MicrosoftExt);
+    New->setObjectOfFriendDecl(getLangOpts().MSVCCompat);
 
   // Set the access specifier.
   if (!Invalid && SearchDC->isRecord())
@@ -11051,12 +11573,6 @@
         II->isStr("FILE"))
       Context.setFILEDecl(New);
 
-  // If we were in function prototype scope (and not in C++ mode), add this
-  // tag to the list of decls to inject into the function definition scope.
-  if (S->isFunctionPrototypeScope() && !getLangOpts().CPlusPlus &&
-      InFunctionDeclarator && Name)
-    DeclsInPrototypeScope.push_back(New);
-
   if (PrevDecl)
     mergeDeclAttributes(New, PrevDecl);
 
@@ -11067,7 +11583,7 @@
   OwnedDecl = true;
   // In C++, don't return an invalid declaration. We can't recover well from
   // the cases where we make the type anonymous.
-  return (Invalid && getLangOpts().CPlusPlus) ? 0 : New;
+  return (Invalid && getLangOpts().CPlusPlus) ? nullptr : New;
 }
 
 void Sema::ActOnTagStartDefinition(Scope *S, Decl *TagD) {
@@ -11119,7 +11635,7 @@
     = CXXRecordDecl::Create(Context, Record->getTagKind(), CurContext,
                             Record->getLocStart(), Record->getLocation(),
                             Record->getIdentifier(),
-                            /*PrevDecl=*/0,
+                            /*PrevDecl=*/nullptr,
                             /*DelayTypeCreation=*/true);
   Context.getTypeDeclType(InjectedClassName, Record);
   InjectedClassName->setImplicit();
@@ -11172,7 +11688,7 @@
 
 void Sema::ActOnObjCReenterContainerContext(DeclContext *DC) {
   ActOnObjCContainerStartDefinition(cast<Decl>(DC));
-  OriginalLexicalContext = 0;
+  OriginalLexicalContext = nullptr;
 }
 
 void Sema::ActOnTagDefinitionError(Scope *S, Decl *TagD) {
@@ -11220,13 +11736,13 @@
   // If the bit-width is type- or value-dependent, don't try to check
   // it now.
   if (BitWidth->isValueDependent() || BitWidth->isTypeDependent())
-    return Owned(BitWidth);
+    return BitWidth;
 
   llvm::APSInt Value;
   ExprResult ICE = VerifyIntegerConstantExpression(BitWidth, &Value);
   if (ICE.isInvalid())
     return ICE;
-  BitWidth = ICE.take();
+  BitWidth = ICE.get();
 
   if (Value != 0 && ZeroWidth)
     *ZeroWidth = false;
@@ -11246,7 +11762,8 @@
   if (!FieldTy->isDependentType()) {
     uint64_t TypeSize = Context.getTypeSize(FieldTy);
     if (Value.getZExtValue() > TypeSize) {
-      if (!getLangOpts().CPlusPlus || IsMsStruct) {
+      if (!getLangOpts().CPlusPlus || IsMsStruct ||
+          Context.getTargetInfo().getCXXABI().isMicrosoft()) {
         if (FieldName) 
           return Diag(FieldLoc, diag::err_bitfield_width_exceeds_type_size)
             << FieldName << (unsigned)Value.getZExtValue() 
@@ -11266,7 +11783,7 @@
     }
   }
 
-  return Owned(BitWidth);
+  return BitWidth;
 }
 
 /// ActOnField - Each field of a C struct/union is passed into this in order
@@ -11324,7 +11841,7 @@
       << DeclSpec::getSpecifierName(TSCS);
 
   // Check to see if this name was declared as a member previously
-  NamedDecl *PrevDecl = 0;
+  NamedDecl *PrevDecl = nullptr;
   LookupResult Previous(*this, II, Loc, LookupMemberName, ForRedeclaration);
   LookupName(Previous, S);
   switch (Previous.getResultKind()) {
@@ -11348,11 +11865,11 @@
     // Maybe we will complain about the shadowed template parameter.
     DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl);
     // Just pretend that we didn't see the previous declaration.
-    PrevDecl = 0;
+    PrevDecl = nullptr;
   }
 
   if (PrevDecl && !isDeclInScope(PrevDecl, Record, S))
-    PrevDecl = 0;
+    PrevDecl = nullptr;
 
   bool Mutable
     = (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_mutable);
@@ -11465,10 +11982,10 @@
   // If this is declared as a bit-field, check the bit-field.
   if (!InvalidDecl && BitWidth) {
     BitWidth = VerifyBitField(Loc, II, T, Record->isMsStruct(Context), BitWidth,
-                              &ZeroWidth).take();
+                              &ZeroWidth).get();
     if (!BitWidth) {
       InvalidDecl = true;
-      BitWidth = 0;
+      BitWidth = nullptr;
       ZeroWidth = false;
     }
   }
@@ -11491,6 +12008,12 @@
     }
   }
 
+  // C++11 [class.union]p8 (DR1460):
+  //   At most one variant member of a union may have a
+  //   brace-or-equal-initializer.
+  if (InitStyle != ICIS_NoInit)
+    checkDuplicateDefaultInit(*this, cast<CXXRecordDecl>(Record), Loc);
+
   FieldDecl *NewFD = FieldDecl::Create(Context, Record, TSSL, Loc, II, T, TInfo,
                                        BitWidth, Mutable, InitStyle);
   if (InvalidDecl)
@@ -11594,8 +12117,9 @@
           SourceLocation Loc = FD->getLocation();
           if (getSourceManager().isInSystemHeader(Loc)) {
             if (!FD->hasAttr<UnavailableAttr>())
-              FD->addAttr(new (Context) UnavailableAttr(Loc, Context,
-                                  "this system field has retaining ownership"));
+              FD->addAttr(UnavailableAttr::CreateImplicit(Context,
+                                  "this system field has retaining ownership",
+                                  Loc));
             return false;
           }
         }
@@ -11646,7 +12170,7 @@
 
   if (BitWidth) {
     // 6.7.2.1p3, 6.7.2.1p4
-    BitWidth = VerifyBitField(Loc, II, T, /*IsMsStruct*/false, BitWidth).take();
+    BitWidth = VerifyBitField(Loc, II, T, /*IsMsStruct*/false, BitWidth).get();
     if (!BitWidth)
       D.setInvalidType();
   } else {
@@ -11673,7 +12197,7 @@
   // Must set ivar's DeclContext to its enclosing interface.
   ObjCContainerDecl *EnclosingDecl = cast<ObjCContainerDecl>(CurContext);
   if (!EnclosingDecl || EnclosingDecl->isInvalidDecl())
-    return 0;
+    return nullptr;
   ObjCContainerDecl *EnclosingContext;
   if (ObjCImplementationDecl *IMPDecl =
       dyn_cast<ObjCImplementationDecl>(EnclosingDecl)) {
@@ -11689,7 +12213,7 @@
         dyn_cast<ObjCCategoryDecl>(EnclosingDecl)) {
       if (LangOpts.ObjCRuntime.isFragile() || !CDecl->IsClassExtension()) {
         Diag(Loc, diag::err_misplaced_ivar) << CDecl->IsClassExtension();
-        return 0;
+        return nullptr;
       }
     }
     EnclosingContext = EnclosingDecl;
@@ -11767,7 +12291,7 @@
   Expr * BW = IntegerLiteral::Create(Context, Zero, Context.IntTy, DeclLoc);
 
   Ivar = ObjCIvarDecl::Create(Context, cast<ObjCContainerDecl>(CurContext),
-                              DeclLoc, DeclLoc, 0,
+                              DeclLoc, DeclLoc, nullptr,
                               Context.CharTy, 
                               Context.getTrivialTypeSourceInfo(Context.CharTy,
                                                                DeclLoc),
@@ -11804,9 +12328,8 @@
   // members of anonymous structs and unions in the total.
   unsigned NumNamedMembers = 0;
   if (Record) {
-    for (RecordDecl::decl_iterator i = Record->decls_begin(),
-                                   e = Record->decls_end(); i != e; i++) {
-      if (IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(*i))
+    for (const auto *I : Record->decls()) {
+      if (const auto *IFD = dyn_cast<IndirectFieldDecl>(I))
         if (IFD->getDeclName())
           ++NumNamedMembers;
     }
@@ -11893,9 +12416,14 @@
         Diag(FD->getLocation(), diag::ext_c99_flexible_array_member)
           << FD->getDeclName() << Record->getTagKind();
 
-      if (!FD->getType()->isDependentType() &&
-          !Context.getBaseElementType(FD->getType()).isPODType(Context)) {
-        Diag(FD->getLocation(), diag::err_flexible_array_has_nonpod_type)
+      // If the element type has a non-trivial destructor, we would not
+      // implicitly destroy the elements, so disallow it for now.
+      //
+      // FIXME: GCC allows this. We should probably either implicitly delete
+      // the destructor of the containing class, or just allow this.
+      QualType BaseElem = Context.getBaseElementType(FD->getType());
+      if (!BaseElem->isDependentType() && BaseElem.isDestructedType()) {
+        Diag(FD->getLocation(), diag::err_flexible_array_has_nontrivial_dtor)
           << FD->getDeclName() << FD->getType();
         FD->setInvalidDecl();
         EnclosingDecl->setInvalidDecl();
@@ -11963,8 +12491,9 @@
         SourceLocation loc = FD->getLocation();
         if (getSourceManager().isInSystemHeader(loc)) {
           if (!FD->hasAttr<UnavailableAttr>()) {
-            FD->addAttr(new (Context) UnavailableAttr(loc, Context,
-                              "this system field has retaining ownership"));
+            FD->addAttr(UnavailableAttr::CreateImplicit(Context,
+                              "this system field has retaining ownership",
+                              loc));
           }
         } else {
           Diag(FD->getLocation(), diag::err_arc_objc_object_in_tag) 
@@ -12012,12 +12541,6 @@
             if (getLangOpts().CPlusPlus11)
               AdjustDestructorExceptionSpec(CXXRecord,
                                             CXXRecord->getDestructor());
-
-            // The Microsoft ABI requires that we perform the destructor body
-            // checks (i.e. operator delete() lookup) at every declaration, as
-            // any translation unit may need to emit a deleting destructor.
-            if (Context.getTargetInfo().getCXXABI().isMicrosoft())
-              CheckDestructor(CXXRecord->getDestructor());
           }
 
           // Add any implicitly-declared members to this class.
@@ -12069,9 +12592,15 @@
     if (!Completed)
       Record->completeDefinition();
 
-    if (Record->hasAttrs())
+    if (Record->hasAttrs()) {
       CheckAlignasUnderalignment(Record);
 
+      if (const MSInheritanceAttr *IA = Record->getAttr<MSInheritanceAttr>())
+        checkMSInheritanceAttrOnDefinition(cast<CXXRecordDecl>(Record),
+                                           IA->getRange(), IA->getBestCase(),
+                                           IA->getSemanticSpelling());
+    }
+
     // Check if the structure/union declaration is a type that can have zero
     // size in C. For C this is a language extension, for C++ it may cause
     // compatibility problems.
@@ -12166,10 +12695,7 @@
             Diag(ClsIvar->getLocation(), diag::note_previous_definition);
             continue;
           }
-          for (ObjCInterfaceDecl::known_extensions_iterator
-                 Ext = IDecl->known_extensions_begin(),
-                 ExtEnd = IDecl->known_extensions_end();
-               Ext != ExtEnd; ++Ext) {
+          for (const auto *Ext : IDecl->known_extensions()) {
             if (const ObjCIvarDecl *ClsExtIvar
                   = Ext->getIvarDecl(ClsFields[i]->getIdentifier())) {
               Diag(ClsFields[i]->getLocation(), 
@@ -12242,10 +12768,10 @@
   QualType EltTy;
 
   if (Val && DiagnoseUnexpandedParameterPack(Val, UPPC_EnumeratorValue))
-    Val = 0;
+    Val = nullptr;
 
   if (Val)
-    Val = DefaultLvalueConversion(Val).take();
+    Val = DefaultLvalueConversion(Val).get();
 
   if (Val) {
     if (Enum->isDependentType() || Val->isTypeDependent())
@@ -12253,7 +12779,7 @@
     else {
       SourceLocation ExpLoc;
       if (getLangOpts().CPlusPlus11 && Enum->isFixed() &&
-          !getLangOpts().MicrosoftMode) {
+          !getLangOpts().MSVCCompat) {
         // C++11 [dcl.enum]p5: If the underlying type is fixed, [...] the
         // constant-expression in the enumerator-definition shall be a converted
         // constant expression of the underlying type.
@@ -12262,12 +12788,12 @@
           CheckConvertedConstantExpression(Val, EltTy, EnumVal,
                                            CCEK_Enumerator);
         if (Converted.isInvalid())
-          Val = 0;
+          Val = nullptr;
         else
-          Val = Converted.take();
+          Val = Converted.get();
       } else if (!Val->isValueDependent() &&
                  !(Val = VerifyIntegerConstantExpression(Val,
-                                                         &EnumVal).take())) {
+                                                         &EnumVal).get())) {
         // C99 6.7.2.2p2: Make sure we have an integer constant expression.
       } else {
         if (Enum->isFixed()) {
@@ -12278,13 +12804,13 @@
           // we perform a non-narrowing conversion as part of converted constant
           // expression checking.
           if (!isRepresentableIntegerValue(Context, EnumVal, EltTy)) {
-            if (getLangOpts().MicrosoftMode) {
+            if (getLangOpts().MSVCCompat) {
               Diag(IdLoc, diag::ext_enumerator_too_large) << EltTy;
-              Val = ImpCastExprToType(Val, EltTy, CK_IntegralCast).take();
+              Val = ImpCastExprToType(Val, EltTy, CK_IntegralCast).get();
             } else
               Diag(IdLoc, diag::err_enumerator_too_large) << EltTy;
           } else
-            Val = ImpCastExprToType(Val, EltTy, CK_IntegralCast).take();
+            Val = ImpCastExprToType(Val, EltTy, CK_IntegralCast).get();
         } else if (getLangOpts().CPlusPlus) {
           // C++11 [dcl.enum]p5:
           //   If the underlying type is not fixed, the type of each enumerator
@@ -12305,7 +12831,7 @@
               << (EnumVal.isUnsigned() || EnumVal.isNonNegative());
           else if (!Context.hasSameType(Val->getType(), Context.IntTy)) {
             // Force the type of the expression to 'int'.
-            Val = ImpCastExprToType(Val, Context.IntTy, CK_IntegralCast).take();
+            Val = ImpCastExprToType(Val, Context.IntTy, CK_IntegralCast).get();
           }
           EltTy = Val->getType();
         }
@@ -12362,7 +12888,7 @@
               << EnumVal.toString(10)
               << EltTy;
           else
-            Diag(IdLoc, diag::warn_enumerator_too_large)
+            Diag(IdLoc, diag::ext_enumerator_increment_too_large)
               << EnumVal.toString(10);
         } else {
           EltTy = T;
@@ -12424,7 +12950,7 @@
     // Maybe we will complain about the shadowed template parameter.
     DiagnoseTemplateParameterShadow(IdLoc, PrevDecl);
     // Just pretend that we didn't see the previous declaration.
-    PrevDecl = 0;
+    PrevDecl = nullptr;
   }
 
   if (PrevDecl) {
@@ -12438,7 +12964,7 @@
       else
         Diag(IdLoc, diag::err_redefinition) << Id;
       Diag(PrevDecl->getLocation(), diag::note_previous_definition);
-      return 0;
+      return nullptr;
     }
   }
 
@@ -12540,9 +13066,7 @@
 static void CheckForDuplicateEnumValues(Sema &S, ArrayRef<Decl *> Elements,
                                         EnumDecl *Enum,
                                         QualType EnumType) {
-  if (S.Diags.getDiagnosticLevel(diag::warn_duplicate_enum_values,
-                                 Enum->getLocation()) ==
-      DiagnosticsEngine::Ignored)
+  if (S.Diags.isIgnored(diag::warn_duplicate_enum_values, Enum->getLocation()))
     return;
   // Avoid anonymous enums
   if (!Enum->getIdentifier())
@@ -12720,7 +13244,7 @@
   // The C99 rule is modified by a gcc extension 
   QualType BestPromotionType;
 
-  bool Packed = Enum->getAttr<PackedAttr>() ? true : false;
+  bool Packed = Enum->hasAttr<PackedAttr>();
   // -fshort-enums is the equivalent to specifying the packed attribute on all
   // enum definitions.
   if (LangOpts.ShortEnums)
@@ -12760,7 +13284,7 @@
         BestWidth = Context.getTargetInfo().getLongLongWidth();
 
         if (NumNegativeBits > BestWidth || NumPositiveBits >= BestWidth)
-          Diag(Enum->getLocation(), diag::warn_enum_too_large);
+          Diag(Enum->getLocation(), diag::ext_enum_too_large);
         BestType = Context.LongLongTy;
       }
     }
@@ -12851,7 +13375,7 @@
       ECD->setInitExpr(ImplicitCastExpr::Create(Context, NewTy,
                                                 CK_IntegralCast,
                                                 ECD->getInitExpr(),
-                                                /*base paths*/ 0,
+                                                /*base paths*/ nullptr,
                                                 VK_RValue));
     if (getLangOpts().CPlusPlus)
       // C++ [dcl.enum]p4: Following the closing brace of an
@@ -12865,11 +13389,6 @@
   Enum->completeDefinition(BestType, BestPromotionType,
                            NumPositiveBits, NumNegativeBits);
 
-  // If we're declaring a function, ensure this decl isn't forgotten about -
-  // it needs to go into the function scope.
-  if (InFunctionDeclarator)
-    DeclsInPrototypeScope.push_back(Enum);
-
   CheckForDuplicateEnumValues(*this, Elements, Enum, EnumType);
 
   // Now that the enum type is defined, ensure it's not been underaligned.
@@ -12889,15 +13408,54 @@
   return New;
 }
 
+static void checkModuleImportContext(Sema &S, Module *M,
+                                     SourceLocation ImportLoc,
+                                     DeclContext *DC) {
+  if (auto *LSD = dyn_cast<LinkageSpecDecl>(DC)) {
+    switch (LSD->getLanguage()) {
+    case LinkageSpecDecl::lang_c:
+      if (!M->IsExternC) {
+        S.Diag(ImportLoc, diag::err_module_import_in_extern_c)
+          << M->getFullModuleName();
+        S.Diag(LSD->getLocStart(), diag::note_module_import_in_extern_c);
+        return;
+      }
+      break;
+    case LinkageSpecDecl::lang_cxx:
+      break;
+    }
+    DC = LSD->getParent();
+  }
+
+  while (isa<LinkageSpecDecl>(DC))
+    DC = DC->getParent();
+  if (!isa<TranslationUnitDecl>(DC)) {
+    S.Diag(ImportLoc, diag::err_module_import_not_at_top_level)
+      << M->getFullModuleName() << DC;
+    S.Diag(cast<Decl>(DC)->getLocStart(),
+           diag::note_module_import_not_at_top_level)
+      << DC;
+  }
+}
+
 DeclResult Sema::ActOnModuleImport(SourceLocation AtLoc, 
                                    SourceLocation ImportLoc, 
                                    ModuleIdPath Path) {
-  Module *Mod = PP.getModuleLoader().loadModule(ImportLoc, Path, 
-                                                Module::AllVisible,
-                                                /*IsIncludeDirective=*/false);
+  Module *Mod =
+      getModuleLoader().loadModule(ImportLoc, Path, Module::AllVisible,
+                                   /*IsIncludeDirective=*/false);
   if (!Mod)
     return true;
-  
+
+  checkModuleImportContext(*this, Mod, ImportLoc, CurContext);
+
+  // FIXME: we should support importing a submodule within a different submodule
+  // of the same top-level module. Until we do, make it an error rather than
+  // silently ignoring the import.
+  if (Mod->getTopLevelModuleName() == getLangOpts().CurrentModule)
+    Diag(ImportLoc, diag::err_module_self_import)
+        << Mod->getFullModuleName() << getLangOpts().CurrentModule;
+
   SmallVector<SourceLocation, 2> IdentifierLocs;
   Module *ModCheck = Mod;
   for (unsigned I = 0, N = Path.size(); I != N; ++I) {
@@ -12919,12 +13477,19 @@
 }
 
 void Sema::ActOnModuleInclude(SourceLocation DirectiveLoc, Module *Mod) {
+  checkModuleImportContext(*this, Mod, DirectiveLoc, CurContext);
+
   // FIXME: Should we synthesize an ImportDecl here?
-  PP.getModuleLoader().makeModuleVisible(Mod, Module::AllVisible, DirectiveLoc,
-                                         /*Complain=*/true);
+  getModuleLoader().makeModuleVisible(Mod, Module::AllVisible, DirectiveLoc,
+                                      /*Complain=*/true);
 }
 
-void Sema::createImplicitModuleImport(SourceLocation Loc, Module *Mod) {
+void Sema::createImplicitModuleImportForErrorRecovery(SourceLocation Loc,
+                                                      Module *Mod) {
+  // Bail if we're not allowed to implicitly import a module here.
+  if (isSFINAEContext() || !getLangOpts().ModulesErrorRecovery)
+    return;
+
   // Create the implicit import declaration.
   TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl();
   ImportDecl *ImportD = ImportDecl::CreateImplicit(getASTContext(), TU,
@@ -12933,8 +13498,8 @@
   Consumer.HandleImplicitImportDecl(ImportD);
 
   // Make the module visible.
-  PP.getModuleLoader().makeModuleVisible(Mod, Module::AllVisible, Loc,
-                                         /*Complain=*/false);
+  getModuleLoader().makeModuleVisible(Mod, Module::AllVisible, Loc,
+                                      /*Complain=*/false);
 }
 
 void Sema::ActOnPragmaRedefineExtname(IdentifierInfo* Name,
@@ -12944,8 +13509,8 @@
                                       SourceLocation AliasNameLoc) {
   Decl *PrevDecl = LookupSingleName(TUScope, Name, NameLoc,
                                     LookupOrdinaryName);
-  AsmLabelAttr *Attr =
-     ::new (Context) AsmLabelAttr(AliasNameLoc, Context, AliasName->getName());
+  AsmLabelAttr *Attr = ::new (Context) AsmLabelAttr(AliasNameLoc, Context,
+                                                    AliasName->getName(), 0);
 
   if (PrevDecl) 
     PrevDecl->addAttr(Attr);
@@ -12960,11 +13525,11 @@
   Decl *PrevDecl = LookupSingleName(TUScope, Name, NameLoc, LookupOrdinaryName);
 
   if (PrevDecl) {
-    PrevDecl->addAttr(::new (Context) WeakAttr(PragmaLoc, Context));
+    PrevDecl->addAttr(WeakAttr::CreateImplicit(Context, PragmaLoc));
   } else {
     (void)WeakUndeclaredIdentifiers.insert(
       std::pair<IdentifierInfo*,WeakInfo>
-        (Name, WeakInfo((IdentifierInfo*)0, NameLoc)));
+        (Name, WeakInfo((IdentifierInfo*)nullptr, NameLoc)));
   }
 }
 
@@ -12993,5 +13558,22 @@
 
 AvailabilityResult Sema::getCurContextAvailability() const {
   const Decl *D = cast<Decl>(getCurObjCLexicalContext());
+  // If we are within an Objective-C method, we should consult
+  // both the availability of the method as well as the
+  // enclosing class.  If the class is (say) deprecated,
+  // the entire method is considered deprecated from the
+  // purpose of checking if the current context is deprecated.
+  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
+    AvailabilityResult R = MD->getAvailability();
+    if (R != AR_Available)
+      return R;
+    D = MD->getClassInterface();
+  }
+  // If we are within an Objective-c @implementation, it
+  // gets the same availability context as the @interface.
+  else if (const ObjCImplementationDecl *ID =
+            dyn_cast<ObjCImplementationDecl>(D)) {
+    D = ID->getClassInterface();
+  }
   return D->getAvailability();
 }
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index a1f3856..61683cd 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -12,13 +12,13 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Sema/SemaInternal.h"
-#include "TargetAttributesSema.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
 #include "clang/AST/Mangle.h"
 #include "clang/Basic/CharInfo.h"
 #include "clang/Basic/SourceManager.h"
@@ -32,84 +32,23 @@
 using namespace clang;
 using namespace sema;
 
-/// These constants match the enumerated choices of
-/// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type.
-enum AttributeDeclKind {
-  ExpectedFunction,
-  ExpectedUnion,
-  ExpectedVariableOrFunction,
-  ExpectedFunctionOrMethod,
-  ExpectedParameter,
-  ExpectedFunctionMethodOrBlock,
-  ExpectedFunctionMethodOrClass,
-  ExpectedFunctionMethodOrParameter,
-  ExpectedClass,
-  ExpectedVariable,
-  ExpectedMethod,
-  ExpectedVariableFunctionOrLabel,
-  ExpectedFieldOrGlobalVar,
-  ExpectedStruct,
-  ExpectedVariableFunctionOrTag,
-  ExpectedTLSVar,
-  ExpectedVariableOrField,
-  ExpectedVariableFieldOrTag,
-  ExpectedTypeOrNamespace,
-  ExpectedObjectiveCInterface,
-  ExpectedMethodOrProperty
-};
+namespace AttributeLangSupport {
+  enum LANG {
+    C,
+    Cpp,
+    ObjC
+  };
+}
 
 //===----------------------------------------------------------------------===//
 //  Helper functions
 //===----------------------------------------------------------------------===//
 
-static const FunctionType *getFunctionType(const Decl *D,
-                                           bool blocksToo = true) {
-  QualType Ty;
-  if (const ValueDecl *decl = dyn_cast<ValueDecl>(D))
-    Ty = decl->getType();
-  else if (const FieldDecl *decl = dyn_cast<FieldDecl>(D))
-    Ty = decl->getType();
-  else if (const TypedefNameDecl* decl = dyn_cast<TypedefNameDecl>(D))
-    Ty = decl->getUnderlyingType();
-  else
-    return 0;
-
-  if (Ty->isFunctionPointerType())
-    Ty = Ty->getAs<PointerType>()->getPointeeType();
-  else if (blocksToo && Ty->isBlockPointerType())
-    Ty = Ty->getAs<BlockPointerType>()->getPointeeType();
-
-  return Ty->getAs<FunctionType>();
-}
-
-// FIXME: We should provide an abstraction around a method or function
-// to provide the following bits of information.
-
-/// isFunction - Return true if the given decl has function
-/// type (function or function-typed variable).
-static bool isFunction(const Decl *D) {
-  return getFunctionType(D, false) != NULL;
-}
-
 /// isFunctionOrMethod - Return true if the given decl has function
 /// type (function or function-typed variable) or an Objective-C
 /// method.
 static bool isFunctionOrMethod(const Decl *D) {
-  return isFunction(D) || isa<ObjCMethodDecl>(D);
-}
-
-/// isFunctionOrMethodOrBlock - Return true if the given decl has function
-/// type (function or function-typed variable) or an Objective-C
-/// method or a block.
-static bool isFunctionOrMethodOrBlock(const Decl *D) {
-  if (isFunctionOrMethod(D))
-    return true;
-  // check for block is more involved.
-  if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
-    QualType Ty = V->getType();
-    return Ty->isBlockPointerType();
-  }
-  return isa<BlockDecl>(D);
+  return (D->getFunctionType() != nullptr) || isa<ObjCMethodDecl>(D);
 }
 
 /// Return true if the given decl has a declarator that should have
@@ -124,42 +63,39 @@
 /// information. This decl should have already passed
 /// isFunctionOrMethod or isFunctionOrMethodOrBlock.
 static bool hasFunctionProto(const Decl *D) {
-  if (const FunctionType *FnTy = getFunctionType(D))
+  if (const FunctionType *FnTy = D->getFunctionType())
     return isa<FunctionProtoType>(FnTy);
-  else {
-    assert(isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D));
-    return true;
-  }
+  return isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D);
 }
 
-/// getFunctionOrMethodNumArgs - Return number of function or method
-/// arguments. It is an error to call this on a K&R function (use
+/// getFunctionOrMethodNumParams - Return number of function or method
+/// parameters. It is an error to call this on a K&R function (use
 /// hasFunctionProto first).
-static unsigned getFunctionOrMethodNumArgs(const Decl *D) {
-  if (const FunctionType *FnTy = getFunctionType(D))
-    return cast<FunctionProtoType>(FnTy)->getNumArgs();
+static unsigned getFunctionOrMethodNumParams(const Decl *D) {
+  if (const FunctionType *FnTy = D->getFunctionType())
+    return cast<FunctionProtoType>(FnTy)->getNumParams();
   if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
     return BD->getNumParams();
   return cast<ObjCMethodDecl>(D)->param_size();
 }
 
-static QualType getFunctionOrMethodArgType(const Decl *D, unsigned Idx) {
-  if (const FunctionType *FnTy = getFunctionType(D))
-    return cast<FunctionProtoType>(FnTy)->getArgType(Idx);
+static QualType getFunctionOrMethodParamType(const Decl *D, unsigned Idx) {
+  if (const FunctionType *FnTy = D->getFunctionType())
+    return cast<FunctionProtoType>(FnTy)->getParamType(Idx);
   if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
     return BD->getParamDecl(Idx)->getType();
 
-  return cast<ObjCMethodDecl>(D)->param_begin()[Idx]->getType();
+  return cast<ObjCMethodDecl>(D)->parameters()[Idx]->getType();
 }
 
 static QualType getFunctionOrMethodResultType(const Decl *D) {
-  if (const FunctionType *FnTy = getFunctionType(D))
-    return cast<FunctionProtoType>(FnTy)->getResultType();
-  return cast<ObjCMethodDecl>(D)->getResultType();
+  if (const FunctionType *FnTy = D->getFunctionType())
+    return cast<FunctionType>(FnTy)->getReturnType();
+  return cast<ObjCMethodDecl>(D)->getReturnType();
 }
 
 static bool isFunctionOrMethodVariadic(const Decl *D) {
-  if (const FunctionType *FnTy = getFunctionType(D)) {
+  if (const FunctionType *FnTy = D->getFunctionType()) {
     const FunctionProtoType *proto = cast<FunctionProtoType>(FnTy);
     return proto->isVariadic();
   } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
@@ -225,30 +161,63 @@
   return true;
 }
 
-
 /// \brief Check if the attribute has at least as many args as Num. May
 /// output an error.
 static bool checkAttributeAtLeastNumArgs(Sema &S, const AttributeList &Attr,
                                          unsigned Num) {
   if (getNumAttributeArgs(Attr) < Num) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_too_few_arguments) << Num;
+    S.Diag(Attr.getLoc(), diag::err_attribute_too_few_arguments)
+      << Attr.getName() << Num;
     return false;
   }
 
   return true;
 }
 
-/// \brief Check if IdxExpr is a valid argument index for a function or
+/// \brief If Expr is a valid integer constant, get the value of the integer
+/// expression and return success or failure. May output an error.
+static bool checkUInt32Argument(Sema &S, const AttributeList &Attr,
+                                const Expr *Expr, uint32_t &Val,
+                                unsigned Idx = UINT_MAX) {
+  llvm::APSInt I(32);
+  if (Expr->isTypeDependent() || Expr->isValueDependent() ||
+      !Expr->isIntegerConstantExpr(I, S.Context)) {
+    if (Idx != UINT_MAX)
+      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
+        << Attr.getName() << Idx << AANT_ArgumentIntegerConstant
+        << Expr->getSourceRange();
+    else
+      S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
+        << Attr.getName() << AANT_ArgumentIntegerConstant
+        << Expr->getSourceRange();
+    return false;
+  }
+  Val = (uint32_t)I.getZExtValue();
+  return true;
+}
+
+/// \brief Diagnose mutually exclusive attributes when present on a given
+/// declaration. Returns true if diagnosed.
+template <typename AttrTy>
+static bool checkAttrMutualExclusion(Sema &S, Decl *D,
+                                     const AttributeList &Attr) {
+  if (AttrTy *A = D->getAttr<AttrTy>()) {
+    S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
+      << Attr.getName() << A;
+    return true;
+  }
+  return false;
+}
+
+/// \brief Check if IdxExpr is a valid parameter index for a function or
 /// instance method D.  May output an error.
 ///
 /// \returns true if IdxExpr is a valid index.
-static bool checkFunctionOrMethodArgumentIndex(Sema &S, const Decl *D,
-                                               StringRef AttrName,
-                                               SourceLocation AttrLoc,
-                                               unsigned AttrArgNum,
-                                               const Expr *IdxExpr,
-                                               uint64_t &Idx)
-{
+static bool checkFunctionOrMethodParameterIndex(Sema &S, const Decl *D,
+                                                const AttributeList &Attr,
+                                                unsigned AttrArgNum,
+                                                const Expr *IdxExpr,
+                                                uint64_t &Idx) {
   assert(isFunctionOrMethod(D));
 
   // In C++ the implicit 'this' function parameter also counts.
@@ -256,30 +225,30 @@
   bool HP = hasFunctionProto(D);
   bool HasImplicitThisParam = isInstanceMethod(D);
   bool IV = HP && isFunctionOrMethodVariadic(D);
-  unsigned NumArgs = (HP ? getFunctionOrMethodNumArgs(D) : 0) +
-                     HasImplicitThisParam;
+  unsigned NumParams =
+      (HP ? getFunctionOrMethodNumParams(D) : 0) + HasImplicitThisParam;
 
   llvm::APSInt IdxInt;
   if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
       !IdxExpr->isIntegerConstantExpr(IdxInt, S.Context)) {
-    std::string Name = std::string("'") + AttrName.str() + std::string("'");
-    S.Diag(AttrLoc, diag::err_attribute_argument_n_type) << Name.c_str()
-      << AttrArgNum << AANT_ArgumentIntegerConstant << IdxExpr->getSourceRange();
+    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
+      << Attr.getName() << AttrArgNum << AANT_ArgumentIntegerConstant
+      << IdxExpr->getSourceRange();
     return false;
   }
 
   Idx = IdxInt.getLimitedValue();
-  if (Idx < 1 || (!IV && Idx > NumArgs)) {
-    S.Diag(AttrLoc, diag::err_attribute_argument_out_of_bounds)
-      << AttrName << AttrArgNum << IdxExpr->getSourceRange();
+  if (Idx < 1 || (!IV && Idx > NumParams)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
+      << Attr.getName() << AttrArgNum << IdxExpr->getSourceRange();
     return false;
   }
   Idx--; // Convert to zero-based.
   if (HasImplicitThisParam) {
     if (Idx == 0) {
-      S.Diag(AttrLoc,
+      S.Diag(Attr.getLoc(),
              diag::err_attribute_invalid_implicit_this_argument)
-        << AttrName << IdxExpr->getSourceRange();
+        << Attr.getName() << IdxExpr->getSourceRange();
       return false;
     }
     --Idx;
@@ -324,17 +293,13 @@
   return true;
 }
 
-///
-/// \brief Check if passed in Decl is a field or potentially shared global var
-/// \return true if the Decl is a field or potentially shared global variable
-///
-static bool mayBeSharedVariable(const Decl *D) {
-  if (isa<FieldDecl>(D))
-    return true;
-  if (const VarDecl *vd = dyn_cast<VarDecl>(D))
-    return vd->hasGlobalStorage() && !vd->getTLSKind();
-
-  return false;
+/// \brief Applies the given attribute to the Decl without performing any
+/// additional semantic checking.
+template <typename AttrType>
+static void handleSimpleAttribute(Sema &S, Decl *D,
+                                  const AttributeList &Attr) {
+  D->addAttr(::new (S.Context) AttrType(Attr.getRange(), S.Context,
+                                        Attr.getAttributeSpellingListIndex()));
 }
 
 /// \brief Check if the passed-in expression is of type int or bool.
@@ -365,28 +330,24 @@
 /// \return true if the Decl is a pointer type; false otherwise
 static bool threadSafetyCheckIsPointer(Sema &S, const Decl *D,
                                        const AttributeList &Attr) {
-  if (const ValueDecl *vd = dyn_cast<ValueDecl>(D)) {
-    QualType QT = vd->getType();
-    if (QT->isAnyPointerType())
+  const ValueDecl *vd = cast<ValueDecl>(D);
+  QualType QT = vd->getType();
+  if (QT->isAnyPointerType())
+    return true;
+
+  if (const RecordType *RT = QT->getAs<RecordType>()) {
+    // If it's an incomplete type, it could be a smart pointer; skip it.
+    // (We don't want to force template instantiation if we can avoid it,
+    // since that would alter the order in which templates are instantiated.)
+    if (RT->isIncompleteType())
       return true;
 
-    if (const RecordType *RT = QT->getAs<RecordType>()) {
-      // If it's an incomplete type, it could be a smart pointer; skip it.
-      // (We don't want to force template instantiation if we can avoid it,
-      // since that would alter the order in which templates are instantiated.)
-      if (RT->isIncompleteType())
-        return true;
-
-      if (threadSafetyCheckIsSmartPointer(S, RT))
-        return true;
-    }
-
-    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_pointer)
-      << Attr.getName()->getName() << QT;
-  } else {
-    S.Diag(Attr.getLoc(), diag::err_attribute_can_be_applied_only_to_value_decl)
-      << Attr.getName();
+    if (threadSafetyCheckIsSmartPointer(S, RT))
+      return true;
   }
+
+  S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_pointer)
+    << Attr.getName() << QT;
   return false;
 }
 
@@ -400,68 +361,101 @@
   if (const PointerType *PT = QT->getAs<PointerType>())
     return PT->getPointeeType()->getAs<RecordType>();
 
-  return 0;
+  return nullptr;
 }
 
+static bool checkRecordTypeForCapability(Sema &S, QualType Ty) {
+  const RecordType *RT = getRecordType(Ty);
 
-static bool checkBaseClassIsLockableCallback(const CXXBaseSpecifier *Specifier,
-                                             CXXBasePath &Path, void *Unused) {
-  const RecordType *RT = Specifier->getType()->getAs<RecordType>();
-  if (RT->getDecl()->getAttr<LockableAttr>())
+  if (!RT)
+    return false;
+
+  // Don't check for the capability if the class hasn't been defined yet.
+  if (RT->isIncompleteType())
     return true;
+
+  // Allow smart pointers to be used as capability objects.
+  // FIXME -- Check the type that the smart pointer points to.
+  if (threadSafetyCheckIsSmartPointer(S, RT))
+    return true;
+
+  // Check if the record itself has a capability.
+  RecordDecl *RD = RT->getDecl();
+  if (RD->hasAttr<CapabilityAttr>())
+    return true;
+
+  // Else check if any base classes have a capability.
+  if (CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
+    CXXBasePaths BPaths(false, false);
+    if (CRD->lookupInBases([](const CXXBaseSpecifier *BS, CXXBasePath &P,
+      void *) {
+      return BS->getType()->getAs<RecordType>()
+        ->getDecl()->hasAttr<CapabilityAttr>();
+    }, nullptr, BPaths))
+      return true;
+  }
   return false;
 }
 
+static bool checkTypedefTypeForCapability(QualType Ty) {
+  const auto *TD = Ty->getAs<TypedefType>();
+  if (!TD)
+    return false;
 
-/// \brief Thread Safety Analysis: Checks that the passed in RecordType
-/// resolves to a lockable object.
-static void checkForLockableRecord(Sema &S, Decl *D, const AttributeList &Attr,
-                                   QualType Ty) {
-  const RecordType *RT = getRecordType(Ty);
+  TypedefNameDecl *TN = TD->getDecl();
+  if (!TN)
+    return false;
 
-  // Warn if could not get record type for this argument.
-  if (!RT) {
-    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_class)
-      << Attr.getName() << Ty.getAsString();
-    return;
-  }
-
-  // Don't check for lockable if the class hasn't been defined yet.
-  if (RT->isIncompleteType())
-    return;
-
-  // Allow smart pointers to be used as lockable objects.
-  // FIXME -- Check the type that the smart pointer points to.
-  if (threadSafetyCheckIsSmartPointer(S, RT))
-    return;
-
-  // Check if the type is lockable.
-  RecordDecl *RD = RT->getDecl();
-  if (RD->getAttr<LockableAttr>())
-    return;
-
-  // Else check if any base classes are lockable.
-  if (CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
-    CXXBasePaths BPaths(false, false);
-    if (CRD->lookupInBases(checkBaseClassIsLockableCallback, 0, BPaths))
-      return;
-  }
-
-  S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_lockable)
-    << Attr.getName() << Ty.getAsString();
+  return TN->hasAttr<CapabilityAttr>();
 }
 
-/// \brief Thread Safety Analysis: Checks that all attribute arguments, starting
-/// from Sidx, resolve to a lockable object.
+static bool typeHasCapability(Sema &S, QualType Ty) {
+  if (checkTypedefTypeForCapability(Ty))
+    return true;
+
+  if (checkRecordTypeForCapability(S, Ty))
+    return true;
+
+  return false;
+}
+
+static bool isCapabilityExpr(Sema &S, const Expr *Ex) {
+  // Capability expressions are simple expressions involving the boolean logic
+  // operators &&, || or !, a simple DeclRefExpr, CastExpr or a ParenExpr. Once
+  // a DeclRefExpr is found, its type should be checked to determine whether it
+  // is a capability or not.
+
+  if (const auto *E = dyn_cast<DeclRefExpr>(Ex))
+    return typeHasCapability(S, E->getType());
+  else if (const auto *E = dyn_cast<CastExpr>(Ex))
+    return isCapabilityExpr(S, E->getSubExpr());
+  else if (const auto *E = dyn_cast<ParenExpr>(Ex))
+    return isCapabilityExpr(S, E->getSubExpr());
+  else if (const auto *E = dyn_cast<UnaryOperator>(Ex)) {
+    if (E->getOpcode() == UO_LNot)
+      return isCapabilityExpr(S, E->getSubExpr());
+    return false;
+  } else if (const auto *E = dyn_cast<BinaryOperator>(Ex)) {
+    if (E->getOpcode() == BO_LAnd || E->getOpcode() == BO_LOr)
+      return isCapabilityExpr(S, E->getLHS()) &&
+             isCapabilityExpr(S, E->getRHS());
+    return false;
+  }
+
+  return false;
+}
+
+/// \brief Checks that all attribute arguments, starting from Sidx, resolve to
+/// a capability object.
 /// \param Sidx The attribute argument index to start checking with.
 /// \param ParamIdxOk Whether an argument can be indexing into a function
 /// parameter list.
-static void checkAttrArgsAreLockableObjs(Sema &S, Decl *D,
-                                         const AttributeList &Attr,
-                                         SmallVectorImpl<Expr*> &Args,
-                                         int Sidx = 0,
-                                         bool ParamIdxOk = false) {
-  for(unsigned Idx = Sidx; Idx < Attr.getNumArgs(); ++Idx) {
+static void checkAttrArgsAreCapabilityObjs(Sema &S, Decl *D,
+                                           const AttributeList &Attr,
+                                           SmallVectorImpl<Expr *> &Args,
+                                           int Sidx = 0,
+                                           bool ParamIdxOk = false) {
+  for (unsigned Idx = Sidx; Idx < Attr.getNumArgs(); ++Idx) {
     Expr *ArgExp = Attr.getArgAsExpr(Idx);
 
     if (ArgExp->isTypeDependent()) {
@@ -497,7 +491,7 @@
           if (DRE->getDecl()->isCXXInstanceMember())
             ArgTy = DRE->getDecl()->getType();
 
-    // First see if we can just cast to record type, or point to record type.
+    // First see if we can just cast to record type, or pointer to record type.
     const RecordType *RT = getRecordType(ArgTy);
 
     // Now check if we index into a record type function param.
@@ -518,7 +512,13 @@
       }
     }
 
-    checkForLockableRecord(S, D, Attr, ArgTy);
+    // If the type does not have a capability, see if the components of the
+    // expression have capabilities. This allows for writing C code where the
+    // capability may be on the type, and the expression is a capability
+    // boolean logic expression. Eg) requires_capability(A || B && !C)
+    if (!typeHasCapability(S, ArgTy) && !isCapabilityExpr(S, ArgExp))
+      S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_lockable)
+          << Attr.getName() << ArgTy;
 
     Args.push_back(ArgExp);
   }
@@ -532,38 +532,8 @@
 // least add some helper functions to check most argument patterns (#
 // and types of args).
 
-enum ThreadAttributeDeclKind {
-  ThreadExpectedFieldOrGlobalVar,
-  ThreadExpectedFunctionOrMethod,
-  ThreadExpectedClassOrStruct
-};
-
-static bool checkGuardedVarAttrCommon(Sema &S, Decl *D,
-                                      const AttributeList &Attr) {
-  // D must be either a member field or global (potentially shared) variable.
-  if (!mayBeSharedVariable(D)) {
-    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
-      << Attr.getName() << ThreadExpectedFieldOrGlobalVar;
-    return false;
-  }
-
-  return true;
-}
-
-static void handleGuardedVarAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  if (!checkGuardedVarAttrCommon(S, D, Attr))
-    return;
-
-  D->addAttr(::new (S.Context)
-             GuardedVarAttr(Attr.getRange(), S.Context,
-                            Attr.getAttributeSpellingListIndex()));
-}
-
 static void handlePtGuardedVarAttr(Sema &S, Decl *D,
                                    const AttributeList &Attr) {
-  if (!checkGuardedVarAttrCommon(S, D, Attr))
-    return;
-
   if (!threadSafetyCheckIsPointer(S, D, Attr))
     return;
 
@@ -575,16 +545,9 @@
 static bool checkGuardedByAttrCommon(Sema &S, Decl *D,
                                      const AttributeList &Attr,
                                      Expr* &Arg) {
-  // D must be either a member field or global (potentially shared) variable.
-  if (!mayBeSharedVariable(D)) {
-    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
-      << Attr.getName() << ThreadExpectedFieldOrGlobalVar;
-    return false;
-  }
-
   SmallVector<Expr*, 1> Args;
   // check that all arguments are lockable objects
-  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
+  checkAttrArgsAreCapabilityObjs(S, D, Attr, Args);
   unsigned Size = Args.size();
   if (Size != 1)
     return false;
@@ -595,16 +558,17 @@
 }
 
 static void handleGuardedByAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  Expr *Arg = 0;
+  Expr *Arg = nullptr;
   if (!checkGuardedByAttrCommon(S, D, Attr, Arg))
     return;
 
-  D->addAttr(::new (S.Context) GuardedByAttr(Attr.getRange(), S.Context, Arg));
+  D->addAttr(::new (S.Context) GuardedByAttr(Attr.getRange(), S.Context, Arg,
+                                        Attr.getAttributeSpellingListIndex()));
 }
 
 static void handlePtGuardedByAttr(Sema &S, Decl *D,
                                   const AttributeList &Attr) {
-  Expr *Arg = 0;
+  Expr *Arg = nullptr;
   if (!checkGuardedByAttrCommon(S, D, Attr, Arg))
     return;
 
@@ -612,85 +576,8 @@
     return;
 
   D->addAttr(::new (S.Context) PtGuardedByAttr(Attr.getRange(),
-                                               S.Context, Arg));
-}
-
-static bool checkLockableAttrCommon(Sema &S, Decl *D,
-                                    const AttributeList &Attr) {
-  // FIXME: Lockable structs for C code.
-  if (!isa<RecordDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
-      << Attr.getName() << ThreadExpectedClassOrStruct;
-    return false;
-  }
-
-  return true;
-}
-
-static void handleLockableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  if (!checkLockableAttrCommon(S, D, Attr))
-    return;
-
-  D->addAttr(::new (S.Context) LockableAttr(Attr.getRange(), S.Context));
-}
-
-static void handleScopedLockableAttr(Sema &S, Decl *D,
-                             const AttributeList &Attr) {
-  if (!checkLockableAttrCommon(S, D, Attr))
-    return;
-
-  D->addAttr(::new (S.Context)
-             ScopedLockableAttr(Attr.getRange(), S.Context,
-                                Attr.getAttributeSpellingListIndex()));
-}
-
-static void handleNoThreadSafetyAnalysis(Sema &S, Decl *D,
-                                         const AttributeList &Attr) {
-  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
-      << Attr.getName() << ThreadExpectedFunctionOrMethod;
-    return;
-  }
-
-  D->addAttr(::new (S.Context) NoThreadSafetyAnalysisAttr(Attr.getRange(),
-                                                          S.Context));
-}
-
-static void handleNoSanitizeAddressAttr(Sema &S, Decl *D,
-                                      const AttributeList &Attr) {
-  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
-      << Attr.getName() << ExpectedFunctionOrMethod;
-    return;
-  }
-
-  D->addAttr(::new (S.Context)
-             NoSanitizeAddressAttr(Attr.getRange(), S.Context,
-                                   Attr.getAttributeSpellingListIndex()));
-}
-
-static void handleNoSanitizeMemory(Sema &S, Decl *D,
-                                   const AttributeList &Attr) {
-  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
-      << Attr.getName() << ExpectedFunctionOrMethod;
-    return;
-  }
-
-  D->addAttr(::new (S.Context) NoSanitizeMemoryAttr(Attr.getRange(),
-                                                         S.Context));
-}
-
-static void handleNoSanitizeThread(Sema &S, Decl *D,
-                                   const AttributeList &Attr) {
-  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
-      << Attr.getName() << ExpectedFunctionOrMethod;
-    return;
-  }
-
-  D->addAttr(::new (S.Context) NoSanitizeThreadAttr(Attr.getRange(),
-                                                    S.Context));
+                                               S.Context, Arg,
+                                        Attr.getAttributeSpellingListIndex()));
 }
 
 static bool checkAcquireOrderAttrCommon(Sema &S, Decl *D,
@@ -699,19 +586,11 @@
   if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
     return false;
 
-  // D must be either a member field or global (potentially shared) variable.
-  ValueDecl *VD = dyn_cast<ValueDecl>(D);
-  if (!VD || !mayBeSharedVariable(D)) {
-    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
-      << Attr.getName() << ThreadExpectedFieldOrGlobalVar;
-    return false;
-  }
-
   // Check that this attribute only applies to lockable types.
-  QualType QT = VD->getType();
+  QualType QT = cast<ValueDecl>(D)->getType();
   if (!QT->isDependentType()) {
     const RecordType *RT = getRecordType(QT);
-    if (!RT || !RT->getDecl()->getAttr<LockableAttr>()) {
+    if (!RT || !RT->getDecl()->hasAttr<CapabilityAttr>()) {
       S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_lockable)
         << Attr.getName();
       return false;
@@ -719,7 +598,7 @@
   }
 
   // Check that all arguments are lockable objects.
-  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
+  checkAttrArgsAreCapabilityObjs(S, D, Attr, Args);
   if (Args.empty())
     return false;
 
@@ -756,47 +635,12 @@
                                    const AttributeList &Attr,
                                    SmallVectorImpl<Expr *> &Args) {
   // zero or more arguments ok
-
-  // check that the attribute is applied to a function
-  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
-      << Attr.getName() << ThreadExpectedFunctionOrMethod;
-    return false;
-  }
-
   // check that all arguments are lockable objects
-  checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true);
+  checkAttrArgsAreCapabilityObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true);
 
   return true;
 }
 
-static void handleSharedLockFunctionAttr(Sema &S, Decl *D,
-                                         const AttributeList &Attr) {
-  SmallVector<Expr*, 1> Args;
-  if (!checkLockFunAttrCommon(S, D, Attr, Args))
-    return;
-
-  unsigned Size = Args.size();
-  Expr **StartArg = Size == 0 ? 0 : &Args[0];
-  D->addAttr(::new (S.Context)
-             SharedLockFunctionAttr(Attr.getRange(), S.Context, StartArg, Size,
-                                    Attr.getAttributeSpellingListIndex()));
-}
-
-static void handleExclusiveLockFunctionAttr(Sema &S, Decl *D,
-                                            const AttributeList &Attr) {
-  SmallVector<Expr*, 1> Args;
-  if (!checkLockFunAttrCommon(S, D, Attr, Args))
-    return;
-
-  unsigned Size = Args.size();
-  Expr **StartArg = Size == 0 ? 0 : &Args[0];
-  D->addAttr(::new (S.Context)
-             ExclusiveLockFunctionAttr(Attr.getRange(), S.Context,
-                                       StartArg, Size,
-                                       Attr.getAttributeSpellingListIndex()));
-}
-
 static void handleAssertSharedLockAttr(Sema &S, Decl *D,
                                        const AttributeList &Attr) {
   SmallVector<Expr*, 1> Args;
@@ -804,7 +648,7 @@
     return;
 
   unsigned Size = Args.size();
-  Expr **StartArg = Size == 0 ? 0 : &Args[0];
+  Expr **StartArg = Size == 0 ? nullptr : &Args[0];
   D->addAttr(::new (S.Context)
              AssertSharedLockAttr(Attr.getRange(), S.Context, StartArg, Size,
                                   Attr.getAttributeSpellingListIndex()));
@@ -817,7 +661,7 @@
     return;
 
   unsigned Size = Args.size();
-  Expr **StartArg = Size == 0 ? 0 : &Args[0];
+  Expr **StartArg = Size == 0 ? nullptr : &Args[0];
   D->addAttr(::new (S.Context)
              AssertExclusiveLockAttr(Attr.getRange(), S.Context,
                                      StartArg, Size,
@@ -831,12 +675,6 @@
   if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
     return false;
 
-  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
-      << Attr.getName() << ThreadExpectedFunctionOrMethod;
-    return false;
-  }
-
   if (!isIntOrBool(Attr.getArgAsExpr(0))) {
     S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
       << Attr.getName() << 1 << AANT_ArgumentIntOrBool;
@@ -844,7 +682,7 @@
   }
 
   // check that all arguments are lockable objects
-  checkAttrArgsAreLockableObjs(S, D, Attr, Args, 1);
+  checkAttrArgsAreCapabilityObjs(S, D, Attr, Args, 1);
 
   return true;
 }
@@ -875,84 +713,11 @@
                                           Attr.getAttributeSpellingListIndex()));
 }
 
-static bool checkLocksRequiredCommon(Sema &S, Decl *D,
-                                     const AttributeList &Attr,
-                                     SmallVectorImpl<Expr *> &Args) {
-  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
-    return false;
-
-  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
-      << Attr.getName() << ThreadExpectedFunctionOrMethod;
-    return false;
-  }
-
-  // check that all arguments are lockable objects
-  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
-  if (Args.empty())
-    return false;
-
-  return true;
-}
-
-static void handleExclusiveLocksRequiredAttr(Sema &S, Decl *D,
-                                             const AttributeList &Attr) {
-  SmallVector<Expr*, 1> Args;
-  if (!checkLocksRequiredCommon(S, D, Attr, Args))
-    return;
-
-  Expr **StartArg = &Args[0];
-  D->addAttr(::new (S.Context)
-             ExclusiveLocksRequiredAttr(Attr.getRange(), S.Context,
-                                        StartArg, Args.size(),
-                                        Attr.getAttributeSpellingListIndex()));
-}
-
-static void handleSharedLocksRequiredAttr(Sema &S, Decl *D,
-                                          const AttributeList &Attr) {
-  SmallVector<Expr*, 1> Args;
-  if (!checkLocksRequiredCommon(S, D, Attr, Args))
-    return;
-
-  Expr **StartArg = &Args[0];
-  D->addAttr(::new (S.Context)
-             SharedLocksRequiredAttr(Attr.getRange(), S.Context,
-                                     StartArg, Args.size(),
-                                     Attr.getAttributeSpellingListIndex()));
-}
-
-static void handleUnlockFunAttr(Sema &S, Decl *D,
-                                const AttributeList &Attr) {
-  // zero or more arguments ok
-
-  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
-      << Attr.getName() << ThreadExpectedFunctionOrMethod;
-    return;
-  }
-
-  // check that all arguments are lockable objects
-  SmallVector<Expr*, 1> Args;
-  checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true);
-  unsigned Size = Args.size();
-  Expr **StartArg = Size == 0 ? 0 : &Args[0];
-
-  D->addAttr(::new (S.Context)
-             UnlockFunctionAttr(Attr.getRange(), S.Context, StartArg, Size,
-                                Attr.getAttributeSpellingListIndex()));
-}
-
 static void handleLockReturnedAttr(Sema &S, Decl *D,
                                    const AttributeList &Attr) {
-  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
-      << Attr.getName() << ThreadExpectedFunctionOrMethod;
-    return;
-  }
-
   // check that the argument is lockable object
   SmallVector<Expr*, 1> Args;
-  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
+  checkAttrArgsAreCapabilityObjs(S, D, Attr, Args);
   unsigned Size = Args.size();
   if (Size == 0)
     return;
@@ -967,15 +732,9 @@
   if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
     return;
 
-  if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_wrong_decl_type)
-      << Attr.getName() << ThreadExpectedFunctionOrMethod;
-    return;
-  }
-
   // check that all arguments are lockable objects
   SmallVector<Expr*, 1> Args;
-  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
+  checkAttrArgsAreCapabilityObjs(S, D, Attr, Args);
   unsigned Size = Args.size();
   if (Size == 0)
     return;
@@ -986,6 +745,34 @@
                                Attr.getAttributeSpellingListIndex()));
 }
 
+static void handleEnableIfAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+  Expr *Cond = Attr.getArgAsExpr(0);
+  if (!Cond->isTypeDependent()) {
+    ExprResult Converted = S.PerformContextuallyConvertToBool(Cond);
+    if (Converted.isInvalid())
+      return;
+    Cond = Converted.get();
+  }
+
+  StringRef Msg;
+  if (!S.checkStringLiteralArgumentAttr(Attr, 1, Msg))
+    return;
+
+  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);
+    for (int I = 0, N = Diags.size(); I != N; ++I)
+      S.Diag(Diags[I].first, Diags[I].second);
+    return;
+  }
+
+  D->addAttr(::new (S.Context)
+             EnableIfAttr(Attr.getRange(), S.Context, Cond, Msg,
+                          Attr.getAttributeSpellingListIndex()));
+}
+
 static void handleConsumableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
   ConsumableAttr::ConsumedState DefaultState;
 
@@ -1002,18 +789,13 @@
         << Attr.getName() << AANT_ArgumentIdentifier;
     return;
   }
-
-  if (!isa<CXXRecordDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) <<
-      Attr.getName() << ExpectedClass;
-    return;
-  }
   
   D->addAttr(::new (S.Context)
              ConsumableAttr(Attr.getRange(), S.Context, DefaultState,
                             Attr.getAttributeSpellingListIndex()));
 }
 
+
 static bool checkForConsumableClass(Sema &S, const CXXMethodDecl *MD,
                                         const AttributeList &Attr) {
   ASTContext &CurrContext = S.getASTContext();
@@ -1036,12 +818,6 @@
                                    const AttributeList &Attr) {
   if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
     return;
-
-  if (!isa<CXXMethodDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) <<
-      Attr.getName() << ExpectedMethod;
-    return;
-  }
   
   if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), Attr))
     return;
@@ -1074,13 +850,7 @@
 static void handleParamTypestateAttr(Sema &S, Decl *D,
                                     const AttributeList &Attr) {
   if (!checkAttributeNumArgs(S, Attr, 1)) return;
-  
-  if (!isa<ParmVarDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) <<
-      Attr.getName() << ExpectedParameter;
-    return;
-  }
-  
+    
   ParamTypestateAttr::ConsumedState ParamState;
   
   if (Attr.isArgIdent(0)) {
@@ -1121,12 +891,6 @@
                                       const AttributeList &Attr) {
   if (!checkAttributeNumArgs(S, Attr, 1)) return;
   
-  if (!(isa<FunctionDecl>(D) || isa<ParmVarDecl>(D))) {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) <<
-      Attr.getName() << ExpectedFunctionMethodOrParameter;
-    return;
-  }
-
   ReturnTypestateAttr::ConsumedState ReturnState;
   
   if (Attr.isArgIdent(0)) {
@@ -1177,12 +941,6 @@
 static void handleSetTypestateAttr(Sema &S, Decl *D, const AttributeList &Attr) {
   if (!checkAttributeNumArgs(S, Attr, 1))
     return;
-
-  if (!isa<CXXMethodDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) <<
-      Attr.getName() << ExpectedMethod;
-    return;
-  }
   
   if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), Attr))
     return;
@@ -1212,12 +970,6 @@
   if (!checkAttributeNumArgs(S, Attr, 1))
     return;
   
-  if (!isa<CXXMethodDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) <<
-      Attr.getName() << ExpectedMethod;
-    return;
-  }
-  
   if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), Attr))
     return;
   
@@ -1243,21 +995,14 @@
 
 static void handleExtVectorTypeAttr(Sema &S, Scope *scope, Decl *D,
                                     const AttributeList &Attr) {
-  TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
-  if (TD == 0) {
-    // __attribute__((ext_vector_type(N))) can only be applied to typedefs
-    // and type-ids.
-    S.Diag(Attr.getLoc(), diag::err_typecheck_ext_vector_not_typedef);
-    return;
-  }
-
   // Remember this typedef decl, we will need it later for diagnostics.
-  S.ExtVectorDecls.push_back(TD);
+  S.ExtVectorDecls.push_back(cast<TypedefNameDecl>(D));
 }
 
 static void handlePackedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
   if (TagDecl *TD = dyn_cast<TagDecl>(D))
-    TD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context));
+    TD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context,
+                                        Attr.getAttributeSpellingListIndex()));
   else if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
     // If the alignment is less than or equal to 8 bits, the packed attribute
     // has no effect.
@@ -1274,28 +1019,6 @@
     S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
 }
 
-static void handleMsStructAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  if (RecordDecl *RD = dyn_cast<RecordDecl>(D))
-    RD->addAttr(::new (S.Context)
-                MsStructAttr(Attr.getRange(), S.Context,
-                             Attr.getAttributeSpellingListIndex()));
-  else
-    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
-}
-
-static void handleIBAction(Sema &S, Decl *D, const AttributeList &Attr) {
-  // The IBAction attributes only apply to instance methods.
-  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
-    if (MD->isInstanceMethod()) {
-      D->addAttr(::new (S.Context)
-                 IBActionAttr(Attr.getRange(), S.Context,
-                              Attr.getAttributeSpellingListIndex()));
-      return;
-    }
-
-  S.Diag(Attr.getLoc(), diag::warn_attribute_ibaction) << Attr.getName();
-}
-
 static bool checkIBOutletCommon(Sema &S, Decl *D, const AttributeList &Attr) {
   // The IBOutlet/IBOutletCollection attributes only apply to instance
   // variables or properties of Objective-C classes.  The outlet must also
@@ -1357,7 +1080,7 @@
     }
   }
 
-  TypeSourceInfo *QTLoc = 0;
+  TypeSourceInfo *QTLoc = nullptr;
   QualType QT = S.GetTypeFromParser(PT, &QTLoc);
   if (!QTLoc)
     QTLoc = S.Context.getTrivialTypeSourceInfo(QT, Attr.getLoc());
@@ -1382,9 +1105,8 @@
   if (const RecordType *UT = T->getAsUnionType())
     if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
       RecordDecl *UD = UT->getDecl();
-      for (RecordDecl::field_iterator it = UD->field_begin(),
-           itend = UD->field_end(); it != itend; ++it) {
-        QualType QT = it->getType();
+      for (const auto *I : UD->fields()) {
+        QualType QT = I->getType();
         if (QT->isAnyPointerType() || QT->isBlockPointerType()) {
           T = QT;
           return;
@@ -1393,74 +1115,34 @@
     }
 }
 
-static void handleAllocSizeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  if (!isFunctionOrMethod(D)) {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
-    << Attr.getName() << ExpectedFunctionOrMethod;
-    return;
+static bool attrNonNullArgCheck(Sema &S, QualType T, const AttributeList &Attr,
+                                SourceRange R, bool isReturnValue = false) {
+  T = T.getNonReferenceType();
+  possibleTransparentUnionPointerType(T);
+
+  if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
+    S.Diag(Attr.getLoc(),
+           isReturnValue ? diag::warn_attribute_return_pointers_only
+                         : diag::warn_attribute_pointers_only)
+      << Attr.getName() << R;
+    return false;
   }
-
-  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
-    return;
-
-  SmallVector<unsigned, 8> SizeArgs;
-  for (unsigned i = 0; i < Attr.getNumArgs(); ++i) {
-    Expr *Ex = Attr.getArgAsExpr(i);
-    uint64_t Idx;
-    if (!checkFunctionOrMethodArgumentIndex(S, D, Attr.getName()->getName(),
-                                            Attr.getLoc(), i + 1, Ex, Idx))
-      return;
-
-    // check if the function argument is of an integer type
-    QualType T = getFunctionOrMethodArgType(D, Idx).getNonReferenceType();
-    if (!T->isIntegerType()) {
-      S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
-        << Attr.getName() << AANT_ArgumentIntegerConstant
-        << Ex->getSourceRange();
-      return;
-    }
-    SizeArgs.push_back(Idx);
-  }
-
-  // check if the function returns a pointer
-  if (!getFunctionType(D)->getResultType()->isAnyPointerType()) {
-    S.Diag(Attr.getLoc(), diag::warn_ns_attribute_wrong_return_type)
-    << Attr.getName() << 0 /*function*/<< 1 /*pointer*/ << D->getSourceRange();
-  }
-
-  D->addAttr(::new (S.Context)
-             AllocSizeAttr(Attr.getRange(), S.Context,
-                           SizeArgs.data(), SizeArgs.size(),
-                           Attr.getAttributeSpellingListIndex()));
+  return true;
 }
 
 static void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  // GCC ignores the nonnull attribute on K&R style function prototypes, so we
-  // ignore it as well
-  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
-      << Attr.getName() << ExpectedFunction;
-    return;
-  }
-
   SmallVector<unsigned, 8> NonNullArgs;
   for (unsigned i = 0; i < Attr.getNumArgs(); ++i) {
     Expr *Ex = Attr.getArgAsExpr(i);
     uint64_t Idx;
-    if (!checkFunctionOrMethodArgumentIndex(S, D, Attr.getName()->getName(),
-                                            Attr.getLoc(), i + 1, Ex, Idx))
+    if (!checkFunctionOrMethodParameterIndex(S, D, Attr, i + 1, Ex, Idx))
       return;
 
     // Is the function argument a pointer type?
-    QualType T = getFunctionOrMethodArgType(D, Idx).getNonReferenceType();
-    possibleTransparentUnionPointerType(T);
-    
-    if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
-      // FIXME: Should also highlight argument in decl.
-      S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only)
-        << "nonnull" << Ex->getSourceRange();
+    // FIXME: Should also highlight argument in decl in the diagnostic.
+    if (!attrNonNullArgCheck(S, getFunctionOrMethodParamType(D, Idx), Attr,
+                             Ex->getSourceRange()))
       continue;
-    }
 
     NonNullArgs.push_back(Idx);
   }
@@ -1468,8 +1150,8 @@
   // If no arguments were specified to __attribute__((nonnull)) then all pointer
   // arguments have a nonnull attribute.
   if (NonNullArgs.empty()) {
-    for (unsigned i = 0, e = getFunctionOrMethodNumArgs(D); i != e; ++i) {
-      QualType T = getFunctionOrMethodArgType(D, i).getNonReferenceType();
+    for (unsigned i = 0, e = getFunctionOrMethodNumParams(D); i != e; ++i) {
+      QualType T = getFunctionOrMethodParamType(D, i).getNonReferenceType();
       possibleTransparentUnionPointerType(T);
       if (T->isAnyPointerType() || T->isBlockPointerType())
         NonNullArgs.push_back(i);
@@ -1493,13 +1175,37 @@
                          Attr.getAttributeSpellingListIndex()));
 }
 
-static const char *ownershipKindToDiagName(OwnershipAttr::OwnershipKind K) {
-  switch (K) {
-    case OwnershipAttr::Holds:    return "'ownership_holds'";
-    case OwnershipAttr::Takes:    return "'ownership_takes'";
-    case OwnershipAttr::Returns:  return "'ownership_returns'";
+static void handleNonNullAttrParameter(Sema &S, ParmVarDecl *D,
+                                       const AttributeList &Attr) {
+  if (Attr.getNumArgs() > 0) {
+    if (D->getFunctionType()) {
+      handleNonNullAttr(S, D, Attr);
+    } else {
+      S.Diag(Attr.getLoc(), diag::warn_attribute_nonnull_parm_no_args)
+        << D->getSourceRange();
+    }
+    return;
   }
-  llvm_unreachable("unknown ownership");
+
+  // Is the argument a pointer type?
+  if (!attrNonNullArgCheck(S, D->getType(), Attr, D->getSourceRange()))
+    return;
+
+  D->addAttr(::new (S.Context)
+             NonNullAttr(Attr.getRange(), S.Context, nullptr, 0,
+                         Attr.getAttributeSpellingListIndex()));
+}
+
+static void handleReturnsNonNullAttr(Sema &S, Decl *D,
+                                     const AttributeList &Attr) {
+  QualType ResultType = getFunctionOrMethodResultType(D);
+  if (!attrNonNullArgCheck(S, ResultType, Attr, Attr.getRange(),
+                           /* isReturnValue */ true))
+    return;
+
+  D->addAttr(::new (S.Context)
+            ReturnsNonNullAttr(Attr.getRange(), S.Context,
+                               Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) {
@@ -1517,58 +1223,49 @@
     return;
   }
 
-  // Figure out our Kind, and check arguments while we're at it.
-  OwnershipAttr::OwnershipKind K;
-  switch (AL.getKind()) {
-  case AttributeList::AT_ownership_takes:
-    K = OwnershipAttr::Takes;
-    if (AL.getNumArgs() < 2) {
-      S.Diag(AL.getLoc(), diag::err_attribute_too_few_arguments) << 2;
-      return;
-    }
-    break;
-  case AttributeList::AT_ownership_holds:
-    K = OwnershipAttr::Holds;
-    if (AL.getNumArgs() < 2) {
-      S.Diag(AL.getLoc(), diag::err_attribute_too_few_arguments) << 2;
-      return;
-    }
-    break;
-  case AttributeList::AT_ownership_returns:
-    K = OwnershipAttr::Returns;
+  // Figure out our Kind.
+  OwnershipAttr::OwnershipKind K =
+      OwnershipAttr(AL.getLoc(), S.Context, nullptr, nullptr, 0,
+                    AL.getAttributeSpellingListIndex()).getOwnKind();
 
+  // Check arguments.
+  switch (K) {
+  case OwnershipAttr::Takes:
+  case OwnershipAttr::Holds:
+    if (AL.getNumArgs() < 2) {
+      S.Diag(AL.getLoc(), diag::err_attribute_too_few_arguments)
+        << AL.getName() << 2;
+      return;
+    }
+    break;
+  case OwnershipAttr::Returns:
     if (AL.getNumArgs() > 2) {
-      S.Diag(AL.getLoc(), diag::err_attribute_too_many_arguments) << 1;
+      S.Diag(AL.getLoc(), diag::err_attribute_too_many_arguments)
+        << AL.getName() << 1;
       return;
     }
     break;
-  default:
-    // This should never happen given how we are called.
-    llvm_unreachable("Unknown ownership attribute");
   }
 
-  if (!isFunction(D) || !hasFunctionProto(D)) {
-    S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
-      << AL.getName() << ExpectedFunction;
-    return;
-  }
-
-  StringRef Module = AL.getArgAsIdent(0)->Ident->getName();
+  IdentifierInfo *Module = AL.getArgAsIdent(0)->Ident;
 
   // Normalize the argument, __foo__ becomes foo.
-  if (Module.startswith("__") && Module.endswith("__"))
-    Module = Module.substr(2, Module.size() - 4);
+  StringRef ModuleName = Module->getName();
+  if (ModuleName.startswith("__") && ModuleName.endswith("__") &&
+      ModuleName.size() > 4) {
+    ModuleName = ModuleName.drop_front(2).drop_back(2);
+    Module = &S.PP.getIdentifierTable().get(ModuleName);
+  }
 
   SmallVector<unsigned, 8> OwnershipArgs;
   for (unsigned i = 1; i < AL.getNumArgs(); ++i) {
     Expr *Ex = AL.getArgAsExpr(i);
     uint64_t Idx;
-    if (!checkFunctionOrMethodArgumentIndex(S, D, AL.getName()->getName(),
-                                            AL.getLoc(), i, Ex, Idx))
+    if (!checkFunctionOrMethodParameterIndex(S, D, AL, i, Ex, Idx))
       return;
 
     // Is the function argument a pointer type?
-    QualType T = getFunctionOrMethodArgType(D, Idx);
+    QualType T = getFunctionOrMethodParamType(D, Idx);
     int Err = -1;  // No error
     switch (K) {
       case OwnershipAttr::Takes:
@@ -1588,13 +1285,13 @@
     }
 
     // Check we don't have a conflict with another ownership attribute.
-    for (specific_attr_iterator<OwnershipAttr>
-         i = D->specific_attr_begin<OwnershipAttr>(),
-         e = D->specific_attr_end<OwnershipAttr>(); i != e; ++i) {
-      if ((*i)->getOwnKind() != K && (*i)->args_end() !=
-          std::find((*i)->args_begin(), (*i)->args_end(), Idx)) {
+    for (const auto *I : D->specific_attrs<OwnershipAttr>()) {
+      // FIXME: A returns attribute should conflict with any returns attribute
+      // with a different index too.
+      if (I->getOwnKind() != K && I->args_end() !=
+          std::find(I->args_begin(), I->args_end(), Idx)) {
         S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
-          << AL.getName() << ownershipKindToDiagName((*i)->getOwnKind());
+          << AL.getName() << I;
         return;
       }
     }
@@ -1606,7 +1303,7 @@
   llvm::array_pod_sort(start, start + size);
 
   D->addAttr(::new (S.Context)
-             OwnershipAttr(AL.getLoc(), S.Context, K, Module, start, size,
+             OwnershipAttr(AL.getLoc(), S.Context, Module, start, size,
                            AL.getAttributeSpellingListIndex()));
 }
 
@@ -1618,12 +1315,6 @@
     return;
   }
 
-  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
-      << Attr.getName() << ExpectedVariableOrFunction;
-    return;
-  }
-
   NamedDecl *nd = cast<NamedDecl>(D);
 
   // gcc rejects
@@ -1638,8 +1329,8 @@
   // we reject them
   const DeclContext *Ctx = D->getDeclContext()->getRedeclContext();
   if (!Ctx->isFileContext()) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
-        nd->getNameAsString();
+    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context)
+      << nd;
     return;
   }
 
@@ -1696,77 +1387,22 @@
                                          Attr.getAttributeSpellingListIndex()));
 }
 
-static void handleMinSizeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  if (!isa<FunctionDecl>(D) && !isa<ObjCMethodDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
-      << Attr.getName() << ExpectedFunctionOrMethod;
-    return;
-  }
-
-  D->addAttr(::new (S.Context)
-             MinSizeAttr(Attr.getRange(), S.Context,
-                         Attr.getAttributeSpellingListIndex()));
-}
-
 static void handleColdAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  if (!isa<FunctionDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
-      << Attr.getName() << ExpectedFunction;
+  if (checkAttrMutualExclusion<HotAttr>(S, D, Attr))
     return;
-  }
-
-  if (D->hasAttr<HotAttr>()) {
-    S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
-      << Attr.getName() << "hot";
-    return;
-  }
 
   D->addAttr(::new (S.Context) ColdAttr(Attr.getRange(), S.Context,
                                         Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleHotAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  if (!isa<FunctionDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
-      << Attr.getName() << ExpectedFunction;
+  if (checkAttrMutualExclusion<ColdAttr>(S, D, Attr))
     return;
-  }
-
-  if (D->hasAttr<ColdAttr>()) {
-    S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
-      << Attr.getName() << "cold";
-    return;
-  }
 
   D->addAttr(::new (S.Context) HotAttr(Attr.getRange(), S.Context,
                                        Attr.getAttributeSpellingListIndex()));
 }
 
-static void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  if (!isa<FunctionDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
-      << Attr.getName() << ExpectedFunction;
-    return;
-  }
-
-  D->addAttr(::new (S.Context)
-             NakedAttr(Attr.getRange(), S.Context,
-                       Attr.getAttributeSpellingListIndex()));
-}
-
-static void handleAlwaysInlineAttr(Sema &S, Decl *D,
-                                   const AttributeList &Attr) {
-  if (!isa<FunctionDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
-      << Attr.getName() << ExpectedFunction;
-    return;
-  }
-
-  D->addAttr(::new (S.Context)
-             AlwaysInlineAttr(Attr.getRange(), S.Context,
-                              Attr.getAttributeSpellingListIndex()));
-}
-
 static void handleTLSModelAttr(Sema &S, Decl *D,
                                const AttributeList &Attr) {
   StringRef Model;
@@ -1775,12 +1411,6 @@
   if (!S.checkStringLiteralArgumentAttr(Attr, 0, Model, &LiteralLoc))
     return;
 
-  if (!isa<VarDecl>(D) || !cast<VarDecl>(D)->getTLSKind()) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
-      << Attr.getName() << ExpectedTLSVar;
-    return;
-  }
-
   // Check that the value.
   if (Model != "global-dynamic" && Model != "local-dynamic"
       && Model != "initial-exec" && Model != "local-exec") {
@@ -1795,7 +1425,7 @@
 
 static void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) {
   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
-    QualType RetTy = FD->getResultType();
+    QualType RetTy = FD->getReturnType();
     if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
       D->addAttr(::new (S.Context)
                  MallocAttr(Attr.getRange(), S.Context,
@@ -1807,35 +1437,15 @@
   S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
 }
 
-static void handleMayAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  D->addAttr(::new (S.Context)
-             MayAliasAttr(Attr.getRange(), S.Context,
-                          Attr.getAttributeSpellingListIndex()));
-}
-
-static void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  if (isa<VarDecl>(D))
-    D->addAttr(::new (S.Context)
-               NoCommonAttr(Attr.getRange(), S.Context,
-                            Attr.getAttributeSpellingListIndex()));
-  else
-    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
-      << Attr.getName() << ExpectedVariable;
-}
-
 static void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
   if (S.LangOpts.CPlusPlus) {
-    S.Diag(Attr.getLoc(), diag::err_common_not_supported_cplusplus);
+    S.Diag(Attr.getLoc(), diag::err_attribute_not_supported_in_lang)
+      << Attr.getName() << AttributeLangSupport::Cpp;
     return;
   }
 
-  if (isa<VarDecl>(D))
-    D->addAttr(::new (S.Context)
-               CommonAttr(Attr.getRange(), S.Context,
-                          Attr.getAttributeSpellingListIndex()));
-  else
-    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
-      << Attr.getName() << ExpectedVariable;
+  D->addAttr(::new (S.Context) CommonAttr(Attr.getRange(), S.Context,
+                                        Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleNoReturnAttr(Sema &S, Decl *D, const AttributeList &attr) {
@@ -1870,8 +1480,8 @@
   // because 'analyzer_noreturn' does not impact the type.
   if (!isFunctionOrMethod(D) && !isa<BlockDecl>(D)) {
     ValueDecl *VD = dyn_cast<ValueDecl>(D);
-    if (VD == 0 || (!VD->getType()->isBlockPointerType()
-                    && !VD->getType()->isFunctionPointerType())) {
+    if (!VD || (!VD->getType()->isBlockPointerType() &&
+                !VD->getType()->isFunctionPointerType())) {
       S.Diag(Attr.getLoc(),
              Attr.isCXX11Attribute() ? diag::err_attribute_wrong_decl_type
              : diag::warn_attribute_wrong_decl_type)
@@ -1885,23 +1495,6 @@
                                   Attr.getAttributeSpellingListIndex()));
 }
 
-static void handleCXX11NoReturnAttr(Sema &S, Decl *D,
-                                    const AttributeList &Attr) {
-  // C++11 [dcl.attr.noreturn]p1:
-  //   The attribute may be applied to the declarator-id in a function
-  //   declaration.
-  FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
-  if (!FD) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
-      << Attr.getName() << ExpectedFunctionOrMethod;
-    return;
-  }
-
-  D->addAttr(::new (S.Context)
-             CXX11NoReturnAttr(Attr.getRange(), S.Context,
-                               Attr.getAttributeSpellingListIndex()));
-}
-
 // PS3 PPU-specific.
 static void handleVecReturnAttr(Sema &S, Decl *D, const AttributeList &Attr) {
 /*
@@ -1927,14 +1520,8 @@
     return result; // This will be returned in a register
   }
 */
-  if (!isa<RecordDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
-      << Attr.getName() << ExpectedClass;
-    return;
-  }
-
-  if (D->getAttr<VecReturnAttr>()) {
-    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn";
+  if (VecReturnAttr *A = D->getAttr<VecReturnAttr>()) {
+    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << A;
     return;
   }
 
@@ -1951,9 +1538,8 @@
     return;
   }
 
-  for (RecordDecl::field_iterator iter = record->field_begin();
-       iter != record->field_end(); iter++) {
-    if ((count == 1) || !iter->getType()->isVectorType()) {
+  for (const auto *I : record->fields()) {
+    if ((count == 1) || !I->getType()->isVectorType()) {
       S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
       return;
     }
@@ -1975,10 +1561,6 @@
              diag::err_carries_dependency_param_not_function_decl);
       return;
     }
-  } else if (!isa<FunctionDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
-      << Attr.getName() << ExpectedFunctionMethodOrParameter;
-    return;
   }
 
   D->addAttr(::new (S.Context) CarriesDependencyAttr(
@@ -1986,36 +1568,10 @@
                                    Attr.getAttributeSpellingListIndex()));
 }
 
-static void handleUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  if (!isa<VarDecl>(D) && !isa<ObjCIvarDecl>(D) && !isFunctionOrMethod(D) &&
-      !isa<TypeDecl>(D) && !isa<LabelDecl>(D) && !isa<FieldDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
-      << Attr.getName() << ExpectedVariableFunctionOrLabel;
-    return;
-  }
-
-  D->addAttr(::new (S.Context)
-             UnusedAttr(Attr.getRange(), S.Context,
-                        Attr.getAttributeSpellingListIndex()));
-}
-
-static void handleReturnsTwiceAttr(Sema &S, Decl *D,
-                                   const AttributeList &Attr) {
-  if (!isa<FunctionDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
-      << Attr.getName() << ExpectedFunction;
-    return;
-  }
-
-  D->addAttr(::new (S.Context)
-             ReturnsTwiceAttr(Attr.getRange(), S.Context,
-                              Attr.getAttributeSpellingListIndex()));
-}
-
 static void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
   if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
     if (VD->hasLocalStorage()) {
-      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "used";
+      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
       return;
     }
   } else if (!isFunctionOrMethod(D)) {
@@ -2032,29 +1588,15 @@
 static void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
   // check the attribute arguments.
   if (Attr.getNumArgs() > 1) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
+    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments)
+      << Attr.getName() << 1;
     return;
   }
 
-  int priority = 65535; // FIXME: Do not hardcode such constants.
-  if (Attr.getNumArgs() > 0) {
-    Expr *E = Attr.getArgAsExpr(0);
-    llvm::APSInt Idx(32);
-    if (E->isTypeDependent() || E->isValueDependent() ||
-        !E->isIntegerConstantExpr(Idx, S.Context)) {
-      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
-        << Attr.getName() << 1 << AANT_ArgumentIntegerConstant
-        << E->getSourceRange();
-      return;
-    }
-    priority = Idx.getZExtValue();
-  }
-
-  if (!isa<FunctionDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
-      << Attr.getName() << ExpectedFunction;
+  uint32_t priority = ConstructorAttr::DefaultPriority;
+  if (Attr.getNumArgs() > 0 &&
+      !checkUInt32Argument(S, Attr, Attr.getArgAsExpr(0), priority))
     return;
-  }
 
   D->addAttr(::new (S.Context)
              ConstructorAttr(Attr.getRange(), S.Context, priority,
@@ -2064,29 +1606,15 @@
 static void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
   // check the attribute arguments.
   if (Attr.getNumArgs() > 1) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
+    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments)
+      << Attr.getName() << 1;
     return;
   }
 
-  int priority = 65535; // FIXME: Do not hardcode such constants.
-  if (Attr.getNumArgs() > 0) {
-    Expr *E = Attr.getArgAsExpr(0);
-    llvm::APSInt Idx(32);
-    if (E->isTypeDependent() || E->isValueDependent() ||
-        !E->isIntegerConstantExpr(Idx, S.Context)) {
-      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
-        << Attr.getName() << 1 << AANT_ArgumentIntegerConstant
-        << E->getSourceRange();
-      return;
-    }
-    priority = Idx.getZExtValue();
-  }
-
-  if (!isa<FunctionDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
-      << Attr.getName() << ExpectedFunction;
+  uint32_t priority = DestructorAttr::DefaultPriority;
+  if (Attr.getNumArgs() > 0 &&
+      !checkUInt32Argument(S, Attr, Attr.getArgAsExpr(0), priority))
     return;
-  }
 
   D->addAttr(::new (S.Context)
              DestructorAttr(Attr.getRange(), S.Context, priority,
@@ -2098,7 +1626,8 @@
                                   const AttributeList &Attr) {
   unsigned NumArgs = Attr.getNumArgs();
   if (NumArgs > 1) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
+    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments)
+      << Attr.getName() << 1;
     return;
   }
 
@@ -2111,38 +1640,19 @@
                                       Attr.getAttributeSpellingListIndex()));
 }
 
-static void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D, 
-                                            const AttributeList &Attr) {
+static void handleObjCSuppresProtocolAttr(Sema &S, Decl *D,
+                                          const AttributeList &Attr) {
+  if (!cast<ObjCProtocolDecl>(D)->isThisDeclarationADefinition()) {
+    S.Diag(Attr.getLoc(), diag::err_objc_attr_protocol_requires_definition)
+      << Attr.getName() << Attr.getRange();
+    return;
+  }
+
   D->addAttr(::new (S.Context)
-             ArcWeakrefUnavailableAttr(Attr.getRange(), S.Context,
+          ObjCExplicitProtocolImplAttr(Attr.getRange(), S.Context,
                                        Attr.getAttributeSpellingListIndex()));
 }
 
-static void handleObjCRootClassAttr(Sema &S, Decl *D, 
-                                    const AttributeList &Attr) {
-  if (!isa<ObjCInterfaceDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
-      << Attr.getName() << ExpectedObjectiveCInterface;
-    return;
-  }
-  
-  D->addAttr(::new (S.Context)
-             ObjCRootClassAttr(Attr.getRange(), S.Context,
-                               Attr.getAttributeSpellingListIndex()));
-}
-
-static void handleObjCRequiresPropertyDefsAttr(Sema &S, Decl *D,
-                                               const AttributeList &Attr) {
-  if (!isa<ObjCInterfaceDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::err_suppress_autosynthesis);
-    return;
-  }
-  
-  D->addAttr(::new (S.Context)
-             ObjCRequiresPropertyDefsAttr(Attr.getRange(), S.Context,
-                                          Attr.getAttributeSpellingListIndex()));
-}
-
 static bool checkAvailabilityAttr(Sema &S, SourceRange Range,
                                   IdentifierInfo *Platform,
                                   VersionTuple Introduced,
@@ -2310,7 +1820,7 @@
       MergedIntroduced == Introduced &&
       MergedDeprecated == Deprecated &&
       MergedObsoleted == Obsoleted)
-    return NULL;
+    return nullptr;
 
   // Only create a new attribute if !Override, but we want to do
   // the checking.
@@ -2322,7 +1832,7 @@
                                             Obsoleted, IsUnavailable, Message,
                                             AttrSpellingListIndex);
   }
-  return NULL;
+  return nullptr;
 }
 
 static void handleAvailabilityAttr(Sema &S, Decl *D,
@@ -2371,7 +1881,7 @@
   if (existingAttr) {
     typename T::VisibilityType existingValue = existingAttr->getVisibility();
     if (existingValue == value)
-      return NULL;
+      return nullptr;
     S.Diag(existingAttr->getLocation(), diag::err_mismatched_visibility);
     S.Diag(range.getBegin(), diag::note_previous_attribute);
     D->dropAttr<T>();
@@ -2448,13 +1958,7 @@
 
 static void handleObjCMethodFamilyAttr(Sema &S, Decl *decl,
                                        const AttributeList &Attr) {
-  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(decl);
-  if (!method) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
-      << ExpectedMethod;
-    return;
-  }
-
+  ObjCMethodDecl *method = cast<ObjCMethodDecl>(decl);
   if (!Attr.isArgIdent(0)) {
     S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
       << Attr.getName() << 1 << AANT_ArgumentIdentifier;
@@ -2469,30 +1973,17 @@
     return;
   }
 
-  if (F == ObjCMethodFamilyAttr::OMF_init && 
-      !method->getResultType()->isObjCObjectPointerType()) {
+  if (F == ObjCMethodFamilyAttr::OMF_init &&
+      !method->getReturnType()->isObjCObjectPointerType()) {
     S.Diag(method->getLocation(), diag::err_init_method_bad_return_type)
-      << method->getResultType();
+        << method->getReturnType();
     // Ignore the attribute.
     return;
   }
 
   method->addAttr(new (S.Context) ObjCMethodFamilyAttr(Attr.getRange(),
-                                                       S.Context, F));
-}
-
-static void handleObjCExceptionAttr(Sema &S, Decl *D,
-                                    const AttributeList &Attr) {
-  ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
-  if (OCI == 0) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
-      << Attr.getName() << ExpectedObjectiveCInterface;
-    return;
-  }
-
-  D->addAttr(::new (S.Context)
-             ObjCExceptionAttr(Attr.getRange(), S.Context,
-                               Attr.getAttributeSpellingListIndex()));
+                                                       S.Context, F,
+                                        Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -2524,18 +2015,6 @@
                               Attr.getAttributeSpellingListIndex()));
 }
 
-static void
-handleOverloadableAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  if (!isa<FunctionDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_overloadable_not_function);
-    return;
-  }
-
-  D->addAttr(::new (S.Context)
-             OverloadableAttr(Attr.getRange(), S.Context,
-                              Attr.getAttributeSpellingListIndex()));
-}
-
 static void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) {
   if (!Attr.isArgIdent(0)) {
     S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
@@ -2559,11 +2038,12 @@
 static void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) {
   // check the attribute arguments.
   if (Attr.getNumArgs() > 2) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
+    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments)
+      << Attr.getName() << 2;
     return;
   }
 
-  unsigned sentinel = 0;
+  unsigned sentinel = (unsigned)SentinelAttr::DefaultSentinel;
   if (Attr.getNumArgs() > 0) {
     Expr *E = Attr.getArgAsExpr(0);
     llvm::APSInt Idx(32);
@@ -2584,7 +2064,7 @@
     sentinel = Idx.getZExtValue();
   }
 
-  unsigned nullPos = 0;
+  unsigned nullPos = (unsigned)SentinelAttr::DefaultNullPos;
   if (Attr.getNumArgs() > 1) {
     Expr *E = Attr.getArgAsExpr(1);
     llvm::APSInt Idx(32);
@@ -2630,7 +2110,8 @@
   } else if (const VarDecl *V = dyn_cast<VarDecl>(D)) {
     QualType Ty = V->getType();
     if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
-      const FunctionType *FT = Ty->isFunctionPointerType() ? getFunctionType(D)
+      const FunctionType *FT = Ty->isFunctionPointerType()
+       ? D->getFunctionType()
        : Ty->getAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
       if (!cast<FunctionProtoType>(FT)->isVariadic()) {
         int m = Ty->isFunctionPointerType() ? 0 : 1;
@@ -2652,27 +2133,15 @@
                           Attr.getAttributeSpellingListIndex()));
 }
 
-static void handleWarnUnusedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  if (RecordDecl *RD = dyn_cast<RecordDecl>(D))
-    RD->addAttr(::new (S.Context) WarnUnusedAttr(Attr.getRange(), S.Context));
-  else
-    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
-}
-
 static void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) {
-  if (!isFunction(D) && !isa<ObjCMethodDecl>(D) && !isa<CXXRecordDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
-      << Attr.getName() << ExpectedFunctionMethodOrClass;
-    return;
-  }
-
-  if (isFunction(D) && getFunctionType(D)->getResultType()->isVoidType()) {
+  if (D->getFunctionType() &&
+      D->getFunctionType()->getReturnType()->isVoidType()) {
     S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
       << Attr.getName() << 0;
     return;
   }
   if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
-    if (MD->getResultType()->isVoidType()) {
+    if (MD->getReturnType()->isVoidType()) {
       S.Diag(Attr.getLoc(), diag::warn_attribute_void_function_method)
       << Attr.getName() << 1;
       return;
@@ -2683,24 +2152,6 @@
                                   Attr.getAttributeSpellingListIndex()));
 }
 
-static void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) {
-    if (isa<CXXRecordDecl>(D)) {
-      D->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context));
-      return;
-    }
-    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
-      << Attr.getName() << ExpectedVariableOrFunction;
-    return;
-  }
-
-  NamedDecl *nd = cast<NamedDecl>(D);
-
-  nd->addAttr(::new (S.Context)
-              WeakAttr(Attr.getRange(), S.Context,
-                       Attr.getAttributeSpellingListIndex()));
-}
-
 static void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
   // weak_import only applies to variable & function declarations.
   bool isDef = false;
@@ -2725,66 +2176,40 @@
 }
 
 // Handles reqd_work_group_size and work_group_size_hint.
+template <typename WorkGroupAttr>
 static void handleWorkGroupSize(Sema &S, Decl *D,
                                 const AttributeList &Attr) {
-  unsigned WGSize[3];
+  uint32_t WGSize[3];
   for (unsigned i = 0; i < 3; ++i) {
-    Expr *E = Attr.getArgAsExpr(i);
-    llvm::APSInt ArgNum(32);
-    if (E->isTypeDependent() || E->isValueDependent() ||
-        !E->isIntegerConstantExpr(ArgNum, S.Context)) {
-      S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
-        << Attr.getName() << AANT_ArgumentIntegerConstant
-        << E->getSourceRange();
+    const Expr *E = Attr.getArgAsExpr(i);
+    if (!checkUInt32Argument(S, Attr, E, WGSize[i], i))
+      return;
+    if (WGSize[i] == 0) {
+      S.Diag(Attr.getLoc(), diag::err_attribute_argument_is_zero)
+        << Attr.getName() << E->getSourceRange();
       return;
     }
-    WGSize[i] = (unsigned) ArgNum.getZExtValue();
   }
 
-  if (Attr.getKind() == AttributeList::AT_ReqdWorkGroupSize
-    && D->hasAttr<ReqdWorkGroupSizeAttr>()) {
-      ReqdWorkGroupSizeAttr *A = D->getAttr<ReqdWorkGroupSizeAttr>();
-      if (!(A->getXDim() == WGSize[0] &&
-            A->getYDim() == WGSize[1] &&
-            A->getZDim() == WGSize[2])) {
-        S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) <<
-          Attr.getName();
-      }
-  }
+  WorkGroupAttr *Existing = D->getAttr<WorkGroupAttr>();
+  if (Existing && !(Existing->getXDim() == WGSize[0] &&
+                    Existing->getYDim() == WGSize[1] &&
+                    Existing->getZDim() == WGSize[2]))
+    S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) << Attr.getName();
 
-  if (Attr.getKind() == AttributeList::AT_WorkGroupSizeHint
-    && D->hasAttr<WorkGroupSizeHintAttr>()) {
-      WorkGroupSizeHintAttr *A = D->getAttr<WorkGroupSizeHintAttr>();
-      if (!(A->getXDim() == WGSize[0] &&
-            A->getYDim() == WGSize[1] &&
-            A->getZDim() == WGSize[2])) {
-        S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) <<
-          Attr.getName();
-      }
-  }
-
-  if (Attr.getKind() == AttributeList::AT_ReqdWorkGroupSize)
-    D->addAttr(::new (S.Context)
-                 ReqdWorkGroupSizeAttr(Attr.getRange(), S.Context,
-                                       WGSize[0], WGSize[1], WGSize[2],
-                                       Attr.getAttributeSpellingListIndex()));
-  else
-    D->addAttr(::new (S.Context)
-                 WorkGroupSizeHintAttr(Attr.getRange(), S.Context,
-                                       WGSize[0], WGSize[1], WGSize[2],
+  D->addAttr(::new (S.Context) WorkGroupAttr(Attr.getRange(), S.Context,
+                                             WGSize[0], WGSize[1], WGSize[2],
                                        Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleVecTypeHint(Sema &S, Decl *D, const AttributeList &Attr) {
-  assert(Attr.getKind() == AttributeList::AT_VecTypeHint);
-
   if (!Attr.hasParsedType()) {
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
       << Attr.getName() << 1;
     return;
   }
 
-  TypeSourceInfo *ParmTSI = 0;
+  TypeSourceInfo *ParmTSI = nullptr;
   QualType ParmType = S.GetTypeFromParser(Attr.getTypeArg(), &ParmTSI);
   assert(ParmTSI && "no type source info for attribute argument");
 
@@ -2796,9 +2221,7 @@
     return;
   }
 
-  if (Attr.getKind() == AttributeList::AT_VecTypeHint &&
-      D->hasAttr<VecTypeHintAttr>()) {
-    VecTypeHintAttr *A = D->getAttr<VecTypeHintAttr>();
+  if (VecTypeHintAttr *A = D->getAttr<VecTypeHintAttr>()) {
     if (!S.Context.hasSameType(A->getTypeHint(), ParmType)) {
       S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) << Attr.getName();
       return;
@@ -2806,7 +2229,8 @@
   }
 
   D->addAttr(::new (S.Context) VecTypeHintAttr(Attr.getLoc(), S.Context,
-                                               ParmTSI));
+                                               ParmTSI,
+                                        Attr.getAttributeSpellingListIndex()));
 }
 
 SectionAttr *Sema::mergeSectionAttr(Decl *D, SourceRange Range,
@@ -2814,10 +2238,10 @@
                                     unsigned AttrSpellingListIndex) {
   if (SectionAttr *ExistingAttr = D->getAttr<SectionAttr>()) {
     if (ExistingAttr->getName() == Name)
-      return NULL;
+      return nullptr;
     Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section);
     Diag(Range.getBegin(), diag::note_previous_attribute);
-    return NULL;
+    return nullptr;
   }
   return ::new (Context) SectionAttr(Range, Context, Name,
                                      AttrSpellingListIndex);
@@ -2839,12 +2263,6 @@
     return;
   }
 
-  // This attribute cannot be applied to local variables.
-  if (isa<VarDecl>(D) && cast<VarDecl>(D)->hasLocalStorage()) {
-    S.Diag(LiteralLoc, diag::err_attribute_section_local_variable);
-    return;
-  }
-  
   unsigned Index = Attr.getAttributeSpellingListIndex();
   SectionAttr *NewAttr = S.mergeSectionAttr(D, Attr.getRange(), Str, Index);
   if (NewAttr)
@@ -2852,44 +2270,16 @@
 }
 
 
-static void handleNothrowAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  if (NoThrowAttr *Existing = D->getAttr<NoThrowAttr>()) {
-    if (Existing->getLocation().isInvalid())
-      Existing->setRange(Attr.getRange());
-  } else {
-    D->addAttr(::new (S.Context)
-               NoThrowAttr(Attr.getRange(), S.Context,
-                           Attr.getAttributeSpellingListIndex()));
-  }
-}
-
-static void handleConstAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  if (ConstAttr *Existing = D->getAttr<ConstAttr>()) {
-   if (Existing->getLocation().isInvalid())
-     Existing->setRange(Attr.getRange());
-  } else {
-    D->addAttr(::new (S.Context)
-               ConstAttr(Attr.getRange(), S.Context,
-                         Attr.getAttributeSpellingListIndex() ));
-  }
-}
-
-static void handlePureAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  D->addAttr(::new (S.Context)
-             PureAttr(Attr.getRange(), S.Context,
-                      Attr.getAttributeSpellingListIndex()));
-}
-
 static void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  VarDecl *VD = dyn_cast<VarDecl>(D);
-  if (!VD || !VD->hasLocalStorage()) {
+  VarDecl *VD = cast<VarDecl>(D);
+  if (!VD->hasLocalStorage()) {
     S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
     return;
   }
 
   Expr *E = Attr.getArgAsExpr(0);
   SourceLocation Loc = E->getExprLoc();
-  FunctionDecl *FD = 0;
+  FunctionDecl *FD = nullptr;
   DeclarationNameInfo NI;
 
   // gcc only allows for simple identifiers. Since we support more than gcc, we
@@ -2946,20 +2336,13 @@
 /// Handle __attribute__((format_arg((idx)))) attribute based on
 /// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
 static void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
-      << Attr.getName() << ExpectedFunction;
-    return;
-  }
-
   Expr *IdxExpr = Attr.getArgAsExpr(0);
-  uint64_t ArgIdx;
-  if (!checkFunctionOrMethodArgumentIndex(S, D, Attr.getName()->getName(),
-                                          Attr.getLoc(), 1, IdxExpr, ArgIdx))
+  uint64_t Idx;
+  if (!checkFunctionOrMethodParameterIndex(S, D, Attr, 1, IdxExpr, Idx))
     return;
 
   // make sure the format string is really a string
-  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
+  QualType Ty = getFunctionOrMethodParamType(D, Idx);
 
   bool not_nsstring_type = !isNSStringType(Ty, S.Context);
   if (not_nsstring_type &&
@@ -2984,7 +2367,7 @@
     return;
   }
 
-  // We cannot use the ArgIdx returned from checkFunctionOrMethodArgumentIndex
+  // We cannot use the Idx returned from checkFunctionOrMethodParameterIndex
   // because that has corrected for the implicit this parameter, and is zero-
   // based.  The attribute expects what the user wrote explicitly.
   llvm::APSInt Val;
@@ -3031,12 +2414,12 @@
     return;
   }
   
-  if (!isa<VarDecl>(D) || S.getCurFunctionOrMethodDecl()) {
+  if (S.getCurFunctionOrMethodDecl()) {
     S.Diag(Attr.getLoc(), diag::err_init_priority_object_attr);
     Attr.setInvalid();
     return;
   }
-  QualType T = dyn_cast<VarDecl>(D)->getType();
+  QualType T = cast<VarDecl>(D)->getType();
   if (S.Context.getAsArrayType(T))
     T = S.Context.getBaseElementType(T);
   if (!T->getAs<RecordType>()) {
@@ -3044,22 +2427,17 @@
     Attr.setInvalid();
     return;
   }
-  
-  Expr *priorityExpr = Attr.getArgAsExpr(0);
-  
-  llvm::APSInt priority(32);
-  if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() ||
-      !priorityExpr->isIntegerConstantExpr(priority, S.Context)) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
-      << Attr.getName() << AANT_ArgumentIntegerConstant
-      << priorityExpr->getSourceRange();
+
+  Expr *E = Attr.getArgAsExpr(0);
+  uint32_t prioritynum;
+  if (!checkUInt32Argument(S, Attr, E, prioritynum)) {
     Attr.setInvalid();
     return;
   }
-  unsigned prioritynum = priority.getZExtValue();
+
   if (prioritynum < 101 || prioritynum > 65535) {
     S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range)
-    <<  priorityExpr->getSourceRange();
+      << E->getSourceRange();
     Attr.setInvalid();
     return;
   }
@@ -3073,19 +2451,15 @@
                                   int FirstArg,
                                   unsigned AttrSpellingListIndex) {
   // Check whether we already have an equivalent format attribute.
-  for (specific_attr_iterator<FormatAttr>
-         i = D->specific_attr_begin<FormatAttr>(),
-         e = D->specific_attr_end<FormatAttr>();
-       i != e ; ++i) {
-    FormatAttr *f = *i;
-    if (f->getType() == Format &&
-        f->getFormatIdx() == FormatIdx &&
-        f->getFirstArg() == FirstArg) {
+  for (auto *F : D->specific_attrs<FormatAttr>()) {
+    if (F->getType() == Format &&
+        F->getFormatIdx() == FormatIdx &&
+        F->getFirstArg() == FirstArg) {
       // If we don't have a valid location for this attribute, adopt the
       // location.
-      if (f->getLocation().isInvalid())
-        f->setRange(Range);
-      return NULL;
+      if (F->getLocation().isInvalid())
+        F->setRange(Range);
+      return nullptr;
     }
   }
 
@@ -3102,17 +2476,10 @@
     return;
   }
 
-  if (!isFunctionOrMethodOrBlock(D) || !hasFunctionProto(D)) {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
-      << Attr.getName() << ExpectedFunction;
-    return;
-  }
-
   // In C++ the implicit 'this' function parameter also counts, and they are
   // counted from one.
   bool HasImplicitThisParam = isInstanceMethod(D);
-  unsigned NumArgs  = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
-  unsigned FirstIdx = 1;
+  unsigned NumArgs = getFunctionOrMethodNumParams(D) + HasImplicitThisParam;
 
   IdentifierInfo *II = Attr.getArgAsIdent(0)->Ident;
   StringRef Format = II->getName();
@@ -3132,29 +2499,24 @@
   
   if (Kind == InvalidFormat) {
     S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
-      << "format" << II->getName();
+      << Attr.getName() << II->getName();
     return;
   }
 
   // checks for the 2nd argument
   Expr *IdxExpr = Attr.getArgAsExpr(1);
-  llvm::APSInt Idx(32);
-  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
-      !IdxExpr->isIntegerConstantExpr(Idx, S.Context)) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
-      << Attr.getName() << 2 << AANT_ArgumentIntegerConstant
-      << IdxExpr->getSourceRange();
+  uint32_t Idx;
+  if (!checkUInt32Argument(S, Attr, IdxExpr, Idx, 2))
     return;
-  }
 
-  if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) {
+  if (Idx < 1 || Idx > NumArgs) {
     S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
-      << "format" << 2 << IdxExpr->getSourceRange();
+      << Attr.getName() << 2 << IdxExpr->getSourceRange();
     return;
   }
 
   // FIXME: Do we need to bounds check?
-  unsigned ArgIdx = Idx.getZExtValue() - 1;
+  unsigned ArgIdx = Idx - 1;
 
   if (HasImplicitThisParam) {
     if (ArgIdx == 0) {
@@ -3167,7 +2529,7 @@
   }
 
   // make sure the format string is really a string
-  QualType Ty = getFunctionOrMethodArgType(D, ArgIdx);
+  QualType Ty = getFunctionOrMethodParamType(D, ArgIdx);
 
   if (Kind == CFStringFormat) {
     if (!isCFStringType(Ty, S.Context)) {
@@ -3194,14 +2556,9 @@
 
   // check the 3rd argument
   Expr *FirstArgExpr = Attr.getArgAsExpr(2);
-  llvm::APSInt FirstArg(32);
-  if (FirstArgExpr->isTypeDependent() || FirstArgExpr->isValueDependent() ||
-      !FirstArgExpr->isIntegerConstantExpr(FirstArg, S.Context)) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
-      << Attr.getName() << 3 << AANT_ArgumentIntegerConstant
-      << FirstArgExpr->getSourceRange();
+  uint32_t FirstArg;
+  if (!checkUInt32Argument(S, Attr, FirstArgExpr, FirstArg, 3))
     return;
-  }
 
   // check if the function is variadic if the 3rd argument non-zero
   if (FirstArg != 0) {
@@ -3224,13 +2581,12 @@
   // if 0 it disables parameter checking (to use with e.g. va_list)
   } else if (FirstArg != 0 && FirstArg != NumArgs) {
     S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
-      << "format" << 3 << FirstArgExpr->getSourceRange();
+      << Attr.getName() << 3 << FirstArgExpr->getSourceRange();
     return;
   }
 
   FormatAttr *NewAttr = S.mergeFormatAttr(D, Attr.getRange(), II,
-                                          Idx.getZExtValue(),
-                                          FirstArg.getZExtValue(),
+                                          Idx, FirstArg,
                                           Attr.getAttributeSpellingListIndex());
   if (NewAttr)
     D->addAttr(NewAttr);
@@ -3239,7 +2595,7 @@
 static void handleTransparentUnionAttr(Sema &S, Decl *D,
                                        const AttributeList &Attr) {
   // Try to find the underlying union declaration.
-  RecordDecl *RD = 0;
+  RecordDecl *RD = nullptr;
   TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
   if (TD && TD->getUnderlyingType()->isUnionType())
     RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
@@ -3278,8 +2634,13 @@
   uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
   for (; Field != FieldEnd; ++Field) {
     QualType FieldType = Field->getType();
+    // FIXME: this isn't fully correct; we also need to test whether the
+    // members of the union would all have the same calling convention as the
+    // first member of the union. Checking just the size and alignment isn't
+    // sufficient (consider structs passed on the stack instead of in registers
+    // as an example).
     if (S.Context.getTypeSize(FieldType) != FirstSize ||
-        S.Context.getTypeAlign(FieldType) != FirstAlign) {
+        S.Context.getTypeAlign(FieldType) > FirstAlign) {
       // Warn if we drop the attribute.
       bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
       unsigned FieldBits = isSize? S.Context.getTypeSize(FieldType)
@@ -3308,10 +2669,8 @@
     return;
 
   // Don't duplicate annotations that are already set.
-  for (specific_attr_iterator<AnnotateAttr>
-       i = D->specific_attr_begin<AnnotateAttr>(),
-       e = D->specific_attr_end<AnnotateAttr>(); i != e; ++i) {
-    if ((*i)->getAnnotation() == Str)
+  for (const auto *I : D->specific_attrs<AnnotateAttr>()) {
+    if (I->getAnnotation() == Str)
       return;
   }
   
@@ -3330,7 +2689,7 @@
 
   if (Attr.getNumArgs() == 0) {
     D->addAttr(::new (S.Context) AlignedAttr(Attr.getRange(), S.Context,
-               true, 0, Attr.getAttributeSpellingListIndex()));
+               true, nullptr, Attr.getAttributeSpellingListIndex()));
     return;
   }
 
@@ -3378,15 +2737,14 @@
       if (FD->isBitField())
         DiagKind = 3;
     } else if (!isa<TagDecl>(D)) {
-      Diag(AttrLoc, diag::err_attribute_wrong_decl_type)
-        << (TmpAttr.isC11() ? "'_Alignas'" : "'alignas'")
+      Diag(AttrLoc, diag::err_attribute_wrong_decl_type) << &TmpAttr
         << (TmpAttr.isC11() ? ExpectedVariableOrField
                             : ExpectedVariableFieldOrTag);
       return;
     }
     if (DiagKind != -1) {
       Diag(AttrLoc, diag::err_alignas_attribute_wrong_decl_type)
-        << TmpAttr.isC11() << DiagKind;
+        << &TmpAttr << DiagKind;
       return;
     }
   }
@@ -3420,18 +2778,16 @@
     return;
   }
 
-  if (TmpAttr.isDeclspec()) {
-    // We've already verified it's a power of 2, now let's make sure it's
-    // 8192 or less.
-    if (Alignment.getZExtValue() > 8192) {
-      Diag(AttrLoc, diag::err_attribute_aligned_greater_than_8192)
-        << E->getSourceRange();
-      return;
-    }
+  // Alignment calculations can wrap around if it's greater than 2**28.
+  unsigned MaxValidAlignment = TmpAttr.isDeclspec() ? 8192 : 268435456;
+  if (Alignment.getZExtValue() > MaxValidAlignment) {
+    Diag(AttrLoc, diag::err_attribute_aligned_too_great) << MaxValidAlignment
+                                                         << E->getSourceRange();
+    return;
   }
 
   AlignedAttr *AA = ::new (Context) AlignedAttr(AttrRange, Context, true,
-                                                ICE.take(), SpellingListIndex);
+                                                ICE.get(), SpellingListIndex);
   AA->setPackExpansion(IsPackExpansion);
   D->addAttr(AA);
 }
@@ -3461,15 +2817,13 @@
   //   The combined effect of all alignment attributes in a declaration shall
   //   not specify an alignment that is less strict than the alignment that
   //   would otherwise be required for the entity being declared.
-  AlignedAttr *AlignasAttr = 0;
+  AlignedAttr *AlignasAttr = nullptr;
   unsigned Align = 0;
-  for (specific_attr_iterator<AlignedAttr>
-         I = D->specific_attr_begin<AlignedAttr>(),
-         E = D->specific_attr_end<AlignedAttr>(); I != E; ++I) {
+  for (auto *I : D->specific_attrs<AlignedAttr>()) {
     if (I->isAlignmentDependent())
       return;
     if (I->isAlignas())
-      AlignasAttr = *I;
+      AlignasAttr = I;
     Align = std::max(Align, I->getAlignment(Context));
   }
 
@@ -3482,6 +2836,35 @@
   }
 }
 
+bool Sema::checkMSInheritanceAttrOnDefinition(
+    CXXRecordDecl *RD, SourceRange Range, bool BestCase,
+    MSInheritanceAttr::Spelling SemanticSpelling) {
+  assert(RD->hasDefinition() && "RD has no definition!");
+
+  // We may not have seen base specifiers or any virtual methods yet.  We will
+  // have to wait until the record is defined to catch any mismatches.
+  if (!RD->getDefinition()->isCompleteDefinition())
+    return false;
+
+  // The unspecified model never matches what a definition could need.
+  if (SemanticSpelling == MSInheritanceAttr::Keyword_unspecified_inheritance)
+    return false;
+
+  if (BestCase) {
+    if (RD->calculateInheritanceModel() == SemanticSpelling)
+      return false;
+  } else {
+    if (RD->calculateInheritanceModel() <= SemanticSpelling)
+      return false;
+  }
+
+  Diag(Range.getBegin(), diag::err_mismatched_ms_inheritance)
+      << 0 /*definition*/;
+  Diag(RD->getDefinition()->getLocation(), diag::note_defined_here)
+      << RD->getNameAsString();
+  return true;
+}
+
 /// handleModeAttr - This attribute modifies the width of a decl with primitive
 /// type.
 ///
@@ -3551,7 +2934,7 @@
     OldTy = VD->getType();
   else {
     S.Diag(D->getLocation(), diag::err_attr_wrong_decl)
-      << "mode" << Attr.getRange();
+      << Attr.getName() << Attr.getRange();
     return;
   }
 
@@ -3573,7 +2956,7 @@
   // FIXME: Make sure floating-point mappings are accurate
   // FIXME: Support XF and TF types
   if (!DestWidth) {
-    S.Diag(Attr.getLoc(), diag::err_unknown_machine_mode) << Name;
+    S.Diag(Attr.getLoc(), diag::err_machine_mode) << 0 /*Unknown*/ << Name;
     return;
   }
 
@@ -3586,7 +2969,7 @@
     NewTy = S.Context.getRealTypeForBitwidth(DestWidth);
 
   if (NewTy.isNull()) {
-    S.Diag(Attr.getLoc(), diag::err_unsupported_machine_mode) << Name;
+    S.Diag(Attr.getLoc(), diag::err_machine_mode) << 1 /*Unsupported*/ << Name;
     return;
   }
 
@@ -3623,141 +3006,44 @@
                          Attr.getAttributeSpellingListIndex()));
 }
 
-static void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  if (!isa<FunctionDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
-      << Attr.getName() << ExpectedFunction;
+static void handleAlwaysInlineAttr(Sema &S, Decl *D,
+                                   const AttributeList &Attr) {
+  if (checkAttrMutualExclusion<OptimizeNoneAttr>(S, D, Attr))
     return;
-  }
 
   D->addAttr(::new (S.Context)
-             NoInlineAttr(Attr.getRange(), S.Context,
-             Attr.getAttributeSpellingListIndex()));
-}
-
-static void handleNoInstrumentFunctionAttr(Sema &S, Decl *D,
-                                           const AttributeList &Attr) {
-  if (!isa<FunctionDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
-      << Attr.getName() << ExpectedFunction;
-    return;
-  }
-
-  D->addAttr(::new (S.Context)
-             NoInstrumentFunctionAttr(Attr.getRange(), S.Context,
-                                      Attr.getAttributeSpellingListIndex()));
-}
-
-static void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  if (S.LangOpts.CUDA) {
-    if (!isa<VarDecl>(D)) {
-      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
-        << Attr.getName() << ExpectedVariable;
-      return;
-    }
-
-    D->addAttr(::new (S.Context)
-               CUDAConstantAttr(Attr.getRange(), S.Context,
-                                Attr.getAttributeSpellingListIndex()));
-  } else {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant";
-  }
-}
-
-static void handleDeviceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  if (S.LangOpts.CUDA) {
-    // check the attribute arguments.
-    if (Attr.getNumArgs() != 0) {
-      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
-        << Attr.getName() << 0;
-      return;
-    }
-
-    if (!isa<FunctionDecl>(D) && !isa<VarDecl>(D)) {
-      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
-        << Attr.getName() << ExpectedVariableOrFunction;
-      return;
-    }
-
-    D->addAttr(::new (S.Context)
-               CUDADeviceAttr(Attr.getRange(), S.Context,
+             AlwaysInlineAttr(Attr.getRange(), S.Context,
                               Attr.getAttributeSpellingListIndex()));
-  } else {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device";
-  }
+}
+
+static void handleOptimizeNoneAttr(Sema &S, Decl *D,
+                                   const AttributeList &Attr) {
+  if (checkAttrMutualExclusion<AlwaysInlineAttr>(S, D, Attr))
+    return;
+
+  D->addAttr(::new (S.Context)
+             OptimizeNoneAttr(Attr.getRange(), S.Context,
+                              Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  if (S.LangOpts.CUDA) {
-    if (!isa<FunctionDecl>(D)) {
-      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
-        << Attr.getName() << ExpectedFunction;
-      return;
-    }
-
-    FunctionDecl *FD = cast<FunctionDecl>(D);
-    if (!FD->getResultType()->isVoidType()) {
-      TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
-      if (FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>()) {
-        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
-          << FD->getType()
-          << FixItHint::CreateReplacement(FTL.getResultLoc().getSourceRange(),
-                                          "void");
-      } else {
-        S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
-          << FD->getType();
-      }
-      return;
-    }
-
-    D->addAttr(::new (S.Context)
-               CUDAGlobalAttr(Attr.getRange(), S.Context,
-                              Attr.getAttributeSpellingListIndex()));
-  } else {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global";
-  }
-}
-
-static void handleHostAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  if (S.LangOpts.CUDA) {
-    if (!isa<FunctionDecl>(D)) {
-      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
-        << Attr.getName() << ExpectedFunction;
-      return;
-    }
-
-    D->addAttr(::new (S.Context)
-               CUDAHostAttr(Attr.getRange(), S.Context,
-                            Attr.getAttributeSpellingListIndex()));
-  } else {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host";
-  }
-}
-
-static void handleSharedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  if (S.LangOpts.CUDA) {
-    if (!isa<VarDecl>(D)) {
-      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
-        << Attr.getName() << ExpectedVariable;
-      return;
-    }
-
-    D->addAttr(::new (S.Context)
-               CUDASharedAttr(Attr.getRange(), S.Context,
-                              Attr.getAttributeSpellingListIndex()));
-  } else {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared";
-  }
-}
-
-static void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  FunctionDecl *Fn = dyn_cast<FunctionDecl>(D);
-  if (Fn == 0) {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
-      << Attr.getName() << ExpectedFunction;
+  FunctionDecl *FD = cast<FunctionDecl>(D);
+  if (!FD->getReturnType()->isVoidType()) {
+    SourceRange RTRange = FD->getReturnTypeSourceRange();
+    S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
+        << FD->getType()
+        << (RTRange.isValid() ? FixItHint::CreateReplacement(RTRange, "void")
+                              : FixItHint());
     return;
   }
 
+  D->addAttr(::new (S.Context)
+              CUDAGlobalAttr(Attr.getRange(), S.Context,
+                            Attr.getAttributeSpellingListIndex()));
+}
+
+static void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+  FunctionDecl *Fn = cast<FunctionDecl>(D);
   if (!Fn->isInlineSpecified()) {
     S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
     return;
@@ -3854,25 +3140,6 @@
   }
 }
 
-static void handleOpenCLKernelAttr(Sema &S, Decl *D, const AttributeList &Attr){
-  D->addAttr(::new (S.Context) OpenCLKernelAttr(Attr.getRange(), S.Context));
-}
-
-static void handleOpenCLImageAccessAttr(Sema &S, Decl *D, const AttributeList &Attr){
-  Expr *E = Attr.getArgAsExpr(0);
-  llvm::APSInt ArgNum(32);
-  if (E->isTypeDependent() || E->isValueDependent() ||
-      !E->isIntegerConstantExpr(ArgNum, S.Context)) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
-      << Attr.getName() << AANT_ArgumentIntegerConstant
-      << E->getSourceRange();
-    return;
-  }
-
-  D->addAttr(::new (S.Context) OpenCLImageAccessAttr(
-    Attr.getRange(), S.Context, ArgNum.getZExtValue()));
-}
-
 bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC, 
                                 const FunctionDecl *FD) {
   if (attr.isInvalid())
@@ -3884,8 +3151,7 @@
     return true;
   }
 
-  // TODO: diagnose uses of these conventions on the wrong target. Or, better
-  // move to TargetAttributesSema one day.
+  // TODO: diagnose uses of these conventions on the wrong target.
   switch (attr.getKind()) {
   case AttributeList::AT_CDecl: CC = CC_C; break;
   case AttributeList::AT_FastCall: CC = CC_X86FastCall; break;
@@ -3938,24 +3204,6 @@
   return false;
 }
 
-static void handleRegparmAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  if (hasDeclarator(D)) return;
-
-  unsigned numParams;
-  if (S.CheckRegparmAttr(Attr, numParams))
-    return;
-
-  if (!isa<ObjCMethodDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
-      << Attr.getName() << ExpectedFunctionOrMethod;
-    return;
-  }
-
-  D->addAttr(::new (S.Context)
-             RegparmAttr(Attr.getRange(), S.Context, numParams,
-                         Attr.getAttributeSpellingListIndex()));
-}
-
 /// Checks a regparm attribute, returning true if it is ill-formed and
 /// otherwise setting numParams to the appropriate value.
 bool Sema::CheckRegparmAttr(const AttributeList &Attr, unsigned &numParams) {
@@ -3967,13 +3215,9 @@
     return true;
   }
 
+  uint32_t NP;
   Expr *NumParamsExpr = Attr.getArgAsExpr(0);
-  llvm::APSInt NumParams(32);
-  if (NumParamsExpr->isTypeDependent() || NumParamsExpr->isValueDependent() ||
-      !NumParamsExpr->isIntegerConstantExpr(NumParams, Context)) {
-    Diag(Attr.getLoc(), diag::err_attribute_argument_type)
-      << Attr.getName() << AANT_ArgumentIntegerConstant
-      << NumParamsExpr->getSourceRange();
+  if (!checkUInt32Argument(*this, Attr, NumParamsExpr, NP)) {
     Attr.setInvalid();
     return true;
   }
@@ -3985,7 +3229,7 @@
     return true;
   }
 
-  numParams = NumParams.getZExtValue();
+  numParams = NP;
   if (numParams > Context.getTargetInfo().getRegParmMax()) {
     Diag(Attr.getLoc(), diag::err_attribute_regparm_invalid_number)
       << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange();
@@ -3996,53 +3240,28 @@
   return false;
 }
 
-static void handleLaunchBoundsAttr(Sema &S, Decl *D, const AttributeList &Attr){
-  if (S.LangOpts.CUDA) {
-    // check the attribute arguments.
-    if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) {
-      // FIXME: 0 is not okay.
-      S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
-      return;
-    }
-
-    if (!isFunctionOrMethod(D)) {
-      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
-        << Attr.getName() << ExpectedFunctionOrMethod;
-      return;
-    }
-
-    Expr *MaxThreadsExpr = Attr.getArgAsExpr(0);
-    llvm::APSInt MaxThreads(32);
-    if (MaxThreadsExpr->isTypeDependent() ||
-        MaxThreadsExpr->isValueDependent() ||
-        !MaxThreadsExpr->isIntegerConstantExpr(MaxThreads, S.Context)) {
-      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
-        << Attr.getName() << 1 << AANT_ArgumentIntegerConstant
-        << MaxThreadsExpr->getSourceRange();
-      return;
-    }
-
-    llvm::APSInt MinBlocks(32);
-    if (Attr.getNumArgs() > 1) {
-      Expr *MinBlocksExpr = Attr.getArgAsExpr(1);
-      if (MinBlocksExpr->isTypeDependent() ||
-          MinBlocksExpr->isValueDependent() ||
-          !MinBlocksExpr->isIntegerConstantExpr(MinBlocks, S.Context)) {
-        S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
-          << Attr.getName() << 2 << AANT_ArgumentIntegerConstant
-          << MinBlocksExpr->getSourceRange();
-        return;
-      }
-    }
-
-    D->addAttr(::new (S.Context)
-               CUDALaunchBoundsAttr(Attr.getRange(), S.Context,
-                                    MaxThreads.getZExtValue(),
-                                    MinBlocks.getZExtValue(),
-                                    Attr.getAttributeSpellingListIndex()));
-  } else {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds";
+static void handleLaunchBoundsAttr(Sema &S, Decl *D,
+                                   const AttributeList &Attr) {
+  // check the attribute arguments.
+  if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) {
+    // FIXME: 0 is not okay.
+    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments)
+      << Attr.getName() << 2;
+    return;
   }
+
+  uint32_t MaxThreads, MinBlocks = 0;
+  if (!checkUInt32Argument(S, Attr, Attr.getArgAsExpr(0), MaxThreads, 1))
+    return;
+  if (Attr.getNumArgs() > 1 && !checkUInt32Argument(S, Attr,
+                                                    Attr.getArgAsExpr(1),
+                                                    MinBlocks, 2))
+    return;
+
+  D->addAttr(::new (S.Context)
+              CUDALaunchBoundsAttr(Attr.getRange(), S.Context,
+                                  MaxThreads, MinBlocks,
+                                  Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleArgumentWithTypeTagAttr(Sema &S, Decl *D,
@@ -4056,7 +3275,6 @@
   if (!checkAttributeNumArgs(S, Attr, 3))
     return;
 
-  StringRef AttrName = Attr.getName()->getName();
   IdentifierInfo *ArgumentKind = Attr.getArgAsIdent(0)->Ident;
 
   if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
@@ -4066,21 +3284,19 @@
   }
 
   uint64_t ArgumentIdx;
-  if (!checkFunctionOrMethodArgumentIndex(S, D, AttrName,
-                                          Attr.getLoc(), 2,
-                                          Attr.getArgAsExpr(1), ArgumentIdx))
+  if (!checkFunctionOrMethodParameterIndex(S, D, Attr, 2, Attr.getArgAsExpr(1),
+                                           ArgumentIdx))
     return;
 
   uint64_t TypeTagIdx;
-  if (!checkFunctionOrMethodArgumentIndex(S, D, AttrName,
-                                          Attr.getLoc(), 3,
-                                          Attr.getArgAsExpr(2), TypeTagIdx))
+  if (!checkFunctionOrMethodParameterIndex(S, D, Attr, 3, Attr.getArgAsExpr(2),
+                                           TypeTagIdx))
     return;
 
-  bool IsPointer = (AttrName == "pointer_with_type_tag");
+  bool IsPointer = (Attr.getName()->getName() == "pointer_with_type_tag");
   if (IsPointer) {
     // Ensure that buffer has a pointer type.
-    QualType BufferTy = getFunctionOrMethodArgType(D, ArgumentIdx);
+    QualType BufferTy = getFunctionOrMethodParamType(D, ArgumentIdx);
     if (!BufferTy->isPointerType()) {
       S.Diag(Attr.getLoc(), diag::err_attribute_pointers_only)
         << Attr.getName();
@@ -4104,8 +3320,14 @@
   if (!checkAttributeNumArgs(S, Attr, 1))
     return;
 
+  if (!isa<VarDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedVariable;
+    return;
+  }
+
   IdentifierInfo *PointerKind = Attr.getArgAsIdent(0)->Ident;
-  TypeSourceInfo *MatchingCTypeLoc = 0;
+  TypeSourceInfo *MatchingCTypeLoc = nullptr;
   S.GetTypeFromParser(Attr.getMatchingCType(), &MatchingCTypeLoc);
   assert(MatchingCTypeLoc && "no type source info for attribute argument");
 
@@ -4121,6 +3343,11 @@
 // Checker-specific attribute handlers.
 //===----------------------------------------------------------------------===//
 
+static bool isValidSubjectOfNSReturnsRetainedAttribute(QualType type) {
+  return type->isDependentType() ||
+         type->isObjCRetainableType();
+}
+
 static bool isValidSubjectOfNSAttribute(Sema &S, QualType type) {
   return type->isDependentType() || 
          type->isObjCObjectPointerType() || 
@@ -4133,14 +3360,9 @@
 }
 
 static void handleNSConsumedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  ParmVarDecl *param = dyn_cast<ParmVarDecl>(D);
-  if (!param) {
-    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
-      << Attr.getRange() << Attr.getName() << ExpectedParameter;
-    return;
-  }
-
+  ParmVarDecl *param = cast<ParmVarDecl>(D);
   bool typeOK, cf;
+
   if (Attr.getKind() == AttributeList::AT_NSConsumed) {
     typeOK = isValidSubjectOfNSAttribute(S, param->getType());
     cf = false;
@@ -4165,33 +3387,20 @@
                                   Attr.getAttributeSpellingListIndex()));
 }
 
-static void handleNSConsumesSelfAttr(Sema &S, Decl *D,
-                                     const AttributeList &Attr) {
-  if (!isa<ObjCMethodDecl>(D)) {
-    S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
-      << Attr.getRange() << Attr.getName() << ExpectedMethod;
-    return;
-  }
-
-  D->addAttr(::new (S.Context)
-             NSConsumesSelfAttr(Attr.getRange(), S.Context,
-                                Attr.getAttributeSpellingListIndex()));
-}
-
 static void handleNSReturnsRetainedAttr(Sema &S, Decl *D,
                                         const AttributeList &Attr) {
 
   QualType returnType;
 
   if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
-    returnType = MD->getResultType();
+    returnType = MD->getReturnType();
   else if (S.getLangOpts().ObjCAutoRefCount && hasDeclarator(D) &&
            (Attr.getKind() == AttributeList::AT_NSReturnsRetained))
     return; // ignore: was handled as a type attribute
   else if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
     returnType = PD->getType();
   else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
-    returnType = FD->getResultType();
+    returnType = FD->getReturnType();
   else {
     S.Diag(D->getLocStart(), diag::warn_attribute_wrong_decl_type)
         << Attr.getRange() << Attr.getName()
@@ -4203,8 +3412,12 @@
   bool cf;
   switch (Attr.getKind()) {
   default: llvm_unreachable("invalid ownership attribute");
-  case AttributeList::AT_NSReturnsAutoreleased:
   case AttributeList::AT_NSReturnsRetained:
+    typeOK = isValidSubjectOfNSReturnsRetainedAttribute(returnType);
+    cf = false;
+    break;
+      
+  case AttributeList::AT_NSReturnsAutoreleased:
   case AttributeList::AT_NSReturnsNotRetained:
     typeOK = isValidSubjectOfNSAttribute(S, returnType);
     cf = false;
@@ -4261,27 +3474,17 @@
   
   SourceLocation loc = attr.getLoc();
   QualType resultType;
-  
-  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D);
-
-  if (!method) {
-    ObjCPropertyDecl *property = dyn_cast<ObjCPropertyDecl>(D);
-    if (!property) {
-      S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
-        << SourceRange(loc, loc) << attr.getName() << ExpectedMethodOrProperty;
-      return;
-    }
-    resultType = property->getType();
-  }
+  if (isa<ObjCMethodDecl>(D))
+    resultType = cast<ObjCMethodDecl>(D)->getReturnType();
   else
-    // Check that the method returns a normal pointer.
-    resultType = method->getResultType();
+    resultType = cast<ObjCPropertyDecl>(D)->getType();
 
   if (!resultType->isReferenceType() &&
       (!resultType->isPointerType() || resultType->isObjCRetainableType())) {
     S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_return_type)
       << SourceRange(loc)
-    << attr.getName() << (method ? EP_ObjCMethod : EP_ObjCProperty)
+    << attr.getName()
+    << (isa<ObjCMethodDecl>(D) ? EP_ObjCMethod : EP_ObjCProperty)
     << /*non-retainable pointer*/ 2;
 
     // Drop the attribute.
@@ -4295,14 +3498,8 @@
 
 static void handleObjCRequiresSuperAttr(Sema &S, Decl *D,
                                         const AttributeList &attr) {
-  SourceLocation loc = attr.getLoc();
-  ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(D);
+  ObjCMethodDecl *method = cast<ObjCMethodDecl>(D);
   
-  if (!method) {
-   S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
-   << SourceRange(loc, loc) << attr.getName() << ExpectedMethod;
-    return;
-  }
   DeclContext *DC = method->getDeclContext();
   if (const ObjCProtocolDecl *PDecl = dyn_cast_or_null<ObjCProtocolDecl>(DC)) {
     S.Diag(D->getLocStart(), diag::warn_objc_requires_super_protocol)
@@ -4321,97 +3518,96 @@
                                         attr.getAttributeSpellingListIndex()));
 }
 
-/// Handle cf_audited_transfer and cf_unknown_transfer.
-static void handleCFTransferAttr(Sema &S, Decl *D, const AttributeList &A) {
-  if (!isa<FunctionDecl>(D)) {
-    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
-      << A.getRange() << A.getName() << ExpectedFunction;
+static void handleCFAuditedTransferAttr(Sema &S, Decl *D,
+                                        const AttributeList &Attr) {
+  if (checkAttrMutualExclusion<CFUnknownTransferAttr>(S, D, Attr))
     return;
-  }
-
-  bool IsAudited = (A.getKind() == AttributeList::AT_CFAuditedTransfer);
-
-  // Check whether there's a conflicting attribute already present.
-  Attr *Existing;
-  if (IsAudited) {
-    Existing = D->getAttr<CFUnknownTransferAttr>();
-  } else {
-    Existing = D->getAttr<CFAuditedTransferAttr>();
-  }
-  if (Existing) {
-    S.Diag(D->getLocStart(), diag::err_attributes_are_not_compatible)
-      << A.getName()
-      << (IsAudited ? "cf_unknown_transfer" : "cf_audited_transfer")
-      << A.getRange() << Existing->getRange();
-    return;
-  }
-
-  // All clear;  add the attribute.
-  if (IsAudited) {
-    D->addAttr(::new (S.Context)
-               CFAuditedTransferAttr(A.getRange(), S.Context,
-                                     A.getAttributeSpellingListIndex()));
-  } else {
-    D->addAttr(::new (S.Context)
-               CFUnknownTransferAttr(A.getRange(), S.Context,
-                                     A.getAttributeSpellingListIndex()));
-  }
-}
-
-static void handleNSBridgedAttr(Sema &S, Scope *Sc, Decl *D,
-                                const AttributeList &Attr) {
-  RecordDecl *RD = dyn_cast<RecordDecl>(D);
-  if (!RD || RD->isUnion()) {
-    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
-      << Attr.getRange() << Attr.getName() << ExpectedStruct;
-  }
-
-  IdentifierLoc *Parm = Attr.isArgIdent(0) ? Attr.getArgAsIdent(0) : 0;
-
-  // In Objective-C, verify that the type names an Objective-C type.
-  // We don't want to check this outside of ObjC because people sometimes
-  // do crazy C declarations of Objective-C types.
-  if (Parm && S.getLangOpts().ObjC1) {
-    // Check for an existing type with this name.
-    LookupResult R(S, DeclarationName(Parm->Ident), Parm->Loc,
-                   Sema::LookupOrdinaryName);
-    if (S.LookupName(R, Sc)) {
-      NamedDecl *Target = R.getFoundDecl();
-      if (Target && !isa<ObjCInterfaceDecl>(Target)) {
-        S.Diag(D->getLocStart(), diag::err_ns_bridged_not_interface);
-        S.Diag(Target->getLocStart(), diag::note_declared_at);
-      }
-    }
-  }
 
   D->addAttr(::new (S.Context)
-             NSBridgedAttr(Attr.getRange(), S.Context, Parm ? Parm->Ident : 0,
-                           Attr.getAttributeSpellingListIndex()));
+             CFAuditedTransferAttr(Attr.getRange(), S.Context,
+                                   Attr.getAttributeSpellingListIndex()));
+}
+
+static void handleCFUnknownTransferAttr(Sema &S, Decl *D,
+                                        const AttributeList &Attr) {
+  if (checkAttrMutualExclusion<CFAuditedTransferAttr>(S, D, Attr))
+    return;
+
+  D->addAttr(::new (S.Context)
+             CFUnknownTransferAttr(Attr.getRange(), S.Context,
+             Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleObjCBridgeAttr(Sema &S, Scope *Sc, Decl *D,
                                 const AttributeList &Attr) {
-  if (!isa<RecordDecl>(D)) {
-    S.Diag(D->getLocStart(), diag::err_objc_bridge_attribute)
-      << S.getLangOpts().CPlusPlus;
-    return;
-  }
-  
-  if (Attr.getNumArgs() != 1) {
-    S.Diag(D->getLocStart(), diag::err_objc_bridge_not_id);
-    return;
-  }
-  IdentifierLoc *Parm = Attr.isArgIdent(0) ? Attr.getArgAsIdent(0) : 0;
+  IdentifierLoc * Parm = Attr.isArgIdent(0) ? Attr.getArgAsIdent(0) : nullptr;
+
   if (!Parm) {
-    S.Diag(D->getLocStart(), diag::err_objc_bridge_not_id);
+    S.Diag(D->getLocStart(), diag::err_objc_attr_not_id) << Attr.getName() << 0;
     return;
   }
   
   D->addAttr(::new (S.Context)
-             ObjCBridgeAttr(Attr.getRange(), S.Context, Parm ? Parm->Ident : 0,
+             ObjCBridgeAttr(Attr.getRange(), S.Context, Parm->Ident,
                            Attr.getAttributeSpellingListIndex()));
 }
 
+static void handleObjCBridgeMutableAttr(Sema &S, Scope *Sc, Decl *D,
+                                        const AttributeList &Attr) {
+  IdentifierLoc * Parm = Attr.isArgIdent(0) ? Attr.getArgAsIdent(0) : nullptr;
+
+  if (!Parm) {
+    S.Diag(D->getLocStart(), diag::err_objc_attr_not_id) << Attr.getName() << 0;
+    return;
+  }
+  
+  D->addAttr(::new (S.Context)
+             ObjCBridgeMutableAttr(Attr.getRange(), S.Context, Parm->Ident,
+                            Attr.getAttributeSpellingListIndex()));
+}
+
+static void handleObjCBridgeRelatedAttr(Sema &S, Scope *Sc, Decl *D,
+                                 const AttributeList &Attr) {
+  IdentifierInfo *RelatedClass =
+    Attr.isArgIdent(0) ? Attr.getArgAsIdent(0)->Ident : nullptr;
+  if (!RelatedClass) {
+    S.Diag(D->getLocStart(), diag::err_objc_attr_not_id) << Attr.getName() << 0;
+    return;
+  }
+  IdentifierInfo *ClassMethod =
+    Attr.getArgAsIdent(1) ? Attr.getArgAsIdent(1)->Ident : nullptr;
+  IdentifierInfo *InstanceMethod =
+    Attr.getArgAsIdent(2) ? Attr.getArgAsIdent(2)->Ident : nullptr;
+  D->addAttr(::new (S.Context)
+             ObjCBridgeRelatedAttr(Attr.getRange(), S.Context, RelatedClass,
+                                   ClassMethod, InstanceMethod,
+                                   Attr.getAttributeSpellingListIndex()));
+}
+
+static void handleObjCDesignatedInitializer(Sema &S, Decl *D,
+                                            const AttributeList &Attr) {
+  ObjCInterfaceDecl *IFace;
+  if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(D->getDeclContext()))
+    IFace = CatDecl->getClassInterface();
+  else
+    IFace = cast<ObjCInterfaceDecl>(D->getDeclContext());
+  IFace->setHasDesignatedInitializers();
+  D->addAttr(::new (S.Context)
+                  ObjCDesignatedInitializerAttr(Attr.getRange(), S.Context,
+                                         Attr.getAttributeSpellingListIndex()));
+}
+
+static void handleObjCRuntimeName(Sema &S, Decl *D,
+                                  const AttributeList &Attr) {
+  StringRef MetaDataName;
+  if (!S.checkStringLiteralArgumentAttr(Attr, 0, MetaDataName))
+    return;
+  D->addAttr(::new (S.Context)
+             ObjCRuntimeNameAttr(Attr.getRange(), S.Context,
+                                 MetaDataName,
+                                 Attr.getAttributeSpellingListIndex()));
+}
+
 static void handleObjCOwnershipAttr(Sema &S, Decl *D,
                                     const AttributeList &Attr) {
   if (hasDeclarator(D)) return;
@@ -4422,12 +3618,6 @@
 
 static void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D,
                                           const AttributeList &Attr) {
-  if (!isa<VarDecl>(D) && !isa<FieldDecl>(D)) {
-    S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
-      << Attr.getRange() << Attr.getName() << ExpectedVariable;
-    return;
-  }
-
   ValueDecl *vd = cast<ValueDecl>(D);
   QualType type = vd->getType();
 
@@ -4471,19 +3661,18 @@
 // Microsoft specific attribute handlers.
 //===----------------------------------------------------------------------===//
 
-// Check if MS extensions or some other language extensions are enabled.  If
-// not, issue a diagnostic that the given attribute is unused.
-static bool checkMicrosoftExt(Sema &S, const AttributeList &Attr,
-                              bool OtherExtension = false) {
-  if (S.LangOpts.MicrosoftExt || OtherExtension)
-    return true;
-  S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
-  return false;
-}
-
 static void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  if (!checkMicrosoftExt(S, Attr, S.LangOpts.Borland))
+  if (!S.LangOpts.CPlusPlus) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_not_supported_in_lang)
+      << Attr.getName() << AttributeLangSupport::C;
     return;
+  }
+
+  if (!isa<CXXRecordDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedClass;
+    return;
+  }
 
   StringRef StrRef;
   SourceLocation LiteralLoc;
@@ -4517,55 +3706,299 @@
                                         Attr.getAttributeSpellingListIndex()));
 }
 
-static void handleInheritanceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  if (!checkMicrosoftExt(S, Attr))
+static void handleMSInheritanceAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+  if (!S.LangOpts.CPlusPlus) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_not_supported_in_lang)
+      << Attr.getName() << AttributeLangSupport::C;
     return;
-
-  AttributeList::Kind Kind = Attr.getKind();
-  if (Kind == AttributeList::AT_SingleInheritance)
-    D->addAttr(
-        ::new (S.Context)
-               SingleInheritanceAttr(Attr.getRange(), S.Context,
-                                     Attr.getAttributeSpellingListIndex()));
-  else if (Kind == AttributeList::AT_MultipleInheritance)
-    D->addAttr(
-        ::new (S.Context)
-               MultipleInheritanceAttr(Attr.getRange(), S.Context,
-                                       Attr.getAttributeSpellingListIndex()));
-  else if (Kind == AttributeList::AT_VirtualInheritance)
-    D->addAttr(
-        ::new (S.Context)
-               VirtualInheritanceAttr(Attr.getRange(), S.Context,
-                                      Attr.getAttributeSpellingListIndex()));
+  }
+  MSInheritanceAttr *IA = S.mergeMSInheritanceAttr(
+      D, Attr.getRange(), /*BestCase=*/true,
+      Attr.getAttributeSpellingListIndex(),
+      (MSInheritanceAttr::Spelling)Attr.getSemanticSpelling());
+  if (IA)
+    D->addAttr(IA);
 }
 
-static void handlePortabilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  if (!checkMicrosoftExt(S, Attr))
+static void handleDeclspecThreadAttr(Sema &S, Decl *D,
+                                     const AttributeList &Attr) {
+  VarDecl *VD = cast<VarDecl>(D);
+  if (!S.Context.getTargetInfo().isTLSSupported()) {
+    S.Diag(Attr.getLoc(), diag::err_thread_unsupported);
     return;
-
-  AttributeList::Kind Kind = Attr.getKind();
-    if (Kind == AttributeList::AT_Win64)
-    D->addAttr(
-        ::new (S.Context) Win64Attr(Attr.getRange(), S.Context,
-                                    Attr.getAttributeSpellingListIndex()));
+  }
+  if (VD->getTSCSpec() != TSCS_unspecified) {
+    S.Diag(Attr.getLoc(), diag::err_declspec_thread_on_thread_variable);
+    return;
+  }
+  if (VD->hasLocalStorage()) {
+    S.Diag(Attr.getLoc(), diag::err_thread_non_global) << "__declspec(thread)";
+    return;
+  }
+  VD->addAttr(::new (S.Context) ThreadAttr(
+      Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex()));
 }
 
-static void handleForceInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  if (!checkMicrosoftExt(S, Attr))
+static void handleARMInterruptAttr(Sema &S, Decl *D,
+                                   const AttributeList &Attr) {
+  // Check the attribute arguments.
+  if (Attr.getNumArgs() > 1) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments)
+      << Attr.getName() << 1;
     return;
+  }
+
+  StringRef Str;
+  SourceLocation ArgLoc;
+
+  if (Attr.getNumArgs() == 0)
+    Str = "";
+  else if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str, &ArgLoc))
+    return;
+
+  ARMInterruptAttr::InterruptType Kind;
+  if (!ARMInterruptAttr::ConvertStrToInterruptType(Str, Kind)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
+      << Attr.getName() << Str << ArgLoc;
+    return;
+  }
+
+  unsigned Index = Attr.getAttributeSpellingListIndex();
   D->addAttr(::new (S.Context)
-             ForceInlineAttr(Attr.getRange(), S.Context,
-                             Attr.getAttributeSpellingListIndex()));
+             ARMInterruptAttr(Attr.getLoc(), S.Context, Kind, Index));
 }
 
-static void handleSelectAnyAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  if (!checkMicrosoftExt(S, Attr))
+static void handleMSP430InterruptAttr(Sema &S, Decl *D,
+                                      const AttributeList &Attr) {
+  if (!checkAttributeNumArgs(S, Attr, 1))
     return;
-  // Check linkage after possibly merging declaratinos.  See
-  // checkAttributesAfterMerging().
+
+  if (!Attr.isArgExpr(0)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) << Attr.getName()
+      << AANT_ArgumentIntegerConstant;
+    return;    
+  }
+
+  // FIXME: Check for decl - it should be void ()(void).
+
+  Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArgAsExpr(0));
+  llvm::APSInt NumParams(32);
+  if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
+      << Attr.getName() << AANT_ArgumentIntegerConstant
+      << NumParamsExpr->getSourceRange();
+    return;
+  }
+
+  unsigned Num = NumParams.getLimitedValue(255);
+  if ((Num & 1) || Num > 30) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
+      << Attr.getName() << (int)NumParams.getSExtValue()
+      << NumParamsExpr->getSourceRange();
+    return;
+  }
+
   D->addAttr(::new (S.Context)
-             SelectAnyAttr(Attr.getRange(), S.Context,
-                           Attr.getAttributeSpellingListIndex()));
+              MSP430InterruptAttr(Attr.getLoc(), S.Context, Num,
+                                  Attr.getAttributeSpellingListIndex()));
+  D->addAttr(UsedAttr::CreateImplicit(S.Context));
+}
+
+static void handleInterruptAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+  // Dispatch the interrupt attribute based on the current target.
+  if (S.Context.getTargetInfo().getTriple().getArch() == llvm::Triple::msp430)
+    handleMSP430InterruptAttr(S, D, Attr);
+  else
+    handleARMInterruptAttr(S, D, Attr);
+}
+
+static void handleX86ForceAlignArgPointerAttr(Sema &S, Decl *D,
+                                              const AttributeList& Attr) {
+  // If we try to apply it to a function pointer, don't warn, but don't
+  // do anything, either. It doesn't matter anyway, because there's nothing
+  // special about calling a force_align_arg_pointer function.
+  ValueDecl *VD = dyn_cast<ValueDecl>(D);
+  if (VD && VD->getType()->isFunctionPointerType())
+    return;
+  // Also don't warn on function pointer typedefs.
+  TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
+  if (TD && (TD->getUnderlyingType()->isFunctionPointerType() ||
+    TD->getUnderlyingType()->isFunctionType()))
+    return;
+  // Attribute can only be applied to function types.
+  if (!isa<FunctionDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << /* function */0;
+    return;
+  }
+
+  D->addAttr(::new (S.Context)
+              X86ForceAlignArgPointerAttr(Attr.getRange(), S.Context,
+                                        Attr.getAttributeSpellingListIndex()));
+}
+
+DLLImportAttr *Sema::mergeDLLImportAttr(Decl *D, SourceRange Range,
+                                        unsigned AttrSpellingListIndex) {
+  if (D->hasAttr<DLLExportAttr>()) {
+    Diag(Range.getBegin(), diag::warn_attribute_ignored) << "'dllimport'";
+    return nullptr;
+  }
+
+  if (D->hasAttr<DLLImportAttr>())
+    return nullptr;
+
+  return ::new (Context) DLLImportAttr(Range, Context, AttrSpellingListIndex);
+}
+
+DLLExportAttr *Sema::mergeDLLExportAttr(Decl *D, SourceRange Range,
+                                        unsigned AttrSpellingListIndex) {
+  if (DLLImportAttr *Import = D->getAttr<DLLImportAttr>()) {
+    Diag(Import->getLocation(), diag::warn_attribute_ignored) << Import;
+    D->dropAttr<DLLImportAttr>();
+  }
+
+  if (D->hasAttr<DLLExportAttr>())
+    return nullptr;
+
+  return ::new (Context) DLLExportAttr(Range, Context, AttrSpellingListIndex);
+}
+
+static void handleDLLAttr(Sema &S, Decl *D, const AttributeList &A) {
+  if (isa<ClassTemplatePartialSpecializationDecl>(D) &&
+      S.Context.getTargetInfo().getCXXABI().isMicrosoft()) {
+    S.Diag(A.getRange().getBegin(), diag::warn_attribute_ignored)
+        << A.getName();
+    return;
+  }
+
+  unsigned Index = A.getAttributeSpellingListIndex();
+  Attr *NewAttr = A.getKind() == AttributeList::AT_DLLExport
+                      ? (Attr *)S.mergeDLLExportAttr(D, A.getRange(), Index)
+                      : (Attr *)S.mergeDLLImportAttr(D, A.getRange(), Index);
+  if (NewAttr)
+    D->addAttr(NewAttr);
+}
+
+MSInheritanceAttr *
+Sema::mergeMSInheritanceAttr(Decl *D, SourceRange Range, bool BestCase,
+                             unsigned AttrSpellingListIndex,
+                             MSInheritanceAttr::Spelling SemanticSpelling) {
+  if (MSInheritanceAttr *IA = D->getAttr<MSInheritanceAttr>()) {
+    if (IA->getSemanticSpelling() == SemanticSpelling)
+      return nullptr;
+    Diag(IA->getLocation(), diag::err_mismatched_ms_inheritance)
+        << 1 /*previous declaration*/;
+    Diag(Range.getBegin(), diag::note_previous_ms_inheritance);
+    D->dropAttr<MSInheritanceAttr>();
+  }
+
+  CXXRecordDecl *RD = cast<CXXRecordDecl>(D);
+  if (RD->hasDefinition()) {
+    if (checkMSInheritanceAttrOnDefinition(RD, Range, BestCase,
+                                           SemanticSpelling)) {
+      return nullptr;
+    }
+  } else {
+    if (isa<ClassTemplatePartialSpecializationDecl>(RD)) {
+      Diag(Range.getBegin(), diag::warn_ignored_ms_inheritance)
+          << 1 /*partial specialization*/;
+      return nullptr;
+    }
+    if (RD->getDescribedClassTemplate()) {
+      Diag(Range.getBegin(), diag::warn_ignored_ms_inheritance)
+          << 0 /*primary template*/;
+      return nullptr;
+    }
+  }
+
+  return ::new (Context)
+      MSInheritanceAttr(Range, Context, BestCase, AttrSpellingListIndex);
+}
+
+static void handleCapabilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+  // The capability attributes take a single string parameter for the name of
+  // the capability they represent. The lockable attribute does not take any
+  // parameters. However, semantically, both attributes represent the same
+  // concept, and so they use the same semantic attribute. Eventually, the
+  // lockable attribute will be removed.
+  //
+  // For backward compatibility, any capability which has no specified string
+  // literal will be considered a "mutex."
+  StringRef N("mutex");
+  SourceLocation LiteralLoc;
+  if (Attr.getKind() == AttributeList::AT_Capability &&
+      !S.checkStringLiteralArgumentAttr(Attr, 0, N, &LiteralLoc))
+    return;
+
+  // Currently, there are only two names allowed for a capability: role and
+  // mutex (case insensitive). Diagnose other capability names.
+  if (!N.equals_lower("mutex") && !N.equals_lower("role"))
+    S.Diag(LiteralLoc, diag::warn_invalid_capability_name) << N;
+
+  D->addAttr(::new (S.Context) CapabilityAttr(Attr.getRange(), S.Context, N,
+                                        Attr.getAttributeSpellingListIndex()));
+}
+
+static void handleAssertCapabilityAttr(Sema &S, Decl *D,
+                                       const AttributeList &Attr) {
+  D->addAttr(::new (S.Context) AssertCapabilityAttr(Attr.getRange(), S.Context,
+                                                    Attr.getArgAsExpr(0),
+                                        Attr.getAttributeSpellingListIndex()));
+}
+
+static void handleAcquireCapabilityAttr(Sema &S, Decl *D,
+                                        const AttributeList &Attr) {
+  SmallVector<Expr*, 1> Args;
+  if (!checkLockFunAttrCommon(S, D, Attr, Args))
+    return;
+
+  D->addAttr(::new (S.Context) AcquireCapabilityAttr(Attr.getRange(),
+                                                     S.Context,
+                                                     Args.data(), Args.size(),
+                                        Attr.getAttributeSpellingListIndex()));
+}
+
+static void handleTryAcquireCapabilityAttr(Sema &S, Decl *D,
+                                           const AttributeList &Attr) {
+  SmallVector<Expr*, 2> Args;
+  if (!checkTryLockFunAttrCommon(S, D, Attr, Args))
+    return;
+
+  D->addAttr(::new (S.Context) TryAcquireCapabilityAttr(Attr.getRange(),
+                                                        S.Context,
+                                                        Attr.getArgAsExpr(0),
+                                                        Args.data(),
+                                                        Args.size(),
+                                        Attr.getAttributeSpellingListIndex()));
+}
+
+static void handleReleaseCapabilityAttr(Sema &S, Decl *D,
+                                        const AttributeList &Attr) {
+  // Check that all arguments are lockable objects.
+  SmallVector<Expr *, 1> Args;
+  checkAttrArgsAreCapabilityObjs(S, D, Attr, Args, 0, true);
+
+  D->addAttr(::new (S.Context) ReleaseCapabilityAttr(
+      Attr.getRange(), S.Context, Args.data(), Args.size(),
+      Attr.getAttributeSpellingListIndex()));
+}
+
+static void handleRequiresCapabilityAttr(Sema &S, Decl *D,
+                                         const AttributeList &Attr) {
+  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
+    return;
+
+  // check that all arguments are lockable objects
+  SmallVector<Expr*, 1> Args;
+  checkAttrArgsAreCapabilityObjs(S, D, Attr, Args);
+  if (Args.empty())
+    return;
+
+  RequiresCapabilityAttr *RCA = ::new (S.Context)
+    RequiresCapabilityAttr(Attr.getRange(), S.Context, Args.data(),
+                           Args.size(), Attr.getAttributeSpellingListIndex());
+
+  D->addAttr(RCA);
 }
 
 /// Handles semantic checking for features that are common to all attributes,
@@ -4579,15 +4012,24 @@
   // We also bail on unknown and ignored attributes because those are handled
   // as part of the target-specific handling logic.
   if (Attr.hasCustomParsing() ||
-      Attr.getKind() == AttributeList::UnknownAttribute ||
-      Attr.getKind() == AttributeList::IgnoredAttribute)
+      Attr.getKind() == AttributeList::UnknownAttribute)
     return false;
 
+  // Check whether the attribute requires specific language extensions to be
+  // enabled.
+  if (!Attr.diagnoseLangOpts(S))
+    return true;
+
   // If there are no optional arguments, then checking for the argument count
   // is trivial.
   if (Attr.getMinArgs() == Attr.getMaxArgs() &&
       !checkAttributeNumArgs(S, Attr, Attr.getMinArgs()))
     return true;
+
+  // Check whether the attribute appertains to the given subject.
+  if (!Attr.diagnoseAppertainsTo(S, D))
+    return true;
+
   return false;
 }
 
@@ -4601,7 +4043,7 @@
 static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
                                  const AttributeList &Attr,
                                  bool IncludeCXX11Attributes) {
-  if (Attr.isInvalid())
+  if (Attr.isInvalid() || Attr.getKind() == AttributeList::IgnoredAttribute)
     return;
 
   // Ignore C++11 attributes on declarator chunks: they appertain to the type
@@ -4609,145 +4051,282 @@
   if (Attr.isCXX11Attribute() && !IncludeCXX11Attributes)
     return;
 
+  // Unknown attributes are automatically warned on. Target-specific attributes
+  // which do not apply to the current target architecture are treated as
+  // though they were unknown attributes.
+  if (Attr.getKind() == AttributeList::UnknownAttribute ||
+      !Attr.existsInTarget(S.Context.getTargetInfo().getTriple())) {
+    S.Diag(Attr.getLoc(), Attr.isDeclspecAttribute()
+                              ? diag::warn_unhandled_ms_attribute_ignored
+                              : diag::warn_unknown_attribute_ignored)
+        << Attr.getName();
+    return;
+  }
+
   if (handleCommonAttributeFeatures(S, scope, D, Attr))
     return;
 
   switch (Attr.getKind()) {
-  case AttributeList::AT_IBAction:    handleIBAction(S, D, Attr); break;
-  case AttributeList::AT_IBOutlet:    handleIBOutlet(S, D, Attr); break;
-  case AttributeList::AT_IBOutletCollection:
-    handleIBOutletCollection(S, D, Attr); break;
-  case AttributeList::AT_AddressSpace:
-  case AttributeList::AT_ObjCGC:
-  case AttributeList::AT_VectorSize:
-  case AttributeList::AT_NeonVectorType:
-  case AttributeList::AT_NeonPolyVectorType:
-  case AttributeList::AT_Ptr32:
-  case AttributeList::AT_Ptr64:
-  case AttributeList::AT_SPtr:
-  case AttributeList::AT_UPtr:
-    // Ignore these, these are type attributes, handled by
-    // ProcessTypeAttributes.
+  default:
+    // Type attributes are handled elsewhere; silently move on.
+    assert(Attr.isTypeAttr() && "Non-type attribute not handled");
     break;
-  case AttributeList::AT_Alias:       handleAliasAttr       (S, D, Attr); break;
-  case AttributeList::AT_Aligned:     handleAlignedAttr     (S, D, Attr); break;
-  case AttributeList::AT_AllocSize:   handleAllocSizeAttr   (S, D, Attr); break;
+  case AttributeList::AT_Interrupt:
+    handleInterruptAttr(S, D, Attr);
+    break;
+  case AttributeList::AT_X86ForceAlignArgPointer:
+    handleX86ForceAlignArgPointerAttr(S, D, Attr);
+    break;
+  case AttributeList::AT_DLLExport:
+  case AttributeList::AT_DLLImport:
+    handleDLLAttr(S, D, Attr);
+    break;
+  case AttributeList::AT_Mips16:
+    handleSimpleAttribute<Mips16Attr>(S, D, Attr);
+    break;
+  case AttributeList::AT_NoMips16:
+    handleSimpleAttribute<NoMips16Attr>(S, D, Attr);
+    break;
+  case AttributeList::AT_IBAction:
+    handleSimpleAttribute<IBActionAttr>(S, D, Attr);
+    break;
+  case AttributeList::AT_IBOutlet:
+    handleIBOutlet(S, D, Attr);
+    break;
+  case AttributeList::AT_IBOutletCollection:
+    handleIBOutletCollection(S, D, Attr);
+    break;
+  case AttributeList::AT_Alias:
+    handleAliasAttr(S, D, Attr);
+    break;
+  case AttributeList::AT_Aligned:
+    handleAlignedAttr(S, D, Attr);
+    break;
   case AttributeList::AT_AlwaysInline:
-    handleAlwaysInlineAttr  (S, D, Attr); break;
+    handleAlwaysInlineAttr(S, D, Attr);
+    break;
   case AttributeList::AT_AnalyzerNoReturn:
-    handleAnalyzerNoReturnAttr  (S, D, Attr); break;
-  case AttributeList::AT_TLSModel:    handleTLSModelAttr    (S, D, Attr); break;
-  case AttributeList::AT_Annotate:    handleAnnotateAttr    (S, D, Attr); break;
-  case AttributeList::AT_Availability:handleAvailabilityAttr(S, D, Attr); break;
+    handleAnalyzerNoReturnAttr(S, D, Attr);
+    break;
+  case AttributeList::AT_TLSModel:
+    handleTLSModelAttr(S, D, Attr);
+    break;
+  case AttributeList::AT_Annotate:
+    handleAnnotateAttr(S, D, Attr);
+    break;
+  case AttributeList::AT_Availability:
+    handleAvailabilityAttr(S, D, Attr);
+    break;
   case AttributeList::AT_CarriesDependency:
     handleDependencyAttr(S, scope, D, Attr);
     break;
-  case AttributeList::AT_Common:      handleCommonAttr      (S, D, Attr); break;
-  case AttributeList::AT_CUDAConstant:handleConstantAttr    (S, D, Attr); break;
-  case AttributeList::AT_Constructor: handleConstructorAttr (S, D, Attr); break;
+  case AttributeList::AT_Common:
+    handleCommonAttr(S, D, Attr);
+    break;
+  case AttributeList::AT_CUDAConstant:
+    handleSimpleAttribute<CUDAConstantAttr>(S, D, Attr);
+    break;
+  case AttributeList::AT_Constructor:
+    handleConstructorAttr(S, D, Attr);
+    break;
   case AttributeList::AT_CXX11NoReturn:
-    handleCXX11NoReturnAttr(S, D, Attr);
+    handleSimpleAttribute<CXX11NoReturnAttr>(S, D, Attr);
     break;
   case AttributeList::AT_Deprecated:
     handleAttrWithMessage<DeprecatedAttr>(S, D, Attr);
     break;
-  case AttributeList::AT_Destructor:  handleDestructorAttr  (S, D, Attr); break;
+  case AttributeList::AT_Destructor:
+    handleDestructorAttr(S, D, Attr);
+    break;
+  case AttributeList::AT_EnableIf:
+    handleEnableIfAttr(S, D, Attr);
+    break;
   case AttributeList::AT_ExtVectorType:
     handleExtVectorTypeAttr(S, scope, D, Attr);
     break;
   case AttributeList::AT_MinSize:
-    handleMinSizeAttr(S, D, Attr);
+    handleSimpleAttribute<MinSizeAttr>(S, D, Attr);
     break;
-  case AttributeList::AT_Format:      handleFormatAttr      (S, D, Attr); break;
-  case AttributeList::AT_FormatArg:   handleFormatArgAttr   (S, D, Attr); break;
-  case AttributeList::AT_CUDAGlobal:  handleGlobalAttr      (S, D, Attr); break;
-  case AttributeList::AT_CUDADevice:  handleDeviceAttr      (S, D, Attr); break;
-  case AttributeList::AT_CUDAHost:    handleHostAttr        (S, D, Attr); break;
-  case AttributeList::AT_GNUInline:   handleGNUInlineAttr   (S, D, Attr); break;
+  case AttributeList::AT_OptimizeNone:
+    handleOptimizeNoneAttr(S, D, Attr);
+    break;
+  case AttributeList::AT_Flatten:
+    handleSimpleAttribute<FlattenAttr>(S, D, Attr);
+    break;
+  case AttributeList::AT_Format:
+    handleFormatAttr(S, D, Attr);
+    break;
+  case AttributeList::AT_FormatArg:
+    handleFormatArgAttr(S, D, Attr);
+    break;
+  case AttributeList::AT_CUDAGlobal:
+    handleGlobalAttr(S, D, Attr);
+    break;
+  case AttributeList::AT_CUDADevice:
+    handleSimpleAttribute<CUDADeviceAttr>(S, D, Attr);
+    break;
+  case AttributeList::AT_CUDAHost:
+    handleSimpleAttribute<CUDAHostAttr>(S, D, Attr);
+    break;
+  case AttributeList::AT_GNUInline:
+    handleGNUInlineAttr(S, D, Attr);
+    break;
   case AttributeList::AT_CUDALaunchBounds:
     handleLaunchBoundsAttr(S, D, Attr);
     break;
-  case AttributeList::AT_Malloc:      handleMallocAttr      (S, D, Attr); break;
-  case AttributeList::AT_MayAlias:    handleMayAliasAttr    (S, D, Attr); break;
-  case AttributeList::AT_Mode:        handleModeAttr        (S, D, Attr); break;
-  case AttributeList::AT_NoCommon:    handleNoCommonAttr    (S, D, Attr); break;
-  case AttributeList::AT_NonNull:     handleNonNullAttr     (S, D, Attr); break;
-  case AttributeList::AT_Overloadable:handleOverloadableAttr(S, D, Attr); break;
-  case AttributeList::AT_ownership_returns:
-  case AttributeList::AT_ownership_takes:
-  case AttributeList::AT_ownership_holds:
-      handleOwnershipAttr     (S, D, Attr); break;
-  case AttributeList::AT_Cold:        handleColdAttr        (S, D, Attr); break;
-  case AttributeList::AT_Hot:         handleHotAttr         (S, D, Attr); break;
-  case AttributeList::AT_Naked:       handleNakedAttr       (S, D, Attr); break;
-  case AttributeList::AT_NoReturn:    handleNoReturnAttr    (S, D, Attr); break;
-  case AttributeList::AT_NoThrow:     handleNothrowAttr     (S, D, Attr); break;
-  case AttributeList::AT_CUDAShared:  handleSharedAttr      (S, D, Attr); break;
-  case AttributeList::AT_VecReturn:   handleVecReturnAttr   (S, D, Attr); break;
+  case AttributeList::AT_Malloc:
+    handleMallocAttr(S, D, Attr);
+    break;
+  case AttributeList::AT_MayAlias:
+    handleSimpleAttribute<MayAliasAttr>(S, D, Attr);
+    break;
+  case AttributeList::AT_Mode:
+    handleModeAttr(S, D, Attr);
+    break;
+  case AttributeList::AT_NoCommon:
+    handleSimpleAttribute<NoCommonAttr>(S, D, Attr);
+    break;
+  case AttributeList::AT_NoSplitStack:
+    handleSimpleAttribute<NoSplitStackAttr>(S, D, Attr);
+    break;
+  case AttributeList::AT_NonNull:
+    if (ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(D))
+      handleNonNullAttrParameter(S, PVD, Attr);
+    else
+      handleNonNullAttr(S, D, Attr);
+    break;
+  case AttributeList::AT_ReturnsNonNull:
+    handleReturnsNonNullAttr(S, D, Attr);
+    break;
+  case AttributeList::AT_Overloadable:
+    handleSimpleAttribute<OverloadableAttr>(S, D, Attr);
+    break;
+  case AttributeList::AT_Ownership:
+    handleOwnershipAttr(S, D, Attr);
+    break;
+  case AttributeList::AT_Cold:
+    handleColdAttr(S, D, Attr);
+    break;
+  case AttributeList::AT_Hot:
+    handleHotAttr(S, D, Attr);
+    break;
+  case AttributeList::AT_Naked:
+    handleSimpleAttribute<NakedAttr>(S, D, Attr);
+    break;
+  case AttributeList::AT_NoReturn:
+    handleNoReturnAttr(S, D, Attr);
+    break;
+  case AttributeList::AT_NoThrow:
+    handleSimpleAttribute<NoThrowAttr>(S, D, Attr);
+    break;
+  case AttributeList::AT_CUDAShared:
+    handleSimpleAttribute<CUDASharedAttr>(S, D, Attr);
+    break;
+  case AttributeList::AT_VecReturn:
+    handleVecReturnAttr(S, D, Attr);
+    break;
 
   case AttributeList::AT_ObjCOwnership:
-    handleObjCOwnershipAttr(S, D, Attr); break;
+    handleObjCOwnershipAttr(S, D, Attr);
+    break;
   case AttributeList::AT_ObjCPreciseLifetime:
-    handleObjCPreciseLifetimeAttr(S, D, Attr); break;
+    handleObjCPreciseLifetimeAttr(S, D, Attr);
+    break;
 
   case AttributeList::AT_ObjCReturnsInnerPointer:
-    handleObjCReturnsInnerPointerAttr(S, D, Attr); break;
+    handleObjCReturnsInnerPointerAttr(S, D, Attr);
+    break;
 
   case AttributeList::AT_ObjCRequiresSuper:
-      handleObjCRequiresSuperAttr(S, D, Attr); break;
-      
-  case AttributeList::AT_NSBridged:
-    handleNSBridgedAttr(S, scope, D, Attr); break;
-      
+    handleObjCRequiresSuperAttr(S, D, Attr);
+    break;
+
   case AttributeList::AT_ObjCBridge:
-    handleObjCBridgeAttr(S, scope, D, Attr); break;
+    handleObjCBridgeAttr(S, scope, D, Attr);
+    break;
 
+  case AttributeList::AT_ObjCBridgeMutable:
+    handleObjCBridgeMutableAttr(S, scope, D, Attr);
+    break;
+
+  case AttributeList::AT_ObjCBridgeRelated:
+    handleObjCBridgeRelatedAttr(S, scope, D, Attr);
+    break;
+
+  case AttributeList::AT_ObjCDesignatedInitializer:
+    handleObjCDesignatedInitializer(S, D, Attr);
+    break;
+
+  case AttributeList::AT_ObjCRuntimeName:
+    handleObjCRuntimeName(S, D, Attr);
+    break;
+          
   case AttributeList::AT_CFAuditedTransfer:
+    handleCFAuditedTransferAttr(S, D, Attr);
+    break;
   case AttributeList::AT_CFUnknownTransfer:
-    handleCFTransferAttr(S, D, Attr); break;
+    handleCFUnknownTransferAttr(S, D, Attr);
+    break;
 
-  // Checker-specific.
   case AttributeList::AT_CFConsumed:
-  case AttributeList::AT_NSConsumed:  handleNSConsumedAttr  (S, D, Attr); break;
+  case AttributeList::AT_NSConsumed:
+    handleNSConsumedAttr(S, D, Attr);
+    break;
   case AttributeList::AT_NSConsumesSelf:
-    handleNSConsumesSelfAttr(S, D, Attr); break;
+    handleSimpleAttribute<NSConsumesSelfAttr>(S, D, Attr);
+    break;
 
   case AttributeList::AT_NSReturnsAutoreleased:
   case AttributeList::AT_NSReturnsNotRetained:
   case AttributeList::AT_CFReturnsNotRetained:
   case AttributeList::AT_NSReturnsRetained:
   case AttributeList::AT_CFReturnsRetained:
-    handleNSReturnsRetainedAttr(S, D, Attr); break;
-
+    handleNSReturnsRetainedAttr(S, D, Attr);
+    break;
   case AttributeList::AT_WorkGroupSizeHint:
+    handleWorkGroupSize<WorkGroupSizeHintAttr>(S, D, Attr);
+    break;
   case AttributeList::AT_ReqdWorkGroupSize:
-    handleWorkGroupSize(S, D, Attr); break;
-
+    handleWorkGroupSize<ReqdWorkGroupSizeAttr>(S, D, Attr);
+    break;
   case AttributeList::AT_VecTypeHint:
-    handleVecTypeHint(S, D, Attr); break;
+    handleVecTypeHint(S, D, Attr);
+    break;
 
-  case AttributeList::AT_InitPriority: 
-      handleInitPriorityAttr(S, D, Attr); break;
-      
-  case AttributeList::AT_Packed:      handlePackedAttr      (S, D, Attr); break;
-  case AttributeList::AT_Section:     handleSectionAttr     (S, D, Attr); break;
+  case AttributeList::AT_InitPriority:
+    handleInitPriorityAttr(S, D, Attr);
+    break;
+
+  case AttributeList::AT_Packed:
+    handlePackedAttr(S, D, Attr);
+    break;
+  case AttributeList::AT_Section:
+    handleSectionAttr(S, D, Attr);
+    break;
   case AttributeList::AT_Unavailable:
     handleAttrWithMessage<UnavailableAttr>(S, D, Attr);
     break;
-  case AttributeList::AT_ArcWeakrefUnavailable: 
-    handleArcWeakrefUnavailableAttr (S, D, Attr); 
+  case AttributeList::AT_ArcWeakrefUnavailable:
+    handleSimpleAttribute<ArcWeakrefUnavailableAttr>(S, D, Attr);
     break;
   case AttributeList::AT_ObjCRootClass:
-    handleObjCRootClassAttr(S, D, Attr);
+    handleSimpleAttribute<ObjCRootClassAttr>(S, D, Attr);
     break;
-  case AttributeList::AT_ObjCRequiresPropertyDefs: 
-    handleObjCRequiresPropertyDefsAttr (S, D, Attr); 
+  case AttributeList::AT_ObjCExplicitProtocolImpl:
+    handleObjCSuppresProtocolAttr(S, D, Attr);
     break;
-  case AttributeList::AT_Unused:      handleUnusedAttr      (S, D, Attr); break;
+  case AttributeList::AT_ObjCRequiresPropertyDefs:
+    handleSimpleAttribute<ObjCRequiresPropertyDefsAttr>(S, D, Attr);
+    break;
+  case AttributeList::AT_Unused:
+    handleSimpleAttribute<UnusedAttr>(S, D, Attr);
+    break;
   case AttributeList::AT_ReturnsTwice:
-    handleReturnsTwiceAttr(S, D, Attr);
+    handleSimpleAttribute<ReturnsTwiceAttr>(S, D, Attr);
     break;
-  case AttributeList::AT_Used:        handleUsedAttr        (S, D, Attr); break;
+  case AttributeList::AT_Used:
+    handleUsedAttr(S, D, Attr);
+    break;
   case AttributeList::AT_Visibility:
     handleVisibilityAttr(S, D, Attr, false);
     break;
@@ -4755,36 +4334,58 @@
     handleVisibilityAttr(S, D, Attr, true);
     break;
   case AttributeList::AT_WarnUnused:
-    handleWarnUnusedAttr(S, D, Attr);
+    handleSimpleAttribute<WarnUnusedAttr>(S, D, Attr);
     break;
-  case AttributeList::AT_WarnUnusedResult: handleWarnUnusedResult(S, D, Attr);
+  case AttributeList::AT_WarnUnusedResult:
+    handleWarnUnusedResult(S, D, Attr);
     break;
-  case AttributeList::AT_Weak:        handleWeakAttr        (S, D, Attr); break;
-  case AttributeList::AT_WeakRef:     handleWeakRefAttr     (S, D, Attr); break;
-  case AttributeList::AT_WeakImport:  handleWeakImportAttr  (S, D, Attr); break;
+  case AttributeList::AT_Weak:
+    handleSimpleAttribute<WeakAttr>(S, D, Attr);
+    break;
+  case AttributeList::AT_WeakRef:
+    handleWeakRefAttr(S, D, Attr);
+    break;
+  case AttributeList::AT_WeakImport:
+    handleWeakImportAttr(S, D, Attr);
+    break;
   case AttributeList::AT_TransparentUnion:
     handleTransparentUnionAttr(S, D, Attr);
     break;
   case AttributeList::AT_ObjCException:
-    handleObjCExceptionAttr(S, D, Attr);
+    handleSimpleAttribute<ObjCExceptionAttr>(S, D, Attr);
     break;
   case AttributeList::AT_ObjCMethodFamily:
     handleObjCMethodFamilyAttr(S, D, Attr);
     break;
-  case AttributeList::AT_ObjCNSObject:handleObjCNSObject    (S, D, Attr); break;
-  case AttributeList::AT_Blocks:      handleBlocksAttr      (S, D, Attr); break;
-  case AttributeList::AT_Sentinel:    handleSentinelAttr    (S, D, Attr); break;
-  case AttributeList::AT_Const:       handleConstAttr       (S, D, Attr); break;
-  case AttributeList::AT_Pure:        handlePureAttr        (S, D, Attr); break;
-  case AttributeList::AT_Cleanup:     handleCleanupAttr     (S, D, Attr); break;
-  case AttributeList::AT_NoDebug:     handleNoDebugAttr     (S, D, Attr); break;
-  case AttributeList::AT_NoInline:    handleNoInlineAttr    (S, D, Attr); break;
-  case AttributeList::AT_Regparm:     handleRegparmAttr     (S, D, Attr); break;
-  case AttributeList::IgnoredAttribute:
-    // Just ignore
+  case AttributeList::AT_ObjCNSObject:
+    handleObjCNSObject(S, D, Attr);
     break;
-  case AttributeList::AT_NoInstrumentFunction:  // Interacts with -pg.
-    handleNoInstrumentFunctionAttr(S, D, Attr);
+  case AttributeList::AT_Blocks:
+    handleBlocksAttr(S, D, Attr);
+    break;
+  case AttributeList::AT_Sentinel:
+    handleSentinelAttr(S, D, Attr);
+    break;
+  case AttributeList::AT_Const:
+    handleSimpleAttribute<ConstAttr>(S, D, Attr);
+    break;
+  case AttributeList::AT_Pure:
+    handleSimpleAttribute<PureAttr>(S, D, Attr);
+    break;
+  case AttributeList::AT_Cleanup:
+    handleCleanupAttr(S, D, Attr);
+    break;
+  case AttributeList::AT_NoDebug:
+    handleNoDebugAttr(S, D, Attr);
+    break;
+  case AttributeList::AT_NoDuplicate:
+    handleSimpleAttribute<NoDuplicateAttr>(S, D, Attr);
+    break;
+  case AttributeList::AT_NoInline:
+    handleSimpleAttribute<NoInlineAttr>(S, D, Attr);
+    break;
+  case AttributeList::AT_NoInstrumentFunction: // Interacts with -pg.
+    handleSimpleAttribute<NoInstrumentFunctionAttr>(S, D, Attr);
     break;
   case AttributeList::AT_StdCall:
   case AttributeList::AT_CDecl:
@@ -4799,32 +4400,27 @@
     handleCallConvAttr(S, D, Attr);
     break;
   case AttributeList::AT_OpenCLKernel:
-    handleOpenCLKernelAttr(S, D, Attr);
+    handleSimpleAttribute<OpenCLKernelAttr>(S, D, Attr);
     break;
   case AttributeList::AT_OpenCLImageAccess:
-    handleOpenCLImageAccessAttr(S, D, Attr);
+    handleSimpleAttribute<OpenCLImageAccessAttr>(S, D, Attr);
     break;
 
   // Microsoft attributes:
   case AttributeList::AT_MsStruct:
-    handleMsStructAttr(S, D, Attr);
+    handleSimpleAttribute<MsStructAttr>(S, D, Attr);
     break;
   case AttributeList::AT_Uuid:
     handleUuidAttr(S, D, Attr);
     break;
-  case AttributeList::AT_SingleInheritance:
-  case AttributeList::AT_MultipleInheritance:
-  case AttributeList::AT_VirtualInheritance:
-    handleInheritanceAttr(S, D, Attr);
-    break;
-  case AttributeList::AT_Win64:
-    handlePortabilityAttr(S, D, Attr);
-    break;
-  case AttributeList::AT_ForceInline:
-    handleForceInlineAttr(S, D, Attr);
+  case AttributeList::AT_MSInheritance:
+    handleMSInheritanceAttr(S, D, Attr);
     break;
   case AttributeList::AT_SelectAny:
-    handleSelectAnyAttr(S, D, Attr);
+    handleSimpleAttribute<SelectAnyAttr>(S, D, Attr);
+    break;
+  case AttributeList::AT_Thread:
+    handleDeclspecThreadAttr(S, D, Attr);
     break;
 
   // Thread safety attributes:
@@ -4835,28 +4431,25 @@
     handleAssertSharedLockAttr(S, D, Attr);
     break;
   case AttributeList::AT_GuardedVar:
-    handleGuardedVarAttr(S, D, Attr);
+    handleSimpleAttribute<GuardedVarAttr>(S, D, Attr);
     break;
   case AttributeList::AT_PtGuardedVar:
     handlePtGuardedVarAttr(S, D, Attr);
     break;
   case AttributeList::AT_ScopedLockable:
-    handleScopedLockableAttr(S, D, Attr);
+    handleSimpleAttribute<ScopedLockableAttr>(S, D, Attr);
     break;
   case AttributeList::AT_NoSanitizeAddress:
-    handleNoSanitizeAddressAttr(S, D, Attr);
+    handleSimpleAttribute<NoSanitizeAddressAttr>(S, D, Attr);
     break;
   case AttributeList::AT_NoThreadSafetyAnalysis:
-    handleNoThreadSafetyAnalysis(S, D, Attr);
+    handleSimpleAttribute<NoThreadSafetyAnalysisAttr>(S, D, Attr);
     break;
   case AttributeList::AT_NoSanitizeThread:
-    handleNoSanitizeThread(S, D, Attr);
+    handleSimpleAttribute<NoSanitizeThreadAttr>(S, D, Attr);
     break;
   case AttributeList::AT_NoSanitizeMemory:
-    handleNoSanitizeMemory(S, D, Attr);
-    break;
-  case AttributeList::AT_Lockable:
-    handleLockableAttr(S, D, Attr);
+    handleSimpleAttribute<NoSanitizeMemoryAttr>(S, D, Attr);
     break;
   case AttributeList::AT_GuardedBy:
     handleGuardedByAttr(S, D, Attr);
@@ -4864,12 +4457,6 @@
   case AttributeList::AT_PtGuardedBy:
     handlePtGuardedByAttr(S, D, Attr);
     break;
-  case AttributeList::AT_ExclusiveLockFunction:
-    handleExclusiveLockFunctionAttr(S, D, Attr);
-    break;
-  case AttributeList::AT_ExclusiveLocksRequired:
-    handleExclusiveLocksRequiredAttr(S, D, Attr);
-    break;
   case AttributeList::AT_ExclusiveTrylockFunction:
     handleExclusiveTrylockFunctionAttr(S, D, Attr);
     break;
@@ -4879,18 +4466,9 @@
   case AttributeList::AT_LocksExcluded:
     handleLocksExcludedAttr(S, D, Attr);
     break;
-  case AttributeList::AT_SharedLockFunction:
-    handleSharedLockFunctionAttr(S, D, Attr);
-    break;
-  case AttributeList::AT_SharedLocksRequired:
-    handleSharedLocksRequiredAttr(S, D, Attr);
-    break;
   case AttributeList::AT_SharedTrylockFunction:
     handleSharedTrylockFunctionAttr(S, D, Attr);
     break;
-  case AttributeList::AT_UnlockFunction:
-    handleUnlockFunAttr(S, D, Attr);
-    break;
   case AttributeList::AT_AcquiredBefore:
     handleAcquiredBeforeAttr(S, D, Attr);
     break;
@@ -4898,10 +4476,38 @@
     handleAcquiredAfterAttr(S, D, Attr);
     break;
 
+  // Capability analysis attributes.
+  case AttributeList::AT_Capability:
+  case AttributeList::AT_Lockable:
+    handleCapabilityAttr(S, D, Attr);
+    break;
+  case AttributeList::AT_RequiresCapability:
+    handleRequiresCapabilityAttr(S, D, Attr);
+    break;
+
+  case AttributeList::AT_AssertCapability:
+    handleAssertCapabilityAttr(S, D, Attr);
+    break;
+  case AttributeList::AT_AcquireCapability:
+    handleAcquireCapabilityAttr(S, D, Attr);
+    break;
+  case AttributeList::AT_ReleaseCapability:
+    handleReleaseCapabilityAttr(S, D, Attr);
+    break;
+  case AttributeList::AT_TryAcquireCapability:
+    handleTryAcquireCapabilityAttr(S, D, Attr);
+    break;
+
   // Consumed analysis attributes.
   case AttributeList::AT_Consumable:
     handleConsumableAttr(S, D, Attr);
     break;
+  case AttributeList::AT_ConsumableAutoCast:
+    handleSimpleAttribute<ConsumableAutoCastAttr>(S, D, Attr);
+    break;
+  case AttributeList::AT_ConsumableSetOnRead:
+    handleSimpleAttribute<ConsumableSetOnReadAttr>(S, D, Attr);
+    break;
   case AttributeList::AT_CallableWhen:
     handleCallableWhenAttr(S, D, Attr);
     break;
@@ -4925,15 +4531,6 @@
   case AttributeList::AT_TypeTagForDatatype:
     handleTypeTagForDatatypeAttr(S, D, Attr);
     break;
-
-  default:
-    // Ask target about the attribute.
-    const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema();
-    if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S))
-      S.Diag(Attr.getLoc(), Attr.isDeclspecAttribute() ? 
-             diag::warn_unhandled_ms_attribute_ignored : 
-             diag::warn_unknown_attribute_ignored) << Attr.getName();
-    break;
   }
 }
 
@@ -4945,15 +4542,32 @@
   for (const AttributeList* l = AttrList; l; l = l->getNext())
     ProcessDeclAttribute(*this, S, D, *l, IncludeCXX11Attributes);
 
+  // FIXME: We should be able to handle these cases in TableGen.
   // GCC accepts
   // static int a9 __attribute__((weakref));
   // but that looks really pointless. We reject it.
   if (D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
-    Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) <<
-    cast<NamedDecl>(D)->getNameAsString();
+    Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias)
+      << cast<NamedDecl>(D);
     D->dropAttr<WeakRefAttr>();
     return;
   }
+
+  if (!D->hasAttr<OpenCLKernelAttr>()) {
+    // These attributes cannot be applied to a non-kernel function.
+    if (Attr *A = D->getAttr<ReqdWorkGroupSizeAttr>()) {
+      Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;
+      D->setInvalidDecl();
+    }
+    if (Attr *A = D->getAttr<WorkGroupSizeHintAttr>()) {
+      Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;
+      D->setInvalidDecl();
+    }
+    if (Attr *A = D->getAttr<VecTypeHintAttr>()) {
+      Diag(D->getLocation(), diag::err_opencl_kernel_attr) << A;
+      D->setInvalidDecl();
+    }
+  }
 }
 
 // Annotation attributes are the only attributes allowed after an access
@@ -5005,7 +4619,7 @@
 NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II,
                                       SourceLocation Loc) {
   assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
-  NamedDecl *NewD = 0;
+  NamedDecl *NewD = nullptr;
   if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
     FunctionDecl *NewFD;
     // FIXME: Missing call to CheckFunctionDeclaration().
@@ -5028,9 +4642,8 @@
     QualType FDTy = FD->getType();
     if (const FunctionProtoType *FT = FDTy->getAs<FunctionProtoType>()) {
       SmallVector<ParmVarDecl*, 16> Params;
-      for (FunctionProtoType::arg_type_iterator AI = FT->arg_type_begin(),
-           AE = FT->arg_type_end(); AI != AE; ++AI) {
-        ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, *AI);
+      for (const auto &AI : FT->param_types()) {
+        ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, AI);
         Param->setScopeInfo(0, Params.size());
         Params.push_back(Param);
       }
@@ -5057,18 +4670,20 @@
   if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
     IdentifierInfo *NDId = ND->getIdentifier();
     NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation());
-    NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
-                                            NDId->getName()));
-    NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
+    NewD->addAttr(AliasAttr::CreateImplicit(Context, NDId->getName(),
+                                            W.getLocation()));
+    NewD->addAttr(WeakAttr::CreateImplicit(Context, W.getLocation()));
     WeakTopLevelDecl.push_back(NewD);
     // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
     // to insert Decl at TU scope, sorry.
     DeclContext *SavedContext = CurContext;
     CurContext = Context.getTranslationUnitDecl();
+    NewD->setDeclContext(CurContext);
+    NewD->setLexicalDeclContext(CurContext);
     PushOnScopeChains(NewD, S);
     CurContext = SavedContext;
   } else { // just add weak to existing
-    ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
+    ND->addAttr(WeakAttr::CreateImplicit(Context, W.getLocation()));
   }
 }
 
@@ -5077,7 +4692,7 @@
   // have to do this.
   LoadExternalWeakUndeclaredIdentifiers();
   if (!WeakUndeclaredIdentifiers.empty()) {
-    NamedDecl *ND = NULL;
+    NamedDecl *ND = nullptr;
     if (VarDecl *VD = dyn_cast<VarDecl>(D))
       if (VD->isExternC())
         ND = VD;
@@ -5137,8 +4752,9 @@
 static void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &diag,
                                        Decl *decl) {
   if (decl && isForbiddenTypeAllowed(S, decl)) {
-    decl->addAttr(new (S.Context) UnavailableAttr(diag.Loc, S.Context,
-                        "this system declaration uses an unsupported type"));
+    decl->addAttr(UnavailableAttr::CreateImplicit(S.Context,
+                        "this system declaration uses an unsupported type",
+                        diag.Loc));
     return;
   }
   if (S.getLangOpts().ObjCAutoRefCount)
@@ -5186,9 +4802,11 @@
 
       switch (diag.Kind) {
       case DelayedDiagnostic::Deprecation:
-        // Don't bother giving deprecation diagnostics if the decl is invalid.
+      case DelayedDiagnostic::Unavailable:
+        // Don't bother giving deprecation/unavailable diagnostics if
+        // the decl is invalid.
         if (!decl->isInvalidDecl())
-          HandleDelayedDeprecationCheck(diag, decl);
+          HandleDelayedAvailabilityCheck(diag, decl);
         break;
 
       case DelayedDiagnostic::Access:
@@ -5223,61 +4841,125 @@
   return false;
 }
 
+static bool isDeclUnavailable(Decl *D) {
+  do {
+    if (D->isUnavailable())
+      return true;
+    // A category implicitly has the availability of the interface.
+    if (const ObjCCategoryDecl *CatD = dyn_cast<ObjCCategoryDecl>(D))
+      return CatD->getClassInterface()->isUnavailable();
+  } while ((D = cast_or_null<Decl>(D->getDeclContext())));
+  return false;
+}
+
 static void
-DoEmitDeprecationWarning(Sema &S, const NamedDecl *D, StringRef Message,
-                         SourceLocation Loc,
-                         const ObjCInterfaceDecl *UnknownObjCClass,
-                         const ObjCPropertyDecl *ObjCPropery) {
+DoEmitAvailabilityWarning(Sema &S,
+                          DelayedDiagnostic::DDKind K,
+                          Decl *Ctx,
+                          const NamedDecl *D,
+                          StringRef Message,
+                          SourceLocation Loc,
+                          const ObjCInterfaceDecl *UnknownObjCClass,
+                          const ObjCPropertyDecl *ObjCProperty,
+                          bool ObjCPropertyAccess) {
+
+  // Diagnostics for deprecated or unavailable.
+  unsigned diag, diag_message, diag_fwdclass_message;
+
+  // Matches 'diag::note_property_attribute' options.
+  unsigned property_note_select;
+
+  // Matches diag::note_availability_specified_here.
+  unsigned available_here_select_kind;
+
+  // Don't warn if our current context is deprecated or unavailable.
+  switch (K) {
+    case DelayedDiagnostic::Deprecation:
+      if (isDeclDeprecated(Ctx))
+        return;
+      diag = !ObjCPropertyAccess ? diag::warn_deprecated
+                                 : diag::warn_property_method_deprecated;
+      diag_message = diag::warn_deprecated_message;
+      diag_fwdclass_message = diag::warn_deprecated_fwdclass_message;
+      property_note_select = /* deprecated */ 0;
+      available_here_select_kind = /* deprecated */ 2;
+      break;
+
+    case DelayedDiagnostic::Unavailable:
+      if (isDeclUnavailable(Ctx))
+        return;
+      diag = !ObjCPropertyAccess ? diag::err_unavailable
+                                 : diag::err_property_method_unavailable;
+      diag_message = diag::err_unavailable_message;
+      diag_fwdclass_message = diag::warn_unavailable_fwdclass_message;
+      property_note_select = /* unavailable */ 1;
+      available_here_select_kind = /* unavailable */ 0;
+      break;
+
+    default:
+      llvm_unreachable("Neither a deprecation or unavailable kind");
+  }
+
   DeclarationName Name = D->getDeclName();
   if (!Message.empty()) {
-    S.Diag(Loc, diag::warn_deprecated_message) << Name << Message;
-    S.Diag(D->getLocation(),
-           isa<ObjCMethodDecl>(D) ? diag::note_method_declared_at
-                                  : diag::note_previous_decl) << Name;
-    if (ObjCPropery)
-      S.Diag(ObjCPropery->getLocation(), diag::note_property_attribute)
-        << ObjCPropery->getDeclName() << 0;
+    S.Diag(Loc, diag_message) << Name << Message;
+    if (ObjCProperty)
+      S.Diag(ObjCProperty->getLocation(), diag::note_property_attribute)
+        << ObjCProperty->getDeclName() << property_note_select;
   } else if (!UnknownObjCClass) {
-    S.Diag(Loc, diag::warn_deprecated) << D->getDeclName();
-    S.Diag(D->getLocation(),
-           isa<ObjCMethodDecl>(D) ? diag::note_method_declared_at
-                                  : diag::note_previous_decl) << Name;
-    if (ObjCPropery)
-      S.Diag(ObjCPropery->getLocation(), diag::note_property_attribute)
-        << ObjCPropery->getDeclName() << 0;
+    S.Diag(Loc, diag) << Name;
+    if (ObjCProperty)
+      S.Diag(ObjCProperty->getLocation(), diag::note_property_attribute)
+        << ObjCProperty->getDeclName() << property_note_select;
   } else {
-    S.Diag(Loc, diag::warn_deprecated_fwdclass_message) << Name;
+    S.Diag(Loc, diag_fwdclass_message) << Name;
     S.Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);
   }
+
+  S.Diag(D->getLocation(), diag::note_availability_specified_here)
+    << D << available_here_select_kind;
 }
 
-void Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
-                                         Decl *Ctx) {
-  if (isDeclDeprecated(Ctx))
-    return;
-
+void Sema::HandleDelayedAvailabilityCheck(DelayedDiagnostic &DD,
+                                          Decl *Ctx) {
   DD.Triggered = true;
-  DoEmitDeprecationWarning(*this, DD.getDeprecationDecl(),
-                           DD.getDeprecationMessage(), DD.Loc,
-                           DD.getUnknownObjCClass(),
-                           DD.getObjCProperty());
+  DoEmitAvailabilityWarning(*this,
+                            (DelayedDiagnostic::DDKind) DD.Kind,
+                            Ctx,
+                            DD.getDeprecationDecl(),
+                            DD.getDeprecationMessage(),
+                            DD.Loc,
+                            DD.getUnknownObjCClass(),
+                            DD.getObjCProperty(), false);
 }
 
-void Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message,
-                                  SourceLocation Loc,
-                                  const ObjCInterfaceDecl *UnknownObjCClass,
-                                  const ObjCPropertyDecl  *ObjCProperty) {
+void Sema::EmitAvailabilityWarning(AvailabilityDiagnostic AD,
+                                   NamedDecl *D, StringRef Message,
+                                   SourceLocation Loc,
+                                   const ObjCInterfaceDecl *UnknownObjCClass,
+                                   const ObjCPropertyDecl  *ObjCProperty,
+                                   bool ObjCPropertyAccess) {
   // Delay if we're currently parsing a declaration.
   if (DelayedDiagnostics.shouldDelayDiagnostics()) {
-    DelayedDiagnostics.add(DelayedDiagnostic::makeDeprecation(Loc, D, 
-                                                              UnknownObjCClass,
-                                                              ObjCProperty,
-                                                              Message));
+    DelayedDiagnostics.add(DelayedDiagnostic::makeAvailability(AD, Loc, D,
+                                                               UnknownObjCClass,
+                                                               ObjCProperty,
+                                                               Message,
+                                                               ObjCPropertyAccess));
     return;
   }
 
-  // Otherwise, don't warn if our current context is deprecated.
-  if (isDeclDeprecated(cast<Decl>(getCurLexicalContext())))
-    return;
-  DoEmitDeprecationWarning(*this, D, Message, Loc, UnknownObjCClass, ObjCProperty);
+  Decl *Ctx = cast<Decl>(getCurLexicalContext());
+  DelayedDiagnostic::DDKind K;
+  switch (AD) {
+    case AD_Deprecation:
+      K = DelayedDiagnostic::Deprecation;
+      break;
+    case AD_Unavailable:
+      K = DelayedDiagnostic::Unavailable;
+      break;
+  }
+
+  DoEmitAvailabilityWarning(*this, K, Ctx, D, Message, Loc,
+                            UnknownObjCClass, ObjCProperty, ObjCPropertyAccess);
 }
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 1eec231..c5cd83d 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -18,7 +18,6 @@
 #include "clang/AST/ASTMutationListener.h"
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/CharUnits.h"
-#include "clang/AST/DeclVisitor.h"
 #include "clang/AST/EvaluatedExprVisitor.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/RecordLayout.h"
@@ -212,11 +211,9 @@
          "Shouldn't collect exceptions when throw-all is guaranteed.");
   ComputedEST = EST_Dynamic;
   // Record the exceptions in this function's exception specification.
-  for (FunctionProtoType::exception_iterator E = Proto->exception_begin(),
-                                          EEnd = Proto->exception_end();
-       E != EEnd; ++E)
-    if (ExceptionsSeen.insert(Self->Context.getCanonicalType(*E)))
-      Exceptions.push_back(*E);
+  for (const auto &E : Proto->exceptions())
+    if (ExceptionsSeen.insert(Self->Context.getCanonicalType(E)))
+      Exceptions.push_back(E);
 }
 
 void Sema::ImplicitExceptionSpecification::CalledExpr(Expr *E) {
@@ -271,7 +268,7 @@
   ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Arg);
   if (Result.isInvalid())
     return true;
-  Arg = Result.takeAs<Expr>();
+  Arg = Result.getAs<Expr>();
 
   CheckCompletedExpr(Arg, EqualLoc);
   Arg = MaybeCreateExprWithCleanups(Arg);
@@ -347,13 +344,16 @@
 
 /// ActOnParamDefaultArgumentError - Parsing or semantic analysis of
 /// the default argument for the parameter param failed.
-void Sema::ActOnParamDefaultArgumentError(Decl *param) {
+void Sema::ActOnParamDefaultArgumentError(Decl *param,
+                                          SourceLocation EqualLoc) {
   if (!param)
     return;
 
   ParmVarDecl *Param = cast<ParmVarDecl>(param);
   Param->setInvalidDecl();
   UnparsedDefaultArgLocs.erase(Param);
+  Param->setDefaultArg(new(Context)
+                       OpaqueValueExpr(EqualLoc, Param->getType(), VK_RValue));
 }
 
 /// CheckExtraCXXDefaultArguments - Check for any extra default
@@ -380,20 +380,20 @@
         MightBeFunction = false;
         continue;
       }
-      for (unsigned argIdx = 0, e = chunk.Fun.NumArgs; argIdx != e; ++argIdx) {
-        ParmVarDecl *Param =
-          cast<ParmVarDecl>(chunk.Fun.ArgInfo[argIdx].Param);
+      for (unsigned argIdx = 0, e = chunk.Fun.NumParams; argIdx != e;
+           ++argIdx) {
+        ParmVarDecl *Param = cast<ParmVarDecl>(chunk.Fun.Params[argIdx].Param);
         if (Param->hasUnparsedDefaultArg()) {
-          CachedTokens *Toks = chunk.Fun.ArgInfo[argIdx].DefaultArgTokens;
+          CachedTokens *Toks = chunk.Fun.Params[argIdx].DefaultArgTokens;
           Diag(Param->getLocation(), diag::err_param_default_argument_nonfunc)
             << SourceRange((*Toks)[1].getLocation(),
                            Toks->back().getLocation());
           delete Toks;
-          chunk.Fun.ArgInfo[argIdx].DefaultArgTokens = 0;
+          chunk.Fun.Params[argIdx].DefaultArgTokens = nullptr;
         } else if (Param->getDefaultArg()) {
           Diag(Param->getLocation(), diag::err_param_default_argument_nonfunc)
             << Param->getDefaultArg()->getSourceRange();
-          Param->setDefaultArg(0);
+          Param->setDefaultArg(nullptr);
         }
       }
     } else if (chunk.Kind != DeclaratorChunk::Paren) {
@@ -479,7 +479,7 @@
                                       OldParam->getUninstantiatedDefaultArg());
           else
             NewParam->setDefaultArg(OldParam->getInit());
-          DiagDefaultParamID = diag::warn_param_default_argument_redefinition;
+          DiagDefaultParamID = diag::ext_param_default_argument_redefinition;
           Invalid = false;
         }
       }
@@ -586,6 +586,7 @@
     }
   }
 
+  const FunctionDecl *Def;
   // C++11 [dcl.constexpr]p1: If any declaration of a function or function
   // template has a constexpr specifier then all its declarations shall
   // contain the constexpr specifier.
@@ -594,6 +595,13 @@
       << New << New->isConstexpr();
     Diag(Old->getLocation(), diag::note_previous_declaration);
     Invalid = true;
+  } else if (!Old->isInlined() && New->isInlined() && Old->isDefined(Def)) {
+    // C++11 [dcl.fcn.spec]p4:
+    //   If the definition of a function appears in a translation unit before its
+    //   first declaration as inline, the program is ill-formed.
+    Diag(New->getLocation(), diag::err_inline_decl_follows_def) << New;
+    Diag(Def->getLocation(), diag::note_previous_definition);
+    Invalid = true;
   }
 
   // C++11 [dcl.fct.default]p4: If a friend declaration specifies a default
@@ -701,7 +709,7 @@
     for (p = 0; p <= LastMissingDefaultArg; ++p) {
       ParmVarDecl *Param = FD->getParamDecl(p);
       if (Param->hasDefaultArg()) {
-        Param->setDefaultArg(0);
+        Param->setDefaultArg(nullptr);
       }
     }
   }
@@ -714,8 +722,9 @@
                                          const FunctionDecl *FD) {
   unsigned ArgIndex = 0;
   const FunctionProtoType *FT = FD->getType()->getAs<FunctionProtoType>();
-  for (FunctionProtoType::arg_type_iterator i = FT->arg_type_begin(),
-       e = FT->arg_type_end(); i != e; ++i, ++ArgIndex) {
+  for (FunctionProtoType::param_type_iterator i = FT->param_type_begin(),
+                                              e = FT->param_type_end();
+       i != e; ++i, ++ArgIndex) {
     const ParmVarDecl *PD = FD->getParamDecl(ArgIndex);
     SourceLocation ParamLoc = PD->getLocation();
     if (!(*i)->isDependentType() &&
@@ -760,10 +769,9 @@
       Diag(NewFD->getLocation(), diag::err_constexpr_virtual_base)
         << isa<CXXConstructorDecl>(NewFD)
         << getRecordDiagFromTagKind(RD->getTagKind()) << RD->getNumVBases();
-      for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(),
-             E = RD->vbases_end(); I != E; ++I)
-        Diag(I->getLocStart(),
-             diag::note_constexpr_virtual_base_here) << I->getSourceRange();
+      for (const auto &I : RD->vbases())
+        Diag(I.getLocStart(),
+             diag::note_constexpr_virtual_base_here) << I.getSourceRange();
       return false;
     }
   }
@@ -789,7 +797,7 @@
     }
 
     // - its return type shall be a literal type;
-    QualType RT = NewFD->getResultType();
+    QualType RT = NewFD->getReturnType();
     if (!RT->isDependentType() &&
         RequireLiteralType(NewFD->getLocation(), RT,
                            diag::err_constexpr_non_literal_return))
@@ -813,9 +821,8 @@
   // C++11 [dcl.constexpr]p3 and p4:
   //  The definition of a constexpr function(p3) or constructor(p4) [...] shall
   //  contain only
-  for (DeclStmt::decl_iterator DclIt = DS->decl_begin(),
-         DclEnd = DS->decl_end(); DclIt != DclEnd; ++DclIt) {
-    switch ((*DclIt)->getKind()) {
+  for (const auto *DclIt : DS->decls()) {
+    switch (DclIt->getKind()) {
     case Decl::StaticAssert:
     case Decl::Using:
     case Decl::UsingShadow:
@@ -831,7 +838,7 @@
     case Decl::TypeAlias: {
       //   - typedef declarations and alias-declarations that do not define
       //     classes or enumerations,
-      TypedefNameDecl *TN = cast<TypedefNameDecl>(*DclIt);
+      const auto *TN = cast<TypedefNameDecl>(DclIt);
       if (TN->getUnderlyingType()->isVariablyModifiedType()) {
         // Don't allow variably-modified types in constexpr functions.
         TypeLoc TL = TN->getTypeSourceInfo()->getTypeLoc();
@@ -846,7 +853,7 @@
     case Decl::Enum:
     case Decl::CXXRecord:
       // C++1y allows types to be defined, not just declared.
-      if (cast<TagDecl>(*DclIt)->isThisDeclarationADefinition())
+      if (cast<TagDecl>(DclIt)->isThisDeclarationADefinition())
         SemaRef.Diag(DS->getLocStart(),
                      SemaRef.getLangOpts().CPlusPlus1y
                        ? diag::warn_cxx11_compat_constexpr_type_definition
@@ -865,7 +872,7 @@
       // C++1y [dcl.constexpr]p3 allows anything except:
       //   a definition of a variable of non-literal type or of static or
       //   thread storage duration or for which no initialization is performed.
-      VarDecl *VD = cast<VarDecl>(*DclIt);
+      const auto *VD = cast<VarDecl>(DclIt);
       if (VD->isThisDeclarationADefinition()) {
         if (VD->isStaticLocal()) {
           SemaRef.Diag(VD->getLocation(),
@@ -880,7 +887,8 @@
               diag::err_constexpr_local_var_non_literal_type,
               isa<CXXConstructorDecl>(Dcl)))
           return false;
-        if (!VD->hasInit() && !VD->isCXXForRangeDecl()) {
+        if (!VD->getType()->isDependentType() &&
+            !VD->hasInit() && !VD->isCXXForRangeDecl()) {
           SemaRef.Diag(VD->getLocation(),
                        diag::err_constexpr_local_var_no_init)
             << isa<CXXConstructorDecl>(Dcl);
@@ -932,8 +940,13 @@
   if (Field->isUnnamedBitfield())
     return;
 
+  // Anonymous unions with no variant members and empty anonymous structs do not
+  // need to be explicitly initialized. FIXME: Anonymous structs that contain no
+  // indirect fields don't need initializing.
   if (Field->isAnonymousStructOrUnion() &&
-      Field->getType()->getAsCXXRecordDecl()->isEmpty())
+      (Field->getType()->isUnionType()
+           ? !Field->getType()->getAsCXXRecordDecl()->hasVariantMembers()
+           : Field->getType()->getAsCXXRecordDecl()->isEmpty()))
     return;
 
   if (!Inits.count(Field)) {
@@ -944,12 +957,11 @@
     SemaRef.Diag(Field->getLocation(), diag::note_constexpr_ctor_missing_init);
   } else if (Field->isAnonymousStructOrUnion()) {
     const RecordDecl *RD = Field->getType()->castAs<RecordType>()->getDecl();
-    for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
-         I != E; ++I)
+    for (auto *I : RD->fields())
       // If an anonymous union contains an anonymous struct of which any member
       // is initialized, all members must be initialized.
-      if (!RD->isUnion() || Inits.count(*I))
-        CheckConstexprCtorInitializer(SemaRef, Dcl, *I, Inits, Diagnosed);
+      if (!RD->isUnion() || Inits.count(I))
+        CheckConstexprCtorInitializer(SemaRef, Dcl, I, Inits, Diagnosed);
   }
 }
 
@@ -993,9 +1005,8 @@
       Cxx1yLoc = S->getLocStart();
 
     CompoundStmt *CompStmt = cast<CompoundStmt>(S);
-    for (CompoundStmt::body_iterator BodyIt = CompStmt->body_begin(),
-           BodyEnd = CompStmt->body_end(); BodyIt != BodyEnd; ++BodyIt) {
-      if (!CheckConstexprFunctionStmt(SemaRef, Dcl, *BodyIt, ReturnStmts,
+    for (auto *BodyIt : CompStmt->body()) {
+      if (!CheckConstexprFunctionStmt(SemaRef, Dcl, BodyIt, ReturnStmts,
                                       Cxx1yLoc))
         return false;
     }
@@ -1097,9 +1108,8 @@
   //   [... list of cases ...]
   CompoundStmt *CompBody = cast<CompoundStmt>(Body);
   SourceLocation Cxx1yLoc;
-  for (CompoundStmt::body_iterator BodyIt = CompBody->body_begin(),
-         BodyEnd = CompBody->body_end(); BodyIt != BodyEnd; ++BodyIt) {
-    if (!CheckConstexprFunctionStmt(*this, Dcl, *BodyIt, ReturnStmts, Cxx1yLoc))
+  for (auto *BodyIt : CompBody->body()) {
+    if (!CheckConstexprFunctionStmt(*this, Dcl, BodyIt, ReturnStmts, Cxx1yLoc))
       return false;
   }
 
@@ -1116,11 +1126,12 @@
     // DR1359:
     // - every non-variant non-static data member and base class sub-object
     //   shall be initialized;
-    // - if the class is a non-empty union, or for each non-empty anonymous
-    //   union member of a non-union class, exactly one non-static data member
+    // DR1460:
+    // - if the class is a union having variant members, exactly one of them
     //   shall be initialized;
     if (RD->isUnion()) {
-      if (Constructor->getNumCtorInitializers() == 0 && !RD->isEmpty()) {
+      if (Constructor->getNumCtorInitializers() == 0 &&
+          RD->hasVariantMembers()) {
         Diag(Dcl->getLocation(), diag::err_constexpr_union_ctor_no_init);
         return false;
       }
@@ -1139,25 +1150,26 @@
           break;
         }
       }
+      // DR1460:
+      // - if the class is a union-like class, but is not a union, for each of
+      //   its anonymous union members having variant members, exactly one of
+      //   them shall be initialized;
       if (AnyAnonStructUnionMembers ||
           Constructor->getNumCtorInitializers() != RD->getNumBases() + Fields) {
         // Check initialization of non-static data members. Base classes are
         // always initialized so do not need to be checked. Dependent bases
         // might not have initializers in the member initializer list.
         llvm::SmallSet<Decl*, 16> Inits;
-        for (CXXConstructorDecl::init_const_iterator
-               I = Constructor->init_begin(), E = Constructor->init_end();
-             I != E; ++I) {
-          if (FieldDecl *FD = (*I)->getMember())
+        for (const auto *I: Constructor->inits()) {
+          if (FieldDecl *FD = I->getMember())
             Inits.insert(FD);
-          else if (IndirectFieldDecl *ID = (*I)->getIndirectMember())
+          else if (IndirectFieldDecl *ID = I->getIndirectMember())
             Inits.insert(ID->chain_begin(), ID->chain_end());
         }
 
         bool Diagnosed = false;
-        for (CXXRecordDecl::field_iterator I = RD->field_begin(),
-             E = RD->field_end(); I != E; ++I)
-          CheckConstexprCtorInitializer(*this, Dcl, *I, Inits, Diagnosed);
+        for (auto *I : RD->fields())
+          CheckConstexprCtorInitializer(*this, Dcl, I, Inits, Diagnosed);
         if (Diagnosed)
           return false;
       }
@@ -1165,10 +1177,12 @@
   } else {
     if (ReturnStmts.empty()) {
       // C++1y doesn't require constexpr functions to contain a 'return'
-      // statement. We still do, unless the return type is void, because
+      // statement. We still do, unless the return type might be void, because
       // otherwise if there's no return statement, the function cannot
       // be used in a core constant expression.
-      bool OK = getLangOpts().CPlusPlus1y && Dcl->getResultType()->isVoidType();
+      bool OK = getLangOpts().CPlusPlus1y &&
+                (Dcl->getReturnType()->isVoidType() ||
+                 Dcl->getReturnType()->isDependentType());
       Diag(Dcl->getLocation(),
            OK ? diag::warn_cxx11_compat_constexpr_body_no_return
               : diag::err_constexpr_body_no_return);
@@ -1261,10 +1275,8 @@
 
   Class = Class->getCanonicalDecl();
   while (true) {
-    for (CXXRecordDecl::base_class_const_iterator I = Current->bases_begin(),
-                                                  E = Current->bases_end();
-         I != E; ++I) {
-      CXXRecordDecl *Base = I->getType()->getAsCXXRecordDecl();
+    for (const auto &I : Current->bases()) {
+      CXXRecordDecl *Base = I.getType()->getAsCXXRecordDecl();
       if (!Base)
         continue;
 
@@ -1287,6 +1299,57 @@
   return false;
 }
 
+/// \brief Perform propagation of DLL attributes from a derived class to a
+/// templated base class for MS compatibility.
+static void propagateDLLAttrToBaseClassTemplate(
+    Sema &S, CXXRecordDecl *Class, Attr *ClassAttr,
+    ClassTemplateSpecializationDecl *BaseTemplateSpec, SourceLocation BaseLoc) {
+  if (getDLLAttr(
+          BaseTemplateSpec->getSpecializedTemplate()->getTemplatedDecl())) {
+    // If the base class template has a DLL attribute, don't try to change it.
+    return;
+  }
+
+  if (BaseTemplateSpec->getSpecializationKind() == TSK_Undeclared) {
+    // If the base class is not already specialized, we can do the propagation.
+    auto *NewAttr = cast<InheritableAttr>(ClassAttr->clone(S.getASTContext()));
+    NewAttr->setInherited(true);
+    BaseTemplateSpec->addAttr(NewAttr);
+    return;
+  }
+
+  bool DifferentAttribute = false;
+  if (Attr *SpecializationAttr = getDLLAttr(BaseTemplateSpec)) {
+    if (!SpecializationAttr->isInherited()) {
+      // The template has previously been specialized or instantiated with an
+      // explicit attribute. We should not try to change it.
+      return;
+    }
+    if (SpecializationAttr->getKind() == ClassAttr->getKind()) {
+      // The specialization already has the right attribute.
+      return;
+    }
+    DifferentAttribute = true;
+  }
+
+  // The template was previously instantiated or explicitly specialized without
+  // a dll attribute, or the template was previously instantiated with a
+  // different inherited attribute. It's too late for us to change the
+  // attribute, so warn that this is unsupported.
+  S.Diag(BaseLoc, diag::warn_attribute_dll_instantiated_base_class)
+      << BaseTemplateSpec->isExplicitSpecialization() << DifferentAttribute;
+  S.Diag(ClassAttr->getLocation(), diag::note_attribute);
+  if (BaseTemplateSpec->isExplicitSpecialization()) {
+    S.Diag(BaseTemplateSpec->getLocation(),
+           diag::note_template_class_explicit_specialization_was_here)
+        << BaseTemplateSpec;
+  } else {
+    S.Diag(BaseTemplateSpec->getPointOfInstantiation(),
+           diag::note_template_class_instantiation_was_here)
+        << BaseTemplateSpec;
+  }
+}
+
 /// \brief Check the validity of a C++ base class specifier.
 ///
 /// \returns a new CXXBaseSpecifier if well-formed, emits diagnostics
@@ -1304,7 +1367,7 @@
   if (Class->isUnion()) {
     Diag(Class->getLocation(), diag::err_base_clause_on_union)
       << SpecifierRange;
-    return 0;
+    return nullptr;
   }
 
   if (EllipsisLoc.isValid() && 
@@ -1330,8 +1393,8 @@
         if (BaseDecl->getCanonicalDecl() != Class->getCanonicalDecl())
           Diag(BaseDecl->getLocation(), diag::note_previous_decl)
             << BaseType;
-            
-        return 0;
+
+        return nullptr;
       }
     }
 
@@ -1343,14 +1406,25 @@
   // Base specifiers must be record types.
   if (!BaseType->isRecordType()) {
     Diag(BaseLoc, diag::err_base_must_be_class) << SpecifierRange;
-    return 0;
+    return nullptr;
   }
 
   // C++ [class.union]p1:
   //   A union shall not be used as a base class.
   if (BaseType->isUnionType()) {
     Diag(BaseLoc, diag::err_union_as_base_class) << SpecifierRange;
-    return 0;
+    return nullptr;
+  }
+
+  // For the MS ABI, propagate DLL attributes to base class templates.
+  if (Context.getTargetInfo().getCXXABI().isMicrosoft()) {
+    if (Attr *ClassAttr = getDLLAttr(Class)) {
+      if (auto *BaseTemplate = dyn_cast_or_null<ClassTemplateSpecializationDecl>(
+              BaseType->getAsCXXRecordDecl())) {
+        propagateDLLAttrToBaseClassTemplate(*this, Class, ClassAttr,
+                                            BaseTemplate, BaseLoc);
+      }
+    }
   }
 
   // C++ [class.derived]p2:
@@ -1359,7 +1433,7 @@
   if (RequireCompleteType(BaseLoc, BaseType,
                           diag::err_incomplete_base_class, SpecifierRange)) {
     Class->setInvalidDecl();
-    return 0;
+    return nullptr;
   }
 
   // If the base class is polymorphic or isn't empty, the new one is/isn't, too.
@@ -1379,7 +1453,7 @@
   if (CXXBaseDecl->hasFlexibleArrayMember()) {
     Diag(BaseLoc, diag::err_base_class_has_flexible_array_member)
       << CXXBaseDecl->getDeclName();
-    return 0;
+    return nullptr;
   }
 
   // C++ [class]p3:
@@ -1389,9 +1463,9 @@
     Diag(BaseLoc, diag::err_class_marked_final_used_as_base)
       << CXXBaseDecl->getDeclName()
       << FA->isSpelledAsSealed();
-    Diag(CXXBaseDecl->getLocation(), diag::note_previous_decl)
-      << CXXBaseDecl->getDeclName();
-    return 0;
+    Diag(CXXBaseDecl->getLocation(), diag::note_entity_declared_at)
+        << CXXBaseDecl->getDeclName() << FA->getRange();
+    return nullptr;
   }
 
   if (BaseDecl->isInvalidDecl())
@@ -1422,6 +1496,9 @@
   if (!Class)
     return true;
 
+  // We haven't yet attached the base specifiers.
+  Class->setIsParsingBaseSpecifiers();
+
   // We do not support any C++11 attributes on base-specifiers yet.
   // Diagnose any attributes we see.
   if (!Attributes.empty()) {
@@ -1438,7 +1515,7 @@
     }
   }
 
-  TypeSourceInfo *TInfo = 0;
+  TypeSourceInfo *TInfo = nullptr;
   GetTypeFromParser(basetype, &TInfo);
 
   if (EllipsisLoc.isInvalid() &&
@@ -1509,7 +1586,7 @@
           Invalid = true;
         }
         if (RD->hasAttr<WeakAttr>())
-          Class->addAttr(::new (Context) WeakAttr(SourceRange(), Context));
+          Class->addAttr(WeakAttr::CreateImplicit(Context));
       }
     }
   }
@@ -1841,10 +1918,10 @@
 }
 
 static AttributeList *getMSPropertyAttr(AttributeList *list) {
-  for (AttributeList* it = list; it != 0; it = it->getNext())
+  for (AttributeList *it = list; it != nullptr; it = it->getNext())
     if (it->isDeclspecPropertyAttribute())
       return it;
-  return 0;
+  return nullptr;
 }
 
 /// ActOnCXXMemberDeclarator - This is invoked when a C++ class member
@@ -1913,7 +1990,7 @@
       else
         Diag(Loc, diag::err_invalid_member_in_interface)
           << (InvalidDecl-1) << "";
-      return 0;
+      return nullptr;
     }
   }
 
@@ -1952,20 +2029,26 @@
         Diag(DS.getConstexprSpecLoc(), diag::err_invalid_constexpr_member);
     SourceLocation ConstexprLoc = DS.getConstexprSpecLoc();
     if (InitStyle == ICIS_NoInit) {
-      B << 0 << 0 << FixItHint::CreateReplacement(ConstexprLoc, "const");
-      D.getMutableDeclSpec().ClearConstexprSpec();
-      const char *PrevSpec;
-      unsigned DiagID;
-      bool Failed = D.getMutableDeclSpec().SetTypeQual(DeclSpec::TQ_const, ConstexprLoc,
-                                         PrevSpec, DiagID, getLangOpts());
-      (void)Failed;
-      assert(!Failed && "Making a constexpr member const shouldn't fail");
+      B << 0 << 0;
+      if (D.getDeclSpec().getTypeQualifiers() & DeclSpec::TQ_const)
+        B << FixItHint::CreateRemoval(ConstexprLoc);
+      else {
+        B << FixItHint::CreateReplacement(ConstexprLoc, "const");
+        D.getMutableDeclSpec().ClearConstexprSpec();
+        const char *PrevSpec;
+        unsigned DiagID;
+        bool Failed = D.getMutableDeclSpec().SetTypeQual(
+            DeclSpec::TQ_const, ConstexprLoc, PrevSpec, DiagID, getLangOpts());
+        (void)Failed;
+        assert(!Failed && "Making a constexpr member const shouldn't fail");
+      }
     } else {
       B << 1;
       const char *PrevSpec;
       unsigned DiagID;
       if (D.getMutableDeclSpec().SetStorageClassSpec(
-          *this, DeclSpec::SCS_static, ConstexprLoc, PrevSpec, DiagID)) {
+          *this, DeclSpec::SCS_static, ConstexprLoc, PrevSpec, DiagID,
+          Context.getPrintingPolicy())) {
         assert(DS.getStorageClassSpec() == DeclSpec::SCS_mutable &&
                "This is the only DeclSpec that should fail to be applied");
         B << 1;
@@ -1984,7 +2067,7 @@
     if (!Name.isIdentifier()) {
       Diag(Loc, diag::err_bad_variable_name)
         << Name;
-      return 0;
+      return nullptr;
     }
 
     IdentifierInfo *II = Name.getAsIdentifierInfo();
@@ -2007,7 +2090,7 @@
             << SourceRange(TemplateParams->getTemplateLoc(),
                 TemplateParams->getRAngleLoc());
       }
-      return 0;
+      return nullptr;
     }
 
     if (SS.isSet() && !SS.isInvalid()) {
@@ -2032,7 +2115,7 @@
       Member = HandleMSProperty(S, cast<CXXRecordDecl>(CurContext), Loc, D,
                                 BitWidth, InitStyle, AS, MSPropertyAttr);
       if (!Member)
-        return 0;
+        return nullptr;
       isInstField = false;
     } else {
       Member = HandleField(S, cast<CXXRecordDecl>(CurContext), Loc, D,
@@ -2044,7 +2127,7 @@
 
     Member = HandleDeclarator(S, D, TemplateParameterLists);
     if (!Member)
-      return 0;
+      return nullptr;
 
     // Non-instance-fields can't have a bitfield.
     if (BitWidth) {
@@ -2067,7 +2150,7 @@
           << BitWidth->getSourceRange();
       }
 
-      BitWidth = 0;
+      BitWidth = nullptr;
       Member->setInvalidDecl();
     }
 
@@ -2082,7 +2165,7 @@
   }
 
   if (VS.isOverrideSpecified())
-    Member->addAttr(new (Context) OverrideAttr(VS.getOverrideLoc(), Context));
+    Member->addAttr(new (Context) OverrideAttr(VS.getOverrideLoc(), Context, 0));
   if (VS.isFinalSpecified())
     Member->addAttr(new (Context) FinalAttr(VS.getFinalLoc(), Context,
                                             VS.isFinalSpelledSealed()));
@@ -2101,9 +2184,7 @@
     FieldDecl *FD = cast<FieldDecl>(Member);
     FieldCollector->Add(FD);
 
-    if (Diags.getDiagnosticLevel(diag::warn_unused_private_field,
-                                 FD->getLocation())
-          != DiagnosticsEngine::Ignored) {
+    if (!Diags.isIgnored(diag::warn_unused_private_field, FD->getLocation())) {
       // Remember all explicit private FieldDecls that have a name, no side
       // effects and are not part of a dependent type declaration.
       if (!FD->isImplicit() && FD->getDeclName() &&
@@ -2278,7 +2359,7 @@
       // In class initializers will point to the constructor.
       UninitializedFieldVisitor(S, Decls, Constructor).Visit(E);
     } else {
-      UninitializedFieldVisitor(S, Decls, 0).Visit(E);
+      UninitializedFieldVisitor(S, Decls, nullptr).Visit(E);
     }
   }
 
@@ -2291,9 +2372,8 @@
   static void DiagnoseUninitializedFields(
       Sema &SemaRef, const CXXConstructorDecl *Constructor) {
 
-    if (SemaRef.getDiagnostics().getDiagnosticLevel(diag::warn_field_is_uninit,
-                                                    Constructor->getLocation())
-        == DiagnosticsEngine::Ignored) {
+    if (SemaRef.getDiagnostics().isIgnored(diag::warn_field_is_uninit,
+                                           Constructor->getLocation())) {
       return;
     }
 
@@ -2306,38 +2386,44 @@
     llvm::SmallPtrSet<ValueDecl*, 4> UninitializedFields;
 
     // At the beginning, all fields are uninitialized.
-    for (DeclContext::decl_iterator I = RD->decls_begin(), E = RD->decls_end();
-         I != E; ++I) {
-      if (FieldDecl *FD = dyn_cast<FieldDecl>(*I)) {
+    for (auto *I : RD->decls()) {
+      if (auto *FD = dyn_cast<FieldDecl>(I)) {
         UninitializedFields.insert(FD);
-      } else if (IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(*I)) {
+      } else if (auto *IFD = dyn_cast<IndirectFieldDecl>(I)) {
         UninitializedFields.insert(IFD->getAnonField());
       }
     }
 
-    for (CXXConstructorDecl::init_const_iterator FieldInit =
-             Constructor->init_begin(),
-             FieldInitEnd = Constructor->init_end();
-         FieldInit != FieldInitEnd; ++FieldInit) {
-
-      Expr *InitExpr = (*FieldInit)->getInit();
+    for (const auto *FieldInit : Constructor->inits()) {
+      Expr *InitExpr = FieldInit->getInit();
 
       CheckInitExprContainsUninitializedFields(
           SemaRef, InitExpr, UninitializedFields, Constructor);
 
-      if (FieldDecl *Field = (*FieldInit)->getAnyMember())
+      if (FieldDecl *Field = FieldInit->getAnyMember())
         UninitializedFields.erase(Field);
     }
   }
 } // namespace
 
-/// ActOnCXXInClassMemberInitializer - This is invoked after parsing an
-/// in-class initializer for a non-static C++ class member, and after
-/// instantiating an in-class initializer in a class template. Such actions
-/// are deferred until the class is complete.
-void
-Sema::ActOnCXXInClassMemberInitializer(Decl *D, SourceLocation InitLoc,
-                                       Expr *InitExpr) {
+/// \brief Enter a new C++ default initializer scope. After calling this, the
+/// caller must call \ref ActOnFinishCXXInClassMemberInitializer, even if
+/// parsing or instantiating the initializer failed.
+void Sema::ActOnStartCXXInClassMemberInitializer() {
+  // Create a synthetic function scope to represent the call to the constructor
+  // that notionally surrounds a use of this initializer.
+  PushFunctionScope();
+}
+
+/// \brief This is invoked after parsing an in-class initializer for a
+/// non-static C++ class member, and after instantiating an in-class initializer
+/// in a class template. Such actions are deferred until the class is complete.
+void Sema::ActOnFinishCXXInClassMemberInitializer(Decl *D,
+                                                  SourceLocation InitLoc,
+                                                  Expr *InitExpr) {
+  // Pop the notional constructor scope we created earlier.
+  PopFunctionScopeInfo(nullptr, D);
+
   FieldDecl *FD = cast<FieldDecl>(D);
   assert(FD->getInClassInitStyle() != ICIS_NoInit &&
          "must set init style when field is created");
@@ -2371,13 +2457,13 @@
   // C++11 [class.base.init]p7:
   //   The initialization of each base and member constitutes a
   //   full-expression.
-  Init = ActOnFinishFullExpr(Init.take(), InitLoc);
+  Init = ActOnFinishFullExpr(Init.get(), InitLoc);
   if (Init.isInvalid()) {
     FD->setInvalidDecl();
     return;
   }
 
-  InitExpr = Init.release();
+  InitExpr = Init.get();
 
   FD->setInClassInitializer(InitExpr);
 }
@@ -2391,14 +2477,12 @@
                                 const CXXBaseSpecifier *&DirectBaseSpec,
                                 const CXXBaseSpecifier *&VirtualBaseSpec) {
   // First, check for a direct base class.
-  DirectBaseSpec = 0;
-  for (CXXRecordDecl::base_class_const_iterator Base
-         = ClassDecl->bases_begin(); 
-       Base != ClassDecl->bases_end(); ++Base) {
-    if (SemaRef.Context.hasSameUnqualifiedType(BaseType, Base->getType())) {
+  DirectBaseSpec = nullptr;
+  for (const auto &Base : ClassDecl->bases()) {
+    if (SemaRef.Context.hasSameUnqualifiedType(BaseType, Base.getType())) {
       // We found a direct base of this type. That's what we're
       // initializing.
-      DirectBaseSpec = &*Base;
+      DirectBaseSpec = &Base;
       break;
     }
   }
@@ -2406,7 +2490,7 @@
   // Check for a virtual base class.
   // FIXME: We might be able to short-circuit this if we know in advance that
   // there are no virtual bases.
-  VirtualBaseSpec = 0;
+  VirtualBaseSpec = nullptr;
   if (!DirectBaseSpec || !DirectBaseSpec->isVirtual()) {
     // We haven't found a base yet; search the class hierarchy for a
     // virtual base class.
@@ -2471,7 +2555,7 @@
   explicit MemInitializerValidatorCCC(CXXRecordDecl *ClassDecl)
       : ClassDecl(ClassDecl) {}
 
-  bool ValidateCandidate(const TypoCorrection &candidate) LLVM_OVERRIDE {
+  bool ValidateCandidate(const TypoCorrection &candidate) override {
     if (NamedDecl *ND = candidate.getCorrectionDecl()) {
       if (FieldDecl *Member = dyn_cast<FieldDecl>(ND))
         return Member->getDeclContext()->getRedeclContext()->Equals(ClassDecl);
@@ -2543,7 +2627,7 @@
   }
   // It didn't name a member, so see if it names a class.
   QualType BaseType;
-  TypeSourceInfo *TInfo = 0;
+  TypeSourceInfo *TInfo = nullptr;
 
   if (TemplateTypeTy) {
     BaseType = GetTypeFromParser(TemplateTypeTy, &TInfo);
@@ -2585,7 +2669,7 @@
       MemInitializerValidatorCCC Validator(ClassDecl);
       if (R.empty() && BaseType.isNull() &&
           (Corr = CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, &SS,
-                              Validator, ClassDecl))) {
+                              Validator, CTK_ErrorRecovery, ClassDecl))) {
         if (FieldDecl *Member = Corr.getCorrectionDeclAs<FieldDecl>()) {
           // We have found a non-static data member with a similar
           // name to what was typed; complain and initialize that
@@ -2629,13 +2713,10 @@
 
     if (BaseType.isNull()) {
       BaseType = Context.getTypeDeclType(TyD);
-      if (SS.isSet()) {
-        NestedNameSpecifier *Qualifier =
-          static_cast<NestedNameSpecifier*>(SS.getScopeRep());
-
+      if (SS.isSet())
         // FIXME: preserve source range information
-        BaseType = Context.getElaboratedType(ETK_None, Qualifier, BaseType);
-      }
+        BaseType = Context.getElaboratedType(ETK_None, SS.getScopeRep(),
+                                             BaseType);
     }
   }
 
@@ -2731,15 +2812,17 @@
 
     // Initialize the member.
     InitializedEntity MemberEntity =
-      DirectMember ? InitializedEntity::InitializeMember(DirectMember, 0)
-                   : InitializedEntity::InitializeMember(IndirectMember, 0);
+      DirectMember ? InitializedEntity::InitializeMember(DirectMember, nullptr)
+                   : InitializedEntity::InitializeMember(IndirectMember,
+                                                         nullptr);
     InitializationKind Kind =
       InitList ? InitializationKind::CreateDirectList(IdLoc)
                : InitializationKind::CreateDirect(IdLoc, InitRange.getBegin(),
                                                   InitRange.getEnd());
 
     InitializationSequence InitSeq(*this, MemberEntity, Kind, Args);
-    ExprResult MemberInit = InitSeq.Perform(*this, MemberEntity, Kind, Args, 0);
+    ExprResult MemberInit = InitSeq.Perform(*this, MemberEntity, Kind, Args,
+                                            nullptr);
     if (MemberInit.isInvalid())
       return true;
 
@@ -2792,7 +2875,7 @@
                                                 InitRange.getEnd());
   InitializationSequence InitSeq(*this, DelegationEntity, Kind, Args);
   ExprResult DelegationInit = InitSeq.Perform(*this, DelegationEntity, Kind,
-                                              Args, 0);
+                                              Args, nullptr);
   if (DelegationInit.isInvalid())
     return true;
 
@@ -2815,10 +2898,10 @@
   // initializer. However, deconstructing the ASTs is a dicey process,
   // and this approach is far more likely to get the corner cases right.
   if (CurContext->isDependentContext())
-    DelegationInit = Owned(Init);
+    DelegationInit = Init;
 
   return new (Context) CXXCtorInitializer(Context, TInfo, InitRange.getBegin(), 
-                                          DelegationInit.takeAs<Expr>(),
+                                          DelegationInit.getAs<Expr>(),
                                           InitRange.getEnd());
 }
 
@@ -2860,8 +2943,8 @@
   }
 
   // Check for direct and virtual base classes.
-  const CXXBaseSpecifier *DirectBaseSpec = 0;
-  const CXXBaseSpecifier *VirtualBaseSpec = 0;
+  const CXXBaseSpecifier *DirectBaseSpec = nullptr;
+  const CXXBaseSpecifier *VirtualBaseSpec = nullptr;
   if (!Dependent) { 
     if (Context.hasSameUnqualifiedType(QualType(ClassDecl->getTypeForDecl(),0),
                                        BaseType))
@@ -2925,7 +3008,7 @@
              : InitializationKind::CreateDirect(BaseLoc, InitRange.getBegin(),
                                                 InitRange.getEnd());
   InitializationSequence InitSeq(*this, BaseEntity, Kind, Args);
-  ExprResult BaseInit = InitSeq.Perform(*this, BaseEntity, Kind, Args, 0);
+  ExprResult BaseInit = InitSeq.Perform(*this, BaseEntity, Kind, Args, nullptr);
   if (BaseInit.isInvalid())
     return true;
 
@@ -2944,12 +3027,12 @@
   // initializer. However, deconstructing the ASTs is a dicey process,
   // and this approach is far more likely to get the corner cases right.
   if (CurContext->isDependentContext())
-    BaseInit = Owned(Init);
+    BaseInit = Init;
 
   return new (Context) CXXCtorInitializer(Context, BaseTInfo,
                                           BaseSpec->isVirtual(),
                                           InitRange.getBegin(),
-                                          BaseInit.takeAs<Expr>(),
+                                          BaseInit.getAs<Expr>(),
                                           InitRange.getEnd(), EllipsisLoc);
 }
 
@@ -2964,7 +3047,7 @@
 
   return SemaRef.BuildCXXNamedCast(ExprLoc, tok::kw_static_cast, TargetLoc, E,
                                    SourceRange(ExprLoc, ExprLoc),
-                                   E->getSourceRange()).take();
+                                   E->getSourceRange()).get();
 }
 
 /// ImplicitInitializerKind - How an implicit base or member initializer should
@@ -3006,7 +3089,7 @@
                                      VK_LValue, SourceLocation());
         if (ArgExpr.isInvalid())
           return true;
-        Args.push_back(CastForMoving(SemaRef, ArgExpr.take(), PD->getType()));
+        Args.push_back(CastForMoving(SemaRef, ArgExpr.get(), PD->getType()));
       }
 
       InitializationKind InitKind = InitializationKind::CreateDirect(
@@ -3035,7 +3118,7 @@
       DeclRefExpr::Create(SemaRef.Context, NestedNameSpecifierLoc(),
                           SourceLocation(), Param, false,
                           Constructor->getLocation(), ParamType,
-                          VK_LValue, 0);
+                          VK_LValue, nullptr);
 
     SemaRef.MarkDeclRefReferenced(cast<DeclRefExpr>(CopyCtorArg));
 
@@ -3053,7 +3136,7 @@
     CopyCtorArg = SemaRef.ImpCastExprToType(CopyCtorArg, ArgTy,
                                             CK_UncheckedDerivedToBase,
                                             Moving ? VK_XValue : VK_LValue,
-                                            &BasePath).take();
+                                            &BasePath).get();
 
     InitializationKind InitKind
       = InitializationKind::CreateDirect(Constructor->getLocation(),
@@ -3074,7 +3157,7 @@
                                                         SourceLocation()),
                                              BaseSpec->isVirtual(),
                                              SourceLocation(),
-                                             BaseInit.takeAs<Expr>(),
+                                             BaseInit.getAs<Expr>(),
                                              SourceLocation(),
                                              SourceLocation());
 
@@ -3108,7 +3191,7 @@
     Expr *MemberExprBase = 
       DeclRefExpr::Create(SemaRef.Context, NestedNameSpecifierLoc(),
                           SourceLocation(), Param, false,
-                          Loc, ParamType, VK_LValue, 0);
+                          Loc, ParamType, VK_LValue, nullptr);
 
     SemaRef.MarkDeclRefReferenced(cast<DeclRefExpr>(MemberExprBase));
 
@@ -3129,9 +3212,9 @@
                                          /*IsArrow=*/false,
                                          SS,
                                          /*TemplateKWLoc=*/SourceLocation(),
-                                         /*FirstQualifierInScope=*/0,
+                                         /*FirstQualifierInScope=*/nullptr,
                                          MemberLookup,
-                                         /*TemplateArgs=*/0);    
+                                         /*TemplateArgs=*/nullptr);
     if (CtorArg.isInvalid())
       return true;
 
@@ -3139,7 +3222,7 @@
     //   - if a member m has rvalue reference type T&&, it is direct-initialized
     //     with static_cast<T&&>(x.m);
     if (RefersToRValueRef(CtorArg.get())) {
-      CtorArg = CastForMoving(SemaRef, CtorArg.take());
+      CtorArg = CastForMoving(SemaRef, CtorArg.get());
     }
 
     // When the field we are copying is an array, create index variables for 
@@ -3154,7 +3237,7 @@
                           = SemaRef.Context.getAsConstantArrayType(BaseType)) {
       InitializingArray = true;
       // Create the iteration variable for this array index.
-      IdentifierInfo *IterationVarName = 0;
+      IdentifierInfo *IterationVarName = nullptr;
       {
         SmallString<8> Str;
         llvm::raw_svector_ostream OS(Str);
@@ -3173,13 +3256,13 @@
         = SemaRef.BuildDeclRefExpr(IterationVar, SizeType, VK_LValue, Loc);
       assert(!IterationVarRef.isInvalid() &&
              "Reference to invented variable cannot fail!");
-      IterationVarRef = SemaRef.DefaultLvalueConversion(IterationVarRef.take());
+      IterationVarRef = SemaRef.DefaultLvalueConversion(IterationVarRef.get());
       assert(!IterationVarRef.isInvalid() &&
              "Conversion of invented variable cannot fail!");
 
       // Subscript the array with this iteration variable.
-      CtorArg = SemaRef.CreateBuiltinArraySubscriptExpr(CtorArg.take(), Loc,
-                                                        IterationVarRef.take(),
+      CtorArg = SemaRef.CreateBuiltinArraySubscriptExpr(CtorArg.get(), Loc,
+                                                        IterationVarRef.get(),
                                                         Loc);
       if (CtorArg.isInvalid())
         return true;
@@ -3189,7 +3272,7 @@
 
     // The array subscript expression is an lvalue, which is wrong for moving.
     if (Moving && InitializingArray)
-      CtorArg = CastForMoving(SemaRef, CtorArg.take());
+      CtorArg = CastForMoving(SemaRef, CtorArg.get());
 
     // Construct the entity that we will be initializing. For an array, this
     // will be first element in the array, which may require several levels
@@ -3209,7 +3292,7 @@
     InitializationKind InitKind =
       InitializationKind::CreateDirect(Loc, SourceLocation(), SourceLocation());
     
-    Expr *CtorArgE = CtorArg.takeAs<Expr>();
+    Expr *CtorArgE = CtorArg.getAs<Expr>();
     InitializationSequence InitSeq(SemaRef, Entities.back(), InitKind, CtorArgE);
     
     ExprResult MemberInit
@@ -3225,11 +3308,11 @@
       CXXMemberInit
         = new (SemaRef.Context) CXXCtorInitializer(SemaRef.Context, Indirect, 
                                                    Loc, Loc, 
-                                                   MemberInit.takeAs<Expr>(), 
+                                                   MemberInit.getAs<Expr>(), 
                                                    Loc);
     } else
       CXXMemberInit = CXXCtorInitializer::Create(SemaRef.Context, Field, Loc, 
-                                                 Loc, MemberInit.takeAs<Expr>(), 
+                                                 Loc, MemberInit.getAs<Expr>(), 
                                                  Loc,
                                                  IndexVariables.data(),
                                                  IndexVariables.size());
@@ -3308,7 +3391,7 @@
   }
       
   // Nothing to initialize.
-  CXXMemberInit = 0;
+  CXXMemberInit = nullptr;
   return false;
 }
 
@@ -3320,6 +3403,7 @@
   ImplicitInitializerKind IIK;
   llvm::DenseMap<const void *, CXXCtorInitializer*> AllBaseFields;
   SmallVector<CXXCtorInitializer*, 8> AllToInit;
+  llvm::DenseMap<TagDecl*, FieldDecl*> ActiveUnionMember;
 
   BaseAndFieldInfo(Sema &S, CXXConstructorDecl *Ctor, bool ErrorsInInits)
     : S(S), Ctor(Ctor), AnyErrorsInInits(ErrorsInInits) {
@@ -3357,20 +3441,48 @@
 
     return false;
   }
-};
-}
 
-/// \brief Determine whether the given indirect field declaration is somewhere
-/// within an anonymous union.
-static bool isWithinAnonymousUnion(IndirectFieldDecl *F) {
-  for (IndirectFieldDecl::chain_iterator C = F->chain_begin(), 
-                                      CEnd = F->chain_end();
-       C != CEnd; ++C)
-    if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>((*C)->getDeclContext()))
-      if (Record->isUnion())
+  bool isInactiveUnionMember(FieldDecl *Field) {
+    RecordDecl *Record = Field->getParent();
+    if (!Record->isUnion())
+      return false;
+
+    if (FieldDecl *Active =
+            ActiveUnionMember.lookup(Record->getCanonicalDecl()))
+      return Active != Field->getCanonicalDecl();
+
+    // In an implicit copy or move constructor, ignore any in-class initializer.
+    if (isImplicitCopyOrMove())
+      return true;
+
+    // If there's no explicit initialization, the field is active only if it
+    // has an in-class initializer...
+    if (Field->hasInClassInitializer())
+      return false;
+    // ... or it's an anonymous struct or union whose class has an in-class
+    // initializer.
+    if (!Field->isAnonymousStructOrUnion())
+      return true;
+    CXXRecordDecl *FieldRD = Field->getType()->getAsCXXRecordDecl();
+    return !FieldRD->hasInClassInitializer();
+  }
+
+  /// \brief Determine whether the given field is, or is within, a union member
+  /// that is inactive (because there was an initializer given for a different
+  /// member of the union, or because the union was not initialized at all).
+  bool isWithinInactiveUnionMember(FieldDecl *Field,
+                                   IndirectFieldDecl *Indirect) {
+    if (!Indirect)
+      return isInactiveUnionMember(Field);
+
+    for (auto *C : Indirect->chain()) {
+      FieldDecl *Field = dyn_cast<FieldDecl>(C);
+      if (Field && isInactiveUnionMember(Field))
         return true;
-        
-  return false;
+    }
+    return false;
+  }
+};
 }
 
 /// \brief Determine whether the given type is an incomplete or zero-lenfgth
@@ -3391,17 +3503,30 @@
 
 static bool CollectFieldInitializer(Sema &SemaRef, BaseAndFieldInfo &Info,
                                     FieldDecl *Field, 
-                                    IndirectFieldDecl *Indirect = 0) {
+                                    IndirectFieldDecl *Indirect = nullptr) {
   if (Field->isInvalidDecl())
     return false;
 
   // Overwhelmingly common case: we have a direct initializer for this field.
-  if (CXXCtorInitializer *Init = Info.AllBaseFields.lookup(Field))
+  if (CXXCtorInitializer *Init =
+          Info.AllBaseFields.lookup(Field->getCanonicalDecl()))
     return Info.addFieldInitializer(Init);
 
-  // C++11 [class.base.init]p8: if the entity is a non-static data member that
-  // has a brace-or-equal-initializer, the entity is initialized as specified
-  // in [dcl.init].
+  // C++11 [class.base.init]p8:
+  //   if the entity is a non-static data member that has a
+  //   brace-or-equal-initializer and either
+  //   -- the constructor's class is a union and no other variant member of that
+  //      union is designated by a mem-initializer-id or
+  //   -- the constructor's class is not a union, and, if the entity is a member
+  //      of an anonymous union, no other member of that union is designated by
+  //      a mem-initializer-id,
+  //   the entity is initialized as specified in [dcl.init].
+  //
+  // We also apply the same rules to handle anonymous structs within anonymous
+  // unions.
+  if (Info.isWithinInactiveUnionMember(Field, Indirect))
+    return false;
+
   if (Field->hasInClassInitializer() && !Info.isImplicitCopyOrMove()) {
     Expr *DIE = CXXDefaultInitExpr::Create(SemaRef.Context,
                                            Info.Ctor->getLocation(), Field);
@@ -3419,12 +3544,6 @@
     return Info.addFieldInitializer(Init);
   }
 
-  // Don't build an implicit initializer for union members if none was
-  // explicitly specified.
-  if (Field->getParent()->isUnion() ||
-      (Indirect && isWithinAnonymousUnion(Indirect)))
-    return false;
-
   // Don't initialize incomplete or zero-length arrays.
   if (isIncompleteOrZeroLengthArrayType(SemaRef.Context, Field->getType()))
     return false;
@@ -3435,7 +3554,7 @@
   if (Info.AnyErrorsInInits)
     return false;
 
-  CXXCtorInitializer *Init = 0;
+  CXXCtorInitializer *Init = nullptr;
   if (BuildImplicitMemberInitializer(Info.S, Info.Ctor, Info.IIK, Field,
                                      Indirect, Init))
     return true;
@@ -3502,24 +3621,35 @@
 
     if (Member->isBaseInitializer())
       Info.AllBaseFields[Member->getBaseClass()->getAs<RecordType>()] = Member;
-    else
-      Info.AllBaseFields[Member->getAnyMember()] = Member;
+    else {
+      Info.AllBaseFields[Member->getAnyMember()->getCanonicalDecl()] = Member;
+
+      if (IndirectFieldDecl *F = Member->getIndirectMember()) {
+        for (auto *C : F->chain()) {
+          FieldDecl *FD = dyn_cast<FieldDecl>(C);
+          if (FD && FD->getParent()->isUnion())
+            Info.ActiveUnionMember.insert(std::make_pair(
+                FD->getParent()->getCanonicalDecl(), FD->getCanonicalDecl()));
+        }
+      } else if (FieldDecl *FD = Member->getMember()) {
+        if (FD->getParent()->isUnion())
+          Info.ActiveUnionMember.insert(std::make_pair(
+              FD->getParent()->getCanonicalDecl(), FD->getCanonicalDecl()));
+      }
+    }
   }
 
   // Keep track of the direct virtual bases.
   llvm::SmallPtrSet<CXXBaseSpecifier *, 16> DirectVBases;
-  for (CXXRecordDecl::base_class_iterator I = ClassDecl->bases_begin(),
-       E = ClassDecl->bases_end(); I != E; ++I) {
-    if (I->isVirtual())
-      DirectVBases.insert(I);
+  for (auto &I : ClassDecl->bases()) {
+    if (I.isVirtual())
+      DirectVBases.insert(&I);
   }
 
   // Push virtual bases before others.
-  for (CXXRecordDecl::base_class_iterator VBase = ClassDecl->vbases_begin(),
-       E = ClassDecl->vbases_end(); VBase != E; ++VBase) {
-
+  for (auto &VBase : ClassDecl->vbases()) {
     if (CXXCtorInitializer *Value
-        = Info.AllBaseFields.lookup(VBase->getType()->getAs<RecordType>())) {
+        = Info.AllBaseFields.lookup(VBase.getType()->getAs<RecordType>())) {
       // [class.base.init]p7, per DR257:
       //   A mem-initializer where the mem-initializer-id names a virtual base
       //   class is ignored during execution of a constructor of any class that
@@ -3528,7 +3658,7 @@
         // FIXME: Provide a fixit to remove the base specifier. This requires
         // tracking the location of the associated comma for a base specifier.
         Diag(Value->getSourceLocation(), diag::warn_abstract_vbase_init_ignored)
-          << VBase->getType() << ClassDecl;
+          << VBase.getType() << ClassDecl;
         DiagnoseAbstractType(ClassDecl);
       }
 
@@ -3538,10 +3668,10 @@
       //   If a given [...] base class is not named by a mem-initializer-id
       //   [...] and the entity is not a virtual base class of an abstract
       //   class, then [...] the entity is default-initialized.
-      bool IsInheritedVirtualBase = !DirectVBases.count(VBase);
+      bool IsInheritedVirtualBase = !DirectVBases.count(&VBase);
       CXXCtorInitializer *CXXBaseInit;
       if (BuildImplicitBaseInitializer(*this, Constructor, Info.IIK,
-                                       VBase, IsInheritedVirtualBase,
+                                       &VBase, IsInheritedVirtualBase,
                                        CXXBaseInit)) {
         HadError = true;
         continue;
@@ -3552,19 +3682,18 @@
   }
 
   // Non-virtual bases.
-  for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
-       E = ClassDecl->bases_end(); Base != E; ++Base) {
+  for (auto &Base : ClassDecl->bases()) {
     // Virtuals are in the virtual base list and already constructed.
-    if (Base->isVirtual())
+    if (Base.isVirtual())
       continue;
 
     if (CXXCtorInitializer *Value
-          = Info.AllBaseFields.lookup(Base->getType()->getAs<RecordType>())) {
+          = Info.AllBaseFields.lookup(Base.getType()->getAs<RecordType>())) {
       Info.AllToInit.push_back(Value);
     } else if (!AnyErrors) {
       CXXCtorInitializer *CXXBaseInit;
       if (BuildImplicitBaseInitializer(*this, Constructor, Info.IIK,
-                                       Base, /*IsInheritedVirtualBase=*/false,
+                                       &Base, /*IsInheritedVirtualBase=*/false,
                                        CXXBaseInit)) {
         HadError = true;
         continue;
@@ -3575,10 +3704,8 @@
   }
 
   // Fields.
-  for (DeclContext::decl_iterator Mem = ClassDecl->decls_begin(),
-                               MemEnd = ClassDecl->decls_end();
-       Mem != MemEnd; ++Mem) {
-    if (FieldDecl *F = dyn_cast<FieldDecl>(*Mem)) {
+  for (auto *Mem : ClassDecl->decls()) {
+    if (auto *F = dyn_cast<FieldDecl>(Mem)) {
       // C++ [class.bit]p2:
       //   A declaration for a bit-field that omits the identifier declares an
       //   unnamed bit-field. Unnamed bit-fields are not members and cannot be
@@ -3601,7 +3728,7 @@
     if (Info.isImplicitCopyOrMove())
       continue;
     
-    if (IndirectFieldDecl *F = dyn_cast<IndirectFieldDecl>(*Mem)) {
+    if (auto *F = dyn_cast<IndirectFieldDecl>(Mem)) {
       if (F->getType()->isIncompleteArrayType()) {
         assert(ClassDecl->hasFlexibleArrayMember() &&
                "Incomplete array type is not valid");
@@ -3638,13 +3765,12 @@
   if (const RecordType *RT = Field->getType()->getAs<RecordType>()) {
     const RecordDecl *RD = RT->getDecl();
     if (RD->isAnonymousStructOrUnion()) {
-      for (RecordDecl::field_iterator Field = RD->field_begin(),
-          E = RD->field_end(); Field != E; ++Field)
-        PopulateKeysForFields(*Field, IdealInits);
+      for (auto *Field : RD->fields())
+        PopulateKeysForFields(Field, IdealInits);
       return;
     }
   }
-  IdealInits.push_back(Field);
+  IdealInits.push_back(Field->getCanonicalDecl());
 }
 
 static const void *GetKeyForBase(ASTContext &Context, QualType BaseType) {
@@ -3656,7 +3782,7 @@
   if (!Member->isAnyMemberInitializer())
     return GetKeyForBase(Context, QualType(Member->getBaseClass(), 0));
     
-  return Member->getAnyMember();
+  return Member->getAnyMember()->getCanonicalDecl();
 }
 
 static void DiagnoseBaseOrMemInitializerOrder(
@@ -3670,9 +3796,8 @@
   bool ShouldCheckOrder = false;
   for (unsigned InitIndex = 0; InitIndex != Inits.size(); ++InitIndex) {
     CXXCtorInitializer *Init = Inits[InitIndex];
-    if (SemaRef.Diags.getDiagnosticLevel(diag::warn_initializer_out_of_order,
-                                         Init->getSourceLocation())
-          != DiagnosticsEngine::Ignored) {
+    if (!SemaRef.Diags.isIgnored(diag::warn_initializer_out_of_order,
+                                 Init->getSourceLocation())) {
       ShouldCheckOrder = true;
       break;
     }
@@ -3688,32 +3813,28 @@
   const CXXRecordDecl *ClassDecl = Constructor->getParent();
 
   // 1. Virtual bases.
-  for (CXXRecordDecl::base_class_const_iterator VBase =
-       ClassDecl->vbases_begin(),
-       E = ClassDecl->vbases_end(); VBase != E; ++VBase)
-    IdealInitKeys.push_back(GetKeyForBase(SemaRef.Context, VBase->getType()));
+  for (const auto &VBase : ClassDecl->vbases())
+    IdealInitKeys.push_back(GetKeyForBase(SemaRef.Context, VBase.getType()));
 
   // 2. Non-virtual bases.
-  for (CXXRecordDecl::base_class_const_iterator Base = ClassDecl->bases_begin(),
-       E = ClassDecl->bases_end(); Base != E; ++Base) {
-    if (Base->isVirtual())
+  for (const auto &Base : ClassDecl->bases()) {
+    if (Base.isVirtual())
       continue;
-    IdealInitKeys.push_back(GetKeyForBase(SemaRef.Context, Base->getType()));
+    IdealInitKeys.push_back(GetKeyForBase(SemaRef.Context, Base.getType()));
   }
 
   // 3. Direct fields.
-  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
-       E = ClassDecl->field_end(); Field != E; ++Field) {
+  for (auto *Field : ClassDecl->fields()) {
     if (Field->isUnnamedBitfield())
       continue;
     
-    PopulateKeysForFields(*Field, IdealInitKeys);
+    PopulateKeysForFields(Field, IdealInitKeys);
   }
   
   unsigned NumIdealInits = IdealInitKeys.size();
   unsigned IdealIndex = 0;
 
-  CXXCtorInitializer *PrevInit = 0;
+  CXXCtorInitializer *PrevInit = nullptr;
   for (unsigned InitIndex = 0; InitIndex != Inits.size(); ++InitIndex) {
     CXXCtorInitializer *Init = Inits[InitIndex];
     const void *InitKey = GetKeyForMember(SemaRef.Context, Init);
@@ -3855,13 +3976,12 @@
     Init->setSourceOrder(i);
 
     if (Init->isAnyMemberInitializer()) {
-      FieldDecl *Field = Init->getAnyMember();
-      if (CheckRedundantInit(*this, Init, Members[Field]) ||
+      const void *Key = GetKeyForMember(Context, Init);
+      if (CheckRedundantInit(*this, Init, Members[Key]) ||
           CheckRedundantUnionInit(*this, Init, MemberUnions))
         HadError = true;
     } else if (Init->isBaseInitializer()) {
-      const void *Key =
-          GetKeyForBase(Context, QualType(Init->getBaseClass(), 0));
+      const void *Key = GetKeyForMember(Context, Init);
       if (CheckRedundantInit(*this, Init, Members[Key]))
         HadError = true;
     } else {
@@ -3903,9 +4023,7 @@
   // emitted, and we currently don't say.
   
   // Non-static data members.
-  for (CXXRecordDecl::field_iterator I = ClassDecl->field_begin(),
-       E = ClassDecl->field_end(); I != E; ++I) {
-    FieldDecl *Field = *I;
+  for (auto *Field : ClassDecl->fields()) {
     if (Field->isInvalidDecl())
       continue;
     
@@ -3942,13 +4060,12 @@
   llvm::SmallPtrSet<const RecordType *, 8> DirectVirtualBases;
 
   // Bases.
-  for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
-       E = ClassDecl->bases_end(); Base != E; ++Base) {
+  for (const auto &Base : ClassDecl->bases()) {
     // Bases are always records in a well-formed non-dependent class.
-    const RecordType *RT = Base->getType()->getAs<RecordType>();
+    const RecordType *RT = Base.getType()->getAs<RecordType>();
 
     // Remember direct virtual bases.
-    if (Base->isVirtual())
+    if (Base.isVirtual())
       DirectVirtualBases.insert(RT);
 
     CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(RT->getDecl());
@@ -3962,10 +4079,10 @@
     assert(Dtor && "No dtor found for BaseClassDecl!");
 
     // FIXME: caret should be on the start of the class name
-    CheckDestructorAccess(Base->getLocStart(), Dtor,
+    CheckDestructorAccess(Base.getLocStart(), Dtor,
                           PDiag(diag::err_access_dtor_base)
-                            << Base->getType()
-                            << Base->getSourceRange(),
+                            << Base.getType()
+                            << Base.getSourceRange(),
                           Context.getTypeDeclType(ClassDecl));
     
     MarkFunctionReferenced(Location, Dtor);
@@ -3973,11 +4090,9 @@
   }
   
   // Virtual bases.
-  for (CXXRecordDecl::base_class_iterator VBase = ClassDecl->vbases_begin(),
-       E = ClassDecl->vbases_end(); VBase != E; ++VBase) {
-
+  for (const auto &VBase : ClassDecl->vbases()) {
     // Bases are always records in a well-formed non-dependent class.
-    const RecordType *RT = VBase->getType()->castAs<RecordType>();
+    const RecordType *RT = VBase.getType()->castAs<RecordType>();
 
     // Ignore direct virtual bases.
     if (DirectVirtualBases.count(RT))
@@ -3995,13 +4110,13 @@
     if (CheckDestructorAccess(
             ClassDecl->getLocation(), Dtor,
             PDiag(diag::err_access_dtor_vbase)
-                << Context.getTypeDeclType(ClassDecl) << VBase->getType(),
+                << Context.getTypeDeclType(ClassDecl) << VBase.getType(),
             Context.getTypeDeclType(ClassDecl)) ==
         AR_accessible) {
       CheckDerivedToBaseConversion(
-          Context.getTypeDeclType(ClassDecl), VBase->getType(),
+          Context.getTypeDeclType(ClassDecl), VBase.getType(),
           diag::err_access_dtor_vbase, 0, ClassDecl->getLocation(),
-          SourceRange(), DeclarationName(), 0);
+          SourceRange(), DeclarationName(), nullptr);
     }
 
     MarkFunctionReferenced(Location, Dtor);
@@ -4030,7 +4145,7 @@
     NonAbstractTypeDiagnoser(unsigned DiagID, AbstractDiagSelID SelID)
       : TypeDiagnoser(DiagID == 0), DiagID(DiagID), SelID(SelID) { }
 
-    void diagnose(Sema &S, SourceLocation Loc, QualType T) LLVM_OVERRIDE {
+    void diagnose(Sema &S, SourceLocation Loc, QualType T) override {
       if (Suppressed) return;
       if (SelID == -1)
         S.Diag(Loc, DiagID) << T;
@@ -4172,12 +4287,12 @@
   }
 
   void Check(FunctionProtoTypeLoc TL, Sema::AbstractDiagSelID Sel) {
-    Visit(TL.getResultLoc(), Sema::AbstractReturnType);
-    for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
-      if (!TL.getArg(I))
+    Visit(TL.getReturnLoc(), Sema::AbstractReturnType);
+    for (unsigned I = 0, E = TL.getNumParams(); I != E; ++I) {
+      if (!TL.getParam(I))
         continue;
-      
-      TypeSourceInfo *TSI = TL.getArg(I)->getTypeSourceInfo();
+
+      TypeSourceInfo *TSI = TL.getParam(I)->getTypeSourceInfo();
       if (TSI) Visit(TSI->getTypeLoc(), Sema::AbstractParamType);
     }
   }
@@ -4267,9 +4382,7 @@
 /// Check for invalid uses of an abstract type within a class definition.
 static void CheckAbstractClassUsage(AbstractUsageInfo &Info,
                                     CXXRecordDecl *RD) {
-  for (CXXRecordDecl::decl_iterator
-         I = RD->decls_begin(), E = RD->decls_end(); I != E; ++I) {
-    Decl *D = *I;
+  for (auto *D : RD->decls()) {
     if (D->isImplicit()) continue;
 
     // Methods and method templates.
@@ -4299,6 +4412,77 @@
   }
 }
 
+/// \brief Check class-level dllimport/dllexport attribute.
+static void checkDLLAttribute(Sema &S, CXXRecordDecl *Class) {
+  Attr *ClassAttr = getDLLAttr(Class);
+  if (!ClassAttr)
+    return;
+
+  bool ClassExported = ClassAttr->getKind() == attr::DLLExport;
+
+  // Force declaration of implicit members so they can inherit the attribute.
+  S.ForceDeclarationOfImplicitMembers(Class);
+
+  // FIXME: MSVC's docs say all bases must be exportable, but this doesn't
+  // seem to be true in practice?
+
+  for (Decl *Member : Class->decls()) {
+    VarDecl *VD = dyn_cast<VarDecl>(Member);
+    CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Member);
+
+    // Only methods and static fields inherit the attributes.
+    if (!VD && !MD)
+      continue;
+
+    // Don't process deleted methods.
+    if (MD && MD->isDeleted())
+      continue;
+
+    if (MD && MD->isMoveAssignmentOperator() && !ClassExported &&
+        MD->isInlined()) {
+      // Current MSVC versions don't export the move assignment operators, so
+      // don't attempt to import them if we have a definition.
+      continue;
+    }
+
+    if (InheritableAttr *MemberAttr = getDLLAttr(Member)) {
+      if (S.Context.getTargetInfo().getCXXABI().isMicrosoft() &&
+          !MemberAttr->isInherited() && !ClassAttr->isInherited()) {
+        S.Diag(MemberAttr->getLocation(),
+               diag::err_attribute_dll_member_of_dll_class)
+            << MemberAttr << ClassAttr;
+        S.Diag(ClassAttr->getLocation(), diag::note_previous_attribute);
+        Member->setInvalidDecl();
+        continue;
+      }
+    } else {
+      auto *NewAttr =
+          cast<InheritableAttr>(ClassAttr->clone(S.getASTContext()));
+      NewAttr->setInherited(true);
+      Member->addAttr(NewAttr);
+    }
+
+    if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Member)) {
+      if (ClassExported) {
+        if (MD->isUserProvided()) {
+          // Instantiate non-default methods.
+          S.MarkFunctionReferenced(Class->getLocation(), MD);
+        } else if (!MD->isTrivial() || MD->isExplicitlyDefaulted() ||
+                   MD->isCopyAssignmentOperator() ||
+                   MD->isMoveAssignmentOperator()) {
+          // Instantiate non-trivial or explicitly defaulted methods, and the
+          // copy assignment / move assignment operators.
+          S.MarkFunctionReferenced(Class->getLocation(), MD);
+          // Resolve its exception specification; CodeGen needs it.
+          auto *FPT = MD->getType()->getAs<FunctionProtoType>();
+          S.ResolveExceptionSpec(Class->getLocation(), FPT);
+          S.ActOnFinishInlineMethodDef(MD);
+        }
+      }
+    }
+  }
+}
+
 /// \brief Perform semantic checks on a class definition that has been
 /// completing, introducing implicitly-declared members, checking for
 /// abstract types, etc.
@@ -4318,9 +4502,7 @@
       !Record->isAggregate() && !Record->hasUserDeclaredConstructor() &&
       !Record->isLambda()) {
     bool Complained = false;
-    for (RecordDecl::field_iterator F = Record->field_begin(), 
-                                 FEnd = Record->field_end();
-         F != FEnd; ++F) {
+    for (const auto *F : Record->fields()) {
       if (F->hasInClassInitializer() || F->isUnnamedBitfield())
         continue;
 
@@ -4367,7 +4549,8 @@
   // Warn if the class has virtual methods but non-virtual public destructor.
   if (Record->isPolymorphic() && !Record->isDependentType()) {
     CXXDestructorDecl *dtor = Record->getDestructor();
-    if (!dtor || (!dtor->isVirtual() && dtor->getAccess() == AS_public))
+    if ((!dtor || (!dtor->isVirtual() && dtor->getAccess() == AS_public)) &&
+        !Record->hasAttr<FinalAttr>())
       Diag(dtor ? dtor->getLocation() : Record->getLocation(),
            diag::warn_non_virtual_dtor) << Context.getRecordType(Record);
   }
@@ -4381,27 +4564,25 @@
   }
 
   if (!Record->isDependentType()) {
-    for (CXXRecordDecl::method_iterator M = Record->method_begin(),
-                                     MEnd = Record->method_end();
-         M != MEnd; ++M) {
+    for (auto *M : Record->methods()) {
       // See if a method overloads virtual methods in a base
       // class without overriding any.
       if (!M->isStatic())
-        DiagnoseHiddenVirtualMethods(*M);
+        DiagnoseHiddenVirtualMethods(M);
 
       // Check whether the explicitly-defaulted special members are valid.
       if (!M->isInvalidDecl() && M->isExplicitlyDefaulted())
-        CheckExplicitlyDefaultedSpecialMember(*M);
+        CheckExplicitlyDefaultedSpecialMember(M);
 
       // For an explicitly defaulted or deleted special member, we defer
       // determining triviality until the class is complete. That time is now!
       if (!M->isImplicit() && !M->isUserProvided()) {
-        CXXSpecialMember CSM = getSpecialMember(*M);
+        CXXSpecialMember CSM = getSpecialMember(M);
         if (CSM != CXXInvalid) {
-          M->setTrivial(SpecialMemberIsTrivial(*M, CSM));
+          M->setTrivial(SpecialMemberIsTrivial(M, CSM));
 
           // Inform the class that we've finished declaring this member.
-          Record->finishedDefaultedOrDeletedMember(*M);
+          Record->finishedDefaultedOrDeletedMember(M);
         }
       }
     }
@@ -4420,10 +4601,8 @@
   // destructor for the class is trivial.
   if (LangOpts.CPlusPlus11 && !Record->isDependentType() &&
       !Record->isLiteral() && !Record->getNumVBases()) {
-    for (CXXRecordDecl::method_iterator M = Record->method_begin(),
-                                     MEnd = Record->method_end();
-         M != MEnd; ++M) {
-      if (M->isConstexpr() && M->isInstance() && !isa<CXXConstructorDecl>(*M)) {
+    for (const auto *M : Record->methods()) {
+      if (M->isConstexpr() && M->isInstance() && !isa<CXXConstructorDecl>(M)) {
         switch (Record->getTemplateSpecializationKind()) {
         case TSK_ImplicitInstantiation:
         case TSK_ExplicitInstantiationDeclaration:
@@ -4446,11 +4625,18 @@
     }
   }
 
-  // Check to see if we're trying to lay out a struct using the ms_struct
-  // attribute that is dynamic.
-  if (Record->isMsStruct(Context) && Record->isDynamicClass()) {
-    Diag(Record->getLocation(), diag::warn_pragma_ms_struct_failed);
-    Record->dropAttr<MsStructAttr>();
+  // ms_struct is a request to use the same ABI rules as MSVC.  Check
+  // whether this class uses any C++ features that are implemented
+  // completely differently in MSVC, and if so, emit a diagnostic.
+  // That diagnostic defaults to an error, but we allow projects to
+  // map it down to a warning (or ignore it).  It's a fairly common
+  // practice among users of the ms_struct pragma to mass-annotate
+  // headers, sweeping up a bunch of types that the project doesn't
+  // really rely on MSVC-compatible layout for.  We must therefore
+  // support "ms_struct except for C++ stuff" as a secondary ABI.
+  if (Record->isMsStruct(Context) &&
+      (Record->isPolymorphic() || Record->getNumBases())) {
+    Diag(Record->getLocation(), diag::warn_cxx_ms_struct);
   }
 
   // Declare inheriting constructors. We do this eagerly here because:
@@ -4461,16 +4647,47 @@
   //   instantiated (e.g. meta-functions). This doesn't apply to classes that
   //   have inheriting constructors.
   DeclareInheritingConstructors(Record);
+
+  checkDLLAttribute(*this, Record);
+}
+
+/// Look up the special member function that would be called by a special
+/// member function for a subobject of class type.
+///
+/// \param Class The class type of the subobject.
+/// \param CSM The kind of special member function.
+/// \param FieldQuals If the subobject is a field, its cv-qualifiers.
+/// \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(
+    Sema &S, CXXRecordDecl *Class, Sema::CXXSpecialMember CSM,
+    unsigned FieldQuals, bool ConstRHS) {
+  unsigned LHSQuals = 0;
+  if (CSM == Sema::CXXCopyAssignment || CSM == Sema::CXXMoveAssignment)
+    LHSQuals = FieldQuals;
+
+  unsigned RHSQuals = FieldQuals;
+  if (CSM == Sema::CXXDefaultConstructor || CSM == Sema::CXXDestructor)
+    RHSQuals = 0;
+  else if (ConstRHS)
+    RHSQuals |= Qualifiers::Const;
+
+  return S.LookupSpecialMember(Class, CSM,
+                               RHSQuals & Qualifiers::Const,
+                               RHSQuals & Qualifiers::Volatile,
+                               false,
+                               LHSQuals & Qualifiers::Const,
+                               LHSQuals & Qualifiers::Volatile);
 }
 
 /// Is the special member function which would be selected to perform the
 /// specified operation on the specified class type a constexpr constructor?
 static bool specialMemberIsConstexpr(Sema &S, CXXRecordDecl *ClassDecl,
                                      Sema::CXXSpecialMember CSM,
-                                     bool ConstArg) {
+                                     unsigned Quals, bool ConstRHS) {
   Sema::SpecialMemberOverloadResult *SMOR =
-      S.LookupSpecialMember(ClassDecl, CSM, ConstArg,
-                            false, false, false, false);
+      lookupCallFromSpecialMember(S, ClassDecl, CSM, Quals, ConstRHS);
   if (!SMOR || !SMOR->getMethod())
     // A constructor we wouldn't select can't be "involved in initializing"
     // anything.
@@ -4540,14 +4757,12 @@
   //      sub-objects shall be a constexpr constructor;
   //   -- the assignment operator selected to copy/move each direct base
   //      class is a constexpr function, and
-  for (CXXRecordDecl::base_class_iterator B = ClassDecl->bases_begin(),
-                                       BEnd = ClassDecl->bases_end();
-       B != BEnd; ++B) {
-    const RecordType *BaseType = B->getType()->getAs<RecordType>();
+  for (const auto &B : ClassDecl->bases()) {
+    const RecordType *BaseType = B.getType()->getAs<RecordType>();
     if (!BaseType) continue;
 
     CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseType->getDecl());
-    if (!specialMemberIsConstexpr(S, BaseClassDecl, CSM, ConstArg))
+    if (!specialMemberIsConstexpr(S, BaseClassDecl, CSM, 0, ConstArg))
       return false;
   }
 
@@ -4555,18 +4770,18 @@
   //      [...] shall be a constexpr constructor;
   //   -- every non-static data member and base class sub-object shall be
   //      initialized
-  //   -- for each non-stastic data member of X that is of class type (or array
+  //   -- for each non-static data member of X that is of class type (or array
   //      thereof), the assignment operator selected to copy/move that member is
   //      a constexpr function
-  for (RecordDecl::field_iterator F = ClassDecl->field_begin(),
-                               FEnd = ClassDecl->field_end();
-       F != FEnd; ++F) {
+  for (const auto *F : ClassDecl->fields()) {
     if (F->isInvalidDecl())
       continue;
-    if (const RecordType *RecordTy =
-            S.Context.getBaseElementType(F->getType())->getAs<RecordType>()) {
+    QualType BaseType = S.Context.getBaseElementType(F->getType());
+    if (const RecordType *RecordTy = BaseType->getAs<RecordType>()) {
       CXXRecordDecl *FieldRecDecl = cast<CXXRecordDecl>(RecordTy->getDecl());
-      if (!specialMemberIsConstexpr(S, FieldRecDecl, CSM, ConstArg))
+      if (!specialMemberIsConstexpr(S, FieldRecDecl, CSM,
+                                    BaseType.getCVRQualifiers(),
+                                    ConstArg && !F->isMutable()))
         return false;
     }
   }
@@ -4598,15 +4813,6 @@
   return S.ComputeInheritingCtorExceptionSpec(cast<CXXConstructorDecl>(MD));
 }
 
-static void
-updateExceptionSpec(Sema &S, FunctionDecl *FD, const FunctionProtoType *FPT,
-                    const Sema::ImplicitExceptionSpecification &ExceptSpec) {
-  FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
-  ExceptSpec.getEPI(EPI);
-  FD->setType(S.Context.getFunctionType(FPT->getResultType(),
-                                        FPT->getArgTypes(), EPI));
-}
-
 static FunctionProtoType::ExtProtoInfo getImplicitMethodEPI(Sema &S,
                                                             CXXMethodDecl *MD) {
   FunctionProtoType::ExtProtoInfo EPI;
@@ -4631,8 +4837,11 @@
   ImplicitExceptionSpecification ExceptSpec =
       computeImplicitExceptionSpec(*this, Loc, MD);
 
+  FunctionProtoType::ExtProtoInfo EPI;
+  ExceptSpec.getEPI(EPI);
+
   // Update the type of the special member to use it.
-  updateExceptionSpec(*this, MD, FPT, ExceptSpec);
+  UpdateExceptionSpec(MD, EPI);
 
   // A user-provided destructor can be defined outside the class. When that
   // happens, be sure to update the exception specification on both
@@ -4640,8 +4849,7 @@
   const FunctionProtoType *CanonicalFPT =
     MD->getCanonicalDecl()->getType()->castAs<FunctionProtoType>();
   if (CanonicalFPT->getExceptionSpecType() == EST_Unevaluated)
-    updateExceptionSpec(*this, MD->getCanonicalDecl(),
-                        CanonicalFPT, ExceptSpec);
+    UpdateExceptionSpec(MD->getCanonicalDecl(), EPI);
 }
 
 void Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD) {
@@ -4691,7 +4899,7 @@
   QualType ReturnType = Context.VoidTy;
   if (CSM == CXXCopyAssignment || CSM == CXXMoveAssignment) {
     // Check for return type matching.
-    ReturnType = Type->getResultType();
+    ReturnType = Type->getReturnType();
     QualType ExpectedReturnType =
         Context.getLValueReferenceType(Context.getTypeDeclType(RD));
     if (!Context.hasSameType(ReturnType, ExpectedReturnType)) {
@@ -4709,7 +4917,7 @@
   }
 
   // Check for parameter type matching.
-  QualType ArgType = ExpectedParams ? Type->getArgType(0) : QualType();
+  QualType ArgType = ExpectedParams ? Type->getParamType(0) : QualType();
   bool HasConstParam = false;
   if (ExpectedParams && ArgType->isReferenceType()) {
     // Argument must be reference to possibly-const T.
@@ -4803,6 +5011,7 @@
       //   [For a] user-provided explicitly-defaulted function [...] if such a
       //   function is implicitly defined as deleted, the program is ill-formed.
       Diag(MD->getLocation(), diag::err_out_of_line_default_deletes) << CSM;
+      ShouldDeleteSpecialMember(MD, CSM, /*Diagnose*/true);
       HadError = true;
     }
   }
@@ -4865,7 +5074,7 @@
   bool Diagnose;
 
   // Properties of the special member, computed for convenience.
-  bool IsConstructor, IsAssignment, IsMove, ConstArg, VolatileArg;
+  bool IsConstructor, IsAssignment, IsMove, ConstArg;
   SourceLocation Loc;
 
   bool AllFieldsAreConst;
@@ -4874,7 +5083,7 @@
                             Sema::CXXSpecialMember CSM, bool Diagnose)
     : S(S), MD(MD), CSM(CSM), Diagnose(Diagnose),
       IsConstructor(false), IsAssignment(false), IsMove(false),
-      ConstArg(false), VolatileArg(false), Loc(MD->getLocation()),
+      ConstArg(false), Loc(MD->getLocation()),
       AllFieldsAreConst(true) {
     switch (CSM) {
       case Sema::CXXDefaultConstructor:
@@ -4899,8 +5108,9 @@
     }
 
     if (MD->getNumParams()) {
-      ConstArg = MD->getParamDecl(0)->getType().isConstQualified();
-      VolatileArg = MD->getParamDecl(0)->getType().isVolatileQualified();
+      if (const ReferenceType *RT =
+              MD->getParamDecl(0)->getType()->getAs<ReferenceType>())
+        ConstArg = RT->getPointeeType().isConstQualified();
     }
   }
 
@@ -4908,17 +5118,9 @@
 
   /// Look up the corresponding special member in the given class.
   Sema::SpecialMemberOverloadResult *lookupIn(CXXRecordDecl *Class,
-                                              unsigned Quals) {
-    unsigned TQ = MD->getTypeQualifiers();
-    // cv-qualifiers on class members don't affect default ctor / dtor calls.
-    if (CSM == Sema::CXXDefaultConstructor || CSM == Sema::CXXDestructor)
-      Quals = 0;
-    return S.LookupSpecialMember(Class, CSM,
-                                 ConstArg || (Quals & Qualifiers::Const),
-                                 VolatileArg || (Quals & Qualifiers::Volatile),
-                                 MD->getRefQualifier() == RQ_RValue,
-                                 TQ & Qualifiers::Const,
-                                 TQ & Qualifiers::Volatile);
+                                              unsigned Quals, bool IsMutable) {
+    return lookupCallFromSpecialMember(S, Class, CSM, Quals,
+                                       ConstArg && !IsMutable);
   }
 
   typedef llvm::PointerUnion<CXXBaseSpecifier*, FieldDecl*> Subobject;
@@ -5013,6 +5215,7 @@
 bool SpecialMemberDeletionInfo::shouldDeleteForClassSubobject(
     CXXRecordDecl *Class, Subobject Subobj, unsigned Quals) {
   FieldDecl *Field = Subobj.dyn_cast<FieldDecl*>();
+  bool IsMutable = Field && Field->isMutable();
 
   // C++11 [class.ctor]p5:
   // -- any direct or virtual base class, or non-static data member with no
@@ -5030,7 +5233,8 @@
   //    that is deleted or inaccessible
   if (!(CSM == Sema::CXXDefaultConstructor &&
         Field && Field->hasInClassInitializer()) &&
-      shouldDeleteForSubobjectCall(Subobj, lookupIn(Class, Quals), false))
+      shouldDeleteForSubobjectCall(Subobj, lookupIn(Class, Quals, IsMutable),
+                                   false))
     return true;
 
   // C++11 [class.ctor]p5, C++11 [class.copy]p11:
@@ -5118,9 +5322,7 @@
       bool AllVariantFieldsAreConst = true;
 
       // FIXME: Handle anonymous unions declared within anonymous unions.
-      for (CXXRecordDecl::field_iterator UI = FieldRecord->field_begin(),
-                                         UE = FieldRecord->field_end();
-           UI != UE; ++UI) {
+      for (auto *UI : FieldRecord->fields()) {
         QualType UnionFieldType = S.Context.getBaseElementType(UI->getType());
 
         if (!UnionFieldType.isConstQualified())
@@ -5128,14 +5330,14 @@
 
         CXXRecordDecl *UnionFieldRecord = UnionFieldType->getAsCXXRecordDecl();
         if (UnionFieldRecord &&
-            shouldDeleteForClassSubobject(UnionFieldRecord, *UI,
+            shouldDeleteForClassSubobject(UnionFieldRecord, UI,
                                           UnionFieldType.getCVRQualifiers()))
           return true;
       }
 
       // At least one member in each anonymous union must be non-const
       if (CSM == Sema::CXXDefaultConstructor && AllVariantFieldsAreConst &&
-          FieldRecord->field_begin() != FieldRecord->field_end()) {
+          !FieldRecord->field_empty()) {
         if (Diagnose)
           S.Diag(FieldRecord->getLocation(),
                  diag::note_deleted_default_ctor_all_const)
@@ -5163,7 +5365,7 @@
   // This is a silly definition, because it gives an empty union a deleted
   // default constructor. Don't do that.
   if (CSM == Sema::CXXDefaultConstructor && inUnion() && AllFieldsAreConst &&
-      (MD->getParent()->field_begin() != MD->getParent()->field_end())) {
+      !MD->getParent()->field_empty()) {
     if (Diagnose)
       S.Diag(MD->getParent()->getLocation(),
              diag::note_deleted_default_ctor_all_const)
@@ -5209,32 +5411,30 @@
   //   operator is defined as deleted.
   if (MD->isImplicit() &&
       (CSM == CXXCopyConstructor || CSM == CXXCopyAssignment)) {
-    CXXMethodDecl *UserDeclaredMove = 0;
+    CXXMethodDecl *UserDeclaredMove = nullptr;
 
     // In Microsoft mode, a user-declared move only causes the deletion of the
     // corresponding copy operation, not both copy operations.
     if (RD->hasUserDeclaredMoveConstructor() &&
-        (!getLangOpts().MicrosoftMode || CSM == CXXCopyConstructor)) {
+        (!getLangOpts().MSVCCompat || CSM == CXXCopyConstructor)) {
       if (!Diagnose) return true;
 
       // Find any user-declared move constructor.
-      for (CXXRecordDecl::ctor_iterator I = RD->ctor_begin(),
-                                        E = RD->ctor_end(); I != E; ++I) {
+      for (auto *I : RD->ctors()) {
         if (I->isMoveConstructor()) {
-          UserDeclaredMove = *I;
+          UserDeclaredMove = I;
           break;
         }
       }
       assert(UserDeclaredMove);
     } else if (RD->hasUserDeclaredMoveAssignment() &&
-               (!getLangOpts().MicrosoftMode || CSM == CXXCopyAssignment)) {
+               (!getLangOpts().MSVCCompat || CSM == CXXCopyAssignment)) {
       if (!Diagnose) return true;
 
       // Find any user-declared move assignment operator.
-      for (CXXRecordDecl::method_iterator I = RD->method_begin(),
-                                          E = RD->method_end(); I != E; ++I) {
+      for (auto *I : RD->methods()) {
         if (I->isMoveAssignmentOperator()) {
-          UserDeclaredMove = *I;
+          UserDeclaredMove = I;
           break;
         }
       }
@@ -5257,7 +5457,7 @@
   // -- for a virtual destructor, lookup of the non-array deallocation function
   //    results in an ambiguity or in a function that is deleted or inaccessible
   if (CSM == CXXDestructor && MD->isVirtual()) {
-    FunctionDecl *OperatorDelete = 0;
+    FunctionDecl *OperatorDelete = nullptr;
     DeclarationName Name =
       Context.DeclarationNames.getCXXOperatorName(OO_Delete);
     if (FindDeallocationFunction(MD->getLocation(), MD->getParent(), Name,
@@ -5270,26 +5470,22 @@
 
   SpecialMemberDeletionInfo SMI(*this, MD, CSM, Diagnose);
 
-  for (CXXRecordDecl::base_class_iterator BI = RD->bases_begin(),
-                                          BE = RD->bases_end(); BI != BE; ++BI)
-    if (!BI->isVirtual() &&
-        SMI.shouldDeleteForBase(BI))
+  for (auto &BI : RD->bases())
+    if (!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.
   if (!RD->isAbstract() || !SMI.IsConstructor) {
-    for (CXXRecordDecl::base_class_iterator BI = RD->vbases_begin(),
-                                            BE = RD->vbases_end();
-         BI != BE; ++BI)
-      if (SMI.shouldDeleteForBase(BI))
+    for (auto &BI : RD->vbases())
+      if (SMI.shouldDeleteForBase(&BI))
         return true;
   }
 
-  for (CXXRecordDecl::field_iterator FI = RD->field_begin(),
-                                     FE = RD->field_end(); FI != FE; ++FI)
+  for (auto *FI : RD->fields())
     if (!FI->isInvalidDecl() && !FI->isUnnamedBitfield() &&
-        SMI.shouldDeleteForField(*FI))
+        SMI.shouldDeleteForField(FI))
       return true;
 
   if (SMI.shouldDeleteForAllConstMembers())
@@ -5308,9 +5504,9 @@
 /// member that was most likely to be intended to be trivial, if any.
 static bool findTrivialSpecialMember(Sema &S, CXXRecordDecl *RD,
                                      Sema::CXXSpecialMember CSM, unsigned Quals,
-                                     CXXMethodDecl **Selected) {
+                                     bool ConstRHS, CXXMethodDecl **Selected) {
   if (Selected)
-    *Selected = 0;
+    *Selected = nullptr;
 
   switch (CSM) {
   case Sema::CXXInvalid:
@@ -5329,14 +5525,13 @@
       // If there's a default constructor which could have been trivial, dig it
       // out. Otherwise, if there's any user-provided default constructor, point
       // to that as an example of why there's not a trivial one.
-      CXXConstructorDecl *DefCtor = 0;
+      CXXConstructorDecl *DefCtor = nullptr;
       if (RD->needsImplicitDefaultConstructor())
         S.DeclareImplicitDefaultConstructor(RD);
-      for (CXXRecordDecl::ctor_iterator CI = RD->ctor_begin(),
-                                        CE = RD->ctor_end(); CI != CE; ++CI) {
+      for (auto *CI : RD->ctors()) {
         if (!CI->isDefaultConstructor())
           continue;
-        DefCtor = *CI;
+        DefCtor = CI;
         if (!DefCtor->isUserProvided())
           break;
       }
@@ -5399,11 +5594,7 @@
   case Sema::CXXMoveAssignment:
   NeedOverloadResolution:
     Sema::SpecialMemberOverloadResult *SMOR =
-      S.LookupSpecialMember(RD, CSM,
-                            Quals & Qualifiers::Const,
-                            Quals & Qualifiers::Volatile,
-                            /*RValueThis*/false, /*ConstThis*/false,
-                            /*VolatileThis*/false);
+        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
@@ -5429,10 +5620,9 @@
 }
 
 static CXXConstructorDecl *findUserDeclaredCtor(CXXRecordDecl *RD) {
-  for (CXXRecordDecl::ctor_iterator CI = RD->ctor_begin(), CE = RD->ctor_end();
-       CI != CE; ++CI)
+  for (auto *CI : RD->ctors())
     if (!CI->isImplicit())
-      return *CI;
+      return CI;
 
   // Look for constructor templates.
   typedef CXXRecordDecl::specific_decl_iterator<FunctionTemplateDecl> tmpl_iter;
@@ -5442,7 +5632,7 @@
       return CD;
   }
 
-  return 0;
+  return nullptr;
 }
 
 /// The kind of subobject we are checking for triviality. The values of this
@@ -5458,7 +5648,7 @@
 
 /// Check whether the special member selected for a given type would be trivial.
 static bool checkTrivialSubobjectCall(Sema &S, SourceLocation SubobjLoc,
-                                      QualType SubType,
+                                      QualType SubType, bool ConstRHS,
                                       Sema::CXXSpecialMember CSM,
                                       TrivialSubobjectKind Kind,
                                       bool Diagnose) {
@@ -5468,10 +5658,13 @@
 
   CXXMethodDecl *Selected;
   if (findTrivialSpecialMember(S, SubRD, CSM, SubType.getCVRQualifiers(),
-                               Diagnose ? &Selected : 0))
+                               ConstRHS, Diagnose ? &Selected : nullptr))
     return true;
 
   if (Diagnose) {
+    if (ConstRHS)
+      SubType.addConst();
+
     if (!Selected && CSM == Sema::CXXDefaultConstructor) {
       S.Diag(SubobjLoc, diag::note_nontrivial_no_def_ctor)
         << Kind << SubType.getUnqualifiedType();
@@ -5507,8 +5700,7 @@
 static bool checkTrivialClassMembers(Sema &S, CXXRecordDecl *RD,
                                      Sema::CXXSpecialMember CSM,
                                      bool ConstArg, bool Diagnose) {
-  for (CXXRecordDecl::field_iterator FI = RD->field_begin(),
-                                     FE = RD->field_end(); FI != FE; ++FI) {
+  for (const auto *FI : RD->fields()) {
     if (FI->isInvalidDecl() || FI->isUnnamedBitfield())
       continue;
 
@@ -5528,7 +5720,7 @@
     //       brace-or-equal-initializer
     if (CSM == Sema::CXXDefaultConstructor && FI->hasInClassInitializer()) {
       if (Diagnose)
-        S.Diag(FI->getLocation(), diag::note_nontrivial_in_class_init) << *FI;
+        S.Diag(FI->getLocation(), diag::note_nontrivial_in_class_init) << FI;
       return false;
     }
 
@@ -5544,10 +5736,9 @@
       return false;
     }
 
-    if (ConstArg && !FI->isMutable())
-      FieldType.addConst();
-    if (!checkTrivialSubobjectCall(S, FI->getLocation(), FieldType, CSM,
-                                   TSK_Field, Diagnose))
+    bool ConstRHS = ConstArg && !FI->isMutable();
+    if (!checkTrivialSubobjectCall(S, FI->getLocation(), FieldType, ConstRHS,
+                                   CSM, TSK_Field, Diagnose))
       return false;
   }
 
@@ -5558,10 +5749,9 @@
 /// the given kind.
 void Sema::DiagnoseNontrivial(const CXXRecordDecl *RD, CXXSpecialMember CSM) {
   QualType Ty = Context.getRecordType(RD);
-  if (CSM == CXXCopyConstructor || CSM == CXXCopyAssignment)
-    Ty.addConst();
 
-  checkTrivialSubobjectCall(*this, RD->getLocation(), Ty, CSM,
+  bool ConstArg = (CSM == CXXCopyConstructor || CSM == CXXCopyAssignment);
+  checkTrivialSubobjectCall(*this, RD->getLocation(), Ty, ConstArg, CSM,
                             TSK_CompleteObject, /*Diagnose*/true);
 }
 
@@ -5644,12 +5834,9 @@
   //   A [default constructor or destructor] is trivial if
   //    -- all the direct base classes have trivial [default constructors or
   //       destructors]
-  for (CXXRecordDecl::base_class_iterator BI = RD->bases_begin(),
-                                          BE = RD->bases_end(); BI != BE; ++BI)
-    if (!checkTrivialSubobjectCall(*this, BI->getLocStart(),
-                                   ConstArg ? BI->getType().withConst()
-                                            : BI->getType(),
-                                   CSM, TSK_BaseClass, Diagnose))
+  for (const auto &BI : RD->bases())
+    if (!checkTrivialSubobjectCall(*this, BI.getLocStart(), BI.getType(),
+                                   ConstArg, CSM, TSK_BaseClass, Diagnose))
       return false;
 
   // C++11 [class.ctor]p5, C++11 [class.dtor]p5:
@@ -5693,8 +5880,7 @@
     }
 
     // Must have a virtual method.
-    for (CXXRecordDecl::method_iterator MI = RD->method_begin(),
-                                        ME = RD->method_end(); MI != ME; ++MI) {
+    for (const auto *MI : RD->methods()) {
       if (MI->isVirtual()) {
         SourceLocation MLoc = MI->getLocStart();
         Diag(MLoc, diag::note_nontrivial_has_virtual) << RD << 0;
@@ -5832,8 +6018,7 @@
   if (MD->isInvalidDecl())
     return;
 
-  if (Diags.getDiagnosticLevel(diag::warn_overloaded_virtual,
-                               MD->getLocation()) == DiagnosticsEngine::Ignored)
+  if (Diags.isIgnored(diag::warn_overloaded_virtual, MD->getLocation()))
     return;
 
   SmallVector<CXXMethodDecl *, 8> OverloadedMethods;
@@ -5933,47 +6118,55 @@
   }
 }
 
-void Sema::ActOnReenterDeclaratorTemplateScope(Scope *S, DeclaratorDecl *D) {
+unsigned Sema::ActOnReenterTemplateScope(Scope *S, Decl *D) {
   if (!D)
-    return;
+    return 0;
 
-  int NumParamList = D->getNumTemplateParameterLists();
-  for (int i = 0; i < NumParamList; i++) {
-    TemplateParameterList* Params = D->getTemplateParameterList(i);
-    for (TemplateParameterList::iterator Param = Params->begin(),
-                                      ParamEnd = Params->end();
-          Param != ParamEnd; ++Param) {
-      NamedDecl *Named = cast<NamedDecl>(*Param);
-      if (Named->getDeclName()) {
-        S->AddDecl(Named);
-        IdResolver.AddDecl(Named);
+  // The order of template parameters is not important here. All names
+  // get added to the same scope.
+  SmallVector<TemplateParameterList *, 4> ParameterLists;
+
+  if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D))
+    D = TD->getTemplatedDecl();
+
+  if (auto *PSD = dyn_cast<ClassTemplatePartialSpecializationDecl>(D))
+    ParameterLists.push_back(PSD->getTemplateParameters());
+
+  if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
+    for (unsigned i = 0; i < DD->getNumTemplateParameterLists(); ++i)
+      ParameterLists.push_back(DD->getTemplateParameterList(i));
+
+    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+      if (FunctionTemplateDecl *FTD = FD->getDescribedFunctionTemplate())
+        ParameterLists.push_back(FTD->getTemplateParameters());
+    }
+  }
+
+  if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
+    for (unsigned i = 0; i < TD->getNumTemplateParameterLists(); ++i)
+      ParameterLists.push_back(TD->getTemplateParameterList(i));
+
+    if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(TD)) {
+      if (ClassTemplateDecl *CTD = RD->getDescribedClassTemplate())
+        ParameterLists.push_back(CTD->getTemplateParameters());
+    }
+  }
+
+  unsigned Count = 0;
+  for (TemplateParameterList *Params : ParameterLists) {
+    if (Params->size() > 0)
+      // Ignore explicit specializations; they don't contribute to the template
+      // depth.
+      ++Count;
+    for (NamedDecl *Param : *Params) {
+      if (Param->getDeclName()) {
+        S->AddDecl(Param);
+        IdResolver.AddDecl(Param);
       }
     }
   }
-}
 
-void Sema::ActOnReenterTemplateScope(Scope *S, Decl *D) {
-  if (!D)
-    return;
-  
-  TemplateParameterList *Params = 0;
-  if (TemplateDecl *Template = dyn_cast<TemplateDecl>(D))
-    Params = Template->getTemplateParameters();
-  else if (ClassTemplatePartialSpecializationDecl *PartialSpec
-           = dyn_cast<ClassTemplatePartialSpecializationDecl>(D))
-    Params = PartialSpec->getTemplateParameters();
-  else
-    return;
-
-  for (TemplateParameterList::iterator Param = Params->begin(),
-                                    ParamEnd = Params->end();
-       Param != ParamEnd; ++Param) {
-    NamedDecl *Named = cast<NamedDecl>(*Param);
-    if (Named->getDeclName()) {
-      S->AddDecl(Named);
-      IdResolver.AddDecl(Named);
-    }
-  }
+  return Count;
 }
 
 void Sema::ActOnStartDelayedMemberDeclarations(Scope *S, Decl *RecordD) {
@@ -5988,6 +6181,18 @@
   PopDeclContext();
 }
 
+/// This is used to implement the constant expression evaluation part of the
+/// attribute enable_if extension. There is nothing in standard C++ which would
+/// require reentering parameters.
+void Sema::ActOnReenterCXXMethodParameter(Scope *S, ParmVarDecl *Param) {
+  if (!Param)
+    return;
+
+  S->AddDecl(Param);
+  if (Param->getDeclName())
+    IdResolver.AddDecl(Param);
+}
+
 /// ActOnStartDelayedCXXMethodDeclaration - We have completed
 /// parsing a top-level (non-nested) C++ class, and we are now
 /// parsing those parts of the given Method declaration that could
@@ -6013,7 +6218,7 @@
   // If this parameter has an unparsed default argument, clear it out
   // to make way for the parsed default argument.
   if (Param->hasUnparsedDefaultArg())
-    Param->setDefaultArg(0);
+    Param->setDefaultArg(nullptr);
 
   S->AddDecl(Param);
   if (Param->getDeclName())
@@ -6077,6 +6282,15 @@
     SC = SC_None;
   }
 
+  if (unsigned TypeQuals = D.getDeclSpec().getTypeQualifiers()) {
+    diagnoseIgnoredQualifiers(
+        diag::err_constructor_return_type, TypeQuals, SourceLocation(),
+        D.getDeclSpec().getConstSpecLoc(), D.getDeclSpec().getVolatileSpecLoc(),
+        D.getDeclSpec().getRestrictSpecLoc(),
+        D.getDeclSpec().getAtomicSpecLoc());
+    D.setInvalidType();
+  }
+
   DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
   if (FTI.TypeQuals != 0) {
     if (FTI.TypeQuals & Qualifiers::Const)
@@ -6104,14 +6318,14 @@
   // case any of the errors above fired) and with "void" as the
   // return type, since constructors don't have return types.
   const FunctionProtoType *Proto = R->getAs<FunctionProtoType>();
-  if (Proto->getResultType() == Context.VoidTy && !D.isInvalidType())
+  if (Proto->getReturnType() == Context.VoidTy && !D.isInvalidType())
     return R;
 
   FunctionProtoType::ExtProtoInfo EPI = Proto->getExtProtoInfo();
   EPI.TypeQuals = 0;
   EPI.RefQualifier = RQ_None;
-  
-  return Context.getFunctionType(Context.VoidTy, Proto->getArgTypes(), EPI);
+
+  return Context.getFunctionType(Context.VoidTy, Proto->getParamTypes(), EPI);
 }
 
 /// CheckConstructor - Checks a fully-formed constructor for
@@ -6166,11 +6380,15 @@
       Loc = RD->getLocation();
     
     // If we have a virtual destructor, look up the deallocation function
-    FunctionDecl *OperatorDelete = 0;
+    FunctionDecl *OperatorDelete = nullptr;
     DeclarationName Name = 
     Context.DeclarationNames.getCXXOperatorName(OO_Delete);
     if (FindDeallocationFunction(Loc, RD, Name, OperatorDelete))
       return true;
+    // If there's no class-specific operator delete, look up the global
+    // non-array delete.
+    if (!OperatorDelete)
+      OperatorDelete = FindUsualDeallocationFunction(Loc, true, Name);
 
     MarkFunctionReferenced(Loc, OperatorDelete);
     
@@ -6180,13 +6398,6 @@
   return false;
 }
 
-static inline bool
-FTIHasSingleVoidArgument(DeclaratorChunk::FunctionTypeInfo &FTI) {
-  return (FTI.NumArgs == 1 && !FTI.isVariadic && FTI.ArgInfo[0].Ident == 0 &&
-          FTI.ArgInfo[0].Param &&
-          cast<ParmVarDecl>(FTI.ArgInfo[0].Param)->getType()->isVoidType());
-}
-
 /// CheckDestructorDeclarator - Called by ActOnDeclarator to check
 /// the well-formednes of the destructor declarator @p D with type @p
 /// R. If there are any errors in the declarator, this routine will
@@ -6227,7 +6438,7 @@
     
     SC = SC_None;
   }
-  if (D.getDeclSpec().hasTypeSpecifier() && !D.isInvalidType()) {
+  if (!D.isInvalidType()) {
     // Destructors don't have return types, but the parser will
     // happily parse something like:
     //
@@ -6236,9 +6447,19 @@
     //   };
     //
     // The return type will be eliminated later.
-    Diag(D.getIdentifierLoc(), diag::err_destructor_return_type)
-      << SourceRange(D.getDeclSpec().getTypeSpecTypeLoc())
-      << SourceRange(D.getIdentifierLoc());
+    if (D.getDeclSpec().hasTypeSpecifier())
+      Diag(D.getIdentifierLoc(), diag::err_destructor_return_type)
+        << SourceRange(D.getDeclSpec().getTypeSpecTypeLoc())
+        << SourceRange(D.getIdentifierLoc());
+    else if (unsigned TypeQuals = D.getDeclSpec().getTypeQualifiers()) {
+      diagnoseIgnoredQualifiers(diag::err_destructor_return_type, TypeQuals,
+                                SourceLocation(),
+                                D.getDeclSpec().getConstSpecLoc(),
+                                D.getDeclSpec().getVolatileSpecLoc(),
+                                D.getDeclSpec().getRestrictSpecLoc(),
+                                D.getDeclSpec().getAtomicSpecLoc());
+      D.setInvalidType();
+    }
   }
 
   DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
@@ -6265,11 +6486,11 @@
   }
   
   // Make sure we don't have any parameters.
-  if (FTI.NumArgs > 0 && !FTIHasSingleVoidArgument(FTI)) {
+  if (FTIHasNonVoidParameters(FTI)) {
     Diag(D.getIdentifierLoc(), diag::err_destructor_with_params);
 
     // Delete the parameters.
-    FTI.freeArgs();
+    FTI.freeParams();
     D.setInvalidType();
   }
 
@@ -6335,11 +6556,11 @@
   const FunctionProtoType *Proto = R->getAs<FunctionProtoType>();
 
   // Make sure we don't have any parameters.
-  if (Proto->getNumArgs() > 0) {
+  if (Proto->getNumParams() > 0) {
     Diag(D.getIdentifierLoc(), diag::err_conv_function_with_params);
 
     // Delete the parameters.
-    D.getFunctionTypeInfo().freeArgs();
+    D.getFunctionTypeInfo().freeParams();
     D.setInvalidType();
   } else if (Proto->isVariadic()) {
     Diag(D.getIdentifierLoc(), diag::err_conv_function_variadic);
@@ -6348,11 +6569,11 @@
 
   // Diagnose "&operator bool()" and other such nonsense.  This
   // is actually a gcc extension which we don't support.
-  if (Proto->getResultType() != ConvType) {
+  if (Proto->getReturnType() != ConvType) {
     Diag(D.getIdentifierLoc(), diag::err_conv_function_with_complex_decl)
-      << Proto->getResultType();
+        << Proto->getReturnType();
     D.setInvalidType();
-    ConvType = Proto->getResultType();
+    ConvType = Proto->getReturnType();
   }
 
   // C++ [class.conv.fct]p4:
@@ -6456,9 +6677,8 @@
       NS->setInline(*IsInline);
     // Patch up the lookup table for the containing namespace. This isn't really
     // correct, but it's good enough for this particular case.
-    for (DeclContext::decl_iterator I = PrevNS->decls_begin(),
-                                    E = PrevNS->decls_end(); I != E; ++I)
-      if (NamedDecl *ND = dyn_cast<NamedDecl>(*I))
+    for (auto *I : PrevNS->decls())
+      if (auto *ND = dyn_cast<NamedDecl>(I))
         PrevNS->getParent()->makeDeclVisibleInContext(ND);
     return;
   }
@@ -6469,8 +6689,7 @@
     S.Diag(Loc, diag::warn_inline_namespace_reopened_noninline)
       << FixItHint::CreateInsertion(KeywordLoc, "inline ");
   else
-    S.Diag(Loc, diag::err_inline_namespace_mismatch)
-      << IsInline;
+    S.Diag(Loc, diag::err_inline_namespace_mismatch) << *IsInline;
 
   S.Diag(PrevNS->getLocation(), diag::note_previous_definition);
   *IsInline = PrevNS->isInline();
@@ -6494,7 +6713,7 @@
   bool AddToKnown = false;
   Scope *DeclRegionScope = NamespcScope->getParent();
 
-  NamespaceDecl *PrevNS = 0;
+  NamespaceDecl *PrevNS = nullptr;
   if (II) {
     // C++ [namespace.def]p2:
     //   The identifier in an original-namespace-definition shall not
@@ -6510,7 +6729,7 @@
     const unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_Member | 
     Decl::IDNS_Type | Decl::IDNS_Using | Decl::IDNS_Tag | 
     Decl::IDNS_Namespace;
-    NamedDecl *PrevDecl = 0;
+    NamedDecl *PrevDecl = nullptr;
     DeclContext::lookup_result R = CurContext->getRedeclContext()->lookup(II);
     for (DeclContext::lookup_iterator I = R.begin(), E = R.end(); I != E;
          ++I) {
@@ -6671,7 +6890,7 @@
                                          /*Inline=*/false,
                                          SourceLocation(), SourceLocation(),
                                          &PP.getIdentifierTable().get("std"),
-                                         /*PrevDecl=*/0);
+                                         /*PrevDecl=*/nullptr);
     getStdNamespace()->setImplicit(true);
   }
   
@@ -6688,8 +6907,8 @@
   if (!StdNamespace) // If we haven't seen namespace std yet, this can't be it.
     return false;
 
-  ClassTemplateDecl *Template = 0;
-  const TemplateArgument *Arguments = 0;
+  ClassTemplateDecl *Template = nullptr;
+  const TemplateArgument *Arguments = nullptr;
 
   if (const RecordType *RT = Ty->getAs<RecordType>()) {
 
@@ -6742,14 +6961,14 @@
   NamespaceDecl *Std = S.getStdNamespace();
   if (!Std) {
     S.Diag(Loc, diag::err_implied_std_initializer_list_not_found);
-    return 0;
+    return nullptr;
   }
 
   LookupResult Result(S, &S.PP.getIdentifierTable().get("initializer_list"),
                       Loc, Sema::LookupOrdinaryName);
   if (!S.LookupQualifiedName(Result, Std)) {
     S.Diag(Loc, diag::err_implied_std_initializer_list_not_found);
-    return 0;
+    return nullptr;
   }
   ClassTemplateDecl *Template = Result.getAsSingle<ClassTemplateDecl>();
   if (!Template) {
@@ -6757,7 +6976,7 @@
     // We found something weird. Complain about the first thing we found.
     NamedDecl *Found = *Result.begin();
     S.Diag(Found->getLocation(), diag::err_malformed_std_initializer_list);
-    return 0;
+    return nullptr;
   }
 
   // We found some template called std::initializer_list. Now verify that it's
@@ -6766,7 +6985,7 @@
   if (Params->getMinRequiredArguments() != 1 ||
       !isa<TemplateTypeParmDecl>(Params->getParam(0))) {
     S.Diag(Template->getLocation(), diag::err_malformed_std_initializer_list);
-    return 0;
+    return nullptr;
   }
 
   return Template;
@@ -6801,7 +7020,7 @@
   if (const ReferenceType *RT = ArgType->getAs<ReferenceType>())
     ArgType = RT->getPointeeType().getUnqualifiedType();
 
-  return isStdInitializerList(ArgType, 0);
+  return isStdInitializerList(ArgType, nullptr);
 }
 
 /// \brief Determine whether a using statement is in a context where it will be
@@ -6822,7 +7041,7 @@
 // Callback to only accept typo corrections that are namespaces.
 class NamespaceValidatorCCC : public CorrectionCandidateCallback {
 public:
-  bool ValidateCandidate(const TypoCorrection &candidate) LLVM_OVERRIDE {
+  bool ValidateCandidate(const TypoCorrection &candidate) override {
     if (NamedDecl *ND = candidate.getCorrectionDecl())
       return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
     return false;
@@ -6839,7 +7058,8 @@
   R.clear();
   if (TypoCorrection Corrected = S.CorrectTypo(R.getLookupNameInfo(),
                                                R.getLookupKind(), Sc, &SS,
-                                               Validator)) {
+                                               Validator,
+                                               Sema::CTK_ErrorRecovery)) {
     if (DeclContext *DC = S.computeDeclContext(SS, false)) {
       std::string CorrectedStr(Corrected.getAsString(S.getLangOpts()));
       bool DroppedSpecifier = Corrected.WillReplaceSpecifier() &&
@@ -6875,16 +7095,16 @@
     S = S->getParent();
   assert(S->getFlags() & Scope::DeclScope && "Invalid Scope.");
 
-  UsingDirectiveDecl *UDir = 0;
-  NestedNameSpecifier *Qualifier = 0;
+  UsingDirectiveDecl *UDir = nullptr;
+  NestedNameSpecifier *Qualifier = nullptr;
   if (SS.isSet())
-    Qualifier = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
+    Qualifier = SS.getScopeRep();
   
   // Lookup namespace name.
   LookupResult R(*this, NamespcName, IdentLoc, LookupNamespaceName);
   LookupParsedName(R, S, &SS);
   if (R.isAmbiguous())
-    return 0;
+    return nullptr;
 
   if (R.empty()) {
     R.clear();
@@ -6949,7 +7169,7 @@
   if (Ctx && !Ctx->isFunctionOrMethod())
     Ctx->addDecl(UDir);
   else
-    // Otherwise, it is at block sope. The using-directives will affect lookup
+    // Otherwise, it is at block scope. The using-directives will affect lookup
     // only to the end of the scope.
     S->PushUsingDirective(UDir);
 }
@@ -6985,23 +7205,23 @@
 
     if (getLangOpts().CPlusPlus11) break;
 
-    return 0;
-      
+    return nullptr;
+
   case UnqualifiedId::IK_DestructorName:
     Diag(Name.getLocStart(), diag::err_using_decl_destructor)
       << SS.getRange();
-    return 0;
-      
+    return nullptr;
+
   case UnqualifiedId::IK_TemplateId:
     Diag(Name.getLocStart(), diag::err_using_decl_template_id)
       << SourceRange(Name.TemplateId->LAngleLoc, Name.TemplateId->RAngleLoc);
-    return 0;
+    return nullptr;
   }
 
   DeclarationNameInfo TargetNameInfo = GetNameFromUnqualifiedId(Name);
   DeclarationName TargetName = TargetNameInfo.getName();
   if (!TargetName)
-    return 0;
+    return nullptr;
 
   // Warn about access declarations.
   if (!HasUsingKeyword) {
@@ -7013,7 +7233,7 @@
 
   if (DiagnoseUnexpandedParameterPack(SS, UPPC_UsingDeclaration) ||
       DiagnoseUnexpandedParameterPack(TargetNameInfo, UPPC_UsingDeclaration))
-    return 0;
+    return nullptr;
 
   NamedDecl *UD = BuildUsingDeclaration(S, AS, UsingLoc, SS,
                                         TargetNameInfo, AttrList,
@@ -7105,7 +7325,7 @@
   // 
   // FIXME: but we might be increasing its access, in which case we
   // should redeclare it.
-  NamedDecl *NonTag = 0, *Tag = 0;
+  NamedDecl *NonTag = nullptr, *Tag = nullptr;
   bool FoundEquivalentDecl = false;
   for (LookupResult::iterator I = Previous.begin(), E = Previous.end();
          I != E; ++I) {
@@ -7122,22 +7342,17 @@
   if (FoundEquivalentDecl)
     return false;
 
-  if (Target->isFunctionOrFunctionTemplate()) {
-    FunctionDecl *FD;
-    if (isa<FunctionTemplateDecl>(Target))
-      FD = cast<FunctionTemplateDecl>(Target)->getTemplatedDecl();
-    else
-      FD = cast<FunctionDecl>(Target);
-
-    NamedDecl *OldDecl = 0;
-    switch (CheckOverload(0, FD, Previous, OldDecl, /*IsForUsingDecl*/ true)) {
+  if (FunctionDecl *FD = Target->getAsFunction()) {
+    NamedDecl *OldDecl = nullptr;
+    switch (CheckOverload(nullptr, FD, Previous, OldDecl,
+                          /*IsForUsingDecl*/ true)) {
     case Ovl_Overload:
       return false;
 
     case Ovl_NonFunction:
       Diag(Using->getLocation(), diag::err_using_decl_conflict);
       break;
-      
+
     // We found a decl with the exact signature.
     case Ovl_Match:
       // If we're in a record, we want to hide the target, so we
@@ -7258,29 +7473,80 @@
   // be possible for this to happen, because...?
 }
 
+/// Find the base specifier for a base class with the given type.
+static CXXBaseSpecifier *findDirectBaseWithType(CXXRecordDecl *Derived,
+                                                QualType DesiredBase,
+                                                bool &AnyDependentBases) {
+  // Check whether the named type is a direct base class.
+  CanQualType CanonicalDesiredBase = DesiredBase->getCanonicalTypeUnqualified();
+  for (auto &Base : Derived->bases()) {
+    CanQualType BaseType = Base.getType()->getCanonicalTypeUnqualified();
+    if (CanonicalDesiredBase == BaseType)
+      return &Base;
+    if (BaseType->isDependentType())
+      AnyDependentBases = true;
+  }
+  return nullptr;
+}
+
 namespace {
 class UsingValidatorCCC : public CorrectionCandidateCallback {
 public:
   UsingValidatorCCC(bool HasTypenameKeyword, bool IsInstantiation,
-                    bool RequireMember)
+                    NestedNameSpecifier *NNS, CXXRecordDecl *RequireMemberOf)
       : HasTypenameKeyword(HasTypenameKeyword),
-        IsInstantiation(IsInstantiation), RequireMember(RequireMember) {}
+        IsInstantiation(IsInstantiation), OldNNS(NNS),
+        RequireMemberOf(RequireMemberOf) {}
 
-  bool ValidateCandidate(const TypoCorrection &Candidate) LLVM_OVERRIDE {
+  bool ValidateCandidate(const TypoCorrection &Candidate) override {
     NamedDecl *ND = Candidate.getCorrectionDecl();
 
     // Keywords are not valid here.
     if (!ND || isa<NamespaceDecl>(ND))
       return false;
 
-    if (RequireMember && !isa<FieldDecl>(ND) && !isa<CXXMethodDecl>(ND) &&
-        !isa<TypeDecl>(ND))
-      return false;
-
     // Completely unqualified names are invalid for a 'using' declaration.
     if (Candidate.WillReplaceSpecifier() && !Candidate.getCorrectionSpecifier())
       return false;
 
+    if (RequireMemberOf) {
+      auto *FoundRecord = dyn_cast<CXXRecordDecl>(ND);
+      if (FoundRecord && FoundRecord->isInjectedClassName()) {
+        // No-one ever wants a using-declaration to name an injected-class-name
+        // of a base class, unless they're declaring an inheriting constructor.
+        ASTContext &Ctx = ND->getASTContext();
+        if (!Ctx.getLangOpts().CPlusPlus11)
+          return false;
+        QualType FoundType = Ctx.getRecordType(FoundRecord);
+
+        // Check that the injected-class-name is named as a member of its own
+        // type; we don't want to suggest 'using Derived::Base;', since that
+        // means something else.
+        NestedNameSpecifier *Specifier =
+            Candidate.WillReplaceSpecifier()
+                ? Candidate.getCorrectionSpecifier()
+                : OldNNS;
+        if (!Specifier->getAsType() ||
+            !Ctx.hasSameType(QualType(Specifier->getAsType(), 0), FoundType))
+          return false;
+
+        // Check that this inheriting constructor declaration actually names a
+        // direct base class of the current class.
+        bool AnyDependentBases = false;
+        if (!findDirectBaseWithType(RequireMemberOf,
+                                    Ctx.getRecordType(FoundRecord),
+                                    AnyDependentBases) &&
+            !AnyDependentBases)
+          return false;
+      } else {
+        auto *RD = dyn_cast<CXXRecordDecl>(ND->getDeclContext());
+        if (!RD || RequireMemberOf->isProvablyNotDerivedFrom(RD))
+          return false;
+
+        // FIXME: Check that the base class member is accessible?
+      }
+    }
+
     if (isa<TypeDecl>(ND))
       return HasTypenameKeyword || !IsInstantiation;
 
@@ -7290,7 +7556,8 @@
 private:
   bool HasTypenameKeyword;
   bool IsInstantiation;
-  bool RequireMember;
+  NestedNameSpecifier *OldNNS;
+  CXXRecordDecl *RequireMemberOf;
 };
 } // end anonymous namespace
 
@@ -7302,7 +7569,7 @@
 NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
                                        SourceLocation UsingLoc,
                                        CXXScopeSpec &SS,
-                                       const DeclarationNameInfo &NameInfo,
+                                       DeclarationNameInfo NameInfo,
                                        AttributeList *AttrList,
                                        bool IsInstantiation,
                                        bool HasTypenameKeyword,
@@ -7315,7 +7582,7 @@
 
   if (SS.isEmpty()) {
     Diag(IdentLoc, diag::err_using_requires_qualname);
-    return 0;
+    return nullptr;
   }
 
   // Do the redeclaration lookup in the current scope.
@@ -7331,6 +7598,13 @@
       NamedDecl *D = F.next();
       if (!isDeclInScope(D, CurContext, S))
         F.erase();
+      // If we found a local extern declaration that's not ordinarily visible,
+      // and this declaration is being added to a non-block scope, ignore it.
+      // We're only checking for scope conflicts here, not also for violations
+      // of the linkage rules.
+      else if (!CurContext->isFunctionOrMethod() && D->isLocalExternDecl() &&
+               !(D->getIdentifierNamespace() & Decl::IDNS_Ordinary))
+        F.erase();
     }
     F.done();
   } else {
@@ -7342,11 +7616,11 @@
   // Check for invalid redeclarations.
   if (CheckUsingDeclRedeclaration(UsingLoc, HasTypenameKeyword,
                                   SS, IdentLoc, Previous))
-    return 0;
+    return nullptr;
 
   // Check for bad qualifiers.
-  if (CheckUsingDeclQualifier(UsingLoc, SS, IdentLoc))
-    return 0;
+  if (CheckUsingDeclQualifier(UsingLoc, SS, NameInfo, IdentLoc))
+    return nullptr;
 
   DeclContext *LookupContext = computeDeclContext(SS);
   NamedDecl *D;
@@ -7362,25 +7636,30 @@
       D = UnresolvedUsingValueDecl::Create(Context, CurContext, UsingLoc, 
                                            QualifierLoc, NameInfo);
     }
-  } else {
-    D = UsingDecl::Create(Context, CurContext, UsingLoc, QualifierLoc,
-                          NameInfo, HasTypenameKeyword);
+    D->setAccess(AS);
+    CurContext->addDecl(D);
+    return D;
   }
-  D->setAccess(AS);
-  CurContext->addDecl(D);
 
-  if (!LookupContext) return D;
-  UsingDecl *UD = cast<UsingDecl>(D);
-
-  if (RequireCompleteDeclContext(SS, LookupContext)) {
-    UD->setInvalidDecl();
+  auto Build = [&](bool Invalid) {
+    UsingDecl *UD =
+        UsingDecl::Create(Context, CurContext, UsingLoc, QualifierLoc, NameInfo,
+                          HasTypenameKeyword);
+    UD->setAccess(AS);
+    CurContext->addDecl(UD);
+    UD->setInvalidDecl(Invalid);
     return UD;
-  }
+  };
+  auto BuildInvalid = [&]{ return Build(true); };
+  auto BuildValid = [&]{ return Build(false); };
+
+  if (RequireCompleteDeclContext(SS, LookupContext))
+    return BuildInvalid();
 
   // The normal rules do not apply to inheriting constructor declarations.
   if (NameInfo.getName().getNameKind() == DeclarationName::CXXConstructorName) {
-    if (CheckInheritingConstructorUsingDecl(UD))
-      UD->setInvalidDecl();
+    UsingDecl *UD = BuildValid();
+    CheckInheritingConstructorUsingDecl(UD);
     return UD;
   }
 
@@ -7406,31 +7685,53 @@
 
   // Try to correct typos if possible.
   if (R.empty()) {
-    UsingValidatorCCC CCC(HasTypenameKeyword, IsInstantiation,
-                          CurContext->isRecord());
+    UsingValidatorCCC CCC(HasTypenameKeyword, IsInstantiation, SS.getScopeRep(),
+                          dyn_cast<CXXRecordDecl>(CurContext));
     if (TypoCorrection Corrected = CorrectTypo(R.getLookupNameInfo(),
-                                               R.getLookupKind(), S, &SS, CCC)){
+                                               R.getLookupKind(), S, &SS, CCC,
+                                               CTK_ErrorRecovery)){
       // We reject any correction for which ND would be NULL.
       NamedDecl *ND = Corrected.getCorrectionDecl();
-      R.setLookupName(Corrected.getCorrection());
-      R.addDecl(ND);
+
       // 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 corrected to an inheriting constructor, handle it as one.
+      auto *RD = dyn_cast<CXXRecordDecl>(ND);
+      if (RD && RD->isInjectedClassName()) {
+        // Fix up the information we'll use to build the using declaration.
+        if (Corrected.WillReplaceSpecifier()) {
+          NestedNameSpecifierLocBuilder Builder;
+          Builder.MakeTrivial(Context, Corrected.getCorrectionSpecifier(),
+                              QualifierLoc.getSourceRange());
+          QualifierLoc = Builder.getWithLocInContext(Context);
+        }
+
+        NameInfo.setName(Context.DeclarationNames.getCXXConstructorName(
+            Context.getCanonicalType(Context.getRecordType(RD))));
+        NameInfo.setNamedTypeInfo(nullptr);
+
+        // Build it and process it as an inheriting constructor.
+        UsingDecl *UD = BuildValid();
+        CheckInheritingConstructorUsingDecl(UD);
+        return UD;
+      }
+
+      // FIXME: Pick up all the declarations if we found an overloaded function.
+      R.setLookupName(Corrected.getCorrection());
+      R.addDecl(ND);
     } else {
       Diag(IdentLoc, diag::err_no_member)
         << NameInfo.getName() << LookupContext << SS.getRange();
-      UD->setInvalidDecl();
-      return UD;
+      return BuildInvalid();
     }
   }
 
-  if (R.isAmbiguous()) {
-    UD->setInvalidDecl();
-    return UD;
-  }
+  if (R.isAmbiguous())
+    return BuildInvalid();
 
   if (HasTypenameKeyword) {
     // If we asked for a typename and got a non-type decl, error out.
@@ -7439,8 +7740,7 @@
       for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I)
         Diag((*I)->getUnderlyingDecl()->getLocation(),
              diag::note_using_decl_target);
-      UD->setInvalidDecl();
-      return UD;
+      return BuildInvalid();
     }
   } else {
     // If we asked for a non-typename and we got a type, error out,
@@ -7449,8 +7749,7 @@
     if (IsInstantiation && R.getAsSingle<TypeDecl>()) {
       Diag(IdentLoc, diag::err_using_dependent_value_is_type);
       Diag(R.getFoundDecl()->getLocation(), diag::note_using_decl_target);
-      UD->setInvalidDecl();
-      return UD;
+      return BuildInvalid();
     }
   }
 
@@ -7459,12 +7758,12 @@
   if (R.getAsSingle<NamespaceDecl>()) {
     Diag(IdentLoc, diag::err_using_decl_can_not_refer_to_namespace)
       << SS.getRange();
-    UD->setInvalidDecl();
-    return UD;
+    return BuildInvalid();
   }
 
+  UsingDecl *UD = BuildValid();
   for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {
-    UsingShadowDecl *PrevDecl = 0;
+    UsingShadowDecl *PrevDecl = nullptr;
     if (!CheckUsingShadowDecl(UD, *I, Previous, PrevDecl))
       BuildUsingShadowDecl(S, UD, *I, PrevDecl);
   }
@@ -7482,28 +7781,20 @@
   CXXRecordDecl *TargetClass = cast<CXXRecordDecl>(CurContext);
 
   // Check whether the named type is a direct base class.
-  CanQualType CanonicalSourceType = SourceType->getCanonicalTypeUnqualified();
-  CXXRecordDecl::base_class_iterator BaseIt, BaseE;
-  for (BaseIt = TargetClass->bases_begin(), BaseE = TargetClass->bases_end();
-       BaseIt != BaseE; ++BaseIt) {
-    CanQualType BaseType = BaseIt->getType()->getCanonicalTypeUnqualified();
-    if (CanonicalSourceType == BaseType)
-      break;
-    if (BaseIt->getType()->isDependentType())
-      break;
-  }
-
-  if (BaseIt == BaseE) {
-    // Did not find SourceType in the bases.
+  bool AnyDependentBases = false;
+  auto *Base = findDirectBaseWithType(TargetClass, QualType(SourceType, 0),
+                                      AnyDependentBases);
+  if (!Base && !AnyDependentBases) {
     Diag(UD->getUsingLoc(),
          diag::err_using_decl_constructor_not_in_direct_base)
       << UD->getNameInfo().getSourceRange()
       << QualType(SourceType, 0) << TargetClass;
+    UD->setInvalidDecl();
     return true;
   }
 
-  if (!CurContext->isDependentContext())
-    BaseIt->setInheritConstructors();
+  if (Base)
+    Base->setInheritConstructors();
 
   return false;
 }
@@ -7526,8 +7817,7 @@
   if (!CurContext->getRedeclContext()->isRecord())
     return false;
 
-  NestedNameSpecifier *Qual
-    = static_cast<NestedNameSpecifier*>(SS.getScopeRep());
+  NestedNameSpecifier *Qual = SS.getScopeRep();
 
   for (LookupResult::iterator I = Prev.begin(), E = Prev.end(); I != E; ++I) {
     NamedDecl *D = *I;
@@ -7572,6 +7862,7 @@
 /// scope.  If an error is found, diagnoses it and returns true.
 bool Sema::CheckUsingDeclQualifier(SourceLocation UsingLoc,
                                    const CXXScopeSpec &SS,
+                                   const DeclarationNameInfo &NameInfo,
                                    SourceLocation NameLoc) {
   DeclContext *NamedContext = computeDeclContext(SS);
 
@@ -7583,8 +7874,56 @@
     // If we weren't able to compute a valid scope, it must be a
     // dependent class scope.
     if (!NamedContext || NamedContext->isRecord()) {
+      auto *RD = dyn_cast<CXXRecordDecl>(NamedContext);
+      if (RD && RequireCompleteDeclContext(const_cast<CXXScopeSpec&>(SS), RD))
+        RD = nullptr;
+
       Diag(NameLoc, diag::err_using_decl_can_not_refer_to_class_member)
         << SS.getRange();
+
+      // If we have a complete, non-dependent source type, try to suggest a
+      // way to get the same effect.
+      if (!RD)
+        return true;
+
+      // Find what this using-declaration was referring to.
+      LookupResult R(*this, NameInfo, LookupOrdinaryName);
+      R.setHideTags(false);
+      R.suppressDiagnostics();
+      LookupQualifiedName(R, RD);
+
+      if (R.getAsSingle<TypeDecl>()) {
+        if (getLangOpts().CPlusPlus11) {
+          // Convert 'using X::Y;' to 'using Y = X::Y;'.
+          Diag(SS.getBeginLoc(), diag::note_using_decl_class_member_workaround)
+            << 0 // alias declaration
+            << FixItHint::CreateInsertion(SS.getBeginLoc(),
+                                          NameInfo.getName().getAsString() +
+                                              " = ");
+        } else {
+          // Convert 'using X::Y;' to 'typedef X::Y Y;'.
+          SourceLocation InsertLoc =
+              PP.getLocForEndOfToken(NameInfo.getLocEnd());
+          Diag(InsertLoc, diag::note_using_decl_class_member_workaround)
+            << 1 // typedef declaration
+            << FixItHint::CreateReplacement(UsingLoc, "typedef")
+            << FixItHint::CreateInsertion(
+                   InsertLoc, " " + NameInfo.getName().getAsString());
+        }
+      } else if (R.getAsSingle<VarDecl>()) {
+        // Don't provide a fixit outside C++11 mode; we don't want to suggest
+        // repeating the type of the static data member here.
+        FixItHint FixIt;
+        if (getLangOpts().CPlusPlus11) {
+          // Convert 'using X::Y;' to 'auto &Y = X::Y;'.
+          FixIt = FixItHint::CreateReplacement(
+              UsingLoc, "auto &" + NameInfo.getName().getAsString() + " = ");
+        }
+
+        Diag(UsingLoc, diag::note_using_decl_class_member_workaround)
+          << 2 // reference declaration
+          << FixIt;
+      }
       return true;
     }
 
@@ -7610,7 +7949,7 @@
     // but we don't have that level of source info.
     Diag(SS.getRange().getBegin(),
          diag::err_using_decl_nested_name_specifier_is_not_class)
-      << (NestedNameSpecifier*) SS.getScopeRep() << SS.getRange();
+      << SS.getScopeRep() << SS.getRange();
     return true;
   }
 
@@ -7635,7 +7974,7 @@
 
       Diag(SS.getRange().getBegin(),
            diag::err_using_decl_nested_name_specifier_is_not_base_class)
-        << (NestedNameSpecifier*) SS.getScopeRep()
+        << SS.getScopeRep()
         << cast<CXXRecordDecl>(CurContext)
         << SS.getRange();
       return true;
@@ -7695,7 +8034,7 @@
 
   Diag(SS.getRange().getBegin(),
        diag::err_using_decl_nested_name_specifier_is_not_base_class)
-    << (NestedNameSpecifier*) SS.getScopeRep()
+    << SS.getScopeRep()
     << cast<CXXRecordDecl>(CurContext)
     << SS.getRange();
 
@@ -7716,15 +8055,15 @@
          "got alias-declaration outside of declaration scope");
 
   if (Type.isInvalid())
-    return 0;
+    return nullptr;
 
   bool Invalid = false;
   DeclarationNameInfo NameInfo = GetNameFromUnqualifiedId(Name);
-  TypeSourceInfo *TInfo = 0;
+  TypeSourceInfo *TInfo = nullptr;
   GetTypeFromParser(Type.get(), &TInfo);
 
   if (DiagnoseClassNameShadow(CurContext, NameInfo))
-    return 0;
+    return nullptr;
 
   if (DiagnoseUnexpandedParameterPack(Name.StartLocation, TInfo,
                                       UPPC_DeclarationType)) {
@@ -7763,8 +8102,8 @@
 
   NamedDecl *NewND;
   if (TemplateParamLists.size()) {
-    TypeAliasTemplateDecl *OldDecl = 0;
-    TemplateParameterList *OldTemplateParams = 0;
+    TypeAliasTemplateDecl *OldDecl = nullptr;
+    TemplateParameterList *OldTemplateParams = nullptr;
 
     if (TemplateParamLists.size() != 1) {
       Diag(UsingLoc, diag::err_alias_template_extra_headers)
@@ -7819,7 +8158,7 @@
     // and check the parameter list.
     if (CheckTemplateParameterList(TemplateParams, OldTemplateParams,
                                    TPC_TypeAliasTemplate))
-      return 0;
+      return nullptr;
 
     TypeAliasTemplateDecl *NewDecl =
       TypeAliasTemplateDecl::Create(Context, CurContext, UsingLoc,
@@ -7863,7 +8202,7 @@
     = LookupSingleName(S, Alias, AliasLoc, LookupOrdinaryName, 
                        ForRedeclaration);
   if (PrevDecl && !isDeclInScope(PrevDecl, CurContext, S))
-    PrevDecl = 0;
+    PrevDecl = nullptr;
 
   if (PrevDecl) {
     if (NamespaceAliasDecl *AD = dyn_cast<NamespaceAliasDecl>(PrevDecl)) {
@@ -7873,23 +8212,23 @@
       // declaration to maintain better source information.
       if (!R.isAmbiguous() && !R.empty() &&
           AD->getNamespace()->Equals(getNamespaceDecl(R.getFoundDecl())))
-        return 0;
+        return nullptr;
     }
 
     unsigned DiagID = isa<NamespaceDecl>(PrevDecl) ? diag::err_redefinition :
       diag::err_redefinition_different_kind;
     Diag(AliasLoc, DiagID) << Alias;
     Diag(PrevDecl->getLocation(), diag::note_previous_definition);
-    return 0;
+    return nullptr;
   }
 
   if (R.isAmbiguous())
-    return 0;
+    return nullptr;
 
   if (R.empty()) {
     if (!TryNamespaceTypoCorrection(*this, R, S, SS, IdentLoc, Ident)) {
       Diag(IdentLoc, diag::err_expected_namespace_name) << SS.getRange();
-      return 0;
+      return nullptr;
     }
   }
 
@@ -7915,40 +8254,34 @@
     return ExceptSpec;
 
   // Direct base-class constructors.
-  for (CXXRecordDecl::base_class_iterator B = ClassDecl->bases_begin(),
-                                       BEnd = ClassDecl->bases_end();
-       B != BEnd; ++B) {
-    if (B->isVirtual()) // Handled below.
+  for (const auto &B : ClassDecl->bases()) {
+    if (B.isVirtual()) // Handled below.
       continue;
     
-    if (const RecordType *BaseType = B->getType()->getAs<RecordType>()) {
+    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);
+        ExceptSpec.CalledDecl(B.getLocStart(), Constructor);
     }
   }
 
   // Virtual base-class constructors.
-  for (CXXRecordDecl::base_class_iterator B = ClassDecl->vbases_begin(),
-                                       BEnd = ClassDecl->vbases_end();
-       B != BEnd; ++B) {
-    if (const RecordType *BaseType = B->getType()->getAs<RecordType>()) {
+  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);
+        ExceptSpec.CalledDecl(B.getLocStart(), Constructor);
     }
   }
 
   // Field constructors.
-  for (RecordDecl::field_iterator F = ClassDecl->field_begin(),
-                               FEnd = ClassDecl->field_end();
-       F != FEnd; ++F) {
+  for (const auto *F : ClassDecl->fields()) {
     if (F->hasInClassInitializer()) {
       if (Expr *E = F->getInClassInitializer())
         ExceptSpec.CalledExpr(E);
@@ -8004,40 +8337,34 @@
   ExceptSpec.CalledDecl(CD->getLocStart(), InheritedCD);
 
   // Direct base-class constructors.
-  for (CXXRecordDecl::base_class_iterator B = ClassDecl->bases_begin(),
-                                       BEnd = ClassDecl->bases_end();
-       B != BEnd; ++B) {
-    if (B->isVirtual()) // Handled below.
+  for (const auto &B : ClassDecl->bases()) {
+    if (B.isVirtual()) // Handled below.
       continue;
 
-    if (const RecordType *BaseType = B->getType()->getAs<RecordType>()) {
+    if (const RecordType *BaseType = B.getType()->getAs<RecordType>()) {
       CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseType->getDecl());
       if (BaseClassDecl == InheritedDecl)
         continue;
       CXXConstructorDecl *Constructor = LookupDefaultConstructor(BaseClassDecl);
       if (Constructor)
-        ExceptSpec.CalledDecl(B->getLocStart(), Constructor);
+        ExceptSpec.CalledDecl(B.getLocStart(), Constructor);
     }
   }
 
   // Virtual base-class constructors.
-  for (CXXRecordDecl::base_class_iterator B = ClassDecl->vbases_begin(),
-                                       BEnd = ClassDecl->vbases_end();
-       B != BEnd; ++B) {
-    if (const RecordType *BaseType = B->getType()->getAs<RecordType>()) {
+  for (const auto &B : ClassDecl->vbases()) {
+    if (const RecordType *BaseType = B.getType()->getAs<RecordType>()) {
       CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseType->getDecl());
       if (BaseClassDecl == InheritedDecl)
         continue;
       CXXConstructorDecl *Constructor = LookupDefaultConstructor(BaseClassDecl);
       if (Constructor)
-        ExceptSpec.CalledDecl(B->getLocStart(), Constructor);
+        ExceptSpec.CalledDecl(B.getLocStart(), Constructor);
     }
   }
 
   // Field constructors.
-  for (RecordDecl::field_iterator F = ClassDecl->field_begin(),
-                               FEnd = ClassDecl->field_end();
-       F != FEnd; ++F) {
+  for (const auto *F : ClassDecl->fields()) {
     if (F->hasInClassInitializer()) {
       if (Expr *E = F->getInClassInitializer())
         ExceptSpec.CalledExpr(E);
@@ -8099,7 +8426,7 @@
 
   DeclaringSpecialMember DSM(*this, ClassDecl, CXXDefaultConstructor);
   if (DSM.isAlreadyBeingDeclared())
-    return 0;
+    return nullptr;
 
   bool Constexpr = defaultedSpecialMemberIsConstexpr(*this, ClassDecl,
                                                      CXXDefaultConstructor,
@@ -8113,9 +8440,9 @@
     = Context.DeclarationNames.getCXXConstructorName(ClassType);
   DeclarationNameInfo NameInfo(Name, ClassLoc);
   CXXConstructorDecl *DefaultCon = CXXConstructorDecl::Create(
-      Context, ClassDecl, ClassLoc, NameInfo, /*Type*/QualType(), /*TInfo=*/0,
-      /*isExplicit=*/false, /*isInline=*/true, /*isImplicitlyDeclared=*/true,
-      Constexpr);
+      Context, ClassDecl, ClassLoc, NameInfo, /*Type*/QualType(),
+      /*TInfo=*/nullptr, /*isExplicit=*/false, /*isInline=*/true,
+      /*isImplicitlyDeclared=*/true, Constexpr);
   DefaultCon->setAccess(AS_public);
   DefaultCon->setDefaulted();
   DefaultCon->setImplicit();
@@ -8161,7 +8488,9 @@
     return;
   }
 
-  SourceLocation Loc = Constructor->getLocation();
+  SourceLocation Loc = Constructor->getLocEnd().isValid()
+                           ? Constructor->getLocEnd()
+                           : Constructor->getLocation();
   Constructor->setBody(new (Context) CompoundStmt(Loc));
 
   Constructor->markUsed(Context);
@@ -8201,7 +8530,7 @@
   /// Information about an inheriting constructor.
   struct InheritingConstructor {
     InheritingConstructor()
-      : DeclaredInDerived(false), BaseCtor(0), DerivedCtor(0) {}
+      : DeclaredInDerived(false), BaseCtor(nullptr), DerivedCtor(nullptr) {}
 
     /// If \c true, a constructor with this signature is already declared
     /// in the derived class.
@@ -8248,10 +8577,8 @@
 
   /// Process all constructors for a class.
   void visitAll(const CXXRecordDecl *RD, VisitFn Callback) {
-    for (CXXRecordDecl::ctor_iterator CtorIt = RD->ctor_begin(),
-                                      CtorE = RD->ctor_end();
-         CtorIt != CtorE; ++CtorIt)
-      (this->*Callback)(*CtorIt);
+    for (const auto *Ctor : RD->ctors())
+      (this->*Callback)(Ctor);
     for (CXXRecordDecl::specific_decl_iterator<FunctionTemplateDecl>
              I(RD->decls_begin()), E(RD->decls_end());
          I != E; ++I) {
@@ -8270,7 +8597,7 @@
   void inherit(const CXXConstructorDecl *Ctor) {
     const FunctionProtoType *CtorType =
         Ctor->getType()->castAs<FunctionProtoType>();
-    ArrayRef<QualType> ArgTypes(CtorType->getArgTypes());
+    ArrayRef<QualType> ArgTypes(CtorType->getParamTypes());
     FunctionProtoType::ExtProtoInfo EPI = CtorType->getExtProtoInfo();
 
     SourceLocation UsingLoc = getUsingLoc(Ctor->getParent());
@@ -8298,7 +8625,7 @@
       do
         declareCtor(UsingLoc, Ctor,
                     SemaRef.Context.getFunctionType(
-                        Ctor->getResultType(), ArgTypes.slice(0, Params), EPI));
+                        Ctor->getReturnType(), ArgTypes.slice(0, Params), EPI));
       while (Params > MinParams &&
              Ctor->getParamDecl(--Params)->hasDefaultArg());
     }
@@ -8384,7 +8711,7 @@
         Context.getCanonicalType(Context.getRecordType(Derived)));
     DeclarationNameInfo NameInfo(Name, UsingLoc);
 
-    TemplateParameterList *TemplateParams = 0;
+    TemplateParameterList *TemplateParams = nullptr;
     if (const FunctionTemplateDecl *FTD =
             BaseCtor->getDescribedFunctionTemplate()) {
       TemplateParams = FTD->getTemplateParameters();
@@ -8412,21 +8739,21 @@
     FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
     EPI.ExceptionSpecType = EST_Unevaluated;
     EPI.ExceptionSpecDecl = DerivedCtor;
-    DerivedCtor->setType(Context.getFunctionType(FPT->getResultType(),
-                                                 FPT->getArgTypes(), EPI));
+    DerivedCtor->setType(Context.getFunctionType(FPT->getReturnType(),
+                                                 FPT->getParamTypes(), EPI));
 
     // Build the parameter declarations.
     SmallVector<ParmVarDecl *, 16> ParamDecls;
-    for (unsigned I = 0, N = FPT->getNumArgs(); I != N; ++I) {
+    for (unsigned I = 0, N = FPT->getNumParams(); I != N; ++I) {
       TypeSourceInfo *TInfo =
-          Context.getTrivialTypeSourceInfo(FPT->getArgType(I), UsingLoc);
+          Context.getTrivialTypeSourceInfo(FPT->getParamType(I), UsingLoc);
       ParmVarDecl *PD = ParmVarDecl::Create(
-          Context, DerivedCtor, UsingLoc, UsingLoc, /*IdentifierInfo=*/0,
-          FPT->getArgType(I), TInfo, SC_None, /*DefaultArg=*/0);
+          Context, DerivedCtor, UsingLoc, UsingLoc, /*IdentifierInfo=*/nullptr,
+          FPT->getParamType(I), TInfo, SC_None, /*DefaultArg=*/nullptr);
       PD->setScopeInfo(0, I);
       PD->setImplicit();
       ParamDecls.push_back(PD);
-      ProtoLoc.setArg(I, PD);
+      ProtoLoc.setParam(I, PD);
     }
 
     // Set up the new constructor.
@@ -8467,11 +8794,9 @@
 
   // Find base classes from which we might inherit constructors.
   SmallVector<CXXRecordDecl*, 4> InheritedBases;
-  for (CXXRecordDecl::base_class_iterator BaseIt = ClassDecl->bases_begin(),
-                                          BaseE = ClassDecl->bases_end();
-       BaseIt != BaseE; ++BaseIt)
-    if (BaseIt->getInheritConstructors())
-      InheritedBases.push_back(BaseIt->getType()->getAsCXXRecordDecl());
+  for (const auto &BaseIt : ClassDecl->bases())
+    if (BaseIt.getInheritConstructors())
+      InheritedBases.push_back(BaseIt.getType()->getAsCXXRecordDecl());
 
   // Go no further if we're not inheriting any constructors.
   if (InheritedBases.empty())
@@ -8524,30 +8849,24 @@
     return ExceptSpec;
 
   // Direct base-class destructors.
-  for (CXXRecordDecl::base_class_iterator B = ClassDecl->bases_begin(),
-                                       BEnd = ClassDecl->bases_end();
-       B != BEnd; ++B) {
-    if (B->isVirtual()) // Handled below.
+  for (const auto &B : ClassDecl->bases()) {
+    if (B.isVirtual()) // Handled below.
       continue;
     
-    if (const RecordType *BaseType = B->getType()->getAs<RecordType>())
-      ExceptSpec.CalledDecl(B->getLocStart(),
+    if (const RecordType *BaseType = B.getType()->getAs<RecordType>())
+      ExceptSpec.CalledDecl(B.getLocStart(),
                    LookupDestructor(cast<CXXRecordDecl>(BaseType->getDecl())));
   }
 
   // Virtual base-class destructors.
-  for (CXXRecordDecl::base_class_iterator B = ClassDecl->vbases_begin(),
-                                       BEnd = ClassDecl->vbases_end();
-       B != BEnd; ++B) {
-    if (const RecordType *BaseType = B->getType()->getAs<RecordType>())
-      ExceptSpec.CalledDecl(B->getLocStart(),
+  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 (RecordDecl::field_iterator F = ClassDecl->field_begin(),
-                               FEnd = ClassDecl->field_end();
-       F != FEnd; ++F) {
+  for (const auto *F : ClassDecl->fields()) {
     if (const RecordType *RecordTy
         = Context.getBaseElementType(F->getType())->getAs<RecordType>())
       ExceptSpec.CalledDecl(F->getLocation(),
@@ -8566,7 +8885,7 @@
 
   DeclaringSpecialMember DSM(*this, ClassDecl, CXXDestructor);
   if (DSM.isAlreadyBeingDeclared())
-    return 0;
+    return nullptr;
 
   // Create the actual destructor declaration.
   CanQualType ClassType
@@ -8577,7 +8896,7 @@
   DeclarationNameInfo NameInfo(Name, ClassLoc);
   CXXDestructorDecl *Destructor
       = CXXDestructorDecl::Create(Context, ClassDecl, ClassLoc, NameInfo,
-                                  QualType(), 0, /*isInline=*/true,
+                                  QualType(), nullptr, /*isInline=*/true,
                                   /*isImplicitlyDeclared=*/true);
   Destructor->setAccess(AS_public);
   Destructor->setDefaulted();
@@ -8633,7 +8952,9 @@
     return;
   }
 
-  SourceLocation Loc = Destructor->getLocation();
+  SourceLocation Loc = Destructor->getLocEnd().isValid()
+                           ? Destructor->getLocEnd()
+                           : Destructor->getLocation();
   Destructor->setBody(new (Context) CompoundStmt(Loc));
   Destructor->markUsed(Context);
   MarkVTableUsed(CurrentLocation, ClassDecl);
@@ -8711,8 +9032,8 @@
   QualType VarType;
 
 public:
-  virtual Expr *build(Sema &S, SourceLocation Loc) const LLVM_OVERRIDE {
-    return assertNotNull(S.BuildDeclRefExpr(Var, VarType, VK_LValue, Loc).take());
+  virtual Expr *build(Sema &S, SourceLocation Loc) const override {
+    return assertNotNull(S.BuildDeclRefExpr(Var, VarType, VK_LValue, Loc).get());
   }
 
   RefBuilder(VarDecl *Var, QualType VarType)
@@ -8721,8 +9042,8 @@
 
 class ThisBuilder: public ExprBuilder {
 public:
-  virtual Expr *build(Sema &S, SourceLocation Loc) const LLVM_OVERRIDE {
-    return assertNotNull(S.ActOnCXXThis(Loc).takeAs<Expr>());
+  virtual Expr *build(Sema &S, SourceLocation Loc) const override {
+    return assertNotNull(S.ActOnCXXThis(Loc).getAs<Expr>());
   }
 };
 
@@ -8733,10 +9054,10 @@
   const CXXCastPath &Path;
 
 public:
-  virtual Expr *build(Sema &S, SourceLocation Loc) const LLVM_OVERRIDE {
+  virtual Expr *build(Sema &S, SourceLocation Loc) const override {
     return assertNotNull(S.ImpCastExprToType(Builder.build(S, Loc), Type,
                                              CK_UncheckedDerivedToBase, Kind,
-                                             &Path).take());
+                                             &Path).get());
   }
 
   CastBuilder(const ExprBuilder &Builder, QualType Type, ExprValueKind Kind,
@@ -8748,9 +9069,9 @@
   const ExprBuilder &Builder;
 
 public:
-  virtual Expr *build(Sema &S, SourceLocation Loc) const LLVM_OVERRIDE {
+  virtual Expr *build(Sema &S, SourceLocation Loc) const override {
     return assertNotNull(
-        S.CreateBuiltinUnaryOp(Loc, UO_Deref, Builder.build(S, Loc)).take());
+        S.CreateBuiltinUnaryOp(Loc, UO_Deref, Builder.build(S, Loc)).get());
   }
 
   DerefBuilder(const ExprBuilder &Builder) : Builder(Builder) {}
@@ -8764,10 +9085,10 @@
   LookupResult &MemberLookup;
 
 public:
-  virtual Expr *build(Sema &S, SourceLocation Loc) const LLVM_OVERRIDE {
+  virtual Expr *build(Sema &S, SourceLocation Loc) const override {
     return assertNotNull(S.BuildMemberReferenceExpr(
-        Builder.build(S, Loc), Type, Loc, IsArrow, SS, SourceLocation(), 0,
-        MemberLookup, 0).take());
+        Builder.build(S, Loc), Type, Loc, IsArrow, SS, SourceLocation(),
+        nullptr, MemberLookup, nullptr).get());
   }
 
   MemberBuilder(const ExprBuilder &Builder, QualType Type, bool IsArrow,
@@ -8780,7 +9101,7 @@
   const ExprBuilder &Builder;
 
 public:
-  virtual Expr *build(Sema &S, SourceLocation Loc) const LLVM_OVERRIDE {
+  virtual Expr *build(Sema &S, SourceLocation Loc) const override {
     return assertNotNull(CastForMoving(S, Builder.build(S, Loc)));
   }
 
@@ -8791,9 +9112,9 @@
   const ExprBuilder &Builder;
 
 public:
-  virtual Expr *build(Sema &S, SourceLocation Loc) const LLVM_OVERRIDE {
+  virtual Expr *build(Sema &S, SourceLocation Loc) const override {
     return assertNotNull(
-        S.DefaultLvalueConversion(Builder.build(S, Loc)).take());
+        S.DefaultLvalueConversion(Builder.build(S, Loc)).get());
   }
 
   LvalueConvBuilder(const ExprBuilder &Builder) : Builder(Builder) {}
@@ -8804,10 +9125,9 @@
   const ExprBuilder &Index;
 
 public:
-  virtual Expr *build(Sema &S, SourceLocation Loc) const
-      LLVM_OVERRIDE {
+  virtual Expr *build(Sema &S, SourceLocation Loc) const override {
     return assertNotNull(S.CreateBuiltinArraySubscriptExpr(
-        Base.build(S, Loc), Loc, Index.build(S, Loc), Loc).take());
+        Base.build(S, Loc), Loc, Index.build(S, Loc), Loc).get());
   }
 
   SubscriptBuilder(const ExprBuilder &Base, const ExprBuilder &Index)
@@ -8859,17 +9179,17 @@
     return StmtError();
 
   ExprResult MemCpyRef = S.BuildDeclRefExpr(MemCpy, S.Context.BuiltinFnTy,
-                                            VK_RValue, Loc, 0);
+                                            VK_RValue, Loc, nullptr);
   assert(MemCpyRef.isUsable() && "Builtin reference cannot fail");
 
   Expr *CallArgs[] = {
     To, From, IntegerLiteral::Create(S.Context, Size, SizeType, Loc)
   };
-  ExprResult Call = S.ActOnCallExpr(/*Scope=*/0, MemCpyRef.take(),
+  ExprResult Call = S.ActOnCallExpr(/*Scope=*/nullptr, MemCpyRef.get(),
                                     Loc, CallArgs, Loc);
 
   assert(!Call.isInvalid() && "Call to __builtin_memcpy cannot fail!");
-  return S.Owned(Call.takeAs<Stmt>());
+  return Call.getAs<Stmt>();
 }
 
 /// \brief Builds a statement that copies/moves the given entity from \p From to
@@ -8968,7 +9288,7 @@
     CXXScopeSpec SS;
     const Type *CanonicalT = S.Context.getCanonicalType(T.getTypePtr());
     SS.MakeTrivial(S.Context,
-                   NestedNameSpecifier::Create(S.Context, 0, false,
+                   NestedNameSpecifier::Create(S.Context, nullptr, false,
                                                CanonicalT),
                    Loc);
 
@@ -8976,9 +9296,9 @@
     ExprResult OpEqualRef
       = S.BuildMemberReferenceExpr(To.build(S, Loc), T, Loc, /*isArrow=*/false,
                                    SS, /*TemplateKWLoc=*/SourceLocation(),
-                                   /*FirstQualifierInScope=*/0,
+                                   /*FirstQualifierInScope=*/nullptr,
                                    OpLookup,
-                                   /*TemplateArgs=*/0,
+                                   /*TemplateArgs=*/nullptr,
                                    /*SuppressQualifierCheck=*/true);
     if (OpEqualRef.isInvalid())
       return StmtError();
@@ -8986,8 +9306,8 @@
     // Build the call to the assignment operator.
 
     Expr *FromInst = From.build(S, Loc);
-    ExprResult Call = S.BuildCallToMemberFunction(/*Scope=*/0,
-                                                  OpEqualRef.takeAs<Expr>(),
+    ExprResult Call = S.BuildCallToMemberFunction(/*Scope=*/nullptr,
+                                                  OpEqualRef.getAs<Expr>(),
                                                   Loc, FromInst, Loc);
     if (Call.isInvalid())
       return StmtError();
@@ -8996,7 +9316,7 @@
     // bail out. We'll replace the whole shebang with a memcpy.
     CXXMemberCallExpr *CE = dyn_cast<CXXMemberCallExpr>(Call.get());
     if (CE && CE->getMethodDecl()->isTrivial() && Depth)
-      return StmtResult((Stmt*)0);
+      return StmtResult((Stmt*)nullptr);
 
     // Convert to an expression-statement, and clean up any produced
     // temporaries.
@@ -9025,7 +9345,7 @@
   QualType SizeType = S.Context.getSizeType();
 
   // Create the iteration variable.
-  IdentifierInfo *IterationVarName = 0;
+  IdentifierInfo *IterationVarName = nullptr;
   {
     SmallString<8> Str;
     llvm::raw_svector_ostream OS(Str);
@@ -9085,8 +9405,8 @@
   // Construct the loop that copies all elements of this array.
   return S.ActOnForStmt(Loc, Loc, InitStmt, 
                         S.MakeFullExpr(Comparison),
-                        0, S.MakeFullDiscardedValueExpr(Increment),
-                        Loc, Copy.take());
+                        nullptr, S.MakeFullDiscardedValueExpr(Increment),
+                        Loc, Copy.get());
 }
 
 static StmtResult
@@ -9119,8 +9439,9 @@
     return ExceptSpec;
 
   const FunctionProtoType *T = MD->getType()->castAs<FunctionProtoType>();
-  assert(T->getNumArgs() == 1 && "not a copy assignment op");
-  unsigned ArgQuals = T->getArgType(0).getNonReferenceType().getCVRQualifiers();
+  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
@@ -9132,33 +9453,26 @@
   // 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 (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
-                                       BaseEnd = ClassDecl->bases_end();
-       Base != BaseEnd; ++Base) {
-    if (Base->isVirtual())
+  for (const auto &Base : ClassDecl->bases()) {
+    if (Base.isVirtual())
       continue;
 
     CXXRecordDecl *BaseClassDecl
-      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+      = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
     if (CXXMethodDecl *CopyAssign = LookupCopyingAssignment(BaseClassDecl,
                                                             ArgQuals, false, 0))
-      ExceptSpec.CalledDecl(Base->getLocStart(), CopyAssign);
+      ExceptSpec.CalledDecl(Base.getLocStart(), CopyAssign);
   }
 
-  for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
-                                       BaseEnd = ClassDecl->vbases_end();
-       Base != BaseEnd; ++Base) {
+  for (const auto &Base : ClassDecl->vbases()) {
     CXXRecordDecl *BaseClassDecl
-      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+      = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
     if (CXXMethodDecl *CopyAssign = LookupCopyingAssignment(BaseClassDecl,
                                                             ArgQuals, false, 0))
-      ExceptSpec.CalledDecl(Base->getLocStart(), CopyAssign);
+      ExceptSpec.CalledDecl(Base.getLocStart(), CopyAssign);
   }
 
-  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
-                                  FieldEnd = ClassDecl->field_end();
-       Field != FieldEnd;
-       ++Field) {
+  for (const auto *Field : ClassDecl->fields()) {
     QualType FieldType = Context.getBaseElementType(Field->getType());
     if (CXXRecordDecl *FieldClassDecl = FieldType->getAsCXXRecordDecl()) {
       if (CXXMethodDecl *CopyAssign =
@@ -9181,7 +9495,7 @@
 
   DeclaringSpecialMember DSM(*this, ClassDecl, CXXCopyAssignment);
   if (DSM.isAlreadyBeingDeclared())
-    return 0;
+    return nullptr;
 
   QualType ArgType = Context.getTypeDeclType(ClassDecl);
   QualType RetType = Context.getLValueReferenceType(ArgType);
@@ -9201,8 +9515,8 @@
   DeclarationNameInfo NameInfo(Name, ClassLoc);
   CXXMethodDecl *CopyAssignment =
       CXXMethodDecl::Create(Context, ClassDecl, ClassLoc, NameInfo, QualType(),
-                            /*TInfo=*/ 0, /*StorageClass=*/ SC_None,
-                            /*isInline=*/ true, Constexpr, SourceLocation());
+                            /*TInfo=*/nullptr, /*StorageClass=*/SC_None,
+                            /*isInline=*/true, Constexpr, SourceLocation());
   CopyAssignment->setAccess(AS_public);
   CopyAssignment->setDefaulted();
   CopyAssignment->setImplicit();
@@ -9214,9 +9528,10 @@
 
   // Add the parameter to the operator.
   ParmVarDecl *FromParam = ParmVarDecl::Create(Context, CopyAssignment,
-                                               ClassLoc, ClassLoc, /*Id=*/0,
-                                               ArgType, /*TInfo=*/0,
-                                               SC_None, 0);
+                                               ClassLoc, ClassLoc,
+                                               /*Id=*/nullptr, ArgType,
+                                               /*TInfo=*/nullptr, SC_None,
+                                               nullptr);
   CopyAssignment->setParams(FromParam);
 
   AddOverriddenMethods(ClassDecl, CopyAssignment);
@@ -9247,7 +9562,7 @@
   assert(CopyOp->isImplicit());
 
   CXXRecordDecl *RD = CopyOp->getParent();
-  CXXMethodDecl *UserDeclaredOperation = 0;
+  CXXMethodDecl *UserDeclaredOperation = nullptr;
 
   // In Microsoft mode, assignment operations don't affect constructors and
   // vice versa.
@@ -9255,24 +9570,22 @@
     UserDeclaredOperation = RD->getDestructor();
   } else if (!isa<CXXConstructorDecl>(CopyOp) &&
              RD->hasUserDeclaredCopyConstructor() &&
-             !S.getLangOpts().MicrosoftMode) {
+             !S.getLangOpts().MSVCCompat) {
     // Find any user-declared copy constructor.
-    for (CXXRecordDecl::ctor_iterator I = RD->ctor_begin(),
-                                      E = RD->ctor_end(); I != E; ++I) {
+    for (auto *I : RD->ctors()) {
       if (I->isCopyConstructor()) {
-        UserDeclaredOperation = *I;
+        UserDeclaredOperation = I;
         break;
       }
     }
     assert(UserDeclaredOperation);
   } else if (isa<CXXConstructorDecl>(CopyOp) &&
              RD->hasUserDeclaredCopyAssignment() &&
-             !S.getLangOpts().MicrosoftMode) {
+             !S.getLangOpts().MSVCCompat) {
     // Find any user-declared move assignment operator.
-    for (CXXRecordDecl::method_iterator I = RD->method_begin(),
-                                        E = RD->method_end(); I != E; ++I) {
+    for (auto *I : RD->methods()) {
       if (I->isCopyAssignmentOperator()) {
-        UserDeclaredOperation = *I;
+        UserDeclaredOperation = I;
         break;
       }
     }
@@ -9341,8 +9654,10 @@
   }
   
   // Our location for everything implicitly-generated.
-  SourceLocation Loc = CopyAssignOperator->getLocation();
-  
+  SourceLocation Loc = CopyAssignOperator->getLocEnd().isValid()
+                           ? CopyAssignOperator->getLocEnd()
+                           : CopyAssignOperator->getLocation();
+
   // Builds a DeclRefExpr for the "other" object.
   RefBuilder OtherRef(Other, OtherRefType);
 
@@ -9351,18 +9666,17 @@
   
   // Assign base classes.
   bool Invalid = false;
-  for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
-       E = ClassDecl->bases_end(); Base != E; ++Base) {
+  for (auto &Base : ClassDecl->bases()) {
     // Form the assignment:
     //   static_cast<Base*>(this)->Base::operator=(static_cast<Base&>(other));
-    QualType BaseType = Base->getType().getUnqualifiedType();
+    QualType BaseType = Base.getType().getUnqualifiedType();
     if (!BaseType->isRecordType()) {
       Invalid = true;
       continue;
     }
 
     CXXCastPath BasePath;
-    BasePath.push_back(Base);
+    BasePath.push_back(&Base);
 
     // Construct the "from" expression, which is an implicit cast to the
     // appropriately-qualified base type.
@@ -9389,13 +9703,11 @@
     }
     
     // Success! Record the copy.
-    Statements.push_back(Copy.takeAs<Expr>());
+    Statements.push_back(Copy.getAs<Expr>());
   }
   
   // Assign non-static members.
-  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
-                                  FieldEnd = ClassDecl->field_end(); 
-       Field != FieldEnd; ++Field) {
+  for (auto *Field : ClassDecl->fields()) {
     if (Field->isUnnamedBitfield())
       continue;
 
@@ -9442,7 +9754,7 @@
     CXXScopeSpec SS; // Intentionally empty
     LookupResult MemberLookup(*this, Field->getDeclName(), Loc,
                               LookupMemberName);
-    MemberLookup.addDecl(*Field);
+    MemberLookup.addDecl(Field);
     MemberLookup.resolveKind();
 
     MemberBuilder From(OtherRef, OtherRefType, /*IsArrow=*/false, MemberLookup);
@@ -9462,18 +9774,18 @@
     }
     
     // Success! Record the copy.
-    Statements.push_back(Copy.takeAs<Stmt>());
+    Statements.push_back(Copy.getAs<Stmt>());
   }
 
   if (!Invalid) {
     // Add a "return *this;"
     ExprResult ThisObj = CreateBuiltinUnaryOp(Loc, UO_Deref, This.build(*this, Loc));
     
-    StmtResult Return = ActOnReturnStmt(Loc, ThisObj.get());
+    StmtResult Return = BuildReturnStmt(Loc, ThisObj.get());
     if (Return.isInvalid())
       Invalid = true;
     else {
-      Statements.push_back(Return.takeAs<Stmt>());
+      Statements.push_back(Return.getAs<Stmt>());
 
       if (Trap.hasErrorOccurred()) {
         Diag(CurrentLocation, diag::note_member_synthesized_at) 
@@ -9495,7 +9807,7 @@
                              /*isStmtExpr=*/false);
     assert(!Body.isInvalid() && "Compound statement creation cannot fail");
   }
-  CopyAssignOperator->setBody(Body.takeAs<Stmt>());
+  CopyAssignOperator->setBody(Body.getAs<Stmt>());
 
   if (ASTMutationListener *L = getASTMutationListener()) {
     L->CompletedImplicitDefinition(CopyAssignOperator);
@@ -9522,33 +9834,26 @@
   // 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 (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
-                                       BaseEnd = ClassDecl->bases_end();
-       Base != BaseEnd; ++Base) {
-    if (Base->isVirtual())
+  for (const auto &Base : ClassDecl->bases()) {
+    if (Base.isVirtual())
       continue;
 
     CXXRecordDecl *BaseClassDecl
-      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+      = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
     if (CXXMethodDecl *MoveAssign = LookupMovingAssignment(BaseClassDecl,
                                                            0, false, 0))
-      ExceptSpec.CalledDecl(Base->getLocStart(), MoveAssign);
+      ExceptSpec.CalledDecl(Base.getLocStart(), MoveAssign);
   }
 
-  for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
-                                       BaseEnd = ClassDecl->vbases_end();
-       Base != BaseEnd; ++Base) {
+  for (const auto &Base : ClassDecl->vbases()) {
     CXXRecordDecl *BaseClassDecl
-      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+      = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
     if (CXXMethodDecl *MoveAssign = LookupMovingAssignment(BaseClassDecl,
                                                            0, false, 0))
-      ExceptSpec.CalledDecl(Base->getLocStart(), MoveAssign);
+      ExceptSpec.CalledDecl(Base.getLocStart(), MoveAssign);
   }
 
-  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
-                                  FieldEnd = ClassDecl->field_end();
-       Field != FieldEnd;
-       ++Field) {
+  for (const auto *Field : ClassDecl->fields()) {
     QualType FieldType = Context.getBaseElementType(Field->getType());
     if (CXXRecordDecl *FieldClassDecl = FieldType->getAsCXXRecordDecl()) {
       if (CXXMethodDecl *MoveAssign =
@@ -9567,7 +9872,7 @@
 
   DeclaringSpecialMember DSM(*this, ClassDecl, CXXMoveAssignment);
   if (DSM.isAlreadyBeingDeclared())
-    return 0;
+    return nullptr;
 
   // Note: The following rules are largely analoguous to the move
   // constructor rules.
@@ -9587,7 +9892,7 @@
   DeclarationNameInfo NameInfo(Name, ClassLoc);
   CXXMethodDecl *MoveAssignment =
       CXXMethodDecl::Create(Context, ClassDecl, ClassLoc, NameInfo, QualType(),
-                            /*TInfo=*/0, /*StorageClass=*/SC_None,
+                            /*TInfo=*/nullptr, /*StorageClass=*/SC_None,
                             /*isInline=*/true, Constexpr, SourceLocation());
   MoveAssignment->setAccess(AS_public);
   MoveAssignment->setDefaulted();
@@ -9600,9 +9905,10 @@
 
   // Add the parameter to the operator.
   ParmVarDecl *FromParam = ParmVarDecl::Create(Context, MoveAssignment,
-                                               ClassLoc, ClassLoc, /*Id=*/0,
-                                               ArgType, /*TInfo=*/0,
-                                               SC_None, 0);
+                                               ClassLoc, ClassLoc,
+                                               /*Id=*/nullptr, ArgType,
+                                               /*TInfo=*/nullptr, SC_None,
+                                               nullptr);
   MoveAssignment->setParams(FromParam);
 
   AddOverriddenMethods(ClassDecl, MoveAssignment);
@@ -9646,10 +9952,8 @@
   typedef llvm::DenseMap<CXXRecordDecl*, CXXBaseSpecifier*> VBaseMap;
   VBaseMap VBases;
 
-  for (CXXRecordDecl::base_class_iterator BI = Class->bases_begin(),
-                                          BE = Class->bases_end();
-       BI != BE; ++BI) {
-    Worklist.push_back(&*BI);
+  for (auto &BI : Class->bases()) {
+    Worklist.push_back(&BI);
     while (!Worklist.empty()) {
       CXXBaseSpecifier *BaseSpec = Worklist.pop_back_val();
       CXXRecordDecl *Base = BaseSpec->getType()->getAsCXXRecordDecl();
@@ -9681,22 +9985,22 @@
         // only happens in one base, we'll diagnose it when synthesizing
         // that base class's move assignment operator.)
         CXXBaseSpecifier *&Existing =
-            VBases.insert(std::make_pair(Base->getCanonicalDecl(), BI))
+            VBases.insert(std::make_pair(Base->getCanonicalDecl(), &BI))
                 .first->second;
-        if (Existing && Existing != BI) {
+        if (Existing && Existing != &BI) {
           S.Diag(CurrentLocation, diag::warn_vbase_moved_multiple_times)
             << Class << Base;
           S.Diag(Existing->getLocStart(), diag::note_vbase_moved_here)
             << (Base->getCanonicalDecl() ==
                 Existing->getType()->getAsCXXRecordDecl()->getCanonicalDecl())
             << Base << Existing->getType() << Existing->getSourceRange();
-          S.Diag(BI->getLocStart(), diag::note_vbase_moved_here)
+          S.Diag(BI.getLocStart(), diag::note_vbase_moved_here)
             << (Base->getCanonicalDecl() ==
-                BI->getType()->getAsCXXRecordDecl()->getCanonicalDecl())
-            << Base << BI->getType() << BaseSpec->getSourceRange();
+                BI.getType()->getAsCXXRecordDecl()->getCanonicalDecl())
+            << Base << BI.getType() << BaseSpec->getSourceRange();
 
           // Only diagnose each vbase once.
-          Existing = 0;
+          Existing = nullptr;
         }
       } else {
         // Only walk over bases that have defaulted move assignment operators.
@@ -9706,10 +10010,8 @@
           continue;
 
         // We're going to move the base classes of Base. Add them to the list.
-        for (CXXRecordDecl::base_class_iterator BI = Base->bases_begin(),
-                                                BE = Base->bases_end();
-             BI != BE; ++BI)
-          Worklist.push_back(&*BI);
+        for (auto &BI : Base->bases())
+          Worklist.push_back(&BI);
       }
     }
   }
@@ -9759,7 +10061,9 @@
          "Bad argument type of defaulted move assignment");
 
   // Our location for everything implicitly-generated.
-  SourceLocation Loc = MoveAssignOperator->getLocation();
+  SourceLocation Loc = MoveAssignOperator->getLocEnd().isValid()
+                           ? MoveAssignOperator->getLocEnd()
+                           : MoveAssignOperator->getLocation();
 
   // Builds a reference to the "other" object.
   RefBuilder OtherRef(Other, OtherRefType);
@@ -9771,8 +10075,7 @@
 
   // Assign base classes.
   bool Invalid = false;
-  for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
-       E = ClassDecl->bases_end(); Base != E; ++Base) {
+  for (auto &Base : ClassDecl->bases()) {
     // C++11 [class.copy]p28:
     //   It is unspecified whether subobjects representing virtual base classes
     //   are assigned more than once by the implicitly-defined copy assignment
@@ -9783,14 +10086,14 @@
 
     // Form the assignment:
     //   static_cast<Base*>(this)->Base::operator=(static_cast<Base&&>(other));
-    QualType BaseType = Base->getType().getUnqualifiedType();
+    QualType BaseType = Base.getType().getUnqualifiedType();
     if (!BaseType->isRecordType()) {
       Invalid = true;
       continue;
     }
 
     CXXCastPath BasePath;
-    BasePath.push_back(Base);
+    BasePath.push_back(&Base);
 
     // Construct the "from" expression, which is an implicit cast to the
     // appropriately-qualified base type.
@@ -9818,13 +10121,11 @@
     }
 
     // Success! Record the move.
-    Statements.push_back(Move.takeAs<Expr>());
+    Statements.push_back(Move.getAs<Expr>());
   }
 
   // Assign non-static members.
-  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
-                                  FieldEnd = ClassDecl->field_end(); 
-       Field != FieldEnd; ++Field) {
+  for (auto *Field : ClassDecl->fields()) {
     if (Field->isUnnamedBitfield())
       continue;
 
@@ -9870,7 +10171,7 @@
     // Build references to the field in the object we're copying from and to.
     LookupResult MemberLookup(*this, Field->getDeclName(), Loc,
                               LookupMemberName);
-    MemberLookup.addDecl(*Field);
+    MemberLookup.addDecl(Field);
     MemberLookup.resolveKind();
     MemberBuilder From(MoveOther, OtherRefType,
                        /*IsArrow=*/false, MemberLookup);
@@ -9894,18 +10195,19 @@
     }
 
     // Success! Record the copy.
-    Statements.push_back(Move.takeAs<Stmt>());
+    Statements.push_back(Move.getAs<Stmt>());
   }
 
   if (!Invalid) {
     // Add a "return *this;"
-    ExprResult ThisObj = CreateBuiltinUnaryOp(Loc, UO_Deref, This.build(*this, Loc));
-    
-    StmtResult Return = ActOnReturnStmt(Loc, ThisObj.get());
+    ExprResult ThisObj =
+        CreateBuiltinUnaryOp(Loc, UO_Deref, This.build(*this, Loc));
+
+    StmtResult Return = BuildReturnStmt(Loc, ThisObj.get());
     if (Return.isInvalid())
       Invalid = true;
     else {
-      Statements.push_back(Return.takeAs<Stmt>());
+      Statements.push_back(Return.getAs<Stmt>());
 
       if (Trap.hasErrorOccurred()) {
         Diag(CurrentLocation, diag::note_member_synthesized_at) 
@@ -9927,7 +10229,7 @@
                              /*isStmtExpr=*/false);
     assert(!Body.isInvalid() && "Compound statement creation cannot fail");
   }
-  MoveAssignOperator->setBody(Body.takeAs<Stmt>());
+  MoveAssignOperator->setBody(Body.getAs<Stmt>());
 
   if (ASTMutationListener *L = getASTMutationListener()) {
     L->CompletedImplicitDefinition(MoveAssignOperator);
@@ -9943,40 +10245,31 @@
     return ExceptSpec;
 
   const FunctionProtoType *T = MD->getType()->castAs<FunctionProtoType>();
-  assert(T->getNumArgs() >= 1 && "not a copy ctor");
-  unsigned Quals = T->getArgType(0).getNonReferenceType().getCVRQualifiers();
+  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 (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
-                                       BaseEnd = ClassDecl->bases_end();
-       Base != BaseEnd; 
-       ++Base) {
+  for (const auto &Base : ClassDecl->bases()) {
     // Virtual bases are handled below.
-    if (Base->isVirtual())
+    if (Base.isVirtual())
       continue;
     
     CXXRecordDecl *BaseClassDecl
-      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+      = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
     if (CXXConstructorDecl *CopyConstructor =
           LookupCopyingConstructor(BaseClassDecl, Quals))
-      ExceptSpec.CalledDecl(Base->getLocStart(), CopyConstructor);
+      ExceptSpec.CalledDecl(Base.getLocStart(), CopyConstructor);
   }
-  for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
-                                       BaseEnd = ClassDecl->vbases_end();
-       Base != BaseEnd; 
-       ++Base) {
+  for (const auto &Base : ClassDecl->vbases()) {
     CXXRecordDecl *BaseClassDecl
-      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+      = cast<CXXRecordDecl>(Base.getType()->getAs<RecordType>()->getDecl());
     if (CXXConstructorDecl *CopyConstructor =
           LookupCopyingConstructor(BaseClassDecl, Quals))
-      ExceptSpec.CalledDecl(Base->getLocStart(), CopyConstructor);
+      ExceptSpec.CalledDecl(Base.getLocStart(), CopyConstructor);
   }
-  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
-                                  FieldEnd = ClassDecl->field_end();
-       Field != FieldEnd;
-       ++Field) {
+  for (const auto *Field : ClassDecl->fields()) {
     QualType FieldType = Context.getBaseElementType(Field->getType());
     if (CXXRecordDecl *FieldClassDecl = FieldType->getAsCXXRecordDecl()) {
       if (CXXConstructorDecl *CopyConstructor =
@@ -9998,7 +10291,7 @@
 
   DeclaringSpecialMember DSM(*this, ClassDecl, CXXCopyConstructor);
   if (DSM.isAlreadyBeingDeclared())
-    return 0;
+    return nullptr;
 
   QualType ClassType = Context.getTypeDeclType(ClassDecl);
   QualType ArgType = ClassType;
@@ -10020,7 +10313,7 @@
   //   An implicitly-declared copy constructor is an inline public
   //   member of its class.
   CXXConstructorDecl *CopyConstructor = CXXConstructorDecl::Create(
-      Context, ClassDecl, ClassLoc, NameInfo, QualType(), /*TInfo=*/0,
+      Context, ClassDecl, ClassLoc, NameInfo, QualType(), /*TInfo=*/nullptr,
       /*isExplicit=*/false, /*isInline=*/true, /*isImplicitlyDeclared=*/true,
       Constexpr);
   CopyConstructor->setAccess(AS_public);
@@ -10035,9 +10328,9 @@
   // Add the parameter to the constructor.
   ParmVarDecl *FromParam = ParmVarDecl::Create(Context, CopyConstructor,
                                                ClassLoc, ClassLoc,
-                                               /*IdentifierInfo=*/0,
-                                               ArgType, /*TInfo=*/0,
-                                               SC_None, 0);
+                                               /*IdentifierInfo=*/nullptr,
+                                               ArgType, /*TInfo=*/nullptr,
+                                               SC_None, nullptr);
   CopyConstructor->setParams(FromParam);
 
   CopyConstructor->setTrivial(
@@ -10085,13 +10378,17 @@
       << CXXCopyConstructor << Context.getTagDeclType(ClassDecl);
     CopyConstructor->setInvalidDecl();
   }  else {
+    SourceLocation Loc = CopyConstructor->getLocEnd().isValid()
+                             ? CopyConstructor->getLocEnd()
+                             : CopyConstructor->getLocation();
     Sema::CompoundScopeRAII CompoundScope(*this);
-    CopyConstructor->setBody(ActOnCompoundStmt(
-        CopyConstructor->getLocation(), CopyConstructor->getLocation(), None,
-        /*isStmtExpr=*/ false).takeAs<Stmt>());
+    CopyConstructor->setBody(
+        ActOnCompoundStmt(Loc, Loc, None, /*isStmtExpr=*/false).getAs<Stmt>());
   }
 
   CopyConstructor->markUsed(Context);
+  MarkVTableUsed(CurrentLocation, ClassDecl);
+
   if (ASTMutationListener *L = getASTMutationListener()) {
     L->CompletedImplicitDefinition(CopyConstructor);
   }
@@ -10109,42 +10406,36 @@
     return ExceptSpec;
 
   // Direct base-class constructors.
-  for (CXXRecordDecl::base_class_iterator B = ClassDecl->bases_begin(),
-                                       BEnd = ClassDecl->bases_end();
-       B != BEnd; ++B) {
-    if (B->isVirtual()) // Handled below.
+  for (const auto &B : ClassDecl->bases()) {
+    if (B.isVirtual()) // Handled below.
       continue;
     
-    if (const RecordType *BaseType = B->getType()->getAs<RecordType>()) {
+    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);
+        ExceptSpec.CalledDecl(B.getLocStart(), Constructor);
     }
   }
 
   // Virtual base-class constructors.
-  for (CXXRecordDecl::base_class_iterator B = ClassDecl->vbases_begin(),
-                                       BEnd = ClassDecl->vbases_end();
-       B != BEnd; ++B) {
-    if (const RecordType *BaseType = B->getType()->getAs<RecordType>()) {
+  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);
+        ExceptSpec.CalledDecl(B.getLocStart(), Constructor);
     }
   }
 
   // Field constructors.
-  for (RecordDecl::field_iterator F = ClassDecl->field_begin(),
-                               FEnd = ClassDecl->field_end();
-       F != FEnd; ++F) {
+  for (const auto *F : ClassDecl->fields()) {
     QualType FieldType = Context.getBaseElementType(F->getType());
     if (CXXRecordDecl *FieldRecDecl = FieldType->getAsCXXRecordDecl()) {
       CXXConstructorDecl *Constructor =
@@ -10168,7 +10459,7 @@
 
   DeclaringSpecialMember DSM(*this, ClassDecl, CXXMoveConstructor);
   if (DSM.isAlreadyBeingDeclared())
-    return 0;
+    return nullptr;
 
   QualType ClassType = Context.getTypeDeclType(ClassDecl);
   QualType ArgType = Context.getRValueReferenceType(ClassType);
@@ -10187,7 +10478,7 @@
   //   An implicitly-declared copy/move constructor is an inline public
   //   member of its class.
   CXXConstructorDecl *MoveConstructor = CXXConstructorDecl::Create(
-      Context, ClassDecl, ClassLoc, NameInfo, QualType(), /*TInfo=*/0,
+      Context, ClassDecl, ClassLoc, NameInfo, QualType(), /*TInfo=*/nullptr,
       /*isExplicit=*/false, /*isInline=*/true, /*isImplicitlyDeclared=*/true,
       Constexpr);
   MoveConstructor->setAccess(AS_public);
@@ -10202,9 +10493,9 @@
   // Add the parameter to the constructor.
   ParmVarDecl *FromParam = ParmVarDecl::Create(Context, MoveConstructor,
                                                ClassLoc, ClassLoc,
-                                               /*IdentifierInfo=*/0,
-                                               ArgType, /*TInfo=*/0,
-                                               SC_None, 0);
+                                               /*IdentifierInfo=*/nullptr,
+                                               ArgType, /*TInfo=*/nullptr,
+                                               SC_None, nullptr);
   MoveConstructor->setParams(FromParam);
 
   MoveConstructor->setTrivial(
@@ -10247,13 +10538,16 @@
       << CXXMoveConstructor << Context.getTagDeclType(ClassDecl);
     MoveConstructor->setInvalidDecl();
   }  else {
+    SourceLocation Loc = MoveConstructor->getLocEnd().isValid()
+                             ? MoveConstructor->getLocEnd()
+                             : MoveConstructor->getLocation();
     Sema::CompoundScopeRAII CompoundScope(*this);
     MoveConstructor->setBody(ActOnCompoundStmt(
-        MoveConstructor->getLocation(), MoveConstructor->getLocation(), None,
-        /*isStmtExpr=*/ false).takeAs<Stmt>());
+        Loc, Loc, None, /*isStmtExpr=*/ false).getAs<Stmt>());
   }
 
   MoveConstructor->markUsed(Context);
+  MarkVTableUsed(CurrentLocation, ClassDecl);
 
   if (ASTMutationListener *L = getASTMutationListener()) {
     L->CompletedImplicitDefinition(MoveConstructor);
@@ -10273,19 +10567,17 @@
   // cache the deduced template arguments for this specialization
   // so that we can use them to retrieve the corresponding call-operator
   // and static-invoker. 
-  const TemplateArgumentList *DeducedTemplateArgs = 0;
-   
-  
+  const TemplateArgumentList *DeducedTemplateArgs = nullptr;
+
   // Retrieve the corresponding call-operator specialization.
   if (Lambda->isGenericLambda()) {
     assert(Conv->isFunctionTemplateSpecialization());
     FunctionTemplateDecl *CallOpTemplate = 
         CallOp->getDescribedFunctionTemplate();
     DeducedTemplateArgs = Conv->getTemplateSpecializationArgs();
-    void *InsertPos = 0;
+    void *InsertPos = nullptr;
     FunctionDecl *CallOpSpec = CallOpTemplate->findSpecialization(
-                                                DeducedTemplateArgs->data(), 
-                                                DeducedTemplateArgs->size(), 
+                                                DeducedTemplateArgs->asArray(),
                                                 InsertPos);
     assert(CallOpSpec && 
           "Conversion operator must have a corresponding call operator");
@@ -10301,7 +10593,7 @@
   SynthesizedFunctionScope Scope(*this, Conv);
   DiagnosticErrorTrap Trap(Diags);
    
-  // Retreive the static invoker...
+  // Retrieve the static invoker...
   CXXMethodDecl *Invoker = Lambda->getLambdaStaticInvoker();
   // ... and get the corresponding specialization for a generic lambda.
   if (Lambda->isGenericLambda()) {
@@ -10309,10 +10601,9 @@
       "Must have deduced template arguments from Conversion Operator");
     FunctionTemplateDecl *InvokeTemplate = 
                           Invoker->getDescribedFunctionTemplate();
-    void *InsertPos = 0;
+    void *InsertPos = nullptr;
     FunctionDecl *InvokeSpec = InvokeTemplate->findSpecialization(
-                                                DeducedTemplateArgs->data(), 
-                                                DeducedTemplateArgs->size(), 
+                                                DeducedTemplateArgs->asArray(),
                                                 InsertPos);
     assert(InvokeSpec && 
       "Must have a corresponding static invoker specialization");
@@ -10320,9 +10611,9 @@
   }
   // Construct the body of the conversion function { return __invoke; }.
   Expr *FunctionRef = BuildDeclRefExpr(Invoker, Invoker->getType(),
-                                        VK_LValue, Conv->getLocation()).take();
+                                        VK_LValue, Conv->getLocation()).get();
    assert(FunctionRef && "Can't refer to __invoke function?");
-   Stmt *Return = ActOnReturnStmt(Conv->getLocation(), FunctionRef).take();
+   Stmt *Return = BuildReturnStmt(Conv->getLocation(), FunctionRef).get();
    Conv->setBody(new (Context) CompoundStmt(Context, Return,
                                             Conv->getLocation(),
                                             Conv->getLocation()));
@@ -10356,8 +10647,8 @@
   DiagnosticErrorTrap Trap(Diags);
   
   // Copy-initialize the lambda object as needed to capture it.
-  Expr *This = ActOnCXXThis(CurrentLocation).take();
-  Expr *DerefThis =CreateBuiltinUnaryOp(CurrentLocation, UO_Deref, This).take();
+  Expr *This = ActOnCXXThis(CurrentLocation).get();
+  Expr *DerefThis =CreateBuiltinUnaryOp(CurrentLocation, UO_Deref, This).get();
   
   ExprResult BuildBlock = BuildBlockForLambdaConversion(CurrentLocation,
                                                         Conv->getLocation(),
@@ -10370,7 +10661,7 @@
   if (!BuildBlock.isInvalid() && !getLangOpts().ObjCAutoRefCount)
     BuildBlock = ImplicitCastExpr::Create(Context, BuildBlock.get()->getType(),
                                           CK_CopyAndAutoreleaseBlockObject,
-                                          BuildBlock.get(), 0, VK_RValue);
+                                          BuildBlock.get(), nullptr, VK_RValue);
 
   if (BuildBlock.isInvalid()) {
     Diag(CurrentLocation, diag::note_lambda_to_block_conv);
@@ -10380,7 +10671,7 @@
 
   // Create the return statement that returns the block from the conversion
   // function.
-  StmtResult Return = ActOnReturnStmt(Conv->getLocation(), BuildBlock.get());
+  StmtResult Return = BuildReturnStmt(Conv->getLocation(), BuildBlock.get());
   if (Return.isInvalid()) {
     Diag(CurrentLocation, diag::note_lambda_to_block_conv);
     Conv->setInvalidDecl();
@@ -10388,7 +10679,7 @@
   }
 
   // Set the body of the conversion function.
-  Stmt *ReturnS = Return.take();
+  Stmt *ReturnS = Return.get();
   Conv->setBody(new (Context) CompoundStmt(Context, ReturnS,
                                            Conv->getLocation(), 
                                            Conv->getLocation()));
@@ -10424,6 +10715,7 @@
                             MultiExprArg ExprArgs,
                             bool HadMultipleCandidates,
                             bool IsListInitialization,
+                            bool IsStdInitListInitialization,
                             bool RequiresZeroInit,
                             unsigned ConstructKind,
                             SourceRange ParenRange) {
@@ -10447,7 +10739,8 @@
 
   return BuildCXXConstructExpr(ConstructLoc, DeclInitType, Constructor,
                                Elidable, ExprArgs, HadMultipleCandidates,
-                               IsListInitialization, RequiresZeroInit,
+                               IsListInitialization,
+                               IsStdInitListInitialization, RequiresZeroInit,
                                ConstructKind, ParenRange);
 }
 
@@ -10459,16 +10752,17 @@
                             MultiExprArg ExprArgs,
                             bool HadMultipleCandidates,
                             bool IsListInitialization,
+                            bool IsStdInitListInitialization,
                             bool RequiresZeroInit,
                             unsigned ConstructKind,
                             SourceRange ParenRange) {
   MarkFunctionReferenced(ConstructLoc, Constructor);
-  return Owned(CXXConstructExpr::Create(Context, DeclInitType, ConstructLoc,
-                                        Constructor, Elidable, ExprArgs,
-                                        HadMultipleCandidates,
-                                        IsListInitialization, RequiresZeroInit,
-              static_cast<CXXConstructExpr::ConstructionKind>(ConstructKind),
-                                        ParenRange));
+  return CXXConstructExpr::Create(
+      Context, DeclInitType, ConstructLoc, Constructor, Elidable, ExprArgs,
+      HadMultipleCandidates, IsListInitialization, IsStdInitListInitialization,
+      RequiresZeroInit,
+      static_cast<CXXConstructExpr::ConstructionKind>(ConstructKind),
+      ParenRange);
 }
 
 void Sema::FinalizeVarWithDestructor(VarDecl *VD, const RecordType *Record) {
@@ -10487,6 +10781,7 @@
                         << VD->getType());
   DiagnoseUseOfDecl(Destructor, VD->getLocation());
 
+  if (Destructor->isTrivial()) return;
   if (!VD->hasGlobalStorage()) return;
 
   // Emit warning for non-trivial dtor in global scope (a real global,
@@ -10517,11 +10812,11 @@
   const FunctionProtoType *Proto 
     = Constructor->getType()->getAs<FunctionProtoType>();
   assert(Proto && "Constructor without a prototype?");
-  unsigned NumArgsInProto = Proto->getNumArgs();
-  
+  unsigned NumParams = Proto->getNumParams();
+
   // If too few arguments are available, we'll fill in the rest with defaults.
-  if (NumArgs < NumArgsInProto)
-    ConvertedArgs.reserve(NumArgsInProto);
+  if (NumArgs < NumParams)
+    ConvertedArgs.reserve(NumParams);
   else
     ConvertedArgs.reserve(NumArgs);
 
@@ -10572,8 +10867,8 @@
                             CanQualType ExpectedFirstParamType,
                             unsigned DependentParamTypeDiag,
                             unsigned InvalidParamTypeDiag) {
-  QualType ResultType = 
-    FnDecl->getType()->getAs<FunctionType>()->getResultType();
+  QualType ResultType =
+      FnDecl->getType()->getAs<FunctionType>()->getReturnType();
 
   // Check that the result type is not dependent.
   if (ResultType->isDependentType())
@@ -10698,10 +10993,8 @@
                   diag::err_operator_overload_static) << FnDecl->getDeclName();
   } else {
     bool ClassOrEnumParam = false;
-    for (FunctionDecl::param_iterator Param = FnDecl->param_begin(),
-                                   ParamEnd = FnDecl->param_end();
-         Param != ParamEnd; ++Param) {
-      QualType ParamType = (*Param)->getType().getNonReferenceType();
+    for (auto Param : FnDecl->params()) {
+      QualType ParamType = Param->getType().getNonReferenceType();
       if (ParamType->isDependentType() || ParamType->isRecordType() ||
           ParamType->isEnumeralType()) {
         ClassOrEnumParam = true;
@@ -10722,12 +11015,11 @@
   // Only the function-call operator allows default arguments
   // (C++ [over.call]p1).
   if (Op != OO_Call) {
-    for (FunctionDecl::param_iterator Param = FnDecl->param_begin();
-         Param != FnDecl->param_end(); ++Param) {
-      if ((*Param)->hasDefaultArg())
-        return Diag((*Param)->getLocation(),
+    for (auto Param : FnDecl->params()) {
+      if (Param->hasDefaultArg())
+        return Diag(Param->getLocation(),
                     diag::err_operator_overload_default_arg)
-          << FnDecl->getDeclName() << (*Param)->getDefaultArgRange();
+          << FnDecl->getDeclName() << Param->getDefaultArgRange();
     }
   }
 
@@ -10794,11 +11086,10 @@
   //   increment operator ++ for objects of that type.
   if ((Op == OO_PlusPlus || Op == OO_MinusMinus) && NumParams == 2) {
     ParmVarDecl *LastParam = FnDecl->getParamDecl(FnDecl->getNumParams() - 1);
-    bool ParamIsInt = false;
-    if (const BuiltinType *BT = LastParam->getType()->getAs<BuiltinType>())
-      ParamIsInt = BT->getKind() == BuiltinType::Int;
+    QualType ParamType = LastParam->getType();
 
-    if (!ParamIsInt)
+    if (!ParamType->isSpecificBuiltinType(BuiltinType::Int) &&
+        !ParamType->isDependentType())
       return Diag(LastParam->getLocation(),
                   diag::err_operator_overload_post_incdec_must_be_int)
         << LastParam->getType() << (Op == OO_MinusMinus);
@@ -10931,13 +11222,11 @@
 
   // A parameter-declaration-clause containing a default argument is not
   // equivalent to any of the permitted forms.
-  for (FunctionDecl::param_iterator Param = FnDecl->param_begin(),
-                                    ParamEnd = FnDecl->param_end();
-       Param != ParamEnd; ++Param) {
-    if ((*Param)->hasDefaultArg()) {
-      Diag((*Param)->getDefaultArgRange().getBegin(),
+  for (auto Param : FnDecl->params()) {
+    if (Param->hasDefaultArg()) {
+      Diag(Param->getDefaultArgRange().getBegin(),
            diag::err_literal_operator_default_argument)
-        << (*Param)->getDefaultArgRange();
+        << Param->getDefaultArgRange();
       break;
     }
   }
@@ -10957,29 +11246,36 @@
 
 /// ActOnStartLinkageSpecification - Parsed the beginning of a C++
 /// linkage specification, including the language and (if present)
-/// the '{'. ExternLoc is the location of the 'extern', LangLoc is
-/// the location of the language string literal, which is provided
-/// by Lang/StrSize. LBraceLoc, if valid, provides the location of
+/// the '{'. ExternLoc is the location of the 'extern', Lang is the
+/// language string literal. LBraceLoc, if valid, provides the location of
 /// the '{' brace. Otherwise, this linkage specification does not
 /// have any braces.
 Decl *Sema::ActOnStartLinkageSpecification(Scope *S, SourceLocation ExternLoc,
-                                           SourceLocation LangLoc,
-                                           StringRef Lang,
+                                           Expr *LangStr,
                                            SourceLocation LBraceLoc) {
+  StringLiteral *Lit = cast<StringLiteral>(LangStr);
+  if (!Lit->isAscii()) {
+    Diag(LangStr->getExprLoc(), diag::err_language_linkage_spec_not_ascii)
+      << LangStr->getSourceRange();
+    return nullptr;
+  }
+
+  StringRef Lang = Lit->getString();
   LinkageSpecDecl::LanguageIDs Language;
-  if (Lang == "\"C\"")
+  if (Lang == "C")
     Language = LinkageSpecDecl::lang_c;
-  else if (Lang == "\"C++\"")
+  else if (Lang == "C++")
     Language = LinkageSpecDecl::lang_cxx;
   else {
-    Diag(LangLoc, diag::err_bad_language);
-    return 0;
+    Diag(LangStr->getExprLoc(), diag::err_language_linkage_spec_unknown)
+      << LangStr->getSourceRange();
+    return nullptr;
   }
 
   // FIXME: Add all the various semantics of linkage specifications
 
-  LinkageSpecDecl *D = LinkageSpecDecl::Create(Context, CurContext,
-                                               ExternLoc, LangLoc, Language,
+  LinkageSpecDecl *D = LinkageSpecDecl::Create(Context, CurContext, ExternLoc,
+                                               LangStr->getExprLoc(), Language,
                                                LBraceLoc.isValid());
   CurContext->addDecl(D);
   PushDeclContext(S, D);
@@ -10993,13 +11289,11 @@
 Decl *Sema::ActOnFinishLinkageSpecification(Scope *S,
                                             Decl *LinkageSpec,
                                             SourceLocation RBraceLoc) {
-  if (LinkageSpec) {
-    if (RBraceLoc.isValid()) {
-      LinkageSpecDecl* LSDecl = cast<LinkageSpecDecl>(LinkageSpec);
-      LSDecl->setRBraceLoc(RBraceLoc);
-    }
-    PopDeclContext();
+  if (RBraceLoc.isValid()) {
+    LinkageSpecDecl* LSDecl = cast<LinkageSpecDecl>(LinkageSpec);
+    LSDecl->setRBraceLoc(RBraceLoc);
   }
+  PopDeclContext();
   return LinkageSpec;
 }
 
@@ -11120,7 +11414,7 @@
       else {
         // If the constructor used was non-trivial, set this as the
         // "initializer".
-        CXXConstructExpr *construct = result.takeAs<CXXConstructExpr>();
+        CXXConstructExpr *construct = result.getAs<CXXConstructExpr>();
         if (!construct->getConstructor()->isTrivial()) {
           Expr *init = MaybeCreateExprWithCleanups(construct);
           ExDecl->setInit(init);
@@ -11157,13 +11451,17 @@
                                              LookupOrdinaryName,
                                              ForRedeclaration)) {
     // The scope should be freshly made just for us. There is just no way
-    // it contains any previous declaration.
+    // it contains any previous declaration, except for function parameters in
+    // a function-try-block's catch statement.
     assert(!S->isDeclScope(PrevDecl));
-    if (PrevDecl->isTemplateParameter()) {
+    if (isDeclInScope(PrevDecl, CurContext, S)) {
+      Diag(D.getIdentifierLoc(), diag::err_redefinition)
+        << D.getIdentifier();
+      Diag(PrevDecl->getLocation(), diag::note_previous_definition);
+      Invalid = true;
+    } else if (PrevDecl->isTemplateParameter())
       // Maybe we will complain about the shadowed template parameter.
       DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl);
-      PrevDecl = 0;
-    }
   }
 
   if (D.getCXXScopeSpec().isSet() && !Invalid) {
@@ -11193,10 +11491,11 @@
                                          Expr *AssertExpr,
                                          Expr *AssertMessageExpr,
                                          SourceLocation RParenLoc) {
-  StringLiteral *AssertMessage = cast<StringLiteral>(AssertMessageExpr);
+  StringLiteral *AssertMessage =
+      AssertMessageExpr ? cast<StringLiteral>(AssertMessageExpr) : nullptr;
 
   if (DiagnoseUnexpandedParameterPack(AssertExpr, UPPC_StaticAssertExpression))
-    return 0;
+    return nullptr;
 
   return BuildStaticAssertDeclaration(StaticAssertLoc, AssertExpr,
                                       AssertMessage, RParenLoc, false);
@@ -11207,6 +11506,7 @@
                                          StringLiteral *AssertMessage,
                                          SourceLocation RParenLoc,
                                          bool Failed) {
+  assert(AssertExpr != nullptr && "Expected non-null condition");
   if (!AssertExpr->isTypeDependent() && !AssertExpr->isValueDependent() &&
       !Failed) {
     // In a static_assert-declaration, the constant-expression shall be a
@@ -11224,9 +11524,10 @@
     if (!Failed && !Cond) {
       SmallString<256> MsgBuffer;
       llvm::raw_svector_ostream Msg(MsgBuffer);
-      AssertMessage->printPretty(Msg, 0, getPrintingPolicy());
+      if (AssertMessage)
+        AssertMessage->printPretty(Msg, nullptr, getPrintingPolicy());
       Diag(StaticAssertLoc, diag::err_static_assert_failed)
-        << Msg.str() << AssertExpr->getSourceRange();
+        << !AssertMessage << Msg.str() << AssertExpr->getSourceRange();
       Failed = true;
     }
   }
@@ -11265,9 +11566,10 @@
       // a tag in front.
       if (const RecordType *RT = T->getAs<RecordType>()) {
         RecordDecl *RD = RT->getDecl();
-      
-        std::string InsertionText = std::string(" ") + RD->getKindName();
-      
+
+        SmallString<16> InsertionText(" ");
+        InsertionText += RD->getKindName();
+
         Diag(TypeRange.getBegin(),
              getLangOpts().CPlusPlus11 ?
                diag::warn_cxx98_compat_unelaborated_friend_type :
@@ -11306,7 +11608,9 @@
   //   If the type specifier in a friend declaration designates a (possibly
   //   cv-qualified) class type, that class is declared as a friend; otherwise,
   //   the friend declaration is ignored.
-  return FriendDecl::Create(Context, CurContext, LocStart, TSInfo, FriendLoc);
+  return FriendDecl::Create(Context, CurContext,
+                            TSInfo->getTypeLoc().getLocStart(), TSInfo,
+                            FriendLoc);
 }
 
 /// Handle a friend tag declaration where the scope specifier was
@@ -11325,19 +11629,18 @@
 
   if (TemplateParameterList *TemplateParams =
           MatchTemplateParametersToScopeSpecifier(
-              TagLoc, NameLoc, SS, TempParamLists, /*friend*/ true,
+              TagLoc, NameLoc, SS, nullptr, TempParamLists, /*friend*/ true,
               isExplicitSpecialization, Invalid)) {
     if (TemplateParams->size() > 0) {
       // This is a declaration of a class template.
       if (Invalid)
-        return 0;
+        return nullptr;
 
-      return CheckClassTemplate(S, TagSpec, TUK_Friend, TagLoc,
-                                SS, Name, NameLoc, Attr,
-                                TemplateParams, AS_public,
+      return CheckClassTemplate(S, TagSpec, TUK_Friend, TagLoc, SS, Name,
+                                NameLoc, Attr, TemplateParams, AS_public,
                                 /*ModulePrivateLoc=*/SourceLocation(),
-                                TempParamLists.size() - 1,
-                                TempParamLists.data()).take();
+                                FriendLoc, TempParamLists.size() - 1,
+                                TempParamLists.data()).get();
     } else {
       // The "template<>" header is extraneous.
       Diag(TemplateParams->getTemplateLoc(), diag::err_template_tag_noparams)
@@ -11346,7 +11649,7 @@
     }
   }
 
-  if (Invalid) return 0;
+  if (Invalid) return nullptr;
 
   bool isAllExplicitSpecializations = true;
   for (unsigned I = TempParamLists.size(); I-- > 0; ) {
@@ -11366,21 +11669,22 @@
       bool Owned = false;
       bool IsDependent = false;
       return ActOnTag(S, TagSpec, TUK_Friend, TagLoc, SS, Name, NameLoc,
-                      Attr, AS_public, 
+                      Attr, AS_public,
                       /*ModulePrivateLoc=*/SourceLocation(),
-                      MultiTemplateParamsArg(), Owned, IsDependent, 
+                      MultiTemplateParamsArg(), Owned, IsDependent,
                       /*ScopedEnumKWLoc=*/SourceLocation(),
                       /*ScopedEnumUsesClassTag=*/false,
-                      /*UnderlyingType=*/TypeResult());          
+                      /*UnderlyingType=*/TypeResult(),
+                      /*IsTypeSpecifier=*/false);
     }
-    
+
     NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context);
     ElaboratedTypeKeyword Keyword
       = TypeWithKeyword::getKeywordForTagTypeKind(Kind);
     QualType T = CheckTypenameType(Keyword, TagLoc, QualifierLoc,
                                    *Name, NameLoc);
     if (T.isNull())
-      return 0;
+      return nullptr;
 
     TypeSourceInfo *TSI = Context.CreateTypeSourceInfo(T);
     if (isa<DependentNameType>(T)) {
@@ -11460,10 +11764,10 @@
   TypeSourceInfo *TSI = GetTypeForDeclarator(TheDeclarator, S);
   QualType T = TSI->getType();
   if (TheDeclarator.isInvalidType())
-    return 0;
+    return nullptr;
 
   if (DiagnoseUnexpandedParameterPack(Loc, TSI, UPPC_FriendDeclaration))
-    return 0;
+    return nullptr;
 
   // This is definitely an error in C++98.  It's probably meant to
   // be forbidden in C++0x, too, but the specification is just
@@ -11482,7 +11786,7 @@
   if (TempParams.size() && !T->isElaboratedTypeSpecifier()) {
     Diag(Loc, diag::err_tagless_friend_type_template)
       << DS.getSourceRange();
-    return 0;
+    return nullptr;
   }
   
   // C++98 [class.friend]p1: A friend of a class is a function
@@ -11507,8 +11811,8 @@
     D = CheckFriendTypeDecl(Loc, DS.getFriendSpecLoc(), TSI);
   
   if (!D)
-    return 0;
-  
+    return nullptr;
+
   D->setAccess(AS_public);
   CurContext->addDecl(D);
 
@@ -11540,7 +11844,7 @@
 
     // It might be worthwhile to try to recover by creating an
     // appropriate declaration.
-    return 0;
+    return nullptr;
   }
 
   // C++ [namespace.memdef]p3
@@ -11567,7 +11871,7 @@
   if (DiagnoseUnexpandedParameterPack(Loc, TInfo, UPPC_FriendDeclaration) ||
       DiagnoseUnexpandedParameterPack(NameInfo, UPPC_FriendDeclaration) ||
       DiagnoseUnexpandedParameterPack(SS, UPPC_FriendDeclaration))
-    return 0;
+    return nullptr;
 
   // The context we found the declaration in, or in which we should
   // create the declaration.
@@ -11580,7 +11884,7 @@
   //   - There's no scope specifier and we're in a local class. Only look
   //     for functions declared in the immediately-enclosing block scope.
   // We recover from invalid scope qualifiers as if they just weren't there.
-  FunctionDecl *FunctionContainingLocalClass = 0;
+  FunctionDecl *FunctionContainingLocalClass = nullptr;
   if ((SS.isInvalid() || !SS.isSet()) &&
       (FunctionContainingLocalClass =
            cast<CXXRecordDecl>(CurContext)->isLocalClass())) {
@@ -11673,9 +11977,9 @@
   //     or function template.
   } else if (!SS.getScopeRep()->isDependent()) {
     DC = computeDeclContext(SS);
-    if (!DC) return 0;
+    if (!DC) return nullptr;
 
-    if (RequireCompleteDeclContext(SS, DC)) return 0;
+    if (RequireCompleteDeclContext(SS, DC)) return nullptr;
 
     LookupQualifiedName(Previous, DC);
 
@@ -11695,7 +11999,7 @@
       D.setInvalidType();
       Diag(Loc, diag::err_qualified_friend_not_found)
           << Name << TInfo->getType();
-      return 0;
+      return nullptr;
     }
 
     // C++ [class.friend]p1: A friend of a class is a function or
@@ -11747,7 +12051,7 @@
       Diag(Loc, diag::err_introducing_special_friend) <<
         (D.getName().getKind() == UnqualifiedId::IK_ConstructorName ? 0 :
          D.getName().getKind() == UnqualifiedId::IK_DestructorName ? 1 : 2);
-      return 0;
+      return nullptr;
     }
   }
 
@@ -11763,7 +12067,7 @@
   bool AddToScope = true;
   NamedDecl *ND = ActOnFunctionDeclarator(DCScope, D, DC, TInfo, Previous,
                                           TemplateParams, AddToScope);
-  if (!ND) return 0;
+  if (!ND) return nullptr;
 
   assert(ND->getLexicalDeclContext() == CurContext);
 
@@ -11833,16 +12137,25 @@
   if (const FunctionDecl *Prev = Fn->getPreviousDecl()) {
     // Don't consider the implicit declaration we generate for explicit
     // specializations. FIXME: Do not generate these implicit declarations.
-    if ((Prev->getTemplateSpecializationKind() != TSK_ExplicitSpecialization
-        || Prev->getPreviousDecl()) && !Prev->isDefined()) {
+    if ((Prev->getTemplateSpecializationKind() != TSK_ExplicitSpecialization ||
+         Prev->getPreviousDecl()) &&
+        !Prev->isDefined()) {
       Diag(DelLoc, diag::err_deleted_decl_not_first);
-      Diag(Prev->getLocation(), diag::note_previous_declaration);
+      Diag(Prev->getLocation().isInvalid() ? DelLoc : Prev->getLocation(),
+           Prev->isImplicit() ? diag::note_previous_implicit_declaration
+                              : diag::note_previous_declaration);
     }
     // If the declaration wasn't the first, we delete the function anyway for
     // recovery.
     Fn = Fn->getCanonicalDecl();
   }
 
+  // dllimport/dllexport cannot be deleted.
+  if (const InheritableAttr *DLLAttr = getDLLAttr(Fn)) {
+    Diag(Fn->getLocation(), diag::err_attribute_dll_deleted) << DLLAttr;
+    Fn->setInvalidDecl();
+  }
+
   if (Fn->isDeleted())
     return;
 
@@ -11863,6 +12176,11 @@
     }
   }
 
+  // C++11 [basic.start.main]p3:
+  //   A program that defines main as deleted [...] is ill-formed.
+  if (Fn->isMain())
+    Diag(DelLoc, diag::err_deleted_main);
+
   Fn->setDeletedAsWritten();
 }
 
@@ -11969,6 +12287,13 @@
   if (NewCC == OldCC)
     return false;
 
+  // If the calling conventions mismatch because the new function is static,
+  // suppress the calling convention mismatch error; the error about static
+  // function override (err_static_overrides_virtual from
+  // Sema::CheckFunctionDeclaration) is more clear.
+  if (New->getStorageClass() == SC_Static)
+    return false;
+
   Diag(New->getLocation(),
        diag::err_conflicting_overriding_cc_attributes)
     << New->getDeclName() << New->getType() << Old->getType();
@@ -11978,8 +12303,8 @@
 
 bool Sema::CheckOverridingFunctionReturnType(const CXXMethodDecl *New,
                                              const CXXMethodDecl *Old) {
-  QualType NewTy = New->getType()->getAs<FunctionType>()->getResultType();
-  QualType OldTy = Old->getType()->getAs<FunctionType>()->getResultType();
+  QualType NewTy = New->getType()->getAs<FunctionType>()->getReturnType();
+  QualType OldTy = Old->getType()->getAs<FunctionType>()->getReturnType();
 
   if (Context.hasSameType(NewTy, OldTy) ||
       NewTy->isDependentType() || OldTy->isDependentType())
@@ -12007,8 +12332,10 @@
   if (NewClassTy.isNull()) {
     Diag(New->getLocation(),
          diag::err_different_return_type_for_overriding_virtual_function)
-      << New->getDeclName() << NewTy << OldTy;
-    Diag(Old->getLocation(), diag::note_overridden_virtual_function);
+        << New->getDeclName() << NewTy << OldTy
+        << New->getReturnTypeSourceRange();
+    Diag(Old->getLocation(), diag::note_overridden_virtual_function)
+        << Old->getReturnTypeSourceRange();
 
     return true;
   }
@@ -12028,24 +12355,27 @@
   if (!Context.hasSameUnqualifiedType(NewClassTy, OldClassTy)) {
     // Check if the new class derives from the old class.
     if (!IsDerivedFrom(NewClassTy, OldClassTy)) {
-      Diag(New->getLocation(),
-           diag::err_covariant_return_not_derived)
-      << New->getDeclName() << NewTy << OldTy;
-      Diag(Old->getLocation(), diag::note_overridden_virtual_function);
+      Diag(New->getLocation(), diag::err_covariant_return_not_derived)
+          << New->getDeclName() << NewTy << OldTy
+          << New->getReturnTypeSourceRange();
+      Diag(Old->getLocation(), diag::note_overridden_virtual_function)
+          << Old->getReturnTypeSourceRange();
       return true;
     }
 
     // Check if we the conversion from derived to base is valid.
-    if (CheckDerivedToBaseConversion(NewClassTy, OldClassTy,
-                    diag::err_covariant_return_inaccessible_base,
-                    diag::err_covariant_return_ambiguous_derived_to_base_conv,
-                    // FIXME: Should this point to the return type?
-                    New->getLocation(), SourceRange(), New->getDeclName(), 0)) {
+    if (CheckDerivedToBaseConversion(
+            NewClassTy, OldClassTy,
+            diag::err_covariant_return_inaccessible_base,
+            diag::err_covariant_return_ambiguous_derived_to_base_conv,
+            New->getLocation(), New->getReturnTypeSourceRange(),
+            New->getDeclName(), nullptr)) {
       // FIXME: this note won't trigger for delayed access control
       // diagnostics, and it's impossible to get an undelayed error
       // here from access control during the original parse because
       // the ParsingDeclSpec/ParsingDeclarator are still in scope.
-      Diag(Old->getLocation(), diag::note_overridden_virtual_function);
+      Diag(Old->getLocation(), diag::note_overridden_virtual_function)
+          << Old->getReturnTypeSourceRange();
       return true;
     }
   }
@@ -12054,8 +12384,10 @@
   if (NewTy.getLocalCVRQualifiers() != OldTy.getLocalCVRQualifiers()) {
     Diag(New->getLocation(),
          diag::err_covariant_return_type_different_qualifications)
-    << New->getDeclName() << NewTy << OldTy;
-    Diag(Old->getLocation(), diag::note_overridden_virtual_function);
+        << New->getDeclName() << NewTy << OldTy
+        << New->getReturnTypeSourceRange();
+    Diag(Old->getLocation(), diag::note_overridden_virtual_function)
+        << Old->getReturnTypeSourceRange();
     return true;
   };
 
@@ -12064,8 +12396,10 @@
   if (NewClassTy.isMoreQualifiedThan(OldClassTy)) {
     Diag(New->getLocation(),
          diag::err_covariant_return_type_class_type_more_qualified)
-    << New->getDeclName() << NewTy << OldTy;
-    Diag(Old->getLocation(), diag::note_overridden_virtual_function);
+        << New->getDeclName() << NewTy << OldTy
+        << New->getReturnTypeSourceRange();
+    Diag(Old->getLocation(), diag::note_overridden_virtual_function)
+        << Old->getReturnTypeSourceRange();
     return true;
   };
 
@@ -12110,13 +12444,16 @@
 /// class X.
 void Sema::ActOnCXXEnterDeclInitializer(Scope *S, Decl *D) {
   // If there is no declaration, there was an error parsing it.
-  if (D == 0 || D->isInvalidDecl()) return;
+  if (!D || D->isInvalidDecl())
+    return;
 
-  // We should only get called for declarations with scope specifiers, like:
-  //   int foo::bar;
-  assert(D->isOutOfLine());
-  EnterDeclaratorContext(S, D->getDeclContext());
-  
+  // We will always have a nested name specifier here, but this declaration
+  // might not be out of line if the specifier names the current namespace:
+  //   extern int n;
+  //   int ::n = 0;
+  if (D->isOutOfLine())
+    EnterDeclaratorContext(S, D->getDeclContext());
+
   // If we are parsing the initializer for a static data member, push a
   // new expression evaluation context that is associated with this static
   // data member.
@@ -12128,13 +12465,14 @@
 /// initializer for the out-of-line declaration 'D'.
 void Sema::ActOnCXXExitDeclInitializer(Scope *S, Decl *D) {
   // If there is no declaration, there was an error parsing it.
-  if (D == 0 || D->isInvalidDecl()) return;
+  if (!D || D->isInvalidDecl())
+    return;
 
   if (isStaticDataMember(D))
-    PopExpressionEvaluationContext();  
+    PopExpressionEvaluationContext();
 
-  assert(D->isOutOfLine());
-  ExitDeclaratorContext(S);
+  if (D->isOutOfLine())
+    ExitDeclaratorContext(S);
 }
 
 /// ActOnCXXConditionDeclarationExpr - Parsed a condition declaration of a
@@ -12208,6 +12546,20 @@
       // Otherwise, we can early exit.
       return;
     }
+  } else {
+    // The Microsoft ABI requires that we perform the destructor body
+    // checks (i.e. operator delete() lookup) when the vtable is marked used, as
+    // the deleting destructor is emitted with the vtable, not with the
+    // destructor definition as in the Itanium ABI.
+    // If it has a definition, we do the check at that point instead.
+    if (Context.getTargetInfo().getCXXABI().isMicrosoft() &&
+        Class->hasUserDeclaredDestructor() &&
+        !Class->getDestructor()->isDefined() &&
+        !Class->getDestructor()->isDeleted()) {
+      CXXDestructorDecl *DD = Class->getDestructor();
+      ContextRAII SavedContext(*this, DD);
+      CheckDestructor(DD);
+    }
   }
 
   // Local classes need to have their virtual members marked
@@ -12259,11 +12611,9 @@
       bool IsExplicitInstantiationDeclaration
         = Class->getTemplateSpecializationKind()
                                       == TSK_ExplicitInstantiationDeclaration;
-      for (TagDecl::redecl_iterator R = Class->redecls_begin(),
-                                 REnd = Class->redecls_end();
-           R != REnd; ++R) {
+      for (auto R : Class->redecls()) {
         TemplateSpecializationKind TSK
-          = cast<CXXRecordDecl>(*R)->getTemplateSpecializationKind();
+          = cast<CXXRecordDecl>(R)->getTemplateSpecializationKind();
         if (TSK == TSK_ExplicitInstantiationDeclaration)
           IsExplicitInstantiationDeclaration = true;
         else if (TSK == TSK_ExplicitInstantiationDefinition) {
@@ -12295,7 +12645,7 @@
     // Optionally warn if we're emitting a weak vtable.
     if (Class->isExternallyVisible() &&
         Class->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) {
-      const FunctionDecl *KeyFunctionDef = 0;
+      const FunctionDecl *KeyFunctionDef = nullptr;
       if (!KeyFunction || 
           (KeyFunction->hasBody(KeyFunctionDef) && 
            KeyFunctionDef->isInlined()))
@@ -12312,10 +12662,9 @@
 
 void Sema::MarkVirtualMemberExceptionSpecsNeeded(SourceLocation Loc,
                                                  const CXXRecordDecl *RD) {
-  for (CXXRecordDecl::method_iterator I = RD->method_begin(),
-                                      E = RD->method_end(); I != E; ++I)
-    if ((*I)->isVirtual() && !(*I)->isPure())
-      ResolveExceptionSpec(Loc, (*I)->getType()->castAs<FunctionProtoType>());
+  for (const auto *I : RD->methods())
+    if (I->isVirtual() && !I->isPure())
+      ResolveExceptionSpec(Loc, I->getType()->castAs<FunctionProtoType>());
 }
 
 void Sema::MarkVirtualMembersReferenced(SourceLocation Loc,
@@ -12343,10 +12692,9 @@
   if (RD->getNumVBases() == 0)
     return;
 
-  for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
-           e = RD->bases_end(); i != e; ++i) {
+  for (const auto &I : RD->bases()) {
     const CXXRecordDecl *Base =
-        cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
+        cast<CXXRecordDecl>(I.getType()->getAs<RecordType>()->getDecl());
     if (Base->getNumVBases() == 0)
       continue;
     MarkVirtualMembersReferenced(Loc, Base);
@@ -12386,7 +12734,7 @@
       Member =
         new (Context) CXXCtorInitializer(Context, Field, SourceLocation(),
                                          SourceLocation(),
-                                         MemberInit.takeAs<Expr>(),
+                                         MemberInit.getAs<Expr>(),
                                          SourceLocation());
       AllToInit.push_back(Member);
       
@@ -12422,7 +12770,7 @@
   // Target may not be determinable yet, for instance if this is a dependent
   // call in an uninstantiated template.
   if (Target) {
-    const FunctionDecl *FNTarget = 0;
+    const FunctionDecl *FNTarget = nullptr;
     (void)Target->hasBody(FNTarget);
     Target = const_cast<CXXConstructorDecl*>(
       cast_or_null<CXXConstructorDecl>(FNTarget));
@@ -12430,7 +12778,7 @@
 
   CXXConstructorDecl *Canonical = Ctor->getCanonicalDecl(),
                      // Avoid dereferencing a null pointer here.
-                     *TCanonical = Target ? Target->getCanonicalDecl() : 0;
+                     *TCanonical = Target? Target->getCanonicalDecl() : nullptr;
 
   if (!Current.insert(Canonical))
     return;
@@ -12455,7 +12803,7 @@
 
       CXXConstructorDecl *C = Target;
       while (C->getCanonicalDecl() != Canonical) {
-        const FunctionDecl *FNTarget = 0;
+        const FunctionDecl *FNTarget = nullptr;
         (void)C->getTargetConstructor()->hasBody(FNTarget);
         assert(FNTarget && "Ctor cycle through bodiless function");
 
@@ -12526,7 +12874,7 @@
   
   // If the return type came after the cv-qualifier-seq, check it now.
   if (Proto->hasTrailingReturn() &&
-      !Finder.TraverseTypeLoc(ProtoTL.getResultLoc()))
+      !Finder.TraverseTypeLoc(ProtoTL.getReturnLoc()))
     return true;
 
   // Check the exception specification.
@@ -12563,10 +12911,8 @@
       return true;
     
   case EST_Dynamic:
-    for (FunctionProtoType::exception_iterator E = Proto->exception_begin(),
-         EEnd = Proto->exception_end();
-         E != EEnd; ++E) {
-      if (!Finder.TraverseType(*E))
+    for (const auto &E : Proto->exceptions()) {
+      if (!Finder.TraverseType(E))
         return true;
     }
     break;
@@ -12579,45 +12925,36 @@
   FindCXXThisExpr Finder(*this);
 
   // Check attributes.
-  for (Decl::attr_iterator A = Method->attr_begin(), AEnd = Method->attr_end();
-       A != AEnd; ++A) {
+  for (const auto *A : Method->attrs()) {
     // FIXME: This should be emitted by tblgen.
-    Expr *Arg = 0;
+    Expr *Arg = nullptr;
     ArrayRef<Expr *> Args;
-    if (GuardedByAttr *G = dyn_cast<GuardedByAttr>(*A))
+    if (const auto *G = dyn_cast<GuardedByAttr>(A))
       Arg = G->getArg();
-    else if (PtGuardedByAttr *G = dyn_cast<PtGuardedByAttr>(*A))
+    else if (const auto *G = dyn_cast<PtGuardedByAttr>(A))
       Arg = G->getArg();
-    else if (AcquiredAfterAttr *AA = dyn_cast<AcquiredAfterAttr>(*A))
+    else if (const auto *AA = dyn_cast<AcquiredAfterAttr>(A))
       Args = ArrayRef<Expr *>(AA->args_begin(), AA->args_size());
-    else if (AcquiredBeforeAttr *AB = dyn_cast<AcquiredBeforeAttr>(*A))
+    else if (const auto *AB = dyn_cast<AcquiredBeforeAttr>(A))
       Args = ArrayRef<Expr *>(AB->args_begin(), AB->args_size());
-    else if (ExclusiveLockFunctionAttr *ELF 
-               = dyn_cast<ExclusiveLockFunctionAttr>(*A))
-      Args = ArrayRef<Expr *>(ELF->args_begin(), ELF->args_size());
-    else if (SharedLockFunctionAttr *SLF 
-               = dyn_cast<SharedLockFunctionAttr>(*A))
-      Args = ArrayRef<Expr *>(SLF->args_begin(), SLF->args_size());
-    else if (ExclusiveTrylockFunctionAttr *ETLF
-               = dyn_cast<ExclusiveTrylockFunctionAttr>(*A)) {
+    else if (const auto *ETLF = dyn_cast<ExclusiveTrylockFunctionAttr>(A)) {
       Arg = ETLF->getSuccessValue();
       Args = ArrayRef<Expr *>(ETLF->args_begin(), ETLF->args_size());
-    } else if (SharedTrylockFunctionAttr *STLF
-                 = dyn_cast<SharedTrylockFunctionAttr>(*A)) {
+    } else if (const auto *STLF = dyn_cast<SharedTrylockFunctionAttr>(A)) {
       Arg = STLF->getSuccessValue();
       Args = ArrayRef<Expr *>(STLF->args_begin(), STLF->args_size());
-    } else if (UnlockFunctionAttr *UF = dyn_cast<UnlockFunctionAttr>(*A))
-      Args = ArrayRef<Expr *>(UF->args_begin(), UF->args_size());
-    else if (LockReturnedAttr *LR = dyn_cast<LockReturnedAttr>(*A))
+    } else if (const auto *LR = dyn_cast<LockReturnedAttr>(A))
       Arg = LR->getArg();
-    else if (LocksExcludedAttr *LE = dyn_cast<LocksExcludedAttr>(*A))
+    else if (const auto *LE = dyn_cast<LocksExcludedAttr>(A))
       Args = ArrayRef<Expr *>(LE->args_begin(), LE->args_size());
-    else if (ExclusiveLocksRequiredAttr *ELR 
-               = dyn_cast<ExclusiveLocksRequiredAttr>(*A))
-      Args = ArrayRef<Expr *>(ELR->args_begin(), ELR->args_size());
-    else if (SharedLocksRequiredAttr *SLR 
-               = dyn_cast<SharedLocksRequiredAttr>(*A))
-      Args = ArrayRef<Expr *>(SLR->args_begin(), SLR->args_size());
+    else if (const auto *RC = dyn_cast<RequiresCapabilityAttr>(A))
+      Args = ArrayRef<Expr *>(RC->args_begin(), RC->args_size());
+    else if (const auto *AC = dyn_cast<AcquireCapabilityAttr>(A))
+      Args = ArrayRef<Expr *>(AC->args_begin(), AC->args_size());
+    else if (const auto *AC = dyn_cast<TryAcquireCapabilityAttr>(A))
+      Args = ArrayRef<Expr *>(AC->args_begin(), AC->args_size());
+    else if (const auto *RC = dyn_cast<ReleaseCapabilityAttr>(A))
+      Args = ArrayRef<Expr *>(RC->args_begin(), RC->args_size());
 
     if (Arg && !Finder.TraverseStmt(Arg))
       return true;
@@ -12678,9 +13015,9 @@
       }
       
       if (!NoexceptExpr->isValueDependent())
-        NoexceptExpr = VerifyIntegerConstantExpression(NoexceptExpr, 0,
+        NoexceptExpr = VerifyIntegerConstantExpression(NoexceptExpr, nullptr,
                          diag::err_noexcept_needs_constant_expression,
-                         /*AllowFold*/ false).take();
+                         /*AllowFold*/ false).get();
       EPI.NoexceptExpr = NoexceptExpr;
     }
     return;
@@ -12738,7 +13075,7 @@
   IdentifierInfo *II = D.getIdentifier();
   if (!II) {
     Diag(DeclStart, diag::err_anonymous_property);
-    return NULL;
+    return nullptr;
   }
   SourceLocation Loc = D.getIdentifierLoc();
 
@@ -12763,7 +13100,7 @@
       << DeclSpec::getSpecifierName(TSCS);
 
   // Check to see if this name was declared as a member previously
-  NamedDecl *PrevDecl = 0;
+  NamedDecl *PrevDecl = nullptr;
   LookupResult Previous(*this, II, Loc, LookupMemberName, ForRedeclaration);
   LookupName(Previous, S);
   switch (Previous.getResultKind()) {
@@ -12786,18 +13123,16 @@
     // Maybe we will complain about the shadowed template parameter.
     DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl);
     // Just pretend that we didn't see the previous declaration.
-    PrevDecl = 0;
+    PrevDecl = nullptr;
   }
 
   if (PrevDecl && !isDeclInScope(PrevDecl, Record, S))
-    PrevDecl = 0;
+    PrevDecl = nullptr;
 
   SourceLocation TSSL = D.getLocStart();
-  MSPropertyDecl *NewPD;
   const AttributeList::PropertyData &Data = MSPropertyAttr->getPropertyData();
-  NewPD = new (Context) MSPropertyDecl(Record, Loc,
-                                       II, T, TInfo, TSSL,
-                                       Data.GetterId, Data.SetterId);
+  MSPropertyDecl *NewPD = MSPropertyDecl::Create(
+      Context, Record, Loc, II, T, TInfo, TSSL, Data.GetterId, Data.SetterId);
   ProcessDeclAttributes(TUScope, NewPD, D);
   NewPD->setAccess(AS);
 
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index f44fb32..b5205b3 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -15,11 +15,11 @@
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTMutationListener.h"
+#include "clang/AST/DataRecursiveASTVisitor.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/Basic/SourceManager.h"
-#include "clang/Lex/Preprocessor.h"
 #include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/ExternalSemaSource.h"
 #include "clang/Sema/Lookup.h"
@@ -48,8 +48,8 @@
 
   // We ignore protocols here.  Should we?  What about Class?
 
-  const ObjCObjectType *result = method->getResultType()
-    ->castAs<ObjCObjectPointerType>()->getObjectType();
+  const ObjCObjectType *result =
+      method->getReturnType()->castAs<ObjCObjectPointerType>()->getObjectType();
 
   if (result->isObjCId()) {
     return false;
@@ -70,7 +70,7 @@
     } else {
       // If this method was declared in a protocol, we can't check
       // anything unless we have a receiver type that's an interface.
-      const ObjCInterfaceDecl *receiverClass = 0;
+      const ObjCInterfaceDecl *receiverClass = nullptr;
       if (isa<ObjCProtocolDecl>(method->getDeclContext())) {
         if (receiverTypeIfCall.isNull())
           return false;
@@ -97,8 +97,9 @@
   // If we're in a system header, and this is not a call, just make
   // the method unusable.
   if (receiverTypeIfCall.isNull() && getSourceManager().isInSystemHeader(loc)) {
-    method->addAttr(new (Context) UnavailableAttr(loc, Context,
-                "init method returns a type unrelated to its receiver type"));
+    method->addAttr(UnavailableAttr::CreateImplicit(Context,
+                "init method returns a type unrelated to its receiver type",
+                loc));
     return true;
   }
 
@@ -116,10 +117,10 @@
     // implies a related result type, and the original (overridden) method has
     // a suitable return type, but the new (overriding) method does not have
     // a suitable return type.
-    QualType ResultType = NewMethod->getResultType();
+    QualType ResultType = NewMethod->getReturnType();
     SourceRange ResultTypeRange;
-    if (const TypeSourceInfo *ResultTypeInfo 
-                                        = NewMethod->getResultTypeSourceInfo())
+    if (const TypeSourceInfo *ResultTypeInfo =
+            NewMethod->getReturnTypeSourceInfo())
       ResultTypeRange = ResultTypeInfo->getTypeLoc().getSourceRange();
     
     // Figure out which class this method is part of, if any.
@@ -207,19 +208,19 @@
     return false;
 
   case OMF_dealloc:
-    if (!Context.hasSameType(method->getResultType(), Context.VoidTy)) {
+    if (!Context.hasSameType(method->getReturnType(), Context.VoidTy)) {
       SourceRange ResultTypeRange;
-      if (const TypeSourceInfo *ResultTypeInfo
-          = method->getResultTypeSourceInfo())
+      if (const TypeSourceInfo *ResultTypeInfo =
+              method->getReturnTypeSourceInfo())
         ResultTypeRange = ResultTypeInfo->getTypeLoc().getSourceRange();
       if (ResultTypeRange.isInvalid())
-        Diag(method->getLocation(), diag::error_dealloc_bad_result_type) 
-          << method->getResultType() 
-          << FixItHint::CreateInsertion(method->getSelectorLoc(0), "(void)");
+        Diag(method->getLocation(), diag::error_dealloc_bad_result_type)
+            << method->getReturnType()
+            << FixItHint::CreateInsertion(method->getSelectorLoc(0), "(void)");
       else
-        Diag(method->getLocation(), diag::error_dealloc_bad_result_type) 
-          << method->getResultType() 
-          << FixItHint::CreateReplacement(ResultTypeRange, "void");
+        Diag(method->getLocation(), diag::error_dealloc_bad_result_type)
+            << method->getReturnType()
+            << FixItHint::CreateReplacement(ResultTypeRange, "void");
       return true;
     }
     return false;
@@ -229,8 +230,7 @@
     if (checkInitMethod(method, QualType()))
       return true;
 
-    method->addAttr(new (Context) NSConsumesSelfAttr(SourceLocation(),
-                                                     Context));
+    method->addAttr(NSConsumesSelfAttr::CreateImplicit(Context));
 
     // Don't add a second copy of this attribute, but otherwise don't
     // let it be suppressed.
@@ -249,8 +249,7 @@
     break;
   }
 
-  method->addAttr(new (Context) NSReturnsRetainedAttr(SourceLocation(),
-                                                      Context));
+  method->addAttr(NSReturnsRetainedAttr::CreateImplicit(Context));
   return false;
 }
 
@@ -304,7 +303,7 @@
 /// ActOnStartOfObjCMethodDef - This routine sets up parameters; invisible
 /// and user declared, in the method definition's AST.
 void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, Decl *D) {
-  assert((getCurMethodDecl() == 0) && "Methodparsing confused");
+  assert((getCurMethodDecl() == nullptr) && "Methodparsing confused");
   ObjCMethodDecl *MDecl = dyn_cast_or_null<ObjCMethodDecl>(D);
   
   // If we don't have a valid method decl, simply return.
@@ -329,17 +328,15 @@
                            /*CheckParameterNames=*/false);
 
   // Introduce all of the other parameters into this scope.
-  for (ObjCMethodDecl::param_iterator PI = MDecl->param_begin(),
-       E = MDecl->param_end(); PI != E; ++PI) {
-    ParmVarDecl *Param = (*PI);
+  for (auto *Param : MDecl->params()) {
     if (!Param->isInvalidDecl() &&
         getLangOpts().ObjCAutoRefCount &&
         !HasExplicitOwnershipAttr(*this, Param))
       Diag(Param->getLocation(), diag::warn_arc_strong_pointer_objc_pointer) <<
             Param->getType();
     
-    if ((*PI)->getIdentifier())
-      PushOnScopeChains(*PI, FnBodyScope);
+    if (Param->getIdentifier())
+      PushOnScopeChains(Param, FnBodyScope);
   }
 
   // In ARC, disallow definition of retain/release/autorelease/retainCount
@@ -378,11 +375,16 @@
         dyn_cast<ObjCImplDecl>(MDecl->getDeclContext());
       ObjCContainerDecl *ContDeclOfMethodDecl = 
         dyn_cast<ObjCContainerDecl>(IMD->getDeclContext());
-      ObjCImplDecl *ImplDeclOfMethodDecl = 0;
+      ObjCImplDecl *ImplDeclOfMethodDecl = nullptr;
       if (ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(ContDeclOfMethodDecl))
         ImplDeclOfMethodDecl = OID->getImplementation();
-      else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(ContDeclOfMethodDecl))
-        ImplDeclOfMethodDecl = CD->getImplementation();
+      else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(ContDeclOfMethodDecl)) {
+        if (CD->IsClassExtension()) {
+          if (ObjCInterfaceDecl *OID = CD->getClassInterface())
+            ImplDeclOfMethodDecl = OID->getImplementation();
+        } else
+            ImplDeclOfMethodDecl = CD->getImplementation();
+      }
       // No need to issue deprecated warning if deprecated mehod in class/category
       // is being implemented in its own implementation (no overriding is involved).
       if (!ImplDeclOfMethodDecl || ImplDeclOfMethodDecl != ImplDeclOfMethodDef)
@@ -391,6 +393,17 @@
                                           MDecl->getLocation(), 0);
     }
 
+    if (MDecl->getMethodFamily() == OMF_init) {
+      if (MDecl->isDesignatedInitializerForTheInterface()) {
+        getCurFunction()->ObjCIsDesignatedInit = true;
+        getCurFunction()->ObjCWarnForNoDesignatedInitChain =
+            IC->getSuperClass() != nullptr;
+      } else if (IC->hasDesignatedInitializers()) {
+        getCurFunction()->ObjCIsSecondaryInit = true;
+        getCurFunction()->ObjCWarnForNoInitDelegation = true;
+      }
+    }
+
     // If this is "dealloc" or "finalize", set some bit here.
     // Then in ActOnSuperMessage() (SemaExprObjC), set it back to false.
     // Finally, in ActOnFinishFunctionBody() (SemaDecl), warn if flag is set.
@@ -424,11 +437,11 @@
 // function will reject corrections to that class.
 class ObjCInterfaceValidatorCCC : public CorrectionCandidateCallback {
  public:
-  ObjCInterfaceValidatorCCC() : CurrentIDecl(0) {}
+  ObjCInterfaceValidatorCCC() : CurrentIDecl(nullptr) {}
   explicit ObjCInterfaceValidatorCCC(ObjCInterfaceDecl *IDecl)
       : CurrentIDecl(IDecl) {}
 
-  virtual bool ValidateCandidate(const TypoCorrection &candidate) {
+  bool ValidateCandidate(const TypoCorrection &candidate) override {
     ObjCInterfaceDecl *ID = candidate.getCorrectionDeclAs<ObjCInterfaceDecl>();
     return ID && !declaresSameEntity(ID, CurrentIDecl);
   }
@@ -510,7 +523,7 @@
       ObjCInterfaceValidatorCCC Validator(IDecl);
       if (TypoCorrection Corrected = CorrectTypo(
           DeclarationNameInfo(SuperName, SuperLoc), LookupOrdinaryName, TUScope,
-          NULL, Validator)) {
+          nullptr, Validator, CTK_ErrorRecovery)) {
         diagnoseTypo(Corrected, PDiag(diag::err_undef_superclass_suggest)
                                     << SuperName << ClassName);
         PrevDecl = Corrected.getCorrectionDeclAs<ObjCInterfaceDecl>();
@@ -529,7 +542,7 @@
       if (SuperClassDecl)
         (void)DiagnoseUseOfDecl(SuperClassDecl, SuperLoc);
 
-      if (PrevDecl && SuperClassDecl == 0) {
+      if (PrevDecl && !SuperClassDecl) {
         // The previous declaration was not a class decl. Check if we have a
         // typedef. If we do, get the underlying class type.
         if (const TypedefNameDecl *TDecl =
@@ -568,7 +581,7 @@
                                      SuperClassDecl->getDeclName(),
                                      ClassName,
                                      SourceRange(AtInterfaceLoc, ClassLoc))) {
-          SuperClassDecl = 0;
+          SuperClassDecl = nullptr;
         }
       }
       IDecl->setSuperClass(SuperClassDecl);
@@ -607,9 +620,8 @@
     QualType T = TDecl->getUnderlyingType();
     if (T->isObjCObjectType())
       if (const ObjCObjectType *OPT = T->getAs<ObjCObjectType>())
-        for (ObjCObjectType::qual_iterator I = OPT->qual_begin(),
-             E = OPT->qual_end(); I != E; ++I)
-          ProtocolRefs.push_back(*I);
+        for (auto *I : OPT->quals())
+          ProtocolRefs.push_back(I);
   }
 }
 
@@ -626,7 +638,7 @@
   if (ADecl) {
     Diag(AliasLocation, diag::err_conflicting_aliasing_type) << AliasName;
     Diag(ADecl->getLocation(), diag::note_previous_declaration);
-    return 0;
+    return nullptr;
   }
   // Check for class declaration
   NamedDecl *CDeclU = LookupSingleName(TUScope, ClassName, ClassLocation,
@@ -643,11 +655,11 @@
     }
   }
   ObjCInterfaceDecl *CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(CDeclU);
-  if (CDecl == 0) {
+  if (!CDecl) {
     Diag(ClassLocation, diag::warn_undef_interface) << ClassName;
     if (CDeclU)
       Diag(CDeclU->getLocation(), diag::note_previous_declaration);
-    return 0;
+    return nullptr;
   }
 
   // Everything checked out, instantiate a new alias declaration AST.
@@ -701,8 +713,8 @@
   assert(ProtocolName && "Missing protocol identifier");
   ObjCProtocolDecl *PrevDecl = LookupProtocol(ProtocolName, ProtocolLoc,
                                               ForRedeclaration);
-  ObjCProtocolDecl *PDecl = 0;
-  if (ObjCProtocolDecl *Def = PrevDecl? PrevDecl->getDefinition() : 0) {
+  ObjCProtocolDecl *PDecl = nullptr;
+  if (ObjCProtocolDecl *Def = PrevDecl? PrevDecl->getDefinition() : nullptr) {
     // If we already have a definition, complain.
     Diag(ProtocolLoc, diag::warn_duplicate_protocol_def) << ProtocolName;
     Diag(Def->getLocation(), diag::note_previous_definition);
@@ -713,7 +725,7 @@
     // FIXME: Can we turn this into an error?
     PDecl = ObjCProtocolDecl::Create(Context, CurContext, ProtocolName,
                                      ProtocolLoc, AtProtoInterfaceLoc,
-                                     /*PrevDecl=*/0);
+                                     /*PrevDecl=*/nullptr);
     PDecl->startDefinition();
   } else {
     if (PrevDecl) {
@@ -751,6 +763,21 @@
   return ActOnObjCContainerStartDefinition(PDecl);
 }
 
+static bool NestedProtocolHasNoDefinition(ObjCProtocolDecl *PDecl,
+                                          ObjCProtocolDecl *&UndefinedProtocol) {
+  if (!PDecl->hasDefinition() || PDecl->getDefinition()->isHidden()) {
+    UndefinedProtocol = PDecl;
+    return true;
+  }
+  
+  for (auto *PI : PDecl->protocols())
+    if (NestedProtocolHasNoDefinition(PI, UndefinedProtocol)) {
+      UndefinedProtocol = PI;
+      return true;
+    }
+  return false;
+}
+
 /// FindProtocolDeclaration - This routine looks up protocols and
 /// issues an error if they are not declared. It returns list of
 /// protocol declarations in its 'Protocols' argument.
@@ -766,7 +793,8 @@
       DeclFilterCCC<ObjCProtocolDecl> Validator;
       TypoCorrection Corrected = CorrectTypo(
           DeclarationNameInfo(ProtocolId[i].first, ProtocolId[i].second),
-          LookupObjCProtocolName, TUScope, NULL, Validator);
+          LookupObjCProtocolName, TUScope, nullptr, Validator,
+          CTK_ErrorRecovery);
       if ((PDecl = Corrected.getCorrectionDeclAs<ObjCProtocolDecl>()))
         diagnoseTypo(Corrected, PDiag(diag::err_undeclared_protocol_suggest)
                                     << ProtocolId[i].first);
@@ -786,10 +814,15 @@
     // If this is a forward declaration and we are supposed to warn in this
     // case, do it.
     // FIXME: Recover nicely in the hidden case.
+    ObjCProtocolDecl *UndefinedProtocol;
+    
     if (WarnOnDeclarations &&
-        (!PDecl->hasDefinition() || PDecl->getDefinition()->isHidden()))
+        NestedProtocolHasNoDefinition(PDecl, UndefinedProtocol)) {
       Diag(ProtocolId[i].second, diag::warn_undef_protocolref)
         << ProtocolId[i].first;
+      Diag(UndefinedProtocol->getLocation(), diag::note_protocol_decl_undefined)
+        << UndefinedProtocol;
+    }
     Protocols.push_back(PDecl);
   }
 }
@@ -803,19 +836,16 @@
     return;  // Possibly due to previous error
 
   llvm::DenseMap<Selector, const ObjCMethodDecl*> MethodMap;
-  for (ObjCInterfaceDecl::method_iterator i = ID->meth_begin(),
-       e =  ID->meth_end(); i != e; ++i) {
-    ObjCMethodDecl *MD = *i;
+  for (auto *MD : ID->methods())
     MethodMap[MD->getSelector()] = MD;
-  }
 
   if (MethodMap.empty())
     return;
-  for (ObjCCategoryDecl::method_iterator i = CAT->meth_begin(),
-       e =  CAT->meth_end(); i != e; ++i) {
-    ObjCMethodDecl *Method = *i;
+  for (const auto *Method : CAT->methods()) {
     const ObjCMethodDecl *&PrevMethod = MethodMap[Method->getSelector()];
-    if (PrevMethod && !MatchTwoMethodDeclarations(Method, PrevMethod)) {
+    if (PrevMethod &&
+        (PrevMethod->isInstanceMethod() == Method->isInstanceMethod()) &&
+        !MatchTwoMethodDeclarations(Method, PrevMethod)) {
       Diag(Method->getLocation(), diag::err_duplicate_method_decl)
             << Method->getDeclName();
       Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
@@ -871,7 +901,7 @@
   if (!IDecl 
       || RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl),
                              diag::err_category_forward_interface,
-                             CategoryName == 0)) {
+                             CategoryName == nullptr)) {
     // Create an invalid ObjCCategoryDecl to serve as context for
     // the enclosing method declarations.  We mark the decl invalid
     // to make it clear that this isn't a valid AST.
@@ -928,7 +958,7 @@
                       IdentifierInfo *ClassName, SourceLocation ClassLoc,
                       IdentifierInfo *CatName, SourceLocation CatLoc) {
   ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName, ClassLoc, true);
-  ObjCCategoryDecl *CatIDecl = 0;
+  ObjCCategoryDecl *CatIDecl = nullptr;
   if (IDecl && IDecl->hasDefinition()) {
     CatIDecl = IDecl->FindCategoryDeclaration(CatName);
     if (!CatIDecl) {
@@ -987,7 +1017,7 @@
                       IdentifierInfo *ClassName, SourceLocation ClassLoc,
                       IdentifierInfo *SuperClassname,
                       SourceLocation SuperClassLoc) {
-  ObjCInterfaceDecl *IDecl = 0;
+  ObjCInterfaceDecl *IDecl = nullptr;
   // Check for another declaration kind with the same name.
   NamedDecl *PrevDecl
     = LookupSingleName(TUScope, ClassName, ClassLoc, LookupOrdinaryName,
@@ -1004,7 +1034,8 @@
     ObjCInterfaceValidatorCCC Validator;
     TypoCorrection Corrected =
             CorrectTypo(DeclarationNameInfo(ClassName, ClassLoc),
-                        LookupOrdinaryName, TUScope, NULL, Validator);
+                        LookupOrdinaryName, TUScope, nullptr, Validator,
+                        CTK_NonError);
     if (Corrected.getCorrectionDeclAs<ObjCInterfaceDecl>()) {
       // Suggest the (potentially) correct interface name. Don't provide a
       // code-modification hint or use the typo name for recovery, because
@@ -1018,7 +1049,7 @@
   }
 
   // Check that super class name is valid class name
-  ObjCInterfaceDecl* SDecl = 0;
+  ObjCInterfaceDecl *SDecl = nullptr;
   if (SuperClassname) {
     // Check if a different kind of symbol declared in this scope.
     PrevDecl = LookupSingleName(TUScope, SuperClassname, SuperClassLoc,
@@ -1030,7 +1061,7 @@
     } else {
       SDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
       if (SDecl && !SDecl->hasDefinition())
-        SDecl = 0;
+        SDecl = nullptr;
       if (!SDecl)
         Diag(SuperClassLoc, diag::err_undef_superclass)
           << SuperClassname << ClassName;
@@ -1051,7 +1082,7 @@
     // FIXME: Do we support attributes on the @implementation? If so we should
     // copy them over.
     IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtClassImplLoc,
-                                      ClassName, /*PrevDecl=*/0, ClassLoc, 
+                                      ClassName, /*PrevDecl=*/nullptr, ClassLoc,
                                       true);
     IDecl->startDefinition();
     if (SDecl) {
@@ -1154,11 +1185,7 @@
         continue;
       }
       // Check class extensions (unnamed categories) for duplicate ivars.
-      for (ObjCInterfaceDecl::visible_extensions_iterator
-           Ext = IDecl->visible_extensions_begin(),
-           ExtEnd = IDecl->visible_extensions_end();
-         Ext != ExtEnd; ++Ext) {
-        ObjCCategoryDecl *CDecl = *Ext;
+      for (const auto *CDecl : IDecl->visible_extensions()) {
         if (const ObjCIvarDecl *ClsExtIvar = 
             CDecl->getIvarDecl(ImplIvar->getIdentifier())) {
           Diag(ImplIvar->getLocation(), diag::err_duplicate_ivar_declaration); 
@@ -1209,13 +1236,16 @@
   }
 
   if (numIvars > 0)
-    Diag(ivars[j]->getLocation(), diag::err_inconsistant_ivar_count);
+    Diag(ivars[j]->getLocation(), diag::err_inconsistent_ivar_count);
   else if (IVI != IVE)
-    Diag(IVI->getLocation(), diag::err_inconsistant_ivar_count);
+    Diag(IVI->getLocation(), diag::err_inconsistent_ivar_count);
 }
 
-void Sema::WarnUndefinedMethod(SourceLocation ImpLoc, ObjCMethodDecl *method,
-                               bool &IncompleteImpl, unsigned DiagID) {
+static void WarnUndefinedMethod(Sema &S, SourceLocation ImpLoc,
+                                ObjCMethodDecl *method,
+                                bool &IncompleteImpl,
+                                unsigned DiagID,
+                                NamedDecl *NeededFor = nullptr) {
   // No point warning no definition of method which is 'unavailable'.
   switch (method->getAvailability()) {
   case AR_Available:
@@ -1233,13 +1263,17 @@
   // warning, but some users strongly voiced that they would prefer
   // separate warnings.  We will give that approach a try, as that
   // matches what we do with protocols.
-  
-  Diag(ImpLoc, DiagID) << method->getDeclName();
+  {
+    const Sema::SemaDiagnosticBuilder &B = S.Diag(ImpLoc, DiagID);
+    B << method;
+    if (NeededFor)
+      B << NeededFor;
+  }
 
   // Issue a note to the original declaration.
   SourceLocation MethodLoc = method->getLocStart();
   if (MethodLoc.isValid())
-    Diag(MethodLoc, diag::note_method_declared_at) << method;
+    S.Diag(MethodLoc, diag::note_method_declared_at) << method;
 }
 
 /// Determines if type B can be substituted for type A.  Returns true if we can
@@ -1323,21 +1357,21 @@
       (MethodDecl->getObjCDeclQualifier() !=
        MethodImpl->getObjCDeclQualifier())) {
     if (Warn) {
-        S.Diag(MethodImpl->getLocation(), 
-               (IsOverridingMode ? 
-                 diag::warn_conflicting_overriding_ret_type_modifiers 
-                 : diag::warn_conflicting_ret_type_modifiers))
+      S.Diag(MethodImpl->getLocation(),
+             (IsOverridingMode
+                  ? diag::warn_conflicting_overriding_ret_type_modifiers
+                  : diag::warn_conflicting_ret_type_modifiers))
           << MethodImpl->getDeclName()
-          << getTypeRange(MethodImpl->getResultTypeSourceInfo());
-        S.Diag(MethodDecl->getLocation(), diag::note_previous_declaration)
-          << getTypeRange(MethodDecl->getResultTypeSourceInfo());
+          << getTypeRange(MethodImpl->getReturnTypeSourceInfo());
+      S.Diag(MethodDecl->getLocation(), diag::note_previous_declaration)
+          << getTypeRange(MethodDecl->getReturnTypeSourceInfo());
     }
     else
       return false;
   }
-  
-  if (S.Context.hasSameUnqualifiedType(MethodImpl->getResultType(),
-                                       MethodDecl->getResultType()))
+
+  if (S.Context.hasSameUnqualifiedType(MethodImpl->getReturnType(),
+                                       MethodDecl->getReturnType()))
     return true;
   if (!Warn)
     return false;
@@ -1349,9 +1383,9 @@
   // Mismatches between ObjC pointers go into a different warning
   // category, and sometimes they're even completely whitelisted.
   if (const ObjCObjectPointerType *ImplPtrTy =
-        MethodImpl->getResultType()->getAs<ObjCObjectPointerType>()) {
+          MethodImpl->getReturnType()->getAs<ObjCObjectPointerType>()) {
     if (const ObjCObjectPointerType *IfacePtrTy =
-          MethodDecl->getResultType()->getAs<ObjCObjectPointerType>()) {
+            MethodDecl->getReturnType()->getAs<ObjCObjectPointerType>()) {
       // Allow non-matching return types as long as they don't violate
       // the principle of substitutability.  Specifically, we permit
       // return types that are subclasses of the declared return type,
@@ -1366,14 +1400,13 @@
   }
 
   S.Diag(MethodImpl->getLocation(), DiagID)
-    << MethodImpl->getDeclName()
-    << MethodDecl->getResultType()
-    << MethodImpl->getResultType()
-    << getTypeRange(MethodImpl->getResultTypeSourceInfo());
-  S.Diag(MethodDecl->getLocation(), 
-         IsOverridingMode ? diag::note_previous_declaration 
-                          : diag::note_previous_definition)
-    << getTypeRange(MethodDecl->getResultTypeSourceInfo());
+      << MethodImpl->getDeclName() << MethodDecl->getReturnType()
+      << MethodImpl->getReturnType()
+      << getTypeRange(MethodImpl->getReturnTypeSourceInfo());
+  S.Diag(MethodDecl->getLocation(), IsOverridingMode
+                                        ? diag::note_previous_declaration
+                                        : diag::note_previous_definition)
+      << getTypeRange(MethodDecl->getReturnTypeSourceInfo());
   return false;
 }
 
@@ -1505,7 +1538,7 @@
 
   // The only reason these methods don't fall within their families is
   // due to unusual result types.
-  if (unmatched->getResultType()->isObjCObjectPointerType()) {
+  if (unmatched->getReturnType()->isObjCObjectPointerType()) {
     reasonSelector = R_UnrelatedReturn;
   } else {
     reasonSelector = R_NonObjectReturn;
@@ -1615,22 +1648,75 @@
 /// we used an immutable set to keep the table then it wouldn't add significant
 /// memory cost and it would be handy for lookups.
 
+typedef llvm::DenseSet<IdentifierInfo*> ProtocolNameSet;
+typedef std::unique_ptr<ProtocolNameSet> LazyProtocolNameSet;
+
+static void findProtocolsWithExplicitImpls(const ObjCProtocolDecl *PDecl,
+                                           ProtocolNameSet &PNS) {
+  if (PDecl->hasAttr<ObjCExplicitProtocolImplAttr>())
+    PNS.insert(PDecl->getIdentifier());
+  for (const auto *PI : PDecl->protocols())
+    findProtocolsWithExplicitImpls(PI, PNS);
+}
+
+/// Recursively populates a set with all conformed protocols in a class
+/// hierarchy that have the 'objc_protocol_requires_explicit_implementation'
+/// attribute.
+static void findProtocolsWithExplicitImpls(const ObjCInterfaceDecl *Super,
+                                           ProtocolNameSet &PNS) {
+  if (!Super)
+    return;
+
+  for (const auto *I : Super->all_referenced_protocols())
+    findProtocolsWithExplicitImpls(I, PNS);
+
+  findProtocolsWithExplicitImpls(Super->getSuperClass(), PNS);
+}
+
 /// CheckProtocolMethodDefs - This routine checks unimplemented methods
 /// Declared in protocol, and those referenced by it.
-void Sema::CheckProtocolMethodDefs(SourceLocation ImpLoc,
-                                   ObjCProtocolDecl *PDecl,
-                                   bool& IncompleteImpl,
-                                   const SelectorSet &InsMap,
-                                   const SelectorSet &ClsMap,
-                                   ObjCContainerDecl *CDecl) {
+static void CheckProtocolMethodDefs(Sema &S,
+                                    SourceLocation ImpLoc,
+                                    ObjCProtocolDecl *PDecl,
+                                    bool& IncompleteImpl,
+                                    const Sema::SelectorSet &InsMap,
+                                    const Sema::SelectorSet &ClsMap,
+                                    ObjCContainerDecl *CDecl,
+                                    LazyProtocolNameSet &ProtocolsExplictImpl) {
   ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl);
   ObjCInterfaceDecl *IDecl = C ? C->getClassInterface() 
                                : dyn_cast<ObjCInterfaceDecl>(CDecl);
   assert (IDecl && "CheckProtocolMethodDefs - IDecl is null");
   
   ObjCInterfaceDecl *Super = IDecl->getSuperClass();
-  ObjCInterfaceDecl *NSIDecl = 0;
-  if (getLangOpts().ObjCRuntime.isNeXTFamily()) {
+  ObjCInterfaceDecl *NSIDecl = nullptr;
+
+  // If this protocol is marked 'objc_protocol_requires_explicit_implementation'
+  // then we should check if any class in the super class hierarchy also
+  // conforms to this protocol, either directly or via protocol inheritance.
+  // If so, we can skip checking this protocol completely because we
+  // know that a parent class already satisfies this protocol.
+  //
+  // Note: we could generalize this logic for all protocols, and merely
+  // add the limit on looking at the super class chain for just
+  // specially marked protocols.  This may be a good optimization.  This
+  // change is restricted to 'objc_protocol_requires_explicit_implementation'
+  // protocols for now for controlled evaluation.
+  if (PDecl->hasAttr<ObjCExplicitProtocolImplAttr>()) {
+    if (!ProtocolsExplictImpl) {
+      ProtocolsExplictImpl.reset(new ProtocolNameSet);
+      findProtocolsWithExplicitImpls(Super, *ProtocolsExplictImpl);
+    }
+    if (ProtocolsExplictImpl->find(PDecl->getIdentifier()) !=
+        ProtocolsExplictImpl->end())
+      return;
+
+    // If no super class conforms to the protocol, we should not search
+    // for methods in the super class to implicitly satisfy the protocol.
+    Super = nullptr;
+  }
+
+  if (S.getLangOpts().ObjCRuntime.isNeXTFamily()) {
     // check to see if class implements forwardInvocation method and objects
     // of this class are derived from 'NSProxy' so that to forward requests
     // from one object to another.
@@ -1638,12 +1724,12 @@
     // implemented in the class, we should not issue "Method definition not
     // found" warnings.
     // FIXME: Use a general GetUnarySelector method for this.
-    IdentifierInfo* II = &Context.Idents.get("forwardInvocation");
-    Selector fISelector = Context.Selectors.getSelector(1, &II);
+    IdentifierInfo* II = &S.Context.Idents.get("forwardInvocation");
+    Selector fISelector = S.Context.Selectors.getSelector(1, &II);
     if (InsMap.count(fISelector))
       // Is IDecl derived from 'NSProxy'? If so, no instance methods
       // need be implemented in the implementation.
-      NSIDecl = IDecl->lookupInheritedClass(&Context.Idents.get("NSProxy"));
+      NSIDecl = IDecl->lookupInheritedClass(&S.Context.Idents.get("NSProxy"));
   }
 
   // If this is a forward protocol declaration, get its definition.
@@ -1658,13 +1744,15 @@
 
   // check unimplemented instance methods.
   if (!NSIDecl)
-    for (ObjCProtocolDecl::instmeth_iterator I = PDecl->instmeth_begin(),
-         E = PDecl->instmeth_end(); I != E; ++I) {
-      ObjCMethodDecl *method = *I;
+    for (auto *method : PDecl->instance_methods()) {
       if (method->getImplementationControl() != ObjCMethodDecl::Optional &&
           !method->isPropertyAccessor() &&
           !InsMap.count(method->getSelector()) &&
-          (!Super || !Super->lookupInstanceMethod(method->getSelector()))) {
+          (!Super || !Super->lookupMethod(method->getSelector(),
+                                          true /* instance */,
+                                          false /* shallowCategory */,
+                                          true /* followsSuper */,
+                                          nullptr /* category */))) {
             // If a method is not implemented in the category implementation but
             // has been declared in its primary class, superclass,
             // or in one of their protocols, no need to issue the warning. 
@@ -1675,44 +1763,45 @@
             // have been synthesized due to a property declared in the class which
             // uses the protocol.
             if (ObjCMethodDecl *MethodInClass =
-                  IDecl->lookupInstanceMethod(method->getSelector(), 
-                                              true /*shallowCategoryLookup*/))
+                  IDecl->lookupMethod(method->getSelector(),
+                                      true /* instance */,
+                                      true /* shallowCategoryLookup */,
+                                      false /* followSuper */))
               if (C || MethodInClass->isPropertyAccessor())
                 continue;
             unsigned DIAG = diag::warn_unimplemented_protocol_method;
-            if (Diags.getDiagnosticLevel(DIAG, ImpLoc)
-                != DiagnosticsEngine::Ignored) {
-              WarnUndefinedMethod(ImpLoc, method, IncompleteImpl, DIAG);
-              Diag(CDecl->getLocation(), diag::note_required_for_protocol_at)
-                << PDecl->getDeclName();
+            if (!S.Diags.isIgnored(DIAG, ImpLoc)) {
+              WarnUndefinedMethod(S, ImpLoc, method, IncompleteImpl, DIAG,
+                                  PDecl);
             }
           }
     }
   // check unimplemented class methods
-  for (ObjCProtocolDecl::classmeth_iterator
-         I = PDecl->classmeth_begin(), E = PDecl->classmeth_end();
-       I != E; ++I) {
-    ObjCMethodDecl *method = *I;
+  for (auto *method : PDecl->class_methods()) {
     if (method->getImplementationControl() != ObjCMethodDecl::Optional &&
         !ClsMap.count(method->getSelector()) &&
-        (!Super || !Super->lookupClassMethod(method->getSelector()))) {
+        (!Super || !Super->lookupMethod(method->getSelector(),
+                                        false /* class method */,
+                                        false /* shallowCategoryLookup */,
+                                        true  /* followSuper */,
+                                        nullptr /* category */))) {
       // See above comment for instance method lookups.
-      if (C && IDecl->lookupClassMethod(method->getSelector(), 
-                                        true /*shallowCategoryLookup*/))
+      if (C && IDecl->lookupMethod(method->getSelector(),
+                                   false /* class */,
+                                   true /* shallowCategoryLookup */,
+                                   false /* followSuper */))
         continue;
+
       unsigned DIAG = diag::warn_unimplemented_protocol_method;
-      if (Diags.getDiagnosticLevel(DIAG, ImpLoc) !=
-            DiagnosticsEngine::Ignored) {
-        WarnUndefinedMethod(ImpLoc, method, IncompleteImpl, DIAG);
-        Diag(IDecl->getLocation(), diag::note_required_for_protocol_at) <<
-          PDecl->getDeclName();
+      if (!S.Diags.isIgnored(DIAG, ImpLoc)) {
+        WarnUndefinedMethod(S, ImpLoc, method, IncompleteImpl, DIAG, PDecl);
       }
     }
   }
   // Check on this protocols's referenced protocols, recursively.
-  for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
-       E = PDecl->protocol_end(); PI != E; ++PI)
-    CheckProtocolMethodDefs(ImpLoc, *PI, IncompleteImpl, InsMap, ClsMap, CDecl);
+  for (auto *PI : PDecl->protocols())
+    CheckProtocolMethodDefs(S, ImpLoc, PI, IncompleteImpl, InsMap, ClsMap,
+                            CDecl, ProtocolsExplictImpl);
 }
 
 /// MatchAllMethodDeclarations - Check methods declared in interface
@@ -1729,56 +1818,50 @@
                                       bool WarnCategoryMethodImpl) {
   // Check and see if instance methods in class interface have been
   // implemented in the implementation class. If so, their types match.
-  for (ObjCInterfaceDecl::instmeth_iterator I = CDecl->instmeth_begin(),
-       E = CDecl->instmeth_end(); I != E; ++I) {
-    if (!InsMapSeen.insert((*I)->getSelector()))
+  for (auto *I : CDecl->instance_methods()) {
+    if (!InsMapSeen.insert(I->getSelector()))
       continue;
-    if (!(*I)->isPropertyAccessor() &&
-        !InsMap.count((*I)->getSelector())) {
+    if (!I->isPropertyAccessor() &&
+        !InsMap.count(I->getSelector())) {
       if (ImmediateClass)
-        WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl,
+        WarnUndefinedMethod(*this, IMPDecl->getLocation(), I, IncompleteImpl,
                             diag::warn_undef_method_impl);
       continue;
     } else {
       ObjCMethodDecl *ImpMethodDecl =
-        IMPDecl->getInstanceMethod((*I)->getSelector());
-      assert(CDecl->getInstanceMethod((*I)->getSelector()) &&
+        IMPDecl->getInstanceMethod(I->getSelector());
+      assert(CDecl->getInstanceMethod(I->getSelector()) &&
              "Expected to find the method through lookup as well");
-      ObjCMethodDecl *MethodDecl = *I;
       // ImpMethodDecl may be null as in a @dynamic property.
       if (ImpMethodDecl) {
         if (!WarnCategoryMethodImpl)
-          WarnConflictingTypedMethods(ImpMethodDecl, MethodDecl,
+          WarnConflictingTypedMethods(ImpMethodDecl, I,
                                       isa<ObjCProtocolDecl>(CDecl));
-        else if (!MethodDecl->isPropertyAccessor())
-          WarnExactTypedMethods(ImpMethodDecl, MethodDecl,
-                                isa<ObjCProtocolDecl>(CDecl));
+        else if (!I->isPropertyAccessor())
+          WarnExactTypedMethods(ImpMethodDecl, I, isa<ObjCProtocolDecl>(CDecl));
       }
     }
   }
 
   // Check and see if class methods in class interface have been
   // implemented in the implementation class. If so, their types match.
-  for (ObjCInterfaceDecl::classmeth_iterator I = CDecl->classmeth_begin(),
-                                             E = CDecl->classmeth_end();
-       I != E; ++I) {
-    if (!ClsMapSeen.insert((*I)->getSelector()))
+  for (auto *I : CDecl->class_methods()) {
+    if (!ClsMapSeen.insert(I->getSelector()))
       continue;
-    if (!ClsMap.count((*I)->getSelector())) {
+    if (!ClsMap.count(I->getSelector())) {
       if (ImmediateClass)
-        WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl,
+        WarnUndefinedMethod(*this, IMPDecl->getLocation(), I, IncompleteImpl,
                             diag::warn_undef_method_impl);
     } else {
       ObjCMethodDecl *ImpMethodDecl =
-        IMPDecl->getClassMethod((*I)->getSelector());
-      assert(CDecl->getClassMethod((*I)->getSelector()) &&
+        IMPDecl->getClassMethod(I->getSelector());
+      assert(CDecl->getClassMethod(I->getSelector()) &&
              "Expected to find the method through lookup as well");
-      ObjCMethodDecl *MethodDecl = *I;
       if (!WarnCategoryMethodImpl)
-        WarnConflictingTypedMethods(ImpMethodDecl, MethodDecl, 
+        WarnConflictingTypedMethods(ImpMethodDecl, I, 
                                     isa<ObjCProtocolDecl>(CDecl));
       else
-        WarnExactTypedMethods(ImpMethodDecl, MethodDecl,
+        WarnExactTypedMethods(ImpMethodDecl, I,
                               isa<ObjCProtocolDecl>(CDecl));
     }
   }
@@ -1786,10 +1869,9 @@
   if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl> (CDecl)) {
     // Also, check for methods declared in protocols inherited by
     // this protocol.
-    for (ObjCProtocolDecl::protocol_iterator
-          PI = PD->protocol_begin(), E = PD->protocol_end(); PI != E; ++PI)
+    for (auto *PI : PD->protocols())
       MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
-                                 IMPDecl, (*PI), IncompleteImpl, false,
+                                 IMPDecl, PI, IncompleteImpl, false,
                                  WarnCategoryMethodImpl);
   }
   
@@ -1798,35 +1880,24 @@
     // i.e. when WarnCategoryMethodImpl is false, check declarations in class
     // extension; as well as those in categories.
     if (!WarnCategoryMethodImpl) {
-      for (ObjCInterfaceDecl::visible_categories_iterator
-             Cat = I->visible_categories_begin(),
-           CatEnd = I->visible_categories_end();
-           Cat != CatEnd; ++Cat) {
+      for (auto *Cat : I->visible_categories())
         MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
-                                   IMPDecl, *Cat, IncompleteImpl, false,
+                                   IMPDecl, Cat, IncompleteImpl, false,
                                    WarnCategoryMethodImpl);
-      }
     } else {
       // Also methods in class extensions need be looked at next.
-      for (ObjCInterfaceDecl::visible_extensions_iterator
-             Ext = I->visible_extensions_begin(),
-             ExtEnd = I->visible_extensions_end();
-           Ext != ExtEnd; ++Ext) {
+      for (auto *Ext : I->visible_extensions())
         MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
-                                   IMPDecl, *Ext, IncompleteImpl, false,
+                                   IMPDecl, Ext, IncompleteImpl, false,
                                    WarnCategoryMethodImpl);
-      }
     }
 
     // Check for any implementation of a methods declared in protocol.
-    for (ObjCInterfaceDecl::all_protocol_iterator
-          PI = I->all_referenced_protocol_begin(),
-          E = I->all_referenced_protocol_end(); PI != E; ++PI)
+    for (auto *PI : I->all_referenced_protocols())
       MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
-                                 IMPDecl,
-                                 (*PI), IncompleteImpl, false, 
+                                 IMPDecl, PI, IncompleteImpl, false,
                                  WarnCategoryMethodImpl);
-    
+
     // FIXME. For now, we are not checking for extact match of methods 
     // in category implementation and its primary class's super class. 
     if (!WarnCategoryMethodImpl && I->getSuperClass())
@@ -1841,20 +1912,6 @@
 /// warns each time an exact match is found. 
 void Sema::CheckCategoryVsClassMethodMatches(
                                   ObjCCategoryImplDecl *CatIMPDecl) {
-  SelectorSet InsMap, ClsMap;
-  
-  for (ObjCImplementationDecl::instmeth_iterator
-       I = CatIMPDecl->instmeth_begin(), 
-       E = CatIMPDecl->instmeth_end(); I!=E; ++I)
-    InsMap.insert((*I)->getSelector());
-  
-  for (ObjCImplementationDecl::classmeth_iterator
-       I = CatIMPDecl->classmeth_begin(),
-       E = CatIMPDecl->classmeth_end(); I != E; ++I)
-    ClsMap.insert((*I)->getSelector());
-  if (InsMap.empty() && ClsMap.empty())
-    return;
-  
   // Get category's primary class.
   ObjCCategoryDecl *CatDecl = CatIMPDecl->getCategoryDecl();
   if (!CatDecl)
@@ -1862,6 +1919,28 @@
   ObjCInterfaceDecl *IDecl = CatDecl->getClassInterface();
   if (!IDecl)
     return;
+  ObjCInterfaceDecl *SuperIDecl = IDecl->getSuperClass();
+  SelectorSet InsMap, ClsMap;
+  
+  for (const auto *I : CatIMPDecl->instance_methods()) {
+    Selector Sel = I->getSelector();
+    // When checking for methods implemented in the category, skip over
+    // those declared in category class's super class. This is because
+    // the super class must implement the method.
+    if (SuperIDecl && SuperIDecl->lookupMethod(Sel, true))
+      continue;
+    InsMap.insert(Sel);
+  }
+  
+  for (const auto *I : CatIMPDecl->class_methods()) {
+    Selector Sel = I->getSelector();
+    if (SuperIDecl && SuperIDecl->lookupMethod(Sel, false))
+      continue;
+    ClsMap.insert(Sel);
+  }
+  if (InsMap.empty() && ClsMap.empty())
+    return;
+  
   SelectorSet InsMapSeen, ClsMapSeen;
   bool IncompleteImpl = false;
   MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
@@ -1876,24 +1955,22 @@
   SelectorSet InsMap;
   // Check and see if instance methods in class interface have been
   // implemented in the implementation class.
-  for (ObjCImplementationDecl::instmeth_iterator
-         I = IMPDecl->instmeth_begin(), E = IMPDecl->instmeth_end(); I!=E; ++I)
-    InsMap.insert((*I)->getSelector());
+  for (const auto *I : IMPDecl->instance_methods())
+    InsMap.insert(I->getSelector());
 
   // Check and see if properties declared in the interface have either 1)
   // an implementation or 2) there is a @synthesize/@dynamic implementation
   // of the property in the @implementation.
-  if (const ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl))
-    if  (!(LangOpts.ObjCDefaultSynthProperties &&
-           LangOpts.ObjCRuntime.isNonFragile()) ||
-         IDecl->isObjCRequiresPropertyDefs())
-      DiagnoseUnimplementedProperties(S, IMPDecl, CDecl);
-      
+  if (const ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)) {
+    bool SynthesizeProperties = LangOpts.ObjCDefaultSynthProperties &&
+                                LangOpts.ObjCRuntime.isNonFragile() &&
+                                !IDecl->isObjCRequiresPropertyDefs();
+    DiagnoseUnimplementedProperties(S, IMPDecl, CDecl, SynthesizeProperties);
+  }
+
   SelectorSet ClsMap;
-  for (ObjCImplementationDecl::classmeth_iterator
-       I = IMPDecl->classmeth_begin(),
-       E = IMPDecl->classmeth_end(); I != E; ++I)
-    ClsMap.insert((*I)->getSelector());
+  for (const auto *I : IMPDecl->class_methods())
+    ClsMap.insert(I->getSelector());
 
   // Check for type conflict of methods declared in a class/protocol and
   // its implementation; if any.
@@ -1913,28 +1990,25 @@
   // Check and see if class methods in class interface have been
   // implemented in the implementation class.
 
+  LazyProtocolNameSet ExplicitImplProtocols;
+
   if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl> (CDecl)) {
-    for (ObjCInterfaceDecl::all_protocol_iterator
-          PI = I->all_referenced_protocol_begin(),
-          E = I->all_referenced_protocol_end(); PI != E; ++PI)
-      CheckProtocolMethodDefs(IMPDecl->getLocation(), *PI, IncompleteImpl,
-                              InsMap, ClsMap, I);
+    for (auto *PI : I->all_referenced_protocols())
+      CheckProtocolMethodDefs(*this, IMPDecl->getLocation(), PI, IncompleteImpl,
+                              InsMap, ClsMap, I, ExplicitImplProtocols);
     // Check class extensions (unnamed categories)
-    for (ObjCInterfaceDecl::visible_extensions_iterator
-           Ext = I->visible_extensions_begin(),
-           ExtEnd = I->visible_extensions_end();
-         Ext != ExtEnd; ++Ext) {
-      ImplMethodsVsClassMethods(S, IMPDecl, *Ext, IncompleteImpl);
-    }
+    for (auto *Ext : I->visible_extensions())
+      ImplMethodsVsClassMethods(S, IMPDecl, Ext, IncompleteImpl);
   } else if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl)) {
     // For extended class, unimplemented methods in its protocols will
     // be reported in the primary class.
     if (!C->IsClassExtension()) {
-      for (ObjCCategoryDecl::protocol_iterator PI = C->protocol_begin(),
-           E = C->protocol_end(); PI != E; ++PI)
-        CheckProtocolMethodDefs(IMPDecl->getLocation(), *PI, IncompleteImpl,
-                                InsMap, ClsMap, CDecl);
-      DiagnoseUnimplementedProperties(S, IMPDecl, CDecl);
+      for (auto *P : C->protocols())
+        CheckProtocolMethodDefs(*this, IMPDecl->getLocation(), P,
+                                IncompleteImpl, InsMap, ClsMap, CDecl,
+                                ExplicitImplProtocols);
+      DiagnoseUnimplementedProperties(S, IMPDecl, CDecl,
+                                      /* SynthesizeProperties */ false);
     } 
   } else
     llvm_unreachable("invalid ObjCContainerDecl type.");
@@ -2103,8 +2177,8 @@
 bool Sema::MatchTwoMethodDeclarations(const ObjCMethodDecl *left,
                                       const ObjCMethodDecl *right,
                                       MethodMatchStrategy strategy) {
-  if (!matchTypes(Context, strategy,
-                  left->getResultType(), right->getResultType()))
+  if (!matchTypes(Context, strategy, left->getReturnType(),
+                  right->getReturnType()))
     return false;
 
   // If either is hidden, it is not considered to match.
@@ -2145,9 +2219,9 @@
         List->setBits(List->getBits()+1);
 
   // If the list is empty, make it a singleton list.
-  if (List->Method == 0) {
+  if (List->Method == nullptr) {
     List->Method = Method;
-    List->setNext(0);
+    List->setNext(nullptr);
     return;
   }
   
@@ -2187,7 +2261,7 @@
   // We have a new signature for an existing method - add it.
   // This is extremely rare. Only 1% of Cocoa selectors are "overloaded".
   ObjCMethodList *Mem = BumpAlloc.Allocate<ObjCMethodList>();
-  Previous->setNext(new (Mem) ObjCMethodList(Method, 0));
+  Previous->setNext(new (Mem) ObjCMethodList(Method, nullptr));
 }
 
 /// \brief Read the contents of the method pool for a given selector from
@@ -2233,7 +2307,7 @@
 
   // Don't complain about mismatches for -length if the method we
   // chose has an integral result type.
-  return (chosen->getResultType()->isIntegerType());
+  return (chosen->getReturnType()->isIntegerType());
 }
 
 ObjCMethodDecl *Sema::LookupMethodInGlobalPool(Selector Sel, SourceRange R,
@@ -2244,7 +2318,7 @@
     
   GlobalMethodPool::iterator Pos = MethodPool.find(Sel);
   if (Pos == MethodPool.end())
-    return 0;
+    return nullptr;
 
   // Gather the non-hidden methods.
   ObjCMethodList &MethList = instance ? Pos->second.first : Pos->second.second;
@@ -2262,7 +2336,7 @@
   // If there aren't any visible methods, we're done.
   // FIXME: Recover if there are any known-but-hidden methods?
   if (Methods.empty())
-    return 0;
+    return nullptr;
 
   if (Methods.size() == 1)
     return Methods[0];
@@ -2273,10 +2347,8 @@
   // We support a warning which complains about *any* difference in
   // method signature.
   bool strictSelectorMatch =
-    (receiverIdOrClass && warn &&
-     (Diags.getDiagnosticLevel(diag::warn_strict_multiple_method_decl,
-                               R.getBegin())
-        != DiagnosticsEngine::Ignored));
+      receiverIdOrClass && warn &&
+      !Diags.isIgnored(diag::warn_strict_multiple_method_decl, R.getBegin());
   if (strictSelectorMatch) {
     for (unsigned I = 1, N = Methods.size(); I != N; ++I) {
       if (!MatchTwoMethodDeclarations(Methods[0], Methods[I], MMS_strict)) {
@@ -2324,15 +2396,19 @@
 ObjCMethodDecl *Sema::LookupImplementedMethodInGlobalPool(Selector Sel) {
   GlobalMethodPool::iterator Pos = MethodPool.find(Sel);
   if (Pos == MethodPool.end())
-    return 0;
+    return nullptr;
 
   GlobalMethods &Methods = Pos->second;
-
-  if (Methods.first.Method && Methods.first.Method->isDefined())
-    return Methods.first.Method;
-  if (Methods.second.Method && Methods.second.Method->isDefined())
-    return Methods.second.Method;
-  return 0;
+  for (const ObjCMethodList *Method = &Methods.first; Method;
+       Method = Method->getNext())
+    if (Method->Method && Method->Method->isDefined())
+      return Method->Method;
+  
+  for (const ObjCMethodList *Method = &Methods.second; Method;
+       Method = Method->getNext())
+    if (Method->Method && Method->Method->isDefined())
+      return Method->Method;
+  return nullptr;
 }
 
 static void
@@ -2364,7 +2440,8 @@
     return true;
   if (S.LookupMethodInObjectType(Sel, ObjectType, true/*Instance method*/))
     return true;
-  return S.LookupMethodInObjectType(Sel, ObjectType, false/*Class method*/) != 0;
+  return S.LookupMethodInObjectType(Sel, ObjectType, false/*Class method*/) !=
+         nullptr;
 }
 
 const ObjCMethodDecl *
@@ -2376,7 +2453,7 @@
   if (ObjectType.isNull())
     ObjectIsId = ObjectIsClass = false;
   else if (!ObjectType->isObjCObjectPointerType())
-    return 0;
+    return nullptr;
   else if (const ObjCObjectPointerType *ObjCPtr =
            ObjectType->getAsObjCInterfacePointerType()) {
     ObjectType = QualType(ObjCPtr->getInterfaceType(), 0);
@@ -2387,8 +2464,8 @@
   else if (ObjectType->isObjCClassType() || ObjectType->isObjCQualifiedClassType())
     ObjectIsId = false;
   else
-    return 0;
-  
+    return nullptr;
+
   for (GlobalMethodPool::iterator b = MethodPool.begin(),
        e = MethodPool.end(); b != e; b++) {
     // instance methods
@@ -2420,52 +2497,7 @@
     HelperSelectorsForTypoCorrection(SelectedMethods,
                                      Sel.getAsString(), Methods[i]);
   }
-  return (SelectedMethods.size() == 1) ? SelectedMethods[0] : NULL;
-}
-
-static void
-HelperToDiagnoseMismatchedMethodsInGlobalPool(Sema &S,
-                                              ObjCMethodList &MethList) {
-  ObjCMethodList *M = &MethList;
-  ObjCMethodDecl *TargetMethod = M->Method;
-  while (TargetMethod &&
-         isa<ObjCImplDecl>(TargetMethod->getDeclContext())) {
-    M = M->getNext();
-    TargetMethod = M ? M->Method : 0;
-  }
-  if (!TargetMethod)
-    return;
-  bool FirstTime = true;
-  for (M = M->getNext(); M; M=M->getNext()) {
-    ObjCMethodDecl *MatchingMethodDecl = M->Method;
-    if (isa<ObjCImplDecl>(MatchingMethodDecl->getDeclContext()))
-      continue;
-    if (!S.MatchTwoMethodDeclarations(TargetMethod,
-                                      MatchingMethodDecl, Sema::MMS_loose)) {
-      if (FirstTime) {
-        FirstTime = false;
-        S.Diag(TargetMethod->getLocation(), diag::warning_multiple_selectors)
-        << TargetMethod->getSelector();
-      }
-      S.Diag(MatchingMethodDecl->getLocation(), diag::note_also_found);
-    }
-  }
-}
-
-void Sema::DiagnoseMismatchedMethodsInGlobalPool() {
-  unsigned DIAG = diag::warning_multiple_selectors;
-  if (Diags.getDiagnosticLevel(DIAG, SourceLocation())
-      == DiagnosticsEngine::Ignored)
-    return;
-  for (GlobalMethodPool::iterator b = MethodPool.begin(),
-       e = MethodPool.end(); b != e; b++) {
-    // first, instance methods
-    ObjCMethodList &InstMethList = b->second.first;
-    HelperToDiagnoseMismatchedMethodsInGlobalPool(*this, InstMethList);
-    // second, class methods
-    ObjCMethodList &ClsMethList = b->second.second;
-    HelperToDiagnoseMismatchedMethodsInGlobalPool(*this, ClsMethList);
-  }
+  return (SelectedMethods.size() == 1) ? SelectedMethods[0] : nullptr;
 }
 
 /// DiagnoseDuplicateIvars -
@@ -2475,9 +2507,7 @@
 /// class's \@implementation is seen.
 void Sema::DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID, 
                                   ObjCInterfaceDecl *SID) {
-  for (ObjCInterfaceDecl::ivar_iterator IVI = ID->ivar_begin(),
-       IVE = ID->ivar_end(); IVI != IVE; ++IVI) {
-    ObjCIvarDecl* Ivar = *IVI;
+  for (auto *Ivar : ID->ivars()) {
     if (Ivar->isInvalidDecl())
       continue;
     if (IdentifierInfo *II = Ivar->getIdentifier()) {
@@ -2516,7 +2546,7 @@
 Decl *Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd, ArrayRef<Decl *> allMethods,
                        ArrayRef<DeclGroupPtrTy> allTUVars) {
   if (getObjCContainerKind() == Sema::OCK_None)
-    return 0;
+    return nullptr;
 
   assert(AtEnd.isValid() && "Invalid location for '@end'");
 
@@ -2603,10 +2633,8 @@
       // ProcessPropertyDecl is responsible for diagnosing conflicts with any
       // user-defined setter/getter. It also synthesizes setter/getter methods
       // and adds them to the DeclContext and global method pools.
-      for (ObjCContainerDecl::prop_iterator I = CDecl->prop_begin(),
-                                            E = CDecl->prop_end();
-           I != E; ++I)
-        ProcessPropertyDecl(*I, CDecl);
+      for (auto *I : CDecl->properties())
+        ProcessPropertyDecl(I, CDecl);
     CDecl->setAtEndRange(AtEnd);
   }
   if (ObjCImplementationDecl *IC=dyn_cast<ObjCImplementationDecl>(ClassDecl)) {
@@ -2617,13 +2645,8 @@
       // of the other class extensions. Mark them as synthesized as
       // property will be synthesized when property with same name is
       // seen in the @implementation.
-      for (ObjCInterfaceDecl::visible_extensions_iterator
-             Ext = IDecl->visible_extensions_begin(),
-             ExtEnd = IDecl->visible_extensions_end();
-           Ext != ExtEnd; ++Ext) {
-        for (ObjCContainerDecl::prop_iterator I = Ext->prop_begin(),
-             E = Ext->prop_end(); I != E; ++I) {
-          ObjCPropertyDecl *Property = *I;
+      for (const auto *Ext : IDecl->visible_extensions()) {
+        for (const auto *Property : Ext->properties()) {
           // Skip over properties declared @dynamic
           if (const ObjCPropertyImplDecl *PIDecl
               = IC->FindPropertyImplDecl(Property->getIdentifier()))
@@ -2631,10 +2654,7 @@
                   == ObjCPropertyImplDecl::Dynamic)
               continue;
 
-          for (ObjCInterfaceDecl::visible_extensions_iterator
-                 Ext = IDecl->visible_extensions_begin(),
-                 ExtEnd = IDecl->visible_extensions_end();
-               Ext != ExtEnd; ++Ext) {
+          for (const auto *Ext : IDecl->visible_extensions()) {
             if (ObjCMethodDecl *GetterMethod
                   = Ext->getInstanceMethod(Property->getGetterName()))
               GetterMethod->setPropertyAccessor(true);
@@ -2648,14 +2668,17 @@
       ImplMethodsVsClassMethods(S, IC, IDecl);
       AtomicPropertySetterGetterRules(IC, IDecl);
       DiagnoseOwningPropertyGetterSynthesis(IC);
-  
+      DiagnoseUnusedBackingIvarInAccessor(S, IC);
+      if (IDecl->hasDesignatedInitializers())
+        DiagnoseMissingDesignatedInitOverrides(IC, IDecl);
+
       bool HasRootClassAttr = IDecl->hasAttr<ObjCRootClassAttr>();
-      if (IDecl->getSuperClass() == NULL) {
+      if (IDecl->getSuperClass() == nullptr) {
         // This class has no superclass, so check that it has been marked with
         // __attribute((objc_root_class)).
         if (!HasRootClassAttr) {
           SourceLocation DeclLoc(IDecl->getLocation());
-          SourceLocation SuperClassLoc(PP.getLocForEndOfToken(DeclLoc));
+          SourceLocation SuperClassLoc(getLocForEndOfToken(DeclLoc));
           Diag(DeclLoc, diag::warn_objc_root_class_missing)
             << IDecl->getIdentifier();
           // See if NSObject is in the current scope, and if it is, suggest
@@ -2729,72 +2752,14 @@
   return (Decl::ObjCDeclQualifier) (unsigned) PQTVal;
 }
 
-static inline
-unsigned countAlignAttr(const AttrVec &A) {
-  unsigned count=0;
-  for (AttrVec::const_iterator i = A.begin(), e = A.end(); i != e; ++i)
-    if ((*i)->getKind() == attr::Aligned)
-      ++count;
-  return count;
-}
-
-static inline
-bool containsInvalidMethodImplAttribute(ObjCMethodDecl *IMD,
-                                        const AttrVec &A) {
-  // If method is only declared in implementation (private method),
-  // No need to issue any diagnostics on method definition with attributes.
-  if (!IMD)
-    return false;
-  
-  // method declared in interface has no attribute. 
-  // But implementation has attributes. This is invalid.
-  // Except when implementation has 'Align' attribute which is
-  // immaterial to method declared in interface.
-  if (!IMD->hasAttrs())
-    return (A.size() > countAlignAttr(A));
-
-  const AttrVec &D = IMD->getAttrs();
-
-  unsigned countAlignOnImpl = countAlignAttr(A);
-  if (!countAlignOnImpl && (A.size() != D.size()))
-    return true;
-  else if (countAlignOnImpl) {
-    unsigned countAlignOnDecl = countAlignAttr(D);
-    if (countAlignOnDecl && (A.size() != D.size()))
-      return true;
-    else if (!countAlignOnDecl && 
-             ((A.size()-countAlignOnImpl) != D.size()))
-      return true;
-  }
-  
-  // attributes on method declaration and definition must match exactly.
-  // Note that we have at most a couple of attributes on methods, so this
-  // n*n search is good enough.
-  for (AttrVec::const_iterator i = A.begin(), e = A.end(); i != e; ++i) {
-    if ((*i)->getKind() == attr::Aligned)
-      continue;
-    bool match = false;
-    for (AttrVec::const_iterator i1 = D.begin(), e1 = D.end(); i1 != e1; ++i1) {
-      if ((*i)->getKind() == (*i1)->getKind()) {
-        match = true;
-        break;
-      }
-    }
-    if (!match)
-      return true;
-  }
-  
-  return false;
-}
-
 /// \brief Check whether the declared result type of the given Objective-C
 /// method declaration is compatible with the method's class.
 ///
 static Sema::ResultTypeCompatibilityKind 
 CheckRelatedResultTypeCompatibility(Sema &S, ObjCMethodDecl *Method,
                                     ObjCInterfaceDecl *CurrentClass) {
-  QualType ResultType = Method->getResultType();
-  
+  QualType ResultType = Method->getReturnType();
+
   // If an Objective-C method inherits its related result type, then its 
   // declared result type must be compatible with its own class type. The
   // declared result type is compatible if:
@@ -2928,12 +2893,8 @@
       return;
     
     //   - categories,
-    for (ObjCInterfaceDecl::known_categories_iterator
-           cat = iface->known_categories_begin(),
-           catEnd = iface->known_categories_end();
-         cat != catEnd; ++cat) {
-      search(*cat);
-    }
+    for (auto *Cat : iface->known_categories())
+      search(Cat);
 
     //   - the super class, and
     if (ObjCInterfaceDecl *super = iface->getSuperClass())
@@ -3095,19 +3056,19 @@
   // Make sure we can establish a context for the method.
   if (!CurContext->isObjCContainer()) {
     Diag(MethodLoc, diag::error_missing_method_context);
-    return 0;
+    return nullptr;
   }
   ObjCContainerDecl *OCD = dyn_cast<ObjCContainerDecl>(CurContext);
   Decl *ClassDecl = cast<Decl>(OCD); 
   QualType resultDeclType;
 
   bool HasRelatedResultType = false;
-  TypeSourceInfo *ResultTInfo = 0;
+  TypeSourceInfo *ReturnTInfo = nullptr;
   if (ReturnType) {
-    resultDeclType = GetTypeFromParser(ReturnType, &ResultTInfo);
+    resultDeclType = GetTypeFromParser(ReturnType, &ReturnTInfo);
 
     if (CheckFunctionReturnType(resultDeclType, MethodLoc))
-      return 0;
+      return nullptr;
 
     HasRelatedResultType = (resultDeclType == Context.getObjCInstanceType());
   } else { // get the type for "id".
@@ -3116,18 +3077,14 @@
       << FixItHint::CreateInsertion(SelectorLocs.front(), "(id)");
   }
 
-  ObjCMethodDecl* ObjCMethod =
-    ObjCMethodDecl::Create(Context, MethodLoc, EndLoc, Sel,
-                           resultDeclType,
-                           ResultTInfo,
-                           CurContext,
-                           MethodType == tok::minus, isVariadic,
-                           /*isPropertyAccessor=*/false,
-                           /*isImplicitlyDeclared=*/false, /*isDefined=*/false,
-                           MethodDeclKind == tok::objc_optional 
-                             ? ObjCMethodDecl::Optional
-                             : ObjCMethodDecl::Required,
-                           HasRelatedResultType);
+  ObjCMethodDecl *ObjCMethod = ObjCMethodDecl::Create(
+      Context, MethodLoc, EndLoc, Sel, resultDeclType, ReturnTInfo, CurContext,
+      MethodType == tok::minus, isVariadic,
+      /*isPropertyAccessor=*/false,
+      /*isImplicitlyDeclared=*/false, /*isDefined=*/false,
+      MethodDeclKind == tok::objc_optional ? ObjCMethodDecl::Optional
+                                           : ObjCMethodDecl::Required,
+      HasRelatedResultType);
 
   SmallVector<ParmVarDecl*, 16> Params;
 
@@ -3137,7 +3094,7 @@
 
     if (!ArgInfo[i].Type) {
       ArgType = Context.getObjCIdType();
-      DI = 0;
+      DI = nullptr;
     } else {
       ArgType = GetTypeFromParser(ArgInfo[i].Type, &DI);
     }
@@ -3204,7 +3161,7 @@
     ProcessDeclAttributeList(TUScope, ObjCMethod, AttrList);
 
   // Add the method now.
-  const ObjCMethodDecl *PrevMethod = 0;
+  const ObjCMethodDecl *PrevMethod = nullptr;
   if (ObjCImplDecl *ImpDecl = dyn_cast<ObjCImplDecl>(ClassDecl)) {
     if (MethodType == tok::minus) {
       PrevMethod = ImpDecl->getInstanceMethod(Sel);
@@ -3214,24 +3171,22 @@
       ImpDecl->addClassMethod(ObjCMethod);
     }
 
-    ObjCMethodDecl *IMD = 0;
+    ObjCMethodDecl *IMD = nullptr;
     if (ObjCInterfaceDecl *IDecl = ImpDecl->getClassInterface())
       IMD = IDecl->lookupMethod(ObjCMethod->getSelector(), 
                                 ObjCMethod->isInstanceMethod());
     if (IMD && IMD->hasAttr<ObjCRequiresSuperAttr>() &&
         !ObjCMethod->hasAttr<ObjCRequiresSuperAttr>()) {
       // merge the attribute into implementation.
-      ObjCMethod->addAttr(
-        new (Context) ObjCRequiresSuperAttr(ObjCMethod->getLocation(), Context));
+      ObjCMethod->addAttr(ObjCRequiresSuperAttr::CreateImplicit(Context,
+                                                   ObjCMethod->getLocation()));
     }
-    if (ObjCMethod->hasAttrs() &&
-        containsInvalidMethodImplAttribute(IMD, ObjCMethod->getAttrs())) {
-      SourceLocation MethodLoc = IMD->getLocation();
-      if (!getSourceManager().isInSystemHeader(MethodLoc)) {
-        Diag(EndLoc, diag::warn_attribute_method_def);
-        Diag(MethodLoc, diag::note_method_declared_at)
+    if (isa<ObjCCategoryImplDecl>(ImpDecl)) {
+      ObjCMethodFamily family = 
+        ObjCMethod->getSelector().getMethodFamily();
+      if (family == OMF_dealloc && IMD && IMD->isOverriding()) 
+        Diag(ObjCMethod->getLocation(), diag::warn_dealloc_in_category)
           << ObjCMethod->getDeclName();
-      }
     }
   } else {
     cast<DeclContext>(ClassDecl)->addDecl(ObjCMethod);
@@ -3482,8 +3437,6 @@
       ReferencedSelectors[Sels[I].first] = Sels[I].second;
   }
   
-  DiagnoseMismatchedMethodsInGlobalPool();
-  
   // Warning will be issued only when selector table is
   // generated (which means there is at lease one implementation
   // in the TU). This is to match gcc's behavior.
@@ -3503,39 +3456,93 @@
 ObjCIvarDecl *
 Sema::GetIvarBackingPropertyAccessor(const ObjCMethodDecl *Method,
                                      const ObjCPropertyDecl *&PDecl) const {
-  
+  if (Method->isClassMethod())
+    return nullptr;
   const ObjCInterfaceDecl *IDecl = Method->getClassInterface();
   if (!IDecl)
-    return 0;
-  Method = IDecl->lookupMethod(Method->getSelector(), true);
+    return nullptr;
+  Method = IDecl->lookupMethod(Method->getSelector(), /*isInstance=*/true,
+                               /*shallowCategoryLookup=*/false,
+                               /*followSuper=*/false);
   if (!Method || !Method->isPropertyAccessor())
-    return 0;
-  if ((PDecl = Method->findPropertyDecl())) {
-    if (!PDecl->getDeclContext())
-      return 0;
-    // Make sure property belongs to accessor's class and not to
-    // one of its super classes.
-    if (const ObjCInterfaceDecl *CID =
-        dyn_cast<ObjCInterfaceDecl>(PDecl->getDeclContext()))
-      if (CID != IDecl)
-        return 0;
-    return PDecl->getPropertyIvarDecl();
-  }
-  return 0;
+    return nullptr;
+  if ((PDecl = Method->findPropertyDecl()))
+    if (ObjCIvarDecl *IV = PDecl->getPropertyIvarDecl()) {
+      // property backing ivar must belong to property's class
+      // or be a private ivar in class's implementation.
+      // FIXME. fix the const-ness issue.
+      IV = const_cast<ObjCInterfaceDecl *>(IDecl)->lookupInstanceVariable(
+                                                        IV->getIdentifier());
+      return IV;
+    }
+  return nullptr;
 }
 
-void Sema::DiagnoseUnusedBackingIvarInAccessor(Scope *S) {
-  if (S->hasUnrecoverableErrorOccurred() || !S->isInObjcMethodScope())
+namespace {
+  /// Used by Sema::DiagnoseUnusedBackingIvarInAccessor to check if a property
+  /// accessor references the backing ivar.
+  class UnusedBackingIvarChecker :
+      public DataRecursiveASTVisitor<UnusedBackingIvarChecker> {
+  public:
+    Sema &S;
+    const ObjCMethodDecl *Method;
+    const ObjCIvarDecl *IvarD;
+    bool AccessedIvar;
+    bool InvokedSelfMethod;
+
+    UnusedBackingIvarChecker(Sema &S, const ObjCMethodDecl *Method,
+                             const ObjCIvarDecl *IvarD)
+      : S(S), Method(Method), IvarD(IvarD),
+        AccessedIvar(false), InvokedSelfMethod(false) {
+      assert(IvarD);
+    }
+
+    bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
+      if (E->getDecl() == IvarD) {
+        AccessedIvar = true;
+        return false;
+      }
+      return true;
+    }
+
+    bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
+      if (E->getReceiverKind() == ObjCMessageExpr::Instance &&
+          S.isSelfExpr(E->getInstanceReceiver(), Method)) {
+        InvokedSelfMethod = true;
+      }
+      return true;
+    }
+  };
+}
+
+void Sema::DiagnoseUnusedBackingIvarInAccessor(Scope *S,
+                                          const ObjCImplementationDecl *ImplD) {
+  if (S->hasUnrecoverableErrorOccurred())
     return;
-  
-  const ObjCMethodDecl *CurMethod = getCurMethodDecl();
-  if (!CurMethod)
-    return;
-  const ObjCPropertyDecl *PDecl;
-  const ObjCIvarDecl *IV = GetIvarBackingPropertyAccessor(CurMethod, PDecl);
-  if (IV && !IV->getBackingIvarReferencedInAccessor()) {
-    Diag(getCurMethodDecl()->getLocation(), diag::warn_unused_property_backing_ivar)
-    << IV->getDeclName();
-    Diag(PDecl->getLocation(), diag::note_property_declare);
+
+  for (const auto *CurMethod : ImplD->instance_methods()) {
+    unsigned DIAG = diag::warn_unused_property_backing_ivar;
+    SourceLocation Loc = CurMethod->getLocation();
+    if (Diags.isIgnored(DIAG, Loc))
+      continue;
+
+    const ObjCPropertyDecl *PDecl;
+    const ObjCIvarDecl *IV = GetIvarBackingPropertyAccessor(CurMethod, PDecl);
+    if (!IV)
+      continue;
+
+    UnusedBackingIvarChecker Checker(*this, CurMethod, IV);
+    Checker.TraverseStmt(CurMethod->getBody());
+    if (Checker.AccessedIvar)
+      continue;
+
+    // Do not issue this warning if backing ivar is used somewhere and accessor
+    // implementation makes a self call. This is to prevent false positive in
+    // cases where the ivar is accessed by another method that the accessor
+    // delegates to.
+    if (!IV->isReferenced() || !Checker.InvokedSelfMethod) {
+      Diag(Loc, DIAG) << IV;
+      Diag(PDecl->getLocation(), diag::note_property_declare);
+    }
   }
 }
diff --git a/lib/Sema/SemaExceptionSpec.cpp b/lib/Sema/SemaExceptionSpec.cpp
index 3e8f324..b92fcbd 100644
--- a/lib/Sema/SemaExceptionSpec.cpp
+++ b/lib/Sema/SemaExceptionSpec.cpp
@@ -12,13 +12,13 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Sema/SemaInternal.h"
+#include "clang/AST/ASTMutationListener.h"
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/TypeLoc.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/SourceManager.h"
-#include "clang/Lex/Preprocessor.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallString.h"
 
@@ -132,6 +132,25 @@
   return SourceDecl->getType()->castAs<FunctionProtoType>();
 }
 
+void Sema::UpdateExceptionSpec(FunctionDecl *FD,
+                               const FunctionProtoType::ExtProtoInfo &EPI) {
+  const FunctionProtoType *Proto = FD->getType()->castAs<FunctionProtoType>();
+
+  // Overwrite the exception spec and rebuild the function type.
+  FunctionProtoType::ExtProtoInfo NewEPI = Proto->getExtProtoInfo();
+  NewEPI.ExceptionSpecType = EPI.ExceptionSpecType;
+  NewEPI.NumExceptions = EPI.NumExceptions;
+  NewEPI.Exceptions = EPI.Exceptions;
+  NewEPI.NoexceptExpr = EPI.NoexceptExpr;
+  FD->setType(Context.getFunctionType(Proto->getReturnType(),
+                                      Proto->getParamTypes(), NewEPI));
+
+  // If we've fully resolved the exception specification, notify listeners.
+  if (!isUnresolvedExceptionSpec(EPI.ExceptionSpecType))
+    if (auto *Listener = getASTMutationListener())
+      Listener->ResolvedExceptionSpec(FD);
+}
+
 /// Determine whether a function has an implicitly-generated exception
 /// specification.
 static bool hasImplicitExceptionSpec(FunctionDecl *Decl) {
@@ -140,10 +159,13 @@
       Decl->getDeclName().getCXXOverloadedOperator() != OO_Array_Delete)
     return false;
 
-  // If the user didn't declare the function, its exception specification must
-  // be implicit.
+  // For a function that the user didn't declare:
+  //  - if this is a destructor, its exception specification is implicit.
+  //  - if this is 'operator delete' or 'operator delete[]', the exception
+  //    specification is as-if an explicit exception specification was given
+  //    (per [basic.stc.dynamic]p2).
   if (!Decl->getTypeSourceInfo())
-    return true;
+    return isa<CXXDestructorDecl>(Decl);
 
   const FunctionProtoType *Ty =
     Decl->getTypeSourceInfo()->getType()->getAs<FunctionProtoType>();
@@ -155,9 +177,13 @@
   bool IsOperatorNew = OO == OO_New || OO == OO_Array_New;
   bool MissingExceptionSpecification = false;
   bool MissingEmptyExceptionSpecification = false;
+
   unsigned DiagID = diag::err_mismatched_exception_spec;
-  if (getLangOpts().MicrosoftExt)
-    DiagID = diag::warn_mismatched_exception_spec; 
+  bool ReturnValueOnError = true;
+  if (getLangOpts().MicrosoftExt) {
+    DiagID = diag::ext_mismatched_exception_spec;
+    ReturnValueOnError = false;
+  }
 
   // Check the types as written: they must match before any exception
   // specification adjustment is applied.
@@ -182,9 +208,9 @@
   }
 
   // The failure was something other than an missing exception
-  // specification; return an error.
+  // specification; return an error, except in MS mode where this is a warning.
   if (!MissingExceptionSpecification)
-    return true;
+    return ReturnValueOnError;
 
   const FunctionProtoType *NewProto =
     New->getType()->castAs<FunctionProtoType>();
@@ -203,8 +229,8 @@
       Old->isExternC()) {
     FunctionProtoType::ExtProtoInfo EPI = NewProto->getExtProtoInfo();
     EPI.ExceptionSpecType = EST_DynamicNone;
-    QualType NewType = Context.getFunctionType(NewProto->getResultType(),
-                                               NewProto->getArgTypes(), EPI);
+    QualType NewType = Context.getFunctionType(NewProto->getReturnType(),
+                                               NewProto->getParamTypes(), EPI);
     New->setType(NewType);
     return false;
   }
@@ -224,8 +250,8 @@
 
   // Update the type of the function with the appropriate exception
   // specification.
-  QualType NewType = Context.getFunctionType(NewProto->getResultType(),
-                                             NewProto->getArgTypes(), EPI);
+  QualType NewType = Context.getFunctionType(NewProto->getReturnType(),
+                                             NewProto->getParamTypes(), EPI);
   New->setType(NewType);
 
   // Warn about the lack of exception specification.
@@ -239,16 +265,13 @@
   case EST_Dynamic: {
     OS << "throw(";
     bool OnFirstException = true;
-    for (FunctionProtoType::exception_iterator E = OldProto->exception_begin(),
-                                            EEnd = OldProto->exception_end();
-         E != EEnd;
-         ++E) {
+    for (const auto &E : OldProto->exceptions()) {
       if (OnFirstException)
         OnFirstException = false;
       else
         OS << ", ";
       
-      OS << E->getAsString(getPrintingPolicy());
+      OS << E.getAsString(getPrintingPolicy());
     }
     OS << ")";
     break;
@@ -260,7 +283,8 @@
 
   case EST_ComputedNoexcept:
     OS << "noexcept(";
-    OldProto->getNoexceptExpr()->printPretty(OS, 0, getPrintingPolicy());
+    assert(OldProto->getNoexceptExpr() != nullptr && "Expected non-null Expr");
+    OldProto->getNoexceptExpr()->printPretty(OS, nullptr, getPrintingPolicy());
     OS << ")";
     break;
 
@@ -273,7 +297,7 @@
   if (TypeSourceInfo *TSInfo = New->getTypeSourceInfo()) {
     TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
     if (FunctionTypeLoc FTLoc = TL.getAs<FunctionTypeLoc>())
-      FixItLoc = PP.getLocForEndOfToken(FTLoc.getLocalRangeEnd());
+      FixItLoc = getLocForEndOfToken(FTLoc.getLocalRangeEnd());
   }
 
   if (FixItLoc.isInvalid())
@@ -302,10 +326,14 @@
     const FunctionProtoType *New, SourceLocation NewLoc) {
   unsigned DiagID = diag::err_mismatched_exception_spec;
   if (getLangOpts().MicrosoftExt)
-    DiagID = diag::warn_mismatched_exception_spec; 
-  return CheckEquivalentExceptionSpec(PDiag(DiagID),
-                                      PDiag(diag::note_previous_declaration),
-                                      Old, OldLoc, New, NewLoc);
+    DiagID = diag::ext_mismatched_exception_spec;
+  bool Result = CheckEquivalentExceptionSpec(PDiag(DiagID),
+      PDiag(diag::note_previous_declaration), Old, OldLoc, New, NewLoc);
+
+  // In Microsoft mode, mismatching exception specifications just cause a warning.
+  if (getLangOpts().MicrosoftExt)
+    return false;
+  return Result;
 }
 
 /// CheckEquivalentExceptionSpec - Check if the two types have compatible
@@ -428,7 +456,7 @@
   // throw(std::bad_alloc) as equivalent for operator new and operator new[].
   // This is because the implicit declaration changed, but old code would break.
   if (getLangOpts().CPlusPlus11 && IsOperatorNew) {
-    const FunctionProtoType *WithExceptions = 0;
+    const FunctionProtoType *WithExceptions = nullptr;
     if (OldEST == EST_None && NewEST == EST_Dynamic)
       WithExceptions = New;
     else if (OldEST == EST_Dynamic && NewEST == EST_None)
@@ -441,15 +469,8 @@
         IdentifierInfo* Name = ExRecord->getIdentifier();
         if (Name && Name->getName() == "bad_alloc") {
           // It's called bad_alloc, but is it in std?
-          DeclContext* DC = ExRecord->getDeclContext();
-          DC = DC->getEnclosingNamespaceContext();
-          if (NamespaceDecl* NS = dyn_cast<NamespaceDecl>(DC)) {
-            IdentifierInfo* NSName = NS->getIdentifier();
-            DC = DC->getParent();
-            if (NSName && NSName->getName() == "std" &&
-                DC->getEnclosingNamespaceContext()->isTranslationUnit()) {
-              return false;
-            }
+          if (ExRecord->isInStdNamespace()) {
+            return false;
           }
         }
       }
@@ -488,13 +509,11 @@
   // Both have a dynamic exception spec. Collect the first set, then compare
   // to the second.
   llvm::SmallPtrSet<CanQualType, 8> OldTypes, NewTypes;
-  for (FunctionProtoType::exception_iterator I = Old->exception_begin(),
-       E = Old->exception_end(); I != E; ++I)
-    OldTypes.insert(Context.getCanonicalType(*I).getUnqualifiedType());
+  for (const auto &I : Old->exceptions())
+    OldTypes.insert(Context.getCanonicalType(I).getUnqualifiedType());
 
-  for (FunctionProtoType::exception_iterator I = New->exception_begin(),
-       E = New->exception_end(); I != E && Success; ++I) {
-    CanQualType TypePtr = Context.getCanonicalType(*I).getUnqualifiedType();
+  for (const auto &I : New->exceptions()) {
+    CanQualType TypePtr = Context.getCanonicalType(I).getUnqualifiedType();
     if(OldTypes.count(TypePtr))
       NewTypes.insert(TypePtr);
     else
@@ -602,10 +621,9 @@
          "Exception spec subset: non-dynamic case slipped through.");
 
   // Neither contains everything or nothing. Do a proper comparison.
-  for (FunctionProtoType::exception_iterator SubI = Subset->exception_begin(),
-       SubE = Subset->exception_end(); SubI != SubE; ++SubI) {
+  for (const auto &SubI : Subset->exceptions()) {
     // Take one type from the subset.
-    QualType CanonicalSubT = Context.getCanonicalType(*SubI);
+    QualType CanonicalSubT = Context.getCanonicalType(SubI);
     // Unwrap pointers and references so that we can do checks within a class
     // hierarchy. Don't unwrap member pointers; they don't have hierarchy
     // conversions on the pointee.
@@ -624,10 +642,8 @@
 
     bool Contained = false;
     // Make sure it's in the superset.
-    for (FunctionProtoType::exception_iterator SuperI =
-           Superset->exception_begin(), SuperE = Superset->exception_end();
-         SuperI != SuperE; ++SuperI) {
-      QualType CanonicalSuperT = Context.getCanonicalType(*SuperI);
+    for (const auto &SuperI : Superset->exceptions()) {
+      QualType CanonicalSuperT = Context.getCanonicalType(SuperI);
       // SubT must be SuperT or derived from it, or pointer or reference to
       // such types.
       if (const ReferenceType *RefTy = CanonicalSuperT->getAs<ReferenceType>())
@@ -711,23 +727,21 @@
     const FunctionProtoType *Target, SourceLocation TargetLoc,
     const FunctionProtoType *Source, SourceLocation SourceLoc)
 {
-  if (CheckSpecForTypesEquivalent(*this,
-                           PDiag(diag::err_deep_exception_specs_differ) << 0, 
-                                  PDiag(),
-                                  Target->getResultType(), TargetLoc,
-                                  Source->getResultType(), SourceLoc))
+  if (CheckSpecForTypesEquivalent(
+          *this, PDiag(diag::err_deep_exception_specs_differ) << 0, PDiag(),
+          Target->getReturnType(), TargetLoc, Source->getReturnType(),
+          SourceLoc))
     return true;
 
   // We shouldn't even be testing this unless the arguments are otherwise
   // compatible.
-  assert(Target->getNumArgs() == Source->getNumArgs() &&
+  assert(Target->getNumParams() == Source->getNumParams() &&
          "Functions have different argument counts.");
-  for (unsigned i = 0, E = Target->getNumArgs(); i != E; ++i) {
-    if (CheckSpecForTypesEquivalent(*this,
-                           PDiag(diag::err_deep_exception_specs_differ) << 1, 
-                                    PDiag(),
-                                    Target->getArgType(i), TargetLoc,
-                                    Source->getArgType(i), SourceLoc))
+  for (unsigned i = 0, E = Target->getNumParams(); i != E; ++i) {
+    if (CheckSpecForTypesEquivalent(
+            *this, PDiag(diag::err_deep_exception_specs_differ) << 1, PDiag(),
+            Target->getParamType(i), TargetLoc, Source->getParamType(i),
+            SourceLoc))
       return true;
   }
   return false;
@@ -773,7 +787,7 @@
   }
   unsigned DiagID = diag::err_override_exception_spec;
   if (getLangOpts().MicrosoftExt)
-    DiagID = diag::warn_override_exception_spec;
+    DiagID = diag::ext_override_exception_spec;
   return CheckExceptionSpecSubset(PDiag(DiagID),
                                   PDiag(diag::note_overridden_virtual_function),
                                   Old->getType()->getAs<FunctionProtoType>(),
@@ -1063,7 +1077,6 @@
   case Expr::AddrLabelExprClass:
   case Expr::ArrayTypeTraitExprClass:
   case Expr::AtomicExprClass:
-  case Expr::BinaryTypeTraitExprClass:
   case Expr::TypeTraitExprClass:
   case Expr::CXXBoolLiteralExprClass:
   case Expr::CXXNoexceptExprClass:
@@ -1086,7 +1099,6 @@
   case Expr::PredefinedExprClass:
   case Expr::SizeOfPackExprClass:
   case Expr::StringLiteralClass:
-  case Expr::UnaryTypeTraitExprClass:
     // These expressions can never throw.
     return CT_Cannot;
 
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 8ec58d4..35dad82 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -59,8 +59,8 @@
 
     // If the function has a deduced return type, and we can't deduce it,
     // then we can't use it either.
-    if (getLangOpts().CPlusPlus1y && FD->getResultType()->isUndeducedType() &&
-        DeduceReturnType(FD, SourceLocation(), /*Diagnose*/false))
+    if (getLangOpts().CPlusPlus1y && FD->getReturnType()->isUndeducedType() &&
+        DeduceReturnType(FD, SourceLocation(), /*Diagnose*/ false))
       return false;
   }
 
@@ -83,9 +83,16 @@
 
 static AvailabilityResult DiagnoseAvailabilityOfDecl(Sema &S,
                               NamedDecl *D, SourceLocation Loc,
-                              const ObjCInterfaceDecl *UnknownObjCClass) {
+                              const ObjCInterfaceDecl *UnknownObjCClass,
+                              bool ObjCPropertyAccess) {
   // See if this declaration is unavailable or deprecated.
   std::string Message;
+    
+  // Forward class declarations get their attributes from their definition.
+  if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(D)) {
+    if (IDecl->getDefinition())
+      D = IDecl->getDefinition();
+  }
   AvailabilityResult Result = D->getAvailability(&Message);
   if (const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D))
     if (Result == AR_Available) {
@@ -94,11 +101,11 @@
         Result = TheEnumDecl->getAvailability(&Message);
     }
 
-  const ObjCPropertyDecl *ObjCPDecl = 0;
+  const ObjCPropertyDecl *ObjCPDecl = nullptr;
   if (Result == AR_Deprecated || Result == AR_Unavailable) {
     if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
       if (const ObjCPropertyDecl *PD = MD->findPropertyDecl()) {
-        AvailabilityResult PDeclResult = PD->getAvailability(0);
+        AvailabilityResult PDeclResult = PD->getAvailability(nullptr);
         if (PDeclResult == Result)
           ObjCPDecl = PD;
       }
@@ -111,32 +118,19 @@
       break;
             
     case AR_Deprecated:
-      S.EmitDeprecationWarning(D, Message, Loc, UnknownObjCClass, ObjCPDecl);
+      if (S.getCurContextAvailability() != AR_Deprecated)
+        S.EmitAvailabilityWarning(Sema::AD_Deprecation,
+                                  D, Message, Loc, UnknownObjCClass, ObjCPDecl,
+                                  ObjCPropertyAccess);
       break;
-            
+
     case AR_Unavailable:
-      if (S.getCurContextAvailability() != AR_Unavailable) {
-        if (Message.empty()) {
-          if (!UnknownObjCClass) {
-            S.Diag(Loc, diag::err_unavailable) << D->getDeclName();
-            if (ObjCPDecl)
-              S.Diag(ObjCPDecl->getLocation(), diag::note_property_attribute)
-                << ObjCPDecl->getDeclName() << 1;
-          }
-          else
-            S.Diag(Loc, diag::warn_unavailable_fwdclass_message) 
-              << D->getDeclName();
-        }
-        else
-          S.Diag(Loc, diag::err_unavailable_message) 
-            << D->getDeclName() << Message;
-        S.Diag(D->getLocation(), diag::note_unavailable_here)
-                  << isa<FunctionDecl>(D) << false;
-        if (ObjCPDecl)
-          S.Diag(ObjCPDecl->getLocation(), diag::note_property_attribute)
-          << ObjCPDecl->getDeclName() << 1;
-      }
+      if (S.getCurContextAvailability() != AR_Unavailable)
+        S.EmitAvailabilityWarning(Sema::AD_Unavailable,
+                                  D, Message, Loc, UnknownObjCClass, ObjCPDecl,
+                                  ObjCPropertyAccess);
       break;
+
     }
     return Result;
 }
@@ -176,16 +170,14 @@
     }
   }
 
-  Diag(Decl->getLocation(), diag::note_unavailable_here)
-    << 1 << true;
+  Diag(Decl->getLocation(), diag::note_availability_specified_here)
+    << Decl << true;
 }
 
 /// \brief Determine whether a FunctionDecl was ever declared with an
 /// explicit storage class.
 static bool hasAnyExplicitStorageClass(const FunctionDecl *D) {
-  for (FunctionDecl::redecl_iterator I = D->redecls_begin(),
-                                     E = D->redecls_end();
-       I != E; ++I) {
+  for (auto I : D->redecls()) {
     if (I->getStorageClass() != SC_None)
       return true;
   }
@@ -234,15 +226,14 @@
   if (!DowngradeWarning && UsedFn)
     DowngradeWarning = UsedFn->isInlined() || UsedFn->hasAttr<ConstAttr>();
 
-  S.Diag(Loc, DowngradeWarning ? diag::ext_internal_in_extern_inline
-                               : diag::warn_internal_in_extern_inline)
+  S.Diag(Loc, DowngradeWarning ? diag::ext_internal_in_extern_inline_quiet
+                               : diag::ext_internal_in_extern_inline)
     << /*IsVar=*/!UsedFn << D;
 
   S.MaybeSuggestAddingStaticToDecl(Current);
 
-  S.Diag(D->getCanonicalDecl()->getLocation(),
-         diag::note_internal_decl_declared_here)
-    << D;
+  S.Diag(D->getCanonicalDecl()->getLocation(), diag::note_entity_declared_at)
+      << D;
 }
 
 void Sema::MaybeSuggestAddingStaticToDecl(const FunctionDecl *Cur) {
@@ -269,7 +260,8 @@
 /// referenced), false otherwise.
 ///
 bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc,
-                             const ObjCInterfaceDecl *UnknownObjCClass) {
+                             const ObjCInterfaceDecl *UnknownObjCClass,
+                             bool ObjCPropertyAccess) {
   if (getLangOpts().CPlusPlus && isa<FunctionDecl>(D)) {
     // If there were any diagnostics suppressed by template argument deduction,
     // emit them now.
@@ -279,13 +271,18 @@
       SmallVectorImpl<PartialDiagnosticAt> &Suppressed = Pos->second;
       for (unsigned I = 0, N = Suppressed.size(); I != N; ++I)
         Diag(Suppressed[I].first, Suppressed[I].second);
-      
+
       // Clear out the list of suppressed diagnostics, so that we don't emit
       // them again for this specialization. However, we don't obsolete this
       // entry from the table, because we want to avoid ever emitting these
       // diagnostics again.
       Suppressed.clear();
     }
+
+    // C++ [basic.start.main]p3:
+    //   The function 'main' shall not be used within a program.
+    if (cast<FunctionDecl>(D)->isMain())
+      Diag(Loc, diag::ext_main_used);
   }
 
   // See if this is an auto-typed variable whose initializer we are parsing.
@@ -305,11 +302,11 @@
 
     // If the function has a deduced return type, and we can't deduce it,
     // then we can't use it either.
-    if (getLangOpts().CPlusPlus1y && FD->getResultType()->isUndeducedType() &&
+    if (getLangOpts().CPlusPlus1y && FD->getReturnType()->isUndeducedType() &&
         DeduceReturnType(FD, Loc))
       return true;
   }
-  DiagnoseAvailabilityOfDecl(*this, D, Loc, UnknownObjCClass);
+  DiagnoseAvailabilityOfDecl(*this, D, Loc, UnknownObjCClass, ObjCPropertyAccess);
 
   DiagnoseUnusedOfDecl(*this, D, Loc);
 
@@ -354,7 +351,7 @@
     calleeType = CT_Function;
   } else if (isa<VarDecl>(D)) {
     QualType type = cast<ValueDecl>(D)->getType();
-    const FunctionType *fn = 0;
+    const FunctionType *fn = nullptr;
     if (const PointerType *ptr = type->getAs<PointerType>()) {
       fn = ptr->getPointeeType()->getAs<FunctionType>();
       if (!fn) return;
@@ -367,7 +364,7 @@
     }
 
     if (const FunctionProtoType *proto = dyn_cast<FunctionProtoType>(fn)) {
-      numFormalParams = proto->getNumArgs();
+      numFormalParams = proto->getNumParams();
     } else {
       numFormalParams = 0;
     }
@@ -438,16 +435,22 @@
   if (E->getType()->isPlaceholderType()) {
     ExprResult result = CheckPlaceholderExpr(E);
     if (result.isInvalid()) return ExprError();
-    E = result.take();
+    E = result.get();
   }
   
   QualType Ty = E->getType();
   assert(!Ty.isNull() && "DefaultFunctionArrayConversion - missing type");
 
-  if (Ty->isFunctionType())
+  if (Ty->isFunctionType()) {
+    // If we are here, we are not calling a function but taking
+    // its address (which is not allowed in OpenCL v1.0 s6.8.a.3).
+    if (getLangOpts().OpenCL) {
+      Diag(E->getExprLoc(), diag::err_opencl_taking_function_address);
+      return ExprError();
+    }
     E = ImpCastExprToType(E, Context.getPointerType(Ty),
-                          CK_FunctionToPointerDecay).take();
-  else if (Ty->isArrayType()) {
+                          CK_FunctionToPointerDecay).get();
+  } else if (Ty->isArrayType()) {
     // In C90 mode, arrays only promote to pointers if the array expression is
     // an lvalue.  The relevant legalese is C90 6.2.2.1p3: "an lvalue that has
     // type 'array of type' is converted to an expression that has type 'pointer
@@ -461,9 +464,9 @@
     //
     if (getLangOpts().C99 || getLangOpts().CPlusPlus || E->isLValue())
       E = ImpCastExprToType(E, Context.getArrayDecayedType(Ty),
-                            CK_ArrayToPointerDecay).take();
+                            CK_ArrayToPointerDecay).get();
   }
-  return Owned(E);
+  return E;
 }
 
 static void CheckForNullPointerDereference(Sema &S, Expr *E) {
@@ -503,7 +506,7 @@
     BaseType = BaseType->getPointeeType();
   if (const ObjCObjectType *OTy = BaseType->getAs<ObjCObjectType>())
     if (ObjCInterfaceDecl *IDecl = OTy->getInterface()) {
-      ObjCInterfaceDecl *ClassDeclared = 0;
+      ObjCInterfaceDecl *ClassDeclared = nullptr;
       ObjCIvarDecl *IV = IDecl->lookupInstanceVariable(Member, ClassDeclared);
       if (!ClassDeclared->getSuperClass()
           && (*ClassDeclared->ivar_begin()) == IV) {
@@ -546,13 +549,13 @@
   if (E->getType()->isPlaceholderType()) {
     ExprResult result = CheckPlaceholderExpr(E);
     if (result.isInvalid()) return ExprError();
-    E = result.take();
+    E = result.get();
   }
   
   // C++ [conv.lval]p1:
   //   A glvalue of a non-function, non-array type T can be
   //   converted to a prvalue.
-  if (!E->isGLValue()) return Owned(E);
+  if (!E->isGLValue()) return E;
 
   QualType T = E->getType();
   assert(!T.isNull() && "r-value conversion on typeless expression?");
@@ -563,7 +566,7 @@
       (E->getType() == Context.OverloadTy ||
        T->isDependentType() ||
        T->isRecordType()))
-    return Owned(E);
+    return E;
 
   // The C standard is actually really unclear on this point, and
   // DR106 tells us what the result should be but not why.  It's
@@ -571,7 +574,7 @@
   // lvalue-to-rvalue at all.  Note that expressions of unqualified
   // 'void' type are never l-values, but qualified void can be.
   if (T->isVoidType())
-    return Owned(E);
+    return E;
 
   // OpenCL usually rejects direct accesses to values of 'half' type.
   if (getLangOpts().OpenCL && !getOpenCLOptions().cl_khr_fp16 &&
@@ -596,8 +599,8 @@
   }
   else if (const ObjCIvarRefExpr *OIRE =
             dyn_cast<ObjCIvarRefExpr>(E->IgnoreParenCasts()))
-    DiagnoseDirectIsaAccess(*this, OIRE, SourceLocation(), /* Expr*/0);
-  
+    DiagnoseDirectIsaAccess(*this, OIRE, SourceLocation(), /* Expr*/nullptr);
+
   // C++ [conv.lval]p1:
   //   [...] If T is a non-class type, the type of the prvalue is the
   //   cv-unqualified version of T. Otherwise, the type of the
@@ -618,16 +621,16 @@
       E->getType().getObjCLifetime() == Qualifiers::OCL_Weak)
     ExprNeedsCleanups = true;
 
-  ExprResult Res = Owned(ImplicitCastExpr::Create(Context, T, CK_LValueToRValue,
-                                                  E, 0, VK_RValue));
+  ExprResult Res = ImplicitCastExpr::Create(Context, T, CK_LValueToRValue, E,
+                                            nullptr, VK_RValue);
 
   // C11 6.3.2.1p2:
   //   ... if the lvalue has atomic type, the value has the non-atomic version 
   //   of the type of the lvalue ...
   if (const AtomicType *Atomic = T->getAs<AtomicType>()) {
     T = Atomic->getValueType().getUnqualifiedType();
-    Res = Owned(ImplicitCastExpr::Create(Context, T, CK_AtomicToNonAtomic,
-                                         Res.get(), 0, VK_RValue));
+    Res = ImplicitCastExpr::Create(Context, T, CK_AtomicToNonAtomic, Res.get(),
+                                   nullptr, VK_RValue);
   }
   
   return Res;
@@ -637,12 +640,30 @@
   ExprResult Res = DefaultFunctionArrayConversion(E);
   if (Res.isInvalid())
     return ExprError();
-  Res = DefaultLvalueConversion(Res.take());
+  Res = DefaultLvalueConversion(Res.get());
   if (Res.isInvalid())
     return ExprError();
   return Res;
 }
 
+/// CallExprUnaryConversions - a special case of an unary conversion
+/// performed on a function designator of a call expression.
+ExprResult Sema::CallExprUnaryConversions(Expr *E) {
+  QualType Ty = E->getType();
+  ExprResult Res = E;
+  // Only do implicit cast for a function type, but not for a pointer
+  // to function type.
+  if (Ty->isFunctionType()) {
+    Res = ImpCastExprToType(E, Context.getPointerType(Ty),
+                            CK_FunctionToPointerDecay).get();
+    if (Res.isInvalid())
+      return ExprError();
+  }
+  Res = DefaultLvalueConversion(Res.get());
+  if (Res.isInvalid())
+    return ExprError();
+  return Res.get();
+}
 
 /// UsualUnaryConversions - Performs various conversions that are common to most
 /// operators (C99 6.3). The conversions of array and function types are
@@ -654,14 +675,14 @@
   ExprResult Res = DefaultFunctionArrayLvalueConversion(E);
   if (Res.isInvalid())
     return ExprError();
-  E = Res.take();
+  E = Res.get();
 
   QualType Ty = E->getType();
   assert(!Ty.isNull() && "UsualUnaryConversions - missing type");
 
   // Half FP have to be promoted to float unless it is natively supported
   if (Ty->isHalfType() && !getLangOpts().NativeHalfType)
-    return ImpCastExprToType(Res.take(), Context.FloatTy, CK_FloatingCast);
+    return ImpCastExprToType(Res.get(), Context.FloatTy, CK_FloatingCast);
 
   // Try to perform integral promotions if the object has a theoretically
   // promotable type.
@@ -682,16 +703,16 @@
 
     QualType PTy = Context.isPromotableBitField(E);
     if (!PTy.isNull()) {
-      E = ImpCastExprToType(E, PTy, CK_IntegralCast).take();
-      return Owned(E);
+      E = ImpCastExprToType(E, PTy, CK_IntegralCast).get();
+      return E;
     }
     if (Ty->isPromotableIntegerType()) {
       QualType PT = Context.getPromotedIntegerType(Ty);
-      E = ImpCastExprToType(E, PT, CK_IntegralCast).take();
-      return Owned(E);
+      E = ImpCastExprToType(E, PT, CK_IntegralCast).get();
+      return E;
     }
   }
-  return Owned(E);
+  return E;
 }
 
 /// DefaultArgumentPromotion (C99 6.5.2.2p6). Used for function calls that
@@ -705,14 +726,14 @@
   ExprResult Res = UsualUnaryConversions(E);
   if (Res.isInvalid())
     return ExprError();
-  E = Res.take();
+  E = Res.get();
 
   // If this is a 'float' or '__fp16' (CVR qualified or typedef) promote to
   // double.
   const BuiltinType *BTy = Ty->getAs<BuiltinType>();
   if (BTy && (BTy->getKind() == BuiltinType::Half ||
               BTy->getKind() == BuiltinType::Float))
-    E = ImpCastExprToType(E, Context.DoubleTy, CK_FloatingCast).take();
+    E = ImpCastExprToType(E, Context.DoubleTy, CK_FloatingCast).get();
 
   // C++ performs lvalue-to-rvalue conversion as a default argument
   // promotion, even on class types, but note:
@@ -728,14 +749,13 @@
   if (getLangOpts().CPlusPlus && E->isGLValue() && !isUnevaluatedContext()) {
     ExprResult Temp = PerformCopyInitialization(
                        InitializedEntity::InitializeTemporary(E->getType()),
-                                                E->getExprLoc(),
-                                                Owned(E));
+                                                E->getExprLoc(), E);
     if (Temp.isInvalid())
       return ExprError();
     E = Temp.get();
   }
 
-  return Owned(E);
+  return E;
 }
 
 /// Determine the degree of POD-ness for an expression.
@@ -792,19 +812,25 @@
 
   // Complain about passing non-POD types through varargs.
   switch (VAK) {
-  case VAK_Valid:
-    break;
-
   case VAK_ValidInCXX11:
     DiagRuntimeBehavior(
-        E->getLocStart(), 0,
+        E->getLocStart(), nullptr,
         PDiag(diag::warn_cxx98_compat_pass_non_pod_arg_to_vararg)
-          << E->getType() << CT);
+          << Ty << CT);
+    // Fall through.
+  case VAK_Valid:
+    if (Ty->isRecordType()) {
+      // This is unlikely to be what the user intended. If the class has a
+      // 'c_str' member function, the user probably meant to call that.
+      DiagRuntimeBehavior(E->getLocStart(), nullptr,
+                          PDiag(diag::warn_pass_class_arg_to_vararg)
+                            << Ty << CT << hasCStrMethod(E) << ".c_str()");
+    }
     break;
 
   case VAK_Undefined:
     DiagRuntimeBehavior(
-        E->getLocStart(), 0,
+        E->getLocStart(), nullptr,
         PDiag(diag::warn_cannot_pass_non_pod_arg_to_vararg)
           << getLangOpts().CPlusPlus11 << Ty << CT);
     break;
@@ -812,7 +838,7 @@
   case VAK_Invalid:
     if (Ty->isObjCObjectType())
       DiagRuntimeBehavior(
-          E->getLocStart(), 0,
+          E->getLocStart(), nullptr,
           PDiag(diag::err_cannot_pass_objc_interface_to_vararg)
             << Ty << CT);
     else
@@ -838,14 +864,14 @@
       ExprResult ExprRes = CheckPlaceholderExpr(E);
       if (ExprRes.isInvalid())
         return ExprError();
-      E = ExprRes.take();
+      E = ExprRes.get();
     }
   }
   
   ExprResult ExprRes = DefaultArgumentPromotion(E);
   if (ExprRes.isInvalid())
     return ExprError();
-  E = ExprRes.take();
+  E = ExprRes.get();
 
   // Diagnostics regarding non-POD argument types are
   // emitted along with format string checking in Sema::CheckFunctionCall().
@@ -879,7 +905,7 @@
                           diag::err_call_incomplete_argument))
     return ExprError();
 
-  return Owned(E);
+  return E;
 }
 
 /// \brief Converts an integer to complex float type.  Helper function of
@@ -896,12 +922,12 @@
   if (SkipCast) return false;
   if (IntTy->isIntegerType()) {
     QualType fpTy = cast<ComplexType>(ComplexTy)->getElementType();
-    IntExpr = S.ImpCastExprToType(IntExpr.take(), fpTy, CK_IntegralToFloating);
-    IntExpr = S.ImpCastExprToType(IntExpr.take(), ComplexTy,
+    IntExpr = S.ImpCastExprToType(IntExpr.get(), fpTy, CK_IntegralToFloating);
+    IntExpr = S.ImpCastExprToType(IntExpr.get(), ComplexTy,
                                   CK_FloatingRealToComplex);
   } else {
     assert(IntTy->isComplexIntegerType());
-    IntExpr = S.ImpCastExprToType(IntExpr.take(), ComplexTy,
+    IntExpr = S.ImpCastExprToType(IntExpr.get(), ComplexTy,
                                   CK_IntegralComplexToFloatingComplex);
   }
   return false;
@@ -919,12 +945,12 @@
   if (order < 0) {
     // _Complex float -> _Complex double
     if (!IsCompAssign)
-      LHS = S.ImpCastExprToType(LHS.take(), RHSType, CK_FloatingComplexCast);
+      LHS = S.ImpCastExprToType(LHS.get(), RHSType, CK_FloatingComplexCast);
     return RHSType;
   }
   if (order > 0)
     // _Complex float -> _Complex double
-    RHS = S.ImpCastExprToType(RHS.take(), LHSType, CK_FloatingComplexCast);
+    RHS = S.ImpCastExprToType(RHS.get(), LHSType, CK_FloatingComplexCast);
   return LHSType;
 }
 
@@ -945,8 +971,8 @@
     // float -> _Complex double
     if (ConvertOtherExpr) {
       QualType fp = cast<ComplexType>(ComplexTy)->getElementType();
-      OtherExpr = S.ImpCastExprToType(OtherExpr.take(), fp, CK_FloatingCast);
-      OtherExpr = S.ImpCastExprToType(OtherExpr.take(), ComplexTy,
+      OtherExpr = S.ImpCastExprToType(OtherExpr.get(), fp, CK_FloatingCast);
+      OtherExpr = S.ImpCastExprToType(OtherExpr.get(), ComplexTy,
                                       CK_FloatingRealToComplex);
     }
     return ComplexTy;
@@ -958,12 +984,12 @@
 
   // double -> _Complex double
   if (ConvertOtherExpr)
-    OtherExpr = S.ImpCastExprToType(OtherExpr.take(), result,
+    OtherExpr = S.ImpCastExprToType(OtherExpr.get(), result,
                                     CK_FloatingRealToComplex);
 
   // _Complex float -> _Complex double
   if (ConvertComplexExpr && order < 0)
-    ComplexExpr = S.ImpCastExprToType(ComplexExpr.take(), result,
+    ComplexExpr = S.ImpCastExprToType(ComplexExpr.get(), result,
                                       CK_FloatingComplexCast);
 
   return result;
@@ -1025,7 +1051,7 @@
   if (IntTy->isIntegerType()) {
     if (ConvertInt)
       // Convert intExpr to the lhs floating point type.
-      IntExpr = S.ImpCastExprToType(IntExpr.take(), FloatTy,
+      IntExpr = S.ImpCastExprToType(IntExpr.get(), FloatTy,
                                     CK_IntegralToFloating);
     return FloatTy;
   }
@@ -1036,12 +1062,12 @@
 
   // _Complex int -> _Complex float
   if (ConvertInt)
-    IntExpr = S.ImpCastExprToType(IntExpr.take(), result,
+    IntExpr = S.ImpCastExprToType(IntExpr.get(), result,
                                   CK_IntegralComplexToFloatingComplex);
 
   // float -> _Complex float
   if (ConvertFloat)
-    FloatExpr = S.ImpCastExprToType(FloatExpr.take(), result,
+    FloatExpr = S.ImpCastExprToType(FloatExpr.get(), result,
                                     CK_FloatingRealToComplex);
 
   return result;
@@ -1060,13 +1086,13 @@
   if (LHSFloat && RHSFloat) {
     int order = S.Context.getFloatingTypeOrder(LHSType, RHSType);
     if (order > 0) {
-      RHS = S.ImpCastExprToType(RHS.take(), LHSType, CK_FloatingCast);
+      RHS = S.ImpCastExprToType(RHS.get(), LHSType, CK_FloatingCast);
       return LHSType;
     }
 
     assert(order < 0 && "illegal float comparison");
     if (!IsCompAssign)
-      LHS = S.ImpCastExprToType(LHS.take(), RHSType, CK_FloatingCast);
+      LHS = S.ImpCastExprToType(LHS.get(), RHSType, CK_FloatingCast);
     return RHSType;
   }
 
@@ -1108,29 +1134,29 @@
   if (LHSSigned == RHSSigned) {
     // Same signedness; use the higher-ranked type
     if (order >= 0) {
-      RHS = (*doRHSCast)(S, RHS.take(), LHSType);
+      RHS = (*doRHSCast)(S, RHS.get(), LHSType);
       return LHSType;
     } else if (!IsCompAssign)
-      LHS = (*doLHSCast)(S, LHS.take(), RHSType);
+      LHS = (*doLHSCast)(S, LHS.get(), RHSType);
     return RHSType;
   } else if (order != (LHSSigned ? 1 : -1)) {
     // The unsigned type has greater than or equal rank to the
     // signed type, so use the unsigned type
     if (RHSSigned) {
-      RHS = (*doRHSCast)(S, RHS.take(), LHSType);
+      RHS = (*doRHSCast)(S, RHS.get(), LHSType);
       return LHSType;
     } else if (!IsCompAssign)
-      LHS = (*doLHSCast)(S, LHS.take(), RHSType);
+      LHS = (*doLHSCast)(S, LHS.get(), RHSType);
     return RHSType;
   } else if (S.Context.getIntWidth(LHSType) != S.Context.getIntWidth(RHSType)) {
     // The two types are different widths; if we are here, that
     // means the signed type is larger than the unsigned type, so
     // use the signed type.
     if (LHSSigned) {
-      RHS = (*doRHSCast)(S, RHS.take(), LHSType);
+      RHS = (*doRHSCast)(S, RHS.get(), LHSType);
       return LHSType;
     } else if (!IsCompAssign)
-      LHS = (*doLHSCast)(S, LHS.take(), RHSType);
+      LHS = (*doLHSCast)(S, LHS.get(), RHSType);
     return RHSType;
   } else {
     // The signed type is higher-ranked than the unsigned type,
@@ -1139,9 +1165,9 @@
     // to the signed type.
     QualType result =
       S.Context.getCorrespondingUnsignedType(LHSSigned ? LHSType : RHSType);
-    RHS = (*doRHSCast)(S, RHS.take(), result);
+    RHS = (*doRHSCast)(S, RHS.get(), result);
     if (!IsCompAssign)
-      LHS = (*doLHSCast)(S, LHS.take(), result);
+      LHS = (*doLHSCast)(S, LHS.get(), result);
     return result;
   }
 }
@@ -1171,7 +1197,7 @@
       handleIntegerConversion<doComplexIntegralCast, doIntegralCast>
         (S, LHS, RHS, LHSEltType, RHSType, IsCompAssign);
     QualType ComplexType = S.Context.getComplexType(ScalarType);
-    RHS = S.ImpCastExprToType(RHS.take(), ComplexType,
+    RHS = S.ImpCastExprToType(RHS.get(), ComplexType,
                               CK_IntegralRealToComplex);
  
     return ComplexType;
@@ -1186,7 +1212,7 @@
   QualType ComplexType = S.Context.getComplexType(ScalarType);
   
   if (!IsCompAssign)
-    LHS = S.ImpCastExprToType(LHS.take(), ComplexType,
+    LHS = S.ImpCastExprToType(LHS.get(), ComplexType,
                               CK_IntegralRealToComplex);
   return ComplexType;
 }
@@ -1198,12 +1224,12 @@
 QualType Sema::UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS,
                                           bool IsCompAssign) {
   if (!IsCompAssign) {
-    LHS = UsualUnaryConversions(LHS.take());
+    LHS = UsualUnaryConversions(LHS.get());
     if (LHS.isInvalid())
       return QualType();
   }
 
-  RHS = UsualUnaryConversions(RHS.take());
+  RHS = UsualUnaryConversions(RHS.get());
   if (RHS.isInvalid())
     return QualType();
 
@@ -1235,7 +1261,7 @@
   if (!LHSBitfieldPromoteTy.isNull())
     LHSType = LHSBitfieldPromoteTy;
   if (LHSType != LHSUnpromotedType && !IsCompAssign)
-    LHS = ImpCastExprToType(LHS.take(), LHSType, CK_IntegralCast);
+    LHS = ImpCastExprToType(LHS.get(), LHSType, CK_IntegralCast);
 
   // If both types are identical, no conversion is needed.
   if (LHSType == RHSType)
@@ -1284,7 +1310,7 @@
     if (ArgTypes[i])
       (void) GetTypeFromParser(ArgTypes[i], &Types[i]);
     else
-      Types[i] = 0;
+      Types[i] = nullptr;
   }
 
   ExprResult ER = CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
@@ -1307,7 +1333,7 @@
   if (ControllingExpr->getType()->isPlaceholderType()) {
     ExprResult result = CheckPlaceholderExpr(ControllingExpr);
     if (result.isInvalid()) return ExprError();
-    ControllingExpr = result.take();
+    ControllingExpr = result.get();
   }
 
   bool TypeErrorFound = false,
@@ -1369,10 +1395,9 @@
   // If we determined that the generic selection is result-dependent, don't
   // try to compute the result expression.
   if (IsResultDependent)
-    return Owned(new (Context) GenericSelectionExpr(
-                   Context, KeyLoc, ControllingExpr,
-                   Types, Exprs,
-                   DefaultLoc, RParenLoc, ContainsUnexpandedParameterPack));
+    return new (Context) GenericSelectionExpr(
+        Context, KeyLoc, ControllingExpr, Types, Exprs, DefaultLoc, RParenLoc,
+        ContainsUnexpandedParameterPack);
 
   SmallVector<unsigned, 1> CompatIndices;
   unsigned DefaultIndex = -1U;
@@ -1424,11 +1449,9 @@
   unsigned ResultIndex =
     CompatIndices.size() ? CompatIndices[0] : DefaultIndex;
 
-  return Owned(new (Context) GenericSelectionExpr(
-                 Context, KeyLoc, ControllingExpr,
-                 Types, Exprs,
-                 DefaultLoc, RParenLoc, ContainsUnexpandedParameterPack,
-                 ResultIndex));
+  return new (Context) GenericSelectionExpr(
+      Context, KeyLoc, ControllingExpr, Types, Exprs, DefaultLoc, RParenLoc,
+      ContainsUnexpandedParameterPack, ResultIndex);
 }
 
 /// getUDSuffixLoc - Create a SourceLocation for a ud-suffix, given the
@@ -1476,16 +1499,15 @@
 /// string.
 ///
 ExprResult
-Sema::ActOnStringLiteral(const Token *StringToks, unsigned NumStringToks,
-                         Scope *UDLScope) {
-  assert(NumStringToks && "Must have at least one string!");
+Sema::ActOnStringLiteral(ArrayRef<Token> StringToks, Scope *UDLScope) {
+  assert(!StringToks.empty() && "Must have at least one string!");
 
-  StringLiteralParser Literal(StringToks, NumStringToks, PP);
+  StringLiteralParser Literal(StringToks, PP);
   if (Literal.hadError)
     return ExprError();
 
   SmallVector<SourceLocation, 4> StringTokLocs;
-  for (unsigned i = 0; i != NumStringToks; ++i)
+  for (unsigned i = 0; i != StringToks.size(); ++i)
     StringTokLocs.push_back(StringToks[i].getLocation());
 
   QualType CharTy = Context.CharTy;
@@ -1528,7 +1550,7 @@
                                              &StringTokLocs[0],
                                              StringTokLocs.size());
   if (Literal.getUDSuffix().empty())
-    return Owned(Lit);
+    return Lit;
 
   // We're building a user-defined literal.
   IdentifierInfo *UDSuffix = &Context.Idents.get(Literal.getUDSuffix());
@@ -1643,7 +1665,7 @@
         NameInfo.getLoc(), Ty, VK, FoundD, TemplateArgs);
   } else {
     assert(!TemplateArgs && "No template arguments for non-variable"
-                            " template specialization referrences");
+                            " template specialization references");
     E = DeclRefExpr::Create(
         Context,
         SS ? SS->getWithLocInContext(Context) : NestedNameSpecifierLoc(),
@@ -1653,20 +1675,16 @@
   MarkDeclRefReferenced(E);
 
   if (getLangOpts().ObjCARCWeak && isa<VarDecl>(D) &&
-      Ty.getObjCLifetime() == Qualifiers::OCL_Weak) {
-    DiagnosticsEngine::Level Level =
-      Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak,
-                               E->getLocStart());
-    if (Level != DiagnosticsEngine::Ignored)
+      Ty.getObjCLifetime() == Qualifiers::OCL_Weak &&
+      !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, E->getLocStart()))
       recordUseOfEvaluatedWeak(E);
-  }
 
   // Just in case we're building an illegal pointer-to-member.
   FieldDecl *FD = dyn_cast<FieldDecl>(D);
   if (FD && FD->isBitField())
     E->setObjectKind(OK_BitField);
 
-  return Owned(E);
+  return E;
 }
 
 /// Decomposes the given name into a DeclarationNameInfo, its location, and
@@ -1697,7 +1715,7 @@
     TemplateArgs = &Buffer;
   } else {
     NameInfo = GetNameFromUnqualifiedId(Id);
-    TemplateArgs = 0;
+    TemplateArgs = nullptr;
   }
 }
 
@@ -1724,7 +1742,7 @@
   // original lookup would not have found something because it was a
   // dependent name.
   DeclContext *DC = (SS.isEmpty() && !CallsUndergoingInstantiation.empty())
-    ? CurContext : 0;
+    ? CurContext : nullptr;
   while (DC) {
     if (isa<CXXRecordDecl>(DC)) {
       LookupQualifiedName(R, DC);
@@ -1748,8 +1766,8 @@
         // Give a code modification hint to insert 'this->'.
         // TODO: fixit for inserting 'Base<T>::' in the other cases.
         // Actually quite difficult!
-        if (getLangOpts().MicrosoftMode)
-          diagnostic = diag::warn_found_via_dependent_bases_lookup;
+        if (getLangOpts().MSVCCompat)
+          diagnostic = diag::ext_found_via_dependent_bases_lookup;
         if (isInstance) {
           Diag(R.getNameLoc(), diagnostic) << Name
             << FixItHint::CreateInsertion(R.getNameLoc(), "this->");
@@ -1782,9 +1800,9 @@
               CXXDependentScopeMemberExpr::Create(
                   Context, DepThis, DepThisType, true, SourceLocation(),
                   SS.getWithLocInContext(Context),
-                  ULE->getTemplateKeywordLoc(), 0,
+                  ULE->getTemplateKeywordLoc(), nullptr,
                   R.getLookupNameInfo(),
-                  ULE->hasExplicitTemplateArgs() ? &TList : 0);
+                  ULE->hasExplicitTemplateArgs() ? &TList : nullptr);
           CallsUndergoingInstantiation.back()->setCallee(DepExpr);
         } else {
           Diag(R.getNameLoc(), diagnostic) << Name;
@@ -1814,7 +1832,7 @@
     // function definition declared at class scope then we must set
     // DC to the lexical parent to be able to search into the parent
     // class.
-    if (getLangOpts().MicrosoftMode && isa<FunctionDecl>(DC) &&
+    if (getLangOpts().MSVCCompat && isa<FunctionDecl>(DC) &&
         cast<FunctionDecl>(DC)->getFriendObjectKind() &&
         DC->getLexicalParent()->isRecord())
       DC = DC->getLexicalParent();
@@ -1825,7 +1843,7 @@
   // We didn't find anything, so try to correct for a typo.
   TypoCorrection Corrected;
   if (S && (Corrected = CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(),
-                                    S, &SS, CCC))) {
+                                    S, &SS, CCC, CTK_ErrorRecovery))) {
     std::string CorrectedStr(Corrected.getAsString(getLangOpts()));
     bool DroppedSpecifier =
         Corrected.WillReplaceSpecifier() && Name.getAsString() == CorrectedStr;
@@ -1836,7 +1854,8 @@
     NamedDecl *ND = Corrected.getCorrectionDecl();
     if (ND) {
       if (Corrected.isOverloaded()) {
-        OverloadCandidateSet OCS(R.getNameLoc());
+        OverloadCandidateSet OCS(R.getNameLoc(),
+                                 OverloadCandidateSet::CSK_Normal);
         OverloadCandidateSet::iterator Best;
         for (TypoCorrection::decl_iterator CD = Corrected.begin(),
                                         CDEnd = Corrected.end();
@@ -1863,6 +1882,17 @@
         }
       }
       R.addDecl(ND);
+      if (getLangOpts().CPlusPlus && ND->isCXXClassMember()) {
+        CXXRecordDecl *Record = nullptr;
+        if (Corrected.getCorrectionSpecifier()) {
+          const Type *Ty = Corrected.getCorrectionSpecifier()->getAsType();
+          Record = Ty->getAsCXXRecordDecl();
+        }
+        if (!Record)
+          Record = cast<CXXRecordDecl>(
+              ND->getDeclContext()->getRedeclContext());
+        R.setNamingClass(Record);
+      }
 
       AcceptableWithRecovery =
           isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND);
@@ -1913,6 +1943,53 @@
   return true;
 }
 
+/// In Microsoft mode, if we are inside a template class whose parent class has
+/// dependent base classes, and we can't resolve an unqualified identifier, then
+/// assume the identifier is a member of a dependent base class.  We can only
+/// recover successfully in static methods, instance methods, and other contexts
+/// where 'this' is available.  This doesn't precisely match MSVC's
+/// instantiation model, but it's close enough.
+static Expr *
+recoverFromMSUnqualifiedLookup(Sema &S, ASTContext &Context,
+                               DeclarationNameInfo &NameInfo,
+                               SourceLocation TemplateKWLoc,
+                               const TemplateArgumentListInfo *TemplateArgs) {
+  // Only try to recover from lookup into dependent bases in static methods or
+  // contexts where 'this' is available.
+  QualType ThisType = S.getCurrentThisType();
+  const CXXRecordDecl *RD = nullptr;
+  if (!ThisType.isNull())
+    RD = ThisType->getPointeeType()->getAsCXXRecordDecl();
+  else if (auto *MD = dyn_cast<CXXMethodDecl>(S.CurContext))
+    RD = MD->getParent();
+  if (!RD || !RD->hasAnyDependentBases())
+    return nullptr;
+
+  // Diagnose this as unqualified lookup into a dependent base class.  If 'this'
+  // is available, suggest inserting 'this->' as a fixit.
+  SourceLocation Loc = NameInfo.getLoc();
+  auto DB = S.Diag(Loc, diag::ext_undeclared_unqual_id_with_dependent_base);
+  DB << NameInfo.getName() << RD;
+
+  if (!ThisType.isNull()) {
+    DB << FixItHint::CreateInsertion(Loc, "this->");
+    return CXXDependentScopeMemberExpr::Create(
+        Context, /*This=*/nullptr, ThisType, /*IsArrow=*/true,
+        /*Op=*/SourceLocation(), NestedNameSpecifierLoc(), TemplateKWLoc,
+        /*FirstQualifierInScope=*/nullptr, NameInfo, TemplateArgs);
+  }
+
+  // Synthesize a fake NNS that points to the derived class.  This will
+  // perform name lookup during template instantiation.
+  CXXScopeSpec SS;
+  auto *NNS =
+      NestedNameSpecifier::Create(Context, nullptr, true, RD->getTypeForDecl());
+  SS.MakeTrivial(Context, NNS, SourceRange(Loc, Loc));
+  return DependentScopeDeclRefExpr::Create(
+      Context, SS.getWithLocInContext(Context), TemplateKWLoc, NameInfo,
+      TemplateArgs);
+}
+
 ExprResult Sema::ActOnIdExpression(Scope *S,
                                    CXXScopeSpec &SS,
                                    SourceLocation TemplateKWLoc,
@@ -2000,77 +2077,59 @@
       if (E.isInvalid())
         return ExprError();
 
-      if (Expr *Ex = E.takeAs<Expr>())
-        return Owned(Ex);
+      if (Expr *Ex = E.getAs<Expr>())
+        return Ex;
     }
   }
 
   if (R.isAmbiguous())
     return ExprError();
 
+  // This could be an implicitly declared function reference (legal in C90,
+  // extension in C99, forbidden in C++).
+  if (R.empty() && HasTrailingLParen && II && !getLangOpts().CPlusPlus) {
+    NamedDecl *D = ImplicitlyDefineFunction(NameLoc, *II, S);
+    if (D) R.addDecl(D);
+  }
+
   // Determine whether this name might be a candidate for
   // argument-dependent lookup.
   bool ADL = UseArgumentDependentLookup(SS, R, HasTrailingLParen);
 
   if (R.empty() && !ADL) {
-
-    // Otherwise, this could be an implicitly declared function reference (legal
-    // in C90, extension in C99, forbidden in C++).
-    if (HasTrailingLParen && II && !getLangOpts().CPlusPlus) {
-      NamedDecl *D = ImplicitlyDefineFunction(NameLoc, *II, S);
-      if (D) R.addDecl(D);
+    if (SS.isEmpty() && getLangOpts().MSVCCompat) {
+      if (Expr *E = recoverFromMSUnqualifiedLookup(*this, Context, NameInfo,
+                                                   TemplateKWLoc, TemplateArgs))
+        return E;
     }
 
+    // Don't diagnose an empty lookup for inline assembly.
+    if (IsInlineAsmIdentifier)
+      return ExprError();
+
     // If this name wasn't predeclared and if this is not a function
     // call, diagnose the problem.
-    if (R.empty()) {
-      // In Microsoft mode, if we are inside a template class member function
-      // whose parent class has dependent base classes, and we can't resolve
-      // an identifier, then assume the identifier is a member of a dependent
-      // base class.  The goal is to postpone name lookup to instantiation time
-      // to be able to search into the type dependent base classes.
-      // FIXME: If we want 100% compatibility with MSVC, we will have delay all
-      // unqualified name lookup.  Any name lookup during template parsing means
-      // clang might find something that MSVC doesn't.  For now, we only handle
-      // the common case of members of a dependent base class.
-      if (getLangOpts().MicrosoftMode) {
-        CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CurContext);
-        if (MD && MD->isInstance() && MD->getParent()->hasAnyDependentBases()) {
-          assert(SS.isEmpty() && "qualifiers should be already handled");
-          QualType ThisType = MD->getThisType(Context);
-          // Since the 'this' expression is synthesized, we don't need to
-          // perform the double-lookup check.
-          NamedDecl *FirstQualifierInScope = 0;
-          return Owned(CXXDependentScopeMemberExpr::Create(
-              Context, /*This=*/0, ThisType, /*IsArrow=*/true,
-              /*Op=*/SourceLocation(), SS.getWithLocInContext(Context),
-              TemplateKWLoc, FirstQualifierInScope, NameInfo, TemplateArgs));
-        }
-      }
+    CorrectionCandidateCallback DefaultValidator;
+    DefaultValidator.IsAddressOfOperand = IsAddressOfOperand;
+    assert((!CCC || CCC->IsAddressOfOperand == IsAddressOfOperand) &&
+           "Typo correction callback misconfigured");
+    if (DiagnoseEmptyLookup(S, SS, R, CCC ? *CCC : DefaultValidator))
+      return ExprError();
 
-      // Don't diagnose an empty lookup for inline assmebly.
-      if (IsInlineAsmIdentifier)
+    assert(!R.empty() &&
+           "DiagnoseEmptyLookup returned false but added no results");
+
+    // If we found an Objective-C instance variable, let
+    // LookupInObjCMethod build the appropriate expression to
+    // reference the ivar.
+    if (ObjCIvarDecl *Ivar = R.getAsSingle<ObjCIvarDecl>()) {
+      R.clear();
+      ExprResult E(LookupInObjCMethod(R, S, Ivar->getIdentifier()));
+      // In a hopelessly buggy code, Objective-C instance variable
+      // lookup fails and no expression will be built to reference it.
+      if (!E.isInvalid() && !E.get())
         return ExprError();
-
-      CorrectionCandidateCallback DefaultValidator;
-      if (DiagnoseEmptyLookup(S, SS, R, CCC ? *CCC : DefaultValidator))
-        return ExprError();
-
-      assert(!R.empty() &&
-             "DiagnoseEmptyLookup returned false but added no results");
-
-      // If we found an Objective-C instance variable, let
-      // LookupInObjCMethod build the appropriate expression to
-      // reference the ivar.
-      if (ObjCIvarDecl *Ivar = R.getAsSingle<ObjCIvarDecl>()) {
-        R.clear();
-        ExprResult E(LookupInObjCMethod(R, S, Ivar->getIdentifier()));
-        // In a hopelessly buggy code, Objective-C instance variable
-        // lookup fails and no expression will be built to reference it.
-        if (!E.isInvalid() && !E.get())
-          return ExprError();
-        return E;
-      }
+      return E;
     }
   }
 
@@ -2145,11 +2204,12 @@
 ExprResult
 Sema::BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS,
                                         const DeclarationNameInfo &NameInfo,
-                                        bool IsAddressOfOperand) {
+                                        bool IsAddressOfOperand,
+                                        TypeSourceInfo **RecoveryTSI) {
   DeclContext *DC = computeDeclContext(SS, false);
   if (!DC)
     return BuildDependentDeclRefExpr(SS, /*TemplateKWLoc=*/SourceLocation(),
-                                     NameInfo, /*TemplateArgs=*/0);
+                                     NameInfo, /*TemplateArgs=*/nullptr);
 
   if (RequireCompleteDeclContext(SS, DC))
     return ExprError();
@@ -2162,7 +2222,7 @@
 
   if (R.getResultKind() == LookupResult::NotFoundInCurrentInstantiation)
     return BuildDependentDeclRefExpr(SS, /*TemplateKWLoc=*/SourceLocation(),
-                                     NameInfo, /*TemplateArgs=*/0);
+                                     NameInfo, /*TemplateArgs=*/nullptr);
 
   if (R.empty()) {
     Diag(NameInfo.getLoc(), diag::err_no_member)
@@ -2170,6 +2230,41 @@
     return ExprError();
   }
 
+  if (const TypeDecl *TD = R.getAsSingle<TypeDecl>()) {
+    // Diagnose a missing typename if this resolved unambiguously to a type in
+    // a dependent context.  If we can recover with a type, downgrade this to
+    // a warning in Microsoft compatibility mode.
+    unsigned DiagID = diag::err_typename_missing;
+    if (RecoveryTSI && getLangOpts().MSVCCompat)
+      DiagID = diag::ext_typename_missing;
+    SourceLocation Loc = SS.getBeginLoc();
+    auto D = Diag(Loc, DiagID);
+    D << SS.getScopeRep() << NameInfo.getName().getAsString()
+      << SourceRange(Loc, NameInfo.getEndLoc());
+
+    // Don't recover if the caller isn't expecting us to or if we're in a SFINAE
+    // context.
+    if (!RecoveryTSI)
+      return ExprError();
+
+    // Only issue the fixit if we're prepared to recover.
+    D << FixItHint::CreateInsertion(Loc, "typename ");
+
+    // Recover by pretending this was an elaborated type.
+    QualType Ty = Context.getTypeDeclType(TD);
+    TypeLocBuilder TLB;
+    TLB.pushTypeSpec(Ty).setNameLoc(NameInfo.getLoc());
+
+    QualType ET = getElaboratedType(ETK_None, SS, Ty);
+    ElaboratedTypeLoc QTL = TLB.push<ElaboratedTypeLoc>(ET);
+    QTL.setElaboratedKeywordLoc(SourceLocation());
+    QTL.setQualifierLoc(SS.getWithLocInContext(Context));
+
+    *RecoveryTSI = TLB.getTypeSourceInfo(Context, ET);
+
+    return ExprEmpty();
+  }
+
   // Defend against this resolving to an implicit member access. We usually
   // won't get here if this might be a legitimate a class member (we end up in
   // BuildMemberReferenceExpr instead), but this can be valid if we're forming
@@ -2177,7 +2272,7 @@
   if (!R.empty() && (*R.begin())->isCXXClassMember() && !IsAddressOfOperand)
     return BuildPossibleImplicitMemberExpr(SS,
                                            /*TemplateKWLoc=*/SourceLocation(),
-                                           R, /*TemplateArgs=*/0);
+                                           R, /*TemplateArgs=*/nullptr);
 
   return BuildDeclarationNameExpr(SS, R, /* ADL */ false);
 }
@@ -2219,11 +2314,11 @@
   else
     LookForIvars = (Lookup.isSingleResult() &&
                     Lookup.getFoundDecl()->isDefinedOutsideFunctionOrMethod());
-  ObjCInterfaceDecl *IFace = 0;
+  ObjCInterfaceDecl *IFace = nullptr;
   if (LookForIvars) {
     IFace = CurMethod->getClassInterface();
     ObjCInterfaceDecl *ClassDeclared;
-    ObjCIvarDecl *IV = 0;
+    ObjCIvarDecl *IV = nullptr;
     if (IFace && (IV = IFace->lookupInstanceVariable(II, ClassDeclared))) {
       // Diagnose using an ivar in a class method.
       if (IsClassMethod)
@@ -2258,20 +2353,12 @@
       if (SelfExpr.isInvalid())
         return ExprError();
 
-      SelfExpr = DefaultLvalueConversion(SelfExpr.take());
+      SelfExpr = DefaultLvalueConversion(SelfExpr.get());
       if (SelfExpr.isInvalid())
         return ExprError();
 
       MarkAnyDeclReferenced(Loc, IV, true);
-      if (!IV->getBackingIvarReferencedInAccessor()) {
-        // Mark this ivar 'referenced' in this method, if it is a backing ivar
-        // of a property and current method is one of its property accessor.
-        const ObjCPropertyDecl *PDecl;
-        const ObjCIvarDecl *BIV = GetIvarBackingPropertyAccessor(CurMethod, PDecl);
-        if (BIV && BIV == IV)
-          IV->setBackingIvarReferencedInAccessor(true);
-      }
-      
+
       ObjCMethodFamily MF = CurMethod->getMethodFamily();
       if (MF != OMF_init && MF != OMF_dealloc && MF != OMF_finalize &&
           !IvarBacksCurrentMethodAccessor(IFace, CurMethod, IV))
@@ -2279,14 +2366,12 @@
 
       ObjCIvarRefExpr *Result = new (Context) ObjCIvarRefExpr(IV, IV->getType(),
                                                               Loc, IV->getLocation(),
-                                                              SelfExpr.take(),
+                                                              SelfExpr.get(),
                                                               true, true);
 
       if (getLangOpts().ObjCAutoRefCount) {
         if (IV->getType().getObjCLifetime() == Qualifiers::OCL_Weak) {
-          DiagnosticsEngine::Level Level =
-            Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak, Loc);
-          if (Level != DiagnosticsEngine::Ignored)
+          if (!Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
             recordUseOfEvaluatedWeak(Result);
         }
         if (CurContext->isClosure())
@@ -2294,7 +2379,7 @@
             << FixItHint::CreateInsertion(Loc, "self->");
       }
       
-      return Owned(Result);
+      return Result;
     }
   } else if (CurMethod->isInstanceMethod()) {
     // We should warn if a local variable hides an ivar.
@@ -2327,7 +2412,7 @@
     }
   }
   // Sentinel value saying that we didn't do anything special.
-  return Owned((Expr*) 0);
+  return ExprResult((Expr *)nullptr);
 }
 
 /// \brief Cast a base object to a member's actual type.
@@ -2354,7 +2439,7 @@
                                     NamedDecl *Member) {
   CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Member->getDeclContext());
   if (!RD)
-    return Owned(From);
+    return From;
 
   QualType DestRecordType;
   QualType DestType;
@@ -2374,7 +2459,7 @@
     }
   } else if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Member)) {
     if (Method->isStatic())
-      return Owned(From);
+      return From;
 
     DestType = Method->getThisType(Context);
     DestRecordType = DestType->getPointeeType();
@@ -2388,15 +2473,15 @@
     }
   } else {
     // No conversion necessary.
-    return Owned(From);
+    return From;
   }
 
   if (DestType->isDependentType() || FromType->isDependentType())
-    return Owned(From);
+    return From;
 
   // If the unqualified types are the same, no conversion is necessary.
   if (Context.hasSameUnqualifiedType(FromRecordType, DestRecordType))
-    return Owned(From);
+    return From;
 
   SourceRange FromRange = From->getSourceRange();
   SourceLocation FromLoc = FromRange.getBegin();
@@ -2439,7 +2524,7 @@
       if (PointerConversions)
         QType = Context.getPointerType(QType);
       From = ImpCastExprToType(From, QType, CK_UncheckedDerivedToBase,
-                               VK, &BasePath).take();
+                               VK, &BasePath).get();
 
       FromType = QType;
       FromRecordType = QRecordType;
@@ -2447,7 +2532,7 @@
       // If the qualifier type was the same as the destination type,
       // we're done.
       if (Context.hasSameUnqualifiedType(FromRecordType, DestRecordType))
-        return Owned(From);
+        return From;
     }
   }
 
@@ -2476,7 +2561,7 @@
       if (PointerConversions)
         UType = Context.getPointerType(UType);
       From = ImpCastExprToType(From, UType, CK_UncheckedDerivedToBase,
-                               VK, &BasePath).take();
+                               VK, &BasePath).get();
       FromType = UType;
       FromRecordType = URecordType;
     }
@@ -2604,7 +2689,7 @@
                                    NeedsADL, R.isOverloadedResult(),
                                    R.begin(), R.end());
 
-  return Owned(ULE);
+  return ULE;
 }
 
 /// \brief Complete semantic analysis for a reference to the given declaration.
@@ -2755,7 +2840,7 @@
 
       // If we're referring to a function with an __unknown_anytype
       // result type, make the entire expression __unknown_anytype.
-      if (fty->getResultType() == Context.UnknownAnyTy) {
+      if (fty->getReturnType() == Context.UnknownAnyTy) {
         type = Context.UnknownAnyTy;
         valueKind = VK_RValue;
         break;
@@ -2774,7 +2859,7 @@
       // type.
       if (!cast<FunctionDecl>(VD)->hasPrototype() &&
           isa<FunctionProtoType>(fty))
-        type = Context.getFunctionNoProtoType(fty->getResultType(),
+        type = Context.getFunctionNoProtoType(fty->getReturnType(),
                                               fty->getExtInfo());
 
       // Functions are r-values in C.
@@ -2792,7 +2877,7 @@
       // This should only be possible with a type written directly.
       if (const FunctionProtoType *proto
             = dyn_cast<FunctionProtoType>(VD->getType()))
-        if (proto->getResultType() == Context.UnknownAnyTy) {
+        if (proto->getReturnType() == Context.UnknownAnyTy) {
           type = Context.UnknownAnyTy;
           valueKind = VK_RValue;
           break;
@@ -2820,7 +2905,7 @@
 ExprResult Sema::BuildPredefinedExpr(SourceLocation Loc,
                                      PredefinedExpr::IdentType IT) {
   // Pick the current block, lambda, captured statement or function.
-  Decl *currentDecl = 0;
+  Decl *currentDecl = nullptr;
   if (const BlockScopeInfo *BSI = getCurBlock())
     currentDecl = BSI->TheDecl;
   else if (const LambdaScopeInfo *LSI = getCurLambda())
@@ -2851,7 +2936,7 @@
     ResTy = Context.getConstantArrayType(ResTy, LengthI, ArrayType::Normal, 0);
   }
 
-  return Owned(new (Context) PredefinedExpr(Loc, ResTy, IT));
+  return new (Context) PredefinedExpr(Loc, ResTy, IT);
 }
 
 ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind) {
@@ -2862,6 +2947,7 @@
   case tok::kw___func__: IT = PredefinedExpr::Func; break; // [C99 6.4.2.2]
   case tok::kw___FUNCTION__: IT = PredefinedExpr::Function; break;
   case tok::kw___FUNCDNAME__: IT = PredefinedExpr::FuncDName; break; // [MS]
+  case tok::kw___FUNCSIG__: IT = PredefinedExpr::FuncSig; break; // [MS]
   case tok::kw_L__FUNCTION__: IT = PredefinedExpr::LFunction; break;
   case tok::kw___PRETTY_FUNCTION__: IT = PredefinedExpr::PrettyFunction; break;
   }
@@ -2905,7 +2991,7 @@
                                              Tok.getLocation());
 
   if (Literal.getUDSuffix().empty())
-    return Owned(Lit);
+    return Lit;
 
   // We're building a user-defined literal.
   IdentifierInfo *UDSuffix = &Context.Idents.get(Literal.getUDSuffix());
@@ -2924,8 +3010,8 @@
 
 ExprResult Sema::ActOnIntegerConstant(SourceLocation Loc, uint64_t Val) {
   unsigned IntSize = Context.getTargetInfo().getIntWidth();
-  return Owned(IntegerLiteral::Create(Context, llvm::APInt(IntSize, Val),
-                                      Context.IntTy, Loc));
+  return IntegerLiteral::Create(Context, llvm::APInt(IntSize, Val),
+                                Context.IntTy, Loc);
 }
 
 static Expr *BuildFloatingLiteral(Sema &S, NumericLiteralParser &Literal,
@@ -3090,10 +3176,10 @@
 
     if (Ty == Context.DoubleTy) {
       if (getLangOpts().SinglePrecisionConstants) {
-        Res = ImpCastExprToType(Res, Context.FloatTy, CK_FloatingCast).take();
+        Res = ImpCastExprToType(Res, Context.FloatTy, CK_FloatingCast).get();
       } else if (getLangOpts().OpenCL && !getOpenCLOptions().cl_khr_fp64) {
         Diag(Tok.getLocation(), diag::warn_double_const_requires_fp64);
-        Res = ImpCastExprToType(Res, Context.FloatTy, CK_FloatingCast).take();
+        Res = ImpCastExprToType(Res, Context.FloatTy, CK_FloatingCast).get();
       }
     }
   } else if (!Literal.isIntegerLiteral()) {
@@ -3117,8 +3203,8 @@
     // may be wider than [u]intmax_t.
     // FIXME: Actually, they don't. We seem to have accidentally invented the
     //        i128 suffix.
-    if (Literal.isMicrosoftInteger && MaxWidth < 128 &&
-        PP.getTargetInfo().hasInt128Type())
+    if (Literal.MicrosoftInteger == 128 && MaxWidth < 128 &&
+        Context.getTargetInfo().hasInt128Type())
       MaxWidth = 128;
     llvm::APInt ResultVal(MaxWidth, 0);
 
@@ -3138,7 +3224,22 @@
 
       // Check from smallest to largest, picking the smallest type we can.
       unsigned Width = 0;
-      if (!Literal.isLong && !Literal.isLongLong) {
+
+      // Microsoft specific integer suffixes are explicitly sized.
+      if (Literal.MicrosoftInteger) {
+        if (Literal.MicrosoftInteger > MaxWidth) {
+          // If this target doesn't support __int128, error and force to ull.
+          Diag(Tok.getLocation(), diag::err_int128_unsupported);
+          Width = MaxWidth;
+          Ty = Context.getIntMaxType();
+        } else {
+          Width = Literal.MicrosoftInteger;
+          Ty = Context.getIntTypeForBitwidth(Width,
+                                             /*Signed=*/!Literal.isUnsigned);
+        }
+      }
+
+      if (Ty.isNull() && !Literal.isLong && !Literal.isLongLong) {
         // Are int/unsigned possibilities?
         unsigned IntSize = Context.getTargetInfo().getIntWidth();
 
@@ -3185,22 +3286,11 @@
           Width = LongLongSize;
         }
       }
-        
-      // If it doesn't fit in unsigned long long, and we're using Microsoft
-      // extensions, then its a 128-bit integer literal.
-      if (Ty.isNull() && Literal.isMicrosoftInteger &&
-          PP.getTargetInfo().hasInt128Type()) {
-        if (Literal.isUnsigned)
-          Ty = Context.UnsignedInt128Ty;
-        else
-          Ty = Context.Int128Ty;
-        Width = 128;
-      }
 
       // If we still couldn't decide a type, we probably have something that
       // does not fit in a signed long long, but has no U suffix.
       if (Ty.isNull()) {
-        Diag(Tok.getLocation(), diag::warn_integer_too_large_for_signed);
+        Diag(Tok.getLocation(), diag::ext_integer_too_large_for_signed);
         Ty = Context.UnsignedLongLongTy;
         Width = Context.getTargetInfo().getLongLongWidth();
       }
@@ -3216,12 +3306,12 @@
     Res = new (Context) ImaginaryLiteral(Res,
                                         Context.getComplexType(Res->getType()));
 
-  return Owned(Res);
+  return Res;
 }
 
 ExprResult Sema::ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E) {
-  assert((E != 0) && "ActOnParenExpr() missing expr");
-  return Owned(new (Context) ParenExpr(L, R, E));
+  assert(E && "ActOnParenExpr() missing expr");
+  return new (Context) ParenExpr(L, R, E);
 }
 
 static bool CheckVecStepTraitOperandType(Sema &S, QualType T,
@@ -3259,9 +3349,12 @@
     return false;
   }
 
-  // Allow sizeof(void)/alignof(void) as an extension.
+  // Allow sizeof(void)/alignof(void) as an extension, unless in OpenCL where
+  // this is an error (OpenCL v1.1 s6.3.k)
   if (T->isVoidType()) {
-    S.Diag(Loc, diag::ext_sizeof_alignof_void_type) << TraitKind << ArgRange;
+    unsigned DiagID = S.LangOpts.OpenCL ? diag::err_opencl_sizeof_alignof_type
+                                        : diag::ext_sizeof_alignof_void_type;
+    S.Diag(Loc, DiagID) << TraitKind << ArgRange;
     return false;
   }
 
@@ -3302,7 +3395,7 @@
                                              << ICE->getSubExpr()->getType();
 }
 
-/// \brief Check the constrains on expression operands to unary type expression
+/// \brief Check the constraints on expression operands to unary type expression
 /// and type traits.
 ///
 /// Completes any types necessary and validates the constraints on the operand
@@ -3323,10 +3416,21 @@
                                       E->getSourceRange(), ExprKind))
     return false;
 
-  if (RequireCompleteExprType(E,
-                              diag::err_sizeof_alignof_incomplete_type,
-                              ExprKind, E->getSourceRange()))
-    return true;
+  // 'alignof' applied to an expression only requires the base element type of
+  // the expression to be complete. 'sizeof' requires the expression's type to
+  // be complete (and will attempt to complete it if it's an array of unknown
+  // bound).
+  if (ExprKind == UETT_AlignOf) {
+    if (RequireCompleteType(E->getExprLoc(),
+                            Context.getBaseElementType(E->getType()),
+                            diag::err_sizeof_alignof_incomplete_type, ExprKind,
+                            E->getSourceRange()))
+      return true;
+  } else {
+    if (RequireCompleteExprType(E, diag::err_sizeof_alignof_incomplete_type,
+                                ExprKind, E->getSourceRange()))
+      return true;
+  }
 
   // Completing the expression's type may have changed it.
   ExprTy = E->getType();
@@ -3391,13 +3495,21 @@
   if (ExprType->isDependentType())
     return false;
 
-  // C++ [expr.sizeof]p2: "When applied to a reference or a reference type,
-  //   the result is the size of the referenced type."
-  // C++ [expr.alignof]p3: "When alignof is applied to a reference type, the
-  //   result shall be the alignment of the referenced type."
+  // C++ [expr.sizeof]p2:
+  //     When applied to a reference or a reference type, the result
+  //     is the size of the referenced type.
+  // C++11 [expr.alignof]p3:
+  //     When alignof is applied to a reference type, the result
+  //     shall be the alignment of the referenced type.
   if (const ReferenceType *Ref = ExprType->getAs<ReferenceType>())
     ExprType = Ref->getPointeeType();
 
+  // C11 6.5.3.4/3, C++11 [expr.alignof]p3:
+  //   When alignof or _Alignof is applied to an array type, the result
+  //   is the alignment of the element type.
+  if (ExprKind == UETT_AlignOf)
+    ExprType = Context.getBaseElementType(ExprType);
+
   if (ExprKind == UETT_VecStep)
     return CheckVecStepTraitOperandType(*this, ExprType, OpLoc, ExprRange);
 
@@ -3437,7 +3549,7 @@
     return true;
   }
 
-  ValueDecl *D = 0;
+  ValueDecl *D = nullptr;
   if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
     D = DRE->getDecl();
   } else if (MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
@@ -3447,21 +3559,10 @@
   // If it's a field, require the containing struct to have a
   // complete definition so that we can compute the layout.
   //
-  // This requires a very particular set of circumstances.  For a
-  // field to be contained within an incomplete type, we must in the
-  // process of parsing that type.  To have an expression refer to a
-  // field, it must be an id-expression or a member-expression, but
-  // the latter are always ill-formed when the base type is
-  // incomplete, including only being partially complete.  An
-  // id-expression can never refer to a field in C because fields
-  // are not in the ordinary namespace.  In C++, an id-expression
-  // can implicitly be a member access, but only if there's an
-  // implicit 'this' value, and all such contexts are subject to
-  // delayed parsing --- except for trailing return types in C++11.
-  // And if an id-expression referring to a field occurs in a
-  // context that lacks a 'this' value, it's ill-formed --- except,
-  // agian, in C++11, where such references are allowed in an
-  // unevaluated context.  So C++11 introduces some new complexity.
+  // This can happen in C++11 onwards, either by naming the member
+  // in a way that is not transformed into a member access expression
+  // (in an unevaluated operand, for instance), or by naming the member
+  // in a trailing-return-type.
   //
   // For the record, since __alignof__ on expressions is a GCC
   // extension, GCC seems to permit this but always gives the
@@ -3518,9 +3619,8 @@
     return ExprError();
 
   // C99 6.5.3.4p4: the type (an unsigned integer type) is size_t.
-  return Owned(new (Context) UnaryExprOrTypeTraitExpr(ExprKind, TInfo,
-                                                      Context.getSizeType(),
-                                                      OpLoc, R.getEnd()));
+  return new (Context) UnaryExprOrTypeTraitExpr(
+      ExprKind, TInfo, Context.getSizeType(), OpLoc, R.getEnd());
 }
 
 /// \brief Build a sizeof or alignof expression given an expression
@@ -3555,13 +3655,12 @@
   if (ExprKind == UETT_SizeOf && E->getType()->isVariableArrayType()) {
     PE = TransformToPotentiallyEvaluated(E);
     if (PE.isInvalid()) return ExprError();
-    E = PE.take();
+    E = PE.get();
   }
 
   // C99 6.5.3.4p4: the type (an unsigned integer type) is size_t.
-  return Owned(new (Context) UnaryExprOrTypeTraitExpr(
-      ExprKind, E, Context.getSizeType(), OpLoc,
-      E->getSourceRange().getEnd()));
+  return new (Context) UnaryExprOrTypeTraitExpr(
+      ExprKind, E, Context.getSizeType(), OpLoc, E->getSourceRange().getEnd());
 }
 
 /// ActOnUnaryExprOrTypeTraitExpr - Handle @c sizeof(type) and @c sizeof @c
@@ -3572,7 +3671,7 @@
                                     UnaryExprOrTypeTrait ExprKind, bool IsType,
                                     void *TyOrEx, const SourceRange &ArgRange) {
   // If error parsing type, ignore.
-  if (TyOrEx == 0) return ExprError();
+  if (!TyOrEx) return ExprError();
 
   if (IsType) {
     TypeSourceInfo *TInfo;
@@ -3592,7 +3691,7 @@
 
   // _Real and _Imag are only l-values for normal l-values.
   if (V.get()->getObjectKind() != OK_Ordinary) {
-    V = S.DefaultLvalueConversion(V.take());
+    V = S.DefaultLvalueConversion(V.get());
     if (V.isInvalid())
       return QualType();
   }
@@ -3634,7 +3733,7 @@
   // Since this might is a postfix expression, get rid of ParenListExprs.
   ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Input);
   if (Result.isInvalid()) return ExprError();
-  Input = Result.take();
+  Input = Result.get();
 
   return BuildUnaryOp(S, OpLoc, Opc, Input);
 }
@@ -3663,7 +3762,7 @@
   if (isa<ParenListExpr>(base)) {
     ExprResult result = MaybeConvertParenListExprToParenExpr(S, base);
     if (result.isInvalid()) return ExprError();
-    base = result.take();
+    base = result.get();
   }
 
   // Handle any non-overload placeholder types in the base and index
@@ -3674,21 +3773,19 @@
   if (base->getType()->isNonOverloadPlaceholderType()) {
     ExprResult result = CheckPlaceholderExpr(base);
     if (result.isInvalid()) return ExprError();
-    base = result.take();
+    base = result.get();
   }
   if (idx->getType()->isNonOverloadPlaceholderType()) {
     ExprResult result = CheckPlaceholderExpr(idx);
     if (result.isInvalid()) return ExprError();
-    idx = result.take();
+    idx = result.get();
   }
 
   // Build an unanalyzed expression if either operand is type-dependent.
   if (getLangOpts().CPlusPlus &&
       (base->isTypeDependent() || idx->isTypeDependent())) {
-    return Owned(new (Context) ArraySubscriptExpr(base, idx,
-                                                  Context.DependentTy,
-                                                  VK_LValue, OK_Ordinary,
-                                                  rbLoc));
+    return new (Context) ArraySubscriptExpr(base, idx, Context.DependentTy,
+                                            VK_LValue, OK_Ordinary, rbLoc);
   }
 
   // Use C++ overloaded-operator rules if either operand has record
@@ -3720,12 +3817,12 @@
     ExprResult Result = DefaultFunctionArrayLvalueConversion(LHSExp);
     if (Result.isInvalid())
       return ExprError();
-    LHSExp = Result.take();
+    LHSExp = Result.get();
   }
   ExprResult Result = DefaultFunctionArrayLvalueConversion(RHSExp);
   if (Result.isInvalid())
     return ExprError();
-  RHSExp = Result.take();
+  RHSExp = Result.get();
 
   QualType LHSTy = LHSExp->getType(), RHSTy = RHSExp->getType();
   ExprValueKind VK = VK_LValue;
@@ -3753,7 +3850,8 @@
     // Use custom logic if this should be the pseudo-object subscript
     // expression.
     if (!LangOpts.isSubscriptPointerArithmetic())
-      return BuildObjCSubscriptExpression(RLoc, BaseExpr, IndexExpr, 0, 0);
+      return BuildObjCSubscriptExpression(RLoc, BaseExpr, IndexExpr, nullptr,
+                                          nullptr);
 
     ResultType = PTy->getPointeeType();
   } else if (const PointerType *PTy = RHSTy->getAs<PointerType>()) {
@@ -3790,7 +3888,7 @@
     Diag(LHSExp->getLocStart(), diag::ext_subscript_non_lvalue) <<
         LHSExp->getSourceRange();
     LHSExp = ImpCastExprToType(LHSExp, Context.getArrayDecayedType(LHSTy),
-                               CK_ArrayToPointerDecay).take();
+                               CK_ArrayToPointerDecay).get();
     LHSTy = LHSExp->getType();
 
     BaseExpr = LHSExp;
@@ -3801,7 +3899,7 @@
     Diag(RHSExp->getLocStart(), diag::ext_subscript_non_lvalue) <<
         RHSExp->getSourceRange();
     RHSExp = ImpCastExprToType(RHSExp, Context.getArrayDecayedType(RHSTy),
-                               CK_ArrayToPointerDecay).take();
+                               CK_ArrayToPointerDecay).get();
     RHSTy = RHSExp->getType();
 
     BaseExpr = RHSExp;
@@ -3847,8 +3945,8 @@
   assert(VK == VK_RValue || LangOpts.CPlusPlus ||
          !ResultType.isCForbiddenLValueType());
 
-  return Owned(new (Context) ArraySubscriptExpr(LHSExp, RHSExp,
-                                                ResultType, VK, OK, RLoc));
+  return new (Context)
+      ArraySubscriptExpr(LHSExp, RHSExp, ResultType, VK, OK, RLoc);
 }
 
 ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc,
@@ -3871,7 +3969,7 @@
 
     // Instantiate the expression.
     MultiLevelTemplateArgumentList MutiLevelArgList
-      = getTemplateInstantiationArgs(FD, 0, /*RelativeToPrimary=*/true);
+      = getTemplateInstantiationArgs(FD, nullptr, /*RelativeToPrimary=*/true);
 
     InstantiatingTemplate Inst(*this, CallLoc, Param,
                                MutiLevelArgList.getInnermost());
@@ -3897,17 +3995,17 @@
     InitializationKind Kind
       = InitializationKind::CreateCopy(Param->getLocation(),
              /*FIXME:EqualLoc*/UninstExpr->getLocStart());
-    Expr *ResultE = Result.takeAs<Expr>();
+    Expr *ResultE = Result.getAs<Expr>();
 
     InitializationSequence InitSeq(*this, Entity, Kind, ResultE);
     Result = InitSeq.Perform(*this, Entity, Kind, ResultE);
     if (Result.isInvalid())
       return ExprError();
 
-    Expr *Arg = Result.takeAs<Expr>();
+    Expr *Arg = Result.getAs<Expr>();
     CheckCompletedExpr(Arg, Param->getOuterLocStart());
     // Build the default argument expression.
-    return Owned(CXXDefaultArgExpr::Create(Context, CallLoc, Param, Arg));
+    return CXXDefaultArgExpr::Create(Context, CallLoc, Param, Arg);
   }
 
   // If the default expression creates temporaries, we need to
@@ -3934,7 +4032,7 @@
   // as being "referenced".
   MarkDeclarationsReferencedInExpr(Param->getDefaultArg(),
                                    /*SkipLocalVariables=*/true);
-  return Owned(CXXDefaultArgExpr::Create(Context, CallLoc, Param));
+  return CXXDefaultArgExpr::Create(Context, CallLoc, Param);
 }
 
 
@@ -3961,11 +4059,11 @@
 class FunctionCallCCC : public FunctionCallFilterCCC {
 public:
   FunctionCallCCC(Sema &SemaRef, const IdentifierInfo *FuncName,
-                  unsigned NumArgs, bool HasExplicitTemplateArgs)
-      : FunctionCallFilterCCC(SemaRef, NumArgs, HasExplicitTemplateArgs),
+                  unsigned NumArgs, MemberExpr *ME)
+      : FunctionCallFilterCCC(SemaRef, NumArgs, false, ME),
         FunctionName(FuncName) {}
 
-  virtual bool ValidateCandidate(const TypoCorrection &candidate) {
+  bool ValidateCandidate(const TypoCorrection &candidate) override {
     if (!candidate.getCorrectionSpecifier() ||
         candidate.getCorrectionAsIdentifierInfo() != FunctionName) {
       return false;
@@ -3979,17 +4077,21 @@
 };
 }
 
-static TypoCorrection TryTypoCorrectionForCall(Sema &S,
-                                               DeclarationNameInfo FuncName,
+static TypoCorrection TryTypoCorrectionForCall(Sema &S, Expr *Fn,
+                                               FunctionDecl *FDecl,
                                                ArrayRef<Expr *> Args) {
-  FunctionCallCCC CCC(S, FuncName.getName().getAsIdentifierInfo(),
-                      Args.size(), false);
-  if (TypoCorrection Corrected =
-          S.CorrectTypo(FuncName, Sema::LookupOrdinaryName,
-                        S.getScopeForContext(S.CurContext), NULL, CCC)) {
+  MemberExpr *ME = dyn_cast<MemberExpr>(Fn);
+  DeclarationName FuncName = FDecl->getDeclName();
+  SourceLocation NameLoc = ME ? ME->getMemberLoc() : Fn->getLocStart();
+  FunctionCallCCC CCC(S, FuncName.getAsIdentifierInfo(), Args.size(), ME);
+
+  if (TypoCorrection Corrected = S.CorrectTypo(
+          DeclarationNameInfo(FuncName, NameLoc), Sema::LookupOrdinaryName,
+          S.getScopeForContext(S.CurContext), nullptr, CCC,
+          Sema::CTK_ErrorRecovery)) {
     if (NamedDecl *ND = Corrected.getCorrectionDecl()) {
       if (Corrected.isOverloaded()) {
-        OverloadCandidateSet OCS(FuncName.getLoc());
+        OverloadCandidateSet OCS(NameLoc, OverloadCandidateSet::CSK_Normal);
         OverloadCandidateSet::iterator Best;
         for (TypoCorrection::decl_iterator CD = Corrected.begin(),
                                            CDEnd = Corrected.end();
@@ -3998,7 +4100,7 @@
             S.AddOverloadCandidate(FD, DeclAccessPair::make(FD, AS_none), Args,
                                    OCS);
         }
-        switch (OCS.BestViableFunction(S, FuncName.getLoc(), Best)) {
+        switch (OCS.BestViableFunction(S, NameLoc, Best)) {
         case OR_Success:
           ND = Best->Function;
           Corrected.setCorrectionDecl(ND);
@@ -4037,9 +4139,9 @@
 
   // C99 6.5.2.2p7 - the arguments are implicitly converted, as if by
   // assignment, to the types of the corresponding parameter, ...
-  unsigned NumArgsInProto = Proto->getNumArgs();
+  unsigned NumParams = Proto->getNumParams();
   bool Invalid = false;
-  unsigned MinArgs = FDecl ? FDecl->getMinRequiredArguments() : NumArgsInProto;
+  unsigned MinArgs = FDecl ? FDecl->getMinRequiredArguments() : NumParams;
   unsigned FnKind = Fn->getType()->isBlockPointerType()
                        ? 1 /* block */
                        : (IsExecConfig ? 3 /* kernel function (exec config) */
@@ -4047,35 +4149,29 @@
 
   // If too few arguments are available (and we don't have default
   // arguments for the remaining parameters), don't make the call.
-  if (Args.size() < NumArgsInProto) {
+  if (Args.size() < NumParams) {
     if (Args.size() < MinArgs) {
-      MemberExpr *ME = dyn_cast<MemberExpr>(Fn);
       TypoCorrection TC;
-      if (FDecl && (TC = TryTypoCorrectionForCall(
-                        *this, DeclarationNameInfo(FDecl->getDeclName(),
-                                                   (ME ? ME->getMemberLoc()
-                                                       : Fn->getLocStart())),
-                        Args))) {
+      if (FDecl && (TC = TryTypoCorrectionForCall(*this, Fn, FDecl, Args))) {
         unsigned diag_id =
-            MinArgs == NumArgsInProto && !Proto->isVariadic()
+            MinArgs == NumParams && !Proto->isVariadic()
                 ? diag::err_typecheck_call_too_few_args_suggest
                 : diag::err_typecheck_call_too_few_args_at_least_suggest;
         diagnoseTypo(TC, PDiag(diag_id) << FnKind << MinArgs
                                         << static_cast<unsigned>(Args.size())
-                                        << Fn->getSourceRange());
+                                        << TC.getCorrectionRange());
       } else if (MinArgs == 1 && FDecl && FDecl->getParamDecl(0)->getDeclName())
-        Diag(RParenLoc, MinArgs == NumArgsInProto && !Proto->isVariadic()
-                          ? diag::err_typecheck_call_too_few_args_one
-                          : diag::err_typecheck_call_too_few_args_at_least_one)
-          << FnKind
-          << FDecl->getParamDecl(0) << Fn->getSourceRange();
+        Diag(RParenLoc,
+             MinArgs == NumParams && !Proto->isVariadic()
+                 ? diag::err_typecheck_call_too_few_args_one
+                 : diag::err_typecheck_call_too_few_args_at_least_one)
+            << FnKind << FDecl->getParamDecl(0) << Fn->getSourceRange();
       else
-        Diag(RParenLoc, MinArgs == NumArgsInProto && !Proto->isVariadic()
-                          ? diag::err_typecheck_call_too_few_args
-                          : diag::err_typecheck_call_too_few_args_at_least)
-          << FnKind
-          << MinArgs << static_cast<unsigned>(Args.size())
-          << Fn->getSourceRange();
+        Diag(RParenLoc, MinArgs == NumParams && !Proto->isVariadic()
+                            ? diag::err_typecheck_call_too_few_args
+                            : diag::err_typecheck_call_too_few_args_at_least)
+            << FnKind << MinArgs << static_cast<unsigned>(Args.size())
+            << Fn->getSourceRange();
 
       // Emit the location of the prototype.
       if (!TC && FDecl && !FDecl->getBuiltinID() && !IsExecConfig)
@@ -4084,46 +4180,41 @@
 
       return true;
     }
-    Call->setNumArgs(Context, NumArgsInProto);
+    Call->setNumArgs(Context, NumParams);
   }
 
   // If too many are passed and not variadic, error on the extras and drop
   // them.
-  if (Args.size() > NumArgsInProto) {
+  if (Args.size() > NumParams) {
     if (!Proto->isVariadic()) {
       TypoCorrection TC;
-      if (FDecl && (TC = TryTypoCorrectionForCall(
-                        *this, DeclarationNameInfo(FDecl->getDeclName(),
-                                                   Fn->getLocStart()),
-                        Args))) {
+      if (FDecl && (TC = TryTypoCorrectionForCall(*this, Fn, FDecl, Args))) {
         unsigned diag_id =
-            MinArgs == NumArgsInProto && !Proto->isVariadic()
+            MinArgs == NumParams && !Proto->isVariadic()
                 ? diag::err_typecheck_call_too_many_args_suggest
                 : diag::err_typecheck_call_too_many_args_at_most_suggest;
-        diagnoseTypo(TC, PDiag(diag_id) << FnKind << NumArgsInProto
+        diagnoseTypo(TC, PDiag(diag_id) << FnKind << NumParams
                                         << static_cast<unsigned>(Args.size())
-                                        << Fn->getSourceRange());
-      } else if (NumArgsInProto == 1 && FDecl &&
+                                        << TC.getCorrectionRange());
+      } else if (NumParams == 1 && FDecl &&
                  FDecl->getParamDecl(0)->getDeclName())
-        Diag(Args[NumArgsInProto]->getLocStart(),
-             MinArgs == NumArgsInProto
-               ? diag::err_typecheck_call_too_many_args_one
-               : diag::err_typecheck_call_too_many_args_at_most_one)
-          << FnKind
-          << FDecl->getParamDecl(0) << static_cast<unsigned>(Args.size())
-          << Fn->getSourceRange()
-          << SourceRange(Args[NumArgsInProto]->getLocStart(),
-                         Args.back()->getLocEnd());
+        Diag(Args[NumParams]->getLocStart(),
+             MinArgs == NumParams
+                 ? diag::err_typecheck_call_too_many_args_one
+                 : diag::err_typecheck_call_too_many_args_at_most_one)
+            << FnKind << FDecl->getParamDecl(0)
+            << static_cast<unsigned>(Args.size()) << Fn->getSourceRange()
+            << SourceRange(Args[NumParams]->getLocStart(),
+                           Args.back()->getLocEnd());
       else
-        Diag(Args[NumArgsInProto]->getLocStart(),
-             MinArgs == NumArgsInProto
-               ? diag::err_typecheck_call_too_many_args
-               : diag::err_typecheck_call_too_many_args_at_most)
-          << FnKind
-          << NumArgsInProto << static_cast<unsigned>(Args.size())
-          << Fn->getSourceRange()
-          << SourceRange(Args[NumArgsInProto]->getLocStart(),
-                         Args.back()->getLocEnd());
+        Diag(Args[NumParams]->getLocStart(),
+             MinArgs == NumParams
+                 ? diag::err_typecheck_call_too_many_args
+                 : diag::err_typecheck_call_too_many_args_at_most)
+            << FnKind << NumParams << static_cast<unsigned>(Args.size())
+            << Fn->getSourceRange()
+            << SourceRange(Args[NumParams]->getLocStart(),
+                           Args.back()->getLocEnd());
 
       // Emit the location of the prototype.
       if (!TC && FDecl && !FDecl->getBuiltinID() && !IsExecConfig)
@@ -4131,7 +4222,7 @@
           << FDecl;
       
       // This deletes the extra arguments.
-      Call->setNumArgs(Context, NumArgsInProto);
+      Call->setNumArgs(Context, NumParams);
       return true;
     }
   }
@@ -4149,28 +4240,21 @@
   return false;
 }
 
-bool Sema::GatherArgumentsForCall(SourceLocation CallLoc,
-                                  FunctionDecl *FDecl,
+bool Sema::GatherArgumentsForCall(SourceLocation CallLoc, FunctionDecl *FDecl,
                                   const FunctionProtoType *Proto,
-                                  unsigned FirstProtoArg,
-                                  ArrayRef<Expr *> Args,
+                                  unsigned FirstParam, ArrayRef<Expr *> Args,
                                   SmallVectorImpl<Expr *> &AllArgs,
-                                  VariadicCallType CallType,
-                                  bool AllowExplicit,
+                                  VariadicCallType CallType, bool AllowExplicit,
                                   bool IsListInitialization) {
-  unsigned NumArgsInProto = Proto->getNumArgs();
-  unsigned NumArgsToCheck = Args.size();
+  unsigned NumParams = Proto->getNumParams();
   bool Invalid = false;
-  if (Args.size() != NumArgsInProto)
-    // Use default arguments for missing arguments
-    NumArgsToCheck = NumArgsInProto;
   unsigned ArgIx = 0;
   // Continue to check argument types (even if we have too few/many args).
-  for (unsigned i = FirstProtoArg; i != NumArgsToCheck; i++) {
-    QualType ProtoArgType = Proto->getArgType(i);
+  for (unsigned i = FirstParam; i < NumParams; i++) {
+    QualType ProtoArgType = Proto->getParamType(i);
 
     Expr *Arg;
-    ParmVarDecl *Param;
+    ParmVarDecl *Param = FDecl ? FDecl->getParamDecl(i) : nullptr;
     if (ArgIx < Args.size()) {
       Arg = Args[ArgIx++];
 
@@ -4179,11 +4263,6 @@
                               diag::err_call_incomplete_argument, Arg))
         return true;
 
-      // Pass the argument
-      Param = 0;
-      if (FDecl && i < FDecl->getNumParams())
-        Param = FDecl->getParamDecl(i);
-
       // Strip the unbridged-cast placeholder expression off, if applicable.
       bool CFAudited = false;
       if (Arg->getType() == Context.ARCUnbridgedCastTy &&
@@ -4195,34 +4274,31 @@
                (!Param || !Param->hasAttr<CFConsumedAttr>()))
         CFAudited = true;
 
-      InitializedEntity Entity = Param ?
-          InitializedEntity::InitializeParameter(Context, Param, ProtoArgType)
-        : InitializedEntity::InitializeParameter(Context, ProtoArgType,
-                                                 Proto->isArgConsumed(i));
-      
+      InitializedEntity Entity =
+          Param ? InitializedEntity::InitializeParameter(Context, Param,
+                                                         ProtoArgType)
+                : InitializedEntity::InitializeParameter(
+                      Context, ProtoArgType, Proto->isParamConsumed(i));
+
       // Remember that parameter belongs to a CF audited API.
       if (CFAudited)
         Entity.setParameterCFAudited();
-      
-      ExprResult ArgE = PerformCopyInitialization(Entity,
-                                                  SourceLocation(),
-                                                  Owned(Arg),
-                                                  IsListInitialization,
-                                                  AllowExplicit);
+
+      ExprResult ArgE = PerformCopyInitialization(
+          Entity, SourceLocation(), Arg, IsListInitialization, AllowExplicit);
       if (ArgE.isInvalid())
         return true;
 
-      Arg = ArgE.takeAs<Expr>();
+      Arg = ArgE.getAs<Expr>();
     } else {
-      assert(FDecl && "can't use default arguments without a known callee");
-      Param = FDecl->getParamDecl(i);
+      assert(Param && "can't use default arguments without a known callee");
 
       ExprResult ArgExpr =
         BuildCXXDefaultArgExpr(CallLoc, FDecl, Param);
       if (ArgExpr.isInvalid())
         return true;
 
-      Arg = ArgExpr.takeAs<Expr>();
+      Arg = ArgExpr.getAs<Expr>();
     }
 
     // Check for array bounds violations for each argument to the call. This
@@ -4240,13 +4316,13 @@
   if (CallType != VariadicDoesNotApply) {
     // Assume that extern "C" functions with variadic arguments that
     // return __unknown_anytype aren't *really* variadic.
-    if (Proto->getResultType() == Context.UnknownAnyTy &&
-        FDecl && FDecl->isExternC()) {
+    if (Proto->getReturnType() == Context.UnknownAnyTy && FDecl &&
+        FDecl->isExternC()) {
       for (unsigned i = ArgIx, e = Args.size(); i != e; ++i) {
         QualType paramType; // ignored
         ExprResult arg = checkUnknownAnyArg(CallLoc, Args[i], paramType);
         Invalid |= arg.isInvalid();
-        AllArgs.push_back(arg.take());
+        AllArgs.push_back(arg.get());
       }
 
     // Otherwise do argument promotion, (C99 6.5.2.2p7).
@@ -4255,7 +4331,7 @@
         ExprResult Arg = DefaultVariadicArgumentPromotion(Args[i], CallType,
                                                           FDecl);
         Invalid |= Arg.isInvalid();
-        AllArgs.push_back(Arg.take());
+        AllArgs.push_back(Arg.get());
       }
     }
 
@@ -4377,7 +4453,7 @@
     if (isPlaceholderToRemoveAsArg(args[i]->getType())) {
       ExprResult result = S.CheckPlaceholderExpr(args[i]);
       if (result.isInvalid()) hasInvalid = true;
-      else args[i] = result.take();
+      else args[i] = result.get();
     }
   }
   return hasInvalid;
@@ -4393,7 +4469,7 @@
   // Since this might be a postfix expression, get rid of ParenListExprs.
   ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Fn);
   if (Result.isInvalid()) return ExprError();
-  Fn = Result.take();
+  Fn = Result.get();
 
   if (checkArgsForPlaceholders(*this, ArgExprs))
     return ExprError();
@@ -4409,14 +4485,13 @@
                                                 ArgExprs.back()->getLocEnd()));
       }
 
-      return Owned(new (Context) CallExpr(Context, Fn, None,
-                                          Context.VoidTy, VK_RValue,
-                                          RParenLoc));
+      return new (Context)
+          CallExpr(Context, Fn, None, Context.VoidTy, VK_RValue, RParenLoc);
     }
     if (Fn->getType() == Context.PseudoObjectTy) {
       ExprResult result = CheckPlaceholderExpr(Fn);
       if (result.isInvalid()) return ExprError();
-      Fn = result.take();
+      Fn = result.get();
     }
 
     // Determine whether this is a dependent call inside a C++ template,
@@ -4431,25 +4506,24 @@
 
     if (Dependent) {
       if (ExecConfig) {
-        return Owned(new (Context) CUDAKernelCallExpr(
+        return new (Context) CUDAKernelCallExpr(
             Context, Fn, cast<CallExpr>(ExecConfig), ArgExprs,
-            Context.DependentTy, VK_RValue, RParenLoc));
+            Context.DependentTy, VK_RValue, RParenLoc);
       } else {
-        return Owned(new (Context) CallExpr(Context, Fn, ArgExprs,
-                                            Context.DependentTy, VK_RValue,
-                                            RParenLoc));
+        return new (Context) CallExpr(
+            Context, Fn, ArgExprs, Context.DependentTy, VK_RValue, RParenLoc);
       }
     }
 
     // Determine whether this is a call to an object (C++ [over.call.object]).
     if (Fn->getType()->isRecordType())
-      return Owned(BuildCallToObjectOfClassType(S, Fn, LParenLoc,
-                                                ArgExprs, RParenLoc));
+      return BuildCallToObjectOfClassType(S, Fn, LParenLoc, ArgExprs,
+                                          RParenLoc);
 
     if (Fn->getType() == Context.UnknownAnyTy) {
       ExprResult result = rebuildUnknownAnyFunction(*this, Fn);
       if (result.isInvalid()) return ExprError();
-      Fn = result.take();
+      Fn = result.get();
     }
 
     if (Fn->getType() == Context.BoundMemberTy) {
@@ -4479,12 +4553,12 @@
   if (Fn->getType() == Context.UnknownAnyTy) {
     ExprResult result = rebuildUnknownAnyFunction(*this, Fn);
     if (result.isInvalid()) return ExprError();
-    Fn = result.take();
+    Fn = result.get();
   }
 
   Expr *NakedFn = Fn->IgnoreParens();
 
-  NamedDecl *NDecl = 0;
+  NamedDecl *NDecl = nullptr;
   if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(NakedFn))
     if (UnOp->getOpcode() == UO_AddrOf)
       NakedFn = UnOp->getSubExpr()->IgnoreParens();
@@ -4494,6 +4568,21 @@
   else if (isa<MemberExpr>(NakedFn))
     NDecl = cast<MemberExpr>(NakedFn)->getMemberDecl();
 
+  if (FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(NDecl)) {
+    if (FD->hasAttr<EnableIfAttr>()) {
+      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();
+      }
+    }
+  }
+
   return BuildResolvedCallExpr(Fn, NDecl, LParenLoc, ArgExprs, RParenLoc,
                                ExecConfig, IsExecConfig);
 }
@@ -4511,7 +4600,7 @@
       ConfigDecl, false, ConfigQTy, VK_LValue, LLLLoc);
   MarkFunctionReferenced(LLLLoc, ConfigDecl);
 
-  return ActOnCallExpr(S, ConfigDR, LLLLoc, ExecConfig, GGGLoc, 0,
+  return ActOnCallExpr(S, ConfigDR, LLLLoc, ExecConfig, GGGLoc, nullptr,
                        /*IsExecConfig=*/true);
 }
 
@@ -4532,8 +4621,7 @@
                      << DstTy
                      << SrcTy
                      << E->getSourceRange());
-  return Owned(new (Context) AsTypeExpr(E, DstTy, VK, OK, BuiltinLoc,
-               RParenLoc));
+  return new (Context) AsTypeExpr(E, DstTy, VK, OK, BuiltinLoc, RParenLoc);
 }
 
 /// ActOnConvertVectorExpr - create a new convert-vector expression from the
@@ -4571,13 +4659,13 @@
   if (BuiltinID &&
       Fn->getType()->isSpecificBuiltinType(BuiltinType::BuiltinFn)) {
     Result = ImpCastExprToType(Fn, Context.getPointerType(FDecl->getType()),
-                               CK_BuiltinFnToFnPtr).take();
+                               CK_BuiltinFnToFnPtr).get();
   } else {
-    Result = UsualUnaryConversions(Fn);
+    Result = CallExprUnaryConversions(Fn);
   }
   if (Result.isInvalid())
     return ExprError();
-  Fn = Result.take();
+  Fn = Result.get();
 
   // Make the call expr early, before semantic checks.  This guarantees cleanup
   // of arguments and function on error.
@@ -4601,7 +4689,7 @@
     // C99 6.5.2.2p1 - "The expression that denotes the called function shall
     // have type pointer to function".
     FuncT = PT->getPointeeType()->getAs<FunctionType>();
-    if (FuncT == 0)
+    if (!FuncT)
       return ExprError(Diag(LParenLoc, diag::err_typecheck_call_not_function)
                          << Fn->getType() << Fn->getSourceRange());
   } else if (const BlockPointerType *BPT =
@@ -4612,7 +4700,7 @@
     if (Fn->getType() == Context.UnknownAnyTy) {
       ExprResult rewrite = rebuildUnknownAnyFunction(*this, Fn);
       if (rewrite.isInvalid()) return ExprError();
-      Fn = rewrite.take();
+      Fn = rewrite.get();
       TheCall->setCallee(Fn);
       goto retry;
     }
@@ -4629,7 +4717,7 @@
             << FDecl->getName() << Fn->getSourceRange());
 
       // CUDA: Kernel function must have 'void' return type
-      if (!FuncT->getResultType()->isVoidType())
+      if (!FuncT->getReturnType()->isVoidType())
         return ExprError(Diag(LParenLoc, diag::err_kern_type_not_void_return)
             << Fn->getType() << Fn->getSourceRange());
     } else {
@@ -4641,14 +4729,13 @@
   }
 
   // Check for a valid return type
-  if (CheckCallReturnType(FuncT->getResultType(),
-                          Fn->getLocStart(), TheCall,
+  if (CheckCallReturnType(FuncT->getReturnType(), Fn->getLocStart(), TheCall,
                           FDecl))
     return ExprError();
 
   // We know the result type of the call, set it.
   TheCall->setType(FuncT->getCallResultType(Context));
-  TheCall->setValueKind(Expr::getValueKindForType(FuncT->getResultType()));
+  TheCall->setValueKind(Expr::getValueKindForType(FuncT->getReturnType()));
 
   const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FuncT);
   if (Proto) {
@@ -4661,7 +4748,7 @@
     if (FDecl) {
       // Check if we have too few/too many template arguments, based
       // on our knowledge of the function definition.
-      const FunctionDecl *Def = 0;
+      const FunctionDecl *Def = nullptr;
       if (FDecl->hasBody(Def) && Args.size() != Def->param_size()) {
         Proto = Def->getType()->getAs<FunctionProtoType>();
        if (!Proto || !(Proto->isVariadic() && Args.size() >= Def->param_size()))
@@ -4679,18 +4766,15 @@
     for (unsigned i = 0, e = Args.size(); i != e; i++) {
       Expr *Arg = Args[i];
 
-      if (Proto && i < Proto->getNumArgs()) {
-        InitializedEntity Entity
-          = InitializedEntity::InitializeParameter(Context, 
-                                                   Proto->getArgType(i),
-                                                   Proto->isArgConsumed(i));
-        ExprResult ArgE = PerformCopyInitialization(Entity,
-                                                    SourceLocation(),
-                                                    Owned(Arg));
+      if (Proto && i < Proto->getNumParams()) {
+        InitializedEntity Entity = InitializedEntity::InitializeParameter(
+            Context, Proto->getParamType(i), Proto->isParamConsumed(i));
+        ExprResult ArgE =
+            PerformCopyInitialization(Entity, SourceLocation(), Arg);
         if (ArgE.isInvalid())
           return true;
         
-        Arg = ArgE.takeAs<Expr>();
+        Arg = ArgE.getAs<Expr>();
 
       } else {
         ExprResult ArgE = DefaultArgumentPromotion(Arg);
@@ -4698,7 +4782,7 @@
         if (ArgE.isInvalid())
           return true;
 
-        Arg = ArgE.takeAs<Expr>();
+        Arg = ArgE.getAs<Expr>();
       }
       
       if (RequireCompleteType(Arg->getLocStart(),
@@ -4785,7 +4869,7 @@
     return ExprError();
   LiteralExpr = Result.get();
 
-  bool isFileScope = getCurFunctionOrMethodDecl() == 0;
+  bool isFileScope = getCurFunctionOrMethodDecl() == nullptr;
   if (isFileScope &&
       !LiteralExpr->isTypeDependent() &&
       !LiteralExpr->isValueDependent() &&
@@ -4815,7 +4899,7 @@
       // of one failure would be terrible for indexing/etc.
       if (result.isInvalid()) continue;
 
-      InitArgList[I] = result.take();
+      InitArgList[I] = result.get();
     }
   }
 
@@ -4825,7 +4909,7 @@
   InitListExpr *E = new (Context) InitListExpr(Context, LBraceLoc, InitArgList,
                                                RBraceLoc);
   E->setType(Context.VoidTy); // FIXME: just a place holder for now.
-  return Owned(E);
+  return E;
 }
 
 /// Do an explicit extend of the given block pointer if we're in ARC.
@@ -4838,7 +4922,7 @@
 
   E = ImplicitCastExpr::Create(S.Context, E.get()->getType(),
                                CK_ARCExtendBlockObject, E.get(),
-                               /*base path*/ 0, VK_RValue);
+                               /*base path*/ nullptr, VK_RValue);
   S.ExprNeedsCleanups = true;
 }
 
@@ -4876,8 +4960,13 @@
   case Type::STK_BlockPointer:
   case Type::STK_ObjCObjectPointer:
     switch (DestTy->getScalarTypeKind()) {
-    case Type::STK_CPointer:
+    case Type::STK_CPointer: {
+      unsigned SrcAS = SrcTy->getPointeeType().getAddressSpace();
+      unsigned DestAS = DestTy->getPointeeType().getAddressSpace();
+      if (SrcAS != DestAS)
+        return CK_AddressSpaceConversion;
       return CK_BitCast;
+    }
     case Type::STK_BlockPointer:
       return (SrcKind == Type::STK_BlockPointer
                 ? CK_BitCast : CK_AnyPointerToBlockPointerCast);
@@ -4917,12 +5006,12 @@
     case Type::STK_Floating:
       return CK_IntegralToFloating;
     case Type::STK_IntegralComplex:
-      Src = ImpCastExprToType(Src.take(),
+      Src = ImpCastExprToType(Src.get(),
                               DestTy->castAs<ComplexType>()->getElementType(),
                               CK_IntegralCast);
       return CK_IntegralRealToComplex;
     case Type::STK_FloatingComplex:
-      Src = ImpCastExprToType(Src.take(),
+      Src = ImpCastExprToType(Src.get(),
                               DestTy->castAs<ComplexType>()->getElementType(),
                               CK_IntegralToFloating);
       return CK_FloatingRealToComplex;
@@ -4940,12 +5029,12 @@
     case Type::STK_Integral:
       return CK_FloatingToIntegral;
     case Type::STK_FloatingComplex:
-      Src = ImpCastExprToType(Src.take(),
+      Src = ImpCastExprToType(Src.get(),
                               DestTy->castAs<ComplexType>()->getElementType(),
                               CK_FloatingCast);
       return CK_FloatingRealToComplex;
     case Type::STK_IntegralComplex:
-      Src = ImpCastExprToType(Src.take(),
+      Src = ImpCastExprToType(Src.get(),
                               DestTy->castAs<ComplexType>()->getElementType(),
                               CK_FloatingToIntegral);
       return CK_IntegralRealToComplex;
@@ -4968,13 +5057,13 @@
       QualType ET = SrcTy->castAs<ComplexType>()->getElementType();
       if (Context.hasSameType(ET, DestTy))
         return CK_FloatingComplexToReal;
-      Src = ImpCastExprToType(Src.take(), ET, CK_FloatingComplexToReal);
+      Src = ImpCastExprToType(Src.get(), ET, CK_FloatingComplexToReal);
       return CK_FloatingCast;
     }
     case Type::STK_Bool:
       return CK_FloatingComplexToBoolean;
     case Type::STK_Integral:
-      Src = ImpCastExprToType(Src.take(),
+      Src = ImpCastExprToType(Src.get(),
                               SrcTy->castAs<ComplexType>()->getElementType(),
                               CK_FloatingComplexToReal);
       return CK_FloatingToIntegral;
@@ -4997,13 +5086,13 @@
       QualType ET = SrcTy->castAs<ComplexType>()->getElementType();
       if (Context.hasSameType(ET, DestTy))
         return CK_IntegralComplexToReal;
-      Src = ImpCastExprToType(Src.take(), ET, CK_IntegralComplexToReal);
+      Src = ImpCastExprToType(Src.get(), ET, CK_IntegralComplexToReal);
       return CK_IntegralCast;
     }
     case Type::STK_Bool:
       return CK_IntegralComplexToBoolean;
     case Type::STK_Floating:
-      Src = ImpCastExprToType(Src.take(),
+      Src = ImpCastExprToType(Src.get(),
                               SrcTy->castAs<ComplexType>()->getElementType(),
                               CK_IntegralComplexToReal);
       return CK_IntegralToFloating;
@@ -5020,12 +5109,55 @@
   llvm_unreachable("Unhandled scalar cast");
 }
 
+static bool breakDownVectorType(QualType type, uint64_t &len,
+                                QualType &eltType) {
+  // Vectors are simple.
+  if (const VectorType *vecType = type->getAs<VectorType>()) {
+    len = vecType->getNumElements();
+    eltType = vecType->getElementType();
+    assert(eltType->isScalarType());
+    return true;
+  }
+  
+  // We allow lax conversion to and from non-vector types, but only if
+  // they're real types (i.e. non-complex, non-pointer scalar types).
+  if (!type->isRealType()) return false;
+  
+  len = 1;
+  eltType = type;
+  return true;
+}
+
+static bool VectorTypesMatch(Sema &S, QualType srcTy, QualType destTy) {
+  uint64_t srcLen, destLen;
+  QualType srcElt, destElt;
+  if (!breakDownVectorType(srcTy, srcLen, srcElt)) return false;
+  if (!breakDownVectorType(destTy, destLen, destElt)) return false;
+  
+  // ASTContext::getTypeSize will return the size rounded up to a
+  // power of 2, so instead of using that, we need to use the raw
+  // element size multiplied by the element count.
+  uint64_t srcEltSize = S.Context.getTypeSize(srcElt);
+  uint64_t destEltSize = S.Context.getTypeSize(destElt);
+  
+  return (srcLen * srcEltSize == destLen * destEltSize);
+}
+
+/// Is this a legal conversion between two known vector types?
+bool Sema::isLaxVectorConversion(QualType srcTy, QualType destTy) {
+  assert(destTy->isVectorType() || srcTy->isVectorType());
+  
+  if (!Context.getLangOpts().LaxVectorConversions)
+    return false;
+  return VectorTypesMatch(*this, srcTy, destTy);
+}
+
 bool Sema::CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty,
                            CastKind &Kind) {
   assert(VectorTy->isVectorType() && "Not a vector type!");
 
   if (Ty->isVectorType() || Ty->isIntegerType()) {
-    if (Context.getTypeSize(VectorTy) != Context.getTypeSize(Ty))
+    if (!VectorTypesMatch(*this, Ty, VectorTy))
       return Diag(R.getBegin(),
                   Ty->isVectorType() ?
                   diag::err_invalid_conversion_between_vectors :
@@ -5051,7 +5183,7 @@
   // In OpenCL, casts between vectors of different types are not allowed.
   // (See OpenCL 6.2).
   if (SrcTy->isVectorType()) {
-    if (Context.getTypeSize(DestTy) != Context.getTypeSize(SrcTy)
+    if (!VectorTypesMatch(*this, SrcTy, DestTy)
         || (getLangOpts().OpenCL &&
             (DestTy.getCanonicalType() != SrcTy.getCanonicalType()))) {
       Diag(R.getBegin(),diag::err_invalid_conversion_between_ext_vectors)
@@ -5059,7 +5191,7 @@
       return ExprError();
     }
     Kind = CK_BitCast;
-    return Owned(CastExpr);
+    return CastExpr;
   }
 
   // All non-pointer scalars can be cast to ExtVector type.  The appropriate
@@ -5071,21 +5203,21 @@
       << DestTy << SrcTy << R;
 
   QualType DestElemTy = DestTy->getAs<ExtVectorType>()->getElementType();
-  ExprResult CastExprRes = Owned(CastExpr);
+  ExprResult CastExprRes = CastExpr;
   CastKind CK = PrepareScalarCast(CastExprRes, DestElemTy);
   if (CastExprRes.isInvalid())
     return ExprError();
-  CastExpr = ImpCastExprToType(CastExprRes.take(), DestElemTy, CK).take();
+  CastExpr = ImpCastExprToType(CastExprRes.get(), DestElemTy, CK).get();
 
   Kind = CK_VectorSplat;
-  return Owned(CastExpr);
+  return CastExpr;
 }
 
 ExprResult
 Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc,
                     Declarator &D, ParsedType &Ty,
                     SourceLocation RParenLoc, Expr *CastExpr) {
-  assert(!D.isInvalidType() && (CastExpr != 0) &&
+  assert(!D.isInvalidType() && (CastExpr != nullptr) &&
          "ActOnCastExpr(): missing type or expr");
 
   TypeSourceInfo *castTInfo = GetTypeForDeclaratorCast(D, CastExpr->getType());
@@ -5134,9 +5266,17 @@
   if (isa<ParenListExpr>(CastExpr)) {
     ExprResult Result = MaybeConvertParenListExprToParenExpr(S, CastExpr);
     if (Result.isInvalid()) return ExprError();
-    CastExpr = Result.take();
+    CastExpr = Result.get();
   }
 
+  if (getLangOpts().CPlusPlus && !castType->isVoidType() &&
+      !getSourceManager().isInSystemMacro(LParenLoc))
+    Diag(LParenLoc, diag::warn_old_style_cast) << CastExpr->getSourceRange();
+  
+  CheckTollFreeBridgeCast(castType, CastExpr);
+  
+  CheckObjCBridgeRelatedCast(castType, CastExpr);
+  
   return BuildCStyleCastExpr(LParenLoc, castTInfo, RParenLoc, CastExpr);
 }
 
@@ -5183,9 +5323,9 @@
       ExprResult Literal = DefaultLvalueConversion(exprs[0]);
       if (Literal.isInvalid())
         return ExprError();
-      Literal = ImpCastExprToType(Literal.take(), ElemTy,
+      Literal = ImpCastExprToType(Literal.get(), ElemTy,
                                   PrepareScalarCast(Literal, ElemTy));
-      return BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, Literal.take());
+      return BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, Literal.get());
     }
     else if (numExprs < numElems) {
       Diag(E->getExprLoc(),
@@ -5205,9 +5345,9 @@
         ExprResult Literal = DefaultLvalueConversion(exprs[0]);
         if (Literal.isInvalid())
           return ExprError();
-        Literal = ImpCastExprToType(Literal.take(), ElemTy,
+        Literal = ImpCastExprToType(Literal.get(), ElemTy,
                                     PrepareScalarCast(Literal, ElemTy));
-        return BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, Literal.take());
+        return BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, Literal.get());
     }
     
     initExprs.append(exprs, exprs + numExprs);
@@ -5226,7 +5366,7 @@
 Sema::MaybeConvertParenListExprToParenExpr(Scope *S, Expr *OrigExpr) {
   ParenListExpr *E = dyn_cast<ParenListExpr>(OrigExpr);
   if (!E)
-    return Owned(OrigExpr);
+    return OrigExpr;
 
   ExprResult Result(E->getExpr(0));
 
@@ -5243,7 +5383,7 @@
                                     SourceLocation R,
                                     MultiExprArg Val) {
   Expr *expr = new (Context) ParenListExpr(Context, L, Val, R);
-  return Owned(expr);
+  return expr;
 }
 
 /// \brief Emit a specialized diagnostic when one expression is a null pointer
@@ -5324,8 +5464,8 @@
   }
 
   // Implicity convert these scalars to the type of the condition.
-  LHS = S.ImpCastExprToType(LHS.take(), CondTy, CK_IntegralCast);
-  RHS = S.ImpCastExprToType(RHS.take(), CondTy, CK_IntegralCast);
+  LHS = S.ImpCastExprToType(LHS.get(), CondTy, CK_IntegralCast);
+  RHS = S.ImpCastExprToType(RHS.get(), CondTy, CK_IntegralCast);
   return false;
 }
 
@@ -5341,8 +5481,8 @@
     if (!RHSExpr->getType()->isVoidType())
       S.Diag(LHSExpr->getLocStart(), diag::ext_typecheck_cond_one_void)
         << LHSExpr->getSourceRange();
-    LHS = S.ImpCastExprToType(LHS.take(), S.Context.VoidTy, CK_ToVoid);
-    RHS = S.ImpCastExprToType(RHS.take(), S.Context.VoidTy, CK_ToVoid);
+    LHS = S.ImpCastExprToType(LHS.get(), S.Context.VoidTy, CK_ToVoid);
+    RHS = S.ImpCastExprToType(RHS.get(), S.Context.VoidTy, CK_ToVoid);
     return S.Context.VoidTy;
 }
 
@@ -5355,7 +5495,7 @@
                                             Expr::NPC_ValueDependentIsNull))
     return true;
 
-  NullExpr = S.ImpCastExprToType(NullExpr.take(), PointerTy, CK_NullToPointer);
+  NullExpr = S.ImpCastExprToType(NullExpr.get(), PointerTy, CK_NullToPointer);
   return false;
 }
 
@@ -5407,15 +5547,15 @@
   QualType CompositeTy = S.Context.mergeTypes(lhptee, rhptee);
 
   if (CompositeTy.isNull()) {
-    S.Diag(Loc, diag::warn_typecheck_cond_incompatible_pointers)
+    S.Diag(Loc, diag::ext_typecheck_cond_incompatible_pointers)
       << LHSTy << RHSTy << LHS.get()->getSourceRange()
       << RHS.get()->getSourceRange();
     // 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 = S.Context.getPointerType(S.Context.VoidTy);
-    LHS = S.ImpCastExprToType(LHS.take(), incompatTy, CK_BitCast);
-    RHS = S.ImpCastExprToType(RHS.take(), incompatTy, CK_BitCast);
+    LHS = S.ImpCastExprToType(LHS.get(), incompatTy, CK_BitCast);
+    RHS = S.ImpCastExprToType(RHS.get(), incompatTy, CK_BitCast);
     return incompatTy;
   }
 
@@ -5426,11 +5566,41 @@
   else
     ResultTy = S.Context.getPointerType(ResultTy);
 
-  LHS = S.ImpCastExprToType(LHS.take(), ResultTy, CK_BitCast);
-  RHS = S.ImpCastExprToType(RHS.take(), ResultTy, CK_BitCast);
+  LHS = S.ImpCastExprToType(LHS.get(), ResultTy, CK_BitCast);
+  RHS = S.ImpCastExprToType(RHS.get(), ResultTy, CK_BitCast);
   return ResultTy;
 }
 
+/// \brief Returns true if QT is quelified-id and implements 'NSObject' and/or
+/// 'NSCopying' protocols (and nothing else); or QT is an NSObject and optionally
+/// implements 'NSObject' and/or NSCopying' protocols (and nothing else).
+static bool isObjCPtrBlockCompatible(Sema &S, ASTContext &C, QualType QT) {
+  if (QT->isObjCIdType())
+    return true;
+  
+  const ObjCObjectPointerType *OPT = QT->getAs<ObjCObjectPointerType>();
+  if (!OPT)
+    return false;
+
+  if (ObjCInterfaceDecl *ID = OPT->getInterfaceDecl())
+    if (ID->getIdentifier() != &C.Idents.get("NSObject"))
+      return false;
+  
+  ObjCProtocolDecl* PNSCopying =
+    S.LookupProtocol(&C.Idents.get("NSCopying"), SourceLocation());
+  ObjCProtocolDecl* PNSObject =
+    S.LookupProtocol(&C.Idents.get("NSObject"), SourceLocation());
+
+  for (auto *Proto : OPT->quals()) {
+    if ((PNSCopying && declaresSameEntity(Proto, PNSCopying)) ||
+        (PNSObject && declaresSameEntity(Proto, PNSObject)))
+      ;
+    else
+      return false;
+  }
+  return true;
+}
+
 /// \brief Return the resulting type when the operands are both block pointers.
 static QualType checkConditionalBlockPointerCompatibility(Sema &S,
                                                           ExprResult &LHS,
@@ -5442,8 +5612,8 @@
   if (!LHSTy->isBlockPointerType() || !RHSTy->isBlockPointerType()) {
     if (LHSTy->isVoidPointerType() || RHSTy->isVoidPointerType()) {
       QualType destType = S.Context.getPointerType(S.Context.VoidTy);
-      LHS = S.ImpCastExprToType(LHS.take(), destType, CK_BitCast);
-      RHS = S.ImpCastExprToType(RHS.take(), destType, CK_BitCast);
+      LHS = S.ImpCastExprToType(LHS.get(), destType, CK_BitCast);
+      RHS = S.ImpCastExprToType(RHS.get(), destType, CK_BitCast);
       return destType;
     }
     S.Diag(Loc, diag::err_typecheck_cond_incompatible_operands)
@@ -5476,9 +5646,9 @@
       = S.Context.getQualifiedType(lhptee, rhptee.getQualifiers());
     QualType destType = S.Context.getPointerType(destPointee);
     // Add qualifiers if necessary.
-    LHS = S.ImpCastExprToType(LHS.take(), destType, CK_NoOp);
+    LHS = S.ImpCastExprToType(LHS.get(), destType, CK_NoOp);
     // Promote to void*.
-    RHS = S.ImpCastExprToType(RHS.take(), destType, CK_BitCast);
+    RHS = S.ImpCastExprToType(RHS.get(), destType, CK_BitCast);
     return destType;
   }
   if (rhptee->isVoidType() && lhptee->isIncompleteOrObjectType()) {
@@ -5486,9 +5656,9 @@
       = S.Context.getQualifiedType(rhptee, lhptee.getQualifiers());
     QualType destType = S.Context.getPointerType(destPointee);
     // Add qualifiers if necessary.
-    RHS = S.ImpCastExprToType(RHS.take(), destType, CK_NoOp);
+    RHS = S.ImpCastExprToType(RHS.get(), destType, CK_NoOp);
     // Promote to void*.
-    LHS = S.ImpCastExprToType(LHS.take(), destType, CK_BitCast);
+    LHS = S.ImpCastExprToType(LHS.get(), destType, CK_BitCast);
     return destType;
   }
 
@@ -5507,10 +5677,10 @@
   Expr *Expr1 = IsIntFirstExpr ? Int.get() : PointerExpr;
   Expr *Expr2 = IsIntFirstExpr ? PointerExpr : Int.get();
 
-  S.Diag(Loc, diag::warn_typecheck_cond_pointer_integer_mismatch)
+  S.Diag(Loc, diag::ext_typecheck_cond_pointer_integer_mismatch)
     << Expr1->getType() << Expr2->getType()
     << Expr1->getSourceRange() << Expr2->getSourceRange();
-  Int = S.ImpCastExprToType(Int.take(), PointerExpr->getType(),
+  Int = S.ImpCastExprToType(Int.get(), PointerExpr->getType(),
                             CK_IntegralToPointer);
   return true;
 }
@@ -5539,7 +5709,7 @@
   OK = OK_Ordinary;
 
   // First, check the condition.
-  Cond = UsualUnaryConversions(Cond.take());
+  Cond = UsualUnaryConversions(Cond.get());
   if (Cond.isInvalid())
     return QualType();
   if (checkCondition(*this, Cond.get()))
@@ -5645,34 +5815,34 @@
   // redefinition type if an attempt is made to access its fields.
   if (LHSTy->isObjCClassType() &&
       (Context.hasSameType(RHSTy, Context.getObjCClassRedefinitionType()))) {
-    RHS = ImpCastExprToType(RHS.take(), LHSTy, CK_CPointerToObjCPointerCast);
+    RHS = ImpCastExprToType(RHS.get(), LHSTy, CK_CPointerToObjCPointerCast);
     return LHSTy;
   }
   if (RHSTy->isObjCClassType() &&
       (Context.hasSameType(LHSTy, Context.getObjCClassRedefinitionType()))) {
-    LHS = ImpCastExprToType(LHS.take(), RHSTy, CK_CPointerToObjCPointerCast);
+    LHS = ImpCastExprToType(LHS.get(), RHSTy, CK_CPointerToObjCPointerCast);
     return RHSTy;
   }
   // And the same for struct objc_object* / id
   if (LHSTy->isObjCIdType() &&
       (Context.hasSameType(RHSTy, Context.getObjCIdRedefinitionType()))) {
-    RHS = ImpCastExprToType(RHS.take(), LHSTy, CK_CPointerToObjCPointerCast);
+    RHS = ImpCastExprToType(RHS.get(), LHSTy, CK_CPointerToObjCPointerCast);
     return LHSTy;
   }
   if (RHSTy->isObjCIdType() &&
       (Context.hasSameType(LHSTy, Context.getObjCIdRedefinitionType()))) {
-    LHS = ImpCastExprToType(LHS.take(), RHSTy, CK_CPointerToObjCPointerCast);
+    LHS = ImpCastExprToType(LHS.get(), RHSTy, CK_CPointerToObjCPointerCast);
     return RHSTy;
   }
   // And the same for struct objc_selector* / SEL
   if (Context.isObjCSelType(LHSTy) &&
       (Context.hasSameType(RHSTy, Context.getObjCSelRedefinitionType()))) {
-    RHS = ImpCastExprToType(RHS.take(), LHSTy, CK_BitCast);
+    RHS = ImpCastExprToType(RHS.get(), LHSTy, CK_BitCast);
     return LHSTy;
   }
   if (Context.isObjCSelType(RHSTy) &&
       (Context.hasSameType(LHSTy, Context.getObjCSelRedefinitionType()))) {
-    LHS = ImpCastExprToType(LHS.take(), RHSTy, CK_BitCast);
+    LHS = ImpCastExprToType(LHS.get(), RHSTy, CK_BitCast);
     return RHSTy;
   }
   // Check constraints for Objective-C object pointers types.
@@ -5721,13 +5891,13 @@
       << LHSTy << RHSTy
       << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
       QualType incompatTy = Context.getObjCIdType();
-      LHS = ImpCastExprToType(LHS.take(), incompatTy, CK_BitCast);
-      RHS = ImpCastExprToType(RHS.take(), incompatTy, CK_BitCast);
+      LHS = ImpCastExprToType(LHS.get(), incompatTy, CK_BitCast);
+      RHS = ImpCastExprToType(RHS.get(), incompatTy, CK_BitCast);
       return incompatTy;
     }
     // The object pointer types are compatible.
-    LHS = ImpCastExprToType(LHS.take(), compositeType, CK_BitCast);
-    RHS = ImpCastExprToType(RHS.take(), compositeType, CK_BitCast);
+    LHS = ImpCastExprToType(LHS.get(), compositeType, CK_BitCast);
+    RHS = ImpCastExprToType(RHS.get(), compositeType, CK_BitCast);
     return compositeType;
   }
   // Check Objective-C object pointer types and 'void *'
@@ -5746,9 +5916,9 @@
     = Context.getQualifiedType(lhptee, rhptee.getQualifiers());
     QualType destType = Context.getPointerType(destPointee);
     // Add qualifiers if necessary.
-    LHS = ImpCastExprToType(LHS.take(), destType, CK_NoOp);
+    LHS = ImpCastExprToType(LHS.get(), destType, CK_NoOp);
     // Promote to void*.
-    RHS = ImpCastExprToType(RHS.take(), destType, CK_BitCast);
+    RHS = ImpCastExprToType(RHS.get(), destType, CK_BitCast);
     return destType;
   }
   if (LHSTy->isObjCObjectPointerType() && RHSTy->isVoidPointerType()) {
@@ -5766,9 +5936,9 @@
     = Context.getQualifiedType(rhptee, lhptee.getQualifiers());
     QualType destType = Context.getPointerType(destPointee);
     // Add qualifiers if necessary.
-    RHS = ImpCastExprToType(RHS.take(), destType, CK_NoOp);
+    RHS = ImpCastExprToType(RHS.get(), destType, CK_NoOp);
     // Promote to void*.
-    LHS = ImpCastExprToType(LHS.take(), destType, CK_BitCast);
+    LHS = ImpCastExprToType(LHS.get(), destType, CK_BitCast);
     return destType;
   }
   return QualType();
@@ -5900,9 +6070,9 @@
                                     Expr *RHSExpr) {
   // If this is the gnu "x ?: y" extension, analyze the types as though the LHS
   // was the condition.
-  OpaqueValueExpr *opaqueValue = 0;
-  Expr *commonExpr = 0;
-  if (LHSExpr == 0) {
+  OpaqueValueExpr *opaqueValue = nullptr;
+  Expr *commonExpr = nullptr;
+  if (!LHSExpr) {
     commonExpr = CondExpr;
     // Lower out placeholder types first.  This is important so that we don't
     // try to capture a placeholder. This happens in few cases in C++; such
@@ -5910,7 +6080,7 @@
     if (commonExpr->hasPlaceholderType()) {
       ExprResult result = CheckPlaceholderExpr(commonExpr);
       if (!result.isUsable()) return ExprError();
-      commonExpr = result.take();
+      commonExpr = result.get();
     }
     // We usually want to apply unary conversions *before* saving, except
     // in the special case of a C++ l-value conditional.
@@ -5924,7 +6094,7 @@
       ExprResult commonRes = UsualUnaryConversions(commonExpr);
       if (commonRes.isInvalid())
         return ExprError();
-      commonExpr = commonRes.take();
+      commonExpr = commonRes.get();
     }
 
     opaqueValue = new (Context) OpaqueValueExpr(commonExpr->getExprLoc(),
@@ -5937,7 +6107,7 @@
 
   ExprValueKind VK = VK_RValue;
   ExprObjectKind OK = OK_Ordinary;
-  ExprResult Cond = Owned(CondExpr), LHS = Owned(LHSExpr), RHS = Owned(RHSExpr);
+  ExprResult Cond = CondExpr, LHS = LHSExpr, RHS = RHSExpr;
   QualType result = CheckConditionalOperands(Cond, LHS, RHS, 
                                              VK, OK, QuestionLoc);
   if (result.isNull() || Cond.isInvalid() || LHS.isInvalid() ||
@@ -5948,14 +6118,13 @@
                                 RHS.get());
 
   if (!commonExpr)
-    return Owned(new (Context) ConditionalOperator(Cond.take(), QuestionLoc,
-                                                   LHS.take(), ColonLoc, 
-                                                   RHS.take(), result, VK, OK));
+    return new (Context)
+        ConditionalOperator(Cond.get(), QuestionLoc, LHS.get(), ColonLoc,
+                            RHS.get(), result, VK, OK);
 
-  return Owned(new (Context)
-    BinaryConditionalOperator(commonExpr, opaqueValue, Cond.take(), LHS.take(),
-                              RHS.take(), QuestionLoc, ColonLoc, result, VK,
-                              OK));
+  return new (Context) BinaryConditionalOperator(
+      commonExpr, opaqueValue, Cond.get(), LHS.get(), RHS.get(), QuestionLoc,
+      ColonLoc, result, VK, OK);
 }
 
 // checkPointerTypesForAssignment - This is a very tricky routine (despite
@@ -5971,15 +6140,16 @@
   // get the "pointed to" type (ignoring qualifiers at the top level)
   const Type *lhptee, *rhptee;
   Qualifiers lhq, rhq;
-  llvm::tie(lhptee, lhq) = cast<PointerType>(LHSType)->getPointeeType().split();
-  llvm::tie(rhptee, rhq) = cast<PointerType>(RHSType)->getPointeeType().split();
+  std::tie(lhptee, lhq) =
+      cast<PointerType>(LHSType)->getPointeeType().split().asPair();
+  std::tie(rhptee, rhq) =
+      cast<PointerType>(RHSType)->getPointeeType().split().asPair();
 
   Sema::AssignConvertType ConvTy = Sema::Compatible;
 
   // C99 6.5.16.1p1: This following citation is common to constraints
   // 3 & 4 (below). ...and the type *pointed to* by the left has all the
   // qualifiers of the type *pointed to* by the right;
-  Qualifiers lq;
 
   // As a special case, 'non-__weak A *' -> 'non-__weak const *' is okay.
   if (lhq.getObjCLifetime() != rhq.getObjCLifetime() &&
@@ -6206,7 +6376,7 @@
     if (result != Compatible)
       return result;
     if (Kind != CK_NoOp)
-      RHS = ImpCastExprToType(RHS.take(), AtomicTy->getValueType(), Kind);
+      RHS = ImpCastExprToType(RHS.get(), AtomicTy->getValueType(), Kind);
     Kind = CK_NonAtomicToAtomic;
     return Compatible;
   }
@@ -6237,7 +6407,7 @@
       QualType elType = cast<ExtVectorType>(LHSType)->getElementType();
       if (elType != RHSType) {
         Kind = PrepareScalarCast(RHS, elType);
-        RHS = ImpCastExprToType(RHS.take(), elType, Kind);
+        RHS = ImpCastExprToType(RHS.get(), elType, Kind);
       }
       Kind = CK_VectorSplat;
       return Compatible;
@@ -6257,8 +6427,7 @@
       // If we are allowing lax vector conversions, and LHS and RHS are both
       // vectors, the total size only needs to be the same. This is a bitcast;
       // no bits are changed but the result type is different.
-      if (getLangOpts().LaxVectorConversions &&
-          (Context.getTypeSize(LHSType) == Context.getTypeSize(RHSType))) {
+      if (isLaxVectorConversion(RHSType, LHSType)) {
         Kind = CK_BitCast;
         return IncompatibleVectors;
       }
@@ -6389,8 +6558,9 @@
       return IncompatiblePointer;
     }
 
-    // T^ -> A*
-    if (RHSType->isBlockPointerType()) {
+    // Only under strict condition T^ is compatible with an Objective-C pointer.
+    if (RHSType->isBlockPointerType() &&
+        isObjCPtrBlockCompatible(*this, Context, LHSType)) {
       maybeExtendBlockObject(*this, RHS);
       Kind = CK_BlockPointerToObjCPointerCast;
       return Compatible;
@@ -6451,7 +6621,7 @@
                                       FieldDecl *Field) {
   // Build an initializer list that designates the appropriate member
   // of the transparent union.
-  Expr *E = EResult.take();
+  Expr *E = EResult.get();
   InitListExpr *Initializer = new (C) InitListExpr(C, SourceLocation(),
                                                    E, SourceLocation());
   Initializer->setType(UnionType);
@@ -6460,9 +6630,8 @@
   // Build a compound literal constructing a value of the transparent
   // union type from this initializer list.
   TypeSourceInfo *unionTInfo = C.getTrivialTypeSourceInfo(UnionType);
-  EResult = S.Owned(
-    new (C) CompoundLiteralExpr(SourceLocation(), unionTInfo, UnionType,
-                                VK_RValue, Initializer, false));
+  EResult = new (C) CompoundLiteralExpr(SourceLocation(), unionTInfo, UnionType,
+                                        VK_RValue, Initializer, false);
 }
 
 Sema::AssignConvertType
@@ -6478,27 +6647,25 @@
 
   // The field to initialize within the transparent union.
   RecordDecl *UD = UT->getDecl();
-  FieldDecl *InitField = 0;
+  FieldDecl *InitField = nullptr;
   // It's compatible if the expression matches any of the fields.
-  for (RecordDecl::field_iterator it = UD->field_begin(),
-         itend = UD->field_end();
-       it != itend; ++it) {
+  for (auto *it : UD->fields()) {
     if (it->getType()->isPointerType()) {
       // If the transparent union contains a pointer type, we allow:
       // 1) void pointer
       // 2) null pointer constant
       if (RHSType->isPointerType())
         if (RHSType->castAs<PointerType>()->getPointeeType()->isVoidType()) {
-          RHS = ImpCastExprToType(RHS.take(), it->getType(), CK_BitCast);
-          InitField = *it;
+          RHS = ImpCastExprToType(RHS.get(), it->getType(), CK_BitCast);
+          InitField = it;
           break;
         }
 
       if (RHS.get()->isNullPointerConstant(Context,
                                            Expr::NPC_ValueDependentIsNull)) {
-        RHS = ImpCastExprToType(RHS.take(), it->getType(),
+        RHS = ImpCastExprToType(RHS.get(), it->getType(),
                                 CK_NullToPointer);
-        InitField = *it;
+        InitField = it;
         break;
       }
     }
@@ -6506,8 +6673,8 @@
     CastKind Kind = CK_Invalid;
     if (CheckAssignmentConstraints(it->getType(), RHS, Kind)
           == Compatible) {
-      RHS = ImpCastExprToType(RHS.take(), it->getType(), Kind);
-      InitField = *it;
+      RHS = ImpCastExprToType(RHS.get(), it->getType(), Kind);
+      InitField = it;
       break;
     }
   }
@@ -6564,12 +6731,14 @@
 
   // C99 6.5.16.1p1: the left operand is a pointer and the right is
   // a null pointer constant.
-  if ((LHSType->isPointerType() ||
-       LHSType->isObjCObjectPointerType() ||
-       LHSType->isBlockPointerType())
-      && RHS.get()->isNullPointerConstant(Context,
-                                          Expr::NPC_ValueDependentIsNull)) {
-    RHS = ImpCastExprToType(RHS.take(), LHSType, CK_NullToPointer);
+  if ((LHSType->isPointerType() || LHSType->isObjCObjectPointerType() ||
+       LHSType->isBlockPointerType()) &&
+      RHS.get()->isNullPointerConstant(Context,
+                                       Expr::NPC_ValueDependentIsNull)) {
+    CastKind Kind;
+    CXXCastPath Path;
+    CheckPointerConversion(RHS.get(), LHSType, Kind, Path, false);
+    RHS = ImpCastExprToType(RHS.get(), LHSType, Kind, VK_RValue, &Path);
     return Compatible;
   }
 
@@ -6580,7 +6749,7 @@
   //
   // Suppress this for references: C++ 8.5.3p5.
   if (!LHSType->isReferenceType()) {
-    RHS = DefaultFunctionArrayLvalueConversion(RHS.take());
+    RHS = DefaultFunctionArrayLvalueConversion(RHS.get());
     if (RHS.isInvalid())
       return Incompatible;
   }
@@ -6597,10 +6766,18 @@
   // does not have reference type.
   if (result != Incompatible && RHS.get()->getType() != LHSType) {
     QualType Ty = LHSType.getNonLValueExprType(Context);
-    Expr *E = RHS.take();
+    Expr *E = RHS.get();
     if (getLangOpts().ObjCAutoRefCount)
       CheckObjCARCConversion(SourceRange(), Ty, E, CCK_ImplicitConversion,
                              DiagnoseCFAudited);
+    if (getLangOpts().ObjC1 &&
+        (CheckObjCBridgeRelatedConversions(E->getLocStart(),
+                                          LHSType, E->getType(), E) ||
+         ConversionToObjCStringLiteralCheck(LHSType, E))) {
+      RHS = E;
+      return Compatible;
+    }
+    
     RHS = ImpCastExprToType(E, Ty, Kind);
   }
   return result;
@@ -6614,97 +6791,128 @@
   return QualType();
 }
 
+/// Try to convert a value of non-vector type to a vector type by converting
+/// the type to the element type of the vector and then performing a splat.
+/// If the language is OpenCL, we only use conversions that promote scalar
+/// rank; for C, Obj-C, and C++ we allow any real scalar conversion except
+/// for float->int.
+///
+/// \param scalar - if non-null, actually perform the conversions
+/// \return true if the operation fails (but without diagnosing the failure)
+static bool tryVectorConvertAndSplat(Sema &S, ExprResult *scalar,
+                                     QualType scalarTy,
+                                     QualType vectorEltTy,
+                                     QualType vectorTy) {
+  // The conversion to apply to the scalar before splatting it,
+  // if necessary.
+  CastKind scalarCast = CK_Invalid;
+  
+  if (vectorEltTy->isIntegralType(S.Context)) {
+    if (!scalarTy->isIntegralType(S.Context))
+      return true;
+    if (S.getLangOpts().OpenCL &&
+        S.Context.getIntegerTypeOrder(vectorEltTy, scalarTy) < 0)
+      return true;
+    scalarCast = CK_IntegralCast;
+  } else if (vectorEltTy->isRealFloatingType()) {
+    if (scalarTy->isRealFloatingType()) {
+      if (S.getLangOpts().OpenCL &&
+          S.Context.getFloatingTypeOrder(vectorEltTy, scalarTy) < 0)
+        return true;
+      scalarCast = CK_FloatingCast;
+    }
+    else if (scalarTy->isIntegralType(S.Context))
+      scalarCast = CK_IntegralToFloating;
+    else
+      return true;
+  } else {
+    return true;
+  }
+
+  // Adjust scalar if desired.
+  if (scalar) {
+    if (scalarCast != CK_Invalid)
+      *scalar = S.ImpCastExprToType(scalar->get(), vectorEltTy, scalarCast);
+    *scalar = S.ImpCastExprToType(scalar->get(), vectorTy, CK_VectorSplat);
+  }
+  return false;
+}
+
 QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
                                    SourceLocation Loc, bool IsCompAssign) {
   if (!IsCompAssign) {
-    LHS = DefaultFunctionArrayLvalueConversion(LHS.take());
+    LHS = DefaultFunctionArrayLvalueConversion(LHS.get());
     if (LHS.isInvalid())
       return QualType();
   }
-  RHS = DefaultFunctionArrayLvalueConversion(RHS.take());
+  RHS = DefaultFunctionArrayLvalueConversion(RHS.get());
   if (RHS.isInvalid())
     return QualType();
 
   // For conversion purposes, we ignore any qualifiers.
   // For example, "const float" and "float" are equivalent.
-  QualType LHSType =
-    Context.getCanonicalType(LHS.get()->getType()).getUnqualifiedType();
-  QualType RHSType =
-    Context.getCanonicalType(RHS.get()->getType()).getUnqualifiedType();
+  QualType LHSType = LHS.get()->getType().getUnqualifiedType();
+  QualType RHSType = RHS.get()->getType().getUnqualifiedType();
 
   // If the vector types are identical, return.
-  if (LHSType == RHSType)
+  if (Context.hasSameType(LHSType, RHSType))
     return LHSType;
 
-  // Handle the case of equivalent AltiVec and GCC vector types
-  if (LHSType->isVectorType() && RHSType->isVectorType() &&
+  const VectorType *LHSVecType = LHSType->getAs<VectorType>();
+  const VectorType *RHSVecType = RHSType->getAs<VectorType>();
+  assert(LHSVecType || RHSVecType);
+
+  // If we have compatible AltiVec and GCC vector types, use the AltiVec type.
+  if (LHSVecType && RHSVecType &&
       Context.areCompatibleVectorTypes(LHSType, RHSType)) {
-    if (LHSType->isExtVectorType()) {
-      RHS = ImpCastExprToType(RHS.take(), LHSType, CK_BitCast);
+    if (isa<ExtVectorType>(LHSVecType)) {
+      RHS = ImpCastExprToType(RHS.get(), LHSType, CK_BitCast);
       return LHSType;
     }
 
     if (!IsCompAssign)
-      LHS = ImpCastExprToType(LHS.take(), RHSType, CK_BitCast);
+      LHS = ImpCastExprToType(LHS.get(), RHSType, CK_BitCast);
     return RHSType;
   }
 
-  if (getLangOpts().LaxVectorConversions &&
-      Context.getTypeSize(LHSType) == Context.getTypeSize(RHSType)) {
-    // If we are allowing lax vector conversions, and LHS and RHS are both
-    // vectors, the total size only needs to be the same. This is a
-    // bitcast; no bits are changed but the result type is different.
-    // FIXME: Should we really be allowing this?
-    RHS = ImpCastExprToType(RHS.take(), LHSType, CK_BitCast);
-    return LHSType;
+  // If there's an ext-vector type and a scalar, try to convert the scalar to
+  // the vector element type and splat.
+  if (!RHSVecType && isa<ExtVectorType>(LHSVecType)) {
+    if (!tryVectorConvertAndSplat(*this, &RHS, RHSType,
+                                  LHSVecType->getElementType(), LHSType))
+      return LHSType;
+  }
+  if (!LHSVecType && isa<ExtVectorType>(RHSVecType)) {
+    if (!tryVectorConvertAndSplat(*this, (IsCompAssign ? nullptr : &LHS),
+                                  LHSType, RHSVecType->getElementType(),
+                                  RHSType))
+      return RHSType;
   }
 
-  // Canonicalize the ExtVector to the LHS, remember if we swapped so we can
-  // swap back (so that we don't reverse the inputs to a subtract, for instance.
-  bool swapped = false;
-  if (RHSType->isExtVectorType() && !IsCompAssign) {
-    swapped = true;
-    std::swap(RHS, LHS);
-    std::swap(RHSType, LHSType);
+  // If we're allowing lax vector conversions, only the total (data) size
+  // needs to be the same.
+  // FIXME: Should we really be allowing this?
+  // FIXME: We really just pick the LHS type arbitrarily?
+  if (isLaxVectorConversion(RHSType, LHSType)) {
+    QualType resultType = LHSType;
+    RHS = ImpCastExprToType(RHS.get(), resultType, CK_BitCast);
+    return resultType;
   }
 
-  // Handle the case of an ext vector and scalar.
-  if (const ExtVectorType *LV = LHSType->getAs<ExtVectorType>()) {
-    QualType EltTy = LV->getElementType();
-    if (EltTy->isIntegralType(Context) && RHSType->isIntegralType(Context)) {
-      int order = Context.getIntegerTypeOrder(EltTy, RHSType);
-      if (order > 0)
-        RHS = ImpCastExprToType(RHS.take(), EltTy, CK_IntegralCast);
-      if (order >= 0) {
-        RHS = ImpCastExprToType(RHS.take(), LHSType, CK_VectorSplat);
-        if (swapped) std::swap(RHS, LHS);
-        return LHSType;
-      }
-    }
-    if (EltTy->isRealFloatingType() && RHSType->isScalarType()) {
-      if (RHSType->isRealFloatingType()) {
-        int order = Context.getFloatingTypeOrder(EltTy, RHSType);
-        if (order > 0)
-          RHS = ImpCastExprToType(RHS.take(), EltTy, CK_FloatingCast);
-        if (order >= 0) {
-          RHS = ImpCastExprToType(RHS.take(), LHSType, CK_VectorSplat);
-          if (swapped) std::swap(RHS, LHS);
-          return LHSType;
-        }
-      }
-      if (RHSType->isIntegralType(Context)) {
-        RHS = ImpCastExprToType(RHS.take(), EltTy, CK_IntegralToFloating);
-        RHS = ImpCastExprToType(RHS.take(), LHSType, CK_VectorSplat);
-        if (swapped) std::swap(RHS, LHS);
-        return LHSType;
-      }
-    }
+  // Okay, the expression is invalid.
+
+  // If there's a non-vector, non-real operand, diagnose that.
+  if ((!RHSVecType && !RHSType->isRealType()) ||
+      (!LHSVecType && !LHSType->isRealType())) {
+    Diag(Loc, diag::err_typecheck_vector_not_convertable_non_scalar)
+      << LHSType << RHSType
+      << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
+    return QualType();
   }
 
-  // Vectors of different size or scalar and non-ext-vector are errors.
-  if (swapped) std::swap(RHS, LHS);
+  // Otherwise, use the generic diagnostic.
   Diag(Loc, diag::err_typecheck_vector_not_convertable)
-    << LHS.get()->getType() << RHS.get()->getType()
+    << LHSType << RHSType
     << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
   return QualType();
 }
@@ -7157,7 +7365,7 @@
         return QualType();
 
       // Check array bounds for pointer arithemtic
-      CheckArrayAccess(LHS.get(), RHS.get(), /*ArraySubscriptExpr*/0,
+      CheckArrayAccess(LHS.get(), RHS.get(), /*ArraySubscriptExpr*/nullptr,
                        /*AllowOnePastEnd*/true, /*IndexNegated*/true);
 
       if (CompLHSTy) *CompLHSTy = LHS.get()->getType();
@@ -7300,14 +7508,14 @@
   // For the LHS, do usual unary conversions, but then reset them away
   // if this is a compound assignment.
   ExprResult OldLHS = LHS;
-  LHS = UsualUnaryConversions(LHS.take());
+  LHS = UsualUnaryConversions(LHS.get());
   if (LHS.isInvalid())
     return QualType();
   QualType LHSType = LHS.get()->getType();
   if (IsCompAssign) LHS = OldLHS;
 
   // The RHS is simpler.
-  RHS = UsualUnaryConversions(RHS.take());
+  RHS = UsualUnaryConversions(RHS.get());
   if (RHS.isInvalid())
     return QualType();
   QualType RHSType = RHS.get()->getType();
@@ -7407,7 +7615,7 @@
          (LHSType->isMemberPointerType() && RHSType->isMemberPointerType()));
 
   bool NonStandardCompositeType = false;
-  bool *BoolPtr = S.isSFINAEContext() ? 0 : &NonStandardCompositeType;
+  bool *BoolPtr = S.isSFINAEContext() ? nullptr : &NonStandardCompositeType;
   QualType T = S.FindCompositePointerType(Loc, LHS, RHS, BoolPtr);
   if (T.isNull()) {
     diagnoseDistinctPointerComparison(S, Loc, LHS, RHS, /*isError*/true);
@@ -7419,8 +7627,8 @@
       << LHSType << RHSType << T << LHS.get()->getSourceRange()
       << RHS.get()->getSourceRange();
 
-  LHS = S.ImpCastExprToType(LHS.take(), T, CK_BitCast);
-  RHS = S.ImpCastExprToType(RHS.take(), T, CK_BitCast);
+  LHS = S.ImpCastExprToType(LHS.get(), T, CK_BitCast);
+  RHS = S.ImpCastExprToType(RHS.get(), T, CK_BitCast);
   return false;
 }
 
@@ -7486,11 +7694,11 @@
   if (!Method)
     return false;
 
-  QualType T = Method->param_begin()[0]->getType();
+  QualType T = Method->parameters()[0]->getType();
   if (!T->isObjCObjectPointerType())
     return false;
-  
-  QualType R = Method->getResultType();
+
+  QualType R = Method->getReturnType();
   if (!R->isScalarType())
     return false;
 
@@ -7644,7 +7852,7 @@
     if (Mem->isImplicitAccess())
       return Mem->getMemberDecl();
   }
-  return 0;
+  return nullptr;
 }
 
 // C99 6.5.8, C++ [expr.rel]
@@ -7687,7 +7895,7 @@
     ValueDecl *DL = getCompareDecl(LHSStripped);
     ValueDecl *DR = getCompareDecl(RHSStripped);
     if (DL && DR && DL == DR && !IsWithinTemplateSpecialization(DL)) {
-      DiagRuntimeBehavior(Loc, 0, PDiag(diag::warn_comparison_always)
+      DiagRuntimeBehavior(Loc, nullptr, PDiag(diag::warn_comparison_always)
                           << 0 // self-
                           << (Opc == BO_EQ
                               || Opc == BO_LE
@@ -7709,7 +7917,7 @@
           always_evals_to = 2; // e.g. array1 <= array2
           break;
         }
-        DiagRuntimeBehavior(Loc, 0, PDiag(diag::warn_comparison_always)
+        DiagRuntimeBehavior(Loc, nullptr, PDiag(diag::warn_comparison_always)
                             << 1 // array
                             << always_evals_to);
     }
@@ -7721,8 +7929,8 @@
 
     // Warn about comparisons against a string constant (unless the other
     // operand is null), the user probably wants strcmp.
-    Expr *literalString = 0;
-    Expr *literalStringStripped = 0;
+    Expr *literalString = nullptr;
+    Expr *literalStringStripped = nullptr;
     if ((isa<StringLiteral>(LHSStripped) || isa<ObjCEncodeExpr>(LHSStripped)) &&
         !RHSStripped->isNullPointerConstant(Context,
                                             Expr::NPC_ValueDependentIsNull)) {
@@ -7737,7 +7945,7 @@
     }
 
     if (literalString) {
-      DiagRuntimeBehavior(Loc, 0,
+      DiagRuntimeBehavior(Loc, nullptr,
         PDiag(diag::warn_stringcompare)
           << isa<ObjCEncodeExpr>(literalStringStripped)
           << literalString->getSourceRange());
@@ -7767,10 +7975,22 @@
       return ResultTy;
   }
 
-  bool LHSIsNull = LHS.get()->isNullPointerConstant(Context,
-                                              Expr::NPC_ValueDependentIsNull);
-  bool RHSIsNull = RHS.get()->isNullPointerConstant(Context,
-                                              Expr::NPC_ValueDependentIsNull);
+  const Expr::NullPointerConstantKind LHSNullKind =
+      LHS.get()->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull);
+  const Expr::NullPointerConstantKind RHSNullKind =
+      RHS.get()->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull);
+  bool LHSIsNull = LHSNullKind != Expr::NPCK_NotNull;
+  bool RHSIsNull = RHSNullKind != Expr::NPCK_NotNull;
+
+  if (!IsRelational && LHSIsNull != RHSIsNull) {
+    bool IsEquality = Opc == BO_EQ;
+    if (RHSIsNull)
+      DiagnoseAlwaysNonNullPointer(LHS.get(), RHSNullKind, IsEquality,
+                                   RHS.get()->getSourceRange());
+    else
+      DiagnoseAlwaysNonNullPointer(RHS.get(), LHSNullKind, IsEquality,
+                                   LHS.get()->getSourceRange());
+  }
 
   // All of the following pointer-related warnings are GCC extensions, except
   // when handling null pointer constants. 
@@ -7797,7 +8017,7 @@
           if (isSFINAEContext())
             return QualType();
           
-          RHS = ImpCastExprToType(RHS.take(), LHSType, CK_BitCast);
+          RHS = ImpCastExprToType(RHS.get(), LHSType, CK_BitCast);
           return ResultTy;
         }
       }
@@ -7828,10 +8048,14 @@
       diagnoseDistinctPointerComparison(*this, Loc, LHS, RHS, /*isError*/false);
     }
     if (LCanPointeeTy != RCanPointeeTy) {
+      unsigned AddrSpaceL = LCanPointeeTy.getAddressSpace();
+      unsigned AddrSpaceR = RCanPointeeTy.getAddressSpace();
+      CastKind Kind = AddrSpaceL != AddrSpaceR ? CK_AddressSpaceConversion
+                                               : CK_BitCast;
       if (LHSIsNull && !RHSIsNull)
-        LHS = ImpCastExprToType(LHS.take(), RHSType, CK_BitCast);
+        LHS = ImpCastExprToType(LHS.get(), RHSType, Kind);
       else
-        RHS = ImpCastExprToType(RHS.take(), LHSType, CK_BitCast);
+        RHS = ImpCastExprToType(RHS.get(), LHSType, Kind);
     }
     return ResultTy;
   }
@@ -7847,7 +8071,7 @@
         ((LHSType->isAnyPointerType() || LHSType->isNullPtrType()) ||
          (!IsRelational && 
           (LHSType->isMemberPointerType() || LHSType->isBlockPointerType())))) {
-      RHS = ImpCastExprToType(RHS.take(), LHSType, 
+      RHS = ImpCastExprToType(RHS.get(), LHSType, 
                         LHSType->isMemberPointerType()
                           ? CK_NullToMemberPointer
                           : CK_NullToPointer);
@@ -7857,7 +8081,7 @@
         ((RHSType->isAnyPointerType() || RHSType->isNullPtrType()) ||
          (!IsRelational && 
           (RHSType->isMemberPointerType() || RHSType->isBlockPointerType())))) {
-      LHS = ImpCastExprToType(LHS.take(), RHSType, 
+      LHS = ImpCastExprToType(LHS.get(), RHSType, 
                         RHSType->isMemberPointerType()
                           ? CK_NullToMemberPointer
                           : CK_NullToPointer);
@@ -7893,7 +8117,7 @@
         << LHSType << RHSType << LHS.get()->getSourceRange()
         << RHS.get()->getSourceRange();
     }
-    RHS = ImpCastExprToType(RHS.take(), LHSType, CK_BitCast);
+    RHS = ImpCastExprToType(RHS.get(), LHSType, CK_BitCast);
     return ResultTy;
   }
 
@@ -7911,11 +8135,11 @@
           << RHS.get()->getSourceRange();
     }
     if (LHSIsNull && !RHSIsNull)
-      LHS = ImpCastExprToType(LHS.take(), RHSType,
+      LHS = ImpCastExprToType(LHS.get(), RHSType,
                               RHSType->isPointerType() ? CK_BitCast
                                 : CK_AnyPointerToBlockPointerCast);
     else
-      RHS = ImpCastExprToType(RHS.take(), LHSType,
+      RHS = ImpCastExprToType(RHS.get(), LHSType,
                               LHSType->isPointerType() ? CK_BitCast
                                 : CK_AnyPointerToBlockPointerCast);
     return ResultTy;
@@ -7935,16 +8159,17 @@
                                           /*isError*/false);
       }
       if (LHSIsNull && !RHSIsNull) {
-        Expr *E = LHS.take();
+        Expr *E = LHS.get();
         if (getLangOpts().ObjCAutoRefCount)
           CheckObjCARCConversion(SourceRange(), RHSType, E, CCK_ImplicitConversion);
         LHS = ImpCastExprToType(E, RHSType,
                                 RPT ? CK_BitCast :CK_CPointerToObjCPointerCast);
       }
       else {
-        Expr *E = RHS.take();
+        Expr *E = RHS.get();
         if (getLangOpts().ObjCAutoRefCount)
-          CheckObjCARCConversion(SourceRange(), LHSType, E, CCK_ImplicitConversion);
+          CheckObjCARCConversion(SourceRange(), LHSType, E, CCK_ImplicitConversion, false,
+                                 Opc);
         RHS = ImpCastExprToType(E, LHSType,
                                 LPT ? CK_BitCast :CK_CPointerToObjCPointerCast);
       }
@@ -7959,9 +8184,9 @@
         diagnoseObjCLiteralComparison(*this, Loc, LHS, RHS, Opc);
 
       if (LHSIsNull && !RHSIsNull)
-        LHS = ImpCastExprToType(LHS.take(), RHSType, CK_BitCast);
+        LHS = ImpCastExprToType(LHS.get(), RHSType, CK_BitCast);
       else
-        RHS = ImpCastExprToType(RHS.take(), LHSType, CK_BitCast);
+        RHS = ImpCastExprToType(RHS.get(), LHSType, CK_BitCast);
       return ResultTy;
     }
   }
@@ -7993,10 +8218,10 @@
     }
     
     if (LHSType->isIntegerType())
-      LHS = ImpCastExprToType(LHS.take(), RHSType,
+      LHS = ImpCastExprToType(LHS.get(), RHSType,
                         LHSIsNull ? CK_NullToPointer : CK_IntegralToPointer);
     else
-      RHS = ImpCastExprToType(RHS.take(), LHSType,
+      RHS = ImpCastExprToType(RHS.get(), LHSType,
                         RHSIsNull ? CK_NullToPointer : CK_IntegralToPointer);
     return ResultTy;
   }
@@ -8004,12 +8229,12 @@
   // Handle block pointers.
   if (!IsRelational && RHSIsNull
       && LHSType->isBlockPointerType() && RHSType->isIntegerType()) {
-    RHS = ImpCastExprToType(RHS.take(), LHSType, CK_NullToPointer);
+    RHS = ImpCastExprToType(RHS.get(), LHSType, CK_NullToPointer);
     return ResultTy;
   }
   if (!IsRelational && LHSIsNull
       && LHSType->isIntegerType() && RHSType->isBlockPointerType()) {
-    LHS = ImpCastExprToType(LHS.take(), RHSType, CK_NullToPointer);
+    LHS = ImpCastExprToType(LHS.get(), RHSType, CK_NullToPointer);
     return ResultTy;
   }
 
@@ -8066,7 +8291,7 @@
       if (DeclRefExpr* DRR
             = dyn_cast<DeclRefExpr>(RHS.get()->IgnoreParenImpCasts()))
         if (DRL->getDecl() == DRR->getDecl())
-          DiagRuntimeBehavior(Loc, 0,
+          DiagRuntimeBehavior(Loc, nullptr,
                               PDiag(diag::warn_comparison_always)
                                 << 0 // self-
                                 << 2 // "a constant"
@@ -8110,13 +8335,13 @@
     return InvalidOperands(Loc, LHS, RHS);
   }
 
-  ExprResult LHSResult = Owned(LHS), RHSResult = Owned(RHS);
+  ExprResult LHSResult = LHS, RHSResult = RHS;
   QualType compType = UsualArithmeticConversions(LHSResult, RHSResult,
                                                  IsCompAssign);
   if (LHSResult.isInvalid() || RHSResult.isInvalid())
     return QualType();
-  LHS = LHSResult.take();
-  RHS = RHSResult.take();
+  LHS = LHSResult.get();
+  RHS = RHSResult.get();
 
   if (!compType.isNull() && compType->isIntegralOrUnscopedEnumerationType())
     return compType;
@@ -8144,7 +8369,8 @@
     // Parens on the RHS are ignored.
     llvm::APSInt Result;
     if (RHS.get()->EvaluateAsInt(Result, Context))
-      if ((getLangOpts().Bool && !RHS.get()->getType()->isBooleanType()) ||
+      if ((getLangOpts().Bool && !RHS.get()->getType()->isBooleanType() &&
+           !RHS.get()->getExprLoc().isMacroID()) ||
           (Result != 0 && Result != 1)) {
         Diag(Loc, diag::warn_logical_instead_of_bitwise)
           << RHS.get()->getSourceRange()
@@ -8178,11 +8404,11 @@
         return InvalidOperands(Loc, LHS, RHS);
     }
 
-    LHS = UsualUnaryConversions(LHS.take());
+    LHS = UsualUnaryConversions(LHS.get());
     if (LHS.isInvalid())
       return QualType();
 
-    RHS = UsualUnaryConversions(RHS.take());
+    RHS = UsualUnaryConversions(RHS.get());
     if (RHS.isInvalid())
       return QualType();
 
@@ -8222,7 +8448,7 @@
   ObjCMessageExpr *Base =
     dyn_cast<ObjCMessageExpr>(ME->getBase()->IgnoreParenImpCasts());
   if (!Base) return false;
-  return Base->getMethodDecl() != 0;
+  return Base->getMethodDecl() != nullptr;
 }
 
 /// Is the given expression (which must be 'const') a reference to a
@@ -8245,7 +8471,7 @@
   assert(var->hasLocalStorage() && "capture added 'const' to non-local?");
 
   // Decide whether the first capture was for a block or a lambda.
-  DeclContext *DC = S.CurContext, *Prev = 0;
+  DeclContext *DC = S.CurContext, *Prev = nullptr;
   while (DC != var->getDeclContext()) {
     Prev = DC;
     DC = DC->getParent();
@@ -8462,10 +8688,8 @@
         // we do not warn to warn spuriously when 'x' and 'y' are on separate
         // paths through the function. This should be revisited if
         // -Wrepeated-use-of-weak is made flow-sensitive.
-        DiagnosticsEngine::Level Level =
-          Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak,
-                                   RHS.get()->getLocStart());
-        if (Level != DiagnosticsEngine::Ignored)
+        if (!Diags.isIgnored(diag::warn_arc_repeated_use_of_weak,
+                             RHS.get()->getLocStart()))
           getCurFunction()->markSafeWeakUse(RHS.get());
 
       } else if (getLangOpts().ObjCAutoRefCount) {
@@ -8497,8 +8721,8 @@
 // C99 6.5.17
 static QualType CheckCommaOperands(Sema &S, ExprResult &LHS, ExprResult &RHS,
                                    SourceLocation Loc) {
-  LHS = S.CheckPlaceholderExpr(LHS.take());
-  RHS = S.CheckPlaceholderExpr(RHS.take());
+  LHS = S.CheckPlaceholderExpr(LHS.get());
+  RHS = S.CheckPlaceholderExpr(RHS.get());
   if (LHS.isInvalid() || RHS.isInvalid())
     return QualType();
 
@@ -8508,14 +8732,14 @@
 
   // So we treat the LHS as a ignored value, and in C++ we allow the
   // containing site to determine what should be done with the RHS.
-  LHS = S.IgnoredValueConversions(LHS.take());
+  LHS = S.IgnoredValueConversions(LHS.get());
   if (LHS.isInvalid())
     return QualType();
 
   S.DiagnoseUnusedExprResult(LHS.get());
 
   if (!S.getLangOpts().CPlusPlus) {
-    RHS = S.DefaultFunctionArrayLvalueConversion(RHS.take());
+    RHS = S.DefaultFunctionArrayLvalueConversion(RHS.get());
     if (RHS.isInvalid())
       return QualType();
     if (!RHS.get()->getType()->isVoidType())
@@ -8575,7 +8799,7 @@
   } else if (ResType->isPlaceholderType()) {
     ExprResult PR = S.CheckPlaceholderExpr(Op);
     if (PR.isInvalid()) return QualType();
-    return CheckIncrementDecrementOperand(S, PR.take(), VK, OpLoc,
+    return CheckIncrementDecrementOperand(S, PR.get(), VK, OpLoc,
                                           IsInc, IsPrefix);
   } else if (S.getLangOpts().AltiVec && ResType->isVectorType()) {
     // OK! ( C/C++ Language Extensions for CBEA(Version 2.6) 10.3 )
@@ -8625,7 +8849,7 @@
     // the base's value, so the object the base refers to is
     // irrelevant.
     if (cast<MemberExpr>(E)->isArrow())
-      return 0;
+      return nullptr;
     // Otherwise, the expression refers to a part of the base
     return getPrimaryDecl(cast<MemberExpr>(E)->getBase());
   case Stmt::ArraySubscriptExprClass: {
@@ -8636,7 +8860,7 @@
       if (ICE->getSubExpr()->getType()->isArrayType())
         return getPrimaryDecl(ICE->getSubExpr());
     }
-    return 0;
+    return nullptr;
   }
   case Stmt::UnaryOperatorClass: {
     UnaryOperator *UO = cast<UnaryOperator>(E);
@@ -8647,7 +8871,7 @@
     case UO_Extension:
       return getPrimaryDecl(UO->getSubExpr());
     default:
-      return 0;
+      return nullptr;
     }
   }
   case Stmt::ParenExprClass:
@@ -8657,7 +8881,7 @@
     // the sub-expression; otherwise, the result here doesn't matter.
     return getPrimaryDecl(cast<ImplicitCastExpr>(E)->getSubExpr());
   default:
-    return 0;
+    return nullptr;
   }
 }
 
@@ -8716,7 +8940,7 @@
       return QualType();
     }
 
-    OrigOp = CheckPlaceholderExpr(OrigOp.take());
+    OrigOp = CheckPlaceholderExpr(OrigOp.get());
     if (OrigOp.isInvalid()) return QualType();
   }
 
@@ -8728,6 +8952,12 @@
   // Make sure to ignore parentheses in subsequent checks
   Expr *op = OrigOp.get()->IgnoreParens();
 
+  // OpenCL v1.0 s6.8.a.3: Pointers to functions are not allowed.
+  if (LangOpts.OpenCL && op->getType()->isFunctionType()) {
+    Diag(op->getExprLoc(), diag::err_opencl_taking_function_address);
+    return QualType();
+  }
+
   if (getLangOpts().C99) {
     // Implement C99-only parts of addressof rules.
     if (UnaryOperator* uOp = dyn_cast<UnaryOperator>(op)) {
@@ -8752,7 +8982,7 @@
       return QualType();
     // Materialize the temporary as an lvalue so that we can take its address.
     OrigOp = op = new (Context)
-        MaterializeTemporaryExpr(op->getType(), OrigOp.take(), true, 0);
+        MaterializeTemporaryExpr(op->getType(), OrigOp.get(), true);
   } else if (isa<ObjCSelectorExpr>(op)) {
     return Context.getPointerType(op->getType());
   } else if (lval == Expr::LV_MemberFunction) {
@@ -8791,8 +9021,11 @@
     if (isa<CXXDestructorDecl>(MD))
       Diag(OpLoc, diag::err_typecheck_addrof_dtor) << op->getSourceRange();
 
-    return Context.getMemberPointerType(op->getType(),
-              Context.getTypeDeclType(MD->getParent()).getTypePtr());
+    QualType MPTy = Context.getMemberPointerType(
+        op->getType(), Context.getTypeDeclType(MD->getParent()).getTypePtr());
+    if (Context.getTargetInfo().getCXXABI().isMicrosoft())
+      RequireCompleteType(OpLoc, MPTy, 0);
+    return MPTy;
   } else if (lval != Expr::LV_Valid && lval != Expr::LV_IncompleteVoidType) {
     // C99 6.5.3.2p1
     // The operand must be either an l-value or a function designator
@@ -8840,8 +9073,13 @@
 
           while (cast<RecordDecl>(Ctx)->isAnonymousStructOrUnion())
             Ctx = Ctx->getParent();
-          return Context.getMemberPointerType(op->getType(),
-                Context.getTypeDeclType(cast<RecordDecl>(Ctx)).getTypePtr());
+
+          QualType MPTy = Context.getMemberPointerType(
+              op->getType(),
+              Context.getTypeDeclType(cast<RecordDecl>(Ctx)).getTypePtr());
+          if (Context.getTargetInfo().getCXXABI().isMicrosoft())
+            RequireCompleteType(OpLoc, MPTy, 0);
+          return MPTy;
         }
       }
     } else if (!isa<FunctionDecl>(dcl) && !isa<NonTypeTemplateParmDecl>(dcl))
@@ -8875,7 +9113,7 @@
   ExprResult ConvResult = S.UsualUnaryConversions(Op);
   if (ConvResult.isInvalid())
     return QualType();
-  Op = ConvResult.take();
+  Op = ConvResult.get();
   QualType OpTy = Op->getType();
   QualType Result;
 
@@ -8885,10 +9123,6 @@
                                      Op->getSourceRange());
   }
 
-  // Note that per both C89 and C99, indirection is always legal, even if OpTy
-  // is an incomplete type or void.  It would be possible to warn about
-  // dereferencing a void pointer, but it's completely well-defined, and such a
-  // warning is unlikely to catch any mistakes.
   if (const PointerType *PT = OpTy->getAs<PointerType>())
     Result = PT->getPointeeType();
   else if (const ObjCObjectPointerType *OPT =
@@ -8897,8 +9131,8 @@
   else {
     ExprResult PR = S.CheckPlaceholderExpr(Op);
     if (PR.isInvalid()) return QualType();
-    if (PR.take() != Op)
-      return CheckIndirectionOperand(S, PR.take(), VK, OpLoc);
+    if (PR.get() != Op)
+      return CheckIndirectionOperand(S, PR.get(), VK, OpLoc);
   }
 
   if (Result.isNull()) {
@@ -8907,6 +9141,19 @@
     return QualType();
   }
 
+  // Note that per both C89 and C99, indirection is always legal, even if Result
+  // is an incomplete type or void.  It would be possible to warn about
+  // dereferencing a void pointer, but it's completely well-defined, and such a
+  // warning is unlikely to catch any mistakes. In C++, indirection is not valid
+  // for pointers to 'void' but is fine for any other pointer type:
+  //
+  // C++ [expr.unary.op]p1:
+  //   [...] the expression to which [the unary * operator] is applied shall
+  //   be a pointer to an object type, or a pointer to a function type
+  if (S.getLangOpts().CPlusPlus && Result->isVoidType())
+    S.Diag(OpLoc, diag::ext_typecheck_indirection_through_void_pointer)
+      << OpTy << Op->getSourceRange();
+
   // Dereferences are usually l-values...
   VK = VK_LValue;
 
@@ -9019,7 +9266,7 @@
   if (!S.getLangOpts().ObjC1)
     return;
 
-  const Expr *ObjCPointerExpr = 0, *OtherExpr = 0;
+  const Expr *ObjCPointerExpr = nullptr, *OtherExpr = nullptr;
   const Expr *LHS = L.get();
   const Expr *RHS = R.get();
 
@@ -9076,10 +9323,10 @@
     ExprResult Init = InitSeq.Perform(*this, Entity, Kind, RHSExpr);
     if (Init.isInvalid())
       return Init;
-    RHSExpr = Init.take();
+    RHSExpr = Init.get();
   }
 
-  ExprResult LHS = Owned(LHSExpr), RHS = Owned(RHSExpr);
+  ExprResult LHS = LHSExpr, RHS = RHSExpr;
   QualType ResultTy;     // Result type of the binary operator.
   // The following two variables are used for compound assignment operators
   QualType CompLHSTy;    // Type of LHS after promotions for computation
@@ -9173,8 +9420,9 @@
       ResultTy = CheckAssignmentOperands(LHS.get(), RHS, OpLoc, CompResultTy);
     break;
   case BO_AndAssign:
+  case BO_OrAssign: // fallthrough
+	  DiagnoseSelfAssignment(*this, LHS.get(), RHS.get(), OpLoc);
   case BO_XorAssign:
-  case BO_OrAssign:
     CompResultTy = CheckBitwiseOperands(LHS, RHS, OpLoc, true);
     CompLHSTy = CompResultTy;
     if (!CompResultTy.isNull() && !LHS.isInvalid() && !RHS.isInvalid())
@@ -9214,18 +9462,16 @@
     DiagnoseDirectIsaAccess(*this, OIRE, OpLoc, RHS.get());
   
   if (CompResultTy.isNull())
-    return Owned(new (Context) BinaryOperator(LHS.take(), RHS.take(), Opc,
-                                              ResultTy, VK, OK, OpLoc,
-                                              FPFeatures.fp_contract));
+    return new (Context) BinaryOperator(LHS.get(), RHS.get(), Opc, ResultTy, VK,
+                                        OK, OpLoc, FPFeatures.fp_contract);
   if (getLangOpts().CPlusPlus && LHS.get()->getObjectKind() !=
       OK_ObjCProperty) {
     VK = VK_LValue;
     OK = LHS.get()->getObjectKind();
   }
-  return Owned(new (Context) CompoundAssignOperator(LHS.take(), RHS.take(), Opc,
-                                                    ResultTy, VK, OK, CompLHSTy,
-                                                    CompResultTy, OpLoc,
-                                                    FPFeatures.fp_contract));
+  return new (Context) CompoundAssignOperator(
+      LHS.get(), RHS.get(), Opc, ResultTy, VK, OK, CompLHSTy, CompResultTy,
+      OpLoc, FPFeatures.fp_contract);
 }
 
 /// DiagnoseBitwisePrecedence - Emit a warning when bitwise and comparison
@@ -9443,8 +9689,8 @@
                             tok::TokenKind Kind,
                             Expr *LHSExpr, Expr *RHSExpr) {
   BinaryOperatorKind Opc = ConvertTokenKindToBinaryOpcode(Kind);
-  assert((LHSExpr != 0) && "ActOnBinOp(): missing left expression");
-  assert((RHSExpr != 0) && "ActOnBinOp(): missing right expression");
+  assert(LHSExpr && "ActOnBinOp(): missing left expression");
+  assert(RHSExpr && "ActOnBinOp(): missing right expression");
 
   // Emit warnings for tricky precedence issues, e.g. "bitfield & 0x4 == 0"
   DiagnoseBinOpPrecedence(*this, Opc, TokLoc, LHSExpr, RHSExpr);
@@ -9497,7 +9743,7 @@
       // instantiates to having an overloadable type.
       ExprResult resolvedRHS = CheckPlaceholderExpr(RHSExpr);
       if (resolvedRHS.isInvalid()) return ExprError();
-      RHSExpr = resolvedRHS.take();
+      RHSExpr = resolvedRHS.get();
 
       if (RHSExpr->isTypeDependent() ||
           RHSExpr->getType()->isOverloadableType())
@@ -9506,7 +9752,7 @@
         
     ExprResult LHS = CheckPlaceholderExpr(LHSExpr);
     if (LHS.isInvalid()) return ExprError();
-    LHSExpr = LHS.take();
+    LHSExpr = LHS.get();
   }
 
   // Handle pseudo-objects in the RHS.
@@ -9530,7 +9776,7 @@
 
     ExprResult resolvedRHS = CheckPlaceholderExpr(RHSExpr);
     if (!resolvedRHS.isUsable()) return ExprError();
-    RHSExpr = resolvedRHS.take();
+    RHSExpr = resolvedRHS.get();
   }
 
   if (getLangOpts().CPlusPlus) {
@@ -9553,7 +9799,7 @@
 ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
                                       UnaryOperatorKind Opc,
                                       Expr *InputExpr) {
-  ExprResult Input = Owned(InputExpr);
+  ExprResult Input = InputExpr;
   ExprValueKind VK = VK_RValue;
   ExprObjectKind OK = OK_Ordinary;
   QualType resultType;
@@ -9572,14 +9818,14 @@
     resultType = CheckAddressOfOperand(Input, OpLoc);
     break;
   case UO_Deref: {
-    Input = DefaultFunctionArrayLvalueConversion(Input.take());
+    Input = DefaultFunctionArrayLvalueConversion(Input.get());
     if (Input.isInvalid()) return ExprError();
     resultType = CheckIndirectionOperand(*this, Input.get(), VK, OpLoc);
     break;
   }
   case UO_Plus:
   case UO_Minus:
-    Input = UsualUnaryConversions(Input.take());
+    Input = UsualUnaryConversions(Input.get());
     if (Input.isInvalid()) return ExprError();
     resultType = Input.get()->getType();
     if (resultType->isDependentType())
@@ -9596,7 +9842,7 @@
       << resultType << Input.get()->getSourceRange());
 
   case UO_Not: // bitwise complement
-    Input = UsualUnaryConversions(Input.take());
+    Input = UsualUnaryConversions(Input.get());
     if (Input.isInvalid())
       return ExprError();
     resultType = Input.get()->getType();
@@ -9627,24 +9873,24 @@
 
   case UO_LNot: // logical negation
     // Unlike +/-/~, integer promotions aren't done here (C99 6.5.3.3p5).
-    Input = DefaultFunctionArrayLvalueConversion(Input.take());
+    Input = DefaultFunctionArrayLvalueConversion(Input.get());
     if (Input.isInvalid()) return ExprError();
     resultType = Input.get()->getType();
 
     // Though we still have to promote half FP to float...
     if (resultType->isHalfType() && !Context.getLangOpts().NativeHalfType) {
-      Input = ImpCastExprToType(Input.take(), Context.FloatTy, CK_FloatingCast).take();
+      Input = ImpCastExprToType(Input.get(), Context.FloatTy, CK_FloatingCast).get();
       resultType = Context.FloatTy;
     }
 
     if (resultType->isDependentType())
       break;
-    if (resultType->isScalarType()) {
+    if (resultType->isScalarType() && !isScopedEnumerationType(resultType)) {
       // C99 6.5.3.3p1: ok, fallthrough;
       if (Context.getLangOpts().CPlusPlus) {
         // C++03 [expr.unary.op]p8, C++0x [expr.unary.op]p9:
         // operand contextually converted to bool.
-        Input = ImpCastExprToType(Input.take(), Context.BoolTy,
+        Input = ImpCastExprToType(Input.get(), Context.BoolTy,
                                   ScalarTypeToBooleanCastKind(resultType));
       } else if (Context.getLangOpts().OpenCL &&
                  Context.getLangOpts().OpenCLVersion < 120) {
@@ -9688,7 +9934,7 @@
         VK = Input.get()->getValueKind();
     } else if (!getLangOpts().CPlusPlus) {
       // In C, a volatile scalar is read by __imag. In C++, it is not.
-      Input = DefaultLvalueConversion(Input.take());
+      Input = DefaultLvalueConversion(Input.get());
     }
     break;
   case UO_Extension:
@@ -9707,8 +9953,8 @@
   if (Opc != UO_AddrOf && Opc != UO_Deref)
     CheckArrayAccess(Input.get());
 
-  return Owned(new (Context) UnaryOperator(Input.take(), Opc, resultType,
-                                           VK, OK, OpLoc));
+  return new (Context)
+      UnaryOperator(Input.get(), Opc, resultType, VK, OK, OpLoc);
 }
 
 /// \brief Determine whether the given expression is a qualified member
@@ -9778,7 +10024,7 @@
     // Anything else needs to be handled now.
     ExprResult Result = CheckPlaceholderExpr(Input);
     if (Result.isInvalid()) return ExprError();
-    Input = Result.take();
+    Input = Result.get();
   }
 
   if (getLangOpts().CPlusPlus && Input->getType()->isOverloadableType() &&
@@ -9811,8 +10057,8 @@
                                 LabelDecl *TheDecl) {
   TheDecl->markUsed(Context);
   // Create the AST node.  The address of a label always has type 'void*'.
-  return Owned(new (Context) AddrLabelExpr(OpLoc, LabLoc, TheDecl,
-                                       Context.getPointerType(Context.VoidTy)));
+  return new (Context) AddrLabelExpr(OpLoc, LabLoc, TheDecl,
+                                     Context.getPointerType(Context.VoidTy));
 }
 
 /// Given the last statement in a statement-expression, check whether
@@ -9823,11 +10069,11 @@
 static Expr *maybeRebuildARCConsumingStmt(Stmt *Statement) {
   // Should always be wrapped with one of these.
   ExprWithCleanups *cleanups = dyn_cast<ExprWithCleanups>(Statement);
-  if (!cleanups) return 0;
+  if (!cleanups) return nullptr;
 
   ImplicitCastExpr *cast = dyn_cast<ImplicitCastExpr>(cleanups->getSubExpr());
   if (!cast || cast->getCastKind() != CK_ARCConsumeObject)
-    return 0;
+    return nullptr;
 
   // Splice out the cast.  This shouldn't modify any interesting
   // features of the statement.
@@ -9862,7 +10108,7 @@
   PopExpressionEvaluationContext();
 
   bool isFileScope
-    = (getCurFunctionOrMethodDecl() == 0) && (getCurBlock() == 0);
+    = (getCurFunctionOrMethodDecl() == nullptr) && (getCurBlock() == nullptr);
   if (isFileScope)
     return ExprError(Diag(LPLoc, diag::err_stmtexpr_file_scope));
 
@@ -9870,13 +10116,13 @@
   // example, it is not possible to goto into a stmt expression apparently.
   // More semantic analysis is needed.
 
-  // If there are sub stmts in the compound stmt, take the type of the last one
+  // If there are sub-stmts in the compound stmt, take the type of the last one
   // as the type of the stmtexpr.
   QualType Ty = Context.VoidTy;
   bool StmtExprMayBindToTemp = false;
   if (!Compound->body_empty()) {
     Stmt *LastStmt = Compound->body_back();
-    LabelStmt *LastLabelStmt = 0;
+    LabelStmt *LastLabelStmt = nullptr;
     // If LastStmt is a label, skip down through into the body.
     while (LabelStmt *Label = dyn_cast<LabelStmt>(LastStmt)) {
       LastLabelStmt = Label;
@@ -9912,11 +10158,11 @@
 
         if (LastExpr.isInvalid())
           return ExprError();
-        if (LastExpr.get() != 0) {
+        if (LastExpr.get() != nullptr) {
           if (!LastLabelStmt)
-            Compound->setLastStmt(LastExpr.take());
+            Compound->setLastStmt(LastExpr.get());
           else
-            LastLabelStmt->setSubStmt(LastExpr.take());
+            LastLabelStmt->setSubStmt(LastExpr.get());
           StmtExprMayBindToTemp = true;
         }
       }
@@ -9928,7 +10174,7 @@
   Expr *ResStmtExpr = new (Context) StmtExpr(Compound, Ty, LPLoc, RPLoc);
   if (StmtExprMayBindToTemp)
     return MaybeBindToTemporary(ResStmtExpr);
-  return Owned(ResStmtExpr);
+  return ResStmtExpr;
 }
 
 ExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc,
@@ -9983,7 +10229,7 @@
       ExprResult IdxRval = DefaultLvalueConversion(static_cast<Expr*>(OC.U.E));
       if (IdxRval.isInvalid())
         return ExprError();
-      Expr *Idx = IdxRval.take();
+      Expr *Idx = IdxRval.get();
 
       // The expression must be an integral expression.
       // FIXME: An integral constant expression?
@@ -10030,11 +10276,11 @@
     if (CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
       bool IsSafe = LangOpts.CPlusPlus11? CRD->isStandardLayout() : CRD->isPOD();
       unsigned DiagID =
-        LangOpts.CPlusPlus11? diag::warn_offsetof_non_standardlayout_type
-                            : diag::warn_offsetof_non_pod_type;
+        LangOpts.CPlusPlus11? diag::ext_offsetof_non_standardlayout_type
+                            : diag::ext_offsetof_non_pod_type;
 
       if (!IsSafe && !DidWarnAboutNonPOD &&
-          DiagRuntimeBehavior(BuiltinLoc, 0,
+          DiagRuntimeBehavior(BuiltinLoc, nullptr,
                               PDiag(DiagID)
                               << SourceRange(CompPtr[0].LocStart, OC.LocEnd)
                               << CurrentType))
@@ -10045,7 +10291,7 @@
     LookupResult R(*this, OC.U.IdentInfo, OC.LocStart, LookupMemberName);
     LookupQualifiedName(R, RD);
     FieldDecl *MemberDecl = R.getAsSingle<FieldDecl>();
-    IndirectFieldDecl *IndirectMemberDecl = 0;
+    IndirectFieldDecl *IndirectMemberDecl = nullptr;
     if (!MemberDecl) {
       if ((IndirectMemberDecl = R.getAsSingle<IndirectFieldDecl>()))
         MemberDecl = IndirectMemberDecl->getAnonField();
@@ -10090,12 +10336,10 @@
     }
 
     if (IndirectMemberDecl) {
-      for (IndirectFieldDecl::chain_iterator FI =
-           IndirectMemberDecl->chain_begin(),
-           FEnd = IndirectMemberDecl->chain_end(); FI != FEnd; FI++) {
-        assert(isa<FieldDecl>(*FI));
+      for (auto *FI : IndirectMemberDecl->chain()) {
+        assert(isa<FieldDecl>(FI));
         Comps.push_back(OffsetOfNode(OC.LocStart,
-                                     cast<FieldDecl>(*FI), OC.LocEnd));
+                                     cast<FieldDecl>(FI), OC.LocEnd));
       }
     } else
       Comps.push_back(OffsetOfNode(OC.LocStart, MemberDecl, OC.LocEnd));
@@ -10103,8 +10347,8 @@
     CurrentType = MemberDecl->getType().getNonReferenceType(); 
   }
   
-  return Owned(OffsetOfExpr::Create(Context, Context.getSizeType(), BuiltinLoc, 
-                                    TInfo, Comps, Exprs, RParenLoc));
+  return OffsetOfExpr::Create(Context, Context.getSizeType(), BuiltinLoc, TInfo,
+                              Comps, Exprs, RParenLoc);
 }
 
 ExprResult Sema::ActOnBuiltinOffsetOf(Scope *S,
@@ -10150,7 +10394,7 @@
           diag::err_typecheck_choose_expr_requires_constant, false);
     if (CondICE.isInvalid())
       return ExprError();
-    CondExpr = CondICE.take();
+    CondExpr = CondICE.get();
     CondIsTrue = condEval.getZExtValue();
 
     // If the condition is > zero, then the AST type is the same as the LSHExpr.
@@ -10162,10 +10406,9 @@
     OK = ActiveExpr->getObjectKind();
   }
 
-  return Owned(new (Context) ChooseExpr(BuiltinLoc, CondExpr, LHSExpr, RHSExpr,
-                                        resType, VK, OK, RPLoc, CondIsTrue,
-                                        resType->isDependentType(),
-                                        ValueDependent));
+  return new (Context)
+      ChooseExpr(BuiltinLoc, CondExpr, LHSExpr, RHSExpr, resType, VK, OK, RPLoc,
+                 CondIsTrue, resType->isDependentType(), ValueDependent);
 }
 
 //===----------------------------------------------------------------------===//
@@ -10202,7 +10445,8 @@
 
 void Sema::ActOnBlockArguments(SourceLocation CaretLoc, Declarator &ParamInfo,
                                Scope *CurScope) {
-  assert(ParamInfo.getIdentifier()==0 && "block-id should have no identifier!");
+  assert(ParamInfo.getIdentifier() == nullptr &&
+         "block-id should have no identifier!");
   assert(ParamInfo.getContext() == Declarator::BlockLiteralContext);
   BlockScopeInfo *CurBlock = getCurBlock();
 
@@ -10239,7 +10483,7 @@
         ExplicitSignature.getLocalRangeEnd()) {
       // This would be much cheaper if we stored TypeLocs instead of
       // TypeSourceInfos.
-      TypeLoc Result = ExplicitSignature.getResultLoc();
+      TypeLoc Result = ExplicitSignature.getReturnLoc();
       unsigned Size = Result.getFullDataSize();
       Sig = Context.CreateTypeSourceInfo(Result.getType(), Size);
       Sig->getTypeLoc().initializeFullCopy(Result, Size);
@@ -10252,7 +10496,7 @@
   CurBlock->FunctionType = T;
 
   const FunctionType *Fn = T->getAs<FunctionType>();
-  QualType RetTy = Fn->getResultType();
+  QualType RetTy = Fn->getReturnType();
   bool isVariadic =
     (isa<FunctionProtoType>(Fn) && cast<FunctionProtoType>(Fn)->isVariadic());
 
@@ -10271,9 +10515,9 @@
   // Push block parameters from the declarator if we had them.
   SmallVector<ParmVarDecl*, 8> Params;
   if (ExplicitSignature) {
-    for (unsigned I = 0, E = ExplicitSignature.getNumArgs(); I != E; ++I) {
-      ParmVarDecl *Param = ExplicitSignature.getArg(I);
-      if (Param->getIdentifier() == 0 &&
+    for (unsigned I = 0, E = ExplicitSignature.getNumParams(); I != E; ++I) {
+      ParmVarDecl *Param = ExplicitSignature.getParam(I);
+      if (Param->getIdentifier() == nullptr &&
           !Param->isImplicit() &&
           !Param->isInvalidDecl() &&
           !getLangOpts().CPlusPlus)
@@ -10284,12 +10528,9 @@
   // Fake up parameter variables if we have a typedef, like
   //   ^ fntype { ... }
   } else if (const FunctionProtoType *Fn = T->getAs<FunctionProtoType>()) {
-    for (FunctionProtoType::arg_type_iterator
-           I = Fn->arg_type_begin(), E = Fn->arg_type_end(); I != E; ++I) {
-      ParmVarDecl *Param =
-        BuildParmVarDeclForTypedef(CurBlock->TheDecl,
-                                   ParamInfo.getLocStart(),
-                                   *I);
+    for (const auto &I : Fn->param_types()) {
+      ParmVarDecl *Param = BuildParmVarDeclForTypedef(
+          CurBlock->TheDecl, ParamInfo.getLocStart(), I);
       Params.push_back(Param);
     }
   }
@@ -10306,15 +10547,14 @@
   ProcessDeclAttributes(CurScope, CurBlock->TheDecl, ParamInfo);
 
   // Put the parameter variables in scope.
-  for (BlockDecl::param_iterator AI = CurBlock->TheDecl->param_begin(),
-         E = CurBlock->TheDecl->param_end(); AI != E; ++AI) {
-    (*AI)->setOwningFunction(CurBlock->TheDecl);
+  for (auto AI : CurBlock->TheDecl->params()) {
+    AI->setOwningFunction(CurBlock->TheDecl);
 
     // If this has an identifier, add it to the scope stack.
-    if ((*AI)->getIdentifier()) {
-      CheckShadow(CurBlock->TheScope, *AI);
+    if (AI->getIdentifier()) {
+      CheckShadow(CurBlock->TheScope, AI);
 
-      PushOnScopeChains(*AI, CurBlock->TheScope);
+      PushOnScopeChains(AI, CurBlock->TheScope);
     }
   }
 }
@@ -10356,7 +10596,7 @@
   if (!BSI->ReturnType.isNull())
     RetTy = BSI->ReturnType;
 
-  bool NoReturn = BSI->TheDecl->getAttr<NoReturnAttr>();
+  bool NoReturn = BSI->TheDecl->hasAttr<NoReturnAttr>();
   QualType BlockTy;
 
   // Set the captured variables on the block.
@@ -10388,7 +10628,7 @@
 
     // Otherwise, if we don't need to change anything about the function type,
     // preserve its sugar structure.
-    } else if (FTy->getResultType() == RetTy &&
+    } else if (FTy->getReturnType() == RetTy &&
                (!NoReturn || FTy->getNoReturnAttr())) {
       BlockTy = BSI->FunctionType;
 
@@ -10398,7 +10638,7 @@
       FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
       EPI.TypeQuals = 0; // FIXME: silently?
       EPI.ExtInfo = Ext;
-      BlockTy = Context.getFunctionType(RetTy, FPT->getArgTypes(), EPI);
+      BlockTy = Context.getFunctionType(RetTy, FPT->getParamTypes(), EPI);
     }
 
   // If we don't have a function type, just build one from nothing.
@@ -10414,7 +10654,6 @@
 
   // If needed, diagnose invalid gotos and switches in the block.
   if (getCurFunction()->NeedsScopeChecking() &&
-      !hasAnyUnrecoverableErrorsInThisFunction() &&
       !PP.isCodeCompletionEnabled())
     DiagnoseInvalidJumps(cast<CompoundStmt>(Body));
 
@@ -10425,7 +10664,7 @@
   // to deduce an implicit return type.
   if (getLangOpts().CPlusPlus && RetTy->isRecordType() &&
       !BSI->TheDecl->isDependentContext())
-    computeNRVO(Body, getCurBlock());
+    computeNRVO(Body, BSI);
   
   BlockExpr *Result = new (Context) BlockExpr(BSI->TheDecl, BlockTy);
   AnalysisBasedWarnings::Policy WP = AnalysisWarnings.getDefaultPolicy();
@@ -10440,10 +10679,8 @@
 
     // It also gets a branch-protected scope if any of the captured
     // variables needs destruction.
-    for (BlockDecl::capture_const_iterator
-           ci = Result->getBlockDecl()->capture_begin(),
-           ce = Result->getBlockDecl()->capture_end(); ci != ce; ++ci) {
-      const VarDecl *var = ci->getVariable();
+    for (const auto &CI : Result->getBlockDecl()->captures()) {
+      const VarDecl *var = CI.getVariable();
       if (var->getType().isDestructedType() != QualType::DK_none) {
         getCurFunction()->setHasBranchProtectedScope();
         break;
@@ -10451,7 +10688,7 @@
     }
   }
 
-  return Owned(Result);
+  return Result;
 }
 
 ExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc,
@@ -10478,7 +10715,7 @@
     ExprResult Result = UsualUnaryConversions(E);
     if (Result.isInvalid())
       return ExprError();
-    E = Result.take();
+    E = Result.get();
   } else if (VaListType->isRecordType() && getLangOpts().CPlusPlus) {
     // If va_list is a record type and we are compiling in C++ mode,
     // check the argument using reference binding.
@@ -10488,7 +10725,7 @@
     ExprResult Init = PerformCopyInitialization(Entity, SourceLocation(), E);
     if (Init.isInvalid())
       return ExprError();
-    E = Init.takeAs<Expr>();
+    E = Init.getAs<Expr>();
   } else {
     // Otherwise, the va_list argument must be an l-value because
     // it is modified by va_arg.
@@ -10544,7 +10781,7 @@
   }
 
   QualType T = TInfo->getType().getNonLValueExprType(Context);
-  return Owned(new (Context) VAArgExpr(BuiltinLoc, E, TInfo, RPLoc, T));
+  return new (Context) VAArgExpr(BuiltinLoc, E, TInfo, RPLoc, T);
 }
 
 ExprResult Sema::ActOnGNUNullExpr(SourceLocation TokenLoc) {
@@ -10562,41 +10799,40 @@
     llvm_unreachable("I don't know size of pointer!");
   }
 
-  return Owned(new (Context) GNUNullExpr(Ty, TokenLoc));
+  return new (Context) GNUNullExpr(Ty, TokenLoc);
 }
 
-static void MakeObjCStringLiteralFixItHint(Sema& SemaRef, QualType DstType,
-                                           Expr *SrcExpr, FixItHint &Hint,
-                                           bool &IsNSString) {
-  if (!SemaRef.getLangOpts().ObjC1)
-    return;
+bool
+Sema::ConversionToObjCStringLiteralCheck(QualType DstType, Expr *&Exp) {
+  if (!getLangOpts().ObjC1)
+    return false;
 
   const ObjCObjectPointerType *PT = DstType->getAs<ObjCObjectPointerType>();
   if (!PT)
-    return;
+    return false;
 
-  // Check if the destination is of type 'id'.
   if (!PT->isObjCIdType()) {
     // Check if the destination is the 'NSString' interface.
     const ObjCInterfaceDecl *ID = PT->getInterfaceDecl();
     if (!ID || !ID->getIdentifier()->isStr("NSString"))
-      return;
-    IsNSString = true;
+      return false;
   }
-
+  
   // Ignore any parens, implicit casts (should only be
   // array-to-pointer decays), and not-so-opaque values.  The last is
   // important for making this trigger for property assignments.
-  SrcExpr = SrcExpr->IgnoreParenImpCasts();
+  Expr *SrcExpr = Exp->IgnoreParenImpCasts();
   if (OpaqueValueExpr *OV = dyn_cast<OpaqueValueExpr>(SrcExpr))
     if (OV->getSourceExpr())
       SrcExpr = OV->getSourceExpr()->IgnoreParenImpCasts();
 
   StringLiteral *SL = dyn_cast<StringLiteral>(SrcExpr);
   if (!SL || !SL->isAscii())
-    return;
-
-  Hint = FixItHint::CreateInsertion(SL->getLocStart(), "@");
+    return false;
+  Diag(SL->getLocStart(), diag::err_missing_atsign_prefix)
+    << FixItHint::CreateInsertion(SL->getLocStart(), "@");
+  Exp = BuildObjCStringLiteral(SL->getLocStart(), SL).get();
+  return true;
 }
 
 bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
@@ -10615,21 +10851,13 @@
   ConversionFixItGenerator ConvHints;
   bool MayHaveConvFixit = false;
   bool MayHaveFunctionDiff = false;
-  bool IsNSString = false;
+  const ObjCInterfaceDecl *IFace = nullptr;
+  const ObjCProtocolDecl *PDecl = nullptr;
 
   switch (ConvTy) {
   case Compatible:
-    // See if a proper null pointer constant is to be assigned.
-    if (DstType->isAnyPointerType() && !SrcType->isAnyPointerType() &&
-        SrcExpr->isNullPointerConstant(Context,
-                                       Expr::NPC_NeverValueDependent) ==
-            Expr::NPCK_ZeroExpression &&
-        !isUnevaluatedContext())
-      Diag(SrcExpr->getExprLoc(), diag::warn_non_literal_null_pointer)
-        << DstType << SrcExpr->getSourceRange();
-
-    DiagnoseAssignmentEnum(DstType, SrcType, SrcExpr);
-    return false;
+      DiagnoseAssignmentEnum(DstType, SrcType, SrcExpr);
+      return false;
 
   case PointerToInt:
     DiagKind = diag::ext_typecheck_convert_pointer_int;
@@ -10642,7 +10870,6 @@
     MayHaveConvFixit = true;
     break;
   case IncompatiblePointer:
-    MakeObjCStringLiteralFixItHint(*this, DstType, SrcExpr, Hint, IsNSString);
       DiagKind =
         (Action == AA_Passing_CFAudited ?
           diag::err_arc_typecheck_convert_incompatible_pointer :
@@ -10656,8 +10883,6 @@
       SrcType = SrcType.getUnqualifiedType();
       DstType = DstType.getUnqualifiedType();
     }
-    else if (IsNSString && !Hint.isNull())
-      DiagKind = diag::warn_missing_atsign_prefix;
     MayHaveConvFixit = true;
     break;
   case IncompatiblePointerSign:
@@ -10709,11 +10934,32 @@
   case IncompatibleBlockPointer:
     DiagKind = diag::err_typecheck_convert_incompatible_block_pointer;
     break;
-  case IncompatibleObjCQualifiedId:
-    // FIXME: Diagnose the problem in ObjCQualifiedIdTypesAreCompatible, since
-    // it can give a more specific diagnostic.
+  case IncompatibleObjCQualifiedId: {
+    if (SrcType->isObjCQualifiedIdType()) {
+      const ObjCObjectPointerType *srcOPT =
+                SrcType->getAs<ObjCObjectPointerType>();
+      for (auto *srcProto : srcOPT->quals()) {
+        PDecl = srcProto;
+        break;
+      }
+      if (const ObjCInterfaceType *IFaceT =
+            DstType->getAs<ObjCObjectPointerType>()->getInterfaceType())
+        IFace = IFaceT->getDecl();
+    }
+    else if (DstType->isObjCQualifiedIdType()) {
+      const ObjCObjectPointerType *dstOPT =
+        DstType->getAs<ObjCObjectPointerType>();
+      for (auto *dstProto : dstOPT->quals()) {
+        PDecl = dstProto;
+        break;
+      }
+      if (const ObjCInterfaceType *IFaceT =
+            SrcType->getAs<ObjCObjectPointerType>()->getInterfaceType())
+        IFace = IFaceT->getDecl();
+    }
     DiagKind = diag::warn_incompatible_qualified_id;
     break;
+  }
   case IncompatibleVectors:
     DiagKind = diag::warn_incompatible_vectors;
     break;
@@ -10771,7 +11017,11 @@
     HandleFunctionTypeMismatch(FDiag, SecondType, FirstType);
 
   Diag(Loc, FDiag);
-
+  if (DiagKind == diag::warn_incompatible_qualified_id &&
+      PDecl && IFace && !IFace->hasDefinition())
+      Diag(IFace->getLocation(), diag::not_incomplete_class_and_qualified_id)
+        << IFace->getName() << PDecl->getName();
+    
   if (SecondType == Context.OverloadTy)
     NoteAllOverloadCandidates(OverloadExpr::find(SrcExpr).Expression,
                               FirstType);
@@ -10791,7 +11041,7 @@
                                                  llvm::APSInt *Result) {
   class SimpleICEDiagnoser : public VerifyICEDiagnoser {
   public:
-    virtual void diagnoseNotICE(Sema &S, SourceLocation Loc, SourceRange SR) {
+    void diagnoseNotICE(Sema &S, SourceLocation Loc, SourceRange SR) override {
       S.Diag(Loc, diag::err_expr_not_ice) << S.LangOpts.CPlusPlus << SR;
     }
   } Diagnoser;
@@ -10810,7 +11060,7 @@
     IDDiagnoser(unsigned DiagID)
       : VerifyICEDiagnoser(DiagID == 0), DiagID(DiagID) { }
     
-    virtual void diagnoseNotICE(Sema &S, SourceLocation Loc, SourceRange SR) {
+    void diagnoseNotICE(Sema &S, SourceLocation Loc, SourceRange SR) override {
       S.Diag(Loc, DiagID) << SR;
     }
   } Diagnoser(DiagID);
@@ -10842,40 +11092,40 @@
           : ICEConvertDiagnoser(/*AllowScopedEnumerations*/false,
                                 Silent, true) {}
 
-      virtual SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
-                                                   QualType T) {
+      SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
+                                           QualType T) override {
         return S.Diag(Loc, diag::err_ice_not_integral) << T;
       }
 
-      virtual SemaDiagnosticBuilder diagnoseIncomplete(
-          Sema &S, SourceLocation Loc, QualType T) {
+      SemaDiagnosticBuilder diagnoseIncomplete(
+          Sema &S, SourceLocation Loc, QualType T) override {
         return S.Diag(Loc, diag::err_ice_incomplete_type) << T;
       }
 
-      virtual SemaDiagnosticBuilder diagnoseExplicitConv(
-          Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) {
+      SemaDiagnosticBuilder diagnoseExplicitConv(
+          Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override {
         return S.Diag(Loc, diag::err_ice_explicit_conversion) << T << ConvTy;
       }
 
-      virtual SemaDiagnosticBuilder noteExplicitConv(
-          Sema &S, CXXConversionDecl *Conv, QualType ConvTy) {
+      SemaDiagnosticBuilder noteExplicitConv(
+          Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override {
         return S.Diag(Conv->getLocation(), diag::note_ice_conversion_here)
                  << ConvTy->isEnumeralType() << ConvTy;
       }
 
-      virtual SemaDiagnosticBuilder diagnoseAmbiguous(
-          Sema &S, SourceLocation Loc, QualType T) {
+      SemaDiagnosticBuilder diagnoseAmbiguous(
+          Sema &S, SourceLocation Loc, QualType T) override {
         return S.Diag(Loc, diag::err_ice_ambiguous_conversion) << T;
       }
 
-      virtual SemaDiagnosticBuilder noteAmbiguous(
-          Sema &S, CXXConversionDecl *Conv, QualType ConvTy) {
+      SemaDiagnosticBuilder noteAmbiguous(
+          Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override {
         return S.Diag(Conv->getLocation(), diag::note_ice_conversion_here)
                  << ConvTy->isEnumeralType() << ConvTy;
       }
 
-      virtual SemaDiagnosticBuilder diagnoseConversion(
-          Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) {
+      SemaDiagnosticBuilder diagnoseConversion(
+          Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override {
         llvm_unreachable("conversion functions are permitted");
       }
     } ConvertDiagnoser(Diagnoser.Suppress);
@@ -10884,7 +11134,7 @@
                                                     ConvertDiagnoser);
     if (Converted.isInvalid())
       return Converted;
-    E = Converted.take();
+    E = Converted.get();
     if (!E->getType()->isIntegralOrUnscopedEnumerationType())
       return ExprError();
   } else if (!E->getType()->isIntegralOrUnscopedEnumerationType()) {
@@ -10899,7 +11149,7 @@
   if (!getLangOpts().CPlusPlus11 && E->isIntegerConstantExpr(Context)) {
     if (Result)
       *Result = E->EvaluateKnownConstInt(Context);
-    return Owned(E);
+    return E;
   }
 
   Expr::EvalResult EvalResult;
@@ -10917,7 +11167,7 @@
   if (Folded && getLangOpts().CPlusPlus11 && Notes.empty()) {
     if (Result)
       *Result = EvalResult.Val.getInt();
-    return Owned(E);
+    return E;
   }
 
   // If our only note is the usual "invalid subexpression" note, just point
@@ -10945,7 +11195,7 @@
 
   if (Result)
     *Result = EvalResult.Val.getInt();
-  return Owned(E);
+  return E;
 }
 
 namespace {
@@ -10964,7 +11214,7 @@
     // FIXME: This does the right thing, but maybe we need a more general
     // fix to TreeTransform?
     StmtResult TransformLabelStmt(LabelStmt *S) {
-      S->getDecl()->setStmt(0);
+      S->getDecl()->setStmt(nullptr);
       return BaseTransform::TransformLabelStmt(S);
     }
 
@@ -11181,37 +11431,32 @@
 
   // Note that this declaration has been used.
   if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(Func)) {
+    Constructor = cast<CXXConstructorDecl>(Constructor->getFirstDecl());
     if (Constructor->isDefaulted() && !Constructor->isDeleted()) {
       if (Constructor->isDefaultConstructor()) {
-        if (Constructor->isTrivial())
+        if (Constructor->isTrivial() && !Constructor->hasAttr<DLLExportAttr>())
           return;
-        if (!Constructor->isUsed(false))
-          DefineImplicitDefaultConstructor(Loc, Constructor);
+        DefineImplicitDefaultConstructor(Loc, Constructor);
       } else if (Constructor->isCopyConstructor()) {
-        if (!Constructor->isUsed(false))
-          DefineImplicitCopyConstructor(Loc, Constructor);
+        DefineImplicitCopyConstructor(Loc, Constructor);
       } else if (Constructor->isMoveConstructor()) {
-        if (!Constructor->isUsed(false))
-          DefineImplicitMoveConstructor(Loc, Constructor);
+        DefineImplicitMoveConstructor(Loc, Constructor);
       }
     } else if (Constructor->getInheritedConstructor()) {
-      if (!Constructor->isUsed(false))
-        DefineInheritingConstructor(Loc, Constructor);
+      DefineInheritingConstructor(Loc, Constructor);
     }
-
-    MarkVTableUsed(Loc, Constructor->getParent());
   } else if (CXXDestructorDecl *Destructor =
                  dyn_cast<CXXDestructorDecl>(Func)) {
-    if (Destructor->isDefaulted() && !Destructor->isDeleted() &&
-        !Destructor->isUsed(false))
+    Destructor = cast<CXXDestructorDecl>(Destructor->getFirstDecl());
+    if (Destructor->isDefaulted() && !Destructor->isDeleted())
       DefineImplicitDestructor(Loc, Destructor);
     if (Destructor->isVirtual())
       MarkVTableUsed(Loc, Destructor->getParent());
   } else if (CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(Func)) {
-    if (MethodDecl->isDefaulted() && !MethodDecl->isDeleted() &&
-        MethodDecl->isOverloadedOperator() &&
+    if (MethodDecl->isOverloadedOperator() &&
         MethodDecl->getOverloadedOperator() == OO_Equal) {
-      if (!MethodDecl->isUsed(false)) {
+      MethodDecl = cast<CXXMethodDecl>(MethodDecl->getFirstDecl());
+      if (MethodDecl->isDefaulted() && !MethodDecl->isDeleted()) {
         if (MethodDecl->isCopyAssignmentOperator())
           DefineImplicitCopyAssignment(Loc, MethodDecl);
         else
@@ -11219,7 +11464,8 @@
       }
     } else if (isa<CXXConversionDecl>(MethodDecl) &&
                MethodDecl->getParent()->isLambda()) {
-      CXXConversionDecl *Conversion = cast<CXXConversionDecl>(MethodDecl);
+      CXXConversionDecl *Conversion =
+          cast<CXXConversionDecl>(MethodDecl->getFirstDecl());
       if (Conversion->isLambdaToBlockPointerConversion())
         DefineImplicitLambdaToBlockPointerConversion(Loc, Conversion);
       else
@@ -11283,10 +11529,9 @@
     }
   } else {
     // Walk redefinitions, as some of them may be instantiable.
-    for (FunctionDecl::redecl_iterator i(Func->redecls_begin()),
-         e(Func->redecls_end()); i != e; ++i) {
+    for (auto i : Func->redecls()) {
       if (!i->isUsed(false) && i->isImplicitlyInstantiable())
-        MarkFunctionReferenced(Loc, *i);
+        MarkFunctionReferenced(Loc, i);
     }
   }
 
@@ -11352,8 +11597,8 @@
       << var->getIdentifier();
   }
 
-  S.Diag(var->getLocation(), diag::note_local_variable_declared_here)
-    << var->getIdentifier();
+  S.Diag(var->getLocation(), diag::note_entity_declared_at)
+      << var->getIdentifier();
 
   // FIXME: Add additional diagnostic info about class etc. which prevents
   // capture.
@@ -11395,7 +11640,7 @@
     if (Diagnose)
        diagnoseUncapturableValueReference(S, Loc, Var, DC);
   }
-  return 0;
+  return nullptr;
 }
 
 // Certain capturing entities (lambdas, blocks etc.) are not allowed to capture 
@@ -11421,7 +11666,7 @@
   }
 
   // Prohibit variably-modified types; they're difficult to deal with.
-  if (Var->getType()->isVariablyModifiedType()) {
+  if (Var->getType()->isVariablyModifiedType() && (IsBlock || IsLambda)) {
     if (Diagnose) {
       if (IsBlock)
         S.Diag(Loc, diag::err_ref_vm_type);
@@ -11472,7 +11717,7 @@
                                  QualType &DeclRefType, 
                                  const bool Nested,
                                  Sema &S) {
-  Expr *CopyExpr = 0;
+  Expr *CopyExpr = nullptr;
   bool ByRef = false;
       
   // Blocks are not allowed to capture arrays.
@@ -11530,7 +11775,7 @@
           = S.PerformCopyInitialization(
               InitializedEntity::InitializeBlock(Var->getLocation(),
                                                   CaptureType, false),
-              Loc, S.Owned(DeclRef));
+              Loc, DeclRef);
             
         // Build a full-expression copy expression if initialization
         // succeeded and used a non-trivial constructor.  Recover from
@@ -11539,7 +11784,7 @@
             !cast<CXXConstructExpr>(Result.get())->getConstructor()
                 ->isTrivial()) {
           Result = S.MaybeCreateExprWithCleanups(Result);
-          CopyExpr = Result.take();
+          CopyExpr = Result.get();
         }
       }
     }
@@ -11569,18 +11814,17 @@
   bool ByRef = true;
   // Using an LValue reference type is consistent with Lambdas (see below).
   CaptureType = S.Context.getLValueReferenceType(DeclRefType);
-  Expr *CopyExpr = 0;
+  Expr *CopyExpr = nullptr;
   if (BuildAndDiagnose) {
     // The current implementation assumes that all variables are captured
-    // by references. Since there is no capture by copy, no expression evaluation
-    // will be needed.
-    //
+    // by references. Since there is no capture by copy, no expression
+    // evaluation will be needed.
     RecordDecl *RD = RSI->TheRecordDecl;
 
     FieldDecl *Field
-      = FieldDecl::Create(S.Context, RD, Loc, Loc, 0, CaptureType,
+      = FieldDecl::Create(S.Context, RD, Loc, Loc, nullptr, CaptureType,
                           S.Context.getTrivialTypeSourceInfo(CaptureType, Loc),
-                          0, false, ICIS_NoInit);
+                          nullptr, false, ICIS_NoInit);
     Field->setImplicit(true);
     Field->setAccess(AS_private);
     RD->addDecl(Field);
@@ -11612,9 +11856,9 @@
 
   // Build the non-static data member.
   FieldDecl *Field
-    = FieldDecl::Create(S.Context, Lambda, Loc, Loc, 0, FieldType,
+    = FieldDecl::Create(S.Context, Lambda, Loc, Loc, nullptr, FieldType,
                         S.Context.getTrivialTypeSourceInfo(FieldType, Loc),
-                        0, false, ICIS_NoInit);
+                        nullptr, false, ICIS_NoInit);
   Field->setImplicit(true);
   Field->setAccess(AS_private);
   Lambda->addDecl(Field);
@@ -11652,7 +11896,7 @@
   while (const ConstantArrayType *Array
                         = S.Context.getAsConstantArrayType(BaseType)) {
     // Create the iteration variable for this array index.
-    IdentifierInfo *IterationVarName = 0;
+    IdentifierInfo *IterationVarName = nullptr;
     {
       SmallString<8> Str;
       llvm::raw_svector_ostream OS(Str);
@@ -11672,20 +11916,20 @@
       = S.BuildDeclRefExpr(IterationVar, SizeType, VK_LValue, Loc);
     assert(!IterationVarRef.isInvalid() &&
            "Reference to invented variable cannot fail!");
-    IterationVarRef = S.DefaultLvalueConversion(IterationVarRef.take());
+    IterationVarRef = S.DefaultLvalueConversion(IterationVarRef.get());
     assert(!IterationVarRef.isInvalid() &&
            "Conversion of invented variable cannot fail!");
     
     // Subscript the array with this iteration variable.
     ExprResult Subscript = S.CreateBuiltinArraySubscriptExpr(
-                             Ref, Loc, IterationVarRef.take(), Loc);
+                             Ref, Loc, IterationVarRef.get(), Loc);
     if (Subscript.isInvalid()) {
       S.CleanupVarDeclMarking();
       S.DiscardCleanupsInEvaluationContext();
       return ExprError();
     }
 
-    Ref = Subscript.take();
+    Ref = Subscript.get();
     BaseType = Array->getElementType();
   }
 
@@ -11695,7 +11939,8 @@
   SmallVector<InitializedEntity, 4> Entities;
   Entities.reserve(1 + IndexVariables.size());
   Entities.push_back(
-    InitializedEntity::InitializeLambdaCapture(Var, Field, Loc));
+    InitializedEntity::InitializeLambdaCapture(Var->getIdentifier(), 
+        Field->getType(), Loc));
   for (unsigned I = 0, N = IndexVariables.size(); I != N; ++I)
     Entities.push_back(InitializedEntity::InitializeElement(S.Context,
                                                             0,
@@ -11784,19 +12029,28 @@
       return false;
     }
 
-    if (S.RequireNonAbstractType(Loc, CaptureType,
-                                 diag::err_capture_of_abstract_type))
-      return false;
+    // Make sure that by-copy captures are of a complete and non-abstract type.
+    if (BuildAndDiagnose) {
+      if (!CaptureType->isDependentType() &&
+          S.RequireCompleteType(Loc, CaptureType,
+                                diag::err_capture_of_incomplete_type,
+                                Var->getDeclName()))
+        return false;
+
+      if (S.RequireNonAbstractType(Loc, CaptureType,
+                                   diag::err_capture_of_abstract_type))
+        return false;
+    }
   }
 
   // Capture this variable in the lambda.
-  Expr *CopyExpr = 0;
+  Expr *CopyExpr = nullptr;
   if (BuildAndDiagnose) {
     ExprResult Result = addAsFieldToClosureType(S, LSI, Var, 
                                         CaptureType, DeclRefType, Loc,
                                         RefersToEnclosingLocal);
     if (!Result.isInvalid())
-      CopyExpr = Result.take();
+      CopyExpr = Result.get();
   }
     
   // Compute the type of a reference to this captured variable.
@@ -11899,8 +12153,107 @@
     // certain types of variables (unnamed, variably modified types etc.)
     // so check for eligibility.
     if (!isVariableCapturable(CSI, Var, ExprLoc, BuildAndDiagnose, *this))
-       return true;    
-    
+       return true;
+
+    // Try to capture variable-length arrays types.
+    if (Var->getType()->isVariablyModifiedType()) {
+      // We're going to walk down into the type and look for VLA
+      // expressions.
+      QualType QTy = Var->getType();
+      if (ParmVarDecl *PVD = dyn_cast_or_null<ParmVarDecl>(Var))
+        QTy = PVD->getOriginalType();
+      do {
+        const Type *Ty = QTy.getTypePtr();
+        switch (Ty->getTypeClass()) {
+#define TYPE(Class, Base)
+#define ABSTRACT_TYPE(Class, Base)
+#define NON_CANONICAL_TYPE(Class, Base)
+#define DEPENDENT_TYPE(Class, Base) case Type::Class:
+#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base)
+#include "clang/AST/TypeNodes.def"
+          QTy = QualType();
+          break;
+        // These types are never variably-modified.
+        case Type::Builtin:
+        case Type::Complex:
+        case Type::Vector:
+        case Type::ExtVector:
+        case Type::Record:
+        case Type::Enum:
+        case Type::Elaborated:
+        case Type::TemplateSpecialization:
+        case Type::ObjCObject:
+        case Type::ObjCInterface:
+        case Type::ObjCObjectPointer:
+          llvm_unreachable("type class is never variably-modified!");
+        case Type::Adjusted:
+          QTy = cast<AdjustedType>(Ty)->getOriginalType();
+          break;
+        case Type::Decayed:
+          QTy = cast<DecayedType>(Ty)->getPointeeType();
+          break;
+        case Type::Pointer:
+          QTy = cast<PointerType>(Ty)->getPointeeType();
+          break;
+        case Type::BlockPointer:
+          QTy = cast<BlockPointerType>(Ty)->getPointeeType();
+          break;
+        case Type::LValueReference:
+        case Type::RValueReference:
+          QTy = cast<ReferenceType>(Ty)->getPointeeType();
+          break;
+        case Type::MemberPointer:
+          QTy = cast<MemberPointerType>(Ty)->getPointeeType();
+          break;
+        case Type::ConstantArray:
+        case Type::IncompleteArray:
+          // Losing element qualification here is fine.
+          QTy = cast<ArrayType>(Ty)->getElementType();
+          break;
+        case Type::VariableArray: {
+          // Losing element qualification here is fine.
+          const VariableArrayType *Vat = cast<VariableArrayType>(Ty);
+
+          // Unknown size indication requires no size computation.
+          // Otherwise, evaluate and record it.
+          if (Expr *Size = Vat->getSizeExpr()) {
+            MarkDeclarationsReferencedInExpr(Size);
+          }
+          QTy = Vat->getElementType();
+          break;
+        }
+        case Type::FunctionProto:
+        case Type::FunctionNoProto:
+          QTy = cast<FunctionType>(Ty)->getReturnType();
+          break;
+        case Type::Paren:
+        case Type::TypeOf:
+        case Type::UnaryTransform:
+        case Type::Attributed:
+        case Type::SubstTemplateTypeParm:
+        case Type::PackExpansion:
+          // Keep walking after single level desugaring.
+          QTy = QTy.getSingleStepDesugaredType(getASTContext());
+          break;
+        case Type::Typedef:
+          QTy = cast<TypedefType>(Ty)->desugar();
+          break;
+        case Type::Decltype:
+          QTy = cast<DecltypeType>(Ty)->desugar();
+          break;
+        case Type::Auto:
+          QTy = cast<AutoType>(Ty)->getDeducedType();
+          break;
+        case Type::TypeOfExpr:
+          QTy = cast<TypeOfExprType>(Ty)->getUnderlyingExpr()->getType();
+          break;
+        case Type::Atomic:
+          QTy = cast<AtomicType>(Ty)->getValueType();
+          break;
+        }
+      } while (!QTy.isNull() && QTy->isVariablyModifiedType());
+    }
+
     if (CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_None && !Explicit) {
       // No capture-default, and this is not an explicit capture 
       // so cannot capture this variable.  
@@ -11970,7 +12323,7 @@
   QualType DeclRefType;
   return tryCaptureVariable(Var, Loc, Kind, EllipsisLoc,
                             /*BuildAndDiagnose=*/true, CaptureType,
-                            DeclRefType, 0);
+                            DeclRefType, nullptr);
 }
 
 QualType Sema::getCapturedDeclRefType(VarDecl *Var, SourceLocation Loc) {
@@ -11980,7 +12333,7 @@
   // Determine whether we can capture this variable.
   if (tryCaptureVariable(Var, Loc, TryCapture_Implicit, SourceLocation(),
                          /*BuildAndDiagnose=*/false, CaptureType, 
-                         DeclRefType, 0))
+                         DeclRefType, nullptr))
     return QualType();
 
   return DeclRefType;
@@ -11997,7 +12350,7 @@
  
   if (Var->getType()->isDependentType()) 
     return false;
-  const VarDecl *DefVD = 0;
+  const VarDecl *DefVD = nullptr;
   Var->getAnyInitializer(DefVD);
   if (!DefVD) 
     return false;
@@ -12023,7 +12376,7 @@
   // variable. 
   if (LambdaScopeInfo *LSI = getCurLambda()) {
     Expr *SansParensExpr = E->IgnoreParens();
-    VarDecl *Var = 0;
+    VarDecl *Var = nullptr;
     if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(SansParensExpr)) 
       Var = dyn_cast<VarDecl>(DRE->getFoundDecl());
     else if (MemberExpr *ME = dyn_cast<MemberExpr>(SansParensExpr))
@@ -12062,7 +12415,8 @@
       llvm_unreachable("Unexpcted expression");
     }
 
-    MarkVarDeclODRUsed(Var, Loc, *this, /*MaxFunctionScopeIndex Pointer*/ 0);
+    MarkVarDeclODRUsed(Var, Loc, *this,
+                       /*MaxFunctionScopeIndex Pointer*/ nullptr);
   }
 
   MaybeODRUseExprs.clear();
@@ -12075,42 +12429,39 @@
          "Invalid Expr argument to DoMarkVarDeclReferenced");
   Var->setReferenced();
 
-  // If the context is not PotentiallyEvaluated and not Unevaluated 
-  // (i.e PotentiallyEvaluatedIfUsed) do not bother to consider variables 
-  // in this context for odr-use unless we are within a lambda.  
-  // If we don't know whether the context is potentially evaluated or not 
-  // (for e.g., if we're in a generic lambda), we want to add a potential 
-  // capture and eventually analyze for odr-use.
-  // We should also be able to analyze certain constructs in a non-generic 
-  // lambda setting for potential odr-use and capture violation:
-  // template<class T> void foo(T t) {
-  //    auto L = [](int i) { return t; };
-  // }
-  // 
+  // 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 (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)
+      return;
 
-    const bool refersToEnclosingScope =
-      (SemaRef.CurContext != Var->getDeclContext() &&
-           Var->getDeclContext()->isFunctionOrMethod());
-    if (!refersToEnclosingScope) return;
-    
     if (LambdaScopeInfo *const LSI = SemaRef.getCurLambda()) {
       // If a variable could potentially be odr-used, defer marking it so
-      // until we finish analyzing the full expression for any lvalue-to-rvalue 
+      // 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).
-      const bool IsConstantExpr = IsVariableNonDependentAndAConstantExpression(
-          Var, SemaRef.Context);
       assert(E && "Capture variable should be used in an expression.");
-      if (!IsConstantExpr || !Var->getType()->isReferenceType())
-        LSI->addPotentialCapture(E->IgnoreParens());      
-    } 
-    return;  
+      if (!Var->getType()->isReferenceType() ||
+          !IsVariableNonDependentAndAConstantExpression(Var, SemaRef.Context))
+        LSI->addPotentialCapture(E->IgnoreParens());
+    }
+    return;
   }
 
   VarTemplateSpecializationDecl *VarSpec =
@@ -12118,10 +12469,10 @@
   assert(!isa<VarTemplatePartialSpecializationDecl>(Var) &&
          "Can't instantiate a partial template specialization.");
 
-  // 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.
+  // 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.
   TemplateSpecializationKind TSK = Var->getTemplateSpecializationKind();
   if (isTemplateInstantiation(TSK)) {
     bool TryInstantiating = TSK == TSK_ImplicitInstantiation;
@@ -12161,6 +12512,7 @@
       }
     }
   }
+
   // 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)
@@ -12170,22 +12522,20 @@
   // 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)) {
-    // A reference initialized by a constant expression can never be 
+    // A reference initialized by a constant expression can never be
     // odr-used, so simply ignore it.
-    // But a non-reference might get odr-used if it doesn't undergo
-    // an lvalue-to-rvalue or is discarded, so track it.
     if (!Var->getType()->isReferenceType())
       SemaRef.MaybeODRUseExprs.insert(E);
-  }
-  else
-    MarkVarDeclODRUsed(Var, Loc, SemaRef, /*MaxFunctionScopeIndex ptr*/0);
+  } else
+    MarkVarDeclODRUsed(Var, Loc, SemaRef,
+                       /*MaxFunctionScopeIndex ptr*/ nullptr);
 }
 
 /// \brief Mark a variable referenced, and check whether it is odr-used
 /// (C++ [basic.def.odr]p2, C99 6.9p3).  Note that this should not be
 /// used directly for normal expressions referring to VarDecl.
 void Sema::MarkVariableReferenced(SourceLocation Loc, VarDecl *Var) {
-  DoMarkVarDeclReferenced(*this, Loc, Var, 0);
+  DoMarkVarDeclReferenced(*this, Loc, Var, nullptr);
 }
 
 static void MarkExprReferenced(Sema &SemaRef, SourceLocation Loc,
@@ -12247,9 +12597,9 @@
 }
 
 /// \brief Perform marking for a reference to an arbitrary declaration.  It
-/// marks the declaration referenced, and performs odr-use checking for functions
-/// and variables. This method should not be used when building an normal
-/// expression which refers to a variable.
+/// marks the declaration referenced, and performs odr-use checking for
+/// functions and variables. This method should not be used when building a
+/// normal expression which refers to a variable.
 void Sema::MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool OdrUse) {
   if (OdrUse) {
     if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
@@ -12283,7 +12633,7 @@
 }
 
 bool MarkReferencedDecls::TraverseTemplateArgument(
-  const TemplateArgument &Arg) {
+    const TemplateArgument &Arg) {
   if (Arg.getKind() == TemplateArgument::Declaration) {
     if (Decl *D = Arg.getAsDecl())
       S.MarkAnyDeclReferenced(Loc, D, true);
@@ -12330,7 +12680,7 @@
       
       S.MarkDeclRefReferenced(E);
     }
-    
+
     void VisitMemberExpr(MemberExpr *E) {
       S.MarkMemberReferenced(E);
       Inherited::VisitMemberExpr(E);
@@ -12453,8 +12803,8 @@
   public:
     CallReturnIncompleteDiagnoser(FunctionDecl *FD, CallExpr *CE)
       : FD(FD), CE(CE) { }
-    
-    virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) {
+
+    void diagnose(Sema &S, SourceLocation Loc, QualType T) override {
       if (!FD) {
         S.Diag(Loc, diag::err_call_incomplete_return)
           << T << CE->getSourceRange();
@@ -12463,9 +12813,8 @@
       
       S.Diag(Loc, diag::err_call_function_incomplete_return)
         << CE->getSourceRange() << FD->getDeclName() << T;
-      S.Diag(FD->getLocation(),
-             diag::note_function_with_incomplete_return_type_declared_here)
-        << FD->getDeclName();
+      S.Diag(FD->getLocation(), diag::note_entity_declared_at)
+          << FD->getDeclName();
     }
   } Diagnoser(FD, CE);
   
@@ -12569,7 +12918,7 @@
 
   ExprResult result = CheckPlaceholderExpr(E);
   if (result.isInvalid()) return ExprError();
-  E = result.take();
+  E = result.get();
 
   if (!E->isTypeDependent()) {
     if (getLangOpts().CPlusPlus)
@@ -12578,7 +12927,7 @@
     ExprResult ERes = DefaultFunctionArrayLvalueConversion(E);
     if (ERes.isInvalid())
       return ExprError();
-    E = ERes.take();
+    E = ERes.get();
 
     QualType T = E->getType();
     if (!T->isScalarType()) { // C99 6.8.4.1p1
@@ -12588,7 +12937,7 @@
     }
   }
 
-  return Owned(E);
+  return E;
 }
 
 ExprResult Sema::ActOnBooleanCondition(Scope *S, SourceLocation Loc,
@@ -12625,7 +12974,7 @@
       ExprResult SubResult = Visit(E->getSubExpr());
       if (SubResult.isInvalid()) return ExprError();
 
-      Expr *SubExpr = SubResult.take();
+      Expr *SubExpr = SubResult.get();
       E->setSubExpr(SubExpr);
       E->setType(SubExpr->getType());
       E->setValueKind(SubExpr->getValueKind());
@@ -12645,7 +12994,7 @@
       ExprResult SubResult = Visit(E->getSubExpr());
       if (SubResult.isInvalid()) return ExprError();
 
-      Expr *SubExpr = SubResult.take();
+      Expr *SubExpr = SubResult.get();
       E->setSubExpr(SubExpr);
       E->setType(S.Context.getPointerType(SubExpr->getType()));
       assert(E->getValueKind() == VK_RValue);
@@ -12682,7 +13031,7 @@
 static ExprResult rebuildUnknownAnyFunction(Sema &S, Expr *FunctionExpr) {
   ExprResult Result = RebuildUnknownAnyFunction(S).Visit(FunctionExpr);
   if (Result.isInvalid()) return ExprError();
-  return S.DefaultFunctionArrayConversion(Result.take());
+  return S.DefaultFunctionArrayConversion(Result.get());
 }
 
 namespace {
@@ -12719,7 +13068,7 @@
     template <class T> ExprResult rebuildSugarExpr(T *E) {
       ExprResult SubResult = Visit(E->getSubExpr());
       if (SubResult.isInvalid()) return ExprError();
-      Expr *SubExpr = SubResult.take();
+      Expr *SubExpr = SubResult.get();
       E->setSubExpr(SubExpr);
       E->setType(SubExpr->getType());
       E->setValueKind(SubExpr->getValueKind());
@@ -12750,7 +13099,7 @@
       DestType = Ptr->getPointeeType();
       ExprResult SubResult = Visit(E->getSubExpr());
       if (SubResult.isInvalid()) return ExprError();
-      E->setSubExpr(SubResult.take());
+      E->setSubExpr(SubResult.get());
       return E;
     }
 
@@ -12831,7 +13180,7 @@
     // This is a hack, but it is far superior to moving the
     // corresponding target-specific code from IR-gen to Sema/AST.
 
-    ArrayRef<QualType> ParamTypes = Proto->getArgTypes();
+    ArrayRef<QualType> ParamTypes = Proto->getParamTypes();
     SmallVector<QualType, 8> ArgTypes;
     if (ParamTypes.empty() && Proto->isVariadic()) { // the special case
       ArgTypes.reserve(E->getNumArgs());
@@ -12872,7 +13221,7 @@
   // Finally, we can recurse.
   ExprResult CalleeResult = Visit(CalleeExpr);
   if (!CalleeResult.isUsable()) return ExprError();
-  E->setCallee(CalleeResult.take());
+  E->setCallee(CalleeResult.get());
 
   // Bind a temporary if necessary.
   return S.MaybeBindToTemporary(E);
@@ -12888,8 +13237,8 @@
 
   // Rewrite the method result type if available.
   if (ObjCMethodDecl *Method = E->getMethodDecl()) {
-    assert(Method->getResultType() == S.Context.UnknownAnyTy);
-    Method->setResultType(DestType);
+    assert(Method->getReturnType() == S.Context.UnknownAnyTy);
+    Method->setReturnType(DestType);
   }
 
   // Change the type of the message.
@@ -12913,8 +13262,8 @@
     ExprResult Result = Visit(E->getSubExpr());
     if (!Result.isUsable()) return ExprError();
   
-    E->setSubExpr(Result.take());
-    return S.Owned(E);
+    E->setSubExpr(Result.get());
+    return E;
   } else if (E->getCastKind() == CK_LValueToRValue) {
     assert(E->getValueKind() == VK_RValue);
     assert(E->getObjectKind() == OK_Ordinary);
@@ -12929,8 +13278,8 @@
     ExprResult Result = Visit(E->getSubExpr());
     if (!Result.isUsable()) return ExprError();
 
-    E->setSubExpr(Result.take());
-    return S.Owned(E);
+    E->setSubExpr(Result.get());
+    return E;
   } else {
     llvm_unreachable("Unhandled cast type!");
   }
@@ -12948,7 +13297,7 @@
       DestType = Ptr->getPointeeType();
       ExprResult Result = resolveDecl(E, VD);
       if (Result.isInvalid()) return ExprError();
-      return S.ImpCastExprToType(Result.take(), Type,
+      return S.ImpCastExprToType(Result.get(), Type,
                                  CK_FunctionToPointerDecay, VK_RValue);
     }
 
@@ -12990,7 +13339,7 @@
   VD->setType(DestType);
   E->setType(Type);
   E->setValueKind(ValueKind);
-  return S.Owned(E);
+  return E;
 }
 
 /// Check a cast of an unknown-any type.  We intentionally only
@@ -13002,7 +13351,7 @@
   ExprResult result = RebuildUnknownAnyExpr(*this, CastType).Visit(CastExpr);
   if (!result.isUsable()) return ExprError();
 
-  CastExpr = result.take();
+  CastExpr = result.get();
   VK = CastExpr->getValueKind();
   CastKind = CK_NoOp;
 
@@ -13033,7 +13382,7 @@
   InitializedEntity entity =
     InitializedEntity::InitializeParameter(Context, paramType,
                                            /*consumed*/ false);
-  return PerformCopyInitialization(entity, callLoc, Owned(arg));
+  return PerformCopyInitialization(entity, callLoc, arg);
 }
 
 static ExprResult diagnoseUnknownAnyExpr(Sema &S, Expr *E) {
@@ -13083,7 +13432,7 @@
 /// Returns true if there was an error and no recovery was possible.
 ExprResult Sema::CheckPlaceholderExpr(Expr *E) {
   const BuiltinType *placeholderType = E->getType()->getAsPlaceholderType();
-  if (!placeholderType) return Owned(E);
+  if (!placeholderType) return E;
 
   switch (placeholderType->getKind()) {
 
@@ -13091,7 +13440,7 @@
   case BuiltinType::Overload: {
     // Try to resolve a single function template specialization.
     // This is obligatory.
-    ExprResult result = Owned(E);
+    ExprResult result = E;
     if (ResolveAndFixSingleFunctionTemplateSpecialization(result, false)) {
       return result;
 
@@ -13105,7 +13454,7 @@
 
   // Bound member functions.
   case BuiltinType::BoundMember: {
-    ExprResult result = Owned(E);
+    ExprResult result = E;
     tryToRecoverWithCall(result, PDiag(diag::err_bound_member_function),
                          /*complain*/ true);
     return result;
@@ -13115,7 +13464,7 @@
   case BuiltinType::ARCUnbridgedCast: {
     Expr *realCast = stripARCUnbridgedCast(E);
     diagnoseARCUnbridgedCast(realCast);
-    return Owned(realCast);
+    return realCast;
   }
 
   // Expressions of unknown type.
@@ -13126,9 +13475,22 @@
   case BuiltinType::PseudoObject:
     return checkPseudoObjectRValue(E);
 
-  case BuiltinType::BuiltinFn:
+  case BuiltinType::BuiltinFn: {
+    // Accept __noop without parens by implicitly converting it to a call expr.
+    auto *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts());
+    if (DRE) {
+      auto *FD = cast<FunctionDecl>(DRE->getDecl());
+      if (FD->getBuiltinID() == Builtin::BI__noop) {
+        E = ImpCastExprToType(E, Context.getPointerType(FD->getType()),
+                              CK_BuiltinFnToFnPtr).get();
+        return new (Context) CallExpr(Context, E, None, Context.IntTy,
+                                      VK_RValue, SourceLocation());
+      }
+    }
+
     Diag(E->getLocStart(), diag::err_builtin_fn_use);
     return ExprError();
+  }
 
   // Everything else should be impossible.
 #define BUILTIN_TYPE(Id, SingletonId) \
@@ -13166,6 +13528,6 @@
   }
   if (Context.getBOOLDecl())
     BoolT = Context.getBOOLType();
-  return Owned(new (Context) ObjCBoolLiteralExpr(Kind == tok::kw___objc_yes,
-                                        BoolT, OpLoc));
+  return new (Context)
+      ObjCBoolLiteralExpr(Kind == tok::kw___objc_yes, BoolT, OpLoc);
 }
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 59a167a..0dabdca 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -15,6 +15,7 @@
 #include "clang/Sema/SemaInternal.h"
 #include "TypeLocBuilder.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTLambda.h"
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/CharUnits.h"
 #include "clang/AST/DeclObjC.h"
@@ -106,7 +107,7 @@
   // For this reason, we're currently only doing the C++03 version of this
   // code; the C++0x version has to wait until we get a proper spec.
   QualType SearchType;
-  DeclContext *LookupCtx = 0;
+  DeclContext *LookupCtx = nullptr;
   bool isDependent = false;
   bool LookInScope = false;
 
@@ -117,38 +118,33 @@
     SearchType = GetTypeFromParser(ObjectTypePtr);
 
   if (SS.isSet()) {
-    NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
+    NestedNameSpecifier *NNS = SS.getScopeRep();
 
     bool AlreadySearched = false;
     bool LookAtPrefix = true;
-    // C++ [basic.lookup.qual]p6:
+    // C++11 [basic.lookup.qual]p6:
     //   If a pseudo-destructor-name (5.2.4) contains a nested-name-specifier,
     //   the type-names are looked up as types in the scope designated by the
-    //   nested-name-specifier. In a qualified-id of the form:
+    //   nested-name-specifier. Similarly, in a qualified-id of the form:
     //
-    //     ::[opt] nested-name-specifier  ~ class-name
+    //     nested-name-specifier[opt] class-name :: ~ class-name
     //
-    //   where the nested-name-specifier designates a namespace scope, and in
-    //   a qualified-id of the form:
+    //   the second class-name is looked up in the same scope as the first.
     //
-    //     ::opt nested-name-specifier class-name ::  ~ class-name
-    //
-    //   the class-names are looked up as types in the scope designated by
-    //   the nested-name-specifier.
-    //
-    // Here, we check the first case (completely) and determine whether the
-    // code below is permitted to look at the prefix of the
-    // nested-name-specifier.
+    // Here, we determine whether the code below is permitted to look at the
+    // prefix of the nested-name-specifier.
     DeclContext *DC = computeDeclContext(SS, EnteringContext);
     if (DC && DC->isFileContext()) {
       AlreadySearched = true;
       LookupCtx = DC;
       isDependent = false;
-    } else if (DC && isa<CXXRecordDecl>(DC))
+    } else if (DC && isa<CXXRecordDecl>(DC)) {
       LookAtPrefix = false;
+      LookInScope = true;
+    }
 
     // The second case from the C++03 rules quoted further above.
-    NestedNameSpecifier *Prefix = 0;
+    NestedNameSpecifier *Prefix = nullptr;
     if (AlreadySearched) {
       // Nothing left to do.
     } else if (LookAtPrefix && (Prefix = NNS->getPrefix())) {
@@ -163,8 +159,6 @@
       LookupCtx = computeDeclContext(SS, EnteringContext);
       isDependent = LookupCtx && LookupCtx->isDependentContext();
     }
-
-    LookInScope = false;
   } else if (ObjectTypePtr) {
     // C++ [basic.lookup.classref]p3:
     //   If the unqualified-id is ~type-name, the type-name is looked up
@@ -184,7 +178,7 @@
     LookInScope = true;
   }
 
-  TypeDecl *NonMatchingTypeDecl = 0;
+  TypeDecl *NonMatchingTypeDecl = nullptr;
   LookupResult Found(*this, &II, NameLoc, LookupOrdinaryName);
   for (unsigned Step = 0; Step != 2; ++Step) {
     // Look for the name first in the computed lookup context (if we
@@ -209,7 +203,8 @@
           Context.hasSameUnqualifiedType(T, SearchType)) {
         // We found our type!
 
-        return ParsedType::make(T);
+        return CreateParsedType(T,
+                                Context.getTrivialTypeSourceInfo(T, NameLoc));
       }
 
       if (!SearchType.isNull())
@@ -245,7 +240,9 @@
               = dyn_cast<ClassTemplateSpecializationDecl>(Record->getDecl())) {
           if (Spec->getSpecializedTemplate()->getCanonicalDecl() ==
                 Template->getCanonicalDecl())
-            return ParsedType::make(MemberOfType);
+            return CreateParsedType(
+                MemberOfType,
+                Context.getTrivialTypeSourceInfo(MemberOfType, NameLoc));
         }
 
         continue;
@@ -264,7 +261,9 @@
         // specialized.
         if (TemplateDecl *SpecTemplate = SpecName.getAsTemplateDecl()) {
           if (SpecTemplate->getCanonicalDecl() == Template->getCanonicalDecl())
-            return ParsedType::make(MemberOfType);
+            return CreateParsedType(
+                MemberOfType,
+                Context.getTrivialTypeSourceInfo(MemberOfType, NameLoc));
 
           continue;
         }
@@ -275,7 +274,9 @@
                                     = SpecName.getAsDependentTemplateName()) {
           if (DepTemplate->isIdentifier() &&
               DepTemplate->getIdentifier() == Template->getIdentifier())
-            return ParsedType::make(MemberOfType);
+            return CreateParsedType(
+                MemberOfType,
+                Context.getTrivialTypeSourceInfo(MemberOfType, NameLoc));
 
           continue;
         }
@@ -333,6 +334,34 @@
     return ParsedType();
 }
 
+bool Sema::checkLiteralOperatorId(const CXXScopeSpec &SS,
+                                  const UnqualifiedId &Name) {
+  assert(Name.getKind() == UnqualifiedId::IK_LiteralOperatorId);
+
+  if (!SS.isValid())
+    return false;
+
+  switch (SS.getScopeRep()->getKind()) {
+  case NestedNameSpecifier::Identifier:
+  case NestedNameSpecifier::TypeSpec:
+  case NestedNameSpecifier::TypeSpecWithTemplate:
+    // Per C++11 [over.literal]p2, literal operators can only be declared at
+    // namespace scope. Therefore, this unqualified-id cannot name anything.
+    // Reject it early, because we have no AST representation for this in the
+    // case where the scope is dependent.
+    Diag(Name.getLocStart(), diag::err_literal_operator_id_outside_namespace)
+      << SS.getScopeRep();
+    return true;
+
+  case NestedNameSpecifier::Global:
+  case NestedNameSpecifier::Namespace:
+  case NestedNameSpecifier::NamespaceAlias:
+    return false;
+  }
+
+  llvm_unreachable("unknown nested name specifier kind");
+}
+
 /// \brief Build a C++ typeid expression with a type operand.
 ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
                                 SourceLocation TypeidLoc,
@@ -351,9 +380,8 @@
       RequireCompleteType(TypeidLoc, T, diag::err_incomplete_typeid))
     return ExprError();
 
-  return Owned(new (Context) CXXTypeidExpr(TypeInfoType.withConst(),
-                                           Operand,
-                                           SourceRange(TypeidLoc, RParenLoc)));
+  return new (Context) CXXTypeidExpr(TypeInfoType.withConst(), Operand,
+                                     SourceRange(TypeidLoc, RParenLoc));
 }
 
 /// \brief Build a C++ typeid expression with an expression operand.
@@ -365,7 +393,7 @@
     if (E->getType()->isPlaceholderType()) {
       ExprResult result = CheckPlaceholderExpr(E);
       if (result.isInvalid()) return ExprError();
-      E = result.take();
+      E = result.get();
     }
 
     QualType T = E->getType();
@@ -386,7 +414,7 @@
         // and recheck the subexpression.
         ExprResult Result = TransformToPotentiallyEvaluated(E);
         if (Result.isInvalid()) return ExprError();
-        E = Result.take();
+        E = Result.get();
 
         // We require a vtable to query the type at run time.
         MarkVTableUsed(TypeidLoc, RecordD);
@@ -402,13 +430,12 @@
     QualType UnqualT = Context.getUnqualifiedArrayType(T, Quals);
     if (!Context.hasSameType(T, UnqualT)) {
       T = UnqualT;
-      E = ImpCastExprToType(E, UnqualT, CK_NoOp, E->getValueKind()).take();
+      E = ImpCastExprToType(E, UnqualT, CK_NoOp, E->getValueKind()).get();
     }
   }
 
-  return Owned(new (Context) CXXTypeidExpr(TypeInfoType.withConst(),
-                                           E,
-                                           SourceRange(TypeidLoc, RParenLoc)));
+  return new (Context) CXXTypeidExpr(TypeInfoType.withConst(), E,
+                                     SourceRange(TypeidLoc, RParenLoc));
 }
 
 /// ActOnCXXTypeidOfType - Parse typeid( type-id ) or typeid (expression);
@@ -426,7 +453,7 @@
     CXXTypeInfoDecl = R.getAsSingle<RecordDecl>();
     // Microsoft's typeinfo doesn't have type_info in std but in the global
     // namespace if _HAS_EXCEPTIONS is defined to 0. See PR13153.
-    if (!CXXTypeInfoDecl && LangOpts.MicrosoftMode) {
+    if (!CXXTypeInfoDecl && LangOpts.MSVCCompat) {
       LookupQualifiedName(R, Context.getTranslationUnitDecl());
       CXXTypeInfoDecl = R.getAsSingle<RecordDecl>();
     }
@@ -442,7 +469,7 @@
 
   if (isType) {
     // The operand is a type; handle it as such.
-    TypeSourceInfo *TInfo = 0;
+    TypeSourceInfo *TInfo = nullptr;
     QualType T = GetTypeFromParser(ParsedType::getFromOpaquePtr(TyOrExpr),
                                    &TInfo);
     if (T.isNull())
@@ -474,9 +501,8 @@
     }
   }
 
-  return Owned(new (Context) CXXUuidofExpr(TypeInfoType.withConst(),
-                                           Operand,
-                                           SourceRange(TypeidLoc, RParenLoc)));
+  return new (Context) CXXUuidofExpr(TypeInfoType.withConst(), Operand,
+                                     SourceRange(TypeidLoc, RParenLoc));
 }
 
 /// \brief Build a Microsoft __uuidof expression with an expression operand.
@@ -495,9 +521,8 @@
     }
   }
 
-  return Owned(new (Context) CXXUuidofExpr(TypeInfoType.withConst(),
-                                           E,
-                                           SourceRange(TypeidLoc, RParenLoc)));
+  return new (Context) CXXUuidofExpr(TypeInfoType.withConst(), E,
+                                     SourceRange(TypeidLoc, RParenLoc));
 }
 
 /// ActOnCXXUuidof - Parse __uuidof( type-id ) or __uuidof (expression);
@@ -518,7 +543,7 @@
 
   if (isType) {
     // The operand is a type; handle it as such.
-    TypeSourceInfo *TInfo = 0;
+    TypeSourceInfo *TInfo = nullptr;
     QualType T = GetTypeFromParser(ParsedType::getFromOpaquePtr(TyOrExpr),
                                    &TInfo);
     if (T.isNull())
@@ -539,14 +564,14 @@
 Sema::ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind) {
   assert((Kind == tok::kw_true || Kind == tok::kw_false) &&
          "Unknown C++ Boolean value!");
-  return Owned(new (Context) CXXBoolLiteralExpr(Kind == tok::kw_true,
-                                                Context.BoolTy, OpLoc));
+  return new (Context)
+      CXXBoolLiteralExpr(Kind == tok::kw_true, Context.BoolTy, OpLoc);
 }
 
 /// ActOnCXXNullPtrLiteral - Parse 'nullptr'.
 ExprResult
 Sema::ActOnCXXNullPtrLiteral(SourceLocation Loc) {
-  return Owned(new (Context) CXXNullPtrLiteralExpr(Context.NullPtrTy, Loc));
+  return new (Context) CXXNullPtrLiteralExpr(Context.NullPtrTy, Loc);
 }
 
 /// ActOnCXXThrow - Parse throw expressions.
@@ -593,16 +618,19 @@
   if (!getLangOpts().CXXExceptions &&
       !getSourceManager().isInSystemHeader(OpLoc))
     Diag(OpLoc, diag::err_exceptions_disabled) << "throw";
-  
+
+  if (getCurScope() && getCurScope()->isOpenMPSimdDirectiveScope())
+    Diag(OpLoc, diag::err_omp_simd_region_cannot_use_stmt) << "throw";
+
   if (Ex && !Ex->isTypeDependent()) {
     ExprResult ExRes = CheckCXXThrowOperand(OpLoc, Ex, IsThrownVarInScope);
     if (ExRes.isInvalid())
       return ExprError();
-    Ex = ExRes.take();
+    Ex = ExRes.get();
   }
   
-  return Owned(new (Context) CXXThrowExpr(Ex, Context.VoidTy, OpLoc,
-                                          IsThrownVarInScope));
+  return new (Context)
+      CXXThrowExpr(Ex, Context.VoidTy, OpLoc, IsThrownVarInScope);
 }
 
 /// CheckCXXThrowOperand - Validate the operand of a throw.
@@ -616,12 +644,12 @@
   //   or "pointer to function returning T", [...]
   if (E->getType().hasQualifiers())
     E = ImpCastExprToType(E, E->getType().getUnqualifiedType(), CK_NoOp,
-                          E->getValueKind()).take();
+                          E->getValueKind()).get();
 
   ExprResult Res = DefaultFunctionArrayConversion(E);
   if (Res.isInvalid())
     return ExprError();
-  E = Res.take();
+  E = Res.get();
 
   //   If the type of the exception would be an incomplete type or a pointer
   //   to an incomplete type other than (cv) void the program is ill-formed.
@@ -657,24 +685,24 @@
   //       operation from the operand to the exception object (15.1) can be 
   //       omitted by constructing the automatic object directly into the 
   //       exception object
-  const VarDecl *NRVOVariable = 0;
+  const VarDecl *NRVOVariable = nullptr;
   if (IsThrownVarInScope)
     NRVOVariable = getCopyElisionCandidate(QualType(), E, false);
-  
+
   InitializedEntity Entity =
       InitializedEntity::InitializeException(ThrowLoc, E->getType(),
-                                             /*NRVO=*/NRVOVariable != 0);
+                                             /*NRVO=*/NRVOVariable != nullptr);
   Res = PerformMoveOrCopyInitialization(Entity, NRVOVariable,
                                         QualType(), E,
                                         IsThrownVarInScope);
   if (Res.isInvalid())
     return ExprError();
-  E = Res.take();
+  E = Res.get();
 
   // If the exception has class type, we need additional handling.
   const RecordType *RecordTy = Ty->getAs<RecordType>();
   if (!RecordTy)
-    return Owned(E);
+    return E;
   CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
 
   // If we are throwing a polymorphic class type or pointer thereof,
@@ -683,22 +711,22 @@
 
   // If a pointer is thrown, the referenced object will not be destroyed.
   if (isPointer)
-    return Owned(E);
+    return E;
 
   // If the class has a destructor, we must be able to call it.
   if (RD->hasIrrelevantDestructor())
-    return Owned(E);
+    return E;
 
   CXXDestructorDecl *Destructor = LookupDestructor(RD);
   if (!Destructor)
-    return Owned(E);
+    return E;
 
   MarkFunctionReferenced(E->getExprLoc(), Destructor);
   CheckDestructorAccess(E->getExprLoc(), Destructor,
                         PDiag(diag::err_access_dtor_exception) << Ty);
   if (DiagnoseUseOfDecl(Destructor, E->getExprLoc()))
     return ExprError();
-  return Owned(E);
+  return E;
 }
 
 QualType Sema::getCurrentThisType() {
@@ -708,7 +736,20 @@
     if (method && method->isInstance())
       ThisTy = method->getThisType(Context);
   }
-  
+  if (ThisTy.isNull()) {
+    if (isGenericLambdaCallOperatorSpecialization(CurContext) &&
+        CurContext->getParent()->getParent()->isRecord()) {
+      // This is a generic lambda call operator that is being instantiated
+      // within a default initializer - so use the enclosing class as 'this'.
+      // There is no enclosing member function to retrieve the 'this' pointer
+      // from.
+      QualType ClassTy = Context.getTypeDeclType(
+          cast<CXXRecordDecl>(CurContext->getParent()->getParent()));
+      // There are no cv-qualifiers for 'this' within default initializers, 
+      // per [expr.prim.general]p4.
+      return Context.getPointerType(ClassTy);
+    }
+  }
   return ThisTy;
 }
 
@@ -720,8 +761,8 @@
 {
   if (!Enabled || !ContextDecl)
     return;
-  
-  CXXRecordDecl *Record = 0;
+
+  CXXRecordDecl *Record = nullptr;
   if (ClassTemplateDecl *Template = dyn_cast<ClassTemplateDecl>(ContextDecl))
     Record = Template->getTemplatedDecl();
   else
@@ -744,9 +785,9 @@
 static Expr *captureThis(ASTContext &Context, RecordDecl *RD,
                          QualType ThisTy, SourceLocation Loc) {
   FieldDecl *Field
-    = FieldDecl::Create(Context, RD, Loc, Loc, 0, ThisTy,
+    = FieldDecl::Create(Context, RD, Loc, Loc, nullptr, ThisTy,
                         Context.getTrivialTypeSourceInfo(ThisTy, Loc),
-                        0, false, ICIS_NoInit);
+                        nullptr, false, ICIS_NoInit);
   Field->setImplicit(true);
   Field->setAccess(AS_private);
   RD->addDecl(Field);
@@ -801,7 +842,7 @@
   for (unsigned idx = MaxFunctionScopesIndex; NumClosures; 
       --idx, --NumClosures) {
     CapturingScopeInfo *CSI = cast<CapturingScopeInfo>(FunctionScopes[idx]);
-    Expr *ThisExpr = 0;
+    Expr *ThisExpr = nullptr;
     QualType ThisTy = getCurrentThisType();
     if (LambdaScopeInfo *LSI = dyn_cast<LambdaScopeInfo>(CSI))
       // For lambda expressions, build a field and an initializing expression.
@@ -825,7 +866,7 @@
   if (ThisTy.isNull()) return Diag(Loc, diag::err_invalid_this_use);
 
   CheckCXXThisCapture(Loc);
-  return Owned(new (Context) CXXThisExpr(Loc, ThisTy, /*isImplicit=*/false));
+  return new (Context) CXXThisExpr(Loc, ThisTy, /*isImplicit=*/false);
 }
 
 bool Sema::isThisOutsideMemberFunctionBody(QualType BaseType) {
@@ -869,10 +910,8 @@
   SourceLocation TyBeginLoc = TInfo->getTypeLoc().getBeginLoc();
 
   if (Ty->isDependentType() || CallExpr::hasAnyTypeDependentArguments(Exprs)) {
-    return Owned(CXXUnresolvedConstructExpr::Create(Context, TInfo,
-                                                    LParenLoc,
-                                                    Exprs,
-                                                    RParenLoc));
+    return CXXUnresolvedConstructExpr::Create(Context, TInfo, LParenLoc, Exprs,
+                                              RParenLoc);
   }
 
   bool ListInitialization = LParenLoc.isInvalid();
@@ -928,9 +967,9 @@
     // want, since it will be treated as an initializer list in further
     // processing. Explicitly insert a cast here.
     QualType ResultType = Result.get()->getType();
-    Result = Owned(CXXFunctionalCastExpr::Create(
+    Result = CXXFunctionalCastExpr::Create(
         Context, ResultType, Expr::getValueKindForType(TInfo->getType()), TInfo,
-        CK_NoOp, Result.take(), /*Path=*/ 0, LParenLoc, RParenLoc));
+        CK_NoOp, Result.get(), /*Path=*/nullptr, LParenLoc, RParenLoc);
   }
 
   // FIXME: Improve AST representation?
@@ -1016,7 +1055,7 @@
                   Declarator &D, Expr *Initializer) {
   bool TypeContainsAuto = D.getDeclSpec().containsPlaceholderType();
 
-  Expr *ArraySize = 0;
+  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) {
@@ -1054,12 +1093,12 @@
             Array.NumElts
              = CheckConvertedConstantExpression(NumElts, Context.getSizeType(), Value,
                                                 CCEK_NewExpr)
-                 .take();
+                 .get();
           } else {
             Array.NumElts
-              = VerifyIntegerConstantExpression(NumElts, 0,
+              = VerifyIntegerConstantExpression(NumElts, nullptr,
                                                 diag::err_new_array_nonconst)
-                  .take();
+                  .get();
           }
           if (!Array.NumElts)
             return ExprError();
@@ -1068,7 +1107,7 @@
     }
   }
 
-  TypeSourceInfo *TInfo = GetTypeForDeclarator(D, /*Scope=*/0);
+  TypeSourceInfo *TInfo = GetTypeForDeclarator(D, /*Scope=*/nullptr);
   QualType AllocType = TInfo->getType();
   if (D.isInvalidType())
     return ExprError();
@@ -1145,22 +1184,15 @@
     NumInits = List->getNumExprs();
   }
 
-  // Determine whether we've already built the initializer.
-  bool HaveCompleteInit = false;
-  if (Initializer && isa<CXXConstructExpr>(Initializer) &&
-      !isa<CXXTemporaryObjectExpr>(Initializer))
-    HaveCompleteInit = true;
-  else if (Initializer && isa<ImplicitValueInitExpr>(Initializer))
-    HaveCompleteInit = true;
-
-  // C++11 [decl.spec.auto]p6. Deduce the type which 'auto' stands in for.
+  // C++11 [dcl.spec.auto]p6. Deduce the type which 'auto' stands in for.
   if (TypeMayContainAuto && AllocType->isUndeducedType()) {
     if (initStyle == CXXNewExpr::NoInit || NumInits == 0)
       return ExprError(Diag(StartLoc, diag::err_auto_new_requires_ctor_arg)
                        << AllocType << TypeRange);
-    if (initStyle == CXXNewExpr::ListInit)
+    if (initStyle == CXXNewExpr::ListInit ||
+        (NumInits == 1 && isa<InitListExpr>(Inits[0])))
       return ExprError(Diag(Inits[0]->getLocStart(),
-                            diag::err_auto_new_requires_parens)
+                            diag::err_auto_new_list_init)
                        << AllocType << TypeRange);
     if (NumInits > 1) {
       Expr *FirstBad = Inits[1];
@@ -1194,7 +1226,8 @@
   if (CheckAllocatedType(AllocType, TypeRange.getBegin(), TypeRange))
     return ExprError();
 
-  if (initStyle == CXXNewExpr::ListInit && isStdInitializerList(AllocType, 0)) {
+  if (initStyle == CXXNewExpr::ListInit &&
+      isStdInitializerList(AllocType, nullptr)) {
     Diag(AllocTypeInfo->getTypeLoc().getBeginLoc(),
          diag::warn_dangling_std_initializer_list)
         << /*at end of FE*/0 << Inits[0]->getSourceRange();
@@ -1213,7 +1246,7 @@
   if (ArraySize && ArraySize->getType()->isNonOverloadPlaceholderType()) {
     ExprResult result = CheckPlaceholderExpr(ArraySize);
     if (result.isInvalid()) return ExprError();
-    ArraySize = result.take();
+    ArraySize = result.get();
   }
   // C++98 5.3.4p6: "The expression in a direct-new-declarator shall have
   //   integral or enumeration type with a non-negative value."
@@ -1225,9 +1258,8 @@
   if (ArraySize && !ArraySize->isTypeDependent()) {
     ExprResult ConvertedSize;
     if (getLangOpts().CPlusPlus1y) {
-      unsigned IntWidth = Context.getTargetInfo().getIntWidth();
-      assert(IntWidth && "Builtin type of size 0?");
-      llvm::APSInt Value(IntWidth);
+      assert(Context.getTargetInfo().getIntWidth() && "Builtin type of size 0?");
+
       ConvertedSize = PerformImplicitConversion(ArraySize, Context.getSizeType(),
 						AA_Converting);
 
@@ -1245,43 +1277,43 @@
         SizeConvertDiagnoser(Expr *ArraySize)
             : ICEConvertDiagnoser(/*AllowScopedEnumerations*/false, false, false),
               ArraySize(ArraySize) {}
-  
-        virtual SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
-                                                     QualType T) {
+
+        SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
+                                             QualType T) override {
           return S.Diag(Loc, diag::err_array_size_not_integral)
                    << S.getLangOpts().CPlusPlus11 << T;
         }
-  
-        virtual SemaDiagnosticBuilder diagnoseIncomplete(
-            Sema &S, SourceLocation Loc, QualType T) {
+
+        SemaDiagnosticBuilder diagnoseIncomplete(
+            Sema &S, SourceLocation Loc, QualType T) override {
           return S.Diag(Loc, diag::err_array_size_incomplete_type)
                    << T << ArraySize->getSourceRange();
         }
-  
-        virtual SemaDiagnosticBuilder diagnoseExplicitConv(
-            Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) {
+
+        SemaDiagnosticBuilder diagnoseExplicitConv(
+            Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override {
           return S.Diag(Loc, diag::err_array_size_explicit_conversion) << T << ConvTy;
         }
-  
-        virtual SemaDiagnosticBuilder noteExplicitConv(
-            Sema &S, CXXConversionDecl *Conv, QualType ConvTy) {
+
+        SemaDiagnosticBuilder noteExplicitConv(
+            Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override {
           return S.Diag(Conv->getLocation(), diag::note_array_size_conversion)
                    << ConvTy->isEnumeralType() << ConvTy;
         }
-  
-        virtual SemaDiagnosticBuilder diagnoseAmbiguous(
-            Sema &S, SourceLocation Loc, QualType T) {
+
+        SemaDiagnosticBuilder diagnoseAmbiguous(
+            Sema &S, SourceLocation Loc, QualType T) override {
           return S.Diag(Loc, diag::err_array_size_ambiguous_conversion) << T;
         }
-  
-        virtual SemaDiagnosticBuilder noteAmbiguous(
-            Sema &S, CXXConversionDecl *Conv, QualType ConvTy) {
+
+        SemaDiagnosticBuilder noteAmbiguous(
+            Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override {
           return S.Diag(Conv->getLocation(), diag::note_array_size_conversion)
                    << ConvTy->isEnumeralType() << ConvTy;
         }
 
         virtual SemaDiagnosticBuilder diagnoseConversion(
-            Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) {
+            Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override {
           return S.Diag(Loc,
                         S.getLangOpts().CPlusPlus11
                           ? diag::warn_cxx98_compat_array_size_conversion
@@ -1296,7 +1328,7 @@
     if (ConvertedSize.isInvalid())
       return ExprError();
 
-    ArraySize = ConvertedSize.take();
+    ArraySize = ConvertedSize.get();
     QualType SizeType = ArraySize->getType();
 
     if (!SizeType->isIntegralOrUnscopedEnumerationType())
@@ -1359,8 +1391,8 @@
     // be signed, larger than size_t, whatever.
   }
 
-  FunctionDecl *OperatorNew = 0;
-  FunctionDecl *OperatorDelete = 0;
+  FunctionDecl *OperatorNew = nullptr;
+  FunctionDecl *OperatorDelete = nullptr;
 
   if (!AllocType->isDependentType() &&
       !Expr::hasAnyTypeDependentArguments(PlacementArgs) &&
@@ -1379,12 +1411,14 @@
 
   SmallVector<Expr *, 8> AllPlaceArgs;
   if (OperatorNew) {
-    // Add default arguments, if any.
     const FunctionProtoType *Proto =
-      OperatorNew->getType()->getAs<FunctionProtoType>();
-    VariadicCallType CallType =
-      Proto->isVariadic() ? VariadicFunction : VariadicDoesNotApply;
+        OperatorNew->getType()->getAs<FunctionProtoType>();
+    VariadicCallType CallType = Proto->isVariadic() ? VariadicFunction
+                                                    : VariadicDoesNotApply;
 
+    // We've already converted the placement args, just fill in any default
+    // arguments. Skip the first parameter because we don't have a corresponding
+    // argument.
     if (GatherArgumentsForCall(PlacementLParen, OperatorNew, Proto, 1,
                                PlacementArgs, AllPlaceArgs, CallType))
       return ExprError();
@@ -1392,6 +1426,7 @@
     if (!AllPlaceArgs.empty())
       PlacementArgs = AllPlaceArgs;
 
+    // FIXME: This is wrong: PlacementArgs misses out the first (size) argument.
     DiagnoseSentinelCalls(OperatorNew, PlacementLParen, PlacementArgs);
 
     // FIXME: Missing call to CheckFunctionCall or equivalent
@@ -1438,8 +1473,7 @@
   // do it now.
   if (!AllocType->isDependentType() &&
       !Expr::hasAnyTypeDependentArguments(
-        llvm::makeArrayRef(Inits, NumInits)) &&
-      !HaveCompleteInit) {
+          llvm::makeArrayRef(Inits, NumInits))) {
     // C++11 [expr.new]p15:
     //   A new-expression that creates an object of type T initializes that
     //   object as follows:
@@ -1469,9 +1503,9 @@
     // we don't want the initialized object to be destructed.
     if (CXXBindTemporaryExpr *Binder =
             dyn_cast_or_null<CXXBindTemporaryExpr>(FullInit.get()))
-      FullInit = Owned(Binder->getSubExpr());
+      FullInit = Binder->getSubExpr();
 
-    Initializer = FullInit.take();
+    Initializer = FullInit.get();
   }
 
   // Mark the new and delete operators as referenced.
@@ -1504,13 +1538,11 @@
     }
   }
 
-  return Owned(new (Context) CXXNewExpr(Context, UseGlobal, OperatorNew,
-                                        OperatorDelete,
-                                        UsualArrayDeleteWantsSize,
-                                        PlacementArgs, TypeIdParens,
-                                        ArraySize, initStyle, Initializer,
-                                        ResultType, AllocTypeInfo,
-                                        Range, DirectInitRange));
+  return new (Context)
+      CXXNewExpr(Context, UseGlobal, OperatorNew, OperatorDelete,
+                 UsualArrayDeleteWantsSize, PlacementArgs, TypeIdParens,
+                 ArraySize, initStyle, Initializer, ResultType, AllocTypeInfo,
+                 Range, DirectInitRange);
 }
 
 /// \brief Checks that a type is suitable as the allocated type
@@ -1623,7 +1655,7 @@
     // Didn't find a member overload. Look for a global one.
     DeclareGlobalNewDelete();
     DeclContext *TUDecl = Context.getTranslationUnitDecl();
-    bool FallbackEnabled = IsArray && Context.getLangOpts().MicrosoftMode;
+    bool FallbackEnabled = IsArray && Context.getLangOpts().MSVCCompat;
     if (FindAllocationOverload(StartLoc, Range, NewName, AllocArgs, TUDecl,
                                /*AllowMissing=*/FallbackEnabled, OperatorNew,
                                /*Diagnose=*/!FallbackEnabled)) {
@@ -1645,15 +1677,10 @@
   // We don't need an operator delete if we're running under
   // -fno-exceptions.
   if (!getLangOpts().Exceptions) {
-    OperatorDelete = 0;
+    OperatorDelete = nullptr;
     return false;
   }
 
-  // FindAllocationOverload can change the passed in arguments, so we need to
-  // copy them back.
-  if (!PlaceArgs.empty())
-    std::copy(AllocArgs.begin() + 1, AllocArgs.end(), PlaceArgs.data());
-
   // C++ [expr.new]p19:
   //
   //   If the new-expression begins with a unary :: operator, the
@@ -1708,8 +1735,8 @@
 
       SmallVector<QualType, 4> ArgTypes;
       ArgTypes.push_back(Context.VoidPtrTy);
-      for (unsigned I = 1, N = Proto->getNumArgs(); I < N; ++I)
-        ArgTypes.push_back(Proto->getArgType(I));
+      for (unsigned I = 1, N = Proto->getNumParams(); I < N; ++I)
+        ArgTypes.push_back(Proto->getParamType(I));
 
       FunctionProtoType::ExtProtoInfo EPI;
       EPI.Variadic = Proto->isVariadic();
@@ -1721,13 +1748,14 @@
     for (LookupResult::iterator D = FoundDelete.begin(),
                              DEnd = FoundDelete.end();
          D != DEnd; ++D) {
-      FunctionDecl *Fn = 0;
+      FunctionDecl *Fn = nullptr;
       if (FunctionTemplateDecl *FnTmpl
             = dyn_cast<FunctionTemplateDecl>((*D)->getUnderlyingDecl())) {
         // Perform template argument deduction to try to match the
         // expected function type.
         TemplateDeductionInfo Info(StartLoc);
-        if (DeduceTemplateArguments(FnTmpl, 0, ExpectedFunctionType, Fn, Info))
+        if (DeduceTemplateArguments(FnTmpl, nullptr, ExpectedFunctionType, Fn,
+                                    Info))
           continue;
       } else
         Fn = cast<FunctionDecl>((*D)->getUnderlyingDecl());
@@ -1763,7 +1791,7 @@
       else
         Matches.erase(Matches.begin() + 1);
       assert(Matches[0].second->getNumParams() == 2 &&
-             "found an unexpected uusal deallocation function");
+             "found an unexpected usual deallocation function");
     }
   }
 
@@ -1797,8 +1825,22 @@
   return false;
 }
 
-/// FindAllocationOverload - Find an fitting overload for the allocation
-/// function in the specified scope.
+/// \brief Find an fitting overload for the allocation function
+/// in the specified scope.
+///
+/// \param StartLoc The location of the 'new' token.
+/// \param Range The range of the placement arguments.
+/// \param Name The name of the function ('operator new' or 'operator new[]').
+/// \param Args The placement arguments specified.
+/// \param Ctx The scope in which we should search; either a class scope or the
+///        translation unit.
+/// \param AllowMissing If \c true, report an error if we can't find any
+///        allocation functions. Otherwise, succeed but don't fill in \p
+///        Operator.
+/// \param Operator Filled in with the found allocation function. Unchanged if
+///        no allocation function was found.
+/// \param Diagnose If \c true, issue errors if the allocation function is not
+///        usable.
 bool Sema::FindAllocationOverload(SourceLocation StartLoc, SourceRange Range,
                                   DeclarationName Name, MultiExprArg Args,
                                   DeclContext *Ctx,
@@ -1818,7 +1860,7 @@
 
   R.suppressDiagnostics();
 
-  OverloadCandidateSet Candidates(StartLoc);
+  OverloadCandidateSet Candidates(StartLoc, OverloadCandidateSet::CSK_Normal);
   for (LookupResult::iterator Alloc = R.begin(), AllocEnd = R.end();
        Alloc != AllocEnd; ++Alloc) {
     // Even member operator new/delete are implicitly treated as
@@ -1827,7 +1869,7 @@
 
     if (FunctionTemplateDecl *FnTemplate = dyn_cast<FunctionTemplateDecl>(D)) {
       AddTemplateOverloadCandidate(FnTemplate, Alloc.getPair(),
-                                   /*ExplicitTemplateArgs=*/0,
+                                   /*ExplicitTemplateArgs=*/nullptr,
                                    Args, Candidates,
                                    /*SuppressUserConversions=*/false);
       continue;
@@ -1844,33 +1886,11 @@
   case OR_Success: {
     // Got one!
     FunctionDecl *FnDecl = Best->Function;
-    MarkFunctionReferenced(StartLoc, FnDecl);
-    // The first argument is size_t, and the first parameter must be size_t,
-    // too. This is checked on declaration and can be assumed. (It can't be
-    // asserted on, though, since invalid decls are left in there.)
-    // Watch out for variadic allocator function.
-    unsigned NumArgsInFnDecl = FnDecl->getNumParams();
-    for (unsigned i = 0; (i < Args.size() && i < NumArgsInFnDecl); ++i) {
-      InitializedEntity Entity = InitializedEntity::InitializeParameter(Context,
-                                                       FnDecl->getParamDecl(i));
-
-      if (!Diagnose && !CanPerformCopyInitialization(Entity, Owned(Args[i])))
-        return true;
-
-      ExprResult Result
-        = PerformCopyInitialization(Entity, SourceLocation(), Owned(Args[i]));
-      if (Result.isInvalid())
-        return true;
-
-      Args[i] = Result.takeAs<Expr>();
-    }
-
-    Operator = FnDecl;
-
     if (CheckAllocationAccess(StartLoc, Range, R.getNamingClass(),
                               Best->FoundDecl, Diagnose) == AR_inaccessible)
       return true;
 
+    Operator = FnDecl;
     return false;
   }
 
@@ -1970,7 +1990,7 @@
                                         getOrCreateStdNamespace(),
                                         SourceLocation(), SourceLocation(),
                                       &PP.getIdentifierTable().get("bad_alloc"),
-                                        0);
+                                        nullptr);
     getStdBadAlloc()->setImplicit(true);
   }
 
@@ -2031,8 +2051,7 @@
         if (InitialParam1Type == Param1 &&
             (NumParams == 1 || InitialParam2Type == Param2)) {
           if (AddMallocAttr && !Func->hasAttr<MallocAttr>())
-            Func->addAttr(::new (Context) MallocAttr(SourceLocation(),
-                                                     Context));
+            Func->addAttr(MallocAttr::CreateImplicit(Context));
           // Make the function visible to name lookup, even if we found it in
           // an unimported module. It either is an implicitly-declared global
           // allocation function, or is suppressing that function.
@@ -2043,18 +2062,16 @@
     }
   }
 
+  FunctionProtoType::ExtProtoInfo EPI;
+
   QualType BadAllocType;
   bool HasBadAllocExceptionSpec
     = (Name.getCXXOverloadedOperator() == OO_New ||
        Name.getCXXOverloadedOperator() == OO_Array_New);
-  if (HasBadAllocExceptionSpec && !getLangOpts().CPlusPlus11) {
-    assert(StdBadAlloc && "Must have std::bad_alloc declared");
-    BadAllocType = Context.getTypeDeclType(getStdBadAlloc());
-  }
-
-  FunctionProtoType::ExtProtoInfo EPI;
   if (HasBadAllocExceptionSpec) {
     if (!getLangOpts().CPlusPlus11) {
+      BadAllocType = Context.getTypeDeclType(getStdBadAlloc());
+      assert(StdBadAlloc && "Must have std::bad_alloc declared");
       EPI.ExceptionSpecType = EST_Dynamic;
       EPI.NumExceptions = 1;
       EPI.Exceptions = &BadAllocType;
@@ -2071,24 +2088,24 @@
   FunctionDecl *Alloc =
     FunctionDecl::Create(Context, GlobalCtx, SourceLocation(),
                          SourceLocation(), Name,
-                         FnType, /*TInfo=*/0, SC_None, false, true);
+                         FnType, /*TInfo=*/nullptr, SC_None, false, true);
   Alloc->setImplicit();
 
   if (AddMallocAttr)
-    Alloc->addAttr(::new (Context) MallocAttr(SourceLocation(), Context));
+    Alloc->addAttr(MallocAttr::CreateImplicit(Context));
 
   ParmVarDecl *ParamDecls[2];
-  for (unsigned I = 0; I != NumParams; ++I)
+  for (unsigned I = 0; I != NumParams; ++I) {
     ParamDecls[I] = ParmVarDecl::Create(Context, Alloc, SourceLocation(),
-                                        SourceLocation(), 0,
-                                        Params[I], /*TInfo=*/0,
-                                        SC_None, 0);
+                                        SourceLocation(), nullptr,
+                                        Params[I], /*TInfo=*/nullptr,
+                                        SC_None, nullptr);
+    ParamDecls[I]->setImplicit();
+  }
   Alloc->setParams(ArrayRef<ParmVarDecl*>(ParamDecls, NumParams));
 
-  // FIXME: Also add this declaration to the IdentifierResolver, but
-  // make sure it is at the end of the chain to coincide with the
-  // global scope.
   Context.getTranslationUnitDecl()->addDecl(Alloc);
+  IdResolver.tryAddTopLevelDecl(Alloc, Name);
 }
 
 FunctionDecl *Sema::FindUsualDeallocationFunction(SourceLocation StartLoc,
@@ -2125,7 +2142,7 @@
     else
       Matches.erase(Matches.begin() + 1);
     assert(Matches[0]->getNumParams() == NumArgs &&
-           "found an unexpected uusal deallocation function");
+           "found an unexpected usual deallocation function");
   }
 
   assert(Matches.size() == 1 &&
@@ -2206,8 +2223,7 @@
     return true;
   }
 
-  // Look for a global declaration.
-  Operator = FindUsualDeallocationFunction(StartLoc, true, Name);
+  Operator = nullptr;
   return false;
 }
 
@@ -2225,14 +2241,14 @@
   //
   // DR599 amends "pointer type" to "pointer to object type" in both cases.
 
-  ExprResult Ex = Owned(ExE);
-  FunctionDecl *OperatorDelete = 0;
+  ExprResult Ex = ExE;
+  FunctionDecl *OperatorDelete = nullptr;
   bool ArrayFormAsWritten = ArrayForm;
   bool UsualArrayDeleteWantsSize = false;
 
   if (!Ex.get()->isTypeDependent()) {
     // Perform lvalue-to-rvalue cast, if needed.
-    Ex = DefaultLvalueConversion(Ex.take());
+    Ex = DefaultLvalueConversion(Ex.get());
     if (Ex.isInvalid())
       return ExprError();
 
@@ -2242,7 +2258,7 @@
     public:
       DeleteConverter() : ContextualImplicitConverter(false, true) {}
 
-      bool match(QualType ConvType) {
+      bool match(QualType ConvType) override {
         // FIXME: If we have an operator T* and an operator void*, we must pick
         // the operator T*.
         if (const PointerType *ConvPtrType = ConvType->getAs<PointerType>())
@@ -2252,44 +2268,46 @@
       }
 
       SemaDiagnosticBuilder diagnoseNoMatch(Sema &S, SourceLocation Loc,
-                                            QualType T) {
+                                            QualType T) override {
         return S.Diag(Loc, diag::err_delete_operand) << T;
       }
 
       SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
-                                               QualType T) {
+                                               QualType T) override {
         return S.Diag(Loc, diag::err_delete_incomplete_class_type) << T;
       }
 
       SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
-                                                 QualType T, QualType ConvTy) {
+                                                 QualType T,
+                                                 QualType ConvTy) override {
         return S.Diag(Loc, diag::err_delete_explicit_conversion) << T << ConvTy;
       }
 
       SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
-                                             QualType ConvTy) {
+                                             QualType ConvTy) override {
         return S.Diag(Conv->getLocation(), diag::note_delete_conversion)
           << ConvTy;
       }
 
       SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
-                                              QualType T) {
+                                              QualType T) override {
         return S.Diag(Loc, diag::err_ambiguous_delete_operand) << T;
       }
 
       SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
-                                          QualType ConvTy) {
+                                          QualType ConvTy) override {
         return S.Diag(Conv->getLocation(), diag::note_delete_conversion)
           << ConvTy;
       }
 
       SemaDiagnosticBuilder diagnoseConversion(Sema &S, SourceLocation Loc,
-                                               QualType T, QualType ConvTy) {
+                                               QualType T,
+                                               QualType ConvTy) override {
         llvm_unreachable("conversion functions are permitted");
       }
     } Converter;
 
-    Ex = PerformContextualImplicitConversion(StartLoc, Ex.take(), Converter);
+    Ex = PerformContextualImplicitConversion(StartLoc, Ex.get(), Converter);
     if (Ex.isInvalid())
       return ExprError();
     Type = Ex.get()->getType();
@@ -2306,7 +2324,7 @@
                   diag::err_address_space_qualified_delete)
                << Pointee.getUnqualifiedType() << AddressSpace;
 
-    CXXRecordDecl *PointeeRD = 0;
+    CXXRecordDecl *PointeeRD = nullptr;
     if (Pointee->isVoidType() && !isSFINAEContext()) {
       // The C++ standard bans deleting a pointer to a non-object type, which
       // effectively bans deletion of "void*". However, most compilers support
@@ -2357,7 +2375,7 @@
 
         // Otherwise, the usual operator delete[] should be the
         // function we just found.
-        else if (isa<CXXMethodDecl>(OperatorDelete))
+        else if (OperatorDelete && isa<CXXMethodDecl>(OperatorDelete))
           UsualArrayDeleteWantsSize = (OperatorDelete->getNumParams() == 2);
       }
 
@@ -2414,10 +2432,9 @@
     }
   }
 
-  return Owned(new (Context) CXXDeleteExpr(Context.VoidTy, UseGlobal, ArrayForm,
-                                           ArrayFormAsWritten,
-                                           UsualArrayDeleteWantsSize,
-                                           OperatorDelete, Ex.take(), StartLoc));
+  return new (Context) CXXDeleteExpr(
+      Context.VoidTy, UseGlobal, ArrayForm, ArrayFormAsWritten,
+      UsualArrayDeleteWantsSize, OperatorDelete, Ex.get(), StartLoc);
 }
 
 /// \brief Check the use of the given variable as a C++ condition in an if,
@@ -2441,19 +2458,15 @@
                           diag::err_invalid_use_of_array_type)
                      << ConditionVar->getSourceRange());
 
-  ExprResult Condition =
-    Owned(DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
-                              SourceLocation(),
-                              ConditionVar,
-                              /*enclosing*/ false,
-                              ConditionVar->getLocation(),
-                              ConditionVar->getType().getNonReferenceType(),
-                              VK_LValue));
+  ExprResult Condition = DeclRefExpr::Create(
+      Context, NestedNameSpecifierLoc(), SourceLocation(), ConditionVar,
+      /*enclosing*/ false, ConditionVar->getLocation(),
+      ConditionVar->getType().getNonReferenceType(), VK_LValue);
 
   MarkDeclRefReferenced(cast<DeclRefExpr>(Condition.get()));
 
   if (ConvertToBoolean) {
-    Condition = CheckBooleanCondition(Condition.take(), StmtLoc);
+    Condition = CheckBooleanCondition(Condition.get(), StmtLoc);
     if (Condition.isInvalid())
       return ExprError();
   }
@@ -2538,15 +2551,15 @@
                              InitializedEntity::InitializeTemporary(Ty),
                              Constructor->getAccess());
 
-    ExprResult Result
-      = S.BuildCXXConstructExpr(CastLoc, Ty, cast<CXXConstructorDecl>(Method),
-                                ConstructorArgs, HadMultipleCandidates,
-                                /*ListInit*/ false, /*ZeroInit*/ false,
-                                CXXConstructExpr::CK_Complete, SourceRange());
+    ExprResult Result = S.BuildCXXConstructExpr(
+        CastLoc, Ty, cast<CXXConstructorDecl>(Method),
+        ConstructorArgs, HadMultipleCandidates,
+        /*ListInit*/ false, /*StdInitListInit*/ false, /*ZeroInit*/ false,
+        CXXConstructExpr::CK_Complete, SourceRange());
     if (Result.isInvalid())
       return ExprError();
 
-    return S.MaybeBindToTemporary(Result.takeAs<Expr>());
+    return S.MaybeBindToTemporary(Result.getAs<Expr>());
   }
 
   case CK_UserDefinedConversion: {
@@ -2559,13 +2572,11 @@
     if (Result.isInvalid())
       return ExprError();
     // Record usage of conversion in an implicit cast.
-    Result = S.Owned(ImplicitCastExpr::Create(S.Context,
-                                              Result.get()->getType(),
-                                              CK_UserDefinedConversion,
-                                              Result.get(), 0,
-                                              Result.get()->getValueKind()));
+    Result = ImplicitCastExpr::Create(S.Context, Result.get()->getType(),
+                                      CK_UserDefinedConversion, Result.get(),
+                                      nullptr, Result.get()->getValueKind());
 
-    S.CheckMemberOperatorAccess(CastLoc, From, /*arg*/ 0, FoundDecl);
+    S.CheckMemberOperatorAccess(CastLoc, From, /*arg*/ nullptr, FoundDecl);
 
     return S.MaybeBindToTemporary(Result.get());
   }
@@ -2588,7 +2599,7 @@
                                                Action, CCK);
     if (Res.isInvalid())
       return ExprError();
-    From = Res.take();
+    From = Res.get();
     break;
   }
 
@@ -2624,7 +2635,7 @@
                                     CCK);
         if (Res.isInvalid())
           return ExprError();
-        From = Res.take();
+        From = Res.get();
       }
 
       ExprResult CastArg
@@ -2639,7 +2650,7 @@
       if (CastArg.isInvalid())
         return ExprError();
 
-      From = CastArg.take();
+      From = CastArg.get();
 
       return PerformImplicitConversion(From, ToType, ICS.UserDefined.After,
                                        AA_Converting, CCK);
@@ -2659,7 +2670,7 @@
   }
 
   // Everything went well.
-  return Owned(From);
+  return From;
 }
 
 /// PerformImplicitConversion - Perform an implicit conversion of the
@@ -2689,20 +2700,17 @@
                                   From, /*FIXME:ConstructLoc*/SourceLocation(),
                                   ConstructorArgs))
         return ExprError();
-      return BuildCXXConstructExpr(/*FIXME:ConstructLoc*/SourceLocation(),
-                                   ToType, SCS.CopyConstructor,
-                                   ConstructorArgs,
-                                   /*HadMultipleCandidates*/ false,
-                                   /*ListInit*/ false, /*ZeroInit*/ false,
-                                   CXXConstructExpr::CK_Complete,
-                                   SourceRange());
+      return BuildCXXConstructExpr(
+          /*FIXME:ConstructLoc*/ SourceLocation(), ToType, SCS.CopyConstructor,
+          ConstructorArgs, /*HadMultipleCandidates*/ false,
+          /*ListInit*/ false, /*StdInitListInit*/ false, /*ZeroInit*/ false,
+          CXXConstructExpr::CK_Complete, SourceRange());
     }
-    return BuildCXXConstructExpr(/*FIXME:ConstructLoc*/SourceLocation(),
-                                 ToType, SCS.CopyConstructor,
-                                 From, /*HadMultipleCandidates*/ false,
-                                 /*ListInit*/ false, /*ZeroInit*/ false,
-                                 CXXConstructExpr::CK_Complete,
-                                 SourceRange());
+    return BuildCXXConstructExpr(
+        /*FIXME:ConstructLoc*/ SourceLocation(), ToType, SCS.CopyConstructor,
+        From, /*HadMultipleCandidates*/ false,
+        /*ListInit*/ false, /*StdInitListInit*/ false, /*ZeroInit*/ false,
+        CXXConstructExpr::CK_Complete, SourceRange());
   }
 
   // Resolve overloaded function references.
@@ -2739,20 +2747,20 @@
     FromType = FromType.getUnqualifiedType();
     ExprResult FromRes = DefaultLvalueConversion(From);
     assert(!FromRes.isInvalid() && "Can't perform deduced conversion?!");
-    From = FromRes.take();
+    From = FromRes.get();
     break;
   }
 
   case ICK_Array_To_Pointer:
     FromType = Context.getArrayDecayedType(FromType);
     From = ImpCastExprToType(From, FromType, CK_ArrayToPointerDecay, 
-                             VK_RValue, /*BasePath=*/0, CCK).take();
+                             VK_RValue, /*BasePath=*/nullptr, CCK).get();
     break;
 
   case ICK_Function_To_Pointer:
     FromType = Context.getPointerType(FromType);
     From = ImpCastExprToType(From, FromType, CK_FunctionToPointerDecay, 
-                             VK_RValue, /*BasePath=*/0, CCK).take();
+                             VK_RValue, /*BasePath=*/nullptr, CCK).get();
     break;
 
   default:
@@ -2776,7 +2784,7 @@
       return ExprError();
 
     From = ImpCastExprToType(From, ToType, CK_NoOp, 
-                             VK_RValue, /*BasePath=*/0, CCK).take();
+                             VK_RValue, /*BasePath=*/nullptr, CCK).get();
     break;
 
   case ICK_Integral_Promotion:
@@ -2786,17 +2794,17 @@
              SCS.Second == ICK_Integral_Promotion &&
              "only enums with fixed underlying type can promote to bool");
       From = ImpCastExprToType(From, ToType, CK_IntegralToBoolean,
-                               VK_RValue, /*BasePath=*/0, CCK).take();
+                               VK_RValue, /*BasePath=*/nullptr, CCK).get();
     } else {
       From = ImpCastExprToType(From, ToType, CK_IntegralCast,
-                               VK_RValue, /*BasePath=*/0, CCK).take();
+                               VK_RValue, /*BasePath=*/nullptr, CCK).get();
     }
     break;
 
   case ICK_Floating_Promotion:
   case ICK_Floating_Conversion:
     From = ImpCastExprToType(From, ToType, CK_FloatingCast, 
-                             VK_RValue, /*BasePath=*/0, CCK).take();
+                             VK_RValue, /*BasePath=*/nullptr, CCK).get();
     break;
 
   case ICK_Complex_Promotion:
@@ -2815,22 +2823,22 @@
       CK = CK_IntegralComplexCast;
     }
     From = ImpCastExprToType(From, ToType, CK, 
-                             VK_RValue, /*BasePath=*/0, CCK).take();
+                             VK_RValue, /*BasePath=*/nullptr, CCK).get();
     break;
   }
 
   case ICK_Floating_Integral:
     if (ToType->isRealFloatingType())
       From = ImpCastExprToType(From, ToType, CK_IntegralToFloating, 
-                               VK_RValue, /*BasePath=*/0, CCK).take();
+                               VK_RValue, /*BasePath=*/nullptr, CCK).get();
     else
       From = ImpCastExprToType(From, ToType, CK_FloatingToIntegral, 
-                               VK_RValue, /*BasePath=*/0, CCK).take();
+                               VK_RValue, /*BasePath=*/nullptr, CCK).get();
     break;
 
   case ICK_Compatible_Conversion:
       From = ImpCastExprToType(From, ToType, CK_NoOp, 
-                               VK_RValue, /*BasePath=*/0, CCK).take();
+                               VK_RValue, /*BasePath=*/nullptr, CCK).get();
     break;
 
   case ICK_Writeback_Conversion:
@@ -2875,12 +2883,12 @@
     if (Kind == CK_BlockPointerToObjCPointerCast) {
       ExprResult E = From;
       (void) PrepareCastToObjCObjectPointer(E);
-      From = E.take();
+      From = E.get();
     }
     if (getLangOpts().ObjCAutoRefCount)
       CheckObjCARCConversion(SourceRange(), ToType, From, CCK);
     From = ImpCastExprToType(From, ToType, Kind, VK_RValue, &BasePath, CCK)
-             .take();
+             .get();
     break;
   }
 
@@ -2892,20 +2900,20 @@
     if (CheckExceptionSpecCompatibility(From, ToType))
       return ExprError();
     From = ImpCastExprToType(From, ToType, Kind, VK_RValue, &BasePath, CCK)
-             .take();
+             .get();
     break;
   }
 
   case ICK_Boolean_Conversion:
     // Perform half-to-boolean conversion via float.
     if (From->getType()->isHalfType()) {
-      From = ImpCastExprToType(From, Context.FloatTy, CK_FloatingCast).take();
+      From = ImpCastExprToType(From, Context.FloatTy, CK_FloatingCast).get();
       FromType = Context.FloatTy;
     }
 
     From = ImpCastExprToType(From, Context.BoolTy,
                              ScalarTypeToBooleanCastKind(FromType), 
-                             VK_RValue, /*BasePath=*/0, CCK).take();
+                             VK_RValue, /*BasePath=*/nullptr, CCK).get();
     break;
 
   case ICK_Derived_To_Base: {
@@ -2920,18 +2928,18 @@
 
     From = ImpCastExprToType(From, ToType.getNonReferenceType(),
                       CK_DerivedToBase, From->getValueKind(),
-                      &BasePath, CCK).take();
+                      &BasePath, CCK).get();
     break;
   }
 
   case ICK_Vector_Conversion:
     From = ImpCastExprToType(From, ToType, CK_BitCast, 
-                             VK_RValue, /*BasePath=*/0, CCK).take();
+                             VK_RValue, /*BasePath=*/nullptr, CCK).get();
     break;
 
   case ICK_Vector_Splat:
     From = ImpCastExprToType(From, ToType, CK_VectorSplat, 
-                             VK_RValue, /*BasePath=*/0, CCK).take();
+                             VK_RValue, /*BasePath=*/nullptr, CCK).get();
     break;
 
   case ICK_Complex_Real:
@@ -2945,16 +2953,16 @@
         // do nothing
       } else if (From->getType()->isRealFloatingType()) {
         From = ImpCastExprToType(From, ElType,
-                isFloatingComplex ? CK_FloatingCast : CK_FloatingToIntegral).take();
+                isFloatingComplex ? CK_FloatingCast : CK_FloatingToIntegral).get();
       } else {
         assert(From->getType()->isIntegerType());
         From = ImpCastExprToType(From, ElType,
-                isFloatingComplex ? CK_IntegralToFloating : CK_IntegralCast).take();
+                isFloatingComplex ? CK_IntegralToFloating : CK_IntegralCast).get();
       }
       // y -> _Complex y
       From = ImpCastExprToType(From, ToType,
                    isFloatingComplex ? CK_FloatingRealToComplex
-                                     : CK_IntegralRealToComplex).take();
+                                     : CK_IntegralRealToComplex).get();
 
     // Case 2.  _Complex x -> y
     } else {
@@ -2968,7 +2976,7 @@
       From = ImpCastExprToType(From, ElType,
                    isFloatingComplex ? CK_FloatingComplexToReal
                                      : CK_IntegralComplexToReal, 
-                               VK_RValue, /*BasePath=*/0, CCK).take();
+                               VK_RValue, /*BasePath=*/nullptr, CCK).get();
 
       // x -> y
       if (Context.hasSameUnqualifiedType(ElType, ToType)) {
@@ -2976,29 +2984,29 @@
       } else if (ToType->isRealFloatingType()) {
         From = ImpCastExprToType(From, ToType,
                    isFloatingComplex ? CK_FloatingCast : CK_IntegralToFloating, 
-                                 VK_RValue, /*BasePath=*/0, CCK).take();
+                                 VK_RValue, /*BasePath=*/nullptr, CCK).get();
       } else {
         assert(ToType->isIntegerType());
         From = ImpCastExprToType(From, ToType,
                    isFloatingComplex ? CK_FloatingToIntegral : CK_IntegralCast, 
-                                 VK_RValue, /*BasePath=*/0, CCK).take();
+                                 VK_RValue, /*BasePath=*/nullptr, CCK).get();
       }
     }
     break;
   
   case ICK_Block_Pointer_Conversion: {
     From = ImpCastExprToType(From, ToType.getUnqualifiedType(), CK_BitCast,
-                             VK_RValue, /*BasePath=*/0, CCK).take();
+                             VK_RValue, /*BasePath=*/nullptr, CCK).get();
     break;
   }
       
   case ICK_TransparentUnionConversion: {
-    ExprResult FromRes = Owned(From);
+    ExprResult FromRes = From;
     Sema::AssignConvertType ConvTy =
       CheckTransparentUnionArgumentConstraints(ToType, FromRes);
     if (FromRes.isInvalid())
       return ExprError();
-    From = FromRes.take();
+    From = FromRes.get();
     assert ((ConvTy == Sema::Compatible) &&
             "Improper transparent union conversion");
     (void)ConvTy;
@@ -3008,7 +3016,7 @@
   case ICK_Zero_Event_Conversion:
     From = ImpCastExprToType(From, ToType,
                              CK_ZeroToOCLEvent,
-                             From->getValueKind()).take();
+                             From->getValueKind()).get();
     break;
 
   case ICK_Lvalue_To_Rvalue:
@@ -3030,12 +3038,15 @@
     ExprValueKind VK = ToType->isReferenceType() ?
                                   From->getValueKind() : VK_RValue;
     From = ImpCastExprToType(From, ToType.getNonLValueExprType(Context),
-                             CK_NoOp, VK, /*BasePath=*/0, CCK).take();
+                             CK_NoOp, VK, /*BasePath=*/nullptr, CCK).get();
 
     if (SCS.DeprecatedStringLiteralToCharPtr &&
-        !getLangOpts().WritableStrings)
-      Diag(From->getLocStart(), diag::warn_deprecated_string_literal_conversion)
+        !getLangOpts().WritableStrings) {
+      Diag(From->getLocStart(), getLangOpts().CPlusPlus11
+           ? diag::ext_deprecated_string_literal_conversion
+           : diag::warn_deprecated_string_literal_conversion)
         << ToType.getNonReferenceType();
+    }
 
     break;
   }
@@ -3050,22 +3061,10 @@
     assert(Context.hasSameType(
         ToAtomicType->castAs<AtomicType>()->getValueType(), From->getType()));
     From = ImpCastExprToType(From, ToAtomicType, CK_NonAtomicToAtomic,
-                             VK_RValue, 0, CCK).take();
+                             VK_RValue, nullptr, CCK).get();
   }
 
-  return Owned(From);
-}
-
-ExprResult Sema::ActOnUnaryTypeTrait(UnaryTypeTrait UTT,
-                                     SourceLocation KWLoc,
-                                     ParsedType Ty,
-                                     SourceLocation RParen) {
-  TypeSourceInfo *TSInfo;
-  QualType T = GetTypeFromParser(Ty, &TSInfo);
-
-  if (!TSInfo)
-    TSInfo = Context.getTrivialTypeSourceInfo(T);
-  return BuildUnaryTypeTrait(UTT, KWLoc, TSInfo, RParen);
+  return From;
 }
 
 /// \brief Check the completeness of a type in a unary type trait.
@@ -3074,8 +3073,7 @@
 /// it. If completing the type fails, a diagnostic is emitted and false
 /// returned. If completing the type succeeds or no completion was required,
 /// returns true.
-static bool CheckUnaryTypeTraitTypeCompleteness(Sema &S,
-                                                UnaryTypeTrait UTT,
+static bool CheckUnaryTypeTraitTypeCompleteness(Sema &S, TypeTrait UTT,
                                                 SourceLocation Loc,
                                                 QualType ArgTy) {
   // C++0x [meta.unary.prop]p3:
@@ -3088,6 +3086,7 @@
   // these class templates. We also try to follow any GCC documented behavior
   // in these expressions to ensure portability of standard libraries.
   switch (UTT) {
+  default: llvm_unreachable("not a UTT");
     // is_complete_type somewhat obviously cannot require a complete type.
   case UTT_IsCompleteType:
     // Fall-through
@@ -3140,6 +3139,8 @@
   case UTT_IsPolymorphic:
   case UTT_IsAbstract:
   case UTT_IsInterfaceClass:
+  case UTT_IsDestructible:
+  case UTT_IsNothrowDestructible:
     // Fall-through
 
   // These traits require a complete type.
@@ -3174,7 +3175,6 @@
     return !S.RequireCompleteType(
       Loc, ElTy, diag::err_incomplete_type_used_in_type_trait_expr);
   }
-  llvm_unreachable("Type trait not handled by switch");
 }
 
 static bool HasNoThrowOperator(const RecordType *RT, OverloadedOperatorKind Op,
@@ -3204,7 +3204,7 @@
         const FunctionProtoType *CPT =
           Operator->getType()->getAs<FunctionProtoType>();
         CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
-        if (!CPT || !CPT->isNothrow(Self.Context))
+        if (!CPT || !CPT->isNothrow(C))
           return false;
       }
     }
@@ -3213,12 +3213,13 @@
   return false;
 }
 
-static bool EvaluateUnaryTypeTrait(Sema &Self, UnaryTypeTrait UTT,
+static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT,
                                    SourceLocation KeyLoc, QualType T) {
   assert(!T->isDependentType() && "Cannot evaluate traits of dependent type");
 
   ASTContext &C = Self.Context;
   switch(UTT) {
+  default: llvm_unreachable("not a UTT");
     // Type trait expressions corresponding to the primary type category
     // predicates in C++0x [meta.unary.cat].
   case UTT_IsVoid:
@@ -3405,8 +3406,12 @@
       return RD->hasTrivialCopyAssignment() &&
              !RD->hasNonTrivialCopyAssignment();
     return false;
+  case UTT_IsDestructible:
+  case UTT_IsNothrowDestructible:
+    // FIXME: Implement UTT_IsDestructible and UTT_IsNothrowDestructible.
+    // For now, let's fall through.
   case UTT_HasTrivialDestructor:
-    // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
+    // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html
     //   If __is_pod (type) is true or type is a reference type
     //   then the trait is true, else if type is a cv class or union
     //   type (or array thereof) with a trivial destructor
@@ -3489,9 +3494,9 @@
           CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
           if (!CPT)
             return false;
-          // FIXME: check whether evaluating default arguments can throw.
+          // TODO: check whether evaluating default arguments can throw.
           // For now, we'll be conservative and assume that they can throw.
-          if (!CPT->isNothrow(Self.Context) || CPT->getNumArgs() > 1)
+          if (!CPT->isNothrow(Self.Context) || CPT->getNumParams() > 1)
             return false;
         }
       }
@@ -3500,7 +3505,7 @@
     }
     return false;
   case UTT_HasNothrowConstructor:
-    // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
+    // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html
     //   If __has_trivial_constructor (type) is true then the trait is
     //   true, else if type is a cv class or union type (or array
     //   thereof) with a default constructor that is known not to
@@ -3512,6 +3517,7 @@
           !RD->hasNonTrivialDefaultConstructor())
         return true;
 
+      bool FoundConstructor = false;
       DeclContext::lookup_const_result R = Self.LookupConstructors(RD);
       for (DeclContext::lookup_const_iterator Con = R.begin(),
            ConEnd = R.end(); Con != ConEnd; ++Con) {
@@ -3520,16 +3526,19 @@
           continue;
         CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con);
         if (Constructor->isDefaultConstructor()) {
+          FoundConstructor = true;
           const FunctionProtoType *CPT
               = Constructor->getType()->getAs<FunctionProtoType>();
           CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
           if (!CPT)
             return false;
-          // TODO: check whether evaluating default arguments can throw.
+          // FIXME: check whether evaluating default arguments can throw.
           // For now, we'll be conservative and assume that they can throw.
-          return CPT->isNothrow(Self.Context) && CPT->getNumArgs() == 0;
+          if (!CPT->isNothrow(Self.Context) || CPT->getNumParams() > 0)
+            return false;
         }
       }
+      return FoundConstructor;
     }
     return false;
   case UTT_HasVirtualDestructor:
@@ -3550,41 +3559,6 @@
     //   function call.
     return !T->isIncompleteType();
   }
-  llvm_unreachable("Type trait not covered by switch");
-}
-
-ExprResult Sema::BuildUnaryTypeTrait(UnaryTypeTrait UTT,
-                                     SourceLocation KWLoc,
-                                     TypeSourceInfo *TSInfo,
-                                     SourceLocation RParen) {
-  QualType T = TSInfo->getType();
-  if (!CheckUnaryTypeTraitTypeCompleteness(*this, UTT, KWLoc, T))
-    return ExprError();
-
-  bool Value = false;
-  if (!T->isDependentType())
-    Value = EvaluateUnaryTypeTrait(*this, UTT, KWLoc, T);
-
-  return Owned(new (Context) UnaryTypeTraitExpr(KWLoc, UTT, TSInfo, Value,
-                                                RParen, Context.BoolTy));
-}
-
-ExprResult Sema::ActOnBinaryTypeTrait(BinaryTypeTrait BTT,
-                                      SourceLocation KWLoc,
-                                      ParsedType LhsTy,
-                                      ParsedType RhsTy,
-                                      SourceLocation RParen) {
-  TypeSourceInfo *LhsTSInfo;
-  QualType LhsT = GetTypeFromParser(LhsTy, &LhsTSInfo);
-  if (!LhsTSInfo)
-    LhsTSInfo = Context.getTrivialTypeSourceInfo(LhsT);
-
-  TypeSourceInfo *RhsTSInfo;
-  QualType RhsT = GetTypeFromParser(RhsTy, &RhsTSInfo);
-  if (!RhsTSInfo)
-    RhsTSInfo = Context.getTrivialTypeSourceInfo(RhsT);
-
-  return BuildBinaryTypeTrait(BTT, KWLoc, LhsTSInfo, RhsTSInfo, RParen);
 }
 
 /// \brief Determine whether T has a non-trivial Objective-C lifetime in
@@ -3606,10 +3580,22 @@
   llvm_unreachable("Unknown ObjC lifetime qualifier");
 }
 
+static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT,
+                                    QualType RhsT, SourceLocation KeyLoc);
+
 static bool evaluateTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc,
                               ArrayRef<TypeSourceInfo *> Args,
                               SourceLocation RParenLoc) {
+  if (Kind <= UTT_Last)
+    return EvaluateUnaryTypeTrait(S, Kind, KWLoc, Args[0]->getType());
+
+  if (Kind <= BTT_Last)
+    return EvaluateBinaryTypeTrait(S, Kind, Args[0]->getType(),
+                                   Args[1]->getType(), RParenLoc);
+
   switch (Kind) {
+  case clang::TT_IsConstructible:
+  case clang::TT_IsNothrowConstructible:
   case clang::TT_IsTriviallyConstructible: {
     // C++11 [meta.unary.prop]:
     //   is_trivially_constructible is defined as:
@@ -3624,11 +3610,7 @@
     //   variable t:
     //
     //     T t(create<Args>()...);
-    if (Args.empty()) {
-      S.Diag(KWLoc, diag::err_type_trait_arity)
-        << 1 << 1 << 1 << (int)Args.size();
-      return false;
-    }
+    assert(!Args.empty());
 
     // Precondition: T and all types in the parameter pack Args shall be
     // complete types, (possibly cv-qualified) void, or arrays of
@@ -3647,6 +3629,11 @@
     if (Args[0]->getType()->isIncompleteType())
       return false;
 
+    // Make sure the first argument is not an abstract type.
+    CXXRecordDecl *RD = Args[0]->getType()->getAsCXXRecordDecl();
+    if (RD && RD->isAbstract())
+      return false;
+
     SmallVector<OpaqueValueExpr, 2> OpaqueArgExprs;
     SmallVector<Expr *, 2> ArgExprs;
     ArgExprs.reserve(Args.size() - 1);
@@ -3672,21 +3659,33 @@
     InitializationSequence Init(S, To, InitKind, ArgExprs);
     if (Init.Failed())
       return false;
-    
+
     ExprResult Result = Init.Perform(S, To, InitKind, ArgExprs);
     if (Result.isInvalid() || SFINAE.hasErrorOccurred())
       return false;
 
-    // Under Objective-C ARC, if the destination has non-trivial Objective-C
-    // lifetime, this is a non-trivial construction.
-    if (S.getLangOpts().ObjCAutoRefCount &&
-        hasNontrivialObjCLifetime(Args[0]->getType().getNonReferenceType()))
-      return false;
+    if (Kind == clang::TT_IsConstructible)
+      return true;
 
-    // The initialization succeeded; now make sure there are no non-trivial
-    // calls.
-    return !Result.get()->hasNonTrivialCall(S.Context);
+    if (Kind == clang::TT_IsNothrowConstructible)
+      return S.canThrow(Result.get()) == CT_Cannot;
+
+    if (Kind == clang::TT_IsTriviallyConstructible) {
+      // Under Objective-C ARC, if the destination has non-trivial Objective-C
+      // lifetime, this is a non-trivial construction.
+      if (S.getLangOpts().ObjCAutoRefCount &&
+          hasNontrivialObjCLifetime(Args[0]->getType().getNonReferenceType()))
+        return false;
+
+      // The initialization succeeded; now make sure there are no non-trivial
+      // calls.
+      return !Result.get()->hasNonTrivialCall(S.Context);
+    }
+
+    llvm_unreachable("unhandled type trait");
+    return false;
   }
+    default: llvm_unreachable("not a TT");
   }
   
   return false;
@@ -3695,6 +3694,12 @@
 ExprResult Sema::BuildTypeTrait(TypeTrait Kind, SourceLocation KWLoc, 
                                 ArrayRef<TypeSourceInfo *> Args, 
                                 SourceLocation RParenLoc) {
+  QualType ResultType = Context.getLogicalOperationType();
+
+  if (Kind <= UTT_Last && !CheckUnaryTypeTraitTypeCompleteness(
+                               *this, Kind, KWLoc, Args[0]->getType()))
+    return ExprError();
+
   bool Dependent = false;
   for (unsigned I = 0, N = Args.size(); I != N; ++I) {
     if (Args[I]->getType()->isDependentType()) {
@@ -3702,17 +3707,17 @@
       break;
     }
   }
-  
-  bool Value = false;
+
+  bool Result = false;
   if (!Dependent)
-    Value = evaluateTypeTrait(*this, Kind, KWLoc, Args, RParenLoc);
-  
-  return TypeTraitExpr::Create(Context, Context.BoolTy, KWLoc, Kind,
-                               Args, RParenLoc, Value);
+    Result = evaluateTypeTrait(*this, Kind, KWLoc, Args, RParenLoc);
+
+  return TypeTraitExpr::Create(Context, ResultType, KWLoc, Kind, Args,
+                               RParenLoc, Result);
 }
 
-ExprResult Sema::ActOnTypeTrait(TypeTrait Kind, SourceLocation KWLoc, 
-                                ArrayRef<ParsedType> Args, 
+ExprResult Sema::ActOnTypeTrait(TypeTrait Kind, SourceLocation KWLoc,
+                                ArrayRef<ParsedType> Args,
                                 SourceLocation RParenLoc) {
   SmallVector<TypeSourceInfo *, 4> ConvertedArgs;
   ConvertedArgs.reserve(Args.size());
@@ -3725,13 +3730,12 @@
     
     ConvertedArgs.push_back(TInfo);    
   }
-  
+
   return BuildTypeTrait(Kind, KWLoc, ConvertedArgs, RParenLoc);
 }
 
-static bool EvaluateBinaryTypeTrait(Sema &Self, BinaryTypeTrait BTT,
-                                    QualType LhsT, QualType RhsT,
-                                    SourceLocation KeyLoc) {
+static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT,
+                                    QualType RhsT, SourceLocation KeyLoc) {
   assert(!LhsT->isDependentType() && !RhsT->isDependentType() &&
          "Cannot evaluate traits of dependent types");
 
@@ -3834,7 +3838,8 @@
     ExprResult Result = Init.Perform(Self, To, Kind, FromPtr);
     return !Result.isInvalid() && !SFINAE.hasErrorOccurred();
   }
-      
+
+  case BTT_IsNothrowAssignable:
   case BTT_IsTriviallyAssignable: {
     // C++11 [meta.unary.prop]p3:
     //   is_trivially_assignable is defined as:
@@ -3876,58 +3881,32 @@
     EnterExpressionEvaluationContext Unevaluated(Self, Sema::Unevaluated);
     Sema::SFINAETrap SFINAE(Self, /*AccessCheckingSFINAE=*/true);
     Sema::ContextRAII TUContext(Self, Self.Context.getTranslationUnitDecl());
-    ExprResult Result = Self.BuildBinOp(/*S=*/0, KeyLoc, BO_Assign, &Lhs, &Rhs);
+    ExprResult Result = Self.BuildBinOp(/*S=*/nullptr, KeyLoc, BO_Assign, &Lhs,
+                                        &Rhs);
     if (Result.isInvalid() || SFINAE.hasErrorOccurred())
       return false;
 
-    // Under Objective-C ARC, if the destination has non-trivial Objective-C
-    // lifetime, this is a non-trivial assignment.
-    if (Self.getLangOpts().ObjCAutoRefCount &&
-        hasNontrivialObjCLifetime(LhsT.getNonReferenceType()))
-      return false;
+    if (BTT == BTT_IsNothrowAssignable)
+      return Self.canThrow(Result.get()) == CT_Cannot;
 
-    return !Result.get()->hasNonTrivialCall(Self.Context);
+    if (BTT == BTT_IsTriviallyAssignable) {
+      // Under Objective-C ARC, if the destination has non-trivial Objective-C
+      // lifetime, this is a non-trivial assignment.
+      if (Self.getLangOpts().ObjCAutoRefCount &&
+          hasNontrivialObjCLifetime(LhsT.getNonReferenceType()))
+        return false;
+
+      return !Result.get()->hasNonTrivialCall(Self.Context);
+    }
+
+    llvm_unreachable("unhandled type trait");
+    return false;
   }
+    default: llvm_unreachable("not a BTT");
   }
   llvm_unreachable("Unknown type trait or not implemented");
 }
 
-ExprResult Sema::BuildBinaryTypeTrait(BinaryTypeTrait BTT,
-                                      SourceLocation KWLoc,
-                                      TypeSourceInfo *LhsTSInfo,
-                                      TypeSourceInfo *RhsTSInfo,
-                                      SourceLocation RParen) {
-  QualType LhsT = LhsTSInfo->getType();
-  QualType RhsT = RhsTSInfo->getType();
-
-  if (BTT == BTT_TypeCompatible) {
-    if (getLangOpts().CPlusPlus) {
-      Diag(KWLoc, diag::err_types_compatible_p_in_cplusplus)
-        << SourceRange(KWLoc, RParen);
-      return ExprError();
-    }
-  }
-
-  bool Value = false;
-  if (!LhsT->isDependentType() && !RhsT->isDependentType())
-    Value = EvaluateBinaryTypeTrait(*this, BTT, LhsT, RhsT, KWLoc);
-
-  // Select trait result type.
-  QualType ResultType;
-  switch (BTT) {
-  case BTT_IsBaseOf:       ResultType = Context.BoolTy; break;
-  case BTT_IsConvertible:  ResultType = Context.BoolTy; break;
-  case BTT_IsSame:         ResultType = Context.BoolTy; break;
-  case BTT_TypeCompatible: ResultType = Context.IntTy; break;
-  case BTT_IsConvertibleTo: ResultType = Context.BoolTy; break;
-  case BTT_IsTriviallyAssignable: ResultType = Context.BoolTy;
-  }
-
-  return Owned(new (Context) BinaryTypeTraitExpr(KWLoc, BTT, LhsTSInfo,
-                                                 RhsTSInfo, Value, RParen,
-                                                 ResultType));
-}
-
 ExprResult Sema::ActOnArrayTypeTrait(ArrayTypeTrait ATT,
                                      SourceLocation KWLoc,
                                      ParsedType Ty,
@@ -4013,9 +3992,8 @@
   // returns 'size_t'. On Windows, the primary platform for the Embarcadero
   // compiler, there is no difference. On several other platforms this is an
   // important distinction.
-  return Owned(new (Context) ArrayTypeTraitExpr(KWLoc, ATT, TSInfo, Value,
-                                                DimExpr, RParen,
-                                                Context.getSizeType()));
+  return new (Context) ArrayTypeTraitExpr(KWLoc, ATT, TSInfo, Value, DimExpr,
+                                          RParen, Context.getSizeType());
 }
 
 ExprResult Sema::ActOnExpressionTrait(ExpressionTrait ET,
@@ -4048,13 +4026,13 @@
   } else if (Queried->getType()->isPlaceholderType()) {
     ExprResult PE = CheckPlaceholderExpr(Queried);
     if (PE.isInvalid()) return ExprError();
-    return BuildExpressionTrait(ET, KWLoc, PE.take(), RParen);
+    return BuildExpressionTrait(ET, KWLoc, PE.get(), RParen);
   }
 
   bool Value = EvaluateExpressionTrait(ET, Queried);
 
-  return Owned(new (Context) ExpressionTraitExpr(KWLoc, ET, Queried, Value,
-                                                 RParen, Context.BoolTy));
+  return new (Context)
+      ExpressionTraitExpr(KWLoc, ET, Queried, Value, RParen, Context.BoolTy);
 }
 
 QualType Sema::CheckPointerToMemberOperands(ExprResult &LHS, ExprResult &RHS,
@@ -4067,12 +4045,12 @@
 
   // The LHS undergoes lvalue conversions if this is ->*.
   if (isIndirect) {
-    LHS = DefaultLvalueConversion(LHS.take());
+    LHS = DefaultLvalueConversion(LHS.get());
     if (LHS.isInvalid()) return QualType();
   }
 
   // The RHS always undergoes lvalue conversions.
-  RHS = DefaultLvalueConversion(RHS.take());
+  RHS = DefaultLvalueConversion(RHS.get());
   if (RHS.isInvalid()) return QualType();
 
   const char *OpSpelling = isIndirect ? "->*" : ".*";
@@ -4118,23 +4096,24 @@
                             OpSpelling, (int)isIndirect)) {
       return QualType();
     }
-    CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
-                       /*DetectVirtual=*/false);
-    // FIXME: Would it be useful to print full ambiguity paths, or is that
-    // overkill?
-    if (!IsDerivedFrom(LHSType, Class, Paths) ||
-        Paths.isAmbiguous(Context.getCanonicalType(Class))) {
+
+    if (!IsDerivedFrom(LHSType, Class)) {
       Diag(Loc, diag::err_bad_memptr_lhs) << OpSpelling
         << (int)isIndirect << LHS.get()->getType();
       return QualType();
     }
+
+    CXXCastPath BasePath;
+    if (CheckDerivedToBaseConversion(LHSType, Class, Loc,
+                                     SourceRange(LHS.get()->getLocStart(),
+                                                 RHS.get()->getLocEnd()),
+                                     &BasePath))
+      return QualType();
+
     // Cast LHS to type of use.
     QualType UseType = isIndirect ? Context.getPointerType(Class) : Class;
     ExprValueKind VK = isIndirect ? VK_RValue : LHS.get()->getValueKind();
-
-    CXXCastPath BasePath;
-    BuildBasePathArray(Paths, BasePath);
-    LHS = ImpCastExprToType(LHS.take(), UseType, CK_DerivedToBase, VK,
+    LHS = ImpCastExprToType(LHS.get(), UseType, CK_DerivedToBase, VK,
                             &BasePath);
   }
 
@@ -4297,7 +4276,8 @@
 static bool FindConditionalOverload(Sema &Self, ExprResult &LHS, ExprResult &RHS,
                                     SourceLocation QuestionLoc) {
   Expr *Args[2] = { LHS.get(), RHS.get() };
-  OverloadCandidateSet CandidateSet(QuestionLoc);
+  OverloadCandidateSet CandidateSet(QuestionLoc,
+                                    OverloadCandidateSet::CSK_Operator);
   Self.AddBuiltinOperatorCandidates(OO_Conditional, QuestionLoc, Args,
                                     CandidateSet);
 
@@ -4356,7 +4336,7 @@
   InitializedEntity Entity = InitializedEntity::InitializeTemporary(T);
   InitializationKind Kind = InitializationKind::CreateCopy(E.get()->getLocStart(),
                                                            SourceLocation());
-  Expr *Arg = E.take();
+  Expr *Arg = E.get();
   InitializationSequence InitSeq(Self, Entity, Kind, Arg);
   ExprResult Result = InitSeq.Perform(Self, Entity, Kind, Arg);
   if (Result.isInvalid())
@@ -4380,7 +4360,7 @@
   // C++11 [expr.cond]p1
   //   The first expression is contextually converted to bool.
   if (!Cond.get()->isTypeDependent()) {
-    ExprResult CondRes = CheckCXXBooleanCondition(Cond.take());
+    ExprResult CondRes = CheckCXXBooleanCondition(Cond.get());
     if (CondRes.isInvalid())
       return QualType();
     Cond = CondRes;
@@ -4401,42 +4381,21 @@
   bool LVoid = LTy->isVoidType();
   bool RVoid = RTy->isVoidType();
   if (LVoid || RVoid) {
-    //   ... then the [l2r] conversions are performed on the second and third
-    //   operands ...
-    LHS = DefaultFunctionArrayLvalueConversion(LHS.take());
-    RHS = DefaultFunctionArrayLvalueConversion(RHS.take());
-    if (LHS.isInvalid() || RHS.isInvalid())
-      return QualType();
-
-    // Finish off the lvalue-to-rvalue conversion by copy-initializing a
-    // temporary if necessary. DefaultFunctionArrayLvalueConversion doesn't
-    // do this part for us.
-    ExprResult &NonVoid = LVoid ? RHS : LHS;
-    if (NonVoid.get()->getType()->isRecordType() &&
-        NonVoid.get()->isGLValue()) {
-      if (RequireNonAbstractType(QuestionLoc, NonVoid.get()->getType(),
-                             diag::err_allocation_of_abstract_type))
-        return QualType();
-      InitializedEntity Entity =
-          InitializedEntity::InitializeTemporary(NonVoid.get()->getType());
-      NonVoid = PerformCopyInitialization(Entity, SourceLocation(), NonVoid);
-      if (NonVoid.isInvalid())
-        return QualType();
+    //   ... one of the following shall hold:
+    //   -- The second or the third operand (but not both) is a (possibly
+    //      parenthesized) throw-expression; the result is of the type
+    //      and value category of the other.
+    bool LThrow = isa<CXXThrowExpr>(LHS.get()->IgnoreParenImpCasts());
+    bool RThrow = isa<CXXThrowExpr>(RHS.get()->IgnoreParenImpCasts());
+    if (LThrow != RThrow) {
+      Expr *NonThrow = LThrow ? RHS.get() : LHS.get();
+      VK = NonThrow->getValueKind();
+      // DR (no number yet): the result is a bit-field if the
+      // non-throw-expression operand is a bit-field.
+      OK = NonThrow->getObjectKind();
+      return NonThrow->getType();
     }
 
-    LTy = LHS.get()->getType();
-    RTy = RHS.get()->getType();
-
-    //   ... and one of the following shall hold:
-    //   -- The second or the third operand (but not both) is a throw-
-    //      expression; the result is of the type of the other and is a prvalue.
-    bool LThrow = isa<CXXThrowExpr>(LHS.get()->IgnoreParenCasts());
-    bool RThrow = isa<CXXThrowExpr>(RHS.get()->IgnoreParenCasts());
-    if (LThrow && !RThrow)
-      return RTy;
-    if (RThrow && !LThrow)
-      return LTy;
-
     //   -- Both the second and third operands have type void; the result is of
     //      type void and is a prvalue.
     if (LVoid && RVoid)
@@ -4457,7 +4416,6 @@
   //   those operands to the type of the other.
   if (!Context.hasSameType(LTy, RTy) &&
       (LTy->isRecordType() || RTy->isRecordType())) {
-    ImplicitConversionSequence ICSLeftToRight, ICSRightToLeft;
     // These return true if a single direction is already ambiguous.
     QualType L2RType, R2LType;
     bool HaveL2R, HaveR2L;
@@ -4502,11 +4460,11 @@
     Qualifiers LCVR = Qualifiers::fromCVRMask(LTy.getCVRQualifiers());
     Qualifiers RCVR = Qualifiers::fromCVRMask(RTy.getCVRQualifiers());
     if (RCVR.isStrictSupersetOf(LCVR)) {
-      LHS = ImpCastExprToType(LHS.take(), RTy, CK_NoOp, LVK);
+      LHS = ImpCastExprToType(LHS.get(), RTy, CK_NoOp, LVK);
       LTy = LHS.get()->getType();
     }
     else if (LCVR.isStrictSupersetOf(RCVR)) {
-      RHS = ImpCastExprToType(RHS.take(), LTy, CK_NoOp, RVK);
+      RHS = ImpCastExprToType(RHS.get(), LTy, CK_NoOp, RVK);
       RTy = RHS.get()->getType();
     }
   }
@@ -4543,8 +4501,8 @@
   // C++11 [expr.cond]p6
   //   Lvalue-to-rvalue, array-to-pointer, and function-to-pointer standard
   //   conversions are performed on the second and third operands.
-  LHS = DefaultFunctionArrayLvalueConversion(LHS.take());
-  RHS = DefaultFunctionArrayLvalueConversion(RHS.take());
+  LHS = DefaultFunctionArrayLvalueConversion(LHS.get());
+  RHS = DefaultFunctionArrayLvalueConversion(RHS.get());
   if (LHS.isInvalid() || RHS.isInvalid())
     return QualType();
   LTy = LHS.get()->getType();
@@ -4611,7 +4569,8 @@
   //      operand. The result is of the common type.
   bool NonStandardCompositeType = false;
   QualType Composite = FindCompositePointerType(QuestionLoc, LHS, RHS,
-                              isSFINAEContext()? 0 : &NonStandardCompositeType);
+                                 isSFINAEContext() ? nullptr
+                                                   : &NonStandardCompositeType);
   if (!Composite.isNull()) {
     if (NonStandardCompositeType)
       Diag(QuestionLoc,
@@ -4670,12 +4629,12 @@
       !T2->isAnyPointerType() && !T2->isMemberPointerType()) {
     if (T1->isNullPtrType() &&
         E2->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
-      E2 = ImpCastExprToType(E2, T1, CK_NullToPointer).take();
+      E2 = ImpCastExprToType(E2, T1, CK_NullToPointer).get();
       return T1;
     }
     if (T2->isNullPtrType() &&
         E1->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
-      E1 = ImpCastExprToType(E1, T2, CK_NullToPointer).take();
+      E1 = ImpCastExprToType(E1, T2, CK_NullToPointer).get();
       return T2;
     }
     return QualType();
@@ -4683,16 +4642,16 @@
 
   if (E1->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
     if (T2->isMemberPointerType())
-      E1 = ImpCastExprToType(E1, T2, CK_NullToMemberPointer).take();
+      E1 = ImpCastExprToType(E1, T2, CK_NullToMemberPointer).get();
     else
-      E1 = ImpCastExprToType(E1, T2, CK_NullToPointer).take();
+      E1 = ImpCastExprToType(E1, T2, CK_NullToPointer).get();
     return T2;
   }
   if (E2->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
     if (T1->isMemberPointerType())
-      E2 = ImpCastExprToType(E2, T1, CK_NullToMemberPointer).take();
+      E2 = ImpCastExprToType(E2, T1, CK_NullToMemberPointer).get();
     else
-      E2 = ImpCastExprToType(E2, T1, CK_NullToPointer).take();
+      E2 = ImpCastExprToType(E2, T1, CK_NullToPointer).get();
     return T1;
   }
 
@@ -4735,7 +4694,7 @@
 
       QualifierUnion.push_back(
                  Composite1.getCVRQualifiers() | Composite2.getCVRQualifiers());
-      MemberOfClass.push_back(std::make_pair((const Type *)0, (const Type *)0));
+      MemberOfClass.push_back(std::make_pair(nullptr, nullptr));
       continue;
     }
 
@@ -4830,14 +4789,14 @@
       = E1ToC1.Perform(*this, Entity1, Kind, E1);
     if (E1Result.isInvalid())
       return QualType();
-    E1 = E1Result.takeAs<Expr>();
+    E1 = E1Result.getAs<Expr>();
 
     // Convert E2 to Composite1
     ExprResult E2Result
       = E2ToC1.Perform(*this, Entity1, Kind, E2);
     if (E2Result.isInvalid())
       return QualType();
-    E2 = E2Result.takeAs<Expr>();
+    E2 = E2Result.getAs<Expr>();
 
     return Composite1;
   }
@@ -4855,14 +4814,14 @@
     = E1ToC2.Perform(*this, Entity2, Kind, E1);
   if (E1Result.isInvalid())
     return QualType();
-  E1 = E1Result.takeAs<Expr>();
+  E1 = E1Result.getAs<Expr>();
 
   // Convert E2 to Composite2
   ExprResult E2Result
     = E2ToC2.Perform(*this, Entity2, Kind, E2);
   if (E2Result.isInvalid())
     return QualType();
-  E2 = E2Result.takeAs<Expr>();
+  E2 = E2Result.getAs<Expr>();
 
   return Composite2;
 }
@@ -4875,7 +4834,7 @@
 
   // If the result is a glvalue, we shouldn't bind it.
   if (!E->isRValue())
-    return Owned(E);
+    return E;
 
   // In ARC, calls that return a retainable type can return retained,
   // in which case we have to insert a consuming cast.
@@ -4918,13 +4877,13 @@
     // we don't want any extra casts here.
     } else if (isa<CastExpr>(E) &&
                isa<BlockExpr>(cast<CastExpr>(E)->getSubExpr())) {
-      return Owned(E);
+      return E;
 
     // For message sends and property references, we try to find an
     // actual method.  FIXME: we should infer retention by selector in
     // cases where we don't have an actual method.
     } else {
-      ObjCMethodDecl *D = 0;
+      ObjCMethodDecl *D = nullptr;
       if (ObjCMessageExpr *Send = dyn_cast<ObjCMessageExpr>(E)) {
         D = Send->getMethodDecl();
       } else if (ObjCBoxedExpr *BoxedExpr = dyn_cast<ObjCBoxedExpr>(E)) {
@@ -4943,28 +4902,28 @@
       // return an object.
       if (!ReturnsRetained &&
           D && D->getMethodFamily() == OMF_performSelector)
-        return Owned(E);
+        return E;
     }
 
     // Don't reclaim an object of Class type.
     if (!ReturnsRetained && E->getType()->isObjCARCImplicitlyUnretainedType())
-      return Owned(E);
+      return E;
 
     ExprNeedsCleanups = true;
 
     CastKind ck = (ReturnsRetained ? CK_ARCConsumeObject
                                    : CK_ARCReclaimReturnedObject);
-    return Owned(ImplicitCastExpr::Create(Context, E->getType(), ck, E, 0,
-                                          VK_RValue));
+    return ImplicitCastExpr::Create(Context, E->getType(), ck, E, nullptr,
+                                    VK_RValue);
   }
 
   if (!getLangOpts().CPlusPlus)
-    return Owned(E);
+    return E;
 
   // Search for the base element type (cf. ASTContext::getBaseElementType) with
   // a fast path for the common case that the type is directly a RecordType.
   const Type *T = Context.getCanonicalType(E->getType().getTypePtr());
-  const RecordType *RT = 0;
+  const RecordType *RT = nullptr;
   while (!RT) {
     switch (T->getTypeClass()) {
     case Type::Record:
@@ -4977,7 +4936,7 @@
       T = cast<ArrayType>(T)->getElementType().getTypePtr();
       break;
     default:
-      return Owned(E);
+      return E;
     }
   }
 
@@ -4985,10 +4944,10 @@
   // not processing a decltype expression.
   CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
   if (RD->isInvalidDecl() || RD->isDependentContext())
-    return Owned(E);
+    return E;
 
   bool IsDecltype = ExprEvalContexts.back().IsDecltype;
-  CXXDestructorDecl *Destructor = IsDecltype ? 0 : LookupDestructor(RD);
+  CXXDestructorDecl *Destructor = IsDecltype ? nullptr : LookupDestructor(RD);
 
   if (Destructor) {
     MarkFunctionReferenced(E->getExprLoc(), Destructor);
@@ -5000,7 +4959,7 @@
 
     // If destructor is trivial, we can avoid the extra copy.
     if (Destructor->isTrivial())
-      return Owned(E);
+      return E;
 
     // We need a cleanup, but we don't need to remember the temporary.
     ExprNeedsCleanups = true;
@@ -5012,7 +4971,7 @@
   if (IsDecltype)
     ExprEvalContexts.back().DelayedDecltypeBinds.push_back(Bind);
 
-  return Owned(Bind);
+  return Bind;
 }
 
 ExprResult
@@ -5020,11 +4979,11 @@
   if (SubExpr.isInvalid())
     return ExprError();
 
-  return Owned(MaybeCreateExprWithCleanups(SubExpr.take()));
+  return MaybeCreateExprWithCleanups(SubExpr.get());
 }
 
 Expr *Sema::MaybeCreateExprWithCleanups(Expr *SubExpr) {
-  assert(SubExpr && "sub expression can't be null!");
+  assert(SubExpr && "subexpression can't be null!");
 
   CleanupVarDeclMarking();
 
@@ -5045,7 +5004,7 @@
 }
 
 Stmt *Sema::MaybeCreateStmtWithCleanups(Stmt *SubStmt) {
-  assert(SubStmt && "sub statement can't be null!");
+  assert(SubStmt && "sub-statement can't be null!");
 
   CleanupVarDeclMarking();
 
@@ -5086,8 +5045,8 @@
     if (SubExpr.isInvalid())
       return ExprError();
     if (SubExpr.get() == PE->getSubExpr())
-      return Owned(E);
-    return ActOnParenExpr(PE->getLParen(), PE->getRParen(), SubExpr.take());
+      return E;
+    return ActOnParenExpr(PE->getLParen(), PE->getRParen(), SubExpr.get());
   }
   if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
     if (BO->getOpcode() == BO_Comma) {
@@ -5095,30 +5054,30 @@
       if (RHS.isInvalid())
         return ExprError();
       if (RHS.get() == BO->getRHS())
-        return Owned(E);
-      return Owned(new (Context) BinaryOperator(BO->getLHS(), RHS.take(),
-                                                BO_Comma, BO->getType(),
-                                                BO->getValueKind(),
-                                                BO->getObjectKind(),
-                                                BO->getOperatorLoc(),
-                                                BO->isFPContractable()));
+        return E;
+      return new (Context) BinaryOperator(
+          BO->getLHS(), RHS.get(), BO_Comma, BO->getType(), BO->getValueKind(),
+          BO->getObjectKind(), BO->getOperatorLoc(), BO->isFPContractable());
     }
   }
 
   CXXBindTemporaryExpr *TopBind = dyn_cast<CXXBindTemporaryExpr>(E);
-  if (TopBind)
-    E = TopBind->getSubExpr();
+  CallExpr *TopCall = TopBind ? dyn_cast<CallExpr>(TopBind->getSubExpr())
+                              : nullptr;
+  if (TopCall)
+    E = TopCall;
+  else
+    TopBind = nullptr;
 
   // Disable the special decltype handling now.
   ExprEvalContexts.back().IsDecltype = false;
 
   // In MS mode, don't perform any extra checking of call return types within a
   // decltype expression.
-  if (getLangOpts().MicrosoftMode)
-    return Owned(E);
+  if (getLangOpts().MSVCCompat)
+    return E;
 
   // Perform the semantic checks we delayed until this point.
-  CallExpr *TopCall = dyn_cast<CallExpr>(E);
   for (unsigned I = 0, N = ExprEvalContexts.back().DelayedDecltypeCalls.size();
        I != N; ++I) {
     CallExpr *Call = ExprEvalContexts.back().DelayedDecltypeCalls[I];
@@ -5159,12 +5118,12 @@
   }
 
   // Possibly strip off the top CXXBindTemporaryExpr.
-  return Owned(E);
+  return E;
 }
 
 /// Note a set of 'operator->' functions that were used for a member access.
 static void noteOperatorArrows(Sema &S,
-                               llvm::ArrayRef<FunctionDecl *> OperatorArrows) {
+                               ArrayRef<FunctionDecl *> OperatorArrows) {
   unsigned SkipStart = OperatorArrows.size(), SkipCount = 0;
   // FIXME: Make this configurable?
   unsigned Limit = 9;
@@ -5199,7 +5158,7 @@
 
   Result = CheckPlaceholderExpr(Base);
   if (Result.isInvalid()) return ExprError();
-  Base = Result.take();
+  Base = Result.get();
 
   QualType BaseType = Base->getType();
   MayBePseudoDestructor = false;
@@ -5213,7 +5172,7 @@
 
     ObjectType = ParsedType::make(BaseType);
     MayBePseudoDestructor = true;
-    return Owned(Base);
+    return Base;
   }
 
   // C++ [over.match.oper]p8:
@@ -5246,7 +5205,7 @@
           // separate note) instead of having the error reported back to here
           // and giving a diagnostic with a fixit attached to the error itself.
           (FirstIteration && CurFD && CurFD->isFunctionTemplateSpecialization())
-              ? 0
+              ? nullptr
               : &NoArrowOperatorFound);
       if (Result.isInvalid()) {
         if (NoArrowOperatorFound) {
@@ -5260,7 +5219,7 @@
           Diag(OpLoc, diag::err_typecheck_member_reference_arrow)
             << BaseType << Base->getSourceRange();
           CallExpr *CE = dyn_cast<CallExpr>(Base);
-          if (Decl *CD = (CE ? CE->getCalleeDecl() : 0)) {
+          if (Decl *CD = (CE ? CE->getCalleeDecl() : nullptr)) {
             Diag(CD->getLocStart(),
                  diag::note_member_reference_arrow_from_operator_arrow);
           }
@@ -5303,7 +5262,7 @@
   } else if (!BaseType->isRecordType()) {
     ObjectType = ParsedType();
     MayBePseudoDestructor = true;
-    return Owned(Base);
+    return Base;
   }
 
   // The object type must be complete (or dependent), or
@@ -5332,7 +5291,7 @@
     << isa<CXXPseudoDestructorExpr>(MemExpr)
     << FixItHint::CreateInsertion(ExpectedLParenLoc, "()");
 
-  return ActOnCallExpr(/*Scope*/ 0,
+  return ActOnCallExpr(/*Scope*/ nullptr,
                        MemExpr,
                        /*LPLoc*/ ExpectedLParenLoc,
                        None,
@@ -5344,7 +5303,7 @@
   if (Base->hasPlaceholderType()) {
     ExprResult result = S.CheckPlaceholderExpr(Base);
     if (result.isInvalid()) return true;
-    Base = result.take();
+    Base = result.get();
   }
   ObjectType = Base->getType();
 
@@ -5389,12 +5348,13 @@
 
   if (!ObjectType->isDependentType() && !ObjectType->isScalarType() &&
       !ObjectType->isVectorType()) {
-    if (getLangOpts().MicrosoftMode && ObjectType->isVoidType())
+    if (getLangOpts().MSVCCompat && ObjectType->isVoidType())
       Diag(OpLoc, diag::ext_pseudo_dtor_on_void) << Base->getSourceRange();
-    else
+    else {
       Diag(OpLoc, diag::err_pseudo_dtor_base_not_scalar)
         << ObjectType << Base->getSourceRange();
-    return ExprError();
+      return ExprError();
+    }
   }
 
   // C++ [expr.pseudo]p2:
@@ -5454,7 +5414,7 @@
         << ScopeTypeInfo->getTypeLoc().getLocalSourceRange();
 
       ScopeType = QualType();
-      ScopeTypeInfo = 0;
+      ScopeTypeInfo = nullptr;
     }
   }
 
@@ -5468,7 +5428,7 @@
                                             Destructed);
 
   if (HasTrailingLParen)
-    return Owned(Result);
+    return Result;
 
   return DiagnoseDtorReference(Destructed.getLocation(), Result);
 }
@@ -5506,7 +5466,7 @@
   // Convert the name of the type being destructed (following the ~) into a
   // type (with source-location information).
   QualType DestructedType;
-  TypeSourceInfo *DestructedTypeInfo = 0;
+  TypeSourceInfo *DestructedTypeInfo = nullptr;
   PseudoDestructorTypeStorage Destructed;
   if (SecondTypeName.getKind() == UnqualifiedId::IK_Identifier) {
     ParsedType T = getTypeName(*SecondTypeName.Identifier,
@@ -5561,7 +5521,7 @@
   }
 
   // Convert the name of the scope type (the type prior to '::') into a type.
-  TypeSourceInfo *ScopeTypeInfo = 0;
+  TypeSourceInfo *ScopeTypeInfo = nullptr;
   QualType ScopeType;
   if (FirstTypeName.getKind() == UnqualifiedId::IK_TemplateId ||
       FirstTypeName.Identifier) {
@@ -5630,7 +5590,7 @@
   PseudoDestructorTypeStorage Destructed(DestructedTypeInfo);
 
   return BuildPseudoDestructorExpr(Base, OpLoc, OpKind, CXXScopeSpec(),
-                                   0, SourceLocation(), TildeLoc,
+                                   nullptr, SourceLocation(), TildeLoc,
                                    Destructed, HasTrailingLParen);
 }
 
@@ -5663,22 +5623,21 @@
       return Exp;
     }
   }
-      
 
-  ExprResult Exp = PerformObjectArgumentInitialization(E, /*Qualifier=*/0,
+  ExprResult Exp = PerformObjectArgumentInitialization(E, /*Qualifier=*/nullptr,
                                           FoundDecl, Method);
   if (Exp.isInvalid())
     return true;
 
   MemberExpr *ME =
-      new (Context) MemberExpr(Exp.take(), /*IsArrow=*/false, Method,
+      new (Context) MemberExpr(Exp.get(), /*IsArrow=*/false, Method,
                                SourceLocation(), Context.BoundMemberTy,
                                VK_RValue, OK_Ordinary);
   if (HadMultipleCandidates)
     ME->setHadMultipleCandidates(true);
   MarkMemberReferenced(ME);
 
-  QualType ResultType = Method->getResultType();
+  QualType ResultType = Method->getReturnType();
   ExprValueKind VK = Expr::getValueKindForType(ResultType);
   ResultType = ResultType.getNonLValueExprType(Context);
 
@@ -5691,8 +5650,8 @@
 ExprResult Sema::BuildCXXNoexceptExpr(SourceLocation KeyLoc, Expr *Operand,
                                       SourceLocation RParen) {
   CanThrowResult CanThrow = canThrow(Operand);
-  return Owned(new (Context) CXXNoexceptExpr(Context.BoolTy, Operand,
-                                             CanThrow, KeyLoc, RParen));
+  return new (Context)
+      CXXNoexceptExpr(Context.BoolTy, Operand, CanThrow, KeyLoc, RParen);
 }
 
 ExprResult Sema::ActOnNoexceptExpr(SourceLocation KeyLoc, SourceLocation,
@@ -5760,8 +5719,8 @@
 ExprResult Sema::IgnoredValueConversions(Expr *E) {
   if (E->hasPlaceholderType()) {
     ExprResult result = CheckPlaceholderExpr(E);
-    if (result.isInvalid()) return Owned(E);
-    E = result.take();
+    if (result.isInvalid()) return E;
+    E = result.get();
   }
 
   // C99 6.3.2.1:
@@ -5776,7 +5735,7 @@
     if (!getLangOpts().CPlusPlus && E->getType()->isFunctionType())
       return DefaultFunctionArrayConversion(E);
 
-    return Owned(E);
+    return E;
   }
 
   if (getLangOpts().CPlusPlus)  {
@@ -5789,30 +5748,30 @@
         IsSpecialDiscardedValue(E)) {
       ExprResult Res = DefaultLvalueConversion(E);
       if (Res.isInvalid())
-        return Owned(E);
-      E = Res.take();
+        return E;
+      E = Res.get();
     } 
-    return Owned(E);
+    return E;
   }
 
   // GCC seems to also exclude expressions of incomplete enum type.
   if (const EnumType *T = E->getType()->getAs<EnumType>()) {
     if (!T->getDecl()->isComplete()) {
       // FIXME: stupid workaround for a codegen bug!
-      E = ImpCastExprToType(E, Context.VoidTy, CK_ToVoid).take();
-      return Owned(E);
+      E = ImpCastExprToType(E, Context.VoidTy, CK_ToVoid).get();
+      return E;
     }
   }
 
   ExprResult Res = DefaultFunctionArrayLvalueConversion(E);
   if (Res.isInvalid())
-    return Owned(E);
-  E = Res.take();
+    return E;
+  E = Res.get();
 
   if (!E->getType()->isVoidType())
     RequireCompleteType(E->getExprLoc(), E->getType(),
                         diag::err_incomplete_type);
-  return Owned(E);
+  return E;
 }
 
 // If we can unambiguously determine whether Var can never be used
@@ -5830,63 +5789,78 @@
 static inline bool VariableCanNeverBeAConstantExpression(VarDecl *Var, 
     ASTContext &Context) {
   if (isa<ParmVarDecl>(Var)) return true;
-  const VarDecl *DefVD = 0;
+  const VarDecl *DefVD = nullptr;
 
   // If there is no initializer - this can not be a constant expression.
   if (!Var->getAnyInitializer(DefVD)) return true;
   assert(DefVD);
   if (DefVD->isWeak()) return false;
   EvaluatedStmt *Eval = DefVD->ensureEvaluatedStmt();
-  
+
   Expr *Init = cast<Expr>(Eval->Value);
 
   if (Var->getType()->isDependentType() || Init->isValueDependent()) {
-    if (!Init->isValueDependent())
-      return !DefVD->checkInitIsICE();
-    // FIXME: We might still be able to do some analysis of Init here
-    // to conclude that even in a dependent setting, Init can never
-    // be a constexpr - but for now admit agnosticity.
+    // FIXME: Teach the constant evaluator to deal with the non-dependent parts
+    // of value-dependent expressions, and use it here to determine whether the
+    // initializer is a potential constant expression.
     return false;
-  } 
+  }
+
   return !IsVariableAConstantExpression(Var, Context); 
 }
 
-/// \brief Check if the current lambda scope has any potential captures, and 
-///  whether they can be captured by any of the enclosing lambdas that are 
-///  ready to capture. If there is a lambda that can capture a nested 
-///  potential-capture, go ahead and do so.  Also, check to see if any 
-///  variables are uncaptureable or do not involve an odr-use so do not 
-///  need to be captured.
+/// \brief Check if the current lambda has any potential captures 
+/// that must be captured by any of its enclosing lambdas that are ready to 
+/// capture. If there is a lambda that can capture a nested 
+/// potential-capture, go ahead and do so.  Also, check to see if any 
+/// variables are uncaptureable or do not involve an odr-use so do not 
+/// need to be captured.
 
-static void CheckLambdaCaptures(Expr *const FE, 
-    LambdaScopeInfo *const CurrentLSI, Sema &S) {
-    
+static void CheckIfAnyEnclosingLambdasMustCaptureAnyPotentialCaptures(
+    Expr *const FE, LambdaScopeInfo *const CurrentLSI, Sema &S) {
+
   assert(!S.isUnevaluatedContext());  
   assert(S.CurContext->isDependentContext()); 
-  const bool IsFullExprInstantiationDependent = 
-      FE->isInstantiationDependent();
-  // All the potentially captureable variables in the current nested 
+  assert(CurrentLSI->CallOperator == S.CurContext && 
+      "The current call operator must be synchronized with Sema's CurContext");
+
+  const bool IsFullExprInstantiationDependent = FE->isInstantiationDependent();
+
+  ArrayRef<const FunctionScopeInfo *> FunctionScopesArrayRef(
+      S.FunctionScopes.data(), S.FunctionScopes.size());
+  
+  // All the potentially captureable variables in the current nested
   // lambda (within a generic outer lambda), must be captured by an
   // outer lambda that is enclosed within a non-dependent context.
-     
-  for (size_t I = 0, N = CurrentLSI->getNumPotentialVariableCaptures(); 
-      I != N; ++I) {
-    Expr *VarExpr = 0;
-    VarDecl *Var = 0;
+  const unsigned NumPotentialCaptures =
+      CurrentLSI->getNumPotentialVariableCaptures();
+  for (unsigned I = 0; I != NumPotentialCaptures; ++I) {
+    Expr *VarExpr = nullptr;
+    VarDecl *Var = nullptr;
     CurrentLSI->getPotentialVariableCapture(I, Var, VarExpr);
-    // 
-    if (CurrentLSI->isVariableExprMarkedAsNonODRUsed(VarExpr) && 
+    // If the variable is clearly identified as non-odr-used and the full
+    // expression is not instantiation dependent, only then do we not 
+    // need to check enclosing lambda's for speculative captures.
+    // For e.g.:
+    // Even though 'x' is not odr-used, it should be captured.
+    // int test() {
+    //   const int x = 10;
+    //   auto L = [=](auto a) {
+    //     (void) +x + a;
+    //   };
+    // }
+    if (CurrentLSI->isVariableExprMarkedAsNonODRUsed(VarExpr) &&
         !IsFullExprInstantiationDependent)
-      continue; 
-    // Climb up until we find a lambda that can capture:
-    //   - a generic-or-non-generic lambda call operator that is enclosed
-    //     within a non-dependent context.
-    unsigned FunctionScopeIndexOfCapturableLambda = 0;
-    if (GetInnermostEnclosingCapturableLambda(
-            S.FunctionScopes, FunctionScopeIndexOfCapturableLambda,
-            S.CurContext, Var, S)) {
-      MarkVarDeclODRUsed(Var, VarExpr->getExprLoc(), 
-          S, &FunctionScopeIndexOfCapturableLambda);
+      continue;
+
+    // If we have a capture-capable lambda for the variable, go ahead and
+    // capture the variable in that lambda (and all its enclosing lambdas).
+    if (const Optional<unsigned> Index =
+            getStackIndexOfNearestEnclosingCaptureCapableLambda(
+                FunctionScopesArrayRef, Var, S)) {
+      const unsigned FunctionScopeIndexOfCapturableLambda = Index.getValue();
+      MarkVarDeclODRUsed(Var, VarExpr->getExprLoc(), S,
+                         &FunctionScopeIndexOfCapturableLambda);
     } 
     const bool IsVarNeverAConstantExpression = 
         VariableCanNeverBeAConstantExpression(Var, S.Context);
@@ -5902,56 +5876,78 @@
       if (S.tryCaptureVariable(Var, ExprLoc, S.TryCapture_Implicit,
                           /*EllipsisLoc*/ SourceLocation(), 
                           /*BuildAndDiagnose*/false, CaptureType, 
-                          DeclRefType, 0)) {
+                          DeclRefType, nullptr)) {
         // We will never be able to capture this variable, and we need
         // to be able to in any and all instantiations, so diagnose it.
         S.tryCaptureVariable(Var, ExprLoc, S.TryCapture_Implicit,
                           /*EllipsisLoc*/ SourceLocation(), 
                           /*BuildAndDiagnose*/true, CaptureType, 
-                          DeclRefType, 0);
+                          DeclRefType, nullptr);
       }
     }
   }
 
+  // Check if 'this' needs to be captured.
   if (CurrentLSI->hasPotentialThisCapture()) {
-    unsigned FunctionScopeIndexOfCapturableLambda = 0;
-    if (GetInnermostEnclosingCapturableLambda(
-            S.FunctionScopes, FunctionScopeIndexOfCapturableLambda,
-            S.CurContext, /*0 is 'this'*/ 0, S)) {
-      S.CheckCXXThisCapture(CurrentLSI->PotentialThisCaptureLocation, 
-          /*Explicit*/false, /*BuildAndDiagnose*/true,  
-          &FunctionScopeIndexOfCapturableLambda);
+    // If we have a capture-capable lambda for 'this', go ahead and capture
+    // 'this' in that lambda (and all its enclosing lambdas).
+    if (const Optional<unsigned> Index =
+            getStackIndexOfNearestEnclosingCaptureCapableLambda(
+                FunctionScopesArrayRef, /*0 is 'this'*/ nullptr, S)) {
+      const unsigned FunctionScopeIndexOfCapturableLambda = Index.getValue();
+      S.CheckCXXThisCapture(CurrentLSI->PotentialThisCaptureLocation,
+                            /*Explicit*/ false, /*BuildAndDiagnose*/ true,
+                            &FunctionScopeIndexOfCapturableLambda);
     }
   }
+
+  // Reset all the potential captures at the end of each full-expression.
   CurrentLSI->clearPotentialCaptures();
 }
 
 
 ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC,
                                      bool DiscardedValue,
-                                     bool IsConstexpr) {
-  ExprResult FullExpr = Owned(FE);
+                                     bool IsConstexpr, 
+                                     bool IsLambdaInitCaptureInitializer) {
+  ExprResult FullExpr = FE;
 
   if (!FullExpr.get())
     return ExprError();
-
-  if (DiagnoseUnexpandedParameterPack(FullExpr.get()))
+ 
+  // If we are an init-expression in a lambdas init-capture, we should not 
+  // diagnose an unexpanded pack now (will be diagnosed once lambda-expr 
+  // containing full-expression is done).
+  // template<class ... Ts> void test(Ts ... t) {
+  //   test([&a(t)]() { <-- (t) is an init-expr that shouldn't be diagnosed now.
+  //     return a;
+  //   }() ...);
+  // }
+  // FIXME: This is a hack. It would be better if we pushed the lambda scope
+  // when we parse the lambda introducer, and teach capturing (but not
+  // unexpanded pack detection) to walk over LambdaScopeInfos which don't have a
+  // corresponding class yet (that is, have LambdaScopeInfo either represent a
+  // lambda where we've entered the introducer but not the body, or represent a
+  // lambda where we've entered the body, depending on where the
+  // parser/instantiation has got to).
+  if (!IsLambdaInitCaptureInitializer && 
+      DiagnoseUnexpandedParameterPack(FullExpr.get()))
     return ExprError();
 
   // Top-level expressions default to 'id' when we're in a debugger.
   if (DiscardedValue && getLangOpts().DebuggerCastResultToId &&
       FullExpr.get()->getType() == Context.UnknownAnyTy) {
-    FullExpr = forceUnknownAnyToType(FullExpr.take(), Context.getObjCIdType());
+    FullExpr = forceUnknownAnyToType(FullExpr.get(), Context.getObjCIdType());
     if (FullExpr.isInvalid())
       return ExprError();
   }
 
   if (DiscardedValue) {
-    FullExpr = CheckPlaceholderExpr(FullExpr.take());
+    FullExpr = CheckPlaceholderExpr(FullExpr.get());
     if (FullExpr.isInvalid())
       return ExprError();
 
-    FullExpr = IgnoredValueConversions(FullExpr.take());
+    FullExpr = IgnoredValueConversions(FullExpr.get());
     if (FullExpr.isInvalid())
       return ExprError();
   }
@@ -6002,11 +5998,12 @@
   //     FunctionScopes.size() in InstantiatingTemplate's 
   //     constructor/destructor.
   //  - Teach the handful of places that iterate over FunctionScopes to 
-  //    stop at the outermost enclosing lexical scope." 
-  const bool IsInLambdaDeclContext = isLambdaCallOperator(CurContext); 
-  if (IsInLambdaDeclContext && CurrentLSI && 
+  //    stop at the outermost enclosing lexical scope."
+  const bool IsInLambdaDeclContext = isLambdaCallOperator(CurContext);
+  if (IsInLambdaDeclContext && CurrentLSI &&
       CurrentLSI->hasPotentialCaptures() && !FullExpr.isInvalid())
-    CheckLambdaCaptures(FE, CurrentLSI, *this);
+    CheckIfAnyEnclosingLambdasMustCaptureAnyPotentialCaptures(FE, CurrentLSI,
+                                                              *this);
   return MaybeCreateExprWithCleanups(FullExpr);
 }
 
diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp
index f6accb1..ef78982 100644
--- a/lib/Sema/SemaExprMember.cpp
+++ b/lib/Sema/SemaExprMember.cpp
@@ -206,7 +206,7 @@
 
   DeclContext *FunctionLevelDC = SemaRef.getFunctionLevelDeclContext();
   CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FunctionLevelDC);
-  CXXRecordDecl *ContextClass = Method ? Method->getParent() : 0;
+  CXXRecordDecl *ContextClass = Method ? Method->getParent() : nullptr;
   CXXRecordDecl *RepClass = dyn_cast<CXXRecordDecl>(Rep->getDeclContext());
 
   bool InStaticMethod = Method && Method->isStatic();
@@ -292,7 +292,7 @@
 
   // This flag determines whether or not CompName has an 's' char prefix,
   // indicating that it is a string of hex values to be used as vector indices.
-  bool HexSwizzle = *compStr == 's' || *compStr == 'S';
+  bool HexSwizzle = (*compStr == 's' || *compStr == 'S') && compStr[1];
 
   bool HasRepeated = false;
   bool HasIndex[16] = {};
@@ -384,13 +384,12 @@
   if (ObjCMethodDecl *OMD = PDecl->getInstanceMethod(Sel))
     return OMD;
 
-  for (ObjCProtocolDecl::protocol_iterator I = PDecl->protocol_begin(),
-       E = PDecl->protocol_end(); I != E; ++I) {
-    if (Decl *D = FindGetterSetterNameDeclFromProtocolList(*I, Member, Sel,
+  for (const auto *I : PDecl->protocols()) {
+    if (Decl *D = FindGetterSetterNameDeclFromProtocolList(I, Member, Sel,
                                                            Context))
       return D;
   }
-  return 0;
+  return nullptr;
 }
 
 static Decl *FindGetterSetterNameDecl(const ObjCObjectPointerType *QIdTy,
@@ -398,26 +397,23 @@
                                       const Selector &Sel,
                                       ASTContext &Context) {
   // Check protocols on qualified interfaces.
-  Decl *GDecl = 0;
-  for (ObjCObjectPointerType::qual_iterator I = QIdTy->qual_begin(),
-       E = QIdTy->qual_end(); I != E; ++I) {
+  Decl *GDecl = nullptr;
+  for (const auto *I : QIdTy->quals()) {
     if (Member)
-      if (ObjCPropertyDecl *PD = (*I)->FindPropertyDeclaration(Member)) {
+      if (ObjCPropertyDecl *PD = I->FindPropertyDeclaration(Member)) {
         GDecl = PD;
         break;
       }
     // Also must look for a getter or setter name which uses property syntax.
-    if (ObjCMethodDecl *OMD = (*I)->getInstanceMethod(Sel)) {
+    if (ObjCMethodDecl *OMD = I->getInstanceMethod(Sel)) {
       GDecl = OMD;
       break;
     }
   }
   if (!GDecl) {
-    for (ObjCObjectPointerType::qual_iterator I = QIdTy->qual_begin(),
-         E = QIdTy->qual_end(); I != E; ++I) {
+    for (const auto *I : QIdTy->quals()) {
       // Search in the protocol-qualifier list of current protocol.
-      GDecl = FindGetterSetterNameDeclFromProtocolList(*I, Member, Sel, 
-                                                       Context);
+      GDecl = FindGetterSetterNameDeclFromProtocolList(I, Member, Sel, Context);
       if (GDecl)
         return GDecl;
     }
@@ -459,12 +455,10 @@
 
   // Get the type being accessed in BaseType.  If this is an arrow, the BaseExpr
   // must have pointer type, and the accessed type is the pointee.
-  return Owned(CXXDependentScopeMemberExpr::Create(Context, BaseExpr, BaseType,
-                                                   IsArrow, OpLoc,
-                                               SS.getWithLocInContext(Context),
-                                                   TemplateKWLoc,
-                                                   FirstQualifierInScope,
-                                                   NameInfo, TemplateArgs));
+  return CXXDependentScopeMemberExpr::Create(
+      Context, BaseExpr, BaseType, IsArrow, OpLoc,
+      SS.getWithLocInContext(Context), TemplateKWLoc, FirstQualifierInScope,
+      NameInfo, TemplateArgs);
 }
 
 /// We know that the given qualified member reference points only to
@@ -546,7 +540,7 @@
   explicit RecordMemberExprValidatorCCC(const RecordType *RTy)
       : Record(RTy->getDecl()) {}
 
-  virtual bool ValidateCandidate(const TypoCorrection &candidate) {
+  bool ValidateCandidate(const TypoCorrection &candidate) override {
     NamedDecl *ND = candidate.getCorrectionDecl();
     // Don't accept candidates that cannot be member functions, constants,
     // variables, or templates.
@@ -559,11 +553,9 @@
 
     if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Record)) {
       // Accept candidates that occur in any of the current class' base classes.
-      for (CXXRecordDecl::base_class_const_iterator BS = RD->bases_begin(),
-                                                    BSEnd = RD->bases_end();
-           BS != BSEnd; ++BS) {
+      for (const auto &BS : RD->bases()) {
         if (const RecordType *BSTy = dyn_cast_or_null<RecordType>(
-                BS->getType().getTypePtrOrNull())) {
+                BS.getType().getTypePtrOrNull())) {
           if (BSTy->getDecl()->containsDecl(ND))
             return true;
         }
@@ -596,7 +588,7 @@
     QualType ObjectType = SS.isSet() ? QualType() : QualType(RTy, 0);
 
     bool MOUS;
-    SemaRef.LookupTemplateName(R, 0, SS, ObjectType, false, MOUS);
+    SemaRef.LookupTemplateName(R, nullptr, SS, ObjectType, false, MOUS);
     return false;
   }
 
@@ -632,8 +624,9 @@
   DeclarationName Name = R.getLookupName();
   RecordMemberExprValidatorCCC Validator(RTy);
   TypoCorrection Corrected = SemaRef.CorrectTypo(R.getLookupNameInfo(),
-                                                 R.getLookupKind(), NULL,
-                                                 &SS, Validator, DC);
+                                                 R.getLookupKind(), nullptr,
+                                                 &SS, Validator,
+                                                 Sema::CTK_ErrorRecovery, DC);
   R.clear();
   if (Corrected.isResolved() && !Corrected.isKeyword()) {
     R.setLookupName(Corrected.getCorrection());
@@ -648,7 +641,7 @@
     // information to do overload resolution, so we don't know which previous
     // declaration to point to.
     if (Corrected.isOverloaded())
-      Corrected.setCorrectionDecl(0);
+      Corrected.setCorrectionDecl(nullptr);
     bool DroppedSpecifier =
         Corrected.WillReplaceSpecifier() &&
         Name.getAsString() == Corrected.getAsString(SemaRef.getLangOpts());
@@ -660,6 +653,11 @@
   return false;
 }
 
+static ExprResult LookupMemberExpr(Sema &S, LookupResult &R,
+                                   ExprResult &BaseExpr, bool &IsArrow,
+                                   SourceLocation OpLoc, CXXScopeSpec &SS,
+                                   Decl *ObjCImpDecl, bool HasTemplateArgs);
+
 ExprResult
 Sema::BuildMemberReferenceExpr(Expr *Base, QualType BaseType,
                                SourceLocation OpLoc, bool IsArrow,
@@ -667,7 +665,8 @@
                                SourceLocation TemplateKWLoc,
                                NamedDecl *FirstQualifierInScope,
                                const DeclarationNameInfo &NameInfo,
-                               const TemplateArgumentListInfo *TemplateArgs) {
+                               const TemplateArgumentListInfo *TemplateArgs,
+                               ActOnMemberAccessExtraArgs *ExtraArgs) {
   if (BaseType->isDependentType() ||
       (SS.isSet() && isDependentScopeSpecifier(SS)))
     return ActOnDependentMemberExpr(Base, BaseType,
@@ -683,24 +682,23 @@
     if (IsArrow) RecordTy = RecordTy->getAs<PointerType>()->getPointeeType();
     if (LookupMemberExprInRecord(*this, R, SourceRange(),
                                  RecordTy->getAs<RecordType>(),
-                                 OpLoc, SS, TemplateArgs != 0))
+                                 OpLoc, SS, TemplateArgs != nullptr))
       return ExprError();
 
   // Explicit member accesses.
   } else {
-    ExprResult BaseResult = Owned(Base);
-    ExprResult Result =
-      LookupMemberExpr(R, BaseResult, IsArrow, OpLoc,
-                       SS, /*ObjCImpDecl*/ 0, TemplateArgs != 0);
+    ExprResult BaseResult = Base;
+    ExprResult Result = LookupMemberExpr(
+        *this, R, BaseResult, IsArrow, OpLoc, SS,
+        ExtraArgs ? ExtraArgs->ObjCImpDecl : nullptr,
+        TemplateArgs != nullptr);
 
     if (BaseResult.isInvalid())
       return ExprError();
-    Base = BaseResult.take();
+    Base = BaseResult.get();
 
-    if (Result.isInvalid()) {
-      Owned(Base);
+    if (Result.isInvalid())
       return ExprError();
-    }
 
     if (Result.get())
       return Result;
@@ -711,7 +709,8 @@
 
   return BuildMemberReferenceExpr(Base, BaseType,
                                   OpLoc, IsArrow, SS, TemplateKWLoc,
-                                  FirstQualifierInScope, R, TemplateArgs);
+                                  FirstQualifierInScope, R, TemplateArgs,
+                                  false, ExtraArgs);
 }
 
 static ExprResult
@@ -751,7 +750,7 @@
       = BuildDeclarationNameExpr(EmptySS, baseNameInfo, baseVariable);
     if (result.isInvalid()) return ExprError();
     
-    baseObjectExpr = result.take();    
+    baseObjectExpr = result.get();    
     baseObjectIsPointer = false;
     baseQuals = baseObjectExpr->getType().getQualifiers();
     
@@ -807,12 +806,10 @@
     
     result = BuildFieldReferenceExpr(*this, result, baseObjectIsPointer,
                                      EmptySS, field, foundDecl,
-                                     memberNameInfo).take();
+                                     memberNameInfo).get();
     if (!result)
       return ExprError();
 
-    baseObjectIsPointer = false;
-    
     // FIXME: check qualified member access
   }
   
@@ -829,10 +826,10 @@
 
     result = BuildFieldReferenceExpr(*this, result, /*isarrow*/ false,
                                      (FI == FEnd? SS : EmptySS), field,
-                                     fakeFoundDecl, memberNameInfo).take();
+                                     fakeFoundDecl, memberNameInfo).get();
   }
   
-  return Owned(result);
+  return result;
 }
 
 static ExprResult
@@ -849,16 +846,13 @@
 }
 
 /// \brief Build a MemberExpr AST node.
-static MemberExpr *BuildMemberExpr(Sema &SemaRef,
-                                   ASTContext &C, Expr *Base, bool isArrow,
-                                   const CXXScopeSpec &SS,
-                                   SourceLocation TemplateKWLoc,
-                                   ValueDecl *Member,
-                                   DeclAccessPair FoundDecl,
-                                   const DeclarationNameInfo &MemberNameInfo,
-                                   QualType Ty,
-                                   ExprValueKind VK, ExprObjectKind OK,
-                                   const TemplateArgumentListInfo *TemplateArgs = 0) {
+static MemberExpr *
+BuildMemberExpr(Sema &SemaRef, ASTContext &C, Expr *Base, bool isArrow,
+                const CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
+                ValueDecl *Member, DeclAccessPair FoundDecl,
+                const DeclarationNameInfo &MemberNameInfo, QualType Ty,
+                ExprValueKind VK, ExprObjectKind OK,
+                const TemplateArgumentListInfo *TemplateArgs = nullptr) {
   assert((!isArrow || Base->isRValue()) && "-> base must be a pointer rvalue");
   MemberExpr *E =
       MemberExpr::Create(C, Base, isArrow, SS.getWithLocInContext(C),
@@ -1006,7 +1000,7 @@
                                      TemplateKWLoc, MemberNameInfo,
                                      TemplateArgs, R.begin(), R.end());
 
-    return Owned(MemExpr);
+    return MemExpr;
   }
 
   assert(R.isSingleResult());
@@ -1043,10 +1037,8 @@
   }
 
   // Check the use of this member.
-  if (ShouldCheckUse && DiagnoseUseOfDecl(MemberDecl, MemberLoc)) {
-    Owned(BaseExpr);
+  if (ShouldCheckUse && DiagnoseUseOfDecl(MemberDecl, MemberLoc))
     return ExprError();
-  }
 
   if (FieldDecl *FD = dyn_cast<FieldDecl>(MemberDecl))
     return BuildFieldReferenceExpr(*this, BaseExpr, IsArrow,
@@ -1064,10 +1056,10 @@
                                                     OpLoc);
 
   if (VarDecl *Var = dyn_cast<VarDecl>(MemberDecl)) {
-    return Owned(BuildMemberExpr(*this, Context, BaseExpr, IsArrow, SS,
-                                 TemplateKWLoc, Var, FoundDecl, MemberNameInfo,
-                                 Var->getType().getNonReferenceType(),
-                                 VK_LValue, OK_Ordinary));
+    return BuildMemberExpr(*this, Context, BaseExpr, IsArrow, SS, TemplateKWLoc,
+                           Var, FoundDecl, MemberNameInfo,
+                           Var->getType().getNonReferenceType(), VK_LValue,
+                           OK_Ordinary);
   }
 
   if (CXXMethodDecl *MemberFn = dyn_cast<CXXMethodDecl>(MemberDecl)) {
@@ -1081,21 +1073,18 @@
       type = MemberFn->getType();
     }
 
-    return Owned(BuildMemberExpr(*this, Context, BaseExpr, IsArrow, SS, 
-                                 TemplateKWLoc, MemberFn, FoundDecl, 
-                                 MemberNameInfo, type, valueKind,
-                                 OK_Ordinary));
+    return BuildMemberExpr(*this, Context, BaseExpr, IsArrow, SS, TemplateKWLoc,
+                           MemberFn, FoundDecl, MemberNameInfo, type, valueKind,
+                           OK_Ordinary);
   }
   assert(!isa<FunctionDecl>(MemberDecl) && "member function not C++ method?");
 
   if (EnumConstantDecl *Enum = dyn_cast<EnumConstantDecl>(MemberDecl)) {
-    return Owned(BuildMemberExpr(*this, Context, BaseExpr, IsArrow, SS,
-                                 TemplateKWLoc, Enum, FoundDecl, MemberNameInfo,
-                                 Enum->getType(), VK_RValue, OK_Ordinary));
+    return BuildMemberExpr(*this, Context, BaseExpr, IsArrow, SS, TemplateKWLoc,
+                           Enum, FoundDecl, MemberNameInfo, Enum->getType(),
+                           VK_RValue, OK_Ordinary);
   }
 
-  Owned(BaseExpr);
-
   // We found something that we didn't expect. Complain.
   if (isa<TypeDecl>(MemberDecl))
     Diag(MemberLoc, diag::err_typecheck_member_reference_type)
@@ -1138,7 +1127,7 @@
   if (opty && !opty->getObjectType()->getInterface())
     return false;
 
-  base = S.ImpCastExprToType(base.take(), redef, CK_BitCast);
+  base = S.ImpCastExprToType(base.get(), redef, CK_BitCast);
   return true;
 }
 
@@ -1170,15 +1159,14 @@
 ///
 /// The ObjCImpDecl bit is a gross hack that will need to be properly
 /// fixed for ObjC++.
-ExprResult
-Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr,
-                       bool &IsArrow, SourceLocation OpLoc,
-                       CXXScopeSpec &SS,
-                       Decl *ObjCImpDecl, bool HasTemplateArgs) {
+static ExprResult LookupMemberExpr(Sema &S, LookupResult &R,
+                                   ExprResult &BaseExpr, bool &IsArrow,
+                                   SourceLocation OpLoc, CXXScopeSpec &SS,
+                                   Decl *ObjCImpDecl, bool HasTemplateArgs) {
   assert(BaseExpr.get() && "no base expression");
 
   // Perform default conversions.
-  BaseExpr = PerformMemberExprBaseConversion(BaseExpr.take(), IsArrow);
+  BaseExpr = S.PerformMemberExprBaseConversion(BaseExpr.get(), IsArrow);
   if (BaseExpr.isInvalid())
     return ExprError();
 
@@ -1206,8 +1194,8 @@
       // overloaded operator->, but that should have been dealt with
       // by now--or a diagnostic message already issued if a problem
       // was encountered while looking for the overloaded operator->.
-      if (!getLangOpts().CPlusPlus) {
-        Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
+      if (!S.getLangOpts().CPlusPlus) {
+        S.Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
           << BaseType << int(IsArrow) << BaseExpr.get()->getSourceRange()
           << FixItHint::CreateReplacement(OpLoc, ".");
       }
@@ -1215,7 +1203,7 @@
     } else if (BaseType->isFunctionType()) {
       goto fail;
     } else {
-      Diag(MemberLoc, diag::err_typecheck_member_reference_arrow)
+      S.Diag(MemberLoc, diag::err_typecheck_member_reference_arrow)
         << BaseType << BaseExpr.get()->getSourceRange();
       return ExprError();
     }
@@ -1223,24 +1211,24 @@
 
   // Handle field access to simple records.
   if (const RecordType *RTy = BaseType->getAs<RecordType>()) {
-    if (LookupMemberExprInRecord(*this, R, BaseExpr.get()->getSourceRange(),
+    if (LookupMemberExprInRecord(S, R, BaseExpr.get()->getSourceRange(),
                                  RTy, OpLoc, SS, HasTemplateArgs))
       return ExprError();
 
     // Returning valid-but-null is how we indicate to the caller that
     // the lookup result was filled in.
-    return Owned((Expr*) 0);
+    return ExprResult((Expr *)nullptr);
   }
 
   // Handle ivar access to Objective-C objects.
   if (const ObjCObjectType *OTy = BaseType->getAs<ObjCObjectType>()) {
     if (!SS.isEmpty() && !SS.isInvalid()) {
-      Diag(SS.getRange().getBegin(), diag::err_qualified_objc_access)
+      S.Diag(SS.getRange().getBegin(), diag::err_qualified_objc_access)
         << 1 << SS.getScopeRep()
         << FixItHint::CreateRemoval(SS.getRange());
       SS.clear();
     }
-    
+
     IdentifierInfo *Member = MemberName.getAsIdentifierInfo();
 
     // There are three cases for the base type:
@@ -1249,40 +1237,41 @@
     //   - an interface
     ObjCInterfaceDecl *IDecl = OTy->getInterface();
     if (!IDecl) {
-      if (getLangOpts().ObjCAutoRefCount &&
+      if (S.getLangOpts().ObjCAutoRefCount &&
           (OTy->isObjCId() || OTy->isObjCClass()))
         goto fail;
       // There's an implicit 'isa' ivar on all objects.
       // But we only actually find it this way on objects of type 'id',
       // apparently.
       if (OTy->isObjCId() && Member->isStr("isa"))
-        return Owned(new (Context) ObjCIsaExpr(BaseExpr.take(), IsArrow, MemberLoc,
-                                               OpLoc,
-                                               Context.getObjCClassType()));
-      if (ShouldTryAgainWithRedefinitionType(*this, BaseExpr))
-        return LookupMemberExpr(R, BaseExpr, IsArrow, OpLoc, SS,
+        return new (S.Context) ObjCIsaExpr(BaseExpr.get(), IsArrow, MemberLoc,
+                                           OpLoc, S.Context.getObjCClassType());
+      if (ShouldTryAgainWithRedefinitionType(S, BaseExpr))
+        return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
                                 ObjCImpDecl, HasTemplateArgs);
       goto fail;
     }
-    
-    if (RequireCompleteType(OpLoc, BaseType, diag::err_typecheck_incomplete_tag,
-                            BaseExpr.get()))
+
+    if (S.RequireCompleteType(OpLoc, BaseType,
+                              diag::err_typecheck_incomplete_tag,
+                              BaseExpr.get()))
       return ExprError();
-    
-    ObjCInterfaceDecl *ClassDeclared = 0;
+
+    ObjCInterfaceDecl *ClassDeclared = nullptr;
     ObjCIvarDecl *IV = IDecl->lookupInstanceVariable(Member, ClassDeclared);
 
     if (!IV) {
       // Attempt to correct for typos in ivar names.
       DeclFilterCCC<ObjCIvarDecl> Validator;
       Validator.IsObjCIvarLookup = IsArrow;
-      if (TypoCorrection Corrected = CorrectTypo(R.getLookupNameInfo(),
-                                                 LookupMemberName, NULL, NULL,
-                                                 Validator, IDecl)) {
+      if (TypoCorrection Corrected = S.CorrectTypo(
+              R.getLookupNameInfo(), Sema::LookupMemberName, nullptr, nullptr,
+              Validator, Sema::CTK_ErrorRecovery, IDecl)) {
         IV = Corrected.getCorrectionDeclAs<ObjCIvarDecl>();
-        diagnoseTypo(Corrected,
-                     PDiag(diag::err_typecheck_member_reference_ivar_suggest)
-                          << IDecl->getDeclName() << MemberName);
+        S.diagnoseTypo(
+            Corrected,
+            S.PDiag(diag::err_typecheck_member_reference_ivar_suggest)
+                << IDecl->getDeclName() << MemberName);
 
         // Figure out the class that declares the ivar.
         assert(!ClassDeclared);
@@ -1292,20 +1281,19 @@
         ClassDeclared = cast<ObjCInterfaceDecl>(D);
       } else {
         if (IsArrow && IDecl->FindPropertyDeclaration(Member)) {
-          Diag(MemberLoc, 
-          diag::err_property_found_suggest)
-          << Member << BaseExpr.get()->getType()
-          << FixItHint::CreateReplacement(OpLoc, ".");
+          S.Diag(MemberLoc, diag::err_property_found_suggest)
+              << Member << BaseExpr.get()->getType()
+              << FixItHint::CreateReplacement(OpLoc, ".");
           return ExprError();
         }
 
-        Diag(MemberLoc, diag::err_typecheck_member_reference_ivar)
-          << IDecl->getDeclName() << MemberName
-          << BaseExpr.get()->getSourceRange();
+        S.Diag(MemberLoc, diag::err_typecheck_member_reference_ivar)
+            << IDecl->getDeclName() << MemberName
+            << BaseExpr.get()->getSourceRange();
         return ExprError();
       }
     }
-    
+
     assert(ClassDeclared);
 
     // If the decl being referenced had an error, return an error for this
@@ -1315,14 +1303,14 @@
       return ExprError();
 
     // Check whether we can reference this field.
-    if (DiagnoseUseOfDecl(IV, MemberLoc))
+    if (S.DiagnoseUseOfDecl(IV, MemberLoc))
       return ExprError();
     if (IV->getAccessControl() != ObjCIvarDecl::Public &&
         IV->getAccessControl() != ObjCIvarDecl::Package) {
-      ObjCInterfaceDecl *ClassOfMethodDecl = 0;
-      if (ObjCMethodDecl *MD = getCurMethodDecl())
+      ObjCInterfaceDecl *ClassOfMethodDecl = nullptr;
+      if (ObjCMethodDecl *MD = S.getCurMethodDecl())
         ClassOfMethodDecl =  MD->getClassInterface();
-      else if (ObjCImpDecl && getCurFunctionDecl()) {
+      else if (ObjCImpDecl && S.getCurFunctionDecl()) {
         // Case of a c-function declared inside an objc implementation.
         // FIXME: For a c-style function nested inside an objc implementation
         // class, there is no implementation context available, so we pass
@@ -1336,20 +1324,20 @@
                    dyn_cast<ObjCCategoryImplDecl>(ObjCImpDecl))
           ClassOfMethodDecl = CatImplClass->getClassInterface();
       }
-      if (!getLangOpts().DebuggerSupport) {
+      if (!S.getLangOpts().DebuggerSupport) {
         if (IV->getAccessControl() == ObjCIvarDecl::Private) {
           if (!declaresSameEntity(ClassDeclared, IDecl) ||
               !declaresSameEntity(ClassOfMethodDecl, ClassDeclared))
-            Diag(MemberLoc, diag::error_private_ivar_access)
+            S.Diag(MemberLoc, diag::error_private_ivar_access)
               << IV->getDeclName();
         } else if (!IDecl->isSuperClassOf(ClassOfMethodDecl))
           // @protected
-          Diag(MemberLoc, diag::error_protected_ivar_access)
-            << IV->getDeclName();
+          S.Diag(MemberLoc, diag::error_protected_ivar_access)
+              << IV->getDeclName();
       }
     }
     bool warn = true;
-    if (getLangOpts().ObjCAutoRefCount) {
+    if (S.getLangOpts().ObjCAutoRefCount) {
       Expr *BaseExp = BaseExpr.get()->IgnoreParenImpCasts();
       if (UnaryOperator *UO = dyn_cast<UnaryOperator>(BaseExp))
         if (UO->getOpcode() == UO_Deref)
@@ -1357,55 +1345,50 @@
       
       if (DeclRefExpr *DE = dyn_cast<DeclRefExpr>(BaseExp))
         if (DE->getType().getObjCLifetime() == Qualifiers::OCL_Weak) {
-          Diag(DE->getLocation(), diag::error_arc_weak_ivar_access);
+          S.Diag(DE->getLocation(), diag::error_arc_weak_ivar_access);
           warn = false;
         }
     }
     if (warn) {
-      if (ObjCMethodDecl *MD = getCurMethodDecl()) {
+      if (ObjCMethodDecl *MD = S.getCurMethodDecl()) {
         ObjCMethodFamily MF = MD->getMethodFamily();
         warn = (MF != OMF_init && MF != OMF_dealloc && 
                 MF != OMF_finalize &&
-                !IvarBacksCurrentMethodAccessor(IDecl, MD, IV));
+                !S.IvarBacksCurrentMethodAccessor(IDecl, MD, IV));
       }
       if (warn)
-        Diag(MemberLoc, diag::warn_direct_ivar_access) << IV->getDeclName();
+        S.Diag(MemberLoc, diag::warn_direct_ivar_access) << IV->getDeclName();
     }
 
-    ObjCIvarRefExpr *Result = new (Context) ObjCIvarRefExpr(IV, IV->getType(),
-                                                            MemberLoc, OpLoc,
-                                                            BaseExpr.take(),
-                                                            IsArrow);
+    ObjCIvarRefExpr *Result = new (S.Context) ObjCIvarRefExpr(
+        IV, IV->getType(), MemberLoc, OpLoc, BaseExpr.get(), IsArrow);
 
-    if (getLangOpts().ObjCAutoRefCount) {
+    if (S.getLangOpts().ObjCAutoRefCount) {
       if (IV->getType().getObjCLifetime() == Qualifiers::OCL_Weak) {
-        DiagnosticsEngine::Level Level =
-          Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak,
-                                   MemberLoc);
-        if (Level != DiagnosticsEngine::Ignored)
-          recordUseOfEvaluatedWeak(Result);
+        if (!S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, MemberLoc))
+          S.recordUseOfEvaluatedWeak(Result);
       }
     }
 
-    return Owned(Result);
+    return Result;
   }
 
   // Objective-C property access.
   const ObjCObjectPointerType *OPT;
   if (!IsArrow && (OPT = BaseType->getAs<ObjCObjectPointerType>())) {
     if (!SS.isEmpty() && !SS.isInvalid()) {
-      Diag(SS.getRange().getBegin(), diag::err_qualified_objc_access)
-        << 0 << SS.getScopeRep()
-        << FixItHint::CreateRemoval(SS.getRange());
+      S.Diag(SS.getRange().getBegin(), diag::err_qualified_objc_access)
+          << 0 << SS.getScopeRep() << FixItHint::CreateRemoval(SS.getRange());
       SS.clear();
     }
 
     // This actually uses the base as an r-value.
-    BaseExpr = DefaultLvalueConversion(BaseExpr.take());
+    BaseExpr = S.DefaultLvalueConversion(BaseExpr.get());
     if (BaseExpr.isInvalid())
       return ExprError();
 
-    assert(Context.hasSameUnqualifiedType(BaseType, BaseExpr.get()->getType()));
+    assert(S.Context.hasSameUnqualifiedType(BaseType,
+                                            BaseExpr.get()->getType()));
 
     IdentifierInfo *Member = MemberName.getAsIdentifierInfo();
 
@@ -1414,77 +1397,75 @@
     // id, with and without qualifiers.
     if (OT->isObjCId()) {
       // Check protocols on qualified interfaces.
-      Selector Sel = PP.getSelectorTable().getNullarySelector(Member);
-      if (Decl *PMDecl = FindGetterSetterNameDecl(OPT, Member, Sel, Context)) {
+      Selector Sel = S.PP.getSelectorTable().getNullarySelector(Member);
+      if (Decl *PMDecl =
+              FindGetterSetterNameDecl(OPT, Member, Sel, S.Context)) {
         if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(PMDecl)) {
           // Check the use of this declaration
-          if (DiagnoseUseOfDecl(PD, MemberLoc))
+          if (S.DiagnoseUseOfDecl(PD, MemberLoc))
             return ExprError();
 
-          return Owned(new (Context) ObjCPropertyRefExpr(PD,
-                                                         Context.PseudoObjectTy,
-                                                         VK_LValue,
-                                                         OK_ObjCProperty,
-                                                         MemberLoc, 
-                                                         BaseExpr.take()));
+          return new (S.Context)
+              ObjCPropertyRefExpr(PD, S.Context.PseudoObjectTy, VK_LValue,
+                                  OK_ObjCProperty, MemberLoc, BaseExpr.get());
         }
 
         if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(PMDecl)) {
           // Check the use of this method.
-          if (DiagnoseUseOfDecl(OMD, MemberLoc))
+          if (S.DiagnoseUseOfDecl(OMD, MemberLoc))
             return ExprError();
           Selector SetterSel =
-            SelectorTable::constructSetterSelector(PP.getIdentifierTable(),
-                                                   PP.getSelectorTable(),
+            SelectorTable::constructSetterSelector(S.PP.getIdentifierTable(),
+                                                   S.PP.getSelectorTable(),
                                                    Member);
-          ObjCMethodDecl *SMD = 0;
-          if (Decl *SDecl = FindGetterSetterNameDecl(OPT, /*Property id*/0, 
-                                                     SetterSel, Context))
+          ObjCMethodDecl *SMD = nullptr;
+          if (Decl *SDecl = FindGetterSetterNameDecl(OPT,
+                                                     /*Property id*/ nullptr,
+                                                     SetterSel, S.Context))
             SMD = dyn_cast<ObjCMethodDecl>(SDecl);
-          
-          return Owned(new (Context) ObjCPropertyRefExpr(OMD, SMD,
-                                                         Context.PseudoObjectTy,
-                                                         VK_LValue, OK_ObjCProperty,
-                                                         MemberLoc, BaseExpr.take()));
+
+          return new (S.Context)
+              ObjCPropertyRefExpr(OMD, SMD, S.Context.PseudoObjectTy, VK_LValue,
+                                  OK_ObjCProperty, MemberLoc, BaseExpr.get());
         }
       }
       // Use of id.member can only be for a property reference. Do not
       // use the 'id' redefinition in this case.
-      if (IsArrow && ShouldTryAgainWithRedefinitionType(*this, BaseExpr))
-        return LookupMemberExpr(R, BaseExpr, IsArrow, OpLoc, SS,
+      if (IsArrow && ShouldTryAgainWithRedefinitionType(S, BaseExpr))
+        return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
                                 ObjCImpDecl, HasTemplateArgs);
 
-      return ExprError(Diag(MemberLoc, diag::err_property_not_found)
+      return ExprError(S.Diag(MemberLoc, diag::err_property_not_found)
                          << MemberName << BaseType);
     }
 
     // 'Class', unqualified only.
     if (OT->isObjCClass()) {
       // Only works in a method declaration (??!).
-      ObjCMethodDecl *MD = getCurMethodDecl();
+      ObjCMethodDecl *MD = S.getCurMethodDecl();
       if (!MD) {
-        if (ShouldTryAgainWithRedefinitionType(*this, BaseExpr))
-          return LookupMemberExpr(R, BaseExpr, IsArrow, OpLoc, SS,
+        if (ShouldTryAgainWithRedefinitionType(S, BaseExpr))
+          return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
                                   ObjCImpDecl, HasTemplateArgs);
 
         goto fail;
       }
 
       // Also must look for a getter name which uses property syntax.
-      Selector Sel = PP.getSelectorTable().getNullarySelector(Member);
+      Selector Sel = S.PP.getSelectorTable().getNullarySelector(Member);
       ObjCInterfaceDecl *IFace = MD->getClassInterface();
       ObjCMethodDecl *Getter;
       if ((Getter = IFace->lookupClassMethod(Sel))) {
         // Check the use of this method.
-        if (DiagnoseUseOfDecl(Getter, MemberLoc))
+        if (S.DiagnoseUseOfDecl(Getter, MemberLoc))
           return ExprError();
       } else
         Getter = IFace->lookupPrivateMethod(Sel, false);
       // If we found a getter then this may be a valid dot-reference, we
       // will look for the matching setter, in case it is needed.
       Selector SetterSel =
-        SelectorTable::constructSetterSelector(PP.getIdentifierTable(),
-                                               PP.getSelectorTable(),
+        SelectorTable::constructSetterSelector(S.PP.getIdentifierTable(),
+                                               S.PP.getSelectorTable(),
                                                Member);
       ObjCMethodDecl *Setter = IFace->lookupClassMethod(SetterSel);
       if (!Setter) {
@@ -1493,28 +1474,27 @@
         Setter = IFace->lookupPrivateMethod(SetterSel, false);
       }
 
-      if (Setter && DiagnoseUseOfDecl(Setter, MemberLoc))
+      if (Setter && S.DiagnoseUseOfDecl(Setter, MemberLoc))
         return ExprError();
 
       if (Getter || Setter) {
-        return Owned(new (Context) ObjCPropertyRefExpr(Getter, Setter,
-                                                       Context.PseudoObjectTy,
-                                                       VK_LValue, OK_ObjCProperty,
-                                                       MemberLoc, BaseExpr.take()));
+        return new (S.Context) ObjCPropertyRefExpr(
+            Getter, Setter, S.Context.PseudoObjectTy, VK_LValue,
+            OK_ObjCProperty, MemberLoc, BaseExpr.get());
       }
 
-      if (ShouldTryAgainWithRedefinitionType(*this, BaseExpr))
-        return LookupMemberExpr(R, BaseExpr, IsArrow, OpLoc, SS,
+      if (ShouldTryAgainWithRedefinitionType(S, BaseExpr))
+        return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
                                 ObjCImpDecl, HasTemplateArgs);
 
-      return ExprError(Diag(MemberLoc, diag::err_property_not_found)
+      return ExprError(S.Diag(MemberLoc, diag::err_property_not_found)
                          << MemberName << BaseType);
     }
 
     // Normal property access.
-    return HandleExprPropertyRefExpr(OPT, BaseExpr.get(), OpLoc, 
-                                     MemberName, MemberLoc,
-                                     SourceLocation(), QualType(), false);
+    return S.HandleExprPropertyRefExpr(OPT, BaseExpr.get(), OpLoc, MemberName,
+                                       MemberLoc, SourceLocation(), QualType(),
+                                       false);
   }
 
   // Handle 'field access' to vectors, such as 'V.xx'.
@@ -1522,24 +1502,22 @@
     // FIXME: this expr should store IsArrow.
     IdentifierInfo *Member = MemberName.getAsIdentifierInfo();
     ExprValueKind VK = (IsArrow ? VK_LValue : BaseExpr.get()->getValueKind());
-    QualType ret = CheckExtVectorComponent(*this, BaseType, VK, OpLoc,
+    QualType ret = CheckExtVectorComponent(S, BaseType, VK, OpLoc,
                                            Member, MemberLoc);
     if (ret.isNull())
       return ExprError();
 
-    return Owned(new (Context) ExtVectorElementExpr(ret, VK, BaseExpr.take(),
-                                                    *Member, MemberLoc));
+    return new (S.Context)
+        ExtVectorElementExpr(ret, VK, BaseExpr.get(), *Member, MemberLoc);
   }
 
   // Adjust builtin-sel to the appropriate redefinition type if that's
   // not just a pointer to builtin-sel again.
-  if (IsArrow &&
-      BaseType->isSpecificBuiltinType(BuiltinType::ObjCSel) &&
-      !Context.getObjCSelRedefinitionType()->isObjCSelType()) {
-    BaseExpr = ImpCastExprToType(BaseExpr.take(), 
-                                 Context.getObjCSelRedefinitionType(),
-                                 CK_BitCast);
-    return LookupMemberExpr(R, BaseExpr, IsArrow, OpLoc, SS,
+  if (IsArrow && BaseType->isSpecificBuiltinType(BuiltinType::ObjCSel) &&
+      !S.Context.getObjCSelRedefinitionType()->isObjCSelType()) {
+    BaseExpr = S.ImpCastExprToType(
+        BaseExpr.get(), S.Context.getObjCSelRedefinitionType(), CK_BitCast);
+    return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
                             ObjCImpDecl, HasTemplateArgs);
   }
 
@@ -1556,31 +1534,31 @@
   if (const PointerType *Ptr = BaseType->getAs<PointerType>()) {
     if (!IsArrow && Ptr->getPointeeType()->isRecordType() &&
         MemberName.getNameKind() != DeclarationName::CXXDestructorName) {
-      Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
-        << BaseType << int(IsArrow) << BaseExpr.get()->getSourceRange()
+      S.Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
+          << BaseType << int(IsArrow) << BaseExpr.get()->getSourceRange()
           << FixItHint::CreateReplacement(OpLoc, "->");
 
       // Recurse as an -> access.
       IsArrow = true;
-      return LookupMemberExpr(R, BaseExpr, IsArrow, OpLoc, SS,
+      return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
                               ObjCImpDecl, HasTemplateArgs);
     }
   }
 
   // If the user is trying to apply -> or . to a function name, it's probably
   // because they forgot parentheses to call that function.
-  if (tryToRecoverWithCall(BaseExpr,
-                           PDiag(diag::err_member_reference_needs_call),
-                           /*complain*/ false,
-                           IsArrow ? &isPointerToRecordType : &isRecordType)) {
+  if (S.tryToRecoverWithCall(
+          BaseExpr, S.PDiag(diag::err_member_reference_needs_call),
+          /*complain*/ false,
+          IsArrow ? &isPointerToRecordType : &isRecordType)) {
     if (BaseExpr.isInvalid())
       return ExprError();
-    BaseExpr = DefaultFunctionArrayConversion(BaseExpr.take());
-    return LookupMemberExpr(R, BaseExpr, IsArrow, OpLoc, SS,
+    BaseExpr = S.DefaultFunctionArrayConversion(BaseExpr.get());
+    return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
                             ObjCImpDecl, HasTemplateArgs);
   }
 
-  Diag(OpLoc, diag::err_typecheck_member_reference_struct_union)
+  S.Diag(OpLoc, diag::err_typecheck_member_reference_struct_union)
     << BaseType << BaseExpr.get()->getSourceRange() << MemberLoc;
 
   return ExprError();
@@ -1610,6 +1588,19 @@
   if (SS.isSet() && SS.isInvalid())
     return ExprError();
 
+  // The only way a reference to a destructor can be used is to
+  // immediately call it. If the next token is not a '(', produce
+  // a diagnostic and build the call now.
+  if (!HasTrailingLParen &&
+      Id.getKind() == UnqualifiedId::IK_DestructorName) {
+    ExprResult DtorAccess =
+        ActOnMemberAccessExpr(S, Base, OpLoc, OpKind, SS, TemplateKWLoc, Id,
+                              ObjCImpDecl, /*HasTrailingLParen*/true);
+    if (DtorAccess.isInvalid())
+      return DtorAccess;
+    return DiagnoseDtorReference(Id.getLocStart(), DtorAccess.get());
+  }
+
   // Warn about the explicit constructor calls Microsoft extension.
   if (getLangOpts().MicrosoftExt &&
       Id.getKind() == UnqualifiedId::IK_ConstructorName)
@@ -1628,54 +1619,25 @@
   bool IsArrow = (OpKind == tok::arrow);
 
   NamedDecl *FirstQualifierInScope
-    = (!SS.isSet() ? 0 : FindFirstQualifierInScope(S,
-                       static_cast<NestedNameSpecifier*>(SS.getScopeRep())));
+    = (!SS.isSet() ? nullptr : FindFirstQualifierInScope(S, SS.getScopeRep()));
 
   // This is a postfix expression, so get rid of ParenListExprs.
   ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Base);
   if (Result.isInvalid()) return ExprError();
-  Base = Result.take();
+  Base = Result.get();
 
   if (Base->getType()->isDependentType() || Name.isDependentName() ||
       isDependentScopeSpecifier(SS)) {
-    Result = ActOnDependentMemberExpr(Base, Base->getType(),
-                                      IsArrow, OpLoc,
-                                      SS, TemplateKWLoc, FirstQualifierInScope,
-                                      NameInfo, TemplateArgs);
-  } else {
-    LookupResult R(*this, NameInfo, LookupMemberName);
-    ExprResult BaseResult = Owned(Base);
-    Result = LookupMemberExpr(R, BaseResult, IsArrow, OpLoc,
-                              SS, ObjCImpDecl, TemplateArgs != 0);
-    if (BaseResult.isInvalid())
-      return ExprError();
-    Base = BaseResult.take();
-
-    if (Result.isInvalid()) {
-      Owned(Base);
-      return ExprError();
-    }
-
-    if (Result.get()) {
-      // The only way a reference to a destructor can be used is to
-      // immediately call it, which falls into this case.  If the
-      // next token is not a '(', produce a diagnostic and build the
-      // call now.
-      if (!HasTrailingLParen &&
-          Id.getKind() == UnqualifiedId::IK_DestructorName)
-        return DiagnoseDtorReference(NameInfo.getLoc(), Result.get());
-
-      return Result;
-    }
-
-    ActOnMemberAccessExtraArgs ExtraArgs = {S, Id, ObjCImpDecl, HasTrailingLParen};
-    Result = BuildMemberReferenceExpr(Base, Base->getType(),
-                                      OpLoc, IsArrow, SS, TemplateKWLoc,
-                                      FirstQualifierInScope, R, TemplateArgs,
-                                      false, &ExtraArgs);
+    return ActOnDependentMemberExpr(Base, Base->getType(), IsArrow, OpLoc, SS,
+                                    TemplateKWLoc, FirstQualifierInScope,
+                                    NameInfo, TemplateArgs);
   }
 
-  return Result;
+  ActOnMemberAccessExtraArgs ExtraArgs = {S, Id, ObjCImpDecl,
+                                          HasTrailingLParen};
+  return BuildMemberReferenceExpr(Base, Base->getType(), OpLoc, IsArrow, SS,
+                                  TemplateKWLoc, FirstQualifierInScope,
+                                  NameInfo, TemplateArgs, &ExtraArgs);
 }
 
 static ExprResult
@@ -1734,10 +1696,9 @@
                                   FoundDecl, Field);
   if (Base.isInvalid())
     return ExprError();
-  return S.Owned(BuildMemberExpr(S, S.Context, Base.take(), IsArrow, SS,
-                                 /*TemplateKWLoc=*/SourceLocation(),
-                                 Field, FoundDecl, MemberNameInfo,
-                                 MemberType, VK, OK));
+  return BuildMemberExpr(S, S.Context, Base.get(), IsArrow, SS,
+                         /*TemplateKWLoc=*/SourceLocation(), Field, FoundDecl,
+                         MemberNameInfo, MemberType, VK, OK);
 }
 
 /// Builds an implicit member access expression.  The current context
@@ -1753,21 +1714,14 @@
   assert(!R.empty() && !R.isAmbiguous());
   
   SourceLocation loc = R.getNameLoc();
-  
-  // We may have found a field within an anonymous union or struct
-  // (C++ [class.union]).
-  // FIXME: template-ids inside anonymous structs?
-  if (IndirectFieldDecl *FD = R.getAsSingle<IndirectFieldDecl>())
-    return BuildAnonymousStructUnionMemberReference(SS, R.getNameLoc(), FD,
-                                                    R.begin().getPair());
-  
+
   // If this is known to be an instance access, go ahead and build an
   // implicit 'this' expression now.
   // 'this' expression now.
   QualType ThisTy = getCurrentThisType();
   assert(!ThisTy.isNull() && "didn't correctly pre-flight capture of 'this'");
-  
-  Expr *baseExpr = 0; // null signifies implicit access
+
+  Expr *baseExpr = nullptr; // null signifies implicit access
   if (IsKnownInstance) {
     SourceLocation Loc = R.getNameLoc();
     if (SS.getRange().isValid())
@@ -1775,11 +1729,11 @@
     CheckCXXThisCapture(Loc);
     baseExpr = new (Context) CXXThisExpr(loc, ThisTy, /*isImplicit=*/true);
   }
-  
+
   return BuildMemberReferenceExpr(baseExpr, ThisTy,
                                   /*OpLoc*/ SourceLocation(),
                                   /*IsArrow*/ true,
                                   SS, TemplateKWLoc,
-                                  /*FirstQualifierInScope*/ 0,
+                                  /*FirstQualifierInScope*/ nullptr,
                                   R, TemplateArgs);
 }
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index cc8eace..5002332 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -67,10 +67,14 @@
 
     // Create the aggregate string with the appropriate content and location
     // information.
-    S = StringLiteral::Create(Context, StrBuf,
-                              StringLiteral::Ascii, /*Pascal=*/false,
-                              Context.getPointerType(Context.CharTy),
-                              &StrLocs[0], StrLocs.size());
+    const ConstantArrayType *CAT = Context.getAsConstantArrayType(S->getType());
+    assert(CAT && "String literal not of constant array type!");
+    QualType StrTy = Context.getConstantArrayType(
+        CAT->getElementType(), llvm::APInt(32, StrBuf.size() + 1),
+        CAT->getSizeModifier(), CAT->getIndexTypeCVRQualifiers());
+    S = StringLiteral::Create(Context, StrBuf, StringLiteral::Ascii,
+                              /*Pascal=*/false, StrTy, &StrLocs[0],
+                              StrLocs.size());
   }
   
   return BuildObjCStringLiteral(AtLocs[0], S);
@@ -89,7 +93,7 @@
   if (!Ty.isNull()) {
     Ty = Context.getObjCObjectPointerType(Ty);
   } else if (getLangOpts().NoConstantCFStrings) {
-    IdentifierInfo *NSIdent=0;
+    IdentifierInfo *NSIdent=nullptr;
     std::string StringClass(getLangOpts().ObjCConstantStringClass);
     
     if (StringClass.empty())
@@ -129,7 +133,7 @@
           ObjCInterfaceDecl::Create (Context, 
                                      Context.getTranslationUnitDecl(), 
                                      SourceLocation(), NSIdent, 
-                                     0, SourceLocation());
+                                     nullptr, SourceLocation());
         Ty = Context.getObjCInterfaceType(NSStringIDecl);
         Context.setObjCNSStringType(Ty);
       }
@@ -152,7 +156,7 @@
   }
 
   // Make sure the return type is reasonable.
-  QualType ReturnType = Method->getResultType();
+  QualType ReturnType = Method->getReturnType();
   if (!ReturnType->isObjCObjectPointerType()) {
     S.Diag(Loc, diag::err_objc_literal_method_sig)
       << Sel;
@@ -178,7 +182,7 @@
       S.Diag(Loc, diag::err_invalid_nsnumber_type)
         << NumberType << R;
     }
-    return 0;
+    return nullptr;
   }
   
   // If we already looked up this method, we're done.
@@ -204,15 +208,15 @@
         S.NSNumberDecl = ObjCInterfaceDecl::Create(CX,
                                                    CX.getTranslationUnitDecl(),
                                                    SourceLocation(), NSNumberId,
-                                                   0, SourceLocation());
+                                                   nullptr, SourceLocation());
       } else {
         // Otherwise, require a declaration of NSNumber.
         S.Diag(Loc, diag::err_undeclared_nsnumber);
-        return 0;
+        return nullptr;
       }
     } else if (!S.NSNumberDecl->hasDefinition()) {
       S.Diag(Loc, diag::err_undeclared_nsnumber);
-      return 0;
+      return nullptr;
     }
     
     // generate the pointer to NSNumber type.
@@ -224,26 +228,25 @@
   ObjCMethodDecl *Method = S.NSNumberDecl->lookupClassMethod(Sel);
   if (!Method && S.getLangOpts().DebuggerObjCLiteral) {
     // create a stub definition this NSNumber factory method.
-    TypeSourceInfo *ResultTInfo = 0;
-    Method = ObjCMethodDecl::Create(CX, SourceLocation(), SourceLocation(), Sel,
-                                    S.NSNumberPointer, ResultTInfo,
-                                    S.NSNumberDecl,
-                                    /*isInstance=*/false, /*isVariadic=*/false,
-                                    /*isPropertyAccessor=*/false,
-                                    /*isImplicitlyDeclared=*/true,
-                                    /*isDefined=*/false,
-                                    ObjCMethodDecl::Required,
-                                    /*HasRelatedResultType=*/false);
+    TypeSourceInfo *ReturnTInfo = nullptr;
+    Method =
+        ObjCMethodDecl::Create(CX, SourceLocation(), SourceLocation(), Sel,
+                               S.NSNumberPointer, ReturnTInfo, S.NSNumberDecl,
+                               /*isInstance=*/false, /*isVariadic=*/false,
+                               /*isPropertyAccessor=*/false,
+                               /*isImplicitlyDeclared=*/true,
+                               /*isDefined=*/false, ObjCMethodDecl::Required,
+                               /*HasRelatedResultType=*/false);
     ParmVarDecl *value = ParmVarDecl::Create(S.Context, Method,
                                              SourceLocation(), SourceLocation(),
                                              &CX.Idents.get("value"),
-                                             NumberType, /*TInfo=*/0, SC_None,
-                                             0);
+                                             NumberType, /*TInfo=*/nullptr,
+                                             SC_None, nullptr);
     Method->setMethodParams(S.Context, value, None);
   }
 
   if (!validateBoxingMethod(S, Loc, S.NSNumberDecl, Sel, Method))
-    return 0;
+    return nullptr;
 
   // Note: if the parameter type is out-of-line, we'll catch it later in the
   // implicit conversion.
@@ -288,12 +291,12 @@
     return ExprError();
 
   // Convert the number to the type that the parameter expects.
-  ParmVarDecl *ParamDecl = Method->param_begin()[0];
+  ParmVarDecl *ParamDecl = Method->parameters()[0];
   InitializedEntity Entity = InitializedEntity::InitializeParameter(Context,
                                                                     ParamDecl);
   ExprResult ConvertedNumber = PerformCopyInitialization(Entity,
                                                          SourceLocation(),
-                                                         Owned(Number));
+                                                         Number);
   if (ConvertedNumber.isInvalid())
     return ExprError();
   Number = ConvertedNumber.get();
@@ -441,10 +444,10 @@
 ExprResult Sema::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
   if (ValueExpr->isTypeDependent()) {
     ObjCBoxedExpr *BoxedExpr = 
-      new (Context) ObjCBoxedExpr(ValueExpr, Context.DependentTy, NULL, SR);
-    return Owned(BoxedExpr);
+      new (Context) ObjCBoxedExpr(ValueExpr, Context.DependentTy, nullptr, SR);
+    return BoxedExpr;
   }
-  ObjCMethodDecl *BoxingMethod = NULL;
+  ObjCMethodDecl *BoxingMethod = nullptr;
   QualType BoxedType;
   // Convert the expression to an RValue, so we can check for pointer types...
   ExprResult RValue = DefaultFunctionArrayLvalueConversion(ValueExpr);
@@ -470,7 +473,7 @@
             NSStringDecl = ObjCInterfaceDecl::Create(Context, TU,
                                                      SourceLocation(),
                                                      NSStringId,
-                                                     0, SourceLocation());
+                                                     nullptr, SourceLocation());
           } else {
             Diag(SR.getBegin(), diag::err_undeclared_nsstring);
             return ExprError();
@@ -492,25 +495,23 @@
         BoxingMethod = NSStringDecl->lookupClassMethod(stringWithUTF8String);
         if (!BoxingMethod && getLangOpts().DebuggerObjCLiteral) {
           // Debugger needs to work even if NSString hasn't been defined.
-          TypeSourceInfo *ResultTInfo = 0;
-          ObjCMethodDecl *M =
-            ObjCMethodDecl::Create(Context, SourceLocation(), SourceLocation(),
-                                   stringWithUTF8String, NSStringPointer,
-                                   ResultTInfo, NSStringDecl,
-                                   /*isInstance=*/false, /*isVariadic=*/false,
-                                   /*isPropertyAccessor=*/false,
-                                   /*isImplicitlyDeclared=*/true,
-                                   /*isDefined=*/false,
-                                   ObjCMethodDecl::Required,
-                                   /*HasRelatedResultType=*/false);
+          TypeSourceInfo *ReturnTInfo = nullptr;
+          ObjCMethodDecl *M = ObjCMethodDecl::Create(
+              Context, SourceLocation(), SourceLocation(), stringWithUTF8String,
+              NSStringPointer, ReturnTInfo, NSStringDecl,
+              /*isInstance=*/false, /*isVariadic=*/false,
+              /*isPropertyAccessor=*/false,
+              /*isImplicitlyDeclared=*/true,
+              /*isDefined=*/false, ObjCMethodDecl::Required,
+              /*HasRelatedResultType=*/false);
           QualType ConstCharType = Context.CharTy.withConst();
           ParmVarDecl *value =
             ParmVarDecl::Create(Context, M,
                                 SourceLocation(), SourceLocation(),
                                 &Context.Idents.get("value"),
                                 Context.getPointerType(ConstCharType),
-                                /*TInfo=*/0,
-                                SC_None, 0);
+                                /*TInfo=*/nullptr,
+                                SC_None, nullptr);
           M->setMethodParams(Context, value, None);
           BoxingMethod = M;
         }
@@ -554,7 +555,7 @@
         break;
       }
     }
-    
+    CheckForIntOverflow(ValueExpr);
     // FIXME:  Do I need to do anything special with BoolTy expressions?
     
     // Look for the appropriate method within NSNumber.
@@ -580,12 +581,12 @@
   }
   
   // Convert the expression to the type that the parameter requires.
-  ParmVarDecl *ParamDecl = BoxingMethod->param_begin()[0];
+  ParmVarDecl *ParamDecl = BoxingMethod->parameters()[0];
   InitializedEntity Entity = InitializedEntity::InitializeParameter(Context,
                                                                     ParamDecl);
   ExprResult ConvertedValueExpr = PerformCopyInitialization(Entity,
                                                             SourceLocation(),
-                                                            Owned(ValueExpr));
+                                                            ValueExpr);
   if (ConvertedValueExpr.isInvalid())
     return ExprError();
   ValueExpr = ConvertedValueExpr.get();
@@ -623,13 +624,9 @@
   BaseExpr = Result.get();
 
   // Build the pseudo-object expression.
-  return Owned(ObjCSubscriptRefExpr::Create(Context, 
-                                            BaseExpr,
-                                            IndexExpr,
-                                            Context.PseudoObjectTy,
-                                            getterMethod,
-                                            setterMethod, RB));
-  
+  return ObjCSubscriptRefExpr::Create(Context, BaseExpr, IndexExpr,
+                                      Context.PseudoObjectTy, getterMethod,
+                                      setterMethod, RB);
 }
 
 ExprResult Sema::BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements) {
@@ -645,7 +642,7 @@
                             Context.getTranslationUnitDecl(),
                             SourceLocation(),
                             NSAPIObj->getNSClassId(NSAPI::ClassId_NSArray),
-                            0, SourceLocation());
+                            nullptr, SourceLocation());
 
     if (!NSArrayDecl) {
       Diag(SR.getBegin(), diag::err_undeclared_nsarray);
@@ -660,31 +657,30 @@
       Sel = NSAPIObj->getNSArraySelector(NSAPI::NSArr_arrayWithObjectsCount);
     ObjCMethodDecl *Method = NSArrayDecl->lookupClassMethod(Sel);
     if (!Method && getLangOpts().DebuggerObjCLiteral) {
-      TypeSourceInfo *ResultTInfo = 0;
-      Method = ObjCMethodDecl::Create(Context,
-                           SourceLocation(), SourceLocation(), Sel,
-                           IdT,
-                           ResultTInfo,
-                           Context.getTranslationUnitDecl(),
-                           false /*Instance*/, false/*isVariadic*/,
-                           /*isPropertyAccessor=*/false,
-                           /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
-                           ObjCMethodDecl::Required,
-                           false);
+      TypeSourceInfo *ReturnTInfo = nullptr;
+      Method = ObjCMethodDecl::Create(
+          Context, SourceLocation(), SourceLocation(), Sel, IdT, ReturnTInfo,
+          Context.getTranslationUnitDecl(), false /*Instance*/,
+          false /*isVariadic*/,
+          /*isPropertyAccessor=*/false,
+          /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
+          ObjCMethodDecl::Required, false);
       SmallVector<ParmVarDecl *, 2> Params;
       ParmVarDecl *objects = ParmVarDecl::Create(Context, Method,
                                                  SourceLocation(),
                                                  SourceLocation(),
                                                  &Context.Idents.get("objects"),
                                                  Context.getPointerType(IdT),
-                                                 /*TInfo=*/0, SC_None, 0);
+                                                 /*TInfo=*/nullptr,
+                                                 SC_None, nullptr);
       Params.push_back(objects);
       ParmVarDecl *cnt = ParmVarDecl::Create(Context, Method,
                                              SourceLocation(),
                                              SourceLocation(),
                                              &Context.Idents.get("cnt"),
                                              Context.UnsignedLongTy,
-                                             /*TInfo=*/0, SC_None, 0);
+                                             /*TInfo=*/nullptr, SC_None,
+                                             nullptr);
       Params.push_back(cnt);
       Method->setMethodParams(Context, Params, None);
     }
@@ -693,13 +689,13 @@
       return ExprError();
 
     // Dig out the type that all elements should be converted to.
-    QualType T = Method->param_begin()[0]->getType();
+    QualType T = Method->parameters()[0]->getType();
     const PointerType *PtrT = T->getAs<PointerType>();
     if (!PtrT || 
         !Context.hasSameUnqualifiedType(PtrT->getPointeeType(), IdT)) {
       Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
         << Sel;
-      Diag(Method->param_begin()[0]->getLocation(),
+      Diag(Method->parameters()[0]->getLocation(),
            diag::note_objc_literal_method_param)
         << 0 << T 
         << Context.getPointerType(IdT.withConst());
@@ -707,13 +703,13 @@
     }
   
     // Check that the 'count' parameter is integral.
-    if (!Method->param_begin()[1]->getType()->isIntegerType()) {
+    if (!Method->parameters()[1]->getType()->isIntegerType()) {
       Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
         << Sel;
-      Diag(Method->param_begin()[1]->getLocation(),
+      Diag(Method->parameters()[1]->getLocation(),
            diag::note_objc_literal_method_param)
         << 1 
-        << Method->param_begin()[1]->getType()
+        << Method->parameters()[1]->getType()
         << "integral";
       return ExprError();
     }
@@ -722,7 +718,7 @@
     ArrayWithObjectsMethod = Method;
   }
 
-  QualType ObjectsType = ArrayWithObjectsMethod->param_begin()[0]->getType();
+  QualType ObjectsType = ArrayWithObjectsMethod->parameters()[0]->getType();
   QualType RequiredType = ObjectsType->castAs<PointerType>()->getPointeeType();
 
   // Check that each of the elements provided is valid in a collection literal,
@@ -761,7 +757,7 @@
                             Context.getTranslationUnitDecl(),
                             SourceLocation(),
                             NSAPIObj->getNSClassId(NSAPI::ClassId_NSDictionary),
-                            0, SourceLocation());
+                            nullptr, SourceLocation());
 
     if (!NSDictionaryDecl) {
       Diag(SR.getBegin(), diag::err_undeclared_nsdictionary);
@@ -780,7 +776,7 @@
       Method = ObjCMethodDecl::Create(Context,  
                            SourceLocation(), SourceLocation(), Sel,
                            IdT,
-                           0 /*TypeSourceInfo */,
+                           nullptr /*TypeSourceInfo */,
                            Context.getTranslationUnitDecl(),
                            false /*Instance*/, false/*isVariadic*/,
                            /*isPropertyAccessor=*/false,
@@ -793,21 +789,24 @@
                                                  SourceLocation(),
                                                  &Context.Idents.get("objects"),
                                                  Context.getPointerType(IdT),
-                                                 /*TInfo=*/0, SC_None, 0);
+                                                 /*TInfo=*/nullptr, SC_None,
+                                                 nullptr);
       Params.push_back(objects);
       ParmVarDecl *keys = ParmVarDecl::Create(Context, Method,
                                               SourceLocation(),
                                               SourceLocation(),
                                               &Context.Idents.get("keys"),
                                               Context.getPointerType(IdT),
-                                              /*TInfo=*/0, SC_None, 0);
+                                              /*TInfo=*/nullptr, SC_None,
+                                              nullptr);
       Params.push_back(keys);
       ParmVarDecl *cnt = ParmVarDecl::Create(Context, Method,
                                              SourceLocation(),
                                              SourceLocation(),
                                              &Context.Idents.get("cnt"),
                                              Context.UnsignedLongTy,
-                                             /*TInfo=*/0, SC_None, 0);
+                                             /*TInfo=*/nullptr, SC_None,
+                                             nullptr);
       Params.push_back(cnt);
       Method->setMethodParams(Context, Params, None);
     }
@@ -817,13 +816,13 @@
        return ExprError();
 
     // Dig out the type that all values should be converted to.
-    QualType ValueT = Method->param_begin()[0]->getType();
+    QualType ValueT = Method->parameters()[0]->getType();
     const PointerType *PtrValue = ValueT->getAs<PointerType>();
     if (!PtrValue || 
         !Context.hasSameUnqualifiedType(PtrValue->getPointeeType(), IdT)) {
       Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
         << Sel;
-      Diag(Method->param_begin()[0]->getLocation(),
+      Diag(Method->parameters()[0]->getLocation(),
            diag::note_objc_literal_method_param)
         << 0 << ValueT
         << Context.getPointerType(IdT.withConst());
@@ -831,7 +830,7 @@
     }
 
     // Dig out the type that all keys should be converted to.
-    QualType KeyT = Method->param_begin()[1]->getType();
+    QualType KeyT = Method->parameters()[1]->getType();
     const PointerType *PtrKey = KeyT->getAs<PointerType>();
     if (!PtrKey || 
         !Context.hasSameUnqualifiedType(PtrKey->getPointeeType(),
@@ -857,7 +856,7 @@
       if (err) {
         Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
           << Sel;
-        Diag(Method->param_begin()[1]->getLocation(),
+        Diag(Method->parameters()[1]->getLocation(),
              diag::note_objc_literal_method_param)
           << 1 << KeyT
           << Context.getPointerType(IdT.withConst());
@@ -866,11 +865,11 @@
     }
 
     // Check that the 'count' parameter is integral.
-    QualType CountType = Method->param_begin()[2]->getType();
+    QualType CountType = Method->parameters()[2]->getType();
     if (!CountType->isIntegerType()) {
       Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
         << Sel;
-      Diag(Method->param_begin()[2]->getLocation(),
+      Diag(Method->parameters()[2]->getLocation(),
            diag::note_objc_literal_method_param)
         << 2 << CountType
         << "integral";
@@ -881,9 +880,9 @@
     DictionaryWithObjectsMethod = Method;
   }
 
-  QualType ValuesT = DictionaryWithObjectsMethod->param_begin()[0]->getType();
+  QualType ValuesT = DictionaryWithObjectsMethod->parameters()[0]->getType();
   QualType ValueT = ValuesT->castAs<PointerType>()->getPointeeType();
-  QualType KeysT = DictionaryWithObjectsMethod->param_begin()[1]->getType();
+  QualType KeysT = DictionaryWithObjectsMethod->parameters()[1]->getType();
   QualType KeyT = KeysT->castAs<PointerType>()->getPointeeType();
 
   // Check that each of the keys and values provided is valid in a collection 
@@ -975,11 +974,68 @@
   return BuildObjCEncodeExpression(AtLoc, TInfo, RParenLoc);
 }
 
+static bool HelperToDiagnoseMismatchedMethodsInGlobalPool(Sema &S,
+                                               SourceLocation AtLoc,
+                                               SourceLocation LParenLoc,
+                                               SourceLocation RParenLoc,
+                                               ObjCMethodDecl *Method,
+                                               ObjCMethodList &MethList) {
+  ObjCMethodList *M = &MethList;
+  bool Warned = false;
+  for (M = M->getNext(); M; M=M->getNext()) {
+    ObjCMethodDecl *MatchingMethodDecl = M->Method;
+    if (MatchingMethodDecl == Method ||
+        isa<ObjCImplDecl>(MatchingMethodDecl->getDeclContext()) ||
+        MatchingMethodDecl->getSelector() != Method->getSelector())
+      continue;
+    if (!S.MatchTwoMethodDeclarations(Method,
+                                      MatchingMethodDecl, Sema::MMS_loose)) {
+      if (!Warned) {
+        Warned = true;
+        S.Diag(AtLoc, diag::warning_multiple_selectors)
+          << Method->getSelector() << FixItHint::CreateInsertion(LParenLoc, "(")
+          << FixItHint::CreateInsertion(RParenLoc, ")");
+        S.Diag(Method->getLocation(), diag::note_method_declared_at)
+          << Method->getDeclName();
+      }
+      S.Diag(MatchingMethodDecl->getLocation(), diag::note_method_declared_at)
+        << MatchingMethodDecl->getDeclName();
+    }
+  }
+  return Warned;
+}
+
+static void DiagnoseMismatchedSelectors(Sema &S, SourceLocation AtLoc,
+                                        ObjCMethodDecl *Method,
+                                        SourceLocation LParenLoc,
+                                        SourceLocation RParenLoc,
+                                        bool WarnMultipleSelectors) {
+  if (!WarnMultipleSelectors ||
+      S.Diags.isIgnored(diag::warning_multiple_selectors, SourceLocation()))
+    return;
+  bool Warned = false;
+  for (Sema::GlobalMethodPool::iterator b = S.MethodPool.begin(),
+       e = S.MethodPool.end(); b != e; b++) {
+    // first, instance methods
+    ObjCMethodList &InstMethList = b->second.first;
+    if (HelperToDiagnoseMismatchedMethodsInGlobalPool(S, AtLoc, LParenLoc, RParenLoc,
+                                                      Method, InstMethList))
+      Warned = true;
+        
+    // second, class methods
+    ObjCMethodList &ClsMethList = b->second.second;
+    if (HelperToDiagnoseMismatchedMethodsInGlobalPool(S, AtLoc, LParenLoc, RParenLoc,
+                                                      Method, ClsMethList) || Warned)
+      return;
+  }
+}
+
 ExprResult Sema::ParseObjCSelectorExpression(Selector Sel,
                                              SourceLocation AtLoc,
                                              SourceLocation SelLoc,
                                              SourceLocation LParenLoc,
-                                             SourceLocation RParenLoc) {
+                                             SourceLocation RParenLoc,
+                                             bool WarnMultipleSelectors) {
   ObjCMethodDecl *Method = LookupInstanceMethodInGlobalPool(Sel,
                              SourceRange(LParenLoc, RParenLoc), false, false);
   if (!Method)
@@ -996,10 +1052,13 @@
       
     } else
         Diag(SelLoc, diag::warn_undeclared_selector) << Sel;
-  }
+  } else
+    DiagnoseMismatchedSelectors(*this, AtLoc, Method, LParenLoc, RParenLoc,
+                                WarnMultipleSelectors);
   
-  if (!Method ||
-      Method->getImplementationControl() != ObjCMethodDecl::Optional) {
+  if (Method &&
+      Method->getImplementationControl() != ObjCMethodDecl::Optional &&
+      !getSourceManager().isInSystemHeader(Method->getLocation())) {
     llvm::DenseMap<Selector, SourceLocation>::iterator Pos
       = ReferencedSelectors.find(Sel);
     if (Pos == ReferencedSelectors.end())
@@ -1063,7 +1122,7 @@
   // still have a 'self', and we really do still need to capture it!
   ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(DC);
   if (!method)
-    return 0;
+    return nullptr;
 
   tryCaptureVariable(method->getSelfDecl(), Loc);
 
@@ -1120,7 +1179,8 @@
 static const ObjCMethodDecl *
 findExplicitInstancetypeDeclarer(const ObjCMethodDecl *MD,
                                  QualType instancetype) {
-  if (MD->getResultType() == instancetype) return MD;
+  if (MD->getReturnType() == instancetype)
+    return MD;
 
   // For these purposes, a method in an @implementation overrides a
   // declaration in the @interface.
@@ -1147,7 +1207,7 @@
       return result;
   }
 
-  return 0;
+  return nullptr;
 }
 
 void Sema::EmitRelatedResultTypeNoteForReturn(QualType destType) {
@@ -1155,7 +1215,7 @@
   // type doesn't match the method's declared return type.
   ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(CurContext);
   if (!MD || !MD->hasRelatedResultType() ||
-      Context.hasSameUnqualifiedType(destType, MD->getResultType()))
+      Context.hasSameUnqualifiedType(destType, MD->getReturnType()))
     return;
 
   // Look for a method overridden by this method which explicitly uses
@@ -1164,7 +1224,7 @@
         findExplicitInstancetypeDeclarer(MD, Context.getObjCInstanceType())) {
     SourceLocation loc;
     SourceRange range;
-    if (TypeSourceInfo *TSI = overridden->getResultTypeSourceInfo()) {
+    if (TypeSourceInfo *TSI = overridden->getReturnTypeSourceInfo()) {
       range = TSI->getTypeLoc().getSourceRange();
       loc = range.getBegin();
     }
@@ -1195,13 +1255,12 @@
   
   if (!Method->hasRelatedResultType())
     return;
-  
-  if (Context.hasSameUnqualifiedType(Method->getResultType()
-                                                        .getNonReferenceType(),
-                                     MsgSend->getType()))
+
+  if (Context.hasSameUnqualifiedType(
+          Method->getReturnType().getNonReferenceType(), MsgSend->getType()))
     return;
-  
-  if (!Context.hasSameUnqualifiedType(Method->getResultType(), 
+
+  if (!Context.hasSameUnqualifiedType(Method->getReturnType(),
                                       Context.getObjCInstanceType()))
     return;
   
@@ -1239,7 +1298,7 @@
       }
       if (result.isInvalid())
         return true;
-      Args[i] = result.take();
+      Args[i] = result.get();
     }
 
     unsigned DiagID;
@@ -1287,7 +1346,7 @@
 
   ReturnType = getMessageSendResultType(ReceiverType, Method, isClassMessage, 
                                         isSuperMessage);
-  VK = Expr::getValueKindForType(Method->getResultType());
+  VK = Expr::getValueKindForType(Method->getReturnType());
 
   unsigned NumNamedArgs = Sel.getNumArgs();
   // Method might have more arguments than selector indicates. This is due
@@ -1309,7 +1368,7 @@
 
     Expr *argExpr = Args[i];
 
-    ParmVarDecl *param = Method->param_begin()[i];
+    ParmVarDecl *param = Method->parameters()[i];
     assert(argExpr && "CheckMessageArgumentTypes(): missing expression");
 
     // Strip the unbridged-cast placeholder expression off unless it's
@@ -1326,7 +1385,7 @@
       if (argE.isInvalid()) {
         IsError = true;
       } else {
-        Args[i] = argE.take();
+        Args[i] = argE.get();
 
         // Update the parameter type in-place.
         param->setType(paramType);
@@ -1341,11 +1400,11 @@
 
     InitializedEntity Entity = InitializedEntity::InitializeParameter(Context,
                                                                       param);
-    ExprResult ArgE = PerformCopyInitialization(Entity, SelLoc, Owned(argExpr));
+    ExprResult ArgE = PerformCopyInitialization(Entity, SelLoc, argExpr);
     if (ArgE.isInvalid())
       IsError = true;
     else
-      Args[i] = ArgE.takeAs<Expr>();
+      Args[i] = ArgE.getAs<Expr>();
   }
 
   // Promote additional arguments to variadic methods.
@@ -1355,9 +1414,9 @@
         continue;
 
       ExprResult Arg = DefaultVariadicArgumentPromotion(Args[i], VariadicMethod,
-                                                        0);
+                                                        nullptr);
       IsError |= Arg.isInvalid();
-      Args[i] = Arg.take();
+      Args[i] = Arg.get();
     }
   } else {
     // Check for extra arguments to non-variadic methods.
@@ -1380,10 +1439,14 @@
   return IsError;
 }
 
-bool Sema::isSelfExpr(Expr *receiver) {
+bool Sema::isSelfExpr(Expr *RExpr) {
   // 'self' is objc 'self' in an objc method only.
-  ObjCMethodDecl *method =
-    dyn_cast_or_null<ObjCMethodDecl>(CurContext->getNonClosureAncestor());
+  ObjCMethodDecl *Method =
+      dyn_cast_or_null<ObjCMethodDecl>(CurContext->getNonClosureAncestor());
+  return isSelfExpr(RExpr, Method);
+}
+
+bool Sema::isSelfExpr(Expr *receiver, const ObjCMethodDecl *method) {
   if (!method) return false;
 
   receiver = receiver->IgnoreParenLValueCasts();
@@ -1409,12 +1472,11 @@
   }
 
   // Check qualifiers.
-  for (ObjCObjectType::qual_iterator
-         i = objType->qual_begin(), e = objType->qual_end(); i != e; ++i)
-    if (ObjCMethodDecl *method = (*i)->lookupMethod(sel, isInstance))
+  for (const auto *I : objType->quals())
+    if (ObjCMethodDecl *method = I->lookupMethod(sel, isInstance))
       return method;
 
-  return 0;
+  return nullptr;
 }
 
 /// LookupMethodInQualifiedType - Lookups up a method in protocol qualifier 
@@ -1423,15 +1485,13 @@
                                               const ObjCObjectPointerType *OPT,
                                               bool Instance)
 {
-  ObjCMethodDecl *MD = 0;
-  for (ObjCObjectPointerType::qual_iterator I = OPT->qual_begin(),
-       E = OPT->qual_end(); I != E; ++I) {
-    ObjCProtocolDecl *PROTO = (*I);
+  ObjCMethodDecl *MD = nullptr;
+  for (const auto *PROTO : OPT->quals()) {
     if ((MD = PROTO->lookupMethod(Sel, Instance))) {
       return MD;
     }
   }
-  return 0;
+  return nullptr;
 }
 
 static void DiagnoseARCUseOfWeakReceiver(Sema &S, Expr *Receiver) {
@@ -1444,15 +1504,15 @@
   Expr *RExpr = Receiver->IgnoreParenImpCasts();
   SourceLocation Loc = RExpr->getLocStart();
   QualType T = RExpr->getType();
-  const ObjCPropertyDecl *PDecl = 0;
-  const ObjCMethodDecl *GDecl = 0;
+  const ObjCPropertyDecl *PDecl = nullptr;
+  const ObjCMethodDecl *GDecl = nullptr;
   if (PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(RExpr)) {
     RExpr = POE->getSyntacticForm();
     if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(RExpr)) {
       if (PRE->isImplicitProperty()) {
         GDecl = PRE->getImplicitPropertyGetter();
         if (GDecl) {
-          T = GDecl->getResultType();
+          T = GDecl->getReturnType();
         }
       }
       else {
@@ -1525,37 +1585,29 @@
     if (DiagnoseUseOfDecl(PD, MemberLoc))
       return ExprError();
     if (Super)
-      return Owned(new (Context) ObjCPropertyRefExpr(PD, Context.PseudoObjectTy,
-                                                     VK_LValue, OK_ObjCProperty,
-                                                     MemberLoc, 
-                                                     SuperLoc, SuperType));
+      return new (Context)
+          ObjCPropertyRefExpr(PD, Context.PseudoObjectTy, VK_LValue,
+                              OK_ObjCProperty, MemberLoc, SuperLoc, SuperType);
     else
-      return Owned(new (Context) ObjCPropertyRefExpr(PD, Context.PseudoObjectTy,
-                                                     VK_LValue, OK_ObjCProperty,
-                                                     MemberLoc, BaseExpr));
+      return new (Context)
+          ObjCPropertyRefExpr(PD, Context.PseudoObjectTy, VK_LValue,
+                              OK_ObjCProperty, MemberLoc, BaseExpr);
   }
   // Check protocols on qualified interfaces.
-  for (ObjCObjectPointerType::qual_iterator I = OPT->qual_begin(),
-       E = OPT->qual_end(); I != E; ++I)
-    if (ObjCPropertyDecl *PD = (*I)->FindPropertyDeclaration(Member)) {
+  for (const auto *I : OPT->quals())
+    if (ObjCPropertyDecl *PD = I->FindPropertyDeclaration(Member)) {
       // Check whether we can reference this property.
       if (DiagnoseUseOfDecl(PD, MemberLoc))
         return ExprError();
 
       if (Super)
-        return Owned(new (Context) ObjCPropertyRefExpr(PD,
-                                                       Context.PseudoObjectTy,
-                                                       VK_LValue,
-                                                       OK_ObjCProperty,
-                                                       MemberLoc, 
-                                                       SuperLoc, SuperType));
+        return new (Context) ObjCPropertyRefExpr(
+            PD, Context.PseudoObjectTy, VK_LValue, OK_ObjCProperty, MemberLoc,
+            SuperLoc, SuperType);
       else
-        return Owned(new (Context) ObjCPropertyRefExpr(PD,
-                                                       Context.PseudoObjectTy,
-                                                       VK_LValue,
-                                                       OK_ObjCProperty,
-                                                       MemberLoc,
-                                                       BaseExpr));
+        return new (Context)
+            ObjCPropertyRefExpr(PD, Context.PseudoObjectTy, VK_LValue,
+                                OK_ObjCProperty, MemberLoc, BaseExpr);
     }
   // If that failed, look for an "implicit" property by seeing if the nullary
   // selector is implemented.
@@ -1601,24 +1653,21 @@
 
   if (Getter || Setter) {
     if (Super)
-      return Owned(new (Context) ObjCPropertyRefExpr(Getter, Setter,
-                                                     Context.PseudoObjectTy,
-                                                     VK_LValue, OK_ObjCProperty,
-                                                     MemberLoc,
-                                                     SuperLoc, SuperType));
+      return new (Context)
+          ObjCPropertyRefExpr(Getter, Setter, Context.PseudoObjectTy, VK_LValue,
+                              OK_ObjCProperty, MemberLoc, SuperLoc, SuperType);
     else
-      return Owned(new (Context) ObjCPropertyRefExpr(Getter, Setter,
-                                                     Context.PseudoObjectTy,
-                                                     VK_LValue, OK_ObjCProperty,
-                                                     MemberLoc, BaseExpr));
+      return new (Context)
+          ObjCPropertyRefExpr(Getter, Setter, Context.PseudoObjectTy, VK_LValue,
+                              OK_ObjCProperty, MemberLoc, BaseExpr);
 
   }
 
   // Attempt to correct for typos in property names.
   DeclFilterCCC<ObjCPropertyDecl> Validator;
   if (TypoCorrection Corrected = CorrectTypo(
-          DeclarationNameInfo(MemberName, MemberLoc), LookupOrdinaryName, NULL,
-          NULL, Validator, IFace, false, OPT)) {
+          DeclarationNameInfo(MemberName, MemberLoc), LookupOrdinaryName,
+          nullptr, nullptr, Validator, CTK_ErrorRecovery, IFace, false, OPT)) {
     diagnoseTypo(Corrected, PDiag(diag::err_property_not_found_suggest)
                               << MemberName << QualType(OPT, 0));
     DeclarationName TypoResult = Corrected.getCorrection();
@@ -1665,7 +1714,7 @@
                                                   receiverNameLoc);
 
   bool IsSuper = false;
-  if (IFace == 0) {
+  if (!IFace) {
     // If the "receiver" is 'super' in a method, handle it as an expression-like
     // property reference.
     if (receiverNamePtr->isStr("super")) {
@@ -1683,9 +1732,9 @@
           }
           QualType T = Context.getObjCInterfaceType(Super);
           T = Context.getObjCObjectPointerType(T);
-        
+
           return HandleExprPropertyRefExpr(T->getAsObjCInterfacePointerType(),
-                                           /*BaseExpr*/0, 
+                                           /*BaseExpr*/nullptr,
                                            SourceLocation()/*OpLoc*/, 
                                            &propertyName,
                                            propertyNameLoc,
@@ -1697,9 +1746,10 @@
         IFace = CurMethod->getClassInterface()->getSuperClass();
       }
     }
-    
-    if (IFace == 0) {
-      Diag(receiverNameLoc, diag::err_expected_ident_or_lparen);
+
+    if (!IFace) {
+      Diag(receiverNameLoc, diag::err_expected_either) << tok::identifier
+                                                       << tok::l_paren;
       return ExprError();
     }
   }
@@ -1710,10 +1760,7 @@
 
   // If this reference is in an @implementation, check for 'private' methods.
   if (!Getter)
-    if (ObjCMethodDecl *CurMeth = getCurMethodDecl())
-      if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
-        if (ObjCImplementationDecl *ImpDecl = ClassDecl->getImplementation())
-          Getter = ImpDecl->getClassMethod(Sel);
+    Getter = IFace->lookupPrivateClassMethod(Sel);
 
   if (Getter) {
     // FIXME: refactor/share with ActOnMemberReference().
@@ -1732,10 +1779,7 @@
   if (!Setter) {
     // If this reference is in an @implementation, also check for 'private'
     // methods.
-    if (ObjCMethodDecl *CurMeth = getCurMethodDecl())
-      if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
-        if (ObjCImplementationDecl *ImpDecl = ClassDecl->getImplementation())
-          Setter = ImpDecl->getClassMethod(SetterSel);
+    Setter = IFace->lookupPrivateClassMethod(SetterSel);
   }
   // Look through local category implementations associated with the class.
   if (!Setter)
@@ -1746,18 +1790,14 @@
 
   if (Getter || Setter) {
     if (IsSuper)
-    return Owned(new (Context) ObjCPropertyRefExpr(Getter, Setter,
-                                                   Context.PseudoObjectTy,
-                                                   VK_LValue, OK_ObjCProperty,
-                                                   propertyNameLoc,
-                                                   receiverNameLoc, 
-                                          Context.getObjCInterfaceType(IFace)));
+      return new (Context)
+          ObjCPropertyRefExpr(Getter, Setter, Context.PseudoObjectTy, VK_LValue,
+                              OK_ObjCProperty, propertyNameLoc, receiverNameLoc,
+                              Context.getObjCInterfaceType(IFace));
 
-    return Owned(new (Context) ObjCPropertyRefExpr(Getter, Setter,
-                                                   Context.PseudoObjectTy,
-                                                   VK_LValue, OK_ObjCProperty,
-                                                   propertyNameLoc,
-                                                   receiverNameLoc, IFace));
+    return new (Context) ObjCPropertyRefExpr(
+        Getter, Setter, Context.PseudoObjectTy, VK_LValue, OK_ObjCProperty,
+        propertyNameLoc, receiverNameLoc, IFace);
   }
   return ExprError(Diag(propertyNameLoc, diag::err_property_not_found)
                      << &propertyName << Context.getObjCInterfaceType(IFace));
@@ -1773,7 +1813,7 @@
       WantObjCSuper = Method->getClassInterface()->getSuperClass();
   }
 
-  virtual bool ValidateCandidate(const TypoCorrection &candidate) {
+  bool ValidateCandidate(const TypoCorrection &candidate) override {
     return candidate.getCorrectionDeclAs<ObjCInterfaceDecl>() ||
         candidate.isKeyword("super");
   }
@@ -1855,7 +1895,8 @@
   ObjCInterfaceOrSuperCCC Validator(getCurMethodDecl());
   if (TypoCorrection Corrected =
           CorrectTypo(Result.getLookupNameInfo(), Result.getLookupKind(), S,
-                      NULL, Validator, NULL, false, NULL, false)) {
+                      nullptr, Validator, CTK_ErrorRecovery, nullptr, false,
+                      nullptr, false)) {
     if (Corrected.isKeyword()) {
       // If we've found the keyword "super" (the only keyword that would be
       // returned by CorrectTypo), this is a send to super.
@@ -1918,16 +1959,16 @@
     // message to the superclass instance.
     QualType SuperTy = Context.getObjCInterfaceType(Super);
     SuperTy = Context.getObjCObjectPointerType(SuperTy);
-    return BuildInstanceMessage(0, SuperTy, SuperLoc,
-                                Sel, /*Method=*/0,
+    return BuildInstanceMessage(nullptr, SuperTy, SuperLoc,
+                                Sel, /*Method=*/nullptr,
                                 LBracLoc, SelectorLocs, RBracLoc, Args);
   }
   
   // Since we are in a class method, this is a class message to
   // the superclass.
-  return BuildClassMessage(/*ReceiverTypeInfo=*/0,
+  return BuildClassMessage(/*ReceiverTypeInfo=*/nullptr,
                            Context.getObjCInterfaceType(Super),
-                           SuperLoc, Sel, /*Method=*/0,
+                           SuperLoc, Sel, /*Method=*/nullptr,
                            LBracLoc, SelectorLocs, RBracLoc, Args);
 }
 
@@ -1938,7 +1979,7 @@
                                            Selector Sel,
                                            ObjCMethodDecl *Method,
                                            MultiExprArg Args) {
-  TypeSourceInfo *receiverTypeInfo = 0;
+  TypeSourceInfo *receiverTypeInfo = nullptr;
   if (!ReceiverType.isNull())
     receiverTypeInfo = Context.getTrivialTypeSourceInfo(ReceiverType);
 
@@ -1954,7 +1995,7 @@
                                bool (*refactor)(const ObjCMessageExpr *,
                                               const NSAPI &, edit::Commit &)) {
   SourceLocation MsgLoc = Msg->getExprLoc();
-  if (S.Diags.getDiagnosticLevel(DiagID, MsgLoc) == DiagnosticsEngine::Ignored)
+  if (S.Diags.isIgnored(DiagID, MsgLoc))
     return;
 
   SourceManager &SM = S.SourceMgr;
@@ -2050,15 +2091,14 @@
     unsigned NumArgs = ArgsIn.size();
     Expr **Args = ArgsIn.data();
     assert(SuperLoc.isInvalid() && "Message to super with dependent type");
-    return Owned(ObjCMessageExpr::Create(Context, ReceiverType,
-                                         VK_RValue, LBracLoc, ReceiverTypeInfo,
-                                         Sel, SelectorLocs, /*Method=*/0,
-                                         makeArrayRef(Args, NumArgs),RBracLoc,
-                                         isImplicit));
+    return ObjCMessageExpr::Create(
+        Context, ReceiverType, VK_RValue, LBracLoc, ReceiverTypeInfo, Sel,
+        SelectorLocs, /*Method=*/nullptr, makeArrayRef(Args, NumArgs), RBracLoc,
+        isImplicit);
   }
   
   // Find the class to which we are sending this message.
-  ObjCInterfaceDecl *Class = 0;
+  ObjCInterfaceDecl *Class = nullptr;
   const ObjCObjectType *ClassType = ReceiverType->getAs<ObjCObjectType>();
   if (!ClassType || !(Class = ClassType->getInterface())) {
     Diag(Loc, diag::err_invalid_receiver_class_message)
@@ -2110,8 +2150,8 @@
                                 ReturnType, VK))
     return ExprError();
 
-  if (Method && !Method->getResultType()->isVoidType() &&
-      RequireCompleteType(LBracLoc, Method->getResultType(), 
+  if (Method && !Method->getReturnType()->isVoidType() &&
+      RequireCompleteType(LBracLoc, Method->getReturnType(),
                           diag::err_illegal_message_expr_incomplete_type))
     return ExprError();
 
@@ -2154,8 +2194,9 @@
     ReceiverTypeInfo = Context.getTrivialTypeSourceInfo(ReceiverType, LBracLoc);
 
   return BuildClassMessage(ReceiverTypeInfo, ReceiverType, 
-                           /*SuperLoc=*/SourceLocation(), Sel, /*Method=*/0,
-                           LBracLoc, SelectorLocs, RBracLoc, Args);
+                           /*SuperLoc=*/SourceLocation(), Sel,
+                           /*Method=*/nullptr, LBracLoc, SelectorLocs, RBracLoc,
+                           Args);
 }
 
 ExprResult Sema::BuildInstanceMessageImplicit(Expr *Receiver,
@@ -2234,7 +2275,7 @@
       else
         Result = CheckPlaceholderExpr(Receiver);
       if (Result.isInvalid()) return ExprError();
-      Receiver = Result.take();
+      Receiver = Result.get();
     }
 
     if (Receiver->isTypeDependent()) {
@@ -2243,11 +2284,10 @@
       unsigned NumArgs = ArgsIn.size();
       Expr **Args = ArgsIn.data();
       assert(SuperLoc.isInvalid() && "Message to super with dependent type");
-      return Owned(ObjCMessageExpr::Create(Context, Context.DependentTy,
-                                           VK_RValue, LBracLoc, Receiver, Sel, 
-                                           SelectorLocs, /*Method=*/0,
-                                           makeArrayRef(Args, NumArgs),
-                                           RBracLoc, isImplicit));
+      return ObjCMessageExpr::Create(
+          Context, Context.DependentTy, VK_RValue, LBracLoc, Receiver, Sel,
+          SelectorLocs, /*Method=*/nullptr, makeArrayRef(Args, NumArgs),
+          RBracLoc, isImplicit);
     }
 
     // If necessary, apply function/array conversion to the receiver.
@@ -2255,7 +2295,7 @@
     ExprResult Result = DefaultFunctionArrayLvalueConversion(Receiver);
     if (Result.isInvalid())
       return ExprError();
-    Receiver = Result.take();
+    Receiver = Result.get();
     ReceiverType = Receiver->getType();
 
     // If the receiver is an ObjC pointer, a block pointer, or an
@@ -2274,14 +2314,14 @@
         << Receiver->getSourceRange();
       if (ReceiverType->isPointerType()) {
         Receiver = ImpCastExprToType(Receiver, Context.getObjCIdType(), 
-                                     CK_CPointerToObjCPointerCast).take();
+                                     CK_CPointerToObjCPointerCast).get();
       } else {
         // TODO: specialized warning on null receivers?
         bool IsNull = Receiver->isNullPointerConstant(Context,
                                               Expr::NPC_ValueDependentIsNull);
         CastKind Kind = IsNull ? CK_NullToPointer : CK_IntegralToPointer;
         Receiver = ImpCastExprToType(Receiver, Context.getObjCIdType(),
-                                     Kind).take();
+                                     Kind).get();
       }
       ReceiverType = Receiver->getType();
     } else if (getLangOpts().CPlusPlus) {
@@ -2292,7 +2332,7 @@
 
       ExprResult result = PerformContextuallyConvertToObjCPointer(Receiver);
       if (result.isUsable()) {
-        Receiver = result.take();
+        Receiver = result.get();
         ReceiverType = Receiver->getType();
       }
     }
@@ -2369,7 +2409,7 @@
         }
       }
     } else {
-      ObjCInterfaceDecl* ClassDecl = 0;
+      ObjCInterfaceDecl *ClassDecl = nullptr;
 
       // We allow sending a message to a qualified ID ("id<foo>"), which is ok as
       // long as one of the protocols implements the selector (if not, warn).
@@ -2389,7 +2429,7 @@
 
         // Try to complete the type. Under ARC, this is a hard error from which
         // we don't try to recover.
-        const ObjCInterfaceDecl *forwardClass = 0;
+        const ObjCInterfaceDecl *forwardClass = nullptr;
         if (RequireCompleteType(Loc, OCIType->getPointeeType(),
               getLangOpts().ObjCAutoRefCount
                 ? diag::err_arc_receiver_forward_instance
@@ -2402,7 +2442,7 @@
           forwardClass = OCIType->getInterfaceDecl();
           Diag(Receiver ? Receiver->getLocStart() 
                         : SuperLoc, diag::note_receiver_is_id);
-          Method = 0;
+          Method = nullptr;
         } else {
           Method = ClassDecl->lookupInstanceMethod(Sel);
         }
@@ -2447,6 +2487,52 @@
     }
   }
 
+  FunctionScopeInfo *DIFunctionScopeInfo =
+    (Method && Method->getMethodFamily() == OMF_init)
+      ? getEnclosingFunction() : nullptr;
+
+  if (DIFunctionScopeInfo &&
+      DIFunctionScopeInfo->ObjCIsDesignatedInit &&
+      (SuperLoc.isValid() || isSelfExpr(Receiver))) {
+    bool isDesignatedInitChain = false;
+    if (SuperLoc.isValid()) {
+      if (const ObjCObjectPointerType *
+            OCIType = ReceiverType->getAsObjCInterfacePointerType()) {
+        if (const ObjCInterfaceDecl *ID = OCIType->getInterfaceDecl()) {
+          // Either we know this is a designated initializer or we
+          // conservatively assume it because we don't know for sure.
+          if (!ID->declaresOrInheritsDesignatedInitializers() ||
+              ID->isDesignatedInitializer(Sel)) {
+            isDesignatedInitChain = true;
+            DIFunctionScopeInfo->ObjCWarnForNoDesignatedInitChain = false;
+          }
+        }
+      }
+    }
+    if (!isDesignatedInitChain) {
+      const ObjCMethodDecl *InitMethod = nullptr;
+      bool isDesignated =
+        getCurMethodDecl()->isDesignatedInitializerForTheInterface(&InitMethod);
+      assert(isDesignated && InitMethod);
+      (void)isDesignated;
+      Diag(SelLoc, SuperLoc.isValid() ?
+             diag::warn_objc_designated_init_non_designated_init_call :
+             diag::warn_objc_designated_init_non_super_designated_init_call);
+      Diag(InitMethod->getLocation(),
+           diag::note_objc_designated_init_marked_here);
+    }
+  }
+
+  if (DIFunctionScopeInfo &&
+      DIFunctionScopeInfo->ObjCIsSecondaryInit &&
+      (SuperLoc.isValid() || isSelfExpr(Receiver))) {
+    if (SuperLoc.isValid()) {
+      Diag(SelLoc, diag::warn_objc_secondary_init_super_init_call);
+    } else {
+      DIFunctionScopeInfo->ObjCWarnForNoInitDelegation = false;
+    }
+  }
+
   // Check the message arguments.
   unsigned NumArgs = ArgsIn.size();
   Expr **Args = ArgsIn.data();
@@ -2459,9 +2545,9 @@
                                 ClassMessage, SuperLoc.isValid(), 
                                 LBracLoc, RBracLoc, ReturnType, VK))
     return ExprError();
-  
-  if (Method && !Method->getResultType()->isVoidType() &&
-      RequireCompleteType(LBracLoc, Method->getResultType(), 
+
+  if (Method && !Method->getReturnType()->isVoidType() &&
+      RequireCompleteType(LBracLoc, Method->getReturnType(),
                           diag::err_illegal_message_expr_incomplete_type))
     return ExprError();
 
@@ -2562,7 +2648,14 @@
   }
 
   if (getLangOpts().ObjCAutoRefCount) {
-    DiagnoseARCUseOfWeakReceiver(*this, Receiver);
+    // Do not warn about IBOutlet weak property receivers being set to null
+    // as this cannot asynchronously happen.
+    bool WarnWeakReceiver = true;
+    if (isImplicit && Method)
+      if (const ObjCPropertyDecl *PropertyDecl = Method->findPropertyDecl())
+        WarnWeakReceiver = !PropertyDecl->hasAttr<IBOutletAttr>();
+    if (WarnWeakReceiver)
+      DiagnoseARCUseOfWeakReceiver(*this, Receiver);
     
     // In ARC, annotate delegate init calls.
     if (Result->getMethodFamily() == OMF_init &&
@@ -2574,7 +2667,7 @@
         // The implicit assignment to self means we also don't want to
         // consume the result.
         Result->setDelegateInitCall(true);
-        return Owned(Result);
+        return Result;
       }
     }
 
@@ -2588,19 +2681,13 @@
           Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_weak;
         if (!IsWeak && Sel.isUnarySelector())
           IsWeak = ReturnType.getObjCLifetime() & Qualifiers::OCL_Weak;
-
-        if (IsWeak) {
-          DiagnosticsEngine::Level Level =
-            Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak,
-                                     LBracLoc);
-          if (Level != DiagnosticsEngine::Ignored)
-            getCurFunction()->recordUseOfWeak(Result, Prop);
-
-        }
+        if (IsWeak &&
+            !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, LBracLoc))
+          getCurFunction()->recordUseOfWeak(Result, Prop);
       }
     }
   }
-      
+  
   return MaybeBindToTemporary(Result);
 }
 
@@ -2633,7 +2720,7 @@
   if (isa<ParenListExpr>(Receiver)) {
     ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Receiver);
     if (Result.isInvalid()) return ExprError();
-    Receiver = Result.take();
+    Receiver = Result.get();
   }
   
   if (RespondsToSelectorSel.isNull()) {
@@ -2642,10 +2729,11 @@
   }
   if (Sel == RespondsToSelectorSel)
     RemoveSelectorFromWarningCache(*this, Args[0]);
-    
+
   return BuildInstanceMessage(Receiver, Receiver->getType(),
-                              /*SuperLoc=*/SourceLocation(), Sel, /*Method=*/0, 
-                              LBracLoc, SelectorLocs, RBracLoc, Args);
+                              /*SuperLoc=*/SourceLocation(), Sel,
+                              /*Method=*/nullptr, LBracLoc, SelectorLocs,
+                              RBracLoc, Args);
 }
 
 enum ARCConversionTypeClass {
@@ -2859,7 +2947,7 @@
 
     ACCResult checkCallToFunction(FunctionDecl *fn) {
       // Require a CF*Ref return type.
-      if (!isCFType(fn->getResultType()))
+      if (!isCFType(fn->getReturnType()))
         return ACC_invalid;
 
       if (!isAnyRetainable(TargetClass))
@@ -2912,7 +3000,7 @@
       // Check for message sends to functions returning CF types.  We
       // just obey the Cocoa conventions with these, even though the
       // return type is CF.
-      if (!isAnyRetainable(TargetClass) || !isCFType(method->getResultType()))
+      if (!isAnyRetainable(TargetClass) || !isCFType(method->getReturnType()))
         return ACC_invalid;
       
       // If the method is explicitly marked not-retained, it's +0.
@@ -3045,6 +3133,31 @@
   }
 }
 
+template <typename T>
+static inline T *getObjCBridgeAttr(const TypedefType *TD) {
+  TypedefNameDecl *TDNDecl = TD->getDecl();
+  QualType QT = TDNDecl->getUnderlyingType();
+  if (QT->isPointerType()) {
+    QT = QT->getPointeeType();
+    if (const RecordType *RT = QT->getAs<RecordType>())
+      if (RecordDecl *RD = RT->getDecl()->getMostRecentDecl())
+        return RD->getAttr<T>();
+  }
+  return nullptr;
+}
+
+static ObjCBridgeRelatedAttr *ObjCBridgeRelatedAttrFromType(QualType T,
+                                                            TypedefNameDecl *&TDNDecl) {
+  while (const TypedefType *TD = dyn_cast<TypedefType>(T.getTypePtr())) {
+    TDNDecl = TD->getDecl();
+    if (ObjCBridgeRelatedAttr *ObjCBAttr =
+        getObjCBridgeAttr<ObjCBridgeRelatedAttr>(TD))
+      return ObjCBAttr;
+    T = TDNDecl->getUnderlyingType();
+  }
+  return nullptr;
+}
+
 static void
 diagnoseObjCARCConversion(Sema &S, SourceRange castRange,
                           QualType castType, ARCConversionTypeClass castACTC,
@@ -3059,6 +3172,12 @@
     return;
 
   QualType castExprType = castExpr->getType();
+  TypedefNameDecl *TDNDecl = nullptr;
+  if ((castACTC == ACTC_coreFoundation &&  exprACTC == ACTC_retainable &&
+       ObjCBridgeRelatedAttrFromType(castType, TDNDecl)) ||
+      (exprACTC == ACTC_coreFoundation && castACTC == ACTC_retainable &&
+       ObjCBridgeRelatedAttrFromType(castExprType, TDNDecl)))
+    return;
   
   unsigned srcKind = 0;
   switch (exprACTC) {
@@ -3099,9 +3218,10 @@
       DiagnosticBuilder DiagB = 
         (CCK != Sema::CCK_OtherCast) ? S.Diag(noteLoc, diag::note_arc_bridge)
                               : S.Diag(noteLoc, diag::note_arc_cstyle_bridge);
-      
+
       addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,
-                                   castType, castExpr, realCast, "__bridge ", 0);
+                                   castType, castExpr, realCast, "__bridge ",
+                                   nullptr);
     }
     if (CreateRule != ACC_plusZero)
     {
@@ -3111,15 +3231,15 @@
           S.Diag(br ? castExpr->getExprLoc() : noteLoc,
                  diag::note_arc_bridge_transfer)
             << castExprType << br;
-      
+
       addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,
                                    castType, castExpr, realCast, "__bridge_transfer ",
-                                   br ? "CFBridgingRelease" : 0);
+                                   br ? "CFBridgingRelease" : nullptr);
     }
 
     return;
   }
-    
+  
   // Bridge from a CF type to an ARC type.
   if (exprACTC == ACTC_retainable && isAnyRetainable(castACTC)) {
     bool br = S.isKnownName("CFBridgingRetain");
@@ -3140,7 +3260,8 @@
       (CCK != Sema::CCK_OtherCast) ? S.Diag(noteLoc, diag::note_arc_bridge)
                                : S.Diag(noteLoc, diag::note_arc_cstyle_bridge);
       addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,
-                                   castType, castExpr, realCast, "__bridge ", 0);
+                                   castType, castExpr, realCast, "__bridge ",
+                                   nullptr);
     }
     if (CreateRule != ACC_plusZero)
     {
@@ -3150,10 +3271,10 @@
           S.Diag(br ? castExpr->getExprLoc() : noteLoc,
                  diag::note_arc_bridge_retained)
             << castType << br;
-      
+
       addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,
                                    castType, castExpr, realCast, "__bridge_retained ",
-                                   br ? "CFBridgingRetain" : 0);
+                                   br ? "CFBridgingRetain" : nullptr);
     }
 
     return;
@@ -3165,26 +3286,17 @@
     << castRange << castExpr->getSourceRange();
 }
 
-static inline ObjCBridgeAttr *getObjCBridgeAttr(const TypedefType *TD) {
-  TypedefNameDecl *TDNDecl = TD->getDecl();
-  QualType QT = TDNDecl->getUnderlyingType();
-  if (QT->isPointerType()) {
-    QT = QT->getPointeeType();
-    if (const RecordType *RT = QT->getAs<RecordType>())
-      if (RecordDecl *RD = RT->getDecl())
-        if (RD->hasAttr<ObjCBridgeAttr>())
-          return RD->getAttr<ObjCBridgeAttr>();
-  }
-  return 0;
-}
-
-static bool CheckObjCBridgeNSCast(Sema &S, QualType castType, Expr *castExpr) {
+template <typename TB>
+static bool CheckObjCBridgeNSCast(Sema &S, QualType castType, Expr *castExpr,
+                                  bool &HadTheAttribute, bool warn) {
   QualType T = castExpr->getType();
+  HadTheAttribute = false;
   while (const TypedefType *TD = dyn_cast<TypedefType>(T.getTypePtr())) {
     TypedefNameDecl *TDNDecl = TD->getDecl();
-    if (ObjCBridgeAttr *ObjCBAttr = getObjCBridgeAttr(TD)) {
+    if (TB *ObjCBAttr = getObjCBridgeAttr<TB>(TD)) {
       if (IdentifierInfo *Parm = ObjCBAttr->getBridgedType()) {
-        NamedDecl *Target = 0;
+        HadTheAttribute = true;
+        NamedDecl *Target = nullptr;
         // Check for an existing type with this name.
         LookupResult R(S, DeclarationName(Parm), SourceLocation(),
                        Sema::LookupOrdinaryName);
@@ -3196,39 +3308,56 @@
                   castType->getAsObjCInterfacePointerType()) {
               ObjCInterfaceDecl *CastClass
                 = InterfacePointerType->getObjectType()->getInterface();
-              if ((CastClass == ExprClass) || (CastClass && ExprClass->isSuperClassOf(CastClass)))
+              if ((CastClass == ExprClass) ||
+                  (CastClass && ExprClass->isSuperClassOf(CastClass)))
                 return true;
-              S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge)
-                << T << Target->getName() << castType->getPointeeType();
+              if (warn)
+                S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge)
+                  << T << Target->getName() << castType->getPointeeType();
+              return false;
+            } else if (castType->isObjCIdType() ||
+                       (S.Context.ObjCObjectAdoptsQTypeProtocols(
+                          castType, ExprClass)))
+              // ok to cast to 'id'.
+              // casting to id<p-list> is ok if bridge type adopts all of
+              // p-list protocols.
               return true;
-            } else {
-              S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge)
-                << T << Target->getName() << castType;
-              return true;
+            else {
+              if (warn) {
+                S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge)
+                  << T << Target->getName() << castType;
+                S.Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+                S.Diag(Target->getLocStart(), diag::note_declared_at);
+              }
+              return false;
            }
           }
         }
         S.Diag(castExpr->getLocStart(), diag::err_objc_cf_bridged_not_interface)
-        << castExpr->getType() << Parm->getName();
+          << castExpr->getType() << Parm;
         S.Diag(TDNDecl->getLocStart(), diag::note_declared_at);
         if (Target)
           S.Diag(Target->getLocStart(), diag::note_declared_at);
+        return true;
       }
-      return true;
+      return false;
     }
     T = TDNDecl->getUnderlyingType();
   }
-  return false;
+  return true;
 }
 
-// (CFErrorRef)ns
-static bool CheckObjCBridgeCFCast(Sema &S, QualType castType, Expr *castExpr) {
+template <typename TB>
+static bool CheckObjCBridgeCFCast(Sema &S, QualType castType, Expr *castExpr,
+                                  bool &HadTheAttribute, bool warn) {
   QualType T = castType;
+  HadTheAttribute = false;
   while (const TypedefType *TD = dyn_cast<TypedefType>(T.getTypePtr())) {
     TypedefNameDecl *TDNDecl = TD->getDecl();
-    if (ObjCBridgeAttr *ObjCBAttr = getObjCBridgeAttr(TD)) {
+    if (TB *ObjCBAttr = getObjCBridgeAttr<TB>(TD)) {
       if (IdentifierInfo *Parm = ObjCBAttr->getBridgedType()) {
-        NamedDecl *Target = 0;
+        HadTheAttribute = true;
+        NamedDecl *Target = nullptr;
         // Check for an existing type with this name.
         LookupResult R(S, DeclarationName(Parm), SourceLocation(),
                        Sema::LookupOrdinaryName);
@@ -3240,17 +3369,30 @@
                   castExpr->getType()->getAsObjCInterfacePointerType()) {
               ObjCInterfaceDecl *ExprClass
                 = InterfacePointerType->getObjectType()->getInterface();
-              if ((CastClass == ExprClass) || (ExprClass && CastClass->isSuperClassOf(ExprClass)))
+              if ((CastClass == ExprClass) ||
+                  (ExprClass && CastClass->isSuperClassOf(ExprClass)))
                 return true;
-              S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge_to_cf)
-                << castExpr->getType()->getPointeeType() << T;
-              S.Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+              if (warn) {
+                S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge_to_cf)
+                  << castExpr->getType()->getPointeeType() << T;
+                S.Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+              }
+              return false;
+            } else if (castExpr->getType()->isObjCIdType() ||
+                       (S.Context.QIdProtocolsAdoptObjCObjectProtocols(
+                          castExpr->getType(), CastClass)))
+              // ok to cast an 'id' expression to a CFtype.
+              // ok to cast an 'id<plist>' expression to CFtype provided plist
+              // adopts all of CFtype's ObjetiveC's class plist.
               return true;
-            } else {
-              S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge_to_cf)
-                << castExpr->getType() << castType;
-              S.Diag(TDNDecl->getLocStart(), diag::note_declared_at);
-              return true;
+            else {
+              if (warn) {
+                S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge_to_cf)
+                  << castExpr->getType() << castType;
+                S.Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+                S.Diag(Target->getLocStart(), diag::note_declared_at);
+              }
+              return false;
             }
           }
         }
@@ -3259,18 +3401,262 @@
         S.Diag(TDNDecl->getLocStart(), diag::note_declared_at);
         if (Target)
           S.Diag(Target->getLocStart(), diag::note_declared_at);
+        return true;
       }
-      return true;
+      return false;
     }
     T = TDNDecl->getUnderlyingType();
   }
+  return true;
+}
+
+void Sema::CheckTollFreeBridgeCast(QualType castType, Expr *castExpr) {
+  if (!getLangOpts().ObjC1)
+    return;
+  // warn in presence of __bridge casting to or from a toll free bridge cast.
+  ARCConversionTypeClass exprACTC = classifyTypeForARCConversion(castExpr->getType());
+  ARCConversionTypeClass castACTC = classifyTypeForARCConversion(castType);
+  if (castACTC == ACTC_retainable && exprACTC == ACTC_coreFoundation) {
+    bool HasObjCBridgeAttr;
+    bool ObjCBridgeAttrWillNotWarn =
+      CheckObjCBridgeNSCast<ObjCBridgeAttr>(*this, castType, castExpr, HasObjCBridgeAttr,
+                                            false);
+    if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr)
+      return;
+    bool HasObjCBridgeMutableAttr;
+    bool ObjCBridgeMutableAttrWillNotWarn =
+      CheckObjCBridgeNSCast<ObjCBridgeMutableAttr>(*this, castType, castExpr,
+                                                   HasObjCBridgeMutableAttr, false);
+    if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr)
+      return;
+    
+    if (HasObjCBridgeAttr)
+      CheckObjCBridgeNSCast<ObjCBridgeAttr>(*this, castType, castExpr, HasObjCBridgeAttr,
+                                            true);
+    else if (HasObjCBridgeMutableAttr)
+      CheckObjCBridgeNSCast<ObjCBridgeMutableAttr>(*this, castType, castExpr,
+                                                   HasObjCBridgeMutableAttr, true);
+  }
+  else if (castACTC == ACTC_coreFoundation && exprACTC == ACTC_retainable) {
+    bool HasObjCBridgeAttr;
+    bool ObjCBridgeAttrWillNotWarn =
+      CheckObjCBridgeCFCast<ObjCBridgeAttr>(*this, castType, castExpr, HasObjCBridgeAttr,
+                                            false);
+    if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr)
+      return;
+    bool HasObjCBridgeMutableAttr;
+    bool ObjCBridgeMutableAttrWillNotWarn =
+      CheckObjCBridgeCFCast<ObjCBridgeMutableAttr>(*this, castType, castExpr,
+                                                   HasObjCBridgeMutableAttr, false);
+    if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr)
+      return;
+    
+    if (HasObjCBridgeAttr)
+      CheckObjCBridgeCFCast<ObjCBridgeAttr>(*this, castType, castExpr, HasObjCBridgeAttr,
+                                            true);
+    else if (HasObjCBridgeMutableAttr)
+      CheckObjCBridgeCFCast<ObjCBridgeMutableAttr>(*this, castType, castExpr,
+                                                   HasObjCBridgeMutableAttr, true);
+  }
+}
+
+void Sema::CheckObjCBridgeRelatedCast(QualType castType, Expr *castExpr) {
+  QualType SrcType = castExpr->getType();
+  if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(castExpr)) {
+    if (PRE->isExplicitProperty()) {
+      if (ObjCPropertyDecl *PDecl = PRE->getExplicitProperty())
+        SrcType = PDecl->getType();
+    }
+    else if (PRE->isImplicitProperty()) {
+      if (ObjCMethodDecl *Getter = PRE->getImplicitPropertyGetter())
+        SrcType = Getter->getReturnType();
+      
+    }
+  }
+  
+  ARCConversionTypeClass srcExprACTC = classifyTypeForARCConversion(SrcType);
+  ARCConversionTypeClass castExprACTC = classifyTypeForARCConversion(castType);
+  if (srcExprACTC != ACTC_retainable || castExprACTC != ACTC_coreFoundation)
+    return;
+  CheckObjCBridgeRelatedConversions(castExpr->getLocStart(),
+                                    castType, SrcType, castExpr);
+  return;
+}
+
+bool Sema::CheckTollFreeBridgeStaticCast(QualType castType, Expr *castExpr,
+                                         CastKind &Kind) {
+  if (!getLangOpts().ObjC1)
+    return false;
+  ARCConversionTypeClass exprACTC =
+    classifyTypeForARCConversion(castExpr->getType());
+  ARCConversionTypeClass castACTC = classifyTypeForARCConversion(castType);
+  if ((castACTC == ACTC_retainable && exprACTC == ACTC_coreFoundation) ||
+      (castACTC == ACTC_coreFoundation && exprACTC == ACTC_retainable)) {
+    CheckTollFreeBridgeCast(castType, castExpr);
+    Kind = (castACTC == ACTC_coreFoundation) ? CK_BitCast
+                                             : CK_CPointerToObjCPointerCast;
+    return true;
+  }
+  return false;
+}
+
+bool Sema::checkObjCBridgeRelatedComponents(SourceLocation Loc,
+                                            QualType DestType, QualType SrcType,
+                                            ObjCInterfaceDecl *&RelatedClass,
+                                            ObjCMethodDecl *&ClassMethod,
+                                            ObjCMethodDecl *&InstanceMethod,
+                                            TypedefNameDecl *&TDNDecl,
+                                            bool CfToNs) {
+  QualType T = CfToNs ? SrcType : DestType;
+  ObjCBridgeRelatedAttr *ObjCBAttr = ObjCBridgeRelatedAttrFromType(T, TDNDecl);
+  if (!ObjCBAttr)
+    return false;
+  
+  IdentifierInfo *RCId = ObjCBAttr->getRelatedClass();
+  IdentifierInfo *CMId = ObjCBAttr->getClassMethod();
+  IdentifierInfo *IMId = ObjCBAttr->getInstanceMethod();
+  if (!RCId)
+    return false;
+  NamedDecl *Target = nullptr;
+  // Check for an existing type with this name.
+  LookupResult R(*this, DeclarationName(RCId), SourceLocation(),
+                 Sema::LookupOrdinaryName);
+  if (!LookupName(R, TUScope)) {
+    Diag(Loc, diag::err_objc_bridged_related_invalid_class) << RCId
+          << SrcType << DestType;
+    Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+    return false;
+  }
+  Target = R.getFoundDecl();
+  if (Target && isa<ObjCInterfaceDecl>(Target))
+    RelatedClass = cast<ObjCInterfaceDecl>(Target);
+  else {
+    Diag(Loc, diag::err_objc_bridged_related_invalid_class_name) << RCId
+          << SrcType << DestType;
+    Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+    if (Target)
+      Diag(Target->getLocStart(), diag::note_declared_at);
+    return false;
+  }
+      
+  // Check for an existing class method with the given selector name.
+  if (CfToNs && CMId) {
+    Selector Sel = Context.Selectors.getUnarySelector(CMId);
+    ClassMethod = RelatedClass->lookupMethod(Sel, false);
+    if (!ClassMethod) {
+      Diag(Loc, diag::err_objc_bridged_related_known_method)
+            << SrcType << DestType << Sel << false;
+      Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+      return false;
+    }
+  }
+      
+  // Check for an existing instance method with the given selector name.
+  if (!CfToNs && IMId) {
+    Selector Sel = Context.Selectors.getNullarySelector(IMId);
+    InstanceMethod = RelatedClass->lookupMethod(Sel, true);
+    if (!InstanceMethod) {
+      Diag(Loc, diag::err_objc_bridged_related_known_method)
+            << SrcType << DestType << Sel << true;
+      Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+      return false;
+    }
+  }
+  return true;
+}
+
+bool
+Sema::CheckObjCBridgeRelatedConversions(SourceLocation Loc,
+                                        QualType DestType, QualType SrcType,
+                                        Expr *&SrcExpr) {
+  ARCConversionTypeClass rhsExprACTC = classifyTypeForARCConversion(SrcType);
+  ARCConversionTypeClass lhsExprACTC = classifyTypeForARCConversion(DestType);
+  bool CfToNs = (rhsExprACTC == ACTC_coreFoundation && lhsExprACTC == ACTC_retainable);
+  bool NsToCf = (rhsExprACTC == ACTC_retainable && lhsExprACTC == ACTC_coreFoundation);
+  if (!CfToNs && !NsToCf)
+    return false;
+  
+  ObjCInterfaceDecl *RelatedClass;
+  ObjCMethodDecl *ClassMethod = nullptr;
+  ObjCMethodDecl *InstanceMethod = nullptr;
+  TypedefNameDecl *TDNDecl = nullptr;
+  if (!checkObjCBridgeRelatedComponents(Loc, DestType, SrcType, RelatedClass,
+                                        ClassMethod, InstanceMethod, TDNDecl, CfToNs))
+    return false;
+  
+  if (CfToNs) {
+    // Implicit conversion from CF to ObjC object is needed.
+    if (ClassMethod) {
+      std::string ExpressionString = "[";
+      ExpressionString += RelatedClass->getNameAsString();
+      ExpressionString += " ";
+      ExpressionString += ClassMethod->getSelector().getAsString();
+      SourceLocation SrcExprEndLoc = PP.getLocForEndOfToken(SrcExpr->getLocEnd());
+      // Provide a fixit: [RelatedClass ClassMethod SrcExpr]
+      Diag(Loc, diag::err_objc_bridged_related_known_method)
+        << SrcType << DestType << ClassMethod->getSelector() << false
+        << FixItHint::CreateInsertion(SrcExpr->getLocStart(), ExpressionString)
+        << FixItHint::CreateInsertion(SrcExprEndLoc, "]");
+      Diag(RelatedClass->getLocStart(), diag::note_declared_at);
+      Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+      
+      QualType receiverType =
+        Context.getObjCInterfaceType(RelatedClass);
+      // Argument.
+      Expr *args[] = { SrcExpr };
+      ExprResult msg = BuildClassMessageImplicit(receiverType, false,
+                                      ClassMethod->getLocation(),
+                                      ClassMethod->getSelector(), ClassMethod,
+                                      MultiExprArg(args, 1));
+      SrcExpr = msg.get();
+      return true;
+    }
+  }
+  else {
+    // Implicit conversion from ObjC type to CF object is needed.
+    if (InstanceMethod) {
+      std::string ExpressionString;
+      SourceLocation SrcExprEndLoc = PP.getLocForEndOfToken(SrcExpr->getLocEnd());
+      if (InstanceMethod->isPropertyAccessor())
+        if (const ObjCPropertyDecl *PDecl = InstanceMethod->findPropertyDecl()) {
+          // fixit: ObjectExpr.propertyname when it is  aproperty accessor.
+          ExpressionString = ".";
+          ExpressionString += PDecl->getNameAsString();
+          Diag(Loc, diag::err_objc_bridged_related_known_method)
+          << SrcType << DestType << InstanceMethod->getSelector() << true
+          << FixItHint::CreateInsertion(SrcExprEndLoc, ExpressionString);
+        }
+      if (ExpressionString.empty()) {
+        // Provide a fixit: [ObjectExpr InstanceMethod]
+        ExpressionString = " ";
+        ExpressionString += InstanceMethod->getSelector().getAsString();
+        ExpressionString += "]";
+      
+        Diag(Loc, diag::err_objc_bridged_related_known_method)
+        << SrcType << DestType << InstanceMethod->getSelector() << true
+        << FixItHint::CreateInsertion(SrcExpr->getLocStart(), "[")
+        << FixItHint::CreateInsertion(SrcExprEndLoc, ExpressionString);
+      }
+      Diag(RelatedClass->getLocStart(), diag::note_declared_at);
+      Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+      
+      ExprResult msg =
+        BuildInstanceMessageImplicit(SrcExpr, SrcType,
+                                     InstanceMethod->getLocation(),
+                                     InstanceMethod->getSelector(),
+                                     InstanceMethod, None);
+      SrcExpr = msg.get();
+      return true;
+    }
+  }
   return false;
 }
 
 Sema::ARCConversionResult
 Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType,
                              Expr *&castExpr, CheckedConversionKind CCK,
-                             bool DiagnoseCFAudited) {
+                             bool DiagnoseCFAudited,
+                             BinaryOperatorKind Opc) {
   QualType castExprType = castExpr->getType();
 
   // For the purposes of the classification, we assume reference types
@@ -3324,17 +3710,6 @@
   if (castACTC == ACTC_indirectRetainable && exprACTC == ACTC_voidPtr &&
       CCK != CCK_ImplicitConversion)
     return ACR_okay;
-  
-  if (castACTC == ACTC_retainable && exprACTC == ACTC_coreFoundation &&
-      (CCK == CCK_CStyleCast || CCK == CCK_FunctionalCast))
-    if (CheckObjCBridgeNSCast(*this, castType, castExpr))
-      return ACR_okay;
-    
-  if (castACTC == ACTC_coreFoundation && exprACTC == ACTC_retainable &&
-      (CCK == CCK_CStyleCast || CCK == CCK_FunctionalCast))
-    if (CheckObjCBridgeCFCast(*this, castType, castExpr))
-      return ACR_okay;
-    
 
   switch (ARCCastChecker(Context, exprACTC, castACTC, false).Visit(castExpr)) {
   // For invalid casts, fall through.
@@ -3350,7 +3725,7 @@
   case ACC_plusOne:
     castExpr = ImplicitCastExpr::Create(Context, castExpr->getType(),
                                         CK_ARCConsumeObject, castExpr,
-                                        0, VK_RValue);
+                                        nullptr, VK_RValue);
     ExprNeedsCleanups = true;
     return ACR_okay;
   }
@@ -3362,14 +3737,23 @@
       CCK != CCK_ImplicitConversion)
     return ACR_unbridged;
 
+  // Do not issue bridge cast" diagnostic when implicit casting a cstring
+  // to 'NSString *'. Let caller issue a normal mismatched diagnostic with
+  // suitable fix-it.
+  if (castACTC == ACTC_retainable && exprACTC == ACTC_none &&
+      ConversionToObjCStringLiteralCheck(castType, castExpr))
+    return ACR_okay;
+  
   // Do not issue "bridge cast" diagnostic when implicit casting
   // a retainable object to a CF type parameter belonging to an audited
   // CF API function. Let caller issue a normal type mismatched diagnostic
   // instead.
   if (!DiagnoseCFAudited || exprACTC != ACTC_retainable ||
       castACTC != ACTC_coreFoundation)
-    diagnoseObjCARCConversion(*this, castRange, castType, castACTC,
-                              castExpr, castExpr, exprACTC, CCK);
+    if (!(exprACTC == ACTC_voidPtr && castACTC == ACTC_retainable &&
+          (Opc == BO_NE || Opc == BO_EQ)))
+      diagnoseObjCARCConversion(*this, castRange, castType, castACTC,
+                                castExpr, castExpr, exprACTC, CCK);
   return ACR_okay;
 }
 
@@ -3486,7 +3870,7 @@
                                       Expr *SubExpr) {
   ExprResult SubResult = UsualUnaryConversions(SubExpr);
   if (SubResult.isInvalid()) return ExprError();
-  SubExpr = SubResult.take();
+  SubExpr = SubResult.get();
 
   QualType T = TSInfo->getType();
   QualType FromType = SubExpr->getType();
@@ -3545,7 +3929,7 @@
       // Produce the object before casting it.
       SubExpr = ImplicitCastExpr::Create(Context, FromType,
                                          CK_ARCProduceObject,
-                                         SubExpr, 0, VK_RValue);
+                                         SubExpr, nullptr, VK_RValue);
       break;
       
     case OBC_BridgeTransfer: {
@@ -3584,7 +3968,7 @@
   if (MustConsume) {
     ExprNeedsCleanups = true;
     Result = ImplicitCastExpr::Create(Context, T, CK_ARCConsumeObject, Result, 
-                                      0, VK_RValue);    
+                                      nullptr, VK_RValue);
   }
   
   return Result;
@@ -3597,8 +3981,10 @@
                                       ParsedType Type,
                                       SourceLocation RParenLoc,
                                       Expr *SubExpr) {
-  TypeSourceInfo *TSInfo = 0;
+  TypeSourceInfo *TSInfo = nullptr;
   QualType T = GetTypeFromParser(Type, &TSInfo);
+  if (Kind == OBC_Bridge)
+    CheckTollFreeBridgeCast(T, SubExpr);
   if (!TSInfo)
     TSInfo = Context.getTrivialTypeSourceInfo(T, LParenLoc);
   return BuildObjCBridgedCast(LParenLoc, Kind, BridgeKeywordLoc, TSInfo, 
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 72c37eb..06ca9ae 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -17,7 +17,7 @@
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/TypeLoc.h"
-#include "clang/Lex/Preprocessor.h"
+#include "clang/Basic/TargetInfo.h"
 #include "clang/Sema/Designator.h"
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/SemaInternal.h"
@@ -70,7 +70,7 @@
 
   // Otherwise we can only handle string literals.
   StringLiteral *SL = dyn_cast<StringLiteral>(Init);
-  if (SL == 0)
+  if (!SL)
     return SIF_Other;
 
   const QualType ElemTy =
@@ -189,7 +189,7 @@
     // C99 6.7.8p14.
     if (StrLength-1 > CAT->getSize().getZExtValue())
       S.Diag(Str->getLocStart(),
-             diag::warn_initializer_string_for_char_array_too_long)
+             diag::ext_initializer_string_for_char_array_too_long)
         << Str->getSourceRange();
   }
 
@@ -313,15 +313,20 @@
   int numArrayElements(QualType DeclType);
   int numStructUnionElements(QualType DeclType);
 
-  void FillInValueInitForField(unsigned Init, FieldDecl *Field,
+  static ExprResult PerformEmptyInit(Sema &SemaRef,
+                                     SourceLocation Loc,
+                                     const InitializedEntity &Entity,
+                                     bool VerifyOnly);
+  void FillInEmptyInitForField(unsigned Init, FieldDecl *Field,
                                const InitializedEntity &ParentEntity,
                                InitListExpr *ILE, bool &RequiresSecondPass);
-  void FillInValueInitializations(const InitializedEntity &Entity,
+  void FillInEmptyInitializations(const InitializedEntity &Entity,
                                   InitListExpr *ILE, bool &RequiresSecondPass);
   bool CheckFlexibleArrayInit(const InitializedEntity &Entity,
                               Expr *InitExpr, FieldDecl *Field,
                               bool TopLevelObject);
-  void CheckValueInitializable(const InitializedEntity &Entity);
+  void CheckEmptyInitializable(const InitializedEntity &Entity,
+                               SourceLocation Loc);
 
 public:
   InitListChecker(Sema &S, const InitializedEntity &Entity,
@@ -334,33 +339,134 @@
 };
 } // end anonymous namespace
 
-void InitListChecker::CheckValueInitializable(const InitializedEntity &Entity) {
-  assert(VerifyOnly &&
-         "CheckValueInitializable is only inteded for verification mode.");
-
-  SourceLocation Loc;
+ExprResult InitListChecker::PerformEmptyInit(Sema &SemaRef,
+                                             SourceLocation Loc,
+                                             const InitializedEntity &Entity,
+                                             bool VerifyOnly) {
   InitializationKind Kind = InitializationKind::CreateValue(Loc, Loc, Loc,
                                                             true);
-  InitializationSequence InitSeq(SemaRef, Entity, Kind, None);
-  if (InitSeq.Failed())
+  MultiExprArg SubInit;
+  Expr *InitExpr;
+  InitListExpr DummyInitList(SemaRef.Context, Loc, None, Loc);
+
+  // C++ [dcl.init.aggr]p7:
+  //   If there are fewer initializer-clauses in the list than there are
+  //   members in the aggregate, then each member not explicitly initialized
+  //   ...
+  bool EmptyInitList = SemaRef.getLangOpts().CPlusPlus11 &&
+      Entity.getType()->getBaseElementTypeUnsafe()->isRecordType();
+  if (EmptyInitList) {
+    // C++1y / DR1070:
+    //   shall be initialized [...] from an empty initializer list.
+    //
+    // We apply the resolution of this DR to C++11 but not C++98, since C++98
+    // does not have useful semantics for initialization from an init list.
+    // We treat this as copy-initialization, because aggregate initialization
+    // always performs copy-initialization on its elements.
+    //
+    // Only do this if we're initializing a class type, to avoid filling in
+    // the initializer list where possible.
+    InitExpr = VerifyOnly ? &DummyInitList : new (SemaRef.Context)
+                   InitListExpr(SemaRef.Context, Loc, None, Loc);
+    InitExpr->setType(SemaRef.Context.VoidTy);
+    SubInit = InitExpr;
+    Kind = InitializationKind::CreateCopy(Loc, Loc);
+  } else {
+    // C++03:
+    //   shall be value-initialized.
+  }
+
+  InitializationSequence InitSeq(SemaRef, Entity, Kind, SubInit);
+  // libstdc++4.6 marks the vector default constructor as explicit in
+  // _GLIBCXX_DEBUG mode, so recover using the C++03 logic in that case.
+  // stlport does so too. Look for std::__debug for libstdc++, and for
+  // std:: for stlport.  This is effectively a compiler-side implementation of
+  // LWG2193.
+  if (!InitSeq && EmptyInitList && InitSeq.getFailureKind() ==
+          InitializationSequence::FK_ExplicitConstructor) {
+    OverloadCandidateSet::iterator Best;
+    OverloadingResult O =
+        InitSeq.getFailedCandidateSet()
+            .BestViableFunction(SemaRef, Kind.getLocation(), Best);
+    (void)O;
+    assert(O == OR_Success && "Inconsistent overload resolution");
+    CXXConstructorDecl *CtorDecl = cast<CXXConstructorDecl>(Best->Function);
+    CXXRecordDecl *R = CtorDecl->getParent();
+
+    if (CtorDecl->getMinRequiredArguments() == 0 &&
+        CtorDecl->isExplicit() && R->getDeclName() &&
+        SemaRef.SourceMgr.isInSystemHeader(CtorDecl->getLocation())) {
+
+
+      bool IsInStd = false;
+      for (NamespaceDecl *ND = dyn_cast<NamespaceDecl>(R->getDeclContext());
+           ND && !IsInStd; ND = dyn_cast<NamespaceDecl>(ND->getParent())) {
+        if (SemaRef.getStdNamespace()->InEnclosingNamespaceSetOf(ND))
+          IsInStd = true;
+      }
+
+      if (IsInStd && llvm::StringSwitch<bool>(R->getName()) 
+              .Cases("basic_string", "deque", "forward_list", true)
+              .Cases("list", "map", "multimap", "multiset", true)
+              .Cases("priority_queue", "queue", "set", "stack", true)
+              .Cases("unordered_map", "unordered_set", "vector", true)
+              .Default(false)) {
+        InitSeq.InitializeFrom(
+            SemaRef, Entity,
+            InitializationKind::CreateValue(Loc, Loc, Loc, true),
+            MultiExprArg(), /*TopLevelOfInitList=*/false);
+        // Emit a warning for this.  System header warnings aren't shown
+        // by default, but people working on system headers should see it.
+        if (!VerifyOnly) {
+          SemaRef.Diag(CtorDecl->getLocation(),
+                       diag::warn_invalid_initializer_from_system_header);
+          SemaRef.Diag(Entity.getDecl()->getLocation(),
+                       diag::note_used_in_initialization_here);
+        }
+      }
+    }
+  }
+  if (!InitSeq) {
+    if (!VerifyOnly) {
+      InitSeq.Diagnose(SemaRef, Entity, Kind, SubInit);
+      if (Entity.getKind() == InitializedEntity::EK_Member)
+        SemaRef.Diag(Entity.getDecl()->getLocation(),
+                     diag::note_in_omitted_aggregate_initializer)
+          << /*field*/1 << Entity.getDecl();
+      else if (Entity.getKind() == InitializedEntity::EK_ArrayElement)
+        SemaRef.Diag(Loc, diag::note_in_omitted_aggregate_initializer)
+          << /*array element*/0 << Entity.getElementIndex();
+    }
+    return ExprError();
+  }
+
+  return VerifyOnly ? ExprResult(static_cast<Expr *>(nullptr))
+                    : InitSeq.Perform(SemaRef, Entity, Kind, SubInit);
+}
+
+void InitListChecker::CheckEmptyInitializable(const InitializedEntity &Entity,
+                                              SourceLocation Loc) {
+  assert(VerifyOnly &&
+         "CheckEmptyInitializable is only inteded for verification mode.");
+  if (PerformEmptyInit(SemaRef, Loc, Entity, /*VerifyOnly*/true).isInvalid())
     hadError = true;
 }
 
-void InitListChecker::FillInValueInitForField(unsigned Init, FieldDecl *Field,
+void InitListChecker::FillInEmptyInitForField(unsigned Init, FieldDecl *Field,
                                         const InitializedEntity &ParentEntity,
                                               InitListExpr *ILE,
                                               bool &RequiresSecondPass) {
-  SourceLocation Loc = ILE->getLocStart();
+  SourceLocation Loc = ILE->getLocEnd();
   unsigned NumInits = ILE->getNumInits();
   InitializedEntity MemberEntity
     = InitializedEntity::InitializeMember(Field, &ParentEntity);
   if (Init >= NumInits || !ILE->getInit(Init)) {
-    // If there's no explicit initializer but we have a default initializer, use
-    // that. This only happens in C++1y, since classes with default
-    // initializers are not aggregates in C++11.
+    // C++1y [dcl.init.aggr]p7:
+    //   If there are fewer initializer-clauses in the list than there are
+    //   members in the aggregate, then each member not explicitly initialized
+    //   shall be initialized from its brace-or-equal-initializer [...]
     if (Field->hasInClassInitializer()) {
-      Expr *DIE = CXXDefaultInitExpr::Create(SemaRef.Context,
-                                             ILE->getRBraceLoc(), Field);
+      Expr *DIE = CXXDefaultInitExpr::Create(SemaRef.Context, Loc, Field);
       if (Init < NumInits)
         ILE->setInit(Init, DIE);
       else {
@@ -370,9 +476,6 @@
       return;
     }
 
-    // FIXME: We probably don't need to handle references
-    // specially here, since value-initialization of references is
-    // handled in InitializationSequence.
     if (Field->getType()->isReferenceType()) {
       // C++ [dcl.init.aggr]p9:
       //   If an incomplete or empty initializer-list leaves a
@@ -387,17 +490,8 @@
       return;
     }
 
-    InitializationKind Kind = InitializationKind::CreateValue(Loc, Loc, Loc,
-                                                              true);
-    InitializationSequence InitSeq(SemaRef, MemberEntity, Kind, None);
-    if (!InitSeq) {
-      InitSeq.Diagnose(SemaRef, MemberEntity, Kind, None);
-      hadError = true;
-      return;
-    }
-
-    ExprResult MemberInit
-      = InitSeq.Perform(SemaRef, MemberEntity, Kind, None);
+    ExprResult MemberInit = PerformEmptyInit(SemaRef, Loc, MemberEntity,
+                                             /*VerifyOnly*/false);
     if (MemberInit.isInvalid()) {
       hadError = true;
       return;
@@ -406,18 +500,18 @@
     if (hadError) {
       // Do nothing
     } else if (Init < NumInits) {
-      ILE->setInit(Init, MemberInit.takeAs<Expr>());
-    } else if (InitSeq.isConstructorInitialization()) {
-      // Value-initialization requires a constructor call, so
+      ILE->setInit(Init, MemberInit.getAs<Expr>());
+    } else if (!isa<ImplicitValueInitExpr>(MemberInit.get())) {
+      // Empty initialization requires a constructor call, so
       // extend the initializer list to include the constructor
       // call and make a note that we'll need to take another pass
       // through the initializer list.
-      ILE->updateInit(SemaRef.Context, Init, MemberInit.takeAs<Expr>());
+      ILE->updateInit(SemaRef.Context, Init, MemberInit.getAs<Expr>());
       RequiresSecondPass = true;
     }
   } else if (InitListExpr *InnerILE
                = dyn_cast<InitListExpr>(ILE->getInit(Init)))
-    FillInValueInitializations(MemberEntity, InnerILE,
+    FillInEmptyInitializations(MemberEntity, InnerILE,
                                RequiresSecondPass);
 }
 
@@ -425,42 +519,35 @@
 /// with expressions that perform value-initialization of the
 /// appropriate type.
 void
-InitListChecker::FillInValueInitializations(const InitializedEntity &Entity,
+InitListChecker::FillInEmptyInitializations(const InitializedEntity &Entity,
                                             InitListExpr *ILE,
                                             bool &RequiresSecondPass) {
   assert((ILE->getType() != SemaRef.Context.VoidTy) &&
          "Should not have void type");
-  SourceLocation Loc = ILE->getLocStart();
-  if (ILE->getSyntacticForm())
-    Loc = ILE->getSyntacticForm()->getLocStart();
 
   if (const RecordType *RType = ILE->getType()->getAs<RecordType>()) {
     const RecordDecl *RDecl = RType->getDecl();
     if (RDecl->isUnion() && ILE->getInitializedFieldInUnion())
-      FillInValueInitForField(0, ILE->getInitializedFieldInUnion(),
+      FillInEmptyInitForField(0, ILE->getInitializedFieldInUnion(),
                               Entity, ILE, RequiresSecondPass);
     else if (RDecl->isUnion() && isa<CXXRecordDecl>(RDecl) &&
              cast<CXXRecordDecl>(RDecl)->hasInClassInitializer()) {
-      for (RecordDecl::field_iterator Field = RDecl->field_begin(),
-                                      FieldEnd = RDecl->field_end();
-           Field != FieldEnd; ++Field) {
+      for (auto *Field : RDecl->fields()) {
         if (Field->hasInClassInitializer()) {
-          FillInValueInitForField(0, *Field, Entity, ILE, RequiresSecondPass);
+          FillInEmptyInitForField(0, Field, Entity, ILE, RequiresSecondPass);
           break;
         }
       }
     } else {
       unsigned Init = 0;
-      for (RecordDecl::field_iterator Field = RDecl->field_begin(),
-                                      FieldEnd = RDecl->field_end();
-           Field != FieldEnd; ++Field) {
+      for (auto *Field : RDecl->fields()) {
         if (Field->isUnnamedBitfield())
           continue;
 
         if (hadError)
           return;
 
-        FillInValueInitForField(Init, *Field, Entity, ILE, RequiresSecondPass);
+        FillInEmptyInitForField(Init, Field, Entity, ILE, RequiresSecondPass);
         if (hadError)
           return;
 
@@ -494,7 +581,6 @@
   } else
     ElementType = ILE->getType();
 
-
   for (unsigned Init = 0; Init != NumElements; ++Init) {
     if (hadError)
       return;
@@ -503,19 +589,11 @@
         ElementEntity.getKind() == InitializedEntity::EK_VectorElement)
       ElementEntity.setElementIndex(Init);
 
-    Expr *InitExpr = (Init < NumInits ? ILE->getInit(Init) : 0);
+    Expr *InitExpr = (Init < NumInits ? ILE->getInit(Init) : nullptr);
     if (!InitExpr && !ILE->hasArrayFiller()) {
-      InitializationKind Kind = InitializationKind::CreateValue(Loc, Loc, Loc,
-                                                                true);
-      InitializationSequence InitSeq(SemaRef, ElementEntity, Kind, None);
-      if (!InitSeq) {
-        InitSeq.Diagnose(SemaRef, ElementEntity, Kind, None);
-        hadError = true;
-        return;
-      }
-
-      ExprResult ElementInit
-        = InitSeq.Perform(SemaRef, ElementEntity, Kind, None);
+      ExprResult ElementInit = PerformEmptyInit(SemaRef, ILE->getLocEnd(),
+                                                ElementEntity,
+                                                /*VerifyOnly*/false);
       if (ElementInit.isInvalid()) {
         hadError = true;
         return;
@@ -527,29 +605,29 @@
         // For arrays, just set the expression used for value-initialization
         // of the "holes" in the array.
         if (ElementEntity.getKind() == InitializedEntity::EK_ArrayElement)
-          ILE->setArrayFiller(ElementInit.takeAs<Expr>());
+          ILE->setArrayFiller(ElementInit.getAs<Expr>());
         else
-          ILE->setInit(Init, ElementInit.takeAs<Expr>());
+          ILE->setInit(Init, ElementInit.getAs<Expr>());
       } else {
         // For arrays, just set the expression used for value-initialization
         // of the rest of elements and exit.
         if (ElementEntity.getKind() == InitializedEntity::EK_ArrayElement) {
-          ILE->setArrayFiller(ElementInit.takeAs<Expr>());
+          ILE->setArrayFiller(ElementInit.getAs<Expr>());
           return;
         }
 
-        if (InitSeq.isConstructorInitialization()) {
-          // Value-initialization requires a constructor call, so
+        if (!isa<ImplicitValueInitExpr>(ElementInit.get())) {
+          // Empty initialization requires a constructor call, so
           // extend the initializer list to include the constructor
           // call and make a note that we'll need to take another pass
           // through the initializer list.
-          ILE->updateInit(SemaRef.Context, Init, ElementInit.takeAs<Expr>());
+          ILE->updateInit(SemaRef.Context, Init, ElementInit.getAs<Expr>());
           RequiresSecondPass = true;
         }
       }
     } else if (InitListExpr *InnerILE
                  = dyn_cast_or_null<InitListExpr>(InitExpr))
-      FillInValueInitializations(ElementEntity, InnerILE, RequiresSecondPass);
+      FillInEmptyInitializations(ElementEntity, InnerILE, RequiresSecondPass);
   }
 }
 
@@ -561,15 +639,15 @@
   hadError = false;
 
   FullyStructuredList =
-      getStructuredSubobjectInit(IL, 0, T, 0, 0, IL->getSourceRange());
+      getStructuredSubobjectInit(IL, 0, T, nullptr, 0, IL->getSourceRange());
   CheckExplicitInitList(Entity, IL, T, FullyStructuredList,
                         /*TopLevelObject=*/true);
 
   if (!hadError && !VerifyOnly) {
     bool RequiresSecondPass = false;
-    FillInValueInitializations(Entity, FullyStructuredList, RequiresSecondPass);
+    FillInEmptyInitializations(Entity, FullyStructuredList, RequiresSecondPass);
     if (RequiresSecondPass && !hadError)
-      FillInValueInitializations(Entity, FullyStructuredList,
+      FillInEmptyInitializations(Entity, FullyStructuredList,
                                  RequiresSecondPass);
   }
 }
@@ -587,13 +665,10 @@
 int InitListChecker::numStructUnionElements(QualType DeclType) {
   RecordDecl *structDecl = DeclType->getAs<RecordType>()->getDecl();
   int InitializableMembers = 0;
-  for (RecordDecl::field_iterator
-         Field = structDecl->field_begin(),
-         FieldEnd = structDecl->field_end();
-       Field != FieldEnd; ++Field) {
+  for (const auto *Field : structDecl->fields())
     if (!Field->isUnnamedBitfield())
       ++InitializableMembers;
-  }
+
   if (structDecl->isUnion())
     return std::min(InitializableMembers, 1);
   return InitializableMembers - structDecl->hasFlexibleArrayMember();
@@ -661,13 +736,13 @@
     if (T->isArrayType() || T->isRecordType()) {
       SemaRef.Diag(StructuredSubobjectInitList->getLocStart(),
                    diag::warn_missing_braces)
-        << StructuredSubobjectInitList->getSourceRange()
-        << FixItHint::CreateInsertion(
-              StructuredSubobjectInitList->getLocStart(), "{")
-        << FixItHint::CreateInsertion(
-              SemaRef.PP.getLocForEndOfToken(
-                                      StructuredSubobjectInitList->getLocEnd()),
-              "}");
+          << StructuredSubobjectInitList->getSourceRange()
+          << FixItHint::CreateInsertion(
+                 StructuredSubobjectInitList->getLocStart(), "{")
+          << FixItHint::CreateInsertion(
+                 SemaRef.getLocForEndOfToken(
+                     StructuredSubobjectInitList->getLocEnd()),
+                 "}");
     }
   }
 }
@@ -681,7 +756,6 @@
                                             InitListExpr *IList, QualType &T,
                                             InitListExpr *StructuredList,
                                             bool TopLevelObject) {
-  assert(IList->isExplicit() && "Illegal Implicit InitListExpr");
   if (!VerifyOnly) {
     SyntacticToSemantic[IList] = StructuredList;
     StructuredList->setSyntacticForm(IList);
@@ -714,7 +788,7 @@
     if (StructuredIndex == 1 &&
         IsStringInit(StructuredList->getInit(0), T, SemaRef.Context) ==
             SIF_None) {
-      unsigned DK = diag::warn_excess_initializers_in_char_array_initializer;
+      unsigned DK = diag::ext_excess_initializers_in_char_array_initializer;
       if (SemaRef.getLangOpts().CPlusPlus) {
         DK = diag::err_excess_initializers_in_char_array_initializer;
         hadError = true;
@@ -733,7 +807,7 @@
         CurrentObjectType->isUnionType()? 3 :
         4;
 
-      unsigned DK = diag::warn_excess_initializers;
+      unsigned DK = diag::ext_excess_initializers;
       if (SemaRef.getLangOpts().CPlusPlus) {
         DK = diag::err_excess_initializers;
         hadError = true;
@@ -840,6 +914,15 @@
     assert(SemaRef.getLangOpts().CPlusPlus &&
            "non-aggregate records are only possible in C++");
     // C++ initialization is handled later.
+  } else if (isa<ImplicitValueInitExpr>(expr)) {
+    // This happens during template instantiation when we see an InitListExpr
+    // that we've already checked once.
+    assert(SemaRef.Context.hasSameType(expr->getType(), ElemType) &&
+           "found implicit initialization for the wrong type");
+    if (!VerifyOnly)
+      UpdateStructuredListElement(StructuredList, StructuredIndex, expr);
+    ++Index;
+    return;
   }
 
   // FIXME: Need to handle atomic aggregate types with implicit init lists.
@@ -886,7 +969,7 @@
           hadError = true;
 
         UpdateStructuredListElement(StructuredList, StructuredIndex,
-                                    Result.takeAs<Expr>());
+                                    Result.getAs<Expr>());
       }
       ++Index;
       return;
@@ -902,7 +985,7 @@
     //   compatible structure or union type. In the latter case, the
     //   initial value of the object, including unnamed members, is
     //   that of the expression.
-    ExprResult ExprRes = SemaRef.Owned(expr);
+    ExprResult ExprRes = expr;
     if ((ElemType->isRecordType() || ElemType->isVectorType()) &&
         SemaRef.CheckSingleAssignmentConstraints(ElemType, ExprRes,
                                                  !VerifyOnly)
@@ -910,16 +993,16 @@
       if (ExprRes.isInvalid())
         hadError = true;
       else {
-        ExprRes = SemaRef.DefaultFunctionArrayLvalueConversion(ExprRes.take());
+        ExprRes = SemaRef.DefaultFunctionArrayLvalueConversion(ExprRes.get());
           if (ExprRes.isInvalid())
             hadError = true;
       }
       UpdateStructuredListElement(StructuredList, StructuredIndex,
-                                  ExprRes.takeAs<Expr>());
+                                  ExprRes.getAs<Expr>());
       ++Index;
       return;
     }
-    ExprRes.release();
+    ExprRes.get();
     // Fall through for subaggregate initialization
   }
 
@@ -938,8 +1021,7 @@
     if (!VerifyOnly) {
       // We cannot initialize this element, so let
       // PerformCopyInitialization produce the appropriate diagnostic.
-      SemaRef.PerformCopyInitialization(Entity, SourceLocation(),
-                                        SemaRef.Owned(expr),
+      SemaRef.PerformCopyInitialization(Entity, SourceLocation(), expr,
                                         /*TopLevelOfInitList=*/true);
     }
     hadError = true;
@@ -1005,9 +1087,11 @@
 
   Expr *expr = IList->getInit(Index);
   if (InitListExpr *SubIList = dyn_cast<InitListExpr>(expr)) {
+    // FIXME: This is invalid, and accepting it causes overload resolution
+    // to pick the wrong overload in some corner cases.
     if (!VerifyOnly)
       SemaRef.Diag(SubIList->getLocStart(),
-                   diag::warn_many_braces_around_scalar_init)
+                   diag::ext_many_braces_around_scalar_init)
         << SubIList->getSourceRange();
 
     CheckScalarType(Entity, SubIList, DeclType, Index, StructuredList,
@@ -1025,23 +1109,22 @@
   }
 
   if (VerifyOnly) {
-    if (!SemaRef.CanPerformCopyInitialization(Entity, SemaRef.Owned(expr)))
+    if (!SemaRef.CanPerformCopyInitialization(Entity,expr))
       hadError = true;
     ++Index;
     return;
   }
 
   ExprResult Result =
-    SemaRef.PerformCopyInitialization(Entity, expr->getLocStart(),
-                                      SemaRef.Owned(expr),
+    SemaRef.PerformCopyInitialization(Entity, expr->getLocStart(), expr,
                                       /*TopLevelOfInitList=*/true);
 
-  Expr *ResultExpr = 0;
+  Expr *ResultExpr = nullptr;
 
   if (Result.isInvalid())
     hadError = true; // types weren't compatible.
   else {
-    ResultExpr = Result.takeAs<Expr>();
+    ResultExpr = Result.getAs<Expr>();
 
     if (ResultExpr != expr) {
       // The type was promoted, update initializer list.
@@ -1088,21 +1171,20 @@
   }
 
   if (VerifyOnly) {
-    if (!SemaRef.CanPerformCopyInitialization(Entity, SemaRef.Owned(expr)))
+    if (!SemaRef.CanPerformCopyInitialization(Entity,expr))
       hadError = true;
     ++Index;
     return;
   }
 
   ExprResult Result =
-    SemaRef.PerformCopyInitialization(Entity, expr->getLocStart(),
-                                      SemaRef.Owned(expr),
-                                      /*TopLevelOfInitList=*/true);
+      SemaRef.PerformCopyInitialization(Entity, expr->getLocStart(), expr,
+                                        /*TopLevelOfInitList=*/true);
 
   if (Result.isInvalid())
     hadError = true;
 
-  expr = Result.takeAs<Expr>();
+  expr = Result.getAs<Expr>();
   IList->setInit(Index, expr);
 
   if (hadError)
@@ -1125,8 +1207,9 @@
   if (Index >= IList->getNumInits()) {
     // Make sure the element type can be value-initialized.
     if (VerifyOnly)
-      CheckValueInitializable(
-          InitializedEntity::InitializeElement(SemaRef.Context, 0, Entity));
+      CheckEmptyInitializable(
+          InitializedEntity::InitializeElement(SemaRef.Context, 0, Entity),
+          IList->getLocEnd());
     return;
   }
 
@@ -1136,22 +1219,21 @@
     Expr *Init = IList->getInit(Index);
     if (!isa<InitListExpr>(Init) && Init->getType()->isVectorType()) {
       if (VerifyOnly) {
-        if (!SemaRef.CanPerformCopyInitialization(Entity, SemaRef.Owned(Init)))
+        if (!SemaRef.CanPerformCopyInitialization(Entity, Init))
           hadError = true;
         ++Index;
         return;
       }
 
-      ExprResult Result =
-        SemaRef.PerformCopyInitialization(Entity, Init->getLocStart(),
-                                          SemaRef.Owned(Init),
-                                          /*TopLevelOfInitList=*/true);
+  ExprResult Result =
+      SemaRef.PerformCopyInitialization(Entity, Init->getLocStart(), Init,
+                                        /*TopLevelOfInitList=*/true);
 
-      Expr *ResultExpr = 0;
+      Expr *ResultExpr = nullptr;
       if (Result.isInvalid())
         hadError = true; // types weren't compatible.
       else {
-        ResultExpr = Result.takeAs<Expr>();
+        ResultExpr = Result.getAs<Expr>();
 
         if (ResultExpr != Init) {
           // The type was promoted, update initializer list.
@@ -1174,7 +1256,7 @@
       // Don't attempt to go past the end of the init list
       if (Index >= IList->getNumInits()) {
         if (VerifyOnly)
-          CheckValueInitializable(ElementEntity);
+          CheckEmptyInitializable(ElementEntity, IList->getLocEnd());
         break;
       }
 
@@ -1182,6 +1264,46 @@
       CheckSubElementType(ElementEntity, IList, elementType, Index,
                           StructuredList, StructuredIndex);
     }
+
+    if (VerifyOnly)
+      return;
+
+    bool isBigEndian = SemaRef.Context.getTargetInfo().isBigEndian();
+    const VectorType *T = Entity.getType()->getAs<VectorType>();
+    if (isBigEndian && (T->getVectorKind() == VectorType::NeonVector ||
+                        T->getVectorKind() == VectorType::NeonPolyVector)) {
+      // The ability to use vector initializer lists is a GNU vector extension
+      // and is unrelated to the NEON intrinsics in arm_neon.h. On little
+      // endian machines it works fine, however on big endian machines it 
+      // exhibits surprising behaviour:
+      //
+      //   uint32x2_t x = {42, 64};
+      //   return vget_lane_u32(x, 0); // Will return 64.
+      //
+      // Because of this, explicitly call out that it is non-portable.
+      //
+      SemaRef.Diag(IList->getLocStart(),
+                   diag::warn_neon_vector_initializer_non_portable);
+
+      const char *typeCode;
+      unsigned typeSize = SemaRef.Context.getTypeSize(elementType);
+
+      if (elementType->isFloatingType())
+        typeCode = "f";
+      else if (elementType->isSignedIntegerType())
+        typeCode = "s";
+      else if (elementType->isUnsignedIntegerType())
+        typeCode = "u";
+      else
+        llvm_unreachable("Invalid element type!");
+
+      SemaRef.Diag(IList->getLocStart(),
+                   SemaRef.Context.getTypeSize(VT) > 64 ?
+                   diag::note_neon_vector_initializer_non_portable_q :
+                   diag::note_neon_vector_initializer_non_portable)
+        << typeCode << typeSize;
+    }
+
     return;
   }
 
@@ -1293,7 +1415,7 @@
       // Handle this designated initializer. elementIndex will be
       // updated to be the next array element we'll initialize.
       if (CheckDesignatedInitializer(Entity, IList, DIE, 0,
-                                     DeclType, 0, &elementIndex, Index,
+                                     DeclType, nullptr, &elementIndex, Index,
                                      StructuredList, StructuredIndex, true,
                                      false)) {
         hadError = true;
@@ -1351,8 +1473,9 @@
     // If so, check if doing that is possible.
     // FIXME: This needs to detect holes left by designated initializers too.
     if (maxElementsKnown && elementIndex < maxElements)
-      CheckValueInitializable(InitializedEntity::InitializeElement(
-                                                  SemaRef.Context, 0, Entity));
+      CheckEmptyInitializable(InitializedEntity::InitializeElement(
+                                                  SemaRef.Context, 0, Entity),
+                              IList->getLocEnd());
   }
 }
 
@@ -1437,8 +1560,9 @@
          Field != FieldEnd; ++Field) {
       if (Field->getDeclName()) {
         if (VerifyOnly)
-          CheckValueInitializable(
-              InitializedEntity::InitializeMember(*Field, &Entity));
+          CheckEmptyInitializable(
+              InitializedEntity::InitializeMember(*Field, &Entity),
+              IList->getLocEnd());
         else
           StructuredList->setInitializedFieldInUnion(*Field);
         break;
@@ -1468,7 +1592,7 @@
       // Handle this designated initializer. Field will be updated to
       // the next field that we'll be initializing.
       if (CheckDesignatedInitializer(Entity, IList, DIE, 0,
-                                     DeclType, &Field, 0, Index,
+                                     DeclType, &Field, nullptr, Index,
                                      StructuredList, StructuredIndex,
                                      true, TopLevelObject))
         hadError = true;
@@ -1538,7 +1662,7 @@
          it != end; ++it) {
       if (!it->isUnnamedBitfield() && !it->hasInClassInitializer()) {
         SemaRef.Diag(IList->getSourceRange().getEnd(),
-                     diag::warn_missing_field_initializers) << it->getName();
+                     diag::warn_missing_field_initializers) << *it;
         break;
       }
     }
@@ -1550,8 +1674,9 @@
     // FIXME: Should check for holes left by designated initializers too.
     for (; Field != FieldEnd && !hadError; ++Field) {
       if (!Field->isUnnamedBitfield() && !Field->hasInClassInitializer())
-        CheckValueInitializable(
-            InitializedEntity::InitializeMember(*Field, &Entity));
+        CheckEmptyInitializable(
+            InitializedEntity::InitializeMember(*Field, &Entity),
+            IList->getLocEnd());
     }
   }
 
@@ -1592,12 +1717,12 @@
   for (IndirectFieldDecl::chain_iterator PI = IndirectField->chain_begin(),
        PE = IndirectField->chain_end(); PI != PE; ++PI) {
     if (PI + 1 == PE)
-      Replacements.push_back(Designator((IdentifierInfo *)0,
+      Replacements.push_back(Designator((IdentifierInfo *)nullptr,
                                     DIE->getDesignator(DesigIdx)->getDotLoc(),
                                 DIE->getDesignator(DesigIdx)->getFieldLoc()));
     else
-      Replacements.push_back(Designator((IdentifierInfo *)0, SourceLocation(),
-                                        SourceLocation()));
+      Replacements.push_back(Designator((IdentifierInfo *)nullptr,
+                                        SourceLocation(), SourceLocation()));
     assert(isa<FieldDecl>(*PI));
     Replacements.back().setField(cast<FieldDecl>(*PI));
   }
@@ -1614,7 +1739,7 @@
 static IndirectFieldDecl *FindIndirectFieldDesignator(FieldDecl *AnonField,
                                                  IdentifierInfo *FieldName) {
   if (!FieldName)
-    return 0;
+    return nullptr;
 
   assert(AnonField->isAnonymousStructOrUnion());
   Decl *NextDecl = AnonField->getNextDeclInContext();
@@ -1624,7 +1749,7 @@
       return IF;
     NextDecl = NextDecl->getNextDeclInContext();
   }
-  return 0;
+  return nullptr;
 }
 
 static DesignatedInitExpr *CloneDesignatedInitExpr(Sema &SemaRef,
@@ -1648,7 +1773,7 @@
   explicit FieldInitializerValidatorCCC(RecordDecl *RD)
       : Record(RD) {}
 
-  virtual bool ValidateCandidate(const TypoCorrection &candidate) {
+  bool ValidateCandidate(const TypoCorrection &candidate) override {
     FieldDecl *FD = candidate.getCorrectionDeclAs<FieldDecl>();
     return FD && FD->getDeclContext()->getRedeclContext()->Equals(Record);
   }
@@ -1813,15 +1938,15 @@
       // may find nothing, or may find a member of an anonymous
       // struct/union.
       DeclContext::lookup_result Lookup = RT->getDecl()->lookup(FieldName);
-      FieldDecl *ReplacementField = 0;
+      FieldDecl *ReplacementField = nullptr;
       if (Lookup.empty()) {
         // Name lookup didn't find anything. Determine whether this
         // was a typo for another field name.
         FieldInitializerValidatorCCC Validator(RT->getDecl());
         if (TypoCorrection Corrected = SemaRef.CorrectTypo(
                 DeclarationNameInfo(FieldName, D->getFieldLoc()),
-                Sema::LookupMemberName, /*Scope=*/ 0, /*SS=*/ 0, Validator,
-                RT->getDecl())) {
+                Sema::LookupMemberName, /*Scope=*/ nullptr, /*SS=*/ nullptr,
+                Validator, Sema::CTK_ErrorRecovery, RT->getDecl())) {
           SemaRef.diagnoseTypo(
               Corrected,
               SemaRef.PDiag(diag::err_field_designator_unknown_suggest)
@@ -1886,7 +2011,7 @@
 
           // remove existing initializer
           StructuredList->resizeInits(SemaRef.Context, 0);
-          StructuredList->setInitializedFieldInUnion(0);
+          StructuredList->setInitializedFieldInUnion(nullptr);
         }
 
         StructuredList->setInitializedFieldInUnion(*Field);
@@ -1984,7 +2109,7 @@
       InitializedEntity MemberEntity =
         InitializedEntity::InitializeMember(*Field, &Entity);
       if (CheckDesignatedInitializer(MemberEntity, IList, DIE, DesigIdx + 1,
-                                     FieldType, 0, 0, Index,
+                                     FieldType, nullptr, nullptr, Index,
                                      StructuredList, newStructuredIndex,
                                      true, false))
         return true;
@@ -2043,7 +2168,7 @@
     return true;
   }
 
-  Expr *IndexExpr = 0;
+  Expr *IndexExpr = nullptr;
   llvm::APSInt DesignatedStartIndex, DesignatedEndIndex;
   if (D->isArrayDesignator()) {
     IndexExpr = DIE->getArrayIndex(*D);
@@ -2128,7 +2253,7 @@
             Context, CodeUnit, PromotedCharTy, SubExpr->getExprLoc());
         if (CharTy != PromotedCharTy)
           Init = ImplicitCastExpr::Create(Context, CharTy, CK_IntegralCast,
-                                          Init, 0, VK_RValue);
+                                          Init, nullptr, VK_RValue);
         StructuredList->updateInit(Context, i, Init);
       }
     } else {
@@ -2150,7 +2275,7 @@
             Context, CodeUnit, PromotedCharTy, SubExpr->getExprLoc());
         if (CharTy != PromotedCharTy)
           Init = ImplicitCastExpr::Create(Context, CharTy, CK_IntegralCast,
-                                          Init, 0, VK_RValue);
+                                          Init, nullptr, VK_RValue);
         StructuredList->updateInit(Context, i, Init);
       }
     }
@@ -2180,7 +2305,7 @@
 
     ElementEntity.setElementIndex(ElementIndex);
     if (CheckDesignatedInitializer(ElementEntity, IList, DIE, DesigIdx + 1,
-                                   ElementType, 0, 0, Index,
+                                   ElementType, nullptr, nullptr, Index,
                                    StructuredList, ElementIndex,
                                    (DesignatedStartIndex == DesignatedEndIndex),
                                    false))
@@ -2220,8 +2345,8 @@
                                             unsigned StructuredIndex,
                                             SourceRange InitRange) {
   if (VerifyOnly)
-    return 0; // No structured list in verification-only mode.
-  Expr *ExistingInit = 0;
+    return nullptr; // No structured list in verification-only mode.
+  Expr *ExistingInit = nullptr;
   if (!StructuredList)
     ExistingInit = SyntacticToSemantic.lookup(IList);
   else if (StructuredIndex < StructuredList->getNumInits())
@@ -2291,8 +2416,7 @@
     if (RDecl->isUnion())
       NumElements = 1;
     else
-      NumElements = std::distance(RDecl->field_begin(),
-                                  RDecl->field_end());
+      NumElements = std::distance(RDecl->field_begin(), RDecl->field_end());
   }
 
   Result->reserveInits(SemaRef.Context, NumElements);
@@ -2380,7 +2504,7 @@
       Expr *Index = static_cast<Expr *>(D.getArrayIndex());
       llvm::APSInt IndexValue;
       if (!Index->isTypeDependent() && !Index->isValueDependent())
-        Index = CheckArrayDesignatorExpr(*this, Index, IndexValue).take();
+        Index = CheckArrayDesignatorExpr(*this, Index, IndexValue).get();
       if (!Index)
         Invalid = true;
       else {
@@ -2403,9 +2527,9 @@
                           EndIndex->isValueDependent();
       if (!StartDependent)
         StartIndex =
-            CheckArrayDesignatorExpr(*this, StartIndex, StartValue).take();
+            CheckArrayDesignatorExpr(*this, StartIndex, StartValue).get();
       if (!EndDependent)
-        EndIndex = CheckArrayDesignatorExpr(*this, EndIndex, EndValue).take();
+        EndIndex = CheckArrayDesignatorExpr(*this, EndIndex, EndValue).get();
 
       if (!StartIndex || !EndIndex)
         Invalid = true;
@@ -2447,13 +2571,13 @@
     = DesignatedInitExpr::Create(Context,
                                  Designators.data(), Designators.size(),
                                  InitExpressions, Loc, GNUSyntax,
-                                 Init.takeAs<Expr>());
+                                 Init.getAs<Expr>());
 
   if (!getLangOpts().C99)
     Diag(DIE->getLocStart(), diag::ext_designated_init)
       << DIE->getSourceRange();
 
-  return Owned(DIE);
+  return DIE;
 }
 
 //===----------------------------------------------------------------------===//
@@ -2484,7 +2608,7 @@
                                   bool IsInheritedVirtualBase) {
   InitializedEntity Result;
   Result.Kind = EK_Base;
-  Result.Parent = 0;
+  Result.Parent = nullptr;
   Result.Base = reinterpret_cast<uintptr_t>(Base);
   if (IsInheritedVirtualBase)
     Result.Base |= 0x01;
@@ -2506,7 +2630,7 @@
     return VariableOrMember->getDeclName();
 
   case EK_LambdaCapture:
-    return Capture.Var->getDeclName();
+    return DeclarationName(Capture.VarID);
       
   case EK_Result:
   case EK_Exception:
@@ -2549,7 +2673,7 @@
   case EK_LambdaCapture:
   case EK_CompoundLiteralInit:
   case EK_RelatedResult:
-    return 0;
+    return nullptr;
   }
 
   llvm_unreachable("Invalid EntityKind!");
@@ -2608,7 +2732,7 @@
   case EK_BlockElement: OS << "Block"; break;
   case EK_LambdaCapture:
     OS << "LambdaCapture ";
-    getCapturedVar()->printName(OS);
+    OS << DeclarationName(Capture.VarID);
     break;
   }
 
@@ -2643,12 +2767,13 @@
   case SK_QualificationConversionRValue:
   case SK_QualificationConversionXValue:
   case SK_QualificationConversionLValue:
+  case SK_AtomicConversion:
   case SK_LValueToRValue:
   case SK_ListInitialization:
-  case SK_ListConstructorCall:
   case SK_UnwrapInitList:
   case SK_RewrapInitList:
   case SK_ConstructorInitialization:
+  case SK_ConstructorInitializationFromList:
   case SK_ZeroInitialization:
   case SK_CAssignment:
   case SK_StringInit:
@@ -2659,6 +2784,7 @@
   case SK_PassByIndirectRestore:
   case SK_ProduceObjCObject:
   case SK_StdInitializerList:
+  case SK_StdInitializerListConstructorCall:
   case SK_OCLSamplerInit:
   case SK_OCLZeroEvent:
     break;
@@ -2794,6 +2920,13 @@
   Steps.push_back(S);
 }
 
+void InitializationSequence::AddAtomicConversionStep(QualType Ty) {
+  Step S;
+  S.Kind = SK_AtomicConversion;
+  S.Type = Ty;
+  Steps.push_back(S);
+}
+
 void InitializationSequence::AddLValueToRValueStep(QualType Ty) {
   assert(!Ty.hasQualifiers() && "rvalues may not have qualifiers");
 
@@ -2829,8 +2962,9 @@
                                    bool HadMultipleCandidates,
                                    bool FromInitList, bool AsInitList) {
   Step S;
-  S.Kind = FromInitList && !AsInitList ? SK_ListConstructorCall
-                                       : SK_ConstructorInitialization;
+  S.Kind = FromInitList ? AsInitList ? SK_StdInitializerListConstructorCall
+                                     : SK_ConstructorInitializationFromList
+                        : SK_ConstructorInitialization;
   S.Type = T;
   S.Function.HadMultipleCandidates = HadMultipleCandidates;
   S.Function.Function = Constructor;
@@ -3026,7 +3160,7 @@
     bool SuppressUserConversions = false;
 
     // Find the constructor (which may be a template).
-    CXXConstructorDecl *Constructor = 0;
+    CXXConstructorDecl *Constructor = nullptr;
     FunctionTemplateDecl *ConstructorTmpl = dyn_cast<FunctionTemplateDecl>(D);
     if (ConstructorTmpl)
       Constructor = cast<CXXConstructorDecl>(
@@ -3057,7 +3191,7 @@
         (!OnlyListConstructors || S.isInitListConstructor(Constructor))) {
       if (ConstructorTmpl)
         S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl,
-                                       /*ExplicitArgs*/ 0, Args,
+                                       /*ExplicitArgs*/ nullptr, Args,
                                        CandidateSet, SuppressUserConversions);
       else {
         // C++ [over.match.copy]p1:
@@ -3243,7 +3377,7 @@
                                    const InitializedEntity &Entity,
                                    const InitializationKind &Kind,
                                    InitializationSequence &Sequence,
-                                   InitListExpr *InitList = 0);
+                                   InitListExpr *InitList = nullptr);
 
 /// \brief Attempt list initialization of a reference.
 static void TryReferenceListInitialization(Sema &S,
@@ -3442,7 +3576,7 @@
   bool AllowExplicit = Kind.AllowExplicit();
   bool AllowExplicitConvs = Kind.allowExplicitConversionFunctionsInRefBinding();
 
-  const RecordType *T1RecordType = 0;
+  const RecordType *T1RecordType = nullptr;
   if (AllowRValues && (T1RecordType = T1->getAs<RecordType>()) &&
       !S.RequireCompleteType(Kind.getLocation(), T1, 0)) {
     // The type we're converting to is a class type. Enumerate its constructors
@@ -3460,7 +3594,7 @@
       DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess());
 
       // Find the constructor (which may be a template).
-      CXXConstructorDecl *Constructor = 0;
+      CXXConstructorDecl *Constructor = nullptr;
       FunctionTemplateDecl *ConstructorTmpl = dyn_cast<FunctionTemplateDecl>(D);
       if (ConstructorTmpl)
         Constructor = cast<CXXConstructorDecl>(
@@ -3472,7 +3606,7 @@
           Constructor->isConvertingConstructor(AllowExplicit)) {
         if (ConstructorTmpl)
           S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl,
-                                         /*ExplicitArgs*/ 0,
+                                         /*ExplicitArgs*/ nullptr,
                                          Initializer, CandidateSet,
                                          /*SuppressUserConversions=*/true);
         else
@@ -3485,7 +3619,7 @@
   if (T1RecordType && T1RecordType->getDecl()->isInvalidDecl())
     return OR_No_Viable_Function;
 
-  const RecordType *T2RecordType = 0;
+  const RecordType *T2RecordType = nullptr;
   if ((T2RecordType = T2->getAs<RecordType>()) &&
       !S.RequireCompleteType(Kind.getLocation(), T2, 0)) {
     // The type we're converting from is a class type, enumerate its conversion
@@ -3520,10 +3654,13 @@
         if (ConvTemplate)
           S.AddTemplateConversionCandidate(ConvTemplate, I.getPair(),
                                            ActingDC, Initializer,
-                                           DestType, CandidateSet);
+                                           DestType, CandidateSet,
+                                           /*AllowObjCConversionOnExplicit=*/
+                                             false);
         else
           S.AddConversionCandidate(Conv, I.getPair(), ActingDC,
-                                   Initializer, DestType, CandidateSet);
+                                   Initializer, DestType, CandidateSet,
+                                   /*AllowObjCConversionOnExplicit=*/false);
       }
     }
   }
@@ -3545,7 +3682,7 @@
 
   // Compute the returned type of the conversion.
   if (isa<CXXConversionDecl>(Function))
-    T2 = Function->getResultType();
+    T2 = Function->getReturnType();
   else
     T2 = cv1T1;
 
@@ -4045,12 +4182,11 @@
 /// which enumerates all conversion functions and performs overload resolution
 /// to select the best.
 static void TryUserDefinedConversion(Sema &S,
-                                     const InitializedEntity &Entity,
+                                     QualType DestType,
                                      const InitializationKind &Kind,
                                      Expr *Initializer,
                                      InitializationSequence &Sequence,
                                      bool TopLevelOfInitList) {
-  QualType DestType = Entity.getType();
   assert(!DestType->isReferenceType() && "References are handled elsewhere");
   QualType SourceType = Initializer->getType();
   assert((DestType->isRecordType() || SourceType->isRecordType()) &&
@@ -4085,7 +4221,7 @@
         DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess());
 
         // Find the constructor (which may be a template).
-        CXXConstructorDecl *Constructor = 0;
+        CXXConstructorDecl *Constructor = nullptr;
         FunctionTemplateDecl *ConstructorTmpl
           = dyn_cast<FunctionTemplateDecl>(D);
         if (ConstructorTmpl)
@@ -4098,7 +4234,7 @@
             Constructor->isConvertingConstructor(AllowExplicit)) {
           if (ConstructorTmpl)
             S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl,
-                                           /*ExplicitArgs*/ 0,
+                                           /*ExplicitArgs*/ nullptr,
                                            Initializer, CandidateSet,
                                            /*SuppressUserConversions=*/true);
           else
@@ -4143,10 +4279,11 @@
           if (ConvTemplate)
             S.AddTemplateConversionCandidate(ConvTemplate, I.getPair(),
                                              ActingDC, Initializer, DestType,
-                                             CandidateSet);
+                                             CandidateSet, AllowExplicit);
           else
             S.AddConversionCandidate(Conv, I.getPair(), ActingDC,
-                                     Initializer, DestType, CandidateSet);
+                                     Initializer, DestType, CandidateSet,
+                                     AllowExplicit);
         }
       }
     }
@@ -4413,7 +4550,7 @@
                                                const InitializationKind &Kind,
                                                MultiExprArg Args,
                                                bool TopLevelOfInitList)
-    : FailedCandidateSet(Kind.getLocation()) {
+    : FailedCandidateSet(Kind.getLocation(), OverloadCandidateSet::CSK_Normal) {
   InitializeFrom(S, Entity, Kind, Args, TopLevelOfInitList);
 }
 
@@ -4436,7 +4573,7 @@
         SetFailed(FK_PlaceholderType);
         return;
       }
-      Args[I] = result.take();
+      Args[I] = result.get();
     }
 
   // C++0x [dcl.init]p16:
@@ -4457,9 +4594,16 @@
   setSequenceKind(NormalSequence);
 
   QualType SourceType;
-  Expr *Initializer = 0;
+  Expr *Initializer = nullptr;
   if (Args.size() == 1) {
     Initializer = Args[0];
+    if (S.getLangOpts().ObjC1) {
+      if (S.CheckObjCBridgeRelatedConversions(Initializer->getLocStart(),
+                                              DestType, Initializer->getType(),
+                                              Initializer) ||
+          S.ConversionToObjCStringLiteralCheck(DestType, Initializer))
+        Args[0] = Initializer;
+    }
     if (!isa<InitListExpr>(Initializer))
       SourceType = Initializer->getType();
   }
@@ -4603,7 +4747,7 @@
          (Context.hasSameUnqualifiedType(SourceType, DestType) ||
           S.IsDerivedFrom(SourceType, DestType))))
       TryConstructorInitialization(S, Entity, Kind, Args,
-                                   Entity.getType(), *this);
+                                   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
@@ -4611,7 +4755,7 @@
     //       13.3.1.4, and the best one is chosen through overload resolution
     //       (13.3).
     else
-      TryUserDefinedConversion(S, Entity, Kind, Initializer, *this,
+      TryUserDefinedConversion(S, DestType, Kind, Initializer, *this,
                                TopLevelOfInitList);
     return;
   }
@@ -4625,9 +4769,22 @@
   //    - Otherwise, if the source type is a (possibly cv-qualified) class
   //      type, conversion functions are considered.
   if (!SourceType.isNull() && SourceType->isRecordType()) {
-    TryUserDefinedConversion(S, Entity, Kind, Initializer, *this,
+    // For a conversion to _Atomic(T) from either T or a class type derived
+    // from T, initialize the T object then convert to _Atomic type.
+    bool NeedAtomicConversion = false;
+    if (const AtomicType *Atomic = DestType->getAs<AtomicType>()) {
+      if (Context.hasSameUnqualifiedType(SourceType, Atomic->getValueType()) ||
+          S.IsDerivedFrom(SourceType, Atomic->getValueType())) {
+        DestType = Atomic->getValueType();
+        NeedAtomicConversion = true;
+      }
+    }
+
+    TryUserDefinedConversion(S, DestType, Kind, Initializer, *this,
                              TopLevelOfInitList);
     MaybeProduceObjCObject(S, *this, Entity);
+    if (!Failed() && NeedAtomicConversion)
+      AddAtomicConversionStep(Entity.getType());
     return;
   }
 
@@ -4636,16 +4793,16 @@
   //      conversions (Clause 4) will be used, if necessary, to convert the
   //      initializer expression to the cv-unqualified version of the
   //      destination type; no user-defined conversions are considered.
-      
+
   ImplicitConversionSequence ICS
-    = S.TryImplicitConversion(Initializer, Entity.getType(),
+    = S.TryImplicitConversion(Initializer, DestType,
                               /*SuppressUserConversions*/true,
                               /*AllowExplicitConversions*/ false,
                               /*InOverloadResolution*/ false,
                               /*CStyle=*/Kind.isCStyleOrFunctionalCast(),
                               allowObjCWritebackConversion);
-      
-  if (ICS.isStandard() && 
+
+  if (ICS.isStandard() &&
       ICS.Standard.Second == ICK_Writeback_Conversion) {
     // Objective-C ARC writeback conversion.
     
@@ -4666,7 +4823,7 @@
       AddConversionSequenceStep(LvalueICS, ICS.Standard.getToType(0));
     }
     
-    AddPassByIndirectCopyRestoreStep(Entity.getType(), ShouldCopy);
+    AddPassByIndirectCopyRestoreStep(DestType, ShouldCopy);
   } else if (ICS.isBad()) {
     DeclAccessPair dap;
     if (isLibstdcxxPointerReturnFalseHack(S, Entity, Initializer)) {
@@ -4678,7 +4835,7 @@
     else
       SetFailed(InitializationSequence::FK_ConversionFailed);
   } else {
-    AddConversionSequenceStep(ICS, Entity.getType(), TopLevelOfInitList);
+    AddConversionSequenceStep(ICS, DestType, TopLevelOfInitList);
 
     MaybeProduceObjCObject(S, *this, Entity);
   }
@@ -4811,7 +4968,7 @@
   for (SmallVectorImpl<NamedDecl *>::iterator
          CI = Ctors.begin(), CE = Ctors.end(); CI != CE; ++CI) {
     NamedDecl *D = *CI;
-    CXXConstructorDecl *Constructor = 0;
+    CXXConstructorDecl *Constructor = nullptr;
 
     if ((Constructor = dyn_cast<CXXConstructorDecl>(D))) {
       // Handle copy/moveconstructors, only.
@@ -4841,7 +4998,7 @@
     // candidates?
     DeclAccessPair FoundDecl
       = DeclAccessPair::make(ConstructorTmpl, ConstructorTmpl->getAccess());
-    S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl, 0,
+    S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl, nullptr,
                                    CurInitExpr, CandidateSet, true);
   }
 }
@@ -4907,7 +5064,7 @@
                              bool IsExtraneousCopy) {
   // Determine which class type we're copying to.
   Expr *CurInitExpr = (Expr *)CurInit.get();
-  CXXRecordDecl *Class = 0;
+  CXXRecordDecl *Class = nullptr;
   if (const RecordType *Record = T->getAs<RecordType>())
     Class = cast<CXXRecordDecl>(Record->getDecl());
   if (!Class)
@@ -4939,7 +5096,7 @@
   // Only consider constructors and constructor templates. Per
   // C++0x [dcl.init]p16, second bullet to class types, this initialization
   // is direct-initialization.
-  OverloadCandidateSet CandidateSet(Loc);
+  OverloadCandidateSet CandidateSet(Loc, OverloadCandidateSet::CSK_Normal);
   LookupCopyAndMoveConstructors(S, CandidateSet, Class, CurInitExpr);
 
   bool HadMultipleCandidates = (CandidateSet.size() > 1);
@@ -4977,7 +5134,7 @@
 
   CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(Best->Function);
   SmallVector<Expr*, 8> ConstructorArgs;
-  CurInit.release(); // Ownership transferred into MultiExprArg, below.
+  CurInit.get(); // Ownership transferred into MultiExprArg, below.
 
   S.CheckConstructorAccess(Loc, Constructor, Entity,
                            Best->FoundDecl.getAccess(), IsExtraneousCopy);
@@ -5005,7 +5162,7 @@
       S.BuildCXXDefaultArgExpr(Loc, Constructor, Parm);
     }
 
-    return S.Owned(CurInitExpr);
+    return CurInitExpr;
   }
 
   // Determine the arguments required to actually perform the
@@ -5019,13 +5176,14 @@
                                     ConstructorArgs,
                                     HadMultipleCandidates,
                                     /*ListInit*/ false,
+                                    /*StdInitListInit*/ false,
                                     /*ZeroInit*/ false,
                                     CXXConstructExpr::CK_Complete,
                                     SourceRange());
 
   // If we're supposed to bind temporaries, do so.
   if (!CurInit.isInvalid() && shouldBindAsTemporary(Entity))
-    CurInit = S.MaybeBindToTemporary(CurInit.takeAs<Expr>());
+    CurInit = S.MaybeBindToTemporary(CurInit.getAs<Expr>());
   return CurInit;
 }
 
@@ -5042,12 +5200,11 @@
     return;
 
   SourceLocation Loc = getInitializationLoc(Entity, CurInitExpr);
-  if (S.Diags.getDiagnosticLevel(diag::warn_cxx98_compat_temp_copy, Loc)
-        == DiagnosticsEngine::Ignored)
+  if (S.Diags.isIgnored(diag::warn_cxx98_compat_temp_copy, Loc))
     return;
 
   // Find constructors which would have been considered.
-  OverloadCandidateSet CandidateSet(Loc);
+  OverloadCandidateSet CandidateSet(Loc, OverloadCandidateSet::CSK_Normal);
   LookupCopyAndMoveConstructors(
       S, CandidateSet, cast<CXXRecordDecl>(Record->getDecl()), CurInitExpr);
 
@@ -5141,6 +5298,7 @@
                                  const InitializationSequence::Step& Step,
                                  bool &ConstructorInitRequiresZeroInit,
                                  bool IsListInitialization,
+                                 bool IsStdInitListInitialization,
                                  SourceLocation LBraceLoc,
                                  SourceLocation RBraceLoc) {
   unsigned NumArgs = Args.size();
@@ -5164,7 +5322,7 @@
       S.DefineImplicitDefaultConstructor(Loc, Constructor);
   }
 
-  ExprResult CurInit = S.Owned((Expr *)0);
+  ExprResult CurInit((Expr *)nullptr);
 
   // C++ [over.match.copy]p1:
   //   - When initializing a temporary to be bound to the first parameter 
@@ -5199,13 +5357,10 @@
       ? SourceRange(LBraceLoc, RBraceLoc)
       : Kind.getParenRange();
 
-    CurInit = S.Owned(
-      new (S.Context) CXXTemporaryObjectExpr(S.Context, Constructor,
-                                             TSInfo, ConstructorArgs,
-                                             ParenOrBraceRange,
-                                             HadMultipleCandidates,
-                                             IsListInitialization,
-                                             ConstructorInitRequiresZeroInit));
+    CurInit = new (S.Context) CXXTemporaryObjectExpr(
+        S.Context, Constructor, TSInfo, ConstructorArgs, ParenOrBraceRange,
+        HadMultipleCandidates, IsListInitialization,
+        IsStdInitListInitialization, ConstructorInitRequiresZeroInit);
   } else {
     CXXConstructExpr::ConstructionKind ConstructKind =
       CXXConstructExpr::CK_Complete;
@@ -5218,10 +5373,13 @@
       ConstructKind = CXXConstructExpr::CK_Delegating;
     }
 
-    // Only get the parenthesis range if it is a direct construction.
-    SourceRange parenRange =
-        Kind.getKind() == InitializationKind::IK_Direct ?
-        Kind.getParenRange() : SourceRange();
+    // Only get the parenthesis or brace range if it is a list initialization or
+    // direct construction.
+    SourceRange ParenOrBraceRange;
+    if (IsListInitialization)
+      ParenOrBraceRange = SourceRange(LBraceLoc, RBraceLoc);
+    else if (Kind.getKind() == InitializationKind::IK_Direct)
+      ParenOrBraceRange = Kind.getParenRange();
 
     // If the entity allows NRVO, mark the construction as elidable
     // unconditionally.
@@ -5231,18 +5389,20 @@
                                         ConstructorArgs,
                                         HadMultipleCandidates,
                                         IsListInitialization,
+                                        IsStdInitListInitialization,
                                         ConstructorInitRequiresZeroInit,
                                         ConstructKind,
-                                        parenRange);
+                                        ParenOrBraceRange);
     else
       CurInit = S.BuildCXXConstructExpr(Loc, Entity.getType(),
                                         Constructor,
                                         ConstructorArgs,
                                         HadMultipleCandidates,
                                         IsListInitialization,
+                                        IsStdInitListInitialization,
                                         ConstructorInitRequiresZeroInit,
                                         ConstructKind,
-                                        parenRange);
+                                        ParenOrBraceRange);
   }
   if (CurInit.isInvalid())
     return ExprError();
@@ -5254,7 +5414,7 @@
     return ExprError();
 
   if (shouldBindAsTemporary(Entity))
-    CurInit = S.MaybeBindToTemporary(CurInit.take());
+    CurInit = S.MaybeBindToTemporary(CurInit.get());
 
   return CurInit;
 }
@@ -5302,25 +5462,25 @@
 /// Determine the declaration which an initialized entity ultimately refers to,
 /// for the purpose of lifetime-extending a temporary bound to a reference in
 /// the initialization of \p Entity.
-static const ValueDecl *
-getDeclForTemporaryLifetimeExtension(const InitializedEntity &Entity,
-                                     const ValueDecl *FallbackDecl = 0) {
+static const InitializedEntity *getEntityForTemporaryLifetimeExtension(
+    const InitializedEntity *Entity,
+    const InitializedEntity *FallbackDecl = nullptr) {
   // C++11 [class.temporary]p5:
-  switch (Entity.getKind()) {
+  switch (Entity->getKind()) {
   case InitializedEntity::EK_Variable:
     //   The temporary [...] persists for the lifetime of the reference
-    return Entity.getDecl();
+    return Entity;
 
   case InitializedEntity::EK_Member:
     // For subobjects, we look at the complete object.
-    if (Entity.getParent())
-      return getDeclForTemporaryLifetimeExtension(*Entity.getParent(),
-                                                  Entity.getDecl());
+    if (Entity->getParent())
+      return getEntityForTemporaryLifetimeExtension(Entity->getParent(),
+                                                    Entity);
 
     //   except:
     //   -- A temporary bound to a reference member in a constructor's
     //      ctor-initializer persists until the constructor exits.
-    return Entity.getDecl();
+    return Entity;
 
   case InitializedEntity::EK_Parameter:
   case InitializedEntity::EK_Parameter_CF_Audited:
@@ -5335,7 +5495,7 @@
     //   -- A temporary bound to a reference in a new-initializer persists
     //      until the completion of the full-expression containing the
     //      new-initializer.
-    return 0;
+    return nullptr;
 
   case InitializedEntity::EK_Temporary:
   case InitializedEntity::EK_CompoundLiteralInit:
@@ -5343,12 +5503,12 @@
     // We don't yet know the storage duration of the surrounding temporary.
     // Assume it's got full-expression duration for now, it will patch up our
     // storage duration if that's not correct.
-    return 0;
+    return nullptr;
 
   case InitializedEntity::EK_ArrayElement:
     // For subobjects, we look at the complete object.
-    return getDeclForTemporaryLifetimeExtension(*Entity.getParent(),
-                                                FallbackDecl);
+    return getEntityForTemporaryLifetimeExtension(Entity->getParent(),
+                                                  FallbackDecl);
 
   case InitializedEntity::EK_Base:
   case InitializedEntity::EK_Delegating:
@@ -5363,17 +5523,20 @@
   case InitializedEntity::EK_Exception:
   case InitializedEntity::EK_VectorElement:
   case InitializedEntity::EK_ComplexElement:
-    return 0;
+    return nullptr;
   }
   llvm_unreachable("unknown entity kind");
 }
 
-static void performLifetimeExtension(Expr *Init, const ValueDecl *ExtendingD);
+static void performLifetimeExtension(Expr *Init,
+                                     const InitializedEntity *ExtendingEntity);
 
 /// Update a glvalue expression that is used as the initializer of a reference
 /// to note that its lifetime is extended.
 /// \return \c true if any temporary had its lifetime extended.
-static bool performReferenceExtension(Expr *Init, const ValueDecl *ExtendingD) {
+static bool
+performReferenceExtension(Expr *Init,
+                          const InitializedEntity *ExtendingEntity) {
   if (InitListExpr *ILE = dyn_cast<InitListExpr>(Init)) {
     if (ILE->getNumInits() == 1 && ILE->isGLValue()) {
       // This is just redundant braces around an initializer. Step over it.
@@ -5407,8 +5570,9 @@
   if (MaterializeTemporaryExpr *ME = dyn_cast<MaterializeTemporaryExpr>(Init)) {
     // Update the storage duration of the materialized temporary.
     // FIXME: Rebuild the expression instead of mutating it.
-    ME->setExtendingDecl(ExtendingD);
-    performLifetimeExtension(ME->GetTemporaryExpr(), ExtendingD);
+    ME->setExtendingDecl(ExtendingEntity->getDecl(),
+                         ExtendingEntity->allocateManglingNumber());
+    performLifetimeExtension(ME->GetTemporaryExpr(), ExtendingEntity);
     return true;
   }
 
@@ -5417,7 +5581,8 @@
 
 /// Update a prvalue expression that is going to be materialized as a
 /// lifetime-extended temporary.
-static void performLifetimeExtension(Expr *Init, const ValueDecl *ExtendingD) {
+static void performLifetimeExtension(Expr *Init,
+                                     const InitializedEntity *ExtendingEntity) {
   // Dig out the expression which constructs the extended temporary.
   SmallVector<const Expr *, 2> CommaLHSs;
   SmallVector<SubobjectAdjustment, 2> Adjustments;
@@ -5429,14 +5594,14 @@
 
   if (CXXStdInitializerListExpr *ILE =
           dyn_cast<CXXStdInitializerListExpr>(Init)) {
-    performReferenceExtension(ILE->getSubExpr(), ExtendingD);
+    performReferenceExtension(ILE->getSubExpr(), ExtendingEntity);
     return;
   }
 
   if (InitListExpr *ILE = dyn_cast<InitListExpr>(Init)) {
     if (ILE->getType()->isArrayType()) {
       for (unsigned I = 0, N = ILE->getNumInits(); I != N; ++I)
-        performLifetimeExtension(ILE->getInit(I), ExtendingD);
+        performLifetimeExtension(ILE->getInit(I), ExtendingEntity);
       return;
     }
 
@@ -5448,25 +5613,23 @@
       // bound to temporaries, those temporaries are also lifetime-extended.
       if (RD->isUnion() && ILE->getInitializedFieldInUnion() &&
           ILE->getInitializedFieldInUnion()->getType()->isReferenceType())
-        performReferenceExtension(ILE->getInit(0), ExtendingD);
+        performReferenceExtension(ILE->getInit(0), ExtendingEntity);
       else {
         unsigned Index = 0;
-        for (RecordDecl::field_iterator I = RD->field_begin(),
-                                        E = RD->field_end();
-             I != E; ++I) {
+        for (const auto *I : RD->fields()) {
           if (Index >= ILE->getNumInits())
             break;
           if (I->isUnnamedBitfield())
             continue;
           Expr *SubInit = ILE->getInit(Index);
           if (I->getType()->isReferenceType())
-            performReferenceExtension(SubInit, ExtendingD);
+            performReferenceExtension(SubInit, ExtendingEntity);
           else if (isa<InitListExpr>(SubInit) ||
                    isa<CXXStdInitializerListExpr>(SubInit))
             // This may be either aggregate-initialization of a member or
             // initialization of a std::initializer_list object. Either way,
             // we should recursively lifetime-extend that initializer.
-            performLifetimeExtension(SubInit, ExtendingD);
+            performLifetimeExtension(SubInit, ExtendingEntity);
           ++Index;
         }
       }
@@ -5555,7 +5718,7 @@
 
           *ResultType
             = S.Context.getDependentSizedArrayType(ArrayT->getElementType(),
-                                                   /*NumElts=*/0,
+                                                   /*NumElts=*/nullptr,
                                                    ArrayT->getSizeModifier(),
                                        ArrayT->getIndexTypeCVRQualifiers(),
                                                    Brackets);
@@ -5578,7 +5741,7 @@
 
   // No steps means no initialization.
   if (Steps.empty())
-    return S.Owned((Expr *)0);
+    return ExprResult((Expr *)nullptr);
 
   if (S.getLangOpts().CPlusPlus11 && Entity.getType()->isReferenceType() &&
       Args.size() == 1 && isa<InitListExpr>(Args[0]) &&
@@ -5611,7 +5774,7 @@
     *ResultType = Entity.getDecl() ? Entity.getDecl()->getType() :
                                      Entity.getType();
 
-  ExprResult CurInit = S.Owned((Expr *)0);
+  ExprResult CurInit((Expr *)nullptr);
 
   // For initialization steps that start with a single initializer,
   // grab the only argument out the Args and place it into the "current"
@@ -5628,6 +5791,7 @@
   case SK_QualificationConversionLValue:
   case SK_QualificationConversionXValue:
   case SK_QualificationConversionRValue:
+  case SK_AtomicConversion:
   case SK_LValueToRValue:
   case SK_ConversionSequence:
   case SK_ConversionSequenceNoNarrowing:
@@ -5652,7 +5816,8 @@
   }
 
   case SK_ConstructorInitialization:
-  case SK_ListConstructorCall:
+  case SK_ConstructorInitializationFromList:
+  case SK_StdInitializerListConstructorCall:
   case SK_ZeroInitialization:
     break;
   }
@@ -5710,11 +5875,9 @@
               (Step->Kind == SK_CastDerivedToBaseXValue ?
                    VK_XValue :
                    VK_RValue);
-      CurInit = S.Owned(ImplicitCastExpr::Create(S.Context,
-                                                 Step->Type,
-                                                 CK_DerivedToBase,
-                                                 CurInit.get(),
-                                                 &BasePath, VK));
+      CurInit =
+          ImplicitCastExpr::Create(S.Context, Step->Type, CK_DerivedToBase,
+                                   CurInit.get(), &BasePath, VK);
       break;
     }
 
@@ -5726,7 +5889,7 @@
         S.Diag(Kind.getLocation(), diag::err_reference_bind_to_bitfield)
           << Entity.getType().isVolatileQualified()
           << (BitField ? BitField->getDeclName() : DeclarationName())
-          << (BitField != NULL)
+          << (BitField != nullptr)
           << CurInit.get()->getSourceRange();
         if (BitField)
           S.Diag(BitField->getLocation(), diag::note_bitfield_decl);
@@ -5752,12 +5915,12 @@
       // Even though we didn't materialize a temporary, the binding may still
       // extend the lifetime of a temporary. This happens if we bind a reference
       // to the result of a cast to reference type.
-      if (const ValueDecl *ExtendingDecl =
-              getDeclForTemporaryLifetimeExtension(Entity)) {
-        if (performReferenceExtension(CurInit.get(), ExtendingDecl))
-          warnOnLifetimeExtension(S, Entity, CurInit.get(), false,
-                                  ExtendingDecl);
-      }
+      if (const InitializedEntity *ExtendingEntity =
+              getEntityForTemporaryLifetimeExtension(&Entity))
+        if (performReferenceExtension(CurInit.get(), ExtendingEntity))
+          warnOnLifetimeExtension(S, Entity, CurInit.get(),
+                                  /*IsInitializerList=*/false,
+                                  ExtendingEntity->getDecl());
 
       break;
 
@@ -5769,19 +5932,18 @@
       if (S.CheckExceptionSpecCompatibility(CurInit.get(), DestType))
         return ExprError();
 
-      // Maybe lifetime-extend the temporary's subobjects to match the
-      // entity's lifetime.
-      const ValueDecl *ExtendingDecl =
-          getDeclForTemporaryLifetimeExtension(Entity);
-      if (ExtendingDecl) {
-        performLifetimeExtension(CurInit.get(), ExtendingDecl);
-        warnOnLifetimeExtension(S, Entity, CurInit.get(), false, ExtendingDecl);
-      }
-
       // Materialize the temporary into memory.
       MaterializeTemporaryExpr *MTE = new (S.Context) MaterializeTemporaryExpr(
           Entity.getType().getNonReferenceType(), CurInit.get(),
-          Entity.getType()->isLValueReferenceType(), ExtendingDecl);
+          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,
+                                  ExtendingEntity->getDecl());
 
       // If we're binding to an Objective-C object that has lifetime, we
       // need cleanups. Likewise if we're extending this temporary to automatic
@@ -5793,7 +5955,7 @@
            MTE->getType().isDestructedType()))
         S.ExprNeedsCleanups = true;
 
-      CurInit = S.Owned(MTE);
+      CurInit = MTE;
       break;
     }
 
@@ -5815,7 +5977,7 @@
         // Build a call to the selected constructor.
         SmallVector<Expr*, 8> ConstructorArgs;
         SourceLocation Loc = CurInit.get()->getLocStart();
-        CurInit.release(); // Ownership transferred into MultiExprArg, below.
+        CurInit.get(); // Ownership transferred into MultiExprArg, below.
 
         // Determine the arguments required to actually perform the constructor
         // call.
@@ -5830,6 +5992,7 @@
                                           ConstructorArgs,
                                           HadMultipleCandidates,
                                           /*ListInit*/ false,
+                                          /*StdInitListInit*/ false,
                                           /*ZeroInit*/ false,
                                           CXXConstructExpr::CK_Complete,
                                           SourceRange());
@@ -5851,7 +6014,7 @@
       } else {
         // Build a call to the conversion function.
         CXXConversionDecl *Conversion = cast<CXXConversionDecl>(Fn);
-        S.CheckMemberOperatorAccess(Kind.getLocation(), CurInit.get(), 0,
+        S.CheckMemberOperatorAccess(Kind.getLocation(), CurInit.get(), nullptr,
                                     FoundFn);
         if (S.DiagnoseUseOfDecl(FoundFn, Kind.getLocation()))
           return ExprError();
@@ -5860,7 +6023,8 @@
         // derived-to-base conversion? I believe the answer is "no", because
         // we don't want to turn off access control here for c-style casts.
         ExprResult CurInitExprRes =
-          S.PerformObjectArgumentInitialization(CurInit.take(), /*Qualifier=*/0,
+          S.PerformObjectArgumentInitialization(CurInit.get(),
+                                                /*Qualifier=*/nullptr,
                                                 FoundFn, Conversion);
         if(CurInitExprRes.isInvalid())
           return ExprError();
@@ -5874,7 +6038,7 @@
 
         CastKind = CK_UserDefinedConversion;
 
-        CreatedObject = Conversion->getResultType()->isRecordType();
+        CreatedObject = Conversion->getReturnType()->isRecordType();
       }
 
       bool RequiresCopy = !IsCopy && !isReferenceBinding(Steps.back());
@@ -5893,12 +6057,11 @@
         }
       }
 
-      CurInit = S.Owned(ImplicitCastExpr::Create(S.Context,
-                                                 CurInit.get()->getType(),
-                                                 CastKind, CurInit.get(), 0,
-                                                CurInit.get()->getValueKind()));
+      CurInit = ImplicitCastExpr::Create(S.Context, CurInit.get()->getType(),
+                                         CastKind, CurInit.get(), nullptr,
+                                         CurInit.get()->getValueKind());
       if (MaybeBindToTemp)
-        CurInit = S.MaybeBindToTemporary(CurInit.takeAs<Expr>());
+        CurInit = S.MaybeBindToTemporary(CurInit.getAs<Expr>());
       if (RequiresCopy)
         CurInit = CopyObject(S, Entity.getType().getNonReferenceType(), Entity,
                              CurInit, /*IsExtraneousCopy=*/false);
@@ -5915,17 +6078,22 @@
               (Step->Kind == SK_QualificationConversionXValue ?
                    VK_XValue :
                    VK_RValue);
-      CurInit = S.ImpCastExprToType(CurInit.take(), Step->Type, CK_NoOp, VK);
+      CurInit = S.ImpCastExprToType(CurInit.get(), Step->Type, CK_NoOp, VK);
+      break;
+    }
+
+    case SK_AtomicConversion: {
+      assert(CurInit.get()->isRValue() && "cannot convert glvalue to atomic");
+      CurInit = S.ImpCastExprToType(CurInit.get(), Step->Type,
+                                    CK_NonAtomicToAtomic, VK_RValue);
       break;
     }
 
     case SK_LValueToRValue: {
       assert(CurInit.get()->isGLValue() && "cannot load from a prvalue");
-      CurInit = S.Owned(ImplicitCastExpr::Create(S.Context, Step->Type,
-                                                 CK_LValueToRValue,
-                                                 CurInit.take(),
-                                                 /*BasePath=*/0,
-                                                 VK_RValue));
+      CurInit = ImplicitCastExpr::Create(S.Context, Step->Type,
+                                         CK_LValueToRValue, CurInit.get(),
+                                         /*BasePath=*/nullptr, VK_RValue);
       break;
     }
 
@@ -5978,14 +6146,14 @@
 
       InitListExpr *StructuredInitList =
           PerformInitList.getFullyStructuredList();
-      CurInit.release();
+      CurInit.get();
       CurInit = shouldBindAsTemporary(InitEntity)
           ? S.MaybeBindToTemporary(StructuredInitList)
-          : S.Owned(StructuredInitList);
+          : StructuredInitList;
       break;
     }
 
-    case SK_ListConstructorCall: {
+    case SK_ConstructorInitializationFromList: {
       // 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.
@@ -6004,29 +6172,31 @@
                                                                    Entity,
                                                  Kind, Arg, *Step,
                                                ConstructorInitRequiresZeroInit,
-                                               /*IsListInitialization*/ true,
+                                               /*IsListInitialization*/true,
+                                               /*IsStdInitListInit*/false,
                                                InitList->getLBraceLoc(),
                                                InitList->getRBraceLoc());
       break;
     }
 
     case SK_UnwrapInitList:
-      CurInit = S.Owned(cast<InitListExpr>(CurInit.take())->getInit(0));
+      CurInit = cast<InitListExpr>(CurInit.get())->getInit(0);
       break;
 
     case SK_RewrapInitList: {
-      Expr *E = CurInit.take();
+      Expr *E = CurInit.get();
       InitListExpr *Syntactic = Step->WrappingSyntacticList;
       InitListExpr *ILE = new (S.Context) InitListExpr(S.Context,
           Syntactic->getLBraceLoc(), E, Syntactic->getRBraceLoc());
       ILE->setSyntacticForm(Syntactic);
       ILE->setType(E->getType());
       ILE->setValueKind(E->getValueKind());
-      CurInit = S.Owned(ILE);
+      CurInit = ILE;
       break;
     }
 
-    case SK_ConstructorInitialization: {
+    case SK_ConstructorInitialization:
+    case SK_StdInitializerListConstructorCall: {
       // 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.
@@ -6036,13 +6206,15 @@
       InitializedEntity TempEntity = InitializedEntity::InitializeTemporary(
                                         Entity.getType().getNonReferenceType());
       bool UseTemporary = Entity.getType()->isReferenceType();
-      CurInit = PerformConstructorInitialization(S, UseTemporary ? TempEntity
-                                                                 : Entity,
-                                                 Kind, Args, *Step,
-                                               ConstructorInitRequiresZeroInit,
-                                               /*IsListInitialization*/ false,
-                                               /*LBraceLoc*/ SourceLocation(),
-                                               /*RBraceLoc*/ SourceLocation());
+      bool IsStdInitListInit =
+          Step->Kind == SK_StdInitializerListConstructorCall;
+      CurInit = PerformConstructorInitialization(
+          S, UseTemporary ? TempEntity : Entity, Kind, Args, *Step,
+          ConstructorInitRequiresZeroInit,
+          /*IsListInitialization*/IsStdInitListInit,
+          /*IsStdInitListInitialization*/IsStdInitListInit,
+          /*LBraceLoc*/SourceLocation(),
+          /*RBraceLoc*/SourceLocation());
       break;
     }
 
@@ -6051,7 +6223,7 @@
       ++NextStep;
       if (NextStep != StepEnd &&
           (NextStep->Kind == SK_ConstructorInitialization ||
-           NextStep->Kind == SK_ListConstructorCall)) {
+           NextStep->Kind == SK_ConstructorInitializationFromList)) {
         // The need for zero-initialization is recorded directly into
         // the call to the object's constructor within the next step.
         ConstructorInitRequiresZeroInit = true;
@@ -6063,12 +6235,11 @@
           TSInfo = S.Context.getTrivialTypeSourceInfo(Step->Type,
                                                     Kind.getRange().getBegin());
 
-        CurInit = S.Owned(new (S.Context) CXXScalarValueInitExpr(
-                              TSInfo->getType().getNonLValueExprType(S.Context),
-                                                                 TSInfo,
-                                                    Kind.getRange().getEnd()));
+        CurInit = new (S.Context) CXXScalarValueInitExpr(
+            TSInfo->getType().getNonLValueExprType(S.Context), TSInfo,
+            Kind.getRange().getEnd());
       } else {
-        CurInit = S.Owned(new (S.Context) ImplicitValueInitExpr(Step->Type));
+        CurInit = new (S.Context) ImplicitValueInitExpr(Step->Type);
       }
       break;
     }
@@ -6115,7 +6286,7 @@
     }
 
     case SK_ObjCObjectConversion:
-      CurInit = S.ImpCastExprToType(CurInit.take(), Step->Type,
+      CurInit = S.ImpCastExprToType(CurInit.get(), Step->Type,
                           CK_ObjCObjectLValueCast,
                           CurInit.get()->getValueKind());
       break;
@@ -6153,15 +6324,15 @@
     case SK_PassByIndirectCopyRestore:
     case SK_PassByIndirectRestore:
       checkIndirectCopyRestoreSource(S, CurInit.get());
-      CurInit = S.Owned(new (S.Context)
-                        ObjCIndirectCopyRestoreExpr(CurInit.take(), Step->Type,
-                                Step->Kind == SK_PassByIndirectCopyRestore));
+      CurInit = new (S.Context) ObjCIndirectCopyRestoreExpr(
+          CurInit.get(), Step->Type,
+          Step->Kind == SK_PassByIndirectCopyRestore);
       break;
 
     case SK_ProduceObjCObject:
-      CurInit = S.Owned(ImplicitCastExpr::Create(S.Context, Step->Type,
-                                                 CK_ARCProduceObject,
-                                                 CurInit.take(), 0, VK_RValue));
+      CurInit =
+          ImplicitCastExpr::Create(S.Context, Step->Type, CK_ARCProduceObject,
+                                   CurInit.get(), nullptr, VK_RValue);
       break;
 
     case SK_StdInitializerList: {
@@ -6169,34 +6340,33 @@
              diag::warn_cxx98_compat_initializer_list_init)
         << CurInit.get()->getSourceRange();
 
-      // Maybe lifetime-extend the array temporary's subobjects to match the
-      // entity's lifetime.
-      const ValueDecl *ExtendingDecl =
-          getDeclForTemporaryLifetimeExtension(Entity);
-      if (ExtendingDecl) {
-        performLifetimeExtension(CurInit.get(), ExtendingDecl);
-        warnOnLifetimeExtension(S, Entity, CurInit.get(), true, ExtendingDecl);
-      }
-
       // Materialize the temporary into memory.
       MaterializeTemporaryExpr *MTE = new (S.Context)
           MaterializeTemporaryExpr(CurInit.get()->getType(), CurInit.get(),
-                                   /*lvalue reference*/ false, ExtendingDecl);
+                                   /*BoundToLvalueReference=*/false);
+
+      // Maybe lifetime-extend the array 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=*/true,
+                                  ExtendingEntity->getDecl());
 
       // Wrap it in a construction of a std::initializer_list<T>.
-      CurInit = S.Owned(
-          new (S.Context) CXXStdInitializerListExpr(Step->Type, MTE));
+      CurInit = new (S.Context) CXXStdInitializerListExpr(Step->Type, MTE);
 
       // Bind the result, in case the library has given initializer_list a
       // non-trivial destructor.
       if (shouldBindAsTemporary(Entity))
-        CurInit = S.MaybeBindToTemporary(CurInit.take());
+        CurInit = S.MaybeBindToTemporary(CurInit.get());
       break;
     }
 
     case SK_OCLSamplerInit: {
       assert(Step->Type->isSamplerT() && 
-             "Sampler initialization on non sampler type.");
+             "Sampler initialization on non-sampler type.");
 
       QualType SourceType = CurInit.get()->getType();
 
@@ -6212,9 +6382,9 @@
     }
     case SK_OCLZeroEvent: {
       assert(Step->Type->isEventT() && 
-             "Event initialization on non event type.");
+             "Event initialization on non-event type.");
 
-      CurInit = S.ImpCastExprToType(CurInit.take(), Step->Type,
+      CurInit = S.ImpCastExprToType(CurInit.get(), Step->Type,
                                     CK_ZeroToOCLEvent,
                                     CurInit.get()->getValueKind());
       break;
@@ -6246,8 +6416,7 @@
   if (!RD || !RD->hasUninitializedReferenceMember())
     return false;
 
-  for (CXXRecordDecl::field_iterator FI = RD->field_begin(),
-                                     FE = RD->field_end(); FI != FE; ++FI) {
+  for (const auto *FI : RD->fields()) {
     if (FI->isUnnamedBitfield())
       continue;
 
@@ -6257,10 +6426,8 @@
     }
   }
 
-  for (CXXRecordDecl::base_class_iterator BI = RD->bases_begin(),
-                                          BE = RD->bases_end();
-       BI != BE; ++BI) {
-    if (DiagnoseUninitializedReference(S, BI->getLocStart(), BI->getType())) {
+  for (const auto &BI : RD->bases()) {
+    if (DiagnoseUninitializedReference(S, BI.getLocStart(), BI.getType())) {
       S.Diag(Loc, diag::note_value_initialization_here) << RD;
       return true;
     }
@@ -6293,6 +6460,28 @@
   }
 }
 
+static void diagnoseListInit(Sema &S, const InitializedEntity &Entity,
+                             InitListExpr *InitList) {
+  QualType DestType = Entity.getType();
+
+  QualType E;
+  if (S.getLangOpts().CPlusPlus11 && S.isStdInitializerList(DestType, &E)) {
+    QualType ArrayType = S.Context.getConstantArrayType(
+        E.withConst(),
+        llvm::APInt(S.Context.getTypeSize(S.Context.getSizeType()),
+                    InitList->getNumInits()),
+        clang::ArrayType::Normal, 0);
+    InitializedEntity HiddenArray =
+        InitializedEntity::InitializeTemporary(ArrayType);
+    return diagnoseListInit(S, HiddenArray, InitList);
+  }
+
+  InitListChecker DiagnoseInitList(S, Entity, InitList, DestType,
+                                   /*VerifyOnly=*/false);
+  assert(DiagnoseInitList.HadError() &&
+         "Inconsistent init list check result.");
+}
+
 bool InitializationSequence::Diagnose(Sema &S,
                                       const InitializedEntity &Entity,
                                       const InitializationKind &Kind,
@@ -6340,7 +6529,7 @@
     break;
   case FK_ArrayTypeMismatch:
   case FK_NonConstantArrayInit:
-    S.Diag(Kind.getLocation(), 
+    S.Diag(Kind.getLocation(),
            (Failure == FK_ArrayTypeMismatch
               ? diag::err_array_init_different_type
               : diag::err_array_init_non_constant_array))
@@ -6483,7 +6672,7 @@
     else
       R = SourceRange(Args.front()->getLocEnd(), Args.back()->getLocEnd());
 
-    R.setBegin(S.PP.getLocForEndOfToken(R.getBegin()));
+    R.setBegin(S.getLocForEndOfToken(R.getBegin()));
     if (Kind.isCStyleOrFunctionalCast())
       S.Diag(Kind.getLocation(), diag::err_builtin_func_cast_more_than_one_arg)
         << R;
@@ -6511,7 +6700,8 @@
                               Args.back()->getLocEnd());
 
     if (Failure == FK_ListConstructorOverloadFailed) {
-      assert(Args.size() == 1 && "List construction from other than 1 argument.");
+      assert(Args.size() == 1 &&
+             "List construction from other than 1 argument.");
       InitListExpr *InitList = cast<InitListExpr>(Args[0]);
       Args = MultiExprArg(InitList->getInits(), InitList->getNumInits());
     }
@@ -6556,7 +6746,8 @@
               << S.Context.getTypeDeclType(Constructor->getParent())
               << /*member=*/1
               << Entity.getName();
-            S.Diag(Entity.getDecl()->getLocation(), diag::note_field_decl);
+            S.Diag(Entity.getDecl()->getLocation(),
+                   diag::note_member_declared_at);
 
             if (const RecordType *Record
                                  = Entity.getType()->getAs<RecordType>())
@@ -6632,12 +6823,8 @@
 
   case FK_ListInitializationFailed: {
     // Run the init list checker again to emit diagnostics.
-    InitListExpr* InitList = cast<InitListExpr>(Args[0]);
-    QualType DestType = Entity.getType();
-    InitListChecker DiagnoseInitList(S, Entity, InitList,
-            DestType, /*VerifyOnly=*/false);
-    assert(DiagnoseInitList.HadError() &&
-           "Inconsistent init list check result.");
+    InitListExpr *InitList = cast<InitListExpr>(Args[0]);
+    diagnoseListInit(S, Entity, InitList);
     break;
   }
 
@@ -6852,6 +7039,10 @@
       OS << "qualification conversion (lvalue)";
       break;
 
+    case SK_AtomicConversion:
+      OS << "non-atomic-to-atomic conversion";
+      break;
+
     case SK_LValueToRValue:
       OS << "load (lvalue to rvalue)";
       break;
@@ -6872,10 +7063,6 @@
       OS << "list aggregate initialization";
       break;
 
-    case SK_ListConstructorCall:
-      OS << "list initialization via constructor";
-      break;
-
     case SK_UnwrapInitList:
       OS << "unwrap reference initializer list";
       break;
@@ -6888,6 +7075,10 @@
       OS << "constructor initialization";
       break;
 
+    case SK_ConstructorInitializationFromList:
+      OS << "list initialization via constructor";
+      break;
+
     case SK_ZeroInitialization:
       OS << "zero initialization";
       break;
@@ -6928,6 +7119,10 @@
       OS << "std::initializer_list from initializer list";
       break;
 
+    case SK_StdInitializerListConstructorCall:
+      OS << "list initialization from std::initializer_list";
+      break;
+
     case SK_OCLSamplerInit:
       OS << "OpenCL sampler_t from integer constant";
       break;
@@ -6952,7 +7147,7 @@
                                         QualType PreNarrowingType,
                                         QualType EntityType,
                                         const Expr *PostInit) {
-  const StandardConversionSequence *SCS = 0;
+  const StandardConversionSequence *SCS = nullptr;
   switch (ICS.getKind()) {
   case ImplicitConversionSequence::StandardConversion:
     SCS = &ICS.Standard;
@@ -7029,11 +7224,11 @@
     return;
   }
   OS << ">(";
-  S.Diag(PostInit->getLocStart(), diag::note_init_list_narrowing_override)
-    << PostInit->getSourceRange()
-    << FixItHint::CreateInsertion(PostInit->getLocStart(), OS.str())
-    << FixItHint::CreateInsertion(
-      S.getPreprocessor().getLocForEndOfToken(PostInit->getLocEnd()), ")");
+  S.Diag(PostInit->getLocStart(), diag::note_init_list_narrowing_silence)
+      << PostInit->getSourceRange()
+      << FixItHint::CreateInsertion(PostInit->getLocStart(), OS.str())
+      << FixItHint::CreateInsertion(
+             S.getLocForEndOfToken(PostInit->getLocEnd()), ")");
 }
 
 //===----------------------------------------------------------------------===//
@@ -7073,7 +7268,7 @@
                                                            EqualLoc,
                                                            AllowExplicit);
   InitializationSequence Seq(*this, Entity, Kind, InitE, TopLevelOfInitList);
-  Init.release();
+  Init.get();
 
   ExprResult Result = Seq.Perform(*this, Entity, Kind, InitE);
 
diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp
index 6db37ec..0cf4ed7 100644
--- a/lib/Sema/SemaLambda.cpp
+++ b/lib/Sema/SemaLambda.cpp
@@ -11,125 +11,214 @@
 //
 //===----------------------------------------------------------------------===//
 #include "clang/Sema/DeclSpec.h"
+#include "TypeLocBuilder.h"
 #include "clang/AST/ASTLambda.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/Basic/TargetInfo.h"
-#include "clang/Lex/Preprocessor.h"
 #include "clang/Sema/Initialization.h"
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/Scope.h"
 #include "clang/Sema/ScopeInfo.h"
 #include "clang/Sema/SemaInternal.h"
 #include "clang/Sema/SemaLambda.h"
-#include "TypeLocBuilder.h"
 using namespace clang;
 using namespace sema;
 
-// returns -1 if none of the lambdas on the scope stack can capture.
-// A lambda 'L' is capture-ready for a certain variable 'V' if,
-//  - its enclosing context is non-dependent
-//  - and if the chain of lambdas between L and the lambda in which 
-//    V is potentially used, call all capture or have captured V.
-static inline int GetScopeIndexOfNearestCaptureReadyLambda(
-    ArrayRef<clang::sema::FunctionScopeInfo*> FunctionScopes,
-    DeclContext *const CurContext, VarDecl *VD) {
+/// \brief Examines the FunctionScopeInfo stack to determine the nearest
+/// enclosing lambda (to the current lambda) that is 'capture-ready' for 
+/// the variable referenced in the current lambda (i.e. \p VarToCapture).
+/// If successful, returns the index into Sema's FunctionScopeInfo stack
+/// of the capture-ready lambda's LambdaScopeInfo.
+///  
+/// Climbs down the stack of lambdas (deepest nested lambda - i.e. current 
+/// lambda - is on top) to determine the index of the nearest enclosing/outer
+/// lambda that is ready to capture the \p VarToCapture being referenced in 
+/// the current lambda. 
+/// As we climb down the stack, we want the index of the first such lambda -
+/// that is the lambda with the highest index that is 'capture-ready'. 
+/// 
+/// A lambda 'L' is capture-ready for 'V' (var or this) if:
+///  - its enclosing context is non-dependent
+///  - and if the chain of lambdas between L and the lambda in which
+///    V is potentially used (i.e. the lambda at the top of the scope info 
+///    stack), can all capture or have already captured V.
+/// If \p VarToCapture is 'null' then we are trying to capture 'this'.
+/// 
+/// Note that a lambda that is deemed 'capture-ready' still needs to be checked
+/// for whether it is 'capture-capable' (see
+/// getStackIndexOfNearestEnclosingCaptureCapableLambda), before it can truly 
+/// capture.
+///
+/// \param FunctionScopes - Sema's stack of nested FunctionScopeInfo's (which a
+///  LambdaScopeInfo inherits from).  The current/deepest/innermost lambda
+///  is at the top of the stack and has the highest index.
+/// \param VarToCapture - the variable to capture.  If NULL, capture 'this'.
+///
+/// \returns An Optional<unsigned> Index that if evaluates to 'true' contains
+/// the index (into Sema's FunctionScopeInfo stack) of the innermost lambda
+/// which is capture-ready.  If the return value evaluates to 'false' then
+/// no lambda is capture-ready for \p VarToCapture.
+
+static inline Optional<unsigned>
+getStackIndexOfNearestEnclosingCaptureReadyLambda(
+    ArrayRef<const clang::sema::FunctionScopeInfo *> FunctionScopes,
+    VarDecl *VarToCapture) {
+  // Label failure to capture.
+  const Optional<unsigned> NoLambdaIsCaptureReady;
+
+  assert(
+      isa<clang::sema::LambdaScopeInfo>(
+          FunctionScopes[FunctionScopes.size() - 1]) &&
+      "The function on the top of sema's function-info stack must be a lambda");
   
-  DeclContext *EnclosingDC = CurContext;
-  // If VD is null, we are attempting to capture 'this'
-  const bool IsCapturingThis = !VD;
+  // If VarToCapture is null, we are attempting to capture 'this'.
+  const bool IsCapturingThis = !VarToCapture;
   const bool IsCapturingVariable = !IsCapturingThis;
-  int RetIndex = -1;
+
+  // Start with the current lambda at the top of the stack (highest index).
   unsigned CurScopeIndex = FunctionScopes.size() - 1;
-  while (!EnclosingDC->isTranslationUnit() && 
-      EnclosingDC->isDependentContext() && isLambdaCallOperator(EnclosingDC)) {
-    RetIndex = CurScopeIndex;
-    clang::sema::LambdaScopeInfo *LSI = 
-          cast<sema::LambdaScopeInfo>(FunctionScopes[CurScopeIndex]);
-    // We have crawled up to an intervening lambda that contains the 
-    // variable declaration - so not only does it not need to capture;
-    // none of the enclosing lambdas need to capture it, and since all
-    // other nested lambdas are dependent (otherwise we wouldn't have
-    // arrived here) - we don't yet have a lambda that can capture the
+  DeclContext *EnclosingDC =
+      cast<sema::LambdaScopeInfo>(FunctionScopes[CurScopeIndex])->CallOperator;
+
+  do {
+    const clang::sema::LambdaScopeInfo *LSI =
+        cast<sema::LambdaScopeInfo>(FunctionScopes[CurScopeIndex]);
+    // IF we have climbed down to an intervening enclosing lambda that contains
+    // the variable declaration - it obviously can/must not capture the
     // variable.
-    if (IsCapturingVariable && VD->getDeclContext()->Equals(EnclosingDC)) 
-      return -1;
-    // All intervening lambda call operators have to be able to capture.
+    // Since its enclosing DC is dependent, all the lambdas between it and the
+    // innermost nested lambda are dependent (otherwise we wouldn't have
+    // arrived here) - so we don't yet have a lambda that can capture the
+    // variable.
+    if (IsCapturingVariable &&
+        VarToCapture->getDeclContext()->Equals(EnclosingDC))
+      return NoLambdaIsCaptureReady;
+
+    // For an enclosing lambda to be capture ready for an entity, all
+    // intervening lambda's have to be able to capture that entity. If even
+    // one of the intervening lambda's is not capable of capturing the entity
+    // then no enclosing lambda can ever capture that entity.
+    // For e.g.
+    // const int x = 10;
+    // [=](auto a) {    #1
+    //   [](auto b) {   #2 <-- an intervening lambda that can never capture 'x'
+    //    [=](auto c) { #3
+    //       f(x, c);  <-- can not lead to x's speculative capture by #1 or #2
+    //    }; }; };
     // If they do not have a default implicit capture, check to see
     // if the entity has already been explicitly captured.
-    // If even a single dependent enclosing lambda lacks the capability 
-    // to ever capture this variable, there is no further enclosing 
+    // If even a single dependent enclosing lambda lacks the capability
+    // to ever capture this variable, there is no further enclosing
     // non-dependent lambda that can capture this variable.
     if (LSI->ImpCaptureStyle == sema::LambdaScopeInfo::ImpCap_None) {
-      if (IsCapturingVariable && !LSI->isCaptured(VD)) 
-        return -1;
+      if (IsCapturingVariable && !LSI->isCaptured(VarToCapture))
+        return NoLambdaIsCaptureReady;
       if (IsCapturingThis && !LSI->isCXXThisCaptured())
-        return -1;
+        return NoLambdaIsCaptureReady;
     }
     EnclosingDC = getLambdaAwareParentOfDeclContext(EnclosingDC);
+    
+    assert(CurScopeIndex);
     --CurScopeIndex;
-  }
-  // If the enclosingDC is not dependent, then the immediately nested lambda
-  // is capture-ready.
-  if (!EnclosingDC->isDependentContext())
-    return RetIndex;
-  return -1;
-}
-// Given a lambda's call operator and a variable (or null for 'this'), 
-// compute the nearest enclosing lambda that is capture-ready (i.e 
-// the enclosing context is not dependent, and all intervening lambdas can 
-// either implicitly or explicitly capture Var)
-// 
-// The approach is as follows, for the entity VD ('this' if null):
-//   - start with the current lambda
-//     - if it is non-dependent and can capture VD, return it. 
-//     - if it is dependent and has an implicit or explicit capture, check its parent 
-//       whether the parent is non-depdendent and all its intervening lambdas
-//       can capture, if so return the child.
-//       [Note: When we hit a generic lambda specialization, do not climb up
-//         the scope stack any further since not only do we not need to,
-//         the scope stack will often not be synchronized with any lambdas 
-//         enclosing the specialized generic lambda]
-//       
-// Return the CallOperator of the capturable lambda and set function scope 
-// index to the correct index within the function scope stack to correspond 
-// to the capturable lambda.
-// If VarDecl *VD is null, we check for 'this' capture.
-CXXMethodDecl* clang::GetInnermostEnclosingCapturableLambda(
-                             ArrayRef<sema::FunctionScopeInfo*> FunctionScopes,
-                             unsigned &FunctionScopeIndex, 
-                             DeclContext *const CurContext, VarDecl *VD, 
-                             Sema &S) {
+  } while (!EnclosingDC->isTranslationUnit() &&
+           EnclosingDC->isDependentContext() &&
+           isLambdaCallOperator(EnclosingDC));
 
-  const int IndexOfCaptureReadyLambda = 
-      GetScopeIndexOfNearestCaptureReadyLambda(FunctionScopes,CurContext, VD);
-  if (IndexOfCaptureReadyLambda == -1) return 0;
-  assert(IndexOfCaptureReadyLambda >= 0);
-  const unsigned IndexOfCaptureReadyLambdaU = 
-      static_cast<unsigned>(IndexOfCaptureReadyLambda);
-  sema::LambdaScopeInfo *const CaptureReadyLambdaLSI = 
-      cast<sema::LambdaScopeInfo>(FunctionScopes[IndexOfCaptureReadyLambdaU]);
-  // If VD is null, we are attempting to capture 'this'
-  const bool IsCapturingThis = !VD;
+  assert(CurScopeIndex < (FunctionScopes.size() - 1));
+  // If the enclosingDC is not dependent, then the immediately nested lambda
+  // (one index above) is capture-ready.
+  if (!EnclosingDC->isDependentContext())
+    return CurScopeIndex + 1;
+  return NoLambdaIsCaptureReady;
+}
+
+/// \brief Examines the FunctionScopeInfo stack to determine the nearest
+/// enclosing lambda (to the current lambda) that is 'capture-capable' for 
+/// the variable referenced in the current lambda (i.e. \p VarToCapture).
+/// If successful, returns the index into Sema's FunctionScopeInfo stack
+/// of the capture-capable lambda's LambdaScopeInfo.
+///
+/// Given the current stack of lambdas being processed by Sema and
+/// the variable of interest, to identify the nearest enclosing lambda (to the 
+/// current lambda at the top of the stack) that can truly capture
+/// a variable, it has to have the following two properties:
+///  a) 'capture-ready' - be the innermost lambda that is 'capture-ready':
+///     - climb down the stack (i.e. starting from the innermost and examining
+///       each outer lambda step by step) checking if each enclosing
+///       lambda can either implicitly or explicitly capture the variable.
+///       Record the first such lambda that is enclosed in a non-dependent
+///       context. If no such lambda currently exists return failure.
+///  b) 'capture-capable' - make sure the 'capture-ready' lambda can truly
+///  capture the variable by checking all its enclosing lambdas:
+///     - check if all outer lambdas enclosing the 'capture-ready' lambda
+///       identified above in 'a' can also capture the variable (this is done
+///       via tryCaptureVariable for variables and CheckCXXThisCapture for
+///       'this' by passing in the index of the Lambda identified in step 'a')
+///
+/// \param FunctionScopes - Sema's stack of nested FunctionScopeInfo's (which a
+/// LambdaScopeInfo inherits from).  The current/deepest/innermost lambda
+/// is at the top of the stack.
+///
+/// \param VarToCapture - the variable to capture.  If NULL, capture 'this'.
+///
+///
+/// \returns An Optional<unsigned> Index that if evaluates to 'true' contains
+/// the index (into Sema's FunctionScopeInfo stack) of the innermost lambda
+/// which is capture-capable.  If the return value evaluates to 'false' then
+/// no lambda is capture-capable for \p VarToCapture.
+
+Optional<unsigned> clang::getStackIndexOfNearestEnclosingCaptureCapableLambda(
+    ArrayRef<const sema::FunctionScopeInfo *> FunctionScopes,
+    VarDecl *VarToCapture, Sema &S) {
+
+  const Optional<unsigned> NoLambdaIsCaptureCapable;
+  
+  const Optional<unsigned> OptionalStackIndex =
+      getStackIndexOfNearestEnclosingCaptureReadyLambda(FunctionScopes,
+                                                        VarToCapture);
+  if (!OptionalStackIndex)
+    return NoLambdaIsCaptureCapable;
+
+  const unsigned IndexOfCaptureReadyLambda = OptionalStackIndex.getValue();
+  assert(((IndexOfCaptureReadyLambda != (FunctionScopes.size() - 1)) ||
+          S.getCurGenericLambda()) &&
+         "The capture ready lambda for a potential capture can only be the "
+         "current lambda if it is a generic lambda");
+
+  const sema::LambdaScopeInfo *const CaptureReadyLambdaLSI =
+      cast<sema::LambdaScopeInfo>(FunctionScopes[IndexOfCaptureReadyLambda]);
+  
+  // If VarToCapture is null, we are attempting to capture 'this'
+  const bool IsCapturingThis = !VarToCapture;
   const bool IsCapturingVariable = !IsCapturingThis;
 
   if (IsCapturingVariable) {
-    // Now check to see if this lambda can truly capture, and also
-    // if all enclosing lambdas of this lambda allow this capture.
+    // Check if the capture-ready lambda can truly capture the variable, by
+    // checking whether all enclosing lambdas of the capture-ready lambda allow
+    // the capture - i.e. make sure it is capture-capable.
     QualType CaptureType, DeclRefType;
-    const bool CanCaptureVariable = !S.tryCaptureVariable(VD, 
-      /*ExprVarIsUsedInLoc*/SourceLocation(), clang::Sema::TryCapture_Implicit,
-      /*EllipsisLoc*/ SourceLocation(), 
-      /*BuildAndDiagnose*/false, CaptureType, DeclRefType, 
-      &IndexOfCaptureReadyLambdaU);
-    if (!CanCaptureVariable) return 0;
-  } else { 
-    const bool CanCaptureThis = !S.CheckCXXThisCapture(
-        CaptureReadyLambdaLSI->PotentialThisCaptureLocation, false, false, 
-        &IndexOfCaptureReadyLambdaU);
-    if (!CanCaptureThis) return 0;      
-  } // end 'this' capture test
-  FunctionScopeIndex = IndexOfCaptureReadyLambdaU;
-  return CaptureReadyLambdaLSI->CallOperator;
+    const bool CanCaptureVariable =
+        !S.tryCaptureVariable(VarToCapture,
+                              /*ExprVarIsUsedInLoc*/ SourceLocation(),
+                              clang::Sema::TryCapture_Implicit,
+                              /*EllipsisLoc*/ SourceLocation(),
+                              /*BuildAndDiagnose*/ false, CaptureType,
+                              DeclRefType, &IndexOfCaptureReadyLambda);
+    if (!CanCaptureVariable)
+      return NoLambdaIsCaptureCapable;
+  } else {
+    // Check if the capture-ready lambda can truly capture 'this' by checking
+    // whether all enclosing lambdas of the capture-ready lambda can capture
+    // 'this'.
+    const bool CanCaptureThis =
+        !S.CheckCXXThisCapture(
+             CaptureReadyLambdaLSI->PotentialThisCaptureLocation,
+             /*Explicit*/ false, /*BuildAndDiagnose*/ false,
+             &IndexOfCaptureReadyLambda);
+    if (!CanCaptureThis)
+      return NoLambdaIsCaptureCapable;
+  } 
+  return IndexOfCaptureReadyLambda;
 }
 
 static inline TemplateParameterList *
@@ -142,17 +231,14 @@
     SourceLocation LAngleLoc = IntroRange.getBegin();
     SourceLocation RAngleLoc = IntroRange.getEnd();
     LSI->GLTemplateParameterList = TemplateParameterList::Create(
-                                   SemaRef.Context, 
-                                   /*Template kw loc*/SourceLocation(), 
-                                   LAngleLoc,
-                                   (NamedDecl**)LSI->AutoTemplateParams.data(),
-                                   LSI->AutoTemplateParams.size(), RAngleLoc);  
+        SemaRef.Context,
+        /*Template kw loc*/ SourceLocation(), LAngleLoc,
+        (NamedDecl **)LSI->AutoTemplateParams.data(),
+        LSI->AutoTemplateParams.size(), RAngleLoc);
   }
   return LSI->GLTemplateParameterList;
 }
 
-
-
 CXXRecordDecl *Sema::createLambdaClosureType(SourceRange IntroducerRange,
                                              TypeSourceInfo *Info,
                                              bool KnownDependent, 
@@ -169,7 +255,7 @@
                                                      IsGenericLambda, 
                                                      CaptureDefault);
   DC->addDecl(Class);
-  
+
   return Class;
 }
 
@@ -230,18 +316,18 @@
     if ((IsInNonspecializedTemplate &&
          !(ManglingContextDecl && isa<ParmVarDecl>(ManglingContextDecl))) ||
         isInInlineFunction(CurContext)) {
-      ManglingContextDecl = 0;
+      ManglingContextDecl = nullptr;
       return &Context.getManglingNumberContext(DC);
     }
 
-    ManglingContextDecl = 0;
-    return 0;
+    ManglingContextDecl = nullptr;
+    return nullptr;
 
   case StaticDataMember:
     //  -- the initializers of nonspecialized static members of template classes
     if (!IsInNonspecializedTemplate) {
-      ManglingContextDecl = 0;
-      return 0;
+      ManglingContextDecl = nullptr;
+      return nullptr;
     }
     // Fall through to get the current context.
 
@@ -277,10 +363,10 @@
   // dependent type.
   if (Class->isDependentContext() || TemplateParams) {
     const FunctionProtoType *FPT = MethodType->castAs<FunctionProtoType>();
-    QualType Result = FPT->getResultType();
+    QualType Result = FPT->getReturnType();
     if (Result->isUndeducedType()) {
       Result = SubstAutoType(Result, Context.DependentTy);
-      MethodType = Context.getFunctionType(Result, FPT->getArgTypes(),
+      MethodType = Context.getFunctionType(Result, FPT->getParamTypes(),
                                            FPT->getExtProtoInfo());
     }
   }
@@ -317,7 +403,7 @@
             FunctionTemplateDecl::Create(Context, Class,
                                          Method->getLocation(), MethodName, 
                                          TemplateParams,
-                                         Method) : 0;
+                                         Method) : nullptr;
   if (TemplateMethod) {
     TemplateMethod->setLexicalDeclContext(CurContext);
     TemplateMethod->setAccess(AS_public);
@@ -331,10 +417,8 @@
                              const_cast<ParmVarDecl **>(Params.end()),
                              /*CheckParameterNames=*/false);
     
-    for (CXXMethodDecl::param_iterator P = Method->param_begin(), 
-                                    PEnd = Method->param_end();
-         P != PEnd; ++P)
-      (*P)->setOwningFunction(Method);
+    for (auto P : Method->params())
+      P->setOwningFunction(Method);
   }
 
   Decl *ManglingContextDecl;
@@ -369,8 +453,8 @@
   LSI->Mutable = Mutable;
 
   if (ExplicitResultType) {
-    LSI->ReturnType = CallOperator->getResultType();
-    
+    LSI->ReturnType = CallOperator->getReturnType();
+
     if (!LSI->ReturnType->isDependentType() &&
         !LSI->ReturnType->isVoidType()) {
       if (RequireCompleteType(CallOperator->getLocStart(), LSI->ReturnType,
@@ -420,7 +504,7 @@
           = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
       return cast<EnumDecl>(D->getDeclContext());
     }
-    return 0;
+    return nullptr;
   }
 
   //  - it is a comma expression whose RHS is an enumerator-like
@@ -428,7 +512,7 @@
   if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
     if (BO->getOpcode() == BO_Comma)
       return findEnumForBlockReturn(BO->getRHS());
-    return 0;
+    return nullptr;
   }
 
   //  - it is a statement-expression whose value expression is an
@@ -436,7 +520,7 @@
   if (StmtExpr *SE = dyn_cast<StmtExpr>(E)) {
     if (Expr *last = dyn_cast_or_null<Expr>(SE->getSubStmt()->body_back()))
       return findEnumForBlockReturn(last);
-    return 0;
+    return nullptr;
   }
 
   //   - it is a ternary conditional operator (not the GNU ?:
@@ -446,7 +530,7 @@
     if (EnumDecl *ED = findEnumForBlockReturn(CO->getTrueExpr()))
       if (ED == findEnumForBlockReturn(CO->getFalseExpr()))
         return ED;
-    return 0;
+    return nullptr;
   }
 
   // (implicitly:)
@@ -467,7 +551,7 @@
   }
 
   // Otherwise, nope.
-  return 0;
+  return nullptr;
 }
 
 /// Attempt to find a type T for which the returned expression of the
@@ -475,7 +559,7 @@
 static EnumDecl *findEnumForBlockReturn(ReturnStmt *ret) {
   if (Expr *retValue = ret->getRetValue())
     return findEnumForBlockReturn(retValue);
-  return 0;
+  return nullptr;
 }
 
 /// Attempt to find a common type T for which all of the returned
@@ -486,16 +570,16 @@
 
   // Try to find one for the first return.
   EnumDecl *ED = findEnumForBlockReturn(*i);
-  if (!ED) return 0;
+  if (!ED) return nullptr;
 
   // Check that the rest of the returns have the same enum.
   for (++i; i != e; ++i) {
     if (findEnumForBlockReturn(*i) != ED)
-      return 0;
+      return nullptr;
   }
 
   // Never infer an anonymous enum type.
-  if (!ED->hasNameForLinkage()) return 0;
+  if (!ED->hasNameForLinkage()) return nullptr;
 
   return ED;
 }
@@ -519,7 +603,7 @@
 
     Expr *E = (cleanups ? cleanups->getSubExpr() : retValue);
     E = ImplicitCastExpr::Create(S.Context, returnType, CK_IntegralCast,
-                                 E, /*base path*/ 0, VK_RValue);
+                                 E, /*base path*/ nullptr, VK_RValue);
     if (cleanups) {
       cleanups->setSubExpr(E);
     } else {
@@ -609,12 +693,20 @@
   }
 }
 
-VarDecl *Sema::checkInitCapture(SourceLocation Loc, bool ByRef,
-                                IdentifierInfo *Id, Expr *Init) {
-  // C++1y [expr.prim.lambda]p11:
-  //   An init-capture behaves as if it declares and explicitly captures
-  //   a variable of the form
-  //     "auto init-capture;"
+QualType Sema::performLambdaInitCaptureInitialization(SourceLocation Loc,
+                                                      bool ByRef,
+                                                      IdentifierInfo *Id,
+                                                      Expr *&Init) {
+
+  // We do not need to distinguish between direct-list-initialization
+  // and copy-list-initialization here, because we will always deduce
+  // std::initializer_list<T>, and direct- and copy-list-initialization
+  // always behave the same for such a type.
+  // FIXME: We should model whether an '=' was present.
+  const bool IsDirectInit = isa<ParenListExpr>(Init) || isa<InitListExpr>(Init);
+
+  // Create an 'auto' or 'auto&' TypeSourceInfo that we can use to
+  // deduce against.
   QualType DeductType = Context.getAutoDeductType();
   TypeLocBuilder TLB;
   TLB.pushTypeSpec(DeductType).setNameLoc(Loc);
@@ -625,30 +717,110 @@
   }
   TypeSourceInfo *TSI = TLB.getTypeSourceInfo(Context, DeductType);
 
+  // Are we a non-list direct initialization?
+  ParenListExpr *CXXDirectInit = dyn_cast<ParenListExpr>(Init);
+
+  Expr *DeduceInit = Init;
+  // Initializer could be a C++ direct-initializer. Deduction only works if it
+  // contains exactly one expression.
+  if (CXXDirectInit) {
+    if (CXXDirectInit->getNumExprs() == 0) {
+      Diag(CXXDirectInit->getLocStart(), diag::err_init_capture_no_expression)
+          << DeclarationName(Id) << TSI->getType() << Loc;
+      return QualType();
+    } else if (CXXDirectInit->getNumExprs() > 1) {
+      Diag(CXXDirectInit->getExpr(1)->getLocStart(),
+           diag::err_init_capture_multiple_expressions)
+          << DeclarationName(Id) << TSI->getType() << Loc;
+      return QualType();
+    } else {
+      DeduceInit = CXXDirectInit->getExpr(0);
+      if (isa<InitListExpr>(DeduceInit))
+        Diag(CXXDirectInit->getLocStart(), diag::err_init_capture_paren_braces)
+          << DeclarationName(Id) << Loc;
+    }
+  }
+
+  // Now deduce against the initialization expression and store the deduced
+  // type below.
+  QualType DeducedType;
+  if (DeduceAutoType(TSI, DeduceInit, DeducedType) == DAR_Failed) {
+    if (isa<InitListExpr>(Init))
+      Diag(Loc, diag::err_init_capture_deduction_failure_from_init_list)
+          << DeclarationName(Id)
+          << (DeduceInit->getType().isNull() ? TSI->getType()
+                                             : DeduceInit->getType())
+          << DeduceInit->getSourceRange();
+    else
+      Diag(Loc, diag::err_init_capture_deduction_failure)
+          << DeclarationName(Id) << TSI->getType()
+          << (DeduceInit->getType().isNull() ? TSI->getType()
+                                             : DeduceInit->getType())
+          << DeduceInit->getSourceRange();
+  }
+  if (DeducedType.isNull())
+    return QualType();
+
+  // Perform initialization analysis and ensure any implicit conversions
+  // (such as lvalue-to-rvalue) are enforced.
+  InitializedEntity Entity =
+      InitializedEntity::InitializeLambdaCapture(Id, DeducedType, Loc);
+  InitializationKind Kind =
+      IsDirectInit
+          ? (CXXDirectInit ? InitializationKind::CreateDirect(
+                                 Loc, Init->getLocStart(), Init->getLocEnd())
+                           : InitializationKind::CreateDirectList(Loc))
+          : InitializationKind::CreateCopy(Loc, Init->getLocStart());
+
+  MultiExprArg Args = Init;
+  if (CXXDirectInit)
+    Args =
+        MultiExprArg(CXXDirectInit->getExprs(), CXXDirectInit->getNumExprs());
+  QualType DclT;
+  InitializationSequence InitSeq(*this, Entity, Kind, Args);
+  ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Args, &DclT);
+
+  if (Result.isInvalid())
+    return QualType();
+  Init = Result.getAs<Expr>();
+
+  // The init-capture initialization is a full-expression that must be
+  // processed as one before we enter the declcontext of the lambda's
+  // call-operator.
+  Result = ActOnFinishFullExpr(Init, Loc, /*DiscardedValue*/ false,
+                               /*IsConstexpr*/ false,
+                               /*IsLambdaInitCaptureInitalizer*/ true);
+  if (Result.isInvalid())
+    return QualType();
+
+  Init = Result.getAs<Expr>();
+  return DeducedType;
+}
+
+VarDecl *Sema::createLambdaInitCaptureVarDecl(SourceLocation Loc, 
+    QualType InitCaptureType, IdentifierInfo *Id, Expr *Init) {
+
+  TypeSourceInfo *TSI = Context.getTrivialTypeSourceInfo(InitCaptureType,
+      Loc);
   // Create a dummy variable representing the init-capture. This is not actually
   // used as a variable, and only exists as a way to name and refer to the
   // init-capture.
   // FIXME: Pass in separate source locations for '&' and identifier.
   VarDecl *NewVD = VarDecl::Create(Context, CurContext, Loc,
-                                   Loc, Id, TSI->getType(), TSI, SC_Auto);
+                                   Loc, Id, InitCaptureType, TSI, SC_Auto);
   NewVD->setInitCapture(true);
   NewVD->setReferenced(true);
   NewVD->markUsed(Context);
-
-  // We do not need to distinguish between direct-list-initialization
-  // and copy-list-initialization here, because we will always deduce
-  // std::initializer_list<T>, and direct- and copy-list-initialization
-  // always behave the same for such a type.
-  // FIXME: We should model whether an '=' was present.
-  bool DirectInit = isa<ParenListExpr>(Init) || isa<InitListExpr>(Init);
-  AddInitializerToDecl(NewVD, Init, DirectInit, /*ContainsAuto*/true);
+  NewVD->setInit(Init);
   return NewVD;
+
 }
 
 FieldDecl *Sema::buildInitCaptureField(LambdaScopeInfo *LSI, VarDecl *Var) {
   FieldDecl *Field = FieldDecl::Create(
       Context, LSI->Lambda, Var->getLocation(), Var->getLocation(),
-      0, Var->getType(), Var->getTypeSourceInfo(), 0, false, ICIS_NoInit);
+      nullptr, Var->getType(), Var->getTypeSourceInfo(), nullptr, false,
+      ICIS_NoInit);
   Field->setImplicit(true);
   Field->setAccess(AS_private);
   LSI->Lambda->addDecl(Field);
@@ -674,7 +846,7 @@
     // has template params, only then are we in a dependent scope.
     if (TemplateParams)  {
       TmplScope = TmplScope->getParent();
-      TmplScope = TmplScope ? TmplScope->getTemplateParamParent() : 0;
+      TmplScope = TmplScope ? TmplScope->getTemplateParamParent() : nullptr;
     }
     if (TmplScope && !TmplScope->decl_empty())
       KnownDependent = true;
@@ -727,14 +899,10 @@
 
     ExplicitResultType = FTI.hasTrailingReturnType();
 
-    if (FTI.NumArgs == 1 && !FTI.isVariadic && FTI.ArgInfo[0].Ident == 0 &&
-        cast<ParmVarDecl>(FTI.ArgInfo[0].Param)->getType()->isVoidType()) {
-      // Empty arg list, don't push any params.
-      checkVoidParamDecl(cast<ParmVarDecl>(FTI.ArgInfo[0].Param));
-    } else {
-      Params.reserve(FTI.NumArgs);
-      for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i)
-        Params.push_back(cast<ParmVarDecl>(FTI.ArgInfo[i].Param));
+    if (FTIHasNonVoidParameters(FTI)) {
+      Params.reserve(FTI.NumParams);
+      for (unsigned i = 0, e = FTI.NumParams; i != e; ++i)
+        Params.push_back(cast<ParmVarDecl>(FTI.Params[i].Param));
     }
 
     // Check for unexpanded parameter packs in the method type.
@@ -764,27 +932,40 @@
                        ExplicitResultType,
                        !Method->isConst());
 
+  // C++11 [expr.prim.lambda]p9:
+  //   A lambda-expression whose smallest enclosing scope is a block scope is a
+  //   local lambda expression; any other lambda expression shall not have a
+  //   capture-default or simple-capture in its lambda-introducer.
+  //
+  // For simple-captures, this is covered by the check below that any named
+  // entity is a variable that can be captured.
+  //
+  // For DR1632, we also allow a capture-default in any context where we can
+  // odr-use 'this' (in particular, in a default initializer for a non-static
+  // data member).
+  if (Intro.Default != LCD_None && !Class->getParent()->isFunctionOrMethod() &&
+      (getCurrentThisType().isNull() ||
+       CheckCXXThisCapture(SourceLocation(), /*Explicit*/true,
+                           /*BuildAndDiagnose*/false)))
+    Diag(Intro.DefaultLoc, diag::err_capture_default_non_local);
+
   // Distinct capture names, for diagnostics.
   llvm::SmallSet<IdentifierInfo*, 8> CaptureNames;
 
   // Handle explicit captures.
   SourceLocation PrevCaptureLoc
     = Intro.Default == LCD_None? Intro.Range.getBegin() : Intro.DefaultLoc;
-  for (SmallVectorImpl<LambdaCapture>::const_iterator
-         C = Intro.Captures.begin(),
-         E = Intro.Captures.end();
-       C != E;
+  for (auto C = Intro.Captures.begin(), E = Intro.Captures.end(); C != E;
        PrevCaptureLoc = C->Loc, ++C) {
     if (C->Kind == LCK_This) {
       // C++11 [expr.prim.lambda]p8:
       //   An identifier or this shall not appear more than once in a 
       //   lambda-capture.
       if (LSI->isCXXThisCaptured()) {
-        Diag(C->Loc, diag::err_capture_more_than_once) 
-          << "'this'"
-          << SourceRange(LSI->getCXXThisCapture().getLocation())
-          << FixItHint::CreateRemoval(
-               SourceRange(PP.getLocForEndOfToken(PrevCaptureLoc), C->Loc));
+        Diag(C->Loc, diag::err_capture_more_than_once)
+            << "'this'" << SourceRange(LSI->getCXXThisCapture().getLocation())
+            << FixItHint::CreateRemoval(
+                   SourceRange(getLocForEndOfToken(PrevCaptureLoc), C->Loc));
         continue;
       }
 
@@ -793,8 +974,8 @@
       //   lambda-capture shall not contain this [...].
       if (Intro.Default == LCD_ByCopy) {
         Diag(C->Loc, diag::err_this_capture_with_copy_default)
-          << FixItHint::CreateRemoval(
-               SourceRange(PP.getLocForEndOfToken(PrevCaptureLoc), C->Loc));
+            << FixItHint::CreateRemoval(
+                SourceRange(getLocForEndOfToken(PrevCaptureLoc), C->Loc));
         continue;
       }
 
@@ -816,7 +997,7 @@
     if (C->Init.isInvalid())
       continue;
 
-    VarDecl *Var;
+    VarDecl *Var = nullptr;
     if (C->Init.isUsable()) {
       Diag(C->Loc, getLangOpts().CPlusPlus1y
                        ? diag::warn_cxx11_compat_init_capture
@@ -824,9 +1005,15 @@
 
       if (C->Init.get()->containsUnexpandedParameterPack())
         ContainsUnexpandedParameterPack = true;
-
-      Var = checkInitCapture(C->Loc, C->Kind == LCK_ByRef,
-                             C->Id, C->Init.take());
+      // If the initializer expression is usable, but the InitCaptureType
+      // is not, then an error has occurred - so ignore the capture for now.
+      // for e.g., [n{0}] { }; <-- if no <initializer_list> is included.
+      // FIXME: we should create the init capture variable and mark it invalid 
+      // in this case.
+      if (C->InitCaptureType.get().isNull()) 
+        continue;
+      Var = createLambdaInitCaptureVarDecl(C->Loc, C->InitCaptureType.get(), 
+            C->Id, C->Init.get());
       // C++1y [expr.prim.lambda]p11:
       //   An init-capture behaves as if it declares and explicitly
       //   captures a variable [...] whose declarative region is the
@@ -841,13 +1028,13 @@
       //   each identifier it contains shall be preceded by &.
       if (C->Kind == LCK_ByRef && Intro.Default == LCD_ByRef) {
         Diag(C->Loc, diag::err_reference_capture_with_reference_default)
-          << FixItHint::CreateRemoval(
-               SourceRange(PP.getLocForEndOfToken(PrevCaptureLoc), C->Loc));
+            << FixItHint::CreateRemoval(
+                SourceRange(getLocForEndOfToken(PrevCaptureLoc), C->Loc));
         continue;
       } else if (C->Kind == LCK_ByCopy && Intro.Default == LCD_ByCopy) {
         Diag(C->Loc, diag::err_copy_capture_with_copy_default)
-          << FixItHint::CreateRemoval(
-               SourceRange(PP.getLocForEndOfToken(PrevCaptureLoc), C->Loc));
+            << FixItHint::CreateRemoval(
+                SourceRange(getLocForEndOfToken(PrevCaptureLoc), C->Loc));
         continue;
       }
 
@@ -868,6 +1055,8 @@
       }
 
       Var = R.getAsSingle<VarDecl>();
+      if (Var && DiagnoseUseOfDecl(Var, C->Loc))
+        continue;
     }
 
     // C++11 [expr.prim.lambda]p8:
@@ -876,9 +1065,9 @@
     if (!CaptureNames.insert(C->Id)) {
       if (Var && LSI->isCaptured(Var)) {
         Diag(C->Loc, diag::err_capture_more_than_once)
-          << C->Id << SourceRange(LSI->getCapture(Var).getLocation())
-          << FixItHint::CreateRemoval(
-               SourceRange(PP.getLocForEndOfToken(PrevCaptureLoc), C->Loc));
+            << C->Id << SourceRange(LSI->getCapture(Var).getLocation())
+            << FixItHint::CreateRemoval(
+                   SourceRange(getLocForEndOfToken(PrevCaptureLoc), C->Loc));
       } else
         // Previous capture captured something different (one or both was
         // an init-cpature): no fixit.
@@ -943,6 +1132,8 @@
 
 void Sema::ActOnLambdaError(SourceLocation StartLoc, Scope *CurScope,
                             bool IsInstantiation) {
+  LambdaScopeInfo *LSI = getCurLambda();
+
   // Leave the expression-evaluation context.
   DiscardCleanupsInEvaluationContext();
   PopExpressionEvaluationContext();
@@ -952,15 +1143,11 @@
     PopDeclContext();
 
   // Finalize the lambda.
-  LambdaScopeInfo *LSI = getCurLambda();
   CXXRecordDecl *Class = LSI->Lambda;
   Class->setInvalidDecl();
-  SmallVector<Decl*, 4> Fields;
-  for (RecordDecl::field_iterator i = Class->field_begin(),
-                                  e = Class->field_end(); i != e; ++i)
-    Fields.push_back(*i);
-  ActOnFields(0, Class->getLocation(), Class, Fields, 
-              SourceLocation(), SourceLocation(), 0);
+  SmallVector<Decl*, 4> Fields(Class->fields());
+  ActOnFields(nullptr, Class->getLocation(), Class, Fields, SourceLocation(),
+              SourceLocation(), nullptr);
   CheckCompletedCXXClass(Class);
 
   PopFunctionScopeInfo();
@@ -987,8 +1174,9 @@
     InvokerExtInfo.TypeQuals = 0;
     assert(InvokerExtInfo.RefQualifier == RQ_None && 
         "Lambda's call operator should not have a reference qualifier");
-    InvokerFunctionTy = S.Context.getFunctionType(CallOpProto->getResultType(),
-        CallOpProto->getArgTypes(), InvokerExtInfo);
+    InvokerFunctionTy =
+        S.Context.getFunctionType(CallOpProto->getReturnType(),
+                                  CallOpProto->getParamTypes(), InvokerExtInfo);
     PtrToFunctionTy = S.Context.getPointerType(InvokerFunctionTy);
   }
 
@@ -1032,7 +1220,7 @@
       ConvTSI->getTypeLoc().getAs<FunctionProtoTypeLoc>();
   // Get the result of the conversion function which is a pointer-to-function.
   PointerTypeLoc PtrToFunctionTL = 
-      ConvTL.getResultLoc().getAs<PointerTypeLoc>();
+      ConvTL.getReturnLoc().getAs<PointerTypeLoc>();
   // Do the same for the TypeSourceInfo that is used to name the conversion
   // operator.
   PointerTypeLoc ConvNamePtrToFunctionTL = 
@@ -1066,9 +1254,9 @@
                                              From->getType(),
                                              From->getTypeSourceInfo(),
                                              From->getStorageClass(),
-                                             /*DefaultArg=*/0));
-    CallOpConvTL.setArg(I, From);
-    CallOpConvNameTL.setArg(I, From);
+                                             /*DefaultArg=*/nullptr));
+    CallOpConvTL.setParam(I, From);
+    CallOpConvNameTL.setParam(I, From);
   }
 
   CXXConversionDecl *Conversion 
@@ -1154,7 +1342,7 @@
     FunctionProtoType::ExtProtoInfo ExtInfo = Proto->getExtProtoInfo();
     ExtInfo.TypeQuals = 0;
     QualType FunctionTy = S.Context.getFunctionType(
-        Proto->getResultType(), Proto->getArgTypes(), ExtInfo);
+        Proto->getReturnType(), Proto->getParamTypes(), ExtInfo);
     BlockPtrTy = S.Context.getBlockPointerType(FunctionTy);
   }
 
@@ -1186,7 +1374,7 @@
                                  Scope *CurScope, 
                                  bool IsInstantiation) {
   // Collect information from the lambda scope.
-  SmallVector<LambdaExpr::Capture, 4> Captures;
+  SmallVector<LambdaCapture, 4> Captures;
   SmallVector<Expr *, 4> CaptureInits;
   LambdaCaptureDefault CaptureDefault;
   SourceLocation CaptureDefaultLoc;
@@ -1219,9 +1407,8 @@
 
       // Handle 'this' capture.
       if (From.isThisCapture()) {
-        Captures.push_back(LambdaExpr::Capture(From.getLocation(),
-                                               IsImplicit,
-                                               LCK_This));
+        Captures.push_back(
+            LambdaCapture(From.getLocation(), IsImplicit, LCK_This));
         CaptureInits.push_back(new (Context) CXXThisExpr(From.getLocation(),
                                                          getCurrentThisType(),
                                                          /*isImplicit=*/true));
@@ -1230,8 +1417,8 @@
 
       VarDecl *Var = From.getVariable();
       LambdaCaptureKind Kind = From.isCopyCapture()? LCK_ByCopy : LCK_ByRef;
-      Captures.push_back(LambdaExpr::Capture(From.getLocation(), IsImplicit, 
-                                             Kind, Var, From.getEllipsisLoc()));
+      Captures.push_back(LambdaCapture(From.getLocation(), IsImplicit, Kind,
+                                       Var, From.getEllipsisLoc()));
       CaptureInits.push_back(From.getInitExpr());
     }
 
@@ -1279,7 +1466,7 @@
       const FunctionProtoType *Proto
         = CallOperator->getType()->getAs<FunctionProtoType>();
       QualType FunctionTy = Context.getFunctionType(
-          LSI->ReturnType, Proto->getArgTypes(), Proto->getExtProtoInfo());
+          LSI->ReturnType, Proto->getParamTypes(), Proto->getExtProtoInfo());
       CallOperator->setType(FunctionTy);
     }
     // C++ [expr.prim.lambda]p7:
@@ -1317,12 +1504,9 @@
       addBlockPointerConversion(*this, IntroducerRange, Class, CallOperator);
     
     // Finalize the lambda class.
-    SmallVector<Decl*, 4> Fields;
-    for (RecordDecl::field_iterator i = Class->field_begin(),
-                                    e = Class->field_end(); i != e; ++i)
-      Fields.push_back(*i);
-    ActOnFields(0, Class->getLocation(), Class, Fields, 
-                SourceLocation(), SourceLocation(), 0);
+    SmallVector<Decl*, 4> Fields(Class->fields());
+    ActOnFields(nullptr, Class->getLocation(), Class, Fields, SourceLocation(),
+                SourceLocation(), nullptr);
     CheckCompletedCXXClass(Class);
   }
 
@@ -1388,7 +1572,7 @@
                                                          /*NRVO=*/false),
                       CurrentLocation, Src);
   if (!Init.isInvalid())
-    Init = ActOnFinishFullExpr(Init.take());
+    Init = ActOnFinishFullExpr(Init.get());
   
   if (Init.isInvalid())
     return ExprError();
@@ -1412,7 +1596,7 @@
                                               From->getType(),
                                               From->getTypeSourceInfo(),
                                               From->getStorageClass(),
-                                              /*DefaultArg=*/0));
+                                              /*DefaultArg=*/nullptr));
   }
   Block->setParams(BlockParams);
 
@@ -1424,11 +1608,11 @@
   TypeSourceInfo *CapVarTSI =
       Context.getTrivialTypeSourceInfo(Src->getType());
   VarDecl *CapVar = VarDecl::Create(Context, Block, ConvLocation,
-                                    ConvLocation, 0,
+                                    ConvLocation, nullptr,
                                     Src->getType(), CapVarTSI,
                                     SC_None);
   BlockDecl::Capture Capture(/*Variable=*/CapVar, /*ByRef=*/false,
-                             /*Nested=*/false, /*Copy=*/Init.take());
+                             /*Nested=*/false, /*Copy=*/Init.get());
   Block->setCaptures(Context, &Capture, &Capture + 1, 
                      /*CapturesCXXThis=*/false);
 
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index 919c6ad..fe2c816 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -23,6 +23,7 @@
 #include "clang/AST/ExprCXX.h"
 #include "clang/Basic/Builtins.h"
 #include "clang/Basic/LangOptions.h"
+#include "clang/Lex/ModuleLoader.h"
 #include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/ExternalSemaSource.h"
 #include "clang/Sema/Overload.h"
@@ -113,10 +114,8 @@
         if (Ctx && Ctx->isFileContext()) {
           visit(Ctx, Ctx);
         } else if (!Ctx || Ctx->isFunctionOrMethod()) {
-          Scope::udir_iterator I = S->using_directives_begin(),
-                             End = S->using_directives_end();
-          for (; I != End; ++I)
-            visit(*I, InnermostFileDC);
+          for (auto *I : S->using_directives())
+            visit(I, InnermostFileDC);
         }
       }
     }
@@ -153,9 +152,7 @@
     void addUsingDirectives(DeclContext *DC, DeclContext *EffectiveDC) {
       SmallVector<DeclContext*,4> queue;
       while (true) {
-        DeclContext::udir_iterator I, End;
-        for (llvm::tie(I, End) = DC->getUsingDirectives(); I != End; ++I) {
-          UsingDirectiveDecl *UD = *I;
+        for (auto UD : DC->using_directives()) {
           DeclContext *NS = UD->getNominatedNamespace();
           if (visited.insert(NS)) {
             addUsingDirective(UD, EffectiveDC);
@@ -248,10 +245,11 @@
       IDNS = Decl::IDNS_Tag;
     }
     break;
+
   case Sema::LookupLabel:
     IDNS = Decl::IDNS_Label;
     break;
-      
+
   case Sema::LookupMemberName:
     IDNS = Decl::IDNS_Member;
     if (CPlusPlus)
@@ -267,8 +265,10 @@
     break;
 
   case Sema::LookupUsingDeclName:
-    IDNS = Decl::IDNS_Ordinary | Decl::IDNS_Tag
-         | Decl::IDNS_Member | Decl::IDNS_Using;
+    assert(Redeclaration && "should only be used for redecl lookup");
+    IDNS = Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Member |
+           Decl::IDNS_Using | Decl::IDNS_TagFriend | Decl::IDNS_OrdinaryFriend |
+           Decl::IDNS_LocalExtern;
     break;
 
   case Sema::LookupObjCProtocolName:
@@ -288,36 +288,33 @@
   IDNS = getIDNS(LookupKind, SemaRef.getLangOpts().CPlusPlus,
                  isForRedeclaration());
 
-  if (!isForRedeclaration()) {
-    // If we're looking for one of the allocation or deallocation
-    // operators, make sure that the implicitly-declared new and delete
-    // operators can be found.
-    switch (NameInfo.getName().getCXXOverloadedOperator()) {
-    case OO_New:
-    case OO_Delete:
-    case OO_Array_New:
-    case OO_Array_Delete:
-      SemaRef.DeclareGlobalNewDelete();
-      break;
+  // If we're looking for one of the allocation or deallocation
+  // operators, make sure that the implicitly-declared new and delete
+  // operators can be found.
+  switch (NameInfo.getName().getCXXOverloadedOperator()) {
+  case OO_New:
+  case OO_Delete:
+  case OO_Array_New:
+  case OO_Array_Delete:
+    SemaRef.DeclareGlobalNewDelete();
+    break;
 
-    default:
-      break;
-    }
+  default:
+    break;
+  }
 
-    // Compiler builtins are always visible, regardless of where they end
-    // up being declared.
-    if (IdentifierInfo *Id = NameInfo.getName().getAsIdentifierInfo()) {
-      if (unsigned BuiltinID = Id->getBuiltinID()) {
-        if (!SemaRef.Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID))
-          AllowHidden = true;
-      }
+  // Compiler builtins are always visible, regardless of where they end
+  // up being declared.
+  if (IdentifierInfo *Id = NameInfo.getName().getAsIdentifierInfo()) {
+    if (unsigned BuiltinID = Id->getBuiltinID()) {
+      if (!SemaRef.Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID))
+        AllowHidden = true;
     }
   }
 }
 
-void LookupResult::sanityImpl() const {
-  // Note that this function is never called by NDEBUG builds. See
-  // LookupResult::sanity().
+bool LookupResult::sanity() const {
+  // This function is never called by NDEBUG builds.
   assert(ResultKind != NotFound || Decls.size() == 0);
   assert(ResultKind != Found || Decls.size() == 1);
   assert(ResultKind != FoundOverloaded || Decls.size() > 1 ||
@@ -327,9 +324,10 @@
   assert(ResultKind != Ambiguous || Decls.size() > 1 ||
          (Decls.size() == 1 && (Ambiguity == AmbiguousBaseSubobjects ||
                                 Ambiguity == AmbiguousBaseSubobjectTypes)));
-  assert((Paths != NULL) == (ResultKind == Ambiguous &&
-                             (Ambiguity == AmbiguousBaseSubobjectTypes ||
-                              Ambiguity == AmbiguousBaseSubobjects)));
+  assert((Paths != nullptr) == (ResultKind == Ambiguous &&
+                                (Ambiguity == AmbiguousBaseSubobjectTypes ||
+                                 Ambiguity == AmbiguousBaseSubobjects)));
+  return true;
 }
 
 // Necessary because CXXBasePaths is not complete in Sema.h
@@ -544,14 +542,6 @@
           R.addDecl(D);
           return true;
         }
-
-        if (R.isForRedeclaration()) {
-          // If we're redeclaring this function anyway, forget that
-          // this was a builtin at all.
-          S.Context.BuiltinInfo.ForgetBuiltin(BuiltinID, S.Context.Idents);
-        }
-
-        return false;
       }
     }
   }
@@ -734,7 +724,7 @@
     // specialization into the result set. We do this to avoid forcing all
     // callers to perform special deduction for conversion functions.
     TemplateDeductionInfo Info(R.getNameLoc());
-    FunctionDecl *Specialization = 0;
+    FunctionDecl *Specialization = nullptr;
 
     const FunctionProtoType *ConvProto
       = ConvTemplate->getTemplatedDecl()->getType()->getAs<FunctionProtoType>();
@@ -753,7 +743,7 @@
 
     // Perform template argument deduction against the type that we would
     // expect the function to have.
-    if (R.getSema().DeduceTemplateArguments(ConvTemplate, 0, ExpectedType,
+    if (R.getSema().DeduceTemplateArguments(ConvTemplate, nullptr, ExpectedType,
                                             Specialization, Info)
           == Sema::TDK_Success) {
       R.addDecl(Specialization);
@@ -777,7 +767,7 @@
   // Perform direct name lookup into the namespaces nominated by the
   // using directives whose common ancestor is this namespace.
   UnqualUsingDirectiveSet::const_iterator UI, UEnd;
-  llvm::tie(UI, UEnd) = UDirs.getNamespacesFor(NS);
+  std::tie(UI, UEnd) = UDirs.getNamespacesFor(NS);
 
   for (; UI != UEnd; ++UI)
     if (LookupDirect(S, R, UI->getNominatedNamespace()))
@@ -803,7 +793,7 @@
 // it leaves the current template parameter scope.
 static std::pair<DeclContext *, bool> findOuterContext(Scope *S) {
   DeclContext *DC = S->getEntity();
-  DeclContext *Lexical = 0;
+  DeclContext *Lexical = nullptr;
   for (Scope *OuterS = S->getParent(); OuterS;
        OuterS = OuterS->getParent()) {
     if (OuterS->getEntity()) {
@@ -926,7 +916,7 @@
   UnqualUsingDirectiveSet UDirs;
   bool VisitedUsingDirectives = false;
   bool LeftStartingScope = false;
-  DeclContext *OutsideOfTemplateParamDC = 0;
+  DeclContext *OutsideOfTemplateParamDC = nullptr;
 
   // When performing a scope lookup, we want to find local extern decls.
   FindLocalExternScope FindLocals(R);
@@ -983,13 +973,13 @@
       // findOuterContext(). This implements the name lookup behavior
       // of C++ [temp.local]p8.
       Ctx = OutsideOfTemplateParamDC;
-      OutsideOfTemplateParamDC = 0;
+      OutsideOfTemplateParamDC = nullptr;
     }
 
     if (Ctx) {
       DeclContext *OuterCtx;
       bool SearchAfterTemplateScope;
-      llvm::tie(OuterCtx, SearchAfterTemplateScope) = findOuterContext(S);
+      std::tie(OuterCtx, SearchAfterTemplateScope) = findOuterContext(S);
       if (SearchAfterTemplateScope)
         OutsideOfTemplateParamDC = OuterCtx;
 
@@ -1126,13 +1116,13 @@
       // findOuterContext(). This implements the name lookup behavior
       // of C++ [temp.local]p8.
       Ctx = OutsideOfTemplateParamDC;
-      OutsideOfTemplateParamDC = 0;
+      OutsideOfTemplateParamDC = nullptr;
     }
 
     if (Ctx) {
       DeclContext *OuterCtx;
       bool SearchAfterTemplateScope;
-      llvm::tie(OuterCtx, SearchAfterTemplateScope) = findOuterContext(S);
+      std::tie(OuterCtx, SearchAfterTemplateScope) = findOuterContext(S);
       if (SearchAfterTemplateScope)
         OutsideOfTemplateParamDC = OuterCtx;
 
@@ -1224,7 +1214,7 @@
        I != N; ++I) {
     Module *M = getDefiningModule(ActiveTemplateInstantiations[I].Entity);
     if (M && !LookupModulesCache.insert(M).second)
-      M = 0;
+      M = nullptr;
     ActiveTemplateInstantiationLookupModules.push_back(M);
   }
   return LookupModulesCache;
@@ -1278,15 +1268,14 @@
 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) {
   assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case");
 
-  for (Decl::redecl_iterator RD = D->redecls_begin(), RDEnd = D->redecls_end();
-       RD != RDEnd; ++RD) {
-    if (NamedDecl *ND = dyn_cast<NamedDecl>(*RD)) {
+  for (auto RD : D->redecls()) {
+    if (auto ND = dyn_cast<NamedDecl>(RD)) {
       if (LookupResult::isVisible(SemaRef, ND))
         return ND;
     }
   }
 
-  return 0;
+  return nullptr;
 }
 
 NamedDecl *LookupResult::getAcceptableDeclSlow(NamedDecl *D) const {
@@ -1381,10 +1370,10 @@
           // then we'll need to perform our checks based on the matching
           // DeclContexts rather than matching scopes.
           if (S && isNamespaceOrTranslationUnitScope(S))
-            S = 0;
+            S = nullptr;
 
           // Compute the DeclContext, if we need it.
-          DeclContext *DC = 0;
+          DeclContext *DC = nullptr;
           if (!S)
             DC = (*I)->getDeclContext()->getRedeclContext();
             
@@ -1462,10 +1451,8 @@
                                                  DeclContext *StartDC) {
   assert(StartDC->isFileContext() && "start context is not a file context");
 
-  DeclContext::udir_iterator I = StartDC->using_directives_begin();
-  DeclContext::udir_iterator E = StartDC->using_directives_end();
-
-  if (I == E) return false;
+  DeclContext::udir_range UsingDirectives = StartDC->using_directives();
+  if (UsingDirectives.begin() == UsingDirectives.end()) return false;
 
   // We have at least added all these contexts to the queue.
   llvm::SmallPtrSet<DeclContext*, 8> Visited;
@@ -1477,8 +1464,8 @@
 
   // We have already looked into the initial namespace; seed the queue
   // with its using-children.
-  for (; I != E; ++I) {
-    NamespaceDecl *ND = (*I)->getNominatedNamespace()->getOriginalNamespace();
+  for (auto *I : UsingDirectives) {
+    NamespaceDecl *ND = I->getNominatedNamespace()->getOriginalNamespace();
     if (Visited.insert(ND))
       Queue.push_back(ND);
   }
@@ -1525,8 +1512,8 @@
       continue;
     }
 
-    for (llvm::tie(I,E) = ND->getUsingDirectives(); I != E; ++I) {
-      NamespaceDecl *Nom = (*I)->getNominatedNamespace();
+    for (auto I : ND->using_directives()) {
+      NamespaceDecl *Nom = I->getNominatedNamespace();
       if (Visited.insert(Nom))
         Queue.push_back(Nom);
     }
@@ -1667,7 +1654,7 @@
   Paths.setOrigin(LookupRec);
 
   // Look for this member in our base classes
-  CXXRecordDecl::BaseMatchesCallback *BaseCallback = 0;
+  CXXRecordDecl::BaseMatchesCallback *BaseCallback = nullptr;
   switch (R.getLookupKind()) {
     case LookupObjCImplicitSelfParam:
     case LookupOrdinaryName:
@@ -1736,7 +1723,7 @@
                  != Context.getCanonicalType(PathElement.Base->getType())) {
       // We found members of the given name in two subobjects of
       // different types. If the declaration sets aren't the same, this
-      // this lookup is ambiguous.
+      // lookup is ambiguous.
       if (HasOnlyStaticMembers(Path->Decls.begin(), Path->Decls.end())) {
         CXXBasePaths::paths_iterator FirstPath = Paths.begin();
         DeclContext::lookup_iterator FirstD = FirstPath->Decls.begin();
@@ -1780,9 +1767,7 @@
 
   // Lookup in a base class succeeded; return these results.
 
-  DeclContext::lookup_result DR = Paths.front().Decls;
-  for (DeclContext::lookup_iterator I = DR.begin(), E = DR.end(); I != E; ++I) {
-    NamedDecl *D = *I;
+  for (auto *D : Paths.front().Decls) {
     AccessSpecifier AS = CXXRecordDecl::MergeAccess(SubobjectAccess,
                                                     D->getAccess());
     R.addDecl(D, AS);
@@ -1890,16 +1875,15 @@
 
     llvm::SmallPtrSet<NamedDecl*,8> TagDecls;
 
-    LookupResult::iterator DI, DE = Result.end();
-    for (DI = Result.begin(); DI != DE; ++DI)
-      if (TagDecl *TD = dyn_cast<TagDecl>(*DI)) {
+    for (auto *D : Result)
+      if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
         TagDecls.insert(TD);
         Diag(TD->getLocation(), diag::note_hidden_tag);
       }
 
-    for (DI = Result.begin(); DI != DE; ++DI)
-      if (!isa<TagDecl>(*DI))
-        Diag((*DI)->getLocation(), diag::note_hiding_object);
+    for (auto *D : Result)
+      if (!isa<TagDecl>(D))
+        Diag(D->getLocation(), diag::note_hiding_object);
 
     // For recovery purposes, go ahead and implement the hiding.
     LookupResult::Filter F = Result.makeFilter();
@@ -1914,9 +1898,8 @@
   case LookupResult::AmbiguousReference: {
     Diag(NameLoc, diag::err_ambiguous_reference) << Name << LookupRange;
 
-    LookupResult::iterator DI = Result.begin(), DE = Result.end();
-    for (; DI != DE; ++DI)
-      Diag((*DI)->getLocation(), diag::note_ambiguous_candidate) << *DI;
+    for (auto *D : Result)
+      Diag(D->getLocation(), diag::note_ambiguous_candidate) << D;
     break;
   }
   }
@@ -2003,10 +1986,8 @@
       break;
 
     case TemplateArgument::Pack:
-      for (TemplateArgument::pack_iterator P = Arg.pack_begin(),
-                                        PEnd = Arg.pack_end();
-           P != PEnd; ++P)
-        addAssociatedClassesAndNamespaces(Result, *P);
+      for (const auto &P : Arg.pack_elements())
+        addAssociatedClassesAndNamespaces(Result, P);
       break;
   }
 }
@@ -2039,6 +2020,10 @@
 
   // Add the class itself. If we've already seen this class, we don't
   // need to visit base classes.
+  //
+  // FIXME: That's not correct, we may have added this class only because it
+  // was the enclosing class of another class, and in that case we won't have
+  // added its base classes yet.
   if (!Result.Classes.insert(Class))
     return;
 
@@ -2065,12 +2050,8 @@
   }
 
   // Only recurse into base classes for complete types.
-  if (!Class->hasDefinition()) {
-    QualType type = Result.S.Context.getTypeDeclType(Class);
-    if (Result.S.RequireCompleteType(Result.InstantiationLoc, type,
-                                     /*no diagnostic*/ 0))
-      return;
-  }
+  if (!Class->hasDefinition())
+    return;
 
   // Add direct and indirect base classes along with their associated
   // namespaces.
@@ -2081,10 +2062,8 @@
     Class = Bases.pop_back_val();
 
     // Visit the base classes.
-    for (CXXRecordDecl::base_class_iterator Base = Class->bases_begin(),
-                                         BaseEnd = Class->bases_end();
-         Base != BaseEnd; ++Base) {
-      const RecordType *BaseType = Base->getType()->getAs<RecordType>();
+    for (const auto &Base : Class->bases()) {
+      const RecordType *BaseType = Base.getType()->getAs<RecordType>();
       // In dependent contexts, we do ADL twice, and the first time around,
       // the base type might be a dependent TemplateSpecializationType, or a
       // TemplateTypeParmType. If that happens, simply ignore it.
@@ -2164,6 +2143,8 @@
     //        classes. Its associated namespaces are the namespaces in
     //        which its associated classes are defined.
     case Type::Record: {
+      Result.S.RequireCompleteType(Result.InstantiationLoc, QualType(T, 0),
+                                   /*no diagnostic*/ 0);
       CXXRecordDecl *Class
         = cast<CXXRecordDecl>(cast<RecordType>(T)->getDecl());
       addAssociatedClassesAndNamespaces(Result, Class);
@@ -2192,15 +2173,13 @@
     //        types and those associated with the return type.
     case Type::FunctionProto: {
       const FunctionProtoType *Proto = cast<FunctionProtoType>(T);
-      for (FunctionProtoType::arg_type_iterator Arg = Proto->arg_type_begin(),
-                                             ArgEnd = Proto->arg_type_end();
-             Arg != ArgEnd; ++Arg)
-        Queue.push_back(Arg->getTypePtr());
+      for (const auto &Arg : Proto->param_types())
+        Queue.push_back(Arg.getTypePtr());
       // fallthrough
     }
     case Type::FunctionNoProto: {
       const FunctionType *FnType = cast<FunctionType>(T);
-      T = FnType->getResultType().getTypePtr();
+      T = FnType->getReturnType().getTypePtr();
       continue;
     }
 
@@ -2315,14 +2294,9 @@
     UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Arg);
     if (!ULE) continue;
 
-    for (UnresolvedSetIterator I = ULE->decls_begin(), E = ULE->decls_end();
-           I != E; ++I) {
+    for (const auto *D : ULE->decls()) {
       // Look through any using declarations to find the underlying function.
-      NamedDecl *Fn = (*I)->getUnderlyingDecl();
-
-      FunctionDecl *FDecl = dyn_cast<FunctionDecl>(Fn);
-      if (!FDecl)
-        FDecl = cast<FunctionTemplateDecl>(Fn)->getTemplatedDecl();
+      const FunctionDecl *FDecl = D->getUnderlyingDecl()->getAsFunction();
 
       // Add the classes and namespaces associated with the parameter
       // types and return type of this function.
@@ -2331,43 +2305,6 @@
   }
 }
 
-/// IsAcceptableNonMemberOperatorCandidate - Determine whether Fn is
-/// an acceptable non-member overloaded operator for a call whose
-/// arguments have types T1 (and, if non-empty, T2). This routine
-/// implements the check in C++ [over.match.oper]p3b2 concerning
-/// enumeration types.
-static bool
-IsAcceptableNonMemberOperatorCandidate(FunctionDecl *Fn,
-                                       QualType T1, QualType T2,
-                                       ASTContext &Context) {
-  if (T1->isDependentType() || (!T2.isNull() && T2->isDependentType()))
-    return true;
-
-  if (T1->isRecordType() || (!T2.isNull() && T2->isRecordType()))
-    return true;
-
-  const FunctionProtoType *Proto = Fn->getType()->getAs<FunctionProtoType>();
-  if (Proto->getNumArgs() < 1)
-    return false;
-
-  if (T1->isEnumeralType()) {
-    QualType ArgType = Proto->getArgType(0).getNonReferenceType();
-    if (Context.hasSameUnqualifiedType(T1, ArgType))
-      return true;
-  }
-
-  if (Proto->getNumArgs() < 2)
-    return false;
-
-  if (!T2.isNull() && T2->isEnumeralType()) {
-    QualType ArgType = Proto->getArgType(1).getNonReferenceType();
-    if (Context.hasSameUnqualifiedType(T2, ArgType))
-      return true;
-  }
-
-  return false;
-}
-
 NamedDecl *Sema::LookupSingleName(Scope *S, DeclarationName Name,
                                   SourceLocation Loc,
                                   LookupNameKind NameKind,
@@ -2394,37 +2331,13 @@
   //        unqualified lookup of operator@ in the context of the
   //        expression according to the usual rules for name lookup in
   //        unqualified function calls (3.4.2) except that all member
-  //        functions are ignored. However, if no operand has a class
-  //        type, only those non-member functions in the lookup set
-  //        that have a first parameter of type T1 or "reference to
-  //        (possibly cv-qualified) T1", when T1 is an enumeration
-  //        type, or (if there is a right operand) a second parameter
-  //        of type T2 or "reference to (possibly cv-qualified) T2",
-  //        when T2 is an enumeration type, are candidate functions.
+  //        functions are ignored.
   DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(Op);
   LookupResult Operators(*this, OpName, SourceLocation(), LookupOperatorName);
   LookupName(Operators, S);
 
   assert(!Operators.isAmbiguous() && "Operator lookup cannot be ambiguous");
-
-  if (Operators.empty())
-    return;
-
-  for (LookupResult::iterator Op = Operators.begin(), OpEnd = Operators.end();
-       Op != OpEnd; ++Op) {
-    NamedDecl *Found = (*Op)->getUnderlyingDecl();
-    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(Found)) {
-      if (IsAcceptableNonMemberOperatorCandidate(FD, T1, T2, Context))
-        Functions.addDecl(*Op, Op.getAccess()); // FIXME: canonical FD
-    } else if (FunctionTemplateDecl *FunTmpl
-                 = dyn_cast<FunctionTemplateDecl>(Found)) {
-      // FIXME: friend operators?
-      // FIXME: do we need to check IsAcceptableNonMemberOperatorCandidate,
-      // later?
-      if (!FunTmpl->getDeclContext()->isRecord())
-        Functions.addDecl(*Op, Op.getAccess());
-    }
-  }
+  Functions.append(Operators.begin(), Operators.end());
 }
 
 Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *RD,
@@ -2481,7 +2394,7 @@
   // if necessary and make sure that implicit functions are declared.
   CanQualType CanTy = Context.getCanonicalType(Context.getTagDeclType(RD));
   DeclarationName Name;
-  Expr *Arg = 0;
+  Expr *Arg = nullptr;
   unsigned NumArgs;
 
   QualType ArgType = CanTy;
@@ -2545,7 +2458,7 @@
   // 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((SourceLocation()));
+  OverloadCandidateSet OCS(RD->getLocation(), OverloadCandidateSet::CSK_Normal);
   DeclContext::lookup_result R = RD->lookup(Name);
   assert(!R.empty() &&
          "lookup for a constructor or assignment operator was empty");
@@ -2554,11 +2467,7 @@
   // from an external source and invalidate lookup_result.
   SmallVector<NamedDecl *, 8> Candidates(R.begin(), R.end());
 
-  for (SmallVectorImpl<NamedDecl *>::iterator I = Candidates.begin(),
-                                              E = Candidates.end();
-       I != E; ++I) {
-    NamedDecl *Cand = *I;
-
+  for (auto *Cand : Candidates) {
     if (Cand->isInvalidDecl())
       continue;
 
@@ -2585,12 +2494,12 @@
                  dyn_cast<FunctionTemplateDecl>(Cand)) {
       if (SM == CXXCopyAssignment || SM == CXXMoveAssignment)
         AddMethodTemplateCandidate(Tmpl, DeclAccessPair::make(Tmpl, AS_public),
-                                   RD, 0, ThisTy, Classification,
+                                   RD, nullptr, ThisTy, Classification,
                                    llvm::makeArrayRef(&Arg, NumArgs),
                                    OCS, true);
       else
         AddTemplateOverloadCandidate(Tmpl, DeclAccessPair::make(Tmpl, AS_public),
-                                     0, llvm::makeArrayRef(&Arg, NumArgs),
+                                     nullptr, llvm::makeArrayRef(&Arg, NumArgs),
                                      OCS, true);
     } else {
       assert(isa<UsingDecl>(Cand) && "illegal Kind of operator = Decl");
@@ -2610,12 +2519,12 @@
       break;
 
     case OR_Ambiguous:
-      Result->setMethod(0);
+      Result->setMethod(nullptr);
       Result->setKind(SpecialMemberOverloadResult::Ambiguous);
       break;
 
     case OR_No_Viable_Function:
-      Result->setMethod(0);
+      Result->setMethod(nullptr);
       Result->setKind(SpecialMemberOverloadResult::NoMemberOrDeleted);
       break;
   }
@@ -2812,14 +2721,8 @@
   // operator template, but not both.
   if (FoundRaw && FoundTemplate) {
     Diag(R.getNameLoc(), diag::err_ovl_ambiguous_call) << R.getLookupName();
-    for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {
-      Decl *D = *I;
-      if (UsingShadowDecl *USD = dyn_cast<UsingShadowDecl>(D))
-        D = USD->getTargetDecl();
-      if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
-        D = FunTmpl->getTemplatedDecl();
-      NoteOverloadCandidate(cast<FunctionDecl>(D));
-    }
+    for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I)
+      NoteOverloadCandidate((*I)->getUnderlyingDecl()->getAsFunction());
     return LOLR_Error;
   }
 
@@ -2845,20 +2748,14 @@
 
   // If we haven't yet seen a decl for this key, or the last decl
   // was exactly this one, we're done.
-  if (Old == 0 || Old == New) {
+  if (Old == nullptr || Old == New) {
     Old = New;
     return;
   }
 
   // Otherwise, decide which is a more recent redeclaration.
-  FunctionDecl *OldFD, *NewFD;
-  if (isa<FunctionTemplateDecl>(New)) {
-    OldFD = cast<FunctionTemplateDecl>(Old)->getTemplatedDecl();
-    NewFD = cast<FunctionTemplateDecl>(New)->getTemplatedDecl();
-  } else {
-    OldFD = cast<FunctionDecl>(Old);
-    NewFD = cast<FunctionDecl>(New);
-  }
+  FunctionDecl *OldFD = Old->getAsFunction();
+  FunctionDecl *NewFD = New->getAsFunction();
 
   FunctionDecl *Cursor = NewFD;
   while (true) {
@@ -2877,9 +2774,8 @@
   Old = New;
 }
 
-void Sema::ArgumentDependentLookup(DeclarationName Name, bool Operator,
-                                   SourceLocation Loc, ArrayRef<Expr *> Args,
-                                   ADLResult &Result) {
+void Sema::ArgumentDependentLookup(DeclarationName Name, SourceLocation Loc,
+                                   ArrayRef<Expr *> Args, ADLResult &Result) {
   // Find all of the associated namespaces and classes based on the
   // arguments we have.
   AssociatedNamespaceSet AssociatedNamespaces;
@@ -2888,13 +2784,6 @@
                                      AssociatedNamespaces,
                                      AssociatedClasses);
 
-  QualType T1, T2;
-  if (Operator) {
-    T1 = Args[0]->getType();
-    if (Args.size() >= 2)
-      T2 = Args[1]->getType();
-  }
-
   // C++ [basic.lookup.argdep]p3:
   //   Let X be the lookup set produced by unqualified lookup (3.4.1)
   //   and let Y be the lookup set produced by argument dependent
@@ -2906,9 +2795,7 @@
   //
   // Here, we compute Y and add its members to the overloaded
   // candidate set.
-  for (AssociatedNamespaceSet::iterator NS = AssociatedNamespaces.begin(),
-                                     NSEnd = AssociatedNamespaces.end();
-       NS != NSEnd; ++NS) {
+  for (auto *NS : AssociatedNamespaces) {
     //   When considering an associated namespace, the lookup is the
     //   same as the lookup performed when the associated namespace is
     //   used as a qualifier (3.4.3.2) except that:
@@ -2920,10 +2807,8 @@
     //        associated classes are visible within their respective
     //        namespaces even if they are not visible during an ordinary
     //        lookup (11.4).
-    DeclContext::lookup_result R = (*NS)->lookup(Name);
-    for (DeclContext::lookup_iterator I = R.begin(), E = R.end(); I != E;
-         ++I) {
-      NamedDecl *D = *I;
+    DeclContext::lookup_result R = NS->lookup(Name);
+    for (auto *D : R) {
       // If the only declaration here is an ordinary friend, consider
       // it only if it was declared in an associated classes.
       if ((D->getIdentifierNamespace() & Decl::IDNS_Ordinary) == 0) {
@@ -2947,12 +2832,7 @@
       if (isa<UsingShadowDecl>(D))
         D = cast<UsingShadowDecl>(D)->getTargetDecl();
 
-      if (isa<FunctionDecl>(D)) {
-        if (Operator &&
-            !IsAcceptableNonMemberOperatorCandidate(cast<FunctionDecl>(D),
-                                                    T1, T2, Context))
-          continue;
-      } else if (!isa<FunctionTemplateDecl>(D))
+      if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D))
         continue;
 
       Result.insert(D);
@@ -3045,35 +2925,33 @@
     if (Pos == SM->end())
       continue;
 
-    for (ShadowMapEntry::iterator I = Pos->second.begin(),
-                               IEnd = Pos->second.end();
-         I != IEnd; ++I) {
+    for (auto *D : Pos->second) {
       // A tag declaration does not hide a non-tag declaration.
-      if ((*I)->hasTagIdentifierNamespace() &&
+      if (D->hasTagIdentifierNamespace() &&
           (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
                    Decl::IDNS_ObjCProtocol)))
         continue;
 
       // Protocols are in distinct namespaces from everything else.
-      if ((((*I)->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
+      if (((D->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
            || (IDNS & Decl::IDNS_ObjCProtocol)) &&
-          (*I)->getIdentifierNamespace() != IDNS)
+          D->getIdentifierNamespace() != IDNS)
         continue;
 
       // Functions and function templates in the same scope overload
       // rather than hide.  FIXME: Look for hiding based on function
       // signatures!
-      if ((*I)->isFunctionOrFunctionTemplate() &&
-          ND->isFunctionOrFunctionTemplate() &&
+      if (D->getUnderlyingDecl()->isFunctionOrFunctionTemplate() &&
+          ND->getUnderlyingDecl()->isFunctionOrFunctionTemplate() &&
           SM == ShadowMaps.rbegin())
         continue;
 
       // We've found a declaration that hides this one.
-      return *I;
+      return D;
     }
   }
 
-  return 0;
+  return nullptr;
 }
 
 static void LookupVisibleDecls(DeclContext *Ctx, LookupResult &Result,
@@ -3092,13 +2970,9 @@
     Result.getSema().ForceDeclarationOfImplicitMembers(Class);
 
   // Enumerate all of the results in this context.
-  for (DeclContext::all_lookups_iterator L = Ctx->lookups_begin(),
-                                      LEnd = Ctx->lookups_end();
-       L != LEnd; ++L) {
-    DeclContext::lookup_result R = *L;
-    for (DeclContext::lookup_iterator I = R.begin(), E = R.end(); I != E;
-         ++I) {
-      if (NamedDecl *ND = dyn_cast<NamedDecl>(*I)) {
+  for (const auto &R : Ctx->lookups()) {
+    for (auto *I : R) {
+      if (NamedDecl *ND = dyn_cast<NamedDecl>(I)) {
         if ((ND = Result.getAcceptableDecl(ND))) {
           Consumer.FoundDecl(ND, Visited.checkHidden(ND), Ctx, InBaseClass);
           Visited.add(ND);
@@ -3110,9 +2984,8 @@
   // Traverse using directives for qualified name lookup.
   if (QualifiedNameLookup) {
     ShadowContextRAII Shadow(Visited);
-    DeclContext::udir_iterator I, E;
-    for (llvm::tie(I, E) = Ctx->getUsingDirectives(); I != E; ++I) {
-      LookupVisibleDecls((*I)->getNominatedNamespace(), Result,
+    for (auto I : Ctx->using_directives()) {
+      LookupVisibleDecls(I->getNominatedNamespace(), Result,
                          QualifiedNameLookup, InBaseClass, Consumer, Visited);
     }
   }
@@ -3122,10 +2995,8 @@
     if (!Record->hasDefinition())
       return;
 
-    for (CXXRecordDecl::base_class_iterator B = Record->bases_begin(),
-                                         BEnd = Record->bases_end();
-         B != BEnd; ++B) {
-      QualType BaseType = B->getType();
+    for (const auto &B : Record->bases()) {
+      QualType BaseType = B.getType();
 
       // Don't look into dependent bases, because name lookup can't look
       // there anyway.
@@ -3165,21 +3036,16 @@
   // Traverse the contexts of Objective-C classes.
   if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Ctx)) {
     // Traverse categories.
-    for (ObjCInterfaceDecl::visible_categories_iterator
-           Cat = IFace->visible_categories_begin(),
-           CatEnd = IFace->visible_categories_end();
-         Cat != CatEnd; ++Cat) {
+    for (auto *Cat : IFace->visible_categories()) {
       ShadowContextRAII Shadow(Visited);
-      LookupVisibleDecls(*Cat, Result, QualifiedNameLookup, false,
+      LookupVisibleDecls(Cat, Result, QualifiedNameLookup, false,
                          Consumer, Visited);
     }
 
     // Traverse protocols.
-    for (ObjCInterfaceDecl::all_protocol_iterator
-         I = IFace->all_referenced_protocol_begin(),
-         E = IFace->all_referenced_protocol_end(); I != E; ++I) {
+    for (auto *I : IFace->all_referenced_protocols()) {
       ShadowContextRAII Shadow(Visited);
-      LookupVisibleDecls(*I, Result, QualifiedNameLookup, false, Consumer,
+      LookupVisibleDecls(I, Result, QualifiedNameLookup, false, Consumer,
                          Visited);
     }
 
@@ -3198,17 +3064,15 @@
                          QualifiedNameLookup, InBaseClass, Consumer, Visited);
     }
   } else if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Ctx)) {
-    for (ObjCProtocolDecl::protocol_iterator I = Protocol->protocol_begin(),
-           E = Protocol->protocol_end(); I != E; ++I) {
+    for (auto *I : Protocol->protocols()) {
       ShadowContextRAII Shadow(Visited);
-      LookupVisibleDecls(*I, Result, QualifiedNameLookup, false, Consumer,
+      LookupVisibleDecls(I, Result, QualifiedNameLookup, false, Consumer,
                          Visited);
     }
   } else if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Ctx)) {
-    for (ObjCCategoryDecl::protocol_iterator I = Category->protocol_begin(),
-           E = Category->protocol_end(); I != E; ++I) {
+    for (auto *I : Category->protocols()) {
       ShadowContextRAII Shadow(Visited);
-      LookupVisibleDecls(*I, Result, QualifiedNameLookup, false, Consumer,
+      LookupVisibleDecls(I, Result, QualifiedNameLookup, false, Consumer,
                          Visited);
     }
 
@@ -3234,18 +3098,17 @@
       (S->getEntity())->isFunctionOrMethod()) {
     FindLocalExternScope FindLocals(Result);
     // Walk through the declarations in this Scope.
-    for (Scope::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
-         D != DEnd; ++D) {
-      if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
+    for (auto *D : S->decls()) {
+      if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
         if ((ND = Result.getAcceptableDecl(ND))) {
-          Consumer.FoundDecl(ND, Visited.checkHidden(ND), 0, false);
+          Consumer.FoundDecl(ND, Visited.checkHidden(ND), nullptr, false);
           Visited.add(ND);
         }
     }
   }
 
   // FIXME: C++ [temp.local]p8
-  DeclContext *Entity = 0;
+  DeclContext *Entity = nullptr;
   if (S->getEntity()) {
     // Look into this scope's declaration context, along with any of its
     // parent lookup contexts (e.g., enclosing classes), up to the point
@@ -3297,7 +3160,7 @@
     // Lookup visible declarations in any namespaces found by using
     // directives.
     UnqualUsingDirectiveSet::const_iterator UI, UEnd;
-    llvm::tie(UI, UEnd) = UDirs.getNamespacesFor(Entity);
+    std::tie(UI, UEnd) = UDirs.getNamespacesFor(Entity);
     for (; UI != UEnd; ++UI)
       LookupVisibleDecls(const_cast<DeclContext *>(UI->getNominatedNamespace()),
                          Result, /*QualifiedNameLookup=*/false,
@@ -3355,7 +3218,7 @@
 LabelDecl *Sema::LookupOrCreateLabel(IdentifierInfo *II, SourceLocation Loc,
                                      SourceLocation GnuLabelLoc) {
   // Do a lookup to see if we have a label with this name already.
-  NamedDecl *Res = 0;
+  NamedDecl *Res = nullptr;
 
   if (GnuLabelLoc.isValid()) {
     // Local label definitions always shadow existing labels.
@@ -3370,8 +3233,8 @@
   // If we found a label, check to see if it is in the same context as us.
   // When in a Block, we don't want to reuse a label in an enclosing function.
   if (Res && Res->getDeclContext() != CurContext)
-    Res = 0;
-  if (Res == 0) {
+    Res = nullptr;
+  if (!Res) {
     // If not forward referenced or defined already, create the backing decl.
     Res = LabelDecl::Create(Context, CurContext, Loc, II);
     Scope *S = CurScope->getFnParent();
@@ -3385,151 +3248,20 @@
 // Typo correction
 //===----------------------------------------------------------------------===//
 
-namespace {
-
-typedef SmallVector<TypoCorrection, 1> TypoResultList;
-typedef llvm::StringMap<TypoResultList, llvm::BumpPtrAllocator> TypoResultsMap;
-typedef std::map<unsigned, TypoResultsMap> TypoEditDistanceMap;
-
-static const unsigned MaxTypoDistanceResultSets = 5;
-
-class TypoCorrectionConsumer : public VisibleDeclConsumer {
-  /// \brief The name written that is a typo in the source.
-  StringRef Typo;
-
-  /// \brief The results found that have the smallest edit distance
-  /// found (so far) with the typo name.
-  ///
-  /// The pointer value being set to the current DeclContext indicates
-  /// whether there is a keyword with this name.
-  TypoEditDistanceMap CorrectionResults;
-
-  Sema &SemaRef;
-
-public:
-  explicit TypoCorrectionConsumer(Sema &SemaRef, IdentifierInfo *Typo)
-    : Typo(Typo->getName()),
-      SemaRef(SemaRef) {}
-
-  bool includeHiddenDecls() const { return true; }
-
-  virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx,
-                         bool InBaseClass);
-  void FoundName(StringRef Name);
-  void addKeywordResult(StringRef Keyword);
-  void addName(StringRef Name, NamedDecl *ND, NestedNameSpecifier *NNS = NULL,
-               bool isKeyword = false);
-  void addCorrection(TypoCorrection Correction);
-
-  typedef TypoResultsMap::iterator result_iterator;
-  typedef TypoEditDistanceMap::iterator distance_iterator;
-  distance_iterator begin() { return CorrectionResults.begin(); }
-  distance_iterator end()  { return CorrectionResults.end(); }
-  void erase(distance_iterator I) { CorrectionResults.erase(I); }
-  unsigned size() const { return CorrectionResults.size(); }
-  bool empty() const { return CorrectionResults.empty(); }
-
-  TypoResultList &operator[](StringRef Name) {
-    return CorrectionResults.begin()->second[Name];
-  }
-
-  unsigned getBestEditDistance(bool Normalized) {
-    if (CorrectionResults.empty())
-      return (std::numeric_limits<unsigned>::max)();
-
-    unsigned BestED = CorrectionResults.begin()->first;
-    return Normalized ? TypoCorrection::NormalizeEditDistance(BestED) : BestED;
-  }
-
-  TypoResultsMap &getBestResults() {
-    return CorrectionResults.begin()->second;
-  }
-
-};
-
+static bool isCandidateViable(CorrectionCandidateCallback &CCC,
+                              TypoCorrection &Candidate) {
+  Candidate.setCallbackDistance(CCC.RankCandidate(Candidate));
+  return Candidate.getEditDistance(false) != TypoCorrection::InvalidDistance;
 }
 
-void TypoCorrectionConsumer::FoundDecl(NamedDecl *ND, NamedDecl *Hiding,
-                                       DeclContext *Ctx, bool InBaseClass) {
-  // Don't consider hidden names for typo correction.
-  if (Hiding)
-    return;
-
-  // Only consider entities with identifiers for names, ignoring
-  // special names (constructors, overloaded operators, selectors,
-  // etc.).
-  IdentifierInfo *Name = ND->getIdentifier();
-  if (!Name)
-    return;
-
-  // Only consider visible declarations and declarations from modules with
-  // names that exactly match.
-  if (!LookupResult::isVisible(SemaRef, ND) && Name->getName() != Typo &&
-      !findAcceptableDecl(SemaRef, ND))
-    return;
-
-  FoundName(Name->getName());
-}
-
-void TypoCorrectionConsumer::FoundName(StringRef Name) {
-  // Compute the edit distance between the typo and the name of this
-  // entity, and add the identifier to the list of results.
-  addName(Name, NULL);
-}
-
-void TypoCorrectionConsumer::addKeywordResult(StringRef Keyword) {
-  // Compute the edit distance between the typo and this keyword,
-  // and add the keyword to the list of results.
-  addName(Keyword, NULL, NULL, true);
-}
-
-void TypoCorrectionConsumer::addName(StringRef Name, NamedDecl *ND,
-                                     NestedNameSpecifier *NNS, bool isKeyword) {
-  // Use a simple length-based heuristic to determine the minimum possible
-  // edit distance. If the minimum isn't good enough, bail out early.
-  unsigned MinED = abs((int)Name.size() - (int)Typo.size());
-  if (MinED && Typo.size() / MinED < 3)
-    return;
-
-  // Compute an upper bound on the allowable edit distance, so that the
-  // edit-distance algorithm can short-circuit.
-  unsigned UpperBound = (Typo.size() + 2) / 3 + 1;
-  unsigned ED = Typo.edit_distance(Name, true, UpperBound);
-  if (ED >= UpperBound) return;
-
-  TypoCorrection TC(&SemaRef.Context.Idents.get(Name), ND, NNS, ED);
-  if (isKeyword) TC.makeKeyword();
-  addCorrection(TC);
-}
-
-void TypoCorrectionConsumer::addCorrection(TypoCorrection Correction) {
-  StringRef Name = Correction.getCorrectionAsIdentifierInfo()->getName();
-  TypoResultList &CList =
-      CorrectionResults[Correction.getEditDistance(false)][Name];
-
-  if (!CList.empty() && !CList.back().isResolved())
-    CList.pop_back();
-  if (NamedDecl *NewND = Correction.getCorrectionDecl()) {
-    std::string CorrectionStr = Correction.getAsString(SemaRef.getLangOpts());
-    for (TypoResultList::iterator RI = CList.begin(), RIEnd = CList.end();
-         RI != RIEnd; ++RI) {
-      // If the Correction refers to a decl already in the result list,
-      // replace the existing result if the string representation of Correction
-      // comes before the current result alphabetically, then stop as there is
-      // nothing more to be done to add Correction to the candidate set.
-      if (RI->getCorrectionDecl() == NewND) {
-        if (CorrectionStr < RI->getAsString(SemaRef.getLangOpts()))
-          *RI = Correction;
-        return;
-      }
-    }
-  }
-  if (CList.empty() || Correction.isResolved())
-    CList.push_back(Correction);
-
-  while (CorrectionResults.size() > MaxTypoDistanceResultSets)
-    erase(llvm::prior(CorrectionResults.end()));
-}
+static void LookupPotentialTypoResult(Sema &SemaRef,
+                                      LookupResult &Res,
+                                      IdentifierInfo *Name,
+                                      Scope *S, CXXScopeSpec *SS,
+                                      DeclContext *MemberContext,
+                                      bool EnteringContext,
+                                      bool isObjCIvarLookup,
+                                      bool FindHidden);
 
 // Fill the supplied vector with the IdentifierInfo pointers for each piece of
 // the given NestedNameSpecifier (i.e. given a NestedNameSpecifier "foo::bar::",
@@ -3542,7 +3274,7 @@
   else
     Identifiers.clear();
 
-  const IdentifierInfo *II = NULL;
+  const IdentifierInfo *II = nullptr;
 
   switch (NNS->getKind()) {
   case NestedNameSpecifier::Identifier:
@@ -3574,84 +3306,455 @@
 
 namespace {
 
-class SpecifierInfo {
- public:
-  DeclContext* DeclCtx;
-  NestedNameSpecifier* NameSpecifier;
-  unsigned EditDistance;
+static const unsigned MaxTypoDistanceResultSets = 5;
 
-  SpecifierInfo(DeclContext *Ctx, NestedNameSpecifier *NNS, unsigned ED)
-      : DeclCtx(Ctx), NameSpecifier(NNS), EditDistance(ED) {}
-};
+class TypoCorrectionConsumer : public VisibleDeclConsumer {
+  typedef SmallVector<TypoCorrection, 1> TypoResultList;
+  typedef llvm::StringMap<TypoResultList> TypoResultsMap;
+  typedef std::map<unsigned, TypoResultsMap> TypoEditDistanceMap;
 
-typedef SmallVector<DeclContext*, 4> DeclContextList;
-typedef SmallVector<SpecifierInfo, 16> SpecifierInfoList;
-
-class NamespaceSpecifierSet {
-  ASTContext &Context;
-  DeclContextList CurContextChain;
-  std::string CurNameSpecifier;
-  SmallVector<const IdentifierInfo*, 4> CurContextIdentifiers;
-  SmallVector<const IdentifierInfo*, 4> CurNameSpecifierIdentifiers;
-  bool isSorted;
-
-  SpecifierInfoList Specifiers;
-  llvm::SmallSetVector<unsigned, 4> Distances;
-  llvm::DenseMap<unsigned, SpecifierInfoList> DistanceMap;
-
-  /// \brief Helper for building the list of DeclContexts between the current
-  /// context and the top of the translation unit
-  static DeclContextList BuildContextChain(DeclContext *Start);
-
-  void SortNamespaces();
-
- public:
-  NamespaceSpecifierSet(ASTContext &Context, DeclContext *CurContext,
-                        CXXScopeSpec *CurScopeSpec)
-      : Context(Context), CurContextChain(BuildContextChain(CurContext)),
-        isSorted(false) {
-    if (NestedNameSpecifier *NNS =
-            CurScopeSpec ? CurScopeSpec->getScopeRep() : 0) {
-      llvm::raw_string_ostream SpecifierOStream(CurNameSpecifier);
-      NNS->print(SpecifierOStream, Context.getPrintingPolicy());
-
-      getNestedNameSpecifierIdentifiers(NNS, CurNameSpecifierIdentifiers);
-    }
-    // Build the list of identifiers that would be used for an absolute
-    // (from the global context) NestedNameSpecifier referring to the current
-    // context.
-    for (DeclContextList::reverse_iterator C = CurContextChain.rbegin(),
-                                        CEnd = CurContextChain.rend();
-         C != CEnd; ++C) {
-      if (NamespaceDecl *ND = dyn_cast_or_null<NamespaceDecl>(*C))
-        CurContextIdentifiers.push_back(ND->getIdentifier());
-    }
-
-    // Add the global context as a NestedNameSpecifier
-    Distances.insert(1);
-    DistanceMap[1].push_back(
-        SpecifierInfo(cast<DeclContext>(Context.getTranslationUnitDecl()),
-                      NestedNameSpecifier::GlobalSpecifier(Context), 1));
+public:
+  explicit TypoCorrectionConsumer(Sema &SemaRef,
+                                  const DeclarationNameInfo &TypoName,
+                                  Sema::LookupNameKind LookupKind,
+                                  Scope *S, CXXScopeSpec *SS,
+                                  CorrectionCandidateCallback &CCC,
+                                  DeclContext *MemberContext,
+                                  bool EnteringContext)
+      : Typo(TypoName.getName().getAsIdentifierInfo()), SemaRef(SemaRef), S(S),
+        SS(SS), CorrectionValidator(CCC), MemberContext(MemberContext),
+        Result(SemaRef, TypoName, LookupKind),
+        Namespaces(SemaRef.Context, SemaRef.CurContext, SS),
+        EnteringContext(EnteringContext), SearchNamespaces(false) {
+    Result.suppressDiagnostics();
   }
 
-  /// \brief Add the DeclContext (a namespace or record) to the set, computing
-  /// the corresponding NestedNameSpecifier and its distance in the process.
-  void AddNameSpecifier(DeclContext *Ctx);
+  bool includeHiddenDecls() const override { return true; }
 
-  typedef SpecifierInfoList::iterator iterator;
-  iterator begin() {
-    if (!isSorted) SortNamespaces();
-    return Specifiers.begin();
+  // Methods for adding potential corrections to the consumer.
+  void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx,
+                 bool InBaseClass) override;
+  void FoundName(StringRef Name);
+  void addKeywordResult(StringRef Keyword);
+  void addCorrection(TypoCorrection Correction);
+
+  bool empty() const { return CorrectionResults.empty(); }
+
+  /// \brief Return the list of TypoCorrections for the given identifier from
+  /// the set of corrections that have the closest edit distance, if any.
+  TypoResultList &operator[](StringRef Name) {
+    return CorrectionResults.begin()->second[Name];
   }
-  iterator end() { return Specifiers.end(); }
+
+  /// \brief Return the edit distance of the corrections that have the
+  /// closest/best edit distance from the original typop.
+  unsigned getBestEditDistance(bool Normalized) {
+    if (CorrectionResults.empty())
+      return (std::numeric_limits<unsigned>::max)();
+
+    unsigned BestED = CorrectionResults.begin()->first;
+    return Normalized ? TypoCorrection::NormalizeEditDistance(BestED) : BestED;
+  }
+
+  /// \brief Set-up method to add to the consumer the set of namespaces to use
+  /// in performing corrections to nested name specifiers. This method also
+  /// implicitly adds all of the known classes in the current AST context to the
+  /// to the consumer for correcting nested name specifiers.
+  void
+  addNamespaces(const llvm::MapVector<NamespaceDecl *, bool> &KnownNamespaces);
+
+  /// \brief Return the next typo correction that passes all internal filters
+  /// and is deemed valid by the consumer's CorrectionCandidateCallback,
+  /// starting with the corrections that have the closest edit distance. An
+  /// empty TypoCorrection is returned once no more viable corrections remain
+  /// in the consumer.
+  TypoCorrection getNextCorrection();
+
+private:
+  class NamespaceSpecifierSet {
+    struct SpecifierInfo {
+      DeclContext* DeclCtx;
+      NestedNameSpecifier* NameSpecifier;
+      unsigned EditDistance;
+    };
+
+    typedef SmallVector<DeclContext*, 4> DeclContextList;
+    typedef SmallVector<SpecifierInfo, 16> SpecifierInfoList;
+
+    ASTContext &Context;
+    DeclContextList CurContextChain;
+    std::string CurNameSpecifier;
+    SmallVector<const IdentifierInfo*, 4> CurContextIdentifiers;
+    SmallVector<const IdentifierInfo*, 4> CurNameSpecifierIdentifiers;
+    bool isSorted;
+
+    SpecifierInfoList Specifiers;
+    llvm::SmallSetVector<unsigned, 4> Distances;
+    llvm::DenseMap<unsigned, SpecifierInfoList> DistanceMap;
+
+    /// \brief Helper for building the list of DeclContexts between the current
+    /// context and the top of the translation unit
+    static DeclContextList buildContextChain(DeclContext *Start);
+
+    void sortNamespaces();
+
+    unsigned buildNestedNameSpecifier(DeclContextList &DeclChain,
+                                      NestedNameSpecifier *&NNS);
+
+   public:
+    NamespaceSpecifierSet(ASTContext &Context, DeclContext *CurContext,
+                          CXXScopeSpec *CurScopeSpec);
+
+    /// \brief Add the DeclContext (a namespace or record) to the set, computing
+    /// the corresponding NestedNameSpecifier and its distance in the process.
+    void addNameSpecifier(DeclContext *Ctx);
+
+    typedef SpecifierInfoList::iterator iterator;
+    iterator begin() {
+      if (!isSorted) sortNamespaces();
+      return Specifiers.begin();
+    }
+    iterator end() { return Specifiers.end(); }
+  };
+
+  void addName(StringRef Name, NamedDecl *ND,
+               NestedNameSpecifier *NNS = nullptr, bool isKeyword = false);
+
+  /// \brief Find any visible decls for the given typo correction candidate.
+  /// If none are found, it to the set of candidates for which qualified lookups
+  /// will be performed to find possible nested name specifier changes.
+  bool resolveCorrection(TypoCorrection &Candidate);
+
+  /// \brief Perform qualified lookups on the queued set of typo correction
+  /// candidates and add the nested name specifier changes to each candidate if
+  /// a lookup succeeds (at which point the candidate will be returned to the
+  /// main pool of potential corrections).
+  void performQualifiedLookups();
+
+  /// \brief The name written that is a typo in the source.
+  IdentifierInfo *Typo;
+
+  /// \brief The results found that have the smallest edit distance
+  /// found (so far) with the typo name.
+  ///
+  /// The pointer value being set to the current DeclContext indicates
+  /// whether there is a keyword with this name.
+  TypoEditDistanceMap CorrectionResults;
+
+  Sema &SemaRef;
+  Scope *S;
+  CXXScopeSpec *SS;
+  CorrectionCandidateCallback &CorrectionValidator;
+  DeclContext *MemberContext;
+  LookupResult Result;
+  NamespaceSpecifierSet Namespaces;
+  SmallVector<TypoCorrection, 2> QualifiedResults;
+  bool EnteringContext;
+  bool SearchNamespaces;
 };
 
 }
 
-DeclContextList NamespaceSpecifierSet::BuildContextChain(DeclContext *Start) {
+void TypoCorrectionConsumer::FoundDecl(NamedDecl *ND, NamedDecl *Hiding,
+                                       DeclContext *Ctx, bool InBaseClass) {
+  // Don't consider hidden names for typo correction.
+  if (Hiding)
+    return;
+
+  // Only consider entities with identifiers for names, ignoring
+  // special names (constructors, overloaded operators, selectors,
+  // etc.).
+  IdentifierInfo *Name = ND->getIdentifier();
+  if (!Name)
+    return;
+
+  // Only consider visible declarations and declarations from modules with
+  // names that exactly match.
+  if (!LookupResult::isVisible(SemaRef, ND) && Name != Typo &&
+      !findAcceptableDecl(SemaRef, ND))
+    return;
+
+  FoundName(Name->getName());
+}
+
+void TypoCorrectionConsumer::FoundName(StringRef Name) {
+  // Compute the edit distance between the typo and the name of this
+  // entity, and add the identifier to the list of results.
+  addName(Name, nullptr);
+}
+
+void TypoCorrectionConsumer::addKeywordResult(StringRef Keyword) {
+  // Compute the edit distance between the typo and this keyword,
+  // and add the keyword to the list of results.
+  addName(Keyword, nullptr, nullptr, true);
+}
+
+void TypoCorrectionConsumer::addName(StringRef Name, NamedDecl *ND,
+                                     NestedNameSpecifier *NNS, bool isKeyword) {
+  // Use a simple length-based heuristic to determine the minimum possible
+  // edit distance. If the minimum isn't good enough, bail out early.
+  StringRef TypoStr = Typo->getName();
+  unsigned MinED = abs((int)Name.size() - (int)TypoStr.size());
+  if (MinED && TypoStr.size() / MinED < 3)
+    return;
+
+  // Compute an upper bound on the allowable edit distance, so that the
+  // edit-distance algorithm can short-circuit.
+  unsigned UpperBound = (TypoStr.size() + 2) / 3 + 1;
+  unsigned ED = TypoStr.edit_distance(Name, true, UpperBound);
+  if (ED >= UpperBound) return;
+
+  TypoCorrection TC(&SemaRef.Context.Idents.get(Name), ND, NNS, ED);
+  if (isKeyword) TC.makeKeyword();
+  addCorrection(TC);
+}
+
+void TypoCorrectionConsumer::addCorrection(TypoCorrection Correction) {
+  StringRef TypoStr = Typo->getName();
+  StringRef Name = Correction.getCorrectionAsIdentifierInfo()->getName();
+
+  // For very short typos, ignore potential corrections that have a different
+  // base identifier from the typo or which have a normalized edit distance
+  // longer than the typo itself.
+  if (TypoStr.size() < 3 &&
+      (Name != TypoStr || Correction.getEditDistance(true) > TypoStr.size()))
+    return;
+
+  // If the correction is resolved but is not viable, ignore it.
+  if (Correction.isResolved() &&
+      !isCandidateViable(CorrectionValidator, Correction))
+    return;
+
+  TypoResultList &CList =
+      CorrectionResults[Correction.getEditDistance(false)][Name];
+
+  if (!CList.empty() && !CList.back().isResolved())
+    CList.pop_back();
+  if (NamedDecl *NewND = Correction.getCorrectionDecl()) {
+    std::string CorrectionStr = Correction.getAsString(SemaRef.getLangOpts());
+    for (TypoResultList::iterator RI = CList.begin(), RIEnd = CList.end();
+         RI != RIEnd; ++RI) {
+      // If the Correction refers to a decl already in the result list,
+      // replace the existing result if the string representation of Correction
+      // comes before the current result alphabetically, then stop as there is
+      // nothing more to be done to add Correction to the candidate set.
+      if (RI->getCorrectionDecl() == NewND) {
+        if (CorrectionStr < RI->getAsString(SemaRef.getLangOpts()))
+          *RI = Correction;
+        return;
+      }
+    }
+  }
+  if (CList.empty() || Correction.isResolved())
+    CList.push_back(Correction);
+
+  while (CorrectionResults.size() > MaxTypoDistanceResultSets)
+    CorrectionResults.erase(std::prev(CorrectionResults.end()));
+}
+
+void TypoCorrectionConsumer::addNamespaces(
+    const llvm::MapVector<NamespaceDecl *, bool> &KnownNamespaces) {
+  SearchNamespaces = true;
+
+  for (auto KNPair : KnownNamespaces)
+    Namespaces.addNameSpecifier(KNPair.first);
+
+  bool SSIsTemplate = false;
+  if (NestedNameSpecifier *NNS =
+          (SS && SS->isValid()) ? SS->getScopeRep() : nullptr) {
+    if (const Type *T = NNS->getAsType())
+      SSIsTemplate = T->getTypeClass() == Type::TemplateSpecialization;
+  }
+  for (const auto *TI : SemaRef.getASTContext().types()) {
+    if (CXXRecordDecl *CD = TI->getAsCXXRecordDecl()) {
+      CD = CD->getCanonicalDecl();
+      if (!CD->isDependentType() && !CD->isAnonymousStructOrUnion() &&
+          !CD->isUnion() && CD->getIdentifier() &&
+          (SSIsTemplate || !isa<ClassTemplateSpecializationDecl>(CD)) &&
+          (CD->isBeingDefined() || CD->isCompleteDefinition()))
+        Namespaces.addNameSpecifier(CD);
+    }
+  }
+}
+
+TypoCorrection TypoCorrectionConsumer::getNextCorrection() {
+  while (!CorrectionResults.empty()) {
+    auto DI = CorrectionResults.begin();
+    if (DI->second.empty()) {
+      CorrectionResults.erase(DI);
+      continue;
+    }
+
+    auto RI = DI->second.begin();
+    if (RI->second.empty()) {
+      DI->second.erase(RI);
+      performQualifiedLookups();
+      continue;
+    }
+
+    TypoCorrection TC = RI->second.pop_back_val();
+    if (TC.isResolved() || resolveCorrection(TC))
+      return TC;
+  }
+  return TypoCorrection();
+}
+
+bool TypoCorrectionConsumer::resolveCorrection(TypoCorrection &Candidate) {
+  IdentifierInfo *Name = Candidate.getCorrectionAsIdentifierInfo();
+  DeclContext *TempMemberContext = MemberContext;
+  CXXScopeSpec *TempSS = SS;
+retry_lookup:
+  LookupPotentialTypoResult(SemaRef, Result, Name, S, TempSS, TempMemberContext,
+                            EnteringContext,
+                            CorrectionValidator.IsObjCIvarLookup,
+                            Name == Typo && !Candidate.WillReplaceSpecifier());
+  switch (Result.getResultKind()) {
+  case LookupResult::NotFound:
+  case LookupResult::NotFoundInCurrentInstantiation:
+  case LookupResult::FoundUnresolvedValue:
+    if (TempSS) {
+      // Immediately retry the lookup without the given CXXScopeSpec
+      TempSS = nullptr;
+      Candidate.WillReplaceSpecifier(true);
+      goto retry_lookup;
+    }
+    if (TempMemberContext) {
+      if (SS && !TempSS)
+        TempSS = SS;
+      TempMemberContext = nullptr;
+      goto retry_lookup;
+    }
+    if (SearchNamespaces)
+      QualifiedResults.push_back(Candidate);
+    break;
+
+  case LookupResult::Ambiguous:
+    // We don't deal with ambiguities.
+    break;
+
+  case LookupResult::Found:
+  case LookupResult::FoundOverloaded:
+    // Store all of the Decls for overloaded symbols
+    for (auto *TRD : Result)
+      Candidate.addCorrectionDecl(TRD);
+    if (!isCandidateViable(CorrectionValidator, Candidate)) {
+      if (SearchNamespaces)
+        QualifiedResults.push_back(Candidate);
+      break;
+    }
+    return true;
+  }
+  return false;
+}
+
+void TypoCorrectionConsumer::performQualifiedLookups() {
+  unsigned TypoLen = Typo->getName().size();
+  for (auto QR : QualifiedResults) {
+    for (auto NSI : Namespaces) {
+      DeclContext *Ctx = NSI.DeclCtx;
+      const Type *NSType = NSI.NameSpecifier->getAsType();
+
+      // If the current NestedNameSpecifier refers to a class and the
+      // current correction candidate is the name of that class, then skip
+      // it as it is unlikely a qualified version of the class' constructor
+      // is an appropriate correction.
+      if (CXXRecordDecl *NSDecl = NSType ? NSType->getAsCXXRecordDecl() : 0) {
+        if (NSDecl->getIdentifier() == QR.getCorrectionAsIdentifierInfo())
+          continue;
+      }
+
+      TypoCorrection TC(QR);
+      TC.ClearCorrectionDecls();
+      TC.setCorrectionSpecifier(NSI.NameSpecifier);
+      TC.setQualifierDistance(NSI.EditDistance);
+      TC.setCallbackDistance(0); // Reset the callback distance
+
+      // If the current correction candidate and namespace combination are
+      // too far away from the original typo based on the normalized edit
+      // distance, then skip performing a qualified name lookup.
+      unsigned TmpED = TC.getEditDistance(true);
+      if (QR.getCorrectionAsIdentifierInfo() != Typo && TmpED &&
+          TypoLen / TmpED < 3)
+        continue;
+
+      Result.clear();
+      Result.setLookupName(QR.getCorrectionAsIdentifierInfo());
+      if (!SemaRef.LookupQualifiedName(Result, Ctx))
+        continue;
+
+      // Any corrections added below will be validated in subsequent
+      // iterations of the main while() loop over the Consumer's contents.
+      switch (Result.getResultKind()) {
+      case LookupResult::Found:
+      case LookupResult::FoundOverloaded: {
+        if (SS && SS->isValid()) {
+          std::string NewQualified = TC.getAsString(SemaRef.getLangOpts());
+          std::string OldQualified;
+          llvm::raw_string_ostream OldOStream(OldQualified);
+          SS->getScopeRep()->print(OldOStream, SemaRef.getPrintingPolicy());
+          OldOStream << Typo->getName();
+          // If correction candidate would be an identical written qualified
+          // identifer, then the existing CXXScopeSpec probably included a
+          // typedef that didn't get accounted for properly.
+          if (OldOStream.str() == NewQualified)
+            break;
+        }
+        for (LookupResult::iterator TRD = Result.begin(), TRDEnd = Result.end();
+             TRD != TRDEnd; ++TRD) {
+          if (SemaRef.CheckMemberAccess(TC.getCorrectionRange().getBegin(),
+                                        NSType ? NSType->getAsCXXRecordDecl()
+                                               : nullptr,
+                                        TRD.getPair()) == Sema::AR_accessible)
+            TC.addCorrectionDecl(*TRD);
+        }
+        if (TC.isResolved())
+          addCorrection(TC);
+        break;
+      }
+      case LookupResult::NotFound:
+      case LookupResult::NotFoundInCurrentInstantiation:
+      case LookupResult::Ambiguous:
+      case LookupResult::FoundUnresolvedValue:
+        break;
+      }
+    }
+  }
+  QualifiedResults.clear();
+}
+
+TypoCorrectionConsumer::NamespaceSpecifierSet::NamespaceSpecifierSet(
+    ASTContext &Context, DeclContext *CurContext, CXXScopeSpec *CurScopeSpec)
+    : Context(Context), CurContextChain(buildContextChain(CurContext)),
+      isSorted(false) {
+  if (NestedNameSpecifier *NNS =
+          CurScopeSpec ? CurScopeSpec->getScopeRep() : nullptr) {
+    llvm::raw_string_ostream SpecifierOStream(CurNameSpecifier);
+    NNS->print(SpecifierOStream, Context.getPrintingPolicy());
+
+    getNestedNameSpecifierIdentifiers(NNS, CurNameSpecifierIdentifiers);
+  }
+  // Build the list of identifiers that would be used for an absolute
+  // (from the global context) NestedNameSpecifier referring to the current
+  // context.
+  for (DeclContextList::reverse_iterator C = CurContextChain.rbegin(),
+                                         CEnd = CurContextChain.rend();
+       C != CEnd; ++C) {
+    if (NamespaceDecl *ND = dyn_cast_or_null<NamespaceDecl>(*C))
+      CurContextIdentifiers.push_back(ND->getIdentifier());
+  }
+
+  // Add the global context as a NestedNameSpecifier
+  Distances.insert(1);
+  SpecifierInfo SI = {cast<DeclContext>(Context.getTranslationUnitDecl()),
+                      NestedNameSpecifier::GlobalSpecifier(Context), 1};
+  DistanceMap[1].push_back(SI);
+}
+
+auto TypoCorrectionConsumer::NamespaceSpecifierSet::buildContextChain(
+    DeclContext *Start) -> DeclContextList {
   assert(Start && "Building a context chain from a null context");
   DeclContextList Chain;
-  for (DeclContext *DC = Start->getPrimaryContext(); DC != NULL;
+  for (DeclContext *DC = Start->getPrimaryContext(); DC != nullptr;
        DC = DC->getLookupParent()) {
     NamespaceDecl *ND = dyn_cast_or_null<NamespaceDecl>(DC);
     if (!DC->isInlineNamespace() && !DC->isTransparentContext() &&
@@ -3661,7 +3764,7 @@
   return Chain;
 }
 
-void NamespaceSpecifierSet::SortNamespaces() {
+void TypoCorrectionConsumer::NamespaceSpecifierSet::sortNamespaces() {
   SmallVector<unsigned, 4> sortedDistances;
   sortedDistances.append(Distances.begin(), Distances.end());
 
@@ -3669,19 +3772,17 @@
     std::sort(sortedDistances.begin(), sortedDistances.end());
 
   Specifiers.clear();
-  for (SmallVectorImpl<unsigned>::iterator DI = sortedDistances.begin(),
-                                        DIEnd = sortedDistances.end();
-       DI != DIEnd; ++DI) {
-    SpecifierInfoList &SpecList = DistanceMap[*DI];
+  for (auto D : sortedDistances) {
+    SpecifierInfoList &SpecList = DistanceMap[D];
     Specifiers.append(SpecList.begin(), SpecList.end());
   }
 
   isSorted = true;
 }
 
-static unsigned BuildNestedNameSpecifier(ASTContext &Context,
-                                         DeclContextList &DeclChain,
-                                         NestedNameSpecifier *&NNS) {
+unsigned
+TypoCorrectionConsumer::NamespaceSpecifierSet::buildNestedNameSpecifier(
+    DeclContextList &DeclChain, NestedNameSpecifier *&NNS) {
   unsigned NumSpecifiers = 0;
   for (DeclContextList::reverse_iterator C = DeclChain.rbegin(),
                                       CEnd = DeclChain.rend();
@@ -3698,10 +3799,11 @@
   return NumSpecifiers;
 }
 
-void NamespaceSpecifierSet::AddNameSpecifier(DeclContext *Ctx) {
-  NestedNameSpecifier *NNS = NULL;
+void TypoCorrectionConsumer::NamespaceSpecifierSet::addNameSpecifier(
+    DeclContext *Ctx) {
+  NestedNameSpecifier *NNS = nullptr;
   unsigned NumSpecifiers = 0;
-  DeclContextList NamespaceDeclChain(BuildContextChain(Ctx));
+  DeclContextList NamespaceDeclChain(buildContextChain(Ctx));
   DeclContextList FullNamespaceDeclChain(NamespaceDeclChain);
 
   // Eliminate common elements from the two DeclContext chains.
@@ -3713,14 +3815,14 @@
   }
 
   // Build the NestedNameSpecifier from what is left of the NamespaceDeclChain
-  NumSpecifiers = BuildNestedNameSpecifier(Context, NamespaceDeclChain, NNS);
+  NumSpecifiers = buildNestedNameSpecifier(NamespaceDeclChain, NNS);
 
   // Add an explicit leading '::' specifier if needed.
   if (NamespaceDeclChain.empty()) {
     // Rebuild the NestedNameSpecifier as a globally-qualified specifier.
     NNS = NestedNameSpecifier::GlobalSpecifier(Context);
     NumSpecifiers =
-        BuildNestedNameSpecifier(Context, FullNamespaceDeclChain, NNS);
+        buildNestedNameSpecifier(FullNamespaceDeclChain, NNS);
   } else if (NamedDecl *ND =
                  dyn_cast_or_null<NamedDecl>(NamespaceDeclChain.back())) {
     IdentifierInfo *Name = ND->getIdentifier();
@@ -3742,7 +3844,7 @@
       // Rebuild the NestedNameSpecifier as a globally-qualified specifier.
       NNS = NestedNameSpecifier::GlobalSpecifier(Context);
       NumSpecifiers =
-          BuildNestedNameSpecifier(Context, FullNamespaceDeclChain, NNS);
+          buildNestedNameSpecifier(FullNamespaceDeclChain, NNS);
     }
   }
 
@@ -3760,7 +3862,8 @@
 
   isSorted = false;
   Distances.insert(NumSpecifiers);
-  DistanceMap[NumSpecifiers].push_back(SpecifierInfo(Ctx, NNS, NumSpecifiers));
+  SpecifierInfo SI = {Ctx, NNS, NumSpecifiers};
+  DistanceMap[NumSpecifiers].push_back(SI);
 }
 
 /// \brief Perform name lookup for a possible result for typo correction.
@@ -3960,17 +4063,10 @@
   }
 }
 
-static bool isCandidateViable(CorrectionCandidateCallback &CCC,
-                              TypoCorrection &Candidate) {
-  Candidate.setCallbackDistance(CCC.RankCandidate(Candidate));
-  return Candidate.getEditDistance(false) != TypoCorrection::InvalidDistance;
-}
-
 /// \brief Check whether the declarations found for a typo correction are
 /// visible, and if none of them are, convert the correction to an 'import
 /// a module' correction.
-static void checkCorrectionVisibility(Sema &SemaRef, TypoCorrection &TC,
-                                      DeclarationName TypoName) {
+static void checkCorrectionVisibility(Sema &SemaRef, TypoCorrection &TC) {
   if (TC.begin() == TC.end())
     return;
 
@@ -4045,6 +4141,7 @@
                                  Sema::LookupNameKind LookupKind,
                                  Scope *S, CXXScopeSpec *SS,
                                  CorrectionCandidateCallback &CCC,
+                                 CorrectTypoKind Mode,
                                  DeclContext *MemberContext,
                                  bool EnteringContext,
                                  const ObjCObjectPointerType *OPT,
@@ -4064,7 +4161,7 @@
   // In Microsoft mode, don't perform typo correction in a template member
   // function dependent context because it interferes with the "lookup into
   // dependent bases of class templates" feature.
-  if (getLangOpts().MicrosoftMode && CurContext->isDependentContext() &&
+  if (getLangOpts().MSVCCompat && CurContext->isDependentContext() &&
       isa<CXXMethodDecl>(CurContext))
     return TypoCorrection();
 
@@ -4099,9 +4196,17 @@
   if (getLangOpts().AltiVec && Typo->isStr("vector"))
     return TypoCorrection();
 
-  NamespaceSpecifierSet Namespaces(Context, CurContext, SS);
+  // If we're handling a missing symbol error, using modules, and the
+  // special search all modules option is used, look for a missing import.
+  if ((Mode == CTK_ErrorRecovery) &&  getLangOpts().Modules &&
+      getLangOpts().ModulesSearchAll) {
+    // The following has the side effect of loading the missing module.
+    getModuleLoader().lookupMissingImports(Typo->getName(),
+                                           TypoName.getLocStart());
+  }
 
-  TypoCorrectionConsumer Consumer(*this, Typo);
+  TypoCorrectionConsumer Consumer(*this, TypoName, LookupKind, S, SS, CCC,
+                                  MemberContext, EnteringContext);
 
   // If a callback object considers an empty typo correction candidate to be
   // viable, assume it does not do any actual validation of the candidates.
@@ -4116,10 +4221,8 @@
 
     // Look in qualified interfaces.
     if (OPT) {
-      for (ObjCObjectPointerType::qual_iterator
-             I = OPT->qual_begin(), E = OPT->qual_end();
-           I != E; ++I)
-        LookupVisibleDecls(*I, LookupKind, Consumer);
+      for (auto *I : OPT->quals())
+        LookupVisibleDecls(I, LookupKind, Consumer);
     }
   } else if (SS && SS->isSet()) {
     QualifiedDC = computeDeclContext(*SS, EnteringContext);
@@ -4182,16 +4285,14 @@
     // For unqualified lookup, look through all of the names that we have
     // seen in this translation unit.
     // FIXME: Re-add the ability to skip very unlikely potential corrections.
-    for (IdentifierTable::iterator I = Context.Idents.begin(),
-                                IEnd = Context.Idents.end();
-         I != IEnd; ++I)
-      Consumer.FoundName(I->getKey());
+    for (const auto &I : Context.Idents)
+      Consumer.FoundName(I.getKey());
 
     // Walk through identifiers in external identifier sources.
     // FIXME: Re-add the ability to skip very unlikely potential corrections.
     if (IdentifierInfoLookup *External
                             = Context.Idents.getExternalIdentifierLookup()) {
-      OwningPtr<IdentifierIterator> Iter(External->getIdentifiers());
+      std::unique_ptr<IdentifierIterator> Iter(External->getIdentifiers());
       do {
         StringRef Name = Iter->Next();
         if (Name.empty())
@@ -4224,240 +4325,19 @@
       SmallVector<NamespaceDecl *, 4> ExternalKnownNamespaces;
       LoadedExternalKnownNamespaces = true;
       ExternalSource->ReadKnownNamespaces(ExternalKnownNamespaces);
-      for (unsigned I = 0, N = ExternalKnownNamespaces.size(); I != N; ++I)
-        KnownNamespaces[ExternalKnownNamespaces[I]] = true;
+      for (auto *N : ExternalKnownNamespaces)
+        KnownNamespaces[N] = true;
     }
 
-    for (llvm::MapVector<NamespaceDecl*, bool>::iterator
-           KNI = KnownNamespaces.begin(),
-           KNIEnd = KnownNamespaces.end();
-         KNI != KNIEnd; ++KNI)
-      Namespaces.AddNameSpecifier(KNI->first);
-
-    for (ASTContext::type_iterator TI = Context.types_begin(),
-                                   TIEnd = Context.types_end();
-         TI != TIEnd; ++TI) {
-      if (CXXRecordDecl *CD = (*TI)->getAsCXXRecordDecl()) {
-        CD = CD->getCanonicalDecl();
-        if (!CD->isDependentType() && !CD->isAnonymousStructOrUnion() &&
-            !CD->isUnion() &&
-            (CD->isBeingDefined() || CD->isCompleteDefinition()))
-          Namespaces.AddNameSpecifier(CD);
-      }
-    }
+    Consumer.addNamespaces(KnownNamespaces);
   }
 
-  // Weed out any names that could not be found by name lookup or, if a
-  // CorrectionCandidateCallback object was provided, failed validation.
-  SmallVector<TypoCorrection, 16> QualifiedResults;
-  LookupResult TmpRes(*this, TypoName, LookupKind);
-  TmpRes.suppressDiagnostics();
-  while (!Consumer.empty()) {
-    TypoCorrectionConsumer::distance_iterator DI = Consumer.begin();
-    for (TypoCorrectionConsumer::result_iterator I = DI->second.begin(),
-                                              IEnd = DI->second.end();
-         I != IEnd; /* Increment in loop. */) {
-      // If we only want nested name specifier corrections, ignore potential
-      // corrections that have a different base identifier from the typo.
-      if (AllowOnlyNNSChanges &&
-          I->second.front().getCorrectionAsIdentifierInfo() != Typo) {
-        TypoCorrectionConsumer::result_iterator Prev = I;
-        ++I;
-        DI->second.erase(Prev);
-        continue;
-      }
-
-      // If the item already has been looked up or is a keyword, keep it.
-      // If a validator callback object was given, drop the correction
-      // unless it passes validation.
-      bool Viable = false;
-      for (TypoResultList::iterator RI = I->second.begin();
-           RI != I->second.end(); /* Increment in loop. */) {
-        TypoResultList::iterator Prev = RI;
-        ++RI;
-        if (Prev->isResolved()) {
-          if (!isCandidateViable(CCC, *Prev))
-            RI = I->second.erase(Prev);
-          else
-            Viable = true;
-        }
-      }
-      if (Viable || I->second.empty()) {
-        TypoCorrectionConsumer::result_iterator Prev = I;
-        ++I;
-        if (!Viable)
-          DI->second.erase(Prev);
-        continue;
-      }
-      assert(I->second.size() == 1 && "Expected a single unresolved candidate");
-
-      // Perform name lookup on this name.
-      TypoCorrection &Candidate = I->second.front();
-      IdentifierInfo *Name = Candidate.getCorrectionAsIdentifierInfo();
-      DeclContext *TempMemberContext = MemberContext;
-      CXXScopeSpec *TempSS = SS;
-retry_lookup:
-      LookupPotentialTypoResult(*this, TmpRes, Name, S, TempSS,
-                                TempMemberContext, EnteringContext,
-                                CCC.IsObjCIvarLookup,
-                                Name == TypoName.getName() &&
-                                  !Candidate.WillReplaceSpecifier());
-
-      switch (TmpRes.getResultKind()) {
-      case LookupResult::NotFound:
-      case LookupResult::NotFoundInCurrentInstantiation:
-      case LookupResult::FoundUnresolvedValue:
-        if (TempSS) {
-          // Immediately retry the lookup without the given CXXScopeSpec
-          TempSS = NULL;
-          Candidate.WillReplaceSpecifier(true);
-          goto retry_lookup;
-        }
-        if (TempMemberContext) {
-          if (SS && !TempSS)
-            TempSS = SS;
-          TempMemberContext = NULL;
-          goto retry_lookup;
-        }
-        QualifiedResults.push_back(Candidate);
-        // We didn't find this name in our scope, or didn't like what we found;
-        // ignore it.
-        {
-          TypoCorrectionConsumer::result_iterator Next = I;
-          ++Next;
-          DI->second.erase(I);
-          I = Next;
-        }
-        break;
-
-      case LookupResult::Ambiguous:
-        // We don't deal with ambiguities.
-        return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure);
-
-      case LookupResult::FoundOverloaded: {
-        TypoCorrectionConsumer::result_iterator Prev = I;
-        // Store all of the Decls for overloaded symbols
-        for (LookupResult::iterator TRD = TmpRes.begin(),
-                                 TRDEnd = TmpRes.end();
-             TRD != TRDEnd; ++TRD)
-          Candidate.addCorrectionDecl(*TRD);
-        ++I;
-        if (!isCandidateViable(CCC, Candidate)) {
-          QualifiedResults.push_back(Candidate);
-          DI->second.erase(Prev);
-        }
-        break;
-      }
-
-      case LookupResult::Found: {
-        TypoCorrectionConsumer::result_iterator Prev = I;
-        Candidate.setCorrectionDecl(TmpRes.getAsSingle<NamedDecl>());
-        ++I;
-        if (!isCandidateViable(CCC, Candidate)) {
-          QualifiedResults.push_back(Candidate);
-          DI->second.erase(Prev);
-        }
-        break;
-      }
-
-      }
-    }
-
-    if (DI->second.empty())
-      Consumer.erase(DI);
-    else if (!getLangOpts().CPlusPlus || QualifiedResults.empty() || !DI->first)
-      // If there are results in the closest possible bucket, stop
-      break;
-
-    // Only perform the qualified lookups for C++
-    if (SearchNamespaces) {
-      TmpRes.suppressDiagnostics();
-      for (SmallVector<TypoCorrection,
-                       16>::iterator QRI = QualifiedResults.begin(),
-                                  QRIEnd = QualifiedResults.end();
-           QRI != QRIEnd; ++QRI) {
-        for (NamespaceSpecifierSet::iterator NI = Namespaces.begin(),
-                                          NIEnd = Namespaces.end();
-             NI != NIEnd; ++NI) {
-          DeclContext *Ctx = NI->DeclCtx;
-          const Type *NSType = NI->NameSpecifier->getAsType();
-
-          // If the current NestedNameSpecifier refers to a class and the
-          // current correction candidate is the name of that class, then skip
-          // it as it is unlikely a qualified version of the class' constructor
-          // is an appropriate correction.
-          if (CXXRecordDecl *NSDecl =
-                  NSType ? NSType->getAsCXXRecordDecl() : 0) {
-            if (NSDecl->getIdentifier() == QRI->getCorrectionAsIdentifierInfo())
-              continue;
-          }
-
-          TypoCorrection TC(*QRI);
-          TC.ClearCorrectionDecls();
-          TC.setCorrectionSpecifier(NI->NameSpecifier);
-          TC.setQualifierDistance(NI->EditDistance);
-          TC.setCallbackDistance(0); // Reset the callback distance
-
-          // If the current correction candidate and namespace combination are
-          // too far away from the original typo based on the normalized edit
-          // distance, then skip performing a qualified name lookup.
-          unsigned TmpED = TC.getEditDistance(true);
-          if (QRI->getCorrectionAsIdentifierInfo() != Typo &&
-              TmpED && TypoLen / TmpED < 3)
-            continue;
-
-          TmpRes.clear();
-          TmpRes.setLookupName(QRI->getCorrectionAsIdentifierInfo());
-          if (!LookupQualifiedName(TmpRes, Ctx)) continue;
-
-          // Any corrections added below will be validated in subsequent
-          // iterations of the main while() loop over the Consumer's contents.
-          switch (TmpRes.getResultKind()) {
-          case LookupResult::Found:
-          case LookupResult::FoundOverloaded: {
-            if (SS && SS->isValid()) {
-              std::string NewQualified = TC.getAsString(getLangOpts());
-              std::string OldQualified;
-              llvm::raw_string_ostream OldOStream(OldQualified);
-              SS->getScopeRep()->print(OldOStream, getPrintingPolicy());
-              OldOStream << TypoName;
-              // If correction candidate would be an identical written qualified
-              // identifer, then the existing CXXScopeSpec probably included a
-              // typedef that didn't get accounted for properly.
-              if (OldOStream.str() == NewQualified)
-                break;
-            }
-            for (LookupResult::iterator TRD = TmpRes.begin(),
-                                     TRDEnd = TmpRes.end();
-                 TRD != TRDEnd; ++TRD) {
-              if (CheckMemberAccess(TC.getCorrectionRange().getBegin(),
-                                    NSType ? NSType->getAsCXXRecordDecl() : 0,
-                                    TRD.getPair()) == AR_accessible)
-                TC.addCorrectionDecl(*TRD);
-            }
-            if (TC.isResolved())
-              Consumer.addCorrection(TC);
-            break;
-          }
-          case LookupResult::NotFound:
-          case LookupResult::NotFoundInCurrentInstantiation:
-          case LookupResult::Ambiguous:
-          case LookupResult::FoundUnresolvedValue:
-            break;
-          }
-        }
-      }
-    }
-
-    QualifiedResults.clear();
-  }
-
-  // No corrections remain...
-  if (Consumer.empty())
+  TypoCorrection BestTC = Consumer.getNextCorrection();
+  TypoCorrection SecondBestTC = Consumer.getNextCorrection();
+  if (!BestTC)
     return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure);
 
-  TypoResultsMap &BestResults = Consumer.getBestResults();
-  ED = Consumer.getBestEditDistance(true);
+  ED = BestTC.getEditDistance();
 
   if (!AllowOnlyNNSChanges && ED > 0 && TypoLen / ED < 3) {
     // If this was an unqualified lookup and we believe the callback
@@ -4468,11 +4348,9 @@
   }
 
   // If only a single name remains, return that result.
-  if (BestResults.size() == 1) {
-    const TypoResultList &CorrectionList = BestResults.begin()->second;
-    const TypoCorrection &Result = CorrectionList.front();
-    if (CorrectionList.size() != 1)
-      return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure);
+  if (!SecondBestTC ||
+      SecondBestTC.getEditDistance(false) > BestTC.getEditDistance(false)) {
+    const TypoCorrection &Result = BestTC;
 
     // Don't correct to a keyword that's the same as the typo; the keyword
     // wasn't actually in scope.
@@ -4485,39 +4363,42 @@
 
     TypoCorrection TC = Result;
     TC.setCorrectionRange(SS, TypoName);
-    checkCorrectionVisibility(*this, TC, TypoName.getName());
+    checkCorrectionVisibility(*this, TC);
     return TC;
   }
-  else if (BestResults.size() > 1
-           // Ugly hack equivalent to CTC == CTC_ObjCMessageReceiver;
-           // WantObjCSuper is only true for CTC_ObjCMessageReceiver and for
-           // some instances of CTC_Unknown, while WantRemainingKeywords is true
-           // for CTC_Unknown but not for CTC_ObjCMessageReceiver.
-           && CCC.WantObjCSuper && !CCC.WantRemainingKeywords
-           && BestResults["super"].front().isKeyword()) {
+  // Ugly hack equivalent to CTC == CTC_ObjCMessageReceiver;
+  // WantObjCSuper is only true for CTC_ObjCMessageReceiver and for
+  // some instances of CTC_Unknown, while WantRemainingKeywords is true
+  // for CTC_Unknown but not for CTC_ObjCMessageReceiver.
+  else if (SecondBestTC && CCC.WantObjCSuper && !CCC.WantRemainingKeywords) {
     // Prefer 'super' when we're completing in a message-receiver
     // context.
 
+    if (BestTC.getCorrection().getAsString() != "super") {
+      if (SecondBestTC.getCorrection().getAsString() == "super")
+        BestTC = SecondBestTC;
+      else if (Consumer["super"].front().isKeyword())
+        BestTC = Consumer["super"].front();
+    }
     // Don't correct to a keyword that's the same as the typo; the keyword
     // wasn't actually in scope.
-    if (ED == 0)
+    if (BestTC.getEditDistance() == 0 ||
+        BestTC.getCorrection().getAsString() != "super")
       return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure);
 
     // Record the correction for unqualified lookup.
     if (IsUnqualifiedLookup)
-      UnqualifiedTyposCorrected[Typo] = BestResults["super"].front();
+      UnqualifiedTyposCorrected[Typo] = BestTC;
 
-    TypoCorrection TC = BestResults["super"].front();
-    TC.setCorrectionRange(SS, TypoName);
-    return TC;
+    BestTC.setCorrectionRange(SS, TypoName);
+    return BestTC;
   }
 
-  // If this was an unqualified lookup and we believe the callback object did
-  // not filter out possible corrections, note that no correction was found.
-  if (IsUnqualifiedLookup && !ValidatingCallback)
-    (void)UnqualifiedTyposCorrected[Typo];
-
-  return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure);
+  // Record the failure's location if needed and return an empty correction. If
+  // this was an unqualified lookup and we believe the callback object did not
+  // filter out possible corrections, also cache the failure for the typo.
+  return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure,
+                          IsUnqualifiedLookup && !ValidatingCallback);
 }
 
 void TypoCorrection::addCorrectionDecl(NamedDecl *CDecl) {
@@ -4552,19 +4433,34 @@
     return WantTypeSpecifiers || WantExpressionKeywords || WantCXXNamedCasts ||
            WantRemainingKeywords || WantObjCSuper;
 
-  for (TypoCorrection::const_decl_iterator CDecl = candidate.begin(),
-                                           CDeclEnd = candidate.end();
-       CDecl != CDeclEnd; ++CDecl) {
-    if (!isa<TypeDecl>(*CDecl))
-      return true;
+  bool HasNonType = false;
+  bool HasStaticMethod = false;
+  bool HasNonStaticMethod = false;
+  for (Decl *D : candidate) {
+    if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(D))
+      D = FTD->getTemplatedDecl();
+    if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
+      if (Method->isStatic())
+        HasStaticMethod = true;
+      else
+        HasNonStaticMethod = true;
+    }
+    if (!isa<TypeDecl>(D))
+      HasNonType = true;
   }
 
-  return WantTypeSpecifiers;
+  if (IsAddressOfOperand && HasNonStaticMethod && !HasStaticMethod &&
+      !candidate.getCorrectionSpecifier())
+    return false;
+
+  return WantTypeSpecifiers || HasNonType;
 }
 
 FunctionCallFilterCCC::FunctionCallFilterCCC(Sema &SemaRef, unsigned NumArgs,
-                                             bool HasExplicitTemplateArgs)
-    : NumArgs(NumArgs), HasExplicitTemplateArgs(HasExplicitTemplateArgs) {
+                                             bool HasExplicitTemplateArgs,
+                                             MemberExpr *ME)
+    : NumArgs(NumArgs), HasExplicitTemplateArgs(HasExplicitTemplateArgs),
+      CurContext(SemaRef.CurContext), MemberFn(ME) {
   WantTypeSpecifiers = SemaRef.getLangOpts().CPlusPlus;
   WantRemainingKeywords = false;
 }
@@ -4573,11 +4469,9 @@
   if (!candidate.getCorrectionDecl())
     return candidate.isKeyword();
 
-  for (TypoCorrection::const_decl_iterator DI = candidate.begin(),
-                                           DIEnd = candidate.end();
-       DI != DIEnd; ++DI) {
-    FunctionDecl *FD = 0;
-    NamedDecl *ND = (*DI)->getUnderlyingDecl();
+  for (auto *C : candidate) {
+    FunctionDecl *FD = nullptr;
+    NamedDecl *ND = C->getUnderlyingDecl();
     if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(ND))
       FD = FTD->getTemplatedDecl();
     if (!HasExplicitTemplateArgs && !FD) {
@@ -4589,13 +4483,35 @@
         if (ValType->isAnyPointerType() || ValType->isReferenceType())
           ValType = ValType->getPointeeType();
         if (const FunctionProtoType *FPT = ValType->getAs<FunctionProtoType>())
-          if (FPT->getNumArgs() == NumArgs)
+          if (FPT->getNumParams() == NumArgs)
             return true;
       }
     }
-    if (FD && FD->getNumParams() >= NumArgs &&
-        FD->getMinRequiredArguments() <= NumArgs)
-      return true;
+
+    // Skip the current candidate if it is not a FunctionDecl or does not accept
+    // the current number of arguments.
+    if (!FD || !(FD->getNumParams() >= NumArgs &&
+                 FD->getMinRequiredArguments() <= NumArgs))
+      continue;
+
+    // If the current candidate is a non-static C++ method, skip the candidate
+    // unless the method being corrected--or the current DeclContext, if the
+    // function being corrected is not a method--is a method in the same class
+    // or a descendent class of the candidate's parent class.
+    if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
+      if (MemberFn || !MD->isStatic()) {
+        CXXMethodDecl *CurMD =
+            MemberFn
+                ? dyn_cast_or_null<CXXMethodDecl>(MemberFn->getMemberDecl())
+                : dyn_cast_or_null<CXXMethodDecl>(CurContext);
+        CXXRecordDecl *CurRD =
+            CurMD ? CurMD->getParent()->getCanonicalDecl() : nullptr;
+        CXXRecordDecl *RD = MD->getParent()->getCanonicalDecl();
+        if (!CurRD || (CurRD != RD && !CurRD->isDerivedFrom(RD)))
+          continue;
+      }
+    }
+    return true;
   }
   return false;
 }
@@ -4613,7 +4529,7 @@
   if (const VarDecl *VD = dyn_cast<VarDecl>(D))
     return VD->getDefinition();
   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
-    return FD->isDefined(FD) ? FD : 0;
+    return FD->isDefined(FD) ? FD : nullptr;
   if (const TagDecl *TD = dyn_cast<TagDecl>(D))
     return TD->getDefinition();
   if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
@@ -4622,7 +4538,7 @@
     return PD->getDefinition();
   if (const TemplateDecl *TD = dyn_cast<TemplateDecl>(D))
     return getDefinitionToImport(TD->getTemplatedDecl());
-  return 0;
+  return nullptr;
 }
 
 /// \brief Diagnose a successfully-corrected typo. Separated from the correction
@@ -4665,9 +4581,9 @@
     Diag(Def->getLocation(), diag::note_previous_declaration);
 
     // Recover by implicitly importing this module.
-    if (!isSFINAEContext() && ErrorRecovery)
-      createImplicitModuleImport(Correction.getCorrectionRange().getBegin(),
-                                 Owner);
+    if (ErrorRecovery)
+      createImplicitModuleImportForErrorRecovery(
+          Correction.getCorrectionRange().getBegin(), Owner);
     return;
   }
 
@@ -4675,7 +4591,7 @@
     << CorrectedQuotedStr << (ErrorRecovery ? FixTypo : FixItHint());
 
   NamedDecl *ChosenDecl =
-      Correction.isKeyword() ? 0 : Correction.getCorrectionDecl();
+      Correction.isKeyword() ? nullptr : Correction.getCorrectionDecl();
   if (PrevNote.getDiagID() && ChosenDecl)
     Diag(ChosenDecl->getLocation(), PrevNote)
       << CorrectedQuotedStr << (ErrorRecovery ? FixItHint() : FixTypo);
diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp
index 9d18c65..8eb806b 100644
--- a/lib/Sema/SemaObjCProperty.cpp
+++ b/lib/Sema/SemaObjCProperty.cpp
@@ -19,7 +19,6 @@
 #include "clang/AST/ExprObjC.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Lex/Lexer.h"
-#include "clang/Lex/Preprocessor.h"
 #include "clang/Sema/Initialization.h"
 #include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/SmallString.h"
@@ -132,11 +131,8 @@
   }
 
   // Check this property against any protocols we inherit.
-  for (ObjCProtocolDecl::protocol_iterator P = Proto->protocol_begin(),
-                                        PEnd = Proto->protocol_end();
-       P != PEnd; ++P) {
-    CheckPropertyAgainstProtocol(S, Prop, *P, Known);
-  }
+  for (auto *P : Proto->protocols())
+    CheckPropertyAgainstProtocol(S, Prop, P, Known);
 }
 
 Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
@@ -168,7 +164,7 @@
 
   // Proceed with constructing the ObjCPropertyDecls.
   ObjCContainerDecl *ClassDecl = cast<ObjCContainerDecl>(CurContext);
-  ObjCPropertyDecl *Res = 0;
+  ObjCPropertyDecl *Res = nullptr;
   if (ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl)) {
     if (CDecl->IsClassExtension()) {
       Res = HandlePropertyInClassExtension(S, AtLoc, LParenLoc,
@@ -179,7 +175,7 @@
                                            isOverridingProperty, TSI,
                                            MethodImplKind);
       if (!Res)
-        return 0;
+        return nullptr;
     }
   }
 
@@ -204,7 +200,8 @@
   if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) {
     // For a class, compare the property against a property in our superclass.
     bool FoundInSuper = false;
-    if (ObjCInterfaceDecl *Super = IFace->getSuperClass()) {
+    ObjCInterfaceDecl *CurrentInterfaceDecl = IFace;
+    while (ObjCInterfaceDecl *Super = CurrentInterfaceDecl->getSuperClass()) {
       DeclContext::lookup_result R = Super->lookup(Res->getDeclName());
       for (unsigned I = 0, N = R.size(); I != N; ++I) {
         if (ObjCPropertyDecl *SuperProp = dyn_cast<ObjCPropertyDecl>(R[I])) {
@@ -213,37 +210,30 @@
           break;
         }
       }
+      if (FoundInSuper)
+        break;
+      else
+        CurrentInterfaceDecl = Super;
     }
 
     if (FoundInSuper) {
       // Also compare the property against a property in our protocols.
-      for (ObjCInterfaceDecl::protocol_iterator P = IFace->protocol_begin(),
-                                             PEnd = IFace->protocol_end();
-           P != PEnd; ++P) {
-        CheckPropertyAgainstProtocol(*this, Res, *P, KnownProtos);
+      for (auto *P : CurrentInterfaceDecl->protocols()) {
+        CheckPropertyAgainstProtocol(*this, Res, P, KnownProtos);
       }
     } else {
       // Slower path: look in all protocols we referenced.
-      for (ObjCInterfaceDecl::all_protocol_iterator
-             P = IFace->all_referenced_protocol_begin(),
-             PEnd = IFace->all_referenced_protocol_end();
-           P != PEnd; ++P) {
-        CheckPropertyAgainstProtocol(*this, Res, *P, KnownProtos);
+      for (auto *P : IFace->all_referenced_protocols()) {
+        CheckPropertyAgainstProtocol(*this, Res, P, KnownProtos);
       }
     }
   } else if (ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(ClassDecl)) {
-    for (ObjCCategoryDecl::protocol_iterator P = Cat->protocol_begin(),
-                                          PEnd = Cat->protocol_end();
-         P != PEnd; ++P) {
-      CheckPropertyAgainstProtocol(*this, Res, *P, KnownProtos);
-    }
+    for (auto *P : Cat->protocols())
+      CheckPropertyAgainstProtocol(*this, Res, P, KnownProtos);
   } else {
     ObjCProtocolDecl *Proto = cast<ObjCProtocolDecl>(ClassDecl);
-    for (ObjCProtocolDecl::protocol_iterator P = Proto->protocol_begin(),
-                                          PEnd = Proto->protocol_end();
-         P != PEnd; ++P) {
-      CheckPropertyAgainstProtocol(*this, Res, *P, KnownProtos);
-    }
+    for (auto *P : Proto->protocols())
+      CheckPropertyAgainstProtocol(*this, Res, P, KnownProtos);
   }
 
   ActOnDocumentableDecl(Res);
@@ -302,8 +292,7 @@
   Token Tok;
   do {
     lexer.LexFromRawLexer(Tok);
-    if (Tok.is(tok::raw_identifier) &&
-        StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == attrName) {
+    if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == attrName) {
       Loc = Tok.getLocation();
       return true;
     }
@@ -321,21 +310,6 @@
                  ObjCPropertyDecl::OBJC_PR_unsafe_unretained);
 }
 
-static const char *NameOfOwnershipAttribute(unsigned attr) {
-  if (attr & ObjCPropertyDecl::OBJC_PR_assign)
-    return "assign";
-  if (attr & ObjCPropertyDecl::OBJC_PR_retain )
-    return "retain";
-  if (attr & ObjCPropertyDecl::OBJC_PR_copy)
-    return "copy";
-  if (attr & ObjCPropertyDecl::OBJC_PR_weak)
-    return "weak";
-  if (attr & ObjCPropertyDecl::OBJC_PR_strong)
-    return "strong";
-  assert(attr & ObjCPropertyDecl::OBJC_PR_unsafe_unretained);
-  return "unsafe_unretained";
-}
-
 ObjCPropertyDecl *
 Sema::HandlePropertyInClassExtension(Scope *S,
                                      SourceLocation AtLoc,
@@ -358,15 +332,12 @@
   if (CCPrimary) {
     // Check for duplicate declaration of this property in current and
     // other class extensions.
-    for (ObjCInterfaceDecl::known_extensions_iterator
-           Ext = CCPrimary->known_extensions_begin(),
-           ExtEnd = CCPrimary->known_extensions_end();
-         Ext != ExtEnd; ++Ext) {
+    for (const auto *Ext : CCPrimary->known_extensions()) {
       if (ObjCPropertyDecl *prevDecl
-            = ObjCPropertyDecl::findPropertyDecl(*Ext, PropertyId)) {
+            = ObjCPropertyDecl::findPropertyDecl(Ext, PropertyId)) {
         Diag(AtLoc, diag::err_duplicate_property);
         Diag(prevDecl->getLocation(), diag::note_property_declare);
-        return 0;
+        return nullptr;
       }
     }
   }
@@ -398,7 +369,7 @@
   if (!CCPrimary) {
     Diag(CDecl->getLocation(), diag::err_continuation_class);
     *isOverridingProperty = true;
-    return 0;
+    return nullptr;
   }
 
   // Find the property in continuation class's primary class only.
@@ -416,12 +387,14 @@
     // A case of continuation class adding a new property in the class. This
     // is not what it was meant for. However, gcc supports it and so should we.
     // Make sure setter/getters are declared here.
-    ProcessPropertyDecl(PrimaryPDecl, CCPrimary, /* redeclaredProperty = */ 0,
+    ProcessPropertyDecl(PrimaryPDecl, CCPrimary,
+                        /* redeclaredProperty = */ nullptr,
                         /* lexicalDC = */ CDecl);
     PDecl->setGetterMethodDecl(PrimaryPDecl->getGetterMethodDecl());
     PDecl->setSetterMethodDecl(PrimaryPDecl->getSetterMethodDecl());
     if (ASTMutationListener *L = Context.getASTMutationListener())
-      L->AddedObjCPropertyInClassExtension(PrimaryPDecl, /*OrigProp=*/0, CDecl);
+      L->AddedObjCPropertyInClassExtension(PrimaryPDecl, /*OrigProp=*/nullptr,
+                                           CDecl);
     return PrimaryPDecl;
   }
   if (!Context.hasSameType(PIDecl->getType(), PDecl->getType())) {
@@ -441,7 +414,7 @@
       Diag(AtLoc, 
           diag::err_type_mismatch_continuation_class) << PDecl->getType();
       Diag(PIDecl->getLocation(), diag::note_property_declare);
-      return 0;
+      return nullptr;
     }
   }
     
@@ -463,10 +436,12 @@
       QualType PrimaryPropertyQT =
         Context.getCanonicalType(PIDecl->getType()).getUnqualifiedType();
       if (isa<ObjCObjectPointerType>(PrimaryPropertyQT)) {
+        bool PropertyIsWeak = ((PIkind & ObjCPropertyDecl::OBJC_PR_weak) != 0);
         Qualifiers::ObjCLifetime PrimaryPropertyLifeTime =
           PrimaryPropertyQT.getObjCLifetime();
         if (PrimaryPropertyLifeTime == Qualifiers::OCL_None &&
-            (Attributes & ObjCDeclSpec::DQ_PR_weak)) {
+            (Attributes & ObjCDeclSpec::DQ_PR_weak) &&
+            !PropertyIsWeak) {
               Diag(AtLoc, diag::warn_property_implicitly_mismatched);
               Diag(PIDecl->getLocation(), diag::note_property_declare);
             }
@@ -476,6 +451,18 @@
     DeclContext *DC = cast<DeclContext>(CCPrimary);
     if (!ObjCPropertyDecl::findPropertyDecl(DC,
                                  PIDecl->getDeclName().getAsIdentifierInfo())) {
+      // In mrr mode, 'readwrite' property must have an explicit
+      // memory attribute. If none specified, select the default (assign).
+      if (!getLangOpts().ObjCAutoRefCount) {
+        if (!(PIkind & (ObjCDeclSpec::DQ_PR_assign |
+                        ObjCDeclSpec::DQ_PR_retain |
+                        ObjCDeclSpec::DQ_PR_strong |
+                        ObjCDeclSpec::DQ_PR_copy |
+                        ObjCDeclSpec::DQ_PR_unsafe_unretained |
+                        ObjCDeclSpec::DQ_PR_weak)))
+          PIkind |= ObjCPropertyDecl::OBJC_PR_assign;
+      }
+      
       // Protocol is not in the primary class. Must build one for it.
       ObjCDeclSpec ProtocolPropertyODS;
       // FIXME. Assuming that ObjCDeclSpec::ObjCPropertyAttributeKind
@@ -518,7 +505,7 @@
     Diag(AtLoc, diag)
       << CCPrimary->getDeclName();
     Diag(PIDecl->getLocation(), diag::note_property_declare);
-    return 0;
+    return nullptr;
   }
   *isOverridingProperty = true;
   // Make sure setter decl is synthesized, and added to primary class's list.
@@ -563,7 +550,7 @@
 
   if (T->isObjCObjectType()) {
     SourceLocation StarLoc = TInfo->getTypeLoc().getLocEnd();
-    StarLoc = PP.getLocForEndOfToken(StarLoc);
+    StarLoc = getLocForEndOfToken(StarLoc);
     Diag(FD.D.getIdentifierLoc(), diag::err_statically_allocated_object)
       << FixItHint::CreateInsertion(StarLoc, "*");
     T = Context.getObjCObjectPointerType(T);
@@ -761,18 +748,14 @@
                                         ObjCInterfaceDecl *ClassDecl,
                                         ObjCPropertyDecl *Property) {
   ObjCInterfaceDecl::ProtocolPropertyMap PropMap;
-  for (ObjCInterfaceDecl::all_protocol_iterator
-       PI = ClassDecl->all_referenced_protocol_begin(),
-       E = ClassDecl->all_referenced_protocol_end(); PI != E; ++PI) {
-    if (const ObjCProtocolDecl *PDecl = (*PI)->getDefinition())
+  for (const auto *PI : ClassDecl->all_referenced_protocols()) {
+    if (const ObjCProtocolDecl *PDecl = PI->getDefinition())
       PDecl->collectInheritedProtocolProperties(Property, PropMap);
   }
   if (ObjCInterfaceDecl *SDecl = ClassDecl->getSuperClass())
     while (SDecl) {
-      for (ObjCInterfaceDecl::all_protocol_iterator
-           PI = SDecl->all_referenced_protocol_begin(),
-           E = SDecl->all_referenced_protocol_end(); PI != E; ++PI) {
-        if (const ObjCProtocolDecl *PDecl = (*PI)->getDefinition())
+      for (const auto *PI : SDecl->all_referenced_protocols()) {
+        if (const ObjCProtocolDecl *PDecl = PI->getDefinition())
           PDecl->collectInheritedProtocolProperties(Property, PropMap);
       }
       SDecl = SDecl->getSuperClass();
@@ -822,19 +805,19 @@
   // Make sure we have a context for the property implementation declaration.
   if (!ClassImpDecl) {
     Diag(AtLoc, diag::error_missing_property_context);
-    return 0;
+    return nullptr;
   }
   if (PropertyIvarLoc.isInvalid())
     PropertyIvarLoc = PropertyLoc;
   SourceLocation PropertyDiagLoc = PropertyLoc;
   if (PropertyDiagLoc.isInvalid())
     PropertyDiagLoc = ClassImpDecl->getLocStart();
-  ObjCPropertyDecl *property = 0;
-  ObjCInterfaceDecl* IDecl = 0;
+  ObjCPropertyDecl *property = nullptr;
+  ObjCInterfaceDecl *IDecl = nullptr;
   // Find the class or category class where this property must have
   // a declaration.
-  ObjCImplementationDecl *IC = 0;
-  ObjCCategoryImplDecl* CatImplClass = 0;
+  ObjCImplementationDecl *IC = nullptr;
+  ObjCCategoryImplDecl *CatImplClass = nullptr;
   if ((IC = dyn_cast<ObjCImplementationDecl>(ClassImpDecl))) {
     IDecl = IC->getClassInterface();
     // We always synthesize an interface for an implementation
@@ -846,7 +829,7 @@
     property = IDecl->FindPropertyDeclaration(PropertyId);
     if (!property) {
       Diag(PropertyLoc, diag::error_bad_property_decl) << IDecl->getDeclName();
-      return 0;
+      return nullptr;
     }
     unsigned PIkind = property->getPropertyAttributesAsWritten();
     if ((PIkind & (ObjCPropertyDecl::OBJC_PR_atomic |
@@ -863,7 +846,7 @@
       if (!CD->IsClassExtension()) {
         Diag(PropertyLoc, diag::error_category_property) << CD->getDeclName();
         Diag(property->getLocation(), diag::note_property_declare);
-        return 0;
+        return nullptr;
       }
     }
     if (Synthesize&&
@@ -873,9 +856,7 @@
       bool ReadWriteProperty = false;
       // Search into the class extensions and see if 'readonly property is
       // redeclared 'readwrite', then no warning is to be issued.
-      for (ObjCInterfaceDecl::known_extensions_iterator
-            Ext = IDecl->known_extensions_begin(),
-            ExtEnd = IDecl->known_extensions_end(); Ext != ExtEnd; ++Ext) {
+      for (auto *Ext : IDecl->known_extensions()) {
         DeclContext::lookup_result R = Ext->lookup(property->getDeclName());
         if (!R.empty())
           if (ObjCPropertyDecl *ExtProp = dyn_cast<ObjCPropertyDecl>(R[0])) {
@@ -889,7 +870,7 @@
       
       if (!ReadWriteProperty) {
         Diag(property->getLocation(), diag::warn_auto_readonly_iboutlet_property)
-            << property->getName();
+            << property;
         SourceLocation readonlyLoc;
         if (LocPropertyAttribute(Context, "readonly", 
                                  property->getLParenLoc(), readonlyLoc)) {
@@ -908,12 +889,12 @@
   } else if ((CatImplClass = dyn_cast<ObjCCategoryImplDecl>(ClassImpDecl))) {
     if (Synthesize) {
       Diag(AtLoc, diag::error_synthesize_category_decl);
-      return 0;
+      return nullptr;
     }
     IDecl = CatImplClass->getClassInterface();
     if (!IDecl) {
       Diag(AtLoc, diag::error_missing_property_interface);
-      return 0;
+      return nullptr;
     }
     ObjCCategoryDecl *Category =
     IDecl->FindCategoryDeclaration(CatImplClass->getIdentifier());
@@ -921,19 +902,19 @@
     // If category for this implementation not found, it is an error which
     // has already been reported eralier.
     if (!Category)
-      return 0;
+      return nullptr;
     // Look for this property declaration in @implementation's category
     property = Category->FindPropertyDeclaration(PropertyId);
     if (!property) {
       Diag(PropertyLoc, diag::error_bad_category_property_decl)
       << Category->getDeclName();
-      return 0;
+      return nullptr;
     }
   } else {
     Diag(AtLoc, diag::error_bad_property_context);
-    return 0;
+    return nullptr;
   }
-  ObjCIvarDecl *Ivar = 0;
+  ObjCIvarDecl *Ivar = nullptr;
   bool CompleteTypeErr = false;
   bool compat = true;
   // Check that we have a valid, previously declared ivar for @synthesize
@@ -981,14 +962,14 @@
       // an ivar matching property name and issue warning; since this
       // is the most common case of not using an ivar used for backing
       // property in non-default synthesis case.
-      ObjCInterfaceDecl *ClassDeclared=0;
+      ObjCInterfaceDecl *ClassDeclared=nullptr;
       ObjCIvarDecl *originalIvar = 
       IDecl->lookupInstanceVariable(property->getIdentifier(), 
                                     ClassDeclared);
       if (originalIvar) {
         Diag(PropertyDiagLoc, 
              diag::warn_autosynthesis_property_ivar_match)
-        << PropertyId << (Ivar == 0) << PropertyIvar 
+        << PropertyId << (Ivar == nullptr) << PropertyIvar
         << originalIvar->getIdentifier();
         Diag(property->getLocation(), diag::note_property_declare);
         Diag(originalIvar->getLocation(), diag::note_ivar_decl);
@@ -1047,9 +1028,9 @@
 
       Ivar = ObjCIvarDecl::Create(Context, ClassImpDecl,
                                   PropertyIvarLoc,PropertyIvarLoc, PropertyIvar,
-                                  PropertyIvarType, /*Dinfo=*/0,
+                                  PropertyIvarType, /*Dinfo=*/nullptr,
                                   ObjCIvarDecl::Private,
-                                  (Expr *)0, true);
+                                  (Expr *)nullptr, true);
       if (RequireNonAbstractType(PropertyIvarLoc,
                                  PropertyIvarType,
                                  diag::err_abstract_type_in_decl,
@@ -1161,21 +1142,23 @@
       ImplicitParamDecl *SelfDecl = getterMethod->getSelfDecl();
       DeclRefExpr *SelfExpr = 
         new (Context) DeclRefExpr(SelfDecl, false, SelfDecl->getType(),
-                                  VK_RValue, PropertyDiagLoc);
+                                  VK_LValue, PropertyDiagLoc);
       MarkDeclRefReferenced(SelfExpr);
+      Expr *LoadSelfExpr =
+        ImplicitCastExpr::Create(Context, SelfDecl->getType(),
+                                 CK_LValueToRValue, SelfExpr, nullptr,
+                                 VK_RValue);
       Expr *IvarRefExpr =
         new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), PropertyDiagLoc,
                                       Ivar->getLocation(),
-                                      SelfExpr, true, true);
-      ExprResult Res = 
-        PerformCopyInitialization(InitializedEntity::InitializeResult(
-                                    PropertyDiagLoc,
-                                    getterMethod->getResultType(),
-                                    /*NRVO=*/false),
-                                  PropertyDiagLoc,
-                                  Owned(IvarRefExpr));
+                                      LoadSelfExpr, true, true);
+      ExprResult Res = PerformCopyInitialization(
+          InitializedEntity::InitializeResult(PropertyDiagLoc,
+                                              getterMethod->getReturnType(),
+                                              /*NRVO=*/false),
+          PropertyDiagLoc, IvarRefExpr);
       if (!Res.isInvalid()) {
-        Expr *ResExpr = Res.takeAs<Expr>();
+        Expr *ResExpr = Res.getAs<Expr>();
         if (ResExpr)
           ResExpr = MaybeCreateExprWithCleanups(ResExpr);
         PIDecl->setGetterCXXConstructor(ResExpr);
@@ -1209,12 +1192,16 @@
       ImplicitParamDecl *SelfDecl = setterMethod->getSelfDecl();
       DeclRefExpr *SelfExpr = 
         new (Context) DeclRefExpr(SelfDecl, false, SelfDecl->getType(),
-                                  VK_RValue, PropertyDiagLoc);
+                                  VK_LValue, PropertyDiagLoc);
       MarkDeclRefReferenced(SelfExpr);
+      Expr *LoadSelfExpr =
+        ImplicitCastExpr::Create(Context, SelfDecl->getType(),
+                                 CK_LValueToRValue, SelfExpr, nullptr,
+                                 VK_RValue);
       Expr *lhs =
         new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), PropertyDiagLoc,
                                       Ivar->getLocation(),
-                                      SelfExpr, true, true);
+                                      LoadSelfExpr, true, true);
       ObjCMethodDecl::param_iterator P = setterMethod->param_begin();
       ParmVarDecl *Param = (*P);
       QualType T = Param->getType().getNonReferenceType();
@@ -1225,7 +1212,7 @@
                                   BO_Assign, lhs, rhs);
       if (property->getPropertyAttributes() & 
           ObjCPropertyDecl::OBJC_PR_atomic) {
-        Expr *callExpr = Res.takeAs<Expr>();
+        Expr *callExpr = Res.getAs<Expr>();
         if (const CXXOperatorCallExpr *CXXCE = 
               dyn_cast_or_null<CXXOperatorCallExpr>(callExpr))
           if (const FunctionDecl *FuncDecl = CXXCE->getDirectCallee())
@@ -1238,7 +1225,7 @@
                      diag::note_callee_decl) << FuncDecl;
               }
       }
-      PIDecl->setSetterCXXAssignment(Res.takeAs<Expr>());
+      PIDecl->setSetterCXXAssignment(Res.getAs<Expr>());
     }
   }
   
@@ -1256,7 +1243,7 @@
         = IC->FindPropertyImplDecl(PropertyId)) {
       Diag(PropertyLoc, diag::error_property_implemented) << PropertyId;
       Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
-      return 0;
+      return nullptr;
     }
     IC->addPropertyImplementation(PIDecl);
     if (getLangOpts().ObjCDefaultSynthProperties &&
@@ -1265,8 +1252,8 @@
       // Diagnose if an ivar was lazily synthesdized due to a previous
       // use and if 1) property is @dynamic or 2) property is synthesized
       // but it requires an ivar of different name.
-      ObjCInterfaceDecl *ClassDeclared=0;
-      ObjCIvarDecl *Ivar = 0;
+      ObjCInterfaceDecl *ClassDeclared=nullptr;
+      ObjCIvarDecl *Ivar = nullptr;
       if (!Synthesize)
         Ivar = IDecl->lookupInstanceVariable(PropertyId, ClassDeclared);
       else {
@@ -1295,7 +1282,7 @@
         CatImplClass->FindPropertyImplDecl(PropertyId)) {
       Diag(PropertyDiagLoc, diag::error_property_implemented) << PropertyId;
       Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
-      return 0;
+      return nullptr;
     }
     CatImplClass->addPropertyImplementation(PIDecl);
   }
@@ -1392,7 +1379,7 @@
                                             SourceLocation Loc) {
   if (!GetterMethod)
     return false;
-  QualType GetterType = GetterMethod->getResultType().getNonReferenceType();
+  QualType GetterType = GetterMethod->getReturnType().getNonReferenceType();
   QualType PropertyIvarType = property->getType().getNonReferenceType();
   bool compat = Context.hasSameType(PropertyIvarType, GetterType);
   if (!compat) {
@@ -1431,37 +1418,32 @@
 
 /// CollectImmediateProperties - This routine collects all properties in
 /// the class and its conforming protocols; but not those in its super class.
-void Sema::CollectImmediateProperties(ObjCContainerDecl *CDecl,
-            ObjCContainerDecl::PropertyMap &PropMap,
-            ObjCContainerDecl::PropertyMap &SuperPropMap) {
+static void CollectImmediateProperties(ObjCContainerDecl *CDecl,
+                                       ObjCContainerDecl::PropertyMap &PropMap,
+                                       ObjCContainerDecl::PropertyMap &SuperPropMap,
+                                       bool IncludeProtocols = true) {
+
   if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)) {
-    for (ObjCContainerDecl::prop_iterator P = IDecl->prop_begin(),
-         E = IDecl->prop_end(); P != E; ++P) {
-      ObjCPropertyDecl *Prop = *P;
+    for (auto *Prop : IDecl->properties())
       PropMap[Prop->getIdentifier()] = Prop;
+    if (IncludeProtocols) {
+      // Scan through class's protocols.
+      for (auto *PI : IDecl->all_referenced_protocols())
+        CollectImmediateProperties(PI, PropMap, SuperPropMap);
     }
-    // scan through class's protocols.
-    for (ObjCInterfaceDecl::all_protocol_iterator
-         PI = IDecl->all_referenced_protocol_begin(),
-         E = IDecl->all_referenced_protocol_end(); PI != E; ++PI)
-        CollectImmediateProperties((*PI), PropMap, SuperPropMap);
   }
   if (ObjCCategoryDecl *CATDecl = dyn_cast<ObjCCategoryDecl>(CDecl)) {
     if (!CATDecl->IsClassExtension())
-      for (ObjCContainerDecl::prop_iterator P = CATDecl->prop_begin(),
-           E = CATDecl->prop_end(); P != E; ++P) {
-        ObjCPropertyDecl *Prop = *P;
+      for (auto *Prop : CATDecl->properties())
         PropMap[Prop->getIdentifier()] = Prop;
-      }
-    // scan through class's protocols.
-    for (ObjCCategoryDecl::protocol_iterator PI = CATDecl->protocol_begin(),
-         E = CATDecl->protocol_end(); PI != E; ++PI)
-      CollectImmediateProperties((*PI), PropMap, SuperPropMap);
+    if (IncludeProtocols) {
+      // Scan through class's protocols.
+      for (auto *PI : CATDecl->protocols())
+        CollectImmediateProperties(PI, PropMap, SuperPropMap);
+    }
   }
   else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(CDecl)) {
-    for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(),
-         E = PDecl->prop_end(); P != E; ++P) {
-      ObjCPropertyDecl *Prop = *P;
+    for (auto *Prop : PDecl->properties()) {
       ObjCPropertyDecl *PropertyFromSuper = SuperPropMap[Prop->getIdentifier()];
       // Exclude property for protocols which conform to class's super-class, 
       // as super-class has to implement the property.
@@ -1473,9 +1455,8 @@
       }
     }
     // scan through protocol's protocols.
-    for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
-         E = PDecl->protocol_end(); PI != E; ++PI)
-      CollectImmediateProperties((*PI), PropMap, SuperPropMap);
+    for (auto *PI : PDecl->protocols())
+      CollectImmediateProperties(PI, PropMap, SuperPropMap);
   }
 }
 
@@ -1508,17 +1489,35 @@
   
   // look up a property declaration whose one of its accessors is implemented
   // by this method.
-  for (ObjCContainerDecl::prop_iterator P = IFace->prop_begin(),
-       E = IFace->prop_end(); P != E; ++P) {
-    ObjCPropertyDecl *property = *P;
-    if ((property->getGetterName() == IMD->getSelector() ||
-         property->getSetterName() == IMD->getSelector()) &&
-        (property->getPropertyIvarDecl() == IV))
+  for (const auto *Property : IFace->properties()) {
+    if ((Property->getGetterName() == IMD->getSelector() ||
+         Property->getSetterName() == IMD->getSelector()) &&
+        (Property->getPropertyIvarDecl() == IV))
       return true;
   }
   return false;
 }
 
+static bool SuperClassImplementsProperty(ObjCInterfaceDecl *IDecl,
+                                         ObjCPropertyDecl *Prop) {
+  bool SuperClassImplementsGetter = false;
+  bool SuperClassImplementsSetter = false;
+  if (Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_readonly)
+    SuperClassImplementsSetter = true;
+
+  while (IDecl->getSuperClass()) {
+    ObjCInterfaceDecl *SDecl = IDecl->getSuperClass();
+    if (!SuperClassImplementsGetter && SDecl->getInstanceMethod(Prop->getGetterName()))
+      SuperClassImplementsGetter = true;
+
+    if (!SuperClassImplementsSetter && SDecl->getInstanceMethod(Prop->getSetterName()))
+      SuperClassImplementsSetter = true;
+    if (SuperClassImplementsGetter && SuperClassImplementsSetter)
+      return true;
+    IDecl = IDecl->getSuperClass();
+  }
+  return false;
+}
 
 /// \brief Default synthesizes all properties which must be synthesized
 /// in class's \@implementation.
@@ -1557,7 +1556,7 @@
           !IMPDecl->getInstanceMethod(Prop->getSetterName()) &&
           !IDecl->HasUserDeclaredSetterMethod(Prop)) {
             Diag(Prop->getLocation(), diag::warn_no_autosynthesis_property)
-              << Prop->getIdentifier()->getName();
+              << Prop->getIdentifier();
             Diag(PropInSuperClass->getLocation(), diag::note_property_declare);
       }
       continue;
@@ -1566,17 +1565,23 @@
         IMPDecl->FindPropertyImplIvarDecl(Prop->getIdentifier())) {
       if (PID->getPropertyDecl() != Prop) {
         Diag(Prop->getLocation(), diag::warn_no_autosynthesis_shared_ivar_property)
-        << Prop->getIdentifier()->getName();
+          << Prop->getIdentifier();
         if (!PID->getLocation().isInvalid())
           Diag(PID->getLocation(), diag::note_property_synthesize);
       }
       continue;
     }
-    if (isa<ObjCProtocolDecl>(Prop->getDeclContext())) {
+    if (ObjCProtocolDecl *Proto =
+          dyn_cast<ObjCProtocolDecl>(Prop->getDeclContext())) {
       // We won't auto-synthesize properties declared in protocols.
-      Diag(IMPDecl->getLocation(), 
-           diag::warn_auto_synthesizing_protocol_property);
-      Diag(Prop->getLocation(), diag::note_property_declare);
+      // Suppress the warning if class's superclass implements property's
+      // getter and implements property's setter (if readwrite property).
+      if (!SuperClassImplementsProperty(IDecl, Prop)) {
+        Diag(IMPDecl->getLocation(),
+             diag::warn_auto_synthesizing_protocol_property)
+          << Prop << Proto;
+        Diag(Prop->getLocation(), diag::note_property_declare);
+      }
       continue;
     }
 
@@ -1608,44 +1613,108 @@
       DefaultSynthesizeProperties(S, IC, IDecl);
 }
 
+static void DiagnoseUnimplementedAccessor(Sema &S,
+                                          ObjCInterfaceDecl *PrimaryClass,
+                                          Selector Method,
+                                          ObjCImplDecl* IMPDecl,
+                                          ObjCContainerDecl *CDecl,
+                                          ObjCCategoryDecl *C,
+                                          ObjCPropertyDecl *Prop,
+                                          Sema::SelectorSet &SMap) {
+  // When reporting on missing property setter/getter implementation in
+  // categories, do not report when they are declared in primary class,
+  // class's protocol, or one of it super classes. This is because,
+  // the class is going to implement them.
+  if (!SMap.count(Method) &&
+      (PrimaryClass == nullptr ||
+       !PrimaryClass->lookupPropertyAccessor(Method, C))) {
+        S.Diag(IMPDecl->getLocation(),
+               isa<ObjCCategoryDecl>(CDecl) ?
+               diag::warn_setter_getter_impl_required_in_category :
+               diag::warn_setter_getter_impl_required)
+            << Prop->getDeclName() << Method;
+        S.Diag(Prop->getLocation(),
+             diag::note_property_declare);
+        if (S.LangOpts.ObjCDefaultSynthProperties &&
+            S.LangOpts.ObjCRuntime.isNonFragile())
+          if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(CDecl))
+            if (const ObjCInterfaceDecl *RID = ID->isObjCRequiresPropertyDefs())
+            S.Diag(RID->getLocation(), diag::note_suppressed_class_declare);
+      }
+}
+
 void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl,
-                                      ObjCContainerDecl *CDecl) {
-  ObjCContainerDecl::PropertyMap NoNeedToImplPropMap;
-  ObjCInterfaceDecl *IDecl;
-  // Gather properties which need not be implemented in this class
-  // or category.
-  if (!(IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl)))
-    if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl)) {
-      // For categories, no need to implement properties declared in
-      // its primary class (and its super classes) if property is
-      // declared in one of those containers.
-      if ((IDecl = C->getClassInterface())) {
-        ObjCInterfaceDecl::PropertyDeclOrder PO;
-        IDecl->collectPropertiesToImplement(NoNeedToImplPropMap, PO);
+                                           ObjCContainerDecl *CDecl,
+                                           bool SynthesizeProperties) {
+  ObjCContainerDecl::PropertyMap PropMap;
+  ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl);
+
+  if (!SynthesizeProperties) {
+    ObjCContainerDecl::PropertyMap NoNeedToImplPropMap;
+    // Gather properties which need not be implemented in this class
+    // or category.
+    if (!IDecl)
+      if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl)) {
+        // For categories, no need to implement properties declared in
+        // its primary class (and its super classes) if property is
+        // declared in one of those containers.
+        if ((IDecl = C->getClassInterface())) {
+          ObjCInterfaceDecl::PropertyDeclOrder PO;
+          IDecl->collectPropertiesToImplement(NoNeedToImplPropMap, PO);
+        }
+      }
+    if (IDecl)
+      CollectSuperClassPropertyImplementations(IDecl, NoNeedToImplPropMap);
+    
+    CollectImmediateProperties(CDecl, PropMap, NoNeedToImplPropMap);
+  }
+
+  // Scan the @interface to see if any of the protocols it adopts
+  // require an explicit implementation, via attribute
+  // 'objc_protocol_requires_explicit_implementation'.
+  if (IDecl) {
+    std::unique_ptr<ObjCContainerDecl::PropertyMap> LazyMap;
+
+    for (auto *PDecl : IDecl->all_referenced_protocols()) {
+      if (!PDecl->hasAttr<ObjCExplicitProtocolImplAttr>())
+        continue;
+      // Lazily construct a set of all the properties in the @interface
+      // of the class, without looking at the superclass.  We cannot
+      // use the call to CollectImmediateProperties() above as that
+      // utilizes information from the super class's properties as well
+      // as scans the adopted protocols.  This work only triggers for protocols
+      // with the attribute, which is very rare, and only occurs when
+      // analyzing the @implementation.
+      if (!LazyMap) {
+        ObjCContainerDecl::PropertyMap NoNeedToImplPropMap;
+        LazyMap.reset(new ObjCContainerDecl::PropertyMap());
+        CollectImmediateProperties(CDecl, *LazyMap, NoNeedToImplPropMap,
+                                   /* IncludeProtocols */ false);
+      }
+      // Add the properties of 'PDecl' to the list of properties that
+      // need to be implemented.
+      for (auto *PropDecl : PDecl->properties()) {
+        if ((*LazyMap)[PropDecl->getIdentifier()])
+          continue;
+        PropMap[PropDecl->getIdentifier()] = PropDecl;
       }
     }
-  if (IDecl)
-    CollectSuperClassPropertyImplementations(IDecl, NoNeedToImplPropMap);
-  
-  ObjCContainerDecl::PropertyMap PropMap;
-  CollectImmediateProperties(CDecl, PropMap, NoNeedToImplPropMap);
+  }
+
   if (PropMap.empty())
     return;
 
   llvm::DenseSet<ObjCPropertyDecl *> PropImplMap;
-  for (ObjCImplDecl::propimpl_iterator
-       I = IMPDecl->propimpl_begin(),
-       EI = IMPDecl->propimpl_end(); I != EI; ++I)
+  for (const auto *I : IMPDecl->property_impls())
     PropImplMap.insert(I->getPropertyDecl());
 
   SelectorSet InsMap;
   // Collect property accessors implemented in current implementation.
-  for (ObjCImplementationDecl::instmeth_iterator
-       I = IMPDecl->instmeth_begin(), E = IMPDecl->instmeth_end(); I!=E; ++I)
-    InsMap.insert((*I)->getSelector());
+  for (const auto *I : IMPDecl->instance_methods())
+    InsMap.insert(I->getSelector());
   
   ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl);
-  ObjCInterfaceDecl *PrimaryClass = 0;
+  ObjCInterfaceDecl *PrimaryClass = nullptr;
   if (C && !C->IsClassExtension())
     if ((PrimaryClass = C->getClassInterface()))
       // Report unimplemented properties in the category as well.
@@ -1653,9 +1722,8 @@
         // When reporting on missing setter/getters, do not report when
         // setter/getter is implemented in category's primary class
         // implementation.
-        for (ObjCImplementationDecl::instmeth_iterator
-             I = IMP->instmeth_begin(), E = IMP->instmeth_end(); I!=E; ++I)
-          InsMap.insert((*I)->getSelector());
+        for (const auto *I : IMP->instance_methods())
+          InsMap.insert(I->getSelector());
       }
 
   for (ObjCContainerDecl::PropertyMap::iterator
@@ -1667,45 +1735,14 @@
         PropImplMap.count(Prop) ||
         Prop->getAvailability() == AR_Unavailable)
       continue;
-    // When reporting on missing property getter implementation in
-    // categories, do not report when they are declared in primary class,
-    // class's protocol, or one of it super classes. This is because,
-    // the class is going to implement them.
-    if (!InsMap.count(Prop->getGetterName()) &&
-        (PrimaryClass == 0 ||
-         !PrimaryClass->lookupPropertyAccessor(Prop->getGetterName(), C))) {
-      Diag(IMPDecl->getLocation(),
-           isa<ObjCCategoryDecl>(CDecl) ?
-            diag::warn_setter_getter_impl_required_in_category :
-            diag::warn_setter_getter_impl_required)
-      << Prop->getDeclName() << Prop->getGetterName();
-      Diag(Prop->getLocation(),
-           diag::note_property_declare);
-      if (LangOpts.ObjCDefaultSynthProperties && LangOpts.ObjCRuntime.isNonFragile())
-        if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(CDecl))
-          if (const ObjCInterfaceDecl *RID = ID->isObjCRequiresPropertyDefs())
-            Diag(RID->getLocation(), diag::note_suppressed_class_declare);
-            
-    }
-    // When reporting on missing property setter implementation in
-    // categories, do not report when they are declared in primary class,
-    // class's protocol, or one of it super classes. This is because,
-    // the class is going to implement them.
-    if (!Prop->isReadOnly() && !InsMap.count(Prop->getSetterName()) &&
-        (PrimaryClass == 0 ||
-         !PrimaryClass->lookupPropertyAccessor(Prop->getSetterName(), C))) {
-      Diag(IMPDecl->getLocation(),
-           isa<ObjCCategoryDecl>(CDecl) ?
-           diag::warn_setter_getter_impl_required_in_category :
-           diag::warn_setter_getter_impl_required)
-      << Prop->getDeclName() << Prop->getSetterName();
-      Diag(Prop->getLocation(),
-           diag::note_property_declare);
-      if (LangOpts.ObjCDefaultSynthProperties && LangOpts.ObjCRuntime.isNonFragile())
-        if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(CDecl))
-          if (const ObjCInterfaceDecl *RID = ID->isObjCRequiresPropertyDefs())
-            Diag(RID->getLocation(), diag::note_suppressed_class_declare);
-    }
+
+    // Diagnose unimplemented getters and setters.
+    DiagnoseUnimplementedAccessor(*this,
+          PrimaryClass, Prop->getGetterName(), IMPDecl, CDecl, C, Prop, InsMap);
+    if (!Prop->isReadOnly())
+      DiagnoseUnimplementedAccessor(*this,
+                                    PrimaryClass, Prop->getSetterName(),
+                                    IMPDecl, CDecl, C, Prop, InsMap);
   }
 }
 
@@ -1715,12 +1752,9 @@
   // Rules apply in non-GC mode only
   if (getLangOpts().getGC() != LangOptions::NonGC)
     return;
-  for (ObjCContainerDecl::prop_iterator I = IDecl->prop_begin(),
-       E = IDecl->prop_end();
-       I != E; ++I) {
-    ObjCPropertyDecl *Property = *I;
-    ObjCMethodDecl *GetterMethod = 0;
-    ObjCMethodDecl *SetterMethod = 0;
+  for (const auto *Property : IDecl->properties()) {
+    ObjCMethodDecl *GetterMethod = nullptr;
+    ObjCMethodDecl *SetterMethod = nullptr;
     bool LookedUpGetterSetter = false;
 
     unsigned Attributes = Property->getPropertyAttributes();
@@ -1756,15 +1790,14 @@
       if (!LookedUpGetterSetter) {
         GetterMethod = IMPDecl->getInstanceMethod(Property->getGetterName());
         SetterMethod = IMPDecl->getInstanceMethod(Property->getSetterName());
-        LookedUpGetterSetter = true;
       }
       if ((GetterMethod && !SetterMethod) || (!GetterMethod && SetterMethod)) {
         SourceLocation MethodLoc =
           (GetterMethod ? GetterMethod->getLocation()
                         : SetterMethod->getLocation());
         Diag(MethodLoc, diag::warn_atomic_property_rule)
-          << Property->getIdentifier() << (GetterMethod != 0)
-          << (SetterMethod != 0);
+          << Property->getIdentifier() << (GetterMethod != nullptr)
+          << (SetterMethod != nullptr);
         // fixit stuff.
         if (!AttributesAsWritten) {
           if (Property->getLParenLoc().isValid()) {
@@ -1803,12 +1836,7 @@
   if (getLangOpts().getGC() == LangOptions::GCOnly)
     return;
 
-  for (ObjCImplementationDecl::propimpl_iterator
-         i = D->propimpl_begin(), e = D->propimpl_end(); i != e; ++i) {
-    ObjCPropertyImplDecl *PID = *i;
-    if (PID->getPropertyImplementation() != ObjCPropertyImplDecl::Synthesize)
-      continue;
-    
+  for (const auto *PID : D->property_impls()) {
     const ObjCPropertyDecl *PD = PID->getPropertyDecl();
     if (PD && !PD->hasAttr<NSReturnsNotRetainedAttr>() &&
         !D->getInstanceMethod(PD->getGetterName())) {
@@ -1819,27 +1847,51 @@
       if (family == OMF_alloc || family == OMF_copy ||
           family == OMF_mutableCopy || family == OMF_new) {
         if (getLangOpts().ObjCAutoRefCount)
-          Diag(PID->getLocation(), diag::err_ownin_getter_rule);
+          Diag(PD->getLocation(), diag::err_cocoa_naming_owned_rule);
         else
-          Diag(PID->getLocation(), diag::warn_owning_getter_rule);
-        Diag(PD->getLocation(), diag::note_property_declare);
+          Diag(PD->getLocation(), diag::warn_cocoa_naming_owned_rule);
       }
     }
   }
 }
 
+void Sema::DiagnoseMissingDesignatedInitOverrides(
+                                            const ObjCImplementationDecl *ImplD,
+                                            const ObjCInterfaceDecl *IFD) {
+  assert(IFD->hasDesignatedInitializers());
+  const ObjCInterfaceDecl *SuperD = IFD->getSuperClass();
+  if (!SuperD)
+    return;
+
+  SelectorSet InitSelSet;
+  for (const auto *I : ImplD->instance_methods())
+    if (I->getMethodFamily() == OMF_init)
+      InitSelSet.insert(I->getSelector());
+
+  SmallVector<const ObjCMethodDecl *, 8> DesignatedInits;
+  SuperD->getDesignatedInitializers(DesignatedInits);
+  for (SmallVector<const ObjCMethodDecl *, 8>::iterator
+         I = DesignatedInits.begin(), E = DesignatedInits.end(); I != E; ++I) {
+    const ObjCMethodDecl *MD = *I;
+    if (!InitSelSet.count(MD->getSelector())) {
+      Diag(ImplD->getLocation(),
+           diag::warn_objc_implementation_missing_designated_init_override)
+        << MD->getSelector();
+      Diag(MD->getLocation(), diag::note_objc_designated_init_marked_here);
+    }
+  }
+}
+
 /// AddPropertyAttrs - Propagates attributes from a property to the
 /// implicitly-declared getter or setter for that property.
 static void AddPropertyAttrs(Sema &S, ObjCMethodDecl *PropertyMethod,
                              ObjCPropertyDecl *Property) {
   // Should we just clone all attributes over?
-  for (Decl::attr_iterator A = Property->attr_begin(), 
-                        AEnd = Property->attr_end(); 
-       A != AEnd; ++A) {
-    if (isa<DeprecatedAttr>(*A) || 
-        isa<UnavailableAttr>(*A) || 
-        isa<AvailabilityAttr>(*A))
-      PropertyMethod->addAttr((*A)->clone(S.Context));
+  for (const auto *A : Property->attrs()) {
+    if (isa<DeprecatedAttr>(A) || 
+        isa<UnavailableAttr>(A) || 
+        isa<AvailabilityAttr>(A))
+      PropertyMethod->addAttr(A->clone(S.Context));
   }
 }
 
@@ -1855,6 +1907,9 @@
 
   ObjCMethodDecl *GetterMethod, *SetterMethod;
 
+  if (CD->isInvalidDecl())
+    return;
+
   GetterMethod = CD->getInstanceMethod(property->getGetterName());
   SetterMethod = CD->getInstanceMethod(property->getSetterName());
   DiagnosePropertyAccessorMismatch(property, GetterMethod,
@@ -1864,8 +1919,8 @@
     ObjCPropertyDecl::PropertyAttributeKind CAttr =
       property->getPropertyAttributes();
     if ((!(CAttr & ObjCPropertyDecl::OBJC_PR_readonly)) &&
-        Context.getCanonicalType(SetterMethod->getResultType()) !=
-          Context.VoidTy)
+        Context.getCanonicalType(SetterMethod->getReturnType()) !=
+            Context.VoidTy)
       Diag(SetterMethod->getLocation(), diag::err_setter_type_void);
     if (SetterMethod->param_size() != 1 ||
         !Context.hasSameUnqualifiedType(
@@ -1895,8 +1950,9 @@
 
     GetterMethod = ObjCMethodDecl::Create(Context, Loc, Loc,
                              property->getGetterName(),
-                             property->getType(), 0, CD, /*isInstance=*/true,
-                             /*isVariadic=*/false, /*isPropertyAccessor=*/true,
+                             property->getType(), nullptr, CD,
+                             /*isInstance=*/true, /*isVariadic=*/false,
+                             /*isPropertyAccessor=*/true,
                              /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
                              (property->getPropertyImplementation() ==
                               ObjCPropertyDecl::Optional) ?
@@ -1911,12 +1967,17 @@
     if (lexicalDC)
       GetterMethod->setLexicalDeclContext(lexicalDC);
     if (property->hasAttr<NSReturnsNotRetainedAttr>())
-      GetterMethod->addAttr(
-        ::new (Context) NSReturnsNotRetainedAttr(Loc, Context));
+      GetterMethod->addAttr(NSReturnsNotRetainedAttr::CreateImplicit(Context,
+                                                                     Loc));
     
     if (property->hasAttr<ObjCReturnsInnerPointerAttr>())
       GetterMethod->addAttr(
-        ::new (Context) ObjCReturnsInnerPointerAttr(Loc, Context));
+        ObjCReturnsInnerPointerAttr::CreateImplicit(Context, Loc));
+    
+    if (const SectionAttr *SA = property->getAttr<SectionAttr>())
+      GetterMethod->addAttr(
+          SectionAttr::CreateImplicit(Context, SectionAttr::GNU_section,
+                                      SA->getName(), Loc));
 
     if (getLangOpts().ObjCAutoRefCount)
       CheckARCMethodDecl(GetterMethod);
@@ -1939,8 +2000,9 @@
 
       SetterMethod =
         ObjCMethodDecl::Create(Context, Loc, Loc,
-                               property->getSetterName(), Context.VoidTy, 0,
-                               CD, /*isInstance=*/true, /*isVariadic=*/false,
+                               property->getSetterName(), Context.VoidTy,
+                               nullptr, CD, /*isInstance=*/true,
+                               /*isVariadic=*/false,
                                /*isPropertyAccessor=*/true,
                                /*isImplicitlyDeclared=*/true,
                                /*isDefined=*/false,
@@ -1955,9 +2017,9 @@
                                                   Loc, Loc,
                                                   property->getIdentifier(),
                                     property->getType().getUnqualifiedType(),
-                                                  /*TInfo=*/0,
+                                                  /*TInfo=*/nullptr,
                                                   SC_None,
-                                                  0);
+                                                  nullptr);
       SetterMethod->setMethodParams(Context, Argument, None);
 
       AddPropertyAttrs(*this, SetterMethod, property);
@@ -1967,7 +2029,10 @@
       // and the real context should be the same.
       if (lexicalDC)
         SetterMethod->setLexicalDeclContext(lexicalDC);
-
+      if (const SectionAttr *SA = property->getAttr<SectionAttr>())
+        SetterMethod->addAttr(
+            SectionAttr::CreateImplicit(Context, SectionAttr::GNU_section,
+                                        SA->getName(), Loc));
       // It's possible for the user to have set a very odd custom
       // setter selector that causes it to have a method family.
       if (getLangOpts().ObjCAutoRefCount)
@@ -2025,27 +2090,19 @@
   QualType PropertyTy = PropertyDecl->getType();
   unsigned PropertyOwnership = getOwnershipRule(Attributes);
 
-  if (Attributes & ObjCDeclSpec::DQ_PR_readonly) {
-    if (getLangOpts().ObjCAutoRefCount &&
-        PropertyTy->isObjCRetainableType() &&
-        !PropertyOwnership) {
-      // 'readonly' property with no obvious lifetime.
-      // its life time will be determined by its backing ivar.
-      return;
-    }
-    else if (PropertyOwnership) {
-      if (!getSourceManager().isInSystemHeader(Loc))
-        Diag(Loc, diag::warn_objc_property_attr_mutually_exclusive)
-          << "readonly" << NameOfOwnershipAttribute(Attributes);
-      return;
-    }
-  }
+  // 'readonly' property with no obvious lifetime.
+  // its life time will be determined by its backing ivar.
+  if (getLangOpts().ObjCAutoRefCount &&
+      Attributes & ObjCDeclSpec::DQ_PR_readonly &&
+      PropertyTy->isObjCRetainableType() &&
+      !PropertyOwnership)
+    return;
 
   // Check for copy or retain on non-object types.
   if ((Attributes & (ObjCDeclSpec::DQ_PR_weak | ObjCDeclSpec::DQ_PR_copy |
                     ObjCDeclSpec::DQ_PR_retain | ObjCDeclSpec::DQ_PR_strong)) &&
       !PropertyTy->isObjCRetainableType() &&
-      !PropertyDecl->getAttr<ObjCNSObjectAttr>()) {
+      !PropertyDecl->hasAttr<ObjCNSObjectAttr>()) {
     Diag(Loc, diag::err_objc_property_requires_object)
       << (Attributes & ObjCDeclSpec::DQ_PR_weak ? "weak" :
           Attributes & ObjCDeclSpec::DQ_PR_copy ? "copy" : "retain (or strong)");
@@ -2077,7 +2134,7 @@
         << "assign" << "weak";
       Attributes &= ~ObjCDeclSpec::DQ_PR_weak;
     }
-    if (PropertyDecl->getAttr<IBOutletCollectionAttr>())
+    if (PropertyDecl->hasAttr<IBOutletCollectionAttr>())
       Diag(Loc, diag::warn_iboutletcollection_property_assign);
   } else if (Attributes & ObjCDeclSpec::DQ_PR_unsafe_unretained) {
     if (Attributes & ObjCDeclSpec::DQ_PR_copy) {
diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp
index c63caf4..7f2af68 100644
--- a/lib/Sema/SemaOpenMP.cpp
+++ b/lib/Sema/SemaOpenMP.cpp
@@ -1,4 +1,4 @@
-//===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ----------===//
+//===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -12,19 +12,20 @@
 ///
 //===----------------------------------------------------------------------===//
 
-#include "clang/Basic/OpenMPKinds.h"
+#include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclOpenMP.h"
 #include "clang/AST/StmtCXX.h"
 #include "clang/AST/StmtOpenMP.h"
 #include "clang/AST/StmtVisitor.h"
+#include "clang/Basic/OpenMPKinds.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Sema/Initialization.h"
-#include "clang/Sema/SemaInternal.h"
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/Scope.h"
 #include "clang/Sema/ScopeInfo.h"
+#include "clang/Sema/SemaInternal.h"
 using namespace clang;
 
 //===----------------------------------------------------------------------===//
@@ -34,11 +35,31 @@
 namespace {
 /// \brief Default data sharing attributes, which can be applied to directive.
 enum DefaultDataSharingAttributes {
-  DSA_unspecified = 0,   /// \brief Data sharing attribute not specified.
-  DSA_none = 1 << 0,     /// \brief Default data sharing attribute 'none'.
-  DSA_shared = 1 << 1    /// \brief Default data sharing attribute 'shared'.
+  DSA_unspecified = 0, /// \brief Data sharing attribute not specified.
+  DSA_none = 1 << 0,   /// \brief Default data sharing attribute 'none'.
+  DSA_shared = 1 << 1  /// \brief Default data sharing attribute 'shared'.
 };
 
+template <class T> struct MatchesAny {
+  explicit MatchesAny(ArrayRef<T> Arr) : Arr(std::move(Arr)) {}
+  bool operator()(T Kind) {
+    for (auto KindEl : Arr)
+      if (KindEl == Kind)
+        return true;
+    return false;
+  }
+
+private:
+  ArrayRef<T> Arr;
+};
+struct MatchesAlways {
+  MatchesAlways() {}
+  template <class T> bool operator()(T) { return true; }
+};
+
+typedef MatchesAny<OpenMPClauseKind> MatchesAnyClause;
+typedef MatchesAny<OpenMPDirectiveKind> MatchesAnyDirective;
+
 /// \brief Stack for tracking declarations used in OpenMP directives and
 /// clauses and their data-sharing attributes.
 class DSAStackTy {
@@ -47,47 +68,60 @@
     OpenMPDirectiveKind DKind;
     OpenMPClauseKind CKind;
     DeclRefExpr *RefExpr;
-    DSAVarData() : DKind(OMPD_unknown), CKind(OMPC_unknown), RefExpr(0) { }
+    SourceLocation ImplicitDSALoc;
+    DSAVarData()
+        : DKind(OMPD_unknown), CKind(OMPC_unknown), RefExpr(nullptr),
+          ImplicitDSALoc() {}
   };
+
 private:
   struct DSAInfo {
     OpenMPClauseKind Attributes;
     DeclRefExpr *RefExpr;
   };
   typedef llvm::SmallDenseMap<VarDecl *, DSAInfo, 64> DeclSAMapTy;
+  typedef llvm::SmallDenseMap<VarDecl *, DeclRefExpr *, 64> AlignedMapTy;
 
   struct SharingMapTy {
     DeclSAMapTy SharingMap;
+    AlignedMapTy AlignedMap;
     DefaultDataSharingAttributes DefaultAttr;
+    SourceLocation DefaultAttrLoc;
     OpenMPDirectiveKind Directive;
     DeclarationNameInfo DirectiveName;
     Scope *CurScope;
-    SharingMapTy(OpenMPDirectiveKind DKind,
-                 const DeclarationNameInfo &Name,
-                 Scope *CurScope)
-      : SharingMap(), DefaultAttr(DSA_unspecified), Directive(DKind),
-        DirectiveName(Name), CurScope(CurScope) { }
+    SourceLocation ConstructLoc;
+    SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
+                 Scope *CurScope, SourceLocation Loc)
+        : SharingMap(), AlignedMap(), DefaultAttr(DSA_unspecified),
+          Directive(DKind), DirectiveName(std::move(Name)), CurScope(CurScope),
+          ConstructLoc(Loc) {}
     SharingMapTy()
-      : SharingMap(), DefaultAttr(DSA_unspecified),
-        Directive(OMPD_unknown), DirectiveName(),
-        CurScope(0) { }
+        : SharingMap(), AlignedMap(), DefaultAttr(DSA_unspecified),
+          Directive(OMPD_unknown), DirectiveName(), CurScope(nullptr),
+          ConstructLoc() {}
   };
 
   typedef SmallVector<SharingMapTy, 64> StackTy;
 
   /// \brief Stack of used declaration and their data-sharing attributes.
   StackTy Stack;
-  Sema &Actions;
+  Sema &SemaRef;
 
   typedef SmallVector<SharingMapTy, 8>::reverse_iterator reverse_iterator;
 
   DSAVarData getDSA(StackTy::reverse_iterator Iter, VarDecl *D);
+
+  /// \brief Checks if the variable is a local for OpenMP region.
+  bool isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter);
+
 public:
-  explicit DSAStackTy(Sema &S) : Stack(1), Actions(S) { }
+  explicit DSAStackTy(Sema &S) : Stack(1), SemaRef(S) {}
 
   void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
-            Scope *CurScope) {
-    Stack.push_back(SharingMapTy(DKind, DirName, CurScope));
+            Scope *CurScope, SourceLocation Loc) {
+    Stack.push_back(SharingMapTy(DKind, DirName, CurScope, Loc));
+    Stack.back().DefaultAttrLoc = Loc;
   }
 
   void pop() {
@@ -95,51 +129,90 @@
     Stack.pop_back();
   }
 
+  /// \brief If 'aligned' declaration for given variable \a D was not seen yet,
+  /// add it and return NULL; otherwise return previous occurrence's expression
+  /// for diagnostics.
+  DeclRefExpr *addUniqueAligned(VarDecl *D, DeclRefExpr *NewDE);
+
   /// \brief Adds explicit data sharing attribute to the specified declaration.
   void addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A);
 
-  /// \brief Checks if the variable is a local for OpenMP region.
-  bool isOpenMPLocal(VarDecl *D);
-
   /// \brief Returns data sharing attributes from top of the stack for the
   /// specified declaration.
-  DSAVarData getTopDSA(VarDecl *D);
+  DSAVarData getTopDSA(VarDecl *D, bool FromParent);
   /// \brief Returns data-sharing attributes for the specified declaration.
-  DSAVarData getImplicitDSA(VarDecl *D);
-  /// \brief Checks if the specified variables has \a CKind data-sharing
-  /// attribute in \a DKind directive.
-  DSAVarData hasDSA(VarDecl *D, OpenMPClauseKind CKind,
-                    OpenMPDirectiveKind DKind = OMPD_unknown);
-
+  DSAVarData getImplicitDSA(VarDecl *D, bool FromParent);
+  /// \brief Checks if the specified variables has data-sharing attributes which
+  /// match specified \a CPred predicate in any directive which matches \a DPred
+  /// predicate.
+  template <class ClausesPredicate, class DirectivesPredicate>
+  DSAVarData hasDSA(VarDecl *D, ClausesPredicate CPred,
+                    DirectivesPredicate DPred, bool FromParent);
+  /// \brief Checks if the specified variables has data-sharing attributes which
+  /// match specified \a CPred predicate in any innermost directive which
+  /// matches \a DPred predicate.
+  template <class ClausesPredicate, class DirectivesPredicate>
+  DSAVarData hasInnermostDSA(VarDecl *D, ClausesPredicate CPred,
+                             DirectivesPredicate DPred,
+                             bool FromParent);
+  /// \brief Finds a directive which matches specified \a DPred predicate.
+  template <class NamedDirectivesPredicate>
+  bool hasDirective(NamedDirectivesPredicate DPred, bool FromParent);
 
   /// \brief Returns currently analyzed directive.
   OpenMPDirectiveKind getCurrentDirective() const {
     return Stack.back().Directive;
   }
+  /// \brief Returns parent directive.
+  OpenMPDirectiveKind getParentDirective() const {
+    if (Stack.size() > 2)
+      return Stack[Stack.size() - 2].Directive;
+    return OMPD_unknown;
+  }
 
   /// \brief Set default data sharing attribute to none.
-  void setDefaultDSANone() { Stack.back().DefaultAttr = DSA_none; }
+  void setDefaultDSANone(SourceLocation Loc) {
+    Stack.back().DefaultAttr = DSA_none;
+    Stack.back().DefaultAttrLoc = Loc;
+  }
   /// \brief Set default data sharing attribute to shared.
-  void setDefaultDSAShared() { Stack.back().DefaultAttr = DSA_shared; }
+  void setDefaultDSAShared(SourceLocation Loc) {
+    Stack.back().DefaultAttr = DSA_shared;
+    Stack.back().DefaultAttrLoc = Loc;
+  }
 
   DefaultDataSharingAttributes getDefaultDSA() const {
     return Stack.back().DefaultAttr;
   }
+  SourceLocation getDefaultDSALocation() const {
+    return Stack.back().DefaultAttrLoc;
+  }
 
+  /// \brief Checks if the specified variable is a threadprivate.
+  bool isThreadPrivate(VarDecl *D) {
+    DSAVarData DVar = getTopDSA(D, false);
+    return isOpenMPThreadPrivate(DVar.CKind);
+  }
+
+  Scope *getCurScope() const { return Stack.back().CurScope; }
   Scope *getCurScope() { return Stack.back().CurScope; }
+  SourceLocation getConstructLoc() { return Stack.back().ConstructLoc; }
 };
-} // end anonymous namespace.
+bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) {
+  return isOpenMPParallelDirective(DKind) || DKind == OMPD_task ||
+         DKind == OMPD_unknown;
+}
+} // namespace
 
 DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator Iter,
                                           VarDecl *D) {
   DSAVarData DVar;
-  if (Iter == Stack.rend() - 1) {
+  if (Iter == std::prev(Stack.rend())) {
     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
     // in a region but not in construct]
     //  File-scope or namespace-scope variables referenced in called routines
     //  in the region are shared unless they appear in a threadprivate
     //  directive.
-    // TODO
     if (!D->isFunctionOrMethodVarDecl())
       DVar.CKind = OMPC_shared;
 
@@ -152,12 +225,24 @@
 
     return DVar;
   }
+
   DVar.DKind = Iter->Directive;
+  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
+  // in a Construct, C/C++, predetermined, p.1]
+  // Variables with automatic storage duration that are declared in a scope
+  // inside the construct are private.
+  if (isOpenMPLocal(D, Iter) && D->isLocalVarDecl() &&
+      (D->getStorageClass() == SC_Auto || D->getStorageClass() == SC_None)) {
+    DVar.CKind = OMPC_private;
+    return DVar;
+  }
+
   // Explicitly specified attributes and local variables with predetermined
   // attributes.
   if (Iter->SharingMap.count(D)) {
     DVar.RefExpr = Iter->SharingMap[D].RefExpr;
     DVar.CKind = Iter->SharingMap[D].Attributes;
+    DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
     return DVar;
   }
 
@@ -168,6 +253,7 @@
   switch (Iter->DefaultAttr) {
   case DSA_shared:
     DVar.CKind = OMPC_shared;
+    DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
     return DVar;
   case DSA_none:
     return DVar;
@@ -176,7 +262,8 @@
     // in a Construct, implicitly determined, p.2]
     //  In a parallel construct, if no default clause is present, these
     //  variables are shared.
-    if (DVar.DKind == OMPD_parallel) {
+    DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
+    if (isOpenMPParallelDirective(DVar.DKind)) {
       DVar.CKind = OMPC_shared;
       return DVar;
     }
@@ -186,29 +273,30 @@
     //  In a task construct, if no default clause is present, a variable that in
     //  the enclosing context is determined to be shared by all implicit tasks
     //  bound to the current team is shared.
-    // TODO
     if (DVar.DKind == OMPD_task) {
       DSAVarData DVarTemp;
-      for (StackTy::reverse_iterator I = Iter + 1,
-                                     EE = Stack.rend() - 1;
+      for (StackTy::reverse_iterator I = std::next(Iter),
+                                     EE = std::prev(Stack.rend());
            I != EE; ++I) {
-        // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
+        // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
+        // Referenced
         // in a Construct, implicitly determined, p.6]
         //  In a task construct, if no default clause is present, a variable
         //  whose data-sharing attribute is not determined by the rules above is
         //  firstprivate.
         DVarTemp = getDSA(I, D);
         if (DVarTemp.CKind != OMPC_shared) {
-          DVar.RefExpr = 0;
+          DVar.RefExpr = nullptr;
           DVar.DKind = OMPD_task;
           DVar.CKind = OMPC_firstprivate;
           return DVar;
         }
-        if (I->Directive == OMPD_parallel) break;
+        if (isParallelOrTaskRegion(I->Directive))
+          break;
       }
       DVar.DKind = OMPD_task;
       DVar.CKind =
-        (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
+          (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
       return DVar;
     }
   }
@@ -217,7 +305,21 @@
   //  For constructs other than task, if no default clause is present, these
   //  variables inherit their data-sharing attributes from the enclosing
   //  context.
-  return getDSA(Iter + 1, D);
+  return getDSA(std::next(Iter), D);
+}
+
+DeclRefExpr *DSAStackTy::addUniqueAligned(VarDecl *D, DeclRefExpr *NewDE) {
+  assert(Stack.size() > 1 && "Data sharing attributes stack is empty");
+  auto It = Stack.back().AlignedMap.find(D);
+  if (It == Stack.back().AlignedMap.end()) {
+    assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
+    Stack.back().AlignedMap[D] = NewDE;
+    return nullptr;
+  } else {
+    assert(It->second && "Unexpected nullptr expr in the aligned map");
+    return It->second;
+  }
+  return nullptr;
 }
 
 void DSAStackTy::addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A) {
@@ -231,26 +333,26 @@
   }
 }
 
-bool DSAStackTy::isOpenMPLocal(VarDecl *D) {
-  Scope *CurScope = getCurScope();
-  while (CurScope && !CurScope->isDeclScope(D))
-    CurScope = CurScope->getParent();
-  while (CurScope && !CurScope->isOpenMPDirectiveScope())
-    CurScope = CurScope->getParent();
-  bool isOpenMPLocal = !!CurScope;
-  if (!isOpenMPLocal) {
-    CurScope = getCurScope();
-    while (CurScope && !CurScope->isOpenMPDirectiveScope())
+bool DSAStackTy::isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter) {
+  if (Stack.size() > 2) {
+    reverse_iterator I = Iter, E = std::prev(Stack.rend());
+    Scope *TopScope = nullptr;
+    while (I != E && !isParallelOrTaskRegion(I->Directive)) {
+      ++I;
+    }
+    if (I == E)
+      return false;
+    TopScope = I->CurScope ? I->CurScope->getParent() : nullptr;
+    Scope *CurScope = getCurScope();
+    while (CurScope != TopScope && !CurScope->isDeclScope(D)) {
       CurScope = CurScope->getParent();
-    isOpenMPLocal =
-      CurScope &&
-      isa<CapturedDecl>(D->getDeclContext()) &&
-      CurScope->getFnParent()->getEntity()->Encloses(D->getDeclContext());
+    }
+    return CurScope != TopScope;
   }
-  return isOpenMPLocal;
+  return false;
 }
 
-DSAStackTy::DSAVarData DSAStackTy::getTopDSA(VarDecl *D) {
+DSAStackTy::DSAVarData DSAStackTy::getTopDSA(VarDecl *D, bool FromParent) {
   DSAVarData DVar;
 
   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
@@ -270,20 +372,29 @@
   // in a Construct, C/C++, predetermined, p.1]
   // Variables with automatic storage duration that are declared in a scope
   // inside the construct are private.
-  if (isOpenMPLocal(D) && D->isLocalVarDecl() &&
-      (D->getStorageClass() == SC_Auto ||
-       D->getStorageClass() == SC_None)) {
-    DVar.CKind = OMPC_private;
-    return DVar;
+  OpenMPDirectiveKind Kind =
+      FromParent ? getParentDirective() : getCurrentDirective();
+  auto StartI = std::next(Stack.rbegin());
+  auto EndI = std::prev(Stack.rend());
+  if (FromParent && StartI != EndI) {
+    StartI = std::next(StartI);
+  }
+  if (!isParallelOrTaskRegion(Kind)) {
+    if (isOpenMPLocal(D, StartI) && D->isLocalVarDecl() &&
+        (D->getStorageClass() == SC_Auto || D->getStorageClass() == SC_None)) {
+      DVar.CKind = OMPC_private;
+      return DVar;
+    }
   }
 
   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
   // in a Construct, C/C++, predetermined, p.4]
-  //  Static data memebers are shared.
+  //  Static data members are shared.
   if (D->isStaticDataMember()) {
-    // Variables with const-qualified type having no mutable member may be listed
-    // in a firstprivate clause, even if they are static data members.
-    DSAVarData DVarTemp = hasDSA(D, OMPC_firstprivate);
+    // Variables with const-qualified type having no mutable member may be
+    // listed in a firstprivate clause, even if they are static data members.
+    DSAVarData DVarTemp = hasDSA(D, MatchesAnyClause(OMPC_firstprivate),
+                                 MatchesAlways(), FromParent);
     if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr)
       return DVar;
 
@@ -292,7 +403,7 @@
   }
 
   QualType Type = D->getType().getNonReferenceType().getCanonicalType();
-  bool IsConstant = Type.isConstant(Actions.getASTContext());
+  bool IsConstant = Type.isConstant(SemaRef.getASTContext());
   while (Type->isArrayType()) {
     QualType ElemType = cast<ArrayType>(Type.getTypePtr())->getElementType();
     Type = ElemType.getNonReferenceType().getCanonicalType();
@@ -301,13 +412,14 @@
   // in a Construct, C/C++, predetermined, p.6]
   //  Variables with const qualified type having no mutable member are
   //  shared.
-  CXXRecordDecl *RD = Actions.getLangOpts().CPlusPlus ?
-                                Type->getAsCXXRecordDecl() : 0;
+  CXXRecordDecl *RD =
+      SemaRef.getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr;
   if (IsConstant &&
-      !(Actions.getLangOpts().CPlusPlus && RD && RD->hasMutableFields())) {
+      !(SemaRef.getLangOpts().CPlusPlus && RD && RD->hasMutableFields())) {
     // Variables with const-qualified type having no mutable member may be
     // listed in a firstprivate clause, even if they are static data members.
-    DSAVarData DVarTemp = hasDSA(D, OMPC_firstprivate);
+    DSAVarData DVarTemp = hasDSA(D, MatchesAnyClause(OMPC_firstprivate),
+                                 MatchesAlways(), FromParent);
     if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr)
       return DVar;
 
@@ -319,56 +431,151 @@
   // in a Construct, C/C++, predetermined, p.7]
   //  Variables with static storage duration that are declared in a scope
   //  inside the construct are shared.
-  if (isOpenMPLocal(D) && D->isStaticLocal()) {
+  if (D->isStaticLocal()) {
     DVar.CKind = OMPC_shared;
     return DVar;
   }
 
   // Explicitly specified attributes and local variables with predetermined
   // attributes.
-  if (Stack.back().SharingMap.count(D)) {
-    DVar.RefExpr = Stack.back().SharingMap[D].RefExpr;
-    DVar.CKind = Stack.back().SharingMap[D].Attributes;
+  auto I = std::prev(StartI);
+  if (I->SharingMap.count(D)) {
+    DVar.RefExpr = I->SharingMap[D].RefExpr;
+    DVar.CKind = I->SharingMap[D].Attributes;
+    DVar.ImplicitDSALoc = I->DefaultAttrLoc;
   }
 
   return DVar;
 }
 
-DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(VarDecl *D) {
-  return getDSA(Stack.rbegin() + 1, D);
+DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(VarDecl *D, bool FromParent) {
+  auto StartI = Stack.rbegin();
+  auto EndI = std::prev(Stack.rend());
+  if (FromParent && StartI != EndI) {
+    StartI = std::next(StartI);
+  }
+  return getDSA(StartI, D);
 }
 
-DSAStackTy::DSAVarData DSAStackTy::hasDSA(VarDecl *D, OpenMPClauseKind CKind,
-                                          OpenMPDirectiveKind DKind) {
-  for (StackTy::reverse_iterator I = Stack.rbegin() + 1,
-                                 E = Stack.rend() - 1;
-       I != E; ++I) {
-    if (DKind != OMPD_unknown && DKind != I->Directive) continue;
+template <class ClausesPredicate, class DirectivesPredicate>
+DSAStackTy::DSAVarData DSAStackTy::hasDSA(VarDecl *D, ClausesPredicate CPred,
+                                          DirectivesPredicate DPred,
+                                          bool FromParent) {
+  auto StartI = std::next(Stack.rbegin());
+  auto EndI = std::prev(Stack.rend());
+  if (FromParent && StartI != EndI) {
+    StartI = std::next(StartI);
+  }
+  for (auto I = StartI, EE = EndI; I != EE; ++I) {
+    if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive))
+      continue;
     DSAVarData DVar = getDSA(I, D);
-    if (DVar.CKind == CKind)
+    if (CPred(DVar.CKind))
       return DVar;
   }
   return DSAVarData();
 }
 
+template <class ClausesPredicate, class DirectivesPredicate>
+DSAStackTy::DSAVarData
+DSAStackTy::hasInnermostDSA(VarDecl *D, ClausesPredicate CPred,
+                            DirectivesPredicate DPred, bool FromParent) {
+  auto StartI = std::next(Stack.rbegin());
+  auto EndI = std::prev(Stack.rend());
+  if (FromParent && StartI != EndI) {
+    StartI = std::next(StartI);
+  }
+  for (auto I = StartI, EE = EndI; I != EE; ++I) {
+    if (!DPred(I->Directive))
+      break;
+    DSAVarData DVar = getDSA(I, D);
+    if (CPred(DVar.CKind))
+      return DVar;
+    return DSAVarData();
+  }
+  return DSAVarData();
+}
+
+template <class NamedDirectivesPredicate>
+bool DSAStackTy::hasDirective(NamedDirectivesPredicate DPred, bool FromParent) {
+  auto StartI = std::next(Stack.rbegin());
+  auto EndI = std::prev(Stack.rend());
+  if (FromParent && StartI != EndI) {
+    StartI = std::next(StartI);
+  }
+  for (auto I = StartI, EE = EndI; I != EE; ++I) {
+    if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
+      return true;
+  }
+  return false;
+}
+
 void Sema::InitDataSharingAttributesStack() {
   VarDataSharingAttributesStack = new DSAStackTy(*this);
 }
 
 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
 
-void Sema::DestroyDataSharingAttributesStack() {
-  delete DSAStack;
-}
+void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
 
 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
                                const DeclarationNameInfo &DirName,
-                               Scope *CurScope) {
-  DSAStack->push(DKind, DirName, CurScope);
+                               Scope *CurScope, SourceLocation Loc) {
+  DSAStack->push(DKind, DirName, CurScope, Loc);
   PushExpressionEvaluationContext(PotentiallyEvaluated);
 }
 
 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
+  // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
+  //  A variable of class type (or array thereof) that appears in a lastprivate
+  //  clause requires an accessible, unambiguous default constructor for the
+  //  class type, unless the list item is also specified in a firstprivate
+  //  clause.
+  if (auto D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
+    for (auto C : D->clauses()) {
+      if (auto Clause = dyn_cast<OMPLastprivateClause>(C)) {
+        for (auto VarRef : Clause->varlists()) {
+          if (VarRef->isValueDependent() || VarRef->isTypeDependent())
+            continue;
+          auto VD = cast<VarDecl>(cast<DeclRefExpr>(VarRef)->getDecl());
+          auto DVar = DSAStack->getTopDSA(VD, false);
+          if (DVar.CKind == OMPC_lastprivate) {
+            SourceLocation ELoc = VarRef->getExprLoc();
+            auto Type = VarRef->getType();
+            if (Type->isArrayType())
+              Type = QualType(Type->getArrayElementTypeNoTypeQual(), 0);
+            CXXRecordDecl *RD =
+                getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr;
+            // FIXME This code must be replaced by actual constructing of the
+            // lastprivate variable.
+            if (RD) {
+              CXXConstructorDecl *CD = LookupDefaultConstructor(RD);
+              PartialDiagnostic PD =
+                  PartialDiagnostic(PartialDiagnostic::NullDiagnostic());
+              if (!CD ||
+                  CheckConstructorAccess(
+                      ELoc, CD, InitializedEntity::InitializeTemporary(Type),
+                      CD->getAccess(), PD) == AR_inaccessible ||
+                  CD->isDeleted()) {
+                Diag(ELoc, diag::err_omp_required_method)
+                    << getOpenMPClauseName(OMPC_lastprivate) << 0;
+                bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
+                              VarDecl::DeclarationOnly;
+                Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl
+                                               : diag::note_defined_here)
+                    << VD;
+                Diag(RD->getLocation(), diag::note_previous_decl) << RD;
+                continue;
+              }
+              MarkFunctionReferenced(ELoc, CD);
+              DiagnoseUseOfDecl(CD, ELoc);
+            }
+          }
+        }
+      }
+    }
+  }
+
   DSAStack->pop();
   DiscardCleanupsInEvaluationContext();
   PopExpressionEvaluationContext();
@@ -378,20 +585,21 @@
 
 class VarDeclFilterCCC : public CorrectionCandidateCallback {
 private:
-  Sema &Actions;
+  Sema &SemaRef;
+
 public:
-  VarDeclFilterCCC(Sema &S) : Actions(S) { }
-  virtual bool ValidateCandidate(const TypoCorrection &Candidate) {
+  explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
+  bool ValidateCandidate(const TypoCorrection &Candidate) override {
     NamedDecl *ND = Candidate.getCorrectionDecl();
     if (VarDecl *VD = dyn_cast_or_null<VarDecl>(ND)) {
       return VD->hasGlobalStorage() &&
-             Actions.isDeclInScope(ND, Actions.getCurLexicalContext(),
-                                   Actions.getCurScope());
+             SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
+                                   SemaRef.getCurScope());
     }
     return false;
   }
 };
-}
+} // namespace
 
 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
                                          CXXScopeSpec &ScopeSpec,
@@ -405,12 +613,14 @@
   VarDecl *VD;
   if (!Lookup.isSingleResult()) {
     VarDeclFilterCCC Validator(*this);
-    if (TypoCorrection Corrected = CorrectTypo(Id, LookupOrdinaryName, CurScope,
-                                               0, Validator)) {
+    if (TypoCorrection Corrected =
+            CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, Validator,
+                        CTK_ErrorRecovery)) {
       diagnoseTypo(Corrected,
-                   PDiag(Lookup.empty()? diag::err_undeclared_var_use_suggest
-                                       : diag::err_omp_expected_var_arg_suggest)
-                     << Id.getName());
+                   PDiag(Lookup.empty()
+                             ? diag::err_undeclared_var_use_suggest
+                             : diag::err_omp_expected_var_arg_suggest)
+                       << Id.getName());
       VD = Corrected.getCorrectionDeclAs<VarDecl>();
     } else {
       Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
@@ -420,8 +630,7 @@
     }
   } else {
     if (!(VD = Lookup.getAsSingle<VarDecl>())) {
-      Diag(Id.getLoc(), diag::err_omp_expected_var_arg)
-        << Id.getName();
+      Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
       Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
       return ExprError();
     }
@@ -432,12 +641,12 @@
   //   Variables must be file-scope, namespace-scope, or static block-scope.
   if (!VD->hasGlobalStorage()) {
     Diag(Id.getLoc(), diag::err_omp_global_var_arg)
-      << getOpenMPDirectiveName(OMPD_threadprivate)
-      << !VD->isStaticLocal();
-    bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
-                  VarDecl::DeclarationOnly;
+        << getOpenMPDirectiveName(OMPD_threadprivate) << !VD->isStaticLocal();
+    bool IsDecl =
+        VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
     Diag(VD->getLocation(),
-         IsDecl ? diag::note_previous_decl : diag::note_defined_here) << VD;
+         IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+        << VD;
     return ExprError();
   }
 
@@ -449,11 +658,12 @@
   if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
       !getCurLexicalContext()->isTranslationUnit()) {
     Diag(Id.getLoc(), diag::err_omp_var_scope)
-      << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
-    bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
-                  VarDecl::DeclarationOnly;
-    Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
-                                     diag::note_defined_here) << VD;
+        << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
+    bool IsDecl =
+        VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+    Diag(VD->getLocation(),
+         IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+        << VD;
     return ExprError();
   }
   // OpenMP [2.9.2, Restrictions, C/C++, p.3]
@@ -463,11 +673,12 @@
   if (CanonicalVD->isStaticDataMember() &&
       !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
     Diag(Id.getLoc(), diag::err_omp_var_scope)
-      << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
-    bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
-                  VarDecl::DeclarationOnly;
-    Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
-                                     diag::note_defined_here) << VD;
+        << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
+    bool IsDecl =
+        VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+    Diag(VD->getLocation(),
+         IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+        << VD;
     return ExprError();
   }
   // OpenMP [2.9.2, Restrictions, C/C++, p.4]
@@ -478,11 +689,12 @@
       (!getCurLexicalContext()->isFileContext() ||
        !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
     Diag(Id.getLoc(), diag::err_omp_var_scope)
-      << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
-    bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
-                  VarDecl::DeclarationOnly;
-    Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
-                                     diag::note_defined_here) << VD;
+        << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
+    bool IsDecl =
+        VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+    Diag(VD->getLocation(),
+         IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+        << VD;
     return ExprError();
   }
   // OpenMP [2.9.2, Restrictions, C/C++, p.6]
@@ -491,11 +703,12 @@
   if (CanonicalVD->isStaticLocal() && CurScope &&
       !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
     Diag(Id.getLoc(), diag::err_omp_var_scope)
-      << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
-    bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
-                  VarDecl::DeclarationOnly;
-    Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
-                                     diag::note_defined_here) << VD;
+        << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
+    bool IsDecl =
+        VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+    Diag(VD->getLocation(),
+         IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+        << VD;
     return ExprError();
   }
 
@@ -504,19 +717,18 @@
   //   of the variables in its list.
   if (VD->isUsed()) {
     Diag(Id.getLoc(), diag::err_omp_var_used)
-      << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
+        << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
     return ExprError();
   }
 
   QualType ExprType = VD->getType().getNonReferenceType();
-  ExprResult DE = BuildDeclRefExpr(VD, ExprType, VK_RValue, Id.getLoc());
-  DSAStack->addDSA(VD, cast<DeclRefExpr>(DE.get()), OMPC_threadprivate);
+  ExprResult DE = BuildDeclRefExpr(VD, ExprType, VK_LValue, Id.getLoc());
   return DE;
 }
 
-Sema::DeclGroupPtrTy Sema::ActOnOpenMPThreadprivateDirective(
-                                SourceLocation Loc,
-                                ArrayRef<Expr *> VarList) {
+Sema::DeclGroupPtrTy
+Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
+                                        ArrayRef<Expr *> VarList) {
   if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
     CurContext->addDecl(D);
     return DeclGroupPtrTy::make(DeclGroupRef(D));
@@ -524,14 +736,40 @@
   return DeclGroupPtrTy();
 }
 
-OMPThreadPrivateDecl *Sema::CheckOMPThreadPrivateDecl(
-                                 SourceLocation Loc,
-                                 ArrayRef<Expr *> VarList) {
+namespace {
+class LocalVarRefChecker : public ConstStmtVisitor<LocalVarRefChecker, bool> {
+  Sema &SemaRef;
+
+public:
+  bool VisitDeclRefExpr(const DeclRefExpr *E) {
+    if (auto VD = dyn_cast<VarDecl>(E->getDecl())) {
+      if (VD->hasLocalStorage()) {
+        SemaRef.Diag(E->getLocStart(),
+                     diag::err_omp_local_var_in_threadprivate_init)
+            << E->getSourceRange();
+        SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
+            << VD << VD->getSourceRange();
+        return true;
+      }
+    }
+    return false;
+  }
+  bool VisitStmt(const Stmt *S) {
+    for (auto Child : S->children()) {
+      if (Child && Visit(Child))
+        return true;
+    }
+    return false;
+  }
+  explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
+};
+} // namespace
+
+OMPThreadPrivateDecl *
+Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
   SmallVector<Expr *, 8> Vars;
-  for (ArrayRef<Expr *>::iterator I = VarList.begin(),
-                                         E = VarList.end();
-       I != E; ++I) {
-    DeclRefExpr *DE = cast<DeclRefExpr>(*I);
+  for (auto &RefExpr : VarList) {
+    DeclRefExpr *DE = cast<DeclRefExpr>(RefExpr);
     VarDecl *VD = cast<VarDecl>(DE->getDecl());
     SourceLocation ILoc = DE->getExprLoc();
 
@@ -546,64 +784,130 @@
     //   A threadprivate variable must not have a reference type.
     if (VD->getType()->isReferenceType()) {
       Diag(ILoc, diag::err_omp_ref_type_arg)
-        << getOpenMPDirectiveName(OMPD_threadprivate)
-        << VD->getType();
-      bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
-                    VarDecl::DeclarationOnly;
-      Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
-                                       diag::note_defined_here) << VD;
+          << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
+      bool IsDecl =
+          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+      Diag(VD->getLocation(),
+           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+          << VD;
       continue;
     }
 
     // Check if this is a TLS variable.
     if (VD->getTLSKind()) {
       Diag(ILoc, diag::err_omp_var_thread_local) << VD;
-      bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
-                    VarDecl::DeclarationOnly;
-      Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
-                                       diag::note_defined_here) << VD;
+      bool IsDecl =
+          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+      Diag(VD->getLocation(),
+           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+          << VD;
       continue;
     }
 
-    Vars.push_back(*I);
+    // Check if initial value of threadprivate variable reference variable with
+    // local storage (it is not supported by runtime).
+    if (auto Init = VD->getAnyInitializer()) {
+      LocalVarRefChecker Checker(*this);
+      if (Checker.Visit(Init))
+        continue;
+    }
+
+    Vars.push_back(RefExpr);
+    DSAStack->addDSA(VD, DE, OMPC_threadprivate);
   }
-  return Vars.empty() ?
-              0 : OMPThreadPrivateDecl::Create(Context,
-                                               getCurLexicalContext(),
-                                               Loc, Vars);
+  OMPThreadPrivateDecl *D = nullptr;
+  if (!Vars.empty()) {
+    D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
+                                     Vars);
+    D->setAccess(AS_public);
+  }
+  return D;
+}
+
+static void ReportOriginalDSA(Sema &SemaRef, DSAStackTy *Stack,
+                              const VarDecl *VD, DSAStackTy::DSAVarData DVar,
+                              bool IsLoopIterVar = false) {
+  if (DVar.RefExpr) {
+    SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
+        << getOpenMPClauseName(DVar.CKind);
+    return;
+  }
+  enum {
+    PDSA_StaticMemberShared,
+    PDSA_StaticLocalVarShared,
+    PDSA_LoopIterVarPrivate,
+    PDSA_LoopIterVarLinear,
+    PDSA_LoopIterVarLastprivate,
+    PDSA_ConstVarShared,
+    PDSA_GlobalVarShared,
+    PDSA_TaskVarFirstprivate,
+    PDSA_LocalVarPrivate,
+    PDSA_Implicit
+  } Reason = PDSA_Implicit;
+  bool ReportHint = false;
+  auto ReportLoc = VD->getLocation();
+  if (IsLoopIterVar) {
+    if (DVar.CKind == OMPC_private)
+      Reason = PDSA_LoopIterVarPrivate;
+    else if (DVar.CKind == OMPC_lastprivate)
+      Reason = PDSA_LoopIterVarLastprivate;
+    else
+      Reason = PDSA_LoopIterVarLinear;
+  } else if (DVar.DKind == OMPD_task && DVar.CKind == OMPC_firstprivate) {
+    Reason = PDSA_TaskVarFirstprivate;
+    ReportLoc = DVar.ImplicitDSALoc;
+  } else if (VD->isStaticLocal())
+    Reason = PDSA_StaticLocalVarShared;
+  else if (VD->isStaticDataMember())
+    Reason = PDSA_StaticMemberShared;
+  else if (VD->isFileVarDecl())
+    Reason = PDSA_GlobalVarShared;
+  else if (VD->getType().isConstant(SemaRef.getASTContext()))
+    Reason = PDSA_ConstVarShared;
+  else if (VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
+    ReportHint = true;
+    Reason = PDSA_LocalVarPrivate;
+  }
+  if (Reason != PDSA_Implicit) {
+    SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
+        << Reason << ReportHint
+        << getOpenMPDirectiveName(Stack->getCurrentDirective());
+  } else if (DVar.ImplicitDSALoc.isValid()) {
+    SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
+        << getOpenMPClauseName(DVar.CKind);
+  }
 }
 
 namespace {
 class DSAAttrChecker : public StmtVisitor<DSAAttrChecker, void> {
   DSAStackTy *Stack;
-  Sema &Actions;
+  Sema &SemaRef;
   bool ErrorFound;
   CapturedStmt *CS;
   llvm::SmallVector<Expr *, 8> ImplicitFirstprivate;
+  llvm::DenseMap<VarDecl *, Expr *> VarsWithInheritedDSA;
+
 public:
   void VisitDeclRefExpr(DeclRefExpr *E) {
-    if(VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) {
+    if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
       // Skip internally declared variables.
-      if (VD->isLocalVarDecl() && !CS->capturesVariable(VD)) return;
-
-      SourceLocation ELoc = E->getExprLoc();
-
-      OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
-      DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD);
-      if (DVar.CKind != OMPC_unknown) {
-        if (DKind == OMPD_task && DVar.CKind != OMPC_shared &&
-            DVar.CKind != OMPC_threadprivate && !DVar.RefExpr)
-          ImplicitFirstprivate.push_back(DVar.RefExpr);
+      if (VD->isLocalVarDecl() && !CS->capturesVariable(VD))
         return;
-      }
+
+      auto DVar = Stack->getTopDSA(VD, false);
+      // Check if the variable has explicit DSA set and stop analysis if it so.
+      if (DVar.RefExpr) return;
+
+      auto ELoc = E->getExprLoc();
+      auto DKind = Stack->getCurrentDirective();
       // The default(none) clause requires that each variable that is referenced
       // in the construct, and does not have a predetermined data-sharing
       // attribute, must have its data-sharing attribute explicitly determined
       // by being listed in a data-sharing attribute clause.
       if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none &&
-          (DKind == OMPD_parallel || DKind == OMPD_task)) {
-        ErrorFound = true;
-        Actions.Diag(ELoc, diag::err_omp_no_dsa_for_variable) << VD;
+          isParallelOrTaskRegion(DKind) &&
+          VarsWithInheritedDSA.count(VD) == 0) {
+        VarsWithInheritedDSA[VD] = E;
         return;
       }
 
@@ -611,84 +915,593 @@
       //  A list item that appears in a reduction clause of the innermost
       //  enclosing worksharing or parallel construct may not be accessed in an
       //  explicit task.
-      // TODO:
+      DVar = Stack->hasInnermostDSA(VD, MatchesAnyClause(OMPC_reduction),
+                                    [](OpenMPDirectiveKind K) -> bool {
+                                      return isOpenMPParallelDirective(K) ||
+                                             isOpenMPWorksharingDirective(K);
+                                    },
+                                    false);
+      if (DKind == OMPD_task && DVar.CKind == OMPC_reduction) {
+        ErrorFound = true;
+        SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
+        ReportOriginalDSA(SemaRef, Stack, VD, DVar);
+        return;
+      }
 
       // Define implicit data-sharing attributes for task.
-      DVar = Stack->getImplicitDSA(VD);
+      DVar = Stack->getImplicitDSA(VD, false);
       if (DKind == OMPD_task && DVar.CKind != OMPC_shared)
-        ImplicitFirstprivate.push_back(DVar.RefExpr);
+        ImplicitFirstprivate.push_back(E);
     }
   }
   void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
-    for (ArrayRef<OMPClause *>::iterator I = S->clauses().begin(),
-                                         E = S->clauses().end();
-         I != E; ++I)
-      if (OMPClause *C = *I)
-        for (StmtRange R = C->children(); R; ++R)
-          if (Stmt *Child = *R)
-            Visit(Child);
+    for (auto *C : S->clauses()) {
+      // Skip analysis of arguments of implicitly defined firstprivate clause
+      // for task directives.
+      if (C && (!isa<OMPFirstprivateClause>(C) || C->getLocStart().isValid()))
+        for (auto *CC : C->children()) {
+          if (CC)
+            Visit(CC);
+        }
+    }
   }
   void VisitStmt(Stmt *S) {
-    for (Stmt::child_iterator I = S->child_begin(), E = S->child_end();
-         I != E; ++I)
-      if (Stmt *Child = *I)
-        if (!isa<OMPExecutableDirective>(Child))
-          Visit(Child);
+    for (auto *C : S->children()) {
+      if (C && !isa<OMPExecutableDirective>(C))
+        Visit(C);
     }
+  }
 
   bool isErrorFound() { return ErrorFound; }
   ArrayRef<Expr *> getImplicitFirstprivate() { return ImplicitFirstprivate; }
+  llvm::DenseMap<VarDecl *, Expr *> &getVarsWithInheritedDSA() {
+    return VarsWithInheritedDSA;
+  }
 
-  DSAAttrChecker(DSAStackTy *S, Sema &Actions, CapturedStmt *CS)
-    : Stack(S), Actions(Actions), ErrorFound(false), CS(CS) { }
+  DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
+      : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {}
 };
+} // namespace
+
+void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
+  switch (DKind) {
+  case OMPD_parallel: {
+    QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
+    QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty);
+    Sema::CapturedParamNameType Params[] = {
+        std::make_pair(".global_tid.", KmpInt32PtrTy),
+        std::make_pair(".bound_tid.", KmpInt32PtrTy),
+        std::make_pair(StringRef(), QualType()) // __context with shared vars
+    };
+    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
+                             Params);
+    break;
+  }
+  case OMPD_simd: {
+    Sema::CapturedParamNameType Params[] = {
+        std::make_pair(StringRef(), QualType()) // __context with shared vars
+    };
+    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
+                             Params);
+    break;
+  }
+  case OMPD_for: {
+    Sema::CapturedParamNameType Params[] = {
+        std::make_pair(StringRef(), QualType()) // __context with shared vars
+    };
+    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
+                             Params);
+    break;
+  }
+  case OMPD_sections: {
+    Sema::CapturedParamNameType Params[] = {
+        std::make_pair(StringRef(), QualType()) // __context with shared vars
+    };
+    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
+                             Params);
+    break;
+  }
+  case OMPD_section: {
+    Sema::CapturedParamNameType Params[] = {
+        std::make_pair(StringRef(), QualType()) // __context with shared vars
+    };
+    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
+                             Params);
+    break;
+  }
+  case OMPD_single: {
+    Sema::CapturedParamNameType Params[] = {
+        std::make_pair(StringRef(), QualType()) // __context with shared vars
+    };
+    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
+                             Params);
+    break;
+  }
+  case OMPD_master: {
+    Sema::CapturedParamNameType Params[] = {
+        std::make_pair(StringRef(), QualType()) // __context with shared vars
+    };
+    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
+                             Params);
+    break;
+  }
+  case OMPD_critical: {
+    Sema::CapturedParamNameType Params[] = {
+        std::make_pair(StringRef(), QualType()) // __context with shared vars
+    };
+    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
+                             Params);
+    break;
+  }
+  case OMPD_parallel_for: {
+    QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
+    QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty);
+    Sema::CapturedParamNameType Params[] = {
+        std::make_pair(".global_tid.", KmpInt32PtrTy),
+        std::make_pair(".bound_tid.", KmpInt32PtrTy),
+        std::make_pair(StringRef(), QualType()) // __context with shared vars
+    };
+    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
+                             Params);
+    break;
+  }
+  case OMPD_parallel_sections: {
+    Sema::CapturedParamNameType Params[] = {
+        std::make_pair(StringRef(), QualType()) // __context with shared vars
+    };
+    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
+                             Params);
+    break;
+  }
+  case OMPD_task: {
+    Sema::CapturedParamNameType Params[] = {
+        std::make_pair(StringRef(), QualType()) // __context with shared vars
+    };
+    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
+                             Params);
+    break;
+  }
+  case OMPD_taskyield: {
+    Sema::CapturedParamNameType Params[] = {
+        std::make_pair(StringRef(), QualType()) // __context with shared vars
+    };
+    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
+                             Params);
+    break;
+  }
+  case OMPD_barrier: {
+    Sema::CapturedParamNameType Params[] = {
+        std::make_pair(StringRef(), QualType()) // __context with shared vars
+    };
+    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
+                             Params);
+    break;
+  }
+  case OMPD_taskwait: {
+    Sema::CapturedParamNameType Params[] = {
+        std::make_pair(StringRef(), QualType()) // __context with shared vars
+    };
+    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
+                             Params);
+    break;
+  }
+  case OMPD_flush: {
+    Sema::CapturedParamNameType Params[] = {
+        std::make_pair(StringRef(), QualType()) // __context with shared vars
+    };
+    ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
+                             Params);
+    break;
+  }
+  case OMPD_threadprivate:
+    llvm_unreachable("OpenMP Directive is not allowed");
+  case OMPD_unknown:
+    llvm_unreachable("Unknown OpenMP directive");
+  }
+}
+
+static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
+                                  OpenMPDirectiveKind CurrentRegion,
+                                  const DeclarationNameInfo &CurrentName,
+                                  SourceLocation StartLoc) {
+  // Allowed nesting of constructs
+  // +------------------+-----------------+------------------------------------+
+  // | Parent directive | Child directive | Closely (!), No-Closely(+), Both(*)|
+  // +------------------+-----------------+------------------------------------+
+  // | parallel         | parallel        | *                                  |
+  // | parallel         | for             | *                                  |
+  // | parallel         | master          | *                                  |
+  // | parallel         | critical        | *                                  |
+  // | parallel         | simd            | *                                  |
+  // | parallel         | sections        | *                                  |
+  // | parallel         | section         | +                                  |
+  // | parallel         | single          | *                                  |
+  // | parallel         | parallel for    | *                                  |
+  // | parallel         |parallel sections| *                                  |
+  // | parallel         | task            | *                                  |
+  // | parallel         | taskyield       | *                                  |
+  // | parallel         | barrier         | *                                  |
+  // | parallel         | taskwait        | *                                  |
+  // | parallel         | flush           | *                                  |
+  // +------------------+-----------------+------------------------------------+
+  // | for              | parallel        | *                                  |
+  // | for              | for             | +                                  |
+  // | for              | master          | +                                  |
+  // | for              | critical        | *                                  |
+  // | for              | simd            | *                                  |
+  // | for              | sections        | +                                  |
+  // | for              | section         | +                                  |
+  // | for              | single          | +                                  |
+  // | for              | parallel for    | *                                  |
+  // | for              |parallel sections| *                                  |
+  // | for              | task            | *                                  |
+  // | for              | taskyield       | *                                  |
+  // | for              | barrier         | +                                  |
+  // | for              | taskwait        | *                                  |
+  // | for              | flush           | *                                  |
+  // +------------------+-----------------+------------------------------------+
+  // | master           | parallel        | *                                  |
+  // | master           | for             | +                                  |
+  // | master           | master          | *                                  |
+  // | master           | critical        | *                                  |
+  // | master           | simd            | *                                  |
+  // | master           | sections        | +                                  |
+  // | master           | section         | +                                  |
+  // | master           | single          | +                                  |
+  // | master           | parallel for    | *                                  |
+  // | master           |parallel sections| *                                  |
+  // | master           | task            | *                                  |
+  // | master           | taskyield       | *                                  |
+  // | master           | barrier         | +                                  |
+  // | master           | taskwait        | *                                  |
+  // | master           | flush           | *                                  |
+  // +------------------+-----------------+------------------------------------+
+  // | critical         | parallel        | *                                  |
+  // | critical         | for             | +                                  |
+  // | critical         | master          | *                                  |
+  // | critical         | critical        | * (should have dirrerent names)    |
+  // | critical         | simd            | *                                  |
+  // | critical         | sections        | +                                  |
+  // | critical         | section         | +                                  |
+  // | critical         | single          | +                                  |
+  // | critical         | parallel for    | *                                  |
+  // | critical         |parallel sections| *                                  |
+  // | critical         | task            | *                                  |
+  // | critical         | taskyield       | *                                  |
+  // | critical         | barrier         | +                                  |
+  // | critical         | taskwait        | *                                  |
+  // +------------------+-----------------+------------------------------------+
+  // | simd             | parallel        |                                    |
+  // | simd             | for             |                                    |
+  // | simd             | master          |                                    |
+  // | simd             | critical        |                                    |
+  // | simd             | simd            |                                    |
+  // | simd             | sections        |                                    |
+  // | simd             | section         |                                    |
+  // | simd             | single          |                                    |
+  // | simd             | parallel for    |                                    |
+  // | simd             |parallel sections|                                    |
+  // | simd             | task            |                                    |
+  // | simd             | taskyield       |                                    |
+  // | simd             | barrier         |                                    |
+  // | simd             | taskwait        |                                    |
+  // | simd             | flush           |                                    |
+  // +------------------+-----------------+------------------------------------+
+  // | sections         | parallel        | *                                  |
+  // | sections         | for             | +                                  |
+  // | sections         | master          | +                                  |
+  // | sections         | critical        | *                                  |
+  // | sections         | simd            | *                                  |
+  // | sections         | sections        | +                                  |
+  // | sections         | section         | *                                  |
+  // | sections         | single          | +                                  |
+  // | sections         | parallel for    | *                                  |
+  // | sections         |parallel sections| *                                  |
+  // | sections         | task            | *                                  |
+  // | sections         | taskyield       | *                                  |
+  // | sections         | barrier         | +                                  |
+  // | sections         | taskwait        | *                                  |
+  // | sections         | flush           | *                                  |
+  // +------------------+-----------------+------------------------------------+
+  // | section          | parallel        | *                                  |
+  // | section          | for             | +                                  |
+  // | section          | master          | +                                  |
+  // | section          | critical        | *                                  |
+  // | section          | simd            | *                                  |
+  // | section          | sections        | +                                  |
+  // | section          | section         | +                                  |
+  // | section          | single          | +                                  |
+  // | section          | parallel for    | *                                  |
+  // | section          |parallel sections| *                                  |
+  // | section          | task            | *                                  |
+  // | section          | taskyield       | *                                  |
+  // | section          | barrier         | +                                  |
+  // | section          | taskwait        | *                                  |
+  // | section          | flush           | *                                  |
+  // +------------------+-----------------+------------------------------------+
+  // | single           | parallel        | *                                  |
+  // | single           | for             | +                                  |
+  // | single           | master          | +                                  |
+  // | single           | critical        | *                                  |
+  // | single           | simd            | *                                  |
+  // | single           | sections        | +                                  |
+  // | single           | section         | +                                  |
+  // | single           | single          | +                                  |
+  // | single           | parallel for    | *                                  |
+  // | single           |parallel sections| *                                  |
+  // | single           | task            | *                                  |
+  // | single           | taskyield       | *                                  |
+  // | single           | barrier         | +                                  |
+  // | single           | taskwait        | *                                  |
+  // | single           | flush           | *                                  |
+  // +------------------+-----------------+------------------------------------+
+  // | parallel for     | parallel        | *                                  |
+  // | parallel for     | for             | +                                  |
+  // | parallel for     | master          | +                                  |
+  // | parallel for     | critical        | *                                  |
+  // | parallel for     | simd            | *                                  |
+  // | parallel for     | sections        | +                                  |
+  // | parallel for     | section         | +                                  |
+  // | parallel for     | single          | +                                  |
+  // | parallel for     | parallel for    | *                                  |
+  // | parallel for     |parallel sections| *                                  |
+  // | parallel for     | task            | *                                  |
+  // | parallel for     | taskyield       | *                                  |
+  // | parallel for     | barrier         | +                                  |
+  // | parallel for     | taskwait        | *                                  |
+  // | parallel for     | flush           | *                                  |
+  // +------------------+-----------------+------------------------------------+
+  // | parallel sections| parallel        | *                                  |
+  // | parallel sections| for             | +                                  |
+  // | parallel sections| master          | +                                  |
+  // | parallel sections| critical        | +                                  |
+  // | parallel sections| simd            | *                                  |
+  // | parallel sections| sections        | +                                  |
+  // | parallel sections| section         | *                                  |
+  // | parallel sections| single          | +                                  |
+  // | parallel sections| parallel for    | *                                  |
+  // | parallel sections|parallel sections| *                                  |
+  // | parallel sections| task            | *                                  |
+  // | parallel sections| taskyield       | *                                  |
+  // | parallel sections| barrier         | +                                  |
+  // | parallel sections| taskwait        | *                                  |
+  // | parallel sections| flush           | *                                  |
+  // +------------------+-----------------+------------------------------------+
+  // | task             | parallel        | *                                  |
+  // | task             | for             | +                                  |
+  // | task             | master          | +                                  |
+  // | task             | critical        | *                                  |
+  // | task             | simd            | *                                  |
+  // | task             | sections        | +                                  |
+  // | task             | section         | +                                  |
+  // | task             | single          | +                                  |
+  // | task             | parallel for    | *                                  |
+  // | task             |parallel sections| *                                  |
+  // | task             | task            | *                                  |
+  // | task             | taskyield       | *                                  |
+  // | task             | barrier         | +                                  |
+  // | task             | taskwait        | *                                  |
+  // | task             | flush           | *                                  |
+  // +------------------+-----------------+------------------------------------+
+  if (Stack->getCurScope()) {
+    auto ParentRegion = Stack->getParentDirective();
+    bool NestingProhibited = false;
+    bool CloseNesting = true;
+    bool ShouldBeInParallelRegion = false;
+    if (isOpenMPSimdDirective(ParentRegion)) {
+      // OpenMP [2.16, Nesting of Regions]
+      // OpenMP constructs may not be nested inside a simd region.
+      SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_simd);
+      return true;
+    }
+    if (CurrentRegion == OMPD_section) {
+      // OpenMP [2.7.2, sections Construct, Restrictions]
+      // Orphaned section directives are prohibited. That is, the section
+      // directives must appear within the sections construct and must not be
+      // encountered elsewhere in the sections region.
+      if (ParentRegion != OMPD_sections &&
+          ParentRegion != OMPD_parallel_sections) {
+        SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
+            << (ParentRegion != OMPD_unknown)
+            << getOpenMPDirectiveName(ParentRegion);
+        return true;
+      }
+      return false;
+    }
+    if (CurrentRegion == OMPD_master) {
+      // OpenMP [2.16, Nesting of Regions]
+      // A master region may not be closely nested inside a worksharing,
+      // atomic (TODO), or explicit task region.
+      NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
+                          ParentRegion == OMPD_task;
+    } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
+      // OpenMP [2.16, Nesting of Regions]
+      // A critical region may not be nested (closely or otherwise) inside a
+      // critical region with the same name. Note that this restriction is not
+      // sufficient to prevent deadlock.
+      SourceLocation PreviousCriticalLoc;
+      bool DeadLock =
+          Stack->hasDirective([CurrentName, &PreviousCriticalLoc](
+                                  OpenMPDirectiveKind K,
+                                  const DeclarationNameInfo &DNI,
+                                  SourceLocation Loc)
+                                  ->bool {
+                                if (K == OMPD_critical &&
+                                    DNI.getName() == CurrentName.getName()) {
+                                  PreviousCriticalLoc = Loc;
+                                  return true;
+                                } else
+                                  return false;
+                              },
+                              false /* skip top directive */);
+      if (DeadLock) {
+        SemaRef.Diag(StartLoc,
+                     diag::err_omp_prohibited_region_critical_same_name)
+            << CurrentName.getName();
+        if (PreviousCriticalLoc.isValid())
+          SemaRef.Diag(PreviousCriticalLoc,
+                       diag::note_omp_previous_critical_region);
+        return true;
+      }
+    } else if (CurrentRegion == OMPD_barrier) {
+      // OpenMP [2.16, Nesting of Regions]
+      // A barrier region may not be closely nested inside a worksharing,
+      // explicit task, critical, ordered(TODO), atomic(TODO), or master
+      // region.
+      NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
+                          ParentRegion == OMPD_task ||
+                          ParentRegion == OMPD_master ||
+                          ParentRegion == OMPD_critical;
+    } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
+               !isOpenMPParallelDirective(CurrentRegion) &&
+               !isOpenMPSimdDirective(CurrentRegion)) {
+      // OpenMP [2.16, Nesting of Regions]
+      // A worksharing region may not be closely nested inside a worksharing,
+      // explicit task, critical, ordered, atomic, or master region.
+      // TODO
+      NestingProhibited = (isOpenMPWorksharingDirective(ParentRegion) &&
+                           !isOpenMPSimdDirective(ParentRegion)) ||
+                          ParentRegion == OMPD_task ||
+                          ParentRegion == OMPD_master ||
+                          ParentRegion == OMPD_critical;
+      ShouldBeInParallelRegion = true;
+    }
+    if (NestingProhibited) {
+      SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
+          << CloseNesting << getOpenMPDirectiveName(ParentRegion)
+          << ShouldBeInParallelRegion << getOpenMPDirectiveName(CurrentRegion);
+      return true;
+    }
+  }
+  return false;
 }
 
 StmtResult Sema::ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,
+                                                const DeclarationNameInfo &DirName,
                                                 ArrayRef<OMPClause *> Clauses,
                                                 Stmt *AStmt,
                                                 SourceLocation StartLoc,
                                                 SourceLocation EndLoc) {
-  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
-
   StmtResult Res = StmtError();
-
-  // Check default data sharing attributes for referenced variables.
-  DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
-  DSAChecker.Visit(cast<CapturedStmt>(AStmt)->getCapturedStmt());
-  if (DSAChecker.isErrorFound())
+  if (CheckNestingOfRegions(*this, DSAStack, Kind, DirName, StartLoc))
     return StmtError();
-  // Generate list of implicitly defined firstprivate variables.
-  llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
-  ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
 
+  llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
+  llvm::DenseMap<VarDecl *, Expr *> VarsWithInheritedDSA;
   bool ErrorFound = false;
-  if (!DSAChecker.getImplicitFirstprivate().empty()) {
-    if (OMPClause *Implicit =
-         ActOnOpenMPFirstprivateClause(DSAChecker.getImplicitFirstprivate(),
-                                       SourceLocation(), SourceLocation(),
-                                       SourceLocation())) {
-      ClausesWithImplicit.push_back(Implicit);
-      ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
-                                    DSAChecker.getImplicitFirstprivate().size();
-    } else
-      ErrorFound = true;
+  ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
+  if (AStmt) {
+    assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
+
+    // Check default data sharing attributes for referenced variables.
+    DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
+    DSAChecker.Visit(cast<CapturedStmt>(AStmt)->getCapturedStmt());
+    if (DSAChecker.isErrorFound())
+      return StmtError();
+    // Generate list of implicitly defined firstprivate variables.
+    VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
+
+    if (!DSAChecker.getImplicitFirstprivate().empty()) {
+      if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
+              DSAChecker.getImplicitFirstprivate(), SourceLocation(),
+              SourceLocation(), SourceLocation())) {
+        ClausesWithImplicit.push_back(Implicit);
+        ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
+                     DSAChecker.getImplicitFirstprivate().size();
+      } else
+        ErrorFound = true;
+    }
   }
 
   switch (Kind) {
   case OMPD_parallel:
-    Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt,
-                                       StartLoc, EndLoc);
+    Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
+                                       EndLoc);
+    break;
+  case OMPD_simd:
+    Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
+                                   VarsWithInheritedDSA);
+    break;
+  case OMPD_for:
+    Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
+                                  VarsWithInheritedDSA);
+    break;
+  case OMPD_sections:
+    Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
+                                       EndLoc);
+    break;
+  case OMPD_section:
+    assert(ClausesWithImplicit.empty() &&
+           "No clauses are allowed for 'omp section' directive");
+    Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
+    break;
+  case OMPD_single:
+    Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
+                                     EndLoc);
+    break;
+  case OMPD_master:
+    assert(ClausesWithImplicit.empty() &&
+           "No clauses are allowed for 'omp master' directive");
+    Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
+    break;
+  case OMPD_critical:
+    assert(ClausesWithImplicit.empty() &&
+           "No clauses are allowed for 'omp critical' directive");
+    Res = ActOnOpenMPCriticalDirective(DirName, AStmt, StartLoc, EndLoc);
+    break;
+  case OMPD_parallel_for:
+    Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
+                                          EndLoc, VarsWithInheritedDSA);
+    break;
+  case OMPD_parallel_sections:
+    Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
+                                               StartLoc, EndLoc);
+    break;
+  case OMPD_task:
+    Res =
+        ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
+    break;
+  case OMPD_taskyield:
+    assert(ClausesWithImplicit.empty() &&
+           "No clauses are allowed for 'omp taskyield' directive");
+    assert(AStmt == nullptr &&
+           "No associated statement allowed for 'omp taskyield' directive");
+    Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
+    break;
+  case OMPD_barrier:
+    assert(ClausesWithImplicit.empty() &&
+           "No clauses are allowed for 'omp barrier' directive");
+    assert(AStmt == nullptr &&
+           "No associated statement allowed for 'omp barrier' directive");
+    Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
+    break;
+  case OMPD_taskwait:
+    assert(ClausesWithImplicit.empty() &&
+           "No clauses are allowed for 'omp taskwait' directive");
+    assert(AStmt == nullptr &&
+           "No associated statement allowed for 'omp taskwait' directive");
+    Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
+    break;
+  case OMPD_flush:
+    assert(AStmt == nullptr &&
+           "No associated statement allowed for 'omp flush' directive");
+    Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
     break;
   case OMPD_threadprivate:
-  case OMPD_task:
     llvm_unreachable("OpenMP Directive is not allowed");
   case OMPD_unknown:
-  case NUM_OPENMP_DIRECTIVES:
     llvm_unreachable("Unknown OpenMP directive");
   }
 
-  if (ErrorFound) return StmtError();
+  for (auto P : VarsWithInheritedDSA) {
+    Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
+        << P.first << P.second->getSourceRange();
+  }
+  if (!VarsWithInheritedDSA.empty())
+    return StmtError();
+
+  if (ErrorFound)
+    return StmtError();
   return Res;
 }
 
@@ -696,31 +1509,1004 @@
                                               Stmt *AStmt,
                                               SourceLocation StartLoc,
                                               SourceLocation EndLoc) {
+  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
+  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
+  // 1.2.2 OpenMP Language Terminology
+  // Structured block - An executable statement with a single entry at the
+  // top and a single exit at the bottom.
+  // The point of exit cannot be a branch out of the structured block.
+  // longjmp() and throw() must not violate the entry/exit criteria.
+  CS->getCapturedDecl()->setNothrow();
+
   getCurFunction()->setHasBranchProtectedScope();
 
-  return Owned(OMPParallelDirective::Create(Context, StartLoc, EndLoc,
-                                            Clauses, AStmt));
+  return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses,
+                                      AStmt);
 }
 
-OMPClause *Sema::ActOnOpenMPSimpleClause(OpenMPClauseKind Kind,
-                                         unsigned Argument,
-                                         SourceLocation ArgumentLoc,
-                                         SourceLocation StartLoc,
-                                         SourceLocation LParenLoc,
-                                         SourceLocation EndLoc) {
-  OMPClause *Res = 0;
+namespace {
+/// \brief Helper class for checking canonical form of the OpenMP loops and
+/// extracting iteration space of each loop in the loop nest, that will be used
+/// for IR generation.
+class OpenMPIterationSpaceChecker {
+  /// \brief Reference to Sema.
+  Sema &SemaRef;
+  /// \brief A location for diagnostics (when there is no some better location).
+  SourceLocation DefaultLoc;
+  /// \brief A location for diagnostics (when increment is not compatible).
+  SourceLocation ConditionLoc;
+  /// \brief A source location for referring to condition later.
+  SourceRange ConditionSrcRange;
+  /// \brief Loop variable.
+  VarDecl *Var;
+  /// \brief Lower bound (initializer for the var).
+  Expr *LB;
+  /// \brief Upper bound.
+  Expr *UB;
+  /// \brief Loop step (increment).
+  Expr *Step;
+  /// \brief This flag is true when condition is one of:
+  ///   Var <  UB
+  ///   Var <= UB
+  ///   UB  >  Var
+  ///   UB  >= Var
+  bool TestIsLessOp;
+  /// \brief This flag is true when condition is strict ( < or > ).
+  bool TestIsStrictOp;
+  /// \brief This flag is true when step is subtracted on each iteration.
+  bool SubtractStep;
+
+public:
+  OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc)
+      : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc),
+        ConditionSrcRange(SourceRange()), Var(nullptr), LB(nullptr),
+        UB(nullptr), Step(nullptr), TestIsLessOp(false), TestIsStrictOp(false),
+        SubtractStep(false) {}
+  /// \brief Check init-expr for canonical loop form and save loop counter
+  /// variable - #Var and its initialization value - #LB.
+  bool CheckInit(Stmt *S);
+  /// \brief Check test-expr for canonical form, save upper-bound (#UB), flags
+  /// for less/greater and for strict/non-strict comparison.
+  bool CheckCond(Expr *S);
+  /// \brief Check incr-expr for canonical loop form and return true if it
+  /// does not conform, otherwise save loop step (#Step).
+  bool CheckInc(Expr *S);
+  /// \brief Return the loop counter variable.
+  VarDecl *GetLoopVar() const { return Var; }
+  /// \brief Return true if any expression is dependent.
+  bool Dependent() const;
+
+private:
+  /// \brief Check the right-hand side of an assignment in the increment
+  /// expression.
+  bool CheckIncRHS(Expr *RHS);
+  /// \brief Helper to set loop counter variable and its initializer.
+  bool SetVarAndLB(VarDecl *NewVar, Expr *NewLB);
+  /// \brief Helper to set upper bound.
+  bool SetUB(Expr *NewUB, bool LessOp, bool StrictOp, const SourceRange &SR,
+             const SourceLocation &SL);
+  /// \brief Helper to set loop increment.
+  bool SetStep(Expr *NewStep, bool Subtract);
+};
+
+bool OpenMPIterationSpaceChecker::Dependent() const {
+  if (!Var) {
+    assert(!LB && !UB && !Step);
+    return false;
+  }
+  return Var->getType()->isDependentType() || (LB && LB->isValueDependent()) ||
+         (UB && UB->isValueDependent()) || (Step && Step->isValueDependent());
+}
+
+bool OpenMPIterationSpaceChecker::SetVarAndLB(VarDecl *NewVar, Expr *NewLB) {
+  // State consistency checking to ensure correct usage.
+  assert(Var == nullptr && LB == nullptr && UB == nullptr && Step == nullptr &&
+         !TestIsLessOp && !TestIsStrictOp);
+  if (!NewVar || !NewLB)
+    return true;
+  Var = NewVar;
+  LB = NewLB;
+  return false;
+}
+
+bool OpenMPIterationSpaceChecker::SetUB(Expr *NewUB, bool LessOp, bool StrictOp,
+                                        const SourceRange &SR,
+                                        const SourceLocation &SL) {
+  // State consistency checking to ensure correct usage.
+  assert(Var != nullptr && LB != nullptr && UB == nullptr && Step == nullptr &&
+         !TestIsLessOp && !TestIsStrictOp);
+  if (!NewUB)
+    return true;
+  UB = NewUB;
+  TestIsLessOp = LessOp;
+  TestIsStrictOp = StrictOp;
+  ConditionSrcRange = SR;
+  ConditionLoc = SL;
+  return false;
+}
+
+bool OpenMPIterationSpaceChecker::SetStep(Expr *NewStep, bool Subtract) {
+  // State consistency checking to ensure correct usage.
+  assert(Var != nullptr && LB != nullptr && Step == nullptr);
+  if (!NewStep)
+    return true;
+  if (!NewStep->isValueDependent()) {
+    // Check that the step is integer expression.
+    SourceLocation StepLoc = NewStep->getLocStart();
+    ExprResult Val =
+        SemaRef.PerformOpenMPImplicitIntegerConversion(StepLoc, NewStep);
+    if (Val.isInvalid())
+      return true;
+    NewStep = Val.get();
+
+    // OpenMP [2.6, Canonical Loop Form, Restrictions]
+    //  If test-expr is of form var relational-op b and relational-op is < or
+    //  <= then incr-expr must cause var to increase on each iteration of the
+    //  loop. If test-expr is of form var relational-op b and relational-op is
+    //  > or >= then incr-expr must cause var to decrease on each iteration of
+    //  the loop.
+    //  If test-expr is of form b relational-op var and relational-op is < or
+    //  <= then incr-expr must cause var to decrease on each iteration of the
+    //  loop. If test-expr is of form b relational-op var and relational-op is
+    //  > or >= then incr-expr must cause var to increase on each iteration of
+    //  the loop.
+    llvm::APSInt Result;
+    bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context);
+    bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
+    bool IsConstNeg =
+        IsConstant && Result.isSigned() && (Subtract != Result.isNegative());
+    bool IsConstZero = IsConstant && !Result.getBoolValue();
+    if (UB && (IsConstZero ||
+               (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract))
+                             : (!IsConstNeg || (IsUnsigned && !Subtract))))) {
+      SemaRef.Diag(NewStep->getExprLoc(),
+                   diag::err_omp_loop_incr_not_compatible)
+          << Var << TestIsLessOp << NewStep->getSourceRange();
+      SemaRef.Diag(ConditionLoc,
+                   diag::note_omp_loop_cond_requres_compatible_incr)
+          << TestIsLessOp << ConditionSrcRange;
+      return true;
+    }
+  }
+
+  Step = NewStep;
+  SubtractStep = Subtract;
+  return false;
+}
+
+bool OpenMPIterationSpaceChecker::CheckInit(Stmt *S) {
+  // Check init-expr for canonical loop form and save loop counter
+  // variable - #Var and its initialization value - #LB.
+  // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
+  //   var = lb
+  //   integer-type var = lb
+  //   random-access-iterator-type var = lb
+  //   pointer-type var = lb
+  //
+  if (!S) {
+    SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
+    return true;
+  }
+  if (Expr *E = dyn_cast<Expr>(S))
+    S = E->IgnoreParens();
+  if (auto BO = dyn_cast<BinaryOperator>(S)) {
+    if (BO->getOpcode() == BO_Assign)
+      if (auto DRE = dyn_cast<DeclRefExpr>(BO->getLHS()->IgnoreParens()))
+        return SetVarAndLB(dyn_cast<VarDecl>(DRE->getDecl()), BO->getLHS());
+  } else if (auto DS = dyn_cast<DeclStmt>(S)) {
+    if (DS->isSingleDecl()) {
+      if (auto Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
+        if (Var->hasInit()) {
+          // Accept non-canonical init form here but emit ext. warning.
+          if (Var->getInitStyle() != VarDecl::CInit)
+            SemaRef.Diag(S->getLocStart(),
+                         diag::ext_omp_loop_not_canonical_init)
+                << S->getSourceRange();
+          return SetVarAndLB(Var, Var->getInit());
+        }
+      }
+    }
+  } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S))
+    if (CE->getOperator() == OO_Equal)
+      if (auto DRE = dyn_cast<DeclRefExpr>(CE->getArg(0)))
+        return SetVarAndLB(dyn_cast<VarDecl>(DRE->getDecl()), CE->getArg(1));
+
+  SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_init)
+      << S->getSourceRange();
+  return true;
+}
+
+/// \brief Ignore parenthesizes, implicit casts, copy constructor and return the
+/// variable (which may be the loop variable) if possible.
+static const VarDecl *GetInitVarDecl(const Expr *E) {
+  if (!E)
+    return nullptr;
+  E = E->IgnoreParenImpCasts();
+  if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
+    if (const CXXConstructorDecl *Ctor = CE->getConstructor())
+      if (Ctor->isCopyConstructor() && CE->getNumArgs() == 1 &&
+          CE->getArg(0) != nullptr)
+        E = CE->getArg(0)->IgnoreParenImpCasts();
+  auto DRE = dyn_cast_or_null<DeclRefExpr>(E);
+  if (!DRE)
+    return nullptr;
+  return dyn_cast<VarDecl>(DRE->getDecl());
+}
+
+bool OpenMPIterationSpaceChecker::CheckCond(Expr *S) {
+  // Check test-expr for canonical form, save upper-bound UB, flags for
+  // less/greater and for strict/non-strict comparison.
+  // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
+  //   var relational-op b
+  //   b relational-op var
+  //
+  if (!S) {
+    SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << Var;
+    return true;
+  }
+  S = S->IgnoreParenImpCasts();
+  SourceLocation CondLoc = S->getLocStart();
+  if (auto BO = dyn_cast<BinaryOperator>(S)) {
+    if (BO->isRelationalOp()) {
+      if (GetInitVarDecl(BO->getLHS()) == Var)
+        return SetUB(BO->getRHS(),
+                     (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
+                     (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
+                     BO->getSourceRange(), BO->getOperatorLoc());
+      if (GetInitVarDecl(BO->getRHS()) == Var)
+        return SetUB(BO->getLHS(),
+                     (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
+                     (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
+                     BO->getSourceRange(), BO->getOperatorLoc());
+    }
+  } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) {
+    if (CE->getNumArgs() == 2) {
+      auto Op = CE->getOperator();
+      switch (Op) {
+      case OO_Greater:
+      case OO_GreaterEqual:
+      case OO_Less:
+      case OO_LessEqual:
+        if (GetInitVarDecl(CE->getArg(0)) == Var)
+          return SetUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
+                       Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
+                       CE->getOperatorLoc());
+        if (GetInitVarDecl(CE->getArg(1)) == Var)
+          return SetUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
+                       Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
+                       CE->getOperatorLoc());
+        break;
+      default:
+        break;
+      }
+    }
+  }
+  SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
+      << S->getSourceRange() << Var;
+  return true;
+}
+
+bool OpenMPIterationSpaceChecker::CheckIncRHS(Expr *RHS) {
+  // RHS of canonical loop form increment can be:
+  //   var + incr
+  //   incr + var
+  //   var - incr
+  //
+  RHS = RHS->IgnoreParenImpCasts();
+  if (auto BO = dyn_cast<BinaryOperator>(RHS)) {
+    if (BO->isAdditiveOp()) {
+      bool IsAdd = BO->getOpcode() == BO_Add;
+      if (GetInitVarDecl(BO->getLHS()) == Var)
+        return SetStep(BO->getRHS(), !IsAdd);
+      if (IsAdd && GetInitVarDecl(BO->getRHS()) == Var)
+        return SetStep(BO->getLHS(), false);
+    }
+  } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
+    bool IsAdd = CE->getOperator() == OO_Plus;
+    if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
+      if (GetInitVarDecl(CE->getArg(0)) == Var)
+        return SetStep(CE->getArg(1), !IsAdd);
+      if (IsAdd && GetInitVarDecl(CE->getArg(1)) == Var)
+        return SetStep(CE->getArg(0), false);
+    }
+  }
+  SemaRef.Diag(RHS->getLocStart(), diag::err_omp_loop_not_canonical_incr)
+      << RHS->getSourceRange() << Var;
+  return true;
+}
+
+bool OpenMPIterationSpaceChecker::CheckInc(Expr *S) {
+  // Check incr-expr for canonical loop form and return true if it
+  // does not conform.
+  // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
+  //   ++var
+  //   var++
+  //   --var
+  //   var--
+  //   var += incr
+  //   var -= incr
+  //   var = var + incr
+  //   var = incr + var
+  //   var = var - incr
+  //
+  if (!S) {
+    SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << Var;
+    return true;
+  }
+  S = S->IgnoreParens();
+  if (auto UO = dyn_cast<UnaryOperator>(S)) {
+    if (UO->isIncrementDecrementOp() && GetInitVarDecl(UO->getSubExpr()) == Var)
+      return SetStep(
+          SemaRef.ActOnIntegerConstant(UO->getLocStart(),
+                                       (UO->isDecrementOp() ? -1 : 1)).get(),
+          false);
+  } else if (auto BO = dyn_cast<BinaryOperator>(S)) {
+    switch (BO->getOpcode()) {
+    case BO_AddAssign:
+    case BO_SubAssign:
+      if (GetInitVarDecl(BO->getLHS()) == Var)
+        return SetStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
+      break;
+    case BO_Assign:
+      if (GetInitVarDecl(BO->getLHS()) == Var)
+        return CheckIncRHS(BO->getRHS());
+      break;
+    default:
+      break;
+    }
+  } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) {
+    switch (CE->getOperator()) {
+    case OO_PlusPlus:
+    case OO_MinusMinus:
+      if (GetInitVarDecl(CE->getArg(0)) == Var)
+        return SetStep(
+            SemaRef.ActOnIntegerConstant(
+                        CE->getLocStart(),
+                        ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)).get(),
+            false);
+      break;
+    case OO_PlusEqual:
+    case OO_MinusEqual:
+      if (GetInitVarDecl(CE->getArg(0)) == Var)
+        return SetStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
+      break;
+    case OO_Equal:
+      if (GetInitVarDecl(CE->getArg(0)) == Var)
+        return CheckIncRHS(CE->getArg(1));
+      break;
+    default:
+      break;
+    }
+  }
+  SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_incr)
+      << S->getSourceRange() << Var;
+  return true;
+}
+} // namespace
+
+/// \brief Called on a for stmt to check and extract its iteration space
+/// for further processing (such as collapsing).
+static bool CheckOpenMPIterationSpace(
+    OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
+    unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
+    Expr *NestedLoopCountExpr,
+    llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
+  // OpenMP [2.6, Canonical Loop Form]
+  //   for (init-expr; test-expr; incr-expr) structured-block
+  auto For = dyn_cast_or_null<ForStmt>(S);
+  if (!For) {
+    SemaRef.Diag(S->getLocStart(), diag::err_omp_not_for)
+        << (NestedLoopCountExpr != nullptr) << getOpenMPDirectiveName(DKind)
+        << NestedLoopCount << (CurrentNestedLoopCount > 0)
+        << CurrentNestedLoopCount;
+    if (NestedLoopCount > 1)
+      SemaRef.Diag(NestedLoopCountExpr->getExprLoc(),
+                   diag::note_omp_collapse_expr)
+          << NestedLoopCountExpr->getSourceRange();
+    return true;
+  }
+  assert(For->getBody());
+
+  OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc());
+
+  // Check init.
+  auto Init = For->getInit();
+  if (ISC.CheckInit(Init)) {
+    return true;
+  }
+
+  bool HasErrors = false;
+
+  // Check loop variable's type.
+  auto Var = ISC.GetLoopVar();
+
+  // OpenMP [2.6, Canonical Loop Form]
+  // Var is one of the following:
+  //   A variable of signed or unsigned integer type.
+  //   For C++, a variable of a random access iterator type.
+  //   For C, a variable of a pointer type.
+  auto VarType = Var->getType();
+  if (!VarType->isDependentType() && !VarType->isIntegerType() &&
+      !VarType->isPointerType() &&
+      !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
+    SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_variable_type)
+        << SemaRef.getLangOpts().CPlusPlus;
+    HasErrors = true;
+  }
+
+  // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in a
+  // Construct
+  // The loop iteration variable(s) in the associated for-loop(s) of a for or
+  // parallel for construct is (are) private.
+  // The loop iteration variable in the associated for-loop of a simd construct
+  // with just one associated for-loop is linear with a constant-linear-step
+  // that is the increment of the associated for-loop.
+  // Exclude loop var from the list of variables with implicitly defined data
+  // sharing attributes.
+  while (VarsWithImplicitDSA.count(Var) > 0)
+    VarsWithImplicitDSA.erase(Var);
+
+  // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced in
+  // a Construct, C/C++].
+  // The loop iteration variable in the associated for-loop of a simd construct
+  // with just one associated for-loop may be listed in a linear clause with a
+  // constant-linear-step that is the increment of the associated for-loop.
+  // The loop iteration variable(s) in the associated for-loop(s) of a for or
+  // parallel for construct may be listed in a private or lastprivate clause.
+  DSAStackTy::DSAVarData DVar = DSA.getTopDSA(Var, false);
+  auto PredeterminedCKind =
+      isOpenMPSimdDirective(DKind)
+          ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate)
+          : OMPC_private;
+  if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
+        DVar.CKind != PredeterminedCKind) ||
+       (isOpenMPWorksharingDirective(DKind) && DVar.CKind != OMPC_unknown &&
+        DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
+      (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
+    SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa)
+        << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind)
+        << getOpenMPClauseName(PredeterminedCKind);
+    ReportOriginalDSA(SemaRef, &DSA, Var, DVar, true);
+    HasErrors = true;
+  } else {
+    // Make the loop iteration variable private (for worksharing constructs),
+    // linear (for simd directives with the only one associated loop) or
+    // lastprivate (for simd directives with several collapsed loops).
+    DSA.addDSA(Var, nullptr, PredeterminedCKind);
+  }
+
+  assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
+
+  // Check test-expr.
+  HasErrors |= ISC.CheckCond(For->getCond());
+
+  // Check incr-expr.
+  HasErrors |= ISC.CheckInc(For->getInc());
+
+  if (ISC.Dependent())
+    return HasErrors;
+
+  // FIXME: Build loop's iteration space representation.
+  return HasErrors;
+}
+
+/// \brief A helper routine to skip no-op (attributed, compound) stmts get the
+/// next nested for loop. If \a IgnoreCaptured is true, it skips captured stmt
+/// to get the first for loop.
+static Stmt *IgnoreContainerStmts(Stmt *S, bool IgnoreCaptured) {
+  if (IgnoreCaptured)
+    if (auto CapS = dyn_cast_or_null<CapturedStmt>(S))
+      S = CapS->getCapturedStmt();
+  // OpenMP [2.8.1, simd construct, Restrictions]
+  // All loops associated with the construct must be perfectly nested; that is,
+  // there must be no intervening code nor any OpenMP directive between any two
+  // loops.
+  while (true) {
+    if (auto AS = dyn_cast_or_null<AttributedStmt>(S))
+      S = AS->getSubStmt();
+    else if (auto CS = dyn_cast_or_null<CompoundStmt>(S)) {
+      if (CS->size() != 1)
+        break;
+      S = CS->body_back();
+    } else
+      break;
+  }
+  return S;
+}
+
+/// \brief Called on a for stmt to check itself and nested loops (if any).
+/// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
+/// number of collapsed loops otherwise.
+static unsigned
+CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *NestedLoopCountExpr,
+                Stmt *AStmt, Sema &SemaRef, DSAStackTy &DSA,
+                llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
+  unsigned NestedLoopCount = 1;
+  if (NestedLoopCountExpr) {
+    // Found 'collapse' clause - calculate collapse number.
+    llvm::APSInt Result;
+    if (NestedLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext()))
+      NestedLoopCount = Result.getLimitedValue();
+  }
+  // This is helper routine for loop directives (e.g., 'for', 'simd',
+  // 'for simd', etc.).
+  Stmt *CurStmt = IgnoreContainerStmts(AStmt, true);
+  for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
+    if (CheckOpenMPIterationSpace(DKind, CurStmt, SemaRef, DSA, Cnt,
+                                  NestedLoopCount, NestedLoopCountExpr,
+                                  VarsWithImplicitDSA))
+      return 0;
+    // Move on to the next nested for loop, or to the loop body.
+    CurStmt = IgnoreContainerStmts(cast<ForStmt>(CurStmt)->getBody(), false);
+  }
+
+  // FIXME: Build resulting iteration space for IR generation (collapsing
+  // iteration spaces when loop count > 1 ('collapse' clause)).
+  return NestedLoopCount;
+}
+
+static Expr *GetCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
+  auto CollapseFilter = [](const OMPClause *C) -> bool {
+    return C->getClauseKind() == OMPC_collapse;
+  };
+  OMPExecutableDirective::filtered_clause_iterator<decltype(CollapseFilter)> I(
+      Clauses, CollapseFilter);
+  if (I)
+    return cast<OMPCollapseClause>(*I)->getNumForLoops();
+  return nullptr;
+}
+
+StmtResult Sema::ActOnOpenMPSimdDirective(
+    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+    SourceLocation EndLoc,
+    llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
+  // In presence of clause 'collapse', it will define the nested loops number.
+  unsigned NestedLoopCount =
+      CheckOpenMPLoop(OMPD_simd, GetCollapseNumberExpr(Clauses), AStmt, *this,
+                      *DSAStack, VarsWithImplicitDSA);
+  if (NestedLoopCount == 0)
+    return StmtError();
+
+  getCurFunction()->setHasBranchProtectedScope();
+  return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
+                                  Clauses, AStmt);
+}
+
+StmtResult Sema::ActOnOpenMPForDirective(
+    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+    SourceLocation EndLoc,
+    llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
+  // In presence of clause 'collapse', it will define the nested loops number.
+  unsigned NestedLoopCount =
+      CheckOpenMPLoop(OMPD_for, GetCollapseNumberExpr(Clauses), AStmt, *this,
+                      *DSAStack, VarsWithImplicitDSA);
+  if (NestedLoopCount == 0)
+    return StmtError();
+
+  getCurFunction()->setHasBranchProtectedScope();
+  return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
+                                 Clauses, AStmt);
+}
+
+StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
+                                              Stmt *AStmt,
+                                              SourceLocation StartLoc,
+                                              SourceLocation EndLoc) {
+  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
+  auto BaseStmt = AStmt;
+  while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
+    BaseStmt = CS->getCapturedStmt();
+  if (auto C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
+    auto S = C->children();
+    if (!S)
+      return StmtError();
+    // All associated statements must be '#pragma omp section' except for
+    // the first one.
+    for (++S; S; ++S) {
+      auto SectionStmt = *S;
+      if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
+        if (SectionStmt)
+          Diag(SectionStmt->getLocStart(),
+               diag::err_omp_sections_substmt_not_section);
+        return StmtError();
+      }
+    }
+  } else {
+    Diag(AStmt->getLocStart(), diag::err_omp_sections_not_compound_stmt);
+    return StmtError();
+  }
+
+  getCurFunction()->setHasBranchProtectedScope();
+
+  return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses,
+                                      AStmt);
+}
+
+StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
+                                             SourceLocation StartLoc,
+                                             SourceLocation EndLoc) {
+  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
+
+  getCurFunction()->setHasBranchProtectedScope();
+
+  return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt);
+}
+
+StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
+                                            Stmt *AStmt,
+                                            SourceLocation StartLoc,
+                                            SourceLocation EndLoc) {
+  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
+
+  getCurFunction()->setHasBranchProtectedScope();
+
+  return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
+}
+
+StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
+                                            SourceLocation StartLoc,
+                                            SourceLocation EndLoc) {
+  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
+
+  getCurFunction()->setHasBranchProtectedScope();
+
+  return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
+}
+
+StmtResult
+Sema::ActOnOpenMPCriticalDirective(const DeclarationNameInfo &DirName,
+                                   Stmt *AStmt, SourceLocation StartLoc,
+                                   SourceLocation EndLoc) {
+  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
+
+  getCurFunction()->setHasBranchProtectedScope();
+
+  return OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
+                                      AStmt);
+}
+
+StmtResult Sema::ActOnOpenMPParallelForDirective(
+    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+    SourceLocation EndLoc,
+    llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
+  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
+  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
+  // 1.2.2 OpenMP Language Terminology
+  // Structured block - An executable statement with a single entry at the
+  // top and a single exit at the bottom.
+  // The point of exit cannot be a branch out of the structured block.
+  // longjmp() and throw() must not violate the entry/exit criteria.
+  CS->getCapturedDecl()->setNothrow();
+
+  // In presence of clause 'collapse', it will define the nested loops number.
+  unsigned NestedLoopCount =
+      CheckOpenMPLoop(OMPD_parallel_for, GetCollapseNumberExpr(Clauses), AStmt,
+                      *this, *DSAStack, VarsWithImplicitDSA);
+  if (NestedLoopCount == 0)
+    return StmtError();
+
+  getCurFunction()->setHasBranchProtectedScope();
+  return OMPParallelForDirective::Create(Context, StartLoc, EndLoc,
+                                         NestedLoopCount, Clauses, AStmt);
+}
+
+StmtResult
+Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
+                                           Stmt *AStmt, SourceLocation StartLoc,
+                                           SourceLocation EndLoc) {
+  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
+  auto BaseStmt = AStmt;
+  while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
+    BaseStmt = CS->getCapturedStmt();
+  if (auto C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
+    auto S = C->children();
+    if (!S)
+      return StmtError();
+    // All associated statements must be '#pragma omp section' except for
+    // the first one.
+    for (++S; S; ++S) {
+      auto SectionStmt = *S;
+      if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
+        if (SectionStmt)
+          Diag(SectionStmt->getLocStart(),
+               diag::err_omp_parallel_sections_substmt_not_section);
+        return StmtError();
+      }
+    }
+  } else {
+    Diag(AStmt->getLocStart(),
+         diag::err_omp_parallel_sections_not_compound_stmt);
+    return StmtError();
+  }
+
+  getCurFunction()->setHasBranchProtectedScope();
+
+  return OMPParallelSectionsDirective::Create(Context, StartLoc, EndLoc,
+                                              Clauses, AStmt);
+}
+
+StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
+                                          Stmt *AStmt, SourceLocation StartLoc,
+                                          SourceLocation EndLoc) {
+  assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
+  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
+  // 1.2.2 OpenMP Language Terminology
+  // Structured block - An executable statement with a single entry at the
+  // top and a single exit at the bottom.
+  // The point of exit cannot be a branch out of the structured block.
+  // longjmp() and throw() must not violate the entry/exit criteria.
+  CS->getCapturedDecl()->setNothrow();
+
+  getCurFunction()->setHasBranchProtectedScope();
+
+  return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
+}
+
+StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
+                                               SourceLocation EndLoc) {
+  return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
+}
+
+StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
+                                             SourceLocation EndLoc) {
+  return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
+}
+
+StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
+                                              SourceLocation EndLoc) {
+  return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
+}
+
+StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
+                                           SourceLocation StartLoc,
+                                           SourceLocation EndLoc) {
+  assert(Clauses.size() <= 1 && "Extra clauses in flush directive");
+  return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
+}
+
+OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
+                                             SourceLocation StartLoc,
+                                             SourceLocation LParenLoc,
+                                             SourceLocation EndLoc) {
+  OMPClause *Res = nullptr;
+  switch (Kind) {
+  case OMPC_if:
+    Res = ActOnOpenMPIfClause(Expr, StartLoc, LParenLoc, EndLoc);
+    break;
+  case OMPC_final:
+    Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
+    break;
+  case OMPC_num_threads:
+    Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
+    break;
+  case OMPC_safelen:
+    Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
+    break;
+  case OMPC_collapse:
+    Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
+    break;
+  case OMPC_default:
+  case OMPC_proc_bind:
+  case OMPC_schedule:
+  case OMPC_private:
+  case OMPC_firstprivate:
+  case OMPC_lastprivate:
+  case OMPC_shared:
+  case OMPC_reduction:
+  case OMPC_linear:
+  case OMPC_aligned:
+  case OMPC_copyin:
+  case OMPC_copyprivate:
+  case OMPC_ordered:
+  case OMPC_nowait:
+  case OMPC_untied:
+  case OMPC_mergeable:
+  case OMPC_threadprivate:
+  case OMPC_flush:
+  case OMPC_unknown:
+    llvm_unreachable("Clause is not allowed.");
+  }
+  return Res;
+}
+
+OMPClause *Sema::ActOnOpenMPIfClause(Expr *Condition, SourceLocation StartLoc,
+                                     SourceLocation LParenLoc,
+                                     SourceLocation EndLoc) {
+  Expr *ValExpr = Condition;
+  if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
+      !Condition->isInstantiationDependent() &&
+      !Condition->containsUnexpandedParameterPack()) {
+    ExprResult Val = ActOnBooleanCondition(DSAStack->getCurScope(),
+                                           Condition->getExprLoc(), Condition);
+    if (Val.isInvalid())
+      return nullptr;
+
+    ValExpr = Val.get();
+  }
+
+  return new (Context) OMPIfClause(ValExpr, StartLoc, LParenLoc, EndLoc);
+}
+
+OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
+                                        SourceLocation StartLoc,
+                                        SourceLocation LParenLoc,
+                                        SourceLocation EndLoc) {
+  Expr *ValExpr = Condition;
+  if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
+      !Condition->isInstantiationDependent() &&
+      !Condition->containsUnexpandedParameterPack()) {
+    ExprResult Val = ActOnBooleanCondition(DSAStack->getCurScope(),
+                                           Condition->getExprLoc(), Condition);
+    if (Val.isInvalid())
+      return nullptr;
+
+    ValExpr = Val.get();
+  }
+
+  return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc);
+}
+
+ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
+                                                        Expr *Op) {
+  if (!Op)
+    return ExprError();
+
+  class IntConvertDiagnoser : public ICEConvertDiagnoser {
+  public:
+    IntConvertDiagnoser()
+        : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
+    SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
+                                         QualType T) override {
+      return S.Diag(Loc, diag::err_omp_not_integral) << T;
+    }
+    SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
+                                             QualType T) override {
+      return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
+    }
+    SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
+                                               QualType T,
+                                               QualType ConvTy) override {
+      return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
+    }
+    SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
+                                           QualType ConvTy) override {
+      return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
+             << ConvTy->isEnumeralType() << ConvTy;
+    }
+    SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
+                                            QualType T) override {
+      return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
+    }
+    SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
+                                        QualType ConvTy) override {
+      return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
+             << ConvTy->isEnumeralType() << ConvTy;
+    }
+    SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
+                                             QualType) override {
+      llvm_unreachable("conversion functions are permitted");
+    }
+  } ConvertDiagnoser;
+  return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
+}
+
+OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
+                                             SourceLocation StartLoc,
+                                             SourceLocation LParenLoc,
+                                             SourceLocation EndLoc) {
+  Expr *ValExpr = NumThreads;
+  if (!NumThreads->isValueDependent() && !NumThreads->isTypeDependent() &&
+      !NumThreads->isInstantiationDependent() &&
+      !NumThreads->containsUnexpandedParameterPack()) {
+    SourceLocation NumThreadsLoc = NumThreads->getLocStart();
+    ExprResult Val =
+        PerformOpenMPImplicitIntegerConversion(NumThreadsLoc, NumThreads);
+    if (Val.isInvalid())
+      return nullptr;
+
+    ValExpr = Val.get();
+
+    // OpenMP [2.5, Restrictions]
+    //  The num_threads expression must evaluate to a positive integer value.
+    llvm::APSInt Result;
+    if (ValExpr->isIntegerConstantExpr(Result, Context) && Result.isSigned() &&
+        !Result.isStrictlyPositive()) {
+      Diag(NumThreadsLoc, diag::err_omp_negative_expression_in_clause)
+          << "num_threads" << NumThreads->getSourceRange();
+      return nullptr;
+    }
+  }
+
+  return new (Context)
+      OMPNumThreadsClause(ValExpr, StartLoc, LParenLoc, EndLoc);
+}
+
+ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
+                                                       OpenMPClauseKind CKind) {
+  if (!E)
+    return ExprError();
+  if (E->isValueDependent() || E->isTypeDependent() ||
+      E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
+    return E;
+  llvm::APSInt Result;
+  ExprResult ICE = VerifyIntegerConstantExpression(E, &Result);
+  if (ICE.isInvalid())
+    return ExprError();
+  if (!Result.isStrictlyPositive()) {
+    Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
+        << getOpenMPClauseName(CKind) << E->getSourceRange();
+    return ExprError();
+  }
+  return ICE;
+}
+
+OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc,
+                                          SourceLocation LParenLoc,
+                                          SourceLocation EndLoc) {
+  // OpenMP [2.8.1, simd construct, Description]
+  // The parameter of the safelen clause must be a constant
+  // positive integer expression.
+  ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
+  if (Safelen.isInvalid())
+    return nullptr;
+  return new (Context)
+      OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
+}
+
+OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
+                                           SourceLocation StartLoc,
+                                           SourceLocation LParenLoc,
+                                           SourceLocation EndLoc) {
+  // OpenMP [2.7.1, loop construct, Description]
+  // OpenMP [2.8.1, simd construct, Description]
+  // OpenMP [2.9.6, distribute construct, Description]
+  // The parameter of the collapse clause must be a constant
+  // positive integer expression.
+  ExprResult NumForLoopsResult =
+      VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
+  if (NumForLoopsResult.isInvalid())
+    return nullptr;
+  return new (Context)
+      OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
+}
+
+OMPClause *Sema::ActOnOpenMPSimpleClause(
+    OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
+    SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
+  OMPClause *Res = nullptr;
   switch (Kind) {
   case OMPC_default:
     Res =
-      ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument),
-                               ArgumentLoc, StartLoc, LParenLoc, EndLoc);
+        ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument),
+                                 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
     break;
+  case OMPC_proc_bind:
+    Res = ActOnOpenMPProcBindClause(
+        static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc,
+        LParenLoc, EndLoc);
+    break;
+  case OMPC_if:
+  case OMPC_final:
+  case OMPC_num_threads:
+  case OMPC_safelen:
+  case OMPC_collapse:
+  case OMPC_schedule:
   case OMPC_private:
   case OMPC_firstprivate:
+  case OMPC_lastprivate:
   case OMPC_shared:
+  case OMPC_reduction:
+  case OMPC_linear:
+  case OMPC_aligned:
+  case OMPC_copyin:
+  case OMPC_copyprivate:
+  case OMPC_ordered:
+  case OMPC_nowait:
+  case OMPC_untied:
+  case OMPC_mergeable:
   case OMPC_threadprivate:
+  case OMPC_flush:
   case OMPC_unknown:
-  case NUM_OPENMP_CLAUSES:
     llvm_unreachable("Clause is not allowed.");
   }
   return Res;
@@ -733,17 +2519,18 @@
                                           SourceLocation EndLoc) {
   if (Kind == OMPC_DEFAULT_unknown) {
     std::string Values;
-    std::string Sep(NUM_OPENMP_DEFAULT_KINDS > 1 ? ", " : "");
-    for (unsigned i = OMPC_DEFAULT_unknown + 1;
-         i < NUM_OPENMP_DEFAULT_KINDS; ++i) {
+    static_assert(OMPC_DEFAULT_unknown > 0,
+                  "OMPC_DEFAULT_unknown not greater than 0");
+    std::string Sep(", ");
+    for (unsigned i = 0; i < OMPC_DEFAULT_unknown; ++i) {
       Values += "'";
       Values += getOpenMPSimpleClauseTypeName(OMPC_default, i);
       Values += "'";
       switch (i) {
-      case NUM_OPENMP_DEFAULT_KINDS - 2:
+      case OMPC_DEFAULT_unknown - 2:
         Values += " or ";
         break;
-      case NUM_OPENMP_DEFAULT_KINDS - 1:
+      case OMPC_DEFAULT_unknown - 1:
         break;
       default:
         Values += Sep;
@@ -751,29 +2538,219 @@
       }
     }
     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
-      << Values << getOpenMPClauseName(OMPC_default);
-    return 0;
+        << Values << getOpenMPClauseName(OMPC_default);
+    return nullptr;
   }
   switch (Kind) {
   case OMPC_DEFAULT_none:
-    DSAStack->setDefaultDSANone();
+    DSAStack->setDefaultDSANone(KindKwLoc);
     break;
   case OMPC_DEFAULT_shared:
-    DSAStack->setDefaultDSAShared();
+    DSAStack->setDefaultDSAShared(KindKwLoc);
     break;
-  default:
+  case OMPC_DEFAULT_unknown:
+    llvm_unreachable("Clause kind is not allowed.");
     break;
   }
-  return new (Context) OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc,
-                                        EndLoc);
+  return new (Context)
+      OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
 }
 
-OMPClause *Sema::ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
-                                          ArrayRef<Expr *> VarList,
-                                          SourceLocation StartLoc,
-                                          SourceLocation LParenLoc,
+OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind,
+                                           SourceLocation KindKwLoc,
+                                           SourceLocation StartLoc,
+                                           SourceLocation LParenLoc,
+                                           SourceLocation EndLoc) {
+  if (Kind == OMPC_PROC_BIND_unknown) {
+    std::string Values;
+    std::string Sep(", ");
+    for (unsigned i = 0; i < OMPC_PROC_BIND_unknown; ++i) {
+      Values += "'";
+      Values += getOpenMPSimpleClauseTypeName(OMPC_proc_bind, i);
+      Values += "'";
+      switch (i) {
+      case OMPC_PROC_BIND_unknown - 2:
+        Values += " or ";
+        break;
+      case OMPC_PROC_BIND_unknown - 1:
+        break;
+      default:
+        Values += Sep;
+        break;
+      }
+    }
+    Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
+        << Values << getOpenMPClauseName(OMPC_proc_bind);
+    return nullptr;
+  }
+  return new (Context)
+      OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
+}
+
+OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
+    OpenMPClauseKind Kind, unsigned Argument, Expr *Expr,
+    SourceLocation StartLoc, SourceLocation LParenLoc,
+    SourceLocation ArgumentLoc, SourceLocation CommaLoc,
+    SourceLocation EndLoc) {
+  OMPClause *Res = nullptr;
+  switch (Kind) {
+  case OMPC_schedule:
+    Res = ActOnOpenMPScheduleClause(
+        static_cast<OpenMPScheduleClauseKind>(Argument), Expr, StartLoc,
+        LParenLoc, ArgumentLoc, CommaLoc, EndLoc);
+    break;
+  case OMPC_if:
+  case OMPC_final:
+  case OMPC_num_threads:
+  case OMPC_safelen:
+  case OMPC_collapse:
+  case OMPC_default:
+  case OMPC_proc_bind:
+  case OMPC_private:
+  case OMPC_firstprivate:
+  case OMPC_lastprivate:
+  case OMPC_shared:
+  case OMPC_reduction:
+  case OMPC_linear:
+  case OMPC_aligned:
+  case OMPC_copyin:
+  case OMPC_copyprivate:
+  case OMPC_ordered:
+  case OMPC_nowait:
+  case OMPC_untied:
+  case OMPC_mergeable:
+  case OMPC_threadprivate:
+  case OMPC_flush:
+  case OMPC_unknown:
+    llvm_unreachable("Clause is not allowed.");
+  }
+  return Res;
+}
+
+OMPClause *Sema::ActOnOpenMPScheduleClause(
+    OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
+    SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
+    SourceLocation EndLoc) {
+  if (Kind == OMPC_SCHEDULE_unknown) {
+    std::string Values;
+    std::string Sep(", ");
+    for (unsigned i = 0; i < OMPC_SCHEDULE_unknown; ++i) {
+      Values += "'";
+      Values += getOpenMPSimpleClauseTypeName(OMPC_schedule, i);
+      Values += "'";
+      switch (i) {
+      case OMPC_SCHEDULE_unknown - 2:
+        Values += " or ";
+        break;
+      case OMPC_SCHEDULE_unknown - 1:
+        break;
+      default:
+        Values += Sep;
+        break;
+      }
+    }
+    Diag(KindLoc, diag::err_omp_unexpected_clause_value)
+        << Values << getOpenMPClauseName(OMPC_schedule);
+    return nullptr;
+  }
+  Expr *ValExpr = ChunkSize;
+  if (ChunkSize) {
+    if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
+        !ChunkSize->isInstantiationDependent() &&
+        !ChunkSize->containsUnexpandedParameterPack()) {
+      SourceLocation ChunkSizeLoc = ChunkSize->getLocStart();
+      ExprResult Val =
+          PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
+      if (Val.isInvalid())
+        return nullptr;
+
+      ValExpr = Val.get();
+
+      // OpenMP [2.7.1, Restrictions]
+      //  chunk_size must be a loop invariant integer expression with a positive
+      //  value.
+      llvm::APSInt Result;
+      if (ValExpr->isIntegerConstantExpr(Result, Context) &&
+          Result.isSigned() && !Result.isStrictlyPositive()) {
+        Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
+            << "schedule" << ChunkSize->getSourceRange();
+        return nullptr;
+      }
+    }
+  }
+
+  return new (Context) OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc,
+                                         EndLoc, Kind, ValExpr);
+}
+
+OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
+                                   SourceLocation StartLoc,
+                                   SourceLocation EndLoc) {
+  OMPClause *Res = nullptr;
+  switch (Kind) {
+  case OMPC_ordered:
+    Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
+    break;
+  case OMPC_nowait:
+    Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
+    break;
+  case OMPC_untied:
+    Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
+    break;
+  case OMPC_mergeable:
+    Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
+    break;
+  case OMPC_if:
+  case OMPC_final:
+  case OMPC_num_threads:
+  case OMPC_safelen:
+  case OMPC_collapse:
+  case OMPC_schedule:
+  case OMPC_private:
+  case OMPC_firstprivate:
+  case OMPC_lastprivate:
+  case OMPC_shared:
+  case OMPC_reduction:
+  case OMPC_linear:
+  case OMPC_aligned:
+  case OMPC_copyin:
+  case OMPC_copyprivate:
+  case OMPC_default:
+  case OMPC_proc_bind:
+  case OMPC_threadprivate:
+  case OMPC_flush:
+  case OMPC_unknown:
+    llvm_unreachable("Clause is not allowed.");
+  }
+  return Res;
+}
+
+OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
                                           SourceLocation EndLoc) {
-  OMPClause *Res = 0;
+  return new (Context) OMPOrderedClause(StartLoc, EndLoc);
+}
+
+OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
+                                         SourceLocation EndLoc) {
+  return new (Context) OMPNowaitClause(StartLoc, EndLoc);
+}
+
+OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
+                                         SourceLocation EndLoc) {
+  return new (Context) OMPUntiedClause(StartLoc, EndLoc);
+}
+
+OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
+                                            SourceLocation EndLoc) {
+  return new (Context) OMPMergeableClause(StartLoc, EndLoc);
+}
+
+OMPClause *Sema::ActOnOpenMPVarListClause(
+    OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr,
+    SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
+    SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
+    const DeclarationNameInfo &ReductionId) {
+  OMPClause *Res = nullptr;
   switch (Kind) {
   case OMPC_private:
     Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
@@ -781,13 +2758,47 @@
   case OMPC_firstprivate:
     Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
     break;
+  case OMPC_lastprivate:
+    Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
+    break;
   case OMPC_shared:
     Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
     break;
+  case OMPC_reduction:
+    Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
+                                     EndLoc, ReductionIdScopeSpec, ReductionId);
+    break;
+  case OMPC_linear:
+    Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc,
+                                  ColonLoc, EndLoc);
+    break;
+  case OMPC_aligned:
+    Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc,
+                                   ColonLoc, EndLoc);
+    break;
+  case OMPC_copyin:
+    Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
+    break;
+  case OMPC_copyprivate:
+    Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
+    break;
+  case OMPC_flush:
+    Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
+    break;
+  case OMPC_if:
+  case OMPC_final:
+  case OMPC_num_threads:
+  case OMPC_safelen:
+  case OMPC_collapse:
   case OMPC_default:
+  case OMPC_proc_bind:
+  case OMPC_schedule:
+  case OMPC_ordered:
+  case OMPC_nowait:
+  case OMPC_untied:
+  case OMPC_mergeable:
   case OMPC_threadprivate:
   case OMPC_unknown:
-  case NUM_OPENMP_CLAUSES:
     llvm_unreachable("Clause is not allowed.");
   }
   return Res;
@@ -798,25 +2809,23 @@
                                           SourceLocation LParenLoc,
                                           SourceLocation EndLoc) {
   SmallVector<Expr *, 8> Vars;
-  for (ArrayRef<Expr *>::iterator I = VarList.begin(), E = VarList.end();
-       I != E; ++I) {
-    assert(*I && "NULL expr in OpenMP private clause.");
-    if (isa<DependentScopeDeclRefExpr>(*I)) {
+  for (auto &RefExpr : VarList) {
+    assert(RefExpr && "NULL expr in OpenMP private clause.");
+    if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
       // It will be analyzed later.
-      Vars.push_back(*I);
+      Vars.push_back(RefExpr);
       continue;
     }
 
-    SourceLocation ELoc = (*I)->getExprLoc();
+    SourceLocation ELoc = RefExpr->getExprLoc();
     // OpenMP [2.1, C/C++]
     //  A list item is a variable name.
     // OpenMP  [2.9.3.3, Restrictions, p.1]
     //  A variable that is part of another variable (as an array or
     //  structure element) cannot appear in a private clause.
-    DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(*I);
+    DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
     if (!DE || !isa<VarDecl>(DE->getDecl())) {
-      Diag(ELoc, diag::err_omp_expected_var_name)
-        << (*I)->getSourceRange();
+      Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
       continue;
     }
     Decl *D = DE->getDecl();
@@ -838,39 +2847,44 @@
     }
     if (Type->isReferenceType()) {
       Diag(ELoc, diag::err_omp_clause_ref_type_arg)
-        << getOpenMPClauseName(OMPC_private) << Type;
-      bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
-                    VarDecl::DeclarationOnly;
-      Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
-                                       diag::note_defined_here) << VD;
+          << getOpenMPClauseName(OMPC_private) << Type;
+      bool IsDecl =
+          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+      Diag(VD->getLocation(),
+           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+          << VD;
       continue;
     }
 
     // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
     //  A variable of class type (or array thereof) that appears in a private
-    //  clause requires an accesible, unambiguous default constructor for the
+    //  clause requires an accessible, unambiguous default constructor for the
     //  class type.
     while (Type.getNonReferenceType()->isArrayType()) {
-      Type = cast<ArrayType>(
-                 Type.getNonReferenceType().getTypePtr())->getElementType();
+      Type = cast<ArrayType>(Type.getNonReferenceType().getTypePtr())
+                 ->getElementType();
     }
-    CXXRecordDecl *RD = getLangOpts().CPlusPlus ?
-                          Type.getNonReferenceType()->getAsCXXRecordDecl() : 0;
+    CXXRecordDecl *RD = getLangOpts().CPlusPlus
+                            ? Type.getNonReferenceType()->getAsCXXRecordDecl()
+                            : nullptr;
+    // FIXME This code must be replaced by actual constructing/destructing of
+    // the private variable.
     if (RD) {
       CXXConstructorDecl *CD = LookupDefaultConstructor(RD);
       PartialDiagnostic PD =
-        PartialDiagnostic(PartialDiagnostic::NullDiagnostic());
+          PartialDiagnostic(PartialDiagnostic::NullDiagnostic());
       if (!CD ||
           CheckConstructorAccess(ELoc, CD,
                                  InitializedEntity::InitializeTemporary(Type),
                                  CD->getAccess(), PD) == AR_inaccessible ||
           CD->isDeleted()) {
         Diag(ELoc, diag::err_omp_required_method)
-             << getOpenMPClauseName(OMPC_private) << 0;
+            << getOpenMPClauseName(OMPC_private) << 0;
         bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
                       VarDecl::DeclarationOnly;
-        Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
-                                         diag::note_defined_here) << VD;
+        Diag(VD->getLocation(),
+             IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+            << VD;
         Diag(RD->getLocation(), diag::note_previous_decl) << RD;
         continue;
       }
@@ -882,11 +2896,12 @@
         if (CheckDestructorAccess(ELoc, DD, PD) == AR_inaccessible ||
             DD->isDeleted()) {
           Diag(ELoc, diag::err_omp_required_method)
-               << getOpenMPClauseName(OMPC_private) << 4;
+              << getOpenMPClauseName(OMPC_private) << 4;
           bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
                         VarDecl::DeclarationOnly;
-          Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
-                                           diag::note_defined_here) << VD;
+          Diag(VD->getLocation(),
+               IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+              << VD;
           Diag(RD->getLocation(), diag::note_previous_decl) << RD;
           continue;
         }
@@ -902,18 +2917,11 @@
     //  listed below. For these exceptions only, listing a predetermined
     //  variable in a data-sharing attribute clause is allowed and overrides
     //  the variable's predetermined data-sharing attributes.
-    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD);
+    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false);
     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
-      Diag(ELoc, diag::err_omp_wrong_dsa)
-         << getOpenMPClauseName(DVar.CKind)
-         << getOpenMPClauseName(OMPC_private);
-      if (DVar.RefExpr) {
-        Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
-             << getOpenMPClauseName(DVar.CKind);
-      } else {
-        Diag(VD->getLocation(), diag::note_omp_predetermined_dsa)
-             << getOpenMPClauseName(DVar.CKind);
-      }
+      Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
+                                          << getOpenMPClauseName(OMPC_private);
+      ReportOriginalDSA(*this, DSAStack, VD, DVar);
       continue;
     }
 
@@ -921,7 +2929,8 @@
     Vars.push_back(DE);
   }
 
-  if (Vars.empty()) return 0;
+  if (Vars.empty())
+    return nullptr;
 
   return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
 }
@@ -931,25 +2940,28 @@
                                                SourceLocation LParenLoc,
                                                SourceLocation EndLoc) {
   SmallVector<Expr *, 8> Vars;
-  for (ArrayRef<Expr *>::iterator I = VarList.begin(), E = VarList.end();
-       I != E; ++I) {
-    assert(*I && "NULL expr in OpenMP firstprivate clause.");
-    if (isa<DependentScopeDeclRefExpr>(*I)) {
+  bool IsImplicitClause =
+      StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
+  auto ImplicitClauseLoc = DSAStack->getConstructLoc();
+
+  for (auto &RefExpr : VarList) {
+    assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
+    if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
       // It will be analyzed later.
-      Vars.push_back(*I);
+      Vars.push_back(RefExpr);
       continue;
     }
 
-    SourceLocation ELoc = (*I)->getExprLoc();
+    SourceLocation ELoc = IsImplicitClause ? ImplicitClauseLoc
+                                           : RefExpr->getExprLoc();
     // OpenMP [2.1, C/C++]
     //  A list item is a variable name.
     // OpenMP  [2.9.3.3, Restrictions, p.1]
     //  A variable that is part of another variable (as an array or
     //  structure element) cannot appear in a private clause.
-    DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(*I);
+    DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
     if (!DE || !isa<VarDecl>(DE->getDecl())) {
-      Diag(ELoc, diag::err_omp_expected_var_name)
-        << (*I)->getSourceRange();
+      Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
       continue;
     }
     Decl *D = DE->getDecl();
@@ -970,37 +2982,56 @@
       continue;
     }
     if (Type->isReferenceType()) {
-      Diag(ELoc, diag::err_omp_clause_ref_type_arg)
-        << getOpenMPClauseName(OMPC_firstprivate) << Type;
-      bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
-                    VarDecl::DeclarationOnly;
-      Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
-                                       diag::note_defined_here) << VD;
+      if (IsImplicitClause) {
+        Diag(ImplicitClauseLoc,
+             diag::err_omp_task_predetermined_firstprivate_ref_type_arg)
+            << Type;
+        Diag(RefExpr->getExprLoc(), diag::note_used_here);
+      } else {
+        Diag(ELoc, diag::err_omp_clause_ref_type_arg)
+            << getOpenMPClauseName(OMPC_firstprivate) << Type;
+      }
+      bool IsDecl =
+          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+      Diag(VD->getLocation(),
+           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+          << VD;
       continue;
     }
 
     // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
     //  A variable of class type (or array thereof) that appears in a private
-    //  clause requires an accesible, unambiguous copy constructor for the
+    //  clause requires an accessible, unambiguous copy constructor for the
     //  class type.
     Type = Context.getBaseElementType(Type);
-    CXXRecordDecl *RD = getLangOpts().CPlusPlus ?
-                          Type.getNonReferenceType()->getAsCXXRecordDecl() : 0;
+    CXXRecordDecl *RD = getLangOpts().CPlusPlus
+                            ? Type.getNonReferenceType()->getAsCXXRecordDecl()
+                            : nullptr;
+    // FIXME This code must be replaced by actual constructing/destructing of
+    // the firstprivate variable.
     if (RD) {
       CXXConstructorDecl *CD = LookupCopyingConstructor(RD, 0);
       PartialDiagnostic PD =
-        PartialDiagnostic(PartialDiagnostic::NullDiagnostic());
+          PartialDiagnostic(PartialDiagnostic::NullDiagnostic());
       if (!CD ||
           CheckConstructorAccess(ELoc, CD,
                                  InitializedEntity::InitializeTemporary(Type),
                                  CD->getAccess(), PD) == AR_inaccessible ||
           CD->isDeleted()) {
-        Diag(ELoc, diag::err_omp_required_method)
-             << getOpenMPClauseName(OMPC_firstprivate) << 1;
+        if (IsImplicitClause) {
+          Diag(ImplicitClauseLoc,
+               diag::err_omp_task_predetermined_firstprivate_required_method)
+              << 0;
+          Diag(RefExpr->getExprLoc(), diag::note_used_here);
+        } else {
+          Diag(ELoc, diag::err_omp_required_method)
+              << getOpenMPClauseName(OMPC_firstprivate) << 1;
+        }
         bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
                       VarDecl::DeclarationOnly;
-        Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
-                                         diag::note_defined_here) << VD;
+        Diag(VD->getLocation(),
+             IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+            << VD;
         Diag(RD->getLocation(), diag::note_previous_decl) << RD;
         continue;
       }
@@ -1011,12 +3042,20 @@
       if (DD) {
         if (CheckDestructorAccess(ELoc, DD, PD) == AR_inaccessible ||
             DD->isDeleted()) {
-          Diag(ELoc, diag::err_omp_required_method)
-               << getOpenMPClauseName(OMPC_firstprivate) << 4;
+          if (IsImplicitClause) {
+            Diag(ImplicitClauseLoc,
+                 diag::err_omp_task_predetermined_firstprivate_required_method)
+                << 1;
+            Diag(RefExpr->getExprLoc(), diag::note_used_here);
+          } else {
+            Diag(ELoc, diag::err_omp_required_method)
+                << getOpenMPClauseName(OMPC_firstprivate) << 4;
+          }
           bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
                         VarDecl::DeclarationOnly;
-          Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
-                                           diag::note_defined_here) << VD;
+          Diag(VD->getLocation(),
+               IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+              << VD;
           Diag(RD->getLocation(), diag::note_previous_decl) << RD;
           continue;
         }
@@ -1025,10 +3064,9 @@
       }
     }
 
-    // If StartLoc and EndLoc are invalid - this is an implicit firstprivate
-    // variable and it was checked already.
-    if (StartLoc.isValid() && EndLoc.isValid()) {
-      DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD);
+    // If an implicit firstprivate variable found it was checked already.
+    if (!IsImplicitClause) {
+      DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false);
       Type = Type.getNonReferenceType().getCanonicalType();
       bool IsConstant = Type.isConstant(Context);
       Type = Context.getBaseElementType(Type);
@@ -1036,14 +3074,12 @@
       //  A list item that specifies a given variable may not appear in more
       // than one clause on the same directive, except that a variable may be
       //  specified in both firstprivate and lastprivate clauses.
-      //  TODO: add processing for lastprivate.
       if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
-          DVar.RefExpr) {
+          DVar.CKind != OMPC_lastprivate && DVar.RefExpr) {
         Diag(ELoc, diag::err_omp_wrong_dsa)
-           << getOpenMPClauseName(DVar.CKind)
-           << getOpenMPClauseName(OMPC_firstprivate);
-        Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
-           << getOpenMPClauseName(DVar.CKind);
+            << getOpenMPClauseName(DVar.CKind)
+            << getOpenMPClauseName(OMPC_firstprivate);
+        ReportOriginalDSA(*this, DSAStack, VD, DVar);
         continue;
       }
 
@@ -1061,18 +3097,31 @@
       if (!(IsConstant || VD->isStaticDataMember()) && !DVar.RefExpr &&
           DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
         Diag(ELoc, diag::err_omp_wrong_dsa)
-           << getOpenMPClauseName(DVar.CKind)
-           << getOpenMPClauseName(OMPC_firstprivate);
-        Diag(VD->getLocation(), diag::note_omp_predetermined_dsa)
-           << getOpenMPClauseName(DVar.CKind);
+            << getOpenMPClauseName(DVar.CKind)
+            << getOpenMPClauseName(OMPC_firstprivate);
+        ReportOriginalDSA(*this, DSAStack, VD, DVar);
         continue;
       }
 
+      OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
       // OpenMP [2.9.3.4, Restrictions, p.2]
       //  A list item that is private within a parallel region must not appear
       //  in a firstprivate clause on a worksharing construct if any of the
       //  worksharing regions arising from the worksharing construct ever bind
       //  to any of the parallel regions arising from the parallel construct.
+      if (isOpenMPWorksharingDirective(CurrDir) &&
+          !isOpenMPParallelDirective(CurrDir)) {
+        DVar = DSAStack->getImplicitDSA(VD, true);
+        if (DVar.CKind != OMPC_shared &&
+            (isOpenMPParallelDirective(DVar.DKind) ||
+             DVar.DKind == OMPD_unknown)) {
+          Diag(ELoc, diag::err_omp_required_access)
+              << getOpenMPClauseName(OMPC_firstprivate)
+              << getOpenMPClauseName(OMPC_shared);
+          ReportOriginalDSA(*this, DSAStack, VD, DVar);
+          continue;
+        }
+      }
       // OpenMP [2.9.3.4, Restrictions, p.3]
       //  A list item that appears in a reduction clause of a parallel construct
       //  must not appear in a firstprivate clause on a worksharing or task
@@ -1084,43 +3133,214 @@
       //  construct must not appear in a firstprivate clause in a task construct
       //  encountered during execution of any of the worksharing regions arising
       //  from the worksharing construct.
-      // TODO:
+      if (CurrDir == OMPD_task) {
+        DVar =
+            DSAStack->hasInnermostDSA(VD, MatchesAnyClause(OMPC_reduction),
+                                      [](OpenMPDirectiveKind K) -> bool {
+                                        return isOpenMPParallelDirective(K) ||
+                                               isOpenMPWorksharingDirective(K);
+                                      },
+                                      false);
+        if (DVar.CKind == OMPC_reduction &&
+            (isOpenMPParallelDirective(DVar.DKind) ||
+             isOpenMPWorksharingDirective(DVar.DKind))) {
+          Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
+              << getOpenMPDirectiveName(DVar.DKind);
+          ReportOriginalDSA(*this, DSAStack, VD, DVar);
+          continue;
+        }
+      }
     }
 
     DSAStack->addDSA(VD, DE, OMPC_firstprivate);
     Vars.push_back(DE);
   }
 
-  if (Vars.empty()) return 0;
+  if (Vars.empty())
+    return nullptr;
 
   return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
                                        Vars);
 }
 
+OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList,
+                                              SourceLocation StartLoc,
+                                              SourceLocation LParenLoc,
+                                              SourceLocation EndLoc) {
+  SmallVector<Expr *, 8> Vars;
+  for (auto &RefExpr : VarList) {
+    assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
+    if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
+      // It will be analyzed later.
+      Vars.push_back(RefExpr);
+      continue;
+    }
+
+    SourceLocation ELoc = RefExpr->getExprLoc();
+    // OpenMP [2.1, C/C++]
+    //  A list item is a variable name.
+    // OpenMP  [2.14.3.5, Restrictions, p.1]
+    //  A variable that is part of another variable (as an array or structure
+    //  element) cannot appear in a lastprivate clause.
+    DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
+    if (!DE || !isa<VarDecl>(DE->getDecl())) {
+      Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
+      continue;
+    }
+    Decl *D = DE->getDecl();
+    VarDecl *VD = cast<VarDecl>(D);
+
+    QualType Type = VD->getType();
+    if (Type->isDependentType() || Type->isInstantiationDependentType()) {
+      // It will be analyzed later.
+      Vars.push_back(DE);
+      continue;
+    }
+
+    // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
+    //  A variable that appears in a lastprivate clause must not have an
+    //  incomplete type or a reference type.
+    if (RequireCompleteType(ELoc, Type,
+                            diag::err_omp_lastprivate_incomplete_type)) {
+      continue;
+    }
+    if (Type->isReferenceType()) {
+      Diag(ELoc, diag::err_omp_clause_ref_type_arg)
+          << getOpenMPClauseName(OMPC_lastprivate) << Type;
+      bool IsDecl =
+          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+      Diag(VD->getLocation(),
+           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+          << VD;
+      continue;
+    }
+
+    // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
+    // in a Construct]
+    //  Variables with the predetermined data-sharing attributes may not be
+    //  listed in data-sharing attributes clauses, except for the cases
+    //  listed below.
+    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false);
+    if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
+        DVar.CKind != OMPC_firstprivate &&
+        (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
+      Diag(ELoc, diag::err_omp_wrong_dsa)
+          << getOpenMPClauseName(DVar.CKind)
+          << getOpenMPClauseName(OMPC_lastprivate);
+      ReportOriginalDSA(*this, DSAStack, VD, DVar);
+      continue;
+    }
+
+    OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
+    // OpenMP [2.14.3.5, Restrictions, p.2]
+    // A list item that is private within a parallel region, or that appears in
+    // the reduction clause of a parallel construct, must not appear in a
+    // lastprivate clause on a worksharing construct if any of the corresponding
+    // worksharing regions ever binds to any of the corresponding parallel
+    // regions.
+    if (isOpenMPWorksharingDirective(CurrDir) &&
+        !isOpenMPParallelDirective(CurrDir)) {
+      DVar = DSAStack->getImplicitDSA(VD, true);
+      if (DVar.CKind != OMPC_shared) {
+        Diag(ELoc, diag::err_omp_required_access)
+            << getOpenMPClauseName(OMPC_lastprivate)
+            << getOpenMPClauseName(OMPC_shared);
+        ReportOriginalDSA(*this, DSAStack, VD, DVar);
+        continue;
+      }
+    }
+    // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
+    //  A variable of class type (or array thereof) that appears in a
+    //  lastprivate clause requires an accessible, unambiguous default
+    //  constructor for the class type, unless the list item is also specified
+    //  in a firstprivate clause.
+    //  A variable of class type (or array thereof) that appears in a
+    //  lastprivate clause requires an accessible, unambiguous copy assignment
+    //  operator for the class type.
+    while (Type.getNonReferenceType()->isArrayType())
+      Type = cast<ArrayType>(Type.getNonReferenceType().getTypePtr())
+                 ->getElementType();
+    CXXRecordDecl *RD = getLangOpts().CPlusPlus
+                            ? Type.getNonReferenceType()->getAsCXXRecordDecl()
+                            : nullptr;
+    // FIXME This code must be replaced by actual copying and destructing of the
+    // lastprivate variable.
+    if (RD) {
+      CXXMethodDecl *MD = LookupCopyingAssignment(RD, 0, false, 0);
+      DeclAccessPair FoundDecl = DeclAccessPair::make(MD, MD->getAccess());
+      if (MD) {
+        if (CheckMemberAccess(ELoc, RD, FoundDecl) == AR_inaccessible ||
+            MD->isDeleted()) {
+          Diag(ELoc, diag::err_omp_required_method)
+              << getOpenMPClauseName(OMPC_lastprivate) << 2;
+          bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
+                        VarDecl::DeclarationOnly;
+          Diag(VD->getLocation(),
+               IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+              << VD;
+          Diag(RD->getLocation(), diag::note_previous_decl) << RD;
+          continue;
+        }
+        MarkFunctionReferenced(ELoc, MD);
+        DiagnoseUseOfDecl(MD, ELoc);
+      }
+
+      CXXDestructorDecl *DD = RD->getDestructor();
+      if (DD) {
+        PartialDiagnostic PD =
+            PartialDiagnostic(PartialDiagnostic::NullDiagnostic());
+        if (CheckDestructorAccess(ELoc, DD, PD) == AR_inaccessible ||
+            DD->isDeleted()) {
+          Diag(ELoc, diag::err_omp_required_method)
+              << getOpenMPClauseName(OMPC_lastprivate) << 4;
+          bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
+                        VarDecl::DeclarationOnly;
+          Diag(VD->getLocation(),
+               IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+              << VD;
+          Diag(RD->getLocation(), diag::note_previous_decl) << RD;
+          continue;
+        }
+        MarkFunctionReferenced(ELoc, DD);
+        DiagnoseUseOfDecl(DD, ELoc);
+      }
+    }
+
+    if (DVar.CKind != OMPC_firstprivate)
+      DSAStack->addDSA(VD, DE, OMPC_lastprivate);
+    Vars.push_back(DE);
+  }
+
+  if (Vars.empty())
+    return nullptr;
+
+  return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
+                                      Vars);
+}
+
 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
                                          SourceLocation StartLoc,
                                          SourceLocation LParenLoc,
                                          SourceLocation EndLoc) {
   SmallVector<Expr *, 8> Vars;
-  for (ArrayRef<Expr *>::iterator I = VarList.begin(), E = VarList.end();
-       I != E; ++I) {
-    assert(*I && "NULL expr in OpenMP shared clause.");
-    if (isa<DependentScopeDeclRefExpr>(*I)) {
+  for (auto &RefExpr : VarList) {
+    assert(RefExpr && "NULL expr in OpenMP shared clause.");
+    if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
       // It will be analyzed later.
-      Vars.push_back(*I);
+      Vars.push_back(RefExpr);
       continue;
     }
 
-    SourceLocation ELoc = (*I)->getExprLoc();
+    SourceLocation ELoc = RefExpr->getExprLoc();
     // OpenMP [2.1, C/C++]
     //  A list item is a variable name.
-    // OpenMP  [2.9.3.4, Restrictions, p.1]
-    //  A variable that is part of another variable (as an array or
-    //  structure element) cannot appear in a private clause.
-    DeclRefExpr *DE = dyn_cast<DeclRefExpr>(*I);
+    // OpenMP  [2.14.3.2, Restrictions, p.1]
+    //  A variable that is part of another variable (as an array or structure
+    //  element) cannot appear in a shared unless it is a static data member
+    //  of a C++ class.
+    DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr);
     if (!DE || !isa<VarDecl>(DE->getDecl())) {
-      Diag(ELoc, diag::err_omp_expected_var_name)
-        << (*I)->getSourceRange();
+      Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
       continue;
     }
     Decl *D = DE->getDecl();
@@ -1140,13 +3360,12 @@
     //  listed below. For these exceptions only, listing a predetermined
     //  variable in a data-sharing attribute clause is allowed and overrides
     //  the variable's predetermined data-sharing attributes.
-    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD);
-    if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && DVar.RefExpr) {
-      Diag(ELoc, diag::err_omp_wrong_dsa)
-         << getOpenMPClauseName(DVar.CKind)
-         << getOpenMPClauseName(OMPC_shared);
-      Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
-           << getOpenMPClauseName(DVar.CKind);
+    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false);
+    if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
+        DVar.RefExpr) {
+      Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
+                                          << getOpenMPClauseName(OMPC_shared);
+      ReportOriginalDSA(*this, DSAStack, VD, DVar);
       continue;
     }
 
@@ -1154,9 +3373,730 @@
     Vars.push_back(DE);
   }
 
-  if (Vars.empty()) return 0;
+  if (Vars.empty())
+    return nullptr;
 
   return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
 }
 
+namespace {
+class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
+  DSAStackTy *Stack;
+
+public:
+  bool VisitDeclRefExpr(DeclRefExpr *E) {
+    if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) {
+      DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, false);
+      if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
+        return false;
+      if (DVar.CKind != OMPC_unknown)
+        return true;
+      DSAStackTy::DSAVarData DVarPrivate =
+          Stack->hasDSA(VD, isOpenMPPrivate, MatchesAlways(), false);
+      if (DVarPrivate.CKind != OMPC_unknown)
+        return true;
+      return false;
+    }
+    return false;
+  }
+  bool VisitStmt(Stmt *S) {
+    for (auto Child : S->children()) {
+      if (Child && Visit(Child))
+        return true;
+    }
+    return false;
+  }
+  explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
+};
+} // namespace
+
+OMPClause *Sema::ActOnOpenMPReductionClause(
+    ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
+    SourceLocation ColonLoc, SourceLocation EndLoc,
+    CXXScopeSpec &ReductionIdScopeSpec,
+    const DeclarationNameInfo &ReductionId) {
+  // TODO: Allow scope specification search when 'declare reduction' is
+  // supported.
+  assert(ReductionIdScopeSpec.isEmpty() &&
+         "No support for scoped reduction identifiers yet.");
+
+  auto DN = ReductionId.getName();
+  auto OOK = DN.getCXXOverloadedOperator();
+  BinaryOperatorKind BOK = BO_Comma;
+
+  // OpenMP [2.14.3.6, reduction clause]
+  // C
+  // reduction-identifier is either an identifier or one of the following
+  // operators: +, -, *,  &, |, ^, && and ||
+  // C++
+  // reduction-identifier is either an id-expression or one of the following
+  // operators: +, -, *, &, |, ^, && and ||
+  // FIXME: Only 'min' and 'max' identifiers are supported for now.
+  switch (OOK) {
+  case OO_Plus:
+  case OO_Minus:
+    BOK = BO_AddAssign;
+    break;
+  case OO_Star:
+    BOK = BO_MulAssign;
+    break;
+  case OO_Amp:
+    BOK = BO_AndAssign;
+    break;
+  case OO_Pipe:
+    BOK = BO_OrAssign;
+    break;
+  case OO_Caret:
+    BOK = BO_XorAssign;
+    break;
+  case OO_AmpAmp:
+    BOK = BO_LAnd;
+    break;
+  case OO_PipePipe:
+    BOK = BO_LOr;
+    break;
+  default:
+    if (auto II = DN.getAsIdentifierInfo()) {
+      if (II->isStr("max"))
+        BOK = BO_GT;
+      else if (II->isStr("min"))
+        BOK = BO_LT;
+    }
+    break;
+  }
+  SourceRange ReductionIdRange;
+  if (ReductionIdScopeSpec.isValid()) {
+    ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
+  }
+  ReductionIdRange.setEnd(ReductionId.getEndLoc());
+  if (BOK == BO_Comma) {
+    // Not allowed reduction identifier is found.
+    Diag(ReductionId.getLocStart(), diag::err_omp_unknown_reduction_identifier)
+        << ReductionIdRange;
+    return nullptr;
+  }
+
+  SmallVector<Expr *, 8> Vars;
+  for (auto RefExpr : VarList) {
+    assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
+    if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
+      // It will be analyzed later.
+      Vars.push_back(RefExpr);
+      continue;
+    }
+
+    if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
+        RefExpr->isInstantiationDependent() ||
+        RefExpr->containsUnexpandedParameterPack()) {
+      // It will be analyzed later.
+      Vars.push_back(RefExpr);
+      continue;
+    }
+
+    auto ELoc = RefExpr->getExprLoc();
+    auto ERange = RefExpr->getSourceRange();
+    // OpenMP [2.1, C/C++]
+    //  A list item is a variable or array section, subject to the restrictions
+    //  specified in Section 2.4 on page 42 and in each of the sections
+    // describing clauses and directives for which a list appears.
+    // OpenMP  [2.14.3.3, Restrictions, p.1]
+    //  A variable that is part of another variable (as an array or
+    //  structure element) cannot appear in a private clause.
+    auto DE = dyn_cast<DeclRefExpr>(RefExpr);
+    if (!DE || !isa<VarDecl>(DE->getDecl())) {
+      Diag(ELoc, diag::err_omp_expected_var_name) << ERange;
+      continue;
+    }
+    auto D = DE->getDecl();
+    auto VD = cast<VarDecl>(D);
+    auto Type = VD->getType();
+    // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
+    //  A variable that appears in a private clause must not have an incomplete
+    //  type or a reference type.
+    if (RequireCompleteType(ELoc, Type,
+                            diag::err_omp_reduction_incomplete_type))
+      continue;
+    // OpenMP [2.14.3.6, reduction clause, Restrictions]
+    // Arrays may not appear in a reduction clause.
+    if (Type.getNonReferenceType()->isArrayType()) {
+      Diag(ELoc, diag::err_omp_reduction_type_array) << Type << ERange;
+      bool IsDecl =
+          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+      Diag(VD->getLocation(),
+           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+          << VD;
+      continue;
+    }
+    // OpenMP [2.14.3.6, reduction clause, Restrictions]
+    // A list item that appears in a reduction clause must not be
+    // const-qualified.
+    if (Type.getNonReferenceType().isConstant(Context)) {
+      Diag(ELoc, diag::err_omp_const_variable)
+          << getOpenMPClauseName(OMPC_reduction) << Type << ERange;
+      bool IsDecl =
+          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+      Diag(VD->getLocation(),
+           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+          << VD;
+      continue;
+    }
+    // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
+    //  If a list-item is a reference type then it must bind to the same object
+    //  for all threads of the team.
+    VarDecl *VDDef = VD->getDefinition();
+    if (Type->isReferenceType() && VDDef) {
+      DSARefChecker Check(DSAStack);
+      if (Check.Visit(VDDef->getInit())) {
+        Diag(ELoc, diag::err_omp_reduction_ref_type_arg) << ERange;
+        Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
+        continue;
+      }
+    }
+    // OpenMP [2.14.3.6, reduction clause, Restrictions]
+    // The type of a list item that appears in a reduction clause must be valid
+    // for the reduction-identifier. For a max or min reduction in C, the type
+    // of the list item must be an allowed arithmetic data type: char, int,
+    // float, double, or _Bool, possibly modified with long, short, signed, or
+    // unsigned. For a max or min reduction in C++, the type of the list item
+    // must be an allowed arithmetic data type: char, wchar_t, int, float,
+    // double, or bool, possibly modified with long, short, signed, or unsigned.
+    if ((BOK == BO_GT || BOK == BO_LT) &&
+        !(Type->isScalarType() ||
+          (getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
+      Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
+          << getLangOpts().CPlusPlus;
+      bool IsDecl =
+          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+      Diag(VD->getLocation(),
+           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+          << VD;
+      continue;
+    }
+    if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
+        !getLangOpts().CPlusPlus && Type->isFloatingType()) {
+      Diag(ELoc, diag::err_omp_clause_floating_type_arg);
+      bool IsDecl =
+          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+      Diag(VD->getLocation(),
+           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+          << VD;
+      continue;
+    }
+    bool Suppress = getDiagnostics().getSuppressAllDiagnostics();
+    getDiagnostics().setSuppressAllDiagnostics(true);
+    ExprResult ReductionOp =
+        BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(), BOK,
+                   RefExpr, RefExpr);
+    getDiagnostics().setSuppressAllDiagnostics(Suppress);
+    if (ReductionOp.isInvalid()) {
+      Diag(ELoc, diag::err_omp_reduction_id_not_compatible) << Type
+                                                            << ReductionIdRange;
+      bool IsDecl =
+          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+      Diag(VD->getLocation(),
+           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+          << VD;
+      continue;
+    }
+
+    // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
+    // in a Construct]
+    //  Variables with the predetermined data-sharing attributes may not be
+    //  listed in data-sharing attributes clauses, except for the cases
+    //  listed below. For these exceptions only, listing a predetermined
+    //  variable in a data-sharing attribute clause is allowed and overrides
+    //  the variable's predetermined data-sharing attributes.
+    // OpenMP [2.14.3.6, Restrictions, p.3]
+    //  Any number of reduction clauses can be specified on the directive,
+    //  but a list item can appear only once in the reduction clauses for that
+    //  directive.
+    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false);
+    if (DVar.CKind == OMPC_reduction) {
+      Diag(ELoc, diag::err_omp_once_referenced)
+          << getOpenMPClauseName(OMPC_reduction);
+      if (DVar.RefExpr) {
+        Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
+      }
+    } else if (DVar.CKind != OMPC_unknown) {
+      Diag(ELoc, diag::err_omp_wrong_dsa)
+          << getOpenMPClauseName(DVar.CKind)
+          << getOpenMPClauseName(OMPC_reduction);
+      ReportOriginalDSA(*this, DSAStack, VD, DVar);
+      continue;
+    }
+
+    // OpenMP [2.14.3.6, Restrictions, p.1]
+    //  A list item that appears in a reduction clause of a worksharing
+    //  construct must be shared in the parallel regions to which any of the
+    //  worksharing regions arising from the worksharing construct bind.
+    OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
+    if (isOpenMPWorksharingDirective(CurrDir) &&
+        !isOpenMPParallelDirective(CurrDir)) {
+      DVar = DSAStack->getImplicitDSA(VD, true);
+      if (DVar.CKind != OMPC_shared) {
+        Diag(ELoc, diag::err_omp_required_access)
+            << getOpenMPClauseName(OMPC_reduction)
+            << getOpenMPClauseName(OMPC_shared);
+        ReportOriginalDSA(*this, DSAStack, VD, DVar);
+        continue;
+      }
+    }
+
+    CXXRecordDecl *RD = getLangOpts().CPlusPlus
+                            ? Type.getNonReferenceType()->getAsCXXRecordDecl()
+                            : nullptr;
+    // FIXME This code must be replaced by actual constructing/destructing of
+    // the reduction variable.
+    if (RD) {
+      CXXConstructorDecl *CD = LookupDefaultConstructor(RD);
+      PartialDiagnostic PD =
+          PartialDiagnostic(PartialDiagnostic::NullDiagnostic());
+      if (!CD ||
+          CheckConstructorAccess(ELoc, CD,
+                                 InitializedEntity::InitializeTemporary(Type),
+                                 CD->getAccess(), PD) == AR_inaccessible ||
+          CD->isDeleted()) {
+        Diag(ELoc, diag::err_omp_required_method)
+            << getOpenMPClauseName(OMPC_reduction) << 0;
+        bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
+                      VarDecl::DeclarationOnly;
+        Diag(VD->getLocation(),
+             IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+            << VD;
+        Diag(RD->getLocation(), diag::note_previous_decl) << RD;
+        continue;
+      }
+      MarkFunctionReferenced(ELoc, CD);
+      DiagnoseUseOfDecl(CD, ELoc);
+
+      CXXDestructorDecl *DD = RD->getDestructor();
+      if (DD) {
+        if (CheckDestructorAccess(ELoc, DD, PD) == AR_inaccessible ||
+            DD->isDeleted()) {
+          Diag(ELoc, diag::err_omp_required_method)
+              << getOpenMPClauseName(OMPC_reduction) << 4;
+          bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
+                        VarDecl::DeclarationOnly;
+          Diag(VD->getLocation(),
+               IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+              << VD;
+          Diag(RD->getLocation(), diag::note_previous_decl) << RD;
+          continue;
+        }
+        MarkFunctionReferenced(ELoc, DD);
+        DiagnoseUseOfDecl(DD, ELoc);
+      }
+    }
+
+    DSAStack->addDSA(VD, DE, OMPC_reduction);
+    Vars.push_back(DE);
+  }
+
+  if (Vars.empty())
+    return nullptr;
+
+  return OMPReductionClause::Create(
+      Context, StartLoc, LParenLoc, ColonLoc, EndLoc, Vars,
+      ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId);
+}
+
+OMPClause *Sema::ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step,
+                                         SourceLocation StartLoc,
+                                         SourceLocation LParenLoc,
+                                         SourceLocation ColonLoc,
+                                         SourceLocation EndLoc) {
+  SmallVector<Expr *, 8> Vars;
+  for (auto &RefExpr : VarList) {
+    assert(RefExpr && "NULL expr in OpenMP linear clause.");
+    if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
+      // It will be analyzed later.
+      Vars.push_back(RefExpr);
+      continue;
+    }
+
+    // OpenMP [2.14.3.7, linear clause]
+    // A list item that appears in a linear clause is subject to the private
+    // clause semantics described in Section 2.14.3.3 on page 159 except as
+    // noted. In addition, the value of the new list item on each iteration
+    // of the associated loop(s) corresponds to the value of the original
+    // list item before entering the construct plus the logical number of
+    // the iteration times linear-step.
+
+    SourceLocation ELoc = RefExpr->getExprLoc();
+    // OpenMP [2.1, C/C++]
+    //  A list item is a variable name.
+    // OpenMP  [2.14.3.3, Restrictions, p.1]
+    //  A variable that is part of another variable (as an array or
+    //  structure element) cannot appear in a private clause.
+    DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr);
+    if (!DE || !isa<VarDecl>(DE->getDecl())) {
+      Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
+      continue;
+    }
+
+    VarDecl *VD = cast<VarDecl>(DE->getDecl());
+
+    // OpenMP [2.14.3.7, linear clause]
+    //  A list-item cannot appear in more than one linear clause.
+    //  A list-item that appears in a linear clause cannot appear in any
+    //  other data-sharing attribute clause.
+    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false);
+    if (DVar.RefExpr) {
+      Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
+                                          << getOpenMPClauseName(OMPC_linear);
+      ReportOriginalDSA(*this, DSAStack, VD, DVar);
+      continue;
+    }
+
+    QualType QType = VD->getType();
+    if (QType->isDependentType() || QType->isInstantiationDependentType()) {
+      // It will be analyzed later.
+      Vars.push_back(DE);
+      continue;
+    }
+
+    // A variable must not have an incomplete type or a reference type.
+    if (RequireCompleteType(ELoc, QType,
+                            diag::err_omp_linear_incomplete_type)) {
+      continue;
+    }
+    if (QType->isReferenceType()) {
+      Diag(ELoc, diag::err_omp_clause_ref_type_arg)
+          << getOpenMPClauseName(OMPC_linear) << QType;
+      bool IsDecl =
+          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+      Diag(VD->getLocation(),
+           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+          << VD;
+      continue;
+    }
+
+    // A list item must not be const-qualified.
+    if (QType.isConstant(Context)) {
+      Diag(ELoc, diag::err_omp_const_variable)
+          << getOpenMPClauseName(OMPC_linear);
+      bool IsDecl =
+          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+      Diag(VD->getLocation(),
+           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+          << VD;
+      continue;
+    }
+
+    // A list item must be of integral or pointer type.
+    QType = QType.getUnqualifiedType().getCanonicalType();
+    const Type *Ty = QType.getTypePtrOrNull();
+    if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) &&
+                !Ty->isPointerType())) {
+      Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << QType;
+      bool IsDecl =
+          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+      Diag(VD->getLocation(),
+           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+          << VD;
+      continue;
+    }
+
+    DSAStack->addDSA(VD, DE, OMPC_linear);
+    Vars.push_back(DE);
+  }
+
+  if (Vars.empty())
+    return nullptr;
+
+  Expr *StepExpr = Step;
+  if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
+      !Step->isInstantiationDependent() &&
+      !Step->containsUnexpandedParameterPack()) {
+    SourceLocation StepLoc = Step->getLocStart();
+    ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
+    if (Val.isInvalid())
+      return nullptr;
+    StepExpr = Val.get();
+
+    // Warn about zero linear step (it would be probably better specified as
+    // making corresponding variables 'const').
+    llvm::APSInt Result;
+    if (StepExpr->isIntegerConstantExpr(Result, Context) &&
+        !Result.isNegative() && !Result.isStrictlyPositive())
+      Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0]
+                                                     << (Vars.size() > 1);
+  }
+
+  return OMPLinearClause::Create(Context, StartLoc, LParenLoc, ColonLoc, EndLoc,
+                                 Vars, StepExpr);
+}
+
+OMPClause *Sema::ActOnOpenMPAlignedClause(
+    ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
+    SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
+
+  SmallVector<Expr *, 8> Vars;
+  for (auto &RefExpr : VarList) {
+    assert(RefExpr && "NULL expr in OpenMP aligned clause.");
+    if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
+      // It will be analyzed later.
+      Vars.push_back(RefExpr);
+      continue;
+    }
+
+    SourceLocation ELoc = RefExpr->getExprLoc();
+    // OpenMP [2.1, C/C++]
+    //  A list item is a variable name.
+    DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr);
+    if (!DE || !isa<VarDecl>(DE->getDecl())) {
+      Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
+      continue;
+    }
+
+    VarDecl *VD = cast<VarDecl>(DE->getDecl());
+
+    // OpenMP  [2.8.1, simd construct, Restrictions]
+    // The type of list items appearing in the aligned clause must be
+    // array, pointer, reference to array, or reference to pointer.
+    QualType QType = DE->getType()
+                         .getNonReferenceType()
+                         .getUnqualifiedType()
+                         .getCanonicalType();
+    const Type *Ty = QType.getTypePtrOrNull();
+    if (!Ty || (!Ty->isDependentType() && !Ty->isArrayType() &&
+                !Ty->isPointerType())) {
+      Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
+          << QType << getLangOpts().CPlusPlus << RefExpr->getSourceRange();
+      bool IsDecl =
+          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+      Diag(VD->getLocation(),
+           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+          << VD;
+      continue;
+    }
+
+    // OpenMP  [2.8.1, simd construct, Restrictions]
+    // A list-item cannot appear in more than one aligned clause.
+    if (DeclRefExpr *PrevRef = DSAStack->addUniqueAligned(VD, DE)) {
+      Diag(ELoc, diag::err_omp_aligned_twice) << RefExpr->getSourceRange();
+      Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
+          << getOpenMPClauseName(OMPC_aligned);
+      continue;
+    }
+
+    Vars.push_back(DE);
+  }
+
+  // OpenMP [2.8.1, simd construct, Description]
+  // The parameter of the aligned clause, alignment, must be a constant
+  // positive integer expression.
+  // If no optional parameter is specified, implementation-defined default
+  // alignments for SIMD instructions on the target platforms are assumed.
+  if (Alignment != nullptr) {
+    ExprResult AlignResult =
+        VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
+    if (AlignResult.isInvalid())
+      return nullptr;
+    Alignment = AlignResult.get();
+  }
+  if (Vars.empty())
+    return nullptr;
+
+  return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
+                                  EndLoc, Vars, Alignment);
+}
+
+OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
+                                         SourceLocation StartLoc,
+                                         SourceLocation LParenLoc,
+                                         SourceLocation EndLoc) {
+  SmallVector<Expr *, 8> Vars;
+  for (auto &RefExpr : VarList) {
+    assert(RefExpr && "NULL expr in OpenMP copyin clause.");
+    if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
+      // It will be analyzed later.
+      Vars.push_back(RefExpr);
+      continue;
+    }
+
+    SourceLocation ELoc = RefExpr->getExprLoc();
+    // OpenMP [2.1, C/C++]
+    //  A list item is a variable name.
+    // OpenMP  [2.14.4.1, Restrictions, p.1]
+    //  A list item that appears in a copyin clause must be threadprivate.
+    DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr);
+    if (!DE || !isa<VarDecl>(DE->getDecl())) {
+      Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
+      continue;
+    }
+
+    Decl *D = DE->getDecl();
+    VarDecl *VD = cast<VarDecl>(D);
+
+    QualType Type = VD->getType();
+    if (Type->isDependentType() || Type->isInstantiationDependentType()) {
+      // It will be analyzed later.
+      Vars.push_back(DE);
+      continue;
+    }
+
+    // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
+    //  A list item that appears in a copyin clause must be threadprivate.
+    if (!DSAStack->isThreadPrivate(VD)) {
+      Diag(ELoc, diag::err_omp_required_access)
+          << getOpenMPClauseName(OMPC_copyin)
+          << getOpenMPDirectiveName(OMPD_threadprivate);
+      continue;
+    }
+
+    // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
+    //  A variable of class type (or array thereof) that appears in a
+    //  copyin clause requires an accessible, unambiguous copy assignment
+    //  operator for the class type.
+    Type = Context.getBaseElementType(Type);
+    CXXRecordDecl *RD =
+        getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr;
+    // FIXME This code must be replaced by actual assignment of the
+    // threadprivate variable.
+    if (RD) {
+      CXXMethodDecl *MD = LookupCopyingAssignment(RD, 0, false, 0);
+      DeclAccessPair FoundDecl = DeclAccessPair::make(MD, MD->getAccess());
+      if (MD) {
+        if (CheckMemberAccess(ELoc, RD, FoundDecl) == AR_inaccessible ||
+            MD->isDeleted()) {
+          Diag(ELoc, diag::err_omp_required_method)
+              << getOpenMPClauseName(OMPC_copyin) << 2;
+          bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
+                        VarDecl::DeclarationOnly;
+          Diag(VD->getLocation(),
+               IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+              << VD;
+          Diag(RD->getLocation(), diag::note_previous_decl) << RD;
+          continue;
+        }
+        MarkFunctionReferenced(ELoc, MD);
+        DiagnoseUseOfDecl(MD, ELoc);
+      }
+    }
+
+    DSAStack->addDSA(VD, DE, OMPC_copyin);
+    Vars.push_back(DE);
+  }
+
+  if (Vars.empty())
+    return nullptr;
+
+  return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
+}
+
+OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
+                                              SourceLocation StartLoc,
+                                              SourceLocation LParenLoc,
+                                              SourceLocation EndLoc) {
+  SmallVector<Expr *, 8> Vars;
+  for (auto &RefExpr : VarList) {
+    assert(RefExpr && "NULL expr in OpenMP copyprivate clause.");
+    if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
+      // It will be analyzed later.
+      Vars.push_back(RefExpr);
+      continue;
+    }
+
+    SourceLocation ELoc = RefExpr->getExprLoc();
+    // OpenMP [2.1, C/C++]
+    //  A list item is a variable name.
+    // OpenMP  [2.14.4.1, Restrictions, p.1]
+    //  A list item that appears in a copyin clause must be threadprivate.
+    DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr);
+    if (!DE || !isa<VarDecl>(DE->getDecl())) {
+      Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
+      continue;
+    }
+
+    Decl *D = DE->getDecl();
+    VarDecl *VD = cast<VarDecl>(D);
+
+    QualType Type = VD->getType();
+    if (Type->isDependentType() || Type->isInstantiationDependentType()) {
+      // It will be analyzed later.
+      Vars.push_back(DE);
+      continue;
+    }
+
+    // OpenMP [2.14.4.2, Restrictions, p.2]
+    //  A list item that appears in a copyprivate clause may not appear in a
+    //  private or firstprivate clause on the single construct.
+    if (!DSAStack->isThreadPrivate(VD)) {
+      auto DVar = DSAStack->getTopDSA(VD, false);
+      if (DVar.CKind != OMPC_copyprivate && DVar.CKind != OMPC_unknown &&
+          !(DVar.CKind == OMPC_private && !DVar.RefExpr)) {
+        Diag(ELoc, diag::err_omp_wrong_dsa)
+            << getOpenMPClauseName(DVar.CKind)
+            << getOpenMPClauseName(OMPC_copyprivate);
+        ReportOriginalDSA(*this, DSAStack, VD, DVar);
+        continue;
+      }
+
+      // OpenMP [2.11.4.2, Restrictions, p.1]
+      //  All list items that appear in a copyprivate clause must be either
+      //  threadprivate or private in the enclosing context.
+      if (DVar.CKind == OMPC_unknown) {
+        DVar = DSAStack->getImplicitDSA(VD, false);
+        if (DVar.CKind == OMPC_shared) {
+          Diag(ELoc, diag::err_omp_required_access)
+              << getOpenMPClauseName(OMPC_copyprivate)
+              << "threadprivate or private in the enclosing context";
+          ReportOriginalDSA(*this, DSAStack, VD, DVar);
+          continue;
+        }
+      }
+    }
+
+    // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
+    //  A variable of class type (or array thereof) that appears in a
+    //  copyin clause requires an accessible, unambiguous copy assignment
+    //  operator for the class type.
+    Type = Context.getBaseElementType(Type);
+    CXXRecordDecl *RD =
+        getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr;
+    // FIXME This code must be replaced by actual assignment of the
+    // threadprivate variable.
+    if (RD) {
+      CXXMethodDecl *MD = LookupCopyingAssignment(RD, 0, false, 0);
+      DeclAccessPair FoundDecl = DeclAccessPair::make(MD, MD->getAccess());
+      if (MD) {
+        if (CheckMemberAccess(ELoc, RD, FoundDecl) == AR_inaccessible ||
+            MD->isDeleted()) {
+          Diag(ELoc, diag::err_omp_required_method)
+              << getOpenMPClauseName(OMPC_copyprivate) << 2;
+          bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
+                        VarDecl::DeclarationOnly;
+          Diag(VD->getLocation(),
+               IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+              << VD;
+          Diag(RD->getLocation(), diag::note_previous_decl) << RD;
+          continue;
+        }
+        MarkFunctionReferenced(ELoc, MD);
+        DiagnoseUseOfDecl(MD, ELoc);
+      }
+    }
+
+    // No need to mark vars as copyprivate, they are already threadprivate or
+    // implicitly private.
+    Vars.push_back(DE);
+  }
+
+  if (Vars.empty())
+    return nullptr;
+
+  return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
+}
+
+OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
+                                        SourceLocation StartLoc,
+                                        SourceLocation LParenLoc,
+                                        SourceLocation EndLoc) {
+  if (VarList.empty())
+    return nullptr;
+
+  return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
+}
+
 #undef DSAStack
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 802f2b7..03001d8 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -20,9 +20,9 @@
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/TypeOrdering.h"
 #include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/PartialDiagnostic.h"
 #include "clang/Basic/TargetInfo.h"
-#include "clang/Lex/Preprocessor.h"
 #include "clang/Sema/Initialization.h"
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/SemaInternal.h"
@@ -33,6 +33,7 @@
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallString.h"
 #include <algorithm>
+#include <cstdlib>
 
 namespace clang {
 using namespace sema;
@@ -60,8 +61,8 @@
 
   S.MarkDeclRefReferenced(DRE);
 
-  ExprResult E = S.Owned(DRE);
-  E = S.DefaultFunctionArrayConversion(E.take());
+  ExprResult E = DRE;
+  E = S.DefaultFunctionArrayConversion(E.get());
   if (E.isInvalid())
     return ExprError();
   return E;
@@ -215,7 +216,7 @@
   BindsToRvalue = false;
   BindsImplicitObjectArgumentWithoutRefQualifier = false;
   ObjCLifetimeConversionBinding = false;
-  CopyConstructor = 0;
+  CopyConstructor = nullptr;
 }
 
 /// getRank - Retrieve the rank of this standard conversion sequence
@@ -573,7 +574,7 @@
   DeductionFailureInfo Result;
   Result.Result = static_cast<unsigned>(TDK);
   Result.HasDiagnostic = false;
-  Result.Data = 0;
+  Result.Data = nullptr;
   switch (TDK) {
   case Sema::TDK_Success:
   case Sema::TDK_Invalid:
@@ -644,12 +645,12 @@
   case Sema::TDK_Underqualified:
   case Sema::TDK_NonDeducedMismatch:
     // FIXME: Destroy the data?
-    Data = 0;
+    Data = nullptr;
     break;
 
   case Sema::TDK_SubstitutionFailure:
     // FIXME: Destroy the template argument list?
-    Data = 0;
+    Data = nullptr;
     if (PartialDiagnosticAt *Diag = getSFINAEDiagnostic()) {
       Diag->~PartialDiagnosticAt();
       HasDiagnostic = false;
@@ -665,7 +666,7 @@
 PartialDiagnosticAt *DeductionFailureInfo::getSFINAEDiagnostic() {
   if (HasDiagnostic)
     return static_cast<PartialDiagnosticAt*>(static_cast<void*>(Diagnostic));
-  return 0;
+  return nullptr;
 }
 
 TemplateParameter DeductionFailureInfo::getTemplateParameter() {
@@ -709,7 +710,7 @@
   case Sema::TDK_Underqualified:
   case Sema::TDK_NonDeducedMismatch:
   case Sema::TDK_FailedOverloadResolution:
-    return 0;
+    return nullptr;
 
   case Sema::TDK_SubstitutionFailure:
     return static_cast<TemplateArgumentList*>(Data);
@@ -719,7 +720,7 @@
     break;
   }
 
-  return 0;
+  return nullptr;
 }
 
 const TemplateArgument *DeductionFailureInfo::getFirstArg() {
@@ -733,7 +734,7 @@
   case Sema::TDK_InvalidExplicitArguments:
   case Sema::TDK_SubstitutionFailure:
   case Sema::TDK_FailedOverloadResolution:
-    return 0;
+    return nullptr;
 
   case Sema::TDK_Inconsistent:
   case Sema::TDK_Underqualified:
@@ -745,7 +746,7 @@
     break;
   }
 
-  return 0;
+  return nullptr;
 }
 
 const TemplateArgument *DeductionFailureInfo::getSecondArg() {
@@ -759,7 +760,7 @@
   case Sema::TDK_InvalidExplicitArguments:
   case Sema::TDK_SubstitutionFailure:
   case Sema::TDK_FailedOverloadResolution:
-    return 0;
+    return nullptr;
 
   case Sema::TDK_Inconsistent:
   case Sema::TDK_Underqualified:
@@ -771,7 +772,7 @@
     break;
   }
 
-  return 0;
+  return nullptr;
 }
 
 Expr *DeductionFailureInfo::getExpr() {
@@ -779,7 +780,7 @@
         Sema::TDK_FailedOverloadResolution)
     return static_cast<Expr*>(Data);
 
-  return 0;
+  return nullptr;
 }
 
 void OverloadCandidateSet::destroyCandidates() {
@@ -829,8 +830,9 @@
 ///   without this, they will be immediately diagnosed as errors
 ///
 /// Return true on unrecoverable error.
-static bool checkPlaceholderForOverload(Sema &S, Expr *&E,
-                                        UnbridgedCastsSet *unbridgedCasts = 0) {
+static bool
+checkPlaceholderForOverload(Sema &S, Expr *&E,
+                            UnbridgedCastsSet *unbridgedCasts = nullptr) {
   if (const BuiltinType *placeholder =  E->getType()->getAsPlaceholderType()) {
     // We can't handle overloaded expressions here because overload
     // resolution might reasonably tweak them.
@@ -849,7 +851,7 @@
     if (result.isInvalid())
       return true;
 
-    E = result.take();
+    E = result.get();
     return false;
   }
 
@@ -930,24 +932,15 @@
       (OldIsUsingDecl || NewIsUsingDecl) && CurContext->isRecord() &&
       !New->getFriendObjectKind();
 
-    if (FunctionTemplateDecl *OldT = dyn_cast<FunctionTemplateDecl>(OldD)) {
-      if (!IsOverload(New, OldT->getTemplatedDecl(), UseMemberUsingDeclRules)) {
-        if (UseMemberUsingDeclRules && OldIsUsingDecl) {
-          HideUsingShadowDecl(S, cast<UsingShadowDecl>(*I));
-          continue;
-        }
-
-        Match = *I;
-        return Ovl_Match;
-      }
-    } else if (FunctionDecl *OldF = dyn_cast<FunctionDecl>(OldD)) {
+    if (FunctionDecl *OldF = OldD->getAsFunction()) {
       if (!IsOverload(New, OldF, UseMemberUsingDeclRules)) {
         if (UseMemberUsingDeclRules && OldIsUsingDecl) {
           HideUsingShadowDecl(S, cast<UsingShadowDecl>(*I));
           continue;
         }
 
-        if (!shouldLinkPossiblyHiddenDecl(*I, New))
+        if (!isa<FunctionTemplateDecl>(OldD) &&
+            !shouldLinkPossiblyHiddenDecl(*I, New))
           continue;
 
         Match = *I;
@@ -991,7 +984,7 @@
   // C++ [temp.fct]p2:
   //   A function template can be overloaded with other function templates
   //   and with normal (non-template) functions.
-  if ((OldTemplate == 0) != (NewTemplate == 0))
+  if ((OldTemplate == nullptr) != (NewTemplate == nullptr))
     return true;
 
   // Is the function New an overload of the function Old?
@@ -1008,16 +1001,16 @@
       isa<FunctionNoProtoType>(NewQType.getTypePtr()))
     return false;
 
-  const FunctionProtoType* OldType = cast<FunctionProtoType>(OldQType);
-  const FunctionProtoType* NewType = cast<FunctionProtoType>(NewQType);
+  const FunctionProtoType *OldType = cast<FunctionProtoType>(OldQType);
+  const FunctionProtoType *NewType = cast<FunctionProtoType>(NewQType);
 
   // The signature of a function includes the types of its
   // parameters (C++ 1.3.10), which includes the presence or absence
   // of the ellipsis; see C++ DR 357).
   if (OldQType != NewQType &&
-      (OldType->getNumArgs() != NewType->getNumArgs() ||
+      (OldType->getNumParams() != NewType->getNumParams() ||
        OldType->isVariadic() != NewType->isVariadic() ||
-       !FunctionArgTypesAreEqual(OldType, NewType)))
+       !FunctionParamTypesAreEqual(OldType, NewType)))
     return true;
 
   // C++ [temp.over.link]p4:
@@ -1036,7 +1029,7 @@
       (!TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(),
                                        OldTemplate->getTemplateParameters(),
                                        false, TPL_TemplateMatch) ||
-       OldType->getResultType() != NewType->getResultType()))
+       OldType->getReturnType() != NewType->getReturnType()))
     return true;
 
   // If the function is a class member, its signature includes the
@@ -1085,6 +1078,22 @@
       return true;
   }
 
+  // enable_if attributes are an order-sensitive part of the signature.
+  for (specific_attr_iterator<EnableIfAttr>
+         NewI = New->specific_attr_begin<EnableIfAttr>(),
+         NewE = New->specific_attr_end<EnableIfAttr>(),
+         OldI = Old->specific_attr_begin<EnableIfAttr>(),
+         OldE = Old->specific_attr_end<EnableIfAttr>();
+       NewI != NewE || OldI != OldE; ++NewI, ++OldI) {
+    if (NewI == NewE || OldI == OldE)
+      return true;
+    llvm::FoldingSetNodeID NewID, OldID;
+    NewI->getCond()->Profile(NewID, Context, true);
+    OldI->getCond()->Profile(OldID, Context, true);
+    if (NewID != OldID)
+      return true;
+  }
+
   // The signatures match; this is not an overload.
   return false;
 }
@@ -1120,13 +1129,15 @@
   }
 
   // Attempt user-defined conversion.
-  OverloadCandidateSet Conversions(From->getExprLoc());
+  OverloadCandidateSet Conversions(From->getExprLoc(),
+                                   OverloadCandidateSet::CSK_Normal);
   OverloadingResult UserDefResult
     = IsUserDefinedConversion(S, From, ToType, ICS.UserDefined, Conversions,
                               AllowExplicit, AllowObjCConversionOnExplicit);
 
   if (UserDefResult == OR_Success) {
     ICS.setUserDefined();
+    ICS.UserDefined.Before.setAsIdentityConversion();
     // C++ [over.ics.user]p4:
     //   A conversion of an expression of class type to the same class
     //   type is given Exact Match rank, and a conversion of an
@@ -1153,17 +1164,6 @@
           ICS.Standard.Second = ICK_Derived_To_Base;
       }
     }
-
-    // C++ [over.best.ics]p4:
-    //   However, when considering the argument of a user-defined
-    //   conversion function that is a candidate by 13.3.1.3 when
-    //   invoked for the copying of the temporary in the second step
-    //   of a class copy-initialization, or by 13.3.1.4, 13.3.1.5, or
-    //   13.3.1.6 in all cases, only standard conversion sequences and
-    //   ellipsis conversion sequences are allowed.
-    if (SuppressUserConversions && ICS.isUserDefined()) {
-      ICS.setBad(BadConversionSequence::suppressed_user, From, ToType);
-    }
   } else if (UserDefResult == OR_Ambiguous && !SuppressUserConversions) {
     ICS.setAmbiguous();
     ICS.Ambiguous.setFromType(From->getType());
@@ -1246,7 +1246,7 @@
     // copy/move constructor, since overloading just assumes that it
     // exists. When we actually perform initialization, we'll find the
     // appropriate constructor to copy the returned object, if needed.
-    ICS.Standard.CopyConstructor = 0;
+    ICS.Standard.CopyConstructor = nullptr;
 
     // Determine whether this is considered a derived-to-base conversion.
     if (!S.Context.hasSameUnqualifiedType(FromType, ToType))
@@ -1298,7 +1298,9 @@
   bool AllowObjCWritebackConversion
     = getLangOpts().ObjCAutoRefCount && 
       (Action == AA_Passing || Action == AA_Sending);
-
+  if (getLangOpts().ObjC1)
+    CheckObjCBridgeRelatedConversions(From->getLocStart(),
+                                      ToType, From->getType(), From);
   ICS = clang::TryImplicitConversion(*this, From, ToType,
                                      /*SuppressUserConversions=*/false,
                                      AllowExplicit,
@@ -1362,7 +1364,7 @@
 ///
 /// \param ICK Will be set to the vector conversion kind, if this is a vector
 /// conversion.
-static bool IsVectorConversion(ASTContext &Context, QualType FromType,
+static bool IsVectorConversion(Sema &S, QualType FromType,
                                QualType ToType, ImplicitConversionKind &ICK) {
   // We need at least one of these types to be a vector type to have a vector
   // conversion.
@@ -1370,7 +1372,7 @@
     return false;
 
   // Identical types require no conversions.
-  if (Context.hasSameUnqualifiedType(FromType, ToType))
+  if (S.Context.hasSameUnqualifiedType(FromType, ToType))
     return false;
 
   // There are no conversions between extended vector types, only identity.
@@ -1392,9 +1394,8 @@
   // 2)lax vector conversions are permitted and the vector types are of the
   //   same size
   if (ToType->isVectorType() && FromType->isVectorType()) {
-    if (Context.areCompatibleVectorTypes(FromType, ToType) ||
-        (Context.getLangOpts().LaxVectorConversions &&
-         (Context.getTypeSize(FromType) == Context.getTypeSize(ToType)))) {
+    if (S.Context.areCompatibleVectorTypes(FromType, ToType) ||
+        S.isLaxVectorConversion(FromType, ToType)) {
       ICK = ICK_Vector_Conversion;
       return true;
     }
@@ -1425,10 +1426,9 @@
 
   // Standard conversions (C++ [conv])
   SCS.setAsIdentityConversion();
-  SCS.DeprecatedStringLiteralToCharPtr = false;
   SCS.IncompatibleObjC = false;
   SCS.setFromType(FromType);
-  SCS.CopyConstructor = 0;
+  SCS.CopyConstructor = nullptr;
 
   // There are no standard conversions for class types in C++, so
   // abort early. When overloading in C, however, we do permit
@@ -1524,7 +1524,7 @@
     FromType = S.Context.getArrayDecayedType(FromType);
 
     if (S.IsStringLiteralToNonConstPointerConversion(From, ToType)) {
-      // This conversion is deprecated. (C++ D.4).
+      // This conversion is deprecated in C++03 (D.4)
       SCS.DeprecatedStringLiteralToCharPtr = true;
 
       // For the purpose of ranking in overload resolution
@@ -1624,7 +1624,7 @@
                                          InOverloadResolution, FromType)) {
     // Pointer to member conversions (4.11).
     SCS.Second = ICK_Pointer_Member;
-  } else if (IsVectorConversion(S.Context, FromType, ToType, SecondICK)) {
+  } else if (IsVectorConversion(S, FromType, ToType, SecondICK)) {
     SCS.Second = SecondICK;
     FromType = ToType.getUnqualifiedType();
   } else if (!S.getLangOpts().CPlusPlus &&
@@ -1707,9 +1707,7 @@
   // The field to initialize within the transparent union.
   RecordDecl *UD = UT->getDecl();
   // It's compatible if the expression matches any of the fields.
-  for (RecordDecl::field_iterator it = UD->field_begin(),
-       itend = UD->field_end();
-       it != itend; ++it) {
+  for (const auto *it : UD->fields()) {
     if (IsStandardConversion(S, From, it->getType(), InOverloadResolution, SCS,
                              CStyle, /*ObjCWritebackConversion=*/false)) {
       ToType = it->getType();
@@ -1914,7 +1912,7 @@
 
   return IsFloatingPointPromotion(FromComplex->getElementType(),
                                   ToComplex->getElementType()) ||
-    IsIntegralPromotion(0, FromComplex->getElementType(),
+    IsIntegralPromotion(nullptr, FromComplex->getElementType(),
                         ToComplex->getElementType());
 }
 
@@ -2288,17 +2286,17 @@
 
     // Perform the quick checks that will tell us whether these
     // function types are obviously different.
-    if (FromFunctionType->getNumArgs() != ToFunctionType->getNumArgs() ||
+    if (FromFunctionType->getNumParams() != ToFunctionType->getNumParams() ||
         FromFunctionType->isVariadic() != ToFunctionType->isVariadic() ||
         FromFunctionType->getTypeQuals() != ToFunctionType->getTypeQuals())
       return false;
 
     bool HasObjCConversion = false;
-    if (Context.getCanonicalType(FromFunctionType->getResultType())
-          == Context.getCanonicalType(ToFunctionType->getResultType())) {
+    if (Context.getCanonicalType(FromFunctionType->getReturnType()) ==
+        Context.getCanonicalType(ToFunctionType->getReturnType())) {
       // Okay, the types match exactly. Nothing to do.
-    } else if (isObjCPointerConversion(FromFunctionType->getResultType(),
-                                       ToFunctionType->getResultType(),
+    } else if (isObjCPointerConversion(FromFunctionType->getReturnType(),
+                                       ToFunctionType->getReturnType(),
                                        ConvertedType, IncompatibleObjC)) {
       // Okay, we have an Objective-C pointer conversion.
       HasObjCConversion = true;
@@ -2308,10 +2306,10 @@
     }
 
     // Check argument types.
-    for (unsigned ArgIdx = 0, NumArgs = FromFunctionType->getNumArgs();
+    for (unsigned ArgIdx = 0, NumArgs = FromFunctionType->getNumParams();
          ArgIdx != NumArgs; ++ArgIdx) {
-      QualType FromArgType = FromFunctionType->getArgType(ArgIdx);
-      QualType ToArgType = ToFunctionType->getArgType(ArgIdx);
+      QualType FromArgType = FromFunctionType->getParamType(ArgIdx);
+      QualType ToArgType = ToFunctionType->getParamType(ArgIdx);
       if (Context.getCanonicalType(FromArgType)
             == Context.getCanonicalType(ToArgType)) {
         // Okay, the types match exactly. Nothing to do.
@@ -2436,7 +2434,7 @@
     
   // Perform the quick checks that will tell us whether these
   // function types are obviously different.
-  if (FromFunctionType->getNumArgs() != ToFunctionType->getNumArgs() ||
+  if (FromFunctionType->getNumParams() != ToFunctionType->getNumParams() ||
       FromFunctionType->isVariadic() != ToFunctionType->isVariadic())
     return false;
     
@@ -2446,12 +2444,12 @@
     return false;
 
   bool IncompatibleObjC = false;
-  if (Context.hasSameType(FromFunctionType->getResultType(), 
-                          ToFunctionType->getResultType())) {
+  if (Context.hasSameType(FromFunctionType->getReturnType(),
+                          ToFunctionType->getReturnType())) {
     // Okay, the types match exactly. Nothing to do.
   } else {
-    QualType RHS = FromFunctionType->getResultType();
-    QualType LHS = ToFunctionType->getResultType();
+    QualType RHS = FromFunctionType->getReturnType();
+    QualType LHS = ToFunctionType->getReturnType();
     if ((!getLangOpts().CPlusPlus || !RHS->isRecordType()) &&
         !RHS.hasQualifiers() && LHS.hasQualifiers())
        LHS = LHS.getUnqualifiedType();
@@ -2469,11 +2467,11 @@
    }
     
    // Check argument types.
-   for (unsigned ArgIdx = 0, NumArgs = FromFunctionType->getNumArgs();
+   for (unsigned ArgIdx = 0, NumArgs = FromFunctionType->getNumParams();
         ArgIdx != NumArgs; ++ArgIdx) {
      IncompatibleObjC = false;
-     QualType FromArgType = FromFunctionType->getArgType(ArgIdx);
-     QualType ToArgType = ToFunctionType->getArgType(ArgIdx);
+     QualType FromArgType = FromFunctionType->getParamType(ArgIdx);
+     QualType ToArgType = ToFunctionType->getParamType(ArgIdx);
      if (Context.hasSameType(FromArgType, ToArgType)) {
        // Okay, the types match exactly. Nothing to do.
      } else if (isObjCPointerConversion(ToArgType, FromArgType,
@@ -2518,7 +2516,7 @@
   if (FromType->isMemberPointerType() && ToType->isMemberPointerType()) {
     const MemberPointerType *FromMember = FromType->getAs<MemberPointerType>(),
                             *ToMember = ToType->getAs<MemberPointerType>();
-    if (FromMember->getClass() != ToMember->getClass()) {
+    if (!Context.hasSameType(FromMember->getClass(), ToMember->getClass())) {
       PDiag << ft_different_class << QualType(ToMember->getClass(), 0)
             << QualType(FromMember->getClass(), 0);
       return;
@@ -2558,26 +2556,26 @@
     return;
   }
 
-  if (FromFunction->getNumArgs() != ToFunction->getNumArgs()) {
-    PDiag << ft_parameter_arity << ToFunction->getNumArgs()
-          << FromFunction->getNumArgs();
+  if (FromFunction->getNumParams() != ToFunction->getNumParams()) {
+    PDiag << ft_parameter_arity << ToFunction->getNumParams()
+          << FromFunction->getNumParams();
     return;
   }
 
   // Handle different parameter types.
   unsigned ArgPos;
-  if (!FunctionArgTypesAreEqual(FromFunction, ToFunction, &ArgPos)) {
+  if (!FunctionParamTypesAreEqual(FromFunction, ToFunction, &ArgPos)) {
     PDiag << ft_parameter_mismatch << ArgPos + 1
-          << ToFunction->getArgType(ArgPos)
-          << FromFunction->getArgType(ArgPos);
+          << ToFunction->getParamType(ArgPos)
+          << FromFunction->getParamType(ArgPos);
     return;
   }
 
   // Handle different return type.
-  if (!Context.hasSameType(FromFunction->getResultType(),
-                           ToFunction->getResultType())) {
-    PDiag << ft_return_type << ToFunction->getResultType()
-          << FromFunction->getResultType();
+  if (!Context.hasSameType(FromFunction->getReturnType(),
+                           ToFunction->getReturnType())) {
+    PDiag << ft_return_type << ToFunction->getReturnType()
+          << FromFunction->getReturnType();
     return;
   }
 
@@ -2592,19 +2590,21 @@
   PDiag << ft_default;
 }
 
-/// FunctionArgTypesAreEqual - This routine checks two function proto types
+/// FunctionParamTypesAreEqual - This routine checks two function proto types
 /// for equality of their argument types. Caller has already checked that
 /// they have same number of arguments.  If the parameters are different,
 /// ArgPos will have the parameter index of the first different parameter.
-bool Sema::FunctionArgTypesAreEqual(const FunctionProtoType *OldType,
-                                    const FunctionProtoType *NewType,
-                                    unsigned *ArgPos) {
-  for (FunctionProtoType::arg_type_iterator O = OldType->arg_type_begin(),
-       N = NewType->arg_type_begin(),
-       E = OldType->arg_type_end(); O && (O != E); ++O, ++N) {
+bool Sema::FunctionParamTypesAreEqual(const FunctionProtoType *OldType,
+                                      const FunctionProtoType *NewType,
+                                      unsigned *ArgPos) {
+  for (FunctionProtoType::param_type_iterator O = OldType->param_type_begin(),
+                                              N = NewType->param_type_begin(),
+                                              E = OldType->param_type_end();
+       O && (O != E); ++O, ++N) {
     if (!Context.hasSameType(O->getUnqualifiedType(),
                              N->getUnqualifiedType())) {
-      if (ArgPos) *ArgPos = O - OldType->arg_type_begin();
+      if (ArgPos)
+        *ArgPos = O - OldType->param_type_begin();
       return false;
     }
   }
@@ -2919,8 +2919,8 @@
                                               QualType Type) {
   const FunctionProtoType *CtorType =
       Constructor->getType()->getAs<FunctionProtoType>();
-  if (CtorType->getNumArgs() > 0) {
-    QualType FirstArg = CtorType->getArgType(0);
+  if (CtorType->getNumParams() > 0) {
+    QualType FirstArg = CtorType->getParamType(0);
     if (Context.hasSameUnqualifiedType(Type, FirstArg.getNonReferenceType()))
       return true;
   }
@@ -2940,7 +2940,7 @@
     DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess());
 
     // Find the constructor (which may be a template).
-    CXXConstructorDecl *Constructor = 0;
+    CXXConstructorDecl *Constructor = nullptr;
     FunctionTemplateDecl *ConstructorTmpl
       = dyn_cast<FunctionTemplateDecl>(D);
     if (ConstructorTmpl)
@@ -2959,7 +2959,7 @@
           isFirstArgumentCompatibleWithType(S.Context, Constructor, ToType);
       if (ConstructorTmpl)
         S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl,
-                                       /*ExplicitArgs*/ 0,
+                                       /*ExplicitArgs*/ nullptr,
                                        From, CandidateSet,
                                        SuppressUserConversions);
       else
@@ -3075,7 +3075,7 @@
         DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess());
 
         // Find the constructor (which may be a template).
-        CXXConstructorDecl *Constructor = 0;
+        CXXConstructorDecl *Constructor = nullptr;
         FunctionTemplateDecl *ConstructorTmpl
           = dyn_cast<FunctionTemplateDecl>(D);
         if (ConstructorTmpl)
@@ -3102,7 +3102,7 @@
           }
           if (ConstructorTmpl)
             S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl,
-                                           /*ExplicitArgs*/ 0,
+                                           /*ExplicitArgs*/ nullptr,
                                            llvm::makeArrayRef(Args, NumArgs),
                                            CandidateSet, SuppressUserConversions);
           else
@@ -3236,23 +3236,21 @@
 bool
 Sema::DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType) {
   ImplicitConversionSequence ICS;
-  OverloadCandidateSet CandidateSet(From->getExprLoc());
+  OverloadCandidateSet CandidateSet(From->getExprLoc(),
+                                    OverloadCandidateSet::CSK_Normal);
   OverloadingResult OvResult =
     IsUserDefinedConversion(*this, From, ToType, ICS.UserDefined,
                             CandidateSet, false, false);
   if (OvResult == OR_Ambiguous)
-    Diag(From->getLocStart(),
-         diag::err_typecheck_ambiguous_condition)
-          << From->getType() << ToType << From->getSourceRange();
+    Diag(From->getLocStart(), diag::err_typecheck_ambiguous_condition)
+        << From->getType() << ToType << From->getSourceRange();
   else if (OvResult == OR_No_Viable_Function && !CandidateSet.empty()) {
     if (!RequireCompleteType(From->getLocStart(), ToType,
-                          diag::err_typecheck_nonviable_condition_incomplete,
+                             diag::err_typecheck_nonviable_condition_incomplete,
                              From->getType(), From->getSourceRange()))
-      Diag(From->getLocStart(),
-           diag::err_typecheck_nonviable_condition)
-           << From->getType() << From->getSourceRange() << ToType;
-  }
-  else
+      Diag(From->getLocStart(), diag::err_typecheck_nonviable_condition)
+          << From->getType() << From->getSourceRange() << ToType;
+  } else
     return false;
   CandidateSet.NoteCandidates(*this, OCD_AllCandidates, From);
   return true;
@@ -3262,37 +3260,43 @@
 /// of two user-defined conversion sequences to determine whether any ordering
 /// is possible.
 static ImplicitConversionSequence::CompareKind
-compareConversionFunctions(Sema &S,
-                           FunctionDecl *Function1,
+compareConversionFunctions(Sema &S, FunctionDecl *Function1,
                            FunctionDecl *Function2) {
   if (!S.getLangOpts().ObjC1 || !S.getLangOpts().CPlusPlus11)
     return ImplicitConversionSequence::Indistinguishable;
-  
+
   // Objective-C++:
   //   If both conversion functions are implicitly-declared conversions from
-  //   a lambda closure type to a function pointer and a block pointer, 
+  //   a lambda closure type to a function pointer and a block pointer,
   //   respectively, always prefer the conversion to a function pointer,
   //   because the function pointer is more lightweight and is more likely
   //   to keep code working.
-  CXXConversionDecl *Conv1 = dyn_cast<CXXConversionDecl>(Function1);
+  CXXConversionDecl *Conv1 = dyn_cast_or_null<CXXConversionDecl>(Function1);
   if (!Conv1)
     return ImplicitConversionSequence::Indistinguishable;
-    
+
   CXXConversionDecl *Conv2 = dyn_cast<CXXConversionDecl>(Function2);
   if (!Conv2)
     return ImplicitConversionSequence::Indistinguishable;
-  
+
   if (Conv1->getParent()->isLambda() && Conv2->getParent()->isLambda()) {
     bool Block1 = Conv1->getConversionType()->isBlockPointerType();
     bool Block2 = Conv2->getConversionType()->isBlockPointerType();
     if (Block1 != Block2)
-      return Block1? ImplicitConversionSequence::Worse 
-                   : ImplicitConversionSequence::Better;
+      return Block1 ? ImplicitConversionSequence::Worse
+                    : ImplicitConversionSequence::Better;
   }
 
   return ImplicitConversionSequence::Indistinguishable;
 }
-  
+
+static bool hasDeprecatedStringLiteralToCharPtrConversion(
+    const ImplicitConversionSequence &ICS) {
+  return (ICS.isStandard() && ICS.Standard.DeprecatedStringLiteralToCharPtr) ||
+         (ICS.isUserDefined() &&
+          ICS.UserDefined.Before.DeprecatedStringLiteralToCharPtr);
+}
+
 /// CompareImplicitConversionSequences - Compare two implicit
 /// conversion sequences to determine whether one is better than the
 /// other or if they are indistinguishable (C++ 13.3.3.2).
@@ -3315,6 +3319,32 @@
   //   described in 13.3.3.2, the ambiguous conversion sequence is
   //   treated as a user-defined sequence that is indistinguishable
   //   from any other user-defined conversion sequence.
+
+  // String literal to 'char *' conversion has been deprecated in C++03. It has
+  // been removed from C++11. We still accept this conversion, if it happens at
+  // the best viable function. Otherwise, this conversion is considered worse
+  // than ellipsis conversion. Consider this as an extension; this is not in the
+  // standard. For example:
+  //
+  // int &f(...);    // #1
+  // void f(char*);  // #2
+  // void g() { int &r = f("foo"); }
+  //
+  // In C++03, we pick #2 as the best viable function.
+  // In C++11, we pick #1 as the best viable function, because ellipsis
+  // conversion is better than string-literal to char* conversion (since there
+  // is no such conversion in C++11). If there was no #1 at all or #1 couldn't
+  // convert arguments, #2 would be the best viable function in C++11.
+  // If the best viable function has this conversion, a warning will be issued
+  // in C++03, or an ExtWarn (+SFINAE failure) will be issued in C++11.
+
+  if (S.getLangOpts().CPlusPlus11 && !S.getLangOpts().WritableStrings &&
+      hasDeprecatedStringLiteralToCharPtrConversion(ICS1) !=
+      hasDeprecatedStringLiteralToCharPtrConversion(ICS2))
+    return hasDeprecatedStringLiteralToCharPtrConversion(ICS1)
+               ? ImplicitConversionSequence::Worse
+               : ImplicitConversionSequence::Better;
+
   if (ICS1.getKindRank() < ICS2.getKindRank())
     return ImplicitConversionSequence::Better;
   if (ICS2.getKindRank() < ICS1.getKindRank())
@@ -3424,8 +3454,9 @@
 
 /// \brief Determine whether one of the given reference bindings is better
 /// than the other based on what kind of bindings they are.
-static bool isBetterReferenceBindingKind(const StandardConversionSequence &SCS1,
-                                       const StandardConversionSequence &SCS2) {
+static bool
+isBetterReferenceBindingKind(const StandardConversionSequence &SCS1,
+                             const StandardConversionSequence &SCS2) {
   // C++0x [over.ics.rank]p3b4:
   //   -- S1 and S2 are reference bindings (8.5.3) and neither refers to an
   //      implicit object parameter of a non-static member function declared
@@ -3446,7 +3477,7 @@
   return (!SCS1.IsLvalueReference && SCS1.BindsToRvalue &&
           SCS2.IsLvalueReference) ||
          (SCS1.IsLvalueReference && SCS1.BindsToFunctionLvalue &&
-          !SCS2.IsLvalueReference);
+          !SCS2.IsLvalueReference && SCS2.BindsToFunctionLvalue);
 }
 
 /// CompareStandardConversionSequences - Compare two standard
@@ -3613,11 +3644,10 @@
   // }
   // Here, MSVC will call f(int) instead of generating a compile error
   // as clang will do in standard mode.
-  if (S.getLangOpts().MicrosoftMode &&
-      SCS1.Second == ICK_Integral_Conversion &&
-      SCS2.Second == ICK_Floating_Integral && 
+  if (S.getLangOpts().MSVCCompat && SCS1.Second == ICK_Integral_Conversion &&
+      SCS2.Second == ICK_Floating_Integral &&
       S.Context.getTypeSize(SCS1.getFromType()) ==
-      S.Context.getTypeSize(SCS1.getToType(2)))
+          S.Context.getTypeSize(SCS1.getToType(2)))
     return ImplicitConversionSequence::Better;
 
   return ImplicitConversionSequence::Indistinguishable;
@@ -4035,7 +4065,7 @@
   CXXRecordDecl *T2RecordDecl
     = dyn_cast<CXXRecordDecl>(T2->getAs<RecordType>()->getDecl());
 
-  OverloadCandidateSet CandidateSet(DeclLoc);
+  OverloadCandidateSet CandidateSet(DeclLoc, OverloadCandidateSet::CSK_Normal);
   std::pair<CXXRecordDecl::conversion_iterator,
             CXXRecordDecl::conversion_iterator>
     Conversions = T2RecordDecl->getVisibleConversionFunctions();
@@ -4226,7 +4256,8 @@
       ICS.Standard.BindsToRvalue = false;
       ICS.Standard.BindsImplicitObjectArgumentWithoutRefQualifier = false;
       ICS.Standard.ObjCLifetimeConversionBinding = ObjCLifetimeConversion;
-      ICS.Standard.CopyConstructor = 0;
+      ICS.Standard.CopyConstructor = nullptr;
+      ICS.Standard.DeprecatedStringLiteralToCharPtr = false;
 
       // Nothing more to do: the inaccessibility/ambiguity check for
       // derived-to-base conversions is suppressed when we're
@@ -4294,13 +4325,14 @@
     // standard library implementors; therefore, we need the xvalue check here.
     ICS.Standard.DirectBinding =
       S.getLangOpts().CPlusPlus11 ||
-      (InitCategory.isPRValue() && !T2->isRecordType());
+      !(InitCategory.isPRValue() || T2->isRecordType());
     ICS.Standard.IsLvalueReference = !isRValRef;
     ICS.Standard.BindsToFunctionLvalue = T2->isFunctionType();
     ICS.Standard.BindsToRvalue = InitCategory.isRValue();
     ICS.Standard.BindsImplicitObjectArgumentWithoutRefQualifier = false;
     ICS.Standard.ObjCLifetimeConversionBinding = ObjCLifetimeConversion;
-    ICS.Standard.CopyConstructor = 0;
+    ICS.Standard.CopyConstructor = nullptr;
+    ICS.Standard.DeprecatedStringLiteralToCharPtr = false;
     return ICS;
   }
 
@@ -4330,6 +4362,10 @@
     return ICS;
   }
 
+  // A temporary of function type cannot be created; don't even try.
+  if (T1->isFunctionType())
+    return ICS;
+
   //       -- Otherwise, a temporary of type "cv1 T1" is created and
   //          initialized from the initializer expression using the
   //          rules for a non-reference copy initialization (8.5). The
@@ -4391,28 +4427,34 @@
   if (ICS.isStandard()) {
     ICS.Standard.ReferenceBinding = true;
     ICS.Standard.IsLvalueReference = !isRValRef;
-    ICS.Standard.BindsToFunctionLvalue = T2->isFunctionType();
+    ICS.Standard.BindsToFunctionLvalue = false;
     ICS.Standard.BindsToRvalue = true;
     ICS.Standard.BindsImplicitObjectArgumentWithoutRefQualifier = false;
     ICS.Standard.ObjCLifetimeConversionBinding = false;
   } else if (ICS.isUserDefined()) {
-    // Don't allow rvalue references to bind to lvalues.
-    if (DeclType->isRValueReferenceType()) {
-      if (const ReferenceType *RefType
-            = ICS.UserDefined.ConversionFunction->getResultType()
-                ->getAs<LValueReferenceType>()) {
-        if (!RefType->getPointeeType()->isFunctionType()) {
-          ICS.setBad(BadConversionSequence::lvalue_ref_to_rvalue, Init, 
-                     DeclType);
-          return ICS;
-        }
-      }
+    const ReferenceType *LValRefType =
+        ICS.UserDefined.ConversionFunction->getReturnType()
+            ->getAs<LValueReferenceType>();
+
+    // C++ [over.ics.ref]p3:
+    //   Except for an implicit object parameter, for which see 13.3.1, a
+    //   standard conversion sequence cannot be formed if it requires [...]
+    //   binding an rvalue reference to an lvalue other than a function
+    //   lvalue.
+    // Note that the function case is not possible here.
+    if (DeclType->isRValueReferenceType() && LValRefType) {
+      // FIXME: This is the wrong BadConversionSequence. The problem is binding
+      // an rvalue reference to a (non-function) lvalue, not binding an lvalue
+      // reference to an rvalue!
+      ICS.setBad(BadConversionSequence::lvalue_ref_to_rvalue, Init, DeclType);
+      return ICS;
     }
-    
+
+    ICS.UserDefined.Before.setAsIdentityConversion();
     ICS.UserDefined.After.ReferenceBinding = true;
     ICS.UserDefined.After.IsLvalueReference = !isRValRef;
-    ICS.UserDefined.After.BindsToFunctionLvalue = T2->isFunctionType();
-    ICS.UserDefined.After.BindsToRvalue = true;
+    ICS.UserDefined.After.BindsToFunctionLvalue = false;
+    ICS.UserDefined.After.BindsToRvalue = !LValRefType;
     ICS.UserDefined.After.BindsImplicitObjectArgumentWithoutRefQualifier = false;
     ICS.UserDefined.After.ObjCLifetimeConversionBinding = false;
   }
@@ -4515,7 +4557,7 @@
     InitializedEntity Entity =
         InitializedEntity::InitializeParameter(S.Context, ToType,
                                                /*Consumed=*/false);
-    if (S.CanPerformCopyInitialization(Entity, S.Owned(From))) {
+    if (S.CanPerformCopyInitialization(Entity, From)) {
       Result.setUserDefined();
       Result.UserDefined.Before.setAsIdentityConversion();
       // Initializer lists don't have a type.
@@ -4525,7 +4567,7 @@
       Result.UserDefined.After.setAsIdentityConversion();
       Result.UserDefined.After.setFromType(ToType);
       Result.UserDefined.After.setAllToTypes(ToType);
-      Result.UserDefined.ConversionFunction = 0;
+      Result.UserDefined.ConversionFunction = nullptr;
     }
     return Result;
   }
@@ -4836,13 +4878,13 @@
       PerformObjectMemberConversion(From, Qualifier, FoundDecl, Method);
     if (FromRes.isInvalid())
       return ExprError();
-    From = FromRes.take();
+    From = FromRes.get();
   }
 
   if (!Context.hasSameType(From->getType(), DestType))
     From = ImpCastExprToType(From, DestType, CK_NoOp,
-                             From->getValueKind()).take();
-  return Owned(From);
+                             From->getValueKind()).get();
+  return From;
 }
 
 /// TryContextuallyConvertToBool - Attempt to contextually convert the
@@ -4954,7 +4996,7 @@
                           /*InOverloadResolution=*/false,
                           /*CStyle=*/false,
                           /*AllowObjcWritebackConversion=*/false);
-  StandardConversionSequence *SCS = 0;
+  StandardConversionSequence *SCS = nullptr;
   switch (ICS.getKind()) {
   case ImplicitConversionSequence::StandardConversion:
     if (!CheckConvertedConstantConversions(*this, ICS.Standard))
@@ -5124,7 +5166,7 @@
     QualType ConvTy = Conv->getConversionType().getNonReferenceType();
     Converter.noteAmbiguous(SemaRef, Conv, ConvTy);
   }
-  return SemaRef.Owned(From);
+  return From;
 }
 
 static bool
@@ -5147,7 +5189,7 @@
         << FixItHint::CreateInsertion(From->getLocStart(),
                                       "static_cast<" + TypeStr + ">(")
         << FixItHint::CreateInsertion(
-               SemaRef.PP.getLocForEndOfToken(From->getLocEnd()), ")");
+               SemaRef.getLocForEndOfToken(From->getLocEnd()), ")");
     Converter.noteExplicitConv(SemaRef, Conversion, ConvTy);
 
     // If we aren't in a SFINAE context, build a call to the
@@ -5155,15 +5197,15 @@
     if (SemaRef.isSFINAEContext())
       return true;
 
-    SemaRef.CheckMemberOperatorAccess(From->getExprLoc(), From, 0, Found);
+    SemaRef.CheckMemberOperatorAccess(From->getExprLoc(), From, nullptr, Found);
     ExprResult Result = SemaRef.BuildCXXMemberCallExpr(From, Found, Conversion,
                                                        HadMultipleCandidates);
     if (Result.isInvalid())
       return true;
     // Record usage of conversion in an implicit cast.
     From = ImplicitCastExpr::Create(SemaRef.Context, Result.get()->getType(),
-                                    CK_UserDefinedConversion, Result.get(), 0,
-                                    Result.get()->getValueKind());
+                                    CK_UserDefinedConversion, Result.get(),
+                                    nullptr, Result.get()->getValueKind());
   }
   return false;
 }
@@ -5174,7 +5216,7 @@
                              DeclAccessPair &Found) {
   CXXConversionDecl *Conversion =
       cast<CXXConversionDecl>(Found->getUnderlyingDecl());
-  SemaRef.CheckMemberOperatorAccess(From->getExprLoc(), From, 0, Found);
+  SemaRef.CheckMemberOperatorAccess(From->getExprLoc(), From, nullptr, Found);
 
   QualType ToType = Conversion->getConversionType().getNonReferenceType();
   if (!Converter.SuppressConversion) {
@@ -5191,8 +5233,8 @@
     return true;
   // Record usage of conversion in an implicit cast.
   From = ImplicitCastExpr::Create(SemaRef.Context, Result.get()->getType(),
-                                  CK_UserDefinedConversion, Result.get(), 0,
-                                  Result.get()->getValueKind());
+                                  CK_UserDefinedConversion, Result.get(),
+                                  nullptr, Result.get()->getValueKind());
   return false;
 }
 
@@ -5257,14 +5299,14 @@
     SourceLocation Loc, Expr *From, ContextualImplicitConverter &Converter) {
   // We can't perform any more checking for type-dependent expressions.
   if (From->isTypeDependent())
-    return Owned(From);
+    return From;
 
   // Process placeholders immediately.
   if (From->hasPlaceholderType()) {
     ExprResult result = CheckPlaceholderExpr(From);
     if (result.isInvalid())
       return result;
-    From = result.take();
+    From = result.get();
   }
 
   // If the expression already has a matching type, we're golden.
@@ -5280,7 +5322,7 @@
   if (!RecordTy || !getLangOpts().CPlusPlus) {
     if (!Converter.Suppress)
       Converter.diagnoseNoMatch(*this, Loc, T) << From->getSourceRange();
-    return Owned(From);
+    return From;
   }
 
   // We must have a complete class type.
@@ -5291,13 +5333,13 @@
     TypeDiagnoserPartialDiag(ContextualImplicitConverter &Converter, Expr *From)
         : TypeDiagnoser(Converter.Suppress), Converter(Converter), From(From) {}
 
-    virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) {
+    void diagnose(Sema &S, SourceLocation Loc, QualType T) override {
       Converter.diagnoseIncomplete(S, Loc, T) << From->getSourceRange();
     }
   } IncompleteDiagnoser(Converter, From);
 
   if (RequireCompleteType(Loc, T, IncompleteDiagnoser))
-    return Owned(From);
+    return From;
 
   // Look for a conversion to an integral or enumeration type.
   UnresolvedSet<4>
@@ -5381,7 +5423,7 @@
     // If one unique T is found:
     // First, build a candidate set from the previously recorded
     // potentially viable conversions.
-    OverloadCandidateSet CandidateSet(Loc);
+    OverloadCandidateSet CandidateSet(Loc, OverloadCandidateSet::CSK_Normal);
     collectViableConversionCandidates(*this, From, ToType, ViableConversions,
                                       CandidateSet);
 
@@ -5438,6 +5480,45 @@
   return finishContextualImplicitConversion(*this, Loc, From, Converter);
 }
 
+/// IsAcceptableNonMemberOperatorCandidate - Determine whether Fn is
+/// an acceptable non-member overloaded operator for a call whose
+/// arguments have types T1 (and, if non-empty, T2). This routine
+/// implements the check in C++ [over.match.oper]p3b2 concerning
+/// enumeration types.
+static bool IsAcceptableNonMemberOperatorCandidate(ASTContext &Context,
+                                                   FunctionDecl *Fn,
+                                                   ArrayRef<Expr *> Args) {
+  QualType T1 = Args[0]->getType();
+  QualType T2 = Args.size() > 1 ? Args[1]->getType() : QualType();
+
+  if (T1->isDependentType() || (!T2.isNull() && T2->isDependentType()))
+    return true;
+
+  if (T1->isRecordType() || (!T2.isNull() && T2->isRecordType()))
+    return true;
+
+  const FunctionProtoType *Proto = Fn->getType()->getAs<FunctionProtoType>();
+  if (Proto->getNumParams() < 1)
+    return false;
+
+  if (T1->isEnumeralType()) {
+    QualType ArgType = Proto->getParamType(0).getNonReferenceType();
+    if (Context.hasSameUnqualifiedType(T1, ArgType))
+      return true;
+  }
+
+  if (Proto->getNumParams() < 2)
+    return false;
+
+  if (!T2.isNull() && T2->isEnumeralType()) {
+    QualType ArgType = Proto->getParamType(1).getNonReferenceType();
+    if (Context.hasSameUnqualifiedType(T2, ArgType))
+      return true;
+  }
+
+  return false;
+}
+
 /// AddOverloadCandidate - Adds the given function to the set of
 /// candidate functions, using the given function call arguments.  If
 /// @p SuppressUserConversions, then don't allow user-defined
@@ -5450,11 +5531,11 @@
 Sema::AddOverloadCandidate(FunctionDecl *Function,
                            DeclAccessPair FoundDecl,
                            ArrayRef<Expr *> Args,
-                           OverloadCandidateSet& CandidateSet,
+                           OverloadCandidateSet &CandidateSet,
                            bool SuppressUserConversions,
                            bool PartialOverloading,
                            bool AllowExplicit) {
-  const FunctionProtoType* Proto
+  const FunctionProtoType *Proto
     = dyn_cast<FunctionProtoType>(Function->getType()->getAs<FunctionType>());
   assert(Proto && "Functions without a prototype cannot be overloaded");
   assert(!Function->getDescribedFunctionTemplate() &&
@@ -5481,6 +5562,17 @@
   if (!CandidateSet.isNewCandidate(Function))
     return;
 
+  // C++ [over.match.oper]p3:
+  //   if no operand has a class type, only those non-member functions in the
+  //   lookup set that have a first parameter of type T1 or "reference to
+  //   (possibly cv-qualified) T1", when T1 is an enumeration type, or (if there
+  //   is a right operand) a second parameter of type T2 or "reference to
+  //   (possibly cv-qualified) T2", when T2 is an enumeration type, are
+  //   candidate functions.
+  if (CandidateSet.getKind() == OverloadCandidateSet::CSK_Operator &&
+      !IsAcceptableNonMemberOperatorCandidate(Context, Function, Args))
+    return;
+
   // C++11 [class.copy]p11: [DR1402]
   //   A defaulted move constructor that is defined as deleted is ignored by
   //   overload resolution.
@@ -5513,12 +5605,12 @@
   Candidate.IgnoreObjectArgument = false;
   Candidate.ExplicitCallArguments = Args.size();
 
-  unsigned NumArgsInProto = Proto->getNumArgs();
+  unsigned NumParams = Proto->getNumParams();
 
   // (C++ 13.3.2p2): A candidate function having fewer than m
   // parameters is viable only if it has an ellipsis in its parameter
   // list (8.3.5).
-  if ((Args.size() + (PartialOverloading && Args.size())) > NumArgsInProto &&
+  if ((Args.size() + (PartialOverloading && Args.size())) > NumParams &&
       !Proto->isVariadic()) {
     Candidate.Viable = false;
     Candidate.FailureKind = ovl_fail_too_many_arguments;
@@ -5550,12 +5642,12 @@
   // Determine the implicit conversion sequences for each of the
   // arguments.
   for (unsigned ArgIdx = 0; ArgIdx < Args.size(); ++ArgIdx) {
-    if (ArgIdx < NumArgsInProto) {
+    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
       // parameter of F.
-      QualType ParamType = Proto->getArgType(ArgIdx);
+      QualType ParamType = Proto->getParamType(ArgIdx);
       Candidate.Conversions[ArgIdx]
         = TryCopyInitialization(*this, Args[ArgIdx], ParamType,
                                 SuppressUserConversions,
@@ -5566,7 +5658,7 @@
       if (Candidate.Conversions[ArgIdx].isBad()) {
         Candidate.Viable = false;
         Candidate.FailureKind = ovl_fail_bad_conversion;
-        break;
+        return;
       }
     } else {
       // (C++ 13.3.2p2): For the purposes of overload resolution, any
@@ -5575,6 +5667,78 @@
       Candidate.Conversions[ArgIdx].setEllipsis();
     }
   }
+
+  if (EnableIfAttr *FailedAttr = CheckEnableIf(Function, Args)) {
+    Candidate.Viable = false;
+    Candidate.FailureKind = ovl_fail_enable_if;
+    Candidate.DeductionFailure.Data = FailedAttr;
+    return;
+  }
+}
+
+static bool IsNotEnableIfAttr(Attr *A) { return !isa<EnableIfAttr>(A); }
+
+EnableIfAttr *Sema::CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args,
+                                  bool MissingImplicitThis) {
+  // FIXME: specific_attr_iterator<EnableIfAttr> iterates in reverse order, but
+  // we need to find the first failing one.
+  if (!Function->hasAttrs())
+    return nullptr;
+  AttrVec Attrs = Function->getAttrs();
+  AttrVec::iterator E = std::remove_if(Attrs.begin(), Attrs.end(),
+                                       IsNotEnableIfAttr);
+  if (Attrs.begin() == E)
+    return nullptr;
+  std::reverse(Attrs.begin(), E);
+
+  SFINAETrap Trap(*this);
+
+  // Convert the arguments.
+  SmallVector<Expr *, 16> ConvertedArgs;
+  bool InitializationFailed = false;
+  for (unsigned i = 0, e = Args.size(); i != e; ++i) {
+    if (i == 0 && !MissingImplicitThis && isa<CXXMethodDecl>(Function) &&
+        !cast<CXXMethodDecl>(Function)->isStatic() &&
+        !isa<CXXConstructorDecl>(Function)) {
+      CXXMethodDecl *Method = cast<CXXMethodDecl>(Function);
+      ExprResult R =
+        PerformObjectArgumentInitialization(Args[0], /*Qualifier=*/nullptr,
+                                            Method, Method);
+      if (R.isInvalid()) {
+        InitializationFailed = true;
+        break;
+      }
+      ConvertedArgs.push_back(R.get());
+    } else {
+      ExprResult R =
+        PerformCopyInitialization(InitializedEntity::InitializeParameter(
+                                                Context,
+                                                Function->getParamDecl(i)),
+                                  SourceLocation(),
+                                  Args[i]);
+      if (R.isInvalid()) {
+        InitializationFailed = true;
+        break;
+      }
+      ConvertedArgs.push_back(R.get());
+    }
+  }
+
+  if (InitializationFailed || Trap.hasErrorOccurred())
+    return cast<EnableIfAttr>(Attrs[0]);
+
+  for (AttrVec::iterator I = Attrs.begin(); I != E; ++I) {
+    APValue Result;
+    EnableIfAttr *EIA = cast<EnableIfAttr>(*I);
+    if (!EIA->getCond()->EvaluateWithSubstitution(
+            Result, Context, Function,
+            ArrayRef<const Expr*>(ConvertedArgs.data(),
+                                  ConvertedArgs.size())) ||
+        !Result.isInt() || !Result.getInt().getBoolValue()) {
+      return EIA;
+    }
+  }
+  return nullptr;
 }
 
 /// \brief Add all of the function declarations in the given function set to
@@ -5632,7 +5796,7 @@
     assert(isa<CXXMethodDecl>(TD->getTemplatedDecl()) &&
            "Expected a member function template");
     AddMethodTemplateCandidate(TD, FoundDecl, ActingContext,
-                               /*ExplicitArgs*/ 0,
+                               /*ExplicitArgs*/ nullptr,
                                ObjectType, ObjectClassification,
                                Args, CandidateSet,
                                SuppressUserConversions);
@@ -5656,9 +5820,9 @@
                          CXXRecordDecl *ActingContext, QualType ObjectType,
                          Expr::Classification ObjectClassification,
                          ArrayRef<Expr *> Args,
-                         OverloadCandidateSet& CandidateSet,
+                         OverloadCandidateSet &CandidateSet,
                          bool SuppressUserConversions) {
-  const FunctionProtoType* Proto
+  const FunctionProtoType *Proto
     = dyn_cast<FunctionProtoType>(Method->getType()->getAs<FunctionType>());
   assert(Proto && "Methods without a prototype cannot be overloaded");
   assert(!isa<CXXConstructorDecl>(Method) &&
@@ -5685,12 +5849,12 @@
   Candidate.IgnoreObjectArgument = false;
   Candidate.ExplicitCallArguments = Args.size();
 
-  unsigned NumArgsInProto = Proto->getNumArgs();
+  unsigned NumParams = Proto->getNumParams();
 
   // (C++ 13.3.2p2): A candidate function having fewer than m
   // parameters is viable only if it has an ellipsis in its parameter
   // list (8.3.5).
-  if (Args.size() > NumArgsInProto && !Proto->isVariadic()) {
+  if (Args.size() > NumParams && !Proto->isVariadic()) {
     Candidate.Viable = false;
     Candidate.FailureKind = ovl_fail_too_many_arguments;
     return;
@@ -5730,12 +5894,12 @@
   // Determine the implicit conversion sequences for each of the
   // arguments.
   for (unsigned ArgIdx = 0; ArgIdx < Args.size(); ++ArgIdx) {
-    if (ArgIdx < NumArgsInProto) {
+    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
       // parameter of F.
-      QualType ParamType = Proto->getArgType(ArgIdx);
+      QualType ParamType = Proto->getParamType(ArgIdx);
       Candidate.Conversions[ArgIdx + 1]
         = TryCopyInitialization(*this, Args[ArgIdx], ParamType,
                                 SuppressUserConversions,
@@ -5745,15 +5909,22 @@
       if (Candidate.Conversions[ArgIdx + 1].isBad()) {
         Candidate.Viable = false;
         Candidate.FailureKind = ovl_fail_bad_conversion;
-        break;
+        return;
       }
     } else {
       // (C++ 13.3.2p2): For the purposes of overload resolution, any
       // argument for which there is no corresponding parameter is
-      // considered to ""match the ellipsis" (C+ 13.3.3.1.3).
+      // considered to "match the ellipsis" (C+ 13.3.3.1.3).
       Candidate.Conversions[ArgIdx + 1].setEllipsis();
     }
   }
+
+  if (EnableIfAttr *FailedAttr = CheckEnableIf(Method, Args, true)) {
+    Candidate.Viable = false;
+    Candidate.FailureKind = ovl_fail_enable_if;
+    Candidate.DeductionFailure.Data = FailedAttr;
+    return;
+  }
 }
 
 /// \brief Add a C++ member function template as a candidate to the candidate
@@ -5782,7 +5953,7 @@
   //   function template are combined with the set of non-template candidate
   //   functions.
   TemplateDeductionInfo Info(CandidateSet.getLocation());
-  FunctionDecl *Specialization = 0;
+  FunctionDecl *Specialization = nullptr;
   if (TemplateDeductionResult Result
       = DeduceTemplateArguments(MethodTmpl, ExplicitTemplateArgs, Args,
                                 Specialization, Info)) {
@@ -5832,7 +6003,7 @@
   //   function template are combined with the set of non-template candidate
   //   functions.
   TemplateDeductionInfo Info(CandidateSet.getLocation());
-  FunctionDecl *Specialization = 0;
+  FunctionDecl *Specialization = nullptr;
   if (TemplateDeductionResult Result
         = DeduceTemplateArguments(FunctionTemplate, ExplicitTemplateArgs, Args,
                                   Specialization, Info)) {
@@ -5969,7 +6140,7 @@
     return;
   }
 
-  // We won't go through a user-define type conversion function to convert a
+  // We won't go through a user-defined type conversion function to convert a
   // derived to base as such conversions are given Conversion Rank. They only
   // go through a copy constructor. 13.3.3.1.2-p4 [over.ics.user]
   QualType FromCanon
@@ -6029,6 +6200,7 @@
         GetConversionRank(ICS.Standard.Second) != ICR_Exact_Match) {
       Candidate.Viable = false;
       Candidate.FailureKind = ovl_fail_final_conversion_not_exact;
+      return;
     }
 
     // C++0x [dcl.init.ref]p5:
@@ -6040,18 +6212,26 @@
         ICS.Standard.First == ICK_Lvalue_To_Rvalue) {
       Candidate.Viable = false;
       Candidate.FailureKind = ovl_fail_bad_final_conversion;
+      return;
     }
     break;
 
   case ImplicitConversionSequence::BadConversion:
     Candidate.Viable = false;
     Candidate.FailureKind = ovl_fail_bad_final_conversion;
-    break;
+    return;
 
   default:
     llvm_unreachable(
            "Can only end up with a standard conversion sequence or failure");
   }
+
+  if (EnableIfAttr *FailedAttr = CheckEnableIf(Conversion, ArrayRef<Expr*>())) {
+    Candidate.Viable = false;
+    Candidate.FailureKind = ovl_fail_enable_if;
+    Candidate.DeductionFailure.Data = FailedAttr;
+    return;
+  }
 }
 
 /// \brief Adds a conversion function template specialization
@@ -6073,7 +6253,7 @@
     return;
 
   TemplateDeductionInfo Info(CandidateSet.getLocation());
-  CXXConversionDecl *Specialization = 0;
+  CXXConversionDecl *Specialization = nullptr;
   if (TemplateDeductionResult Result
         = DeduceTemplateArguments(FunctionTemplate, ToType,
                                   Specialization, Info)) {
@@ -6117,7 +6297,7 @@
 
   OverloadCandidate &Candidate = CandidateSet.addCandidate(Args.size() + 1);
   Candidate.FoundDecl = FoundDecl;
-  Candidate.Function = 0;
+  Candidate.Function = nullptr;
   Candidate.Surrogate = Conversion;
   Candidate.Viable = true;
   Candidate.IsSurrogate = true;
@@ -6151,12 +6331,12 @@
   Candidate.Conversions[0].UserDefined.After.setAsIdentityConversion();
 
   // Find the
-  unsigned NumArgsInProto = Proto->getNumArgs();
+  unsigned NumParams = Proto->getNumParams();
 
   // (C++ 13.3.2p2): A candidate function having fewer than m
   // parameters is viable only if it has an ellipsis in its parameter
   // list (8.3.5).
-  if (Args.size() > NumArgsInProto && !Proto->isVariadic()) {
+  if (Args.size() > NumParams && !Proto->isVariadic()) {
     Candidate.Viable = false;
     Candidate.FailureKind = ovl_fail_too_many_arguments;
     return;
@@ -6164,7 +6344,7 @@
 
   // Function types don't have any default arguments, so just check if
   // we have enough arguments.
-  if (Args.size() < NumArgsInProto) {
+  if (Args.size() < NumParams) {
     // Not enough arguments.
     Candidate.Viable = false;
     Candidate.FailureKind = ovl_fail_too_few_arguments;
@@ -6174,12 +6354,12 @@
   // Determine the implicit conversion sequences for each of the
   // arguments.
   for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) {
-    if (ArgIdx < NumArgsInProto) {
+    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
       // parameter of F.
-      QualType ParamType = Proto->getArgType(ArgIdx);
+      QualType ParamType = Proto->getParamType(ArgIdx);
       Candidate.Conversions[ArgIdx + 1]
         = TryCopyInitialization(*this, Args[ArgIdx], ParamType,
                                 /*SuppressUserConversions=*/false,
@@ -6189,7 +6369,7 @@
       if (Candidate.Conversions[ArgIdx + 1].isBad()) {
         Candidate.Viable = false;
         Candidate.FailureKind = ovl_fail_bad_conversion;
-        break;
+        return;
       }
     } else {
       // (C++ 13.3.2p2): For the purposes of overload resolution, any
@@ -6198,6 +6378,13 @@
       Candidate.Conversions[ArgIdx + 1].setEllipsis();
     }
   }
+
+  if (EnableIfAttr *FailedAttr = CheckEnableIf(Conversion, ArrayRef<Expr*>())) {
+    Candidate.Viable = false;
+    Candidate.FailureKind = ovl_fail_enable_if;
+    Candidate.DeductionFailure.Data = FailedAttr;
+    return;
+  }
 }
 
 /// \brief Add overload candidates for overloaded operators that are
@@ -6270,8 +6457,8 @@
 
   // Add this candidate
   OverloadCandidate &Candidate = CandidateSet.addCandidate(Args.size());
-  Candidate.FoundDecl = DeclAccessPair::make(0, AS_none);
-  Candidate.Function = 0;
+  Candidate.FoundDecl = DeclAccessPair::make(nullptr, AS_none);
+  Candidate.Function = nullptr;
   Candidate.IsSurrogate = false;
   Candidate.IgnoreObjectArgument = false;
   Candidate.BuiltinTypes.ResultTy = ResultTy;
@@ -7951,7 +8138,7 @@
 /// candidate set (C++ [basic.lookup.argdep]).
 void
 Sema::AddArgumentDependentLookupCandidates(DeclarationName Name,
-                                           bool Operator, SourceLocation Loc,
+                                           SourceLocation Loc,
                                            ArrayRef<Expr *> Args,
                                  TemplateArgumentListInfo *ExplicitTemplateArgs,
                                            OverloadCandidateSet& CandidateSet,
@@ -7966,7 +8153,7 @@
   // we supposed to consider on ADL candidates, anyway?
 
   // FIXME: Pass in the explicit template arguments?
-  ArgumentDependentLookup(Name, Operator, Loc, Args, Fns);
+  ArgumentDependentLookup(Name, Loc, Args, Fns);
 
   // Erase all of the candidates we already knew about.
   for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
@@ -8051,29 +8238,6 @@
   if (HasBetterConversion)
     return true;
 
-  //     - F1 is a non-template function and F2 is a function template
-  //       specialization, or, if not that,
-  if ((!Cand1.Function || !Cand1.Function->getPrimaryTemplate()) &&
-      Cand2.Function && Cand2.Function->getPrimaryTemplate())
-    return true;
-
-  //   -- F1 and F2 are function template specializations, and the function
-  //      template for F1 is more specialized than the template for F2
-  //      according to the partial ordering rules described in 14.5.5.2, or,
-  //      if not that,
-  if (Cand1.Function && Cand1.Function->getPrimaryTemplate() &&
-      Cand2.Function && Cand2.Function->getPrimaryTemplate()) {
-    if (FunctionTemplateDecl *BetterTemplate
-          = S.getMoreSpecializedTemplate(Cand1.Function->getPrimaryTemplate(),
-                                         Cand2.Function->getPrimaryTemplate(),
-                                         Loc,
-                       isa<CXXConversionDecl>(Cand1.Function)? TPOC_Conversion
-                                                             : TPOC_Call,
-                                         Cand1.ExplicitCallArguments,
-                                         Cand2.ExplicitCallArguments))
-      return BetterTemplate == Cand1.Function->getPrimaryTemplate();
-  }
-
   //   -- the context is an initialization by user-defined conversion
   //      (see 8.5, 13.3.1.5) and the standard conversion sequence
   //      from the return type of F1 to the destination type (i.e.,
@@ -8087,26 +8251,89 @@
     // other. This only distinguishes the results in non-standard, extension
     // cases such as the conversion from a lambda closure type to a function
     // pointer or block.
-    ImplicitConversionSequence::CompareKind FuncResult
-      = compareConversionFunctions(S, Cand1.Function, Cand2.Function);
-    if (FuncResult != ImplicitConversionSequence::Indistinguishable)
-      return FuncResult;
-          
-    switch (CompareStandardConversionSequences(S,
-                                               Cand1.FinalConversion,
-                                               Cand2.FinalConversion)) {
-    case ImplicitConversionSequence::Better:
-      // Cand1 has a better conversion sequence.
-      return true;
+    ImplicitConversionSequence::CompareKind Result =
+        compareConversionFunctions(S, Cand1.Function, Cand2.Function);
+    if (Result == ImplicitConversionSequence::Indistinguishable)
+      Result = CompareStandardConversionSequences(S,
+                                                  Cand1.FinalConversion,
+                                                  Cand2.FinalConversion);
 
-    case ImplicitConversionSequence::Worse:
-      // Cand1 can't be better than Cand2.
+    if (Result != ImplicitConversionSequence::Indistinguishable)
+      return Result == ImplicitConversionSequence::Better;
+
+    // FIXME: Compare kind of reference binding if conversion functions
+    // convert to a reference type used in direct reference binding, per
+    // C++14 [over.match.best]p1 section 2 bullet 3.
+  }
+
+  //    -- F1 is a non-template function and F2 is a function template
+  //       specialization, or, if not that,
+  bool Cand1IsSpecialization = Cand1.Function &&
+                               Cand1.Function->getPrimaryTemplate();
+  bool Cand2IsSpecialization = Cand2.Function &&
+                               Cand2.Function->getPrimaryTemplate();
+  if (Cand1IsSpecialization != Cand2IsSpecialization)
+    return Cand2IsSpecialization;
+
+  //   -- F1 and F2 are function template specializations, and the function
+  //      template for F1 is more specialized than the template for F2
+  //      according to the partial ordering rules described in 14.5.5.2, or,
+  //      if not that,
+  if (Cand1IsSpecialization && Cand2IsSpecialization) {
+    if (FunctionTemplateDecl *BetterTemplate
+          = S.getMoreSpecializedTemplate(Cand1.Function->getPrimaryTemplate(),
+                                         Cand2.Function->getPrimaryTemplate(),
+                                         Loc,
+                       isa<CXXConversionDecl>(Cand1.Function)? TPOC_Conversion
+                                                             : TPOC_Call,
+                                         Cand1.ExplicitCallArguments,
+                                         Cand2.ExplicitCallArguments))
+      return BetterTemplate == Cand1.Function->getPrimaryTemplate();
+  }
+
+  // Check for enable_if value-based overload resolution.
+  if (Cand1.Function && Cand2.Function &&
+      (Cand1.Function->hasAttr<EnableIfAttr>() ||
+       Cand2.Function->hasAttr<EnableIfAttr>())) {
+    // FIXME: The next several lines are just
+    // specific_attr_iterator<EnableIfAttr> but going in declaration order,
+    // instead of reverse order which is how they're stored in the AST.
+    AttrVec Cand1Attrs;
+    if (Cand1.Function->hasAttrs()) {
+      Cand1Attrs = Cand1.Function->getAttrs();
+      Cand1Attrs.erase(std::remove_if(Cand1Attrs.begin(), Cand1Attrs.end(),
+                                      IsNotEnableIfAttr),
+                       Cand1Attrs.end());
+      std::reverse(Cand1Attrs.begin(), Cand1Attrs.end());
+    }
+
+    AttrVec Cand2Attrs;
+    if (Cand2.Function->hasAttrs()) {
+      Cand2Attrs = Cand2.Function->getAttrs();
+      Cand2Attrs.erase(std::remove_if(Cand2Attrs.begin(), Cand2Attrs.end(),
+                                      IsNotEnableIfAttr),
+                       Cand2Attrs.end());
+      std::reverse(Cand2Attrs.begin(), Cand2Attrs.end());
+    }
+
+    // Candidate 1 is better if it has strictly more attributes and
+    // the common sequence is identical.
+    if (Cand1Attrs.size() <= Cand2Attrs.size())
       return false;
 
-    case ImplicitConversionSequence::Indistinguishable:
-      // Do nothing
-      break;
+    auto Cand1I = Cand1Attrs.begin();
+    for (auto &Cand2A : Cand2Attrs) {
+      auto &Cand1A = *Cand1I++;
+      llvm::FoldingSetNodeID Cand1ID, Cand2ID;
+      cast<EnableIfAttr>(Cand1A)->getCond()->Profile(Cand1ID,
+                                                     S.getASTContext(), true);
+      cast<EnableIfAttr>(Cand2A)->getCond()->Profile(Cand2ID,
+                                                     S.getASTContext(), true);
+      if (Cand1ID != Cand2ID)
+        return false;
     }
+
+    return true;
   }
 
   return false;
@@ -8557,18 +8784,18 @@
   // at least / at most / exactly
   unsigned mode, modeCount;
   if (NumFormalArgs < MinParams) {
-    if (MinParams != FnTy->getNumArgs() ||
-        FnTy->isVariadic() || FnTy->isTemplateVariadic())
+    if (MinParams != FnTy->getNumParams() || FnTy->isVariadic() ||
+        FnTy->isTemplateVariadic())
       mode = 0; // "at least"
     else
       mode = 2; // "exactly"
     modeCount = MinParams;
   } else {
-    if (MinParams != FnTy->getNumArgs())
+    if (MinParams != FnTy->getNumParams())
       mode = 1; // "at most"
     else
       mode = 2; // "exactly"
-    modeCount = FnTy->getNumArgs();
+    modeCount = FnTy->getNumParams();
   }
 
   std::string Description;
@@ -8576,12 +8803,12 @@
 
   if (modeCount == 1 && Fn->getParamDecl(0)->getDeclName())
     S.Diag(Fn->getLocation(), diag::note_ovl_candidate_arity_one)
-      << (unsigned) FnKind << (Fn->getDescribedFunctionTemplate() != 0) << mode
-      << Fn->getParamDecl(0) << NumFormalArgs;
+      << (unsigned) FnKind << (Fn->getDescribedFunctionTemplate() != nullptr)
+      << mode << Fn->getParamDecl(0) << NumFormalArgs;
   else
     S.Diag(Fn->getLocation(), diag::note_ovl_candidate_arity)
-      << (unsigned) FnKind << (Fn->getDescribedFunctionTemplate() != 0) << mode
-      << modeCount << NumFormalArgs;
+      << (unsigned) FnKind << (Fn->getDescribedFunctionTemplate() != nullptr)
+      << mode << modeCount << NumFormalArgs;
   MaybeEmitInheritedConstructorNote(S, Fn);
 }
 
@@ -8817,6 +9044,15 @@
       << (unsigned) FnKind << CalleeTarget << CallerTarget;
 }
 
+void DiagnoseFailedEnableIfAttr(Sema &S, OverloadCandidate *Cand) {
+  FunctionDecl *Callee = Cand->Function;
+  EnableIfAttr *Attr = static_cast<EnableIfAttr*>(Cand->DeductionFailure.Data);
+
+  S.Diag(Callee->getLocation(),
+         diag::note_ovl_candidate_disabled_by_enable_if_attr)
+      << Attr->getCond()->getSourceRange() << Attr->getMessage();
+}
+
 /// Generates a 'note' diagnostic for an overload candidate.  We've
 /// already generated a primary error at the call site.
 ///
@@ -8880,6 +9116,9 @@
 
   case ovl_fail_bad_target:
     return DiagnoseBadTarget(S, Cand);
+
+  case ovl_fail_enable_if:
+    return DiagnoseFailedEnableIfAttr(S, Cand);
   }
 }
 
@@ -8991,7 +9230,10 @@
 
 struct CompareOverloadCandidatesForDisplay {
   Sema &S;
-  CompareOverloadCandidatesForDisplay(Sema &S) : S(S) {}
+  size_t NumArgs;
+
+  CompareOverloadCandidatesForDisplay(Sema &S, size_t nArgs)
+      : S(S), NumArgs(nArgs) {}
 
   bool operator()(const OverloadCandidate *L,
                   const OverloadCandidate *R) {
@@ -9016,8 +9258,24 @@
     if (!L->Viable) {
       // 1. Arity mismatches come after other candidates.
       if (L->FailureKind == ovl_fail_too_many_arguments ||
-          L->FailureKind == ovl_fail_too_few_arguments)
+          L->FailureKind == ovl_fail_too_few_arguments) {
+        if (R->FailureKind == ovl_fail_too_many_arguments ||
+            R->FailureKind == ovl_fail_too_few_arguments) {
+          int LDist = std::abs((int)L->getNumParams() - (int)NumArgs);
+          int RDist = std::abs((int)R->getNumParams() - (int)NumArgs);
+          if (LDist == RDist) {
+            if (L->FailureKind == R->FailureKind)
+              // Sort non-surrogates before surrogates.
+              return !L->IsSurrogate && R->IsSurrogate;
+            // Sort candidates requiring fewer parameters than there were
+            // arguments given after candidates requiring more parameters
+            // than there were arguments given.
+            return L->FailureKind == ovl_fail_too_many_arguments;
+          }
+          return LDist < RDist;
+        }
         return false;
+      }
       if (R->FailureKind == ovl_fail_too_many_arguments ||
           R->FailureKind == ovl_fail_too_few_arguments)
         return true;
@@ -9160,15 +9418,14 @@
   }
 
   // Fill in the rest of the conversions.
-  unsigned NumArgsInProto = Proto->getNumArgs();
+  unsigned NumParams = Proto->getNumParams();
   for (; ConvIdx != ConvCount; ++ConvIdx, ++ArgIdx) {
-    if (ArgIdx < NumArgsInProto) {
-      Cand->Conversions[ConvIdx]
-        = TryCopyInitialization(S, Args[ArgIdx], Proto->getArgType(ArgIdx),
-                                SuppressUserConversions,
-                                /*InOverloadResolution=*/true,
-                                /*AllowObjCWritebackConversion=*/
-                                  S.getLangOpts().ObjCAutoRefCount);
+    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);
@@ -9205,7 +9462,7 @@
   }
 
   std::sort(Cands.begin(), Cands.end(),
-            CompareOverloadCandidatesForDisplay(S));
+            CompareOverloadCandidatesForDisplay(S, Args.size()));
 
   bool ReportedAmbiguousConversions = false;
 
@@ -9320,7 +9577,7 @@
   for (iterator Cand = begin(), LastCand = end(); Cand != LastCand; ++Cand) {
     if (Cand->Specialization)
       Cands.push_back(Cand);
-    // Otherwise, this is a non matching builtin candidate.  We do not,
+    // Otherwise, this is a non-matching builtin candidate.  We do not,
     // in general, want to list every possible builtin candidate.
   }
 
@@ -9486,7 +9743,7 @@
     //   resulting template argument list is used to generate a single
     //   function template specialization, which is added to the set of
     //   overloaded functions considered.
-    FunctionDecl *Specialization = 0;
+    FunctionDecl *Specialization = nullptr;
     TemplateDeductionInfo Info(FailedCandidates.getLocation());
     if (Sema::TemplateDeductionResult Result
           = S.DeduceTemplateArguments(FunctionTemplate, 
@@ -9531,7 +9788,7 @@
       // If any candidate has a placeholder return type, trigger its deduction
       // now.
       if (S.getLangOpts().CPlusPlus1y &&
-          FunDecl->getResultType()->isUndeducedType() &&
+          FunDecl->getReturnType()->isUndeducedType() &&
           S.DeduceReturnType(FunDecl, SourceExpr->getLocStart(), Complain))
         return false;
 
@@ -9622,7 +9879,7 @@
     //   [...] any function template specializations in the set are
     //   eliminated if the set also contains a non-template function, [...]
     for (unsigned I = 0, N = Matches.size(); I != N; ) {
-      if (Matches[I].second->getPrimaryTemplate() == 0)
+      if (Matches[I].second->getPrimaryTemplate() == nullptr)
         ++I;
       else {
         Matches[I] = Matches[--N];
@@ -9694,12 +9951,12 @@
   int getNumMatches() const { return Matches.size(); }
   
   FunctionDecl* getMatchingFunctionDecl() const {
-    if (Matches.size() != 1) return 0;
+    if (Matches.size() != 1) return nullptr;
     return Matches[0].second;
   }
   
   const DeclAccessPair* getMatchingFunctionAccessPair() const {
-    if (Matches.size() != 1) return 0;
+    if (Matches.size() != 1) return nullptr;
     return &Matches[0].first;
   }
 };
@@ -9730,7 +9987,7 @@
   AddressOfFunctionResolver Resolver(*this, AddressOfExpr, TargetType,
                                      Complain);
   int NumMatches = Resolver.getNumMatches();
-  FunctionDecl* Fn = 0;
+  FunctionDecl *Fn = nullptr;
   if (NumMatches == 0 && Complain) {
     if (Resolver.IsInvalidFormOfPointerToMemberFunction())
       Resolver.ComplainIsInvalidFormOfPointerToMemberFunction();
@@ -9779,7 +10036,7 @@
 
   // If we didn't actually find any template-ids, we're done.
   if (!ovl->hasExplicitTemplateArgs())
-    return 0;
+    return nullptr;
 
   TemplateArgumentListInfo ExplicitTemplateArgs;
   ovl->getExplicitTemplateArgs().copyInto(ExplicitTemplateArgs);
@@ -9787,7 +10044,7 @@
 
   // Look through all of the overloaded functions, searching for one
   // whose type matches exactly.
-  FunctionDecl *Matched = 0;
+  FunctionDecl *Matched = nullptr;
   for (UnresolvedSetIterator I = ovl->decls_begin(),
          E = ovl->decls_end(); I != E; ++I) {
     // C++0x [temp.arg.explicit]p3:
@@ -9805,7 +10062,7 @@
     //   resulting template argument list is used to generate a single
     //   function template specialization, which is added to the set of
     //   overloaded functions considered.
-    FunctionDecl *Specialization = 0;
+    FunctionDecl *Specialization = nullptr;
     TemplateDeductionInfo Info(FailedCandidates.getLocation());
     if (TemplateDeductionResult Result
           = DeduceTemplateArguments(FunctionTemplate, &ExplicitTemplateArgs,
@@ -9828,7 +10085,7 @@
           << ovl->getName();
         NoteAllOverloadCandidates(ovl);
       }
-      return 0;
+      return nullptr;
     }
     
     Matched = Specialization;
@@ -9836,9 +10093,9 @@
   }
 
   if (Matched && getLangOpts().CPlusPlus1y &&
-      Matched->getResultType()->isUndeducedType() &&
+      Matched->getReturnType()->isUndeducedType() &&
       DeduceReturnType(Matched, ovl->getExprLoc(), Complain))
-    return 0;
+    return nullptr;
 
   return Matched;
 }
@@ -9896,12 +10153,12 @@
 
     // Fix the expression to refer to 'fn'.
     SingleFunctionExpression =
-      Owned(FixOverloadedFunctionReference(SrcExpr.take(), found, fn));
+        FixOverloadedFunctionReference(SrcExpr.get(), found, fn);
 
     // If desired, do function-to-pointer decay.
     if (doFunctionPointerConverion) {
       SingleFunctionExpression =
-        DefaultFunctionArrayLvalueConversion(SingleFunctionExpression.take());
+        DefaultFunctionArrayLvalueConversion(SingleFunctionExpression.get());
       if (SingleFunctionExpression.isInvalid()) {
         SrcExpr = ExprError();
         return true;
@@ -9999,7 +10256,7 @@
 
   // It would be nice to avoid this copy.
   TemplateArgumentListInfo TABuffer;
-  TemplateArgumentListInfo *ExplicitTemplateArgs = 0;
+  TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr;
   if (ULE->hasExplicitTemplateArgs()) {
     ULE->copyTemplateArgumentsInto(TABuffer);
     ExplicitTemplateArgs = &TABuffer;
@@ -10012,8 +10269,7 @@
                                /*KnownValid*/ true);
 
   if (ULE->requiresADL())
-    AddArgumentDependentLookupCandidates(ULE->getName(), /*Operator*/ false,
-                                         ULE->getExprLoc(),
+    AddArgumentDependentLookupCandidates(ULE->getName(), ULE->getExprLoc(),
                                          Args, ExplicitTemplateArgs,
                                          CandidateSet, PartialOverloading);
 }
@@ -10040,6 +10296,7 @@
 static bool
 DiagnoseTwoPhaseLookup(Sema &SemaRef, SourceLocation FnLoc,
                        const CXXScopeSpec &SS, LookupResult &R,
+                       OverloadCandidateSet::CandidateSetKind CSK,
                        TemplateArgumentListInfo *ExplicitTemplateArgs,
                        ArrayRef<Expr *> Args) {
   if (SemaRef.ActiveTemplateInstantiations.empty() || !SS.isEmpty())
@@ -10061,7 +10318,7 @@
         return false;
       }
 
-      OverloadCandidateSet Candidates(FnLoc);
+      OverloadCandidateSet Candidates(FnLoc, CSK);
       for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I)
         AddOverloadedCallCandidate(SemaRef, I.getPair(),
                                    ExplicitTemplateArgs, Args,
@@ -10145,7 +10402,8 @@
     SemaRef.Context.DeclarationNames.getCXXOperatorName(Op);
   LookupResult R(SemaRef, OpName, OpLoc, Sema::LookupOperatorName);
   return DiagnoseTwoPhaseLookup(SemaRef, OpLoc, CXXScopeSpec(), R,
-                                /*ExplicitTemplateArgs=*/0, Args);
+                                OverloadCandidateSet::CSK_Operator,
+                                /*ExplicitTemplateArgs=*/nullptr, Args);
 }
 
 namespace {
@@ -10171,7 +10429,7 @@
 BuildRecoveryCallExpr(Sema &SemaRef, Scope *S, Expr *Fn,
                       UnresolvedLookupExpr *ULE,
                       SourceLocation LParenLoc,
-                      llvm::MutableArrayRef<Expr *> Args,
+                      MutableArrayRef<Expr *> Args,
                       SourceLocation RParenLoc,
                       bool EmptyLookup, bool AllowTypoCorrection) {
   // Do not try to recover if it is already building a recovery call.
@@ -10189,7 +10447,7 @@
   SourceLocation TemplateKWLoc = ULE->getTemplateKeywordLoc();
 
   TemplateArgumentListInfo TABuffer;
-  TemplateArgumentListInfo *ExplicitTemplateArgs = 0;
+  TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr;
   if (ULE->hasExplicitTemplateArgs()) {
     ULE->copyTemplateArgumentsInto(TABuffer);
     ExplicitTemplateArgs = &TABuffer;
@@ -10198,12 +10456,14 @@
   LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(),
                  Sema::LookupOrdinaryName);
   FunctionCallFilterCCC Validator(SemaRef, Args.size(),
-                                  ExplicitTemplateArgs != 0);
+                                  ExplicitTemplateArgs != nullptr,
+                                  dyn_cast<MemberExpr>(Fn));
   NoTypoCorrectionCCC RejectAll;
   CorrectionCandidateCallback *CCC = AllowTypoCorrection ?
       (CorrectionCandidateCallback*)&Validator :
       (CorrectionCandidateCallback*)&RejectAll;
   if (!DiagnoseTwoPhaseLookup(SemaRef, Fn->getExprLoc(), SS, R,
+                              OverloadCandidateSet::CSK_Normal,
                               ExplicitTemplateArgs, Args) &&
       (!EmptyLookup ||
        SemaRef.DiagnoseEmptyLookup(S, SS, R, *CCC,
@@ -10230,7 +10490,7 @@
   // This shouldn't cause an infinite loop because we're giving it
   // an expression with viable lookup results, which should never
   // end up here.
-  return SemaRef.ActOnCallExpr(/*Scope*/ 0, NewFn.take(), LParenLoc,
+  return SemaRef.ActOnCallExpr(/*Scope*/ nullptr, NewFn.get(), LParenLoc,
                                MultiExprArg(Args.data(), Args.size()),
                                RParenLoc);
 }
@@ -10280,13 +10540,13 @@
     // create a type dependent CallExpr. The goal is to postpone name lookup
     // to instantiation time to be able to search into type dependent base
     // classes.
-    if (getLangOpts().MicrosoftMode && CurContext->isDependentContext() && 
+    if (getLangOpts().MSVCCompat && CurContext->isDependentContext() &&
         (isa<FunctionDecl>(CurContext) || isa<CXXRecordDecl>(CurContext))) {
       CallExpr *CE = new (Context) CallExpr(Context, Fn, Args,
                                             Context.DependentTy, VK_RValue,
                                             RParenLoc);
       CE->setTypeDependent(true);
-      *Result = Owned(CE);
+      *Result = CE;
       return true;
     }
     return false;
@@ -10382,7 +10642,8 @@
                                          SourceLocation RParenLoc,
                                          Expr *ExecConfig,
                                          bool AllowTypoCorrection) {
-  OverloadCandidateSet CandidateSet(Fn->getExprLoc());
+  OverloadCandidateSet CandidateSet(Fn->getExprLoc(),
+                                    OverloadCandidateSet::CSK_Normal);
   ExprResult result;
 
   if (buildOverloadedCallSet(S, Fn, ULE, Args, LParenLoc, &CandidateSet,
@@ -10435,7 +10696,7 @@
   if (checkPlaceholderForOverload(*this, Input))
     return ExprError();
 
-  Expr *Args[2] = { Input, 0 };
+  Expr *Args[2] = { Input, nullptr };
   unsigned NumArgs = 1;
 
   // For post-increment and post-decrement, add the implicit '0' as
@@ -10452,26 +10713,22 @@
 
   if (Input->isTypeDependent()) {
     if (Fns.empty())
-      return Owned(new (Context) UnaryOperator(Input,
-                                               Opc,
-                                               Context.DependentTy,
-                                               VK_RValue, OK_Ordinary,
-                                               OpLoc));
+      return new (Context) UnaryOperator(Input, Opc, Context.DependentTy,
+                                         VK_RValue, OK_Ordinary, OpLoc);
 
-    CXXRecordDecl *NamingClass = 0; // because lookup ignores member operators
+    CXXRecordDecl *NamingClass = nullptr; // lookup ignores member operators
     UnresolvedLookupExpr *Fn
       = UnresolvedLookupExpr::Create(Context, NamingClass,
                                      NestedNameSpecifierLoc(), OpNameInfo,
                                      /*ADL*/ true, IsOverloaded(Fns),
                                      Fns.begin(), Fns.end());
-    return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn, ArgsArray,
-                                                   Context.DependentTy,
-                                                   VK_RValue,
-                                                   OpLoc, false));
+    return new (Context)
+        CXXOperatorCallExpr(Context, Op, Fn, ArgsArray, Context.DependentTy,
+                            VK_RValue, OpLoc, false);
   }
 
   // Build an empty overload set.
-  OverloadCandidateSet CandidateSet(OpLoc);
+  OverloadCandidateSet CandidateSet(OpLoc, OverloadCandidateSet::CSK_Operator);
 
   // Add the candidates from the given function set.
   AddFunctionCandidates(Fns, ArgsArray, CandidateSet, false);
@@ -10480,8 +10737,8 @@
   AddMemberOperatorCandidates(Op, OpLoc, ArgsArray, CandidateSet);
 
   // Add candidates from ADL.
-  AddArgumentDependentLookupCandidates(OpName, /*Operator*/ true, OpLoc,
-                                       ArgsArray, /*ExplicitTemplateArgs*/ 0,                                       
+  AddArgumentDependentLookupCandidates(OpName, OpLoc, ArgsArray,
+                                       /*ExplicitTemplateArgs*/nullptr,
                                        CandidateSet);
 
   // Add builtin operator candidates.
@@ -10502,14 +10759,14 @@
 
       // Convert the arguments.
       if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FnDecl)) {
-        CheckMemberOperatorAccess(OpLoc, Args[0], 0, Best->FoundDecl);
+        CheckMemberOperatorAccess(OpLoc, Args[0], nullptr, Best->FoundDecl);
 
         ExprResult InputRes =
-          PerformObjectArgumentInitialization(Input, /*Qualifier=*/0,
+          PerformObjectArgumentInitialization(Input, /*Qualifier=*/nullptr,
                                               Best->FoundDecl, Method);
         if (InputRes.isInvalid())
           return ExprError();
-        Input = InputRes.take();
+        Input = InputRes.get();
       } else {
         // Convert the arguments.
         ExprResult InputInit
@@ -10520,7 +10777,7 @@
                                       Input);
         if (InputInit.isInvalid())
           return ExprError();
-        Input = InputInit.take();
+        Input = InputInit.get();
       }
 
       // Build the actual expression node.
@@ -10530,17 +10787,16 @@
         return ExprError();
 
       // Determine the result type.
-      QualType ResultTy = FnDecl->getResultType();
+      QualType ResultTy = FnDecl->getReturnType();
       ExprValueKind VK = Expr::getValueKindForType(ResultTy);
       ResultTy = ResultTy.getNonLValueExprType(Context);
 
       Args[0] = Input;
       CallExpr *TheCall =
-        new (Context) CXXOperatorCallExpr(Context, Op, FnExpr.take(), ArgsArray,
+        new (Context) CXXOperatorCallExpr(Context, Op, FnExpr.get(), ArgsArray,
                                           ResultTy, VK, OpLoc, false);
 
-      if (CheckCallReturnType(FnDecl->getResultType(), OpLoc, TheCall,
-                              FnDecl))
+      if (CheckCallReturnType(FnDecl->getReturnType(), OpLoc, TheCall, FnDecl))
         return ExprError();
 
       return MaybeBindToTemporary(TheCall);
@@ -10553,7 +10809,7 @@
                                   Best->Conversions[0], AA_Passing);
       if (InputRes.isInvalid())
         return ExprError();
-      Input = InputRes.take();
+      Input = InputRes.get();
       break;
     }
   }
@@ -10619,7 +10875,7 @@
                             const UnresolvedSetImpl &Fns,
                             Expr *LHS, Expr *RHS) {
   Expr *Args[2] = { LHS, RHS };
-  LHS=RHS=0; //Please use only Args instead of LHS/RHS couple
+  LHS=RHS=nullptr; // Please use only Args instead of LHS/RHS couple
 
   BinaryOperator::Opcode Opc = static_cast<BinaryOperator::Opcode>(OpcIn);
   OverloadedOperatorKind Op = BinaryOperator::getOverloadedOperator(Opc);
@@ -10632,24 +10888,18 @@
       // If there are no functions to store, just build a dependent
       // BinaryOperator or CompoundAssignment.
       if (Opc <= BO_Assign || Opc > BO_OrAssign)
-        return Owned(new (Context) BinaryOperator(Args[0], Args[1], Opc,
-                                                  Context.DependentTy,
-                                                  VK_RValue, OK_Ordinary,
-                                                  OpLoc,
-                                                  FPFeatures.fp_contract));
+        return new (Context) BinaryOperator(
+            Args[0], Args[1], Opc, Context.DependentTy, VK_RValue, OK_Ordinary,
+            OpLoc, FPFeatures.fp_contract);
 
-      return Owned(new (Context) CompoundAssignOperator(Args[0], Args[1], Opc,
-                                                        Context.DependentTy,
-                                                        VK_LValue,
-                                                        OK_Ordinary,
-                                                        Context.DependentTy,
-                                                        Context.DependentTy,
-                                                        OpLoc,
-                                                        FPFeatures.fp_contract));
+      return new (Context) CompoundAssignOperator(
+          Args[0], Args[1], Opc, Context.DependentTy, VK_LValue, OK_Ordinary,
+          Context.DependentTy, Context.DependentTy, OpLoc,
+          FPFeatures.fp_contract);
     }
 
     // FIXME: save results of ADL from here?
-    CXXRecordDecl *NamingClass = 0; // because lookup ignores member operators
+    CXXRecordDecl *NamingClass = nullptr; // lookup ignores member operators
     // TODO: provide better source location info in DNLoc component.
     DeclarationNameInfo OpNameInfo(OpName, OpLoc);
     UnresolvedLookupExpr *Fn
@@ -10657,9 +10907,9 @@
                                      NestedNameSpecifierLoc(), OpNameInfo, 
                                      /*ADL*/ true, IsOverloaded(Fns),
                                      Fns.begin(), Fns.end());
-    return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn, Args,
-                                                Context.DependentTy, VK_RValue,
-                                                OpLoc, FPFeatures.fp_contract));
+    return new (Context)
+        CXXOperatorCallExpr(Context, Op, Fn, Args, Context.DependentTy,
+                            VK_RValue, OpLoc, FPFeatures.fp_contract);
   }
 
   // Always do placeholder-like conversions on the RHS.
@@ -10687,7 +10937,7 @@
     return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
 
   // Build an empty overload set.
-  OverloadCandidateSet CandidateSet(OpLoc);
+  OverloadCandidateSet CandidateSet(OpLoc, OverloadCandidateSet::CSK_Operator);
 
   // Add the candidates from the given function set.
   AddFunctionCandidates(Fns, Args, CandidateSet, false);
@@ -10696,9 +10946,8 @@
   AddMemberOperatorCandidates(Op, OpLoc, Args, CandidateSet);
 
   // Add candidates from ADL.
-  AddArgumentDependentLookupCandidates(OpName, /*Operator*/ true,
-                                       OpLoc, Args,
-                                       /*ExplicitTemplateArgs*/ 0,
+  AddArgumentDependentLookupCandidates(OpName, OpLoc, Args,
+                                       /*ExplicitTemplateArgs*/ nullptr,
                                        CandidateSet);
 
   // Add builtin operator candidates.
@@ -10726,23 +10975,23 @@
             PerformCopyInitialization(
               InitializedEntity::InitializeParameter(Context,
                                                      FnDecl->getParamDecl(0)),
-              SourceLocation(), Owned(Args[1]));
+              SourceLocation(), Args[1]);
           if (Arg1.isInvalid())
             return ExprError();
 
           ExprResult Arg0 =
-            PerformObjectArgumentInitialization(Args[0], /*Qualifier=*/0,
+            PerformObjectArgumentInitialization(Args[0], /*Qualifier=*/nullptr,
                                                 Best->FoundDecl, Method);
           if (Arg0.isInvalid())
             return ExprError();
-          Args[0] = Arg0.takeAs<Expr>();
-          Args[1] = RHS = Arg1.takeAs<Expr>();
+          Args[0] = Arg0.getAs<Expr>();
+          Args[1] = RHS = Arg1.getAs<Expr>();
         } else {
           // Convert the arguments.
           ExprResult Arg0 = PerformCopyInitialization(
             InitializedEntity::InitializeParameter(Context,
                                                    FnDecl->getParamDecl(0)),
-            SourceLocation(), Owned(Args[0]));
+            SourceLocation(), Args[0]);
           if (Arg0.isInvalid())
             return ExprError();
 
@@ -10750,11 +10999,11 @@
             PerformCopyInitialization(
               InitializedEntity::InitializeParameter(Context,
                                                      FnDecl->getParamDecl(1)),
-              SourceLocation(), Owned(Args[1]));
+              SourceLocation(), Args[1]);
           if (Arg1.isInvalid())
             return ExprError();
-          Args[0] = LHS = Arg0.takeAs<Expr>();
-          Args[1] = RHS = Arg1.takeAs<Expr>();
+          Args[0] = LHS = Arg0.getAs<Expr>();
+          Args[1] = RHS = Arg1.getAs<Expr>();
         }
 
         // Build the actual expression node.
@@ -10765,16 +11014,16 @@
           return ExprError();
 
         // Determine the result type.
-        QualType ResultTy = FnDecl->getResultType();
+        QualType ResultTy = FnDecl->getReturnType();
         ExprValueKind VK = Expr::getValueKindForType(ResultTy);
         ResultTy = ResultTy.getNonLValueExprType(Context);
 
         CXXOperatorCallExpr *TheCall =
-          new (Context) CXXOperatorCallExpr(Context, Op, FnExpr.take(),
+          new (Context) CXXOperatorCallExpr(Context, Op, FnExpr.get(),
                                             Args, ResultTy, VK, OpLoc,
                                             FPFeatures.fp_contract);
 
-        if (CheckCallReturnType(FnDecl->getResultType(), OpLoc, TheCall,
+        if (CheckCallReturnType(FnDecl->getReturnType(), OpLoc, TheCall,
                                 FnDecl))
           return ExprError();
 
@@ -10795,14 +11044,14 @@
                                     Best->Conversions[0], AA_Passing);
         if (ArgsRes0.isInvalid())
           return ExprError();
-        Args[0] = ArgsRes0.take();
+        Args[0] = ArgsRes0.get();
 
         ExprResult ArgsRes1 =
           PerformImplicitConversion(Args[1], Best->BuiltinTypes.ParamTypes[1],
                                     Best->Conversions[1], AA_Passing);
         if (ArgsRes1.isInvalid())
           return ExprError();
-        Args[1] = ArgsRes1.take();
+        Args[1] = ArgsRes1.get();
         break;
       }
     }
@@ -10897,7 +11146,7 @@
   // expression.
   if (Args[0]->isTypeDependent() || Args[1]->isTypeDependent()) {
 
-    CXXRecordDecl *NamingClass = 0; // because lookup ignores member operators
+    CXXRecordDecl *NamingClass = nullptr; // lookup ignores member operators
     // CHECKME: no 'operator' keyword?
     DeclarationNameInfo OpNameInfo(OpName, LLoc);
     OpNameInfo.setCXXOperatorNameRange(SourceRange(LLoc, RLoc));
@@ -10909,11 +11158,9 @@
                                      UnresolvedSetIterator());
     // Can't add any actual overloads yet
 
-    return Owned(new (Context) CXXOperatorCallExpr(Context, OO_Subscript, Fn,
-                                                   Args,
-                                                   Context.DependentTy,
-                                                   VK_RValue,
-                                                   RLoc, false));
+    return new (Context)
+        CXXOperatorCallExpr(Context, OO_Subscript, Fn, Args,
+                            Context.DependentTy, VK_RValue, RLoc, false);
   }
 
   // Handle placeholders on both operands.
@@ -10923,7 +11170,7 @@
     return ExprError();
 
   // Build an empty overload set.
-  OverloadCandidateSet CandidateSet(LLoc);
+  OverloadCandidateSet CandidateSet(LLoc, OverloadCandidateSet::CSK_Operator);
 
   // Subscript can only be overloaded as a member function.
 
@@ -10951,11 +11198,11 @@
         // Convert the arguments.
         CXXMethodDecl *Method = cast<CXXMethodDecl>(FnDecl);
         ExprResult Arg0 =
-          PerformObjectArgumentInitialization(Args[0], /*Qualifier=*/0,
+          PerformObjectArgumentInitialization(Args[0], /*Qualifier=*/nullptr,
                                               Best->FoundDecl, Method);
         if (Arg0.isInvalid())
           return ExprError();
-        Args[0] = Arg0.take();
+        Args[0] = Arg0.get();
 
         // Convert the arguments.
         ExprResult InputInit
@@ -10963,11 +11210,11 @@
                                                       Context,
                                                       FnDecl->getParamDecl(0)),
                                       SourceLocation(),
-                                      Owned(Args[1]));
+                                      Args[1]);
         if (InputInit.isInvalid())
           return ExprError();
 
-        Args[1] = InputInit.takeAs<Expr>();
+        Args[1] = InputInit.getAs<Expr>();
 
         // Build the actual expression node.
         DeclarationNameInfo OpLocInfo(OpName, LLoc);
@@ -10981,18 +11228,17 @@
           return ExprError();
 
         // Determine the result type
-        QualType ResultTy = FnDecl->getResultType();
+        QualType ResultTy = FnDecl->getReturnType();
         ExprValueKind VK = Expr::getValueKindForType(ResultTy);
         ResultTy = ResultTy.getNonLValueExprType(Context);
 
         CXXOperatorCallExpr *TheCall =
           new (Context) CXXOperatorCallExpr(Context, OO_Subscript,
-                                            FnExpr.take(), Args,
+                                            FnExpr.get(), Args,
                                             ResultTy, VK, RLoc,
                                             false);
 
-        if (CheckCallReturnType(FnDecl->getResultType(), LLoc, TheCall,
-                                FnDecl))
+        if (CheckCallReturnType(FnDecl->getReturnType(), LLoc, TheCall, FnDecl))
           return ExprError();
 
         return MaybeBindToTemporary(TheCall);
@@ -11005,14 +11251,14 @@
                                     Best->Conversions[0], AA_Passing);
         if (ArgsRes0.isInvalid())
           return ExprError();
-        Args[0] = ArgsRes0.take();
+        Args[0] = ArgsRes0.get();
 
         ExprResult ArgsRes1 =
           PerformImplicitConversion(Args[1], Best->BuiltinTypes.ParamTypes[1],
                                     Best->Conversions[1], AA_Passing);
         if (ArgsRes1.isInvalid())
           return ExprError();
-        Args[1] = ArgsRes1.take();
+        Args[1] = ArgsRes1.get();
 
         break;
       }
@@ -11084,7 +11330,7 @@
 
     const FunctionProtoType *proto = fnType->castAs<FunctionProtoType>();
     QualType resultType = proto->getCallResultType(Context);
-    ExprValueKind valueKind = Expr::getValueKindForType(proto->getResultType());
+    ExprValueKind valueKind = Expr::getValueKindForType(proto->getReturnType());
 
     // Check that the object type isn't more qualified than the
     // member function we're calling.
@@ -11105,17 +11351,16 @@
         << qualsString
         << (qualsString.find(' ') == std::string::npos ? 1 : 2);
     }
-              
+
     CXXMemberCallExpr *call
       = new (Context) CXXMemberCallExpr(Context, MemExprE, Args,
                                         resultType, valueKind, RParenLoc);
 
-    if (CheckCallReturnType(proto->getResultType(),
-                            op->getRHS()->getLocStart(),
-                            call, 0))
+    if (CheckCallReturnType(proto->getReturnType(), op->getRHS()->getLocStart(),
+                            call, nullptr))
       return ExprError();
 
-    if (ConvertArgumentsForCall(call, op, 0, proto, Args, RParenLoc))
+    if (ConvertArgumentsForCall(call, op, nullptr, proto, Args, RParenLoc))
       return ExprError();
 
     if (CheckOtherCall(call, proto))
@@ -11129,9 +11374,9 @@
     return ExprError();
 
   MemberExpr *MemExpr;
-  CXXMethodDecl *Method = 0;
-  DeclAccessPair FoundDecl = DeclAccessPair::make(0, AS_public);
-  NestedNameSpecifier *Qualifier = 0;
+  CXXMethodDecl *Method = nullptr;
+  DeclAccessPair FoundDecl = DeclAccessPair::make(nullptr, AS_public);
+  NestedNameSpecifier *Qualifier = nullptr;
   if (isa<MemberExpr>(NakedMemExpr)) {
     MemExpr = cast<MemberExpr>(NakedMemExpr);
     Method = cast<CXXMethodDecl>(MemExpr->getMemberDecl());
@@ -11148,10 +11393,11 @@
                             : UnresExpr->getBase()->Classify(Context);
 
     // Add overload candidates
-    OverloadCandidateSet CandidateSet(UnresExpr->getMemberLoc());
+    OverloadCandidateSet CandidateSet(UnresExpr->getMemberLoc(),
+                                      OverloadCandidateSet::CSK_Normal);
 
     // FIXME: avoid copy.
-    TemplateArgumentListInfo TemplateArgsBuffer, *TemplateArgs = 0;
+    TemplateArgumentListInfo TemplateArgsBuffer, *TemplateArgs = nullptr;
     if (UnresExpr->hasExplicitTemplateArgs()) {
       UnresExpr->copyTemplateArgumentsInto(TemplateArgsBuffer);
       TemplateArgs = &TemplateArgsBuffer;
@@ -11250,7 +11496,7 @@
     MemExpr = cast<MemberExpr>(MemExprE->IgnoreParens());
   }
 
-  QualType ResultType = Method->getResultType();
+  QualType ResultType = Method->getReturnType();
   ExprValueKind VK = Expr::getValueKindForType(ResultType);
   ResultType = ResultType.getNonLValueExprType(Context);
 
@@ -11260,7 +11506,7 @@
                                     ResultType, VK, RParenLoc);
 
   // Check for a valid return type.
-  if (CheckCallReturnType(Method->getResultType(), MemExpr->getMemberLoc(),
+  if (CheckCallReturnType(Method->getReturnType(), MemExpr->getMemberLoc(),
                           TheCall, Method))
     return ExprError();
 
@@ -11273,7 +11519,7 @@
                                           FoundDecl, Method);
     if (ObjectArg.isInvalid())
       return ExprError();
-    MemExpr->setBase(ObjectArg.take());
+    MemExpr->setBase(ObjectArg.get());
   }
 
   // Convert the rest of the arguments
@@ -11316,7 +11562,7 @@
                                    SourceLocation RParenLoc) {
   if (checkPlaceholderForOverload(*this, Obj))
     return ExprError();
-  ExprResult Object = Owned(Obj);
+  ExprResult Object = Obj;
 
   UnbridgedCastsSet UnbridgedCasts;
   if (checkArgPlaceholdersForOverload(*this, Args, UnbridgedCasts))
@@ -11332,7 +11578,8 @@
   //  operators of T. The function call operators of T are obtained by
   //  ordinary lookup of the name operator() in the context of
   //  (E).operator().
-  OverloadCandidateSet CandidateSet(LParenLoc);
+  OverloadCandidateSet CandidateSet(LParenLoc,
+                                    OverloadCandidateSet::CSK_Operator);
   DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(OO_Call);
 
   if (RequireCompleteType(LParenLoc, Object.get()->getType(),
@@ -11445,14 +11692,15 @@
 
   UnbridgedCasts.restore();
 
-  if (Best->Function == 0) {
+  if (Best->Function == nullptr) {
     // Since there is no function declaration, this is one of the
     // surrogate candidates. Dig out the conversion function.
     CXXConversionDecl *Conv
       = cast<CXXConversionDecl>(
                          Best->Conversions[0].UserDefined.ConversionFunction);
 
-    CheckMemberOperatorAccess(LParenLoc, Object.get(), 0, Best->FoundDecl);
+    CheckMemberOperatorAccess(LParenLoc, Object.get(), nullptr,
+                              Best->FoundDecl);
     if (DiagnoseUseOfDecl(Best->FoundDecl, LParenLoc))
       return ExprError();
     assert(Conv == Best->FoundDecl.getDecl() && 
@@ -11468,14 +11716,14 @@
     if (Call.isInvalid())
       return ExprError();
     // Record usage of conversion in an implicit cast.
-    Call = Owned(ImplicitCastExpr::Create(Context, Call.get()->getType(),
-                                          CK_UserDefinedConversion,
-                                          Call.get(), 0, VK_RValue));
+    Call = ImplicitCastExpr::Create(Context, Call.get()->getType(),
+                                    CK_UserDefinedConversion, Call.get(),
+                                    nullptr, VK_RValue);
 
     return ActOnCallExpr(S, Call.get(), LParenLoc, Args, RParenLoc);
   }
 
-  CheckMemberOperatorAccess(LParenLoc, Object.get(), 0, Best->FoundDecl);
+  CheckMemberOperatorAccess(LParenLoc, Object.get(), nullptr, Best->FoundDecl);
 
   // We found an overloaded operator(). Build a CXXOperatorCallExpr
   // that calls this method, using Object for the implicit object
@@ -11489,7 +11737,7 @@
   const FunctionProtoType *Proto =
     Method->getType()->getAs<FunctionProtoType>();
 
-  unsigned NumArgsInProto = Proto->getNumArgs();
+  unsigned NumParams = Proto->getNumParams();
 
   DeclarationNameInfo OpLocInfo(
                Context.DeclarationNames.getCXXOperatorName(OO_Call), LParenLoc);
@@ -11503,45 +11751,44 @@
 
   // Build the full argument list for the method call (the implicit object
   // parameter is placed at the beginning of the list).
-  llvm::OwningArrayPtr<Expr *> MethodArgs(new Expr*[Args.size() + 1]);
+  std::unique_ptr<Expr * []> MethodArgs(new Expr *[Args.size() + 1]);
   MethodArgs[0] = Object.get();
   std::copy(Args.begin(), Args.end(), &MethodArgs[1]);
 
   // Once we've built TheCall, all of the expressions are properly
   // owned.
-  QualType ResultTy = Method->getResultType();
+  QualType ResultTy = Method->getReturnType();
   ExprValueKind VK = Expr::getValueKindForType(ResultTy);
   ResultTy = ResultTy.getNonLValueExprType(Context);
 
   CXXOperatorCallExpr *TheCall = new (Context)
-      CXXOperatorCallExpr(Context, OO_Call, NewFn.take(),
+      CXXOperatorCallExpr(Context, OO_Call, NewFn.get(),
                           llvm::makeArrayRef(MethodArgs.get(), Args.size() + 1),
                           ResultTy, VK, RParenLoc, false);
   MethodArgs.reset();
 
-  if (CheckCallReturnType(Method->getResultType(), LParenLoc, TheCall,
-                          Method))
+  if (CheckCallReturnType(Method->getReturnType(), LParenLoc, TheCall, Method))
     return true;
 
   // We may have default arguments. If so, we need to allocate more
   // slots in the call for them.
-  if (Args.size() < NumArgsInProto)
-    TheCall->setNumArgs(Context, NumArgsInProto + 1);
+  if (Args.size() < NumParams)
+    TheCall->setNumArgs(Context, NumParams + 1);
 
   bool IsError = false;
 
   // Initialize the implicit object parameter.
   ExprResult ObjRes =
-    PerformObjectArgumentInitialization(Object.get(), /*Qualifier=*/0,
+    PerformObjectArgumentInitialization(Object.get(), /*Qualifier=*/nullptr,
                                         Best->FoundDecl, Method);
   if (ObjRes.isInvalid())
     IsError = true;
   else
     Object = ObjRes;
-  TheCall->setArg(0, Object.take());
+  TheCall->setArg(0, Object.get());
 
   // Check the argument types.
-  for (unsigned i = 0; i != NumArgsInProto; i++) {
+  for (unsigned i = 0; i != NumParams; i++) {
     Expr *Arg;
     if (i < Args.size()) {
       Arg = Args[i];
@@ -11555,7 +11802,7 @@
                                     SourceLocation(), Arg);
 
       IsError |= InputInit.isInvalid();
-      Arg = InputInit.takeAs<Expr>();
+      Arg = InputInit.getAs<Expr>();
     } else {
       ExprResult DefArg
         = BuildCXXDefaultArgExpr(LParenLoc, Method, Method->getParamDecl(i));
@@ -11564,7 +11811,7 @@
         break;
       }
 
-      Arg = DefArg.takeAs<Expr>();
+      Arg = DefArg.getAs<Expr>();
     }
 
     TheCall->setArg(i + 1, Arg);
@@ -11573,10 +11820,11 @@
   // If this is a variadic call, handle args passed through "...".
   if (Proto->isVariadic()) {
     // Promote the arguments (C99 6.5.2.2p7).
-    for (unsigned i = NumArgsInProto, e = Args.size(); i < e; i++) {
-      ExprResult Arg = DefaultVariadicArgumentPromotion(Args[i], VariadicMethod, 0);
+    for (unsigned i = NumParams, e = Args.size(); i < e; i++) {
+      ExprResult Arg = DefaultVariadicArgumentPromotion(Args[i], VariadicMethod,
+                                                        nullptr);
       IsError |= Arg.isInvalid();
-      TheCall->setArg(i + 1, Arg.take());
+      TheCall->setArg(i + 1, Arg.get());
     }
   }
 
@@ -11612,7 +11860,7 @@
   //   overload resolution mechanism (13.3).
   DeclarationName OpName =
     Context.DeclarationNames.getCXXOperatorName(OO_Arrow);
-  OverloadCandidateSet CandidateSet(Loc);
+  OverloadCandidateSet CandidateSet(Loc, OverloadCandidateSet::CSK_Operator);
   const RecordType *BaseRecord = Base->getType()->getAs<RecordType>();
 
   if (RequireCompleteType(Loc, Base->getType(),
@@ -11675,16 +11923,16 @@
     return ExprError();
   }
 
-  CheckMemberOperatorAccess(OpLoc, Base, 0, Best->FoundDecl);
+  CheckMemberOperatorAccess(OpLoc, Base, nullptr, Best->FoundDecl);
 
   // Convert the object parameter.
   CXXMethodDecl *Method = cast<CXXMethodDecl>(Best->Function);
   ExprResult BaseResult =
-    PerformObjectArgumentInitialization(Base, /*Qualifier=*/0,
+    PerformObjectArgumentInitialization(Base, /*Qualifier=*/nullptr,
                                         Best->FoundDecl, Method);
   if (BaseResult.isInvalid())
     return ExprError();
-  Base = BaseResult.take();
+  Base = BaseResult.get();
 
   // Build the operator call.
   ExprResult FnExpr = CreateFunctionRefExpr(*this, Method, Best->FoundDecl,
@@ -11692,15 +11940,14 @@
   if (FnExpr.isInvalid())
     return ExprError();
 
-  QualType ResultTy = Method->getResultType();
+  QualType ResultTy = Method->getReturnType();
   ExprValueKind VK = Expr::getValueKindForType(ResultTy);
   ResultTy = ResultTy.getNonLValueExprType(Context);
   CXXOperatorCallExpr *TheCall =
-    new (Context) CXXOperatorCallExpr(Context, OO_Arrow, FnExpr.take(),
+    new (Context) CXXOperatorCallExpr(Context, OO_Arrow, FnExpr.get(),
                                       Base, ResultTy, VK, OpLoc, false);
 
-  if (CheckCallReturnType(Method->getResultType(), OpLoc, TheCall,
-                          Method))
+  if (CheckCallReturnType(Method->getReturnType(), OpLoc, TheCall, Method))
           return ExprError();
 
   return MaybeBindToTemporary(TheCall);
@@ -11715,7 +11962,8 @@
                                        TemplateArgumentListInfo *TemplateArgs) {
   SourceLocation UDSuffixLoc = SuffixInfo.getCXXLiteralOperatorNameLoc();
 
-  OverloadCandidateSet CandidateSet(UDSuffixLoc);
+  OverloadCandidateSet CandidateSet(UDSuffixLoc,
+                                    OverloadCandidateSet::CSK_Normal);
   AddFunctionCandidates(R.asUnresolvedSet(), Args, CandidateSet, true,
                         TemplateArgs);
 
@@ -11758,22 +12006,22 @@
       SourceLocation(), Args[ArgIdx]);
     if (InputInit.isInvalid())
       return true;
-    ConvArgs[ArgIdx] = InputInit.take();
+    ConvArgs[ArgIdx] = InputInit.get();
   }
 
-  QualType ResultTy = FD->getResultType();
+  QualType ResultTy = FD->getReturnType();
   ExprValueKind VK = Expr::getValueKindForType(ResultTy);
   ResultTy = ResultTy.getNonLValueExprType(Context);
 
   UserDefinedLiteral *UDL =
-    new (Context) UserDefinedLiteral(Context, Fn.take(),
+    new (Context) UserDefinedLiteral(Context, Fn.get(),
                                      llvm::makeArrayRef(ConvArgs, Args.size()),
                                      ResultTy, VK, LitEndLoc, UDSuffixLoc);
 
-  if (CheckCallReturnType(FD->getResultType(), UDSuffixLoc, UDL, FD))
+  if (CheckCallReturnType(FD->getReturnType(), UDSuffixLoc, UDL, FD))
     return ExprError();
 
-  if (CheckFunctionCall(FD, UDL, NULL))
+  if (CheckFunctionCall(FD, UDL, nullptr))
     return ExprError();
 
   return MaybeBindToTemporary(UDL);
@@ -11800,16 +12048,16 @@
         BuildMemberReferenceExpr(Range, Range->getType(), Loc,
                                  /*IsPtr=*/false, CXXScopeSpec(),
                                  /*TemplateKWLoc=*/SourceLocation(),
-                                 /*FirstQualifierInScope=*/0,
+                                 /*FirstQualifierInScope=*/nullptr,
                                  MemberLookup,
-                                 /*TemplateArgs=*/0);
+                                 /*TemplateArgs=*/nullptr);
     if (MemberRef.isInvalid()) {
       *CallExpr = ExprError();
       Diag(Range->getLocStart(), diag::note_in_for_range)
           << RangeLoc << BEF << Range->getType();
       return FRS_DiagnosticIssued;
     }
-    *CallExpr = ActOnCallExpr(S, MemberRef.get(), Loc, None, Loc, 0);
+    *CallExpr = ActOnCallExpr(S, MemberRef.get(), Loc, None, Loc, nullptr);
     if (CallExpr->isInvalid()) {
       *CallExpr = ExprError();
       Diag(Range->getLocStart(), diag::note_in_for_range)
@@ -11819,7 +12067,7 @@
   } else {
     UnresolvedSet<0> FoundNames;
     UnresolvedLookupExpr *Fn =
-      UnresolvedLookupExpr::Create(Context, /*NamingClass=*/0,
+      UnresolvedLookupExpr::Create(Context, /*NamingClass=*/nullptr,
                                    NestedNameSpecifierLoc(), NameInfo,
                                    /*NeedsADL=*/true, /*Overloaded=*/false,
                                    FoundNames.begin(), FoundNames.end());
@@ -11839,7 +12087,7 @@
       return FRS_NoViableFunction;
     }
     *CallExpr = FinishOverloadedCallExpr(*this, S, Fn, Fn, Loc, Range,
-                                         Loc, 0, CandidateSet, &Best,
+                                         Loc, nullptr, CandidateSet, &Best,
                                          OverloadResult,
                                          /*AllowTypoCorrection=*/false);
     if (CallExpr->isInvalid() || OverloadResult != OR_Success) {
@@ -11881,7 +12129,7 @@
 
     return ImplicitCastExpr::Create(Context, ICE->getType(),
                                     ICE->getCastKind(),
-                                    SubExpr, 0,
+                                    SubExpr, nullptr,
                                     ICE->getValueKind());
   }
 
@@ -11893,7 +12141,7 @@
         // Do nothing: static member functions aren't any different
         // from non-member functions.
       } else {
-        // Fix the sub expression, which really has to be an
+        // Fix the subexpression, which really has to be an
         // UnresolvedLookupExpr holding an overloaded member function
         // or template.
         Expr *SubExpr = FixOverloadedFunctionReference(UnOp->getSubExpr(),
@@ -11932,7 +12180,7 @@
 
   if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(E)) {
     // FIXME: avoid copy.
-    TemplateArgumentListInfo TemplateArgsBuffer, *TemplateArgs = 0;
+    TemplateArgumentListInfo TemplateArgsBuffer, *TemplateArgs = nullptr;
     if (ULE->hasExplicitTemplateArgs()) {
       ULE->copyTemplateArgumentsInto(TemplateArgsBuffer);
       TemplateArgs = &TemplateArgsBuffer;
@@ -11955,7 +12203,7 @@
 
   if (UnresolvedMemberExpr *MemExpr = dyn_cast<UnresolvedMemberExpr>(E)) {
     // FIXME: avoid copy.
-    TemplateArgumentListInfo TemplateArgsBuffer, *TemplateArgs = 0;
+    TemplateArgumentListInfo TemplateArgsBuffer, *TemplateArgs = nullptr;
     if (MemExpr->hasExplicitTemplateArgs()) {
       MemExpr->copyTemplateArgumentsInto(TemplateArgsBuffer);
       TemplateArgs = &TemplateArgsBuffer;
@@ -12022,7 +12270,7 @@
 ExprResult Sema::FixOverloadedFunctionReference(ExprResult E,
                                                 DeclAccessPair Found,
                                                 FunctionDecl *Fn) {
-  return Owned(FixOverloadedFunctionReference((Expr *)E.get(), Found, Fn));
+  return FixOverloadedFunctionReference(E.get(), Found, Fn);
 }
 
 } // end namespace clang
diff --git a/lib/Sema/SemaPseudoObject.cpp b/lib/Sema/SemaPseudoObject.cpp
index af74f0d..aa3e89e 100644
--- a/lib/Sema/SemaPseudoObject.cpp
+++ b/lib/Sema/SemaPseudoObject.cpp
@@ -31,6 +31,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Sema/SemaInternal.h"
+#include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/Basic/CharInfo.h"
 #include "clang/Lex/Preprocessor.h"
@@ -235,7 +236,10 @@
     }
 
     /// Return true if assignments have a non-void result.
-    bool CanCaptureValueOfType(QualType ty) {
+    bool CanCaptureValue(Expr *exp) {
+      if (exp->isGLValue())
+        return true;
+      QualType ty = exp->getType();
       assert(!ty->isIncompleteType());
       assert(!ty->isDependentType());
 
@@ -264,7 +268,8 @@
   public:
     ObjCPropertyOpBuilder(Sema &S, ObjCPropertyRefExpr *refExpr) :
       PseudoOpBuilder(S, refExpr->getLocation()), RefExpr(refExpr),
-      SyntacticRefExpr(0), InstanceReceiver(0), Getter(0), Setter(0) {
+      SyntacticRefExpr(nullptr), InstanceReceiver(nullptr), Getter(nullptr),
+      Setter(nullptr) {
     }
 
     ExprResult buildRValueOperation(Expr *op);
@@ -279,11 +284,12 @@
     bool tryBuildGetOfReference(Expr *op, ExprResult &result);
     bool findSetter(bool warn=true);
     bool findGetter();
+    void DiagnoseUnsupportedPropertyUse();
 
-    Expr *rebuildAndCaptureObject(Expr *syntacticBase);
-    ExprResult buildGet();
-    ExprResult buildSet(Expr *op, SourceLocation, bool);
-    ExprResult complete(Expr *SyntacticForm);
+    Expr *rebuildAndCaptureObject(Expr *syntacticBase) override;
+    ExprResult buildGet() override;
+    ExprResult buildSet(Expr *op, SourceLocation, bool) override;
+    ExprResult complete(Expr *SyntacticForm) override;
 
     bool isWeakProperty() const;
   };
@@ -303,21 +309,21 @@
     ObjCSubscriptOpBuilder(Sema &S, ObjCSubscriptRefExpr *refExpr) :
       PseudoOpBuilder(S, refExpr->getSourceRange().getBegin()), 
       RefExpr(refExpr),
-    InstanceBase(0), InstanceKey(0), 
-    AtIndexGetter(0), AtIndexSetter(0) { }
-  
+      InstanceBase(nullptr), InstanceKey(nullptr),
+      AtIndexGetter(nullptr), AtIndexSetter(nullptr) {}
+
    ExprResult buildRValueOperation(Expr *op);
    ExprResult buildAssignmentOperation(Scope *Sc,
                                        SourceLocation opLoc,
                                        BinaryOperatorKind opcode,
                                        Expr *LHS, Expr *RHS);
-   Expr *rebuildAndCaptureObject(Expr *syntacticBase);
-   
+   Expr *rebuildAndCaptureObject(Expr *syntacticBase) override;
+
    bool findAtIndexGetter();
    bool findAtIndexSetter();
-  
-   ExprResult buildGet();
-   ExprResult buildSet(Expr *op, SourceLocation, bool);
+
+   ExprResult buildGet() override;
+   ExprResult buildSet(Expr *op, SourceLocation, bool) override;
  };
 
  class MSPropertyOpBuilder : public PseudoOpBuilder {
@@ -328,9 +334,9 @@
      PseudoOpBuilder(S, refExpr->getSourceRange().getBegin()),
      RefExpr(refExpr) {}
 
-   Expr *rebuildAndCaptureObject(Expr *);
-   ExprResult buildGet();
-   ExprResult buildSet(Expr *op, SourceLocation, bool);
+   Expr *rebuildAndCaptureObject(Expr *) override;
+   ExprResult buildGet() override;
+   ExprResult buildSet(Expr *op, SourceLocation, bool) override;
  };
 }
 
@@ -388,7 +394,7 @@
 
   ExprResult getExpr = buildGet();
   if (getExpr.isInvalid()) return ExprError();
-  addResultSemanticExpr(getExpr.take());
+  addResultSemanticExpr(getExpr.get());
 
   return complete(syntacticBase);
 }
@@ -421,7 +427,7 @@
     BinaryOperatorKind nonCompound =
       BinaryOperator::getOpForCompoundAssignment(opcode);
     result = S.BuildBinOp(Sc, opcLoc, nonCompound,
-                          opLHS.take(), capturedRHS);
+                          opLHS.get(), capturedRHS);
     if (result.isInvalid()) return ExprError();
 
     syntactic =
@@ -436,9 +442,9 @@
 
   // The result of the assignment, if not void, is the value set into
   // the l-value.
-  result = buildSet(result.take(), opcLoc, /*captureSetValueAsResult*/ true);
+  result = buildSet(result.get(), opcLoc, /*captureSetValueAsResult*/ true);
   if (result.isInvalid()) return ExprError();
-  addSemanticExpr(result.take());
+  addSemanticExpr(result.get());
 
   return complete(syntactic);
 }
@@ -461,8 +467,8 @@
 
   // That's the postfix result.
   if (UnaryOperator::isPostfix(opcode) &&
-      (result.get()->isTypeDependent() || CanCaptureValueOfType(resultType))) {
-    result = capture(result.take());
+      (result.get()->isTypeDependent() || CanCaptureValue(result.get()))) {
+    result = capture(result.get());
     setResultToLastSemantic();
   }
 
@@ -472,17 +478,17 @@
                                      GenericLoc);
 
   if (UnaryOperator::isIncrementOp(opcode)) {
-    result = S.BuildBinOp(Sc, opcLoc, BO_Add, result.take(), one);
+    result = S.BuildBinOp(Sc, opcLoc, BO_Add, result.get(), one);
   } else {
-    result = S.BuildBinOp(Sc, opcLoc, BO_Sub, result.take(), one);
+    result = S.BuildBinOp(Sc, opcLoc, BO_Sub, result.get(), one);
   }
   if (result.isInvalid()) return ExprError();
 
   // Store that back into the result.  The value stored is the result
   // of a prefix operation.
-  result = buildSet(result.take(), opcLoc, UnaryOperator::isPrefix(opcode));
+  result = buildSet(result.get(), opcLoc, UnaryOperator::isPrefix(opcode));
   if (result.isInvalid()) return ExprError();
-  addSemanticExpr(result.take());
+  addSemanticExpr(result.get());
 
   UnaryOperator *syntactic =
     new (S.Context) UnaryOperator(syntacticOp, opcode, resultType,
@@ -536,11 +542,11 @@
   if (RefExpr->isExplicitProperty()) {
     const ObjCPropertyDecl *Prop = RefExpr->getExplicitProperty();
     if (Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_weak)
-      return true;
+      return !Prop->hasAttr<IBOutletAttr>();
 
     T = Prop->getType();
   } else if (Getter) {
-    T = Getter->getResultType();
+    T = Getter->getReturnType();
   } else {
     return false;
   }
@@ -563,19 +569,17 @@
       assert(setter && "both setter and getter are null - cannot happen");
       IdentifierInfo *setterName = 
         setter->getSelector().getIdentifierInfoForSlot(0);
-      const char *compStr = setterName->getNameStart();
-      compStr += 3;
-      IdentifierInfo *getterName = &S.Context.Idents.get(compStr);
+      IdentifierInfo *getterName =
+          &S.Context.Idents.get(setterName->getName().substr(3));
       GetterSelector = 
         S.PP.getSelectorTable().getNullarySelector(getterName);
       return false;
-
     }
   }
 
   ObjCPropertyDecl *prop = RefExpr->getExplicitProperty();
   Getter = LookupMethodInReceiverType(S, prop->getGetterName(), RefExpr);
-  return (Getter != 0);
+  return (Getter != nullptr);
 }
 
 /// Try to find the most accurate setter declaration for the property
@@ -621,7 +625,7 @@
         if (ObjCPropertyDecl *prop1 = IFace->FindPropertyDeclaration(AltMember))
           if (prop != prop1 && (prop1->getSetterMethodDecl() == setter)) {
             S.Diag(RefExpr->getExprLoc(), diag::error_property_setter_ambiguous_use)
-              << prop->getName() << prop1->getName() << setter->getSelector();
+              << prop << prop1 << setter->getSelector();
             S.Diag(prop->getLocation(), diag::note_property_declare);
             S.Diag(prop1->getLocation(), diag::note_property_declare);
           }
@@ -638,9 +642,21 @@
   return false;
 }
 
+void ObjCPropertyOpBuilder::DiagnoseUnsupportedPropertyUse() {
+  if (S.getCurLexicalContext()->isObjCContainer() &&
+      S.getCurLexicalContext()->getDeclKind() != Decl::ObjCCategoryImpl &&
+      S.getCurLexicalContext()->getDeclKind() != Decl::ObjCImplementation) {
+    if (ObjCPropertyDecl *prop = RefExpr->getExplicitProperty()) {
+        S.Diag(RefExpr->getLocation(),
+               diag::err_property_function_in_objc_container);
+        S.Diag(prop->getLocation(), diag::note_property_declare);
+    }
+  }
+}
+
 /// Capture the base object of an Objective-C property expression.
 Expr *ObjCPropertyOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) {
-  assert(InstanceReceiver == 0);
+  assert(InstanceReceiver == nullptr);
 
   // If we have a base, capture it in an OVE and rebuild the syntactic
   // form to use the OVE as its base.
@@ -661,7 +677,10 @@
 /// Load from an Objective-C property reference.
 ExprResult ObjCPropertyOpBuilder::buildGet() {
   findGetter();
-  assert(Getter);
+  if (!Getter) {
+    DiagnoseUnsupportedPropertyUse();
+    return ExprError();
+  }
 
   if (SyntacticRefExpr)
     SyntacticRefExpr->setIsMessagingGetter();
@@ -675,10 +694,12 @@
     assert(InstanceReceiver);
     receiverType = InstanceReceiver->getType();
   }
-
+  if (!Getter->isImplicit())
+    S.DiagnoseUseOfDecl(Getter, GenericLoc, nullptr, true);
   // Build a message-send.
   ExprResult msg;
-  if (Getter->isInstanceMethod() || RefExpr->isObjectReceiver()) {
+  if ((Getter->isInstanceMethod() && !RefExpr->isClassReceiver()) ||
+      RefExpr->isObjectReceiver()) {
     assert(InstanceReceiver || RefExpr->isSuperReceiver());
     msg = S.BuildInstanceMessageImplicit(InstanceReceiver, receiverType,
                                          GenericLoc, Getter->getSelector(),
@@ -697,8 +718,10 @@
 ///   value being set as the value of the property operation.
 ExprResult ObjCPropertyOpBuilder::buildSet(Expr *op, SourceLocation opcLoc,
                                            bool captureSetValueAsResult) {
-  bool hasSetter = findSetter(false);
-  assert(hasSetter); (void) hasSetter;
+  if (!findSetter(false)) {
+    DiagnoseUnsupportedPropertyUse();
+    return ExprError();
+  }
 
   if (SyntacticRefExpr)
     SyntacticRefExpr->setIsMessagingSetter();
@@ -727,7 +750,7 @@
                                      Sema::AA_Assigning))
         return ExprError();
 
-      op = opResult.take();
+      op = opResult.get();
       assert(op && "successful assignment left argument invalid?");
     }
     else if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(op)) {
@@ -747,7 +770,10 @@
 
   // Build a message-send.
   ExprResult msg;
-  if (Setter->isInstanceMethod() || RefExpr->isObjectReceiver()) {
+  if (!Setter->isImplicit())
+    S.DiagnoseUseOfDecl(Setter, GenericLoc, nullptr, true);
+  if ((Setter->isInstanceMethod() && !RefExpr->isClassReceiver()) ||
+      RefExpr->isObjectReceiver()) {
     msg = S.BuildInstanceMessageImplicit(InstanceReceiver, receiverType,
                                          GenericLoc, SetterSelector, Setter,
                                          MultiExprArg(args, 1));
@@ -762,7 +788,7 @@
     ObjCMessageExpr *msgExpr =
       cast<ObjCMessageExpr>(msg.get()->IgnoreImplicit());
     Expr *arg = msgExpr->getArg(0);
-    if (CanCaptureValueOfType(arg->getType()))
+    if (CanCaptureValue(arg))
       msgExpr->setArg(0, captureValueAsResult(arg));
   }
 
@@ -788,13 +814,20 @@
 
   // As a special case, if the method returns 'id', try to get
   // a better type from the property.
-  if (RefExpr->isExplicitProperty() && result.get()->isRValue() &&
-      result.get()->getType()->isObjCIdType()) {
+  if (RefExpr->isExplicitProperty() && result.get()->isRValue()) {
     QualType propType = RefExpr->getExplicitProperty()->getType();
-    if (const ObjCObjectPointerType *ptr
-          = propType->getAs<ObjCObjectPointerType>()) {
-      if (!ptr->isObjCIdType())
-        result = S.ImpCastExprToType(result.get(), propType, CK_BitCast);
+    if (result.get()->getType()->isObjCIdType()) {
+      if (const ObjCObjectPointerType *ptr
+            = propType->getAs<ObjCObjectPointerType>()) {
+        if (!ptr->isObjCIdType())
+          result = S.ImpCastExprToType(result.get(), propType, CK_BitCast);
+      }
+    }
+    if (S.getLangOpts().ObjCAutoRefCount) {
+      Qualifiers::ObjCLifetime LT = propType.getObjCLifetime();
+      if (LT == Qualifiers::OCL_Weak)
+        if (!S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, RefExpr->getLocation()))
+              S.getCurFunction()->markSafeWeakUse(RefExpr);
     }
   }
 
@@ -810,10 +843,15 @@
   if (!S.getLangOpts().CPlusPlus) return false;
 
   findGetter();
-  assert(Getter && "property has no setter and no getter!");
+  if (!Getter) {
+    // The property has no setter and no getter! This can happen if the type is
+    // invalid. Error have already been reported.
+    result = ExprError();
+    return true;
+  }
 
   // Only do this if the getter returns an l-value reference type.
-  QualType resultType = Getter->getResultType();
+  QualType resultType = Getter->getReturnType();
   if (!resultType->isLValueReferenceType()) return false;
 
   result = buildRValueOperation(op);
@@ -834,7 +872,7 @@
     ExprResult result;
     if (tryBuildGetOfReference(LHS, result)) {
       if (result.isInvalid()) return ExprError();
-      return S.BuildBinOp(Sc, opcLoc, opcode, result.take(), RHS);
+      return S.BuildBinOp(Sc, opcLoc, opcode, result.get(), RHS);
     }
 
     // Otherwise, it's an error.
@@ -878,7 +916,7 @@
     ExprResult result;
     if (tryBuildGetOfReference(op, result)) {
       if (result.isInvalid()) return ExprError();
-      return S.BuildUnaryOp(Sc, opcLoc, opcode, result.take());
+      return S.BuildUnaryOp(Sc, opcLoc, opcode, result.get());
     }
 
     // Otherwise, it's an error.
@@ -906,14 +944,11 @@
 }
 
 ExprResult ObjCPropertyOpBuilder::complete(Expr *SyntacticForm) {
-  if (S.getLangOpts().ObjCAutoRefCount && isWeakProperty()) {
-    DiagnosticsEngine::Level Level =
-      S.Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak,
-                                 SyntacticForm->getLocStart());
-    if (Level != DiagnosticsEngine::Ignored)
+  if (S.getLangOpts().ObjCAutoRefCount && isWeakProperty() &&
+      !S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak,
+                         SyntacticForm->getLocStart()))
       S.recordUseOfEvaluatedWeak(SyntacticRefExpr,
                                  SyntacticRefExpr->isMessagingGetter());
-  }
 
   return PseudoOpBuilder::complete(SyntacticForm);
 }
@@ -961,8 +996,8 @@
 
 /// Capture the base object of an Objective-C Index'ed expression.
 Expr *ObjCSubscriptOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) {
-  assert(InstanceBase == 0);
-  
+  assert(InstanceBase == nullptr);
+
   // Capture base expression in an OVE and rebuild the syntactic
   // form to use the OVE as its base expression.
   InstanceBase = capture(RefExpr->getBaseExpr());
@@ -1011,8 +1046,6 @@
   
   // Look for a conversion to an integral, enumeration type, or
   // objective-C pointer type.
-  UnresolvedSet<4> ViableConversions;
-  UnresolvedSet<4> ExplicitConversions;
   std::pair<CXXRecordDecl::conversion_iterator,
             CXXRecordDecl::conversion_iterator> Conversions
     = cast<CXXRecordDecl>(RecordTy->getDecl())->getVisibleConversionFunctions();
@@ -1069,7 +1102,7 @@
                                                       true /*instance*/);
   if (!Getter)
     return;
-  QualType T = Getter->param_begin()[0]->getType();
+  QualType T = Getter->parameters()[0]->getType();
   S.CheckObjCARCConversion(Key->getSourceRange(), 
                          T, Key, Sema::CCK_ImplicitConversion);
 }
@@ -1130,7 +1163,7 @@
     AtIndexGetter = ObjCMethodDecl::Create(S.Context, SourceLocation(), 
                            SourceLocation(), AtIndexGetterSelector,
                            S.Context.getObjCIdType() /*ReturnType*/,
-                           0 /*TypeSourceInfo */,
+                           nullptr /*TypeSourceInfo */,
                            S.Context.getTranslationUnitDecl(),
                            true /*Instance*/, false/*isVariadic*/,
                            /*isPropertyAccessor=*/false,
@@ -1143,9 +1176,9 @@
                                                          : &S.Context.Idents.get("key"),
                                                 arrayRef ? S.Context.UnsignedLongTy
                                                          : S.Context.getObjCIdType(),
-                                                /*TInfo=*/0,
+                                                /*TInfo=*/nullptr,
                                                 SC_None,
-                                                0);
+                                                nullptr);
     AtIndexGetter->setMethodParams(S.Context, Argument, None);
   }
 
@@ -1162,17 +1195,17 @@
   }
   
   if (AtIndexGetter) {
-    QualType T = AtIndexGetter->param_begin()[0]->getType();
+    QualType T = AtIndexGetter->parameters()[0]->getType();
     if ((arrayRef && !T->isIntegralOrEnumerationType()) ||
         (!arrayRef && !T->isObjCObjectPointerType())) {
       S.Diag(RefExpr->getKeyExpr()->getExprLoc(), 
              arrayRef ? diag::err_objc_subscript_index_type
                       : diag::err_objc_subscript_key_type) << T;
-      S.Diag(AtIndexGetter->param_begin()[0]->getLocation(), 
+      S.Diag(AtIndexGetter->parameters()[0]->getLocation(), 
              diag::note_parameter_type) << T;
       return false;
     }
-    QualType R = AtIndexGetter->getResultType();
+    QualType R = AtIndexGetter->getReturnType();
     if (!R->isObjCObjectPointerType()) {
       S.Diag(RefExpr->getKeyExpr()->getExprLoc(),
              diag::err_objc_indexing_method_result_type) << R << arrayRef;
@@ -1239,26 +1272,23 @@
                          BaseT->isObjCQualifiedIdType());
 
   if (!AtIndexSetter && S.getLangOpts().DebuggerObjCLiteral) {
-    TypeSourceInfo *ResultTInfo = 0;
+    TypeSourceInfo *ReturnTInfo = nullptr;
     QualType ReturnType = S.Context.VoidTy;
-    AtIndexSetter = ObjCMethodDecl::Create(S.Context, SourceLocation(),
-                           SourceLocation(), AtIndexSetterSelector,
-                           ReturnType,
-                           ResultTInfo,
-                           S.Context.getTranslationUnitDecl(),
-                           true /*Instance*/, false/*isVariadic*/,
-                           /*isPropertyAccessor=*/false,
-                           /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
-                           ObjCMethodDecl::Required,
-                           false); 
+    AtIndexSetter = ObjCMethodDecl::Create(
+        S.Context, SourceLocation(), SourceLocation(), AtIndexSetterSelector,
+        ReturnType, ReturnTInfo, S.Context.getTranslationUnitDecl(),
+        true /*Instance*/, false /*isVariadic*/,
+        /*isPropertyAccessor=*/false,
+        /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
+        ObjCMethodDecl::Required, false);
     SmallVector<ParmVarDecl *, 2> Params;
     ParmVarDecl *object = ParmVarDecl::Create(S.Context, AtIndexSetter,
                                                 SourceLocation(), SourceLocation(),
                                                 &S.Context.Idents.get("object"),
                                                 S.Context.getObjCIdType(),
-                                                /*TInfo=*/0,
+                                                /*TInfo=*/nullptr,
                                                 SC_None,
-                                                0);
+                                                nullptr);
     Params.push_back(object);
     ParmVarDecl *key = ParmVarDecl::Create(S.Context, AtIndexSetter,
                                                 SourceLocation(), SourceLocation(),
@@ -1266,9 +1296,9 @@
                                                          :  &S.Context.Idents.get("key"),
                                                 arrayRef ? S.Context.UnsignedLongTy
                                                          : S.Context.getObjCIdType(),
-                                                /*TInfo=*/0,
+                                                /*TInfo=*/nullptr,
                                                 SC_None,
-                                                0);
+                                                nullptr);
     Params.push_back(key);
     AtIndexSetter->setMethodParams(S.Context, Params, None);
   }
@@ -1288,26 +1318,26 @@
   
   bool err = false;
   if (AtIndexSetter && arrayRef) {
-    QualType T = AtIndexSetter->param_begin()[1]->getType();
+    QualType T = AtIndexSetter->parameters()[1]->getType();
     if (!T->isIntegralOrEnumerationType()) {
       S.Diag(RefExpr->getKeyExpr()->getExprLoc(), 
              diag::err_objc_subscript_index_type) << T;
-      S.Diag(AtIndexSetter->param_begin()[1]->getLocation(), 
+      S.Diag(AtIndexSetter->parameters()[1]->getLocation(), 
              diag::note_parameter_type) << T;
       err = true;
     }
-    T = AtIndexSetter->param_begin()[0]->getType();
+    T = AtIndexSetter->parameters()[0]->getType();
     if (!T->isObjCObjectPointerType()) {
       S.Diag(RefExpr->getBaseExpr()->getExprLoc(), 
              diag::err_objc_subscript_object_type) << T << arrayRef;
-      S.Diag(AtIndexSetter->param_begin()[0]->getLocation(), 
+      S.Diag(AtIndexSetter->parameters()[0]->getLocation(), 
              diag::note_parameter_type) << T;
       err = true;
     }
   }
   else if (AtIndexSetter && !arrayRef)
     for (unsigned i=0; i <2; i++) {
-      QualType T = AtIndexSetter->param_begin()[i]->getType();
+      QualType T = AtIndexSetter->parameters()[i]->getType();
       if (!T->isObjCObjectPointerType()) {
         if (i == 1)
           S.Diag(RefExpr->getKeyExpr()->getExprLoc(),
@@ -1315,7 +1345,7 @@
         else
           S.Diag(RefExpr->getBaseExpr()->getExprLoc(),
                  diag::err_objc_subscript_dic_object_type) << T;
-        S.Diag(AtIndexSetter->param_begin()[i]->getLocation(), 
+        S.Diag(AtIndexSetter->parameters()[i]->getLocation(), 
                diag::note_parameter_type) << T;
         err = true;
       }
@@ -1339,6 +1369,8 @@
   // Arguments.
   Expr *args[] = { Index };
   assert(InstanceBase);
+  if (AtIndexGetter)
+    S.DiagnoseUseOfDecl(AtIndexGetter, GenericLoc);
   msg = S.BuildInstanceMessageImplicit(InstanceBase, receiverType,
                                        GenericLoc,
                                        AtIndexGetterSelector, AtIndexGetter,
@@ -1355,7 +1387,8 @@
                                            bool captureSetValueAsResult) {
   if (!findAtIndexSetter())
     return ExprError();
-  
+  if (AtIndexSetter)
+    S.DiagnoseUseOfDecl(AtIndexSetter, GenericLoc);
   QualType receiverType = InstanceBase->getType();
   Expr *Index = InstanceKey;
   
@@ -1373,7 +1406,7 @@
     ObjCMessageExpr *msgExpr =
       cast<ObjCMessageExpr>(msg.get()->IgnoreImplicit());
     Expr *arg = msgExpr->getArg(0);
-    if (CanCaptureValueOfType(arg->getType()))
+    if (CanCaptureValue(arg))
       msgExpr->setArg(0, captureValueAsResult(arg));
   }
   
@@ -1395,8 +1428,8 @@
 
 ExprResult MSPropertyOpBuilder::buildGet() {
   if (!RefExpr->getPropertyDecl()->hasGetter()) {
-    S.Diag(RefExpr->getMemberLoc(), diag::err_no_getter_for_property)
-      << RefExpr->getPropertyDecl()->getName();
+    S.Diag(RefExpr->getMemberLoc(), diag::err_no_accessor_for_property)
+      << 0 /* getter */ << RefExpr->getPropertyDecl();
     return ExprError();
   }
 
@@ -1408,15 +1441,16 @@
   ExprResult GetterExpr = S.ActOnMemberAccessExpr(
     S.getCurScope(), RefExpr->getBaseExpr(), SourceLocation(),
     RefExpr->isArrow() ? tok::arrow : tok::period, SS, SourceLocation(),
-    GetterName, 0, true);
+    GetterName, nullptr, true);
   if (GetterExpr.isInvalid()) {
-    S.Diag(RefExpr->getMemberLoc(), diag::error_cannot_find_suitable_getter)
-      << RefExpr->getPropertyDecl()->getName();
+    S.Diag(RefExpr->getMemberLoc(),
+           diag::error_cannot_find_suitable_accessor) << 0 /* getter */
+      << RefExpr->getPropertyDecl();
     return ExprError();
   }
 
   MultiExprArg ArgExprs;
-  return S.ActOnCallExpr(S.getCurScope(), GetterExpr.take(),
+  return S.ActOnCallExpr(S.getCurScope(), GetterExpr.get(),
                          RefExpr->getSourceRange().getBegin(), ArgExprs,
                          RefExpr->getSourceRange().getEnd());
 }
@@ -1424,8 +1458,8 @@
 ExprResult MSPropertyOpBuilder::buildSet(Expr *op, SourceLocation sl,
                                          bool captureSetValueAsResult) {
   if (!RefExpr->getPropertyDecl()->hasSetter()) {
-    S.Diag(RefExpr->getMemberLoc(), diag::err_no_setter_for_property)
-      << RefExpr->getPropertyDecl()->getName();
+    S.Diag(RefExpr->getMemberLoc(), diag::err_no_accessor_for_property)
+      << 1 /* setter */ << RefExpr->getPropertyDecl();
     return ExprError();
   }
 
@@ -1437,16 +1471,17 @@
   ExprResult SetterExpr = S.ActOnMemberAccessExpr(
     S.getCurScope(), RefExpr->getBaseExpr(), SourceLocation(),
     RefExpr->isArrow() ? tok::arrow : tok::period, SS, SourceLocation(),
-    SetterName, 0, true);
+    SetterName, nullptr, true);
   if (SetterExpr.isInvalid()) {
-    S.Diag(RefExpr->getMemberLoc(), diag::error_cannot_find_suitable_setter)
-      << RefExpr->getPropertyDecl()->getName();
+    S.Diag(RefExpr->getMemberLoc(),
+           diag::error_cannot_find_suitable_accessor) << 1 /* setter */
+      << RefExpr->getPropertyDecl();
     return ExprError();
   }
 
   SmallVector<Expr*, 1> ArgExprs;
   ArgExprs.push_back(op);
-  return S.ActOnCallExpr(S.getCurScope(), SetterExpr.take(),
+  return S.ActOnCallExpr(S.getCurScope(), SetterExpr.get(),
                          RefExpr->getSourceRange().getBegin(), ArgExprs,
                          op->getSourceRange().getEnd());
 }
@@ -1513,7 +1548,7 @@
   if (RHS->getType()->isNonOverloadPlaceholderType()) {
     ExprResult result = CheckPlaceholderExpr(RHS);
     if (result.isInvalid()) return ExprError();
-    RHS = result.take();
+    RHS = result.get();
   }
 
   Expr *opaqueRef = LHS->IgnoreParens();
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 9bd8678..278e6d6 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -49,7 +49,7 @@
   // operand, even incomplete types.
 
   // Same thing in for stmt first clause (when expr) and third clause.
-  return Owned(static_cast<Stmt*>(FE.take()));
+  return StmtResult(FE.getAs<Stmt>());
 }
 
 
@@ -60,7 +60,7 @@
 
 StmtResult Sema::ActOnNullStmt(SourceLocation SemiLoc,
                                bool HasLeadingEmptyMacro) {
-  return Owned(new (Context) NullStmt(SemiLoc, HasLeadingEmptyMacro));
+  return new (Context) NullStmt(SemiLoc, HasLeadingEmptyMacro);
 }
 
 StmtResult Sema::ActOnDeclStmt(DeclGroupPtrTy dg, SourceLocation StartLoc,
@@ -70,7 +70,7 @@
   // If we have an invalid decl, just return an error.
   if (DG.isNull()) return StmtError();
 
-  return Owned(new (Context) DeclStmt(DG, StartLoc, EndLoc));
+  return new (Context) DeclStmt(DG, StartLoc, EndLoc);
 }
 
 void Sema::ActOnForEachDeclStmt(DeclGroupPtrTy dg) {
@@ -95,7 +95,7 @@
 
   // foreach variables are never actually initialized in the way that
   // the parser came up with.
-  var->setInit(0);
+  var->setInit(nullptr);
 
   // In ARC, we don't need to retain the iteration variable of a fast
   // enumeration loop.  Rather than actually trying to catch that
@@ -114,25 +114,38 @@
   }
 }
 
-/// \brief Diagnose unused '==' and '!=' as likely typos for '=' or '|='.
+/// \brief Diagnose unused comparisons, both builtin and overloaded operators.
+/// For '==' and '!=', suggest fixits for '=' or '|='.
 ///
 /// Adding a cast to void (or other expression wrappers) will prevent the
 /// warning from firing.
 static bool DiagnoseUnusedComparison(Sema &S, const Expr *E) {
   SourceLocation Loc;
-  bool IsNotEqual, CanAssign;
+  bool IsNotEqual, CanAssign, IsRelational;
 
   if (const BinaryOperator *Op = dyn_cast<BinaryOperator>(E)) {
-    if (Op->getOpcode() != BO_EQ && Op->getOpcode() != BO_NE)
+    if (!Op->isComparisonOp())
       return false;
 
+    IsRelational = Op->isRelationalOp();
     Loc = Op->getOperatorLoc();
     IsNotEqual = Op->getOpcode() == BO_NE;
     CanAssign = Op->getLHS()->IgnoreParenImpCasts()->isLValue();
   } else if (const CXXOperatorCallExpr *Op = dyn_cast<CXXOperatorCallExpr>(E)) {
-    if (Op->getOperator() != OO_EqualEqual &&
-        Op->getOperator() != OO_ExclaimEqual)
+    switch (Op->getOperator()) {
+    default:
       return false;
+    case OO_EqualEqual:
+    case OO_ExclaimEqual:
+      IsRelational = false;
+      break;
+    case OO_Less:
+    case OO_Greater:
+    case OO_GreaterEqual:
+    case OO_LessEqual:
+      IsRelational = true;
+      break;
+    }
 
     Loc = Op->getOperatorLoc();
     IsNotEqual = Op->getOperator() == OO_ExclaimEqual;
@@ -148,11 +161,11 @@
     return false;
 
   S.Diag(Loc, diag::warn_unused_comparison)
-    << (unsigned)IsNotEqual << E->getSourceRange();
+    << (unsigned)IsRelational << (unsigned)IsNotEqual << E->getSourceRange();
 
   // If the LHS is a plausible entity to assign to, provide a fixit hint to
   // correct common typos.
-  if (CanAssign) {
+  if (!IsRelational && CanAssign) {
     if (IsNotEqual)
       S.Diag(Loc, diag::note_inequality_comparison_to_or_assign)
         << FixItHint::CreateReplacement(Loc, "|=");
@@ -216,17 +229,17 @@
     // is written in a macro body, only warn if it has the warn_unused_result
     // attribute.
     if (const Decl *FD = CE->getCalleeDecl()) {
-      if (FD->getAttr<WarnUnusedResultAttr>()) {
+      if (FD->hasAttr<WarnUnusedResultAttr>()) {
         Diag(Loc, diag::warn_unused_result) << R1 << R2;
         return;
       }
       if (ShouldSuppress)
         return;
-      if (FD->getAttr<PureAttr>()) {
+      if (FD->hasAttr<PureAttr>()) {
         Diag(Loc, diag::warn_unused_call) << R1 << R2 << "pure";
         return;
       }
-      if (FD->getAttr<ConstAttr>()) {
+      if (FD->hasAttr<ConstAttr>()) {
         Diag(Loc, diag::warn_unused_call) << R1 << R2 << "const";
         return;
       }
@@ -240,9 +253,15 @@
       return;
     }
     const ObjCMethodDecl *MD = ME->getMethodDecl();
-    if (MD && MD->getAttr<WarnUnusedResultAttr>()) {
-      Diag(Loc, diag::warn_unused_result) << R1 << R2;
-      return;
+    if (MD) {
+      if (MD->hasAttr<WarnUnusedResultAttr>()) {
+        Diag(Loc, diag::warn_unused_result) << R1 << R2;
+        return;
+      }
+      if (MD->isPropertyAccessor()) {
+        Diag(Loc, diag::warn_unused_property_expr);
+        return;
+      }
     }
   } else if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E)) {
     const Expr *Source = POE->getSyntacticForm();
@@ -276,7 +295,7 @@
     return;
   }
 
-  DiagRuntimeBehavior(Loc, 0, PDiag(DiagID) << R1 << R2);
+  DiagRuntimeBehavior(Loc, nullptr, PDiag(DiagID) << R1 << R2);
 }
 
 void Sema::ActOnStartOfCompoundStmt() {
@@ -331,14 +350,14 @@
       DiagnoseEmptyLoopBody(Elts[i], Elts[i + 1]);
   }
 
-  return Owned(new (Context) CompoundStmt(Context, Elts, L, R));
+  return new (Context) CompoundStmt(Context, Elts, L, R);
 }
 
 StmtResult
 Sema::ActOnCaseStmt(SourceLocation CaseLoc, Expr *LHSVal,
                     SourceLocation DotDotDotLoc, Expr *RHSVal,
                     SourceLocation ColonLoc) {
-  assert((LHSVal != 0) && "missing expression in case statement");
+  assert(LHSVal && "missing expression in case statement");
 
   if (getCurFunction()->SwitchStack.empty()) {
     Diag(CaseLoc, diag::err_case_not_in_switch);
@@ -349,7 +368,7 @@
     // C99 6.8.4.2p3: The expression shall be an integer constant.
     // However, GCC allows any evaluatable integer expression.
     if (!LHSVal->isTypeDependent() && !LHSVal->isValueDependent()) {
-      LHSVal = VerifyIntegerConstantExpression(LHSVal).take();
+      LHSVal = VerifyIntegerConstantExpression(LHSVal).get();
       if (!LHSVal)
         return StmtError();
     }
@@ -357,21 +376,21 @@
     // GCC extension: The expression shall be an integer constant.
 
     if (RHSVal && !RHSVal->isTypeDependent() && !RHSVal->isValueDependent()) {
-      RHSVal = VerifyIntegerConstantExpression(RHSVal).take();
+      RHSVal = VerifyIntegerConstantExpression(RHSVal).get();
       // Recover from an error by just forgetting about it.
     }
   }
 
   LHSVal = ActOnFinishFullExpr(LHSVal, LHSVal->getExprLoc(), false,
-                               getLangOpts().CPlusPlus11).take();
+                               getLangOpts().CPlusPlus11).get();
   if (RHSVal)
     RHSVal = ActOnFinishFullExpr(RHSVal, RHSVal->getExprLoc(), false,
-                                 getLangOpts().CPlusPlus11).take();
+                                 getLangOpts().CPlusPlus11).get();
 
   CaseStmt *CS = new (Context) CaseStmt(LHSVal, RHSVal, CaseLoc, DotDotDotLoc,
                                         ColonLoc);
   getCurFunction()->SwitchStack.back()->addSwitchCase(CS);
-  return Owned(CS);
+  return CS;
 }
 
 /// ActOnCaseStmtBody - This installs a statement as the body of a case.
@@ -389,12 +408,12 @@
 
   if (getCurFunction()->SwitchStack.empty()) {
     Diag(DefaultLoc, diag::err_default_not_in_switch);
-    return Owned(SubStmt);
+    return SubStmt;
   }
 
   DefaultStmt *DS = new (Context) DefaultStmt(DefaultLoc, ColonLoc, SubStmt);
   getCurFunction()->SwitchStack.back()->addSwitchCase(DS);
-  return Owned(DS);
+  return DS;
 }
 
 StmtResult
@@ -404,7 +423,7 @@
   if (TheDecl->getStmt()) {
     Diag(IdentLoc, diag::err_redefinition_of_label) << TheDecl->getDeclName();
     Diag(TheDecl->getLocation(), diag::note_previous_definition);
-    return Owned(SubStmt);
+    return SubStmt;
   }
 
   // Otherwise, things are good.  Fill in the declaration and return it.
@@ -414,7 +433,7 @@
     TheDecl->setLocStart(IdentLoc);
     TheDecl->setLocation(IdentLoc);
   }
-  return Owned(LS);
+  return LS;
 }
 
 StmtResult Sema::ActOnAttributedStmt(SourceLocation AttrLoc,
@@ -422,7 +441,7 @@
                                      Stmt *SubStmt) {
   // Fill in the declaration and return it.
   AttributedStmt *LS = AttributedStmt::Create(Context, AttrLoc, Attrs, SubStmt);
-  return Owned(LS);
+  return LS;
 }
 
 StmtResult
@@ -438,14 +457,14 @@
 
   ExprResult CondResult(CondVal.release());
 
-  VarDecl *ConditionVar = 0;
+  VarDecl *ConditionVar = nullptr;
   if (CondVar) {
     ConditionVar = cast<VarDecl>(CondVar);
     CondResult = CheckConditionVariable(ConditionVar, IfLoc, true);
     if (CondResult.isInvalid())
       return StmtError();
   }
-  Expr *ConditionExpr = CondResult.takeAs<Expr>();
+  Expr *ConditionExpr = CondResult.getAs<Expr>();
   if (!ConditionExpr)
     return StmtError();
 
@@ -458,8 +477,8 @@
 
   DiagnoseUnusedExprResult(elseStmt);
 
-  return Owned(new (Context) IfStmt(Context, IfLoc, ConditionVar, ConditionExpr,
-                                    thenStmt, ElseLoc, elseStmt));
+  return new (Context) IfStmt(Context, IfLoc, ConditionVar, ConditionExpr,
+                              thenStmt, ElseLoc, elseStmt);
 }
 
 /// ConvertIntegerToTypeWarnOnOverflow - Convert the specified APInt to have
@@ -499,7 +518,6 @@
     // We don't diagnose this overflow, because it is implementation-defined
     // behavior.
     // FIXME: Introduce a second, default-ignored warning for this case?
-    llvm::APSInt OldVal(Val);
     Val.setIsSigned(NewSign);
   }
 }
@@ -568,14 +586,14 @@
                              Decl *CondVar) {
   ExprResult CondResult;
 
-  VarDecl *ConditionVar = 0;
+  VarDecl *ConditionVar = nullptr;
   if (CondVar) {
     ConditionVar = cast<VarDecl>(CondVar);
     CondResult = CheckConditionVariable(ConditionVar, SourceLocation(), false);
     if (CondResult.isInvalid())
       return StmtError();
 
-    Cond = CondResult.release();
+    Cond = CondResult.get();
   }
 
   if (!Cond)
@@ -589,41 +607,41 @@
         : ICEConvertDiagnoser(/*AllowScopedEnumerations*/true, false, true),
           Cond(Cond) {}
 
-    virtual SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
-                                                 QualType T) {
+    SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
+                                         QualType T) override {
       return S.Diag(Loc, diag::err_typecheck_statement_requires_integer) << T;
     }
 
-    virtual SemaDiagnosticBuilder diagnoseIncomplete(
-        Sema &S, SourceLocation Loc, QualType T) {
+    SemaDiagnosticBuilder diagnoseIncomplete(
+        Sema &S, SourceLocation Loc, QualType T) override {
       return S.Diag(Loc, diag::err_switch_incomplete_class_type)
                << T << Cond->getSourceRange();
     }
 
-    virtual SemaDiagnosticBuilder diagnoseExplicitConv(
-        Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) {
+    SemaDiagnosticBuilder diagnoseExplicitConv(
+        Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override {
       return S.Diag(Loc, diag::err_switch_explicit_conversion) << T << ConvTy;
     }
 
-    virtual SemaDiagnosticBuilder noteExplicitConv(
-        Sema &S, CXXConversionDecl *Conv, QualType ConvTy) {
+    SemaDiagnosticBuilder noteExplicitConv(
+        Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override {
       return S.Diag(Conv->getLocation(), diag::note_switch_conversion)
         << ConvTy->isEnumeralType() << ConvTy;
     }
 
-    virtual SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
-                                                    QualType T) {
+    SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
+                                            QualType T) override {
       return S.Diag(Loc, diag::err_switch_multiple_conversions) << T;
     }
 
-    virtual SemaDiagnosticBuilder noteAmbiguous(
-        Sema &S, CXXConversionDecl *Conv, QualType ConvTy) {
+    SemaDiagnosticBuilder noteAmbiguous(
+        Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override {
       return S.Diag(Conv->getLocation(), diag::note_switch_conversion)
       << ConvTy->isEnumeralType() << ConvTy;
     }
 
-    virtual SemaDiagnosticBuilder diagnoseConversion(
-        Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) {
+    SemaDiagnosticBuilder diagnoseConversion(
+        Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override {
       llvm_unreachable("conversion functions are permitted");
     }
   } SwitchDiagnoser(Cond);
@@ -631,25 +649,25 @@
   CondResult =
       PerformContextualImplicitConversion(SwitchLoc, Cond, SwitchDiagnoser);
   if (CondResult.isInvalid()) return StmtError();
-  Cond = CondResult.take();
+  Cond = CondResult.get();
 
   // C99 6.8.4.2p5 - Integer promotions are performed on the controlling expr.
   CondResult = UsualUnaryConversions(Cond);
   if (CondResult.isInvalid()) return StmtError();
-  Cond = CondResult.take();
+  Cond = CondResult.get();
 
   if (!CondVar) {
     CondResult = ActOnFinishFullExpr(Cond, SwitchLoc);
     if (CondResult.isInvalid())
       return StmtError();
-    Cond = CondResult.take();
+    Cond = CondResult.get();
   }
 
   getCurFunction()->setHasBranchIntoScope();
 
   SwitchStmt *SS = new (Context) SwitchStmt(Context, ConditionVar, Cond);
   getCurFunction()->SwitchStack.push_back(SS);
-  return Owned(SS);
+  return SS;
 }
 
 static void AdjustAPSInt(llvm::APSInt &Val, unsigned BitWidth, bool IsSigned) {
@@ -660,6 +678,29 @@
   Val.setIsSigned(IsSigned);
 }
 
+/// Returns true if we should emit a diagnostic about this case expression not
+/// being a part of the enum used in the switch controlling expression.
+static bool ShouldDiagnoseSwitchCaseNotInEnum(const ASTContext &Ctx,
+                                              const EnumDecl *ED,
+                                              const Expr *CaseExpr) {
+  // Don't warn if the 'case' expression refers to a static const variable of
+  // the enum type.
+  CaseExpr = CaseExpr->IgnoreParenImpCasts();
+  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseExpr)) {
+    if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
+      if (!VD->hasGlobalStorage())
+        return true;
+      QualType VarType = VD->getType();
+      if (!VarType.isConstQualified())
+        return true;
+      QualType EnumType = Ctx.getTypeDeclType(ED);
+      if (Ctx.hasSameUnqualifiedType(EnumType, VarType))
+        return false;
+    }
+  }
+  return true;
+}
+
 StmtResult
 Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
                             Stmt *BodyStmt) {
@@ -667,6 +708,7 @@
   assert(SS == getCurFunction()->SwitchStack.back() &&
          "switch stack missing push/pop!");
 
+  if (!BodyStmt) return StmtError();
   SS->setBody(BodyStmt, SwitchLoc);
   getCurFunction()->SwitchStack.pop_back();
 
@@ -721,7 +763,7 @@
   typedef std::vector<std::pair<llvm::APSInt, CaseStmt*> > CaseRangesTy;
   CaseRangesTy CaseRanges;
 
-  DefaultStmt *TheDefaultStmt = 0;
+  DefaultStmt *TheDefaultStmt = nullptr;
 
   bool CaseListIsErroneous = false;
 
@@ -762,7 +804,7 @@
           CaseListIsErroneous = true;
           continue;
         }
-        Lo = ConvLo.take();
+        Lo = ConvLo.get();
       } else {
         // We already verified that the expression has a i-c-e value (C99
         // 6.8.4.2p3) - get that value now.
@@ -770,8 +812,8 @@
 
         // If the LHS is not the same type as the condition, insert an implicit
         // cast.
-        Lo = DefaultLvalueConversion(Lo).take();
-        Lo = ImpCastExprToType(Lo, CondType, CK_IntegralCast).take();
+        Lo = DefaultLvalueConversion(Lo).get();
+        Lo = ImpCastExprToType(Lo, CondType, CK_IntegralCast).get();
       }
 
       // Convert the value to the same width/sign as the condition had prior to
@@ -883,14 +925,14 @@
             CaseListIsErroneous = true;
             continue;
           }
-          Hi = ConvHi.take();
+          Hi = ConvHi.get();
         } else {
           HiVal = Hi->EvaluateKnownConstInt(Context);
 
           // If the RHS is not the same type as the condition, insert an
           // implicit cast.
-          Hi = DefaultLvalueConversion(Hi).take();
-          Hi = ImpCastExprToType(Hi, CondType, CK_IntegralCast).take();
+          Hi = DefaultLvalueConversion(Hi).get();
+          Hi = ImpCastExprToType(Hi, CondType, CK_IntegralCast).get();
         }
 
         // Convert the value to the same width/sign as the condition.
@@ -928,7 +970,7 @@
 
         // Check to see whether the case range overlaps with any
         // singleton cases.
-        CaseStmt *OverlapStmt = 0;
+        CaseStmt *OverlapStmt = nullptr;
         llvm::APSInt OverlapVal(32);
 
         // Find the smallest value >= the lower bound.  If I is in the
@@ -993,11 +1035,10 @@
 
       // Gather all enum values, set their type and sort them,
       // allowing easier comparison with CaseVals.
-      for (EnumDecl::enumerator_iterator EDI = ED->enumerator_begin();
-           EDI != ED->enumerator_end(); ++EDI) {
+      for (auto *EDI : ED->enumerators()) {
         llvm::APSInt Val = EDI->getInitVal();
         AdjustAPSInt(Val, CondWidth, CondIsSigned);
-        EnumVals.push_back(std::make_pair(Val, *EDI));
+        EnumVals.push_back(std::make_pair(Val, EDI));
       }
       std::stable_sort(EnumVals.begin(), EnumVals.end(), CmpEnumVals);
       EnumValsTy::iterator EIend =
@@ -1009,9 +1050,12 @@
            CI != CaseVals.end(); CI++) {
         while (EI != EIend && EI->first < CI->first)
           EI++;
-        if (EI == EIend || EI->first > CI->first)
-          Diag(CI->second->getLHS()->getExprLoc(), diag::warn_not_in_enum)
-            << CondTypeBeforePromotion;
+        if (EI == EIend || EI->first > CI->first) {
+          Expr *CaseExpr = CI->second->getLHS();
+          if (ShouldDiagnoseSwitchCaseNotInEnum(Context, ED, CaseExpr))
+            Diag(CaseExpr->getExprLoc(), diag::warn_not_in_enum)
+              << CondTypeBeforePromotion;
+        }
       }
       // See which of case ranges aren't in enum
       EI = EnumVals.begin();
@@ -1021,8 +1065,10 @@
           EI++;
 
         if (EI == EIend || EI->first != RI->first) {
-          Diag(RI->second->getLHS()->getExprLoc(), diag::warn_not_in_enum)
-            << CondTypeBeforePromotion;
+          Expr *CaseExpr = RI->second->getLHS();
+          if (ShouldDiagnoseSwitchCaseNotInEnum(Context, ED, CaseExpr))
+            Diag(CaseExpr->getExprLoc(), diag::warn_not_in_enum)
+              << CondTypeBeforePromotion;
         }
 
         llvm::APSInt Hi =
@@ -1030,9 +1076,12 @@
         AdjustAPSInt(Hi, CondWidth, CondIsSigned);
         while (EI != EIend && EI->first < Hi)
           EI++;
-        if (EI == EIend || EI->first != Hi)
-          Diag(RI->second->getRHS()->getExprLoc(), diag::warn_not_in_enum)
-            << CondTypeBeforePromotion;
+        if (EI == EIend || EI->first != Hi) {
+          Expr *CaseExpr = RI->second->getRHS();
+          if (ShouldDiagnoseSwitchCaseNotInEnum(Context, ED, CaseExpr))
+            Diag(CaseExpr->getExprLoc(), diag::warn_not_in_enum)
+              << CondTypeBeforePromotion;
+        }
       }
 
       // Check which enum vals aren't in switch
@@ -1044,7 +1093,6 @@
 
       for (EI = EnumVals.begin(); EI != EIend; EI++){
         // Drop unneeded case values
-        llvm::APSInt CIVal;
         while (CI != CaseVals.end() && CI->first < EI->first)
           CI++;
 
@@ -1100,27 +1148,26 @@
     }
   }
 
-  DiagnoseEmptyStmtBody(CondExpr->getLocEnd(), BodyStmt,
-                        diag::warn_empty_switch_body);
+  if (BodyStmt)
+    DiagnoseEmptyStmtBody(CondExpr->getLocEnd(), BodyStmt,
+                          diag::warn_empty_switch_body);
 
   // FIXME: If the case list was broken is some way, we don't have a good system
   // to patch it up.  Instead, just return the whole substmt as broken.
   if (CaseListIsErroneous)
     return StmtError();
 
-  return Owned(SS);
+  return SS;
 }
 
 void
 Sema::DiagnoseAssignmentEnum(QualType DstType, QualType SrcType,
                              Expr *SrcExpr) {
-  if (Diags.getDiagnosticLevel(diag::warn_not_in_enum_assignment,
-                               SrcExpr->getExprLoc()) ==
-      DiagnosticsEngine::Ignored)
+  if (Diags.isIgnored(diag::warn_not_in_enum_assignment, SrcExpr->getExprLoc()))
     return;
 
   if (const EnumType *ET = DstType->getAs<EnumType>())
-    if (!Context.hasSameType(SrcType, DstType) &&
+    if (!Context.hasSameUnqualifiedType(SrcType, DstType) &&
         SrcType->isIntegerType()) {
       if (!SrcExpr->isTypeDependent() && !SrcExpr->isValueDependent() &&
           SrcExpr->isIntegerConstantExpr(Context)) {
@@ -1137,11 +1184,10 @@
 
         // Gather all enum values, set their type and sort them,
         // allowing easier comparison with rhs constant.
-        for (EnumDecl::enumerator_iterator EDI = ED->enumerator_begin();
-             EDI != ED->enumerator_end(); ++EDI) {
+        for (auto *EDI : ED->enumerators()) {
           llvm::APSInt Val = EDI->getInitVal();
           AdjustAPSInt(Val, DstWidth, DstIsSigned);
-          EnumVals.push_back(std::make_pair(Val, *EDI));
+          EnumVals.push_back(std::make_pair(Val, EDI));
         }
         if (EnumVals.empty())
           return;
@@ -1155,7 +1201,7 @@
           EI++;
         if (EI == EIend || EI->first != RhsVal) {
           Diag(SrcExpr->getExprLoc(), diag::warn_not_in_enum_assignment)
-          << DstType;
+              << DstType.getUnqualifiedType();
         }
       }
     }
@@ -1166,24 +1212,25 @@
                      Decl *CondVar, Stmt *Body) {
   ExprResult CondResult(Cond.release());
 
-  VarDecl *ConditionVar = 0;
+  VarDecl *ConditionVar = nullptr;
   if (CondVar) {
     ConditionVar = cast<VarDecl>(CondVar);
     CondResult = CheckConditionVariable(ConditionVar, WhileLoc, true);
     if (CondResult.isInvalid())
       return StmtError();
   }
-  Expr *ConditionExpr = CondResult.take();
+  Expr *ConditionExpr = CondResult.get();
   if (!ConditionExpr)
     return StmtError();
+  CheckBreakContinueBinding(ConditionExpr);
 
   DiagnoseUnusedExprResult(Body);
 
   if (isa<NullStmt>(Body))
     getCurCompoundScope().setHasEmptyLoopBodies();
 
-  return Owned(new (Context) WhileStmt(Context, ConditionVar, ConditionExpr,
-                                       Body, WhileLoc));
+  return new (Context)
+      WhileStmt(Context, ConditionVar, ConditionExpr, Body, WhileLoc);
 }
 
 StmtResult
@@ -1192,19 +1239,20 @@
                   Expr *Cond, SourceLocation CondRParen) {
   assert(Cond && "ActOnDoStmt(): missing expression");
 
+  CheckBreakContinueBinding(Cond);
   ExprResult CondResult = CheckBooleanCondition(Cond, DoLoc);
   if (CondResult.isInvalid())
     return StmtError();
-  Cond = CondResult.take();
+  Cond = CondResult.get();
 
   CondResult = ActOnFinishFullExpr(Cond, DoLoc);
   if (CondResult.isInvalid())
     return StmtError();
-  Cond = CondResult.take();
+  Cond = CondResult.get();
 
   DiagnoseUnusedExprResult(Body);
 
-  return Owned(new (Context) DoStmt(Body, Cond, DoLoc, WhileLoc, CondRParen));
+  return new (Context) DoStmt(Body, Cond, DoLoc, WhileLoc, CondRParen);
 }
 
 namespace {
@@ -1362,9 +1410,8 @@
     // Condition is empty
     if (!Second) return;
 
-    if (S.Diags.getDiagnosticLevel(diag::warn_variables_not_in_loop_body,
-                                   Second->getLocStart())
-        == DiagnosticsEngine::Ignored)
+    if (S.Diags.isIgnored(diag::warn_variables_not_in_loop_body,
+                          Second->getLocStart()))
       return;
 
     PartialDiagnostic PDiag = S.PDiag(diag::warn_variables_not_in_loop_body);
@@ -1454,25 +1501,33 @@
     return false;
   }
 
-  // A visitor to determine if a continue statement is a subexpression.
-  class ContinueFinder : public EvaluatedExprVisitor<ContinueFinder> {
-    bool Found;
+  // A visitor to determine if a continue or break statement is a
+  // subexpression.
+  class BreakContinueFinder : public EvaluatedExprVisitor<BreakContinueFinder> {
+    SourceLocation BreakLoc;
+    SourceLocation ContinueLoc;
   public:
-    ContinueFinder(Sema &S, Stmt* Body) :
-        Inherited(S.Context),
-        Found(false) {
+    BreakContinueFinder(Sema &S, Stmt* Body) :
+        Inherited(S.Context) {
       Visit(Body);
     }
 
-    typedef EvaluatedExprVisitor<ContinueFinder> Inherited;
+    typedef EvaluatedExprVisitor<BreakContinueFinder> Inherited;
 
     void VisitContinueStmt(ContinueStmt* E) {
-      Found = true;
+      ContinueLoc = E->getContinueLoc();
     }
 
-    bool ContinueFound() { return Found; }
+    void VisitBreakStmt(BreakStmt* E) {
+      BreakLoc = E->getBreakLoc();
+    }
 
-  };  // end class ContinueFinder
+    bool ContinueFound() { return ContinueLoc.isValid(); }
+    bool BreakFound() { return BreakLoc.isValid(); }
+    SourceLocation GetContinueLoc() { return ContinueLoc; }
+    SourceLocation GetBreakLoc() { return BreakLoc; }
+
+  };  // end class BreakContinueFinder
 
   // Emit a warning when a loop increment/decrement appears twice per loop
   // iteration.  The conditions which trigger this warning are:
@@ -1483,9 +1538,8 @@
     // Return when there is nothing to check.
     if (!Body || !Third) return;
 
-    if (S.Diags.getDiagnosticLevel(diag::warn_redundant_loop_iteration,
-                                   Third->getLocStart())
-        == DiagnosticsEngine::Ignored)
+    if (S.Diags.isIgnored(diag::warn_redundant_loop_iteration,
+                          Third->getLocStart()))
       return;
 
     // Get the last statement from the loop body.
@@ -1501,11 +1555,11 @@
     if (!ProcessIterationStmt(S, LastStmt, LastIncrement, LastDRE)) return;
 
     // Check that the two statements are both increments or both decrements
-    // on the same varaible.
+    // on the same variable.
     if (LoopIncrement != LastIncrement ||
         LoopDRE->getDecl() != LastDRE->getDecl()) return;
 
-    if (ContinueFinder(S, Body).ContinueFound()) return;
+    if (BreakContinueFinder(S, Body).ContinueFound()) return;
 
     S.Diag(LastDRE->getLocation(), diag::warn_redundant_loop_iteration)
          << LastDRE->getDecl() << LastIncrement;
@@ -1515,6 +1569,25 @@
 
 } // end namespace
 
+
+void Sema::CheckBreakContinueBinding(Expr *E) {
+  if (!E || getLangOpts().CPlusPlus)
+    return;
+  BreakContinueFinder BCFinder(*this, E);
+  Scope *BreakParent = CurScope->getBreakParent();
+  if (BCFinder.BreakFound() && BreakParent) {
+    if (BreakParent->getFlags() & Scope::SwitchScope) {
+      Diag(BCFinder.GetBreakLoc(), diag::warn_break_binds_to_switch);
+    } else {
+      Diag(BCFinder.GetBreakLoc(), diag::warn_loop_ctrl_binds_to_inner)
+          << "break";
+    }
+  } else if (BCFinder.ContinueFound() && CurScope->getContinueParent()) {
+    Diag(BCFinder.GetContinueLoc(), diag::warn_loop_ctrl_binds_to_inner)
+        << "continue";
+  }
+}
+
 StmtResult
 Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
                    Stmt *First, FullExprArg second, Decl *secondVar,
@@ -1525,24 +1598,26 @@
       // C99 6.8.5p3: The declaration part of a 'for' statement shall only
       // declare identifiers for objects having storage class 'auto' or
       // 'register'.
-      for (DeclStmt::decl_iterator DI=DS->decl_begin(), DE=DS->decl_end();
-           DI!=DE; ++DI) {
-        VarDecl *VD = dyn_cast<VarDecl>(*DI);
+      for (auto *DI : DS->decls()) {
+        VarDecl *VD = dyn_cast<VarDecl>(DI);
         if (VD && VD->isLocalVarDecl() && !VD->hasLocalStorage())
-          VD = 0;
-        if (VD == 0) {
-          Diag((*DI)->getLocation(), diag::err_non_local_variable_decl_in_for);
-          (*DI)->setInvalidDecl();
+          VD = nullptr;
+        if (!VD) {
+          Diag(DI->getLocation(), diag::err_non_local_variable_decl_in_for);
+          DI->setInvalidDecl();
         }
       }
     }
   }
 
+  CheckBreakContinueBinding(second.get());
+  CheckBreakContinueBinding(third.get());
+
   CheckForLoopConditionalStatement(*this, second.get(), third.get(), Body);
   CheckForRedundantIteration(*this, third.get(), Body);
 
   ExprResult SecondResult(second.release());
-  VarDecl *ConditionVar = 0;
+  VarDecl *ConditionVar = nullptr;
   if (secondVar) {
     ConditionVar = cast<VarDecl>(secondVar);
     SecondResult = CheckConditionVariable(ConditionVar, ForLoc, true);
@@ -1550,7 +1625,7 @@
       return StmtError();
   }
 
-  Expr *Third  = third.release().takeAs<Expr>();
+  Expr *Third  = third.release().getAs<Expr>();
 
   DiagnoseUnusedExprResult(First);
   DiagnoseUnusedExprResult(Third);
@@ -1559,10 +1634,8 @@
   if (isa<NullStmt>(Body))
     getCurCompoundScope().setHasEmptyLoopBodies();
 
-  return Owned(new (Context) ForStmt(Context, First,
-                                     SecondResult.take(), ConditionVar,
-                                     Third, Body, ForLoc, LParenLoc,
-                                     RParenLoc));
+  return new (Context) ForStmt(Context, First, SecondResult.get(), ConditionVar,
+                               Third, Body, ForLoc, LParenLoc, RParenLoc);
 }
 
 /// In an Objective C collection iteration statement:
@@ -1574,12 +1647,12 @@
   // use of pseudo-object l-values in this position.
   ExprResult result = CheckPlaceholderExpr(E);
   if (result.isInvalid()) return StmtError();
-  E = result.take();
+  E = result.get();
 
   ExprResult FullExpr = ActOnFinishFullExpr(E);
   if (FullExpr.isInvalid())
     return StmtError();
-  return StmtResult(static_cast<Stmt*>(FullExpr.take()));
+  return StmtResult(static_cast<Stmt*>(FullExpr.get()));
 }
 
 ExprResult
@@ -1588,13 +1661,13 @@
     return ExprError();
 
   // Bail out early if we've got a type-dependent expression.
-  if (collection->isTypeDependent()) return Owned(collection);
+  if (collection->isTypeDependent()) return collection;
 
   // Perform normal l-value conversion.
   ExprResult result = DefaultFunctionArrayLvalueConversion(collection);
   if (result.isInvalid())
     return ExprError();
-  collection = result.take();
+  collection = result.get();
 
   // The operand needs to have object-pointer type.
   // TODO: should we do a contextual conversion?
@@ -1627,7 +1700,7 @@
     };
     Selector selector = Context.Selectors.getSelector(3, &selectorIdents[0]);
 
-    ObjCMethodDecl *method = 0;
+    ObjCMethodDecl *method = nullptr;
 
     // If there's an interface, look in both the public and private APIs.
     if (iface) {
@@ -1650,7 +1723,7 @@
   }
 
   // Wrap up any cleanups in the expression.
-  return Owned(collection);
+  return collection;
 }
 
 StmtResult
@@ -1725,13 +1798,12 @@
   if (CollectionExprResult.isInvalid())
     return StmtError();
 
-  CollectionExprResult = ActOnFinishFullExpr(CollectionExprResult.take());
+  CollectionExprResult = ActOnFinishFullExpr(CollectionExprResult.get());
   if (CollectionExprResult.isInvalid())
     return StmtError();
 
-  return Owned(new (Context) ObjCForCollectionStmt(First,
-                                                   CollectionExprResult.take(), 0,
-                                                   ForLoc, RParenLoc));
+  return new (Context) ObjCForCollectionStmt(First, CollectionExprResult.get(),
+                                             nullptr, ForLoc, RParenLoc);
 }
 
 /// Finish building a variable declaration for a for-range statement.
@@ -1809,7 +1881,7 @@
 
 static bool ObjCEnumerationCollection(Expr *Collection) {
   return !Collection->isTypeDependent()
-          && Collection->getType()->getAs<ObjCObjectPointerType>() != 0;
+          && Collection->getType()->getAs<ObjCObjectPointerType>() != nullptr;
 }
 
 /// ActOnCXXForRangeStmt - Check and build a C++11 for-range statement.
@@ -1868,7 +1940,7 @@
 
   // Claim the type doesn't contain auto: we've already done the checking.
   DeclGroupPtrTy RangeGroup =
-      BuildDeclaratorGroup(llvm::MutableArrayRef<Decl *>((Decl **)&RangeVar, 1),
+      BuildDeclaratorGroup(MutableArrayRef<Decl *>((Decl **)&RangeVar, 1),
                            /*TypeMayContainAuto=*/ false);
   StmtResult RangeDecl = ActOnDeclStmt(RangeGroup, RangeLoc, RangeLoc);
   if (RangeDecl.isInvalid()) {
@@ -1877,8 +1949,8 @@
   }
 
   return BuildCXXForRangeStmt(ForLoc, ColonLoc, RangeDecl.get(),
-                              /*BeginEndDecl=*/0, /*Cond=*/0, /*Inc=*/0, DS,
-                              RParenLoc, Kind);
+                              /*BeginEndDecl=*/nullptr, /*Cond=*/nullptr,
+                              /*Inc=*/nullptr, DS, RParenLoc, Kind);
 }
 
 /// \brief Create the initialization, compare, and increment steps for
@@ -2100,9 +2172,8 @@
       // Find the array bound.
       ExprResult BoundExpr;
       if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(UnqAT))
-        BoundExpr = Owned(IntegerLiteral::Create(Context, CAT->getSize(),
-                                                 Context.getPointerDiffType(),
-                                                 RangeLoc));
+        BoundExpr = IntegerLiteral::Create(
+            Context, CAT->getSize(), Context.getPointerDiffType(), RangeLoc);
       else if (const VariableArrayType *VAT =
                dyn_cast<VariableArrayType>(UnqAT))
         BoundExpr = VAT->getSizeExpr();
@@ -2123,7 +2194,8 @@
         return StmtError();
       }
     } else {
-      OverloadCandidateSet CandidateSet(RangeLoc);
+      OverloadCandidateSet CandidateSet(RangeLoc,
+                                        OverloadCandidateSet::CSK_Normal);
       Sema::BeginEndFunction BEFFailure;
       ForRangeStatus RangeStatus =
           BuildNonArrayForRange(*this, S, BeginRangeRef.get(),
@@ -2185,7 +2257,7 @@
     Decl *BeginEndDecls[] = { BeginVar, EndVar };
     // Claim the type doesn't contain auto: we've already done the checking.
     DeclGroupPtrTy BeginEndGroup =
-        BuildDeclaratorGroup(llvm::MutableArrayRef<Decl *>(BeginEndDecls, 2),
+        BuildDeclaratorGroup(MutableArrayRef<Decl *>(BeginEndDecls, 2),
                              /*TypeMayContainAuto=*/ false);
     BeginEndDecl = ActOnDeclStmt(BeginEndGroup, ColonLoc, ColonLoc);
 
@@ -2258,11 +2330,9 @@
   if (Kind == BFRK_Check)
     return StmtResult();
 
-  return Owned(new (Context) CXXForRangeStmt(RangeDS,
-                                     cast_or_null<DeclStmt>(BeginEndDecl.get()),
-                                             NotEqExpr.take(), IncrExpr.take(),
-                                             LoopVarDS, /*Body=*/0, ForLoc,
-                                             ColonLoc, RParenLoc));
+  return new (Context) CXXForRangeStmt(
+      RangeDS, cast_or_null<DeclStmt>(BeginEndDecl.get()), NotEqExpr.get(),
+      IncrExpr.get(), LoopVarDS, /*Body=*/nullptr, ForLoc, ColonLoc, RParenLoc);
 }
 
 /// FinishObjCForCollectionStmt - Attach the body to a objective-C foreach
@@ -2301,7 +2371,7 @@
                                LabelDecl *TheDecl) {
   getCurFunction()->setHasBranchIntoScope();
   TheDecl->markUsed(Context);
-  return Owned(new (Context) GotoStmt(TheDecl, GotoLoc, LabelLoc));
+  return new (Context) GotoStmt(TheDecl, GotoLoc, LabelLoc);
 }
 
 StmtResult
@@ -2311,12 +2381,12 @@
   if (!E->isTypeDependent()) {
     QualType ETy = E->getType();
     QualType DestTy = Context.getPointerType(Context.VoidTy.withConst());
-    ExprResult ExprRes = Owned(E);
+    ExprResult ExprRes = E;
     AssignConvertType ConvTy =
       CheckSingleAssignmentConstraints(DestTy, ExprRes);
     if (ExprRes.isInvalid())
       return StmtError();
-    E = ExprRes.take();
+    E = ExprRes.get();
     if (DiagnoseAssignmentResult(ConvTy, StarLoc, DestTy, ETy, E, AA_Passing))
       return StmtError();
   }
@@ -2324,11 +2394,11 @@
   ExprResult ExprRes = ActOnFinishFullExpr(E);
   if (ExprRes.isInvalid())
     return StmtError();
-  E = ExprRes.take();
+  E = ExprRes.get();
 
   getCurFunction()->setHasIndirectGoto();
 
-  return Owned(new (Context) IndirectGotoStmt(GotoLoc, StarLoc, E));
+  return new (Context) IndirectGotoStmt(GotoLoc, StarLoc, E);
 }
 
 StmtResult
@@ -2339,7 +2409,7 @@
     return StmtError(Diag(ContinueLoc, diag::err_continue_not_in_loop));
   }
 
-  return Owned(new (Context) ContinueStmt(ContinueLoc));
+  return new (Context) ContinueStmt(ContinueLoc);
 }
 
 StmtResult
@@ -2349,8 +2419,11 @@
     // C99 6.8.6.3p1: A break shall appear only in or as a switch/loop body.
     return StmtError(Diag(BreakLoc, diag::err_break_not_in_loop_or_switch));
   }
+  if (S->isOpenMPLoopScope())
+    return StmtError(Diag(BreakLoc, diag::err_omp_loop_cannot_use_stmt)
+                     << "break");
 
-  return Owned(new (Context) BreakStmt(BreakLoc));
+  return new (Context) BreakStmt(BreakLoc);
 }
 
 /// \brief Determine whether the given expression is a candidate for
@@ -2371,52 +2444,62 @@
 ///
 /// \returns The NRVO candidate variable, if the return statement may use the
 /// NRVO, or NULL if there is no such candidate.
-const VarDecl *Sema::getCopyElisionCandidate(QualType ReturnType,
-                                             Expr *E,
-                                             bool AllowFunctionParameter) {
-  QualType ExprType = E->getType();
+VarDecl *Sema::getCopyElisionCandidate(QualType ReturnType,
+                                       Expr *E,
+                                       bool AllowFunctionParameter) {
+  if (!getLangOpts().CPlusPlus)
+    return nullptr;
+
+  // - in a return statement in a function [where] ...
+  // ... the expression is the name of a non-volatile automatic object ...
+  DeclRefExpr *DR = dyn_cast<DeclRefExpr>(E->IgnoreParens());
+  if (!DR || DR->refersToEnclosingLocal())
+    return nullptr;
+  VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl());
+  if (!VD)
+    return nullptr;
+
+  if (isCopyElisionCandidate(ReturnType, VD, AllowFunctionParameter))
+    return VD;
+  return nullptr;
+}
+
+bool Sema::isCopyElisionCandidate(QualType ReturnType, const VarDecl *VD,
+                                  bool AllowFunctionParameter) {
+  QualType VDType = VD->getType();
   // - in a return statement in a function with ...
   // ... a class return type ...
-  if (!ReturnType.isNull()) {
+  if (!ReturnType.isNull() && !ReturnType->isDependentType()) {
     if (!ReturnType->isRecordType())
-      return 0;
+      return false;
     // ... the same cv-unqualified type as the function return type ...
-    if (!Context.hasSameUnqualifiedType(ReturnType, ExprType))
-      return 0;
+    if (!VDType->isDependentType() &&
+        !Context.hasSameUnqualifiedType(ReturnType, VDType))
+      return false;
   }
 
-  // ... the expression is the name of a non-volatile automatic object
-  // (other than a function or catch-clause parameter)) ...
-  const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(E->IgnoreParens());
-  if (!DR || DR->refersToEnclosingLocal())
-    return 0;
-  const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl());
-  if (!VD)
-    return 0;
-
   // ...object (other than a function or catch-clause parameter)...
   if (VD->getKind() != Decl::Var &&
       !(AllowFunctionParameter && VD->getKind() == Decl::ParmVar))
-    return 0;
-  if (VD->isExceptionVariable()) return 0;
+    return false;
+  if (VD->isExceptionVariable()) return false;
 
   // ...automatic...
-  if (!VD->hasLocalStorage()) return 0;
+  if (!VD->hasLocalStorage()) return false;
 
   // ...non-volatile...
-  if (VD->getType().isVolatileQualified()) return 0;
-  if (VD->getType()->isReferenceType()) return 0;
+  if (VD->getType().isVolatileQualified()) return false;
 
   // __block variables can't be allocated in a way that permits NRVO.
-  if (VD->hasAttr<BlocksAttr>()) return 0;
+  if (VD->hasAttr<BlocksAttr>()) return false;
 
   // Variables with higher required alignment than their type's ABI
   // alignment cannot use NRVO.
-  if (VD->hasAttr<AlignedAttr>() &&
+  if (!VD->getType()->isDependentType() && VD->hasAttr<AlignedAttr>() &&
       Context.getDeclAlign(VD) > Context.getTypeAlignInChars(VD->getType()))
-    return 0;
+    return false;
 
-  return VD;
+  return true;
 }
 
 /// \brief Perform the initialization of a potentially-movable value, which
@@ -2476,7 +2559,7 @@
         // Promote "AsRvalue" to the heap, since we now need this
         // expression node to persist.
         Value = ImplicitCastExpr::Create(Context, Value->getType(),
-                                         CK_NoOp, Value, 0, VK_XValue);
+                                         CK_NoOp, Value, nullptr, VK_XValue);
 
         // Complete type-checking the initialization of the return type
         // using the constructor we found.
@@ -2499,7 +2582,7 @@
 static bool hasDeducedReturnType(FunctionDecl *FD) {
   const FunctionProtoType *FPT =
       FD->getTypeSourceInfo()->getType()->castAs<FunctionProtoType>();
-  return FPT->getResultType()->isUndeducedType();
+  return FPT->getReturnType()->isUndeducedType();
 }
 
 /// ActOnCapScopeReturnStmt - Utility routine to type-check return statements
@@ -2518,7 +2601,7 @@
     // FIXME: Blocks might have a return type of 'auto' explicitly specified.
     FunctionDecl *FD = CurLambda->CallOperator;
     if (CurCap->ReturnType.isNull())
-      CurCap->ReturnType = FD->getResultType();
+      CurCap->ReturnType = FD->getReturnType();
 
     AutoType *AT = CurCap->ReturnType->getContainedAutoType();
     assert(AT && "lost auto type from lambda return type");
@@ -2526,7 +2609,7 @@
       FD->setInvalidDecl();
       return StmtError();
     }
-    CurCap->ReturnType = FnRetType = FD->getResultType();
+    CurCap->ReturnType = FnRetType = FD->getReturnType();
   } else if (CurCap->HasImplicitReturnType) {
     // For blocks/lambdas with implicit return types, we check each return
     // statement individually, and deduce the common return type when the block
@@ -2536,7 +2619,7 @@
       ExprResult Result = DefaultFunctionArrayLvalueConversion(RetValExp);
       if (Result.isInvalid())
         return StmtError();
-      RetValExp = Result.take();
+      RetValExp = Result.get();
 
       if (!CurContext->isDependentContext())
         FnRetType = RetValExp->getType();
@@ -2582,7 +2665,7 @@
   // Otherwise, verify that this result type matches the previous one.  We are
   // pickier with blocks than for normal functions because we don't have GCC
   // compatibility to worry about here.
-  const VarDecl *NRVOCandidate = 0;
+  const VarDecl *NRVOCandidate = nullptr;
   if (FnRetType->isDependentType()) {
     // Delay processing for now.  TODO: there are lots of dependent
     // types we can conclusively prove aren't void.
@@ -2596,7 +2679,7 @@
         Diag(ReturnLoc, diag::ext_return_has_void_expr) << "literal" << 2;
       else {
         Diag(ReturnLoc, diag::err_return_block_has_expr);
-        RetValExp = 0;
+        RetValExp = nullptr;
       }
     }
   } else if (!RetValExp) {
@@ -2613,22 +2696,24 @@
     NRVOCandidate = getCopyElisionCandidate(FnRetType, RetValExp, false);
     InitializedEntity Entity = InitializedEntity::InitializeResult(ReturnLoc,
                                                                    FnRetType,
-                                                          NRVOCandidate != 0);
+                                                      NRVOCandidate != nullptr);
     ExprResult Res = PerformMoveOrCopyInitialization(Entity, NRVOCandidate,
                                                      FnRetType, RetValExp);
     if (Res.isInvalid()) {
       // FIXME: Cleanup temporaries here, anyway?
       return StmtError();
     }
-    RetValExp = Res.take();
-    CheckReturnStackAddr(RetValExp, FnRetType, ReturnLoc);
+    RetValExp = Res.get();
+    CheckReturnValExpr(RetValExp, FnRetType, ReturnLoc);
+  } else {
+    NRVOCandidate = getCopyElisionCandidate(FnRetType, RetValExp, false);
   }
 
   if (RetValExp) {
     ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc);
     if (ER.isInvalid())
       return StmtError();
-    RetValExp = ER.take();
+    RetValExp = ER.get();
   }
   ReturnStmt *Result = new (Context) ReturnStmt(ReturnLoc, RetValExp,
                                                 NRVOCandidate);
@@ -2636,12 +2721,10 @@
   // If we need to check for the named return value optimization,
   // or if we need to infer the return type,
   // save the return statement in our scope for later processing.
-  if (CurCap->HasImplicitReturnType ||
-      (getLangOpts().CPlusPlus && FnRetType->isRecordType() &&
-       !CurContext->isDependentContext()))
+  if (CurCap->HasImplicitReturnType || NRVOCandidate)
     FunctionScopes.back()->Returns.push_back(Result);
 
-  return Owned(Result);
+  return Result;
 }
 
 /// Deduce the return type for a function from a returned expression, per
@@ -2651,7 +2734,7 @@
                                             Expr *&RetExpr,
                                             AutoType *AT) {
   TypeLoc OrigResultType = FD->getTypeSourceInfo()->getTypeLoc().
-    IgnoreParens().castAs<FunctionProtoTypeLoc>().getResultLoc();
+    IgnoreParens().castAs<FunctionProtoTypeLoc>().getReturnLoc();
   QualType Deduced;
 
   if (RetExpr && isa<InitListExpr>(RetExpr)) {
@@ -2735,7 +2818,24 @@
 }
 
 StmtResult
-Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
+Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp,
+                      Scope *CurScope) {
+  StmtResult R = BuildReturnStmt(ReturnLoc, RetValExp);
+  if (R.isInvalid()) {
+    return R;
+  }
+
+  if (VarDecl *VD =
+      const_cast<VarDecl*>(cast<ReturnStmt>(R.get())->getNRVOCandidate())) {
+    CurScope->addNRVOCandidate(VD);
+  } else {
+    CurScope->setNoNRVO();
+  }
+
+  return R;
+}
+
+StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
   // Check for unexpanded parameter packs.
   if (RetValExp && DiagnoseUnexpandedParameterPack(RetValExp))
     return StmtError();
@@ -2745,13 +2845,21 @@
 
   QualType FnRetType;
   QualType RelatedRetType;
+  const AttrVec *Attrs = nullptr;
+  bool isObjCMethod = false;
+
   if (const FunctionDecl *FD = getCurFunctionDecl()) {
-    FnRetType = FD->getResultType();
+    FnRetType = FD->getReturnType();
+    if (FD->hasAttrs())
+      Attrs = &FD->getAttrs();
     if (FD->isNoReturn())
       Diag(ReturnLoc, diag::warn_noreturn_function_has_return_expr)
         << FD->getDeclName();
   } else if (ObjCMethodDecl *MD = getCurMethodDecl()) {
-    FnRetType = MD->getResultType();
+    FnRetType = MD->getReturnType();
+    isObjCMethod = true;
+    if (MD->hasAttrs())
+      Attrs = &MD->getAttrs();
     if (MD->hasRelatedResultType() && MD->getClassInterface()) {
       // In the implementation of a method with a related return type, the
       // type used to type-check the validity of return statements within the
@@ -2771,14 +2879,14 @@
         FD->setInvalidDecl();
         return StmtError();
       } else {
-        FnRetType = FD->getResultType();
+        FnRetType = FD->getReturnType();
       }
     }
   }
 
   bool HasDependentReturnType = FnRetType->isDependentType();
 
-  ReturnStmt *Result = 0;
+  ReturnStmt *Result = nullptr;
   if (FnRetType->isVoidType()) {
     if (RetValExp) {
       if (isa<InitListExpr>(RetValExp)) {
@@ -2799,24 +2907,36 @@
           << RetValExp->getSourceRange();
 
         // Drop the expression.
-        RetValExp = 0;
+        RetValExp = nullptr;
       } else if (!RetValExp->isTypeDependent()) {
         // C99 6.8.6.4p1 (ext_ since GCC warns)
         unsigned D = diag::ext_return_has_expr;
-        if (RetValExp->getType()->isVoidType())
-          D = diag::ext_return_has_void_expr;
+        if (RetValExp->getType()->isVoidType()) {
+          NamedDecl *CurDecl = getCurFunctionOrMethodDecl();
+          if (isa<CXXConstructorDecl>(CurDecl) ||
+              isa<CXXDestructorDecl>(CurDecl))
+            D = diag::err_ctor_dtor_returns_void;
+          else
+            D = diag::ext_return_has_void_expr;
+        }
         else {
-          ExprResult Result = Owned(RetValExp);
-          Result = IgnoredValueConversions(Result.take());
+          ExprResult Result = RetValExp;
+          Result = IgnoredValueConversions(Result.get());
           if (Result.isInvalid())
             return StmtError();
-          RetValExp = Result.take();
+          RetValExp = Result.get();
           RetValExp = ImpCastExprToType(RetValExp,
-                                        Context.VoidTy, CK_ToVoid).take();
+                                        Context.VoidTy, CK_ToVoid).get();
         }
-
+        // return of void in constructor/destructor is illegal in C++.
+        if (D == diag::err_ctor_dtor_returns_void) {
+          NamedDecl *CurDecl = getCurFunctionOrMethodDecl();
+          Diag(ReturnLoc, D)
+            << CurDecl->getDeclName() << isa<CXXDestructorDecl>(CurDecl)
+            << RetValExp->getSourceRange();
+        }
         // return (some void expression); is legal in C++.
-        if (D != diag::ext_return_has_void_expr ||
+        else if (D != diag::ext_return_has_void_expr ||
             !getLangOpts().CPlusPlus) {
           NamedDecl *CurDecl = getCurFunctionOrMethodDecl();
 
@@ -2838,11 +2958,11 @@
         ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc);
         if (ER.isInvalid())
           return StmtError();
-        RetValExp = ER.take();
+        RetValExp = ER.get();
       }
     }
 
-    Result = new (Context) ReturnStmt(ReturnLoc, RetValExp, 0);
+    Result = new (Context) ReturnStmt(ReturnLoc, RetValExp, nullptr);
   } else if (!RetValExp && !HasDependentReturnType) {
     unsigned DiagID = diag::warn_return_missing_expr;  // C90 6.6.6.4p4
     // C99 6.8.6.4p1 (ext_ since GCC warns)
@@ -2855,29 +2975,30 @@
     Result = new (Context) ReturnStmt(ReturnLoc);
   } else {
     assert(RetValExp || HasDependentReturnType);
-    const VarDecl *NRVOCandidate = 0;
+    const VarDecl *NRVOCandidate = nullptr;
+
+    QualType RetType = RelatedRetType.isNull() ? FnRetType : RelatedRetType;
+
+    // C99 6.8.6.4p3(136): The return statement is not an assignment. The
+    // overlap restriction of subclause 6.5.16.1 does not apply to the case of
+    // function return.
+
+    // In C++ the return statement is handled via a copy initialization,
+    // the C version of which boils down to CheckSingleAssignmentConstraints.
+    if (RetValExp)
+      NRVOCandidate = getCopyElisionCandidate(FnRetType, RetValExp, false);
     if (!HasDependentReturnType && !RetValExp->isTypeDependent()) {
       // we have a non-void function with an expression, continue checking
-
-      QualType RetType = (RelatedRetType.isNull() ? FnRetType : RelatedRetType);
-
-      // C99 6.8.6.4p3(136): The return statement is not an assignment. The
-      // overlap restriction of subclause 6.5.16.1 does not apply to the case of
-      // function return.
-
-      // In C++ the return statement is handled via a copy initialization,
-      // the C version of which boils down to CheckSingleAssignmentConstraints.
-      NRVOCandidate = getCopyElisionCandidate(FnRetType, RetValExp, false);
       InitializedEntity Entity = InitializedEntity::InitializeResult(ReturnLoc,
                                                                      RetType,
-                                                            NRVOCandidate != 0);
+                                                      NRVOCandidate != nullptr);
       ExprResult Res = PerformMoveOrCopyInitialization(Entity, NRVOCandidate,
                                                        RetType, RetValExp);
       if (Res.isInvalid()) {
         // FIXME: Clean up temporaries here anyway?
         return StmtError();
       }
-      RetValExp = Res.takeAs<Expr>();
+      RetValExp = Res.getAs<Expr>();
 
       // If we have a related result type, we need to implicitly
       // convert back to the formal result type.  We can't pretend to
@@ -2891,28 +3012,28 @@
           // FIXME: Clean up temporaries here anyway?
           return StmtError();
         }
-        RetValExp = Res.takeAs<Expr>();
+        RetValExp = Res.getAs<Expr>();
       }
 
-      CheckReturnStackAddr(RetValExp, FnRetType, ReturnLoc);
+      CheckReturnValExpr(RetValExp, FnRetType, ReturnLoc, isObjCMethod, Attrs,
+                         getCurFunctionDecl());
     }
 
     if (RetValExp) {
       ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc);
       if (ER.isInvalid())
         return StmtError();
-      RetValExp = ER.take();
+      RetValExp = ER.get();
     }
     Result = new (Context) ReturnStmt(ReturnLoc, RetValExp, NRVOCandidate);
   }
 
   // If we need to check for the named return value optimization, save the
   // return statement in our scope for later processing.
-  if (getLangOpts().CPlusPlus && FnRetType->isRecordType() &&
-      !CurContext->isDependentContext())
+  if (Result->getNRVOCandidate())
     FunctionScopes.back()->Returns.push_back(Result);
 
-  return Owned(Result);
+  return Result;
 }
 
 StmtResult
@@ -2923,12 +3044,12 @@
   if (Var && Var->isInvalidDecl())
     return StmtError();
 
-  return Owned(new (Context) ObjCAtCatchStmt(AtLoc, RParen, Var, Body));
+  return new (Context) ObjCAtCatchStmt(AtLoc, RParen, Var, Body);
 }
 
 StmtResult
 Sema::ActOnObjCAtFinallyStmt(SourceLocation AtLoc, Stmt *Body) {
-  return Owned(new (Context) ObjCAtFinallyStmt(AtLoc, Body));
+  return new (Context) ObjCAtFinallyStmt(AtLoc, Body);
 }
 
 StmtResult
@@ -2939,10 +3060,8 @@
 
   getCurFunction()->setHasBranchProtectedScope();
   unsigned NumCatchStmts = CatchStmts.size();
-  return Owned(ObjCAtTryStmt::Create(Context, AtLoc, Try,
-                                     CatchStmts.data(),
-                                     NumCatchStmts,
-                                     Finally));
+  return ObjCAtTryStmt::Create(Context, AtLoc, Try, CatchStmts.data(),
+                               NumCatchStmts, Finally);
 }
 
 StmtResult Sema::BuildObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw) {
@@ -2951,10 +3070,10 @@
     if (Result.isInvalid())
       return StmtError();
 
-    Result = ActOnFinishFullExpr(Result.take());
+    Result = ActOnFinishFullExpr(Result.get());
     if (Result.isInvalid())
       return StmtError();
-    Throw = Result.take();
+    Throw = Result.get();
 
     QualType ThrowType = Throw->getType();
     // Make sure the expression type is an ObjC pointer or "void *".
@@ -2967,7 +3086,7 @@
     }
   }
 
-  return Owned(new (Context) ObjCAtThrowStmt(AtLoc, Throw));
+  return new (Context) ObjCAtThrowStmt(AtLoc, Throw);
 }
 
 StmtResult
@@ -2993,7 +3112,7 @@
   ExprResult result = DefaultLvalueConversion(operand);
   if (result.isInvalid())
     return ExprError();
-  operand = result.take();
+  operand = result.get();
 
   // Make sure the expression type is an ObjC pointer or "void *".
   QualType type = operand->getType();
@@ -3014,7 +3133,7 @@
                                   Stmt *SyncBody) {
   // We can't jump into or indirect-jump out of a @synchronized block.
   getCurFunction()->setHasBranchProtectedScope();
-  return Owned(new (Context) ObjCAtSynchronizedStmt(AtLoc, SyncExpr, SyncBody));
+  return new (Context) ObjCAtSynchronizedStmt(AtLoc, SyncExpr, SyncBody);
 }
 
 /// ActOnCXXCatchBlock - Takes an exception declaration and a handler block
@@ -3023,15 +3142,14 @@
 Sema::ActOnCXXCatchBlock(SourceLocation CatchLoc, Decl *ExDecl,
                          Stmt *HandlerBlock) {
   // There's nothing to test that ActOnExceptionDecl didn't already test.
-  return Owned(new (Context) CXXCatchStmt(CatchLoc,
-                                          cast_or_null<VarDecl>(ExDecl),
-                                          HandlerBlock));
+  return new (Context)
+      CXXCatchStmt(CatchLoc, cast_or_null<VarDecl>(ExDecl), HandlerBlock);
 }
 
 StmtResult
 Sema::ActOnObjCAutoreleasePoolStmt(SourceLocation AtLoc, Stmt *Body) {
   getCurFunction()->setHasBranchProtectedScope();
-  return Owned(new (Context) ObjCAutoreleasePoolStmt(AtLoc, Body));
+  return new (Context) ObjCAutoreleasePoolStmt(AtLoc, Body);
 }
 
 namespace {
@@ -3075,6 +3193,9 @@
       !getSourceManager().isInSystemHeader(TryLoc))
       Diag(TryLoc, diag::err_exceptions_disabled) << "try";
 
+  if (getCurScope() && getCurScope()->isOpenMPSimdDirectiveScope())
+    Diag(TryLoc, diag::err_omp_simd_region_cannot_use_stmt) << "try";
+
   const unsigned NumHandlers = Handlers.size();
   assert(NumHandlers > 0 &&
          "The parser shouldn't call this if there are no handlers.");
@@ -3125,19 +3246,18 @@
   // Neither of these are explicitly forbidden, but every compiler detects them
   // and warns.
 
-  return Owned(CXXTryStmt::Create(Context, TryLoc, TryBlock, Handlers));
+  return CXXTryStmt::Create(Context, TryLoc, TryBlock, Handlers);
 }
 
-StmtResult
-Sema::ActOnSEHTryBlock(bool IsCXXTry,
-                       SourceLocation TryLoc,
-                       Stmt *TryBlock,
-                       Stmt *Handler) {
+StmtResult Sema::ActOnSEHTryBlock(bool IsCXXTry, SourceLocation TryLoc,
+                                  Stmt *TryBlock, Stmt *Handler,
+                                  int HandlerIndex, int HandlerParentIndex) {
   assert(TryBlock && Handler);
 
   getCurFunction()->setHasBranchProtectedScope();
 
-  return Owned(SEHTryStmt::Create(Context,IsCXXTry,TryLoc,TryBlock,Handler));
+  return SEHTryStmt::Create(Context, IsCXXTry, TryLoc, TryBlock, Handler,
+                            HandlerIndex, HandlerParentIndex);
 }
 
 StmtResult
@@ -3152,14 +3272,25 @@
                      << FilterExpr->getType());
   }
 
-  return Owned(SEHExceptStmt::Create(Context,Loc,FilterExpr,Block));
+  return SEHExceptStmt::Create(Context,Loc,FilterExpr,Block);
 }
 
 StmtResult
 Sema::ActOnSEHFinallyBlock(SourceLocation Loc,
                            Stmt *Block) {
   assert(Block);
-  return Owned(SEHFinallyStmt::Create(Context,Loc,Block));
+  return SEHFinallyStmt::Create(Context,Loc,Block);
+}
+
+StmtResult
+Sema::ActOnSEHLeaveStmt(SourceLocation Loc, Scope *CurScope) {
+  Scope *SEHTryParent = CurScope;
+  while (SEHTryParent && !SEHTryParent->isSEHTryScope())
+    SEHTryParent = SEHTryParent->getParent();
+  if (!SEHTryParent)
+    return StmtError(Diag(Loc, diag::err_ms___leave_not_in___try));
+
+  return new (Context) SEHLeaveStmt(Loc);
 }
 
 StmtResult Sema::BuildMSDependentExistsStmt(SourceLocation KeywordLoc,
@@ -3192,30 +3323,20 @@
   while (!(DC->isFunctionOrMethod() || DC->isRecord() || DC->isFileContext()))
     DC = DC->getParent();
 
-  RecordDecl *RD = 0;
+  RecordDecl *RD = nullptr;
   if (getLangOpts().CPlusPlus)
-    RD = CXXRecordDecl::Create(Context, TTK_Struct, DC, Loc, Loc, /*Id=*/0);
+    RD = CXXRecordDecl::Create(Context, TTK_Struct, DC, Loc, Loc,
+                               /*Id=*/nullptr);
   else
-    RD = RecordDecl::Create(Context, TTK_Struct, DC, Loc, Loc, /*Id=*/0);
+    RD = RecordDecl::Create(Context, TTK_Struct, DC, Loc, Loc, /*Id=*/nullptr);
 
   DC->addDecl(RD);
   RD->setImplicit();
   RD->startDefinition();
 
+  assert(NumParams > 0 && "CapturedStmt requires context parameter");
   CD = CapturedDecl::Create(Context, CurContext, NumParams);
   DC->addDecl(CD);
-
-  // Build the context parameter
-  assert(NumParams > 0 && "CapturedStmt requires context parameter");
-  DC = CapturedDecl::castToDeclContext(CD);
-  IdentifierInfo *VarName = &Context.Idents.get("__context");
-  QualType ParamType = Context.getPointerType(Context.getTagDeclType(RD));
-  ImplicitParamDecl *Param
-    = ImplicitParamDecl::Create(Context, DC, Loc, VarName, ParamType);
-  DC->addDecl(Param);
-
-  CD->setContextParam(Param);
-
   return RD;
 }
 
@@ -3247,9 +3368,71 @@
 void Sema::ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope,
                                     CapturedRegionKind Kind,
                                     unsigned NumParams) {
-  CapturedDecl *CD = 0;
+  CapturedDecl *CD = nullptr;
   RecordDecl *RD = CreateCapturedStmtRecordDecl(CD, Loc, NumParams);
 
+  // Build the context parameter
+  DeclContext *DC = CapturedDecl::castToDeclContext(CD);
+  IdentifierInfo *ParamName = &Context.Idents.get("__context");
+  QualType ParamType = Context.getPointerType(Context.getTagDeclType(RD));
+  ImplicitParamDecl *Param
+    = ImplicitParamDecl::Create(Context, DC, Loc, ParamName, ParamType);
+  DC->addDecl(Param);
+
+  CD->setContextParam(0, Param);
+
+  // Enter the capturing scope for this captured region.
+  PushCapturedRegionScope(CurScope, CD, RD, Kind);
+
+  if (CurScope)
+    PushDeclContext(CurScope, CD);
+  else
+    CurContext = CD;
+
+  PushExpressionEvaluationContext(PotentiallyEvaluated);
+}
+
+void Sema::ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope,
+                                    CapturedRegionKind Kind,
+                                    ArrayRef<CapturedParamNameType> Params) {
+  CapturedDecl *CD = nullptr;
+  RecordDecl *RD = CreateCapturedStmtRecordDecl(CD, Loc, Params.size());
+
+  // Build the context parameter
+  DeclContext *DC = CapturedDecl::castToDeclContext(CD);
+  bool ContextIsFound = false;
+  unsigned ParamNum = 0;
+  for (ArrayRef<CapturedParamNameType>::iterator I = Params.begin(),
+                                                 E = Params.end();
+       I != E; ++I, ++ParamNum) {
+    if (I->second.isNull()) {
+      assert(!ContextIsFound &&
+             "null type has been found already for '__context' parameter");
+      IdentifierInfo *ParamName = &Context.Idents.get("__context");
+      QualType ParamType = Context.getPointerType(Context.getTagDeclType(RD));
+      ImplicitParamDecl *Param
+        = ImplicitParamDecl::Create(Context, DC, Loc, ParamName, ParamType);
+      DC->addDecl(Param);
+      CD->setContextParam(ParamNum, Param);
+      ContextIsFound = true;
+    } else {
+      IdentifierInfo *ParamName = &Context.Idents.get(I->first);
+      ImplicitParamDecl *Param
+        = ImplicitParamDecl::Create(Context, DC, Loc, ParamName, I->second);
+      DC->addDecl(Param);
+      CD->setParam(ParamNum, Param);
+    }
+  }
+  assert(ContextIsFound && "no null type for '__context' parameter");
+  if (!ContextIsFound) {
+    // Add __context implicitly if it is not specified.
+    IdentifierInfo *ParamName = &Context.Idents.get("__context");
+    QualType ParamType = Context.getPointerType(Context.getTagDeclType(RD));
+    ImplicitParamDecl *Param =
+        ImplicitParamDecl::Create(Context, DC, Loc, ParamName, ParamType);
+    DC->addDecl(Param);
+    CD->setContextParam(ParamNum, Param);
+  }
   // Enter the capturing scope for this captured region.
   PushCapturedRegionScope(CurScope, CD, RD, Kind);
 
@@ -3269,12 +3452,9 @@
   RecordDecl *Record = RSI->TheRecordDecl;
   Record->setInvalidDecl();
 
-  SmallVector<Decl*, 4> Fields;
-  for (RecordDecl::field_iterator I = Record->field_begin(),
-                                  E = Record->field_end(); I != E; ++I)
-    Fields.push_back(*I);
-  ActOnFields(/*Scope=*/0, Record->getLocation(), Record, Fields,
-              SourceLocation(), SourceLocation(), /*AttributeList=*/0);
+  SmallVector<Decl*, 4> Fields(Record->fields());
+  ActOnFields(/*Scope=*/nullptr, Record->getLocation(), Record, Fields,
+              SourceLocation(), SourceLocation(), /*AttributeList=*/nullptr);
 
   PopDeclContext();
   PopFunctionScopeInfo();
@@ -3303,5 +3483,5 @@
   PopDeclContext();
   PopFunctionScopeInfo();
 
-  return Owned(Res);
+  return Res;
 }
diff --git a/lib/Sema/SemaStmtAsm.cpp b/lib/Sema/SemaStmtAsm.cpp
index 9169032..5d076ca 100644
--- a/lib/Sema/SemaStmtAsm.cpp
+++ b/lib/Sema/SemaStmtAsm.cpp
@@ -15,13 +15,13 @@
 #include "clang/AST/RecordLayout.h"
 #include "clang/AST/TypeLoc.h"
 #include "clang/Basic/TargetInfo.h"
-#include "clang/Lex/Preprocessor.h"
 #include "clang/Sema/Initialization.h"
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/Scope.h"
 #include "clang/Sema/ScopeInfo.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/BitVector.h"
+#include "llvm/MC/MCParser/MCAsmParser.h"
 using namespace clang;
 using namespace sema;
 
@@ -152,6 +152,12 @@
                               diag::err_asm_invalid_lvalue_in_input)
                          << Info.getConstraintStr()
                          << InputExpr->getSourceRange());
+    } else {
+      ExprResult Result = DefaultFunctionArrayLvalueConversion(Exprs[i]);
+      if (Result.isInvalid())
+        return StmtError();
+
+      Exprs[i] = Result.get();
     }
 
     if (Info.allowsRegister()) {
@@ -163,11 +169,6 @@
       }
     }
 
-    ExprResult Result = DefaultFunctionArrayLvalueConversion(Exprs[i]);
-    if (Result.isInvalid())
-      return StmtError();
-
-    Exprs[i] = Result.take();
     InputConstraintInfos.push_back(Info);
 
     const Type *Ty = Exprs[i]->getType().getTypePtr();
@@ -352,7 +353,7 @@
         InputExpr->isEvaluatable(Context)) {
       CastKind castKind =
         (OutTy->isBooleanType() ? CK_IntegralToBoolean : CK_IntegralCast);
-      InputExpr = ImpCastExprToType(InputExpr, OutTy, castKind).take();
+      InputExpr = ImpCastExprToType(InputExpr, OutTy, castKind).get();
       Exprs[InputOpNo] = InputExpr;
       NS->setInputExpr(i, InputExpr);
       continue;
@@ -365,13 +366,13 @@
     return StmtError();
   }
 
-  return Owned(NS);
+  return NS;
 }
 
 ExprResult Sema::LookupInlineAsmIdentifier(CXXScopeSpec &SS,
                                            SourceLocation TemplateKWLoc,
                                            UnqualifiedId &Id,
-                                           InlineAsmIdentifierInfo &Info,
+                                           llvm::InlineAsmIdentifierInfo &Info,
                                            bool IsUnevaluatedContext) {
   Info.clear();
 
@@ -382,7 +383,7 @@
   ExprResult Result = ActOnIdExpression(getCurScope(), SS, TemplateKWLoc, Id,
                                         /*trailing lparen*/ false,
                                         /*is & operand*/ false,
-                                        /*CorrectionCandidateCallback=*/0,
+                                        /*CorrectionCandidateCallback=*/nullptr,
                                         /*IsInlineAsmIdentifier=*/ true);
 
   if (IsUnevaluatedContext)
@@ -390,7 +391,7 @@
 
   if (!Result.isUsable()) return Result;
 
-  Result = CheckPlaceholderExpr(Result.take());
+  Result = CheckPlaceholderExpr(Result.get());
   if (!Result.isUsable()) return Result;
 
   QualType T = Result.get()->getType();
@@ -438,12 +439,14 @@
   if (!BaseResult.isSingleResult())
     return true;
 
-  const RecordType *RT = 0;
+  const RecordType *RT = nullptr;
   NamedDecl *FoundDecl = BaseResult.getFoundDecl();
   if (VarDecl *VD = dyn_cast<VarDecl>(FoundDecl))
     RT = VD->getType()->getAs<RecordType>();
-  else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(FoundDecl))
+  else if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(FoundDecl))
     RT = TD->getUnderlyingType()->getAs<RecordType>();
+  else if (TypeDecl *TD = dyn_cast<TypeDecl>(FoundDecl))
+    RT = TD->getTypeForDecl()->getAs<RecordType>();
   if (!RT)
     return true;
 
@@ -483,5 +486,5 @@
                             /*IsVolatile*/ true, AsmToks, NumOutputs, NumInputs,
                             Constraints, Exprs, AsmString,
                             Clobbers, EndLoc);
-  return Owned(NS);
+  return NS;
 }
diff --git a/lib/Sema/SemaStmtAttr.cpp b/lib/Sema/SemaStmtAttr.cpp
index eb0188a..a32e0fb 100644
--- a/lib/Sema/SemaStmtAttr.cpp
+++ b/lib/Sema/SemaStmtAttr.cpp
@@ -12,12 +12,11 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Sema/SemaInternal.h"
-#include "TargetAttributesSema.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/Basic/SourceManager.h"
-#include "clang/Lex/Lexer.h"
 #include "clang/Sema/DelayedDiagnostic.h"
 #include "clang/Sema/Lookup.h"
+#include "clang/Sema/LoopHint.h"
 #include "clang/Sema/ScopeInfo.h"
 #include "llvm/ADT/StringExtras.h"
 
@@ -30,20 +29,164 @@
     S.Diag(A.getRange().getBegin(), diag::err_fallthrough_attr_wrong_target)
         << St->getLocStart();
     if (isa<SwitchCase>(St)) {
-      SourceLocation L = Lexer::getLocForEndOfToken(Range.getEnd(), 0,
-                                  S.getSourceManager(), S.getLangOpts());
+      SourceLocation L = S.getLocForEndOfToken(Range.getEnd());
       S.Diag(L, diag::note_fallthrough_insert_semi_fixit)
           << FixItHint::CreateInsertion(L, ";");
     }
-    return 0;
+    return nullptr;
   }
   if (S.getCurFunction()->SwitchStack.empty()) {
     S.Diag(A.getRange().getBegin(), diag::err_fallthrough_attr_outside_switch);
-    return 0;
+    return nullptr;
   }
-  return ::new (S.Context) FallThroughAttr(A.getRange(), S.Context);
+  return ::new (S.Context) FallThroughAttr(A.getRange(), S.Context,
+                                           A.getAttributeSpellingListIndex());
 }
 
+static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const AttributeList &A,
+                                SourceRange) {
+  IdentifierLoc *PragmaNameLoc = A.getArgAsIdent(0);
+  IdentifierLoc *OptionLoc = A.getArgAsIdent(1);
+  IdentifierInfo *OptionInfo = OptionLoc->Ident;
+  IdentifierLoc *ValueLoc = A.getArgAsIdent(2);
+  IdentifierInfo *ValueInfo = ValueLoc ? ValueLoc->Ident : nullptr;
+  Expr *ValueExpr = A.getArgAsExpr(3);
+
+  assert(OptionInfo && "Attribute must have valid option info.");
+
+  if (St->getStmtClass() != Stmt::DoStmtClass &&
+      St->getStmtClass() != Stmt::ForStmtClass &&
+      St->getStmtClass() != Stmt::CXXForRangeStmtClass &&
+      St->getStmtClass() != Stmt::WhileStmtClass) {
+    const char *Pragma = PragmaNameLoc->Ident->getName() == "unroll"
+                             ? "#pragma unroll"
+                             : "#pragma clang loop";
+    S.Diag(St->getLocStart(), diag::err_pragma_loop_precedes_nonloop) << Pragma;
+    return nullptr;
+  }
+
+  LoopHintAttr::OptionType Option;
+  LoopHintAttr::Spelling Spelling;
+  if (PragmaNameLoc->Ident->getName() == "unroll") {
+    Option = ValueLoc ? LoopHintAttr::UnrollCount : LoopHintAttr::Unroll;
+    Spelling = LoopHintAttr::Pragma_unroll;
+  } else {
+    Option = llvm::StringSwitch<LoopHintAttr::OptionType>(OptionInfo->getName())
+                 .Case("vectorize", LoopHintAttr::Vectorize)
+                 .Case("vectorize_width", LoopHintAttr::VectorizeWidth)
+                 .Case("interleave", LoopHintAttr::Interleave)
+                 .Case("interleave_count", LoopHintAttr::InterleaveCount)
+                 .Case("unroll", LoopHintAttr::Unroll)
+                 .Case("unroll_count", LoopHintAttr::UnrollCount)
+                 .Default(LoopHintAttr::Vectorize);
+    Spelling = LoopHintAttr::Pragma_clang_loop;
+  }
+
+  int ValueInt;
+  if (Option == LoopHintAttr::Unroll &&
+      Spelling == LoopHintAttr::Pragma_unroll) {
+    ValueInt = 1;
+  } else if (Option == LoopHintAttr::Vectorize ||
+             Option == LoopHintAttr::Interleave ||
+             Option == LoopHintAttr::Unroll) {
+    if (!ValueInfo) {
+      S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_keyword);
+      return nullptr;
+    }
+    if (ValueInfo->isStr("disable"))
+      ValueInt = 0;
+    else if (ValueInfo->isStr("enable"))
+      ValueInt = 1;
+    else {
+      S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_keyword);
+      return nullptr;
+    }
+  } else if (Option == LoopHintAttr::VectorizeWidth ||
+             Option == LoopHintAttr::InterleaveCount ||
+             Option == LoopHintAttr::UnrollCount) {
+    // FIXME: We should support template parameters for the loop hint value.
+    // See bug report #19610.
+    llvm::APSInt ValueAPS;
+    if (!ValueExpr || !ValueExpr->isIntegerConstantExpr(ValueAPS, S.Context) ||
+        (ValueInt = ValueAPS.getSExtValue()) < 1) {
+      S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_value);
+      return nullptr;
+    }
+  } else
+    llvm_unreachable("Unknown loop hint option");
+
+  return LoopHintAttr::CreateImplicit(S.Context, Spelling, Option, ValueInt,
+                                      A.getRange());
+}
+
+static void CheckForIncompatibleAttributes(
+    Sema &S, const SmallVectorImpl<const Attr *> &Attrs) {
+  // There are 3 categories of loop hints: vectorize, interleave, and
+  // unroll. Each comes in two variants: an enable/disable form and a
+  // form which takes a numeric argument. For example:
+  // unroll(enable|disable) and unroll_count(N). The following array
+  // accumulate the hints encountered while iterating through the
+  // attributes to check for compatibility.
+  struct {
+    const LoopHintAttr *EnableAttr;
+    const LoopHintAttr *NumericAttr;
+  } HintAttrs[] = {{nullptr, nullptr}, {nullptr, nullptr}, {nullptr, nullptr}};
+
+  for (const auto *I : Attrs) {
+    const LoopHintAttr *LH = dyn_cast<LoopHintAttr>(I);
+
+    // Skip non loop hint attributes
+    if (!LH)
+      continue;
+
+    int Option = LH->getOption();
+    int Category;
+    switch (Option) {
+    case LoopHintAttr::Vectorize:
+    case LoopHintAttr::VectorizeWidth:
+      Category = 0;
+      break;
+    case LoopHintAttr::Interleave:
+    case LoopHintAttr::InterleaveCount:
+      Category = 1;
+      break;
+    case LoopHintAttr::Unroll:
+    case LoopHintAttr::UnrollCount:
+      Category = 2;
+      break;
+    };
+
+    auto &CategoryState = HintAttrs[Category];
+    SourceLocation OptionLoc = LH->getRange().getBegin();
+    const LoopHintAttr *PrevAttr;
+    if (Option == LoopHintAttr::Vectorize ||
+        Option == LoopHintAttr::Interleave || Option == LoopHintAttr::Unroll) {
+      // Enable|disable hint.  For example, vectorize(enable).
+      PrevAttr = CategoryState.EnableAttr;
+      CategoryState.EnableAttr = LH;
+    } else {
+      // Numeric hint.  For example, vectorize_width(8).
+      PrevAttr = CategoryState.NumericAttr;
+      CategoryState.NumericAttr = LH;
+    }
+
+    if (PrevAttr)
+      // Cannot specify same type of attribute twice.
+      S.Diag(OptionLoc, diag::err_pragma_loop_compatibility)
+          << /*Duplicate=*/true << PrevAttr->getDiagnosticName()
+          << LH->getDiagnosticName();
+
+    if (CategoryState.EnableAttr && !CategoryState.EnableAttr->getValue() &&
+        CategoryState.NumericAttr) {
+      // Disable hints are not compatible with numeric hints of the
+      // same category.
+      S.Diag(OptionLoc, diag::err_pragma_loop_compatibility)
+          << /*Duplicate=*/false
+          << CategoryState.EnableAttr->getDiagnosticName()
+          << CategoryState.NumericAttr->getDiagnosticName();
+    }
+  }
+}
 
 static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const AttributeList &A,
                                   SourceRange Range) {
@@ -52,15 +195,17 @@
     S.Diag(A.getLoc(), A.isDeclspecAttribute() ?
            diag::warn_unhandled_ms_attribute_ignored :
            diag::warn_unknown_attribute_ignored) << A.getName();
-    return 0;
+    return nullptr;
   case AttributeList::AT_FallThrough:
     return handleFallThroughAttr(S, St, A, Range);
+  case AttributeList::AT_LoopHint:
+    return handleLoopHintAttr(S, St, A, Range);
   default:
     // if we're here, then we parsed a known attribute, but didn't recognize
     // it as a statement attribute => it is declaration attribute
     S.Diag(A.getRange().getBegin(), diag::err_attribute_invalid_on_stmt)
         << A.getName() << St->getLocStart();
-    return 0;
+    return nullptr;
   }
 }
 
@@ -72,6 +217,8 @@
       Attrs.push_back(a);
   }
 
+  CheckForIncompatibleAttributes(*this, Attrs);
+
   if (Attrs.empty())
     return S;
 
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 6d40e00..63581a4 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -10,8 +10,8 @@
 //===----------------------------------------------------------------------===/
 
 #include "TreeTransform.h"
-#include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclFriend.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
@@ -20,6 +20,7 @@
 #include "clang/AST/TypeVisitor.h"
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/TargetInfo.h"
 #include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/ParsedTemplate.h"
@@ -51,8 +52,8 @@
 
   if (isa<TemplateDecl>(D)) {
     if (!AllowFunctionTemplates && isa<FunctionTemplateDecl>(D))
-      return 0;
-    
+      return nullptr;
+
     return Orig;
   }
 
@@ -78,10 +79,10 @@
         return Spec->getSpecializedTemplate();
     }
 
-    return 0;
+    return nullptr;
   }
 
-  return 0;
+  return nullptr;
 }
 
 void Sema::FilterAcceptableTemplateNames(LookupResult &R, 
@@ -193,8 +194,7 @@
     TemplateDecl *TD = cast<TemplateDecl>((*R.begin())->getUnderlyingDecl());
 
     if (SS.isSet() && !SS.isInvalid()) {
-      NestedNameSpecifier *Qualifier
-        = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
+      NestedNameSpecifier *Qualifier = SS.getScopeRep();
       Template = Context.getQualifiedTemplateName(Qualifier,
                                                   hasTemplateKeyword, TD);
     } else {
@@ -250,7 +250,7 @@
                               bool &MemberOfUnknownSpecialization) {
   // Determine where to perform name lookup
   MemberOfUnknownSpecialization = false;
-  DeclContext *LookupCtx = 0;
+  DeclContext *LookupCtx = nullptr;
   bool isDependent = false;
   if (!ObjectType.isNull()) {
     // This nested-name-specifier occurs in a member access expression, e.g.,
@@ -325,7 +325,8 @@
     FilterCCC.WantCXXNamedCasts = true;
     if (TypoCorrection Corrected = CorrectTypo(Found.getLookupNameInfo(),
                                                Found.getLookupKind(), S, &SS,
-                                               FilterCCC, LookupCtx)) {
+                                               FilterCCC, CTK_ErrorRecovery,
+                                               LookupCtx)) {
       Found.setLookupName(Corrected.getCorrection());
       if (Corrected.getCorrectionDecl())
         Found.addDecl(Corrected.getCorrectionDecl());
@@ -418,17 +419,12 @@
 
     // Since the 'this' expression is synthesized, we don't need to
     // perform the double-lookup check.
-    NamedDecl *FirstQualifierInScope = 0;
+    NamedDecl *FirstQualifierInScope = nullptr;
 
-    return Owned(CXXDependentScopeMemberExpr::Create(Context,
-                                                     /*This*/ 0, ThisType,
-                                                     /*IsArrow*/ true,
-                                                     /*Op*/ SourceLocation(),
-                                               SS.getWithLocInContext(Context),
-                                                     TemplateKWLoc,
-                                                     FirstQualifierInScope,
-                                                     NameInfo,
-                                                     TemplateArgs));
+    return CXXDependentScopeMemberExpr::Create(
+        Context, /*This*/ nullptr, ThisType, /*IsArrow*/ true,
+        /*Op*/ SourceLocation(), SS.getWithLocInContext(Context), TemplateKWLoc,
+        FirstQualifierInScope, NameInfo, TemplateArgs);
   }
 
   return BuildDependentDeclRefExpr(SS, TemplateKWLoc, NameInfo, TemplateArgs);
@@ -439,11 +435,9 @@
                                 SourceLocation TemplateKWLoc,
                                 const DeclarationNameInfo &NameInfo,
                                 const TemplateArgumentListInfo *TemplateArgs) {
-  return Owned(DependentScopeDeclRefExpr::Create(Context,
-                                               SS.getWithLocInContext(Context),
-                                                 TemplateKWLoc,
-                                                 NameInfo,
-                                                 TemplateArgs));
+  return DependentScopeDeclRefExpr::Create(
+      Context, SS.getWithLocInContext(Context), TemplateKWLoc, NameInfo,
+      TemplateArgs);
 }
 
 /// DiagnoseTemplateParameterShadow - Produce a diagnostic complaining
@@ -474,7 +468,7 @@
     D = Temp->getTemplatedDecl();
     return Temp;
   }
-  return 0;
+  return nullptr;
 }
 
 ParsedTemplateArgument ParsedTemplateArgument::getTemplatePackExpansion(
@@ -550,7 +544,7 @@
 /// ParamNameLoc is the location of the parameter name (if any).
 /// If the type parameter has a default argument, it will be added
 /// later via ActOnTypeParameterDefault.
-Decl *Sema::ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis,
+Decl *Sema::ActOnTypeParameter(Scope *S, bool Typename,
                                SourceLocation EllipsisLoc,
                                SourceLocation KeyLoc,
                                IdentifierInfo *ParamName,
@@ -566,10 +560,11 @@
   if (!ParamName)
     Loc = KeyLoc;
 
+  bool IsParameterPack = EllipsisLoc.isValid();
   TemplateTypeParmDecl *Param
     = TemplateTypeParmDecl::Create(Context, Context.getTranslationUnitDecl(),
                                    KeyLoc, Loc, Depth, Position, ParamName,
-                                   Typename, Ellipsis);
+                                   Typename, IsParameterPack);
   Param->setAccess(AS_public);
   if (Invalid)
     Param->setInvalidDecl();
@@ -585,7 +580,7 @@
   // C++0x [temp.param]p9:
   //   A default template-argument may be specified for any kind of
   //   template-parameter that is not a template parameter pack.
-  if (DefaultArg && Ellipsis) {
+  if (DefaultArg && IsParameterPack) {
     Diag(EqualLoc, diag::err_template_param_pack_default_arg);
     DefaultArg = ParsedType();
   }
@@ -715,7 +710,7 @@
   //   template-parameter that is not a template parameter pack.
   if (Default && IsParameterPack) {
     Diag(EqualLoc, diag::err_template_param_pack_default_arg);
-    Default = 0;
+    Default = nullptr;
   }
 
   // Check the well-formedness of the default template argument, if provided.
@@ -730,7 +725,7 @@
       Param->setInvalidDecl();
       return Param;
     }
-    Default = DefaultRes.take();
+    Default = DefaultRes.get();
 
     Param->setDefaultArgument(Default, false);
   }
@@ -843,6 +838,7 @@
                          AttributeList *Attr,
                          TemplateParameterList *TemplateParams,
                          AccessSpecifier AS, SourceLocation ModulePrivateLoc,
+                         SourceLocation FriendLoc,
                          unsigned NumOuterTemplateParamLists,
                          TemplateParameterList** OuterTemplateParamLists) {
   assert(TemplateParams && TemplateParams->size() > 0 &&
@@ -906,7 +902,7 @@
   if (Previous.isAmbiguous())
     return true;
 
-  NamedDecl *PrevDecl = 0;
+  NamedDecl *PrevDecl = nullptr;
   if (Previous.begin() != Previous.end())
     PrevDecl = (*Previous.begin())->getUnderlyingDecl();
 
@@ -949,7 +945,7 @@
         // Declarations in outer scopes don't matter. However, the outermost
         // context we computed is the semantic context for our new
         // declaration.
-        PrevDecl = PrevClassTemplate = 0;
+        PrevDecl = PrevClassTemplate = nullptr;
         SemanticContext = OutermostContext;
 
         // Check that the chosen semantic context doesn't already contain a
@@ -968,8 +964,9 @@
           PrevDecl = (*Previous.begin())->getUnderlyingDecl();
       }
     }
-  } else if (PrevDecl && !isDeclInScope(PrevDecl, SemanticContext, S))
-    PrevDecl = PrevClassTemplate = 0;
+  } else if (PrevDecl &&
+             !isDeclInScope(PrevDecl, SemanticContext, S, SS.isValid()))
+    PrevDecl = PrevClassTemplate = nullptr;
 
   if (PrevClassTemplate) {
     // Ensure that the template parameter lists are compatible. Skip this check
@@ -1011,7 +1008,7 @@
     // Maybe we will complain about the shadowed template parameter.
     DiagnoseTemplateParameterShadow(NameLoc, PrevDecl);
     // Just pretend that we didn't see the previous declaration.
-    PrevDecl = 0;
+    PrevDecl = nullptr;
   } else if (PrevDecl) {
     // C++ [temp]p5:
     //   A class template shall not have the same name as any other
@@ -1030,7 +1027,8 @@
   if (!(TUK == TUK_Friend && CurContext->isDependentContext()) &&
       CheckTemplateParameterList(
           TemplateParams,
-          PrevClassTemplate ? PrevClassTemplate->getTemplateParameters() : 0,
+          PrevClassTemplate ? PrevClassTemplate->getTemplateParameters()
+                            : nullptr,
           (SS.isSet() && SemanticContext && SemanticContext->isRecord() &&
            SemanticContext->isDependentContext())
               ? TPC_ClassTemplateMember
@@ -1052,7 +1050,7 @@
   CXXRecordDecl *NewClass =
     CXXRecordDecl::Create(Context, Kind, SemanticContext, KWLoc, NameLoc, Name,
                           PrevClassTemplate?
-                            PrevClassTemplate->getTemplatedDecl() : 0,
+                            PrevClassTemplate->getTemplatedDecl() : nullptr,
                           /*DelayTypeCreation=*/true);
   SetNestedNameSpecifier(NewClass, SS);
   if (NumOuterTemplateParamLists > 0)
@@ -1126,10 +1124,8 @@
                           /* AddToContext = */ false);
     }
 
-    FriendDecl *Friend = FriendDecl::Create(Context, CurContext,
-                                            NewClass->getLocation(),
-                                            NewTemplate,
-                                    /*FIXME:*/NewClass->getLocation());
+    FriendDecl *Friend = FriendDecl::Create(
+        Context, CurContext, NewClass->getLocation(), NewTemplate, FriendLoc);
     Friend->setAccess(AS_public);
     CurContext->addDecl(Friend);
   }
@@ -1299,7 +1295,7 @@
 
       // Merge default arguments for template type parameters.
       TemplateTypeParmDecl *OldTypeParm
-          = OldParams? cast<TemplateTypeParmDecl>(*OldParam) : 0;
+          = OldParams? cast<TemplateTypeParmDecl>(*OldParam) : nullptr;
 
       if (NewTypeParm->isParameterPack()) {
         assert(!NewTypeParm->hasDefaultArgument() &&
@@ -1344,7 +1340,7 @@
 
       // Merge default arguments for non-type template parameters
       NonTypeTemplateParmDecl *OldNonTypeParm
-        = OldParams? cast<NonTypeTemplateParmDecl>(*OldParam) : 0;
+        = OldParams? cast<NonTypeTemplateParmDecl>(*OldParam) : nullptr;
       if (NewNonTypeParm->isParameterPack()) {
         assert(!NewNonTypeParm->hasDefaultArgument() &&
                "Parameter packs can't have a default argument!");
@@ -1391,7 +1387,7 @@
 
       // Merge default arguments for template template parameters
       TemplateTemplateParmDecl *OldTemplateParm
-        = OldParams? cast<TemplateTemplateParmDecl>(*OldParam) : 0;
+        = OldParams? cast<TemplateTemplateParmDecl>(*OldParam) : nullptr;
       if (NewTemplateParm->isParameterPack()) {
         assert(!NewTemplateParm->hasDefaultArgument() &&
                "Parameter packs can't have a default argument!");
@@ -1487,6 +1483,9 @@
 
   unsigned Depth;
   bool Match;
+  SourceLocation MatchLoc;
+
+  DependencyChecker(unsigned Depth) : Depth(Depth), Match(false) {}
 
   DependencyChecker(TemplateParameterList *Params) : Match(false) {
     NamedDecl *ND = Params->getParam(0);
@@ -1500,14 +1499,19 @@
     }
   }
 
-  bool Matches(unsigned ParmDepth) {
+  bool Matches(unsigned ParmDepth, SourceLocation Loc = SourceLocation()) {
     if (ParmDepth >= Depth) {
       Match = true;
+      MatchLoc = Loc;
       return true;
     }
     return false;
   }
 
+  bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
+    return !Matches(TL.getTypePtr()->getDepth(), TL.getNameLoc());
+  }
+
   bool VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
     return !Matches(T->getDepth());
   }
@@ -1515,21 +1519,28 @@
   bool TraverseTemplateName(TemplateName N) {
     if (TemplateTemplateParmDecl *PD =
           dyn_cast_or_null<TemplateTemplateParmDecl>(N.getAsTemplateDecl()))
-      if (Matches(PD->getDepth())) return false;
+      if (Matches(PD->getDepth()))
+        return false;
     return super::TraverseTemplateName(N);
   }
 
   bool VisitDeclRefExpr(DeclRefExpr *E) {
     if (NonTypeTemplateParmDecl *PD =
-          dyn_cast<NonTypeTemplateParmDecl>(E->getDecl())) {
-      if (PD->getDepth() == Depth) {
-        Match = true;
+          dyn_cast<NonTypeTemplateParmDecl>(E->getDecl()))
+      if (Matches(PD->getDepth(), E->getExprLoc()))
         return false;
-      }
-    }
     return super::VisitDeclRefExpr(E);
   }
-  
+
+  bool VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
+    return TraverseType(T->getReplacementType());
+  }
+
+  bool
+  VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T) {
+    return TraverseTemplateArgument(T->getArgumentPack());
+  }
+
   bool TraverseInjectedClassNameType(const InjectedClassNameType *T) {
     return TraverseType(T->getInjectedSpecializationType());
   }
@@ -1577,6 +1588,9 @@
 /// parameter lists. This scope specifier precedes a qualified name that is
 /// being declared.
 ///
+/// \param TemplateId The template-id following the scope specifier, if there
+/// is one. Used to check for a missing 'template<>'.
+///
 /// \param ParamLists the template parameter lists, from the outermost to the
 /// innermost template parameter lists.
 ///
@@ -1595,6 +1609,7 @@
 /// itself a template).
 TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier(
     SourceLocation DeclStartLoc, SourceLocation DeclLoc, const CXXScopeSpec &SS,
+    TemplateIdAnnotation *TemplateId,
     ArrayRef<TemplateParameterList *> ParamLists, bool IsFriend,
     bool &IsExplicitSpecialization, bool &Invalid) {
   IsExplicitSpecialization = false;
@@ -1701,6 +1716,37 @@
   //   template<> for each enclosing class template that is
   //   explicitly specialized.
   bool SawNonEmptyTemplateParameterList = false;
+
+  auto CheckExplicitSpecialization = [&](SourceRange Range, bool Recovery) {
+    if (SawNonEmptyTemplateParameterList) {
+      Diag(DeclLoc, diag::err_specialize_member_of_template)
+        << !Recovery << Range;
+      Invalid = true;
+      IsExplicitSpecialization = false;
+      return true;
+    }
+
+    return false;
+  };
+
+  auto DiagnoseMissingExplicitSpecialization = [&] (SourceRange Range) {
+    // Check that we can have an explicit specialization here.
+    if (CheckExplicitSpecialization(Range, true))
+      return true;
+
+    // We don't have a template header, but we should.
+    SourceLocation ExpectedTemplateLoc;
+    if (!ParamLists.empty())
+      ExpectedTemplateLoc = ParamLists[0]->getTemplateLoc();
+    else
+      ExpectedTemplateLoc = DeclStartLoc;
+
+    Diag(DeclLoc, diag::err_template_spec_needs_header)
+      << Range
+      << FixItHint::CreateInsertion(ExpectedTemplateLoc, "template<> ");
+    return false;
+  };
+
   unsigned ParamIdx = 0;
   for (unsigned TypeIdx = 0, NumTypes = NestedTypes.size(); TypeIdx != NumTypes;
        ++TypeIdx) {
@@ -1714,7 +1760,7 @@
     
     // For a dependent type, the set of template parameters that we
     // expect to see.
-    TemplateParameterList *ExpectedTemplateParams = 0;
+    TemplateParameterList *ExpectedTemplateParams = nullptr;
 
     // C++0x [temp.expl.spec]p15:
     //   A member or a member template may be nested within many enclosing 
@@ -1771,13 +1817,9 @@
     //   are not explicitly specialized as well.
     if (ParamIdx < ParamLists.size()) {
       if (ParamLists[ParamIdx]->size() == 0) {
-        if (SawNonEmptyTemplateParameterList) {
-          Diag(DeclLoc, diag::err_specialize_member_of_template)
-            << ParamLists[ParamIdx]->getSourceRange();
-          Invalid = true;
-          IsExplicitSpecialization = false;
-          return 0;
-        }
+        if (CheckExplicitSpecialization(ParamLists[ParamIdx]->getSourceRange(),
+                                        false))
+          return nullptr;
       } else
         SawNonEmptyTemplateParameterList = true;
     }
@@ -1798,30 +1840,22 @@
                            ParamLists[ParamIdx]->getRAngleLoc())
             << getRangeOfTypeInNestedNameSpecifier(Context, T, SS);
           Invalid = true;
-          return 0;
+          return nullptr;
         }
-        
+
         // Consume this template header.
         ++ParamIdx;
         continue;
-      } 
-      
-      if (!IsFriend) {
-        // We don't have a template header, but we should.
-        SourceLocation ExpectedTemplateLoc;
-        if (!ParamLists.empty())
-          ExpectedTemplateLoc = ParamLists[0]->getTemplateLoc();
-        else
-          ExpectedTemplateLoc = DeclStartLoc;
-
-        Diag(DeclLoc, diag::err_template_spec_needs_header)
-          << getRangeOfTypeInNestedNameSpecifier(Context, T, SS)
-          << FixItHint::CreateInsertion(ExpectedTemplateLoc, "template<> ");
       }
-      
+
+      if (!IsFriend)
+        if (DiagnoseMissingExplicitSpecialization(
+                getRangeOfTypeInNestedNameSpecifier(Context, T, SS)))
+          return nullptr;
+
       continue;
     }
-    
+
     if (NeedNonemptyTemplateHeader) {
       // In friend declarations we can have template-ids which don't
       // depend on the corresponding template parameter lists.  But
@@ -1830,7 +1864,7 @@
       if (IsFriend && T->isDependentType()) {
         if (ParamIdx < ParamLists.size() &&
             DependsOnTemplateParameters(T, ParamLists[ParamIdx]))
-          ExpectedTemplateParams = 0;
+          ExpectedTemplateParams = nullptr;
         else 
           continue;
       }
@@ -1842,9 +1876,9 @@
                                             ExpectedTemplateParams,
                                             true, TPL_TemplateMatch))
           Invalid = true;
-        
+
         if (!Invalid &&
-            CheckTemplateParameterList(ParamLists[ParamIdx], 0,
+            CheckTemplateParameterList(ParamLists[ParamIdx], nullptr,
                                        TPC_ClassTemplateMember))
           Invalid = true;
         
@@ -1859,12 +1893,26 @@
       continue;
     }
   }
-    
+
   // If there were at least as many template-ids as there were template
   // parameter lists, then there are no template parameter lists remaining for
   // the declaration itself.
-  if (ParamIdx >= ParamLists.size())
-    return 0;
+  if (ParamIdx >= ParamLists.size()) {
+    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));
+
+      // Fabricate an empty template parameter list for the invented header.
+      return TemplateParameterList::Create(Context, SourceLocation(),
+                                           SourceLocation(), nullptr, 0,
+                                           SourceLocation());
+    }
+
+    return nullptr;
+  }
 
   // If there were too many template parameter lists, complain about that now.
   if (ParamIdx < ParamLists.size() - 1) {
@@ -1905,14 +1953,11 @@
   //   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 && SawNonEmptyTemplateParameterList) {
-    Diag(DeclLoc, diag::err_specialize_member_of_template)
-      << ParamLists[ParamIdx]->getSourceRange();
-    Invalid = true;
-    IsExplicitSpecialization = false;
-    return 0;
-  }
-  
+  if (ParamLists.back()->size() == 0 &&
+      CheckExplicitSpecialization(ParamLists[ParamIdx]->getSourceRange(),
+                                  false))
+    return nullptr;
+
   // Return the last template parameter list, which corresponds to the
   // entity being declared.
   return ParamLists.back();
@@ -1959,7 +2004,8 @@
                                                           TemplateArgs);
 
   TemplateDecl *Template = Name.getAsTemplateDecl();
-  if (!Template || isa<FunctionTemplateDecl>(Template)) {
+  if (!Template || isa<FunctionTemplateDecl>(Template) ||
+      isa<VarTemplateDecl>(Template)) {
     // We might have a substituted template template parameter pack. If so,
     // build a template specialization type for it.
     if (Name.getAsSubstTemplateTemplateParmPack())
@@ -1974,17 +2020,15 @@
   // Check that the template argument list is well-formed for this
   // template.
   SmallVector<TemplateArgument, 4> Converted;
-  bool ExpansionIntoFixedList = false;
   if (CheckTemplateArgumentList(Template, TemplateLoc, TemplateArgs,
-                                false, Converted, &ExpansionIntoFixedList))
+                                false, Converted))
     return QualType();
 
   QualType CanonType;
 
   bool InstantiationDependent = false;
-  TypeAliasTemplateDecl *AliasTemplate = 0;
-  if (!ExpansionIntoFixedList &&
-      (AliasTemplate = dyn_cast<TypeAliasTemplateDecl>(Template))) {
+  if (TypeAliasTemplateDecl *AliasTemplate =
+          dyn_cast<TypeAliasTemplateDecl>(Template)) {
     // Find the canonical type for this type alias template specialization.
     TypeAliasDecl *Pattern = AliasTemplate->getTemplatedDecl();
     if (Pattern->isInvalidDecl())
@@ -2072,10 +2116,9 @@
                = dyn_cast<ClassTemplateDecl>(Template)) {
     // Find the class template specialization declaration that
     // corresponds to these arguments.
-    void *InsertPos = 0;
+    void *InsertPos = nullptr;
     ClassTemplateSpecializationDecl *Decl
-      = ClassTemplate->findSpecialization(Converted.data(), Converted.size(),
-                                          InsertPos);
+      = ClassTemplate->findSpecialization(Converted, InsertPos);
     if (!Decl) {
       // This is the first time we have referenced this class template
       // specialization. Create the canonical declaration and add it to
@@ -2087,7 +2130,7 @@
                                                 ClassTemplate->getLocation(),
                                                      ClassTemplate,
                                                      Converted.data(),
-                                                     Converted.size(), 0);
+                                                     Converted.size(), nullptr);
       ClassTemplate->AddSpecialization(Decl, InsertPos);
       if (ClassTemplate->isOutOfLine())
         Decl->setLexicalDeclContext(ClassTemplate->getLexicalDeclContext());
@@ -2267,8 +2310,8 @@
 }
 
 static bool CheckTemplatePartialSpecializationArgs(
-    Sema &S, TemplateParameterList *TemplateParams,
-    SmallVectorImpl<TemplateArgument> &TemplateArgs);
+    Sema &S, SourceLocation NameLoc, TemplateParameterList *TemplateParams,
+    unsigned ExplicitArgs, SmallVectorImpl<TemplateArgument> &TemplateArgs);
 
 static bool CheckTemplateSpecializationScope(Sema &S, NamedDecl *Specialized,
                                              NamedDecl *PrevDecl,
@@ -2340,25 +2383,49 @@
   return true;
 }
 
-DeclResult Sema::ActOnVarTemplateSpecialization(
-    Scope *S, VarTemplateDecl *VarTemplate, Declarator &D, TypeSourceInfo *DI,
-    SourceLocation TemplateKWLoc, TemplateParameterList *TemplateParams,
-    VarDecl::StorageClass SC, bool IsPartialSpecialization) {
-  assert(VarTemplate && "A variable template id without template?");
+/// Convert the parser's template argument list representation into our form.
+static TemplateArgumentListInfo
+makeTemplateArgumentListInfo(Sema &S, TemplateIdAnnotation &TemplateId) {
+  TemplateArgumentListInfo TemplateArgs(TemplateId.LAngleLoc,
+                                        TemplateId.RAngleLoc);
+  ASTTemplateArgsPtr TemplateArgsPtr(TemplateId.getTemplateArgs(),
+                                     TemplateId.NumArgs);
+  S.translateTemplateArguments(TemplateArgsPtr, TemplateArgs);
+  return TemplateArgs;
+}
 
+DeclResult Sema::ActOnVarTemplateSpecialization(
+    Scope *S, Declarator &D, TypeSourceInfo *DI, SourceLocation TemplateKWLoc,
+    TemplateParameterList *TemplateParams, VarDecl::StorageClass SC,
+    bool IsPartialSpecialization) {
   // D must be variable template id.
   assert(D.getName().getKind() == UnqualifiedId::IK_TemplateId &&
          "Variable template specialization is declared with a template it.");
 
   TemplateIdAnnotation *TemplateId = D.getName().TemplateId;
+  TemplateArgumentListInfo TemplateArgs =
+      makeTemplateArgumentListInfo(*this, *TemplateId);
   SourceLocation TemplateNameLoc = D.getIdentifierLoc();
   SourceLocation LAngleLoc = TemplateId->LAngleLoc;
   SourceLocation RAngleLoc = TemplateId->RAngleLoc;
-  ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),
-                                     TemplateId->NumArgs);
-  TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc);
-  translateTemplateArguments(TemplateArgsPtr, TemplateArgs);
-  TemplateName Name(VarTemplate);
+
+  TemplateName Name = TemplateId->Template.get();
+
+  // The template-id must name a variable template.
+  VarTemplateDecl *VarTemplate =
+      dyn_cast_or_null<VarTemplateDecl>(Name.getAsTemplateDecl());
+  if (!VarTemplate) {
+    NamedDecl *FnTemplate;
+    if (auto *OTS = Name.getAsOverloadedTemplate())
+      FnTemplate = *OTS->begin();
+    else
+      FnTemplate = dyn_cast_or_null<FunctionTemplateDecl>(Name.getAsTemplateDecl());
+    if (FnTemplate)
+      return Diag(D.getIdentifierLoc(), diag::err_var_spec_no_template_but_method)
+               << FnTemplate->getDeclName();
+    return Diag(D.getIdentifierLoc(), diag::err_var_spec_no_template)
+             << IsPartialSpecialization;
+  }
 
   // Check for unexpanded parameter packs in any of the template arguments.
   for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
@@ -2396,7 +2463,8 @@
   // corresponds to these arguments.
   if (IsPartialSpecialization) {
     if (CheckTemplatePartialSpecializationArgs(
-            *this, VarTemplate->getTemplateParameters(), Converted))
+            *this, TemplateNameLoc, VarTemplate->getTemplateParameters(),
+            TemplateArgs.size(), Converted))
       return true;
 
     bool InstantiationDependent;
@@ -2425,18 +2493,16 @@
     }
   }
 
-  void *InsertPos = 0;
-  VarTemplateSpecializationDecl *PrevDecl = 0;
+  void *InsertPos = nullptr;
+  VarTemplateSpecializationDecl *PrevDecl = nullptr;
 
   if (IsPartialSpecialization)
     // FIXME: Template parameter list matters too
-    PrevDecl = VarTemplate->findPartialSpecialization(
-        Converted.data(), Converted.size(), InsertPos);
+    PrevDecl = VarTemplate->findPartialSpecialization(Converted, InsertPos);
   else
-    PrevDecl = VarTemplate->findSpecialization(Converted.data(),
-                                               Converted.size(), InsertPos);
+    PrevDecl = VarTemplate->findSpecialization(Converted, InsertPos);
 
-  VarTemplateSpecializationDecl *Specialization = 0;
+  VarTemplateSpecializationDecl *Specialization = nullptr;
 
   // Check whether we can declare a variable template specialization in
   // the current scope.
@@ -2452,7 +2518,7 @@
     // the list of outer template parameters to reflect our new declaration.
     Specialization = PrevDecl;
     Specialization->setLocation(TemplateNameLoc);
-    PrevDecl = 0;
+    PrevDecl = nullptr;
   } else if (IsPartialSpecialization) {
     // Create a new class template partial specialization declaration node.
     VarTemplatePartialSpecializationDecl *PrevPartial =
@@ -2494,7 +2560,7 @@
                 << Param->getDeclName();
           else
             Diag(Param->getLocation(), diag::note_partial_spec_unused_parameter)
-                << "<anonymous>";
+                << "(anonymous)";
         }
       }
     }
@@ -2589,18 +2655,17 @@
 
   // Check that the template argument list is well-formed for this template.
   SmallVector<TemplateArgument, 4> Converted;
-  bool ExpansionIntoFixedList = false;
   if (CheckTemplateArgumentList(
           Template, TemplateNameLoc,
           const_cast<TemplateArgumentListInfo &>(TemplateArgs), false,
-          Converted, &ExpansionIntoFixedList))
+          Converted))
     return true;
 
   // Find the variable template specialization declaration that
   // corresponds to these arguments.
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
   if (VarTemplateSpecializationDecl *Spec = Template->findSpecialization(
-          Converted.data(), Converted.size(), InsertPos))
+          Converted, InsertPos))
     // If we already have a variable template specialization, return it.
     return Spec;
 
@@ -2652,11 +2717,6 @@
       }
     }
 
-    // If we're dealing with a member template where the template parameters
-    // have been instantiated, this provides the original template parameters
-    // from which the member template's parameters were instantiated.
-    SmallVector<const NamedDecl *, 4> InstantiatedTemplateParameters;
-
     if (Matched.size() >= 1) {
       SmallVector<MatchResult, 4>::iterator Best = Matched.begin();
       if (Matched.size() == 1) {
@@ -2756,7 +2816,7 @@
 
   // Build an ordinary singleton decl ref.
   return BuildDeclarationNameExpr(SS, NameInfo, Var,
-                                  /*FoundD=*/0, TemplateArgs);
+                                  /*FoundD=*/nullptr, TemplateArgs);
 }
 
 ExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS,
@@ -2779,10 +2839,13 @@
   assert(!R.isAmbiguous() && "ambiguous lookup when building templateid");
 
   // In C++1y, check variable template ids.
-  if (R.getAsSingle<VarTemplateDecl>()) {
-    return Owned(CheckVarTemplateId(SS, R.getLookupNameInfo(),
-                                    R.getAsSingle<VarTemplateDecl>(),
-                                    TemplateKWLoc, TemplateArgs));
+  bool InstantiationDependent;
+  if (R.getAsSingle<VarTemplateDecl>() &&
+      !TemplateSpecializationType::anyDependentTemplateArguments(
+           *TemplateArgs, InstantiationDependent)) {
+    return CheckVarTemplateId(SS, R.getLookupNameInfo(),
+                              R.getAsSingle<VarTemplateDecl>(),
+                              TemplateKWLoc, TemplateArgs);
   }
 
   // We don't want lookup warnings at this point.
@@ -2796,7 +2859,7 @@
                                    RequiresADL, TemplateArgs,
                                    R.begin(), R.end());
 
-  return Owned(ULE);
+  return ULE;
 }
 
 // We actually only call this from template instantiation.
@@ -2815,7 +2878,7 @@
 
   bool MemberOfUnknownSpecialization;
   LookupResult R(*this, NameInfo, LookupOrdinaryName);
-  LookupTemplateName(R, (Scope*) 0, SS, QualType(), /*Entering*/ false,
+  LookupTemplateName(R, (Scope*)nullptr, SS, QualType(), /*Entering*/ false,
                      MemberOfUnknownSpecialization);
 
   if (R.isAmbiguous())
@@ -2829,8 +2892,8 @@
 
   if (ClassTemplateDecl *Temp = R.getAsSingle<ClassTemplateDecl>()) {
     Diag(NameInfo.getLoc(), diag::err_template_kw_refers_to_class_template)
-      << (NestedNameSpecifier*) SS.getScopeRep()
-      << NameInfo.getName() << SS.getRange();
+      << SS.getScopeRep()
+      << NameInfo.getName().getAsString() << SS.getRange();
     Diag(Temp->getLocation(), diag::note_referenced_class_template);
     return ExprError();
   }
@@ -2859,7 +2922,7 @@
            diag::ext_template_outside_of_template)
       << FixItHint::CreateRemoval(TemplateKWLoc);
 
-  DeclContext *LookupCtx = 0;
+  DeclContext *LookupCtx = nullptr;
   if (SS.isSet())
     LookupCtx = computeDeclContext(SS, EnteringContext);
   if (!LookupCtx && ObjectType)
@@ -2903,8 +2966,7 @@
     }
   }
 
-  NestedNameSpecifier *Qualifier
-    = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
+  NestedNameSpecifier *Qualifier = SS.getScopeRep();
 
   switch (Name.getKind()) {
   case UnqualifiedId::IK_Identifier:
@@ -2915,11 +2977,10 @@
   case UnqualifiedId::IK_OperatorFunctionId:
     Result = TemplateTy::make(Context.getDependentTemplateName(Qualifier,
                                              Name.OperatorFunctionId.Operator));
-    return TNK_Dependent_template_name;
+    return TNK_Function_template;
 
   case UnqualifiedId::IK_LiteralOperatorId:
-    llvm_unreachable(
-            "We don't support these; Parse shouldn't have allowed propagation");
+    llvm_unreachable("literal operator id cannot have a dependent scope");
 
   default:
     break;
@@ -2934,9 +2995,11 @@
 }
 
 bool Sema::CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
-                                     const TemplateArgumentLoc &AL,
+                                     TemplateArgumentLoc &AL,
                           SmallVectorImpl<TemplateArgument> &Converted) {
   const TemplateArgument &Arg = AL.getArgument();
+  QualType ArgType;
+  TypeSourceInfo *TSI = nullptr;
 
   // Check template type parameter.
   switch(Arg.getKind()) {
@@ -2944,6 +3007,8 @@
     // C++ [temp.arg.type]p1:
     //   A template-argument for a template-parameter which is a
     //   type shall be a type-id.
+    ArgType = Arg.getAsType();
+    TSI = AL.getTypeSourceInfo();
     break;
   case TemplateArgument::Template: {
     // We have a template type parameter but the template argument
@@ -2978,18 +3043,38 @@
       }
     }
 
-    if (NameInfo.getName().isIdentifier()) {
+    if (auto *II = NameInfo.getName().getAsIdentifierInfo()) {
       LookupResult Result(*this, NameInfo, LookupOrdinaryName);
       LookupParsedName(Result, CurScope, &SS);
 
       if (Result.getAsSingle<TypeDecl>() ||
           Result.getResultKind() ==
-            LookupResult::NotFoundInCurrentInstantiation) {
-        // FIXME: Add a FixIt and fix up the template argument for recovery.
+              LookupResult::NotFoundInCurrentInstantiation) {
+        // Suggest that the user add 'typename' before the NNS.
         SourceLocation Loc = AL.getSourceRange().getBegin();
-        Diag(Loc, diag::err_template_arg_must_be_type_suggest);
+        Diag(Loc, getLangOpts().MSVCCompat
+                      ? diag::ext_ms_template_type_arg_missing_typename
+                      : diag::err_template_arg_must_be_type_suggest)
+            << FixItHint::CreateInsertion(Loc, "typename ");
         Diag(Param->getLocation(), diag::note_template_param_here);
-        return true;
+
+        // Recover by synthesizing a type using the location information that we
+        // already have.
+        ArgType =
+            Context.getDependentNameType(ETK_Typename, SS.getScopeRep(), II);
+        TypeLocBuilder TLB;
+        DependentNameTypeLoc TL = TLB.push<DependentNameTypeLoc>(ArgType);
+        TL.setElaboratedKeywordLoc(SourceLocation(/*synthesized*/));
+        TL.setQualifierLoc(SS.getWithLocInContext(Context));
+        TL.setNameLoc(NameInfo.getLoc());
+        TSI = TLB.getTypeSourceInfo(Context, ArgType);
+
+        // Overwrite our input TemplateArgumentLoc so that we can recover
+        // properly.
+        AL = TemplateArgumentLoc(TemplateArgument(ArgType),
+                                 TemplateArgumentLocInfo(TSI));
+
+        break;
       }
     }
     // fallthrough
@@ -3005,11 +3090,11 @@
   }
   }
 
-  if (CheckTemplateArgument(Param, AL.getTypeSourceInfo()))
+  if (CheckTemplateArgument(Param, TSI))
     return true;
 
   // Add the converted template type argument.
-  QualType ArgType = Context.getCanonicalType(Arg.getAsType());
+  ArgType = Context.getCanonicalType(ArgType);
   
   // Objective-C ARC:
   //   If an explicitly-specified template argument type is a lifetime type
@@ -3063,7 +3148,7 @@
                                      Template, Converted,
                                      SourceRange(TemplateLoc, RAngleLoc));
     if (Inst.isInvalid())
-      return 0;
+      return nullptr;
 
     TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
                                       Converted.data(), Converted.size());
@@ -3239,7 +3324,7 @@
     if (Arg.isInvalid())
       return TemplateArgumentLoc();
 
-    Expr *ArgE = Arg.takeAs<Expr>();
+    Expr *ArgE = Arg.getAs<Expr>();
     return TemplateArgumentLoc(TemplateArgument(ArgE), ArgE);
   }
 
@@ -3291,7 +3376,7 @@
 ///
 /// \returns true on error, false otherwise.
 bool Sema::CheckTemplateArgument(NamedDecl *Param,
-                                 const TemplateArgumentLoc &Arg,
+                                 TemplateArgumentLoc &Arg,
                                  NamedDecl *Template,
                                  SourceLocation TemplateLoc,
                                  SourceLocation RAngleLoc,
@@ -3381,21 +3466,20 @@
         // so it was provided with a template keyword. However, its source
         // location is not stored in the template argument structure.
         SourceLocation TemplateKWLoc;
-        ExprResult E = Owned(DependentScopeDeclRefExpr::Create(Context,
-                                                SS.getWithLocInContext(Context),
-                                                               TemplateKWLoc,
-                                                               NameInfo, 0));
+        ExprResult E = DependentScopeDeclRefExpr::Create(
+            Context, SS.getWithLocInContext(Context), TemplateKWLoc, NameInfo,
+            nullptr);
 
         // If we parsed the template argument as a pack expansion, create a
         // pack expansion expression.
         if (Arg.getArgument().getKind() == TemplateArgument::TemplateExpansion){
-          E = ActOnPackExpansion(E.take(), Arg.getTemplateEllipsisLoc());
+          E = ActOnPackExpansion(E.get(), Arg.getTemplateEllipsisLoc());
           if (E.isInvalid())
             return true;
         }
 
         TemplateArgument Result;
-        E = CheckTemplateArgument(NTTP, NTTPType, E.take(), Result);
+        E = CheckTemplateArgument(NTTP, NTTPType, E.get(), Result);
         if (E.isInvalid())
           return true;
 
@@ -3555,11 +3639,7 @@
                                      SourceLocation TemplateLoc,
                                      TemplateArgumentListInfo &TemplateArgs,
                                      bool PartialTemplateArgs,
-                          SmallVectorImpl<TemplateArgument> &Converted,
-                                     bool *ExpansionIntoFixedList) {
-  if (ExpansionIntoFixedList)
-    *ExpansionIntoFixedList = false;
-
+                          SmallVectorImpl<TemplateArgument> &Converted) {
   TemplateParameterList *Params = Template->getTemplateParameters();
 
   SourceLocation RAngleLoc = TemplateArgs.getRAngleLoc();
@@ -3612,6 +3692,20 @@
                                 ArgumentPack.size(), Converted))
         return true;
 
+      if (TemplateArgs[ArgIdx].getArgument().isPackExpansion() &&
+          isa<TypeAliasTemplateDecl>(Template) &&
+          !(Param + 1 == ParamEnd && (*Param)->isTemplateParameterPack() &&
+            !getExpandedPackSize(*Param))) {
+        // Core issue 1430: we have a pack expansion as an argument to an
+        // alias template, and it's not part of a final parameter pack. This
+        // can't be canonicalized, so reject it now.
+        Diag(TemplateArgs[ArgIdx].getLocation(),
+             diag::err_alias_template_expansion_into_fixed_list)
+          << TemplateArgs[ArgIdx].getSourceRange();
+        Diag((*Param)->getLocation(), diag::note_template_param_here);
+        return true;
+      }
+
       // We're now done with this argument.
       ++ArgIdx;
 
@@ -3658,9 +3752,6 @@
                                              ArgumentPack.data(),
                                              ArgumentPack.size()));
           ArgumentPack.clear();
-        } else if (ExpansionIntoFixedList) {
-          // We have expanded a pack into a fixed list.
-          *ExpansionIntoFixedList = true;
         }
 
         return false;
@@ -3738,7 +3829,7 @@
       if (E.isInvalid())
         return true;
 
-      Expr *Ex = E.takeAs<Expr>();
+      Expr *Ex = E.getAs<Expr>();
       Arg = TemplateArgumentLoc(TemplateArgument(Ex), Ex);
     } else {
       TemplateTemplateParmDecl *TempParm
@@ -3785,6 +3876,17 @@
     ++ArgIdx;
   }
 
+  // If we're performing a partial argument substitution, allow any trailing
+  // pack expansions; they might be empty. This can happen even if
+  // PartialTemplateArgs is false (the list of arguments is complete but
+  // still dependent).
+  if (ArgIdx < NumArgs && CurrentInstantiationScope &&
+      CurrentInstantiationScope->getPartiallySubstitutedPack()) {
+    while (ArgIdx < NumArgs &&
+           TemplateArgs[ArgIdx].getArgument().isPackExpansion())
+      Converted.push_back(TemplateArgs[ArgIdx++].getArgument());
+  }
+
   // If we have any leftover arguments, then there were too many arguments.
   // Complain and fail.
   if (ArgIdx < NumArgs)
@@ -3889,19 +3991,17 @@
 
 bool UnnamedLocalNoLinkageFinder::VisitFunctionProtoType(
                                                   const FunctionProtoType* T) {
-  for (FunctionProtoType::arg_type_iterator A = T->arg_type_begin(),
-                                         AEnd = T->arg_type_end();
-       A != AEnd; ++A) {
-    if (Visit(*A))
+  for (const auto &A : T->param_types()) {
+    if (Visit(A))
       return true;
   }
 
-  return Visit(T->getResultType());
+  return Visit(T->getReturnType());
 }
 
 bool UnnamedLocalNoLinkageFinder::VisitFunctionNoProtoType(
                                                const FunctionNoProtoType* T) {
-  return Visit(T->getResultType());
+  return Visit(T->getReturnType());
 }
 
 bool UnnamedLocalNoLinkageFinder::VisitUnresolvedUsingType(
@@ -4057,12 +4157,17 @@
   //
   // C++11 allows these, and even in C++03 we allow them as an extension with
   // a warning.
-  if (LangOpts.CPlusPlus11 ?
-     Diags.getDiagnosticLevel(diag::warn_cxx98_compat_template_arg_unnamed_type,
-                              SR.getBegin()) != DiagnosticsEngine::Ignored ||
-      Diags.getDiagnosticLevel(diag::warn_cxx98_compat_template_arg_local_type,
-                               SR.getBegin()) != DiagnosticsEngine::Ignored :
-      Arg->hasUnnamedOrLocalType()) {
+  bool NeedsCheck;
+  if (LangOpts.CPlusPlus11)
+    NeedsCheck =
+        !Diags.isIgnored(diag::warn_cxx98_compat_template_arg_unnamed_type,
+                         SR.getBegin()) ||
+        !Diags.isIgnored(diag::warn_cxx98_compat_template_arg_local_type,
+                         SR.getBegin());
+  else
+    NeedsCheck = Arg->hasUnnamedOrLocalType();
+
+  if (NeedsCheck) {
     UnnamedLocalNoLinkageFinder Finder(*this, SR);
     (void)Finder.Visit(Context.getCanonicalType(Arg));
   }
@@ -4091,7 +4196,7 @@
   ExprResult ArgRV = S.DefaultFunctionArrayConversion(Arg);
   if (ArgRV.isInvalid())
     return NPV_Error;
-  Arg = ArgRV.take();
+  Arg = ArgRV.get();
   
   Expr::EvalResult EvalResult;
   SmallVector<PartialDiagnosticAt, 8> Notes;
@@ -4149,10 +4254,9 @@
   if (Arg->isNullPointerConstant(S.Context, Expr::NPC_NeverValueDependent)) {
     std::string Code = "static_cast<" + ParamType.getAsString() + ">(";
     S.Diag(Arg->getExprLoc(), diag::err_template_arg_untyped_null_constant)
-      << ParamType
-      << FixItHint::CreateInsertion(Arg->getLocStart(), Code)
-      << FixItHint::CreateInsertion(S.PP.getLocForEndOfToken(Arg->getLocEnd()),
-                                    ")");
+        << ParamType << FixItHint::CreateInsertion(Arg->getLocStart(), Code)
+        << FixItHint::CreateInsertion(S.getLocForEndOfToken(Arg->getLocEnd()),
+                                      ")");
     S.Diag(Param->getLocation(), diag::note_template_param_here);
     return NPV_NullPointer;
   }
@@ -4232,22 +4336,6 @@
   Expr *Arg = ArgIn;
   QualType ArgType = Arg->getType();
 
-  // If our parameter has pointer type, check for a null template value.
-  if (ParamType->isPointerType() || ParamType->isNullPtrType()) {
-    switch (isNullPointerValueTemplateArgument(S, Param, ParamType, Arg)) {
-    case NPV_NullPointer:
-      S.Diag(Arg->getExprLoc(), diag::warn_cxx98_compat_template_arg_null);
-      Converted = TemplateArgument(ParamType, /*isNullPtr*/true);
-      return false;
-
-    case NPV_Error:
-      return true;
-        
-    case NPV_NotNullPointer:
-      break;
-    }
-  }
-
   bool AddressTaken = false;
   SourceLocation AddrOpLoc;
   if (S.getLangOpts().MicrosoftExt) {
@@ -4335,6 +4423,33 @@
       Arg = subst->getReplacement()->IgnoreImpCasts();
   }
 
+  DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Arg);
+  ValueDecl *Entity = DRE ? DRE->getDecl() : nullptr;
+
+  // If our parameter has pointer type, check for a null template value.
+  if (ParamType->isPointerType() || ParamType->isNullPtrType()) {
+    NullPointerValueKind NPV;
+    // dllimport'd entities aren't constant but are available inside of template
+    // arguments.
+    if (Entity && Entity->hasAttr<DLLImportAttr>())
+      NPV = NPV_NotNullPointer;
+    else
+      NPV = isNullPointerValueTemplateArgument(S, Param, ParamType, ArgIn);
+    switch (NPV) {
+    case NPV_NullPointer:
+      S.Diag(Arg->getExprLoc(), diag::warn_cxx98_compat_template_arg_null);
+      Converted = TemplateArgument(S.Context.getCanonicalType(ParamType),
+                                   /*isNullPtr=*/true);
+      return false;
+
+    case NPV_Error:
+      return true;
+
+    case NPV_NotNullPointer:
+      break;
+    }
+  }
+
   // Stop checking the precise nature of the argument if it is value dependent,
   // it should be checked when instantiated.
   if (Arg->isValueDependent()) {
@@ -4351,7 +4466,6 @@
     return false;
   }
 
-  DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Arg);
   if (!DRE) {
     S.Diag(Arg->getLocStart(), diag::err_template_arg_not_decl_ref)
     << Arg->getSourceRange();
@@ -4359,8 +4473,6 @@
     return true;
   }
 
-  ValueDecl *Entity = DRE->getDecl();
-
   // Cannot refer to non-static data members
   if (isa<FieldDecl>(Entity) || isa<IndirectFieldDecl>(Entity)) {
     S.Diag(Arg->getLocStart(), diag::err_template_arg_field)
@@ -4522,7 +4634,10 @@
     return true;
   case NPV_NullPointer:
     S.Diag(Arg->getExprLoc(), diag::warn_cxx98_compat_template_arg_null);
-    Converted = TemplateArgument(ParamType, /*isNullPtr*/true);
+    Converted = TemplateArgument(S.Context.getCanonicalType(ParamType),
+                                 /*isNullPtr*/true);
+    if (S.Context.getTargetInfo().getCXXABI().isMicrosoft())
+      S.RequireCompleteType(Arg->getExprLoc(), ParamType, 0);
     return false;
   case NPV_NotNullPointer:
     break;
@@ -4533,7 +4648,7 @@
                                   ParamType.getNonReferenceType(),
                                   false, ObjCLifetimeConversion)) {
     Arg = S.ImpCastExprToType(Arg, ParamType, CK_NoOp,
-                              Arg->getValueKind()).take();
+                              Arg->getValueKind()).get();
     ResultArg = Arg;
   } else if (!S.Context.hasSameUnqualifiedType(Arg->getType(),
                 ParamType.getNonReferenceType())) {
@@ -4554,7 +4669,7 @@
   //   template-parameter shall be one of: [...]
   //
   //     -- a pointer to member expressed as described in 5.3.1.
-  DeclRefExpr *DRE = 0;
+  DeclRefExpr *DRE = nullptr;
 
   // In C++98/03 mode, give an extension warning on any extra parentheses.
   // See http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#773
@@ -4581,16 +4696,14 @@
     if (UnOp->getOpcode() == UO_AddrOf) {
       DRE = dyn_cast<DeclRefExpr>(UnOp->getSubExpr());
       if (DRE && !DRE->getQualifier())
-        DRE = 0;
+        DRE = nullptr;
     }
   }
   // A constant of pointer-to-member type.
   else if ((DRE = dyn_cast<DeclRefExpr>(Arg))) {
     if (ValueDecl *VD = dyn_cast<ValueDecl>(DRE->getDecl())) {
       if (VD->getType()->isMemberPointerType()) {
-        if (isa<NonTypeTemplateParmDecl>(VD) ||
-            (isa<VarDecl>(VD) &&
-             S.Context.getCanonicalType(VD->getType()).isConstQualified())) {
+        if (isa<NonTypeTemplateParmDecl>(VD)) {
           if (Arg->isTypeDependent() || Arg->isValueDependent()) {
             Converted = TemplateArgument(Arg);
           } else {
@@ -4602,7 +4715,7 @@
       }
     }
 
-    DRE = 0;
+    DRE = nullptr;
   }
 
   if (!DRE)
@@ -4656,7 +4769,7 @@
   if (InstantiatedParamType->isDependentType() || Arg->isTypeDependent()) {
     // FIXME: Produce a cloned, canonical expression?
     Converted = TemplateArgument(Arg);
-    return Owned(Arg);
+    return Arg;
   }
 
   // C++ [temp.arg.nontype]p5:
@@ -4700,7 +4813,7 @@
       // we should be able to diagnose that prior to instantiation.
       if (Arg->isValueDependent()) {
         Converted = TemplateArgument(Arg);
-        return Owned(Arg);
+        return Arg;
       }
 
       // C++ [temp.arg.nontype]p1:
@@ -4733,7 +4846,7 @@
     ExprResult ArgResult = DefaultLvalueConversion(Arg);
     if (ArgResult.isInvalid())
       return ExprError();
-    Arg = ArgResult.take();
+    Arg = ArgResult.get();
 
     QualType ArgType = Arg->getType();
 
@@ -4758,15 +4871,15 @@
         
       public:
         TmplArgICEDiagnoser(QualType T) : T(T) { }
-        
-        virtual void diagnoseNotICE(Sema &S, SourceLocation Loc,
-                                    SourceRange SR) {
+
+        void diagnoseNotICE(Sema &S, SourceLocation Loc,
+                            SourceRange SR) override {
           S.Diag(Loc, diag::err_template_arg_not_ice) << T << SR;
         }
       } Diagnoser(ArgType);
 
       Arg = VerifyIntegerConstantExpression(Arg, &Value, Diagnoser,
-                                            false).take();
+                                            false).get();
       if (!Arg)
         return ExprError();
     }
@@ -4781,11 +4894,11 @@
       // Okay: no conversion necessary
     } else if (ParamType->isBooleanType()) {
       // This is an integral-to-boolean conversion.
-      Arg = ImpCastExprToType(Arg, ParamType, CK_IntegralToBoolean).take();
+      Arg = ImpCastExprToType(Arg, ParamType, CK_IntegralToBoolean).get();
     } else if (IsIntegralPromotion(Arg, ArgType, ParamType) ||
                !ParamType->isEnumeralType()) {
       // This is an integral promotion or conversion.
-      Arg = ImpCastExprToType(Arg, ParamType, CK_IntegralCast).take();
+      Arg = ImpCastExprToType(Arg, ParamType, CK_IntegralCast).get();
     } else {
       // We can't perform this conversion.
       Diag(Arg->getLocStart(),
@@ -4802,7 +4915,7 @@
       // The argument is value-dependent. Create a new
       // TemplateArgument with the converted expression.
       Converted = TemplateArgument(Arg);
-      return Owned(Arg);
+      return Arg;
     }
 
     QualType IntegerType = Context.getCanonicalType(ParamType);
@@ -4856,7 +4969,7 @@
                                  ParamType->isEnumeralType() 
                                    ? Context.getCanonicalType(ParamType)
                                    : IntegerType);
-    return Owned(Arg);
+    return Arg;
   }
 
   QualType ArgType = Arg->getType();
@@ -4904,13 +5017,13 @@
                                                          ParamType,
                                                          Arg, Converted))
         return ExprError();
-      return Owned(Arg);
+      return Arg;
     }
 
     if (CheckTemplateArgumentPointerToMember(*this, Param, ParamType, Arg,
                                              Converted))
       return ExprError();
-    return Owned(Arg);
+    return Arg;
   }
 
   if (ParamType->isPointerType()) {
@@ -4925,7 +5038,7 @@
                                                        ParamType,
                                                        Arg, Converted))
       return ExprError();
-    return Owned(Arg);
+    return Arg;
   }
 
   if (const ReferenceType *ParamRefType = ParamType->getAs<ReferenceType>()) {
@@ -4956,14 +5069,14 @@
                                                        ParamType,
                                                        Arg, Converted))
       return ExprError();
-    return Owned(Arg);
+    return Arg;
   }
 
   // Deal with parameters of type std::nullptr_t.
   if (ParamType->isNullPtrType()) {
     if (Arg->isTypeDependent() || Arg->isValueDependent()) {
       Converted = TemplateArgument(Arg);
-      return Owned(Arg);
+      return Arg;
     }
     
     switch (isNullPointerValueTemplateArgument(*this, Param, ParamType, Arg)) {
@@ -4978,8 +5091,9 @@
       
     case NPV_NullPointer:
       Diag(Arg->getExprLoc(), diag::warn_cxx98_compat_template_arg_null);
-      Converted = TemplateArgument(ParamType, /*isNullPtr*/true);
-      return Owned(Arg);
+      Converted = TemplateArgument(Context.getCanonicalType(ParamType),
+                                   /*isNullPtr*/true);
+      return Arg;
     }
   }
 
@@ -4990,7 +5104,7 @@
   if (CheckTemplateArgumentPointerToMember(*this, Param, ParamType, Arg,
                                            Converted))
     return ExprError();
-  return Owned(Arg);
+  return Arg;
 }
 
 /// \brief Check a template argument against its corresponding
@@ -4999,7 +5113,7 @@
 /// This routine implements the semantics of C++ [temp.arg.template].
 /// It returns true if an error occurred, and false otherwise.
 bool Sema::CheckTemplateArgument(TemplateTemplateParmDecl *Param,
-                                 const TemplateArgumentLoc &Arg,
+                                 TemplateArgumentLoc &Arg,
                                  unsigned ArgumentPackIndex) {
   TemplateName Name = Arg.getArgument().getAsTemplateOrTemplatePattern();
   TemplateDecl *Template = Name.getAsTemplateDecl();
@@ -5087,7 +5201,7 @@
       QualType ClassType
         = Context.getTypeDeclType(cast<RecordDecl>(VD->getDeclContext()));
       NestedNameSpecifier *Qualifier
-        = NestedNameSpecifier::Create(Context, 0, false,
+        = NestedNameSpecifier::Create(Context, nullptr, false,
                                       ClassType.getTypePtr());
       CXXScopeSpec SS;
       SS.MakeTrivial(Context, Qualifier, Loc);
@@ -5116,7 +5230,7 @@
       if (IsQualificationConversion(((Expr*) RefExpr.get())->getType(),
                                     ParamType.getUnqualifiedType(), false,
                                     ObjCLifetimeConversion))
-        RefExpr = ImpCastExprToType(RefExpr.take(), ParamType.getUnqualifiedType(), CK_NoOp);
+        RefExpr = ImpCastExprToType(RefExpr.get(), ParamType.getUnqualifiedType(), CK_NoOp);
 
       assert(!RefExpr.isInvalid() &&
              Context.hasSameType(((Expr*) RefExpr.get())->getType(),
@@ -5136,7 +5250,7 @@
 
     if (T->isFunctionType() || T->isArrayType()) {
       // Decay functions and arrays.
-      RefExpr = DefaultFunctionArrayConversion(RefExpr.take());
+      RefExpr = DefaultFunctionArrayConversion(RefExpr.get());
       if (RefExpr.isInvalid())
         return ExprError();
 
@@ -5213,12 +5327,13 @@
   if (OrigT->isEnumeralType()) {
     // FIXME: This is a hack. We need a better way to handle substituted
     // non-type template parameters.
-    E = CStyleCastExpr::Create(Context, OrigT, VK_RValue, CK_IntegralCast, E, 0,
+    E = CStyleCastExpr::Create(Context, OrigT, VK_RValue, CK_IntegralCast, E,
+                               nullptr,
                                Context.getTrivialTypeSourceInfo(OrigT, Loc),
                                Loc, Loc);
   }
   
-  return Owned(E);
+  return E;
 }
 
 /// \brief Match two template parameters within template parameter lists.
@@ -5452,18 +5567,19 @@
          (S->getFlags() & Scope::TemplateParamScope) != 0)
     S = S->getParent();
 
-  // C++ [temp]p2:
-  //   A template-declaration can appear only as a namespace scope or
-  //   class scope declaration.
+  // C++ [temp]p4:
+  //   A template [...] shall not have C linkage.
   DeclContext *Ctx = S->getEntity();
-  if (Ctx && isa<LinkageSpecDecl>(Ctx) &&
-      cast<LinkageSpecDecl>(Ctx)->getLanguage() != LinkageSpecDecl::lang_cxx)
+  if (Ctx && Ctx->isExternCContext())
     return Diag(TemplateParams->getTemplateLoc(), diag::err_template_linkage)
              << TemplateParams->getSourceRange();
 
   while (Ctx && isa<LinkageSpecDecl>(Ctx))
     Ctx = Ctx->getParent();
 
+  // C++ [temp]p2:
+  //   A template-declaration can appear only as a namespace scope or
+  //   class scope declaration.
   if (Ctx) {
     if (Ctx->isFileContext())
       return false;
@@ -5600,13 +5716,37 @@
   //   A class template partial specialization may be declared or redeclared
   //   in any namespace scope in which its definition may be defined (14.5.1
   //   and 14.5.2).
-  bool ComplainedAboutScope = false;
-  DeclContext *SpecializedContext 
+  DeclContext *SpecializedContext
     = Specialized->getDeclContext()->getEnclosingNamespaceContext();
   DeclContext *DC = S.CurContext->getEnclosingNamespaceContext();
-  if ((!PrevDecl ||
-       getTemplateSpecializationKind(PrevDecl) == TSK_Undeclared ||
-       getTemplateSpecializationKind(PrevDecl) == TSK_ImplicitInstantiation)){
+
+  // Make sure that this redeclaration (or definition) occurs in an enclosing
+  // namespace.
+  // Note that HandleDeclarator() performs this check for explicit
+  // specializations of function templates, static data members, and member
+  // functions, so we skip the check here for those kinds of entities.
+  // FIXME: HandleDeclarator's diagnostics aren't quite as good, though.
+  // Should we refactor that check, so that it occurs later?
+  if (!DC->Encloses(SpecializedContext) &&
+      !(isa<FunctionTemplateDecl>(Specialized) ||
+        isa<FunctionDecl>(Specialized) ||
+        isa<VarTemplateDecl>(Specialized) ||
+        isa<VarDecl>(Specialized))) {
+    if (isa<TranslationUnitDecl>(SpecializedContext))
+      S.Diag(Loc, diag::err_template_spec_redecl_global_scope)
+        << EntityKind << Specialized;
+    else if (isa<NamespaceDecl>(SpecializedContext))
+      S.Diag(Loc, diag::err_template_spec_redecl_out_of_scope)
+        << EntityKind << Specialized
+        << cast<NamedDecl>(SpecializedContext);
+    else
+      llvm_unreachable("unexpected namespace context for specialization");
+
+    S.Diag(Specialized->getLocation(), diag::note_specialized_entity);
+  } else if ((!PrevDecl ||
+              getTemplateSpecializationKind(PrevDecl) == TSK_Undeclared ||
+              getTemplateSpecializationKind(PrevDecl) ==
+                  TSK_ImplicitInstantiation)) {
     // C++ [temp.exp.spec]p2:
     //   An explicit specialization shall be declared in the namespace of which
     //   the template is a member, or, for member templates, in the namespace
@@ -5615,9 +5755,12 @@
     //   static data member of a class template shall be declared in the
     //   namespace of which the class template is a member.
     //
-    // C++0x [temp.expl.spec]p2:
+    // C++11 [temp.expl.spec]p2:
     //   An explicit specialization shall be declared in a namespace enclosing
     //   the specialized template.
+    // C++11 [temp.explicit]p3:
+    //   An explicit instantiation shall appear in an enclosing namespace of its
+    //   template.
     if (!DC->InEnclosingNamespaceSetOf(SpecializedContext)) {
       bool IsCPlusPlus11Extension = DC->Encloses(SpecializedContext);
       if (isa<TranslationUnitDecl>(SpecializedContext)) {
@@ -5638,46 +5781,42 @@
       }
 
       S.Diag(Specialized->getLocation(), diag::note_specialized_entity);
-      ComplainedAboutScope =
-        !(IsCPlusPlus11Extension && S.getLangOpts().CPlusPlus11);
     }
   }
 
-  // Make sure that this redeclaration (or definition) occurs in an enclosing
-  // namespace.
-  // Note that HandleDeclarator() performs this check for explicit
-  // specializations of function templates, static data members, and member
-  // functions, so we skip the check here for those kinds of entities.
-  // FIXME: HandleDeclarator's diagnostics aren't quite as good, though.
-  // Should we refactor that check, so that it occurs later?
-  if (!ComplainedAboutScope && !DC->Encloses(SpecializedContext) &&
-      !(isa<FunctionTemplateDecl>(Specialized) || isa<VarDecl>(Specialized) ||
-        isa<FunctionDecl>(Specialized))) {
-    if (isa<TranslationUnitDecl>(SpecializedContext))
-      S.Diag(Loc, diag::err_template_spec_redecl_global_scope)
-        << EntityKind << Specialized;
-    else if (isa<NamespaceDecl>(SpecializedContext))
-      S.Diag(Loc, diag::err_template_spec_redecl_out_of_scope)
-        << EntityKind << Specialized
-        << cast<NamedDecl>(SpecializedContext);
-
-    S.Diag(Specialized->getLocation(), diag::note_specialized_entity);
-  }
-
-  // FIXME: check for specialization-after-instantiation errors and such.
-
   return false;
 }
 
+static SourceRange findTemplateParameter(unsigned Depth, Expr *E) {
+  if (!E->isInstantiationDependent())
+    return SourceLocation();
+  DependencyChecker Checker(Depth);
+  Checker.TraverseStmt(E);
+  if (Checker.Match && Checker.MatchLoc.isInvalid())
+    return E->getSourceRange();
+  return Checker.MatchLoc;
+}
+
+static SourceRange findTemplateParameter(unsigned Depth, TypeLoc TL) {
+  if (!TL.getType()->isDependentType())
+    return SourceLocation();
+  DependencyChecker Checker(Depth);
+  Checker.TraverseTypeLoc(TL);
+  if (Checker.Match && Checker.MatchLoc.isInvalid())
+    return TL.getSourceRange();
+  return Checker.MatchLoc;
+}
+
 /// \brief Subroutine of Sema::CheckTemplatePartialSpecializationArgs
 /// that checks non-type template partial specialization arguments.
 static bool CheckNonTypeTemplatePartialSpecializationArgs(
-    Sema &S, NonTypeTemplateParmDecl *Param, const TemplateArgument *Args,
-    unsigned NumArgs) {
+    Sema &S, SourceLocation TemplateNameLoc, NonTypeTemplateParmDecl *Param,
+    const TemplateArgument *Args, unsigned NumArgs, bool IsDefaultArgument) {
   for (unsigned I = 0; I != NumArgs; ++I) {
     if (Args[I].getKind() == TemplateArgument::Pack) {
       if (CheckNonTypeTemplatePartialSpecializationArgs(
-              S, Param, Args[I].pack_begin(), Args[I].pack_size()))
+              S, TemplateNameLoc, Param, Args[I].pack_begin(),
+              Args[I].pack_size(), IsDefaultArgument))
         return true;
 
       continue;
@@ -5715,22 +5854,43 @@
     //        shall not involve a template parameter of the partial
     //        specialization except when the argument expression is a
     //        simple identifier.
-    if (ArgExpr->isTypeDependent() || ArgExpr->isValueDependent()) {
-      S.Diag(ArgExpr->getLocStart(),
-           diag::err_dependent_non_type_arg_in_partial_spec)
-        << ArgExpr->getSourceRange();
+    SourceRange ParamUseRange =
+        findTemplateParameter(Param->getDepth(), ArgExpr);
+    if (ParamUseRange.isValid()) {
+      if (IsDefaultArgument) {
+        S.Diag(TemplateNameLoc,
+               diag::err_dependent_non_type_arg_in_partial_spec);
+        S.Diag(ParamUseRange.getBegin(),
+               diag::note_dependent_non_type_default_arg_in_partial_spec)
+          << ParamUseRange;
+      } else {
+        S.Diag(ParamUseRange.getBegin(),
+               diag::err_dependent_non_type_arg_in_partial_spec)
+          << ParamUseRange;
+      }
       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.
-    if (Param->getType()->isDependentType()) {
-      S.Diag(ArgExpr->getLocStart(),
-           diag::err_dependent_typed_non_type_arg_in_partial_spec)
-        << Param->getType()
-        << ArgExpr->getSourceRange();
-      S.Diag(Param->getLocation(), diag::note_template_param_here);
+    //
+    // 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());
+    if (ParamUseRange.isValid()) {
+      S.Diag(IsDefaultArgument ? TemplateNameLoc : ArgExpr->getLocStart(),
+             diag::err_dependent_typed_non_type_arg_in_partial_spec)
+        << Param->getType() << ParamUseRange;
+      S.Diag(Param->getLocation(), diag::note_template_param_here)
+        << (IsDefaultArgument ? ParamUseRange : SourceRange());
       return true;
     }
   }
@@ -5741,15 +5901,17 @@
 /// \brief Check the non-type template arguments of a class template
 /// 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
-/// template.
-///
+///        template.
+/// \param NumExplicit the number of explicitly-specified template arguments.
 /// \param TemplateArgs the template arguments of the class template
-/// partial specialization.
+///        partial specialization.
 ///
-/// \returns true if there was an error, false otherwise.
+/// \returns \c true if there was an error, \c false otherwise.
 static bool CheckTemplatePartialSpecializationArgs(
-    Sema &S, TemplateParameterList *TemplateParams,
+    Sema &S, SourceLocation TemplateNameLoc,
+    TemplateParameterList *TemplateParams, unsigned NumExplicit,
     SmallVectorImpl<TemplateArgument> &TemplateArgs) {
   const TemplateArgument *ArgList = TemplateArgs.data();
 
@@ -5759,7 +5921,8 @@
     if (!Param)
       continue;
 
-    if (CheckNonTypeTemplatePartialSpecializationArgs(S, Param, &ArgList[I], 1))
+    if (CheckNonTypeTemplatePartialSpecializationArgs(
+            S, TemplateNameLoc, Param, &ArgList[I], 1, I >= NumExplicit))
       return true;
   }
 
@@ -5771,23 +5934,23 @@
                                        TagUseKind TUK,
                                        SourceLocation KWLoc,
                                        SourceLocation ModulePrivateLoc,
-                                       CXXScopeSpec &SS,
-                                       TemplateTy TemplateD,
-                                       SourceLocation TemplateNameLoc,
-                                       SourceLocation LAngleLoc,
-                                       ASTTemplateArgsPtr TemplateArgsIn,
-                                       SourceLocation RAngleLoc,
+                                       TemplateIdAnnotation &TemplateId,
                                        AttributeList *Attr,
                                MultiTemplateParamsArg TemplateParameterLists) {
   assert(TUK != TUK_Reference && "References are not specializations");
 
+  CXXScopeSpec &SS = TemplateId.SS;
+
   // NOTE: KWLoc is the location of the tag keyword. This will instead
   // store the location of the outermost template keyword in the declaration.
   SourceLocation TemplateKWLoc = TemplateParameterLists.size() > 0
-    ? TemplateParameterLists[0]->getTemplateLoc() : SourceLocation();
+    ? TemplateParameterLists[0]->getTemplateLoc() : KWLoc;
+  SourceLocation TemplateNameLoc = TemplateId.TemplateNameLoc;
+  SourceLocation LAngleLoc = TemplateId.LAngleLoc;
+  SourceLocation RAngleLoc = TemplateId.RAngleLoc;
 
   // Find the class template we're specializing
-  TemplateName Name = TemplateD.get();
+  TemplateName Name = TemplateId.Template.get();
   ClassTemplateDecl *ClassTemplate
     = dyn_cast_or_null<ClassTemplateDecl>(Name.getAsTemplateDecl());
 
@@ -5808,8 +5971,9 @@
   bool Invalid = false;
   TemplateParameterList *TemplateParams =
       MatchTemplateParametersToScopeSpecifier(
-          TemplateNameLoc, TemplateNameLoc, SS, TemplateParameterLists,
-          TUK == TUK_Friend, isExplicitSpecialization, Invalid);
+          KWLoc, TemplateNameLoc, SS, &TemplateId,
+          TemplateParameterLists, TUK == TUK_Friend, isExplicitSpecialization,
+          Invalid);
   if (Invalid)
     return true;
 
@@ -5860,11 +6024,8 @@
         << SourceRange(LAngleLoc, RAngleLoc);
     else
       isExplicitSpecialization = true;
-  } else if (TUK != TUK_Friend) {
-    Diag(KWLoc, diag::err_template_spec_needs_header)
-      << FixItHint::CreateInsertion(KWLoc, "template<> ");
-    TemplateKWLoc = KWLoc;
-    isExplicitSpecialization = true;
+  } else {
+    assert(TUK == TUK_Friend && "should have a 'template<>' for this decl");
   }
 
   // Check that the specialization uses the same tag kind as the
@@ -5884,10 +6045,8 @@
   }
 
   // Translate the parser's template argument list in our AST format.
-  TemplateArgumentListInfo TemplateArgs;
-  TemplateArgs.setLAngleLoc(LAngleLoc);
-  TemplateArgs.setRAngleLoc(RAngleLoc);
-  translateTemplateArguments(TemplateArgsIn, TemplateArgs);
+  TemplateArgumentListInfo TemplateArgs =
+      makeTemplateArgumentListInfo(*this, TemplateId);
 
   // Check for unexpanded parameter packs in any of the template arguments.
   for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
@@ -5906,7 +6065,8 @@
   // corresponds to these arguments.
   if (isPartialSpecialization) {
     if (CheckTemplatePartialSpecializationArgs(
-            *this, ClassTemplate->getTemplateParameters(), Converted))
+            *this, TemplateNameLoc, ClassTemplate->getTemplateParameters(),
+            TemplateArgs.size(), Converted))
       return true;
 
     bool InstantiationDependent;
@@ -5921,21 +6081,16 @@
     }
   }
 
-  void *InsertPos = 0;
-  ClassTemplateSpecializationDecl *PrevDecl = 0;
+  void *InsertPos = nullptr;
+  ClassTemplateSpecializationDecl *PrevDecl = nullptr;
 
   if (isPartialSpecialization)
     // FIXME: Template parameter list matters, too
-    PrevDecl
-      = ClassTemplate->findPartialSpecialization(Converted.data(),
-                                                 Converted.size(),
-                                                 InsertPos);
+    PrevDecl = ClassTemplate->findPartialSpecialization(Converted, InsertPos);
   else
-    PrevDecl
-      = ClassTemplate->findSpecialization(Converted.data(),
-                                          Converted.size(), InsertPos);
+    PrevDecl = ClassTemplate->findSpecialization(Converted, InsertPos);
 
-  ClassTemplateSpecializationDecl *Specialization = 0;
+  ClassTemplateSpecializationDecl *Specialization = nullptr;
 
   // Check whether we can declare a class template specialization in
   // the current scope.
@@ -5947,24 +6102,7 @@
 
   // The canonical type
   QualType CanonType;
-  if (PrevDecl &&
-      (PrevDecl->getSpecializationKind() == TSK_Undeclared ||
-               TUK == TUK_Friend)) {
-    // Since the only prior class template specialization with these
-    // arguments was referenced but not declared, or we're only
-    // referencing this specialization as a friend, reuse that
-    // declaration node as our own, updating its source location and
-    // the list of outer template parameters to reflect our new declaration.
-    Specialization = PrevDecl;
-    Specialization->setLocation(TemplateNameLoc);
-    if (TemplateParameterLists.size() > 0) {
-      Specialization->setTemplateParameterListsInfo(Context,
-                                              TemplateParameterLists.size(),
-                                              TemplateParameterLists.data());
-    }
-    PrevDecl = 0;
-    CanonType = Context.getTypeDeclType(Specialization);
-  } else if (isPartialSpecialization) {
+  if (isPartialSpecialization) {
     // Build the canonical type that describes the converted template
     // arguments of the class template partial specialization.
     TemplateName CanonTemplate = Context.getCanonicalTemplateName(Name);
@@ -5987,6 +6125,7 @@
                                 Attr,
                                 TemplateParams,
                                 AS_none, /*ModulePrivateLoc=*/SourceLocation(),
+                                /*FriendLoc*/SourceLocation(),
                                 TemplateParameterLists.size() - 1,
                                 TemplateParameterLists.data());
     }
@@ -6045,7 +6184,7 @@
           else
             Diag(Param->getLocation(),
                  diag::note_partial_spec_unused_parameter)
-              << "<anonymous>";
+              << "(anonymous)";
         }
       }
     }
@@ -6189,7 +6328,7 @@
 Decl *Sema::ActOnStartOfFunctionTemplateDef(Scope *FnBodyScope,
                                MultiTemplateParamsArg TemplateParameterLists,
                                             Declarator &D) {
-  assert(getCurFunctionDecl() == 0 && "Function parsing confused");
+  assert(getCurFunctionDecl() == nullptr && "Function parsing confused");
   DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
 
   if (FTI.hasPrototype) {
@@ -6212,10 +6351,8 @@
   if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
     FD->setInlineSpecified(false);
 
-    for (FunctionDecl::param_iterator I = FD->param_begin(),
-                                      E = FD->param_end();
-         I != E; ++I)
-      (*I)->dropAttrs();
+    for (auto I : FD->params())
+      I->dropAttrs();
   }
 }
 
@@ -6270,7 +6407,10 @@
   switch (NewTSK) {
   case TSK_Undeclared:
   case TSK_ImplicitInstantiation:
-    llvm_unreachable("Don't check implicit instantiations here");
+    assert(
+        (PrevTSK == TSK_Undeclared || PrevTSK == TSK_ImplicitInstantiation) &&
+        "previous declaration must be implicit!");
+    return false;
 
   case TSK_ExplicitSpecialization:
     switch (PrevTSK) {
@@ -6406,8 +6546,12 @@
       //   For a given template and a given set of template-arguments,
       //     - an explicit instantiation definition shall appear at most once
       //       in a program,
-      Diag(NewLoc, diag::err_explicit_instantiation_duplicate)
-        << PrevDecl;
+
+      // MSVCCompat: MSVC silently ignores duplicate explicit instantiations.
+      Diag(NewLoc, (getLangOpts().MSVCCompat)
+                       ? diag::ext_explicit_instantiation_duplicate
+                       : diag::err_explicit_instantiation_duplicate)
+          << PrevDecl;
       Diag(DiagLocForExplicitInstantiation(PrevDecl, PrevPointOfInstantiation),
            diag::note_previous_explicit_instantiation);
       HasNoEffect = true;
@@ -6501,31 +6645,18 @@
       // it will be a static member function until we know which template it
       // specializes), so adjust it now assuming it specializes this template.
       QualType FT = FD->getType();
-      const FunctionProtoType *FPT = FT->castAs<FunctionProtoType>();
-      FunctionDecl *TmplFD = FunTmpl->getTemplatedDecl();
       if (FD->isConstexpr()) {
-        CXXMethodDecl *OldMD = dyn_cast<CXXMethodDecl>(TmplFD);
+        CXXMethodDecl *OldMD =
+          dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
         if (OldMD && OldMD->isConst()) {
+          const FunctionProtoType *FPT = FT->castAs<FunctionProtoType>();
           FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
           EPI.TypeQuals |= Qualifiers::Const;
-          FT = Context.getFunctionType(FPT->getResultType(), FPT->getArgTypes(),
-                                       EPI);
+          FT = Context.getFunctionType(FPT->getReturnType(),
+                                       FPT->getParamTypes(), EPI);
         }
       }
 
-      // Ignore differences in calling convention and noreturn until decl
-      // merging.
-      const FunctionProtoType *TmplFT =
-          TmplFD->getType()->castAs<FunctionProtoType>();
-      if (FPT->getCallConv() != TmplFT->getCallConv() ||
-          FPT->getNoReturnAttr() != TmplFT->getNoReturnAttr()) {
-        FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
-        EPI.ExtInfo = EPI.ExtInfo.withCallingConv(TmplFT->getCallConv());
-        EPI.ExtInfo = EPI.ExtInfo.withNoReturn(TmplFT->getNoReturnAttr());
-        FT = Context.getFunctionType(FPT->getResultType(), FPT->getArgTypes(),
-                                     EPI);
-      }
-
       // C++ [temp.expl.spec]p11:
       //   A trailing template-argument can be left unspecified in the
       //   template-id naming an explicit function template specialization
@@ -6534,10 +6665,10 @@
       // specializing this template.
       // FIXME: It is somewhat wasteful to build
       TemplateDeductionInfo Info(FailedCandidates.getLocation());
-      FunctionDecl *Specialization = 0;
-      if (TemplateDeductionResult TDK
-            = DeduceTemplateArguments(FunTmpl, ExplicitTemplateArgs, FT,
-                                      Specialization, Info)) {
+      FunctionDecl *Specialization = nullptr;
+      if (TemplateDeductionResult TDK = DeduceTemplateArguments(
+              cast<FunctionTemplateDecl>(FunTmpl->getFirstDecl()),
+              ExplicitTemplateArgs, FT, Specialization, Info)) {
         // Template argument deduction failed; record why it failed, so
         // that we can provide nifty diagnostics.
         FailedCandidates.addCandidate()
@@ -6558,7 +6689,7 @@
       FD->getLocation(),
       PDiag(diag::err_function_template_spec_no_match) << FD->getDeclName(),
       PDiag(diag::err_function_template_spec_ambiguous)
-          << FD->getDeclName() << (ExplicitTemplateArgs != 0),
+          << FD->getDeclName() << (ExplicitTemplateArgs != nullptr),
       PDiag(diag::note_function_template_spec_matched));
 
   if (Result == Candidates.end())
@@ -6627,7 +6758,7 @@
   const TemplateArgumentList* TemplArgs = new (Context)
     TemplateArgumentList(Specialization->getTemplateSpecializationArgs());
   FD->setFunctionTemplateSpecialization(Specialization->getPrimaryTemplate(),
-                                        TemplArgs, /*InsertPos=*/0,
+                                        TemplArgs, /*InsertPos=*/nullptr,
                                     SpecInfo->getTemplateSpecializationKind(),
                                         ExplicitTemplateArgs);
 
@@ -6657,9 +6788,9 @@
   assert(!isa<TemplateDecl>(Member) && "Only for non-template members");
 
   // Try to find the member we are instantiating.
-  NamedDecl *Instantiation = 0;
-  NamedDecl *InstantiatedFrom = 0;
-  MemberSpecializationInfo *MSInfo = 0;
+  NamedDecl *Instantiation = nullptr;
+  NamedDecl *InstantiatedFrom = nullptr;
+  MemberSpecializationInfo *MSInfo = nullptr;
 
   if (Previous.empty()) {
     // Nowhere to look anyway.
@@ -6668,7 +6799,10 @@
            I != E; ++I) {
       NamedDecl *D = (*I)->getUnderlyingDecl();
       if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
-        if (Context.hasSameType(Function->getType(), Method->getType())) {
+        QualType Adjusted = Function->getType();
+        if (!hasExplicitCallingConv(Adjusted))
+          Adjusted = adjustCCAndNoReturn(Adjusted, Method->getType());
+        if (Context.hasSameType(Adjusted, Method->getType())) {
           Instantiation = Method;
           InstantiatedFrom = Method->getInstantiatedFromMemberFunction();
           MSInfo = Method->getMemberSpecializationInfo();
@@ -6889,8 +7023,8 @@
   //   name shall be a simple-template-id.
   //
   // C++98 has the same restriction, just worded differently.
-  for (NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
-       NNS; NNS = NNS->getPrefix())
+  for (NestedNameSpecifier *NNS = SS.getScopeRep(); NNS;
+       NNS = NNS->getPrefix())
     if (const Type *T = NNS->getAsType())
       if (isa<TemplateSpecializationType>(T))
         return true;
@@ -6963,10 +7097,9 @@
 
   // Find the class template specialization declaration that
   // corresponds to these arguments.
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
   ClassTemplateSpecializationDecl *PrevDecl
-    = ClassTemplate->findSpecialization(Converted.data(),
-                                        Converted.size(), InsertPos);
+    = ClassTemplate->findSpecialization(Converted, InsertPos);
 
   TemplateSpecializationKind PrevDecl_TSK
     = PrevDecl ? PrevDecl->getTemplateSpecializationKind() : TSK_Undeclared;
@@ -6980,7 +7113,7 @@
                                       SS.isSet()))
     return true;
 
-  ClassTemplateSpecializationDecl *Specialization = 0;
+  ClassTemplateSpecializationDecl *Specialization = nullptr;
 
   bool HasNoEffect = false;
   if (PrevDecl) {
@@ -7002,7 +7135,7 @@
       // (Other source locations will be updated later.)
       Specialization = PrevDecl;
       Specialization->setLocation(TemplateNameLoc);
-      PrevDecl = 0;
+      PrevDecl = nullptr;
     }
   }
 
@@ -7086,6 +7219,7 @@
     // TSK_ExplicitInstantiationDefinition
     if (Old_TSK == TSK_ExplicitInstantiationDeclaration &&
         TSK == TSK_ExplicitInstantiationDefinition)
+      // FIXME: Need to notify the ASTMutationListener that we did this.
       Def->setTemplateSpecializationKind(TSK);
 
     InstantiateClassTemplateSpecializationMembers(TemplateNameLoc, Def, TSK);
@@ -7114,7 +7248,8 @@
                         KWLoc, SS, Name, NameLoc, Attr, AS_none,
                         /*ModulePrivateLoc=*/SourceLocation(),
                         MultiTemplateParamsArg(), Owned, IsDependent,
-                        SourceLocation(), false, TypeResult());
+                        SourceLocation(), false, TypeResult(),
+                        /*IsTypeSpecifier*/false);
   assert(!IsDependent && "explicit instantiation of dependent name not yet handled");
 
   if (!TagD)
@@ -7354,13 +7489,8 @@
       }
 
       // Translate the parser's template argument list into our AST format.
-      TemplateArgumentListInfo TemplateArgs;
-      TemplateIdAnnotation *TemplateId = D.getName().TemplateId;
-      TemplateArgs.setLAngleLoc(TemplateId->LAngleLoc);
-      TemplateArgs.setRAngleLoc(TemplateId->RAngleLoc);
-      ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),
-                                         TemplateId->NumArgs);
-      translateTemplateArguments(TemplateArgsPtr, TemplateArgs);
+      TemplateArgumentListInfo TemplateArgs =
+          makeTemplateArgumentListInfo(*this, *D.getName().TemplateId);
 
       DeclResult Res = CheckVarTemplateId(PrevTemplate, TemplateLoc,
                                           D.getIdentifierLoc(), TemplateArgs);
@@ -7422,7 +7552,7 @@
     }
 
     // FIXME: Create an ExplicitInstantiation node?
-    return (Decl*) 0;
+    return (Decl*) nullptr;
   }
 
   // If the declarator is a template-id, translate the parser's template
@@ -7430,12 +7560,7 @@
   bool HasExplicitTemplateArgs = false;
   TemplateArgumentListInfo TemplateArgs;
   if (D.getName().getKind() == UnqualifiedId::IK_TemplateId) {
-    TemplateIdAnnotation *TemplateId = D.getName().TemplateId;
-    TemplateArgs.setLAngleLoc(TemplateId->LAngleLoc);
-    TemplateArgs.setRAngleLoc(TemplateId->RAngleLoc);
-    ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),
-                                       TemplateId->NumArgs);
-    translateTemplateArguments(TemplateArgsPtr, TemplateArgs);
+    TemplateArgs = makeTemplateArgumentListInfo(*this, *D.getName().TemplateId);
     HasExplicitTemplateArgs = true;
   }
 
@@ -7451,7 +7576,8 @@
     NamedDecl *Prev = *P;
     if (!HasExplicitTemplateArgs) {
       if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Prev)) {
-        if (Context.hasSameUnqualifiedType(Method->getType(), R)) {
+        QualType Adjusted = adjustCCAndNoReturn(R, Method->getType());
+        if (Context.hasSameUnqualifiedType(Method->getType(), Adjusted)) {
           Matches.clear();
 
           Matches.addDecl(Method, P.getAccess());
@@ -7466,10 +7592,11 @@
       continue;
 
     TemplateDeductionInfo Info(FailedCandidates.getLocation());
-    FunctionDecl *Specialization = 0;
+    FunctionDecl *Specialization = nullptr;
     if (TemplateDeductionResult TDK
           = DeduceTemplateArguments(FunTmpl,
-                               (HasExplicitTemplateArgs ? &TemplateArgs : 0),
+                               (HasExplicitTemplateArgs ? &TemplateArgs
+                                                        : nullptr),
                                     R, Specialization, Info)) {
       // Keep track of almost-matches.
       FailedCandidates.addCandidate()
@@ -7522,7 +7649,7 @@
     // FIXME: We may still want to build some representation of this
     // explicit specialization.
     if (HasNoEffect)
-      return (Decl*) 0;
+      return (Decl*) nullptr;
   }
 
   Specialization->setTemplateSpecializationKind(TSK, D.getIdentifierLoc());
@@ -7530,7 +7657,11 @@
   if (Attr)
     ProcessDeclAttributeList(S, Specialization, Attr);
 
-  if (TSK == TSK_ExplicitInstantiationDefinition)
+  if (Specialization->isDefined()) {
+    // Let the ASTConsumer know that this function has been explicitly
+    // instantiated now, and its linkage might have changed.
+    Consumer.HandleTopLevelDecl(DeclGroupRef(Specialization));
+  } else if (TSK == TSK_ExplicitInstantiationDefinition)
     InstantiateFunctionDefinition(D.getIdentifierLoc(), Specialization);
 
   // C++0x [temp.explicit]p2:
@@ -7555,7 +7686,7 @@
                                   D.getCXXScopeSpec().isSet());
 
   // FIXME: Create some kind of ExplicitInstantiationDecl here.
-  return (Decl*) 0;
+  return (Decl*) nullptr;
 }
 
 TypeResult
@@ -7565,8 +7696,7 @@
   // This has to hold, because SS is expected to be defined.
   assert(Name && "Expected a name in a dependent tag");
 
-  NestedNameSpecifier *NNS
-    = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
+  NestedNameSpecifier *NNS = SS.getScopeRep();
   if (!NNS)
     return true;
 
@@ -7652,8 +7782,7 @@
   if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) {
     // Construct a dependent template specialization type.
     assert(DTN && "dependent template has non-dependent name?");
-    assert(DTN->getQualifier()
-           == static_cast<NestedNameSpecifier*>(SS.getScopeRep()));
+    assert(DTN->getQualifier() == SS.getScopeRep());
     QualType T = Context.getDependentTemplateSpecializationType(ETK_Typename,
                                                           DTN->getQualifier(),
                                                           DTN->getIdentifier(),
@@ -7769,7 +7898,7 @@
   LookupResult Result(*this, Name, IILoc, LookupOrdinaryName);
   LookupQualifiedName(Result, Ctx);
   unsigned DiagID = 0;
-  Decl *Referenced = 0;
+  Decl *Referenced = nullptr;
   switch (Result.getResultKind()) {
   case LookupResult::NotFound: {
     // If we're looking up 'type' within a template named 'enable_if', produce
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index b401db2..53a75d2 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -126,7 +126,7 @@
                                    unsigned TDF,
                                    bool PartialOrdering = false,
                             SmallVectorImpl<RefParamPartialOrderingComparison> *
-                                                      RefParamComparisons = 0);
+                                                 RefParamComparisons = nullptr);
 
 static Sema::TemplateDeductionResult
 DeduceTemplateArguments(Sema &S,
@@ -155,7 +155,7 @@
   if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
     return dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl());
 
-  return 0;
+  return nullptr;
 }
 
 /// \brief Determine whether two declaration pointers refer to the same
@@ -297,6 +297,7 @@
                                       XAEnd = X.pack_end(),
                                          YA = Y.pack_begin();
          XA != XAEnd; ++XA, ++YA) {
+      // FIXME: Do we need to merge the results together here?
       if (checkDeducedTemplateArguments(Context,
                     DeducedTemplateArgument(*XA, X.wasDeducedFromArrayBound()),
                     DeducedTemplateArgument(*YA, Y.wasDeducedFromArrayBound()))
@@ -382,7 +383,7 @@
   assert(NTTP->getDepth() == 0 &&
          "Cannot deduce non-type template argument with depth > 0");
 
-  D = D ? cast<ValueDecl>(D->getCanonicalDecl()) : 0;
+  D = D ? cast<ValueDecl>(D->getCanonicalDecl()) : nullptr;
   TemplateArgument New(D, NTTP->getType()->isReferenceType());
   DeducedTemplateArgument NewDeduced(New);
   DeducedTemplateArgument Result = checkDeducedTemplateArguments(S.Context,
@@ -581,96 +582,181 @@
   return TemplateParameter(cast<TemplateTemplateParmDecl>(D));
 }
 
-typedef SmallVector<SmallVector<DeducedTemplateArgument, 4>, 2>
-  NewlyDeducedPacksType;
+/// A pack that we're currently deducing.
+struct clang::DeducedPack {
+  DeducedPack(unsigned Index) : Index(Index), Outer(nullptr) {}
 
-/// \brief Prepare to perform template argument deduction for all of the
-/// arguments in a set of argument packs.
-static void
-PrepareArgumentPackDeduction(Sema &S,
-                           SmallVectorImpl<DeducedTemplateArgument> &Deduced,
-                           ArrayRef<unsigned> PackIndices,
-                           SmallVectorImpl<DeducedTemplateArgument> &SavedPacks,
-                           NewlyDeducedPacksType &NewlyDeducedPacks) {
-  // Save the deduced template arguments for each parameter pack expanded
-  // by this pack expansion, then clear out the deduction.
-  for (unsigned I = 0, N = PackIndices.size(); I != N; ++I) {
-    // Save the previously-deduced argument pack, then clear it out so that we
-    // can deduce a new argument pack.
-    SavedPacks[I] = Deduced[PackIndices[I]];
-    Deduced[PackIndices[I]] = TemplateArgument();
+  // The index of the pack.
+  unsigned Index;
 
-    if (!S.CurrentInstantiationScope)
-      continue;
+  // The old value of the pack before we started deducing it.
+  DeducedTemplateArgument Saved;
 
-    // If the template argument pack was explicitly specified, add that to
-    // the set of deduced arguments.
-    const TemplateArgument *ExplicitArgs;
-    unsigned NumExplicitArgs;
-    if (NamedDecl *PartiallySubstitutedPack
-        = S.CurrentInstantiationScope->getPartiallySubstitutedPack(
-                                                           &ExplicitArgs,
-                                                           &NumExplicitArgs)) {
-      if (getDepthAndIndex(PartiallySubstitutedPack).second == PackIndices[I])
-        NewlyDeducedPacks[I].append(ExplicitArgs,
-                                    ExplicitArgs + NumExplicitArgs);
+  // A deferred value of this pack from an inner deduction, that couldn't be
+  // deduced because this deduction hadn't happened yet.
+  DeducedTemplateArgument DeferredDeduction;
+
+  // The new value of the pack.
+  SmallVector<DeducedTemplateArgument, 4> New;
+
+  // The outer deduction for this pack, if any.
+  DeducedPack *Outer;
+};
+
+/// A scope in which we're performing pack deduction.
+class PackDeductionScope {
+public:
+  PackDeductionScope(Sema &S, TemplateParameterList *TemplateParams,
+                     SmallVectorImpl<DeducedTemplateArgument> &Deduced,
+                     TemplateDeductionInfo &Info, TemplateArgument Pattern)
+      : S(S), TemplateParams(TemplateParams), Deduced(Deduced), Info(Info) {
+    // Compute the set of template parameter indices that correspond to
+    // parameter packs expanded by the pack expansion.
+    {
+      llvm::SmallBitVector SawIndices(TemplateParams->size());
+      SmallVector<UnexpandedParameterPack, 2> Unexpanded;
+      S.collectUnexpandedParameterPacks(Pattern, Unexpanded);
+      for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
+        unsigned Depth, Index;
+        std::tie(Depth, Index) = getDepthAndIndex(Unexpanded[I]);
+        if (Depth == 0 && !SawIndices[Index]) {
+          SawIndices[Index] = true;
+
+          // Save the deduced template argument for the parameter pack expanded
+          // by this pack expansion, then clear out the deduction.
+          DeducedPack Pack(Index);
+          Pack.Saved = Deduced[Index];
+          Deduced[Index] = TemplateArgument();
+
+          Packs.push_back(Pack);
+        }
+      }
+    }
+    assert(!Packs.empty() && "Pack expansion without unexpanded packs?");
+
+    for (auto &Pack : Packs) {
+      if (Info.PendingDeducedPacks.size() > Pack.Index)
+        Pack.Outer = Info.PendingDeducedPacks[Pack.Index];
+      else
+        Info.PendingDeducedPacks.resize(Pack.Index + 1);
+      Info.PendingDeducedPacks[Pack.Index] = &Pack;
+
+      if (S.CurrentInstantiationScope) {
+        // If the template argument pack was explicitly specified, add that to
+        // the set of deduced arguments.
+        const TemplateArgument *ExplicitArgs;
+        unsigned NumExplicitArgs;
+        NamedDecl *PartiallySubstitutedPack =
+            S.CurrentInstantiationScope->getPartiallySubstitutedPack(
+                &ExplicitArgs, &NumExplicitArgs);
+        if (PartiallySubstitutedPack &&
+            getDepthAndIndex(PartiallySubstitutedPack).second == Pack.Index)
+          Pack.New.append(ExplicitArgs, ExplicitArgs + NumExplicitArgs);
+      }
     }
   }
-}
 
-/// \brief Finish template argument deduction for a set of argument packs,
-/// producing the argument packs and checking for consistency with prior
-/// deductions.
-static Sema::TemplateDeductionResult
-FinishArgumentPackDeduction(Sema &S,
-                           TemplateParameterList *TemplateParams,
-                           bool HasAnyArguments,
-                           SmallVectorImpl<DeducedTemplateArgument> &Deduced,
-                           ArrayRef<unsigned> PackIndices,
-                           SmallVectorImpl<DeducedTemplateArgument> &SavedPacks,
-                           NewlyDeducedPacksType &NewlyDeducedPacks,
-                           TemplateDeductionInfo &Info) {
-  // Build argument packs for each of the parameter packs expanded by this
-  // pack expansion.
-  for (unsigned I = 0, N = PackIndices.size(); I != N; ++I) {
-    if (HasAnyArguments && NewlyDeducedPacks[I].empty()) {
-      // We were not able to deduce anything for this parameter pack,
-      // so just restore the saved argument pack.
-      Deduced[PackIndices[I]] = SavedPacks[I];
-      continue;
-    }
-
-    DeducedTemplateArgument NewPack;
-
-    if (NewlyDeducedPacks[I].empty()) {
-      // If we deduced an empty argument pack, create it now.
-      NewPack = DeducedTemplateArgument(TemplateArgument::getEmptyPack());
-    } else {
-      TemplateArgument *ArgumentPack
-        = new (S.Context) TemplateArgument [NewlyDeducedPacks[I].size()];
-      std::copy(NewlyDeducedPacks[I].begin(), NewlyDeducedPacks[I].end(),
-                ArgumentPack);
-      NewPack
-        = DeducedTemplateArgument(TemplateArgument(ArgumentPack,
-                                                   NewlyDeducedPacks[I].size()),
-                            NewlyDeducedPacks[I][0].wasDeducedFromArrayBound());
-    }
-
-    DeducedTemplateArgument Result
-      = checkDeducedTemplateArguments(S.Context, SavedPacks[I], NewPack);
-    if (Result.isNull()) {
-      Info.Param
-        = makeTemplateParameter(TemplateParams->getParam(PackIndices[I]));
-      Info.FirstArg = SavedPacks[I];
-      Info.SecondArg = NewPack;
-      return Sema::TDK_Inconsistent;
-    }
-
-    Deduced[PackIndices[I]] = Result;
+  ~PackDeductionScope() {
+    for (auto &Pack : Packs)
+      Info.PendingDeducedPacks[Pack.Index] = Pack.Outer;
   }
 
-  return Sema::TDK_Success;
-}
+  /// Move to deducing the next element in each pack that is being deduced.
+  void nextPackElement() {
+    // Capture the deduced template arguments for each parameter pack expanded
+    // by this pack expansion, add them to the list of arguments we've deduced
+    // for that pack, then clear out the deduced argument.
+    for (auto &Pack : Packs) {
+      DeducedTemplateArgument &DeducedArg = Deduced[Pack.Index];
+      if (!DeducedArg.isNull()) {
+        Pack.New.push_back(DeducedArg);
+        DeducedArg = DeducedTemplateArgument();
+      }
+    }
+  }
+
+  /// \brief Finish template argument deduction for a set of argument packs,
+  /// producing the argument packs and checking for consistency with prior
+  /// deductions.
+  Sema::TemplateDeductionResult finish(bool HasAnyArguments) {
+    // Build argument packs for each of the parameter packs expanded by this
+    // pack expansion.
+    for (auto &Pack : Packs) {
+      // Put back the old value for this pack.
+      Deduced[Pack.Index] = Pack.Saved;
+
+      // Build or find a new value for this pack.
+      DeducedTemplateArgument NewPack;
+      if (HasAnyArguments && Pack.New.empty()) {
+        if (Pack.DeferredDeduction.isNull()) {
+          // We were not able to deduce anything for this parameter pack
+          // (because it only appeared in non-deduced contexts), so just
+          // restore the saved argument pack.
+          continue;
+        }
+
+        NewPack = Pack.DeferredDeduction;
+        Pack.DeferredDeduction = TemplateArgument();
+      } else if (Pack.New.empty()) {
+        // If we deduced an empty argument pack, create it now.
+        NewPack = DeducedTemplateArgument(TemplateArgument::getEmptyPack());
+      } else {
+        TemplateArgument *ArgumentPack =
+            new (S.Context) TemplateArgument[Pack.New.size()];
+        std::copy(Pack.New.begin(), Pack.New.end(), ArgumentPack);
+        NewPack = DeducedTemplateArgument(
+            TemplateArgument(ArgumentPack, Pack.New.size()),
+            Pack.New[0].wasDeducedFromArrayBound());
+      }
+
+      // Pick where we're going to put the merged pack.
+      DeducedTemplateArgument *Loc;
+      if (Pack.Outer) {
+        if (Pack.Outer->DeferredDeduction.isNull()) {
+          // Defer checking this pack until we have a complete pack to compare
+          // it against.
+          Pack.Outer->DeferredDeduction = NewPack;
+          continue;
+        }
+        Loc = &Pack.Outer->DeferredDeduction;
+      } else {
+        Loc = &Deduced[Pack.Index];
+      }
+
+      // Check the new pack matches any previous value.
+      DeducedTemplateArgument OldPack = *Loc;
+      DeducedTemplateArgument Result =
+          checkDeducedTemplateArguments(S.Context, OldPack, NewPack);
+
+      // If we deferred a deduction of this pack, check that one now too.
+      if (!Result.isNull() && !Pack.DeferredDeduction.isNull()) {
+        OldPack = Result;
+        NewPack = Pack.DeferredDeduction;
+        Result = checkDeducedTemplateArguments(S.Context, OldPack, NewPack);
+      }
+
+      if (Result.isNull()) {
+        Info.Param =
+            makeTemplateParameter(TemplateParams->getParam(Pack.Index));
+        Info.FirstArg = OldPack;
+        Info.SecondArg = NewPack;
+        return Sema::TDK_Inconsistent;
+      }
+
+      *Loc = Result;
+    }
+
+    return Sema::TDK_Success;
+  }
+
+private:
+  Sema &S;
+  TemplateParameterList *TemplateParams;
+  SmallVectorImpl<DeducedTemplateArgument> &Deduced;
+  TemplateDeductionInfo &Info;
+
+  SmallVector<DeducedPack, 2> Packs;
+};
 
 /// \brief Deduce the template arguments by comparing the list of parameter
 /// types to the list of argument types, as in the parameter-type-lists of
@@ -715,7 +801,7 @@
                         unsigned TDF,
                         bool PartialOrdering = false,
                         SmallVectorImpl<RefParamPartialOrderingComparison> *
-                                                     RefParamComparisons = 0) {
+                                                RefParamComparisons = nullptr) {
   // Fast-path check to see if we have too many/too few arguments.
   if (NumParams != NumArgs &&
       !(NumParams && isa<PackExpansionType>(Params[NumParams - 1])) &&
@@ -773,33 +859,8 @@
     //   comparison deduces template arguments for subsequent positions in the
     //   template parameter packs expanded by the function parameter pack.
 
-    // Compute the set of template parameter indices that correspond to
-    // parameter packs expanded by the pack expansion.
-    SmallVector<unsigned, 2> PackIndices;
     QualType Pattern = Expansion->getPattern();
-    {
-      llvm::SmallBitVector SawIndices(TemplateParams->size());
-      SmallVector<UnexpandedParameterPack, 2> Unexpanded;
-      S.collectUnexpandedParameterPacks(Pattern, Unexpanded);
-      for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
-        unsigned Depth, Index;
-        llvm::tie(Depth, Index) = getDepthAndIndex(Unexpanded[I]);
-        if (Depth == 0 && !SawIndices[Index]) {
-          SawIndices[Index] = true;
-          PackIndices.push_back(Index);
-        }
-      }
-    }
-    assert(!PackIndices.empty() && "Pack expansion without unexpanded packs?");
-
-    // Keep track of the deduced template arguments for each parameter pack
-    // expanded by this pack expansion (the outer index) and for each
-    // template argument (the inner SmallVectors).
-    NewlyDeducedPacksType NewlyDeducedPacks(PackIndices.size());
-    SmallVector<DeducedTemplateArgument, 2>
-      SavedPacks(PackIndices.size());
-    PrepareArgumentPackDeduction(S, Deduced, PackIndices, SavedPacks,
-                                 NewlyDeducedPacks);
+    PackDeductionScope PackScope(S, TemplateParams, Deduced, Info, Pattern);
 
     bool HasAnyArguments = false;
     for (; ArgIdx < NumArgs; ++ArgIdx) {
@@ -813,24 +874,12 @@
                                                  RefParamComparisons))
         return Result;
 
-      // Capture the deduced template arguments for each parameter pack expanded
-      // by this pack expansion, add them to the list of arguments we've deduced
-      // for that pack, then clear out the deduced argument.
-      for (unsigned I = 0, N = PackIndices.size(); I != N; ++I) {
-        DeducedTemplateArgument &DeducedArg = Deduced[PackIndices[I]];
-        if (!DeducedArg.isNull()) {
-          NewlyDeducedPacks[I].push_back(DeducedArg);
-          DeducedArg = DeducedTemplateArgument();
-        }
-      }
+      PackScope.nextPackElement();
     }
 
     // Build argument packs for each of the parameter packs expanded by this
     // pack expansion.
-    if (Sema::TemplateDeductionResult Result
-          = FinishArgumentPackDeduction(S, TemplateParams, HasAnyArguments,
-                                        Deduced, PackIndices, SavedPacks,
-                                        NewlyDeducedPacks, Info))
+    if (auto Result = PackScope.finish(HasAnyArguments))
       return Result;
   }
 
@@ -981,6 +1030,17 @@
         Comparison.Qualifiers = ParamMoreQualified;
       else if (ArgQuals.isStrictSupersetOf(ParamQuals))
         Comparison.Qualifiers = ArgMoreQualified;
+      else if (ArgQuals.getObjCLifetime() != ParamQuals.getObjCLifetime() &&
+               ArgQuals.withoutObjCLifetime()
+                 == ParamQuals.withoutObjCLifetime()) {
+        // Prefer binding to non-__unsafe_autoretained parameters.
+        if (ArgQuals.getObjCLifetime() == Qualifiers::OCL_ExplicitNone &&
+            ParamQuals.getObjCLifetime())
+          Comparison.Qualifiers = ParamMoreQualified;
+        else if (ParamQuals.getObjCLifetime() == Qualifiers::OCL_ExplicitNone &&
+                 ArgQuals.getObjCLifetime())
+          Comparison.Qualifiers = ArgMoreQualified;
+      }
       RefParamComparisons->push_back(Comparison);
     }
 
@@ -1364,19 +1424,17 @@
         return Sema::TDK_NonDeducedMismatch;
 
       // Check return types.
-      if (Sema::TemplateDeductionResult Result
-            = DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
-                                            FunctionProtoParam->getResultType(),
-                                            FunctionProtoArg->getResultType(),
-                                            Info, Deduced, 0))
+      if (Sema::TemplateDeductionResult Result =
+              DeduceTemplateArgumentsByTypeMatch(
+                  S, TemplateParams, FunctionProtoParam->getReturnType(),
+                  FunctionProtoArg->getReturnType(), Info, Deduced, 0))
         return Result;
 
-      return DeduceTemplateArguments(S, TemplateParams,
-                                     FunctionProtoParam->arg_type_begin(),
-                                     FunctionProtoParam->getNumArgs(),
-                                     FunctionProtoArg->arg_type_begin(),
-                                     FunctionProtoArg->getNumArgs(),
-                                     Info, Deduced, SubTDF);
+      return DeduceTemplateArguments(
+          S, TemplateParams, FunctionProtoParam->param_type_begin(),
+          FunctionProtoParam->getNumParams(),
+          FunctionProtoArg->param_type_begin(),
+          FunctionProtoArg->getNumParams(), Info, Deduced, SubTDF);
     }
 
     case Type::InjectedClassName: {
@@ -1463,12 +1521,10 @@
 
             // Visit base classes
             CXXRecordDecl *Next = cast<CXXRecordDecl>(NextT->getDecl());
-            for (CXXRecordDecl::base_class_iterator Base = Next->bases_begin(),
-                                                 BaseEnd = Next->bases_end();
-                 Base != BaseEnd; ++Base) {
-              assert(Base->getType()->isRecordType() &&
+            for (const auto &Base : Next->bases()) {
+              assert(Base.getType()->isRecordType() &&
                      "Base class that isn't a record?");
-              ToVisit.push_back(Base->getType()->getAs<RecordType>());
+              ToVisit.push_back(Base.getType()->getAs<RecordType>());
             }
           }
 
@@ -1845,41 +1901,18 @@
     //   template parameter packs expanded by Pi.
     TemplateArgument Pattern = Params[ParamIdx].getPackExpansionPattern();
 
-    // Compute the set of template parameter indices that correspond to
-    // parameter packs expanded by the pack expansion.
-    SmallVector<unsigned, 2> PackIndices;
-    {
-      llvm::SmallBitVector SawIndices(TemplateParams->size());
-      SmallVector<UnexpandedParameterPack, 2> Unexpanded;
-      S.collectUnexpandedParameterPacks(Pattern, Unexpanded);
-      for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
-        unsigned Depth, Index;
-        llvm::tie(Depth, Index) = getDepthAndIndex(Unexpanded[I]);
-        if (Depth == 0 && !SawIndices[Index]) {
-          SawIndices[Index] = true;
-          PackIndices.push_back(Index);
-        }
-      }
-    }
-    assert(!PackIndices.empty() && "Pack expansion without unexpanded packs?");
-
     // FIXME: If there are no remaining arguments, we can bail out early
     // and set any deduced parameter packs to an empty argument pack.
     // The latter part of this is a (minor) correctness issue.
 
-    // Save the deduced template arguments for each parameter pack expanded
-    // by this pack expansion, then clear out the deduction.
-    SmallVector<DeducedTemplateArgument, 2>
-      SavedPacks(PackIndices.size());
-    NewlyDeducedPacksType NewlyDeducedPacks(PackIndices.size());
-    PrepareArgumentPackDeduction(S, Deduced, PackIndices, SavedPacks,
-                                 NewlyDeducedPacks);
+    // Prepare to deduce the packs within the pattern.
+    PackDeductionScope PackScope(S, TemplateParams, Deduced, Info, Pattern);
 
     // Keep track of the deduced template arguments for each parameter pack
     // expanded by this pack expansion (the outer index) and for each
     // template argument (the inner SmallVectors).
     bool HasAnyArguments = false;
-    while (hasTemplateArgumentForDeduction(Args, ArgIdx, NumArgs)) {
+    for (; hasTemplateArgumentForDeduction(Args, ArgIdx, NumArgs); ++ArgIdx) {
       HasAnyArguments = true;
 
       // Deduce template arguments from the pattern.
@@ -1888,26 +1921,12 @@
                                       Info, Deduced))
         return Result;
 
-      // Capture the deduced template arguments for each parameter pack expanded
-      // by this pack expansion, add them to the list of arguments we've deduced
-      // for that pack, then clear out the deduced argument.
-      for (unsigned I = 0, N = PackIndices.size(); I != N; ++I) {
-        DeducedTemplateArgument &DeducedArg = Deduced[PackIndices[I]];
-        if (!DeducedArg.isNull()) {
-          NewlyDeducedPacks[I].push_back(DeducedArg);
-          DeducedArg = DeducedTemplateArgument();
-        }
-      }
-
-      ++ArgIdx;
+      PackScope.nextPackElement();
     }
 
     // Build argument packs for each of the parameter packs expanded by this
     // pack expansion.
-    if (Sema::TemplateDeductionResult Result
-          = FinishArgumentPackDeduction(S, TemplateParams, HasAnyArguments,
-                                        Deduced, PackIndices, SavedPacks,
-                                        NewlyDeducedPacks, Info))
+    if (auto Result = PackScope.finish(HasAnyArguments))
       return Result;
   }
 
@@ -2013,21 +2032,21 @@
   case TemplateArgument::Declaration: {
     Expr *E
       = S.BuildExpressionFromDeclTemplateArgument(Arg, NTTPType, Loc)
-          .takeAs<Expr>();
+          .getAs<Expr>();
     return TemplateArgumentLoc(TemplateArgument(E), E);
   }
 
   case TemplateArgument::NullPtr: {
     Expr *E
       = S.BuildExpressionFromDeclTemplateArgument(Arg, NTTPType, Loc)
-          .takeAs<Expr>();
+          .getAs<Expr>();
     return TemplateArgumentLoc(TemplateArgument(NTTPType, /*isNullPtr*/true),
                                E);
   }
 
   case TemplateArgument::Integral: {
     Expr *E
-      = S.BuildExpressionFromIntegralTemplateArgument(Arg, Loc).takeAs<Expr>();
+      = S.BuildExpressionFromIntegralTemplateArgument(Arg, Loc).getAs<Expr>();
     return TemplateArgumentLoc(TemplateArgument(E), E);
   }
 
@@ -2076,13 +2095,11 @@
     // This is a template argument pack, so check each of its arguments against
     // the template parameter.
     SmallVector<TemplateArgument, 2> PackedArgsBuilder;
-    for (TemplateArgument::pack_iterator PA = Arg.pack_begin(),
-                                      PAEnd = Arg.pack_end();
-         PA != PAEnd; ++PA) {
+    for (const auto &P : Arg.pack_elements()) {
       // When converting the deduced template argument, append it to the
       // general output list. We need to do this so that the template argument
       // checking logic has all of the prior template arguments available.
-      DeducedTemplateArgument InnerArg(*PA);
+      DeducedTemplateArgument InnerArg(P);
       InnerArg.setDeducedFromArrayBound(Arg.wasDeducedFromArrayBound());
       if (ConvertDeducedTemplateArgument(S, Param, InnerArg, Template,
                                          NTTPType, PackedArgsBuilder.size(),
@@ -2274,8 +2291,8 @@
     return Result;
 
   SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(), Deduced.end());
-  InstantiatingTemplate Inst(*this, Partial->getLocation(), Partial,
-                             DeducedArgs, Info);
+  InstantiatingTemplate Inst(*this, Info.getLocation(), Partial, DeducedArgs,
+                             Info);
   if (Inst.isInvalid())
     return TDK_InstantiationDepth;
 
@@ -2438,8 +2455,8 @@
     return Result;
 
   SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(), Deduced.end());
-  InstantiatingTemplate Inst(*this, Partial->getLocation(), Partial,
-                             DeducedArgs, Info);
+  InstantiatingTemplate Inst(*this, Info.getLocation(), Partial, DeducedArgs,
+                             Info);
   if (Inst.isInvalid())
     return TDK_InstantiationDepth;
 
@@ -2454,7 +2471,7 @@
 static bool isSimpleTemplateIdType(QualType T) {
   if (const TemplateSpecializationType *Spec
         = T->getAs<TemplateSpecializationType>())
-    return Spec->getTemplateName().getAsTemplateDecl() != 0;
+    return Spec->getTemplateName().getAsTemplateDecl() != nullptr;
 
   return false;
 }
@@ -2498,11 +2515,8 @@
   if (ExplicitTemplateArgs.size() == 0) {
     // No arguments to substitute; just copy over the parameter types and
     // fill in the function type.
-    for (FunctionDecl::param_iterator P = Function->param_begin(),
-                                   PEnd = Function->param_end();
-         P != PEnd;
-         ++P)
-      ParamTypes.push_back((*P)->getType());
+    for (auto P : Function->params())
+      ParamTypes.push_back(P->getType());
 
     if (FunctionType)
       *FunctionType = Function->getType();
@@ -2524,8 +2538,8 @@
   // 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, FunctionTemplate->getLocation(),
-                             FunctionTemplate, DeducedArgs,
+  InstantiatingTemplate Inst(*this, Info.getLocation(), FunctionTemplate,
+                             DeducedArgs,
            ActiveTemplateInstantiation::ExplicitTemplateArgumentSubstitution,
                              Info);
   if (Inst.isInvalid())
@@ -2596,7 +2610,7 @@
     //   and the end of the function-definition, member-declarator, or 
     //   declarator.
     unsigned ThisTypeQuals = 0;
-    CXXRecordDecl *ThisContext = 0;
+    CXXRecordDecl *ThisContext = nullptr;
     if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Function)) {
       ThisContext = Method->getParent();
       ThisTypeQuals = Method->getTypeQualifiers();
@@ -2604,11 +2618,11 @@
       
     CXXThisScopeRAII ThisScope(*this, ThisContext, ThisTypeQuals,
                                getLangOpts().CPlusPlus11);
-    
-    ResultType = SubstType(Proto->getResultType(),
-                   MultiLevelTemplateArgumentList(*ExplicitArgumentList),
-                   Function->getTypeSpecStartLoc(),
-                   Function->getDeclName());
+
+    ResultType =
+        SubstType(Proto->getReturnType(),
+                  MultiLevelTemplateArgumentList(*ExplicitArgumentList),
+                  Function->getTypeSpecStartLoc(), Function->getDeclName());
     if (ResultType.isNull() || Trap.hasErrorOccurred())
       return TDK_SubstitutionFailure;
   }
@@ -2778,8 +2792,8 @@
   // Enter a new template instantiation context while we instantiate the
   // actual function declaration.
   SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(), Deduced.end());
-  InstantiatingTemplate Inst(*this, FunctionTemplate->getLocation(),
-                             FunctionTemplate, DeducedArgs,
+  InstantiatingTemplate Inst(*this, Info.getLocation(), FunctionTemplate,
+                             DeducedArgs,
               ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution,
                              Info);
   if (Inst.isInvalid())
@@ -2800,9 +2814,19 @@
         // argument, because it was explicitly-specified. Just record the
         // presence of this argument.
         Builder.push_back(Deduced[I]);
+        // We may have had explicitly-specified template arguments for a
+        // template parameter pack (that may or may not have been extended
+        // via additional deduced arguments).
+        if (Param->isParameterPack() && CurrentInstantiationScope) {
+          if (CurrentInstantiationScope->getPartiallySubstitutedPack() ==
+              Param) {
+            // Forget the partially-substituted pack; its substitution is now
+            // complete.
+            CurrentInstantiationScope->ResetPartiallySubstitutedPack();
+          }
+        }
         continue;
       }
-
       // We have deduced this argument, so it still needs to be
       // checked and converted.
 
@@ -2976,8 +3000,8 @@
 static QualType GetTypeOfFunction(Sema &S, const OverloadExpr::FindResult &R,
                                   FunctionDecl *Fn) {
   // We may need to deduce the return type of the function now.
-  if (S.getLangOpts().CPlusPlus1y && Fn->getResultType()->isUndeducedType() &&
-      S.DeduceReturnType(Fn, R.Expression->getExprLoc(), /*Diagnose*/false))
+  if (S.getLangOpts().CPlusPlus1y && Fn->getReturnType()->isUndeducedType() &&
+      S.DeduceReturnType(Fn, R.Expression->getExprLoc(), /*Diagnose*/ false))
     return QualType();
 
   if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Fn))
@@ -3048,7 +3072,7 @@
         return QualType();
       
       // Otherwise, see if we can resolve a function type 
-      FunctionDecl *Specialization = 0;
+      FunctionDecl *Specialization = nullptr;
       TemplateDeductionInfo Info(Ovl->getNameLoc());
       if (S.DeduceTemplateArguments(FunTmpl, &ExplicitTemplateArgs,
                                     Specialization, Info))
@@ -3140,7 +3164,7 @@
   if (ArgType == S.Context.OverloadTy) {
     ArgType = ResolveOverloadForDeduction(S, TemplateParams,
                                           Arg, ParamType,
-                                          ParamRefType != 0);
+                                          ParamRefType != nullptr);
     if (ArgType.isNull())
       return true;
   }
@@ -3309,7 +3333,7 @@
                                           *ExplicitTemplateArgs,
                                           Deduced,
                                           ParamTypes,
-                                          0,
+                                          nullptr,
                                           Info);
     if (Result)
       return Result;
@@ -3399,30 +3423,9 @@
       break;
 
     QualType ParamPattern = ParamExpansion->getPattern();
-    SmallVector<unsigned, 2> PackIndices;
-    {
-      llvm::SmallBitVector SawIndices(TemplateParams->size());
-      SmallVector<UnexpandedParameterPack, 2> Unexpanded;
-      collectUnexpandedParameterPacks(ParamPattern, Unexpanded);
-      for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
-        unsigned Depth, Index;
-        llvm::tie(Depth, Index) = getDepthAndIndex(Unexpanded[I]);
-        if (Depth == 0 && !SawIndices[Index]) {
-          SawIndices[Index] = true;
-          PackIndices.push_back(Index);
-        }
-      }
-    }
-    assert(!PackIndices.empty() && "Pack expansion without unexpanded packs?");
+    PackDeductionScope PackScope(*this, TemplateParams, Deduced, Info,
+                                 ParamPattern);
 
-    // Keep track of the deduced template arguments for each parameter pack
-    // expanded by this pack expansion (the outer index) and for each
-    // template argument (the inner SmallVectors).
-    NewlyDeducedPacksType NewlyDeducedPacks(PackIndices.size());
-    SmallVector<DeducedTemplateArgument, 2>
-      SavedPacks(PackIndices.size());
-    PrepareArgumentPackDeduction(*this, Deduced, PackIndices, SavedPacks,
-                                 NewlyDeducedPacks);
     bool HasAnyArguments = false;
     for (; ArgIdx < Args.size(); ++ArgIdx) {
       HasAnyArguments = true;
@@ -3431,7 +3434,7 @@
       ParamType = OrigParamType;
       Expr *Arg = Args[ArgIdx];
       QualType ArgType = Arg->getType();
-      
+
       unsigned TDF = 0;
       if (AdjustFunctionParmAndArgTypesForDeduction(*this, TemplateParams,
                                                     ParamType, ArgType, Arg,
@@ -3472,24 +3475,12 @@
           return Result;
       }
 
-      // Capture the deduced template arguments for each parameter pack expanded
-      // by this pack expansion, add them to the list of arguments we've deduced
-      // for that pack, then clear out the deduced argument.
-      for (unsigned I = 0, N = PackIndices.size(); I != N; ++I) {
-        DeducedTemplateArgument &DeducedArg = Deduced[PackIndices[I]];
-        if (!DeducedArg.isNull()) {
-          NewlyDeducedPacks[I].push_back(DeducedArg);
-          DeducedArg = DeducedTemplateArgument();
-        }
-      }
+      PackScope.nextPackElement();
     }
 
     // Build argument packs for each of the parameter packs expanded by this
     // pack expansion.
-    if (Sema::TemplateDeductionResult Result
-          = FinishArgumentPackDeduction(*this, TemplateParams, HasAnyArguments,
-                                        Deduced, PackIndices, SavedPacks,
-                                        NewlyDeducedPacks, Info))
+    if (auto Result = PackScope.finish(HasAnyArguments))
       return Result;
 
     // After we've matching against a parameter pack, we're done.
@@ -3501,6 +3492,28 @@
                                          Specialization, Info, &OriginalCallArgs);
 }
 
+QualType Sema::adjustCCAndNoReturn(QualType ArgFunctionType,
+                                   QualType FunctionType) {
+  if (ArgFunctionType.isNull())
+    return ArgFunctionType;
+
+  const FunctionProtoType *FunctionTypeP =
+      FunctionType->castAs<FunctionProtoType>();
+  CallingConv CC = FunctionTypeP->getCallConv();
+  bool NoReturn = FunctionTypeP->getNoReturnAttr();
+  const FunctionProtoType *ArgFunctionTypeP =
+      ArgFunctionType->getAs<FunctionProtoType>();
+  if (ArgFunctionTypeP->getCallConv() == CC &&
+      ArgFunctionTypeP->getNoReturnAttr() == NoReturn)
+    return ArgFunctionType;
+
+  FunctionType::ExtInfo EI = ArgFunctionTypeP->getExtInfo().withCallingConv(CC);
+  EI = EI.withNoReturn(NoReturn);
+  ArgFunctionTypeP =
+      cast<FunctionProtoType>(Context.adjustFunctionType(ArgFunctionTypeP, EI));
+  return QualType(ArgFunctionTypeP, 0);
+}
+
 /// \brief Deduce template arguments when taking the address of a function
 /// template (C++ [temp.deduct.funcaddr]) or matching a specialization to
 /// a template.
@@ -3538,6 +3551,8 @@
   TemplateParameterList *TemplateParams
     = FunctionTemplate->getTemplateParameters();
   QualType FunctionType = Function->getType();
+  if (!InOverloadResolution)
+    ArgFunctionType = adjustCCAndNoReturn(ArgFunctionType, FunctionType);
 
   // Substitute any explicit template arguments.
   LocalInstantiationScope InstScope(*this);
@@ -3565,7 +3580,7 @@
   // type so that we treat it as a non-deduced context in what follows.
   bool HasDeducedReturnType = false;
   if (getLangOpts().CPlusPlus1y && InOverloadResolution &&
-      Function->getResultType()->getContainedAutoType()) {
+      Function->getReturnType()->getContainedAutoType()) {
     FunctionType = SubstAutoType(FunctionType, Context.DependentTy);
     HasDeducedReturnType = true;
   }
@@ -3590,7 +3605,7 @@
   // If the function has a deduced return type, deduce it now, so we can check
   // that the deduced function type matches the requested type.
   if (HasDeducedReturnType &&
-      Specialization->getResultType()->isUndeducedType() &&
+      Specialization->getReturnType()->isUndeducedType() &&
       DeduceReturnType(Specialization, Info.getLocation(), false))
     return TDK_MiscellaneousDeductionFailure;
 
@@ -3619,7 +3634,7 @@
 SubstAutoWithinFunctionReturnType(FunctionDecl *F, 
                                     QualType TypeToReplaceAutoWith, Sema &S) {
   assert(!TypeToReplaceAutoWith->getContainedAutoType());
-  QualType AutoResultType = F->getResultType();
+  QualType AutoResultType = F->getReturnType();
   assert(AutoResultType->getContainedAutoType()); 
   QualType DeducedResultType = S.SubstAutoType(AutoResultType, 
                                                TypeToReplaceAutoWith);
@@ -3644,14 +3659,14 @@
   assert(LambdaClass && LambdaClass->isGenericLambda()); 
   
   CXXMethodDecl *CallOpGeneric = LambdaClass->getLambdaCallOperator();
-  QualType CallOpResultType = CallOpGeneric->getResultType(); 
+  QualType CallOpResultType = CallOpGeneric->getReturnType();
   const bool GenericLambdaCallOperatorHasDeducedReturnType = 
       CallOpResultType->getContainedAutoType();
   
   FunctionTemplateDecl *CallOpTemplate = 
       CallOpGeneric->getDescribedFunctionTemplate();
 
-  FunctionDecl *CallOpSpecialized = 0;
+  FunctionDecl *CallOpSpecialized = nullptr;
   // Use the deduced arguments of the conversion function, to specialize our 
   // generic lambda's call operator.
   if (Sema::TemplateDeductionResult Result
@@ -3661,15 +3676,15 @@
     return Result;
  
   // If we need to deduce the return type, do so (instantiates the callop).
-  if (GenericLambdaCallOperatorHasDeducedReturnType && 
-                CallOpSpecialized->getResultType()->isUndeducedType())
+  if (GenericLambdaCallOperatorHasDeducedReturnType &&
+      CallOpSpecialized->getReturnType()->isUndeducedType())
     S.DeduceReturnType(CallOpSpecialized, 
                        CallOpSpecialized->getPointOfInstantiation(),
                        /*Diagnose*/ true);
     
   // Check to see if the return type of the destination ptr-to-function
   // matches the return type of the call operator.
-  if (!S.Context.hasSameType(CallOpSpecialized->getResultType(), 
+  if (!S.Context.hasSameType(CallOpSpecialized->getReturnType(),
                              ReturnTypeOfDestFunctionPtr))
     return Sema::TDK_NonDeducedMismatch;
   // Since we have succeeded in matching the source and destination
@@ -3677,7 +3692,7 @@
   // specialized our corresponding call operator, we are ready to
   // specialize the static invoker with the deduced arguments of our
   // ptr-to-function.
-  FunctionDecl *InvokerSpecialized = 0;
+  FunctionDecl *InvokerSpecialized = nullptr;
   FunctionTemplateDecl *InvokerTemplate = LambdaClass->
                   getLambdaStaticInvoker()->getDescribedFunctionTemplate();
 
@@ -3688,8 +3703,8 @@
     "If the call operator succeeded so should the invoker!");
   // Set the result type to match the corresponding call operator
   // specialization's result type.
-  if (GenericLambdaCallOperatorHasDeducedReturnType && 
-      InvokerSpecialized->getResultType()->isUndeducedType()) {
+  if (GenericLambdaCallOperatorHasDeducedReturnType &&
+      InvokerSpecialized->getReturnType()->isUndeducedType()) {
     // Be sure to get the type to replace 'auto' with and not
     // the full result type of the call op specialization 
     // to substitute into the 'auto' of the invoker and conversion
@@ -3698,9 +3713,9 @@
     //  int* (*fp)(int*) = [](auto* a) -> auto* { return a; };
     // We don't want to subst 'int*' into 'auto' to get int**.
 
-    QualType TypeToReplaceAutoWith = 
-        CallOpSpecialized->getResultType()->
-            getContainedAutoType()->getDeducedType();
+    QualType TypeToReplaceAutoWith = CallOpSpecialized->getReturnType()
+                                         ->getContainedAutoType()
+                                         ->getDeducedType();
     SubstAutoWithinFunctionReturnType(InvokerSpecialized,
         TypeToReplaceAutoWith, S);
     SubstAutoWithinFunctionReturnType(ConversionSpecialized, 
@@ -3716,7 +3731,7 @@
   FunctionProtoType::ExtProtoInfo EPI = InvokerFPT->getExtProtoInfo();
   EPI.TypeQuals = 0;
   InvokerSpecialized->setType(S.Context.getFunctionType(
-      InvokerFPT->getResultType(), InvokerFPT->getArgTypes(),EPI));
+      InvokerFPT->getReturnType(), InvokerFPT->getParamTypes(), EPI));
   return Sema::TDK_Success;
 }
 /// \brief Deduce template arguments for a templated conversion
@@ -3820,7 +3835,7 @@
   // Create an Instantiation Scope for finalizing the operator.
   LocalInstantiationScope InstScope(*this);
   // Finish template argument deduction.
-  FunctionDecl *ConversionSpecialized = 0;
+  FunctionDecl *ConversionSpecialized = nullptr;
   TemplateDeductionResult Result
       = FinishTemplateArgumentDeduction(ConversionTemplate, Deduced, 0, 
                                         ConversionSpecialized, Info);
@@ -3839,8 +3854,8 @@
         "Can only convert from lambda to ptr-to-function");
     const FunctionType *ToFunType = 
         A->getPointeeType().getTypePtr()->getAs<FunctionType>();
-    const QualType DestFunctionPtrReturnType = ToFunType->getResultType();
-    
+    const QualType DestFunctionPtrReturnType = ToFunType->getReturnType();
+
     // Create the corresponding specializations of the call operator and 
     // the static-invoker; and if the return type is auto, 
     // deduce the return type and check if it matches the 
@@ -3954,7 +3969,7 @@
     ExprResult NonPlaceholder = CheckPlaceholderExpr(Init);
     if (NonPlaceholder.isInvalid())
       return DAR_FailedAlreadyDiagnosed;
-    Init = NonPlaceholder.take();
+    Init = NonPlaceholder.get();
   }
 
   if (Init->isTypeDependent() || Type.getType()->isDependentType()) {
@@ -3989,8 +4004,8 @@
 
   // Build template<class TemplParam> void Func(FuncParam);
   TemplateTypeParmDecl *TemplParam =
-    TemplateTypeParmDecl::Create(Context, 0, SourceLocation(), Loc, 0, 0, 0,
-                                 false, false);
+    TemplateTypeParmDecl::Create(Context, nullptr, SourceLocation(), Loc, 0, 0,
+                                 nullptr, false, false);
   QualType TemplArg = QualType(TemplParam->getTypeForDecl(), 0);
   NamedDecl *TemplParamPtr = TemplParam;
   FixedSizeTemplateParameterList<1> TemplateParams(Loc, Loc, &TemplParamPtr,
@@ -4085,12 +4100,12 @@
 
 bool Sema::DeduceReturnType(FunctionDecl *FD, SourceLocation Loc,
                             bool Diagnose) {
-  assert(FD->getResultType()->isUndeducedType());
+  assert(FD->getReturnType()->isUndeducedType());
 
   if (FD->getTemplateInstantiationPattern())
     InstantiateFunctionDefinition(Loc, FD);
 
-  bool StillUndeduced = FD->getResultType()->isUndeducedType();
+  bool StillUndeduced = FD->getReturnType()->isUndeducedType();
   if (StillUndeduced && Diagnose && !FD->isInvalidDecl()) {
     Diag(Loc, diag::err_auto_fn_used_before_defined) << FD;
     Diag(FD->getLocation(), diag::note_callee_decl) << FD;
@@ -4171,35 +4186,25 @@
     // otherwise, the ordering rules for static functions against non-static
     // functions don't make any sense.
     //
-    // C++98/03 doesn't have this provision, so instead we drop the
-    // first argument of the free function, which seems to match
-    // existing practice.
+    // C++98/03 doesn't have this provision but we've extended DR532 to cover
+    // it as wording was broken prior to it.
     SmallVector<QualType, 4> Args1;
 
-    unsigned Skip1 = 0, Skip2 = 0;
     unsigned NumComparedArguments = NumCallArguments1;
 
     if (!Method2 && Method1 && !Method1->isStatic()) {
-      if (S.getLangOpts().CPlusPlus11) {
-        // Compare 'this' from Method1 against first parameter from Method2.
-        AddImplicitObjectParameterType(S.Context, Method1, Args1);
-        ++NumComparedArguments;
-      } else
-        // Ignore first parameter from Method2.
-        ++Skip2;
+      // Compare 'this' from Method1 against first parameter from Method2.
+      AddImplicitObjectParameterType(S.Context, Method1, Args1);
+      ++NumComparedArguments;
     } else if (!Method1 && Method2 && !Method2->isStatic()) {
-      if (S.getLangOpts().CPlusPlus11)
-        // Compare 'this' from Method2 against first parameter from Method1.
-        AddImplicitObjectParameterType(S.Context, Method2, Args2);
-      else
-        // Ignore first parameter from Method1.
-        ++Skip1;
+      // Compare 'this' from Method2 against first parameter from Method1.
+      AddImplicitObjectParameterType(S.Context, Method2, Args2);
     }
 
-    Args1.insert(Args1.end(),
-                 Proto1->arg_type_begin() + Skip1, Proto1->arg_type_end());
-    Args2.insert(Args2.end(),
-                 Proto2->arg_type_begin() + Skip2, Proto2->arg_type_end());
+    Args1.insert(Args1.end(), Proto1->param_type_begin(),
+                 Proto1->param_type_end());
+    Args2.insert(Args2.end(), Proto2->param_type_begin(),
+                 Proto2->param_type_end());
 
     // C++ [temp.func.order]p5:
     //   The presence of unused ellipsis and default arguments has no effect on
@@ -4212,7 +4217,7 @@
                                 Args1.data(), Args1.size(), Info, Deduced,
                                 TDF_None, /*PartialOrdering=*/true,
                                 RefParamComparisons))
-        return false;
+      return false;
 
     break;
   }
@@ -4220,12 +4225,10 @@
   case TPOC_Conversion:
     //   - In the context of a call to a conversion operator, the return types
     //     of the conversion function templates are used.
-    if (DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
-                                           Proto2->getResultType(),
-                                           Proto1->getResultType(),
-                                           Info, Deduced, TDF_None,
-                                           /*PartialOrdering=*/true,
-                                           RefParamComparisons))
+    if (DeduceTemplateArgumentsByTypeMatch(
+            S, TemplateParams, Proto2->getReturnType(), Proto1->getReturnType(),
+            Info, Deduced, TDF_None,
+            /*PartialOrdering=*/true, RefParamComparisons))
       return false;
     break;
 
@@ -4269,9 +4272,8 @@
     break;
 
   case TPOC_Conversion:
-    ::MarkUsedTemplateParameters(S.Context, Proto2->getResultType(), false,
-                                 TemplateParams->getDepth(),
-                                 UsedParameters);
+    ::MarkUsedTemplateParameters(S.Context, Proto2->getReturnType(), false,
+                                 TemplateParams->getDepth(), UsedParameters);
     break;
 
   case TPOC_Other:
@@ -4338,7 +4340,7 @@
                                  unsigned NumCallArguments2) {
   SmallVector<RefParamPartialOrderingComparison, 4> RefParamComparisons;
   bool Better1 = isAtLeastAsSpecializedAs(*this, Loc, FT1, FT2, TPOC,
-                                          NumCallArguments1, 0);
+                                          NumCallArguments1, nullptr);
   bool Better2 = isAtLeastAsSpecializedAs(*this, Loc, FT2, FT1, TPOC,
                                           NumCallArguments2,
                                           &RefParamComparisons);
@@ -4347,7 +4349,7 @@
     return Better1? FT1 : FT2;
 
   if (!Better1 && !Better2) // Neither is better than the other
-    return 0;
+    return nullptr;
 
   // C++0x [temp.deduct.partial]p10:
   //   If for each type being considered a given template is at least as
@@ -4373,13 +4375,13 @@
         RefParamComparisons[I].ParamIsRvalueRef) {
       Better2 = true;
       if (Better1)
-        return 0;
+        return nullptr;
       continue;
     } else if (!RefParamComparisons[I].ParamIsRvalueRef &&
                RefParamComparisons[I].ArgIsRvalueRef) {
       Better1 = true;
       if (Better2)
-        return 0;
+        return nullptr;
       continue;
     }
 
@@ -4394,13 +4396,13 @@
     case ParamMoreQualified:
       Better1 = true;
       if (Better2)
-        return 0;
+        return nullptr;
       continue;
 
     case ArgMoreQualified:
       Better2 = true;
       if (Better1)
-        return 0;
+        return nullptr;
       continue;
     }
 
@@ -4421,7 +4423,7 @@
   if (Variadic1 != Variadic2)
     return Variadic1? FT2 : FT1;
 
-  return 0;
+  return nullptr;
 }
 
 /// \brief Determine if the two templates are equivalent.
@@ -4586,11 +4588,10 @@
                                             PS2->getTemplateParameters(),
                                             PT2, PT1, Info, Deduced, TDF_None,
                                             /*PartialOrdering=*/true,
-                                            /*RefParamComparisons=*/0);
+                                            /*RefParamComparisons=*/nullptr);
   if (Better1) {
     SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(),Deduced.end());
-    InstantiatingTemplate Inst(*this, PS2->getLocation(), PS2, DeducedArgs,
-                               Info);
+    InstantiatingTemplate Inst(*this, Loc, PS2, DeducedArgs, Info);
     Better1 = !::FinishTemplateArgumentDeduction(
         *this, PS2, PS1->getTemplateArgs(), Deduced, Info);
   }
@@ -4601,18 +4602,17 @@
   bool Better2 = !DeduceTemplateArgumentsByTypeMatch(
       *this, PS1->getTemplateParameters(), PT1, PT2, Info, Deduced, TDF_None,
       /*PartialOrdering=*/true,
-      /*RefParamComparisons=*/0);
+      /*RefParamComparisons=*/nullptr);
   if (Better2) {
     SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(),
                                                  Deduced.end());
-    InstantiatingTemplate Inst(*this, PS1->getLocation(), PS1, DeducedArgs,
-                               Info);
+    InstantiatingTemplate Inst(*this, Loc, PS1, DeducedArgs, Info);
     Better2 = !::FinishTemplateArgumentDeduction(
         *this, PS1, PS2->getTemplateArgs(), Deduced, Info);
   }
 
   if (Better1 == Better2)
-    return 0;
+    return nullptr;
 
   return Better1 ? PS1 : PS2;
 }
@@ -4629,7 +4629,7 @@
   SmallVector<DeducedTemplateArgument, 4> Deduced;
   TemplateDeductionInfo Info(Loc);
 
-  assert(PS1->getSpecializedTemplate() == PS1->getSpecializedTemplate() &&
+  assert(PS1->getSpecializedTemplate() == PS2->getSpecializedTemplate() &&
          "the partial specializations being compared should specialize"
          " the same template.");
   TemplateName Name(PS1->getSpecializedTemplate());
@@ -4646,12 +4646,11 @@
   bool Better1 = !DeduceTemplateArgumentsByTypeMatch(
       *this, PS2->getTemplateParameters(), PT2, PT1, Info, Deduced, TDF_None,
       /*PartialOrdering=*/true,
-      /*RefParamComparisons=*/0);
+      /*RefParamComparisons=*/nullptr);
   if (Better1) {
     SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(),
                                                  Deduced.end());
-    InstantiatingTemplate Inst(*this, PS2->getLocation(), PS2,
-                               DeducedArgs, Info);
+    InstantiatingTemplate Inst(*this, Loc, PS2, DeducedArgs, Info);
     Better1 = !::FinishTemplateArgumentDeduction(*this, PS2,
                                                  PS1->getTemplateArgs(),
                                                  Deduced, Info);
@@ -4664,18 +4663,17 @@
                                             PS1->getTemplateParameters(),
                                             PT1, PT2, Info, Deduced, TDF_None,
                                             /*PartialOrdering=*/true,
-                                            /*RefParamComparisons=*/0);
+                                            /*RefParamComparisons=*/nullptr);
   if (Better2) {
     SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(),Deduced.end());
-    InstantiatingTemplate Inst(*this, PS1->getLocation(), PS1,
-                               DeducedArgs, Info);
+    InstantiatingTemplate Inst(*this, Loc, PS1, DeducedArgs, Info);
     Better2 = !::FinishTemplateArgumentDeduction(*this, PS1,
                                                  PS2->getTemplateArgs(),
                                                  Deduced, Info);
   }
 
   if (Better1 == Better2)
-    return 0;
+    return nullptr;
 
   return Better1? PS1 : PS2;
 }
@@ -4850,10 +4848,10 @@
 
   case Type::FunctionProto: {
     const FunctionProtoType *Proto = cast<FunctionProtoType>(T);
-    MarkUsedTemplateParameters(Ctx, Proto->getResultType(), OnlyDeduced,
-                               Depth, Used);
-    for (unsigned I = 0, N = Proto->getNumArgs(); I != N; ++I)
-      MarkUsedTemplateParameters(Ctx, Proto->getArgType(I), OnlyDeduced,
+    MarkUsedTemplateParameters(Ctx, Proto->getReturnType(), OnlyDeduced, Depth,
+                               Used);
+    for (unsigned I = 0, N = Proto->getNumParams(); I != N; ++I)
+      MarkUsedTemplateParameters(Ctx, Proto->getParamType(I), OnlyDeduced,
                                  Depth, Used);
     break;
   }
@@ -5037,10 +5035,8 @@
     break;
 
   case TemplateArgument::Pack:
-    for (TemplateArgument::pack_iterator P = TemplateArg.pack_begin(),
-                                      PEnd = TemplateArg.pack_end();
-         P != PEnd; ++P)
-      MarkUsedTemplateParameters(Ctx, *P, OnlyDeduced, Depth, Used);
+    for (const auto &P : TemplateArg.pack_elements())
+      MarkUsedTemplateParameters(Ctx, P, OnlyDeduced, Depth, Used);
     break;
   }
 }
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 3c621da..14c6405 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -76,8 +76,18 @@
       // If this variable template specialization was instantiated from a
       // specialized member that is a variable template, we're done.
       assert(Spec->getSpecializedTemplate() && "No variable template?");
-      if (Spec->getSpecializedTemplate()->isMemberSpecialization())
-        return Result;
+      llvm::PointerUnion<VarTemplateDecl*,
+                         VarTemplatePartialSpecializationDecl*> Specialized
+                             = Spec->getSpecializedTemplateOrPartial();
+      if (VarTemplatePartialSpecializationDecl *Partial =
+              Specialized.dyn_cast<VarTemplatePartialSpecializationDecl *>()) {
+        if (Partial->isMemberSpecialization())
+          return Result;
+      } else {
+        VarTemplateDecl *Tmpl = Specialized.get<VarTemplateDecl *>();
+        if (Tmpl->isMemberSpecialization())
+          return Result;
+      }
     }
 
     // If we have a template template parameter with translation unit context,
@@ -190,50 +200,49 @@
   llvm_unreachable("Invalid InstantiationKind!");
 }
 
+void Sema::InstantiatingTemplate::Initialize(
+    ActiveTemplateInstantiation::InstantiationKind Kind,
+    SourceLocation PointOfInstantiation, SourceRange InstantiationRange,
+    Decl *Entity, NamedDecl *Template, ArrayRef<TemplateArgument> TemplateArgs,
+    sema::TemplateDeductionInfo *DeductionInfo) {
+  SavedInNonInstantiationSFINAEContext =
+      SemaRef.InNonInstantiationSFINAEContext;
+  Invalid = CheckInstantiationDepth(PointOfInstantiation, InstantiationRange);
+  if (!Invalid) {
+    ActiveTemplateInstantiation Inst;
+    Inst.Kind = Kind;
+    Inst.PointOfInstantiation = PointOfInstantiation;
+    Inst.Entity = Entity;
+    Inst.Template = Template;
+    Inst.TemplateArgs = TemplateArgs.data();
+    Inst.NumTemplateArgs = TemplateArgs.size();
+    Inst.DeductionInfo = DeductionInfo;
+    Inst.InstantiationRange = InstantiationRange;
+    SemaRef.InNonInstantiationSFINAEContext = false;
+    SemaRef.ActiveTemplateInstantiations.push_back(Inst);
+    if (!Inst.isInstantiationRecord())
+      ++SemaRef.NonInstantiationEntries;
+  }
+}
+
 Sema::InstantiatingTemplate::
 InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
                       Decl *Entity,
                       SourceRange InstantiationRange)
-  : SemaRef(SemaRef),
-    SavedInNonInstantiationSFINAEContext(
-                                        SemaRef.InNonInstantiationSFINAEContext)
+  : SemaRef(SemaRef)
 {
-  Invalid = CheckInstantiationDepth(PointOfInstantiation,
-                                    InstantiationRange);
-  if (!Invalid) {
-    ActiveTemplateInstantiation Inst;
-    Inst.Kind = ActiveTemplateInstantiation::TemplateInstantiation;
-    Inst.PointOfInstantiation = PointOfInstantiation;
-    Inst.Entity = Entity;
-    Inst.TemplateArgs = 0;
-    Inst.NumTemplateArgs = 0;
-    Inst.InstantiationRange = InstantiationRange;
-    SemaRef.InNonInstantiationSFINAEContext = false;
-    SemaRef.ActiveTemplateInstantiations.push_back(Inst);
-  }
+  Initialize(ActiveTemplateInstantiation::TemplateInstantiation,
+             PointOfInstantiation, InstantiationRange, Entity);
 }
 
 Sema::InstantiatingTemplate::
 InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
                       FunctionDecl *Entity, ExceptionSpecification,
                       SourceRange InstantiationRange)
-  : SemaRef(SemaRef),
-    SavedInNonInstantiationSFINAEContext(
-                                        SemaRef.InNonInstantiationSFINAEContext)
+  : SemaRef(SemaRef)
 {
-  Invalid = CheckInstantiationDepth(PointOfInstantiation,
-                                    InstantiationRange);
-  if (!Invalid) {
-    ActiveTemplateInstantiation Inst;
-    Inst.Kind = ActiveTemplateInstantiation::ExceptionSpecInstantiation;
-    Inst.PointOfInstantiation = PointOfInstantiation;
-    Inst.Entity = Entity;
-    Inst.TemplateArgs = 0;
-    Inst.NumTemplateArgs = 0;
-    Inst.InstantiationRange = InstantiationRange;
-    SemaRef.InNonInstantiationSFINAEContext = false;
-    SemaRef.ActiveTemplateInstantiations.push_back(Inst);
-  }
+  Initialize(ActiveTemplateInstantiation::ExceptionSpecInstantiation,
+             PointOfInstantiation, InstantiationRange, Entity);
 }
 
 Sema::InstantiatingTemplate::
@@ -241,24 +250,11 @@
                       TemplateDecl *Template,
                       ArrayRef<TemplateArgument> TemplateArgs,
                       SourceRange InstantiationRange)
-  : SemaRef(SemaRef),
-    SavedInNonInstantiationSFINAEContext(
-                                     SemaRef.InNonInstantiationSFINAEContext)
+  : SemaRef(SemaRef)
 {
-  Invalid = CheckInstantiationDepth(PointOfInstantiation,
-                                    InstantiationRange);
-  if (!Invalid) {
-    ActiveTemplateInstantiation Inst;
-    Inst.Kind
-      = ActiveTemplateInstantiation::DefaultTemplateArgumentInstantiation;
-    Inst.PointOfInstantiation = PointOfInstantiation;
-    Inst.Entity = Template;
-    Inst.TemplateArgs = TemplateArgs.data();
-    Inst.NumTemplateArgs = TemplateArgs.size();
-    Inst.InstantiationRange = InstantiationRange;
-    SemaRef.InNonInstantiationSFINAEContext = false;
-    SemaRef.ActiveTemplateInstantiations.push_back(Inst);
-  }
+  Initialize(ActiveTemplateInstantiation::DefaultTemplateArgumentInstantiation,
+             PointOfInstantiation, InstantiationRange,
+             Template, nullptr, TemplateArgs);
 }
 
 Sema::InstantiatingTemplate::
@@ -268,26 +264,10 @@
                       ActiveTemplateInstantiation::InstantiationKind Kind,
                       sema::TemplateDeductionInfo &DeductionInfo,
                       SourceRange InstantiationRange)
-  : SemaRef(SemaRef),
-    SavedInNonInstantiationSFINAEContext(
-                                     SemaRef.InNonInstantiationSFINAEContext)
+  : SemaRef(SemaRef)
 {
-  Invalid = CheckInstantiationDepth(PointOfInstantiation, InstantiationRange);
-  if (!Invalid) {
-    ActiveTemplateInstantiation Inst;
-    Inst.Kind = Kind;
-    Inst.PointOfInstantiation = PointOfInstantiation;
-    Inst.Entity = FunctionTemplate;
-    Inst.TemplateArgs = TemplateArgs.data();
-    Inst.NumTemplateArgs = TemplateArgs.size();
-    Inst.DeductionInfo = &DeductionInfo;
-    Inst.InstantiationRange = InstantiationRange;
-    SemaRef.InNonInstantiationSFINAEContext = false;
-    SemaRef.ActiveTemplateInstantiations.push_back(Inst);
-    
-    if (!Inst.isInstantiationRecord())
-      ++SemaRef.NonInstantiationEntries;
-  }
+  Initialize(Kind, PointOfInstantiation, InstantiationRange,
+             FunctionTemplate, nullptr, TemplateArgs, &DeductionInfo);
 }
 
 Sema::InstantiatingTemplate::
@@ -296,23 +276,11 @@
                       ArrayRef<TemplateArgument> TemplateArgs,
                       sema::TemplateDeductionInfo &DeductionInfo,
                       SourceRange InstantiationRange)
-  : SemaRef(SemaRef),
-    SavedInNonInstantiationSFINAEContext(
-                                     SemaRef.InNonInstantiationSFINAEContext)
+  : SemaRef(SemaRef)
 {
-  Invalid = CheckInstantiationDepth(PointOfInstantiation, InstantiationRange);
-  if (!Invalid) {
-    ActiveTemplateInstantiation Inst;
-    Inst.Kind = ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution;
-    Inst.PointOfInstantiation = PointOfInstantiation;
-    Inst.Entity = PartialSpec;
-    Inst.TemplateArgs = TemplateArgs.data();
-    Inst.NumTemplateArgs = TemplateArgs.size();
-    Inst.DeductionInfo = &DeductionInfo;
-    Inst.InstantiationRange = InstantiationRange;
-    SemaRef.InNonInstantiationSFINAEContext = false;
-    SemaRef.ActiveTemplateInstantiations.push_back(Inst);
-  }
+  Initialize(ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution,
+             PointOfInstantiation, InstantiationRange,
+             PartialSpec, nullptr, TemplateArgs, &DeductionInfo);
 }
 
 Sema::InstantiatingTemplate::InstantiatingTemplate(
@@ -320,22 +288,11 @@
     VarTemplatePartialSpecializationDecl *PartialSpec,
     ArrayRef<TemplateArgument> TemplateArgs,
     sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
-    : SemaRef(SemaRef), SavedInNonInstantiationSFINAEContext(
-                            SemaRef.InNonInstantiationSFINAEContext) {
-  Invalid = CheckInstantiationDepth(PointOfInstantiation, InstantiationRange);
-  if (!Invalid) {
-    ActiveTemplateInstantiation Inst;
-    Inst.Kind =
-        ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution;
-    Inst.PointOfInstantiation = PointOfInstantiation;
-    Inst.Entity = PartialSpec;
-    Inst.TemplateArgs = TemplateArgs.data();
-    Inst.NumTemplateArgs = TemplateArgs.size();
-    Inst.DeductionInfo = &DeductionInfo;
-    Inst.InstantiationRange = InstantiationRange;
-    SemaRef.InNonInstantiationSFINAEContext = false;
-    SemaRef.ActiveTemplateInstantiations.push_back(Inst);
-  }
+  : SemaRef(SemaRef)
+{
+  Initialize(ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution,
+             PointOfInstantiation, InstantiationRange,
+             PartialSpec, nullptr, TemplateArgs, &DeductionInfo);
 }
 
 Sema::InstantiatingTemplate::
@@ -343,47 +300,24 @@
                       ParmVarDecl *Param,
                       ArrayRef<TemplateArgument> TemplateArgs,
                       SourceRange InstantiationRange)
-  : SemaRef(SemaRef),
-    SavedInNonInstantiationSFINAEContext(
-                                     SemaRef.InNonInstantiationSFINAEContext)
+  : SemaRef(SemaRef)
 {
-  Invalid = CheckInstantiationDepth(PointOfInstantiation, InstantiationRange);
-  if (!Invalid) {
-    ActiveTemplateInstantiation Inst;
-    Inst.Kind
-      = ActiveTemplateInstantiation::DefaultFunctionArgumentInstantiation;
-    Inst.PointOfInstantiation = PointOfInstantiation;
-    Inst.Entity = Param;
-    Inst.TemplateArgs = TemplateArgs.data();
-    Inst.NumTemplateArgs = TemplateArgs.size();
-    Inst.InstantiationRange = InstantiationRange;
-    SemaRef.InNonInstantiationSFINAEContext = false;
-    SemaRef.ActiveTemplateInstantiations.push_back(Inst);
-  }
+  Initialize(ActiveTemplateInstantiation::DefaultFunctionArgumentInstantiation,
+             PointOfInstantiation, InstantiationRange,
+             Param, nullptr, TemplateArgs);
 }
 
+
 Sema::InstantiatingTemplate::
 InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
                       NamedDecl *Template, NonTypeTemplateParmDecl *Param,
                       ArrayRef<TemplateArgument> TemplateArgs,
                       SourceRange InstantiationRange)
-  : SemaRef(SemaRef),
-    SavedInNonInstantiationSFINAEContext(
-                                     SemaRef.InNonInstantiationSFINAEContext)
+  : SemaRef(SemaRef)
 {
-  Invalid = CheckInstantiationDepth(PointOfInstantiation, InstantiationRange);
-  if (!Invalid) {
-    ActiveTemplateInstantiation Inst;
-    Inst.Kind = ActiveTemplateInstantiation::PriorTemplateArgumentSubstitution;
-    Inst.PointOfInstantiation = PointOfInstantiation;
-    Inst.Template = Template;
-    Inst.Entity = Param;
-    Inst.TemplateArgs = TemplateArgs.data();
-    Inst.NumTemplateArgs = TemplateArgs.size();
-    Inst.InstantiationRange = InstantiationRange;
-    SemaRef.InNonInstantiationSFINAEContext = false;
-    SemaRef.ActiveTemplateInstantiations.push_back(Inst);
-  }
+  Initialize(ActiveTemplateInstantiation::PriorTemplateArgumentSubstitution,
+             PointOfInstantiation, InstantiationRange,
+             Param, Template, TemplateArgs);
 }
 
 Sema::InstantiatingTemplate::
@@ -391,23 +325,11 @@
                       NamedDecl *Template, TemplateTemplateParmDecl *Param,
                       ArrayRef<TemplateArgument> TemplateArgs,
                       SourceRange InstantiationRange)
-  : SemaRef(SemaRef),
-    SavedInNonInstantiationSFINAEContext(
-                                     SemaRef.InNonInstantiationSFINAEContext)
+  : SemaRef(SemaRef)
 {
-  Invalid = CheckInstantiationDepth(PointOfInstantiation, InstantiationRange);
-  if (!Invalid) {
-    ActiveTemplateInstantiation Inst;
-    Inst.Kind = ActiveTemplateInstantiation::PriorTemplateArgumentSubstitution;
-    Inst.PointOfInstantiation = PointOfInstantiation;
-    Inst.Template = Template;
-    Inst.Entity = Param;
-    Inst.TemplateArgs = TemplateArgs.data();
-    Inst.NumTemplateArgs = TemplateArgs.size();
-    Inst.InstantiationRange = InstantiationRange;
-    SemaRef.InNonInstantiationSFINAEContext = false;
-    SemaRef.ActiveTemplateInstantiations.push_back(Inst);
-  }
+  Initialize(ActiveTemplateInstantiation::PriorTemplateArgumentSubstitution,
+             PointOfInstantiation, InstantiationRange,
+             Param, Template, TemplateArgs);
 }
 
 Sema::InstantiatingTemplate::
@@ -415,25 +337,11 @@
                       TemplateDecl *Template, NamedDecl *Param,
                       ArrayRef<TemplateArgument> TemplateArgs,
                       SourceRange InstantiationRange)
-  : SemaRef(SemaRef),
-    SavedInNonInstantiationSFINAEContext(
-                                     SemaRef.InNonInstantiationSFINAEContext)
+  : SemaRef(SemaRef)
 {
-  Invalid = false;
-  
-  ActiveTemplateInstantiation Inst;
-  Inst.Kind = ActiveTemplateInstantiation::DefaultTemplateArgumentChecking;
-  Inst.PointOfInstantiation = PointOfInstantiation;
-  Inst.Template = Template;
-  Inst.Entity = Param;
-  Inst.TemplateArgs = TemplateArgs.data();
-  Inst.NumTemplateArgs = TemplateArgs.size();
-  Inst.InstantiationRange = InstantiationRange;
-  SemaRef.InNonInstantiationSFINAEContext = false;
-  SemaRef.ActiveTemplateInstantiations.push_back(Inst);
-  
-  assert(!Inst.isInstantiationRecord());
-  ++SemaRef.NonInstantiationEntries;
+  Initialize(ActiveTemplateInstantiation::DefaultTemplateArgumentChecking,
+             PointOfInstantiation, InstantiationRange,
+             Param, Template, TemplateArgs);
 }
 
 void Sema::InstantiatingTemplate::Clear() {
@@ -624,8 +532,8 @@
       std::string Name;
       if (!Parm->getName().empty())
         Name = std::string(" '") + Parm->getName().str() + "'";
-                    
-      TemplateParameterList *TemplateParams = 0;
+
+      TemplateParameterList *TemplateParams = nullptr;
       if (TemplateDecl *Template = dyn_cast<TemplateDecl>(Active->Template))
         TemplateParams = Template->getTemplateParameters();
       else
@@ -644,7 +552,7 @@
     }
 
     case ActiveTemplateInstantiation::DefaultTemplateArgumentChecking: {
-      TemplateParameterList *TemplateParams = 0;
+      TemplateParameterList *TemplateParams = nullptr;
       if (TemplateDecl *Template = dyn_cast<TemplateDecl>(Active->Template))
         TemplateParams = Template->getTemplateParameters();
       else
@@ -673,7 +581,7 @@
 
 Optional<TemplateDeductionInfo *> Sema::isSFINAEContext() const {
   if (InNonInstantiationSFINAEContext)
-    return Optional<TemplateDeductionInfo *>(0);
+    return Optional<TemplateDeductionInfo *>(nullptr);
 
   for (SmallVectorImpl<ActiveTemplateInstantiation>::const_reverse_iterator
          Active = ActiveTemplateInstantiations.rbegin(),
@@ -789,7 +697,7 @@
         MultiLevelTemplateArgumentList &TemplateArgs
           = const_cast<MultiLevelTemplateArgumentList &>(this->TemplateArgs);
         unsigned Depth, Index;
-        llvm::tie(Depth, Index) = getDepthAndIndex(PartialPack);
+        std::tie(Depth, Index) = getDepthAndIndex(PartialPack);
         if (TemplateArgs.hasTemplateArgument(Depth, Index)) {
           Result = TemplateArgs(Depth, Index);
           TemplateArgs.setArgument(Depth, Index, TemplateArgument());
@@ -808,7 +716,7 @@
         MultiLevelTemplateArgumentList &TemplateArgs
         = const_cast<MultiLevelTemplateArgumentList &>(this->TemplateArgs);
         unsigned Depth, Index;
-        llvm::tie(Depth, Index) = getDepthAndIndex(PartialPack);
+        std::tie(Depth, Index) = getDepthAndIndex(PartialPack);
         TemplateArgs.setArgument(Depth, Index, Arg);
       }
     }
@@ -853,11 +761,11 @@
                                    NestedNameSpecifierLoc QualifierLoc,
                                    QualType T);
 
-    TemplateName TransformTemplateName(CXXScopeSpec &SS,
-                                       TemplateName Name,
-                                       SourceLocation NameLoc,                                     
-                                       QualType ObjectType = QualType(),
-                                       NamedDecl *FirstQualifierInScope = 0);
+    TemplateName
+    TransformTemplateName(CXXScopeSpec &SS, TemplateName Name,
+                          SourceLocation NameLoc,
+                          QualType ObjectType = QualType(),
+                          NamedDecl *FirstQualifierInScope = nullptr);
 
     ExprResult TransformPredefinedExpr(PredefinedExpr *E);
     ExprResult TransformDeclRefExpr(DeclRefExpr *E);
@@ -917,7 +825,8 @@
     }
 
     ExprResult TransformLambdaScope(LambdaExpr *E,
-                                    CXXMethodDecl *NewCallOperator) {
+        CXXMethodDecl *NewCallOperator, 
+        ArrayRef<InitCaptureInfoTy> InitCaptureExprsAndTypes) {
       CXXMethodDecl *const OldCallOperator = E->getCallOperator();   
       // In the generic lambda case, we set the NewTemplate to be considered
       // an "instantiation" of the OldTemplate.
@@ -928,17 +837,16 @@
                               OldCallOperator->getDescribedFunctionTemplate();
         NewCallOperatorTemplate->setInstantiatedFromMemberTemplate(
                                                      OldCallOperatorTemplate);
-        // Mark the NewCallOperatorTemplate a specialization.  
-        NewCallOperatorTemplate->setMemberSpecialization();
       } else 
         // For a non-generic lambda we set the NewCallOperator to 
         // be an instantiation of the OldCallOperator.
         NewCallOperator->setInstantiationOfMemberFunction(OldCallOperator,
                                                     TSK_ImplicitInstantiation);
       
-      return inherited::TransformLambdaScope(E, NewCallOperator);
+      return inherited::TransformLambdaScope(E, NewCallOperator, 
+          InitCaptureExprsAndTypes);
     }
-    TemplateParameterList *TransformTemplateParameterList(

+    TemplateParameterList *TransformTemplateParameterList(
                               TemplateParameterList *OrigTPL)  {
       if (!OrigTPL || !OrigTPL->size()) return OrigTPL;
          
@@ -977,7 +885,7 @@
 
 Decl *TemplateInstantiator::TransformDecl(SourceLocation Loc, Decl *D) {
   if (!D)
-    return 0;
+    return nullptr;
 
   if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(D)) {
     if (TTP->getDepth() < TemplateArgs.getNumLevels()) {
@@ -1013,7 +921,7 @@
 Decl *TemplateInstantiator::TransformDefinition(SourceLocation Loc, Decl *D) {
   Decl *Inst = getSema().SubstDecl(D, getSema().CurContext, TemplateArgs);
   if (!Inst)
-    return 0;
+    return nullptr;
 
   getSema().CurrentInstantiationScope->InstantiatedLocal(D, Inst);
   return Inst;
@@ -1037,8 +945,8 @@
                "Missing argument pack");
         
         if (getSema().ArgumentPackSubstitutionIndex == -1)
-          return 0;
-        
+          return nullptr;
+
         Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
       }
 
@@ -1051,7 +959,7 @@
       
       // The resulting type is not a tag; complain.
       getSema().Diag(Loc, diag::err_nested_name_spec_non_tag) << T;
-      return 0;
+      return nullptr;
     }
   }
   
@@ -1176,7 +1084,7 @@
 ExprResult 
 TemplateInstantiator::TransformPredefinedExpr(PredefinedExpr *E) {
   if (!E->isTypeDependent())
-    return SemaRef.Owned(E);
+    return E;
 
   return getSema().BuildPredefinedExpr(E->getLocation(), E->getIdentType());
 }
@@ -1190,7 +1098,7 @@
   // arguments left unspecified.
   if (!TemplateArgs.hasTemplateArgument(NTTP->getDepth(),
                                         NTTP->getPosition()))
-    return SemaRef.Owned(E);
+    return E;
 
   TemplateArgument Arg = TemplateArgs(NTTP->getDepth(), NTTP->getPosition());
   if (NTTP->isParameterPack()) {
@@ -1230,7 +1138,7 @@
   // case we just return that expression.
   if (arg.getKind() == TemplateArgument::Expression) {
     Expr *argExpr = arg.getAsExpr();
-    result = SemaRef.Owned(argExpr);
+    result = argExpr;
     type = argExpr->getType();
 
   } else if (arg.getKind() == TemplateArgument::Declaration ||
@@ -1247,7 +1155,7 @@
         return ExprError();
     } else {
       // Propagate NULL template argument.
-      VD = 0;
+      VD = nullptr;
     }
     
     // Derive the type we want the substituted decl to have.  This had
@@ -1277,11 +1185,9 @@
   }
   if (result.isInvalid()) return ExprError();
 
-  Expr *resultExpr = result.take();
-  return SemaRef.Owned(new (SemaRef.Context)
-                SubstNonTypeTemplateParmExpr(type,
-                                             resultExpr->getValueKind(),
-                                             loc, parm, resultExpr));
+  Expr *resultExpr = result.get();
+  return new (SemaRef.Context) SubstNonTypeTemplateParmExpr(
+      type, resultExpr->getValueKind(), loc, parm, resultExpr);
 }
                                                    
 ExprResult 
@@ -1289,7 +1195,7 @@
                                           SubstNonTypeTemplateParmPackExpr *E) {
   if (getSema().ArgumentPackSubstitutionIndex == -1) {
     // We aren't expanding the parameter pack, so just return ourselves.
-    return getSema().Owned(E);
+    return E;
   }
 
   TemplateArgument Arg = E->getArgumentPack();
@@ -1485,7 +1391,7 @@
   // the template parameter list of a member template inside the
   // template we are instantiating). Create a new template type
   // parameter with the template "level" reduced by one.
-  TemplateTypeParmDecl *NewTTPDecl = 0;
+  TemplateTypeParmDecl *NewTTPDecl = nullptr;
   if (TemplateTypeParmDecl *OldTTPDecl = T->getDecl())
     NewTTPDecl = cast_or_null<TemplateTypeParmDecl>(
                                   TransformDecl(TL.getNameLoc(), OldTTPDecl));
@@ -1578,7 +1484,7 @@
          "instantiation stack");
   
   if (TL.getType().isNull())
-    return 0;
+    return nullptr;
 
   if (!TL.getType()->isInstantiationDependentType() && 
       !TL.getType()->isVariablyModifiedType()) {
@@ -1594,7 +1500,7 @@
   TLB.reserve(TL.getFullDataSize());
   QualType Result = Instantiator.TransformType(TLB, TL);
   if (Result.isNull())
-    return 0;
+    return nullptr;
 
   return TLB.getTypeSourceInfo(Context, Result);
 }
@@ -1626,8 +1532,8 @@
     return false;
 
   FunctionProtoTypeLoc FP = TL.castAs<FunctionProtoTypeLoc>();
-  for (unsigned I = 0, E = FP.getNumArgs(); I != E; ++I) {
-    ParmVarDecl *P = FP.getArg(I);
+  for (unsigned I = 0, E = FP.getNumParams(); I != E; ++I) {
+    ParmVarDecl *P = FP.getParam(I);
 
     // This must be synthesized from a typedef.
     if (!P) continue;
@@ -1680,7 +1586,7 @@
     Result = Instantiator.TransformType(TLB, TL);
   }
   if (Result.isNull())
-    return 0;
+    return nullptr;
 
   return TLB.getTypeSourceInfo(Context, Result);
 }
@@ -1691,8 +1597,8 @@
                                     Optional<unsigned> NumExpansions,
                                     bool ExpectParameterPack) {
   TypeSourceInfo *OldDI = OldParm->getTypeSourceInfo();
-  TypeSourceInfo *NewDI = 0;
-  
+  TypeSourceInfo *NewDI = nullptr;
+
   TypeLoc OldTL = OldDI->getTypeLoc();
   if (PackExpansionTypeLoc ExpansionTL = OldTL.getAs<PackExpansionTypeLoc>()) {
 
@@ -1701,8 +1607,8 @@
     NewDI = SubstType(ExpansionTL.getPatternLoc(), TemplateArgs, 
                       OldParm->getLocation(), OldParm->getDeclName());
     if (!NewDI)
-      return 0;
-        
+      return nullptr;
+
     if (NewDI->getType()->containsUnexpandedParameterPack()) {
       // We still have unexpanded parameter packs, which means that
       // our function parameter is still a function parameter pack.
@@ -1717,7 +1623,7 @@
       Diag(OldParm->getLocation(), 
            diag::err_function_parameter_pack_without_parameter_packs)
         << NewDI->getType();
-      return 0;
+      return nullptr;
     } 
   } else {
     NewDI = SubstType(OldDI, TemplateArgs, OldParm->getLocation(), 
@@ -1725,11 +1631,11 @@
   }
   
   if (!NewDI)
-    return 0;
+    return nullptr;
 
   if (NewDI->getType()->isVoidType()) {
     Diag(OldParm->getLocation(), diag::err_param_with_void_type);
-    return 0;
+    return nullptr;
   }
 
   ParmVarDecl *NewParm = CheckParameter(Context.getTranslationUnitDecl(),
@@ -1739,8 +1645,8 @@
                                         NewDI->getType(), NewDI,
                                         OldParm->getStorageClass());
   if (!NewParm)
-    return 0;
-                                                
+    return nullptr;
+
   // Mark the (new) default argument as uninstantiated (if any).
   if (OldParm->hasUninstantiatedDefaultArg()) {
     Expr *Arg = OldParm->getUninstantiatedDefaultArg();
@@ -1790,8 +1696,9 @@
   
   TemplateInstantiator Instantiator(*this, TemplateArgs, Loc, 
                                     DeclarationName());
-  return Instantiator.TransformFunctionTypeParams(Loc, Params, NumParams, 0,
-                                                  ParamTypes, OutParams);
+  return Instantiator.TransformFunctionTypeParams(Loc, Params, NumParams,
+                                                  nullptr, ParamTypes,
+                                                  OutParams);
 }
 
 /// \brief Perform substitution on the base class specifiers of the
@@ -1806,31 +1713,29 @@
                           const MultiLevelTemplateArgumentList &TemplateArgs) {
   bool Invalid = false;
   SmallVector<CXXBaseSpecifier*, 4> InstantiatedBases;
-  for (ClassTemplateSpecializationDecl::base_class_iterator
-         Base = Pattern->bases_begin(), BaseEnd = Pattern->bases_end();
-       Base != BaseEnd; ++Base) {
-    if (!Base->getType()->isDependentType()) {
-      if (const CXXRecordDecl *RD = Base->getType()->getAsCXXRecordDecl()) {
+  for (const auto Base : Pattern->bases()) {
+    if (!Base.getType()->isDependentType()) {
+      if (const CXXRecordDecl *RD = Base.getType()->getAsCXXRecordDecl()) {
         if (RD->isInvalidDecl())
           Instantiation->setInvalidDecl();
       }
-      InstantiatedBases.push_back(new (Context) CXXBaseSpecifier(*Base));
+      InstantiatedBases.push_back(new (Context) CXXBaseSpecifier(Base));
       continue;
     }
 
     SourceLocation EllipsisLoc;
     TypeSourceInfo *BaseTypeLoc;
-    if (Base->isPackExpansion()) {
+    if (Base.isPackExpansion()) {
       // This is a pack expansion. See whether we should expand it now, or
       // wait until later.
       SmallVector<UnexpandedParameterPack, 2> Unexpanded;
-      collectUnexpandedParameterPacks(Base->getTypeSourceInfo()->getTypeLoc(),
+      collectUnexpandedParameterPacks(Base.getTypeSourceInfo()->getTypeLoc(),
                                       Unexpanded);
       bool ShouldExpand = false;
       bool RetainExpansion = false;
       Optional<unsigned> NumExpansions;
-      if (CheckParameterPacksForExpansion(Base->getEllipsisLoc(), 
-                                          Base->getSourceRange(),
+      if (CheckParameterPacksForExpansion(Base.getEllipsisLoc(), 
+                                          Base.getSourceRange(),
                                           Unexpanded,
                                           TemplateArgs, ShouldExpand, 
                                           RetainExpansion,
@@ -1844,9 +1749,9 @@
         for (unsigned I = 0; I != *NumExpansions; ++I) {
             Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(*this, I);
           
-          TypeSourceInfo *BaseTypeLoc = SubstType(Base->getTypeSourceInfo(),
+          TypeSourceInfo *BaseTypeLoc = SubstType(Base.getTypeSourceInfo(),
                                                   TemplateArgs,
-                                              Base->getSourceRange().getBegin(),
+                                              Base.getSourceRange().getBegin(),
                                                   DeclarationName());
           if (!BaseTypeLoc) {
             Invalid = true;
@@ -1855,9 +1760,9 @@
           
           if (CXXBaseSpecifier *InstantiatedBase
                 = CheckBaseSpecifier(Instantiation,
-                                     Base->getSourceRange(),
-                                     Base->isVirtual(),
-                                     Base->getAccessSpecifierAsWritten(),
+                                     Base.getSourceRange(),
+                                     Base.isVirtual(),
+                                     Base.getAccessSpecifierAsWritten(),
                                      BaseTypeLoc,
                                      SourceLocation()))
             InstantiatedBases.push_back(InstantiatedBase);
@@ -1869,16 +1774,16 @@
       }
       
       // The resulting base specifier will (still) be a pack expansion.
-      EllipsisLoc = Base->getEllipsisLoc();
+      EllipsisLoc = Base.getEllipsisLoc();
       Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(*this, -1);
-      BaseTypeLoc = SubstType(Base->getTypeSourceInfo(),
+      BaseTypeLoc = SubstType(Base.getTypeSourceInfo(),
                               TemplateArgs,
-                              Base->getSourceRange().getBegin(),
+                              Base.getSourceRange().getBegin(),
                               DeclarationName());
     } else {
-      BaseTypeLoc = SubstType(Base->getTypeSourceInfo(),
+      BaseTypeLoc = SubstType(Base.getTypeSourceInfo(),
                               TemplateArgs,
-                              Base->getSourceRange().getBegin(),
+                              Base.getSourceRange().getBegin(),
                               DeclarationName());
     }
     
@@ -1889,9 +1794,9 @@
 
     if (CXXBaseSpecifier *InstantiatedBase
           = CheckBaseSpecifier(Instantiation,
-                               Base->getSourceRange(),
-                               Base->isVirtual(),
-                               Base->getAccessSpecifierAsWritten(),
+                               Base.getSourceRange(),
+                               Base.isVirtual(),
+                               Base.getAccessSpecifierAsWritten(),
                                BaseTypeLoc,
                                EllipsisLoc))
       InstantiatedBases.push_back(InstantiatedBase);
@@ -1943,7 +1848,7 @@
     S.Diag(PointOfInstantiation,
            diag::err_implicit_instantiate_member_undefined)
       << S.Context.getTypeDeclType(Instantiation);
-    S.Diag(Pattern->getLocation(), diag::note_member_of_template_here);
+    S.Diag(Pattern->getLocation(), diag::note_member_declared_at);
   } else {
     S.Diag(PointOfInstantiation, diag::err_template_instantiate_undefined)
       << (TSK != TSK_ImplicitInstantiation)
@@ -2006,7 +1911,7 @@
     Spec->setTemplateSpecializationKind(TSK);
     Spec->setPointOfInstantiation(PointOfInstantiation);
   }
-  
+
   InstantiatingTemplate Inst(*this, PointOfInstantiation, Instantiation);
   if (Inst.isInvalid())
     return true;
@@ -2028,7 +1933,12 @@
 
   // Start the definition of this instantiation.
   Instantiation->startDefinition();
-  
+
+  // The instantiation is visible here, even if it was first declared in an
+  // unimported module.
+  Instantiation->setHidden(false);
+
+  // FIXME: This loses the as-written tag kind for an explicit instantiation.
   Instantiation->setTagKind(Pattern->getTagKind());
 
   // Do substitution on the base class specifiers.
@@ -2043,9 +1953,7 @@
   LateInstantiatedAttrVec LateAttrs;
   Instantiator.enableLateAttributeInstantiation(&LateAttrs);
 
-  for (RecordDecl::decl_iterator Member = Pattern->decls_begin(),
-         MemberEnd = Pattern->decls_end();
-       Member != MemberEnd; ++Member) {
+  for (auto *Member : Pattern->decls()) {
     // Don't instantiate members not belonging in this semantic context.
     // e.g. for:
     // @code
@@ -2055,19 +1963,19 @@
     // @endcode
     // 'class B' has the template as lexical context but semantically it is
     // introduced in namespace scope.
-    if ((*Member)->getDeclContext() != Pattern)
+    if (Member->getDeclContext() != Pattern)
       continue;
 
-    if ((*Member)->isInvalidDecl()) {
+    if (Member->isInvalidDecl()) {
       Instantiation->setInvalidDecl();
       continue;
     }
 
-    Decl *NewMember = Instantiator.Visit(*Member);
+    Decl *NewMember = Instantiator.Visit(Member);
     if (NewMember) {
       if (FieldDecl *Field = dyn_cast<FieldDecl>(NewMember)) {
         Fields.push_back(Field);
-        FieldDecl *OldField = cast<FieldDecl>(*Member);
+        FieldDecl *OldField = cast<FieldDecl>(Member);
         if (OldField->getInClassInitializer())
           FieldsWithMemberInitializers.push_back(std::make_pair(OldField,
                                                                 Field));
@@ -2103,8 +2011,8 @@
   }
 
   // Finish checking fields.
-  ActOnFields(0, Instantiation->getLocation(), Instantiation, Fields, 
-              SourceLocation(), SourceLocation(), 0);
+  ActOnFields(nullptr, Instantiation->getLocation(), Instantiation, Fields,
+              SourceLocation(), SourceLocation(), nullptr);
   CheckCompletedCXXClass(Instantiation);
 
   // Attach any in-class member initializers now the class is complete.
@@ -2122,16 +2030,14 @@
       FieldDecl *NewField = FieldsWithMemberInitializers[I].second;
       Expr *OldInit = OldField->getInClassInitializer();
 
+      ActOnStartCXXInClassMemberInitializer();
       ExprResult NewInit = SubstInitializer(OldInit, TemplateArgs,
                                             /*CXXDirectInit=*/false);
-      if (NewInit.isInvalid())
-        NewField->setInvalidDecl();
-      else {
-        Expr *Init = NewInit.take();
-        assert(Init && "no-argument initializer in class");
-        assert(!isa<ParenListExpr>(Init) && "call-style init in class");
-        ActOnCXXInClassMemberInitializer(NewField, Init->getLocStart(), Init);
-      }
+      Expr *Init = NewInit.get();
+      assert((!Init || !isa<ParenListExpr>(Init)) &&
+             "call-style init in class");
+      ActOnFinishCXXInClassMemberInitializer(NewField,
+        Init ? Init->getLocStart() : SourceLocation(), Init);
     }
   }
   // Instantiate late parsed attributes, and attach them to their decls.
@@ -2159,6 +2065,8 @@
 
   ActOnFinishDelayedMemberInitializers(Instantiation);
 
+  // FIXME: We should do something similar for explicit instantiations so they
+  // end up in the right module.
   if (TSK == TSK_ImplicitInstantiation) {
     Instantiation->setLocation(Pattern->getLocation());
     Instantiation->setLocStart(Pattern->getInnerLocStart());
@@ -2248,6 +2156,10 @@
   if (Inst.isInvalid())
     return true;
 
+  // The instantiation is visible here, even if it was first declared in an
+  // unimported module.
+  Instantiation->setHidden(false);
+
   // Enter the scope of this instantiation. We don't use
   // PushDeclContext because we don't have a scope.
   ContextRAII SavedContext(*this, Instantiation);
@@ -2315,7 +2227,7 @@
     return true;
   
   ClassTemplateDecl *Template = ClassTemplateSpec->getSpecializedTemplate();
-  CXXRecordDecl *Pattern = 0;
+  CXXRecordDecl *Pattern = nullptr;
 
   // C++ [temp.class.spec.match]p1:
   //   When a class template is used in a context that requires an
@@ -2352,8 +2264,7 @@
   // If we're dealing with a member template where the template parameters
   // have been instantiated, this provides the original template parameters
   // from which the member template's parameters were instantiated.
-  SmallVector<const NamedDecl *, 4> InstantiatedTemplateParameters;
-  
+
   if (Matched.size() >= 1) {
     SmallVectorImpl<MatchResult>::iterator Best = Matched.begin();
     if (Matched.size() == 1) {
@@ -2457,11 +2368,17 @@
                               CXXRecordDecl *Instantiation,
                         const MultiLevelTemplateArgumentList &TemplateArgs,
                               TemplateSpecializationKind TSK) {
-  for (DeclContext::decl_iterator D = Instantiation->decls_begin(),
-                               DEnd = Instantiation->decls_end();
-       D != DEnd; ++D) {
+  // FIXME: We need to notify the ASTMutationListener that we did all of these
+  // things, in case we have an explicit instantiation definition in a PCM, a
+  // module, or preamble, and the declaration is in an imported AST.
+  assert(
+      (TSK == TSK_ExplicitInstantiationDefinition ||
+       TSK == TSK_ExplicitInstantiationDeclaration ||
+       (TSK == TSK_ImplicitInstantiation && Instantiation->isLocalClass())) &&
+      "Unexpected template specialization kind!");
+  for (auto *D : Instantiation->decls()) {
     bool SuppressNew = false;
-    if (FunctionDecl *Function = dyn_cast<FunctionDecl>(*D)) {
+    if (auto *Function = dyn_cast<FunctionDecl>(D)) {
       if (FunctionDecl *Pattern
             = Function->getInstantiatedFromMemberFunction()) {
         MemberSpecializationInfo *MSInfo 
@@ -2478,28 +2395,30 @@
                                                    SuppressNew) ||
             SuppressNew)
           continue;
-        
-        if (Function->isDefined())
+
+        // C++11 [temp.explicit]p8:
+        //   An explicit instantiation definition that names a class template
+        //   specialization explicitly instantiates the class template
+        //   specialization and is only an explicit instantiation definition
+        //   of members whose definition is visible at the point of
+        //   instantiation.
+        if (TSK == TSK_ExplicitInstantiationDefinition && !Pattern->isDefined())
           continue;
 
-        if (TSK == TSK_ExplicitInstantiationDefinition) {
-          // C++0x [temp.explicit]p8:
-          //   An explicit instantiation definition that names a class template
-          //   specialization explicitly instantiates the class template 
-          //   specialization and is only an explicit instantiation definition 
-          //   of members whose definition is visible at the point of 
-          //   instantiation.
-          if (!Pattern->isDefined())
-            continue;
-        
-          Function->setTemplateSpecializationKind(TSK, PointOfInstantiation);
-                      
+        Function->setTemplateSpecializationKind(TSK, PointOfInstantiation);
+
+        if (Function->isDefined()) {
+          // Let the ASTConsumer know that this function has been explicitly
+          // instantiated now, and its linkage might have changed.
+          Consumer.HandleTopLevelDecl(DeclGroupRef(Function));
+        } else if (TSK == TSK_ExplicitInstantiationDefinition) {
           InstantiateFunctionDefinition(PointOfInstantiation, Function);
-        } else {
-          Function->setTemplateSpecializationKind(TSK, PointOfInstantiation);
+        } else if (TSK == TSK_ImplicitInstantiation) {
+          PendingLocalImplicitInstantiations.push_back(
+              std::make_pair(Function, PointOfInstantiation));
         }
       }
-    } else if (VarDecl *Var = dyn_cast<VarDecl>(*D)) {
+    } else if (auto *Var = dyn_cast<VarDecl>(D)) {
       if (isa<VarTemplateSpecializationDecl>(Var))
         continue;
 
@@ -2535,7 +2454,7 @@
           Var->setTemplateSpecializationKind(TSK, PointOfInstantiation);
         }
       }      
-    } else if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(*D)) {
+    } else if (auto *Record = dyn_cast<CXXRecordDecl>(D)) {
       // Always skip the injected-class-name, along with any
       // redeclarations of nested classes, since both would cause us
       // to try to instantiate the members of a class twice.
@@ -2592,7 +2511,7 @@
       if (Pattern)
         InstantiateClassMembers(PointOfInstantiation, Pattern, TemplateArgs, 
                                 TSK);
-    } else if (EnumDecl *Enum = dyn_cast<EnumDecl>(*D)) {
+    } else if (auto *Enum = dyn_cast<EnumDecl>(D)) {
       MemberSpecializationInfo *MSInfo = Enum->getMemberSpecializationInfo();
       assert(MSInfo && "No member specialization information?");
 
@@ -2650,7 +2569,7 @@
 StmtResult
 Sema::SubstStmt(Stmt *S, const MultiLevelTemplateArgumentList &TemplateArgs) {
   if (!S)
-    return Owned(S);
+    return S;
 
   TemplateInstantiator Instantiator(*this, TemplateArgs,
                                     SourceLocation(),
@@ -2661,7 +2580,7 @@
 ExprResult
 Sema::SubstExpr(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs) {
   if (!E)
-    return Owned(E);
+    return E;
 
   TemplateInstantiator Instantiator(*this, TemplateArgs,
                                     SourceLocation(),
@@ -2764,7 +2683,7 @@
       if (const TagDecl *Tag = dyn_cast<TagDecl>(CheckD))
         CheckD = Tag->getPreviousDecl();
       else
-        CheckD = 0;
+        CheckD = nullptr;
     } while (CheckD);
     
     // If we aren't combined with our outer scope, we're done. 
@@ -2776,13 +2695,13 @@
   // deduction, we may not have values for template parameters yet.
   if (isa<NonTypeTemplateParmDecl>(D) || isa<TemplateTypeParmDecl>(D) ||
       isa<TemplateTemplateParmDecl>(D))
-    return 0;
+    return nullptr;
 
   // If we didn't find the decl, then we either have a sema bug, or we have a
   // forward reference to a label declaration.  Return null to indicate that
   // we have an uninstantiated label.
   assert(isa<LabelDecl>(D) && "declaration not instantiated in this scope");
-  return 0;
+  return nullptr;
 }
 
 void LocalInstantiationScope::InstantiatedLocal(const Decl *D, Decl *Inst) {
@@ -2829,7 +2748,7 @@
                                          const TemplateArgument **ExplicitArgs,
                                               unsigned *NumExplicitArgs) const {
   if (ExplicitArgs)
-    *ExplicitArgs = 0;
+    *ExplicitArgs = nullptr;
   if (NumExplicitArgs)
     *NumExplicitArgs = 0;
   
@@ -2847,6 +2766,6 @@
     if (!Current->CombineWithOuterScope)
       break;
   }
-  
-  return 0;
+
+  return nullptr;
 }
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index f5c4c72..accec95 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -12,19 +12,30 @@
 #include "clang/Sema/SemaInternal.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTMutationListener.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/DeclVisitor.h"
 #include "clang/AST/DependentDiagnostic.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/TypeLoc.h"
-#include "clang/Lex/Preprocessor.h"
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/PrettyDeclStackTrace.h"
 #include "clang/Sema/Template.h"
 
 using namespace clang;
 
+static bool isDeclWithinFunction(const Decl *D) {
+  const DeclContext *DC = D->getDeclContext();
+  if (DC->isFunctionOrMethod())
+    return true;
+
+  if (DC->isRecord())
+    return cast<CXXRecordDecl>(DC)->isLocalClass();
+
+  return false;
+}
+
 bool TemplateDeclInstantiator::SubstQualifier(const DeclaratorDecl *OldDecl,
                                               DeclaratorDecl *NewDecl) {
   if (!OldDecl->getQualifierLoc())
@@ -68,7 +79,7 @@
     EnterExpressionEvaluationContext Unevaluated(S, Sema::ConstantEvaluated);
     ExprResult Result = S.SubstExpr(Aligned->getAlignmentExpr(), TemplateArgs);
     if (!Result.isInvalid())
-      S.AddAlignedAttr(Aligned->getLocation(), New, Result.takeAs<Expr>(),
+      S.AddAlignedAttr(Aligned->getLocation(), New, Result.getAs<Expr>(),
                        Aligned->getSpellingListIndex(), IsPackExpansion);
   } else {
     TypeSourceInfo *Result = S.SubstType(Aligned->getAlignmentType(),
@@ -118,14 +129,46 @@
   }
 }
 
+static void instantiateDependentEnableIfAttr(
+    Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
+    const EnableIfAttr *A, const Decl *Tmpl, Decl *New) {
+  Expr *Cond = nullptr;
+  {
+    EnterExpressionEvaluationContext Unevaluated(S, Sema::Unevaluated);
+    ExprResult Result = S.SubstExpr(A->getCond(), TemplateArgs);
+    if (Result.isInvalid())
+      return;
+    Cond = Result.getAs<Expr>();
+  }
+  if (A->getCond()->isTypeDependent() && !Cond->isTypeDependent()) {
+    ExprResult Converted = S.PerformContextuallyConvertToBool(Cond);
+    if (Converted.isInvalid())
+      return;
+    Cond = Converted.get();
+  }
+
+  SmallVector<PartialDiagnosticAt, 8> Diags;
+  if (A->getCond()->isValueDependent() && !Cond->isValueDependent() &&
+      !Expr::isPotentialConstantExprUnevaluated(Cond, cast<FunctionDecl>(Tmpl),
+                                                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;
+  }
+
+  EnableIfAttr *EIA = new (S.getASTContext())
+                        EnableIfAttr(A->getLocation(), S.getASTContext(), Cond,
+                                     A->getMessage(),
+                                     A->getSpellingListIndex());
+  New->addAttr(EIA);
+}
+
 void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
                             const Decl *Tmpl, Decl *New,
                             LateInstantiatedAttrVec *LateAttrs,
                             LocalInstantiationScope *OuterMostScope) {
-  for (AttrVec::const_iterator i = Tmpl->attr_begin(), e = Tmpl->attr_end();
-       i != e; ++i) {
-    const Attr *TmplAttr = *i;
-
+  for (const auto *TmplAttr : Tmpl->attrs()) {
     // FIXME: This should be generalized to more than just the AlignedAttr.
     const AlignedAttr *Aligned = dyn_cast<AlignedAttr>(TmplAttr);
     if (Aligned && Aligned->isAlignmentDependent()) {
@@ -133,11 +176,18 @@
       continue;
     }
 
+    const EnableIfAttr *EnableIf = dyn_cast<EnableIfAttr>(TmplAttr);
+    if (EnableIf && EnableIf->getCond()->isValueDependent()) {
+      instantiateDependentEnableIfAttr(*this, TemplateArgs, EnableIf, Tmpl,
+                                       New);
+      continue;
+    }
+
     assert(!TmplAttr->isPackExpansion());
     if (TmplAttr->isLateParsed() && LateAttrs) {
       // Late parsed attributes must be instantiated and attached after the
       // enclosing class has been instantiated.  See Sema::InstantiateClass.
-      LocalInstantiationScope *Saved = 0;
+      LocalInstantiationScope *Saved = nullptr;
       if (CurrentInstantiationScope)
         Saved = CurrentInstantiationScope->cloneScopes(OuterMostScope);
       LateAttrs->push_back(LateInstantiatedAttribute(TmplAttr, Saved, New));
@@ -247,7 +297,7 @@
     NamedDecl *InstPrev = SemaRef.FindInstantiatedDecl(D->getLocation(), Prev,
                                                        TemplateArgs);
     if (!InstPrev)
-      return 0;
+      return nullptr;
 
     TypedefNameDecl *InstPrevTypedef = cast<TypedefNameDecl>(InstPrev);
 
@@ -285,11 +335,11 @@
   TemplateParameterList *TempParams = D->getTemplateParameters();
   TemplateParameterList *InstParams = SubstTemplateParams(TempParams);
   if (!InstParams)
-    return 0;
+    return nullptr;
 
   TypeAliasDecl *Pattern = D->getTemplatedDecl();
 
-  TypeAliasTemplateDecl *PrevAliasTemplate = 0;
+  TypeAliasTemplateDecl *PrevAliasTemplate = nullptr;
   if (Pattern->getPreviousDecl()) {
     DeclContext::lookup_result Found = Owner->lookup(Pattern->getDeclName());
     if (!Found.empty()) {
@@ -300,7 +350,7 @@
   TypeAliasDecl *AliasInst = cast_or_null<TypeAliasDecl>(
     InstantiateTypedefNameDecl(Pattern, /*IsTypeAlias=*/true));
   if (!AliasInst)
-    return 0;
+    return nullptr;
 
   TypeAliasTemplateDecl *Inst
     = TypeAliasTemplateDecl::Create(SemaRef.Context, Owner, D->getLocation(),
@@ -330,7 +380,7 @@
   if (const RecordType *RecordTy = D->getType()->getAs<RecordType>())
     if (RecordTy->getDecl()->isAnonymousStructOrUnion())
       if (!VisitCXXRecordDecl(cast<CXXRecordDecl>(RecordTy->getDecl())))
-        return 0;
+        return nullptr;
 
   // Do substitution on the type of the declaration
   TypeSourceInfo *DI = SemaRef.SubstType(D->getTypeSourceInfo(),
@@ -338,12 +388,12 @@
                                          D->getTypeSpecStartLoc(),
                                          D->getDeclName());
   if (!DI)
-    return 0;
+    return nullptr;
 
   if (DI->getType()->isFunctionType()) {
     SemaRef.Diag(D->getLocation(), diag::err_variable_instantiates_to_function)
       << D->isStaticDataMember() << DI->getType();
-    return 0;
+    return nullptr;
   }
 
   DeclContext *DC = Owner;
@@ -362,10 +412,19 @@
 
   // Substitute the nested name specifier, if any.
   if (SubstQualifier(D, Var))
-    return 0;
+    return nullptr;
 
   SemaRef.BuildVariableInstantiation(Var, D, TemplateArgs, LateAttrs, Owner,
                                      StartingScope, InstantiatingVarTemplate);
+
+  if (D->isNRVOVariable()) {
+    QualType ReturnType = cast<FunctionDecl>(DC)->getReturnType();
+    if (SemaRef.isCopyElisionCandidate(ReturnType, Var, false))
+      Var->setNRVOVariable(true);
+  }
+
+  Var->setImplicit(D->isImplicit());
+
   return Var;
 }
 
@@ -404,7 +463,7 @@
 
   Expr *BitWidth = D->getBitWidth();
   if (Invalid)
-    BitWidth = 0;
+    BitWidth = nullptr;
   else if (BitWidth) {
     // The bit-width expression is a constant expression.
     EnterExpressionEvaluationContext Unevaluated(SemaRef,
@@ -414,9 +473,9 @@
       = SemaRef.SubstExpr(BitWidth, TemplateArgs);
     if (InstantiatedBitWidth.isInvalid()) {
       Invalid = true;
-      BitWidth = 0;
+      BitWidth = nullptr;
     } else
-      BitWidth = InstantiatedBitWidth.takeAs<Expr>();
+      BitWidth = InstantiatedBitWidth.getAs<Expr>();
   }
 
   FieldDecl *Field = SemaRef.CheckFieldDecl(D->getDeclName(),
@@ -428,10 +487,10 @@
                                             D->getInClassInitStyle(),
                                             D->getInnerLocStart(),
                                             D->getAccess(),
-                                            0);
+                                            nullptr);
   if (!Field) {
     cast<Decl>(Owner)->setInvalidDecl();
-    return 0;
+    return nullptr;
   }
 
   SemaRef.InstantiateAttrs(TemplateArgs, D, Field, LateAttrs, StartingScope);
@@ -465,7 +524,7 @@
 
   if (DI->getType()->isVariablyModifiedType()) {
     SemaRef.Diag(D->getLocation(), diag::err_property_is_variably_modified)
-    << D->getName();
+      << D;
     Invalid = true;
   } else if (DI->getType()->isInstantiationDependentType())  {
     DI = SemaRef.SubstType(DI, TemplateArgs,
@@ -488,11 +547,9 @@
     SemaRef.MarkDeclarationsReferencedInType(D->getLocation(), DI->getType());
   }
 
-  MSPropertyDecl *Property = new (SemaRef.Context)
-      MSPropertyDecl(Owner, D->getLocation(),
-                     D->getDeclName(), DI->getType(), DI,
-                     D->getLocStart(),
-                     D->getGetterId(), D->getSetterId());
+  MSPropertyDecl *Property = MSPropertyDecl::Create(
+      SemaRef.Context, Owner, D->getLocation(), D->getDeclName(), DI->getType(),
+      DI, D->getLocStart(), D->getGetterId(), D->getSetterId());
 
   SemaRef.InstantiateAttrs(TemplateArgs, D, Property, LateAttrs,
                            StartingScope);
@@ -511,13 +568,11 @@
     new (SemaRef.Context)NamedDecl*[D->getChainingSize()];
 
   int i = 0;
-  for (IndirectFieldDecl::chain_iterator PI =
-       D->chain_begin(), PE = D->chain_end();
-       PI != PE; ++PI) {
-    NamedDecl *Next = SemaRef.FindInstantiatedDecl(D->getLocation(), *PI,
+  for (auto *PI : D->chain()) {
+    NamedDecl *Next = SemaRef.FindInstantiatedDecl(D->getLocation(), PI,
                                               TemplateArgs);
     if (!Next)
-      return 0;
+      return nullptr;
 
     NamedChain[i++] = Next;
   }
@@ -551,12 +606,12 @@
                                  D->getLocation(), DeclarationName());
     }
     if (!InstTy)
-      return 0;
+      return nullptr;
 
     FriendDecl *FD = SemaRef.CheckFriendTypeDecl(D->getLocStart(),
                                                  D->getFriendLoc(), InstTy);
     if (!FD)
-      return 0;
+      return nullptr;
 
     FD->setAccess(AS_public);
     FD->setUnsupportedFriend(D->isUnsupportedFriend());
@@ -572,7 +627,7 @@
   // objects, with the most important detail being that the target
   // decl should almost certainly not be placed in Owner.
   Decl *NewND = Visit(ND);
-  if (!NewND) return 0;
+  if (!NewND) return nullptr;
 
   FriendDecl *FD =
     FriendDecl::Create(SemaRef.Context, Owner, D->getLocation(),
@@ -593,7 +648,7 @@
   ExprResult InstantiatedAssertExpr
     = SemaRef.SubstExpr(AssertExpr, TemplateArgs);
   if (InstantiatedAssertExpr.isInvalid())
-    return 0;
+    return nullptr;
 
   return SemaRef.BuildStaticAssertDeclaration(D->getLocation(),
                                               InstantiatedAssertExpr.get(),
@@ -603,12 +658,12 @@
 }
 
 Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {
-  EnumDecl *PrevDecl = 0;
+  EnumDecl *PrevDecl = nullptr;
   if (D->getPreviousDecl()) {
     NamedDecl *Prev = SemaRef.FindInstantiatedDecl(D->getLocation(),
                                                    D->getPreviousDecl(),
                                                    TemplateArgs);
-    if (!Prev) return 0;
+    if (!Prev) return nullptr;
     PrevDecl = cast<EnumDecl>(Prev);
   }
 
@@ -639,7 +694,9 @@
 
   Enum->setInstantiationOfMemberEnum(D, TSK_ImplicitInstantiation);
   Enum->setAccess(D->getAccess());
-  if (SubstQualifier(D, Enum)) return 0;
+  // Forward the mangling number from the template to the instantiated decl.
+  SemaRef.Context.setManglingNumber(Enum, SemaRef.Context.getManglingNumber(D));
+  if (SubstQualifier(D, Enum)) return nullptr;
   Owner->addDecl(Enum);
 
   EnumDecl *Def = D->getDefinition();
@@ -657,19 +714,17 @@
     }
   }
 
-  if (D->getDeclContext()->isFunctionOrMethod())
-    SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Enum);
-
   // C++11 [temp.inst]p1: The implicit instantiation of a class template
   // specialization causes the implicit instantiation of the declarations, but
   // not the definitions of scoped member enumerations.
-  // FIXME: There appears to be no wording for what happens for an enum defined
-  // within a block scope, but we treat that much like a member template. Only
-  // instantiate the definition when visiting the definition in that case, since
-  // we will visit all redeclarations.
-  if (!Enum->isScoped() && Def &&
-      (!D->getDeclContext()->isFunctionOrMethod() || D->isCompleteDefinition()))
+  //
+  // DR1484 clarifies that enumeration definitions inside of a template
+  // declaration aren't considered entities that can be separately instantiated
+  // from the rest of the entity they are declared inside of.
+  if (isDeclWithinFunction(D) ? D == Def : Def && !Enum->isScoped()) {
+    SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Enum);
     InstantiateEnumDefinition(Enum, Def);
+  }
 
   return Enum;
 }
@@ -683,12 +738,10 @@
 
   SmallVector<Decl*, 4> Enumerators;
 
-  EnumConstantDecl *LastEnumConst = 0;
-  for (EnumDecl::enumerator_iterator EC = Pattern->enumerator_begin(),
-         ECEnd = Pattern->enumerator_end();
-       EC != ECEnd; ++EC) {
+  EnumConstantDecl *LastEnumConst = nullptr;
+  for (auto *EC : Pattern->enumerators()) {
     // The specified value for the enumerator.
-    ExprResult Value = SemaRef.Owned((Expr *)0);
+    ExprResult Value((Expr *)nullptr);
     if (Expr *UninstValue = EC->getInitExpr()) {
       // The enumerator's value expression is a constant expression.
       EnterExpressionEvaluationContext Unevaluated(SemaRef,
@@ -700,7 +753,7 @@
     // Drop the initial value and continue.
     bool isInvalid = false;
     if (Value.isInvalid()) {
-      Value = SemaRef.Owned((Expr *)0);
+      Value = nullptr;
       isInvalid = true;
     }
 
@@ -716,7 +769,7 @@
     }
 
     if (EnumConst) {
-      SemaRef.InstantiateAttrs(TemplateArgs, *EC, EnumConst);
+      SemaRef.InstantiateAttrs(TemplateArgs, EC, EnumConst);
 
       EnumConst->setAccess(Enum->getAccess());
       Enum->addDecl(EnumConst);
@@ -727,7 +780,7 @@
           !Enum->isScoped()) {
         // If the enumeration is within a function or method, record the enum
         // constant as a local.
-        SemaRef.CurrentInstantiationScope->InstantiatedLocal(*EC, EnumConst);
+        SemaRef.CurrentInstantiationScope->InstantiatedLocal(EC, EnumConst);
       }
     }
   }
@@ -736,7 +789,7 @@
   SemaRef.ActOnEnumBody(Enum->getLocation(), SourceLocation(),
                         Enum->getRBraceLoc(), Enum,
                         Enumerators,
-                        0, 0);
+                        nullptr, nullptr);
 }
 
 Decl *TemplateDeclInstantiator::VisitEnumConstantDecl(EnumConstantDecl *D) {
@@ -752,7 +805,7 @@
   TemplateParameterList *TempParams = D->getTemplateParameters();
   TemplateParameterList *InstParams = SubstTemplateParams(TempParams);
   if (!InstParams)
-    return NULL;
+    return nullptr;
 
   CXXRecordDecl *Pattern = D->getTemplatedDecl();
 
@@ -764,11 +817,11 @@
     QualifierLoc = SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc,
                                                        TemplateArgs);
     if (!QualifierLoc)
-      return 0;
+      return nullptr;
   }
 
-  CXXRecordDecl *PrevDecl = 0;
-  ClassTemplateDecl *PrevClassTemplate = 0;
+  CXXRecordDecl *PrevDecl = nullptr;
+  ClassTemplateDecl *PrevClassTemplate = nullptr;
 
   if (!isFriend && Pattern->getPreviousDecl()) {
     DeclContext::lookup_result Found = Owner->lookup(Pattern->getDeclName());
@@ -789,7 +842,7 @@
       CXXScopeSpec SS;
       SS.Adopt(QualifierLoc);
       DC = SemaRef.computeDeclContext(SS);
-      if (!DC) return 0;
+      if (!DC) return nullptr;
     } else {
       DC = SemaRef.FindInstantiatedContext(Pattern->getLocation(),
                                            Pattern->getDeclContext(),
@@ -812,7 +865,7 @@
       SemaRef.Diag(Pattern->getLocation(), diag::err_not_tag_in_scope)
         << D->getTemplatedDecl()->getTagKind() << Pattern->getDeclName() << DC
         << QualifierLoc.getSourceRange();
-      return 0;
+      return nullptr;
     }
 
     bool AdoptedPreviousTemplateParams = false;
@@ -834,11 +887,7 @@
         if (DCParent->isNamespace() &&
             cast<NamespaceDecl>(DCParent)->getIdentifier() &&
             cast<NamespaceDecl>(DCParent)->getIdentifier()->isStr("tr1")) {
-          DeclContext *DCParent2 = DCParent->getParent();
-          if (DCParent2->isNamespace() &&
-              cast<NamespaceDecl>(DCParent2)->getIdentifier() &&
-              cast<NamespaceDecl>(DCParent2)->getIdentifier()->isStr("std") &&
-              DCParent2->getParent()->isTranslationUnit())
+          if (cast<Decl>(DCParent)->isInStdNamespace())
             Complain = false;
         }
       }
@@ -851,7 +900,7 @@
                                                   Complain,
                                                   Sema::TPL_TemplateMatch)) {
         if (Complain)
-          return 0;
+          return nullptr;
 
         AdoptedPreviousTemplateParams = true;
         InstParams = PrevParams;
@@ -862,7 +911,7 @@
       if (!AdoptedPreviousTemplateParams &&
           SemaRef.CheckTemplateParameterList(InstParams, PrevParams,
                                              Sema::TPC_ClassTemplate))
-        return 0;
+        return nullptr;
     }
   }
 
@@ -939,12 +988,12 @@
   DeclContext::lookup_result Found
     = Owner->lookup(ClassTemplate->getDeclName());
   if (Found.empty())
-    return 0;
+    return nullptr;
 
   ClassTemplateDecl *InstClassTemplate
     = dyn_cast<ClassTemplateDecl>(Found.front());
   if (!InstClassTemplate)
-    return 0;
+    return nullptr;
 
   if (ClassTemplatePartialSpecializationDecl *Result
         = InstClassTemplate->findPartialSpecInstantiatedFromMember(D))
@@ -963,10 +1012,10 @@
   TemplateParameterList *TempParams = D->getTemplateParameters();
   TemplateParameterList *InstParams = SubstTemplateParams(TempParams);
   if (!InstParams)
-    return NULL;
+    return nullptr;
 
   VarDecl *Pattern = D->getTemplatedDecl();
-  VarTemplateDecl *PrevVarTemplate = 0;
+  VarTemplateDecl *PrevVarTemplate = nullptr;
 
   if (Pattern->getPreviousDecl()) {
     DeclContext::lookup_result Found = Owner->lookup(Pattern->getDeclName());
@@ -982,8 +1031,9 @@
 
   VarTemplateDecl *Inst = VarTemplateDecl::Create(
       SemaRef.Context, DC, D->getLocation(), D->getIdentifier(), InstParams,
-      VarInst, PrevVarTemplate);
+      VarInst);
   VarInst->setDescribedVarTemplate(Inst);
+  Inst->setPreviousDecl(PrevVarTemplate);
 
   Inst->setAccess(D->getAccess());
   if (!PrevVarTemplate)
@@ -1043,9 +1093,9 @@
   TemplateParameterList *TempParams = D->getTemplateParameters();
   TemplateParameterList *InstParams = SubstTemplateParams(TempParams);
   if (!InstParams)
-    return NULL;
+    return nullptr;
 
-  FunctionDecl *Instantiated = 0;
+  FunctionDecl *Instantiated = nullptr;
   if (CXXMethodDecl *DMethod = dyn_cast<CXXMethodDecl>(D->getTemplatedDecl()))
     Instantiated = cast_or_null<FunctionDecl>(VisitCXXMethodDecl(DMethod,
                                                                  InstParams));
@@ -1055,7 +1105,7 @@
                                                                 InstParams));
 
   if (!Instantiated)
-    return 0;
+    return nullptr;
 
   // Link the instantiated function template declaration to the function
   // template from which it was instantiated.
@@ -1085,14 +1135,14 @@
 }
 
 Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) {
-  CXXRecordDecl *PrevDecl = 0;
+  CXXRecordDecl *PrevDecl = nullptr;
   if (D->isInjectedClassName())
     PrevDecl = cast<CXXRecordDecl>(Owner);
   else if (D->getPreviousDecl()) {
     NamedDecl *Prev = SemaRef.FindInstantiatedDecl(D->getLocation(),
                                                    D->getPreviousDecl(),
                                                    TemplateArgs);
-    if (!Prev) return 0;
+    if (!Prev) return nullptr;
     PrevDecl = cast<CXXRecordDecl>(Prev);
   }
 
@@ -1103,7 +1153,7 @@
 
   // Substitute the nested name specifier, if any.
   if (SubstQualifier(D, Record))
-    return 0;
+    return nullptr;
 
   Record->setImplicit(D->isImplicit());
   // FIXME: Check against AS_none is an ugly hack to work around the issue that
@@ -1120,13 +1170,27 @@
     Record->setObjectOfFriendDecl();
 
   // Make sure that anonymous structs and unions are recorded.
-  if (D->isAnonymousStructOrUnion()) {
+  if (D->isAnonymousStructOrUnion())
     Record->setAnonymousStructOrUnion(true);
-    if (Record->getDeclContext()->getRedeclContext()->isFunctionOrMethod())
-      SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Record);
-  }
+
+  if (D->isLocalClass())
+    SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Record);
+
+  // Forward the mangling number from the template to the instantiated decl.
+  SemaRef.Context.setManglingNumber(Record,
+                                    SemaRef.Context.getManglingNumber(D));
 
   Owner->addDecl(Record);
+
+  // DR1484 clarifies that the members of a local class are instantiated as part
+  // of the instantiation of their enclosing entity.
+  if (D->isCompleteDefinition() && D->isLocalClass()) {
+    SemaRef.InstantiateClass(D->getLocation(), Record, D, TemplateArgs,
+                             TSK_ImplicitInstantiation,
+                             /*Complain=*/true);
+    SemaRef.InstantiateClassMembers(D->getLocation(), Record, TemplateArgs,
+                                    TSK_ImplicitInstantiation);
+  }
   return Record;
 }
 
@@ -1148,15 +1212,14 @@
 
   FunctionProtoType::ExtProtoInfo NewEPI = NewFunc->getExtProtoInfo();
   NewEPI.ExtInfo = OrigFunc->getExtInfo();
-  return Context.getFunctionType(NewFunc->getResultType(),
-                                 NewFunc->getArgTypes(), NewEPI);
+  return Context.getFunctionType(NewFunc->getReturnType(),
+                                 NewFunc->getParamTypes(), NewEPI);
 }
 
 /// Normal class members are of more specific types and therefore
 /// don't make it here.  This function serves two purposes:
 ///   1) instantiating function templates
 ///   2) substituting friend declarations
-/// FIXME: preserve function definitions in case #2
 Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
                                        TemplateParameterList *TemplateParams) {
   // Check whether there is already a function template specialization for
@@ -1165,10 +1228,9 @@
   if (FunctionTemplate && !TemplateParams) {
     ArrayRef<TemplateArgument> Innermost = TemplateArgs.getInnermost();
 
-    void *InsertPos = 0;
+    void *InsertPos = nullptr;
     FunctionDecl *SpecFunc
-      = FunctionTemplate->findSpecialization(Innermost.begin(), Innermost.size(),
-                                             InsertPos);
+      = FunctionTemplate->findSpecialization(Innermost, InsertPos);
 
     // If we already have a function template specialization, return it.
     if (SpecFunc)
@@ -1181,7 +1243,7 @@
   else
     isFriend = (D->getFriendObjectKind() != Decl::FOK_None);
 
-  bool MergeWithParentScope = (TemplateParams != 0) ||
+  bool MergeWithParentScope = (TemplateParams != nullptr) ||
     Owner->isFunctionOrMethod() ||
     !(isa<Decl>(Owner) &&
       cast<Decl>(Owner)->isDefinedOutsideFunctionOrMethod());
@@ -1190,7 +1252,7 @@
   SmallVector<ParmVarDecl *, 4> Params;
   TypeSourceInfo *TInfo = SubstFunctionType(D, Params);
   if (!TInfo)
-    return 0;
+    return nullptr;
   QualType T = adjustFunctionTypeForInstantiation(SemaRef.Context, D, TInfo);
 
   NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc();
@@ -1198,7 +1260,7 @@
     QualifierLoc = SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc,
                                                        TemplateArgs);
     if (!QualifierLoc)
-      return 0;
+      return nullptr;
   }
 
   // If we're instantiating a local function declaration, put the result
@@ -1212,7 +1274,7 @@
     CXXScopeSpec SS;
     SS.Adopt(QualifierLoc);
     DC = SemaRef.computeDeclContext(SS);
-    if (!DC) return 0;
+    if (!DC) return nullptr;
   } else {
     DC = SemaRef.FindInstantiatedContext(D->getLocation(), D->getDeclContext(),
                                          TemplateArgs);
@@ -1286,7 +1348,7 @@
                             TemplateArgumentList::CreateCopy(SemaRef.Context,
                                                              Innermost.begin(),
                                                              Innermost.size()),
-                                                /*InsertPos=*/0);
+                                                /*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
@@ -1320,14 +1382,14 @@
                                           Info->getRAngleLoc());
     if (SemaRef.Subst(Info->getTemplateArgs(), Info->getNumTemplateArgs(),
                       ExplicitArgs, TemplateArgs))
-      return 0;
+      return nullptr;
 
     // Map the candidate templates to their instantiations.
     for (unsigned I = 0, E = Info->getNumTemplates(); I != E; ++I) {
       Decl *Temp = SemaRef.FindInstantiatedDecl(D->getLocation(),
                                                 Info->getTemplate(I),
                                                 TemplateArgs);
-      if (!Temp) return 0;
+      if (!Temp) return nullptr;
 
       Previous.addDecl(cast<FunctionTemplateDecl>(Temp));
     }
@@ -1353,7 +1415,7 @@
       Previous.clear();
   }
 
-  SemaRef.CheckFunctionDeclaration(/*Scope*/ 0, Function, Previous,
+  SemaRef.CheckFunctionDeclaration(/*Scope*/ nullptr, Function, Previous,
                                    isExplicitSpecialization);
 
   NamedDecl *PrincipalDecl = (TemplateParams
@@ -1366,73 +1428,56 @@
     PrincipalDecl->setObjectOfFriendDecl();
     DC->makeDeclVisibleInContext(PrincipalDecl);
 
-    bool queuedInstantiation = false;
+    bool QueuedInstantiation = false;
 
-    // C++98 [temp.friend]p5: When a function is defined in a friend function
-    //   declaration in a class template, the function is defined at each
-    //   instantiation of the class template. The function is defined even if it
-    //   is never used.
-    // C++11 [temp.friend]p4: When a function is defined in a friend function
-    //   declaration in a class template, the function is instantiated when the
-    //   function is odr-used.
-    //
-    // If -Wc++98-compat is enabled, we go through the motions of checking for a
-    // redefinition, but don't instantiate the function.
-    if ((!SemaRef.getLangOpts().CPlusPlus11 ||
-         SemaRef.Diags.getDiagnosticLevel(
-             diag::warn_cxx98_compat_friend_redefinition,
-             Function->getLocation())
-           != DiagnosticsEngine::Ignored) &&
-        D->isThisDeclarationADefinition()) {
+    // C++11 [temp.friend]p4 (DR329):
+    //   When a function is defined in a friend function declaration in a class
+    //   template, the function is instantiated when the function is odr-used.
+    //   The same restrictions on multiple declarations and definitions that
+    //   apply to non-template function declarations and definitions also apply
+    //   to these implicit definitions.
+    if (D->isThisDeclarationADefinition()) {
       // Check for a function body.
-      const FunctionDecl *Definition = 0;
+      const FunctionDecl *Definition = nullptr;
       if (Function->isDefined(Definition) &&
           Definition->getTemplateSpecializationKind() == TSK_Undeclared) {
-        SemaRef.Diag(Function->getLocation(),
-                     SemaRef.getLangOpts().CPlusPlus11 ?
-                       diag::warn_cxx98_compat_friend_redefinition :
-                       diag::err_redefinition) << Function->getDeclName();
+        SemaRef.Diag(Function->getLocation(), diag::err_redefinition)
+            << Function->getDeclName();
         SemaRef.Diag(Definition->getLocation(), diag::note_previous_definition);
-        if (!SemaRef.getLangOpts().CPlusPlus11)
-          Function->setInvalidDecl();
       }
       // Check for redefinitions due to other instantiations of this or
       // a similar friend function.
-      else for (FunctionDecl::redecl_iterator R = Function->redecls_begin(),
-                                           REnd = Function->redecls_end();
-                R != REnd; ++R) {
-        if (*R == Function)
+      else for (auto R : Function->redecls()) {
+        if (R == Function)
           continue;
-        switch (R->getFriendObjectKind()) {
-        case Decl::FOK_None:
-          if (!SemaRef.getLangOpts().CPlusPlus11 &&
-              !queuedInstantiation && R->isUsed(false)) {
-            if (MemberSpecializationInfo *MSInfo
-                = Function->getMemberSpecializationInfo()) {
-              if (MSInfo->getPointOfInstantiation().isInvalid()) {
-                SourceLocation Loc = R->getLocation(); // FIXME
-                MSInfo->setPointOfInstantiation(Loc);
-                SemaRef.PendingLocalImplicitInstantiations.push_back(
-                                                 std::make_pair(Function, Loc));
-                queuedInstantiation = true;
-              }
+
+        // If some prior declaration of this function has been used, we need
+        // to instantiate its definition.
+        if (!QueuedInstantiation && R->isUsed(false)) {
+          if (MemberSpecializationInfo *MSInfo =
+                  Function->getMemberSpecializationInfo()) {
+            if (MSInfo->getPointOfInstantiation().isInvalid()) {
+              SourceLocation Loc = R->getLocation(); // FIXME
+              MSInfo->setPointOfInstantiation(Loc);
+              SemaRef.PendingLocalImplicitInstantiations.push_back(
+                                               std::make_pair(Function, Loc));
+              QueuedInstantiation = true;
             }
           }
-          break;
-        default:
-          if (const FunctionDecl *RPattern
-              = R->getTemplateInstantiationPattern())
+        }
+
+        // If some prior declaration of this function was a friend with an
+        // uninstantiated definition, reject it.
+        if (R->getFriendObjectKind()) {
+          if (const FunctionDecl *RPattern =
+                  R->getTemplateInstantiationPattern()) {
             if (RPattern->isDefined(RPattern)) {
-              SemaRef.Diag(Function->getLocation(),
-                           SemaRef.getLangOpts().CPlusPlus11 ?
-                             diag::warn_cxx98_compat_friend_redefinition :
-                             diag::err_redefinition)
+              SemaRef.Diag(Function->getLocation(), diag::err_redefinition)
                 << Function->getDeclName();
               SemaRef.Diag(R->getLocation(), diag::note_previous_definition);
-              if (!SemaRef.getLangOpts().CPlusPlus11)
-                Function->setInvalidDecl();
               break;
             }
+          }
         }
       }
     }
@@ -1460,11 +1505,9 @@
     // specialization for this particular set of template arguments.
     ArrayRef<TemplateArgument> Innermost = TemplateArgs.getInnermost();
 
-    void *InsertPos = 0;
+    void *InsertPos = nullptr;
     FunctionDecl *SpecFunc
-      = FunctionTemplate->findSpecialization(Innermost.begin(), 
-                                             Innermost.size(),
-                                             InsertPos);
+      = FunctionTemplate->findSpecialization(Innermost, InsertPos);
 
     // If we already have a function template specialization, return it.
     if (SpecFunc)
@@ -1477,7 +1520,7 @@
   else
     isFriend = (D->getFriendObjectKind() != Decl::FOK_None);
 
-  bool MergeWithParentScope = (TemplateParams != 0) ||
+  bool MergeWithParentScope = (TemplateParams != nullptr) ||
     !(isa<Decl>(Owner) &&
       cast<Decl>(Owner)->isDefinedOutsideFunctionOrMethod());
   LocalInstantiationScope Scope(SemaRef, MergeWithParentScope);
@@ -1491,7 +1534,7 @@
       TemplateParameterList *TempParams = D->getTemplateParameterList(I);
       TemplateParameterList *InstParams = SubstTemplateParams(TempParams);
       if (!InstParams)
-        return NULL;
+        return nullptr;
       TempParamLists[I] = InstParams;
     }
   }
@@ -1499,7 +1542,7 @@
   SmallVector<ParmVarDecl *, 4> Params;
   TypeSourceInfo *TInfo = SubstFunctionType(D, Params);
   if (!TInfo)
-    return 0;
+    return nullptr;
   QualType T = adjustFunctionTypeForInstantiation(SemaRef.Context, D, TInfo);
 
   NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc();
@@ -1507,7 +1550,7 @@
     QualifierLoc = SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc,
                                                  TemplateArgs);
     if (!QualifierLoc)
-      return 0;
+      return nullptr;
   }
 
   DeclContext *DC = Owner;
@@ -1518,18 +1561,18 @@
       DC = SemaRef.computeDeclContext(SS);
 
       if (DC && SemaRef.RequireCompleteDeclContext(SS, DC))
-        return 0;
+        return nullptr;
     } else {
       DC = SemaRef.FindInstantiatedContext(D->getLocation(),
                                            D->getDeclContext(),
                                            TemplateArgs);
     }
-    if (!DC) return 0;
+    if (!DC) return nullptr;
   }
 
   // Build the instantiated method declaration.
   CXXRecordDecl *Record = cast<CXXRecordDecl>(DC);
-  CXXMethodDecl *Method = 0;
+  CXXMethodDecl *Method = nullptr;
 
   SourceLocation StartLoc = D->getInnerLocStart();
   DeclarationNameInfo NameInfo
@@ -1555,7 +1598,7 @@
         Sema::InstantiatingTemplate Inst(SemaRef, Constructor->getLocation(),
                                          Inh);
         if (Inst.isInvalid())
-          return 0;
+          return nullptr;
         Sema::ContextRAII SavedContext(SemaRef, Inh->getDeclContext());
         LocalInstantiationScope LocalScope(SemaRef);
 
@@ -1566,7 +1609,7 @@
         Inh = cast_or_null<CXXConstructorDecl>(
             SemaRef.SubstDecl(Inh, Inh->getDeclContext(), InheritedArgs));
         if (!Inh)
-          return 0;
+          return nullptr;
       }
       cast<CXXConstructorDecl>(Method)->setInheritedConstructor(Inh);
     }
@@ -1627,7 +1670,7 @@
                          TemplateArgumentList::CreateCopy(SemaRef.Context,
                                                           Innermost.begin(),
                                                           Innermost.size()),
-                                              /*InsertPos=*/0);
+                                              /*InsertPos=*/nullptr);
   } else if (!isFriend) {
     // Record that this is an instantiation of a member function.
     Method->setInstantiationOfMemberFunction(D, TSK_ImplicitInstantiation);
@@ -1670,7 +1713,7 @@
   }
 
   if (!IsClassScopeSpecialization)
-    SemaRef.CheckFunctionDeclaration(0, Method, Previous, false);
+    SemaRef.CheckFunctionDeclaration(nullptr, Method, Previous, false);
 
   if (D->isPure())
     SemaRef.CheckPureMethod(Method, SourceRange());
@@ -1788,13 +1831,13 @@
                                                D->getLocation(),
                                                D->getDeclName());
       if (!NewDI)
-        return 0;
+        return nullptr;
 
       ExpandedParameterPackTypesAsWritten.push_back(NewDI);
       QualType NewT =SemaRef.CheckNonTypeTemplateParameterType(NewDI->getType(),
                                                               D->getLocation());
       if (NewT.isNull())
-        return 0;
+        return nullptr;
       ExpandedParameterPackTypes.push_back(NewT);
     }
 
@@ -1823,7 +1866,7 @@
                                                 TemplateArgs,
                                                 Expand, RetainExpansion,
                                                 NumExpansions))
-      return 0;
+      return nullptr;
 
     if (Expand) {
       for (unsigned I = 0; I != *NumExpansions; ++I) {
@@ -1832,14 +1875,14 @@
                                                   D->getLocation(),
                                                   D->getDeclName());
         if (!NewDI)
-          return 0;
+          return nullptr;
 
         ExpandedParameterPackTypesAsWritten.push_back(NewDI);
         QualType NewT = SemaRef.CheckNonTypeTemplateParameterType(
                                                               NewDI->getType(),
                                                               D->getLocation());
         if (NewT.isNull())
-          return 0;
+          return nullptr;
         ExpandedParameterPackTypes.push_back(NewT);
       }
 
@@ -1857,12 +1900,12 @@
                                                      D->getLocation(),
                                                      D->getDeclName());
       if (!NewPattern)
-        return 0;
+        return nullptr;
 
       DI = SemaRef.CheckPackExpansion(NewPattern, Expansion.getEllipsisLoc(),
                                       NumExpansions);
       if (!DI)
-        return 0;
+        return nullptr;
 
       T = DI->getType();
     }
@@ -1871,7 +1914,7 @@
     DI = SemaRef.SubstType(D->getTypeSourceInfo(), TemplateArgs,
                            D->getLocation(), D->getDeclName());
     if (!DI)
-      return 0;
+      return nullptr;
 
     // Check that this type is acceptable for a non-type template parameter.
     T = SemaRef.CheckNonTypeTemplateParameterType(DI->getType(),
@@ -1957,7 +2000,7 @@
       TemplateParameterList *Expansion =
         SubstTemplateParams(D->getExpansionTemplateParameters(I));
       if (!Expansion)
-        return 0;
+        return nullptr;
       ExpandedParams.push_back(Expansion);
     }
 
@@ -1982,7 +2025,7 @@
                                                 TemplateArgs,
                                                 Expand, RetainExpansion,
                                                 NumExpansions))
-      return 0;
+      return nullptr;
 
     if (Expand) {
       for (unsigned I = 0; I != *NumExpansions; ++I) {
@@ -1990,7 +2033,7 @@
         LocalInstantiationScope Scope(SemaRef);
         TemplateParameterList *Expansion = SubstTemplateParams(TempParams);
         if (!Expansion)
-          return 0;
+          return nullptr;
         ExpandedParams.push_back(Expansion);
       }
 
@@ -2007,7 +2050,7 @@
       LocalInstantiationScope Scope(SemaRef);
       InstParams = SubstTemplateParams(TempParams);
       if (!InstParams)
-        return 0;
+        return nullptr;
     }
   } else {
     // Perform the actual substitution of template parameters within a new,
@@ -2015,7 +2058,7 @@
     LocalInstantiationScope Scope(SemaRef);
     InstParams = SubstTemplateParams(TempParams);
     if (!InstParams)
-      return 0;
+      return nullptr;
   }
 
   // Build the template template parameter.
@@ -2092,7 +2135,7 @@
     = SemaRef.SubstNestedNameSpecifierLoc(D->getQualifierLoc(),
                                           TemplateArgs);
   if (!QualifierLoc)
-    return 0;
+    return nullptr;
 
   // The name info is non-dependent, so no transformation
   // is required.
@@ -2127,7 +2170,7 @@
   }
 
   if (!NewUD->isInvalidDecl() &&
-      SemaRef.CheckUsingDeclQualifier(D->getUsingLoc(), SS,
+      SemaRef.CheckUsingDeclQualifier(D->getUsingLoc(), SS, NameInfo,
                                       D->getLocation()))
     NewUD->setInvalidDecl();
 
@@ -2140,24 +2183,21 @@
     return NewUD;
 
   if (NameInfo.getName().getNameKind() == DeclarationName::CXXConstructorName) {
-    if (SemaRef.CheckInheritingConstructorUsingDecl(NewUD))
-      NewUD->setInvalidDecl();
+    SemaRef.CheckInheritingConstructorUsingDecl(NewUD);
     return NewUD;
   }
 
   bool isFunctionScope = Owner->isFunctionOrMethod();
 
   // Process the shadow decls.
-  for (UsingDecl::shadow_iterator I = D->shadow_begin(), E = D->shadow_end();
-         I != E; ++I) {
-    UsingShadowDecl *Shadow = *I;
+  for (auto *Shadow : D->shadows()) {
     NamedDecl *InstTarget =
         cast_or_null<NamedDecl>(SemaRef.FindInstantiatedDecl(
             Shadow->getLocation(), Shadow->getTargetDecl(), TemplateArgs));
     if (!InstTarget)
-      return 0;
+      return nullptr;
 
-    UsingShadowDecl *PrevDecl = 0;
+    UsingShadowDecl *PrevDecl = nullptr;
     if (CheckRedeclaration) {
       if (SemaRef.CheckUsingShadowDecl(NewUD, InstTarget, Prev, PrevDecl))
         continue;
@@ -2167,7 +2207,8 @@
     }
 
     UsingShadowDecl *InstShadow =
-        SemaRef.BuildUsingShadowDecl(/*Scope*/0, NewUD, InstTarget, PrevDecl);
+        SemaRef.BuildUsingShadowDecl(/*Scope*/nullptr, NewUD, InstTarget,
+                                     PrevDecl);
     SemaRef.Context.setInstantiatedFromUsingShadowDecl(InstShadow, Shadow);
 
     if (isFunctionScope)
@@ -2179,7 +2220,7 @@
 
 Decl *TemplateDeclInstantiator::VisitUsingShadowDecl(UsingShadowDecl *D) {
   // Ignore these;  we handle them in bulk when processing the UsingDecl.
-  return 0;
+  return nullptr;
 }
 
 Decl * TemplateDeclInstantiator
@@ -2188,7 +2229,7 @@
     = SemaRef.SubstNestedNameSpecifierLoc(D->getQualifierLoc(),
                                           TemplateArgs);
   if (!QualifierLoc)
-    return 0;
+    return nullptr;
 
   CXXScopeSpec SS;
   SS.Adopt(QualifierLoc);
@@ -2197,8 +2238,8 @@
   // Hence, no transformation is required for it.
   DeclarationNameInfo NameInfo(D->getDeclName(), D->getLocation());
   NamedDecl *UD =
-    SemaRef.BuildUsingDeclaration(/*Scope*/ 0, D->getAccess(),
-                                  D->getUsingLoc(), SS, NameInfo, 0,
+    SemaRef.BuildUsingDeclaration(/*Scope*/ nullptr, D->getAccess(),
+                                  D->getUsingLoc(), SS, NameInfo, nullptr,
                                   /*instantiation*/ true,
                                   /*typename*/ true, D->getTypenameLoc());
   if (UD)
@@ -2212,7 +2253,7 @@
   NestedNameSpecifierLoc QualifierLoc
       = SemaRef.SubstNestedNameSpecifierLoc(D->getQualifierLoc(), TemplateArgs);
   if (!QualifierLoc)
-    return 0;
+    return nullptr;
 
   CXXScopeSpec SS;
   SS.Adopt(QualifierLoc);
@@ -2221,8 +2262,8 @@
     = SemaRef.SubstDeclarationNameInfo(D->getNameInfo(), TemplateArgs);
 
   NamedDecl *UD =
-    SemaRef.BuildUsingDeclaration(/*Scope*/ 0, D->getAccess(),
-                                  D->getUsingLoc(), SS, NameInfo, 0,
+    SemaRef.BuildUsingDeclaration(/*Scope*/ nullptr, D->getAccess(),
+                                  D->getUsingLoc(), SS, NameInfo, nullptr,
                                   /*instantiation*/ true,
                                   /*typename*/ false, SourceLocation());
   if (UD)
@@ -2236,13 +2277,13 @@
                                      ClassScopeFunctionSpecializationDecl *Decl) {
   CXXMethodDecl *OldFD = Decl->getSpecialization();
   CXXMethodDecl *NewFD = cast<CXXMethodDecl>(VisitCXXMethodDecl(OldFD,
-                                                                0, true));
+                                                                nullptr, true));
 
   LookupResult Previous(SemaRef, NewFD->getNameInfo(), Sema::LookupOrdinaryName,
                         Sema::ForRedeclaration);
 
   TemplateArgumentListInfo TemplateArgs;
-  TemplateArgumentListInfo* TemplateArgsPtr = 0;
+  TemplateArgumentListInfo *TemplateArgsPtr = nullptr;
   if (Decl->hasExplicitTemplateArgs()) {
     TemplateArgs = Decl->templateArgs();
     TemplateArgsPtr = &TemplateArgs;
@@ -2266,10 +2307,8 @@
 Decl *TemplateDeclInstantiator::VisitOMPThreadPrivateDecl(
                                      OMPThreadPrivateDecl *D) {
   SmallVector<Expr *, 5> Vars;
-  for (ArrayRef<Expr *>::iterator I = D->varlist_begin(),
-                                  E = D->varlist_end();
-       I != E; ++I) {
-    Expr *Var = SemaRef.SubstExpr(*I, TemplateArgs).take();
+  for (auto *I : D->varlists()) {
+    Expr *Var = SemaRef.SubstExpr(I, TemplateArgs).get();
     assert(isa<DeclRefExpr>(Var) && "threadprivate arg is not a DeclRefExpr");
     Vars.push_back(Var);
   }
@@ -2277,15 +2316,18 @@
   OMPThreadPrivateDecl *TD =
     SemaRef.CheckOMPThreadPrivateDecl(D->getLocation(), Vars);
 
+  TD->setAccess(AS_public);
+  Owner->addDecl(TD);
+
   return TD;
 }
 
 Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D) {
-  return VisitFunctionDecl(D, 0);
+  return VisitFunctionDecl(D, nullptr);
 }
 
 Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D) {
-  return VisitCXXMethodDecl(D, 0);
+  return VisitCXXMethodDecl(D, nullptr);
 }
 
 Decl *TemplateDeclInstantiator::VisitRecordDecl(RecordDecl *D) {
@@ -2295,8 +2337,143 @@
 Decl *
 TemplateDeclInstantiator::VisitClassTemplateSpecializationDecl(
     ClassTemplateSpecializationDecl *D) {
-  llvm_unreachable("Only ClassTemplatePartialSpecializationDecls occur"
-                   "inside templates");
+  // As a MS extension, we permit class-scope explicit specialization
+  // of member class templates.
+  ClassTemplateDecl *ClassTemplate = D->getSpecializedTemplate();
+  assert(ClassTemplate->getDeclContext()->isRecord() &&
+         D->getTemplateSpecializationKind() == TSK_ExplicitSpecialization &&
+         "can only instantiate an explicit specialization "
+         "for a member class template");
+
+  // Lookup the already-instantiated declaration in the instantiation
+  // of the class template. FIXME: Diagnose or assert if this fails?
+  DeclContext::lookup_result Found
+    = Owner->lookup(ClassTemplate->getDeclName());
+  if (Found.empty())
+    return nullptr;
+  ClassTemplateDecl *InstClassTemplate
+    = dyn_cast<ClassTemplateDecl>(Found.front());
+  if (!InstClassTemplate)
+    return nullptr;
+
+  // Substitute into the template arguments of the class template explicit
+  // specialization.
+  TemplateSpecializationTypeLoc Loc = D->getTypeAsWritten()->getTypeLoc().
+                                        castAs<TemplateSpecializationTypeLoc>();
+  TemplateArgumentListInfo InstTemplateArgs(Loc.getLAngleLoc(),
+                                            Loc.getRAngleLoc());
+  SmallVector<TemplateArgumentLoc, 4> ArgLocs;
+  for (unsigned I = 0; I != Loc.getNumArgs(); ++I)
+    ArgLocs.push_back(Loc.getArgLoc(I));
+  if (SemaRef.Subst(ArgLocs.data(), ArgLocs.size(),
+                    InstTemplateArgs, TemplateArgs))
+    return nullptr;
+
+  // Check that the template argument list is well-formed for this
+  // class template.
+  SmallVector<TemplateArgument, 4> Converted;
+  if (SemaRef.CheckTemplateArgumentList(InstClassTemplate,
+                                        D->getLocation(),
+                                        InstTemplateArgs,
+                                        false,
+                                        Converted))
+    return nullptr;
+
+  // Figure out where to insert this class template explicit specialization
+  // in the member template's set of class template explicit specializations.
+  void *InsertPos = nullptr;
+  ClassTemplateSpecializationDecl *PrevDecl =
+      InstClassTemplate->findSpecialization(Converted, InsertPos);
+
+  // Check whether we've already seen a conflicting instantiation of this
+  // declaration (for instance, if there was a prior implicit instantiation).
+  bool Ignored;
+  if (PrevDecl &&
+      SemaRef.CheckSpecializationInstantiationRedecl(D->getLocation(),
+                                                     D->getSpecializationKind(),
+                                                     PrevDecl,
+                                                     PrevDecl->getSpecializationKind(),
+                                                     PrevDecl->getPointOfInstantiation(),
+                                                     Ignored))
+    return nullptr;
+
+  // If PrevDecl was a definition and D is also a definition, diagnose.
+  // This happens in cases like:
+  //
+  //   template<typename T, typename U>
+  //   struct Outer {
+  //     template<typename X> struct Inner;
+  //     template<> struct Inner<T> {};
+  //     template<> struct Inner<U> {};
+  //   };
+  //
+  //   Outer<int, int> outer; // error: the explicit specializations of Inner
+  //                          // have the same signature.
+  if (PrevDecl && PrevDecl->getDefinition() &&
+      D->isThisDeclarationADefinition()) {
+    SemaRef.Diag(D->getLocation(), diag::err_redefinition) << PrevDecl;
+    SemaRef.Diag(PrevDecl->getDefinition()->getLocation(),
+                 diag::note_previous_definition);
+    return nullptr;
+  }
+
+  // Create the class template partial specialization declaration.
+  ClassTemplateSpecializationDecl *InstD
+    = ClassTemplateSpecializationDecl::Create(SemaRef.Context,
+                                              D->getTagKind(),
+                                              Owner,
+                                              D->getLocStart(),
+                                              D->getLocation(),
+                                              InstClassTemplate,
+                                              Converted.data(),
+                                              Converted.size(),
+                                              PrevDecl);
+
+  // Add this partial specialization to the set of class template partial
+  // specializations.
+  if (!PrevDecl)
+    InstClassTemplate->AddSpecialization(InstD, InsertPos);
+
+  // Substitute the nested name specifier, if any.
+  if (SubstQualifier(D, InstD))
+    return nullptr;
+
+  // Build the canonical type that describes the converted template
+  // arguments of the class template explicit specialization.
+  QualType CanonType = SemaRef.Context.getTemplateSpecializationType(
+      TemplateName(InstClassTemplate), Converted.data(), Converted.size(),
+      SemaRef.Context.getRecordType(InstD));
+
+  // 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
+  // from the specialization's declaration the way that the user
+  // actually wrote the specialization, rather than formatting the
+  // name based on the "canonical" representation used to store the
+  // template arguments in the specialization.
+  TypeSourceInfo *WrittenTy = SemaRef.Context.getTemplateSpecializationTypeInfo(
+      TemplateName(InstClassTemplate), D->getLocation(), InstTemplateArgs,
+      CanonType);
+
+  InstD->setAccess(D->getAccess());
+  InstD->setInstantiationOfMemberClass(D, TSK_ImplicitInstantiation);
+  InstD->setSpecializationKind(D->getSpecializationKind());
+  InstD->setTypeAsWritten(WrittenTy);
+  InstD->setExternLoc(D->getExternLoc());
+  InstD->setTemplateKeywordLoc(D->getTemplateKeywordLoc());
+
+  Owner->addDecl(InstD);
+
+  // Instantiate the members of the class-scope explicit specialization eagerly.
+  // We don't have support for lazy instantiation of an explicit specialization
+  // yet, and MSVC eagerly instantiates in this case.
+  if (D->isThisDeclarationADefinition() &&
+      SemaRef.InstantiateClass(D->getLocation(), InstD, D, TemplateArgs,
+                               TSK_ImplicitInstantiation,
+                               /*Complain=*/true))
+    return nullptr;
+
+  return InstD;
 }
 
 Decl *TemplateDeclInstantiator::VisitVarTemplateSpecializationDecl(
@@ -2314,22 +2491,21 @@
 
   if (SemaRef.Subst(TemplateArgsInfo.getArgumentArray(),
                     TemplateArgsInfo.size(), VarTemplateArgsInfo, TemplateArgs))
-    return 0;
+    return nullptr;
 
   // Check that the template argument list is well-formed for this template.
   SmallVector<TemplateArgument, 4> Converted;
-  bool ExpansionIntoFixedList = false;
   if (SemaRef.CheckTemplateArgumentList(
           VarTemplate, VarTemplate->getLocStart(),
           const_cast<TemplateArgumentListInfo &>(VarTemplateArgsInfo), false,
-          Converted, &ExpansionIntoFixedList))
-    return 0;
+          Converted))
+    return nullptr;
 
   // Find the variable template specialization declaration that
   // corresponds to these arguments.
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
   if (VarTemplateSpecializationDecl *VarSpec = VarTemplate->findSpecialization(
-          Converted.data(), Converted.size(), InsertPos))
+          Converted, InsertPos))
     // If we already have a variable template specialization, return it.
     return VarSpec;
 
@@ -2340,26 +2516,26 @@
 Decl *TemplateDeclInstantiator::VisitVarTemplateSpecializationDecl(
     VarTemplateDecl *VarTemplate, VarDecl *D, void *InsertPos,
     const TemplateArgumentListInfo &TemplateArgsInfo,
-    llvm::ArrayRef<TemplateArgument> Converted) {
+    ArrayRef<TemplateArgument> Converted) {
 
   // If this is the variable for an anonymous struct or union,
   // instantiate the anonymous struct/union type first.
   if (const RecordType *RecordTy = D->getType()->getAs<RecordType>())
     if (RecordTy->getDecl()->isAnonymousStructOrUnion())
       if (!VisitCXXRecordDecl(cast<CXXRecordDecl>(RecordTy->getDecl())))
-        return 0;
+        return nullptr;
 
   // Do substitution on the type of the declaration
   TypeSourceInfo *DI =
       SemaRef.SubstType(D->getTypeSourceInfo(), TemplateArgs,
                         D->getTypeSpecStartLoc(), D->getDeclName());
   if (!DI)
-    return 0;
+    return nullptr;
 
   if (DI->getType()->isFunctionType()) {
     SemaRef.Diag(D->getLocation(), diag::err_variable_instantiates_to_function)
         << D->isStaticDataMember() << DI->getType();
-    return 0;
+    return nullptr;
   }
 
   // Build the instantiated declaration
@@ -2373,7 +2549,7 @@
 
   // Substitute the nested name specifier, if any.
   if (SubstQualifier(D, Var))
-    return 0;
+    return nullptr;
 
   SemaRef.BuildVariableInstantiation(Var, D, TemplateArgs, LateAttrs,
                                      Owner, StartingScope);
@@ -2393,7 +2569,7 @@
   SemaRef.Diag(D->getLocation(), DiagID)
     << D->getDeclKindName();
 
-  return 0;
+  return nullptr;
 }
 
 Decl *TemplateDeclInstantiator::VisitDecl(Decl *D) {
@@ -2404,7 +2580,7 @@
                       const MultiLevelTemplateArgumentList &TemplateArgs) {
   TemplateDeclInstantiator Instantiator(*this, Owner, TemplateArgs);
   if (D->isInvalidDecl())
-    return 0;
+    return nullptr;
 
   return Instantiator.Visit(D);
 }
@@ -2433,7 +2609,7 @@
 
   // Clean up if we had an error.
   if (Invalid)
-    return NULL;
+    return nullptr;
 
   TemplateParameterList *InstL
     = TemplateParameterList::Create(SemaRef.Context, L->getTemplateLoc(),
@@ -2467,7 +2643,7 @@
   TemplateParameterList *TempParams = PartialSpec->getTemplateParameters();
   TemplateParameterList *InstParams = SubstTemplateParams(TempParams);
   if (!InstParams)
-    return 0;
+    return nullptr;
 
   // Substitute into the template arguments of the class template partial
   // specialization.
@@ -2478,7 +2654,7 @@
   if (SemaRef.Subst(TemplArgInfo->getTemplateArgs(),
                     TemplArgInfo->NumTemplateArgs,
                     InstTemplateArgs, TemplateArgs))
-    return 0;
+    return nullptr;
 
   // Check that the template argument list is well-formed for this
   // class template.
@@ -2488,14 +2664,13 @@
                                         InstTemplateArgs,
                                         false,
                                         Converted))
-    return 0;
+    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 = 0;
+  void *InsertPos = nullptr;
   ClassTemplateSpecializationDecl *PrevDecl
-    = ClassTemplate->findPartialSpecialization(Converted.data(),
-                                               Converted.size(), InsertPos);
+    = ClassTemplate->findPartialSpecialization(Converted, InsertPos);
 
   // Build the canonical type that describes the converted template
   // arguments of the class template partial specialization.
@@ -2538,7 +2713,7 @@
       << WrittenTy->getType();
     SemaRef.Diag(PrevDecl->getLocation(), diag::note_prev_partial_spec_here)
       << SemaRef.Context.getTypeDeclType(PrevDecl);
-    return 0;
+    return nullptr;
   }
 
 
@@ -2555,17 +2730,18 @@
                                                      Converted.size(),
                                                      InstTemplateArgs,
                                                      CanonType,
-                                                     0);
+                                                     nullptr);
   // Substitute the nested name specifier, if any.
   if (SubstQualifier(PartialSpec, InstPartialSpec))
-    return 0;
+    return nullptr;
 
   InstPartialSpec->setInstantiatedFromMember(PartialSpec);
   InstPartialSpec->setTypeAsWritten(WrittenTy);
 
   // Add this partial specialization to the set of class template partial
   // specializations.
-  ClassTemplate->AddPartialSpecialization(InstPartialSpec, /*InsertPos=*/0);
+  ClassTemplate->AddPartialSpecialization(InstPartialSpec,
+                                          /*InsertPos=*/nullptr);
   return InstPartialSpec;
 }
 
@@ -2594,7 +2770,7 @@
   TemplateParameterList *TempParams = PartialSpec->getTemplateParameters();
   TemplateParameterList *InstParams = SubstTemplateParams(TempParams);
   if (!InstParams)
-    return 0;
+    return nullptr;
 
   // Substitute into the template arguments of the variable template partial
   // specialization.
@@ -2605,21 +2781,20 @@
   if (SemaRef.Subst(TemplArgInfo->getTemplateArgs(),
                     TemplArgInfo->NumTemplateArgs,
                     InstTemplateArgs, TemplateArgs))
-    return 0;
+    return nullptr;
 
   // Check that the template argument list is well-formed for this
   // class template.
   SmallVector<TemplateArgument, 4> Converted;
   if (SemaRef.CheckTemplateArgumentList(VarTemplate, PartialSpec->getLocation(),
                                         InstTemplateArgs, false, Converted))
-    return 0;
+    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 = 0;
+  void *InsertPos = nullptr;
   VarTemplateSpecializationDecl *PrevDecl =
-      VarTemplate->findPartialSpecialization(Converted.data(), Converted.size(),
-                                             InsertPos);
+      VarTemplate->findPartialSpecialization(Converted, InsertPos);
 
   // Build the canonical type that describes the converted template
   // arguments of the variable template partial specialization.
@@ -2658,7 +2833,7 @@
         << WrittenTy->getType();
     SemaRef.Diag(PrevDecl->getLocation(),
                  diag::note_var_prev_partial_spec_here);
-    return 0;
+    return nullptr;
   }
 
   // Do substitution on the type of the declaration
@@ -2666,13 +2841,13 @@
       PartialSpec->getTypeSourceInfo(), TemplateArgs,
       PartialSpec->getTypeSpecStartLoc(), PartialSpec->getDeclName());
   if (!DI)
-    return 0;
+    return nullptr;
 
   if (DI->getType()->isFunctionType()) {
     SemaRef.Diag(PartialSpec->getLocation(),
                  diag::err_variable_instantiates_to_function)
         << PartialSpec->isStaticDataMember() << DI->getType();
-    return 0;
+    return nullptr;
   }
 
   // Create the variable template partial specialization declaration.
@@ -2685,14 +2860,14 @@
 
   // Substitute the nested name specifier, if any.
   if (SubstQualifier(PartialSpec, InstPartialSpec))
-    return 0;
+    return nullptr;
 
   InstPartialSpec->setInstantiatedFromMember(PartialSpec);
   InstPartialSpec->setTypeAsWritten(WrittenTy);
 
   // Add this partial specialization to the set of variable template partial
   // specializations. The instantiation of the initializer is not necessary.
-  VarTemplate->AddPartialSpecialization(InstPartialSpec, /*InsertPos=*/0);
+  VarTemplate->AddPartialSpecialization(InstPartialSpec, /*InsertPos=*/nullptr);
 
   SemaRef.BuildVariableInstantiation(InstPartialSpec, PartialSpec, TemplateArgs,
                                      LateAttrs, Owner, StartingScope);
@@ -2706,8 +2881,8 @@
   TypeSourceInfo *OldTInfo = D->getTypeSourceInfo();
   assert(OldTInfo && "substituting function without type source info");
   assert(Params.empty() && "parameter vector is non-empty at start");
-  
-  CXXRecordDecl *ThisContext = 0;
+
+  CXXRecordDecl *ThisContext = nullptr;
   unsigned ThisTypeQuals = 0;
   if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
     ThisContext = cast<CXXRecordDecl>(Owner);
@@ -2720,7 +2895,7 @@
                                     D->getDeclName(),
                                     ThisContext, ThisTypeQuals);
   if (!NewTInfo)
-    return 0;
+    return nullptr;
 
   TypeLoc OldTL = OldTInfo->getTypeLoc().IgnoreParens();
   if (FunctionProtoTypeLoc OldProtoLoc = OldTL.getAs<FunctionProtoTypeLoc>()) {
@@ -2729,9 +2904,9 @@
       TypeLoc NewTL = NewTInfo->getTypeLoc().IgnoreParens();
       FunctionProtoTypeLoc NewProtoLoc = NewTL.castAs<FunctionProtoTypeLoc>();
       unsigned NewIdx = 0;
-      for (unsigned OldIdx = 0, NumOldParams = OldProtoLoc.getNumArgs();
+      for (unsigned OldIdx = 0, NumOldParams = OldProtoLoc.getNumParams();
            OldIdx != NumOldParams; ++OldIdx) {
-        ParmVarDecl *OldParam = OldProtoLoc.getArg(OldIdx);
+        ParmVarDecl *OldParam = OldProtoLoc.getParam(OldIdx);
         LocalInstantiationScope *Scope = SemaRef.CurrentInstantiationScope;
 
         Optional<unsigned> NumArgumentsInExpansion;
@@ -2742,14 +2917,14 @@
         if (!NumArgumentsInExpansion) {
           // Simple case: normal parameter, or a parameter pack that's
           // instantiated to a (still-dependent) parameter pack.
-          ParmVarDecl *NewParam = NewProtoLoc.getArg(NewIdx++);
+          ParmVarDecl *NewParam = NewProtoLoc.getParam(NewIdx++);
           Params.push_back(NewParam);
           Scope->InstantiatedLocal(OldParam, NewParam);
         } else {
           // Parameter pack expansion: make the instantiation an argument pack.
           Scope->MakeInstantiatedLocalArgPack(OldParam);
           for (unsigned I = 0; I != *NumArgumentsInExpansion; ++I) {
-            ParmVarDecl *NewParam = NewProtoLoc.getArg(NewIdx++);
+            ParmVarDecl *NewParam = NewProtoLoc.getParam(NewIdx++);
             Params.push_back(NewParam);
             Scope->InstantiatedLocalPackArg(OldParam, NewParam);
           }
@@ -2761,18 +2936,19 @@
       // the function parameters themselves.
       const FunctionProtoType *OldProto =
           cast<FunctionProtoType>(OldProtoLoc.getType());
-      for (unsigned i = 0, i_end = OldProtoLoc.getNumArgs(); i != i_end; ++i) {
-        ParmVarDecl *OldParam = OldProtoLoc.getArg(i);
+      for (unsigned i = 0, i_end = OldProtoLoc.getNumParams(); i != i_end;
+           ++i) {
+        ParmVarDecl *OldParam = OldProtoLoc.getParam(i);
         if (!OldParam) {
           Params.push_back(SemaRef.BuildParmVarDeclForTypedef(
-              D, D->getLocation(), OldProto->getArgType(i)));
+              D, D->getLocation(), OldProto->getParamType(i)));
           continue;
         }
 
         ParmVarDecl *Parm =
             cast_or_null<ParmVarDecl>(VisitParmVarDecl(OldParam));
         if (!Parm)
-          return 0;
+          return nullptr;
         Params.push_back(Parm);
       }
     }
@@ -2791,7 +2967,7 @@
     if (SemaRef.SubstParmTypes(D->getLocation(), D->param_begin(),
                                D->getNumParams(), TemplateArgs, ParamTypes,
                                &Params))
-      return 0;
+      return nullptr;
   }
 
   return NewTInfo;
@@ -2811,6 +2987,14 @@
       // Simple case: not a parameter pack.
       assert(FParamIdx < Function->getNumParams());
       ParmVarDecl *FunctionParam = Function->getParamDecl(FParamIdx);
+      // If the parameter's type is not dependent, update it to match the type
+      // in the pattern. They can differ in top-level cv-qualifiers, and we want
+      // the pattern's type here. If the type is dependent, they can't differ,
+      // per core issue 1668.
+      // FIXME: Updating the type to work around this is at best fragile.
+      if (!PatternDecl->getType()->isDependentType())
+        FunctionParam->setType(PatternParam->getType());
+
       FunctionParam->setDeclName(PatternParam->getDeclName());
       Scope.InstantiatedLocal(PatternParam, FunctionParam);
       ++FParamIdx;
@@ -2825,6 +3009,9 @@
            "should only be called when all template arguments are known");
     for (unsigned Arg = 0; Arg < *NumArgumentsInExpansion; ++Arg) {
       ParmVarDecl *FunctionParam = Function->getParamDecl(FParamIdx);
+      if (!PatternDecl->getType()->isDependentType())
+        FunctionParam->setType(PatternParam->getType());
+
       FunctionParam->setDeclName(PatternParam->getDeclName());
       Scope.InstantiatedLocalPackArg(PatternParam, FunctionParam);
       ++FParamIdx;
@@ -2843,7 +3030,7 @@
   //   "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
   //   and the end of the function-definition, member-declarator, or 
   //   declarator.    
-  CXXRecordDecl *ThisContext = 0;
+  CXXRecordDecl *ThisContext = nullptr;
   unsigned ThisTypeQuals = 0;
   if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(New)) {
     ThisContext = Method->getParent();
@@ -2925,7 +3112,7 @@
 
     Exceptions.push_back(T);
   }
-  Expr *NoexceptExpr = 0;
+  Expr *NoexceptExpr = nullptr;
   if (Expr *OldNoexceptExpr = Proto->getNoexceptExpr()) {
     EnterExpressionEvaluationContext Unevaluated(SemaRef,
                                                  Sema::ConstantEvaluated);
@@ -2934,29 +3121,23 @@
       E = SemaRef.CheckBooleanCondition(E.get(), E.get()->getLocStart());
 
     if (E.isUsable()) {
-      NoexceptExpr = E.take();
+      NoexceptExpr = E.get();
       if (!NoexceptExpr->isTypeDependent() &&
           !NoexceptExpr->isValueDependent())
         NoexceptExpr
           = SemaRef.VerifyIntegerConstantExpression(NoexceptExpr,
-              0, diag::err_noexcept_needs_constant_expression,
-              /*AllowFold*/ false).take();
+              nullptr, diag::err_noexcept_needs_constant_expression,
+              /*AllowFold*/ false).get();
     }
   }
 
-  // Rebuild the function type
-  const FunctionProtoType *NewProto
-    = New->getType()->getAs<FunctionProtoType>();
-  assert(NewProto && "Template instantiation without function prototype?");
-
-  FunctionProtoType::ExtProtoInfo EPI = NewProto->getExtProtoInfo();
+  FunctionProtoType::ExtProtoInfo EPI;
   EPI.ExceptionSpecType = Proto->getExceptionSpecType();
   EPI.NumExceptions = Exceptions.size();
   EPI.Exceptions = Exceptions.data();
   EPI.NoexceptExpr = NoexceptExpr;
 
-  New->setType(SemaRef.Context.getFunctionType(NewProto->getResultType(),
-                                               NewProto->getArgTypes(), EPI));
+  SemaRef.UpdateExceptionSpec(New, EPI);
 }
 
 void Sema::InstantiateExceptionSpec(SourceLocation PointOfInstantiation,
@@ -2970,10 +3151,9 @@
   if (Inst.isInvalid()) {
     // We hit the instantiation depth limit. Clear the exception specification
     // so that our callers don't have to cope with EST_Uninstantiated.
-    FunctionProtoType::ExtProtoInfo EPI = Proto->getExtProtoInfo();
+    FunctionProtoType::ExtProtoInfo EPI;
     EPI.ExceptionSpecType = EST_None;
-    Decl->setType(Context.getFunctionType(Proto->getResultType(),
-                                          Proto->getArgTypes(), EPI));
+    UpdateExceptionSpec(Decl, EPI);
     return;
   }
 
@@ -2983,7 +3163,7 @@
   LocalInstantiationScope Scope(*this);
 
   MultiLevelTemplateArgumentList TemplateArgs =
-    getTemplateInstantiationArgs(Decl, 0, /*RelativeToPrimary*/true);
+    getTemplateInstantiationArgs(Decl, nullptr, /*RelativeToPrimary*/true);
 
   FunctionDecl *Template = Proto->getExceptionSpecTemplate();
   addInstantiatedParametersToScope(*this, Decl, Template, Scope, TemplateArgs);
@@ -3003,6 +3183,10 @@
   if (Tmpl->isDeleted())
     New->setDeletedAsWritten();
 
+  // Forward the mangling number from the template to the instantiated decl.
+  SemaRef.Context.setManglingNumber(New,
+                                    SemaRef.Context.getManglingNumber(Tmpl));
+
   // If we are performing substituting explicitly-specified template arguments
   // or deduced template arguments into a function template and we reach this
   // point, we are now past the point where SFINAE applies and have committed
@@ -3053,7 +3237,7 @@
       EPI.ExceptionSpecDecl = New;
       EPI.ExceptionSpecTemplate = ExceptionSpecTemplate;
       New->setType(SemaRef.Context.getFunctionType(
-          NewProto->getResultType(), NewProto->getArgTypes(), EPI));
+          NewProto->getReturnType(), NewProto->getParamTypes(), EPI));
     } else {
       ::InstantiateExceptionSpec(SemaRef, New, Proto, TemplateArgs);
     }
@@ -3181,14 +3365,22 @@
   //   initializer or return value, and class template specializations, other
   //   explicit instantiation declarations have the effect of suppressing the
   //   implicit instantiation of the entity to which they refer.
-  if (Function->getTemplateSpecializationKind()
-        == TSK_ExplicitInstantiationDeclaration &&
+  if (Function->getTemplateSpecializationKind() ==
+          TSK_ExplicitInstantiationDeclaration &&
       !PatternDecl->isInlined() &&
-      !PatternDecl->getResultType()->getContainedAutoType())
+      !PatternDecl->getReturnType()->getContainedAutoType())
     return;
 
-  if (PatternDecl->isInlined())
-    Function->setImplicitlyInline();
+  if (PatternDecl->isInlined()) {
+    // Function, and all later redeclarations of it (from imported modules,
+    // for instance), are now implicitly inline.
+    for (auto *D = Function->getMostRecentDecl(); /**/;
+         D = D->getPreviousDecl()) {
+      D->setImplicitlyInline();
+      if (D == Function)
+        break;
+    }
+  }
 
   InstantiatingTemplate Inst(*this, PointOfInstantiation, Function);
   if (Inst.isInvalid())
@@ -3202,10 +3394,8 @@
   // while we're still within our own instantiation context.
   SmallVector<VTableUse, 16> SavedVTableUses;
   std::deque<PendingImplicitInstantiation> SavedPendingInstantiations;
-  std::deque<PendingImplicitInstantiation> 
-                              SavedPendingLocalImplicitInstantiations;
-  SavedPendingLocalImplicitInstantiations.swap(
-                                  PendingLocalImplicitInstantiations);
+  SavePendingLocalImplicitInstantiationsRAII
+      SavedPendingLocalImplicitInstantiations(*this);
   if (Recursive) {
     VTableUses.swap(SavedVTableUses);
     PendingInstantiations.swap(SavedPendingInstantiations);
@@ -3227,14 +3417,14 @@
   if (PatternDecl->isDefaulted())
     SetDeclDefaulted(Function, PatternDecl->getLocation());
   else {
-    ActOnStartOfFunctionDef(0, Function);
+    ActOnStartOfFunctionDef(nullptr, Function);
 
     // Enter the scope of this instantiation. We don't use
     // PushDeclContext because we don't have a scope.
     Sema::ContextRAII savedContext(*this, Function);
 
     MultiLevelTemplateArgumentList TemplateArgs =
-      getTemplateInstantiationArgs(Function, 0, false, PatternDecl);
+      getTemplateInstantiationArgs(Function, nullptr, false, PatternDecl);
 
     addInstantiatedParametersToScope(*this, Function, PatternDecl, Scope,
                                      TemplateArgs);
@@ -3257,6 +3447,9 @@
 
     PerformDependentDiagnostics(PatternDecl, TemplateArgs);
 
+    if (auto *Listener = getASTMutationListener())
+      Listener->FunctionDefinitionInstantiated(Function);
+
     savedContext.pop();
   }
 
@@ -3286,8 +3479,6 @@
            "PendingInstantiations should be empty before it is discarded.");
     PendingInstantiations.swap(SavedPendingInstantiations);
   }
-  SavedPendingLocalImplicitInstantiations.swap(
-                            PendingLocalImplicitInstantiations);
 }
 
 VarTemplateSpecializationDecl *Sema::BuildVarTemplateInstantiation(
@@ -3299,11 +3490,11 @@
     LateInstantiatedAttrVec *LateAttrs,
     LocalInstantiationScope *StartingScope) {
   if (FromVar->isInvalidDecl())
-    return 0;
+    return nullptr;
 
   InstantiatingTemplate Inst(*this, PointOfInstantiation, FromVar);
   if (Inst.isInvalid())
-    return 0;
+    return nullptr;
 
   MultiLevelTemplateArgumentList TemplateArgLists;
   TemplateArgLists.addOuterTemplateArguments(&TemplateArgList);
@@ -3313,7 +3504,18 @@
   // or may not be the declaration in the class; if it's in the class, we want
   // to instantiate a member in the class (a declaration), and if it's outside,
   // we want to instantiate a definition.
-  FromVar = FromVar->getFirstDecl();
+  //
+  // If we're instantiating an explicitly-specialized member template or member
+  // partial specialization, don't do this. The member specialization completely
+  // replaces the original declaration in this case.
+  bool IsMemberSpec = false;
+  if (VarTemplatePartialSpecializationDecl *PartialSpec =
+          dyn_cast<VarTemplatePartialSpecializationDecl>(FromVar))
+    IsMemberSpec = PartialSpec->isMemberSpecialization();
+  else if (VarTemplateDecl *FromTemplate = FromVar->getDescribedVarTemplate())
+    IsMemberSpec = FromTemplate->isMemberSpecialization();
+  if (!IsMemberSpec)
+    FromVar = FromVar->getFirstDecl();
 
   MultiLevelTemplateArgumentList MultiLevelList(TemplateArgList);
   TemplateDeclInstantiator Instantiator(*this, FromVar->getDeclContext(),
@@ -3337,7 +3539,7 @@
       SubstType(PatternDecl->getTypeSourceInfo(), TemplateArgs,
                 PatternDecl->getTypeSpecStartLoc(), PatternDecl->getDeclName());
   if (!DI)
-    return 0;
+    return nullptr;
 
   // Update the type of this variable template specialization.
   VarSpec->setType(DI->getType());
@@ -3398,16 +3600,15 @@
 
   InstantiateAttrs(TemplateArgs, OldVar, NewVar, LateAttrs, StartingScope);
 
-  if (NewVar->hasAttrs())
-    CheckAlignasUnderalignment(NewVar);
-
   LookupResult Previous(
       *this, NewVar->getDeclName(), NewVar->getLocation(),
       NewVar->isLocalExternDecl() ? Sema::LookupRedeclarationWithLinkage
                                   : Sema::LookupOrdinaryName,
       Sema::ForRedeclaration);
 
-  if (NewVar->isLocalExternDecl() && OldVar->getPreviousDecl()) {
+  if (NewVar->isLocalExternDecl() && OldVar->getPreviousDecl() &&
+      (!OldVar->getPreviousDecl()->getDeclContext()->isDependentContext() ||
+       OldVar->getPreviousDecl()->getDeclContext()==OldVar->getDeclContext())) {
     // We have a previous declaration. Use that one, so we merge with the
     // right type.
     if (NamedDecl *NewPrev = FindInstantiatedDecl(
@@ -3435,9 +3636,16 @@
     NewVar->setInstantiationOfStaticDataMember(OldVar,
                                                TSK_ImplicitInstantiation);
 
+  // Forward the mangling number from the template to the instantiated decl.
+  Context.setManglingNumber(NewVar, Context.getManglingNumber(OldVar));
+  Context.setStaticLocalNumber(NewVar, Context.getStaticLocalNumber(OldVar));
+
   // Delay instantiation of the initializer for variable templates until a
-  // definition of the variable is needed.
-  if (!isa<VarTemplateSpecializationDecl>(NewVar) && !InstantiatingVarTemplate)
+  // definition of the variable is needed. We need it right away if the type
+  // contains 'auto'.
+  if ((!isa<VarTemplateSpecializationDecl>(NewVar) &&
+       !InstantiatingVarTemplate) ||
+      NewVar->getType()->isUndeducedType())
     InstantiateVariableInitializer(NewVar, OldVar, TemplateArgs);
 
   // Diagnose unused local variables with dependent types, where the diagnostic
@@ -3469,9 +3677,15 @@
                          OldVar->getInitStyle() == VarDecl::CallInit);
     if (!Init.isInvalid()) {
       bool TypeMayContainAuto = true;
-      if (Init.get()) {
+      Expr *InitExpr = Init.get();
+
+      if (Var->hasAttr<DLLImportAttr>() &&
+          (!InitExpr ||
+           !InitExpr->isConstantInitializer(getASTContext(), false))) {
+        // Do not dynamically initialize dllimport variables.
+      } else if (InitExpr) {
         bool DirectInit = OldVar->isDirectInit();
-        AddInitializerToDecl(Var, Init.take(), DirectInit, TypeMayContainAuto);
+        AddInitializerToDecl(Var, InitExpr, DirectInit, TypeMayContainAuto);
       } else
         ActOnUninitializedDecl(Var, TypeMayContainAuto);
     } else {
@@ -3519,7 +3733,7 @@
 
   VarTemplateSpecializationDecl *VarSpec =
       dyn_cast<VarTemplateSpecializationDecl>(Var);
-  VarDecl *PatternDecl = 0, *Def = 0;
+  VarDecl *PatternDecl = nullptr, *Def = nullptr;
   MultiLevelTemplateArgumentList TemplateArgs =
       getTemplateInstantiationArgs(Var);
 
@@ -3705,6 +3919,8 @@
   // while we're still within our own instantiation context.
   SmallVector<VTableUse, 16> SavedVTableUses;
   std::deque<PendingImplicitInstantiation> SavedPendingInstantiations;
+  SavePendingLocalImplicitInstantiationsRAII
+      SavedPendingLocalImplicitInstantiations(*this);
   if (Recursive) {
     VTableUses.swap(SavedVTableUses);
     PendingInstantiations.swap(SavedPendingInstantiations);
@@ -3727,7 +3943,7 @@
     TemplateDeclInstantiator Instantiator(*this, Var->getDeclContext(),
                                           TemplateArgs);
     Var = cast_or_null<VarDecl>(Instantiator.VisitVarTemplateSpecializationDecl(
-        VarSpec->getSpecializedTemplate(), Def, 0,
+        VarSpec->getSpecializedTemplate(), Def, nullptr,
         VarSpec->getTemplateArgsInfo(), VarSpec->getTemplateArgs().asArray()));
     if (Var) {
       llvm::PointerUnion<VarTemplateDecl *,
@@ -3795,11 +4011,7 @@
   bool AnyErrors = Tmpl->isInvalidDecl();
 
   // Instantiate all the initializers.
-  for (CXXConstructorDecl::init_const_iterator Inits = Tmpl->init_begin(),
-                                            InitsEnd = Tmpl->init_end();
-       Inits != InitsEnd; ++Inits) {
-    CXXCtorInitializer *Init = *Inits;
-
+  for (const auto *Init : Tmpl->inits()) {
     // Only instantiate written initializers, let Sema re-construct implicit
     // ones.
     if (!Init->isWritten())
@@ -3852,7 +4064,7 @@
 
         // Build the initializer.
         MemInitResult NewInit = BuildBaseInitializer(BaseTInfo->getType(),
-                                                     BaseTInfo, TempInit.take(),
+                                                     BaseTInfo, TempInit.get(),
                                                      New->getParent(),
                                                      SourceLocation());
         if (NewInit.isInvalid()) {
@@ -3887,10 +4099,10 @@
       }
 
       if (Init->isBaseInitializer())
-        NewInit = BuildBaseInitializer(TInfo->getType(), TInfo, TempInit.take(),
+        NewInit = BuildBaseInitializer(TInfo->getType(), TInfo, TempInit.get(),
                                        New->getParent(), EllipsisLoc);
       else
-        NewInit = BuildDelegatingInitializer(TInfo, TempInit.take(),
+        NewInit = BuildDelegatingInitializer(TInfo, TempInit.get(),
                                   cast<CXXRecordDecl>(CurContext->getParent()));
     } else if (Init->isMemberInitializer()) {
       FieldDecl *Member = cast_or_null<FieldDecl>(FindInstantiatedDecl(
@@ -3903,7 +4115,7 @@
         continue;
       }
 
-      NewInit = BuildMemberInitializer(Member, TempInit.take(),
+      NewInit = BuildMemberInitializer(Member, TempInit.get(),
                                        Init->getSourceLocation());
     } else if (Init->isIndirectMemberInitializer()) {
       IndirectFieldDecl *IndirectMember =
@@ -3917,7 +4129,7 @@
         continue;
       }
 
-      NewInit = BuildMemberInitializer(IndirectMember, TempInit.take(),
+      NewInit = BuildMemberInitializer(IndirectMember, TempInit.get(),
                                        Init->getSourceLocation());
     }
 
@@ -4131,7 +4343,7 @@
     if (isInstantiationOf(Ctx, D, *first))
       return cast<NamedDecl>(*first);
 
-  return 0;
+  return nullptr;
 }
 
 /// \brief Finds the instantiation of the given declaration context
@@ -4183,7 +4395,7 @@
   // find an instantiated decl for (T y) when the ParentDC for y is
   // the translation unit.  
   //   e.g. template <class T> void Foo(auto (*p)(T y) -> decltype(y())) {} 
-  //   float baz(float(*)()) { return 0.0; }

+  //   float baz(float(*)()) { return 0.0; }
   //   Foo(baz);
   // The better fix here is perhaps to ensure that a ParmVarDecl, by the time
   // it gets here, always has a FunctionOrMethod as its ParentDC??
@@ -4221,7 +4433,7 @@
       return D;
 
     if (D->isInvalidDecl())
-      return 0;
+      return nullptr;
 
     // If we didn't find the decl, then we must have a label decl that hasn't
     // been found yet.  Lazily instantiate it and return it now.
@@ -4305,7 +4517,7 @@
 
   ParentDC = FindInstantiatedContext(Loc, ParentDC, TemplateArgs);
   if (!ParentDC)
-    return 0;
+    return nullptr;
 
   if (ParentDC != D->getDeclContext()) {
     // We performed some kind of instantiation in the parent context,
@@ -4324,13 +4536,13 @@
           IsBeingInstantiated = true;
         if (!Tag->isBeingDefined() &&
             RequireCompleteType(Loc, T, diag::err_incomplete_type))
-          return 0;
+          return nullptr;
 
         ParentDC = Tag->getDecl();
       }
     }
 
-    NamedDecl *Result = 0;
+    NamedDecl *Result = nullptr;
     if (D->getDeclName()) {
       DeclContext::lookup_result Found = ParentDC->lookup(D->getDeclName());
       Result = findInstantiationOf(Context, D, Found.begin(), Found.end());
@@ -4394,14 +4606,6 @@
 /// \brief Performs template instantiation for all implicit template
 /// instantiations we have seen until this point.
 void Sema::PerformPendingInstantiations(bool LocalOnly) {
-  // Load pending instantiations from the external source.
-  if (!LocalOnly && ExternalSource) {
-    SmallVector<PendingImplicitInstantiation, 4> Pending;
-    ExternalSource->ReadPendingInstantiations(Pending);
-    PendingInstantiations.insert(PendingInstantiations.begin(),
-                                 Pending.begin(), Pending.end());
-  }
-
   while (!PendingLocalImplicitInstantiations.empty() ||
          (!LocalOnly && !PendingInstantiations.empty())) {
     PendingImplicitInstantiation Inst;
@@ -4468,10 +4672,7 @@
 
 void Sema::PerformDependentDiagnostics(const DeclContext *Pattern,
                        const MultiLevelTemplateArgumentList &TemplateArgs) {
-  for (DeclContext::ddiag_iterator I = Pattern->ddiag_begin(),
-         E = Pattern->ddiag_end(); I != E; ++I) {
-    DependentDiagnostic *DD = *I;
-
+  for (auto DD : Pattern->ddiags()) {
     switch (DD->getKind()) {
     case DependentDiagnostic::Access:
       HandleDependentAccessCheck(*DD, TemplateArgs);
diff --git a/lib/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp
index 78aa7f8..8e4ce0d 100644
--- a/lib/Sema/SemaTemplateVariadic.cpp
+++ b/lib/Sema/SemaTemplateVariadic.cpp
@@ -10,6 +10,7 @@
 //===----------------------------------------------------------------------===/
 
 #include "clang/Sema/Sema.h"
+#include "TypeLocBuilder.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/TypeLoc.h"
@@ -18,7 +19,6 @@
 #include "clang/Sema/ScopeInfo.h"
 #include "clang/Sema/SemaInternal.h"
 #include "clang/Sema/Template.h"
-#include "TypeLocBuilder.h"
 
 using namespace clang;
 
@@ -223,7 +223,7 @@
   llvm::SmallPtrSet<IdentifierInfo *, 4> NamesKnown;
 
   for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
-    IdentifierInfo *Name = 0;
+    IdentifierInfo *Name = nullptr;
     if (const TemplateTypeParmType *TTP
           = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>())
       Name = TTP->getIdentifier();
@@ -463,7 +463,7 @@
                                        Pattern->getTypeLoc().getSourceRange(),
                                        EllipsisLoc, NumExpansions);
   if (Result.isNull())
-    return 0;
+    return nullptr;
 
   TypeLocBuilder TLB;
   TLB.pushFullCopy(Pattern->getTypeLoc());
@@ -509,8 +509,8 @@
   }
   
   // Create the pack expansion expression and source-location information.
-  return Owned(new (Context) PackExpansionExpr(Context.DependentTy, Pattern,
-                                               EllipsisLoc, NumExpansions));
+  return new (Context)
+    PackExpansionExpr(Context.DependentTy, Pattern, EllipsisLoc, NumExpansions);
 }
 
 /// \brief Retrieve the depth and index of a parameter pack.
@@ -554,8 +554,8 @@
       if (isa<ParmVarDecl>(ND))
         IsFunctionParameterPack = true;
       else
-        llvm::tie(Depth, Index) = getDepthAndIndex(ND);        
-      
+        std::tie(Depth, Index) = getDepthAndIndex(ND);
+
       Name = ND->getIdentifier();
     }
     
@@ -599,7 +599,7 @@
       if (NamedDecl *PartialPack 
                     = CurrentInstantiationScope->getPartiallySubstitutedPack()){
         unsigned PartialDepth, PartialIndex;
-        llvm::tie(PartialDepth, PartialIndex) = getDepthAndIndex(PartialPack);
+        std::tie(PartialDepth, PartialIndex) = getDepthAndIndex(PartialPack);
         if (PartialDepth == Depth && PartialIndex == Index)
           RetainExpansion = true;
       }
@@ -669,8 +669,8 @@
         Result = Size;
         continue;
       }
-      
-      llvm::tie(Depth, Index) = getDepthAndIndex(ND);        
+
+      std::tie(Depth, Index) = getDepthAndIndex(ND);
     }
     if (Depth >= TemplateArgs.getNumLevels() ||
         !TemplateArgs.hasTemplateArgument(Depth, Index))
@@ -730,14 +730,6 @@
   case TST_auto:
   case TST_decltype_auto:
   case TST_unknown_anytype:
-  case TST_image1d_t:
-  case TST_image1d_array_t:
-  case TST_image1d_buffer_t:
-  case TST_image2d_t:
-  case TST_image2d_array_t:
-  case TST_image3d_t:
-  case TST_sampler_t:
-  case TST_event_t:
   case TST_error:
     break;
   }
@@ -775,7 +767,7 @@
 // Callback to only accept typo corrections that refer to parameter packs.
 class ParameterPackValidatorCCC : public CorrectionCandidateCallback {
  public:
-  virtual bool ValidateCandidate(const TypoCorrection &candidate) {
+  bool ValidateCandidate(const TypoCorrection &candidate) override {
     NamedDecl *ND = candidate.getCorrectionDecl();
     return ND && ND->isParameterPack();
   }
@@ -806,8 +798,8 @@
   //   The identifier in a sizeof... expression shall name a parameter pack.
   LookupResult R(*this, &Name, NameLoc, LookupOrdinaryName);
   LookupName(R, S);
-  
-  NamedDecl *ParameterPack = 0;
+
+  NamedDecl *ParameterPack = nullptr;
   ParameterPackValidatorCCC Validator;
   switch (R.getResultKind()) {
   case LookupResult::Found:
@@ -817,8 +809,8 @@
   case LookupResult::NotFound:
   case LookupResult::NotFoundInCurrentInstantiation:
     if (TypoCorrection Corrected = CorrectTypo(R.getLookupNameInfo(),
-                                               R.getLookupKind(), S, 0,
-                                               Validator)) {
+                                               R.getLookupKind(), S, nullptr,
+                                               Validator, CTK_ErrorRecovery)) {
       diagnoseTypo(Corrected,
                    PDiag(diag::err_sizeof_pack_no_pack_name_suggest) << &Name,
                    PDiag(diag::note_parameter_pack_here));
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 436b4b6..be1191c 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Sema/SemaInternal.h"
+#include "TypeLocBuilder.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTMutationListener.h"
@@ -21,10 +22,8 @@
 #include "clang/AST/Expr.h"
 #include "clang/AST/TypeLoc.h"
 #include "clang/AST/TypeLocVisitor.h"
-#include "clang/Basic/OpenCL.h"
 #include "clang/Basic/PartialDiagnostic.h"
 #include "clang/Basic/TargetInfo.h"
-#include "clang/Lex/Preprocessor.h"
 #include "clang/Parse/ParseDiagnostic.h"
 #include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/DelayedDiagnostic.h"
@@ -34,7 +33,6 @@
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/ErrorHandling.h"
-#include "TypeLocBuilder.h"
 
 using namespace clang;
 
@@ -81,7 +79,8 @@
   StringRef name = attr.getName()->getName();
 
   // The GC attributes are usually written with macros;  special-case them.
-  IdentifierInfo *II = attr.isArgIdent(0) ? attr.getArgAsIdent(0)->Ident : 0;
+  IdentifierInfo *II = attr.isArgIdent(0) ? attr.getArgAsIdent(0)->Ident
+                                          : nullptr;
   if (useExpansionLoc && loc.isMacroID() && II) {
     if (II->isStr("strong")) {
       if (S.findMacroSpelling(loc, "__strong")) name = "__strong";
@@ -225,14 +224,14 @@
       assert(hasSavedAttrs);
 
       if (savedAttrs.empty()) {
-        getMutableDeclSpec().getAttributes().set(0);
+        getMutableDeclSpec().getAttributes().set(nullptr);
         return;
       }
 
       getMutableDeclSpec().getAttributes().set(savedAttrs[0]);
       for (unsigned i = 0, e = savedAttrs.size() - 1; i != e; ++i)
         savedAttrs[i]->setNext(savedAttrs[i+1]);
-      savedAttrs.back()->setNext(0);
+      savedAttrs.back()->setNext(nullptr);
     }
   };
 }
@@ -312,7 +311,7 @@
                                                 unsigned i) {
   assert(i <= declarator.getNumTypeObjects());
 
-  DeclaratorChunk *result = 0;
+  DeclaratorChunk *result = nullptr;
 
   // First, look inwards past parens for a function declarator.
   for (; i != 0; --i) {
@@ -380,7 +379,7 @@
     case DeclaratorChunk::BlockPointer: {
       // But don't move an ARC ownership attribute to the return type
       // of a block.
-      DeclaratorChunk *destChunk = 0;
+      DeclaratorChunk *destChunk = nullptr;
       if (state.isProcessingDeclSpec() &&
           attr.getKind() == AttributeList::AT_ObjCOwnership)
         destChunk = maybeMovePastReturnType(declarator, i - 1);
@@ -664,7 +663,7 @@
                              /*HasProto=*/true,
                              /*IsAmbiguous=*/false,
                              /*LParenLoc=*/NoLoc,
-                             /*ArgInfo=*/0,
+                             /*ArgInfo=*/nullptr,
                              /*NumArgs=*/0,
                              /*EllipsisLoc=*/NoLoc,
                              /*RParenLoc=*/NoLoc,
@@ -676,10 +675,10 @@
                              /*MutableLoc=*/NoLoc,
                              EST_None,
                              /*ESpecLoc=*/NoLoc,
-                             /*Exceptions=*/0,
-                             /*ExceptionRanges=*/0,
+                             /*Exceptions=*/nullptr,
+                             /*ExceptionRanges=*/nullptr,
                              /*NumExceptions=*/0,
-                             /*NoexceptExpr=*/0,
+                             /*NoexceptExpr=*/nullptr,
                              loc, loc, declarator));
 
   // For consistency, make sure the state still has us as processing
@@ -728,13 +727,15 @@
       Result = Context.WCharTy;
     else if (DS.getTypeSpecSign() == DeclSpec::TSS_signed) {
       S.Diag(DS.getTypeSpecSignLoc(), diag::ext_invalid_sign_spec)
-        << DS.getSpecifierName(DS.getTypeSpecType());
+        << DS.getSpecifierName(DS.getTypeSpecType(),
+                               Context.getPrintingPolicy());
       Result = Context.getSignedWCharType();
     } else {
       assert(DS.getTypeSpecSign() == DeclSpec::TSS_unsigned &&
         "Unknown TSS value");
       S.Diag(DS.getTypeSpecSignLoc(), diag::ext_invalid_sign_spec)
-        << DS.getSpecifierName(DS.getTypeSpecType());
+        << DS.getSpecifierName(DS.getTypeSpecType(),
+                               Context.getPrintingPolicy());
       Result = Context.getUnsignedWCharType();
     }
     break;
@@ -851,7 +852,7 @@
     break;
   }
   case DeclSpec::TST_int128:
-    if (!S.PP.getTargetInfo().hasInt128Type())
+    if (!S.Context.getTargetInfo().hasInt128Type())
       S.Diag(DS.getTypeSpecTypeLoc(), diag::err_int128_unsupported);
     if (DS.getTypeSpecSign() == DeclSpec::TSS_unsigned)
       Result = Context.UnsignedInt128Ty;
@@ -1058,38 +1059,6 @@
     }
     break;
 
-  case DeclSpec::TST_image1d_t:
-    Result = Context.OCLImage1dTy;
-    break;
-
-  case DeclSpec::TST_image1d_array_t:
-    Result = Context.OCLImage1dArrayTy;
-    break;
-
-  case DeclSpec::TST_image1d_buffer_t:
-    Result = Context.OCLImage1dBufferTy;
-    break;
-
-  case DeclSpec::TST_image2d_t:
-    Result = Context.OCLImage2dTy;
-    break;
-
-  case DeclSpec::TST_image2d_array_t:
-    Result = Context.OCLImage2dArrayTy;
-    break;
-
-  case DeclSpec::TST_image3d_t:
-    Result = Context.OCLImage3dTy;
-    break;
-
-  case DeclSpec::TST_sampler_t:
-    Result = Context.OCLSamplerTy;
-    break;
-
-  case DeclSpec::TST_event_t:
-    Result = Context.OCLEventTy;
-    break;
-
   case DeclSpec::TST_error:
     Result = Context.IntTy;
     declarator.setInvalidType(true);
@@ -1148,17 +1117,33 @@
       }
     }
 
-    // C++ [dcl.ref]p1:
+    // C++11 [dcl.ref]p1:
     //   Cv-qualified references are ill-formed except when the
-    //   cv-qualifiers are introduced through the use of a typedef
-    //   (7.1.3) or of a template type argument (14.3), in which
-    //   case the cv-qualifiers are ignored.
-    // FIXME: Shouldn't we be checking SCS_typedef here?
+    //   cv-qualifiers are introduced through the use of a typedef-name
+    //   or decltype-specifier, in which case the cv-qualifiers are ignored.
+    //
+    // There don't appear to be any other contexts in which a cv-qualified
+    // reference type could be formed, so the 'ill-formed' clause here appears
+    // to never happen.
     if (DS.getTypeSpecType() == DeclSpec::TST_typename &&
         TypeQuals && Result->isReferenceType()) {
-      TypeQuals &= ~DeclSpec::TQ_const;
-      TypeQuals &= ~DeclSpec::TQ_volatile;
-      TypeQuals &= ~DeclSpec::TQ_atomic;
+      // If this occurs outside a template instantiation, warn the user about
+      // it; they probably didn't mean to specify a redundant qualifier.
+      typedef std::pair<DeclSpec::TQ, SourceLocation> QualLoc;
+      QualLoc Quals[] = {
+        QualLoc(DeclSpec::TQ_const, DS.getConstSpecLoc()),
+        QualLoc(DeclSpec::TQ_volatile, DS.getVolatileSpecLoc()),
+        QualLoc(DeclSpec::TQ_atomic, DS.getAtomicSpecLoc())
+      };
+      for (unsigned I = 0, N = llvm::array_lengthof(Quals); I != N; ++I) {
+        if (S.ActiveTemplateInstantiations.empty()) {
+          if (TypeQuals & Quals[I].first)
+            S.Diag(Quals[I].second, diag::warn_typecheck_reference_qualifiers)
+              << DeclSpec::getSpecifierName(Quals[I].first) << Result
+              << FixItHint::CreateRemoval(Quals[I].second);
+        }
+        TypeQuals &= ~Quals[I].first;
+      }
     }
 
     // C90 6.5.3 constraints: "The same type qualifier shall not appear more
@@ -1327,6 +1312,59 @@
   return S.Context.getQualifiedType(type, qs);
 }
 
+static std::string getFunctionQualifiersAsString(const FunctionProtoType *FnTy){
+  std::string Quals =
+    Qualifiers::fromCVRMask(FnTy->getTypeQuals()).getAsString();
+
+  switch (FnTy->getRefQualifier()) {
+  case RQ_None:
+    break;
+
+  case RQ_LValue:
+    if (!Quals.empty())
+      Quals += ' ';
+    Quals += '&';
+    break;
+
+  case RQ_RValue:
+    if (!Quals.empty())
+      Quals += ' ';
+    Quals += "&&";
+    break;
+  }
+
+  return Quals;
+}
+
+namespace {
+/// Kinds of declarator that cannot contain a qualified function type.
+///
+/// C++98 [dcl.fct]p4 / C++11 [dcl.fct]p6:
+///     a function type with a cv-qualifier or a ref-qualifier can only appear
+///     at the topmost level of a type.
+///
+/// Parens and member pointers are permitted. We don't diagnose array and
+/// function declarators, because they don't allow function types at all.
+///
+/// The values of this enum are used in diagnostics.
+enum QualifiedFunctionKind { QFK_BlockPointer, QFK_Pointer, QFK_Reference };
+}
+
+/// Check whether the type T is a qualified function type, and if it is,
+/// diagnose that it cannot be contained within the given kind of declarator.
+static bool checkQualifiedFunction(Sema &S, QualType T, SourceLocation Loc,
+                                   QualifiedFunctionKind QFK) {
+  // Does T refer to a function type with a cv-qualifier or a ref-qualifier?
+  const FunctionProtoType *FPT = T->getAs<FunctionProtoType>();
+  if (!FPT || (FPT->getTypeQuals() == 0 && FPT->getRefQualifier() == RQ_None))
+    return false;
+
+  S.Diag(Loc, diag::err_compound_qualified_function_type)
+    << QFK << isa<FunctionType>(T.IgnoreParens()) << T
+    << getFunctionQualifiersAsString(FPT);
+  return true;
+}
+
 /// \brief Build a pointer type.
 ///
 /// \param T The type to which we'll be building a pointer.
@@ -1349,6 +1387,9 @@
     return QualType();
   }
 
+  if (checkQualifiedFunction(*this, T, Loc, QFK_Pointer))
+    return QualType();
+
   assert(!T->isObjCObjectType() && "Should build ObjCObjectPointerType");
 
   // In ARC, it is forbidden to build pointers to unqualified pointers.
@@ -1408,6 +1449,9 @@
     return QualType();
   }
 
+  if (checkQualifiedFunction(*this, T, Loc, QFK_Reference))
+    return QualType();
+
   // In ARC, it is forbidden to build references to unqualified pointers.
   if (getLangOpts().ObjCAutoRefCount)
     T = inferARCLifetimeForPointee(*this, T, Loc, /*reference*/ true);
@@ -1427,10 +1471,10 @@
   public:
     VLADiagnoser() : Sema::VerifyICEDiagnoser(true) {}
 
-    virtual void diagnoseNotICE(Sema &S, SourceLocation Loc, SourceRange SR) {
+    void diagnoseNotICE(Sema &S, SourceLocation Loc, SourceRange SR) override {
     }
 
-    virtual void diagnoseFold(Sema &S, SourceLocation Loc, SourceRange SR) {
+    void diagnoseFold(Sema &S, SourceLocation Loc, SourceRange SR) override {
       S.Diag(Loc, diag::ext_vla_folded_to_constant) << SR;
     }
   } Diagnoser;
@@ -1487,6 +1531,13 @@
                                diag::err_array_of_abstract_type))
       return QualType();
 
+    // Mentioning a member pointer type for an array type causes us to lock in
+    // an inheritance model, even if it's inside an unused typedef.
+    if (Context.getTargetInfo().getCXXABI().isMicrosoft())
+      if (const MemberPointerType *MPTy = T->getAs<MemberPointerType>())
+        if (!MPTy->getClass()->isDependentType())
+          RequireCompleteType(Loc, T, 0);
+
   } else {
     // C99 6.7.5.2p1: If the element type is an incomplete or function type,
     // reject it (e.g. void ary[7], struct foo ary[7], void ary[7]())
@@ -1515,7 +1566,7 @@
   if (ArraySize && ArraySize->hasPlaceholderType()) {
     ExprResult Result = CheckPlaceholderExpr(ArraySize);
     if (Result.isInvalid()) return QualType();
-    ArraySize = Result.take();
+    ArraySize = Result.get();
   }
 
   // Do lvalue-to-rvalue conversions on the array size expression.
@@ -1524,7 +1575,7 @@
     if (Result.isInvalid())
       return QualType();
 
-    ArraySize = Result.take();
+    ArraySize = Result.get();
   }
 
   // C99 6.7.5.2p1: The size expression shall have integer type.
@@ -1540,7 +1591,7 @@
   llvm::APSInt ConstVal(Context.getTypeSize(Context.getSizeType()));
   if (!ArraySize) {
     if (ASM == ArrayType::Star)
-      T = Context.getVariableArrayType(T, 0, ASM, Quals, Brackets);
+      T = Context.getVariableArrayType(T, nullptr, ASM, Quals, Brackets);
     else
       T = Context.getIncompleteArrayType(T, ASM, Quals);
   } else if (ArraySize->isTypeDependent() || ArraySize->isValueDependent()) {
@@ -1614,6 +1665,7 @@
       // Prohibit the use of non-POD types in VLAs.
       QualType BaseT = Context.getBaseElementType(T);
       if (!T->isDependentType() &&
+          !RequireCompleteType(Loc, BaseT, 0) &&
           !BaseT.isPODType(Context) &&
           !BaseT->isObjCLifetimeType()) {
         Diag(Loc, diag::err_vla_non_pod)
@@ -1711,7 +1763,7 @@
 }
 
 QualType Sema::BuildFunctionType(QualType T,
-                                 llvm::MutableArrayRef<QualType> ParamTypes,
+                                 MutableArrayRef<QualType> ParamTypes,
                                  SourceLocation Loc, DeclarationName Entity,
                                  const FunctionProtoType::ExtProtoInfo &EPI) {
   bool Invalid = false;
@@ -1769,13 +1821,13 @@
   //   with reference type, or "cv void."
   if (T->isReferenceType()) {
     Diag(Loc, diag::err_illegal_decl_mempointer_to_reference)
-      << (Entity? Entity.getAsString() : "type name") << T;
+      << getPrintableNameForEntity(Entity) << T;
     return QualType();
   }
 
   if (T->isVoidType()) {
     Diag(Loc, diag::err_illegal_decl_mempointer_to_void)
-      << (Entity? Entity.getAsString() : "type name");
+      << getPrintableNameForEntity(Entity);
     return QualType();
   }
 
@@ -1784,35 +1836,10 @@
     return QualType();
   }
 
-  // C++ allows the class type in a member pointer to be an incomplete type.
-  // In the Microsoft ABI, the size of the member pointer can vary
-  // according to the class type, which means that we really need a
-  // complete type if possible, which means we need to instantiate templates.
-  //
-  // If template instantiation fails or the type is just incomplete, we have to
-  // add an extra slot to the member pointer.  Yes, this does cause problems
-  // when passing pointers between TUs that disagree about the size.
-  if (Context.getTargetInfo().getCXXABI().isMicrosoft()) {
-    CXXRecordDecl *RD = Class->getAsCXXRecordDecl();
-    if (RD && !RD->hasAttr<MSInheritanceAttr>()) {
-      // Lock in the inheritance model on the first use of a member pointer.
-      // Otherwise we may disagree about the size at different points in the TU.
-      // FIXME: MSVC picks a model on the first use that needs to know the size,
-      // rather than on the first mention of the type, e.g. typedefs.
-      if (RequireCompleteType(Loc, Class, 0) && !RD->isBeingDefined()) {
-        // We know it doesn't have an attribute and it's incomplete, so use the
-        // unspecified inheritance model.  If we're in the record body, we can
-        // figure out the inheritance model.
-        for (CXXRecordDecl::redecl_iterator I = RD->redecls_begin(),
-             E = RD->redecls_end(); I != E; ++I) {
-          I->addAttr(::new (Context) UnspecifiedInheritanceAttr(
-              RD->getSourceRange(), Context));
-        }
-      }
-    }
-  }
-
-  // FIXME: Adjust member function pointer calling conventions.
+  // Adjust the default free function calling convention to the default method
+  // calling convention.
+  if (T->isFunctionType())
+    adjustMemberFunctionCC(T, /*IsStatic=*/false);
 
   return Context.getMemberPointerType(T, Class.getTypePtr());
 }
@@ -1836,17 +1863,20 @@
     return QualType();
   }
 
+  if (checkQualifiedFunction(*this, T, Loc, QFK_BlockPointer))
+    return QualType();
+
   return Context.getBlockPointerType(T);
 }
 
 QualType Sema::GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo) {
   QualType QT = Ty.get();
   if (QT.isNull()) {
-    if (TInfo) *TInfo = 0;
+    if (TInfo) *TInfo = nullptr;
     return QualType();
   }
 
-  TypeSourceInfo *DI = 0;
+  TypeSourceInfo *DI = nullptr;
   if (const LocInfoType *LIT = dyn_cast<LocInfoType>(QT)) {
     QT = LIT->getType();
     DI = LIT->getTypeSourceInfo();
@@ -1959,18 +1989,15 @@
   // TODO: mark whether we did this inference?
 }
 
-static void diagnoseIgnoredQualifiers(
-    Sema &S, unsigned Quals,
-    SourceLocation FallbackLoc,
-    SourceLocation ConstQualLoc = SourceLocation(),
-    SourceLocation VolatileQualLoc = SourceLocation(),
-    SourceLocation RestrictQualLoc = SourceLocation(),
-    SourceLocation AtomicQualLoc = SourceLocation()) {
+void Sema::diagnoseIgnoredQualifiers(unsigned DiagID, unsigned Quals,
+                                     SourceLocation FallbackLoc,
+                                     SourceLocation ConstQualLoc,
+                                     SourceLocation VolatileQualLoc,
+                                     SourceLocation RestrictQualLoc,
+                                     SourceLocation AtomicQualLoc) {
   if (!Quals)
     return;
 
-  const SourceManager &SM = S.getSourceManager();
-
   struct Qual {
     unsigned Mask;
     const char *Name;
@@ -1997,7 +2024,8 @@
       SourceLocation QualLoc = QualKinds[I].Loc;
       if (!QualLoc.isInvalid()) {
         FixIts[NumQuals] = FixItHint::CreateRemoval(QualLoc);
-        if (Loc.isInvalid() || SM.isBeforeInTranslationUnit(QualLoc, Loc))
+        if (Loc.isInvalid() ||
+            getSourceManager().isBeforeInTranslationUnit(QualLoc, Loc))
           Loc = QualLoc;
       }
 
@@ -2005,19 +2033,20 @@
     }
   }
 
-  S.Diag(Loc.isInvalid() ? FallbackLoc : Loc, diag::warn_qual_return_type)
+  Diag(Loc.isInvalid() ? FallbackLoc : Loc, DiagID)
     << QualStr << NumQuals << FixIts[0] << FixIts[1] << FixIts[2] << FixIts[3];
 }
 
 // Diagnose pointless type qualifiers on the return type of a function.
-static void diagnoseIgnoredFunctionQualifiers(Sema &S, QualType RetTy,
-                                              Declarator &D,
-                                              unsigned FunctionChunkIndex) {
+static void diagnoseRedundantReturnTypeQualifiers(Sema &S, QualType RetTy,
+                                                  Declarator &D,
+                                                  unsigned FunctionChunkIndex) {
   if (D.getTypeObject(FunctionChunkIndex).Fun.hasTrailingReturnType()) {
     // FIXME: TypeSourceInfo doesn't preserve location information for
     // qualifiers.
-    diagnoseIgnoredQualifiers(S, RetTy.getLocalCVRQualifiers(),
-                              D.getIdentifierLoc());
+    S.diagnoseIgnoredQualifiers(diag::warn_qual_return_type,
+                                RetTy.getLocalCVRQualifiers(),
+                                D.getIdentifierLoc());
     return;
   }
 
@@ -2031,8 +2060,9 @@
 
     case DeclaratorChunk::Pointer: {
       DeclaratorChunk::PointerTypeInfo &PTI = OuterChunk.Ptr;
-      diagnoseIgnoredQualifiers(
-          S, PTI.TypeQuals,
+      S.diagnoseIgnoredQualifiers(
+          diag::warn_qual_return_type,
+          PTI.TypeQuals,
           SourceLocation(),
           SourceLocation::getFromRawEncoding(PTI.ConstQualLoc),
           SourceLocation::getFromRawEncoding(PTI.VolatileQualLoc),
@@ -2049,8 +2079,9 @@
       // FIXME: We can't currently provide an accurate source location and a
       // fix-it hint for these.
       unsigned AtomicQual = RetTy->isAtomicType() ? DeclSpec::TQ_atomic : 0;
-      diagnoseIgnoredQualifiers(S, RetTy.getCVRQualifiers() | AtomicQual,
-                                D.getIdentifierLoc());
+      S.diagnoseIgnoredQualifiers(diag::warn_qual_return_type,
+                                  RetTy.getCVRQualifiers() | AtomicQual,
+                                  D.getIdentifierLoc());
       return;
     }
 
@@ -2065,12 +2096,13 @@
 
   // Just parens all the way out to the decl specifiers. Diagnose any qualifiers
   // which are present there.
-  diagnoseIgnoredQualifiers(S, D.getDeclSpec().getTypeQualifiers(),
-                            D.getIdentifierLoc(),
-                            D.getDeclSpec().getConstSpecLoc(),
-                            D.getDeclSpec().getVolatileSpecLoc(),
-                            D.getDeclSpec().getRestrictSpecLoc(),
-                            D.getDeclSpec().getAtomicSpecLoc());
+  S.diagnoseIgnoredQualifiers(diag::warn_qual_return_type,
+                              D.getDeclSpec().getTypeQualifiers(),
+                              D.getIdentifierLoc(),
+                              D.getDeclSpec().getConstSpecLoc(),
+                              D.getDeclSpec().getVolatileSpecLoc(),
+                              D.getDeclSpec().getRestrictSpecLoc(),
+                              D.getDeclSpec().getAtomicSpecLoc());
 }
 
 static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
@@ -2078,10 +2110,10 @@
   Sema &SemaRef = state.getSema();
   Declarator &D = state.getDeclarator();
   QualType T;
-  ReturnTypeInfo = 0;
+  ReturnTypeInfo = nullptr;
 
   // The TagDecl owned by the DeclSpec.
-  TagDecl *OwnedTagDecl = 0;
+  TagDecl *OwnedTagDecl = nullptr;
 
   bool ContainsPlaceholderType = false;
 
@@ -2303,67 +2335,7 @@
   return T;
 }
 
-static std::string getFunctionQualifiersAsString(const FunctionProtoType *FnTy){
-  std::string Quals =
-    Qualifiers::fromCVRMask(FnTy->getTypeQuals()).getAsString();
-
-  switch (FnTy->getRefQualifier()) {
-  case RQ_None:
-    break;
-
-  case RQ_LValue:
-    if (!Quals.empty())
-      Quals += ' ';
-    Quals += '&';
-    break;
-
-  case RQ_RValue:
-    if (!Quals.empty())
-      Quals += ' ';
-    Quals += "&&";
-    break;
-  }
-
-  return Quals;
-}
-
-/// Check that the function type T, which has a cv-qualifier or a ref-qualifier,
-/// can be contained within the declarator chunk DeclType, and produce an
-/// appropriate diagnostic if not.
-static void checkQualifiedFunction(Sema &S, QualType T,
-                                   DeclaratorChunk &DeclType) {
-  // C++98 [dcl.fct]p4 / C++11 [dcl.fct]p6: a function type with a
-  // cv-qualifier or a ref-qualifier can only appear at the topmost level
-  // of a type.
-  int DiagKind = -1;
-  switch (DeclType.Kind) {
-  case DeclaratorChunk::Paren:
-  case DeclaratorChunk::MemberPointer:
-    // These cases are permitted.
-    return;
-  case DeclaratorChunk::Array:
-  case DeclaratorChunk::Function:
-    // These cases don't allow function types at all; no need to diagnose the
-    // qualifiers separately.
-    return;
-  case DeclaratorChunk::BlockPointer:
-    DiagKind = 0;
-    break;
-  case DeclaratorChunk::Pointer:
-    DiagKind = 1;
-    break;
-  case DeclaratorChunk::Reference:
-    DiagKind = 2;
-    break;
-  }
-
-  assert(DiagKind != -1);
-  S.Diag(DeclType.Loc, diag::err_compound_qualified_function_type)
-    << DiagKind << isa<FunctionType>(T.IgnoreParens()) << T
-    << getFunctionQualifiersAsString(T->castAs<FunctionProtoType>());
-}
-
-/// Produce an approprioate diagnostic for an ambiguity between a function
+/// Produce an appropriate diagnostic for an ambiguity between a function
 /// declarator and a C++ direct-initializer.
 static void warnAboutAmbiguousFunction(Sema &S, Declarator &D,
                                        DeclaratorChunk &DeclType, QualType RT) {
@@ -2375,11 +2347,11 @@
     return;
 
   // An initializer for a non-class type can have at most one argument.
-  if (!RT->isRecordType() && FTI.NumArgs > 1)
+  if (!RT->isRecordType() && FTI.NumParams > 1)
     return;
 
   // An initializer for a reference must have exactly one argument.
-  if (RT->isReferenceType() && FTI.NumArgs != 1)
+  if (RT->isReferenceType() && FTI.NumParams != 1)
     return;
 
   // Only warn if this declarator is declaring a function at block scope, and
@@ -2399,9 +2371,9 @@
   SourceRange ParenRange(DeclType.Loc, DeclType.EndLoc);
 
   S.Diag(DeclType.Loc,
-         FTI.NumArgs ? diag::warn_parens_disambiguated_as_function_declaration
-                     : diag::warn_empty_parens_are_function_decl)
-    << ParenRange;
+         FTI.NumParams ? diag::warn_parens_disambiguated_as_function_declaration
+                       : diag::warn_empty_parens_are_function_decl)
+      << ParenRange;
 
   // If the declaration looks like:
   //   T var1,
@@ -2422,21 +2394,21 @@
     }
   }
 
-  if (FTI.NumArgs > 0) {
-    // For a declaration with parameters, eg. "T var(T());", suggest adding parens
-    // around the first parameter to turn the declaration into a variable
-    // declaration.
-    SourceRange Range = FTI.ArgInfo[0].Param->getSourceRange();
+  if (FTI.NumParams > 0) {
+    // For a declaration with parameters, eg. "T var(T());", suggest adding
+    // parens around the first parameter to turn the declaration into a
+    // variable declaration.
+    SourceRange Range = FTI.Params[0].Param->getSourceRange();
     SourceLocation B = Range.getBegin();
-    SourceLocation E = S.PP.getLocForEndOfToken(Range.getEnd());
+    SourceLocation E = S.getLocForEndOfToken(Range.getEnd());
     // FIXME: Maybe we should suggest adding braces instead of parens
     // in C++11 for classes that don't have an initializer_list constructor.
     S.Diag(B, diag::note_additional_parens_for_variable_declaration)
       << FixItHint::CreateInsertion(B, "(")
       << FixItHint::CreateInsertion(E, ")");
   } else {
-    // For a declaration without parameters, eg. "T var();", suggest replacing the
-    // parens with an initializer to turn the declaration into a variable
+    // For a declaration without parameters, eg. "T var();", suggest replacing
+    // the parens with an initializer to turn the declaration into a variable
     // declaration.
     const CXXRecordDecl *RD = RT->getAsCXXRecordDecl();
 
@@ -2506,136 +2478,6 @@
                                                IsCXXInstanceMethod);
 }
 
-namespace {
-  /// A helper class to unwrap a type down to a function for the
-  /// purposes of applying attributes there.
-  ///
-  /// Use:
-  ///   FunctionTypeUnwrapper unwrapped(SemaRef, T);
-  ///   if (unwrapped.isFunctionType()) {
-  ///     const FunctionType *fn = unwrapped.get();
-  ///     // change fn somehow
-  ///     T = unwrapped.wrap(fn);
-  ///   }
-  struct FunctionTypeUnwrapper {
-    enum WrapKind {
-      Desugar,
-      Parens,
-      Pointer,
-      BlockPointer,
-      Reference,
-      MemberPointer
-    };
-
-    QualType Original;
-    const FunctionType *Fn;
-    SmallVector<unsigned char /*WrapKind*/, 8> Stack;
-
-    FunctionTypeUnwrapper(Sema &S, QualType T) : Original(T) {
-      while (true) {
-        const Type *Ty = T.getTypePtr();
-        if (isa<FunctionType>(Ty)) {
-          Fn = cast<FunctionType>(Ty);
-          return;
-        } else if (isa<ParenType>(Ty)) {
-          T = cast<ParenType>(Ty)->getInnerType();
-          Stack.push_back(Parens);
-        } else if (isa<PointerType>(Ty)) {
-          T = cast<PointerType>(Ty)->getPointeeType();
-          Stack.push_back(Pointer);
-        } else if (isa<BlockPointerType>(Ty)) {
-          T = cast<BlockPointerType>(Ty)->getPointeeType();
-          Stack.push_back(BlockPointer);
-        } else if (isa<MemberPointerType>(Ty)) {
-          T = cast<MemberPointerType>(Ty)->getPointeeType();
-          Stack.push_back(MemberPointer);
-        } else if (isa<ReferenceType>(Ty)) {
-          T = cast<ReferenceType>(Ty)->getPointeeType();
-          Stack.push_back(Reference);
-        } else {
-          const Type *DTy = Ty->getUnqualifiedDesugaredType();
-          if (Ty == DTy) {
-            Fn = 0;
-            return;
-          }
-
-          T = QualType(DTy, 0);
-          Stack.push_back(Desugar);
-        }
-      }
-    }
-
-    bool isFunctionType() const { return (Fn != 0); }
-    const FunctionType *get() const { return Fn; }
-
-    QualType wrap(Sema &S, const FunctionType *New) {
-      // If T wasn't modified from the unwrapped type, do nothing.
-      if (New == get()) return Original;
-
-      Fn = New;
-      return wrap(S.Context, Original, 0);
-    }
-
-  private:
-    QualType wrap(ASTContext &C, QualType Old, unsigned I) {
-      if (I == Stack.size())
-        return C.getQualifiedType(Fn, Old.getQualifiers());
-
-      // Build up the inner type, applying the qualifiers from the old
-      // type to the new type.
-      SplitQualType SplitOld = Old.split();
-
-      // As a special case, tail-recurse if there are no qualifiers.
-      if (SplitOld.Quals.empty())
-        return wrap(C, SplitOld.Ty, I);
-      return C.getQualifiedType(wrap(C, SplitOld.Ty, I), SplitOld.Quals);
-    }
-
-    QualType wrap(ASTContext &C, const Type *Old, unsigned I) {
-      if (I == Stack.size()) return QualType(Fn, 0);
-
-      switch (static_cast<WrapKind>(Stack[I++])) {
-      case Desugar:
-        // This is the point at which we potentially lose source
-        // information.
-        return wrap(C, Old->getUnqualifiedDesugaredType(), I);
-
-      case Parens: {
-        QualType New = wrap(C, cast<ParenType>(Old)->getInnerType(), I);
-        return C.getParenType(New);
-      }
-
-      case Pointer: {
-        QualType New = wrap(C, cast<PointerType>(Old)->getPointeeType(), I);
-        return C.getPointerType(New);
-      }
-
-      case BlockPointer: {
-        QualType New = wrap(C, cast<BlockPointerType>(Old)->getPointeeType(),I);
-        return C.getBlockPointerType(New);
-      }
-
-      case MemberPointer: {
-        const MemberPointerType *OldMPT = cast<MemberPointerType>(Old);
-        QualType New = wrap(C, OldMPT->getPointeeType(), I);
-        return C.getMemberPointerType(New, OldMPT->getClass());
-      }
-
-      case Reference: {
-        const ReferenceType *OldRef = cast<ReferenceType>(Old);
-        QualType New = wrap(C, OldRef->getPointeeType(), I);
-        if (isa<LValueReferenceType>(OldRef))
-          return C.getLValueReferenceType(New, OldRef->isSpelledAsLValue());
-        else
-          return C.getRValueReferenceType(New);
-      }
-      }
-
-      llvm_unreachable("unknown wrapping kind");
-    }
-  };
-}
-
 static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
                                                 QualType declSpecType,
                                                 TypeSourceInfo *TInfo) {
@@ -2709,10 +2551,7 @@
     unsigned chunkIndex = e - i - 1;
     state.setCurrentChunkIndex(chunkIndex);
     DeclaratorChunk &DeclType = D.getTypeObject(chunkIndex);
-    if (IsQualifiedFunction) {
-      checkQualifiedFunction(S, T, DeclType);
-      IsQualifiedFunction = DeclType.Kind == DeclaratorChunk::Paren;
-    }
+    IsQualifiedFunction &= DeclType.Kind == DeclaratorChunk::Paren;
     switch (DeclType.Kind) {
     case DeclaratorChunk::Paren:
       T = S.BuildParenType(T);
@@ -2755,7 +2594,6 @@
       }
       T = S.BuildReferenceType(T, DeclType.Ref.LValueRef, DeclType.Loc, Name);
 
-      Qualifiers Quals;
       if (DeclType.Ref.HasRestrict)
         T = S.BuildQualifiedType(T, DeclType.Loc, Qualifiers::Restrict);
       break;
@@ -2857,11 +2695,13 @@
       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().getTypeSpecType() == DeclSpec::TST_auto &&
+        if (D.getDeclSpec().containsPlaceholderType() &&
             !FTI.hasTrailingReturnType() && chunkIndex == 0 &&
             !S.getLangOpts().CPlusPlus1y) {
           S.Diag(D.getDeclSpec().getTypeSpecTypeLoc(),
-               diag::err_auto_missing_trailing_return);
+                 D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto
+                     ? diag::err_auto_missing_trailing_return
+                     : diag::err_deduced_return_type);
           T = Context.IntTy;
           D.setInvalidType(true);
         } else if (FTI.hasTrailingReturnType()) {
@@ -2924,10 +2764,10 @@
         SourceLocation DiagLoc, FixitLoc;
         if (TInfo) {
           DiagLoc = TInfo->getTypeLoc().getLocStart();
-          FixitLoc = S.PP.getLocForEndOfToken(TInfo->getTypeLoc().getLocEnd());
+          FixitLoc = S.getLocForEndOfToken(TInfo->getTypeLoc().getLocEnd());
         } else {
           DiagLoc = D.getDeclSpec().getTypeSpecTypeLoc();
-          FixitLoc = S.PP.getLocForEndOfToken(D.getDeclSpec().getLocEnd());
+          FixitLoc = S.getLocForEndOfToken(D.getDeclSpec().getLocEnd());
         }
         S.Diag(DiagLoc, diag::err_object_cannot_be_passed_returned_by_value)
           << 0 << T
@@ -2950,7 +2790,7 @@
       if ((T.getCVRQualifiers() || T->isAtomicType()) &&
           !(S.getLangOpts().CPlusPlus &&
             (T->isDependentType() || T->isRecordType())))
-        diagnoseIgnoredFunctionQualifiers(S, T, D, chunkIndex);
+        diagnoseRedundantReturnTypeQualifiers(S, T, D, chunkIndex);
 
       // Objective-C ARC ownership qualifiers are ignored on the function
       // return type (by type canonicalization). Complain if this attribute
@@ -2990,13 +2830,12 @@
         }
       }
 
-      if (LangOpts.CPlusPlus && D.getDeclSpec().isTypeSpecOwned()) {
+      if (LangOpts.CPlusPlus && D.getDeclSpec().hasTagDefinition()) {
         // C++ [dcl.fct]p6:
         //   Types shall not be defined in return or parameter types.
         TagDecl *Tag = cast<TagDecl>(D.getDeclSpec().getRepAsDecl());
-        if (Tag->isCompleteDefinition())
-          S.Diag(Tag->getLocation(), diag::err_type_defined_in_result_type)
-            << Context.getTypeDeclType(Tag);
+        S.Diag(Tag->getLocation(), diag::err_type_defined_in_result_type)
+          << Context.getTypeDeclType(Tag);
       }
 
       // Exception specs are not allowed in typedefs. Complain, but add it
@@ -3013,14 +2852,14 @@
 
       FunctionType::ExtInfo EI(getCCForDeclaratorChunk(S, D, FTI, chunkIndex));
 
-      if (!FTI.NumArgs && !FTI.isVariadic && !LangOpts.CPlusPlus) {
+      if (!FTI.NumParams && !FTI.isVariadic && !LangOpts.CPlusPlus) {
         // Simple void foo(), where the incoming T is the result type.
         T = Context.getFunctionNoProtoType(T, EI);
       } else {
         // We allow a zero-parameter variadic function in C if the
         // function is marked with the "overloadable" attribute. Scan
         // for this attribute now.
-        if (!FTI.NumArgs && FTI.isVariadic && !LangOpts.CPlusPlus) {
+        if (!FTI.NumParams && FTI.isVariadic && !LangOpts.CPlusPlus) {
           bool Overloadable = false;
           for (const AttributeList *Attrs = D.getAttributes();
                Attrs; Attrs = Attrs->getNext()) {
@@ -3031,13 +2870,14 @@
           }
 
           if (!Overloadable)
-            S.Diag(FTI.getEllipsisLoc(), diag::err_ellipsis_first_arg);
+            S.Diag(FTI.getEllipsisLoc(), diag::err_ellipsis_first_param);
         }
 
-        if (FTI.NumArgs && FTI.ArgInfo[0].Param == 0) {
+        if (FTI.NumParams && FTI.Params[0].Param == nullptr) {
           // C99 6.7.5.3p3: Reject int(x,y,z) when it's not a function
           // definition.
-          S.Diag(FTI.ArgInfo[0].IdentLoc, diag::err_ident_list_in_fn_declaration);
+          S.Diag(FTI.Params[0].IdentLoc,
+                 diag::err_ident_list_in_fn_declaration);
           D.setInvalidType(true);
           // Recover by creating a K&R-style function type.
           T = Context.getFunctionNoProtoType(T, EI);
@@ -3053,52 +2893,51 @@
                     : FTI.RefQualifierIsLValueRef? RQ_LValue
                     : RQ_RValue;
 
-        // Otherwise, we have a function with an argument list that is
+        // Otherwise, we have a function with a parameter list that is
         // potentially variadic.
-        SmallVector<QualType, 16> ArgTys;
-        ArgTys.reserve(FTI.NumArgs);
+        SmallVector<QualType, 16> ParamTys;
+        ParamTys.reserve(FTI.NumParams);
 
-        SmallVector<bool, 16> ConsumedArguments;
-        ConsumedArguments.reserve(FTI.NumArgs);
-        bool HasAnyConsumedArguments = false;
+        SmallVector<bool, 16> ConsumedParameters;
+        ConsumedParameters.reserve(FTI.NumParams);
+        bool HasAnyConsumedParameters = false;
 
-        for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i) {
-          ParmVarDecl *Param = cast<ParmVarDecl>(FTI.ArgInfo[i].Param);
-          QualType ArgTy = Param->getType();
-          assert(!ArgTy.isNull() && "Couldn't parse type?");
+        for (unsigned i = 0, e = FTI.NumParams; i != e; ++i) {
+          ParmVarDecl *Param = cast<ParmVarDecl>(FTI.Params[i].Param);
+          QualType ParamTy = Param->getType();
+          assert(!ParamTy.isNull() && "Couldn't parse type?");
 
-          // Look for 'void'.  void is allowed only as a single argument to a
+          // Look for 'void'.  void is allowed only as a single parameter to a
           // function with no other parameters (C99 6.7.5.3p10).  We record
-          // int(void) as a FunctionProtoType with an empty argument list.
-          if (ArgTy->isVoidType()) {
+          // int(void) as a FunctionProtoType with an empty parameter list.
+          if (ParamTy->isVoidType()) {
             // If this is something like 'float(int, void)', reject it.  'void'
             // is an incomplete type (C99 6.2.5p19) and function decls cannot
-            // have arguments of incomplete type.
-            if (FTI.NumArgs != 1 || FTI.isVariadic) {
+            // have parameters of incomplete type.
+            if (FTI.NumParams != 1 || FTI.isVariadic) {
               S.Diag(DeclType.Loc, diag::err_void_only_param);
-              ArgTy = Context.IntTy;
-              Param->setType(ArgTy);
-            } else if (FTI.ArgInfo[i].Ident) {
+              ParamTy = Context.IntTy;
+              Param->setType(ParamTy);
+            } else if (FTI.Params[i].Ident) {
               // Reject, but continue to parse 'int(void abc)'.
-              S.Diag(FTI.ArgInfo[i].IdentLoc,
-                   diag::err_param_with_void_type);
-              ArgTy = Context.IntTy;
-              Param->setType(ArgTy);
+              S.Diag(FTI.Params[i].IdentLoc, diag::err_param_with_void_type);
+              ParamTy = Context.IntTy;
+              Param->setType(ParamTy);
             } else {
               // Reject, but continue to parse 'float(const void)'.
-              if (ArgTy.hasQualifiers())
+              if (ParamTy.hasQualifiers())
                 S.Diag(DeclType.Loc, diag::err_void_param_qualified);
 
-              // Do not add 'void' to the ArgTys list.
+              // Do not add 'void' to the list.
               break;
             }
-          } else if (ArgTy->isHalfType()) {
-            // Disallow half FP arguments.
+          } else if (ParamTy->isHalfType()) {
+            // Disallow half FP parameters.
             // FIXME: This really should be in BuildFunctionType.
             if (S.getLangOpts().OpenCL) {
               if (!S.getOpenCLOptions().cl_khr_fp16) {
                 S.Diag(Param->getLocation(),
-                  diag::err_opencl_half_argument) << ArgTy;
+                  diag::err_opencl_half_param) << ParamTy;
                 D.setInvalidType();
                 Param->setInvalidDecl();
               }
@@ -3108,12 +2947,12 @@
               D.setInvalidType();
             }
           } else if (!FTI.hasPrototype) {
-            if (ArgTy->isPromotableIntegerType()) {
-              ArgTy = Context.getPromotedIntegerType(ArgTy);
+            if (ParamTy->isPromotableIntegerType()) {
+              ParamTy = Context.getPromotedIntegerType(ParamTy);
               Param->setKNRPromoted(true);
-            } else if (const BuiltinType* BTy = ArgTy->getAs<BuiltinType>()) {
+            } else if (const BuiltinType* BTy = ParamTy->getAs<BuiltinType>()) {
               if (BTy->getKind() == BuiltinType::Float) {
-                ArgTy = Context.DoubleTy;
+                ParamTy = Context.DoubleTy;
                 Param->setKNRPromoted(true);
               }
             }
@@ -3121,20 +2960,20 @@
 
           if (LangOpts.ObjCAutoRefCount) {
             bool Consumed = Param->hasAttr<NSConsumedAttr>();
-            ConsumedArguments.push_back(Consumed);
-            HasAnyConsumedArguments |= Consumed;
+            ConsumedParameters.push_back(Consumed);
+            HasAnyConsumedParameters |= Consumed;
           }
 
-          ArgTys.push_back(ArgTy);
+          ParamTys.push_back(ParamTy);
         }
 
-        if (HasAnyConsumedArguments)
-          EPI.ConsumedArguments = ConsumedArguments.data();
+        if (HasAnyConsumedParameters)
+          EPI.ConsumedParameters = ConsumedParameters.data();
 
         SmallVector<QualType, 4> Exceptions;
         SmallVector<ParsedType, 2> DynamicExceptions;
         SmallVector<SourceRange, 2> DynamicExceptionRanges;
-        Expr *NoexceptExpr = 0;
+        Expr *NoexceptExpr = nullptr;
 
         if (FTI.getExceptionSpecType() == EST_Dynamic) {
           // FIXME: It's rather inefficient to have to split into two vectors
@@ -3157,7 +2996,7 @@
                                       Exceptions,
                                       EPI);
 
-        T = Context.getFunctionType(T, ArgTys, EPI);
+        T = Context.getFunctionType(T, ParamTys, EPI);
       }
 
       break;
@@ -3171,8 +3010,7 @@
         D.setInvalidType(true);
       } else if (S.isDependentScopeSpecifier(SS) ||
                  dyn_cast_or_null<CXXRecordDecl>(S.computeDeclContext(SS))) {
-        NestedNameSpecifier *NNS
-          = static_cast<NestedNameSpecifier*>(SS.getScopeRep());
+        NestedNameSpecifier *NNS = SS.getScopeRep();
         NestedNameSpecifier *NNSPrefix = NNS->getPrefix();
         switch (NNS->getKind()) {
         case NestedNameSpecifier::Identifier:
@@ -3240,27 +3078,14 @@
     // top-level template type arguments.
     bool FreeFunction;
     if (!D.getCXXScopeSpec().isSet()) {
-      const DeclSpec &Spec = D.getDeclSpec();
-      FreeFunction = (D.getContext() != Declarator::MemberContext &&
-                      D.getContext() != Declarator::LambdaExprContext) ||
-                     Spec.isFriendSpecified() ||
-                     Spec.getStorageClassSpec() == DeclSpec::SCS_typedef;
+      FreeFunction = ((D.getContext() != Declarator::MemberContext &&
+                       D.getContext() != Declarator::LambdaExprContext) ||
+                      D.getDeclSpec().isFriendSpecified());
     } else {
       DeclContext *DC = S.computeDeclContext(D.getCXXScopeSpec());
       FreeFunction = (DC && !DC->isRecord());
     }
 
-    if (!S.getCallingConvAttributedType(T)) {
-      CallingConv CC =
-        Context.getDefaultCallingConvention(FnTy->isVariadic(), !FreeFunction);
-      if (CC != FnTy->getCallConv()) {
-        FunctionType::ExtInfo EI = FnTy->getExtInfo().withCallingConv(CC);
-        FnTy = cast<FunctionProtoType>(S.Context.adjustFunctionType(FnTy, EI));
-        FunctionTypeUnwrapper Unwrapped(S, T);
-        T = Unwrapped.wrap(S, FnTy);
-      }
-    }
-
     // C++11 [dcl.fct]p6 (w/DR1417):
     // An attempt to specify a function type with a cv-qualifier-seq or a
     // ref-qualifier (including by typedef-name) is ill-formed unless it is:
@@ -3270,6 +3095,13 @@
     //    alias-declaration,
     //  - the type-id in the default argument of a type-parameter, or
     //  - the type-id of a template-argument for a type-parameter
+    //
+    // FIXME: Checking this here is insufficient. We accept-invalid on:
+    //
+    //   template<typename T> struct S { void f(T); };
+    //   S<int() const> s;
+    //
+    // ... for instance.
     if (IsQualifiedFunction &&
         !(!FreeFunction &&
           D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_static) &&
@@ -3309,7 +3141,7 @@
       EPI.TypeQuals = 0;
       EPI.RefQualifier = RQ_None;
 
-      T = Context.getFunctionType(FnTy->getResultType(), FnTy->getArgTypes(),
+      T = Context.getFunctionType(FnTy->getReturnType(), FnTy->getParamTypes(),
                                   EPI);
       // Rebuild any parens around the identifier in the function type.
       for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i) {
@@ -3427,7 +3259,7 @@
 
   TypeProcessingState state(*this, D);
 
-  TypeSourceInfo *ReturnTypeInfo = 0;
+  TypeSourceInfo *ReturnTypeInfo = nullptr;
   QualType T = GetDeclSpecTypeForDeclarator(state, ReturnTypeInfo);
   if (T.isNull())
     return Context.getNullTypeSourceInfo();
@@ -3462,7 +3294,7 @@
     if (attr->getKind() == AttributeList::AT_ObjCOwnership)
       return;
 
-  const char *attrStr = 0;
+  const char *attrStr = nullptr;
   switch (ownership) {
   case Qualifiers::OCL_None: llvm_unreachable("no ownership!");
   case Qualifiers::OCL_ExplicitNone: attrStr = "none"; break;
@@ -3481,7 +3313,7 @@
   // so that we don't make an AttributedType for it).
   AttributeList *attr = D.getAttributePool()
     .create(&S.Context.Idents.get("objc_ownership"), SourceLocation(),
-            /*scope*/ 0, SourceLocation(),
+            /*scope*/ nullptr, SourceLocation(),
             /*args*/ &Args, 1, AttributeList::AS_GNU);
   spliceAttrIntoList(*attr, chunk.getAttrListRef());
 
@@ -3542,7 +3374,7 @@
 TypeSourceInfo *Sema::GetTypeForDeclaratorCast(Declarator &D, QualType FromTy) {
   TypeProcessingState state(*this, D);
 
-  TypeSourceInfo *ReturnTypeInfo = 0;
+  TypeSourceInfo *ReturnTypeInfo = nullptr;
   QualType declSpecTy = GetDeclSpecTypeForDeclarator(state, ReturnTypeInfo);
   if (declSpecTy.isNull())
     return Context.getNullTypeSourceInfo();
@@ -3620,10 +3452,17 @@
   }
 
   TL.setAttrNameLoc(attrs->getLoc());
-  if (TL.hasAttrExprOperand() && attrs->isArgExpr(0))
+  if (TL.hasAttrExprOperand()) {
+    assert(attrs->isArgExpr(0) && "mismatched attribute operand kind");
     TL.setAttrExprOperand(attrs->getArgAsExpr(0));
-  else if (TL.hasAttrEnumOperand() && attrs->isArgIdent(0))
-    TL.setAttrEnumOperandLoc(attrs->getArgAsIdent(0)->Loc);
+  } else if (TL.hasAttrEnumOperand()) {
+    assert((attrs->isArgIdent(0) || attrs->isArgExpr(0)) &&
+           "unexpected attribute operand kind");
+    if (attrs->isArgIdent(0))
+      TL.setAttrEnumOperandLoc(attrs->getArgAsIdent(0)->Loc);
+    else
+      TL.setAttrEnumOperandLoc(attrs->getArgAsExpr(0)->getExprLoc());
+  }
 
   // FIXME: preserve this information to here.
   if (TL.hasAttrOperand())
@@ -3685,7 +3524,7 @@
       Visit(TL.getPointeeLoc());
     }
     void VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) {
-      TypeSourceInfo *TInfo = 0;
+      TypeSourceInfo *TInfo = nullptr;
       Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
 
       // If we got no declarator info from previous Sema routines,
@@ -3717,7 +3556,7 @@
       TL.setTypeofLoc(DS.getTypeSpecTypeLoc());
       TL.setParensRange(DS.getTypeofParensRange());
       assert(DS.getRepAsType());
-      TypeSourceInfo *TInfo = 0;
+      TypeSourceInfo *TInfo = nullptr;
       Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
       TL.setUnderlyingTInfo(TInfo);
     }
@@ -3727,7 +3566,7 @@
       TL.setKWLoc(DS.getTypeSpecTypeLoc());
       TL.setParensRange(DS.getTypeofParensRange());
       assert(DS.getRepAsType());
-      TypeSourceInfo *TInfo = 0;
+      TypeSourceInfo *TInfo = nullptr;
       Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
       TL.setUnderlyingTInfo(TInfo);
     }
@@ -3750,7 +3589,7 @@
       ElaboratedTypeKeyword Keyword
         = TypeWithKeyword::getKeywordForTypeSpec(DS.getTypeSpecType());
       if (DS.getTypeSpecType() == TST_typename) {
-        TypeSourceInfo *TInfo = 0;
+        TypeSourceInfo *TInfo = nullptr;
         Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
         if (TInfo) {
           TL.copy(TInfo->getTypeLoc().castAs<ElaboratedTypeLoc>());
@@ -3766,7 +3605,7 @@
     }
     void VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
       assert(DS.getTypeSpecType() == TST_typename);
-      TypeSourceInfo *TInfo = 0;
+      TypeSourceInfo *TInfo = nullptr;
       Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
       assert(TInfo);
       TL.copy(TInfo->getTypeLoc().castAs<DependentNameTypeLoc>());
@@ -3774,7 +3613,7 @@
     void VisitDependentTemplateSpecializationTypeLoc(
                                  DependentTemplateSpecializationTypeLoc TL) {
       assert(DS.getTypeSpecType() == TST_typename);
-      TypeSourceInfo *TInfo = 0;
+      TypeSourceInfo *TInfo = nullptr;
       Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
       assert(TInfo);
       TL.copy(
@@ -3790,7 +3629,7 @@
         TL.setKWLoc(DS.getTypeSpecTypeLoc());
         TL.setParensRange(DS.getTypeofParensRange());
 
-        TypeSourceInfo *TInfo = 0;
+        TypeSourceInfo *TInfo = nullptr;
         Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
         assert(TInfo);
         TL.getValueLoc().initializeFullCopy(TInfo->getTypeLoc());
@@ -3826,6 +3665,9 @@
     void VisitAttributedTypeLoc(AttributedTypeLoc TL) {
       fillAttributedTypeLoc(TL, Chunk.getAttrs());
     }
+    void VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
+      // nothing
+    }
     void VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
       assert(Chunk.Kind == DeclaratorChunk::BlockPointer);
       TL.setCaretLoc(Chunk.Loc);
@@ -3907,9 +3749,9 @@
       const DeclaratorChunk::FunctionTypeInfo &FTI = Chunk.Fun;
       TL.setLParenLoc(FTI.getLParenLoc());
       TL.setRParenLoc(FTI.getRParenLoc());
-      for (unsigned i = 0, e = TL.getNumArgs(), tpi = 0; i != e; ++i) {
-        ParmVarDecl *Param = cast<ParmVarDecl>(FTI.ArgInfo[i].Param);
-        TL.setArg(tpi++, Param);
+      for (unsigned i = 0, e = TL.getNumParams(), tpi = 0; i != e; ++i) {
+        ParmVarDecl *Param = cast<ParmVarDecl>(FTI.Params[i].Param);
+        TL.setParam(tpi++, Param);
       }
       // FIXME: exception specs
     }
@@ -3981,6 +3823,10 @@
       CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc();
     }
 
+    // FIXME: Ordering here?
+    while (AdjustedTypeLoc TL = CurrTL.getAs<AdjustedTypeLoc>())
+      CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc();
+
     DeclaratorLocFiller(Context, D.getTypeObject(i)).Visit(CurrTL);
     CurrTL = CurrTL.getNextTypeLoc().getUnqualifiedLoc();
   }
@@ -4021,7 +3867,8 @@
 TypeResult Sema::ActOnTypeName(Scope *S, Declarator &D) {
   // C99 6.7.6: Type names have no identifier.  This is already validated by
   // the parser.
-  assert(D.getIdentifier() == 0 && "Type name should have no identifier!");
+  assert(D.getIdentifier() == nullptr &&
+         "Type name should have no identifier!");
 
   TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
   QualType T = TInfo->getType();
@@ -4080,44 +3927,60 @@
     return;
   }
 
-  // Check the attribute arguments.
-  if (Attr.getNumArgs() != 1) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
-      << Attr.getName() << 1;
-    Attr.setInvalid();
-    return;
-  }
-  Expr *ASArgExpr = static_cast<Expr *>(Attr.getArgAsExpr(0));
-  llvm::APSInt addrSpace(32);
-  if (ASArgExpr->isTypeDependent() || ASArgExpr->isValueDependent() ||
-      !ASArgExpr->isIntegerConstantExpr(addrSpace, S.Context)) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
-      << Attr.getName() << AANT_ArgumentIntegerConstant
-      << ASArgExpr->getSourceRange();
-    Attr.setInvalid();
-    return;
-  }
-
-  // Bounds checking.
-  if (addrSpace.isSigned()) {
-    if (addrSpace.isNegative()) {
-      S.Diag(Attr.getLoc(), diag::err_attribute_address_space_negative)
+  unsigned ASIdx;
+  if (Attr.getKind() == AttributeList::AT_AddressSpace) {
+    // Check the attribute arguments.
+    if (Attr.getNumArgs() != 1) {
+      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
+        << Attr.getName() << 1;
+      Attr.setInvalid();
+      return;
+    }
+    Expr *ASArgExpr = static_cast<Expr *>(Attr.getArgAsExpr(0));
+    llvm::APSInt addrSpace(32);
+    if (ASArgExpr->isTypeDependent() || ASArgExpr->isValueDependent() ||
+        !ASArgExpr->isIntegerConstantExpr(addrSpace, S.Context)) {
+      S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
+        << Attr.getName() << AANT_ArgumentIntegerConstant
         << ASArgExpr->getSourceRange();
       Attr.setInvalid();
       return;
     }
-    addrSpace.setIsSigned(false);
-  }
-  llvm::APSInt max(addrSpace.getBitWidth());
-  max = Qualifiers::MaxAddressSpace;
-  if (addrSpace > max) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_address_space_too_high)
-      << int(Qualifiers::MaxAddressSpace) << ASArgExpr->getSourceRange();
-    Attr.setInvalid();
-    return;
-  }
 
-  unsigned ASIdx = static_cast<unsigned>(addrSpace.getZExtValue());
+    // Bounds checking.
+    if (addrSpace.isSigned()) {
+      if (addrSpace.isNegative()) {
+        S.Diag(Attr.getLoc(), diag::err_attribute_address_space_negative)
+          << ASArgExpr->getSourceRange();
+        Attr.setInvalid();
+        return;
+      }
+      addrSpace.setIsSigned(false);
+    }
+    llvm::APSInt max(addrSpace.getBitWidth());
+    max = Qualifiers::MaxAddressSpace;
+    if (addrSpace > max) {
+      S.Diag(Attr.getLoc(), diag::err_attribute_address_space_too_high)
+        << int(Qualifiers::MaxAddressSpace) << ASArgExpr->getSourceRange();
+      Attr.setInvalid();
+      return;
+    }
+    ASIdx = static_cast<unsigned>(addrSpace.getZExtValue());
+  } else {
+    // The keyword-based type attributes imply which address space to use.
+    switch (Attr.getKind()) {
+    case AttributeList::AT_OpenCLGlobalAddressSpace:
+      ASIdx = LangAS::opencl_global; break;
+    case AttributeList::AT_OpenCLLocalAddressSpace:
+      ASIdx = LangAS::opencl_local; break;
+    case AttributeList::AT_OpenCLConstantAddressSpace:
+      ASIdx = LangAS::opencl_constant; break;
+    default:
+      assert(Attr.getKind() == AttributeList::AT_OpenCLPrivateAddressSpace);
+      ASIdx = 0; break;
+    }
+  }
+  
   Type = S.Context.getAddrSpaceQualType(Type, ASIdx);
 }
 
@@ -4361,6 +4224,136 @@
   return true;
 }
 
+namespace {
+  /// A helper class to unwrap a type down to a function for the
+  /// purposes of applying attributes there.
+  ///
+  /// Use:
+  ///   FunctionTypeUnwrapper unwrapped(SemaRef, T);
+  ///   if (unwrapped.isFunctionType()) {
+  ///     const FunctionType *fn = unwrapped.get();
+  ///     // change fn somehow
+  ///     T = unwrapped.wrap(fn);
+  ///   }
+  struct FunctionTypeUnwrapper {
+    enum WrapKind {
+      Desugar,
+      Parens,
+      Pointer,
+      BlockPointer,
+      Reference,
+      MemberPointer
+    };
+
+    QualType Original;
+    const FunctionType *Fn;
+    SmallVector<unsigned char /*WrapKind*/, 8> Stack;
+
+    FunctionTypeUnwrapper(Sema &S, QualType T) : Original(T) {
+      while (true) {
+        const Type *Ty = T.getTypePtr();
+        if (isa<FunctionType>(Ty)) {
+          Fn = cast<FunctionType>(Ty);
+          return;
+        } else if (isa<ParenType>(Ty)) {
+          T = cast<ParenType>(Ty)->getInnerType();
+          Stack.push_back(Parens);
+        } else if (isa<PointerType>(Ty)) {
+          T = cast<PointerType>(Ty)->getPointeeType();
+          Stack.push_back(Pointer);
+        } else if (isa<BlockPointerType>(Ty)) {
+          T = cast<BlockPointerType>(Ty)->getPointeeType();
+          Stack.push_back(BlockPointer);
+        } else if (isa<MemberPointerType>(Ty)) {
+          T = cast<MemberPointerType>(Ty)->getPointeeType();
+          Stack.push_back(MemberPointer);
+        } else if (isa<ReferenceType>(Ty)) {
+          T = cast<ReferenceType>(Ty)->getPointeeType();
+          Stack.push_back(Reference);
+        } else {
+          const Type *DTy = Ty->getUnqualifiedDesugaredType();
+          if (Ty == DTy) {
+            Fn = nullptr;
+            return;
+          }
+
+          T = QualType(DTy, 0);
+          Stack.push_back(Desugar);
+        }
+      }
+    }
+
+    bool isFunctionType() const { return (Fn != nullptr); }
+    const FunctionType *get() const { return Fn; }
+
+    QualType wrap(Sema &S, const FunctionType *New) {
+      // If T wasn't modified from the unwrapped type, do nothing.
+      if (New == get()) return Original;
+
+      Fn = New;
+      return wrap(S.Context, Original, 0);
+    }
+
+  private:
+    QualType wrap(ASTContext &C, QualType Old, unsigned I) {
+      if (I == Stack.size())
+        return C.getQualifiedType(Fn, Old.getQualifiers());
+
+      // Build up the inner type, applying the qualifiers from the old
+      // type to the new type.
+      SplitQualType SplitOld = Old.split();
+
+      // As a special case, tail-recurse if there are no qualifiers.
+      if (SplitOld.Quals.empty())
+        return wrap(C, SplitOld.Ty, I);
+      return C.getQualifiedType(wrap(C, SplitOld.Ty, I), SplitOld.Quals);
+    }
+
+    QualType wrap(ASTContext &C, const Type *Old, unsigned I) {
+      if (I == Stack.size()) return QualType(Fn, 0);
+
+      switch (static_cast<WrapKind>(Stack[I++])) {
+      case Desugar:
+        // This is the point at which we potentially lose source
+        // information.
+        return wrap(C, Old->getUnqualifiedDesugaredType(), I);
+
+      case Parens: {
+        QualType New = wrap(C, cast<ParenType>(Old)->getInnerType(), I);
+        return C.getParenType(New);
+      }
+
+      case Pointer: {
+        QualType New = wrap(C, cast<PointerType>(Old)->getPointeeType(), I);
+        return C.getPointerType(New);
+      }
+
+      case BlockPointer: {
+        QualType New = wrap(C, cast<BlockPointerType>(Old)->getPointeeType(),I);
+        return C.getBlockPointerType(New);
+      }
+
+      case MemberPointer: {
+        const MemberPointerType *OldMPT = cast<MemberPointerType>(Old);
+        QualType New = wrap(C, OldMPT->getPointeeType(), I);
+        return C.getMemberPointerType(New, OldMPT->getClass());
+      }
+
+      case Reference: {
+        const ReferenceType *OldRef = cast<ReferenceType>(Old);
+        QualType New = wrap(C, OldRef->getPointeeType(), I);
+        if (isa<LValueReferenceType>(OldRef))
+          return C.getLValueReferenceType(New, OldRef->isSpelledAsLValue());
+        else
+          return C.getRValueReferenceType(New);
+      }
+      }
+
+      llvm_unreachable("unknown wrapping kind");
+    }
+  };
+}
+
 static bool handleMSPointerTypeQualifierAttr(TypeProcessingState &State,
                                              AttributeList &Attr,
                                              QualType &Type) {
@@ -4600,73 +4593,38 @@
   return true;
 }
 
+bool Sema::hasExplicitCallingConv(QualType &T) {
+  QualType R = T.IgnoreParens();
+  while (const AttributedType *AT = dyn_cast<AttributedType>(R)) {
+    if (AT->isCallingConv())
+      return true;
+    R = AT->getModifiedType().IgnoreParens();
+  }
+  return false;
+}
+
 void Sema::adjustMemberFunctionCC(QualType &T, bool IsStatic) {
-  const FunctionType *FT = T->castAs<FunctionType>();
+  FunctionTypeUnwrapper Unwrapped(*this, T);
+  const FunctionType *FT = Unwrapped.get();
   bool IsVariadic = (isa<FunctionProtoType>(FT) &&
                      cast<FunctionProtoType>(FT)->isVariadic());
-  CallingConv CC = FT->getCallConv();
 
   // Only adjust types with the default convention.  For example, on Windows we
   // should adjust a __cdecl type to __thiscall for instance methods, and a
   // __thiscall type to __cdecl for static methods.
-  CallingConv DefaultCC =
+  CallingConv CurCC = FT->getCallConv();
+  CallingConv FromCC =
       Context.getDefaultCallingConvention(IsVariadic, IsStatic);
-  if (CC != DefaultCC)
+  CallingConv ToCC = Context.getDefaultCallingConvention(IsVariadic, !IsStatic);
+  if (CurCC != FromCC || FromCC == ToCC)
     return;
 
-  // Check if there was an explicit attribute, but only look through parens.
-  // The intent is to look for an attribute on the current declarator, but not
-  // one that came from a typedef.
-  QualType R = T.IgnoreParens();
-  while (const AttributedType *AT = dyn_cast<AttributedType>(R)) {
-    if (AT->isCallingConv())
-      return;
-    R = AT->getModifiedType().IgnoreParens();
-  }
-
-  // FIXME: This loses sugar.  This should probably be fixed with an implicit
-  // AttributedType node that adjusts the convention.
-  CC = Context.getDefaultCallingConvention(IsVariadic, !IsStatic);
-  FT = Context.adjustFunctionType(FT, FT->getExtInfo().withCallingConv(CC));
-  FunctionTypeUnwrapper Unwrapped(*this, T);
-  T = Unwrapped.wrap(*this, FT);
-}
-
-/// Handle OpenCL image access qualifiers: read_only, write_only, read_write
-static void HandleOpenCLImageAccessAttribute(QualType& CurType,
-                                             const AttributeList &Attr,
-                                             Sema &S) {
-  // Check the attribute arguments.
-  if (Attr.getNumArgs() != 1) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
-      << Attr.getName() << 1;
-    Attr.setInvalid();
+  if (hasExplicitCallingConv(T))
     return;
-  }
-  Expr *sizeExpr = static_cast<Expr *>(Attr.getArgAsExpr(0));
-  llvm::APSInt arg(32);
-  if (sizeExpr->isTypeDependent() || sizeExpr->isValueDependent() ||
-      !sizeExpr->isIntegerConstantExpr(arg, S.Context)) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
-      << Attr.getName() << AANT_ArgumentIntegerConstant
-      << sizeExpr->getSourceRange();
-    Attr.setInvalid();
-    return;
-  }
-  unsigned iarg = static_cast<unsigned>(arg.getZExtValue());
-  switch (iarg) {
-  case CLIA_read_only:
-  case CLIA_write_only:
-  case CLIA_read_write:
-    // Implemented in a separate patch
-    break;
-  default:
-    // Implemented in a separate patch
-    S.Diag(Attr.getLoc(), diag::err_attribute_invalid_size)
-      << sizeExpr->getSourceRange();
-    Attr.setInvalid();
-    break;
-  }
+
+  FT = Context.adjustFunctionType(FT, FT->getExtInfo().withCallingConv(ToCC));
+  QualType Wrapped = Unwrapped.wrap(*this, FT);
+  T = Context.getAdjustedType(T, Wrapped);
 }
 
 /// HandleVectorSizeAttribute - this attribute is only applicable to integral
@@ -4771,17 +4729,25 @@
 }
 
 static bool isPermittedNeonBaseType(QualType &Ty,
-                                    VectorType::VectorKind VecKind,
-                                    bool IsAArch64) {
+                                    VectorType::VectorKind VecKind, Sema &S) {
   const BuiltinType *BTy = Ty->getAs<BuiltinType>();
   if (!BTy)
     return false;
 
+  llvm::Triple Triple = S.Context.getTargetInfo().getTriple();
+
+  // Signed poly is mathematically wrong, but has been baked into some ABIs by
+  // now.
+  bool IsPolyUnsigned = Triple.getArch() == llvm::Triple::aarch64 ||
+                        Triple.getArch() == llvm::Triple::aarch64_be ||
+                        Triple.getArch() == llvm::Triple::arm64 ||
+                        Triple.getArch() == llvm::Triple::arm64_be;
   if (VecKind == VectorType::NeonPolyVector) {
-    if (IsAArch64) {
+    if (IsPolyUnsigned) {
       // AArch64 polynomial vectors are unsigned and support poly64.
       return BTy->getKind() == BuiltinType::UChar ||
              BTy->getKind() == BuiltinType::UShort ||
+             BTy->getKind() == BuiltinType::ULong ||
              BTy->getKind() == BuiltinType::ULongLong;
     } else {
       // AArch32 polynomial vector are signed.
@@ -4792,7 +4758,12 @@
 
   // Non-polynomial vector types: the usual suspects are allowed, as well as
   // float64_t on AArch64.
-  if (IsAArch64 && BTy->getKind() == BuiltinType::Double)
+  bool Is64Bit = Triple.getArch() == llvm::Triple::aarch64 ||
+                 Triple.getArch() == llvm::Triple::aarch64_be ||
+                 Triple.getArch() == llvm::Triple::arm64 ||
+                 Triple.getArch() == llvm::Triple::arm64_be;
+
+  if (Is64Bit && BTy->getKind() == BuiltinType::Double)
     return true;
 
   return BTy->getKind() == BuiltinType::SChar ||
@@ -4801,6 +4772,8 @@
          BTy->getKind() == BuiltinType::UShort ||
          BTy->getKind() == BuiltinType::Int ||
          BTy->getKind() == BuiltinType::UInt ||
+         BTy->getKind() == BuiltinType::Long ||
+         BTy->getKind() == BuiltinType::ULong ||
          BTy->getKind() == BuiltinType::LongLong ||
          BTy->getKind() == BuiltinType::ULongLong ||
          BTy->getKind() == BuiltinType::Float ||
@@ -4842,10 +4815,7 @@
     return;
   }
   // Only certain element types are supported for Neon vectors.
-  llvm::Triple::ArchType Arch =
-        S.Context.getTargetInfo().getTriple().getArch();
-  if (!isPermittedNeonBaseType(CurType, VecKind,
-                               Arch == llvm::Triple::aarch64)) {
+  if (!isPermittedNeonBaseType(CurType, VecKind, S)) {
     S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << CurType;
     Attr.setInvalid();
     return;
@@ -4925,6 +4895,10 @@
       // it it breaks large amounts of Linux software.
       attr.setUsedAsTypeAttr();
       break;
+    case AttributeList::AT_OpenCLPrivateAddressSpace:
+    case AttributeList::AT_OpenCLGlobalAddressSpace:
+    case AttributeList::AT_OpenCLLocalAddressSpace:
+    case AttributeList::AT_OpenCLConstantAddressSpace:
     case AttributeList::AT_AddressSpace:
       HandleAddressSpaceTypeAttribute(type, attr, state.getSema());
       attr.setUsedAsTypeAttr();
@@ -4953,13 +4927,11 @@
       attr.setUsedAsTypeAttr();
       break;
     case AttributeList::AT_OpenCLImageAccess:
-      HandleOpenCLImageAccessAttribute(type, attr, state.getSema());
+      // FIXME: there should be some type checking happening here, I would
+      // imagine, but the original handler's checking was entirely superfluous.
       attr.setUsedAsTypeAttr();
       break;
 
-    case AttributeList::AT_Win64:
-      attr.setUsedAsTypeAttr();
-      break;
     MS_TYPE_ATTRS_CASELIST:
       if (!handleMSPointerTypeQualifierAttr(state, attr, type))
         attr.setUsedAsTypeAttr();
@@ -5072,7 +5044,7 @@
     TypeDiagnoserDiag(unsigned DiagID)
       : Sema::TypeDiagnoser(DiagID == 0), DiagID(DiagID) {}
 
-    virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) {
+    void diagnose(Sema &S, SourceLocation Loc, QualType T) override {
       if (Suppressed) return;
       S.Diag(Loc, DiagID) << T;
     }
@@ -5114,6 +5086,108 @@
   return false;
 }
 
+/// \brief Determine whether there is any declaration of \p D that was ever a
+///        definition (perhaps before module merging) and is currently visible.
+/// \param D The definition of the entity.
+/// \param Suggested Filled in with the declaration that should be made visible
+///        in order to provide a definition of this entity.
+static bool hasVisibleDefinition(Sema &S, NamedDecl *D, NamedDecl **Suggested) {
+  // Easy case: if we don't have modules, all declarations are visible.
+  if (!S.getLangOpts().Modules)
+    return true;
+
+  // If this definition was instantiated from a template, map back to the
+  // pattern from which it was instantiated.
+  //
+  // FIXME: There must be a better place for this to live.
+  if (auto *RD = dyn_cast<CXXRecordDecl>(D)) {
+    if (auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
+      auto From = TD->getInstantiatedFrom();
+      if (auto *CTD = From.dyn_cast<ClassTemplateDecl*>()) {
+        while (auto *NewCTD = CTD->getInstantiatedFromMemberTemplate()) {
+          if (NewCTD->isMemberSpecialization())
+            break;
+          CTD = NewCTD;
+        }
+        RD = CTD->getTemplatedDecl();
+      } else if (auto *CTPSD = From.dyn_cast<
+                     ClassTemplatePartialSpecializationDecl *>()) {
+        while (auto *NewCTPSD = CTPSD->getInstantiatedFromMember()) {
+          if (NewCTPSD->isMemberSpecialization())
+            break;
+          CTPSD = NewCTPSD;
+        }
+        RD = CTPSD;
+      }
+    } else if (isTemplateInstantiation(RD->getTemplateSpecializationKind())) {
+      while (auto *NewRD = RD->getInstantiatedFromMemberClass())
+        RD = NewRD;
+    }
+    D = RD->getDefinition();
+  } else if (auto *ED = dyn_cast<EnumDecl>(D)) {
+    while (auto *NewED = ED->getInstantiatedFromMemberEnum())
+      ED = NewED;
+    if (ED->isFixed()) {
+      // If the enum has a fixed underlying type, any declaration of it will do.
+      *Suggested = nullptr;
+      for (auto *Redecl : ED->redecls()) {
+        if (LookupResult::isVisible(S, Redecl))
+          return true;
+        if (Redecl->isThisDeclarationADefinition() ||
+            (Redecl->isCanonicalDecl() && !*Suggested))
+          *Suggested = Redecl;
+      }
+      return false;
+    }
+    D = ED->getDefinition();
+  }
+  assert(D && "missing definition for pattern of instantiated definition");
+
+  // FIXME: If we merged any other decl into D, and that declaration is visible,
+  // then we should consider a definition to be visible.
+  *Suggested = D;
+  return LookupResult::isVisible(S, D);
+}
+
+/// Locks in the inheritance model for the given class and all of its bases.
+static void assignInheritanceModel(Sema &S, CXXRecordDecl *RD) {
+  RD = RD->getMostRecentDecl();
+  if (!RD->hasAttr<MSInheritanceAttr>()) {
+    MSInheritanceAttr::Spelling IM;
+
+    switch (S.MSPointerToMemberRepresentationMethod) {
+    case LangOptions::PPTMK_BestCase:
+      IM = RD->calculateInheritanceModel();
+      break;
+    case LangOptions::PPTMK_FullGeneralitySingleInheritance:
+      IM = MSInheritanceAttr::Keyword_single_inheritance;
+      break;
+    case LangOptions::PPTMK_FullGeneralityMultipleInheritance:
+      IM = MSInheritanceAttr::Keyword_multiple_inheritance;
+      break;
+    case LangOptions::PPTMK_FullGeneralityVirtualInheritance:
+      IM = MSInheritanceAttr::Keyword_unspecified_inheritance;
+      break;
+    }
+
+    RD->addAttr(MSInheritanceAttr::CreateImplicit(
+        S.getASTContext(), IM,
+        /*BestCase=*/S.MSPointerToMemberRepresentationMethod ==
+            LangOptions::PPTMK_BestCase,
+        S.ImplicitMSInheritanceAttrLoc.isValid()
+            ? S.ImplicitMSInheritanceAttrLoc
+            : RD->getSourceRange()));
+  }
+
+  if (RD->hasDefinition()) {
+    // Assign inheritance models to all of the base classes, because now we can
+    // form pointers to members of base classes without calling
+    // RequireCompleteType on the pointer to member of the base class type.
+    for (const CXXBaseSpecifier &BS : RD->bases())
+      assignInheritanceModel(S, BS.getType()->getAsCXXRecordDecl());
+  }
+}
+
 /// \brief The implementation of RequireCompleteType
 bool Sema::RequireCompleteTypeImpl(SourceLocation Loc, QualType T,
                                    TypeDiagnoser &Diagnoser) {
@@ -5126,62 +5200,70 @@
   //         "Can't ask whether a dependent type is complete");
 
   // If we have a complete type, we're done.
-  NamedDecl *Def = 0;
+  NamedDecl *Def = nullptr;
   if (!T->isIncompleteType(&Def)) {
     // If we know about the definition but it is not visible, complain.
-    if (!Diagnoser.Suppressed && Def && !LookupResult::isVisible(*this, Def)) {
+    NamedDecl *SuggestedDef = nullptr;
+    if (!Diagnoser.Suppressed && Def &&
+        !hasVisibleDefinition(*this, Def, &SuggestedDef)) {
       // Suppress this error outside of a SFINAE context if we've already
       // emitted the error once for this type. There's no usefulness in
       // repeating the diagnostic.
       // FIXME: Add a Fix-It that imports the corresponding module or includes
       // the header.
-      Module *Owner = Def->getOwningModule();
+      Module *Owner = SuggestedDef->getOwningModule();
       Diag(Loc, diag::err_module_private_definition)
         << T << Owner->getFullModuleName();
-      Diag(Def->getLocation(), diag::note_previous_definition);
+      Diag(SuggestedDef->getLocation(), diag::note_previous_definition);
 
-      if (!isSFINAEContext()) {
-        // Recover by implicitly importing this module.
-        createImplicitModuleImport(Loc, Owner);
+      // Try to recover by implicitly importing this module.
+      createImplicitModuleImportForErrorRecovery(Loc, Owner);
+    }
+
+    // We lock in the inheritance model once somebody has asked us to ensure
+    // that a pointer-to-member type is complete.
+    if (Context.getTargetInfo().getCXXABI().isMicrosoft()) {
+      if (const MemberPointerType *MPTy = T->getAs<MemberPointerType>()) {
+        if (!MPTy->getClass()->isDependentType()) {
+          RequireCompleteType(Loc, QualType(MPTy->getClass(), 0), 0);
+          assignInheritanceModel(*this, MPTy->getMostRecentCXXRecordDecl());
+        }
       }
     }
 
     return false;
   }
 
-  // FIXME: If there's an unimported definition of this type in a module (for
+  const TagType *Tag = T->getAs<TagType>();
+  const ObjCInterfaceType *IFace = T->getAs<ObjCInterfaceType>();
+
+  // If there's an unimported definition of this type in a module (for
   // instance, because we forward declared it, then imported the definition),
   // import that definition now.
+  //
   // FIXME: What about other cases where an import extends a redeclaration
   // chain for a declaration that can be accessed through a mechanism other
   // than name lookup (eg, referenced in a template, or a variable whose type
   // could be completed by the module)?
+  if (Tag || IFace) {
+    NamedDecl *D =
+        Tag ? static_cast<NamedDecl *>(Tag->getDecl()) : IFace->getDecl();
 
-  const TagType *Tag = T->getAs<TagType>();
-  const ObjCInterfaceType *IFace = 0;
-
-  if (Tag) {
     // Avoid diagnosing invalid decls as incomplete.
-    if (Tag->getDecl()->isInvalidDecl())
+    if (D->isInvalidDecl())
       return true;
 
     // Give the external AST source a chance to complete the type.
-    if (Tag->getDecl()->hasExternalLexicalStorage()) {
-      Context.getExternalSource()->CompleteType(Tag->getDecl());
-      if (!Tag->isIncompleteType())
-        return false;
-    }
-  }
-  else if ((IFace = T->getAs<ObjCInterfaceType>())) {
-    // Avoid diagnosing invalid decls as incomplete.
-    if (IFace->getDecl()->isInvalidDecl())
-      return true;
+    if (auto *Source = Context.getExternalSource()) {
+      if (Tag)
+        Source->CompleteType(Tag->getDecl());
+      else
+        Source->CompleteType(IFace->getDecl());
 
-    // Give the external AST source a chance to complete the type.
-    if (IFace->getDecl()->hasExternalLexicalStorage()) {
-      Context.getExternalSource()->CompleteType(IFace->getDecl());
-      if (!IFace->isIncompleteType())
-        return false;
+      // If the external source completed the type, go through the motions
+      // again to ensure we're allowed to use the completed type.
+      if (!T->isIncompleteType())
+        return RequireCompleteTypeImpl(Loc, T, Diagnoser);
     }
   }
 
@@ -5324,29 +5406,26 @@
   if (RD->getNumVBases()) {
     Diag(RD->getLocation(), diag::note_non_literal_virtual_base)
       << getLiteralDiagFromTagKind(RD->getTagKind()) << RD->getNumVBases();
-    for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(),
-           E = RD->vbases_end(); I != E; ++I)
-      Diag(I->getLocStart(),
-           diag::note_constexpr_virtual_base_here) << I->getSourceRange();
+    for (const auto &I : RD->vbases())
+      Diag(I.getLocStart(), diag::note_constexpr_virtual_base_here)
+          << I.getSourceRange();
   } else if (!RD->isAggregate() && !RD->hasConstexprNonCopyMoveConstructor() &&
              !RD->hasTrivialDefaultConstructor()) {
     Diag(RD->getLocation(), diag::note_non_literal_no_constexpr_ctors) << RD;
   } else if (RD->hasNonLiteralTypeFieldsOrBases()) {
-    for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
-         E = RD->bases_end(); I != E; ++I) {
-      if (!I->getType()->isLiteralType(Context)) {
-        Diag(I->getLocStart(),
+    for (const auto &I : RD->bases()) {
+      if (!I.getType()->isLiteralType(Context)) {
+        Diag(I.getLocStart(),
              diag::note_non_literal_base_class)
-          << RD << I->getType() << I->getSourceRange();
+          << RD << I.getType() << I.getSourceRange();
         return true;
       }
     }
-    for (CXXRecordDecl::field_iterator I = RD->field_begin(),
-         E = RD->field_end(); I != E; ++I) {
+    for (const auto *I : RD->fields()) {
       if (!I->getType()->isLiteralType(Context) ||
           I->getType().isVolatileQualified()) {
         Diag(I->getLocation(), diag::note_non_literal_field)
-          << RD << *I << I->getType()
+          << RD << I << I->getType()
           << I->getType().isVolatileQualified();
         return true;
       }
@@ -5382,11 +5461,11 @@
     return T;
   NestedNameSpecifier *NNS;
   if (SS.isValid())
-    NNS = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
+    NNS = SS.getScopeRep();
   else {
     if (Keyword == ETK_None)
       return T;
-    NNS = 0;
+    NNS = nullptr;
   }
   return Context.getElaboratedType(Keyword, NNS, T);
 }
@@ -5394,7 +5473,7 @@
 QualType Sema::BuildTypeofExprType(Expr *E, SourceLocation Loc) {
   ExprResult ER = CheckPlaceholderExpr(E);
   if (ER.isInvalid()) return QualType();
-  E = ER.take();
+  E = ER.get();
 
   if (!E->isTypeDependent()) {
     QualType T = E->getType();
@@ -5474,7 +5553,7 @@
 QualType Sema::BuildDecltypeType(Expr *E, SourceLocation Loc) {
   ExprResult ER = CheckPlaceholderExpr(E);
   if (ER.isInvalid()) return QualType();
-  E = ER.take();
+  E = ER.get();
 
   return Context.getDecltypeType(E, getDecltypeForExpr(*this, E));
 }
@@ -5490,12 +5569,23 @@
     } else {
       QualType Underlying = BaseType;
       if (!BaseType->isDependentType()) {
+        // The enum could be incomplete if we're parsing its definition or
+        // recovering from an error.
+        NamedDecl *FwdDecl = nullptr;
+        if (BaseType->isIncompleteType(&FwdDecl)) {
+          Diag(Loc, diag::err_underlying_type_of_incomplete_enum) << BaseType;
+          Diag(FwdDecl->getLocation(), diag::note_forward_declaration) << FwdDecl;
+          return QualType();
+        }
+
         EnumDecl *ED = BaseType->getAs<EnumType>()->getDecl();
         assert(ED && "EnumType has no EnumDecl");
+
         DiagnoseUseOfDecl(ED, Loc);
+
         Underlying = ED->getIntegerType();
+        assert(!Underlying.isNull());
       }
-      assert(!Underlying.isNull());
       return Context.getUnaryTransformType(BaseType, Underlying,
                                         UnaryTransformType::EnumUnderlyingType);
     }
diff --git a/lib/Sema/TargetAttributesSema.cpp b/lib/Sema/TargetAttributesSema.cpp
deleted file mode 100644
index 45067de..0000000
--- a/lib/Sema/TargetAttributesSema.cpp
+++ /dev/null
@@ -1,353 +0,0 @@
-//===-- TargetAttributesSema.cpp - Encapsulate target attributes-*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains semantic analysis implementation for target-specific
-// attributes.
-//
-//===----------------------------------------------------------------------===//
-
-#include "TargetAttributesSema.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/Basic/TargetInfo.h"
-#include "clang/Sema/SemaInternal.h"
-#include "llvm/ADT/Triple.h"
-
-using namespace clang;
-
-TargetAttributesSema::~TargetAttributesSema() {}
-bool TargetAttributesSema::ProcessDeclAttribute(Scope *scope, Decl *D,
-                                    const AttributeList &Attr, Sema &S) const {
-  return false;
-}
-
-static void HandleARMInterruptAttr(Decl *d,
-                                   const AttributeList &Attr, Sema &S) {
-  // Check the attribute arguments.
-  if (Attr.getNumArgs() > 1) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments)
-        << 1;
-    return;
-  }
-
-  StringRef Str;
-  SourceLocation ArgLoc;
-
-  if (Attr.getNumArgs() == 0)
-    Str = "";
-  else if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str, &ArgLoc))
-    return;
-
-  ARMInterruptAttr::InterruptType Kind;
-  if (!ARMInterruptAttr::ConvertStrToInterruptType(Str, Kind)) {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
-        << Attr.getName() << Str << ArgLoc;
-    return;
-  }
-
-  unsigned Index = Attr.getAttributeSpellingListIndex();
-  d->addAttr(::new (S.Context)
-             ARMInterruptAttr(Attr.getLoc(), S.Context, Kind, Index));
-}
-
-namespace {
-  class ARMAttributesSema : public TargetAttributesSema {
-  public:
-    ARMAttributesSema() { }
-    bool ProcessDeclAttribute(Scope *scope, Decl *D,
-                              const AttributeList &Attr, Sema &S) const {
-      if (Attr.getName()->getName() == "interrupt") {
-        HandleARMInterruptAttr(D, Attr, S);
-        return true;
-      }
-      return false;
-    }
-  };
-}
-
-static void HandleMSP430InterruptAttr(Decl *d,
-                                      const AttributeList &Attr, Sema &S) {
-    // Check the attribute arguments.
-    if (Attr.getNumArgs() != 1) {
-      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
-        << Attr.getName() << 1;
-      return;
-    }
-
-    // FIXME: Check for decl - it should be void ()(void).
-
-    Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArgAsExpr(0));
-    llvm::APSInt NumParams(32);
-    if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) {
-      S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
-        << Attr.getName() << AANT_ArgumentIntegerConstant
-        << NumParamsExpr->getSourceRange();
-      return;
-    }
-
-    unsigned Num = NumParams.getLimitedValue(255);
-    if ((Num & 1) || Num > 30) {
-      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
-        << "interrupt" << (int)NumParams.getSExtValue()
-        << NumParamsExpr->getSourceRange();
-      return;
-    }
-
-    d->addAttr(::new (S.Context) MSP430InterruptAttr(Attr.getLoc(), S.Context, Num));
-    d->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context));
-  }
-
-namespace {
-  class MSP430AttributesSema : public TargetAttributesSema {
-  public:
-    MSP430AttributesSema() { }
-    bool ProcessDeclAttribute(Scope *scope, Decl *D,
-                              const AttributeList &Attr, Sema &S) const {
-      if (Attr.getName()->getName() == "interrupt") {
-        HandleMSP430InterruptAttr(D, Attr, S);
-        return true;
-      }
-      return false;
-    }
-  };
-}
-
-static void HandleX86ForceAlignArgPointerAttr(Decl *D,
-                                              const AttributeList& Attr,
-                                              Sema &S) {
-  // Check the attribute arguments.
-  if (Attr.getNumArgs() != 0) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
-      << Attr.getName() << 0;
-    return;
-  }
-
-  // If we try to apply it to a function pointer, don't warn, but don't
-  // do anything, either. It doesn't matter anyway, because there's nothing
-  // special about calling a force_align_arg_pointer function.
-  ValueDecl *VD = dyn_cast<ValueDecl>(D);
-  if (VD && VD->getType()->isFunctionPointerType())
-    return;
-  // Also don't warn on function pointer typedefs.
-  TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
-  if (TD && (TD->getUnderlyingType()->isFunctionPointerType() ||
-             TD->getUnderlyingType()->isFunctionType()))
-    return;
-  // Attribute can only be applied to function types.
-  if (!isa<FunctionDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
-      << Attr.getName() << /* function */0;
-    return;
-  }
-
-  D->addAttr(::new (S.Context) X86ForceAlignArgPointerAttr(Attr.getRange(),
-                                                           S.Context));
-}
-
-DLLImportAttr *Sema::mergeDLLImportAttr(Decl *D, SourceRange Range,
-                                        unsigned AttrSpellingListIndex) {
-  if (D->hasAttr<DLLExportAttr>()) {
-    Diag(Range.getBegin(), diag::warn_attribute_ignored) << "dllimport";
-    return NULL;
-  }
-
-  if (D->hasAttr<DLLImportAttr>())
-    return NULL;
-
-  if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
-    if (VD->hasDefinition()) {
-      // dllimport cannot be applied to definitions.
-      Diag(D->getLocation(), diag::warn_attribute_invalid_on_definition)
-        << "dllimport";
-      return NULL;
-    }
-  }
-
-  return ::new (Context) DLLImportAttr(Range, Context,
-                                       AttrSpellingListIndex);
-}
-
-static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
-  // check the attribute arguments.
-  if (Attr.getNumArgs() != 0) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
-      << Attr.getName() << 0;
-    return;
-  }
-
-  // Attribute can be applied only to functions or variables.
-  FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
-  if (!FD && !isa<VarDecl>(D)) {
-    // Apparently Visual C++ thinks it is okay to not emit a warning
-    // in this case, so only emit a warning when -fms-extensions is not
-    // specified.
-    if (!S.getLangOpts().MicrosoftExt)
-      S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
-        << Attr.getName() << 2 /*variable and function*/;
-    return;
-  }
-
-  // Currently, the dllimport attribute is ignored for inlined functions.
-  // Warning is emitted.
-  if (FD && FD->isInlineSpecified()) {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
-    return;
-  }
-
-  unsigned Index = Attr.getAttributeSpellingListIndex();
-  DLLImportAttr *NewAttr = S.mergeDLLImportAttr(D, Attr.getRange(), Index);
-  if (NewAttr)
-    D->addAttr(NewAttr);
-}
-
-DLLExportAttr *Sema::mergeDLLExportAttr(Decl *D, SourceRange Range,
-                                        unsigned AttrSpellingListIndex) {
-  if (DLLImportAttr *Import = D->getAttr<DLLImportAttr>()) {
-    Diag(Import->getLocation(), diag::warn_attribute_ignored) << "dllimport";
-    D->dropAttr<DLLImportAttr>();
-  }
-
-  if (D->hasAttr<DLLExportAttr>())
-    return NULL;
-
-  return ::new (Context) DLLExportAttr(Range, Context,
-                                       AttrSpellingListIndex);
-}
-
-static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
-  // check the attribute arguments.
-  if (Attr.getNumArgs() != 0) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
-      << Attr.getName() << 0;
-    return;
-  }
-
-  // Attribute can be applied only to functions or variables.
-  FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
-  if (!FD && !isa<VarDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
-      << Attr.getName() << 2 /*variable and function*/;
-    return;
-  }
-
-  // Currently, the dllexport attribute is ignored for inlined functions, unless
-  // the -fkeep-inline-functions flag has been used. Warning is emitted;
-  if (FD && FD->isInlineSpecified()) {
-    // FIXME: ... unless the -fkeep-inline-functions flag has been used.
-    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllexport";
-    return;
-  }
-
-  unsigned Index = Attr.getAttributeSpellingListIndex();
-  DLLExportAttr *NewAttr = S.mergeDLLExportAttr(D, Attr.getRange(), Index);
-  if (NewAttr)
-    D->addAttr(NewAttr);
-}
-
-namespace {
-  class X86AttributesSema : public TargetAttributesSema {
-  public:
-    X86AttributesSema() { }
-    bool ProcessDeclAttribute(Scope *scope, Decl *D,
-                              const AttributeList &Attr, Sema &S) const {
-      const llvm::Triple &Triple(S.Context.getTargetInfo().getTriple());
-      if (Triple.getOS() == llvm::Triple::Win32 ||
-          Triple.getOS() == llvm::Triple::MinGW32) {
-        switch (Attr.getKind()) {
-        case AttributeList::AT_DLLImport: HandleDLLImportAttr(D, Attr, S);
-                                          return true;
-        case AttributeList::AT_DLLExport: HandleDLLExportAttr(D, Attr, S);
-                                          return true;
-        default:                          break;
-        }
-      }
-      if (Triple.getArch() != llvm::Triple::x86_64 &&
-          (Attr.getName()->getName() == "force_align_arg_pointer" ||
-           Attr.getName()->getName() == "__force_align_arg_pointer__")) {
-        HandleX86ForceAlignArgPointerAttr(D, Attr, S);
-        return true;
-      }
-      return false;
-    }
-  };
-}
-
-static void HandleMips16Attr(Decl *D, const AttributeList &Attr, Sema &S) {
-  // check the attribute arguments.
-  if (Attr.getNumArgs()) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
-      << Attr.getName() << 0;
-    return;
-  }
-  // Attribute can only be applied to function types.
-  if (!isa<FunctionDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
-      << Attr.getName() << /* function */0;
-    return;
-  }
-  D->addAttr(::new (S.Context) Mips16Attr(Attr.getRange(), S.Context,
-                                          Attr.getAttributeSpellingListIndex()));
-}
-
-static void HandleNoMips16Attr(Decl *D, const AttributeList &Attr, Sema &S) {
-  // check the attribute arguments.
-  if (Attr.getNumArgs()) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
-      << Attr.getName() << 0;
-    return;
-  }
-  // Attribute can only be applied to function types.
-  if (!isa<FunctionDecl>(D)) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
-      << Attr.getName() << /* function */0;
-    return;
-  }
-  D->addAttr(::new (S.Context)
-             NoMips16Attr(Attr.getRange(), S.Context,
-                          Attr.getAttributeSpellingListIndex()));
-}
-
-namespace {
-  class MipsAttributesSema : public TargetAttributesSema {
-  public:
-    MipsAttributesSema() { }
-    bool ProcessDeclAttribute(Scope *scope, Decl *D, const AttributeList &Attr,
-                              Sema &S) const {
-      if (Attr.getName()->getName() == "mips16") {
-        HandleMips16Attr(D, Attr, S);
-        return true;
-      } else if (Attr.getName()->getName() == "nomips16") {
-        HandleNoMips16Attr(D, Attr, S);
-        return true;
-      }
-      return false;
-    }
-  };
-}
-
-const TargetAttributesSema &Sema::getTargetAttributesSema() const {
-  if (TheTargetAttributesSema)
-    return *TheTargetAttributesSema;
-
-  const llvm::Triple &Triple(Context.getTargetInfo().getTriple());
-  switch (Triple.getArch()) {
-  case llvm::Triple::arm:
-  case llvm::Triple::thumb:
-    return *(TheTargetAttributesSema = new ARMAttributesSema);
-  case llvm::Triple::msp430:
-    return *(TheTargetAttributesSema = new MSP430AttributesSema);
-  case llvm::Triple::x86:
-  case llvm::Triple::x86_64:
-    return *(TheTargetAttributesSema = new X86AttributesSema);
-  case llvm::Triple::mips:
-  case llvm::Triple::mipsel:
-    return *(TheTargetAttributesSema = new MipsAttributesSema);
-  default:
-    return *(TheTargetAttributesSema = new TargetAttributesSema);
-  }
-}
diff --git a/lib/Sema/TargetAttributesSema.h b/lib/Sema/TargetAttributesSema.h
deleted file mode 100644
index 410c900..0000000
--- a/lib/Sema/TargetAttributesSema.h
+++ /dev/null
@@ -1,27 +0,0 @@
-//===--- TargetAttributesSema.h - Semantic Analysis For Target Attributes -===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef CLANG_SEMA_TARGETSEMA_H
-#define CLANG_SEMA_TARGETSEMA_H
-
-namespace clang {
-  class Scope;
-  class Decl;
-  class AttributeList;
-  class Sema;
-
-  class TargetAttributesSema {
-  public:
-    virtual ~TargetAttributesSema();
-    virtual bool ProcessDeclAttribute(Scope *scope, Decl *D,
-                                      const AttributeList &Attr, Sema &S) const;
-  };
-}
-
-#endif
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 4b70e70..312811d 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -25,7 +25,6 @@
 #include "clang/AST/StmtCXX.h"
 #include "clang/AST/StmtObjC.h"
 #include "clang/AST/StmtOpenMP.h"
-#include "clang/Lex/Preprocessor.h"
 #include "clang/Sema/Designator.h"
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/Ownership.h"
@@ -345,7 +344,7 @@
   /// TransformExpr or TransformExprs.
   ///
   /// \returns the transformed initializer.
-  ExprResult TransformInitializer(Expr *Init, bool CXXDirectInit);
+  ExprResult TransformInitializer(Expr *Init, bool NotCopyInit);
 
   /// \brief Transform the given list of expressions.
   ///
@@ -372,7 +371,7 @@
   /// \returns true if an error occurred, false otherwise.
   bool TransformExprs(Expr **Inputs, unsigned NumInputs, bool IsCall,
                       SmallVectorImpl<Expr *> &Outputs,
-                      bool *ArgChanged = 0);
+                      bool *ArgChanged = nullptr);
 
   /// \brief Transform the given declaration, which is referenced from a type
   /// or expression.
@@ -434,10 +433,10 @@
   /// By default, transforms all of the types and declarations within the
   /// nested-name-specifier. Subclasses may override this function to provide
   /// alternate behavior.
-  NestedNameSpecifierLoc TransformNestedNameSpecifierLoc(
-                                                    NestedNameSpecifierLoc NNS,
-                                          QualType ObjectType = QualType(),
-                                          NamedDecl *FirstQualifierInScope = 0);
+  NestedNameSpecifierLoc
+  TransformNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
+                                  QualType ObjectType = QualType(),
+                                  NamedDecl *FirstQualifierInScope = nullptr);
 
   /// \brief Transform the given declaration name.
   ///
@@ -468,11 +467,11 @@
   /// By default, transforms the template name by transforming the declarations
   /// and nested-name-specifiers that occur within the template name.
   /// Subclasses may override this function to provide alternate behavior.
-  TemplateName TransformTemplateName(CXXScopeSpec &SS,
-                                     TemplateName Name,
-                                     SourceLocation NameLoc,
-                                     QualType ObjectType = QualType(),
-                                     NamedDecl *FirstQualifierInScope = 0);
+  TemplateName
+  TransformTemplateName(CXXScopeSpec &SS, TemplateName Name,
+                        SourceLocation NameLoc,
+                        QualType ObjectType = QualType(),
+                        NamedDecl *FirstQualifierInScope = nullptr);
 
   /// \brief Transform the given template argument.
   ///
@@ -593,9 +592,11 @@
 
   StmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
   ExprResult TransformCXXNamedCastExpr(CXXNamedCastExpr *E);
-
+  
+  typedef std::pair<ExprResult, QualType> InitCaptureInfoTy;
   /// \brief Transform the captures and body of a lambda expression.
-  ExprResult TransformLambdaScope(LambdaExpr *E, CXXMethodDecl *CallOperator);
+  ExprResult TransformLambdaScope(LambdaExpr *E, CXXMethodDecl *CallOperator, 
+       ArrayRef<InitCaptureInfoTy> InitCaptureExprsAndTypes);
 
   TemplateParameterList *TransformTemplateParameterList(
         TemplateParameterList *TPL) {
@@ -603,8 +604,16 @@
   }
 
   ExprResult TransformAddressOfOperand(Expr *E);
+
   ExprResult TransformDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E,
-                                                bool IsAddressOfOperand);
+                                                bool IsAddressOfOperand,
+                                                TypeSourceInfo **RecoveryTSI);
+
+  ExprResult TransformParenDependentScopeDeclRefExpr(
+      ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool IsAddressOfOperand,
+      TypeSourceInfo **RecoveryTSI);
+
+  StmtResult TransformOMPExecutableDirective(OMPExecutableDirective *S);
 
 // FIXME: We use LLVM_ATTRIBUTE_NOINLINE because inlining causes a ridiculous
 // amount of stack usage with clang.
@@ -741,7 +750,7 @@
   /// By default, performs semantic analysis when building the function type.
   /// Subclasses may override this routine to provide different behavior.
   QualType RebuildFunctionProtoType(QualType T,
-                                    llvm::MutableArrayRef<QualType> ParamTypes,
+                                    MutableArrayRef<QualType> ParamTypes,
                                     const FunctionProtoType::ExtProtoInfo &EPI);
 
   /// \brief Build a new unprototyped function type.
@@ -846,7 +855,8 @@
     CXXScopeSpec SS;
     SS.Adopt(QualifierLoc);
     TemplateName InstName
-      = getDerived().RebuildTemplateName(SS, *Name, NameLoc, QualType(), 0);
+      = getDerived().RebuildTemplateName(SS, *Name, NameLoc, QualType(),
+                                         nullptr);
 
     if (InstName.isNull())
       return QualType();
@@ -864,7 +874,7 @@
     getDerived().RebuildTemplateSpecializationType(InstName, NameLoc, Args);
     if (T.isNull()) return QualType();
 
-    if (Keyword == ETK_None && QualifierLoc.getNestedNameSpecifier() == 0)
+    if (Keyword == ETK_None && QualifierLoc.getNestedNameSpecifier() == nullptr)
       return T;
 
     return SemaRef.Context.getElaboratedType(Keyword,
@@ -910,7 +920,7 @@
     if (SemaRef.RequireCompleteDeclContext(SS, DC))
       return QualType();
 
-    TagDecl *Tag = 0;
+    TagDecl *Tag = nullptr;
     SemaRef.LookupQualifiedName(Result, DC);
     switch (Result.getResultKind()) {
       case LookupResult::NotFound:
@@ -949,9 +959,8 @@
           break;
         }
         default:
-          // FIXME: Would be nice to highlight just the source range.
           SemaRef.Diag(IdLoc, diag::err_not_tag_in_scope)
-            << Kind << Id << DC;
+              << Kind << Id << DC << QualifierLoc.getSourceRange();
           break;
       }
       return QualType();
@@ -1078,7 +1087,7 @@
                                       SourceLocation ColonLoc,
                                       Stmt *SubStmt) {
     return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, SubStmt,
-                                      /*CurScope=*/0);
+                                      /*CurScope=*/nullptr);
   }
 
   /// \brief Build a new label statement.
@@ -1185,14 +1194,14 @@
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
   StmtResult RebuildReturnStmt(SourceLocation ReturnLoc, Expr *Result) {
-    return getSema().ActOnReturnStmt(ReturnLoc, Result);
+    return getSema().BuildReturnStmt(ReturnLoc, Result);
   }
 
   /// \brief Build a new declaration statement.
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  StmtResult RebuildDeclStmt(llvm::MutableArrayRef<Decl *> Decls,
+  StmtResult RebuildDeclStmt(MutableArrayRef<Decl *> Decls,
                              SourceLocation StartLoc, SourceLocation EndLoc) {
     Sema::DeclGroupPtrTy DG = getSema().BuildDeclaratorGroup(Decls);
     return getSema().ActOnDeclStmt(DG, StartLoc, EndLoc);
@@ -1284,21 +1293,78 @@
     return getSema().BuildObjCAtThrowStmt(AtLoc, Operand);
   }
 
-  /// \brief Build a new OpenMP parallel directive.
+  /// \brief Build a new OpenMP executable directive.
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  StmtResult RebuildOMPParallelDirective(ArrayRef<OMPClause *> Clauses,
-                                         Stmt *AStmt,
-                                         SourceLocation StartLoc,
-                                         SourceLocation EndLoc) {
-    return getSema().ActOnOpenMPParallelDirective(Clauses, AStmt,
-                                                  StartLoc, EndLoc);
+  StmtResult RebuildOMPExecutableDirective(OpenMPDirectiveKind Kind,
+                                           DeclarationNameInfo DirName,
+                                           ArrayRef<OMPClause *> Clauses,
+                                           Stmt *AStmt, SourceLocation StartLoc,
+                                           SourceLocation EndLoc) {
+    return getSema().ActOnOpenMPExecutableDirective(Kind, DirName, Clauses,
+                                                    AStmt, StartLoc, EndLoc);
+  }
+
+  /// \brief Build a new OpenMP 'if' clause.
+  ///
+  /// By default, performs semantic analysis to build the new OpenMP clause.
+  /// Subclasses may override this routine to provide different behavior.
+  OMPClause *RebuildOMPIfClause(Expr *Condition,
+                                SourceLocation StartLoc,
+                                SourceLocation LParenLoc,
+                                SourceLocation EndLoc) {
+    return getSema().ActOnOpenMPIfClause(Condition, StartLoc,
+                                         LParenLoc, EndLoc);
+  }
+
+  /// \brief Build a new OpenMP 'final' clause.
+  ///
+  /// By default, performs semantic analysis to build the new OpenMP clause.
+  /// Subclasses may override this routine to provide different behavior.
+  OMPClause *RebuildOMPFinalClause(Expr *Condition, SourceLocation StartLoc,
+                                   SourceLocation LParenLoc,
+                                   SourceLocation EndLoc) {
+    return getSema().ActOnOpenMPFinalClause(Condition, StartLoc, LParenLoc,
+                                            EndLoc);
+  }
+
+  /// \brief Build a new OpenMP 'num_threads' clause.
+  ///
+  /// By default, performs semantic analysis to build the new OpenMP clause.
+  /// Subclasses may override this routine to provide different behavior.
+  OMPClause *RebuildOMPNumThreadsClause(Expr *NumThreads,
+                                        SourceLocation StartLoc,
+                                        SourceLocation LParenLoc,
+                                        SourceLocation EndLoc) {
+    return getSema().ActOnOpenMPNumThreadsClause(NumThreads, StartLoc,
+                                                 LParenLoc, EndLoc);
+  }
+
+  /// \brief Build a new OpenMP 'safelen' clause.
+  ///
+  /// By default, performs semantic analysis to build the new OpenMP clause.
+  /// Subclasses may override this routine to provide different behavior.
+  OMPClause *RebuildOMPSafelenClause(Expr *Len, SourceLocation StartLoc,
+                                     SourceLocation LParenLoc,
+                                     SourceLocation EndLoc) {
+    return getSema().ActOnOpenMPSafelenClause(Len, StartLoc, LParenLoc, EndLoc);
+  }
+
+  /// \brief Build a new OpenMP 'collapse' clause.
+  ///
+  /// By default, performs semantic analysis to build the new OpenMP clause.
+  /// Subclasses may override this routine to provide different behavior.
+  OMPClause *RebuildOMPCollapseClause(Expr *Num, SourceLocation StartLoc,
+                                      SourceLocation LParenLoc,
+                                      SourceLocation EndLoc) {
+    return getSema().ActOnOpenMPCollapseClause(Num, StartLoc, LParenLoc,
+                                               EndLoc);
   }
 
   /// \brief Build a new OpenMP 'default' clause.
   ///
-  /// By default, performs semantic analysis to build the new statement.
+  /// By default, performs semantic analysis to build the new OpenMP clause.
   /// Subclasses may override this routine to provide different behavior.
   OMPClause *RebuildOMPDefaultClause(OpenMPDefaultClauseKind Kind,
                                      SourceLocation KindKwLoc,
@@ -1309,9 +1375,37 @@
                                               StartLoc, LParenLoc, EndLoc);
   }
 
+  /// \brief Build a new OpenMP 'proc_bind' clause.
+  ///
+  /// By default, performs semantic analysis to build the new OpenMP clause.
+  /// Subclasses may override this routine to provide different behavior.
+  OMPClause *RebuildOMPProcBindClause(OpenMPProcBindClauseKind Kind,
+                                      SourceLocation KindKwLoc,
+                                      SourceLocation StartLoc,
+                                      SourceLocation LParenLoc,
+                                      SourceLocation EndLoc) {
+    return getSema().ActOnOpenMPProcBindClause(Kind, KindKwLoc,
+                                               StartLoc, LParenLoc, EndLoc);
+  }
+
+  /// \brief Build a new OpenMP 'schedule' clause.
+  ///
+  /// By default, performs semantic analysis to build the new OpenMP clause.
+  /// Subclasses may override this routine to provide different behavior.
+  OMPClause *RebuildOMPScheduleClause(OpenMPScheduleClauseKind Kind,
+                                      Expr *ChunkSize,
+                                      SourceLocation StartLoc,
+                                      SourceLocation LParenLoc,
+                                      SourceLocation KindLoc,
+                                      SourceLocation CommaLoc,
+                                      SourceLocation EndLoc) {
+    return getSema().ActOnOpenMPScheduleClause(
+        Kind, ChunkSize, StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc);
+  }
+
   /// \brief Build a new OpenMP 'private' clause.
   ///
-  /// By default, performs semantic analysis to build the new statement.
+  /// By default, performs semantic analysis to build the new OpenMP clause.
   /// Subclasses may override this routine to provide different behavior.
   OMPClause *RebuildOMPPrivateClause(ArrayRef<Expr *> VarList,
                                      SourceLocation StartLoc,
@@ -1323,7 +1417,7 @@
 
   /// \brief Build a new OpenMP 'firstprivate' clause.
   ///
-  /// By default, performs semantic analysis to build the new statement.
+  /// By default, performs semantic analysis to build the new OpenMP clause.
   /// Subclasses may override this routine to provide different behavior.
   OMPClause *RebuildOMPFirstprivateClause(ArrayRef<Expr *> VarList,
                                           SourceLocation StartLoc,
@@ -1333,6 +1427,22 @@
                                                    EndLoc);
   }
 
+  /// \brief Build a new OpenMP 'lastprivate' clause.
+  ///
+  /// By default, performs semantic analysis to build the new OpenMP clause.
+  /// Subclasses may override this routine to provide different behavior.
+  OMPClause *RebuildOMPLastprivateClause(ArrayRef<Expr *> VarList,
+                                         SourceLocation StartLoc,
+                                         SourceLocation LParenLoc,
+                                         SourceLocation EndLoc) {
+    return getSema().ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc,
+                                                  EndLoc);
+  }
+
+  /// \brief Build a new OpenMP 'shared' clause.
+  ///
+  /// By default, performs semantic analysis to build the new OpenMP clause.
+  /// Subclasses may override this routine to provide different behavior.
   OMPClause *RebuildOMPSharedClause(ArrayRef<Expr *> VarList,
                                     SourceLocation StartLoc,
                                     SourceLocation LParenLoc,
@@ -1341,6 +1451,84 @@
                                              EndLoc);
   }
 
+  /// \brief Build a new OpenMP 'reduction' clause.
+  ///
+  /// By default, performs semantic analysis to build the new statement.
+  /// Subclasses may override this routine to provide different behavior.
+  OMPClause *RebuildOMPReductionClause(ArrayRef<Expr *> VarList,
+                                       SourceLocation StartLoc,
+                                       SourceLocation LParenLoc,
+                                       SourceLocation ColonLoc,
+                                       SourceLocation EndLoc,
+                                       CXXScopeSpec &ReductionIdScopeSpec,
+                                       const DeclarationNameInfo &ReductionId) {
+    return getSema().ActOnOpenMPReductionClause(
+        VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
+        ReductionId);
+  }
+
+  /// \brief Build a new OpenMP 'linear' clause.
+  ///
+  /// By default, performs semantic analysis to build the new OpenMP clause.
+  /// Subclasses may override this routine to provide different behavior.
+  OMPClause *RebuildOMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step,
+                                    SourceLocation StartLoc,
+                                    SourceLocation LParenLoc,
+                                    SourceLocation ColonLoc,
+                                    SourceLocation EndLoc) {
+    return getSema().ActOnOpenMPLinearClause(VarList, Step, StartLoc, LParenLoc,
+                                             ColonLoc, EndLoc);
+  }
+
+  /// \brief Build a new OpenMP 'aligned' clause.
+  ///
+  /// By default, performs semantic analysis to build the new OpenMP clause.
+  /// Subclasses may override this routine to provide different behavior.
+  OMPClause *RebuildOMPAlignedClause(ArrayRef<Expr *> VarList, Expr *Alignment,
+                                     SourceLocation StartLoc,
+                                     SourceLocation LParenLoc,
+                                     SourceLocation ColonLoc,
+                                     SourceLocation EndLoc) {
+    return getSema().ActOnOpenMPAlignedClause(VarList, Alignment, StartLoc,
+                                              LParenLoc, ColonLoc, EndLoc);
+  }
+
+  /// \brief Build a new OpenMP 'copyin' clause.
+  ///
+  /// By default, performs semantic analysis to build the new OpenMP clause.
+  /// Subclasses may override this routine to provide different behavior.
+  OMPClause *RebuildOMPCopyinClause(ArrayRef<Expr *> VarList,
+                                    SourceLocation StartLoc,
+                                    SourceLocation LParenLoc,
+                                    SourceLocation EndLoc) {
+    return getSema().ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc,
+                                             EndLoc);
+  }
+
+  /// \brief Build a new OpenMP 'copyprivate' clause.
+  ///
+  /// By default, performs semantic analysis to build the new OpenMP clause.
+  /// Subclasses may override this routine to provide different behavior.
+  OMPClause *RebuildOMPCopyprivateClause(ArrayRef<Expr *> VarList,
+                                         SourceLocation StartLoc,
+                                         SourceLocation LParenLoc,
+                                         SourceLocation EndLoc) {
+    return getSema().ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc,
+                                                  EndLoc);
+  }
+
+  /// \brief Build a new OpenMP 'flush' pseudo clause.
+  ///
+  /// By default, performs semantic analysis to build the new OpenMP clause.
+  /// Subclasses may override this routine to provide different behavior.
+  OMPClause *RebuildOMPFlushClause(ArrayRef<Expr *> VarList,
+                                   SourceLocation StartLoc,
+                                   SourceLocation LParenLoc,
+                                   SourceLocation EndLoc) {
+    return getSema().ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc,
+                                            EndLoc);
+  }
+
   /// \brief Rebuild the operand to an Objective-C \@synchronized statement.
   ///
   /// By default, performs semantic analysis to build the new statement.
@@ -1384,7 +1572,7 @@
     if (ForEachStmt.isInvalid())
       return StmtError();
 
-    return getSema().FinishObjCForCollectionStmt(ForEachStmt.take(), Body);
+    return getSema().FinishObjCForCollectionStmt(ForEachStmt.get(), Body);
   }
 
   /// \brief Build a new C++ exception declaration.
@@ -1396,7 +1584,7 @@
                                 SourceLocation StartLoc,
                                 SourceLocation IdLoc,
                                 IdentifierInfo *Id) {
-    VarDecl *Var = getSema().BuildExceptionDeclaration(0, Declarator,
+    VarDecl *Var = getSema().BuildExceptionDeclaration(nullptr, Declarator,
                                                        StartLoc, IdLoc, Id);
     if (Var)
       getSema().CurContext->addDecl(Var);
@@ -1477,8 +1665,10 @@
   }
 
   StmtResult RebuildSEHTryStmt(bool IsCXXTry, SourceLocation TryLoc,
-                               Stmt *TryBlock, Stmt *Handler) {
-    return getSema().ActOnSEHTryBlock(IsCXXTry, TryLoc, TryBlock, Handler);
+                               Stmt *TryBlock, Stmt *Handler, int HandlerIndex,
+                               int HandlerParentIndex) {
+    return getSema().ActOnSEHTryBlock(IsCXXTry, TryLoc, TryBlock, Handler,
+                                      HandlerIndex, HandlerParentIndex);
   }
 
   StmtResult RebuildSEHExceptStmt(SourceLocation Loc, Expr *FilterExpr,
@@ -1546,7 +1736,7 @@
   ExprResult RebuildUnaryOperator(SourceLocation OpLoc,
                                         UnaryOperatorKind Opc,
                                         Expr *SubExpr) {
-    return getSema().BuildUnaryOp(/*Scope=*/0, OpLoc, Opc, SubExpr);
+    return getSema().BuildUnaryOp(/*Scope=*/nullptr, OpLoc, Opc, SubExpr);
   }
 
   /// \brief Build a new builtin offsetof expression.
@@ -1598,7 +1788,7 @@
                                              SourceLocation LBracketLoc,
                                              Expr *RHS,
                                              SourceLocation RBracketLoc) {
-    return getSema().ActOnArraySubscriptExpr(/*Scope=*/0, LHS,
+    return getSema().ActOnArraySubscriptExpr(/*Scope=*/nullptr, LHS,
                                              LBracketLoc, RHS,
                                              RBracketLoc);
   }
@@ -1610,8 +1800,8 @@
   ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc,
                                    MultiExprArg Args,
                                    SourceLocation RParenLoc,
-                                   Expr *ExecConfig = 0) {
-    return getSema().ActOnCallExpr(/*Scope=*/0, Callee, LParenLoc,
+                                   Expr *ExecConfig = nullptr) {
+    return getSema().ActOnCallExpr(/*Scope=*/nullptr, Callee, LParenLoc,
                                    Args, RParenLoc, ExecConfig);
   }
 
@@ -1639,25 +1829,25 @@
              "unnamed member not of record type?");
 
       BaseResult =
-        getSema().PerformObjectMemberConversion(BaseResult.take(),
+        getSema().PerformObjectMemberConversion(BaseResult.get(),
                                                 QualifierLoc.getNestedNameSpecifier(),
                                                 FoundDecl, Member);
       if (BaseResult.isInvalid())
         return ExprError();
-      Base = BaseResult.take();
+      Base = BaseResult.get();
       ExprValueKind VK = isArrow ? VK_LValue : Base->getValueKind();
       MemberExpr *ME =
         new (getSema().Context) MemberExpr(Base, isArrow,
                                            Member, MemberNameInfo,
                                            cast<FieldDecl>(Member)->getType(),
                                            VK, OK_Ordinary);
-      return getSema().Owned(ME);
+      return ME;
     }
 
     CXXScopeSpec SS;
     SS.Adopt(QualifierLoc);
 
-    Base = BaseResult.take();
+    Base = BaseResult.get();
     QualType BaseType = Base->getType();
 
     // FIXME: this involves duplicating earlier analysis in a lot of
@@ -1679,7 +1869,7 @@
   ExprResult RebuildBinaryOperator(SourceLocation OpLoc,
                                          BinaryOperatorKind Opc,
                                          Expr *LHS, Expr *RHS) {
-    return getSema().BuildBinOp(/*Scope=*/0, OpLoc, Opc, LHS, RHS);
+    return getSema().BuildBinOp(/*Scope=*/nullptr, OpLoc, Opc, LHS, RHS);
   }
 
   /// \brief Build a new conditional operator expression.
@@ -1733,9 +1923,9 @@
     return getSema().BuildMemberReferenceExpr(Base, Base->getType(),
                                               OpLoc, /*IsArrow*/ false,
                                               SS, SourceLocation(),
-                                              /*FirstQualifierInScope*/ 0,
+                                              /*FirstQualifierInScope*/ nullptr,
                                               NameInfo,
-                                              /* TemplateArgs */ 0);
+                                              /* TemplateArgs */ nullptr);
   }
 
   /// \brief Build a new initializer list expression.
@@ -1782,7 +1972,7 @@
   /// any semantic analysis. Subclasses may override this routine to provide
   /// different behavior.
   ExprResult RebuildImplicitValueInitExpr(QualType T) {
-    return SemaRef.Owned(new (SemaRef.Context) ImplicitValueInitExpr(T));
+    return new (SemaRef.Context) ImplicitValueInitExpr(T);
   }
 
   /// \brief Build a new \c va_arg expression.
@@ -2047,9 +2237,7 @@
                                 QualType ThisType,
                                 bool isImplicit) {
     getSema().CheckCXXThisCapture(ThisLoc);
-    return getSema().Owned(
-                      new (getSema().Context) CXXThisExpr(ThisLoc, ThisType,
-                                                          isImplicit));
+    return new (getSema().Context) CXXThisExpr(ThisLoc, ThisType, isImplicit);
   }
 
   /// \brief Build a new C++ throw expression.
@@ -2068,8 +2256,7 @@
   /// provide different behavior.
   ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc,
                                             ParmVarDecl *Param) {
-    return getSema().Owned(CXXDefaultArgExpr::Create(getSema().Context, Loc,
-                                                     Param));
+    return CXXDefaultArgExpr::Create(getSema().Context, Loc, Param);
   }
 
   /// \brief Build a new C++11 default-initialization expression.
@@ -2079,8 +2266,7 @@
   /// routine to provide different behavior.
   ExprResult RebuildCXXDefaultInitExpr(SourceLocation Loc,
                                        FieldDecl *Field) {
-    return getSema().Owned(CXXDefaultInitExpr::Create(getSema().Context, Loc,
-                                                      Field));
+    return CXXDefaultInitExpr::Create(getSema().Context, Loc, Field);
   }
 
   /// \brief Build a new C++ zero-initialization expression.
@@ -2133,29 +2319,6 @@
                                     Operand);
   }
 
-  /// \brief Build a new unary type trait expression.
-  ///
-  /// By default, performs semantic analysis to build the new expression.
-  /// Subclasses may override this routine to provide different behavior.
-  ExprResult RebuildUnaryTypeTrait(UnaryTypeTrait Trait,
-                                   SourceLocation StartLoc,
-                                   TypeSourceInfo *T,
-                                   SourceLocation RParenLoc) {
-    return getSema().BuildUnaryTypeTrait(Trait, StartLoc, T, RParenLoc);
-  }
-
-  /// \brief Build a new binary type trait expression.
-  ///
-  /// By default, performs semantic analysis to build the new expression.
-  /// Subclasses may override this routine to provide different behavior.
-  ExprResult RebuildBinaryTypeTrait(BinaryTypeTrait Trait,
-                                    SourceLocation StartLoc,
-                                    TypeSourceInfo *LhsT,
-                                    TypeSourceInfo *RhsT,
-                                    SourceLocation RParenLoc) {
-    return getSema().BuildBinaryTypeTrait(Trait, StartLoc, LhsT, RhsT, RParenLoc);
-  }
-
   /// \brief Build a new type trait expression.
   ///
   /// By default, performs semantic analysis to build the new expression.
@@ -2200,16 +2363,17 @@
                                           SourceLocation TemplateKWLoc,
                                        const DeclarationNameInfo &NameInfo,
                               const TemplateArgumentListInfo *TemplateArgs,
-                                          bool IsAddressOfOperand) {
+                                          bool IsAddressOfOperand,
+                                          TypeSourceInfo **RecoveryTSI) {
     CXXScopeSpec SS;
     SS.Adopt(QualifierLoc);
 
     if (TemplateArgs || TemplateKWLoc.isValid())
-      return getSema().BuildQualifiedTemplateIdExpr(SS, TemplateKWLoc,
-                                                    NameInfo, TemplateArgs);
+      return getSema().BuildQualifiedTemplateIdExpr(SS, TemplateKWLoc, NameInfo,
+                                                    TemplateArgs);
 
-    return getSema().BuildQualifiedDeclarationNameExpr(SS, NameInfo,
-                                                       IsAddressOfOperand);
+    return getSema().BuildQualifiedDeclarationNameExpr(
+        SS, NameInfo, IsAddressOfOperand, RecoveryTSI);
   }
 
   /// \brief Build a new template-id expression.
@@ -2236,6 +2400,7 @@
                                      MultiExprArg Args,
                                      bool HadMultipleCandidates,
                                      bool ListInitialization,
+                                     bool StdInitListInitialization,
                                      bool RequiresZeroInit,
                              CXXConstructExpr::ConstructionKind ConstructKind,
                                      SourceRange ParenRange) {
@@ -2248,6 +2413,7 @@
                                            ConvertedArgs,
                                            HadMultipleCandidates,
                                            ListInitialization,
+                                           StdInitListInitialization,
                                            RequiresZeroInit, ConstructKind,
                                            ParenRange);
   }
@@ -2392,8 +2558,7 @@
   ExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
                                          TypeSourceInfo *EncodeTypeInfo,
                                          SourceLocation RParenLoc) {
-    return SemaRef.Owned(SemaRef.BuildObjCEncodeExpression(AtLoc, EncodeTypeInfo,
-                                                           RParenLoc));
+    return SemaRef.BuildObjCEncodeExpression(AtLoc, EncodeTypeInfo, RParenLoc);
   }
 
   /// \brief Build a new Objective-C class message.
@@ -2435,25 +2600,13 @@
                                           bool IsArrow, bool IsFreeIvar) {
     // FIXME: We lose track of the IsFreeIvar bit.
     CXXScopeSpec SS;
-    ExprResult Base = getSema().Owned(BaseArg);
-    LookupResult R(getSema(), Ivar->getDeclName(), IvarLoc,
-                   Sema::LookupMemberName);
-    ExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
-                                                         /*FIME:*/IvarLoc,
-                                                         SS, 0,
-                                                         false);
-    if (Result.isInvalid() || Base.isInvalid())
-      return ExprError();
-
-    if (Result.get())
-      return Result;
-
-    return getSema().BuildMemberReferenceExpr(Base.get(), Base.get()->getType(),
+    DeclarationNameInfo NameInfo(Ivar->getDeclName(), IvarLoc);
+    return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
                                               /*FIXME:*/IvarLoc, IsArrow,
                                               SS, SourceLocation(),
-                                              /*FirstQualifierInScope=*/0,
-                                              R,
-                                              /*TemplateArgs=*/0);
+                                              /*FirstQualifierInScope=*/nullptr,
+                                              NameInfo,
+                                              /*TemplateArgs=*/nullptr);
   }
 
   /// \brief Build a new Objective-C property reference expression.
@@ -2464,25 +2617,14 @@
                                         ObjCPropertyDecl *Property,
                                         SourceLocation PropertyLoc) {
     CXXScopeSpec SS;
-    ExprResult Base = getSema().Owned(BaseArg);
-    LookupResult R(getSema(), Property->getDeclName(), PropertyLoc,
-                   Sema::LookupMemberName);
-    bool IsArrow = false;
-    ExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
-                                                         /*FIME:*/PropertyLoc,
-                                                         SS, 0, false);
-    if (Result.isInvalid() || Base.isInvalid())
-      return ExprError();
-
-    if (Result.get())
-      return Result;
-
-    return getSema().BuildMemberReferenceExpr(Base.get(), Base.get()->getType(),
-                                              /*FIXME:*/PropertyLoc, IsArrow,
+    DeclarationNameInfo NameInfo(Property->getDeclName(), PropertyLoc);
+    return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
+                                              /*FIXME:*/PropertyLoc,
+                                              /*IsArrow=*/false,
                                               SS, SourceLocation(),
-                                              /*FirstQualifierInScope=*/0,
-                                              R,
-                                              /*TemplateArgs=*/0);
+                                              /*FirstQualifierInScope=*/nullptr,
+                                              NameInfo,
+                                              /*TemplateArgs=*/nullptr);
   }
 
   /// \brief Build a new Objective-C property reference expression.
@@ -2506,27 +2648,15 @@
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
   ExprResult RebuildObjCIsaExpr(Expr *BaseArg, SourceLocation IsaLoc,
-                                SourceLocation OpLoc,
-                                      bool IsArrow) {
+                                SourceLocation OpLoc, bool IsArrow) {
     CXXScopeSpec SS;
-    ExprResult Base = getSema().Owned(BaseArg);
-    LookupResult R(getSema(), &getSema().Context.Idents.get("isa"), IsaLoc,
-                   Sema::LookupMemberName);
-    ExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
-                                                         OpLoc,
-                                                         SS, 0, false);
-    if (Result.isInvalid() || Base.isInvalid())
-      return ExprError();
-
-    if (Result.get())
-      return Result;
-
-    return getSema().BuildMemberReferenceExpr(Base.get(), Base.get()->getType(),
+    DeclarationNameInfo NameInfo(&getSema().Context.Idents.get("isa"), IsaLoc);
+    return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
                                               OpLoc, IsArrow,
                                               SS, SourceLocation(),
-                                              /*FirstQualifierInScope=*/0,
-                                              R,
-                                              /*TemplateArgs=*/0);
+                                              /*FirstQualifierInScope=*/nullptr,
+                                              NameInfo,
+                                              /*TemplateArgs=*/nullptr);
   }
 
   /// \brief Build a new shuffle vector expression.
@@ -2550,17 +2680,15 @@
                                                   VK_RValue, BuiltinLoc);
     QualType CalleePtrTy = SemaRef.Context.getPointerType(Builtin->getType());
     Callee = SemaRef.ImpCastExprToType(Callee, CalleePtrTy,
-                                       CK_BuiltinFnToFnPtr).take();
+                                       CK_BuiltinFnToFnPtr).get();
 
     // Build the CallExpr
-    ExprResult TheCall = SemaRef.Owned(
-      new (SemaRef.Context) CallExpr(SemaRef.Context, Callee, SubExprs,
-                                     Builtin->getCallResultType(),
-                            Expr::getValueKindForType(Builtin->getResultType()),
-                                     RParenLoc));
+    ExprResult TheCall = new (SemaRef.Context) CallExpr(
+        SemaRef.Context, Callee, SubExprs, Builtin->getCallResultType(),
+        Expr::getValueKindForType(Builtin->getReturnType()), RParenLoc);
 
     // Type-check the __builtin_shufflevector expression.
-    return SemaRef.SemaBuiltinShuffleVector(cast<CallExpr>(TheCall.take()));
+    return SemaRef.SemaBuiltinShuffleVector(cast<CallExpr>(TheCall.get()));
   }
 
   /// \brief Build a new convert vector expression.
@@ -2655,12 +2783,16 @@
                                              QualType ObjectType,
                                              NamedDecl *FirstQualifierInScope,
                                              CXXScopeSpec &SS);
+
+  TypeSourceInfo *TransformTSIInObjectScope(TypeLoc TL, QualType ObjectType,
+                                            NamedDecl *FirstQualifierInScope,
+                                            CXXScopeSpec &SS);
 };
 
 template<typename Derived>
 StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) {
   if (!S)
-    return SemaRef.Owned(S);
+    return S;
 
   switch (S->getStmtClass()) {
   case Stmt::NoStmtClass: break;
@@ -2686,7 +2818,7 @@
     }
   }
 
-  return SemaRef.Owned(S);
+  return S;
 }
 
 template<typename Derived>
@@ -2710,7 +2842,7 @@
 template<typename Derived>
 ExprResult TreeTransform<Derived>::TransformExpr(Expr *E) {
   if (!E)
-    return SemaRef.Owned(E);
+    return E;
 
   switch (E->getStmtClass()) {
     case Stmt::NoStmtClass: break;
@@ -2721,16 +2853,16 @@
 #include "clang/AST/StmtNodes.inc"
   }
 
-  return SemaRef.Owned(E);
+  return E;
 }
 
 template<typename Derived>
 ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init,
-                                                        bool CXXDirectInit) {
+                                                        bool NotCopyInit) {
   // Initializers are instantiated like expressions, except that various outer
   // layers are stripped.
   if (!Init)
-    return SemaRef.Owned(Init);
+    return Init;
 
   if (ExprWithCleanups *ExprTemp = dyn_cast<ExprWithCleanups>(Init))
     Init = ExprTemp->getSubExpr();
@@ -2746,13 +2878,13 @@
 
   if (CXXStdInitializerListExpr *ILE =
           dyn_cast<CXXStdInitializerListExpr>(Init))
-    return TransformInitializer(ILE->getSubExpr(), CXXDirectInit);
+    return TransformInitializer(ILE->getSubExpr(), NotCopyInit);
 
-  // If this is not a direct-initializer, we only need to reconstruct
+  // If this is copy-initialization, we only need to reconstruct
   // InitListExprs. Other forms of copy-initialization will be a no-op if
   // the initializer is already the right type.
   CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init);
-  if (!CXXDirectInit && !(Construct && Construct->isListInitialization()))
+  if (!NotCopyInit && !(Construct && Construct->isListInitialization()))
     return getDerived().TransformExpr(Init);
 
   // Revert value-initialization back to empty parens.
@@ -2772,10 +2904,15 @@
   if (!Construct || isa<CXXTemporaryObjectExpr>(Construct))
     return getDerived().TransformExpr(Init);
 
+  // If the initialization implicitly converted an initializer list to a
+  // std::initializer_list object, unwrap the std::initializer_list too.
+  if (Construct && Construct->isStdInitListInitialization())
+    return TransformInitializer(Construct->getArg(0), NotCopyInit);
+
   SmallVector<Expr*, 8> NewArgs;
   bool ArgChanged = false;
   if (getDerived().TransformExprs(Construct->getArgs(), Construct->getNumArgs(),
-                     /*IsCall*/true, NewArgs, &ArgChanged))
+                                  /*IsCall*/true, NewArgs, &ArgChanged))
     return ExprError();
 
   // If this was list initialization, revert to list form.
@@ -2786,6 +2923,13 @@
 
   // Build a ParenListExpr to represent anything else.
   SourceRange Parens = Construct->getParenOrBraceRange();
+  if (Parens.isInvalid()) {
+    // This was a variable declaration's initialization for which no initializer
+    // was specified.
+    assert(NewArgs.empty() &&
+           "no parens or braces but have direct init with arguments?");
+    return ExprEmpty();
+  }
   return getDerived().RebuildParenListExpr(Parens.getBegin(), NewArgs,
                                            Parens.getEnd());
 }
@@ -2858,9 +3002,11 @@
         if (Out.isInvalid())
           return true;
 
+        // FIXME: Can this happen? We should not try to expand the pack
+        // in this case.
         if (Out.get()->containsUnexpandedParameterPack()) {
-          Out = RebuildPackExpansion(Out.get(), Expansion->getEllipsisLoc(),
-                                     OrigNumExpansions);
+          Out = getDerived().RebuildPackExpansion(
+              Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
           if (Out.isInvalid())
             return true;
         }
@@ -2868,6 +3014,23 @@
         Outputs.push_back(Out.get());
       }
 
+      // If we're supposed to retain a pack expansion, do so by temporarily
+      // forgetting the partially-substituted parameter pack.
+      if (RetainExpansion) {
+        ForgetPartiallySubstitutedPackRAII Forget(getDerived());
+
+        ExprResult Out = getDerived().TransformExpr(Pattern);
+        if (Out.isInvalid())
+          return true;
+
+        Out = getDerived().RebuildPackExpansion(
+            Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
+        if (Out.isInvalid())
+          return true;
+
+        Outputs.push_back(Out.get());
+      }
+
       continue;
     }
 
@@ -2904,7 +3067,7 @@
 
     switch (QNNS->getKind()) {
     case NestedNameSpecifier::Identifier:
-      if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/0,
+      if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/nullptr,
                                               *QNNS->getAsIdentifier(),
                                               Q.getLocalBeginLoc(),
                                               Q.getLocalEndLoc(),
@@ -2972,7 +3135,7 @@
     }
 
     // The qualifier-in-scope and object type only apply to the leftmost entity.
-    FirstQualifierInScope = 0;
+    FirstQualifierInScope = nullptr;
     ObjectType = QualType();
   }
 
@@ -3021,7 +3184,7 @@
       NewCanTy = SemaRef.Context.getCanonicalType(NewTInfo->getType());
     }
     else {
-      NewTInfo = 0;
+      NewTInfo = nullptr;
       TemporaryBase Rebase(*this, NameInfo.getLoc(), Name);
       QualType NewT = getDerived().TransformType(Name.getCXXNameType());
       if (NewT.isNull())
@@ -3072,7 +3235,7 @@
     if (SS.getScopeRep()) {
       // These apply to the scope specifier, not the template.
       ObjectType = QualType();
-      FirstQualifierInScope = 0;
+      FirstQualifierInScope = nullptr;
     }
 
     if (!getDerived().AlwaysRebuild() &&
@@ -3191,7 +3354,7 @@
 
   case TemplateArgument::Type: {
     TypeSourceInfo *DI = Input.getTypeSourceInfo();
-    if (DI == NULL)
+    if (!DI)
       DI = InventTypeSourceInfo(Input.getArgument().getAsType());
 
     DI = getDerived().TransformType(DI);
@@ -3236,7 +3399,7 @@
     ExprResult E = getDerived().TransformExpr(InputExpr);
     E = SemaRef.ActOnConstantExpression(E);
     if (E.isInvalid()) return true;
-    Output = TemplateArgumentLoc(TemplateArgument(E.take()), E.take());
+    Output = TemplateArgumentLoc(TemplateArgument(E.get()), E.get());
     return false;
   }
   }
@@ -3461,7 +3624,7 @@
 
   QualType Result = getDerived().TransformType(TLB, TL);
   if (Result.isNull())
-    return 0;
+    return nullptr;
 
   return TLB.getTypeSourceInfo(SemaRef.Context, Result);
 }
@@ -3562,52 +3725,14 @@
                                                    QualType ObjectType,
                                                    NamedDecl *UnqualLookup,
                                                    CXXScopeSpec &SS) {
-  QualType T = TL.getType();
-  if (getDerived().AlreadyTransformed(T))
+  if (getDerived().AlreadyTransformed(TL.getType()))
     return TL;
 
-  TypeLocBuilder TLB;
-  QualType Result;
-
-  if (isa<TemplateSpecializationType>(T)) {
-    TemplateSpecializationTypeLoc SpecTL =
-        TL.castAs<TemplateSpecializationTypeLoc>();
-
-    TemplateName Template =
-      getDerived().TransformTemplateName(SS,
-                                         SpecTL.getTypePtr()->getTemplateName(),
-                                         SpecTL.getTemplateNameLoc(),
-                                         ObjectType, UnqualLookup);
-    if (Template.isNull())
-      return TypeLoc();
-
-    Result = getDerived().TransformTemplateSpecializationType(TLB, SpecTL,
-                                                              Template);
-  } else if (isa<DependentTemplateSpecializationType>(T)) {
-    DependentTemplateSpecializationTypeLoc SpecTL =
-        TL.castAs<DependentTemplateSpecializationTypeLoc>();
-
-    TemplateName Template
-      = getDerived().RebuildTemplateName(SS,
-                                         *SpecTL.getTypePtr()->getIdentifier(),
-                                         SpecTL.getTemplateNameLoc(),
-                                         ObjectType, UnqualLookup);
-    if (Template.isNull())
-      return TypeLoc();
-
-    Result = getDerived().TransformDependentTemplateSpecializationType(TLB,
-                                                                       SpecTL,
-                                                                     Template,
-                                                                       SS);
-  } else {
-    // Nothing special needs to be done for these.
-    Result = getDerived().TransformType(TLB, TL);
-  }
-
-  if (Result.isNull())
-    return TypeLoc();
-
-  return TLB.getTypeSourceInfo(SemaRef.Context, Result)->getTypeLoc();
+  TypeSourceInfo *TSI =
+      TransformTSIInObjectScope(TL, ObjectType, UnqualLookup, SS);
+  if (TSI)
+    return TSI->getTypeLoc();
+  return TypeLoc();
 }
 
 template<typename Derived>
@@ -3616,16 +3741,23 @@
                                                    QualType ObjectType,
                                                    NamedDecl *UnqualLookup,
                                                    CXXScopeSpec &SS) {
-  // FIXME: Painfully copy-paste from the above!
-
-  QualType T = TSInfo->getType();
-  if (getDerived().AlreadyTransformed(T))
+  if (getDerived().AlreadyTransformed(TSInfo->getType()))
     return TSInfo;
 
+  return TransformTSIInObjectScope(TSInfo->getTypeLoc(), ObjectType,
+                                   UnqualLookup, SS);
+}
+
+template <typename Derived>
+TypeSourceInfo *TreeTransform<Derived>::TransformTSIInObjectScope(
+    TypeLoc TL, QualType ObjectType, NamedDecl *UnqualLookup,
+    CXXScopeSpec &SS) {
+  QualType T = TL.getType();
+  assert(!getDerived().AlreadyTransformed(T));
+
   TypeLocBuilder TLB;
   QualType Result;
 
-  TypeLoc TL = TSInfo->getTypeLoc();
   if (isa<TemplateSpecializationType>(T)) {
     TemplateSpecializationTypeLoc SpecTL =
         TL.castAs<TemplateSpecializationTypeLoc>();
@@ -3636,7 +3768,7 @@
                                          SpecTL.getTemplateNameLoc(),
                                          ObjectType, UnqualLookup);
     if (Template.isNull())
-      return 0;
+      return nullptr;
 
     Result = getDerived().TransformTemplateSpecializationType(TLB, SpecTL,
                                                               Template);
@@ -3650,7 +3782,7 @@
                                          SpecTL.getTemplateNameLoc(),
                                          ObjectType, UnqualLookup);
     if (Template.isNull())
-      return 0;
+      return nullptr;
 
     Result = getDerived().TransformDependentTemplateSpecializationType(TLB,
                                                                        SpecTL,
@@ -3662,7 +3794,7 @@
   }
 
   if (Result.isNull())
-    return 0;
+    return nullptr;
 
   return TLB.getTypeSourceInfo(SemaRef.Context, Result);
 }
@@ -3691,6 +3823,13 @@
   return TransformTypeSpecType(TLB, T);
 }
 
+template <typename Derived>
+QualType TreeTransform<Derived>::TransformAdjustedType(TypeLocBuilder &TLB,
+                                                       AdjustedTypeLoc TL) {
+  // Adjustments applied during transformation are handled elsewhere.
+  return getDerived().TransformType(TLB, TL.getOriginalLoc());
+}
+
 template<typename Derived>
 QualType TreeTransform<Derived>::TransformDecayedType(TypeLocBuilder &TLB,
                                                       DecayedTypeLoc TL) {
@@ -3831,7 +3970,7 @@
     return QualType();
 
   TypeSourceInfo* OldClsTInfo = TL.getClassTInfo();
-  TypeSourceInfo* NewClsTInfo = 0;
+  TypeSourceInfo *NewClsTInfo = nullptr;
   if (OldClsTInfo) {
     NewClsTInfo = getDerived().TransformType(OldClsTInfo);
     if (!NewClsTInfo)
@@ -3859,6 +3998,14 @@
       return QualType();
   }
 
+  // If we had to adjust the pointee type when building a member pointer, make
+  // sure to push TypeLoc info for it.
+  const MemberPointerType *MPT = Result->getAs<MemberPointerType>();
+  if (MPT && PointeeType != MPT->getPointeeType()) {
+    assert(isa<AdjustedType>(MPT->getPointeeType()));
+    TLB.push<AdjustedTypeLoc>(MPT->getPointeeType());
+  }
+
   MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(Result);
   NewTL.setSigilLoc(TL.getSigilLoc());
   NewTL.setClassTInfo(NewClsTInfo);
@@ -3899,8 +4046,8 @@
   if (Size) {
     EnterExpressionEvaluationContext Unevaluated(SemaRef,
                                                  Sema::ConstantEvaluated);
-    Size = getDerived().TransformExpr(Size).template takeAs<Expr>();
-    Size = SemaRef.ActOnConstantExpression(Size).take();
+    Size = getDerived().TransformExpr(Size).template getAs<Expr>();
+    Size = SemaRef.ActOnConstantExpression(Size).get();
   }
   NewTL.setSizeExpr(Size);
 
@@ -3930,7 +4077,7 @@
   IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(Result);
   NewTL.setLBracketLoc(TL.getLBracketLoc());
   NewTL.setRBracketLoc(TL.getRBracketLoc());
-  NewTL.setSizeExpr(0);
+  NewTL.setSizeExpr(nullptr);
 
   return Result;
 }
@@ -3949,7 +4096,7 @@
   if (SizeResult.isInvalid())
     return QualType();
 
-  Expr *Size = SizeResult.take();
+  Expr *Size = SizeResult.get();
 
   QualType Result = TL.getType();
   if (getDerived().AlwaysRebuild() ||
@@ -3964,7 +4111,9 @@
       return QualType();
   }
 
-  VariableArrayTypeLoc NewTL = TLB.push<VariableArrayTypeLoc>(Result);
+  // We might have constant size array now, but fortunately it has the same
+  // location layout.
+  ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
   NewTL.setLBracketLoc(TL.getLBracketLoc());
   NewTL.setRBracketLoc(TL.getRBracketLoc());
   NewTL.setSizeExpr(Size);
@@ -4045,7 +4194,7 @@
       ElementType != T->getElementType() ||
       Size.get() != T->getSizeExpr()) {
     Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
-                                                             Size.take(),
+                                                             Size.get(),
                                                          T->getAttributeLoc());
     if (Result.isNull())
       return QualType();
@@ -4116,7 +4265,7 @@
     ParmVarDecl *OldParm, int indexAdjustment, Optional<unsigned> NumExpansions,
     bool ExpectParameterPack) {
   TypeSourceInfo *OldDI = OldParm->getTypeSourceInfo();
-  TypeSourceInfo *NewDI = 0;
+  TypeSourceInfo *NewDI = nullptr;
 
   if (NumExpansions && isa<PackExpansionType>(OldDI->getType())) {
     // If we're substituting into a pack expansion type and we know the
@@ -4131,14 +4280,14 @@
     QualType Result = getDerived().TransformType(TLB,
                                                OldExpansionTL.getPatternLoc());
     if (Result.isNull())
-      return 0;
+      return nullptr;
 
     Result = RebuildPackExpansionType(Result,
                                 OldExpansionTL.getPatternLoc().getSourceRange(),
                                       OldExpansionTL.getEllipsisLoc(),
                                       NumExpansions);
     if (Result.isNull())
-      return 0;
+      return nullptr;
 
     PackExpansionTypeLoc NewExpansionTL
       = TLB.push<PackExpansionTypeLoc>(Result);
@@ -4147,7 +4296,7 @@
   } else
     NewDI = getDerived().TransformType(OldDI);
   if (!NewDI)
-    return 0;
+    return nullptr;
 
   if (NewDI == OldDI && indexAdjustment == 0)
     return OldParm;
@@ -4160,7 +4309,7 @@
                                              NewDI->getType(),
                                              NewDI,
                                              OldParm->getStorageClass(),
-                                             /* DefArg */ NULL);
+                                             /* DefArg */ nullptr);
   newParm->setScopeInfo(OldParm->getFunctionScopeDepth(),
                         OldParm->getFunctionScopeIndex() + indexAdjustment);
   return newParm;
@@ -4180,7 +4329,7 @@
       assert(OldParm->getFunctionScopeIndex() == i);
 
       Optional<unsigned> NumExpansions;
-      ParmVarDecl *NewParm = 0;
+      ParmVarDecl *NewParm = nullptr;
       if (OldParm->isParameterPack()) {
         // We have a function parameter pack that may need to be expanded.
         SmallVector<UnexpandedParameterPack, 2> Unexpanded;
@@ -4309,7 +4458,7 @@
 
           OutParamTypes.push_back(NewType);
           if (PVars)
-            PVars->push_back(0);
+            PVars->push_back(nullptr);
         }
 
         // We're done with the pack expansion.
@@ -4326,7 +4475,7 @@
 
         OutParamTypes.push_back(NewType);
         if (PVars)
-          PVars->push_back(0);
+          PVars->push_back(nullptr);
       }
 
       // We'll substitute the parameter now without expanding the pack
@@ -4348,7 +4497,7 @@
 
     OutParamTypes.push_back(NewType);
     if (PVars)
-      PVars->push_back(0);
+      PVars->push_back(nullptr);
   }
 
 #ifndef NDEBUG
@@ -4366,7 +4515,7 @@
 QualType
 TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
                                                    FunctionProtoTypeLoc TL) {
-  return getDerived().TransformFunctionProtoType(TLB, TL, 0, 0);
+  return getDerived().TransformFunctionProtoType(TLB, TL, nullptr, 0);
 }
 
 template<typename Derived>
@@ -4389,11 +4538,9 @@
   QualType ResultType;
 
   if (T->hasTrailingReturn()) {
-    if (getDerived().TransformFunctionTypeParams(TL.getBeginLoc(),
-                                                 TL.getParmArray(),
-                                                 TL.getNumArgs(),
-                                             TL.getTypePtr()->arg_type_begin(),
-                                                 ParamTypes, &ParamDecls))
+    if (getDerived().TransformFunctionTypeParams(
+            TL.getBeginLoc(), TL.getParmArray(), TL.getNumParams(),
+            TL.getTypePtr()->param_type_begin(), ParamTypes, &ParamDecls))
       return QualType();
 
     {
@@ -4405,31 +4552,29 @@
       //   declarator.
       Sema::CXXThisScopeRAII ThisScope(SemaRef, ThisContext, ThisTypeQuals);
 
-      ResultType = getDerived().TransformType(TLB, TL.getResultLoc());
+      ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
       if (ResultType.isNull())
         return QualType();
     }
   }
   else {
-    ResultType = getDerived().TransformType(TLB, TL.getResultLoc());
+    ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
     if (ResultType.isNull())
       return QualType();
 
-    if (getDerived().TransformFunctionTypeParams(TL.getBeginLoc(),
-                                                 TL.getParmArray(),
-                                                 TL.getNumArgs(),
-                                             TL.getTypePtr()->arg_type_begin(),
-                                                 ParamTypes, &ParamDecls))
+    if (getDerived().TransformFunctionTypeParams(
+            TL.getBeginLoc(), TL.getParmArray(), TL.getNumParams(),
+            TL.getTypePtr()->param_type_begin(), ParamTypes, &ParamDecls))
       return QualType();
   }
 
   // FIXME: Need to transform the exception-specification too.
 
   QualType Result = TL.getType();
-  if (getDerived().AlwaysRebuild() ||
-      ResultType != T->getResultType() ||
-      T->getNumArgs() != ParamTypes.size() ||
-      !std::equal(T->arg_type_begin(), T->arg_type_end(), ParamTypes.begin())) {
+  if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType() ||
+      T->getNumParams() != ParamTypes.size() ||
+      !std::equal(T->param_type_begin(), T->param_type_end(),
+                  ParamTypes.begin())) {
     Result = getDerived().RebuildFunctionProtoType(ResultType, ParamTypes,
                                                    T->getExtProtoInfo());
     if (Result.isNull())
@@ -4441,8 +4586,8 @@
   NewTL.setLParenLoc(TL.getLParenLoc());
   NewTL.setRParenLoc(TL.getRParenLoc());
   NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
-  for (unsigned i = 0, e = NewTL.getNumArgs(); i != e; ++i)
-    NewTL.setArg(i, ParamDecls[i]);
+  for (unsigned i = 0, e = NewTL.getNumParams(); i != e; ++i)
+    NewTL.setParam(i, ParamDecls[i]);
 
   return Result;
 }
@@ -4452,13 +4597,12 @@
                                                  TypeLocBuilder &TLB,
                                                  FunctionNoProtoTypeLoc TL) {
   const FunctionNoProtoType *T = TL.getTypePtr();
-  QualType ResultType = getDerived().TransformType(TLB, TL.getResultLoc());
+  QualType ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
   if (ResultType.isNull())
     return QualType();
 
   QualType Result = TL.getType();
-  if (getDerived().AlwaysRebuild() ||
-      ResultType != T->getResultType())
+  if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType())
     Result = getDerived().RebuildFunctionNoProtoType(ResultType);
 
   FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(Result);
@@ -4539,7 +4683,7 @@
     if (Result.isNull())
       return QualType();
   }
-  else E.take();
+  else E.get();
 
   TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(Result);
   NewTL.setTypeofLoc(TL.getTypeofLoc());
@@ -4579,14 +4723,14 @@
   const DecltypeType *T = TL.getTypePtr();
 
   // decltype expressions are not potentially evaluated contexts
-  EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated, 0,
-                                               /*IsDecltype=*/ true);
+  EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated,
+                                               nullptr, /*IsDecltype=*/ true);
 
   ExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
   if (E.isInvalid())
     return QualType();
 
-  E = getSema().ActOnDecltypeExpression(E.take());
+  E = getSema().ActOnDecltypeExpression(E.get());
   if (E.isInvalid())
     return QualType();
 
@@ -4597,7 +4741,7 @@
     if (Result.isNull())
       return QualType();
   }
-  else E.take();
+  else E.get();
 
   DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(Result);
   NewTL.setNameLoc(TL.getNameLoc());
@@ -5264,7 +5408,7 @@
 template<typename Derived>
 StmtResult
 TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
-  return SemaRef.Owned(S);
+  return S;
 }
 
 template<typename Derived>
@@ -5282,13 +5426,12 @@
   bool SubStmtInvalid = false;
   bool SubStmtChanged = false;
   SmallVector<Stmt*, 8> Statements;
-  for (CompoundStmt::body_iterator B = S->body_begin(), BEnd = S->body_end();
-       B != BEnd; ++B) {
-    StmtResult Result = getDerived().TransformStmt(*B);
+  for (auto *B : S->body()) {
+    StmtResult Result = getDerived().TransformStmt(B);
     if (Result.isInvalid()) {
       // Immediately fail if this was a DeclStmt, since it's very
       // likely that this will cause problems for future statements.
-      if (isa<DeclStmt>(*B))
+      if (isa<DeclStmt>(B))
         return StmtError();
 
       // Otherwise, just keep processing substatements and fail later.
@@ -5296,8 +5439,8 @@
       continue;
     }
 
-    SubStmtChanged = SubStmtChanged || Result.get() != *B;
-    Statements.push_back(Result.takeAs<Stmt>());
+    SubStmtChanged = SubStmtChanged || Result.get() != B;
+    Statements.push_back(Result.getAs<Stmt>());
   }
 
   if (SubStmtInvalid)
@@ -5305,7 +5448,7 @@
 
   if (!getDerived().AlwaysRebuild() &&
       !SubStmtChanged)
-    return SemaRef.Owned(S);
+    return S;
 
   return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
                                           Statements,
@@ -5407,7 +5550,7 @@
 TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
   // Transform the condition
   ExprResult Cond;
-  VarDecl *ConditionVar = 0;
+  VarDecl *ConditionVar = nullptr;
   if (S->getConditionVariable()) {
     ConditionVar
       = cast_or_null<VarDecl>(
@@ -5424,7 +5567,7 @@
 
     // Convert the condition to a boolean value.
     if (S->getCond()) {
-      ExprResult CondE = getSema().ActOnBooleanCondition(0, S->getIfLoc(),
+      ExprResult CondE = getSema().ActOnBooleanCondition(nullptr, S->getIfLoc(),
                                                          Cond.get());
       if (CondE.isInvalid())
         return StmtError();
@@ -5433,7 +5576,7 @@
     }
   }
 
-  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.take()));
+  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.get()));
   if (!S->getConditionVariable() && S->getCond() && !FullCond.get())
     return StmtError();
 
@@ -5452,7 +5595,7 @@
       ConditionVar == S->getConditionVariable() &&
       Then.get() == S->getThen() &&
       Else.get() == S->getElse())
-    return SemaRef.Owned(S);
+    return S;
 
   return getDerived().RebuildIfStmt(S->getIfLoc(), FullCond, ConditionVar,
                                     Then.get(),
@@ -5464,7 +5607,7 @@
 TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
   // Transform the condition.
   ExprResult Cond;
-  VarDecl *ConditionVar = 0;
+  VarDecl *ConditionVar = nullptr;
   if (S->getConditionVariable()) {
     ConditionVar
       = cast_or_null<VarDecl>(
@@ -5502,7 +5645,7 @@
 TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
   // Transform the condition
   ExprResult Cond;
-  VarDecl *ConditionVar = 0;
+  VarDecl *ConditionVar = nullptr;
   if (S->getConditionVariable()) {
     ConditionVar
       = cast_or_null<VarDecl>(
@@ -5519,7 +5662,8 @@
 
     if (S->getCond()) {
       // Convert the condition to a boolean value.
-      ExprResult CondE = getSema().ActOnBooleanCondition(0, S->getWhileLoc(),
+      ExprResult CondE = getSema().ActOnBooleanCondition(nullptr,
+                                                         S->getWhileLoc(),
                                                          Cond.get());
       if (CondE.isInvalid())
         return StmtError();
@@ -5527,7 +5671,7 @@
     }
   }
 
-  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.take()));
+  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.get()));
   if (!S->getConditionVariable() && S->getCond() && !FullCond.get())
     return StmtError();
 
@@ -5562,7 +5706,7 @@
   if (!getDerived().AlwaysRebuild() &&
       Cond.get() == S->getCond() &&
       Body.get() == S->getBody())
-    return SemaRef.Owned(S);
+    return S;
 
   return getDerived().RebuildDoStmt(S->getDoLoc(), Body.get(), S->getWhileLoc(),
                                     /*FIXME:*/S->getWhileLoc(), Cond.get(),
@@ -5579,7 +5723,7 @@
 
   // Transform the condition
   ExprResult Cond;
-  VarDecl *ConditionVar = 0;
+  VarDecl *ConditionVar = nullptr;
   if (S->getConditionVariable()) {
     ConditionVar
       = cast_or_null<VarDecl>(
@@ -5596,7 +5740,8 @@
 
     if (S->getCond()) {
       // Convert the condition to a boolean value.
-      ExprResult CondE = getSema().ActOnBooleanCondition(0, S->getForLoc(),
+      ExprResult CondE = getSema().ActOnBooleanCondition(nullptr,
+                                                         S->getForLoc(),
                                                          Cond.get());
       if (CondE.isInvalid())
         return StmtError();
@@ -5605,7 +5750,7 @@
     }
   }
 
-  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.take()));
+  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.get()));
   if (!S->getConditionVariable() && S->getCond() && !FullCond.get())
     return StmtError();
 
@@ -5628,7 +5773,7 @@
       FullCond.get() == S->getCond() &&
       Inc.get() == S->getInc() &&
       Body.get() == S->getBody())
-    return SemaRef.Owned(S);
+    return S;
 
   return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
                                      Init.get(), FullCond, ConditionVar,
@@ -5654,11 +5799,11 @@
   ExprResult Target = getDerived().TransformExpr(S->getTarget());
   if (Target.isInvalid())
     return StmtError();
-  Target = SemaRef.MaybeCreateExprWithCleanups(Target.take());
+  Target = SemaRef.MaybeCreateExprWithCleanups(Target.get());
 
   if (!getDerived().AlwaysRebuild() &&
       Target.get() == S->getTarget())
-    return SemaRef.Owned(S);
+    return S;
 
   return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
                                               Target.get());
@@ -5667,13 +5812,13 @@
 template<typename Derived>
 StmtResult
 TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
-  return SemaRef.Owned(S);
+  return S;
 }
 
 template<typename Derived>
 StmtResult
 TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
-  return SemaRef.Owned(S);
+  return S;
 }
 
 template<typename Derived>
@@ -5693,21 +5838,19 @@
 TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
   bool DeclChanged = false;
   SmallVector<Decl *, 4> Decls;
-  for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
-       D != DEnd; ++D) {
-    Decl *Transformed = getDerived().TransformDefinition((*D)->getLocation(),
-                                                         *D);
+  for (auto *D : S->decls()) {
+    Decl *Transformed = getDerived().TransformDefinition(D->getLocation(), D);
     if (!Transformed)
       return StmtError();
 
-    if (Transformed != *D)
+    if (Transformed != D)
       DeclChanged = true;
 
     Decls.push_back(Transformed);
   }
 
   if (!getDerived().AlwaysRebuild() && !DeclChanged)
-    return SemaRef.Owned(S);
+    return S;
 
   return getDerived().RebuildDeclStmt(Decls, S->getStartLoc(), S->getEndLoc());
 }
@@ -5762,14 +5905,14 @@
   }
 
   if (!getDerived().AlwaysRebuild() && !ExprsChanged)
-    return SemaRef.Owned(S);
+    return S;
 
   // Go through the clobbers.
   for (unsigned I = 0, E = S->getNumClobbers(); I != E; ++I)
     Clobbers.push_back(S->getClobberStringLiteral(I));
 
   // No need to transform the asm string literal.
-  AsmString = SemaRef.Owned(S->getAsmString());
+  AsmString = S->getAsmString();
   return getDerived().RebuildGCCAsmStmt(S->getAsmLoc(), S->isSimple(),
                                         S->isVolatile(), S->getNumOutputs(),
                                         S->getNumInputs(), Names.data(),
@@ -5794,7 +5937,7 @@
       HadError = true;
     } else {
       HadChange |= (Result.get() != SrcExprs[i]);
-      TransformedExprs.push_back(Result.take());
+      TransformedExprs.push_back(Result.get());
     }
   }
 
@@ -5826,7 +5969,7 @@
       return StmtError();
     if (Catch.get() != S->getCatchStmt(I))
       AnyCatchChanged = true;
-    CatchStmts.push_back(Catch.release());
+    CatchStmts.push_back(Catch.get());
   }
 
   // Transform the @finally statement (if present).
@@ -5842,7 +5985,7 @@
       TryBody.get() == S->getTryBody() &&
       !AnyCatchChanged &&
       Finally.get() == S->getFinallyStmt())
-    return SemaRef.Owned(S);
+    return S;
 
   // Build a new statement.
   return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), TryBody.get(),
@@ -5853,9 +5996,9 @@
 StmtResult
 TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
   // Transform the @catch parameter, if there is one.
-  VarDecl *Var = 0;
+  VarDecl *Var = nullptr;
   if (VarDecl *FromVar = S->getCatchParamDecl()) {
-    TypeSourceInfo *TSInfo = 0;
+    TypeSourceInfo *TSInfo = nullptr;
     if (FromVar->getTypeSourceInfo()) {
       TSInfo = getDerived().TransformType(FromVar->getTypeSourceInfo());
       if (!TSInfo)
@@ -5896,7 +6039,7 @@
   // If nothing changed, just retain this statement.
   if (!getDerived().AlwaysRebuild() &&
       Body.get() == S->getFinallyBody())
-    return SemaRef.Owned(S);
+    return S;
 
   // Build a new statement.
   return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(),
@@ -5915,7 +6058,7 @@
 
   if (!getDerived().AlwaysRebuild() &&
       Operand.get() == S->getThrowExpr())
-    return getSema().Owned(S);
+    return S;
 
   return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), Operand.get());
 }
@@ -5943,7 +6086,7 @@
   if (!getDerived().AlwaysRebuild() &&
       Object.get() == S->getSynchExpr() &&
       Body.get() == S->getSynchBody())
-    return SemaRef.Owned(S);
+    return S;
 
   // Build a new statement.
   return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(),
@@ -5962,7 +6105,7 @@
   // If nothing changed, just retain this statement.
   if (!getDerived().AlwaysRebuild() &&
       Body.get() == S->getSubStmt())
-    return SemaRef.Owned(S);
+    return S;
 
   // Build a new statement.
   return getDerived().RebuildObjCAutoreleasePoolStmt(
@@ -5993,7 +6136,7 @@
       Element.get() == S->getElement() &&
       Collection.get() == S->getCollection() &&
       Body.get() == S->getBody())
-    return SemaRef.Owned(S);
+    return S;
 
   // Build a new statement.
   return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(),
@@ -6006,7 +6149,7 @@
 template <typename Derived>
 StmtResult TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
   // Transform the exception declaration, if any.
-  VarDecl *Var = 0;
+  VarDecl *Var = nullptr;
   if (VarDecl *ExceptionDecl = S->getExceptionDecl()) {
     TypeSourceInfo *T =
         getDerived().TransformType(ExceptionDecl->getTypeSourceInfo());
@@ -6027,7 +6170,7 @@
 
   if (!getDerived().AlwaysRebuild() && !Var &&
       Handler.get() == S->getHandlerBlock())
-    return SemaRef.Owned(S);
+    return S;
 
   return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(), Var, Handler.get());
 }
@@ -6048,12 +6191,12 @@
       return StmtError();
 
     HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(I);
-    Handlers.push_back(Handler.takeAs<Stmt>());
+    Handlers.push_back(Handler.getAs<Stmt>());
   }
 
   if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
       !HandlerChanged)
-    return SemaRef.Owned(S);
+    return S;
 
   return getDerived().RebuildCXXTryStmt(S->getTryLoc(), TryBlock.get(),
                                         Handlers);
@@ -6074,17 +6217,17 @@
   if (Cond.isInvalid())
     return StmtError();
   if (Cond.get())
-    Cond = SemaRef.CheckBooleanCondition(Cond.take(), S->getColonLoc());
+    Cond = SemaRef.CheckBooleanCondition(Cond.get(), S->getColonLoc());
   if (Cond.isInvalid())
     return StmtError();
   if (Cond.get())
-    Cond = SemaRef.MaybeCreateExprWithCleanups(Cond.take());
+    Cond = SemaRef.MaybeCreateExprWithCleanups(Cond.get());
 
   ExprResult Inc = getDerived().TransformExpr(S->getInc());
   if (Inc.isInvalid())
     return StmtError();
   if (Inc.get())
-    Inc = SemaRef.MaybeCreateExprWithCleanups(Inc.take());
+    Inc = SemaRef.MaybeCreateExprWithCleanups(Inc.get());
 
   StmtResult LoopVar = getDerived().TransformStmt(S->getLoopVarStmt());
   if (LoopVar.isInvalid())
@@ -6123,7 +6266,7 @@
   }
 
   if (NewStmt.get() == S)
-    return SemaRef.Owned(S);
+    return S;
 
   return FinishCXXForRangeStmt(NewStmt.get(), Body.get());
 }
@@ -6159,7 +6302,7 @@
   CXXScopeSpec SS;
   SS.Adopt(QualifierLoc);
   bool Dependent = false;
-  switch (getSema().CheckMicrosoftIfExistsSymbol(/*S=*/0, SS, NameInfo)) {
+  switch (getSema().CheckMicrosoftIfExistsSymbol(/*S=*/nullptr, SS, NameInfo)) {
   case Sema::IER_Exists:
     if (S->isIfExists())
       break;
@@ -6235,10 +6378,11 @@
 
   if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
       Handler.get() == S->getHandler())
-    return SemaRef.Owned(S);
+    return S;
 
-  return getDerived().RebuildSEHTryStmt(S->getIsCXXTry(), S->getTryLoc(),
-                                        TryBlock.take(), Handler.take());
+  return getDerived().RebuildSEHTryStmt(
+      S->getIsCXXTry(), S->getTryLoc(), TryBlock.get(), Handler.get(),
+      S->getHandlerIndex(), S->getHandlerParentIndex());
 }
 
 template <typename Derived>
@@ -6247,7 +6391,7 @@
   if (Block.isInvalid())
     return StmtError();
 
-  return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(), Block.take());
+  return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(), Block.get());
 }
 
 template <typename Derived>
@@ -6260,8 +6404,8 @@
   if (Block.isInvalid())
     return StmtError();
 
-  return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(), FilterExpr.take(),
-                                           Block.take());
+  return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(), FilterExpr.get(),
+                                           Block.get());
 }
 
 template <typename Derived>
@@ -6274,9 +6418,16 @@
 
 template<typename Derived>
 StmtResult
-TreeTransform<Derived>::TransformOMPParallelDirective(OMPParallelDirective *D) {
-  DeclarationNameInfo DirName;
-  getSema().StartOpenMPDSABlock(OMPD_parallel, DirName, 0);
+TreeTransform<Derived>::TransformSEHLeaveStmt(SEHLeaveStmt *S) {
+  return S;
+}
+
+//===----------------------------------------------------------------------===//
+// OpenMP directive transformation
+//===----------------------------------------------------------------------===//
+template <typename Derived>
+StmtResult TreeTransform<Derived>::TransformOMPExecutableDirective(
+    OMPExecutableDirective *D) {
 
   // Transform the clauses
   llvm::SmallVector<OMPClause *, 16> TClauses;
@@ -6286,101 +6437,473 @@
        I != E; ++I) {
     if (*I) {
       OMPClause *Clause = getDerived().TransformOMPClause(*I);
-      if (!Clause) {
-        getSema().EndOpenMPDSABlock(0);
-        return StmtError();
-      }
-      TClauses.push_back(Clause);
-    }
-    else {
-      TClauses.push_back(0);
+      if (Clause)
+        TClauses.push_back(Clause);
+    } else {
+      TClauses.push_back(nullptr);
     }
   }
-  if (!D->getAssociatedStmt()) {
-    getSema().EndOpenMPDSABlock(0);
-    return StmtError();
+  StmtResult AssociatedStmt;
+  if (D->hasAssociatedStmt()) {
+    if (!D->getAssociatedStmt()) {
+      return StmtError();
+    }
+    AssociatedStmt = getDerived().TransformStmt(D->getAssociatedStmt());
+    if (AssociatedStmt.isInvalid()) {
+      return StmtError();
+    }
   }
-  StmtResult AssociatedStmt =
-    getDerived().TransformStmt(D->getAssociatedStmt());
-  if (AssociatedStmt.isInvalid()) {
-    getSema().EndOpenMPDSABlock(0);
+  if (TClauses.size() != Clauses.size()) {
     return StmtError();
   }
 
-  StmtResult Res = getDerived().RebuildOMPParallelDirective(TClauses,
-                                                            AssociatedStmt.take(),
-                                                            D->getLocStart(),
-                                                            D->getLocEnd());
-  getSema().EndOpenMPDSABlock(Res.get());
+  // Transform directive name for 'omp critical' directive.
+  DeclarationNameInfo DirName;
+  if (D->getDirectiveKind() == OMPD_critical) {
+    DirName = cast<OMPCriticalDirective>(D)->getDirectiveName();
+    DirName = getDerived().TransformDeclarationNameInfo(DirName);
+  }
+
+  return getDerived().RebuildOMPExecutableDirective(
+      D->getDirectiveKind(), DirName, TClauses, AssociatedStmt.get(),
+      D->getLocStart(), D->getLocEnd());
+}
+
+template <typename Derived>
+StmtResult
+TreeTransform<Derived>::TransformOMPParallelDirective(OMPParallelDirective *D) {
+  DeclarationNameInfo DirName;
+  getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel, DirName, nullptr,
+                                             D->getLocStart());
+  StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
+  getDerived().getSema().EndOpenMPDSABlock(Res.get());
   return Res;
 }
 
-template<typename Derived>
-OMPClause *
-TreeTransform<Derived>::TransformOMPDefaultClause(OMPDefaultClause *C) {
-  return getDerived().RebuildOMPDefaultClause(C->getDefaultKind(),
-                                              C->getDefaultKindKwLoc(),
-                                              C->getLocStart(),
-                                              C->getLParenLoc(),
-                                              C->getLocEnd());
+template <typename Derived>
+StmtResult
+TreeTransform<Derived>::TransformOMPSimdDirective(OMPSimdDirective *D) {
+  DeclarationNameInfo DirName;
+  getDerived().getSema().StartOpenMPDSABlock(OMPD_simd, DirName, nullptr,
+                                             D->getLocStart());
+  StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
+  getDerived().getSema().EndOpenMPDSABlock(Res.get());
+  return Res;
 }
 
-template<typename Derived>
+template <typename Derived>
+StmtResult
+TreeTransform<Derived>::TransformOMPForDirective(OMPForDirective *D) {
+  DeclarationNameInfo DirName;
+  getDerived().getSema().StartOpenMPDSABlock(OMPD_for, DirName, nullptr,
+                                             D->getLocStart());
+  StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
+  getDerived().getSema().EndOpenMPDSABlock(Res.get());
+  return Res;
+}
+
+template <typename Derived>
+StmtResult
+TreeTransform<Derived>::TransformOMPSectionsDirective(OMPSectionsDirective *D) {
+  DeclarationNameInfo DirName;
+  getDerived().getSema().StartOpenMPDSABlock(OMPD_sections, DirName, nullptr,
+                                             D->getLocStart());
+  StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
+  getDerived().getSema().EndOpenMPDSABlock(Res.get());
+  return Res;
+}
+
+template <typename Derived>
+StmtResult
+TreeTransform<Derived>::TransformOMPSectionDirective(OMPSectionDirective *D) {
+  DeclarationNameInfo DirName;
+  getDerived().getSema().StartOpenMPDSABlock(OMPD_section, DirName, nullptr,
+                                             D->getLocStart());
+  StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
+  getDerived().getSema().EndOpenMPDSABlock(Res.get());
+  return Res;
+}
+
+template <typename Derived>
+StmtResult
+TreeTransform<Derived>::TransformOMPSingleDirective(OMPSingleDirective *D) {
+  DeclarationNameInfo DirName;
+  getDerived().getSema().StartOpenMPDSABlock(OMPD_single, DirName, nullptr,
+                                             D->getLocStart());
+  StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
+  getDerived().getSema().EndOpenMPDSABlock(Res.get());
+  return Res;
+}
+
+template <typename Derived>
+StmtResult
+TreeTransform<Derived>::TransformOMPMasterDirective(OMPMasterDirective *D) {
+  DeclarationNameInfo DirName;
+  getDerived().getSema().StartOpenMPDSABlock(OMPD_master, DirName, nullptr,
+                                             D->getLocStart());
+  StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
+  getDerived().getSema().EndOpenMPDSABlock(Res.get());
+  return Res;
+}
+
+template <typename Derived>
+StmtResult
+TreeTransform<Derived>::TransformOMPCriticalDirective(OMPCriticalDirective *D) {
+  getDerived().getSema().StartOpenMPDSABlock(
+      OMPD_critical, D->getDirectiveName(), nullptr, D->getLocStart());
+  StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
+  getDerived().getSema().EndOpenMPDSABlock(Res.get());
+  return Res;
+}
+
+template <typename Derived>
+StmtResult TreeTransform<Derived>::TransformOMPParallelForDirective(
+    OMPParallelForDirective *D) {
+  DeclarationNameInfo DirName;
+  getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_for, DirName,
+                                             nullptr, D->getLocStart());
+  StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
+  getDerived().getSema().EndOpenMPDSABlock(Res.get());
+  return Res;
+}
+
+template <typename Derived>
+StmtResult TreeTransform<Derived>::TransformOMPParallelSectionsDirective(
+    OMPParallelSectionsDirective *D) {
+  DeclarationNameInfo DirName;
+  getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_sections, DirName,
+                                             nullptr, D->getLocStart());
+  StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
+  getDerived().getSema().EndOpenMPDSABlock(Res.get());
+  return Res;
+}
+
+template <typename Derived>
+StmtResult
+TreeTransform<Derived>::TransformOMPTaskDirective(OMPTaskDirective *D) {
+  DeclarationNameInfo DirName;
+  getDerived().getSema().StartOpenMPDSABlock(OMPD_task, DirName, nullptr,
+                                             D->getLocStart());
+  StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
+  getDerived().getSema().EndOpenMPDSABlock(Res.get());
+  return Res;
+}
+
+template <typename Derived>
+StmtResult TreeTransform<Derived>::TransformOMPTaskyieldDirective(
+    OMPTaskyieldDirective *D) {
+  DeclarationNameInfo DirName;
+  getDerived().getSema().StartOpenMPDSABlock(OMPD_taskyield, DirName, nullptr,
+                                             D->getLocStart());
+  StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
+  getDerived().getSema().EndOpenMPDSABlock(Res.get());
+  return Res;
+}
+
+template <typename Derived>
+StmtResult
+TreeTransform<Derived>::TransformOMPBarrierDirective(OMPBarrierDirective *D) {
+  DeclarationNameInfo DirName;
+  getDerived().getSema().StartOpenMPDSABlock(OMPD_barrier, DirName, nullptr,
+                                             D->getLocStart());
+  StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
+  getDerived().getSema().EndOpenMPDSABlock(Res.get());
+  return Res;
+}
+
+template <typename Derived>
+StmtResult
+TreeTransform<Derived>::TransformOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
+  DeclarationNameInfo DirName;
+  getDerived().getSema().StartOpenMPDSABlock(OMPD_taskwait, DirName, nullptr,
+                                             D->getLocStart());
+  StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
+  getDerived().getSema().EndOpenMPDSABlock(Res.get());
+  return Res;
+}
+
+template <typename Derived>
+StmtResult
+TreeTransform<Derived>::TransformOMPFlushDirective(OMPFlushDirective *D) {
+  DeclarationNameInfo DirName;
+  getDerived().getSema().StartOpenMPDSABlock(OMPD_flush, DirName, nullptr,
+                                             D->getLocStart());
+  StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
+  getDerived().getSema().EndOpenMPDSABlock(Res.get());
+  return Res;
+}
+
+//===----------------------------------------------------------------------===//
+// OpenMP clause transformation
+//===----------------------------------------------------------------------===//
+template <typename Derived>
+OMPClause *TreeTransform<Derived>::TransformOMPIfClause(OMPIfClause *C) {
+  ExprResult Cond = getDerived().TransformExpr(C->getCondition());
+  if (Cond.isInvalid())
+    return nullptr;
+  return getDerived().RebuildOMPIfClause(Cond.get(), C->getLocStart(),
+                                         C->getLParenLoc(), C->getLocEnd());
+}
+
+template <typename Derived>
+OMPClause *TreeTransform<Derived>::TransformOMPFinalClause(OMPFinalClause *C) {
+  ExprResult Cond = getDerived().TransformExpr(C->getCondition());
+  if (Cond.isInvalid())
+    return nullptr;
+  return getDerived().RebuildOMPFinalClause(Cond.get(), C->getLocStart(),
+                                            C->getLParenLoc(), C->getLocEnd());
+}
+
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPNumThreadsClause(OMPNumThreadsClause *C) {
+  ExprResult NumThreads = getDerived().TransformExpr(C->getNumThreads());
+  if (NumThreads.isInvalid())
+    return nullptr;
+  return getDerived().RebuildOMPNumThreadsClause(
+      NumThreads.get(), C->getLocStart(), C->getLParenLoc(), C->getLocEnd());
+}
+
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPSafelenClause(OMPSafelenClause *C) {
+  ExprResult E = getDerived().TransformExpr(C->getSafelen());
+  if (E.isInvalid())
+    return nullptr;
+  return getDerived().RebuildOMPSafelenClause(
+      E.get(), C->getLocStart(), C->getLParenLoc(), C->getLocEnd());
+}
+
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPCollapseClause(OMPCollapseClause *C) {
+  ExprResult E = getDerived().TransformExpr(C->getNumForLoops());
+  if (E.isInvalid())
+    return 0;
+  return getDerived().RebuildOMPCollapseClause(
+      E.get(), C->getLocStart(), C->getLParenLoc(), C->getLocEnd());
+}
+
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPDefaultClause(OMPDefaultClause *C) {
+  return getDerived().RebuildOMPDefaultClause(
+      C->getDefaultKind(), C->getDefaultKindKwLoc(), C->getLocStart(),
+      C->getLParenLoc(), C->getLocEnd());
+}
+
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPProcBindClause(OMPProcBindClause *C) {
+  return getDerived().RebuildOMPProcBindClause(
+      C->getProcBindKind(), C->getProcBindKindKwLoc(), C->getLocStart(),
+      C->getLParenLoc(), C->getLocEnd());
+}
+
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPScheduleClause(OMPScheduleClause *C) {
+  ExprResult E = getDerived().TransformExpr(C->getChunkSize());
+  if (E.isInvalid())
+    return nullptr;
+  return getDerived().RebuildOMPScheduleClause(
+      C->getScheduleKind(), E.get(), C->getLocStart(), C->getLParenLoc(),
+      C->getScheduleKindLoc(), C->getCommaLoc(), C->getLocEnd());
+}
+
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPOrderedClause(OMPOrderedClause *C) {
+  // No need to rebuild this clause, no template-dependent parameters.
+  return C;
+}
+
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPNowaitClause(OMPNowaitClause *C) {
+  // No need to rebuild this clause, no template-dependent parameters.
+  return C;
+}
+
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPUntiedClause(OMPUntiedClause *C) {
+  // No need to rebuild this clause, no template-dependent parameters.
+  return C;
+}
+
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPMergeableClause(OMPMergeableClause *C) {
+  // No need to rebuild this clause, no template-dependent parameters.
+  return C;
+}
+
+template <typename Derived>
 OMPClause *
 TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {
   llvm::SmallVector<Expr *, 16> Vars;
   Vars.reserve(C->varlist_size());
-  for (OMPPrivateClause::varlist_iterator I = C->varlist_begin(),
-                                          E = C->varlist_end();
-       I != E; ++I) {
-    ExprResult EVar = getDerived().TransformExpr(cast<Expr>(*I));
+  for (auto *VE : C->varlists()) {
+    ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
     if (EVar.isInvalid())
-      return 0;
-    Vars.push_back(EVar.take());
+      return nullptr;
+    Vars.push_back(EVar.get());
   }
-  return getDerived().RebuildOMPPrivateClause(Vars,
-                                              C->getLocStart(),
-                                              C->getLParenLoc(),
-                                              C->getLocEnd());
+  return getDerived().RebuildOMPPrivateClause(
+      Vars, C->getLocStart(), C->getLParenLoc(), C->getLocEnd());
 }
 
-template<typename Derived>
-OMPClause *
-TreeTransform<Derived>::TransformOMPFirstprivateClause(
-                                                 OMPFirstprivateClause *C) {
+template <typename Derived>
+OMPClause *TreeTransform<Derived>::TransformOMPFirstprivateClause(
+    OMPFirstprivateClause *C) {
   llvm::SmallVector<Expr *, 16> Vars;
   Vars.reserve(C->varlist_size());
-  for (OMPFirstprivateClause::varlist_iterator I = C->varlist_begin(),
-                                               E = C->varlist_end();
-       I != E; ++I) {
-    ExprResult EVar = getDerived().TransformExpr(cast<Expr>(*I));
+  for (auto *VE : C->varlists()) {
+    ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
     if (EVar.isInvalid())
-      return 0;
-    Vars.push_back(EVar.take());
+      return nullptr;
+    Vars.push_back(EVar.get());
   }
-  return getDerived().RebuildOMPFirstprivateClause(Vars,
-                                                   C->getLocStart(),
-                                                   C->getLParenLoc(),
-                                                   C->getLocEnd());
+  return getDerived().RebuildOMPFirstprivateClause(
+      Vars, C->getLocStart(), C->getLParenLoc(), C->getLocEnd());
 }
 
-template<typename Derived>
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPLastprivateClause(OMPLastprivateClause *C) {
+  llvm::SmallVector<Expr *, 16> Vars;
+  Vars.reserve(C->varlist_size());
+  for (auto *VE : C->varlists()) {
+    ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
+    if (EVar.isInvalid())
+      return nullptr;
+    Vars.push_back(EVar.get());
+  }
+  return getDerived().RebuildOMPLastprivateClause(
+      Vars, C->getLocStart(), C->getLParenLoc(), C->getLocEnd());
+}
+
+template <typename Derived>
 OMPClause *
 TreeTransform<Derived>::TransformOMPSharedClause(OMPSharedClause *C) {
   llvm::SmallVector<Expr *, 16> Vars;
   Vars.reserve(C->varlist_size());
-  for (OMPSharedClause::varlist_iterator I = C->varlist_begin(),
-                                         E = C->varlist_end();
-       I != E; ++I) {
-    ExprResult EVar = getDerived().TransformExpr(cast<Expr>(*I));
+  for (auto *VE : C->varlists()) {
+    ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
     if (EVar.isInvalid())
-      return 0;
-    Vars.push_back(EVar.take());
+      return nullptr;
+    Vars.push_back(EVar.get());
   }
-  return getDerived().RebuildOMPSharedClause(Vars,
-                                             C->getLocStart(),
+  return getDerived().RebuildOMPSharedClause(Vars, C->getLocStart(),
+                                             C->getLParenLoc(), C->getLocEnd());
+}
+
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause *C) {
+  llvm::SmallVector<Expr *, 16> Vars;
+  Vars.reserve(C->varlist_size());
+  for (auto *VE : C->varlists()) {
+    ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
+    if (EVar.isInvalid())
+      return nullptr;
+    Vars.push_back(EVar.get());
+  }
+  CXXScopeSpec ReductionIdScopeSpec;
+  ReductionIdScopeSpec.Adopt(C->getQualifierLoc());
+
+  DeclarationNameInfo NameInfo = C->getNameInfo();
+  if (NameInfo.getName()) {
+    NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
+    if (!NameInfo.getName())
+      return nullptr;
+  }
+  return getDerived().RebuildOMPReductionClause(
+      Vars, C->getLocStart(), C->getLParenLoc(), C->getColonLoc(),
+      C->getLocEnd(), ReductionIdScopeSpec, NameInfo);
+}
+
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *C) {
+  llvm::SmallVector<Expr *, 16> Vars;
+  Vars.reserve(C->varlist_size());
+  for (auto *VE : C->varlists()) {
+    ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
+    if (EVar.isInvalid())
+      return nullptr;
+    Vars.push_back(EVar.get());
+  }
+  ExprResult Step = getDerived().TransformExpr(C->getStep());
+  if (Step.isInvalid())
+    return nullptr;
+  return getDerived().RebuildOMPLinearClause(Vars, Step.get(), C->getLocStart(),
                                              C->getLParenLoc(),
-                                             C->getLocEnd());
+                                             C->getColonLoc(), C->getLocEnd());
+}
+
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPAlignedClause(OMPAlignedClause *C) {
+  llvm::SmallVector<Expr *, 16> Vars;
+  Vars.reserve(C->varlist_size());
+  for (auto *VE : C->varlists()) {
+    ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
+    if (EVar.isInvalid())
+      return nullptr;
+    Vars.push_back(EVar.get());
+  }
+  ExprResult Alignment = getDerived().TransformExpr(C->getAlignment());
+  if (Alignment.isInvalid())
+    return nullptr;
+  return getDerived().RebuildOMPAlignedClause(
+      Vars, Alignment.get(), C->getLocStart(), C->getLParenLoc(),
+      C->getColonLoc(), C->getLocEnd());
+}
+
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPCopyinClause(OMPCopyinClause *C) {
+  llvm::SmallVector<Expr *, 16> Vars;
+  Vars.reserve(C->varlist_size());
+  for (auto *VE : C->varlists()) {
+    ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
+    if (EVar.isInvalid())
+      return nullptr;
+    Vars.push_back(EVar.get());
+  }
+  return getDerived().RebuildOMPCopyinClause(Vars, C->getLocStart(),
+                                             C->getLParenLoc(), C->getLocEnd());
+}
+
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPCopyprivateClause(OMPCopyprivateClause *C) {
+  llvm::SmallVector<Expr *, 16> Vars;
+  Vars.reserve(C->varlist_size());
+  for (auto *VE : C->varlists()) {
+    ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
+    if (EVar.isInvalid())
+      return nullptr;
+    Vars.push_back(EVar.get());
+  }
+  return getDerived().RebuildOMPCopyprivateClause(
+      Vars, C->getLocStart(), C->getLParenLoc(), C->getLocEnd());
+}
+
+template <typename Derived>
+OMPClause *TreeTransform<Derived>::TransformOMPFlushClause(OMPFlushClause *C) {
+  llvm::SmallVector<Expr *, 16> Vars;
+  Vars.reserve(C->varlist_size());
+  for (auto *VE : C->varlists()) {
+    ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
+    if (EVar.isInvalid())
+      return nullptr;
+    Vars.push_back(EVar.get());
+  }
+  return getDerived().RebuildOMPFlushClause(Vars, C->getLocStart(),
+                                            C->getLParenLoc(), C->getLocEnd());
 }
 
 //===----------------------------------------------------------------------===//
@@ -6389,7 +6912,7 @@
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
-  return SemaRef.Owned(E);
+  return E;
 }
 
 template<typename Derived>
@@ -6426,10 +6949,10 @@
     // FIXME: this is a bit instantiation-specific.
     SemaRef.MarkDeclRefReferenced(E);
 
-    return SemaRef.Owned(E);
+    return E;
   }
 
-  TemplateArgumentListInfo TransArgs, *TemplateArgs = 0;
+  TemplateArgumentListInfo TransArgs, *TemplateArgs = nullptr;
   if (E->hasExplicitTemplateArgs()) {
     TemplateArgs = &TransArgs;
     TransArgs.setLAngleLoc(E->getLAngleLoc());
@@ -6447,31 +6970,31 @@
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
-  return SemaRef.Owned(E);
+  return E;
 }
 
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
-  return SemaRef.Owned(E);
+  return E;
 }
 
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
-  return SemaRef.Owned(E);
+  return E;
 }
 
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
-  return SemaRef.Owned(E);
+  return E;
 }
 
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
-  return SemaRef.Owned(E);
+  return E;
 }
 
 template<typename Derived>
@@ -6500,19 +7023,19 @@
         return ExprError();
       AssocTypes.push_back(AssocType);
     } else {
-      AssocTypes.push_back(0);
+      AssocTypes.push_back(nullptr);
     }
 
     ExprResult AssocExpr = getDerived().TransformExpr(E->getAssocExpr(i));
     if (AssocExpr.isInvalid())
       return ExprError();
-    AssocExprs.push_back(AssocExpr.release());
+    AssocExprs.push_back(AssocExpr.get());
   }
 
   return getDerived().RebuildGenericSelectionExpr(E->getGenericLoc(),
                                                   E->getDefaultLoc(),
                                                   E->getRParenLoc(),
-                                                  ControllingExpr.release(),
+                                                  ControllingExpr.get(),
                                                   AssocTypes,
                                                   AssocExprs);
 }
@@ -6525,7 +7048,7 @@
     return ExprError();
 
   if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildParenExpr(SubExpr.get(), E->getLParen(),
                                        E->getRParen());
@@ -6538,7 +7061,7 @@
 ExprResult
 TreeTransform<Derived>::TransformAddressOfOperand(Expr *E) {
   if (DependentScopeDeclRefExpr *DRE = dyn_cast<DependentScopeDeclRefExpr>(E))
-    return getDerived().TransformDependentScopeDeclRefExpr(DRE, true);
+    return getDerived().TransformDependentScopeDeclRefExpr(DRE, true, nullptr);
   else
     return getDerived().TransformExpr(E);
 }
@@ -6555,7 +7078,7 @@
     return ExprError();
 
   if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
                                            E->getOpcode(),
@@ -6620,7 +7143,7 @@
   if (!getDerived().AlwaysRebuild() &&
       Type == E->getTypeSourceInfo() &&
       !ExprChanged)
-    return SemaRef.Owned(E);
+    return E;
 
   // Build a new offsetof expression.
   return getDerived().RebuildOffsetOfExpr(E->getOperatorLoc(), Type,
@@ -6633,7 +7156,7 @@
 TreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) {
   assert(getDerived().AlreadyTransformed(E->getType()) &&
          "opaque value expression requires transformation");
-  return SemaRef.Owned(E);
+  return E;
 }
 
 template<typename Derived>
@@ -6653,7 +7176,7 @@
   // expression must have been an lvalue-to-rvalue conversion which we
   // should reapply.
   if (result.get()->hasPlaceholderType(BuiltinType::PseudoObject))
-    result = SemaRef.checkPseudoObjectRValue(result.take());
+    result = SemaRef.checkPseudoObjectRValue(result.get());
 
   return result;
 }
@@ -6670,7 +7193,7 @@
       return ExprError();
 
     if (!getDerived().AlwaysRebuild() && OldT == NewT)
-      return SemaRef.Owned(E);
+      return E;
 
     return getDerived().RebuildUnaryExprOrTypeTrait(NewT, E->getOperatorLoc(),
                                                     E->getKind(),
@@ -6683,12 +7206,26 @@
   EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated,
                                                Sema::ReuseLambdaContextDecl);
 
-  ExprResult SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
-  if (SubExpr.isInvalid())
+  // Try to recover if we have something like sizeof(T::X) where X is a type.
+  // Notably, there must be *exactly* one set of parens if X is a type.
+  TypeSourceInfo *RecoveryTSI = nullptr;
+  ExprResult SubExpr;
+  auto *PE = dyn_cast<ParenExpr>(E->getArgumentExpr());
+  if (auto *DRE =
+          PE ? dyn_cast<DependentScopeDeclRefExpr>(PE->getSubExpr()) : nullptr)
+    SubExpr = getDerived().TransformParenDependentScopeDeclRefExpr(
+        PE, DRE, false, &RecoveryTSI);
+  else
+    SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
+
+  if (RecoveryTSI) {
+    return getDerived().RebuildUnaryExprOrTypeTrait(
+        RecoveryTSI, E->getOperatorLoc(), E->getKind(), E->getSourceRange());
+  } else if (SubExpr.isInvalid())
     return ExprError();
 
   if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildUnaryExprOrTypeTrait(SubExpr.get(),
                                                   E->getOperatorLoc(),
@@ -6711,7 +7248,7 @@
   if (!getDerived().AlwaysRebuild() &&
       LHS.get() == E->getLHS() &&
       RHS.get() == E->getRHS())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildArraySubscriptExpr(LHS.get(),
                                            /*FIXME:*/E->getLHS()->getLocStart(),
@@ -6791,7 +7328,7 @@
     // FIXME: this is a bit instantiation-specific.
     SemaRef.MarkMemberReferenced(E);
 
-    return SemaRef.Owned(E);
+    return E;
   }
 
   TemplateArgumentListInfo TransArgs;
@@ -6805,14 +7342,14 @@
   }
 
   // FIXME: Bogus source location for the operator
-  SourceLocation FakeOperatorLoc
-    = SemaRef.PP.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
+  SourceLocation FakeOperatorLoc =
+      SemaRef.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
 
   // FIXME: to do this check properly, we will need to preserve the
   // first-qualifier-in-scope here, just in case we had a dependent
   // base (and therefore couldn't do the check) and a
   // nested-name-qualifier (and therefore could do the lookup).
-  NamedDecl *FirstQualifierInScope = 0;
+  NamedDecl *FirstQualifierInScope = nullptr;
 
   return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc,
                                         E->isArrow(),
@@ -6822,7 +7359,7 @@
                                         Member,
                                         FoundDecl,
                                         (E->hasExplicitTemplateArgs()
-                                           ? &TransArgs : 0),
+                                           ? &TransArgs : nullptr),
                                         FirstQualifierInScope);
 }
 
@@ -6840,7 +7377,7 @@
   if (!getDerived().AlwaysRebuild() &&
       LHS.get() == E->getLHS() &&
       RHS.get() == E->getRHS())
-    return SemaRef.Owned(E);
+    return E;
 
   Sema::FPContractStateRAII FPContractState(getSema());
   getSema().FPFeatures.fp_contract = E->isFPContractable();
@@ -6873,11 +7410,11 @@
   if (!getDerived().AlwaysRebuild() &&
       commonExpr.get() == e->getCommon() &&
       rhs.get() == e->getFalseExpr())
-    return SemaRef.Owned(e);
+    return e;
 
-  return getDerived().RebuildConditionalOperator(commonExpr.take(),
+  return getDerived().RebuildConditionalOperator(commonExpr.get(),
                                                  e->getQuestionLoc(),
-                                                 0,
+                                                 nullptr,
                                                  e->getColonLoc(),
                                                  rhs.get());
 }
@@ -6901,7 +7438,7 @@
       Cond.get() == E->getCond() &&
       LHS.get() == E->getLHS() &&
       RHS.get() == E->getRHS())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildConditionalOperator(Cond.get(),
                                                  E->getQuestionLoc(),
@@ -6933,7 +7470,7 @@
   if (!getDerived().AlwaysRebuild() &&
       Type == E->getTypeInfoAsWritten() &&
       SubExpr.get() == E->getSubExpr())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildCStyleCastExpr(E->getLParenLoc(),
                                             Type,
@@ -6976,11 +7513,11 @@
 
   if (!getDerived().AlwaysRebuild() &&
       Base.get() == E->getBase())
-    return SemaRef.Owned(E);
+    return E;
 
   // FIXME: Bad source location
-  SourceLocation FakeOperatorLoc
-    = SemaRef.PP.getLocForEndOfToken(E->getBase()->getLocEnd());
+  SourceLocation FakeOperatorLoc =
+      SemaRef.getLocForEndOfToken(E->getBase()->getLocEnd());
   return getDerived().RebuildExtVectorElementExpr(Base.get(), FakeOperatorLoc,
                                                   E->getAccessorLoc(),
                                                   E->getAccessor());
@@ -6997,7 +7534,7 @@
     return ExprError();
 
   if (!getDerived().AlwaysRebuild() && !InitChanged)
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildInitList(E->getLBraceLoc(), Inits,
                                       E->getRBraceLoc(), E->getType());
@@ -7035,7 +7572,7 @@
                                                D->getLBracketLoc()));
 
       ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(*D);
-      ArrayExprs.push_back(Index.release());
+      ArrayExprs.push_back(Index.get());
       continue;
     }
 
@@ -7057,14 +7594,14 @@
     ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(*D) ||
       End.get() != E->getArrayRangeEnd(*D);
 
-    ArrayExprs.push_back(Start.release());
-    ArrayExprs.push_back(End.release());
+    ArrayExprs.push_back(Start.get());
+    ArrayExprs.push_back(End.get());
   }
 
   if (!getDerived().AlwaysRebuild() &&
       Init.get() == E->getInit() &&
       !ExprChanged)
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildDesignatedInitExpr(Desig, ArrayExprs,
                                                 E->getEqualOrColonLoc(),
@@ -7085,7 +7622,7 @@
 
   if (!getDerived().AlwaysRebuild() &&
       T == E->getType())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildImplicitValueInitExpr(T);
 }
@@ -7104,7 +7641,7 @@
   if (!getDerived().AlwaysRebuild() &&
       TInfo == E->getWrittenTypeInfo() &&
       SubExpr.get() == E->getSubExpr())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), SubExpr.get(),
                                        TInfo, E->getRParenLoc());
@@ -7183,7 +7720,7 @@
       Cond.get() == E->getCond() &&
       LHS.get() == E->getLHS() &&
       RHS.get() == E->getRHS())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
                                         Cond.get(), LHS.get(), RHS.get(),
@@ -7193,7 +7730,7 @@
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
-  return SemaRef.Owned(E);
+  return E;
 }
 
 template<typename Derived>
@@ -7216,9 +7753,8 @@
       return ExprError();
 
     // FIXME: Poor location information
-    SourceLocation FakeLParenLoc
-      = SemaRef.PP.getLocForEndOfToken(
-                              static_cast<Expr *>(Object.get())->getLocEnd());
+    SourceLocation FakeLParenLoc = SemaRef.getLocForEndOfToken(
+        static_cast<Expr *>(Object.get())->getLocEnd());
 
     // Transform the call arguments.
     SmallVector<Expr*, 8> Args;
@@ -7336,7 +7872,7 @@
   if (!getDerived().AlwaysRebuild() &&
       Type == E->getTypeInfoAsWritten() &&
       SubExpr.get() == E->getSubExpr())
-    return SemaRef.Owned(E);
+    return E;
   return getDerived().RebuildCXXNamedCastExpr(E->getOperatorLoc(),
                                               E->getStmtClass(),
                                               E->getAngleBrackets().getBegin(),
@@ -7389,7 +7925,7 @@
   if (!getDerived().AlwaysRebuild() &&
       Type == E->getTypeInfoAsWritten() &&
       SubExpr.get() == E->getSubExpr())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildCXXFunctionalCastExpr(Type,
                                                    E->getLParenLoc(),
@@ -7408,7 +7944,7 @@
 
     if (!getDerived().AlwaysRebuild() &&
         TInfo == E->getTypeOperandSourceInfo())
-      return SemaRef.Owned(E);
+      return E;
 
     return getDerived().RebuildCXXTypeidExpr(E->getType(),
                                              E->getLocStart(),
@@ -7429,7 +7965,7 @@
 
   if (!getDerived().AlwaysRebuild() &&
       SubExpr.get() == E->getExprOperand())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildCXXTypeidExpr(E->getType(),
                                            E->getLocStart(),
@@ -7448,7 +7984,7 @@
 
     if (!getDerived().AlwaysRebuild() &&
         TInfo == E->getTypeOperandSourceInfo())
-      return SemaRef.Owned(E);
+      return E;
 
     return getDerived().RebuildCXXUuidofExpr(E->getType(),
                                              E->getLocStart(),
@@ -7464,7 +8000,7 @@
 
   if (!getDerived().AlwaysRebuild() &&
       SubExpr.get() == E->getExprOperand())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildCXXUuidofExpr(E->getType(),
                                            E->getLocStart(),
@@ -7475,14 +8011,14 @@
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
-  return SemaRef.Owned(E);
+  return E;
 }
 
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
                                                      CXXNullPtrLiteralExpr *E) {
-  return SemaRef.Owned(E);
+  return E;
 }
 
 template<typename Derived>
@@ -7493,7 +8029,7 @@
   if (!getDerived().AlwaysRebuild() && T == E->getType()) {
     // Make sure that we capture 'this'.
     getSema().CheckCXXThisCapture(E->getLocStart());
-    return SemaRef.Owned(E);
+    return E;
   }
 
   return getDerived().RebuildCXXThisExpr(E->getLocStart(), T, E->isImplicit());
@@ -7508,7 +8044,7 @@
 
   if (!getDerived().AlwaysRebuild() &&
       SubExpr.get() == E->getSubExpr())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), SubExpr.get(),
                                           E->isThrownVariableInScope());
@@ -7525,7 +8061,7 @@
 
   if (!getDerived().AlwaysRebuild() &&
       Param == E->getParam())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param);
 }
@@ -7540,7 +8076,7 @@
     return ExprError();
 
   if (!getDerived().AlwaysRebuild() && Field == E->getField())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildCXXDefaultInitExpr(E->getExprLoc(), Field);
 }
@@ -7555,7 +8091,7 @@
 
   if (!getDerived().AlwaysRebuild() &&
       T == E->getTypeSourceInfo())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildCXXScalarValueInitExpr(T,
                                           /*FIXME:*/T->getTypeLoc().getEndLoc(),
@@ -7588,12 +8124,12 @@
   Expr *OldInit = E->getInitializer();
   ExprResult NewInit;
   if (OldInit)
-    NewInit = getDerived().TransformExpr(OldInit);
+    NewInit = getDerived().TransformInitializer(OldInit, true);
   if (NewInit.isInvalid())
     return ExprError();
 
   // Transform new operator and delete operator.
-  FunctionDecl *OperatorNew = 0;
+  FunctionDecl *OperatorNew = nullptr;
   if (E->getOperatorNew()) {
     OperatorNew = cast_or_null<FunctionDecl>(
                                  getDerived().TransformDecl(E->getLocStart(),
@@ -7602,7 +8138,7 @@
       return ExprError();
   }
 
-  FunctionDecl *OperatorDelete = 0;
+  FunctionDecl *OperatorDelete = nullptr;
   if (E->getOperatorDelete()) {
     OperatorDelete = cast_or_null<FunctionDecl>(
                                    getDerived().TransformDecl(E->getLocStart(),
@@ -7636,7 +8172,7 @@
       }
     }
 
-    return SemaRef.Owned(E);
+    return E;
   }
 
   QualType AllocType = AllocTypeInfo->getType();
@@ -7651,16 +8187,14 @@
       // Do nothing
     } else if (const ConstantArrayType *ConsArrayT
                                      = dyn_cast<ConstantArrayType>(ArrayT)) {
-      ArraySize
-        = SemaRef.Owned(IntegerLiteral::Create(SemaRef.Context,
-                                               ConsArrayT->getSize(),
-                                               SemaRef.Context.getSizeType(),
-                                               /*FIXME:*/E->getLocStart()));
+      ArraySize = IntegerLiteral::Create(SemaRef.Context, ConsArrayT->getSize(),
+                                         SemaRef.Context.getSizeType(),
+                                         /*FIXME:*/ E->getLocStart());
       AllocType = ConsArrayT->getElementType();
     } else if (const DependentSizedArrayType *DepArrayT
                               = dyn_cast<DependentSizedArrayType>(ArrayT)) {
       if (DepArrayT->getSizeExpr()) {
-        ArraySize = SemaRef.Owned(DepArrayT->getSizeExpr());
+        ArraySize = DepArrayT->getSizeExpr();
         AllocType = DepArrayT->getElementType();
       }
     }
@@ -7676,7 +8210,7 @@
                                         AllocTypeInfo,
                                         ArraySize.get(),
                                         E->getDirectInitRange(),
-                                        NewInit.take());
+                                        NewInit.get());
 }
 
 template<typename Derived>
@@ -7687,7 +8221,7 @@
     return ExprError();
 
   // Transform the delete operator, if known.
-  FunctionDecl *OperatorDelete = 0;
+  FunctionDecl *OperatorDelete = nullptr;
   if (E->getOperatorDelete()) {
     OperatorDelete = cast_or_null<FunctionDecl>(
                                    getDerived().TransformDecl(E->getLocStart(),
@@ -7714,7 +8248,7 @@
       }
     }
 
-    return SemaRef.Owned(E);
+    return E;
   }
 
   return getDerived().RebuildCXXDeleteExpr(E->getLocStart(),
@@ -7733,7 +8267,7 @@
 
   ParsedType ObjectTypePtr;
   bool MayBePseudoDestructor = false;
-  Base = SemaRef.ActOnStartCXXMemberReference(0, Base.get(),
+  Base = SemaRef.ActOnStartCXXMemberReference(nullptr, Base.get(),
                                               E->getOperatorLoc(),
                                         E->isArrow()? tok::arrow : tok::period,
                                               ObjectTypePtr,
@@ -7756,7 +8290,7 @@
   if (E->getDestroyedTypeInfo()) {
     TypeSourceInfo *DestroyedTypeInfo
       = getDerived().TransformTypeInObjectScope(E->getDestroyedTypeInfo(),
-                                                ObjectType, 0, SS);
+                                                ObjectType, nullptr, SS);
     if (!DestroyedTypeInfo)
       return ExprError();
     Destroyed = DestroyedTypeInfo;
@@ -7770,7 +8304,7 @@
     ParsedType T = SemaRef.getDestructorName(E->getTildeLoc(),
                                               *E->getDestroyedTypeIdentifier(),
                                                 E->getDestroyedTypeLoc(),
-                                                /*Scope=*/0,
+                                                /*Scope=*/nullptr,
                                                 SS, ObjectTypePtr,
                                                 false);
     if (!T)
@@ -7781,11 +8315,11 @@
                                                  E->getDestroyedTypeLoc());
   }
 
-  TypeSourceInfo *ScopeTypeInfo = 0;
+  TypeSourceInfo *ScopeTypeInfo = nullptr;
   if (E->getScopeTypeInfo()) {
     CXXScopeSpec EmptySS;
     ScopeTypeInfo = getDerived().TransformTypeInObjectScope(
-                      E->getScopeTypeInfo(), ObjectType, 0, EmptySS);
+                      E->getScopeTypeInfo(), ObjectType, nullptr, EmptySS);
     if (!ScopeTypeInfo)
       return ExprError();
   }
@@ -7827,9 +8361,8 @@
     // Expand using declarations.
     if (isa<UsingDecl>(InstD)) {
       UsingDecl *UD = cast<UsingDecl>(InstD);
-      for (UsingDecl::shadow_iterator I = UD->shadow_begin(),
-             E = UD->shadow_end(); I != E; ++I)
-        R.addDecl(*I);
+      for (auto *I : UD->shadows())
+        R.addDecl(I);
       continue;
     }
 
@@ -7888,44 +8421,6 @@
 
 template<typename Derived>
 ExprResult
-TreeTransform<Derived>::TransformUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
-  TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo());
-  if (!T)
-    return ExprError();
-
-  if (!getDerived().AlwaysRebuild() &&
-      T == E->getQueriedTypeSourceInfo())
-    return SemaRef.Owned(E);
-
-  return getDerived().RebuildUnaryTypeTrait(E->getTrait(),
-                                            E->getLocStart(),
-                                            T,
-                                            E->getLocEnd());
-}
-
-template<typename Derived>
-ExprResult
-TreeTransform<Derived>::TransformBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
-  TypeSourceInfo *LhsT = getDerived().TransformType(E->getLhsTypeSourceInfo());
-  if (!LhsT)
-    return ExprError();
-
-  TypeSourceInfo *RhsT = getDerived().TransformType(E->getRhsTypeSourceInfo());
-  if (!RhsT)
-    return ExprError();
-
-  if (!getDerived().AlwaysRebuild() &&
-      LhsT == E->getLhsTypeSourceInfo() && RhsT == E->getRhsTypeSourceInfo())
-    return SemaRef.Owned(E);
-
-  return getDerived().RebuildBinaryTypeTrait(E->getTrait(),
-                                            E->getLocStart(),
-                                            LhsT, RhsT,
-                                            E->getLocEnd());
-}
-
-template<typename Derived>
-ExprResult
 TreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) {
   bool ArgChanged = false;
   SmallVector<TypeSourceInfo *, 4> Args;
@@ -8051,7 +8546,7 @@
   }
 
   if (!getDerived().AlwaysRebuild() && !ArgChanged)
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildTypeTrait(E->getTrait(),
                                        E->getLocStart(),
@@ -8068,7 +8563,7 @@
 
   if (!getDerived().AlwaysRebuild() &&
       T == E->getQueriedTypeSourceInfo())
-    return SemaRef.Owned(E);
+    return E;
 
   ExprResult SubExpr;
   {
@@ -8078,7 +8573,7 @@
       return ExprError();
 
     if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getDimensionExpression())
-      return SemaRef.Owned(E);
+      return E;
   }
 
   return getDerived().RebuildArrayTypeTrait(E->getTrait(),
@@ -8099,25 +8594,44 @@
       return ExprError();
 
     if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getQueriedExpression())
-      return SemaRef.Owned(E);
+      return E;
   }
 
   return getDerived().RebuildExpressionTrait(
       E->getTrait(), E->getLocStart(), SubExpr.get(), E->getLocEnd());
 }
 
-template<typename Derived>
-ExprResult
-TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
-                                               DependentScopeDeclRefExpr *E) {
-  return TransformDependentScopeDeclRefExpr(E, /*IsAddressOfOperand*/false);
+template <typename Derived>
+ExprResult TreeTransform<Derived>::TransformParenDependentScopeDeclRefExpr(
+    ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool AddrTaken,
+    TypeSourceInfo **RecoveryTSI) {
+  ExprResult NewDRE = getDerived().TransformDependentScopeDeclRefExpr(
+      DRE, AddrTaken, RecoveryTSI);
+
+  // Propagate both errors and recovered types, which return ExprEmpty.
+  if (!NewDRE.isUsable())
+    return NewDRE;
+
+  // We got an expr, wrap it up in parens.
+  if (!getDerived().AlwaysRebuild() && NewDRE.get() == DRE)
+    return PE;
+  return getDerived().RebuildParenExpr(NewDRE.get(), PE->getLParen(),
+                                       PE->getRParen());
+}
+
+template <typename Derived>
+ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
+    DependentScopeDeclRefExpr *E) {
+  return TransformDependentScopeDeclRefExpr(E, /*IsAddressOfOperand=*/false,
+                                            nullptr);
 }
 
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
                                                DependentScopeDeclRefExpr *E,
-                                               bool IsAddressOfOperand) {
+                                               bool IsAddressOfOperand,
+                                               TypeSourceInfo **RecoveryTSI) {
   assert(E->getQualifierLoc());
   NestedNameSpecifierLoc QualifierLoc
   = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
@@ -8140,13 +8654,11 @@
         // Note: it is sufficient to compare the Name component of NameInfo:
         // if name has not changed, DNLoc has not changed either.
         NameInfo.getName() == E->getDeclName())
-      return SemaRef.Owned(E);
+      return E;
 
-    return getDerived().RebuildDependentScopeDeclRefExpr(QualifierLoc,
-                                                         TemplateKWLoc,
-                                                         NameInfo,
-                                                         /*TemplateArgs*/ 0,
-                                                         IsAddressOfOperand);
+    return getDerived().RebuildDependentScopeDeclRefExpr(
+        QualifierLoc, TemplateKWLoc, NameInfo, /*TemplateArgs=*/nullptr,
+        IsAddressOfOperand, RecoveryTSI);
   }
 
   TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
@@ -8155,11 +8667,9 @@
                                               TransArgs))
     return ExprError();
 
-  return getDerived().RebuildDependentScopeDeclRefExpr(QualifierLoc,
-                                                       TemplateKWLoc,
-                                                       NameInfo,
-                                                       &TransArgs,
-                                                       IsAddressOfOperand);
+  return getDerived().RebuildDependentScopeDeclRefExpr(
+      QualifierLoc, TemplateKWLoc, NameInfo, &TransArgs, IsAddressOfOperand,
+      RecoveryTSI);
 }
 
 template<typename Derived>
@@ -8200,7 +8710,7 @@
     // Mark the constructor as referenced.
     // FIXME: Instantiation-specific
     SemaRef.MarkFunctionReferenced(E->getLocStart(), Constructor);
-    return SemaRef.Owned(E);
+    return E;
   }
 
   return getDerived().RebuildCXXConstructExpr(T, /*FIXME:*/E->getLocStart(),
@@ -8208,6 +8718,7 @@
                                               Args,
                                               E->hadMultipleCandidates(),
                                               E->isListInitialization(),
+                                              E->isStdInitListInitialization(),
                                               E->requiresZeroInitialization(),
                                               E->getConstructionKind(),
                                               E->getParenOrBraceRange());
@@ -8275,7 +8786,39 @@
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
- 
+   
+  // Transform any init-capture expressions before entering the scope of the 
+  // lambda body, because they are not semantically within that scope.
+  SmallVector<InitCaptureInfoTy, 8> InitCaptureExprsAndTypes;
+  InitCaptureExprsAndTypes.resize(E->explicit_capture_end() -
+      E->explicit_capture_begin());
+  
+  for (LambdaExpr::capture_iterator C = E->capture_begin(),
+      CEnd = E->capture_end();
+      C != CEnd; ++C) {
+    if (!C->isInitCapture())
+      continue;
+    EnterExpressionEvaluationContext  EEEC(getSema(), 
+        Sema::PotentiallyEvaluated);    
+    ExprResult NewExprInitResult = getDerived().TransformInitializer(
+        C->getCapturedVar()->getInit(),
+        C->getCapturedVar()->getInitStyle() == VarDecl::CallInit);
+    
+    if (NewExprInitResult.isInvalid())
+      return ExprError();
+    Expr *NewExprInit = NewExprInitResult.get();
+      
+    VarDecl *OldVD = C->getCapturedVar();
+    QualType NewInitCaptureType = 
+        getSema().performLambdaInitCaptureInitialization(C->getLocation(), 
+            OldVD->getType()->isReferenceType(), OldVD->getIdentifier(), 
+            NewExprInit);
+    NewExprInitResult = NewExprInit;
+    InitCaptureExprsAndTypes[C - E->capture_begin()] =
+        std::make_pair(NewExprInitResult, NewInitCaptureType);
+
+  }
+
   LambdaScopeInfo *LSI = getSema().PushLambdaScope();
   // Transform the template parameters, and add them to the current
   // instantiation scope. The null case is handled correctly.
@@ -8289,8 +8832,8 @@
   TypeSourceInfo *OldCallOpTSI = E->getCallOperator()->getTypeSourceInfo();
   FunctionProtoTypeLoc OldCallOpFPTL = 
       OldCallOpTSI->getTypeLoc().getAs<FunctionProtoTypeLoc>();
-  TypeSourceInfo *NewCallOpTSI = 0;
-  
+  TypeSourceInfo *NewCallOpTSI = nullptr;
+
   const bool CallOpWasAlreadyTransformed = 
       getDerived().AlreadyTransformed(OldCallOpTSI->getType()); 
   
@@ -8306,7 +8849,7 @@
     TypeLocBuilder NewCallOpTLBuilder;
     QualType NewCallOpType = TransformFunctionProtoType(NewCallOpTLBuilder, 
                                                         OldCallOpFPTL, 
-                                                        0, 0);
+                                                        nullptr, 0);
     NewCallOpTSI = NewCallOpTLBuilder.getTypeSourceInfo(getSema().Context,
                                                         NewCallOpType);
   }
@@ -8319,7 +8862,7 @@
     FunctionProtoTypeLoc NewCallOpFPTL = 
         NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>();
     ParmVarDecl **NewParamDeclArray = NewCallOpFPTL.getParmArray();
-    const unsigned NewNumArgs = NewCallOpFPTL.getNumArgs();
+    const unsigned NewNumArgs = NewCallOpFPTL.getNumParams();
 
     for (unsigned I = 0; I < NewNumArgs; ++I) {
       // If this call operator's type does not require transformation, 
@@ -8370,33 +8913,20 @@
 
   getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
 
-  return getDerived().TransformLambdaScope(E, NewCallOperator);
+  return getDerived().TransformLambdaScope(E, NewCallOperator, 
+      InitCaptureExprsAndTypes);
 }
 
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformLambdaScope(LambdaExpr *E,
-                                             CXXMethodDecl *CallOperator) {
+    CXXMethodDecl *CallOperator, 
+    ArrayRef<InitCaptureInfoTy> InitCaptureExprsAndTypes) {
   bool Invalid = false;
 
-  // Transform any init-capture expressions before entering the scope of the
-  // lambda.
-  SmallVector<ExprResult, 8> InitCaptureExprs;
-  InitCaptureExprs.resize(E->explicit_capture_end() -
-                          E->explicit_capture_begin());
-  for (LambdaExpr::capture_iterator C = E->capture_begin(),
-                                 CEnd = E->capture_end();
-       C != CEnd; ++C) {
-    if (!C->isInitCapture())
-      continue;
-    InitCaptureExprs[C - E->capture_begin()] =
-        getDerived().TransformInitializer(
-            C->getCapturedVar()->getInit(),
-            C->getCapturedVar()->getInitStyle() == VarDecl::CallInit);
-  }
-
   // Introduce the context of the call operator.
-  Sema::ContextRAII SavedContext(getSema(), CallOperator);
+  Sema::ContextRAII SavedContext(getSema(), CallOperator,
+                                 /*NewThisContext*/false);
 
   LambdaScopeInfo *const LSI = getSema().getCurLambda();
   // Enter the scope of the lambda.
@@ -8427,19 +8957,24 @@
 
     // Rebuild init-captures, including the implied field declaration.
     if (C->isInitCapture()) {
-      ExprResult Init = InitCaptureExprs[C - E->capture_begin()];
-      if (Init.isInvalid()) {
+      
+      InitCaptureInfoTy InitExprTypePair = 
+          InitCaptureExprsAndTypes[C - E->capture_begin()];
+      ExprResult Init = InitExprTypePair.first;
+      QualType InitQualType = InitExprTypePair.second;
+      if (Init.isInvalid() || InitQualType.isNull()) {
         Invalid = true;
         continue;
       }
       VarDecl *OldVD = C->getCapturedVar();
-      VarDecl *NewVD = getSema().checkInitCapture(
-          C->getLocation(), OldVD->getType()->isReferenceType(),
-          OldVD->getIdentifier(), Init.take());
+      VarDecl *NewVD = getSema().createLambdaInitCaptureVarDecl(
+          OldVD->getLocation(), InitExprTypePair.second, 
+          OldVD->getIdentifier(), Init.get());
       if (!NewVD)
         Invalid = true;
-      else
+      else {
         getDerived().transformedLocalDecl(OldVD, NewVD);
+      }
       getSema().buildInitCaptureField(LSI, NewVD);
       continue;
     }
@@ -8485,6 +9020,9 @@
           // Capture the transformed variable.
           getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);
         }
+
+        // FIXME: Retain a pack expansion if RetainExpansion is true.
+
         continue;
       }
 
@@ -8512,7 +9050,7 @@
   getSema().PushExpressionEvaluationContext(Sema::PotentiallyEvaluated);
 
   if (Invalid) {
-    getSema().ActOnLambdaError(E->getLocStart(), /*CurScope=*/0,
+    getSema().ActOnLambdaError(E->getLocStart(), /*CurScope=*/nullptr,
                                /*IsInstantiation=*/true);
     return ExprError();
   }
@@ -8520,13 +9058,14 @@
   // Instantiate the body of the lambda expression.
   StmtResult Body = getDerived().TransformStmt(E->getBody());
   if (Body.isInvalid()) {
-    getSema().ActOnLambdaError(E->getLocStart(), /*CurScope=*/0,
+    getSema().ActOnLambdaError(E->getLocStart(), /*CurScope=*/nullptr,
                                /*IsInstantiation=*/true);
     return ExprError();
   }
 
-  return getSema().ActOnLambdaExpr(E->getLocStart(), Body.take(),
-                                   /*CurScope=*/0, /*IsInstantiation=*/true);
+  return getSema().ActOnLambdaExpr(E->getLocStart(), Body.get(),
+                                   /*CurScope=*/nullptr,
+                                   /*IsInstantiation=*/true);
 }
 
 template<typename Derived>
@@ -8547,7 +9086,7 @@
   if (!getDerived().AlwaysRebuild() &&
       T == E->getTypeSourceInfo() &&
       !ArgumentChanged)
-    return SemaRef.Owned(E);
+    return E;
 
   // FIXME: we're faking the locations of the commas
   return getDerived().RebuildCXXUnresolvedConstructExpr(T,
@@ -8561,7 +9100,7 @@
 TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
                                              CXXDependentScopeMemberExpr *E) {
   // Transform the base of the expression.
-  ExprResult Base((Expr*) 0);
+  ExprResult Base((Expr*) nullptr);
   Expr *OldBase;
   QualType BaseType;
   QualType ObjectType;
@@ -8574,7 +9113,7 @@
     // Start the member reference and compute the object's type.
     ParsedType ObjectTy;
     bool MayBePseudoDestructor = false;
-    Base = SemaRef.ActOnStartCXXMemberReference(0, Base.get(),
+    Base = SemaRef.ActOnStartCXXMemberReference(nullptr, Base.get(),
                                                 E->getOperatorLoc(),
                                       E->isArrow()? tok::arrow : tok::period,
                                                 ObjectTy,
@@ -8585,7 +9124,7 @@
     ObjectType = ObjectTy.get();
     BaseType = ((Expr*) Base.get())->getType();
   } else {
-    OldBase = 0;
+    OldBase = nullptr;
     BaseType = getDerived().TransformType(E->getBaseType());
     ObjectType = BaseType->getAs<PointerType>()->getPointeeType();
   }
@@ -8627,7 +9166,7 @@
         QualifierLoc == E->getQualifierLoc() &&
         NameInfo.getName() == E->getMember() &&
         FirstQualifierInScope == E->getFirstQualifierFoundInScope())
-      return SemaRef.Owned(E);
+      return E;
 
     return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
                                                        BaseType,
@@ -8637,7 +9176,7 @@
                                                        TemplateKWLoc,
                                                        FirstQualifierInScope,
                                                        NameInfo,
-                                                       /*TemplateArgs*/ 0);
+                                                       /*TemplateArgs*/nullptr);
   }
 
   TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
@@ -8661,13 +9200,13 @@
 ExprResult
 TreeTransform<Derived>::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old) {
   // Transform the base of the expression.
-  ExprResult Base((Expr*) 0);
+  ExprResult Base((Expr*) nullptr);
   QualType BaseType;
   if (!Old->isImplicitAccess()) {
     Base = getDerived().TransformExpr(Old->getBase());
     if (Base.isInvalid())
       return ExprError();
-    Base = getSema().PerformMemberExprBaseConversion(Base.take(),
+    Base = getSema().PerformMemberExprBaseConversion(Base.get(),
                                                      Old->isArrow());
     if (Base.isInvalid())
       return ExprError();
@@ -8709,9 +9248,8 @@
     // Expand using declarations.
     if (isa<UsingDecl>(InstD)) {
       UsingDecl *UD = cast<UsingDecl>(InstD);
-      for (UsingDecl::shadow_iterator I = UD->shadow_begin(),
-             E = UD->shadow_end(); I != E; ++I)
-        R.addDecl(*I);
+      for (auto *I : UD->shadows())
+        R.addDecl(I);
       continue;
     }
 
@@ -8746,7 +9284,7 @@
   // first-qualifier-in-scope here, just in case we had a dependent
   // base (and therefore couldn't do the check) and a
   // nested-name-qualifier (and therefore could do the lookup).
-  NamedDecl *FirstQualifierInScope = 0;
+  NamedDecl *FirstQualifierInScope = nullptr;
 
   return getDerived().RebuildUnresolvedMemberExpr(Base.get(),
                                                   BaseType,
@@ -8757,7 +9295,7 @@
                                                   FirstQualifierInScope,
                                                   R,
                                               (Old->hasExplicitTemplateArgs()
-                                                  ? &TransArgs : 0));
+                                                  ? &TransArgs : nullptr));
 }
 
 template<typename Derived>
@@ -8769,7 +9307,7 @@
     return ExprError();
 
   if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getOperand())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildCXXNoexceptExpr(E->getSourceRange(),SubExpr.get());
 }
@@ -8782,7 +9320,7 @@
     return ExprError();
 
   if (!getDerived().AlwaysRebuild() && Pattern.get() == E->getPattern())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildPackExpansion(Pattern.get(), E->getEllipsisLoc(),
                                            E->getNumExpansions());
@@ -8794,7 +9332,7 @@
   // If E is not value-dependent, then nothing will change when we transform it.
   // Note: This is an instantiation-centric view.
   if (!E->isValueDependent())
-    return SemaRef.Owned(E);
+    return E;
 
   // Note: None of the implementations of TryExpandParameterPacks can ever
   // produce a diagnostic when given only a single unexpanded parameter pack,
@@ -8810,7 +9348,7 @@
     return ExprError();
 
   if (RetainExpansion)
-    return SemaRef.Owned(E);
+    return E;
 
   NamedDecl *Pack = E->getPack();
   if (!ShouldExpand) {
@@ -8833,7 +9371,7 @@
 TreeTransform<Derived>::TransformSubstNonTypeTemplateParmPackExpr(
                                           SubstNonTypeTemplateParmPackExpr *E) {
   // Default behavior is to do nothing with this transformation.
-  return SemaRef.Owned(E);
+  return E;
 }
 
 template<typename Derived>
@@ -8841,14 +9379,14 @@
 TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr(
                                           SubstNonTypeTemplateParmExpr *E) {
   // Default behavior is to do nothing with this transformation.
-  return SemaRef.Owned(E);
+  return E;
 }
 
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
   // Default behavior is to do nothing with this transformation.
-  return SemaRef.Owned(E);
+  return E;
 }
 
 template<typename Derived>
@@ -8874,7 +9412,7 @@
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
-  return SemaRef.Owned(E);
+  return E;
 }
 
 template<typename Derived>
@@ -8886,7 +9424,7 @@
 
   if (!getDerived().AlwaysRebuild() &&
       SubExpr.get() == E->getSubExpr())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildObjCBoxedExpr(E->getSourceRange(), SubExpr.get());
 }
@@ -8989,6 +9527,7 @@
 
         // If any unexpanded parameter packs remain, we still have a
         // pack expansion.
+        // FIXME: Can this really happen?
         if (Key.get()->containsUnexpandedParameterPack() ||
             Value.get()->containsUnexpandedParameterPack())
           Element.EllipsisLoc = OrigElement.EllipsisLoc;
@@ -8996,6 +9535,8 @@
         Elements.push_back(Element);
       }
 
+      // FIXME: Retain a pack expansion if RetainExpansion is true.
+
       // We've finished with this pack expansion.
       continue;
     }
@@ -9041,7 +9582,7 @@
 
   if (!getDerived().AlwaysRebuild() &&
       EncodedTypeInfo == E->getEncodedTypeSourceInfo())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
                                             EncodedTypeInfo,
@@ -9073,7 +9614,7 @@
   if (!getDerived().AlwaysRebuild() &&
       TSInfo == E->getTypeInfoAsWritten() &&
       Result.get() == E->getSubExpr())
-    return SemaRef.Owned(E);
+    return E;
 
   return SemaRef.BuildObjCBridgedCast(E->getLParenLoc(), E->getBridgeKind(),
                                       E->getBridgeKeywordLoc(), TSInfo,
@@ -9143,13 +9684,13 @@
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
-  return SemaRef.Owned(E);
+  return E;
 }
 
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
-  return SemaRef.Owned(E);
+  return E;
 }
 
 template<typename Derived>
@@ -9165,7 +9706,7 @@
   // If nothing changed, just retain the existing expression.
   if (!getDerived().AlwaysRebuild() &&
       Base.get() == E->getBase())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildObjCIvarRefExpr(Base.get(), E->getDecl(),
                                              E->getLocation(),
@@ -9178,7 +9719,7 @@
   // 'super' and types never change. Property never changes. Just
   // retain the existing expression.
   if (!E->isObjectReceiver())
-    return SemaRef.Owned(E);
+    return E;
 
   // Transform the base expression.
   ExprResult Base = getDerived().TransformExpr(E->getBase());
@@ -9190,7 +9731,7 @@
   // If nothing changed, just retain the existing expression.
   if (!getDerived().AlwaysRebuild() &&
       Base.get() == E->getBase())
-    return SemaRef.Owned(E);
+    return E;
 
   if (E->isExplicitProperty())
     return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
@@ -9220,7 +9761,7 @@
   // If nothing changed, just retain the existing expression.
   if (!getDerived().AlwaysRebuild() &&
       Key.get() == E->getKeyExpr() && Base.get() == E->getBaseExpr())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildObjCSubscriptRefExpr(E->getRBracket(),
                                                   Base.get(), Key.get(),
@@ -9239,7 +9780,7 @@
   // If nothing changed, just retain the existing expression.
   if (!getDerived().AlwaysRebuild() &&
       Base.get() == E->getBase())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildObjCIsaExpr(Base.get(), E->getIsaMemberLoc(),
                                          E->getOpLoc(),
@@ -9258,7 +9799,7 @@
 
   if (!getDerived().AlwaysRebuild() &&
       !ArgumentChanged)
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
                                                SubExprs,
@@ -9279,7 +9820,7 @@
   if (!getDerived().AlwaysRebuild() &&
       Type == E->getTypeSourceInfo() &&
       SrcExpr.get() == E->getSrcExpr())
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildConvertVectorExpr(E->getBuiltinLoc(),
                                                SrcExpr.get(), Type,
@@ -9291,7 +9832,7 @@
 TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
   BlockDecl *oldBlock = E->getBlockDecl();
 
-  SemaRef.ActOnBlockStart(E->getCaretLocation(), /*Scope=*/0);
+  SemaRef.ActOnBlockStart(E->getCaretLocation(), /*Scope=*/nullptr);
   BlockScopeInfo *blockScope = SemaRef.getCurBlock();
 
   blockScope->TheDecl->setIsVariadic(oldBlock->isVariadic());
@@ -9305,14 +9846,14 @@
   if (getDerived().TransformFunctionTypeParams(E->getCaretLocation(),
                                                oldBlock->param_begin(),
                                                oldBlock->param_size(),
-                                               0, paramTypes, &params)) {
-    getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/0);
+                                               nullptr, paramTypes, &params)) {
+    getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
     return ExprError();
   }
 
   const FunctionProtoType *exprFunctionType = E->getFunctionType();
   QualType exprResultType =
-      getDerived().TransformType(exprFunctionType->getResultType());
+      getDerived().TransformType(exprFunctionType->getReturnType());
 
   QualType functionType =
     getDerived().RebuildFunctionProtoType(exprResultType, paramTypes,
@@ -9331,7 +9872,7 @@
   // Transform the body
   StmtResult body = getDerived().TransformStmt(E->getBody());
   if (body.isInvalid()) {
-    getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/0);
+    getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
     return ExprError();
   }
 
@@ -9339,9 +9880,8 @@
   // In builds with assertions, make sure that we captured everything we
   // captured before.
   if (!SemaRef.getDiagnostics().hasErrorOccurred()) {
-    for (BlockDecl::capture_iterator i = oldBlock->capture_begin(),
-           e = oldBlock->capture_end(); i != e; ++i) {
-      VarDecl *oldCapture = i->getVariable();
+    for (const auto &I : oldBlock->captures()) {
+      VarDecl *oldCapture = I.getVariable();
 
       // Ignore parameter packs.
       if (isa<ParmVarDecl>(oldCapture) &&
@@ -9358,7 +9898,7 @@
 #endif
 
   return SemaRef.ActOnBlockStmtExpr(E->getCaretLocation(), body.get(),
-                                    /*Scope=*/0);
+                                    /*Scope=*/nullptr);
 }
 
 template<typename Derived>
@@ -9380,7 +9920,7 @@
 
   if (!getDerived().AlwaysRebuild() &&
       !ArgumentChanged)
-    return SemaRef.Owned(E);
+    return E;
 
   return getDerived().RebuildAtomicExpr(E->getBuiltinLoc(), SubExprs,
                                         RetTy, E->getOp(), E->getRParenLoc());
@@ -9418,8 +9958,8 @@
 TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType,
                                                  QualType ClassType,
                                                  SourceLocation Sigil) {
-  return SemaRef.BuildMemberPointerType(PointeeType, ClassType,
-                                        Sigil, getDerived().getBaseEntity());
+  return SemaRef.BuildMemberPointerType(PointeeType, ClassType, Sigil,
+                                        getDerived().getBaseEntity());
 }
 
 template<typename Derived>
@@ -9465,7 +10005,7 @@
                                                  const llvm::APInt &Size,
                                                  unsigned IndexTypeQuals,
                                                  SourceRange BracketsRange) {
-  return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, 0,
+  return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, nullptr,
                                         IndexTypeQuals, BracketsRange);
 }
 
@@ -9475,7 +10015,7 @@
                                           ArrayType::ArraySizeModifier SizeMod,
                                                  unsigned IndexTypeQuals,
                                                    SourceRange BracketsRange) {
-  return getDerived().RebuildArrayType(ElementType, SizeMod, 0, 0,
+  return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr, nullptr,
                                        IndexTypeQuals, BracketsRange);
 }
 
@@ -9486,7 +10026,7 @@
                                                  Expr *SizeExpr,
                                                  unsigned IndexTypeQuals,
                                                  SourceRange BracketsRange) {
-  return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
+  return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
                                        SizeExpr,
                                        IndexTypeQuals, BracketsRange);
 }
@@ -9498,7 +10038,7 @@
                                                        Expr *SizeExpr,
                                                        unsigned IndexTypeQuals,
                                                    SourceRange BracketsRange) {
-  return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
+  return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
                                        SizeExpr,
                                        IndexTypeQuals, BracketsRange);
 }
@@ -9534,7 +10074,7 @@
 template<typename Derived>
 QualType TreeTransform<Derived>::RebuildFunctionProtoType(
     QualType T,
-    llvm::MutableArrayRef<QualType> ParamTypes,
+    MutableArrayRef<QualType> ParamTypes,
     const FunctionProtoType::ExtProtoInfo &EPI) {
   return SemaRef.BuildFunctionType(T, ParamTypes,
                                    getDerived().getBaseLocation(),
@@ -9630,7 +10170,7 @@
   TemplateName.setIdentifier(&Name, NameLoc);
   Sema::TemplateTy Template;
   SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller.
-  getSema().ActOnDependentTemplateName(/*Scope=*/0,
+  getSema().ActOnDependentTemplateName(/*Scope=*/nullptr,
                                        SS, TemplateKWLoc, TemplateName,
                                        ParsedType::make(ObjectType),
                                        /*EnteringContext=*/false,
@@ -9650,7 +10190,7 @@
   Name.setOperatorFunctionId(NameLoc, Operator, SymbolLocations);
   SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller.
   Sema::TemplateTy Template;
-  getSema().ActOnDependentTemplateName(/*Scope=*/0,
+  getSema().ActOnDependentTemplateName(/*Scope=*/nullptr,
                                        SS, TemplateKWLoc, Name,
                                        ParsedType::make(ObjectType),
                                        /*EnteringContext=*/false,
@@ -9668,6 +10208,24 @@
   Expr *Callee = OrigCallee->IgnoreParenCasts();
   bool isPostIncDec = Second && (Op == OO_PlusPlus || Op == OO_MinusMinus);
 
+  if (First->getObjectKind() == OK_ObjCProperty) {
+    BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
+    if (BinaryOperator::isAssignmentOp(Opc))
+      return SemaRef.checkPseudoObjectAssignment(/*Scope=*/nullptr, OpLoc, Opc,
+                                                 First, Second);
+    ExprResult Result = SemaRef.CheckPlaceholderExpr(First);
+    if (Result.isInvalid())
+      return ExprError();
+    First = Result.get();
+  }
+
+  if (Second && Second->getObjectKind() == OK_ObjCProperty) {
+    ExprResult Result = SemaRef.CheckPlaceholderExpr(Second);
+    if (Result.isInvalid())
+      return ExprError();
+    Second = Result.get();
+  }
+
   // Determine whether this should be a builtin operation.
   if (Op == OO_Subscript) {
     if (!First->getType()->isOverloadableType() &&
@@ -9677,8 +10235,8 @@
                                                        Second, OpLoc);
   } else if (Op == OO_Arrow) {
     // -> is never a builtin operation.
-    return SemaRef.BuildOverloadedArrowExpr(0, First, OpLoc);
-  } else if (Second == 0 || isPostIncDec) {
+    return SemaRef.BuildOverloadedArrowExpr(nullptr, First, OpLoc);
+  } else if (Second == nullptr || isPostIncDec) {
     if (!First->getType()->isOverloadableType()) {
       // The argument is not of overloadable type, so try to create a
       // built-in unary operation.
@@ -9708,9 +10266,6 @@
 
   if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Callee)) {
     assert(ULE->requiresADL());
-
-    // FIXME: Do we have to check
-    // IsAcceptableNonMemberOperatorCandidate for each of these?
     Functions.append(ULE->decls_begin(), ULE->decls_end());
   } else {
     // If we've resolved this to a particular non-member function, just call
@@ -9723,7 +10278,7 @@
 
   // Add any functions found via argument-dependent lookup.
   Expr *Args[2] = { First, Second };
-  unsigned NumArgs = 1 + (Second != 0);
+  unsigned NumArgs = 1 + (Second != nullptr);
 
   // Create the overloaded operator invocation for unary operators.
   if (NumArgs == 1 || isPostIncDec) {
@@ -9801,26 +10356,43 @@
   return getSema().BuildMemberReferenceExpr(Base, BaseType,
                                             OperatorLoc, isArrow,
                                             SS, TemplateKWLoc,
-                                            /*FIXME: FirstQualifier*/ 0,
+                                            /*FIXME: FirstQualifier*/ nullptr,
                                             NameInfo,
-                                            /*TemplateArgs*/ 0);
+                                            /*TemplateArgs*/ nullptr);
 }
 
 template<typename Derived>
 StmtResult
 TreeTransform<Derived>::TransformCapturedStmt(CapturedStmt *S) {
   SourceLocation Loc = S->getLocStart();
-  unsigned NumParams = S->getCapturedDecl()->getNumParams();
-  getSema().ActOnCapturedRegionStart(Loc, /*CurScope*/0,
-                                     S->getCapturedRegionKind(), NumParams);
-  StmtResult Body = getDerived().TransformStmt(S->getCapturedStmt());
+  CapturedDecl *CD = S->getCapturedDecl();
+  unsigned NumParams = CD->getNumParams();
+  unsigned ContextParamPos = CD->getContextParamPosition();
+  SmallVector<Sema::CapturedParamNameType, 4> Params;
+  for (unsigned I = 0; I < NumParams; ++I) {
+    if (I != ContextParamPos) {
+      Params.push_back(
+             std::make_pair(
+                  CD->getParam(I)->getName(),
+                  getDerived().TransformType(CD->getParam(I)->getType())));
+    } else {
+      Params.push_back(std::make_pair(StringRef(), QualType()));
+    }
+  }
+  getSema().ActOnCapturedRegionStart(Loc, /*CurScope*/nullptr,
+                                     S->getCapturedRegionKind(), Params);
+  StmtResult Body;
+  {
+    Sema::CompoundScopeRAII CompoundScope(getSema());
+    Body = getDerived().TransformStmt(S->getCapturedStmt());
+  }
 
   if (Body.isInvalid()) {
     getSema().ActOnCapturedRegionError();
     return StmtError();
   }
 
-  return getSema().ActOnCapturedRegionEnd(Body.take());
+  return getSema().ActOnCapturedRegionEnd(Body.get());
 }
 
 } // end namespace clang
diff --git a/lib/Sema/TypeLocBuilder.cpp b/lib/Sema/TypeLocBuilder.cpp
index c7d43b7..be99540 100644
--- a/lib/Sema/TypeLocBuilder.cpp
+++ b/lib/Sema/TypeLocBuilder.cpp
@@ -62,7 +62,7 @@
 
 TypeLoc TypeLocBuilder::pushImpl(QualType T, size_t LocalSize, unsigned LocalAlignment) {
 #ifndef NDEBUG
-  QualType TLast = TypeLoc(T, 0).getNextTypeLoc().getType();
+  QualType TLast = TypeLoc(T, nullptr).getNextTypeLoc().getType();
   assert(TLast == LastTy &&
          "mismatch between last type and new type's inner type");
   LastTy = T;
diff --git a/lib/Sema/TypeLocBuilder.h b/lib/Sema/TypeLocBuilder.h
index b1e9098..c3f874e 100644
--- a/lib/Sema/TypeLocBuilder.h
+++ b/lib/Sema/TypeLocBuilder.h
@@ -94,7 +94,7 @@
   /// Pushes space for a new TypeLoc of the given type.  Invalidates
   /// any TypeLocs previously retrieved from this builder.
   template <class TyLocType> TyLocType push(QualType T) {
-    TyLocType Loc = TypeLoc(T, 0).castAs<TyLocType>();
+    TyLocType Loc = TypeLoc(T, nullptr).castAs<TyLocType>();
     size_t LocalSize = Loc.getLocalDataSize();
     unsigned LocalAlign = Loc.getLocalDataAlignment();
     return pushImpl(T, LocalSize, LocalAlign).castAs<TyLocType>();
diff --git a/lib/Serialization/ASTCommon.cpp b/lib/Serialization/ASTCommon.cpp
index a817687..ad046ff 100644
--- a/lib/Serialization/ASTCommon.cpp
+++ b/lib/Serialization/ASTCommon.cpp
@@ -95,21 +95,21 @@
   case Decl::TranslationUnit:
   case Decl::Namespace:
   case Decl::LinkageSpec:
-    return 0;
+    return nullptr;
 
   // C/C++ tag types can only be defined in one place.
   case Decl::Enum:
   case Decl::Record:
     if (const TagDecl *Def = cast<TagDecl>(DC)->getDefinition())
       return Def;
-    return 0;
+    return nullptr;
 
   // FIXME: These can be defined in one place... except special member
   // functions and out-of-line definitions.
   case Decl::CXXRecord:
   case Decl::ClassTemplateSpecialization:
   case Decl::ClassTemplatePartialSpecialization:
-    return 0;
+    return nullptr;
 
   // Each function, method, and block declaration is its own DeclContext.
   case Decl::Function:
@@ -131,14 +131,14 @@
     if (const ObjCProtocolDecl *Def
           = cast<ObjCProtocolDecl>(DC)->getDefinition())
       return Def;
-    return 0;
+    return nullptr;
 
   // FIXME: These are defined in one place, but properties in class extensions
   // end up being back-patched into the main interface. See
   // Sema::HandlePropertyInClassExtension for the offending code.
   case Decl::ObjCInterface:
-    return 0;
-    
+    return nullptr;
+
   default:
     llvm_unreachable("Unhandled DeclContext in AST reader");
   }
diff --git a/lib/Serialization/ASTCommon.h b/lib/Serialization/ASTCommon.h
index ef81e69..c766974 100644
--- a/lib/Serialization/ASTCommon.h
+++ b/lib/Serialization/ASTCommon.h
@@ -26,8 +26,13 @@
   UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION,
   UPD_CXX_ADDED_ANONYMOUS_NAMESPACE,
   UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER,
+  UPD_CXX_INSTANTIATED_FUNCTION_DEFINITION,
+  UPD_CXX_INSTANTIATED_CLASS_DEFINITION,
+  UPD_CXX_RESOLVED_EXCEPTION_SPEC,
   UPD_CXX_DEDUCED_RETURN_TYPE,
-  UPD_DECL_MARKED_USED
+  UPD_DECL_MARKED_USED,
+  UPD_MANGLING_NUMBER,
+  UPD_STATIC_LOCAL_NUMBER
 };
 
 TypeIdx TypeIdxFromBuiltin(const BuiltinType *BT);
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 4d1b4b9..ae41654 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -22,6 +22,7 @@
 #include "clang/AST/NestedNameSpecifier.h"
 #include "clang/AST/Type.h"
 #include "clang/AST/TypeLocVisitor.h"
+#include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/SourceManagerInternals.h"
@@ -29,6 +30,7 @@
 #include "clang/Basic/TargetOptions.h"
 #include "clang/Basic/Version.h"
 #include "clang/Basic/VersionTuple.h"
+#include "clang/Frontend/Utils.h"
 #include "clang/Lex/HeaderSearch.h"
 #include "clang/Lex/HeaderSearchOptions.h"
 #include "clang/Lex/MacroInfo.h"
@@ -49,16 +51,100 @@
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/SaveAndRestore.h"
-#include "llvm/Support/system_error.h"
+#include "llvm/Support/raw_ostream.h"
 #include <algorithm>
 #include <cstdio>
 #include <iterator>
+#include <system_error>
 
 using namespace clang;
 using namespace clang::serialization;
 using namespace clang::serialization::reader;
 using llvm::BitstreamCursor;
 
+
+//===----------------------------------------------------------------------===//
+// ChainedASTReaderListener implementation
+//===----------------------------------------------------------------------===//
+
+bool
+ChainedASTReaderListener::ReadFullVersionInformation(StringRef FullVersion) {
+  return First->ReadFullVersionInformation(FullVersion) ||
+         Second->ReadFullVersionInformation(FullVersion);
+}
+void ChainedASTReaderListener::ReadModuleName(StringRef ModuleName) {
+  First->ReadModuleName(ModuleName);
+  Second->ReadModuleName(ModuleName);
+}
+void ChainedASTReaderListener::ReadModuleMapFile(StringRef ModuleMapPath) {
+  First->ReadModuleMapFile(ModuleMapPath);
+  Second->ReadModuleMapFile(ModuleMapPath);
+}
+bool ChainedASTReaderListener::ReadLanguageOptions(const LangOptions &LangOpts,
+                                                   bool Complain) {
+  return First->ReadLanguageOptions(LangOpts, Complain) ||
+         Second->ReadLanguageOptions(LangOpts, Complain);
+}
+bool
+ChainedASTReaderListener::ReadTargetOptions(const TargetOptions &TargetOpts,
+                                            bool Complain) {
+  return First->ReadTargetOptions(TargetOpts, Complain) ||
+         Second->ReadTargetOptions(TargetOpts, Complain);
+}
+bool ChainedASTReaderListener::ReadDiagnosticOptions(
+    IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts, bool Complain) {
+  return First->ReadDiagnosticOptions(DiagOpts, Complain) ||
+         Second->ReadDiagnosticOptions(DiagOpts, Complain);
+}
+bool
+ChainedASTReaderListener::ReadFileSystemOptions(const FileSystemOptions &FSOpts,
+                                                bool Complain) {
+  return First->ReadFileSystemOptions(FSOpts, Complain) ||
+         Second->ReadFileSystemOptions(FSOpts, Complain);
+}
+
+bool ChainedASTReaderListener::ReadHeaderSearchOptions(
+    const HeaderSearchOptions &HSOpts, bool Complain) {
+  return First->ReadHeaderSearchOptions(HSOpts, Complain) ||
+         Second->ReadHeaderSearchOptions(HSOpts, Complain);
+}
+bool ChainedASTReaderListener::ReadPreprocessorOptions(
+    const PreprocessorOptions &PPOpts, bool Complain,
+    std::string &SuggestedPredefines) {
+  return First->ReadPreprocessorOptions(PPOpts, Complain,
+                                        SuggestedPredefines) ||
+         Second->ReadPreprocessorOptions(PPOpts, Complain, SuggestedPredefines);
+}
+void ChainedASTReaderListener::ReadCounter(const serialization::ModuleFile &M,
+                                           unsigned Value) {
+  First->ReadCounter(M, Value);
+  Second->ReadCounter(M, Value);
+}
+bool ChainedASTReaderListener::needsInputFileVisitation() {
+  return First->needsInputFileVisitation() ||
+         Second->needsInputFileVisitation();
+}
+bool ChainedASTReaderListener::needsSystemInputFileVisitation() {
+  return First->needsSystemInputFileVisitation() ||
+  Second->needsSystemInputFileVisitation();
+}
+void ChainedASTReaderListener::visitModuleFile(StringRef Filename) {
+  First->visitModuleFile(Filename);
+  Second->visitModuleFile(Filename);
+}
+bool ChainedASTReaderListener::visitInputFile(StringRef Filename,
+                                              bool isSystem,
+                                              bool isOverridden) {
+  bool Continue = false;
+  if (First->needsInputFileVisitation() &&
+      (!isSystem || First->needsSystemInputFileVisitation()))
+    Continue |= First->visitInputFile(Filename, isSystem, isOverridden);
+  if (Second->needsInputFileVisitation() &&
+      (!isSystem || Second->needsSystemInputFileVisitation()))
+    Continue |= Second->visitInputFile(Filename, isSystem, isOverridden);
+  return Continue;
+}
+
 //===----------------------------------------------------------------------===//
 // PCH validator implementation
 //===----------------------------------------------------------------------===//
@@ -140,8 +226,6 @@
   CHECK_TARGET_OPT(Triple, "target");
   CHECK_TARGET_OPT(CPU, "target CPU");
   CHECK_TARGET_OPT(ABI, "target ABI");
-  CHECK_TARGET_OPT(CXXABI, "target C++ ABI");
-  CHECK_TARGET_OPT(LinkerVersion, "target linker version");
 #undef CHECK_TARGET_OPT
 
   // Compare feature sets.
@@ -197,14 +281,14 @@
                                   bool Complain) {
   const LangOptions &ExistingLangOpts = PP.getLangOpts();
   return checkLanguageOptions(LangOpts, ExistingLangOpts,
-                              Complain? &Reader.Diags : 0);
+                              Complain? &Reader.Diags : nullptr);
 }
 
 bool PCHValidator::ReadTargetOptions(const TargetOptions &TargetOpts,
                                      bool Complain) {
   const TargetOptions &ExistingTargetOpts = PP.getTargetInfo().getTargetOpts();
   return checkTargetOptions(TargetOpts, ExistingTargetOpts,
-                            Complain? &Reader.Diags : 0);
+                            Complain? &Reader.Diags : nullptr);
 }
 
 namespace {
@@ -214,11 +298,124 @@
     DeclsMap;
 }
 
+static bool checkDiagnosticGroupMappings(DiagnosticsEngine &StoredDiags,
+                                         DiagnosticsEngine &Diags,
+                                         bool Complain) {
+  typedef DiagnosticsEngine::Level Level;
+
+  // Check current mappings for new -Werror mappings, and the stored mappings
+  // for cases that were explicitly mapped to *not* be errors that are now
+  // errors because of options like -Werror.
+  DiagnosticsEngine *MappingSources[] = { &Diags, &StoredDiags };
+
+  for (DiagnosticsEngine *MappingSource : MappingSources) {
+    for (auto DiagIDMappingPair : MappingSource->getDiagnosticMappings()) {
+      diag::kind DiagID = DiagIDMappingPair.first;
+      Level CurLevel = Diags.getDiagnosticLevel(DiagID, SourceLocation());
+      if (CurLevel < DiagnosticsEngine::Error)
+        continue; // not significant
+      Level StoredLevel =
+          StoredDiags.getDiagnosticLevel(DiagID, SourceLocation());
+      if (StoredLevel < DiagnosticsEngine::Error) {
+        if (Complain)
+          Diags.Report(diag::err_pch_diagopt_mismatch) << "-Werror=" +
+              Diags.getDiagnosticIDs()->getWarningOptionForDiag(DiagID).str();
+        return true;
+      }
+    }
+  }
+
+  return false;
+}
+
+static bool isExtHandlingFromDiagsError(DiagnosticsEngine &Diags) {
+  diag::Severity Ext = Diags.getExtensionHandlingBehavior();
+  if (Ext == diag::Severity::Warning && Diags.getWarningsAsErrors())
+    return true;
+  return Ext >= diag::Severity::Error;
+}
+
+static bool checkDiagnosticMappings(DiagnosticsEngine &StoredDiags,
+                                    DiagnosticsEngine &Diags,
+                                    bool IsSystem, bool Complain) {
+  // Top-level options
+  if (IsSystem) {
+    if (Diags.getSuppressSystemWarnings())
+      return false;
+    // If -Wsystem-headers was not enabled before, be conservative
+    if (StoredDiags.getSuppressSystemWarnings()) {
+      if (Complain)
+        Diags.Report(diag::err_pch_diagopt_mismatch) << "-Wsystem-headers";
+      return true;
+    }
+  }
+
+  if (Diags.getWarningsAsErrors() && !StoredDiags.getWarningsAsErrors()) {
+    if (Complain)
+      Diags.Report(diag::err_pch_diagopt_mismatch) << "-Werror";
+    return true;
+  }
+
+  if (Diags.getWarningsAsErrors() && Diags.getEnableAllWarnings() &&
+      !StoredDiags.getEnableAllWarnings()) {
+    if (Complain)
+      Diags.Report(diag::err_pch_diagopt_mismatch) << "-Weverything -Werror";
+    return true;
+  }
+
+  if (isExtHandlingFromDiagsError(Diags) &&
+      !isExtHandlingFromDiagsError(StoredDiags)) {
+    if (Complain)
+      Diags.Report(diag::err_pch_diagopt_mismatch) << "-pedantic-errors";
+    return true;
+  }
+
+  return checkDiagnosticGroupMappings(StoredDiags, Diags, Complain);
+}
+
+bool PCHValidator::ReadDiagnosticOptions(
+    IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts, bool Complain) {
+  DiagnosticsEngine &ExistingDiags = PP.getDiagnostics();
+  IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(ExistingDiags.getDiagnosticIDs());
+  IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
+      new DiagnosticsEngine(DiagIDs, DiagOpts.get()));
+  // This should never fail, because we would have processed these options
+  // before writing them to an ASTFile.
+  ProcessWarningOptions(*Diags, *DiagOpts, /*Report*/false);
+
+  ModuleManager &ModuleMgr = Reader.getModuleManager();
+  assert(ModuleMgr.size() >= 1 && "what ASTFile is this then");
+
+  // If the original import came from a file explicitly generated by the user,
+  // don't check the diagnostic mappings.
+  // FIXME: currently this is approximated by checking whether this is not a
+  // module import.
+  // Note: ModuleMgr.rbegin() may not be the current module, but it must be in
+  // the transitive closure of its imports, since unrelated modules cannot be
+  // imported until after this module finishes validation.
+  ModuleFile *TopImport = *ModuleMgr.rbegin();
+  while (!TopImport->ImportedBy.empty())
+    TopImport = TopImport->ImportedBy[0];
+  if (TopImport->Kind != MK_Module)
+    return false;
+
+  StringRef ModuleName = TopImport->ModuleName;
+  assert(!ModuleName.empty() && "diagnostic options read before module name");
+
+  Module *M = PP.getHeaderSearchInfo().lookupModule(ModuleName);
+  assert(M && "missing module");
+
+  // FIXME: if the diagnostics are incompatible, save a DiagnosticOptions that
+  // contains the union of their flags.
+  return checkDiagnosticMappings(*Diags, ExistingDiags, M->IsSystem, Complain);
+}
+
 /// \brief Collect the macro definitions provided by the given preprocessor
 /// options.
-static void collectMacroDefinitions(const PreprocessorOptions &PPOpts,
-                                    MacroDefinitionsMap &Macros,
-                                    SmallVectorImpl<StringRef> *MacroNames = 0){
+static void
+collectMacroDefinitions(const PreprocessorOptions &PPOpts,
+                        MacroDefinitionsMap &Macros,
+                        SmallVectorImpl<StringRef> *MacroNames = nullptr) {
   for (unsigned I = 0, N = PPOpts.Macros.size(); I != N; ++I) {
     StringRef Macro = PPOpts.Macros[I].first;
     bool IsUndef = PPOpts.Macros[I].second;
@@ -373,7 +570,7 @@
   const PreprocessorOptions &ExistingPPOpts = PP.getPreprocessorOpts();
 
   return checkPreprocessorOptions(PPOpts, ExistingPPOpts,
-                                  Complain? &Reader.Diags : 0,
+                                  Complain? &Reader.Diags : nullptr,
                                   PP.getFileManager(),
                                   SuggestedPredefines,
                                   PP.getLangOpts());
@@ -387,9 +584,10 @@
 // AST reader implementation
 //===----------------------------------------------------------------------===//
 
-void
-ASTReader::setDeserializationListener(ASTDeserializationListener *Listener) {
+void ASTReader::setDeserializationListener(ASTDeserializationListener *Listener,
+                                           bool TakeOwnership) {
   DeserializationListener = Listener;
+  OwnsDeserializationListener = TakeOwnership;
 }
 
 
@@ -401,19 +599,19 @@
 
 std::pair<unsigned, unsigned>
 ASTSelectorLookupTrait::ReadKeyDataLength(const unsigned char*& d) {
-  using namespace clang::io;
-  unsigned KeyLen = ReadUnalignedLE16(d);
-  unsigned DataLen = ReadUnalignedLE16(d);
+  using namespace llvm::support;
+  unsigned KeyLen = endian::readNext<uint16_t, little, unaligned>(d);
+  unsigned DataLen = endian::readNext<uint16_t, little, unaligned>(d);
   return std::make_pair(KeyLen, DataLen);
 }
 
 ASTSelectorLookupTrait::internal_key_type 
 ASTSelectorLookupTrait::ReadKey(const unsigned char* d, unsigned) {
-  using namespace clang::io;
+  using namespace llvm::support;
   SelectorTable &SelTable = Reader.getContext().Selectors;
-  unsigned N = ReadUnalignedLE16(d);
-  IdentifierInfo *FirstII
-    = Reader.getLocalIdentifier(F, ReadUnalignedLE32(d));
+  unsigned N = endian::readNext<uint16_t, little, unaligned>(d);
+  IdentifierInfo *FirstII = Reader.getLocalIdentifier(
+      F, endian::readNext<uint32_t, little, unaligned>(d));
   if (N == 0)
     return SelTable.getNullarySelector(FirstII);
   else if (N == 1)
@@ -422,7 +620,8 @@
   SmallVector<IdentifierInfo *, 16> Args;
   Args.push_back(FirstII);
   for (unsigned I = 1; I != N; ++I)
-    Args.push_back(Reader.getLocalIdentifier(F, ReadUnalignedLE32(d)));
+    Args.push_back(Reader.getLocalIdentifier(
+        F, endian::readNext<uint32_t, little, unaligned>(d)));
 
   return SelTable.getSelector(N, Args.data());
 }
@@ -430,13 +629,16 @@
 ASTSelectorLookupTrait::data_type 
 ASTSelectorLookupTrait::ReadData(Selector, const unsigned char* d, 
                                  unsigned DataLen) {
-  using namespace clang::io;
+  using namespace llvm::support;
 
   data_type Result;
 
-  Result.ID = Reader.getGlobalSelectorID(F, ReadUnalignedLE32(d));
-  unsigned NumInstanceMethodsAndBits = ReadUnalignedLE16(d);
-  unsigned NumFactoryMethodsAndBits = ReadUnalignedLE16(d);
+  Result.ID = Reader.getGlobalSelectorID(
+      F, endian::readNext<uint32_t, little, unaligned>(d));
+  unsigned NumInstanceMethodsAndBits =
+      endian::readNext<uint16_t, little, unaligned>(d);
+  unsigned NumFactoryMethodsAndBits =
+      endian::readNext<uint16_t, little, unaligned>(d);
   Result.InstanceBits = NumInstanceMethodsAndBits & 0x3;
   Result.FactoryBits = NumFactoryMethodsAndBits & 0x3;
   unsigned NumInstanceMethods = NumInstanceMethodsAndBits >> 2;
@@ -444,15 +646,15 @@
 
   // Load instance methods
   for (unsigned I = 0; I != NumInstanceMethods; ++I) {
-    if (ObjCMethodDecl *Method
-          = Reader.GetLocalDeclAs<ObjCMethodDecl>(F, ReadUnalignedLE32(d)))
+    if (ObjCMethodDecl *Method = Reader.GetLocalDeclAs<ObjCMethodDecl>(
+            F, endian::readNext<uint32_t, little, unaligned>(d)))
       Result.Instance.push_back(Method);
   }
 
   // Load factory methods
   for (unsigned I = 0; I != NumFactoryMethods; ++I) {
-    if (ObjCMethodDecl *Method
-          = Reader.GetLocalDeclAs<ObjCMethodDecl>(F, ReadUnalignedLE32(d)))
+    if (ObjCMethodDecl *Method = Reader.GetLocalDeclAs<ObjCMethodDecl>(
+            F, endian::readNext<uint32_t, little, unaligned>(d)))
       Result.Factory.push_back(Method);
   }
 
@@ -465,9 +667,9 @@
 
 std::pair<unsigned, unsigned>
 ASTIdentifierLookupTraitBase::ReadKeyDataLength(const unsigned char*& d) {
-  using namespace clang::io;
-  unsigned DataLen = ReadUnalignedLE16(d);
-  unsigned KeyLen = ReadUnalignedLE16(d);
+  using namespace llvm::support;
+  unsigned DataLen = endian::readNext<uint16_t, little, unaligned>(d);
+  unsigned KeyLen = endian::readNext<uint16_t, little, unaligned>(d);
   return std::make_pair(KeyLen, DataLen);
 }
 
@@ -490,8 +692,8 @@
 IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k,
                                                    const unsigned char* d,
                                                    unsigned DataLen) {
-  using namespace clang::io;
-  unsigned RawID = ReadUnalignedLE32(d);
+  using namespace llvm::support;
+  unsigned RawID = endian::readNext<uint32_t, little, unaligned>(d);
   bool IsInteresting = RawID & 0x01;
 
   // Wipe out the "is interesting" bit.
@@ -517,8 +719,8 @@
     return II;
   }
 
-  unsigned ObjCOrBuiltinID = ReadUnalignedLE16(d);
-  unsigned Bits = ReadUnalignedLE16(d);
+  unsigned ObjCOrBuiltinID = endian::readNext<uint16_t, little, unaligned>(d);
+  unsigned Bits = endian::readNext<uint16_t, little, unaligned>(d);
   bool CPlusPlusOperatorKeyword = Bits & 0x01;
   Bits >>= 1;
   bool HasRevertedTokenIDToIdentifier = Bits & 0x01;
@@ -567,11 +769,13 @@
   // If this identifier is a macro, deserialize the macro
   // definition.
   if (hadMacroDefinition) {
-    uint32_t MacroDirectivesOffset = ReadUnalignedLE32(d);
+    uint32_t MacroDirectivesOffset =
+        endian::readNext<uint32_t, little, unaligned>(d);
     DataLen -= 4;
     SmallVector<uint32_t, 8> LocalMacroIDs;
     if (hasSubmoduleMacros) {
-      while (uint32_t LocalMacroID = ReadUnalignedLE32(d)) {
+      while (uint32_t LocalMacroID =
+                 endian::readNext<uint32_t, little, unaligned>(d)) {
         DataLen -= 4;
         LocalMacroIDs.push_back(LocalMacroID);
       }
@@ -579,11 +783,34 @@
     }
 
     if (F.Kind == MK_Module) {
+      // Macro definitions are stored from newest to oldest, so reverse them
+      // before registering them.
+      llvm::SmallVector<unsigned, 8> MacroSizes;
       for (SmallVectorImpl<uint32_t>::iterator
-             I = LocalMacroIDs.begin(), E = LocalMacroIDs.end(); I != E; ++I) {
-        MacroID MacID = Reader.getGlobalMacroID(F, *I);
-        Reader.addPendingMacroFromModule(II, &F, MacID, F.DirectImportLoc);
+             I = LocalMacroIDs.begin(), E = LocalMacroIDs.end(); I != E; /**/) {
+        unsigned Size = 1;
+
+        static const uint32_t HasOverridesFlag = 0x80000000U;
+        if (I + 1 != E && (I[1] & HasOverridesFlag))
+          Size += 1 + (I[1] & ~HasOverridesFlag);
+
+        MacroSizes.push_back(Size);
+        I += Size;
       }
+
+      SmallVectorImpl<uint32_t>::iterator I = LocalMacroIDs.end();
+      for (SmallVectorImpl<unsigned>::reverse_iterator SI = MacroSizes.rbegin(),
+                                                       SE = MacroSizes.rend();
+           SI != SE; ++SI) {
+        I -= *SI;
+
+        uint32_t LocalMacroID = *I;
+        ArrayRef<uint32_t> Overrides;
+        if (*SI != 1)
+          Overrides = llvm::makeArrayRef(&I[2], *SI - 2);
+        Reader.addPendingMacroFromModule(II, &F, LocalMacroID, Overrides);
+      }
+      assert(I == LocalMacroIDs.begin());
     } else {
       Reader.addPendingMacroFromPCH(II, &F, MacroDirectivesOffset);
     }
@@ -596,7 +823,8 @@
   if (DataLen > 0) {
     SmallVector<uint32_t, 4> DeclIDs;
     for (; DataLen > 0; DataLen -= 4)
-      DeclIDs.push_back(Reader.getGlobalDeclID(F, ReadUnalignedLE32(d)));
+      DeclIDs.push_back(Reader.getGlobalDeclID(
+          F, endian::readNext<uint32_t, little, unaligned>(d)));
     Reader.SetGloballyVisibleDecls(II, DeclIDs);
   }
 
@@ -664,34 +892,37 @@
 
 std::pair<unsigned, unsigned>
 ASTDeclContextNameLookupTrait::ReadKeyDataLength(const unsigned char*& d) {
-  using namespace clang::io;
-  unsigned KeyLen = ReadUnalignedLE16(d);
-  unsigned DataLen = ReadUnalignedLE16(d);
+  using namespace llvm::support;
+  unsigned KeyLen = endian::readNext<uint16_t, little, unaligned>(d);
+  unsigned DataLen = endian::readNext<uint16_t, little, unaligned>(d);
   return std::make_pair(KeyLen, DataLen);
 }
 
 ASTDeclContextNameLookupTrait::internal_key_type 
 ASTDeclContextNameLookupTrait::ReadKey(const unsigned char* d, unsigned) {
-  using namespace clang::io;
+  using namespace llvm::support;
 
   DeclNameKey Key;
   Key.Kind = (DeclarationName::NameKind)*d++;
   switch (Key.Kind) {
   case DeclarationName::Identifier:
-    Key.Data = (uint64_t)Reader.getLocalIdentifier(F, ReadUnalignedLE32(d));
+    Key.Data = (uint64_t)Reader.getLocalIdentifier(
+        F, endian::readNext<uint32_t, little, unaligned>(d));
     break;
   case DeclarationName::ObjCZeroArgSelector:
   case DeclarationName::ObjCOneArgSelector:
   case DeclarationName::ObjCMultiArgSelector:
     Key.Data =
-       (uint64_t)Reader.getLocalSelector(F, ReadUnalignedLE32(d))
-                   .getAsOpaquePtr();
+        (uint64_t)Reader.getLocalSelector(
+                             F, endian::readNext<uint32_t, little, unaligned>(
+                                    d)).getAsOpaquePtr();
     break;
   case DeclarationName::CXXOperatorName:
     Key.Data = *d++; // OverloadedOperatorKind
     break;
   case DeclarationName::CXXLiteralOperatorName:
-    Key.Data = (uint64_t)Reader.getLocalIdentifier(F, ReadUnalignedLE32(d));
+    Key.Data = (uint64_t)Reader.getLocalIdentifier(
+        F, endian::readNext<uint32_t, little, unaligned>(d));
     break;
   case DeclarationName::CXXConstructorName:
   case DeclarationName::CXXDestructorName:
@@ -708,8 +939,8 @@
 ASTDeclContextNameLookupTrait::ReadData(internal_key_type, 
                                         const unsigned char* d,
                                         unsigned DataLen) {
-  using namespace clang::io;
-  unsigned NumDecls = ReadUnalignedLE16(d);
+  using namespace llvm::support;
+  unsigned NumDecls = endian::readNext<uint16_t, little, unaligned>(d);
   LE32DeclID *Start = reinterpret_cast<LE32DeclID *>(
                         const_cast<unsigned char *>(d));
   return std::make_pair(Start, Start + NumDecls);
@@ -749,11 +980,11 @@
       Error("Expected visible lookup table block");
       return true;
     }
-    Info.NameLookupTableData
-      = ASTDeclContextNameLookupTable::Create(
-                    (const unsigned char *)Blob.data() + Record[0],
-                    (const unsigned char *)Blob.data(),
-                    ASTDeclContextNameLookupTrait(*this, M));
+    Info.NameLookupTableData = ASTDeclContextNameLookupTable::Create(
+        (const unsigned char *)Blob.data() + Record[0],
+        (const unsigned char *)Blob.data() + sizeof(uint32_t),
+        (const unsigned char *)Blob.data(),
+        ASTDeclContextNameLookupTrait(*this, M));
   }
 
   return false;
@@ -1023,8 +1254,8 @@
 
     llvm::MemoryBuffer *Buffer
       = llvm::MemoryBuffer::getMemBuffer(Blob.drop_back(1), Name);
-    SourceMgr.createFileIDForMemBuffer(Buffer, FileCharacter, ID,
-                                       BaseOffset + Offset, IncludeLoc);
+    SourceMgr.createFileID(Buffer, FileCharacter, ID, BaseOffset + Offset,
+                           IncludeLoc);
     break;
   }
 
@@ -1059,7 +1290,7 @@
 
   // FIXME: Can we map this down to a particular submodule? That would be
   // ideal.
-  return std::make_pair(M->ImportLoc, llvm::sys::path::stem(M->FileName));
+  return std::make_pair(M->ImportLoc, StringRef(M->ModuleName));
 }
 
 /// \brief Find the location where the module F is imported.
@@ -1070,14 +1301,10 @@
   // 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]) {
-    // Main file is the importer. We assume that it is the first entry in the
-    // entry table. We can't ask the manager, because at the time of PCH loading
-    // the main file entry doesn't exist yet.
-    // The very first entry is the invalid instantiation loc, which takes up
-    // offsets 0 and 1.
-    return SourceLocation::getFromRawEncoding(2U);
+    // Main file is the importer.
+    assert(!SourceMgr.getMainFileID().isInvalid() && "missing main file");
+    return SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
   }
-  //return F->Loaders[0]->FirstLoc;
   return F->ImportedBy[0]->FirstLoc;
 }
 
@@ -1126,7 +1353,7 @@
   Stream.JumpToBit(Offset);
   RecordData Record;
   SmallVector<IdentifierInfo*, 16> MacroArgs;
-  MacroInfo *Macro = 0;
+  MacroInfo *Macro = nullptr;
 
   while (true) {
     // Advance to the next record, but if we get to the end of the block, don't
@@ -1169,6 +1396,7 @@
       MacroInfo *MI = PP.AllocateDeserializedMacroInfo(Loc, SubModID);
       MI->setDefinitionEndLoc(ReadSourceLocation(F, Record, NextIndex));
       MI->setIsUsed(Record[NextIndex++]);
+      MI->setUsedForHeaderGuard(Record[NextIndex++]);
 
       if (RecType == PP_MACRO_FUNCTION_LIKE) {
         // Decode function-like macro info.
@@ -1214,7 +1442,7 @@
     case PP_TOKEN: {
       // If we see a TOKEN before a PP_MACRO_*, then the file is
       // erroneous, just pretend we didn't see this.
-      if (Macro == 0) break;
+      if (!Macro) break;
 
       unsigned Idx = 0;
       Token Tok = ReadToken(F, Record, Idx);
@@ -1262,16 +1490,18 @@
     
 std::pair<unsigned, unsigned>
 HeaderFileInfoTrait::ReadKeyDataLength(const unsigned char*& d) {
-  unsigned KeyLen = (unsigned) clang::io::ReadUnalignedLE16(d);
+  using namespace llvm::support;
+  unsigned KeyLen = (unsigned) endian::readNext<uint16_t, little, unaligned>(d);
   unsigned DataLen = (unsigned) *d++;
   return std::make_pair(KeyLen, DataLen);
 }
 
 HeaderFileInfoTrait::internal_key_type
 HeaderFileInfoTrait::ReadKey(const unsigned char *d, unsigned) {
+  using namespace llvm::support;
   internal_key_type ikey;
-  ikey.Size = off_t(clang::io::ReadUnalignedLE64(d));
-  ikey.ModTime = time_t(clang::io::ReadUnalignedLE64(d));
+  ikey.Size = off_t(endian::readNext<uint64_t, little, unaligned>(d));
+  ikey.ModTime = time_t(endian::readNext<uint64_t, little, unaligned>(d));
   ikey.Filename = (const char *)d;
   return ikey;
 }
@@ -1280,7 +1510,7 @@
 HeaderFileInfoTrait::ReadData(internal_key_ref key, const unsigned char *d,
                               unsigned DataLen) {
   const unsigned char *End = d + DataLen;
-  using namespace clang::io;
+  using namespace llvm::support;
   HeaderFileInfo HFI;
   unsigned Flags = *d++;
   HFI.HeaderRole = static_cast<ModuleMap::ModuleHeaderRole>
@@ -1290,10 +1520,11 @@
   HFI.DirInfo = (Flags >> 2) & 0x03;
   HFI.Resolved = (Flags >> 1) & 0x01;
   HFI.IndexHeaderMapHeader = Flags & 0x01;
-  HFI.NumIncludes = ReadUnalignedLE16(d);
-  HFI.ControllingMacroID = Reader.getGlobalIdentifierID(M, 
-                                                        ReadUnalignedLE32(d));
-  if (unsigned FrameworkOffset = ReadUnalignedLE32(d)) {
+  HFI.NumIncludes = endian::readNext<uint16_t, little, unaligned>(d);
+  HFI.ControllingMacroID = Reader.getGlobalIdentifierID(
+      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, 
     // since 0 is used as an indicator for "no framework name".
     StringRef FrameworkName(FrameworkStrings + FrameworkOffset - 1);
@@ -1301,7 +1532,7 @@
   }
   
   if (d != End) {
-    uint32_t LocalSMID = ReadUnalignedLE32(d);
+    uint32_t LocalSMID = endian::readNext<uint32_t, little, unaligned>(d);
     if (LocalSMID) {
       // This header is part of a module. Associate it with the module to enable
       // implicit module import.
@@ -1323,12 +1554,19 @@
   return HFI;
 }
 
-void ASTReader::addPendingMacroFromModule(IdentifierInfo *II,
-                                          ModuleFile *M,
-                                          GlobalMacroID GMacID,
-                                          SourceLocation ImportLoc) {
+void
+ASTReader::addPendingMacroFromModule(IdentifierInfo *II, ModuleFile *M,
+                                     GlobalMacroID GMacID,
+                                     ArrayRef<SubmoduleID> Overrides) {
   assert(NumCurrentElementsDeserializing > 0 &&"Missing deserialization guard");
-  PendingMacroIDs[II].push_back(PendingMacroInfo(M, GMacID, ImportLoc));
+  SubmoduleID *OverrideData = nullptr;
+  if (!Overrides.empty()) {
+    OverrideData = new (Context) SubmoduleID[Overrides.size() + 1];
+    OverrideData[0] = Overrides.size();
+    for (unsigned I = 0; I != Overrides.size(); ++I)
+      OverrideData[I + 1] = getGlobalSubmoduleID(*M, Overrides[I]);
+  }
+  PendingMacroIDs[II].push_back(PendingMacroInfo(M, GMacID, OverrideData));
 }
 
 void ASTReader::addPendingMacroFromPCH(IdentifierInfo *II,
@@ -1452,7 +1690,7 @@
   // If there is a global index, look there first to determine which modules
   // provably do not have any results for this identifier.
   GlobalModuleIndex::HitSet Hits;
-  GlobalModuleIndex::HitSet *HitsPtr = 0;
+  GlobalModuleIndex::HitSet *HitsPtr = nullptr;
   if (!loadGlobalIndex()) {
     if (GlobalIndex->lookupIdentifier(II.getName(), Hits)) {
       HitsPtr = &Hits;
@@ -1474,7 +1712,60 @@
 
   // Update the generation for this identifier.
   if (getContext().getLangOpts().Modules)
-    IdentifierGeneration[II] = CurrentGeneration;
+    IdentifierGeneration[II] = getGeneration();
+}
+
+struct ASTReader::ModuleMacroInfo {
+  SubmoduleID SubModID;
+  MacroInfo *MI;
+  SubmoduleID *Overrides;
+  // FIXME: Remove this.
+  ModuleFile *F;
+
+  bool isDefine() const { return MI; }
+
+  SubmoduleID getSubmoduleID() const { return SubModID; }
+
+  ArrayRef<SubmoduleID> getOverriddenSubmodules() const {
+    if (!Overrides)
+      return None;
+    return llvm::makeArrayRef(Overrides + 1, *Overrides);
+  }
+
+  DefMacroDirective *import(Preprocessor &PP, SourceLocation ImportLoc) const {
+    if (!MI)
+      return nullptr;
+    return PP.AllocateDefMacroDirective(MI, ImportLoc, /*isImported=*/true);
+  }
+};
+
+ASTReader::ModuleMacroInfo *
+ASTReader::getModuleMacro(const PendingMacroInfo &PMInfo) {
+  ModuleMacroInfo Info;
+
+  uint32_t ID = PMInfo.ModuleMacroData.MacID;
+  if (ID & 1) {
+    // Macro undefinition.
+    Info.SubModID = getGlobalSubmoduleID(*PMInfo.M, ID >> 1);
+    Info.MI = nullptr;
+  } else {
+    // Macro definition.
+    GlobalMacroID GMacID = getGlobalMacroID(*PMInfo.M, ID >> 1);
+    assert(GMacID);
+
+    // If this macro has already been loaded, don't do so again.
+    // FIXME: This is highly dubious. Multiple macro definitions can have the
+    // same MacroInfo (and hence the same GMacID) due to #pragma push_macro etc.
+    if (MacrosLoaded[GMacID - NUM_PREDEF_MACRO_IDS])
+      return nullptr;
+
+    Info.MI = getMacro(GMacID);
+    Info.SubModID = Info.MI->getOwningModuleID();
+  }
+  Info.Overrides = PMInfo.ModuleMacroData.Overrides;
+  Info.F = PMInfo.M;
+
+  return new (Context) ModuleMacroInfo(Info);
 }
 
 void ASTReader::resolvePendingMacro(IdentifierInfo *II,
@@ -1486,42 +1777,21 @@
                               PMInfo.PCHMacroData.MacroDirectivesOffset);
     return;
   }
-  
+
   // Module Macro.
 
-  GlobalMacroID GMacID = PMInfo.ModuleMacroData.GMacID;
-  SourceLocation ImportLoc =
-      SourceLocation::getFromRawEncoding(PMInfo.ModuleMacroData.ImportLoc);
-
-  assert(GMacID);
-  // If this macro has already been loaded, don't do so again.
-  if (MacrosLoaded[GMacID - NUM_PREDEF_MACRO_IDS])
+  ModuleMacroInfo *MMI = getModuleMacro(PMInfo);
+  if (!MMI)
     return;
 
-  MacroInfo *MI = getMacro(GMacID);
-  SubmoduleID SubModID = MI->getOwningModuleID();
-  MacroDirective *MD = PP.AllocateDefMacroDirective(MI, ImportLoc,
-                                                    /*isImported=*/true);
-
-  // Determine whether this macro definition is visible.
-  bool Hidden = false;
-  Module *Owner = 0;
-  if (SubModID) {
-    if ((Owner = getSubmodule(SubModID))) {
-      if (Owner->NameVisibility == Module::Hidden) {
-        // The owning module is not visible, and this macro definition
-        // should not be, either.
-        Hidden = true;
-
-        // Note that this macro definition was hidden because its owning
-        // module is not yet visible.
-        HiddenNamesMap[Owner].push_back(HiddenName(II, MD));
-      }
-    }
+  Module *Owner = getSubmodule(MMI->getSubmoduleID());
+  if (Owner && Owner->NameVisibility == Module::Hidden) {
+    // Macros in the owning module are hidden. Just remember this macro to
+    // install if we make this module visible.
+    HiddenNamesMap[Owner].HiddenMacros.insert(std::make_pair(II, MMI));
+  } else {
+    installImportedMacro(II, MMI, Owner, /*FromFinalization*/false);
   }
-
-  if (!Hidden)
-    installImportedMacro(II, MD, Owner);
 }
 
 void ASTReader::installPCHMacroDirectives(IdentifierInfo *II,
@@ -1548,10 +1818,10 @@
   }
 
   // Deserialize the macro directives history in reverse source-order.
-  MacroDirective *Latest = 0, *Earliest = 0;
+  MacroDirective *Latest = nullptr, *Earliest = nullptr;
   unsigned Idx = 0, N = Record.size();
   while (Idx < N) {
-    MacroDirective *MD = 0;
+    MacroDirective *MD = nullptr;
     SourceLocation Loc = ReadSourceLocation(M, Record, Idx);
     MacroDirective::Kind K = (MacroDirective::Kind)Record[Idx++];
     switch (K) {
@@ -1591,7 +1861,7 @@
 static bool areDefinedInSystemModules(MacroInfo *PrevMI, MacroInfo *NewMI,
                                       Module *NewOwner, ASTReader &Reader) {
   assert(PrevMI && NewMI);
-  Module *PrevOwner = 0;
+  Module *PrevOwner = nullptr;
   if (SubmoduleID PrevModID = PrevMI->getOwningModuleID())
     PrevOwner = Reader.getSubmodule(PrevModID);
   SourceManager &SrcMgr = Reader.getSourceManager();
@@ -1606,34 +1876,181 @@
   return PrevInSystem && NewInSystem;
 }
 
-void ASTReader::installImportedMacro(IdentifierInfo *II, MacroDirective *MD,
-                                     Module *Owner) {
-  assert(II && MD);
+void ASTReader::removeOverriddenMacros(IdentifierInfo *II,
+                                       AmbiguousMacros &Ambig,
+                                       ArrayRef<SubmoduleID> Overrides) {
+  for (unsigned OI = 0, ON = Overrides.size(); OI != ON; ++OI) {
+    SubmoduleID OwnerID = Overrides[OI];
 
-  DefMacroDirective *DefMD = cast<DefMacroDirective>(MD);
+    // If this macro is not yet visible, remove it from the hidden names list.
+    Module *Owner = getSubmodule(OwnerID);
+    HiddenNames &Hidden = HiddenNamesMap[Owner];
+    HiddenMacrosMap::iterator HI = Hidden.HiddenMacros.find(II);
+    if (HI != Hidden.HiddenMacros.end()) {
+      auto SubOverrides = HI->second->getOverriddenSubmodules();
+      Hidden.HiddenMacros.erase(HI);
+      removeOverriddenMacros(II, Ambig, SubOverrides);
+    }
+
+    // If this macro is already in our list of conflicts, remove it from there.
+    Ambig.erase(
+        std::remove_if(Ambig.begin(), Ambig.end(), [&](DefMacroDirective *MD) {
+          return MD->getInfo()->getOwningModuleID() == OwnerID;
+        }),
+        Ambig.end());
+  }
+}
+
+ASTReader::AmbiguousMacros *
+ASTReader::removeOverriddenMacros(IdentifierInfo *II,
+                                  ArrayRef<SubmoduleID> Overrides) {
   MacroDirective *Prev = PP.getMacroDirective(II);
-  if (Prev) {
-    MacroDirective::DefInfo PrevDef = Prev->getDefinition();
-    MacroInfo *PrevMI = PrevDef.getMacroInfo();
-    MacroInfo *NewMI = DefMD->getInfo();
-    if (NewMI != PrevMI && !PrevMI->isIdenticalTo(*NewMI, PP,
-                                                  /*Syntactically=*/true)) {
-      // Before marking the macros as ambiguous, check if this is a case where
-      // both macros are in system headers. If so, we trust that the system
-      // did not get it wrong. This also handles cases where Clang's own
-      // headers have a different spelling of certain system macros:
-      //   #define LONG_MAX __LONG_MAX__ (clang's limits.h)
-      //   #define LONG_MAX 0x7fffffffffffffffL (system's limits.h)
-      if (!areDefinedInSystemModules(PrevMI, NewMI, Owner, *this)) {
-        PrevDef.getDirective()->setAmbiguous(true);
-        DefMD->setAmbiguous(true);
-      }
+  if (!Prev && Overrides.empty())
+    return nullptr;
+
+  DefMacroDirective *PrevDef = Prev ? Prev->getDefinition().getDirective()
+                                    : nullptr;
+  if (PrevDef && PrevDef->isAmbiguous()) {
+    // We had a prior ambiguity. Check whether we resolve it (or make it worse).
+    AmbiguousMacros &Ambig = AmbiguousMacroDefs[II];
+    Ambig.push_back(PrevDef);
+
+    removeOverriddenMacros(II, Ambig, Overrides);
+
+    if (!Ambig.empty())
+      return &Ambig;
+
+    AmbiguousMacroDefs.erase(II);
+  } else {
+    // There's no ambiguity yet. Maybe we're introducing one.
+    AmbiguousMacros Ambig;
+    if (PrevDef)
+      Ambig.push_back(PrevDef);
+
+    removeOverriddenMacros(II, Ambig, Overrides);
+
+    if (!Ambig.empty()) {
+      AmbiguousMacros &Result = AmbiguousMacroDefs[II];
+      std::swap(Result, Ambig);
+      return &Result;
     }
   }
-  
+
+  // We ended up with no ambiguity.
+  return nullptr;
+}
+
+void ASTReader::installImportedMacro(IdentifierInfo *II, ModuleMacroInfo *MMI,
+                                     Module *Owner, bool FromFinalization) {
+  assert(II && Owner);
+
+  SourceLocation ImportLoc = Owner->MacroVisibilityLoc;
+  if (ImportLoc.isInvalid() && !FromFinalization) {
+    // FIXME: If we made macros from this module visible but didn't provide a
+    // source location for the import, we don't have a location for the macro.
+    // Use the location at which the containing module file was first imported
+    // for now.
+    ImportLoc = MMI->F->DirectImportLoc;
+    assert(ImportLoc.isValid() && "no import location for a visible macro?");
+  }
+
+  AmbiguousMacros *Prev =
+      removeOverriddenMacros(II, MMI->getOverriddenSubmodules());
+
+  // Create a synthetic macro definition corresponding to the import (or null
+  // if this was an undefinition of the macro).
+  DefMacroDirective *MD = MMI->import(PP, ImportLoc);
+
+  // If there's no ambiguity, just install the macro.
+  if (!Prev) {
+    if (MD)
+      PP.appendMacroDirective(II, MD);
+    else
+      PP.appendMacroDirective(II, PP.AllocateUndefMacroDirective(ImportLoc));
+    return;
+  }
+  assert(!Prev->empty());
+
+  if (!MD) {
+    // We imported a #undef that didn't remove all prior definitions. The most
+    // recent prior definition remains, and we install it in the place of the
+    // imported directive.
+    MacroInfo *NewMI = Prev->back()->getInfo();
+    Prev->pop_back();
+    MD = PP.AllocateDefMacroDirective(NewMI, ImportLoc, /*Imported*/true);
+  }
+
+  // We're introducing a macro definition that creates or adds to an ambiguity.
+  // We can resolve that ambiguity if this macro is token-for-token identical to
+  // all of the existing definitions.
+  MacroInfo *NewMI = MD->getInfo();
+  assert(NewMI && "macro definition with no MacroInfo?");
+  while (!Prev->empty()) {
+    MacroInfo *PrevMI = Prev->back()->getInfo();
+    assert(PrevMI && "macro definition with no MacroInfo?");
+
+    // Before marking the macros as ambiguous, check if this is a case where
+    // both macros are in system headers. If so, we trust that the system
+    // did not get it wrong. This also handles cases where Clang's own
+    // headers have a different spelling of certain system macros:
+    //   #define LONG_MAX __LONG_MAX__ (clang's limits.h)
+    //   #define LONG_MAX 0x7fffffffffffffffL (system's limits.h)
+    //
+    // FIXME: Remove the defined-in-system-headers check. clang's limits.h
+    // overrides the system limits.h's macros, so there's no conflict here.
+    if (NewMI != PrevMI &&
+        !PrevMI->isIdenticalTo(*NewMI, PP, /*Syntactically=*/true) &&
+        !areDefinedInSystemModules(PrevMI, NewMI, Owner, *this))
+      break;
+
+    // The previous definition is the same as this one (or both are defined in
+    // system modules so we can assume they're equivalent); we don't need to
+    // track it any more.
+    Prev->pop_back();
+  }
+
+  if (!Prev->empty())
+    MD->setAmbiguous(true);
+
   PP.appendMacroDirective(II, MD);
 }
 
+ASTReader::InputFileInfo
+ASTReader::readInputFileInfo(ModuleFile &F, unsigned ID) {
+  // Go find this input file.
+  BitstreamCursor &Cursor = F.InputFilesCursor;
+  SavedStreamPosition SavedPosition(Cursor);
+  Cursor.JumpToBit(F.InputFileOffsets[ID-1]);
+
+  unsigned Code = Cursor.ReadCode();
+  RecordData Record;
+  StringRef Blob;
+
+  unsigned Result = Cursor.readRecord(Code, Record, &Blob);
+  assert(static_cast<InputFileRecordTypes>(Result) == INPUT_FILE &&
+         "invalid record type for input file");
+  (void)Result;
+
+  std::string Filename;
+  off_t StoredSize;
+  time_t StoredTime;
+  bool Overridden;
+  
+  assert(Record[0] == ID && "Bogus stored ID or offset");
+  StoredSize = static_cast<off_t>(Record[1]);
+  StoredTime = static_cast<time_t>(Record[2]);
+  Overridden = static_cast<bool>(Record[3]);
+  Filename = Blob;
+  MaybeAddSystemRootToFilename(F, Filename);
+  
+  InputFileInfo R = { std::move(Filename), StoredSize, StoredTime, Overridden };
+  return R;
+}
+
+std::string ASTReader::getInputFileName(ModuleFile &F, unsigned int ID) {
+  return readInputFileInfo(F, ID).Filename;
+}
+
 InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) {
   // If this ID is bogus, just return an empty input file.
   if (ID == 0 || ID > F.InputFilesLoaded.size())
@@ -1643,107 +2060,113 @@
   if (F.InputFilesLoaded[ID-1].getFile())
     return F.InputFilesLoaded[ID-1];
 
+  if (F.InputFilesLoaded[ID-1].isNotFound())
+    return InputFile();
+
   // Go find this input file.
   BitstreamCursor &Cursor = F.InputFilesCursor;
   SavedStreamPosition SavedPosition(Cursor);
   Cursor.JumpToBit(F.InputFileOffsets[ID-1]);
   
-  unsigned Code = Cursor.ReadCode();
-  RecordData Record;
-  StringRef Blob;
-  switch ((InputFileRecordTypes)Cursor.readRecord(Code, Record, &Blob)) {
-  case INPUT_FILE: {
-    unsigned StoredID = Record[0];
-    assert(ID == StoredID && "Bogus stored ID or offset");
-    (void)StoredID;
-    off_t StoredSize = (off_t)Record[1];
-    time_t StoredTime = (time_t)Record[2];
-    bool Overridden = (bool)Record[3];
-    
-    // Get the file entry for this input file.
-    StringRef OrigFilename = Blob;
-    std::string Filename = OrigFilename;
-    MaybeAddSystemRootToFilename(F, Filename);
-    const FileEntry *File 
-      = Overridden? FileMgr.getVirtualFile(Filename, StoredSize, StoredTime)
-                  : FileMgr.getFile(Filename, /*OpenFile=*/false);
-    
-    // If we didn't find the file, resolve it relative to the
-    // original directory from which this AST file was created.
-    if (File == 0 && !F.OriginalDir.empty() && !CurrentDir.empty() &&
-        F.OriginalDir != CurrentDir) {
-      std::string Resolved = resolveFileRelativeToOriginalDir(Filename,
-                                                              F.OriginalDir,
-                                                              CurrentDir);
-      if (!Resolved.empty())
-        File = FileMgr.getFile(Resolved);
-    }
-    
-    // For an overridden file, create a virtual file with the stored
-    // size/timestamp.
-    if (Overridden && File == 0) {
-      File = FileMgr.getVirtualFile(Filename, StoredSize, StoredTime);
-    }
-    
-    if (File == 0) {
-      if (Complain) {
-        std::string ErrorStr = "could not find file '";
-        ErrorStr += Filename;
-        ErrorStr += "' referenced by AST file";
-        Error(ErrorStr.c_str());
-      }
-      return InputFile();
-    }
+  InputFileInfo FI = readInputFileInfo(F, ID);
+  off_t StoredSize = FI.StoredSize;
+  time_t StoredTime = FI.StoredTime;
+  bool Overridden = FI.Overridden;
+  StringRef Filename = FI.Filename;
 
-    // Check if there was a request to override the contents of the file
-    // that was part of the precompiled header. Overridding such a file
-    // can lead to problems when lexing using the source locations from the
-    // PCH.
-    SourceManager &SM = getSourceManager();
-    if (!Overridden && SM.isFileOverridden(File)) {
-      if (Complain)
-        Error(diag::err_fe_pch_file_overridden, Filename);
-      // After emitting the diagnostic, recover by disabling the override so
-      // that the original file will be used.
-      SM.disableFileContentsOverride(File);
-      // The FileEntry is a virtual file entry with the size of the contents
-      // that would override the original contents. Set it to the original's
-      // size/time.
-      FileMgr.modifyFileEntry(const_cast<FileEntry*>(File),
-                              StoredSize, StoredTime);
+  const FileEntry *File
+    = Overridden? FileMgr.getVirtualFile(Filename, StoredSize, StoredTime)
+                : FileMgr.getFile(Filename, /*OpenFile=*/false);
+
+  // If we didn't find the file, resolve it relative to the
+  // original directory from which this AST file was created.
+  if (File == nullptr && !F.OriginalDir.empty() && !CurrentDir.empty() &&
+      F.OriginalDir != CurrentDir) {
+    std::string Resolved = resolveFileRelativeToOriginalDir(Filename,
+                                                            F.OriginalDir,
+                                                            CurrentDir);
+    if (!Resolved.empty())
+      File = FileMgr.getFile(Resolved);
+  }
+
+  // For an overridden file, create a virtual file with the stored
+  // size/timestamp.
+  if (Overridden && File == nullptr) {
+    File = FileMgr.getVirtualFile(Filename, StoredSize, StoredTime);
+  }
+
+  if (File == nullptr) {
+    if (Complain) {
+      std::string ErrorStr = "could not find file '";
+      ErrorStr += Filename;
+      ErrorStr += "' referenced by AST file";
+      Error(ErrorStr.c_str());
     }
+    // Record that we didn't find the file.
+    F.InputFilesLoaded[ID-1] = InputFile::getNotFound();
+    return InputFile();
+  }
 
-    bool IsOutOfDate = false;
+  // Check if there was a request to override the contents of the file
+  // that was part of the precompiled header. Overridding such a file
+  // can lead to problems when lexing using the source locations from the
+  // PCH.
+  SourceManager &SM = getSourceManager();
+  if (!Overridden && SM.isFileOverridden(File)) {
+    if (Complain)
+      Error(diag::err_fe_pch_file_overridden, Filename);
+    // After emitting the diagnostic, recover by disabling the override so
+    // that the original file will be used.
+    SM.disableFileContentsOverride(File);
+    // The FileEntry is a virtual file entry with the size of the contents
+    // that would override the original contents. Set it to the original's
+    // size/time.
+    FileMgr.modifyFileEntry(const_cast<FileEntry*>(File),
+                            StoredSize, StoredTime);
+  }
 
-    // For an overridden file, there is nothing to validate.
-    if (!Overridden && (StoredSize != File->getSize()
+  bool IsOutOfDate = false;
+
+  // For an overridden file, there is nothing to validate.
+  if (!Overridden && (StoredSize != File->getSize()
 #if !defined(LLVM_ON_WIN32)
-         // In our regression testing, the Windows file system seems to
-         // have inconsistent modification times that sometimes
-         // erroneously trigger this error-handling path.
-         || StoredTime != File->getModificationTime()
+       // In our regression testing, the Windows file system seems to
+       // have inconsistent modification times that sometimes
+       // erroneously trigger this error-handling path.
+       || StoredTime != File->getModificationTime()
 #endif
-         )) {
-      if (Complain) {
-        Error(diag::err_fe_pch_file_modified, Filename, F.FileName);
-        if (Context.getLangOpts().Modules && !Diags.isDiagnosticInFlight()) {
-          Diag(diag::note_module_cache_path)
-            << PP.getHeaderSearchInfo().getModuleCachePath();
-        }
+       )) {
+    if (Complain) {
+      // Build a list of the PCH imports that got us here (in reverse).
+      SmallVector<ModuleFile *, 4> ImportStack(1, &F);
+      while (ImportStack.back()->ImportedBy.size() > 0)
+        ImportStack.push_back(ImportStack.back()->ImportedBy[0]);
+
+      // The top-level PCH is stale.
+      StringRef TopLevelPCHName(ImportStack.back()->FileName);
+      Error(diag::err_fe_pch_file_modified, Filename, TopLevelPCHName);
+
+      // Print the import stack.
+      if (ImportStack.size() > 1 && !Diags.isDiagnosticInFlight()) {
+        Diag(diag::note_pch_required_by)
+          << Filename << ImportStack[0]->FileName;
+        for (unsigned I = 1; I < ImportStack.size(); ++I)
+          Diag(diag::note_pch_required_by)
+            << ImportStack[I-1]->FileName << ImportStack[I]->FileName;
       }
 
-      IsOutOfDate = true;
+      if (!Diags.isDiagnosticInFlight())
+        Diag(diag::note_pch_rebuild_required) << TopLevelPCHName;
     }
 
-    InputFile IF = InputFile(File, Overridden, IsOutOfDate);
-
-    // Note that we've loaded this input file.
-    F.InputFilesLoaded[ID-1] = IF;
-    return IF;
-  }
+    IsOutOfDate = true;
   }
 
-  return InputFile();
+  InputFile IF = InputFile(File, Overridden, IsOutOfDate);
+
+  // Note that we've loaded this input file.
+  F.InputFilesLoaded[ID-1] = IF;
+  return IF;
 }
 
 const FileEntry *ASTReader::getFileEntry(StringRef filenameStrRef) {
@@ -1751,7 +2174,7 @@
   std::string Filename = filenameStrRef;
   MaybeAddSystemRootToFilename(M, Filename);
   const FileEntry *File = FileMgr.getFile(Filename);
-  if (File == 0 && !M.OriginalDir.empty() && !CurrentDir.empty() &&
+  if (File == nullptr && !M.OriginalDir.empty() && !CurrentDir.empty() &&
       M.OriginalDir != CurrentDir) {
     std::string resolved = resolveFileRelativeToOriginalDir(Filename,
                                                             M.OriginalDir,
@@ -1791,6 +2214,7 @@
 ASTReader::ASTReadResult
 ASTReader::ReadControlBlock(ModuleFile &F,
                             SmallVectorImpl<ImportedModule> &Loaded,
+                            const ModuleFile *ImportedBy,
                             unsigned ClientLoadCapabilities) {
   BitstreamCursor &Stream = F.Stream;
 
@@ -1808,20 +2232,54 @@
     case llvm::BitstreamEntry::Error:
       Error("malformed block record in AST file");
       return Failure;
-    case llvm::BitstreamEntry::EndBlock:
-      // Validate all of the non-system input files.
-      if (!DisableValidation) {
+    case llvm::BitstreamEntry::EndBlock: {
+      // Validate input files.
+      const HeaderSearchOptions &HSOpts =
+          PP.getHeaderSearchInfo().getHeaderSearchOpts();
+
+      // All user input files reside at the index range [0, Record[1]), and
+      // system input files reside at [Record[1], Record[0]).
+      // Record is the one from INPUT_FILE_OFFSETS.
+      unsigned NumInputs = Record[0];
+      unsigned NumUserInputs = Record[1];
+
+      if (!DisableValidation &&
+          (ValidateSystemInputs || !HSOpts.ModulesValidateOncePerBuildSession ||
+           F.InputFilesValidationTimestamp <= HSOpts.BuildSessionTimestamp)) {
         bool Complain = (ClientLoadCapabilities & ARR_OutOfDate) == 0;
-        // All user input files reside at the index range [0, Record[1]).
-        // Record is the one from INPUT_FILE_OFFSETS.
-        for (unsigned I = 0, N = Record[1]; I < N; ++I) {
+
+        // If we are reading a module, we will create a verification timestamp,
+        // so we verify all input files.  Otherwise, verify only user input
+        // files.
+
+        unsigned N = NumUserInputs;
+        if (ValidateSystemInputs ||
+            (HSOpts.ModulesValidateOncePerBuildSession && F.Kind == MK_Module))
+          N = NumInputs;
+
+        for (unsigned I = 0; I < N; ++I) {
           InputFile IF = getInputFile(F, I+1, Complain);
           if (!IF.getFile() || IF.isOutOfDate())
             return OutOfDate;
         }
       }
+
+      if (Listener)
+        Listener->visitModuleFile(F.FileName);
+
+      if (Listener && Listener->needsInputFileVisitation()) {
+        unsigned N = Listener->needsSystemInputFileVisitation() ? NumInputs
+                                                                : NumUserInputs;
+        for (unsigned I = 0; I < N; ++I) {
+          bool IsSystem = I >= NumUserInputs;
+          InputFileInfo FI = readInputFileInfo(F, I+1);
+          Listener->visitInputFile(FI.Filename, IsSystem, FI.Overridden);
+        }
+      }
+
       return Success;
-      
+    }
+
     case llvm::BitstreamEntry::SubBlock:
       switch (Entry.ID) {
       case INPUT_FILES_BLOCK_ID:
@@ -1854,8 +2312,8 @@
     case METADATA: {
       if (Record[0] != VERSION_MAJOR && !DisableValidation) {
         if ((ClientLoadCapabilities & ARR_VersionMismatch) == 0)
-          Diag(Record[0] < VERSION_MAJOR? diag::warn_pch_version_too_old
-                                        : diag::warn_pch_version_too_new);
+          Diag(Record[0] < VERSION_MAJOR? diag::err_pch_version_too_old
+                                        : diag::err_pch_version_too_new);
         return VersionMismatch;
       }
 
@@ -1871,7 +2329,7 @@
       StringRef ASTBranch = Blob;
       if (StringRef(CurBranch) != ASTBranch && !DisableValidation) {
         if ((ClientLoadCapabilities & ARR_VersionMismatch) == 0)
-          Diag(diag::warn_pch_different_branch) << ASTBranch << CurBranch;
+          Diag(diag::err_pch_different_branch) << ASTBranch << CurBranch;
         return VersionMismatch;
       }
       break;
@@ -1916,7 +2374,7 @@
       bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0;
       if (Listener && &F == *ModuleMgr.begin() &&
           ParseLanguageOptions(Record, Complain, *Listener) &&
-          !DisableValidation)
+          !DisableValidation && !AllowConfigurationMismatch)
         return ConfigurationMismatch;
       break;
     }
@@ -1925,17 +2383,17 @@
       bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0;
       if (Listener && &F == *ModuleMgr.begin() &&
           ParseTargetOptions(Record, Complain, *Listener) &&
-          !DisableValidation)
+          !DisableValidation && !AllowConfigurationMismatch)
         return ConfigurationMismatch;
       break;
     }
 
     case DIAGNOSTIC_OPTIONS: {
-      bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0;
+      bool Complain = (ClientLoadCapabilities & ARR_OutOfDate)==0;
       if (Listener && &F == *ModuleMgr.begin() &&
           ParseDiagnosticOptions(Record, Complain, *Listener) &&
           !DisableValidation)
-        return ConfigurationMismatch;
+        return OutOfDate;
       break;
     }
 
@@ -1943,7 +2401,7 @@
       bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0;
       if (Listener && &F == *ModuleMgr.begin() &&
           ParseFileSystemOptions(Record, Complain, *Listener) &&
-          !DisableValidation)
+          !DisableValidation && !AllowConfigurationMismatch)
         return ConfigurationMismatch;
       break;
     }
@@ -1952,7 +2410,7 @@
       bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch)==0;
       if (Listener && &F == *ModuleMgr.begin() &&
           ParseHeaderSearchOptions(Record, Complain, *Listener) &&
-          !DisableValidation)
+          !DisableValidation && !AllowConfigurationMismatch)
         return ConfigurationMismatch;
       break;
     }
@@ -1962,7 +2420,7 @@
       if (Listener && &F == *ModuleMgr.begin() &&
           ParsePreprocessorOptions(Record, Complain, *Listener,
                                    SuggestedPredefines) &&
-          !DisableValidation)
+          !DisableValidation && !AllowConfigurationMismatch)
         return ConfigurationMismatch;
       break;
     }
@@ -1982,6 +2440,49 @@
       F.OriginalDir = Blob;
       break;
 
+    case MODULE_NAME:
+      F.ModuleName = Blob;
+      if (Listener)
+        Listener->ReadModuleName(F.ModuleName);
+      break;
+
+    case MODULE_MAP_FILE:
+      F.ModuleMapPath = Blob;
+
+      // Try to resolve ModuleName in the current header search context and
+      // verify that it is found in the same module map file as we saved. If the
+      // top-level AST file is a main file, skip this check because there is no
+      // usable header search context.
+      assert(!F.ModuleName.empty() &&
+             "MODULE_NAME should come before MOUDLE_MAP_FILE");
+      if (F.Kind == MK_Module &&
+          (*ModuleMgr.begin())->Kind != MK_MainFile) {
+        Module *M = PP.getHeaderSearchInfo().lookupModule(F.ModuleName);
+        if (!M) {
+          assert(ImportedBy && "top-level import should be verified");
+          if ((ClientLoadCapabilities & ARR_Missing) == 0)
+            Diag(diag::err_imported_module_not_found)
+              << F.ModuleName << ImportedBy->FileName;
+          return Missing;
+        }
+
+        const FileEntry *StoredModMap = FileMgr.getFile(F.ModuleMapPath);
+        if (StoredModMap == nullptr || StoredModMap != M->ModuleMap) {
+          assert(M->ModuleMap && "found module is missing module map file");
+          assert(M->Name == F.ModuleName && "found module with different name");
+          assert(ImportedBy && "top-level import should be verified");
+          if ((ClientLoadCapabilities & ARR_OutOfDate) == 0)
+            Diag(diag::err_imported_module_modmap_changed)
+              << F.ModuleName << ImportedBy->FileName
+              << M->ModuleMap->getName() << F.ModuleMapPath;
+          return OutOfDate;
+        }
+      }
+
+      if (Listener)
+        Listener->ReadModuleMapFile(F.ModuleMapPath);
+      break;
+
     case INPUT_FILE_OFFSETS:
       F.InputFileOffsets = (const uint32_t *)Blob.data();
       F.InputFilesLoaded.resize(Record[0]);
@@ -1990,12 +2491,13 @@
   }
 }
 
-bool ASTReader::ReadASTBlock(ModuleFile &F) {
+ASTReader::ASTReadResult
+ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
   BitstreamCursor &Stream = F.Stream;
 
   if (Stream.EnterSubBlock(AST_BLOCK_ID)) {
     Error("malformed block record in AST file");
-    return true;
+    return Failure;
   }
 
   // Read all of the records and blocks for the AST file.
@@ -2006,7 +2508,7 @@
     switch (Entry.Kind) {
     case llvm::BitstreamEntry::Error:
       Error("error at end of module block in AST file");
-      return true;
+      return Failure;
     case llvm::BitstreamEntry::EndBlock: {
       // Outside of C++, we do not store a lookup map for the translation unit.
       // Instead, mark it as needing a lookup map to be built if this module
@@ -2018,7 +2520,7 @@
           !getContext().getLangOpts().CPlusPlus)
         DC->setMustBuildLookupTable();
       
-      return false;
+      return Success;
     }
     case llvm::BitstreamEntry::SubBlock:
       switch (Entry.ID) {
@@ -2032,17 +2534,10 @@
             // Read the abbrevs.
             ReadBlockAbbrevs(F.DeclsCursor, DECLTYPES_BLOCK_ID)) {
           Error("malformed block record in AST file");
-          return true;
+          return Failure;
         }
         break;
-        
-      case DECL_UPDATES_BLOCK_ID:
-        if (Stream.SkipBlock()) {
-          Error("malformed block record in AST file");
-          return true;
-        }
-        break;
-        
+
       case PREPROCESSOR_BLOCK_ID:
         F.MacroCursor = Stream;
         if (!PP.getExternalSource())
@@ -2051,7 +2546,7 @@
         if (Stream.SkipBlock() ||
             ReadBlockAbbrevs(F.MacroCursor, PREPROCESSOR_BLOCK_ID)) {
           Error("malformed block record in AST file");
-          return true;
+          return Failure;
         }
         F.MacroStartOffset = F.MacroCursor.GetCurrentBitNo();
         break;
@@ -2062,7 +2557,7 @@
             ReadBlockAbbrevs(F.PreprocessorDetailCursor,
                              PREPROCESSOR_DETAIL_BLOCK_ID)) {
               Error("malformed preprocessor detail record in AST file");
-              return true;
+              return Failure;
             }
         F.PreprocessorDetailStartOffset
         = F.PreprocessorDetailCursor.GetCurrentBitNo();
@@ -2075,12 +2570,12 @@
         
       case SOURCE_MANAGER_BLOCK_ID:
         if (ReadSourceManagerBlock(F))
-          return true;
+          return Failure;
         break;
         
       case SUBMODULE_BLOCK_ID:
-        if (ReadSubmoduleBlock(F))
-          return true;
+        if (ASTReadResult Result = ReadSubmoduleBlock(F, ClientLoadCapabilities))
+          return Result;
         break;
         
       case COMMENTS_BLOCK_ID: {
@@ -2088,7 +2583,7 @@
         if (Stream.SkipBlock() ||
             ReadBlockAbbrevs(C, COMMENTS_BLOCK_ID)) {
           Error("malformed comments block in AST file");
-          return true;
+          return Failure;
         }
         CommentsCursors.push_back(std::make_pair(C, &F));
         break;
@@ -2097,7 +2592,7 @@
       default:
         if (Stream.SkipBlock()) {
           Error("malformed block record in AST file");
-          return true;
+          return Failure;
         }
         break;
       }
@@ -2118,7 +2613,7 @@
     case TYPE_OFFSET: {
       if (F.LocalNumTypes != 0) {
         Error("duplicate TYPE_OFFSET record in AST file");
-        return true;
+        return Failure;
       }
       F.TypeOffsets = (const uint32_t *)Blob.data();
       F.LocalNumTypes = Record[0];
@@ -2142,7 +2637,7 @@
     case DECL_OFFSET: {
       if (F.LocalNumDecls != 0) {
         Error("duplicate DECL_OFFSET record in AST file");
-        return true;
+        return Failure;
       }
       F.DeclOffsets = (const DeclOffset *)Blob.data();
       F.LocalNumDecls = Record[0];
@@ -2183,14 +2678,18 @@
       unsigned Idx = 0;
       serialization::DeclID ID = ReadDeclID(F, Record, Idx);
       ASTDeclContextNameLookupTable *Table =
-        ASTDeclContextNameLookupTable::Create(
-                        (const unsigned char *)Blob.data() + Record[Idx++],
-                        (const unsigned char *)Blob.data(),
-                        ASTDeclContextNameLookupTrait(*this, F));
-      if (ID == PREDEF_DECL_TRANSLATION_UNIT_ID) { // Is it the TU?
-        DeclContext *TU = Context.getTranslationUnitDecl();
-        F.DeclContextInfos[TU].NameLookupTableData = Table;
-        TU->setHasExternalVisibleStorage(true);
+          ASTDeclContextNameLookupTable::Create(
+              (const unsigned char *)Blob.data() + Record[Idx++],
+              (const unsigned char *)Blob.data() + sizeof(uint32_t),
+              (const unsigned char *)Blob.data(),
+              ASTDeclContextNameLookupTrait(*this, F));
+      if (Decl *D = GetExistingDecl(ID)) {
+        auto *DC = cast<DeclContext>(D);
+        DC->getPrimaryContext()->setHasExternalVisibleStorage(true);
+        auto *&LookupTable = F.DeclContextInfos[DC].NameLookupTableData;
+        // FIXME: There should never be an existing lookup table.
+        delete LookupTable;
+        LookupTable = Table;
       } else
         PendingVisibleUpdates[ID].push_back(std::make_pair(Table, &F));
       break;
@@ -2199,11 +2698,11 @@
     case IDENTIFIER_TABLE:
       F.IdentifierTableData = Blob.data();
       if (Record[0]) {
-        F.IdentifierLookupTable
-          = ASTIdentifierLookupTable::Create(
-                       (const unsigned char *)F.IdentifierTableData + Record[0],
-                       (const unsigned char *)F.IdentifierTableData,
-                       ASTIdentifierLookupTrait(*this, F));
+        F.IdentifierLookupTable = ASTIdentifierLookupTable::Create(
+            (const unsigned char *)F.IdentifierTableData + Record[0],
+            (const unsigned char *)F.IdentifierTableData + sizeof(uint32_t),
+            (const unsigned char *)F.IdentifierTableData,
+            ASTIdentifierLookupTrait(*this, F));
         
         PP.getIdentifierTable().setExternalIdentifierLookup(this);
       }
@@ -2212,7 +2711,7 @@
     case IDENTIFIER_OFFSET: {
       if (F.LocalNumIdentifiers != 0) {
         Error("duplicate IDENTIFIER_OFFSET record in AST file");
-        return true;
+        return Failure;
       }
       F.IdentifierOffsets = (const uint32_t *)Blob.data();
       F.LocalNumIdentifiers = Record[0];
@@ -2237,9 +2736,9 @@
       break;
     }
 
-    case EXTERNAL_DEFINITIONS:
+    case EAGERLY_DESERIALIZED_DECLS:
       for (unsigned I = 0, N = Record.size(); I != N; ++I)
-        ExternalDefinitions.push_back(getGlobalDeclID(F, Record[I]));
+        EagerlyDeserializedDecls.push_back(getGlobalDeclID(F, Record[I]));
       break;
 
     case SPECIAL_TYPES:
@@ -2251,7 +2750,7 @@
 
       if (SpecialTypes.size() != Record.size()) {
         Error("invalid special-types record");
-        return true;
+        return Failure;
       }
 
       for (unsigned I = 0, N = Record.size(); I != N; ++I) {
@@ -2283,7 +2782,7 @@
     case WEAK_UNDECLARED_IDENTIFIERS:
       if (Record.size() % 4 != 0) {
         Error("invalid weak identifiers record");
-        return true;
+        return Failure;
       }
         
       // FIXME: Ignore weak undeclared identifiers from non-original PCH 
@@ -2365,7 +2864,7 @@
       F.SLocEntryOffsets = (const uint32_t *)Blob.data();
       F.LocalNumSLocEntries = Record[0];
       unsigned SLocSpaceSize = Record[1];
-      llvm::tie(F.SLocEntryBaseID, F.SLocEntryBaseOffset) =
+      std::tie(F.SLocEntryBaseID, F.SLocEntryBaseOffset) =
           SourceMgr.AllocateLoadedSLocEntries(F.LocalNumSLocEntries,
                                               SLocSpaceSize);
       // Make our entry in the range map. BaseID is negative and growing, so
@@ -2384,9 +2883,9 @@
 
       // Initialize the remapping table.
       // Invalid stays invalid.
-      F.SLocRemap.insert(std::make_pair(0U, 0));
+      F.SLocRemap.insertOrReplace(std::make_pair(0U, 0));
       // This module. Base was 2 when being compiled.
-      F.SLocRemap.insert(std::make_pair(2U,
+      F.SLocRemap.insertOrReplace(std::make_pair(2U,
                                   static_cast<int>(F.SLocEntryBaseOffset - 2)));
       
       TotalNumSLocEntries += F.LocalNumSLocEntries;
@@ -2397,7 +2896,13 @@
       // 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.
       ContinuousRangeMap<uint32_t, int, 2>::Builder SLocRemap(F.SLocRemap);
       ContinuousRangeMap<uint32_t, int, 2>::Builder 
@@ -2414,24 +2919,33 @@
       ContinuousRangeMap<uint32_t, int, 2>::Builder TypeRemap(F.TypeRemap);
 
       while(Data < DataEnd) {
-        uint16_t Len = io::ReadUnalignedLE16(Data);
+        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 true;
+          return Failure;
         }
 
-        uint32_t SLocOffset = io::ReadUnalignedLE32(Data);
-        uint32_t IdentifierIDOffset = io::ReadUnalignedLE32(Data);
-        uint32_t MacroIDOffset = io::ReadUnalignedLE32(Data);
-        uint32_t PreprocessedEntityIDOffset = io::ReadUnalignedLE32(Data);
-        uint32_t SubmoduleIDOffset = io::ReadUnalignedLE32(Data);
-        uint32_t SelectorIDOffset = io::ReadUnalignedLE32(Data);
-        uint32_t DeclIDOffset = io::ReadUnalignedLE32(Data);
-        uint32_t TypeIndexOffset = io::ReadUnalignedLE32(Data);
-        
+        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);
+
         // Source location offset is mapped to OM->SLocEntryBaseOffset.
         SLocRemap.insert(std::make_pair(SLocOffset,
           static_cast<int>(OM->SLocEntryBaseOffset - SLocOffset)));
@@ -2461,7 +2975,7 @@
 
     case SOURCE_MANAGER_LINE_TABLE:
       if (ParseLineTable(F, Record))
-        return true;
+        return Failure;
       break;
 
     case SOURCE_LOCATION_PRELOADS: {
@@ -2469,7 +2983,7 @@
       // which is based off F.SLocEntryBaseID.
       if (!F.PreloadSLocEntries.empty()) {
         Error("Multiple SOURCE_LOCATION_PRELOADS records in AST file");
-        return true;
+        return Failure;
       }
       
       F.PreloadSLocEntries.swap(Record);
@@ -2484,7 +2998,7 @@
     case VTABLE_USES:
       if (Record.size() % 3 != 0) {
         Error("Invalid VTABLE_USES record");
-        return true;
+        return Failure;
       }
         
       // Later tables overwrite earlier ones.
@@ -2508,12 +3022,12 @@
     case PENDING_IMPLICIT_INSTANTIATIONS:
       if (PendingInstantiations.size() % 2 != 0) {
         Error("Invalid existing PendingInstantiations");
-        return true;
+        return Failure;
       }
 
       if (Record.size() % 2 != 0) {
         Error("Invalid PENDING_IMPLICIT_INSTANTIATIONS block");
-        return true;
+        return Failure;
       }
 
       for (unsigned I = 0, N = Record.size(); I != N; /* in loop */) {
@@ -2526,7 +3040,7 @@
     case SEMA_DECL_REFS:
       if (Record.size() != 2) {
         Error("Invalid SEMA_DECL_REFS block");
-        return true;
+        return Failure;
       }
       for (unsigned I = 0, N = Record.size(); I != N; ++I)
         SemaDeclRefs.push_back(getGlobalDeclID(F, Record[I]));
@@ -2567,18 +3081,24 @@
     case DECL_UPDATE_OFFSETS: {
       if (Record.size() % 2 != 0) {
         Error("invalid DECL_UPDATE_OFFSETS block in AST file");
-        return true;
+        return Failure;
       }
-      for (unsigned I = 0, N = Record.size(); I != N; I += 2)
-        DeclUpdateOffsets[getGlobalDeclID(F, Record[I])]
-          .push_back(std::make_pair(&F, Record[I+1]));
+      for (unsigned I = 0, N = Record.size(); I != N; I += 2) {
+        GlobalDeclID ID = getGlobalDeclID(F, Record[I]);
+        DeclUpdateOffsets[ID].push_back(std::make_pair(&F, Record[I + 1]));
+
+        // If we've already loaded the decl, perform the updates when we finish
+        // loading this block.
+        if (Decl *D = GetExistingDecl(ID))
+          PendingUpdateRecords.push_back(std::make_pair(ID, D));
+      }
       break;
     }
 
     case DECL_REPLACEMENTS: {
       if (Record.size() % 3 != 0) {
         Error("invalid DECL_REPLACEMENTS block in AST file");
-        return true;
+        return Failure;
       }
       for (unsigned I = 0, N = Record.size(); I != N; I += 3)
         ReplacedDecls[getGlobalDeclID(F, Record[I])]
@@ -2589,7 +3109,7 @@
     case OBJC_CATEGORIES_MAP: {
       if (F.LocalNumObjCCategoriesInMap != 0) {
         Error("duplicate OBJC_CATEGORIES_MAP record in AST file");
-        return true;
+        return Failure;
       }
       
       F.LocalNumObjCCategoriesInMap = Record[0];
@@ -2604,7 +3124,7 @@
     case CXX_BASE_SPECIFIER_OFFSETS: {
       if (F.LocalNumCXXBaseSpecifiers != 0) {
         Error("duplicate CXX_BASE_SPECIFIER_OFFSETS record in AST file");
-        return true;
+        return Failure;
       }
       
       F.LocalNumCXXBaseSpecifiers = Record[0];
@@ -2671,12 +3191,12 @@
     case UNDEFINED_BUT_USED:
       if (UndefinedButUsed.size() % 2 != 0) {
         Error("Invalid existing UndefinedButUsed");
-        return true;
+        return Failure;
       }
 
       if (Record.size() % 2 != 0) {
         Error("invalid undefined-but-used record");
-        return true;
+        return Failure;
       }
       for (unsigned I = 0, N = Record.size(); I != N; /* in loop */) {
         UndefinedButUsed.push_back(getGlobalDeclID(F, Record[I++]));
@@ -2690,9 +3210,11 @@
         // If we aren't loading a module (which has its own exports), make
         // all of the imported modules visible.
         // FIXME: Deal with macros-only imports.
-        for (unsigned I = 0, N = Record.size(); I != N; ++I) {
-          if (unsigned GlobalID = getGlobalSubmoduleID(F, Record[I]))
-            ImportedModules.push_back(GlobalID);
+        for (unsigned I = 0, N = Record.size(); I != N; /**/) {
+          unsigned GlobalID = getGlobalSubmoduleID(F, Record[I++]);
+          SourceLocation Loc = ReadSourceLocation(F, Record, I);
+          if (GlobalID)
+            ImportedModules.push_back(ImportedSubmodule(GlobalID, Loc));
         }
       }
       break;
@@ -2706,7 +3228,7 @@
     case LOCAL_REDECLARATIONS_MAP: {
       if (F.LocalNumRedeclarationsInMap != 0) {
         Error("duplicate LOCAL_REDECLARATIONS_MAP record in AST file");
-        return true;
+        return Failure;
       }
       
       F.LocalNumRedeclarationsInMap = Record[0];
@@ -2727,7 +3249,7 @@
     case MACRO_OFFSET: {
       if (F.LocalNumMacros != 0) {
         Error("duplicate MACRO_OFFSET record in AST file");
-        return true;
+        return Failure;
       }
       F.MacroOffsets = (const uint32_t *)Blob.data();
       F.LocalNumMacros = Record[0];
@@ -2757,6 +3279,14 @@
       LateParsedTemplates.append(Record.begin(), Record.end());
       break;
     }
+
+    case OPTIMIZE_PRAGMA_OPTIONS:
+      if (Record.size() != 1) {
+        Error("invalid pragma optimize record");
+        return Failure;
+      }
+      OptimizeOffPragmaLocation = ReadSourceLocation(F, Record[0]);
+      break;
     }
   }
 }
@@ -2790,31 +3320,27 @@
   }
 }
 
-void ASTReader::makeNamesVisible(const HiddenNames &Names, Module *Owner) {
-  for (unsigned I = 0, N = Names.size(); I != N; ++I) {
-    switch (Names[I].getKind()) {
-    case HiddenName::Declaration: {
-      Decl *D = Names[I].getDecl();
-      bool wasHidden = D->Hidden;
-      D->Hidden = false;
+void ASTReader::makeNamesVisible(const HiddenNames &Names, Module *Owner,
+                                 bool FromFinalization) {
+  // FIXME: Only do this if Owner->NameVisibility == AllVisible.
+  for (Decl *D : Names.HiddenDecls) {
+    bool wasHidden = D->Hidden;
+    D->Hidden = false;
 
-      if (wasHidden && SemaObj) {
-        if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D)) {
-          moveMethodToBackOfGlobalList(*SemaObj, Method);
-        }
+    if (wasHidden && SemaObj) {
+      if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D)) {
+        moveMethodToBackOfGlobalList(*SemaObj, Method);
       }
-      break;
-    }
-    case HiddenName::MacroVisibility: {
-      std::pair<IdentifierInfo *, MacroDirective *> Macro = Names[I].getMacro();
-      installImportedMacro(Macro.first, Macro.second, Owner);
-      break;
-    }
     }
   }
+
+  assert((FromFinalization || Owner->NameVisibility >= Module::MacrosVisible) &&
+         "nothing to make visible?");
+  for (const auto &Macro : Names.HiddenMacros)
+    installImportedMacro(Macro.first, Macro.second, Owner, FromFinalization);
 }
 
-void ASTReader::makeModuleVisible(Module *Mod, 
+void ASTReader::makeModuleVisible(Module *Mod,
                                   Module::NameVisibilityKind NameVisibility,
                                   SourceLocation ImportLoc,
                                   bool Complain) {
@@ -2829,21 +3355,28 @@
       // there is nothing more to do.
       continue;
     }
-    
+
     if (!Mod->isAvailable()) {
       // Modules that aren't available cannot be made visible.
       continue;
     }
 
     // Update the module's name visibility.
+    if (NameVisibility >= Module::MacrosVisible &&
+        Mod->NameVisibility < Module::MacrosVisible)
+      Mod->MacroVisibilityLoc = ImportLoc;
     Mod->NameVisibility = NameVisibility;
-    
+
     // If we've already deserialized any names from this module,
     // mark them as visible.
     HiddenNamesMapType::iterator Hidden = HiddenNamesMap.find(Mod);
     if (Hidden != HiddenNamesMap.end()) {
-      makeNamesVisible(Hidden->second, Hidden->first);
+      auto HiddenNames = std::move(*Hidden);
       HiddenNamesMap.erase(Hidden);
+      makeNamesVisible(HiddenNames.second, HiddenNames.first,
+                       /*FromFinalization*/false);
+      assert(HiddenNamesMap.find(Mod) == HiddenNamesMap.end() &&
+             "making names visible added hidden names");
     }
 
     // Push any exported modules onto the stack to be marked as visible.
@@ -2899,6 +3432,17 @@
          !hasGlobalIndex() && TriedLoadingGlobalIndex;
 }
 
+static void updateModuleTimestamp(ModuleFile &MF) {
+  // Overwrite the timestamp file contents so that file's mtime changes.
+  std::string TimestampFilename = MF.getTimestampFilename();
+  std::string ErrorInfo;
+  llvm::raw_fd_ostream OS(TimestampFilename.c_str(), ErrorInfo,
+                          llvm::sys::fs::F_Text);
+  if (!ErrorInfo.empty())
+    return;
+  OS << "Timestamp file\n";
+}
+
 ASTReader::ASTReadResult ASTReader::ReadAST(const std::string &FileName,
                                             ModuleKind Type,
                                             SourceLocation ImportLoc,
@@ -2906,13 +3450,16 @@
   llvm::SaveAndRestore<SourceLocation>
     SetCurImportLocRAII(CurrentImportLoc, ImportLoc);
 
+  // Defer any pending actions until we get to the end of reading the AST file.
+  Deserializing AnASTFile(this);
+
   // Bump the generation number.
-  unsigned PreviousGeneration = CurrentGeneration++;
+  unsigned PreviousGeneration = incrementGeneration(Context);
 
   unsigned NumModules = ModuleMgr.size();
   SmallVector<ImportedModule, 4> Loaded;
   switch(ASTReadResult ReadResult = ReadASTCore(FileName, Type, ImportLoc,
-                                                /*ImportedBy=*/0, Loaded,
+                                                /*ImportedBy=*/nullptr, Loaded,
                                                 0, 0,
                                                 ClientLoadCapabilities)) {
   case Failure:
@@ -2920,18 +3467,23 @@
   case OutOfDate:
   case VersionMismatch:
   case ConfigurationMismatch:
-  case HadErrors:
+  case HadErrors: {
+    llvm::SmallPtrSet<ModuleFile *, 4> LoadedSet;
+    for (const ImportedModule &IM : Loaded)
+      LoadedSet.insert(IM.Mod);
+
     ModuleMgr.removeModules(ModuleMgr.begin() + NumModules, ModuleMgr.end(),
+                            LoadedSet,
                             Context.getLangOpts().Modules
                               ? &PP.getHeaderSearchInfo().getModuleMap()
-                              : 0);
+                              : nullptr);
 
     // If we find that any modules are unusable, the global index is going
     // to be out-of-date. Just remove it.
     GlobalIndex.reset();
-    ModuleMgr.setGlobalIndex(0);
+    ModuleMgr.setGlobalIndex(nullptr);
     return ReadResult;
-
+  }
   case Success:
     break;
   }
@@ -2945,8 +3497,8 @@
     ModuleFile &F = *M->Mod;
 
     // Read the AST block.
-    if (ReadASTBlock(F))
-      return Failure;
+    if (ASTReadResult Result = ReadASTBlock(F, ClientLoadCapabilities))
+      return Result;
 
     // Once read, set the ModuleFile bit base offset and update the size in 
     // bits of all files we've seen.
@@ -3057,6 +3609,21 @@
                        PreviousGeneration);
   }
 
+  if (PP.getHeaderSearchInfo()
+          .getHeaderSearchOpts()
+          .ModulesValidateOncePerBuildSession) {
+    // Now we are certain that the module and all modules it depends on are
+    // up to date.  Create or update timestamp files for modules that are
+    // located in the module cache (not for PCH files that could be anywhere
+    // in the filesystem).
+    for (unsigned I = 0, N = Loaded.size(); I != N; ++I) {
+      ImportedModule &M = Loaded[I];
+      if (M.Mod->Kind == MK_Module) {
+        updateModuleTimestamp(*M.Mod);
+      }
+    }
+  }
+
   return Success;
 }
 
@@ -3072,7 +3639,7 @@
   std::string ErrorStr;
   ModuleManager::AddModuleResult AddResult
     = ModuleMgr.addModule(FileName, Type, ImportLoc, ImportedBy,
-                          CurrentGeneration, ExpectedSize, ExpectedModTime,
+                          getGeneration(), ExpectedSize, ExpectedModTime,
                           M, ErrorStr);
 
   switch (AddResult) {
@@ -3162,7 +3729,7 @@
       break;
     case CONTROL_BLOCK_ID:
       HaveReadControlBlock = true;
-      switch (ReadControlBlock(F, Loaded, ClientLoadCapabilities)) {
+      switch (ReadControlBlock(F, Loaded, ImportedBy, ClientLoadCapabilities)) {
       case Success:
         break;
 
@@ -3177,7 +3744,7 @@
     case AST_BLOCK_ID:
       if (!HaveReadControlBlock) {
         if ((ClientLoadCapabilities & ARR_VersionMismatch) == 0)
-          Diag(diag::warn_pch_version_too_old);
+          Diag(diag::err_pch_version_too_old);
         return VersionMismatch;
       }
 
@@ -3203,11 +3770,6 @@
     DeserializationListener->DeclRead(PREDEF_DECL_TRANSLATION_UNIT_ID, 
                                       Context.getTranslationUnitDecl());
 
-  // Make sure we load the declaration update records for the translation unit,
-  // if there are any.
-  loadDeclUpdateRecords(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.
   
@@ -3323,24 +3885,26 @@
     Context.setcudaConfigureCallDecl(
                            cast<FunctionDecl>(GetDecl(CUDASpecialDeclRefs[0])));
   }
-  
+
   // Re-export any modules that were imported by a non-module AST file.
-  for (unsigned I = 0, N = ImportedModules.size(); I != N; ++I) {
-    if (Module *Imported = getSubmodule(ImportedModules[I]))
+  // FIXME: This does not make macro-only imports visible again. It also doesn't
+  // make #includes mapped to module imports visible.
+  for (auto &Import : ImportedModules) {
+    if (Module *Imported = getSubmodule(Import.ID))
       makeModuleVisible(Imported, Module::AllVisible,
-                        /*ImportLoc=*/SourceLocation(),
+                        /*ImportLoc=*/Import.ImportLoc,
                         /*Complain=*/false);
   }
   ImportedModules.clear();
 }
 
 void ASTReader::finalizeForWriting() {
-  for (HiddenNamesMapType::iterator Hidden = HiddenNamesMap.begin(),
-                                 HiddenEnd = HiddenNamesMap.end();
-       Hidden != HiddenEnd; ++Hidden) {
-    makeNamesVisible(Hidden->second, Hidden->first);
+  while (!HiddenNamesMap.empty()) {
+    auto HiddenNames = std::move(*HiddenNamesMap.begin());
+    HiddenNamesMap.erase(HiddenNamesMap.begin());
+    makeNamesVisible(HiddenNames.second, HiddenNames.first,
+                     /*FromFinalization*/true);
   }
-  HiddenNamesMap.clear();
 }
 
 /// \brief Given a cursor at the start of an AST file, scan ahead and drop the
@@ -3381,7 +3945,7 @@
                                              DiagnosticsEngine &Diags) {
   // Open the AST file.
   std::string ErrStr;
-  OwningPtr<llvm::MemoryBuffer> Buffer;
+  std::unique_ptr<llvm::MemoryBuffer> Buffer;
   Buffer.reset(FileMgr.getBufferForFile(ASTFileName, &ErrStr));
   if (!Buffer) {
     Diags.Report(diag::err_fe_unable_to_read_pch_file) << ASTFileName << ErrStr;
@@ -3448,18 +4012,18 @@
     {
     }
 
-    virtual bool ReadLanguageOptions(const LangOptions &LangOpts,
-                                     bool Complain) {
-      return checkLanguageOptions(ExistingLangOpts, LangOpts, 0);
+    bool ReadLanguageOptions(const LangOptions &LangOpts,
+                             bool Complain) override {
+      return checkLanguageOptions(ExistingLangOpts, LangOpts, nullptr);
     }
-    virtual bool ReadTargetOptions(const TargetOptions &TargetOpts,
-                                   bool Complain) {
-      return checkTargetOptions(ExistingTargetOpts, TargetOpts, 0);
+    bool ReadTargetOptions(const TargetOptions &TargetOpts,
+                           bool Complain) override {
+      return checkTargetOptions(ExistingTargetOpts, TargetOpts, nullptr);
     }
-    virtual bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
-                                         bool Complain,
-                                         std::string &SuggestedPredefines) {
-      return checkPreprocessorOptions(ExistingPPOpts, PPOpts, 0, FileMgr,
+    bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
+                                 bool Complain,
+                                 std::string &SuggestedPredefines) override {
+      return checkPreprocessorOptions(ExistingPPOpts, PPOpts, nullptr, FileMgr,
                                       SuggestedPredefines, ExistingLangOpts);
     }
   };
@@ -3470,7 +4034,7 @@
                                         ASTReaderListener &Listener) {
   // Open the AST file.
   std::string ErrStr;
-  OwningPtr<llvm::MemoryBuffer> Buffer;
+  std::unique_ptr<llvm::MemoryBuffer> Buffer;
   Buffer.reset(FileMgr.getBufferForFile(Filename, &ErrStr));
   if (!Buffer) {
     return true;
@@ -3496,6 +4060,7 @@
     return true;
 
   bool NeedsInputFiles = Listener.needsInputFileVisitation();
+  bool NeedsSystemInputFiles = Listener.needsSystemInputFileVisitation();
   BitstreamCursor InputFilesCursor;
   if (NeedsInputFiles) {
     InputFilesCursor = Stream;
@@ -3539,6 +4104,12 @@
       
       break;
     }
+    case MODULE_NAME:
+      Listener.ReadModuleName(Blob);
+      break;
+    case MODULE_MAP_FILE:
+      Listener.ReadModuleMapFile(Blob);
+      break;
     case LANGUAGE_OPTIONS:
       if (ParseLanguageOptions(Record, false, Listener))
         return true;
@@ -3582,6 +4153,10 @@
       for (unsigned I = 0; I != NumInputFiles; ++I) {
         // Go find this input file.
         bool isSystemFile = I >= NumUserFiles;
+
+        if (isSystemFile && !NeedsSystemInputFiles)
+          break; // the rest are system input files
+
         BitstreamCursor &Cursor = InputFilesCursor;
         SavedStreamPosition SavedPosition(Cursor);
         Cursor.JumpToBit(InputFileOffs[I]);
@@ -3592,7 +4167,8 @@
         bool shouldContinue = false;
         switch ((InputFileRecordTypes)Cursor.readRecord(Code, Record, &Blob)) {
         case INPUT_FILE:
-          shouldContinue = Listener.visitInputFile(Blob, isSystemFile);
+          bool Overridden = static_cast<bool>(Record[3]);
+          shouldContinue = Listener.visitInputFile(Blob, isSystemFile, Overridden);
           break;
         }
         if (!shouldContinue)
@@ -3618,16 +4194,17 @@
   return !readASTFileControlBlock(Filename, FileMgr, validator);
 }
 
-bool ASTReader::ReadSubmoduleBlock(ModuleFile &F) {
+ASTReader::ASTReadResult
+ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
   // Enter the submodule block.
   if (F.Stream.EnterSubBlock(SUBMODULE_BLOCK_ID)) {
     Error("malformed submodule block record in AST file");
-    return true;
+    return Failure;
   }
 
   ModuleMap &ModMap = PP.getHeaderSearchInfo().getModuleMap();
   bool First = true;
-  Module *CurrentModule = 0;
+  Module *CurrentModule = nullptr;
   RecordData Record;
   while (true) {
     llvm::BitstreamEntry Entry = F.Stream.advanceSkippingSubblocks();
@@ -3636,9 +4213,9 @@
     case llvm::BitstreamEntry::SubBlock: // Handled for us already.
     case llvm::BitstreamEntry::Error:
       Error("malformed block record in AST file");
-      return true;
+      return Failure;
     case llvm::BitstreamEntry::EndBlock:
-      return false;
+      return Success;
     case llvm::BitstreamEntry::Record:
       // The interesting case.
       break;
@@ -3654,39 +4231,47 @@
     case SUBMODULE_DEFINITION: {
       if (First) {
         Error("missing submodule metadata record at beginning of block");
-        return true;
+        return Failure;
       }
 
       if (Record.size() < 8) {
         Error("malformed module definition");
-        return true;
+        return Failure;
       }
       
       StringRef Name = Blob;
-      SubmoduleID GlobalID = getGlobalSubmoduleID(F, Record[0]);
-      SubmoduleID Parent = getGlobalSubmoduleID(F, Record[1]);
-      bool IsFramework = Record[2];
-      bool IsExplicit = Record[3];
-      bool IsSystem = Record[4];
-      bool InferSubmodules = Record[5];
-      bool InferExplicitSubmodules = Record[6];
-      bool InferExportWildcard = Record[7];
-      bool ConfigMacrosExhaustive = Record[8];
+      unsigned Idx = 0;
+      SubmoduleID GlobalID = getGlobalSubmoduleID(F, Record[Idx++]);
+      SubmoduleID Parent = getGlobalSubmoduleID(F, Record[Idx++]);
+      bool IsFramework = Record[Idx++];
+      bool IsExplicit = Record[Idx++];
+      bool IsSystem = Record[Idx++];
+      bool IsExternC = Record[Idx++];
+      bool InferSubmodules = Record[Idx++];
+      bool InferExplicitSubmodules = Record[Idx++];
+      bool InferExportWildcard = Record[Idx++];
+      bool ConfigMacrosExhaustive = Record[Idx++];
 
-      Module *ParentModule = 0;
-      if (Parent)
+      Module *ParentModule = nullptr;
+      const FileEntry *ModuleMap = nullptr;
+      if (Parent) {
         ParentModule = getSubmodule(Parent);
-      
+        ModuleMap = ParentModule->ModuleMap;
+      }
+
+      if (!F.ModuleMapPath.empty())
+        ModuleMap = FileMgr.getFile(F.ModuleMapPath);
+
       // Retrieve this (sub)module from the module map, creating it if
       // necessary.
-      CurrentModule = ModMap.findOrCreateModule(Name, ParentModule, 
+      CurrentModule = ModMap.findOrCreateModule(Name, ParentModule, ModuleMap,
                                                 IsFramework, 
                                                 IsExplicit).first;
       SubmoduleID GlobalIndex = GlobalID - NUM_PREDEF_SUBMODULE_IDS;
       if (GlobalIndex >= SubmodulesLoaded.size() ||
           SubmodulesLoaded[GlobalIndex]) {
         Error("too many submodules");
-        return true;
+        return Failure;
       }
 
       if (!ParentModule) {
@@ -3698,15 +4283,16 @@
                 << CurFile->getName()
                 << F.File->getName();
             }
-            return true;
+            return Failure;
           }
         }
 
         CurrentModule->setASTFile(F.File);
       }
-      
+
       CurrentModule->IsFromModuleFile = true;
       CurrentModule->IsSystem = IsSystem || CurrentModule->IsSystem;
+      CurrentModule->IsExternC = IsExternC;
       CurrentModule->InferSubmodules = InferSubmodules;
       CurrentModule->InferExplicitSubmodules = InferExplicitSubmodules;
       CurrentModule->InferExportWildcard = InferExportWildcard;
@@ -3727,7 +4313,7 @@
     case SUBMODULE_UMBRELLA_HEADER: {
       if (First) {
         Error("missing submodule metadata record at beginning of block");
-        return true;
+        return Failure;
       }
 
       if (!CurrentModule)
@@ -3737,8 +4323,9 @@
         if (!CurrentModule->getUmbrellaHeader())
           ModMap.setUmbrellaHeader(CurrentModule, Umbrella);
         else if (CurrentModule->getUmbrellaHeader() != Umbrella) {
-          Error("mismatched umbrella headers in submodule");
-          return true;
+          if ((ClientLoadCapabilities & ARR_OutOfDate) == 0)
+            Error("mismatched umbrella headers in submodule");
+          return OutOfDate;
         }
       }
       break;
@@ -3747,7 +4334,7 @@
     case SUBMODULE_HEADER: {
       if (First) {
         Error("missing submodule metadata record at beginning of block");
-        return true;
+        return Failure;
       }
 
       if (!CurrentModule)
@@ -3762,7 +4349,7 @@
     case SUBMODULE_EXCLUDED_HEADER: {
       if (First) {
         Error("missing submodule metadata record at beginning of block");
-        return true;
+        return Failure;
       }
 
       if (!CurrentModule)
@@ -3777,7 +4364,7 @@
     case SUBMODULE_PRIVATE_HEADER: {
       if (First) {
         Error("missing submodule metadata record at beginning of block");
-        return true;
+        return Failure;
       }
 
       if (!CurrentModule)
@@ -3792,7 +4379,7 @@
     case SUBMODULE_TOPHEADER: {
       if (First) {
         Error("missing submodule metadata record at beginning of block");
-        return true;
+        return Failure;
       }
 
       if (!CurrentModule)
@@ -3805,7 +4392,7 @@
     case SUBMODULE_UMBRELLA_DIR: {
       if (First) {
         Error("missing submodule metadata record at beginning of block");
-        return true;
+        return Failure;
       }
       
       if (!CurrentModule)
@@ -3816,8 +4403,9 @@
         if (!CurrentModule->getUmbrellaDir())
           ModMap.setUmbrellaDir(CurrentModule, Umbrella);
         else if (CurrentModule->getUmbrellaDir() != Umbrella) {
-          Error("mismatched umbrella directories in submodule");
-          return true;
+          if ((ClientLoadCapabilities & ARR_OutOfDate) == 0)
+            Error("mismatched umbrella directories in submodule");
+          return OutOfDate;
         }
       }
       break;
@@ -3826,7 +4414,7 @@
     case SUBMODULE_METADATA: {
       if (!First) {
         Error("submodule metadata record not at beginning of block");
-        return true;
+        return Failure;
       }
       First = false;
       
@@ -3852,7 +4440,7 @@
     case SUBMODULE_IMPORTS: {
       if (First) {
         Error("missing submodule metadata record at beginning of block");
-        return true;
+        return Failure;
       }
       
       if (!CurrentModule)
@@ -3873,7 +4461,7 @@
     case SUBMODULE_EXPORTS: {
       if (First) {
         Error("missing submodule metadata record at beginning of block");
-        return true;
+        return Failure;
       }
       
       if (!CurrentModule)
@@ -3897,7 +4485,7 @@
     case SUBMODULE_REQUIRES: {
       if (First) {
         Error("missing submodule metadata record at beginning of block");
-        return true;
+        return Failure;
       }
 
       if (!CurrentModule)
@@ -3911,7 +4499,7 @@
     case SUBMODULE_LINK_LIBRARY:
       if (First) {
         Error("missing submodule metadata record at beginning of block");
-        return true;
+        return Failure;
       }
 
       if (!CurrentModule)
@@ -3924,7 +4512,7 @@
     case SUBMODULE_CONFIG_MACRO:
       if (First) {
         Error("missing submodule metadata record at beginning of block");
-        return true;
+        return Failure;
       }
 
       if (!CurrentModule)
@@ -3936,7 +4524,7 @@
     case SUBMODULE_CONFLICT: {
       if (First) {
         Error("missing submodule metadata record at beginning of block");
-        return true;
+        return Failure;
       }
 
       if (!CurrentModule)
@@ -4004,8 +4592,6 @@
   TargetOpts.Triple = ReadString(Record, Idx);
   TargetOpts.CPU = ReadString(Record, Idx);
   TargetOpts.ABI = ReadString(Record, Idx);
-  TargetOpts.CXXABI = ReadString(Record, Idx);
-  TargetOpts.LinkerVersion = ReadString(Record, Idx);
   for (unsigned N = Record[Idx++]; N; --N) {
     TargetOpts.FeaturesAsWritten.push_back(ReadString(Record, Idx));
   }
@@ -4018,16 +4604,17 @@
 
 bool ASTReader::ParseDiagnosticOptions(const RecordData &Record, bool Complain,
                                        ASTReaderListener &Listener) {
-  DiagnosticOptions DiagOpts;
+  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts(new DiagnosticOptions);
   unsigned Idx = 0;
-#define DIAGOPT(Name, Bits, Default) DiagOpts.Name = Record[Idx++];
+#define DIAGOPT(Name, Bits, Default) DiagOpts->Name = Record[Idx++];
 #define ENUM_DIAGOPT(Name, Type, Bits, Default) \
-  DiagOpts.set##Name(static_cast<Type>(Record[Idx++]));
+  DiagOpts->set##Name(static_cast<Type>(Record[Idx++]));
 #include "clang/Basic/DiagnosticOptions.def"
 
-  for (unsigned N = Record[Idx++]; N; --N) {
-    DiagOpts.Warnings.push_back(ReadString(Record, Idx));
-  }
+  for (unsigned N = Record[Idx++]; N; --N)
+    DiagOpts->Warnings.push_back(ReadString(Record, Idx));
+  for (unsigned N = Record[Idx++]; N; --N)
+    DiagOpts->Remarks.push_back(ReadString(Record, Idx));
 
   return Listener.ReadDiagnosticOptions(DiagOpts, Complain);
 }
@@ -4068,6 +4655,7 @@
 
   HSOpts.ResourceDir = ReadString(Record, Idx);
   HSOpts.ModuleCachePath = ReadString(Record, Idx);
+  HSOpts.ModuleUserBuildPath = ReadString(Record, Idx);
   HSOpts.DisableModuleHash = Record[Idx++];
   HSOpts.UseBuiltinIncludes = Record[Idx++];
   HSOpts.UseStandardSystemIncludes = Record[Idx++];
@@ -4149,7 +4737,7 @@
 
   if (!PP.getPreprocessingRecord()) {
     Error("no preprocessing record");
-    return 0;
+    return nullptr;
   }
   
   SavedStreamPosition SavedPosition(M.PreprocessorDetailCursor);  
@@ -4158,7 +4746,7 @@
   llvm::BitstreamEntry Entry =
     M.PreprocessorDetailCursor.advance(BitstreamCursor::AF_DontPopBlockAtEnd);
   if (Entry.Kind != llvm::BitstreamEntry::Record)
-    return 0;
+    return nullptr;
 
   // Read the record.
   SourceRange Range(ReadSourceLocation(M, PPOffs.Begin),
@@ -4172,8 +4760,8 @@
   switch (RecType) {
   case PPD_MACRO_EXPANSION: {
     bool isBuiltin = Record[0];
-    IdentifierInfo *Name = 0;
-    MacroDefinition *Def = 0;
+    IdentifierInfo *Name = nullptr;
+    MacroDefinition *Def = nullptr;
     if (isBuiltin)
       Name = getLocalIdentifier(M, Record[1]);
     else {
@@ -4207,7 +4795,7 @@
   case PPD_INCLUSION_DIRECTIVE: {
     const char *FullFileNameStart = Blob.data() + Record[0];
     StringRef FullFileName(FullFileNameStart, Blob.size() - Record[0]);
-    const FileEntry *File = 0;
+    const FileEntry *File = nullptr;
     if (!FullFileName.empty())
       File = PP.getFileManager().getFile(FullFileName);
     
@@ -4276,15 +4864,13 @@
 
 }
 
-/// \brief Returns the first preprocessed entity ID that ends after \arg BLoc.
-PreprocessedEntityID
-ASTReader::findBeginPreprocessedEntity(SourceLocation BLoc) const {
-  if (SourceMgr.isLocalSourceLocation(BLoc))
+PreprocessedEntityID ASTReader::findPreprocessedEntity(SourceLocation Loc,
+                                                       bool EndsAfter) const {
+  if (SourceMgr.isLocalSourceLocation(Loc))
     return getTotalNumPreprocessedEntities();
 
-  GlobalSLocOffsetMapType::const_iterator
-    SLocMapI = GlobalSLocOffsetMap.find(SourceManager::MaxLoadedOffset -
-                                        BLoc.getOffset() - 1);
+  GlobalSLocOffsetMapType::const_iterator SLocMapI = GlobalSLocOffsetMap.find(
+      SourceManager::MaxLoadedOffset - Loc.getOffset() - 1);
   assert(SLocMapI != GlobalSLocOffsetMap.end() &&
          "Corrupted global sloc offset map");
 
@@ -4301,21 +4887,26 @@
   pp_iterator First = pp_begin;
   pp_iterator PPI;
 
-  // Do a binary search manually instead of using std::lower_bound because
-  // The end locations of entities may be unordered (when a macro expansion
-  // is inside another macro argument), but for this case it is not important
-  // whether we get the first macro expansion or its containing macro.
-  while (Count > 0) {
-    Half = Count/2;
-    PPI = First;
-    std::advance(PPI, Half);
-    if (SourceMgr.isBeforeInTranslationUnit(ReadSourceLocation(M, PPI->End),
-                                            BLoc)){
-      First = PPI;
-      ++First;
-      Count = Count - Half - 1;
-    } else
-      Count = Half;
+  if (EndsAfter) {
+    PPI = std::upper_bound(pp_begin, pp_end, Loc,
+                           PPEntityComp<&PPEntityOffset::Begin>(*this, M));
+  } else {
+    // Do a binary search manually instead of using std::lower_bound because
+    // The end locations of entities may be unordered (when a macro expansion
+    // is inside another macro argument), but for this case it is not important
+    // whether we get the first macro expansion or its containing macro.
+    while (Count > 0) {
+      Half = Count / 2;
+      PPI = First;
+      std::advance(PPI, Half);
+      if (SourceMgr.isBeforeInTranslationUnit(ReadSourceLocation(M, PPI->End),
+                                              Loc)) {
+        First = PPI;
+        ++First;
+        Count = Count - Half - 1;
+      } else
+        Count = Half;
+    }
   }
 
   if (PPI == pp_end)
@@ -4324,35 +4915,6 @@
   return M.BasePreprocessedEntityID + (PPI - pp_begin);
 }
 
-/// \brief Returns the first preprocessed entity ID that begins after \arg ELoc.
-PreprocessedEntityID
-ASTReader::findEndPreprocessedEntity(SourceLocation ELoc) const {
-  if (SourceMgr.isLocalSourceLocation(ELoc))
-    return getTotalNumPreprocessedEntities();
-
-  GlobalSLocOffsetMapType::const_iterator
-    SLocMapI = GlobalSLocOffsetMap.find(SourceManager::MaxLoadedOffset -
-                                        ELoc.getOffset() - 1);
-  assert(SLocMapI != GlobalSLocOffsetMap.end() &&
-         "Corrupted global sloc offset map");
-
-  if (SLocMapI->second->NumPreprocessedEntities == 0)
-    return findNextPreprocessedEntity(SLocMapI);
-
-  ModuleFile &M = *SLocMapI->second;
-  typedef const PPEntityOffset *pp_iterator;
-  pp_iterator pp_begin = M.PreprocessedEntityOffsets;
-  pp_iterator pp_end = pp_begin + M.NumPreprocessedEntities;
-  pp_iterator PPI =
-      std::upper_bound(pp_begin, pp_end, ELoc,
-                       PPEntityComp<&PPEntityOffset::Begin>(*this, M));
-
-  if (PPI == pp_end)
-    return findNextPreprocessedEntity(SLocMapI);
-
-  return M.BasePreprocessedEntityID + (PPI - pp_begin);
-}
-
 /// \brief Returns a pair of [Begin, End) indices of preallocated
 /// preprocessed entities that \arg Range encompasses.
 std::pair<unsigned, unsigned>
@@ -4361,8 +4923,9 @@
     return std::make_pair(0,0);
   assert(!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(),Range.getBegin()));
 
-  PreprocessedEntityID BeginID = findBeginPreprocessedEntity(Range.getBegin());
-  PreprocessedEntityID EndID = findEndPreprocessedEntity(Range.getEnd());
+  PreprocessedEntityID BeginID =
+      findPreprocessedEntity(Range.getBegin(), false);
+  PreprocessedEntityID EndID = findPreprocessedEntity(Range.getEnd(), true);
   return std::make_pair(BeginID, EndID);
 }
 
@@ -4468,9 +5031,9 @@
         if (DiagID == (unsigned)-1) {
           break; // no more diag/map pairs for this location.
         }
-        diag::Mapping Map = (diag::Mapping)F.PragmaDiagMappings[Idx++];
-        DiagnosticMappingInfo MappingInfo = Diag.makeMappingInfo(Map, Loc);
-        Diag.GetCurDiagState()->setMappingInfo(DiagID, MappingInfo);
+        diag::Severity Map = (diag::Severity)F.PragmaDiagMappings[Idx++];
+        DiagnosticMapping Mapping = Diag.makeUserMapping(Map, Loc);
+        Diag.GetCurDiagState()->setMapping(DiagID, Mapping);
       }
     }
   }
@@ -4548,6 +5111,16 @@
     return DT;
   }
 
+  case TYPE_ADJUSTED: {
+    if (Record.size() != 2) {
+      Error("Incorrect encoding of adjusted type");
+      return QualType();
+    }
+    QualType OriginalTy = readType(*Loc.F, Record, Idx);
+    QualType AdjustedTy = readType(*Loc.F, Record, Idx);
+    return Context.getAdjustedType(OriginalTy, AdjustedTy);
+  }
+
   case TYPE_BLOCK_POINTER: {
     if (Record.size() != 1) {
       Error("Incorrect encoding of block pointer type");
@@ -4671,23 +5244,8 @@
     EPI.HasTrailingReturn = Record[Idx++];
     EPI.TypeQuals = Record[Idx++];
     EPI.RefQualifier = static_cast<RefQualifierKind>(Record[Idx++]);
-    ExceptionSpecificationType EST =
-        static_cast<ExceptionSpecificationType>(Record[Idx++]);
-    EPI.ExceptionSpecType = EST;
-    SmallVector<QualType, 2> Exceptions;
-    if (EST == EST_Dynamic) {
-      EPI.NumExceptions = Record[Idx++];
-      for (unsigned I = 0; I != EPI.NumExceptions; ++I)
-        Exceptions.push_back(readType(*Loc.F, Record, Idx));
-      EPI.Exceptions = Exceptions.data();
-    } else if (EST == EST_ComputedNoexcept) {
-      EPI.NoexceptExpr = ReadExpr(*Loc.F);
-    } else if (EST == EST_Uninstantiated) {
-      EPI.ExceptionSpecDecl = ReadDeclAs<FunctionDecl>(*Loc.F, Record, Idx);
-      EPI.ExceptionSpecTemplate = ReadDeclAs<FunctionDecl>(*Loc.F, Record, Idx);
-    } else if (EST == EST_Unevaluated) {
-      EPI.ExceptionSpecDecl = ReadDeclAs<FunctionDecl>(*Loc.F, Record, Idx);
-    }
+    SmallVector<QualType, 8> ExceptionStorage;
+    readExceptionSpec(*Loc.F, ExceptionStorage, EPI, Record, Idx);
     return Context.getFunctionType(ResultType, ParamTypes, EPI);
   }
 
@@ -4837,9 +5395,9 @@
     unsigned Idx = 0;
     QualType Parm = readType(*Loc.F, Record, Idx);
     QualType Replacement = readType(*Loc.F, Record, Idx);
-    return
-      Context.getSubstTemplateTypeParmType(cast<TemplateTypeParmType>(Parm),
-                                            Replacement);
+    return Context.getSubstTemplateTypeParmType(
+        cast<TemplateTypeParmType>(Parm),
+        Context.getCanonicalType(Replacement));
   }
 
   case TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK: {
@@ -4856,8 +5414,14 @@
     QualType TST = readType(*Loc.F, Record, Idx); // probably derivable
     // FIXME: ASTContext::getInjectedClassNameType is not currently suitable
     // for AST reading, too much interdependencies.
-    return
-      QualType(new (Context, TypeAlignment) InjectedClassNameType(D, TST), 0);
+    const Type *T;
+    if (const Type *Existing = D->getTypeForDecl())
+      T = Existing;
+    else if (auto *Prev = D->getPreviousDecl())
+      T = Prev->getTypeForDecl();
+    else
+      T = new (Context, TypeAlignment) InjectedClassNameType(D, TST);
+    return QualType(T, 0);
   }
 
   case TYPE_TEMPLATE_TYPE_PARM: {
@@ -4942,6 +5506,29 @@
   llvm_unreachable("Invalid TypeCode!");
 }
 
+void ASTReader::readExceptionSpec(ModuleFile &ModuleFile,
+                                  SmallVectorImpl<QualType> &Exceptions,
+                                  FunctionProtoType::ExtProtoInfo &EPI,
+                                  const RecordData &Record, unsigned &Idx) {
+  ExceptionSpecificationType EST =
+      static_cast<ExceptionSpecificationType>(Record[Idx++]);
+  EPI.ExceptionSpecType = EST;
+  if (EST == EST_Dynamic) {
+    EPI.NumExceptions = Record[Idx++];
+    for (unsigned I = 0; I != EPI.NumExceptions; ++I)
+      Exceptions.push_back(readType(ModuleFile, Record, Idx));
+    EPI.Exceptions = Exceptions.data();
+  } else if (EST == EST_ComputedNoexcept) {
+    EPI.NoexceptExpr = ReadExpr(ModuleFile);
+  } else if (EST == EST_Uninstantiated) {
+    EPI.ExceptionSpecDecl = ReadDeclAs<FunctionDecl>(ModuleFile, Record, Idx);
+    EPI.ExceptionSpecTemplate =
+        ReadDeclAs<FunctionDecl>(ModuleFile, Record, Idx);
+  } else if (EST == EST_Unevaluated) {
+    EPI.ExceptionSpecDecl = ReadDeclAs<FunctionDecl>(ModuleFile, Record, Idx);
+  }
+}
+
 class clang::TypeLocReader : public TypeLocVisitor<TypeLocReader> {
   ASTReader &Reader;
   ModuleFile &F;
@@ -4997,6 +5584,9 @@
 void TypeLocReader::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
   // nothing to do
 }
+void TypeLocReader::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
+  // nothing to do
+}
 void TypeLocReader::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
   TL.setCaretLoc(ReadSourceLocation(Record, Idx));
 }
@@ -5016,7 +5606,7 @@
   if (Record[Idx++])
     TL.setSizeExpr(Reader.ReadExpr(F));
   else
-    TL.setSizeExpr(0);
+    TL.setSizeExpr(nullptr);
 }
 void TypeLocReader::VisitConstantArrayTypeLoc(ConstantArrayTypeLoc TL) {
   VisitArrayTypeLoc(TL);
@@ -5046,8 +5636,8 @@
   TL.setLParenLoc(ReadSourceLocation(Record, Idx));
   TL.setRParenLoc(ReadSourceLocation(Record, Idx));
   TL.setLocalRangeEnd(ReadSourceLocation(Record, Idx));
-  for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {
-    TL.setArg(i, ReadDeclAs<ParmVarDecl>(Record, Idx));
+  for (unsigned i = 0, e = TL.getNumParams(); i != e; ++i) {
+    TL.setParam(i, ReadDeclAs<ParmVarDecl>(Record, Idx));
   }
 }
 void TypeLocReader::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) {
@@ -5103,7 +5693,7 @@
     if (Record[Idx++])
       TL.setAttrExprOperand(Reader.ReadExpr(F));
     else
-      TL.setAttrExprOperand(0);
+      TL.setAttrExprOperand(nullptr);
   } else if (TL.hasAttrEnumOperand())
     TL.setAttrEnumOperandLoc(ReadSourceLocation(Record, Idx));
 }
@@ -5187,7 +5777,7 @@
                                              unsigned &Idx) {
   QualType InfoTy = readType(F, Record, Idx);
   if (InfoTy.isNull())
-    return 0;
+    return nullptr;
 
   TypeSourceInfo *TInfo = getContext().CreateTypeSourceInfo(InfoTy);
   TypeLocReader TLR(*this, F, Record, Idx);
@@ -5374,11 +5964,54 @@
   return GetDecl(ID);
 }
 
-uint64_t ASTReader::readCXXBaseSpecifiers(ModuleFile &M, const RecordData &Record, 
-                                          unsigned &Idx){
-  if (Idx >= Record.size())
+void ASTReader::CompleteRedeclChain(const Decl *D) {
+  if (NumCurrentElementsDeserializing) {
+    // We arrange to not care about the complete redeclaration chain while we're
+    // deserializing. Just remember that the AST has marked this one as complete
+    // but that it's not actually complete yet, so we know we still need to
+    // complete it later.
+    PendingIncompleteDeclChains.push_back(const_cast<Decl*>(D));
+    return;
+  }
+
+  const DeclContext *DC = D->getDeclContext()->getRedeclContext();
+
+  // Recursively ensure that the decl context itself is complete
+  // (in particular, this matters if the decl context is a namespace).
+  //
+  // FIXME: This should be performed by lookup instead of here.
+  cast<Decl>(DC)->getMostRecentDecl();
+
+  // If this is a named declaration, complete it by looking it up
+  // within its context.
+  //
+  // FIXME: We don't currently handle the cases where we can't do this;
+  // merging a class definition that contains unnamed entities should merge
+  // those entities. Likewise, merging a function definition should merge
+  // all mergeable entities within it.
+  if (isa<TranslationUnitDecl>(DC) || isa<NamespaceDecl>(DC) ||
+      isa<CXXRecordDecl>(DC) || isa<EnumDecl>(DC)) {
+    if (DeclarationName Name = cast<NamedDecl>(D)->getDeclName()) {
+      auto *II = Name.getAsIdentifierInfo();
+      if (isa<TranslationUnitDecl>(DC) && II) {
+        // Outside of C++, we don't have a lookup table for the TU, so update
+        // the identifier instead. In C++, either way should work fine.
+        if (II->isOutOfDate())
+          updateOutOfDateIdentifier(*II);
+      } else
+        DC->lookup(Name);
+    }
+  }
+}
+
+uint64_t ASTReader::readCXXBaseSpecifiers(ModuleFile &M,
+                                          const RecordData &Record,
+                                          unsigned &Idx) {
+  if (Idx >= Record.size() || Record[Idx] > M.LocalNumCXXBaseSpecifiers) {
+    Error("malformed AST file: missing C++ base specifier");
     return 0;
-  
+  }
+
   unsigned LocalID = Record[Idx++];
   return getGlobalBitOffset(M, M.CXXBaseSpecifiersOffsets[LocalID - 1]);
 }
@@ -5393,8 +6026,8 @@
   unsigned Code = Cursor.ReadCode();
   unsigned RecCode = Cursor.readRecord(Code, Record);
   if (RecCode != DECL_CXX_BASE_SPECIFIERS) {
-    Error("Malformed AST file: missing C++ base specifiers");
-    return 0;
+    Error("malformed AST file: missing C++ base specifiers");
+    return nullptr;
   }
 
   unsigned Idx = 0;
@@ -5427,7 +6060,7 @@
 
 ModuleFile *ASTReader::getOwningModuleFile(const Decl *D) {
   if (!D->isFromASTFile())
-    return 0;
+    return nullptr;
   GlobalDeclMapType::const_iterator I = GlobalDeclMap.find(D->getGlobalID());
   assert(I != GlobalDeclMap.end() && "Corrupted global declaration map");
   return I->second;
@@ -5436,14 +6069,14 @@
 SourceLocation ASTReader::getSourceLocationForDeclID(GlobalDeclID ID) {
   if (ID < NUM_PREDEF_DECL_IDS)
     return SourceLocation();
-  
+
   unsigned Index = ID - NUM_PREDEF_DECL_IDS;
 
   if (Index > DeclsLoaded.size()) {
     Error("declaration ID out-of-range for AST file");
     return SourceLocation();
   }
-  
+
   if (Decl *D = DeclsLoaded[Index])
     return D->getLocation();
 
@@ -5452,15 +6085,15 @@
   return ReadSourceLocation(*Rec.F, RawLocation);
 }
 
-Decl *ASTReader::GetDecl(DeclID ID) {
-  if (ID < NUM_PREDEF_DECL_IDS) {    
+Decl *ASTReader::GetExistingDecl(DeclID ID) {
+  if (ID < NUM_PREDEF_DECL_IDS) {
     switch ((PredefinedDeclIDs)ID) {
     case PREDEF_DECL_NULL_ID:
-      return 0;
-        
+      return nullptr;
+
     case PREDEF_DECL_TRANSLATION_UNIT_ID:
       return Context.getTranslationUnitDecl();
-        
+
     case PREDEF_DECL_OBJC_ID_ID:
       return Context.getObjCIdDecl();
 
@@ -5469,16 +6102,16 @@
 
     case PREDEF_DECL_OBJC_CLASS_ID:
       return Context.getObjCClassDecl();
-        
+
     case PREDEF_DECL_OBJC_PROTOCOL_ID:
       return Context.getObjCProtocolDecl();
-        
+
     case PREDEF_DECL_INT_128_ID:
       return Context.getInt128Decl();
 
     case PREDEF_DECL_UNSIGNED_INT_128_ID:
       return Context.getUInt128Decl();
-        
+
     case PREDEF_DECL_OBJC_INSTANCETYPE_ID:
       return Context.getObjCInstanceTypeDecl();
 
@@ -5486,15 +6119,30 @@
       return Context.getBuiltinVaListDecl();
     }
   }
-  
+
   unsigned Index = ID - NUM_PREDEF_DECL_IDS;
 
   if (Index >= DeclsLoaded.size()) {
     assert(0 && "declaration ID out-of-range for AST file");
     Error("declaration ID out-of-range for AST file");
-    return 0;
+    return nullptr;
   }
-  
+
+  return DeclsLoaded[Index];
+}
+
+Decl *ASTReader::GetDecl(DeclID ID) {
+  if (ID < NUM_PREDEF_DECL_IDS)
+    return GetExistingDecl(ID);
+
+  unsigned Index = ID - NUM_PREDEF_DECL_IDS;
+
+  if (Index >= DeclsLoaded.size()) {
+    assert(0 && "declaration ID out-of-range for AST file");
+    Error("declaration ID out-of-range for AST file");
+    return nullptr;
+  }
+
   if (!DeclsLoaded[Index]) {
     ReadDeclRecord(ID);
     if (DeserializationListener)
@@ -5779,7 +6427,7 @@
   if (const DeclContext *DefDC = getDefinitiveDeclContext(DC))
     return Reader.getOwningModuleFile(cast<Decl>(DefDC));
 
-  return 0;
+  return nullptr;
 }
 
 bool
@@ -5800,14 +6448,19 @@
   Contexts.push_back(DC);
   
   if (DC->isNamespace()) {
-    MergedDeclsMap::iterator Merged
-      = MergedDecls.find(const_cast<Decl *>(cast<Decl>(DC)));
+    auto Merged = MergedDecls.find(const_cast<Decl *>(cast<Decl>(DC)));
     if (Merged != MergedDecls.end()) {
       for (unsigned I = 0, N = Merged->second.size(); I != N; ++I)
         Contexts.push_back(cast<DeclContext>(GetDecl(Merged->second[I])));
     }
   }
-  
+  if (isa<CXXRecordDecl>(DC)) {
+    auto Merged = MergedLookups.find(DC);
+    if (Merged != MergedLookups.end())
+      Contexts.insert(Contexts.end(), Merged->second.begin(),
+                      Merged->second.end());
+  }
+
   DeclContextNameLookupVisitor Visitor(*this, Contexts, Name, Decls);
 
   // If we can definitively determine which module file to look into,
@@ -5924,15 +6577,23 @@
                                        ASTConsumer *Consumer) {
   assert(ImplD && Consumer);
 
-  for (ObjCImplDecl::method_iterator
-         I = ImplD->meth_begin(), E = ImplD->meth_end(); I != E; ++I)
-    Consumer->HandleInterestingDecl(DeclGroupRef(*I));
+  for (auto *I : ImplD->methods())
+    Consumer->HandleInterestingDecl(DeclGroupRef(I));
 
   Consumer->HandleInterestingDecl(DeclGroupRef(ImplD));
 }
 
 void ASTReader::PassInterestingDeclsToConsumer() {
   assert(Consumer);
+
+  if (PassingDeclsToConsumer)
+    return;
+
+  // Guard variable to avoid recursively redoing the process of passing
+  // decls to consumer.
+  SaveAndRestore<bool> GuardPassingDeclsToConsumer(PassingDeclsToConsumer,
+                                                   true);
+
   while (!InterestingDecls.empty()) {
     Decl *D = InterestingDecls.front();
     InterestingDecls.pop_front();
@@ -5954,12 +6615,12 @@
   if (!Consumer)
     return;
 
-  for (unsigned I = 0, N = ExternalDefinitions.size(); I != N; ++I) {
+  for (unsigned I = 0, N = EagerlyDeserializedDecls.size(); I != N; ++I) {
     // Force deserialization of this decl, which will cause it to be queued for
     // passing to the consumer.
-    GetDecl(ExternalDefinitions[I]);
+    GetDecl(EagerlyDeserializedDecls[I]);
   }
-  ExternalDefinitions.clear();
+  EagerlyDeserializedDecls.clear();
 
   PassInterestingDeclsToConsumer();
 }
@@ -5972,15 +6633,15 @@
                                       QualType());
   unsigned NumDeclsLoaded
     = DeclsLoaded.size() - std::count(DeclsLoaded.begin(), DeclsLoaded.end(),
-                                      (Decl *)0);
+                                      (Decl *)nullptr);
   unsigned NumIdentifiersLoaded
     = IdentifiersLoaded.size() - std::count(IdentifiersLoaded.begin(),
                                             IdentifiersLoaded.end(),
-                                            (IdentifierInfo *)0);
+                                            (IdentifierInfo *)nullptr);
   unsigned NumMacrosLoaded
     = MacrosLoaded.size() - std::count(MacrosLoaded.begin(),
                                        MacrosLoaded.end(),
-                                       (MacroInfo *)0);
+                                       (MacroInfo *)nullptr);
   unsigned NumSelectorsLoaded
     = SelectorsLoaded.size() - std::count(SelectorsLoaded.begin(),
                                           SelectorsLoaded.end(),
@@ -6164,6 +6825,11 @@
     }
     SemaDeclRefs.clear();
   }
+
+  // Update the state of 'pragma clang optimize'. Use the same API as if we had
+  // encountered the pragma in the source.
+  if(OptimizeOffPragmaLocation.isValid())
+    SemaObj->ActOnPragmaOptimize(/* IsOn = */ false, OptimizeOffPragmaLocation);
 }
 
 IdentifierInfo* ASTReader::get(const char *NameStart, const char *NameEnd) {
@@ -6174,7 +6840,7 @@
   // If there is a global index, look there first to determine which modules
   // provably do not have any results for this identifier.
   GlobalModuleIndex::HitSet Hits;
-  GlobalModuleIndex::HitSet *HitsPtr = 0;
+  GlobalModuleIndex::HitSet *HitsPtr = nullptr;
   if (!loadGlobalIndex()) {
     if (GlobalIndex->lookupIdentifier(Name, Hits)) {
       HitsPtr = &Hits;
@@ -6211,7 +6877,7 @@
   public:
     explicit ASTIdentifierIterator(const ASTReader &Reader);
 
-    virtual StringRef Next();
+    StringRef Next() override;
   };
 }
 
@@ -6330,7 +6996,7 @@
   // Get the selector generation and update it to the current generation.
   unsigned &Generation = SelectorGeneration[Sel];
   unsigned PriorGeneration = Generation;
-  Generation = CurrentGeneration;
+  Generation = getGeneration();
   
   // Search for methods defined with this selector.
   ++NumMethodPoolLookups;
@@ -6587,11 +7253,11 @@
 
 IdentifierInfo *ASTReader::DecodeIdentifierInfo(IdentifierID ID) {
   if (ID == 0)
-    return 0;
+    return nullptr;
 
   if (IdentifiersLoaded.empty()) {
     Error("no identifier table in AST file");
-    return 0;
+    return nullptr;
   }
 
   ID -= 1;
@@ -6637,11 +7303,11 @@
 
 MacroInfo *ASTReader::getMacro(MacroID ID) {
   if (ID == 0)
-    return 0;
+    return nullptr;
 
   if (MacrosLoaded.empty()) {
     Error("no macro table in AST file");
-    return 0;
+    return nullptr;
   }
 
   ID -= NUM_PREDEF_MACRO_IDS;
@@ -6688,12 +7354,12 @@
 Module *ASTReader::getSubmodule(SubmoduleID GlobalID) {
   if (GlobalID < NUM_PREDEF_SUBMODULE_IDS) {
     assert(GlobalID == 0 && "Unhandled global submodule ID");
-    return 0;
+    return nullptr;
   }
   
   if (GlobalID > SubmodulesLoaded.size()) {
     Error("submodule ID out of range in AST file");
-    return 0;
+    return nullptr;
   }
   
   return SubmodulesLoaded[GlobalID - NUM_PREDEF_SUBMODULE_IDS];
@@ -6716,7 +7382,7 @@
     return Selector();
   }
 
-  if (SelectorsLoaded[ID - 1].getAsOpaquePtr() == 0) {
+  if (SelectorsLoaded[ID - 1].getAsOpaquePtr() == nullptr) {
     // Load this selector from the selector table.
     GlobalSelectorMapType::iterator I = GlobalSelectorMap.find(ID);
     assert(I != GlobalSelectorMap.end() && "Corrupted global selector map");
@@ -7012,16 +7678,16 @@
 std::pair<CXXCtorInitializer **, unsigned>
 ASTReader::ReadCXXCtorInitializers(ModuleFile &F, const RecordData &Record,
                                    unsigned &Idx) {
-  CXXCtorInitializer **CtorInitializers = 0;
+  CXXCtorInitializer **CtorInitializers = nullptr;
   unsigned NumInitializers = Record[Idx++];
   if (NumInitializers) {
     CtorInitializers
         = new (Context) CXXCtorInitializer*[NumInitializers];
     for (unsigned i=0; i != NumInitializers; ++i) {
-      TypeSourceInfo *TInfo = 0;
+      TypeSourceInfo *TInfo = nullptr;
       bool IsBaseVirtual = false;
-      FieldDecl *Member = 0;
-      IndirectFieldDecl *IndirectMember = 0;
+      FieldDecl *Member = nullptr;
+      IndirectFieldDecl *IndirectMember = nullptr;
 
       CtorInitializerType Type = (CtorInitializerType)Record[Idx++];
       switch (Type) {
@@ -7101,7 +7767,7 @@
 ASTReader::ReadNestedNameSpecifier(ModuleFile &F,
                                    const RecordData &Record, unsigned &Idx) {
   unsigned N = Record[Idx++];
-  NestedNameSpecifier *NNS = 0, *Prev = 0;
+  NestedNameSpecifier *NNS = nullptr, *Prev = nullptr;
   for (unsigned I = 0; I != N; ++I) {
     NestedNameSpecifier::SpecifierKind Kind
       = (NestedNameSpecifier::SpecifierKind)Record[Idx++];
@@ -7128,8 +7794,8 @@
     case NestedNameSpecifier::TypeSpecWithTemplate: {
       const Type *T = readType(F, Record, Idx).getTypePtrOrNull();
       if (!T)
-        return 0;
-      
+        return nullptr;
+
       bool Template = Record[Idx++];
       NNS = NestedNameSpecifier::Create(Context, Prev, Template, T);
       break;
@@ -7276,14 +7942,14 @@
 /// \brief Record that the given ID maps to the given switch-case
 /// statement.
 void ASTReader::RecordSwitchCaseID(SwitchCase *SC, unsigned ID) {
-  assert((*CurrSwitchCaseStmts)[ID] == 0 &&
+  assert((*CurrSwitchCaseStmts)[ID] == nullptr &&
          "Already have a SwitchCase with this ID");
   (*CurrSwitchCaseStmts)[ID] = SC;
 }
 
 /// \brief Retrieve the switch-case statement with the given ID.
 SwitchCase *ASTReader::getSwitchCaseWithID(unsigned ID) {
-  assert((*CurrSwitchCaseStmts)[ID] != 0 && "No SwitchCase with this ID");
+  assert((*CurrSwitchCaseStmts)[ID] != nullptr && "No SwitchCase with this ID");
   return (*CurrSwitchCaseStmts)[ID];
 }
 
@@ -7298,6 +7964,7 @@
        I = CommentsCursors.begin(),
        E = CommentsCursors.end();
        I != E; ++I) {
+    Comments.clear();
     BitstreamCursor &Cursor = I->first;
     serialization::ModuleFile &F = *I->second;
     SavedStreamPosition SavedPosition(Cursor);
@@ -7306,7 +7973,7 @@
     while (true) {
       llvm::BitstreamEntry Entry =
         Cursor.advanceSkippingSubblocks(BitstreamCursor::AF_DontPopBlockAtEnd);
-      
+
       switch (Entry.Kind) {
       case llvm::BitstreamEntry::SubBlock: // Handled for us already.
       case llvm::BitstreamEntry::Error:
@@ -7336,15 +8003,29 @@
       }
       }
     }
-  NextCursor:;
+  NextCursor:
+    Context.Comments.addDeserializedComments(Comments);
   }
-  Context.Comments.addCommentsToFront(Comments);
+}
+
+std::string ASTReader::getOwningModuleNameForDiagnostic(const Decl *D) {
+  // If we know the owning module, use it.
+  if (Module *M = D->getOwningModule())
+    return M->getFullModuleName();
+
+  // Otherwise, use the name of the top-level module the decl is within.
+  if (ModuleFile *M = getOwningModuleFile(D))
+    return M->ModuleName;
+
+  // Not from a module.
+  return "";
 }
 
 void ASTReader::finishPendingActions() {
-  while (!PendingIdentifierInfos.empty() || !PendingDeclChains.empty() ||
+  while (!PendingIdentifierInfos.empty() ||
+         !PendingIncompleteDeclChains.empty() || !PendingDeclChains.empty() ||
          !PendingMacroIDs.empty() || !PendingDeclContextInfos.empty() ||
-         !PendingOdrMergeChecks.empty()) {
+         !PendingUpdateRecords.empty() || !PendingOdrMergeChecks.empty()) {
     // If any identifiers with corresponding top-level declarations have
     // been loaded, load those declarations now.
     typedef llvm::DenseMap<IdentifierInfo *, SmallVector<Decl *, 2> >
@@ -7352,14 +8033,21 @@
     TopLevelDeclsMap TopLevelDecls;
 
     while (!PendingIdentifierInfos.empty()) {
-      // FIXME: std::move
       IdentifierInfo *II = PendingIdentifierInfos.back().first;
-      SmallVector<uint32_t, 4> DeclIDs = PendingIdentifierInfos.back().second;
+      SmallVector<uint32_t, 4> DeclIDs =
+          std::move(PendingIdentifierInfos.back().second);
       PendingIdentifierInfos.pop_back();
 
       SetGloballyVisibleDecls(II, DeclIDs, &TopLevelDecls[II]);
     }
-  
+
+    // For each decl chain that we wanted to complete while deserializing, mark
+    // it as "still needs to be completed".
+    for (unsigned I = 0; I != PendingIncompleteDeclChains.size(); ++I) {
+      markIncompleteDeclChain(PendingIncompleteDeclChains[I]);
+    }
+    PendingIncompleteDeclChains.clear();
+
     // Load pending declaration chains.
     for (unsigned I = 0; I != PendingDeclChains.size(); ++I) {
       loadPendingDeclChain(PendingDeclChains[I]);
@@ -7382,14 +8070,14 @@
       SmallVector<PendingMacroInfo, 2> GlobalIDs;
       GlobalIDs.swap(PendingMacroIDs.begin()[I].second);
       // Initialize the macro history from chained-PCHs ahead of module imports.
-      for (unsigned IDIdx = 0, NumIDs = GlobalIDs.size(); IDIdx !=  NumIDs;
+      for (unsigned IDIdx = 0, NumIDs = GlobalIDs.size(); IDIdx != NumIDs;
            ++IDIdx) {
         const PendingMacroInfo &Info = GlobalIDs[IDIdx];
         if (Info.M->Kind != MK_Module)
           resolvePendingMacro(II, Info);
       }
       // Handle module imports.
-      for (unsigned IDIdx = 0, NumIDs = GlobalIDs.size(); IDIdx !=  NumIDs;
+      for (unsigned IDIdx = 0, NumIDs = GlobalIDs.size(); IDIdx != NumIDs;
            ++IDIdx) {
         const PendingMacroInfo &Info = GlobalIDs[IDIdx];
         if (Info.M->Kind == MK_Module)
@@ -7408,6 +8096,30 @@
       Info.D->setDeclContextsImpl(SemaDC, LexicalDC, getContext());
     }
 
+    // Perform any pending declaration updates.
+    //
+    // Don't do this if we have known-incomplete redecl chains: it relies on
+    // being able to walk redeclaration chains.
+    while (PendingDeclChains.empty() && !PendingUpdateRecords.empty()) {
+      auto Update = PendingUpdateRecords.pop_back_val();
+      ReadingKindTracker ReadingKind(Read_Decl, *this);
+      loadDeclUpdateRecords(Update.first, Update.second);
+    }
+
+    // Trigger the import of the full definition of each class that had any
+    // odr-merging problems, so we can produce better diagnostics for them.
+    for (auto &Merge : PendingOdrMergeFailures) {
+      Merge.first->buildLookup();
+      Merge.first->decls_begin();
+      Merge.first->bases_begin();
+      Merge.first->vbases_begin();
+      for (auto *RD : Merge.second) {
+        RD->decls_begin();
+        RD->bases_begin();
+        RD->vbases_begin();
+      }
+    }
+
     // For each declaration from a merged context, check that the canonical
     // definition of that context also contains a declaration of the same
     // entity.
@@ -7430,16 +8142,14 @@
       llvm::SmallVector<const NamedDecl*, 4> Candidates;
       for (DeclContext::lookup_iterator I = R.begin(), E = R.end();
            !Found && I != E; ++I) {
-        for (Decl::redecl_iterator RI = (*I)->redecls_begin(),
-                                   RE = (*I)->redecls_end();
-             RI != RE; ++RI) {
-          if ((*RI)->getLexicalDeclContext() == CanonDef) {
+        for (auto RI : (*I)->redecls()) {
+          if (RI->getLexicalDeclContext() == CanonDef) {
             // This declaration is present in the canonical definition. If it's
             // in the same redecl chain, it's the one we're looking for.
-            if ((*RI)->getCanonicalDecl() == DCanon)
+            if (RI->getCanonicalDecl() == DCanon)
               Found = true;
             else
-              Candidates.push_back(cast<NamedDecl>(*RI));
+              Candidates.push_back(cast<NamedDecl>(RI));
             break;
           }
         }
@@ -7448,11 +8158,11 @@
       if (!Found) {
         D->setInvalidDecl();
 
-        Module *CanonDefModule = cast<Decl>(CanonDef)->getOwningModule();
+        std::string CanonDefModule =
+            getOwningModuleNameForDiagnostic(cast<Decl>(CanonDef));
         Diag(D->getLocation(), diag::err_module_odr_violation_missing_decl)
-          << D << D->getOwningModule()->getFullModuleName()
-          << CanonDef << !CanonDefModule
-          << (CanonDefModule ? CanonDefModule->getFullModuleName() : "");
+          << D << getOwningModuleNameForDiagnostic(D)
+          << CanonDef << CanonDefModule.empty() << CanonDefModule;
 
         if (Candidates.empty())
           Diag(cast<Decl>(CanonDef)->getLocation(),
@@ -7463,6 +8173,8 @@
                  diag::note_module_odr_violation_possible_decl)
               << Candidates[I];
         }
+
+        DiagnosedOdrMergeFailures.insert(CanonDef);
       }
     }
   }
@@ -7475,49 +8187,39 @@
                                            DEnd = PendingDefinitions.end();
        D != DEnd; ++D) {
     if (TagDecl *TD = dyn_cast<TagDecl>(*D)) {
-      if (const TagType *TagT = dyn_cast<TagType>(TD->TypeForDecl)) {
+      if (const TagType *TagT = dyn_cast<TagType>(TD->getTypeForDecl())) {
         // Make sure that the TagType points at the definition.
         const_cast<TagType*>(TagT)->decl = TD;
       }
       
-      if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(*D)) {
-        for (CXXRecordDecl::redecl_iterator R = RD->redecls_begin(),
-                                         REnd = RD->redecls_end();
-             R != REnd; ++R)
-          cast<CXXRecordDecl>(*R)->DefinitionData = RD->DefinitionData;
-        
+      if (auto RD = dyn_cast<CXXRecordDecl>(*D)) {
+        for (auto R : RD->redecls())
+          cast<CXXRecordDecl>(R)->DefinitionData = RD->DefinitionData;
       }
 
       continue;
     }
     
-    if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(*D)) {
+    if (auto ID = dyn_cast<ObjCInterfaceDecl>(*D)) {
       // Make sure that the ObjCInterfaceType points at the definition.
       const_cast<ObjCInterfaceType *>(cast<ObjCInterfaceType>(ID->TypeForDecl))
         ->Decl = ID;
       
-      for (ObjCInterfaceDecl::redecl_iterator R = ID->redecls_begin(),
-                                           REnd = ID->redecls_end();
-           R != REnd; ++R)
+      for (auto R : ID->redecls())
         R->Data = ID->Data;
       
       continue;
     }
     
-    if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(*D)) {
-      for (ObjCProtocolDecl::redecl_iterator R = PD->redecls_begin(),
-                                          REnd = PD->redecls_end();
-           R != REnd; ++R)
+    if (auto PD = dyn_cast<ObjCProtocolDecl>(*D)) {
+      for (auto R : PD->redecls())
         R->Data = PD->Data;
       
       continue;
     }
     
-    RedeclarableTemplateDecl *RTD
-      = cast<RedeclarableTemplateDecl>(*D)->getCanonicalDecl();
-    for (RedeclarableTemplateDecl::redecl_iterator R = RTD->redecls_begin(),
-                                                REnd = RTD->redecls_end();
-         R != REnd; ++R)
+    auto RTD = cast<RedeclarableTemplateDecl>(*D)->getCanonicalDecl();
+    for (auto R : RTD->redecls())
       R->Common = RTD->Common;
   }
   PendingDefinitions.clear();
@@ -7541,6 +8243,46 @@
       MD->setLazyBody(PB->second);
   }
   PendingBodies.clear();
+
+  // Issue any pending ODR-failure diagnostics.
+  for (auto &Merge : PendingOdrMergeFailures) {
+    if (!DiagnosedOdrMergeFailures.insert(Merge.first))
+      continue;
+
+    bool Diagnosed = false;
+    for (auto *RD : 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;
+        }
+
+        Diag(RD->getLocation(),
+             diag::note_module_odr_violation_different_definitions)
+          << getOwningModuleNameForDiagnostic(RD);
+      }
+    }
+
+    if (!Diagnosed) {
+      // All definitions are updates to the same declaration. This happens if a
+      // module instantiates the declaration of a class template specialization
+      // and two or more other modules instantiate its definition.
+      //
+      // FIXME: Indicate which modules had instantiations of this definition.
+      // FIXME: How can this even happen?
+      Diag(Merge.first->getLocation(),
+           diag::err_module_odr_violation_different_instantiations)
+        << Merge.first;
+    }
+  }
+  PendingOdrMergeFailures.clear();
 }
 
 void ASTReader::FinishedDeserializing() {
@@ -7553,20 +8295,10 @@
   }
   --NumCurrentElementsDeserializing;
 
-  if (NumCurrentElementsDeserializing == 0 &&
-      Consumer && !PassingDeclsToConsumer) {
-    // Guard variable to avoid recursively redoing the process of passing
-    // decls to consumer.
-    SaveAndRestore<bool> GuardPassingDeclsToConsumer(PassingDeclsToConsumer,
-                                                     true);
-
-    while (!InterestingDecls.empty()) {
-      // We are not in recursive loading, so it's safe to pass the "interesting"
-      // decls to the consumer.
-      Decl *D = InterestingDecls.front();
-      InterestingDecls.pop_front();
-      PassInterestingDeclToConsumer(D);
-    }
+  if (NumCurrentElementsDeserializing == 0 && Consumer) {
+    // We are not in recursive loading, so it's safe to pass the "interesting"
+    // decls to the consumer.
+    PassInterestingDeclsToConsumer();
   }
 }
 
@@ -7585,34 +8317,39 @@
   }
 }
 
-ASTReader::ASTReader(Preprocessor &PP, ASTContext &Context,
-                     StringRef isysroot, bool DisableValidation,
-                     bool AllowASTWithCompilerErrors, bool UseGlobalIndex)
-  : Listener(new PCHValidator(PP, *this)), DeserializationListener(0),
-    SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()),
-    Diags(PP.getDiagnostics()), SemaObj(0), PP(PP), Context(Context),
-    Consumer(0), ModuleMgr(PP.getFileManager()),
-    isysroot(isysroot), DisableValidation(DisableValidation),
-    AllowASTWithCompilerErrors(AllowASTWithCompilerErrors),
-    UseGlobalIndex(UseGlobalIndex), TriedLoadingGlobalIndex(false),
-    CurrentGeneration(0), 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),
-    NumCXXBaseSpecifiersLoaded(0), ReadingKind(Read_None)
-{
+ASTReader::ASTReader(Preprocessor &PP, ASTContext &Context, StringRef isysroot,
+                     bool DisableValidation, bool AllowASTWithCompilerErrors,
+                     bool AllowConfigurationMismatch, bool ValidateSystemInputs,
+                     bool UseGlobalIndex)
+    : Listener(new PCHValidator(PP, *this)), DeserializationListener(nullptr),
+      OwnsDeserializationListener(false), SourceMgr(PP.getSourceManager()),
+      FileMgr(PP.getFileManager()), Diags(PP.getDiagnostics()),
+      SemaObj(nullptr), PP(PP), Context(Context), Consumer(nullptr),
+      ModuleMgr(PP.getFileManager()), isysroot(isysroot),
+      DisableValidation(DisableValidation),
+      AllowASTWithCompilerErrors(AllowASTWithCompilerErrors),
+      AllowConfigurationMismatch(AllowConfigurationMismatch),
+      ValidateSystemInputs(ValidateSystemInputs),
+      UseGlobalIndex(UseGlobalIndex), TriedLoadingGlobalIndex(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), NumCXXBaseSpecifiersLoaded(0),
+      ReadingKind(Read_None) {
   SourceMgr.setExternalSLocEntrySource(this);
 }
 
 ASTReader::~ASTReader() {
+  if (OwnsDeserializationListener)
+    delete DeserializationListener;
+
   for (DeclContextVisibleUpdatesPending::iterator
            I = PendingVisibleUpdates.begin(),
            E = PendingVisibleUpdates.end();
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index b8102d8..9ed1bf9 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -99,16 +99,19 @@
     Module *readModule(const RecordData &R, unsigned &I) {
       return Reader.getSubmodule(readSubmoduleID(R, I));
     }
-    
+
+    void ReadCXXRecordDefinition(CXXRecordDecl *D);
     void ReadCXXDefinitionData(struct CXXRecordDecl::DefinitionData &Data,
                                const RecordData &R, unsigned &I);
+    void MergeDefinitionData(CXXRecordDecl *D,
+                             struct CXXRecordDecl::DefinitionData &NewDD);
 
     /// \brief RAII class used to capture the first ID within a redeclaration
     /// chain and to introduce it into the list of pending redeclaration chains
     /// on destruction.
     ///
-    /// The caller can choose not to introduce this ID into the redeclaration
-    /// chain by calling \c suppress().
+    /// The caller can choose not to introduce this ID into the list of pending
+    /// redeclaration chains by calling \c suppress().
     class RedeclarableResult {
       ASTReader &Reader;
       GlobalDeclID FirstID;
@@ -160,8 +163,8 @@
       
     public:
       FindExistingResult(ASTReader &Reader)
-        : Reader(Reader), New(0), Existing(0), AddResult(false) { }
-      
+        : Reader(Reader), New(nullptr), Existing(nullptr), AddResult(false) {}
+
       FindExistingResult(ASTReader &Reader, NamedDecl *New, NamedDecl *Existing)
         : Reader(Reader), New(New), Existing(Existing), AddResult(true) { }
       
@@ -195,9 +198,20 @@
         RawLocation(RawLocation), Record(Record), Idx(Idx),
         TypeIDForTypeDecl(0), HasPendingBody(false) { }
 
+    template <typename DeclT>
+    static void attachPreviousDeclImpl(Redeclarable<DeclT> *D, Decl *Previous);
+    static void attachPreviousDeclImpl(...);
     static void attachPreviousDecl(Decl *D, Decl *previous);
+
+    template <typename DeclT>
+    static void attachLatestDeclImpl(Redeclarable<DeclT> *D, Decl *Latest);
+    static void attachLatestDeclImpl(...);
     static void attachLatestDecl(Decl *D, Decl *latest);
 
+    template <typename DeclT>
+    static void markIncompleteDeclChainImpl(Redeclarable<DeclT> *D);
+    static void markIncompleteDeclChainImpl(...);
+
     /// \brief Determine whether this declaration has a pending body.
     bool hasPendingBody() const { return HasPendingBody; }
 
@@ -264,7 +278,7 @@
     void VisitImplicitParamDecl(ImplicitParamDecl *PD);
     void VisitParmVarDecl(ParmVarDecl *PD);
     void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
-    void VisitTemplateDecl(TemplateDecl *D);
+    DeclID VisitTemplateDecl(TemplateDecl *D);
     RedeclarableResult VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D);
     void VisitClassTemplateDecl(ClassTemplateDecl *D);
     void VisitVarTemplateDecl(VarTemplateDecl *D);
@@ -285,20 +299,26 @@
     void VisitEmptyDecl(EmptyDecl *D);
 
     std::pair<uint64_t, uint64_t> VisitDeclContext(DeclContext *DC);
-    
-    template<typename T> 
+
+    template<typename T>
     RedeclarableResult VisitRedeclarable(Redeclarable<T> *D);
 
     template<typename T>
-    void mergeRedeclarable(Redeclarable<T> *D, RedeclarableResult &Redecl);
+    void mergeRedeclarable(Redeclarable<T> *D, RedeclarableResult &Redecl,
+                           DeclID TemplatePatternID = 0);
 
     template<typename T>
     void mergeRedeclarable(Redeclarable<T> *D, T *Existing,
-                           RedeclarableResult &Redecl);
+                           RedeclarableResult &Redecl,
+                           DeclID TemplatePatternID = 0);
 
     template<typename T>
     void mergeMergeable(Mergeable<T> *D);
 
+    void mergeTemplatePattern(RedeclarableTemplateDecl *D,
+                              RedeclarableTemplateDecl *Existing,
+                              DeclID DsID);
+
     // FIXME: Reorder according to DeclNodes.td?
     void VisitObjCMethodDecl(ObjCMethodDecl *D);
     void VisitObjCContainerDecl(ObjCContainerDecl *D);
@@ -337,7 +357,7 @@
   }
 
   if (TypeDecl *TD = dyn_cast<TypeDecl>(D)) {
-    // if we have a fully initialized TypeDecl, we can safely read its type now.
+    // We have a fully initialized TypeDecl. Read its type now.
     TD->setTypeForDecl(Reader.GetType(TypeIDForTypeDecl).getTypePtrOrNull());
   } else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
     // if we have a fully initialized TypeDecl, we can safely read its type now.
@@ -356,11 +376,14 @@
 }
 
 void ASTDeclReader::VisitDecl(Decl *D) {
-  if (D->isTemplateParameter()) {
+  if (D->isTemplateParameter() || D->isTemplateParameterPack() ||
+      isa<ParmVarDecl>(D)) {
     // We don't want to deserialize the DeclContext of a template
-    // parameter immediately, because the template parameter might be
-    // used in the formulation of its DeclContext. Use the translation
-    // unit DeclContext as a placeholder.
+    // parameter or of a parameter of a function template immediately.   These
+    // entities might be used in the formulation of its DeclContext (for
+    // 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);
     Reader.addPendingDeclContextInfo(D,
@@ -409,7 +432,7 @@
           
           // Note that this declaration was hidden because its owning module is 
           // not yet visible.
-          Reader.HiddenNamesMap[Owner].push_back(D);
+          Reader.HiddenNamesMap[Owner].HiddenDecls.push_back(D);
         }
       }
     }
@@ -471,7 +494,8 @@
   } else
     TD->NamedDeclOrQualifier = ReadDeclAs<NamedDecl>(Record, Idx);
 
-  mergeRedeclarable(TD, Redecl);
+  if (!isa<CXXRecordDecl>(TD))
+    mergeRedeclarable(TD, Redecl);
   return Redecl;
 }
 
@@ -573,9 +597,10 @@
 
   switch ((FunctionDecl::TemplatedKind)Record[Idx++]) {
   case FunctionDecl::TK_NonTemplate:
-    mergeRedeclarable(FD, Redecl);      
+    mergeRedeclarable(FD, Redecl);
     break;
   case FunctionDecl::TK_FunctionTemplate:
+    // Merged when we merge the template.
     FD->setDescribedFunctionTemplate(ReadDeclAs<FunctionTemplateDecl>(Record, 
                                                                       Idx));
     break;
@@ -585,6 +610,7 @@
     SourceLocation POI = ReadSourceLocation(Record, Idx);
     FD->setInstantiationOfMemberFunction(Reader.getContext(), InstFD, TSK);
     FD->getMemberSpecializationInfo()->setPointOfInstantiation(POI);
+    mergeRedeclarable(FD, Redecl);
     break;
   }
   case FunctionDecl::TK_FunctionTemplateSpecialization: {
@@ -622,7 +648,8 @@
     FunctionTemplateSpecializationInfo *FTInfo
         = FunctionTemplateSpecializationInfo::Create(C, FD, Template, TSK,
                                                      TemplArgList,
-                             HasTemplateArgumentsAsWritten ? &TemplArgsInfo : 0,
+                             HasTemplateArgumentsAsWritten ? &TemplArgsInfo
+                                                           : nullptr,
                                                      POI);
     FD->TemplateOrSpecialization = FTInfo;
 
@@ -637,9 +664,8 @@
       // We avoid getASTContext because a decl in the parent hierarchy may
       // be initializing.
       llvm::FoldingSetNodeID ID;
-      FunctionTemplateSpecializationInfo::Profile(ID, TemplArgs.data(),
-                                                  TemplArgs.size(), C);
-      void *InsertPos = 0;
+      FunctionTemplateSpecializationInfo::Profile(ID, TemplArgs, C);
+      void *InsertPos = nullptr;
       FunctionTemplateDecl::Common *CommonPtr = CanonTemplate->getCommonPtr();
       CommonPtr->Specializations.FindNodeOrInsertPos(ID, InsertPos);
       if (InsertPos)
@@ -670,6 +696,8 @@
     
     FD->setDependentTemplateSpecialization(Reader.getContext(),
                                            TemplDecls, TemplArgs);
+
+    // FIXME: Merging.
     break;
   }
   }
@@ -709,8 +737,8 @@
   MD->setDeclImplementation((ObjCMethodDecl::ImplementationControl)Record[Idx++]);
   MD->setObjCDeclQualifier((Decl::ObjCDeclQualifier)Record[Idx++]);
   MD->SetRelatedResultType(Record[Idx++]);
-  MD->setResultType(Reader.readType(F, Record, Idx));
-  MD->setResultTypeSourceInfo(GetTypeSourceInfo(Record, Idx));
+  MD->setReturnType(Reader.readType(F, Record, Idx));
+  MD->setReturnTypeSourceInfo(GetTypeSourceInfo(Record, Idx));
   MD->DeclEndLoc = ReadSourceLocation(Record, Idx);
   unsigned NumParams = Record[Idx++];
   SmallVector<ParmVarDecl *, 16> Params;
@@ -755,6 +783,7 @@
     Data.SuperClassLoc = ReadSourceLocation(Record, Idx);
 
     Data.EndLoc = ReadSourceLocation(Record, Idx);
+    Data.HasDesignatedInitializers = Record[Idx++];
     
     // Read the directly referenced protocols and their SourceLocations.
     unsigned NumProtocols = Record[Idx++];
@@ -779,8 +808,8 @@
                                           Reader.getContext());
   
     // We will rebuild this list lazily.
-    ID->setIvarList(0);
-    
+    ID->setIvarList(nullptr);
+
     // Note that we have deserialized a definition.
     Reader.PendingDefinitions.insert(ID);
     
@@ -795,11 +824,9 @@
   VisitFieldDecl(IVD);
   IVD->setAccessControl((ObjCIvarDecl::AccessControl)Record[Idx++]);
   // This field will be built lazily.
-  IVD->setNextIvar(0);
+  IVD->setNextIvar(nullptr);
   bool synth = Record[Idx++];
   IVD->setSynthesize(synth);
-  bool backingIvarReferencedInAccessor = Record[Idx++];
-  IVD->setBackingIvarReferencedInAccessor(backingIvarReferencedInAccessor);
 }
 
 void ASTDeclReader::VisitObjCProtocolDecl(ObjCProtocolDecl *PD) {
@@ -907,8 +934,8 @@
   D->setIvarRBraceLoc(ReadSourceLocation(Record, Idx));
   D->setHasNonZeroConstructors(Record[Idx++]);
   D->setHasDestructors(Record[Idx++]);
-  llvm::tie(D->IvarInitializers, D->NumIvarInitializers)
-      = Reader.ReadCXXCtorInitializers(F, Record, Idx);
+  std::tie(D->IvarInitializers, D->NumIvarInitializers) =
+      Reader.ReadCXXCtorInitializers(F, Record, Idx);
 }
 
 
@@ -971,14 +998,10 @@
   VD->setCachedLinkage(VarLinkage);
 
   // Reconstruct the one piece of the IdentifierNamespace that we need.
-  if (VarLinkage != NoLinkage &&
+  if (VD->getStorageClass() == SC_Extern && VarLinkage != NoLinkage &&
       VD->getLexicalDeclContext()->isFunctionOrMethod())
     VD->setLocalExternDecl();
 
-  // Only true variables (not parameters or implicit parameters) can be merged.
-  if (VD->getKind() != Decl::ParmVar && VD->getKind() != Decl::ImplicitParam)
-    mergeRedeclarable(VD, Redecl);
-  
   if (uint64_t Val = Record[Idx++]) {
     VD->setInit(Reader.ReadExpr(F));
     if (Val > 1) {
@@ -993,8 +1016,13 @@
   };
   switch ((VarKind)Record[Idx++]) {
   case VarNotTemplate:
+    // Only true variables (not parameters or implicit parameters) can be merged
+    if (VD->getKind() != Decl::ParmVar && VD->getKind() != Decl::ImplicitParam &&
+        !isa<VarTemplateSpecializationDecl>(VD))
+      mergeRedeclarable(VD, Redecl);
     break;
   case VarTemplate:
+    // Merged when we merge the template.
     VD->setDescribedVarTemplate(ReadDeclAs<VarTemplateDecl>(Record, Idx));
     break;
   case StaticDataMemberSpecialization: { // HasMemberSpecializationInfo.
@@ -1002,6 +1030,7 @@
     TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++];
     SourceLocation POI = ReadSourceLocation(Record, Idx);
     Reader.getContext().setInstantiatedFromStaticDataMember(VD, Tmpl, TSK,POI);
+    mergeRedeclarable(VD, Redecl);
     break;
   }
   }
@@ -1065,7 +1094,7 @@
     unsigned flags = Record[Idx++];
     bool byRef = (flags & 1);
     bool nested = (flags & 2);
-    Expr *copyExpr = ((flags & 4) ? Reader.ReadExpr(F) : 0);
+    Expr *copyExpr = ((flags & 4) ? Reader.ReadExpr(F) : nullptr);
 
     captures.push_back(BlockDecl::Capture(decl, byRef, nested, copyExpr));
   }
@@ -1075,9 +1104,15 @@
 
 void ASTDeclReader::VisitCapturedDecl(CapturedDecl *CD) {
   VisitDecl(CD);
+  unsigned ContextParamPos = Record[Idx++];
+  CD->setNothrow(Record[Idx++] != 0);
   // Body is set by VisitCapturedStmt.
-  for (unsigned i = 0; i < CD->NumParams; ++i)
-    CD->setParam(i, ReadDeclAs<ImplicitParamDecl>(Record, Idx));
+  for (unsigned I = 0; I < CD->NumParams; ++I) {
+    if (I != ContextParamPos)
+      CD->setParam(I, ReadDeclAs<ImplicitParamDecl>(Record, Idx));
+    else
+      CD->setContextParam(I, ReadDeclAs<ImplicitParamDecl>(Record, Idx));
+  }
 }
 
 void ASTDeclReader::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
@@ -1099,8 +1134,6 @@
   D->setInline(Record[Idx++]);
   D->LocStart = ReadSourceLocation(Record, Idx);
   D->RBraceLoc = ReadSourceLocation(Record, Idx);
-  // FIXME: At the point of this call, D->getCanonicalDecl() returns 0.
-  mergeRedeclarable(D, Redecl);
 
   if (Redecl.getFirstID() == ThisDeclID) {
     // Each module has its own anonymous namespace, which is disjoint from
@@ -1114,6 +1147,8 @@
     // been deserialized.
     D->AnonOrFirstNamespaceAndInline.setPointer(D->getFirstDecl());
   }
+
+  mergeRedeclarable(D, Redecl);
 }
 
 void ASTDeclReader::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
@@ -1186,6 +1221,7 @@
   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++];
@@ -1196,6 +1232,7 @@
   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.DefaultedDefaultConstructorIsConstexpr = Record[Idx++];
@@ -1222,7 +1259,7 @@
   Data.FirstFriend = ReadDeclID(Record, Idx);
 
   if (Data.IsLambda) {
-    typedef LambdaExpr::Capture Capture;
+    typedef LambdaCapture Capture;
     CXXRecordDecl::LambdaDefinitionData &Lambda
       = static_cast<CXXRecordDecl::LambdaDefinitionData &>(Data);
     Lambda.Dependent = Record[Idx++];
@@ -1242,7 +1279,7 @@
       LambdaCaptureKind Kind = static_cast<LambdaCaptureKind>(Record[Idx++]);
       switch (Kind) {
       case LCK_This:
-        *ToCapture++ = Capture(Loc, IsImplicit, Kind, 0, SourceLocation());
+        *ToCapture++ = Capture(Loc, IsImplicit, Kind, nullptr,SourceLocation());
         break;
       case LCK_ByCopy:
       case LCK_ByRef:
@@ -1255,61 +1292,172 @@
   }
 }
 
+void ASTDeclReader::MergeDefinitionData(
+    CXXRecordDecl *D, struct CXXRecordDecl::DefinitionData &MergeDD) {
+  assert(D->DefinitionData.getNotUpdated() &&
+         "merging class definition into non-definition");
+  auto &DD = *D->DefinitionData.getNotUpdated();
+
+  // If the new definition has new special members, let the name lookup
+  // code know that it needs to look in the new definition too.
+  if ((MergeDD.DeclaredSpecialMembers & ~DD.DeclaredSpecialMembers) &&
+      DD.Definition != MergeDD.Definition) {
+    Reader.MergedLookups[DD.Definition].push_back(MergeDD.Definition);
+    DD.Definition->setHasExternalVisibleStorage();
+  }
+
+  // FIXME: Move this out into a .def file?
+  // FIXME: Issue a diagnostic on a mismatched MATCH_FIELD, rather than
+  // asserting; this can happen in the case of an ODR violation.
+  bool DetectedOdrViolation = false;
+#define OR_FIELD(Field) DD.Field |= MergeDD.Field;
+#define MATCH_FIELD(Field) \
+    DetectedOdrViolation |= DD.Field != MergeDD.Field; \
+    OR_FIELD(Field)
+  MATCH_FIELD(UserDeclaredConstructor)
+  MATCH_FIELD(UserDeclaredSpecialMembers)
+  MATCH_FIELD(Aggregate)
+  MATCH_FIELD(PlainOldData)
+  MATCH_FIELD(Empty)
+  MATCH_FIELD(Polymorphic)
+  MATCH_FIELD(Abstract)
+  MATCH_FIELD(IsStandardLayout)
+  MATCH_FIELD(HasNoNonEmptyBases)
+  MATCH_FIELD(HasPrivateFields)
+  MATCH_FIELD(HasProtectedFields)
+  MATCH_FIELD(HasPublicFields)
+  MATCH_FIELD(HasMutableFields)
+  MATCH_FIELD(HasVariantMembers)
+  MATCH_FIELD(HasOnlyCMembers)
+  MATCH_FIELD(HasInClassInitializer)
+  MATCH_FIELD(HasUninitializedReferenceMember)
+  MATCH_FIELD(NeedOverloadResolutionForMoveConstructor)
+  MATCH_FIELD(NeedOverloadResolutionForMoveAssignment)
+  MATCH_FIELD(NeedOverloadResolutionForDestructor)
+  MATCH_FIELD(DefaultedMoveConstructorIsDeleted)
+  MATCH_FIELD(DefaultedMoveAssignmentIsDeleted)
+  MATCH_FIELD(DefaultedDestructorIsDeleted)
+  OR_FIELD(HasTrivialSpecialMembers)
+  OR_FIELD(DeclaredNonTrivialSpecialMembers)
+  MATCH_FIELD(HasIrrelevantDestructor)
+  OR_FIELD(HasConstexprNonCopyMoveConstructor)
+  MATCH_FIELD(DefaultedDefaultConstructorIsConstexpr)
+  OR_FIELD(HasConstexprDefaultConstructor)
+  MATCH_FIELD(HasNonLiteralTypeFieldsOrBases)
+  // ComputedVisibleConversions is handled below.
+  MATCH_FIELD(UserProvidedDefaultConstructor)
+  OR_FIELD(DeclaredSpecialMembers)
+  MATCH_FIELD(ImplicitCopyConstructorHasConstParam)
+  MATCH_FIELD(ImplicitCopyAssignmentHasConstParam)
+  OR_FIELD(HasDeclaredCopyConstructorWithConstParam)
+  OR_FIELD(HasDeclaredCopyAssignmentWithConstParam)
+  MATCH_FIELD(IsLambda)
+#undef OR_FIELD
+#undef MATCH_FIELD
+
+  if (DD.NumBases != MergeDD.NumBases || DD.NumVBases != MergeDD.NumVBases)
+    DetectedOdrViolation = true;
+  // FIXME: Issue a diagnostic if the base classes don't match when we come
+  // to lazily load them.
+
+  // FIXME: Issue a diagnostic if the list of conversion functions doesn't
+  // match when we come to lazily load them.
+  if (MergeDD.ComputedVisibleConversions && !DD.ComputedVisibleConversions) {
+    DD.VisibleConversions = std::move(MergeDD.VisibleConversions);
+    DD.ComputedVisibleConversions = true;
+  }
+
+  // FIXME: Issue a diagnostic if FirstFriend doesn't match when we come to
+  // lazily load it.
+
+  if (DD.IsLambda) {
+    // FIXME: ODR-checking for merging lambdas (this happens, for instance,
+    // when they occur within the body of a function template specialization).
+  }
+
+  if (DetectedOdrViolation)
+    Reader.PendingOdrMergeFailures[DD.Definition].push_back(MergeDD.Definition);
+}
+
+void ASTDeclReader::ReadCXXRecordDefinition(CXXRecordDecl *D) {
+  struct CXXRecordDecl::DefinitionData *DD;
+  ASTContext &C = Reader.getContext();
+
+  // Determine whether this is a lambda closure type, so that we can
+  // allocate the appropriate DefinitionData structure.
+  bool IsLambda = Record[Idx++];
+  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);
+
+  // If we're reading an update record, we might already have a definition for
+  // this record. If so, just merge into it.
+  if (D->DefinitionData.getNotUpdated()) {
+    MergeDefinitionData(D, *DD);
+    return;
+  }
+
+  // Propagate the DefinitionData pointer to the canonical declaration, so
+  // that all other deserialized declarations will see it.
+  CXXRecordDecl *Canon = D->getCanonicalDecl();
+  if (Canon == D) {
+    D->DefinitionData = DD;
+    D->IsCompleteDefinition = true;
+  } else if (auto *CanonDD = Canon->DefinitionData.getNotUpdated()) {
+    // We have already deserialized a definition of this record. This
+    // definition is no longer really a definition. Note that the pre-existing
+    // definition is the *real* definition.
+    Reader.MergedDeclContexts.insert(
+        std::make_pair(D, CanonDD->Definition));
+    D->DefinitionData = Canon->DefinitionData;
+    D->IsCompleteDefinition = false;
+    MergeDefinitionData(D, *DD);
+  } else {
+    Canon->DefinitionData = DD;
+    D->DefinitionData = Canon->DefinitionData;
+    D->IsCompleteDefinition = true;
+
+    // Note that we have deserialized a definition. Any declarations
+    // deserialized before this one will be be given the DefinitionData
+    // pointer at the end.
+    Reader.PendingDefinitions.insert(D);
+  }
+}
+
 ASTDeclReader::RedeclarableResult
 ASTDeclReader::VisitCXXRecordDeclImpl(CXXRecordDecl *D) {
   RedeclarableResult Redecl = VisitRecordDeclImpl(D);
 
   ASTContext &C = Reader.getContext();
-  bool WasDefinition = Record[Idx++];
-  if (WasDefinition) {
-    // Determine whether this is a lambda closure type, so that we can
-    // allocate the appropriate DefinitionData structure.
-    bool IsLambda = Record[Idx++];
-    if (IsLambda)
-      D->DefinitionData = new (C) CXXRecordDecl::LambdaDefinitionData(D, 0,
-                                                                      false,
-                                                                      false, LCD_None);
-    else
-      D->DefinitionData = new (C) struct CXXRecordDecl::DefinitionData(D);
-
-    ReadCXXDefinitionData(*D->DefinitionData, Record, Idx);
-
-    // Propagate the DefinitionData pointer to the canonical declaration, so
-    // that all other deserialized declarations will see it.
-    CXXRecordDecl *Canon = D->getCanonicalDecl();
-    if (Canon == D) {
-      // Nothing to do.
-    } else if (!Canon->DefinitionData) {
-      Canon->DefinitionData = D->DefinitionData;
-
-      // Note that we have deserialized a definition. Any declarations
-      // deserialized before this one will be be given the DefinitionData
-      // pointer at the end.
-      Reader.PendingDefinitions.insert(D);
-    } else {
-      // We have already deserialized a definition of this record. This
-      // definition is no longer really a definition. Note that the pre-existing
-      // definition is the *real* definition.
-      // FIXME: Check DefinitionData for consistency with prior definition.
-      Reader.MergedDeclContexts.insert(
-          std::make_pair(D, D->getCanonicalDecl()->DefinitionData->Definition));
-      D->IsCompleteDefinition = false;
-      D->DefinitionData = D->getCanonicalDecl()->DefinitionData;
-    }
-  } else {
-    // Propagate DefinitionData pointer from the canonical declaration.
-    D->DefinitionData = D->getCanonicalDecl()->DefinitionData;
-  }
 
   enum CXXRecKind {
     CXXRecNotTemplate = 0, CXXRecTemplate, CXXRecMemberSpecialization
   };
   switch ((CXXRecKind)Record[Idx++]) {
   case CXXRecNotTemplate:
+    // Merged when we merge the folding set entry in the primary template.
+    if (!isa<ClassTemplateSpecializationDecl>(D))
+      mergeRedeclarable(D, Redecl);
     break;
-  case CXXRecTemplate:
-    D->TemplateOrInstantiation = ReadDeclAs<ClassTemplateDecl>(Record, Idx);
+  case CXXRecTemplate: {
+    // Merged when we merge the template.
+    ClassTemplateDecl *Template = ReadDeclAs<ClassTemplateDecl>(Record, Idx);
+    D->TemplateOrInstantiation = Template;
+    if (!Template->getTemplatedDecl()) {
+      // We've not actually loaded the ClassTemplateDecl yet, because we're
+      // currently being loaded as its pattern. Rely on it to set up our
+      // TypeForDecl (see VisitClassTemplateDecl).
+      //
+      // Beware: we do not yet know our canonical declaration, and may still
+      // get merged once the surrounding class template has got off the ground.
+      TypeIDForTypeDecl = 0;
+    }
     break;
+  }
   case CXXRecMemberSpecialization: {
     CXXRecordDecl *RD = ReadDeclAs<CXXRecordDecl>(Record, Idx);
     TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++];
@@ -1317,15 +1465,26 @@
     MemberSpecializationInfo *MSI = new (C) MemberSpecializationInfo(RD, TSK);
     MSI->setPointOfInstantiation(POI);
     D->TemplateOrInstantiation = MSI;
+    mergeRedeclarable(D, Redecl);
     break;
   }
   }
 
+  bool WasDefinition = Record[Idx++];
+  if (WasDefinition)
+    ReadCXXRecordDefinition(D);
+  else
+    // Propagate DefinitionData pointer from the canonical declaration.
+    D->DefinitionData = D->getCanonicalDecl()->DefinitionData;
+
   // Lazily load the key function to avoid deserializing every method so we can
   // compute it.
   if (WasDefinition) {
     DeclID KeyFn = ReadDeclID(Record, Idx);
     if (KeyFn && D->IsCompleteDefinition)
+      // FIXME: This is wrong for the ARM ABI, where some other module may have
+      // made this function no longer be a key function. We need an update
+      // record or similar for that case.
       C.KeyFunctions[D] = KeyFn;
   }
 
@@ -1345,10 +1504,13 @@
 
 void ASTDeclReader::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
   VisitCXXMethodDecl(D);
-  
+
+  if (auto *CD = ReadDeclAs<CXXConstructorDecl>(Record, Idx))
+    D->setInheritedConstructor(CD);
   D->IsExplicitSpecified = Record[Idx++];
-  llvm::tie(D->CtorInitializers, D->NumCtorInitializers)
-      = Reader.ReadCXXCtorInitializers(F, Record, Idx);
+  // FIXME: We should defer loading this until we need the constructor's body.
+  std::tie(D->CtorInitializers, D->NumCtorInitializers) =
+      Reader.ReadCXXCtorInitializers(F, Record, Idx);
 }
 
 void ASTDeclReader::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
@@ -1404,16 +1566,19 @@
   D->FriendLoc = ReadSourceLocation(Record, Idx);
 }
 
-void ASTDeclReader::VisitTemplateDecl(TemplateDecl *D) {
+DeclID ASTDeclReader::VisitTemplateDecl(TemplateDecl *D) {
   VisitNamedDecl(D);
 
-  NamedDecl *TemplatedDecl = ReadDeclAs<NamedDecl>(Record, Idx);
+  DeclID PatternID = ReadDeclID(Record, Idx);
+  NamedDecl *TemplatedDecl = cast_or_null<NamedDecl>(Reader.GetDecl(PatternID));
   TemplateParameterList* TemplateParams
       = Reader.ReadTemplateParameterList(F, Record, Idx); 
   D->init(TemplatedDecl, TemplateParams);
 
   // FIXME: If this is a redeclaration of a template from another module, handle
   // inheritance of default template arguments.
+
+  return PatternID;
 }
 
 ASTDeclReader::RedeclarableResult 
@@ -1442,10 +1607,10 @@
     }
   }
 
-  VisitTemplateDecl(D);
+  DeclID PatternID = VisitTemplateDecl(D);
   D->IdentifierNamespace = Record[Idx++];
 
-  mergeRedeclarable(D, Redecl);
+  mergeRedeclarable(D, Redecl, PatternID);
 
   // If we merged the template with a prior declaration chain, merge the common
   // pointer.
@@ -1486,8 +1651,14 @@
       memcpy(CommonPtr->LazySpecializations, SpecIDs.data(), 
              SpecIDs.size() * sizeof(DeclID));
     }
-    
-    CommonPtr->InjectedClassNameType = Reader.readType(F, Record, Idx);
+  }
+
+  if (D->getTemplatedDecl()->TemplateOrInstantiation) {
+    // We were loaded before our templated declaration was. We've not set up
+    // its corresponding type yet (see VisitCXXRecordDeclImpl), so reconstruct
+    // it now.
+    Reader.Context.getInjectedClassNameType(
+        D->getTemplatedDecl(), D->getInjectedClassNameSpecialization());
   }
 }
 
@@ -1580,18 +1751,18 @@
 
         // This declaration might be a definition. Merge with any existing
         // definition.
-        if (D->DefinitionData) {
-          if (!CanonSpec->DefinitionData) {
-            CanonSpec->DefinitionData = D->DefinitionData;
-          } else {
-            // FIXME: Check DefinitionData for consistency with prior definition
+        if (auto *DDD = D->DefinitionData.getNotUpdated()) {
+          if (auto *CanonDD = CanonSpec->DefinitionData.getNotUpdated()) {
+            MergeDefinitionData(CanonSpec, *DDD);
             Reader.PendingDefinitions.erase(D);
             Reader.MergedDeclContexts.insert(
-                std::make_pair(D, CanonSpec->DefinitionData->Definition));
+                std::make_pair(D, CanonDD->Definition));
             D->IsCompleteDefinition = false;
-            D->DefinitionData = CanonSpec->DefinitionData;
+          } else {
+            CanonSpec->DefinitionData = D->DefinitionData;
           }
         }
+        D->DefinitionData = CanonSpec->DefinitionData;
       }
     }
   }
@@ -1838,65 +2009,111 @@
 /// \brief Attempts to merge the given declaration (D) with another declaration
 /// of the same entity.
 template<typename T>
-void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *D,
-                                      RedeclarableResult &Redecl) {
+void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *DBase,
+                                      RedeclarableResult &Redecl,
+                                      DeclID TemplatePatternID) {
+  T *D = static_cast<T*>(DBase);
+  T *DCanon = D->getCanonicalDecl();
+  if (D != DCanon &&
+      (!Reader.getContext().getLangOpts().Modules ||
+       Reader.getOwningModuleFile(DCanon) == Reader.getOwningModuleFile(D))) {
+    // All redeclarations between this declaration and its originally-canonical
+    // declaration get pulled in when we load DCanon; we don't need to
+    // perform any more merging now.
+    Redecl.suppress();
+  }
+
   // If modules are not available, there is no reason to perform this merge.
   if (!Reader.getContext().getLangOpts().Modules)
     return;
 
-  if (FindExistingResult ExistingRes = findExisting(static_cast<T*>(D)))
+  if (FindExistingResult ExistingRes = findExisting(D))
     if (T *Existing = ExistingRes)
-      mergeRedeclarable(D, Existing, Redecl);
+      mergeRedeclarable(D, Existing, Redecl, TemplatePatternID);
+}
+
+/// \brief "Cast" to type T, asserting if we don't have an implicit conversion.
+/// We use this to put code in a template that will only be valid for certain
+/// instantiations.
+template<typename T> static T assert_cast(T t) { return t; }
+template<typename T> static T assert_cast(...) {
+  llvm_unreachable("bad assert_cast");
+}
+
+/// \brief Merge together the pattern declarations from two template
+/// declarations.
+void ASTDeclReader::mergeTemplatePattern(RedeclarableTemplateDecl *D,
+                                         RedeclarableTemplateDecl *Existing,
+                                         DeclID DsID) {
+  auto *DPattern = D->getTemplatedDecl();
+  auto *ExistingPattern = Existing->getTemplatedDecl();
+  RedeclarableResult Result(Reader, DPattern->getCanonicalDecl()->getGlobalID(),
+                            DPattern->getKind());
+  if (auto *DClass = dyn_cast<CXXRecordDecl>(DPattern)) {
+    // Merge with any existing definition.
+    // FIXME: This is duplicated in several places. Refactor.
+    auto *ExistingClass =
+        cast<CXXRecordDecl>(ExistingPattern)->getCanonicalDecl();
+    if (auto *DDD = DClass->DefinitionData.getNotUpdated()) {
+      if (auto *ExistingDD = ExistingClass->DefinitionData.getNotUpdated()) {
+        MergeDefinitionData(ExistingClass, *DDD);
+        Reader.PendingDefinitions.erase(DClass);
+        Reader.MergedDeclContexts.insert(
+            std::make_pair(DClass, ExistingDD->Definition));
+        DClass->IsCompleteDefinition = false;
+      } else {
+        ExistingClass->DefinitionData = DClass->DefinitionData;
+      }
+    }
+    DClass->DefinitionData = ExistingClass->DefinitionData;
+
+    return mergeRedeclarable(DClass, cast<TagDecl>(ExistingPattern),
+                             Result);
+  }
+  if (auto *DFunction = dyn_cast<FunctionDecl>(DPattern))
+    return mergeRedeclarable(DFunction, cast<FunctionDecl>(ExistingPattern),
+                             Result);
+  if (auto *DVar = dyn_cast<VarDecl>(DPattern))
+    return mergeRedeclarable(DVar, cast<VarDecl>(ExistingPattern), Result);
+  llvm_unreachable("merged an unknown kind of redeclarable template");
 }
 
 /// \brief Attempts to merge the given declaration (D) with another declaration
 /// of the same entity.
 template<typename T>
-void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *D, T *Existing,
-                                      RedeclarableResult &Redecl) {
+void ASTDeclReader::mergeRedeclarable(Redeclarable<T> *DBase, T *Existing,
+                                      RedeclarableResult &Redecl,
+                                      DeclID TemplatePatternID) {
+  T *D = static_cast<T*>(DBase);
   T *ExistingCanon = Existing->getCanonicalDecl();
-  T *DCanon = static_cast<T*>(D)->getCanonicalDecl();
+  T *DCanon = D->getCanonicalDecl();
   if (ExistingCanon != DCanon) {
+    assert(DCanon->getGlobalID() == Redecl.getFirstID());
+
     // Have our redeclaration link point back at the canonical declaration
-    // of the existing declaration, so that this declaration has the 
+    // of the existing declaration, so that this declaration has the
     // appropriate canonical declaration.
     D->RedeclLink = Redeclarable<T>::PreviousDeclLink(ExistingCanon);
 
     // When we merge a namespace, update its pointer to the first namespace.
-    if (NamespaceDecl *Namespace
-          = dyn_cast<NamespaceDecl>(static_cast<T*>(D))) {
+    if (auto *Namespace = dyn_cast<NamespaceDecl>(D))
       Namespace->AnonOrFirstNamespaceAndInline.setPointer(
-        static_cast<NamespaceDecl *>(static_cast<void*>(ExistingCanon)));
-    }
+          assert_cast<NamespaceDecl*>(ExistingCanon));
 
-    // Don't introduce DCanon into the set of pending declaration chains.
-    Redecl.suppress();
-
-    // Introduce ExistingCanon into the set of pending declaration chains,
-    // if in fact it came from a module file.
-    if (ExistingCanon->isFromASTFile()) {
-      GlobalDeclID ExistingCanonID = ExistingCanon->getGlobalID();
-      assert(ExistingCanonID && "Unrecorded canonical declaration ID?");
-      if (Reader.PendingDeclChainsKnown.insert(ExistingCanonID))
-        Reader.PendingDeclChains.push_back(ExistingCanonID);
-    }
+    // When we merge a template, merge its pattern.
+    if (auto *DTemplate = dyn_cast<RedeclarableTemplateDecl>(D))
+      mergeTemplatePattern(
+          DTemplate, assert_cast<RedeclarableTemplateDecl*>(ExistingCanon),
+          TemplatePatternID);
 
     // If this declaration was the canonical declaration, make a note of
     // that. We accept the linear algorithm here because the number of
     // unique canonical declarations of an entity should always be tiny.
-    if (DCanon == static_cast<T*>(D)) {
+    if (DCanon == D) {
       SmallVectorImpl<DeclID> &Merged = Reader.MergedDecls[ExistingCanon];
       if (std::find(Merged.begin(), Merged.end(), Redecl.getFirstID())
             == Merged.end())
         Merged.push_back(Redecl.getFirstID());
-
-      // If ExistingCanon did not come from a module file, introduce the
-      // first declaration that *does* come from a module file to the
-      // set of pending declaration chains, so that we merge this
-      // declaration.
-      if (!ExistingCanon->isFromASTFile() &&
-          Reader.PendingDeclChainsKnown.insert(Redecl.getFirstID()))
-        Reader.PendingDeclChains.push_back(Merged[0]);
     }
   }
 }
@@ -1942,7 +2159,7 @@
 void ASTReader::ReadAttributes(ModuleFile &F, AttrVec &Attrs,
                                const RecordData &Record, unsigned &Idx) {
   for (unsigned i = 0, e = Record[Idx++]; i != e; ++i) {
-    Attr *New = 0;
+    Attr *New = nullptr;
     attr::Kind Kind = (attr::Kind)Record[Idx++];
     SourceRange Range = ReadSourceRange(F, Record, Idx);
 
@@ -1981,7 +2198,8 @@
 
   if (isa<FileScopeAsmDecl>(D) || 
       isa<ObjCProtocolDecl>(D) || 
-      isa<ObjCImplDecl>(D))
+      isa<ObjCImplDecl>(D) ||
+      isa<ImportDecl>(D))
     return true;
   if (VarDecl *Var = dyn_cast<VarDecl>(D))
     return Var->isFileVarDecl() &&
@@ -2143,9 +2361,7 @@
   // Fields with the same name and the same type match.
   if (FieldDecl *FDX = dyn_cast<FieldDecl>(X)) {
     FieldDecl *FDY = cast<FieldDecl>(Y);
-    // FIXME: Diagnose if the types don't match. More generally, diagnose if we
-    // get a declaration in a class definition that isn't in the canonical class
-    // definition.
+    // FIXME: Diagnose if the types don't match.
     // FIXME: Also check the bitwidth is odr-equivalent, if any.
     return X->getASTContext().hasSameType(FDX->getType(), FDY->getType());
   }
@@ -2175,9 +2391,10 @@
     return RD->getDefinition();
 
   if (EnumDecl *ED = dyn_cast<EnumDecl>(DC))
-    return ED->getASTContext().getLangOpts().CPlusPlus? ED->getDefinition() : 0;
+    return ED->getASTContext().getLangOpts().CPlusPlus? ED->getDefinition()
+                                                      : nullptr;
 
-  return 0;
+  return nullptr;
 }
 
 ASTDeclReader::FindExistingResult::~FindExistingResult() {
@@ -2198,7 +2415,9 @@
   DeclarationName Name = D->getDeclName();
   if (!Name) {
     // Don't bother trying to find unnamed declarations.
-    FindExistingResult Result(Reader, D, /*Existing=*/0);
+    FindExistingResult Result(Reader, D, /*Existing=*/nullptr);
+    // FIXME: We may still need to pull in the redeclaration chain; there can
+    // be redeclarations via 'decltype'.
     Result.suppress();
     return Result;
   }
@@ -2252,33 +2471,34 @@
 
   // If this declaration is from a merged context, make a note that we need to
   // check that the canonical definition of that context contains the decl.
+  //
+  // FIXME: We should do something similar if we merge two definitions of the
+  // same template specialization into the same CXXRecordDecl.
   if (Reader.MergedDeclContexts.count(D->getLexicalDeclContext()))
     Reader.PendingOdrMergeChecks.push_back(D);
 
-  return FindExistingResult(Reader, D, /*Existing=*/0);
+  return FindExistingResult(Reader, D, /*Existing=*/nullptr);
 }
 
-void ASTDeclReader::attachPreviousDecl(Decl *D, Decl *previous) {
-  assert(D && previous);
-  if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
-    TD->RedeclLink.setNext(cast<TagDecl>(previous));
-  } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
-    FD->RedeclLink.setNext(cast<FunctionDecl>(previous));
-  } else if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
-    VD->RedeclLink.setNext(cast<VarDecl>(previous));
-  } else if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
-    TD->RedeclLink.setNext(cast<TypedefNameDecl>(previous));
-  } else if (UsingShadowDecl *USD = dyn_cast<UsingShadowDecl>(D)) {
-    USD->RedeclLink.setNext(cast<UsingShadowDecl>(previous));
-  } else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
-    ID->RedeclLink.setNext(cast<ObjCInterfaceDecl>(previous));
-  } else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) {
-    PD->RedeclLink.setNext(cast<ObjCProtocolDecl>(previous));
-  } else if (NamespaceDecl *ND = dyn_cast<NamespaceDecl>(D)) {
-    ND->RedeclLink.setNext(cast<NamespaceDecl>(previous));
-  } else {
-    RedeclarableTemplateDecl *TD = cast<RedeclarableTemplateDecl>(D);
-    TD->RedeclLink.setNext(cast<RedeclarableTemplateDecl>(previous));
+template<typename DeclT>
+void ASTDeclReader::attachPreviousDeclImpl(Redeclarable<DeclT> *D,
+                                           Decl *Previous) {
+  D->RedeclLink.setPrevious(cast<DeclT>(Previous));
+}
+void ASTDeclReader::attachPreviousDeclImpl(...) {
+  llvm_unreachable("attachPreviousDecl on non-redeclarable declaration");
+}
+
+void ASTDeclReader::attachPreviousDecl(Decl *D, Decl *Previous) {
+  assert(D && Previous);
+
+  switch (D->getKind()) {
+#define ABSTRACT_DECL(TYPE)
+#define DECL(TYPE, BASE)                                   \
+  case Decl::TYPE:                                         \
+    attachPreviousDeclImpl(cast<TYPE##Decl>(D), Previous); \
+    break;
+#include "clang/AST/DeclNodes.inc"
   }
 
   // If the declaration was visible in one module, a redeclaration of it in
@@ -2287,46 +2507,78 @@
   // FIXME: In this case, the declaration should only be visible if a module
   //        that makes it visible has been imported.
   D->IdentifierNamespace |=
-      previous->IdentifierNamespace &
+      Previous->IdentifierNamespace &
       (Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Type);
+
+  // If the previous declaration is marked as used, then this declaration should
+  // be too.
+  if (Previous->Used)
+    D->Used = true;
+
+  // If the previous declaration is an inline function declaration, then this
+  // declaration is too.
+  if (auto *FD = dyn_cast<FunctionDecl>(D)) {
+    if (cast<FunctionDecl>(Previous)->IsInline != FD->IsInline) {
+      // FIXME: [dcl.fct.spec]p4:
+      //   If a function with external linkage is declared inline in one
+      //   translation unit, it shall be declared inline in all translation
+      //   units in which it appears.
+      //
+      // Be careful of this case:
+      //
+      // module A:
+      //   template<typename T> struct X { void f(); };
+      //   template<typename T> inline void X<T>::f() {}
+      //
+      // module B instantiates the declaration of X<int>::f
+      // module C instantiates the definition of X<int>::f
+      //
+      // If module B and C are merged, we do not have a violation of this rule.
+      //
+      //if (!FD->IsInline || Previous->getOwningModule())
+      //  Diag(FD->getLocation(), diag::err_odr_differing_inline);
+      FD->IsInline = true;
+    }
+  }
+}
+
+template<typename DeclT>
+void ASTDeclReader::attachLatestDeclImpl(Redeclarable<DeclT> *D, Decl *Latest) {
+  D->RedeclLink.setLatest(cast<DeclT>(Latest));
+}
+void ASTDeclReader::attachLatestDeclImpl(...) {
+  llvm_unreachable("attachLatestDecl on non-redeclarable declaration");
 }
 
 void ASTDeclReader::attachLatestDecl(Decl *D, Decl *Latest) {
   assert(D && Latest);
-  if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
-    TD->RedeclLink
-      = Redeclarable<TagDecl>::LatestDeclLink(cast<TagDecl>(Latest));
-  } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
-    FD->RedeclLink
-      = Redeclarable<FunctionDecl>::LatestDeclLink(cast<FunctionDecl>(Latest));
-  } else if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
-    VD->RedeclLink
-      = Redeclarable<VarDecl>::LatestDeclLink(cast<VarDecl>(Latest));
-  } else if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
-    TD->RedeclLink
-      = Redeclarable<TypedefNameDecl>::LatestDeclLink(
-                                                cast<TypedefNameDecl>(Latest));
-  } else if (UsingShadowDecl *USD = dyn_cast<UsingShadowDecl>(D)) {
-    USD->RedeclLink
-      = Redeclarable<UsingShadowDecl>::LatestDeclLink(
-                                             cast<UsingShadowDecl>(Latest));
-  } else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
-    ID->RedeclLink
-      = Redeclarable<ObjCInterfaceDecl>::LatestDeclLink(
-                                              cast<ObjCInterfaceDecl>(Latest));
-  } else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) {
-    PD->RedeclLink
-      = Redeclarable<ObjCProtocolDecl>::LatestDeclLink(
-                                                cast<ObjCProtocolDecl>(Latest));
-  } else if (NamespaceDecl *ND = dyn_cast<NamespaceDecl>(D)) {
-    ND->RedeclLink
-      = Redeclarable<NamespaceDecl>::LatestDeclLink(
-                                                   cast<NamespaceDecl>(Latest));
-  } else {
-    RedeclarableTemplateDecl *TD = cast<RedeclarableTemplateDecl>(D);
-    TD->RedeclLink
-      = Redeclarable<RedeclarableTemplateDecl>::LatestDeclLink(
-                                        cast<RedeclarableTemplateDecl>(Latest));
+
+  switch (D->getKind()) {
+#define ABSTRACT_DECL(TYPE)
+#define DECL(TYPE, BASE)                                  \
+  case Decl::TYPE:                                        \
+    attachLatestDeclImpl(cast<TYPE##Decl>(D), Latest); \
+    break;
+#include "clang/AST/DeclNodes.inc"
+  }
+}
+
+template<typename DeclT>
+void ASTDeclReader::markIncompleteDeclChainImpl(Redeclarable<DeclT> *D) {
+  D->RedeclLink.markIncomplete();
+}
+void ASTDeclReader::markIncompleteDeclChainImpl(...) {
+  llvm_unreachable("markIncompleteDeclChain on non-redeclarable declaration");
+}
+
+void ASTReader::markIncompleteDeclChain(Decl *D) {
+  switch (D->getKind()) {
+#define ABSTRACT_DECL(TYPE)
+#define DECL(TYPE, BASE)                                             \
+  case Decl::TYPE:                                                   \
+    ASTDeclReader::markIncompleteDeclChainImpl(cast<TYPE##Decl>(D)); \
+    break;
+#include "clang/AST/DeclNodes.inc"
   }
 }
 
@@ -2374,7 +2626,7 @@
   unsigned Idx = 0;
   ASTDeclReader Reader(*this, *Loc.F, ID, RawLocation, Record,Idx);
 
-  Decl *D = 0;
+  Decl *D = nullptr;
   switch ((DeclCode)DeclsCursor.readRecord(Code, Record)) {
   case DECL_CONTEXT_LEXICAL:
   case DECL_CONTEXT_VISIBLE:
@@ -2556,7 +2808,7 @@
     break;
   case DECL_CXX_BASE_SPECIFIERS:
     Error("attempt to read a C++ base-specifier record as a declaration");
-    return 0;
+    return nullptr;
   case DECL_IMPORT:
     // Note: last entry of the ImportDecl record is the number of stored source 
     // locations.
@@ -2595,7 +2847,7 @@
         LookupDC->setHasExternalVisibleStorage(true);
       if (ReadDeclContextStorage(*Loc.F, DeclsCursor, Offsets, 
                                  Loc.F->DeclContextInfos[DC]))
-        return 0;
+        return nullptr;
     }
 
     // Now add the pending visible updates for this decl context, if it has any.
@@ -2605,12 +2857,10 @@
       // There are updates. This means the context has external visible
       // storage, even if the original stored version didn't.
       LookupDC->setHasExternalVisibleStorage(true);
-      DeclContextVisibleUpdates &U = I->second;
-      for (DeclContextVisibleUpdates::iterator UI = U.begin(), UE = U.end();
-           UI != UE; ++UI) {
-        DeclContextInfo &Info = UI->second->DeclContextInfos[DC];
+      for (const auto &Update : I->second) {
+        DeclContextInfo &Info = Update.second->DeclContextInfos[DC];
         delete Info.NameLookupTableData;
-        Info.NameLookupTableData = UI->first;
+        Info.NameLookupTableData = Update.first;
       }
       PendingVisibleUpdates.erase(I);
     }
@@ -2618,7 +2868,7 @@
   assert(Idx == Record.size());
 
   // Load any relevant update records.
-  loadDeclUpdateRecords(ID, D);
+  PendingUpdateRecords.push_back(std::make_pair(ID, D));
 
   // Load the categories after recursive loading is finished.
   if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D))
@@ -2642,6 +2892,7 @@
   DeclUpdateOffsetsMap::iterator UpdI = DeclUpdateOffsets.find(ID);
   if (UpdI != DeclUpdateOffsets.end()) {
     FileOffsetsTy &UpdateOffsets = UpdI->second;
+    bool WasInteresting = isConsumerInterestedIn(D, false);
     for (FileOffsetsTy::iterator
          I = UpdateOffsets.begin(), E = UpdateOffsets.end(); I != E; ++I) {
       ModuleFile *F = I->first;
@@ -2654,33 +2905,23 @@
       unsigned RecCode = Cursor.readRecord(Code, Record);
       (void)RecCode;
       assert(RecCode == DECL_UPDATES && "Expected DECL_UPDATES record!");
-      
+
       unsigned Idx = 0;
       ASTDeclReader Reader(*this, *F, ID, 0, Record, Idx);
       Reader.UpdateDecl(D, *F, Record);
+
+      // We might have made this declaration interesting. If so, remember that
+      // we need to hand it off to the consumer.
+      if (!WasInteresting &&
+          isConsumerInterestedIn(D, Reader.hasPendingBody())) {
+        InterestingDecls.push_back(D);
+        WasInteresting = true;
+      }
     }
   }
 }
 
 namespace {
-  struct CompareLocalRedeclarationsInfoToID {
-    bool operator()(const LocalRedeclarationsInfo &X, DeclID Y) {
-      return X.FirstID < Y;
-    }
-
-    bool operator()(DeclID X, const LocalRedeclarationsInfo &Y) {
-      return X < Y.FirstID;
-    }
-
-    bool operator()(const LocalRedeclarationsInfo &X, 
-                    const LocalRedeclarationsInfo &Y) {
-      return X.FirstID < Y.FirstID;
-    }
-    bool operator()(DeclID X, DeclID Y) {
-      return X < Y;
-    }
-  };
-  
   /// \brief Module visitor class that finds all of the redeclarations of a 
   /// 
   class RedeclChainVisitor {
@@ -2724,10 +2965,11 @@
       
       // Perform a binary search to find the local redeclarations for this
       // declaration (if any).
+      const LocalRedeclarationsInfo Compare = { ID, 0 };
       const LocalRedeclarationsInfo *Result
         = std::lower_bound(M.RedeclarationsMap,
                            M.RedeclarationsMap + M.LocalNumRedeclarationsInMap, 
-                           ID, CompareLocalRedeclarationsInfoToID());
+                           Compare);
       if (Result == M.RedeclarationsMap + M.LocalNumRedeclarationsInMap ||
           Result->FirstID != ID) {
         // If we have a previously-canonical singleton declaration that was 
@@ -2755,6 +2997,8 @@
       // Visit each of the declarations.
       for (unsigned I = 0, N = SearchDecls.size(); I != N; ++I)
         searchForID(M, SearchDecls[I]);
+      // FIXME: If none of the SearchDecls had local IDs in this module, can
+      // we avoid searching any ancestor module files?
       return false;
     }
     
@@ -2802,24 +3046,6 @@
 }
 
 namespace {
-  struct CompareObjCCategoriesInfo {
-    bool operator()(const ObjCCategoriesInfo &X, DeclID Y) {
-      return X.DefinitionID < Y;
-    }
-    
-    bool operator()(DeclID X, const ObjCCategoriesInfo &Y) {
-      return X < Y.DefinitionID;
-    }
-    
-    bool operator()(const ObjCCategoriesInfo &X, 
-                    const ObjCCategoriesInfo &Y) {
-      return X.DefinitionID < Y.DefinitionID;
-    }
-    bool operator()(DeclID X, DeclID Y) {
-      return X < Y;
-    }
-  };
-
   /// \brief Given an ObjC interface, goes through the modules and links to the
   /// interface all the categories for it.
   class ObjCCategoriesVisitor {
@@ -2878,18 +3104,15 @@
                           unsigned PreviousGeneration)
       : Reader(Reader), InterfaceID(InterfaceID), Interface(Interface),
         Deserialized(Deserialized), PreviousGeneration(PreviousGeneration),
-        Tail(0) 
+        Tail(nullptr)
     {
       // Populate the name -> category map with the set of known categories.
-      for (ObjCInterfaceDecl::known_categories_iterator
-             Cat = Interface->known_categories_begin(),
-             CatEnd = Interface->known_categories_end();
-           Cat != CatEnd; ++Cat) {
+      for (auto *Cat : Interface->known_categories()) {
         if (Cat->getDeclName())
-          NameCategoryMap[Cat->getDeclName()] = *Cat;
+          NameCategoryMap[Cat->getDeclName()] = Cat;
         
         // Keep track of the tail of the category list.
-        Tail = *Cat;
+        Tail = Cat;
       }
     }
 
@@ -2912,10 +3135,11 @@
 
       // Perform a binary search to find the local redeclarations for this
       // declaration (if any).
+      const ObjCCategoriesInfo Compare = { LocalID, 0 };
       const ObjCCategoriesInfo *Result
         = std::lower_bound(M.ObjCCategoriesMap,
                            M.ObjCCategoriesMap + M.LocalNumObjCCategoriesInMap, 
-                           LocalID, CompareObjCCategoriesInfo());
+                           Compare);
       if (Result == M.ObjCCategoriesMap + M.LocalNumObjCCategoriesInMap ||
           Result->DefinitionID != LocalID) {
         // We didn't find anything. If the class definition is in this module
@@ -2946,12 +3170,14 @@
 
 void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,
                                const RecordData &Record) {
-  unsigned Idx = 0;
   while (Idx < Record.size()) {
     switch ((DeclUpdateKind)Record[Idx++]) {
-    case UPD_CXX_ADDED_IMPLICIT_MEMBER:
-      cast<CXXRecordDecl>(D)->addedMember(Reader.ReadDecl(ModuleFile, Record, Idx));
+    case UPD_CXX_ADDED_IMPLICIT_MEMBER: {
+      Decl *MD = Reader.ReadDecl(ModuleFile, Record, Idx);
+      assert(MD && "couldn't read decl from update record");
+      cast<CXXRecordDecl>(D)->addedMember(MD);
       break;
+    }
 
     case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION:
       // It will be added to the template's specializations set when loaded.
@@ -2979,6 +3205,96 @@
           Reader.ReadSourceLocation(ModuleFile, Record, Idx));
       break;
 
+    case UPD_CXX_INSTANTIATED_FUNCTION_DEFINITION: {
+      FunctionDecl *FD = cast<FunctionDecl>(D);
+      if (Reader.PendingBodies[FD]) {
+        // FIXME: Maybe check for ODR violations.
+        // It's safe to stop now because this update record is always last.
+        return;
+      }
+
+      if (Record[Idx++]) {
+        // Maintain AST consistency: any later redeclarations of this function
+        // are inline if this one is. (We might have merged another declaration
+        // into this one.)
+        for (auto *D = FD->getMostRecentDecl(); /**/;
+             D = D->getPreviousDecl()) {
+          D->setImplicitlyInline();
+          if (D == FD)
+            break;
+        }
+      }
+      FD->setInnerLocStart(Reader.ReadSourceLocation(ModuleFile, Record, Idx));
+      if (auto *CD = dyn_cast<CXXConstructorDecl>(FD))
+        std::tie(CD->CtorInitializers, CD->NumCtorInitializers) =
+            Reader.ReadCXXCtorInitializers(ModuleFile, 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");
+      break;
+    }
+
+    case UPD_CXX_INSTANTIATED_CLASS_DEFINITION: {
+      auto *RD = cast<CXXRecordDecl>(D);
+      bool HadDefinition = RD->getDefinition();
+      ReadCXXRecordDefinition(RD);
+      // Visible update is handled separately.
+      uint64_t LexicalOffset = Record[Idx++];
+      if (!HadDefinition && LexicalOffset) {
+        RD->setHasExternalLexicalStorage(true);
+        Reader.ReadDeclContextStorage(ModuleFile, ModuleFile.DeclsCursor,
+                                          std::make_pair(LexicalOffset, 0),
+                                          ModuleFile.DeclContextInfos[RD]);
+      }
+
+      auto TSK = (TemplateSpecializationKind)Record[Idx++];
+      SourceLocation POI = Reader.ReadSourceLocation(ModuleFile, Record, Idx);
+      if (MemberSpecializationInfo *MSInfo =
+              RD->getMemberSpecializationInfo()) {
+        MSInfo->setTemplateSpecializationKind(TSK);
+        MSInfo->setPointOfInstantiation(POI);
+      } else {
+        ClassTemplateSpecializationDecl *Spec =
+            cast<ClassTemplateSpecializationDecl>(RD);
+        Spec->setTemplateSpecializationKind(TSK);
+        Spec->setPointOfInstantiation(POI);
+
+        if (Record[Idx++]) {
+          auto PartialSpec =
+              ReadDeclAs<ClassTemplatePartialSpecializationDecl>(Record, Idx);
+          SmallVector<TemplateArgument, 8> TemplArgs;
+          Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx);
+          auto *TemplArgList = TemplateArgumentList::CreateCopy(
+              Reader.getContext(), TemplArgs.data(), TemplArgs.size());
+          Spec->setInstantiationOf(PartialSpec, TemplArgList);
+        }
+      }
+
+      RD->setTagKind((TagTypeKind)Record[Idx++]);
+      RD->setLocation(Reader.ReadSourceLocation(ModuleFile, Record, Idx));
+      RD->setLocStart(Reader.ReadSourceLocation(ModuleFile, Record, Idx));
+      RD->setRBraceLoc(Reader.ReadSourceLocation(ModuleFile, Record, Idx));
+
+      if (Record[Idx++]) {
+        AttrVec Attrs;
+        Reader.ReadAttributes(F, Attrs, Record, Idx);
+        D->setAttrsImpl(Attrs, Reader.getContext());
+      }
+      break;
+    }
+
+    case UPD_CXX_RESOLVED_EXCEPTION_SPEC: {
+      auto *FD = cast<FunctionDecl>(D);
+      auto *FPT = FD->getType()->castAs<FunctionProtoType>();
+      auto EPI = FPT->getExtProtoInfo();
+      SmallVector<QualType, 8> ExceptionStorage;
+      Reader.readExceptionSpec(ModuleFile, ExceptionStorage, EPI, Record, Idx);
+      FD->setType(Reader.Context.getFunctionType(FPT->getReturnType(),
+                                                 FPT->getParamTypes(), EPI));
+      break;
+    }
+
     case UPD_CXX_DEDUCED_RETURN_TYPE: {
       FunctionDecl *FD = cast<FunctionDecl>(D);
       Reader.Context.adjustDeducedFunctionResultType(
@@ -2989,9 +3305,28 @@
     case UPD_DECL_MARKED_USED: {
       // FIXME: This doesn't send the right notifications if there are
       // ASTMutationListeners other than an ASTWriter.
-      D->Used = true;
+
+      // FIXME: We can't both pull in declarations (and thus create new pending
+      // redeclaration chains) *and* walk redeclaration chains in this function.
+      // We should defer the updates that require walking redecl chains.
+
+      // Maintain AST consistency: any later redeclarations are used too.
+      for (auto *Redecl = D->getMostRecentDecl(); /**/;
+           Redecl = Redecl->getPreviousDecl()) {
+        Redecl->Used = true;
+        if (Redecl == D)
+          break;
+      }
       break;
     }
+
+    case UPD_MANGLING_NUMBER:
+      Reader.Context.setManglingNumber(cast<NamedDecl>(D), Record[Idx++]);
+      break;
+
+    case UPD_STATIC_LOCAL_NUMBER:
+      Reader.Context.setStaticLocalNumber(cast<VarDecl>(D), Record[Idx++]);
+      break;
     }
   }
 }
diff --git a/lib/Serialization/ASTReaderInternals.h b/lib/Serialization/ASTReaderInternals.h
index 9149b18..a63e362 100644
--- a/lib/Serialization/ASTReaderInternals.h
+++ b/lib/Serialization/ASTReaderInternals.h
@@ -14,10 +14,9 @@
 #define LLVM_CLANG_SERIALIZATION_ASTREADER_INTERNALS_H
 
 #include "clang/AST/DeclarationName.h"
-#include "clang/Basic/OnDiskHashTable.h"
 #include "clang/Serialization/ASTBitCodes.h"
 #include "llvm/Support/Endian.h"
-#include <sys/stat.h>
+#include "llvm/Support/OnDiskHashTable.h"
 #include <utility>
 
 namespace clang {
@@ -46,6 +45,8 @@
   /// particular lookup t
   typedef llvm::support::ulittle32_t LE32DeclID;
   typedef std::pair<LE32DeclID *, LE32DeclID *> data_type;
+  typedef unsigned hash_value_type;
+  typedef unsigned offset_type;
 
   /// \brief Special internal key for declaration names.
   /// The hash table creates keys for comparison; we do not create
@@ -67,7 +68,7 @@
     return a.Kind == b.Kind && a.Data == b.Data;
   }
 
-  unsigned ComputeHash(const DeclNameKey &Key) const;
+  hash_value_type ComputeHash(const DeclNameKey &Key) const;
   internal_key_type GetInternalKey(const external_key_type& Name) const;
 
   static std::pair<unsigned, unsigned>
@@ -92,13 +93,14 @@
 public:
   typedef StringRef external_key_type;
   typedef StringRef internal_key_type;
-  
+  typedef unsigned hash_value_type;
+  typedef unsigned offset_type;
 
   static bool EqualKey(const internal_key_type& a, const internal_key_type& b) {
     return a == b;
   }
 
-  static unsigned ComputeHash(const internal_key_type& a);
+  static hash_value_type ComputeHash(const internal_key_type& a);
  
   static std::pair<unsigned, unsigned>
   ReadKeyDataLength(const unsigned char*& d);
@@ -126,11 +128,11 @@
   
 public:
   typedef IdentifierInfo * data_type;
-  
+
   ASTIdentifierLookupTrait(ASTReader &Reader, ModuleFile &F,
-                           IdentifierInfo *II = 0)
+                           IdentifierInfo *II = nullptr)
     : Reader(Reader), F(F), KnownII(II) { }
-       
+
   data_type ReadData(const internal_key_type& k,
                      const unsigned char* d,
                      unsigned DataLen);
@@ -140,7 +142,7 @@
   
 /// \brief The on-disk hash table used to contain information about
 /// all of the identifiers in the program.
-typedef OnDiskChainedHashTable<ASTIdentifierLookupTrait>
+typedef llvm::OnDiskIterableChainedHashTable<ASTIdentifierLookupTrait>
   ASTIdentifierLookupTable;
 
 /// \brief Class that performs lookup for a selector's entries in the global
@@ -160,6 +162,8 @@
   
   typedef Selector external_key_type;
   typedef external_key_type internal_key_type;
+  typedef unsigned hash_value_type;
+  typedef unsigned offset_type;
   
   ASTSelectorLookupTrait(ASTReader &Reader, ModuleFile &F) 
     : Reader(Reader), F(F) { }
@@ -169,7 +173,7 @@
     return a == b;
   }
   
-  static unsigned ComputeHash(Selector Sel);
+  static hash_value_type ComputeHash(Selector Sel);
   
   static const internal_key_type&
   GetInternalKey(const external_key_type& x) { return x; }
@@ -182,7 +186,7 @@
 };
   
 /// \brief The on-disk hash table used for the global method pool.
-typedef OnDiskChainedHashTable<ASTSelectorLookupTrait>
+typedef llvm::OnDiskChainedHashTable<ASTSelectorLookupTrait>
   ASTSelectorLookupTable;
   
 /// \brief Trait class used to search the on-disk hash table containing all of
@@ -211,12 +215,14 @@
   typedef const internal_key_type &internal_key_ref;
   
   typedef HeaderFileInfo data_type;
+  typedef unsigned hash_value_type;
+  typedef unsigned offset_type;
   
   HeaderFileInfoTrait(ASTReader &Reader, ModuleFile &M, HeaderSearch *HS,
                       const char *FrameworkStrings)
   : Reader(Reader), M(M), HS(HS), FrameworkStrings(FrameworkStrings) { }
   
-  static unsigned ComputeHash(internal_key_ref ikey);
+  static hash_value_type ComputeHash(internal_key_ref ikey);
   static internal_key_type GetInternalKey(const FileEntry *FE);
   bool EqualKey(internal_key_ref a, internal_key_ref b);
   
@@ -229,7 +235,7 @@
 };
 
 /// \brief The on-disk hash table used for known header files.
-typedef OnDiskChainedHashTable<HeaderFileInfoTrait>
+typedef llvm::OnDiskChainedHashTable<HeaderFileInfoTrait>
   HeaderFileInfoLookupTable;
   
 } // end namespace clang::serialization::reader
diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp
index 1115e8f..8bf17d5 100644
--- a/lib/Serialization/ASTReaderStmt.cpp
+++ b/lib/Serialization/ASTReaderStmt.cpp
@@ -176,7 +176,7 @@
   (void)NumAttrs;
   assert(NumAttrs == S->NumAttrs);
   assert(NumAttrs == Attrs.size());
-  std::copy(Attrs.begin(), Attrs.end(), S->Attrs);
+  std::copy(Attrs.begin(), Attrs.end(), S->getAttrArrayPtr());
   S->SubStmt = Reader.ReadSubStmt();
   S->AttrLoc = ReadSourceLocation(Record, Idx);
 }
@@ -202,7 +202,7 @@
   if (Record[Idx++])
     S->setAllEnumCasesCovered();
 
-  SwitchCase *PrevSC = 0;
+  SwitchCase *PrevSC = nullptr;
   for (unsigned N = Record.size(); Idx != N; ++Idx) {
     SwitchCase *SC = Reader.getSwitchCaseWithID(Record[Idx]);
     if (PrevSC)
@@ -399,13 +399,11 @@
   S->getCapturedDecl()->setBody(S->getCapturedStmt());
 
   // Captures
-  for (CapturedStmt::capture_iterator I = S->capture_begin(),
-                                      E = S->capture_end();
-       I != E; ++I) {
-    I->VarAndKind.setPointer(ReadDeclAs<VarDecl>(Record, Idx));
-    I->VarAndKind
+  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.Loc = ReadSourceLocation(Record, Idx);
   }
 }
 
@@ -718,7 +716,7 @@
   E->setLBraceLoc(ReadSourceLocation(Record, Idx));
   E->setRBraceLoc(ReadSourceLocation(Record, Idx));
   bool isArrayFiller = Record[Idx++];
-  Expr *filler = 0;
+  Expr *filler = nullptr;
   if (isArrayFiller) {
     filler = Reader.ReadSubExpr();
     E->ArrayFillerOrUnionFieldInit = filler;
@@ -1198,6 +1196,7 @@
   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);
@@ -1484,33 +1483,15 @@
   E->NamingClass = ReadDeclAs<CXXRecordDecl>(Record, Idx);
 }
 
-void ASTStmtReader::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
-  VisitExpr(E);
-  E->UTT = (UnaryTypeTrait)Record[Idx++];
-  E->Value = (bool)Record[Idx++];
-  SourceRange Range = ReadSourceRange(Record, Idx);
-  E->Loc = Range.getBegin();
-  E->RParen = Range.getEnd();
-  E->QueriedType = GetTypeSourceInfo(Record, Idx);
-}
-
-void ASTStmtReader::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
-  VisitExpr(E);
-  E->BTT = (BinaryTypeTrait)Record[Idx++];
-  E->Value = (bool)Record[Idx++];
-  SourceRange Range = ReadSourceRange(Record, Idx);
-  E->Loc = Range.getBegin();
-  E->RParen = Range.getEnd();
-  E->LhsType = GetTypeSourceInfo(Record, Idx);
-  E->RhsType = GetTypeSourceInfo(Record, Idx);
-}
-
 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->Loc = Range.getBegin();
+  E->RParenLoc = Range.getEnd();
+
   TypeSourceInfo **Args = E->getTypeSourceInfos();
   for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
     Args[I] = GetTypeSourceInfo(Record, Idx);
@@ -1592,8 +1573,10 @@
 
 void ASTStmtReader::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
   VisitExpr(E);
-  E->Temporary = Reader.ReadSubExpr();
-  E->ExtendingDecl = ReadDeclAs<ValueDecl>(Record, Idx);
+  E->State = Reader.ReadSubExpr();
+  auto VD = ReadDeclAs<ValueDecl>(Record, Idx);
+  unsigned ManglingNumber = Record[Idx++];
+  E->setExtendingDecl(VD, ManglingNumber);
 }
 
 void ASTStmtReader::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
@@ -1627,6 +1610,11 @@
   E->setExprOperand(Reader.ReadSubExpr());
 }
 
+void ASTStmtReader::VisitSEHLeaveStmt(SEHLeaveStmt *S) {
+  VisitStmt(S);
+  S->setLeaveLoc(ReadSourceLocation(Record, Idx));
+}
+
 void ASTStmtReader::VisitSEHExceptStmt(SEHExceptStmt *S) {
   VisitStmt(S);
   S->Loc = ReadSourceLocation(Record, Idx);
@@ -1691,18 +1679,72 @@
 OMPClause *OMPClauseReader::readClause() {
   OMPClause *C;
   switch (Record[Idx++]) {
+  case OMPC_if:
+    C = new (Context) OMPIfClause();
+    break;
+  case OMPC_final:
+    C = new (Context) OMPFinalClause();
+    break;
+  case OMPC_num_threads:
+    C = new (Context) OMPNumThreadsClause();
+    break;
+  case OMPC_safelen:
+    C = new (Context) OMPSafelenClause();
+    break;
+  case OMPC_collapse:
+    C = new (Context) OMPCollapseClause();
+    break;
   case OMPC_default:
     C = new (Context) OMPDefaultClause();
     break;
+  case OMPC_proc_bind:
+    C = new (Context) OMPProcBindClause();
+    break;
+  case OMPC_schedule:
+    C = new (Context) OMPScheduleClause();
+    break;
+  case OMPC_ordered:
+    C = new (Context) OMPOrderedClause();
+    break;
+  case OMPC_nowait:
+    C = new (Context) OMPNowaitClause();
+    break;
+  case OMPC_untied:
+    C = new (Context) OMPUntiedClause();
+    break;
+  case OMPC_mergeable:
+    C = new (Context) OMPMergeableClause();
+    break;
   case OMPC_private:
     C = OMPPrivateClause::CreateEmpty(Context, Record[Idx++]);
     break;
   case OMPC_firstprivate:
     C = OMPFirstprivateClause::CreateEmpty(Context, Record[Idx++]);
     break;
+  case OMPC_lastprivate:
+    C = OMPLastprivateClause::CreateEmpty(Context, Record[Idx++]);
+    break;
   case OMPC_shared:
     C = OMPSharedClause::CreateEmpty(Context, Record[Idx++]);
     break;
+  case OMPC_reduction:
+    C = OMPReductionClause::CreateEmpty(Context, Record[Idx++]);
+    break;
+  case OMPC_linear:
+    C = OMPLinearClause::CreateEmpty(Context, Record[Idx++]);
+    break;
+  case OMPC_aligned:
+    C = OMPAlignedClause::CreateEmpty(Context, Record[Idx++]);
+    break;
+  case OMPC_copyin:
+    C = OMPCopyinClause::CreateEmpty(Context, Record[Idx++]);
+    break;
+  case OMPC_copyprivate:
+    C = OMPCopyprivateClause::CreateEmpty(Context, Record[Idx++]);
+    break;
+  case OMPC_flush:
+    C = OMPFlushClause::CreateEmpty(Context, Record[Idx++]);
+    break;
   }
   Visit(C);
   C->setLocStart(Reader->ReadSourceLocation(Record, Idx));
@@ -1711,6 +1753,31 @@
   return C;
 }
 
+void OMPClauseReader::VisitOMPIfClause(OMPIfClause *C) {
+  C->setCondition(Reader->Reader.ReadSubExpr());
+  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+}
+
+void OMPClauseReader::VisitOMPFinalClause(OMPFinalClause *C) {
+  C->setCondition(Reader->Reader.ReadSubExpr());
+  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+}
+
+void OMPClauseReader::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) {
+  C->setNumThreads(Reader->Reader.ReadSubExpr());
+  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+}
+
+void OMPClauseReader::VisitOMPSafelenClause(OMPSafelenClause *C) {
+  C->setSafelen(Reader->Reader.ReadSubExpr());
+  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+}
+
+void OMPClauseReader::VisitOMPCollapseClause(OMPCollapseClause *C) {
+  C->setNumForLoops(Reader->Reader.ReadSubExpr());
+  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+}
+
 void OMPClauseReader::VisitOMPDefaultClause(OMPDefaultClause *C) {
   C->setDefaultKind(
        static_cast<OpenMPDefaultClauseKind>(Record[Idx++]));
@@ -1718,6 +1785,30 @@
   C->setDefaultKindKwLoc(Reader->ReadSourceLocation(Record, Idx));
 }
 
+void OMPClauseReader::VisitOMPProcBindClause(OMPProcBindClause *C) {
+  C->setProcBindKind(
+       static_cast<OpenMPProcBindClauseKind>(Record[Idx++]));
+  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  C->setProcBindKindKwLoc(Reader->ReadSourceLocation(Record, Idx));
+}
+
+void OMPClauseReader::VisitOMPScheduleClause(OMPScheduleClause *C) {
+  C->setScheduleKind(
+       static_cast<OpenMPScheduleClauseKind>(Record[Idx++]));
+  C->setChunkSize(Reader->Reader.ReadSubExpr());
+  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  C->setScheduleKindLoc(Reader->ReadSourceLocation(Record, Idx));
+  C->setCommaLoc(Reader->ReadSourceLocation(Record, Idx));
+}
+
+void OMPClauseReader::VisitOMPOrderedClause(OMPOrderedClause *) {}
+
+void OMPClauseReader::VisitOMPNowaitClause(OMPNowaitClause *) {}
+
+void OMPClauseReader::VisitOMPUntiedClause(OMPUntiedClause *) {}
+
+void OMPClauseReader::VisitOMPMergeableClause(OMPMergeableClause *) {}
+
 void OMPClauseReader::VisitOMPPrivateClause(OMPPrivateClause *C) {
   C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
   unsigned NumVars = C->varlist_size();
@@ -1738,6 +1829,16 @@
   C->setVarRefs(Vars);
 }
 
+void OMPClauseReader::VisitOMPLastprivateClause(OMPLastprivateClause *C) {
+  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  unsigned NumVars = C->varlist_size();
+  SmallVector<Expr *, 16> Vars;
+  Vars.reserve(NumVars);
+  for (unsigned i = 0; i != NumVars; ++i)
+    Vars.push_back(Reader->Reader.ReadSubExpr());
+  C->setVarRefs(Vars);
+}
+
 void OMPClauseReader::VisitOMPSharedClause(OMPSharedClause *C) {
   C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
   unsigned NumVars = C->varlist_size();
@@ -1748,12 +1849,82 @@
   C->setVarRefs(Vars);
 }
 
+void OMPClauseReader::VisitOMPReductionClause(OMPReductionClause *C) {
+  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  C->setColonLoc(Reader->ReadSourceLocation(Record, Idx));
+  NestedNameSpecifierLoc NNSL =
+    Reader->Reader.ReadNestedNameSpecifierLoc(Reader->F, Record, Idx);
+  DeclarationNameInfo DNI;
+  Reader->ReadDeclarationNameInfo(DNI, Record, Idx);
+  C->setQualifierLoc(NNSL);
+  C->setNameInfo(DNI);
+
+  unsigned NumVars = C->varlist_size();
+  SmallVector<Expr *, 16> Vars;
+  Vars.reserve(NumVars);
+  for (unsigned i = 0; i != NumVars; ++i)
+    Vars.push_back(Reader->Reader.ReadSubExpr());
+  C->setVarRefs(Vars);
+}
+
+void OMPClauseReader::VisitOMPLinearClause(OMPLinearClause *C) {
+  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  C->setColonLoc(Reader->ReadSourceLocation(Record, Idx));
+  unsigned NumVars = C->varlist_size();
+  SmallVector<Expr *, 16> Vars;
+  Vars.reserve(NumVars);
+  for (unsigned i = 0; i != NumVars; ++i)
+    Vars.push_back(Reader->Reader.ReadSubExpr());
+  C->setVarRefs(Vars);
+  C->setStep(Reader->Reader.ReadSubExpr());
+}
+
+void OMPClauseReader::VisitOMPAlignedClause(OMPAlignedClause *C) {
+  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  C->setColonLoc(Reader->ReadSourceLocation(Record, Idx));
+  unsigned NumVars = C->varlist_size();
+  SmallVector<Expr *, 16> Vars;
+  Vars.reserve(NumVars);
+  for (unsigned i = 0; i != NumVars; ++i)
+    Vars.push_back(Reader->Reader.ReadSubExpr());
+  C->setVarRefs(Vars);
+  C->setAlignment(Reader->Reader.ReadSubExpr());
+}
+
+void OMPClauseReader::VisitOMPCopyinClause(OMPCopyinClause *C) {
+  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  unsigned NumVars = C->varlist_size();
+  SmallVector<Expr *, 16> Vars;
+  Vars.reserve(NumVars);
+  for (unsigned i = 0; i != NumVars; ++i)
+    Vars.push_back(Reader->Reader.ReadSubExpr());
+  C->setVarRefs(Vars);
+}
+
+void OMPClauseReader::VisitOMPCopyprivateClause(OMPCopyprivateClause *C) {
+  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  unsigned NumVars = C->varlist_size();
+  SmallVector<Expr *, 16> Vars;
+  Vars.reserve(NumVars);
+  for (unsigned i = 0; i != NumVars; ++i)
+    Vars.push_back(Reader->Reader.ReadSubExpr());
+  C->setVarRefs(Vars);
+}
+
+void OMPClauseReader::VisitOMPFlushClause(OMPFlushClause *C) {
+  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  unsigned NumVars = C->varlist_size();
+  SmallVector<Expr *, 16> Vars;
+  Vars.reserve(NumVars);
+  for (unsigned i = 0; i != NumVars; ++i)
+    Vars.push_back(Reader->Reader.ReadSubExpr());
+  C->setVarRefs(Vars);
+}
+
 //===----------------------------------------------------------------------===//
 // OpenMP Directives.
 //===----------------------------------------------------------------------===//
 void ASTStmtReader::VisitOMPExecutableDirective(OMPExecutableDirective *E) {
-  VisitStmt(E);
-  ++Idx;
   E->setLocStart(ReadSourceLocation(Record, Idx));
   E->setLocEnd(ReadSourceLocation(Record, Idx));
   OMPClauseReader ClauseReader(this, Reader.getContext(), Record, Idx);
@@ -1761,10 +1932,102 @@
   for (unsigned i = 0; i < E->getNumClauses(); ++i)
     Clauses.push_back(ClauseReader.readClause());
   E->setClauses(Clauses);
-  E->setAssociatedStmt(Reader.ReadSubStmt());
+  if (E->hasAssociatedStmt())
+    E->setAssociatedStmt(Reader.ReadSubStmt());
 }
 
 void ASTStmtReader::VisitOMPParallelDirective(OMPParallelDirective *D) {
+  VisitStmt(D);
+  // The NumClauses field was read in ReadStmtFromStream.
+  ++Idx;
+  VisitOMPExecutableDirective(D);
+}
+
+void ASTStmtReader::VisitOMPSimdDirective(OMPSimdDirective *D) {
+  VisitStmt(D);
+  // Two fields (NumClauses and CollapsedNum) were read in ReadStmtFromStream.
+  Idx += 2;
+  VisitOMPExecutableDirective(D);
+}
+
+void ASTStmtReader::VisitOMPForDirective(OMPForDirective *D) {
+  VisitStmt(D);
+  // Two fields (NumClauses and CollapsedNum) were read in ReadStmtFromStream.
+  Idx += 2;
+  VisitOMPExecutableDirective(D);
+}
+
+void ASTStmtReader::VisitOMPSectionsDirective(OMPSectionsDirective *D) {
+  VisitStmt(D);
+  // The NumClauses field was read in ReadStmtFromStream.
+  ++Idx;
+  VisitOMPExecutableDirective(D);
+}
+
+void ASTStmtReader::VisitOMPSectionDirective(OMPSectionDirective *D) {
+  VisitStmt(D);
+  VisitOMPExecutableDirective(D);
+}
+
+void ASTStmtReader::VisitOMPSingleDirective(OMPSingleDirective *D) {
+  VisitStmt(D);
+  // The NumClauses field was read in ReadStmtFromStream.
+  ++Idx;
+  VisitOMPExecutableDirective(D);
+}
+
+void ASTStmtReader::VisitOMPMasterDirective(OMPMasterDirective *D) {
+  VisitStmt(D);
+  VisitOMPExecutableDirective(D);
+}
+
+void ASTStmtReader::VisitOMPCriticalDirective(OMPCriticalDirective *D) {
+  VisitStmt(D);
+  VisitOMPExecutableDirective(D);
+  ReadDeclarationNameInfo(D->DirName, Record, Idx);
+}
+
+void ASTStmtReader::VisitOMPParallelForDirective(OMPParallelForDirective *D) {
+  VisitStmt(D);
+  // Two fields (NumClauses and CollapsedNum) were read in ReadStmtFromStream.
+  Idx += 2;
+  VisitOMPExecutableDirective(D);
+}
+
+void ASTStmtReader::VisitOMPParallelSectionsDirective(
+    OMPParallelSectionsDirective *D) {
+  VisitStmt(D);
+  // The NumClauses field was read in ReadStmtFromStream.
+  ++Idx;
+  VisitOMPExecutableDirective(D);
+}
+
+void ASTStmtReader::VisitOMPTaskDirective(OMPTaskDirective *D) {
+  VisitStmt(D);
+  // The NumClauses field was read in ReadStmtFromStream.
+  ++Idx;
+  VisitOMPExecutableDirective(D);
+}
+
+void ASTStmtReader::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *D) {
+  VisitStmt(D);
+  VisitOMPExecutableDirective(D);
+}
+
+void ASTStmtReader::VisitOMPBarrierDirective(OMPBarrierDirective *D) {
+  VisitStmt(D);
+  VisitOMPExecutableDirective(D);
+}
+
+void ASTStmtReader::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
+  VisitStmt(D);
+  VisitOMPExecutableDirective(D);
+}
+
+void ASTStmtReader::VisitOMPFlushDirective(OMPFlushDirective *D) {
+  VisitStmt(D);
+  // The NumClauses field was read in ReadStmtFromStream.
+  ++Idx;
   VisitOMPExecutableDirective(D);
 }
 
@@ -1826,7 +2089,7 @@
     case llvm::BitstreamEntry::SubBlock: // Handled for us already.
     case llvm::BitstreamEntry::Error:
       Error("malformed block record in AST file");
-      return 0;
+      return nullptr;
     case llvm::BitstreamEntry::EndBlock:
       goto Done;
     case llvm::BitstreamEntry::Record:
@@ -1834,8 +2097,7 @@
       break;
     }
 
-
-    Stmt *S = 0;
+    Stmt *S = nullptr;
     Idx = 0;
     Record.clear();
     bool Finished = false;
@@ -1853,7 +2115,7 @@
       break;
 
     case STMT_NULL_PTR:
-      S = 0;
+      S = nullptr;
       break;
 
     case STMT_NULL:
@@ -2044,7 +2306,7 @@
 
       S = MemberExpr::Create(Context, Base, IsArrow, QualifierLoc,
                              TemplateKWLoc, MemberD, FoundDecl, MemberNameInfo,
-                             HasTemplateKWAndArgsInfo ? &ArgInfo : 0,
+                             HasTemplateKWAndArgsInfo ? &ArgInfo : nullptr,
                              T, VK, OK);
       ReadDeclarationNameLoc(F, cast<MemberExpr>(S)->MemberDNLoc,
                              MemberD->getDeclName(), Record, Idx);
@@ -2212,6 +2474,9 @@
     case EXPR_OBJC_BOOL_LITERAL:
       S = new (Context) ObjCBoolLiteralExpr(Empty);
       break;
+    case STMT_SEH_LEAVE:
+      S = new (Context) SEHLeaveStmt(Empty);
+      break;
     case STMT_SEH_EXCEPT:
       S = new (Context) SEHExceptStmt(Empty);
       break;
@@ -2238,15 +2503,89 @@
       S = new (Context) MSDependentExistsStmt(SourceLocation(), true,
                                               NestedNameSpecifierLoc(),
                                               DeclarationNameInfo(),
-                                              0);
+                                              nullptr);
       break;
+
     case STMT_OMP_PARALLEL_DIRECTIVE:
       S =
         OMPParallelDirective::CreateEmpty(Context,
                                           Record[ASTStmtReader::NumStmtFields],
                                           Empty);
       break;
-        
+
+    case STMT_OMP_SIMD_DIRECTIVE: {
+      unsigned NumClauses = Record[ASTStmtReader::NumStmtFields];
+      unsigned CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1];
+      S = OMPSimdDirective::CreateEmpty(Context, NumClauses,
+                                        CollapsedNum, Empty);
+      break;
+    }
+
+    case STMT_OMP_FOR_DIRECTIVE: {
+      unsigned NumClauses = Record[ASTStmtReader::NumStmtFields];
+      unsigned CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1];
+      S = OMPForDirective::CreateEmpty(Context, NumClauses, CollapsedNum,
+                                       Empty);
+      break;
+    }
+
+    case STMT_OMP_SECTIONS_DIRECTIVE:
+      S = OMPSectionsDirective::CreateEmpty(
+          Context, Record[ASTStmtReader::NumStmtFields], Empty);
+      break;
+
+    case STMT_OMP_SECTION_DIRECTIVE:
+      S = OMPSectionDirective::CreateEmpty(Context, Empty);
+      break;
+
+    case STMT_OMP_SINGLE_DIRECTIVE:
+      S = OMPSingleDirective::CreateEmpty(
+          Context, Record[ASTStmtReader::NumStmtFields], Empty);
+      break;
+
+    case STMT_OMP_MASTER_DIRECTIVE:
+      S = OMPMasterDirective::CreateEmpty(Context, Empty);
+      break;
+
+    case STMT_OMP_CRITICAL_DIRECTIVE:
+      S = OMPCriticalDirective::CreateEmpty(Context, Empty);
+      break;
+
+    case STMT_OMP_PARALLEL_FOR_DIRECTIVE: {
+      unsigned NumClauses = Record[ASTStmtReader::NumStmtFields];
+      unsigned CollapsedNum = Record[ASTStmtReader::NumStmtFields + 1];
+      S = OMPParallelForDirective::CreateEmpty(Context, NumClauses,
+                                               CollapsedNum, Empty);
+      break;
+    }
+
+    case STMT_OMP_PARALLEL_SECTIONS_DIRECTIVE:
+      S = OMPParallelSectionsDirective::CreateEmpty(
+          Context, Record[ASTStmtReader::NumStmtFields], Empty);
+      break;
+
+    case STMT_OMP_TASK_DIRECTIVE:
+      S = OMPTaskDirective::CreateEmpty(
+          Context, Record[ASTStmtReader::NumStmtFields], Empty);
+      break;
+
+    case STMT_OMP_TASKYIELD_DIRECTIVE:
+      S = OMPTaskyieldDirective::CreateEmpty(Context, Empty);
+      break;
+
+    case STMT_OMP_BARRIER_DIRECTIVE:
+      S = OMPBarrierDirective::CreateEmpty(Context, Empty);
+      break;
+
+    case STMT_OMP_TASKWAIT_DIRECTIVE:
+      S = OMPTaskwaitDirective::CreateEmpty(Context, Empty);
+      break;
+
+    case STMT_OMP_FLUSH_DIRECTIVE:
+      S = OMPFlushDirective::CreateEmpty(
+          Context, Record[ASTStmtReader::NumStmtFields], Empty);
+      break;
+
     case EXPR_CXX_OPERATOR_CALL:
       S = new (Context) CXXOperatorCallExpr(Context, Empty);
       break;
@@ -2254,11 +2593,11 @@
     case EXPR_CXX_MEMBER_CALL:
       S = new (Context) CXXMemberCallExpr(Context, Empty);
       break;
-        
+
     case EXPR_CXX_CONSTRUCT:
       S = new (Context) CXXConstructExpr(Empty);
       break;
-      
+
     case EXPR_CXX_TEMPORARY_OBJECT:
       S = new (Context) CXXTemporaryObjectExpr(Empty);
       break;
@@ -2327,7 +2666,8 @@
       bool HasOtherExprStored = Record[ASTStmtReader::NumExprFields];
       if (HasOtherExprStored) {
         Expr *SubExpr = ReadSubExpr();
-        S = CXXDefaultArgExpr::Create(Context, SourceLocation(), 0, SubExpr);
+        S = CXXDefaultArgExpr::Create(Context, SourceLocation(), nullptr,
+                                      SubExpr);
       } else
         S = new (Context) CXXDefaultArgExpr(Empty);
       break;
@@ -2393,14 +2733,6 @@
                                    ? Record[ASTStmtReader::NumExprFields + 1] 
                                    : 0);
       break;
-      
-    case EXPR_CXX_UNARY_TYPE_TRAIT:
-      S = new (Context) UnaryTypeTraitExpr(Empty);
-      break;
-
-    case EXPR_BINARY_TYPE_TRAIT:
-      S = new (Context) BinaryTypeTraitExpr(Empty);
-      break;
 
     case EXPR_TYPE_TRAIT:
       S = TypeTraitExpr::CreateDeserialized(Context, 
@@ -2491,7 +2823,7 @@
     StmtStack.push_back(S);
   }
 Done:
-  assert(StmtStack.size() > PrevNumStmts && "Read too many sub stmts!");
+  assert(StmtStack.size() > PrevNumStmts && "Read too many sub-stmts!");
   assert(StmtStack.size() == PrevNumStmts + 1 && "Extra expressions on stack!");
   return StmtStack.pop_back_val();
 }
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index 405488c..0f52a9f 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -17,14 +17,15 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclContextInternals.h"
 #include "clang/AST/DeclFriend.h"
+#include "clang/AST/DeclLookups.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/Type.h"
 #include "clang/AST/TypeLocVisitor.h"
+#include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/FileSystemStatCache.h"
-#include "clang/Basic/OnDiskHashTable.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/SourceManagerInternals.h"
 #include "clang/Basic/TargetInfo.h"
@@ -45,8 +46,10 @@
 #include "llvm/ADT/Hashing.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Bitcode/BitstreamWriter.h"
+#include "llvm/Support/EndianStream.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/OnDiskHashTable.h"
 #include "llvm/Support/Path.h"
 #include <algorithm>
 #include <cstdio>
@@ -113,6 +116,12 @@
   Code = TYPE_DECAYED;
 }
 
+void ASTTypeWriter::VisitAdjustedType(const AdjustedType *T) {
+  Writer.AddTypeRef(T->getOriginalType(), Record);
+  Writer.AddTypeRef(T->getAdjustedType(), Record);
+  Code = TYPE_ADJUSTED;
+}
+
 void ASTTypeWriter::VisitBlockPointerType(const BlockPointerType *T) {
   Writer.AddTypeRef(T->getPointeeType(), Record);
   Code = TYPE_BLOCK_POINTER;
@@ -173,7 +182,7 @@
 }
 
 void ASTTypeWriter::VisitFunctionType(const FunctionType *T) {
-  Writer.AddTypeRef(T->getResultType(), Record);
+  Writer.AddTypeRef(T->getReturnType(), Record);
   FunctionType::ExtInfo C = T->getExtInfo();
   Record.push_back(C.getNoReturn());
   Record.push_back(C.getHasRegParm());
@@ -188,15 +197,8 @@
   Code = TYPE_FUNCTION_NO_PROTO;
 }
 
-void ASTTypeWriter::VisitFunctionProtoType(const FunctionProtoType *T) {
-  VisitFunctionType(T);
-  Record.push_back(T->getNumArgs());
-  for (unsigned I = 0, N = T->getNumArgs(); I != N; ++I)
-    Writer.AddTypeRef(T->getArgType(I), Record);
-  Record.push_back(T->isVariadic());
-  Record.push_back(T->hasTrailingReturn());
-  Record.push_back(T->getTypeQuals());
-  Record.push_back(static_cast<unsigned>(T->getRefQualifier()));
+static void addExceptionSpec(ASTWriter &Writer, const FunctionProtoType *T,
+                             ASTWriter::RecordDataImpl &Record) {
   Record.push_back(T->getExceptionSpecType());
   if (T->getExceptionSpecType() == EST_Dynamic) {
     Record.push_back(T->getNumExceptions());
@@ -210,6 +212,18 @@
   } else if (T->getExceptionSpecType() == EST_Unevaluated) {
     Writer.AddDeclRef(T->getExceptionSpecDecl(), Record);
   }
+}
+
+void ASTTypeWriter::VisitFunctionProtoType(const FunctionProtoType *T) {
+  VisitFunctionType(T);
+  Record.push_back(T->getNumParams());
+  for (unsigned I = 0, N = T->getNumParams(); I != N; ++I)
+    Writer.AddTypeRef(T->getParamType(I), Record);
+  Record.push_back(T->isVariadic());
+  Record.push_back(T->hasTrailingReturn());
+  Record.push_back(T->getTypeQuals());
+  Record.push_back(static_cast<unsigned>(T->getRefQualifier()));
+  addExceptionSpec(Writer, T, Record);
   Code = TYPE_FUNCTION_PROTO;
 }
 
@@ -395,9 +409,8 @@
 void ASTTypeWriter::VisitObjCObjectType(const ObjCObjectType *T) {
   Writer.AddTypeRef(T->getBaseType(), Record);
   Record.push_back(T->getNumProtocols());
-  for (ObjCObjectType::qual_iterator I = T->qual_begin(),
-       E = T->qual_end(); I != E; ++I)
-    Writer.AddDeclRef(*I, Record);
+  for (const auto *I : T->quals())
+    Writer.AddDeclRef(I, Record);
   Code = TYPE_OBJC_OBJECT;
 }
 
@@ -455,6 +468,9 @@
 void TypeLocWriter::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
   // nothing to do
 }
+void TypeLocWriter::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
+  // nothing to do
+}
 void TypeLocWriter::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
   Writer.AddSourceLocation(TL.getCaretLoc(), Record);
 }
@@ -503,8 +519,8 @@
   Writer.AddSourceLocation(TL.getLParenLoc(), Record);
   Writer.AddSourceLocation(TL.getRParenLoc(), Record);
   Writer.AddSourceLocation(TL.getLocalRangeEnd(), Record);
-  for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
-    Writer.AddDeclRef(TL.getArg(i), Record);
+  for (unsigned i = 0, e = TL.getNumParams(); i != e; ++i)
+    Writer.AddDeclRef(TL.getParam(i), Record);
 }
 void TypeLocWriter::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) {
   VisitFunctionTypeLoc(TL);
@@ -645,7 +661,8 @@
   Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETBID, Record);
 
   // Emit the block name if present.
-  if (Name == 0 || Name[0] == 0) return;
+  if (!Name || Name[0] == 0)
+    return;
   Record.clear();
   while (*Name)
     Record.push_back(*Name++);
@@ -764,10 +781,8 @@
   RECORD(EXPR_CXX_UNRESOLVED_CONSTRUCT);
   RECORD(EXPR_CXX_UNRESOLVED_MEMBER);
   RECORD(EXPR_CXX_UNRESOLVED_LOOKUP);
-  RECORD(EXPR_CXX_UNARY_TYPE_TRAIT);
   RECORD(EXPR_CXX_NOEXCEPT);
   RECORD(EXPR_OPAQUE_VALUE);
-  RECORD(EXPR_BINARY_TYPE_TRAIT);
   RECORD(EXPR_PACK_EXPANSION);
   RECORD(EXPR_SIZEOF_PACK);
   RECORD(EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK);
@@ -785,6 +800,8 @@
   // Control Block.
   BLOCK(CONTROL_BLOCK);
   RECORD(METADATA);
+  RECORD(MODULE_NAME);
+  RECORD(MODULE_MAP_FILE);
   RECORD(IMPORTS);
   RECORD(LANGUAGE_OPTIONS);
   RECORD(TARGET_OPTIONS);
@@ -806,7 +823,7 @@
   RECORD(DECL_OFFSET);
   RECORD(IDENTIFIER_OFFSET);
   RECORD(IDENTIFIER_TABLE);
-  RECORD(EXTERNAL_DEFINITIONS);
+  RECORD(EAGERLY_DESERIALIZED_DECLS);
   RECORD(SPECIAL_TYPES);
   RECORD(STATISTICS);
   RECORD(TENTATIVE_DEFINITIONS);
@@ -849,6 +866,7 @@
   RECORD(MACRO_OFFSET);
   RECORD(MACRO_TABLE);
   RECORD(LATE_PARSED_TEMPLATE);
+  RECORD(OPTIMIZE_PRAGMA_OPTIONS);
 
   // SourceManager Block.
   BLOCK(SOURCE_MANAGER_BLOCK);
@@ -1037,10 +1055,35 @@
   Stream.EmitRecordWithBlob(MetadataAbbrevCode, Record,
                             getClangFullRepositoryVersion());
 
+  // Module name
+  if (WritingModule) {
+    BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
+    Abbrev->Add(BitCodeAbbrevOp(MODULE_NAME));
+    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
+    unsigned AbbrevCode = Stream.EmitAbbrev(Abbrev);
+    RecordData Record;
+    Record.push_back(MODULE_NAME);
+    Stream.EmitRecordWithBlob(AbbrevCode, Record, WritingModule->Name);
+  }
+
+  // Module map file
+  if (WritingModule) {
+    BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
+    Abbrev->Add(BitCodeAbbrevOp(MODULE_MAP_FILE));
+    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Filename
+    unsigned AbbrevCode = Stream.EmitAbbrev(Abbrev);
+
+    assert(WritingModule->ModuleMap && "missing module map");
+    SmallString<128> ModuleMap(WritingModule->ModuleMap->getName());
+    llvm::sys::fs::make_absolute(ModuleMap);
+    RecordData Record;
+    Record.push_back(MODULE_MAP_FILE);
+    Stream.EmitRecordWithBlob(AbbrevCode, Record, ModuleMap.str());
+  }
+
   // Imports
   if (Chain) {
     serialization::ModuleManager &Mgr = Chain->getModuleManager();
-    SmallVector<char, 128> ModulePaths;
     Record.clear();
 
     for (ModuleManager::ModuleIterator M = Mgr.begin(), MEnd = Mgr.end();
@@ -1053,7 +1096,6 @@
       AddSourceLocation((*M)->ImportLoc, Record);
       Record.push_back((*M)->File->getSize());
       Record.push_back((*M)->File->getModificationTime());
-      // FIXME: This writes the absolute path for AST files we depend on.
       const std::string &FileName = (*M)->FileName;
       Record.push_back(FileName.size());
       Record.append(FileName.begin(), FileName.end());
@@ -1097,8 +1139,6 @@
   AddString(TargetOpts.Triple, Record);
   AddString(TargetOpts.CPU, Record);
   AddString(TargetOpts.ABI, Record);
-  AddString(TargetOpts.CXXABI, Record);
-  AddString(TargetOpts.LinkerVersion, Record);
   Record.push_back(TargetOpts.FeaturesAsWritten.size());
   for (unsigned I = 0, N = TargetOpts.FeaturesAsWritten.size(); I != N; ++I) {
     AddString(TargetOpts.FeaturesAsWritten[I], Record);
@@ -1120,6 +1160,9 @@
   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);
@@ -1156,6 +1199,7 @@
 
   AddString(HSOpts.ResourceDir, Record);
   AddString(HSOpts.ModuleCachePath, Record);
+  AddString(HSOpts.ModuleUserBuildPath, Record);
   Record.push_back(HSOpts.DisableModuleHash);
   Record.push_back(HSOpts.UseBuiltinIncludes);
   Record.push_back(HSOpts.UseStandardSystemIncludes);
@@ -1294,33 +1338,6 @@
       SortedFiles.push_front(Entry);
   }
 
-  // If we have an isysroot for a Darwin SDK, include its SDKSettings.plist in
-  // the set of (non-system) input files. This is simple heuristic for
-  // detecting whether the system headers may have changed, because it is too
-  // expensive to stat() all of the system headers.
-  FileManager &FileMgr = SourceMgr.getFileManager();
-  if (!HSOpts.Sysroot.empty() && !Chain) {
-    llvm::SmallString<128> SDKSettingsFileName(HSOpts.Sysroot);
-    llvm::sys::path::append(SDKSettingsFileName, "SDKSettings.plist");
-    if (const FileEntry *SDKSettingsFile = FileMgr.getFile(SDKSettingsFileName)) {
-      InputFileEntry Entry = { SDKSettingsFile, false, false };
-      SortedFiles.push_front(Entry);
-    }
-  }
-
-  // Add the compiler's own module.map in the set of (non-system) input files.
-  // This is a simple heuristic for detecting whether the compiler's headers
-  // have changed, because we don't want to stat() all of them.
-  if (Modules && !Chain) {
-    SmallString<128> P = StringRef(HSOpts.ResourceDir);
-    llvm::sys::path::append(P, "include");
-    llvm::sys::path::append(P, "module.map");
-    if (const FileEntry *ModuleMapFile = FileMgr.getFile(P)) {
-      InputFileEntry Entry = { ModuleMapFile, false, false };
-      SortedFiles.push_front(Entry);
-    }
-  }
-
   unsigned UserFilesNum = 0;
   // Write out all of the input files.
   std::vector<uint32_t> InputFileOffsets;
@@ -1357,7 +1374,7 @@
     
     // Ask the file manager to fixup the relative path for us. This will 
     // honor the working directory.
-    FileMgr.FixupRelativePath(FilePath);
+    SourceMgr.getFileManager().FixupRelativePath(FilePath);
     
     // FIXME: This call to make_absolute shouldn't be necessary, the
     // call to FixupRelativePath should always return an absolute path.
@@ -1470,8 +1487,10 @@
     
     typedef HeaderFileInfo data_type;
     typedef const data_type &data_type_ref;
+    typedef unsigned hash_value_type;
+    typedef unsigned offset_type;
     
-    static unsigned ComputeHash(key_type_ref key) {
+    static hash_value_type ComputeHash(key_type_ref key) {
       // The hash is based only on size/time of the file, so that the reader can
       // match even when symlinking or excess path elements ("foo/../", "../")
       // change the form of the name. However, complete path is still the key.
@@ -1481,26 +1500,31 @@
     
     std::pair<unsigned,unsigned>
     EmitKeyDataLength(raw_ostream& Out, key_type_ref key, data_type_ref Data) {
+      using namespace llvm::support;
+      endian::Writer<little> Writer(Out);
       unsigned KeyLen = strlen(key.Filename) + 1 + 8 + 8;
-      clang::io::Emit16(Out, KeyLen);
+      Writer.write<uint16_t>(KeyLen);
       unsigned DataLen = 1 + 2 + 4 + 4;
       if (Data.isModuleHeader)
         DataLen += 4;
-      clang::io::Emit8(Out, DataLen);
+      Writer.write<uint8_t>(DataLen);
       return std::make_pair(KeyLen, DataLen);
     }
     
     void EmitKey(raw_ostream& Out, key_type_ref key, unsigned KeyLen) {
-      clang::io::Emit64(Out, key.FE->getSize());
+      using namespace llvm::support;
+      endian::Writer<little> LE(Out);
+      LE.write<uint64_t>(key.FE->getSize());
       KeyLen -= 8;
-      clang::io::Emit64(Out, key.FE->getModificationTime());
+      LE.write<uint64_t>(key.FE->getModificationTime());
       KeyLen -= 8;
       Out.write(key.Filename, KeyLen);
     }
     
     void EmitData(raw_ostream &Out, key_type_ref key,
                   data_type_ref Data, unsigned DataLen) {
-      using namespace clang::io;
+      using namespace llvm::support;
+      endian::Writer<little> LE(Out);
       uint64_t Start = Out.tell(); (void)Start;
       
       unsigned char Flags = (Data.HeaderRole << 6)
@@ -1509,13 +1533,13 @@
                           | (Data.DirInfo << 2)
                           | (Data.Resolved << 1)
                           | Data.IndexHeaderMapHeader;
-      Emit8(Out, (uint8_t)Flags);
-      Emit16(Out, (uint16_t) Data.NumIncludes);
+      LE.write<uint8_t>(Flags);
+      LE.write<uint16_t>(Data.NumIncludes);
       
       if (!Data.ControllingMacro)
-        Emit32(Out, (uint32_t)Data.ControllingMacroID);
+        LE.write<uint32_t>(Data.ControllingMacroID);
       else
-        Emit32(Out, (uint32_t)Writer.getIdentifierRef(Data.ControllingMacro));
+        LE.write<uint32_t>(Writer.getIdentifierRef(Data.ControllingMacro));
       
       unsigned Offset = 0;
       if (!Data.Framework.empty()) {
@@ -1532,11 +1556,11 @@
         } else
           Offset = Pos->second;
       }
-      Emit32(Out, Offset);
+      LE.write<uint32_t>(Offset);
 
       if (Data.isModuleHeader) {
         Module *Mod = HS.findModuleForHeader(key.FE).getModule();
-        Emit32(Out, Writer.getExistingSubmoduleID(Mod));
+        LE.write<uint32_t>(Writer.getExistingSubmoduleID(Mod));
       }
 
       assert(Out.tell() - Start == DataLen && "Wrong data length");
@@ -1558,7 +1582,7 @@
     FilesByUID.resize(HS.header_file_size());
   
   HeaderFileInfoTrait GeneratorTrait(*this, HS);
-  OnDiskChainedHashTableGenerator<HeaderFileInfoTrait> Generator;  
+  llvm::OnDiskChainedHashTableGenerator<HeaderFileInfoTrait> Generator;
   SmallVector<const char *, 4> SavedStrings;
   unsigned NumHeaderSearchEntries = 0;
   for (unsigned UID = 0, LastUID = FilesByUID.size(); UID != LastUID; ++UID) {
@@ -1568,10 +1592,10 @@
 
     // Use HeaderSearch's getFileInfo to make sure we get the HeaderFileInfo
     // from the external source if it was not provided already.
-    const HeaderFileInfo &HFI = HS.getFileInfo(File);
-    if (HFI.External && Chain)
-      continue;
-    if (HFI.isModuleHeader && !HFI.isCompilingModuleHeader)
+    HeaderFileInfo HFI;
+    if (!HS.tryGetFileInfo(File, HFI) ||
+        (HFI.External && Chain) ||
+        (HFI.isModuleHeader && !HFI.isCompilingModuleHeader))
       continue;
 
     // Turn the file name into an absolute path, if it isn't already.
@@ -1594,9 +1618,10 @@
   SmallString<4096> TableData;
   uint32_t BucketOffset;
   {
+    using namespace llvm::support;
     llvm::raw_svector_ostream Out(TableData);
     // Make sure that no bucket is at offset 0
-    clang::io::Emit32(Out, 0);
+    endian::Writer<little>(Out).write<uint32_t>(0);
     BucketOffset = Generator.Emit(Out, GeneratorTrait);
   }
 
@@ -1837,8 +1862,10 @@
 
   typedef Data data_type;
   typedef const data_type &data_type_ref;
+  typedef unsigned hash_value_type;
+  typedef unsigned offset_type;
 
-  static unsigned ComputeHash(IdentID IdID) {
+  static hash_value_type ComputeHash(IdentID IdID) {
     return llvm::hash_value(IdID);
   }
 
@@ -1851,12 +1878,14 @@
   }
 
   static void EmitKey(raw_ostream& Out, key_type_ref Key, unsigned KeyLen) {
-    clang::io::Emit32(Out, Key);
+    using namespace llvm::support;
+    endian::Writer<little>(Out).write<uint32_t>(Key);
   }
 
   static void EmitData(raw_ostream& Out, key_type_ref Key, data_type_ref Data,
                        unsigned) {
-    clang::io::Emit32(Out, Data.MacroDirectivesOffset);
+    using namespace llvm::support;
+    endian::Writer<little>(Out).write<uint32_t>(Data.MacroDirectivesOffset);
   }
 };
 } // end anonymous namespace
@@ -1874,6 +1903,12 @@
       return true;
 
   if (IsModule) {
+    // Re-export any imported directives.
+    // FIXME: Also ensure we re-export imported #undef directives.
+    if (auto *DMD = dyn_cast<DefMacroDirective>(MD))
+      if (DMD->isImported())
+        return false;
+
     SourceLocation Loc = MD->getLocation();
     if (Loc.isInvalid())
       return true;
@@ -1928,7 +1963,7 @@
   llvm::array_pod_sort(MacroDirectives.begin(), MacroDirectives.end(),
                        &compareMacroDirectives);
 
-  OnDiskChainedHashTableGenerator<ASTMacroTableTrait> Generator;
+  llvm::OnDiskChainedHashTableGenerator<ASTMacroTableTrait> Generator;
 
   // Emit the macro directives as a list and associate the offset with the
   // identifier they belong to.
@@ -1946,8 +1981,6 @@
 
     // Emit the macro directives in reverse source order.
     for (; MD; MD = MD->getPrevious()) {
-      if (MD->isHidden())
-        continue;
       if (shouldIgnoreMacro(MD, IsModule, PP))
         continue;
 
@@ -2012,6 +2045,7 @@
     AddSourceLocation(MI->getDefinitionLoc(), Record);
     AddSourceLocation(MI->getDefinitionEndLoc(), Record);
     Record.push_back(MI->isUsed());
+    Record.push_back(MI->isUsedForHeaderGuard());
     unsigned Code;
     if (MI->isObjectLike()) {
       Code = PP_MACRO_OBJECT_LIKE;
@@ -2054,9 +2088,10 @@
   SmallString<4096> MacroTable;
   uint32_t BucketOffset;
   {
+    using namespace llvm::support;
     llvm::raw_svector_ostream Out(MacroTable);
     // Make sure that no bucket is at offset 0
-    clang::io::Emit32(Out, 0);
+    endian::Writer<little>(Out).write<uint32_t>(0);
     BucketOffset = Generator.Emit(Out);
   }
 
@@ -2227,9 +2262,7 @@
   // other consumers of this information.
   SourceManager &SrcMgr = PP->getSourceManager();
   ModuleMap &ModMap = PP->getHeaderSearchInfo().getModuleMap();
-  for (ASTContext::import_iterator I = Context->local_import_begin(),
-                                IEnd = Context->local_import_end();
-       I != IEnd; ++I) {
+  for (const auto *I : Context->local_imports()) {
     if (Module *ImportedFrom
           = ModMap.inferModuleFromLocation(FullSourceLoc(I->getLocation(), 
                                                          SrcMgr))) {
@@ -2248,7 +2281,8 @@
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Parent
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFramework
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsExplicit
-  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsSystem  
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsSystem
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsExternC
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InferSubmodules...
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InferExplicit...
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InferExportWild...
@@ -2336,6 +2370,7 @@
     Record.push_back(Mod->IsFramework);
     Record.push_back(Mod->IsExplicit);
     Record.push_back(Mod->IsSystem);
+    Record.push_back(Mod->IsExternC);
     Record.push_back(Mod->InferSubmodules);
     Record.push_back(Mod->InferExplicitSubmodules);
     Record.push_back(Mod->InferExportWildcard);
@@ -2516,7 +2551,7 @@
              I = point.State->begin(), E = point.State->end(); I != E; ++I) {
         if (I->second.isPragma()) {
           Record.push_back(I->first);
-          Record.push_back(I->second.getMapping());
+          Record.push_back((unsigned)I->second.getSeverity());
         }
       }
       Record.push_back(-1); // mark the end of the diag/map pairs for this
@@ -2618,9 +2653,8 @@
   RecordData Record;
   Record.push_back(DECL_CONTEXT_LEXICAL);
   SmallVector<KindDeclIDPair, 64> Decls;
-  for (DeclContext::decl_iterator D = DC->decls_begin(), DEnd = DC->decls_end();
-         D != DEnd; ++D)
-    Decls.push_back(std::make_pair((*D)->getKind(), GetDeclRef(*D)));
+  for (const auto *D : DC->decls())
+    Decls.push_back(std::make_pair(D->getKind(), GetDeclRef(D)));
 
   ++NumLexicalDeclContexts;
   Stream.EmitRecordWithBlob(DeclContextLexicalAbbrev, Record, data(Decls));
@@ -2719,17 +2753,22 @@
   };
   typedef const data_type& data_type_ref;
 
+  typedef unsigned hash_value_type;
+  typedef unsigned offset_type;
+
   explicit ASTMethodPoolTrait(ASTWriter &Writer) : Writer(Writer) { }
 
-  static unsigned ComputeHash(Selector Sel) {
+  static hash_value_type ComputeHash(Selector Sel) {
     return serialization::ComputeHash(Sel);
   }
 
   std::pair<unsigned,unsigned>
     EmitKeyDataLength(raw_ostream& Out, Selector Sel,
                       data_type_ref Methods) {
+    using namespace llvm::support;
+    endian::Writer<little> LE(Out);
     unsigned KeyLen = 2 + (Sel.getNumArgs()? Sel.getNumArgs() * 4 : 4);
-    clang::io::Emit16(Out, KeyLen);
+    LE.write<uint16_t>(KeyLen);
     unsigned DataLen = 4 + 2 + 2; // 2 bytes for each of the method counts
     for (const ObjCMethodList *Method = &Methods.Instance; Method;
          Method = Method->getNext())
@@ -2739,27 +2778,31 @@
          Method = Method->getNext())
       if (Method->Method)
         DataLen += 4;
-    clang::io::Emit16(Out, DataLen);
+    LE.write<uint16_t>(DataLen);
     return std::make_pair(KeyLen, DataLen);
   }
 
   void EmitKey(raw_ostream& Out, Selector Sel, unsigned) {
+    using namespace llvm::support;
+    endian::Writer<little> LE(Out);
     uint64_t Start = Out.tell();
     assert((Start >> 32) == 0 && "Selector key offset too large");
     Writer.SetSelectorOffset(Sel, Start);
     unsigned N = Sel.getNumArgs();
-    clang::io::Emit16(Out, N);
+    LE.write<uint16_t>(N);
     if (N == 0)
       N = 1;
     for (unsigned I = 0; I != N; ++I)
-      clang::io::Emit32(Out,
-                    Writer.getIdentifierRef(Sel.getIdentifierInfoForSlot(I)));
+      LE.write<uint32_t>(
+          Writer.getIdentifierRef(Sel.getIdentifierInfoForSlot(I)));
   }
 
   void EmitData(raw_ostream& Out, key_type_ref,
                 data_type_ref Methods, unsigned DataLen) {
+    using namespace llvm::support;
+    endian::Writer<little> LE(Out);
     uint64_t Start = Out.tell(); (void)Start;
-    clang::io::Emit32(Out, Methods.ID);
+    LE.write<uint32_t>(Methods.ID);
     unsigned NumInstanceMethods = 0;
     for (const ObjCMethodList *Method = &Methods.Instance; Method;
          Method = Method->getNext())
@@ -2779,16 +2822,16 @@
     unsigned FactoryBits = Methods.Factory.getBits();
     assert(FactoryBits < 4);
     unsigned NumFactoryMethodsAndBits = (NumFactoryMethods << 2) | FactoryBits;
-    clang::io::Emit16(Out, NumInstanceMethodsAndBits);
-    clang::io::Emit16(Out, NumFactoryMethodsAndBits);
+    LE.write<uint16_t>(NumInstanceMethodsAndBits);
+    LE.write<uint16_t>(NumFactoryMethodsAndBits);
     for (const ObjCMethodList *Method = &Methods.Instance; Method;
          Method = Method->getNext())
       if (Method->Method)
-        clang::io::Emit32(Out, Writer.getDeclID(Method->Method));
+        LE.write<uint32_t>(Writer.getDeclID(Method->Method));
     for (const ObjCMethodList *Method = &Methods.Factory; Method;
          Method = Method->getNext())
       if (Method->Method)
-        clang::io::Emit32(Out, Writer.getDeclID(Method->Method));
+        LE.write<uint32_t>(Writer.getDeclID(Method->Method));
 
     assert(Out.tell() - Start == DataLen && "Data length is wrong");
   }
@@ -2809,7 +2852,7 @@
   unsigned NumTableEntries = 0;
   // Create and write out the blob that contains selectors and the method pool.
   {
-    OnDiskChainedHashTableGenerator<ASTMethodPoolTrait> Generator;
+    llvm::OnDiskChainedHashTableGenerator<ASTMethodPoolTrait> Generator;
     ASTMethodPoolTrait Trait(*this);
 
     // Create the on-disk hash table representation. We walk through every
@@ -2857,10 +2900,11 @@
     SmallString<4096> MethodPool;
     uint32_t BucketOffset;
     {
+      using namespace llvm::support;
       ASTMethodPoolTrait Trait(*this);
       llvm::raw_svector_ostream Out(MethodPool);
       // Make sure that no bucket is at offset 0
-      clang::io::Emit32(Out, 0);
+      endian::Writer<little>(Out).write<uint32_t>(0);
       BucketOffset = Generator.Emit(Out, Trait);
     }
 
@@ -2959,83 +3003,110 @@
     return false;
   }
 
-  DefMacroDirective *getFirstPublicSubmoduleMacro(MacroDirective *MD,
-                                                  SubmoduleID &ModID) {
+  typedef llvm::SmallVectorImpl<SubmoduleID> OverriddenList;
+
+  MacroDirective *
+  getFirstPublicSubmoduleMacro(MacroDirective *MD, SubmoduleID &ModID) {
     ModID = 0;
-    if (DefMacroDirective *DefMD = getPublicSubmoduleMacro(MD, ModID))
-      if (!shouldIgnoreMacro(DefMD, IsModule, PP))
-        return DefMD;
-    return 0;
+    llvm::SmallVector<SubmoduleID, 1> Overridden;
+    if (MacroDirective *NextMD = getPublicSubmoduleMacro(MD, ModID, Overridden))
+      if (!shouldIgnoreMacro(NextMD, IsModule, PP))
+        return NextMD;
+    return nullptr;
   }
 
-  DefMacroDirective *getNextPublicSubmoduleMacro(DefMacroDirective *MD,
-                                                 SubmoduleID &ModID) {
-    if (DefMacroDirective *
-          DefMD = getPublicSubmoduleMacro(MD->getPrevious(), ModID))
-      if (!shouldIgnoreMacro(DefMD, IsModule, PP))
-        return DefMD;
-    return 0;
+  MacroDirective *
+  getNextPublicSubmoduleMacro(MacroDirective *MD, SubmoduleID &ModID,
+                              OverriddenList &Overridden) {
+    if (MacroDirective *NextMD =
+            getPublicSubmoduleMacro(MD->getPrevious(), ModID, Overridden))
+      if (!shouldIgnoreMacro(NextMD, IsModule, PP))
+        return NextMD;
+    return nullptr;
   }
 
   /// \brief Traverses the macro directives history and returns the latest
-  /// macro that is public and not undefined in the same submodule.
-  /// A macro that is defined in submodule A and undefined in submodule B,
+  /// public macro definition or undefinition that is not in ModID.
+  /// A macro that is defined in submodule A and undefined in submodule B
   /// will still be considered as defined/exported from submodule A.
-  DefMacroDirective *getPublicSubmoduleMacro(MacroDirective *MD,
-                                             SubmoduleID &ModID) {
+  /// ModID is updated to the module containing the returned directive.
+  ///
+  /// FIXME: This process breaks down if a module defines a macro, imports
+  ///        another submodule that changes the macro, then changes the
+  ///        macro again itself.
+  MacroDirective *getPublicSubmoduleMacro(MacroDirective *MD,
+                                          SubmoduleID &ModID,
+                                          OverriddenList &Overridden) {
+    Overridden.clear();
     if (!MD)
-      return 0;
+      return nullptr;
 
     SubmoduleID OrigModID = ModID;
-    bool isUndefined = false;
-    Optional<bool> isPublic;
+    Optional<bool> IsPublic;
     for (; MD; MD = MD->getPrevious()) {
-      if (MD->isHidden())
-        continue;
-
       SubmoduleID ThisModID = getSubmoduleID(MD);
       if (ThisModID == 0) {
-        isUndefined = false;
-        isPublic = Optional<bool>();
+        IsPublic = Optional<bool>();
+
+        // If we have no directive location, this macro was installed when
+        // finalizing the ASTReader.
+        if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(MD))
+          if (DefMD->getInfo()->getOwningModuleID())
+            return MD;
+        // Skip imports that only produce #undefs for now.
+        // FIXME: We should still re-export them!
+
         continue;
       }
-      if (ThisModID != ModID){
+      if (ThisModID != ModID) {
         ModID = ThisModID;
-        isUndefined = false;
-        isPublic = Optional<bool>();
+        IsPublic = Optional<bool>();
       }
+
+      // If this is a definition from a submodule import, that submodule's
+      // definition is overridden by the definition or undefinition that we
+      // started with.
+      // FIXME: This should only apply to macros defined in OrigModID.
+      // We can't do that currently, because a #include of a different submodule
+      // of the same module just leaks through macros instead of providing new
+      // DefMacroDirectives for them.
+      if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(MD)) {
+        // Figure out which submodule the macro was originally defined within.
+        SubmoduleID SourceID = DefMD->getInfo()->getOwningModuleID();
+        if (!SourceID) {
+          SourceLocation DefLoc = DefMD->getInfo()->getDefinitionLoc();
+          if (DefLoc == MD->getLocation())
+            SourceID = ThisModID;
+          else
+            SourceID = Writer.inferSubmoduleIDFromLocation(DefLoc);
+        }
+        if (OrigModID && SourceID != OrigModID)
+          Overridden.push_back(SourceID);
+      }
+
       // We are looking for a definition in a different submodule than the one
       // that we started with. If a submodule has re-definitions of the same
       // macro, only the last definition will be used as the "exported" one.
       if (ModID == OrigModID)
         continue;
 
-      if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(MD)) {
-        if (!isUndefined && (!isPublic.hasValue() || isPublic.getValue()))
-          return DefMD;
-        continue;
+      // The latest visibility directive for a name in a submodule affects all
+      // the directives that come before it.
+      if (VisibilityMacroDirective *VisMD =
+              dyn_cast<VisibilityMacroDirective>(MD)) {
+        if (!IsPublic.hasValue())
+          IsPublic = VisMD->isPublic();
+      } else if (!IsPublic.hasValue() || IsPublic.getValue()) {
+        // FIXME: If we find an imported macro, we should include its list of
+        // overrides in our export.
+        return MD;
       }
-
-      if (isa<UndefMacroDirective>(MD)) {
-        isUndefined = true;
-        continue;
-      }
-
-      VisibilityMacroDirective *VisMD = cast<VisibilityMacroDirective>(MD);
-      if (!isPublic.hasValue())
-        isPublic = VisMD->isPublic();
     }
 
-    return 0;
+    return nullptr;
   }
 
   SubmoduleID getSubmoduleID(MacroDirective *MD) {
-    if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(MD)) {
-      MacroInfo *MI = DefMD->getInfo();
-      if (unsigned ID = MI->getOwningModuleID())
-        return ID;
-      return Writer.inferSubmoduleIDFromLocation(MI->getDefinitionLoc());
-    }
     return Writer.inferSubmoduleIDFromLocation(MD->getLocation());
   }
 
@@ -3046,11 +3117,14 @@
   typedef IdentID data_type;
   typedef data_type data_type_ref;
 
+  typedef unsigned hash_value_type;
+  typedef unsigned offset_type;
+
   ASTIdentifierTableTrait(ASTWriter &Writer, Preprocessor &PP, 
                           IdentifierResolver &IdResolver, bool IsModule)
     : Writer(Writer), PP(PP), IdResolver(IdResolver), IsModule(IsModule) { }
 
-  static unsigned ComputeHash(const IdentifierInfo* II) {
+  static hash_value_type ComputeHash(const IdentifierInfo* II) {
     return llvm::HashString(II->getName());
   }
 
@@ -3058,7 +3132,7 @@
   EmitKeyDataLength(raw_ostream& Out, IdentifierInfo* II, IdentID ID) {
     unsigned KeyLen = II->getLength() + 1;
     unsigned DataLen = 4; // 4 bytes for the persistent ID << 1
-    MacroDirective *Macro = 0;
+    MacroDirective *Macro = nullptr;
     if (isInterestingIdentifier(II, Macro)) {
       DataLen += 2; // 2 bytes for builtin ID
       DataLen += 2; // 2 bytes for flags
@@ -3066,11 +3140,18 @@
         DataLen += 4; // MacroDirectives offset.
         if (IsModule) {
           SubmoduleID ModID;
-          for (DefMacroDirective *
-                 DefMD = getFirstPublicSubmoduleMacro(Macro, ModID);
-                 DefMD; DefMD = getNextPublicSubmoduleMacro(DefMD, ModID)) {
-            DataLen += 4; // MacroInfo ID.
+          llvm::SmallVector<SubmoduleID, 4> Overridden;
+          for (MacroDirective *
+                 MD = getFirstPublicSubmoduleMacro(Macro, ModID);
+                 MD; MD = getNextPublicSubmoduleMacro(MD, ModID, Overridden)) {
+            // Previous macro's overrides.
+            if (!Overridden.empty())
+              DataLen += 4 * (1 + Overridden.size());
+            DataLen += 4; // MacroInfo ID or ModuleID.
           }
+          // Previous macro's overrides.
+          if (!Overridden.empty())
+            DataLen += 4 * (1 + Overridden.size());
           DataLen += 4;
         }
       }
@@ -3080,11 +3161,14 @@
            D != DEnd; ++D)
         DataLen += sizeof(DeclID);
     }
-    clang::io::Emit16(Out, DataLen);
+    using namespace llvm::support;
+    endian::Writer<little> LE(Out);
+
+    LE.write<uint16_t>(DataLen);
     // We emit the key length after the data length so that every
     // string is preceded by a 16-bit length. This matches the PTH
     // format for storing identifiers.
-    clang::io::Emit16(Out, KeyLen);
+    LE.write<uint16_t>(KeyLen);
     return std::make_pair(KeyLen, DataLen);
   }
 
@@ -3096,18 +3180,31 @@
     Out.write(II->getNameStart(), KeyLen);
   }
 
+  static void emitMacroOverrides(raw_ostream &Out,
+                                 ArrayRef<SubmoduleID> Overridden) {
+    if (!Overridden.empty()) {
+      using namespace llvm::support;
+      endian::Writer<little> LE(Out);
+      LE.write<uint32_t>(Overridden.size() | 0x80000000U);
+      for (unsigned I = 0, N = Overridden.size(); I != N; ++I)
+        LE.write<uint32_t>(Overridden[I]);
+    }
+  }
+
   void EmitData(raw_ostream& Out, IdentifierInfo* II,
                 IdentID ID, unsigned) {
-    MacroDirective *Macro = 0;
+    using namespace llvm::support;
+    endian::Writer<little> LE(Out);
+    MacroDirective *Macro = nullptr;
     if (!isInterestingIdentifier(II, Macro)) {
-      clang::io::Emit32(Out, ID << 1);
+      LE.write<uint32_t>(ID << 1);
       return;
     }
 
-    clang::io::Emit32(Out, (ID << 1) | 0x01);
+    LE.write<uint32_t>((ID << 1) | 0x01);
     uint32_t Bits = (uint32_t)II->getObjCOrBuiltinID();
     assert((Bits & 0xffff) == Bits && "ObjCOrBuiltinID too big for ASTReader.");
-    clang::io::Emit16(Out, Bits);
+    LE.write<uint16_t>(Bits);
     Bits = 0;
     bool HadMacroDefinition = hadMacroDefinition(II, Macro);
     Bits = (Bits << 1) | unsigned(HadMacroDefinition);
@@ -3116,21 +3213,30 @@
     Bits = (Bits << 1) | unsigned(II->isPoisoned());
     Bits = (Bits << 1) | unsigned(II->hasRevertedTokenIDToIdentifier());
     Bits = (Bits << 1) | unsigned(II->isCPlusPlusOperatorKeyword());
-    clang::io::Emit16(Out, Bits);
+    LE.write<uint16_t>(Bits);
 
     if (HadMacroDefinition) {
-      clang::io::Emit32(Out, Writer.getMacroDirectivesOffset(II));
+      LE.write<uint32_t>(Writer.getMacroDirectivesOffset(II));
       if (IsModule) {
         // Write the IDs of macros coming from different submodules.
         SubmoduleID ModID;
-        for (DefMacroDirective *
-               DefMD = getFirstPublicSubmoduleMacro(Macro, ModID);
-               DefMD; DefMD = getNextPublicSubmoduleMacro(DefMD, ModID)) {
-          MacroID InfoID = Writer.getMacroID(DefMD->getInfo());
-          assert(InfoID);
-          clang::io::Emit32(Out, InfoID);
+        llvm::SmallVector<SubmoduleID, 4> Overridden;
+        for (MacroDirective *
+               MD = getFirstPublicSubmoduleMacro(Macro, ModID);
+               MD; MD = getNextPublicSubmoduleMacro(MD, ModID, Overridden)) {
+          MacroID InfoID = 0;
+          emitMacroOverrides(Out, Overridden);
+          if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(MD)) {
+            InfoID = Writer.getMacroID(DefMD->getInfo());
+            assert(InfoID);
+            LE.write<uint32_t>(InfoID << 1);
+          } else {
+            assert(isa<UndefMacroDirective>(MD));
+            LE.write<uint32_t>((ModID << 1) | 1);
+          }
         }
-        clang::io::Emit32(Out, 0);
+        emitMacroOverrides(Out, Overridden);
+        LE.write<uint32_t>(0);
       }
     }
 
@@ -3145,7 +3251,7 @@
     for (SmallVectorImpl<Decl *>::reverse_iterator D = Decls.rbegin(),
                                                 DEnd = Decls.rend();
          D != DEnd; ++D)
-      clang::io::Emit32(Out, Writer.getDeclID(getMostRecentLocalDecl(*D)));
+      LE.write<uint32_t>(Writer.getDeclID(getMostRecentLocalDecl(*D)));
   }
 
   /// \brief Returns the most recent local decl or the given decl if there are
@@ -3184,7 +3290,7 @@
   // Create and write out the blob that contains the identifier
   // strings.
   {
-    OnDiskChainedHashTableGenerator<ASTIdentifierTableTrait> Generator;
+    llvm::OnDiskChainedHashTableGenerator<ASTIdentifierTableTrait> Generator;
     ASTIdentifierTableTrait Trait(*this, PP, IdResolver, IsModule);
 
     // Look for any identifiers that were named while processing the
@@ -3214,10 +3320,11 @@
     SmallString<4096> IdentifierTable;
     uint32_t BucketOffset;
     {
+      using namespace llvm::support;
       ASTIdentifierTableTrait Trait(*this, PP, IdResolver, IsModule);
       llvm::raw_svector_ostream Out(IdentifierTable);
       // Make sure that no bucket is at offset 0
-      clang::io::Emit32(Out, 0);
+      endian::Writer<little>(Out).write<uint32_t>(0);
       BucketOffset = Generator.Emit(Out, Trait);
     }
 
@@ -3272,9 +3379,12 @@
   typedef DeclContext::lookup_result data_type;
   typedef const data_type& data_type_ref;
 
+  typedef unsigned hash_value_type;
+  typedef unsigned offset_type;
+
   explicit ASTDeclContextNameLookupTrait(ASTWriter &Writer) : Writer(Writer) { }
 
-  unsigned ComputeHash(DeclarationName Name) {
+  hash_value_type ComputeHash(DeclarationName Name) {
     llvm::FoldingSetNodeID ID;
     ID.AddInteger(Name.getNameKind());
 
@@ -3306,6 +3416,8 @@
   std::pair<unsigned,unsigned>
     EmitKeyDataLength(raw_ostream& Out, DeclarationName Name,
                       data_type_ref Lookup) {
+    using namespace llvm::support;
+    endian::Writer<little> LE(Out);
     unsigned KeyLen = 1;
     switch (Name.getNameKind()) {
     case DeclarationName::Identifier:
@@ -3324,35 +3436,35 @@
     case DeclarationName::CXXUsingDirective:
       break;
     }
-    clang::io::Emit16(Out, KeyLen);
+    LE.write<uint16_t>(KeyLen);
 
     // 2 bytes for num of decls and 4 for each DeclID.
     unsigned DataLen = 2 + 4 * Lookup.size();
-    clang::io::Emit16(Out, DataLen);
+    LE.write<uint16_t>(DataLen);
 
     return std::make_pair(KeyLen, DataLen);
   }
 
   void EmitKey(raw_ostream& Out, DeclarationName Name, unsigned) {
-    using namespace clang::io;
-
-    Emit8(Out, Name.getNameKind());
+    using namespace llvm::support;
+    endian::Writer<little> LE(Out);
+    LE.write<uint8_t>(Name.getNameKind());
     switch (Name.getNameKind()) {
     case DeclarationName::Identifier:
-      Emit32(Out, Writer.getIdentifierRef(Name.getAsIdentifierInfo()));
+      LE.write<uint32_t>(Writer.getIdentifierRef(Name.getAsIdentifierInfo()));
       return;
     case DeclarationName::ObjCZeroArgSelector:
     case DeclarationName::ObjCOneArgSelector:
     case DeclarationName::ObjCMultiArgSelector:
-      Emit32(Out, Writer.getSelectorRef(Name.getObjCSelector()));
+      LE.write<uint32_t>(Writer.getSelectorRef(Name.getObjCSelector()));
       return;
     case DeclarationName::CXXOperatorName:
       assert(Name.getCXXOverloadedOperator() < NUM_OVERLOADED_OPERATORS &&
              "Invalid operator?");
-      Emit8(Out, Name.getCXXOverloadedOperator());
+      LE.write<uint8_t>(Name.getCXXOverloadedOperator());
       return;
     case DeclarationName::CXXLiteralOperatorName:
-      Emit32(Out, Writer.getIdentifierRef(Name.getCXXLiteralIdentifier()));
+      LE.write<uint32_t>(Writer.getIdentifierRef(Name.getCXXLiteralIdentifier()));
       return;
     case DeclarationName::CXXConstructorName:
     case DeclarationName::CXXDestructorName:
@@ -3366,17 +3478,134 @@
 
   void EmitData(raw_ostream& Out, key_type_ref,
                 data_type Lookup, unsigned DataLen) {
+    using namespace llvm::support;
+    endian::Writer<little> LE(Out);
     uint64_t Start = Out.tell(); (void)Start;
-    clang::io::Emit16(Out, Lookup.size());
+    LE.write<uint16_t>(Lookup.size());
     for (DeclContext::lookup_iterator I = Lookup.begin(), E = Lookup.end();
          I != E; ++I)
-      clang::io::Emit32(Out, Writer.GetDeclRef(*I));
+      LE.write<uint32_t>(Writer.GetDeclRef(*I));
 
     assert(Out.tell() - Start == DataLen && "Data length is wrong");
   }
 };
 } // end anonymous namespace
 
+template<typename Visitor>
+static void visitLocalLookupResults(const DeclContext *ConstDC,
+                                    bool NeedToReconcileExternalVisibleStorage,
+                                    Visitor AddLookupResult) {
+  // FIXME: We need to build the lookups table, which is logically const.
+  DeclContext *DC = const_cast<DeclContext*>(ConstDC);
+  assert(DC == DC->getPrimaryContext() && "only primary DC has lookup table");
+
+  SmallVector<DeclarationName, 16> ExternalNames;
+  for (auto &Lookup : *DC->buildLookup()) {
+    if (Lookup.second.hasExternalDecls() ||
+        NeedToReconcileExternalVisibleStorage) {
+      // We don't know for sure what declarations are found by this name,
+      // because the external source might have a different set from the set
+      // that are in the lookup map, and we can't update it now without
+      // risking invalidating our lookup iterator. So add it to a queue to
+      // deal with later.
+      ExternalNames.push_back(Lookup.first);
+      continue;
+    }
+
+    AddLookupResult(Lookup.first, Lookup.second.getLookupResult());
+  }
+
+  // Add the names we needed to defer. Note, this shouldn't add any new decls
+  // to the list we need to serialize: any new declarations we find here should
+  // be imported from an external source.
+  // FIXME: What if the external source isn't an ASTReader?
+  for (const auto &Name : ExternalNames)
+    AddLookupResult(Name, DC->lookup(Name));
+}
+
+void ASTWriter::AddUpdatedDeclContext(const DeclContext *DC) {
+  if (UpdatedDeclContexts.insert(DC) && WritingAST) {
+    // Ensure we emit all the visible declarations.
+    visitLocalLookupResults(DC, DC->NeedToReconcileExternalVisibleStorage,
+                            [&](DeclarationName Name,
+                                DeclContext::lookup_const_result Result) {
+      for (auto *Decl : Result)
+        GetDeclRef(Decl);
+    });
+  }
+}
+
+uint32_t
+ASTWriter::GenerateNameLookupTable(const DeclContext *DC,
+                                   llvm::SmallVectorImpl<char> &LookupTable) {
+  assert(!DC->LookupPtr.getInt() && "must call buildLookups first");
+
+  llvm::OnDiskChainedHashTableGenerator<ASTDeclContextNameLookupTrait>
+      Generator;
+  ASTDeclContextNameLookupTrait Trait(*this);
+
+  // Create the on-disk hash table representation.
+  DeclarationName ConstructorName;
+  DeclarationName ConversionName;
+  SmallVector<NamedDecl *, 8> ConstructorDecls;
+  SmallVector<NamedDecl *, 4> ConversionDecls;
+
+  visitLocalLookupResults(DC, DC->NeedToReconcileExternalVisibleStorage,
+                          [&](DeclarationName Name,
+                              DeclContext::lookup_result Result) {
+    if (Result.empty())
+      return;
+
+    // Different DeclarationName values of certain kinds are mapped to
+    // identical serialized keys, because we don't want to use type
+    // identifiers in the keys (since type ids are local to the module).
+    switch (Name.getNameKind()) {
+    case DeclarationName::CXXConstructorName:
+      // There may be different CXXConstructorName DeclarationName values
+      // in a DeclContext because a UsingDecl that inherits constructors
+      // has the DeclarationName of the inherited constructors.
+      if (!ConstructorName)
+        ConstructorName = Name;
+      ConstructorDecls.append(Result.begin(), Result.end());
+      return;
+
+    case DeclarationName::CXXConversionFunctionName:
+      if (!ConversionName)
+        ConversionName = Name;
+      ConversionDecls.append(Result.begin(), Result.end());
+      return;
+
+    default:
+      break;
+    }
+
+    Generator.insert(Name, Result, Trait);
+  });
+
+  // Add the constructors.
+  if (!ConstructorDecls.empty()) {
+    Generator.insert(ConstructorName,
+                     DeclContext::lookup_result(ConstructorDecls.begin(),
+                                                ConstructorDecls.end()),
+                     Trait);
+  }
+
+  // Add the conversion functions.
+  if (!ConversionDecls.empty()) {
+    Generator.insert(ConversionName,
+                     DeclContext::lookup_result(ConversionDecls.begin(),
+                                                ConversionDecls.end()),
+                     Trait);
+  }
+
+  // Create the on-disk hash table in a buffer.
+  llvm::raw_svector_ostream Out(LookupTable);
+  // Make sure that no bucket is at offset 0
+  using namespace llvm::support;
+  endian::Writer<little>(Out).write<uint32_t>(0);
+  return Generator.Emit(Out, Trait);
+}
+
 /// \brief Write the block containing all of the declaration IDs
 /// visible from the given DeclContext.
 ///
@@ -3407,50 +3636,9 @@
   if (!Map || Map->empty())
     return 0;
 
-  OnDiskChainedHashTableGenerator<ASTDeclContextNameLookupTrait> Generator;
-  ASTDeclContextNameLookupTrait Trait(*this);
-
-  // Create the on-disk hash table representation.
-  DeclarationName ConversionName;
-  SmallVector<NamedDecl *, 4> ConversionDecls;
-  for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end();
-       D != DEnd; ++D) {
-    DeclarationName Name = D->first;
-    DeclContext::lookup_result Result = D->second.getLookupResult();
-    if (!Result.empty()) {
-      if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName) {
-        // Hash all conversion function names to the same name. The actual
-        // type information in conversion function name is not used in the
-        // key (since such type information is not stable across different
-        // modules), so the intended effect is to coalesce all of the conversion
-        // functions under a single key.
-        if (!ConversionName)
-          ConversionName = Name;
-        ConversionDecls.append(Result.begin(), Result.end());
-        continue;
-      }
-      
-      Generator.insert(Name, Result, Trait);
-    }
-  }
-
-  // Add the conversion functions
-  if (!ConversionDecls.empty()) {
-    Generator.insert(ConversionName, 
-                     DeclContext::lookup_result(ConversionDecls.begin(),
-                                                ConversionDecls.end()),
-                     Trait);
-  }
-  
   // Create the on-disk hash table in a buffer.
   SmallString<4096> LookupTable;
-  uint32_t BucketOffset;
-  {
-    llvm::raw_svector_ostream Out(LookupTable);
-    // Make sure that no bucket is at offset 0
-    clang::io::Emit32(Out, 0);
-    BucketOffset = Generator.Emit(Out, Trait);
-  }
+  uint32_t BucketOffset = GenerateNameLookupTable(DC, LookupTable);
 
   // Write the lookup table
   RecordData Record;
@@ -3471,33 +3659,13 @@
 /// (in C++), for namespaces, and for classes with forward-declared unscoped
 /// enumeration members (in C++11).
 void ASTWriter::WriteDeclContextVisibleUpdate(const DeclContext *DC) {
-  StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(DC->getLookupPtr());
+  StoredDeclsMap *Map = DC->getLookupPtr();
   if (!Map || Map->empty())
     return;
 
-  OnDiskChainedHashTableGenerator<ASTDeclContextNameLookupTrait> Generator;
-  ASTDeclContextNameLookupTrait Trait(*this);
-
-  // Create the hash table.
-  for (StoredDeclsMap::iterator D = Map->begin(), DEnd = Map->end();
-       D != DEnd; ++D) {
-    DeclarationName Name = D->first;
-    DeclContext::lookup_result Result = D->second.getLookupResult();
-    // For any name that appears in this table, the results are complete, i.e.
-    // they overwrite results from previous PCHs. Merging is always a mess.
-    if (!Result.empty())
-      Generator.insert(Name, Result, Trait);
-  }
-
   // Create the on-disk hash table in a buffer.
   SmallString<4096> LookupTable;
-  uint32_t BucketOffset;
-  {
-    llvm::raw_svector_ostream Out(LookupTable);
-    // Make sure that no bucket is at offset 0
-    clang::io::Emit32(Out, 0);
-    BucketOffset = Generator.Emit(Out, Trait);
-  }
+  uint32_t BucketOffset = GenerateNameLookupTable(DC, LookupTable);
 
   // Write the lookup table
   RecordData Record;
@@ -3667,7 +3835,7 @@
                                         IEnd = Chain->MergedDecls.end();
        I != IEnd; ++I) {
     DeclID CanonID = I->first->isFromASTFile()? I->first->getGlobalID()
-                                              : getDeclID(I->first);
+                                              : GetDeclRef(I->first);
     assert(CanonID && "Merged declaration not known?");
     
     Record.push_back(CanonID);
@@ -3701,6 +3869,14 @@
   Stream.EmitRecord(LATE_PARSED_TEMPLATE, Record);
 }
 
+/// \brief Write the state of 'pragma clang optimize' at the end of the module.
+void ASTWriter::WriteOptimizePragmaOptions(Sema &SemaRef) {
+  RecordData Record;
+  SourceLocation PragmaLoc = SemaRef.getOptimizeOffPragmaLocation();
+  AddSourceLocation(PragmaLoc, Record);
+  Stream.EmitRecord(OPTIMIZE_PRAGMA_OPTIONS, Record);
+}
+
 //===----------------------------------------------------------------------===//
 // General Serialization Routines
 //===----------------------------------------------------------------------===//
@@ -3774,8 +3950,8 @@
 }
 
 ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream)
-  : Stream(Stream), Context(0), PP(0), Chain(0), WritingModule(0),
-    WritingAST(false), DoneWritingDeclsAndTypes(false),
+  : Stream(Stream), Context(nullptr), PP(nullptr), Chain(nullptr),
+    WritingModule(nullptr), WritingAST(false), DoneWritingDeclsAndTypes(false),
     ASTHasCompilerErrors(false),
     FirstDeclID(NUM_PREDEF_DECL_IDS), NextDeclID(FirstDeclID),
     FirstTypeID(NUM_PREDEF_TYPE_IDS), NextTypeID(FirstTypeID),
@@ -3799,9 +3975,7 @@
 }
 
 ASTWriter::~ASTWriter() {
-  for (FileDeclIDsTy::iterator
-         I = FileDeclIDs.begin(), E = FileDeclIDs.end(); I != E; ++I)
-    delete I->second;
+  llvm::DeleteContainerSeconds(FileDeclIDs);
 }
 
 void ASTWriter::WriteAST(Sema &SemaRef,
@@ -3824,18 +3998,18 @@
   PP = &SemaRef.PP;
   this->WritingModule = WritingModule;
   WriteASTCore(SemaRef, isysroot, OutputFile, WritingModule);
-  Context = 0;
-  PP = 0;
-  this->WritingModule = 0;
-  
+  Context = nullptr;
+  PP = nullptr;
+  this->WritingModule = nullptr;
+
   WritingAST = false;
 }
 
 template<typename Vector>
 static void AddLazyVectorDecls(ASTWriter &Writer, Vector &Vec,
                                ASTWriter::RecordData &Record) {
-  for (typename Vector::iterator I = Vec.begin(0, true), E = Vec.end();
-       I != E; ++I)  {
+  for (typename Vector::iterator I = Vec.begin(nullptr, true), E = Vec.end();
+       I != E; ++I) {
     Writer.AddDeclRef(*I, Record);
   }
 }
@@ -3846,7 +4020,7 @@
                              Module *WritingModule) {
   using namespace llvm;
 
-  bool isModule = WritingModule != 0;
+  bool isModule = WritingModule != nullptr;
 
   // Make sure that the AST reader knows to finalize itself.
   if (Chain)
@@ -3906,6 +4080,15 @@
     }
   }
 
+  // If we saw any DeclContext updates before we started writing the AST file,
+  // make sure all visible decls in those DeclContexts are written out.
+  if (!UpdatedDeclContexts.empty()) {
+    auto OldUpdatedDeclContexts = std::move(UpdatedDeclContexts);
+    UpdatedDeclContexts.clear();
+    for (auto *DC : OldUpdatedDeclContexts)
+      AddUpdatedDeclContext(DC);
+  }
+
   // Build a record containing all of the tentative definitions in this file, in
   // TentativeDefinitions order.  Generally, this record will be empty for
   // headers.
@@ -4032,11 +4215,9 @@
   // translation unit that do not come from other AST files.
   const TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
   SmallVector<KindDeclIDPair, 64> NewGlobalDecls;
-  for (DeclContext::decl_iterator I = TU->noload_decls_begin(),
-                                  E = TU->noload_decls_end();
-       I != E; ++I) {
-    if (!(*I)->isFromASTFile())
-      NewGlobalDecls.push_back(std::make_pair((*I)->getKind(), GetDeclRef(*I)));
+  for (const auto *I : TU->noload_decls()) {
+    if (!I->isFromASTFile())
+      NewGlobalDecls.push_back(std::make_pair(I->getKind(), GetDeclRef(I)));
   }
   
   llvm::BitCodeAbbrev *Abv = new llvm::BitCodeAbbrev();
@@ -4059,14 +4240,25 @@
   
   // If the translation unit has an anonymous namespace, and we don't already
   // have an update block for it, write it as an update block.
+  // FIXME: Why do we not do this if there's already an update block?
   if (NamespaceDecl *NS = TU->getAnonymousNamespace()) {
     ASTWriter::UpdateRecord &Record = DeclUpdates[TU];
-    if (Record.empty()) {
-      Record.push_back(UPD_CXX_ADDED_ANONYMOUS_NAMESPACE);
-      Record.push_back(reinterpret_cast<uint64_t>(NS));
-    }
+    if (Record.empty())
+      Record.push_back(DeclUpdate(UPD_CXX_ADDED_ANONYMOUS_NAMESPACE, NS));
   }
 
+  // Add update records for all mangling numbers and static local numbers.
+  // These aren't really update records, but this is a convenient way of
+  // tagging this rare extra data onto the declarations.
+  for (const auto &Number : Context.MangleNumbers)
+    if (!Number.first->isFromASTFile())
+      DeclUpdates[Number.first].push_back(DeclUpdate(UPD_MANGLING_NUMBER,
+                                                     Number.second));
+  for (const auto &Number : Context.StaticLocalNumbers)
+    if (!Number.first->isFromASTFile())
+      DeclUpdates[Number.first].push_back(DeclUpdate(UPD_STATIC_LOCAL_NUMBER,
+                                                     Number.second));
+
   // Make sure visible decls, added to DeclContexts previously loaded from
   // an AST file, are registered for serialization.
   for (SmallVectorImpl<const Decl *>::iterator
@@ -4090,9 +4282,6 @@
     }
   }
 
-  // Resolve any declaration pointers within the declaration updates block.
-  ResolveDeclUpdatesBlocks();
-  
   // Form the record of special types.
   RecordData SpecialTypes;
   AddTypeRef(Context.getRawCFConstantStringType(), SpecialTypes);
@@ -4104,30 +4293,6 @@
   AddTypeRef(Context.ObjCSelRedefinitionType, SpecialTypes);
   AddTypeRef(Context.getucontext_tType(), SpecialTypes);
 
-  // Keep writing types and declarations until all types and
-  // declarations have been written.
-  Stream.EnterSubblock(DECLTYPES_BLOCK_ID, NUM_ALLOWED_ABBREVS_SIZE);
-  WriteDeclsBlockAbbrevs();
-  for (DeclsToRewriteTy::iterator I = DeclsToRewrite.begin(), 
-                                  E = DeclsToRewrite.end(); 
-       I != E; ++I)
-    DeclTypesToEmit.push(const_cast<Decl*>(*I));
-  while (!DeclTypesToEmit.empty()) {
-    DeclOrType DOT = DeclTypesToEmit.front();
-    DeclTypesToEmit.pop();
-    if (DOT.isType())
-      WriteType(DOT.getType());
-    else
-      WriteDecl(Context, DOT.getDecl());
-  }
-  Stream.ExitBlock();
-
-  DoneWritingDeclsAndTypes = true;
-
-  WriteFileDeclIDsMap();
-  WriteSourceManagerBlock(Context.getSourceManager(), PP, isysroot);
-  WriteComments();
-  
   if (Chain) {
     // Write the mapping information describing our module dependencies and how
     // each of those modules were mapped into our own offset/ID space, so that
@@ -4154,17 +4319,19 @@
       for (ModuleManager::ModuleConstIterator M = Chain->ModuleMgr.begin(),
                                            MEnd = Chain->ModuleMgr.end();
            M != MEnd; ++M) {
+        using namespace llvm::support;
+        endian::Writer<little> LE(Out);
         StringRef FileName = (*M)->FileName;
-        io::Emit16(Out, FileName.size());
+        LE.write<uint16_t>(FileName.size());
         Out.write(FileName.data(), FileName.size());
-        io::Emit32(Out, (*M)->SLocEntryBaseOffset);
-        io::Emit32(Out, (*M)->BaseIdentifierID);
-        io::Emit32(Out, (*M)->BaseMacroID);
-        io::Emit32(Out, (*M)->BasePreprocessedEntityID);
-        io::Emit32(Out, (*M)->BaseSubmoduleID);
-        io::Emit32(Out, (*M)->BaseSelectorID);
-        io::Emit32(Out, (*M)->BaseDeclID);
-        io::Emit32(Out, (*M)->BaseTypeIndex);
+        LE.write<uint32_t>((*M)->SLocEntryBaseOffset);
+        LE.write<uint32_t>((*M)->BaseIdentifierID);
+        LE.write<uint32_t>((*M)->BaseMacroID);
+        LE.write<uint32_t>((*M)->BasePreprocessedEntityID);
+        LE.write<uint32_t>((*M)->BaseSubmoduleID);
+        LE.write<uint32_t>((*M)->BaseSelectorID);
+        LE.write<uint32_t>((*M)->BaseDeclID);
+        LE.write<uint32_t>((*M)->BaseTypeIndex);
       }
     }
     Record.clear();
@@ -4172,6 +4339,41 @@
     Stream.EmitRecordWithBlob(ModuleOffsetMapAbbrev, Record,
                               Buffer.data(), Buffer.size());
   }
+
+  RecordData DeclUpdatesOffsetsRecord;
+
+  // Keep writing types, declarations, and declaration update records
+  // until we've emitted all of them.
+  Stream.EnterSubblock(DECLTYPES_BLOCK_ID, NUM_ALLOWED_ABBREVS_SIZE);
+  WriteDeclsBlockAbbrevs();
+  for (DeclsToRewriteTy::iterator I = DeclsToRewrite.begin(),
+                                  E = DeclsToRewrite.end();
+       I != E; ++I)
+    DeclTypesToEmit.push(const_cast<Decl*>(*I));
+  do {
+    WriteDeclUpdatesBlocks(DeclUpdatesOffsetsRecord);
+    while (!DeclTypesToEmit.empty()) {
+      DeclOrType DOT = DeclTypesToEmit.front();
+      DeclTypesToEmit.pop();
+      if (DOT.isType())
+        WriteType(DOT.getType());
+      else
+        WriteDecl(Context, DOT.getDecl());
+    }
+  } while (!DeclUpdates.empty());
+  Stream.ExitBlock();
+
+  DoneWritingDeclsAndTypes = true;
+
+  // These things can only be done once we've written out decls and types.
+  WriteTypeDeclOffsets();
+  if (!DeclUpdatesOffsetsRecord.empty())
+    Stream.EmitRecord(DECL_UPDATE_OFFSETS, DeclUpdatesOffsetsRecord);
+  WriteCXXBaseSpecifiersOffsets();
+  WriteFileDeclIDsMap();
+  WriteSourceManagerBlock(Context.getSourceManager(), PP, isysroot);
+
+  WriteComments();
   WritePreprocessor(PP, isModule);
   WriteHeaderSearch(PP.getHeaderSearchInfo(), isysroot);
   WriteSelectors(SemaRef);
@@ -4179,12 +4381,8 @@
   WriteIdentifierTable(PP, SemaRef.IdResolver, isModule);
   WriteFPPragmaOptions(SemaRef.getFPOptions());
   WriteOpenCLExtensions(SemaRef);
-
-  WriteTypeDeclOffsets();
   WritePragmaDiagnosticMappings(Context.getDiagnostics(), isModule);
 
-  WriteCXXBaseSpecifiersOffsets();
-  
   // If we're emitting a module, write out the submodule information.  
   if (WritingModule)
     WriteSubmodules(WritingModule);
@@ -4192,8 +4390,8 @@
   Stream.EmitRecord(SPECIAL_TYPES, SpecialTypes);
 
   // Write the record containing external, unnamed definitions.
-  if (!ExternalDefinitions.empty())
-    Stream.EmitRecord(EXTERNAL_DEFINITIONS, ExternalDefinitions);
+  if (!EagerlyDeserializedDecls.empty())
+    Stream.EmitRecord(EAGERLY_DESERIALIZED_DECLS, EagerlyDeserializedDecls);
 
   // Write the record containing tentative definitions.
   if (!TentativeDefinitions.empty())
@@ -4250,40 +4448,53 @@
     Stream.EmitRecord(UNDEFINED_BUT_USED, UndefinedButUsed);
   
   // Write the visible updates to DeclContexts.
-  for (llvm::SmallPtrSet<const DeclContext *, 16>::iterator
-       I = UpdatedDeclContexts.begin(),
-       E = UpdatedDeclContexts.end();
-       I != E; ++I)
-    WriteDeclContextVisibleUpdate(*I);
+  for (auto *DC : UpdatedDeclContexts)
+    WriteDeclContextVisibleUpdate(DC);
 
   if (!WritingModule) {
     // Write the submodules that were imported, if any.
-    RecordData ImportedModules;
-    for (ASTContext::import_iterator I = Context.local_import_begin(),
-                                  IEnd = Context.local_import_end();
-         I != IEnd; ++I) {
+    struct ModuleInfo {
+      uint64_t ID;
+      Module *M;
+      ModuleInfo(uint64_t ID, Module *M) : ID(ID), M(M) {}
+    };
+    llvm::SmallVector<ModuleInfo, 64> Imports;
+    for (const auto *I : Context.local_imports()) {
       assert(SubmoduleIDs.find(I->getImportedModule()) != SubmoduleIDs.end());
-      ImportedModules.push_back(SubmoduleIDs[I->getImportedModule()]);
+      Imports.push_back(ModuleInfo(SubmoduleIDs[I->getImportedModule()],
+                         I->getImportedModule()));
     }
-    if (!ImportedModules.empty()) {
-      // Sort module IDs.
-      llvm::array_pod_sort(ImportedModules.begin(), ImportedModules.end());
-      
-      // Unique module IDs.
-      ImportedModules.erase(std::unique(ImportedModules.begin(), 
-                                        ImportedModules.end()),
-                            ImportedModules.end());
-      
+
+    if (!Imports.empty()) {
+      auto Cmp = [](const ModuleInfo &A, const ModuleInfo &B) {
+        return A.ID < B.ID;
+      };
+
+      // Sort and deduplicate module IDs.
+      std::sort(Imports.begin(), Imports.end(), Cmp);
+      Imports.erase(std::unique(Imports.begin(), Imports.end(), Cmp),
+                    Imports.end());
+
+      RecordData ImportedModules;
+      for (const auto &Import : Imports) {
+        ImportedModules.push_back(Import.ID);
+        // FIXME: If the module has macros imported then later has declarations
+        // imported, this location won't be the right one as a location for the
+        // declaration imports.
+        AddSourceLocation(Import.M->MacroVisibilityLoc, ImportedModules);
+      }
+
       Stream.EmitRecord(IMPORTED_MODULES, ImportedModules);
     }
   }
 
-  WriteDeclUpdatesBlocks();
   WriteDeclReplacementsBlock();
   WriteRedeclarations();
   WriteMergedDecls();
   WriteObjCCategories();
   WriteLateParsedTemplates(SemaRef);
+  if(!WritingModule)
+    WriteOptimizePragmaOptions(SemaRef);
 
   // Some simple statistics
   Record.clear();
@@ -4295,64 +4506,129 @@
   Stream.ExitBlock();
 }
 
-/// \brief Go through the declaration update blocks and resolve declaration
-/// pointers into declaration IDs.
-void ASTWriter::ResolveDeclUpdatesBlocks() {
-  for (DeclUpdateMap::iterator
-       I = DeclUpdates.begin(), E = DeclUpdates.end(); I != E; ++I) {
-    const Decl *D = I->first;
-    UpdateRecord &URec = I->second;
-    
-    if (isRewritten(D))
-      continue; // The decl will be written completely
-
-    unsigned Idx = 0, N = URec.size();
-    while (Idx < N) {
-      switch ((DeclUpdateKind)URec[Idx++]) {
-      case UPD_CXX_ADDED_IMPLICIT_MEMBER:
-      case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION:
-      case UPD_CXX_ADDED_ANONYMOUS_NAMESPACE:
-        URec[Idx] = GetDeclRef(reinterpret_cast<Decl *>(URec[Idx]));
-        ++Idx;
-        break;
-
-      case UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER:
-      case UPD_DECL_MARKED_USED:
-        ++Idx;
-        break;
-
-      case UPD_CXX_DEDUCED_RETURN_TYPE:
-        URec[Idx] = GetOrCreateTypeID(
-            QualType::getFromOpaquePtr(reinterpret_cast<void *>(URec[Idx])));
-        ++Idx;
-        break;
-      }
-    }
-  }
-}
-
-void ASTWriter::WriteDeclUpdatesBlocks() {
+void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) {
   if (DeclUpdates.empty())
     return;
 
-  RecordData OffsetsRecord;
-  Stream.EnterSubblock(DECL_UPDATES_BLOCK_ID, NUM_ALLOWED_ABBREVS_SIZE);
-  for (DeclUpdateMap::iterator
-         I = DeclUpdates.begin(), E = DeclUpdates.end(); I != E; ++I) {
-    const Decl *D = I->first;
-    UpdateRecord &URec = I->second;
+  DeclUpdateMap LocalUpdates;
+  LocalUpdates.swap(DeclUpdates);
 
+  for (auto &DeclUpdate : LocalUpdates) {
+    const Decl *D = DeclUpdate.first;
     if (isRewritten(D))
       continue; // The decl will be written completely,no need to store updates.
 
-    uint64_t Offset = Stream.GetCurrentBitNo();
-    Stream.EmitRecord(DECL_UPDATES, URec);
+    bool HasUpdatedBody = false;
+    RecordData Record;
+    for (auto &Update : DeclUpdate.second) {
+      DeclUpdateKind Kind = (DeclUpdateKind)Update.getKind();
+
+      Record.push_back(Kind);
+      switch (Kind) {
+      case UPD_CXX_ADDED_IMPLICIT_MEMBER:
+      case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION:
+      case UPD_CXX_ADDED_ANONYMOUS_NAMESPACE:
+        assert(Update.getDecl() && "no decl to add?");
+        Record.push_back(GetDeclRef(Update.getDecl()));
+        break;
+
+      case UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER:
+        AddSourceLocation(Update.getLoc(), Record);
+        break;
+
+      case UPD_CXX_INSTANTIATED_FUNCTION_DEFINITION:
+        // An updated body is emitted last, so that the reader doesn't need
+        // to skip over the lazy body to reach statements for other records.
+        Record.pop_back();
+        HasUpdatedBody = true;
+        break;
+
+      case UPD_CXX_INSTANTIATED_CLASS_DEFINITION: {
+        auto *RD = cast<CXXRecordDecl>(D);
+        AddUpdatedDeclContext(RD->getPrimaryContext());
+        AddCXXDefinitionData(RD, Record);
+        Record.push_back(WriteDeclContextLexicalBlock(
+            *Context, const_cast<CXXRecordDecl *>(RD)));
+
+        // This state is sometimes updated by template instantiation, when we
+        // switch from the specialization referring to the template declaration
+        // to it referring to the template definition.
+        if (auto *MSInfo = RD->getMemberSpecializationInfo()) {
+          Record.push_back(MSInfo->getTemplateSpecializationKind());
+          AddSourceLocation(MSInfo->getPointOfInstantiation(), Record);
+        } else {
+          auto *Spec = cast<ClassTemplateSpecializationDecl>(RD);
+          Record.push_back(Spec->getTemplateSpecializationKind());
+          AddSourceLocation(Spec->getPointOfInstantiation(), Record);
+
+          // The instantiation might have been resolved to a partial
+          // specialization. If so, record which one.
+          auto From = Spec->getInstantiatedFrom();
+          if (auto PartialSpec =
+                From.dyn_cast<ClassTemplatePartialSpecializationDecl*>()) {
+            Record.push_back(true);
+            AddDeclRef(PartialSpec, Record);
+            AddTemplateArgumentList(&Spec->getTemplateInstantiationArgs(),
+                                    Record);
+          } else {
+            Record.push_back(false);
+          }
+        }
+        Record.push_back(RD->getTagKind());
+        AddSourceLocation(RD->getLocation(), Record);
+        AddSourceLocation(RD->getLocStart(), Record);
+        AddSourceLocation(RD->getRBraceLoc(), Record);
+
+        // Instantiation may change attributes; write them all out afresh.
+        Record.push_back(D->hasAttrs());
+        if (Record.back())
+          WriteAttributes(ArrayRef<const Attr*>(D->getAttrs().begin(),
+                                                D->getAttrs().size()), Record);
+
+        // FIXME: Ensure we don't get here for explicit instantiations.
+        break;
+      }
+
+      case UPD_CXX_RESOLVED_EXCEPTION_SPEC:
+        addExceptionSpec(
+            *this,
+            cast<FunctionDecl>(D)->getType()->castAs<FunctionProtoType>(),
+            Record);
+        break;
+
+      case UPD_CXX_DEDUCED_RETURN_TYPE:
+        Record.push_back(GetOrCreateTypeID(Update.getType()));
+        break;
+
+      case UPD_DECL_MARKED_USED:
+        break;
+
+      case UPD_MANGLING_NUMBER:
+      case UPD_STATIC_LOCAL_NUMBER:
+        Record.push_back(Update.getNumber());
+        break;
+      }
+    }
+
+    if (HasUpdatedBody) {
+      const FunctionDecl *Def = cast<FunctionDecl>(D);
+      Record.push_back(UPD_CXX_INSTANTIATED_FUNCTION_DEFINITION);
+      Record.push_back(Def->isInlined());
+      AddSourceLocation(Def->getInnerLocStart(), Record);
+      AddFunctionDefinition(Def, Record);
+    }
 
     OffsetsRecord.push_back(GetDeclRef(D));
-    OffsetsRecord.push_back(Offset);
+    OffsetsRecord.push_back(Stream.GetCurrentBitNo());
+
+    Stream.EmitRecord(DECL_UPDATES, Record);
+
+    // Flush any statements that were written as part of this update record.
+    FlushStmts();
+
+    // Flush C++ base specifiers, if there are any.
+    FlushCXXBaseSpecifiers();
   }
-  Stream.ExitBlock();
-  Stream.EmitRecord(DECL_UPDATE_OFFSETS, OffsetsRecord);
 }
 
 void ASTWriter::WriteDeclReplacementsBlock() {
@@ -4398,7 +4674,7 @@
 }
 
 IdentID ASTWriter::getIdentifierRef(const IdentifierInfo *II) {
-  if (II == 0)
+  if (!II)
     return 0;
 
   IdentID &ID = IdentifierIDs[II];
@@ -4411,7 +4687,7 @@
   // Don't emit builtin macros like __LINE__ to the AST file unless they
   // have been redefined by the header (in which case they are not
   // isBuiltinMacro).
-  if (MI == 0 || MI->isBuiltinMacro())
+  if (!MI || MI->isBuiltinMacro())
     return 0;
 
   MacroID &ID = MacroIDs[MI];
@@ -4424,7 +4700,7 @@
 }
 
 MacroID ASTWriter::getMacroID(MacroInfo *MI) {
-  if (MI == 0 || MI->isBuiltinMacro())
+  if (!MI || MI->isBuiltinMacro())
     return 0;
   
   assert(MacroIDs.find(MI) != MacroIDs.end() && "Macro not emitted!");
@@ -4441,7 +4717,7 @@
 }
 
 SelectorID ASTWriter::getSelectorRef(Selector Sel) {
-  if (Sel.getAsOpaquePtr() == 0) {
+  if (Sel.getAsOpaquePtr() == nullptr) {
     return 0;
   }
 
@@ -4519,7 +4795,7 @@
 
 void ASTWriter::AddTypeSourceInfo(TypeSourceInfo *TInfo, 
                                   RecordDataImpl &Record) {
-  if (TInfo == 0) {
+  if (!TInfo) {
     AddTypeRef(QualType(), Record);
     return;
   }
@@ -4587,8 +4863,8 @@
 
 DeclID ASTWriter::GetDeclRef(const Decl *D) {
   assert(WritingAST && "Cannot request a declaration ID before AST writing");
-  
-  if (D == 0) {
+
+  if (!D) {
     return 0;
   }
   
@@ -4615,7 +4891,7 @@
 }
 
 DeclID ASTWriter::getDeclID(const Decl *D) {
-  if (D == 0)
+  if (!D)
     return 0;
 
   // If D comes from an AST file, its declaration ID is already known and
@@ -4648,7 +4924,7 @@
   assert(SM.isLocalSourceLocation(FileLoc));
   FileID FID;
   unsigned Offset;
-  llvm::tie(FID, Offset) = SM.getDecomposedLoc(FileLoc);
+  std::tie(FID, Offset) = SM.getDecomposedLoc(FileLoc);
   if (FID.isInvalid())
     return;
   assert(SM.getSLocEntry(FID).isFile());
@@ -4934,9 +5210,8 @@
     break;
   case TemplateArgument::Pack:
     Record.push_back(Arg.pack_size());
-    for (TemplateArgument::pack_iterator I=Arg.pack_begin(), E=Arg.pack_end();
-           I != E; ++I)
-      AddTemplateArgument(*I, Record);
+    for (const auto &P : Arg.pack_elements())
+      AddTemplateArgument(P, Record);
     break;
   }
 }
@@ -5068,8 +5343,7 @@
 }
 
 void ASTWriter::AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Record) {
-  assert(D->DefinitionData);
-  struct CXXRecordDecl::DefinitionData &Data = *D->DefinitionData;
+  auto &Data = D->data();
   Record.push_back(Data.IsLambda);
   Record.push_back(Data.UserDeclaredConstructor);
   Record.push_back(Data.UserDeclaredSpecialMembers);
@@ -5084,6 +5358,7 @@
   Record.push_back(Data.HasProtectedFields);
   Record.push_back(Data.HasPublicFields);
   Record.push_back(Data.HasMutableFields);
+  Record.push_back(Data.HasVariantMembers);
   Record.push_back(Data.HasOnlyCMembers);
   Record.push_back(Data.HasInClassInitializer);
   Record.push_back(Data.HasUninitializedReferenceMember);
@@ -5094,6 +5369,7 @@
   Record.push_back(Data.DefaultedMoveAssignmentIsDeleted);
   Record.push_back(Data.DefaultedDestructorIsDeleted);
   Record.push_back(Data.HasTrivialSpecialMembers);
+  Record.push_back(Data.DeclaredNonTrivialSpecialMembers);
   Record.push_back(Data.HasIrrelevantDestructor);
   Record.push_back(Data.HasConstexprNonCopyMoveConstructor);
   Record.push_back(Data.DefaultedDefaultConstructorIsConstexpr);
@@ -5126,7 +5402,7 @@
   
   // Add lambda-specific data.
   if (Data.IsLambda) {
-    CXXRecordDecl::LambdaDefinitionData &Lambda = D->getLambdaData();
+    auto &Lambda = D->getLambdaData();
     Record.push_back(Lambda.Dependent);
     Record.push_back(Lambda.IsGenericLambda);
     Record.push_back(Lambda.CaptureDefault);
@@ -5136,7 +5412,7 @@
     AddDeclRef(Lambda.ContextDecl, Record);
     AddTypeSourceInfo(Lambda.MethodTyInfo, Record);
     for (unsigned I = 0, N = Lambda.NumCaptures; I != N; ++I) {
-      LambdaExpr::Capture &Capture = Lambda.Captures[I];
+      const LambdaCapture &Capture = Lambda.Captures[I];
       AddSourceLocation(Capture.getLocation(), Record);
       Record.push_back(Capture.isImplicit());
       Record.push_back(Capture.getCaptureKind());
@@ -5146,7 +5422,7 @@
       case LCK_ByCopy:
       case LCK_ByRef:
         VarDecl *Var =
-            Capture.capturesVariable() ? Capture.getCapturedVar() : 0;
+            Capture.capturesVariable() ? Capture.getCapturedVar() : nullptr;
         AddDeclRef(Var, Record);
         AddSourceLocation(Capture.isPackExpansion() ? Capture.getEllipsisLoc()
                                                     : SourceLocation(),
@@ -5236,7 +5512,10 @@
       // A forward reference was mutated into a definition. Rewrite it.
       // FIXME: This happens during template instantiation, should we
       // have created a new definition decl instead ?
-      RewriteDecl(RD);
+      assert(isTemplateInstantiation(RD->getTemplateSpecializationKind()) &&
+             "completed a tag from another module but not by instantiation?");
+      DeclUpdates[RD].push_back(
+          DeclUpdate(UPD_CXX_INSTANTIATED_CLASS_DEFINITION));
     }
   }
 }
@@ -5266,9 +5545,7 @@
 
   // A decl coming from PCH was modified.
   assert(RD->isCompleteDefinition());
-  UpdateRecord &Record = DeclUpdates[RD];
-  Record.push_back(UPD_CXX_ADDED_IMPLICIT_MEMBER);
-  Record.push_back(reinterpret_cast<uint64_t>(D));
+  DeclUpdates[RD].push_back(DeclUpdate(UPD_CXX_ADDED_IMPLICIT_MEMBER, D));
 }
 
 void ASTWriter::AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD,
@@ -5279,9 +5556,8 @@
   if (!(!D->isFromASTFile() && TD->isFromASTFile()))
     return; // Not a source specialization added to a template from PCH.
 
-  UpdateRecord &Record = DeclUpdates[TD];
-  Record.push_back(UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION);
-  Record.push_back(reinterpret_cast<uint64_t>(D));
+  DeclUpdates[TD].push_back(DeclUpdate(UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION,
+                                       D));
 }
 
 void ASTWriter::AddedCXXTemplateSpecialization(
@@ -5292,9 +5568,8 @@
   if (!(!D->isFromASTFile() && TD->isFromASTFile()))
     return; // Not a source specialization added to a template from PCH.
 
-  UpdateRecord &Record = DeclUpdates[TD];
-  Record.push_back(UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION);
-  Record.push_back(reinterpret_cast<uint64_t>(D));
+  DeclUpdates[TD].push_back(DeclUpdate(UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION,
+                                       D));
 }
 
 void ASTWriter::AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD,
@@ -5305,9 +5580,17 @@
   if (!(!D->isFromASTFile() && TD->isFromASTFile()))
     return; // Not a source specialization added to a template from PCH.
 
-  UpdateRecord &Record = DeclUpdates[TD];
-  Record.push_back(UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION);
-  Record.push_back(reinterpret_cast<uint64_t>(D));
+  DeclUpdates[TD].push_back(DeclUpdate(UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION,
+                                       D));
+}
+
+void ASTWriter::ResolvedExceptionSpec(const FunctionDecl *FD) {
+  assert(!WritingAST && "Already writing the AST!");
+  FD = FD->getCanonicalDecl();
+  if (!FD->isFromASTFile())
+    return; // Not a function declared in PCH and defined outside.
+
+  DeclUpdates[FD].push_back(UPD_CXX_RESOLVED_EXCEPTION_SPEC);
 }
 
 void ASTWriter::DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) {
@@ -5316,9 +5599,7 @@
   if (!FD->isFromASTFile())
     return; // Not a function declared in PCH and defined outside.
 
-  UpdateRecord &Record = DeclUpdates[FD];
-  Record.push_back(UPD_CXX_DEDUCED_RETURN_TYPE);
-  Record.push_back(reinterpret_cast<uint64_t>(ReturnType.getAsOpaquePtr()));
+  DeclUpdates[FD].push_back(DeclUpdate(UPD_CXX_DEDUCED_RETURN_TYPE, ReturnType));
 }
 
 void ASTWriter::CompletedImplicitDefinition(const FunctionDecl *D) {
@@ -5331,6 +5612,17 @@
   RewriteDecl(D);
 }
 
+void ASTWriter::FunctionDefinitionInstantiated(const FunctionDecl *D) {
+  assert(!WritingAST && "Already writing the AST!");
+  if (!D->isFromASTFile())
+    return;
+
+  // Since the actual instantiation is delayed, this really means that we need
+  // to update the instantiation location.
+  DeclUpdates[D].push_back(
+      DeclUpdate(UPD_CXX_INSTANTIATED_FUNCTION_DEFINITION));
+}
+
 void ASTWriter::StaticDataMemberInstantiated(const VarDecl *D) {
   assert(!WritingAST && "Already writing the AST!");
   if (!D->isFromASTFile())
@@ -5338,10 +5630,9 @@
 
   // Since the actual instantiation is delayed, this really means that we need
   // to update the instantiation location.
-  UpdateRecord &Record = DeclUpdates[D];
-  Record.push_back(UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER);
-  AddSourceLocation(
-      D->getMemberSpecializationInfo()->getPointOfInstantiation(), Record);
+  DeclUpdates[D].push_back(
+      DeclUpdate(UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER,
+       D->getMemberSpecializationInfo()->getPointOfInstantiation()));
 }
 
 void ASTWriter::AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
@@ -5375,6 +5666,5 @@
   if (!D->isFromASTFile())
     return;
 
-  UpdateRecord &Record = DeclUpdates[D];
-  Record.push_back(UPD_DECL_MARKED_USED);
+  DeclUpdates[D].push_back(DeclUpdate(UPD_DECL_MARKED_USED));
 }
diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp
index 55f830a..47ce747 100644
--- a/lib/Serialization/ASTWriterDecl.cpp
+++ b/lib/Serialization/ASTWriterDecl.cpp
@@ -130,6 +130,14 @@
     void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
     void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
     void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D);
+
+    void AddFunctionDefinition(const FunctionDecl *FD) {
+      assert(FD->doesThisDeclarationHaveABody());
+      if (auto *CD = dyn_cast<CXXConstructorDecl>(FD))
+        Writer.AddCXXCtorInitializers(CD->CtorInitializers,
+                                      CD->NumCtorInitializers, Record);
+      Writer.AddStmt(FD->getBody());
+    }
   };
 }
 
@@ -168,6 +176,24 @@
   Record.push_back(D->getAccess());
   Record.push_back(D->isModulePrivate());
   Record.push_back(Writer.inferSubmoduleIDFromLocation(D->getLocation()));
+
+  // If this declaration injected a name into a context different from its
+  // lexical context, and that context is an imported namespace, we need to
+  // update its visible declarations to include this name.
+  //
+  // This happens when we instantiate a class with a friend declaration or a
+  // function with a local extern declaration, for instance.
+  if (D->isOutOfLine()) {
+    auto *DC = D->getDeclContext();
+    while (auto *NS = dyn_cast<NamespaceDecl>(DC->getRedeclContext())) {
+      if (!NS->isFromASTFile())
+        break;
+      Writer.AddUpdatedDeclContext(NS->getPrimaryContext());
+      if (!NS->isInlineNamespace())
+        break;
+      DC = NS->getParent();
+    }
+  }
 }
 
 void ASTDeclWriter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
@@ -251,7 +277,7 @@
     Record.push_back(MemberInfo->getTemplateSpecializationKind());
     Writer.AddSourceLocation(MemberInfo->getPointOfInstantiation(), Record);
   } else {
-    Writer.AddDeclRef(0, Record);
+    Writer.AddDeclRef(nullptr, Record);
   }
 
   if (!D->hasAttrs() &&
@@ -372,7 +398,7 @@
     Writer.AddTemplateArgumentList(FTSInfo->TemplateArguments, Record);
     
     // Template args as written.
-    Record.push_back(FTSInfo->TemplateArgumentsAsWritten != 0);
+    Record.push_back(FTSInfo->TemplateArgumentsAsWritten != nullptr);
     if (FTSInfo->TemplateArgumentsAsWritten) {
       Record.push_back(FTSInfo->TemplateArgumentsAsWritten->NumTemplateArgs);
       for (int i=0, e = FTSInfo->TemplateArgumentsAsWritten->NumTemplateArgs;
@@ -414,9 +440,8 @@
   }
 
   Record.push_back(D->param_size());
-  for (FunctionDecl::param_iterator P = D->param_begin(), PEnd = D->param_end();
-       P != PEnd; ++P)
-    Writer.AddDeclRef(*P, Record);
+  for (auto P : D->params())
+    Writer.AddDeclRef(P, Record);
   Code = serialization::DECL_FUNCTION;
 }
 
@@ -424,8 +449,8 @@
   VisitNamedDecl(D);
   // FIXME: convert to LazyStmtPtr?
   // Unlike C/C++, method bodies will never be in header files.
-  bool HasBodyStuff = D->getBody() != 0     ||
-                      D->getSelfDecl() != 0 || D->getCmdDecl() != 0;
+  bool HasBodyStuff = D->getBody() != nullptr     ||
+                      D->getSelfDecl() != nullptr || D->getCmdDecl() != nullptr;
   Record.push_back(HasBodyStuff);
   if (HasBodyStuff) {
     Writer.AddStmt(D->getBody());
@@ -451,13 +476,12 @@
   // FIXME: stable encoding for in/out/inout/bycopy/byref/oneway
   Record.push_back(D->getObjCDeclQualifier());
   Record.push_back(D->hasRelatedResultType());
-  Writer.AddTypeRef(D->getResultType(), Record);
-  Writer.AddTypeSourceInfo(D->getResultTypeSourceInfo(), Record);
+  Writer.AddTypeRef(D->getReturnType(), Record);
+  Writer.AddTypeSourceInfo(D->getReturnTypeSourceInfo(), Record);
   Writer.AddSourceLocation(D->getLocEnd(), Record);
   Record.push_back(D->param_size());
-  for (ObjCMethodDecl::param_iterator P = D->param_begin(),
-                                   PEnd = D->param_end(); P != PEnd; ++P)
-    Writer.AddDeclRef(*P, Record);
+  for (const auto *P : D->params())
+    Writer.AddDeclRef(P, Record);
 
   Record.push_back(D->SelLocsKind);
   unsigned NumStoredSelLocs = D->getNumStoredSelLocs();
@@ -489,17 +513,14 @@
     Writer.AddDeclRef(D->getSuperClass(), Record);
     Writer.AddSourceLocation(D->getSuperClassLoc(), Record);
     Writer.AddSourceLocation(D->getEndOfDefinitionLoc(), Record);
+    Record.push_back(Data.HasDesignatedInitializers);
 
     // Write out the protocols that are directly referenced by the @interface.
     Record.push_back(Data.ReferencedProtocols.size());
-    for (ObjCInterfaceDecl::protocol_iterator P = D->protocol_begin(),
-                                           PEnd = D->protocol_end();
-         P != PEnd; ++P)
-      Writer.AddDeclRef(*P, Record);
-    for (ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin(),
-         PLEnd = D->protocol_loc_end();
-         PL != PLEnd; ++PL)
-      Writer.AddSourceLocation(*PL, Record);
+    for (const auto *P : D->protocols())
+      Writer.AddDeclRef(P, Record);
+    for (const auto &PL : D->protocol_locs())
+      Writer.AddSourceLocation(PL, Record);
     
     // Write out the protocols that are transitively referenced.
     Record.push_back(Data.AllReferencedProtocols.size());
@@ -528,7 +549,6 @@
   // FIXME: stable encoding for @public/@private/@protected/@package
   Record.push_back(D->getAccessControl());
   Record.push_back(D->getSynthesize());
-  Record.push_back(D->getBackingIvarReferencedInAccessor());
 
   if (!D->hasAttrs() &&
       !D->isImplicit() &&
@@ -551,13 +571,10 @@
   Record.push_back(D->isThisDeclarationADefinition());
   if (D->isThisDeclarationADefinition()) {
     Record.push_back(D->protocol_size());
-    for (ObjCProtocolDecl::protocol_iterator
-         I = D->protocol_begin(), IEnd = D->protocol_end(); I != IEnd; ++I)
-      Writer.AddDeclRef(*I, Record);
-    for (ObjCProtocolDecl::protocol_loc_iterator PL = D->protocol_loc_begin(),
-           PLEnd = D->protocol_loc_end();
-         PL != PLEnd; ++PL)
-      Writer.AddSourceLocation(*PL, Record);
+    for (const auto *I : D->protocols())
+      Writer.AddDeclRef(I, Record);
+    for (const auto &PL : D->protocol_locs())
+      Writer.AddSourceLocation(PL, Record);
   }
   
   Code = serialization::DECL_OBJC_PROTOCOL;
@@ -575,13 +592,10 @@
   Writer.AddSourceLocation(D->getIvarRBraceLoc(), Record);
   Writer.AddDeclRef(D->getClassInterface(), Record);
   Record.push_back(D->protocol_size());
-  for (ObjCCategoryDecl::protocol_iterator
-       I = D->protocol_begin(), IEnd = D->protocol_end(); I != IEnd; ++I)
-    Writer.AddDeclRef(*I, Record);
-  for (ObjCCategoryDecl::protocol_loc_iterator 
-         PL = D->protocol_loc_begin(), PLEnd = D->protocol_loc_end();
-       PL != PLEnd; ++PL)
-    Writer.AddSourceLocation(*PL, Record);
+  for (const auto *I : D->protocols())
+    Writer.AddDeclRef(I, Record);
+  for (const auto &PL : D->protocol_locs())
+    Writer.AddSourceLocation(PL, Record);
   Code = serialization::DECL_OBJC_CATEGORY;
 }
 
@@ -688,10 +702,8 @@
   VisitValueDecl(D);
   Record.push_back(D->getChainingSize());
 
-  for (IndirectFieldDecl::chain_iterator
-       P = D->chain_begin(),
-       PEnd = D->chain_end(); P != PEnd; ++P)
-    Writer.AddDeclRef(*P, Record);
+  for (const auto *P : D->chain())
+    Writer.AddDeclRef(P, Record);
   Code = serialization::DECL_INDIRECTFIELD;
 }
 
@@ -745,7 +757,7 @@
       !D->hasExtInfo() &&
       D->getFirstDecl() == D->getMostRecentDecl() &&
       D->getInitStyle() == VarDecl::CInit &&
-      D->getInit() == 0 &&
+      D->getInit() == nullptr &&
       !isa<ParmVarDecl>(D) &&
       !isa<VarTemplateSpecializationDecl>(D) &&
       !D->isConstexpr() &&
@@ -794,7 +806,7 @@
       D->getObjCDeclQualifier() == 0 &&
       !D->isKNRPromoted() &&
       !D->hasInheritedDefaultArg() &&
-      D->getInit() == 0 &&
+      D->getInit() == nullptr &&
       !D->hasUninstantiatedDefaultArg())  // No default expr.
     AbbrevToUse = Writer.getDeclParmVarAbbrev();
 
@@ -803,7 +815,7 @@
   assert(!D->getTSCSpec() && "PARM_VAR_DECL can't use TLS");
   assert(D->getAccess() == AS_none && "PARM_VAR_DECL can't be public/private");
   assert(!D->isExceptionVariable() && "PARM_VAR_DECL can't be exception var");
-  assert(D->getPreviousDecl() == 0 && "PARM_VAR_DECL can't be redecl");
+  assert(D->getPreviousDecl() == nullptr && "PARM_VAR_DECL can't be redecl");
   assert(!D->isStaticDataMember() &&
          "PARM_VAR_DECL can't be static data member");
 }
@@ -833,9 +845,7 @@
   Record.push_back(D->isConversionFromLambda());
   Record.push_back(D->capturesCXXThis());
   Record.push_back(D->getNumCaptures());
-  for (BlockDecl::capture_iterator
-         i = D->capture_begin(), e = D->capture_end(); i != e; ++i) {
-    const BlockDecl::Capture &capture = *i;
+  for (const auto &capture : D->captures()) {
     Writer.AddDeclRef(capture.getVariable(), Record);
 
     unsigned flags = 0;
@@ -853,9 +863,11 @@
 void ASTDeclWriter::VisitCapturedDecl(CapturedDecl *CD) {
   Record.push_back(CD->getNumParams());
   VisitDecl(CD);
+  Record.push_back(CD->getContextParamPosition());
+  Record.push_back(CD->isNothrow() ? 1 : 0);
   // Body is stored by VisitCapturedStmt.
-  for (unsigned i = 0; i < CD->getNumParams(); ++i)
-    Writer.AddDeclRef(CD->getParam(i), Record);
+  for (unsigned I = 0; I < CD->getNumParams(); ++I)
+    Writer.AddDeclRef(CD->getParam(I), Record);
   Code = serialization::DECL_CAPTURED;
 }
 
@@ -911,9 +923,8 @@
     Decl *Parent = cast<Decl>(
         D->getParent()->getRedeclContext()->getPrimaryContext());
     if (Parent->isFromASTFile() || isa<TranslationUnitDecl>(Parent)) {
-      ASTWriter::UpdateRecord &Record = Writer.DeclUpdates[Parent];
-      Record.push_back(UPD_CXX_ADDED_ANONYMOUS_NAMESPACE);
-      Writer.AddDeclRef(D, Record);
+      Writer.DeclUpdates[Parent].push_back(
+          ASTWriter::DeclUpdate(UPD_CXX_ADDED_ANONYMOUS_NAMESPACE, D));
     }
   }
 }
@@ -975,9 +986,6 @@
 
 void ASTDeclWriter::VisitCXXRecordDecl(CXXRecordDecl *D) {
   VisitRecordDecl(D);
-  Record.push_back(D->isThisDeclarationADefinition());
-  if (D->isThisDeclarationADefinition())
-    Writer.AddCXXDefinitionData(D, Record);
 
   enum {
     CXXRecNotTemplate = 0, CXXRecTemplate, CXXRecMemberSpecialization
@@ -995,6 +1003,10 @@
     Record.push_back(CXXRecNotTemplate);
   }
 
+  Record.push_back(D->isThisDeclarationADefinition());
+  if (D->isThisDeclarationADefinition())
+    Writer.AddCXXDefinitionData(D, Record);
+
   // Store (what we currently believe to be) the key function to avoid
   // deserializing every method so we can compute it.
   if (D->IsCompleteDefinition)
@@ -1021,6 +1033,7 @@
 void ASTDeclWriter::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
   VisitCXXMethodDecl(D);
 
+  Writer.AddDeclRef(D->getInheritedConstructor(), Record);
   Record.push_back(D->IsExplicitSpecified);
   Writer.AddCXXCtorInitializers(D->CtorInitializers, D->NumCtorInitializers,
                                 Record);
@@ -1091,7 +1104,7 @@
   Record.push_back(D->getNumTemplateParameters());
   for (unsigned i = 0, e = D->getNumTemplateParameters(); i != e; ++i)
     Writer.AddTemplateParameterList(D->getTemplateParameterList(i), Record);
-  Record.push_back(D->getFriendDecl() != 0);
+  Record.push_back(D->getFriendDecl() != nullptr);
   if (D->getFriendDecl())
     Writer.AddDeclRef(D->getFriendDecl(), Record);
   else
@@ -1143,8 +1156,6 @@
       assert(I->isCanonicalDecl() && "Expected only canonical decls in set");
       Writer.AddDeclRef(&*I, Record); 
     }
-
-    Writer.AddTypeRef(D->getCommonPtr()->InjectedClassNameType, Record);
   }
   Code = serialization::DECL_CLASS_TEMPLATE;
 }
@@ -1192,7 +1203,7 @@
   Writer.AddASTTemplateArgumentListInfo(D->getTemplateArgsAsWritten(), Record);
 
   // These are read/set from/to the first declaration.
-  if (D->getPreviousDecl() == 0) {
+  if (D->getPreviousDecl() == nullptr) {
     Writer.AddDeclRef(D->getInstantiatedFromMember(), Record);
     Record.push_back(D->isMemberSpecialization());
   }
@@ -1268,7 +1279,7 @@
   Writer.AddASTTemplateArgumentListInfo(D->getTemplateArgsAsWritten(), Record);
 
   // These are read/set from/to the first declaration.
-  if (D->getPreviousDecl() == 0) {
+  if (D->getPreviousDecl() == nullptr) {
     Writer.AddDeclRef(D->getInstantiatedFromMember(), Record);
     Record.push_back(D->isMemberSpecialization());
   }
@@ -1335,7 +1346,7 @@
   } else {
     // Rest of NonTypeTemplateParmDecl.
     Record.push_back(D->isParameterPack());
-    Record.push_back(D->getDefaultArgument() != 0);
+    Record.push_back(D->getDefaultArgument() != nullptr);
     if (D->getDefaultArgument()) {
       Writer.AddStmt(D->getDefaultArgument());
       Record.push_back(D->defaultArgumentWasInherited());
@@ -1429,10 +1440,8 @@
 void ASTDeclWriter::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) {
   Record.push_back(D->varlist_size());
   VisitDecl(D);
-  for (OMPThreadPrivateDecl::varlist_iterator I = D->varlist_begin(),
-                                              E = D->varlist_end();
-       I != E; ++I)
-    Writer.AddStmt(*I);
+  for (auto *I : D->varlists())
+    Writer.AddStmt(I);
   Code = serialization::DECL_OMP_THREADPRIVATE;
 }
 
@@ -1506,8 +1515,6 @@
   // ObjC Ivar
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getAccessControl
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // getSynthesize
-  // getBackingIvarReferencedInAccessor
-  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
   // Type Source Info
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array));
@@ -1817,8 +1824,10 @@
   // An ObjCMethodDecl is never considered as "required" because its
   // implementation container always is.
 
-  // File scoped assembly or obj-c implementation must be seen.
-  if (isa<FileScopeAsmDecl>(D) || isa<ObjCImplDecl>(D))
+  // File scoped assembly or obj-c implementation must be seen. ImportDecl is
+  // used by codegen to determine the set of imported modules to search for
+  // inputs for automatic linking.
+  if (isa<FileScopeAsmDecl>(D) || isa<ObjCImplDecl>(D) || isa<ImportDecl>(D))
     return true;
 
   return Context.DeclMustBeEmitted(D);
@@ -1906,10 +1915,16 @@
   // Flush C++ base specifiers, if there are any.
   FlushCXXBaseSpecifiers();
   
-  // Note "external" declarations so that we can add them to a record in the
-  // AST file later.
-  //
-  // FIXME: This should be renamed, the predicate is much more complicated.
+  // 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))
-    ExternalDefinitions.push_back(ID);
+    EagerlyDeserializedDecls.push_back(ID);
+}
+
+void ASTWriter::AddFunctionDefinition(const FunctionDecl *FD,
+                                      RecordData &Record) {
+  ClearSwitchCaseIDs();
+
+  ASTDeclWriter W(*this, FD->getASTContext(), Record);
+  W.AddFunctionDefinition(FD);
 }
diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp
index 072fc98..a43b352 100644
--- a/lib/Serialization/ASTWriterStmt.cpp
+++ b/lib/Serialization/ASTWriterStmt.cpp
@@ -71,9 +71,8 @@
 void ASTStmtWriter::VisitCompoundStmt(CompoundStmt *S) {
   VisitStmt(S);
   Record.push_back(S->size());
-  for (CompoundStmt::body_iterator CS = S->body_begin(), CSEnd = S->body_end();
-       CS != CSEnd; ++CS)
-    Writer.AddStmt(*CS);
+  for (auto *CS : S->body())
+    Writer.AddStmt(CS);
   Writer.AddSourceLocation(S->getLBracLoc(), Record);
   Writer.AddSourceLocation(S->getRBracLoc(), Record);
   Code = serialization::STMT_COMPOUND;
@@ -300,24 +299,20 @@
   Writer.AddDeclRef(S->getCapturedRecordDecl(), Record);
 
   // Capture inits
-  for (CapturedStmt::capture_init_iterator I = S->capture_init_begin(),
-                                           E = S->capture_init_end();
-       I != E; ++I)
-    Writer.AddStmt(*I);
+  for (auto *I : S->capture_inits())
+    Writer.AddStmt(I);
 
   // Body
   Writer.AddStmt(S->getCapturedStmt());
 
   // Captures
-  for (CapturedStmt::capture_iterator I = S->capture_begin(),
-                                      E = S->capture_end();
-       I != E; ++I) {
-    if (I->capturesThis())
-      Writer.AddDeclRef(0, Record);
+  for (const auto &I : S->captures()) {
+    if (I.capturesThis())
+      Writer.AddDeclRef(nullptr, Record);
     else
-      Writer.AddDeclRef(I->getCapturedVar(), Record);
-    Record.push_back(I->getCaptureKind());
-    Writer.AddSourceLocation(I->getLocation(), Record);
+      Writer.AddDeclRef(I.getCapturedVar(), Record);
+    Record.push_back(I.getCaptureKind());
+    Writer.AddSourceLocation(I.getLocation(), Record);
   }
 
   Code = serialization::STMT_CAPTURED;
@@ -692,7 +687,7 @@
     // Replace them by 0 to indicate that the filler goes in that place.
     Expr *filler = E->getArrayFiller();
     for (unsigned I = 0, N = E->getNumInits(); I != N; ++I)
-      Writer.AddStmt(E->getInit(I) != filler ? E->getInit(I) : 0);
+      Writer.AddStmt(E->getInit(I) != filler ? E->getInit(I) : nullptr);
   } else {
     for (unsigned I = 0, N = E->getNumInits(); I != N; ++I)
       Writer.AddStmt(E->getInit(I));
@@ -1056,7 +1051,7 @@
 
 void ASTStmtWriter::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
   Record.push_back(S->getNumCatchStmts());
-  Record.push_back(S->getFinallyStmt() != 0);
+  Record.push_back(S->getFinallyStmt() != nullptr);
   Writer.AddStmt(S->getTryBody());
   for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I)
     Writer.AddStmt(S->getCatchStmt(I));
@@ -1155,6 +1150,7 @@
   Record.push_back(E->isElidable());
   Record.push_back(E->hadMultipleCandidates());
   Record.push_back(E->isListInitialization());
+  Record.push_back(E->isStdInitListInitialization());
   Record.push_back(E->requiresZeroInitialization());
   Record.push_back(E->getConstructionKind()); // FIXME: stable encoding
   Writer.AddSourceRange(E->getParenOrBraceRange(), Record);
@@ -1402,7 +1398,7 @@
   if (!E->isImplicitAccess())
     Writer.AddStmt(E->getBase());
   else
-    Writer.AddStmt(0);
+    Writer.AddStmt(nullptr);
   Writer.AddTypeRef(E->getBaseType(), Record);
   Record.push_back(E->isArrow());
   Writer.AddSourceLocation(E->getOperatorLoc(), Record);
@@ -1472,7 +1468,7 @@
   VisitOverloadExpr(E);
   Record.push_back(E->isArrow());
   Record.push_back(E->hasUnresolvedUsing());
-  Writer.AddStmt(!E->isImplicitAccess() ? E->getBase() : 0);
+  Writer.AddStmt(!E->isImplicitAccess() ? E->getBase() : nullptr);
   Writer.AddTypeRef(E->getBaseType(), Record);
   Writer.AddSourceLocation(E->getOperatorLoc(), Record);
   Code = serialization::EXPR_CXX_UNRESOLVED_MEMBER;
@@ -1486,30 +1482,12 @@
   Code = serialization::EXPR_CXX_UNRESOLVED_LOOKUP;
 }
 
-void ASTStmtWriter::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
-  VisitExpr(E);
-  Record.push_back(E->getTrait());
-  Record.push_back(E->getValue());
-  Writer.AddSourceRange(E->getSourceRange(), Record);
-  Writer.AddTypeSourceInfo(E->getQueriedTypeSourceInfo(), Record);
-  Code = serialization::EXPR_CXX_UNARY_TYPE_TRAIT;
-}
-
-void ASTStmtWriter::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
-  VisitExpr(E);
-  Record.push_back(E->getTrait());
-  Record.push_back(E->getValue());
-  Writer.AddSourceRange(E->getSourceRange(), Record);
-  Writer.AddTypeSourceInfo(E->getLhsTypeSourceInfo(), Record);
-  Writer.AddTypeSourceInfo(E->getRhsTypeSourceInfo(), Record);
-  Code = serialization::EXPR_BINARY_TYPE_TRAIT;
-}
-
 void ASTStmtWriter::VisitTypeTraitExpr(TypeTraitExpr *E) {
   VisitExpr(E);
   Record.push_back(E->TypeTraitExprBits.NumArgs);
   Record.push_back(E->TypeTraitExprBits.Kind); // FIXME: Stable encoding
   Record.push_back(E->TypeTraitExprBits.Value);
+  Writer.AddSourceRange(E->getSourceRange(), Record);
   for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
     Writer.AddTypeSourceInfo(E->getArg(I), Record);
   Code = serialization::EXPR_TYPE_TRAIT;
@@ -1590,8 +1568,9 @@
 
 void ASTStmtWriter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
   VisitExpr(E);
-  Writer.AddStmt(E->Temporary);
-  Writer.AddDeclRef(E->ExtendingDecl, Record);
+  Writer.AddStmt(E->getTemporary());
+  Writer.AddDeclRef(E->getExtendingDecl(), Record);
+  Record.push_back(E->getManglingNumber());
   Code = serialization::EXPR_MATERIALIZE_TEMPORARY;
 }
 
@@ -1672,6 +1651,12 @@
   Code = serialization::STMT_SEH_TRY;
 }
 
+void ASTStmtWriter::VisitSEHLeaveStmt(SEHLeaveStmt *S) {
+  VisitStmt(S);
+  Writer.AddSourceLocation(S->getLeaveLoc(), Record);
+  Code = serialization::STMT_SEH_LEAVE;
+}
+
 //===----------------------------------------------------------------------===//
 // OpenMP Clauses.
 //===----------------------------------------------------------------------===//
@@ -1697,59 +1682,254 @@
   Writer->Writer.AddSourceLocation(C->getLocEnd(), Record);
 }
 
+void OMPClauseWriter::VisitOMPIfClause(OMPIfClause *C) {
+  Writer->Writer.AddStmt(C->getCondition());
+  Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
+}
+
+void OMPClauseWriter::VisitOMPFinalClause(OMPFinalClause *C) {
+  Writer->Writer.AddStmt(C->getCondition());
+  Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
+}
+
+void OMPClauseWriter::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) {
+  Writer->Writer.AddStmt(C->getNumThreads());
+  Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
+}
+
+void OMPClauseWriter::VisitOMPSafelenClause(OMPSafelenClause *C) {
+  Writer->Writer.AddStmt(C->getSafelen());
+  Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
+}
+
+void OMPClauseWriter::VisitOMPCollapseClause(OMPCollapseClause *C) {
+  Writer->Writer.AddStmt(C->getNumForLoops());
+  Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
+}
+
 void OMPClauseWriter::VisitOMPDefaultClause(OMPDefaultClause *C) {
   Record.push_back(C->getDefaultKind());
   Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
   Writer->Writer.AddSourceLocation(C->getDefaultKindKwLoc(), Record);
 }
 
+void OMPClauseWriter::VisitOMPProcBindClause(OMPProcBindClause *C) {
+  Record.push_back(C->getProcBindKind());
+  Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
+  Writer->Writer.AddSourceLocation(C->getProcBindKindKwLoc(), Record);
+}
+
+void OMPClauseWriter::VisitOMPScheduleClause(OMPScheduleClause *C) {
+  Record.push_back(C->getScheduleKind());
+  Writer->Writer.AddStmt(C->getChunkSize());
+  Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
+  Writer->Writer.AddSourceLocation(C->getScheduleKindLoc(), Record);
+  Writer->Writer.AddSourceLocation(C->getCommaLoc(), Record);
+}
+
+void OMPClauseWriter::VisitOMPOrderedClause(OMPOrderedClause *) {}
+
+void OMPClauseWriter::VisitOMPNowaitClause(OMPNowaitClause *) {}
+
+void OMPClauseWriter::VisitOMPUntiedClause(OMPUntiedClause *) {}
+
+void OMPClauseWriter::VisitOMPMergeableClause(OMPMergeableClause *) {}
+
 void OMPClauseWriter::VisitOMPPrivateClause(OMPPrivateClause *C) {
   Record.push_back(C->varlist_size());
   Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
-  for (OMPPrivateClause::varlist_iterator I = C->varlist_begin(),
-                                          E = C->varlist_end();
-       I != E; ++I)
-    Writer->Writer.AddStmt(*I);
+  for (auto *VE : C->varlists())
+    Writer->Writer.AddStmt(VE);
 }
 
 void OMPClauseWriter::VisitOMPFirstprivateClause(OMPFirstprivateClause *C) {
   Record.push_back(C->varlist_size());
   Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
-  for (OMPFirstprivateClause::varlist_iterator I = C->varlist_begin(),
-                                               E = C->varlist_end();
-       I != E; ++I)
-    Writer->Writer.AddStmt(*I);
+  for (auto *VE : C->varlists())
+    Writer->Writer.AddStmt(VE);
+}
+
+void OMPClauseWriter::VisitOMPLastprivateClause(OMPLastprivateClause *C) {
+  Record.push_back(C->varlist_size());
+  Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
+  for (auto *VE : C->varlists())
+    Writer->Writer.AddStmt(VE);
 }
 
 void OMPClauseWriter::VisitOMPSharedClause(OMPSharedClause *C) {
   Record.push_back(C->varlist_size());
   Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
-  for (OMPSharedClause::varlist_iterator I = C->varlist_begin(),
-                                         E = C->varlist_end();
-       I != E; ++I)
-    Writer->Writer.AddStmt(*I);
+  for (auto *VE : C->varlists())
+    Writer->Writer.AddStmt(VE);
+}
+
+void OMPClauseWriter::VisitOMPReductionClause(OMPReductionClause *C) {
+  Record.push_back(C->varlist_size());
+  Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
+  Writer->Writer.AddSourceLocation(C->getColonLoc(), Record);
+  Writer->Writer.AddNestedNameSpecifierLoc(C->getQualifierLoc(), Record);
+  Writer->Writer.AddDeclarationNameInfo(C->getNameInfo(), Record);
+  for (auto *VE : C->varlists())
+    Writer->Writer.AddStmt(VE);
+}
+
+void OMPClauseWriter::VisitOMPLinearClause(OMPLinearClause *C) {
+  Record.push_back(C->varlist_size());
+  Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
+  Writer->Writer.AddSourceLocation(C->getColonLoc(), Record);
+  for (auto *VE : C->varlists())
+    Writer->Writer.AddStmt(VE);
+  Writer->Writer.AddStmt(C->getStep());
+}
+
+void OMPClauseWriter::VisitOMPAlignedClause(OMPAlignedClause *C) {
+  Record.push_back(C->varlist_size());
+  Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
+  Writer->Writer.AddSourceLocation(C->getColonLoc(), Record);
+  for (auto *VE : C->varlists())
+    Writer->Writer.AddStmt(VE);
+  Writer->Writer.AddStmt(C->getAlignment());
+}
+
+void OMPClauseWriter::VisitOMPCopyinClause(OMPCopyinClause *C) {
+  Record.push_back(C->varlist_size());
+  Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
+  for (auto *VE : C->varlists())
+    Writer->Writer.AddStmt(VE);
+}
+
+void OMPClauseWriter::VisitOMPCopyprivateClause(OMPCopyprivateClause *C) {
+  Record.push_back(C->varlist_size());
+  Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
+  for (auto *VE : C->varlists())
+    Writer->Writer.AddStmt(VE);
+}
+
+void OMPClauseWriter::VisitOMPFlushClause(OMPFlushClause *C) {
+  Record.push_back(C->varlist_size());
+  Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
+  for (auto *VE : C->varlists())
+    Writer->Writer.AddStmt(VE);
 }
 
 //===----------------------------------------------------------------------===//
 // OpenMP Directives.
 //===----------------------------------------------------------------------===//
 void ASTStmtWriter::VisitOMPExecutableDirective(OMPExecutableDirective *E) {
-  VisitStmt(E);
-  Record.push_back(E->getNumClauses());
   Writer.AddSourceLocation(E->getLocStart(), Record);
   Writer.AddSourceLocation(E->getLocEnd(), Record);
   OMPClauseWriter ClauseWriter(this, Record);
   for (unsigned i = 0; i < E->getNumClauses(); ++i) {
     ClauseWriter.writeClause(E->getClause(i));
   }
-  Writer.AddStmt(E->getAssociatedStmt());
+  if (E->hasAssociatedStmt())
+    Writer.AddStmt(E->getAssociatedStmt());
 }
 
 void ASTStmtWriter::VisitOMPParallelDirective(OMPParallelDirective *D) {
+  VisitStmt(D);
+  Record.push_back(D->getNumClauses());
   VisitOMPExecutableDirective(D);
   Code = serialization::STMT_OMP_PARALLEL_DIRECTIVE;
 }
 
+void ASTStmtWriter::VisitOMPSimdDirective(OMPSimdDirective *D) {
+  VisitStmt(D);
+  Record.push_back(D->getNumClauses());
+  Record.push_back(D->getCollapsedNumber());
+  VisitOMPExecutableDirective(D);
+  Code = serialization::STMT_OMP_SIMD_DIRECTIVE;
+}
+
+void ASTStmtWriter::VisitOMPForDirective(OMPForDirective *D) {
+  VisitStmt(D);
+  Record.push_back(D->getNumClauses());
+  Record.push_back(D->getCollapsedNumber());
+  VisitOMPExecutableDirective(D);
+  Code = serialization::STMT_OMP_FOR_DIRECTIVE;
+}
+
+void ASTStmtWriter::VisitOMPSectionsDirective(OMPSectionsDirective *D) {
+  VisitStmt(D);
+  Record.push_back(D->getNumClauses());
+  VisitOMPExecutableDirective(D);
+  Code = serialization::STMT_OMP_SECTIONS_DIRECTIVE;
+}
+
+void ASTStmtWriter::VisitOMPSectionDirective(OMPSectionDirective *D) {
+  VisitStmt(D);
+  VisitOMPExecutableDirective(D);
+  Code = serialization::STMT_OMP_SECTION_DIRECTIVE;
+}
+
+void ASTStmtWriter::VisitOMPSingleDirective(OMPSingleDirective *D) {
+  VisitStmt(D);
+  Record.push_back(D->getNumClauses());
+  VisitOMPExecutableDirective(D);
+  Code = serialization::STMT_OMP_SINGLE_DIRECTIVE;
+}
+
+void ASTStmtWriter::VisitOMPMasterDirective(OMPMasterDirective *D) {
+  VisitStmt(D);
+  VisitOMPExecutableDirective(D);
+  Code = serialization::STMT_OMP_MASTER_DIRECTIVE;
+}
+
+void ASTStmtWriter::VisitOMPCriticalDirective(OMPCriticalDirective *D) {
+  VisitStmt(D);
+  VisitOMPExecutableDirective(D);
+  Writer.AddDeclarationNameInfo(D->getDirectiveName(), Record);
+  Code = serialization::STMT_OMP_CRITICAL_DIRECTIVE;
+}
+
+void ASTStmtWriter::VisitOMPParallelForDirective(OMPParallelForDirective *D) {
+  VisitStmt(D);
+  Record.push_back(D->getNumClauses());
+  Record.push_back(D->getCollapsedNumber());
+  VisitOMPExecutableDirective(D);
+  Code = serialization::STMT_OMP_PARALLEL_FOR_DIRECTIVE;
+}
+
+void ASTStmtWriter::VisitOMPParallelSectionsDirective(
+    OMPParallelSectionsDirective *D) {
+  VisitStmt(D);
+  Record.push_back(D->getNumClauses());
+  VisitOMPExecutableDirective(D);
+  Code = serialization::STMT_OMP_PARALLEL_SECTIONS_DIRECTIVE;
+}
+
+void ASTStmtWriter::VisitOMPTaskDirective(OMPTaskDirective *D) {
+  VisitStmt(D);
+  Record.push_back(D->getNumClauses());
+  VisitOMPExecutableDirective(D);
+  Code = serialization::STMT_OMP_TASK_DIRECTIVE;
+}
+
+void ASTStmtWriter::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *D) {
+  VisitStmt(D);
+  VisitOMPExecutableDirective(D);
+  Code = serialization::STMT_OMP_TASKYIELD_DIRECTIVE;
+}
+
+void ASTStmtWriter::VisitOMPBarrierDirective(OMPBarrierDirective *D) {
+  VisitStmt(D);
+  VisitOMPExecutableDirective(D);
+  Code = serialization::STMT_OMP_BARRIER_DIRECTIVE;
+}
+
+void ASTStmtWriter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
+  VisitStmt(D);
+  VisitOMPExecutableDirective(D);
+  Code = serialization::STMT_OMP_TASKWAIT_DIRECTIVE;
+}
+
+void ASTStmtWriter::VisitOMPFlushDirective(OMPFlushDirective *D) {
+  VisitStmt(D);
+  Record.push_back(D->getNumClauses());
+  VisitOMPExecutableDirective(D);
+  Code = serialization::STMT_OMP_FLUSH_DIRECTIVE;
+}
+
 //===----------------------------------------------------------------------===//
 // ASTWriter Implementation
 //===----------------------------------------------------------------------===//
@@ -1812,7 +1992,7 @@
   ParentStmtInserterRAII ParentStmtInserter(S, ParentStmts);
 #endif
 
-  // Redirect ASTWriter::AddStmt to collect sub stmts.
+  // Redirect ASTWriter::AddStmt to collect sub-stmts.
   SmallVector<Stmt *, 16> SubStmts;
   CollectedStmts = &SubStmts;
 
@@ -1825,16 +2005,16 @@
     SourceManager &SrcMgr
       = DeclIDs.begin()->first->getASTContext().getSourceManager();
     S->dump(SrcMgr);
-    llvm_unreachable("Unhandled sub statement writing AST file");
+    llvm_unreachable("Unhandled sub-statement writing AST file");
   }
 #endif
 
   // Revert ASTWriter::AddStmt.
   CollectedStmts = &StmtsToEmit;
 
-  // Write the sub stmts in reverse order, last to first. When reading them back
+  // Write the sub-stmts in reverse order, last to first. When reading them back
   // we will read them in correct order by "pop"ing them from the Stmts stack.
-  // This simplifies reading and allows to store a variable number of sub stmts
+  // This simplifies reading and allows to store a variable number of sub-stmts
   // without knowing it in advance.
   while (!SubStmts.empty())
     WriteSubStmt(SubStmts.pop_back_val(), SubStmtEntries, ParentStmts);
@@ -1851,7 +2031,7 @@
 
   // We expect to be the only consumer of the two temporary statement maps,
   // assert that they are empty.
-  assert(SubStmtEntries.empty() && "unexpected entries in sub stmt map");
+  assert(SubStmtEntries.empty() && "unexpected entries in sub-stmt map");
   assert(ParentStmts.empty() && "unexpected entries in parent stmt map");
 
   for (unsigned I = 0, N = StmtsToEmit.size(); I != N; ++I) {
diff --git a/lib/Serialization/CMakeLists.txt b/lib/Serialization/CMakeLists.txt
index 3c68b64..d885db2 100644
--- a/lib/Serialization/CMakeLists.txt
+++ b/lib/Serialization/CMakeLists.txt
@@ -1,8 +1,10 @@
-set(LLVM_LINK_COMPONENTS bitreader)
+set(LLVM_LINK_COMPONENTS
+  BitReader
+  Support
+  )
+
 
 add_clang_library(clangSerialization
-  ASTCommon.h
-  ASTReaderInternals.h
   ASTCommon.cpp
   ASTReader.cpp
   ASTReaderDecl.cpp
@@ -14,23 +16,14 @@
   GlobalModuleIndex.cpp
   Module.cpp
   ModuleManager.cpp
-  )
 
-add_dependencies(clangSerialization
-  ClangAttrClasses
-  ClangAttrList
-  ClangAttrParsedAttrList
-  ClangAttrPCHRead
-  ClangAttrPCHWrite
-  ClangCommentNodes
-  ClangDeclNodes
-  ClangDiagnosticCommon
-  ClangDiagnosticLex
-  ClangDiagnosticSema
-  ClangDiagnosticSerialization
-  ClangStmtNodes
-  )
+  ADDITIONAL_HEADERS
+  ASTCommon.h
+  ASTReaderInternals.h
 
-target_link_libraries(clangSerialization
+  LINK_LIBS
+  clangAST
+  clangBasic
+  clangLex
   clangSema
   )
diff --git a/lib/Serialization/GeneratePCH.cpp b/lib/Serialization/GeneratePCH.cpp
index 7e8baa2..b5031fd 100644
--- a/lib/Serialization/GeneratePCH.cpp
+++ b/lib/Serialization/GeneratePCH.cpp
@@ -31,7 +31,7 @@
                            raw_ostream *OS, bool AllowASTWithErrors)
   : PP(PP), OutputFile(OutputFile), Module(Module), 
     isysroot(isysroot.str()), Out(OS), 
-    SemaPtr(0), Stream(Buffer), Writer(Stream),
+    SemaPtr(nullptr), Stream(Buffer), Writer(Stream),
     AllowASTWithErrors(AllowASTWithErrors),
     HasEmittedPCH(false) {
 }
diff --git a/lib/Serialization/GlobalModuleIndex.cpp b/lib/Serialization/GlobalModuleIndex.cpp
index fb647b0..9858122 100644
--- a/lib/Serialization/GlobalModuleIndex.cpp
+++ b/lib/Serialization/GlobalModuleIndex.cpp
@@ -13,7 +13,7 @@
 
 #include "ASTReaderInternals.h"
 #include "clang/Basic/FileManager.h"
-#include "clang/Basic/OnDiskHashTable.h"
+#include "clang/Lex/HeaderSearch.h"
 #include "clang/Serialization/ASTBitCodes.h"
 #include "clang/Serialization/GlobalModuleIndex.h"
 #include "clang/Serialization/Module.h"
@@ -26,6 +26,7 @@
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/LockFileManager.h"
 #include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/OnDiskHashTable.h"
 #include "llvm/Support/Path.h"
 #include <cstdio>
 using namespace clang;
@@ -71,20 +72,22 @@
   typedef StringRef external_key_type;
   typedef StringRef internal_key_type;
   typedef SmallVector<unsigned, 2> data_type;
+  typedef unsigned hash_value_type;
+  typedef unsigned offset_type;
 
   static bool EqualKey(const internal_key_type& a, const internal_key_type& b) {
     return a == b;
   }
 
-  static unsigned ComputeHash(const internal_key_type& a) {
+  static hash_value_type ComputeHash(const internal_key_type& a) {
     return llvm::HashString(a);
   }
 
   static std::pair<unsigned, unsigned>
   ReadKeyDataLength(const unsigned char*& d) {
-    using namespace clang::io;
-    unsigned KeyLen = ReadUnalignedLE16(d);
-    unsigned DataLen = ReadUnalignedLE16(d);
+    using namespace llvm::support;
+    unsigned KeyLen = endian::readNext<uint16_t, little, unaligned>(d);
+    unsigned DataLen = endian::readNext<uint16_t, little, unaligned>(d);
     return std::make_pair(KeyLen, DataLen);
   }
 
@@ -101,11 +104,11 @@
   static data_type ReadData(const internal_key_type& k,
                             const unsigned char* d,
                             unsigned DataLen) {
-    using namespace clang::io;
+    using namespace llvm::support;
 
     data_type Result;
     while (DataLen > 0) {
-      unsigned ID = ReadUnalignedLE32(d);
+      unsigned ID = endian::readNext<uint32_t, little, unaligned>(d);
       Result.push_back(ID);
       DataLen -= 4;
     }
@@ -114,7 +117,8 @@
   }
 };
 
-typedef OnDiskChainedHashTable<IdentifierIndexReaderTrait> IdentifierIndexTable;
+typedef llvm::OnDiskIterableChainedHashTable<IdentifierIndexReaderTrait>
+    IdentifierIndexTable;
 
 }
 
@@ -202,7 +206,12 @@
       assert(Idx == Record.size() && "More module info?");
 
       // Record this module as an unresolved module.
-      UnresolvedModules[llvm::sys::path::stem(Modules[ID].FileName)] = ID;
+      // FIXME: this doesn't work correctly for module names containing path
+      // separators.
+      StringRef ModuleName = llvm::sys::path::stem(Modules[ID].FileName);
+      // Remove the -<hash of ModuleMapPath>
+      ModuleName = ModuleName.rsplit('-').first;
+      UnresolvedModules[ModuleName] = ID;
       break;
     }
 
@@ -210,16 +219,18 @@
       // Wire up the identifier index.
       if (Record[0]) {
         IdentifierIndex = IdentifierIndexTable::Create(
-                            (const unsigned char *)Blob.data() + Record[0],
-                            (const unsigned char *)Blob.data(),
-                            IdentifierIndexReaderTrait());
+            (const unsigned char *)Blob.data() + Record[0],
+            (const unsigned char *)Blob.data() + sizeof(uint32_t),
+            (const unsigned char *)Blob.data(), IdentifierIndexReaderTrait());
       }
       break;
     }
   }
 }
 
-GlobalModuleIndex::~GlobalModuleIndex() { }
+GlobalModuleIndex::~GlobalModuleIndex() {
+  delete static_cast<IdentifierIndexTable *>(IdentifierIndex);
+}
 
 std::pair<GlobalModuleIndex *, GlobalModuleIndex::ErrorCode>
 GlobalModuleIndex::readIndex(StringRef Path) {
@@ -228,10 +239,11 @@
   IndexPath += Path;
   llvm::sys::path::append(IndexPath, IndexFileName);
 
-  llvm::OwningPtr<llvm::MemoryBuffer> Buffer;
-  if (llvm::MemoryBuffer::getFile(IndexPath.c_str(), Buffer) !=
-      llvm::errc::success)
-    return std::make_pair((GlobalModuleIndex *)0, EC_NotFound);
+  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> BufferOrErr =
+      llvm::MemoryBuffer::getFile(IndexPath.c_str());
+  if (!BufferOrErr)
+    return std::make_pair(nullptr, EC_NotFound);
+  std::unique_ptr<llvm::MemoryBuffer> Buffer = std::move(BufferOrErr.get());
 
   /// \brief The bitstream reader from which we'll read the AST file.
   llvm::BitstreamReader Reader((const unsigned char *)Buffer->getBufferStart(),
@@ -245,10 +257,11 @@
       Cursor.Read(8) != 'C' ||
       Cursor.Read(8) != 'G' ||
       Cursor.Read(8) != 'I') {
-    return std::make_pair((GlobalModuleIndex *)0, EC_IOError);
+    return std::make_pair(nullptr, EC_IOError);
   }
-  
-  return std::make_pair(new GlobalModuleIndex(Buffer.take(), Cursor), EC_None);
+
+  return std::make_pair(new GlobalModuleIndex(Buffer.release(), Cursor),
+                        EC_None);
 }
 
 void
@@ -306,7 +319,7 @@
 
 bool GlobalModuleIndex::loadedModuleFile(ModuleFile *File) {
   // Look for the module in the global module index based on the module name.
-  StringRef Name = llvm::sys::path::stem(File->FileName);
+  StringRef Name = File->ModuleName;
   llvm::StringMap<unsigned>::iterator Known = UnresolvedModules.find(Name);
   if (Known == UnresolvedModules.end()) {
     return true;
@@ -341,6 +354,19 @@
   std::fprintf(stderr, "\n");
 }
 
+void GlobalModuleIndex::dump() {
+  llvm::errs() << "*** Global Module Index Dump:\n";
+  llvm::errs() << "Module files:\n";
+  for (auto &MI : Modules) {
+    llvm::errs() << "** " << MI.FileName << "\n";
+    if (MI.File)
+      MI.File->dump();
+    else
+      llvm::errs() << "\n";
+  }
+  llvm::errs() << "\n";
+}
+
 //----------------------------------------------------------------------------//
 // Global module index writer.
 //----------------------------------------------------------------------------//
@@ -411,7 +437,7 @@
   Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETBID, Record);
 
   // Emit the block name if present.
-  if (Name == 0 || Name[0] == 0) return;
+  if (!Name || Name[0] == 0) return;
   Record.clear();
   while (*Name)
     Record.push_back(*Name++);
@@ -458,8 +484,8 @@
                        unsigned DataLen) {
       // The first bit indicates whether this identifier is interesting.
       // That's all we care about.
-      using namespace clang::io;
-      unsigned RawID = ReadUnalignedLE32(d);
+      using namespace llvm::support;
+      unsigned RawID = endian::readNext<uint32_t, little, unaligned>(d);
       bool IsInteresting = RawID & 0x01;
       return std::make_pair(k, IsInteresting);
     }
@@ -468,7 +494,7 @@
 
 bool GlobalModuleIndexBuilder::loadModuleFile(const FileEntry *File) {
   // Open the module file.
-  OwningPtr<llvm::MemoryBuffer> Buffer;
+  std::unique_ptr<llvm::MemoryBuffer> Buffer;
   std::string ErrorStr;
   Buffer.reset(FileMgr.getBufferForFile(File, &ErrorStr, /*isVolatile=*/true));
   if (!Buffer) {
@@ -590,12 +616,13 @@
 
     // Handle the identifier table
     if (State == ASTBlock && Code == IDENTIFIER_TABLE && Record[0] > 0) {
-      typedef OnDiskChainedHashTable<InterestingASTIdentifierLookupTrait>
-        InterestingIdentifierTable;
-      llvm::OwningPtr<InterestingIdentifierTable>
-        Table(InterestingIdentifierTable::Create(
-                (const unsigned char *)Blob.data() + Record[0],
-                (const unsigned char *)Blob.data()));
+      typedef llvm::OnDiskIterableChainedHashTable<
+          InterestingASTIdentifierLookupTrait> InterestingIdentifierTable;
+      std::unique_ptr<InterestingIdentifierTable> Table(
+          InterestingIdentifierTable::Create(
+              (const unsigned char *)Blob.data() + Record[0],
+              (const unsigned char *)Blob.data() + sizeof(uint32_t),
+              (const unsigned char *)Blob.data()));
       for (InterestingIdentifierTable::data_iterator D = Table->data_begin(),
                                                      DEnd = Table->data_end();
            D != DEnd; ++D) {
@@ -623,17 +650,21 @@
   typedef StringRef key_type_ref;
   typedef SmallVector<unsigned, 2> data_type;
   typedef const SmallVector<unsigned, 2> &data_type_ref;
+  typedef unsigned hash_value_type;
+  typedef unsigned offset_type;
 
-  static unsigned ComputeHash(key_type_ref Key) {
+  static hash_value_type ComputeHash(key_type_ref Key) {
     return llvm::HashString(Key);
   }
 
   std::pair<unsigned,unsigned>
   EmitKeyDataLength(raw_ostream& Out, key_type_ref Key, data_type_ref Data) {
+    using namespace llvm::support;
+    endian::Writer<little> LE(Out);
     unsigned KeyLen = Key.size();
     unsigned DataLen = Data.size() * 4;
-    clang::io::Emit16(Out, KeyLen);
-    clang::io::Emit16(Out, DataLen);
+    LE.write<uint16_t>(KeyLen);
+    LE.write<uint16_t>(DataLen);
     return std::make_pair(KeyLen, DataLen);
   }
   
@@ -643,8 +674,9 @@
 
   void EmitData(raw_ostream& Out, key_type_ref Key, data_type_ref Data,
                 unsigned DataLen) {
+    using namespace llvm::support;
     for (unsigned I = 0, N = Data.size(); I != N; ++I)
-      clang::io::Emit32(Out, Data[I]);
+      endian::Writer<little>(Out).write<uint32_t>(Data[I]);
   }
 };
 
@@ -692,7 +724,7 @@
 
   // Write the identifier -> module file mapping.
   {
-    OnDiskChainedHashTableGenerator<IdentifierIndexWriterTrait> Generator;
+    llvm::OnDiskChainedHashTableGenerator<IdentifierIndexWriterTrait> Generator;
     IdentifierIndexWriterTrait Trait;
 
     // Populate the hash table.
@@ -706,9 +738,10 @@
     SmallString<4096> IdentifierTable;
     uint32_t BucketOffset;
     {
+      using namespace llvm::support;
       llvm::raw_svector_ostream Out(IdentifierTable);
       // Make sure that no bucket is at offset 0
-      clang::io::Emit32(Out, 0);
+      endian::Writer<little>(Out).write<uint32_t>(0);
       BucketOffset = Generator.Emit(Out, Trait);
     }
 
@@ -756,7 +789,7 @@
   GlobalModuleIndexBuilder Builder(FileMgr);
   
   // Load each of the module files.
-  llvm::error_code EC;
+  std::error_code EC;
   for (llvm::sys::fs::directory_iterator D(Path, EC), DEnd;
        D != DEnd && !EC;
        D.increment(EC)) {
@@ -807,13 +840,12 @@
     return EC_IOError;
 
   // Remove the old index file. It isn't relevant any more.
-  bool OldIndexExisted;
-  llvm::sys::fs::remove(IndexPath.str(), OldIndexExisted);
+  llvm::sys::fs::remove(IndexPath.str());
 
   // Rename the newly-written index file to the proper name.
   if (llvm::sys::fs::rename(IndexTmpPath.str(), IndexPath.str())) {
     // Rename failed; just remove the 
-    llvm::sys::fs::remove(IndexTmpPath.str(), OldIndexExisted);
+    llvm::sys::fs::remove(IndexTmpPath.str());
     return EC_IOError;
   }
 
@@ -835,7 +867,7 @@
       End = Idx.key_end();
     }
 
-    virtual StringRef Next() {
+    StringRef Next() override {
       if (Current == End)
         return StringRef();
 
diff --git a/lib/Serialization/Module.cpp b/lib/Serialization/Module.cpp
index 2eb3971..6f2a3c2 100644
--- a/lib/Serialization/Module.cpp
+++ b/lib/Serialization/Module.cpp
@@ -21,27 +21,27 @@
 using namespace reader;
 
 ModuleFile::ModuleFile(ModuleKind Kind, unsigned Generation)
-  : Kind(Kind), File(0), DirectlyImported(false),
+  : Kind(Kind), File(nullptr), DirectlyImported(false),
     Generation(Generation), SizeInBits(0),
     LocalNumSLocEntries(0), SLocEntryBaseID(0),
-    SLocEntryBaseOffset(0), SLocEntryOffsets(0),
+    SLocEntryBaseOffset(0), SLocEntryOffsets(nullptr),
     LocalNumIdentifiers(0),
-    IdentifierOffsets(0), BaseIdentifierID(0), IdentifierTableData(0),
-    IdentifierLookupTable(0),
-    LocalNumMacros(0), MacroOffsets(0),
+    IdentifierOffsets(nullptr), BaseIdentifierID(0),
+    IdentifierTableData(nullptr), IdentifierLookupTable(nullptr),
+    LocalNumMacros(0), MacroOffsets(nullptr),
     BasePreprocessedEntityID(0),
-    PreprocessedEntityOffsets(0), NumPreprocessedEntities(0),
+    PreprocessedEntityOffsets(nullptr), NumPreprocessedEntities(0),
     LocalNumHeaderFileInfos(0), 
-    HeaderFileInfoTableData(0), HeaderFileInfoTable(0),
+    HeaderFileInfoTableData(nullptr), HeaderFileInfoTable(nullptr),
     LocalNumSubmodules(0), BaseSubmoduleID(0),
-    LocalNumSelectors(0), SelectorOffsets(0), BaseSelectorID(0),
-    SelectorLookupTableData(0), SelectorLookupTable(0), LocalNumDecls(0),
-    DeclOffsets(0), BaseDeclID(0),
-    LocalNumCXXBaseSpecifiers(0), CXXBaseSpecifiersOffsets(0),
-    FileSortedDecls(0), NumFileSortedDecls(0),
-    RedeclarationsMap(0), LocalNumRedeclarationsInMap(0),
-    ObjCCategoriesMap(0), LocalNumObjCCategoriesInMap(0),
-    LocalNumTypes(0), TypeOffsets(0), BaseTypeIndex(0)
+    LocalNumSelectors(0), SelectorOffsets(nullptr), BaseSelectorID(0),
+    SelectorLookupTableData(nullptr), SelectorLookupTable(nullptr),
+    LocalNumDecls(0), DeclOffsets(nullptr), BaseDeclID(0),
+    LocalNumCXXBaseSpecifiers(0), CXXBaseSpecifiersOffsets(nullptr),
+    FileSortedDecls(nullptr), NumFileSortedDecls(0),
+    RedeclarationsMap(nullptr), LocalNumRedeclarationsInMap(0),
+    ObjCCategoriesMap(nullptr), LocalNumObjCCategoriesInMap(0),
+    LocalNumTypes(0), TypeOffsets(nullptr), BaseTypeIndex(0)
 {}
 
 ModuleFile::~ModuleFile() {
diff --git a/lib/Serialization/ModuleManager.cpp b/lib/Serialization/ModuleManager.cpp
index 9c4b3d9..2c10c11 100644
--- a/lib/Serialization/ModuleManager.cpp
+++ b/lib/Serialization/ModuleManager.cpp
@@ -11,13 +11,14 @@
 //  modules for the ASTReader.
 //
 //===----------------------------------------------------------------------===//
+#include "clang/Lex/HeaderSearch.h"
 #include "clang/Lex/ModuleMap.h"
 #include "clang/Serialization/GlobalModuleIndex.h"
 #include "clang/Serialization/ModuleManager.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/system_error.h"
+#include <system_error>
 
 #ifndef NDEBUG
 #include "llvm/Support/GraphWriter.h"
@@ -32,14 +33,14 @@
   if (Entry)
     return lookup(Entry);
 
-  return 0;
+  return nullptr;
 }
 
 ModuleFile *ModuleManager::lookup(const FileEntry *File) {
   llvm::DenseMap<const FileEntry *, ModuleFile *>::iterator Known
     = Modules.find(File);
   if (Known == Modules.end())
-    return 0;
+    return nullptr;
 
   return Known->second;
 }
@@ -57,7 +58,7 @@
                          off_t ExpectedSize, time_t ExpectedModTime,
                          ModuleFile *&Module,
                          std::string &ErrorStr) {
-  Module = 0;
+  Module = nullptr;
 
   // Look for the file entry. This only fails if the expected size or
   // modification time differ.
@@ -86,6 +87,16 @@
     NewModule = true;
     ModuleEntry = New;
 
+    New->InputFilesValidationTimestamp = 0;
+    if (New->Kind == MK_Module) {
+      std::string TimestampFilename = New->getTimestampFilename();
+      vfs::Status Status;
+      // A cached stat value would be fine as well.
+      if (!FileMgr.getNoncachedStatValue(TimestampFilename, Status))
+        New->InputFilesValidationTimestamp =
+            Status.getLastModificationTime().toEpochTime();
+    }
+
     // Load the contents of the module
     if (llvm::MemoryBuffer *Buffer = lookupBuffer(FileName)) {
       // The buffer was already provided for us.
@@ -93,13 +104,24 @@
       New->Buffer.reset(Buffer);
     } else {
       // Open the AST file.
-      llvm::error_code ec;
+      std::error_code ec;
       if (FileName == "-") {
-        ec = llvm::MemoryBuffer::getSTDIN(New->Buffer);
+        llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buf =
+            llvm::MemoryBuffer::getSTDIN();
+        ec = Buf.getError();
         if (ec)
           ErrorStr = ec.message();
-      } else
-        New->Buffer.reset(FileMgr.getBufferForFile(FileName, &ErrorStr));
+        else
+          New->Buffer = std::move(Buf.get());
+      } else {
+        // Leave the FileEntry open so if it gets read again by another
+        // ModuleManager it must be the same underlying file.
+        // FIXME: Because FileManager::getFile() doesn't guarantee that it will
+        // give us an open file, this may not be 100% reliable.
+        New->Buffer.reset(FileMgr.getBufferForFile(New->File, &ErrorStr,
+                                                   /*IsVolatile*/false,
+                                                   /*ShouldClose*/false));
+      }
       
       if (!New->Buffer)
         return Missing;
@@ -124,24 +146,10 @@
   return NewModule? NewlyLoaded : AlreadyLoaded;
 }
 
-namespace {
-  /// \brief Predicate that checks whether a module file occurs within
-  /// the given set.
-  class IsInModuleFileSet : public std::unary_function<ModuleFile *, bool> {
-    llvm::SmallPtrSet<ModuleFile *, 4> &Removed;
-
-  public:
-    IsInModuleFileSet(llvm::SmallPtrSet<ModuleFile *, 4> &Removed)
-    : Removed(Removed) { }
-
-    bool operator()(ModuleFile *MF) const {
-      return Removed.count(MF);
-    }
-  };
-}
-
-void ModuleManager::removeModules(ModuleIterator first, ModuleIterator last,
-                                  ModuleMap *modMap) {
+void ModuleManager::removeModules(
+    ModuleIterator first, ModuleIterator last,
+    llvm::SmallPtrSetImpl<ModuleFile *> &LoadedSuccessfully,
+    ModuleMap *modMap) {
   if (first == last)
     return;
 
@@ -149,22 +157,29 @@
   llvm::SmallPtrSet<ModuleFile *, 4> victimSet(first, last);
 
   // Remove any references to the now-destroyed modules.
-  IsInModuleFileSet checkInSet(victimSet);
   for (unsigned i = 0, n = Chain.size(); i != n; ++i) {
-    Chain[i]->ImportedBy.remove_if(checkInSet);
+    Chain[i]->ImportedBy.remove_if([&](ModuleFile *MF) {
+      return victimSet.count(MF);
+    });
   }
 
   // Delete the modules and erase them from the various structures.
   for (ModuleIterator victim = first; victim != last; ++victim) {
     Modules.erase((*victim)->File);
 
-    FileMgr.invalidateCache((*victim)->File);
     if (modMap) {
-      StringRef ModuleName = llvm::sys::path::stem((*victim)->FileName);
+      StringRef ModuleName = (*victim)->ModuleName;
       if (Module *mod = modMap->findModule(ModuleName)) {
-        mod->setASTFile(0);
+        mod->setASTFile(nullptr);
       }
     }
+
+    // Files that didn't make it through ReadASTCore successfully will be
+    // rebuilt (or there was an error). Invalidate them so that we can load the
+    // new files that will be renamed over the old ones.
+    if (LoadedSuccessfully.count(*victim) == 0)
+      FileMgr.invalidateCache((*victim)->File);
+
     delete *victim;
   }
 
@@ -185,7 +200,7 @@
   if (FirstVisitState) {
     VisitState *Result = FirstVisitState;
     FirstVisitState = FirstVisitState->NextState;
-    Result->NextState = 0;
+    Result->NextState = nullptr;
     return Result;
   }
 
@@ -194,7 +209,7 @@
 }
 
 void ModuleManager::returnVisitState(VisitState *State) {
-  assert(State->NextState == 0 && "Visited state is in list?");
+  assert(State->NextState == nullptr && "Visited state is in list?");
   State->NextState = FirstVisitState;
   FirstVisitState = State;
 }
@@ -223,7 +238,7 @@
 }
 
 ModuleManager::ModuleManager(FileManager &FileMgr)
-  : FileMgr(FileMgr), GlobalIndex(), FirstVisitState(0) { }
+  : FileMgr(FileMgr), GlobalIndex(), FirstVisitState(nullptr) {}
 
 ModuleManager::~ModuleManager() {
   for (unsigned i = 0, e = Chain.size(); i != e; ++i)
@@ -283,7 +298,7 @@
     assert(VisitOrder.size() == N && "Visitation order is wrong?");
 
     delete FirstVisitState;
-    FirstVisitState = 0;
+    FirstVisitState = nullptr;
   }
 
   VisitState *State = allocateVisitState();
@@ -385,16 +400,19 @@
                                      off_t ExpectedSize,
                                      time_t ExpectedModTime,
                                      const FileEntry *&File) {
-  File = FileMgr.getFile(FileName, /*openFile=*/false, /*cacheFailure=*/false);
+  // Open the file immediately to ensure there is no race between stat'ing and
+  // opening the file.
+  File = FileMgr.getFile(FileName, /*openFile=*/true, /*cacheFailure=*/false);
 
   if (!File && FileName != "-") {
     return false;
   }
 
   if ((ExpectedSize && ExpectedSize != File->getSize()) ||
-      (ExpectedModTime && ExpectedModTime != File->getModificationTime())) {
+      (ExpectedModTime && ExpectedModTime != File->getModificationTime()))
+    // Do not destroy File, as it may be referenced. If we need to rebuild it,
+    // it will be destroyed by removeModules.
     return true;
-  }
 
   return false;
 }
@@ -434,7 +452,7 @@
     }
 
     std::string getNodeLabel(ModuleFile *M, const ModuleManager&) {
-      return llvm::sys::path::stem(M->FileName);
+      return M->ModuleName;
     }
   };
 }
diff --git a/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp b/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp
index 9af0a5a..166471a 100644
--- a/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp
@@ -8,8 +8,6 @@
 //===----------------------------------------------------------------------===//
 // This file reports various statistics about analyzer visitation.
 //===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "StatsChecker"
-
 #include "ClangSACheckers.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/Basic/SourceManager.h"
@@ -26,6 +24,8 @@
 using namespace clang;
 using namespace ento;
 
+#define DEBUG_TYPE "StatsChecker"
+
 STATISTIC(NumBlocks,
           "The # of blocks in top level functions");
 STATISTIC(NumBlocksUnreachable,
@@ -41,7 +41,7 @@
 void AnalyzerStatsChecker::checkEndAnalysis(ExplodedGraph &G,
                                             BugReporter &B,
                                             ExprEngine &Eng) const {
-  const CFG *C  = 0;
+  const CFG *C = nullptr;
   const SourceManager &SM = B.getSourceManager();
   llvm::SmallPtrSet<const CFGBlock*, 256> reachable;
 
@@ -112,7 +112,7 @@
       << " | Empty WorkList: "
       << (Eng.hasEmptyWorkList() ? "yes" : "no");
 
-  B.EmitBasicReport(D, "Analyzer Statistics", "Internal Statistics",
+  B.EmitBasicReport(D, this, "Analyzer Statistics", "Internal Statistics",
                     output.str(), PathDiagnosticLocation(D, SM));
 
   // Emit warning for each block we bailed out on.
@@ -129,7 +129,7 @@
       outputI << "(" << NameOfRootFunction << ")" <<
                  ": The analyzer generated a sink at this point";
       B.EmitBasicReport(
-          D, "Sink Point", "Internal Statistics", outputI.str(),
+          D, this, "Sink Point", "Internal Statistics", outputI.str(),
           PathDiagnosticLocation::createBegin(CS->getStmt(), SM, LC));
     }
   }
diff --git a/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp b/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp
index 312bc74..cb5b010 100644
--- a/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp
@@ -25,7 +25,8 @@
 namespace {
 class ArrayBoundChecker : 
     public Checker<check::Location> {
-  mutable OwningPtr<BuiltinBug> BT;
+  mutable std::unique_ptr<BuiltinBug> BT;
+
 public:
   void checkLocation(SVal l, bool isLoad, const Stmt* S,
                      CheckerContext &C) const;
@@ -66,8 +67,9 @@
       return;
   
     if (!BT)
-      BT.reset(new BuiltinBug("Out-of-bound array access",
-                       "Access out-of-bound array element (buffer overflow)"));
+      BT.reset(new BuiltinBug(
+          this, "Out-of-bound array access",
+          "Access out-of-bound array element (buffer overflow)"));
 
     // FIXME: It would be nice to eventually make this diagnostic more clear,
     // e.g., by referencing the original declaration or by saying *why* this
diff --git a/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp b/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
index 5e4b824..20360ef 100644
--- a/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
+++ b/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
@@ -28,8 +28,8 @@
 namespace {
 class ArrayBoundCheckerV2 : 
     public Checker<check::Location> {
-  mutable OwningPtr<BuiltinBug> BT;
-      
+  mutable std::unique_ptr<BuiltinBug> BT;
+
   enum OOB_Kind { OOB_Precedes, OOB_Excedes, OOB_Tainted };
   
   void reportOOB(CheckerContext &C, ProgramStateRef errorState,
@@ -45,9 +45,9 @@
 private:
   const SubRegion *baseRegion;
   SVal byteOffset;
-  
+
   RegionRawOffsetV2()
-    : baseRegion(0), byteOffset(UnknownVal()) {}
+    : baseRegion(nullptr), byteOffset(UnknownVal()) {}
 
 public:
   RegionRawOffsetV2(const SubRegion* base, SVal offset)
@@ -120,7 +120,7 @@
       return;
     
     ProgramStateRef state_precedesLowerBound, state_withinLowerBound;
-    llvm::tie(state_precedesLowerBound, state_withinLowerBound) =
+    std::tie(state_precedesLowerBound, state_withinLowerBound) =
       state->assume(*lowerBoundToCheck);
 
     // Are we constrained enough to definitely precede the lower bound?
@@ -152,7 +152,7 @@
       break;
   
     ProgramStateRef state_exceedsUpperBound, state_withinUpperBound;
-    llvm::tie(state_exceedsUpperBound, state_withinUpperBound) =
+    std::tie(state_exceedsUpperBound, state_withinUpperBound) =
       state->assume(*upperboundToCheck);
 
     // If we are under constrained and the index variables are tainted, report.
@@ -187,7 +187,7 @@
     return;
 
   if (!BT)
-    BT.reset(new BuiltinBug("Out-of-bound access"));
+    BT.reset(new BuiltinBug(this, "Out-of-bound access"));
 
   // FIXME: This diagnostics are preliminary.  We should get far better
   // diagnostics for explaining buffer overruns.
@@ -311,7 +311,6 @@
   return RegionRawOffsetV2();
 }
 
-
 void ento::registerArrayBoundCheckerV2(CheckerManager &mgr) {
   mgr.registerChecker<ArrayBoundCheckerV2>();
 }
diff --git a/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp b/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
index f66f8b7..3fd5576 100644
--- a/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
+++ b/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
@@ -14,6 +14,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "ClangSACheckers.h"
+#include "SelectorExtras.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/Expr.h"
@@ -39,7 +40,8 @@
 namespace {
 class APIMisuse : public BugType {
 public:
-  APIMisuse(const char* name) : BugType(name, "API Misuse (Apple)") {}
+  APIMisuse(const CheckerBase *checker, const char *name)
+      : BugType(checker, name, "API Misuse (Apple)") {}
 };
 } // end anonymous namespace
 
@@ -94,7 +96,19 @@
   class NilArgChecker : public Checker<check::PreObjCMessage,
                                        check::PostStmt<ObjCDictionaryLiteral>,
                                        check::PostStmt<ObjCArrayLiteral> > {
-    mutable OwningPtr<APIMisuse> BT;
+    mutable std::unique_ptr<APIMisuse> BT;
+
+    mutable llvm::SmallDenseMap<Selector, unsigned, 16> StringSelectors;
+    mutable Selector ArrayWithObjectSel;
+    mutable Selector AddObjectSel;
+    mutable Selector InsertObjectAtIndexSel;
+    mutable Selector ReplaceObjectAtIndexWithObjectSel;
+    mutable Selector SetObjectAtIndexedSubscriptSel;
+    mutable Selector ArrayByAddingObjectSel;
+    mutable Selector DictionaryWithObjectForKeySel;
+    mutable Selector SetObjectForKeySel;
+    mutable Selector SetObjectForKeyedSubscriptSel;
+    mutable Selector RemoveObjectForKeySel;
 
     void warnIfNilExpr(const Expr *E,
                        const char *Msg,
@@ -170,10 +184,13 @@
           assert(Arg == 1);
           os << "Key argument ";
         }
-        os << "to '" << msg.getSelector().getAsString() << "' cannot be nil";
+        os << "to '";
+        msg.getSelector().print(os);
+        os << "' cannot be nil";
       } else {
-        os << "Argument to '" << GetReceiverInterfaceName(msg) << "' method '"
-        << msg.getSelector().getAsString() << "' cannot be nil";
+        os << "Argument to '" << GetReceiverInterfaceName(msg) << "' method '";
+        msg.getSelector().print(os);
+        os << "' cannot be nil";
       }
     }
     
@@ -188,7 +205,7 @@
                                       const Expr *E,
                                       CheckerContext &C) const {
   if (!BT)
-    BT.reset(new APIMisuse("nil argument"));
+    BT.reset(new APIMisuse(this, "nil argument"));
 
   BugReport *R = new BugReport(*BT, Msg, N);
   R->addRange(Range);
@@ -210,50 +227,62 @@
   
   if (Class == FC_NSString) {
     Selector S = msg.getSelector();
-    
+
     if (S.isUnarySelector())
       return;
-    
-    // FIXME: This is going to be really slow doing these checks with
-    //  lexical comparisons.
-    
-    std::string NameStr = S.getAsString();
-    StringRef Name(NameStr);
-    assert(!Name.empty());
-    
-    // FIXME: Checking for initWithFormat: will not work in most cases
-    //  yet because [NSString alloc] returns id, not NSString*.  We will
-    //  need support for tracking expected-type information in the analyzer
-    //  to find these errors.
-    if (Name == "caseInsensitiveCompare:" ||
-        Name == "compare:" ||
-        Name == "compare:options:" ||
-        Name == "compare:options:range:" ||
-        Name == "compare:options:range:locale:" ||
-        Name == "componentsSeparatedByCharactersInSet:" ||
-        Name == "initWithFormat:") {
-      Arg = 0;
+
+    if (StringSelectors.empty()) {
+      ASTContext &Ctx = C.getASTContext();
+      Selector Sels[] = {
+        getKeywordSelector(Ctx, "caseInsensitiveCompare", nullptr),
+        getKeywordSelector(Ctx, "compare", nullptr),
+        getKeywordSelector(Ctx, "compare", "options", nullptr),
+        getKeywordSelector(Ctx, "compare", "options", "range", nullptr),
+        getKeywordSelector(Ctx, "compare", "options", "range", "locale",
+                           nullptr),
+        getKeywordSelector(Ctx, "componentsSeparatedByCharactersInSet",
+                           nullptr),
+        getKeywordSelector(Ctx, "initWithFormat",
+                           nullptr),
+        getKeywordSelector(Ctx, "localizedCaseInsensitiveCompare", nullptr),
+        getKeywordSelector(Ctx, "localizedCompare", nullptr),
+        getKeywordSelector(Ctx, "localizedStandardCompare", nullptr),
+      };
+      for (Selector KnownSel : Sels)
+        StringSelectors[KnownSel] = 0;
     }
+    auto I = StringSelectors.find(S);
+    if (I == StringSelectors.end())
+      return;
+    Arg = I->second;
   } else if (Class == FC_NSArray) {
     Selector S = msg.getSelector();
 
     if (S.isUnarySelector())
       return;
 
-    if (S.getNameForSlot(0).equals("addObject")) {
+    if (ArrayWithObjectSel.isNull()) {
+      ASTContext &Ctx = C.getASTContext();
+      ArrayWithObjectSel = getKeywordSelector(Ctx, "arrayWithObject", nullptr);
+      AddObjectSel = getKeywordSelector(Ctx, "addObject", nullptr);
+      InsertObjectAtIndexSel =
+        getKeywordSelector(Ctx, "insertObject", "atIndex", nullptr);
+      ReplaceObjectAtIndexWithObjectSel =
+        getKeywordSelector(Ctx, "replaceObjectAtIndex", "withObject", nullptr);
+      SetObjectAtIndexedSubscriptSel =
+        getKeywordSelector(Ctx, "setObject", "atIndexedSubscript", nullptr);
+      ArrayByAddingObjectSel =
+        getKeywordSelector(Ctx, "arrayByAddingObject", nullptr);
+    }
+
+    if (S == ArrayWithObjectSel || S == AddObjectSel ||
+        S == InsertObjectAtIndexSel || S == ArrayByAddingObjectSel) {
       Arg = 0;
-    } else if (S.getNameForSlot(0).equals("insertObject") &&
-               S.getNameForSlot(1).equals("atIndex")) {
-      Arg = 0;
-    } else if (S.getNameForSlot(0).equals("replaceObjectAtIndex") &&
-               S.getNameForSlot(1).equals("withObject")) {
-      Arg = 1;
-    } else if (S.getNameForSlot(0).equals("setObject") &&
-               S.getNameForSlot(1).equals("atIndexedSubscript")) {
+    } else if (S == SetObjectAtIndexedSubscriptSel) {
       Arg = 0;
       CanBeSubscript = true;
-    } else if (S.getNameForSlot(0).equals("arrayByAddingObject")) {
-      Arg = 0;
+    } else if (S == ReplaceObjectAtIndexWithObjectSel) {
+      Arg = 1;
     }
   } else if (Class == FC_NSDictionary) {
     Selector S = msg.getSelector();
@@ -261,20 +290,26 @@
     if (S.isUnarySelector())
       return;
 
-    if (S.getNameForSlot(0).equals("dictionaryWithObject") &&
-        S.getNameForSlot(1).equals("forKey")) {
+    if (DictionaryWithObjectForKeySel.isNull()) {
+      ASTContext &Ctx = C.getASTContext();
+      DictionaryWithObjectForKeySel =
+        getKeywordSelector(Ctx, "dictionaryWithObject", "forKey", nullptr);
+      SetObjectForKeySel =
+        getKeywordSelector(Ctx, "setObject", "forKey", nullptr);
+      SetObjectForKeyedSubscriptSel =
+        getKeywordSelector(Ctx, "setObject", "forKeyedSubscript", nullptr);
+      RemoveObjectForKeySel =
+        getKeywordSelector(Ctx, "removeObjectForKey", nullptr);
+    }
+
+    if (S == DictionaryWithObjectForKeySel || S == SetObjectForKeySel) {
       Arg = 0;
       warnIfNilArg(C, msg, /* Arg */1, Class);
-    } else if (S.getNameForSlot(0).equals("setObject") &&
-               S.getNameForSlot(1).equals("forKey")) {
-      Arg = 0;
-      warnIfNilArg(C, msg, /* Arg */1, Class);
-    } else if (S.getNameForSlot(0).equals("setObject") &&
-               S.getNameForSlot(1).equals("forKeyedSubscript")) {
+    } else if (S == SetObjectForKeyedSubscriptSel) {
       CanBeSubscript = true;
       Arg = 0;
       warnIfNilArg(C, msg, /* Arg */1, Class, CanBeSubscript);
-    } else if (S.getNameForSlot(0).equals("removeObjectForKey")) {
+    } else if (S == RemoveObjectForKeySel) {
       Arg = 0;
     }
   }
@@ -282,7 +317,6 @@
   // If argument is '0', report a warning.
   if ((Arg != InvalidArgIndex))
     warnIfNilArg(C, msg, Arg, Class, CanBeSubscript);
-
 }
 
 void NilArgChecker::checkPostStmt(const ObjCArrayLiteral *AL,
@@ -309,10 +343,10 @@
 
 namespace {
 class CFNumberCreateChecker : public Checker< check::PreStmt<CallExpr> > {
-  mutable OwningPtr<APIMisuse> BT;
+  mutable std::unique_ptr<APIMisuse> BT;
   mutable IdentifierInfo* II;
 public:
-  CFNumberCreateChecker() : II(0) {}
+  CFNumberCreateChecker() : II(nullptr) {}
 
   void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
 
@@ -480,8 +514,8 @@
       << " bits of the input integer will be lost.";
 
     if (!BT)
-      BT.reset(new APIMisuse("Bad use of CFNumberCreate"));
-    
+      BT.reset(new APIMisuse(this, "Bad use of CFNumberCreate"));
+
     BugReport *report = new BugReport(*BT, os.str(), N);
     report->addRange(CE->getArg(2)->getSourceRange());
     C.emitReport(report);
@@ -489,15 +523,17 @@
 }
 
 //===----------------------------------------------------------------------===//
-// CFRetain/CFRelease/CFMakeCollectable checking for null arguments.
+// CFRetain/CFRelease/CFMakeCollectable/CFAutorelease checking for null arguments.
 //===----------------------------------------------------------------------===//
 
 namespace {
 class CFRetainReleaseChecker : public Checker< check::PreStmt<CallExpr> > {
-  mutable OwningPtr<APIMisuse> BT;
-  mutable IdentifierInfo *Retain, *Release, *MakeCollectable;
+  mutable std::unique_ptr<APIMisuse> BT;
+  mutable IdentifierInfo *Retain, *Release, *MakeCollectable, *Autorelease;
 public:
-  CFRetainReleaseChecker(): Retain(0), Release(0), MakeCollectable(0) {}
+  CFRetainReleaseChecker()
+      : Retain(nullptr), Release(nullptr), MakeCollectable(nullptr),
+        Autorelease(nullptr) {}
   void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
 };
 } // end anonymous namespace
@@ -519,13 +555,15 @@
     Retain = &Ctx.Idents.get("CFRetain");
     Release = &Ctx.Idents.get("CFRelease");
     MakeCollectable = &Ctx.Idents.get("CFMakeCollectable");
-    BT.reset(
-      new APIMisuse("null passed to CFRetain/CFRelease/CFMakeCollectable"));
+    Autorelease = &Ctx.Idents.get("CFAutorelease");
+    BT.reset(new APIMisuse(
+        this, "null passed to CF memory management function"));
   }
 
-  // Check if we called CFRetain/CFRelease/CFMakeCollectable.
+  // Check if we called CFRetain/CFRelease/CFMakeCollectable/CFAutorelease.
   const IdentifierInfo *FuncII = FD->getIdentifier();
-  if (!(FuncII == Retain || FuncII == Release || FuncII == MakeCollectable))
+  if (!(FuncII == Retain || FuncII == Release || FuncII == MakeCollectable ||
+        FuncII == Autorelease))
     return;
 
   // FIXME: The rest of this just checks that the argument is non-null.
@@ -548,7 +586,7 @@
 
   // Are they equal?
   ProgramStateRef stateTrue, stateFalse;
-  llvm::tie(stateTrue, stateFalse) = state->assume(ArgIsNull);
+  std::tie(stateTrue, stateFalse) = state->assume(ArgIsNull);
 
   if (stateTrue && !stateFalse) {
     ExplodedNode *N = C.generateSink(stateTrue);
@@ -562,6 +600,8 @@
       description = "Null pointer argument in call to CFRelease";
     else if (FuncII == MakeCollectable)
       description = "Null pointer argument in call to CFMakeCollectable";
+    else if (FuncII == Autorelease)
+      description = "Null pointer argument in call to CFAutorelease";
     else
       llvm_unreachable("impossible case");
 
@@ -586,7 +626,7 @@
   mutable Selector retainS;
   mutable Selector autoreleaseS;
   mutable Selector drainS;
-  mutable OwningPtr<BugType> BT;
+  mutable std::unique_ptr<BugType> BT;
 
 public:
   void checkPreObjCMessage(const ObjCMethodCall &msg, CheckerContext &C) const;
@@ -597,9 +637,9 @@
                                               CheckerContext &C) const {
   
   if (!BT) {
-    BT.reset(new APIMisuse("message incorrectly sent to class instead of class "
-                           "instance"));
-  
+    BT.reset(new APIMisuse(
+        this, "message incorrectly sent to class instead of class instance"));
+
     ASTContext &Ctx = C.getASTContext();
     releaseS = GetNullarySelector("release", Ctx);
     retainS = GetNullarySelector("retain", Ctx);
@@ -620,7 +660,9 @@
     SmallString<200> buf;
     llvm::raw_svector_ostream os(buf);
 
-    os << "The '" << S.getAsString() << "' message should be sent to instances "
+    os << "The '";
+    S.print(os);
+    os << "' message should be sent to instances "
           "of class '" << Class->getName()
        << "' and not the class directly";
   
@@ -643,7 +685,7 @@
   mutable Selector orderedSetWithObjectsS;
   mutable Selector initWithObjectsS;
   mutable Selector initWithObjectsAndKeysS;
-  mutable OwningPtr<BugType> BT;
+  mutable std::unique_ptr<BugType> BT;
 
   bool isVariadicMessage(const ObjCMethodCall &msg) const;
 
@@ -703,7 +745,8 @@
 void VariadicMethodTypeChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
                                                     CheckerContext &C) const {
   if (!BT) {
-    BT.reset(new APIMisuse("Arguments passed to variadic method aren't all "
+    BT.reset(new APIMisuse(this,
+                           "Arguments passed to variadic method aren't all "
                            "Objective-C pointer types"));
 
     ASTContext &Ctx = C.getASTContext();
@@ -733,8 +776,7 @@
 
   // Verify that all arguments have Objective-C types.
   Optional<ExplodedNode*> errorNode;
-  ProgramStateRef state = C.getState();
-  
+
   for (unsigned I = variadicArgsBegin; I != variadicArgsEnd; ++I) {
     QualType ArgTy = msg.getArgExpr(I)->getType();
     if (ArgTy->isObjCObjectPointerType())
@@ -772,8 +814,8 @@
     else
       os << "Argument to method '";
 
-    os << msg.getSelector().getAsString() 
-       << "' should be an Objective-C pointer type, not '";
+    msg.getSelector().print(os);
+    os << "' should be an Objective-C pointer type, not '";
     ArgTy.print(os, C.getLangOpts());
     os << "'";
 
@@ -804,7 +846,7 @@
                                CheckerContext &C) const;
 
 public:
-  ObjCLoopChecker() : CountSelectorII(0) {}
+  ObjCLoopChecker() : CountSelectorII(nullptr) {}
   void checkPostStmt(const ObjCForCollectionStmt *FCS, CheckerContext &C) const;
   void checkPostObjCMessage(const ObjCMethodCall &M, CheckerContext &C) const;
   void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
@@ -844,7 +886,7 @@
                                              ProgramStateRef State,
                                              const ObjCForCollectionStmt *FCS) {
   if (!State)
-    return NULL;
+    return nullptr;
 
   SVal CollectionVal = C.getSVal(FCS->getCollection());
   Optional<DefinedSVal> KnownCollection = CollectionVal.getAs<DefinedSVal>();
@@ -852,10 +894,10 @@
     return State;
 
   ProgramStateRef StNonNil, StNil;
-  llvm::tie(StNonNil, StNil) = State->assume(*KnownCollection);
+  std::tie(StNonNil, StNil) = State->assume(*KnownCollection);
   if (StNil && !StNonNil) {
     // The collection is nil. This path is infeasible.
-    return NULL;
+    return nullptr;
   }
 
   return StNonNil;
@@ -869,7 +911,7 @@
                                           ProgramStateRef State,
                                           const ObjCForCollectionStmt *FCS) {
   if (!State)
-    return NULL;
+    return nullptr;
 
   // See if the collection is one where we /know/ the elements are non-nil.
   if (!isKnownNonNilCollectionType(FCS->getCollection()->getType()))
@@ -882,7 +924,7 @@
   Optional<Loc> ElementLoc;
   if (const DeclStmt *DS = dyn_cast<DeclStmt>(Element)) {
     const VarDecl *ElemDecl = cast<VarDecl>(DS->getSingleDecl());
-    assert(ElemDecl->getInit() == 0);
+    assert(ElemDecl->getInit() == nullptr);
     ElementLoc = State->getLValue(ElemDecl, LCtx);
   } else {
     ElementLoc = State->getSVal(Element, LCtx).getAs<Loc>();
@@ -909,7 +951,7 @@
     const bool *KnownNonEmpty = State->get<ContainerNonEmptyMap>(CollectionS);
     if (!KnownNonEmpty)
       return State->set<ContainerNonEmptyMap>(CollectionS, Assumption);
-    return (Assumption == *KnownNonEmpty) ? State : NULL;
+    return (Assumption == *KnownNonEmpty) ? State : nullptr;
   }
 
   SValBuilder &SvalBuilder = C.getSValBuilder();
@@ -934,7 +976,7 @@
                          const ObjCForCollectionStmt *FCS,
                          bool Assumption) {
   if (!State)
-    return NULL;
+    return nullptr;
 
   SymbolRef CollectionS =
     State->getSVal(FCS->getCollection(), C.getLocationContext()).getAsSymbol();
@@ -1049,11 +1091,11 @@
 static SymbolRef getMethodReceiverIfKnownImmutable(const CallEvent *Call) {
   const ObjCMethodCall *Message = dyn_cast_or_null<ObjCMethodCall>(Call);
   if (!Message)
-    return 0;
+    return nullptr;
 
   const ObjCMethodDecl *MD = Message->getDecl();
   if (!MD)
-    return 0;
+    return nullptr;
 
   const ObjCInterfaceDecl *StaticClass;
   if (isa<ObjCProtocolDecl>(MD->getDeclContext())) {
@@ -1066,11 +1108,11 @@
   }
 
   if (!StaticClass)
-    return 0;
+    return nullptr;
 
   switch (findKnownClass(StaticClass, /*IncludeSuper=*/false)) {
   case FC_None:
-    return 0;
+    return nullptr;
   case FC_NSArray:
   case FC_NSDictionary:
   case FC_NSEnumerator:
@@ -1135,7 +1177,10 @@
 /// \brief The checker restricts the return values of APIs known to
 /// never (or almost never) return 'nil'.
 class ObjCNonNilReturnValueChecker
-  : public Checker<check::PostObjCMessage> {
+  : public Checker<check::PostObjCMessage,
+                   check::PostStmt<ObjCArrayLiteral>,
+                   check::PostStmt<ObjCDictionaryLiteral>,
+                   check::PostStmt<ObjCBoxedExpr> > {
     mutable bool Initialized;
     mutable Selector ObjectAtIndex;
     mutable Selector ObjectAtIndexedSubscript;
@@ -1143,13 +1188,32 @@
 
 public:
   ObjCNonNilReturnValueChecker() : Initialized(false) {}
+
+  ProgramStateRef assumeExprIsNonNull(const Expr *NonNullExpr,
+                                      ProgramStateRef State,
+                                      CheckerContext &C) const;
+  void assumeExprIsNonNull(const Expr *E, CheckerContext &C) const {
+    C.addTransition(assumeExprIsNonNull(E, C.getState(), C));
+  }
+
+  void checkPostStmt(const ObjCArrayLiteral *E, CheckerContext &C) const {
+    assumeExprIsNonNull(E, C);
+  }
+  void checkPostStmt(const ObjCDictionaryLiteral *E, CheckerContext &C) const {
+    assumeExprIsNonNull(E, C);
+  }
+  void checkPostStmt(const ObjCBoxedExpr *E, CheckerContext &C) const {
+    assumeExprIsNonNull(E, C);
+  }
+
   void checkPostObjCMessage(const ObjCMethodCall &M, CheckerContext &C) const;
 };
 }
 
-static ProgramStateRef assumeExprIsNonNull(const Expr *NonNullExpr,
-                                           ProgramStateRef State,
-                                           CheckerContext &C) {
+ProgramStateRef
+ObjCNonNilReturnValueChecker::assumeExprIsNonNull(const Expr *NonNullExpr,
+                                                  ProgramStateRef State,
+                                                  CheckerContext &C) const {
   SVal Val = State->getSVal(NonNullExpr, C.getLocationContext());
   if (Optional<DefinedOrUnknownSVal> DV = Val.getAs<DefinedOrUnknownSVal>())
     return State->assume(*DV, true);
@@ -1237,6 +1301,7 @@
   mgr.registerChecker<ObjCLoopChecker>();
 }
 
-void ento::registerObjCNonNilReturnValueChecker(CheckerManager &mgr) {
+void
+ento::registerObjCNonNilReturnValueChecker(CheckerManager &mgr) {
   mgr.registerChecker<ObjCNonNilReturnValueChecker>();
 }
diff --git a/lib/StaticAnalyzer/Checkers/BoolAssignmentChecker.cpp b/lib/StaticAnalyzer/Checkers/BoolAssignmentChecker.cpp
index 5169244..83a37c9 100644
--- a/lib/StaticAnalyzer/Checkers/BoolAssignmentChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/BoolAssignmentChecker.cpp
@@ -23,7 +23,7 @@
 
 namespace {
   class BoolAssignmentChecker : public Checker< check::Bind > {
-    mutable OwningPtr<BuiltinBug> BT;
+    mutable std::unique_ptr<BuiltinBug> BT;
     void emitReport(ProgramStateRef state, CheckerContext &C) const;
   public:
     void checkBind(SVal loc, SVal val, const Stmt *S, CheckerContext &C) const;
@@ -34,7 +34,7 @@
                                        CheckerContext &C) const {
   if (ExplodedNode *N = C.addTransition(state)) {
     if (!BT)
-      BT.reset(new BuiltinBug("Assignment of a non-Boolean value"));    
+      BT.reset(new BuiltinBug(this, "Assignment of a non-Boolean value"));
     C.emitReport(new BugReport(*BT, BT->getDescription(), N));
   }
 }
@@ -96,7 +96,7 @@
   }
   
   ProgramStateRef stateLT, stateGE;
-  llvm::tie(stateGE, stateLT) = CM.assumeDual(state, *greaterThanEqualToZero);
+  std::tie(stateGE, stateLT) = CM.assumeDual(state, *greaterThanEqualToZero);
   
   // Is it possible for the value to be less than zero?
   if (stateLT) {
@@ -132,7 +132,7 @@
   }
   
   ProgramStateRef stateGT, stateLE;
-  llvm::tie(stateLE, stateGT) = CM.assumeDual(state, *lessThanEqToOne);
+  std::tie(stateLE, stateGT) = CM.assumeDual(state, *lessThanEqToOne);
   
   // Is it possible for the value to be greater than one?
   if (stateGT) {
diff --git a/lib/StaticAnalyzer/Checkers/CMakeLists.txt b/lib/StaticAnalyzer/Checkers/CMakeLists.txt
index ebd3377..9fb22ec 100644
--- a/lib/StaticAnalyzer/Checkers/CMakeLists.txt
+++ b/lib/StaticAnalyzer/Checkers/CMakeLists.txt
@@ -3,6 +3,10 @@
   SOURCE Checkers.td
   TARGET ClangSACheckers)
 
+set(LLVM_LINK_COMPONENTS
+  Support
+  )
+
 add_clang_library(clangStaticAnalyzerCheckers
   AllocationDiagnostics.cpp
   AnalyzerStatsChecker.cpp
@@ -32,7 +36,6 @@
   ExprInspectionChecker.cpp
   FixedAddressChecker.cpp
   GenericTaintChecker.cpp
-  IdempotentOperationChecker.cpp
   IdenticalExprChecker.cpp
   IvarInvalidationChecker.cpp
   LLVMConventionsChecker.cpp
@@ -61,6 +64,7 @@
   StackAddrEscapeChecker.cpp
   StreamChecker.cpp
   TaintTesterChecker.cpp
+  TestAfterDivZeroChecker.cpp
   TraversalChecker.cpp
   UndefBranchChecker.cpp
   UndefCapturedBlockVarChecker.cpp
@@ -71,21 +75,13 @@
   UnreachableCodeChecker.cpp
   VLASizeChecker.cpp
   VirtualCallChecker.cpp
-  )
 
-add_dependencies(clangStaticAnalyzerCheckers
-  clangStaticAnalyzerCore
-  ClangAttrClasses
-  ClangAttrList
-  ClangCommentNodes
-  ClangDeclNodes
-  ClangDiagnosticCommon
-  ClangStmtNodes
+  DEPENDS
   ClangSACheckers
-  )
 
-target_link_libraries(clangStaticAnalyzerCheckers
-  clangBasic
+  LINK_LIBS
   clangAST
+  clangAnalysis
+  clangBasic
   clangStaticAnalyzerCore
   )
diff --git a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
index c3736d7..0693bd6 100644
--- a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
@@ -35,11 +35,8 @@
                                          check::DeadSymbols,
                                          check::RegionChanges
                                          > {
-  mutable OwningPtr<BugType> BT_Null,
-                             BT_Bounds,
-                             BT_Overlap,
-                             BT_NotCString,
-                             BT_AdditionOverflow;
+  mutable std::unique_ptr<BugType> BT_Null, BT_Bounds, BT_Overlap,
+      BT_NotCString, BT_AdditionOverflow;
 
   mutable const char *CurrentFunctionDescription;
 
@@ -51,6 +48,11 @@
     DefaultBool CheckCStringOutOfBounds;
     DefaultBool CheckCStringBufferOverlap;
     DefaultBool CheckCStringNotNullTerm;
+
+    CheckName CheckNameCStringNullArg;
+    CheckName CheckNameCStringOutOfBounds;
+    CheckName CheckNameCStringBufferOverlap;
+    CheckName CheckNameCStringNotNullTerm;
   };
 
   CStringChecksFilter Filter;
@@ -157,24 +159,24 @@
                                     ProgramStateRef state,
                                     const Expr *S,
                                     SVal l,
-                                    const char *message = NULL) const;
+                                    const char *message = nullptr) const;
   ProgramStateRef CheckBufferAccess(CheckerContext &C,
                                         ProgramStateRef state,
                                         const Expr *Size,
                                         const Expr *FirstBuf,
                                         const Expr *SecondBuf,
-                                        const char *firstMessage = NULL,
-                                        const char *secondMessage = NULL,
+                                        const char *firstMessage = nullptr,
+                                        const char *secondMessage = nullptr,
                                         bool WarnAboutSize = false) const;
 
   ProgramStateRef CheckBufferAccess(CheckerContext &C,
                                         ProgramStateRef state,
                                         const Expr *Size,
                                         const Expr *Buf,
-                                        const char *message = NULL,
+                                        const char *message = nullptr,
                                         bool WarnAboutSize = false) const {
     // This is a convenience override.
-    return CheckBufferAccess(C, state, Size, Buf, NULL, message, NULL,
+    return CheckBufferAccess(C, state, Size, Buf, nullptr, message, nullptr,
                              WarnAboutSize);
   }
   ProgramStateRef CheckOverlap(CheckerContext &C,
@@ -218,22 +220,23 @@
                                             const Expr *S, SVal l) const {
   // If a previous check has failed, propagate the failure.
   if (!state)
-    return NULL;
+    return nullptr;
 
   ProgramStateRef stateNull, stateNonNull;
-  llvm::tie(stateNull, stateNonNull) = assumeZero(C, state, l, S->getType());
+  std::tie(stateNull, stateNonNull) = assumeZero(C, state, l, S->getType());
 
   if (stateNull && !stateNonNull) {
     if (!Filter.CheckCStringNullArg)
-      return NULL;
+      return nullptr;
 
     ExplodedNode *N = C.generateSink(stateNull);
     if (!N)
-      return NULL;
+      return nullptr;
 
     if (!BT_Null)
-      BT_Null.reset(new BuiltinBug(categories::UnixAPI,
-        "Null pointer argument in call to byte string function"));
+      BT_Null.reset(new BuiltinBug(
+          Filter.CheckNameCStringNullArg, categories::UnixAPI,
+          "Null pointer argument in call to byte string function"));
 
     SmallString<80> buf;
     llvm::raw_svector_ostream os(buf);
@@ -247,7 +250,7 @@
     report->addRange(S->getSourceRange());
     bugreporter::trackNullOrUndefValue(N, S, *report);
     C.emitReport(report);
-    return NULL;
+    return nullptr;
   }
 
   // From here on, assume that the value is non-null.
@@ -262,7 +265,7 @@
                                              const char *warningMsg) const {
   // If a previous check has failed, propagate the failure.
   if (!state)
-    return NULL;
+    return nullptr;
 
   // Check for out of bound array element access.
   const MemRegion *R = l.getAsRegion();
@@ -291,11 +294,12 @@
   if (StOutBound && !StInBound) {
     ExplodedNode *N = C.generateSink(StOutBound);
     if (!N)
-      return NULL;
+      return nullptr;
 
     if (!BT_Bounds) {
-      BT_Bounds.reset(new BuiltinBug("Out-of-bound array access",
-        "Byte string function accesses out-of-bound array element"));
+      BT_Bounds.reset(new BuiltinBug(
+          Filter.CheckNameCStringOutOfBounds, "Out-of-bound array access",
+          "Byte string function accesses out-of-bound array element"));
     }
     BuiltinBug *BT = static_cast<BuiltinBug*>(BT_Bounds.get());
 
@@ -321,7 +325,7 @@
 
     report->addRange(S->getSourceRange());
     C.emitReport(report);
-    return NULL;
+    return nullptr;
   }
   
   // Array bound check succeeded.  From this point forward the array bound
@@ -339,7 +343,7 @@
                                                  bool WarnAboutSize) const {
   // If a previous check has failed, propagate the failure.
   if (!state)
-    return NULL;
+    return nullptr;
 
   SValBuilder &svalBuilder = C.getSValBuilder();
   ASTContext &Ctx = svalBuilder.getContext();
@@ -352,7 +356,7 @@
   SVal BufVal = state->getSVal(FirstBuf, LCtx);
   state = checkNonNull(C, state, FirstBuf, BufVal);
   if (!state)
-    return NULL;
+    return nullptr;
 
   // If out-of-bounds checking is turned off, skip the rest.
   if (!Filter.CheckCStringOutOfBounds)
@@ -382,7 +386,7 @@
 
     // If the buffer isn't large enough, abort.
     if (!state)
-      return NULL;
+      return nullptr;
   }
 
   // If there's a second buffer, check it as well.
@@ -390,7 +394,7 @@
     BufVal = state->getSVal(SecondBuf, LCtx);
     state = checkNonNull(C, state, SecondBuf, BufVal);
     if (!state)
-      return NULL;
+      return nullptr;
 
     BufStart = svalBuilder.evalCast(BufVal, PtrTy, SecondBuf->getType());
     if (Optional<Loc> BufLoc = BufStart.getAs<Loc>()) {
@@ -420,7 +424,7 @@
 
   // If a previous check has failed, propagate the failure.
   if (!state)
-    return NULL;
+    return nullptr;
 
   ProgramStateRef stateTrue, stateFalse;
 
@@ -439,13 +443,13 @@
 
   // Are the two values the same?
   SValBuilder &svalBuilder = C.getSValBuilder();  
-  llvm::tie(stateTrue, stateFalse) =
+  std::tie(stateTrue, stateFalse) =
     state->assume(svalBuilder.evalEQ(state, *firstLoc, *secondLoc));
 
   if (stateTrue && !stateFalse) {
     // If the values are known to be equal, that's automatically an overlap.
     emitOverlapBug(C, stateTrue, First, Second);
-    return NULL;
+    return nullptr;
   }
 
   // assume the two expressions are not equal.
@@ -461,7 +465,7 @@
   if (!reverseTest)
     return state;
 
-  llvm::tie(stateTrue, stateFalse) = state->assume(*reverseTest);
+  std::tie(stateTrue, stateFalse) = state->assume(*reverseTest);
   if (stateTrue) {
     if (stateFalse) {
       // If we don't know which one comes first, we can't perform this test.
@@ -506,12 +510,12 @@
   if (!OverlapTest)
     return state;
 
-  llvm::tie(stateTrue, stateFalse) = state->assume(*OverlapTest);
+  std::tie(stateTrue, stateFalse) = state->assume(*OverlapTest);
 
   if (stateTrue && !stateFalse) {
     // Overlap!
     emitOverlapBug(C, stateTrue, First, Second);
-    return NULL;
+    return nullptr;
   }
 
   // assume the two expressions don't overlap.
@@ -526,7 +530,8 @@
     return;
 
   if (!BT_Overlap)
-    BT_Overlap.reset(new BugType(categories::UnixAPI, "Improper arguments"));
+    BT_Overlap.reset(new BugType(Filter.CheckNameCStringBufferOverlap,
+                                 categories::UnixAPI, "Improper arguments"));
 
   // Generate a report for this bug.
   BugReport *report = 
@@ -548,7 +553,7 @@
 
   // If a previous check has failed, propagate the failure.
   if (!state)
-    return NULL;
+    return nullptr;
 
   SValBuilder &svalBuilder = C.getSValBuilder();
   BasicValueFactory &BVF = svalBuilder.getBasicValueFactory();
@@ -576,18 +581,19 @@
                                                 *maxMinusRightNL, cmpTy);
 
     ProgramStateRef stateOverflow, stateOkay;
-    llvm::tie(stateOverflow, stateOkay) =
+    std::tie(stateOverflow, stateOkay) =
       state->assume(willOverflow.castAs<DefinedOrUnknownSVal>());
 
     if (stateOverflow && !stateOkay) {
       // We have an overflow. Emit a bug report.
       ExplodedNode *N = C.generateSink(stateOverflow);
       if (!N)
-        return NULL;
+        return nullptr;
 
       if (!BT_AdditionOverflow)
-        BT_AdditionOverflow.reset(new BuiltinBug("API",
-          "Sum of expressions causes overflow"));
+        BT_AdditionOverflow.reset(
+            new BuiltinBug(Filter.CheckNameCStringOutOfBounds, "API",
+                           "Sum of expressions causes overflow"));
 
       // This isn't a great error message, but this should never occur in real
       // code anyway -- you'd have to create a buffer longer than a size_t can
@@ -600,7 +606,7 @@
       BugReport *report = new BugReport(*BT_AdditionOverflow, warning, N);
       C.emitReport(report);        
 
-      return NULL;
+      return nullptr;
     }
 
     // From now on, assume an overflow didn't occur.
@@ -703,8 +709,9 @@
 
       if (ExplodedNode *N = C.addTransition(state)) {
         if (!BT_NotCString)
-          BT_NotCString.reset(new BuiltinBug(categories::UnixAPI,
-            "Argument is not a null-terminated string."));
+          BT_NotCString.reset(new BuiltinBug(
+              Filter.CheckNameCStringNotNullTerm, categories::UnixAPI,
+              "Argument is not a null-terminated string."));
 
         SmallString<120> buf;
         llvm::raw_svector_ostream os(buf);
@@ -714,8 +721,7 @@
            << "', which is not a null-terminated string";
 
         // Generate a report for this bug.
-        BugReport *report = new BugReport(*BT_NotCString,
-                                                          os.str(), N);
+        BugReport *report = new BugReport(*BT_NotCString, os.str(), N);
 
         report->addRange(Ex->getSourceRange());
         C.emitReport(report);        
@@ -763,8 +769,9 @@
 
     if (ExplodedNode *N = C.addTransition(state)) {
       if (!BT_NotCString)
-        BT_NotCString.reset(new BuiltinBug(categories::UnixAPI,
-          "Argument is not a null-terminated string."));
+        BT_NotCString.reset(new BuiltinBug(
+            Filter.CheckNameCStringNotNullTerm, categories::UnixAPI,
+            "Argument is not a null-terminated string."));
 
       SmallString<120> buf;
       llvm::raw_svector_ostream os(buf);
@@ -795,7 +802,7 @@
   // Get the memory region pointed to by the val.
   const MemRegion *bufRegion = val.getAsRegion();
   if (!bufRegion)
-    return NULL; 
+    return nullptr;
 
   // Strip casts off the memory region.
   bufRegion = bufRegion->StripCasts();
@@ -803,7 +810,7 @@
   // Cast the memory region to a string region.
   const StringRegion *strRegion= dyn_cast<StringRegion>(bufRegion);
   if (!strRegion)
-    return NULL; 
+    return nullptr;
 
   // Return the actual string in the string region.
   return strRegion->getStringLiteral();
@@ -845,7 +852,8 @@
     }
 
     return state->invalidateRegions(R, E, C.blockCount(), LCtx, 
-                                    CausesPointerEscape, 0, 0, &ITraits);
+                                    CausesPointerEscape, nullptr, nullptr,
+                                    &ITraits);
   }
 
   // If we have a non-region value by chance, just remove the binding.
@@ -909,7 +917,7 @@
   QualType sizeTy = Size->getType();
 
   ProgramStateRef stateZeroSize, stateNonZeroSize;
-  llvm::tie(stateZeroSize, stateNonZeroSize) =
+  std::tie(stateZeroSize, stateNonZeroSize) =
     assumeZero(C, state, sizeVal, sizeTy);
 
   // Get the value of the Dest.
@@ -946,7 +954,7 @@
     const char * const writeWarning =
       "Memory copy function overflows destination buffer";
     state = CheckBufferAccess(C, state, Size, Dest, Source,
-                              writeWarning, /* sourceWarning = */ NULL);
+                              writeWarning, /* sourceWarning = */ nullptr);
     if (Restricted)
       state = CheckOverlap(C, state, Size, Dest, Source);
 
@@ -971,7 +979,7 @@
       } else {
         // If we don't know how much we copied, we can at least
         // conjure a return value for later.
-        SVal result = C.getSValBuilder().conjureSymbolVal(0, CE, LCtx,
+        SVal result = C.getSValBuilder().conjureSymbolVal(nullptr, CE, LCtx,
                                                           C.blockCount());
         state = state->BindExpr(CE, LCtx, result);
       }
@@ -1066,7 +1074,7 @@
   QualType sizeTy = Size->getType();
 
   ProgramStateRef stateZeroSize, stateNonZeroSize;
-  llvm::tie(stateZeroSize, stateNonZeroSize) =
+  std::tie(stateZeroSize, stateNonZeroSize) =
     assumeZero(C, state, sizeVal, sizeTy);
 
   // If the size can be zero, the result will be 0 in that case, and we don't
@@ -1092,7 +1100,7 @@
     // See if they are the same.
     DefinedOrUnknownSVal SameBuf = svalBuilder.evalEQ(state, LV, RV);
     ProgramStateRef StSameBuf, StNotSameBuf;
-    llvm::tie(StSameBuf, StNotSameBuf) = state->assume(SameBuf);
+    std::tie(StSameBuf, StNotSameBuf) = state->assume(SameBuf);
 
     // If the two arguments might be the same buffer, we know the result is 0,
     // and we only need to check one size.
@@ -1113,7 +1121,8 @@
       state = CheckBufferAccess(C, state, Size, Left, Right);
       if (state) {
         // The return value is the comparison result, which we don't know.
-        SVal CmpV = svalBuilder.conjureSymbolVal(0, CE, LCtx, C.blockCount());
+        SVal CmpV = svalBuilder.conjureSymbolVal(nullptr, CE, LCtx,
+                                                 C.blockCount());
         state = state->BindExpr(CE, LCtx, CmpV);
         C.addTransition(state);
       }
@@ -1150,7 +1159,7 @@
     SVal maxlenVal = state->getSVal(maxlenExpr, LCtx);
 
     ProgramStateRef stateZeroSize, stateNonZeroSize;
-    llvm::tie(stateZeroSize, stateNonZeroSize) =
+    std::tie(stateZeroSize, stateNonZeroSize) =
       assumeZero(C, state, maxlenVal, maxlenExpr->getType());
 
     // If the size can be zero, the result will be 0 in that case, and we don't
@@ -1204,10 +1213,10 @@
       ProgramStateRef stateStringTooLong, stateStringNotTooLong;
 
       // Check if the strLength is greater than the maxlen.
-      llvm::tie(stateStringTooLong, stateStringNotTooLong) =
-          state->assume(C.getSValBuilder().evalBinOpNN(
-              state, BO_GT, *strLengthNL, *maxlenValNL, cmpTy)
-                            .castAs<DefinedOrUnknownSVal>());
+      std::tie(stateStringTooLong, stateStringNotTooLong) = state->assume(
+          C.getSValBuilder()
+              .evalBinOpNN(state, BO_GT, *strLengthNL, *maxlenValNL, cmpTy)
+              .castAs<DefinedOrUnknownSVal>());
 
       if (stateStringTooLong && !stateStringNotTooLong) {
         // If the string is longer than maxlen, return maxlen.
@@ -1223,7 +1232,8 @@
       // no guarantee the full string length will actually be returned.
       // All we know is the return value is the min of the string length
       // and the limit. This is better than nothing.
-      result = C.getSValBuilder().conjureSymbolVal(0, CE, LCtx, C.blockCount());
+      result = C.getSValBuilder().conjureSymbolVal(nullptr, CE, LCtx,
+                                                   C.blockCount());
       NonLoc resultNL = result.castAs<NonLoc>();
 
       if (strLengthNL) {
@@ -1246,7 +1256,8 @@
     // If we don't know the length of the string, conjure a return
     // value, so it can be used in constraints, at least.
     if (result.isUnknown()) {
-      result = C.getSValBuilder().conjureSymbolVal(0, CE, LCtx, C.blockCount());
+      result = C.getSValBuilder().conjureSymbolVal(nullptr, CE, LCtx,
+                                                   C.blockCount());
     }
   }
 
@@ -1349,7 +1360,7 @@
   // - potential overflows caused by a bound that could exceed the destination
   SVal amountCopied = UnknownVal();
   SVal maxLastElementIndex = UnknownVal();
-  const char *boundWarning = NULL;
+  const char *boundWarning = nullptr;
 
   // If the function is strncpy, strncat, etc... it is bounded.
   if (isBounded) {
@@ -1371,7 +1382,7 @@
       // Check if the max number to copy is less than the length of the src.
       // If the bound is equal to the source length, strncpy won't null-
       // terminate the result!
-      llvm::tie(stateSourceTooLong, stateSourceNotTooLong) = state->assume(
+      std::tie(stateSourceTooLong, stateSourceNotTooLong) = state->assume(
           svalBuilder.evalBinOpNN(state, BO_GE, *strLengthNL, *lenValNL, cmpTy)
               .castAs<DefinedOrUnknownSVal>());
 
@@ -1418,7 +1429,7 @@
         // case strncpy will do no work at all. Our bounds check uses n-1
         // as the last element accessed, so n == 0 is problematic.
         ProgramStateRef StateZeroSize, StateNonZeroSize;
-        llvm::tie(StateZeroSize, StateNonZeroSize) =
+        std::tie(StateZeroSize, StateNonZeroSize) =
           assumeZero(C, state, *lenValNL, sizeTy);
 
         // If the size is known to be zero, we're done.
@@ -1629,7 +1640,7 @@
   // If this is a stpcpy-style copy, but we were unable to check for a buffer
   // overflow, we still need a result. Conjure a return value.
   if (returnEnd && Result.isUnknown()) {
-    Result = svalBuilder.conjureSymbolVal(0, CE, LCtx, C.blockCount());
+    Result = svalBuilder.conjureSymbolVal(nullptr, CE, LCtx, C.blockCount());
   }
 
   // Set the return value.
@@ -1711,7 +1722,7 @@
   SValBuilder &svalBuilder = C.getSValBuilder();
   DefinedOrUnknownSVal SameBuf = svalBuilder.evalEQ(state, LV, RV);
   ProgramStateRef StSameBuf, StNotSameBuf;
-  llvm::tie(StSameBuf, StNotSameBuf) = state->assume(SameBuf);
+  std::tie(StSameBuf, StNotSameBuf) = state->assume(SameBuf);
 
   // If the two arguments might be the same buffer, we know the result is 0,
   // and we only need to check one size.
@@ -1786,7 +1797,8 @@
 
   if (!canComputeResult) {
     // Conjure a symbolic value. It's the best we can do.
-    SVal resultVal = svalBuilder.conjureSymbolVal(0, CE, LCtx, C.blockCount());
+    SVal resultVal = svalBuilder.conjureSymbolVal(nullptr, CE, LCtx,
+                                                  C.blockCount());
     state = state->BindExpr(CE, LCtx, resultVal);
   }
 
@@ -1843,7 +1855,7 @@
   } else {
     assert(SearchStrVal.isUnknown());
     // Conjure a symbolic value. It's the best we can do.
-    Result = SVB.conjureSymbolVal(0, CE, LCtx, C.blockCount());
+    Result = SVB.conjureSymbolVal(nullptr, CE, LCtx, C.blockCount());
   }
 
   // Set the return value, and finish.
@@ -1863,7 +1875,7 @@
     return false;
 
   // FIXME: Poorly-factored string switches are slow.
-  FnCheck evalFunction = 0;
+  FnCheck evalFunction = nullptr;
   if (C.isCLibraryFunction(FDecl, "memcpy"))
     evalFunction =  &CStringChecker::evalMemcpy;
   else if (C.isCLibraryFunction(FDecl, "mempcpy"))
@@ -1907,7 +1919,7 @@
 
   // Make sure each function sets its own description.
   // (But don't bother in a release build.)
-  assert(!(CurrentFunctionDescription = NULL));
+  assert(!(CurrentFunctionDescription = nullptr));
 
   // Check and evaluate the call.
   (this->*evalFunction)(C, CE);
@@ -1928,9 +1940,8 @@
   // Record string length for char a[] = "abc";
   ProgramStateRef state = C.getState();
 
-  for (DeclStmt::const_decl_iterator I = DS->decl_begin(), E = DS->decl_end();
-       I != E; ++I) {
-    const VarDecl *D = dyn_cast<VarDecl>(*I);
+  for (const auto *I : DS->decls()) {
+    const VarDecl *D = dyn_cast<VarDecl>(I);
     if (!D)
       continue;
 
@@ -2057,10 +2068,12 @@
   C.addTransition(state);
 }
 
-#define REGISTER_CHECKER(name) \
-void ento::register##name(CheckerManager &mgr) {\
-  mgr.registerChecker<CStringChecker>()->Filter.Check##name = true; \
-}
+#define REGISTER_CHECKER(name)                                                 \
+  void ento::register##name(CheckerManager &mgr) {                             \
+    CStringChecker *checker = mgr.registerChecker<CStringChecker>();           \
+    checker->Filter.Check##name = true;                                        \
+    checker->Filter.CheckName##name = mgr.getCurrentCheckName();               \
+  }
 
 REGISTER_CHECKER(CStringNullArg)
 REGISTER_CHECKER(CStringOutOfBounds)
diff --git a/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp b/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp
index d29a12a..abfb971 100644
--- a/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp
@@ -31,6 +31,7 @@
 
 namespace {
 class WalkAST: public StmtVisitor<WalkAST> {
+  const CheckerBase *Checker;
   BugReporter &BR;
   AnalysisDeclContext* AC;
 
@@ -81,9 +82,8 @@
   bool containsBadStrncatPattern(const CallExpr *CE);
 
 public:
-  WalkAST(BugReporter &br, AnalysisDeclContext* ac) :
-      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);
@@ -157,8 +157,9 @@
         os << "U";
       os << "se a safer 'strlcat' API";
 
-      BR.EmitBasicReport(FD, "Anti-pattern in the argument", "C String API",
-                         os.str(), Loc, LenArg->getSourceRange());
+      BR.EmitBasicReport(FD, Checker, "Anti-pattern in the argument",
+                         "C String API", os.str(), Loc,
+                         LenArg->getSourceRange());
     }
   }
 
@@ -179,7 +180,7 @@
 
   void checkASTCodeBody(const Decl *D, AnalysisManager& Mgr,
       BugReporter &BR) const {
-    WalkAST walker(BR, Mgr.getAnalysisDeclContext(D));
+    WalkAST walker(this, BR, Mgr.getAnalysisDeclContext(D));
     walker.Visit(D->getBody());
   }
 };
diff --git a/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp b/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
index fefcbe7..adb7a54 100644
--- a/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
@@ -27,24 +27,35 @@
 using namespace ento;
 
 namespace {
+
+struct ChecksFilter {
+  DefaultBool Check_CallAndMessageUnInitRefArg;
+  DefaultBool Check_CallAndMessageChecker;
+
+  CheckName CheckName_CallAndMessageUnInitRefArg;
+  CheckName CheckName_CallAndMessageChecker;
+};
+
 class CallAndMessageChecker
   : public Checker< check::PreStmt<CallExpr>,
                     check::PreStmt<CXXDeleteExpr>,
                     check::PreObjCMessage,
                     check::PreCall > {
-  mutable OwningPtr<BugType> BT_call_null;
-  mutable OwningPtr<BugType> BT_call_undef;
-  mutable OwningPtr<BugType> BT_cxx_call_null;
-  mutable OwningPtr<BugType> BT_cxx_call_undef;
-  mutable OwningPtr<BugType> BT_call_arg;
-  mutable OwningPtr<BugType> BT_cxx_delete_undef;
-  mutable OwningPtr<BugType> BT_msg_undef;
-  mutable OwningPtr<BugType> BT_objc_prop_undef;
-  mutable OwningPtr<BugType> BT_objc_subscript_undef;
-  mutable OwningPtr<BugType> BT_msg_arg;
-  mutable OwningPtr<BugType> BT_msg_ret;
-  mutable OwningPtr<BugType> BT_call_few_args;
+  mutable std::unique_ptr<BugType> BT_call_null;
+  mutable std::unique_ptr<BugType> BT_call_undef;
+  mutable std::unique_ptr<BugType> BT_cxx_call_null;
+  mutable std::unique_ptr<BugType> BT_cxx_call_undef;
+  mutable std::unique_ptr<BugType> BT_call_arg;
+  mutable std::unique_ptr<BugType> BT_cxx_delete_undef;
+  mutable std::unique_ptr<BugType> BT_msg_undef;
+  mutable std::unique_ptr<BugType> BT_objc_prop_undef;
+  mutable std::unique_ptr<BugType> BT_objc_subscript_undef;
+  mutable std::unique_ptr<BugType> BT_msg_arg;
+  mutable std::unique_ptr<BugType> BT_msg_ret;
+  mutable std::unique_ptr<BugType> BT_call_few_args;
+
 public:
+  ChecksFilter Filter;
 
   void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
   void checkPreStmt(const CXXDeleteExpr *DE, CheckerContext &C) const;
@@ -52,10 +63,11 @@
   void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
 
 private:
-  static bool PreVisitProcessArg(CheckerContext &C, SVal V,
-                                 SourceRange argRange, const Expr *argEx,
-                                 bool IsFirstArgument, bool checkUninitFields,
-                                 const CallEvent &Call, OwningPtr<BugType> &BT);
+  bool PreVisitProcessArg(CheckerContext &C, SVal V, SourceRange ArgRange,
+                          const Expr *ArgEx, bool IsFirstArgument,
+                          bool CheckUninitFields, const CallEvent &Call,
+                          std::unique_ptr<BugType> &BT,
+                          const ParmVarDecl *ParamDecl) const;
 
   static void emitBadCall(BugType *BT, CheckerContext &C, const Expr *BadE);
   void emitNilReceiverBug(CheckerContext &C, const ObjCMethodCall &msg,
@@ -65,10 +77,14 @@
                          ProgramStateRef state,
                          const ObjCMethodCall &msg) const;
 
-  static void LazyInit_BT(const char *desc, OwningPtr<BugType> &BT) {
+  void LazyInit_BT(const char *desc, std::unique_ptr<BugType> &BT) const {
     if (!BT)
-      BT.reset(new BuiltinBug(desc));
+      BT.reset(new BuiltinBug(this, desc));
   }
+  bool uninitRefOrPointer(CheckerContext &C, const SVal &V,
+                          const SourceRange &ArgRange,
+                          const Expr *ArgEx, std::unique_ptr<BugType> &BT,
+                          const ParmVarDecl *ParamDecl, const char *BD) const;
 };
 } // end anonymous namespace
 
@@ -113,30 +129,86 @@
   }
 }
 
+bool CallAndMessageChecker::uninitRefOrPointer(CheckerContext &C,
+                                               const SVal &V,
+                                               const SourceRange &ArgRange,
+                                               const Expr *ArgEx,
+                                               std::unique_ptr<BugType> &BT,
+                                               const ParmVarDecl *ParamDecl,
+                                               const char *BD) const {
+  if (!Filter.Check_CallAndMessageUnInitRefArg)
+    return false;
+
+  // No parameter declaration available, i.e. variadic function argument.
+  if(!ParamDecl)
+    return false;
+
+  // 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;
+
+  if (ParamDecl->getType()->isPointerType()) {
+    Message = "Function call argument is a pointer to uninitialized value";
+  } else if (ParamDecl->getType()->isReferenceType()) {
+    Message = "Function call argument is an uninitialized value";
+  } else
+    return false;
+
+  if(!ParamDecl->getType()->getPointeeType().isConstQualified())
+    return false;
+
+  if (const MemRegion *SValMemRegion = V.getAsRegion()) {
+    const ProgramStateRef State = C.getState();
+    const SVal PSV = State->getSVal(SValMemRegion);
+    if (PSV.isUndef()) {
+      if (ExplodedNode *N = C.generateSink()) {
+        LazyInit_BT(BD, BT);
+        BugReport *R = new BugReport(*BT, Message, N);
+        R->addRange(ArgRange);
+        if (ArgEx) {
+          bugreporter::trackNullOrUndefValue(N, ArgEx, *R);
+        }
+        C.emitReport(R);
+      }
+      return true;
+    }
+  }
+  return false;
+}
+
 bool CallAndMessageChecker::PreVisitProcessArg(CheckerContext &C,
-                                               SVal V, SourceRange argRange,
-                                               const Expr *argEx,
+                                               SVal V,
+                                               SourceRange ArgRange,
+                                               const Expr *ArgEx,
                                                bool IsFirstArgument,
-                                               bool checkUninitFields,
+                                               bool CheckUninitFields,
                                                const CallEvent &Call,
-                                               OwningPtr<BugType> &BT) {
+                                               std::unique_ptr<BugType> &BT,
+                                               const ParmVarDecl *ParamDecl
+                                               ) const {
+  const char *BD = "Uninitialized argument value";
+
+  if (uninitRefOrPointer(C, V, ArgRange, ArgEx, BT, ParamDecl, BD))
+    return true;
+
   if (V.isUndef()) {
     if (ExplodedNode *N = C.generateSink()) {
-      LazyInit_BT("Uninitialized argument value", BT);
+      LazyInit_BT(BD, BT);
 
       // Generate a report for this bug.
-      StringRef Desc = describeUninitializedArgumentInCall(Call,
-                                                           IsFirstArgument);
+      StringRef Desc =
+          describeUninitializedArgumentInCall(Call, IsFirstArgument);
       BugReport *R = new BugReport(*BT, Desc, N);
-      R->addRange(argRange);
-      if (argEx)
-        bugreporter::trackNullOrUndefValue(N, argEx, *R);
+      R->addRange(ArgRange);
+      if (ArgEx)
+        bugreporter::trackNullOrUndefValue(N, ArgEx, *R);
       C.emitReport(R);
     }
     return true;
   }
 
-  if (!checkUninitFields)
+  if (!CheckUninitFields)
     return false;
 
   if (Optional<nonloc::LazyCompoundVal> LV =
@@ -159,10 +231,9 @@
         if (const RecordType *RT = T->getAsStructureType()) {
           const RecordDecl *RD = RT->getDecl()->getDefinition();
           assert(RD && "Referred record has no definition");
-          for (RecordDecl::field_iterator I =
-               RD->field_begin(), E = RD->field_end(); I!=E; ++I) {
-            const FieldRegion *FR = MrMgr.getFieldRegion(*I, R);
-            FieldChain.push_back(*I);
+          for (const auto *I : RD->fields()) {
+            const FieldRegion *FR = MrMgr.getFieldRegion(I, R);
+            FieldChain.push_back(I);
             T = I->getType();
             if (T->getAsStructureType()) {
               if (Find(FR))
@@ -188,7 +259,7 @@
 
     if (F.Find(D->getRegion())) {
       if (ExplodedNode *N = C.generateSink()) {
-        LazyInit_BT("Uninitialized argument value", BT);
+        LazyInit_BT(BD, BT);
         SmallString<512> Str;
         llvm::raw_svector_ostream os(Str);
         os << "Passed-by-value struct argument contains uninitialized data";
@@ -211,7 +282,7 @@
 
         // Generate a report for this bug.
         BugReport *R = new BugReport(*BT, os.str(), N);
-        R->addRange(argRange);
+        R->addRange(ArgRange);
 
         // FIXME: enhance track back for uninitialized value for arbitrary
         // memregions
@@ -234,20 +305,19 @@
 
   if (L.isUndef()) {
     if (!BT_call_undef)
-      BT_call_undef.reset(new BuiltinBug("Called function pointer is an "
-                                         "uninitalized pointer value"));
+      BT_call_undef.reset(new BuiltinBug(
+          this, "Called function pointer is an uninitalized pointer value"));
     emitBadCall(BT_call_undef.get(), C, Callee);
     return;
   }
 
   ProgramStateRef StNonNull, StNull;
-  llvm::tie(StNonNull, StNull) =
-      State->assume(L.castAs<DefinedOrUnknownSVal>());
+  std::tie(StNonNull, StNull) = State->assume(L.castAs<DefinedOrUnknownSVal>());
 
   if (StNull && !StNonNull) {
     if (!BT_call_null)
-      BT_call_null.reset(
-        new BuiltinBug("Called function pointer is null (null dereference)"));
+      BT_call_null.reset(new BuiltinBug(
+          this, "Called function pointer is null (null dereference)"));
     emitBadCall(BT_call_null.get(), C, Callee);
     return;
   }
@@ -265,7 +335,8 @@
     if (!N)
       return;
     if (!BT_cxx_delete_undef)
-      BT_cxx_delete_undef.reset(new BuiltinBug("Uninitialized argument value"));
+      BT_cxx_delete_undef.reset(
+          new BuiltinBug(this, "Uninitialized argument value"));
     if (DE->isArrayFormAsWritten())
       Desc = "Argument to 'delete[]' is uninitialized";
     else
@@ -289,20 +360,20 @@
     SVal V = CC->getCXXThisVal();
     if (V.isUndef()) {
       if (!BT_cxx_call_undef)
-        BT_cxx_call_undef.reset(new BuiltinBug("Called C++ object pointer is "
-                                               "uninitialized"));
+        BT_cxx_call_undef.reset(
+            new BuiltinBug(this, "Called C++ object pointer is uninitialized"));
       emitBadCall(BT_cxx_call_undef.get(), C, CC->getCXXThisExpr());
       return;
     }
 
     ProgramStateRef StNonNull, StNull;
-    llvm::tie(StNonNull, StNull) =
+    std::tie(StNonNull, StNull) =
         State->assume(V.castAs<DefinedOrUnknownSVal>());
 
     if (StNull && !StNonNull) {
       if (!BT_cxx_call_null)
-        BT_cxx_call_null.reset(new BuiltinBug("Called C++ object pointer "
-                                              "is null"));
+        BT_cxx_call_null.reset(
+            new BuiltinBug(this, "Called C++ object pointer is null"));
       emitBadCall(BT_cxx_call_null.get(), C, CC->getCXXThisExpr());
       return;
     }
@@ -311,7 +382,8 @@
   }
 
   const Decl *D = Call.getDecl();
-  if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) {
+  const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
+  if (FD) {
     // If we have a declaration, we can make sure we pass enough parameters to
     // the function.
     unsigned Params = FD->getNumParams();
@@ -340,17 +412,21 @@
   const bool checkUninitFields =
     !(C.getAnalysisManager().shouldInlineCall() && (D && D->getBody()));
 
-  OwningPtr<BugType> *BT;
+  std::unique_ptr<BugType> *BT;
   if (isa<ObjCMethodCall>(Call))
     BT = &BT_msg_arg;
   else
     BT = &BT_call_arg;
 
-  for (unsigned i = 0, e = Call.getNumArgs(); i != e; ++i)
+  for (unsigned i = 0, e = Call.getNumArgs(); i != e; ++i) {
+    const ParmVarDecl *ParamDecl = nullptr;
+    if(FD && i < FD->getNumParams())
+      ParamDecl = FD->getParamDecl(i);
     if (PreVisitProcessArg(C, Call.getArgSVal(i), Call.getArgSourceRange(i),
                            Call.getArgExpr(i), /*IsFirstArgument=*/i == 0,
-                           checkUninitFields, Call, *BT))
+                           checkUninitFields, Call, *BT, ParamDecl))
       return;
+  }
 
   // If we make it here, record our assumptions about the callee.
   C.addTransition(State);
@@ -361,26 +437,25 @@
   SVal recVal = msg.getReceiverSVal();
   if (recVal.isUndef()) {
     if (ExplodedNode *N = C.generateSink()) {
-      BugType *BT = 0;
+      BugType *BT = nullptr;
       switch (msg.getMessageKind()) {
       case OCM_Message:
         if (!BT_msg_undef)
-          BT_msg_undef.reset(new BuiltinBug("Receiver in message expression "
+          BT_msg_undef.reset(new BuiltinBug(this,
+                                            "Receiver in message expression "
                                             "is an uninitialized value"));
         BT = BT_msg_undef.get();
         break;
       case OCM_PropertyAccess:
         if (!BT_objc_prop_undef)
-          BT_objc_prop_undef.reset(new BuiltinBug("Property access on an "
-                                                  "uninitialized object "
-                                                  "pointer"));
+          BT_objc_prop_undef.reset(new BuiltinBug(
+              this, "Property access on an uninitialized object pointer"));
         BT = BT_objc_prop_undef.get();
         break;
       case OCM_Subscript:
         if (!BT_objc_subscript_undef)
-          BT_objc_subscript_undef.reset(new BuiltinBug("Subscript access on an "
-                                                       "uninitialized object "
-                                                       "pointer"));
+          BT_objc_subscript_undef.reset(new BuiltinBug(
+              this, "Subscript access on an uninitialized object pointer"));
         BT = BT_objc_subscript_undef.get();
         break;
       }
@@ -402,7 +477,7 @@
 
     ProgramStateRef state = C.getState();
     ProgramStateRef notNilState, nilState;
-    llvm::tie(notNilState, nilState) = state->assume(receiverVal);
+    std::tie(notNilState, nilState) = state->assume(receiverVal);
 
     // Handle receiver must be nil.
     if (nilState && !notNilState) {
@@ -418,7 +493,7 @@
 
   if (!BT_msg_ret)
     BT_msg_ret.reset(
-      new BuiltinBug("Receiver in message expression is 'nil'"));
+        new BuiltinBug(this, "Receiver in message expression is 'nil'"));
 
   const ObjCMessageExpr *ME = msg.getOriginExpr();
 
@@ -426,8 +501,9 @@
 
   SmallString<200> buf;
   llvm::raw_svector_ostream os(buf);
-  os << "The receiver of message '" << ME->getSelector().getAsString()
-     << "' is nil";
+  os << "The receiver of message '";
+  ME->getSelector().print(os);
+  os << "' is nil";
   if (ResTy->isReferenceType()) {
     os << ", which results in forming a null reference";
   } else {
@@ -454,7 +530,7 @@
                                               ProgramStateRef state,
                                               const ObjCMethodCall &Msg) const {
   ASTContext &Ctx = C.getASTContext();
-  static SimpleProgramPointTag Tag("CallAndMessageChecker : NilReceiver");
+  static CheckerProgramPointTag Tag(this, "NilReceiver");
 
   // Check the return type of the message expression.  A message to nil will
   // return different values depending on the return type and the architecture.
@@ -484,7 +560,7 @@
             Ctx.LongDoubleTy == CanRetTy ||
             Ctx.LongLongTy == CanRetTy ||
             Ctx.UnsignedLongLongTy == CanRetTy)))) {
-      if (ExplodedNode *N = C.generateSink(state, 0 , &Tag))
+      if (ExplodedNode *N = C.generateSink(state, nullptr, &Tag))
         emitNilReceiverBug(C, Msg, N);
       return;
     }
@@ -510,6 +586,13 @@
   C.addTransition(state);
 }
 
-void ento::registerCallAndMessageChecker(CheckerManager &mgr) {
-  mgr.registerChecker<CallAndMessageChecker>();
-}
+#define REGISTER_CHECKER(name)                                                 \
+  void ento::register##name(CheckerManager &mgr) {                             \
+    CallAndMessageChecker *Checker =                                           \
+        mgr.registerChecker<CallAndMessageChecker>();                          \
+    Checker->Filter.Check_##name = true;                                       \
+    Checker->Filter.CheckName_##name = mgr.getCurrentCheckName();              \
+  }
+
+REGISTER_CHECKER(CallAndMessageUnInitRefArg)
+REGISTER_CHECKER(CallAndMessageChecker)
diff --git a/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp b/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp
index 5e6e105..3ba063d 100644
--- a/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp
@@ -23,12 +23,71 @@
 
 namespace {
 class CastSizeChecker : public Checker< check::PreStmt<CastExpr> > {
-  mutable OwningPtr<BuiltinBug> BT;
+  mutable std::unique_ptr<BuiltinBug> BT;
+
 public:
   void checkPreStmt(const CastExpr *CE, CheckerContext &C) const;
 };
 }
 
+/// Check if we are casting to a struct with a flexible array at the end.
+/// \code
+/// struct foo {
+///   size_t len;
+///   struct bar data[];
+/// };
+/// \endcode
+/// or
+/// \code
+/// struct foo {
+///   size_t len;
+///   struct bar data[0];
+/// }
+/// \endcode
+/// In these cases it is also valid to allocate size of struct foo + a multiple
+/// of struct bar.
+static bool evenFlexibleArraySize(ASTContext &Ctx, CharUnits RegionSize,
+                                  CharUnits TypeSize, QualType ToPointeeTy) {
+  const RecordType *RT = ToPointeeTy->getAs<RecordType>();
+  if (!RT)
+    return false;
+
+  const RecordDecl *RD = RT->getDecl();
+  RecordDecl::field_iterator Iter(RD->field_begin());
+  RecordDecl::field_iterator End(RD->field_end());
+  const FieldDecl *Last = nullptr;
+  for (; Iter != End; ++Iter)
+    Last = *Iter;
+  assert(Last && "empty structs should already be handled");
+
+  const Type *ElemType = Last->getType()->getArrayElementTypeNoTypeQual();
+  CharUnits FlexSize;
+  if (const ConstantArrayType *ArrayTy =
+        Ctx.getAsConstantArrayType(Last->getType())) {
+    FlexSize = Ctx.getTypeSizeInChars(ElemType);
+    if (ArrayTy->getSize() == 1 && TypeSize > FlexSize)
+      TypeSize -= FlexSize;
+    else if (ArrayTy->getSize() != 0)
+      return false;
+  } else if (RD->hasFlexibleArrayMember()) {
+    FlexSize = Ctx.getTypeSizeInChars(ElemType);
+  } else {
+    return false;
+  }
+
+  if (FlexSize.isZero())
+    return false;
+
+  CharUnits Left = RegionSize - TypeSize;
+  if (Left.isNegative())
+    return false;
+
+  if (Left % FlexSize == 0)
+    return true;
+
+  return false;
+}
+
 void CastSizeChecker::checkPreStmt(const CastExpr *CE,CheckerContext &C) const {
   const Expr *E = CE->getSubExpr();
   ASTContext &Ctx = C.getASTContext();
@@ -46,11 +105,11 @@
 
   ProgramStateRef state = C.getState();
   const MemRegion *R = state->getSVal(E, C.getLocationContext()).getAsRegion();
-  if (R == 0)
+  if (!R)
     return;
 
   const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R);
-  if (SR == 0)
+  if (!SR)
     return;
 
   SValBuilder &svalBuilder = C.getSValBuilder();
@@ -66,21 +125,23 @@
   if (typeSize.isZero())
     return;
 
-  if (regionSize % typeSize != 0) {
-    if (ExplodedNode *errorNode = C.generateSink()) {
-      if (!BT)
-        BT.reset(new BuiltinBug("Cast region with wrong size.",
-                            "Cast a region whose size is not a multiple of the"
-                            " destination type size."));
-      BugReport *R = new BugReport(*BT, BT->getDescription(),
-                                               errorNode);
-      R->addRange(CE->getSourceRange());
-      C.emitReport(R);
-    }
+  if (regionSize % typeSize == 0)
+    return;
+
+  if (evenFlexibleArraySize(Ctx, regionSize, typeSize, ToPointeeTy))
+    return;
+
+  if (ExplodedNode *errorNode = C.generateSink()) {
+    if (!BT)
+      BT.reset(new BuiltinBug(this, "Cast region with wrong size.",
+                                    "Cast a region whose size is not a multiple"
+                                    " of the destination type size."));
+    BugReport *R = new BugReport(*BT, BT->getDescription(), errorNode);
+    R->addRange(CE->getSourceRange());
+    C.emitReport(R);
   }
 }
 
-
 void ento::registerCastSizeChecker(CheckerManager &mgr) {
-  mgr.registerChecker<CastSizeChecker>();  
+  mgr.registerChecker<CastSizeChecker>();
 }
diff --git a/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp b/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp
index 60348c7..d765315 100644
--- a/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp
@@ -24,7 +24,7 @@
 
 namespace {
 class CastToStructChecker : public Checker< check::PreStmt<CastExpr> > {
-  mutable OwningPtr<BuiltinBug> BT;
+  mutable std::unique_ptr<BuiltinBug> BT;
 
 public:
   void checkPreStmt(const CastExpr *CE, CheckerContext &C) const;
@@ -58,10 +58,11 @@
   if (!OrigPointeeTy->isRecordType()) {
     if (ExplodedNode *N = C.addTransition()) {
       if (!BT)
-        BT.reset(new BuiltinBug("Cast from non-struct type to struct type",
-                            "Casting a non-structure type to a structure type "
-                            "and accessing a field can lead to memory access "
-                            "errors or data corruption."));
+        BT.reset(
+            new BuiltinBug(this, "Cast from non-struct type to struct type",
+                           "Casting a non-structure type to a structure type "
+                           "and accessing a field can lead to memory access "
+                           "errors or data corruption."));
       BugReport *R = new BugReport(*BT,BT->getDescription(), N);
       R->addRange(CE->getSourceRange());
       C.emitReport(R);
diff --git a/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp b/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp
index 3f9b3cc..d186144 100644
--- a/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp
+++ b/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp
@@ -97,8 +97,9 @@
   return false;
 }
 
-static void checkObjCDealloc(const ObjCImplementationDecl *D,
-                             const LangOptions& LOpts, BugReporter& BR) {
+static void checkObjCDealloc(const CheckerBase *Checker,
+                             const ObjCImplementationDecl *D,
+                             const LangOptions &LOpts, BugReporter &BR) {
 
   assert (LOpts.getGC() != LangOptions::GCOnly);
 
@@ -112,15 +113,12 @@
 
   bool containsPointerIvar = false;
 
-  for (ObjCInterfaceDecl::ivar_iterator I=ID->ivar_begin(), E=ID->ivar_end();
-       I!=E; ++I) {
-
-    ObjCIvarDecl *ID = *I;
-    QualType T = ID->getType();
+  for (const auto *Ivar : ID->ivars()) {
+    QualType T = Ivar->getType();
 
     if (!T->isObjCObjectPointerType() ||
-        ID->getAttr<IBOutletAttr>() || // Skip IBOutlets.
-        ID->getAttr<IBOutletCollectionAttr>()) // Skip IBOutletCollections.
+        Ivar->hasAttr<IBOutletAttr>() || // Skip IBOutlets.
+        Ivar->hasAttr<IBOutletCollectionAttr>()) // Skip IBOutletCollections.
       continue;
 
     containsPointerIvar = true;
@@ -155,14 +153,12 @@
   // Get the "dealloc" selector.
   IdentifierInfo* II = &Ctx.Idents.get("dealloc");
   Selector S = Ctx.Selectors.getSelector(0, &II);
-  ObjCMethodDecl *MD = 0;
+  const ObjCMethodDecl *MD = nullptr;
 
   // Scan the instance methods for "dealloc".
-  for (ObjCImplementationDecl::instmeth_iterator I = D->instmeth_begin(),
-       E = D->instmeth_end(); I!=E; ++I) {
-
-    if ((*I)->getSelector() == S) {
-      MD = *I;
+  for (const auto *I : D->instance_methods()) {
+    if (I->getSelector() == S) {
+      MD = I;
       break;
     }
   }
@@ -180,7 +176,7 @@
     llvm::raw_string_ostream os(buf);
     os << "Objective-C class '" << *D << "' lacks a 'dealloc' instance method";
 
-    BR.EmitBasicReport(D, name, categories::CoreFoundationObjectiveC,
+    BR.EmitBasicReport(D, Checker, name, categories::CoreFoundationObjectiveC,
                        os.str(), DLoc);
     return;
   }
@@ -198,7 +194,7 @@
        << "' does not send a 'dealloc' message to its super class"
            " (missing [super dealloc])";
 
-    BR.EmitBasicReport(MD, name, categories::CoreFoundationObjectiveC,
+    BR.EmitBasicReport(MD, Checker, name, categories::CoreFoundationObjectiveC,
                        os.str(), DLoc);
     return;
   }
@@ -212,9 +208,7 @@
 
   // Scan for missing and extra releases of ivars used by implementations
   // of synthesized properties
-  for (ObjCImplementationDecl::propimpl_iterator I = D->propimpl_begin(),
-       E = D->propimpl_end(); I!=E; ++I) {
-
+  for (const auto *I : D->property_impls()) {
     // We can only check the synthesized properties
     if (I->getPropertyImplementation() != ObjCPropertyImplDecl::Synthesize)
       continue;
@@ -239,7 +233,7 @@
     bool requiresRelease = PD->getSetterKind() != ObjCPropertyDecl::Assign;
     if (scan_ivar_release(MD->getBody(), ID, PD, RS, SelfII, Ctx)
        != requiresRelease) {
-      const char *name = 0;
+      const char *name = nullptr;
       std::string buf;
       llvm::raw_string_ostream os(buf);
 
@@ -262,10 +256,10 @@
       }
 
       PathDiagnosticLocation SDLoc =
-        PathDiagnosticLocation::createBegin(*I, BR.getSourceManager());
+        PathDiagnosticLocation::createBegin(I, BR.getSourceManager());
 
-      BR.EmitBasicReport(MD, name, categories::CoreFoundationObjectiveC,
-                         os.str(), SDLoc);
+      BR.EmitBasicReport(MD, Checker, name,
+                         categories::CoreFoundationObjectiveC, os.str(), SDLoc);
     }
   }
 }
@@ -282,7 +276,8 @@
                     BugReporter &BR) const {
     if (mgr.getLangOpts().getGC() == LangOptions::GCOnly)
       return;
-    checkObjCDealloc(cast<ObjCImplementationDecl>(D), mgr.getLangOpts(), BR);
+    checkObjCDealloc(this, cast<ObjCImplementationDecl>(D), mgr.getLangOpts(),
+                     BR);
   }
 };
 }
diff --git a/lib/StaticAnalyzer/Checkers/CheckObjCInstMethSignature.cpp b/lib/StaticAnalyzer/Checkers/CheckObjCInstMethSignature.cpp
index 9cb1d2d..cc4c0c3 100644
--- a/lib/StaticAnalyzer/Checkers/CheckObjCInstMethSignature.cpp
+++ b/lib/StaticAnalyzer/Checkers/CheckObjCInstMethSignature.cpp
@@ -40,10 +40,11 @@
 static void CompareReturnTypes(const ObjCMethodDecl *MethDerived,
                                const ObjCMethodDecl *MethAncestor,
                                BugReporter &BR, ASTContext &Ctx,
-                               const ObjCImplementationDecl *ID) {
+                               const ObjCImplementationDecl *ID,
+                               const CheckerBase *Checker) {
 
-  QualType ResDerived  = MethDerived->getResultType();
-  QualType ResAncestor = MethAncestor->getResultType();
+  QualType ResDerived = MethDerived->getReturnType();
+  QualType ResAncestor = MethAncestor->getReturnType();
 
   if (!AreTypesCompatible(ResDerived, ResAncestor, Ctx)) {
     std::string sbuf;
@@ -53,9 +54,9 @@
        << *MethDerived->getClassInterface()
        << "', which is derived from class '"
        << *MethAncestor->getClassInterface()
-       << "', defines the instance method '"
-       << MethDerived->getSelector().getAsString()
-       << "' whose return type is '"
+       << "', defines the instance method '";
+    MethDerived->getSelector().print(os);
+    os << "' whose return type is '"
        << ResDerived.getAsString()
        << "'.  A method with the same name (same selector) is also defined in "
           "class '"
@@ -69,15 +70,15 @@
       PathDiagnosticLocation::createBegin(MethDerived,
                                           BR.getSourceManager());
 
-    BR.EmitBasicReport(MethDerived,
-                       "Incompatible instance method return type",
-                       categories::CoreFoundationObjectiveC,
-                       os.str(), MethDLoc);
+    BR.EmitBasicReport(
+        MethDerived, Checker, "Incompatible instance method return type",
+        categories::CoreFoundationObjectiveC, os.str(), MethDLoc);
   }
 }
 
 static void CheckObjCInstMethSignature(const ObjCImplementationDecl *ID,
-                                       BugReporter& BR) {
+                                       BugReporter &BR,
+                                       const CheckerBase *Checker) {
 
   const ObjCInterfaceDecl *D = ID->getClassInterface();
   const ObjCInterfaceDecl *C = D->getSuperClass();
@@ -92,10 +93,7 @@
   MapTy IMeths;
   unsigned NumMethods = 0;
 
-  for (ObjCImplementationDecl::instmeth_iterator I=ID->instmeth_begin(),
-       E=ID->instmeth_end(); I!=E; ++I) {
-
-    ObjCMethodDecl *M = *I;
+  for (auto *M : ID->instance_methods()) {
     IMeths[M->getSelector()] = M;
     ++NumMethods;
   }
@@ -103,22 +101,19 @@
   // Now recurse the class hierarchy chain looking for methods with the
   // same signatures.
   while (C && NumMethods) {
-    for (ObjCInterfaceDecl::instmeth_iterator I=C->instmeth_begin(),
-         E=C->instmeth_end(); I!=E; ++I) {
-
-      ObjCMethodDecl *M = *I;
+    for (const auto *M : C->instance_methods()) {
       Selector S = M->getSelector();
 
       MapTy::iterator MI = IMeths.find(S);
 
-      if (MI == IMeths.end() || MI->second == 0)
+      if (MI == IMeths.end() || MI->second == nullptr)
         continue;
 
       --NumMethods;
       ObjCMethodDecl *MethDerived = MI->second;
-      MI->second = 0;
+      MI->second = nullptr;
 
-      CompareReturnTypes(MethDerived, M, BR, Ctx, ID);
+      CompareReturnTypes(MethDerived, M, BR, Ctx, ID, Checker);
     }
 
     C = C->getSuperClass();
@@ -135,7 +130,7 @@
 public:
   void checkASTDecl(const ObjCImplementationDecl *D, AnalysisManager& mgr,
                     BugReporter &BR) const {
-    CheckObjCInstMethSignature(D, BR);
+    CheckObjCInstMethSignature(D, BR, this);
   }
 };
 }
diff --git a/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp b/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
index 415d3ec..45768b2 100644
--- a/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
+++ b/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
@@ -46,8 +46,18 @@
   DefaultBool check_vfork;
   DefaultBool check_FloatLoopCounter;
   DefaultBool check_UncheckedReturn;
+
+  CheckName checkName_gets;
+  CheckName checkName_getpw;
+  CheckName checkName_mktemp;
+  CheckName checkName_mkstemp;
+  CheckName checkName_strcpy;
+  CheckName checkName_rand;
+  CheckName checkName_vfork;
+  CheckName checkName_FloatLoopCounter;
+  CheckName checkName_UncheckedReturn;
 };
-  
+
 class WalkAST : public StmtVisitor<WalkAST> {
   BugReporter &BR;
   AnalysisDeclContext* AC;
@@ -139,7 +149,7 @@
     .Case("rand_r", &WalkAST::checkCall_rand)
     .Case("random", &WalkAST::checkCall_random)
     .Case("vfork", &WalkAST::checkCall_vfork)
-    .Default(NULL);
+    .Default(nullptr);
 
   // If the callee isn't defined, it is not of security concern.
   // Check and evaluate the call.
@@ -179,7 +189,7 @@
   if (const BinaryOperator *B = dyn_cast<BinaryOperator>(expr)) {
     if (!(B->isAssignmentOp() || B->isCompoundAssignmentOp() ||
           B->getOpcode() == BO_Comma))
-      return NULL;
+      return nullptr;
 
     if (const DeclRefExpr *lhs = getIncrementedVar(B->getLHS(), x, y))
       return lhs;
@@ -187,19 +197,19 @@
     if (const DeclRefExpr *rhs = getIncrementedVar(B->getRHS(), x, y))
       return rhs;
 
-    return NULL;
+    return nullptr;
   }
 
   if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(expr)) {
     const NamedDecl *ND = DR->getDecl();
-    return ND == x || ND == y ? DR : NULL;
+    return ND == x || ND == y ? DR : nullptr;
   }
 
   if (const UnaryOperator *U = dyn_cast<UnaryOperator>(expr))
     return U->isIncrementDecrementOp()
-      ? getIncrementedVar(U->getSubExpr(), x, y) : NULL;
+      ? getIncrementedVar(U->getSubExpr(), x, y) : nullptr;
 
-  return NULL;
+  return nullptr;
 }
 
 /// CheckLoopConditionForFloat - This check looks for 'for' statements that
@@ -243,14 +253,14 @@
     dyn_cast<DeclRefExpr>(B->getRHS()->IgnoreParenLValueCasts());
 
   // Does at least one of the variables have a floating point type?
-  drLHS = drLHS && drLHS->getType()->isRealFloatingType() ? drLHS : NULL;
-  drRHS = drRHS && drRHS->getType()->isRealFloatingType() ? drRHS : NULL;
+  drLHS = drLHS && drLHS->getType()->isRealFloatingType() ? drLHS : nullptr;
+  drRHS = drRHS && drRHS->getType()->isRealFloatingType() ? drRHS : nullptr;
 
   if (!drLHS && !drRHS)
     return;
 
-  const VarDecl *vdLHS = drLHS ? dyn_cast<VarDecl>(drLHS->getDecl()) : NULL;
-  const VarDecl *vdRHS = drRHS ? dyn_cast<VarDecl>(drRHS->getDecl()) : NULL;
+  const VarDecl *vdLHS = drLHS ? dyn_cast<VarDecl>(drLHS->getDecl()) : nullptr;
+  const VarDecl *vdRHS = drRHS ? dyn_cast<VarDecl>(drRHS->getDecl()) : nullptr;
 
   if (!vdLHS && !vdRHS)
     return;
@@ -281,7 +291,7 @@
 
   PathDiagnosticLocation FSLoc =
     PathDiagnosticLocation::createBegin(FS, BR.getSourceManager(), AC);
-  BR.EmitBasicReport(AC->getDecl(),
+  BR.EmitBasicReport(AC->getDecl(), filter.checkName_FloatLoopCounter,
                      bugType, "Security", os.str(),
                      FSLoc, ranges);
 }
@@ -302,11 +312,11 @@
     return;
 
   // Verify that the function takes a single argument.
-  if (FPT->getNumArgs() != 1)
+  if (FPT->getNumParams() != 1)
     return;
 
   // Is the argument a 'char*'?
-  const PointerType *PT = FPT->getArgType(0)->getAs<PointerType>();
+  const PointerType *PT = FPT->getParamType(0)->getAs<PointerType>();
   if (!PT)
     return;
 
@@ -316,7 +326,7 @@
   // Issue a warning.
   PathDiagnosticLocation CELoc =
     PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
-  BR.EmitBasicReport(AC->getDecl(),
+  BR.EmitBasicReport(AC->getDecl(), filter.checkName_gets,
                      "Potential buffer overflow in call to 'gets'",
                      "Security",
                      "Call to function 'gets' is extremely insecure as it can "
@@ -338,15 +348,15 @@
     return;
 
   // Verify that the function takes two arguments.
-  if (FPT->getNumArgs() != 2)
+  if (FPT->getNumParams() != 2)
     return;
 
   // Verify the first argument type is integer.
-  if (!FPT->getArgType(0)->isIntegralOrUnscopedEnumerationType())
+  if (!FPT->getParamType(0)->isIntegralOrUnscopedEnumerationType())
     return;
 
   // Verify the second argument type is char*.
-  const PointerType *PT = FPT->getArgType(1)->getAs<PointerType>();
+  const PointerType *PT = FPT->getParamType(1)->getAs<PointerType>();
   if (!PT)
     return;
 
@@ -356,7 +366,7 @@
   // Issue a warning.
   PathDiagnosticLocation CELoc =
     PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
-  BR.EmitBasicReport(AC->getDecl(),
+  BR.EmitBasicReport(AC->getDecl(), filter.checkName_getpw,
                      "Potential buffer overflow in call to 'getpw'",
                      "Security",
                      "The getpw() function is dangerous as it may overflow the "
@@ -382,11 +392,11 @@
     return;
 
   // Verify that the function takes a single argument.
-  if (FPT->getNumArgs() != 1)
+  if (FPT->getNumParams() != 1)
     return;
 
   // Verify that the argument is Pointer Type.
-  const PointerType *PT = FPT->getArgType(0)->getAs<PointerType>();
+  const PointerType *PT = FPT->getParamType(0)->getAs<PointerType>();
   if (!PT)
     return;
 
@@ -394,10 +404,10 @@
   if (PT->getPointeeType().getUnqualifiedType() != BR.getContext().CharTy)
     return;
 
-  // Issue a waring.
+  // Issue a warning.
   PathDiagnosticLocation CELoc =
     PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
-  BR.EmitBasicReport(AC->getDecl(),
+  BR.EmitBasicReport(AC->getDecl(), filter.checkName_mktemp,
                      "Potential insecure temporary file in call 'mktemp'",
                      "Security",
                      "Call to function 'mktemp' is insecure as it always "
@@ -483,7 +493,7 @@
     out << " used as a suffix";
   }
   out << ')';
-  BR.EmitBasicReport(AC->getDecl(),
+  BR.EmitBasicReport(AC->getDecl(), filter.checkName_mkstemp,
                      "Insecure temporary file creation", "Security",
                      out.str(), CELoc, strArg->getSourceRange());
 }
@@ -504,7 +514,7 @@
   // Issue a warning.
   PathDiagnosticLocation CELoc =
     PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
-  BR.EmitBasicReport(AC->getDecl(),
+  BR.EmitBasicReport(AC->getDecl(), filter.checkName_strcpy,
                      "Potential insecure memory buffer bounds restriction in "
                      "call 'strcpy'",
                      "Security",
@@ -531,7 +541,7 @@
   // Issue a warning.
   PathDiagnosticLocation CELoc =
     PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
-  BR.EmitBasicReport(AC->getDecl(),
+  BR.EmitBasicReport(AC->getDecl(), filter.checkName_strcpy,
                      "Potential insecure memory buffer bounds restriction in "
                      "call 'strcat'",
                      "Security",
@@ -551,14 +561,14 @@
     return false;
 
   // Verify the function takes two arguments, three in the _chk version.
-  int numArgs = FPT->getNumArgs();
+  int numArgs = FPT->getNumParams();
   if (numArgs != 2 && numArgs != 3)
     return false;
 
   // Verify the type for both arguments.
   for (int i = 0; i < 2; i++) {
     // Verify that the arguments are pointers.
-    const PointerType *PT = FPT->getArgType(i)->getAs<PointerType>();
+    const PointerType *PT = FPT->getParamType(i)->getAs<PointerType>();
     if (!PT)
       return false;
 
@@ -584,17 +594,16 @@
   if (!FTP)
     return;
 
-  if (FTP->getNumArgs() == 1) {
+  if (FTP->getNumParams() == 1) {
     // Is the argument an 'unsigned short *'?
     // (Actually any integer type is allowed.)
-    const PointerType *PT = FTP->getArgType(0)->getAs<PointerType>();
+    const PointerType *PT = FTP->getParamType(0)->getAs<PointerType>();
     if (!PT)
       return;
 
     if (! PT->getPointeeType()->isIntegralOrUnscopedEnumerationType())
       return;
-  }
-  else if (FTP->getNumArgs() != 0)
+  } else if (FTP->getNumParams() != 0)
     return;
 
   // Issue a warning.
@@ -610,8 +619,9 @@
 
   PathDiagnosticLocation CELoc =
     PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
-  BR.EmitBasicReport(AC->getDecl(), os1.str(), "Security", os2.str(),
-                     CELoc, CE->getCallee()->getSourceRange());
+  BR.EmitBasicReport(AC->getDecl(), filter.checkName_rand, os1.str(),
+                     "Security", os2.str(), CELoc,
+                     CE->getCallee()->getSourceRange());
 }
 
 //===----------------------------------------------------------------------===//
@@ -628,13 +638,13 @@
     return;
 
   // Verify that the function takes no argument.
-  if (FTP->getNumArgs() != 0)
+  if (FTP->getNumParams() != 0)
     return;
 
   // Issue a warning.
   PathDiagnosticLocation CELoc =
     PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
-  BR.EmitBasicReport(AC->getDecl(),
+  BR.EmitBasicReport(AC->getDecl(), filter.checkName_rand,
                      "'random' is not a secure random number generator",
                      "Security",
                      "The 'random' function produces a sequence of values that "
@@ -654,7 +664,7 @@
   // All calls to vfork() are insecure, issue a warning.
   PathDiagnosticLocation CELoc =
     PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
-  BR.EmitBasicReport(AC->getDecl(),
+  BR.EmitBasicReport(AC->getDecl(), filter.checkName_vfork,
                      "Potential insecure implementation-specific behavior in "
                      "call 'vfork'",
                      "Security",
@@ -678,7 +688,7 @@
   if (!FD)
     return;
 
-  if (II_setid[0] == NULL) {
+  if (II_setid[0] == nullptr) {
     static const char * const identifiers[num_setids] = {
       "setuid", "setgid", "seteuid", "setegid",
       "setreuid", "setregid"
@@ -704,12 +714,12 @@
 
   // Verify that the function takes one or two arguments (depending on
   //   the function).
-  if (FTP->getNumArgs() != (identifierid < 4 ? 1 : 2))
+  if (FTP->getNumParams() != (identifierid < 4 ? 1 : 2))
     return;
 
   // The arguments must be integers.
-  for (unsigned i = 0; i < FTP->getNumArgs(); i++)
-    if (! FTP->getArgType(i)->isIntegralOrUnscopedEnumerationType())
+  for (unsigned i = 0; i < FTP->getNumParams(); i++)
+    if (!FTP->getParamType(i)->isIntegralOrUnscopedEnumerationType())
       return;
 
   // Issue a warning.
@@ -725,8 +735,9 @@
 
   PathDiagnosticLocation CELoc =
     PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
-  BR.EmitBasicReport(AC->getDecl(), os1.str(), "Security", os2.str(),
-                     CELoc, CE->getCallee()->getSourceRange());
+  BR.EmitBasicReport(AC->getDecl(), filter.checkName_UncheckedReturn, os1.str(),
+                     "Security", os2.str(), CELoc,
+                     CE->getCallee()->getSourceRange());
 }
 
 //===----------------------------------------------------------------------===//
@@ -746,10 +757,13 @@
 };
 }
 
-#define REGISTER_CHECKER(name) \
-void ento::register##name(CheckerManager &mgr) {\
-  mgr.registerChecker<SecuritySyntaxChecker>()->filter.check_##name = true;\
-}
+#define REGISTER_CHECKER(name)                                                 \
+  void ento::register##name(CheckerManager &mgr) {                             \
+    SecuritySyntaxChecker *checker =                                           \
+        mgr.registerChecker<SecuritySyntaxChecker>();                          \
+    checker->filter.check_##name = true;                                       \
+    checker->filter.checkName_##name = mgr.getCurrentCheckName();              \
+  }
 
 REGISTER_CHECKER(gets)
 REGISTER_CHECKER(getpw)
diff --git a/lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp b/lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp
index 1207b67..a61e658 100644
--- a/lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp
+++ b/lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp
@@ -24,10 +24,12 @@
 namespace {
 class WalkAST : public StmtVisitor<WalkAST> {
   BugReporter &BR;
+  const CheckerBase *Checker;
   AnalysisDeclContext* AC;
 
 public:
-  WalkAST(BugReporter &br, AnalysisDeclContext* ac) : BR(br), AC(ac) {}
+  WalkAST(BugReporter &br, const CheckerBase *checker, AnalysisDeclContext *ac)
+      : BR(br), Checker(checker), AC(ac) {}
   void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E);
   void VisitStmt(Stmt *S) { VisitChildren(S); }
   void VisitChildren(Stmt *S);
@@ -45,7 +47,7 @@
   if (E->getKind() != UETT_SizeOf)
     return;
 
-  // If an explicit type is used in the code, usually the coder knows what he is
+  // If an explicit type is used in the code, usually the coder knows what they are
   // doing.
   if (E->isArgumentType())
     return;
@@ -62,7 +64,7 @@
 
     PathDiagnosticLocation ELoc =
       PathDiagnosticLocation::createBegin(E, BR.getSourceManager(), AC);
-    BR.EmitBasicReport(AC->getDecl(),
+    BR.EmitBasicReport(AC->getDecl(), Checker,
                        "Potential unintended use of sizeof() on pointer type",
                        categories::LogicError,
                        "The code calls sizeof() on a pointer type. "
@@ -80,7 +82,7 @@
 public:
   void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
                         BugReporter &BR) const {
-    WalkAST walker(BR, mgr.getAnalysisDeclContext(D));
+    WalkAST walker(BR, this, mgr.getAnalysisDeclContext(D));
     walker.Visit(D->getBody());
   }
 };
diff --git a/lib/StaticAnalyzer/Checkers/Checkers.td b/lib/StaticAnalyzer/Checkers/Checkers.td
index 862212d..44eb641 100644
--- a/lib/StaticAnalyzer/Checkers/Checkers.td
+++ b/lib/StaticAnalyzer/Checkers/Checkers.td
@@ -120,6 +120,14 @@
   HelpText<"Warn about unintended use of sizeof() on pointer expressions">,
   DescFile<"CheckSizeofPointer.cpp">;
 
+def CallAndMessageUnInitRefArg : Checker<"CallAndMessageUnInitRefArg">,
+  HelpText<"Check for logical errors for function calls and Objective-C message expressions (e.g., uninitialized arguments, null function pointers, and pointer to undefined variables)">,
+  DescFile<"CallAndMessageChecker.cpp">;
+
+def TestAfterDivZeroChecker : Checker<"TestAfterDivZero">,
+  HelpText<"Check for division by variable that is later compared against 0. Either the comparison is useless or there is division by zero.">,
+  DescFile<"TestAfterDivZeroChecker.cpp">;
+
 } // end "alpha.core"
 
 //===----------------------------------------------------------------------===//
@@ -203,10 +211,6 @@
 
 let ParentPackage = DeadCodeAlpha in {
 
-def IdempotentOperationChecker : Checker<"IdempotentOperations">,
-  HelpText<"Warn about idempotent operations">,
-  DescFile<"IdempotentOperationChecker.cpp">;
-
 def UnreachableCodeChecker : Checker<"UnreachableCode">,
   HelpText<"Check unreachable code">,
   DescFile<"UnreachableCodeChecker.cpp">;
@@ -416,6 +420,10 @@
   HelpText<"Model the APIs that are guaranteed to return a non-nil value">,
   DescFile<"BasicObjCFoundationChecks.cpp">;
 
+def ObjCSuperCallChecker : Checker<"MissingSuperCall">,
+  HelpText<"Warn about Objective-C methods that lack a necessary call to super">,
+  DescFile<"ObjCMissingSuperCallChecker.cpp">;
+
 def NSErrorChecker : Checker<"NSError">,
   HelpText<"Check usage of NSError** parameters">,
   DescFile<"NSErrorChecker.cpp">;
@@ -448,10 +456,6 @@
   HelpText<"Check for direct assignments to instance variables in the methods annotated with objc_no_direct_instance_variable_assignment">,
   DescFile<"DirectIvarAssignment.cpp">;
 
-def ObjCSuperCallChecker : Checker<"MissingSuperCall">,
-  HelpText<"Warn about Objective-C methods that lack a necessary call to super">,
-  DescFile<"ObjCMissingSuperCallChecker.cpp">;
-
 } // end "alpha.osx.cocoa"
 
 let ParentPackage = CoreFoundation in {
diff --git a/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp b/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp
index 9912965..ad41577 100644
--- a/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp
@@ -41,11 +41,11 @@
 class ChrootChecker : public Checker<eval::Call, check::PreStmt<CallExpr> > {
   mutable IdentifierInfo *II_chroot, *II_chdir;
   // This bug refers to possibly break out of a chroot() jail.
-  mutable OwningPtr<BuiltinBug> BT_BreakJail;
+  mutable std::unique_ptr<BuiltinBug> BT_BreakJail;
 
 public:
-  ChrootChecker() : II_chroot(0), II_chdir(0) {}
-  
+  ChrootChecker() : II_chroot(nullptr), II_chdir(nullptr) {}
+
   static void *getTag() {
     static int x;
     return &x;
@@ -142,9 +142,9 @@
     if (isRootChanged((intptr_t) *k))
       if (ExplodedNode *N = C.addTransition()) {
         if (!BT_BreakJail)
-          BT_BreakJail.reset(new BuiltinBug("Break out of jail",
-                                        "No call of chdir(\"/\") immediately "
-                                        "after chroot"));
+          BT_BreakJail.reset(new BuiltinBug(
+              this, "Break out of jail", "No call of chdir(\"/\") immediately "
+                                         "after chroot"));
         BugReport *R = new BugReport(*BT_BreakJail, 
                                      BT_BreakJail->getDescription(), N);
         C.emitReport(R);
diff --git a/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp b/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
index 9d855ce..c1ea767 100644
--- a/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
@@ -124,21 +124,23 @@
   const CFG &cfg;
   ASTContext &Ctx;
   BugReporter& BR;
+  const CheckerBase *Checker;
   AnalysisDeclContext* AC;
   ParentMap& Parents;
   llvm::SmallPtrSet<const VarDecl*, 20> Escaped;
-  OwningPtr<ReachableCode> reachableCode;
+  std::unique_ptr<ReachableCode> reachableCode;
   const CFGBlock *currentBlock;
-  OwningPtr<llvm::DenseSet<const VarDecl *> > InEH;
+  std::unique_ptr<llvm::DenseSet<const VarDecl *>> InEH;
 
   enum DeadStoreKind { Standard, Enclosing, DeadIncrement, DeadInit };
 
 public:
-  DeadStoreObs(const CFG &cfg, ASTContext &ctx,
-               BugReporter& br, AnalysisDeclContext* ac, ParentMap& parents,
-               llvm::SmallPtrSet<const VarDecl*, 20> &escaped)
-    : cfg(cfg), Ctx(ctx), BR(br), AC(ac), Parents(parents),
-      Escaped(escaped), currentBlock(0) {}
+  DeadStoreObs(const CFG &cfg, ASTContext &ctx, BugReporter &br,
+               const CheckerBase *checker, AnalysisDeclContext *ac,
+               ParentMap &parents,
+               llvm::SmallPtrSet<const VarDecl *, 20> &escaped)
+      : cfg(cfg), Ctx(ctx), BR(br), Checker(checker), AC(ac), Parents(parents),
+        Escaped(escaped), currentBlock(nullptr) {}
 
   virtual ~DeadStoreObs() {}
 
@@ -176,7 +178,7 @@
 
     SmallString<64> buf;
     llvm::raw_svector_ostream os(buf);
-    const char *BugType = 0;
+    const char *BugType = nullptr;
 
     switch (dsk) {
       case DeadInit:
@@ -199,7 +201,8 @@
         return;
     }
 
-    BR.EmitBasicReport(AC->getDecl(), BugType, "Dead store", os.str(), L, R);
+    BR.EmitBasicReport(AC->getDecl(), Checker, BugType, "Dead store", os.str(),
+                       L, R);
   }
 
   void CheckVarDecl(const VarDecl *VD, const Expr *Ex, const Expr *Val,
@@ -214,7 +217,8 @@
       return;
 
     if (!isLive(Live, VD) &&
-        !(VD->getAttr<UnusedAttr>() || VD->getAttr<BlocksAttr>())) {
+        !(VD->hasAttr<UnusedAttr>() || VD->hasAttr<BlocksAttr>() ||
+          VD->hasAttr<ObjCPreciseLifetimeAttr>())) {
 
       PathDiagnosticLocation ExLoc =
         PathDiagnosticLocation::createBegin(Ex, BR.getSourceManager(), AC);
@@ -251,8 +255,8 @@
     return false;
   }
 
-  virtual void observeStmt(const Stmt *S, const CFGBlock *block,
-                           const LiveVariables::LivenessValues &Live) {
+  void observeStmt(const Stmt *S, const CFGBlock *block,
+                   const LiveVariables::LivenessValues &Live) override {
 
     currentBlock = block;
     
@@ -309,10 +313,8 @@
     else if (const DeclStmt *DS = dyn_cast<DeclStmt>(S))
       // Iterate through the decls.  Warn if any initializers are complex
       // expressions that are not live (never used).
-      for (DeclStmt::const_decl_iterator DI=DS->decl_begin(), DE=DS->decl_end();
-           DI != DE; ++DI) {
-
-        VarDecl *V = dyn_cast<VarDecl>(*DI);
+      for (const auto *DI : DS->decls()) {
+        const auto *V = dyn_cast<VarDecl>(DI);
 
         if (!V)
           continue;
@@ -339,8 +341,10 @@
             
             // A dead initialization is a variable that is dead after it
             // is initialized.  We don't flag warnings for those variables
-            // marked 'unused'.
-            if (!isLive(Live, V) && V->getAttr<UnusedAttr>() == 0) {
+            // marked 'unused' or 'objc_precise_lifetime'.
+            if (!isLive(Live, V) &&
+                !V->hasAttr<UnusedAttr>() &&
+                !V->hasAttr<ObjCPreciseLifetimeAttr>()) {
               // Special case: check for initializations with constants.
               //
               //  e.g. : int x = 0;
@@ -436,7 +440,7 @@
       ParentMap &pmap = mgr.getParentMap(D);
       FindEscaped FS;
       cfg.VisitBlockStmts(FS);
-      DeadStoreObs A(cfg, BR.getContext(), BR, AC, pmap, FS.Escaped);
+      DeadStoreObs A(cfg, BR.getContext(), BR, this, AC, pmap, FS.Escaped);
       L->runOnAllBlocks(A);
     }
   }
diff --git a/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp b/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp
index a2c8d1f..51e7a3d 100644
--- a/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp
+++ b/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp
@@ -95,6 +95,11 @@
 public:
   void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
                         BugReporter &BR) const {
+    PrintingPolicy Policy(mgr.getLangOpts());
+    Policy.TerseOutput = true;
+    Policy.PolishForDeclaration = true;
+    D->print(llvm::errs(), Policy);
+
     if (CFG *cfg = mgr.getCFG(D)) {
       cfg->dump(mgr.getLangOpts(),
                 llvm::sys::Process::StandardErrHasColors());
diff --git a/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp b/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
index 72d46c5..4ee0223 100644
--- a/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
@@ -29,8 +29,8 @@
     : public Checker< check::Location,
                       check::Bind,
                       EventDispatcher<ImplicitNullDerefEvent> > {
-  mutable OwningPtr<BuiltinBug> BT_null;
-  mutable OwningPtr<BuiltinBug> BT_undef;
+  mutable std::unique_ptr<BuiltinBug> BT_null;
+  mutable std::unique_ptr<BuiltinBug> BT_undef;
 
   void reportBug(ProgramStateRef State, const Stmt *S, CheckerContext &C,
                  bool IsBind = false) const;
@@ -97,7 +97,7 @@
   // We know that 'location' cannot be non-null.  This is what
   // we call an "explicit" null dereference.
   if (!BT_null)
-    BT_null.reset(new BuiltinBug("Dereference of null pointer"));
+    BT_null.reset(new BuiltinBug(this, "Dereference of null pointer"));
 
   SmallString<100> buf;
   llvm::raw_svector_ostream os(buf);
@@ -126,7 +126,7 @@
     os << "Array access";
     const ArraySubscriptExpr *AE = cast<ArraySubscriptExpr>(S);
     AddDerefSource(os, Ranges, AE->getBase()->IgnoreParenCasts(),
-                   State.getPtr(), N->getLocationContext());
+                   State.get(), N->getLocationContext());
     os << " results in a null pointer dereference";
     break;
   }
@@ -134,7 +134,7 @@
     os << "Dereference of null pointer";
     const UnaryOperator *U = cast<UnaryOperator>(S);
     AddDerefSource(os, Ranges, U->getSubExpr()->IgnoreParens(),
-                   State.getPtr(), N->getLocationContext(), true);
+                   State.get(), N->getLocationContext(), true);
     break;
   }
   case Stmt::MemberExprClass: {
@@ -143,7 +143,7 @@
       os << "Access to field '" << M->getMemberNameInfo()
          << "' results in a dereference of a null pointer";
       AddDerefSource(os, Ranges, M->getBase()->IgnoreParenCasts(),
-                     State.getPtr(), N->getLocationContext(), true);
+                     State.get(), N->getLocationContext(), true);
     }
     break;
   }
@@ -152,7 +152,7 @@
     os << "Access to instance variable '" << *IV->getDecl()
        << "' results in a dereference of a null pointer";
     AddDerefSource(os, Ranges, IV->getBase()->IgnoreParenCasts(),
-                   State.getPtr(), N->getLocationContext(), true);
+                   State.get(), N->getLocationContext(), true);
     break;
   }
   default:
@@ -180,7 +180,8 @@
   if (l.isUndef()) {
     if (ExplodedNode *N = C.generateSink()) {
       if (!BT_undef)
-        BT_undef.reset(new BuiltinBug("Dereference of undefined pointer value"));
+        BT_undef.reset(
+            new BuiltinBug(this, "Dereference of undefined pointer value"));
 
       BugReport *report =
         new BugReport(*BT_undef, BT_undef->getDescription(), N);
@@ -200,7 +201,7 @@
   ProgramStateRef state = C.getState();
 
   ProgramStateRef notNullState, nullState;
-  llvm::tie(notNullState, nullState) = state->assume(location);
+  std::tie(notNullState, nullState) = state->assume(location);
 
   // The explicit NULL case.
   if (nullState) {
@@ -239,8 +240,7 @@
   ProgramStateRef State = C.getState();
 
   ProgramStateRef StNonNull, StNull;
-  llvm::tie(StNonNull, StNull) =
-      State->assume(V.castAs<DefinedOrUnknownSVal>());
+  std::tie(StNonNull, StNull) = State->assume(V.castAs<DefinedOrUnknownSVal>());
 
   if (StNull) {
     if (!StNonNull) {
diff --git a/lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp b/lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp
index b43dc18..0bcebf6 100644
--- a/lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp
+++ b/lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp
@@ -63,13 +63,15 @@
     const ObjCMethodDecl *MD;
     const ObjCInterfaceDecl *InterfD;
     BugReporter &BR;
+    const CheckerBase *Checker;
     LocationOrAnalysisDeclContext DCtx;
 
   public:
     MethodCrawler(const IvarToPropertyMapTy &InMap, const ObjCMethodDecl *InMD,
-        const ObjCInterfaceDecl *InID,
-        BugReporter &InBR, AnalysisDeclContext *InDCtx)
-    : IvarToPropMap(InMap), MD(InMD), InterfD(InID), BR(InBR), DCtx(InDCtx) {}
+                  const ObjCInterfaceDecl *InID, BugReporter &InBR,
+                  const CheckerBase *Checker, AnalysisDeclContext *InDCtx)
+        : IvarToPropMap(InMap), MD(InMD), InterfD(InID), BR(InBR),
+          Checker(Checker), DCtx(InDCtx) {}
 
     void VisitStmt(const Stmt *S) { VisitChildren(S); }
 
@@ -122,10 +124,7 @@
   IvarToPropertyMapTy IvarToPropMap;
 
   // Find all properties for this class.
-  for (ObjCInterfaceDecl::prop_iterator I = InterD->prop_begin(),
-      E = InterD->prop_end(); I != E; ++I) {
-    ObjCPropertyDecl *PD = *I;
-
+  for (const auto *PD : InterD->properties()) {
     // Find the corresponding IVar.
     const ObjCIvarDecl *ID = findPropertyBackingIvar(PD, InterD,
                                                      Mgr.getASTContext());
@@ -140,10 +139,7 @@
   if (IvarToPropMap.empty())
     return;
 
-  for (ObjCImplementationDecl::instmeth_iterator I = D->instmeth_begin(),
-      E = D->instmeth_end(); I != E; ++I) {
-
-    ObjCMethodDecl *M = *I;
+  for (const auto *M : D->instance_methods()) {
     AnalysisDeclContext *DCtx = Mgr.getAnalysisDeclContext(M);
 
     if ((*ShouldSkipMethod)(M))
@@ -152,20 +148,17 @@
     const Stmt *Body = M->getBody();
     assert(Body);
 
-    MethodCrawler MC(IvarToPropMap, M->getCanonicalDecl(), InterD, BR, DCtx);
+    MethodCrawler MC(IvarToPropMap, M->getCanonicalDecl(), InterD, BR, this,
+                     DCtx);
     MC.VisitStmt(Body);
   }
 }
 
 static bool isAnnotatedToAllowDirectAssignment(const Decl *D) {
-  for (specific_attr_iterator<AnnotateAttr>
-       AI = D->specific_attr_begin<AnnotateAttr>(),
-       AE = D->specific_attr_end<AnnotateAttr>(); AI != AE; ++AI) {
-    const AnnotateAttr *Ann = *AI;
+  for (const auto *Ann : D->specific_attrs<AnnotateAttr>())
     if (Ann->getAnnotation() ==
         "objc_allow_direct_instance_variable_assignment")
       return true;
-  }
   return false;
 }
 
@@ -204,13 +197,11 @@
       if (GetterMethod && GetterMethod->getCanonicalDecl() == MD)
         return;
 
-      BR.EmitBasicReport(MD,
-          "Property access",
-          categories::CoreFoundationObjectiveC,
+      BR.EmitBasicReport(
+          MD, Checker, "Property access", categories::CoreFoundationObjectiveC,
           "Direct assignment to an instance variable backing a property; "
-          "use the setter instead", PathDiagnosticLocation(IvarRef,
-                                                          BR.getSourceManager(),
-                                                          DCtx));
+          "use the setter instead",
+          PathDiagnosticLocation(IvarRef, BR.getSourceManager(), DCtx));
     }
   }
 }
@@ -225,14 +216,9 @@
 // Register the checker that checks for direct accesses in functions annotated
 // with __attribute__((annotate("objc_no_direct_instance_variable_assignment"))).
 static bool AttrFilter(const ObjCMethodDecl *M) {
-  for (specific_attr_iterator<AnnotateAttr>
-           AI = M->specific_attr_begin<AnnotateAttr>(),
-           AE = M->specific_attr_end<AnnotateAttr>();
-       AI != AE; ++AI) {
-    const AnnotateAttr *Ann = *AI;
+  for (const auto *Ann : M->specific_attrs<AnnotateAttr>())
     if (Ann->getAnnotation() == "objc_no_direct_instance_variable_assignment")
       return false;
-  }
   return true;
 }
 
diff --git a/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp b/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp
index 93daf94..e060c36 100644
--- a/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp
@@ -23,7 +23,7 @@
 
 namespace {
 class DivZeroChecker : public Checker< check::PreStmt<BinaryOperator> > {
-  mutable OwningPtr<BuiltinBug> BT;
+  mutable std::unique_ptr<BuiltinBug> BT;
   void reportBug(const char *Msg,
                  ProgramStateRef StateZero,
                  CheckerContext &C) const ;
@@ -37,7 +37,7 @@
                                CheckerContext &C) const {
   if (ExplodedNode *N = C.generateSink(StateZero)) {
     if (!BT)
-      BT.reset(new BuiltinBug("Division by zero"));
+      BT.reset(new BuiltinBug(this, "Division by zero"));
 
     BugReport *R = new BugReport(*BT, Msg, N);
     bugreporter::trackNullOrUndefValue(N, bugreporter::GetDenomExpr(N), *R);
@@ -68,7 +68,7 @@
   // Check for divide by zero.
   ConstraintManager &CM = C.getConstraintManager();
   ProgramStateRef stateNotZero, stateZero;
-  llvm::tie(stateNotZero, stateZero) = CM.assumeDual(C.getState(), *DV);
+  std::tie(stateNotZero, stateZero) = CM.assumeDual(C.getState(), *DV);
 
   if (!stateNotZero) {
     assert(stateZero);
diff --git a/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp b/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
index 7116e4d..43a2812 100644
--- a/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
+++ b/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
@@ -223,7 +223,7 @@
 
   const Expr *RecE = MsgE->getInstanceReceiver();
   if (!RecE)
-    return 0;
+    return nullptr;
 
   RecE= RecE->IgnoreParenImpCasts();
   if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(RecE)) {
@@ -237,7 +237,7 @@
           return ObjTy;
     }
   }
-  return 0;
+  return nullptr;
 }
 
 // Return a better dynamic type if one can be derived from the cast.
@@ -253,7 +253,7 @@
   const ObjCObjectPointerType *NewTy =
       CastE->getType()->getAs<ObjCObjectPointerType>();
   if (!NewTy)
-    return 0;
+    return nullptr;
   QualType OldDTy = C.getState()->getDynamicTypeInfo(ToR).getType();
   if (OldDTy.isNull()) {
     return NewTy;
@@ -261,7 +261,7 @@
   const ObjCObjectPointerType *OldTy =
     OldDTy->getAs<ObjCObjectPointerType>();
   if (!OldTy)
-    return 0;
+    return nullptr;
 
   // Id the old type is 'id', the new one is more precise.
   if (OldTy->isObjCIdType() && !NewTy->isObjCIdType())
@@ -273,7 +273,7 @@
   if (ToI && FromI && FromI->isSuperClassOf(ToI))
     return NewTy;
 
-  return 0;
+  return nullptr;
 }
 
 void ento::registerDynamicTypePropagation(CheckerManager &mgr) {
diff --git a/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp b/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
index 3ed2435..f36ec2c 100644
--- a/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
@@ -18,7 +18,7 @@
 
 namespace {
 class ExprInspectionChecker : public Checker< eval::Call > {
-  mutable OwningPtr<BugType> BT;
+  mutable std::unique_ptr<BugType> BT;
 
   void analyzerEval(const CallExpr *CE, CheckerContext &C) const;
   void analyzerCheckInlined(const CallExpr *CE, CheckerContext &C) const;
@@ -43,7 +43,7 @@
           &ExprInspectionChecker::analyzerCheckInlined)
     .Case("clang_analyzer_crash", &ExprInspectionChecker::analyzerCrash)
     .Case("clang_analyzer_warnIfReached", &ExprInspectionChecker::analyzerWarnIfReached)
-    .Default(0);
+    .Default(nullptr);
 
   if (!Handler)
     return false;
@@ -68,7 +68,7 @@
     return "UNDEFINED";
 
   ProgramStateRef StTrue, StFalse;
-  llvm::tie(StTrue, StFalse) =
+  std::tie(StTrue, StFalse) =
     State->assume(AssertionVal.castAs<DefinedOrUnknownSVal>());
 
   if (StTrue) {
@@ -91,11 +91,11 @@
 
   // A specific instantiation of an inlined function may have more constrained
   // values than can generally be assumed. Skip the check.
-  if (LC->getCurrentStackFrame()->getParent() != 0)
+  if (LC->getCurrentStackFrame()->getParent() != nullptr)
     return;
 
   if (!BT)
-    BT.reset(new BugType("Checking analyzer assumptions", "debug"));
+    BT.reset(new BugType(this, "Checking analyzer assumptions", "debug"));
 
   BugReport *R = new BugReport(*BT, getArgumentValueString(CE, C), N);
   C.emitReport(R);
@@ -106,7 +106,7 @@
   ExplodedNode *N = C.getPredecessor();
 
   if (!BT)
-    BT.reset(new BugType("Checking analyzer assumptions", "debug"));
+    BT.reset(new BugType(this, "Checking analyzer assumptions", "debug"));
 
   BugReport *R = new BugReport(*BT, "REACHABLE", N);
   C.emitReport(R);
@@ -122,11 +122,11 @@
   // when we are analyzing it as an inlined function. This means that
   // clang_analyzer_checkInlined(true) should always print TRUE, but
   // clang_analyzer_checkInlined(false) should never actually print anything.
-  if (LC->getCurrentStackFrame()->getParent() == 0)
+  if (LC->getCurrentStackFrame()->getParent() == nullptr)
     return;
 
   if (!BT)
-    BT.reset(new BugType("Checking analyzer assumptions", "debug"));
+    BT.reset(new BugType(this, "Checking analyzer assumptions", "debug"));
 
   BugReport *R = new BugReport(*BT, getArgumentValueString(CE, C), N);
   C.emitReport(R);
diff --git a/lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp b/lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp
index 085a991..60bb036 100644
--- a/lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp
@@ -25,7 +25,7 @@
 namespace {
 class FixedAddressChecker 
   : public Checker< check::PreStmt<BinaryOperator> > {
-  mutable OwningPtr<BuiltinBug> BT;
+  mutable std::unique_ptr<BuiltinBug> BT;
 
 public:
   void checkPreStmt(const BinaryOperator *B, CheckerContext &C) const;
@@ -52,10 +52,11 @@
 
   if (ExplodedNode *N = C.addTransition()) {
     if (!BT)
-      BT.reset(new BuiltinBug("Use fixed address", 
-                          "Using a fixed address is not portable because that "
-                          "address will probably not be valid in all "
-                          "environments or platforms."));
+      BT.reset(
+          new BuiltinBug(this, "Use fixed address",
+                         "Using a fixed address is not portable because that "
+                         "address will probably not be valid in all "
+                         "environments or platforms."));
     BugReport *R = new BugReport(*BT, BT->getDescription(), N);
     R->addRange(B->getRHS()->getSourceRange());
     C.emitReport(R);
diff --git a/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp b/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
index 1dc60c6..08ba26a 100644
--- a/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
@@ -34,7 +34,6 @@
   static void *getTag() { static int Tag; return &Tag; }
 
   void checkPostStmt(const CallExpr *CE, CheckerContext &C) const;
-  void checkPostStmt(const DeclRefExpr *DRE, CheckerContext &C) const;
 
   void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
 
@@ -43,10 +42,10 @@
   /// Denotes the return vale.
   static const unsigned ReturnValueIndex = UINT_MAX - 1;
 
-  mutable OwningPtr<BugType> BT;
+  mutable std::unique_ptr<BugType> BT;
   inline void initBugType() const {
     if (!BT)
-      BT.reset(new BugType("Use of Untrusted Data", "Untrusted Data"));
+      BT.reset(new BugType(this, "Use of Untrusted Data", "Untrusted Data"));
   }
 
   /// \brief Catch taint related bugs. Check if tainted data is passed to a
@@ -292,7 +291,7 @@
 
 void GenericTaintChecker::addSourcesPre(const CallExpr *CE,
                                         CheckerContext &C) const {
-  ProgramStateRef State = 0;
+  ProgramStateRef State = nullptr;
   const FunctionDecl *FDecl = C.getCalleeDecl(CE);
   if (!FDecl || FDecl->getKind() != Decl::Function)
     return;
@@ -315,7 +314,7 @@
   // Otherwise, check if we have custom pre-processing implemented.
   FnCheck evalFunction = llvm::StringSwitch<FnCheck>(Name)
     .Case("fscanf", &GenericTaintChecker::preFscanf)
-    .Default(0);
+    .Default(nullptr);
   // Check and evaluate the call.
   if (evalFunction)
     State = (this->*evalFunction)(CE, C);
@@ -389,11 +388,11 @@
     .Case("getch", &GenericTaintChecker::postRetTaint)
     .Case("wgetch", &GenericTaintChecker::postRetTaint)
     .Case("socket", &GenericTaintChecker::postSocket)
-    .Default(0);
+    .Default(nullptr);
 
   // If the callee isn't defined, it is not of security concern.
   // Check and evaluate the call.
-  ProgramStateRef State = 0;
+  ProgramStateRef State = nullptr;
   if (evalFunction)
     State = (this->*evalFunction)(CE, C);
   if (!State)
@@ -429,11 +428,11 @@
   ProgramStateRef State = C.getState();
   SVal AddrVal = State->getSVal(Arg->IgnoreParens(), C.getLocationContext());
   if (AddrVal.isUnknownOrUndef())
-    return 0;
+    return nullptr;
 
   Optional<Loc> AddrLoc = AddrVal.getAs<Loc>();
   if (!AddrLoc)
-    return 0;
+    return nullptr;
 
   const PointerType *ArgTy =
     dyn_cast<PointerType>(Arg->getType().getCanonicalType().getTypePtr());
@@ -527,7 +526,7 @@
     return State;
   }
 
-  return 0;
+  return nullptr;
 }
 
 
@@ -613,11 +612,7 @@
   const FunctionDecl *FDecl = C.getCalleeDecl(CE);
   if (!FDecl)
     return false;
-  for (specific_attr_iterator<FormatAttr>
-         i = FDecl->specific_attr_begin<FormatAttr>(),
-         e = FDecl->specific_attr_end<FormatAttr>(); i != e ; ++i) {
-
-    const FormatAttr *Format = *i;
+  for (const auto *Format : FDecl->specific_attrs<FormatAttr>()) {
     ArgNum = Format->getFormatIdx() - 1;
     if ((Format->getType()->getName() == "printf") &&
          CE->getNumArgs() > ArgNum)
diff --git a/lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp b/lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp
deleted file mode 100644
index 4997f8d..0000000
--- a/lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp
+++ /dev/null
@@ -1,737 +0,0 @@
-//==- IdempotentOperationChecker.cpp - Idempotent Operations ----*- C++ -*-==//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines a set of path-sensitive checks for idempotent and/or
-// tautological operations. Each potential operation is checked along all paths
-// to see if every path results in a pointless operation.
-//                 +-------------------------------------------+
-//                 |Table of idempotent/tautological operations|
-//                 +-------------------------------------------+
-//+--------------------------------------------------------------------------+
-//|Operator | x op x | x op 1 | 1 op x | x op 0 | 0 op x | x op ~0 | ~0 op x |
-//+--------------------------------------------------------------------------+
-//  +, +=   |        |        |        |   x    |   x    |         |
-//  -, -=   |        |        |        |   x    |   -x   |         |
-//  *, *=   |        |   x    |   x    |   0    |   0    |         |
-//  /, /=   |   1    |   x    |        |  N/A   |   0    |         |
-//  &, &=   |   x    |        |        |   0    |   0    |   x     |    x
-//  |, |=   |   x    |        |        |   x    |   x    |   ~0    |    ~0
-//  ^, ^=   |   0    |        |        |   x    |   x    |         |
-//  <<, <<= |        |        |        |   x    |   0    |         |
-//  >>, >>= |        |        |        |   x    |   0    |         |
-//  ||      |   x    |   1    |   1    |   x    |   x    |   1     |    1
-//  &&      |   x    |   x    |   x    |   0    |   0    |   x     |    x
-//  =       |   x    |        |        |        |        |         |
-//  ==      |   1    |        |        |        |        |         |
-//  >=      |   1    |        |        |        |        |         |
-//  <=      |   1    |        |        |        |        |         |
-//  >       |   0    |        |        |        |        |         |
-//  <       |   0    |        |        |        |        |         |
-//  !=      |   0    |        |        |        |        |         |
-//===----------------------------------------------------------------------===//
-//
-// Things TODO:
-// - Improved error messages
-// - Handle mixed assumptions (which assumptions can belong together?)
-// - Finer grained false positive control (levels)
-// - Handling ~0 values
-
-#include "ClangSACheckers.h"
-#include "clang/AST/Stmt.h"
-#include "clang/Analysis/Analyses/CFGReachabilityAnalysis.h"
-#include "clang/Analysis/Analyses/PseudoConstantAnalysis.h"
-#include "clang/Analysis/CFGStmtMap.h"
-#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
-#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
-#include "clang/StaticAnalyzer/Core/Checker.h"
-#include "clang/StaticAnalyzer/Core/CheckerManager.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
-#include "llvm/ADT/BitVector.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace clang;
-using namespace ento;
-
-namespace {
-class IdempotentOperationChecker
-  : public Checker<check::PreStmt<BinaryOperator>,
-                     check::PostStmt<BinaryOperator>,
-                     check::EndAnalysis> {
-public:
-  void checkPreStmt(const BinaryOperator *B, CheckerContext &C) const;
-  void checkPostStmt(const BinaryOperator *B, CheckerContext &C) const;
-  void checkEndAnalysis(ExplodedGraph &G, BugReporter &B,ExprEngine &Eng) const;
-
-private:
-  // Our assumption about a particular operation.
-  enum Assumption { Possible = 0, Impossible, Equal, LHSis1, RHSis1, LHSis0,
-      RHSis0 };
-
-  static void UpdateAssumption(Assumption &A, const Assumption &New);
-
-  // False positive reduction methods
-  static bool isSelfAssign(const Expr *LHS, const Expr *RHS);
-  static bool isUnused(const Expr *E, AnalysisDeclContext *AC);
-  static bool isTruncationExtensionAssignment(const Expr *LHS,
-                                              const Expr *RHS);
-  static bool pathWasCompletelyAnalyzed(AnalysisDeclContext *AC,
-                                        const CFGBlock *CB,
-                                        const CoreEngine &CE);
-  static bool CanVary(const Expr *Ex,
-                      AnalysisDeclContext *AC);
-  static bool isConstantOrPseudoConstant(const DeclRefExpr *DR,
-                                         AnalysisDeclContext *AC);
-  static bool containsNonLocalVarDecl(const Stmt *S);
-
-  // Hash table and related data structures
-  struct BinaryOperatorData {
-    BinaryOperatorData() : assumption(Possible) {}
-
-    Assumption assumption;
-    ExplodedNodeSet explodedNodes; // Set of ExplodedNodes that refer to a
-                                   // BinaryOperator
-  };
-  typedef llvm::DenseMap<const BinaryOperator *, BinaryOperatorData>
-      AssumptionMap;
-  mutable AssumptionMap hash;
-  mutable OwningPtr<BugType> BT;
-};
-}
-
-void IdempotentOperationChecker::checkPreStmt(const BinaryOperator *B,
-                                              CheckerContext &C) const {
-  // Find or create an entry in the hash for this BinaryOperator instance.
-  // If we haven't done a lookup before, it will get default initialized to
-  // 'Possible'. At this stage we do not store the ExplodedNode, as it has not
-  // been created yet.
-  BinaryOperatorData &Data = hash[B];
-  Assumption &A = Data.assumption;
-  AnalysisDeclContext *AC = C.getCurrentAnalysisDeclContext();
-
-  // If we already have visited this node on a path that does not contain an
-  // idempotent operation, return immediately.
-  if (A == Impossible)
-    return;
-
-  // Retrieve both sides of the operator and determine if they can vary (which
-  // may mean this is a false positive.
-  const Expr *LHS = B->getLHS();
-  const Expr *RHS = B->getRHS();
-
-  // At this stage we can calculate whether each side contains a false positive
-  // that applies to all operators. We only need to calculate this the first
-  // time.
-  bool LHSContainsFalsePositive = false, RHSContainsFalsePositive = false;
-  if (A == Possible) {
-    // An expression contains a false positive if it can't vary, or if it
-    // contains a known false positive VarDecl.
-    LHSContainsFalsePositive = !CanVary(LHS, AC)
-        || containsNonLocalVarDecl(LHS);
-    RHSContainsFalsePositive = !CanVary(RHS, AC)
-        || containsNonLocalVarDecl(RHS);
-  }
-
-  ProgramStateRef state = C.getState();
-  const LocationContext *LCtx = C.getLocationContext();
-  SVal LHSVal = state->getSVal(LHS, LCtx);
-  SVal RHSVal = state->getSVal(RHS, LCtx);
-
-  // If either value is unknown, we can't be 100% sure of all paths.
-  if (LHSVal.isUnknownOrUndef() || RHSVal.isUnknownOrUndef()) {
-    A = Impossible;
-    return;
-  }
-  BinaryOperator::Opcode Op = B->getOpcode();
-
-  // Dereference the LHS SVal if this is an assign operation
-  switch (Op) {
-  default:
-    break;
-
-  // Fall through intentional
-  case BO_AddAssign:
-  case BO_SubAssign:
-  case BO_MulAssign:
-  case BO_DivAssign:
-  case BO_AndAssign:
-  case BO_OrAssign:
-  case BO_XorAssign:
-  case BO_ShlAssign:
-  case BO_ShrAssign:
-  case BO_Assign:
-  // Assign statements have one extra level of indirection
-    if (!LHSVal.getAs<Loc>()) {
-      A = Impossible;
-      return;
-    }
-    LHSVal = state->getSVal(LHSVal.castAs<Loc>(), LHS->getType());
-  }
-
-
-  // We now check for various cases which result in an idempotent operation.
-
-  // x op x
-  switch (Op) {
-  default:
-    break; // We don't care about any other operators.
-
-  // Fall through intentional
-  case BO_Assign:
-    // x Assign x can be used to silence unused variable warnings intentionally.
-    // If this is a self assignment and the variable is referenced elsewhere,
-    // and the assignment is not a truncation or extension, then it is a false
-    // positive.
-    if (isSelfAssign(LHS, RHS)) {
-      if (!isUnused(LHS, AC) && !isTruncationExtensionAssignment(LHS, RHS)) {
-        UpdateAssumption(A, Equal);
-        return;
-      }
-      else {
-        A = Impossible;
-        return;
-      }
-    }
-
-  case BO_SubAssign:
-  case BO_DivAssign:
-  case BO_AndAssign:
-  case BO_OrAssign:
-  case BO_XorAssign:
-  case BO_Sub:
-  case BO_Div:
-  case BO_And:
-  case BO_Or:
-  case BO_Xor:
-  case BO_LOr:
-  case BO_LAnd:
-  case BO_EQ:
-  case BO_NE:
-    if (LHSVal != RHSVal || LHSContainsFalsePositive
-        || RHSContainsFalsePositive)
-      break;
-    UpdateAssumption(A, Equal);
-    return;
-  }
-
-  // x op 1
-  switch (Op) {
-   default:
-     break; // We don't care about any other operators.
-
-   // Fall through intentional
-   case BO_MulAssign:
-   case BO_DivAssign:
-   case BO_Mul:
-   case BO_Div:
-   case BO_LOr:
-   case BO_LAnd:
-     if (!RHSVal.isConstant(1) || RHSContainsFalsePositive)
-       break;
-     UpdateAssumption(A, RHSis1);
-     return;
-  }
-
-  // 1 op x
-  switch (Op) {
-  default:
-    break; // We don't care about any other operators.
-
-  // Fall through intentional
-  case BO_MulAssign:
-  case BO_Mul:
-  case BO_LOr:
-  case BO_LAnd:
-    if (!LHSVal.isConstant(1) || LHSContainsFalsePositive)
-      break;
-    UpdateAssumption(A, LHSis1);
-    return;
-  }
-
-  // x op 0
-  switch (Op) {
-  default:
-    break; // We don't care about any other operators.
-
-  // Fall through intentional
-  case BO_AddAssign:
-  case BO_SubAssign:
-  case BO_MulAssign:
-  case BO_AndAssign:
-  case BO_OrAssign:
-  case BO_XorAssign:
-  case BO_Add:
-  case BO_Sub:
-  case BO_Mul:
-  case BO_And:
-  case BO_Or:
-  case BO_Xor:
-  case BO_Shl:
-  case BO_Shr:
-  case BO_LOr:
-  case BO_LAnd:
-    if (!RHSVal.isConstant(0) || RHSContainsFalsePositive)
-      break;
-    UpdateAssumption(A, RHSis0);
-    return;
-  }
-
-  // 0 op x
-  switch (Op) {
-  default:
-    break; // We don't care about any other operators.
-
-  // Fall through intentional
-  //case BO_AddAssign: // Common false positive
-  case BO_SubAssign: // Check only if unsigned
-  case BO_MulAssign:
-  case BO_DivAssign:
-  case BO_AndAssign:
-  //case BO_OrAssign: // Common false positive
-  //case BO_XorAssign: // Common false positive
-  case BO_ShlAssign:
-  case BO_ShrAssign:
-  case BO_Add:
-  case BO_Sub:
-  case BO_Mul:
-  case BO_Div:
-  case BO_And:
-  case BO_Or:
-  case BO_Xor:
-  case BO_Shl:
-  case BO_Shr:
-  case BO_LOr:
-  case BO_LAnd:
-    if (!LHSVal.isConstant(0) || LHSContainsFalsePositive)
-      break;
-    UpdateAssumption(A, LHSis0);
-    return;
-  }
-
-  // If we get to this point, there has been a valid use of this operation.
-  A = Impossible;
-}
-
-// At the post visit stage, the predecessor ExplodedNode will be the
-// BinaryOperator that was just created. We use this hook to collect the
-// ExplodedNode.
-void IdempotentOperationChecker::checkPostStmt(const BinaryOperator *B,
-                                               CheckerContext &C) const {
-  // Add the ExplodedNode we just visited
-  BinaryOperatorData &Data = hash[B];
-
-  const Stmt *predStmt =
-      C.getPredecessor()->getLocation().castAs<StmtPoint>().getStmt();
-
-  // Ignore implicit calls to setters.
-  if (!isa<BinaryOperator>(predStmt))
-    return;
-
-  Data.explodedNodes.Add(C.getPredecessor());
-}
-
-void IdempotentOperationChecker::checkEndAnalysis(ExplodedGraph &G,
-                                                  BugReporter &BR,
-                                                  ExprEngine &Eng) const {
-  if (!BT)
-    BT.reset(new BugType("Idempotent operation", "Dead code"));
-
-  // Iterate over the hash to see if we have any paths with definite
-  // idempotent operations.
-  for (AssumptionMap::const_iterator i = hash.begin(); i != hash.end(); ++i) {
-    // Unpack the hash contents
-    const BinaryOperatorData &Data = i->second;
-    const Assumption &A = Data.assumption;
-    const ExplodedNodeSet &ES = Data.explodedNodes;
-
-    // If there are no nodes accosted with the expression, nothing to report.
-    // FIXME: This is possible because the checker does part of processing in
-    // checkPreStmt and part in checkPostStmt.
-    if (ES.begin() == ES.end())
-      continue;
-
-    const BinaryOperator *B = i->first;
-
-    if (A == Impossible)
-      continue;
-
-    // If the analyzer did not finish, check to see if we can still emit this
-    // warning
-    if (Eng.hasWorkRemaining()) {
-      // If we can trace back
-      AnalysisDeclContext *AC = (*ES.begin())->getLocationContext()
-                                         ->getAnalysisDeclContext();
-      if (!pathWasCompletelyAnalyzed(AC,
-                                     AC->getCFGStmtMap()->getBlock(B),
-                                     Eng.getCoreEngine()))
-        continue;
-    }
-
-    // Select the error message and SourceRanges to report.
-    SmallString<128> buf;
-    llvm::raw_svector_ostream os(buf);
-    bool LHSRelevant = false, RHSRelevant = false;
-    switch (A) {
-    case Equal:
-      LHSRelevant = true;
-      RHSRelevant = true;
-      if (B->getOpcode() == BO_Assign)
-        os << "Assigned value is always the same as the existing value";
-      else
-        os << "Both operands to '" << B->getOpcodeStr()
-           << "' always have the same value";
-      break;
-    case LHSis1:
-      LHSRelevant = true;
-      os << "The left operand to '" << B->getOpcodeStr() << "' is always 1";
-      break;
-    case RHSis1:
-      RHSRelevant = true;
-      os << "The right operand to '" << B->getOpcodeStr() << "' is always 1";
-      break;
-    case LHSis0:
-      LHSRelevant = true;
-      os << "The left operand to '" << B->getOpcodeStr() << "' is always 0";
-      break;
-    case RHSis0:
-      RHSRelevant = true;
-      os << "The right operand to '" << B->getOpcodeStr() << "' is always 0";
-      break;
-    case Possible:
-      llvm_unreachable("Operation was never marked with an assumption");
-    case Impossible:
-      llvm_unreachable(0);
-    }
-
-    // Add a report for each ExplodedNode
-    for (ExplodedNodeSet::iterator I = ES.begin(), E = ES.end(); I != E; ++I) {
-      BugReport *report = new BugReport(*BT, os.str(), *I);
-
-      // Add source ranges and visitor hooks
-      if (LHSRelevant) {
-        const Expr *LHS = i->first->getLHS();
-        report->addRange(LHS->getSourceRange());
-        FindLastStoreBRVisitor::registerStatementVarDecls(*report, LHS, false);
-      }
-      if (RHSRelevant) {
-        const Expr *RHS = i->first->getRHS();
-        report->addRange(i->first->getRHS()->getSourceRange());
-        FindLastStoreBRVisitor::registerStatementVarDecls(*report, RHS, false);
-      }
-
-      BR.emitReport(report);
-    }
-  }
-
-  hash.clear();
-}
-
-// Updates the current assumption given the new assumption
-inline void IdempotentOperationChecker::UpdateAssumption(Assumption &A,
-                                                        const Assumption &New) {
-// If the assumption is the same, there is nothing to do
-  if (A == New)
-    return;
-
-  switch (A) {
-  // If we don't currently have an assumption, set it
-  case Possible:
-    A = New;
-    return;
-
-  // If we have determined that a valid state happened, ignore the new
-  // assumption.
-  case Impossible:
-    return;
-
-  // Any other case means that we had a different assumption last time. We don't
-  // currently support mixing assumptions for diagnostic reasons, so we set
-  // our assumption to be impossible.
-  default:
-    A = Impossible;
-    return;
-  }
-}
-
-// Check for a statement where a variable is self assigned to possibly avoid an
-// unused variable warning.
-bool IdempotentOperationChecker::isSelfAssign(const Expr *LHS, const Expr *RHS) {
-  LHS = LHS->IgnoreParenCasts();
-  RHS = RHS->IgnoreParenCasts();
-
-  const DeclRefExpr *LHS_DR = dyn_cast<DeclRefExpr>(LHS);
-  if (!LHS_DR)
-    return false;
-
-  const VarDecl *VD = dyn_cast<VarDecl>(LHS_DR->getDecl());
-  if (!VD)
-    return false;
-
-  const DeclRefExpr *RHS_DR = dyn_cast<DeclRefExpr>(RHS);
-  if (!RHS_DR)
-    return false;
-
-  if (VD != RHS_DR->getDecl())
-    return false;
-
-  return true;
-}
-
-// Returns true if the Expr points to a VarDecl that is not read anywhere
-// outside of self-assignments.
-bool IdempotentOperationChecker::isUnused(const Expr *E,
-                                          AnalysisDeclContext *AC) {
-  if (!E)
-    return false;
-
-  const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(E->IgnoreParenCasts());
-  if (!DR)
-    return false;
-
-  const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl());
-  if (!VD)
-    return false;
-
-  if (AC->getPseudoConstantAnalysis()->wasReferenced(VD))
-    return false;
-
-  return true;
-}
-
-// Check for self casts truncating/extending a variable
-bool IdempotentOperationChecker::isTruncationExtensionAssignment(
-                                                              const Expr *LHS,
-                                                              const Expr *RHS) {
-
-  const DeclRefExpr *LHS_DR = dyn_cast<DeclRefExpr>(LHS->IgnoreParenCasts());
-  if (!LHS_DR)
-    return false;
-
-  const VarDecl *VD = dyn_cast<VarDecl>(LHS_DR->getDecl());
-  if (!VD)
-    return false;
-
-  const DeclRefExpr *RHS_DR = dyn_cast<DeclRefExpr>(RHS->IgnoreParenCasts());
-  if (!RHS_DR)
-    return false;
-
-  if (VD != RHS_DR->getDecl())
-     return false;
-
-  return dyn_cast<DeclRefExpr>(RHS->IgnoreParenLValueCasts()) == NULL;
-}
-
-// Returns false if a path to this block was not completely analyzed, or true
-// otherwise.
-bool
-IdempotentOperationChecker::pathWasCompletelyAnalyzed(AnalysisDeclContext *AC,
-                                                      const CFGBlock *CB,
-                                                      const CoreEngine &CE) {
-
-  CFGReverseBlockReachabilityAnalysis *CRA = AC->getCFGReachablityAnalysis();
-  
-  // Test for reachability from any aborted blocks to this block
-  typedef CoreEngine::BlocksExhausted::const_iterator ExhaustedIterator;
-  for (ExhaustedIterator I = CE.blocks_exhausted_begin(),
-      E = CE.blocks_exhausted_end(); I != E; ++I) {
-    const BlockEdge &BE =  I->first;
-
-    // The destination block on the BlockEdge is the first block that was not
-    // analyzed. If we can reach this block from the aborted block, then this
-    // block was not completely analyzed.
-    //
-    // Also explicitly check if the current block is the destination block.
-    // While technically reachable, it means we aborted the analysis on
-    // a path that included that block.
-    const CFGBlock *destBlock = BE.getDst();
-    if (destBlock == CB || CRA->isReachable(destBlock, CB))
-      return false;
-  }
-
-  // Test for reachability from blocks we just gave up on.
-  typedef CoreEngine::BlocksAborted::const_iterator AbortedIterator;
-  for (AbortedIterator I = CE.blocks_aborted_begin(),
-       E = CE.blocks_aborted_end(); I != E; ++I) {
-    const CFGBlock *destBlock = I->first;
-    if (destBlock == CB || CRA->isReachable(destBlock, CB))
-      return false;
-  }
-  
-  // For the items still on the worklist, see if they are in blocks that
-  // can eventually reach 'CB'.
-  class VisitWL : public WorkList::Visitor {
-    const CFGStmtMap *CBM;
-    const CFGBlock *TargetBlock;
-    CFGReverseBlockReachabilityAnalysis &CRA;
-  public:
-    VisitWL(const CFGStmtMap *cbm, const CFGBlock *targetBlock,
-            CFGReverseBlockReachabilityAnalysis &cra)
-      : CBM(cbm), TargetBlock(targetBlock), CRA(cra) {}
-    virtual bool visit(const WorkListUnit &U) {
-      ProgramPoint P = U.getNode()->getLocation();
-      const CFGBlock *B = 0;
-      if (Optional<StmtPoint> SP = P.getAs<StmtPoint>()) {
-        B = CBM->getBlock(SP->getStmt());
-      } else if (Optional<BlockEdge> BE = P.getAs<BlockEdge>()) {
-        B = BE->getDst();
-      } else if (Optional<BlockEntrance> BEnt = P.getAs<BlockEntrance>()) {
-        B = BEnt->getBlock();
-      } else if (Optional<BlockExit> BExit = P.getAs<BlockExit>()) {
-        B = BExit->getBlock();
-      }
-      if (!B)
-        return true;
-      
-      return B == TargetBlock || CRA.isReachable(B, TargetBlock);
-    }
-  };
-  VisitWL visitWL(AC->getCFGStmtMap(), CB, *CRA);
-  // Were there any items in the worklist that could potentially reach
-  // this block?
-  if (CE.getWorkList()->visitItemsInWorkList(visitWL))
-    return false;
-
-  // Verify that this block is reachable from the entry block
-  if (!CRA->isReachable(&AC->getCFG()->getEntry(), CB))
-    return false;
-
-  // If we get to this point, there is no connection to the entry block or an
-  // aborted block. This path is unreachable and we can report the error.
-  return true;
-}
-
-// Recursive function that determines whether an expression contains any element
-// that varies. This could be due to a compile-time constant like sizeof. An
-// expression may also involve a variable that behaves like a constant. The
-// function returns true if the expression varies, and false otherwise.
-bool IdempotentOperationChecker::CanVary(const Expr *Ex,
-                                         AnalysisDeclContext *AC) {
-  // Parentheses and casts are irrelevant here
-  Ex = Ex->IgnoreParenCasts();
-
-  if (Ex->getLocStart().isMacroID())
-    return false;
-
-  switch (Ex->getStmtClass()) {
-  // Trivially true cases
-  case Stmt::ArraySubscriptExprClass:
-  case Stmt::MemberExprClass:
-  case Stmt::StmtExprClass:
-  case Stmt::CallExprClass:
-  case Stmt::VAArgExprClass:
-  case Stmt::ShuffleVectorExprClass:
-    return true;
-  default:
-    return true;
-
-  // Trivially false cases
-  case Stmt::IntegerLiteralClass:
-  case Stmt::CharacterLiteralClass:
-  case Stmt::FloatingLiteralClass:
-  case Stmt::PredefinedExprClass:
-  case Stmt::ImaginaryLiteralClass:
-  case Stmt::StringLiteralClass:
-  case Stmt::OffsetOfExprClass:
-  case Stmt::CompoundLiteralExprClass:
-  case Stmt::AddrLabelExprClass:
-  case Stmt::BinaryTypeTraitExprClass:
-  case Stmt::GNUNullExprClass:
-  case Stmt::InitListExprClass:
-  case Stmt::DesignatedInitExprClass:
-  case Stmt::BlockExprClass:
-    return false;
-
-  // Cases requiring custom logic
-  case Stmt::UnaryExprOrTypeTraitExprClass: {
-    const UnaryExprOrTypeTraitExpr *SE = 
-                       cast<const UnaryExprOrTypeTraitExpr>(Ex);
-    if (SE->getKind() != UETT_SizeOf)
-      return false;
-    return SE->getTypeOfArgument()->isVariableArrayType();
-  }
-  case Stmt::DeclRefExprClass:
-    // Check for constants/pseudoconstants
-    return !isConstantOrPseudoConstant(cast<DeclRefExpr>(Ex), AC);
-
-  // The next cases require recursion for subexpressions
-  case Stmt::BinaryOperatorClass: {
-    const BinaryOperator *B = cast<const BinaryOperator>(Ex);
-
-    // Exclude cases involving pointer arithmetic.  These are usually
-    // false positives.
-    if (B->getOpcode() == BO_Sub || B->getOpcode() == BO_Add)
-      if (B->getLHS()->getType()->getAs<PointerType>())
-        return false;
-
-    return CanVary(B->getRHS(), AC)
-        || CanVary(B->getLHS(), AC);
-   }
-  case Stmt::UnaryOperatorClass:
-    return CanVary(cast<UnaryOperator>(Ex)->getSubExpr(), AC);
-  case Stmt::ConditionalOperatorClass:
-  case Stmt::BinaryConditionalOperatorClass:
-    return CanVary(cast<AbstractConditionalOperator>(Ex)->getCond(), AC);
-  }
-}
-
-// Returns true if a DeclRefExpr is or behaves like a constant.
-bool IdempotentOperationChecker::isConstantOrPseudoConstant(
-                                                          const DeclRefExpr *DR,
-                                                          AnalysisDeclContext *AC) {
-  // Check if the type of the Decl is const-qualified
-  if (DR->getType().isConstQualified())
-    return true;
-
-  // Check for an enum
-  if (isa<EnumConstantDecl>(DR->getDecl()))
-    return true;
-
-  const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl());
-  if (!VD)
-    return true;
-
-  // Check if the Decl behaves like a constant. This check also takes care of
-  // static variables, which can only change between function calls if they are
-  // modified in the AST.
-  PseudoConstantAnalysis *PCA = AC->getPseudoConstantAnalysis();
-  if (PCA->isPseudoConstant(VD))
-    return true;
-
-  return false;
-}
-
-// Recursively find any substatements containing VarDecl's with storage other
-// than local
-bool IdempotentOperationChecker::containsNonLocalVarDecl(const Stmt *S) {
-  const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(S);
-
-  if (DR)
-    if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl()))
-      if (!VD->hasLocalStorage())
-        return true;
-
-  for (Stmt::const_child_iterator I = S->child_begin(); I != S->child_end();
-      ++I)
-    if (const Stmt *child = *I)
-      if (containsNonLocalVarDecl(child))
-        return true;
-
-  return false;
-}
-
-
-void ento::registerIdempotentOperationChecker(CheckerManager &mgr) {
-  mgr.registerChecker<IdempotentOperationChecker>();
-}
diff --git a/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp b/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp
index e696e38..d5c52b4 100644
--- a/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp
@@ -11,22 +11,23 @@
 /// \brief This defines IdenticalExprChecker, a check that warns about
 /// unintended use of identical expressions.
 ///
-/// It checks for use of identical expressions with comparison operators.
+/// It checks for use of identical expressions with comparison operators and
+/// inside conditional expressions.
 ///
 //===----------------------------------------------------------------------===//
 
 #include "ClangSACheckers.h"
+#include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
-#include "clang/AST/RecursiveASTVisitor.h"
 
 using namespace clang;
 using namespace ento;
 
-static bool isIdenticalExpr(const ASTContext &Ctx, const Expr *Expr1,
-                            const Expr *Expr2);
+static bool isIdenticalStmt(const ASTContext &Ctx, const Stmt *Stmt1,
+                            const Stmt *Stmt2, bool IgnoreSideEffects = false);
 //===----------------------------------------------------------------------===//
 // FindIdenticalExprVisitor - Identify nodes using identical expressions.
 //===----------------------------------------------------------------------===//
@@ -34,23 +35,153 @@
 namespace {
 class FindIdenticalExprVisitor
     : public RecursiveASTVisitor<FindIdenticalExprVisitor> {
+  BugReporter &BR;
+  const CheckerBase *Checker;
+  AnalysisDeclContext *AC;
 public:
-  explicit FindIdenticalExprVisitor(BugReporter &B, AnalysisDeclContext *A)
-      : BR(B), AC(A) {}
+  explicit FindIdenticalExprVisitor(BugReporter &B,
+                                    const CheckerBase *Checker,
+                                    AnalysisDeclContext *A)
+      : BR(B), Checker(Checker), AC(A) {}
   // FindIdenticalExprVisitor only visits nodes
-  // that are binary operators.
+  // that are binary operators, if statements or
+  // conditional operators.
   bool VisitBinaryOperator(const BinaryOperator *B);
+  bool VisitIfStmt(const IfStmt *I);
+  bool VisitConditionalOperator(const ConditionalOperator *C);
 
 private:
-  BugReporter &BR;
-  AnalysisDeclContext *AC;
+  void reportIdenticalExpr(const BinaryOperator *B, bool CheckBitwise,
+                           ArrayRef<SourceRange> Sr);
+  void checkBitwiseOrLogicalOp(const BinaryOperator *B, bool CheckBitwise);
+  void checkComparisonOp(const BinaryOperator *B);
 };
 } // end anonymous namespace
 
+void FindIdenticalExprVisitor::reportIdenticalExpr(const BinaryOperator *B,
+                                                   bool CheckBitwise,
+                                                   ArrayRef<SourceRange> Sr) {
+  StringRef Message;
+  if (CheckBitwise)
+    Message = "identical expressions on both sides of bitwise operator";
+  else
+    Message = "identical expressions on both sides of logical operator";
+
+  PathDiagnosticLocation ELoc =
+      PathDiagnosticLocation::createOperatorLoc(B, BR.getSourceManager());
+  BR.EmitBasicReport(AC->getDecl(), Checker,
+                     "Use of identical expressions",
+                     categories::LogicError,
+                     Message, ELoc, Sr);
+}
+
+void FindIdenticalExprVisitor::checkBitwiseOrLogicalOp(const BinaryOperator *B,
+                                                       bool CheckBitwise) {
+  SourceRange Sr[2];
+
+  const Expr *LHS = B->getLHS();
+  const Expr *RHS = B->getRHS();
+
+  // Split operators as long as we still have operators to split on. We will
+  // get called for every binary operator in an expression so there is no need
+  // to check every one against each other here, just the right most one with
+  // the others.
+  while (const BinaryOperator *B2 = dyn_cast<BinaryOperator>(LHS)) {
+    if (B->getOpcode() != B2->getOpcode())
+      break;
+    if (isIdenticalStmt(AC->getASTContext(), RHS, B2->getRHS())) {
+      Sr[0] = RHS->getSourceRange();
+      Sr[1] = B2->getRHS()->getSourceRange();
+      reportIdenticalExpr(B, CheckBitwise, Sr);
+    }
+    LHS = B2->getLHS();
+  }
+  
+  if (isIdenticalStmt(AC->getASTContext(), RHS, LHS)) {
+    Sr[0] = RHS->getSourceRange();
+    Sr[1] = LHS->getSourceRange();
+    reportIdenticalExpr(B, CheckBitwise, Sr);
+  }
+}
+
+bool FindIdenticalExprVisitor::VisitIfStmt(const IfStmt *I) {
+  const Stmt *Stmt1 = I->getThen();
+  const Stmt *Stmt2 = I->getElse();
+
+  // Check for identical conditions:
+  //
+  // if (b) {
+  //   foo1();
+  // } else if (b) {
+  //   foo2();
+  // }
+  if (Stmt1 && Stmt2) {
+    const Expr *Cond1 = I->getCond();
+    const Stmt *Else = Stmt2;
+    while (const IfStmt *I2 = dyn_cast_or_null<IfStmt>(Else)) {
+      const Expr *Cond2 = I2->getCond();
+      if (isIdenticalStmt(AC->getASTContext(), Cond1, Cond2, false)) {
+        SourceRange Sr = Cond1->getSourceRange();
+        PathDiagnosticLocation ELoc(Cond2, BR.getSourceManager(), AC);
+        BR.EmitBasicReport(AC->getDecl(), Checker, "Identical conditions",
+                           categories::LogicError,
+                           "expression is identical to previous condition",
+                           ELoc, Sr);
+      }
+      Else = I2->getElse();
+    }
+  }
+
+  if (!Stmt1 || !Stmt2)
+    return true;
+
+  // Special handling for code like:
+  //
+  // if (b) {
+  //   i = 1;
+  // } else
+  //   i = 1;
+  if (const CompoundStmt *CompStmt = dyn_cast<CompoundStmt>(Stmt1)) {
+    if (CompStmt->size() == 1)
+      Stmt1 = CompStmt->body_back();
+  }
+  if (const CompoundStmt *CompStmt = dyn_cast<CompoundStmt>(Stmt2)) {
+    if (CompStmt->size() == 1)
+      Stmt2 = CompStmt->body_back();
+  }
+
+  if (isIdenticalStmt(AC->getASTContext(), Stmt1, Stmt2, true)) {
+      PathDiagnosticLocation ELoc =
+          PathDiagnosticLocation::createBegin(I, BR.getSourceManager(), AC);
+      BR.EmitBasicReport(AC->getDecl(), Checker,
+                         "Identical branches",
+                         categories::LogicError,
+                         "true and false branches are identical", ELoc);
+  }
+  return true;
+}
+
 bool FindIdenticalExprVisitor::VisitBinaryOperator(const BinaryOperator *B) {
   BinaryOperator::Opcode Op = B->getOpcode();
-  if (!BinaryOperator::isComparisonOp(Op))
-    return true;
+
+  if (BinaryOperator::isBitwiseOp(Op))
+    checkBitwiseOrLogicalOp(B, true);
+
+  if (BinaryOperator::isLogicalOp(Op))
+    checkBitwiseOrLogicalOp(B, false);
+
+  if (BinaryOperator::isComparisonOp(Op))
+    checkComparisonOp(B);
+
+  // We want to visit ALL nodes (subexpressions of binary comparison
+  // expressions too) that contains comparison operators.
+  // True is always returned to traverse ALL nodes.
+  return true;
+}
+
+void FindIdenticalExprVisitor::checkComparisonOp(const BinaryOperator *B) {
+  BinaryOperator::Opcode Op = B->getOpcode();
+
   //
   // Special case for floating-point representation.
   //
@@ -83,26 +214,26 @@
         (DeclRef2->getType()->hasFloatingRepresentation())) {
       if (DeclRef1->getDecl() == DeclRef2->getDecl()) {
         if ((Op == BO_EQ) || (Op == BO_NE)) {
-          return true;
+          return;
         }
       }
     }
   } else if ((FloatLit1) && (FloatLit2)) {
     if (FloatLit1->getValue().bitwiseIsEqual(FloatLit2->getValue())) {
       if ((Op == BO_EQ) || (Op == BO_NE)) {
-        return true;
+        return;
       }
     }
   } else if (LHS->getType()->hasFloatingRepresentation()) {
     // If any side of comparison operator still has floating-point
     // representation, then it's an expression. Don't warn.
     // Here only LHS is checked since RHS will be implicit casted to float.
-    return true;
+    return;
   } else {
     // No special case with floating-point representation, report as usual.
   }
 
-  if (isIdenticalExpr(AC->getASTContext(), B->getLHS(), B->getRHS())) {
+  if (isIdenticalStmt(AC->getASTContext(), B->getLHS(), B->getRHS())) {
     PathDiagnosticLocation ELoc =
         PathDiagnosticLocation::createOperatorLoc(B, BR.getSourceManager());
     StringRef Message;
@@ -110,15 +241,41 @@
       Message = "comparison of identical expressions always evaluates to true";
     else
       Message = "comparison of identical expressions always evaluates to false";
-    BR.EmitBasicReport(AC->getDecl(), "Compare of identical expressions",
+    BR.EmitBasicReport(AC->getDecl(), Checker,
+                       "Compare of identical expressions",
                        categories::LogicError, Message, ELoc);
   }
-  // We want to visit ALL nodes (subexpressions of binary comparison
-  // expressions too) that contains comparison operators.
-  // True is always returned to traverse ALL nodes.
+}
+
+bool FindIdenticalExprVisitor::VisitConditionalOperator(
+    const ConditionalOperator *C) {
+
+  // Check if expressions in conditional expression are identical
+  // from a symbolic point of view.
+
+  if (isIdenticalStmt(AC->getASTContext(), C->getTrueExpr(),
+                      C->getFalseExpr(), true)) {
+    PathDiagnosticLocation ELoc =
+        PathDiagnosticLocation::createConditionalColonLoc(
+            C, BR.getSourceManager());
+
+    SourceRange Sr[2];
+    Sr[0] = C->getTrueExpr()->getSourceRange();
+    Sr[1] = C->getFalseExpr()->getSourceRange();
+    BR.EmitBasicReport(
+        AC->getDecl(), Checker,
+        "Identical expressions in conditional expression",
+        categories::LogicError,
+        "identical expressions on both sides of ':' in conditional expression",
+        ELoc, Sr);
+  }
+  // We want to visit ALL nodes (expressions in conditional
+  // expressions too) that contains conditional operators,
+  // thus always return true to traverse ALL nodes.
   return true;
 }
-/// \brief Determines whether two expression trees are identical regarding
+
+/// \brief Determines whether two statement trees are identical regarding
 /// operators and symbols.
 ///
 /// Exceptions: expressions containing macros or functions with possible side
@@ -126,82 +283,189 @@
 /// Limitations: (t + u) and (u + t) are not considered identical.
 /// t*(u + t) and t*u + t*t are not considered identical.
 ///
-static bool isIdenticalExpr(const ASTContext &Ctx, const Expr *Expr1,
-                            const Expr *Expr2) {
-  // If Expr1 & Expr2 are of different class then they are not
-  // identical expression.
-  if (Expr1->getStmtClass() != Expr2->getStmtClass())
+static bool isIdenticalStmt(const ASTContext &Ctx, const Stmt *Stmt1,
+                            const Stmt *Stmt2, bool IgnoreSideEffects) {
+
+  if (!Stmt1 || !Stmt2) {
+    if (!Stmt1 && !Stmt2)
+      return true;
     return false;
-  // If Expr1 has side effects then don't warn even if expressions
-  // are identical.
-  if (Expr1->HasSideEffects(Ctx))
-    return false;
-  // Is expression is based on macro then don't warn even if
-  // the expressions are identical.
-  if ((Expr1->getExprLoc().isMacroID()) || (Expr2->getExprLoc().isMacroID()))
-    return false;
-  // If all children of two expressions are identical, return true.
-  Expr::const_child_iterator I1 = Expr1->child_begin();
-  Expr::const_child_iterator I2 = Expr2->child_begin();
-  while (I1 != Expr1->child_end() && I2 != Expr2->child_end()) {
-    const Expr *Child1 = dyn_cast<Expr>(*I1);
-    const Expr *Child2 = dyn_cast<Expr>(*I2);
-    if (!Child1 || !Child2 || !isIdenticalExpr(Ctx, Child1, Child2))
-      return false;
-    ++I1;
-    ++I2;
   }
-  // If there are different number of children in the expressions, return false.
-  // (TODO: check if this is a redundant condition.)
-  if (I1 != Expr1->child_end())
-    return false;
-  if (I2 != Expr2->child_end())
+
+  // If Stmt1 & Stmt2 are of different class then they are not
+  // identical statements.
+  if (Stmt1->getStmtClass() != Stmt2->getStmtClass())
     return false;
 
-  switch (Expr1->getStmtClass()) {
+  const Expr *Expr1 = dyn_cast<Expr>(Stmt1);
+  const Expr *Expr2 = dyn_cast<Expr>(Stmt2);
+
+  if (Expr1 && Expr2) {
+    // If Stmt1 has side effects then don't warn even if expressions
+    // are identical.
+    if (!IgnoreSideEffects && Expr1->HasSideEffects(Ctx))
+      return false;
+    // If either expression comes from a macro then don't warn even if
+    // the expressions are identical.
+    if ((Expr1->getExprLoc().isMacroID()) || (Expr2->getExprLoc().isMacroID()))
+      return false;
+
+    // If all children of two expressions are identical, return true.
+    Expr::const_child_iterator I1 = Expr1->child_begin();
+    Expr::const_child_iterator I2 = Expr2->child_begin();
+    while (I1 != Expr1->child_end() && I2 != Expr2->child_end()) {
+      if (!*I1 || !*I2 || !isIdenticalStmt(Ctx, *I1, *I2, IgnoreSideEffects))
+        return false;
+      ++I1;
+      ++I2;
+    }
+    // If there are different number of children in the statements, return
+    // false.
+    if (I1 != Expr1->child_end())
+      return false;
+    if (I2 != Expr2->child_end())
+      return false;
+  }
+
+  switch (Stmt1->getStmtClass()) {
   default:
     return false;
+  case Stmt::CallExprClass:
   case Stmt::ArraySubscriptExprClass:
-  case Stmt::CStyleCastExprClass:
   case Stmt::ImplicitCastExprClass:
   case Stmt::ParenExprClass:
+  case Stmt::BreakStmtClass:
+  case Stmt::ContinueStmtClass:
+  case Stmt::NullStmtClass:
     return true;
+  case Stmt::CStyleCastExprClass: {
+    const CStyleCastExpr* CastExpr1 = cast<CStyleCastExpr>(Stmt1);
+    const CStyleCastExpr* CastExpr2 = cast<CStyleCastExpr>(Stmt2);
+
+    return CastExpr1->getTypeAsWritten() == CastExpr2->getTypeAsWritten();
+  }
+  case Stmt::ReturnStmtClass: {
+    const ReturnStmt *ReturnStmt1 = cast<ReturnStmt>(Stmt1);
+    const ReturnStmt *ReturnStmt2 = cast<ReturnStmt>(Stmt2);
+
+    return isIdenticalStmt(Ctx, ReturnStmt1->getRetValue(),
+                           ReturnStmt2->getRetValue(), IgnoreSideEffects);
+  }
+  case Stmt::ForStmtClass: {
+    const ForStmt *ForStmt1 = cast<ForStmt>(Stmt1);
+    const ForStmt *ForStmt2 = cast<ForStmt>(Stmt2);
+
+    if (!isIdenticalStmt(Ctx, ForStmt1->getInit(), ForStmt2->getInit(),
+                         IgnoreSideEffects))
+      return false;
+    if (!isIdenticalStmt(Ctx, ForStmt1->getCond(), ForStmt2->getCond(),
+                         IgnoreSideEffects))
+      return false;
+    if (!isIdenticalStmt(Ctx, ForStmt1->getInc(), ForStmt2->getInc(),
+                         IgnoreSideEffects))
+      return false;
+    if (!isIdenticalStmt(Ctx, ForStmt1->getBody(), ForStmt2->getBody(),
+                         IgnoreSideEffects))
+      return false;
+    return true;
+  }
+  case Stmt::DoStmtClass: {
+    const DoStmt *DStmt1 = cast<DoStmt>(Stmt1);
+    const DoStmt *DStmt2 = cast<DoStmt>(Stmt2);
+
+    if (!isIdenticalStmt(Ctx, DStmt1->getCond(), DStmt2->getCond(),
+                         IgnoreSideEffects))
+      return false;
+    if (!isIdenticalStmt(Ctx, DStmt1->getBody(), DStmt2->getBody(),
+                         IgnoreSideEffects))
+      return false;
+    return true;
+  }
+  case Stmt::WhileStmtClass: {
+    const WhileStmt *WStmt1 = cast<WhileStmt>(Stmt1);
+    const WhileStmt *WStmt2 = cast<WhileStmt>(Stmt2);
+
+    if (!isIdenticalStmt(Ctx, WStmt1->getCond(), WStmt2->getCond(),
+                         IgnoreSideEffects))
+      return false;
+    if (!isIdenticalStmt(Ctx, WStmt1->getBody(), WStmt2->getBody(),
+                         IgnoreSideEffects))
+      return false;
+    return true;
+  }
+  case Stmt::IfStmtClass: {
+    const IfStmt *IStmt1 = cast<IfStmt>(Stmt1);
+    const IfStmt *IStmt2 = cast<IfStmt>(Stmt2);
+
+    if (!isIdenticalStmt(Ctx, IStmt1->getCond(), IStmt2->getCond(),
+                         IgnoreSideEffects))
+      return false;
+    if (!isIdenticalStmt(Ctx, IStmt1->getThen(), IStmt2->getThen(),
+                         IgnoreSideEffects))
+      return false;
+    if (!isIdenticalStmt(Ctx, IStmt1->getElse(), IStmt2->getElse(),
+                         IgnoreSideEffects))
+      return false;
+    return true;
+  }
+  case Stmt::CompoundStmtClass: {
+    const CompoundStmt *CompStmt1 = cast<CompoundStmt>(Stmt1);
+    const CompoundStmt *CompStmt2 = cast<CompoundStmt>(Stmt2);
+
+    if (CompStmt1->size() != CompStmt2->size())
+      return false;
+
+    CompoundStmt::const_body_iterator I1 = CompStmt1->body_begin();
+    CompoundStmt::const_body_iterator I2 = CompStmt2->body_begin();
+    while (I1 != CompStmt1->body_end() && I2 != CompStmt2->body_end()) {
+      if (!isIdenticalStmt(Ctx, *I1, *I2, IgnoreSideEffects))
+        return false;
+      ++I1;
+      ++I2;
+    }
+
+    return true;
+  }
+  case Stmt::CompoundAssignOperatorClass:
   case Stmt::BinaryOperatorClass: {
-    const BinaryOperator *BinOp1 = dyn_cast<BinaryOperator>(Expr1);
-    const BinaryOperator *BinOp2 = dyn_cast<BinaryOperator>(Expr2);
+    const BinaryOperator *BinOp1 = cast<BinaryOperator>(Stmt1);
+    const BinaryOperator *BinOp2 = cast<BinaryOperator>(Stmt2);
     return BinOp1->getOpcode() == BinOp2->getOpcode();
   }
   case Stmt::CharacterLiteralClass: {
-    const CharacterLiteral *CharLit1 = dyn_cast<CharacterLiteral>(Expr1);
-    const CharacterLiteral *CharLit2 = dyn_cast<CharacterLiteral>(Expr2);
+    const CharacterLiteral *CharLit1 = cast<CharacterLiteral>(Stmt1);
+    const CharacterLiteral *CharLit2 = cast<CharacterLiteral>(Stmt2);
     return CharLit1->getValue() == CharLit2->getValue();
   }
   case Stmt::DeclRefExprClass: {
-    const DeclRefExpr *DeclRef1 = dyn_cast<DeclRefExpr>(Expr1);
-    const DeclRefExpr *DeclRef2 = dyn_cast<DeclRefExpr>(Expr2);
+    const DeclRefExpr *DeclRef1 = cast<DeclRefExpr>(Stmt1);
+    const DeclRefExpr *DeclRef2 = cast<DeclRefExpr>(Stmt2);
     return DeclRef1->getDecl() == DeclRef2->getDecl();
   }
   case Stmt::IntegerLiteralClass: {
-    const IntegerLiteral *IntLit1 = dyn_cast<IntegerLiteral>(Expr1);
-    const IntegerLiteral *IntLit2 = dyn_cast<IntegerLiteral>(Expr2);
+    const IntegerLiteral *IntLit1 = cast<IntegerLiteral>(Stmt1);
+    const IntegerLiteral *IntLit2 = cast<IntegerLiteral>(Stmt2);
     return IntLit1->getValue() == IntLit2->getValue();
   }
   case Stmt::FloatingLiteralClass: {
-    const FloatingLiteral *FloatLit1 = dyn_cast<FloatingLiteral>(Expr1);
-    const FloatingLiteral *FloatLit2 = dyn_cast<FloatingLiteral>(Expr2);
+    const FloatingLiteral *FloatLit1 = cast<FloatingLiteral>(Stmt1);
+    const FloatingLiteral *FloatLit2 = cast<FloatingLiteral>(Stmt2);
     return FloatLit1->getValue().bitwiseIsEqual(FloatLit2->getValue());
   }
+  case Stmt::StringLiteralClass: {
+    const StringLiteral *StringLit1 = cast<StringLiteral>(Stmt1);
+    const StringLiteral *StringLit2 = cast<StringLiteral>(Stmt2);
+    return StringLit1->getString() == StringLit2->getString();
+  }
   case Stmt::MemberExprClass: {
-    const MemberExpr *MemberExpr1 = dyn_cast<MemberExpr>(Expr1);
-    const MemberExpr *MemberExpr2 = dyn_cast<MemberExpr>(Expr2);
-    return MemberExpr1->getMemberDecl() == MemberExpr2->getMemberDecl();
+    const MemberExpr *MemberStmt1 = cast<MemberExpr>(Stmt1);
+    const MemberExpr *MemberStmt2 = cast<MemberExpr>(Stmt2);
+    return MemberStmt1->getMemberDecl() == MemberStmt2->getMemberDecl();
   }
   case Stmt::UnaryOperatorClass: {
-    const UnaryOperator *UnaryOp1 = dyn_cast<UnaryOperator>(Expr1);
-    const UnaryOperator *UnaryOp2 = dyn_cast<UnaryOperator>(Expr2);
-    if (UnaryOp1->getOpcode() != UnaryOp2->getOpcode())
-      return false;
-    return !UnaryOp1->isIncrementDecrementOp();
+    const UnaryOperator *UnaryOp1 = cast<UnaryOperator>(Stmt1);
+    const UnaryOperator *UnaryOp2 = cast<UnaryOperator>(Stmt2);
+    return UnaryOp1->getOpcode() == UnaryOp2->getOpcode();
   }
   }
 }
@@ -215,7 +479,7 @@
 public:
   void checkASTCodeBody(const Decl *D, AnalysisManager &Mgr,
                         BugReporter &BR) const {
-    FindIdenticalExprVisitor Visitor(BR, Mgr.getAnalysisDeclContext(D));
+    FindIdenticalExprVisitor Visitor(BR, this, Mgr.getAnalysisDeclContext(D));
     Visitor.TraverseDecl(const_cast<Decl *>(D));
   }
 };
diff --git a/lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp b/lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp
index cc940be..1926600 100644
--- a/lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp
@@ -49,6 +49,9 @@
   DefaultBool check_MissingInvalidationMethod;
   /// Check that all ivars are invalidated.
   DefaultBool check_InstanceVariableInvalidation;
+
+  CheckName checkName_MissingInvalidationMethod;
+  CheckName checkName_InstanceVariableInvalidation;
 };
 
 class IvarInvalidationCheckerImpl {
@@ -154,7 +157,7 @@
       PropertySetterToIvarMap(InPropertySetterToIvarMap),
       PropertyGetterToIvarMap(InPropertyGetterToIvarMap),
       PropertyToIvarMap(InPropertyToIvarMap),
-      InvalidationMethod(0),
+      InvalidationMethod(nullptr),
       Ctx(InCtx) {}
 
     void VisitStmt(const Stmt *S) { VisitChildren(S); }
@@ -200,7 +203,8 @@
                         const ObjCIvarDecl *IvarDecl,
                         const IvarToPropMapTy &IvarToPopertyMap);
 
-  void reportNoInvalidationMethod(const ObjCIvarDecl *FirstIvarDecl,
+  void reportNoInvalidationMethod(CheckName CheckName,
+                                  const ObjCIvarDecl *FirstIvarDecl,
                                   const IvarToPropMapTy &IvarToPopertyMap,
                                   const ObjCInterfaceDecl *InterfaceD,
                                   bool MissingDeclaration) const;
@@ -223,10 +227,7 @@
 };
 
 static bool isInvalidationMethod(const ObjCMethodDecl *M, bool LookForPartial) {
-  for (specific_attr_iterator<AnnotateAttr>
-       AI = M->specific_attr_begin<AnnotateAttr>(),
-       AE = M->specific_attr_end<AnnotateAttr>(); AI != AE; ++AI) {
-    const AnnotateAttr *Ann = *AI;
+  for (const auto *Ann : M->specific_attrs<AnnotateAttr>()) {
     if (!LookForPartial &&
         Ann->getAnnotation() == "objc_instance_variable_invalidator")
       return true;
@@ -247,33 +248,22 @@
   // TODO: Cache the results.
 
   // Check all methods.
-  for (ObjCContainerDecl::method_iterator
-      I = D->meth_begin(),
-      E = D->meth_end(); I != E; ++I) {
-      const ObjCMethodDecl *MDI = *I;
-      if (isInvalidationMethod(MDI, Partial))
-        OutInfo.addInvalidationMethod(
-                               cast<ObjCMethodDecl>(MDI->getCanonicalDecl()));
-  }
+  for (const auto *MDI : D->methods())
+    if (isInvalidationMethod(MDI, Partial))
+      OutInfo.addInvalidationMethod(
+          cast<ObjCMethodDecl>(MDI->getCanonicalDecl()));
 
   // If interface, check all parent protocols and super.
   if (const ObjCInterfaceDecl *InterfD = dyn_cast<ObjCInterfaceDecl>(D)) {
 
     // Visit all protocols.
-    for (ObjCInterfaceDecl::protocol_iterator
-        I = InterfD->protocol_begin(),
-        E = InterfD->protocol_end(); I != E; ++I) {
-      containsInvalidationMethod((*I)->getDefinition(), OutInfo, Partial);
-    }
+    for (const auto *I : InterfD->protocols())
+      containsInvalidationMethod(I->getDefinition(), OutInfo, Partial);
 
     // Visit all categories in case the invalidation method is declared in
     // a category.
-    for (ObjCInterfaceDecl::visible_extensions_iterator
-           Ext = InterfD->visible_extensions_begin(),
-           ExtEnd = InterfD->visible_extensions_end();
-         Ext != ExtEnd; ++Ext) {
-      containsInvalidationMethod(*Ext, OutInfo, Partial);
-    }
+    for (const auto *Ext : InterfD->visible_extensions())
+      containsInvalidationMethod(Ext, OutInfo, Partial);
 
     containsInvalidationMethod(InterfD->getSuperClass(), OutInfo, Partial);
     return;
@@ -281,10 +271,8 @@
 
   // If protocol, check all parent protocols.
   if (const ObjCProtocolDecl *ProtD = dyn_cast<ObjCProtocolDecl>(D)) {
-    for (ObjCInterfaceDecl::protocol_iterator
-        I = ProtD->protocol_begin(),
-        E = ProtD->protocol_end(); I != E; ++I) {
-      containsInvalidationMethod((*I)->getDefinition(), OutInfo, Partial);
+    for (const auto *I : ProtD->protocols()) {
+      containsInvalidationMethod(I->getDefinition(), OutInfo, Partial);
     }
     return;
   }
@@ -318,7 +306,7 @@
                         const ObjCInterfaceDecl *InterfaceD,
                         IvarSet &TrackedIvars,
                         const ObjCIvarDecl **FirstIvarDecl) {
-  const ObjCIvarDecl *IvarD = 0;
+  const ObjCIvarDecl *IvarD = nullptr;
 
   // Lookup for the synthesized case.
   IvarD = Prop->getPropertyIvarDecl();
@@ -355,7 +343,7 @@
   // Note, this is a possible source of false positives. We could look at the
   // getter implementation to find the ivar when its name is not derived from
   // the property name.
-  return 0;
+  return nullptr;
 }
 
 void IvarInvalidationCheckerImpl::printIvar(llvm::raw_svector_ostream &os,
@@ -379,7 +367,7 @@
   // Record the first Ivar needing invalidation; used in reporting when only
   // one ivar is sufficient. Cannot grab the first on the Ivars set to ensure
   // deterministic output.
-  const ObjCIvarDecl *FirstIvarDecl = 0;
+  const ObjCIvarDecl *FirstIvarDecl = nullptr;
   const ObjCInterfaceDecl *InterfaceD = ImplD->getClassInterface();
 
   // Collect ivars declared in this class, its extensions and its implementation
@@ -476,7 +464,8 @@
   // Report an error in case none of the invalidation methods are declared.
   if (!Info.needsInvalidation() && !PartialInfo.needsInvalidation()) {
     if (Filter.check_MissingInvalidationMethod)
-      reportNoInvalidationMethod(FirstIvarDecl, IvarToPopertyMap, InterfaceD,
+      reportNoInvalidationMethod(Filter.checkName_MissingInvalidationMethod,
+                                 FirstIvarDecl, IvarToPopertyMap, InterfaceD,
                                  /*MissingDeclaration*/ true);
     // If there are no invalidation methods, there is no ivar validation work
     // to be done.
@@ -529,20 +518,20 @@
       // invalidation methods.
       for (IvarSet::const_iterator
            I = Ivars.begin(), E = Ivars.end(); I != E; ++I)
-        reportIvarNeedsInvalidation(I->first, IvarToPopertyMap, 0);
+        reportIvarNeedsInvalidation(I->first, IvarToPopertyMap, nullptr);
     } else {
       // Otherwise, no invalidation methods were implemented.
-      reportNoInvalidationMethod(FirstIvarDecl, IvarToPopertyMap, InterfaceD,
+      reportNoInvalidationMethod(Filter.checkName_InstanceVariableInvalidation,
+                                 FirstIvarDecl, IvarToPopertyMap, InterfaceD,
                                  /*MissingDeclaration*/ false);
     }
   }
 }
 
-void IvarInvalidationCheckerImpl::
-reportNoInvalidationMethod(const ObjCIvarDecl *FirstIvarDecl,
-                           const IvarToPropMapTy &IvarToPopertyMap,
-                           const ObjCInterfaceDecl *InterfaceD,
-                           bool MissingDeclaration) const {
+void IvarInvalidationCheckerImpl::reportNoInvalidationMethod(
+    CheckName CheckName, const ObjCIvarDecl *FirstIvarDecl,
+    const IvarToPropMapTy &IvarToPopertyMap,
+    const ObjCInterfaceDecl *InterfaceD, bool MissingDeclaration) const {
   SmallString<128> sbuf;
   llvm::raw_svector_ostream os(sbuf);
   assert(FirstIvarDecl);
@@ -557,7 +546,7 @@
   PathDiagnosticLocation IvarDecLocation =
     PathDiagnosticLocation::createBegin(FirstIvarDecl, BR.getSourceManager());
 
-  BR.EmitBasicReport(FirstIvarDecl, "Incomplete invalidation",
+  BR.EmitBasicReport(FirstIvarDecl, CheckName, "Incomplete invalidation",
                      categories::CoreFoundationObjectiveC, os.str(),
                      IvarDecLocation);
 }
@@ -575,15 +564,16 @@
                            PathDiagnosticLocation::createEnd(MethodD->getBody(),
                            BR.getSourceManager(),
                            Mgr.getAnalysisDeclContext(MethodD));
-    BR.EmitBasicReport(MethodD, "Incomplete invalidation",
+    BR.EmitBasicReport(MethodD, Filter.checkName_InstanceVariableInvalidation,
+                       "Incomplete invalidation",
                        categories::CoreFoundationObjectiveC, os.str(),
                        MethodDecLocation);
   } else {
-    BR.EmitBasicReport(IvarD, "Incomplete invalidation",
-                       categories::CoreFoundationObjectiveC, os.str(),
-                       PathDiagnosticLocation::createBegin(IvarD,
-                                                        BR.getSourceManager()));
-                       
+    BR.EmitBasicReport(
+        IvarD, Filter.checkName_InstanceVariableInvalidation,
+        "Incomplete invalidation", categories::CoreFoundationObjectiveC,
+        os.str(),
+        PathDiagnosticLocation::createBegin(IvarD, BR.getSourceManager()));
   }
 }
 
@@ -727,7 +717,7 @@
   if (Receiver) {
     InvalidationMethod = MD;
     check(Receiver->IgnoreParenCasts());
-    InvalidationMethod = 0;
+    InvalidationMethod = nullptr;
   }
 
   VisitStmt(ME);
@@ -750,10 +740,13 @@
 };
 }
 
-#define REGISTER_CHECKER(name) \
-void ento::register##name(CheckerManager &mgr) {\
-  mgr.registerChecker<IvarInvalidationChecker>()->Filter.check_##name = true;\
-}
+#define REGISTER_CHECKER(name)                                                 \
+  void ento::register##name(CheckerManager &mgr) {                             \
+    IvarInvalidationChecker *checker =                                         \
+        mgr.registerChecker<IvarInvalidationChecker>();                        \
+    checker->Filter.check_##name = true;                                       \
+    checker->Filter.checkName_##name = mgr.getCurrentCheckName();              \
+  }
 
 REGISTER_CHECKER(InstanceVariableInvalidation)
 REGISTER_CHECKER(MissingInvalidationMethod)
diff --git a/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp b/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp
index 02a7cc3..0b7375a 100644
--- a/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp
@@ -58,7 +58,7 @@
 
   const TypedefNameDecl *TD = TT->getDecl();
 
-  if (!InNamespace(TD, "std"))
+  if (!TD->isInStdNamespace())
     return false;
 
   return TD->getName() == "string";
@@ -115,11 +115,14 @@
 
 namespace {
 class StringRefCheckerVisitor : public StmtVisitor<StringRefCheckerVisitor> {
-  BugReporter &BR;
   const Decl *DeclWithIssue;
+  BugReporter &BR;
+  const CheckerBase *Checker;
+
 public:
-  StringRefCheckerVisitor(const Decl *declWithIssue, BugReporter &br)
-    : BR(br), DeclWithIssue(declWithIssue) {}
+  StringRefCheckerVisitor(const Decl *declWithIssue, BugReporter &br,
+                          const CheckerBase *checker)
+      : DeclWithIssue(declWithIssue), BR(br), Checker(checker) {}
   void VisitChildren(Stmt *S) {
     for (Stmt::child_iterator I = S->child_begin(), E = S->child_end() ;
       I != E; ++I)
@@ -133,16 +136,17 @@
 };
 } // end anonymous namespace
 
-static void CheckStringRefAssignedTemporary(const Decl *D, BugReporter &BR) {
-  StringRefCheckerVisitor walker(D, BR);
+static void CheckStringRefAssignedTemporary(const Decl *D, BugReporter &BR,
+                                            const CheckerBase *Checker) {
+  StringRefCheckerVisitor walker(D, BR, Checker);
   walker.Visit(D->getBody());
 }
 
 void StringRefCheckerVisitor::VisitDeclStmt(DeclStmt *S) {
   VisitChildren(S);
 
-  for (DeclStmt::decl_iterator I = S->decl_begin(), E = S->decl_end();I!=E; ++I)
-    if (VarDecl *VD = dyn_cast<VarDecl>(*I))
+  for (auto *I : S->decls())
+    if (VarDecl *VD = dyn_cast<VarDecl>(I))
       VisitVarDecl(VD);
 }
 
@@ -179,7 +183,7 @@
                      "std::string that it outlives";
   PathDiagnosticLocation VDLoc =
     PathDiagnosticLocation::createBegin(VD, BR.getSourceManager());
-  BR.EmitBasicReport(DeclWithIssue, desc, "LLVM Conventions", desc,
+  BR.EmitBasicReport(DeclWithIssue, Checker, desc, "LLVM Conventions", desc,
                      VDLoc, Init->getSourceRange());
 }
 
@@ -197,9 +201,7 @@
   if (IsClangStmt(R) || IsClangType(R) || IsClangDecl(R) || IsClangAttr(R))
     return true;
 
-  for (CXXRecordDecl::base_class_const_iterator I = R->bases_begin(),
-                                                E = R->bases_end(); I!=E; ++I) {
-    CXXBaseSpecifier BS = *I;
+  for (const auto &BS : R->bases()) {
     QualType T = BS.getType();
     if (const RecordType *baseT = T->getAs<RecordType>()) {
       CXXRecordDecl *baseD = cast<CXXRecordDecl>(baseT->getDecl());
@@ -216,23 +218,26 @@
   SmallVector<FieldDecl*, 10> FieldChain;
   const CXXRecordDecl *Root;
   BugReporter &BR;
+  const CheckerBase *Checker;
+
 public:
-  ASTFieldVisitor(const CXXRecordDecl *root, BugReporter &br)
-    : Root(root), BR(br) {}
+  ASTFieldVisitor(const CXXRecordDecl *root, BugReporter &br,
+                  const CheckerBase *checker)
+      : Root(root), BR(br), Checker(checker) {}
 
   void Visit(FieldDecl *D);
   void ReportError(QualType T);
 };
 } // end anonymous namespace
 
-static void CheckASTMemory(const CXXRecordDecl *R, BugReporter &BR) {
+static void CheckASTMemory(const CXXRecordDecl *R, BugReporter &BR,
+                           const CheckerBase *Checker) {
   if (!IsPartOfAST(R))
     return;
 
-  for (RecordDecl::field_iterator I = R->field_begin(), E = R->field_end();
-       I != E; ++I) {
-    ASTFieldVisitor walker(R, BR);
-    walker.Visit(*I);
+  for (auto *I : R->fields()) {
+    ASTFieldVisitor walker(R, BR, Checker);
+    walker.Visit(I);
   }
 }
 
@@ -246,9 +251,8 @@
 
   if (const RecordType *RT = T->getAs<RecordType>()) {
     const RecordDecl *RD = RT->getDecl()->getDefinition();
-    for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
-         I != E; ++I)
-      Visit(*I);
+    for (auto *I : RD->fields())
+      Visit(I);
   }
 
   FieldChain.pop_back();
@@ -284,8 +288,8 @@
   // the class may be in the header file, for example).
   PathDiagnosticLocation L = PathDiagnosticLocation::createBegin(
                                FieldChain.front(), BR.getSourceManager());
-  BR.EmitBasicReport(Root, "AST node allocates heap memory", "LLVM Conventions",
-                     os.str(), L);
+  BR.EmitBasicReport(Root, Checker, "AST node allocates heap memory",
+                     "LLVM Conventions", os.str(), L);
 }
 
 //===----------------------------------------------------------------------===//
@@ -300,12 +304,12 @@
   void checkASTDecl(const CXXRecordDecl *R, AnalysisManager& mgr,
                     BugReporter &BR) const {
     if (R->isCompleteDefinition())
-      CheckASTMemory(R, BR);
+      CheckASTMemory(R, BR, this);
   }
 
   void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
                         BugReporter &BR) const {
-    CheckStringRefAssignedTemporary(D, BR);
+    CheckStringRefAssignedTemporary(D, BR, this);
   }
 };
 }
diff --git a/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp b/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
index f1f06c7..0f227bb 100644
--- a/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
@@ -29,7 +29,7 @@
 class MacOSKeychainAPIChecker : public Checker<check::PreStmt<CallExpr>,
                                                check::PostStmt<CallExpr>,
                                                check::DeadSymbols> {
-  mutable OwningPtr<BugType> BT;
+  mutable std::unique_ptr<BugType> BT;
 
 public:
   /// AllocationState is a part of the checker specific state together with the
@@ -91,7 +91,7 @@
 
   inline void initBugType() const {
     if (!BT)
-      BT.reset(new BugType("Improper use of SecKeychain API",
+      BT.reset(new BugType(this, "Improper use of SecKeychain API",
                            "API Misuse (Apple)"));
   }
 
@@ -139,7 +139,7 @@
     SecKeychainBugVisitor(SymbolRef S) : Sym(S) {}
     virtual ~SecKeychainBugVisitor() {}
 
-    void Profile(llvm::FoldingSetNodeID &ID) const {
+    void Profile(llvm::FoldingSetNodeID &ID) const override {
       static int X = 0;
       ID.AddPointer(&X);
       ID.AddPointer(Sym);
@@ -148,7 +148,7 @@
     PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
                                    const ExplodedNode *PrevN,
                                    BugReporterContext &BRC,
-                                   BugReport &BR);
+                                   BugReport &BR) override;
   };
 };
 }
@@ -224,7 +224,7 @@
     if (sym)
       return sym;
   }
-  return 0;
+  return nullptr;
 }
 
 // When checking for error code, we need to consider the following cases:
@@ -458,7 +458,7 @@
   // If the argument entered as an enclosing function parameter, skip it to
   // avoid false positives.
   if (isEnclosingFunctionParam(ArgExpr) &&
-      C.getLocationContext()->getParent() == 0)
+      C.getLocationContext()->getParent() == nullptr)
     return;
 
   if (SymbolRef V = getAsPointeeSymbol(ArgExpr, C)) {
@@ -503,7 +503,7 @@
     // symbol was tracked.
     if (N->getLocationContext() == LeakContext)
       AllocNode = N;
-    N = N->pred_empty() ? NULL : *(N->pred_begin());
+    N = N->pred_empty() ? nullptr : *(N->pred_begin());
   }
 
   return AllocNode;
@@ -525,7 +525,7 @@
   // allocated, and only report a single path.
   PathDiagnosticLocation LocUsedForUniqueing;
   const ExplodedNode *AllocNode = getAllocationNode(N, AP.first, C);
-  const Stmt *AllocStmt = 0;
+  const Stmt *AllocStmt = nullptr;
   ProgramPoint P = AllocNode->getLocation();
   if (Optional<CallExitEnd> Exit = P.getAs<CallExitEnd>())
     AllocStmt = Exit->getCalleeContext()->getCallSite();
@@ -575,7 +575,7 @@
     return;
   }
 
-  static SimpleProgramPointTag Tag("MacOSKeychainAPIChecker : DeadSymbolsLeak");
+  static CheckerProgramPointTag Tag(this, "DeadSymbolsLeak");
   ExplodedNode *N = C.addTransition(C.getState(), C.getPredecessor(), &Tag);
 
   // Generate the error reports.
@@ -596,10 +596,10 @@
                                                       BugReport &BR) {
   const AllocationState *AS = N->getState()->get<AllocatedData>(Sym);
   if (!AS)
-    return 0;
+    return nullptr;
   const AllocationState *ASPrev = PrevN->getState()->get<AllocatedData>(Sym);
   if (ASPrev)
-    return 0;
+    return nullptr;
 
   // (!ASPrev && AS) ~ We started tracking symbol in node N, it must be the
   // allocation site.
diff --git a/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp b/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp
index 32ebb51..13a401d 100644
--- a/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp
@@ -31,7 +31,7 @@
 
 namespace {
 class MacOSXAPIChecker : public Checker< check::PreStmt<CallExpr> > {
-  mutable OwningPtr<BugType> BT_dispatchOnce;
+  mutable std::unique_ptr<BugType> BT_dispatchOnce;
 
 public:
   void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
@@ -67,7 +67,7 @@
     return;
 
   if (!BT_dispatchOnce)
-    BT_dispatchOnce.reset(new BugType("Improper use of 'dispatch_once'",
+    BT_dispatchOnce.reset(new BugType(this, "Improper use of 'dispatch_once'",
                                       "API Misuse (Apple)"));
 
   // Handle _dispatch_once.  In some versions of the OS X SDK we have the case
@@ -113,7 +113,7 @@
              "_dispatch_once",
              "dispatch_once_f",
              &MacOSXAPIChecker::CheckDispatchOnce)
-      .Default(NULL);
+      .Default(nullptr);
 
   if (SC)
     (this->*SC)(C, CE, Name);
diff --git a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
index c7aa0fb..a03fa25 100644
--- a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -16,6 +16,7 @@
 #include "InterCheckerAPI.h"
 #include "clang/AST/Attr.h"
 #include "clang/Basic/SourceManager.h"
+#include "clang/Basic/TargetInfo.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
@@ -48,7 +49,7 @@
               Allocated,
               // Reference to released/freed memory.
               Released,
-              // The responsibility for freeing resources has transfered from
+              // The responsibility for freeing resources has transferred from
               // this reference. A relinquished symbol should not be freed.
               Relinquished,
               // We are no longer guaranteed to have observed all manipulations
@@ -100,17 +101,16 @@
   }
 
   void dump(raw_ostream &OS) const {
-    static const char *const Table[] = {
-      "Allocated",
-      "Released",
-      "Relinquished"
-    };
-    OS << Table[(unsigned) K];
+    switch (static_cast<Kind>(K)) {
+#define CASE(ID) case ID: OS << #ID; break;
+    CASE(Allocated)
+    CASE(Released)
+    CASE(Relinquished)
+    CASE(Escaped)
+    }
   }
 
-  LLVM_ATTRIBUTE_USED void dump() const {
-    dump(llvm::errs());
-  }
+  LLVM_DUMP_METHOD void dump() const { dump(llvm::errs()); }
 };
 
 enum ReallocPairKind {
@@ -156,30 +156,25 @@
                                      check::Location,
                                      eval::Assume>
 {
-  mutable OwningPtr<BugType> BT_DoubleFree;
-  mutable OwningPtr<BugType> BT_Leak;
-  mutable OwningPtr<BugType> BT_UseFree;
-  mutable OwningPtr<BugType> BT_BadFree;
-  mutable OwningPtr<BugType> BT_MismatchedDealloc;
-  mutable OwningPtr<BugType> BT_OffsetFree;
-  mutable IdentifierInfo *II_malloc, *II_free, *II_realloc, *II_calloc,
-                         *II_valloc, *II_reallocf, *II_strndup, *II_strdup;
-
 public:
-  MallocChecker() : II_malloc(0), II_free(0), II_realloc(0), II_calloc(0),
-                    II_valloc(0), II_reallocf(0), II_strndup(0), II_strdup(0) {}
+  MallocChecker()
+      : II_malloc(nullptr), II_free(nullptr), II_realloc(nullptr),
+        II_calloc(nullptr), II_valloc(nullptr), II_reallocf(nullptr),
+        II_strndup(nullptr), II_strdup(nullptr), II_kmalloc(nullptr) {}
 
   /// In pessimistic mode, the checker assumes that it does not know which
   /// functions might free the memory.
-  struct ChecksFilter {
-    DefaultBool CMallocPessimistic;
-    DefaultBool CMallocOptimistic;
-    DefaultBool CNewDeleteChecker;
-    DefaultBool CNewDeleteLeaksChecker;
-    DefaultBool CMismatchedDeallocatorChecker;
+  enum CheckKind {
+    CK_MallocPessimistic,
+    CK_MallocOptimistic,
+    CK_NewDeleteChecker,
+    CK_NewDeleteLeaksChecker,
+    CK_MismatchedDeallocatorChecker,
+    CK_NumCheckKinds
   };
 
-  ChecksFilter Filter;
+  DefaultBool ChecksEnabled[CK_NumCheckKinds];
+  CheckName CheckNames[CK_NumCheckKinds];
 
   void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
   void checkPostStmt(const CallExpr *CE, CheckerContext &C) const;
@@ -204,9 +199,21 @@
                                           PointerEscapeKind Kind) const;
 
   void printState(raw_ostream &Out, ProgramStateRef State,
-                  const char *NL, const char *Sep) const;
+                  const char *NL, const char *Sep) const override;
 
 private:
+  mutable std::unique_ptr<BugType> BT_DoubleFree[CK_NumCheckKinds];
+  mutable std::unique_ptr<BugType> BT_DoubleDelete;
+  mutable std::unique_ptr<BugType> BT_Leak[CK_NumCheckKinds];
+  mutable std::unique_ptr<BugType> BT_UseFree[CK_NumCheckKinds];
+  mutable std::unique_ptr<BugType> BT_BadFree[CK_NumCheckKinds];
+  mutable std::unique_ptr<BugType> BT_MismatchedDealloc;
+  mutable std::unique_ptr<BugType> BT_OffsetFree[CK_NumCheckKinds];
+  mutable IdentifierInfo *II_malloc, *II_free, *II_realloc, *II_calloc,
+                         *II_valloc, *II_reallocf, *II_strndup, *II_strdup,
+                         *II_kmalloc;
+  mutable Optional<uint64_t> KernelZeroFlagVal;
+
   void initIdentifierInfo(ASTContext &C) const;
 
   /// \brief Determine family of a deallocation expression.
@@ -234,9 +241,9 @@
   bool isAllocationFunction(const FunctionDecl *FD, ASTContext &C) const;
   bool isStandardNewDelete(const FunctionDecl *FD, ASTContext &C) const;
   ///@}
-  static ProgramStateRef MallocMemReturnsAttr(CheckerContext &C,
-                                              const CallExpr *CE,
-                                              const OwnershipAttr* Att);
+  ProgramStateRef MallocMemReturnsAttr(CheckerContext &C,
+                                       const CallExpr *CE,
+                                       const OwnershipAttr* Att) const;
   static ProgramStateRef MallocMemAux(CheckerContext &C, const CallExpr *CE,
                                      const Expr *SizeEx, SVal Init,
                                      ProgramStateRef State,
@@ -251,6 +258,12 @@
                                      ProgramStateRef State,
                                      AllocationFamily Family = AF_Malloc);
 
+  // Check if this malloc() for special flags. At present that means M_ZERO or
+  // __GFP_ZERO (in which case, treat it like calloc).
+  llvm::Optional<ProgramStateRef>
+  performKernelMalloc(const CallExpr *CE, CheckerContext &C,
+                      const ProgramStateRef &State) const;
+
   /// Update the RefState to reflect the new memory allocation.
   static ProgramStateRef 
   MallocUpdateRefState(CheckerContext &C, const Expr *E, ProgramStateRef State,
@@ -279,6 +292,8 @@
 
   bool checkUseAfterFree(SymbolRef Sym, CheckerContext &C, const Stmt *S) const;
 
+  bool checkDoubleDelete(SymbolRef Sym, CheckerContext &C) const;
+
   /// Check if the function is known free memory, or if it is
   /// "interesting" and should be modeled explicitly.
   ///
@@ -302,10 +317,12 @@
 
   ///@{
   /// Tells if a given family/call/symbol is tracked by the current checker.
-  bool isTrackedByCurrentChecker(AllocationFamily Family) const;
-  bool isTrackedByCurrentChecker(CheckerContext &C,
-                                 const Stmt *AllocDeallocStmt) const;
-  bool isTrackedByCurrentChecker(CheckerContext &C, SymbolRef Sym) const;
+  /// Sets CheckKind to the kind of the checker responsible for this
+  /// family/call/symbol.
+  Optional<CheckKind> getCheckIfTracked(AllocationFamily Family) const;
+  Optional<CheckKind> getCheckIfTracked(CheckerContext &C,
+                                        const Stmt *AllocDeallocStmt) const;
+  Optional<CheckKind> getCheckIfTracked(CheckerContext &C, SymbolRef Sym) const;
   ///@}
   static bool SummarizeValue(raw_ostream &os, SVal V);
   static bool SummarizeRegion(raw_ostream &os, const MemRegion *MR);
@@ -316,12 +333,14 @@
                                SymbolRef Sym, bool OwnershipTransferred) const;
   void ReportOffsetFree(CheckerContext &C, SVal ArgVal, SourceRange Range, 
                         const Expr *DeallocExpr, 
-                        const Expr *AllocExpr = 0) const;
+                        const Expr *AllocExpr = nullptr) const;
   void ReportUseAfterFree(CheckerContext &C, SourceRange Range,
                           SymbolRef Sym) const;
   void ReportDoubleFree(CheckerContext &C, SourceRange Range, bool Released,
                         SymbolRef Sym, SymbolRef PrevSym) const;
 
+  void ReportDoubleDelete(CheckerContext &C, SymbolRef Sym) const;
+
   /// Find the location of the allocation for Sym on the path leading to the
   /// exploded node N.
   LeakInfo getAllocationSite(const ExplodedNode *N, SymbolRef Sym,
@@ -352,11 +371,11 @@
 
   public:
     MallocBugVisitor(SymbolRef S, bool isLeak = false)
-       : Sym(S), Mode(Normal), FailedReallocSymbol(0), IsLeak(isLeak) {}
+       : Sym(S), Mode(Normal), FailedReallocSymbol(nullptr), IsLeak(isLeak) {}
 
     virtual ~MallocBugVisitor() {}
 
-    void Profile(llvm::FoldingSetNodeID &ID) const {
+    void Profile(llvm::FoldingSetNodeID &ID) const override {
       static int X = 0;
       ID.AddPointer(&X);
       ID.AddPointer(Sym);
@@ -398,13 +417,13 @@
     PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
                                    const ExplodedNode *PrevN,
                                    BugReporterContext &BRC,
-                                   BugReport &BR);
+                                   BugReport &BR) override;
 
     PathDiagnosticPiece* getEndPath(BugReporterContext &BRC,
                                     const ExplodedNode *EndPathNode,
-                                    BugReport &BR) {
+                                    BugReport &BR) override {
       if (!IsLeak)
-        return 0;
+        return nullptr;
 
       PathDiagnosticLocation L =
         PathDiagnosticLocation::createEndOfPath(EndPathNode,
@@ -420,7 +439,8 @@
       StackHintGeneratorForReallocationFailed(SymbolRef S, StringRef M)
         : StackHintGeneratorForSymbol(S, M) {}
 
-      virtual std::string getMessageForArg(const Expr *ArgE, unsigned ArgIndex) {
+      std::string getMessageForArg(const Expr *ArgE,
+                                   unsigned ArgIndex) override {
         // Printed parameters start at 1, not 0.
         ++ArgIndex;
 
@@ -433,7 +453,7 @@
         return os.str();
       }
 
-      virtual std::string getMessageForReturn(const CallExpr *CallExpr) {
+      std::string getMessageForReturn(const CallExpr *CallExpr) override {
         return "Reallocation of returned value failed";
       }
     };
@@ -455,7 +475,7 @@
   StopTrackingCallback(ProgramStateRef st) : state(st) {}
   ProgramStateRef getState() const { return state; }
 
-  bool VisitSymbol(SymbolRef sym) {
+  bool VisitSymbol(SymbolRef sym) override {
     state = state->remove<RegionState>(sym);
     return true;
   }
@@ -473,6 +493,7 @@
   II_valloc = &Ctx.Idents.get("valloc");
   II_strdup = &Ctx.Idents.get("strdup");
   II_strndup = &Ctx.Idents.get("strndup");
+  II_kmalloc = &Ctx.Idents.get("kmalloc");
 }
 
 bool MallocChecker::isMemFunction(const FunctionDecl *FD, ASTContext &C) const {
@@ -499,16 +520,13 @@
 
     if (FunI == II_malloc || FunI == II_realloc ||
         FunI == II_reallocf || FunI == II_calloc || FunI == II_valloc ||
-        FunI == II_strdup || FunI == II_strndup)
+        FunI == II_strdup || FunI == II_strndup || FunI == II_kmalloc)
       return true;
   }
 
-  if (Filter.CMallocOptimistic && FD->hasAttrs())
-    for (specific_attr_iterator<OwnershipAttr>
-           i = FD->specific_attr_begin<OwnershipAttr>(),
-           e = FD->specific_attr_end<OwnershipAttr>();
-           i != e; ++i)
-      if ((*i)->getOwnKind() == OwnershipAttr::Returns)
+  if (ChecksEnabled[CK_MallocOptimistic] && FD->hasAttrs())
+    for (const auto *I : FD->specific_attrs<OwnershipAttr>())
+      if (I->getOwnKind() == OwnershipAttr::Returns)
         return true;
   return false;
 }
@@ -525,13 +543,10 @@
       return true;
   }
 
-  if (Filter.CMallocOptimistic && FD->hasAttrs())
-    for (specific_attr_iterator<OwnershipAttr>
-           i = FD->specific_attr_begin<OwnershipAttr>(),
-           e = FD->specific_attr_end<OwnershipAttr>();
-           i != e; ++i)
-      if ((*i)->getOwnKind() == OwnershipAttr::Takes ||
-          (*i)->getOwnKind() == OwnershipAttr::Holds)
+  if (ChecksEnabled[CK_MallocOptimistic] && FD->hasAttrs())
+    for (const auto *I : FD->specific_attrs<OwnershipAttr>())
+      if (I->getOwnKind() == OwnershipAttr::Takes ||
+          I->getOwnKind() == OwnershipAttr::Holds)
         return true;
   return false;
 }
@@ -569,10 +584,88 @@
   return true;
 }
 
+llvm::Optional<ProgramStateRef> MallocChecker::performKernelMalloc(
+  const CallExpr *CE, CheckerContext &C, const ProgramStateRef &State) const {
+  // 3-argument malloc(), as commonly used in {Free,Net,Open}BSD Kernels:
+  //
+  // void *malloc(unsigned long size, struct malloc_type *mtp, int flags);
+  //
+  // One of the possible flags is M_ZERO, which means 'give me back an
+  // allocation which is already zeroed', like calloc.
+
+  // 2-argument kmalloc(), as used in the Linux kernel:
+  //
+  // void *kmalloc(size_t size, gfp_t flags);
+  //
+  // Has the similar flag value __GFP_ZERO.
+
+  // This logic is largely cloned from O_CREAT in UnixAPIChecker, maybe some
+  // code could be shared.
+
+  ASTContext &Ctx = C.getASTContext();
+  llvm::Triple::OSType OS = Ctx.getTargetInfo().getTriple().getOS();
+
+  if (!KernelZeroFlagVal.hasValue()) {
+    if (OS == llvm::Triple::FreeBSD)
+      KernelZeroFlagVal = 0x0100;
+    else if (OS == llvm::Triple::NetBSD)
+      KernelZeroFlagVal = 0x0002;
+    else if (OS == llvm::Triple::OpenBSD)
+      KernelZeroFlagVal = 0x0008;
+    else if (OS == llvm::Triple::Linux)
+      // __GFP_ZERO
+      KernelZeroFlagVal = 0x8000;
+    else
+      // FIXME: We need a more general way of getting the M_ZERO value.
+      // See also: O_CREAT in UnixAPIChecker.cpp.
+
+      // Fall back to normal malloc behavior on platforms where we don't
+      // know M_ZERO.
+      return None;
+  }
+
+  // We treat the last argument as the flags argument, and callers fall-back to
+  // normal malloc on a None return. This works for the FreeBSD kernel malloc
+  // as well as Linux kmalloc.
+  if (CE->getNumArgs() < 2)
+    return None;
+
+  const Expr *FlagsEx = CE->getArg(CE->getNumArgs() - 1);
+  const SVal V = State->getSVal(FlagsEx, C.getLocationContext());
+  if (!V.getAs<NonLoc>()) {
+    // The case where 'V' can be a location can only be due to a bad header,
+    // so in this case bail out.
+    return None;
+  }
+
+  NonLoc Flags = V.castAs<NonLoc>();
+  NonLoc ZeroFlag = C.getSValBuilder()
+      .makeIntVal(KernelZeroFlagVal.getValue(), FlagsEx->getType())
+      .castAs<NonLoc>();
+  SVal MaskedFlagsUC = C.getSValBuilder().evalBinOpNN(State, BO_And,
+                                                      Flags, ZeroFlag,
+                                                      FlagsEx->getType());
+  if (MaskedFlagsUC.isUnknownOrUndef())
+    return None;
+  DefinedSVal MaskedFlags = MaskedFlagsUC.castAs<DefinedSVal>();
+
+  // Check if maskedFlags is non-zero.
+  ProgramStateRef TrueState, FalseState;
+  std::tie(TrueState, FalseState) = State->assume(MaskedFlags);
+
+  // If M_ZERO is set, treat this like calloc (initialized).
+  if (TrueState && !FalseState) {
+    SVal ZeroVal = C.getSValBuilder().makeZeroVal(Ctx.CharTy);
+    return MallocMemAux(C, CE, CE->getArg(0), ZeroVal, TrueState);
+  }
+
+  return None;
+}
+
 void MallocChecker::checkPostStmt(const CallExpr *CE, CheckerContext &C) const {
   if (C.wasInlined)
     return;
-  
+
   const FunctionDecl *FD = C.getCalleeDecl(CE);
   if (!FD)
     return;
@@ -584,7 +677,27 @@
     initIdentifierInfo(C.getASTContext());
     IdentifierInfo *FunI = FD->getIdentifier();
 
-    if (FunI == II_malloc || FunI == II_valloc) {
+    if (FunI == II_malloc) {
+      if (CE->getNumArgs() < 1)
+        return;
+      if (CE->getNumArgs() < 3) {
+        State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State);
+      } else if (CE->getNumArgs() == 3) {
+        llvm::Optional<ProgramStateRef> MaybeState =
+          performKernelMalloc(CE, C, State);
+        if (MaybeState.hasValue())
+          State = MaybeState.getValue();
+        else
+          State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State);
+      }
+    } else if (FunI == II_kmalloc) {
+      llvm::Optional<ProgramStateRef> MaybeState =
+        performKernelMalloc(CE, C, State);
+      if (MaybeState.hasValue())
+        State = MaybeState.getValue();
+      else
+        State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State);
+    } else if (FunI == II_valloc) {
       if (CE->getNumArgs() < 1)
         return;
       State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State);
@@ -620,21 +733,19 @@
     }
   }
 
-  if (Filter.CMallocOptimistic || Filter.CMismatchedDeallocatorChecker) {
+  if (ChecksEnabled[CK_MallocOptimistic] ||
+      ChecksEnabled[CK_MismatchedDeallocatorChecker]) {
     // Check all the attributes, if there are any.
     // There can be multiple of these attributes.
     if (FD->hasAttrs())
-      for (specific_attr_iterator<OwnershipAttr>
-          i = FD->specific_attr_begin<OwnershipAttr>(),
-          e = FD->specific_attr_end<OwnershipAttr>();
-          i != e; ++i) {
-        switch ((*i)->getOwnKind()) {
+      for (const auto *I : FD->specific_attrs<OwnershipAttr>()) {
+        switch (I->getOwnKind()) {
         case OwnershipAttr::Returns:
-          State = MallocMemReturnsAttr(C, CE, *i);
+          State = MallocMemReturnsAttr(C, CE, I);
           break;
         case OwnershipAttr::Takes:
         case OwnershipAttr::Holds:
-          State = FreeMemAttr(C, CE, *i);
+          State = FreeMemAttr(C, CE, I);
           break;
         }
       }
@@ -667,7 +778,7 @@
 void MallocChecker::checkPreStmt(const CXXDeleteExpr *DE, 
                                  CheckerContext &C) const {
 
-  if (!Filter.CNewDeleteChecker)
+  if (!ChecksEnabled[CK_NewDeleteChecker])
     if (SymbolRef Sym = C.getSVal(DE->getArgument()).getAsSymbol())
       checkUseAfterFree(Sym, C, DE->getArgument());
 
@@ -729,11 +840,11 @@
   C.addTransition(State);
 }
 
-ProgramStateRef MallocChecker::MallocMemReturnsAttr(CheckerContext &C,
-                                                    const CallExpr *CE,
-                                                    const OwnershipAttr* Att) {
-  if (Att->getModule() != "malloc")
-    return 0;
+ProgramStateRef
+MallocChecker::MallocMemReturnsAttr(CheckerContext &C, const CallExpr *CE,
+                                    const OwnershipAttr *Att) const {
+  if (Att->getModule() != II_malloc)
+    return nullptr;
 
   OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end();
   if (I != E) {
@@ -760,7 +871,7 @@
 
   // We expect the malloc functions to return a pointer.
   if (!RetVal.getAs<Loc>())
-    return 0;
+    return nullptr;
 
   // Fill the region with the initialization value.
   State = State->bindDefault(RetVal, Init);
@@ -769,7 +880,7 @@
   const SymbolicRegion *R =
       dyn_cast_or_null<SymbolicRegion>(RetVal.getAsRegion());
   if (!R)
-    return 0;
+    return nullptr;
   if (Optional<DefinedOrUnknownSVal> DefinedSize =
           Size.getAs<DefinedOrUnknownSVal>()) {
     SValBuilder &svalBuilder = C.getSValBuilder();
@@ -793,7 +904,7 @@
 
   // We expect the malloc functions to return a pointer.
   if (!retVal.getAs<Loc>())
-    return 0;
+    return nullptr;
 
   SymbolRef Sym = retVal.getAsLocSymbol();
   assert(Sym);
@@ -804,16 +915,15 @@
 
 ProgramStateRef MallocChecker::FreeMemAttr(CheckerContext &C,
                                            const CallExpr *CE,
-                                           const OwnershipAttr* Att) const {
-  if (Att->getModule() != "malloc")
-    return 0;
+                                           const OwnershipAttr *Att) const {
+  if (Att->getModule() != II_malloc)
+    return nullptr;
 
   ProgramStateRef State = C.getState();
   bool ReleasedAllocated = false;
 
-  for (OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end();
-       I != E; ++I) {
-    ProgramStateRef StateI = FreeMemAux(C, CE, State, *I,
+  for (const auto &Arg : Att->args()) {
+    ProgramStateRef StateI = FreeMemAux(C, CE, State, Arg,
                                Att->getOwnKind() == OwnershipAttr::Holds,
                                ReleasedAllocated);
     if (StateI)
@@ -830,7 +940,7 @@
                                           bool &ReleasedAllocated,
                                           bool ReturnsNullOnFailure) const {
   if (CE->getNumArgs() < (Num + 1))
-    return 0;
+    return nullptr;
 
   return FreeMemAux(C, CE->getArg(Num), CE, state, Hold,
                     ReleasedAllocated, ReturnsNullOnFailure);
@@ -909,7 +1019,7 @@
       os << "-";
     else
       os << "+";
-    os << Msg->getSelector().getAsString();
+    Msg->getSelector().print(os);
     return true;
   }
 
@@ -962,23 +1072,23 @@
 
   SVal ArgVal = State->getSVal(ArgExpr, C.getLocationContext());
   if (!ArgVal.getAs<DefinedOrUnknownSVal>())
-    return 0;
+    return nullptr;
   DefinedOrUnknownSVal location = ArgVal.castAs<DefinedOrUnknownSVal>();
 
   // Check for null dereferences.
   if (!location.getAs<Loc>())
-    return 0;
+    return nullptr;
 
   // The explicit NULL case, no operation is performed.
   ProgramStateRef notNullState, nullState;
-  llvm::tie(notNullState, nullState) = State->assume(location);
+  std::tie(notNullState, nullState) = State->assume(location);
   if (nullState && !notNullState)
-    return 0;
+    return nullptr;
 
   // Unknown values could easily be okay
   // Undefined values are handled elsewhere
   if (ArgVal.isUnknownOrUndef())
-    return 0;
+    return nullptr;
 
   const MemRegion *R = ArgVal.getAsRegion();
   
@@ -986,7 +1096,7 @@
   // Non-region locations (labels and fixed addresses) also shouldn't be freed.
   if (!R) {
     ReportBadFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr);
-    return 0;
+    return nullptr;
   }
   
   R = R->StripCasts();
@@ -994,7 +1104,7 @@
   // Blocks might show up as heap data, but should not be free()d
   if (isa<BlockDataRegion>(R)) {
     ReportBadFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr);
-    return 0;
+    return nullptr;
   }
   
   const MemSpaceRegion *MS = R->getMemorySpace();
@@ -1011,18 +1121,18 @@
     // False negatives are better than false positives.
     
     ReportBadFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr);
-    return 0;
+    return nullptr;
   }
 
   const SymbolicRegion *SrBase = dyn_cast<SymbolicRegion>(R->getBaseRegion());
   // Various cases could lead to non-symbol values here.
   // For now, ignore them.
   if (!SrBase)
-    return 0;
+    return nullptr;
 
   SymbolRef SymBase = SrBase->getSymbol();
   const RefState *RsBase = State->get<RegionState>(SymBase);
-  SymbolRef PreviousRetStatusSymbol = 0;
+  SymbolRef PreviousRetStatusSymbol = nullptr;
 
   if (RsBase) {
 
@@ -1031,7 +1141,7 @@
         !didPreviousFreeFail(State, SymBase, PreviousRetStatusSymbol)) {
       ReportDoubleFree(C, ParentExpr->getSourceRange(), RsBase->isReleased(),
                        SymBase, PreviousRetStatusSymbol);
-      return 0;
+      return nullptr;
 
     // If the pointer is allocated or escaped, but we are now trying to free it,
     // check that the call to free is proper.
@@ -1043,7 +1153,7 @@
       if (!DeallocMatchesAlloc) {
         ReportMismatchedDealloc(C, ArgExpr->getSourceRange(),
                                 ParentExpr, RsBase, SymBase, Hold);
-        return 0;
+        return nullptr;
       }
 
       // Check if the memory location being freed is the actual location
@@ -1055,12 +1165,12 @@
         const Expr *AllocExpr = cast<Expr>(RsBase->getStmt());
         ReportOffsetFree(C, ArgVal, ArgExpr->getSourceRange(), ParentExpr, 
                          AllocExpr);
-        return 0;
+        return nullptr;
       }
     }
   }
 
-  ReleasedAllocated = (RsBase != 0) && RsBase->isAllocated();
+  ReleasedAllocated = (RsBase != nullptr) && RsBase->isAllocated();
 
   // Clean out the info on previous call to free return info.
   State = State->remove<FreeReturnValue>(SymBase);
@@ -1088,18 +1198,23 @@
                                  RefState::getReleased(Family, ParentExpr));
 }
 
-bool MallocChecker::isTrackedByCurrentChecker(AllocationFamily Family) const {
+Optional<MallocChecker::CheckKind>
+MallocChecker::getCheckIfTracked(AllocationFamily Family) const {
   switch (Family) {
   case AF_Malloc: {
-    if (!Filter.CMallocOptimistic && !Filter.CMallocPessimistic)
-      return false;
-    return true;
+    if (ChecksEnabled[CK_MallocOptimistic]) {
+      return CK_MallocOptimistic;
+    } else if (ChecksEnabled[CK_MallocPessimistic]) {
+      return CK_MallocPessimistic;
+    }
+    return Optional<MallocChecker::CheckKind>();
   }
   case AF_CXXNew:
   case AF_CXXNewArray: {
-    if (!Filter.CNewDeleteChecker)
-      return false;
-    return true;
+    if (ChecksEnabled[CK_NewDeleteChecker]) {
+      return CK_NewDeleteChecker;
+    }
+    return Optional<MallocChecker::CheckKind>();
   }
   case AF_None: {
     llvm_unreachable("no family");
@@ -1108,18 +1223,18 @@
   llvm_unreachable("unhandled family");
 }
 
-bool
-MallocChecker::isTrackedByCurrentChecker(CheckerContext &C, 
-                                         const Stmt *AllocDeallocStmt) const {
-  return isTrackedByCurrentChecker(getAllocationFamily(C, AllocDeallocStmt));
+Optional<MallocChecker::CheckKind>
+MallocChecker::getCheckIfTracked(CheckerContext &C,
+                                 const Stmt *AllocDeallocStmt) const {
+  return getCheckIfTracked(getAllocationFamily(C, AllocDeallocStmt));
 }
 
-bool MallocChecker::isTrackedByCurrentChecker(CheckerContext &C,
-                                              SymbolRef Sym) const {
+Optional<MallocChecker::CheckKind>
+MallocChecker::getCheckIfTracked(CheckerContext &C, SymbolRef Sym) const {
 
   const RefState *RS = C.getState()->get<RegionState>(Sym);
   assert(RS);
-  return isTrackedByCurrentChecker(RS->getAllocationFamily());
+  return getCheckIfTracked(RS->getAllocationFamily());
 }
 
 bool MallocChecker::SummarizeValue(raw_ostream &os, SVal V) {
@@ -1162,8 +1277,8 @@
       if (VR)
         VD = VR->getDecl();
       else
-        VD = NULL;
-      
+        VD = nullptr;
+
       if (VD)
         os << "the address of the local variable '" << VD->getName() << "'";
       else
@@ -1177,8 +1292,8 @@
       if (VR)
         VD = VR->getDecl();
       else
-        VD = NULL;
-      
+        VD = nullptr;
+
       if (VD)
         os << "the address of the parameter '" << VD->getName() << "'";
       else
@@ -1192,8 +1307,8 @@
       if (VR)
         VD = VR->getDecl();
       else
-        VD = NULL;
-      
+        VD = nullptr;
+
       if (VD) {
         if (VD->isStaticLocal())
           os << "the address of the static variable '" << VD->getName() << "'";
@@ -1213,17 +1328,21 @@
                                   SourceRange Range, 
                                   const Expr *DeallocExpr) const {
 
-  if (!Filter.CMallocOptimistic && !Filter.CMallocPessimistic && 
-      !Filter.CNewDeleteChecker)
+  if (!ChecksEnabled[CK_MallocOptimistic] &&
+      !ChecksEnabled[CK_MallocPessimistic] &&
+      !ChecksEnabled[CK_NewDeleteChecker])
     return;
 
-  if (!isTrackedByCurrentChecker(C, DeallocExpr))
+  Optional<MallocChecker::CheckKind> CheckKind =
+      getCheckIfTracked(C, DeallocExpr);
+  if (!CheckKind.hasValue())
     return;
 
   if (ExplodedNode *N = C.generateSink()) {
-    if (!BT_BadFree)
-      BT_BadFree.reset(new BugType("Bad free", "Memory Error"));
-    
+    if (!BT_BadFree[*CheckKind])
+      BT_BadFree[*CheckKind].reset(
+          new BugType(CheckNames[*CheckKind], "Bad free", "Memory Error"));
+
     SmallString<100> buf;
     llvm::raw_svector_ostream os(buf);
 
@@ -1249,7 +1368,7 @@
       printExpectedAllocName(os, C, DeallocExpr);
     }
 
-    BugReport *R = new BugReport(*BT_BadFree, os.str(), N);
+    BugReport *R = new BugReport(*BT_BadFree[*CheckKind], os.str(), N);
     R->markInteresting(MR);
     R->addRange(Range);
     C.emitReport(R);
@@ -1263,14 +1382,15 @@
                                             SymbolRef Sym, 
                                             bool OwnershipTransferred) const {
 
-  if (!Filter.CMismatchedDeallocatorChecker)
+  if (!ChecksEnabled[CK_MismatchedDeallocatorChecker])
     return;
 
   if (ExplodedNode *N = C.generateSink()) {
     if (!BT_MismatchedDealloc)
-      BT_MismatchedDealloc.reset(new BugType("Bad deallocator",
-                                             "Memory Error"));
-    
+      BT_MismatchedDealloc.reset(
+          new BugType(CheckNames[CK_MismatchedDeallocatorChecker],
+                      "Bad deallocator", "Memory Error"));
+
     SmallString<100> buf;
     llvm::raw_svector_ostream os(buf);
 
@@ -1314,19 +1434,23 @@
                                      SourceRange Range, const Expr *DeallocExpr,
                                      const Expr *AllocExpr) const {
 
-  if (!Filter.CMallocOptimistic && !Filter.CMallocPessimistic && 
-      !Filter.CNewDeleteChecker)
+  if (!ChecksEnabled[CK_MallocOptimistic] &&
+      !ChecksEnabled[CK_MallocPessimistic] &&
+      !ChecksEnabled[CK_NewDeleteChecker])
     return;
 
-  if (!isTrackedByCurrentChecker(C, AllocExpr))
+  Optional<MallocChecker::CheckKind> CheckKind =
+      getCheckIfTracked(C, AllocExpr);
+  if (!CheckKind.hasValue())
     return;
 
   ExplodedNode *N = C.generateSink();
-  if (N == NULL)
+  if (!N)
     return;
 
-  if (!BT_OffsetFree)
-    BT_OffsetFree.reset(new BugType("Offset free", "Memory Error"));
+  if (!BT_OffsetFree[*CheckKind])
+    BT_OffsetFree[*CheckKind].reset(
+        new BugType(CheckNames[*CheckKind], "Offset free", "Memory Error"));
 
   SmallString<100> buf;
   llvm::raw_svector_ostream os(buf);
@@ -1357,7 +1481,7 @@
   else
     os << "allocated memory";
 
-  BugReport *R = new BugReport(*BT_OffsetFree, os.str(), N);
+  BugReport *R = new BugReport(*BT_OffsetFree[*CheckKind], os.str(), N);
   R->markInteresting(MR->getBaseRegion());
   R->addRange(Range);
   C.emitReport(R);
@@ -1366,18 +1490,21 @@
 void MallocChecker::ReportUseAfterFree(CheckerContext &C, SourceRange Range,
                                        SymbolRef Sym) const {
 
-  if (!Filter.CMallocOptimistic && !Filter.CMallocPessimistic && 
-      !Filter.CNewDeleteChecker)
+  if (!ChecksEnabled[CK_MallocOptimistic] &&
+      !ChecksEnabled[CK_MallocPessimistic] &&
+      !ChecksEnabled[CK_NewDeleteChecker])
     return;
 
-  if (!isTrackedByCurrentChecker(C, Sym))
+  Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, Sym);
+  if (!CheckKind.hasValue())
     return;
 
   if (ExplodedNode *N = C.generateSink()) {
-    if (!BT_UseFree)
-      BT_UseFree.reset(new BugType("Use-after-free", "Memory Error"));
+    if (!BT_UseFree[*CheckKind])
+      BT_UseFree[*CheckKind].reset(new BugType(
+          CheckNames[*CheckKind], "Use-after-free", "Memory Error"));
 
-    BugReport *R = new BugReport(*BT_UseFree,
+    BugReport *R = new BugReport(*BT_UseFree[*CheckKind],
                                  "Use of memory after it is freed", N);
 
     R->markInteresting(Sym);
@@ -1391,21 +1518,25 @@
                                      bool Released, SymbolRef Sym, 
                                      SymbolRef PrevSym) const {
 
-  if (!Filter.CMallocOptimistic && !Filter.CMallocPessimistic && 
-      !Filter.CNewDeleteChecker)
+  if (!ChecksEnabled[CK_MallocOptimistic] &&
+      !ChecksEnabled[CK_MallocPessimistic] &&
+      !ChecksEnabled[CK_NewDeleteChecker])
     return;
 
-  if (!isTrackedByCurrentChecker(C, Sym))
+  Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, Sym);
+  if (!CheckKind.hasValue())
     return;
 
   if (ExplodedNode *N = C.generateSink()) {
-    if (!BT_DoubleFree)
-      BT_DoubleFree.reset(new BugType("Double free", "Memory Error"));
+    if (!BT_DoubleFree[*CheckKind])
+      BT_DoubleFree[*CheckKind].reset(
+          new BugType(CheckNames[*CheckKind], "Double free", "Memory Error"));
 
-    BugReport *R = new BugReport(*BT_DoubleFree,
-      (Released ? "Attempt to free released memory"
-                : "Attempt to free non-owned memory"),
-      N);
+    BugReport *R =
+        new BugReport(*BT_DoubleFree[*CheckKind],
+                      (Released ? "Attempt to free released memory"
+                                : "Attempt to free non-owned memory"),
+                      N);
     R->addRange(Range);
     R->markInteresting(Sym);
     if (PrevSym)
@@ -1415,18 +1546,42 @@
   }
 }
 
+void MallocChecker::ReportDoubleDelete(CheckerContext &C, SymbolRef Sym) const {
+
+  if (!ChecksEnabled[CK_NewDeleteChecker])
+    return;
+
+  Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(C, Sym);
+  if (!CheckKind.hasValue())
+    return;
+  assert(*CheckKind == CK_NewDeleteChecker && "invalid check kind");
+
+  if (ExplodedNode *N = C.generateSink()) {
+    if (!BT_DoubleDelete)
+      BT_DoubleDelete.reset(new BugType(CheckNames[CK_NewDeleteChecker],
+                                        "Double delete", "Memory Error"));
+
+    BugReport *R = new BugReport(*BT_DoubleDelete,
+                                 "Attempt to delete released memory", N);
+
+    R->markInteresting(Sym);
+    R->addVisitor(new MallocBugVisitor(Sym));
+    C.emitReport(R);
+  }
+}
+
 ProgramStateRef MallocChecker::ReallocMem(CheckerContext &C,
                                           const CallExpr *CE,
                                           bool FreesOnFail) const {
   if (CE->getNumArgs() < 2)
-    return 0;
+    return nullptr;
 
   ProgramStateRef state = C.getState();
   const Expr *arg0Expr = CE->getArg(0);
   const LocationContext *LCtx = C.getLocationContext();
   SVal Arg0Val = state->getSVal(arg0Expr, LCtx);
   if (!Arg0Val.getAs<DefinedOrUnknownSVal>())
-    return 0;
+    return nullptr;
   DefinedOrUnknownSVal arg0Val = Arg0Val.castAs<DefinedOrUnknownSVal>();
 
   SValBuilder &svalBuilder = C.getSValBuilder();
@@ -1437,12 +1592,12 @@
   // Get the size argument. If there is no size arg then give up.
   const Expr *Arg1 = CE->getArg(1);
   if (!Arg1)
-    return 0;
+    return nullptr;
 
   // Get the value of the size argument.
   SVal Arg1ValG = state->getSVal(Arg1, LCtx);
   if (!Arg1ValG.getAs<DefinedOrUnknownSVal>())
-    return 0;
+    return nullptr;
   DefinedOrUnknownSVal Arg1Val = Arg1ValG.castAs<DefinedOrUnknownSVal>();
 
   // Compare the size argument to 0.
@@ -1451,9 +1606,9 @@
                        svalBuilder.makeIntValWithPtrWidth(0, false));
 
   ProgramStateRef StatePtrIsNull, StatePtrNotNull;
-  llvm::tie(StatePtrIsNull, StatePtrNotNull) = state->assume(PtrEQ);
+  std::tie(StatePtrIsNull, StatePtrNotNull) = state->assume(PtrEQ);
   ProgramStateRef StateSizeIsZero, StateSizeNotZero;
-  llvm::tie(StateSizeIsZero, StateSizeNotZero) = state->assume(SizeZero);
+  std::tie(StateSizeIsZero, StateSizeNotZero) = state->assume(SizeZero);
   // We only assume exceptional states if they are definitely true; if the
   // state is under-constrained, assume regular realloc behavior.
   bool PrtIsNull = StatePtrIsNull && !StatePtrNotNull;
@@ -1468,7 +1623,7 @@
   }
 
   if (PrtIsNull && SizeIsZero)
-    return 0;
+    return nullptr;
 
   // Get the from and to pointer symbols as in toPtr = realloc(fromPtr, size).
   assert(!PrtIsNull);
@@ -1476,7 +1631,7 @@
   SVal RetVal = state->getSVal(CE, LCtx);
   SymbolRef ToPtr = RetVal.getAsSymbol();
   if (!FromPtr || !ToPtr)
-    return 0;
+    return nullptr;
 
   bool ReleasedAllocated = false;
 
@@ -1498,7 +1653,7 @@
     ProgramStateRef stateRealloc = MallocMemAux(C, CE, CE->getArg(1),
                                                 UnknownVal(), stateFree);
     if (!stateRealloc)
-      return 0;
+      return nullptr;
 
     ReallocPairKind Kind = RPToBeFreedAfterFailure;
     if (FreesOnFail)
@@ -1514,12 +1669,12 @@
     C.getSymbolManager().addSymbolDependency(ToPtr, FromPtr);
     return stateRealloc;
   }
-  return 0;
+  return nullptr;
 }
 
 ProgramStateRef MallocChecker::CallocMem(CheckerContext &C, const CallExpr *CE){
   if (CE->getNumArgs() < 2)
-    return 0;
+    return nullptr;
 
   ProgramStateRef state = C.getState();
   SValBuilder &svalBuilder = C.getSValBuilder();
@@ -1540,7 +1695,7 @@
   // Walk the ExplodedGraph backwards and find the first node that referred to
   // the tracked symbol.
   const ExplodedNode *AllocNode = N;
-  const MemRegion *ReferenceRegion = 0;
+  const MemRegion *ReferenceRegion = nullptr;
 
   while (N) {
     ProgramStateRef State = N->getState();
@@ -1567,7 +1722,7 @@
     // symbol was tracked.
     if (N->getLocationContext() == LeakContext)
       AllocNode = N;
-    N = N->pred_empty() ? NULL : *(N->pred_begin());
+    N = N->pred_empty() ? nullptr : *(N->pred_begin());
   }
 
   return LeakInfo(AllocNode, ReferenceRegion);
@@ -1576,43 +1731,46 @@
 void MallocChecker::reportLeak(SymbolRef Sym, ExplodedNode *N,
                                CheckerContext &C) const {
 
-  if (!Filter.CMallocOptimistic && !Filter.CMallocPessimistic && 
-      !Filter.CNewDeleteLeaksChecker)
+  if (!ChecksEnabled[CK_MallocOptimistic] &&
+      !ChecksEnabled[CK_MallocPessimistic] &&
+      !ChecksEnabled[CK_NewDeleteLeaksChecker])
     return;
 
   const RefState *RS = C.getState()->get<RegionState>(Sym);
   assert(RS && "cannot leak an untracked symbol");
   AllocationFamily Family = RS->getAllocationFamily();
-  if (!isTrackedByCurrentChecker(Family))
+  Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(Family);
+  if (!CheckKind.hasValue())
     return;
 
   // Special case for new and new[]; these are controlled by a separate checker
   // flag so that they can be selectively disabled.
   if (Family == AF_CXXNew || Family == AF_CXXNewArray)
-    if (!Filter.CNewDeleteLeaksChecker)
+    if (!ChecksEnabled[CK_NewDeleteLeaksChecker])
       return;
 
   assert(N);
-  if (!BT_Leak) {
-    BT_Leak.reset(new BugType("Memory leak", "Memory Error"));
+  if (!BT_Leak[*CheckKind]) {
+    BT_Leak[*CheckKind].reset(
+        new BugType(CheckNames[*CheckKind], "Memory leak", "Memory Error"));
     // Leaks should not be reported if they are post-dominated by a sink:
     // (1) Sinks are higher importance bugs.
     // (2) NoReturnFunctionChecker uses sink nodes to represent paths ending
     //     with __noreturn functions such as assert() or exit(). We choose not
     //     to report leaks on such paths.
-    BT_Leak->setSuppressOnSink(true);
+    BT_Leak[*CheckKind]->setSuppressOnSink(true);
   }
 
   // Most bug reports are cached at the location where they occurred.
   // With leaks, we want to unique them by the location where they were
   // allocated, and only report a single path.
   PathDiagnosticLocation LocUsedForUniqueing;
-  const ExplodedNode *AllocNode = 0;
-  const MemRegion *Region = 0;
-  llvm::tie(AllocNode, Region) = getAllocationSite(N, Sym, C);
+  const ExplodedNode *AllocNode = nullptr;
+  const MemRegion *Region = nullptr;
+  std::tie(AllocNode, Region) = getAllocationSite(N, Sym, C);
   
   ProgramPoint P = AllocNode->getLocation();
-  const Stmt *AllocationStmt = 0;
+  const Stmt *AllocationStmt = nullptr;
   if (Optional<CallExitEnd> Exit = P.getAs<CallExitEnd>())
     AllocationStmt = Exit->getCalleeContext()->getCallSite();
   else if (Optional<StmtPoint> SP = P.getAs<StmtPoint>())
@@ -1631,9 +1789,9 @@
     os << "Potential memory leak";
   }
 
-  BugReport *R = new BugReport(*BT_Leak, os.str(), N, 
-                               LocUsedForUniqueing, 
-                               AllocNode->getLocationContext()->getDecl());
+  BugReport *R =
+      new BugReport(*BT_Leak[*CheckKind], os.str(), N, LocUsedForUniqueing,
+                    AllocNode->getLocationContext()->getDecl());
   R->markInteresting(Sym);
   R->addVisitor(new MallocBugVisitor(Sym, true));
   C.emitReport(R);
@@ -1681,7 +1839,7 @@
   // Generate leak node.
   ExplodedNode *N = C.getPredecessor();
   if (!Errors.empty()) {
-    static SimpleProgramPointTag Tag("MallocChecker : DeadSymbolsLeak");
+    static CheckerProgramPointTag Tag("MallocChecker", "DeadSymbolsLeak");
     N = C.addTransition(C.getState(), C.getPredecessor(), &Tag);
     for (SmallVectorImpl<SymbolRef>::iterator
            I = Errors.begin(), E = Errors.end(); I != E; ++I) {
@@ -1695,17 +1853,24 @@
 void MallocChecker::checkPreCall(const CallEvent &Call,
                                  CheckerContext &C) const {
 
+  if (const CXXDestructorCall *DC = dyn_cast<CXXDestructorCall>(&Call)) {
+    SymbolRef Sym = DC->getCXXThisVal().getAsSymbol();
+    if (!Sym || checkDoubleDelete(Sym, C))
+      return;
+  }
+
   // We will check for double free in the post visit.
   if (const AnyFunctionCall *FC = dyn_cast<AnyFunctionCall>(&Call)) {
     const FunctionDecl *FD = FC->getDecl();
     if (!FD)
       return;
 
-    if ((Filter.CMallocOptimistic || Filter.CMallocPessimistic) &&
+    if ((ChecksEnabled[CK_MallocOptimistic] ||
+         ChecksEnabled[CK_MallocPessimistic]) &&
         isFreeFunction(FD, C.getASTContext()))
       return;
 
-    if (Filter.CNewDeleteChecker &&
+    if (ChecksEnabled[CK_NewDeleteChecker] &&
         isStandardNewDelete(FD, C.getASTContext()))
       return;
   }
@@ -1803,8 +1968,7 @@
 bool MallocChecker::checkUseAfterFree(SymbolRef Sym, CheckerContext &C,
                                       const Stmt *S) const {
 
-  // FIXME: Handle destructor called from delete more precisely.
-  if (isReleased(Sym, C) && S) {
+  if (isReleased(Sym, C)) {
     ReportUseAfterFree(C, S->getSourceRange(), Sym);
     return true;
   }
@@ -1812,6 +1976,15 @@
   return false;
 }
 
+bool MallocChecker::checkDoubleDelete(SymbolRef Sym, CheckerContext &C) const {
+
+  if (isReleased(Sym, C)) {
+    ReportDoubleDelete(C, Sym);
+    return true;
+  }
+  return false;
+}
+
 // Check if the location is a freed symbolic region.
 void MallocChecker::checkLocation(SVal l, bool isLoad, const Stmt *S,
                                   CheckerContext &C) const {
@@ -1867,13 +2040,13 @@
                                               ProgramStateRef State,
                                               SymbolRef &EscapingSymbol) const {
   assert(Call);
-  EscapingSymbol = 0;
-  
-  // For now, assume that any C++ call can free memory.
+  EscapingSymbol = nullptr;
+
+  // For now, assume that any C++ or block call can free memory.
   // TODO: If we want to be more optimistic here, we'll need to make sure that
   // regions escape to C++ containers. They seem to do that even now, but for
   // mysterious reasons.
-  if (!(isa<FunctionCall>(Call) || isa<ObjCMethodCall>(Call)))
+  if (!(isa<SimpleFunctionCall>(Call) || isa<ObjCMethodCall>(Call)))
     return true;
 
   // Check Objective-C messages by selector name.
@@ -1909,7 +2082,8 @@
     // that the pointers get freed by following the container itself.
     if (FirstSlot.startswith("addPointer") ||
         FirstSlot.startswith("insertPointer") ||
-        FirstSlot.startswith("replacePointer")) {
+        FirstSlot.startswith("replacePointer") ||
+        FirstSlot.equals("valueWithPointer")) {
       return true;
     }
 
@@ -1927,7 +2101,7 @@
   }
 
   // At this point the only thing left to handle is straight function calls.
-  const FunctionDecl *FD = cast<FunctionCall>(Call)->getDecl();
+  const FunctionDecl *FD = cast<SimpleFunctionCall>(Call)->getDecl();
   if (!FD)
     return true;
 
@@ -2043,7 +2217,7 @@
                                   bool(*CheckRefState)(const RefState*)) const {
   // If we know that the call does not free memory, or we want to process the
   // call later, keep tracking the top level arguments.
-  SymbolRef EscapingSymbol = 0;
+  SymbolRef EscapingSymbol = nullptr;
   if (Kind == PSK_DirectEscapeOnCall &&
       !mayFreeAnyEscapedMemoryOrIsModeledExplicitly(Call, State,
                                                     EscapingSymbol) &&
@@ -2081,7 +2255,7 @@
       return sym;
   }
 
-  return NULL;
+  return nullptr;
 }
 
 PathDiagnosticPiece *
@@ -2095,11 +2269,11 @@
   const RefState *RS = state->get<RegionState>(Sym);
   const RefState *RSPrev = statePrev->get<RegionState>(Sym);
   if (!RS)
-    return 0;
+    return nullptr;
 
-  const Stmt *S = 0;
-  const char *Msg = 0;
-  StackHintGeneratorForSymbol *StackHint = 0;
+  const Stmt *S = nullptr;
+  const char *Msg = nullptr;
+  StackHintGeneratorForSymbol *StackHint = nullptr;
 
   // Retrieve the associated statement.
   ProgramPoint ProgLoc = N->getLocation();
@@ -2114,7 +2288,7 @@
   }
 
   if (!S)
-    return 0;
+    return nullptr;
 
   // FIXME: We will eventually need to handle non-statement-based events
   // (__attribute__((cleanup))).
@@ -2130,7 +2304,7 @@
       StackHint = new StackHintGeneratorForSymbol(Sym,
                                              "Returning; memory was released");
     } else if (isRelinquished(RS, RSPrev, S)) {
-      Msg = "Memory ownership is transfered";
+      Msg = "Memory ownership is transferred";
       StackHint = new StackHintGeneratorForSymbol(Sym, "");
     } else if (isReallocFailedCheck(RS, RSPrev, S)) {
       Mode = ReallocationFailed;
@@ -2157,13 +2331,13 @@
       Msg = "Attempt to reallocate memory";
       StackHint = new StackHintGeneratorForSymbol(Sym,
                                                  "Returned reallocated memory");
-      FailedReallocSymbol = NULL;
+      FailedReallocSymbol = nullptr;
       Mode = Normal;
     }
   }
 
   if (!Msg)
-    return 0;
+    return nullptr;
   assert(StackHint);
 
   // Generate the extra diagnostic.
@@ -2178,11 +2352,17 @@
   RegionStateTy RS = State->get<RegionState>();
 
   if (!RS.isEmpty()) {
-    Out << Sep << "MallocChecker:" << NL;
+    Out << Sep << "MallocChecker :" << NL;
     for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
+      const RefState *RefS = State->get<RegionState>(I.getKey());
+      AllocationFamily Family = RefS->getAllocationFamily();
+      Optional<MallocChecker::CheckKind> CheckKind = getCheckIfTracked(Family);
+
       I.getKey()->dumpToStream(Out);
       Out << " : ";
       I.getData().dump(Out);
+      if (CheckKind.hasValue())
+        Out << " (" << CheckNames[*CheckKind].getName() << ")";
       Out << NL;
     }
   }
@@ -2190,17 +2370,23 @@
 
 void ento::registerNewDeleteLeaksChecker(CheckerManager &mgr) {
   registerCStringCheckerBasic(mgr);
-  mgr.registerChecker<MallocChecker>()->Filter.CNewDeleteLeaksChecker = true;
+  MallocChecker *checker = mgr.registerChecker<MallocChecker>();
+  checker->ChecksEnabled[MallocChecker::CK_NewDeleteLeaksChecker] = true;
+  checker->CheckNames[MallocChecker::CK_NewDeleteLeaksChecker] =
+      mgr.getCurrentCheckName();
   // We currently treat NewDeleteLeaks checker as a subchecker of NewDelete 
   // checker.
-  mgr.registerChecker<MallocChecker>()->Filter.CNewDeleteChecker = true;
+  if (!checker->ChecksEnabled[MallocChecker::CK_NewDeleteChecker])
+    checker->ChecksEnabled[MallocChecker::CK_NewDeleteChecker] = true;
 }
 
-#define REGISTER_CHECKER(name) \
-void ento::register##name(CheckerManager &mgr) {\
-  registerCStringCheckerBasic(mgr); \
-  mgr.registerChecker<MallocChecker>()->Filter.C##name = true;\
-}
+#define REGISTER_CHECKER(name)                                                 \
+  void ento::register##name(CheckerManager &mgr) {                             \
+    registerCStringCheckerBasic(mgr);                                          \
+    MallocChecker *checker = mgr.registerChecker<MallocChecker>();             \
+    checker->ChecksEnabled[MallocChecker::CK_##name] = true;                   \
+    checker->CheckNames[MallocChecker::CK_##name] = mgr.getCurrentCheckName(); \
+  }
 
 REGISTER_CHECKER(MallocPessimistic)
 REGISTER_CHECKER(MallocOptimistic)
diff --git a/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp
index 0cdf911..f38ce77 100644
--- a/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp
@@ -65,7 +65,7 @@
    conditional expression, an operation that could reduce the range
    of the result, or anything too complicated :-).  */
   const Expr * e = TheArgument;
-  const BinaryOperator * mulop = NULL;
+  const BinaryOperator * mulop = nullptr;
 
   for (;;) {
     e = e->IgnoreParenImpCasts();
@@ -73,7 +73,7 @@
       const BinaryOperator * binop = dyn_cast<BinaryOperator>(e);
       BinaryOperatorKind opc = binop->getOpcode();
       // TODO: ignore multiplications by 1, reject if multiplied by 0.
-      if (mulop == NULL && opc == BO_Mul)
+      if (mulop == nullptr && opc == BO_Mul)
         mulop = binop;
       if (opc != BO_Mul && opc != BO_Add && opc != BO_Sub && opc != BO_Shl)
         return;
@@ -94,7 +94,7 @@
       return;
   }
 
-  if (mulop == NULL)
+  if (mulop == nullptr)
     return;
 
   //  We've found the right structure of malloc argument, now save
@@ -213,11 +213,12 @@
        e = PossibleMallocOverflows.end();
        i != e;
        ++i) {
-    BR.EmitBasicReport(D, "malloc() size overflow", categories::UnixAPI,
-      "the computation of the size of the memory allocation may overflow",
-      PathDiagnosticLocation::createOperatorLoc(i->mulop,
-                                                BR.getSourceManager()),
-      i->mulop->getSourceRange());
+    BR.EmitBasicReport(
+        D, this, "malloc() size overflow", categories::UnixAPI,
+        "the computation of the size of the memory allocation may overflow",
+        PathDiagnosticLocation::createOperatorLoc(i->mulop,
+                                                  BR.getSourceManager()),
+        i->mulop->getSourceRange());
   }
 }
 
@@ -262,6 +263,7 @@
   OutputPossibleOverflows(PossibleMallocOverflows, D, BR, mgr);
 }
 
-void ento::registerMallocOverflowSecurityChecker(CheckerManager &mgr) {
+void
+ento::registerMallocOverflowSecurityChecker(CheckerManager &mgr) {
   mgr.registerChecker<MallocOverflowSecurityChecker>();
 }
diff --git a/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp
index 6c776eb..4a50d93 100644
--- a/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp
@@ -95,15 +95,14 @@
     if (FD) {
       IdentifierInfo *II = FD->getIdentifier();
       if (II == II_malloc || II == II_calloc || II == II_realloc)
-        return TypeCallPair((const TypeSourceInfo *)0, E);
+        return TypeCallPair((const TypeSourceInfo *)nullptr, E);
     }
     return TypeCallPair();
   }
 
   TypeCallPair VisitDeclStmt(const DeclStmt *S) {
-    for (DeclStmt::const_decl_iterator I = S->decl_begin(), E = S->decl_end();
-         I!=E; ++I)
-      if (const VarDecl *VD = dyn_cast<VarDecl>(*I))
+    for (const auto *I : S->decls())
+      if (const VarDecl *VD = dyn_cast<VarDecl>(I))
         if (const Expr *Init = VD->getInit())
           VisitChild(VD, Init);
     return TypeCallPair();
@@ -206,7 +205,7 @@
         if (compatibleWithArrayType(BR.getContext(), PointeeType, SizeofType))
           continue;
 
-        const TypeSourceInfo *TSI = 0;
+        const TypeSourceInfo *TSI = nullptr;
         if (i->CastedExprParent.is<const VarDecl *>()) {
           TSI =
               i->CastedExprParent.get<const VarDecl *>()->getTypeSourceInfo();
@@ -236,10 +235,8 @@
             PathDiagnosticLocation::createBegin(i->AllocCall->getCallee(),
                 BR.getSourceManager(), ADC);
 
-        BR.EmitBasicReport(D, "Allocator sizeof operand mismatch",
-            categories::UnixAPI,
-            OS.str(),
-            L, Ranges);
+        BR.EmitBasicReport(D, this, "Allocator sizeof operand mismatch",
+                           categories::UnixAPI, OS.str(), L, Ranges);
       }
     }
   }
diff --git a/lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp b/lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp
index fc28e1f..b180c03 100644
--- a/lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp
@@ -32,7 +32,7 @@
 namespace {
 class NSAutoreleasePoolChecker
   : public Checker<check::PreObjCMessage> {
-  mutable OwningPtr<BugType> BT;
+  mutable std::unique_ptr<BugType> BT;
   mutable Selector releaseS;
 
 public:
@@ -59,7 +59,7 @@
     return;
 
   if (!BT)
-    BT.reset(new BugType("Use -drain instead of -release",
+    BT.reset(new BugType(this, "Use -drain instead of -release",
                          "API Upgrade (Apple)"));
 
   ExplodedNode *N = C.addTransition();
diff --git a/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp b/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp
index 9f01522..2be7f1d 100644
--- a/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp
@@ -42,7 +42,7 @@
   mutable IdentifierInfo *II;
 
 public:
-  NSErrorMethodChecker() : II(0) { }
+  NSErrorMethodChecker() : II(nullptr) {}
 
   void checkASTDecl(const ObjCMethodDecl *D,
                     AnalysisManager &mgr, BugReporter &BR) const;
@@ -54,16 +54,15 @@
                                         BugReporter &BR) const {
   if (!D->isThisDeclarationADefinition())
     return;
-  if (!D->getResultType()->isVoidType())
+  if (!D->getReturnType()->isVoidType())
     return;
 
   if (!II)
     II = &D->getASTContext().Idents.get("NSError"); 
 
   bool hasNSError = false;
-  for (ObjCMethodDecl::param_const_iterator
-         I = D->param_begin(), E = D->param_end(); I != E; ++I)  {
-    if (IsNSError((*I)->getType(), II)) {
+  for (const auto *I : D->params())  {
+    if (IsNSError(I->getType(), II)) {
       hasNSError = true;
       break;
     }
@@ -75,7 +74,7 @@
         "error occurred";
     PathDiagnosticLocation L =
       PathDiagnosticLocation::create(D, BR.getSourceManager());
-    BR.EmitBasicReport(D, "Bad return type when passing NSError**",
+    BR.EmitBasicReport(D, this, "Bad return type when passing NSError**",
                        "Coding conventions (Apple)", err, L);
   }
 }
@@ -90,7 +89,7 @@
   mutable IdentifierInfo *II;
 
 public:
-  CFErrorFunctionChecker() : II(0) { }
+  CFErrorFunctionChecker() : II(nullptr) {}
 
   void checkASTDecl(const FunctionDecl *D,
                     AnalysisManager &mgr, BugReporter &BR) const;
@@ -102,16 +101,15 @@
                                         BugReporter &BR) const {
   if (!D->doesThisDeclarationHaveABody())
     return;
-  if (!D->getResultType()->isVoidType())
+  if (!D->getReturnType()->isVoidType())
     return;
 
   if (!II)
     II = &D->getASTContext().Idents.get("CFErrorRef"); 
 
   bool hasCFError = false;
-  for (FunctionDecl::param_const_iterator
-         I = D->param_begin(), E = D->param_end(); I != E; ++I)  {
-    if (IsCFError((*I)->getType(), II)) {
+  for (auto I : D->params())  {
+    if (IsCFError(I->getType(), II)) {
       hasCFError = true;
       break;
     }
@@ -123,7 +121,7 @@
         "error occurred";
     PathDiagnosticLocation L =
       PathDiagnosticLocation::create(D, BR.getSourceManager());
-    BR.EmitBasicReport(D, "Bad return type when passing CFErrorRef*",
+    BR.EmitBasicReport(D, this, "Bad return type when passing CFErrorRef*",
                        "Coding conventions (Apple)", err, L);
   }
 }
@@ -136,14 +134,16 @@
 
 class NSErrorDerefBug : public BugType {
 public:
-  NSErrorDerefBug() : BugType("NSError** null dereference",
-                              "Coding conventions (Apple)") {}
+  NSErrorDerefBug(const CheckerBase *Checker)
+      : BugType(Checker, "NSError** null dereference",
+                "Coding conventions (Apple)") {}
 };
 
 class CFErrorDerefBug : public BugType {
 public:
-  CFErrorDerefBug() : BugType("CFErrorRef* null dereference",
-                              "Coding conventions (Apple)") {}
+  CFErrorDerefBug(const CheckerBase *Checker)
+      : BugType(Checker, "CFErrorRef* null dereference",
+                "Coding conventions (Apple)") {}
 };
 
 }
@@ -153,9 +153,11 @@
     : public Checker< check::Location,
                         check::Event<ImplicitNullDerefEvent> > {
   mutable IdentifierInfo *NSErrorII, *CFErrorII;
+  mutable std::unique_ptr<NSErrorDerefBug> NSBT;
+  mutable std::unique_ptr<CFErrorDerefBug> CFBT;
 public:
   bool ShouldCheckNSError, ShouldCheckCFError;
-  NSOrCFErrorDerefChecker() : NSErrorII(0), CFErrorII(0),
+  NSOrCFErrorDerefChecker() : NSErrorII(nullptr), CFErrorII(nullptr),
                               ShouldCheckNSError(0), ShouldCheckCFError(0) { }
 
   void checkLocation(SVal loc, bool isLoad, const Stmt *S,
@@ -262,13 +264,18 @@
 
   os  << " may be null";
 
-  BugType *bug = 0;
-  if (isNSError)
-    bug = new NSErrorDerefBug();
-  else
-    bug = new CFErrorDerefBug();
-  BugReport *report = new BugReport(*bug, os.str(),
-                                                    event.SinkNode);
+  BugType *bug = nullptr;
+  if (isNSError) {
+    if (!NSBT)
+      NSBT.reset(new NSErrorDerefBug(this));
+    bug = NSBT.get();
+  }
+  else {
+    if (!CFBT)
+      CFBT.reset(new CFErrorDerefBug(this));
+    bug = CFBT.get();
+  }
+  BugReport *report = new BugReport(*bug, os.str(), event.SinkNode);
   BR.emitReport(report);
 }
 
@@ -305,14 +312,14 @@
 
 void ento::registerNSErrorChecker(CheckerManager &mgr) {
   mgr.registerChecker<NSErrorMethodChecker>();
-  NSOrCFErrorDerefChecker *
-    checker = mgr.registerChecker<NSOrCFErrorDerefChecker>();
+  NSOrCFErrorDerefChecker *checker =
+      mgr.registerChecker<NSOrCFErrorDerefChecker>();
   checker->ShouldCheckNSError = true;
 }
 
 void ento::registerCFErrorChecker(CheckerManager &mgr) {
   mgr.registerChecker<CFErrorFunctionChecker>();
-  NSOrCFErrorDerefChecker *
-    checker = mgr.registerChecker<NSOrCFErrorDerefChecker>();
+  NSOrCFErrorDerefChecker *checker =
+      mgr.registerChecker<NSOrCFErrorDerefChecker>();
   checker->ShouldCheckCFError = true;
 }
diff --git a/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp b/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp
index 0e1064e..ba82d1d 100644
--- a/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp
@@ -13,6 +13,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "ClangSACheckers.h"
+#include "SelectorExtras.h"
 #include "clang/AST/Attr.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
@@ -28,6 +29,8 @@
 
 class NoReturnFunctionChecker : public Checker< check::PostCall,
                                                 check::PostObjCMessage > {
+  mutable Selector HandleFailureInFunctionSel;
+  mutable Selector HandleFailureInMethodSel;
 public:
   void checkPostCall(const CallEvent &CE, CheckerContext &C) const;
   void checkPostObjCMessage(const ObjCMethodCall &msg, CheckerContext &C) const;
@@ -37,11 +40,10 @@
 
 void NoReturnFunctionChecker::checkPostCall(const CallEvent &CE,
                                             CheckerContext &C) const {
-  ProgramStateRef state = C.getState();
   bool BuildSinks = false;
 
   if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(CE.getDecl()))
-    BuildSinks = FD->getAttr<AnalyzerNoReturnAttr>() || FD->isNoReturn();
+    BuildSinks = FD->hasAttr<AnalyzerNoReturnAttr>() || FD->isNoReturn();
 
   const Expr *Callee = CE.getOriginExpr();
   if (!BuildSinks && Callee)
@@ -82,24 +84,6 @@
     C.generateSink();
 }
 
-static bool END_WITH_NULL isMultiArgSelector(const Selector *Sel, ...) {
-  va_list argp;
-  va_start(argp, Sel);
-
-  unsigned Slot = 0;
-  const char *Arg;
-  while ((Arg = va_arg(argp, const char *))) {
-    if (!Sel->getNameForSlot(Slot).equals(Arg))
-      break; // still need to va_end!
-    ++Slot;
-  }
-
-  va_end(argp);
-
-  // We only succeeded if we made it to the end of the argument list.
-  return (Arg == NULL);
-}
-
 void NoReturnFunctionChecker::checkPostObjCMessage(const ObjCMethodCall &Msg,
                                                    CheckerContext &C) const {
   // Check if the method is annotated with analyzer_noreturn.
@@ -136,13 +120,17 @@
   default:
     return;
   case 4:
-    if (!isMultiArgSelector(&Sel, "handleFailureInFunction", "file",
-                            "lineNumber", "description", NULL))
+    lazyInitKeywordSelector(HandleFailureInFunctionSel, C.getASTContext(),
+                            "handleFailureInFunction", "file", "lineNumber",
+                            "description", nullptr);
+    if (Sel != HandleFailureInFunctionSel)
       return;
     break;
   case 5:
-    if (!isMultiArgSelector(&Sel, "handleFailureInMethod", "object", "file",
-                            "lineNumber", "description", NULL))
+    lazyInitKeywordSelector(HandleFailureInMethodSel, C.getASTContext(),
+                            "handleFailureInMethod", "object", "file",
+                            "lineNumber", "description", nullptr);
+    if (Sel != HandleFailureInMethodSel)
       return;
     break;
   }
@@ -151,7 +139,6 @@
   C.generateSink();
 }
 
-
 void ento::registerNoReturnFunctionChecker(CheckerManager &mgr) {
   mgr.registerChecker<NoReturnFunctionChecker>();
 }
diff --git a/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp b/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp
index 273a7a3..61d2b87 100644
--- a/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp
@@ -29,8 +29,9 @@
 namespace {
 class NonNullParamChecker
   : public Checker< check::PreCall > {
-  mutable OwningPtr<BugType> BTAttrNonNull;
-  mutable OwningPtr<BugType> BTNullRefArg;
+  mutable std::unique_ptr<BugType> BTAttrNonNull;
+  mutable std::unique_ptr<BugType> BTNullRefArg;
+
 public:
 
   void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
@@ -43,7 +44,7 @@
 } // end anonymous namespace
 
 void NonNullParamChecker::checkPreCall(const CallEvent &Call,
-                                      CheckerContext &C) const {
+                                       CheckerContext &C) const {
   const Decl *FD = Call.getDecl();
   if (!FD)
     return;
@@ -66,6 +67,12 @@
     }
 
     bool haveAttrNonNull = Att && Att->isNonNull(idx);
+    if (!haveAttrNonNull) {
+      // Check if the parameter is also marked 'nonnull'.
+      ArrayRef<ParmVarDecl*> parms = Call.parameters();
+      if (idx < parms.size())
+        haveAttrNonNull = parms[idx]->hasAttr<NonNullAttr>();
+    }
 
     if (!haveRefTypeParam && !haveAttrNonNull)
       continue;
@@ -98,7 +105,9 @@
         V = *CSV_I;
         DV = V.getAs<DefinedSVal>();
         assert(++CSV_I == CSV->end());
-        if (!DV)
+        // FIXME: Handle (some_union){ some_other_union_val }, which turns into
+        // a LazyCompoundVal inside a CompoundVal.
+        if (!V.getAs<Loc>())
           continue;
         // Retrieve the corresponding expression.
         if (const CompoundLiteralExpr *CE = dyn_cast<CompoundLiteralExpr>(ArgE))
@@ -114,14 +123,14 @@
 
     ConstraintManager &CM = C.getConstraintManager();
     ProgramStateRef stateNotNull, stateNull;
-    llvm::tie(stateNotNull, stateNull) = CM.assumeDual(state, *DV);
+    std::tie(stateNotNull, stateNull) = CM.assumeDual(state, *DV);
 
     if (stateNull && !stateNotNull) {
       // Generate an error node.  Check for a null node in case
       // we cache out.
       if (ExplodedNode *errorNode = C.generateSink(stateNull)) {
 
-        BugReport *R = 0;
+        BugReport *R = nullptr;
         if (haveAttrNonNull)
           R = genReportNullAttrNonNull(errorNode, ArgE);
         else if (haveRefTypeParam)
@@ -156,8 +165,7 @@
   // the BugReport is passed to 'EmitWarning'.
   if (!BTAttrNonNull)
     BTAttrNonNull.reset(new BugType(
-                            "Argument with 'nonnull' attribute passed null",
-                            "API"));
+        this, "Argument with 'nonnull' attribute passed null", "API"));
 
   BugReport *R = new BugReport(*BTAttrNonNull,
                   "Null pointer passed as an argument to a 'nonnull' parameter",
@@ -171,14 +179,14 @@
 BugReport *NonNullParamChecker::genReportReferenceToNullPointer(
   const ExplodedNode *ErrorNode, const Expr *ArgE) const {
   if (!BTNullRefArg)
-    BTNullRefArg.reset(new BuiltinBug("Dereference of null pointer"));
+    BTNullRefArg.reset(new BuiltinBug(this, "Dereference of null pointer"));
 
   BugReport *R = new BugReport(*BTNullRefArg,
                                "Forming reference to null pointer",
                                ErrorNode);
   if (ArgE) {
     const Expr *ArgEDeref = bugreporter::getDerefExpr(ArgE);
-    if (ArgEDeref == 0)
+    if (!ArgEDeref)
       ArgEDeref = ArgE;
     bugreporter::trackNullOrUndefValue(ErrorNode,
                                        ArgEDeref,
diff --git a/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp
index 4018a66..fbf2d73 100644
--- a/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp
@@ -26,8 +26,8 @@
 namespace {
 class ObjCAtSyncChecker
     : public Checker< check::PreStmt<ObjCAtSynchronizedStmt> > {
-  mutable OwningPtr<BuiltinBug> BT_null;
-  mutable OwningPtr<BuiltinBug> BT_undef;
+  mutable std::unique_ptr<BuiltinBug> BT_null;
+  mutable std::unique_ptr<BuiltinBug> BT_undef;
 
 public:
   void checkPreStmt(const ObjCAtSynchronizedStmt *S, CheckerContext &C) const;
@@ -45,8 +45,8 @@
   if (V.getAs<UndefinedVal>()) {
     if (ExplodedNode *N = C.generateSink()) {
       if (!BT_undef)
-        BT_undef.reset(new BuiltinBug("Uninitialized value used as mutex "
-                                  "for @synchronized"));
+        BT_undef.reset(new BuiltinBug(this, "Uninitialized value used as mutex "
+                                            "for @synchronized"));
       BugReport *report =
         new BugReport(*BT_undef, BT_undef->getDescription(), N);
       bugreporter::trackNullOrUndefValue(N, Ex, *report);
@@ -60,7 +60,7 @@
 
   // Check for null mutexes.
   ProgramStateRef notNullState, nullState;
-  llvm::tie(notNullState, nullState) = state->assume(V.castAs<DefinedSVal>());
+  std::tie(notNullState, nullState) = state->assume(V.castAs<DefinedSVal>());
 
   if (nullState) {
     if (!notNullState) {
@@ -68,8 +68,9 @@
       // a null mutex just means no synchronization occurs.
       if (ExplodedNode *N = C.addTransition(nullState)) {
         if (!BT_null)
-          BT_null.reset(new BuiltinBug("Nil value used as mutex for @synchronized() "
-                                   "(no synchronization will occur)"));
+          BT_null.reset(new BuiltinBug(
+              this, "Nil value used as mutex for @synchronized() "
+                    "(no synchronization will occur)"));
         BugReport *report =
           new BugReport(*BT_null, BT_null->getDescription(), N);
         bugreporter::trackNullOrUndefValue(N, Ex, *report);
diff --git a/lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp
index 503b1b5..e3fc611 100644
--- a/lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp
@@ -27,6 +27,7 @@
 namespace {
 class WalkAST : public StmtVisitor<WalkAST> {
   BugReporter &BR;
+  const CheckerBase *Checker;
   AnalysisDeclContext* AC;
   ASTContext &ASTC;
   uint64_t PtrWidth;
@@ -71,9 +72,9 @@
   }
 
 public:
-  WalkAST(BugReporter &br, AnalysisDeclContext* ac)
-  : BR(br), AC(ac), ASTC(AC->getASTContext()),
-    PtrWidth(ASTC.getTargetInfo().getPointerWidth(0)) {}
+  WalkAST(BugReporter &br, const CheckerBase *checker, AnalysisDeclContext *ac)
+      : BR(br), Checker(checker), AC(ac), ASTC(AC->getASTContext()),
+        PtrWidth(ASTC.getTargetInfo().getPointerWidth(0)) {}
 
   // Statement visitor methods.
   void VisitChildren(Stmt *S);
@@ -99,7 +100,7 @@
   if (Name.empty())
     return;
 
-  const Expr *Arg = 0;
+  const Expr *Arg = nullptr;
   unsigned ArgNum;
 
   if (Name.equals("CFArrayCreate") || Name.equals("CFSetCreate")) {
@@ -142,9 +143,9 @@
 
     PathDiagnosticLocation CELoc =
         PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
-    BR.EmitBasicReport(AC->getDecl(),
-                       OsName.str(), categories::CoreFoundationObjectiveC,
-                       Os.str(), CELoc, Arg->getSourceRange());
+    BR.EmitBasicReport(AC->getDecl(), Checker, OsName.str(),
+                       categories::CoreFoundationObjectiveC, Os.str(), CELoc,
+                       Arg->getSourceRange());
   }
 
   // Recurse and check children.
@@ -163,7 +164,7 @@
 
   void checkASTCodeBody(const Decl *D, AnalysisManager& Mgr,
                         BugReporter &BR) const {
-    WalkAST walker(BR, Mgr.getAnalysisDeclContext(D));
+    WalkAST walker(BR, this, Mgr.getAnalysisDeclContext(D));
     walker.Visit(D->getBody());
   }
 };
diff --git a/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp
index b9e96ee..8e51154 100644
--- a/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp
@@ -30,10 +30,10 @@
 namespace {
 class ObjCContainersChecker : public Checker< check::PreStmt<CallExpr>,
                                              check::PostStmt<CallExpr> > {
-  mutable OwningPtr<BugType> BT;
+  mutable std::unique_ptr<BugType> BT;
   inline void initBugType() const {
     if (!BT)
-      BT.reset(new BugType("CFArray API",
+      BT.reset(new BugType(this, "CFArray API",
                            categories::CoreFoundationObjectiveC));
   }
 
diff --git a/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp
index 789b9f4..a2cf8e1 100644
--- a/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp
@@ -181,16 +181,12 @@
 
 
   // Iterate over all instance methods.
-  for (ObjCImplementationDecl::instmeth_iterator I = D->instmeth_begin(),
-                                                 E = D->instmeth_end();
-       I != E; ++I) {
-    Selector S = (*I)->getSelector();
+  for (auto *MD : D->instance_methods()) {
+    Selector S = MD->getSelector();
     // Find out whether this is a selector that we want to check.
     if (!SelectorsForClass[SuperclassName].count(S))
       continue;
 
-    ObjCMethodDecl *MD = *I;
-
     // Check if the method calls its superclass implementation.
     if (MD->getBody())
     {
@@ -212,7 +208,7 @@
            << "' instance method in " << SuperclassName.str() << " subclass '"
            << *D << "' is missing a [super " << S.getAsString() << "] call";
 
-        BR.EmitBasicReport(MD, Name, categories::CoreFoundationObjectiveC,
+        BR.EmitBasicReport(MD, this, Name, categories::CoreFoundationObjectiveC,
                            os.str(), DLoc);
       }
     }
diff --git a/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
index 8506e08..51bc7e6 100644
--- a/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
@@ -62,7 +62,13 @@
                                              check::PostCall,
                                              check::Location,
                                              check::Bind > {
+  mutable std::unique_ptr<BugType> BT;
+
+  void checkForInvalidSelf(const Expr *E, CheckerContext &C,
+                           const char *errorStr) const;
+
 public:
+  ObjCSelfInitChecker() {}
   void checkPostObjCMessage(const ObjCMethodCall &Msg, CheckerContext &C) const;
   void checkPostStmt(const ObjCIvarRefExpr *E, CheckerContext &C) const;
   void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const;
@@ -74,22 +80,11 @@
   void checkPostCall(const CallEvent &CE, CheckerContext &C) const;
 
   void printState(raw_ostream &Out, ProgramStateRef State,
-                  const char *NL, const char *Sep) const;
+                  const char *NL, const char *Sep) const override;
 };
 } // end anonymous namespace
 
 namespace {
-
-class InitSelfBug : public BugType {
-  const std::string desc;
-public:
-  InitSelfBug() : BugType("Missing \"self = [(super or self) init...]\"",
-                          categories::CoreFoundationObjectiveC) {}
-};
-
-} // end anonymous namespace
-
-namespace {
 enum SelfFlagEnum {
   /// \brief No flag set.
   SelfFlag_None = 0x0,
@@ -146,8 +141,8 @@
   return true;
 }
 
-static void checkForInvalidSelf(const Expr *E, CheckerContext &C,
-                                const char *errorStr) {
+void ObjCSelfInitChecker::checkForInvalidSelf(const Expr *E, CheckerContext &C,
+                                              const char *errorStr) const {
   if (!E)
     return;
   
@@ -162,8 +157,10 @@
   if (!N)
     return;
 
-  BugReport *report =
-    new BugReport(*new InitSelfBug(), errorStr, N);
+  if (!BT)
+    BT.reset(new BugType(this, "Missing \"self = [(super or self) init...]\"",
+                         categories::CoreFoundationObjectiveC));
+  BugReport *report = new BugReport(*BT, errorStr, N);
   C.emitReport(report);
 }
 
@@ -205,9 +202,10 @@
                                  C.getCurrentAnalysisDeclContext()->getDecl())))
     return;
 
-  checkForInvalidSelf(E->getBase(), C,
-    "Instance variable used while 'self' is not set to the result of "
-                                                 "'[(super or self) init...]'");
+  checkForInvalidSelf(
+      E->getBase(), C,
+      "Instance variable used while 'self' is not set to the result of "
+      "'[(super or self) init...]'");
 }
 
 void ObjCSelfInitChecker::checkPreStmt(const ReturnStmt *S,
@@ -218,8 +216,8 @@
     return;
 
   checkForInvalidSelf(S->getRetValue(), C,
-    "Returning 'self' while it is not set to the result of "
-                                                 "'[(super or self) init...]'");
+                      "Returning 'self' while it is not set to the result of "
+                      "'[(super or self) init...]'");
 }
 
 // When a call receives a reference to 'self', [Pre/Post]Call pass
@@ -347,7 +345,7 @@
   if (FlagMap.isEmpty() && !DidCallInit && !PreCallFlags)
     return;
 
-  Out << Sep << NL << "ObjCSelfInitChecker:" << NL;
+  Out << Sep << NL << *this << " :" << NL;
 
   if (DidCallInit)
     Out << "  An init method has been called." << NL;
diff --git a/lib/StaticAnalyzer/Checkers/ObjCUnusedIVarsChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCUnusedIVarsChecker.cpp
index c66c7d0..d3b1753 100644
--- a/lib/StaticAnalyzer/Checkers/ObjCUnusedIVarsChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ObjCUnusedIVarsChecker.cpp
@@ -77,22 +77,17 @@
 
 static void Scan(IvarUsageMap& M, const ObjCContainerDecl *D) {
   // Scan the methods for accesses.
-  for (ObjCContainerDecl::instmeth_iterator I = D->instmeth_begin(),
-       E = D->instmeth_end(); I!=E; ++I)
-    Scan(M, (*I)->getBody());
+  for (const auto *I : D->instance_methods())
+    Scan(M, I->getBody());
 
   if (const ObjCImplementationDecl *ID = dyn_cast<ObjCImplementationDecl>(D)) {
     // Scan for @synthesized property methods that act as setters/getters
     // to an ivar.
-    for (ObjCImplementationDecl::propimpl_iterator I = ID->propimpl_begin(),
-         E = ID->propimpl_end(); I!=E; ++I)
-      Scan(M, *I);
+    for (const auto *I : ID->property_impls())
+      Scan(M, I);
 
     // Scan the associated categories as well.
-    for (ObjCInterfaceDecl::visible_categories_iterator
-           Cat = ID->getClassInterface()->visible_categories_begin(),
-           CatEnd = ID->getClassInterface()->visible_categories_end();
-         Cat != CatEnd; ++Cat) {
+    for (const auto *Cat : ID->getClassInterface()->visible_categories()) {
       if (const ObjCCategoryImplDecl *CID = Cat->getImplementation())
         Scan(M, CID);
     }
@@ -101,9 +96,8 @@
 
 static void Scan(IvarUsageMap &M, const DeclContext *C, const FileID FID,
                  SourceManager &SM) {
-  for (DeclContext::decl_iterator I=C->decls_begin(), E=C->decls_end();
-       I!=E; ++I)
-    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) {
+  for (const auto *I : C->decls())
+    if (const auto *FD = dyn_cast<FunctionDecl>(I)) {
       SourceLocation L = FD->getLocStart();
       if (SM.getFileID(L) == FID)
         Scan(M, FD->getBody());
@@ -111,29 +105,26 @@
 }
 
 static void checkObjCUnusedIvar(const ObjCImplementationDecl *D,
-                                BugReporter &BR) {
+                                BugReporter &BR,
+                                const CheckerBase *Checker) {
 
   const ObjCInterfaceDecl *ID = D->getClassInterface();
   IvarUsageMap M;
 
   // Iterate over the ivars.
-  for (ObjCInterfaceDecl::ivar_iterator I=ID->ivar_begin(),
-        E=ID->ivar_end(); I!=E; ++I) {
-
-    const ObjCIvarDecl *ID = *I;
-
+  for (const auto *Ivar : ID->ivars()) {
     // Ignore ivars that...
     // (a) aren't private
     // (b) explicitly marked unused
     // (c) are iboutlets
     // (d) are unnamed bitfields
-    if (ID->getAccessControl() != ObjCIvarDecl::Private ||
-        ID->getAttr<UnusedAttr>() || ID->getAttr<IBOutletAttr>() ||
-        ID->getAttr<IBOutletCollectionAttr>() ||
-        ID->isUnnamedBitfield())
+    if (Ivar->getAccessControl() != ObjCIvarDecl::Private ||
+        Ivar->hasAttr<UnusedAttr>() || Ivar->hasAttr<IBOutletAttr>() ||
+        Ivar->hasAttr<IBOutletCollectionAttr>() ||
+        Ivar->isUnnamedBitfield())
       continue;
 
-    M[ID] = Unused;
+    M[Ivar] = Unused;
   }
 
   if (M.empty())
@@ -172,7 +163,7 @@
 
       PathDiagnosticLocation L =
         PathDiagnosticLocation::create(I->first, BR.getSourceManager());
-      BR.EmitBasicReport(D, "Unused instance variable", "Optimization",
+      BR.EmitBasicReport(D, Checker, "Unused instance variable", "Optimization",
                          os.str(), L);
     }
 }
@@ -187,7 +178,7 @@
 public:
   void checkASTDecl(const ObjCImplementationDecl *D, AnalysisManager& mgr,
                     BugReporter &BR) const {
-    checkObjCUnusedIvar(D, BR);
+    checkObjCUnusedIvar(D, BR, this);
   }
 };
 }
diff --git a/lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp b/lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp
index bcbfacd..00480e4 100644
--- a/lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp
@@ -24,7 +24,7 @@
 namespace {
 class PointerArithChecker 
   : public Checker< check::PreStmt<BinaryOperator> > {
-  mutable OwningPtr<BuiltinBug> BT;
+  mutable std::unique_ptr<BuiltinBug> BT;
 
 public:
   void checkPreStmt(const BinaryOperator *B, CheckerContext &C) const;
@@ -53,10 +53,11 @@
 
     if (ExplodedNode *N = C.addTransition()) {
       if (!BT)
-        BT.reset(new BuiltinBug("Dangerous pointer arithmetic",
-                            "Pointer arithmetic done on non-array variables "
-                            "means reliance on memory layout, which is "
-                            "dangerous."));
+        BT.reset(
+            new BuiltinBug(this, "Dangerous pointer arithmetic",
+                           "Pointer arithmetic done on non-array variables "
+                           "means reliance on memory layout, which is "
+                           "dangerous."));
       BugReport *R = new BugReport(*BT, BT->getDescription(), N);
       R->addRange(B->getSourceRange());
       C.emitReport(R);
diff --git a/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp b/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp
index 07c82d4..fbb2628 100644
--- a/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp
@@ -25,7 +25,7 @@
 namespace {
 class PointerSubChecker 
   : public Checker< check::PreStmt<BinaryOperator> > {
-  mutable OwningPtr<BuiltinBug> BT;
+  mutable std::unique_ptr<BuiltinBug> BT;
 
 public:
   void checkPreStmt(const BinaryOperator *B, CheckerContext &C) const;
@@ -62,9 +62,10 @@
 
   if (ExplodedNode *N = C.addTransition()) {
     if (!BT)
-      BT.reset(new BuiltinBug("Pointer subtraction", 
-                          "Subtraction of two pointers that do not point to "
-                          "the same memory chunk may cause incorrect result."));
+      BT.reset(
+          new BuiltinBug(this, "Pointer subtraction",
+                         "Subtraction of two pointers that do not point to "
+                         "the same memory chunk may cause incorrect result."));
     BugReport *R = new BugReport(*BT, BT->getDescription(), N);
     R->addRange(B->getSourceRange());
     C.emitReport(R);
diff --git a/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp b/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp
index ffb8cf2..1ede3a2 100644
--- a/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp
@@ -24,9 +24,37 @@
 using namespace ento;
 
 namespace {
+
+struct LockState {
+  enum Kind { Destroyed, Locked, Unlocked } K;
+
+private:
+  LockState(Kind K) : K(K) {}
+
+public:
+  static LockState getLocked(void) { return LockState(Locked); }
+  static LockState getUnlocked(void) { return LockState(Unlocked); }
+  static LockState getDestroyed(void) { return LockState(Destroyed); }
+
+  bool operator==(const LockState &X) const {
+    return K == X.K;
+  }
+
+  bool isLocked() const { return K == Locked; }
+  bool isUnlocked() const { return K == Unlocked; }
+  bool isDestroyed() const { return K == Destroyed; }
+
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    ID.AddInteger(K);
+  }
+};
+
 class PthreadLockChecker : public Checker< check::PostStmt<CallExpr> > {
-  mutable OwningPtr<BugType> BT_doublelock;
-  mutable OwningPtr<BugType> BT_lor;
+  mutable std::unique_ptr<BugType> BT_doublelock;
+  mutable std::unique_ptr<BugType> BT_doubleunlock;
+  mutable std::unique_ptr<BugType> BT_destroylock;
+  mutable std::unique_ptr<BugType> BT_initlock;
+  mutable std::unique_ptr<BugType> BT_lor;
   enum LockingSemantics {
     NotApplicable = 0,
     PthreadSemantics,
@@ -39,12 +67,16 @@
                    bool isTryLock, enum LockingSemantics semantics) const;
     
   void ReleaseLock(CheckerContext &C, const CallExpr *CE, SVal lock) const;
+  void DestroyLock(CheckerContext &C, const CallExpr *CE, SVal Lock) const;
+  void InitLock(CheckerContext &C, const CallExpr *CE, SVal Lock) const;
+  void reportUseDestroyedBug(CheckerContext &C, const CallExpr *CE) const;
 };
 } // end anonymous namespace
 
 // GDM Entry for tracking lock state.
 REGISTER_LIST_WITH_PROGRAMSTATE(LockSet, const MemRegion *)
 
+REGISTER_MAP_WITH_PROGRAMSTATE(LockMap, const MemRegion *, LockState)
 
 void PthreadLockChecker::checkPostStmt(const CallExpr *CE,
                                        CheckerContext &C) const {
@@ -54,7 +86,7 @@
   if (FName.empty())
     return;
 
-  if (CE->getNumArgs() != 1)
+  if (CE->getNumArgs() != 1 && CE->getNumArgs() != 2)
     return;
 
   if (FName == "pthread_mutex_lock" ||
@@ -69,7 +101,7 @@
                 false, XNUSemantics);
   else if (FName == "pthread_mutex_trylock" ||
            FName == "pthread_rwlock_tryrdlock" ||
-           FName == "pthread_rwlock_tryrwlock")
+           FName == "pthread_rwlock_trywrlock")
     AcquireLock(C, CE, state->getSVal(CE->getArg(0), LCtx),
                 true, PthreadSemantics);
   else if (FName == "lck_mtx_try_lock" ||
@@ -82,6 +114,11 @@
            FName == "lck_mtx_unlock" ||
            FName == "lck_rw_done")
     ReleaseLock(C, CE, state->getSVal(CE->getArg(0), LCtx));
+  else if (FName == "pthread_mutex_destroy" ||
+           FName == "lck_mtx_destroy")
+    DestroyLock(C, CE, state->getSVal(CE->getArg(0), LCtx));
+  else if (FName == "pthread_mutex_init")
+    InitLock(C, CE, state->getSVal(CE->getArg(0), LCtx));
 }
 
 void PthreadLockChecker::AcquireLock(CheckerContext &C, const CallExpr *CE,
@@ -100,18 +137,24 @@
   
   DefinedSVal retVal = X.castAs<DefinedSVal>();
 
-  if (state->contains<LockSet>(lockR)) {
-    if (!BT_doublelock)
-      BT_doublelock.reset(new BugType("Double locking", "Lock checker"));
-    ExplodedNode *N = C.generateSink();
-    if (!N)
+  if (const LockState *LState = state->get<LockMap>(lockR)) {
+    if (LState->isLocked()) {
+      if (!BT_doublelock)
+        BT_doublelock.reset(new BugType(this, "Double locking",
+                                        "Lock checker"));
+      ExplodedNode *N = C.generateSink();
+      if (!N)
+        return;
+      BugReport *report = new BugReport(*BT_doublelock,
+                                        "This lock has already been acquired",
+                                        N);
+      report->addRange(CE->getArg(0)->getSourceRange());
+      C.emitReport(report);
       return;
-    BugReport *report = new BugReport(*BT_doublelock,
-                                                      "This lock has already "
-                                                      "been acquired", N);
-    report->addRange(CE->getArg(0)->getSourceRange());
-    C.emitReport(report);
-    return;
+    } else if (LState->isDestroyed()) {
+      reportUseDestroyedBug(C, CE);
+      return;
+    }
   }
 
   ProgramStateRef lockSucc = state;
@@ -120,10 +163,10 @@
     ProgramStateRef lockFail;
     switch (semantics) {
     case PthreadSemantics:
-      llvm::tie(lockFail, lockSucc) = state->assume(retVal);    
+      std::tie(lockFail, lockSucc) = state->assume(retVal);
       break;
     case XNUSemantics:
-      llvm::tie(lockSucc, lockFail) = state->assume(retVal);    
+      std::tie(lockSucc, lockFail) = state->assume(retVal);
       break;
     default:
       llvm_unreachable("Unknown tryLock locking semantics");
@@ -144,6 +187,7 @@
   
   // Record that the lock was acquired.  
   lockSucc = lockSucc->add<LockSet>(lockR);
+  lockSucc = lockSucc->set<LockMap>(lockR, LockState::getLocked());
   C.addTransition(lockSucc);
 }
 
@@ -155,35 +199,140 @@
     return;
   
   ProgramStateRef state = C.getState();
+
+  if (const LockState *LState = state->get<LockMap>(lockR)) {
+    if (LState->isUnlocked()) {
+      if (!BT_doubleunlock)
+        BT_doubleunlock.reset(new BugType(this, "Double unlocking",
+                                          "Lock checker"));
+      ExplodedNode *N = C.generateSink();
+      if (!N)
+        return;
+      BugReport *Report = new BugReport(*BT_doubleunlock,
+                                        "This lock has already been unlocked",
+                                        N);
+      Report->addRange(CE->getArg(0)->getSourceRange());
+      C.emitReport(Report);
+      return;
+    } else if (LState->isDestroyed()) {
+      reportUseDestroyedBug(C, CE);
+      return;
+    }
+  }
+
   LockSetTy LS = state->get<LockSet>();
 
   // FIXME: Better analysis requires IPA for wrappers.
-  // FIXME: check for double unlocks
-  if (LS.isEmpty())
-    return;
-  
-  const MemRegion *firstLockR = LS.getHead();
-  if (firstLockR != lockR) {
-    if (!BT_lor)
-      BT_lor.reset(new BugType("Lock order reversal", "Lock checker"));
-    ExplodedNode *N = C.generateSink();
-    if (!N)
+
+  if (!LS.isEmpty()) {
+    const MemRegion *firstLockR = LS.getHead();
+    if (firstLockR != lockR) {
+      if (!BT_lor)
+        BT_lor.reset(new BugType(this, "Lock order reversal", "Lock checker"));
+      ExplodedNode *N = C.generateSink();
+      if (!N)
+        return;
+      BugReport *report = new BugReport(*BT_lor,
+                                        "This was not the most recently "
+                                        "acquired lock. Possible lock order "
+                                        "reversal",
+                                        N);
+      report->addRange(CE->getArg(0)->getSourceRange());
+      C.emitReport(report);
       return;
-    BugReport *report = new BugReport(*BT_lor,
-                                                      "This was not the most "
-                                                      "recently acquired lock. "
-                                                      "Possible lock order "
-                                                      "reversal", N);
-    report->addRange(CE->getArg(0)->getSourceRange());
-    C.emitReport(report);
-    return;
+    }
+    // Record that the lock was released.
+    state = state->set<LockSet>(LS.getTail());
   }
 
-  // Record that the lock was released. 
-  state = state->set<LockSet>(LS.getTail());
+  state = state->set<LockMap>(lockR, LockState::getUnlocked());
   C.addTransition(state);
 }
 
+void PthreadLockChecker::DestroyLock(CheckerContext &C, const CallExpr *CE,
+                                     SVal Lock) const {
+
+  const MemRegion *LockR = Lock.getAsRegion();
+  if (!LockR)
+    return;
+
+  ProgramStateRef State = C.getState();
+
+  const LockState *LState = State->get<LockMap>(LockR);
+  if (!LState || LState->isUnlocked()) {
+    State = State->set<LockMap>(LockR, LockState::getDestroyed());
+    C.addTransition(State);
+    return;
+  }
+
+  StringRef Message;
+
+  if (LState->isLocked()) {
+    Message = "This lock is still locked";
+  } else {
+    Message = "This lock has already been destroyed";
+  }
+
+  if (!BT_destroylock)
+    BT_destroylock.reset(new BugType(this, "Destroy invalid lock",
+                                     "Lock checker"));
+  ExplodedNode *N = C.generateSink();
+  if (!N)
+    return;
+  BugReport *Report = new BugReport(*BT_destroylock, Message, N);
+  Report->addRange(CE->getArg(0)->getSourceRange());
+  C.emitReport(Report);
+}
+
+void PthreadLockChecker::InitLock(CheckerContext &C, const CallExpr *CE,
+                                  SVal Lock) const {
+
+  const MemRegion *LockR = Lock.getAsRegion();
+  if (!LockR)
+    return;
+
+  ProgramStateRef State = C.getState();
+
+  const struct LockState *LState = State->get<LockMap>(LockR);
+  if (!LState || LState->isDestroyed()) {
+    State = State->set<LockMap>(LockR, LockState::getUnlocked());
+    C.addTransition(State);
+    return;
+  }
+
+  StringRef Message;
+
+  if (LState->isLocked()) {
+    Message = "This lock is still being held";
+  } else {
+    Message = "This lock has already been initialized";
+  }
+
+  if (!BT_initlock)
+    BT_initlock.reset(new BugType(this, "Init invalid lock",
+                                  "Lock checker"));
+  ExplodedNode *N = C.generateSink();
+  if (!N)
+    return;
+  BugReport *Report = new BugReport(*BT_initlock, Message, N);
+  Report->addRange(CE->getArg(0)->getSourceRange());
+  C.emitReport(Report);
+}
+
+void PthreadLockChecker::reportUseDestroyedBug(CheckerContext &C,
+                                               const CallExpr *CE) const {
+  if (!BT_destroylock)
+    BT_destroylock.reset(new BugType(this, "Use destroyed lock",
+                                     "Lock checker"));
+  ExplodedNode *N = C.generateSink();
+  if (!N)
+    return;
+  BugReport *Report = new BugReport(*BT_destroylock,
+                                    "This lock has already been destroyed",
+                                    N);
+  Report->addRange(CE->getArg(0)->getSourceRange());
+  C.emitReport(Report);
+}
 
 void ento::registerPthreadLockChecker(CheckerManager &mgr) {
   mgr.registerChecker<PthreadLockChecker>();
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
index c474e78..eb699d6 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
@@ -13,6 +13,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "ClangSACheckers.h"
+#include "AllocationDiagnostics.h"
+#include "SelectorExtras.h"
 #include "clang/AST/Attr.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
@@ -20,6 +22,7 @@
 #include "clang/Analysis/DomainSpecific/CocoaConventions.h"
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/SourceManager.h"
+#include "clang/StaticAnalyzer/Checkers/ObjCRetainCount.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
@@ -28,7 +31,6 @@
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
-#include "clang/StaticAnalyzer/Checkers/ObjCRetainCount.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/ImmutableList.h"
@@ -38,8 +40,6 @@
 #include "llvm/ADT/StringExtras.h"
 #include <cstdarg>
 
-#include "AllocationDiagnostics.h"
-
 using namespace clang;
 using namespace ento;
 using namespace objc_retain;
@@ -95,29 +95,70 @@
   };
 
 private:
-  Kind kind;
-  RetEffect::ObjKind okind;
+  /// The number of outstanding retains.
   unsigned Cnt;
+  /// The number of outstanding autoreleases.
   unsigned ACnt;
+  /// The (static) type of the object at the time we started tracking it.
   QualType T;
 
-  RefVal(Kind k, RetEffect::ObjKind o, unsigned cnt, unsigned acnt, QualType t)
-  : kind(k), okind(o), Cnt(cnt), ACnt(acnt), T(t) {}
+  /// The current state of the object.
+  ///
+  /// See the RefVal::Kind enum for possible values.
+  unsigned RawKind : 5;
+
+  /// The kind of object being tracked (CF or ObjC), if known.
+  ///
+  /// See the RetEffect::ObjKind enum for possible values.
+  unsigned RawObjectKind : 2;
+
+  /// True if the current state and/or retain count may turn out to not be the
+  /// best possible approximation of the reference counting state.
+  ///
+  /// If true, the checker may decide to throw away ("override") this state
+  /// in favor of something else when it sees the object being used in new ways.
+  ///
+  /// This setting should not be propagated to state derived from this state.
+  /// Once we start deriving new states, it would be inconsistent to override
+  /// them.
+  unsigned IsOverridable : 1;
+
+  RefVal(Kind k, RetEffect::ObjKind o, unsigned cnt, unsigned acnt, QualType t,
+         bool Overridable = false)
+    : Cnt(cnt), ACnt(acnt), T(t), RawKind(static_cast<unsigned>(k)),
+      RawObjectKind(static_cast<unsigned>(o)), IsOverridable(Overridable) {
+    assert(getKind() == k && "not enough bits for the kind");
+    assert(getObjKind() == o && "not enough bits for the object kind");
+  }
 
 public:
-  Kind getKind() const { return kind; }
+  Kind getKind() const { return static_cast<Kind>(RawKind); }
 
-  RetEffect::ObjKind getObjKind() const { return okind; }
+  RetEffect::ObjKind getObjKind() const {
+    return static_cast<RetEffect::ObjKind>(RawObjectKind);
+  }
 
   unsigned getCount() const { return Cnt; }
   unsigned getAutoreleaseCount() const { return ACnt; }
   unsigned getCombinedCounts() const { return Cnt + ACnt; }
-  void clearCounts() { Cnt = 0; ACnt = 0; }
-  void setCount(unsigned i) { Cnt = i; }
-  void setAutoreleaseCount(unsigned i) { ACnt = i; }
+  void clearCounts() {
+    Cnt = 0;
+    ACnt = 0;
+    IsOverridable = false;
+  }
+  void setCount(unsigned i) {
+    Cnt = i;
+    IsOverridable = false;
+  }
+  void setAutoreleaseCount(unsigned i) {
+    ACnt = i;
+    IsOverridable = false;
+  }
 
   QualType getType() const { return T; }
 
+  bool isOverridable() const { return IsOverridable; }
+
   bool isOwned() const {
     return getKind() == Owned;
   }
@@ -134,20 +175,31 @@
     return getKind() == ReturnedNotOwned;
   }
 
+  /// Create a state for an object whose lifetime is the responsibility of the
+  /// current function, at least partially.
+  ///
+  /// Most commonly, this is an owned object with a retain count of +1.
   static RefVal makeOwned(RetEffect::ObjKind o, QualType t,
                           unsigned Count = 1) {
     return RefVal(Owned, o, Count, 0, t);
   }
 
+  /// Create a state for an object whose lifetime is not the responsibility of
+  /// the current function.
+  ///
+  /// Most commonly, this is an unowned object with a retain count of +0.
   static RefVal makeNotOwned(RetEffect::ObjKind o, QualType t,
                              unsigned Count = 0) {
     return RefVal(NotOwned, o, Count, 0, t);
   }
 
-  // Comparison, profiling, and pretty-printing.
-
-  bool operator==(const RefVal& X) const {
-    return kind == X.kind && Cnt == X.Cnt && T == X.T && ACnt == X.ACnt;
+  /// Create an "overridable" state for an unowned object at +0.
+  ///
+  /// An overridable state is one that provides a good approximation of the
+  /// reference counting state now, but which may be discarded later if the
+  /// checker sees the object being used in new ways.
+  static RefVal makeOverridableNotOwned(RetEffect::ObjKind o, QualType t) {
+    return RefVal(NotOwned, o, 0, 0, t, /*Overridable=*/true);
   }
 
   RefVal operator-(size_t i) const {
@@ -170,11 +222,24 @@
                   getType());
   }
 
+  // Comparison, profiling, and pretty-printing.
+
+  bool hasSameState(const RefVal &X) const {
+    return getKind() == X.getKind() && Cnt == X.Cnt && ACnt == X.ACnt;
+  }
+
+  bool operator==(const RefVal& X) const {
+    return T == X.T && hasSameState(X) && getObjKind() == X.getObjKind() &&
+           IsOverridable == X.IsOverridable;
+  }
+  
   void Profile(llvm::FoldingSetNodeID& ID) const {
-    ID.AddInteger((unsigned) kind);
+    ID.Add(T);
+    ID.AddInteger(RawKind);
     ID.AddInteger(Cnt);
     ID.AddInteger(ACnt);
-    ID.Add(T);
+    ID.AddInteger(RawObjectKind);
+    ID.AddBoolean(IsOverridable);
   }
 
   void print(raw_ostream &Out) const;
@@ -184,6 +249,9 @@
   if (!T.isNull())
     Out << "Tracked " << T.getAsString() << '/';
 
+  if (isOverridable())
+    Out << "(overridable) ";
+
   switch (getKind()) {
     default: llvm_unreachable("Invalid RefVal kind");
     case Owned: {
@@ -383,10 +451,10 @@
     : II(ii), S(s) {}
 
   ObjCSummaryKey(const ObjCInterfaceDecl *d, Selector s)
-    : II(d ? d->getIdentifier() : 0), S(s) {}
+    : II(d ? d->getIdentifier() : nullptr), S(s) {}
 
   ObjCSummaryKey(Selector s)
-    : II(0), S(s) {}
+    : II(nullptr), S(s) {}
 
   IdentifierInfo *getIdentifier() const { return II; }
   Selector getSelector() const { return S; }
@@ -435,7 +503,7 @@
     if (I != M.end())
       return I->second;
     if (!D)
-      return NULL;
+      return nullptr;
 
     // Walk the super chain.  If we find a hit with a parent, we'll end
     // up returning that summary.  We actually allow that key (null,S), as
@@ -448,7 +516,7 @@
         break;
 
       if (!C)
-        return NULL;
+        return nullptr;
     }
 
     // Cache the summary with original key to make the next lookup faster
@@ -466,7 +534,7 @@
     if (I == M.end())
       I = M.find(ObjCSummaryKey(S));
 
-    return I == M.end() ? NULL : I->second;
+    return I == M.end() ? nullptr : I->second;
   }
 
   const RetainSummary *& operator[](ObjCSummaryKey K) {
@@ -608,18 +676,9 @@
     ObjCMethodSummaries[ObjCSummaryKey(ClsII, S)]  = Summ;
   }
 
-  Selector generateSelector(va_list argp) {
-    SmallVector<IdentifierInfo*, 10> II;
-
-    while (const char* s = va_arg(argp, const char*))
-      II.push_back(&Ctx.Idents.get(s));
-
-    return Ctx.Selectors.getSelector(II.size(), &II[0]);
-  }
-
-  void addMethodSummary(IdentifierInfo *ClsII, ObjCMethodSummariesTy& Summaries,
-                        const RetainSummary * Summ, va_list argp) {
-    Selector S = generateSelector(argp);
+  void addMethodSummary(IdentifierInfo *ClsII, ObjCMethodSummariesTy &Summaries,
+                        const RetainSummary *Summ, va_list argp) {
+    Selector S = getKeywordSelector(Ctx, argp);
     Summaries[ObjCSummaryKey(ClsII, S)] = Summ;
   }
 
@@ -653,18 +712,18 @@
      AF(BPAlloc), ScratchArgs(AF.getEmptyMap()),
      ObjCAllocRetE(gcenabled
                     ? RetEffect::MakeGCNotOwned()
-                    : (usesARC ? RetEffect::MakeARCNotOwned()
+                    : (usesARC ? RetEffect::MakeNotOwned(RetEffect::ObjC)
                                : RetEffect::MakeOwned(RetEffect::ObjC, true))),
      ObjCInitRetE(gcenabled 
                     ? RetEffect::MakeGCNotOwned()
-                    : (usesARC ? RetEffect::MakeARCNotOwned()
+                    : (usesARC ? RetEffect::MakeNotOwned(RetEffect::ObjC)
                                : RetEffect::MakeOwnedWhenTrackedReceiver())) {
     InitializeClassMethodSummaries();
     InitializeMethodSummaries();
   }
 
   const RetainSummary *getSummary(const CallEvent &Call,
-                                  ProgramStateRef State = 0);
+                                  ProgramStateRef State = nullptr);
 
   const RetainSummary *getFunctionSummary(const FunctionDecl *FD);
 
@@ -689,7 +748,7 @@
   const RetainSummary *getMethodSummary(const ObjCMethodDecl *MD) {
     const ObjCInterfaceDecl *ID = MD->getClassInterface();
     Selector S = MD->getSelector();
-    QualType ResultTy = MD->getResultType();
+    QualType ResultTy = MD->getReturnType();
 
     ObjCMethodSummariesTy *CachedSummaries;
     if (MD->isInstanceMethod())
@@ -861,7 +920,7 @@
     // Special cases where the callback argument CANNOT free the return value.
     // This can generally only happen if we know that the callback will only be
     // called when the return value is already being deallocated.
-    if (const FunctionCall *FC = dyn_cast<FunctionCall>(&Call)) {
+    if (const SimpleFunctionCall *FC = dyn_cast<SimpleFunctionCall>(&Call)) {
       if (IdentifierInfo *Name = FC->getDecl()->getIdentifier()) {
         // When the CGBitmapContext is deallocated, the callback here will free
         // the associated data buffer.
@@ -909,7 +968,7 @@
   const RetainSummary *Summ;
   switch (Call.getKind()) {
   case CE_Function:
-    Summ = getFunctionSummary(cast<FunctionCall>(Call).getDecl());
+    Summ = getFunctionSummary(cast<SimpleFunctionCall>(Call).getDecl());
     break;
   case CE_CXXMember:
   case CE_CXXMemberOperator:
@@ -947,7 +1006,7 @@
     return I->second;
 
   // No summary?  Generate one.
-  const RetainSummary *S = 0;
+  const RetainSummary *S = nullptr;
   bool AllowAnnotations = true;
 
   do {
@@ -971,7 +1030,7 @@
     FName = FName.substr(FName.find_first_not_of('_'));
 
     // Inspect the result type.
-    QualType RetTy = FT->getResultType();
+    QualType RetTy = FT->getReturnType();
 
     // FIXME: This should all be refactored into a chain of "summary lookup"
     //  filters.
@@ -1102,7 +1161,7 @@
         break;
       }
 
-      if (FD->getAttr<CFAuditedTransferAttr>()) {
+      if (FD->hasAttr<CFAuditedTransferAttr>()) {
         S = getCFCreateGetRuleSummary(FD);
         break;
       }
@@ -1175,7 +1234,7 @@
   // Sanity check that this is *really* a unary function.  This can
   // happen if people do weird things.
   const FunctionProtoType* FTP = dyn_cast<FunctionProtoType>(FT);
-  if (!FTP || FTP->getNumArgs() != 1)
+  if (!FTP || FTP->getNumParams() != 1)
     return getPersistentStopSummary();
 
   assert (ScratchArgs.isEmpty());
@@ -1214,21 +1273,21 @@
 RetainSummaryManager::getRetEffectFromAnnotations(QualType RetTy,
                                                   const Decl *D) {
   if (cocoa::isCocoaObjectRef(RetTy)) {
-    if (D->getAttr<NSReturnsRetainedAttr>())
+    if (D->hasAttr<NSReturnsRetainedAttr>())
       return ObjCAllocRetE;
 
-    if (D->getAttr<NSReturnsNotRetainedAttr>() ||
-        D->getAttr<NSReturnsAutoreleasedAttr>())
+    if (D->hasAttr<NSReturnsNotRetainedAttr>() ||
+        D->hasAttr<NSReturnsAutoreleasedAttr>())
       return RetEffect::MakeNotOwned(RetEffect::ObjC);
 
   } else if (!RetTy->isPointerType()) {
     return None;
   }
 
-  if (D->getAttr<CFReturnsRetainedAttr>())
+  if (D->hasAttr<CFReturnsRetainedAttr>())
     return RetEffect::MakeOwned(RetEffect::CF, true);
 
-  if (D->getAttr<CFReturnsNotRetainedAttr>())
+  if (D->hasAttr<CFReturnsNotRetainedAttr>())
     return RetEffect::MakeNotOwned(RetEffect::CF);
 
   return None;
@@ -1248,13 +1307,13 @@
   for (FunctionDecl::param_const_iterator pi = FD->param_begin(), 
          pe = FD->param_end(); pi != pe; ++pi, ++parm_idx) {
     const ParmVarDecl *pd = *pi;
-    if (pd->getAttr<NSConsumedAttr>())
+    if (pd->hasAttr<NSConsumedAttr>())
       Template->addArg(AF, parm_idx, DecRefMsg);
-    else if (pd->getAttr<CFConsumedAttr>())
+    else if (pd->hasAttr<CFConsumedAttr>())
       Template->addArg(AF, parm_idx, DecRef);      
   }
-  
-  QualType RetTy = FD->getResultType();
+
+  QualType RetTy = FD->getReturnType();
   if (Optional<RetEffect> RetE = getRetEffectFromAnnotations(RetTy, FD))
     Template->setRetEffect(*RetE);
 }
@@ -1269,7 +1328,7 @@
   RetainSummaryTemplate Template(Summ, *this);
 
   // Effects on the receiver.
-  if (MD->getAttr<NSConsumesSelfAttr>())
+  if (MD->hasAttr<NSConsumesSelfAttr>())
     Template->setReceiverEffect(DecRefMsg);      
   
   // Effects on the parameters.
@@ -1278,14 +1337,14 @@
          pi=MD->param_begin(), pe=MD->param_end();
        pi != pe; ++pi, ++parm_idx) {
     const ParmVarDecl *pd = *pi;
-    if (pd->getAttr<NSConsumedAttr>())
+    if (pd->hasAttr<NSConsumedAttr>())
       Template->addArg(AF, parm_idx, DecRefMsg);      
-    else if (pd->getAttr<CFConsumedAttr>()) {
+    else if (pd->hasAttr<CFConsumedAttr>()) {
       Template->addArg(AF, parm_idx, DecRef);      
     }   
   }
-  
-  QualType RetTy = MD->getResultType();
+
+  QualType RetTy = MD->getReturnType();
   if (Optional<RetEffect> RetE = getRetEffectFromAnnotations(RetTy, MD))
     Template->setRetEffect(*RetE);
 }
@@ -1388,7 +1447,7 @@
 const RetainSummary *
 RetainSummaryManager::getInstanceMethodSummary(const ObjCMethodCall &Msg,
                                                ProgramStateRef State) {
-  const ObjCInterfaceDecl *ReceiverClass = 0;
+  const ObjCInterfaceDecl *ReceiverClass = nullptr;
 
   // We do better tracking of the type of the object than the core ExprEngine.
   // See if we have its type in our private state.
@@ -1507,6 +1566,11 @@
   //   as for NSWindow objects.
   addClassMethSummary("NSPanel", "alloc", NoTrackYet);
 
+  // For NSNull, objects returned by +null are singletons that ignore
+  // retain/release semantics.  Just don't track them.
+  // <rdar://problem/12858915>
+  addClassMethSummary("NSNull", "null", NoTrackYet);
+
   // Don't track allocated autorelease pools, as it is okay to prematurely
   // exit a method.
   addClassMethSummary("NSAutoreleasePool", "alloc", NoTrackYet);
@@ -1543,8 +1607,9 @@
 
   class CFRefBug : public BugType {
   protected:
-    CFRefBug(StringRef name)
-    : BugType(name, categories::MemoryCoreFoundationObjectiveC) {}
+    CFRefBug(const CheckerBase *checker, StringRef name)
+        : BugType(checker, name, categories::MemoryCoreFoundationObjectiveC) {}
+
   public:
 
     // FIXME: Eventually remove.
@@ -1555,18 +1620,19 @@
 
   class UseAfterRelease : public CFRefBug {
   public:
-    UseAfterRelease() : CFRefBug("Use-after-release") {}
+    UseAfterRelease(const CheckerBase *checker)
+        : CFRefBug(checker, "Use-after-release") {}
 
-    const char *getDescription() const {
+    const char *getDescription() const override {
       return "Reference-counted object is used after it is released";
     }
   };
 
   class BadRelease : public CFRefBug {
   public:
-    BadRelease() : CFRefBug("Bad release") {}
+    BadRelease(const CheckerBase *checker) : CFRefBug(checker, "Bad release") {}
 
-    const char *getDescription() const {
+    const char *getDescription() const override {
       return "Incorrect decrement of the reference count of an object that is "
              "not owned at this point by the caller";
     }
@@ -1574,40 +1640,40 @@
 
   class DeallocGC : public CFRefBug {
   public:
-    DeallocGC()
-    : CFRefBug("-dealloc called while using garbage collection") {}
+    DeallocGC(const CheckerBase *checker)
+        : CFRefBug(checker, "-dealloc called while using garbage collection") {}
 
-    const char *getDescription() const {
+    const char *getDescription() const override {
       return "-dealloc called while using garbage collection";
     }
   };
 
   class DeallocNotOwned : public CFRefBug {
   public:
-    DeallocNotOwned()
-    : CFRefBug("-dealloc sent to non-exclusively owned object") {}
+    DeallocNotOwned(const CheckerBase *checker)
+        : CFRefBug(checker, "-dealloc sent to non-exclusively owned object") {}
 
-    const char *getDescription() const {
+    const char *getDescription() const override {
       return "-dealloc sent to object that may be referenced elsewhere";
     }
   };
 
   class OverAutorelease : public CFRefBug {
   public:
-    OverAutorelease()
-    : CFRefBug("Object autoreleased too many times") {}
+    OverAutorelease(const CheckerBase *checker)
+        : CFRefBug(checker, "Object autoreleased too many times") {}
 
-    const char *getDescription() const {
+    const char *getDescription() const override {
       return "Object autoreleased too many times";
     }
   };
 
   class ReturnedNotOwnedForOwned : public CFRefBug {
   public:
-    ReturnedNotOwnedForOwned()
-    : CFRefBug("Method should return an owned object") {}
+    ReturnedNotOwnedForOwned(const CheckerBase *checker)
+        : CFRefBug(checker, "Method should return an owned object") {}
 
-    const char *getDescription() const {
+    const char *getDescription() const override {
       return "Object with a +0 retain count returned to caller where a +1 "
              "(owning) retain count is expected";
     }
@@ -1615,15 +1681,14 @@
 
   class Leak : public CFRefBug {
   public:
-    Leak(StringRef name)
-    : CFRefBug(name) {
+    Leak(const CheckerBase *checker, StringRef name) : CFRefBug(checker, name) {
       // Leaks should not be reported if they are post-dominated by a sink.
       setSuppressOnSink(true);
     }
 
-    const char *getDescription() const { return ""; }
+    const char *getDescription() const override { return ""; }
 
-    bool isLeak() const { return true; }
+    bool isLeak() const override { return true; }
   };
 
   //===---------===//
@@ -1640,20 +1705,20 @@
     CFRefReportVisitor(SymbolRef sym, bool gcEnabled, const SummaryLogTy &log)
        : Sym(sym), SummaryLog(log), GCEnabled(gcEnabled) {}
 
-    virtual void Profile(llvm::FoldingSetNodeID &ID) const {
+    void Profile(llvm::FoldingSetNodeID &ID) const override {
       static int x = 0;
       ID.AddPointer(&x);
       ID.AddPointer(Sym);
     }
 
-    virtual PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
-                                           const ExplodedNode *PrevN,
-                                           BugReporterContext &BRC,
-                                           BugReport &BR);
+    PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
+                                   const ExplodedNode *PrevN,
+                                   BugReporterContext &BRC,
+                                   BugReport &BR) override;
 
-    virtual PathDiagnosticPiece *getEndPath(BugReporterContext &BRC,
-                                            const ExplodedNode *N,
-                                            BugReport &BR);
+    PathDiagnosticPiece *getEndPath(BugReporterContext &BRC,
+                                    const ExplodedNode *N,
+                                    BugReport &BR) override;
   };
 
   class CFRefLeakReportVisitor : public CFRefReportVisitor {
@@ -1664,9 +1729,9 @@
 
     PathDiagnosticPiece *getEndPath(BugReporterContext &BRC,
                                     const ExplodedNode *N,
-                                    BugReport &BR);
+                                    BugReport &BR) override;
 
-    virtual BugReporterVisitor *clone() const {
+    BugReporterVisitor *clone() const override {
       // The curiously-recurring template pattern only works for one level of
       // subclassing. Rather than make a new template base for
       // CFRefReportVisitor, we simply override clone() to do the right thing.
@@ -1697,7 +1762,7 @@
       addGCModeDescription(LOpts, GCEnabled);
     }
 
-    virtual std::pair<ranges_iterator, ranges_iterator> getRanges() {
+    std::pair<ranges_iterator, ranges_iterator> getRanges() override {
       const CFRefBug& BugTy = static_cast<CFRefBug&>(getBugType());
       if (!BugTy.isLeak())
         return BugReport::getRanges();
@@ -1714,7 +1779,7 @@
                     CheckerContext &Ctx,
                     bool IncludeAllocationLine);
 
-    PathDiagnosticLocation getLocation(const SourceManager &SM) const {
+    PathDiagnosticLocation getLocation(const SourceManager &SM) const override {
       assert(Location.isValid());
       return Location;
     }
@@ -1723,7 +1788,7 @@
 
 void CFRefReport::addGCModeDescription(const LangOptions &LOpts,
                                        bool GCEnabled) {
-  const char *GCModeDescription = 0;
+  const char *GCModeDescription = nullptr;
 
   switch (LOpts.getGC()) {
   case LangOptions::GCOnly:
@@ -1770,7 +1835,7 @@
   // FIXME: We will eventually need to handle non-statement-based events
   // (__attribute__((cleanup))).
   if (!N->getLocation().getAs<StmtPoint>())
-    return NULL;
+    return nullptr;
 
   // Check if the type state has changed.
   ProgramStateRef PrevSt = PrevN->getState();
@@ -1778,7 +1843,7 @@
   const LocationContext *LCtx = N->getLocationContext();
 
   const RefVal* CurrT = getRefBinding(CurrSt, Sym);
-  if (!CurrT) return NULL;
+  if (!CurrT) return nullptr;
 
   const RefVal &CurrV = *CurrT;
   const RefVal *PrevT = getRefBinding(PrevSt, Sym);
@@ -1803,7 +1868,7 @@
       if (isNumericLiteralExpression(BL->getSubExpr()))
         os << "NSNumber literal is an object with a +0 retain count";
       else {
-        const ObjCInterfaceDecl *BoxClass = 0;
+        const ObjCInterfaceDecl *BoxClass = nullptr;
         if (const ObjCMethodDecl *Method = BL->getBoxingMethod())
           BoxClass = Method->getClassInterface();
 
@@ -1918,7 +1983,7 @@
     if (!GCEnabled && std::find(AEffects.begin(), AEffects.end(), Dealloc) !=
                           AEffects.end()) {
       // Determine if the object's reference count was pushed to zero.
-      assert(!(PrevV == CurrV) && "The typestate *must* have changed.");
+      assert(!PrevV.hasSameState(CurrV) && "The state should have changed.");
       // We may not have transitioned to 'release' if we hit an error.
       // This case is handled elsewhere.
       if (CurrV.getKind() == RefVal::Released) {
@@ -1939,7 +2004,7 @@
 
       if (GCEnabled) {
         // Determine if the object's reference count was pushed to zero.
-        assert(!(PrevV == CurrV) && "The typestate *must* have changed.");
+        assert(!PrevV.hasSameState(CurrV) && "The state should have changed.");
 
         os << "In GC mode a call to '" << *FD
         <<  "' decrements an object's retain count and registers the "
@@ -1964,7 +2029,7 @@
     }
 
     // Determine if the typestate has changed.
-    if (!(PrevV == CurrV))
+    if (!PrevV.hasSameState(CurrV))
       switch (CurrV.getKind()) {
         case RefVal::Owned:
         case RefVal::NotOwned:
@@ -1972,7 +2037,7 @@
           if (PrevV.getCount() == CurrV.getCount()) {
             // Did an autorelease message get sent?
             if (PrevV.getAutoreleaseCount() == CurrV.getAutoreleaseCount())
-              return 0;
+              return nullptr;
 
             assert(PrevV.getAutoreleaseCount() < CurrV.getAutoreleaseCount());
             os << "Object autoreleased";
@@ -2002,7 +2067,7 @@
         case RefVal::ReturnedOwned:
           // Autoreleases can be applied after marking a node ReturnedOwned.
           if (CurrV.getAutoreleaseCount())
-            return NULL;
+            return nullptr;
 
           os << "Object returned to caller as an owning reference (single "
                 "retain count transferred to caller)";
@@ -2013,7 +2078,7 @@
           break;
 
         default:
-          return NULL;
+          return nullptr;
       }
 
     // Emit any remaining diagnostics for the argument effects (if any).
@@ -2038,7 +2103,7 @@
   } while (0);
 
   if (os.str().empty())
-    return 0; // We have nothing to say!
+    return nullptr; // We have nothing to say!
 
   const Stmt *S = N->getLocation().castAs<StmtPoint>().getStmt();
   PathDiagnosticLocation Pos(S, BRC.getSourceManager(),
@@ -2078,12 +2143,12 @@
                   SymbolRef Sym) {
   const ExplodedNode *AllocationNode = N;
   const ExplodedNode *AllocationNodeInCurrentContext = N;
-  const MemRegion* FirstBinding = 0;
+  const MemRegion *FirstBinding = nullptr;
   const LocationContext *LeakContext = N->getLocationContext();
 
   // The location context of the init method called on the leaked object, if
   // available.
-  const LocationContext *InitMethodContext = 0;
+  const LocationContext *InitMethodContext = nullptr;
 
   while (N) {
     ProgramStateRef St = N->getState();
@@ -2127,12 +2192,12 @@
         }
       }
 
-    N = N->pred_empty() ? NULL : *(N->pred_begin());
+    N = N->pred_empty() ? nullptr : *(N->pred_begin());
   }
 
   // If we are reporting a leak of the object that was allocated with alloc,
   // mark its init method as interesting.
-  const LocationContext *InterestingMethodContext = 0;
+  const LocationContext *InterestingMethodContext = nullptr;
   if (InitMethodContext) {
     const ProgramPoint AllocPP = AllocationNode->getLocation();
     if (Optional<StmtPoint> SP = AllocPP.getAs<StmtPoint>())
@@ -2145,7 +2210,7 @@
   // do not report the binding.
   assert(N && "Could not find allocation node");
   if (N->getLocationContext() != LeakContext) {
-    FirstBinding = 0;
+    FirstBinding = nullptr;
   }
 
   return AllocationInfo(AllocationNodeInCurrentContext,
@@ -2212,9 +2277,9 @@
     os << (isa<ObjCMethodDecl>(D) ? " is returned from a method "
                                   : " is returned from a function ");
     
-    if (D->getAttr<CFReturnsNotRetainedAttr>())
+    if (D->hasAttr<CFReturnsNotRetainedAttr>())
       os << "that is annotated as CF_RETURNS_NOT_RETAINED";
-    else if (D->getAttr<NSReturnsNotRetainedAttr>())
+    else if (D->hasAttr<NSReturnsNotRetainedAttr>())
       os << "that is annotated as NS_RETURNS_NOT_RETAINED";
     else {
       if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
@@ -2262,7 +2327,7 @@
   // Note that this is *not* the trimmed graph; we are guaranteed, however,
   // that all ancestor nodes that represent the allocation site have the
   // same SourceLocation.
-  const ExplodedNode *AllocNode = 0;
+  const ExplodedNode *AllocNode = nullptr;
 
   const SourceManager& SMgr = Ctx.getSourceManager();
 
@@ -2275,14 +2340,27 @@
 
   // Get the SourceLocation for the allocation site.
   // FIXME: This will crash the analyzer if an allocation comes from an
-  // implicit call. (Currently there are no such allocations in Cocoa, though.)
-  const Stmt *AllocStmt;
+  // implicit call (ex: a destructor call).
+  // (Currently there are no such allocations in Cocoa, though.)
+  const Stmt *AllocStmt = 0;
   ProgramPoint P = AllocNode->getLocation();
   if (Optional<CallExitEnd> Exit = P.getAs<CallExitEnd>())
     AllocStmt = Exit->getCalleeContext()->getCallSite();
-  else
-    AllocStmt = P.castAs<PostStmt>().getStmt();
-  assert(AllocStmt && "All allocations must come from explicit calls");
+  else {
+    // We are going to get a BlockEdge when the leak and allocation happen in
+    // different, non-nested frames (contexts). For example, the case where an
+    // allocation happens in a block that captures a reference to it and
+    // that reference is overwritten/dropped by another call to the block.
+    if (Optional<BlockEdge> Edge = P.getAs<BlockEdge>()) {
+      if (Optional<CFGStmt> St = Edge->getDst()->front().getAs<CFGStmt>()) {
+        AllocStmt = St->getStmt();
+      }
+    }
+    else {
+      AllocStmt = P.castAs<PostStmt>().getStmt();
+    }
+  }
+  assert(AllocStmt && "Cannot find allocation statement");
 
   PathDiagnosticLocation AllocLocation =
     PathDiagnosticLocation::createBegin(AllocStmt, SMgr,
@@ -2328,24 +2406,25 @@
                     check::PostStmt<ObjCArrayLiteral>,
                     check::PostStmt<ObjCDictionaryLiteral>,
                     check::PostStmt<ObjCBoxedExpr>,
+                    check::PostStmt<ObjCIvarRefExpr>,
                     check::PostCall,
                     check::PreStmt<ReturnStmt>,
                     check::RegionChanges,
                     eval::Assume,
                     eval::Call > {
-  mutable OwningPtr<CFRefBug> useAfterRelease, releaseNotOwned;
-  mutable OwningPtr<CFRefBug> deallocGC, deallocNotOwned;
-  mutable OwningPtr<CFRefBug> overAutorelease, returnNotOwnedForOwned;
-  mutable OwningPtr<CFRefBug> leakWithinFunction, leakAtReturn;
-  mutable OwningPtr<CFRefBug> leakWithinFunctionGC, leakAtReturnGC;
+  mutable std::unique_ptr<CFRefBug> useAfterRelease, releaseNotOwned;
+  mutable std::unique_ptr<CFRefBug> deallocGC, deallocNotOwned;
+  mutable std::unique_ptr<CFRefBug> overAutorelease, returnNotOwnedForOwned;
+  mutable std::unique_ptr<CFRefBug> leakWithinFunction, leakAtReturn;
+  mutable std::unique_ptr<CFRefBug> leakWithinFunctionGC, leakAtReturnGC;
 
-  typedef llvm::DenseMap<SymbolRef, const SimpleProgramPointTag *> SymbolTagMap;
+  typedef llvm::DenseMap<SymbolRef, const CheckerProgramPointTag *> SymbolTagMap;
 
   // This map is only used to ensure proper deletion of any allocated tags.
   mutable SymbolTagMap DeadSymbolTags;
 
-  mutable OwningPtr<RetainSummaryManager> Summaries;
-  mutable OwningPtr<RetainSummaryManager> SummariesGC;
+  mutable std::unique_ptr<RetainSummaryManager> Summaries;
+  mutable std::unique_ptr<RetainSummaryManager> SummariesGC;
   mutable SummaryLogTy SummaryLog;
   mutable bool ShouldResetSummaryLog;
 
@@ -2402,17 +2481,18 @@
                                      bool GCEnabled) const {
     if (GCEnabled) {
       if (!leakWithinFunctionGC)
-        leakWithinFunctionGC.reset(new Leak("Leak of object when using "
-                                             "garbage collection"));
+        leakWithinFunctionGC.reset(new Leak(this, "Leak of object when using "
+                                                  "garbage collection"));
       return leakWithinFunctionGC.get();
     } else {
       if (!leakWithinFunction) {
         if (LOpts.getGC() == LangOptions::HybridGC) {
-          leakWithinFunction.reset(new Leak("Leak of object when not using "
+          leakWithinFunction.reset(new Leak(this,
+                                            "Leak of object when not using "
                                             "garbage collection (GC) in "
                                             "dual GC/non-GC code"));
         } else {
-          leakWithinFunction.reset(new Leak("Leak"));
+          leakWithinFunction.reset(new Leak(this, "Leak"));
         }
       }
       return leakWithinFunction.get();
@@ -2422,17 +2502,19 @@
   CFRefBug *getLeakAtReturnBug(const LangOptions &LOpts, bool GCEnabled) const {
     if (GCEnabled) {
       if (!leakAtReturnGC)
-        leakAtReturnGC.reset(new Leak("Leak of returned object when using "
+        leakAtReturnGC.reset(new Leak(this,
+                                      "Leak of returned object when using "
                                       "garbage collection"));
       return leakAtReturnGC.get();
     } else {
       if (!leakAtReturn) {
         if (LOpts.getGC() == LangOptions::HybridGC) {
-          leakAtReturn.reset(new Leak("Leak of returned object when not using "
+          leakAtReturn.reset(new Leak(this,
+                                      "Leak of returned object when not using "
                                       "garbage collection (GC) in dual "
                                       "GC/non-GC code"));
         } else {
-          leakAtReturn.reset(new Leak("Leak of returned object"));
+          leakAtReturn.reset(new Leak(this, "Leak of returned object"));
         }
       }
       return leakAtReturn.get();
@@ -2464,7 +2546,7 @@
   }
 
   void printState(raw_ostream &Out, ProgramStateRef State,
-                  const char *NL, const char *Sep) const;
+                  const char *NL, const char *Sep) const override;
 
   void checkBind(SVal loc, SVal val, const Stmt *S, CheckerContext &C) const;
   void checkPostStmt(const BlockExpr *BE, CheckerContext &C) const;
@@ -2474,6 +2556,8 @@
   void checkPostStmt(const ObjCDictionaryLiteral *DL, CheckerContext &C) const;
   void checkPostStmt(const ObjCBoxedExpr *BE, CheckerContext &C) const;
 
+  void checkPostStmt(const ObjCIvarRefExpr *IRE, CheckerContext &C) const;
+
   void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
                       
   void checkSummary(const RetainSummary &Summ, const CallEvent &Call,
@@ -2531,7 +2615,7 @@
   ExplodedNode *processLeaks(ProgramStateRef state,
                              SmallVectorImpl<SymbolRef> &Leaked,
                              CheckerContext &Ctx,
-                             ExplodedNode *Pred = 0) const;
+                             ExplodedNode *Pred = nullptr) const;
 };
 } // end anonymous namespace
 
@@ -2542,7 +2626,7 @@
   StopTrackingCallback(ProgramStateRef st) : state(st) {}
   ProgramStateRef getState() const { return state; }
 
-  bool VisitSymbol(SymbolRef sym) {
+  bool VisitSymbol(SymbolRef sym) override {
     state = state->remove<RefBindings>(sym);
     return true;
   }
@@ -2691,6 +2775,20 @@
   C.addTransition(State);
 }
 
+void RetainCountChecker::checkPostStmt(const ObjCIvarRefExpr *IRE,
+                                       CheckerContext &C) const {
+  ProgramStateRef State = C.getState();
+  // If an instance variable was previously accessed through a property,
+  // it may have a synthesized refcount of +0. Override right now that we're
+  // doing direct access.
+  if (Optional<Loc> IVarLoc = C.getSVal(IRE).getAs<Loc>())
+    if (SymbolRef Sym = State->getSVal(*IVarLoc).getAsSymbol())
+      if (const RefVal *RV = getRefBinding(State, Sym))
+        if (RV->isOverridable())
+          State = removeRefBinding(State, Sym);
+  C.addTransition(State);
+}
+
 void RetainCountChecker::checkPostCall(const CallEvent &Call,
                                        CheckerContext &C) const {
   RetainSummaryManager &Summaries = getSummaryManager(C);
@@ -2731,6 +2829,16 @@
   return RetTy;
 }
 
+static bool wasSynthesizedProperty(const ObjCMethodCall *Call,
+                                   ExplodedNode *N) {
+  if (!Call || !Call->getDecl()->isPropertyAccessor())
+    return false;
+
+  CallExitEnd PP = N->getLocation().castAs<CallExitEnd>();
+  const StackFrameContext *Frame = PP.getCalleeContext();
+  return Frame->getAnalysisDeclContext()->isBodyAutosynthesized();
+}
+
 // We don't always get the exact modeling of the function with regards to the
 // retain count checker even when the function is inlined. For example, we need
 // to stop tracking the symbols which were marked with StopTrackingHard.
@@ -2765,6 +2873,19 @@
     SymbolRef Sym = CallOrMsg.getReturnValue().getAsSymbol();
     if (Sym)
       state = removeRefBinding(state, Sym);
+  } else if (RE.getKind() == RetEffect::NotOwnedSymbol) {
+    if (wasSynthesizedProperty(MsgInvocation, C.getPredecessor())) {
+      // Believe the summary if we synthesized the body of a property getter
+      // and the return value is currently untracked. If the corresponding
+      // instance variable is later accessed directly, however, we're going to
+      // want to override this state, so that the owning object can perform
+      // reference counting operations on its own ivars.
+      SymbolRef Sym = CallOrMsg.getReturnValue().getAsSymbol();
+      if (Sym && !getRefBinding(state, Sym))
+        state = setRefBinding(state, Sym,
+                              RefVal::makeOverridableNotOwned(RE.getObjKind(),
+                                                              Sym->getType()));
+    }
   }
   
   C.addTransition(state);
@@ -2778,7 +2899,7 @@
   // Evaluate the effect of the arguments.
   RefVal::Kind hasErr = (RefVal::Kind) 0;
   SourceRange ErrorRange;
-  SymbolRef ErrorSym = 0;
+  SymbolRef ErrorSym = nullptr;
 
   for (unsigned idx = 0, e = CallOrMsg.getNumArgs(); idx != e; ++idx) {
     SVal V = CallOrMsg.getArgSVal(idx);
@@ -2857,7 +2978,6 @@
     }
 
     case RetEffect::GCNotOwnedSymbol:
-    case RetEffect::ARCNotOwnedSymbol:
     case RetEffect::NotOwnedSymbol: {
       const Expr *Ex = CallOrMsg.getOriginExpr();
       SymbolRef Sym = CallOrMsg.getReturnValue().getAsSymbol();
@@ -3053,22 +3173,22 @@
       llvm_unreachable("Unhandled error.");
     case RefVal::ErrorUseAfterRelease:
       if (!useAfterRelease)
-        useAfterRelease.reset(new UseAfterRelease());
+        useAfterRelease.reset(new UseAfterRelease(this));
       BT = &*useAfterRelease;
       break;
     case RefVal::ErrorReleaseNotOwned:
       if (!releaseNotOwned)
-        releaseNotOwned.reset(new BadRelease());
+        releaseNotOwned.reset(new BadRelease(this));
       BT = &*releaseNotOwned;
       break;
     case RefVal::ErrorDeallocGC:
       if (!deallocGC)
-        deallocGC.reset(new DeallocGC());
+        deallocGC.reset(new DeallocGC(this));
       BT = &*deallocGC;
       break;
     case RefVal::ErrorDeallocNotOwned:
       if (!deallocNotOwned)
-        deallocNotOwned.reset(new DeallocNotOwned());
+        deallocNotOwned.reset(new DeallocNotOwned(this));
       BT = &*deallocNotOwned;
       break;
   }
@@ -3135,7 +3255,7 @@
   if (RetVal.isUnknown()) {
     // If the receiver is unknown, conjure a return value.
     SValBuilder &SVB = C.getSValBuilder();
-    RetVal = SVB.conjureSymbolVal(0, CE, LCtx, ResultTy, C.blockCount());
+    RetVal = SVB.conjureSymbolVal(nullptr, CE, LCtx, ResultTy, C.blockCount());
   }
   state = state->BindExpr(CE, LCtx, RetVal, false);
 
@@ -3144,7 +3264,7 @@
   if (const MemRegion *ArgRegion = RetVal.getAsRegion()) {
     // Save the refcount status of the argument.
     SymbolRef Sym = RetVal.getAsLocSymbol();
-    const RefVal *Binding = 0;
+    const RefVal *Binding = nullptr;
     if (Sym)
       Binding = getRefBinding(state, Sym);
 
@@ -3232,8 +3352,7 @@
     return;
 
   // Update the autorelease counts.
-  static SimpleProgramPointTag
-         AutoreleaseTag("RetainCountChecker : Autorelease");
+  static CheckerProgramPointTag AutoreleaseTag(this, "Autorelease");
   state = handleAutoreleaseCounts(state, Pred, &AutoreleaseTag, C, Sym, X);
 
   // Did we cache out?
@@ -3294,8 +3413,7 @@
         // Generate an error node.
         state = setRefBinding(state, Sym, X);
 
-        static SimpleProgramPointTag
-               ReturnOwnLeakTag("RetainCountChecker : ReturnsOwnLeak");
+        static CheckerProgramPointTag ReturnOwnLeakTag(this, "ReturnsOwnLeak");
         ExplodedNode *N = C.addTransition(state, Pred, &ReturnOwnLeakTag);
         if (N) {
           const LangOptions &LOpts = C.getASTContext().getLangOpts();
@@ -3315,12 +3433,12 @@
       // owned object.
       state = setRefBinding(state, Sym, X ^ RefVal::ErrorReturnedNotOwned);
 
-      static SimpleProgramPointTag
-             ReturnNotOwnedTag("RetainCountChecker : ReturnNotOwnedForOwned");
+      static CheckerProgramPointTag ReturnNotOwnedTag(this, 
+                                                      "ReturnNotOwnedForOwned");
       ExplodedNode *N = C.addTransition(state, Pred, &ReturnNotOwnedTag);
       if (N) {
         if (!returnNotOwnedForOwned)
-          returnNotOwnedForOwned.reset(new ReturnedNotOwnedForOwned());
+          returnNotOwnedForOwned.reset(new ReturnedNotOwnedForOwned(this));
 
         CFRefReport *report =
             new CFRefReport(*returnNotOwnedForOwned,
@@ -3375,7 +3493,7 @@
   // false positives.
   if (const VarRegion *LVR = dyn_cast_or_null<VarRegion>(loc.getAsRegion())) {
     const VarDecl *VD = LVR->getDecl();
-    if (VD->getAttr<CleanupAttr>()) {
+    if (VD->hasAttr<CleanupAttr>()) {
       escapes = true;
     }
   }
@@ -3508,7 +3626,7 @@
     os << "has a +" << V.getCount() << " retain count";
 
     if (!overAutorelease)
-      overAutorelease.reset(new OverAutorelease());
+      overAutorelease.reset(new OverAutorelease(this));
 
     const LangOptions &LOpts = Ctx.getASTContext().getLangOpts();
     CFRefReport *report =
@@ -3517,7 +3635,7 @@
     Ctx.emitReport(report);
   }
 
-  return 0;
+  return nullptr;
 }
 
 ProgramStateRef 
@@ -3578,7 +3696,7 @@
   }
 
   for (RefBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
-    state = handleAutoreleaseCounts(state, Pred, /*Tag=*/0, Ctx,
+    state = handleAutoreleaseCounts(state, Pred, /*Tag=*/nullptr, Ctx,
                                     I->first, I->second);
     if (!state)
       return;
@@ -3602,13 +3720,13 @@
 
 const ProgramPointTag *
 RetainCountChecker::getDeadSymbolTag(SymbolRef sym) const {
-  const SimpleProgramPointTag *&tag = DeadSymbolTags[sym];
+  const CheckerProgramPointTag *&tag = DeadSymbolTags[sym];
   if (!tag) {
     SmallString<64> buf;
     llvm::raw_svector_ostream out(buf);
-    out << "RetainCountChecker : Dead Symbol : ";
+    out << "Dead Symbol : ";
     sym->dumpToStream(out);
-    tag = new SimpleProgramPointTag(out.str());
+    tag = new CheckerProgramPointTag(this, out.str());
   }
   return tag;  
 }
diff --git a/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp b/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp
index fe253b7..b1cde6b 100644
--- a/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp
@@ -25,7 +25,8 @@
 namespace {
 class ReturnPointerRangeChecker : 
     public Checker< check::PreStmt<ReturnStmt> > {
-  mutable OwningPtr<BuiltinBug> BT;
+  mutable std::unique_ptr<BuiltinBug> BT;
+
 public:
     void checkPreStmt(const ReturnStmt *RS, CheckerContext &C) const;
 };
@@ -69,9 +70,10 @@
     // FIXME: This bug correspond to CWE-466.  Eventually we should have bug
     // types explicitly reference such exploit categories (when applicable).
     if (!BT)
-      BT.reset(new BuiltinBug("Return of pointer value outside of expected range",
-           "Returned pointer value points outside the original object "
-           "(potential buffer overflow)"));
+      BT.reset(new BuiltinBug(
+          this, "Return of pointer value outside of expected range",
+          "Returned pointer value points outside the original object "
+          "(potential buffer overflow)"));
 
     // FIXME: It would be nice to eventually make this diagnostic more clear,
     // e.g., by referencing the original declaration or by saying *why* this
diff --git a/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp b/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp
index ed96c40..6622313 100644
--- a/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp
@@ -25,8 +25,8 @@
 
 namespace {
 class ReturnUndefChecker : public Checker< check::PreStmt<ReturnStmt> > {
-  mutable OwningPtr<BuiltinBug> BT_Undef;
-  mutable OwningPtr<BuiltinBug> BT_NullReference;
+  mutable std::unique_ptr<BuiltinBug> BT_Undef;
+  mutable std::unique_ptr<BuiltinBug> BT_NullReference;
 
   void emitUndef(CheckerContext &C, const Expr *RetE) const;
   void checkReference(CheckerContext &C, const Expr *RetE,
@@ -79,7 +79,7 @@
 }
 
 static void emitBug(CheckerContext &C, BuiltinBug &BT, const Expr *RetE,
-                    const Expr *TrackingE = 0) {
+                    const Expr *TrackingE = nullptr) {
   ExplodedNode *N = C.generateSink();
   if (!N)
     return;
@@ -94,16 +94,16 @@
 
 void ReturnUndefChecker::emitUndef(CheckerContext &C, const Expr *RetE) const {
   if (!BT_Undef)
-    BT_Undef.reset(new BuiltinBug("Garbage return value",
-                                  "Undefined or garbage value "
-                                    "returned to caller"));
+    BT_Undef.reset(
+        new BuiltinBug(this, "Garbage return value",
+                       "Undefined or garbage value returned to caller"));
   emitBug(C, *BT_Undef, RetE);
 }
 
 void ReturnUndefChecker::checkReference(CheckerContext &C, const Expr *RetE,
                                         DefinedOrUnknownSVal RetVal) const {
   ProgramStateRef StNonNull, StNull;
-  llvm::tie(StNonNull, StNull) = C.getState()->assume(RetVal);
+  std::tie(StNonNull, StNull) = C.getState()->assume(RetVal);
 
   if (StNonNull) {
     // Going forward, assume the location is non-null.
@@ -113,7 +113,7 @@
 
   // The return value is known to be null. Emit a bug report.
   if (!BT_NullReference)
-    BT_NullReference.reset(new BuiltinBug("Returning null reference"));
+    BT_NullReference.reset(new BuiltinBug(this, "Returning null reference"));
 
   emitBug(C, *BT_NullReference, RetE, bugreporter::getDerefExpr(RetE));
 }
diff --git a/lib/StaticAnalyzer/Checkers/SelectorExtras.h b/lib/StaticAnalyzer/Checkers/SelectorExtras.h
new file mode 100644
index 0000000..48d96eb
--- /dev/null
+++ b/lib/StaticAnalyzer/Checkers/SelectorExtras.h
@@ -0,0 +1,68 @@
+//=== SelectorExtras.h - Helpers for checkers using selectors -----*- 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_SA_CHECKERS_SELECTOREXTRAS
+#define LLVM_CLANG_SA_CHECKERS_SELECTOREXTRAS
+
+#include "clang/AST/ASTContext.h"
+#include <cstdarg>
+
+namespace clang {
+namespace ento {
+
+static inline Selector getKeywordSelectorImpl(ASTContext &Ctx,
+                                              const char *First,
+                                              va_list argp) {
+  SmallVector<IdentifierInfo*, 10> II;
+  II.push_back(&Ctx.Idents.get(First));
+
+  while (const char *s = va_arg(argp, const char *))
+    II.push_back(&Ctx.Idents.get(s));
+
+  return Ctx.Selectors.getSelector(II.size(), &II[0]);
+}
+
+static inline Selector getKeywordSelector(ASTContext &Ctx, va_list argp) {
+  const char *First = va_arg(argp, const char *);
+  assert(First && "keyword selectors must have at least one argument");
+  return getKeywordSelectorImpl(Ctx, First, argp);
+}
+
+END_WITH_NULL
+static inline Selector getKeywordSelector(ASTContext &Ctx,
+                                          const char *First, ...) {
+  va_list argp;
+  va_start(argp, First);
+  Selector result = getKeywordSelectorImpl(Ctx, First, argp);
+  va_end(argp);
+  return result;
+}
+
+END_WITH_NULL
+static inline void lazyInitKeywordSelector(Selector &Sel, ASTContext &Ctx,
+                                           const char *First, ...) {
+  if (!Sel.isNull())
+    return;
+  va_list argp;
+  va_start(argp, First);
+  Sel = getKeywordSelectorImpl(Ctx, First, argp);
+  va_end(argp);
+}
+
+static inline void lazyInitNullarySelector(Selector &Sel, ASTContext &Ctx,
+                                           const char *Name) {
+  if (!Sel.isNull())
+    return;
+  Sel = GetNullarySelector(Name, Ctx);
+}
+
+} // end namespace ento
+} // end namespace clang
+
+#endif
diff --git a/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp b/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp
index 9ca0ab5..3e9b57b 100644
--- a/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp
@@ -54,8 +54,8 @@
 
   mutable IdentifierInfo *IIfopen, *IIfclose;
 
-  OwningPtr<BugType> DoubleCloseBugType;
-  OwningPtr<BugType> LeakBugType;
+  std::unique_ptr<BugType> DoubleCloseBugType;
+  std::unique_ptr<BugType> LeakBugType;
 
   void initIdentifierInfo(ASTContext &Ctx) const;
 
@@ -99,21 +99,21 @@
   StopTrackingCallback(ProgramStateRef st) : state(st) {}
   ProgramStateRef getState() const { return state; }
 
-  bool VisitSymbol(SymbolRef sym) {
+  bool VisitSymbol(SymbolRef sym) override {
     state = state->remove<StreamMap>(sym);
     return true;
   }
 };
 } // end anonymous namespace
 
-
-SimpleStreamChecker::SimpleStreamChecker() : IIfopen(0), IIfclose(0) {
+SimpleStreamChecker::SimpleStreamChecker()
+    : IIfopen(nullptr), IIfclose(nullptr) {
   // Initialize the bug types.
-  DoubleCloseBugType.reset(new BugType("Double fclose",
-                                       "Unix Stream API Error"));
+  DoubleCloseBugType.reset(
+      new BugType(this, "Double fclose", "Unix Stream API Error"));
 
-  LeakBugType.reset(new BugType("Resource Leak",
-                                "Unix Stream API Error"));
+  LeakBugType.reset(
+      new BugType(this, "Resource Leak", "Unix Stream API Error"));
   // Sinks are higher importance bugs as well as calls to assert() or exit(0).
   LeakBugType->setSuppressOnSink(true);
 }
diff --git a/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp b/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
index 4fd778e..327a9e0 100644
--- a/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
@@ -28,8 +28,8 @@
 namespace {
 class StackAddrEscapeChecker : public Checker< check::PreStmt<ReturnStmt>,
                                                check::EndFunction > {
-  mutable OwningPtr<BuiltinBug> BT_stackleak;
-  mutable OwningPtr<BuiltinBug> BT_returnstack;
+  mutable std::unique_ptr<BuiltinBug> BT_stackleak;
+  mutable std::unique_ptr<BuiltinBug> BT_returnstack;
 
 public:
   void checkPreStmt(const ReturnStmt *RS, CheckerContext &C) const;
@@ -100,8 +100,8 @@
     return;
 
   if (!BT_returnstack)
-   BT_returnstack.reset(
-                 new BuiltinBug("Return of address to stack-allocated memory"));
+    BT_returnstack.reset(
+        new BuiltinBug(this, "Return of address to stack-allocated memory"));
 
   // Generate a report for this bug.
   SmallString<512> buf;
@@ -177,8 +177,8 @@
     {}
     
     bool HandleBinding(StoreManager &SMgr, Store store,
-                       const MemRegion *region, SVal val) {
-      
+                       const MemRegion *region, SVal val) override {
+
       if (!isa<GlobalsSpaceRegion>(region->getMemorySpace()))
         return true;
       
@@ -217,11 +217,11 @@
 
   if (!BT_stackleak)
     BT_stackleak.reset(
-      new BuiltinBug("Stack address stored into global variable",
-                     "Stack address was saved into a global variable. "
-                     "This is dangerous because the address will become "
-                     "invalid after returning from the function"));
-  
+        new BuiltinBug(this, "Stack address stored into global variable",
+                       "Stack address was saved into a global variable. "
+                       "This is dangerous because the address will become "
+                       "invalid after returning from the function"));
+
   for (unsigned i = 0, e = cb.V.size(); i != e; ++i) {
     // Generate a report for this bug.
     SmallString<512> buf;
diff --git a/lib/StaticAnalyzer/Checkers/StreamChecker.cpp b/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
index ffdf2d5..894765a 100644
--- a/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -62,14 +62,16 @@
                  *II_fwrite, 
                  *II_fseek, *II_ftell, *II_rewind, *II_fgetpos, *II_fsetpos,  
                  *II_clearerr, *II_feof, *II_ferror, *II_fileno;
-  mutable OwningPtr<BuiltinBug> BT_nullfp, BT_illegalwhence,
-                                      BT_doubleclose, BT_ResourceLeak;
+  mutable std::unique_ptr<BuiltinBug> BT_nullfp, BT_illegalwhence,
+      BT_doubleclose, BT_ResourceLeak;
 
 public:
   StreamChecker() 
-    : II_fopen(0), II_tmpfile(0) ,II_fclose(0), II_fread(0), II_fwrite(0), 
-      II_fseek(0), II_ftell(0), II_rewind(0), II_fgetpos(0), II_fsetpos(0), 
-      II_clearerr(0), II_feof(0), II_ferror(0), II_fileno(0) {}
+    : II_fopen(nullptr), II_tmpfile(nullptr), II_fclose(nullptr),
+      II_fread(nullptr), II_fwrite(nullptr), II_fseek(nullptr),
+      II_ftell(nullptr), II_rewind(nullptr), II_fgetpos(nullptr),
+      II_fsetpos(nullptr), II_clearerr(nullptr), II_feof(nullptr),
+      II_ferror(nullptr), II_fileno(nullptr) {}
 
   bool evalCall(const CallExpr *CE, CheckerContext &C) const;
   void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
@@ -210,7 +212,8 @@
   ProgramStateRef state = C.getState();
   SValBuilder &svalBuilder = C.getSValBuilder();
   const LocationContext *LCtx = C.getPredecessor()->getLocationContext();
-  DefinedSVal RetVal = svalBuilder.conjureSymbolVal(0, CE, LCtx, C.blockCount())
+  DefinedSVal RetVal = svalBuilder.conjureSymbolVal(nullptr, CE, LCtx,
+                                                    C.blockCount())
       .castAs<DefinedSVal>();
   state = state->BindExpr(CE, C.getLocationContext(), RetVal);
   
@@ -218,7 +221,7 @@
   // Bifurcate the state into two: one with a valid FILE* pointer, the other
   // with a NULL.
   ProgramStateRef stateNotNull, stateNull;
-  llvm::tie(stateNotNull, stateNull) = CM.assumeDual(state, RetVal);
+  std::tie(stateNotNull, stateNull) = CM.assumeDual(state, RetVal);
   
   if (SymbolRef Sym = RetVal.getAsSymbol()) {
     // if RetVal is not NULL, set the symbol's state to Opened.
@@ -270,9 +273,10 @@
 
   if (ExplodedNode *N = C.addTransition(state)) {
     if (!BT_illegalwhence)
-      BT_illegalwhence.reset(new BuiltinBug("Illegal whence argument",
-					"The whence argument to fseek() should be "
-					"SEEK_SET, SEEK_END, or SEEK_CUR."));
+      BT_illegalwhence.reset(
+          new BuiltinBug(this, "Illegal whence argument",
+                         "The whence argument to fseek() should be "
+                         "SEEK_SET, SEEK_END, or SEEK_CUR."));
     BugReport *R = new BugReport(*BT_illegalwhence, 
 				 BT_illegalwhence->getDescription(), N);
     C.emitReport(R);
@@ -339,21 +343,21 @@
                                     CheckerContext &C) const {
   Optional<DefinedSVal> DV = SV.getAs<DefinedSVal>();
   if (!DV)
-    return 0;
+    return nullptr;
 
   ConstraintManager &CM = C.getConstraintManager();
   ProgramStateRef stateNotNull, stateNull;
-  llvm::tie(stateNotNull, stateNull) = CM.assumeDual(state, *DV);
+  std::tie(stateNotNull, stateNull) = CM.assumeDual(state, *DV);
 
   if (!stateNotNull && stateNull) {
     if (ExplodedNode *N = C.generateSink(stateNull)) {
       if (!BT_nullfp)
-        BT_nullfp.reset(new BuiltinBug("NULL stream pointer",
-                                     "Stream pointer might be NULL."));
+        BT_nullfp.reset(new BuiltinBug(this, "NULL stream pointer",
+                                       "Stream pointer might be NULL."));
       BugReport *R =new BugReport(*BT_nullfp, BT_nullfp->getDescription(), N);
       C.emitReport(R);
     }
-    return 0;
+    return nullptr;
   }
   return stateNotNull;
 }
@@ -378,14 +382,14 @@
     ExplodedNode *N = C.generateSink();
     if (N) {
       if (!BT_doubleclose)
-        BT_doubleclose.reset(new BuiltinBug("Double fclose",
-                                        "Try to close a file Descriptor already"
-                                        " closed. Cause undefined behaviour."));
+        BT_doubleclose.reset(new BuiltinBug(
+            this, "Double fclose", "Try to close a file Descriptor already"
+                                   " closed. Cause undefined behaviour."));
       BugReport *R = new BugReport(*BT_doubleclose,
                                    BT_doubleclose->getDescription(), N);
       C.emitReport(R);
     }
-    return NULL;
+    return nullptr;
   }
   
   // Close the File Descriptor.
@@ -407,8 +411,9 @@
       ExplodedNode *N = C.generateSink();
       if (N) {
         if (!BT_ResourceLeak)
-          BT_ResourceLeak.reset(new BuiltinBug("Resource Leak", 
-                         "Opened File never closed. Potential Resource leak."));
+          BT_ResourceLeak.reset(new BuiltinBug(
+              this, "Resource Leak",
+              "Opened File never closed. Potential Resource leak."));
         BugReport *R = new BugReport(*BT_ResourceLeak, 
                                      BT_ResourceLeak->getDescription(), N);
         C.emitReport(R);
diff --git a/lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp b/lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp
index 264f7f9..d33c977 100644
--- a/lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp
@@ -22,7 +22,7 @@
 namespace {
 class TaintTesterChecker : public Checker< check::PostStmt<Expr> > {
 
-  mutable OwningPtr<BugType> BT;
+  mutable std::unique_ptr<BugType> BT;
   void initBugType() const;
 
   /// Given a pointer argument, get the symbol of the value it contains
@@ -38,7 +38,7 @@
 
 inline void TaintTesterChecker::initBugType() const {
   if (!BT)
-    BT.reset(new BugType("Tainted data", "General"));
+    BT.reset(new BugType(this, "Tainted data", "General"));
 }
 
 void TaintTesterChecker::checkPostStmt(const Expr *E,
diff --git a/lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp b/lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp
new file mode 100644
index 0000000..dad5c0d
--- /dev/null
+++ b/lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp
@@ -0,0 +1,264 @@
+//== TestAfterDivZeroChecker.cpp - Test after division by zero checker --*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This defines TestAfterDivZeroChecker, a builtin check that performs checks
+//  for division by zero where the division occurs before comparison with zero.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ClangSACheckers.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "llvm/ADT/FoldingSet.h"
+
+using namespace clang;
+using namespace ento;
+
+namespace {
+
+class ZeroState {
+private:
+  SymbolRef ZeroSymbol;
+  unsigned BlockID;
+  const StackFrameContext *SFC;
+
+public:
+  ZeroState(SymbolRef S, unsigned B, const StackFrameContext *SFC)
+      : ZeroSymbol(S), BlockID(B), SFC(SFC) {}
+
+  const StackFrameContext *getStackFrameContext() const { return SFC; }
+
+  bool operator==(const ZeroState &X) const {
+    return BlockID == X.BlockID && SFC == X.SFC && ZeroSymbol == X.ZeroSymbol;
+  }
+
+  bool operator<(const ZeroState &X) const {
+    if (BlockID != X.BlockID)
+      return BlockID < X.BlockID;
+    if (SFC != X.SFC)
+      return SFC < X.SFC;
+    return ZeroSymbol < X.ZeroSymbol;
+  }
+
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    ID.AddInteger(BlockID);
+    ID.AddPointer(SFC);
+    ID.AddPointer(ZeroSymbol);
+  }
+};
+
+class DivisionBRVisitor : public BugReporterVisitorImpl<DivisionBRVisitor> {
+private:
+  SymbolRef ZeroSymbol;
+  const StackFrameContext *SFC;
+  bool Satisfied;
+
+public:
+  DivisionBRVisitor(SymbolRef ZeroSymbol, const StackFrameContext *SFC)
+      : ZeroSymbol(ZeroSymbol), SFC(SFC), Satisfied(false) {}
+
+  void Profile(llvm::FoldingSetNodeID &ID) const override {
+    ID.Add(ZeroSymbol);
+    ID.Add(SFC);
+  }
+
+  PathDiagnosticPiece *VisitNode(const ExplodedNode *Succ,
+                                 const ExplodedNode *Pred,
+                                 BugReporterContext &BRC,
+                                 BugReport &BR) override;
+};
+
+class TestAfterDivZeroChecker
+    : public Checker<check::PreStmt<BinaryOperator>, check::BranchCondition,
+                     check::EndFunction> {
+  mutable std::unique_ptr<BuiltinBug> DivZeroBug;
+  void reportBug(SVal Val, CheckerContext &C) const;
+
+public:
+  void checkPreStmt(const BinaryOperator *B, CheckerContext &C) const;
+  void checkBranchCondition(const Stmt *Condition, CheckerContext &C) const;
+  void checkEndFunction(CheckerContext &C) const;
+  void setDivZeroMap(SVal Var, CheckerContext &C) const;
+  bool hasDivZeroMap(SVal Var, const CheckerContext &C) const;
+  bool isZero(SVal S, CheckerContext &C) const;
+};
+} // end anonymous namespace
+
+REGISTER_SET_WITH_PROGRAMSTATE(DivZeroMap, ZeroState)
+
+PathDiagnosticPiece *DivisionBRVisitor::VisitNode(const ExplodedNode *Succ,
+                                                  const ExplodedNode *Pred,
+                                                  BugReporterContext &BRC,
+                                                  BugReport &BR) {
+  if (Satisfied)
+    return nullptr;
+
+  const Expr *E = nullptr;
+
+  if (Optional<PostStmt> P = Succ->getLocationAs<PostStmt>())
+    if (const BinaryOperator *BO = P->getStmtAs<BinaryOperator>()) {
+      BinaryOperator::Opcode Op = BO->getOpcode();
+      if (Op == BO_Div || Op == BO_Rem || Op == BO_DivAssign ||
+          Op == BO_RemAssign) {
+        E = BO->getRHS();
+      }
+    }
+
+  if (!E)
+    return nullptr;
+
+  ProgramStateRef State = Succ->getState();
+  SVal S = State->getSVal(E, Succ->getLocationContext());
+  if (ZeroSymbol == S.getAsSymbol() && SFC == Succ->getStackFrame()) {
+    Satisfied = true;
+
+    // Construct a new PathDiagnosticPiece.
+    ProgramPoint P = Succ->getLocation();
+    PathDiagnosticLocation L =
+        PathDiagnosticLocation::create(P, BRC.getSourceManager());
+
+    if (!L.isValid() || !L.asLocation().isValid())
+      return nullptr;
+
+    return new PathDiagnosticEventPiece(
+        L, "Division with compared value made here");
+  }
+
+  return nullptr;
+}
+
+bool TestAfterDivZeroChecker::isZero(SVal S, CheckerContext &C) const {
+  Optional<DefinedSVal> DSV = S.getAs<DefinedSVal>();
+
+  if (!DSV)
+    return false;
+
+  ConstraintManager &CM = C.getConstraintManager();
+  return !CM.assume(C.getState(), *DSV, true);
+}
+
+void TestAfterDivZeroChecker::setDivZeroMap(SVal Var, CheckerContext &C) const {
+  SymbolRef SR = Var.getAsSymbol();
+  if (!SR)
+    return;
+
+  ProgramStateRef State = C.getState();
+  State =
+      State->add<DivZeroMap>(ZeroState(SR, C.getBlockID(), C.getStackFrame()));
+  C.addTransition(State);
+}
+
+bool TestAfterDivZeroChecker::hasDivZeroMap(SVal Var,
+                                            const CheckerContext &C) const {
+  SymbolRef SR = Var.getAsSymbol();
+  if (!SR)
+    return false;
+
+  ZeroState ZS(SR, C.getBlockID(), C.getStackFrame());
+  return C.getState()->contains<DivZeroMap>(ZS);
+}
+
+void TestAfterDivZeroChecker::reportBug(SVal Val, CheckerContext &C) const {
+  if (ExplodedNode *N = C.generateSink(C.getState())) {
+    if (!DivZeroBug)
+      DivZeroBug.reset(new BuiltinBug(this, "Division by zero"));
+
+    BugReport *R =
+        new BugReport(*DivZeroBug, "Value being compared against zero has "
+                                   "already been used for division",
+                      N);
+
+    R->addVisitor(new DivisionBRVisitor(Val.getAsSymbol(), C.getStackFrame()));
+    C.emitReport(R);
+  }
+}
+
+void TestAfterDivZeroChecker::checkEndFunction(CheckerContext &C) const {
+  ProgramStateRef State = C.getState();
+
+  DivZeroMapTy DivZeroes = State->get<DivZeroMap>();
+  if (DivZeroes.isEmpty())
+    return;
+
+  DivZeroMapTy::Factory &F = State->get_context<DivZeroMap>();
+  for (llvm::ImmutableSet<ZeroState>::iterator I = DivZeroes.begin(),
+                                               E = DivZeroes.end();
+       I != E; ++I) {
+    ZeroState ZS = *I;
+    if (ZS.getStackFrameContext() == C.getStackFrame())
+      DivZeroes = F.remove(DivZeroes, ZS);
+  }
+  C.addTransition(State->set<DivZeroMap>(DivZeroes));
+}
+
+void TestAfterDivZeroChecker::checkPreStmt(const BinaryOperator *B,
+                                           CheckerContext &C) const {
+  BinaryOperator::Opcode Op = B->getOpcode();
+  if (Op == BO_Div || Op == BO_Rem || Op == BO_DivAssign ||
+      Op == BO_RemAssign) {
+    SVal S = C.getSVal(B->getRHS());
+
+    if (!isZero(S, C))
+      setDivZeroMap(S, C);
+  }
+}
+
+void TestAfterDivZeroChecker::checkBranchCondition(const Stmt *Condition,
+                                                   CheckerContext &C) const {
+  if (const BinaryOperator *B = dyn_cast<BinaryOperator>(Condition)) {
+    if (B->isComparisonOp()) {
+      const IntegerLiteral *IntLiteral = dyn_cast<IntegerLiteral>(B->getRHS());
+      bool LRHS = true;
+      if (!IntLiteral) {
+        IntLiteral = dyn_cast<IntegerLiteral>(B->getLHS());
+        LRHS = false;
+      }
+
+      if (!IntLiteral || IntLiteral->getValue() != 0)
+        return;
+
+      SVal Val = C.getSVal(LRHS ? B->getLHS() : B->getRHS());
+      if (hasDivZeroMap(Val, C))
+        reportBug(Val, C);
+    }
+  } else if (const UnaryOperator *U = dyn_cast<UnaryOperator>(Condition)) {
+    if (U->getOpcode() == UO_LNot) {
+      SVal Val;
+      if (const ImplicitCastExpr *I =
+              dyn_cast<ImplicitCastExpr>(U->getSubExpr()))
+        Val = C.getSVal(I->getSubExpr());
+
+      if (hasDivZeroMap(Val, C))
+        reportBug(Val, C);
+      else {
+        Val = C.getSVal(U->getSubExpr());
+        if (hasDivZeroMap(Val, C))
+          reportBug(Val, C);
+      }
+    }
+  } else if (const ImplicitCastExpr *IE =
+                 dyn_cast<ImplicitCastExpr>(Condition)) {
+    SVal Val = C.getSVal(IE->getSubExpr());
+
+    if (hasDivZeroMap(Val, C))
+      reportBug(Val, C);
+    else {
+      SVal Val = C.getSVal(Condition);
+
+      if (hasDivZeroMap(Val, C))
+        reportBug(Val, C);
+    }
+  }
+}
+
+void ento::registerTestAfterDivZeroChecker(CheckerManager &mgr) {
+  mgr.registerChecker<TestAfterDivZeroChecker>();
+}
diff --git a/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp b/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp
index 57c9ed4..d02d2df 100644
--- a/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp
@@ -72,7 +72,7 @@
 void CallDumper::checkPreCall(const CallEvent &Call, CheckerContext &C) const {
   unsigned Indentation = 0;
   for (const LocationContext *LC = C.getLocationContext()->getParent();
-       LC != 0; LC = LC->getParent())
+       LC != nullptr; LC = LC->getParent())
     ++Indentation;
 
   // It is mildly evil to print directly to llvm::outs() rather than emitting
@@ -89,7 +89,7 @@
 
   unsigned Indentation = 0;
   for (const LocationContext *LC = C.getLocationContext()->getParent();
-       LC != 0; LC = LC->getParent())
+       LC != nullptr; LC = LC->getParent())
     ++Indentation;
 
   // It is mildly evil to print directly to llvm::outs() rather than emitting
diff --git a/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp b/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
index 8235e68..fc49a46 100644
--- a/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
@@ -24,7 +24,7 @@
 namespace {
 
 class UndefBranchChecker : public Checker<check::BranchCondition> {
-  mutable OwningPtr<BuiltinBug> BT;
+  mutable std::unique_ptr<BuiltinBug> BT;
 
   struct FindUndefExpr {
     ProgramStateRef St;
@@ -35,7 +35,7 @@
 
     const Expr *FindExpr(const Expr *Ex) {
       if (!MatchesCriteria(Ex))
-        return 0;
+        return nullptr;
 
       for (Stmt::const_child_iterator I = Ex->child_begin(), 
                                       E = Ex->child_end();I!=E;++I)
@@ -67,8 +67,8 @@
     ExplodedNode *N = Ctx.generateSink();
     if (N) {
       if (!BT)
-        BT.reset(
-               new BuiltinBug("Branch condition evaluates to a garbage value"));
+        BT.reset(new BuiltinBug(
+            this, "Branch condition evaluates to a garbage value"));
 
       // What's going on here: we want to highlight the subexpression of the
       // condition that is the most likely source of the "uninitialized
diff --git a/lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp b/lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp
index 93812f7..93687db 100644
--- a/lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp
@@ -27,7 +27,7 @@
 namespace {
 class UndefCapturedBlockVarChecker
   : public Checker< check::PostStmt<BlockExpr> > {
- mutable OwningPtr<BugType> BT;
+  mutable std::unique_ptr<BugType> BT;
 
 public:
   void checkPostStmt(const BlockExpr *BE, CheckerContext &C) const;
@@ -48,7 +48,7 @@
         return BR;
     }
 
-  return NULL;
+  return nullptr;
 }
 
 void
@@ -71,7 +71,7 @@
     const VarRegion *VR = I.getCapturedRegion();
     const VarDecl *VD = VR->getDecl();
 
-    if (VD->getAttr<BlocksAttr>() || !VD->hasLocalStorage())
+    if (VD->hasAttr<BlocksAttr>() || !VD->hasLocalStorage())
       continue;
 
     // Get the VarRegion associated with VD in the local stack frame.
@@ -79,7 +79,8 @@
           state->getSVal(I.getOriginalRegion()).getAs<UndefinedVal>()) {
       if (ExplodedNode *N = C.generateSink()) {
         if (!BT)
-          BT.reset(new BuiltinBug("uninitialized variable captured by block"));
+          BT.reset(
+              new BuiltinBug(this, "uninitialized variable captured by block"));
 
         // Generate a bug report.
         SmallString<128> buf;
diff --git a/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp b/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
index 3f6549d..f3f4dce 100644
--- a/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
@@ -28,8 +28,8 @@
 class UndefResultChecker 
   : public Checker< check::PostStmt<BinaryOperator> > {
 
-  mutable OwningPtr<BugType> BT;
-  
+  mutable std::unique_ptr<BugType> BT;
+
 public:
   void checkPostStmt(const BinaryOperator *B, CheckerContext &C) const;
 };
@@ -55,11 +55,12 @@
       return;
     
     if (!BT)
-      BT.reset(new BuiltinBug("Result of operation is garbage or undefined"));
+      BT.reset(
+          new BuiltinBug(this, "Result of operation is garbage or undefined"));
 
     SmallString<256> sbuf;
     llvm::raw_svector_ostream OS(sbuf);
-    const Expr *Ex = NULL;
+    const Expr *Ex = nullptr;
     bool isLeft = true;
     
     if (state->getSVal(B->getLHS(), LCtx).isUndef()) {
diff --git a/lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp b/lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp
index 5df8846..e952671 100644
--- a/lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp
@@ -25,7 +25,7 @@
 namespace {
 class UndefinedArraySubscriptChecker
   : public Checker< check::PreStmt<ArraySubscriptExpr> > {
-  mutable OwningPtr<BugType> BT;
+  mutable std::unique_ptr<BugType> BT;
 
 public:
   void checkPreStmt(const ArraySubscriptExpr *A, CheckerContext &C) const;
@@ -50,7 +50,7 @@
   if (!N)
     return;
   if (!BT)
-    BT.reset(new BuiltinBug("Array subscript is undefined"));
+    BT.reset(new BuiltinBug(this, "Array subscript is undefined"));
 
   // Generate a report for this bug.
   BugReport *R = new BugReport(*BT, BT->getName(), N);
diff --git a/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp b/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
index 016e3c8..bd4493d 100644
--- a/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
@@ -24,7 +24,7 @@
 namespace {
 class UndefinedAssignmentChecker
   : public Checker<check::Bind> {
-  mutable OwningPtr<BugType> BT;
+  mutable std::unique_ptr<BugType> BT;
 
 public:
   void checkBind(SVal location, SVal val, const Stmt *S,
@@ -54,10 +54,10 @@
   const char *str = "Assigned value is garbage or undefined";
 
   if (!BT)
-    BT.reset(new BuiltinBug(str));
+    BT.reset(new BuiltinBug(this, str));
 
   // Generate a report for this bug.
-  const Expr *ex = 0;
+  const Expr *ex = nullptr;
 
   while (StoreE) {
     if (const BinaryOperator *B = dyn_cast<BinaryOperator>(StoreE)) {
diff --git a/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp b/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
index 4ea07e2..4887d80 100644
--- a/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
@@ -30,7 +30,7 @@
 
 namespace {
 class UnixAPIChecker : public Checker< check::PreStmt<CallExpr> > {
-  mutable OwningPtr<BugType> BT_open, BT_pthreadOnce, BT_mallocZero;
+  mutable std::unique_ptr<BugType> BT_open, BT_pthreadOnce, BT_mallocZero;
   mutable Optional<uint64_t> Val_O_CREAT;
 
 public:
@@ -57,21 +57,15 @@
                             const unsigned numArgs,
                             const unsigned sizeArg,
                             const char *fn) const;
+  void LazyInitialize(std::unique_ptr<BugType> &BT, const char *name) const {
+    if (BT)
+      return;
+    BT.reset(new BugType(this, name, categories::UnixAPI));
+  }
 };
 } //end anonymous namespace
 
 //===----------------------------------------------------------------------===//
-// Utility functions.
-//===----------------------------------------------------------------------===//
-
-static inline void LazyInitialize(OwningPtr<BugType> &BT,
-                                  const char *name) {
-  if (BT)
-    return;
-  BT.reset(new BugType(name, categories::UnixAPI));
-}
-
-//===----------------------------------------------------------------------===//
 // "open" (man 2 open)
 //===----------------------------------------------------------------------===//
 
@@ -86,6 +80,7 @@
       // FIXME: We need a more general way of getting the O_CREAT value.
       // We could possibly grovel through the preprocessor state, but
       // that would require passing the Preprocessor object to the ExprEngine.
+      // See also: MallocChecker.cpp / M_ZERO.
       return;
     }
   }
@@ -119,7 +114,7 @@
 
   // Check if maskedFlags is non-zero.
   ProgramStateRef trueState, falseState;
-  llvm::tie(trueState, falseState) = state->assume(maskedFlags);
+  std::tie(trueState, falseState) = state->assume(maskedFlags);
 
   // Only emit an error if the value of 'maskedFlags' is properly
   // constrained;
@@ -199,7 +194,7 @@
                                 const SVal argVal,
                                 ProgramStateRef *trueState,
                                 ProgramStateRef *falseState) {
-  llvm::tie(*trueState, *falseState) =
+  std::tie(*trueState, *falseState) =
     state->assume(argVal.castAs<DefinedSVal>());
   
   return (*falseState && !*trueState);
@@ -207,7 +202,7 @@
 
 // Generates an error report, indicating that the function whose name is given
 // will perform a zero byte allocation.
-// Returns false if an error occured, true otherwise.
+// Returns false if an error occurred, true otherwise.
 bool UnixAPIChecker::ReportZeroByteAllocation(CheckerContext &C,
                                               ProgramStateRef falseState,
                                               const Expr *arg,
@@ -217,7 +212,7 @@
     return false;
 
   LazyInitialize(BT_mallocZero,
-    "Undefined allocation of 0 bytes (CERT MEM04-C; CWE-131)");
+                 "Undefined allocation of 0 bytes (CERT MEM04-C; CWE-131)");
 
   SmallString<256> S;
   llvm::raw_svector_ostream os(S);    
@@ -244,7 +239,7 @@
 
   // Check if the allocation size is 0.
   ProgramStateRef state = C.getState();
-  ProgramStateRef trueState = NULL, falseState = NULL;
+  ProgramStateRef trueState = nullptr, falseState = nullptr;
   const Expr *arg = CE->getArg(sizeArg);
   SVal argVal = state->getSVal(arg, C.getLocationContext());
 
@@ -269,7 +264,7 @@
     return;
 
   ProgramStateRef state = C.getState();
-  ProgramStateRef trueState = NULL, falseState = NULL;
+  ProgramStateRef trueState = nullptr, falseState = nullptr;
 
   unsigned int i;
   for (i = 0; i < nArgs; i++) {
@@ -348,7 +343,7 @@
       .Case("reallocf", &UnixAPIChecker::CheckReallocfZero)
       .Cases("alloca", "__builtin_alloca", &UnixAPIChecker::CheckAllocaZero)
       .Case("valloc", &UnixAPIChecker::CheckVallocZero)
-      .Default(NULL);
+      .Default(nullptr);
 
   if (SC)
     (this->*SC)(C, CE);
diff --git a/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp b/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
index a40b5a3..d78de3c 100644
--- a/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
@@ -58,10 +58,10 @@
   if (Eng.hasWorkRemaining())
     return;
 
-  const Decl *D = 0;
-  CFG *C = 0;
-  ParentMap *PM = 0;
-  const LocationContext *LC = 0;
+  const Decl *D = nullptr;
+  CFG *C = nullptr;
+  ParentMap *PM = nullptr;
+  const LocationContext *LC = nullptr;
   // Iterate over ExplodedGraph
   for (ExplodedGraph::node_iterator I = G.nodes_begin(), E = G.nodes_end();
       I != E; ++I) {
@@ -136,7 +136,7 @@
            ci != ce; ++ci) {
         if (Optional<CFGStmt> S = (*ci).getAs<CFGStmt>())
           if (const CallExpr *CE = dyn_cast<CallExpr>(S->getStmt())) {
-            if (CE->isBuiltinCall() == Builtin::BI__builtin_unreachable) {
+            if (CE->getBuiltinCallee() == Builtin::BI__builtin_unreachable) {
               foundUnreachable = true;
               break;
             }
@@ -165,7 +165,7 @@
     if (SM.isInSystemHeader(SL) || SM.isInExternCSystemHeader(SL))
       continue;
 
-    B.EmitBasicReport(D, "Unreachable code", "Dead code",
+    B.EmitBasicReport(D, this, "Unreachable code", "Dead code",
                       "This statement is never executed", DL, SR);
   }
 }
@@ -178,6 +178,9 @@
 
   for (CFGBlock::const_pred_iterator I = CB->pred_begin(), E = CB->pred_end();
       I != E; ++I) {
+    if (!*I)
+      continue;
+
     if (!reachable.count((*I)->getBlockID())) {
       // If we find an unreachable predecessor, mark this block as reachable so
       // we don't report this block
@@ -198,7 +201,7 @@
   if (const Stmt *S = CB->getTerminator())
     return S;
   else
-    return 0;
+    return nullptr;
 }
 
 // Determines if the path to this CFGBlock contained an element that infers this
@@ -219,6 +222,8 @@
     return false;
 
   const CFGBlock *pred = *CB->pred_begin();
+  if (!pred)
+    return false;
 
   // Get the predecessor block's terminator conditon
   const Stmt *cond = pred->getTerminatorCondition();
@@ -240,9 +245,9 @@
 
 // Returns true if the given CFGBlock is empty
 bool UnreachableCodeChecker::isEmptyCFGBlock(const CFGBlock *CB) {
-  return CB->getLabel() == 0       // No labels
+  return CB->getLabel() == nullptr // No labels
       && CB->size() == 0           // No statements
-      && CB->getTerminator() == 0; // No terminator
+      && !CB->getTerminator();     // No terminator
 }
 
 void ento::registerUnreachableCodeChecker(CheckerManager &mgr) {
diff --git a/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp b/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
index 30aef06..198a628 100644
--- a/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
@@ -29,7 +29,7 @@
 
 namespace {
 class VLASizeChecker : public Checker< check::PreStmt<DeclStmt> > {
-  mutable OwningPtr<BugType> BT;
+  mutable std::unique_ptr<BugType> BT;
   enum VLASize_Kind { VLA_Garbage, VLA_Zero, VLA_Tainted };
 
   void reportBug(VLASize_Kind Kind,
@@ -51,7 +51,8 @@
     return;
 
   if (!BT)
-    BT.reset(new BuiltinBug("Dangerous variable-length array (VLA) declaration"));
+    BT.reset(new BuiltinBug(
+        this, "Dangerous variable-length array (VLA) declaration"));
 
   SmallString<256> buf;
   llvm::raw_svector_ostream os(buf);
@@ -105,7 +106,7 @@
   
   // Check if the size is tainted.
   if (state->isTainted(sizeV)) {
-    reportBug(VLA_Tainted, SE, 0, C);
+    reportBug(VLA_Tainted, SE, nullptr, C);
     return;
   }
 
@@ -113,7 +114,7 @@
   DefinedSVal sizeD = sizeV.castAs<DefinedSVal>();
 
   ProgramStateRef stateNotZero, stateZero;
-  llvm::tie(stateNotZero, stateZero) = state->assume(sizeD);
+  std::tie(stateNotZero, stateZero) = state->assume(sizeD);
 
   if (stateZero && !stateNotZero) {
     reportBug(VLA_Zero, SE, stateZero, C);
diff --git a/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp b/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp
index 7b6adbf..f8f5cf9 100644
--- a/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp
@@ -28,6 +28,7 @@
 namespace {
 
 class WalkAST : public StmtVisitor<WalkAST> {
+  const CheckerBase *Checker;
   BugReporter &BR;
   AnalysisDeclContext *AC;
 
@@ -58,11 +59,10 @@
   const CallExpr *visitingCallExpr;
   
 public:
-  WalkAST(BugReporter &br, AnalysisDeclContext *ac)
-    : BR(br),
-      AC(ac),
-      visitingCallExpr(0) {}
-  
+  WalkAST(const CheckerBase *checker, BugReporter &br,
+          AnalysisDeclContext *ac)
+      : Checker(checker), BR(br), AC(ac), visitingCallExpr(nullptr) {}
+
   bool hasWork() const { return !WList.empty(); }
 
   /// This method adds a CallExpr to the worklist and marks the callee as
@@ -187,21 +187,19 @@
   if (isPure) {
     os << "\n" <<  "Call pure virtual functions during construction or "
        << "destruction may leads undefined behaviour";
-    BR.EmitBasicReport(AC->getDecl(),
+    BR.EmitBasicReport(AC->getDecl(), Checker,
                        "Call pure virtual function during construction or "
                        "Destruction",
-                       "Cplusplus",
-                       os.str(), CELoc, R);
+                       "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(),
+    BR.EmitBasicReport(AC->getDecl(), Checker,
                        "Call virtual function during construction or "
                        "Destruction",
-                       "Cplusplus",
-                       os.str(), CELoc, R);
+                       "Cplusplus", os.str(), CELoc, R);
     return;
   }
 }
@@ -215,11 +213,10 @@
 public:
   void checkASTDecl(const CXXRecordDecl *RD, AnalysisManager& mgr,
                     BugReporter &BR) const {
-    WalkAST walker(BR, mgr.getAnalysisDeclContext(RD));
+    WalkAST walker(this, BR, mgr.getAnalysisDeclContext(RD));
 
     // Check the constructors.
-    for (CXXRecordDecl::ctor_iterator I = RD->ctor_begin(), E = RD->ctor_end();
-         I != E; ++I) {
+    for (const auto *I : RD->ctors()) {
       if (!I->isCopyOrMoveConstructor())
         if (Stmt *Body = I->getBody()) {
           walker.Visit(Body);
diff --git a/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp b/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
index 9dcf58b..7944c7e 100644
--- a/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
+++ b/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
@@ -39,7 +39,7 @@
     // Use the User Mode to set the default IPA value.
     // Note, we have to add the string to the Config map for the ConfigDumper
     // checker to function properly.
-    const char *DefaultIPA = 0;
+    const char *DefaultIPA = nullptr;
     UserModeKind HighLevelMode = getUserMode();
     if (HighLevelMode == UMK_Shallow)
       DefaultIPA = "inlining";
@@ -134,8 +134,14 @@
                           /*Default=*/true);
 }
 
-bool AnalyzerOptions::mayInlineCXXContainerCtorsAndDtors() {
-  return getBooleanOption(InlineCXXContainerCtorsAndDtors,
+bool AnalyzerOptions::mayInlineCXXAllocator() {
+  return getBooleanOption(InlineCXXAllocator,
+                          "c++-allocator-inlining",
+                          /*Default=*/false);
+}
+
+bool AnalyzerOptions::mayInlineCXXContainerMethods() {
+  return getBooleanOption(InlineCXXContainerMethods,
                           "c++-container-inlining",
                           /*Default=*/false);
 }
@@ -183,6 +189,13 @@
                           /* Default = */ false);
 }
 
+
+bool AnalyzerOptions::shouldWriteStableReportFilename() {
+  return getBooleanOption(StableReportFilename,
+                          "stable-report-filename",
+                          /* Default = */ false);
+}
+
 int AnalyzerOptions::getOptionAsInteger(StringRef Name, int DefaultVal) {
   SmallString<10> StrBuf;
   llvm::raw_svector_ostream OS(StrBuf);
diff --git a/lib/StaticAnalyzer/Core/BasicValueFactory.cpp b/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
index a6c400f..0e90566 100644
--- a/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
+++ b/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
@@ -173,12 +173,12 @@
       // FIXME: Expand these checks to include all undefined behavior.
 
       if (V2.isSigned() && V2.isNegative())
-        return NULL;
+        return nullptr;
 
       uint64_t Amt = V2.getZExtValue();
 
-      if (Amt > V1.getBitWidth())
-        return NULL;
+      if (Amt >= V1.getBitWidth())
+        return nullptr;
 
       return &getValue( V1.operator<<( (unsigned) Amt ));
     }
@@ -191,12 +191,12 @@
       // FIXME: Expand these checks to include all undefined behavior.
 
       if (V2.isSigned() && V2.isNegative())
-        return NULL;
+        return nullptr;
 
       uint64_t Amt = V2.getZExtValue();
 
-      if (Amt > V1.getBitWidth())
-        return NULL;
+      if (Amt >= V1.getBitWidth())
+        return nullptr;
 
       return &getValue( V1.operator>>( (unsigned) Amt ));
     }
diff --git a/lib/StaticAnalyzer/Core/BlockCounter.cpp b/lib/StaticAnalyzer/Core/BlockCounter.cpp
index 74d761e..c1ac03d 100644
--- a/lib/StaticAnalyzer/Core/BlockCounter.cpp
+++ b/lib/StaticAnalyzer/Core/BlockCounter.cpp
@@ -34,8 +34,7 @@
   }
 
   bool operator<(const CountKey &RHS) const {
-    return (CallSite == RHS.CallSite) ? (BlockID < RHS.BlockID) 
-                                      : (CallSite < RHS.CallSite);
+    return std::tie(CallSite, BlockID) < std::tie(RHS.CallSite, RHS.BlockID);
   }
 
   void Profile(llvm::FoldingSetNodeID &ID) const {
diff --git a/lib/StaticAnalyzer/Core/BugReporter.cpp b/lib/StaticAnalyzer/Core/BugReporter.cpp
index 1940fa7..141a48b 100644
--- a/lib/StaticAnalyzer/Core/BugReporter.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporter.cpp
@@ -12,16 +12,14 @@
 //
 //===----------------------------------------------------------------------===//
 
-#define DEBUG_TYPE "BugReporter"
-
 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ParentMap.h"
-#include "clang/AST/StmtObjC.h"
 #include "clang/AST/StmtCXX.h"
+#include "clang/AST/StmtObjC.h"
 #include "clang/Analysis/CFG.h"
 #include "clang/Analysis/ProgramPoint.h"
 #include "clang/Basic/SourceManager.h"
@@ -30,16 +28,18 @@
 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/Support/raw_ostream.h"
+#include <memory>
 #include <queue>
 
 using namespace clang;
 using namespace ento;
 
+#define DEBUG_TYPE "BugReporter"
+
 STATISTIC(MaxBugClassSize,
           "The maximum number of bug reports in the same equivalence class");
 STATISTIC(MaxValidBugClassSize,
@@ -59,7 +59,7 @@
     if (const Stmt *S = PathDiagnosticLocation::getStmt(N))
       return S;
 
-  return 0;
+  return nullptr;
 }
 
 static inline const Stmt*
@@ -83,15 +83,15 @@
   const void *tagLesser = TrackConstraintBRVisitor::getTag();
   
   if (X->getLocation() != Y->getLocation())
-    return 0;
-  
+    return nullptr;
+
   if (X->getTag() == tagPreferred && Y->getTag() == tagLesser)
     return X;
   
   if (Y->getTag() == tagPreferred && X->getTag() == tagLesser)
     return Y;
-  
-  return 0;
+
+  return nullptr;
 }
 
 /// An optimization pass over PathPieces that removes redundant diagnostics
@@ -125,7 +125,7 @@
           break;
         
         if (PathDiagnosticEventPiece *nextEvent =
-            dyn_cast<PathDiagnosticEventPiece>(path.front().getPtr())) {
+            dyn_cast<PathDiagnosticEventPiece>(path.front().get())) {
           PathDiagnosticEventPiece *event =
             cast<PathDiagnosticEventPiece>(piece);
           // Check to see if we should keep one of the two pieces.  If we
@@ -214,8 +214,9 @@
 
 /// Recursively scan through a path and make sure that all call pieces have
 /// valid locations. 
-static void adjustCallLocations(PathPieces &Pieces,
-                                PathDiagnosticLocation *LastCallLocation = 0) {
+static void
+adjustCallLocations(PathPieces &Pieces,
+                    PathDiagnosticLocation *LastCallLocation = nullptr) {
   for (PathPieces::iterator I = Pieces.begin(), E = Pieces.end(); I != E; ++I) {
     PathDiagnosticCallPiece *Call = dyn_cast<PathDiagnosticCallPiece>(*I);
 
@@ -265,7 +266,7 @@
         I = Pieces.erase(I);
         continue;
       } else if (End && isa<CXXDefaultInitExpr>(End)) {
-        PathPieces::iterator Next = llvm::next(I);
+        PathPieces::iterator Next = std::next(I);
         if (Next != E) {
           if (PathDiagnosticControlFlowPiece *NextCF =
                 dyn_cast<PathDiagnosticControlFlowPiece>(*Next)) {
@@ -311,7 +312,7 @@
 public:
   NodeMapClosure(InterExplodedGraphMap &m) : M(m) {}
 
-  const ExplodedNode *getOriginalNode(const ExplodedNode *N) {
+  const ExplodedNode *getOriginalNode(const ExplodedNode *N) override {
     return M.lookup(N);
   }
 };
@@ -345,7 +346,7 @@
     return getParentMap().getParent(S);
   }
 
-  virtual NodeMapClosure& getNodeResolver() { return NMC; }
+  NodeMapClosure& getNodeResolver() override { return NMC; }
 
   PathDiagnosticLocation getEnclosingStmtLocation(const Stmt *S);
 
@@ -405,7 +406,7 @@
 
   const Stmt *Parent = PM.getParentIgnoreParens(S);
   if (!Parent)
-    return 0;
+    return nullptr;
 
   switch (Parent->getStmtClass()) {
   case Stmt::ForStmtClass:
@@ -418,7 +419,7 @@
     break;
   }
 
-  return 0;
+  return nullptr;
 }
 
 static PathDiagnosticLocation
@@ -564,7 +565,7 @@
   SourceManager& SMgr = PDB.getSourceManager();
   const LocationContext *LC = PDB.LC;
   const ExplodedNode *NextNode = N->pred_empty()
-                                        ? NULL : *(N->pred_begin());
+                                        ? nullptr : *(N->pred_begin());
 
   StackDiagVector CallStack;
 
@@ -1263,8 +1264,8 @@
           SVal ChildV = State->getSVal(child, LCtx);
           R.markInteresting(ChildV);
         }
-        break;
       }
+      break;
     }
   }
   
@@ -1351,11 +1352,11 @@
     }
     N = N->getFirstPred();
   }
-  return 0;
+  return nullptr;
 }
 
 static bool isInLoopBody(ParentMap &PM, const Stmt *S, const Stmt *Term) {
-  const Stmt *LoopBody = 0;
+  const Stmt *LoopBody = nullptr;
   switch (Term->getStmtClass()) {
     case Stmt::CXXForRangeStmtClass: {
       const CXXForRangeStmt *FR = cast<CXXForRangeStmt>(Term);
@@ -1401,7 +1402,7 @@
   StackDiagVector CallStack;
   InterestingExprs IE;
 
-  const ExplodedNode *NextNode = N->pred_empty() ? NULL : *(N->pred_begin());
+  const ExplodedNode *NextNode = N->pred_empty() ? nullptr : *(N->pred_begin());
   while (NextNode) {
     N = NextNode;
     NextNode = N->getFirstPred();
@@ -1411,7 +1412,7 @@
       if (Optional<PostStmt> PS = P.getAs<PostStmt>()) {
         if (const Expr *Ex = PS->getStmtAs<Expr>())
           reversePropagateIntererstingSymbols(*PDB.getBugReport(), IE,
-                                              N->getState().getPtr(), Ex,
+                                              N->getState().get(), Ex,
                                               N->getLocationContext());
       }
       
@@ -1419,7 +1420,7 @@
         const Stmt *S = CE->getCalleeContext()->getCallSite();
         if (const Expr *Ex = dyn_cast_or_null<Expr>(S)) {
             reversePropagateIntererstingSymbols(*PDB.getBugReport(), IE,
-                                                N->getState().getPtr(), Ex,
+                                                N->getState().get(), Ex,
                                                 N->getLocationContext());
         }
         
@@ -1490,7 +1491,7 @@
           const LocationContext *CalleeCtx = PDB.LC;
           if (CallerCtx != CalleeCtx) {
             reversePropagateInterestingSymbols(*PDB.getBugReport(), IE,
-                                               N->getState().getPtr(),
+                                               N->getState().get(),
                                                CalleeCtx, CallerCtx);
           }
         }
@@ -1498,7 +1499,7 @@
         // Are we jumping to the head of a loop?  Add a special diagnostic.
         if (const Stmt *Loop = BE->getSrc()->getLoopTarget()) {
           PathDiagnosticLocation L(Loop, SM, PDB.LC);
-          const CompoundStmt *CS = NULL;
+          const CompoundStmt *CS = nullptr;
 
           if (const ForStmt *FS = dyn_cast<ForStmt>(Loop))
             CS = dyn_cast<CompoundStmt>(FS->getBody());
@@ -1673,7 +1674,7 @@
 
         PathDiagnosticCallPiece *C;
         if (VisitedEntireCall) {
-          PathDiagnosticPiece *P = PD.getActivePath().front().getPtr();
+          PathDiagnosticPiece *P = PD.getActivePath().front().get();
           C = cast<PathDiagnosticCallPiece>(P);
         } else {
           const Decl *Caller = CE->getLocationContext()->getDecl();
@@ -1683,11 +1684,11 @@
           // reset the mapping from active to location context.
           assert(PD.getActivePath().size() == 1 &&
                  PD.getActivePath().front() == C);
-          LCM[&PD.getActivePath()] = 0;
+          LCM[&PD.getActivePath()] = nullptr;
 
           // Record the location context mapping for the path within
           // the call.
-          assert(LCM[&C->path] == 0 ||
+          assert(LCM[&C->path] == nullptr ||
                  LCM[&C->path] == CE->getCalleeContext());
           LCM[&C->path] = CE->getCalleeContext();
 
@@ -1727,7 +1728,7 @@
         // Propagate the interesting symbols accordingly.
         if (const Expr *Ex = dyn_cast_or_null<Expr>(S)) {
           reversePropagateIntererstingSymbols(*PDB.getBugReport(), IE,
-                                              N->getState().getPtr(), Ex,
+                                              N->getState().get(), Ex,
                                               N->getLocationContext());
         }
 
@@ -1755,7 +1756,7 @@
         // interesting symbols correctly.
         if (const Expr *Ex = PS->getStmtAs<Expr>())
           reversePropagateIntererstingSymbols(*PDB.getBugReport(), IE,
-                                              N->getState().getPtr(), Ex,
+                                              N->getState().get(), Ex,
                                               N->getLocationContext());
 
         // Add an edge.  If this is an ObjCForCollectionStmt do
@@ -1778,7 +1779,7 @@
           const LocationContext *CalleeCtx = PDB.LC;
           if (CallerCtx != CalleeCtx) {
             reversePropagateInterestingSymbols(*PDB.getBugReport(), IE,
-                                               N->getState().getPtr(),
+                                               N->getState().get(),
                                                CalleeCtx, CallerCtx);
           }
         }
@@ -1786,7 +1787,7 @@
         // Are we jumping to the head of a loop?  Add a special diagnostic.
         if (const Stmt *Loop = BE->getSrc()->getLoopTarget()) {
           PathDiagnosticLocation L(Loop, SM, PDB.LC);
-          const Stmt *Body = NULL;
+          const Stmt *Body = nullptr;
 
           if (const ForStmt *FS = dyn_cast<ForStmt>(Loop))
             Body = FS->getBody();
@@ -1827,7 +1828,7 @@
             bool IsInLoopBody =
               isInLoopBody(PM, getStmtBeforeCond(PM, TermCond, N), Term);
 
-            const char *str = 0;
+            const char *str = nullptr;
 
             if (isJumpToFalseBranch(&*BE)) {
               if (!IsInLoopBody) {
@@ -1890,13 +1891,13 @@
 
 static const Stmt *getLocStmt(PathDiagnosticLocation L) {
   if (!L.isValid())
-    return 0;
+    return nullptr;
   return L.asStmt();
 }
 
 static const Stmt *getStmtParent(const Stmt *S, const ParentMap &PM) {
   if (!S)
-    return 0;
+    return nullptr;
 
   while (true) {
     S = PM.getParentIgnoreParens(S);
@@ -1988,7 +1989,7 @@
     SmallVector<PathDiagnosticLocation, 4> SrcContexts;
 
     PathDiagnosticLocation NextSrcContext = SrcLoc;
-    const Stmt *InnerStmt = 0;
+    const Stmt *InnerStmt = nullptr;
     while (NextSrcContext.isValid() && NextSrcContext.asStmt() != InnerStmt) {
       SrcContexts.push_back(NextSrcContext);
       InnerStmt = NextSrcContext.asStmt();
@@ -2073,7 +2074,7 @@
     if (NextI == E)
       break;
 
-    PathDiagnosticControlFlowPiece *PieceNextI = 0;
+    PathDiagnosticControlFlowPiece *PieceNextI = nullptr;
 
     while (true) {
       if (NextI == E)
@@ -2579,8 +2580,8 @@
   
   const ExplodedNode *N = getErrorNode();
   if (!N)
-    return 0;
-  
+    return nullptr;
+
   const LocationContext *LC = N->getLocationContext();
   return LC->getCurrentStackFrame()->getDecl();
 }
@@ -2703,10 +2704,10 @@
 
 const Stmt *BugReport::getStmt() const {
   if (!ErrorNode)
-    return 0;
+    return nullptr;
 
   ProgramPoint ProgP = ErrorNode->getLocation();
-  const Stmt *S = NULL;
+  const Stmt *S = nullptr;
 
   if (Optional<BlockEntrance> BE = ProgP.getAs<BlockEntrance>()) {
     CFGBlock &Exit = ProgP.getLocationContext()->getCFG()->getExit();
@@ -2742,12 +2743,10 @@
     assert(!Location.isValid() &&
      "Either Location or ErrorNode should be specified but not both.");
     return PathDiagnosticLocation::createEndOfPath(ErrorNode, SM);
-  } else {
-    assert(Location.isValid());
-    return Location;
   }
 
-  return PathDiagnosticLocation();
+  assert(Location.isValid());
+  return Location;
 }
 
 //===----------------------------------------------------------------------===//
@@ -2802,9 +2801,7 @@
   // EmitBasicReport.
   // FIXME: There are leaks from checkers that assume that the BugTypes they
   // create will be destroyed by the BugReporter.
-  for (llvm::StringMap<BugType*>::iterator
-         I = StrBugTypes.begin(), E = StrBugTypes.end(); I != E; ++I)
-    delete I->second;
+  llvm::DeleteContainerSeconds(StrBugTypes);
 
   // Remove all references to the BugType objects.
   BugTypes = F.getEmptySet();
@@ -2820,7 +2817,7 @@
 class ReportGraph {
 public:
   InterExplodedGraphMap BackMap;
-  OwningPtr<ExplodedGraph> Graph;
+  std::unique_ptr<ExplodedGraph> Graph;
   const ExplodedNode *ErrorNode;
   size_t Index;
 };
@@ -2835,7 +2832,7 @@
   typedef std::pair<const ExplodedNode *, size_t> NodeIndexPair;
   SmallVector<NodeIndexPair, 32> ReportNodes;
 
-  OwningPtr<ExplodedGraph> G;
+  std::unique_ptr<ExplodedGraph> G;
 
   /// A helper class for sorting ExplodedNodes by priority.
   template <bool Descending>
@@ -2906,7 +2903,7 @@
 
     PriorityMapTy::iterator PriorityEntry;
     bool IsNew;
-    llvm::tie(PriorityEntry, IsNew) =
+    std::tie(PriorityEntry, IsNew) =
       PriorityMap.insert(std::make_pair(Node, Priority));
     ++Priority;
 
@@ -2935,7 +2932,7 @@
     return false;
 
   const ExplodedNode *OrigN;
-  llvm::tie(OrigN, GraphWrapper.Index) = ReportNodes.pop_back_val();
+  std::tie(OrigN, GraphWrapper.Index) = ReportNodes.pop_back_val();
   assert(PriorityMap.find(OrigN) != PriorityMap.end() &&
          "error node not accessible from root");
 
@@ -2947,7 +2944,7 @@
 
   // Now walk from the error node up the BFS path, always taking the
   // predeccessor with the lowest number.
-  ExplodedNode *Succ = 0;
+  ExplodedNode *Succ = nullptr;
   while (true) {
     // Create the equivalent node in the new graph with the same state
     // and location.
@@ -2998,7 +2995,7 @@
   for (PathPieces::const_iterator I = path.begin(), E = path.end();
        I!=E; ++I) {
     
-    PathDiagnosticPiece *piece = I->getPtr();
+    PathDiagnosticPiece *piece = I->get();
 
     // Recursively compact calls.
     if (PathDiagnosticCallPiece *call=dyn_cast<PathDiagnosticCallPiece>(piece)){
@@ -3095,7 +3092,7 @@
     } else {
       // Keep the errorNodes list in sync with the bugReports list.
       HasInvalid = true;
-      errorNodes.push_back(0);
+      errorNodes.push_back(nullptr);
     }
   }
 
@@ -3153,21 +3150,21 @@
 
       // Generate the very last diagnostic piece - the piece is visible before 
       // the trace is expanded.
-      PathDiagnosticPiece *LastPiece = 0;
+      std::unique_ptr<PathDiagnosticPiece> LastPiece;
       for (BugReport::visitor_iterator I = visitors.begin(), E = visitors.end();
           I != E; ++I) {
         if (PathDiagnosticPiece *Piece = (*I)->getEndPath(PDB, N, *R)) {
           assert (!LastPiece &&
               "There can only be one final piece in a diagnostic.");
-          LastPiece = Piece;
+          LastPiece.reset(Piece);
         }
       }
 
       if (ActiveScheme != PathDiagnosticConsumer::None) {
         if (!LastPiece)
-          LastPiece = BugReporterVisitor::getDefaultEndPath(PDB, N, *R);
+          LastPiece.reset(BugReporterVisitor::getDefaultEndPath(PDB, N, *R));
         assert(LastPiece);
-        PD.setEndOfPath(LastPiece);
+        PD.setEndOfPath(LastPiece.release());
       }
 
       // Make sure we get a clean location context map so we don't
@@ -3247,6 +3244,9 @@
 }
 
 void BugReporter::emitReport(BugReport* R) {
+  // To guarantee memory release.
+  std::unique_ptr<BugReport> UniqueR(R);
+
   // Defensive checking: throw the bug away if it comes from a BodyFarm-
   // generated body. We do this very early because report processing relies
   // on the report's location being valid.
@@ -3277,12 +3277,12 @@
   BugReportEquivClass* EQ = EQClasses.FindNodeOrInsertPos(ID, InsertPos);
 
   if (!EQ) {
-    EQ = new BugReportEquivClass(R);
+    EQ = new BugReportEquivClass(UniqueR.release());
     EQClasses.InsertNode(EQ, InsertPos);
     EQClassesVector.push_back(EQ);
   }
   else
-    EQ->AddReport(R);
+    EQ->AddReport(UniqueR.release());
 }
 
 
@@ -3329,7 +3329,7 @@
   // DFS traversal of the ExplodedGraph to find a non-sink node.  We could write
   // this as a recursive function, but we don't want to risk blowing out the
   // stack for very long paths.
-  BugReport *exampleReport = 0;
+  BugReport *exampleReport = nullptr;
 
   for (; I != E; ++I) {
     const ExplodedNode *errorNode = I->getErrorNode();
@@ -3403,10 +3403,8 @@
   SmallVector<BugReport*, 10> bugReports;
   BugReport *exampleReport = FindReportInEquivalenceClass(EQ, bugReports);
   if (exampleReport) {
-    const PathDiagnosticConsumers &C = getPathDiagnosticConsumers();
-    for (PathDiagnosticConsumers::const_iterator I=C.begin(),
-                                                 E=C.end(); I != E; ++I) {
-      FlushReport(exampleReport, **I, bugReports);
+    for (PathDiagnosticConsumer *PDC : getPathDiagnosticConsumers()) {
+      FlushReport(exampleReport, *PDC, bugReports);
     }
   }
 }
@@ -3419,14 +3417,13 @@
   // Probably doesn't make a difference in practice.
   BugType& BT = exampleReport->getBugType();
 
-  OwningPtr<PathDiagnostic>
-    D(new PathDiagnostic(exampleReport->getDeclWithIssue(),
-                         exampleReport->getBugType().getName(),
-                         exampleReport->getDescription(),
-                         exampleReport->getShortDescription(/*Fallback=*/false),
-                         BT.getCategory(),
-                         exampleReport->getUniqueingLocation(),
-                         exampleReport->getUniqueingDecl()));
+  std::unique_ptr<PathDiagnostic> D(new PathDiagnostic(
+      exampleReport->getBugType().getCheckName(),
+      exampleReport->getDeclWithIssue(), exampleReport->getBugType().getName(),
+      exampleReport->getDescription(),
+      exampleReport->getShortDescription(/*Fallback=*/false), BT.getCategory(),
+      exampleReport->getUniqueingLocation(),
+      exampleReport->getUniqueingDecl()));
 
   MaxBugClassSize = std::max(bugReports.size(),
                              static_cast<size_t>(MaxBugClassSize));
@@ -3455,7 +3452,7 @@
     PathDiagnosticPiece *piece =
       new PathDiagnosticEventPiece(L, exampleReport->getDescription());
     BugReport::ranges_iterator Beg, End;
-    llvm::tie(Beg, End) = exampleReport->getRanges();
+    std::tie(Beg, End) = exampleReport->getRanges();
     for ( ; Beg != End; ++Beg)
       piece->addRange(*Beg);
     D->setEndOfPath(piece);
@@ -3468,17 +3465,25 @@
     D->addMeta(*i);
   }
 
-  PD.HandlePathDiagnostic(D.take());
+  PD.HandlePathDiagnostic(D.release());
 }
 
 void BugReporter::EmitBasicReport(const Decl *DeclWithIssue,
-                                  StringRef name,
-                                  StringRef category,
+                                  const CheckerBase *Checker,
+                                  StringRef Name, StringRef Category,
+                                  StringRef Str, PathDiagnosticLocation Loc,
+                                  ArrayRef<SourceRange> Ranges) {
+  EmitBasicReport(DeclWithIssue, Checker->getCheckName(), Name, Category, Str,
+                  Loc, Ranges);
+}
+void BugReporter::EmitBasicReport(const Decl *DeclWithIssue,
+                                  CheckName CheckName,
+                                  StringRef name, StringRef category,
                                   StringRef str, PathDiagnosticLocation Loc,
                                   ArrayRef<SourceRange> Ranges) {
 
   // 'BT' is owned by BugReporter.
-  BugType *BT = getBugTypeForName(name, category);
+  BugType *BT = getBugTypeForName(CheckName, name, category);
   BugReport *R = new BugReport(*BT, str, Loc);
   R->setDeclWithIssue(DeclWithIssue);
   for (ArrayRef<SourceRange>::iterator I = Ranges.begin(), E = Ranges.end();
@@ -3487,22 +3492,22 @@
   emitReport(R);
 }
 
-BugType *BugReporter::getBugTypeForName(StringRef name,
+BugType *BugReporter::getBugTypeForName(CheckName CheckName, StringRef name,
                                         StringRef category) {
   SmallString<136> fullDesc;
-  llvm::raw_svector_ostream(fullDesc) << name << ":" << category;
+  llvm::raw_svector_ostream(fullDesc) << CheckName.getName() << ":" << name
+                                      << ":" << category;
   llvm::StringMapEntry<BugType *> &
       entry = StrBugTypes.GetOrCreateValue(fullDesc);
   BugType *BT = entry.getValue();
   if (!BT) {
-    BT = new BugType(name, category);
+    BT = new BugType(CheckName, name, category);
     entry.setValue(BT);
   }
   return BT;
 }
 
-
-void PathPieces::dump() const {
+LLVM_DUMP_METHOD void PathPieces::dump() const {
   unsigned index = 0;
   for (PathPieces::const_iterator I = begin(), E = end(); I != E; ++I) {
     llvm::errs() << "[" << index++ << "]  ";
diff --git a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
index e1a92b3..0503ace 100644
--- a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
@@ -45,7 +45,7 @@
   //   a[0], p->f, *p
   const Expr *E = dyn_cast<Expr>(S);
   if (!E)
-    return 0;
+    return nullptr;
   E = E->IgnoreParenCasts();
 
   while (true) {
@@ -79,21 +79,21 @@
     break;
   }
 
-  return NULL;
+  return nullptr;
 }
 
 const Stmt *bugreporter::GetDenomExpr(const ExplodedNode *N) {
   const Stmt *S = N->getLocationAs<PreStmt>()->getStmt();
   if (const BinaryOperator *BE = dyn_cast<BinaryOperator>(S))
     return BE->getRHS();
-  return NULL;
+  return nullptr;
 }
 
 const Stmt *bugreporter::GetRetValExpr(const ExplodedNode *N) {
   const Stmt *S = N->getLocationAs<PostStmt>()->getStmt();
   if (const ReturnStmt *RS = dyn_cast<ReturnStmt>(S))
     return RS->getRetValue();
-  return NULL;
+  return nullptr;
 }
 
 //===----------------------------------------------------------------------===//
@@ -104,7 +104,7 @@
 BugReporterVisitor::getEndPath(BugReporterContext &BRC,
                                const ExplodedNode *EndPathNode,
                                BugReport &BR) {
-  return 0;
+  return nullptr;
 }
 
 PathDiagnosticPiece*
@@ -115,7 +115,7 @@
     PathDiagnosticLocation::createEndOfPath(EndPathNode,BRC.getSourceManager());
 
   BugReport::ranges_iterator Beg, End;
-  llvm::tie(Beg, End) = BR.getRanges();
+  std::tie(Beg, End) = BR.getRanges();
 
   // Only add the statement itself as a range if we didn't specify any
   // special ranges for this report.
@@ -156,7 +156,7 @@
     return static_cast<void *>(&Tag);
   }
 
-  virtual void Profile(llvm::FoldingSetNodeID &ID) const {
+  void Profile(llvm::FoldingSetNodeID &ID) const override {
     ID.AddPointer(ReturnVisitor::getTag());
     ID.AddPointer(StackFrame);
     ID.AddBoolean(EnableNullFPSuppression);
@@ -237,22 +237,22 @@
                                         BugReport &BR) {
     // Only print a message at the interesting return statement.
     if (N->getLocationContext() != StackFrame)
-      return 0;
+      return nullptr;
 
     Optional<StmtPoint> SP = N->getLocationAs<StmtPoint>();
     if (!SP)
-      return 0;
+      return nullptr;
 
     const ReturnStmt *Ret = dyn_cast<ReturnStmt>(SP->getStmt());
     if (!Ret)
-      return 0;
+      return nullptr;
 
     // Okay, we're at the right return statement, but do we have the return
     // value available?
     ProgramStateRef State = N->getState();
     SVal V = State->getSVal(Ret, StackFrame);
     if (V.isUnknownOrUndef())
-      return 0;
+      return nullptr;
 
     // Don't print any more notes after this one.
     Mode = Satisfied;
@@ -273,7 +273,7 @@
     // Ignore aggregate rvalues.
     if (V.getAs<nonloc::LazyCompoundVal>() ||
         V.getAs<nonloc::CompoundVal>())
-      return 0;
+      return nullptr;
 
     RetE = RetE->IgnoreParenCasts();
 
@@ -283,7 +283,7 @@
       BR.markInteresting(V);
       ReturnVisitor::addVisitorIfNecessary(N, RetE, BR,
                                            EnableNullFPSuppression);
-      return 0;
+      return nullptr;
     }
       
     // If we're returning 0, we should track where that 0 came from.
@@ -343,10 +343,10 @@
     // Are we at the entry node for this call?
     Optional<CallEnter> CE = N->getLocationAs<CallEnter>();
     if (!CE)
-      return 0;
+      return nullptr;
 
     if (CE->getCalleeContext() != StackFrame)
-      return 0;
+      return nullptr;
 
     Mode = Satisfied;
 
@@ -380,20 +380,20 @@
       // (We will still look at the other arguments, though.)
     }
 
-    return 0;
+    return nullptr;
   }
 
   PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
                                  const ExplodedNode *PrevN,
                                  BugReporterContext &BRC,
-                                 BugReport &BR) {
+                                 BugReport &BR) override {
     switch (Mode) {
     case Initial:
       return visitNodeInitial(N, PrevN, BRC, BR);
     case MaybeUnsuppress:
       return visitNodeMaybeUnsuppress(N, PrevN, BRC, BR);
     case Satisfied:
-      return 0;
+      return nullptr;
     }
 
     llvm_unreachable("Invalid visit mode!");
@@ -401,10 +401,10 @@
 
   PathDiagnosticPiece *getEndPath(BugReporterContext &BRC,
                                   const ExplodedNode *N,
-                                  BugReport &BR) {
+                                  BugReport &BR) override {
     if (EnableNullFPSuppression)
       BR.markInvalid(ReturnVisitor::getTag(), StackFrame);
-    return 0;
+    return nullptr;
   }
 };
 } // end anonymous namespace
@@ -453,10 +453,10 @@
                                                        BugReport &BR) {
 
   if (Satisfied)
-    return NULL;
+    return nullptr;
 
-  const ExplodedNode *StoreSite = 0;
-  const Expr *InitE = 0;
+  const ExplodedNode *StoreSite = nullptr;
+  const Expr *InitE = nullptr;
   bool IsParam = false;
 
   // First see if we reached the declaration of the region.
@@ -484,12 +484,12 @@
   //     the same binding was re-assigned here.
   if (!StoreSite) {
     if (Succ->getState()->getSVal(R) != V)
-      return NULL;
+      return nullptr;
 
     if (Pred->getState()->getSVal(R) == V) {
       Optional<PostStore> PS = Succ->getLocationAs<PostStore>();
       if (!PS || PS->getLocationValue() != R)
-        return NULL;
+        return nullptr;
     }
 
     StoreSite = Succ;
@@ -526,7 +526,7 @@
   }
 
   if (!StoreSite)
-    return NULL;
+    return nullptr;
   Satisfied = true;
 
   // If we have an expression that provided the value, try to track where it
@@ -550,7 +550,7 @@
 
   if (Optional<PostStmt> PS = StoreSite->getLocationAs<PostStmt>()) {
     const Stmt *S = PS->getStmt();
-    const char *action = 0;
+    const char *action = nullptr;
     const DeclStmt *DS = dyn_cast<DeclStmt>(S);
     const VarRegion *VR = dyn_cast<VarRegion>(R);
 
@@ -703,7 +703,7 @@
     L = PathDiagnosticLocation::create(P, BRC.getSourceManager());
 
   if (!L.isValid() || !L.asLocation().isValid())
-    return NULL;
+    return nullptr;
 
   return new PathDiagnosticEventPiece(L, os.str());
 }
@@ -724,7 +724,7 @@
 bool TrackConstraintBRVisitor::isUnderconstrained(const ExplodedNode *N) const {
   if (IsZeroCheck)
     return N->getState()->isNull(Constraint).isUnderconstrained();
-  return N->getState()->assume(Constraint, !Assumption);
+  return (bool)N->getState()->assume(Constraint, !Assumption);
 }
 
 PathDiagnosticPiece *
@@ -733,7 +733,7 @@
                                     BugReporterContext &BRC,
                                     BugReport &BR) {
   if (IsSatisfied)
-    return NULL;
+    return nullptr;
 
   // Start tracking after we see the first state in which the value is
   // constrained.
@@ -741,7 +741,7 @@
     if (!isUnderconstrained(N))
       IsTrackingTurnedOn = true;
   if (!IsTrackingTurnedOn)
-    return 0;
+    return nullptr;
 
   // Check if in the previous state it was feasible for this constraint
   // to *not* be true.
@@ -765,21 +765,21 @@
     }
 
     if (os.str().empty())
-      return NULL;
+      return nullptr;
 
     // Construct a new PathDiagnosticPiece.
     ProgramPoint P = N->getLocation();
     PathDiagnosticLocation L =
       PathDiagnosticLocation::create(P, BRC.getSourceManager());
     if (!L.isValid())
-      return NULL;
-    
+      return nullptr;
+
     PathDiagnosticEventPiece *X = new PathDiagnosticEventPiece(L, os.str());
     X->setTag(getTag());
     return X;
   }
 
-  return NULL;
+  return nullptr;
 }
 
 SuppressInlineDefensiveChecksVisitor::
@@ -813,14 +813,14 @@
                                                 BugReporterContext &BRC,
                                                 BugReport &BR) {
   if (IsSatisfied)
-    return 0;
+    return nullptr;
 
   // Start tracking after we see the first state in which the value is null.
   if (!IsTrackingTurnedOn)
     if (Succ->getState()->isNull(V).isConstrainedTrue())
       IsTrackingTurnedOn = true;
   if (!IsTrackingTurnedOn)
-    return 0;
+    return nullptr;
 
   // Check if in the previous state it was feasible for this value
   // to *not* be null.
@@ -835,7 +835,7 @@
     if (CurLC != ReportLC && !CurLC->isParentOf(ReportLC))
       BR.markInvalid("Suppress IDC", CurLC);
   }
-  return 0;
+  return nullptr;
 }
 
 static const MemRegion *getLocationRegionIfReference(const Expr *E,
@@ -843,7 +843,7 @@
   if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(E)) {
     if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
       if (!VD->getType()->isReferenceType())
-        return 0;
+        return nullptr;
       ProgramStateManager &StateMgr = N->getState()->getStateManager();
       MemRegionManager &MRMgr = StateMgr.getRegionManager();
       return MRMgr.getVarRegion(VD, N->getLocationContext());
@@ -856,7 +856,7 @@
   //   Wrapper w = { *(int *)0 };
   //   w.ref = 1;
 
-  return 0;
+  return nullptr;
 }
 
 static const Expr *peelOffOuterExpr(const Expr *Ex,
@@ -869,7 +869,7 @@
 
   // Peel off the ternary operator.
   if (const ConditionalOperator *CO = dyn_cast<ConditionalOperator>(Ex)) {
-    // Find a node where the branching occured and find out which branch
+    // Find a node where the branching occurred and find out which branch
     // we took (true/false) by looking at the ExplodedGraph.
     const ExplodedNode *NI = N;
     do {
@@ -906,7 +906,7 @@
       S = PeeledEx;
   }
 
-  const Expr *Inner = 0;
+  const Expr *Inner = nullptr;
   if (const Expr *Ex = dyn_cast<Expr>(S)) {
     Ex = Ex->IgnoreParenCasts();
     if (ExplodedGraph::isInterestingLValueExpr(Ex) || CallEvent::isCallStmt(Ex))
@@ -948,7 +948,7 @@
   // See if the expression we're interested refers to a variable.
   // If so, we can track both its contents and constraints on its value.
   if (Inner && ExplodedGraph::isInterestingLValueExpr(Inner)) {
-    const MemRegion *R = 0;
+    const MemRegion *R = nullptr;
 
     // Find the ExplodedNode where the lvalue (the value of 'Ex')
     // was computed.  We need this for getting the location value.
@@ -1060,14 +1060,14 @@
                                                  const ExplodedNode *N) {
   const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(S);
   if (!ME)
-    return 0;
+    return nullptr;
   if (const Expr *Receiver = ME->getInstanceReceiver()) {
     ProgramStateRef state = N->getState();
     SVal V = state->getSVal(Receiver, N->getLocationContext());
     if (state->isNull(V).isConstrainedTrue())
       return Receiver;
   }
-  return 0;
+  return nullptr;
 }
 
 PathDiagnosticPiece *NilReceiverBRVisitor::VisitNode(const ExplodedNode *N,
@@ -1076,18 +1076,20 @@
                                                      BugReport &BR) {
   Optional<PreStmt> P = N->getLocationAs<PreStmt>();
   if (!P)
-    return 0;
+    return nullptr;
 
   const Stmt *S = P->getStmt();
   const Expr *Receiver = getNilReceiver(S, N);
   if (!Receiver)
-    return 0;
+    return nullptr;
 
   llvm::SmallString<256> Buf;
   llvm::raw_svector_ostream OS(Buf);
 
   if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(S)) {
-    OS << "'" << ME->getSelector().getAsString() << "' not called";
+    OS << "'";
+    ME->getSelector().print(OS);
+    OS << "' not called";
   }
   else {
     OS << "No method is called";
@@ -1179,15 +1181,15 @@
   // were generated by the analyzer engine proper, not checkers.
   if (CurrentState->getGDM().getRoot() ==
       PrevState->getGDM().getRoot())
-    return 0;
-  
+    return nullptr;
+
   // If an assumption was made on a branch, it should be caught
   // here by looking at the state transition.
   if (Optional<BlockEdge> BE = progPoint.getAs<BlockEdge>()) {
     const CFGBlock *srcBlk = BE->getSrc();    
     if (const Stmt *term = srcBlk->getTerminator())
       return VisitTerminator(term, N, srcBlk, BE->getDst(), BR, BRC);
-    return 0;
+    return nullptr;
   }
   
   if (Optional<PostStmt> PS = progPoint.getAs<PostStmt>()) {
@@ -1204,11 +1206,11 @@
     if (tag == tags.second)
       return VisitTrueTest(cast<Expr>(PS->getStmt()), false,
                            BRC, BR, N);
-                           
-    return 0;
+
+    return nullptr;
   }
-    
-  return 0;
+
+  return nullptr;
 }
 
 PathDiagnosticPiece *
@@ -1218,11 +1220,11 @@
                                     const CFGBlock *dstBlk,
                                     BugReport &R,
                                     BugReporterContext &BRC) {
-  const Expr *Cond = 0;
-  
+  const Expr *Cond = nullptr;
+
   switch (Term->getStmtClass()) {
   default:
-    return 0;
+    return nullptr;
   case Stmt::IfStmtClass:
     Cond = cast<IfStmt>(Term)->getCond();
     break;
@@ -1250,7 +1252,7 @@
     Ex = Ex->IgnoreParenCasts();
     switch (Ex->getStmtClass()) {
       default:
-        return 0;
+        return nullptr;
       case Stmt::BinaryOperatorClass:
         return VisitTrueTest(Cond, cast<BinaryOperator>(Ex), tookTrue, BRC,
                              R, N);
@@ -1264,7 +1266,7 @@
           Ex = UO->getSubExpr();
           continue;
         }
-        return 0;
+        return nullptr;
       }
     }
   }
@@ -1283,13 +1285,13 @@
     if (quotes) {
       Out << '\'';
       const LocationContext *LCtx = N->getLocationContext();
-      const ProgramState *state = N->getState().getPtr();
+      const ProgramState *state = N->getState().get();
       if (const MemRegion *R = state->getLValue(cast<VarDecl>(DR->getDecl()),
                                                 LCtx).getAsRegion()) {
         if (report.isInteresting(R))
           prunable = false;
         else {
-          const ProgramState *state = N->getState().getPtr();
+          const ProgramState *state = N->getState().get();
           SVal V = state->getSVal(R);
           if (report.isInteresting(V))
             prunable = false;
@@ -1359,8 +1361,8 @@
   // both the LHS and RHS.
   if (LhsString.empty() || RhsString.empty() ||
       !BinaryOperator::isComparisonOp(Op))
-    return 0;
-  
+    return nullptr;
+
   // Should we invert the strings if the LHS is not a variable name?
   SmallString<256> buf;
   llvm::raw_svector_ostream Out(buf);
@@ -1385,7 +1387,7 @@
       case BO_LE: Op = BO_GT; break;
       case BO_GE: Op = BO_LT; break;
       default:
-        return 0;
+        return nullptr;
     }
   
   switch (Op) {
@@ -1435,7 +1437,7 @@
   else if (Ty->isIntegralOrEnumerationType())
     Out << (tookTrue ? "non-zero" : "zero");
   else
-    return 0;
+    return nullptr;
 
   const LocationContext *LCtx = N->getLocationContext();
   PathDiagnosticLocation Loc(CondVarExpr, BRC.getSourceManager(), LCtx);
@@ -1444,7 +1446,7 @@
 
   if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(CondVarExpr)) {
     if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
-      const ProgramState *state = N->getState().getPtr();
+      const ProgramState *state = N->getState().get();
       if (const MemRegion *R = state->getLValue(VD, LCtx).getAsRegion()) {
         if (report.isInteresting(R))
           event->setPrunable(false);
@@ -1465,8 +1467,8 @@
 
   const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl());
   if (!VD)
-    return 0;
-  
+    return nullptr;
+
   SmallString<256> Buf;
   llvm::raw_svector_ostream Out(Buf);
     
@@ -1481,14 +1483,14 @@
   else if (VDTy->isScalarType())
     Out << (tookTrue ? "not equal to 0" : "0");
   else
-    return 0;
-  
+    return nullptr;
+
   const LocationContext *LCtx = N->getLocationContext();
   PathDiagnosticLocation Loc(Cond, BRC.getSourceManager(), LCtx);
   PathDiagnosticEventPiece *event =
     new PathDiagnosticEventPiece(Loc, Out.str());
   
-  const ProgramState *state = N->getState().getPtr();
+  const ProgramState *state = N->getState().get();
   if (const MemRegion *R = state->getLValue(VD, LCtx).getAsRegion()) {
     if (report.isInteresting(R))
       event->setPrunable(false);
@@ -1512,7 +1514,7 @@
   while (const NamespaceDecl *Parent = dyn_cast<NamespaceDecl>(ND->getParent()))
     ND = Parent;
 
-  return ND->getName() == "std";
+  return ND->isStdNamespace();
 }
 
 
@@ -1532,8 +1534,8 @@
     // Note that this will not help for any other data structure libraries, like
     // TR1, Boost, or llvm/ADT.
     if (Options.shouldSuppressFromCXXStandardLibrary()) {
-      BR.markInvalid(getTag(), 0);
-      return 0;
+      BR.markInvalid(getTag(), nullptr);
+      return nullptr;
 
     } else {
       // If the the complete 'std' suppression is not enabled, suppress reports
@@ -1545,8 +1547,8 @@
       if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
         const CXXRecordDecl *CD = MD->getParent();
         if (CD->getName() == "list") {
-          BR.markInvalid(getTag(), 0);
-          return 0;
+          BR.markInvalid(getTag(), nullptr);
+          return nullptr;
         }
       }
 
@@ -1556,25 +1558,18 @@
       //   std::u16string s; s += u'a';
       // because we cannot reason about the internal invariants of the
       // datastructure.
-      const LocationContext *LCtx = N->getLocationContext();
-      do {
+      for (const LocationContext *LCtx = N->getLocationContext(); LCtx;
+           LCtx = LCtx->getParent()) {
         const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LCtx->getDecl());
         if (!MD)
-          break;
+          continue;
 
         const CXXRecordDecl *CD = MD->getParent();
         if (CD->getName() == "basic_string") {
-          BR.markInvalid(getTag(), 0);
-          return 0;
-        } else if (CD->getName().find("allocator") == StringRef::npos) {
-          // Only keep searching if the current method is in a class with the
-          // word "allocator" in its name, e.g. std::allocator or
-          // allocator_traits.
-          break;
+          BR.markInvalid(getTag(), nullptr);
+          return nullptr;
         }
-
-        LCtx = LCtx->getParent();
-      } while (LCtx);
+      }
     }
   }
 
@@ -1585,12 +1580,12 @@
   while (Loc.isMacroID()) {
     Loc = Loc.getSpellingLoc();
     if (SM.getFilename(Loc).endswith("sys/queue.h")) {
-      BR.markInvalid(getTag(), 0);
-      return 0;
+      BR.markInvalid(getTag(), nullptr);
+      return nullptr;
     }
   }
 
-  return 0;
+  return nullptr;
 }
 
 PathDiagnosticPiece *
@@ -1605,14 +1600,16 @@
   // We are only interested in visiting CallEnter nodes.
   Optional<CallEnter> CEnter = ProgLoc.getAs<CallEnter>();
   if (!CEnter)
-    return 0;
+    return nullptr;
 
   // Check if one of the arguments is the region the visitor is tracking.
   CallEventManager &CEMgr = BRC.getStateManager().getCallEventManager();
   CallEventRef<> Call = CEMgr.getCaller(CEnter->getCalleeContext(), State);
   unsigned Idx = 0;
-  for (CallEvent::param_iterator I = Call->param_begin(),
-                                 E = Call->param_end(); I != E; ++I, ++Idx) {
+  ArrayRef<ParmVarDecl*> parms = Call->parameters();
+
+  for (ArrayRef<ParmVarDecl*>::iterator I = parms.begin(), E = parms.end();
+                              I != E; ++I, ++Idx) {
     const MemRegion *ArgReg = Call->getArgSVal(Idx).getAsRegion();
 
     // Are we tracking the argument or its subregion?
@@ -1639,8 +1636,8 @@
     SVal BoundVal = State->getSVal(R);
     if (BoundVal.isUndef() || BoundVal.isZeroConstant()) {
       BR.markInteresting(CEnter->getCalleeContext());
-      return 0;
+      return nullptr;
     }
   }
-  return 0;
+  return nullptr;
 }
diff --git a/lib/StaticAnalyzer/Core/CMakeLists.txt b/lib/StaticAnalyzer/Core/CMakeLists.txt
index 013f8a5..59a6b6f 100644
--- a/lib/StaticAnalyzer/Core/CMakeLists.txt
+++ b/lib/StaticAnalyzer/Core/CMakeLists.txt
@@ -39,21 +39,11 @@
   Store.cpp
   SubEngine.cpp
   SymbolManager.cpp
-  )
 
-add_dependencies(clangStaticAnalyzerCore
-  ClangAttrClasses
-  ClangAttrList
-  ClangCommentNodes
-  ClangDeclNodes
-  ClangDiagnosticCommon
-  ClangStmtNodes
-  )
-
-target_link_libraries(clangStaticAnalyzerCore
+  LINK_LIBS
+  clangAST
+  clangAnalysis
   clangBasic
   clangLex
-  clangAST
-  clangFrontend
-  clangRewriteCore
+  clangRewrite
   )
diff --git a/lib/StaticAnalyzer/Core/CallEvent.cpp b/lib/StaticAnalyzer/Core/CallEvent.cpp
index a3b34f4..7e0670a 100644
--- a/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ b/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -68,8 +68,7 @@
 
   if (const RecordType *RT = T->getAsStructureType()) {
     const RecordDecl *RD = RT->getDecl();
-    for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
-         I != E; ++I) {
+    for (const auto *I : RD->fields()) {
       QualType FieldT = I->getType();
       if (FieldT->isBlockPointerType() || FieldT->isFunctionPointerType())
         return true;
@@ -140,6 +139,11 @@
                                              ProgramStateRef Orig) const {
   ProgramStateRef Result = (Orig ? Orig : getState());
 
+  // Don't invalidate anything if the callee is marked pure/const.
+  if (const Decl *callee = getDecl())
+    if (callee->hasAttr<PureAttr>() || callee->hasAttr<ConstAttr>())
+      return Result;
+
   SmallVector<SVal, 8> ValuesToInvalidate;
   RegionAndSymbolInvalidationTraits ETraits;
 
@@ -168,7 +172,7 @@
   return Result->invalidateRegions(ValuesToInvalidate, getOriginExpr(),
                                    BlockCount, getLocationContext(),
                                    /*CausedByPointerEscape*/ true,
-                                   /*Symbols=*/0, this, &ETraits);
+                                   /*Symbols=*/nullptr, this, &ETraits);
 }
 
 ProgramPoint CallEvent::getProgramPoint(bool IsPreVisit,
@@ -209,14 +213,12 @@
   return getSVal(E);
 }
 
-void CallEvent::dump() const {
-  dump(llvm::errs());
-}
+LLVM_DUMP_METHOD void CallEvent::dump() const { dump(llvm::errs()); }
 
 void CallEvent::dump(raw_ostream &Out) const {
   ASTContext &Ctx = getState()->getStateManager().getContext();
   if (const Expr *E = getOriginExpr()) {
-    E->printPretty(Out, 0, Ctx.getPrintingPolicy());
+    E->printPretty(Out, nullptr, Ctx.getPrintingPolicy());
     Out << "\n";
     return;
   }
@@ -241,9 +243,9 @@
 QualType CallEvent::getDeclaredResultType(const Decl *D) {
   assert(D);
   if (const FunctionDecl* FD = dyn_cast<FunctionDecl>(D))
-    return FD->getResultType();
+    return FD->getReturnType();
   if (const ObjCMethodDecl* MD = dyn_cast<ObjCMethodDecl>(D))
-    return MD->getResultType();
+    return MD->getReturnType();
   if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
     // Blocks are difficult because the return type may not be stored in the
     // BlockDecl itself. The AST should probably be enhanced, but for now we
@@ -256,7 +258,7 @@
     if (const TypeSourceInfo *TSI = BD->getSignatureAsWritten()) {
       QualType Ty = TSI->getType();
       if (const FunctionType *FT = Ty->getAs<FunctionType>())
-        Ty = FT->getResultType();
+        Ty = FT->getReturnType();
       if (!Ty->isDependentType())
         return Ty;
     }
@@ -284,14 +286,14 @@
                                          CallEvent::BindingsTy &Bindings,
                                          SValBuilder &SVB,
                                          const CallEvent &Call,
-                                         CallEvent::param_iterator I,
-                                         CallEvent::param_iterator E) {
+                                         ArrayRef<ParmVarDecl*> parameters) {
   MemRegionManager &MRMgr = SVB.getRegionManager();
 
   // If the function has fewer parameters than the call has arguments, we simply
   // do not bind any values to them.
   unsigned NumArgs = Call.getNumArgs();
   unsigned Idx = 0;
+  ArrayRef<ParmVarDecl*>::iterator I = parameters.begin(), E = parameters.end();
   for (; I != E && Idx < NumArgs; ++I, ++Idx) {
     const ParmVarDecl *ParamDecl = *I;
     assert(ParamDecl && "Formal parameter has no decl?");
@@ -306,21 +308,11 @@
   // FIXME: Variadic arguments are not handled at all right now.
 }
 
-
-CallEvent::param_iterator AnyFunctionCall::param_begin() const {
+ArrayRef<ParmVarDecl*> AnyFunctionCall::parameters() const {
   const FunctionDecl *D = getDecl();
   if (!D)
-    return 0;
-
-  return D->param_begin();
-}
-
-CallEvent::param_iterator AnyFunctionCall::param_end() const {
-  const FunctionDecl *D = getDecl();
-  if (!D)
-    return 0;
-
-  return D->param_end();
+    return None;
+  return D->parameters();
 }
 
 void AnyFunctionCall::getInitialStackFrameContents(
@@ -329,7 +321,7 @@
   const FunctionDecl *D = cast<FunctionDecl>(CalleeCtx->getDecl());
   SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
   addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this,
-                               D->param_begin(), D->param_end());
+                               D->parameters());
 }
 
 bool AnyFunctionCall::argumentsMayEscape() const {
@@ -389,7 +381,7 @@
 }
 
 
-const FunctionDecl *SimpleCall::getDecl() const {
+const FunctionDecl *SimpleFunctionCall::getDecl() const {
   const FunctionDecl *D = getOriginExpr()->getDirectCallee();
   if (D)
     return D;
@@ -484,7 +476,7 @@
   // that ExprEngine can decide what to do with it.
   if (DynType.canBeASubClass())
     return RuntimeDefinition(Definition, R->StripCasts());
-  return RuntimeDefinition(Definition, /*DispatchRegion=*/0);
+  return RuntimeDefinition(Definition, /*DispatchRegion=*/nullptr);
 }
 
 void CXXInstanceCall::getInitialStackFrameContents(
@@ -550,18 +542,11 @@
   return dyn_cast_or_null<BlockDataRegion>(DataReg);
 }
 
-CallEvent::param_iterator BlockCall::param_begin() const {
-  const BlockDecl *D = getBlockDecl();
+ArrayRef<ParmVarDecl*> BlockCall::parameters() const {
+  const BlockDecl *D = getDecl();
   if (!D)
-    return 0;
-  return D->param_begin();
-}
-
-CallEvent::param_iterator BlockCall::param_end() const {
-  const BlockDecl *D = getBlockDecl();
-  if (!D)
-    return 0;
-  return D->param_end();
+    return nullptr;
+  return D->parameters();
 }
 
 void BlockCall::getExtraInvalidatedValues(ValueList &Values) const {
@@ -575,7 +560,7 @@
   const BlockDecl *D = cast<BlockDecl>(CalleeCtx->getDecl());
   SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
   addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this,
-                               D->param_begin(), D->param_end());
+                               D->parameters());
 }
 
 
@@ -604,8 +589,6 @@
   }
 }
 
-
-
 SVal CXXDestructorCall::getCXXThisVal() const {
   if (Data)
     return loc::MemRegionVal(DtorDataTy::getFromOpaqueValue(Data).getPointer());
@@ -621,21 +604,11 @@
   return CXXInstanceCall::getRuntimeDefinition();
 }
 
-
-CallEvent::param_iterator ObjCMethodCall::param_begin() const {
+ArrayRef<ParmVarDecl*> ObjCMethodCall::parameters() const {
   const ObjCMethodDecl *D = getDecl();
   if (!D)
-    return 0;
-
-  return D->param_begin();
-}
-
-CallEvent::param_iterator ObjCMethodCall::param_end() const {
-  const ObjCMethodDecl *D = getDecl();
-  if (!D)
-    return 0;
-
-  return D->param_end();
+    return ArrayRef<ParmVarDecl*>();
+  return D->parameters();
 }
 
 void
@@ -694,13 +667,13 @@
 typedef llvm::PointerIntPair<const PseudoObjectExpr *, 2> ObjCMessageDataTy;
 
 const PseudoObjectExpr *ObjCMethodCall::getContainingPseudoObjectExpr() const {
-  assert(Data != 0 && "Lazy lookup not yet performed.");
+  assert(Data && "Lazy lookup not yet performed.");
   assert(getMessageKind() != OCM_Message && "Explicit message send.");
   return ObjCMessageDataTy::getFromOpaqueValue(Data).getPointer();
 }
 
 ObjCMessageKind ObjCMethodCall::getMessageKind() const {
-  if (Data == 0) {
+  if (!Data) {
 
     // Find the parent, ignoring implicit casts.
     ParentMap &PM = getLocationContext()->getParentMap();
@@ -738,7 +711,7 @@
     }
     
     const_cast<ObjCMethodCall *>(this)->Data
-      = ObjCMessageDataTy(0, 1).getOpaqueValue();
+      = ObjCMessageDataTy(nullptr, 1).getOpaqueValue();
     assert(getMessageKind() == OCM_Message);
     return OCM_Message;
   }
@@ -774,7 +747,7 @@
 
   // Find the first declaration in the class hierarchy that declares
   // the selector.
-  ObjCMethodDecl *D = 0;
+  ObjCMethodDecl *D = nullptr;
   while (true) {
     D = IDecl->lookupMethod(Sel, true);
 
@@ -813,10 +786,10 @@
   if (E->isInstanceMessage()) {
 
     // Find the the receiver type.
-    const ObjCObjectPointerType *ReceiverT = 0;
+    const ObjCObjectPointerType *ReceiverT = nullptr;
     bool CanBeSubClassed = false;
     QualType SupersType = E->getSuperType();
-    const MemRegion *Receiver = 0;
+    const MemRegion *Receiver = nullptr;
 
     if (!SupersType.isNull()) {
       // Super always means the type of immediate predecessor to the method
@@ -865,14 +838,22 @@
         Optional<const ObjCMethodDecl *> &Val = PMC[std::make_pair(IDecl, Sel)];
 
         // Query lookupPrivateMethod() if the cache does not hit.
-        if (!Val.hasValue())
+        if (!Val.hasValue()) {
           Val = IDecl->lookupPrivateMethod(Sel);
 
+          // If the method is a property accessor, we should try to "inline" it
+          // even if we don't actually have an implementation.
+          if (!*Val)
+            if (const ObjCMethodDecl *CompileTimeMD = E->getMethodDecl())
+              if (CompileTimeMD->isPropertyAccessor())
+                Val = IDecl->lookupInstanceMethod(Sel);
+        }
+
         const ObjCMethodDecl *MD = Val.getValue();
         if (CanBeSubClassed)
           return RuntimeDefinition(MD, Receiver);
         else
-          return RuntimeDefinition(MD, 0);
+          return RuntimeDefinition(MD, nullptr);
       }
 
   } else {
@@ -888,13 +869,24 @@
   return RuntimeDefinition();
 }
 
+bool ObjCMethodCall::argumentsMayEscape() const {
+  if (isInSystemHeader() && !isInstanceMessage()) {
+    Selector Sel = getSelector();
+    if (Sel.getNumArgs() == 1 &&
+        Sel.getIdentifierInfoForSlot(0)->isStr("valueWithPointer"))
+      return true;
+  }
+
+  return CallEvent::argumentsMayEscape();
+}
+
 void ObjCMethodCall::getInitialStackFrameContents(
                                              const StackFrameContext *CalleeCtx,
                                              BindingsTy &Bindings) const {
   const ObjCMethodDecl *D = cast<ObjCMethodDecl>(CalleeCtx->getDecl());
   SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
   addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this,
-                               D->param_begin(), D->param_end());
+                               D->parameters());
 
   SVal SelfVal = getReceiverSVal();
   if (!SelfVal.isUnknown()) {
@@ -923,7 +915,7 @@
 
   // Otherwise, it's a normal function call, static member function call, or
   // something we can't reason about.
-  return create<FunctionCall>(CE, State, LCtx);
+  return create<SimpleFunctionCall>(CE, State, LCtx);
 }
 
 
diff --git a/lib/StaticAnalyzer/Core/Checker.cpp b/lib/StaticAnalyzer/Core/Checker.cpp
index 07e0aac..1a3965a 100644
--- a/lib/StaticAnalyzer/Core/Checker.cpp
+++ b/lib/StaticAnalyzer/Core/Checker.cpp
@@ -18,8 +18,23 @@
 using namespace ento;
 
 StringRef CheckerBase::getTagDescription() const {
-  // FIXME: We want to return the package + name of the checker here.
-  return "A Checker";  
+  return getCheckName().getName();
+}
+
+CheckName CheckerBase::getCheckName() const { return Name; }
+
+CheckerProgramPointTag::CheckerProgramPointTag(StringRef CheckerName, 
+                                               StringRef Msg)
+  : SimpleProgramPointTag(CheckerName, Msg) {}
+
+CheckerProgramPointTag::CheckerProgramPointTag(const CheckerBase *Checker,
+                                               StringRef Msg)
+  : SimpleProgramPointTag(Checker->getCheckName().getName(), Msg) {}
+
+raw_ostream& clang::ento::operator<<(raw_ostream &Out,
+                                     const CheckerBase &Checker) {
+  Out << Checker.getCheckName().getName();
+  return Out;
 }
 
 void Checker<check::_VoidCheck, check::_VoidCheck, check::_VoidCheck,
diff --git a/lib/StaticAnalyzer/Core/CheckerManager.cpp b/lib/StaticAnalyzer/Core/CheckerManager.cpp
index c1ae7e9..2684cc7 100644
--- a/lib/StaticAnalyzer/Core/CheckerManager.cpp
+++ b/lib/StaticAnalyzer/Core/CheckerManager.cpp
@@ -58,7 +58,7 @@
   assert(D);
 
   unsigned DeclKind = D->getKind();
-  CachedDeclCheckers *checkers = 0;
+  CachedDeclCheckers *checkers = nullptr;
   CachedDeclCheckersMapTy::iterator CCI = CachedDeclCheckersMap.find(DeclKind);
   if (CCI != CachedDeclCheckersMap.end()) {
     checkers = &(CCI->second);
@@ -109,7 +109,7 @@
   const ExplodedNodeSet *PrevSet = &Src;
 
   for (; I != E; ++I) {
-    ExplodedNodeSet *CurrSet = 0;
+    ExplodedNodeSet *CurrSet = nullptr;
     if (I+1 == E)
       CurrSet = &Dst;
     else {
@@ -477,7 +477,7 @@
     // If any checker declares the state infeasible (or if it starts that way),
     // bail out.
     if (!state)
-      return NULL;
+      return nullptr;
     state = RegionChangesCheckers[i].CheckFn(state, invalidated, 
                                              ExplicitRegions, Regions, Call);
   }
@@ -491,7 +491,7 @@
                                    const CallEvent *Call,
                                    PointerEscapeKind Kind,
                                    RegionAndSymbolInvalidationTraits *ETraits) {
-  assert((Call != NULL ||
+  assert((Call != nullptr ||
           (Kind != PSK_DirectEscapeOnCall &&
            Kind != PSK_IndirectEscapeOnCall)) &&
          "Call must not be NULL when escaping on call");
@@ -499,7 +499,7 @@
       // If any checker declares the state infeasible (or if it starts that
       //  way), bail out.
       if (!State)
-        return NULL;
+        return nullptr;
       State = PointerEscapeCheckers[i](State, Escaped, Call, Kind, ETraits);
     }
   return State;
@@ -513,7 +513,7 @@
     // If any checker declares the state infeasible (or if it starts that way),
     // bail out.
     if (!state)
-      return NULL;
+      return nullptr;
     state = EvalAssumeCheckers[i](state, Cond, Assumption);
   }
   return state;
diff --git a/lib/StaticAnalyzer/Core/CheckerRegistry.cpp b/lib/StaticAnalyzer/Core/CheckerRegistry.cpp
index 4729903..b64e30b 100644
--- a/lib/StaticAnalyzer/Core/CheckerRegistry.cpp
+++ b/lib/StaticAnalyzer/Core/CheckerRegistry.cpp
@@ -45,7 +45,7 @@
                             const llvm::StringMap<size_t> &packageSizes,
                             CheckerOptInfo &opt, CheckerInfoSet &collected) {
   // Use a binary search to find the possible start of the package.
-  CheckerRegistry::CheckerInfo packageInfo(NULL, opt.getName(), "");
+  CheckerRegistry::CheckerInfo packageInfo(nullptr, opt.getName(), "");
   CheckerRegistry::CheckerInfoList::const_iterator e = checkers.end();
   CheckerRegistry::CheckerInfoList::const_iterator i =
     std::lower_bound(checkers.begin(), e, packageInfo, checkerNameLT);
@@ -84,10 +84,10 @@
 
   // Record the presence of the checker in its packages.
   StringRef packageName, leafName;
-  llvm::tie(packageName, leafName) = name.rsplit(PackageSeparator);
+  std::tie(packageName, leafName) = name.rsplit(PackageSeparator);
   while (!leafName.empty()) {
     Packages[packageName] += 1;
-    llvm::tie(packageName, leafName) = packageName.rsplit(PackageSeparator);
+    std::tie(packageName, leafName) = packageName.rsplit(PackageSeparator);
   }
 }
 
@@ -106,6 +106,7 @@
   // Initialize the CheckerManager with all enabled checkers.
   for (CheckerInfoSet::iterator
          i = enabledCheckers.begin(), e = enabledCheckers.end(); i != e; ++i) {
+    checkerMgr.setCurrentCheckName(CheckName((*i)->FullName));
     (*i)->Initialize(checkerMgr);
   }
 }
diff --git a/lib/StaticAnalyzer/Core/CoreEngine.cpp b/lib/StaticAnalyzer/Core/CoreEngine.cpp
index b09b2c2..4623c35 100644
--- a/lib/StaticAnalyzer/Core/CoreEngine.cpp
+++ b/lib/StaticAnalyzer/Core/CoreEngine.cpp
@@ -12,8 +12,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#define DEBUG_TYPE "CoreEngine"
-
 #include "clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/StmtCXX.h"
@@ -26,6 +24,8 @@
 using namespace clang;
 using namespace ento;
 
+#define DEBUG_TYPE "CoreEngine"
+
 STATISTIC(NumSteps,
             "The # of steps executed.");
 STATISTIC(NumReachedMaxSteps,
@@ -43,22 +43,22 @@
 class DFS : public WorkList {
   SmallVector<WorkListUnit,20> Stack;
 public:
-  virtual bool hasWork() const {
+  bool hasWork() const override {
     return !Stack.empty();
   }
 
-  virtual void enqueue(const WorkListUnit& U) {
+  void enqueue(const WorkListUnit& U) override {
     Stack.push_back(U);
   }
 
-  virtual WorkListUnit dequeue() {
+  WorkListUnit dequeue() override {
     assert (!Stack.empty());
     const WorkListUnit& U = Stack.back();
     Stack.pop_back(); // This technically "invalidates" U, but we are fine.
     return U;
   }
-  
-  virtual bool visitItemsInWorkList(Visitor &V) {
+
+  bool visitItemsInWorkList(Visitor &V) override {
     for (SmallVectorImpl<WorkListUnit>::iterator
          I = Stack.begin(), E = Stack.end(); I != E; ++I) {
       if (V.visit(*I))
@@ -71,21 +71,21 @@
 class BFS : public WorkList {
   std::deque<WorkListUnit> Queue;
 public:
-  virtual bool hasWork() const {
+  bool hasWork() const override {
     return !Queue.empty();
   }
 
-  virtual void enqueue(const WorkListUnit& U) {
+  void enqueue(const WorkListUnit& U) override {
     Queue.push_back(U);
   }
 
-  virtual WorkListUnit dequeue() {
+  WorkListUnit dequeue() override {
     WorkListUnit U = Queue.front();
     Queue.pop_front();
     return U;
   }
-  
-  virtual bool visitItemsInWorkList(Visitor &V) {
+
+  bool visitItemsInWorkList(Visitor &V) override {
     for (std::deque<WorkListUnit>::iterator
          I = Queue.begin(), E = Queue.end(); I != E; ++I) {
       if (V.visit(*I))
@@ -109,18 +109,18 @@
     std::deque<WorkListUnit> Queue;
     SmallVector<WorkListUnit,20> Stack;
   public:
-    virtual bool hasWork() const {
+    bool hasWork() const override {
       return !Queue.empty() || !Stack.empty();
     }
 
-    virtual void enqueue(const WorkListUnit& U) {
+    void enqueue(const WorkListUnit& U) override {
       if (U.getNode()->getLocation().getAs<BlockEntrance>())
         Queue.push_front(U);
       else
         Stack.push_back(U);
     }
 
-    virtual WorkListUnit dequeue() {
+    WorkListUnit dequeue() override {
       // Process all basic blocks to completion.
       if (!Stack.empty()) {
         const WorkListUnit& U = Stack.back();
@@ -135,7 +135,7 @@
       Queue.pop_front();
       return U;
     }
-    virtual bool visitItemsInWorkList(Visitor &V) {
+    bool visitItemsInWorkList(Visitor &V) override {
       for (SmallVectorImpl<WorkListUnit>::iterator
            I = Stack.begin(), E = Stack.end(); I != E; ++I) {
         if (V.visit(*I))
@@ -192,9 +192,9 @@
 
     if (!InitState)
       // Generate the root.
-      generateNode(StartLoc, SubEng.getInitialState(L), 0);
+      generateNode(StartLoc, SubEng.getInitialState(L), nullptr);
     else
-      generateNode(StartLoc, InitState, 0);
+      generateNode(StartLoc, InitState, nullptr);
   }
 
   // Check if we have a steps limit
@@ -532,11 +532,16 @@
     return;
   }
 
+  if ((*Block)[Idx].getKind() == CFGElement::NewAllocator) {
+    WList->enqueue(N, Block, Idx+1);
+    return;
+  }
+
   // At this point, we know we're processing a normal statement.
   CFGStmt CS = (*Block)[Idx].castAs<CFGStmt>();
   PostStmt Loc(CS.getStmt(), N->getLocationContext());
 
-  if (Loc == N->getLocation()) {
+  if (Loc == N->getLocation().withTag(nullptr)) {
     // Note: 'N' should be a fresh node because otherwise it shouldn't be
     // a member of Deferred.
     WList->enqueue(N, Block, Idx+1);
@@ -562,7 +567,7 @@
   bool isNew;
   ExplodedNode *Node = G->getNode(Loc, N->getState(), false, &isNew);
   Node->addPredecessor(N, *G);
-  return isNew ? Node : 0;
+  return isNew ? Node : nullptr;
 }
 
 
@@ -611,7 +616,7 @@
   Frontier.erase(FromN);
 
   if (!IsNew)
-    return 0;
+    return nullptr;
 
   if (!MarkAsSink)
     Frontier.Add(N);
@@ -635,7 +640,7 @@
                                               ExplodedNode *NodePred) {
   // If the branch has been marked infeasible we should not generate a node.
   if (!isFeasible(branch))
-    return NULL;
+    return nullptr;
 
   ProgramPoint Loc = BlockEdge(C.Block, branch ? DstT:DstF,
                                NodePred->getLocationContext());
@@ -654,7 +659,7 @@
   Succ->addPredecessor(Pred, *Eng.G);
 
   if (!IsNew)
-    return 0;
+    return nullptr;
 
   if (!IsSink)
     Eng.WList->enqueue(Succ);
@@ -673,7 +678,7 @@
                                       false, &IsNew);
   Succ->addPredecessor(Pred, *Eng.G);
   if (!IsNew)
-    return 0;
+    return nullptr;
 
   Eng.WList->enqueue(Succ);
   return Succ;
@@ -690,8 +695,8 @@
   // Sanity check for default blocks that are unreachable and not caught
   // by earlier stages.
   if (!DefaultBlock)
-    return NULL;
-  
+    return nullptr;
+
   bool IsNew;
   ExplodedNode *Succ = Eng.G->getNode(BlockEdge(Src, DefaultBlock,
                                       Pred->getLocationContext()), St,
@@ -699,7 +704,7 @@
   Succ->addPredecessor(Pred, *Eng.G);
 
   if (!IsNew)
-    return 0;
+    return nullptr;
 
   if (!IsSink)
     Eng.WList->enqueue(Succ);
diff --git a/lib/StaticAnalyzer/Core/Environment.cpp b/lib/StaticAnalyzer/Core/Environment.cpp
index 7b133f6..ae5a4cc 100644
--- a/lib/StaticAnalyzer/Core/Environment.cpp
+++ b/lib/StaticAnalyzer/Core/Environment.cpp
@@ -54,7 +54,8 @@
 EnvironmentEntry::EnvironmentEntry(const Stmt *S, const LocationContext *L)
   : std::pair<const Stmt *,
               const StackFrameContext *>(ignoreTransparentExprs(S),
-                                         L ? L->getCurrentStackFrame() : 0) {}
+                                         L ? L->getCurrentStackFrame()
+                                           : nullptr) {}
 
 SVal Environment::lookupExpr(const EnvironmentEntry &E) const {
   const SVal* X = ExprBindings.lookup(E);
@@ -123,11 +124,11 @@
   SymbolReaper &SymReaper;
 public:
   MarkLiveCallback(SymbolReaper &symreaper) : SymReaper(symreaper) {}
-  bool VisitSymbol(SymbolRef sym) {
+  bool VisitSymbol(SymbolRef sym) override {
     SymReaper.markLive(sym);
     return true;
   }
-  bool VisitMemRegion(const MemRegion *R) {
+  bool VisitMemRegion(const MemRegion *R) override {
     SymReaper.markLive(R);
     return true;
   }
@@ -204,11 +205,12 @@
     }
     
     const Stmt *S = En.getStmt();
-    
+    assert(S != nullptr && "Expected non-null Stmt");
+
     Out << " (" << (const void*) En.getLocationContext() << ','
       << (const void*) S << ") ";
     LangOptions LO; // FIXME.
-    S->printPretty(Out, 0, PrintingPolicy(LO));
+    S->printPretty(Out, nullptr, PrintingPolicy(LO));
     Out << " : " << I.getData();
   }
 }
diff --git a/lib/StaticAnalyzer/Core/ExplodedGraph.cpp b/lib/StaticAnalyzer/Core/ExplodedGraph.cpp
index e9c4a35..1c9a282 100644
--- a/lib/StaticAnalyzer/Core/ExplodedGraph.cpp
+++ b/lib/StaticAnalyzer/Core/ExplodedGraph.cpp
@@ -34,7 +34,7 @@
 ExplodedNode::Auditor::~Auditor() {}
 
 #ifndef NDEBUG
-static ExplodedNode::Auditor* NodeAuditor = 0;
+static ExplodedNode::Auditor* NodeAuditor = nullptr;
 #endif
 
 void ExplodedNode::SetAuditor(ExplodedNode::Auditor* A) {
@@ -90,8 +90,9 @@
   // (7) The LocationContext is the same as the predecessor.
   // (8) Expressions that are *not* lvalue expressions.
   // (9) The PostStmt isn't for a non-consumed Stmt or Expr.
-  // (10) The successor is not a CallExpr StmtPoint (so that we would
-  //      be able to find it when retrying a call with no inlining).
+  // (10) The successor is neither a CallExpr StmtPoint nor a CallEnter or 
+  //      PreImplicitCall (so that we would be able to find it when retrying a 
+  //      call with no inlining).
   // FIXME: It may be safe to reclaim PreCall and PostCall nodes as well.
 
   // Conditions 1 and 2.
@@ -153,6 +154,10 @@
     if (CallEvent::isCallStmt(SP->getStmt()))
       return false;
 
+  // Condition 10, continuation.
+  if (SuccLoc.getAs<CallEnter>() || SuccLoc.getAs<PreImplicitCall>())
+    return false;
+
   return true;
 }
 
@@ -271,11 +276,11 @@
 
 ExplodedNode * const *ExplodedNode::NodeGroup::begin() const {
   if (getFlag())
-    return 0;
+    return nullptr;
 
   const GroupStorage &Storage = reinterpret_cast<const GroupStorage &>(P);
   if (Storage.isNull())
-    return 0;
+    return nullptr;
   if (ExplodedNodeVector *V = Storage.dyn_cast<ExplodedNodeVector *>())
     return V->begin();
   return Storage.getAddrOfPtr1();
@@ -283,11 +288,11 @@
 
 ExplodedNode * const *ExplodedNode::NodeGroup::end() const {
   if (getFlag())
-    return 0;
+    return nullptr;
 
   const GroupStorage &Storage = reinterpret_cast<const GroupStorage &>(P);
   if (Storage.isNull())
-    return 0;
+    return nullptr;
   if (ExplodedNodeVector *V = Storage.dyn_cast<ExplodedNodeVector *>())
     return V->end();
   return Storage.getAddrOfPtr1() + 1;
@@ -299,7 +304,7 @@
                                      bool* IsNew) {
   // Profile 'State' to determine if we already have an existing node.
   llvm::FoldingSetNodeID profile;
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
 
   NodeTy::Profile(profile, L, State, IsSink);
   NodeTy* V = Nodes.FindNodeOrInsertPos(profile, InsertPos);
@@ -337,7 +342,7 @@
                     InterExplodedGraphMap *InverseMap) const{
 
   if (Nodes.empty())
-    return 0;
+    return nullptr;
 
   typedef llvm::DenseSet<const ExplodedNode*> Pass1Ty;
   Pass1Ty Pass1;
@@ -380,7 +385,7 @@
 
   // We didn't hit a root? Return with a null pointer for the new graph.
   if (WL2.empty())
-    return 0;
+    return nullptr;
 
   // Create an empty graph.
   ExplodedGraph* G = MakeEmptyGraph();
@@ -395,7 +400,8 @@
 
     // Create the corresponding node in the new graph and record the mapping
     // from the old node to the new node.
-    ExplodedNode *NewN = G->getNode(N->getLocation(), N->State, N->isSink(), 0);
+    ExplodedNode *NewN = G->getNode(N->getLocation(), N->State, N->isSink(),
+                                    nullptr);
     Pass2[N] = NewN;
 
     // Also record the reverse mapping from the new node to the old node.
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 411e2f6..4e4095c 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -13,8 +13,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#define DEBUG_TYPE "ExprEngine"
-
 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
 #include "PrettyStackTraceLocationContext.h"
 #include "clang/AST/CharUnits.h"
@@ -40,6 +38,8 @@
 using namespace ento;
 using llvm::APSInt;
 
+#define DEBUG_TYPE "ExprEngine"
+
 STATISTIC(NumRemoveDeadBindings,
             "The # of times RemoveDeadBindings is called");
 STATISTIC(NumMaxBlockCountReached,
@@ -55,6 +55,8 @@
 // Engine construction and deletion.
 //===----------------------------------------------------------------------===//
 
+static const char* TagProviderName = "ExprEngine";
+
 ExprEngine::ExprEngine(AnalysisManager &mgr, bool gcEnabled,
                        SetOfConstDecls *VisitedCalleesIn,
                        FunctionSummariesTy *FS,
@@ -68,7 +70,7 @@
              this),
     SymMgr(StateMgr.getSymbolManager()),
     svalBuilder(StateMgr.getSValBuilder()),
-    currStmtIdx(0), currBldrCtx(0),
+    currStmtIdx(0), currBldrCtx(nullptr),
     ObjCNoRet(mgr.getASTContext()),
     ObjCGCEnabled(gcEnabled), BR(mgr, *this),
     VisitedCallees(VisitedCalleesIn),
@@ -118,7 +120,7 @@
       SVal V = state->getSVal(loc::MemRegionVal(R));
       SVal Constraint_untested = evalBinOp(state, BO_GT, V,
                                            svalBuilder.makeZeroVal(T),
-                                           getContext().IntTy);
+                                           svalBuilder.getConditionType());
 
       Optional<DefinedOrUnknownSVal> Constraint =
           Constraint_untested.getAs<DefinedOrUnknownSVal>();
@@ -153,7 +155,7 @@
       // top-level function.  This is our starting assumption for
       // analyzing an "open" program.
       const StackFrameContext *SFC = InitLoc->getCurrentStackFrame();
-      if (SFC->getParent() == 0) {
+      if (SFC->getParent() == nullptr) {
         loc::MemRegionVal L = svalBuilder.getCXXThis(MD, SFC);
         SVal V = state->getSVal(L);
         if (Optional<Loc> LV = V.getAs<Loc>()) {
@@ -209,7 +211,7 @@
 
   // Create a temporary object region for the inner expression (which may have
   // a more derived type) and bind the value into it.
-  const TypedValueRegion *TR = NULL;
+  const TypedValueRegion *TR = nullptr;
   if (const MaterializeTemporaryExpr *MT =
           dyn_cast<MaterializeTemporaryExpr>(Result)) {
     StorageDuration SD = MT->getStorageDuration();
@@ -286,6 +288,10 @@
     case CFGElement::Initializer:
       ProcessInitializer(E.castAs<CFGInitializer>().getInitializer(), Pred);
       return;
+    case CFGElement::NewAllocator:
+      ProcessNewAllocator(E.castAs<CFGNewAllocator>().getAllocatorExpr(),
+                          Pred);
+      return;
     case CFGElement::AutomaticObjectDtor:
     case CFGElement::DeleteDtor:
     case CFGElement::BaseDtor:
@@ -329,7 +335,7 @@
                             const Stmt *DiagnosticStmt,
                             ProgramPoint::Kind K) {
   assert((K == ProgramPoint::PreStmtPurgeDeadSymbolsKind ||
-          ReferenceStmt == 0 || isa<ReturnStmt>(ReferenceStmt))
+          ReferenceStmt == nullptr || isa<ReturnStmt>(ReferenceStmt))
           && "PostStmt is not generally supported by the SymbolReaper yet");
   assert(LC && "Must pass the current (or expiring) LocationContext");
 
@@ -350,7 +356,7 @@
     LC = LC->getParent();
   }
 
-  const StackFrameContext *SFC = LC ? LC->getCurrentStackFrame() : 0;
+  const StackFrameContext *SFC = LC ? LC->getCurrentStackFrame() : nullptr;
   SymbolReaper SymReaper(SFC, ReferenceStmt, SymMgr, getStoreManager());
 
   getCheckerManager().runCheckersForLiveSymbols(CleanedState, SymReaper);
@@ -362,7 +368,7 @@
 
   // Process any special transfer function for dead symbols.
   // A tag to track convenience transitions, which can be removed at cleanup.
-  static SimpleProgramPointTag cleanupTag("ExprEngine : Clean Node");
+  static SimpleProgramPointTag cleanupTag(TagProviderName, "Clean Node");
   if (!SymReaper.hasDeadSymbols()) {
     // Generate a CleanedNode that has the environment and store cleaned
     // up. Since no symbols are dead, we can optimize and not clean out
@@ -547,6 +553,25 @@
   Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx);
 }
 
+void ExprEngine::ProcessNewAllocator(const CXXNewExpr *NE,
+                                     ExplodedNode *Pred) {
+  ExplodedNodeSet Dst;
+  AnalysisManager &AMgr = getAnalysisManager();
+  AnalyzerOptions &Opts = AMgr.options;
+  // TODO: We're not evaluating allocators for all cases just yet as
+  // we're not handling the return value correctly, which causes false
+  // positives when the alpha.cplusplus.NewDeleteLeaks check is on.
+  if (Opts.mayInlineCXXAllocator())
+    VisitCXXNewAllocatorCall(NE, Pred, Dst);
+  else {
+    NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
+    const LocationContext *LCtx = Pred->getLocationContext();
+    PostImplicitCall PP(NE->getOperatorNew(), NE->getLocStart(), LCtx);
+    Bldr.generateNode(PP, Pred->getState(), Pred);
+  }
+  Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx);
+}
+
 void ExprEngine::ProcessAutomaticObjDtor(const CFGAutomaticObjDtor Dtor,
                                          ExplodedNode *Pred,
                                          ExplodedNodeSet &Dst) {
@@ -598,7 +623,6 @@
 void ExprEngine::ProcessBaseDtor(const CFGBaseDtor D,
                                  ExplodedNode *Pred, ExplodedNodeSet &Dst) {
   const LocationContext *LCtx = Pred->getLocationContext();
-  ProgramStateRef State = Pred->getState();
 
   const CXXDestructorDecl *CurDtor = cast<CXXDestructorDecl>(LCtx->getDecl());
   Loc ThisPtr = getSValBuilder().getCXXThis(CurDtor,
@@ -640,7 +664,7 @@
 
   // FIXME: Inlining of temporary destructors is not supported yet anyway, so we
   // just put a NULL region for now. This will need to be changed later.
-  VisitCXXDestructor(varType, NULL, D.getBindTemporaryExpr(),
+  VisitCXXDestructor(varType, nullptr, D.getBindTemporaryExpr(),
                      /*IsBase=*/ false, Pred, Dst);
 }
 
@@ -664,8 +688,6 @@
     case Stmt::MSPropertyRefExprClass:
     case Stmt::CXXUnresolvedConstructExprClass:
     case Stmt::DependentScopeDeclRefExprClass:
-    case Stmt::UnaryTypeTraitExprClass:
-    case Stmt::BinaryTypeTraitExprClass:
     case Stmt::TypeTraitExprClass:
     case Stmt::ArrayTypeTraitExprClass:
     case Stmt::ExpressionTraitExprClass:
@@ -677,6 +699,7 @@
     case Stmt::FunctionParmPackExprClass:
     case Stmt::SEHTryStmtClass:
     case Stmt::SEHExceptStmtClass:
+    case Stmt::SEHLeaveStmtClass:
     case Stmt::LambdaExprClass:
     case Stmt::SEHFinallyStmtClass: {
       const ExplodedNode *node = Bldr.generateSink(S, Pred, Pred->getState());
@@ -709,6 +732,20 @@
     case Expr::MSDependentExistsStmtClass:
     case Stmt::CapturedStmtClass:
     case Stmt::OMPParallelDirectiveClass:
+    case Stmt::OMPSimdDirectiveClass:
+    case Stmt::OMPForDirectiveClass:
+    case Stmt::OMPSectionsDirectiveClass:
+    case Stmt::OMPSectionDirectiveClass:
+    case Stmt::OMPSingleDirectiveClass:
+    case Stmt::OMPMasterDirectiveClass:
+    case Stmt::OMPCriticalDirectiveClass:
+    case Stmt::OMPParallelForDirectiveClass:
+    case Stmt::OMPParallelSectionsDirectiveClass:
+    case Stmt::OMPTaskDirectiveClass:
+    case Stmt::OMPTaskyieldDirectiveClass:
+    case Stmt::OMPBarrierDirectiveClass:
+    case Stmt::OMPTaskwaitDirectiveClass:
+    case Stmt::OMPFlushDirectiveClass:
       llvm_unreachable("Stmt should not be in analyzer evaluation loop");
 
     case Stmt::ObjCSubscriptRefExprClass:
@@ -848,7 +885,8 @@
            it != et; ++it) {      
         ExplodedNode *N = *it;
         const LocationContext *LCtx = N->getLocationContext();
-        SVal result = svalBuilder.conjureSymbolVal(0, Ex, LCtx, resultType,
+        SVal result = svalBuilder.conjureSymbolVal(nullptr, Ex, LCtx,
+                                                   resultType,
                                                    currBldrCtx->blockCount());
         ProgramStateRef state = N->getState()->BindExpr(Ex, LCtx, result);
         Bldr2.generateNode(S, N, state);
@@ -928,7 +966,7 @@
           ProgramStateRef NewState =
             createTemporaryRegionIfNeeded(State, LCtx, OCE->getArg(0));
           if (NewState != State) {
-            Pred = Bldr.generateNode(OCE, Pred, NewState, /*Tag=*/0,
+            Pred = Bldr.generateNode(OCE, Pred, NewState, /*Tag=*/nullptr,
                                      ProgramPoint::PreStmtKind);
             // Did we cache out?
             if (!Pred)
@@ -1187,14 +1225,14 @@
   const StackFrameContext *CalleeSF = CalleeLC->getCurrentStackFrame();
   const StackFrameContext *CallerSF = CalleeSF->getParent()->getCurrentStackFrame();
   assert(CalleeSF && CallerSF);
-  ExplodedNode *BeforeProcessingCall = 0;
+  ExplodedNode *BeforeProcessingCall = nullptr;
   const Stmt *CE = CalleeSF->getCallSite();
 
   // Find the first node before we started processing the call expression.
   while (N) {
     ProgramPoint L = N->getLocation();
     BeforeProcessingCall = N;
-    N = N->pred_empty() ? NULL : *(N->pred_begin());
+    N = N->pred_empty() ? nullptr : *(N->pred_begin());
 
     // Skip the nodes corresponding to the inlined code.
     if (L.getLocationContext()->getCurrentStackFrame() != CallerSF)
@@ -1253,7 +1291,7 @@
 
   // FIXME: Refactor this into a checker.
   if (nodeBuilder.getContext().blockCount() >= AMgr.options.maxBlockVisitOnPath) {
-    static SimpleProgramPointTag tag("ExprEngine : Block count exceeded");
+    static SimpleProgramPointTag tag(TagProviderName, "Block count exceeded");
     const ExplodedNode *Sink =
                    nodeBuilder.generateSink(Pred->getState(), Pred, &tag);
 
@@ -1329,6 +1367,33 @@
   return state->getSVal(Ex, LCtx);
 }
 
+#ifndef NDEBUG
+static const Stmt *getRightmostLeaf(const Stmt *Condition) {
+  while (Condition) {
+    const BinaryOperator *BO = dyn_cast<BinaryOperator>(Condition);
+    if (!BO || !BO->isLogicalOp()) {
+      return Condition;
+    }
+    Condition = BO->getRHS()->IgnoreParens();
+  }
+  return nullptr;
+}
+#endif
+
+// Returns the condition the branch at the end of 'B' depends on and whose value
+// has been evaluated within 'B'.
+// In most cases, the terminator condition of 'B' will be evaluated fully in
+// the last statement of 'B'; in those cases, the resolved condition is the
+// given 'Condition'.
+// If the condition of the branch is a logical binary operator tree, the CFG is
+// optimized: in that case, we know that the expression formed by all but the
+// rightmost leaf of the logical binary operator tree must be true, and thus
+// the branch condition is at this point equivalent to the truth value of that
+// rightmost leaf; the CFG block thus only evaluates this rightmost leaf
+// expression in its final statement. As the full condition in that case was
+// not evaluated, and is thus not in the SVal cache, we need to use that leaf
+// expression to evaluate the truth value of the condition in the current state
+// space.
 static const Stmt *ResolveCondition(const Stmt *Condition,
                                     const CFGBlock *B) {
   if (const Expr *Ex = dyn_cast<Expr>(Condition))
@@ -1338,6 +1403,12 @@
   if (!BO || !BO->isLogicalOp())
     return Condition;
 
+  // FIXME: This is a workaround until we handle temporary destructor branches
+  // correctly; currently, temporary destructor branches lead to blocks that
+  // only have a terminator (and no statements). These blocks violate the
+  // invariant this function assumes.
+  if (B->getTerminator().isTemporaryDtorsBranch()) return Condition;
+
   // For logical operations, we still have the case where some branches
   // use the traditional "merge" approach and others sink the branch
   // directly into the basic blocks representing the logical operation.
@@ -1352,18 +1423,9 @@
     Optional<CFGStmt> CS = Elem.getAs<CFGStmt>();
     if (!CS)
       continue;
-    if (CS->getStmt() != Condition)
-      break;
-    return Condition;
-  }
-
-  assert(I != E);
-
-  while (Condition) {
-    BO = dyn_cast<BinaryOperator>(Condition);
-    if (!BO || !BO->isLogicalOp())
-      return Condition;
-    Condition = BO->getRHS()->IgnoreParens();
+    const Stmt *LastStmt = CS->getStmt();
+    assert(LastStmt == Condition || LastStmt == getRightmostLeaf(Condition));
+    return LastStmt;
   }
   llvm_unreachable("could not resolve condition");
 }
@@ -1386,27 +1448,11 @@
     return;
   }
 
-  SValBuilder &SVB = Pred->getState()->getStateManager().getSValBuilder();
-  SVal TrueVal = SVB.makeTruthVal(true);
-  SVal FalseVal = SVB.makeTruthVal(false);
 
   if (const Expr *Ex = dyn_cast<Expr>(Condition))
     Condition = Ex->IgnoreParens();
 
-  // If the value is already available, we don't need to do anything.
-  if (Pred->getState()->getSVal(Condition, LCtx).isUnknownOrUndef()) {
-    // Resolve the condition in the presence of nested '||' and '&&'.
-    Condition = ResolveCondition(Condition, BldCtx.getBlock());
-  }
-
-  // Cast truth values to the correct type.
-  if (const Expr *Ex = dyn_cast<Expr>(Condition)) {
-    TrueVal = SVB.evalCast(TrueVal, Ex->getType(),
-                           getContext().getLogicalOperationType());
-    FalseVal = SVB.evalCast(FalseVal, Ex->getType(),
-                            getContext().getLogicalOperationType());
-  }
-
+  Condition = ResolveCondition(Condition, BldCtx.getBlock());
   PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
                                 Condition->getLocStart(),
                                 "Error evaluating branch");
@@ -1449,41 +1495,35 @@
       }
     }
     
-    ProgramStateRef StTrue, StFalse;
-
     // If the condition is still unknown, give up.
     if (X.isUnknownOrUndef()) {
-
-      StTrue = PrevState->BindExpr(Condition, BldCtx.LC, TrueVal);
-      StFalse = PrevState->BindExpr(Condition, BldCtx.LC, FalseVal);
-
-      builder.generateNode(StTrue, true, PredI);
-      builder.generateNode(StFalse, false, PredI);
+      builder.generateNode(PrevState, true, PredI);
+      builder.generateNode(PrevState, false, PredI);
       continue;
     }
 
     DefinedSVal V = X.castAs<DefinedSVal>();
-    tie(StTrue, StFalse) = PrevState->assume(V);
+
+    ProgramStateRef StTrue, StFalse;
+    std::tie(StTrue, StFalse) = PrevState->assume(V);
 
     // Process the true branch.
     if (builder.isFeasible(true)) {
-      if (StTrue) {
-        StTrue = StTrue->BindExpr(Condition, BldCtx.LC, TrueVal);
+      if (StTrue)
         builder.generateNode(StTrue, true, PredI);
-      } else
+      else
         builder.markInfeasible(true);
     }
 
     // Process the false branch.
     if (builder.isFeasible(false)) {
-      if (StFalse) {
-        StFalse = StFalse->BindExpr(Condition, BldCtx.LC, FalseVal);
+      if (StFalse)
         builder.generateNode(StFalse, false, PredI);
-      } else
+      else
         builder.markInfeasible(false);
     }
   }
-  currBldrCtx = 0;
+  currBldrCtx = nullptr;
 }
 
 /// The GDM component containing the set of global variables which have been
@@ -1512,7 +1552,7 @@
   builder.generateNode(state, initHasRun, Pred);
   builder.markInfeasible(!initHasRun);
 
-  currBldrCtx = 0;
+  currBldrCtx = nullptr;
 }
 
 /// processIndirectGoto - Called by CoreEngine.  Used to generate successor
@@ -1653,7 +1693,7 @@
         }
         else {
           defaultIsFeasible = false;
-          DefaultSt = NULL;
+          DefaultSt = nullptr;
         }
       }
 
@@ -1714,7 +1754,7 @@
         V = UnknownVal();
     }
 
-    Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), 0,
+    Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), nullptr,
                       ProgramPoint::PostLValueKind);
     return;
   }
@@ -1726,7 +1766,7 @@
   }
   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
     SVal V = svalBuilder.getFunctionPointer(FD);
-    Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), 0,
+    Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), nullptr,
                       ProgramPoint::PostLValueKind);
     return;
   }
@@ -1737,7 +1777,7 @@
     SVal V = svalBuilder.conjureSymbolVal(Ex, LCtx, getContext().VoidPtrTy,
                                           currBldrCtx->blockCount());
     state = state->assume(V.castAs<DefinedOrUnknownSVal>(), true);
-    Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), 0,
+    Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), nullptr,
 		      ProgramPoint::PostLValueKind);
     return;
   }
@@ -1767,82 +1807,91 @@
                               state->getSVal(Idx, LCtx),
                               state->getSVal(Base, LCtx));
     assert(A->isGLValue());
-    Bldr.generateNode(A, *it, state->BindExpr(A, LCtx, V), 0, 
+    Bldr.generateNode(A, *it, state->BindExpr(A, LCtx, V), nullptr,
                       ProgramPoint::PostLValueKind);
   }
 }
 
 /// VisitMemberExpr - Transfer function for member expressions.
 void ExprEngine::VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred,
-                                 ExplodedNodeSet &TopDst) {
+                                 ExplodedNodeSet &Dst) {
 
-  StmtNodeBuilder Bldr(Pred, TopDst, *currBldrCtx);
-  ExplodedNodeSet Dst;
+  // FIXME: Prechecks eventually go in ::Visit().
+  ExplodedNodeSet CheckedSet;
+  getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, M, *this);
+
+  ExplodedNodeSet EvalSet;
   ValueDecl *Member = M->getMemberDecl();
 
   // Handle static member variables and enum constants accessed via
   // member syntax.
   if (isa<VarDecl>(Member) || isa<EnumConstantDecl>(Member)) {
-    Bldr.takeNodes(Pred);
-    VisitCommonDeclRefExpr(M, Member, Pred, Dst);
-    Bldr.addNodes(Dst);
-    return;
-  }
+    ExplodedNodeSet Dst;
+    for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end();
+         I != E; ++I) {
+      VisitCommonDeclRefExpr(M, Member, Pred, EvalSet);
+    }
+  } else {
+    StmtNodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx);
+    ExplodedNodeSet Tmp;
 
-  ProgramStateRef state = Pred->getState();
-  const LocationContext *LCtx = Pred->getLocationContext();
-  Expr *BaseExpr = M->getBase();
+    for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end();
+         I != E; ++I) {
+      ProgramStateRef state = (*I)->getState();
+      const LocationContext *LCtx = (*I)->getLocationContext();
+      Expr *BaseExpr = M->getBase();
 
-  // Handle C++ method calls.
-  if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Member)) {
-    if (MD->isInstance())
+      // Handle C++ method calls.
+      if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Member)) {
+        if (MD->isInstance())
+          state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr);
+
+        SVal MDVal = svalBuilder.getFunctionPointer(MD);
+        state = state->BindExpr(M, LCtx, MDVal);
+
+        Bldr.generateNode(M, *I, state);
+        continue;
+      }
+
+      // Handle regular struct fields / member variables.
       state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr);
+      SVal baseExprVal = state->getSVal(BaseExpr, LCtx);
 
-    SVal MDVal = svalBuilder.getFunctionPointer(MD);
-    state = state->BindExpr(M, LCtx, MDVal);
+      FieldDecl *field = cast<FieldDecl>(Member);
+      SVal L = state->getLValue(field, baseExprVal);
 
-    Bldr.generateNode(M, Pred, state);
-    return;
-  }
+      if (M->isGLValue() || M->getType()->isArrayType()) {
+        // We special-case rvalues of array type because the analyzer cannot
+        // reason about them, since we expect all regions to be wrapped in Locs.
+        // We instead treat these as lvalues and assume that they will decay to
+        // pointers as soon as they are used.
+        if (!M->isGLValue()) {
+          assert(M->getType()->isArrayType());
+          const ImplicitCastExpr *PE =
+            dyn_cast<ImplicitCastExpr>((*I)->getParentMap().getParent(M));
+          if (!PE || PE->getCastKind() != CK_ArrayToPointerDecay) {
+            llvm_unreachable("should always be wrapped in ArrayToPointerDecay");
+          }
+        }
 
-  // Handle regular struct fields / member variables.
-  state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr);
-  SVal baseExprVal = state->getSVal(BaseExpr, LCtx);
+        if (field->getType()->isReferenceType()) {
+          if (const MemRegion *R = L.getAsRegion())
+            L = state->getSVal(R);
+          else
+            L = UnknownVal();
+        }
 
-  FieldDecl *field = cast<FieldDecl>(Member);
-  SVal L = state->getLValue(field, baseExprVal);
-
-  if (M->isGLValue() || M->getType()->isArrayType()) {
-
-    // We special case rvalue of array type because the analyzer cannot reason
-    // about it, since we expect all regions to be wrapped in Locs. So we will
-    // treat these as lvalues assuming that they will decay to pointers as soon
-    // as they are used.
-    if (!M->isGLValue()) {
-      assert(M->getType()->isArrayType());
-      const ImplicitCastExpr *PE =
-        dyn_cast<ImplicitCastExpr>(Pred->getParentMap().getParent(M));
-      if (!PE || PE->getCastKind() != CK_ArrayToPointerDecay) {
-        assert(false &&
-               "We assume that array is always wrapped in ArrayToPointerDecay");
-        L = UnknownVal();
+        Bldr.generateNode(M, *I, state->BindExpr(M, LCtx, L), nullptr,
+                          ProgramPoint::PostLValueKind);
+      } else {
+        Bldr.takeNodes(*I);
+        evalLoad(Tmp, M, M, *I, state, L);
+        Bldr.addNodes(Tmp);
       }
     }
-
-    if (field->getType()->isReferenceType()) {
-      if (const MemRegion *R = L.getAsRegion())
-        L = state->getSVal(R);
-      else
-        L = UnknownVal();
-    }
-
-    Bldr.generateNode(M, Pred, state->BindExpr(M, LCtx, L), 0,
-                      ProgramPoint::PostLValueKind);
-  } else {
-    Bldr.takeNodes(Pred);
-    evalLoad(Dst, M, M, Pred, state, L);
-    Bldr.addNodes(Dst);
   }
+
+  getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, M, *this);
 }
 
 namespace {
@@ -1852,7 +1901,7 @@
   CollectReachableSymbolsCallback(ProgramStateRef State) {}
   const InvalidatedSymbols &getSymbols() const { return Symbols; }
 
-  bool VisitSymbol(SymbolRef Sym) {
+  bool VisitSymbol(SymbolRef Sym) override {
     Symbols.insert(Sym);
     return true;
   }
@@ -1898,9 +1947,9 @@
   const InvalidatedSymbols &EscapedSymbols = Scanner.getSymbols();
   State = getCheckerManager().runCheckersForPointerEscape(State,
                                                           EscapedSymbols,
-                                                          /*CallEvent*/ 0,
+                                                          /*CallEvent*/ nullptr,
                                                           PSK_EscapeOnBind,
-                                                          0);
+                                                          nullptr);
 
   return State;
 }
@@ -1919,7 +1968,7 @@
   if (!Call)
     return getCheckerManager().runCheckersForPointerEscape(State,
                                                            *Invalidated,
-                                                           0,
+                                                           nullptr,
                                                            PSK_EscapeOther,
                                                            &ITraits);
 
@@ -1976,7 +2025,8 @@
   // If the location is not a 'Loc', it will already be handled by
   // the checkers.  There is nothing left to do.
   if (!location.getAs<Loc>()) {
-    const ProgramPoint L = PostStore(StoreE, LC, /*Loc*/0, /*tag*/0);
+    const ProgramPoint L = PostStore(StoreE, LC, /*Loc*/nullptr,
+                                     /*tag*/nullptr);
     ProgramStateRef state = Pred->getState();
     state = processPointerEscapedOnBind(state, location, Val);
     Bldr.generateNode(L, state, Pred);
@@ -1997,13 +2047,13 @@
     state = state->bindLoc(location.castAs<Loc>(),
                            Val, /* notifyChanges = */ !atDeclInit);
 
-    const MemRegion *LocReg = 0;
+    const MemRegion *LocReg = nullptr;
     if (Optional<loc::MemRegionVal> LocRegVal =
             location.getAs<loc::MemRegionVal>()) {
       LocReg = LocRegVal->getRegion();
     }
-    
-    const ProgramPoint L = PostStore(StoreE, LC, LocReg, 0);
+
+    const ProgramPoint L = PostStore(StoreE, LC, LocReg, nullptr);
     Bldr.generateNode(L, state, PredI);
   }
 }
@@ -2059,7 +2109,7 @@
     QualType ValTy = TR->getValueType();
     if (const ReferenceType *RT = ValTy->getAs<ReferenceType>()) {
       static SimpleProgramPointTag
-             loadReferenceTag("ExprEngine : Load Reference");
+             loadReferenceTag(TagProviderName, "Load Reference");
       ExplodedNodeSet Tmp;
       evalLoadCommon(Tmp, NodeEx, BoundEx, Pred, state,
                      location, &loadReferenceTag,
@@ -2142,7 +2192,7 @@
     // instead "int *p" is noted as
     // "Variable 'p' initialized to a null pointer value"
     
-    static SimpleProgramPointTag tag("ExprEngine: Location");
+    static SimpleProgramPointTag tag(TagProviderName, "Location");
     Bldr.generateNode(NodeEx, Pred, state, &tag);
   }
   ExplodedNodeSet Tmp;
@@ -2154,8 +2204,10 @@
 std::pair<const ProgramPointTag *, const ProgramPointTag*>
 ExprEngine::geteagerlyAssumeBinOpBifurcationTags() {
   static SimpleProgramPointTag
-         eagerlyAssumeBinOpBifurcationTrue("ExprEngine : Eagerly Assume True"),
-         eagerlyAssumeBinOpBifurcationFalse("ExprEngine : Eagerly Assume False");
+         eagerlyAssumeBinOpBifurcationTrue(TagProviderName,
+                                           "Eagerly Assume True"),
+         eagerlyAssumeBinOpBifurcationFalse(TagProviderName,
+                                            "Eagerly Assume False");
   return std::make_pair(&eagerlyAssumeBinOpBifurcationTrue,
                         &eagerlyAssumeBinOpBifurcationFalse);
 }
@@ -2183,7 +2235,7 @@
         geteagerlyAssumeBinOpBifurcationTags();
 
       ProgramStateRef StateTrue, StateFalse;
-      tie(StateTrue, StateFalse) = state->assume(*SEV);
+      std::tie(StateTrue, StateFalse) = state->assume(*SEV);
 
       // First assume that the condition is true.
       if (StateTrue) {
@@ -2214,9 +2266,8 @@
 
   ProgramStateRef state = Pred->getState();
 
-  for (GCCAsmStmt::const_outputs_iterator OI = A->begin_outputs(),
-       OE = A->end_outputs(); OI != OE; ++OI) {
-    SVal X = state->getSVal(*OI, Pred->getLocationContext());
+  for (const Expr *O : A->outputs()) {
+    SVal X = state->getSVal(O, Pred->getLocationContext());
     assert (!X.getAs<NonLoc>());  // Should be an Lval, or unknown, undef.
 
     if (Optional<Loc> LV = X.getAs<Loc>())
@@ -2390,11 +2441,12 @@
               if (const CaseStmt *C = dyn_cast<CaseStmt>(Label)) {
                 Out << "\\lcase ";
                 LangOptions LO; // FIXME.
-                C->getLHS()->printPretty(Out, 0, PrintingPolicy(LO));
+                if (C->getLHS())
+                  C->getLHS()->printPretty(Out, nullptr, PrintingPolicy(LO));
 
                 if (const Stmt *RHS = C->getRHS()) {
                   Out << " .. ";
-                  RHS->printPretty(Out, 0, PrintingPolicy(LO));
+                  RHS->printPretty(Out, nullptr, PrintingPolicy(LO));
                 }
 
                 Out << ":";
@@ -2433,10 +2485,11 @@
 
       default: {
         const Stmt *S = Loc.castAs<StmtPoint>().getStmt();
+        assert(S != nullptr && "Expecting non-null Stmt");
 
         Out << S->getStmtClassName() << ' ' << (const void*) S << ' ';
         LangOptions LO; // FIXME.
-        S->printPretty(Out, 0, PrintingPolicy(LO));
+        S->printPretty(Out, nullptr, PrintingPolicy(LO));
         printLocation(Out, S->getLocStart());
 
         if (Loc.getAs<PreStmt>())
@@ -2474,7 +2527,7 @@
     }
 
     ProgramStateRef state = N->getState();
-    Out << "\\|StateID: " << (const void*) state.getPtr()
+    Out << "\\|StateID: " << (const void*) state.get()
         << " NodeID: " << (const void*) N << "\\|";
     state->printDOT(Out);
 
@@ -2526,8 +2579,8 @@
 
     llvm::ViewGraph(*G.roots_begin(), "ExprEngine");
 
-    GraphPrintCheckerState = NULL;
-    GraphPrintSourceManager = NULL;
+    GraphPrintCheckerState = nullptr;
+    GraphPrintSourceManager = nullptr;
   }
 #endif
 }
@@ -2537,14 +2590,14 @@
   GraphPrintCheckerState = this;
   GraphPrintSourceManager = &getContext().getSourceManager();
 
-  OwningPtr<ExplodedGraph> TrimmedG(G.trim(Nodes));
+  std::unique_ptr<ExplodedGraph> TrimmedG(G.trim(Nodes));
 
   if (!TrimmedG.get())
     llvm::errs() << "warning: Trimmed ExplodedGraph is empty.\n";
   else
     llvm::ViewGraph(*TrimmedG->roots_begin(), "TrimmedExprEngine");
 
-  GraphPrintCheckerState = NULL;
-  GraphPrintSourceManager = NULL;
+  GraphPrintCheckerState = nullptr;
+  GraphPrintSourceManager = nullptr;
 #endif
 }
diff --git a/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index a2a1885..ffda527 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -47,7 +47,8 @@
       // FIXME: Handle structs.
       if (RightV.isUnknown()) {
         unsigned Count = currBldrCtx->blockCount();
-        RightV = svalBuilder.conjureSymbolVal(0, B->getRHS(), LCtx, Count);
+        RightV = svalBuilder.conjureSymbolVal(nullptr, B->getRHS(), LCtx,
+                                              Count);
       }
       // Simulate the effects of a "store":  bind the value of the RHS
       // to the L-Value represented by the LHS.
@@ -81,6 +82,12 @@
         }
       }
 
+      // Although we don't yet model pointers-to-members, we do need to make
+      // sure that the members of temporaries have a valid 'this' pointer for
+      // other checks.
+      if (B->getOpcode() == BO_PtrMemD)
+        state = createTemporaryRegionIfNeeded(state, LCtx, LHS);
+
       // Process non-assignments except commas or short-circuited
       // logical expressions (LAnd and LOr).
       SVal Result = evalBinOp(state, Op, LeftV, RightV, B->getType());      
@@ -151,7 +158,7 @@
         // The symbolic value is actually for the type of the left-hand side
         // expression, not the computation type, as this is the value the
         // LValue on the LHS will bind to.
-        LHSVal = svalBuilder.conjureSymbolVal(0, B->getRHS(), LCtx, LTy,
+        LHSVal = svalBuilder.conjureSymbolVal(nullptr, B->getRHS(), LCtx, LTy,
                                               currBldrCtx->blockCount());
         // However, we need to convert the symbol to the computation type.
         Result = svalBuilder.evalCast(LHSVal, CTy, LTy);
@@ -184,7 +191,8 @@
 
   // Get the value of the block itself.
   SVal V = svalBuilder.getBlockPointer(BE->getBlockDecl(), T,
-                                       Pred->getLocationContext());
+                                       Pred->getLocationContext(),
+                                       currBldrCtx->blockCount());
   
   ProgramStateRef State = Pred->getState();
   
@@ -210,8 +218,8 @@
   StmtNodeBuilder Bldr(Pred, Tmp, *currBldrCtx);
   Bldr.generateNode(BE, Pred,
                     State->BindExpr(BE, Pred->getLocationContext(), V),
-                    0, ProgramPoint::PostLValueKind);
-  
+                    nullptr, ProgramPoint::PostLValueKind);
+
   // FIXME: Move all post/pre visits to ::Visit().
   getCheckerManager().runCheckersForPostStmt(Dst, Tmp, BE, *this);
 }
@@ -285,6 +293,7 @@
       case CK_Dependent:
       case CK_ArrayToPointerDecay:
       case CK_BitCast:
+      case CK_AddressSpaceConversion:
       case CK_IntegralCast:
       case CK_NullToPointer:
       case CK_IntegralToPointer:
@@ -359,7 +368,7 @@
           // If we don't know if the cast succeeded, conjure a new symbol.
           if (val.isUnknown()) {
             DefinedOrUnknownSVal NewSym =
-              svalBuilder.conjureSymbolVal(0, CastE, LCtx, resultType,
+              svalBuilder.conjureSymbolVal(nullptr, CastE, LCtx, resultType,
                                            currBldrCtx->blockCount());
             state = state->BindExpr(CastE, LCtx, NewSym);
           } else 
@@ -387,7 +396,7 @@
         QualType resultType = CastE->getType();
         if (CastE->isGLValue())
           resultType = getContext().getPointerType(resultType);
-        SVal result = svalBuilder.conjureSymbolVal(0, CastE, LCtx,
+        SVal result = svalBuilder.conjureSymbolVal(nullptr, CastE, LCtx,
                                                    resultType,
                                                    currBldrCtx->blockCount());
         state = state->BindExpr(CastE, LCtx, result);
@@ -485,7 +494,7 @@
             Ty = getContext().getPointerType(Ty);
           }
 
-          InitVal = svalBuilder.conjureSymbolVal(0, InitEx, LC, Ty,
+          InitVal = svalBuilder.conjureSymbolVal(nullptr, InitEx, LC, Ty,
                                                  currBldrCtx->blockCount());
         }
 
@@ -504,33 +513,6 @@
   getCheckerManager().runCheckersForPostStmt(Dst, B.getResults(), DS, *this);
 }
 
-static ProgramStateRef evaluateLogicalExpression(const Expr *E,
-                                                 const LocationContext *LC,
-                                                 ProgramStateRef State) {
-  SVal X = State->getSVal(E, LC);
-  if (! X.isUnknown())
-    return State;
-
-  const BinaryOperator *B = dyn_cast<BinaryOperator>(E->IgnoreParens());
-  if (!B || (B->getOpcode() != BO_LAnd && B->getOpcode() != BO_LOr))
-    return State;
-
-  State = evaluateLogicalExpression(B->getLHS(), LC, State);
-  X = State->getSVal(B->getLHS(), LC);
-  QualType XType = B->getLHS()->getType();
-
-  assert(X.isConstant());
-  if (!X.isZeroConstant() == (B->getOpcode() == BO_LAnd)) {
-    // LHS not sufficient, we need to check RHS as well
-    State = evaluateLogicalExpression(B->getRHS(), LC, State);
-    X = State->getSVal(B->getRHS(), LC);
-    XType = B->getRHS()->getType();
-  }
-
-  SValBuilder &SVB = State->getStateManager().getSValBuilder();
-  return State->BindExpr(E, LC, SVB.evalCast(X, B->getType(), XType));
-}
-
 void ExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred,
                                   ExplodedNodeSet &Dst) {
   assert(B->getOpcode() == BO_LAnd ||
@@ -539,25 +521,64 @@
   StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
   ProgramStateRef state = Pred->getState();
 
-  state = evaluateLogicalExpression(B, Pred->getLocationContext(), state);
-  SVal X = state->getSVal(B, Pred->getLocationContext());
+  ExplodedNode *N = Pred;
+  while (!N->getLocation().getAs<BlockEntrance>()) {
+    ProgramPoint P = N->getLocation();
+    assert(P.getAs<PreStmt>()|| P.getAs<PreStmtPurgeDeadSymbols>());
+    (void) P;
+    assert(N->pred_size() == 1);
+    N = *N->pred_begin();
+  }
+  assert(N->pred_size() == 1);
+  N = *N->pred_begin();
+  BlockEdge BE = N->getLocation().castAs<BlockEdge>();
+  SVal X;
 
-  if (!X.isUndef()) {
-    DefinedOrUnknownSVal DefinedRHS = X.castAs<DefinedOrUnknownSVal>();
-    ProgramStateRef StTrue, StFalse;
-    llvm::tie(StTrue, StFalse) = state->assume(DefinedRHS);
-    if (StTrue) {
-      if (!StFalse) {
-        // The value is known to be true.
-        X = getSValBuilder().makeIntVal(1, B->getType());
-      } // else The truth value of X is unknown, just leave it as it is.
+  // Determine the value of the expression by introspecting how we
+  // got this location in the CFG.  This requires looking at the previous
+  // block we were in and what kind of control-flow transfer was involved.
+  const CFGBlock *SrcBlock = BE.getSrc();
+  // The only terminator (if there is one) that makes sense is a logical op.
+  CFGTerminator T = SrcBlock->getTerminator();
+  if (const BinaryOperator *Term = cast_or_null<BinaryOperator>(T.getStmt())) {
+    (void) Term;
+    assert(Term->isLogicalOp());
+    assert(SrcBlock->succ_size() == 2);
+    // Did we take the true or false branch?
+    unsigned constant = (*SrcBlock->succ_begin() == BE.getDst()) ? 1 : 0;
+    X = svalBuilder.makeIntVal(constant, B->getType());
+  }
+  else {
+    // If there is no terminator, by construction the last statement
+    // in SrcBlock is the value of the enclosing expression.
+    // However, we still need to constrain that value to be 0 or 1.
+    assert(!SrcBlock->empty());
+    CFGStmt Elem = SrcBlock->rbegin()->castAs<CFGStmt>();
+    const Expr *RHS = cast<Expr>(Elem.getStmt());
+    SVal RHSVal = N->getState()->getSVal(RHS, Pred->getLocationContext());
+
+    if (RHSVal.isUndef()) {
+      X = RHSVal;
     } else {
-      // The value is known to be false.
-      assert(StFalse && "Infeasible path!");
-      X = getSValBuilder().makeIntVal(0, B->getType());
+      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());
+      }
     }
   }
-
   Bldr.generateNode(B, Pred, state->BindExpr(B, Pred->getLocationContext(), X));
 }
 
@@ -620,7 +641,7 @@
   StmtNodeBuilder B(Pred, Dst, *currBldrCtx);
   ProgramStateRef state = Pred->getState();
   const LocationContext *LCtx = Pred->getLocationContext();
-  const CFGBlock *SrcBlock = 0;
+  const CFGBlock *SrcBlock = nullptr;
 
   // Find the predecessor block.
   ProgramStateRef SrcState = state;
@@ -665,7 +686,8 @@
   }
 
   if (!hasValue)
-    V = svalBuilder.conjureSymbolVal(0, Ex, LCtx, currBldrCtx->blockCount());
+    V = svalBuilder.conjureSymbolVal(nullptr, Ex, LCtx,
+                                     currBldrCtx->blockCount());
 
   // Generate a new node with the binding from the appropriate path.
   B.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V, true));
@@ -694,34 +716,43 @@
 VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Ex,
                               ExplodedNode *Pred,
                               ExplodedNodeSet &Dst) {
-  StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
+  // FIXME: Prechecks eventually go in ::Visit().
+  ExplodedNodeSet CheckedSet;
+  getCheckerManager().runCheckersForPreStmt(CheckedSet, Pred, Ex, *this);
+
+  ExplodedNodeSet EvalSet;
+  StmtNodeBuilder Bldr(CheckedSet, EvalSet, *currBldrCtx);
 
   QualType T = Ex->getTypeOfArgument();
-  
-  if (Ex->getKind() == UETT_SizeOf) {
-    if (!T->isIncompleteType() && !T->isConstantSizeType()) {
-      assert(T->isVariableArrayType() && "Unknown non-constant-sized type.");
-      
-      // FIXME: Add support for VLA type arguments and VLA expressions.
-      // When that happens, we should probably refactor VLASizeChecker's code.
-      return;
+
+  for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end();
+       I != E; ++I) {
+    if (Ex->getKind() == UETT_SizeOf) {
+      if (!T->isIncompleteType() && !T->isConstantSizeType()) {
+        assert(T->isVariableArrayType() && "Unknown non-constant-sized type.");
+        
+        // FIXME: Add support for VLA type arguments and VLA expressions.
+        // When that happens, we should probably refactor VLASizeChecker's code.
+        continue;
+      } else if (T->getAs<ObjCObjectType>()) {
+        // Some code tries to take the sizeof an ObjCObjectType, relying that
+        // the compiler has laid out its representation.  Just report Unknown
+        // for these.
+        continue;
+      }
     }
-    else if (T->getAs<ObjCObjectType>()) {
-      // Some code tries to take the sizeof an ObjCObjectType, relying that
-      // the compiler has laid out its representation.  Just report Unknown
-      // for these.
-      return;
-    }
+    
+    APSInt Value = Ex->EvaluateKnownConstInt(getContext());
+    CharUnits amt = CharUnits::fromQuantity(Value.getZExtValue());
+    
+    ProgramStateRef state = (*I)->getState();
+    state = state->BindExpr(Ex, (*I)->getLocationContext(),
+                            svalBuilder.makeIntVal(amt.getQuantity(),
+                                                   Ex->getType()));
+    Bldr.generateNode(Ex, *I, state);
   }
-  
-  APSInt Value = Ex->EvaluateKnownConstInt(getContext());
-  CharUnits amt = CharUnits::fromQuantity(Value.getZExtValue());
-  
-  ProgramStateRef state = Pred->getState();
-  state = state->BindExpr(Ex, Pred->getLocationContext(),
-                          svalBuilder.makeIntVal(amt.getQuantity(),
-                                                     Ex->getType()));
-  Bldr.generateNode(Ex, Pred, state);
+
+  getCheckerManager().runCheckersForPostStmt(Dst, EvalSet, Ex, *this);
 }
 
 void ExprEngine::VisitUnaryOperator(const UnaryOperator* U, 
@@ -906,7 +937,8 @@
     // Conjure a new symbol if necessary to recover precision.
     if (Result.isUnknown()){
       DefinedOrUnknownSVal SymVal =
-        svalBuilder.conjureSymbolVal(0, Ex, LCtx, currBldrCtx->blockCount());
+        svalBuilder.conjureSymbolVal(nullptr, Ex, LCtx,
+                                     currBldrCtx->blockCount());
       Result = SymVal;
       
       // If the value is a location, ++/-- should always preserve
diff --git a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
index eba4f94..2a76621 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -91,12 +91,6 @@
 /// If the type is not an array type at all, the original value is returned.
 static SVal makeZeroElementRegion(ProgramStateRef State, SVal LValue,
                                   QualType &Ty) {
-  // FIXME: This check is just a temporary workaround, because
-  // ProcessTemporaryDtor sends us NULL regions. It will not be necessary once
-  // we can properly process temporary destructors.
-  if (!LValue.getAsRegion())
-    return LValue;
-
   SValBuilder &SVB = State->getStateManager().getSValBuilder();
   ASTContext &Ctx = SVB.getContext();
 
@@ -108,13 +102,85 @@
   return LValue;
 }
 
+
+static const MemRegion *getRegionForConstructedObject(
+    const CXXConstructExpr *CE, ExplodedNode *Pred, ExprEngine &Eng,
+    unsigned int CurrStmtIdx) {
+  const LocationContext *LCtx = Pred->getLocationContext();
+  ProgramStateRef State = Pred->getState();
+  const NodeBuilderContext &CurrBldrCtx = Eng.getBuilderContext();
+
+  // See if we're constructing an existing region by looking at the next
+  // element in the CFG.
+  const CFGBlock *B = CurrBldrCtx.getBlock();
+  unsigned int NextStmtIdx = CurrStmtIdx + 1;
+  if (NextStmtIdx < B->size()) {
+    CFGElement Next = (*B)[NextStmtIdx];
+
+    // Is this a destructor? If so, we might be in the middle of an assignment
+    // to a local or member: look ahead one more element to see what we find.
+    while (Next.getAs<CFGImplicitDtor>() && NextStmtIdx + 1 < B->size()) {
+      ++NextStmtIdx;
+      Next = (*B)[NextStmtIdx];
+    }
+
+    // Is this a constructor for a local variable?
+    if (Optional<CFGStmt> StmtElem = Next.getAs<CFGStmt>()) {
+      if (const DeclStmt *DS = dyn_cast<DeclStmt>(StmtElem->getStmt())) {
+        if (const VarDecl *Var = dyn_cast<VarDecl>(DS->getSingleDecl())) {
+          if (Var->getInit() && Var->getInit()->IgnoreImplicit() == CE) {
+            SVal LValue = State->getLValue(Var, LCtx);
+            QualType Ty = Var->getType();
+            LValue = makeZeroElementRegion(State, LValue, Ty);
+            return LValue.getAsRegion();
+          }
+        }
+      }
+    }
+
+    // Is this a constructor for a member?
+    if (Optional<CFGInitializer> InitElem = Next.getAs<CFGInitializer>()) {
+      const CXXCtorInitializer *Init = InitElem->getInitializer();
+      assert(Init->isAnyMemberInitializer());
+
+      const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl());
+      Loc ThisPtr = Eng.getSValBuilder().getCXXThis(CurCtor,
+          LCtx->getCurrentStackFrame());
+      SVal ThisVal = State->getSVal(ThisPtr);
+
+      const ValueDecl *Field;
+      SVal FieldVal;
+      if (Init->isIndirectMemberInitializer()) {
+        Field = Init->getIndirectMember();
+        FieldVal = State->getLValue(Init->getIndirectMember(), ThisVal);
+      } else {
+        Field = Init->getMember();
+        FieldVal = State->getLValue(Init->getMember(), ThisVal);
+      }
+
+      QualType Ty = Field->getType();
+      FieldVal = makeZeroElementRegion(State, FieldVal, Ty);
+      return FieldVal.getAsRegion();
+    }
+
+    // FIXME: This will eventually need to handle new-expressions as well.
+    // Don't forget to update the pre-constructor initialization code in
+    // ExprEngine::VisitCXXConstructExpr.
+  }
+
+  // If we couldn't find an existing region to construct into, assume we're
+  // constructing a temporary.
+  MemRegionManager &MRMgr = Eng.getSValBuilder().getRegionManager();
+  return MRMgr.getCXXTempObjectRegion(CE, LCtx);
+}
+
 void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE,
                                        ExplodedNode *Pred,
                                        ExplodedNodeSet &destNodes) {
   const LocationContext *LCtx = Pred->getLocationContext();
   ProgramStateRef State = Pred->getState();
 
-  const MemRegion *Target = 0;
+  const MemRegion *Target = nullptr;
 
   // FIXME: Handle arrays, which run the same constructor for every element.
   // For now, we just run the first constructor (which should still invalidate
@@ -122,62 +188,7 @@
 
   switch (CE->getConstructionKind()) {
   case CXXConstructExpr::CK_Complete: {
-    // See if we're constructing an existing region by looking at the next
-    // element in the CFG.
-    const CFGBlock *B = currBldrCtx->getBlock();
-    if (currStmtIdx + 1 < B->size()) {
-      CFGElement Next = (*B)[currStmtIdx+1];
-
-      // Is this a constructor for a local variable?
-      if (Optional<CFGStmt> StmtElem = Next.getAs<CFGStmt>()) {
-        if (const DeclStmt *DS = dyn_cast<DeclStmt>(StmtElem->getStmt())) {
-          if (const VarDecl *Var = dyn_cast<VarDecl>(DS->getSingleDecl())) {
-            if (Var->getInit()->IgnoreImplicit() == CE) {
-              SVal LValue = State->getLValue(Var, LCtx);
-              QualType Ty = Var->getType();
-              LValue = makeZeroElementRegion(State, LValue, Ty);
-              Target = LValue.getAsRegion();
-            }
-          }
-        }
-      }
-      
-      // Is this a constructor for a member?
-      if (Optional<CFGInitializer> InitElem = Next.getAs<CFGInitializer>()) {
-        const CXXCtorInitializer *Init = InitElem->getInitializer();
-        assert(Init->isAnyMemberInitializer());
-
-        const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl());
-        Loc ThisPtr = getSValBuilder().getCXXThis(CurCtor,
-                                                  LCtx->getCurrentStackFrame());
-        SVal ThisVal = State->getSVal(ThisPtr);
-
-        const ValueDecl *Field;
-        SVal FieldVal;
-        if (Init->isIndirectMemberInitializer()) {
-          Field = Init->getIndirectMember();
-          FieldVal = State->getLValue(Init->getIndirectMember(), ThisVal);
-        } else {
-          Field = Init->getMember();
-          FieldVal = State->getLValue(Init->getMember(), ThisVal);
-        }
-
-        QualType Ty = Field->getType();
-        FieldVal = makeZeroElementRegion(State, FieldVal, Ty);
-        Target = FieldVal.getAsRegion();
-      }
-
-      // FIXME: This will eventually need to handle new-expressions as well.
-      // Don't forget to update the pre-constructor initialization code below.
-    }
-
-    // If we couldn't find an existing region to construct into, assume we're
-    // constructing a temporary.
-    if (!Target) {
-      MemRegionManager &MRMgr = getSValBuilder().getRegionManager();
-      Target = MRMgr.getCXXTempObjectRegion(CE, LCtx);
-    }
-
+    Target = getRegionForConstructedObject(CE, Pred, *this, currStmtIdx);
     break;
   }
   case CXXConstructExpr::CK_VirtualBase:
@@ -251,7 +262,8 @@
         // since it's then possible to be initializing one part of a multi-
         // dimensional array.
         State = State->bindDefault(loc::MemRegionVal(Target), ZeroVal);
-        Bldr.generateNode(CE, *I, State, /*tag=*/0, ProgramPoint::PreStmtKind);
+        Bldr.generateNode(CE, *I, State, /*tag=*/nullptr,
+                          ProgramPoint::PreStmtKind);
       }
     }
   }
@@ -329,6 +341,32 @@
                                              *Call, *this);
 }
 
+void ExprEngine::VisitCXXNewAllocatorCall(const CXXNewExpr *CNE,
+                                          ExplodedNode *Pred,
+                                          ExplodedNodeSet &Dst) {
+  ProgramStateRef State = Pred->getState();
+  const LocationContext *LCtx = Pred->getLocationContext();
+  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
+                                CNE->getStartLoc(),
+                                "Error evaluating New Allocator Call");
+  CallEventManager &CEMgr = getStateManager().getCallEventManager();
+  CallEventRef<CXXAllocatorCall> Call =
+    CEMgr.getCXXAllocatorCall(CNE, State, LCtx);
+
+  ExplodedNodeSet DstPreCall;
+  getCheckerManager().runCheckersForPreCall(DstPreCall, Pred,
+                                            *Call, *this);
+
+  ExplodedNodeSet DstInvalidated;
+  StmtNodeBuilder Bldr(DstPreCall, DstInvalidated, *currBldrCtx);
+  for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
+       I != E; ++I)
+    defaultEvalCall(Bldr, *I, *Call);
+  getCheckerManager().runCheckersForPostCall(Dst, DstInvalidated,
+                                             *Call, *this);
+}
+
+
 void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
                                    ExplodedNodeSet &Dst) {
   // FIXME: Much of this should eventually migrate to CXXAllocatorCall.
@@ -360,7 +398,7 @@
   if (IsStandardGlobalOpNewFunction)
     symVal = svalBuilder.getConjuredHeapSymbolVal(CNE, LCtx, blockCount);
   else
-    symVal = svalBuilder.conjureSymbolVal(0, CNE, LCtx, CNE->getType(), 
+    symVal = svalBuilder.conjureSymbolVal(nullptr, CNE, LCtx, CNE->getType(),
                                           blockCount);
 
   ProgramStateRef State = Pred->getState();
diff --git a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
index 06328e4..3f608ba 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
@@ -11,8 +11,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#define DEBUG_TYPE "ExprEngine"
-
 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
 #include "PrettyStackTraceLocationContext.h"
 #include "clang/AST/CXXInheritance.h"
@@ -28,6 +26,8 @@
 using namespace clang;
 using namespace ento;
 
+#define DEBUG_TYPE "ExprEngine"
+
 STATISTIC(NumOfDynamicDispatchPathSplits,
   "The # of times we split the path due to imprecise dynamic dispatch info");
 
@@ -49,7 +49,7 @@
   assert(Entry->empty());
   assert(Entry->succ_size() == 1);
   
-  // Get the solitary sucessor.
+  // Get the solitary successor.
   const CFGBlock *Succ = *(Entry->succ_begin());
   
   // Construct an edge representing the starting location in the callee.
@@ -69,8 +69,8 @@
 // corresponding Block.
 static std::pair<const Stmt*,
                  const CFGBlock*> getLastStmt(const ExplodedNode *Node) {
-  const Stmt *S = 0;
-  const CFGBlock *Blk = 0;
+  const Stmt *S = nullptr;
+  const CFGBlock *Blk = nullptr;
   const StackFrameContext *SF =
           Node->getLocation().getLocationContext()->getCurrentStackFrame();
 
@@ -108,12 +108,12 @@
     }
 
     if (Node->pred_empty())
-      return std::pair<const Stmt*, const CFGBlock*>((Stmt*)0, (CFGBlock*)0);
+      return std::make_pair(nullptr, nullptr);
 
     Node = *Node->pred_begin();
   }
 
-  return std::pair<const Stmt*, const CFGBlock*>(S, Blk);
+  return std::make_pair(S, Blk);
 }
 
 /// Adjusts a return value when the called function's return type does not
@@ -160,9 +160,9 @@
                                            ExplodedNode *Pred,
                                            ExplodedNodeSet &Dst) {
   // Find the last statement in the function and the corresponding basic block.
-  const Stmt *LastSt = 0;
-  const CFGBlock *Blk = 0;
-  llvm::tie(LastSt, Blk) = getLastStmt(Pred);
+  const Stmt *LastSt = nullptr;
+  const CFGBlock *Blk = nullptr;
+  std::tie(LastSt, Blk) = getLastStmt(Pred);
   if (!Blk || !LastSt) {
     Dst.Add(Pred);
     return;
@@ -229,9 +229,9 @@
   const Stmt *CE = calleeCtx->getCallSite();
   ProgramStateRef state = CEBNode->getState();
   // Find the last statement in the function and the corresponding basic block.
-  const Stmt *LastSt = 0;
-  const CFGBlock *Blk = 0;
-  llvm::tie(LastSt, Blk) = getLastStmt(CEBNode);
+  const Stmt *LastSt = nullptr;
+  const CFGBlock *Blk = nullptr;
+  std::tie(LastSt, Blk) = getLastStmt(CEBNode);
 
   // Generate a CallEvent /before/ cleaning the state, so that we can get the
   // correct value for 'this' (if necessary).
@@ -282,7 +282,7 @@
   // they occurred.
   ExplodedNodeSet CleanedNodes;
   if (LastSt && Blk && AMgr.options.AnalysisPurgeOpt != PurgeNone) {
-    static SimpleProgramPointTag retValBind("ExprEngine : Bind Return Value");
+    static SimpleProgramPointTag retValBind("ExprEngine", "Bind Return Value");
     PostStmt Loc(LastSt, calleeCtx, &retValBind);
     bool isNew;
     ExplodedNode *BindedRetNode = G.getNode(Loc, state, false, &isNew);
@@ -296,10 +296,10 @@
     // context, telling it to clean up everything in the callee's context
     // (and its children). We use the callee's function body as a diagnostic
     // statement, with which the program point will be associated.
-    removeDead(BindedRetNode, CleanedNodes, 0, calleeCtx,
+    removeDead(BindedRetNode, CleanedNodes, nullptr, calleeCtx,
                calleeCtx->getAnalysisDeclContext()->getBody(),
                ProgramPoint::PostStmtPurgeDeadSymbolsKind);
-    currBldrCtx = 0;
+    currBldrCtx = nullptr;
   } else {
     CleanedNodes.Add(CEBNode);
   }
@@ -387,14 +387,14 @@
   const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC);
   if (!ND)
     return false;
-  
+
   while (const DeclContext *Parent = ND->getParent()) {
     if (!isa<NamespaceDecl>(Parent))
       break;
     ND = cast<NamespaceDecl>(Parent);
   }
 
-  return ND->getName() == "std";
+  return ND->isStdNamespace();
 }
 
 // The GDM component containing the dynamic dispatch bifurcation info. When
@@ -471,7 +471,7 @@
                                             const Stmt *CallE) {
   const void *ReplayState = State->get<ReplayWithoutInlining>();
   if (!ReplayState)
-    return 0;
+    return nullptr;
 
   assert(ReplayState == CallE && "Backtracked to the wrong call.");
   (void)CallE;
@@ -565,7 +565,7 @@
   QualType ResultTy = Call.getResultType();
   SValBuilder &SVB = getSValBuilder();
   unsigned Count = currBldrCtx->blockCount();
-  SVal R = SVB.conjureSymbolVal(0, E, LCtx, ResultTy, Count);
+  SVal R = SVB.conjureSymbolVal(nullptr, E, LCtx, ResultTy, Count);
   return State->BindExpr(E, LCtx, R);
 }
 
@@ -664,6 +664,8 @@
     break;
   }
   case CE_CXXAllocator:
+    if (Opts.mayInlineCXXAllocator())
+      break;
     // Do not inline allocators until we model deallocators.
     // This is unfortunate, but basically necessary for smart pointers and such.
     return CIP_DisallowedAlways;
@@ -706,18 +708,16 @@
          hasMember(Ctx, RD, "iterator_category");
 }
 
-/// Returns true if the given function refers to a constructor or destructor of
-/// a C++ container or iterator.
+/// Returns true if the given function refers to a method of a C++ container
+/// or iterator.
 ///
-/// We generally do a poor job modeling most containers right now, and would
-/// prefer not to inline their setup and teardown.
-static bool isContainerCtorOrDtor(const ASTContext &Ctx,
-                                  const FunctionDecl *FD) {
-  if (!(isa<CXXConstructorDecl>(FD) || isa<CXXDestructorDecl>(FD)))
-    return false;
-
-  const CXXRecordDecl *RD = cast<CXXMethodDecl>(FD)->getParent();
-  return isContainerClass(Ctx, RD);
+/// We generally do a poor job modeling most containers right now, and might
+/// prefer not to inline their methods.
+static bool isContainerMethod(const ASTContext &Ctx,
+                              const FunctionDecl *FD) {
+  if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD))
+    return isContainerClass(Ctx, MD->getParent());
+  return false;
 }
 
 /// Returns true if the given function is the destructor of a class named
@@ -763,9 +763,9 @@
 
       // Conditionally control the inlining of methods on objects that look
       // like C++ containers.
-      if (!Opts.mayInlineCXXContainerCtorsAndDtors())
+      if (!Opts.mayInlineCXXContainerMethods())
         if (!Ctx.getSourceManager().isInMainFile(FD->getLocation()))
-          if (isContainerCtorOrDtor(Ctx, FD))
+          if (isContainerMethod(Ctx, FD))
             return false;
             
       // Conditionally control the inlining of the destructor of C++ shared_ptr.
diff --git a/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp b/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
index d276d92..a6611e0 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
@@ -77,7 +77,7 @@
   
   if (const DeclStmt *DS = dyn_cast<DeclStmt>(elem)) {
     const VarDecl *elemD = cast<VarDecl>(DS->getSingleDecl());
-    assert(elemD->getInit() == 0);
+    assert(elemD->getInit() == nullptr);
     elementV = state->getLValue(elemD, Pred->getLocationContext());
   }
   else {
@@ -85,7 +85,7 @@
   }
   
   ExplodedNodeSet dstLocation;
-  evalLocation(dstLocation, S, elem, Pred, state, elementV, NULL, false);
+  evalLocation(dstLocation, S, elem, Pred, state, elementV, nullptr, false);
 
   ExplodedNodeSet Tmp;
   StmtNodeBuilder Bldr(Pred, Tmp, *currBldrCtx);
@@ -165,7 +165,7 @@
             recVal.castAs<DefinedOrUnknownSVal>();
 
         ProgramStateRef notNilState, nilState;
-        llvm::tie(notNilState, nilState) = State->assume(receiverVal);
+        std::tie(notNilState, nilState) = State->assume(receiverVal);
         
         // There are three cases: can be nil or non-nil, must be nil, must be
         // non-nil. We ignore must be nil, and merge the rest two into non-nil.
diff --git a/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp b/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
index 365f6ab..b1e9f06c 100644
--- a/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
+++ b/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
@@ -20,11 +20,13 @@
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Rewrite/Core/HTMLRewrite.h"
 #include "clang/Rewrite/Core/Rewriter.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
+#include <sstream>
 
 using namespace clang;
 using namespace ento;
@@ -39,15 +41,16 @@
   std::string Directory;
   bool createdDir, noDir;
   const Preprocessor &PP;
+  AnalyzerOptions &AnalyzerOpts;
 public:
-  HTMLDiagnostics(const std::string& prefix, const Preprocessor &pp);
+  HTMLDiagnostics(AnalyzerOptions &AnalyzerOpts, const std::string& prefix, const Preprocessor &pp);
 
-  virtual ~HTMLDiagnostics() { FlushDiagnostics(NULL); }
+  virtual ~HTMLDiagnostics() { FlushDiagnostics(nullptr); }
 
-  virtual void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags,
-                                    FilesMade *filesMade);
+  void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags,
+                            FilesMade *filesMade) override;
 
-  virtual StringRef getName() const {
+  StringRef getName() const override {
     return "HTMLDiagnostics";
   }
 
@@ -68,16 +71,17 @@
 
 } // end anonymous namespace
 
-HTMLDiagnostics::HTMLDiagnostics(const std::string& prefix,
+HTMLDiagnostics::HTMLDiagnostics(AnalyzerOptions &AnalyzerOpts,
+                                 const std::string& prefix,
                                  const Preprocessor &pp)
-  : Directory(prefix), createdDir(false), noDir(false), PP(pp) {
+    : Directory(prefix), createdDir(false), noDir(false), PP(pp), AnalyzerOpts(AnalyzerOpts) {
 }
 
 void ento::createHTMLDiagnosticConsumer(AnalyzerOptions &AnalyzerOpts,
                                         PathDiagnosticConsumers &C,
                                         const std::string& prefix,
                                         const Preprocessor &PP) {
-  C.push_back(new HTMLDiagnostics(prefix, PP));
+  C.push_back(new HTMLDiagnostics(AnalyzerOpts, prefix, PP));
 }
 
 //===----------------------------------------------------------------------===//
@@ -95,13 +99,11 @@
 
 void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D,
                                  FilesMade *filesMade) {
-    
+
   // Create the HTML directory if it is missing.
   if (!createdDir) {
     createdDir = true;
-    bool existed;
-    if (llvm::error_code ec =
-            llvm::sys::fs::create_directories(Directory, existed)) {
+    if (std::error_code ec = llvm::sys::fs::create_directories(Directory)) {
       llvm::errs() << "warning: could not create directory '"
                    << Directory << "': " << ec.message() << '\n';
 
@@ -128,11 +130,30 @@
   // Create a new rewriter to generate HTML.
   Rewriter R(const_cast<SourceManager&>(SMgr), PP.getLangOpts());
 
+  // Get the function/method name
+  SmallString<128> declName("unknown");
+  int offsetDecl = 0;
+  if (const Decl *DeclWithIssue = D.getDeclWithIssue()) {
+      if (const NamedDecl *ND = dyn_cast<NamedDecl>(DeclWithIssue)) {
+          declName = ND->getDeclName().getAsString();
+      }
+
+      if (const Stmt *Body = DeclWithIssue->getBody()) {
+          // Retrieve the relative position of the declaration which will be used
+          // for the file name
+          FullSourceLoc L(
+              SMgr.getExpansionLoc((*path.rbegin())->getLocation().asLocation()),
+              SMgr);
+          FullSourceLoc FunL(SMgr.getExpansionLoc(Body->getLocStart()), SMgr);
+          offsetDecl = L.getExpansionLineNumber() - FunL.getExpansionLineNumber();
+      }
+  }
+
   // Process the path.
   unsigned n = path.size();
   unsigned max = n;
 
-  for (PathPieces::const_reverse_iterator I = path.rbegin(), 
+  for (PathPieces::const_reverse_iterator I = path.rbegin(),
        E = path.rend();
         I != E; ++I, --n)
     HandlePiece(R, FID, **I, n, max);
@@ -165,6 +186,9 @@
     DirName += '/';
   }
 
+  int LineNumber = (*path.rbegin())->getLocation().asLocation().getExpansionLineNumber();
+  int ColumnNumber = (*path.rbegin())->getLocation().asLocation().getExpansionColumnNumber();
+
   // Add the name of the file as an <h1> tag.
 
   {
@@ -178,9 +202,9 @@
       << html::EscapeText(Entry->getName())
       << "</td></tr>\n<tr><td class=\"rowname\">Location:</td><td>"
          "<a href=\"#EndPath\">line "
-      << (*path.rbegin())->getLocation().asLocation().getExpansionLineNumber()
+      << LineNumber
       << ", column "
-      << (*path.rbegin())->getLocation().asLocation().getExpansionColumnNumber()
+      << ColumnNumber
       << "</a></td></tr>\n"
          "<tr><td class=\"rowname\">Description:</td><td>"
       << D.getVerboseDescription() << "</td></tr>\n";
@@ -217,12 +241,16 @@
 
     os << "\n<!-- BUGFILE " << DirName << Entry->getName() << " -->\n";
 
+    os << "\n<!-- FILENAME " << llvm::sys::path::filename(Entry->getName()) << " -->\n";
+
+    os  << "\n<!-- FUNCTIONNAME " <<  declName << " -->\n";
+
     os << "\n<!-- BUGLINE "
-       << path.back()->getLocation().asLocation().getExpansionLineNumber()
+       << LineNumber
        << " -->\n";
 
     os << "\n<!-- BUGCOLUMN "
-      << path.back()->getLocation().asLocation().getExpansionColumnNumber()
+      << ColumnNumber
       << " -->\n";
 
     os << "\n<!-- BUGPATHLENGTH " << path.size() << " -->\n";
@@ -249,13 +277,42 @@
   // Create a path for the target HTML file.
   int FD;
   SmallString<128> Model, ResultPath;
-  llvm::sys::path::append(Model, Directory, "report-%%%%%%.html");
 
-  if (llvm::error_code EC =
+  if (!AnalyzerOpts.shouldWriteStableReportFilename()) {
+      llvm::sys::path::append(Model, Directory, "report-%%%%%%.html");
+
+      if (std::error_code EC =
           llvm::sys::fs::createUniqueFile(Model.str(), FD, ResultPath)) {
-    llvm::errs() << "warning: could not create file in '" << Directory
-                 << "': " << EC.message() << '\n';
-    return;
+          llvm::errs() << "warning: could not create file in '" << Directory
+                       << "': " << EC.message() << '\n';
+          return;
+      }
+
+  } else {
+      int i = 1;
+      std::error_code EC;
+      do {
+          // Find a filename which is not already used
+          std::stringstream filename;
+          Model = "";
+          filename << "report-"
+                   << llvm::sys::path::filename(Entry->getName()).str()
+                   << "-" << declName.c_str()
+                   << "-" << offsetDecl
+                   << "-" << i << ".html";
+          llvm::sys::path::append(Model, Directory,
+                                  filename.str());
+          EC = llvm::sys::fs::openFileForWrite(Model.str(),
+                                               FD,
+                                               llvm::sys::fs::F_RW |
+                                               llvm::sys::fs::F_Excl);
+          if (EC && EC != std::errc::file_exists) {
+              llvm::errs() << "warning: could not create file '" << Model.str()
+                           << "': " << EC.message() << '\n';
+              return;
+          }
+          i++;
+      } while (EC);
   }
 
   llvm::raw_fd_ostream os(FD, true);
@@ -309,7 +366,7 @@
 
   // Create the html for the message.
 
-  const char *Kind = 0;
+  const char *Kind = nullptr;
   switch (P.getKind()) {
   case PathDiagnosticPiece::Call:
       llvm_unreachable("Calls should already be handled");
@@ -460,7 +517,7 @@
            << (num + 1)
            << ")\">&#x2192;</a></div></td>";
       }
-      
+
       os << "</tr></table>";
     }
   }
diff --git a/lib/StaticAnalyzer/Core/MemRegion.cpp b/lib/StaticAnalyzer/Core/MemRegion.cpp
index 1be5840..22711f5 100644
--- a/lib/StaticAnalyzer/Core/MemRegion.cpp
+++ b/lib/StaticAnalyzer/Core/MemRegion.cpp
@@ -148,7 +148,7 @@
 
 bool SubRegion::isSubRegionOf(const MemRegion* R) const {
   const MemRegion* r = getSuperRegion();
-  while (r != 0) {
+  while (r != nullptr) {
     if (r == R)
       return true;
     if (const SubRegion* sr = dyn_cast<SubRegion>(r))
@@ -173,7 +173,7 @@
 
 const StackFrameContext *VarRegion::getStackFrame() const {
   const StackSpaceRegion *SSR = dyn_cast<StackSpaceRegion>(getMemorySpace());
-  return SSR ? SSR->getStackFrame() : NULL;
+  return SSR ? SSR->getStackFrame() : nullptr;
 }
 
 //===----------------------------------------------------------------------===//
@@ -383,15 +383,17 @@
 void BlockDataRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
                                     const BlockTextRegion *BC,
                                     const LocationContext *LC,
+                                    unsigned BlkCount,
                                     const MemRegion *sReg) {
   ID.AddInteger(MemRegion::BlockDataRegionKind);
   ID.AddPointer(BC);
   ID.AddPointer(LC);
+  ID.AddInteger(BlkCount);
   ID.AddPointer(sReg);
 }
 
 void BlockDataRegion::Profile(llvm::FoldingSetNodeID& ID) const {
-  BlockDataRegion::ProfileRegion(ID, BC, LC, getSuperRegion());
+  BlockDataRegion::ProfileRegion(ID, BC, LC, BlockCount, getSuperRegion());
 }
 
 void CXXTempObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
@@ -464,7 +466,14 @@
 }
 
 void BlockDataRegion::dumpToStream(raw_ostream &os) const {
-  os << "block_data{" << BC << '}';
+  os << "block_data{" << BC;
+  os << "; ";
+  for (BlockDataRegion::referenced_vars_iterator
+         I = referenced_vars_begin(),
+         E = referenced_vars_end(); I != E; ++I)
+    os << "(" << I.getCapturedRegion() << "," <<
+                 I.getOriginalRegion() << ") ";
+  os << '}';
 }
 
 void CompoundLiteralRegion::dumpToStream(raw_ostream &os) const {
@@ -499,11 +508,13 @@
 }
 
 void StringRegion::dumpToStream(raw_ostream &os) const {
-  Str->printPretty(os, 0, PrintingPolicy(getContext().getLangOpts()));
+  assert(Str != nullptr && "Expecting non-null StringLiteral");
+  Str->printPretty(os, nullptr, PrintingPolicy(getContext().getLangOpts()));
 }
 
 void ObjCStringRegion::dumpToStream(raw_ostream &os) const {
-  Str->printPretty(os, 0, PrintingPolicy(getContext().getLangOpts()));
+  assert(Str != nullptr && "Expecting non-null ObjCStringLiteral");
+  Str->printPretty(os, nullptr, PrintingPolicy(getContext().getLangOpts()));
 }
 
 void SymbolicRegion::dumpToStream(raw_ostream &os) const {
@@ -748,12 +759,12 @@
     
     LC = LC->getParent();
   }
-  return (const StackFrameContext*)0;
+  return (const StackFrameContext *)nullptr;
 }
 
 const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
                                                 const LocationContext *LC) {
-  const MemRegion *sReg = 0;
+  const MemRegion *sReg = nullptr;
 
   if (D->hasGlobalStorage() && !D->isStaticLocal()) {
 
@@ -839,8 +850,9 @@
 
 const BlockDataRegion *
 MemRegionManager::getBlockDataRegion(const BlockTextRegion *BC,
-                                     const LocationContext *LC) {
-  const MemRegion *sReg = 0;
+                                     const LocationContext *LC,
+                                     unsigned blockCount) {
+  const MemRegion *sReg = nullptr;
   const BlockDecl *BD = BC->getDecl();
   if (!BD->hasCaptures()) {
     // This handles 'static' blocks.
@@ -861,20 +873,20 @@
     }
   }
 
-  return getSubRegion<BlockDataRegion>(BC, LC, sReg);
+  return getSubRegion<BlockDataRegion>(BC, LC, blockCount, sReg);
 }
 
 const CXXTempObjectRegion *
 MemRegionManager::getCXXStaticTempObjectRegion(const Expr *Ex) {
   return getSubRegion<CXXTempObjectRegion>(
-      Ex, getGlobalsRegion(MemRegion::GlobalInternalSpaceRegionKind, NULL));
+      Ex, getGlobalsRegion(MemRegion::GlobalInternalSpaceRegionKind, nullptr));
 }
 
 const CompoundLiteralRegion*
 MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr *CL,
                                            const LocationContext *LC) {
 
-  const MemRegion *sReg = 0;
+  const MemRegion *sReg = nullptr;
 
   if (CL->isFileScope())
     sReg = getGlobalsRegion();
@@ -965,10 +977,8 @@
   if (IsVirtual)
     return Class->isVirtuallyDerivedFrom(BaseClass);
 
-  for (CXXRecordDecl::base_class_const_iterator I = Class->bases_begin(),
-                                                E = Class->bases_end();
-       I != E; ++I) {
-    if (I->getType()->getAsCXXRecordDecl()->getCanonicalDecl() == BaseClass)
+  for (const auto &I : Class->bases()) {
+    if (I.getType()->getAsCXXRecordDecl()->getCanonicalDecl() == BaseClass)
       return true;
   }
 
@@ -1103,7 +1113,7 @@
       return SymR;
     SubR = dyn_cast<SubRegion>(SubR->getSuperRegion());
   }
-  return 0;
+  return nullptr;
 }
 
 // FIXME: Merge with the implementation of the same method in Store.cpp
@@ -1120,7 +1130,7 @@
 RegionRawOffset ElementRegion::getAsArrayOffset() const {
   CharUnits offset = CharUnits::Zero();
   const ElementRegion *ER = this;
-  const MemRegion *superR = NULL;
+  const MemRegion *superR = nullptr;
   ASTContext &C = getContext();
 
   // FIXME: Handle multi-dimensional arrays.
@@ -1152,7 +1162,7 @@
       continue;
     }
 
-    return NULL;
+    return nullptr;
   }
 
   assert(superR && "super region cannot be NULL");
@@ -1166,10 +1176,8 @@
   // Note that we do NOT canonicalize the base class here, because
   // ASTRecordLayout doesn't either. If that leads us down the wrong path,
   // so be it; at least we won't crash.
-  for (CXXRecordDecl::base_class_const_iterator I = Child->bases_begin(),
-                                                E = Child->bases_end();
-       I != E; ++I) {
-    if (I->getType()->getAsCXXRecordDecl() == Base)
+  for (const auto &I : Child->bases()) {
+    if (I.getType()->getAsCXXRecordDecl() == Base)
       return true;
   }
 
@@ -1178,7 +1186,7 @@
 
 RegionOffset MemRegion::getAsOffset() const {
   const MemRegion *R = this;
-  const MemRegion *SymbolicOffsetBase = 0;
+  const MemRegion *SymbolicOffsetBase = nullptr;
   int64_t Offset = 0;
 
   while (1) {
@@ -1350,10 +1358,10 @@
 std::pair<const VarRegion *, const VarRegion *>
 BlockDataRegion::getCaptureRegions(const VarDecl *VD) {
   MemRegionManager &MemMgr = *getMemRegionManager();
-  const VarRegion *VR = 0;
-  const VarRegion *OriginalVR = 0;
+  const VarRegion *VR = nullptr;
+  const VarRegion *OriginalVR = nullptr;
 
-  if (!VD->getAttr<BlocksAttr>() && VD->hasLocalStorage()) {
+  if (!VD->hasAttr<BlocksAttr>() && VD->hasLocalStorage()) {
     VR = MemMgr.getVarRegion(VD, this);
     OriginalVR = MemMgr.getVarRegion(VD, LC);
   }
@@ -1376,7 +1384,7 @@
 
   AnalysisDeclContext *AC = getCodeRegion()->getAnalysisDeclContext();
   AnalysisDeclContext::referenced_decls_iterator I, E;
-  llvm::tie(I, E) = AC->getReferencedBlockVars(BC->getDecl());
+  std::tie(I, E) = AC->getReferencedBlockVars(BC->getDecl());
 
   if (I == E) {
     ReferencedVars = (void*) 0x1;
@@ -1394,9 +1402,9 @@
   new (BVOriginal) VarVec(BC, E - I);
 
   for ( ; I != E; ++I) {
-    const VarRegion *VR = 0;
-    const VarRegion *OriginalVR = 0;
-    llvm::tie(VR, OriginalVR) = getCaptureRegions(*I);
+    const VarRegion *VR = nullptr;
+    const VarRegion *OriginalVR = nullptr;
+    std::tie(VR, OriginalVR) = getCaptureRegions(*I);
     assert(VR);
     assert(OriginalVR);
     BV->push_back(VR, BC);
@@ -1415,8 +1423,8 @@
     static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
 
   if (Vec == (void*) 0x1)
-    return BlockDataRegion::referenced_vars_iterator(0, 0);
-  
+    return BlockDataRegion::referenced_vars_iterator(nullptr, nullptr);
+
   BumpVector<const MemRegion*> *VecOriginal =
     static_cast<BumpVector<const MemRegion*>*>(OriginalVars);
   
@@ -1432,8 +1440,8 @@
     static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
 
   if (Vec == (void*) 0x1)
-    return BlockDataRegion::referenced_vars_iterator(0, 0);
-  
+    return BlockDataRegion::referenced_vars_iterator(nullptr, nullptr);
+
   BumpVector<const MemRegion*> *VecOriginal =
     static_cast<BumpVector<const MemRegion*>*>(OriginalVars);
 
@@ -1448,7 +1456,7 @@
     if (I.getCapturedRegion() == R)
       return I.getOriginalRegion();
   }
-  return 0;
+  return nullptr;
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
index b504db6..fd25bd8 100644
--- a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
+++ b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
@@ -16,6 +16,7 @@
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
 #include "clang/AST/ParentMap.h"
 #include "clang/AST/StmtCXX.h"
 #include "clang/Basic/SourceManager.h"
@@ -66,7 +67,7 @@
 void PathPieces::flattenTo(PathPieces &Primary, PathPieces &Current,
                            bool ShouldFlattenMacros) const {
   for (PathPieces::const_iterator I = begin(), E = end(); I != E; ++I) {
-    PathDiagnosticPiece *Piece = I->getPtr();
+    PathDiagnosticPiece *Piece = I->get();
 
     switch (Piece->getKind()) {
     case PathDiagnosticPiece::Call: {
@@ -106,12 +107,13 @@
 
 PathDiagnostic::~PathDiagnostic() {}
 
-PathDiagnostic::PathDiagnostic(const Decl *declWithIssue,
+PathDiagnostic::PathDiagnostic(StringRef CheckName, const Decl *declWithIssue,
                                StringRef bugtype, StringRef verboseDesc,
                                StringRef shortDesc, StringRef category,
                                PathDiagnosticLocation LocationToUnique,
                                const Decl *DeclToUnique)
-  : DeclWithIssue(declWithIssue),
+  : CheckName(CheckName),
+    DeclWithIssue(declWithIssue),
     BugType(StripTrailingDots(bugtype)),
     VerboseDesc(StripTrailingDots(verboseDesc)),
     ShortDesc(StripTrailingDots(shortDesc)),
@@ -127,7 +129,7 @@
 
   // If the call is within a macro, don't do anything (for now).
   if (CallLoc.isMacroID())
-    return 0;
+    return nullptr;
 
   assert(SMgr.isInMainFile(CallLoc) &&
          "The call piece should be in the main file.");
@@ -138,7 +140,7 @@
 
   const PathPieces &Path = CP->path;
   if (Path.empty())
-    return 0;
+    return nullptr;
 
   // Check if the last piece in the callee path is a call to a function outside
   // of the main file.
@@ -148,14 +150,14 @@
   }
 
   // Otherwise, the last piece is in the main file.
-  return 0;
+  return nullptr;
 }
 
 void PathDiagnostic::resetDiagnosticLocationToMainFile() {
   if (path.empty())
     return;
 
-  PathDiagnosticPiece *LastP = path.back().getPtr();
+  PathDiagnosticPiece *LastP = path.back().get();
   assert(LastP);
   const SourceManager &SMgr = LastP->getLocation().getManager();
 
@@ -196,8 +198,8 @@
 }
 
 void PathDiagnosticConsumer::HandlePathDiagnostic(PathDiagnostic *D) {
-  OwningPtr<PathDiagnostic> OwningD(D);
-  
+  std::unique_ptr<PathDiagnostic> OwningD(D);
+
   if (!D || D->path.empty())
     return;
   
@@ -220,7 +222,7 @@
 
       for (PathPieces::const_iterator I = path.begin(), E = path.end(); I != E;
            ++I) {
-        const PathDiagnosticPiece *piece = I->getPtr();
+        const PathDiagnosticPiece *piece = I->get();
         FullSourceLoc L = piece->getLocation().asLocation().getExpansionLoc();
       
         if (FID.isInvalid()) {
@@ -258,7 +260,7 @@
   // Profile the node to see if we already have something matching it
   llvm::FoldingSetNodeID profile;
   D->Profile(profile);
-  void *InsertPos = 0;
+  void *InsertPos = nullptr;
 
   if (PathDiagnostic *orig = Diags.FindNodeOrInsertPos(profile, InsertPos)) {
     // Keep the PathDiagnostic with the shorter path.
@@ -274,8 +276,8 @@
     Diags.RemoveNode(orig);
     delete orig;
   }
-  
-  Diags.InsertNode(OwningD.take());
+
+  Diags.InsertNode(OwningD.release());
 }
 
 static Optional<bool> comparePath(const PathPieces &X, const PathPieces &Y);
@@ -415,17 +417,6 @@
   return b.getValue();
 }
 
-namespace {
-struct CompareDiagnostics {
-  // Compare if 'X' is "<" than 'Y'.
-  bool operator()(const PathDiagnostic *X, const PathDiagnostic *Y) const {
-    if (X == Y)
-      return false;
-    return compare(*X, *Y);
-  }
-};
-}
-
 void PathDiagnosticConsumer::FlushDiagnostics(
                                      PathDiagnosticConsumer::FilesMade *Files) {
   if (flushed)
@@ -443,8 +434,11 @@
   // Sort the diagnostics so that they are always emitted in a deterministic
   // order.
   if (!BatchDiags.empty())
-    std::sort(BatchDiags.begin(), BatchDiags.end(), CompareDiagnostics());
-  
+    std::sort(BatchDiags.begin(), BatchDiags.end(),
+              [](const PathDiagnostic *X, const PathDiagnostic *Y) {
+      return X != Y && compare(*X, *Y);
+    });
+
   FlushDiagnosticsImpl(BatchDiags, Files);
 
   // Delete the flushed diagnostics.
@@ -458,6 +452,11 @@
   Diags.clear();
 }
 
+PathDiagnosticConsumer::FilesMade::~FilesMade() {
+  for (PDFileEntry &Entry : *this)
+    Entry.~PDFileEntry();
+}
+
 void PathDiagnosticConsumer::FilesMade::addDiagnostic(const PathDiagnostic &PD,
                                                       StringRef ConsumerName,
                                                       StringRef FileName) {
@@ -487,7 +486,7 @@
   void *InsertPos;
   PDFileEntry *Entry = FindNodeOrInsertPos(NodeID, InsertPos);
   if (!Entry)
-    return 0;
+    return nullptr;
   return &Entry->files;
 }
 
@@ -571,6 +570,7 @@
     return PathDiagnosticLocation::create(CallerInfo->getDecl(), SM);
   }
   case CFGElement::TemporaryDtor:
+  case CFGElement::NewAllocator:
     llvm_unreachable("not yet implemented!");
   }
 
@@ -610,6 +610,14 @@
 }
 
 PathDiagnosticLocation
+  PathDiagnosticLocation::createConditionalColonLoc(
+                                            const ConditionalOperator *CO,
+                                            const SourceManager &SM) {
+  return PathDiagnosticLocation(CO->getColonLoc(), SM, SingleLocK);
+}
+
+
+PathDiagnosticLocation
   PathDiagnosticLocation::createMemberLoc(const MemberExpr *ME,
                                           const SourceManager &SM) {
   return PathDiagnosticLocation(ME->getMemberLoc(), SM, SingleLocK);
@@ -654,7 +662,7 @@
   PathDiagnosticLocation::create(const ProgramPoint& P,
                                  const SourceManager &SMng) {
 
-  const Stmt* S = 0;
+  const Stmt* S = nullptr;
   if (Optional<BlockEdge> BE = P.getAs<BlockEdge>()) {
     const CFGBlock *BSrc = BE->getSrc();
     S = BSrc->getTerminatorCondition();
@@ -695,7 +703,7 @@
   if (Optional<PostInitializer> PIPP = P.getAs<PostInitializer>())
     return PIPP->getInitializer()->getInit();
 
-  return 0;
+  return nullptr;
 }
 
 const Stmt *PathDiagnosticLocation::getNextStmt(const ExplodedNode *N) {
@@ -722,7 +730,7 @@
     }
   }
 
-  return 0;
+  return nullptr;
 }
 
 PathDiagnosticLocation
@@ -731,8 +739,12 @@
   assert(N && "Cannot create a location with a null node.");
   const Stmt *S = getStmt(N);
 
-  if (!S)
+  if (!S) {
+    // If this is an implicit call, return the implicit call point location.
+    if (Optional<PreImplicitCall> PIE = N->getLocationAs<PreImplicitCall>())
+      return PathDiagnosticLocation(PIE->getLocation(), SM);
     S = getNextStmt(N);
+  }
 
   if (S) {
     ProgramPoint P = N->getLocation();
@@ -853,13 +865,13 @@
 void PathDiagnosticLocation::flatten() {
   if (K == StmtK) {
     K = RangeK;
-    S = 0;
-    D = 0;
+    S = nullptr;
+    D = nullptr;
   }
   else if (K == DeclK) {
     K = SingleLocK;
-    S = 0;
-    D = 0;
+    S = nullptr;
+    D = nullptr;
   }
 }
 
@@ -969,7 +981,7 @@
 IntrusiveRefCntPtr<PathDiagnosticEventPiece>
 PathDiagnosticCallPiece::getCallEnterEvent() const {
   if (!Callee)
-    return 0;  
+    return nullptr;
 
   SmallString<256> buf;
   llvm::raw_svector_ostream Out(buf);
@@ -984,12 +996,12 @@
 IntrusiveRefCntPtr<PathDiagnosticEventPiece>
 PathDiagnosticCallPiece::getCallEnterWithinCallerEvent() const {
   if (!callEnterWithin.asLocation().isValid())
-    return 0;
+    return nullptr;
   if (Callee->isImplicit() || !Callee->hasBody())
-    return 0;
+    return nullptr;
   if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Callee))
     if (MD->isDefaulted())
-      return 0;
+      return nullptr;
 
   SmallString<256> buf;
   llvm::raw_svector_ostream Out(buf);
@@ -1003,7 +1015,7 @@
 IntrusiveRefCntPtr<PathDiagnosticEventPiece>
 PathDiagnosticCallPiece::getCallExitEvent() const {
   if (NoExit)
-    return 0;
+    return nullptr;
 
   SmallString<256> buf;
   llvm::raw_svector_ostream Out(buf);
@@ -1025,7 +1037,7 @@
 static void compute_path_size(const PathPieces &pieces, unsigned &size) {
   for (PathPieces::const_iterator it = pieces.begin(),
                                   et = pieces.end(); it != et; ++it) {
-    const PathDiagnosticPiece *piece = it->getPtr();
+    const PathDiagnosticPiece *piece = it->get();
     if (const PathDiagnosticCallPiece *cp = 
         dyn_cast<PathDiagnosticCallPiece>(piece)) {
       compute_path_size(cp->path, size);
diff --git a/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp b/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
index 5dca811..ba3ad2e 100644
--- a/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
+++ b/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
@@ -13,6 +13,7 @@
 
 #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
 #include "clang/Basic/FileManager.h"
+#include "clang/Basic/PlistSupport.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/Version.h"
 #include "clang/Lex/Preprocessor.h"
@@ -21,12 +22,9 @@
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Casting.h"
-#include "llvm/Support/raw_ostream.h"
 using namespace clang;
 using namespace ento;
-
-typedef llvm::DenseMap<FileID, unsigned> FIDMap;
-
+using namespace markup;
 
 namespace {
   class PlistDiagnostics : public PathDiagnosticConsumer {
@@ -42,15 +40,17 @@
     virtual ~PlistDiagnostics() {}
 
     void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags,
-                              FilesMade *filesMade);
-    
-    virtual StringRef getName() const {
+                              FilesMade *filesMade) override;
+
+    virtual StringRef getName() const override {
       return "PlistDiagnostics";
     }
 
-    PathGenerationScheme getGenerationScheme() const { return Extensive; }
-    bool supportsLogicalOpControlFlow() const { return true; }
-    virtual bool supportsCrossFileDiagnostics() const {
+    PathGenerationScheme getGenerationScheme() const override {
+      return Extensive;
+    }
+    bool supportsLogicalOpControlFlow() const override { return true; }
+    bool supportsCrossFileDiagnostics() const override {
       return SupportsCrossFileDiagnostics;
     }
   };
@@ -80,84 +80,6 @@
                                    PP.getLangOpts(), true));
 }
 
-static void AddFID(FIDMap &FIDs, SmallVectorImpl<FileID> &V,
-                   const SourceManager* SM, SourceLocation L) {
-
-  FileID FID = SM->getFileID(SM->getExpansionLoc(L));
-  FIDMap::iterator I = FIDs.find(FID);
-  if (I != FIDs.end()) return;
-  FIDs[FID] = V.size();
-  V.push_back(FID);
-}
-
-static unsigned GetFID(const FIDMap& FIDs, const SourceManager &SM,
-                       SourceLocation L) {
-  FileID FID = SM.getFileID(SM.getExpansionLoc(L));
-  FIDMap::const_iterator I = FIDs.find(FID);
-  assert(I != FIDs.end());
-  return I->second;
-}
-
-static raw_ostream &Indent(raw_ostream &o, const unsigned indent) {
-  for (unsigned i = 0; i < indent; ++i) o << ' ';
-  return o;
-}
-
-static void EmitLocation(raw_ostream &o, const SourceManager &SM,
-                         const LangOptions &LangOpts,
-                         SourceLocation L, const FIDMap &FM,
-                         unsigned indent, bool extend = false) {
-
-  FullSourceLoc Loc(SM.getExpansionLoc(L), const_cast<SourceManager&>(SM));
-
-  // Add in the length of the token, so that we cover multi-char tokens.
-  unsigned offset =
-    extend ? Lexer::MeasureTokenLength(Loc, SM, LangOpts) - 1 : 0;
-
-  Indent(o, indent) << "<dict>\n";
-  Indent(o, indent) << " <key>line</key><integer>"
-                    << Loc.getExpansionLineNumber() << "</integer>\n";
-  Indent(o, indent) << " <key>col</key><integer>"
-                    << Loc.getExpansionColumnNumber() + offset << "</integer>\n";
-  Indent(o, indent) << " <key>file</key><integer>"
-                    << GetFID(FM, SM, Loc) << "</integer>\n";
-  Indent(o, indent) << "</dict>\n";
-}
-
-static void EmitLocation(raw_ostream &o, const SourceManager &SM,
-                         const LangOptions &LangOpts,
-                         const PathDiagnosticLocation &L, const FIDMap& FM,
-                         unsigned indent, bool extend = false) {
-  EmitLocation(o, SM, LangOpts, L.asLocation(), FM, indent, extend);
-}
-
-static void EmitRange(raw_ostream &o, const SourceManager &SM,
-                      const LangOptions &LangOpts,
-                      PathDiagnosticRange R, const FIDMap &FM,
-                      unsigned indent) {
-  Indent(o, indent) << "<array>\n";
-  EmitLocation(o, SM, LangOpts, R.getBegin(), FM, indent+1);
-  EmitLocation(o, SM, LangOpts, R.getEnd(), FM, indent+1, !R.isPoint);
-  Indent(o, indent) << "</array>\n";
-}
-
-static raw_ostream &EmitString(raw_ostream &o, StringRef s) {
-  o << "<string>";
-  for (StringRef::const_iterator I = s.begin(), E = s.end(); I != E; ++I) {
-    char c = *I;
-    switch (c) {
-    default:   o << c; break;
-    case '&':  o << "&amp;"; break;
-    case '<':  o << "&lt;"; break;
-    case '>':  o << "&gt;"; break;
-    case '\'': o << "&apos;"; break;
-    case '\"': o << "&quot;"; break;
-    }
-  }
-  o << "</string>";
-  return o;
-}
-
 static void ReportControlFlow(raw_ostream &o,
                               const PathDiagnosticControlFlowPiece& P,
                               const FIDMap& FM,
@@ -185,11 +107,13 @@
     // logic for clients.
     Indent(o, indent) << "<key>start</key>\n";
     SourceLocation StartEdge = I->getStart().asRange().getBegin();
-    EmitRange(o, SM, LangOpts, SourceRange(StartEdge, StartEdge), FM, indent+1);
+    EmitRange(o, SM, LangOpts, CharSourceRange::getTokenRange(StartEdge), FM,
+              indent + 1);
 
     Indent(o, indent) << "<key>end</key>\n";
     SourceLocation EndEdge = I->getEnd().asRange().getBegin();
-    EmitRange(o, SM, LangOpts, SourceRange(EndEdge, EndEdge), FM, indent+1);
+    EmitRange(o, SM, LangOpts, CharSourceRange::getTokenRange(EndEdge), FM,
+              indent + 1);
 
     --indent;
     Indent(o, indent) << "</dict>\n";
@@ -241,15 +165,16 @@
     ++indent;
     for (ArrayRef<SourceRange>::iterator I = Ranges.begin(), E = Ranges.end();
          I != E; ++I) {
-      EmitRange(o, SM, LangOpts, *I, FM, indent+1);
+      EmitRange(o, SM, LangOpts, CharSourceRange::getTokenRange(*I), FM,
+                indent + 1);
     }
     --indent;
     Indent(o, indent) << "</array>\n";
   }
   
   // Output the call depth.
-  Indent(o, indent) << "<key>depth</key>"
-                    << "<integer>" << depth << "</integer>\n";
+  Indent(o, indent) << "<key>depth</key>";
+  EmitInteger(o, depth) << '\n';
 
   // Output the text.
   assert(!P.getString().empty());
@@ -367,7 +292,7 @@
   // ranges of the diagnostics.
   FIDMap FM;
   SmallVector<FileID, 10> Fids;
-  const SourceManager* SM = 0;
+  const SourceManager* SM = nullptr;
 
   if (!Diags.empty())
     SM = &(*(*Diags.begin())->path.begin())->getLocation().getManager();
@@ -386,13 +311,13 @@
 
       for (PathPieces::const_iterator I = path.begin(), E = path.end(); I != E;
            ++I) {
-        const PathDiagnosticPiece *piece = I->getPtr();
-        AddFID(FM, Fids, SM, piece->getLocation().asLocation());
+        const PathDiagnosticPiece *piece = I->get();
+        AddFID(FM, Fids, *SM, piece->getLocation().asLocation());
         ArrayRef<SourceRange> Ranges = piece->getRanges();
         for (ArrayRef<SourceRange>::iterator I = Ranges.begin(),
                                              E = Ranges.end(); I != E; ++I) {
-          AddFID(FM, Fids, SM, I->getBegin());
-          AddFID(FM, Fids, SM, I->getEnd());
+          AddFID(FM, Fids, *SM, I->getBegin());
+          AddFID(FM, Fids, *SM, I->getEnd());
         }
 
         if (const PathDiagnosticCallPiece *call =
@@ -400,7 +325,7 @@
           IntrusiveRefCntPtr<PathDiagnosticEventPiece>
             callEnterWithin = call->getCallEnterWithinCallerEvent();
           if (callEnterWithin)
-            AddFID(FM, Fids, SM, callEnterWithin->getLocation().asLocation());
+            AddFID(FM, Fids, *SM, callEnterWithin->getLocation().asLocation());
 
           WorkList.push_back(&call->path);
         }
@@ -414,17 +339,13 @@
 
   // Open the file.
   std::string ErrMsg;
-  llvm::raw_fd_ostream o(OutputFile.c_str(), ErrMsg);
+  llvm::raw_fd_ostream o(OutputFile.c_str(), ErrMsg, llvm::sys::fs::F_Text);
   if (!ErrMsg.empty()) {
     llvm::errs() << "warning: could not create file: " << OutputFile << '\n';
     return;
   }
 
-  // Write the plist header.
-  o << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
-  "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" "
-  "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
-  "<plist version=\"1.0\">\n";
+  EmitPlistHeader(o);
 
   // Write the root object: a <dict> containing...
   //  - "clang_version", the string representation of clang version
@@ -436,11 +357,8 @@
   o << " <key>files</key>\n"
        " <array>\n";
 
-  for (SmallVectorImpl<FileID>::iterator I=Fids.begin(), E=Fids.end();
-       I!=E; ++I) {
-    o << "  ";
-    EmitString(o, SM->getFileEntryForID(*I)->getName()) << '\n';
-  }
+  for (FileID FID : Fids)
+    EmitString(o << "  ", SM->getFileEntryForID(FID)->getName()) << '\n';
 
   o << " </array>\n"
        " <key>diagnostics</key>\n"
@@ -535,7 +453,7 @@
 
     // Output the location of the bug.
     o << "  <key>location</key>\n";
-    EmitLocation(o, *SM, LangOpts, D->getLocation(), FM, 2);
+    EmitLocation(o, *SM, LangOpts, D->getLocation().asLocation(), FM, 2);
 
     // Output the diagnostic to the sub-diagnostic client, if any.
     if (!filesMade->empty()) {
diff --git a/lib/StaticAnalyzer/Core/PrettyStackTraceLocationContext.h b/lib/StaticAnalyzer/Core/PrettyStackTraceLocationContext.h
index ed64fcb..c2af36f 100644
--- a/lib/StaticAnalyzer/Core/PrettyStackTraceLocationContext.h
+++ b/lib/StaticAnalyzer/Core/PrettyStackTraceLocationContext.h
@@ -33,7 +33,7 @@
     assert(LCtx);
   }
 
-  virtual void print(raw_ostream &OS) const {
+  void print(raw_ostream &OS) const override {
     OS << "While analyzing stack: \n";
     LCtx->dumpStack(OS, "\t");
   }
diff --git a/lib/StaticAnalyzer/Core/ProgramState.cpp b/lib/StaticAnalyzer/Core/ProgramState.cpp
index 6e23668..1714a27 100644
--- a/lib/StaticAnalyzer/Core/ProgramState.cpp
+++ b/lib/StaticAnalyzer/Core/ProgramState.cpp
@@ -175,7 +175,6 @@
                                     const CallEvent *Call) const {
   ProgramStateManager &Mgr = getStateManager();
   SubEngine* Eng = Mgr.getOwningEngine();
-  InvalidatedSymbols ConstIS;
 
   InvalidatedSymbols Invalidated;
   if (!IS)
@@ -208,7 +207,7 @@
 
   const StoreRef &newStore =
   Mgr.StoreMgr->invalidateRegions(getStore(), Values, E, Count, LCtx, Call,
-                                  *IS, *ITraits, NULL, NULL);
+                                  *IS, *ITraits, nullptr, nullptr);
   return makeWithStore(newStore);
 }
 
@@ -388,7 +387,7 @@
   if (ProgramState *I = StateSet.FindNodeOrInsertPos(ID, InsertPos))
     return I;
 
-  ProgramState *newState = 0;
+  ProgramState *newState = nullptr;
   if (!freeStates.empty()) {
     newState = freeStates.back();
     freeStates.pop_back();    
diff --git a/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp b/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
index 3606e09..77578d3 100644
--- a/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
+++ b/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
@@ -45,7 +45,7 @@
     return *second;
   }
   const llvm::APSInt *getConcreteValue() const {
-    return &From() == &To() ? &From() : NULL;
+    return &From() == &To() ? &From() : nullptr;
   }
 
   void Profile(llvm::FoldingSetNodeID &ID) const {
@@ -98,7 +98,7 @@
   ///  constant then this method returns that value.  Otherwise, it returns
   ///  NULL.
   const llvm::APSInt* getConcreteValue() const {
-    return ranges.isSingleton() ? ranges.begin()->getConcreteValue() : 0;
+    return ranges.isSingleton() ? ranges.begin()->getConcreteValue() : nullptr;
   }
 
 private:
@@ -290,35 +290,37 @@
 
   ProgramStateRef assumeSymNE(ProgramStateRef state, SymbolRef sym,
                              const llvm::APSInt& Int,
-                             const llvm::APSInt& Adjustment);
+                             const llvm::APSInt& Adjustment) override;
 
   ProgramStateRef assumeSymEQ(ProgramStateRef state, SymbolRef sym,
                              const llvm::APSInt& Int,
-                             const llvm::APSInt& Adjustment);
+                             const llvm::APSInt& Adjustment) override;
 
   ProgramStateRef assumeSymLT(ProgramStateRef state, SymbolRef sym,
                              const llvm::APSInt& Int,
-                             const llvm::APSInt& Adjustment);
+                             const llvm::APSInt& Adjustment) override;
 
   ProgramStateRef assumeSymGT(ProgramStateRef state, SymbolRef sym,
                              const llvm::APSInt& Int,
-                             const llvm::APSInt& Adjustment);
+                             const llvm::APSInt& Adjustment) override;
 
   ProgramStateRef assumeSymGE(ProgramStateRef state, SymbolRef sym,
                              const llvm::APSInt& Int,
-                             const llvm::APSInt& Adjustment);
+                             const llvm::APSInt& Adjustment) override;
 
   ProgramStateRef assumeSymLE(ProgramStateRef state, SymbolRef sym,
                              const llvm::APSInt& Int,
-                             const llvm::APSInt& Adjustment);
+                             const llvm::APSInt& Adjustment) override;
 
-  const llvm::APSInt* getSymVal(ProgramStateRef St, SymbolRef sym) const;
-  ConditionTruthVal checkNull(ProgramStateRef State, SymbolRef Sym);
+  const llvm::APSInt* getSymVal(ProgramStateRef St,
+                                SymbolRef sym) const override;
+  ConditionTruthVal checkNull(ProgramStateRef State, SymbolRef Sym) override;
 
-  ProgramStateRef removeDeadBindings(ProgramStateRef St, SymbolReaper& SymReaper);
+  ProgramStateRef removeDeadBindings(ProgramStateRef St,
+                                     SymbolReaper& SymReaper) override;
 
   void print(ProgramStateRef St, raw_ostream &Out,
-             const char* nl, const char *sep);
+             const char* nl, const char *sep) override;
 
 private:
   RangeSet::Factory F;
@@ -334,7 +336,7 @@
 const llvm::APSInt* RangeConstraintManager::getSymVal(ProgramStateRef St,
                                                       SymbolRef sym) const {
   const ConstraintRangeTy::data_type *T = St->get<ConstraintRange>(sym);
-  return T ? T->getConcreteValue() : NULL;
+  return T ? T->getConcreteValue() : nullptr;
 }
 
 ConditionTruthVal RangeConstraintManager::checkNull(ProgramStateRef State,
@@ -430,7 +432,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);
-  return New.isEmpty() ? NULL : St->set<ConstraintRange>(Sym, New);
+  return New.isEmpty() ? nullptr : St->set<ConstraintRange>(Sym, New);
 }
 
 ProgramStateRef 
@@ -440,12 +442,12 @@
   // Before we do any real work, see if the value can even show up.
   APSIntType AdjustmentType(Adjustment);
   if (AdjustmentType.testInRange(Int, true) != APSIntType::RTR_Within)
-    return NULL;
+    return nullptr;
 
   // [Int-Adjustment, Int-Adjustment]
   llvm::APSInt AdjInt = AdjustmentType.convert(Int) - Adjustment;
   RangeSet New = GetRange(St, Sym).Intersect(getBasicVals(), F, AdjInt, AdjInt);
-  return New.isEmpty() ? NULL : St->set<ConstraintRange>(Sym, New);
+  return New.isEmpty() ? nullptr : St->set<ConstraintRange>(Sym, New);
 }
 
 ProgramStateRef 
@@ -456,7 +458,7 @@
   APSIntType AdjustmentType(Adjustment);
   switch (AdjustmentType.testInRange(Int, true)) {
   case APSIntType::RTR_Below:
-    return NULL;
+    return nullptr;
   case APSIntType::RTR_Within:
     break;
   case APSIntType::RTR_Above:
@@ -467,14 +469,14 @@
   llvm::APSInt ComparisonVal = AdjustmentType.convert(Int);
   llvm::APSInt Min = AdjustmentType.getMinValue();
   if (ComparisonVal == Min)
-    return NULL;
+    return nullptr;
 
   llvm::APSInt Lower = Min-Adjustment;
   llvm::APSInt Upper = ComparisonVal-Adjustment;
   --Upper;
 
   RangeSet New = GetRange(St, Sym).Intersect(getBasicVals(), F, Lower, Upper);
-  return New.isEmpty() ? NULL : St->set<ConstraintRange>(Sym, New);
+  return New.isEmpty() ? nullptr : St->set<ConstraintRange>(Sym, New);
 }
 
 ProgramStateRef 
@@ -489,21 +491,21 @@
   case APSIntType::RTR_Within:
     break;
   case APSIntType::RTR_Above:
-    return NULL;
+    return nullptr;
   }
 
   // Special case for Int == Max. This is always false.
   llvm::APSInt ComparisonVal = AdjustmentType.convert(Int);
   llvm::APSInt Max = AdjustmentType.getMaxValue();
   if (ComparisonVal == Max)
-    return NULL;
+    return nullptr;
 
   llvm::APSInt Lower = ComparisonVal-Adjustment;
   llvm::APSInt Upper = Max-Adjustment;
   ++Lower;
 
   RangeSet New = GetRange(St, Sym).Intersect(getBasicVals(), F, Lower, Upper);
-  return New.isEmpty() ? NULL : St->set<ConstraintRange>(Sym, New);
+  return New.isEmpty() ? nullptr : St->set<ConstraintRange>(Sym, New);
 }
 
 ProgramStateRef 
@@ -518,7 +520,7 @@
   case APSIntType::RTR_Within:
     break;
   case APSIntType::RTR_Above:
-    return NULL;
+    return nullptr;
   }
 
   // Special case for Int == Min. This is always feasible.
@@ -532,7 +534,7 @@
   llvm::APSInt Upper = Max-Adjustment;
 
   RangeSet New = GetRange(St, Sym).Intersect(getBasicVals(), F, Lower, Upper);
-  return New.isEmpty() ? NULL : St->set<ConstraintRange>(Sym, New);
+  return New.isEmpty() ? nullptr : St->set<ConstraintRange>(Sym, New);
 }
 
 ProgramStateRef 
@@ -543,7 +545,7 @@
   APSIntType AdjustmentType(Adjustment);
   switch (AdjustmentType.testInRange(Int, true)) {
   case APSIntType::RTR_Below:
-    return NULL;
+    return nullptr;
   case APSIntType::RTR_Within:
     break;
   case APSIntType::RTR_Above:
@@ -561,7 +563,7 @@
   llvm::APSInt Upper = ComparisonVal-Adjustment;
 
   RangeSet New = GetRange(St, Sym).Intersect(getBasicVals(), F, Lower, Upper);
-  return New.isEmpty() ? NULL : St->set<ConstraintRange>(Sym, New);
+  return New.isEmpty() ? nullptr : St->set<ConstraintRange>(Sym, New);
 }
 
 //===------------------------------------------------------------------------===
diff --git a/lib/StaticAnalyzer/Core/RegionStore.cpp b/lib/StaticAnalyzer/Core/RegionStore.cpp
index 0b51976..3bbbb34 100644
--- a/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ b/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -104,7 +104,7 @@
            Data == X.Data;
   }
 
-  LLVM_ATTRIBUTE_USED void dump() const;
+  void dump() const;
 };
 } // end anonymous namespace
 
@@ -133,9 +133,7 @@
   };
 } // end llvm namespace
 
-void BindingKey::dump() const {
-  llvm::errs() << *this;
-}
+LLVM_DUMP_METHOD void BindingKey::dump() const { llvm::errs() << *this; }
 
 //===----------------------------------------------------------------------===//
 // Actual Store type.
@@ -224,9 +222,7 @@
    }
   }
 
-  LLVM_ATTRIBUTE_USED void dump() const {
-    dump(llvm::errs(), "\n");
-  }
+  LLVM_DUMP_METHOD void dump() const { dump(llvm::errs(), "\n"); }
 };
 } // end anonymous namespace
 
@@ -266,7 +262,7 @@
 const SVal *RegionBindingsRef::lookup(BindingKey K) const {
   const ClusterBindings *Cluster = lookup(K.getBaseRegion());
   if (!Cluster)
-    return 0;
+    return nullptr;
   return Cluster->lookup(K);
 }
 
@@ -376,9 +372,9 @@
   ///  version of that lvalue (i.e., a pointer to the first element of
   ///  the array).  This is called by ExprEngine when evaluating
   ///  casts from arrays to pointers.
-  SVal ArrayToPointer(Loc Array, QualType ElementTy);
+  SVal ArrayToPointer(Loc Array, QualType ElementTy) override;
 
-  StoreRef getInitialStore(const LocationContext *InitLoc) {
+  StoreRef getInitialStore(const LocationContext *InitLoc) override {
     return StoreRef(RBFactory.getEmptyMap().getRootWithoutRetain(), *this);
   }
 
@@ -400,24 +396,24 @@
                              InvalidatedSymbols &IS,
                              RegionAndSymbolInvalidationTraits &ITraits,
                              InvalidatedRegions *Invalidated,
-                             InvalidatedRegions *InvalidatedTopLevel);
+                             InvalidatedRegions *InvalidatedTopLevel) override;
 
   bool scanReachableSymbols(Store S, const MemRegion *R,
-                            ScanReachableSymbols &Callbacks);
+                            ScanReachableSymbols &Callbacks) override;
 
   RegionBindingsRef removeSubRegionBindings(RegionBindingsConstRef B,
                                             const SubRegion *R);
 
 public: // Part of public interface to class.
 
-  virtual StoreRef Bind(Store store, Loc LV, SVal V) {
+  StoreRef Bind(Store store, Loc LV, SVal V) override {
     return StoreRef(bind(getRegionBindings(store), LV, V).asStore(), *this);
   }
 
   RegionBindingsRef bind(RegionBindingsConstRef B, Loc LV, SVal V);
 
   // BindDefault is only used to initialize a region with a default value.
-  StoreRef BindDefault(Store store, const MemRegion *R, SVal V) {
+  StoreRef BindDefault(Store store, const MemRegion *R, SVal V) override {
     RegionBindingsRef B = getRegionBindings(store);
     assert(!B.lookup(R, BindingKey::Direct));
 
@@ -471,20 +467,20 @@
   /// \brief Create a new store with the specified binding removed.
   /// \param ST the original store, that is the basis for the new store.
   /// \param L the location whose binding should be removed.
-  virtual StoreRef killBinding(Store ST, Loc L);
+  StoreRef killBinding(Store ST, Loc L) override;
 
-  void incrementReferenceCount(Store store) {
+  void incrementReferenceCount(Store store) override {
     getRegionBindings(store).manualRetain();    
   }
   
   /// If the StoreManager supports it, decrement the reference count of
   /// the specified Store object.  If the reference count hits 0, the memory
   /// associated with the object is recycled.
-  void decrementReferenceCount(Store store) {
+  void decrementReferenceCount(Store store) override {
     getRegionBindings(store).manualRelease();
   }
-  
-  bool includedInBindings(Store store, const MemRegion *region) const;
+
+  bool includedInBindings(Store store, const MemRegion *region) const override;
 
   /// \brief Return the value bound to specified location in a given state.
   ///
@@ -499,7 +495,7 @@
   ///       return undefined
   ///     else
   ///       return symbolic
-  virtual SVal getBinding(Store S, Loc L, QualType T) {
+  SVal getBinding(Store S, Loc L, QualType T) override {
     return getBinding(getRegionBindings(S), L, T);
   }
 
@@ -564,15 +560,16 @@
   /// removeDeadBindings - Scans the RegionStore of 'state' for dead values.
   ///  It returns a new Store with these values removed.
   StoreRef removeDeadBindings(Store store, const StackFrameContext *LCtx,
-                              SymbolReaper& SymReaper);
-  
+                              SymbolReaper& SymReaper) override;
+
   //===------------------------------------------------------------------===//
   // Region "extents".
   //===------------------------------------------------------------------===//
 
   // FIXME: This method will soon be eliminated; see the note in Store.h.
   DefinedOrUnknownSVal getSizeInElements(ProgramStateRef state,
-                                         const MemRegion* R, QualType EleTy);
+                                         const MemRegion* R,
+                                         QualType EleTy) override;
 
   //===------------------------------------------------------------------===//
   // Utility methods.
@@ -585,9 +582,9 @@
   }
 
   void print(Store store, raw_ostream &Out, const char* nl,
-             const char *sep);
+             const char *sep) override;
 
-  void iterBindings(Store store, BindingsHandler& f) {
+  void iterBindings(Store store, BindingsHandler& f) override {
     RegionBindingsRef B = getRegionBindings(store);
     for (RegionBindingsRef::iterator I = B.begin(), E = B.end(); I != E; ++I) {
       const ClusterBindings &Cluster = I.getData();
@@ -1016,7 +1013,7 @@
          BI != BE; ++BI) {
       const VarRegion *VR = BI.getCapturedRegion();
       const VarDecl *VD = VR->getDecl();
-      if (VD->getAttr<BlocksAttr>() || !VD->hasLocalStorage()) {
+      if (VD->hasAttr<BlocksAttr>() || !VD->hasLocalStorage()) {
         AddToWorkList(VR);
       }
       else if (Loc::isLocType(VR->getValueType())) {
@@ -1628,9 +1625,9 @@
   // getBindingForField if 'R' has a direct binding.
 
   // Lazy binding?
-  Store lazyBindingStore = NULL;
-  const SubRegion *lazyBindingRegion = NULL;
-  llvm::tie(lazyBindingStore, lazyBindingRegion) = findLazyBinding(B, R, R);
+  Store lazyBindingStore = nullptr;
+  const SubRegion *lazyBindingRegion = nullptr;
+  std::tie(lazyBindingStore, lazyBindingRegion) = findLazyBinding(B, R, R);
   if (lazyBindingRegion)
     return getLazyBinding(lazyBindingRegion,
                           getRegionBindings(lazyBindingStore));
@@ -1791,7 +1788,7 @@
   // values to return.
   const ClusterBindings *Cluster = B.lookup(LazyR->getBaseRegion());
   if (!Cluster)
-    return (LazyBindingsMap[LCV.getCVData()] = llvm_move(List));
+    return (LazyBindingsMap[LCV.getCVData()] = std::move(List));
 
   SmallVector<BindingPair, 32> Bindings;
   collectSubRegionBindings(Bindings, svalBuilder, *Cluster, LazyR,
@@ -1813,7 +1810,7 @@
     List.push_back(V);
   }
 
-  return (LazyBindingsMap[LCV.getCVData()] = llvm_move(List));
+  return (LazyBindingsMap[LCV.getCVData()] = std::move(List));
 }
 
 NonLoc RegionStoreManager::createLazyBinding(RegionBindingsConstRef B,
@@ -2066,9 +2063,7 @@
     if (Class->getNumBases() != 0 || Class->getNumVBases() != 0)
       return None;
 
-  for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
-       I != E; ++I) {
-    const FieldDecl *FD = *I;
+  for (const auto *FD : RD->fields()) {
     if (FD->isUnnamedBitfield())
       continue;
 
@@ -2081,7 +2076,7 @@
     if (!(Ty->isScalarType() || Ty->isReferenceType()))
       return None;
 
-    Fields.push_back(*I);
+    Fields.push_back(FD);
   }
 
   RegionBindingsRef NewB = B;
@@ -2296,7 +2291,7 @@
     if (const SymbolicRegion *SR = *I) {
       if (SymReaper.isLive(SR->getSymbol())) {
         changed |= AddToWorkList(SR);
-        *I = NULL;
+        *I = nullptr;
       }
     }
   }
diff --git a/lib/StaticAnalyzer/Core/SValBuilder.cpp b/lib/StaticAnalyzer/Core/SValBuilder.cpp
index 2142f06..3ed2bde 100644
--- a/lib/StaticAnalyzer/Core/SValBuilder.cpp
+++ b/lib/StaticAnalyzer/Core/SValBuilder.cpp
@@ -202,10 +202,12 @@
 
 DefinedSVal SValBuilder::getBlockPointer(const BlockDecl *block,
                                          CanQualType locTy,
-                                         const LocationContext *locContext) {
+                                         const LocationContext *locContext,
+                                         unsigned blockCount) {
   const BlockTextRegion *BC =
     MemMgr.getBlockTextRegion(block, locTy, locContext->getAnalysisDeclContext());
-  const BlockDataRegion *BD = MemMgr.getBlockDataRegion(BC, locContext);
+  const BlockDataRegion *BD = MemMgr.getBlockDataRegion(BC, locContext,
+                                                        blockCount);
   return loc::MemRegionVal(BD);
 }
 
@@ -360,7 +362,7 @@
 DefinedOrUnknownSVal SValBuilder::evalEQ(ProgramStateRef state,
                                          DefinedOrUnknownSVal lhs,
                                          DefinedOrUnknownSVal rhs) {
-  return evalBinOp(state, BO_EQ, lhs, rhs, Context.IntTy)
+  return evalBinOp(state, BO_EQ, lhs, rhs, getConditionType())
       .castAs<DefinedOrUnknownSVal>();
 }
 
@@ -374,7 +376,7 @@
     ToTy = Context.getUnqualifiedArrayType(ToTy, Quals1);
     FromTy = Context.getUnqualifiedArrayType(FromTy, Quals2);
 
-    // Make sure that non cvr-qualifiers the other qualifiers (e.g., address
+    // Make sure that non-cvr-qualifiers the other qualifiers (e.g., address
     // spaces) are identical.
     Quals1.removeCVRQualifiers();
     Quals2.removeCVRQualifiers();
diff --git a/lib/StaticAnalyzer/Core/SVals.cpp b/lib/StaticAnalyzer/Core/SVals.cpp
index 6506915..8de939f 100644
--- a/lib/StaticAnalyzer/Core/SVals.cpp
+++ b/lib/StaticAnalyzer/Core/SVals.cpp
@@ -56,7 +56,7 @@
         return FD;
   }
 
-  return 0;
+  return nullptr;
 }
 
 /// \brief If this SVal is a location (subclasses Loc) and wraps a symbol,
@@ -78,7 +78,7 @@
                                       dyn_cast<SymbolicRegion>(R->StripCasts()))
       return SymR->getSymbol();
   }
-  return 0;
+  return nullptr;
 }
 
 /// Get the symbol in the SVal or its base region.
@@ -86,7 +86,7 @@
   Optional<loc::MemRegionVal> X = getAs<loc::MemRegionVal>();
 
   if (!X)
-    return 0;
+    return nullptr;
 
   const MemRegion *R = X->getRegion();
 
@@ -97,7 +97,7 @@
       R = SR->getSuperRegion();
   }
 
-  return 0;
+  return nullptr;
 }
 
 // TODO: The next 3 functions have to be simplified.
@@ -139,12 +139,12 @@
   if (Optional<nonloc::LocAsInteger> X = getAs<nonloc::LocAsInteger>())
     return X->getLoc().getAsRegion();
 
-  return 0;
+  return nullptr;
 }
 
 const MemRegion *loc::MemRegionVal::stripCasts(bool StripBaseCasts) const {
   const MemRegion *R = getRegion();
-  return R ?  R->StripCasts(StripBaseCasts) : NULL;
+  return R ?  R->StripCasts(StripBaseCasts) : nullptr;
 }
 
 const void *nonloc::LazyCompoundVal::getStore() const {
diff --git a/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp b/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
index e6653ae..35930e4 100644
--- a/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
+++ b/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
@@ -181,7 +181,7 @@
   case nonloc::ConcreteIntKind: {
     bool b = Cond.castAs<nonloc::ConcreteInt>().getValue() != 0;
     bool isFeasible = b ? Assumption : !Assumption;
-    return isFeasible ? state : NULL;
+    return isFeasible ? state : nullptr;
   }
 
   case nonloc::LocAsIntegerKind:
diff --git a/lib/StaticAnalyzer/Core/SimpleConstraintManager.h b/lib/StaticAnalyzer/Core/SimpleConstraintManager.h
index 28a9a4d..21e2283 100644
--- a/lib/StaticAnalyzer/Core/SimpleConstraintManager.h
+++ b/lib/StaticAnalyzer/Core/SimpleConstraintManager.h
@@ -34,7 +34,7 @@
   //===------------------------------------------------------------------===//
 
   ProgramStateRef assume(ProgramStateRef state, DefinedSVal Cond,
-                        bool Assumption);
+                        bool Assumption) override;
 
   ProgramStateRef assume(ProgramStateRef state, NonLoc Cond, bool Assumption);
 
@@ -82,7 +82,7 @@
   BasicValueFactory &getBasicVals() const { return SVB.getBasicValueFactory(); }
   SymbolManager &getSymbolManager() const { return SVB.getSymbolManager(); }
 
-  bool canReasonAbout(SVal X) const;
+  bool canReasonAbout(SVal X) const override;
 
   ProgramStateRef assumeAux(ProgramStateRef state,
                                 NonLoc Cond,
diff --git a/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
index cc0ee0b..df9e4d6 100644
--- a/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
+++ b/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
@@ -21,9 +21,9 @@
 namespace {
 class SimpleSValBuilder : public SValBuilder {
 protected:
-  virtual SVal dispatchCast(SVal val, QualType castTy);
-  virtual SVal evalCastFromNonLoc(NonLoc val, QualType castTy);
-  virtual SVal evalCastFromLoc(Loc val, QualType castTy);
+  SVal dispatchCast(SVal val, QualType castTy) override;
+  SVal evalCastFromNonLoc(NonLoc val, QualType castTy) override;
+  SVal evalCastFromLoc(Loc val, QualType castTy) override;
 
 public:
   SimpleSValBuilder(llvm::BumpPtrAllocator &alloc, ASTContext &context,
@@ -31,19 +31,19 @@
                     : SValBuilder(alloc, context, stateMgr) {}
   virtual ~SimpleSValBuilder() {}
 
-  virtual SVal evalMinus(NonLoc val);
-  virtual SVal evalComplement(NonLoc val);
-  virtual SVal evalBinOpNN(ProgramStateRef state, BinaryOperator::Opcode op,
-                           NonLoc lhs, NonLoc rhs, QualType resultTy);
-  virtual SVal evalBinOpLL(ProgramStateRef state, BinaryOperator::Opcode op,
-                           Loc lhs, Loc rhs, QualType resultTy);
-  virtual SVal evalBinOpLN(ProgramStateRef state, BinaryOperator::Opcode op,
-                           Loc lhs, NonLoc rhs, QualType resultTy);
+  SVal evalMinus(NonLoc val) override;
+  SVal evalComplement(NonLoc val) override;
+  SVal evalBinOpNN(ProgramStateRef state, BinaryOperator::Opcode op,
+                   NonLoc lhs, NonLoc rhs, QualType resultTy) override;
+  SVal evalBinOpLL(ProgramStateRef state, BinaryOperator::Opcode op,
+                   Loc lhs, Loc rhs, QualType resultTy) override;
+  SVal evalBinOpLN(ProgramStateRef state, BinaryOperator::Opcode op,
+                   Loc lhs, NonLoc rhs, QualType resultTy) override;
 
   /// getKnownValue - evaluates a given SVal. If the SVal has only one possible
   ///  (integer) value, that value is returned. Otherwise, returns NULL.
-  virtual const llvm::APSInt *getKnownValue(ProgramStateRef state, SVal V);
-  
+  const llvm::APSInt *getKnownValue(ProgramStateRef state, SVal V) override;
+
   SVal MakeSymIntVal(const SymExpr *LHS, BinaryOperator::Opcode op,
                      const llvm::APSInt &RHS, QualType resultTy);
 };
@@ -97,7 +97,7 @@
     return UnknownVal();
   }
 
-  // If value is a non integer constant, produce unknown.
+  // If value is a non-integer constant, produce unknown.
   if (!val.getAs<nonloc::ConcreteInt>())
     return UnknownVal();
 
@@ -108,7 +108,7 @@
   }
 
   // Only handle casts from integers to integers - if val is an integer constant
-  // being cast to a non integer type, produce unknown.
+  // being cast to a non-integer type, produce unknown.
   if (!isLocType && !castTy->isIntegralOrEnumerationType())
     return UnknownVal();
 
@@ -158,7 +158,7 @@
       }
 
       case loc::GotoLabelKind:
-        // Labels and non symbolic memory regions are always true.
+        // Labels and non-symbolic memory regions are always true.
         return makeTruthVal(true, castTy);
     }
   }
@@ -569,11 +569,10 @@
   // members and the units in which bit-fields reside have addresses that
   // increase in the order in which they are declared."
   bool leftFirst = (op == BO_LT || op == BO_LE);
-  for (RecordDecl::field_iterator I = RD->field_begin(),
-       E = RD->field_end(); I!=E; ++I) {
-    if (*I == LeftFD)
+  for (const auto *I : RD->fields()) {
+    if (I == LeftFD)
       return SVB.makeTruthVal(leftFirst, resultTy);
-    if (*I == RightFD)
+    if (I == RightFD)
       return SVB.makeTruthVal(!leftFirst, resultTy);
   }
 
@@ -818,7 +817,7 @@
     RegionOffset LeftOffset = LeftMR->getAsOffset();
     RegionOffset RightOffset = RightMR->getAsOffset();
 
-    if (LeftOffset.getRegion() != NULL &&
+    if (LeftOffset.getRegion() != nullptr &&
         LeftOffset.getRegion() == RightOffset.getRegion() &&
         !LeftOffset.hasSymbolicOffset() && !RightOffset.hasSymbolicOffset()) {
       int64_t left = LeftOffset.getOffset();
@@ -901,7 +900,7 @@
   if (const MemRegion *region = lhs.getAsRegion()) {
     rhs = convertToArrayIndex(rhs).castAs<NonLoc>();
     SVal index = UnknownVal();
-    const MemRegion *superR = 0;
+    const MemRegion *superR = nullptr;
     QualType elementType;
 
     if (const ElementRegion *elemReg = dyn_cast<ElementRegion>(region)) {
@@ -929,7 +928,7 @@
 const llvm::APSInt *SimpleSValBuilder::getKnownValue(ProgramStateRef state,
                                                    SVal V) {
   if (V.isUnknownOrUndef())
-    return NULL;
+    return nullptr;
 
   if (Optional<loc::ConcreteInt> X = V.getAs<loc::ConcreteInt>())
     return &X->getValue();
@@ -941,5 +940,5 @@
     return state->getConstraintManager().getSymVal(state, Sym);
 
   // FIXME: Add support for SymExprs.
-  return NULL;
+  return nullptr;
 }
diff --git a/lib/StaticAnalyzer/Core/Store.cpp b/lib/StaticAnalyzer/Core/Store.cpp
index 0beb9db..e38be3e 100644
--- a/lib/StaticAnalyzer/Core/Store.cpp
+++ b/lib/StaticAnalyzer/Core/Store.cpp
@@ -88,7 +88,7 @@
 
     // We don't know what to make of it.  Return a NULL region, which
     // will be interpretted as UnknownVal.
-    return NULL;
+    return nullptr;
   }
 
   // Now assume we are casting from pointer to pointer. Other cases should
@@ -166,7 +166,7 @@
       // If we cannot compute a raw offset, throw up our hands and return
       // a NULL MemRegion*.
       if (!baseR)
-        return NULL;
+        return nullptr;
 
       CharUnits off = rawOff.getOffset();
 
@@ -193,7 +193,7 @@
 
       // Compute the index for the new ElementRegion.
       int64_t newIndex = 0;
-      const MemRegion *newSuperR = 0;
+      const MemRegion *newSuperR = nullptr;
 
       // We can only compute sizeof(PointeeTy) if it is a complete type.
       if (IsCompleteType(Ctx, PointeeTy)) {
@@ -300,7 +300,7 @@
     return TVR->getValueType()->getAsCXXRecordDecl();
   if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR))
     return SR->getSymbol()->getType()->getPointeeCXXRecordDecl();
-  return 0;
+  return nullptr;
 }
 
 SVal StoreManager::evalDynamicCast(SVal Base, QualType TargetType,
@@ -401,7 +401,7 @@
     return Base;
 
   Loc BaseL = Base.castAs<Loc>();
-  const MemRegion* BaseR = 0;
+  const MemRegion* BaseR = nullptr;
 
   switch (BaseL.getSubKind()) {
   case loc::MemRegionKind:
diff --git a/lib/StaticAnalyzer/Core/SymbolManager.cpp b/lib/StaticAnalyzer/Core/SymbolManager.cpp
index 1b56f82..cca0461 100644
--- a/lib/StaticAnalyzer/Core/SymbolManager.cpp
+++ b/lib/StaticAnalyzer/Core/SymbolManager.cpp
@@ -326,11 +326,7 @@
 }
 
 SymbolManager::~SymbolManager() {
-  for (SymbolDependTy::const_iterator I = SymbolDependencies.begin(),
-       E = SymbolDependencies.end(); I != E; ++I) {
-    delete I->second;
-  }
-
+  llvm::DeleteContainerSeconds(SymbolDependencies);
 }
 
 bool SymbolManager::canSymbolicate(QualType T) {
@@ -351,7 +347,7 @@
 void SymbolManager::addSymbolDependency(const SymbolRef Primary,
                                         const SymbolRef Dependent) {
   SymbolDependTy::iterator I = SymbolDependencies.find(Primary);
-  SymbolRefSmallVectorTy *dependencies = 0;
+  SymbolRefSmallVectorTy *dependencies = nullptr;
   if (I == SymbolDependencies.end()) {
     dependencies = new SymbolRefSmallVectorTy();
     SymbolDependencies[Primary] = dependencies;
@@ -365,7 +361,7 @@
                                                      const SymbolRef Primary) {
   SymbolDependTy::const_iterator I = SymbolDependencies.find(Primary);
   if (I == SymbolDependencies.end())
-    return 0;
+    return nullptr;
   return I->second;
 }
 
@@ -491,7 +487,7 @@
 
 bool
 SymbolReaper::isLive(const Stmt *ExprVal, const LocationContext *ELCtx) const {
-  if (LCtx == 0)
+  if (LCtx == nullptr)
     return false;
 
   if (LCtx != ELCtx) {
diff --git a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
index 9efe997..f0dd274 100644
--- a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
@@ -11,15 +11,13 @@
 //
 //===----------------------------------------------------------------------===//
 
-#define DEBUG_TYPE "AnalysisConsumer"
-
-#include "AnalysisConsumer.h"
+#include "clang/StaticAnalyzer/Frontend/AnalysisConsumer.h"
 #include "clang/AST/ASTConsumer.h"
+#include "clang/AST/DataRecursiveASTVisitor.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/ParentMap.h"
-#include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/Analysis/Analyses/LiveVariables.h"
 #include "clang/Analysis/CFG.h"
 #include "clang/Analysis/CallGraph.h"
@@ -36,7 +34,6 @@
 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
 #include "clang/StaticAnalyzer/Frontend/CheckerRegistration.h"
 #include "llvm/ADT/DepthFirstIterator.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/PostOrderIterator.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/Statistic.h"
@@ -45,12 +42,15 @@
 #include "llvm/Support/Program.h"
 #include "llvm/Support/Timer.h"
 #include "llvm/Support/raw_ostream.h"
+#include <memory>
 #include <queue>
 
 using namespace clang;
 using namespace ento;
 using llvm::SmallPtrSet;
 
+#define DEBUG_TYPE "AnalysisConsumer"
+
 static ExplodedNode::Auditor* CreateUbiViz();
 
 STATISTIC(NumFunctionTopLevel, "The # of functions at top level.");
@@ -90,12 +90,12 @@
   ClangDiagPathDiagConsumer(DiagnosticsEngine &Diag)
     : Diag(Diag), IncludePath(false) {}
   virtual ~ClangDiagPathDiagConsumer() {}
-  virtual StringRef getName() const { return "ClangDiags"; }
+  StringRef getName() const override { return "ClangDiags"; }
 
-  virtual bool supportsLogicalOpControlFlow() const { return true; }
-  virtual bool supportsCrossFileDiagnostics() const { return true; }
+  bool supportsLogicalOpControlFlow() const override { return true; }
+  bool supportsCrossFileDiagnostics() const override { return true; }
 
-  virtual PathGenerationScheme getGenerationScheme() const {
+  PathGenerationScheme getGenerationScheme() const override {
     return IncludePath ? Minimal : None;
   }
 
@@ -103,35 +103,17 @@
     IncludePath = true;
   }
 
-  void emitDiag(SourceLocation L, unsigned DiagID,
-                ArrayRef<SourceRange> Ranges) {
-    DiagnosticBuilder DiagBuilder = Diag.Report(L, DiagID);
-
-    for (ArrayRef<SourceRange>::iterator I = Ranges.begin(), E = Ranges.end();
-         I != E; ++I) {
-      DiagBuilder << *I;
-    }
-  }
-
   void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags,
-                            FilesMade *filesMade) {
+                            FilesMade *filesMade) override {
+    unsigned WarnID = Diag.getCustomDiagID(DiagnosticsEngine::Warning, "%0");
+    unsigned NoteID = Diag.getCustomDiagID(DiagnosticsEngine::Note, "%0");
+
     for (std::vector<const PathDiagnostic*>::iterator I = Diags.begin(),
          E = Diags.end(); I != E; ++I) {
       const PathDiagnostic *PD = *I;
-      StringRef desc = PD->getShortDescription();
-      SmallString<512> TmpStr;
-      llvm::raw_svector_ostream Out(TmpStr);
-      for (StringRef::iterator I=desc.begin(), E=desc.end(); I!=E; ++I) {
-        if (*I == '%')
-          Out << "%%";
-        else
-          Out << *I;
-      }
-      Out.flush();
-      unsigned ErrorDiag = Diag.getCustomDiagID(DiagnosticsEngine::Warning,
-                                                TmpStr);
-      SourceLocation L = PD->getLocation().asLocation();
-      emitDiag(L, ErrorDiag, PD->path.back()->getRanges());
+      SourceLocation WarnLoc = PD->getLocation().asLocation();
+      Diag.Report(WarnLoc, WarnID) << PD->getShortDescription()
+                                   << PD->path.back()->getRanges();
 
       if (!IncludePath)
         continue;
@@ -140,11 +122,9 @@
       for (PathPieces::const_iterator PI = FlatPath.begin(),
                                       PE = FlatPath.end();
            PI != PE; ++PI) {
-        unsigned NoteID = Diag.getCustomDiagID(DiagnosticsEngine::Note,
-                                               (*PI)->getString());
-
         SourceLocation NoteLoc = (*PI)->getLocation().asLocation();
-        emitDiag(NoteLoc, NoteID, (*PI)->getRanges());
+        Diag.Report(NoteLoc, NoteID) << (*PI)->getString()
+                                     << (*PI)->getRanges();
       }
     }
   }
@@ -157,8 +137,8 @@
 
 namespace {
 
-class AnalysisConsumer : public ASTConsumer,
-                         public RecursiveASTVisitor<AnalysisConsumer> {
+class AnalysisConsumer : public AnalysisASTConsumer,
+                         public DataRecursiveASTVisitor<AnalysisConsumer> {
   enum {
     AM_None = 0,
     AM_Syntax = 0x1,
@@ -191,8 +171,8 @@
   StoreManagerCreator CreateStoreMgr;
   ConstraintManagerCreator CreateConstraintMgr;
 
-  OwningPtr<CheckerManager> checkerMgr;
-  OwningPtr<AnalysisManager> Mgr;
+  std::unique_ptr<CheckerManager> checkerMgr;
+  std::unique_ptr<AnalysisManager> Mgr;
 
   /// Time the analyzes time of each translation unit.
   static llvm::Timer* TUTotalTimer;
@@ -205,8 +185,8 @@
                    const std::string& outdir,
                    AnalyzerOptionsRef opts,
                    ArrayRef<std::string> plugins)
-    : RecVisitorMode(0), RecVisitorBR(0),
-      Ctx(0), PP(pp), OutDir(outdir), Opts(opts), Plugins(plugins) {
+    : RecVisitorMode(0), RecVisitorBR(nullptr),
+      Ctx(nullptr), PP(pp), OutDir(outdir), Opts(opts), Plugins(plugins) {
     DigestAnalyzerOptions();
     if (Opts->PrintStats) {
       llvm::EnableStatistics();
@@ -220,21 +200,24 @@
   }
 
   void DigestAnalyzerOptions() {
-    // Create the PathDiagnosticConsumer.
-    ClangDiagPathDiagConsumer *clangDiags =
-      new ClangDiagPathDiagConsumer(PP.getDiagnostics());
-    PathConsumers.push_back(clangDiags);
+    if (Opts->AnalysisDiagOpt != PD_NONE) {
+      // Create the PathDiagnosticConsumer.
+      ClangDiagPathDiagConsumer *clangDiags =
+          new ClangDiagPathDiagConsumer(PP.getDiagnostics());
+      PathConsumers.push_back(clangDiags);
 
-    if (Opts->AnalysisDiagOpt == PD_TEXT) {
-      clangDiags->enablePaths();
+      if (Opts->AnalysisDiagOpt == PD_TEXT) {
+        clangDiags->enablePaths();
 
-    } else if (!OutDir.empty()) {
-      switch (Opts->AnalysisDiagOpt) {
-      default:
-#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN) \
-        case PD_##NAME: CREATEFN(*Opts.getPtr(), PathConsumers, OutDir, PP);\
-        break;
+      } else if (!OutDir.empty()) {
+        switch (Opts->AnalysisDiagOpt) {
+        default:
+#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN)                    \
+  case PD_##NAME:                                                              \
+    CREATEFN(*Opts.get(), PathConsumers, OutDir, PP);                       \
+    break;
 #include "clang/StaticAnalyzer/Core/Analyses.def"
+        }
       }
     }
 
@@ -299,7 +282,7 @@
     }
   }
 
-  virtual void Initialize(ASTContext &Context) {
+  void Initialize(ASTContext &Context) override {
     Ctx = &Context;
     checkerMgr.reset(createCheckerManager(*Opts, PP.getLangOpts(), Plugins,
                                           PP.getDiagnostics()));
@@ -315,16 +298,16 @@
 
   /// \brief Store the top level decls in the set to be processed later on.
   /// (Doing this pre-processing avoids deserialization of data from PCH.)
-  virtual bool HandleTopLevelDecl(DeclGroupRef D);
-  virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef D);
+  bool HandleTopLevelDecl(DeclGroupRef D) override;
+  void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override;
 
-  virtual void HandleTranslationUnit(ASTContext &C);
+  void HandleTranslationUnit(ASTContext &C) override;
 
   /// \brief Determine which inlining mode should be used when this function is
   /// analyzed. This allows to redefine the default inlining policies when
   /// analyzing a given function.
   ExprEngine::InliningModes
-  getInliningModeForFunction(const Decl *D, SetOfConstDecls Visited);
+  getInliningModeForFunction(const Decl *D, const SetOfConstDecls &Visited);
 
   /// \brief Build the call graph for all the top level decls of this TU and
   /// use it to define the order in which the functions should be visited.
@@ -338,7 +321,7 @@
   /// given root function.
   void HandleCode(Decl *D, AnalysisMode Mode,
                   ExprEngine::InliningModes IMode = ExprEngine::Inline_Minimal,
-                  SetOfConstDecls *VisitedCallees = 0);
+                  SetOfConstDecls *VisitedCallees = nullptr);
 
   void RunPathSensitiveChecks(Decl *D,
                               ExprEngine::InliningModes IMode,
@@ -389,6 +372,11 @@
     return true;
   }
 
+  virtual void
+  AddDiagnosticConsumer(PathDiagnosticConsumer *Consumer) override {
+    PathConsumers.push_back(Consumer);
+  }
+
 private:
   void storeTopLevelDecls(DeclGroupRef DG);
 
@@ -402,7 +390,7 @@
 //===----------------------------------------------------------------------===//
 // AnalysisConsumer implementation.
 //===----------------------------------------------------------------------===//
-llvm::Timer* AnalysisConsumer::TUTotalTimer = 0;
+llvm::Timer* AnalysisConsumer::TUTotalTimer = nullptr;
 
 bool AnalysisConsumer::HandleTopLevelDecl(DeclGroupRef DG) {
   storeTopLevelDecls(DG);
@@ -426,8 +414,8 @@
 }
 
 static bool shouldSkipFunction(const Decl *D,
-                               SetOfConstDecls Visited,
-                               SetOfConstDecls VisitedAsTopLevel) {
+                               const SetOfConstDecls &Visited,
+                               const SetOfConstDecls &VisitedAsTopLevel) {
   if (VisitedAsTopLevel.count(D))
     return true;
 
@@ -447,7 +435,7 @@
 
 ExprEngine::InliningModes
 AnalysisConsumer::getInliningModeForFunction(const Decl *D,
-                                             SetOfConstDecls Visited) {
+                                             const SetOfConstDecls &Visited) {
   // We want to reanalyze all ObjC methods as top level to report Retain
   // Count naming convention errors more aggressively. But we should tune down
   // inlining when reanalyzing an already inlined function.
@@ -501,7 +489,7 @@
     SetOfConstDecls VisitedCallees;
 
     HandleCode(D, AM_Path, getInliningModeForFunction(D, Visited),
-               (Mgr->options.InliningMode == All ? 0 : &VisitedCallees));
+               (Mgr->options.InliningMode == All ? nullptr : &VisitedCallees));
 
     // Add the visited callees to the global visited set.
     for (SetOfConstDecls::iterator I = VisitedCallees.begin(),
@@ -551,14 +539,14 @@
     // After all decls handled, run checkers on the entire TranslationUnit.
     checkerMgr->runCheckersOnEndOfTranslationUnit(TU, *Mgr, BR);
 
-    RecVisitorBR = 0;
+    RecVisitorBR = nullptr;
   }
 
   // Explicitly destroy the PathDiagnosticConsumer.  This will flush its output.
   // FIXME: This should be replaced with something that doesn't rely on
   // side-effects in PathDiagnosticConsumer's destructor. This is required when
   // used with option -disable-free.
-  Mgr.reset(NULL);
+  Mgr.reset();
 
   if (TUTotalTimer) TUTotalTimer->stopTimer();
 
@@ -653,7 +641,7 @@
   ExprEngine Eng(*Mgr, ObjCGCEnabled, VisitedCallees, &FunctionSummaries,IMode);
 
   // Set the graph auditor.
-  OwningPtr<ExplodedNode::Auditor> Auditor;
+  std::unique_ptr<ExplodedNode::Auditor> Auditor;
   if (Mgr->options.visualizeExplodedGraphWithUbiGraph) {
     Auditor.reset(CreateUbiViz());
     ExplodedNode::SetAuditor(Auditor.get());
@@ -665,7 +653,7 @@
 
   // Release the auditor (if any) so that it doesn't monitor the graph
   // created BugReporter.
-  ExplodedNode::SetAuditor(0);
+  ExplodedNode::SetAuditor(nullptr);
 
   // Visualize the exploded graph.
   if (Mgr->options.visualizeExplodedGraphWithGraphViz)
@@ -699,10 +687,10 @@
 // AnalysisConsumer creation.
 //===----------------------------------------------------------------------===//
 
-ASTConsumer* ento::CreateAnalysisConsumer(const Preprocessor& pp,
-                                          const std::string& outDir,
-                                          AnalyzerOptionsRef opts,
-                                          ArrayRef<std::string> plugins) {
+AnalysisASTConsumer *
+ento::CreateAnalysisConsumer(const Preprocessor &pp, const std::string &outDir,
+                             AnalyzerOptionsRef opts,
+                             ArrayRef<std::string> plugins) {
   // Disable the effects of '-Werror' when using the AnalysisConsumer.
   pp.getDiagnostics().setWarningsAsErrors(false);
 
@@ -716,7 +704,7 @@
 namespace {
 
 class UbigraphViz : public ExplodedNode::Auditor {
-  OwningPtr<raw_ostream> Out;
+  std::unique_ptr<raw_ostream> Out;
   std::string Filename;
   unsigned Cntr;
 
@@ -724,11 +712,11 @@
   VMap M;
 
 public:
-  UbigraphViz(raw_ostream *Out, StringRef Filename);
+  UbigraphViz(std::unique_ptr<raw_ostream> Out, StringRef Filename);
 
   ~UbigraphViz();
 
-  virtual void AddEdge(ExplodedNode *Src, ExplodedNode *Dst);
+  void AddEdge(ExplodedNode *Src, ExplodedNode *Dst) override;
 };
 
 } // end anonymous namespace
@@ -739,10 +727,9 @@
   llvm::sys::fs::createTemporaryFile("llvm_ubi", "", FD, P);
   llvm::errs() << "Writing '" << P.str() << "'.\n";
 
-  OwningPtr<llvm::raw_fd_ostream> Stream;
-  Stream.reset(new llvm::raw_fd_ostream(FD, true));
+  auto Stream = llvm::make_unique<llvm::raw_fd_ostream>(FD, true);
 
-  return new UbigraphViz(Stream.take(), P);
+  return new UbigraphViz(std::move(Stream), P);
 }
 
 void UbigraphViz::AddEdge(ExplodedNode *Src, ExplodedNode *Dst) {
@@ -779,8 +766,8 @@
        << ", ('arrow','true'), ('oriented', 'true'))\n";
 }
 
-UbigraphViz::UbigraphViz(raw_ostream *Out, StringRef Filename)
-  : Out(Out), Filename(Filename), Cntr(0) {
+UbigraphViz::UbigraphViz(std::unique_ptr<raw_ostream> Out, StringRef Filename)
+    : Out(std::move(Out)), Filename(Filename), Cntr(0) {
 
   *Out << "('vertex_style_attribute', 0, ('shape', 'icosahedron'))\n";
   *Out << "('vertex_style', 1, 0, ('shape', 'sphere'), ('color', '#ffcc66'),"
@@ -788,16 +775,17 @@
 }
 
 UbigraphViz::~UbigraphViz() {
-  Out.reset(0);
+  Out.reset();
   llvm::errs() << "Running 'ubiviz' program... ";
   std::string ErrMsg;
   std::string Ubiviz = llvm::sys::FindProgramByName("ubiviz");
   std::vector<const char*> args;
   args.push_back(Ubiviz.c_str());
   args.push_back(Filename.c_str());
-  args.push_back(0);
+  args.push_back(nullptr);
 
-  if (llvm::sys::ExecuteAndWait(Ubiviz, &args[0], 0, 0, 0, 0, &ErrMsg)) {
+  if (llvm::sys::ExecuteAndWait(Ubiviz, &args[0], nullptr, nullptr, 0, 0,
+                                &ErrMsg)) {
     llvm::errs() << "Error viewing graph: " << ErrMsg << "\n";
   }
 
diff --git a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.h b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.h
deleted file mode 100644
index b75220b..0000000
--- a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.h
+++ /dev/null
@@ -1,43 +0,0 @@
-//===--- AnalysisConsumer.h - Front-end Analysis Engine Hooks ---*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This header contains the functions necessary for a front-end to run various
-// analyses.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_GR_ANALYSISCONSUMER_H
-#define LLVM_CLANG_GR_ANALYSISCONSUMER_H
-
-#include "clang/Basic/LLVM.h"
-#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
-#include <string>
-
-namespace clang {
-
-class ASTConsumer;
-class Preprocessor;
-class DiagnosticsEngine;
-
-namespace ento {
-class CheckerManager;
-
-/// CreateAnalysisConsumer - Creates an ASTConsumer to run various code
-/// analysis passes.  (The set of analyses run is controlled by command-line
-/// options.)
-ASTConsumer* CreateAnalysisConsumer(const Preprocessor &pp,
-                                    const std::string &output,
-                                    AnalyzerOptionsRef opts,
-                                    ArrayRef<std::string> plugins);
-
-} // end GR namespace
-
-} // end clang namespace
-
-#endif
diff --git a/lib/StaticAnalyzer/Frontend/CMakeLists.txt b/lib/StaticAnalyzer/Frontend/CMakeLists.txt
index aafb249..5349ed9 100644
--- a/lib/StaticAnalyzer/Frontend/CMakeLists.txt
+++ b/lib/StaticAnalyzer/Frontend/CMakeLists.txt
@@ -1,31 +1,19 @@
-set(LLVM_NO_RTTI 1)
-
 include_directories( ${CMAKE_CURRENT_BINARY_DIR}/../Checkers )
 
+set(LLVM_LINK_COMPONENTS
+  Support
+  )
+
 add_clang_library(clangStaticAnalyzerFrontend
   AnalysisConsumer.cpp
   CheckerRegistration.cpp
   FrontendActions.cpp
-  )
 
-add_dependencies(clangStaticAnalyzerFrontend
+  LINK_LIBS
+  clangAST
+  clangAnalysis
+  clangBasic
+  clangFrontend
   clangStaticAnalyzerCheckers
   clangStaticAnalyzerCore
-  ClangAttrClasses
-  ClangAttrList
-  ClangCommentNodes
-  ClangDeclNodes
-  ClangDiagnosticCommon
-  ClangDiagnosticFrontend
-  ClangStmtNodes
-  )
-
-target_link_libraries(clangStaticAnalyzerFrontend
-  clangBasic
-  clangLex
-  clangAST
-  clangFrontend
-  clangRewriteCore
-  clangRewriteFrontend
-  clangStaticAnalyzerCheckers
   )
diff --git a/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp b/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp
index e7def08..e2577c3 100644
--- a/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp
+++ b/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp
@@ -20,11 +20,11 @@
 #include "clang/StaticAnalyzer/Core/CheckerOptInfo.h"
 #include "clang/StaticAnalyzer/Core/CheckerRegistry.h"
 #include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/DynamicLibrary.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
+#include <memory>
 
 using namespace clang;
 using namespace ento;
@@ -40,7 +40,7 @@
 
 public:
   ClangCheckerRegistry(ArrayRef<std::string> plugins,
-                       DiagnosticsEngine *diags = 0);
+                       DiagnosticsEngine *diags = nullptr);
 };
   
 } // end anonymous namespace
@@ -73,7 +73,7 @@
 
 bool ClangCheckerRegistry::isCompatibleAPIVersion(const char *versionString) {
   // If the version string is null, it's not an analyzer plugin.
-  if (versionString == 0)
+  if (!versionString)
     return false;
 
   // For now, none of the static analyzer API is considered stable.
@@ -104,8 +104,8 @@
                                            const LangOptions &langOpts,
                                            ArrayRef<std::string> plugins,
                                            DiagnosticsEngine &diags) {
-  OwningPtr<CheckerManager> checkerMgr(new CheckerManager(langOpts,
-                                                          &opts));
+  std::unique_ptr<CheckerManager> checkerMgr(
+      new CheckerManager(langOpts, &opts));
 
   SmallVector<CheckerOptInfo, 8> checkerOpts;
   for (unsigned i = 0, e = opts.CheckersControlList.size(); i != e; ++i) {
@@ -123,7 +123,7 @@
           << checkerOpts[i].getName();
   }
 
-  return checkerMgr.take();
+  return checkerMgr.release();
 }
 
 void ento::printCheckerHelp(raw_ostream &out, ArrayRef<std::string> plugins) {
diff --git a/lib/StaticAnalyzer/Frontend/FrontendActions.cpp b/lib/StaticAnalyzer/Frontend/FrontendActions.cpp
index 13971af..aa38077 100644
--- a/lib/StaticAnalyzer/Frontend/FrontendActions.cpp
+++ b/lib/StaticAnalyzer/Frontend/FrontendActions.cpp
@@ -8,8 +8,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
-#include "AnalysisConsumer.h"
 #include "clang/Frontend/CompilerInstance.h"
+#include "clang/StaticAnalyzer/Frontend/AnalysisConsumer.h"
 using namespace clang;
 using namespace ento;
 
diff --git a/lib/Tooling/CMakeLists.txt b/lib/Tooling/CMakeLists.txt
index d29e564..2bf9652 100644
--- a/lib/Tooling/CMakeLists.txt
+++ b/lib/Tooling/CMakeLists.txt
@@ -9,22 +9,13 @@
   Refactoring.cpp
   RefactoringCallbacks.cpp
   Tooling.cpp
-  )
 
-add_dependencies(clangTooling
-  ClangAttrClasses
-  ClangAttrList
-  ClangDeclNodes
-  ClangDiagnosticCommon
-  ClangDiagnosticFrontend
-  ClangStmtNodes
-  )
-
-target_link_libraries(clangTooling
-  clangBasic
-  clangFrontend
+  LINK_LIBS
   clangAST
   clangASTMatchers
-  clangRewriteCore
-  clangRewriteFrontend
+  clangBasic
+  clangDriver
+  clangFrontend
+  clangLex
+  clangRewrite
   )
diff --git a/lib/Tooling/CommonOptionsParser.cpp b/lib/Tooling/CommonOptionsParser.cpp
index cce4816..e0b844c 100644
--- a/lib/Tooling/CommonOptionsParser.cpp
+++ b/lib/Tooling/CommonOptionsParser.cpp
@@ -54,12 +54,26 @@
     "\n";
 
 CommonOptionsParser::CommonOptionsParser(int &argc, const char **argv,
+                                         cl::OptionCategory &Category,
                                          const char *Overview) {
-  static cl::opt<std::string> BuildPath(
-      "p", cl::desc("Build path"), cl::Optional);
+  static cl::opt<bool> Help("h", cl::desc("Alias for -help"), cl::Hidden);
+
+  static cl::opt<std::string> BuildPath("p", cl::desc("Build path"),
+                                        cl::Optional, cl::cat(Category));
 
   static cl::list<std::string> SourcePaths(
-      cl::Positional, cl::desc("<source0> [... <sourceN>]"), cl::OneOrMore);
+      cl::Positional, cl::desc("<source0> [... <sourceN>]"), cl::OneOrMore,
+      cl::cat(Category));
+
+  // Hide unrelated options.
+  StringMap<cl::Option*> Options;
+  cl::getRegisteredOptions(Options);
+  for (StringMap<cl::Option *>::iterator I = Options.begin(), E = Options.end();
+       I != E; ++I) {
+    if (I->second->Category != &Category && I->first() != "help" &&
+        I->first() != "version")
+      I->second->setHiddenFlag(cl::ReallyHidden);
+  }
 
   Compilations.reset(FixedCompilationDatabase::loadFromCommandLine(argc,
                                                                    argv));
diff --git a/lib/Tooling/CompilationDatabase.cpp b/lib/Tooling/CompilationDatabase.cpp
index c962055..4b776bf 100644
--- a/lib/Tooling/CompilationDatabase.cpp
+++ b/lib/Tooling/CompilationDatabase.cpp
@@ -13,22 +13,22 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Tooling/CompilationDatabase.h"
-#include "clang/Tooling/CompilationDatabasePluginRegistry.h"
-#include "clang/Tooling/Tooling.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/system_error.h"
-#include <sstream>
-
 #include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticOptions.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/Compilation.h"
 #include "clang/Frontend/TextDiagnosticPrinter.h"
-#include "llvm/Support/Host.h"
+#include "clang/Tooling/CompilationDatabasePluginRegistry.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/SmallString.h"
 #include "llvm/Option/Arg.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/Path.h"
+#include <sstream>
+#include <system_error>
 
 namespace clang {
 namespace tooling {
@@ -44,7 +44,7 @@
        Ie = CompilationDatabasePluginRegistry::end();
        It != Ie; ++It) {
     std::string DatabaseErrorMessage;
-    OwningPtr<CompilationDatabasePlugin> Plugin(It->instantiate());
+    std::unique_ptr<CompilationDatabasePlugin> Plugin(It->instantiate());
     if (CompilationDatabase *DB =
         Plugin->loadFromDirectory(BuildDirectory, DatabaseErrorMessage))
       return DB;
@@ -52,7 +52,7 @@
       ErrorStream << It->getName() << ": " << DatabaseErrorMessage << "\n";
   }
   ErrorMessage = ErrorStream.str();
-  return NULL;
+  return nullptr;
 }
 
 static CompilationDatabase *
@@ -76,7 +76,7 @@
     Directory = llvm::sys::path::parent_path(Directory);
   }
   ErrorMessage = ErrorStream.str();
-  return NULL;
+  return nullptr;
 }
 
 CompilationDatabase *
@@ -151,14 +151,14 @@
 // options.
 class UnusedInputDiagConsumer : public DiagnosticConsumer {
 public:
-  UnusedInputDiagConsumer() : Other(0) {}
+  UnusedInputDiagConsumer() : Other(nullptr) {}
 
   // Useful for debugging, chain diagnostics to another consumer after
   // recording for our own purposes.
   UnusedInputDiagConsumer(DiagnosticConsumer *Other) : Other(Other) {}
 
   virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
-                                const Diagnostic &Info) LLVM_OVERRIDE {
+                                const Diagnostic &Info) override {
     if (Info.getID() == clang::diag::warn_drv_input_file_unused) {
       // Arg 1 for this diagnostic is the option that didn't get used.
       UnusedInputs.push_back(Info.getArgStdStr(0));
@@ -204,19 +204,19 @@
 ///          \li true if successful.
 ///          \li false if \c Args cannot be used for compilation jobs (e.g.
 ///          contains an option like -E or -version).
-bool stripPositionalArgs(std::vector<const char *> Args,
-                         std::vector<std::string> &Result) {
+static bool stripPositionalArgs(std::vector<const char *> Args,
+                                std::vector<std::string> &Result) {
   IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
   UnusedInputDiagConsumer DiagClient;
   DiagnosticsEngine Diagnostics(
       IntrusiveRefCntPtr<clang::DiagnosticIDs>(new DiagnosticIDs()),
       &*DiagOpts, &DiagClient, false);
 
-  // Neither clang executable nor default image name are required since the
-  // jobs the driver builds will not be executed.
-  OwningPtr<driver::Driver> NewDriver(new driver::Driver(
+  // The clang executable path isn't required since the jobs the driver builds
+  // will not be executed.
+  std::unique_ptr<driver::Driver> NewDriver(new driver::Driver(
       /* ClangExecutable= */ "", llvm::sys::getDefaultTargetTriple(),
-      /* DefaultImageName= */ "", Diagnostics));
+      Diagnostics));
   NewDriver->setCheckInputsExist(false);
 
   // This becomes the new argv[0]. The value is actually not important as it
@@ -237,7 +237,13 @@
   // up with no jobs but then this is the user's fault.
   Args.push_back("placeholder.cpp");
 
-  const OwningPtr<driver::Compilation> Compilation(
+  // Remove -no-integrated-as; it's not used for syntax checking,
+  // and it confuses targets which don't support this option.
+  Args.erase(std::remove_if(Args.begin(), Args.end(),
+                            MatchesAny(std::string("-no-integrated-as"))),
+             Args.end());
+
+  const std::unique_ptr<driver::Compilation> Compilation(
       NewDriver->BuildCompilation(Args));
 
   const driver::JobList &Jobs = Compilation->getJobs();
@@ -271,6 +277,7 @@
   End = std::remove_if(Args.begin(), End, MatchesAny(DiagClient.UnusedInputs));
 
   // Remove the -c add above as well. It will be at the end right now.
+  assert(strcmp(*(End - 1), "-c") == 0);
   --End;
 
   Result = std::vector<std::string>(Args.begin() + 1, End);
@@ -283,13 +290,13 @@
                                               Twine Directory) {
   const char **DoubleDash = std::find(Argv, Argv + Argc, StringRef("--"));
   if (DoubleDash == Argv + Argc)
-    return NULL;
+    return nullptr;
   std::vector<const char *> CommandLine(DoubleDash + 1, Argv + Argc);
   Argc = DoubleDash - Argv;
 
   std::vector<std::string> StrippedArgs;
   if (!stripPositionalArgs(CommandLine, StrippedArgs))
-    return 0;
+    return nullptr;
   return new FixedCompilationDatabase(Directory, StrippedArgs);
 }
 
@@ -298,7 +305,8 @@
   std::vector<std::string> ToolCommandLine(1, "clang-tool");
   ToolCommandLine.insert(ToolCommandLine.end(),
                          CommandLine.begin(), CommandLine.end());
-  CompileCommands.push_back(CompileCommand(Directory, ToolCommandLine));
+  CompileCommands.push_back(
+      CompileCommand(Directory, std::move(ToolCommandLine)));
 }
 
 std::vector<CompileCommand>
diff --git a/lib/Tooling/FileMatchTrie.cpp b/lib/Tooling/FileMatchTrie.cpp
index 89979a8..dc9999e 100644
--- a/lib/Tooling/FileMatchTrie.cpp
+++ b/lib/Tooling/FileMatchTrie.cpp
@@ -24,7 +24,7 @@
 /// \brief Default \c PathComparator using \c llvm::sys::fs::equivalent().
 struct DefaultPathComparator : public PathComparator {
   virtual ~DefaultPathComparator() {}
-  virtual bool equivalent(StringRef FileA, StringRef FileB) const {
+  bool equivalent(StringRef FileA, StringRef FileB) const override {
     return FileA == FileB || llvm::sys::fs::equivalent(FileA, FileB);
   }
 };
diff --git a/lib/Tooling/JSONCompilationDatabase.cpp b/lib/Tooling/JSONCompilationDatabase.cpp
index 1e33b41..8b8bd29 100644
--- a/lib/Tooling/JSONCompilationDatabase.cpp
+++ b/lib/Tooling/JSONCompilationDatabase.cpp
@@ -17,7 +17,7 @@
 #include "clang/Tooling/Tooling.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/Path.h"
-#include "llvm/Support/system_error.h"
+#include <system_error>
 
 namespace clang {
 namespace tooling {
@@ -118,15 +118,15 @@
 }
 
 class JSONCompilationDatabasePlugin : public CompilationDatabasePlugin {
-  virtual CompilationDatabase *loadFromDirectory(
-      StringRef Directory, std::string &ErrorMessage) {
+  CompilationDatabase *loadFromDirectory(StringRef Directory,
+                                         std::string &ErrorMessage) override {
     SmallString<1024> JSONDatabasePath(Directory);
     llvm::sys::path::append(JSONDatabasePath, "compile_commands.json");
-    OwningPtr<CompilationDatabase> Database(
+    std::unique_ptr<CompilationDatabase> Database(
         JSONCompilationDatabase::loadFromFile(JSONDatabasePath, ErrorMessage));
     if (!Database)
-      return NULL;
-    return Database.take();
+      return nullptr;
+    return Database.release();
   }
 };
 
@@ -144,37 +144,36 @@
 JSONCompilationDatabase *
 JSONCompilationDatabase::loadFromFile(StringRef FilePath,
                                       std::string &ErrorMessage) {
-  OwningPtr<llvm::MemoryBuffer> DatabaseBuffer;
-  llvm::error_code Result =
-    llvm::MemoryBuffer::getFile(FilePath, DatabaseBuffer);
-  if (Result != 0) {
+  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> DatabaseBuffer =
+      llvm::MemoryBuffer::getFile(FilePath);
+  if (std::error_code Result = DatabaseBuffer.getError()) {
     ErrorMessage = "Error while opening JSON database: " + Result.message();
-    return NULL;
+    return nullptr;
   }
-  OwningPtr<JSONCompilationDatabase> Database(
-    new JSONCompilationDatabase(DatabaseBuffer.take()));
+  std::unique_ptr<JSONCompilationDatabase> Database(
+      new JSONCompilationDatabase(DatabaseBuffer->release()));
   if (!Database->parse(ErrorMessage))
-    return NULL;
-  return Database.take();
+    return nullptr;
+  return Database.release();
 }
 
 JSONCompilationDatabase *
 JSONCompilationDatabase::loadFromBuffer(StringRef DatabaseString,
                                         std::string &ErrorMessage) {
-  OwningPtr<llvm::MemoryBuffer> DatabaseBuffer(
+  std::unique_ptr<llvm::MemoryBuffer> DatabaseBuffer(
       llvm::MemoryBuffer::getMemBuffer(DatabaseString));
-  OwningPtr<JSONCompilationDatabase> Database(
-      new JSONCompilationDatabase(DatabaseBuffer.take()));
+  std::unique_ptr<JSONCompilationDatabase> Database(
+      new JSONCompilationDatabase(DatabaseBuffer.release()));
   if (!Database->parse(ErrorMessage))
-    return NULL;
-  return Database.take();
+    return nullptr;
+  return Database.release();
 }
 
 std::vector<CompileCommand>
 JSONCompilationDatabase::getCompileCommands(StringRef FilePath) const {
   SmallString<128> NativeFilePath;
   llvm::sys::path::native(FilePath, NativeFilePath);
-  std::vector<StringRef> PossibleMatches;
+
   std::string Error;
   llvm::raw_string_ostream ES(Error);
   StringRef Match = MatchTrie.findEquivalent(NativeFilePath.str(), ES);
@@ -235,12 +234,12 @@
     return false;
   }
   llvm::yaml::Node *Root = I->getRoot();
-  if (Root == NULL) {
+  if (!Root) {
     ErrorMessage = "Error while parsing YAML.";
     return false;
   }
   llvm::yaml::SequenceNode *Array = dyn_cast<llvm::yaml::SequenceNode>(Root);
-  if (Array == NULL) {
+  if (!Array) {
     ErrorMessage = "Expected array.";
     return false;
   }
@@ -248,30 +247,30 @@
                                           AE = Array->end();
        AI != AE; ++AI) {
     llvm::yaml::MappingNode *Object = dyn_cast<llvm::yaml::MappingNode>(&*AI);
-    if (Object == NULL) {
+    if (!Object) {
       ErrorMessage = "Expected object.";
       return false;
     }
-    llvm::yaml::ScalarNode *Directory = NULL;
-    llvm::yaml::ScalarNode *Command = NULL;
-    llvm::yaml::ScalarNode *File = NULL;
+    llvm::yaml::ScalarNode *Directory = nullptr;
+    llvm::yaml::ScalarNode *Command = nullptr;
+    llvm::yaml::ScalarNode *File = nullptr;
     for (llvm::yaml::MappingNode::iterator KVI = Object->begin(),
                                            KVE = Object->end();
          KVI != KVE; ++KVI) {
       llvm::yaml::Node *Value = (*KVI).getValue();
-      if (Value == NULL) {
+      if (!Value) {
         ErrorMessage = "Expected value.";
         return false;
       }
       llvm::yaml::ScalarNode *ValueString =
           dyn_cast<llvm::yaml::ScalarNode>(Value);
-      if (ValueString == NULL) {
+      if (!ValueString) {
         ErrorMessage = "Expected string as value.";
         return false;
       }
       llvm::yaml::ScalarNode *KeyString =
           dyn_cast<llvm::yaml::ScalarNode>((*KVI).getKey());
-      if (KeyString == NULL) {
+      if (!KeyString) {
         ErrorMessage = "Expected strings as key.";
         return false;
       }
diff --git a/lib/Tooling/Refactoring.cpp b/lib/Tooling/Refactoring.cpp
index e165c12..c96b8c9 100644
--- a/lib/Tooling/Refactoring.cpp
+++ b/lib/Tooling/Refactoring.cpp
@@ -18,9 +18,9 @@
 #include "clang/Lex/Lexer.h"
 #include "clang/Rewrite/Core/Rewriter.h"
 #include "clang/Tooling/Refactoring.h"
-#include "llvm/Support/raw_os_ostream.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/raw_os_ostream.h"
 
 namespace clang {
 namespace tooling {
@@ -35,12 +35,13 @@
     : FilePath(FilePath), ReplacementRange(Offset, Length),
       ReplacementText(ReplacementText) {}
 
-Replacement::Replacement(SourceManager &Sources, SourceLocation Start,
+Replacement::Replacement(const SourceManager &Sources, SourceLocation Start,
                          unsigned Length, StringRef ReplacementText) {
   setFromSourceLocation(Sources, Start, Length, ReplacementText);
 }
 
-Replacement::Replacement(SourceManager &Sources, const CharSourceRange &Range,
+Replacement::Replacement(const SourceManager &Sources,
+                         const CharSourceRange &Range,
                          StringRef ReplacementText) {
   setFromSourceRange(Sources, Range, ReplacementText);
 }
@@ -52,7 +53,7 @@
 bool Replacement::apply(Rewriter &Rewrite) const {
   SourceManager &SM = Rewrite.getSourceMgr();
   const FileEntry *Entry = SM.getFileManager().getFile(FilePath);
-  if (Entry == NULL)
+  if (!Entry)
     return false;
   FileID ID;
   // FIXME: Use SM.translateFile directly.
@@ -99,17 +100,17 @@
          LHS.getReplacementText() == RHS.getReplacementText();
 }
 
-void Replacement::setFromSourceLocation(SourceManager &Sources,
+void Replacement::setFromSourceLocation(const SourceManager &Sources,
                                         SourceLocation Start, unsigned Length,
                                         StringRef ReplacementText) {
   const std::pair<FileID, unsigned> DecomposedLocation =
       Sources.getDecomposedLoc(Start);
   const FileEntry *Entry = Sources.getFileEntryForID(DecomposedLocation.first);
-  if (Entry != NULL) {
+  if (Entry) {
     // Make FilePath absolute so replacements can be applied correctly when
     // relative paths for files are used.
     llvm::SmallString<256> FilePath(Entry->getName());
-    llvm::error_code EC = llvm::sys::fs::make_absolute(FilePath);
+    std::error_code EC = llvm::sys::fs::make_absolute(FilePath);
     this->FilePath = EC ? FilePath.c_str() : Entry->getName();
   } else {
     this->FilePath = InvalidLocation;
@@ -121,7 +122,8 @@
 // FIXME: This should go into the Lexer, but we need to figure out how
 // to handle ranges for refactoring in general first - there is no obvious
 // good way how to integrate this into the Lexer yet.
-static int getRangeSize(SourceManager &Sources, const CharSourceRange &Range) {
+static int getRangeSize(const SourceManager &Sources,
+                        const CharSourceRange &Range) {
   SourceLocation SpellingBegin = Sources.getSpellingLoc(Range.getBegin());
   SourceLocation SpellingEnd = Sources.getSpellingLoc(Range.getEnd());
   std::pair<FileID, unsigned> Start = Sources.getDecomposedLoc(SpellingBegin);
@@ -133,7 +135,7 @@
   return End.second - Start.second;
 }
 
-void Replacement::setFromSourceRange(SourceManager &Sources,
+void Replacement::setFromSourceRange(const SourceManager &Sources,
                                      const CharSourceRange &Range,
                                      StringRef ReplacementText) {
   setFromSourceLocation(Sources, Sources.getSpellingLoc(Range.getBegin()),
diff --git a/lib/Tooling/Tooling.cpp b/lib/Tooling/Tooling.cpp
index a58854d..0db38db 100644
--- a/lib/Tooling/Tooling.cpp
+++ b/lib/Tooling/Tooling.cpp
@@ -24,6 +24,7 @@
 #include "clang/Tooling/ArgumentsAdjusters.h"
 #include "clang/Tooling/CompilationDatabase.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/Config/llvm-config.h"
 #include "llvm/Option/Option.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/FileSystem.h"
@@ -31,12 +32,14 @@
 #include "llvm/Support/raw_ostream.h"
 
 // For chdir, see the comment in ClangTool::run for more information.
-#ifdef _WIN32
+#ifdef LLVM_ON_WIN32
 #  include <direct.h>
 #else
 #  include <unistd.h>
 #endif
 
+#define DEBUG_TYPE "clang-tooling"
+
 namespace clang {
 namespace tooling {
 
@@ -51,10 +54,8 @@
 /// \brief Builds a clang driver initialized for running clang tools.
 static clang::driver::Driver *newDriver(clang::DiagnosticsEngine *Diagnostics,
                                         const char *BinaryName) {
-  const std::string DefaultOutputName = "a.out";
   clang::driver::Driver *CompilerDriver = new clang::driver::Driver(
-    BinaryName, llvm::sys::getDefaultTargetTriple(),
-    DefaultOutputName, *Diagnostics);
+      BinaryName, llvm::sys::getDefaultTargetTriple(), *Diagnostics);
   CompilerDriver->setTitle("clang_based_tool");
   return CompilerDriver;
 }
@@ -74,7 +75,7 @@
     Jobs.Print(error_stream, "; ", true);
     Diagnostics->Report(clang::diag::err_fe_expected_compiler_job)
         << error_stream.str();
-    return NULL;
+    return nullptr;
   }
 
   // The one job we find should be to invoke clang again.
@@ -82,7 +83,7 @@
       cast<clang::driver::Command>(*Jobs.begin());
   if (StringRef(Cmd->getCreator().getName()) != "clang") {
     Diagnostics->Report(clang::diag::err_fe_expected_clang_command);
-    return NULL;
+    return nullptr;
   }
 
   return &Cmd->getArguments();
@@ -99,6 +100,7 @@
       *Diagnostics);
   Invocation->getFrontendOpts().DisableFree = false;
   Invocation->getCodeGenOpts().DisableFree = false;
+  Invocation->getDependencyOutputOpts() = DependencyOutputOptions();
   return Invocation;
 }
 
@@ -127,7 +129,7 @@
   llvm::IntrusiveRefCntPtr<FileManager> Files(
       new FileManager(FileSystemOptions()));
   ToolInvocation Invocation(getSyntaxOnlyToolArgs(Args, FileNameRef), ToolAction,
-                            Files.getPtr());
+                            Files.get());
 
   SmallString<1024> CodeStorage;
   Invocation.mapVirtualFile(FileNameRef,
@@ -143,7 +145,7 @@
   }
 
   SmallString<1024> AbsolutePath = RelativePath;
-  llvm::error_code EC = llvm::sys::fs::make_absolute(AbsolutePath);
+  std::error_code EC = llvm::sys::fs::make_absolute(AbsolutePath);
   assert(!EC);
   (void)EC;
   llvm::sys::path::native(AbsolutePath);
@@ -158,26 +160,26 @@
 public:
   SingleFrontendActionFactory(FrontendAction *Action) : Action(Action) {}
 
-  FrontendAction *create() { return Action; }
+  FrontendAction *create() override { return Action; }
 };
 
 }
 
-ToolInvocation::ToolInvocation(ArrayRef<std::string> CommandLine,
+ToolInvocation::ToolInvocation(std::vector<std::string> CommandLine,
                                ToolAction *Action, FileManager *Files)
-    : CommandLine(CommandLine.vec()),
+    : CommandLine(std::move(CommandLine)),
       Action(Action),
       OwnsAction(false),
       Files(Files),
-      DiagConsumer(NULL) {}
+      DiagConsumer(nullptr) {}
 
-ToolInvocation::ToolInvocation(ArrayRef<std::string> CommandLine,
+ToolInvocation::ToolInvocation(std::vector<std::string> CommandLine,
                                FrontendAction *FAction, FileManager *Files)
-    : CommandLine(CommandLine.vec()),
+    : CommandLine(std::move(CommandLine)),
       Action(new SingleFrontendActionFactory(FAction)),
       OwnsAction(true),
       Files(Files),
-      DiagConsumer(NULL) {}
+      DiagConsumer(nullptr) {}
 
 ToolInvocation::~ToolInvocation() {
   if (OwnsAction)
@@ -196,8 +198,8 @@
 
 bool ToolInvocation::run() {
   std::vector<const char*> Argv;
-  for (int I = 0, E = CommandLine.size(); I != E; ++I)
-    Argv.push_back(CommandLine[I].c_str());
+  for (const std::string &Str : CommandLine)
+    Argv.push_back(Str.c_str());
   const char *const BinaryName = Argv[0];
   IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
   TextDiagnosticPrinter DiagnosticPrinter(
@@ -206,28 +208,25 @@
       IntrusiveRefCntPtr<clang::DiagnosticIDs>(new DiagnosticIDs()), &*DiagOpts,
       DiagConsumer ? DiagConsumer : &DiagnosticPrinter, false);
 
-  const OwningPtr<clang::driver::Driver> Driver(
+  const std::unique_ptr<clang::driver::Driver> Driver(
       newDriver(&Diagnostics, BinaryName));
   // Since the input might only be virtual, don't check whether it exists.
   Driver->setCheckInputsExist(false);
-  const OwningPtr<clang::driver::Compilation> Compilation(
+  const std::unique_ptr<clang::driver::Compilation> Compilation(
       Driver->BuildCompilation(llvm::makeArrayRef(Argv)));
   const llvm::opt::ArgStringList *const CC1Args = getCC1Arguments(
       &Diagnostics, Compilation.get());
-  if (CC1Args == NULL) {
+  if (!CC1Args) {
     return false;
   }
-  OwningPtr<clang::CompilerInvocation> Invocation(
+  std::unique_ptr<clang::CompilerInvocation> Invocation(
       newInvocation(&Diagnostics, *CC1Args));
-  for (llvm::StringMap<StringRef>::const_iterator
-           It = MappedFileContents.begin(), End = MappedFileContents.end();
-       It != End; ++It) {
+  for (const auto &It : MappedFileContents) {
     // Inject the code as the given file name into the preprocessor options.
-    const llvm::MemoryBuffer *Input =
-        llvm::MemoryBuffer::getMemBuffer(It->getValue());
-    Invocation->getPreprocessorOpts().addRemappedFile(It->getKey(), Input);
+    auto *Input = llvm::MemoryBuffer::getMemBuffer(It.getValue());
+    Invocation->getPreprocessorOpts().addRemappedFile(It.getKey(), Input);
   }
-  return runInvocation(BinaryName, Compilation.get(), Invocation.take());
+  return runInvocation(BinaryName, Compilation.get(), Invocation.release());
 }
 
 bool ToolInvocation::runInvocation(
@@ -254,10 +253,10 @@
 
   // The FrontendAction can have lifetime requirements for Compiler or its
   // members, and we need to ensure it's deleted earlier than Compiler. So we
-  // pass it to an OwningPtr declared after the Compiler variable.
-  OwningPtr<FrontendAction> ScopedToolAction(create());
+  // pass it to an std::unique_ptr declared after the Compiler variable.
+  std::unique_ptr<FrontendAction> ScopedToolAction(create());
 
-  // Create the compilers actual diagnostics engine.
+  // Create the compiler's actual diagnostics engine.
   Compiler.createDiagnostics(DiagConsumer, /*ShouldOwnClient=*/false);
   if (!Compiler.hasDiagnostics())
     return false;
@@ -272,18 +271,18 @@
 
 ClangTool::ClangTool(const CompilationDatabase &Compilations,
                      ArrayRef<std::string> SourcePaths)
-    : Files(new FileManager(FileSystemOptions())), DiagConsumer(NULL) {
+    : Files(new FileManager(FileSystemOptions())), DiagConsumer(nullptr) {
   ArgsAdjusters.push_back(new ClangStripOutputAdjuster());
   ArgsAdjusters.push_back(new ClangSyntaxOnlyAdjuster());
-  for (unsigned I = 0, E = SourcePaths.size(); I != E; ++I) {
-    SmallString<1024> File(getAbsolutePath(SourcePaths[I]));
+  for (const auto &SourcePath : SourcePaths) {
+    std::string File(getAbsolutePath(SourcePath));
 
     std::vector<CompileCommand> CompileCommandsForFile =
-      Compilations.getCompileCommands(File.str());
+      Compilations.getCompileCommands(File);
     if (!CompileCommandsForFile.empty()) {
-      for (int I = 0, E = CompileCommandsForFile.size(); I != E; ++I) {
-        CompileCommands.push_back(std::make_pair(File.str(),
-                                  CompileCommandsForFile[I]));
+      for (CompileCommand &CompileCommand : CompileCommandsForFile) {
+        CompileCommands.push_back(
+            std::make_pair(File, std::move(CompileCommand)));
       }
     } else {
       // FIXME: There are two use cases here: doing a fuzzy
@@ -291,7 +290,7 @@
       // about the .cc files that were not found, and the use case where I
       // specify all files I want to run over explicitly, where this should
       // be an error. We'll want to add an option for this.
-      llvm::outs() << "Skipping " << File << ". Command line not found.\n";
+      llvm::errs() << "Skipping " << File << ". Compile command not found.\n";
     }
   }
 }
@@ -332,8 +331,7 @@
       llvm::sys::fs::getMainExecutable("clang_tool", &StaticSymbol);
 
   bool ProcessingFailed = false;
-  for (unsigned I = 0; I < CompileCommands.size(); ++I) {
-    std::string File = CompileCommands[I].first;
+  for (const auto &Command : CompileCommands) {
     // FIXME: chdir is thread hostile; on the other hand, creating the same
     // behavior as chdir is complex: chdir resolves the path once, thus
     // guaranteeing that all subsequent relative path operations work
@@ -341,28 +339,27 @@
     // 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.
-    if (chdir(CompileCommands[I].second.Directory.c_str()))
+    if (chdir(Command.second.Directory.c_str()))
       llvm::report_fatal_error("Cannot chdir into \"" +
-                               CompileCommands[I].second.Directory + "\n!");
-    std::vector<std::string> CommandLine = CompileCommands[I].second.CommandLine;
-    for (unsigned I = 0, E = ArgsAdjusters.size(); I != E; ++I)
-      CommandLine = ArgsAdjusters[I]->Adjust(CommandLine);
+                               Twine(Command.second.Directory) + "\n!");
+    std::vector<std::string> CommandLine = Command.second.CommandLine;
+    for (ArgumentsAdjuster *Adjuster : ArgsAdjusters)
+      CommandLine = Adjuster->Adjust(CommandLine);
     assert(!CommandLine.empty());
     CommandLine[0] = MainExecutable;
     // FIXME: We need a callback mechanism for the tool writer to output a
     // customized message for each file.
     DEBUG({
-      llvm::dbgs() << "Processing: " << File << ".\n";
+      llvm::dbgs() << "Processing: " << Command.first << ".\n";
     });
-    ToolInvocation Invocation(CommandLine, Action, Files.getPtr());
+    ToolInvocation Invocation(std::move(CommandLine), Action, Files.get());
     Invocation.setDiagnosticConsumer(DiagConsumer);
-    for (int I = 0, E = MappedFileContents.size(); I != E; ++I) {
-      Invocation.mapVirtualFile(MappedFileContents[I].first,
-                                MappedFileContents[I].second);
+    for (const auto &MappedFile : MappedFileContents) {
+      Invocation.mapVirtualFile(MappedFile.first, MappedFile.second);
     }
     if (!Invocation.run()) {
       // FIXME: Diagnostics should be used instead.
-      llvm::errs() << "Error while processing " << File << ".\n";
+      llvm::errs() << "Error while processing " << Command.first << ".\n";
       ProcessingFailed = true;
     }
   }
@@ -372,55 +369,58 @@
 namespace {
 
 class ASTBuilderAction : public ToolAction {
-  std::vector<ASTUnit *> &ASTs;
+  std::vector<std::unique_ptr<ASTUnit>> &ASTs;
 
 public:
-  ASTBuilderAction(std::vector<ASTUnit *> &ASTs) : ASTs(ASTs) {}
+  ASTBuilderAction(std::vector<std::unique_ptr<ASTUnit>> &ASTs) : ASTs(ASTs) {}
 
   bool runInvocation(CompilerInvocation *Invocation, FileManager *Files,
-                     DiagnosticConsumer *DiagConsumer) {
+                     DiagnosticConsumer *DiagConsumer) override {
     // FIXME: This should use the provided FileManager.
-    ASTUnit *AST = ASTUnit::LoadFromCompilerInvocation(
+    std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromCompilerInvocation(
         Invocation, CompilerInstance::createDiagnostics(
                         &Invocation->getDiagnosticOpts(), DiagConsumer,
                         /*ShouldOwnClient=*/false));
     if (!AST)
       return false;
 
-    ASTs.push_back(AST);
+    ASTs.push_back(std::move(AST));
     return true;
   }
 };
 
 }
 
-int ClangTool::buildASTs(std::vector<ASTUnit *> &ASTs) {
+int ClangTool::buildASTs(std::vector<std::unique_ptr<ASTUnit>> &ASTs) {
   ASTBuilderAction Action(ASTs);
   return run(&Action);
 }
 
-ASTUnit *buildASTFromCode(const Twine &Code, const Twine &FileName) {
+std::unique_ptr<ASTUnit> buildASTFromCode(const Twine &Code,
+                                          const Twine &FileName) {
   return buildASTFromCodeWithArgs(Code, std::vector<std::string>(), FileName);
 }
 
-ASTUnit *buildASTFromCodeWithArgs(const Twine &Code,
-                                  const std::vector<std::string> &Args,
-                                  const Twine &FileName) {
+std::unique_ptr<ASTUnit>
+buildASTFromCodeWithArgs(const Twine &Code,
+                         const std::vector<std::string> &Args,
+                         const Twine &FileName) {
   SmallString<16> FileNameStorage;
   StringRef FileNameRef = FileName.toNullTerminatedStringRef(FileNameStorage);
 
-  std::vector<ASTUnit *> ASTs;
+  std::vector<std::unique_ptr<ASTUnit>> ASTs;
   ASTBuilderAction Action(ASTs);
-  ToolInvocation Invocation(getSyntaxOnlyToolArgs(Args, FileNameRef), &Action, 0);
+  ToolInvocation Invocation(getSyntaxOnlyToolArgs(Args, FileNameRef), &Action,
+                            nullptr);
 
   SmallString<1024> CodeStorage;
   Invocation.mapVirtualFile(FileNameRef,
                             Code.toNullTerminatedStringRef(CodeStorage));
   if (!Invocation.run())
-    return 0;
+    return nullptr;
 
   assert(ASTs.size() == 1);
-  return ASTs[0];
+  return std::move(ASTs[0]);
 }
 
 } // end namespace tooling
diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt
index 68ee266..dc14541 100644
--- a/runtime/CMakeLists.txt
+++ b/runtime/CMakeLists.txt
@@ -1,7 +1,8 @@
 # TODO: Set the install directory.
 
+include(ExternalProject)
+
 set(known_subdirs
-  "compiler-rt"
   "libcxx"
   )
 
@@ -10,3 +11,98 @@
     add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${dir})
   endif()
 endforeach()
+
+function(get_ext_project_build_command out_var target)
+  if (CMAKE_GENERATOR MATCHES "Make")
+    # Use special command for Makefiles to support parallelism.
+    set(${out_var} "$(MAKE)" "${target}" PARENT_SCOPE)
+  else()
+    set(${out_var} ${CMAKE_COMMAND} --build . --target ${target}
+                                    --config $<CONFIGURATION> PARENT_SCOPE)
+  endif()
+endfunction()
+
+set(COMPILER_RT_SRC_ROOT ${LLVM_MAIN_SRC_DIR}/projects/compiler-rt)
+if(LLVM_BUILD_EXTERNAL_COMPILER_RT AND EXISTS ${COMPILER_RT_SRC_ROOT}/)
+  if(CMAKE_GENERATOR MATCHES "Ninja")
+    message(FATAL_ERROR
+            "Ninja generator can't build compiler-rt as ExternalProject."
+            "Unset LLVM_BUILD_EXTERNAL_COMPILER_RT, or don't use Ninja."
+            "See http://www.cmake.org/Bug/view.php?id=14771")
+  endif()
+
+  # Add compiler-rt as an external project.
+  set(COMPILER_RT_PREFIX ${CMAKE_BINARY_DIR}/projects/compiler-rt)
+  
+  ExternalProject_Add(compiler-rt
+    PREFIX ${COMPILER_RT_PREFIX}
+    SOURCE_DIR ${COMPILER_RT_SRC_ROOT}
+    CMAKE_ARGS -DCMAKE_C_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang
+               -DCMAKE_CXX_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang++
+               -DCMAKE_BUILD_TYPE=Release
+               -DLLVM_CONFIG_PATH=${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-config
+               -DCOMPILER_RT_OUTPUT_DIR=${LLVM_LIBRARY_OUTPUT_INTDIR}/clang/${CLANG_VERSION}
+               -DCOMPILER_RT_EXEC_OUTPUT_DIR=${LLVM_RUNTIME_OUTPUT_INTDIR}
+               -DCOMPILER_RT_INSTALL_PATH=lib${LLVM_LIBDIR_SUFFIX}/clang/${CLANG_VERSION}
+               -DCOMPILER_RT_INCLUDE_TESTS=${LLVM_INCLUDE_TESTS}
+               -DCOMPILER_RT_ENABLE_WERROR=ON
+    INSTALL_COMMAND ""
+    STEP_TARGETS configure build
+    )
+  # Due to a bug, DEPENDS in ExternalProject_Add doesn't work
+  # in CMake 2.8.9 and 2.8.10.
+  add_dependencies(compiler-rt llvm-config clang)
+
+  # Add a custom step to always re-configure compiler-rt (in case some of its
+  # sources have changed).
+  ExternalProject_Add_Step(compiler-rt force-reconfigure
+    DEPENDERS configure
+    ALWAYS 1
+    )
+
+  ExternalProject_Add_Step(compiler-rt clobber
+    COMMAND ${CMAKE_COMMAND} -E remove_directory <BINARY_DIR>
+    COMMAND ${CMAKE_COMMAND} -E make_directory <BINARY_DIR>
+    COMMENT "Clobberring compiler-rt build directory..."
+    DEPENDERS configure
+    DEPENDS ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang
+  )
+
+  ExternalProject_Get_Property(compiler-rt BINARY_DIR)
+  set(COMPILER_RT_BINARY_DIR ${BINARY_DIR})
+
+  # Add top-level targets that build specific compiler-rt runtimes.
+  set(COMPILER_RT_RUNTIMES asan builtins dfsan lsan msan profile tsan ubsan)
+  foreach(runtime ${COMPILER_RT_RUNTIMES})
+    get_ext_project_build_command(build_runtime_cmd ${runtime})
+    add_custom_target(${runtime}
+      COMMAND ${build_runtime_cmd}
+      DEPENDS compiler-rt-configure
+      WORKING_DIRECTORY ${COMPILER_RT_BINARY_DIR}
+      VERBATIM)
+  endforeach()
+
+  # Add binaries that compiler-rt tests depend on.
+  set(COMPILER_RT_TEST_DEPENDENCIES
+    FileCheck count not llvm-nm llvm-symbolizer)
+
+  # Add top-level targets for various compiler-rt test suites.
+  set(COMPILER_RT_TEST_SUITES check-asan check-dfsan check-lsan check-msan
+    check-sanitizer check-tsan check-ubsan)
+  foreach(test_suite ${COMPILER_RT_TEST_SUITES})
+    get_ext_project_build_command(run_test_suite ${test_suite})
+    add_custom_target(${test_suite}
+      COMMAND ${run_test_suite}
+      DEPENDS compiler-rt-build ${COMPILER_RT_TEST_DEPENDENCIES}
+      WORKING_DIRECTORY ${COMPILER_RT_BINARY_DIR}
+      VERBATIM)
+  endforeach()
+
+  # Add special target to run all compiler-rt test suites.
+  get_ext_project_build_command(run_check_compiler_rt check-all)
+  add_custom_target(check-compiler-rt
+    COMMAND ${run_check_compiler_rt}
+    DEPENDS compiler-rt-build ${COMPILER_RT_TEST_DEPENDENCIES}
+    WORKING_DIRECTORY ${COMPILER_RT_BINARY_DIR}
+    VERBATIM)
+endif()
diff --git a/runtime/compiler-rt/Makefile b/runtime/compiler-rt/Makefile
index c6f38b2..ccd83a3 100644
--- a/runtime/compiler-rt/Makefile
+++ b/runtime/compiler-rt/Makefile
@@ -66,7 +66,7 @@
 #  3. Come up with an alternate mechanism to define all the toolchain
 #     information that compiler-rt would need to build libraries for all the
 #     requested targets. This might be a simple short term solution, but is
-#     likely to be unwieldly and irritating to maintain in the long term.
+#     likely to be unwieldy and irritating to maintain in the long term.
 ifneq ($(LLVM_CROSS_COMPILING),1)
 ifneq ($(CLANG_NO_RUNTIME),1)
 ifeq ($(shell test -d $(COMPILERRT_SRC_ROOT) && echo OK),OK)
@@ -78,14 +78,19 @@
 # support.
 RuntimeDirs :=
 ifeq ($(OS),Darwin)
-RuntimeDirs += darwin darwin_embedded
+RuntimeDirs += darwin macho_embedded
 RuntimeLibrary.darwin.Configs := \
 	eprintf.a 10.4.a osx.a ios.a cc_kext.a cc_kext_ios5.a \
 	asan_osx_dynamic.dylib \
 	profile_osx.a profile_ios.a \
 	ubsan_osx.a
-RuntimeLibrary.darwin_embedded.Configs := \
-	soft_static.a hard_static.a soft_pic.a hard_pic.a
+
+RuntimeLibrary.macho_embedded.Configs := \
+	hard_static.a hard_pic.a
+ifneq (,$(findstring ARM,$(TARGETS_TO_BUILD)))
+RuntimeLibrary.macho_embedded.Configs += \
+	soft_static.a soft_pic.a
+endif
 
 # Support building compiler-rt with relocatable SDKs.
 #
@@ -121,8 +126,8 @@
 
 # We try to build 32-bit runtimes both on 32-bit hosts and 64-bit hosts.
 Runtime32BitConfigs = \
-	full-i386.a profile-i386.a san-i386.a asan-i386.a ubsan-i386.a \
-	ubsan_cxx-i386.a
+	builtins-i386.a profile-i386.a san-i386.a asan-i386.a asan_cxx-i386.a \
+	ubsan-i386.a ubsan_cxx-i386.a
 
 # We currently only try to generate runtime libraries on x86.
 ifeq ($(ARCH),x86)
@@ -131,9 +136,9 @@
 
 ifeq ($(ARCH),x86_64)
 RuntimeLibrary.linux.Configs += \
-	full-x86_64.a profile-x86_64.a san-x86_64.a asan-x86_64.a \
-	tsan-x86_64.a msan-x86_64.a ubsan-x86_64.a ubsan_cxx-x86_64.a \
-	dfsan-x86_64.a lsan-x86_64.a
+	builtins-x86_64.a profile-x86_64.a san-x86_64.a asan-x86_64.a \
+	asan_cxx-x86_64.a tsan-x86_64.a msan-x86_64.a ubsan-x86_64.a \
+	ubsan_cxx-x86_64.a dfsan-x86_64.a lsan-x86_64.a
 # We need to build 32-bit ASan/UBsan libraries on 64-bit platform, and add them
 # to the list of runtime libraries to make
 # "clang -fsanitize=(address|undefined) -m32" work.
@@ -164,6 +169,7 @@
 	  ProjSrcRoot=$(COMPILERRT_SRC_ROOT) \
 	  ProjObjRoot=$(PROJ_OBJ_DIR) \
 	  CC="$(ToolDir)/clang" \
+	  VERBOSE=$(VERBOSE) \
 	  LLVM_ANDROID_TOOLCHAIN_DIR="$(LLVM_ANDROID_TOOLCHAIN_DIR)" \
 	  $(COMPILERRT_MAKE_FLAGS) \
 	  $(RuntimeDirs:%=clang_%)
@@ -172,6 +178,7 @@
 	$(Verb) $(MAKE) -C $(COMPILERRT_SRC_ROOT) \
 	  ProjSrcRoot=$(COMPILERRT_SRC_ROOT) \
 	  ProjObjRoot=$(PROJ_OBJ_DIR) \
+	  VERBOSE=$(VERBOSE) \
 	  $(COMPILERRT_MAKE_FLAGS) \
 	  clean
 .PHONY: CleanRuntimeLibraries
diff --git a/test/ARCMT/GC-check-warn-nsalloc.m b/test/ARCMT/GC-check-warn-nsalloc.m
index 5ce36c4..44ccc95 100644
--- a/test/ARCMT/GC-check-warn-nsalloc.m
+++ b/test/ARCMT/GC-check-warn-nsalloc.m
@@ -1,12 +1,11 @@
-// RUN: %clang_cc1 -arcmt-check -verify -no-ns-alloc-error -triple x86_64-apple-darwin10 -fobjc-gc-only %s
-// RUN: %clang_cc1 -arcmt-check -verify -no-ns-alloc-error -triple x86_64-apple-darwin10 -fobjc-gc-only -x objective-c++ %s
-// DISABLE: mingw32
+// RUN: %clang_cc1 -arcmt-check -no-ns-alloc-error -triple x86_64-apple-darwin10 -fobjc-gc-only %s 2>&1 | grep 'warning: \[rewriter\] call returns pointer to GC managed memory'
+// RUN: %clang_cc1 -arcmt-check -no-ns-alloc-error -triple x86_64-apple-darwin10 -fobjc-gc-only -x objective-c++ %s 2>&1 | grep 'warning: \[rewriter\] call returns pointer to GC managed memory'
+// TODO: Investigate VerifyDiagnosticConsumer failures on these tests when using -verify.
 // rdar://10532541
-// XFAIL: *
 
 typedef unsigned NSUInteger;
 void *__strong NSAllocateCollectable(NSUInteger size, NSUInteger options);
 
 void test1() {
-  NSAllocateCollectable(100, 0); // expected-warning {{call returns pointer to GC managed memory; it will become unmanaged in ARC}}
+  NSAllocateCollectable(100, 0);
 }
diff --git a/test/ARCMT/GC-check.m b/test/ARCMT/GC-check.m
index 3a1b67c..9864354 100644
--- a/test/ARCMT/GC-check.m
+++ b/test/ARCMT/GC-check.m
@@ -1,6 +1,5 @@
 // RUN: %clang_cc1 -arcmt-check -verify -triple x86_64-apple-darwin10 -fobjc-gc-only %s
 // RUN: %clang_cc1 -arcmt-check -verify -triple x86_64-apple-darwin10 -fobjc-gc-only -x objective-c++ %s
-// DISABLE: mingw32
 
 #define CF_AUTOMATED_REFCOUNT_UNAVAILABLE __attribute__((unavailable("not available in automatic reference counting mode")))
 typedef unsigned NSUInteger;
diff --git a/test/ARCMT/GC-no-arc-runtime.m b/test/ARCMT/GC-no-arc-runtime.m
index f069992..376134e 100644
--- a/test/ARCMT/GC-no-arc-runtime.m
+++ b/test/ARCMT/GC-no-arc-runtime.m
@@ -3,7 +3,6 @@
 // RUN: diff %t %s.result
 // RUN: arcmt-test --args -triple x86_64-apple-macosx10.6 -fsyntax-only -fobjc-gc-only -x objective-c++ %s > %t
 // RUN: diff %t %s.result
-// DISABLE: mingw32
 
 #include "Common.h"
 #include "GC.h"
diff --git a/test/ARCMT/GC-no-arc-runtime.m.result b/test/ARCMT/GC-no-arc-runtime.m.result
index f55ca38..c338bdb 100644
--- a/test/ARCMT/GC-no-arc-runtime.m.result
+++ b/test/ARCMT/GC-no-arc-runtime.m.result
@@ -3,7 +3,6 @@
 // RUN: diff %t %s.result
 // RUN: arcmt-test --args -triple x86_64-apple-macosx10.6 -fsyntax-only -fobjc-gc-only -x objective-c++ %s > %t
 // RUN: diff %t %s.result
-// DISABLE: mingw32
 
 #include "Common.h"
 #include "GC.h"
diff --git a/test/ARCMT/GC-no-finalize-removal.m b/test/ARCMT/GC-no-finalize-removal.m
index 14e8602..a8db819 100644
--- a/test/ARCMT/GC-no-finalize-removal.m
+++ b/test/ARCMT/GC-no-finalize-removal.m
@@ -3,7 +3,6 @@
 // RUN: diff %t %s.result
 // RUN: arcmt-test --args -triple x86_64-apple-macosx10.7 -fsyntax-only -fobjc-gc-only -no-finalize-removal -x objective-c++ %s > %t
 // RUN: diff %t %s.result
-// DISABLE: mingw32
 
 #include "Common.h"
 #include "GC.h"
diff --git a/test/ARCMT/GC-no-finalize-removal.m.result b/test/ARCMT/GC-no-finalize-removal.m.result
index ea14873..b563d19 100644
--- a/test/ARCMT/GC-no-finalize-removal.m.result
+++ b/test/ARCMT/GC-no-finalize-removal.m.result
@@ -3,7 +3,6 @@
 // RUN: diff %t %s.result
 // RUN: arcmt-test --args -triple x86_64-apple-macosx10.7 -fsyntax-only -fobjc-gc-only -no-finalize-removal -x objective-c++ %s > %t
 // RUN: diff %t %s.result
-// DISABLE: mingw32
 
 #include "Common.h"
 #include "GC.h"
diff --git a/test/ARCMT/GC.m b/test/ARCMT/GC.m
index eebbaf6..2c9ea9c 100644
--- a/test/ARCMT/GC.m
+++ b/test/ARCMT/GC.m
@@ -3,7 +3,6 @@
 // RUN: diff %t %s.result
 // RUN: arcmt-test --args -triple x86_64-apple-macosx10.7 -fsyntax-only -fobjc-gc-only -x objective-c++ %s > %t
 // RUN: diff %t %s.result
-// DISABLE: mingw32
 
 #include "Common.h"
 #include "GC.h"
diff --git a/test/ARCMT/GC.m.result b/test/ARCMT/GC.m.result
index c2c523f..595ff23 100644
--- a/test/ARCMT/GC.m.result
+++ b/test/ARCMT/GC.m.result
@@ -3,7 +3,6 @@
 // RUN: diff %t %s.result
 // RUN: arcmt-test --args -triple x86_64-apple-macosx10.7 -fsyntax-only -fobjc-gc-only -x objective-c++ %s > %t
 // RUN: diff %t %s.result
-// DISABLE: mingw32
 
 #include "Common.h"
 #include "GC.h"
diff --git a/test/ARCMT/Inputs/Module.framework/Frameworks/SubFramework.framework/Headers/SubFramework.h b/test/ARCMT/Inputs/Module.framework/Frameworks/SubFramework.framework/Headers/SubFramework.h
new file mode 100644
index 0000000..f7f9fb6
--- /dev/null
+++ b/test/ARCMT/Inputs/Module.framework/Frameworks/SubFramework.framework/Headers/SubFramework.h
@@ -0,0 +1,5 @@
+#ifndef MODULE_SUBFRAMEWORK_H
+#define MODULE_SUBFRAMEWORK_H
+#__private_macro MODULE_SUBFRAMEWORK_H
+char *module_subframework;
+#endif
diff --git a/test/ARCMT/Inputs/Module.framework/Headers/Buried/Treasure.h b/test/ARCMT/Inputs/Module.framework/Headers/Buried/Treasure.h
new file mode 100644
index 0000000..6e81adc
--- /dev/null
+++ b/test/ARCMT/Inputs/Module.framework/Headers/Buried/Treasure.h
@@ -0,0 +1 @@
+unsigned *Buried_Treasure;
diff --git a/test/ARCMT/Inputs/Module.framework/Headers/Module.h b/test/ARCMT/Inputs/Module.framework/Headers/Module.h
new file mode 100644
index 0000000..3d2476b
--- /dev/null
+++ b/test/ARCMT/Inputs/Module.framework/Headers/Module.h
@@ -0,0 +1,28 @@
+// expected-warning 0-1 {{umbrella header}}
+
+// FIXME: The "umbrella header" warning should be moved to a separate test.
+// This "0-1" is only here because the warning is only emitted when the
+// module is (otherwise) successfully included.
+
+#ifndef MODULE_H
+#define MODULE_H
+const char *getModuleVersion(void);
+
+#ifdef FOO
+#  error Module should have been built without -DFOO
+#endif
+
+@interface Module
++(const char *)version; // retrieve module version
++alloc;
+@end
+
+#define MODULE_H_MACRO 1
+#__private_macro MODULE_H_MACRO
+
+#include <Module/Sub.h>
+#include <Module/Buried/Treasure.h>
+
+__asm("foo");
+
+#endif // MODULE_H
diff --git a/test/ARCMT/Inputs/Module.framework/Headers/NotInModule.h b/test/ARCMT/Inputs/Module.framework/Headers/NotInModule.h
new file mode 100644
index 0000000..6b15791
--- /dev/null
+++ b/test/ARCMT/Inputs/Module.framework/Headers/NotInModule.h
@@ -0,0 +1 @@
+int not_in_module;
diff --git a/test/ARCMT/Inputs/Module.framework/Headers/Sub.h b/test/ARCMT/Inputs/Module.framework/Headers/Sub.h
new file mode 100644
index 0000000..dea76e7
--- /dev/null
+++ b/test/ARCMT/Inputs/Module.framework/Headers/Sub.h
@@ -0,0 +1,3 @@
+#include <Module/Sub2.h>
+int *Module_Sub;
+
diff --git a/test/ARCMT/Inputs/Module.framework/Headers/Sub2.h b/test/ARCMT/Inputs/Module.framework/Headers/Sub2.h
new file mode 100644
index 0000000..beed4a8
--- /dev/null
+++ b/test/ARCMT/Inputs/Module.framework/Headers/Sub2.h
@@ -0,0 +1 @@
+int *Module_Sub2;
diff --git a/include/clang/Driver/CC1Options.h b/test/ARCMT/Inputs/Module.framework/Module
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/ARCMT/Inputs/Module.framework/Module
diff --git a/test/ARCMT/Inputs/Module.framework/PrivateHeaders/ModulePrivate.h b/test/ARCMT/Inputs/Module.framework/PrivateHeaders/ModulePrivate.h
new file mode 100644
index 0000000..0782336
--- /dev/null
+++ b/test/ARCMT/Inputs/Module.framework/PrivateHeaders/ModulePrivate.h
@@ -0,0 +1 @@
+int module_private;
diff --git a/test/ARCMT/Inputs/module.map b/test/ARCMT/Inputs/module.map
new file mode 100644
index 0000000..061abbd
--- /dev/null
+++ b/test/ARCMT/Inputs/module.map
@@ -0,0 +1,309 @@
+module c_library [extern_c] { module inner { header "c-header.h" } }
+module cxx_library { header "cxx-header.h" requires cplusplus }
+module c_library_bad [extern_c] { header "c-header-bad.h" }
+module diamond_top { header "diamond_top.h" }
+module diamond_left { 
+  header "diamond_left.h" 
+  export diamond_top
+}
+module diamond_right { 
+  header "diamond_right.h" 
+  export diamond_top
+}
+module diamond_bottom { 
+  header "diamond_bottom.h" 
+  export *
+}
+module irgen { header "irgen.h" }
+module cxx_irgen_top { header "cxx-irgen-top.h" }
+module cxx_irgen_left { header "cxx-irgen-left.h" }
+module cxx_irgen_right { header "cxx-irgen-right.h" }
+module lookup_left_objc { header "lookup_left.h" }
+module lookup_right_objc { header "lookup_right.h" }
+module lookup_left_cxx { header "lookup_left.hpp" }
+module lookup_right_cxx { header "lookup_right.hpp" }
+module module_private_left { header "module_private_left.h" }
+module module_private_right { header "module_private_right.h" }
+module macros_top { 
+  header "macros_top.h" 
+  explicit module b { header "macros_top_b.h" }
+  explicit module c { header "macros_top_c.h" }
+}
+module macros_left { 
+  header "macros_left.h" 
+  export *
+}
+module macros_right { 
+  header "macros_right.h" 
+  export *
+  explicit module undef {
+    header "macros_right_undef.h"
+  }
+}
+module macros { header "macros.h" }
+module macros_other { header "macros_other.h" }
+module category_top { header "category_top.h" }
+module category_left { 
+  header "category_left.h" 
+  export category_top
+
+  explicit module sub {
+    header "category_left_sub.h"
+  }
+}
+module category_right { 
+  header "category_right.h" 
+  export category_top
+
+  explicit module sub {
+    header "category_right_sub.h"
+  }
+}
+module category_bottom { 
+  header "category_bottom.h" 
+  export category_left
+  export category_right
+}
+module category_other { header "category_other.h" }
+module redeclarations_left { header "redeclarations_left.h" }
+module redeclarations_right { header "redeclarations_right.h" }
+module redecl_namespaces_left { header "redecl_namespaces_left.h" }
+module redecl_namespaces_right { header "redecl_namespaces_right.h" }
+module redecl_add_after_load_top { header "redecl-add-after-load-top.h" }
+module redecl_add_after_load { header "redecl-add-after-load.h" }
+module load_failure { header "load_failure.h" }
+
+module decldef {
+  explicit module Decl { header "decl.h" }
+  explicit module Decl2 { header "decl2.h" }
+  explicit module Def { header "def.h" }
+}
+
+module redecl_merge_top { 
+  header "redecl-merge-top.h"
+  explicit module Explicit { header "redecl-merge-top-explicit.h" }
+  exclude header "nonexistent.h"
+}
+module redecl_merge_left { 
+  header "redecl-merge-left.h" 
+  export *
+}
+module redecl_merge_left_left { 
+  header "redecl-merge-left-left.h" 
+  export *
+}
+module redecl_merge_right { 
+  header "redecl-merge-right.h" 
+  export *
+}
+module redecl_merge_bottom { 
+  explicit module prefix {
+    header "redecl-merge-bottom-prefix.h"
+  }
+
+  header "redecl-merge-bottom.h" 
+  export *
+}
+module namespaces_top { 
+  header "namespaces-top.h"
+  export *
+}
+module namespaces_left { 
+  header "namespaces-left.h"
+  export *
+}
+module namespaces_right { 
+  header "namespaces-right.h"
+  export *
+}
+module templates_top { 
+  header "templates-top.h"
+  export *
+}
+module templates_left { 
+  header "templates-left.h"
+  export *
+}
+module templates_right { 
+  header "templates-right.h"
+  export *
+}
+module MethodPoolA {
+  header "MethodPoolA.h"
+
+  explicit module Sub2 {
+    header "MethodPoolASub2.h"
+  }
+
+  explicit module Sub {
+    header "MethodPoolASub.h"
+  }
+}
+module MethodPoolB {
+  header "MethodPoolB.h"
+
+  explicit module Sub2 {
+    header "MethodPoolBSub2.h"
+  }
+
+  explicit module Sub {
+    header "MethodPoolBSub.h"
+  }
+}
+module import_decl {
+  header "import-decl.h"
+}
+
+framework module * { 
+  exclude NotAModule
+}
+
+module linkage_merge_left {
+  explicit module sub {
+    header "linkage-merge-sub.h"
+  }
+}
+
+module autolink {
+  header "autolink.h"
+  link "autolink"
+
+  explicit module sub {
+    header "autolink-sub.h"
+    link "autolink_sub"
+  }
+
+  explicit module sub2 {
+    header "autolink-sub2.h"
+    link framework "autolink_framework"
+  }
+
+  explicit module sub3 {
+    header "autolink-sub3.h"
+    link "autolink_from_pch"
+  }
+}
+
+module weird_objc {
+  header "weird_objc.h"
+}
+
+module ignored_macros {
+  header "ignored_macros.h"
+}
+
+module cxx_many_overloads {
+  header "cxx-many-overloads.h"
+}
+
+module cxx_inline_namespace {
+  header "cxx-inline-namespace.h"
+}
+
+module cxx_inline_namespace_b {
+  header "cxx-inline-namespace-b.h"
+}
+
+module cxx_linkage_cache {
+  header "cxx-linkage-cache.h"
+}
+
+module cxx_templates_common {
+  header "cxx-templates-common.h"
+}
+
+module cxx_templates_a {
+  header "cxx-templates-a.h"
+}
+
+module cxx_templates_b_impl {
+  header "cxx-templates-b-impl.h"
+}
+
+module cxx_templates_b {
+  header "cxx-templates-b.h"
+}
+
+module cxx_templates_c {
+  header "cxx-templates-c.h"
+}
+
+module cxx_decls {
+  module unimported {
+    header "cxx-decls-unimported.h"
+  }
+  module imported {
+    header "cxx-decls-imported.h"
+  }
+}
+
+module config {
+  header "config.h"
+  config_macros [exhaustive] WANT_FOO, WANT_BAR
+}
+
+module diag_pragma {
+  header "diag_pragma.h"
+}
+
+module dummy {
+  header "dummy.h"
+}
+
+module builtin {
+  header "builtin.h"
+  explicit module sub {
+    header "builtin_sub.h"
+  }
+}
+
+module linkage_merge {
+  explicit module foo {
+    header "linkage-merge-foo.h"
+  }
+  explicit module bar {
+    header "linkage-merge-bar.h"
+  }
+
+}
+
+module incomplete_mod {
+  header "incomplete_mod.h"
+}
+
+module warning {
+  header "warning.h"
+}
+
+module initializer_list {
+  header "initializer_list"
+}
+
+module using_decl {
+  module a { header "using-decl-a.h" export * }
+  module b { header "using-decl-b.h" export * }
+}
+
+module recursive_visibility_a1 {
+  module inner { header "recursive_visibility_a1_inner.h" }
+}
+module recursive_visibility_a2 {
+  module inner {
+    module more_inner {
+      header "recursive_visibility_a2_more_inner.h"
+    }
+  }
+}
+module recursive_visibility_b {
+  header "recursive_visibility_b.h"
+  export *
+}
+module recursive_visibility_c {
+  header "recursive_visibility_c.h"
+}
+module recursive1 {
+  header "recursive1.h"
+}
+module recursive2 {
+  header "recursive2.h"
+}
diff --git a/test/ARCMT/api.m b/test/ARCMT/api.m
index ba122c4..b186ec7 100644
--- a/test/ARCMT/api.m
+++ b/test/ARCMT/api.m
@@ -1,7 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result
 // RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t
 // RUN: diff %t %s.result
-// DISABLE: mingw32
 
 #include "Common.h"
 
diff --git a/test/ARCMT/api.m.result b/test/ARCMT/api.m.result
index 7e04e7d..e309375 100644
--- a/test/ARCMT/api.m.result
+++ b/test/ARCMT/api.m.result
@@ -1,7 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result
 // RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t
 // RUN: diff %t %s.result
-// DISABLE: mingw32
 
 #include "Common.h"
 
diff --git a/test/ARCMT/assign-prop-with-arc-runtime.m b/test/ARCMT/assign-prop-with-arc-runtime.m
index c357eeb..a00538c 100644
--- a/test/ARCMT/assign-prop-with-arc-runtime.m
+++ b/test/ARCMT/assign-prop-with-arc-runtime.m
@@ -1,7 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -x objective-c %s.result
 // RUN: arcmt-test --args -triple x86_64-apple-macosx10.7 -fsyntax-only %s > %t
 // RUN: diff %t %s.result
-// DISABLE: mingw32
 
 #include "Common.h"
 
diff --git a/test/ARCMT/assign-prop-with-arc-runtime.m.result b/test/ARCMT/assign-prop-with-arc-runtime.m.result
index a255a36..8bb684f 100644
--- a/test/ARCMT/assign-prop-with-arc-runtime.m.result
+++ b/test/ARCMT/assign-prop-with-arc-runtime.m.result
@@ -1,7 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak -x objective-c %s.result
 // RUN: arcmt-test --args -triple x86_64-apple-macosx10.7 -fsyntax-only %s > %t
 // RUN: diff %t %s.result
-// DISABLE: mingw32
 
 #include "Common.h"
 
diff --git a/test/ARCMT/atautorelease-2.m b/test/ARCMT/atautorelease-2.m
index 5c2cd6b..b9bc106 100644
--- a/test/ARCMT/atautorelease-2.m
+++ b/test/ARCMT/atautorelease-2.m
@@ -1,7 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result
 // RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t
 // RUN: diff %t %s.result
-// DISABLE: mingw32
 
 @interface NSAutoreleasePool
 - drain;
diff --git a/test/ARCMT/atautorelease-2.m.result b/test/ARCMT/atautorelease-2.m.result
index 06bf0d5..2054733 100644
--- a/test/ARCMT/atautorelease-2.m.result
+++ b/test/ARCMT/atautorelease-2.m.result
@@ -1,7 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result
 // RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t
 // RUN: diff %t %s.result
-// DISABLE: mingw32
 
 @interface NSAutoreleasePool
 - drain;
diff --git a/test/ARCMT/atautorelease-3.m b/test/ARCMT/atautorelease-3.m
index 0b6abdf..87b80af 100644
--- a/test/ARCMT/atautorelease-3.m
+++ b/test/ARCMT/atautorelease-3.m
@@ -1,7 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result
 // RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t
 // RUN: diff %t %s.result
-// DISABLE: mingw32
 
 @interface NSAutoreleasePool
 - drain;
diff --git a/test/ARCMT/atautorelease-3.m.result b/test/ARCMT/atautorelease-3.m.result
index 9103de4..801376a 100644
--- a/test/ARCMT/atautorelease-3.m.result
+++ b/test/ARCMT/atautorelease-3.m.result
@@ -1,7 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result
 // RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t
 // RUN: diff %t %s.result
-// DISABLE: mingw32
 
 @interface NSAutoreleasePool
 - drain;
diff --git a/test/ARCMT/atautorelease-check.m b/test/ARCMT/atautorelease-check.m
index 8daf9d6..d74ef3b 100644
--- a/test/ARCMT/atautorelease-check.m
+++ b/test/ARCMT/atautorelease-check.m
@@ -1,5 +1,4 @@
 // RUN: %clang_cc1 -arcmt-check -verify -triple x86_64-apple-darwin10 %s
-// DISABLE: mingw32
 
 #if __has_feature(objc_arr)
 #define NS_AUTOMATED_REFCOUNT_UNAVAILABLE __attribute__((unavailable("not available in automatic reference counting mode")))
diff --git a/test/ARCMT/atautorelease.m b/test/ARCMT/atautorelease.m
index 132553b..a6aed14 100644
--- a/test/ARCMT/atautorelease.m
+++ b/test/ARCMT/atautorelease.m
@@ -1,7 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result
 // RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t
 // RUN: diff %t %s.result
-// DISABLE: mingw32
 
 #include "Common.h"
 
diff --git a/test/ARCMT/atautorelease.m.result b/test/ARCMT/atautorelease.m.result
index 5191f47..e24339a 100644
--- a/test/ARCMT/atautorelease.m.result
+++ b/test/ARCMT/atautorelease.m.result
@@ -1,7 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result
 // RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t
 // RUN: diff %t %s.result
-// DISABLE: mingw32
 
 #include "Common.h"
 
diff --git a/test/ARCMT/autoreleases.m b/test/ARCMT/autoreleases.m
index 543bcf6..91413e5 100644
--- a/test/ARCMT/autoreleases.m
+++ b/test/ARCMT/autoreleases.m
@@ -1,7 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result
 // RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t
 // RUN: diff %t %s.result
-// DISABLE: mingw32
 
 #include "Common.h"
 
diff --git a/test/ARCMT/autoreleases.m.result b/test/ARCMT/autoreleases.m.result
index 9b71ff8..32c7ad3 100644
--- a/test/ARCMT/autoreleases.m.result
+++ b/test/ARCMT/autoreleases.m.result
@@ -1,7 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result
 // RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t
 // RUN: diff %t %s.result
-// DISABLE: mingw32
 
 #include "Common.h"
 
diff --git a/test/ARCMT/check-with-pch.m b/test/ARCMT/check-with-pch.m
index 7867002..1a94dda 100644
--- a/test/ARCMT/check-with-pch.m
+++ b/test/ARCMT/check-with-pch.m
@@ -1,6 +1,5 @@
 // RUN: %clang_cc1 -x objective-c -triple x86_64-apple-darwin10 %S/Common.h -emit-pch -o %t.pch
 // RUN: %clang_cc1 -include-pch %t.pch -arcmt-check -verify -triple x86_64-apple-darwin10 -fblocks -Werror %s
-// DISABLE: mingw32
 
 // rdar://9601437
 @interface I9601437 {
diff --git a/test/ARCMT/checking-in-arc.m b/test/ARCMT/checking-in-arc.m
index 40d9b16..d41a162 100644
--- a/test/ARCMT/checking-in-arc.m
+++ b/test/ARCMT/checking-in-arc.m
@@ -1,5 +1,4 @@
 // RUN: %clang_cc1 -arcmt-check -fobjc-arc -fobjc-runtime=macosx-10.8.0 -triple x86_64-apple-darwin12 -fblocks -Werror %s
-// DISABLE: mingw32
 
 #if __has_feature(objc_arc)
 #define NS_AUTOMATED_REFCOUNT_UNAVAILABLE __attribute__((unavailable("not available in automatic reference counting mode")))
diff --git a/test/ARCMT/checking.m b/test/ARCMT/checking.m
index a550633..7815103 100644
--- a/test/ARCMT/checking.m
+++ b/test/ARCMT/checking.m
@@ -1,5 +1,4 @@
 // RUN: %clang_cc1 -arcmt-check -verify -triple x86_64-apple-darwin10 -fblocks -Werror %s
-// DISABLE: mingw32
 
 #if __has_feature(objc_arc)
 #define NS_AUTOMATED_REFCOUNT_UNAVAILABLE __attribute__((unavailable("not available in automatic reference counting mode")))
@@ -45,9 +44,9 @@
 };
 
 @interface A : NSObject
-- (id)retain; // expected-note {{declaration has been explicitly marked unavailable here}}
-- (id)retainCount; // expected-note {{declaration has been explicitly marked unavailable here}}
-- (id)autorelease; // expected-note 2 {{declaration has been explicitly marked unavailable here}}
+- (id)retain; // expected-note {{'retain' has been explicitly marked unavailable here}}
+- (id)retainCount; // expected-note {{'retainCount' has been explicitly marked unavailable here}}
+- (id)autorelease; // expected-note 2 {{'autorelease' has been explicitly marked unavailable here}}
 - (id)init;
 - (oneway void)release;
 - (void)dealloc;
diff --git a/test/ARCMT/cxx-checking.mm b/test/ARCMT/cxx-checking.mm
index 2f5d5d5..aa3bc46 100644
--- a/test/ARCMT/cxx-checking.mm
+++ b/test/ARCMT/cxx-checking.mm
@@ -1,5 +1,4 @@
 // RUN: %clang_cc1 -arcmt-check -verify -triple x86_64-apple-darwin10 -fsyntax-only -fblocks %s
-// DISABLE: mingw32
 
 // Classes that have an Objective-C object pointer.
 struct HasObjectMember0 {
@@ -81,7 +80,7 @@
 
 struct FlexibleArrayMember0 {
   int length;
-  id array[]; // expected-error{{flexible array member 'array' of non-POD element type 'id __strong[]'}}
+  id array[]; // expected-error{{flexible array member 'array' of type 'id __strong[]' with non-trivial destruction}}
 };
 
 struct FlexibleArrayMember1 {
diff --git a/test/ARCMT/cxx-rewrite.mm b/test/ARCMT/cxx-rewrite.mm
index 92bb718..4a9c50c 100644
--- a/test/ARCMT/cxx-rewrite.mm
+++ b/test/ARCMT/cxx-rewrite.mm
@@ -1,7 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c++ %s.result
 // RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c++ %s > %t
 // RUN: diff %t %s.result
-// DISABLE: mingw32
 
 #include "Common.h"
 
diff --git a/test/ARCMT/cxx-rewrite.mm.result b/test/ARCMT/cxx-rewrite.mm.result
index 7c944d5..a96d254 100644
--- a/test/ARCMT/cxx-rewrite.mm.result
+++ b/test/ARCMT/cxx-rewrite.mm.result
@@ -1,7 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c++ %s.result
 // RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c++ %s > %t
 // RUN: diff %t %s.result
-// DISABLE: mingw32
 
 #include "Common.h"
 
diff --git a/test/ARCMT/dealloc.m b/test/ARCMT/dealloc.m
index 34df1a4..d7a72af 100644
--- a/test/ARCMT/dealloc.m
+++ b/test/ARCMT/dealloc.m
@@ -1,7 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result
 // RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t
 // RUN: diff %t %s.result
-// DISABLE: mingw32
 
 @interface A
 - (id)retain;
diff --git a/test/ARCMT/dealloc.m.result b/test/ARCMT/dealloc.m.result
index 3ff2885..fbd9e44 100644
--- a/test/ARCMT/dealloc.m.result
+++ b/test/ARCMT/dealloc.m.result
@@ -1,7 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result
 // RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t
 // RUN: diff %t %s.result
-// DISABLE: mingw32
 
 @interface A
 - (id)retain;
diff --git a/test/ARCMT/designated-init-in-header/designated-init-in-header.m b/test/ARCMT/designated-init-in-header/designated-init-in-header.m
new file mode 100644
index 0000000..8286583
--- /dev/null
+++ b/test/ARCMT/designated-init-in-header/designated-init-in-header.m
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 -objcmt-migrate-designated-init -objcmt-migrate-readwrite-property -objcmt-migrate-instancetype -x objective-c %S/file1.m.in -triple x86_64-apple-darwin11 -fobjc-arc -migrate -o %t1.remap
+// RUN: %clang_cc1 -objcmt-migrate-designated-init -objcmt-migrate-readwrite-property -objcmt-migrate-instancetype -x objective-c %S/file2.m.in -triple x86_64-apple-darwin11 -fobjc-arc -migrate -o %t2.remap
+// RUN: c-arcmt-test %t1.remap %t2.remap | arcmt-test -verify-transformed-files %S/header1.h.result %S/file2.m.in.result
diff --git a/test/ARCMT/designated-init-in-header/file1.m.in b/test/ARCMT/designated-init-in-header/file1.m.in
new file mode 100644
index 0000000..0201b32
--- /dev/null
+++ b/test/ARCMT/designated-init-in-header/file1.m.in
@@ -0,0 +1,2 @@
+#include "header1.h"
+
diff --git a/test/ARCMT/designated-init-in-header/file2.m.in b/test/ARCMT/designated-init-in-header/file2.m.in
new file mode 100644
index 0000000..2581597
--- /dev/null
+++ b/test/ARCMT/designated-init-in-header/file2.m.in
@@ -0,0 +1,14 @@
+#include "header1.h"
+
+@implementation S1
+-(int)prop { return 0; }
+-(void)setProp:(int)p {}
++(id)s1 { return 0; }
+-(id)initWithFoo:(NSString*)foo 
+{
+  self = [super init];
+  if (self) {
+  }
+  return self;
+}
+@end
diff --git a/test/ARCMT/designated-init-in-header/file2.m.in.result b/test/ARCMT/designated-init-in-header/file2.m.in.result
new file mode 100644
index 0000000..7465ed5
--- /dev/null
+++ b/test/ARCMT/designated-init-in-header/file2.m.in.result
@@ -0,0 +1,14 @@
+#include "header1.h"
+
+@implementation S1
+-(int)prop { return 0; }
+-(void)setProp:(int)p {}
++(instancetype)s1 { return 0; }
+-(instancetype)initWithFoo:(NSString*)foo 
+{
+  self = [super init];
+  if (self) {
+  }
+  return self;
+}
+@end
diff --git a/test/ARCMT/designated-init-in-header/header1.h b/test/ARCMT/designated-init-in-header/header1.h
new file mode 100644
index 0000000..c5668cc
--- /dev/null
+++ b/test/ARCMT/designated-init-in-header/header1.h
@@ -0,0 +1,14 @@
+#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
+
+@class NSString;
+
+@interface B1
+-(id)init;
+@end
+
+@interface S1 : B1
+-(int)prop;
+-(void)setProp:(int)p;
++(id)s1;
+-(id)initWithFoo:(NSString*)foo;
+@end
diff --git a/test/ARCMT/designated-init-in-header/header1.h.result b/test/ARCMT/designated-init-in-header/header1.h.result
new file mode 100644
index 0000000..974175b
--- /dev/null
+++ b/test/ARCMT/designated-init-in-header/header1.h.result
@@ -0,0 +1,13 @@
+#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
+
+@class NSString;
+
+@interface B1
+-(instancetype)init;
+@end
+
+@interface S1 : B1
+@property (nonatomic) int prop;
++(instancetype)s1;
+-(instancetype)initWithFoo:(NSString*)foo NS_DESIGNATED_INITIALIZER;
+@end
diff --git a/test/ARCMT/init.m b/test/ARCMT/init.m
index 9dbb1f8..b1f127e 100644
--- a/test/ARCMT/init.m
+++ b/test/ARCMT/init.m
@@ -1,7 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result
 // RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t
 // RUN: diff %t %s.result
-// DISABLE: mingw32
 
 #define nil (void *)0
 
diff --git a/test/ARCMT/init.m.result b/test/ARCMT/init.m.result
index d7f7300..d550ded 100644
--- a/test/ARCMT/init.m.result
+++ b/test/ARCMT/init.m.result
@@ -1,7 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result
 // RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t
 // RUN: diff %t %s.result
-// DISABLE: mingw32
 
 #define nil (void *)0
 
diff --git a/test/ARCMT/migrate-on-pch-and-module.m b/test/ARCMT/migrate-on-pch-and-module.m
new file mode 100644
index 0000000..c98ce46
--- /dev/null
+++ b/test/ARCMT/migrate-on-pch-and-module.m
@@ -0,0 +1,12 @@
+// RUN: rm -rf %t-mcp
+// RUN: %clang_cc1 -objcmt-migrate-subscripting -emit-pch -o %t.pch %s -isysroot %S/Inputs/System -triple x86_64-apple-darwin10 -F %S/Inputs -fmodules -fmodules-cache-path=%t-mcp -w
+// RUN: %clang_cc1 -objcmt-migrate-subscripting -include-pch %t.pch %s -migrate -o %t.remap -isysroot %S/Inputs/System -triple x86_64-apple-darwin10 -F %S/Inputs -fmodules -fmodules-cache-path=%t-mcp
+
+#ifndef HEADER
+#define HEADER
+
+@import Module;
+
+#else
+
+#endif
diff --git a/test/ARCMT/migrate-plist-output.m b/test/ARCMT/migrate-plist-output.m
index 377dce3..9b47b91 100644
--- a/test/ARCMT/migrate-plist-output.m
+++ b/test/ARCMT/migrate-plist-output.m
@@ -49,4 +49,3 @@
 // CHECK: </dict>
 // CHECK: </plist>
 
-// DISABLE: mingw32
diff --git a/test/ARCMT/migrate-space-in-path.m b/test/ARCMT/migrate-space-in-path.m
index 89dfe14..a797e6d 100644
--- a/test/ARCMT/migrate-space-in-path.m
+++ b/test/ARCMT/migrate-space-in-path.m
@@ -3,4 +3,3 @@
 // RUN: %clang_cc1 -arcmt-migrate -mt-migrate-directory %t.migrate %S/"with space"/test2.m.in -x objective-c 
 // RUN: c-arcmt-test -mt-migrate-directory %t.migrate | arcmt-test -verify-transformed-files %S/"with space"/test1.m.in.result %S/"with space"/test2.m.in.result %S/"with space"/test.h.result
 // RUN: rm -rf %t.migrate
-// DISABLE: mingw32
diff --git a/test/ARCMT/migrate-with-pch.m b/test/ARCMT/migrate-with-pch.m
index 7dca8be..1aafbda 100644
--- a/test/ARCMT/migrate-with-pch.m
+++ b/test/ARCMT/migrate-with-pch.m
@@ -4,4 +4,3 @@
 // RUN: %clang_cc1 -arcmt-migrate -mt-migrate-directory %t %S/Inputs/test2.m.in -x objective-c -include-pch %t.pch
 // RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %S/Inputs/test1.m.in.result %S/Inputs/test2.m.in.result %S/Inputs/test.h.result
 // RUN: rm -rf %t
-// DISABLE: mingw32
diff --git a/test/ARCMT/migrate.m b/test/ARCMT/migrate.m
index 6f41258..d92cef7 100644
--- a/test/ARCMT/migrate.m
+++ b/test/ARCMT/migrate.m
@@ -3,4 +3,3 @@
 // RUN: %clang_cc1 -arcmt-migrate -mt-migrate-directory %t %S/Inputs/test2.m.in -x objective-c 
 // RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %S/Inputs/test1.m.in.result %S/Inputs/test2.m.in.result %S/Inputs/test.h.result
 // RUN: rm -rf %t
-// DISABLE: mingw32
diff --git a/test/ARCMT/no-canceling-bridge-to-bridge-cast.m b/test/ARCMT/no-canceling-bridge-to-bridge-cast.m
index 81841fb..2c47822 100644
--- a/test/ARCMT/no-canceling-bridge-to-bridge-cast.m
+++ b/test/ARCMT/no-canceling-bridge-to-bridge-cast.m
@@ -1,5 +1,4 @@
 // RUN: %clang_cc1 -arcmt-check -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -verify %s 
-// DISABLE: mingw32
 // rdar://10387088
 typedef const void * CFTypeRef;
 CFTypeRef CFBridgingRetain(id X);
diff --git a/test/ARCMT/nonobjc-to-objc-cast-2.m b/test/ARCMT/nonobjc-to-objc-cast-2.m
index e554c7d..2b421b0 100644
--- a/test/ARCMT/nonobjc-to-objc-cast-2.m
+++ b/test/ARCMT/nonobjc-to-objc-cast-2.m
@@ -1,5 +1,4 @@
 // RUN: %clang_cc1 -arcmt-check -verify -triple x86_64-apple-darwin10 %s
-// DISABLE: mingw32
 
 #include "Common.h"
 
diff --git a/test/ARCMT/nonobjc-to-objc-cast.m b/test/ARCMT/nonobjc-to-objc-cast.m
index 55b6655..b7d2a73 100644
--- a/test/ARCMT/nonobjc-to-objc-cast.m
+++ b/test/ARCMT/nonobjc-to-objc-cast.m
@@ -1,7 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result
 // RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t
 // RUN: diff %t %s.result
-// DISABLE: mingw32
 
 #include "Common.h"
 
diff --git a/test/ARCMT/nonobjc-to-objc-cast.m.result b/test/ARCMT/nonobjc-to-objc-cast.m.result
index 4f508f6..ce827ba 100644
--- a/test/ARCMT/nonobjc-to-objc-cast.m.result
+++ b/test/ARCMT/nonobjc-to-objc-cast.m.result
@@ -1,7 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result
 // RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t
 // RUN: diff %t %s.result
-// DISABLE: mingw32
 
 #include "Common.h"
 
diff --git a/test/ARCMT/objcmt-arc-cf-annotations.m b/test/ARCMT/objcmt-arc-cf-annotations.m
index 9772825..c9a5b82 100644
--- a/test/ARCMT/objcmt-arc-cf-annotations.m
+++ b/test/ARCMT/objcmt-arc-cf-annotations.m
@@ -360,7 +360,7 @@
 
 NSDate* global_x;
 
-// Test to see if we supresss an error when we store the pointer
+// Test to see if we suppress an error when we store the pointer
 // to a global.
 
 CFAbsoluteTime f3() {
@@ -528,38 +528,54 @@
   CFRelease(*B);  // no-warning
 }
 
-// Test when we pass NULL to CFRetain/CFRelease/CFMakeCollectable.
+// Test when we pass NULL to CFRetain/CFRelease/CFMakeCollectable/CFAutorelease.
 void f16(int x, CFTypeRef p) {
   if (p)
     return;
 
-  if (x > 0) {
-    CFRelease(p); // expected-warning{{Null pointer argument in call to CFRelease}}
-  }
-  else if (x < 0) {
-    CFRetain(p); // expected-warning{{Null pointer argument in call to CFRetain}}
-  }
-  else {
-    CFMakeCollectable(p); // expected-warning{{Null pointer argument in call to CFMakeCollectable}}
+  switch (x) {
+  case 0:
+    CFRelease(p);
+    break;
+  case 1:
+    CFRetain(p);
+    break;
+  case 2:
+    CFMakeCollectable(p);
+    break;
+  case 3:
+    CFAutorelease(p);
+    break;
+  default:
+    break;
   }
 }
 
-// Test that an object is non-null after being CFRetained/CFReleased.
+// Test that an object is non-null after CFRetain/CFRelease/CFMakeCollectable/CFAutorelease.
 void f17(int x, CFTypeRef p) {
-  if (x > 0) {
+  switch (x) {
+  case 0:
     CFRelease(p);
     if (!p)
       CFRelease(0); // no-warning
-  }
-  else if (x < 0) {
+    break;
+  case 1:
     CFRetain(p);
     if (!p)
       CFRetain(0); // no-warning
-  }
-  else {
+    break;
+  case 2:
     CFMakeCollectable(p);
     if (!p)
       CFMakeCollectable(0); // no-warning
+    break;
+  case 3:
+    CFAutorelease(p);
+    if (!p)
+      CFAutorelease(0); // no-warning
+    break;
+  default:
+    break;
   }
 }
 
diff --git a/test/ARCMT/objcmt-arc-cf-annotations.m.result b/test/ARCMT/objcmt-arc-cf-annotations.m.result
index 7e0a904..84bc43d 100644
--- a/test/ARCMT/objcmt-arc-cf-annotations.m.result
+++ b/test/ARCMT/objcmt-arc-cf-annotations.m.result
@@ -390,7 +390,7 @@
 
 NSDate* global_x;
 
-// Test to see if we supresss an error when we store the pointer
+// Test to see if we suppress an error when we store the pointer
 // to a global.
 
 CFAbsoluteTime f3() {
@@ -570,38 +570,54 @@
   CFRelease(*B);  // no-warning
 }
 
-// Test when we pass NULL to CFRetain/CFRelease/CFMakeCollectable.
+// Test when we pass NULL to CFRetain/CFRelease/CFMakeCollectable/CFAutorelease.
 void f16(int x, CFTypeRef p) {
   if (p)
     return;
 
-  if (x > 0) {
-    CFRelease(p); // expected-warning{{Null pointer argument in call to CFRelease}}
-  }
-  else if (x < 0) {
-    CFRetain(p); // expected-warning{{Null pointer argument in call to CFRetain}}
-  }
-  else {
-    CFMakeCollectable(p); // expected-warning{{Null pointer argument in call to CFMakeCollectable}}
+  switch (x) {
+  case 0:
+    CFRelease(p);
+    break;
+  case 1:
+    CFRetain(p);
+    break;
+  case 2:
+    CFMakeCollectable(p);
+    break;
+  case 3:
+    CFAutorelease(p);
+    break;
+  default:
+    break;
   }
 }
 
-// Test that an object is non-null after being CFRetained/CFReleased.
+// Test that an object is non-null after CFRetain/CFRelease/CFMakeCollectable/CFAutorelease.
 void f17(int x, CFTypeRef p) {
-  if (x > 0) {
+  switch (x) {
+  case 0:
     CFRelease(p);
     if (!p)
       CFRelease(0); // no-warning
-  }
-  else if (x < 0) {
+    break;
+  case 1:
     CFRetain(p);
     if (!p)
       CFRetain(0); // no-warning
-  }
-  else {
+    break;
+  case 2:
     CFMakeCollectable(p);
     if (!p)
       CFMakeCollectable(0); // no-warning
+    break;
+  case 3:
+    CFAutorelease(p);
+    if (!p)
+      CFAutorelease(0); // no-warning
+    break;
+  default:
+    break;
   }
 }
 
diff --git a/test/ARCMT/objcmt-atomic-property.m.result b/test/ARCMT/objcmt-atomic-property.m.result
index 1650cd2..3378ff1 100644
--- a/test/ARCMT/objcmt-atomic-property.m.result
+++ b/test/ARCMT/objcmt-atomic-property.m.result
@@ -23,14 +23,14 @@
 }
 @property (weak) NSString *WeakProp;
 
-@property (retain) NSString *StrongProp;
+@property (strong) NSString *StrongProp;
 
-@property (retain) NSString *UnavailProp  __attribute__((unavailable));
+@property (strong) NSString *UnavailProp  __attribute__((unavailable));
 - (void) setUnavailProp  : (NSString *)Val;
 
-@property (retain) NSString *UnavailProp1  __attribute__((unavailable));
+@property (strong) NSString *UnavailProp1  __attribute__((unavailable));
 
-@property (retain) NSString *UnavailProp2;
+@property (strong) NSString *UnavailProp2;
 - (void) setUnavailProp2  : (NSString *)Val  __attribute__((unavailable));
 
 @property (copy) NSDictionary *undoAction;
@@ -48,10 +48,10 @@
     NSArray *_names3;
     NSArray *_names4;
 }
-@property (retain) NSArray *names2;
-@property (retain) NSArray *names3;
-@property (retain) NSArray *names4;
-@property (retain) NSArray *names1;
+@property (strong) NSArray *names2;
+@property (strong) NSArray *names3;
+@property (strong) NSArray *names4;
+@property (strong) NSArray *names1;
 @end
 
 // Properties that contain the name "delegate" or "dataSource",
@@ -64,9 +64,9 @@
 @property (assign) id xxxdelegateYYY;
 
 
-@property (retain) id MYtarget;
+@property (strong) id MYtarget;
 
-@property (retain) id targetX;
+@property (strong) id targetX;
  
 @property  int value;
 
@@ -80,14 +80,14 @@
 
 - (void) Nothing;
 @property (readonly) int Length;
-@property (readonly, retain) id object;
+@property (readonly, strong) id object;
 + (double) D;
 @property (readonly) void *JSObject WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER);
 @property (getter=isIgnoringInteractionEvents, readonly) BOOL ignoringInteractionEvents;
 
-@property (getter=getStringValue, retain) NSString *stringValue;
+@property (getter=getStringValue, strong) NSString *stringValue;
 @property (getter=getCounterValue, readonly) BOOL counterValue;
-@property (getter=getns_dixtionary, readonly, retain) NSDictionary *ns_dixtionary;
+@property (getter=getns_dixtionary, readonly, copy) NSDictionary *ns_dixtionary;
 
 - (BOOL)is3bar; // watch out
 - (NSString *)get3foo; // watch out
@@ -108,9 +108,9 @@
 @property (assign) id xxxdelegateYYY;
 
 
-@property (retain) id MYtarget;
+@property (strong) id MYtarget;
 
-@property (retain) id targetX;
+@property (strong) id targetX;
 
 @property  int value;
 
@@ -124,7 +124,7 @@
 
 - (void) Nothing;
 @property (readonly) int Length;
-@property (readonly, retain) id object;
+@property (readonly, strong) id object;
 + (double) D;
 
 - (BOOL)is3bar; // watch out
@@ -161,26 +161,26 @@
 
 @interface NSURL
 // Do not infer a property.
-@property (retain) NSURL *appStoreReceiptURL NS_AVAILABLE;
+@property (strong) NSURL *appStoreReceiptURL NS_AVAILABLE;
 - (void) setAppStoreReceiptURL : (NSURL *)object;
 
-@property (retain) NSURL *appStoreReceiptURLX NS_AVAILABLE;
+@property (strong) NSURL *appStoreReceiptURLX NS_AVAILABLE;
 
 // Do not infer a property.
-@property (retain) NSURL *appStoreReceiptURLY ;
+@property (strong) NSURL *appStoreReceiptURLY ;
 - (void) setAppStoreReceiptURLY : (NSURL *)object NS_AVAILABLE;
 
-@property (readonly, retain) id OkToInfer NS_AVAILABLE;
+@property (readonly, strong) id OkToInfer NS_AVAILABLE;
 
 // Do not infer a property.
-@property (retain) NSURL *appStoreReceiptURLZ ;
+@property (strong) NSURL *appStoreReceiptURLZ ;
 - (void) setAppStoreReceiptURLZ : (NSURL *)object NS_AVAILABLE;
 
 // Do not infer a property.
 - (id) t1 NORETURN NS_AVAILABLE;
 - (void) setT1 : (id) arg NS_AVAILABLE;
 
-@property (retain) id method1 ALIGNED NS_AVAILABLE;
+@property (strong) id method1 ALIGNED NS_AVAILABLE;
 
 - (NSURL *)init;  // No Change
 + (id)alloc;      // No Change
diff --git a/test/ARCMT/objcmt-deprecated-category.m b/test/ARCMT/objcmt-deprecated-category.m
deleted file mode 100644
index 5939e5a..0000000
--- a/test/ARCMT/objcmt-deprecated-category.m
+++ /dev/null
@@ -1,48 +0,0 @@
-// RUN: rm -rf %t
-// RUN: %clang_cc1 -objcmt-migrate-annotation -mt-migrate-directory %t %s -x objective-c -triple x86_64-apple-darwin11
-// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s.result
-// rdar://15337661
-
-#define DEPRECATED  __attribute__((deprecated)) 
-
-@interface NSArray
-- (int)one;
-@end
-
-@interface NSArray (NSDraggingSourceDeprecated)
-
-/* This method is unsafe because it could potentially cause buffer overruns. You should use -getObjects:range: instead.
-*/
-- (void)getObjects:(id __unsafe_unretained [])objects;
-- (void)dep_getObjects:(id __unsafe_unretained [])dep_objects DEPRECATED;
-
-@end
-
-@interface NSArray (NSDeprecated)
-
-/* This method is unsafe because it could potentially cause buffer overruns. You should use -getObjects:range: instead.
-*/
-- (void)dep_getObjects:(id __unsafe_unretained [])dep_objects DEPRECATED;
-- (void)getObjects:(id __unsafe_unretained [])objects;
-@property int P1;
-@property int P2 DEPRECATED;
-@end
-
-@interface NSArray (DraggingSourceDeprecated)
-
-/* This method is unsafe because it could potentially cause buffer overruns. You should use -getObjects:range: instead.
-*/
-- (void)getObjects:(id __unsafe_unretained [])objects;
-- (void)dep_getObjects:(id __unsafe_unretained [])dep_objects DEPRECATED;
-@property int P1;
-@property int P2 DEPRECATED;
-
-@end
-
-@interface NSArray (Deprecated)
-- (void)getObjects:(id __unsafe_unretained [])objects;
-- (void)dep_getObjects:(id __unsafe_unretained [])dep_objects DEPRECATED;
-@property int P1;
-@property int P2 DEPRECATED;
-@end
diff --git a/test/ARCMT/objcmt-deprecated-category.m.result b/test/ARCMT/objcmt-deprecated-category.m.result
deleted file mode 100644
index 3cb1000..0000000
--- a/test/ARCMT/objcmt-deprecated-category.m.result
+++ /dev/null
@@ -1,48 +0,0 @@
-// RUN: rm -rf %t
-// RUN: %clang_cc1 -objcmt-migrate-annotation -mt-migrate-directory %t %s -x objective-c -triple x86_64-apple-darwin11
-// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s.result
-// rdar://15337661
-
-#define DEPRECATED  __attribute__((deprecated)) 
-
-@interface NSArray
-- (int)one;
-@end
-
-@interface NSArray (NSDraggingSourceDeprecated)
-
-/* This method is unsafe because it could potentially cause buffer overruns. You should use -getObjects:range: instead.
-*/
-- (void)getObjects:(id __unsafe_unretained [])objects DEPRECATED;
-- (void)dep_getObjects:(id __unsafe_unretained [])dep_objects DEPRECATED;
-
-@end
-
-@interface NSArray (NSDeprecated)
-
-/* This method is unsafe because it could potentially cause buffer overruns. You should use -getObjects:range: instead.
-*/
-- (void)dep_getObjects:(id __unsafe_unretained [])dep_objects DEPRECATED;
-- (void)getObjects:(id __unsafe_unretained [])objects DEPRECATED;
-@property int P1 DEPRECATED;
-@property int P2 DEPRECATED;
-@end
-
-@interface NSArray (DraggingSourceDeprecated)
-
-/* This method is unsafe because it could potentially cause buffer overruns. You should use -getObjects:range: instead.
-*/
-- (void)getObjects:(id __unsafe_unretained [])objects DEPRECATED;
-- (void)dep_getObjects:(id __unsafe_unretained [])dep_objects DEPRECATED;
-@property int P1 DEPRECATED;
-@property int P2 DEPRECATED;
-
-@end
-
-@interface NSArray (Deprecated)
-- (void)getObjects:(id __unsafe_unretained [])objects DEPRECATED;
-- (void)dep_getObjects:(id __unsafe_unretained [])dep_objects DEPRECATED;
-@property int P1 DEPRECATED;
-@property int P2 DEPRECATED;
-@end
diff --git a/test/ARCMT/objcmt-designated-initializer.m b/test/ARCMT/objcmt-designated-initializer.m
new file mode 100644
index 0000000..279d4f3
--- /dev/null
+++ b/test/ARCMT/objcmt-designated-initializer.m
@@ -0,0 +1,44 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -objcmt-migrate-designated-init %s -triple x86_64-apple-darwin11 -fobjc-arc -migrate -o %t.remap
+// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %s.result
+// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -x objective-c -fobjc-arc %s.result
+
+#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
+
+@class NSString;
+
+@interface B1
+-(id)init;
+@end
+
+@interface S1 : B1
+-(id)initWithFoo:(NSString*)foo;
+@end
+
+@implementation S1
+-(id)initWithFoo:(NSString*)foo
+{
+  self = [super init];
+  if (self) {
+  }
+  return self;
+}
+@end
+
+@interface B2
+-(id)init NS_DESIGNATED_INITIALIZER;
+@end
+
+@interface S2 : B2
+-(id)init;
+@end
+
+@implementation S2
+-(id)init
+{
+  self = [super init];
+  if (self) {
+  }
+  return self;
+}
+@end
diff --git a/test/ARCMT/objcmt-designated-initializer.m.result b/test/ARCMT/objcmt-designated-initializer.m.result
new file mode 100644
index 0000000..4c59b0c
--- /dev/null
+++ b/test/ARCMT/objcmt-designated-initializer.m.result
@@ -0,0 +1,44 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -objcmt-migrate-designated-init %s -triple x86_64-apple-darwin11 -fobjc-arc -migrate -o %t.remap
+// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %s.result
+// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -x objective-c -fobjc-arc %s.result
+
+#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
+
+@class NSString;
+
+@interface B1
+-(id)init;
+@end
+
+@interface S1 : B1
+-(id)initWithFoo:(NSString*)foo NS_DESIGNATED_INITIALIZER;
+@end
+
+@implementation S1
+-(id)initWithFoo:(NSString*)foo
+{
+  self = [super init];
+  if (self) {
+  }
+  return self;
+}
+@end
+
+@interface B2
+-(id)init NS_DESIGNATED_INITIALIZER;
+@end
+
+@interface S2 : B2
+-(id)init;
+@end
+
+@implementation S2
+-(id)init
+{
+  self = [super init];
+  if (self) {
+  }
+  return self;
+}
+@end
diff --git a/test/ARCMT/objcmt-instancetype-2.m.result b/test/ARCMT/objcmt-instancetype-2.m.result
index 8837e97..7a32894 100644
--- a/test/ARCMT/objcmt-instancetype-2.m.result
+++ b/test/ARCMT/objcmt-instancetype-2.m.result
@@ -16,10 +16,10 @@
 
 @class NSString, NSURL;
 @interface NSString (NSStringDeprecated)
-+ (instancetype)stringWithContentsOfFile:(NSString *)path __attribute__((availability(macosx,introduced=10.0 ,message="" )));
-+ (instancetype)stringWithContentsOfURL:(NSURL *)url __attribute__((availability(macosx,introduced=10.0 ,message="" )));
-+ (instancetype)stringWithCString:(const char *)bytes length:(NSUInteger)length __attribute__((availability(macosx,introduced=10.0 ,message="" )));
-+ (instancetype)stringWithCString:(const char *)bytes __attribute__((availability(macosx,introduced=10.0 ,message="" )));
++ (id)stringWithContentsOfFile:(NSString *)path __attribute__((availability(macosx,introduced=10.0 ,message="" )));
++ (id)stringWithContentsOfURL:(NSURL *)url __attribute__((availability(macosx,introduced=10.0 ,message="" )));
++ (id)stringWithCString:(const char *)bytes length:(NSUInteger)length __attribute__((availability(macosx,introduced=10.0 ,message="" )));
++ (id)stringWithCString:(const char *)bytes __attribute__((availability(macosx,introduced=10.0 ,message="" )));
 @end
 
 
diff --git a/test/ARCMT/objcmt-instancetype-unnecessary-diff.m b/test/ARCMT/objcmt-instancetype-unnecessary-diff.m
new file mode 100644
index 0000000..e250bb0
--- /dev/null
+++ b/test/ARCMT/objcmt-instancetype-unnecessary-diff.m
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -objcmt-migrate-instancetype %s -triple x86_64-apple-darwin11 -fobjc-arc -migrate -o %t.remap
+// RUN: FileCheck %s -input-file=%t.remap
+
+// Make sure we don't create an edit unnecessarily.
+// CHECK-NOT: instancetype
+
+@class NSString;
+@interface NSDictionary
++(instancetype) dictionaryWithURLEncodedString:(NSString *)urlEncodedString;
+@end
diff --git a/test/ARCMT/objcmt-ns-nonatomic-iosonly.m.result b/test/ARCMT/objcmt-ns-nonatomic-iosonly.m.result
index 804142e..8e9e3a0 100644
--- a/test/ARCMT/objcmt-ns-nonatomic-iosonly.m.result
+++ b/test/ARCMT/objcmt-ns-nonatomic-iosonly.m.result
@@ -30,14 +30,14 @@
 }
 @property (NS_NONATOMIC_IOSONLY, weak) NSString *WeakProp;
 
-@property (NS_NONATOMIC_IOSONLY, retain) NSString *StrongProp;
+@property (NS_NONATOMIC_IOSONLY, strong) NSString *StrongProp;
 
-@property (NS_NONATOMIC_IOSONLY, retain) NSString *UnavailProp  __attribute__((unavailable));
+@property (NS_NONATOMIC_IOSONLY, strong) NSString *UnavailProp  __attribute__((unavailable));
 - (void) setUnavailProp  : (NSString *)Val;
 
-@property (NS_NONATOMIC_IOSONLY, retain) NSString *UnavailProp1  __attribute__((unavailable));
+@property (NS_NONATOMIC_IOSONLY, strong) NSString *UnavailProp1  __attribute__((unavailable));
 
-@property (NS_NONATOMIC_IOSONLY, retain) NSString *UnavailProp2;
+@property (NS_NONATOMIC_IOSONLY, strong) NSString *UnavailProp2;
 - (void) setUnavailProp2  : (NSString *)Val  __attribute__((unavailable));
 
 @property (NS_NONATOMIC_IOSONLY, copy) NSDictionary *undoAction;
@@ -55,10 +55,10 @@
     NSArray *_names3;
     NSArray *_names4;
 }
-@property (NS_NONATOMIC_IOSONLY, retain) NSArray *names2;
-@property (NS_NONATOMIC_IOSONLY, retain) NSArray *names3;
-@property (NS_NONATOMIC_IOSONLY, retain) NSArray *names4;
-@property (NS_NONATOMIC_IOSONLY, retain) NSArray *names1;
+@property (NS_NONATOMIC_IOSONLY, strong) NSArray *names2;
+@property (NS_NONATOMIC_IOSONLY, strong) NSArray *names3;
+@property (NS_NONATOMIC_IOSONLY, strong) NSArray *names4;
+@property (NS_NONATOMIC_IOSONLY, strong) NSArray *names1;
 @end
 
 // Properties that contain the name "delegate" or "dataSource",
@@ -71,9 +71,9 @@
 @property (NS_NONATOMIC_IOSONLY, assign) id xxxdelegateYYY;
 
 
-@property (NS_NONATOMIC_IOSONLY, retain) id MYtarget;
+@property (NS_NONATOMIC_IOSONLY, strong) id MYtarget;
 
-@property (NS_NONATOMIC_IOSONLY, retain) id targetX;
+@property (NS_NONATOMIC_IOSONLY, strong) id targetX;
  
 @property (NS_NONATOMIC_IOSONLY) int value;
 
@@ -87,14 +87,14 @@
 
 - (void) Nothing;
 @property (NS_NONATOMIC_IOSONLY, readonly) int Length;
-@property (NS_NONATOMIC_IOSONLY, readonly, retain) id object;
+@property (NS_NONATOMIC_IOSONLY, readonly, strong) id object;
 + (double) D;
 @property (NS_NONATOMIC_IOSONLY, readonly) void *JSObject WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER);
 @property (NS_NONATOMIC_IOSONLY, getter=isIgnoringInteractionEvents, readonly) BOOL ignoringInteractionEvents;
 
-@property (NS_NONATOMIC_IOSONLY, getter=getStringValue, retain) NSString *stringValue;
+@property (NS_NONATOMIC_IOSONLY, getter=getStringValue, strong) NSString *stringValue;
 @property (NS_NONATOMIC_IOSONLY, getter=getCounterValue, readonly) BOOL counterValue;
-@property (NS_NONATOMIC_IOSONLY, getter=getns_dixtionary, readonly, retain) NSDictionary *ns_dixtionary;
+@property (NS_NONATOMIC_IOSONLY, getter=getns_dixtionary, readonly, copy) NSDictionary *ns_dixtionary;
 
 - (BOOL)is3bar; // watch out
 - (NSString *)get3foo; // watch out
@@ -115,9 +115,9 @@
 @property (NS_NONATOMIC_IOSONLY, assign) id xxxdelegateYYY;
 
 
-@property (NS_NONATOMIC_IOSONLY, retain) id MYtarget;
+@property (NS_NONATOMIC_IOSONLY, strong) id MYtarget;
 
-@property (NS_NONATOMIC_IOSONLY, retain) id targetX;
+@property (NS_NONATOMIC_IOSONLY, strong) id targetX;
 
 @property (NS_NONATOMIC_IOSONLY) int value;
 
@@ -131,7 +131,7 @@
 
 - (void) Nothing;
 @property (NS_NONATOMIC_IOSONLY, readonly) int Length;
-@property (NS_NONATOMIC_IOSONLY, readonly, retain) id object;
+@property (NS_NONATOMIC_IOSONLY, readonly, strong) id object;
 + (double) D;
 
 - (BOOL)is3bar; // watch out
@@ -168,26 +168,26 @@
 
 @interface NSURL
 // Do not infer a property.
-@property (NS_NONATOMIC_IOSONLY, retain) NSURL *appStoreReceiptURL NS_AVAILABLE;
+@property (NS_NONATOMIC_IOSONLY, strong) NSURL *appStoreReceiptURL NS_AVAILABLE;
 - (void) setAppStoreReceiptURL : (NSURL *)object;
 
-@property (NS_NONATOMIC_IOSONLY, retain) NSURL *appStoreReceiptURLX NS_AVAILABLE;
+@property (NS_NONATOMIC_IOSONLY, strong) NSURL *appStoreReceiptURLX NS_AVAILABLE;
 
 // Do not infer a property.
-@property (NS_NONATOMIC_IOSONLY, retain) NSURL *appStoreReceiptURLY ;
+@property (NS_NONATOMIC_IOSONLY, strong) NSURL *appStoreReceiptURLY ;
 - (void) setAppStoreReceiptURLY : (NSURL *)object NS_AVAILABLE;
 
-@property (NS_NONATOMIC_IOSONLY, readonly, retain) id OkToInfer NS_AVAILABLE;
+@property (NS_NONATOMIC_IOSONLY, readonly, strong) id OkToInfer NS_AVAILABLE;
 
 // Do not infer a property.
-@property (NS_NONATOMIC_IOSONLY, retain) NSURL *appStoreReceiptURLZ ;
+@property (NS_NONATOMIC_IOSONLY, strong) NSURL *appStoreReceiptURLZ ;
 - (void) setAppStoreReceiptURLZ : (NSURL *)object NS_AVAILABLE;
 
 // Do not infer a property.
 - (id) t1 NORETURN NS_AVAILABLE;
 - (void) setT1 : (id) arg NS_AVAILABLE;
 
-@property (NS_NONATOMIC_IOSONLY, retain) id method1 ALIGNED NS_AVAILABLE;
+@property (NS_NONATOMIC_IOSONLY, strong) id method1 ALIGNED NS_AVAILABLE;
 
 - (NSURL *)init;  // No Change
 + (id)alloc;      // No Change
diff --git a/test/ARCMT/objcmt-property-availability.m.result b/test/ARCMT/objcmt-property-availability.m.result
index 681f9a9..a5a45e3 100644
--- a/test/ARCMT/objcmt-property-availability.m.result
+++ b/test/ARCMT/objcmt-property-availability.m.result
@@ -19,20 +19,20 @@
 #define UNAVAILABLE __attribute__((unavailable("not available in automatic reference counting mode")))
 
 @interface MKMapItem
-@property (nonatomic, retain) MKMapItem *source NS_AVAILABLE(10_9, 6_0);
+@property (nonatomic, strong) MKMapItem *source NS_AVAILABLE(10_9, 6_0);
 - (void)setSource:(MKMapItem *)source NS_AVAILABLE(10_9, 7_0);
 
-@property (nonatomic, retain) MKMapItem *dest NS_AVAILABLE(10_9, 6_0);
+@property (nonatomic, strong) MKMapItem *dest NS_AVAILABLE(10_9, 6_0);
 
-@property (nonatomic, retain) MKMapItem *final;
+@property (nonatomic, strong) MKMapItem *final;
 
-@property (nonatomic, retain) MKMapItem *total NS_AVAILABLE(10_9, 6_0);
+@property (nonatomic, strong) MKMapItem *total NS_AVAILABLE(10_9, 6_0);
 - (void)setTotal:(MKMapItem *)source;
 
 - (MKMapItem *)comp NS_AVAILABLE(10_9, 6_0);
 - (void)setComp:(MKMapItem *)source UNAVAILABLE;
 
-@property (nonatomic, retain) MKMapItem *tally  UNAVAILABLE NS_AVAILABLE(10_9, 6_0);
+@property (nonatomic, strong) MKMapItem *tally  UNAVAILABLE NS_AVAILABLE(10_9, 6_0);
 
 - (MKMapItem *)itally  NS_AVAILABLE(10_9, 6_0);
 - (void)setItally:(MKMapItem *)source UNAVAILABLE NS_AVAILABLE(10_9, 6_0);
diff --git a/test/ARCMT/objcmt-property.m b/test/ARCMT/objcmt-property.m
index 3b77aad..61739ef 100644
--- a/test/ARCMT/objcmt-property.m
+++ b/test/ARCMT/objcmt-property.m
@@ -70,6 +70,9 @@
 
 - (id) dataSource;
 
+// rdar://15509831
+- (id)delegate;
+
 - (id)xxxdelegateYYY;
 - (void)setXxxdelegateYYY:(id)delegate;
 
diff --git a/test/ARCMT/objcmt-property.m.result b/test/ARCMT/objcmt-property.m.result
index c6380c8..ec4ac85 100644
--- a/test/ARCMT/objcmt-property.m.result
+++ b/test/ARCMT/objcmt-property.m.result
@@ -23,14 +23,14 @@
 }
 @property (nonatomic, weak) NSString *WeakProp;
 
-@property (nonatomic, retain) NSString *StrongProp;
+@property (nonatomic, strong) NSString *StrongProp;
 
-@property (nonatomic, retain) NSString *UnavailProp  __attribute__((unavailable));
+@property (nonatomic, strong) NSString *UnavailProp  __attribute__((unavailable));
 - (void) setUnavailProp  : (NSString *)Val;
 
-@property (nonatomic, retain) NSString *UnavailProp1  __attribute__((unavailable));
+@property (nonatomic, strong) NSString *UnavailProp1  __attribute__((unavailable));
 
-@property (nonatomic, retain) NSString *UnavailProp2;
+@property (nonatomic, strong) NSString *UnavailProp2;
 - (void) setUnavailProp2  : (NSString *)Val  __attribute__((unavailable));
 
 @property (nonatomic, copy) NSDictionary *undoAction;
@@ -48,10 +48,10 @@
     NSArray *_names3;
     NSArray *_names4;
 }
-@property (nonatomic, retain) NSArray *names2;
-@property (nonatomic, retain) NSArray *names3;
-@property (nonatomic, retain) NSArray *names4;
-@property (nonatomic, retain) NSArray *names1;
+@property (nonatomic, strong) NSArray *names2;
+@property (nonatomic, strong) NSArray *names3;
+@property (nonatomic, strong) NSArray *names4;
+@property (nonatomic, strong) NSArray *names1;
 @end
 
 // Properties that contain the name "delegate" or "dataSource",
@@ -61,12 +61,15 @@
 
 @property (nonatomic, assign) id dataSource;
 
+// rdar://15509831
+@property (nonatomic, readonly, assign) id delegate;
+
 @property (nonatomic, assign) id xxxdelegateYYY;
 
 
-@property (nonatomic, retain) id MYtarget;
+@property (nonatomic, strong) id MYtarget;
 
-@property (nonatomic, retain) id targetX;
+@property (nonatomic, strong) id targetX;
  
 @property (nonatomic) int value;
 
@@ -80,14 +83,14 @@
 
 - (void) Nothing;
 @property (nonatomic, readonly) int Length;
-@property (nonatomic, readonly, retain) id object;
+@property (nonatomic, readonly, strong) id object;
 + (double) D;
 @property (nonatomic, readonly) void *JSObject WEBKIT_OBJC_METHOD_ANNOTATION(AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER);
 @property (nonatomic, getter=isIgnoringInteractionEvents, readonly) BOOL ignoringInteractionEvents;
 
-@property (nonatomic, getter=getStringValue, retain) NSString *stringValue;
+@property (nonatomic, getter=getStringValue, strong) NSString *stringValue;
 @property (nonatomic, getter=getCounterValue, readonly) BOOL counterValue;
-@property (nonatomic, getter=getns_dixtionary, readonly, retain) NSDictionary *ns_dixtionary;
+@property (nonatomic, getter=getns_dixtionary, readonly, copy) NSDictionary *ns_dixtionary;
 
 - (BOOL)is3bar; // watch out
 - (NSString *)get3foo; // watch out
@@ -108,9 +111,9 @@
 @property (nonatomic, assign) id xxxdelegateYYY;
 
 
-@property (nonatomic, retain) id MYtarget;
+@property (nonatomic, strong) id MYtarget;
 
-@property (nonatomic, retain) id targetX;
+@property (nonatomic, strong) id targetX;
 
 @property (nonatomic) int value;
 
@@ -124,7 +127,7 @@
 
 - (void) Nothing;
 @property (nonatomic, readonly) int Length;
-@property (nonatomic, readonly, retain) id object;
+@property (nonatomic, readonly, strong) id object;
 + (double) D;
 
 - (BOOL)is3bar; // watch out
@@ -161,26 +164,26 @@
 
 @interface NSURL
 // Do not infer a property.
-@property (nonatomic, retain) NSURL *appStoreReceiptURL NS_AVAILABLE;
+@property (nonatomic, strong) NSURL *appStoreReceiptURL NS_AVAILABLE;
 - (void) setAppStoreReceiptURL : (NSURL *)object;
 
-@property (nonatomic, retain) NSURL *appStoreReceiptURLX NS_AVAILABLE;
+@property (nonatomic, strong) NSURL *appStoreReceiptURLX NS_AVAILABLE;
 
 // Do not infer a property.
-@property (nonatomic, retain) NSURL *appStoreReceiptURLY ;
+@property (nonatomic, strong) NSURL *appStoreReceiptURLY ;
 - (void) setAppStoreReceiptURLY : (NSURL *)object NS_AVAILABLE;
 
-@property (nonatomic, readonly, retain) id OkToInfer NS_AVAILABLE;
+@property (nonatomic, readonly, strong) id OkToInfer NS_AVAILABLE;
 
 // Do not infer a property.
-@property (nonatomic, retain) NSURL *appStoreReceiptURLZ ;
+@property (nonatomic, strong) NSURL *appStoreReceiptURLZ ;
 - (void) setAppStoreReceiptURLZ : (NSURL *)object NS_AVAILABLE;
 
 // Do not infer a property.
 - (id) t1 NORETURN NS_AVAILABLE;
 - (void) setT1 : (id) arg NS_AVAILABLE;
 
-@property (nonatomic, retain) id method1 ALIGNED NS_AVAILABLE;
+@property (nonatomic, strong) id method1 ALIGNED NS_AVAILABLE;
 
 - (NSURL *)init;  // No Change
 + (id)alloc;      // No Change
diff --git a/test/ARCMT/objcmt-protocol-conformance.m b/test/ARCMT/objcmt-protocol-conformance.m
index 7bc7d93..f4c8f51 100644
--- a/test/ARCMT/objcmt-protocol-conformance.m
+++ b/test/ARCMT/objcmt-protocol-conformance.m
@@ -112,3 +112,19 @@
 @implementation Test7
 @end
 
+// rdar://15515206
+@interface BTLEBrowser
+@end
+
+@protocol CBCentralManagerDelegate; 
+
+@protocol CBCentralManagerDelegate 
+- (id) Meth1: (double) arg;
+@end
+
+@interface BTLEBrowser() <CBCentralManagerDelegate> 
+@end
+
+@implementation BTLEBrowser
+- (id) Meth15515206: (double) arg { return 0; }
+@end
diff --git a/test/ARCMT/objcmt-protocol-conformance.m.result b/test/ARCMT/objcmt-protocol-conformance.m.result
index dc0874c..0322ab8 100644
--- a/test/ARCMT/objcmt-protocol-conformance.m.result
+++ b/test/ARCMT/objcmt-protocol-conformance.m.result
@@ -112,3 +112,19 @@
 @implementation Test7
 @end
 
+// rdar://15515206
+@interface BTLEBrowser
+@end
+
+@protocol CBCentralManagerDelegate; 
+
+@protocol CBCentralManagerDelegate 
+- (id) Meth1: (double) arg;
+@end
+
+@interface BTLEBrowser() <CBCentralManagerDelegate> 
+@end
+
+@implementation BTLEBrowser
+- (id) Meth15515206: (double) arg { return 0; }
+@end
diff --git a/test/ARCMT/protected-scope.m b/test/ARCMT/protected-scope.m
index 8aece44..b522f54 100644
--- a/test/ARCMT/protected-scope.m
+++ b/test/ARCMT/protected-scope.m
@@ -1,7 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result
 // RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t
 // RUN: diff %t %s.result
-// DISABLE: mingw32
 
 #include "Common.h"
 
diff --git a/test/ARCMT/protected-scope.m.result b/test/ARCMT/protected-scope.m.result
index f385d88..55070f2 100644
--- a/test/ARCMT/protected-scope.m.result
+++ b/test/ARCMT/protected-scope.m.result
@@ -1,7 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fobjc-arc -x objective-c %s.result
 // RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s > %t
 // RUN: diff %t %s.result
-// DISABLE: mingw32
 
 #include "Common.h"
 
diff --git a/test/ARCMT/whitelisted/header1.h b/test/ARCMT/whitelisted/header1.h
index a3014eb..d94b9f7 100644
--- a/test/ARCMT/whitelisted/header1.h
+++ b/test/ARCMT/whitelisted/header1.h
@@ -2,4 +2,5 @@
 @interface I1 : NSObject
 -(int)prop;
 -(void)setProp:(int)p;
++(id)i1;
 @end
diff --git a/test/ARCMT/whitelisted/header1.h.result b/test/ARCMT/whitelisted/header1.h.result
index 7808fc8..65cbd26 100644
--- a/test/ARCMT/whitelisted/header1.h.result
+++ b/test/ARCMT/whitelisted/header1.h.result
@@ -1,4 +1,5 @@
 
 @interface I1 : NSObject
 @property (nonatomic) int prop;
++(instancetype)i1;
 @end
diff --git a/test/ARCMT/whitelisted/objcmt-with-whitelist-impl.m b/test/ARCMT/whitelisted/objcmt-with-whitelist-impl.m
new file mode 100644
index 0000000..d734eaa
--- /dev/null
+++ b/test/ARCMT/whitelisted/objcmt-with-whitelist-impl.m
@@ -0,0 +1,18 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -objcmt-migrate-readwrite-property -objcmt-migrate-instancetype -objcmt-white-list-dir-path=%S/Inputs %s -triple x86_64-apple-darwin11 -migrate -o %t.remap
+// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %S/header1.h.result %s.result
+
+@interface NSObject
++ (id)alloc;
+@end
+
+#include "header1.h"
+#include "header2.h"
+
+@interface I2(cat)
+-(id)initInCat;
+@end
+
+@implementation I1
++(id)i1 {}
+@end
diff --git a/test/ARCMT/whitelisted/objcmt-with-whitelist-impl.m.result b/test/ARCMT/whitelisted/objcmt-with-whitelist-impl.m.result
new file mode 100644
index 0000000..b936b52
--- /dev/null
+++ b/test/ARCMT/whitelisted/objcmt-with-whitelist-impl.m.result
@@ -0,0 +1,18 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -objcmt-migrate-readwrite-property -objcmt-migrate-instancetype -objcmt-white-list-dir-path=%S/Inputs %s -triple x86_64-apple-darwin11 -migrate -o %t.remap
+// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %S/header1.h.result %s.result
+
+@interface NSObject
++ (id)alloc;
+@end
+
+#include "header1.h"
+#include "header2.h"
+
+@interface I2(cat)
+-(id)initInCat;
+@end
+
+@implementation I1
++(instancetype)i1 {}
+@end
diff --git a/test/ARCMT/whitelisted/objcmt-with-whitelist.m b/test/ARCMT/whitelisted/objcmt-with-whitelist.m
index 1b44c9a..bef82c8 100644
--- a/test/ARCMT/whitelisted/objcmt-with-whitelist.m
+++ b/test/ARCMT/whitelisted/objcmt-with-whitelist.m
@@ -1,7 +1,7 @@
 // RUN: rm -rf %t
-// RUN: %clang_cc1 -objcmt-migrate-readwrite-property %s -triple x86_64-apple-darwin11 -migrate -o %t.remap
+// RUN: %clang_cc1 -objcmt-migrate-readwrite-property -objcmt-migrate-instancetype %s -triple x86_64-apple-darwin11 -migrate -o %t.remap
 // RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %S/header1.h.result %S/header2.h.result
-// RUN: %clang_cc1 -objcmt-migrate-readwrite-property -objcmt-white-list-dir-path=%S/Inputs %s -triple x86_64-apple-darwin11 -migrate -o %t.remap
+// RUN: %clang_cc1 -objcmt-migrate-readwrite-property -objcmt-migrate-instancetype -objcmt-white-list-dir-path=%S/Inputs %s -triple x86_64-apple-darwin11 -migrate -o %t.remap
 // RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %S/header1.h.result
 
 @interface NSObject
diff --git a/test/Analysis/Inputs/system-header-simulator-cxx.h b/test/Analysis/Inputs/system-header-simulator-cxx.h
index 9bb8ec4..3586921 100644
--- a/test/Analysis/Inputs/system-header-simulator-cxx.h
+++ b/test/Analysis/Inputs/system-header-simulator-cxx.h
@@ -144,7 +144,7 @@
   public:
     void pop_front() {
       // Fake use-after-free.
-      // No warning is expected as we are suppressing warning comming
+      // No warning is expected as we are suppressing warning coming
       // out of std::list.
       int z = 0;
       z = 5/z;
@@ -155,24 +155,47 @@
   // basic_string
   template<class _CharT, class _Alloc = allocator<_CharT> >
   class __attribute__ ((__type_visibility__("default"))) basic_string {
-    _CharT localStorage[4];
+    bool isLong;
+    union {
+      _CharT localStorage[4];
+      _CharT *externalStorage;
+
+      void assignExternal(_CharT *newExternal) {
+        externalStorage = newExternal;
+      }
+    } storage;
 
     typedef allocator_traits<_Alloc> __alloc_traits;
 
   public:
+    basic_string();
+
     void push_back(int c) {
       // Fake error trigger.
-      // No warning is expected as we are suppressing warning comming
+      // No warning is expected as we are suppressing warning coming
       // out of std::basic_string.
       int z = 0;
       z = 5/z;
     }
 
+    _CharT *getBuffer() {
+      return isLong ? storage.externalStorage : storage.localStorage;
+    }
+
     basic_string &operator +=(int c) {
       // Fake deallocate stack-based storage.
       // No warning is expected as we are suppressing warnings within
-      // allocators being used by std::basic_string.
-      __alloc_traits::deallocate(&localStorage);
+      // std::basic_string.
+      __alloc_traits::deallocate(getBuffer());
+    }
+
+    basic_string &operator =(const basic_string &other) {
+      // Fake deallocate stack-based storage, then use the variable in the
+      // same union.
+      // No warning is expected as we are suppressing warnings within
+      // std::basic_string.
+      __alloc_traits::deallocate(getBuffer());
+      storage.assignExternal(new _CharT[4]);
     }
   };
 }
diff --git a/test/Analysis/Inputs/system-header-simulator-objc.h b/test/Analysis/Inputs/system-header-simulator-objc.h
index 3e1d955..8a5d3b6 100644
--- a/test/Analysis/Inputs/system-header-simulator-objc.h
+++ b/test/Analysis/Inputs/system-header-simulator-objc.h
@@ -66,8 +66,11 @@
 NSFastEnumerationState;
 @protocol NSFastEnumeration  - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
 @end           @class NSString, NSDictionary;
-@interface NSValue : NSObject <NSCopying, NSCoding>  - (void)getValue:(void *)value;
-@end  @interface NSNumber : NSValue  - (char)charValue;
+@interface NSValue : NSObject <NSCopying, NSCoding>
++ (NSValue *)valueWithPointer:(const void *)p;
+- (void)getValue:(void *)value;
+@end
+@interface NSNumber : NSValue  - (char)charValue;
 - (id)initWithInt:(int)value;
 @end   @class NSString;
 @interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>  - (NSUInteger)count;
diff --git a/test/Analysis/NSContainers.m b/test/Analysis/NSContainers.m
index a9e76fb..4b34926 100644
--- a/test/Analysis/NSContainers.m
+++ b/test/Analysis/NSContainers.m
@@ -1,4 +1,7 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.NonNilReturnValue,osx.cocoa.NilArg,osx.cocoa.Loops -verify -Wno-objc-root-class %s
+// RUN: %clang_cc1 -analyze -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);
+
 typedef unsigned long NSUInteger;
 typedef signed char BOOL;
 typedef struct _NSZone NSZone;
@@ -276,3 +279,16 @@
 	}
 }
 
+void testLiteralsNonNil() {
+  clang_analyzer_eval(!!@[]); // expected-warning{{TRUE}}
+  clang_analyzer_eval(!!@{}); // expected-warning{{TRUE}}
+}
+
+@interface NSMutableArray (MySafeAdd)
+- (void)addObject:(id)obj safe:(BOOL)safe;
+@end
+
+void testArrayCategory(NSMutableArray *arr) {
+  [arr addObject:0 safe:1]; // no-warning
+}
+
diff --git a/test/Analysis/NewDelete-checker-test.cpp b/test/Analysis/NewDelete-checker-test.cpp
index cc97251..855b05d 100644
--- a/test/Analysis/NewDelete-checker-test.cpp
+++ b/test/Analysis/NewDelete-checker-test.cpp
@@ -338,13 +338,13 @@
 public:
   int *x;
   DerefClass() {}
-  ~DerefClass() {*x = 1;} //expected-warning {{Use of memory after it is freed}}
+  ~DerefClass() {*x = 1;}
 };
 
 void testDoubleDeleteClassInstance() {
   DerefClass *foo = new DerefClass();
   delete foo;
-  delete foo; // FIXME: We should ideally report warning here instead of inside the destructor.
+  delete foo; // expected-warning {{Attempt to delete released memory}}
 }
 
 class EmptyClass{
@@ -356,5 +356,5 @@
 void testDoubleDeleteEmptyClass() {
   EmptyClass *foo = new EmptyClass();
   delete foo;
-  delete foo;  //expected-warning {{Attempt to free released memory}}
+  delete foo;  // expected-warning {{Attempt to delete released memory}}
 }
diff --git a/test/Analysis/NewDelete-variadic.cpp b/test/Analysis/NewDelete-variadic.cpp
index 53dba46..62a7d17 100644
--- a/test/Analysis/NewDelete-variadic.cpp
+++ b/test/Analysis/NewDelete-variadic.cpp
@@ -5,15 +5,19 @@
   typedef __typeof__(sizeof(int)) size_t;
 }
 
-void *operator new(std::size_t, ...);
-void *operator new[](std::size_t, ...);
+struct X {};
+
+void *operator new(std::size_t, X, ...);
+void *operator new[](std::size_t, X, ...);
 
 void testGlobalCustomVariadicNew() {
-  void *p1 = operator new(0); // no warn
+  X x;
 
-  void *p2 = operator new[](0); // no warn
+  void *p1 = operator new(0, x); // no warn
 
-  int *p3 = new int; // no warn
+  void *p2 = operator new[](0, x); // no warn
 
-  int *p4 = new int[0]; // no warn
+  int *p3 = new (x) int; // no warn
+
+  int *p4 = new (x) int[0]; // no warn
 }
diff --git a/test/Analysis/NewDeleteLeaks-PR18394.cpp b/test/Analysis/NewDeleteLeaks-PR18394.cpp
new file mode 100644
index 0000000..dfd9456
--- /dev/null
+++ b/test/Analysis/NewDeleteLeaks-PR18394.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -analyzer-config graph-trim-interval=1 -analyzer-max-loop 1 -analyze -analyzer-checker=core,alpha.cplusplus.NewDeleteLeaks -verify %s
+// expected-no-diagnostics
+
+class A {
+public:
+  void f() {};
+  ~A() {
+    for (int i=0; i<3; i++)
+      f();
+  }
+};
+
+void error() {
+  A *a = new A();
+  delete a;
+}
diff --git a/test/Analysis/NoReturn.m b/test/Analysis/NoReturn.m
index c74d54e..9b7011e 100644
--- a/test/Analysis/NoReturn.m
+++ b/test/Analysis/NoReturn.m
@@ -1,4 +1,4 @@
-// RUN: %clang --analyze -Xclang -analyzer-checker=alpha.core -Xclang -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s
 
 #include <stdarg.h>
 
diff --git a/test/Analysis/PR9741.cpp b/test/Analysis/PR9741.cpp
index 2807c44..542bc2d 100644
--- a/test/Analysis/PR9741.cpp
+++ b/test/Analysis/PR9741.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -cc1 -std=c++11 -Wuninitialized -verify %s
+// RUN: %clang_cc1 -std=c++11 -Wuninitialized -verify %s
 // expected-no-diagnostics
 
 void f() {
diff --git a/test/Analysis/analyzer-stats.c b/test/Analysis/analyzer-stats.c
index 63073b7..a0a50cb 100644
--- a/test/Analysis/analyzer-stats.c
+++ b/test/Analysis/analyzer-stats.c
@@ -2,7 +2,7 @@
 
 int foo();
 
-int test() { // expected-warning-re{{test -> Total CFGBlocks: [0-9]+ \| Unreachable CFGBlocks: 0 \| Exhausted Block: no \| Empty WorkList: yes}}
+int test() { // expected-warning-re{{test -> Total CFGBlocks: {{[0-9]+}} | Unreachable CFGBlocks: 0 | Exhausted Block: no | Empty WorkList: yes}}
   int a = 1;
   a = 34 / 12;
 
diff --git a/test/Analysis/auto-obj-dtors-cfg-output.cpp b/test/Analysis/auto-obj-dtors-cfg-output.cpp
index 0dbbfb5..0b4454f 100644
--- a/test/Analysis/auto-obj-dtors-cfg-output.cpp
+++ b/test/Analysis/auto-obj-dtors-cfg-output.cpp
@@ -228,7 +228,7 @@
 // CHECK-NEXT:   7: b
 // CHECK-NEXT:   8: [B4.7] (ImplicitCastExpr, NoOp, const class A)
 // CHECK-NEXT:   9: [B4.8].operator int
-// CHECK:       10: [B4.9]()
+// CHECK:       10: [B4.8]
 // CHECK:       11: [B4.10] (ImplicitCastExpr, UserDefinedConversion, int)
 // CHECK:       12: [B4.11] (ImplicitCastExpr, IntegralToBoolean, _Bool)
 // CHECK-NEXT:   T: if [B4.12]
@@ -307,7 +307,7 @@
 // CHECK-NEXT:   7: b
 // CHECK-NEXT:   8: [B8.7] (ImplicitCastExpr, NoOp, const class A)
 // CHECK-NEXT:   9: [B8.8].operator int
-// CHECK:       10: [B8.9]()
+// CHECK:       10: [B8.8]
 // CHECK:       11: [B8.10] (ImplicitCastExpr, UserDefinedConversion, int)
 // CHECK:       12: [B8.11] (ImplicitCastExpr, IntegralToBoolean, _Bool)
 // CHECK-NEXT:   T: if [B8.12]
@@ -354,7 +354,7 @@
 // CHECK-NEXT:   5: b
 // CHECK-NEXT:   6: [B4.5] (ImplicitCastExpr, NoOp, const class A)
 // CHECK-NEXT:   7: [B4.6].operator int
-// CHECK-NEXT:   8: [B4.7]()
+// CHECK-NEXT:   8: [B4.6]
 // CHECK-NEXT:   9: [B4.8] (ImplicitCastExpr, UserDefinedConversion, int)
 // CHECK:       10: [B4.9] (ImplicitCastExpr, IntegralToBoolean, _Bool)
 // CHECK-NEXT:   T: while [B4.10]
@@ -440,7 +440,7 @@
 // CHECK-NEXT:   5: b
 // CHECK-NEXT:   6: [B10.5] (ImplicitCastExpr, NoOp, const class A)
 // CHECK-NEXT:   7: [B10.6].operator int
-// CHECK-NEXT:   8: [B10.7]()
+// CHECK-NEXT:   8: [B10.6]
 // CHECK-NEXT:   9: [B10.8] (ImplicitCastExpr, UserDefinedConversion, int)
 // CHECK:       10: [B10.9] (ImplicitCastExpr, IntegralToBoolean, _Bool)
 // CHECK-NEXT:   T: while [B10.10]
@@ -586,7 +586,7 @@
 // CHECK-NEXT:   7: b
 // CHECK-NEXT:   8: [B2.7] (ImplicitCastExpr, NoOp, const class A)
 // CHECK-NEXT:   9: [B2.8].operator int
-// CHECK:       10: [B2.9]()
+// CHECK:       10: [B2.8]
 // CHECK:       11: [B2.10] (ImplicitCastExpr, UserDefinedConversion, int)
 // CHECK-NEXT:   T: switch [B2.11]
 // CHECK-NEXT:   Preds (1): B4
@@ -624,7 +624,7 @@
 // CHECK-NEXT:   7: b
 // CHECK-NEXT:   8: [B2.7] (ImplicitCastExpr, NoOp, const class A)
 // CHECK-NEXT:   9: [B2.8].operator int
-// CHECK:       10: [B2.9]()
+// CHECK:       10: [B2.8]
 // CHECK:       11: [B2.10] (ImplicitCastExpr, UserDefinedConversion, int)
 // CHECK-NEXT:   T: switch [B2.11]
 // CHECK-NEXT:   Preds (1): B9
@@ -710,7 +710,7 @@
 // CHECK-NEXT:   5: b
 // CHECK-NEXT:   6: [B4.5] (ImplicitCastExpr, NoOp, const class A)
 // CHECK-NEXT:   7: [B4.6].operator int
-// CHECK-NEXT:   8: [B4.7]()
+// CHECK-NEXT:   8: [B4.6]
 // CHECK-NEXT:   9: [B4.8] (ImplicitCastExpr, UserDefinedConversion, int)
 // CHECK:       10: [B4.9] (ImplicitCastExpr, IntegralToBoolean, _Bool)
 // CHECK-NEXT:   T: for (...; [B4.10]; )
@@ -796,7 +796,7 @@
 // CHECK-NEXT:   5: c
 // CHECK-NEXT:   6: [B10.5] (ImplicitCastExpr, NoOp, const class A)
 // CHECK-NEXT:   7: [B10.6].operator int
-// CHECK-NEXT:   8: [B10.7]()
+// CHECK-NEXT:   8: [B10.6]
 // CHECK-NEXT:   9: [B10.8] (ImplicitCastExpr, UserDefinedConversion, int)
 // CHECK:       10: [B10.9] (ImplicitCastExpr, IntegralToBoolean, _Bool)
 // CHECK-NEXT:   T: for (...; [B10.10]; )
diff --git a/test/Analysis/bitwise-ops.c b/test/Analysis/bitwise-ops.c
index bf282ec..01daf42 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 -verify %s
+// RUN: %clang_cc1 -analyze -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)
@@ -11,4 +11,22 @@
   // False positives due to SValBuilder giving up on certain kinds of exprs.
   CHECK(1 - x); // expected-warning{{UNKNOWN}}
   CHECK(x & y); // expected-warning{{UNKNOWN}}
+}
+
+int testConstantShifts_PR18073(int which) {
+  // FIXME: We should have a checker that actually specifically checks bitwise
+  // shifts against the width of the LHS's /static/ type, rather than just
+  // having BasicValueFactory return "undefined" when dealing with two constant
+  // operands.
+  switch (which) {
+  case 1:
+    return 0ULL << 63; // no-warning
+  case 2:
+    return 0ULL << 64; // expected-warning{{The result of the '<<' expression is undefined}}
+  case 3:
+    return 0ULL << 65; // expected-warning{{The result of the '<<' expression is undefined}}
+
+  default:
+    return 0;
+  }
 }
\ No newline at end of file
diff --git a/test/Analysis/blocks.m b/test/Analysis/blocks.m
index 6d3495c..62d5360 100644
--- a/test/Analysis/blocks.m
+++ b/test/Analysis/blocks.m
@@ -146,3 +146,19 @@
     return 42;
   }();
 }
+
+// This test used to cause infinite loop in the region invalidation.
+void blockCapturesItselfInTheLoop(int x, int m) {
+  void (^assignData)(int) = ^(int x){
+    x++;
+  };
+  while (m < 0) {
+    void (^loop)(int);
+    loop = ^(int x) {
+      assignData(x);
+    };
+    assignData = loop;
+    m++;
+  }
+  assignData(x);
+}
diff --git a/test/Analysis/call-invalidation.cpp b/test/Analysis/call-invalidation.cpp
index 54281cc..7297d1e 100644
--- a/test/Analysis/call-invalidation.cpp
+++ b/test/Analysis/call-invalidation.cpp
@@ -89,3 +89,32 @@
   clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}
 }
 
+
+void usePointerPure(int * const *) __attribute__((pure));
+void usePointerConst(int * const *) __attribute__((const));
+
+void testPureConst() {
+  extern int global;
+  int x;
+  int *p;
+
+  p = &x;
+  x = 42;
+  global = -5;
+  clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
+  clang_analyzer_eval(global == -5); // expected-warning{{TRUE}}
+
+  usePointerPure(&p);
+  clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
+  clang_analyzer_eval(global == -5); // expected-warning{{TRUE}}
+
+  usePointerConst(&p);
+  clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
+  clang_analyzer_eval(global == -5); // expected-warning{{TRUE}}
+
+  usePointer(&p);
+  clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(global == -5); // expected-warning{{UNKNOWN}}
+}
+
+
diff --git a/test/Analysis/casts.c b/test/Analysis/casts.c
index 3e2f807..42c05be 100644
--- a/test/Analysis/casts.c
+++ b/test/Analysis/casts.c
@@ -110,7 +110,8 @@
     clang_analyzer_eval(symbolicPointer); // expected-warning{{TRUE}}
 
   int localInt;
-  clang_analyzer_eval(&localInt); // expected-warning{{TRUE}}
+  int* ptr = &localInt;
+  clang_analyzer_eval(ptr); // expected-warning{{TRUE}}
   clang_analyzer_eval(&castsToBool); // expected-warning{{TRUE}}
   clang_analyzer_eval("abc"); // expected-warning{{TRUE}}
 
diff --git a/test/Analysis/casts.cpp b/test/Analysis/casts.cpp
index 3395391..53e1cd0 100644
--- a/test/Analysis/casts.cpp
+++ b/test/Analysis/casts.cpp
@@ -1,5 +1,4 @@
 // RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -verify %s
-// expected-no-diagnostics
 
 bool PR14634(int x) {
   double y = (double)x;
@@ -10,3 +9,15 @@
   double y = (double)x;
   return y;
 }
+
+void intAsBoolAsSwitchCondition(int c) {
+  switch ((bool)c) { // expected-warning {{switch condition has boolean value}}
+  case 0:
+    break;
+  }
+
+  switch ((int)(bool)c) { // no-warning
+    case 0:
+      break;
+  }
+}
diff --git a/test/Analysis/cfg.cpp b/test/Analysis/cfg.cpp
index 660d1f2..65060b1 100644
--- a/test/Analysis/cfg.cpp
+++ b/test/Analysis/cfg.cpp
@@ -1,5 +1,7 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -std=c++11 %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -std=c++11 %s > %t 2>&1
+// RUN: FileCheck --input-file=%t %s
 
+// CHECK-LABEL: void checkWrap(int i)
 // CHECK: ENTRY
 // CHECK-NEXT: Succs (1): B1
 // CHECK: [B1]
@@ -35,6 +37,7 @@
   }
 }
 
+// CHECK-LABEL: void checkDeclStmts()
 // CHECK: ENTRY
 // CHECK-NEXT: Succs (1): B1
 // CHECK: [B1]
@@ -48,7 +51,7 @@
 // CHECK-NEXT: CXXConstructExpr
 // CHECK-NEXT:   9: struct standalone myStandalone;
 // CHECK-NEXT: CXXConstructExpr
-// CHECK-NEXT:  11: struct <anonymous struct at {{.*}}> myAnon;
+// CHECK-NEXT:  11: struct (anonymous struct at {{.*}}) myAnon;
 // CHECK-NEXT: CXXConstructExpr
 // CHECK-NEXT:  13: struct named myNamed;
 // CHECK-NEXT:   Preds (1): B2
@@ -67,6 +70,7 @@
   static_assert(1, "abc");
 }
 
+// CHECK-LABEL: void F(EmptyE e)
 // CHECK: ENTRY
 // CHECK-NEXT: Succs (1): B1
 // CHECK: [B1]
@@ -83,6 +87,7 @@
   switch (e) {}
 }
 
+// CHECK-LABEL: void testBuiltinSize()
 // CHECK: ENTRY
 // CHECK-NEXT: Succs (1): B1
 // CHECK: [B1]
@@ -106,16 +111,18 @@
   ~A() {}
 };
 
+// CHECK-LABEL: void test_deletedtor()
 // CHECK: [B2 (ENTRY)]
 // CHECK-NEXT:   Succs (1): B1
 // CHECK: [B1]
-// CHECK-NEXT:   1:  (CXXConstructExpr, class A)
-// CHECK-NEXT:   2: new A([B1.1])
-// CHECK-NEXT:   3: A *a = new A();
-// CHECK-NEXT:   4: a
-// CHECK-NEXT:   5: [B1.4] (ImplicitCastExpr, LValueToRValue, class A *)
-// CHECK-NEXT:   6: [B1.5]->~A() (Implicit destructor)
-// CHECK-NEXT:   7: delete [B1.5]
+// CHECK-NEXT:   1:  CFGNewAllocator(A *)
+// CHECK-NEXT:   2:  (CXXConstructExpr, class A)
+// CHECK-NEXT:   3: new A([B1.2])
+// CHECK-NEXT:   4: A *a = new A();
+// CHECK-NEXT:   5: a
+// CHECK-NEXT:   6: [B1.5] (ImplicitCastExpr, LValueToRValue, class A *)
+// CHECK-NEXT:   7: [B1.6]->~A() (Implicit destructor)
+// CHECK-NEXT:   8: delete [B1.6]
 // CHECK-NEXT:   Preds (1): B2
 // CHECK-NEXT:   Succs (1): B0
 // CHECK: [B0 (EXIT)]
@@ -125,17 +132,19 @@
   delete a;
 }
 
+// CHECK-LABEL: void test_deleteArraydtor()
 // CHECK: [B2 (ENTRY)]
 // CHECK-NEXT:   Succs (1): B1
 // CHECK: [B1]
 // CHECK-NEXT:   1: 5
-// CHECK-NEXT:   2:  (CXXConstructExpr, class A)
-// CHECK-NEXT:   3: new A {{\[\[}}B1.1]]
-// CHECK-NEXT:   4: A *a = new A [5];
-// CHECK-NEXT:   5: a
-// CHECK-NEXT:   6: [B1.5] (ImplicitCastExpr, LValueToRValue, class A *)
-// CHECK-NEXT:   7: [B1.6]->~A() (Implicit destructor)
-// CHECK-NEXT:   8: delete [] [B1.6]
+// CHECK-NEXT:   2: CFGNewAllocator(A *)
+// CHECK-NEXT:   3:  (CXXConstructExpr, class A)
+// CHECK-NEXT:   4: new A {{\[\[}}B1.1]]
+// CHECK-NEXT:   5: A *a = new A [5];
+// CHECK-NEXT:   6: a
+// CHECK-NEXT:   7: [B1.6] (ImplicitCastExpr, LValueToRValue, class A *)
+// CHECK-NEXT:   8: [B1.7]->~A() (Implicit destructor)
+// CHECK-NEXT:   9: delete [] [B1.7]
 // CHECK-NEXT:   Preds (1): B2
 // CHECK-NEXT:   Succs (1): B0
 // CHECK: [B0 (EXIT)]
@@ -157,7 +166,7 @@
     ~B() __attribute__((noreturn));
   };
 
-// CHECK: ENTRY
+// CHECK-LABEL: int test1(int *x)
 // CHECK: 1: 1
 // CHECK-NEXT: 2: return
 // CHECK-NEXT: ~B() (Implicit destructor)
@@ -169,7 +178,7 @@
       return 1;
   }
 
-// CHECK: ENTRY
+// CHECK-LABEL: int test2(int *x)
 // CHECK: 1: 1
 // CHECK-NEXT: 2: return
 // CHECK-NEXT: destructor
@@ -181,3 +190,214 @@
       return 1;
   }
 }
+
+// Test CFG support for "extending" an enum.
+// CHECK-LABEL: int test_enum_with_extension(enum MyEnum value)
+// CHECK:  [B7 (ENTRY)]
+// CHECK-NEXT:    Succs (1): B2
+// CHECK:  [B1]
+// CHECK-NEXT:    1: x
+// CHECK-NEXT:    2: [B1.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:    3: return [B1.2];
+// CHECK-NEXT:    Preds (5): B3 B4 B5 B6 B2(Unreachable)
+// CHECK-NEXT:    Succs (1): B0
+// CHECK:  [B2]
+// CHECK-NEXT:    1: 0
+// CHECK-NEXT:    2: int x = 0;
+// CHECK-NEXT:    3: value
+// CHECK-NEXT:    4: [B2.3] (ImplicitCastExpr, LValueToRValue, enum MyEnum)
+// CHECK-NEXT:    5: [B2.4] (ImplicitCastExpr, IntegralCast, int)
+// CHECK-NEXT:    T: switch [B2.5]
+// CHECK-NEXT:    Preds (1): B7
+// CHECK-NEXT:    Succs (5): B3 B4 B5 B6 B1(Unreachable)
+// CHECK:  [B3]
+// CHECK-NEXT:   case D:
+// CHECK-NEXT:    1: 4
+// CHECK-NEXT:    2: x
+// CHECK-NEXT:    3: [B3.2] = [B3.1]
+// CHECK-NEXT:    T: break;
+// CHECK-NEXT:    Preds (1): B2
+// CHECK-NEXT:    Succs (1): B1
+// CHECK:  [B4]
+// CHECK-NEXT:   case C:
+// CHECK-NEXT:    1: 3
+// CHECK-NEXT:    2: x
+// CHECK-NEXT:    3: [B4.2] = [B4.1]
+// CHECK-NEXT:    T: break;
+// CHECK-NEXT:    Preds (1): B2
+// CHECK-NEXT:    Succs (1): B1
+// CHECK:  [B5]
+// CHECK-NEXT:   case B:
+// CHECK-NEXT:    1: 2
+// CHECK-NEXT:    2: x
+// CHECK-NEXT:    3: [B5.2] = [B5.1]
+// CHECK-NEXT:    T: break;
+// CHECK-NEXT:    Preds (1): B2
+// CHECK-NEXT:    Succs (1): B1
+// CHECK:  [B6]
+// CHECK-NEXT:   case A:
+// CHECK-NEXT:    1: 1
+// CHECK-NEXT:    2: x
+// CHECK-NEXT:    3: [B6.2] = [B6.1]
+// CHECK-NEXT:    T: break;
+// CHECK-NEXT:    Preds (1): B2
+// CHECK-NEXT:    Succs (1): B1
+// CHECK:  [B0 (EXIT)]
+// CHECK-NEXT:    Preds (1): B1
+enum MyEnum { A, B, C };
+static const enum MyEnum D = (enum MyEnum) 32;
+
+int test_enum_with_extension(enum MyEnum value) {
+  int x = 0;
+  switch (value) {
+    case A: x = 1; break;
+    case B: x = 2; break;
+    case C: x = 3; break;
+    case D: x = 4; break;
+  }
+  return x;
+}
+
+// CHECK-LABEL: int test_enum_with_extension_default(enum MyEnum value)
+// CHECK:  [B7 (ENTRY)]
+// CHECK-NEXT:    Succs (1): B2
+// CHECK:  [B1]
+// CHECK-NEXT:    1: x
+// CHECK-NEXT:    2: [B1.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:    3: return [B1.2];
+// CHECK-NEXT:    Preds (4): B3 B4 B5 B6
+// CHECK-NEXT:    Succs (1): B0
+// CHECK:  [B2]
+// CHECK-NEXT:    1: 0
+// CHECK-NEXT:    2: int x = 0;
+// CHECK-NEXT:    3: value
+// CHECK-NEXT:    4: [B2.3] (ImplicitCastExpr, LValueToRValue, enum MyEnum)
+// CHECK-NEXT:    5: [B2.4] (ImplicitCastExpr, IntegralCast, int)
+// CHECK-NEXT:    T: switch [B2.5]
+// CHECK-NEXT:    Preds (1): B7
+// CHECK-NEXT:    Succs (4): B4 B5 B6 B3(Unreachable)
+// CHECK:  [B3]
+// CHECK-NEXT:   default:
+// CHECK-NEXT:    1: 4
+// CHECK-NEXT:    2: x
+// CHECK-NEXT:    3: [B3.2] = [B3.1]
+// CHECK-NEXT:    T: break;
+// CHECK-NEXT:    Preds (1): B2(Unreachable)
+// CHECK-NEXT:    Succs (1): B1
+// CHECK:  [B4]
+// CHECK-NEXT:   case C:
+// CHECK-NEXT:    1: 3
+// CHECK-NEXT:    2: x
+// CHECK-NEXT:    3: [B4.2] = [B4.1]
+// CHECK-NEXT:    T: break;
+// CHECK-NEXT:    Preds (1): B2
+// CHECK-NEXT:    Succs (1): B1
+// CHECK:  [B5]
+// CHECK-NEXT:   case B:
+// CHECK-NEXT:    1: 2
+// CHECK-NEXT:    2: x
+// CHECK-NEXT:    3: [B5.2] = [B5.1]
+// CHECK-NEXT:    T: break;
+// CHECK-NEXT:    Preds (1): B2
+// CHECK-NEXT:    Succs (1): B1
+// CHECK:  [B6]
+// CHECK-NEXT:   case A:
+// CHECK-NEXT:    1: 1
+// CHECK-NEXT:    2: x
+// CHECK-NEXT:    3: [B6.2] = [B6.1]
+// CHECK-NEXT:    T: break;
+// CHECK-NEXT:    Preds (1): B2
+// CHECK-NEXT:    Succs (1): B1
+// CHECK:  [B0 (EXIT)]
+// CHECK-NEXT:    Preds (1): B1
+int test_enum_with_extension_default(enum MyEnum value) {
+  int x = 0;
+  switch (value) {
+    case A: x = 1; break;
+    case B: x = 2; break;
+    case C: x = 3; break;
+    default: x = 4; break;
+  }
+  return x;
+}
+
+
+// CHECK-LABEL: void test_placement_new()
+// CHECK:  [B2 (ENTRY)]
+// CHECK-NEXT:  Succs (1): B1
+// CHECK:  [B1]
+// CHECK-NEXT:  1: int buffer[16];
+// CHECK-NEXT:  2: buffer
+// CHECK-NEXT:  3: [B1.2] (ImplicitCastExpr, ArrayToPointerDecay, int *)
+// CHECK-NEXT:  4: [B1.3] (ImplicitCastExpr, BitCast, void *)
+// CHECK-NEXT:  5: CFGNewAllocator(MyClass *)
+// CHECK-NEXT:  6:  (CXXConstructExpr, class MyClass)
+// CHECK-NEXT:  7: new ([B1.4]) MyClass([B1.6])
+// CHECK-NEXT:  8: MyClass *obj = new (buffer) MyClass();
+// CHECK-NEXT:  Preds (1): B2
+// CHECK-NEXT:  Succs (1): B0
+// CHECK: [B0 (EXIT)]
+// CHECK-NEXT:  Preds (1): B1
+
+extern void* operator new (unsigned long sz, void* v);
+extern void* operator new[] (unsigned long sz, void* ptr);
+
+class MyClass {
+public:
+  MyClass() {}
+  ~MyClass() {}
+};
+
+void test_placement_new() {
+  int buffer[16];
+  MyClass* obj = new (buffer) MyClass();
+}
+
+// CHECK-LABEL: void test_placement_new_array()
+// CHECK:  [B2 (ENTRY)]
+// CHECK-NEXT:  Succs (1): B1
+// CHECK: [B1]
+// CHECK-NEXT:  1: int buffer[16];
+// CHECK-NEXT:  2: buffer
+// CHECK-NEXT:  3: [B1.2] (ImplicitCastExpr, ArrayToPointerDecay, int *)
+// CHECK-NEXT:  4: [B1.3] (ImplicitCastExpr, BitCast, void *)
+// CHECK-NEXT:  5: 5
+// CHECK-NEXT:  6: CFGNewAllocator(MyClass *)
+// CHECK-NEXT:  7:  (CXXConstructExpr, class MyClass)
+// CHECK-NEXT:  8: new ([B1.4]) MyClass {{\[\[}}B1.5]]
+// CHECK-NEXT:  9: MyClass *obj = new (buffer) MyClass [5];
+// CHECK-NEXT:  Preds (1): B2
+// CHECK-NEXT:  Succs (1): B0
+// CHECK: [B0 (EXIT)]
+// CHECK-NEXT:  Preds (1): B1
+
+void test_placement_new_array() {
+  int buffer[16];
+  MyClass* obj = new (buffer) MyClass[5];
+}
+
+
+// CHECK-LABEL: int *PR18472()
+// CHECK: [B2 (ENTRY)]
+// CHECK-NEXT:   Succs (1): B1
+// CHECK: [B1]
+// CHECK-NEXT:   1: 0
+// CHECK-NEXT:   2: [B1.1] (ImplicitCastExpr, NullToPointer, PR18472_t)
+// CHECK-NEXT:   3: (PR18472_t)[B1.2] (CStyleCastExpr, NoOp, PR18472_t)
+// CHECK-NEXT:   4: CFGNewAllocator(int *)
+// CHECK-NEXT:   5: new (([B1.3])) int
+// CHECK-NEXT:   6: return [B1.5];
+// CHECK-NEXT:   Preds (1): B2
+// CHECK-NEXT:   Succs (1): B0
+// CHECK: [B0 (EXIT)]
+// CHECK-NEXT:   Preds (1): B1
+
+extern "C" typedef int *PR18472_t;
+void *operator new (unsigned long, PR18472_t);
+template <class T> T *PR18472() {
+  return new (((PR18472_t) 0)) T;
+}
+void PR18472_helper() {
+  PR18472<int>();
+}
+
diff --git a/test/Analysis/checker-plugins.c b/test/Analysis/checker-plugins.c
new file mode 100644
index 0000000..3882ba6
--- /dev/null
+++ b/test/Analysis/checker-plugins.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -load %llvmshlibdir/SampleAnalyzerPlugin%pluginext -analyze -analyzer-checker='example.MainCallChecker' -verify %s
+// REQUIRES: plugins, examples
+
+// Test that the MainCallChecker example analyzer plugin loads and runs.
+
+int main();
+
+void caller() {
+  main(); // expected-warning {{call to main}}
+}
diff --git a/test/Analysis/ctor.mm b/test/Analysis/ctor.mm
index 77c8790..e7c0c6c 100644
--- a/test/Analysis/ctor.mm
+++ b/test/Analysis/ctor.mm
@@ -674,3 +674,33 @@
     clang_analyzer_eval(list->usedInitializerList); // expected-warning{{UNKNOWN}}
   }
 }
+
+namespace PR19579 {
+  class C {};
+
+  void f() {
+    C();
+    int a;
+
+    extern void use(int);
+    use(a); // expected-warning{{uninitialized}}
+  }
+
+  void g() {
+    struct S {
+      C c;
+      int i;
+    };
+    
+    // This order triggers the initialization of the inner "a" after the
+    // constructor for "C" is run, which used to confuse the analyzer
+    // (is "C()" the initialization of "a"?).
+    struct S s = {
+      C(),
+      ({
+        int a, b = 0;
+        0;
+      })
+    };
+  }
+}
diff --git a/test/Analysis/dead-stores.c b/test/Analysis/dead-stores.c
index 067a050..da8e8bd 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,alpha.deadcode.IdempotentOperations -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
-// RUN: %clang_cc1 -Wunused-variable -analyze -analyzer-checker=core,deadcode.DeadStores,alpha.deadcode.IdempotentOperations -analyzer-store=region -analyzer-constraints=range -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
+// 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 -analyzer-constraints=range -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'}}
@@ -11,7 +11,7 @@
  char *c = (char*)b; // no-warning
  char *d = b+1; // expected-warning {{never read}} expected-warning{{unused variable 'd'}}
  printf("%s", c); // expected-warning{{implicitly declaring library function 'printf' with type 'int (const char *, ...)'}} \
- // expected-note{{please include the header <stdio.h> or explicitly provide a declaration for 'printf'}}
+ // expected-note{{include the header <stdio.h> or explicitly provide a declaration for 'printf'}}
 }
 
 int f();
@@ -152,7 +152,7 @@
 // to see a real bug in this scenario.
 int f16(int x) {
   x = x * 2;
-  x = sizeof(int [x = (x || x + 1) * 2]) // expected-warning{{The left operand to '+' is always 0}} expected-warning{{The left operand to '*' is always 1}}
+  x = sizeof(int [x = (x || x + 1) * 2])
       ? 5 : 8;
   return x;
 }
@@ -480,11 +480,11 @@
 // placed within the increment code of for loops.
 void rdar8014335() {
   for (int i = 0 ; i != 10 ; ({ break; })) {
-    for ( ; ; ({ ++i; break; })) ;
+    for ( ; ; ({ ++i; break; })) ; // expected-warning {{'break' is bound to current loop, GCC binds it to the enclosing loop}}
     // Note that the next value stored to 'i' is never executed
     // because the next statement to be executed is the 'break'
     // in the increment code of the first loop.
-    i = i * 3; // expected-warning{{Value stored to 'i' is never read}} expected-warning{{The left operand to '*' is always 1}}
+    i = i * 3; // expected-warning{{Value stored to 'i' is never read}}
   }
 }
 
diff --git a/test/Analysis/dead-stores.m b/test/Analysis/dead-stores.m
index 5a807ed..13b28dc 100644
--- a/test/Analysis/dead-stores.m
+++ b/test/Analysis/dead-stores.m
@@ -109,3 +109,11 @@
     return wp;
 }
 @end
+
+id test_objc_precise_lifetime_foo();
+void test_objc_precise_lifetime() {
+  __attribute__((objc_precise_lifetime)) id dead = test_objc_precise_lifetime_foo(); // no-warning
+  dead = 0;
+  dead = test_objc_precise_lifetime_foo(); // no-warning
+  dead = 0;
+}
diff --git a/test/Analysis/default-analyze.m b/test/Analysis/default-analyze.m
index 82656b2..5fbaa2f 100644
--- a/test/Analysis/default-analyze.m
+++ b/test/Analysis/default-analyze.m
@@ -11,7 +11,7 @@
     title = @"bar";
     break;
   default:
-    title = "@baz";
+    title = @"baz";
     break;
   }
   return title;
diff --git a/test/Analysis/diagnostics/undef-value-param.m b/test/Analysis/diagnostics/undef-value-param.m
index e977acb..b0ce56c 100644
--- a/test/Analysis/diagnostics/undef-value-param.m
+++ b/test/Analysis/diagnostics/undef-value-param.m
@@ -542,7 +542,7 @@
 // CHECK-NEXT:    </array>
 // CHECK-NEXT:    <key>description</key><string>Null pointer argument in call to CFRelease</string>
 // CHECK-NEXT:    <key>category</key><string>API Misuse (Apple)</string>
-// CHECK-NEXT:    <key>type</key><string>null passed to CFRetain/CFRelease/CFMakeCollectable</string>
+// CHECK-NEXT:    <key>type</key><string>null passed to CF memory management function</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>Objective-C method</string>
 // CHECK-NEXT:   <key>issue_context</key><string>test</string>
 // CHECK-NEXT:   <key>issue_hash</key><string>5</string>
diff --git a/test/Analysis/dtor-cxx11.cpp b/test/Analysis/dtor-cxx11.cpp
new file mode 100644
index 0000000..7d2e87e
--- /dev/null
+++ b/test/Analysis/dtor-cxx11.cpp
@@ -0,0 +1,15 @@
+// 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
+// expected-no-diagnostics
+
+#include "Inputs/system-header-simulator-cxx.h"
+
+namespace Cxx11BraceInit {
+  struct Foo {
+    ~Foo() {}
+  };
+
+  void testInitializerList() {
+    for (Foo foo : {Foo(), Foo()}) {}
+  }
+}
+
diff --git a/test/Analysis/dtor.cpp b/test/Analysis/dtor.cpp
index 11ce0d5..8d6e30a 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 -analyzer-config c++-inlining=destructors -Wno-null-dereference -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=destructors,cfg-temporary-dtors=true -Wno-null-dereference -verify %s
 
 void clang_analyzer_eval(bool);
 void clang_analyzer_checkInlined(bool);
@@ -374,6 +374,70 @@
     clang_analyzer_eval(SaveOnDestruct::lastOutput == 42); // expected-warning{{TRUE}}
   }
 
+  struct NRCheck {
+    bool bool_;
+    NRCheck():bool_(true) {}
+    ~NRCheck() __attribute__((noreturn));
+    operator bool() const { return bool_; }
+  };
+
+  struct CheckAutoDestructor {
+    bool bool_;
+    CheckAutoDestructor():bool_(true) {}
+    operator bool() const { return bool_; }
+  };
+
+  struct CheckCustomDestructor {
+    bool bool_;
+    CheckCustomDestructor():bool_(true) {}
+    ~CheckCustomDestructor();
+    operator bool() const { return bool_; }
+  };
+
+  bool testUnnamedNR() {
+    if (NRCheck())
+      return true;
+    return false;
+  }
+
+  bool testNamedNR() {
+    if (NRCheck c = NRCheck())
+      return true;
+    return false;
+  }
+
+  bool testUnnamedAutoDestructor() {
+    if (CheckAutoDestructor())
+      return true;
+    return false;
+  }
+
+  bool testNamedAutoDestructor() {
+    if (CheckAutoDestructor c = CheckAutoDestructor())
+      return true;
+    return false;
+  }
+
+  bool testUnnamedCustomDestructor() {
+    if (CheckCustomDestructor())
+      return true;
+    return false;
+  }
+
+  // This case used to cause an unexpected "Undefined or garbage value returned
+  // to caller" warning
+  bool testNamedCustomDestructor() {
+    if (CheckCustomDestructor c = CheckCustomDestructor())
+      return true;
+    return false;
+  }
+
+  bool testMultipleTemporariesCustomDestructor() {
+    if (CheckCustomDestructor c = (CheckCustomDestructor(), CheckCustomDestructor()))
+      return true;
+    return false;
+  }
+
   class VirtualDtorBase {
   public:
     int value;
@@ -416,6 +480,11 @@
     f(&x);
     *x = 47; // no warning
   }
+
+  void g2(int *x) {
+    if (! x) NR();
+    *x = 47; // no warning
+  }
 }
 
 namespace PseudoDtor {
diff --git a/test/Analysis/dynamic-cast.cpp b/test/Analysis/dynamic-cast.cpp
index 6bb571d..b48ee5b 100644
--- a/test/Analysis/dynamic-cast.cpp
+++ b/test/Analysis/dynamic-cast.cpp
@@ -169,7 +169,7 @@
   return *res; // no warning
 }
 
-int testReferenceSuccesfulCast() {
+int testReferenceSuccessfulCast() {
   B rb;
   B &b = dynamic_cast<B&>(rb);
   int *x = 0;
diff --git a/test/Analysis/exercise-ps.c b/test/Analysis/exercise-ps.c
index 675dd4e..03b6874 100644
--- a/test/Analysis/exercise-ps.c
+++ b/test/Analysis/exercise-ps.c
@@ -19,5 +19,5 @@
   F12_typedef* x;
   x = f2_helper();
   memcpy((&x[1]), (buf), 1); // expected-warning{{implicitly declaring library function 'memcpy' with type 'void *(void *, const void *}} \
-  // expected-note{{please include the header <string.h> or explicitly provide a declaration for 'memcpy'}}
+  // expected-note{{include the header <string.h> or explicitly provide a declaration for 'memcpy'}}
 }
diff --git a/test/Analysis/idempotent-operations-limited-loops.c b/test/Analysis/idempotent-operations-limited-loops.c
deleted file mode 100644
index c8c51cf..0000000
--- a/test/Analysis/idempotent-operations-limited-loops.c
+++ /dev/null
@@ -1,21 +0,0 @@
-// RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-constraints=range -fblocks -analyzer-opt-analyze-nested-blocks -analyzer-checker=core,alpha.deadcode.IdempotentOperations -analyzer-max-loop 3 -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-constraints=range -fblocks -analyzer-opt-analyze-nested-blocks -analyzer-checker=core,alpha.deadcode.IdempotentOperations -analyzer-max-loop 4 -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-constraints=range -fblocks -analyzer-opt-analyze-nested-blocks -analyzer-checker=core,alpha.deadcode.IdempotentOperations %s -verify
-
-void always_warning() { int *p = 0; *p = 0xDEADBEEF; } // expected-warning{{Dereference of null pointer (loaded from variable 'p')}}
-
-// This test case previously caused a bogus idempotent operation warning
-// due to us not properly culling warnings due to incomplete analysis of loops.
-int pr8403()
-{
-        int i;
-        for(i=0; i<10; i++)
-        {
-                int j;
-                for(j=0; j+1<i; j++)
-                {
-                }
-        }
-        return 0;
-}
-
diff --git a/test/Analysis/idempotent-operations.c b/test/Analysis/idempotent-operations.c
deleted file mode 100644
index 04c9bc1..0000000
--- a/test/Analysis/idempotent-operations.c
+++ /dev/null
@@ -1,244 +0,0 @@
-// RUN: %clang_cc1 -Wno-int-to-pointer-cast -analyze -analyzer-store=region -analyzer-constraints=range -fblocks -analyzer-opt-analyze-nested-blocks -analyzer-checker=alpha.deadcode.IdempotentOperations -verify %s
-
-// Basic tests
-
-extern void test(int i);
-extern void test_f(float f);
-
-unsigned basic() {
-  int x = 10, zero = 0, one = 1;
-
-  // x op x
-  x = x;        // expected-warning {{Assigned value is always the same as the existing value}}
-  test(x - x);  // expected-warning {{Both operands to '-' always have the same value}}
-  x -= x;       // expected-warning {{Both operands to '-=' always have the same value}}
-  x = 10;       // no-warning
-  test(x / x);  // expected-warning {{Both operands to '/' always have the same value}}
-  x /= x;       // expected-warning {{Both operands to '/=' always have the same value}}
-  x = 10;       // no-warning
-  test(x & x);  // expected-warning {{Both operands to '&' always have the same value}}
-  x &= x;       // expected-warning {{Both operands to '&=' always have the same value}}
-  test(x | x);  // expected-warning {{Both operands to '|' always have the same value}}
-  x |= x;       // expected-warning {{Both operands to '|=' always have the same value}}
-
-  // x op 1
-  test(x * one);  // expected-warning {{The right operand to '*' is always 1}}
-  x *= one;       // expected-warning {{The right operand to '*=' is always 1}}
-  test(x / one);  // expected-warning {{The right operand to '/' is always 1}}
-  x /= one;       // expected-warning {{The right operand to '/=' is always 1}}
-
-  // 1 op x
-  test(one * x);   // expected-warning {{The left operand to '*' is always 1}}
-
-  // x op 0
-  test(x + zero);  // expected-warning {{The right operand to '+' is always 0}}
-  test(x - zero);  // expected-warning {{The right operand to '-' is always 0}}
-  test(x * zero);  // expected-warning {{The right operand to '*' is always 0}}
-  test(x & zero);  // expected-warning {{The right operand to '&' is always 0}}
-  test(x | zero);  // expected-warning {{The right operand to '|' is always 0}}
-  test(x ^ zero);  // expected-warning {{The right operand to '^' is always 0}}
-  test(x << zero); // expected-warning {{The right operand to '<<' is always 0}}
-  test(x >> zero); // expected-warning {{The right operand to '>>' is always 0}}
-
-  // 0 op x
-  test(zero + x);  // expected-warning {{The left operand to '+' is always 0}}
-  test(zero - x);  // expected-warning {{The left operand to '-' is always 0}}
-  test(zero / x);  // expected-warning {{The left operand to '/' is always 0}}
-  test(zero * x);  // expected-warning {{The left operand to '*' is always 0}}
-  test(zero & x);  // expected-warning {{The left operand to '&' is always 0}}
-  test(zero | x);  // expected-warning {{The left operand to '|' is always 0}}
-  test(zero ^ x);  // expected-warning {{The left operand to '^' is always 0}}
-  test(zero << x); // expected-warning {{The left operand to '<<' is always 0}}
-  test(zero >> x); // expected-warning {{The left operand to '>>' is always 0}}
-
-  // Overwrite the values so these aren't marked as Pseudoconstants
-  x = 1;
-  zero = 2;
-  one = 3;
-
-  return x + zero + one;
-}
-
-void floats(float x) {
-  test_f(x * 1.0);  // no-warning
-  test_f(x * 1.0F); // no-warning
-}
-
-// Ensure that we don't report false poitives in complex loops
-void bailout() {
-  int unused = 0, result = 4;
-  result = result; // expected-warning {{Assigned value is always the same as the existing value}}
-
-  for (unsigned bg = 0; bg < 1024; bg ++) {
-    result = bg * result; // no-warning
-
-    for (int i = 0; i < 256; i++) {
-      unused *= i; // no-warning
-    }
-  }
-}
-
-// Relaxed liveness - check that we don't kill liveness at assignments
-typedef unsigned uintptr_t;
-void kill_at_assign() {
-  short array[2];
-  uintptr_t x = (uintptr_t) array;
-  short *p = (short *) x;
-
-  // The following branch should be infeasible.
-  if (!(p = &array[0])) { // expected-warning{{Assigned value is always the same as the existing value}}
-    p = 0;
-    *p = 1; // no-warning
-  }
-}
-
-// False positive tests
-
-unsigned false1() {
-  int a = 10;
-  return a * (5 - 2 - 3); // no-warning
-}
-
-enum testenum { enum1 = 0, enum2 };
-unsigned false2() {
-  int a = 1234;
-  return enum1 + a; // no-warning
-}
-
-// Self assignments of unused variables are common false positives
-unsigned false3(int param, int param2) {
-  param = param; // no-warning
-
-  // if a self assigned variable is used later, then it should be reported still
-  param2 = param2; // expected-warning{{Assigned value is always the same as the existing value}}
-
-  unsigned nonparam = 5;
-
-  nonparam = nonparam; // expected-warning{{Assigned value is always the same as the existing value}}
-
-  return param2 + nonparam;
-}
-
-// Pseudo-constants (vars only read) and constants should not be reported
-unsigned false4() {
-  // Trivial constant
-  const int height = 1;
-  int c = 42;
-  test(height * c); // no-warning
-
-  // Pseudo-constant (never changes after decl)
-  int width = height;
-
-  return width * 10; // no-warning
-}
-
-// Block pseudoconstants
-void false4a() {
-  // Pseudo-constant
-  __block int a = 1;
-  int b = 10;
-  __block int c = 0;
-  b *= a; // no-warning
-
-  ^{
-    // Psuedoconstant block var
-    test(b * c); // no-warning
-
-    // Non-pseudoconstant block var
-    int d = 0;
-    test(b * d); // expected-warning{{The right operand to '*' is always 0}}
-    d = 5;
-    test(d);
-  }();
-
-  test(a + b);
-}
-
-// Static vars are common false positives
-int false5() {
-  static int test = 0;
-  int a = 56;
-  a *= test; // no-warning
-  test++;
-  return a;
-}
-
-// Non-local storage vars are considered false positives
-int globalInt = 1;
-int false6() {
-  int localInt = 23;
-
-  localInt /= globalInt;
-
-  return localInt;
-}
-
-// Check that assignments filter out false positives correctly
-int false7() {
-  int zero = 0; // pseudo-constant
-  int one = 1;
-
-  int a = 55;
-  a = a; // expected-warning{{Assigned value is always the same as the existing value}}
-  a = enum1 * a; // no-warning
-
-  int b = 123;
-  b = b; // no-warning
-
-  return a;
-}
-
-// Check truncations do not flag as self-assignments
-void false8() {
-  int a = 10000000;
-  a = (short)a; // no-warning
-  test(a);
-}
-
-// This test case previously flagged a warning at 'b == c' because the
-// analyzer previously allowed 'UnknownVal' as the index for ElementRegions.
-typedef struct RDar8431728_F {
-  int RDar8431728_A;
-  unsigned char *RDar8431728_B;
-  int RDar8431728_E[6];
-} RDar8431728_D;
-static inline int RDar8431728_C(RDar8431728_D * s, int n,
-    unsigned char **RDar8431728_B_ptr) {
-  int xy, wrap, pred, a, b, c;
-
-  xy = s->RDar8431728_E[n];
-  wrap = s->RDar8431728_A;
-
-  a = s->RDar8431728_B[xy - 1];
-  b = s->RDar8431728_B[xy - 1 - wrap];
-  c = s->RDar8431728_B[xy - wrap];
-
-  if (b == c) { // no-warning
-    pred = a;
-  } else {
-    pred = c;
-  }
-
-  *RDar8431728_B_ptr = &s->RDar8431728_B[xy];
-
-  return pred;
-}
-
-// <rdar://problem/8601243> - Don't warn on pointer arithmetic.  This
-// is often idiomatic.
-unsigned rdar8601243_aux(unsigned n);
-void rdar8601243() {
-  char arr[100];
-  char *start = arr;
-  start = start + rdar8601243_aux(sizeof(arr) - (arr - start)); // no-warning
-  (void) start;
-}
-
-
-float testFloatCast(int i) {
-  float f = i;
-
-  // Don't crash when trying to create a "zero" float.
-  return f - f;
-}
-
diff --git a/test/Analysis/idempotent-operations.cpp b/test/Analysis/idempotent-operations.cpp
deleted file mode 100644
index 9663665..0000000
--- a/test/Analysis/idempotent-operations.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-// RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-constraints=range -fblocks -analyzer-opt-analyze-nested-blocks -analyzer-checker=alpha.deadcode.IdempotentOperations -verify %s
-
-// C++ specific false positives
-
-extern void test(int i);
-extern void test_ref(int &i);
-
-// Test references affecting pseudoconstants
-void false1() {
-  int a = 0;
-  int five = 5;
-  int &b = a;
-   test(five * a); // expected-warning {{The right operand to '*' is always 0}}
-   b = 4;
-}
-
-// Test not flagging idempotent operations because we aborted the analysis
-// of a path because of an unsupported construct.
-struct RDar9219143_Foo {
-  ~RDar9219143_Foo();
-  operator bool() const;
-};
-
-RDar9219143_Foo foo();
-unsigned RDar9219143_bar();
-void RDar9219143_test() {
-  unsigned i, e;
-  for (i = 0, e = RDar9219143_bar(); i != e; ++i)
-    if (foo())
-      break;  
-  if (i == e) // no-warning
-    return;
-}
-
diff --git a/test/Analysis/idempotent-operations.m b/test/Analysis/idempotent-operations.m
deleted file mode 100644
index 306376d..0000000
--- a/test/Analysis/idempotent-operations.m
+++ /dev/null
@@ -1,55 +0,0 @@
-// RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-constraints=range -fblocks -analyzer-opt-analyze-nested-blocks -analyzer-checker=alpha.deadcode.IdempotentOperations,osx.cocoa.RetainCount -verify %s
-// expected-no-diagnostics
-
-typedef signed char BOOL;
-typedef unsigned long NSUInteger;
-typedef struct _NSZone NSZone;
-@protocol NSObject  - (BOOL)isEqual:(id)object;
-@end
-
-@interface NSObject {}
-  @property int locked;
-  @property(nonatomic, readonly) NSObject *media;
-@end
-
-// <rdar://problem/8725041> - Don't flag idempotent operation warnings when
-// a method may invalidate an instance variable.
-@interface Rdar8725041 : NSObject {
-  id _attribute;
-}
-  - (void) method2;
-@end
-
-@implementation Rdar8725041
-- (BOOL) method1 {
-  BOOL needsUpdate = (BOOL)0;
-  id oldAttribute = _attribute;
-  [self method2];
-  needsUpdate |= (_attribute != oldAttribute); // no-warning
-  return needsUpdate;
-}
-
-- (void) method2
-{
-  _attribute = ((void*)0);
-}
-@end
-
-// Test that the idempotent operations checker works in the prescence
-// of property expressions.
-void pr9116(NSObject *placeholder) {
-  int x = placeholder.media.locked = placeholder ? 1 : 0;
-}
-
-// <rdar://problem/9130239>: Test that calling property setters doesn't 
-// trigger an assertion failure when the object is nil.
-@interface RDar9130239
-@property (assign) id delegate;
-@end
-
-void test_RDar9130239(RDar9130239 *x) {
-  if (x)
-    return;
-  x.delegate = x; // no-warning
-}
-
diff --git a/test/Analysis/identical-expressions.cpp b/test/Analysis/identical-expressions.cpp
index 50f341d..85e3322 100644
--- a/test/Analysis/identical-expressions.cpp
+++ b/test/Analysis/identical-expressions.cpp
@@ -2,6 +2,21 @@
 
 /* Only one expected warning per function allowed at the very end. */
 
+int func(void)
+{
+  return 0;
+}
+
+int func2(void)
+{
+  return 0;
+}
+
+int funcParam(int a)
+{
+  return 0;
+}
+
 /* '!=' operator*/
 
 /* '!=' with float */
@@ -295,6 +310,38 @@
 }
 /*   end '!=' int*          */
 
+/* '!=' with function*/
+
+int checkNotEqualSameFunction() {
+  unsigned a = 0;
+  unsigned b = 1;
+  int res = (a+func() != a+func());  // no warning
+  return (0);
+}
+
+int checkNotEqualDifferentFunction() {
+  unsigned a = 0;
+  unsigned b = 1;
+  int res = (a+func() != a+func2());  // no warning
+  return (0);
+}
+
+int checkNotEqualSameFunctionSameParam() {
+  unsigned a = 0;
+  unsigned b = 1;
+  int res = (a+funcParam(a) != a+funcParam(a));  // no warning
+  return (0);
+}
+
+int checkNotEqualSameFunctionDifferentParam() {
+  unsigned a = 0;
+  unsigned b = 1;
+  int res = (a+funcParam(a) != a+funcParam(b));  // no warning
+  return (0);
+}
+
+/*   end '!=' with function*/
+
 /*   end '!=' */
 
 
@@ -526,6 +573,37 @@
   return (0);
 }
 
+/* '==' with function*/
+
+int checkEqualSameFunction() {
+  unsigned a = 0;
+  unsigned b = 1;
+  int res = (a+func() == a+func());  // no warning
+  return (0);
+}
+
+int checkEqualDifferentFunction() {
+  unsigned a = 0;
+  unsigned b = 1;
+  int res = (a+func() == a+func2());  // no warning
+  return (0);
+}
+
+int checkEqualSameFunctionSameParam() {
+  unsigned a = 0;
+  unsigned b = 1;
+  int res = (a+funcParam(a) == a+funcParam(a));  // no warning
+  return (0);
+}
+
+int checkEqualSameFunctionDifferentParam() {
+  unsigned a = 0;
+  unsigned b = 1;
+  int res = (a+funcParam(a) == a+funcParam(b));  // no warning
+  return (0);
+}
+
+/*   end '==' with function*/
 
 /*   end EQ int          */
 
@@ -940,3 +1018,496 @@
 /* end GT with int */
 
 /* end GT */
+
+
+/* Checking use of identical expressions in conditional operator*/
+
+unsigned test_unsigned(unsigned a) {
+  unsigned b = 1;
+  a = a > 5 ? b : b; // expected-warning {{identical expressions on both sides of ':' in conditional expression}}
+  return a;
+}
+
+void test_signed() {
+  int a = 0;
+  a = a > 5 ? a : a; // expected-warning {{identical expressions on both sides of ':' in conditional expression}}
+}
+
+void test_bool(bool a) {
+  a = a > 0 ? a : a; // expected-warning {{identical expressions on both sides of ':' in conditional expression}}
+}
+
+void test_float() {
+  float a = 0;
+  float b = 0;
+  a = a > 5 ? a : a; // expected-warning {{identical expressions on both sides of ':' in conditional expression}}
+}
+
+const char *test_string() {
+  float a = 0;
+  return a > 5 ? "abc" : "abc"; // expected-warning {{identical expressions on both sides of ':' in conditional expression}}
+}
+
+void test_unsigned_expr() {
+  unsigned a = 0;
+  unsigned b = 0;
+  a = a > 5 ? a+b : a+b; // expected-warning {{identical expressions on both sides of ':' in conditional expression}}
+}
+
+void test_signed_expr() {
+  int a = 0;
+  int b = 1;
+  a = a > 5 ? a+b : a+b; // expected-warning {{identical expressions on both sides of ':' in conditional expression}}
+}
+
+void test_bool_expr(bool a) {
+  bool b = 0;
+  a = a > 0 ? a&&b : a&&b; // expected-warning {{identical expressions on both sides of ':' in conditional expression}}
+}
+
+void test_unsigned_expr_negative() {
+  unsigned a = 0;
+  unsigned b = 0;
+  a = a > 5 ? a+b : b+a; // no warning
+}
+
+void test_signed_expr_negative() {
+  int a = 0;
+  int b = 1;
+  a = a > 5 ? b+a : a+b; // no warning
+}
+
+void test_bool_expr_negative(bool a) {
+  bool b = 0;
+  a = a > 0 ? a&&b : b&&a; // no warning
+}
+
+void test_float_expr_positive() {
+  float a = 0;
+  float b = 0;
+  a = a > 5 ? a+b : a+b; // expected-warning {{identical expressions on both sides of ':' in conditional expression}}
+}
+
+void test_expr_positive_func() {
+  unsigned a = 0;
+  unsigned b = 1;
+  a = a > 5 ? a+func() : a+func(); // expected-warning {{identical expressions on both sides of ':' in conditional expression}}
+}
+
+void test_expr_negative_func() {
+  unsigned a = 0;
+  unsigned b = 1;
+  a = a > 5 ? a+func() : a+func2(); // no warning
+}
+
+void test_expr_positive_funcParam() {
+  unsigned a = 0;
+  unsigned b = 1;
+  a = a > 5 ? a+funcParam(b) : a+funcParam(b); // expected-warning {{identical expressions on both sides of ':' in conditional expression}}
+}
+
+void test_expr_negative_funcParam() {
+  unsigned a = 0;
+  unsigned b = 1;
+  a = a > 5 ? a+funcParam(a) : a+funcParam(b); // no warning
+}
+
+void test_expr_positive_inc() {
+  unsigned a = 0;
+  unsigned b = 1;
+  a = a > 5 ? a++ : a++; // expected-warning {{identical expressions on both sides of ':' in conditional expression}}
+}
+
+void test_expr_negative_inc() {
+  unsigned a = 0;
+  unsigned b = 1;
+  a = a > 5 ? a++ : b++; // no warning
+}
+
+void test_expr_positive_assign() {
+  unsigned a = 0;
+  unsigned b = 1;
+  a = a > 5 ? a=1 : a=1;  // expected-warning {{identical expressions on both sides of ':' in conditional expression}}
+}
+
+void test_expr_negative_assign() {
+  unsigned a = 0;
+  unsigned b = 1;
+  a = a > 5 ? a=1 : a=2; // no warning
+}
+
+void test_signed_nested_expr() {
+  int a = 0;
+  int b = 1;
+  int c = 3;
+  a = a > 5 ? a+b+(c+a)*(a + b*(c+a)) : a+b+(c+a)*(a + b*(c+a)); // expected-warning {{identical expressions on both sides of ':' in conditional expression}}
+}
+
+void test_signed_nested_expr_negative() {
+  int a = 0;
+  int b = 1;
+  int c = 3;
+  a = a > 5 ? a+b+(c+a)*(a + b*(c+a)) : a+b+(c+a)*(a + b*(a+c)); // no warning
+}
+
+void test_signed_nested_cond_expr_negative() {
+  int a = 0;
+  int b = 1;
+  int c = 3;
+  a = a > 5 ? (b > 5 ? 1 : 4) : (b > 5 ? 2 : 4); // no warning
+}
+
+void test_signed_nested_cond_expr() {
+  int a = 0;
+  int b = 1;
+  int c = 3;
+  a = a > 5 ? (b > 5 ? 1 : 4) : (b > 5 ? 4 : 4); // expected-warning {{identical expressions on both sides of ':' in conditional expression}}
+}
+
+void test_identical_branches1(bool b) {
+  int i = 0;
+  if (b) { // expected-warning {{true and false branches are identical}}
+    ++i;
+  } else {
+    ++i;
+  }
+}
+
+void test_identical_branches2(bool b) {
+  int i = 0;
+  if (b) { // expected-warning {{true and false branches are identical}}
+    ++i;
+  } else
+    ++i;
+}
+
+void test_identical_branches3(bool b) {
+  int i = 0;
+  if (b) { // no warning
+    ++i;
+  } else {
+    i++;
+  }
+}
+
+void test_identical_branches4(bool b) {
+  int i = 0;
+  if (b) { // expected-warning {{true and false branches are identical}}
+  } else {
+  }
+}
+
+void test_identical_branches_break(bool b) {
+  while (true) {
+    if (b) // expected-warning {{true and false branches are identical}}
+      break;
+    else
+      break;
+  }
+}
+
+void test_identical_branches_continue(bool b) {
+  while (true) {
+    if (b) // expected-warning {{true and false branches are identical}}
+      continue;
+    else
+      continue;
+  }
+}
+
+void test_identical_branches_func(bool b) {
+  if (b) // expected-warning {{true and false branches are identical}}
+    func();
+  else
+    func();
+}
+
+void test_identical_branches_func_arguments(bool b) {
+  if (b) // no-warning
+    funcParam(1);
+  else
+    funcParam(2);
+}
+
+void test_identical_branches_cast1(bool b) {
+  long v = -7;
+  if (b) // no-warning
+    v = (signed int) v;
+  else
+    v = (unsigned int) v;
+}
+
+void test_identical_branches_cast2(bool b) {
+  long v = -7;
+  if (b) // expected-warning {{true and false branches are identical}}
+    v = (signed int) v;
+  else
+    v = (signed int) v;
+}
+
+int test_identical_branches_return_int(bool b) {
+  int i = 0;
+  if (b) { // expected-warning {{true and false branches are identical}}
+    i++;
+    return i;
+  } else {
+    i++;
+    return i;
+  }
+}
+
+int test_identical_branches_return_func(bool b) {
+  if (b) { // expected-warning {{true and false branches are identical}}
+    return func();
+  } else {
+    return func();
+  }
+}
+
+void test_identical_branches_for(bool b) {
+  int i;
+  int j;
+  if (b) { // expected-warning {{true and false branches are identical}}
+    for (i = 0, j = 0; i < 10; i++)
+      j += 4;
+  } else {
+    for (i = 0, j = 0; i < 10; i++)
+      j += 4;
+  }
+}
+
+void test_identical_branches_while(bool b) {
+  int i = 10;
+  if (b) { // expected-warning {{true and false branches are identical}}
+    while (func())
+      i--;
+  } else {
+    while (func())
+      i--;
+  }
+}
+
+void test_identical_branches_while_2(bool b) {
+  int i = 10;
+  if (b) { // no-warning
+    while (func())
+      i--;
+  } else {
+    while (func())
+      i++;
+  }
+}
+
+void test_identical_branches_do_while(bool b) {
+  int i = 10;
+  if (b) { // expected-warning {{true and false branches are identical}}
+    do {
+      i--;
+    } while (func());
+  } else {
+    do {
+      i--;
+    } while (func());
+  }
+}
+
+void test_identical_branches_if(bool b, int i) {
+  if (b) { // expected-warning {{true and false branches are identical}}
+    if (i < 5)
+      i += 10;
+  } else {
+    if (i < 5)
+      i += 10;
+  }
+}
+
+void test_identical_bitwise1() {
+  int a = 5 | 5; // expected-warning {{identical expressions on both sides of bitwise operator}}
+}
+
+void test_identical_bitwise2() {
+  int a = 5;
+  int b = a | a; // expected-warning {{identical expressions on both sides of bitwise operator}}
+}
+
+void test_identical_bitwise3() {
+  int a = 5;
+  int b = (a | a); // expected-warning {{identical expressions on both sides of bitwise operator}}
+}
+
+void test_identical_bitwise4() {
+  int a = 4;
+  int b = a | 4; // no-warning
+}
+
+void test_identical_bitwise5() {
+  int a = 4;
+  int b = 4;
+  int c = a | b; // no-warning
+}
+
+void test_identical_bitwise6() {
+  int a = 5;
+  int b = a | 4 | a; // expected-warning {{identical expressions on both sides of bitwise operator}}
+}
+
+void test_identical_bitwise7() {
+  int a = 5;
+  int b = func() | func(); // no-warning
+}
+
+void test_identical_logical1(int a) {
+  if (a == 4 && a == 4) // expected-warning {{identical expressions on both sides of logical operator}}
+    ;
+}
+
+void test_identical_logical2(int a) {
+  if (a == 4 || a == 5 || a == 4) // expected-warning {{identical expressions on both sides of logical operator}}
+    ;
+}
+
+void test_identical_logical3(int a) {
+  if (a == 4 || a == 5 || a == 6) // no-warning
+    ;
+}
+
+void test_identical_logical4(int a) {
+  if (a == func() || a == func()) // no-warning
+    ;
+}
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wlogical-op-parentheses"
+void test_identical_logical5(int x, int y) {
+  if (x == 4 && y == 5 || x == 4 && y == 6) // no-warning
+    ;
+}
+
+void test_identical_logical6(int x, int y) {
+  if (x == 4 && y == 5 || x == 4 && y == 5) // expected-warning {{identical expressions on both sides of logical operator}}
+    ;
+}
+
+void test_identical_logical7(int x, int y) {
+  // FIXME: We should warn here
+  if (x == 4 && y == 5 || x == 4)
+    ;
+}
+
+void test_identical_logical8(int x, int y) {
+  // FIXME: We should warn here
+  if (x == 4 || y == 5 && x == 4)
+    ;
+}
+
+void test_identical_logical9(int x, int y) {
+  // FIXME: We should warn here
+  if (x == 4 || x == 4 && y == 5)
+    ;
+}
+#pragma clang diagnostic pop
+
+void test_warn_chained_if_stmts_1(int x) {
+  if (x == 1)
+    ;
+  else if (x == 1) // expected-warning {{expression is identical to previous condition}}
+    ;
+}
+
+void test_warn_chained_if_stmts_2(int x) {
+  if (x == 1)
+    ;
+  else if (x == 1) // expected-warning {{expression is identical to previous condition}}
+    ;
+  else if (x == 1) // expected-warning {{expression is identical to previous condition}}
+    ;
+}
+
+void test_warn_chained_if_stmts_3(int x) {
+  if (x == 1)
+    ;
+  else if (x == 2)
+    ;
+  else if (x == 1) // expected-warning {{expression is identical to previous condition}}
+    ;
+}
+
+void test_warn_chained_if_stmts_4(int x) {
+  if (x == 1)
+    ;
+  else if (func())
+    ;
+  else if (x == 1) // expected-warning {{expression is identical to previous condition}}
+    ;
+}
+
+void test_warn_chained_if_stmts_5(int x) {
+  if (x & 1)
+    ;
+  else if (x & 1) // expected-warning {{expression is identical to previous condition}}
+    ;
+}
+
+void test_warn_chained_if_stmts_6(int x) {
+  if (x == 1)
+    ;
+  else if (x == 2)
+    ;
+  else if (x == 2) // expected-warning {{expression is identical to previous condition}}
+    ;
+  else if (x == 3)
+    ;
+}
+
+void test_warn_chained_if_stmts_7(int x) {
+  if (x == 1)
+    ;
+  else if (x == 2)
+    ;
+  else if (x == 3)
+    ;
+  else if (x == 2) // expected-warning {{expression is identical to previous condition}}
+    ;
+  else if (x == 5)
+    ;
+}
+
+void test_warn_chained_if_stmts_8(int x) {
+  if (x == 1)
+    ;
+  else if (x == 2)
+    ;
+  else if (x == 3)
+    ;
+  else if (x == 2) // expected-warning {{expression is identical to previous condition}}
+    ;
+  else if (x == 5)
+    ;
+  else if (x == 3) // expected-warning {{expression is identical to previous condition}}
+    ;
+  else if (x == 7)
+    ;
+}
+
+void test_nowarn_chained_if_stmts_1(int x) {
+  if (func())
+    ;
+  else if (func()) // no-warning
+    ;
+}
+
+void test_nowarn_chained_if_stmts_2(int x) {
+  if (func())
+    ;
+  else if (x == 1)
+    ;
+  else if (func()) // no-warning
+    ;
+}
+
+void test_nowarn_chained_if_stmts_3(int x) {
+  if (x++)
+    ;
+  else if (x++) // no-warning
+    ;
+}
diff --git a/test/Analysis/inline.cpp b/test/Analysis/inline.cpp
index ca126dd..183df16 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 -verify %s
+// RUN: %clang_cc1 -analyze -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);
@@ -9,6 +9,7 @@
 // This is the standard placement new.
 inline void* operator new(size_t, void* __p) throw()
 {
+  clang_analyzer_checkInlined(true);// expected-warning{{TRUE}}
   return __p;
 }
 
diff --git a/test/Analysis/inlining/containers.cpp b/test/Analysis/inlining/containers.cpp
index 73b2957..c757da6 100644
--- a/test/Analysis/inlining/containers.cpp
+++ b/test/Analysis/inlining/containers.cpp
@@ -103,7 +103,10 @@
   ~MySet() { delete[] storage; }
 
   bool isEmpty() {
-    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
+    clang_analyzer_checkInlined(true);
+    #if INLINE
+        // expected-warning@-2 {{TRUE}}
+    #endif
     return size == 0;
   }
 
@@ -114,23 +117,35 @@
   };
 
   iterator begin() {
-    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
+    clang_analyzer_checkInlined(true);
+    #if INLINE
+        // expected-warning@-2 {{TRUE}}
+    #endif
     return iterator(storage);
   }
 
   iterator end() {
-    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
+    clang_analyzer_checkInlined(true);
+    #if INLINE
+        // expected-warning@-2 {{TRUE}}
+    #endif
     return iterator(storage+size);
   }
 
   typedef int *raw_iterator;
 
   raw_iterator raw_begin() {
-    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
+    clang_analyzer_checkInlined(true);
+    #if INLINE
+        // expected-warning@-2 {{TRUE}}
+    #endif
     return storage;
   }
   raw_iterator raw_end() {
-    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
+    clang_analyzer_checkInlined(true);
+    #if INLINE
+        // expected-warning@-2 {{TRUE}}
+    #endif
     return storage + size;
   }
 };
@@ -145,7 +160,10 @@
   }
 
   void useIterator(iterator i) {
-    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
+    clang_analyzer_checkInlined(true);
+    #if INLINE
+        // expected-warning@-2 {{TRUE}}
+    #endif
   }
 };
 
@@ -174,7 +192,10 @@
   typedef IterImpl wrapped_iterator;
 
   wrapped_iterator begin() {
-    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
+    clang_analyzer_checkInlined(true);
+    #if INLINE
+        // expected-warning@-2 {{TRUE}}
+    #endif
     return IterImpl(impl.begin());
   }
 };
@@ -193,7 +214,10 @@
   typedef MySet::iterator iterator;
 
   iterator start() {
-    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
+    clang_analyzer_checkInlined(true);
+#if INLINE
+    // expected-warning@-2 {{TRUE}}
+#endif
     return impl.begin();
   }
 };
@@ -212,7 +236,10 @@
   using iterator = MySet::iterator;
 
   iterator start() {
-    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
+    clang_analyzer_checkInlined(true);
+    #if INLINE
+        // expected-warning@-2 {{TRUE}}
+    #endif
     return impl.begin();
   }
 };
@@ -233,7 +260,10 @@
   };
 
   iterator start() {
-    clang_analyzer_checkInlined(true); // expected-warning {{TRUE}}
+    clang_analyzer_checkInlined(true);
+    #if INLINE
+        // expected-warning@-2 {{TRUE}}
+    #endif
     return iterator{impl.begin().impl};
   }
 };
diff --git a/test/Analysis/inlining/dyn-dispatch-bifurcate.cpp b/test/Analysis/inlining/dyn-dispatch-bifurcate.cpp
index d219446..e23d4e2 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 %s
+// RUN: %clang_cc1 -analyze -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/path-notes.cpp b/test/Analysis/inlining/path-notes.cpp
index a354e14..1e23074 100644
--- a/test/Analysis/inlining/path-notes.cpp
+++ b/test/Analysis/inlining/path-notes.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=text -analyzer-config c++-inlining=destructors -std=c++11 -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config c++-inlining=destructors -std=c++11 -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=text -analyzer-config c++-inlining=destructors -std=c++11 -verify -Wno-tautological-undefined-compare %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config c++-inlining=destructors -std=c++11 -analyzer-config path-diagnostics-alternate=false %s -o %t.plist -Wno-tautological-undefined-compare
 // RUN: FileCheck --input-file=%t.plist %s
 
 class Foo {
@@ -1506,7 +1506,7 @@
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
 // CHECK-NEXT:          <key>line</key><integer>120</integer>
-// CHECK-NEXT:          <key>col</key><integer>19</integer>
+// CHECK-NEXT:          <key>col</key><integer>20</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:        </array>
@@ -1535,7 +1535,7 @@
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
 // CHECK-NEXT:          <key>line</key><integer>120</integer>
-// CHECK-NEXT:          <key>col</key><integer>19</integer>
+// CHECK-NEXT:          <key>col</key><integer>20</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:        </array>
@@ -1787,7 +1787,7 @@
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
 // CHECK-NEXT:          <key>line</key><integer>128</integer>
-// CHECK-NEXT:          <key>col</key><integer>32</integer>
+// CHECK-NEXT:          <key>col</key><integer>33</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:        </array>
@@ -2452,12 +2452,12 @@
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
 // CHECK-NEXT:            <key>line</key><integer>105</integer>
-// CHECK-NEXT:            <key>col</key><integer>21</integer>
+// CHECK-NEXT:            <key>col</key><integer>53</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
 // CHECK-NEXT:            <key>line</key><integer>105</integer>
-// CHECK-NEXT:            <key>col</key><integer>28</integer>
+// CHECK-NEXT:            <key>col</key><integer>53</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
@@ -2469,7 +2469,7 @@
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
 // CHECK-NEXT:       <key>line</key><integer>105</integer>
-// CHECK-NEXT:       <key>col</key><integer>21</integer>
+// CHECK-NEXT:       <key>col</key><integer>53</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
 // CHECK-NEXT:      <key>ranges</key>
@@ -2477,12 +2477,12 @@
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
 // CHECK-NEXT:          <key>line</key><integer>105</integer>
-// CHECK-NEXT:          <key>col</key><integer>21</integer>
+// CHECK-NEXT:          <key>col</key><integer>53</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
 // CHECK-NEXT:          <key>line</key><integer>105</integer>
-// CHECK-NEXT:          <key>col</key><integer>28</integer>
+// CHECK-NEXT:          <key>col</key><integer>53</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:        </array>
diff --git a/test/Analysis/inlining/stl.cpp b/test/Analysis/inlining/stl.cpp
index c153174..711c30f 100644
--- a/test/Analysis/inlining/stl.cpp
+++ b/test/Analysis/inlining/stl.cpp
@@ -42,3 +42,8 @@
   std::basic_string<char32_t> v;
   v += 'c'; // no-warning
 }
+
+void testBasicStringSuppression_assign(std::basic_string<char32_t> &v,
+                                       const std::basic_string<char32_t> &v2) {
+  v = v2;
+}
diff --git a/test/Analysis/kmalloc-linux.c b/test/Analysis/kmalloc-linux.c
new file mode 100644
index 0000000..87c1107
--- /dev/null
+++ b/test/Analysis/kmalloc-linux.c
@@ -0,0 +1,58 @@
+// RUN: %clang -target x86_64-unknown-linux --analyze %s
+
+#include "Inputs/system-header-simulator.h"
+
+#define __GFP_ZERO 0x8000
+#define NULL ((void *)0)
+
+void *kmalloc(size_t, int);
+
+struct test {
+};
+
+void foo(struct test *);
+
+void test_zeroed() {
+  struct test **list, *t;
+  int i;
+
+  list = kmalloc(sizeof(*list) * 10, __GFP_ZERO);
+  if (list == NULL)
+    return;
+
+  for (i = 0; i < 10; i++) {
+    t = list[i];
+    foo(t);
+  }
+  free(list); // no-warning
+}
+
+void test_nonzero() {
+  struct test **list, *t;
+  int i;
+
+  list = kmalloc(sizeof(*list) * 10, 0);
+  if (list == NULL)
+    return;
+
+  for (i = 0; i < 10; i++) {
+    t = list[i]; // expected-warning{{undefined}}
+    foo(t);
+  }
+  free(list);
+}
+
+void test_indeterminate(int flags) {
+  struct test **list, *t;
+  int i;
+
+  list = kmalloc(sizeof(*list) * 10, flags);
+  if (list == NULL)
+    return;
+
+  for (i = 0; i < 10; i++) {
+    t = list[i]; // expected-warning{{undefined}}
+    foo(t);
+  }
+  free(list);
+}
diff --git a/test/Analysis/live-variables.cpp b/test/Analysis/live-variables.cpp
new file mode 100644
index 0000000..0cfaa1b
--- /dev/null
+++ b/test/Analysis/live-variables.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s
+// expected-no-diagnostics
+class B {
+public:
+  bool m;
+  ~B() {} // The destructor ensures that the binary logical operator below is wrapped in the ExprWithCleanups.
+};
+B foo();
+int getBool();
+int *getPtr();
+int test() {
+  int r = 0;
+  for (int x = 0; x< 10; x++) {
+    int *p = getPtr();
+    // Liveness info is not computed correctly due to the following expression.
+    // This happens due to CFG being special cased for short circuit operators.
+    // PR18159
+    if (p != 0 && getBool() && foo().m && getBool()) {
+      r = *p; // no warning
+    }
+  }
+  return r;
+}
diff --git a/test/Analysis/live-variables.m b/test/Analysis/live-variables.m
new file mode 100644
index 0000000..eefd292
--- /dev/null
+++ b/test/Analysis/live-variables.m
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -fobjc-arc -verify %s
+// expected-no-diagnostics
+@interface NSObject
+@end
+@interface NSString : NSObject
+- (id)lastPathComponent;
+@end
+int getBool();
+int *getPtr();
+int foo() {
+  int r = 0;
+  NSString *filename = @"filename";
+  for (int x = 0; x< 10; x++) {
+    int *p = getPtr();
+    // Liveness info is not computed correctly due to the following expression.
+    // This happens due to CFG being special cased for short circuit operators.
+    // Note, due to ObjC method call, the outermost logical operator is wrapped in ExprWithCleanups.
+    // PR18159
+    if ((p != 0) && (getBool()) && ([filename lastPathComponent]) && (getBool())) {
+      r = *p; // no-warning
+    }
+  }
+  return r;
+}
\ No newline at end of file
diff --git a/test/Analysis/malloc-three-arg.c b/test/Analysis/malloc-three-arg.c
new file mode 100644
index 0000000..01b08ae
--- /dev/null
+++ b/test/Analysis/malloc-three-arg.c
@@ -0,0 +1,58 @@
+// RUN: %clang -target x86_64-unknown-freebsd --analyze %s
+
+#include "Inputs/system-header-simulator.h"
+
+#define M_ZERO 0x0100
+#define NULL ((void *)0)
+
+void *malloc(size_t, void *, int);
+
+struct test {
+};
+
+void foo(struct test *);
+
+void test_zeroed() {
+  struct test **list, *t;
+  int i;
+
+  list = malloc(sizeof(*list) * 10, NULL, M_ZERO);
+  if (list == NULL)
+    return;
+
+  for (i = 0; i < 10; i++) {
+    t = list[i];
+    foo(t);
+  }
+  free(list); // no-warning
+}
+
+void test_nonzero() {
+  struct test **list, *t;
+  int i;
+
+  list = malloc(sizeof(*list) * 10, NULL, 0);
+  if (list == NULL)
+    return;
+
+  for (i = 0; i < 10; i++) {
+    t = list[i]; // expected-warning{{undefined}}
+    foo(t);
+  }
+  free(list);
+}
+
+void test_indeterminate(int flags) {
+  struct test **list, *t;
+  int i;
+
+  list = malloc(sizeof(*list) * 10, NULL, flags);
+  if (list == NULL)
+    return;
+
+  for (i = 0; i < 10; i++) {
+    t = list[i]; // expected-warning{{undefined}}
+    foo(t);
+  }
+  free(list);
+}
diff --git a/test/Analysis/malloc.c b/test/Analysis/malloc.c
index a0296cb..9c08bbc 100644
--- a/test/Analysis/malloc.c
+++ b/test/Analysis/malloc.c
@@ -270,6 +270,222 @@
   buf[1] = 'c'; // not crash
 }
 
+void cast_emtpy_struct() {
+  struct st {
+  };
+
+  struct st *s = malloc(sizeof(struct st)); // no-warning
+  free(s);
+}
+
+void cast_struct_1() {
+  struct st {
+    int i[100];
+    char j[];
+  };
+
+  struct st *s = malloc(sizeof(struct st)); // no-warning
+  free(s);
+}
+
+void cast_struct_2() {
+  struct st {
+    int i[100];
+    char j[0];
+  };
+
+  struct st *s = malloc(sizeof(struct st)); // no-warning
+  free(s);
+}
+
+void cast_struct_3() {
+  struct st {
+    int i[100];
+    char j[1];
+  };
+
+  struct st *s = malloc(sizeof(struct st)); // no-warning
+  free(s);
+}
+
+void cast_struct_4() {
+  struct st {
+    int i[100];
+    char j[2];
+  };
+
+  struct st *s = malloc(sizeof(struct st)); // no-warning
+  free(s);
+}
+
+void cast_struct_5() {
+  struct st {
+    char i[200];
+    char j[1];
+  };
+
+  struct st *s = malloc(sizeof(struct st) - sizeof(char)); // no-warning
+  free(s);
+}
+
+void cast_struct_warn_1() {
+  struct st {
+    int i[100];
+    char j[2];
+  };
+
+  struct st *s = malloc(sizeof(struct st) + 2); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}}
+  free(s);
+}
+
+void cast_struct_warn_2() {
+  struct st {
+    int i[100];
+    char j[2];
+  };
+
+  struct st *s = malloc(2); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}}
+  free(s);
+}
+
+void cast_struct_flex_array_1() {
+  struct st {
+    int i[100];
+    char j[];
+  };
+
+  struct st *s = malloc(sizeof(struct st) + 3); // no-warning
+  free(s);
+}
+
+void cast_struct_flex_array_2() {
+  struct st {
+    int i[100];
+    char j[0];
+  };
+
+  struct st *s = malloc(sizeof(struct st) + 3); // no-warning
+  free(s);
+}
+
+void cast_struct_flex_array_3() {
+  struct st {
+    int i[100];
+    char j[1];
+  };
+
+  struct st *s = malloc(sizeof(struct st) + 3); // no-warning
+  free(s);
+}
+
+void cast_struct_flex_array_4() {
+  struct foo {
+    char f[32];
+  };
+  struct st {
+    char i[100];
+    struct foo data[];
+  };
+
+  struct st *s = malloc(sizeof(struct st) + 3 * sizeof(struct foo)); // no-warning
+  free(s);
+}
+
+void cast_struct_flex_array_5() {
+  struct foo {
+    char f[32];
+  };
+  struct st {
+    char i[100];
+    struct foo data[0];
+  };
+
+  struct st *s = malloc(sizeof(struct st) + 3 * sizeof(struct foo)); // no-warning
+  free(s);
+}
+
+void cast_struct_flex_array_6() {
+  struct foo {
+    char f[32];
+  };
+  struct st {
+    char i[100];
+    struct foo data[1];
+  };
+
+  struct st *s = malloc(sizeof(struct st) + 3 * sizeof(struct foo)); // no-warning
+  free(s);
+}
+
+void cast_struct_flex_array_warn_1() {
+  struct foo {
+    char f[32];
+  };
+  struct st {
+    char i[100];
+    struct foo data[];
+  };
+
+  struct st *s = malloc(3 * sizeof(struct st) + 3 * sizeof(struct foo)); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}}
+  free(s);
+}
+
+void cast_struct_flex_array_warn_2() {
+  struct foo {
+    char f[32];
+  };
+  struct st {
+    char i[100];
+    struct foo data[0];
+  };
+
+  struct st *s = malloc(3 * sizeof(struct st) + 3 * sizeof(struct foo)); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}}
+  free(s);
+}
+
+void cast_struct_flex_array_warn_3() {
+  struct foo {
+    char f[32];
+  };
+  struct st {
+    char i[100];
+    struct foo data[1];
+  };
+
+  struct st *s = malloc(3 * sizeof(struct st) + 3 * sizeof(struct foo)); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}}
+  free(s);
+}
+
+void cast_struct_flex_array_warn_4() {
+  struct st {
+    int i[100];
+    int j[];
+  };
+
+  struct st *s = malloc(sizeof(struct st) + 3); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}}
+  free(s);
+}
+
+void cast_struct_flex_array_warn_5() {
+  struct st {
+    int i[100];
+    int j[0];
+  };
+
+  struct st *s = malloc(sizeof(struct st) + 3); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}}
+  free(s);
+}
+
+void cast_struct_flex_array_warn_6() {
+  struct st {
+    int i[100];
+    int j[1];
+  };
+
+  struct st *s = malloc(sizeof(struct st) + 3); // expected-warning{{Cast a region whose size is not a multiple of the destination type size}}
+  free(s);
+}
+
 void mallocCastToVoid() {
   void *p = malloc(2);
   const void *cp = p; // not crash
@@ -1290,6 +1506,12 @@
   return p;
 }
 
+int *radar15580979() {
+  int *data = (int *)malloc(32);
+  int *p = data ?: (int*)malloc(32); // no warning
+  return p;
+}
+
 // ----------------------------------------------------------------------------
 // False negatives.
 
diff --git a/test/Analysis/malloc.m b/test/Analysis/malloc.m
index ad16db5..9201c2b 100644
--- a/test/Analysis/malloc.m
+++ b/test/Analysis/malloc.m
@@ -49,4 +49,9 @@
 void testNSDataTruePositiveLeak() {
   char *b = (char *)malloc(12);
   NSData *d = [[NSData alloc] initWithBytes: b length: 12]; // expected-warning {{Potential leak of memory pointed to by 'b'}}
+}
+
+id wrapInNSValue() {
+  void *buffer = malloc(4);
+  return [NSValue valueWithPointer:buffer]; // no-warning
 }
\ No newline at end of file
diff --git a/test/Analysis/member-expr.cpp b/test/Analysis/member-expr.cpp
index cf43738..f8dd324 100644
--- a/test/Analysis/member-expr.cpp
+++ b/test/Analysis/member-expr.cpp
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection %s -verify
 
+void clang_analyzer_checkInlined(bool);
 void clang_analyzer_eval(int);
 
 namespace EnumsViaMemberExpr {
@@ -20,4 +21,21 @@
   void testEnumPtr(Foo *Baz) {
     clang_analyzer_eval(Baz->Bar == Foo::Bar); // expected-warning{{TRUE}}
   }
-}
\ No newline at end of file
+}
+
+namespace PR19531 {
+  struct A {
+    A() : x(0) {}
+    bool h() const;
+    int x;
+  };
+
+  struct B {
+    void g(bool (A::*mp_f)() const) {
+      // This used to trigger an assertion because the 'this' pointer is a
+      // temporary.
+      (A().*mp_f)();
+    }
+    void f() { g(&A::h); }
+  };
+}
diff --git a/test/Analysis/method-arg-decay.m b/test/Analysis/method-arg-decay.m
index 0af9e3e..a222346 100644
--- a/test/Analysis/method-arg-decay.m
+++ b/test/Analysis/method-arg-decay.m
@@ -67,12 +67,12 @@
 @interface XCExtendedTabView : NSTabView <XCDockViewHeader> {
 }
 @end     @class PBXProjectDocument, PBXFileReference, PBXModule, XCWindowTool;
-@interface XCPerspectiveModule : PBXProjectModule <PBXSelectionTarget> { // expected-note {{required for direct or indirect protocol 'PBXSelectionTarget'}}
+@interface XCPerspectiveModule : PBXProjectModule <PBXSelectionTarget> {
   XCExtendedTabView *_perspectivesTabView;
 }
 - (PBXModule *) moduleForTab:(NSTabViewItem *)item;
 @end  
-@implementation XCPerspectiveModule // expected-warning {{method 'performAction:withSelection:' in protocol not implemented}}}
+@implementation XCPerspectiveModule // expected-warning {{method 'performAction:withSelection:' in protocol 'PBXSelectionTarget' not implemented}}}
 + (void) openForProjectDocument:(PBXProjectDocument *)projectDocument {
 }
 - (PBXModule *) type:(Class)type inPerspective:(id)perspectiveIdentifer  matchingFunction:(BOOL (void *, void *))comparator usingData:(void *)data {
diff --git a/test/Analysis/misc-ps-region-store.cpp b/test/Analysis/misc-ps-region-store.cpp
index 6a873f0..af9f7cf 100644
--- a/test/Analysis/misc-ps-region-store.cpp
+++ b/test/Analysis/misc-ps-region-store.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s -fexceptions -fcxx-exceptions
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s -fexceptions -fcxx-exceptions
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s -fexceptions -fcxx-exceptions -Wno-tautological-undefined-compare
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s -fexceptions -fcxx-exceptions -Wno-tautological-undefined-compare
 
 void clang_analyzer_warnIfReached();
 
@@ -588,6 +588,7 @@
   int x = int();
   if (!x) {
     clang_analyzer_warnIfReached();  // expected-warning{{REACHABLE}}
+    ; // Suppress warning that both branches are identical
   }
   else {
     clang_analyzer_warnIfReached();  // no-warning
diff --git a/test/Analysis/misc-ps-region-store.m b/test/Analysis/misc-ps-region-store.m
index ba88dec..5816648 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.deadcode.IdempotentOperations,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.deadcode.IdempotentOperations,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 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
 
 typedef long unsigned int size_t;
 void *memcpy(void *, const void *, size_t);
@@ -253,7 +253,7 @@
   a = A;
   b = B;
   
-  n = *a++; // expected-warning{{Assigned value is always the same as the existing value}}
+  n = *a++;
   if (n)
     x += *b++; // no-warning
 }
@@ -1115,7 +1115,7 @@
   int number = pr8015_A();
   const char *numbers[] = { "zero" };
   if (number == 0) {
-    if (numbers[number] == numbers[0]) // expected-warning{{Both operands to '==' always have the same value}}
+    if (numbers[number] == numbers[0])
       return;
     // Unreachable.
     int *p = 0;
@@ -1362,5 +1362,5 @@
 int rdar11125868_positive() {
   int integersStackArray[1];
   int *integers = integersStackArray;
-  return integers[0] == 0; // expected-warning {{he left operand of '==' is a}}
+  return integers[0] == 0; // expected-warning {{The left operand of '==' is a}}
 }
diff --git a/test/Analysis/misc-ps.m b/test/Analysis/misc-ps.m
index b261b10..6da9604 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.deadcode.IdempotentOperations,alpha.core,osx.cocoa.AtSync -analyzer-store=region -analyzer-constraints=range -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.deadcode.IdempotentOperations,alpha.core,osx.cocoa.AtSync -analyzer-store=region -analyzer-constraints=range -verify -fblocks -Wno-unreachable-code -Wno-null-dereference -Wno-objc-root-class %s
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core,alpha.core,osx.cocoa.AtSync -analyzer-store=region -analyzer-constraints=range -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 -analyzer-constraints=range -verify -fblocks -Wno-unreachable-code -Wno-null-dereference -Wno-objc-root-class %s
 
 #ifndef __clang_analyzer__
 #error __clang_analyzer__ not defined
@@ -80,11 +80,11 @@
 
 void r6268365() {
   unsigned x = 0;
-  x &= r6268365Aux(); // expected-warning{{The left operand to '&=' is always 0}}
+  x &= r6268365Aux();
   unsigned j = 0;
     
   if (x == 0) ++j;
-  if (x == 0) x = x / j; // expected-warning{{Assigned value is always the same as the existing value}} expected-warning{{The right operand to '/' is always 1}}
+  if (x == 0) x = x / j;
 }
 
 void divzeroassume(unsigned x, unsigned j) {  
@@ -412,14 +412,14 @@
   int test_trivial_symbolic_comparison_aux();
   int a = test_trivial_symbolic_comparison_aux();
   int b = a;
-  if (a != b) { // expected-warning{{Both operands to '!=' always have the same value}}
+  if (a != b) {
     int *p = 0;
     *p = 0xDEADBEEF;     // no-warning
   }
   
   a = a == 1;
   b = b == 1;
-  if (a != b) { // expected-warning{{Both operands to '!=' always have the same value}}
+  if (a != b) {
     int *p = 0;
     *p = 0xDEADBEEF;     // no-warning
   }
diff --git a/test/Analysis/new.cpp b/test/Analysis/new.cpp
index 105a973..e262aa7 100644
--- a/test/Analysis/new.cpp
+++ b/test/Analysis/new.cpp
@@ -267,7 +267,7 @@
   clang_analyzer_eval(true); // no warn
 }
 
-//Deleting a non class pointer should not crash/warn
+//Deleting a non-class pointer should not crash/warn
 void test_var_delete() {
   int *v = new int;
   delete v;  // no crash/warn
diff --git a/test/Analysis/no-outofbounds.c b/test/Analysis/no-outofbounds.c
index 84f86d7..d401279 100644
--- a/test/Analysis/no-outofbounds.c
+++ b/test/Analysis/no-outofbounds.c
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,alpha.unix,alpha.security.ArrayBound -analyzer-store=region -verify %s
+// expected-no-diagnostics
 
 //===----------------------------------------------------------------------===//
 // This file tests cases where we should not flag out-of-bounds warnings.
@@ -24,8 +25,7 @@
 
 void field() {
   struct vec { size_t len; int data[0]; };
-  // FIXME: Not warn for this.
-  struct vec *a = malloc(sizeof(struct vec) + 10); // expected-warning {{Cast a region whose size is not a multiple of the destination type size}}
+  struct vec *a = malloc(sizeof(struct vec) + 10*sizeof(int));
   a->len = 10;
   a->data[1] = 5; // no-warning
   free(a);
diff --git a/test/Analysis/nonnull.m b/test/Analysis/nonnull.m
index c32a7f7..0cea80b 100644
--- a/test/Analysis/nonnull.m
+++ b/test/Analysis/nonnull.m
@@ -1,7 +1,9 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -w -verify %s
 
 @interface MyObject
 - (void)takePointer:(void *)ptr __attribute__((nonnull(1)));
+- (void)takePointerArg:(void *)__attribute__((nonnull)) ptr;
+
 @end
 
 void testNonNullMethod(int *p, MyObject *obj) {
@@ -21,3 +23,55 @@
     return;
   [obj takePointer:p]; // expected-warning{{nonnull}}
 }
+
+void testSubclassArg(int *p, Subclass *obj) {
+  if (p)
+    return;
+  [obj takePointerArg:p]; // expected-warning{{nonnull}}
+}
+
+
+union rdar16153464_const_cp_t {
+  const struct rdar16153464_cczp *zp;
+  const struct rdar16153464_cczp_prime *prime;
+} __attribute__((transparent_union));
+
+struct rdar16153464_header {
+  union rdar16153464_const_cp_t cp;
+  unsigned char pad[16 - sizeof(union rdar16153464_const_cp_t *)];
+} __attribute__((aligned(16)));
+
+
+struct rdar16153464_full_ctx {
+  struct rdar16153464_header hdr;
+} __attribute__((aligned(16)));
+
+
+struct rdar16153464_pub_ctx {
+  struct rdar16153464_header hdr;
+} __attribute__((aligned(16)));
+
+
+union rdar16153464_full_ctx_t {
+  struct rdar16153464_full_ctx *_full;
+  struct rdar16153464_header *hdr;
+  struct rdar16153464_body *body;
+  struct rdar16153464_public *pub;
+} __attribute__((transparent_union));
+
+union rdar16153464_pub_ctx_t {
+  struct rdar16153464_pub_ctx *_pub;
+  struct rdar16153464_full_ctx *_full;
+  struct rdar16153464_header *hdr;
+  struct rdar16153464_body *body;
+  struct rdar16153464_public *pub;
+  union rdar16153464_full_ctx_t innert;
+} __attribute__((transparent_union));
+
+int rdar16153464(union rdar16153464_full_ctx_t inner)
+{
+  extern void rdar16153464_check(union rdar16153464_pub_ctx_t outer) __attribute((nonnull(1)));
+  rdar16153464_check((union rdar16153464_pub_ctx_t){ .innert = inner }); // no-warning
+  rdar16153464_check(inner); // no-warning
+  rdar16153464_check(0); // expected-warning{{nonnull}}
+}
diff --git a/test/Analysis/null-deref-ps.c b/test/Analysis/null-deref-ps.c
index 4dc8fc4..240e8ed 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.deadcode.IdempotentOperations,alpha.core -std=gnu99 -analyzer-store=region -analyzer-constraints=range -analyzer-purge=none -verify %s -Wno-error=return-type
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core,deadcode,alpha.deadcode.IdempotentOperations,alpha.core -std=gnu99 -analyzer-store=region -analyzer-constraints=range -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 -analyzer-constraints=range -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 -analyzer-constraints=range -verify %s -Wno-error=return-type 
 
 typedef unsigned uintptr_t;
 
@@ -64,7 +64,7 @@
   short *p = x; // expected-warning{{incompatible integer to pointer conversion}}
 
   // The following branch should be infeasible.
-  if (!(p == &array[0])) { // expected-warning{{Both operands to '==' always have the same value}}
+  if (!(p == &array[0])) {
     p = 0;
     *p = 1; // no-warning
   }
@@ -297,7 +297,7 @@
 int foo10595327(int b) {
   void (*fp)(int *);
   // We use path sensitivity to get the function declaration. Even when the
-  // function pointer is cast to non pointer-to-const parameter type, we can
+  // function pointer is cast to non-pointer-to-const parameter type, we can
   // find the right function declaration.
   if (b > 5)
     fp = (NoConstType)ttt2;
diff --git a/test/Analysis/objc-arc.m b/test/Analysis/objc-arc.m
index ba590d614..92432b1 100644
--- a/test/Analysis/objc-arc.m
+++ b/test/Analysis/objc-arc.m
@@ -138,7 +138,7 @@
 void from_cf() {
   id obj1 = (__bridge_transfer id)CFCreateSomething(); // expected-warning{{never read}}
   id obj2 = (__bridge_transfer NSString*)CFCreateString();
-  [obj2 self]; // Add a use, to show we can use the object after it has been transfered.
+  [obj2 self]; // Add a use, to show we can use the object after it has been transferred.
   id obj3 = (__bridge id)CFGetSomething();
   [obj3 self]; // Add a use, to show we can use the object after it has been bridged.
   id obj4 = (__bridge NSString*)CFGetString(); // expected-warning{{never read}}
diff --git a/test/Analysis/objc-boxing.m b/test/Analysis/objc-boxing.m
index 98310b5..c23192e 100644
--- a/test/Analysis/objc-boxing.m
+++ b/test/Analysis/objc-boxing.m
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -analyzer-store=region -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,osx.cocoa.NonNilReturnValue,debug.ExprInspection -analyzer-store=region -verify %s
+
+void clang_analyzer_eval(int);
 
 typedef signed char BOOL;
 typedef long NSInteger;
@@ -41,4 +43,15 @@
   if (x)
     return @(3);
   return @(*x); // expected-warning {{Dereference of null pointer (loaded from variable 'x')}}
-}
\ No newline at end of file
+}
+
+void checkNonNil() {
+  clang_analyzer_eval(!!@3); // expected-warning{{TRUE}}
+  clang_analyzer_eval(!!@(3+4)); // expected-warning{{TRUE}}
+  clang_analyzer_eval(!!@(57.0)); // expected-warning{{TRUE}}
+
+  const char *str = "abc";
+  clang_analyzer_eval(!!@(str)); // expected-warning{{TRUE}}
+  clang_analyzer_eval(!!@__objc_yes); // expected-warning{{TRUE}}
+}
+
diff --git a/test/Analysis/objc-for.m b/test/Analysis/objc-for.m
index 2f14b8a..d1e044a 100644
--- a/test/Analysis/objc-for.m
+++ b/test/Analysis/objc-for.m
@@ -109,7 +109,7 @@
 }
 
 int collectionIsEmptyNSSet(NSSet *S){
-  if ([S count] == 2) { // Count is non zero.
+  if ([S count] == 2) { // Count is non-zero.
     int tapCounts[2];
     int i = 0;
     for (NSString *elem in S) {
diff --git a/test/Analysis/objc-properties.m b/test/Analysis/objc-properties.m
index 323f41a..f6ed3e5 100644
--- a/test/Analysis/objc-properties.m
+++ b/test/Analysis/objc-properties.m
@@ -23,8 +23,8 @@
 
   @property (assign, nonatomic) MyClass* Y; // automatically synthesized, implemented
 
-  @property (assign, nonatomic) MyClass* Z; // non synthesized ivar, implemented setter
-  @property (readonly) id nonSynth;  // non synthesized, explicitly implemented to return ivar with expected name
+  @property (assign, nonatomic) MyClass* Z; // non-synthesized ivar, implemented setter
+  @property (readonly) id nonSynth;  // non-synthesized, explicitly implemented to return ivar with expected name
   
   - (id) initWithPtr:(MyClass*) value;
   - (id) myInitWithPtr:(MyClass*) value;
diff --git a/test/Analysis/objc-radar17039661.m b/test/Analysis/objc-radar17039661.m
new file mode 100644
index 0000000..ec4f19d
--- /dev/null
+++ b/test/Analysis/objc-radar17039661.m
@@ -0,0 +1,60 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -verify -fblocks %s
+
+@class NSString;
+typedef long NSInteger;
+typedef unsigned char BOOL;
+@interface NSObject {}
++(id)alloc;
+-(id)init;
+-(id)autorelease;
+-(id)copy;
+-(id)retain;
+@end
+@interface NSNumber : NSObject
++ (NSNumber *)numberWithInteger:(NSInteger)value __attribute__((availability(ios,introduced=2.0)));
+@end
+
+NSInteger *inoutIntegerValueGlobal;
+NSInteger *inoutIntegerValueGlobal2;
+NSString *traitNameGlobal;
+static BOOL cond;
+
+static inline void reallyPerformAction(void (^integerHandler)(NSInteger *inoutIntegerValue, NSString *traitName)) {
+  integerHandler(inoutIntegerValueGlobal, traitNameGlobal);
+  integerHandler(inoutIntegerValueGlobal2,traitNameGlobal);
+}
+
+static inline BOOL performAction(NSNumber *(^action)(NSNumber *traitValue)) {
+  __attribute__((__blocks__(byref))) BOOL didFindTrait = 0;
+  reallyPerformAction(^(NSInteger *inoutIntegerValue,NSString *traitName) {
+
+    if (cond) {
+
+      NSNumber *traitValue = @(*inoutIntegerValue);
+
+      NSNumber *newTraitValue = action(traitValue);
+
+      if (traitValue != newTraitValue) {
+        *inoutIntegerValue = newTraitValue ? *inoutIntegerValue : *inoutIntegerValue;
+      }
+      didFindTrait = 1;
+    }
+
+  });
+  return didFindTrait;
+}
+
+void runTest() {
+  __attribute__((__blocks__(byref))) NSNumber *builtinResult = ((NSNumber *)0);
+  BOOL wasBuiltinTrait = performAction(^(NSNumber *traitValue) {
+    builtinResult = [traitValue retain]; // expected-warning {{Potential leak of an object}}
+
+    return traitValue;
+  });
+  if (wasBuiltinTrait) {
+    [builtinResult autorelease];
+    return;
+  } else {
+    return;
+  }
+}
diff --git a/test/Analysis/objc-string.mm b/test/Analysis/objc-string.mm
index c67ab5e..a32b740 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 %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -Wno-objc-literal-conversion %s
 
 void clang_analyzer_eval(bool);
 @class NSString;
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 f1ecd54..4777aed 100644
--- a/test/Analysis/objc/direct-ivar-assignment-in-annotated-functions.m
+++ b/test/Analysis/objc/direct-ivar-assignment-in-annotated-functions.m
@@ -32,8 +32,8 @@
 
   @property (assign, nonatomic) MyClass* Y; // automatically synthesized, implemented
 
-  @property (assign, nonatomic) MyClass* Z; // non synthesized ivar, implemented setter
-  @property (readonly) id nonSynth;  // non synthesized, explicitly implemented to return ivar with expected name
+  @property (assign, nonatomic) MyClass* Z; // non-synthesized ivar, implemented setter
+  @property (readonly) id nonSynth;  // non-synthesized, explicitly implemented to return ivar with expected name
   
   @property (assign) MyClass* NotA;  // warnings should be suppressed, backing ivar is annotated
   @property (assign) MyClass* NotX __attribute__((annotate("objc_allow_direct_instance_variable_assignment")));  // warnings should be suppressed
diff --git a/test/Analysis/properties.m b/test/Analysis/properties.m
index ddd0068..f5b5d92 100644
--- a/test/Analysis/properties.m
+++ b/test/Analysis/properties.m
@@ -1,4 +1,7 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -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 %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,debug.ExprInspection -analyzer-store=region -verify -Wno-objc-root-class -fobjc-arc %s
+
+void clang_analyzer_eval(int);
 
 typedef signed char BOOL;
 typedef unsigned int NSUInteger;
@@ -14,6 +17,7 @@
 -(id)autorelease;
 -(id)copy;
 -(id)retain;
+-(oneway void)release;
 @end
 @interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>
 - (NSUInteger)length;
@@ -36,6 +40,8 @@
 @end
 
 
+#if !__has_feature(objc_arc)
+
 @implementation Test1
 
 @synthesize text;
@@ -114,6 +120,8 @@
   return [result autorelease]; // expected-warning {{Object autoreleased too many times}}
 }
 
+#endif
+
 
 // rdar://6611873
 
@@ -121,18 +129,23 @@
   NSString *_name;
 }
 @property (retain) NSString * name;
+@property (assign) id friend;
 @end
 
 @implementation Person
 @synthesize name = _name;
 @end
 
+#if !__has_feature(objc_arc)
 void rdar6611873() {
   Person *p = [[[Person alloc] init] autorelease];
   
   p.name = [[NSString string] retain]; // expected-warning {{leak}}
   p.name = [[NSString alloc] init]; // expected-warning {{leak}}
+
+  p.friend = [[Person alloc] init]; // expected-warning {{leak}}
 }
+#endif
 
 @interface SubPerson : Person
 -(NSString *)foo;
@@ -144,6 +157,8 @@
 }
 @end
 
+
+#if !__has_feature(objc_arc)
 // <rdar://problem/9241180> Static analyzer doesn't detect uninitialized variable issues for property accesses
 @interface RDar9241180
 @property (readwrite,assign) id x;
@@ -164,5 +179,168 @@
   self.x = y;  // expected-warning {{Argument for property setter is an uninitialized value}}
 }
 @end
+#endif
 
 
+//------
+// Property accessor synthesis
+//------
+
+extern void doSomethingWithPerson(Person *p);
+extern void doSomethingWithName(NSString *name);
+
+void testConsistencyRetain(Person *p) {
+  clang_analyzer_eval(p.name == p.name); // expected-warning{{TRUE}}
+
+  id origName = p.name;
+  clang_analyzer_eval(p.name == origName); // expected-warning{{TRUE}}
+  doSomethingWithPerson(p);
+  clang_analyzer_eval(p.name == origName); // expected-warning{{UNKNOWN}}
+}
+
+void testConsistencyAssign(Person *p) {
+  clang_analyzer_eval(p.friend == p.friend); // expected-warning{{TRUE}}
+
+  id origFriend = p.friend;
+  clang_analyzer_eval(p.friend == origFriend); // expected-warning{{TRUE}}
+  doSomethingWithPerson(p);
+  clang_analyzer_eval(p.friend == origFriend); // expected-warning{{UNKNOWN}}
+}
+
+#if !__has_feature(objc_arc)
+void testOverrelease(Person *p, int coin) {
+  switch (coin) {
+  case 0:
+    [p.name release]; // expected-warning{{not owned}}
+    break;
+  case 1:
+    [p.friend release]; // expected-warning{{not owned}}
+    break;
+  case 2: {
+    id friend = p.friend;
+    doSomethingWithPerson(p);
+    [friend release]; // expected-warning{{not owned}}
+  }
+  }
+}
+
+// <rdar://problem/16333368>
+@implementation Person (Rdar16333368)
+
+- (void)testDeliberateRelease:(Person *)other {
+  doSomethingWithName(self.name);
+  [_name release]; // no-warning
+  self->_name = 0;
+
+  doSomethingWithName(other->_name);
+  [other.name release]; // expected-warning{{not owned}}
+}
+
+- (void)deliberateReleaseFalseNegative {
+  // This is arguably a false negative because the result of p.friend shouldn't
+  // be released, even though we are manipulating the ivar in between the two
+  // actions.
+  id name = self.name;
+  _name = 0;
+  [name release];
+}
+
+- (void)testRetainAndRelease {
+  [self.name retain];
+  [self.name release];
+  [self.name release]; // expected-warning{{not owned}}
+}
+
+- (void)testRetainAndReleaseIVar {
+  [self.name retain];
+  [_name release];
+  [_name release]; // expected-warning{{not owned}}
+}
+
+@end
+#endif
+
+@interface IntWrapper
+@property int value;
+@end
+
+@implementation IntWrapper
+@synthesize value;
+@end
+
+void testConsistencyInt(IntWrapper *w) {
+  clang_analyzer_eval(w.value == w.value); // expected-warning{{TRUE}}
+
+  int origValue = w.value;
+  if (origValue != 42)
+    return;
+
+  clang_analyzer_eval(w.value == 42); // expected-warning{{TRUE}}
+}
+
+void testConsistencyInt2(IntWrapper *w) {
+  if (w.value != 42)
+    return;
+
+  clang_analyzer_eval(w.value == 42); // expected-warning{{TRUE}}
+}
+
+
+@interface IntWrapperAuto
+@property int value;
+@end
+
+@implementation IntWrapperAuto
+@end
+
+void testConsistencyIntAuto(IntWrapperAuto *w) {
+  clang_analyzer_eval(w.value == w.value); // expected-warning{{TRUE}}
+
+  int origValue = w.value;
+  if (origValue != 42)
+    return;
+
+  clang_analyzer_eval(w.value == 42); // expected-warning{{TRUE}}
+}
+
+void testConsistencyIntAuto2(IntWrapperAuto *w) {
+  if (w.value != 42)
+    return;
+
+  clang_analyzer_eval(w.value == 42); // expected-warning{{TRUE}}
+}
+
+
+typedef struct {
+  int value;
+} IntWrapperStruct;
+
+@interface StructWrapper
+@property IntWrapperStruct inner;
+@end
+
+@implementation StructWrapper
+@synthesize inner;
+@end
+
+void testConsistencyStruct(StructWrapper *w) {
+  clang_analyzer_eval(w.inner.value == w.inner.value); // expected-warning{{TRUE}}
+
+  int origValue = w.inner.value;
+  if (origValue != 42)
+    return;
+
+  clang_analyzer_eval(w.inner.value == 42); // expected-warning{{TRUE}}
+}
+
+
+@interface OpaqueIntWrapper
+@property int value;
+@end
+
+// For now, don't assume a property is implemented using an ivar unless we can
+// actually see that it is.
+void testOpaqueConsistency(OpaqueIntWrapper *w) {
+  clang_analyzer_eval(w.value == w.value); // expected-warning{{UNKNOWN}}
+}
+
diff --git a/test/Analysis/properties.mm b/test/Analysis/properties.mm
new file mode 100644
index 0000000..e49d034
--- /dev/null
+++ b/test/Analysis/properties.mm
@@ -0,0 +1,79 @@
+// 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
+
+void clang_analyzer_eval(bool);
+void clang_analyzer_checkInlined(bool);
+
+@interface IntWrapper
+@property (readonly) int &value;
+@end
+
+@implementation IntWrapper
+@synthesize value;
+@end
+
+void testReferenceConsistency(IntWrapper *w) {
+  clang_analyzer_eval(w.value == w.value); // expected-warning{{TRUE}}
+  clang_analyzer_eval(&w.value == &w.value); // expected-warning{{TRUE}}
+
+  if (w.value != 42)
+    return;
+
+  clang_analyzer_eval(w.value == 42); // expected-warning{{TRUE}}
+}
+
+void testReferenceAssignment(IntWrapper *w) {
+  w.value = 42;
+  clang_analyzer_eval(w.value == 42); // expected-warning{{TRUE}}
+}
+
+
+struct IntWrapperStruct {
+  int value;
+};
+
+@interface StructWrapper
+@property IntWrapperStruct inner;
+@end
+
+@implementation StructWrapper
+@synthesize inner;
+@end
+
+void testConsistencyStruct(StructWrapper *w) {
+  clang_analyzer_eval(w.inner.value == w.inner.value); // expected-warning{{TRUE}}
+
+  int origValue = w.inner.value;
+  if (origValue != 42)
+    return;
+
+  clang_analyzer_eval(w.inner.value == 42); // expected-warning{{TRUE}}
+}
+
+
+class CustomCopy {
+public:
+  CustomCopy() : value(0) {}
+  CustomCopy(const CustomCopy &other) : value(other.value) {
+    clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
+  }
+  int value;
+};
+
+@interface CustomCopyWrapper
+@property CustomCopy inner;
+@end
+
+@implementation CustomCopyWrapper
+//@synthesize inner;
+@end
+
+void testConsistencyCustomCopy(CustomCopyWrapper *w) {
+  clang_analyzer_eval(w.inner.value == w.inner.value); // expected-warning{{TRUE}}
+
+  int origValue = w.inner.value;
+  if (origValue != 42)
+    return;
+
+  clang_analyzer_eval(w.inner.value == 42); // expected-warning{{TRUE}}
+}
diff --git a/test/Analysis/pthreadlock.c b/test/Analysis/pthreadlock.c
index b904774..2a59e0f 100644
--- a/test/Analysis/pthreadlock.c
+++ b/test/Analysis/pthreadlock.c
@@ -6,17 +6,31 @@
 	void	*foo;
 } pthread_mutex_t;
 
+typedef struct {
+	void	*foo;
+} pthread_mutexattr_t;
+
+typedef struct {
+	void	*foo;
+} lck_grp_t;
+
 typedef pthread_mutex_t lck_mtx_t;
 
 extern int pthread_mutex_lock(pthread_mutex_t *);
 extern int pthread_mutex_unlock(pthread_mutex_t *);
 extern int pthread_mutex_trylock(pthread_mutex_t *);
+extern int pthread_mutex_destroy(pthread_mutex_t *);
+extern int pthread_mutex_init(pthread_mutex_t  *mutex, const pthread_mutexattr_t *mutexattr);
 extern int lck_mtx_lock(lck_mtx_t *);
 extern int lck_mtx_unlock(lck_mtx_t *);
 extern int lck_mtx_try_lock(lck_mtx_t *);
+extern void lck_mtx_destroy(lck_mtx_t *lck, lck_grp_t *grp);
 
 pthread_mutex_t mtx1, mtx2;
 lck_mtx_t lck1, lck2;
+lck_grp_t grp1;
+
+#define NULL 0
 
 void
 ok1(void)
@@ -69,6 +83,107 @@
 }
 
 void
+ok8(void)
+{
+	pthread_mutex_lock(&mtx1);	// no-warning
+	pthread_mutex_lock(&mtx2);	// no-warning
+	pthread_mutex_unlock(&mtx2);	// no-warning
+	pthread_mutex_unlock(&mtx1);	// no-warning
+}
+
+void
+ok9(void)
+{
+	pthread_mutex_unlock(&mtx1);		// no-warning
+	if (pthread_mutex_trylock(&mtx1) == 0)	// no-warning
+		pthread_mutex_unlock(&mtx1);	// no-warning
+}
+
+void
+ok10(void)
+{
+	if (pthread_mutex_trylock(&mtx1) != 0)	// no-warning
+		pthread_mutex_lock(&mtx1);	// no-warning
+	pthread_mutex_unlock(&mtx1);		// no-warning
+}
+
+void
+ok11(void)
+{
+	pthread_mutex_destroy(&mtx1);	// no-warning
+}
+
+void
+ok12(void)
+{
+	pthread_mutex_destroy(&mtx1);	// no-warning
+	pthread_mutex_destroy(&mtx2);	// no-warning
+}
+
+void
+ok13(void)
+{
+	pthread_mutex_unlock(&mtx1);	// no-warning
+	pthread_mutex_destroy(&mtx1);	// no-warning
+}
+
+void
+ok14(void)
+{
+	pthread_mutex_unlock(&mtx1);	// no-warning
+	pthread_mutex_destroy(&mtx1);	// no-warning
+	pthread_mutex_unlock(&mtx2);	// no-warning
+	pthread_mutex_destroy(&mtx2);	// no-warning
+}
+
+void
+ok15(void)
+{
+	pthread_mutex_lock(&mtx1);	// no-warning
+	pthread_mutex_unlock(&mtx1);	// no-warning
+	pthread_mutex_destroy(&mtx1);	// no-warning
+}
+
+void
+ok16(void)
+{
+	pthread_mutex_init(&mtx1, NULL);	// no-warning
+}
+
+void
+ok17(void)
+{
+	pthread_mutex_init(&mtx1, NULL);	// no-warning
+	pthread_mutex_init(&mtx2, NULL);	// no-warning
+}
+
+void
+ok18(void)
+{
+	pthread_mutex_destroy(&mtx1);		// no-warning
+	pthread_mutex_init(&mtx1, NULL);	// no-warning
+}
+
+void
+ok19(void)
+{
+	pthread_mutex_destroy(&mtx1);		// no-warning
+	pthread_mutex_init(&mtx1, NULL);	// no-warning
+	pthread_mutex_destroy(&mtx2);		// no-warning
+	pthread_mutex_init(&mtx2, NULL);	// no-warning
+}
+
+void
+ok20(void)
+{
+	pthread_mutex_unlock(&mtx1);		// no-warning
+	pthread_mutex_destroy(&mtx1);		// no-warning
+	pthread_mutex_init(&mtx1, NULL);	// no-warning
+	pthread_mutex_destroy(&mtx1);		// no-warning
+	pthread_mutex_init(&mtx1, NULL);	// no-warning
+}
+
+void
 bad1(void)
 {
 	pthread_mutex_lock(&mtx1);	// no-warning
@@ -135,3 +250,151 @@
 	lck_mtx_lock(&lck2);		// no-warning
 	lck_mtx_unlock(&lck1);		// expected-warning{{This was not the most recently acquired lock}}
 }
+
+void
+bad9(void)
+{
+	lck_mtx_unlock(&lck1);		// no-warning
+	lck_mtx_unlock(&lck1);		// expected-warning{{This lock has already been unlocked}}
+}
+
+void
+bad10(void)
+{
+	lck_mtx_lock(&lck1);		// no-warning
+	lck_mtx_unlock(&lck1);		// no-warning
+	lck_mtx_unlock(&lck1);		// expected-warning{{This lock has already been unlocked}}
+}
+
+static void
+bad11_sub(pthread_mutex_t *lock)
+{
+	lck_mtx_unlock(lock);		// expected-warning{{This lock has already been unlocked}}
+}
+
+void
+bad11(int i)
+{
+	lck_mtx_lock(&lck1);		// no-warning
+	lck_mtx_unlock(&lck1);		// no-warning
+	if (i < 5)
+		bad11_sub(&lck1);
+}
+
+void
+bad12(void)
+{
+	pthread_mutex_lock(&mtx1);	// no-warning
+	pthread_mutex_unlock(&mtx1);	// no-warning
+	pthread_mutex_lock(&mtx1);	// no-warning
+	pthread_mutex_unlock(&mtx1);	// no-warning
+	pthread_mutex_unlock(&mtx1);	// expected-warning{{This lock has already been unlocked}}
+}
+
+void
+bad13(void)
+{
+	pthread_mutex_lock(&mtx1);	// no-warning
+	pthread_mutex_unlock(&mtx1);	// no-warning
+	pthread_mutex_lock(&mtx2);	// no-warning
+	pthread_mutex_unlock(&mtx2);	// no-warning
+	pthread_mutex_unlock(&mtx1);	// expected-warning{{This lock has already been unlocked}}
+}
+
+void
+bad14(void)
+{
+	pthread_mutex_lock(&mtx1);	// no-warning
+	pthread_mutex_lock(&mtx2);	// no-warning
+	pthread_mutex_unlock(&mtx2);	// no-warning
+	pthread_mutex_unlock(&mtx1);	// no-warning
+	pthread_mutex_unlock(&mtx2);	// expected-warning{{This lock has already been unlocked}}
+}
+
+void
+bad15(void)
+{
+	pthread_mutex_lock(&mtx1);	// no-warning
+	pthread_mutex_lock(&mtx2);	// no-warning
+	pthread_mutex_unlock(&mtx2);	// no-warning
+	pthread_mutex_unlock(&mtx1);	// no-warning
+	pthread_mutex_lock(&mtx1);	// no-warning
+	pthread_mutex_unlock(&mtx2);	// expected-warning{{This lock has already been unlocked}}
+}
+
+void
+bad16(void)
+{
+	pthread_mutex_destroy(&mtx1);	// no-warning
+	pthread_mutex_lock(&mtx1);	// expected-warning{{This lock has already been destroyed}}
+}
+
+void
+bad17(void)
+{
+	pthread_mutex_destroy(&mtx1);	// no-warning
+	pthread_mutex_unlock(&mtx1);	// expected-warning{{This lock has already been destroyed}}
+}
+
+void
+bad18(void)
+{
+	pthread_mutex_destroy(&mtx1);	// no-warning
+	pthread_mutex_destroy(&mtx1);	// expected-warning{{This lock has already been destroyed}}
+}
+
+void
+bad19(void)
+{
+	pthread_mutex_lock(&mtx1);	// no-warning
+	pthread_mutex_destroy(&mtx1);	// expected-warning{{This lock is still locked}}
+}
+
+void
+bad20(void)
+{
+	lck_mtx_destroy(&mtx1, &grp1);	// no-warning
+	lck_mtx_lock(&mtx1);		// expected-warning{{This lock has already been destroyed}}
+}
+
+void
+bad21(void)
+{
+	lck_mtx_destroy(&mtx1, &grp1);	// no-warning
+	lck_mtx_unlock(&mtx1);		// expected-warning{{This lock has already been destroyed}}
+}
+
+void
+bad22(void)
+{
+	lck_mtx_destroy(&mtx1, &grp1);	// no-warning
+	lck_mtx_destroy(&mtx1, &grp1);	// expected-warning{{This lock has already been destroyed}}
+}
+
+void
+bad23(void)
+{
+	lck_mtx_lock(&mtx1);		// no-warning
+	lck_mtx_destroy(&mtx1, &grp1);	// expected-warning{{This lock is still locked}}
+}
+
+void
+bad24(void)
+{
+	pthread_mutex_init(&mtx1, NULL);	// no-warning
+	pthread_mutex_init(&mtx1, NULL);	// expected-warning{{This lock has already been initialized}}
+}
+
+void
+bad25(void)
+{
+	pthread_mutex_lock(&mtx1);		// no-warning
+	pthread_mutex_init(&mtx1, NULL);	// expected-warning{{This lock is still being held}}
+}
+
+void
+bad26(void)
+{
+	pthread_mutex_unlock(&mtx1);		// no-warning
+	pthread_mutex_init(&mtx1, NULL);	// expected-warning{{This lock has already been initialized}}
+}
diff --git a/test/Analysis/ptr-arith.c b/test/Analysis/ptr-arith.c
index 4a15bc2..96dc8ba 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 %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 %s
+// 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
 
 void clang_analyzer_eval(int);
 
diff --git a/test/Analysis/reference.cpp b/test/Analysis/reference.cpp
index bd5eaaa..cd0202e 100644
--- a/test/Analysis/reference.cpp
+++ b/test/Analysis/reference.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -analyzer-constraints=range -verify -Wno-null-dereference %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -analyzer-constraints=range -verify -Wno-null-dereference -Wno-tautological-undefined-compare %s
 
 void clang_analyzer_eval(bool);
 
diff --git a/test/Analysis/region-1.m b/test/Analysis/region-1.m
index 9edb35b..6940c69 100644
--- a/test/Analysis/region-1.m
+++ b/test/Analysis/region-1.m
@@ -25,7 +25,7 @@
 CK_UNRESTRICTED= 0,     CK_READ_ONLY,     CK_ADD_ONLY,     CK_REMOVE_ONLY };
 @protocol EcoClass <EcoBehavioredClassifier>      - (NSArray *) ownedAttributes;
 @end @protocol EcoNamespace;
-@protocol EcoType;
+@protocol EcoType @end;
 @protocol EcoClassifier <EcoNamespace,EcoType>    - (NSArray *) features; 
 @end @protocol EcoComment;
 @protocol EcoElement <NSObject> - (NSArray *) ownedElements;
diff --git a/test/Analysis/retain-release-cache-out.m b/test/Analysis/retain-release-cache-out.m
new file mode 100644
index 0000000..54573a4
--- /dev/null
+++ b/test/Analysis/retain-release-cache-out.m
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -analyze %s -analyzer-checker=core,osx.cocoa.RetainCount -fblocks -verify
+
+// This test is checking behavior when a single checker runs only with the core
+// checkers, testing that the traversal order in the CFG does not affect the
+// reporting of an error.
+
+#import "Inputs/system-header-simulator-objc.h"
+
+void testDoubleRelease(BOOL z) {
+  id x = [[NSObject alloc] init];
+  if (z) {
+    [x release];
+  } else {
+    ;
+  }
+  [x release]; // expected-warning {{Reference-counted object is used after it is released}}
+}
+
+void testDoubleRelease2(BOOL z) {
+  id x = [[NSObject alloc] init];
+  if (z) {
+    ;
+  } else {
+    [x release];
+  }
+  [x release]; // expected-warning {{Reference-counted object is used after it is released}}
+}
diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m
index aafd94e..6973f9b 100644
--- a/test/Analysis/retain-release.m
+++ b/test/Analysis/retain-release.m
@@ -194,8 +194,15 @@
 @end
 @interface NSMutableDictionary : NSDictionary  - (void)removeObjectForKey:(id)aKey;
 - (void)setObject:(id)anObject forKey:(id)aKey;
-@end  @interface NSMutableDictionary (NSMutableDictionaryCreation)  + (id)dictionaryWithCapacity:(NSUInteger)numItems;
-@end  typedef double CGFloat;
+@end
+@interface NSMutableDictionary (NSMutableDictionaryCreation)  + (id)dictionaryWithCapacity:(NSUInteger)numItems;
+@end
+
+@interface NSNull : NSObject
++ (NSNull*) null;
+@end
+
+typedef double CGFloat;
 struct CGSize {
 };
 typedef struct CGSize CGSize;
@@ -210,7 +217,7 @@
 typedef void (*IOServiceMatchingCallback)(  void * refcon,  io_iterator_t iterator );
 io_service_t IOServiceGetMatchingService(  mach_port_t masterPort,  CFDictionaryRef matching );
 kern_return_t IOServiceGetMatchingServices(  mach_port_t masterPort,  CFDictionaryRef matching,  io_iterator_t * existing );
-kern_return_t IOServiceAddNotification(  mach_port_t masterPort,  const io_name_t notificationType,  CFDictionaryRef matching,  mach_port_t wakePort,  uintptr_t reference,  io_iterator_t * notification ) __attribute__((deprecated)); // expected-note {{'IOServiceAddNotification' declared here}}
+kern_return_t IOServiceAddNotification(  mach_port_t masterPort,  const io_name_t notificationType,  CFDictionaryRef matching,  mach_port_t wakePort,  uintptr_t reference,  io_iterator_t * notification ) __attribute__((deprecated)); // expected-note {{'IOServiceAddNotification' has been explicitly marked deprecated here}}
 kern_return_t IOServiceAddMatchingNotification(  IONotificationPortRef notifyPort,  const io_name_t notificationType,  CFDictionaryRef matching,         IOServiceMatchingCallback callback,         void * refCon,  io_iterator_t * notification );
 CFMutableDictionaryRef IOServiceMatching(  const char * name );
 CFMutableDictionaryRef IOServiceNameMatching(  const char * name );
@@ -348,7 +355,7 @@
 
 NSDate* global_x;
 
-// Test to see if we supresss an error when we store the pointer
+// Test to see if we suppress an error when we store the pointer
 // to a global.
 
 CFAbsoluteTime f3() {
@@ -516,38 +523,54 @@
   CFRelease(*B);  // no-warning
 }
 
-// Test when we pass NULL to CFRetain/CFRelease/CFMakeCollectable.
+// Test when we pass NULL to CFRetain/CFRelease/CFMakeCollectable/CFAutorelease.
 void f16(int x, CFTypeRef p) {
   if (p)
     return;
 
-  if (x > 0) {
+  switch (x) {
+  case 0:
     CFRelease(p); // expected-warning{{Null pointer argument in call to CFRelease}}
-  }
-  else if (x < 0) {
+    break;
+  case 1:
     CFRetain(p); // expected-warning{{Null pointer argument in call to CFRetain}}
-  }
-  else {
+    break;
+  case 2:
     CFMakeCollectable(p); // expected-warning{{Null pointer argument in call to CFMakeCollectable}}
+    break;
+  case 3:
+    CFAutorelease(p); // expected-warning{{Null pointer argument in call to CFAutorelease}}
+    break;
+  default:
+    break;
   }
 }
 
-// Test that an object is non-null after being CFRetained/CFReleased.
+// Test that an object is non-null after CFRetain/CFRelease/CFMakeCollectable/CFAutorelease.
 void f17(int x, CFTypeRef p) {
-  if (x > 0) {
+  switch (x) {
+  case 0:
     CFRelease(p);
     if (!p)
       CFRelease(0); // no-warning
-  }
-  else if (x < 0) {
+    break;
+  case 1:
     CFRetain(p);
     if (!p)
       CFRetain(0); // no-warning
-  }
-  else {
+    break;
+  case 2:
     CFMakeCollectable(p);
     if (!p)
       CFMakeCollectable(0); // no-warning
+    break;
+  case 3:
+    CFAutorelease(p);
+    if (!p)
+      CFAutorelease(0); // no-warning
+    break;
+  default:
+    break;
   }
 }
 
@@ -2121,6 +2144,15 @@
     CFStringCreateWithCString(0, "hello world", kCFStringEncodingUTF8);
 }
 
+//===----------------------------------------------------------------------===//
+// Handle NSNull
+//===----------------------------------------------------------------------===//
+
+__attribute__((ns_returns_retained))
+id returnNSNull() {
+  return [NSNull null]; // no-warning
+}
+
 // CHECK:  <key>diagnostics</key>
 // CHECK-NEXT:  <array>
 // CHECK-NEXT:   <dict>
@@ -2134,12 +2166,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>324</integer>
+// CHECK-NEXT:            <key>line</key><integer>334</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>324</integer>
+// CHECK-NEXT:            <key>line</key><integer>334</integer>
 // CHECK-NEXT:            <key>col</key><integer>16</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -2147,12 +2179,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>325</integer>
+// CHECK-NEXT:            <key>line</key><integer>335</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>325</integer>
+// CHECK-NEXT:            <key>line</key><integer>335</integer>
 // CHECK-NEXT:            <key>col</key><integer>11</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -2161,44 +2193,10 @@
 // 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>325</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>325</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>325</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>325</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>line</key><integer>325</integer>
+// CHECK-NEXT:       <key>line</key><integer>335</integer>
 // CHECK-NEXT:       <key>col</key><integer>20</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -2206,12 +2204,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>325</integer>
+// CHECK-NEXT:          <key>line</key><integer>335</integer>
 // CHECK-NEXT:          <key>col</key><integer>20</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>325</integer>
+// CHECK-NEXT:          <key>line</key><integer>335</integer>
 // CHECK-NEXT:          <key>col</key><integer>37</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -2231,25 +2229,25 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>325</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
+// CHECK-NEXT:            <key>line</key><integer>335</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>325</integer>
-// CHECK-NEXT:            <key>col</key><integer>31</integer>
+// CHECK-NEXT:            <key>line</key><integer>335</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>326</integer>
+// CHECK-NEXT:            <key>line</key><integer>336</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>326</integer>
+// CHECK-NEXT:            <key>line</key><integer>336</integer>
 // CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -2261,7 +2259,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>326</integer>
+// CHECK-NEXT:       <key>line</key><integer>336</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -2269,24 +2267,24 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>326</integer>
+// CHECK-NEXT:          <key>line</key><integer>336</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>326</integer>
+// CHECK-NEXT:          <key>line</key><integer>336</integer>
 // CHECK-NEXT:          <key>col</key><integer>16</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:        </array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>326</integer>
+// CHECK-NEXT:          <key>line</key><integer>336</integer>
 // CHECK-NEXT:          <key>col</key><integer>12</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>326</integer>
+// CHECK-NEXT:          <key>line</key><integer>336</integer>
 // CHECK-NEXT:          <key>col</key><integer>15</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -2306,12 +2304,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>326</integer>
+// CHECK-NEXT:            <key>line</key><integer>336</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>326</integer>
+// CHECK-NEXT:            <key>line</key><integer>336</integer>
 // CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -2319,374 +2317,13 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>327</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>327</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>327</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>327</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>327</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:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>327</integer>
-// CHECK-NEXT:          <key>col</key><integer>13</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>327</integer>
-// CHECK-NEXT:          <key>col</key><integer>16</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Reference count decremented. The object now has a +1 retain count</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Reference count decremented. The object now has a +1 retain count</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>327</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>327</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>329</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>329</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>329</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>329</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>329</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:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>329</integer>
-// CHECK-NEXT:          <key>col</key><integer>13</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>329</integer>
-// CHECK-NEXT:          <key>col</key><integer>16</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Object released</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Object released</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>329</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>329</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>330</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>330</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>330</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>330</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>330</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>330</integer>
-// CHECK-NEXT:            <key>col</key><integer>27</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>330</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>330</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>330</integer>
-// CHECK-NEXT:          <key>col</key><integer>32</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>Reference-counted object is used after it is released</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Reference-counted object is used after it is released</string>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:    </array>
-// CHECK-NEXT:    <key>description</key><string>Reference-counted object is used after it is released</string>
-// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
-// CHECK-NEXT:    <key>type</key><string>Use-after-release</string>
-// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT:   <key>issue_context</key><string>f1</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>7</string>
-// CHECK-NEXT:   <key>location</key>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>330</integer>
-// CHECK-NEXT:    <key>col</key><integer>7</integer>
-// CHECK-NEXT:    <key>file</key><integer>0</integer>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>path</key>
-// CHECK-NEXT:    <array>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>335</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>335</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>336</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>336</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>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>336</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>336</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>336</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>336</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>line</key><integer>336</integer>
-// CHECK-NEXT:       <key>col</key><integer>20</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>336</integer>
-// CHECK-NEXT:          <key>col</key><integer>20</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>336</integer>
-// CHECK-NEXT:          <key>col</key><integer>37</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>Call to function &apos;CFDateCreate&apos; returns a Core Foundation object 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:     </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>336</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>336</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>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
 // CHECK-NEXT:            <key>line</key><integer>337</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>337</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>col</key><integer>11</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
@@ -2711,93 +2348,18 @@
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
 // CHECK-NEXT:          <key>line</key><integer>337</integer>
-// CHECK-NEXT:          <key>col</key><integer>27</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>337</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>337</integer>
-// CHECK-NEXT:          <key>col</key><integer>19</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>Reference count incremented. The object now has a +2 retain count</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Reference count incremented. The object now has a +2 retain count</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>337</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>337</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>338</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>338</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>338</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>338</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>338</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:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>338</integer>
+// CHECK-NEXT:          <key>line</key><integer>337</integer>
 // CHECK-NEXT:          <key>col</key><integer>13</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>338</integer>
+// CHECK-NEXT:          <key>line</key><integer>337</integer>
 // CHECK-NEXT:          <key>col</key><integer>16</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -2817,12 +2379,87 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>338</integer>
+// CHECK-NEXT:            <key>line</key><integer>337</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>338</integer>
+// CHECK-NEXT:            <key>line</key><integer>337</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>339</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>339</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>339</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>339</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>339</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:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>339</integer>
+// CHECK-NEXT:          <key>col</key><integer>13</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>339</integer>
+// CHECK-NEXT:          <key>col</key><integer>16</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Object released</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Object released</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>339</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>339</integer>
 // CHECK-NEXT:            <key>col</key><integer>11</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -2844,11 +2481,45 @@
 // 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>340</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>340</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>340</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>340</integer>
+// CHECK-NEXT:            <key>col</key><integer>27</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>340</integer>
-// CHECK-NEXT:       <key>col</key><integer>3</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>
@@ -2856,23 +2527,316 @@
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
 // CHECK-NEXT:          <key>line</key><integer>340</integer>
-// CHECK-NEXT:          <key>col</key><integer>3</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>340</integer>
+// CHECK-NEXT:          <key>col</key><integer>32</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>Reference-counted object is used after it is released</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Reference-counted object is used after it is released</string>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:    </array>
+// CHECK-NEXT:    <key>description</key><string>Reference-counted object is used after it is released</string>
+// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK-NEXT:    <key>type</key><string>Use-after-release</string>
+// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT:   <key>issue_context</key><string>f1</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>7</string>
+// CHECK-NEXT:   <key>location</key>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>line</key><integer>340</integer>
+// CHECK-NEXT:    <key>col</key><integer>7</integer>
+// CHECK-NEXT:    <key>file</key><integer>0</integer>
+// CHECK-NEXT:   </dict>
+// CHECK-NEXT:   </dict>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>path</key>
+// CHECK-NEXT:    <array>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>control</string>
+// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:       <array>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>345</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>345</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>346</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>346</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>346</integer>
+// CHECK-NEXT:       <key>col</key><integer>20</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>346</integer>
+// CHECK-NEXT:          <key>col</key><integer>20</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>346</integer>
+// CHECK-NEXT:          <key>col</key><integer>37</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>Call to function &apos;CFDateCreate&apos; returns a Core Foundation object 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:     </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>346</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>346</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>347</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>347</integer>
+// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>347</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>347</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>347</integer>
+// CHECK-NEXT:          <key>col</key><integer>27</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>347</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>347</integer>
+// CHECK-NEXT:          <key>col</key><integer>19</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>Reference count incremented. The object now has a +2 retain count</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Reference count incremented. The object now has a +2 retain count</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>347</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>347</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>348</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>348</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>348</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>348</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>348</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:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>348</integer>
+// CHECK-NEXT:          <key>col</key><integer>13</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>348</integer>
+// CHECK-NEXT:          <key>col</key><integer>16</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Reference count decremented. The object now has a +1 retain count</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Reference count decremented. The object now has a +1 retain count</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>348</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>348</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>350</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>350</integer>
+// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>350</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>350</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>350</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:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>340</integer>
+// CHECK-NEXT:          <key>line</key><integer>350</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>340</integer>
+// CHECK-NEXT:          <key>line</key><integer>350</integer>
 // CHECK-NEXT:          <key>col</key><integer>19</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -2892,12 +2856,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>340</integer>
+// CHECK-NEXT:            <key>line</key><integer>350</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>340</integer>
+// CHECK-NEXT:            <key>line</key><integer>350</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -2905,12 +2869,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>341</integer>
+// CHECK-NEXT:            <key>line</key><integer>351</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>341</integer>
+// CHECK-NEXT:            <key>line</key><integer>351</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -2926,12 +2890,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>341</integer>
+// CHECK-NEXT:            <key>line</key><integer>351</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>341</integer>
+// CHECK-NEXT:            <key>line</key><integer>351</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -2939,12 +2903,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>341</integer>
+// CHECK-NEXT:            <key>line</key><integer>351</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>341</integer>
+// CHECK-NEXT:            <key>line</key><integer>351</integer>
 // CHECK-NEXT:            <key>col</key><integer>27</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -2956,7 +2920,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>341</integer>
+// CHECK-NEXT:       <key>line</key><integer>351</integer>
 // CHECK-NEXT:       <key>col</key><integer>7</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -2964,12 +2928,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>341</integer>
+// CHECK-NEXT:          <key>line</key><integer>351</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>341</integer>
+// CHECK-NEXT:          <key>line</key><integer>351</integer>
 // CHECK-NEXT:          <key>col</key><integer>32</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -2990,7 +2954,7 @@
 // CHECK-NEXT:   <key>issue_hash</key><string>7</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>341</integer>
+// CHECK-NEXT:    <key>line</key><integer>351</integer>
 // CHECK-NEXT:    <key>col</key><integer>7</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -3006,12 +2970,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>371</integer>
+// CHECK-NEXT:            <key>line</key><integer>381</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>371</integer>
+// CHECK-NEXT:            <key>line</key><integer>381</integer>
 // CHECK-NEXT:            <key>col</key><integer>16</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -3019,12 +2983,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>372</integer>
+// CHECK-NEXT:            <key>line</key><integer>382</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>372</integer>
+// CHECK-NEXT:            <key>line</key><integer>382</integer>
 // CHECK-NEXT:            <key>col</key><integer>11</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -3033,44 +2997,10 @@
 // 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>372</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>372</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>372</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>372</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>line</key><integer>372</integer>
+// CHECK-NEXT:       <key>line</key><integer>382</integer>
 // CHECK-NEXT:       <key>col</key><integer>20</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -3078,12 +3008,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>372</integer>
+// CHECK-NEXT:          <key>line</key><integer>382</integer>
 // CHECK-NEXT:          <key>col</key><integer>20</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>372</integer>
+// CHECK-NEXT:          <key>line</key><integer>382</integer>
 // CHECK-NEXT:          <key>col</key><integer>37</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -3103,25 +3033,25 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>372</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
+// CHECK-NEXT:            <key>line</key><integer>382</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>372</integer>
-// CHECK-NEXT:            <key>col</key><integer>31</integer>
+// CHECK-NEXT:            <key>line</key><integer>382</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>374</integer>
+// CHECK-NEXT:            <key>line</key><integer>384</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>374</integer>
+// CHECK-NEXT:            <key>line</key><integer>384</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -3137,12 +3067,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>374</integer>
+// CHECK-NEXT:            <key>line</key><integer>384</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>374</integer>
+// CHECK-NEXT:            <key>line</key><integer>384</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -3150,12 +3080,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>374</integer>
+// CHECK-NEXT:            <key>line</key><integer>384</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>374</integer>
+// CHECK-NEXT:            <key>line</key><integer>384</integer>
 // CHECK-NEXT:            <key>col</key><integer>7</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -3167,7 +3097,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>374</integer>
+// CHECK-NEXT:       <key>line</key><integer>384</integer>
 // CHECK-NEXT:       <key>col</key><integer>7</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -3175,12 +3105,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>374</integer>
+// CHECK-NEXT:          <key>line</key><integer>384</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>374</integer>
+// CHECK-NEXT:          <key>line</key><integer>384</integer>
 // CHECK-NEXT:          <key>col</key><integer>7</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -3200,12 +3130,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>374</integer>
+// CHECK-NEXT:            <key>line</key><integer>384</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>374</integer>
+// CHECK-NEXT:            <key>line</key><integer>384</integer>
 // CHECK-NEXT:            <key>col</key><integer>7</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -3213,12 +3143,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>377</integer>
+// CHECK-NEXT:            <key>line</key><integer>387</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>377</integer>
+// CHECK-NEXT:            <key>line</key><integer>387</integer>
 // CHECK-NEXT:            <key>col</key><integer>8</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -3234,12 +3164,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>377</integer>
+// CHECK-NEXT:            <key>line</key><integer>387</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>377</integer>
+// CHECK-NEXT:            <key>line</key><integer>387</integer>
 // CHECK-NEXT:            <key>col</key><integer>8</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -3247,12 +3177,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>377</integer>
+// CHECK-NEXT:            <key>line</key><integer>387</integer>
 // CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>377</integer>
+// CHECK-NEXT:            <key>line</key><integer>387</integer>
 // CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -3264,7 +3194,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>377</integer>
+// CHECK-NEXT:       <key>line</key><integer>387</integer>
 // CHECK-NEXT:       <key>col</key><integer>10</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -3272,12 +3202,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>377</integer>
+// CHECK-NEXT:          <key>line</key><integer>387</integer>
 // CHECK-NEXT:          <key>col</key><integer>10</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>377</integer>
+// CHECK-NEXT:          <key>line</key><integer>387</integer>
 // CHECK-NEXT:          <key>col</key><integer>10</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -3295,10 +3225,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>f5</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>7</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>2</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>377</integer>
+// CHECK-NEXT:    <key>line</key><integer>387</integer>
 // CHECK-NEXT:    <key>col</key><integer>10</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -3307,44 +3237,10 @@
 // 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>383</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>383</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>383</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>383</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>line</key><integer>383</integer>
+// CHECK-NEXT:       <key>line</key><integer>393</integer>
 // CHECK-NEXT:       <key>col</key><integer>20</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -3352,12 +3248,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>383</integer>
+// CHECK-NEXT:          <key>line</key><integer>393</integer>
 // CHECK-NEXT:          <key>col</key><integer>20</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>383</integer>
+// CHECK-NEXT:          <key>line</key><integer>393</integer>
 // CHECK-NEXT:          <key>col</key><integer>62</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -3377,227 +3273,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>383</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>383</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>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>384</integer>
+// CHECK-NEXT:            <key>line</key><integer>393</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>384</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>384</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>384</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>384</integer>
-// CHECK-NEXT:          <key>col</key><integer>16</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>384</integer>
-// CHECK-NEXT:          <key>col</key><integer>12</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>384</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>Reference count incremented. The object now has a +2 retain count</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Reference count incremented. The object now has a +2 retain count</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>384</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>384</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>385</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>385</integer>
-// CHECK-NEXT:            <key>col</key><integer>8</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>385</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>385</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>385</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:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>385</integer>
-// CHECK-NEXT:          <key>col</key><integer>10</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>385</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:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Object returned to caller as an owning reference (single retain count transferred to caller)</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Object returned to caller as an owning reference (single retain count transferred to caller)</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>385</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>385</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>386</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>386</integer>
-// CHECK-NEXT:            <key>col</key><integer>1</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </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>386</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>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;date&apos; is not referenced later in this execution path and has a retain count of +1</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;date&apos; is not referenced later in this execution path and has a retain count of +1</string>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:    </array>
-// CHECK-NEXT:    <key>description</key><string>Potential leak of an object stored into &apos;date&apos;</string>
-// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
-// CHECK-NEXT:    <key>type</key><string>Leak</string>
-// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT:   <key>issue_context</key><string>f6</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>4</string>
-// CHECK-NEXT:   <key>location</key>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>386</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:   <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>391</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>391</integer>
+// CHECK-NEXT:            <key>line</key><integer>393</integer>
 // CHECK-NEXT:            <key>col</key><integer>11</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -3605,151 +3286,13 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>391</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>391</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>line</key><integer>391</integer>
-// CHECK-NEXT:       <key>col</key><integer>20</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>391</integer>
-// CHECK-NEXT:          <key>col</key><integer>20</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>391</integer>
-// CHECK-NEXT:          <key>col</key><integer>62</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>Call to function &apos;CFDateCreate&apos; returns a Core Foundation object 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:     </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>391</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>391</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>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>392</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>392</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>392</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>392</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>392</integer>
-// CHECK-NEXT:          <key>col</key><integer>16</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>392</integer>
-// CHECK-NEXT:          <key>col</key><integer>12</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>392</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>Reference count incremented. The object now has a +2 retain count</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Reference count incremented. The object now has a +2 retain count</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>392</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>392</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
 // CHECK-NEXT:            <key>line</key><integer>394</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>394</integer>
-// CHECK-NEXT:            <key>col</key><integer>8</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
@@ -3774,6 +3317,325 @@
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
 // CHECK-NEXT:          <key>line</key><integer>394</integer>
+// CHECK-NEXT:          <key>col</key><integer>16</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>394</integer>
+// CHECK-NEXT:          <key>col</key><integer>12</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>394</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>Reference count incremented. The object now has a +2 retain count</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Reference count incremented. The object now has a +2 retain count</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>394</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>394</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>395</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>395</integer>
+// CHECK-NEXT:            <key>col</key><integer>8</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>395</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>395</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>395</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:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>395</integer>
+// CHECK-NEXT:          <key>col</key><integer>10</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>395</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:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Object returned to caller as an owning reference (single retain count transferred to caller)</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Object returned to caller as an owning reference (single retain count transferred to caller)</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>395</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>395</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>396</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>396</integer>
+// CHECK-NEXT:            <key>col</key><integer>1</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </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>396</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>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;date&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;date&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:    </array>
+// CHECK-NEXT:    <key>description</key><string>Potential leak of an object stored into &apos;date&apos;</string>
+// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK-NEXT:    <key>type</key><string>Leak</string>
+// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT:   <key>issue_context</key><string>f6</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>1</string>
+// CHECK-NEXT:   <key>location</key>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>line</key><integer>396</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:   <dict>
+// CHECK-NEXT:    <key>path</key>
+// CHECK-NEXT:    <array>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>401</integer>
+// CHECK-NEXT:       <key>col</key><integer>20</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>401</integer>
+// CHECK-NEXT:          <key>col</key><integer>20</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>401</integer>
+// CHECK-NEXT:          <key>col</key><integer>62</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>Call to function &apos;CFDateCreate&apos; returns a Core Foundation object 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:     </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>401</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>401</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>402</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>402</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>402</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>402</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>402</integer>
+// CHECK-NEXT:          <key>col</key><integer>16</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>402</integer>
+// CHECK-NEXT:          <key>col</key><integer>12</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>402</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>Reference count incremented. The object now has a +2 retain count</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Reference count incremented. The object now has a +2 retain count</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>402</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>402</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>404</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>404</integer>
+// CHECK-NEXT:            <key>col</key><integer>8</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>404</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>404</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>404</integer>
 // CHECK-NEXT:          <key>col</key><integer>13</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -3791,10 +3653,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>f7</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>4</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>1</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>394</integer>
+// CHECK-NEXT:    <key>line</key><integer>404</integer>
 // CHECK-NEXT:    <key>col</key><integer>3</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -3810,12 +3672,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>391</integer>
+// CHECK-NEXT:            <key>line</key><integer>401</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>391</integer>
+// CHECK-NEXT:            <key>line</key><integer>401</integer>
 // CHECK-NEXT:            <key>col</key><integer>11</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -3823,12 +3685,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>393</integer>
+// CHECK-NEXT:            <key>line</key><integer>403</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>393</integer>
+// CHECK-NEXT:            <key>line</key><integer>403</integer>
 // CHECK-NEXT:            <key>col</key><integer>6</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -3837,44 +3699,10 @@
 // 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>393</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>393</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>393</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>393</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:     </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>393</integer>
+// CHECK-NEXT:       <key>line</key><integer>403</integer>
 // CHECK-NEXT:       <key>col</key><integer>10</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -3882,12 +3710,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>393</integer>
+// CHECK-NEXT:          <key>line</key><integer>403</integer>
 // CHECK-NEXT:          <key>col</key><integer>10</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>393</integer>
+// CHECK-NEXT:          <key>line</key><integer>403</integer>
 // CHECK-NEXT:          <key>col</key><integer>52</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -3907,272 +3735,13 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>393</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>393</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>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>394</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>394</integer>
-// CHECK-NEXT:            <key>col</key><integer>8</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>394</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>394</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>394</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:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>394</integer>
-// CHECK-NEXT:          <key>col</key><integer>10</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>394</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:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Object returned to caller as an owning reference (single retain count transferred to caller)</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Object returned to caller as an owning reference (single retain count transferred to caller)</string>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>394</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>394</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>394</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:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;date&apos; is returned from a function whose name (&apos;f7&apos;) does not contain &apos;Copy&apos; or &apos;Create&apos;.  This violates the naming convention rules given in the Memory Management Guide for Core Foundation</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;date&apos; is returned from a function whose name (&apos;f7&apos;) does not contain &apos;Copy&apos; or &apos;Create&apos;.  This violates the naming convention rules given in the Memory Management Guide for Core Foundation</string>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:    </array>
-// CHECK-NEXT:    <key>description</key><string>Potential leak of an object stored into &apos;date&apos;</string>
-// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
-// CHECK-NEXT:    <key>type</key><string>Leak of returned object</string>
-// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT:   <key>issue_context</key><string>f7</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>4</string>
-// CHECK-NEXT:   <key>location</key>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>394</integer>
-// CHECK-NEXT:    <key>col</key><integer>3</integer>
-// CHECK-NEXT:    <key>file</key><integer>0</integer>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>path</key>
-// CHECK-NEXT:    <array>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>402</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>402</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>402</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>402</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>line</key><integer>402</integer>
-// CHECK-NEXT:       <key>col</key><integer>20</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>402</integer>
-// CHECK-NEXT:          <key>col</key><integer>20</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>402</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>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Call to function &apos;MyDateCreate&apos; returns a Core Foundation object with a +1 retain count</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to function &apos;MyDateCreate&apos; returns a Core Foundation object with a +1 retain count</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>402</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>402</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>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
 // CHECK-NEXT:            <key>line</key><integer>403</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>403</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>403</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>403</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>403</integer>
-// CHECK-NEXT:          <key>col</key><integer>16</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>403</integer>
-// CHECK-NEXT:          <key>col</key><integer>12</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>403</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>Reference count incremented. The object now has a +2 retain count</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Reference count incremented. The object now has a +2 retain count</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>403</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>403</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>col</key><integer>6</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
@@ -4234,6 +3803,81 @@
 // CHECK-NEXT:      <string>Object returned to caller as an owning reference (single retain count transferred to caller)</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>404</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>404</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>404</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:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;date&apos; is returned from a function whose name (&apos;f7&apos;) does not contain &apos;Copy&apos; or &apos;Create&apos;.  This violates the naming convention rules given in the Memory Management Guide for Core Foundation</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;date&apos; is returned from a function whose name (&apos;f7&apos;) does not contain &apos;Copy&apos; or &apos;Create&apos;.  This violates the naming convention rules given in the Memory Management Guide for Core Foundation</string>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:    </array>
+// CHECK-NEXT:    <key>description</key><string>Potential leak of an object stored into &apos;date&apos;</string>
+// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK-NEXT:    <key>type</key><string>Leak of returned object</string>
+// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT:   <key>issue_context</key><string>f7</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>3</string>
+// CHECK-NEXT:   <key>location</key>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>line</key><integer>404</integer>
+// CHECK-NEXT:    <key>col</key><integer>3</integer>
+// CHECK-NEXT:    <key>file</key><integer>0</integer>
+// CHECK-NEXT:   </dict>
+// CHECK-NEXT:   </dict>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>path</key>
+// CHECK-NEXT:    <array>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>412</integer>
+// CHECK-NEXT:       <key>col</key><integer>20</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>412</integer>
+// CHECK-NEXT:          <key>col</key><integer>20</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>412</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>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Call to function &apos;MyDateCreate&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Call to function &apos;MyDateCreate&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>control</string>
 // CHECK-NEXT:      <key>edges</key>
 // CHECK-NEXT:       <array>
@@ -4241,12 +3885,162 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>404</integer>
+// CHECK-NEXT:            <key>line</key><integer>412</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>404</integer>
+// CHECK-NEXT:            <key>line</key><integer>412</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>413</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>413</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>413</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>413</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>413</integer>
+// CHECK-NEXT:          <key>col</key><integer>16</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>413</integer>
+// CHECK-NEXT:          <key>col</key><integer>12</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>413</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>Reference count incremented. The object now has a +2 retain count</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Reference count incremented. The object now has a +2 retain count</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>413</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>413</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>414</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>414</integer>
+// CHECK-NEXT:            <key>col</key><integer>8</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>414</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>414</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>414</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:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>414</integer>
+// CHECK-NEXT:          <key>col</key><integer>10</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>414</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:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Object returned to caller as an owning reference (single retain count transferred to caller)</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Object returned to caller as an owning reference (single retain count transferred to caller)</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>414</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>414</integer>
 // CHECK-NEXT:            <key>col</key><integer>8</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -4254,12 +4048,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>405</integer>
+// CHECK-NEXT:            <key>line</key><integer>415</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>405</integer>
+// CHECK-NEXT:            <key>line</key><integer>415</integer>
 // CHECK-NEXT:            <key>col</key><integer>1</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -4271,7 +4065,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>405</integer>
+// CHECK-NEXT:       <key>line</key><integer>415</integer>
 // CHECK-NEXT:       <key>col</key><integer>1</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -4287,10 +4081,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>f8</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>4</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>1</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>405</integer>
+// CHECK-NEXT:    <key>line</key><integer>415</integer>
 // CHECK-NEXT:    <key>col</key><integer>1</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -4306,12 +4100,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>408</integer>
+// CHECK-NEXT:            <key>line</key><integer>418</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>408</integer>
+// CHECK-NEXT:            <key>line</key><integer>418</integer>
 // CHECK-NEXT:            <key>col</key><integer>11</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -4319,12 +4113,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>409</integer>
+// CHECK-NEXT:            <key>line</key><integer>419</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>409</integer>
+// CHECK-NEXT:            <key>line</key><integer>419</integer>
 // CHECK-NEXT:            <key>col</key><integer>5</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -4336,7 +4130,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>409</integer>
+// CHECK-NEXT:       <key>line</key><integer>419</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -4344,12 +4138,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>409</integer>
+// CHECK-NEXT:          <key>line</key><integer>419</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>409</integer>
+// CHECK-NEXT:          <key>line</key><integer>419</integer>
 // CHECK-NEXT:          <key>col</key><integer>8</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -4357,9 +4151,9 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Variable &apos;p&apos; initialized to a null pointer value</string>
+// CHECK-NEXT:      <string>&apos;p&apos; initialized to a null pointer value</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Variable &apos;p&apos; initialized to a null pointer value</string>
+// 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>
@@ -4369,12 +4163,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>409</integer>
+// CHECK-NEXT:            <key>line</key><integer>419</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>409</integer>
+// CHECK-NEXT:            <key>line</key><integer>419</integer>
 // CHECK-NEXT:            <key>col</key><integer>5</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -4382,12 +4176,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>411</integer>
+// CHECK-NEXT:            <key>line</key><integer>421</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>411</integer>
+// CHECK-NEXT:            <key>line</key><integer>421</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -4403,12 +4197,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>411</integer>
+// CHECK-NEXT:            <key>line</key><integer>421</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>411</integer>
+// CHECK-NEXT:            <key>line</key><integer>421</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -4416,12 +4210,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>411</integer>
+// CHECK-NEXT:            <key>line</key><integer>421</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>411</integer>
+// CHECK-NEXT:            <key>line</key><integer>421</integer>
 // CHECK-NEXT:            <key>col</key><integer>7</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -4433,7 +4227,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>411</integer>
+// CHECK-NEXT:       <key>line</key><integer>421</integer>
 // CHECK-NEXT:       <key>col</key><integer>7</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -4441,12 +4235,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>411</integer>
+// CHECK-NEXT:          <key>line</key><integer>421</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>411</integer>
+// CHECK-NEXT:          <key>line</key><integer>421</integer>
 // CHECK-NEXT:          <key>col</key><integer>11</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -4466,12 +4260,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>411</integer>
+// CHECK-NEXT:            <key>line</key><integer>421</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>411</integer>
+// CHECK-NEXT:            <key>line</key><integer>421</integer>
 // CHECK-NEXT:            <key>col</key><integer>7</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -4479,12 +4273,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>411</integer>
+// CHECK-NEXT:            <key>line</key><integer>421</integer>
 // CHECK-NEXT:            <key>col</key><integer>14</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>411</integer>
+// CHECK-NEXT:            <key>line</key><integer>421</integer>
 // CHECK-NEXT:            <key>col</key><integer>14</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -4493,23 +4287,57 @@
 // 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>421</integer>
+// CHECK-NEXT:            <key>col</key><integer>14</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>421</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>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>421</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>421</integer>
+// CHECK-NEXT:            <key>col</key><integer>17</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>411</integer>
-// CHECK-NEXT:       <key>col</key><integer>14</integer>
+// CHECK-NEXT:       <key>line</key><integer>421</integer>
+// CHECK-NEXT:       <key>col</key><integer>17</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>411</integer>
+// CHECK-NEXT:          <key>line</key><integer>421</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>411</integer>
+// CHECK-NEXT:          <key>line</key><integer>421</integer>
 // CHECK-NEXT:          <key>col</key><integer>15</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -4530,8 +4358,8 @@
 // CHECK-NEXT:   <key>issue_hash</key><string>4</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>411</integer>
-// CHECK-NEXT:    <key>col</key><integer>14</integer>
+// CHECK-NEXT:    <key>line</key><integer>421</integer>
+// CHECK-NEXT:    <key>col</key><integer>17</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
 // CHECK-NEXT:   </dict>
@@ -4539,44 +4367,10 @@
 // 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>420</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>420</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>420</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>420</integer>
-// CHECK-NEXT:            <key>col</key><integer>42</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>420</integer>
+// CHECK-NEXT:       <key>line</key><integer>430</integer>
 // CHECK-NEXT:       <key>col</key><integer>20</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -4584,12 +4378,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>420</integer>
+// CHECK-NEXT:          <key>line</key><integer>430</integer>
 // CHECK-NEXT:          <key>col</key><integer>20</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>420</integer>
+// CHECK-NEXT:          <key>line</key><integer>430</integer>
 // CHECK-NEXT:          <key>col</key><integer>75</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -4609,388 +4403,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>420</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>420</integer>
-// CHECK-NEXT:            <key>col</key><integer>42</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>421</integer>
+// CHECK-NEXT:            <key>line</key><integer>430</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>421</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>421</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>421</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>421</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>421</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>421</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>421</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>421</integer>
-// CHECK-NEXT:          <key>col</key><integer>10</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is non-null</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Assuming &apos;disk&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:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>421</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>421</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>421</integer>
-// CHECK-NEXT:            <key>col</key><integer>13</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>421</integer>
-// CHECK-NEXT:            <key>col</key><integer>17</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>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>421</integer>
-// CHECK-NEXT:            <key>col</key><integer>13</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>421</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>423</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>423</integer>
-// CHECK-NEXT:            <key>col</key><integer>6</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>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>423</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>423</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>424</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>424</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>424</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>424</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>424</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>424</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>424</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>424</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>424</integer>
-// CHECK-NEXT:          <key>col</key><integer>10</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is null</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is 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:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>424</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>424</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>426</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>426</integer>
-// CHECK-NEXT:            <key>col</key><integer>17</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>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>426</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>426</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>426</integer>
-// CHECK-NEXT:            <key>col</key><integer>48</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>426</integer>
-// CHECK-NEXT:            <key>col</key><integer>48</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>426</integer>
-// CHECK-NEXT:       <key>col</key><integer>48</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>426</integer>
-// CHECK-NEXT:          <key>col</key><integer>48</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>426</integer>
-// CHECK-NEXT:          <key>col</key><integer>48</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>Object leaked: object allocated and stored into &apos;disk&apos; is not referenced later in this execution path and has a retain count of +1</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;disk&apos; is not referenced later in this execution path and has a retain count of +1</string>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:    </array>
-// CHECK-NEXT:    <key>description</key><string>Potential leak of an object stored into &apos;disk&apos;</string>
-// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
-// CHECK-NEXT:    <key>type</key><string>Leak</string>
-// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT:   <key>issue_context</key><string>f10</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>7</string>
-// CHECK-NEXT:   <key>location</key>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>426</integer>
-// CHECK-NEXT:    <key>col</key><integer>48</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>420</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>420</integer>
+// CHECK-NEXT:            <key>line</key><integer>430</integer>
 // CHECK-NEXT:            <key>col</key><integer>11</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -4998,12 +4416,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>421</integer>
+// CHECK-NEXT:            <key>line</key><integer>431</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>421</integer>
+// CHECK-NEXT:            <key>line</key><integer>431</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -5019,12 +4437,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>421</integer>
+// CHECK-NEXT:            <key>line</key><integer>431</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>421</integer>
+// CHECK-NEXT:            <key>line</key><integer>431</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -5032,12 +4450,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>421</integer>
+// CHECK-NEXT:            <key>line</key><integer>431</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>421</integer>
+// CHECK-NEXT:            <key>line</key><integer>431</integer>
 // CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -5049,7 +4467,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>421</integer>
+// CHECK-NEXT:       <key>line</key><integer>431</integer>
 // CHECK-NEXT:       <key>col</key><integer>7</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -5057,1004 +4475,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>421</integer>
+// CHECK-NEXT:          <key>line</key><integer>431</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>421</integer>
-// CHECK-NEXT:          <key>col</key><integer>10</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is null</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is 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:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>421</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>421</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>423</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>423</integer>
-// CHECK-NEXT:            <key>col</key><integer>6</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>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>423</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>423</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>424</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>424</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>424</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>424</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>424</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>424</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>424</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>424</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>424</integer>
-// CHECK-NEXT:          <key>col</key><integer>10</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is null</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is 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:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>424</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>424</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>426</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>426</integer>
-// CHECK-NEXT:            <key>col</key><integer>17</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>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>426</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>426</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>426</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>426</integer>
-// CHECK-NEXT:            <key>col</key><integer>46</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>426</integer>
-// CHECK-NEXT:       <key>col</key><integer>26</integer>
-// CHECK-NEXT:       <key>file</key><integer>0</integer>
-// CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>ranges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>426</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>426</integer>
-// CHECK-NEXT:          <key>col</key><integer>49</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>Call to function &apos;DADiskCopyDescription&apos; returns a Core Foundation object with a +1 retain count</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to function &apos;DADiskCopyDescription&apos; returns a Core Foundation object with a +1 retain count</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>426</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>426</integer>
-// CHECK-NEXT:            <key>col</key><integer>46</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>427</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>427</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>427</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>427</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>427</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>427</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>427</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>427</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>427</integer>
-// CHECK-NEXT:          <key>col</key><integer>10</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Assuming &apos;dict&apos; is non-null</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Assuming &apos;dict&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:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>427</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>427</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>427</integer>
-// CHECK-NEXT:            <key>col</key><integer>13</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>427</integer>
-// CHECK-NEXT:            <key>col</key><integer>17</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>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>427</integer>
-// CHECK-NEXT:            <key>col</key><integer>13</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>427</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>427</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>427</integer>
-// CHECK-NEXT:            <key>col</key><integer>23</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </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>427</integer>
-// CHECK-NEXT:       <key>col</key><integer>20</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>427</integer>
-// CHECK-NEXT:          <key>col</key><integer>20</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>427</integer>
-// CHECK-NEXT:          <key>col</key><integer>23</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;dict&apos; is not referenced later in this execution path and has a retain count of +1</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;dict&apos; is not referenced later in this execution path and has a retain count of +1</string>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:    </array>
-// CHECK-NEXT:    <key>description</key><string>Potential leak of an object stored into &apos;dict&apos;</string>
-// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
-// CHECK-NEXT:    <key>type</key><string>Leak</string>
-// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT:   <key>issue_context</key><string>f10</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>8</string>
-// CHECK-NEXT:   <key>location</key>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>427</integer>
-// CHECK-NEXT:    <key>col</key><integer>20</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>420</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>420</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>421</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>421</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>421</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>421</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>421</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>421</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>421</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>421</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>421</integer>
-// CHECK-NEXT:          <key>col</key><integer>10</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is null</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is 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:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>421</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>421</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>423</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>423</integer>
-// CHECK-NEXT:            <key>col</key><integer>6</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>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>423</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>423</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>424</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>424</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>424</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>424</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>424</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>424</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>424</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>424</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>424</integer>
-// CHECK-NEXT:          <key>col</key><integer>10</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is null</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is 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:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>424</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>424</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>426</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>426</integer>
-// CHECK-NEXT:            <key>col</key><integer>17</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>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>426</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>426</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>427</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>427</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>427</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>427</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>427</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>427</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>427</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>427</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>427</integer>
-// CHECK-NEXT:          <key>col</key><integer>10</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Assuming &apos;dict&apos; is null</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Assuming &apos;dict&apos; is 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:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>427</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>427</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>429</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>429</integer>
-// CHECK-NEXT:            <key>col</key><integer>6</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>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>429</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>429</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>429</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>429</integer>
-// CHECK-NEXT:            <key>col</key><integer>28</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>429</integer>
-// CHECK-NEXT:       <key>col</key><integer>10</integer>
-// CHECK-NEXT:       <key>file</key><integer>0</integer>
-// CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>ranges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>429</integer>
-// CHECK-NEXT:          <key>col</key><integer>10</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>429</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:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Call to function &apos;DADiskCopyWholeDisk&apos; returns a Core Foundation object with a +1 retain count</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to function &apos;DADiskCopyWholeDisk&apos; returns a Core Foundation object with a +1 retain count</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>429</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>429</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:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>430</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>430</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>430</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>430</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>430</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>430</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>430</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>430</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>430</integer>
+// CHECK-NEXT:          <key>line</key><integer>431</integer>
 // CHECK-NEXT:          <key>col</key><integer>10</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -6074,12 +4500,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>430</integer>
+// CHECK-NEXT:            <key>line</key><integer>431</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>430</integer>
+// CHECK-NEXT:            <key>line</key><integer>431</integer>
 // CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -6087,12 +4513,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>430</integer>
+// CHECK-NEXT:            <key>line</key><integer>431</integer>
 // CHECK-NEXT:            <key>col</key><integer>13</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>430</integer>
+// CHECK-NEXT:            <key>line</key><integer>431</integer>
 // CHECK-NEXT:            <key>col</key><integer>17</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -6108,12 +4534,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>430</integer>
+// CHECK-NEXT:            <key>line</key><integer>431</integer>
 // CHECK-NEXT:            <key>col</key><integer>13</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>430</integer>
+// CHECK-NEXT:            <key>line</key><integer>431</integer>
 // CHECK-NEXT:            <key>col</key><integer>17</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -6121,890 +4547,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>430</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>430</integer>
-// CHECK-NEXT:            <key>col</key><integer>23</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </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>430</integer>
-// CHECK-NEXT:       <key>col</key><integer>20</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>430</integer>
-// CHECK-NEXT:          <key>col</key><integer>20</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>430</integer>
-// CHECK-NEXT:          <key>col</key><integer>23</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;disk&apos; is not referenced later in this execution path and has a retain count of +1</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;disk&apos; is not referenced later in this execution path and has a retain count of +1</string>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:    </array>
-// CHECK-NEXT:    <key>description</key><string>Potential leak of an object stored into &apos;disk&apos;</string>
-// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
-// CHECK-NEXT:    <key>type</key><string>Leak</string>
-// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT:   <key>issue_context</key><string>f10</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>11</string>
-// CHECK-NEXT:   <key>location</key>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>430</integer>
-// CHECK-NEXT:    <key>col</key><integer>20</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>420</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>420</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>421</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>421</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>421</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>421</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>421</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>421</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>421</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>421</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>421</integer>
-// CHECK-NEXT:          <key>col</key><integer>10</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is null</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is 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:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>421</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>421</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>423</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>423</integer>
-// CHECK-NEXT:            <key>col</key><integer>6</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>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>423</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>423</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>423</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>423</integer>
-// CHECK-NEXT:            <key>col</key><integer>32</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>423</integer>
-// CHECK-NEXT:       <key>col</key><integer>10</integer>
-// CHECK-NEXT:       <key>file</key><integer>0</integer>
-// CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>ranges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>423</integer>
-// CHECK-NEXT:          <key>col</key><integer>10</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>423</integer>
-// CHECK-NEXT:          <key>col</key><integer>63</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>Call to function &apos;DADiskCreateFromIOMedia&apos; returns a Core Foundation object with a +1 retain count</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to function &apos;DADiskCreateFromIOMedia&apos; returns a Core Foundation object with a +1 retain count</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>423</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>423</integer>
-// CHECK-NEXT:            <key>col</key><integer>32</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>424</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>424</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>424</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>424</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>424</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>424</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>424</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>424</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>424</integer>
-// CHECK-NEXT:          <key>col</key><integer>10</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is non-null</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Assuming &apos;disk&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:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>424</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>424</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>424</integer>
-// CHECK-NEXT:            <key>col</key><integer>13</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>424</integer>
-// CHECK-NEXT:            <key>col</key><integer>17</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>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>424</integer>
-// CHECK-NEXT:            <key>col</key><integer>13</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>424</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>426</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>426</integer>
-// CHECK-NEXT:            <key>col</key><integer>17</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>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>426</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>426</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>427</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>427</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>427</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>427</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>427</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>427</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>427</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>427</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>427</integer>
-// CHECK-NEXT:          <key>col</key><integer>10</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Assuming &apos;dict&apos; is null</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Assuming &apos;dict&apos; is 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:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>427</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>427</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>429</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>429</integer>
-// CHECK-NEXT:            <key>col</key><integer>6</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>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>429</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>429</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>430</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>430</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>430</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>430</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>430</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>430</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>430</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>430</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>430</integer>
-// CHECK-NEXT:          <key>col</key><integer>10</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is null</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is 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:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>430</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>430</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>432</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>432</integer>
-// CHECK-NEXT:            <key>col</key><integer>16</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>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>432</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>432</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>433</integer>
-// CHECK-NEXT:            <key>col</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>433</integer>
-// CHECK-NEXT:            <key>col</key><integer>67</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>433</integer>
-// CHECK-NEXT:       <key>col</key><integer>67</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>433</integer>
-// CHECK-NEXT:          <key>col</key><integer>67</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>433</integer>
-// CHECK-NEXT:          <key>col</key><integer>67</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>Object leaked: object allocated and stored into &apos;disk&apos; is not referenced later in this execution path and has a retain count of +1</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;disk&apos; is not referenced later in this execution path and has a retain count of +1</string>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:    </array>
-// CHECK-NEXT:    <key>description</key><string>Potential leak of an object stored into &apos;disk&apos;</string>
-// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
-// CHECK-NEXT:    <key>type</key><string>Leak</string>
-// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT:   <key>issue_context</key><string>f10</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>14</string>
-// CHECK-NEXT:   <key>location</key>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>433</integer>
-// CHECK-NEXT:    <key>col</key><integer>67</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>420</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>420</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>421</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>421</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>421</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>421</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>421</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>421</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>421</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>421</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>421</integer>
-// CHECK-NEXT:          <key>col</key><integer>10</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is null</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is 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:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>421</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>421</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>423</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>423</integer>
 // CHECK-NEXT:            <key>col</key><integer>6</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -7020,12 +4568,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>423</integer>
+// CHECK-NEXT:            <key>line</key><integer>433</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>423</integer>
+// CHECK-NEXT:            <key>line</key><integer>433</integer>
 // CHECK-NEXT:            <key>col</key><integer>6</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -7033,462 +4581,6 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>424</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>424</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>424</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>424</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>424</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>424</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>424</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>424</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>424</integer>
-// CHECK-NEXT:          <key>col</key><integer>10</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is null</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is 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:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>424</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>424</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>426</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>426</integer>
-// CHECK-NEXT:            <key>col</key><integer>17</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>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>426</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>426</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>427</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>427</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>427</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>427</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>427</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>427</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>427</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>427</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>427</integer>
-// CHECK-NEXT:          <key>col</key><integer>10</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Assuming &apos;dict&apos; is null</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Assuming &apos;dict&apos; is 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:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>427</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>427</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>429</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>429</integer>
-// CHECK-NEXT:            <key>col</key><integer>6</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>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>429</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>429</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>430</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>430</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>430</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>430</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>430</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>430</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>430</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>430</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>430</integer>
-// CHECK-NEXT:          <key>col</key><integer>10</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is null</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is 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:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>430</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>430</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>432</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>432</integer>
-// CHECK-NEXT:            <key>col</key><integer>16</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>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>432</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>432</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>432</integer>
-// CHECK-NEXT:            <key>col</key><integer>30</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>432</integer>
-// CHECK-NEXT:            <key>col</key><integer>46</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>432</integer>
-// CHECK-NEXT:       <key>col</key><integer>30</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>432</integer>
-// CHECK-NEXT:          <key>col</key><integer>30</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>433</integer>
-// CHECK-NEXT:          <key>col</key><integer>68</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>Call to function &apos;DADissenterCreate&apos; returns a Core Foundation object with a +1 retain count</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to function &apos;DADissenterCreate&apos; returns a Core Foundation object with a +1 retain count</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>432</integer>
-// CHECK-NEXT:            <key>col</key><integer>30</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>432</integer>
-// CHECK-NEXT:            <key>col</key><integer>46</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>434</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
@@ -7529,7 +4621,7 @@
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
 // CHECK-NEXT:            <key>line</key><integer>434</integer>
-// CHECK-NEXT:            <key>col</key><integer>15</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
@@ -7554,217 +4646,6 @@
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
 // CHECK-NEXT:          <key>line</key><integer>434</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;dissenter&apos; is non-null</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Assuming &apos;dissenter&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:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>434</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>434</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>434</integer>
-// CHECK-NEXT:            <key>col</key><integer>18</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>434</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:     </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>434</integer>
-// CHECK-NEXT:            <key>col</key><integer>18</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>434</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>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>434</integer>
-// CHECK-NEXT:            <key>col</key><integer>25</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>434</integer>
-// CHECK-NEXT:            <key>col</key><integer>28</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>434</integer>
-// CHECK-NEXT:       <key>col</key><integer>25</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>434</integer>
-// CHECK-NEXT:          <key>col</key><integer>25</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>434</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>Object leaked: object allocated and stored into &apos;dissenter&apos; is not referenced later in this execution path and has a retain count of +1</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;dissenter&apos; is not referenced later in this execution path and has a retain count of +1</string>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:    </array>
-// CHECK-NEXT:    <key>description</key><string>Potential leak of an object stored into &apos;dissenter&apos;</string>
-// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
-// CHECK-NEXT:    <key>type</key><string>Leak</string>
-// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT:   <key>issue_context</key><string>f10</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>15</string>
-// CHECK-NEXT:   <key>location</key>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>434</integer>
-// CHECK-NEXT:    <key>col</key><integer>25</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>420</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>420</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>421</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>421</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>421</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>421</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>421</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>421</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>421</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>421</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>421</integer>
 // CHECK-NEXT:          <key>col</key><integer>10</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -7784,12 +4665,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>421</integer>
+// CHECK-NEXT:            <key>line</key><integer>434</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>421</integer>
+// CHECK-NEXT:            <key>line</key><integer>434</integer>
 // CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -7797,143 +4678,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>423</integer>
+// CHECK-NEXT:            <key>line</key><integer>436</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>423</integer>
-// CHECK-NEXT:            <key>col</key><integer>6</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>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>423</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>423</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>424</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>424</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>424</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>424</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>424</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>424</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>424</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>424</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>424</integer>
-// CHECK-NEXT:          <key>col</key><integer>10</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is null</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is 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:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>424</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>424</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>426</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>426</integer>
+// CHECK-NEXT:            <key>line</key><integer>436</integer>
 // CHECK-NEXT:            <key>col</key><integer>17</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -7949,12 +4699,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>426</integer>
+// CHECK-NEXT:            <key>line</key><integer>436</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>426</integer>
+// CHECK-NEXT:            <key>line</key><integer>436</integer>
 // CHECK-NEXT:            <key>col</key><integer>17</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -7962,406 +4712,13 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>427</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>427</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>427</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>427</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>427</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>427</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>427</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>427</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>427</integer>
-// CHECK-NEXT:          <key>col</key><integer>10</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Assuming &apos;dict&apos; is null</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Assuming &apos;dict&apos; is 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:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>427</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>427</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>429</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>429</integer>
-// CHECK-NEXT:            <key>col</key><integer>6</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>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>429</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>429</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>430</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>430</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>430</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>430</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>430</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>430</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>430</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>430</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>430</integer>
-// CHECK-NEXT:          <key>col</key><integer>10</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is null</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is 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:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>430</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>430</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>432</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>432</integer>
-// CHECK-NEXT:            <key>col</key><integer>16</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>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>432</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>432</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>434</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>434</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>434</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>434</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>434</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>434</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>434</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>434</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>434</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;dissenter&apos; is null</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Assuming &apos;dissenter&apos; is 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:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>434</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>434</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>436</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>436</integer>
-// CHECK-NEXT:            <key>col</key><integer>14</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>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>436</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>436</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>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
 // CHECK-NEXT:            <key>line</key><integer>436</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>436</integer>
-// CHECK-NEXT:            <key>col</key><integer>40</integer>
+// CHECK-NEXT:            <key>col</key><integer>46</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
@@ -8386,16 +4743,324 @@
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
 // CHECK-NEXT:          <key>line</key><integer>436</integer>
-// CHECK-NEXT:          <key>col</key><integer>61</integer>
+// CHECK-NEXT:          <key>col</key><integer>46</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>Call to function &apos;DASessionCreate&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;disk&apos; is not referenced later in this execution path and has a retain count of +1</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to function &apos;DASessionCreate&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;disk&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:    </array>
+// CHECK-NEXT:    <key>description</key><string>Potential leak of an object stored into &apos;disk&apos;</string>
+// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK-NEXT:    <key>type</key><string>Leak</string>
+// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT:   <key>issue_context</key><string>f10</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>1</string>
+// CHECK-NEXT:   <key>location</key>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>line</key><integer>436</integer>
+// CHECK-NEXT:    <key>col</key><integer>26</integer>
+// CHECK-NEXT:    <key>file</key><integer>0</integer>
+// CHECK-NEXT:   </dict>
+// CHECK-NEXT:   </dict>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>path</key>
+// CHECK-NEXT:    <array>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>control</string>
+// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:       <array>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>430</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>430</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>431</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>431</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>431</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>431</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>431</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>431</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>431</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>431</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>431</integer>
+// CHECK-NEXT:          <key>col</key><integer>10</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is null</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is 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:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>431</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>431</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>433</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>433</integer>
+// CHECK-NEXT:            <key>col</key><integer>6</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>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>433</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>433</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>434</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>434</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>434</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>434</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>434</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>434</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>434</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>434</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>434</integer>
+// CHECK-NEXT:          <key>col</key><integer>10</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is null</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is 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:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>434</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>434</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>436</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>436</integer>
+// CHECK-NEXT:            <key>col</key><integer>17</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>436</integer>
+// CHECK-NEXT:       <key>col</key><integer>26</integer>
+// CHECK-NEXT:       <key>file</key><integer>0</integer>
+// CHECK-NEXT:      </dict>
+// CHECK-NEXT:      <key>ranges</key>
+// CHECK-NEXT:      <array>
+// CHECK-NEXT:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>436</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>436</integer>
+// CHECK-NEXT:          <key>col</key><integer>49</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>Call to function &apos;DADiskCopyDescription&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Call to function &apos;DADiskCopyDescription&apos; returns a Core Foundation object with a +1 retain count</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>control</string>
@@ -8406,12 +5071,12 @@
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
 // CHECK-NEXT:            <key>line</key><integer>436</integer>
-// CHECK-NEXT:            <key>col</key><integer>26</integer>
+// CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
 // CHECK-NEXT:            <key>line</key><integer>436</integer>
-// CHECK-NEXT:            <key>col</key><integer>40</integer>
+// CHECK-NEXT:            <key>col</key><integer>17</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
@@ -8458,7 +5123,7 @@
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
 // CHECK-NEXT:            <key>line</key><integer>437</integer>
-// CHECK-NEXT:            <key>col</key><integer>13</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
@@ -8483,6 +5148,2931 @@
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
 // CHECK-NEXT:          <key>line</key><integer>437</integer>
+// CHECK-NEXT:          <key>col</key><integer>10</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Assuming &apos;dict&apos; is non-null</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Assuming &apos;dict&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:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>437</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>437</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>437</integer>
+// CHECK-NEXT:            <key>col</key><integer>13</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>437</integer>
+// CHECK-NEXT:            <key>col</key><integer>17</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>437</integer>
+// CHECK-NEXT:       <key>col</key><integer>13</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>437</integer>
+// CHECK-NEXT:          <key>col</key><integer>13</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>437</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:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;dict&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;dict&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:    </array>
+// CHECK-NEXT:    <key>description</key><string>Potential leak of an object stored into &apos;dict&apos;</string>
+// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK-NEXT:    <key>type</key><string>Leak</string>
+// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT:   <key>issue_context</key><string>f10</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>7</string>
+// CHECK-NEXT:   <key>location</key>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>line</key><integer>437</integer>
+// CHECK-NEXT:    <key>col</key><integer>13</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>430</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>430</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>431</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>431</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>431</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>431</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>431</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>431</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>431</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>431</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>431</integer>
+// CHECK-NEXT:          <key>col</key><integer>10</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is null</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is 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:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>431</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>431</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>433</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>433</integer>
+// CHECK-NEXT:            <key>col</key><integer>6</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>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>433</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>433</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>434</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>434</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>434</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>434</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>434</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>434</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>434</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>434</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>434</integer>
+// CHECK-NEXT:          <key>col</key><integer>10</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is null</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is 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:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>434</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>434</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>436</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>436</integer>
+// CHECK-NEXT:            <key>col</key><integer>17</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>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>436</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>436</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>437</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>437</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>437</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>437</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>437</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>437</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>437</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>437</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>437</integer>
+// CHECK-NEXT:          <key>col</key><integer>10</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Assuming &apos;dict&apos; is null</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Assuming &apos;dict&apos; is 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:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>437</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>437</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>439</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>439</integer>
+// CHECK-NEXT:            <key>col</key><integer>6</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>439</integer>
+// CHECK-NEXT:       <key>col</key><integer>10</integer>
+// CHECK-NEXT:       <key>file</key><integer>0</integer>
+// CHECK-NEXT:      </dict>
+// CHECK-NEXT:      <key>ranges</key>
+// CHECK-NEXT:      <array>
+// CHECK-NEXT:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>439</integer>
+// CHECK-NEXT:          <key>col</key><integer>10</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>439</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:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Call to function &apos;DADiskCopyWholeDisk&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Call to function &apos;DADiskCopyWholeDisk&apos; returns a Core Foundation object with a +1 retain count</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>439</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>439</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>440</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>440</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>440</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>440</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>440</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>440</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>440</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>440</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>440</integer>
+// CHECK-NEXT:          <key>col</key><integer>10</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is non-null</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Assuming &apos;disk&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:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>440</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>440</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>440</integer>
+// CHECK-NEXT:            <key>col</key><integer>13</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>440</integer>
+// CHECK-NEXT:            <key>col</key><integer>17</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>440</integer>
+// CHECK-NEXT:       <key>col</key><integer>13</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>440</integer>
+// CHECK-NEXT:          <key>col</key><integer>13</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>440</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:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;disk&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;disk&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:    </array>
+// CHECK-NEXT:    <key>description</key><string>Potential leak of an object stored into &apos;disk&apos;</string>
+// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK-NEXT:    <key>type</key><string>Leak</string>
+// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT:   <key>issue_context</key><string>f10</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>10</string>
+// CHECK-NEXT:   <key>location</key>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>line</key><integer>440</integer>
+// CHECK-NEXT:    <key>col</key><integer>13</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>430</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>430</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>431</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>431</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>431</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>431</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>431</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>431</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>431</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>431</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>431</integer>
+// CHECK-NEXT:          <key>col</key><integer>10</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is null</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is 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:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>431</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>431</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>433</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>433</integer>
+// CHECK-NEXT:            <key>col</key><integer>6</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>433</integer>
+// CHECK-NEXT:       <key>col</key><integer>10</integer>
+// CHECK-NEXT:       <key>file</key><integer>0</integer>
+// CHECK-NEXT:      </dict>
+// CHECK-NEXT:      <key>ranges</key>
+// CHECK-NEXT:      <array>
+// CHECK-NEXT:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>433</integer>
+// CHECK-NEXT:          <key>col</key><integer>10</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>433</integer>
+// CHECK-NEXT:          <key>col</key><integer>63</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>Call to function &apos;DADiskCreateFromIOMedia&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Call to function &apos;DADiskCreateFromIOMedia&apos; returns a Core Foundation object with a +1 retain count</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>433</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>433</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>434</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>434</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>434</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>434</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>434</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>434</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>434</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>434</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>434</integer>
+// CHECK-NEXT:          <key>col</key><integer>10</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is non-null</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Assuming &apos;disk&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:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>434</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>434</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>434</integer>
+// CHECK-NEXT:            <key>col</key><integer>13</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>434</integer>
+// CHECK-NEXT:            <key>col</key><integer>17</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>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>434</integer>
+// CHECK-NEXT:            <key>col</key><integer>13</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>434</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>436</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>436</integer>
+// CHECK-NEXT:            <key>col</key><integer>17</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>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>436</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>436</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>437</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>437</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>437</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>437</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>437</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>437</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>437</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>437</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>437</integer>
+// CHECK-NEXT:          <key>col</key><integer>10</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Assuming &apos;dict&apos; is null</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Assuming &apos;dict&apos; is 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:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>437</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>437</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>439</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>439</integer>
+// CHECK-NEXT:            <key>col</key><integer>6</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>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>439</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>439</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>440</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>440</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>440</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>440</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>440</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>440</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>440</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>440</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>440</integer>
+// CHECK-NEXT:          <key>col</key><integer>10</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is null</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is 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:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>440</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>440</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>442</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>442</integer>
+// CHECK-NEXT:            <key>col</key><integer>16</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>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>442</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>442</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>442</integer>
+// CHECK-NEXT:            <key>col</key><integer>30</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>442</integer>
+// CHECK-NEXT:            <key>col</key><integer>46</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>442</integer>
+// CHECK-NEXT:       <key>col</key><integer>30</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>442</integer>
+// CHECK-NEXT:          <key>col</key><integer>30</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>442</integer>
+// CHECK-NEXT:          <key>col</key><integer>46</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>Object leaked: object allocated and stored into &apos;disk&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;disk&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:    </array>
+// CHECK-NEXT:    <key>description</key><string>Potential leak of an object stored into &apos;disk&apos;</string>
+// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK-NEXT:    <key>type</key><string>Leak</string>
+// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT:   <key>issue_context</key><string>f10</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>4</string>
+// CHECK-NEXT:   <key>location</key>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>line</key><integer>442</integer>
+// CHECK-NEXT:    <key>col</key><integer>30</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>430</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>430</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>431</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>431</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>431</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>431</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>431</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>431</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>431</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>431</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>431</integer>
+// CHECK-NEXT:          <key>col</key><integer>10</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is null</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is 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:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>431</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>431</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>433</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>433</integer>
+// CHECK-NEXT:            <key>col</key><integer>6</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>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>433</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>433</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>434</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>434</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>434</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>434</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>434</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>434</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>434</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>434</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>434</integer>
+// CHECK-NEXT:          <key>col</key><integer>10</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is null</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is 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:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>434</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>434</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>436</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>436</integer>
+// CHECK-NEXT:            <key>col</key><integer>17</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>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>436</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>436</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>437</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>437</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>437</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>437</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>437</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>437</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>437</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>437</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>437</integer>
+// CHECK-NEXT:          <key>col</key><integer>10</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Assuming &apos;dict&apos; is null</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Assuming &apos;dict&apos; is 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:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>437</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>437</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>439</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>439</integer>
+// CHECK-NEXT:            <key>col</key><integer>6</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>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>439</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>439</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>440</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>440</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>440</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>440</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>440</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>440</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>440</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>440</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>440</integer>
+// CHECK-NEXT:          <key>col</key><integer>10</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is null</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is 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:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>440</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>440</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>442</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>442</integer>
+// CHECK-NEXT:            <key>col</key><integer>16</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>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>442</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>442</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>442</integer>
+// CHECK-NEXT:            <key>col</key><integer>30</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>442</integer>
+// CHECK-NEXT:            <key>col</key><integer>46</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>442</integer>
+// CHECK-NEXT:       <key>col</key><integer>30</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>442</integer>
+// CHECK-NEXT:          <key>col</key><integer>30</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>443</integer>
+// CHECK-NEXT:          <key>col</key><integer>68</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>Call to function &apos;DADissenterCreate&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Call to function &apos;DADissenterCreate&apos; returns a Core Foundation object with a +1 retain count</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>442</integer>
+// CHECK-NEXT:            <key>col</key><integer>30</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>442</integer>
+// CHECK-NEXT:            <key>col</key><integer>46</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>442</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>442</integer>
+// CHECK-NEXT:            <key>col</key><integer>16</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>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>442</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>442</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>444</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>444</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>444</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>444</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>444</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>444</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>444</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>444</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>444</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;dissenter&apos; is non-null</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Assuming &apos;dissenter&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:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>444</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>444</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>444</integer>
+// CHECK-NEXT:            <key>col</key><integer>18</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>444</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:     </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>444</integer>
+// CHECK-NEXT:       <key>col</key><integer>18</integer>
+// CHECK-NEXT:       <key>file</key><integer>0</integer>
+// CHECK-NEXT:      </dict>
+// CHECK-NEXT:      <key>ranges</key>
+// CHECK-NEXT:      <array>
+// CHECK-NEXT:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>444</integer>
+// CHECK-NEXT:          <key>col</key><integer>18</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>444</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:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;dissenter&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;dissenter&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:    </array>
+// CHECK-NEXT:    <key>description</key><string>Potential leak of an object stored into &apos;dissenter&apos;</string>
+// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK-NEXT:    <key>type</key><string>Leak</string>
+// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT:   <key>issue_context</key><string>f10</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>13</string>
+// CHECK-NEXT:   <key>location</key>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>line</key><integer>444</integer>
+// CHECK-NEXT:    <key>col</key><integer>18</integer>
+// CHECK-NEXT:    <key>file</key><integer>0</integer>
+// CHECK-NEXT:   </dict>
+// CHECK-NEXT:   </dict>
+// CHECK-NEXT:   <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>430</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>430</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>431</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>431</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>431</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>431</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>431</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>431</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>431</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>431</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>431</integer>
+// CHECK-NEXT:          <key>col</key><integer>10</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is null</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is 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:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>431</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>431</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>433</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>433</integer>
+// CHECK-NEXT:            <key>col</key><integer>6</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>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>433</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>433</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>434</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>434</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>434</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>434</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>434</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>434</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>434</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>434</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>434</integer>
+// CHECK-NEXT:          <key>col</key><integer>10</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is null</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is 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:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>434</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>434</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>436</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>436</integer>
+// CHECK-NEXT:            <key>col</key><integer>17</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>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>436</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>436</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>437</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>437</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>437</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>437</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>437</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>437</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>437</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>437</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>437</integer>
+// CHECK-NEXT:          <key>col</key><integer>10</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Assuming &apos;dict&apos; is null</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Assuming &apos;dict&apos; is 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:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>437</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>437</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>439</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>439</integer>
+// CHECK-NEXT:            <key>col</key><integer>6</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>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>439</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>439</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>440</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>440</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>440</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>440</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>440</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>440</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>440</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>440</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>440</integer>
+// CHECK-NEXT:          <key>col</key><integer>10</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is null</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Assuming &apos;disk&apos; is 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:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>440</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>440</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>442</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>442</integer>
+// CHECK-NEXT:            <key>col</key><integer>16</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>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>442</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>442</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>444</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>444</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>444</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>444</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>444</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>444</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>444</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>444</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>444</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;dissenter&apos; is null</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Assuming &apos;dissenter&apos; is 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:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>444</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>444</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>446</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>446</integer>
+// CHECK-NEXT:            <key>col</key><integer>14</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>446</integer>
+// CHECK-NEXT:       <key>col</key><integer>26</integer>
+// CHECK-NEXT:       <key>file</key><integer>0</integer>
+// CHECK-NEXT:      </dict>
+// CHECK-NEXT:      <key>ranges</key>
+// CHECK-NEXT:      <array>
+// CHECK-NEXT:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>446</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>446</integer>
+// CHECK-NEXT:          <key>col</key><integer>61</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>Call to function &apos;DASessionCreate&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Call to function &apos;DASessionCreate&apos; returns a Core Foundation object with a +1 retain count</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>446</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>446</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>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>447</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>447</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>447</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>447</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>447</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>447</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>line</key><integer>447</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>447</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>447</integer>
 // CHECK-NEXT:          <key>col</key><integer>13</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -8502,12 +8092,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>437</integer>
+// CHECK-NEXT:            <key>line</key><integer>447</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>437</integer>
+// CHECK-NEXT:            <key>line</key><integer>447</integer>
 // CHECK-NEXT:            <key>col</key><integer>13</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -8515,12 +8105,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>437</integer>
+// CHECK-NEXT:            <key>line</key><integer>447</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>437</integer>
+// CHECK-NEXT:            <key>line</key><integer>447</integer>
 // CHECK-NEXT:            <key>col</key><integer>20</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -8529,58 +8119,24 @@
 // 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>437</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>437</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>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>437</integer>
-// CHECK-NEXT:            <key>col</key><integer>23</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>437</integer>
-// CHECK-NEXT:            <key>col</key><integer>26</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>437</integer>
-// CHECK-NEXT:       <key>col</key><integer>23</integer>
+// CHECK-NEXT:       <key>line</key><integer>447</integer>
+// CHECK-NEXT:       <key>col</key><integer>16</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
 // CHECK-NEXT:      <key>ranges</key>
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>437</integer>
-// CHECK-NEXT:          <key>col</key><integer>23</integer>
+// CHECK-NEXT:          <key>line</key><integer>447</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>437</integer>
-// CHECK-NEXT:          <key>col</key><integer>26</integer>
+// CHECK-NEXT:          <key>line</key><integer>447</integer>
+// CHECK-NEXT:          <key>col</key><integer>20</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:        </array>
@@ -8597,11 +8153,11 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>f10</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>18</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>17</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>437</integer>
-// CHECK-NEXT:    <key>col</key><integer>23</integer>
+// CHECK-NEXT:    <key>line</key><integer>447</integer>
+// CHECK-NEXT:    <key>col</key><integer>16</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
 // CHECK-NEXT:   </dict>
@@ -8616,12 +8172,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>443</integer>
+// CHECK-NEXT:            <key>line</key><integer>453</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>443</integer>
+// CHECK-NEXT:            <key>line</key><integer>453</integer>
 // CHECK-NEXT:            <key>col</key><integer>19</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -8629,12 +8185,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>456</integer>
+// CHECK-NEXT:            <key>line</key><integer>466</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>456</integer>
+// CHECK-NEXT:            <key>line</key><integer>466</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -8643,44 +8199,10 @@
 // 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>456</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>456</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>456</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>456</integer>
-// CHECK-NEXT:            <key>col</key><integer>43</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>456</integer>
+// CHECK-NEXT:       <key>line</key><integer>466</integer>
 // CHECK-NEXT:       <key>col</key><integer>22</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -8688,12 +8210,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>456</integer>
+// CHECK-NEXT:          <key>line</key><integer>466</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>456</integer>
+// CHECK-NEXT:          <key>line</key><integer>466</integer>
 // CHECK-NEXT:          <key>col</key><integer>49</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -8713,25 +8235,25 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>456</integer>
-// CHECK-NEXT:            <key>col</key><integer>22</integer>
+// CHECK-NEXT:            <key>line</key><integer>466</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>456</integer>
-// CHECK-NEXT:            <key>col</key><integer>43</integer>
+// CHECK-NEXT:            <key>line</key><integer>466</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>462</integer>
+// CHECK-NEXT:            <key>line</key><integer>472</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>462</integer>
+// CHECK-NEXT:            <key>line</key><integer>472</integer>
 // CHECK-NEXT:            <key>col</key><integer>11</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -8743,7 +8265,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>462</integer>
+// CHECK-NEXT:       <key>line</key><integer>472</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -8751,12 +8273,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>462</integer>
+// CHECK-NEXT:          <key>line</key><integer>472</integer>
 // CHECK-NEXT:          <key>col</key><integer>13</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>462</integer>
+// CHECK-NEXT:          <key>line</key><integer>472</integer>
 // CHECK-NEXT:          <key>col</key><integer>14</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -8777,7 +8299,7 @@
 // CHECK-NEXT:   <key>issue_hash</key><string>21</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>462</integer>
+// CHECK-NEXT:    <key>line</key><integer>472</integer>
 // CHECK-NEXT:    <key>col</key><integer>3</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -8786,44 +8308,10 @@
 // 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>470</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>470</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>470</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>470</integer>
-// CHECK-NEXT:            <key>col</key><integer>27</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>470</integer>
+// CHECK-NEXT:       <key>line</key><integer>480</integer>
 // CHECK-NEXT:       <key>col</key><integer>17</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -8831,12 +8319,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>470</integer>
+// CHECK-NEXT:          <key>line</key><integer>480</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>470</integer>
+// CHECK-NEXT:          <key>line</key><integer>480</integer>
 // CHECK-NEXT:          <key>col</key><integer>29</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -8856,25 +8344,25 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>470</integer>
-// CHECK-NEXT:            <key>col</key><integer>17</integer>
+// CHECK-NEXT:            <key>line</key><integer>480</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>470</integer>
-// CHECK-NEXT:            <key>col</key><integer>27</integer>
+// CHECK-NEXT:            <key>line</key><integer>480</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>471</integer>
+// CHECK-NEXT:            <key>line</key><integer>481</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>471</integer>
+// CHECK-NEXT:            <key>line</key><integer>481</integer>
 // CHECK-NEXT:            <key>col</key><integer>1</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -8886,7 +8374,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>471</integer>
+// CHECK-NEXT:       <key>line</key><integer>481</integer>
 // CHECK-NEXT:       <key>col</key><integer>1</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -8902,10 +8390,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>f12</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>2</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>1</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>471</integer>
+// CHECK-NEXT:    <key>line</key><integer>481</integer>
 // CHECK-NEXT:    <key>col</key><integer>1</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -8914,44 +8402,10 @@
 // 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>479</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>479</integer>
-// CHECK-NEXT:            <key>col</key><integer>19</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>479</integer>
-// CHECK-NEXT:            <key>col</key><integer>25</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>479</integer>
-// CHECK-NEXT:            <key>col</key><integer>44</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>479</integer>
+// CHECK-NEXT:       <key>line</key><integer>489</integer>
 // CHECK-NEXT:       <key>col</key><integer>25</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -8959,12 +8413,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>479</integer>
+// CHECK-NEXT:          <key>line</key><integer>489</integer>
 // CHECK-NEXT:          <key>col</key><integer>25</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>479</integer>
+// CHECK-NEXT:          <key>line</key><integer>489</integer>
 // CHECK-NEXT:          <key>col</key><integer>75</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -8984,25 +8438,25 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>479</integer>
-// CHECK-NEXT:            <key>col</key><integer>25</integer>
+// CHECK-NEXT:            <key>line</key><integer>489</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>479</integer>
-// CHECK-NEXT:            <key>col</key><integer>44</integer>
+// CHECK-NEXT:            <key>line</key><integer>489</integer>
+// CHECK-NEXT:            <key>col</key><integer>19</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>480</integer>
+// CHECK-NEXT:            <key>line</key><integer>490</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>480</integer>
+// CHECK-NEXT:            <key>line</key><integer>490</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -9014,7 +8468,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>480</integer>
+// CHECK-NEXT:       <key>line</key><integer>490</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -9022,24 +8476,24 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>480</integer>
+// CHECK-NEXT:          <key>line</key><integer>490</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>480</integer>
+// CHECK-NEXT:          <key>line</key><integer>490</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:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>480</integer>
+// CHECK-NEXT:          <key>line</key><integer>490</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>480</integer>
+// CHECK-NEXT:          <key>line</key><integer>490</integer>
 // CHECK-NEXT:          <key>col</key><integer>9</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -9059,12 +8513,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>480</integer>
+// CHECK-NEXT:            <key>line</key><integer>490</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>480</integer>
+// CHECK-NEXT:            <key>line</key><integer>490</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -9072,12 +8526,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>481</integer>
+// CHECK-NEXT:            <key>line</key><integer>491</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>481</integer>
+// CHECK-NEXT:            <key>line</key><integer>491</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -9089,7 +8543,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>481</integer>
+// CHECK-NEXT:       <key>line</key><integer>491</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -9097,24 +8551,24 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>481</integer>
+// CHECK-NEXT:          <key>line</key><integer>491</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>481</integer>
+// CHECK-NEXT:          <key>line</key><integer>491</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:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>481</integer>
+// CHECK-NEXT:          <key>line</key><integer>491</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>481</integer>
+// CHECK-NEXT:          <key>line</key><integer>491</integer>
 // CHECK-NEXT:          <key>col</key><integer>9</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -9134,12 +8588,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>481</integer>
+// CHECK-NEXT:            <key>line</key><integer>491</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>481</integer>
+// CHECK-NEXT:            <key>line</key><integer>491</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -9147,12 +8601,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>482</integer>
+// CHECK-NEXT:            <key>line</key><integer>492</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>482</integer>
+// CHECK-NEXT:            <key>line</key><integer>492</integer>
 // CHECK-NEXT:            <key>col</key><integer>1</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -9164,7 +8618,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>482</integer>
+// CHECK-NEXT:       <key>line</key><integer>492</integer>
 // CHECK-NEXT:       <key>col</key><integer>1</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -9183,7 +8637,7 @@
 // CHECK-NEXT:   <key>issue_hash</key><string>4</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>482</integer>
+// CHECK-NEXT:    <key>line</key><integer>492</integer>
 // CHECK-NEXT:    <key>col</key><integer>1</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -9192,580 +8646,6 @@
 // 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>485</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>485</integer>
-// CHECK-NEXT:            <key>col</key><integer>19</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>485</integer>
-// CHECK-NEXT:            <key>col</key><integer>25</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>485</integer>
-// CHECK-NEXT:            <key>col</key><integer>44</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>485</integer>
-// CHECK-NEXT:       <key>col</key><integer>25</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>485</integer>
-// CHECK-NEXT:          <key>col</key><integer>25</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>485</integer>
-// CHECK-NEXT:          <key>col</key><integer>75</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>Call to function &apos;CFArrayCreateMutable&apos; returns a Core Foundation object with a +1 retain count</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFArrayCreateMutable&apos; returns a Core Foundation object with a +1 retain count</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>485</integer>
-// CHECK-NEXT:            <key>col</key><integer>25</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>485</integer>
-// CHECK-NEXT:            <key>col</key><integer>44</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>486</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>486</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>486</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>486</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>486</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:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>486</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>486</integer>
-// CHECK-NEXT:          <key>col</key><integer>9</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Object autoreleased</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Object autoreleased</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>486</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>486</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>487</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>487</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>487</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>487</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>487</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:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>487</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>487</integer>
-// CHECK-NEXT:          <key>col</key><integer>9</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Object autoreleased</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Object autoreleased</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>487</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>487</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>488</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>488</integer>
-// CHECK-NEXT:            <key>col</key><integer>8</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>488</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>488</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>488</integer>
-// CHECK-NEXT:          <key>col</key><integer>10</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Object was autoreleased 2 times but the object has a +0 retain count</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Object was autoreleased 2 times but the object has a +0 retain count</string>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:    </array>
-// CHECK-NEXT:    <key>description</key><string>Object autoreleased too many times</string>
-// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
-// CHECK-NEXT:    <key>type</key><string>Object autoreleased too many times</string>
-// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT:   <key>issue_context</key><string>f13_autorelease_c</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>4</string>
-// CHECK-NEXT:   <key>location</key>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>488</integer>
-// CHECK-NEXT:    <key>col</key><integer>3</integer>
-// CHECK-NEXT:    <key>file</key><integer>0</integer>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>path</key>
-// CHECK-NEXT:    <array>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>492</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>492</integer>
-// CHECK-NEXT:            <key>col</key><integer>19</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>492</integer>
-// CHECK-NEXT:            <key>col</key><integer>25</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>492</integer>
-// CHECK-NEXT:            <key>col</key><integer>44</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>492</integer>
-// CHECK-NEXT:       <key>col</key><integer>25</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>492</integer>
-// CHECK-NEXT:          <key>col</key><integer>25</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>492</integer>
-// CHECK-NEXT:          <key>col</key><integer>75</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>Call to function &apos;CFArrayCreateMutable&apos; returns a Core Foundation object with a +1 retain count</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Call to function &apos;CFArrayCreateMutable&apos; returns a Core Foundation object with a +1 retain count</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>492</integer>
-// CHECK-NEXT:            <key>col</key><integer>25</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>492</integer>
-// CHECK-NEXT:            <key>col</key><integer>44</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>493</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>493</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>493</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>493</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>493</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:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>493</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>493</integer>
-// CHECK-NEXT:          <key>col</key><integer>9</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Object autoreleased</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Object autoreleased</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>493</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>493</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>494</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>494</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>494</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>494</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>494</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:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>494</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>494</integer>
-// CHECK-NEXT:          <key>col</key><integer>9</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Object autoreleased</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Object autoreleased</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>494</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>494</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>495</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>495</integer>
-// CHECK-NEXT:            <key>col</key><integer>19</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>495</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>495</integer>
-// CHECK-NEXT:            <key>col</key><integer>19</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>495</integer>
-// CHECK-NEXT:            <key>col</key><integer>25</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>495</integer>
-// CHECK-NEXT:            <key>col</key><integer>44</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>
@@ -9790,21 +8670,234 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Object was autoreleased 2 times but the object has a +1 retain count</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFArrayCreateMutable&apos; returns a Core Foundation object with a +1 retain count</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Object was autoreleased 2 times but the object has a +1 retain count</string>
+// CHECK-NEXT:      <string>Call to function &apos;CFArrayCreateMutable&apos; returns a Core Foundation object with a +1 retain count</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>495</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>495</integer>
+// CHECK-NEXT:            <key>col</key><integer>19</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>496</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>496</integer>
+// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>496</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>496</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>496</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:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>496</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>496</integer>
+// CHECK-NEXT:          <key>col</key><integer>9</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Object autoreleased</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Object autoreleased</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>496</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>496</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>497</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>497</integer>
+// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>497</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>497</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>497</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:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>497</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>497</integer>
+// CHECK-NEXT:          <key>col</key><integer>9</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Object autoreleased</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Object autoreleased</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>497</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>497</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>498</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>498</integer>
+// CHECK-NEXT:            <key>col</key><integer>8</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>498</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>498</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>498</integer>
+// CHECK-NEXT:          <key>col</key><integer>10</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Object was autoreleased 2 times but the object has a +0 retain count</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Object was autoreleased 2 times but the object has a +0 retain count</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:    </array>
 // CHECK-NEXT:    <key>description</key><string>Object autoreleased too many times</string>
 // CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
 // CHECK-NEXT:    <key>type</key><string>Object autoreleased too many times</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT:   <key>issue_context</key><string>f13_autorelease_d</string>
+// CHECK-NEXT:   <key>issue_context</key><string>f13_autorelease_c</string>
 // CHECK-NEXT:   <key>issue_hash</key><string>4</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>495</integer>
-// CHECK-NEXT:    <key>col</key><integer>25</integer>
+// CHECK-NEXT:    <key>line</key><integer>498</integer>
+// CHECK-NEXT:    <key>col</key><integer>3</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
 // CHECK-NEXT:   </dict>
@@ -9815,6 +8908,69 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>502</integer>
+// CHECK-NEXT:       <key>col</key><integer>25</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>502</integer>
+// CHECK-NEXT:          <key>col</key><integer>25</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>502</integer>
+// CHECK-NEXT:          <key>col</key><integer>75</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>Call to function &apos;CFArrayCreateMutable&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Call to function &apos;CFArrayCreateMutable&apos; returns a Core Foundation object with a +1 retain count</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>502</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>502</integer>
+// CHECK-NEXT:            <key>col</key><integer>19</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>503</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>503</integer>
+// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
 // CHECK-NEXT:       <key>line</key><integer>503</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
@@ -9829,6 +8985,236 @@
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
 // CHECK-NEXT:          <key>line</key><integer>503</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:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>503</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>503</integer>
+// CHECK-NEXT:          <key>col</key><integer>9</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Object autoreleased</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Object autoreleased</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>503</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>503</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>504</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>504</integer>
+// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>504</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>504</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>504</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:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>504</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>504</integer>
+// CHECK-NEXT:          <key>col</key><integer>9</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Object autoreleased</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Object autoreleased</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>504</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>504</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>505</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>505</integer>
+// CHECK-NEXT:            <key>col</key><integer>19</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>505</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>505</integer>
+// CHECK-NEXT:            <key>col</key><integer>19</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>505</integer>
+// CHECK-NEXT:            <key>col</key><integer>25</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>505</integer>
+// CHECK-NEXT:            <key>col</key><integer>44</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>505</integer>
+// CHECK-NEXT:       <key>col</key><integer>25</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>505</integer>
+// CHECK-NEXT:          <key>col</key><integer>25</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>505</integer>
+// CHECK-NEXT:          <key>col</key><integer>75</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>Object was autoreleased 2 times but the object has a +1 retain count</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Object was autoreleased 2 times but the object has a +1 retain count</string>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:    </array>
+// CHECK-NEXT:    <key>description</key><string>Object autoreleased too many times</string>
+// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK-NEXT:    <key>type</key><string>Object autoreleased too many times</string>
+// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT:   <key>issue_context</key><string>f13_autorelease_d</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>4</string>
+// CHECK-NEXT:   <key>location</key>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>line</key><integer>505</integer>
+// CHECK-NEXT:    <key>col</key><integer>25</integer>
+// CHECK-NEXT:    <key>file</key><integer>0</integer>
+// CHECK-NEXT:   </dict>
+// CHECK-NEXT:   </dict>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>path</key>
+// CHECK-NEXT:    <array>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>513</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>513</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>513</integer>
 // CHECK-NEXT:          <key>col</key><integer>53</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -9848,12 +9234,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>503</integer>
+// CHECK-NEXT:            <key>line</key><integer>513</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>503</integer>
+// CHECK-NEXT:            <key>line</key><integer>513</integer>
 // CHECK-NEXT:            <key>col</key><integer>22</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -9861,12 +9247,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>504</integer>
+// CHECK-NEXT:            <key>line</key><integer>514</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>504</integer>
+// CHECK-NEXT:            <key>line</key><integer>514</integer>
 // CHECK-NEXT:            <key>col</key><integer>1</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -9878,7 +9264,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>504</integer>
+// CHECK-NEXT:       <key>line</key><integer>514</integer>
 // CHECK-NEXT:       <key>col</key><integer>1</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -9894,10 +9280,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>f14_leakimmediately</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>2</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>1</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>504</integer>
+// CHECK-NEXT:    <key>line</key><integer>514</integer>
 // CHECK-NEXT:    <key>col</key><integer>1</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -9913,12 +9299,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>518</integer>
+// CHECK-NEXT:            <key>line</key><integer>528</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>518</integer>
+// CHECK-NEXT:            <key>line</key><integer>528</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -9926,12 +9312,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>518</integer>
+// CHECK-NEXT:            <key>line</key><integer>528</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>518</integer>
+// CHECK-NEXT:            <key>line</key><integer>528</integer>
 // CHECK-NEXT:            <key>col</key><integer>7</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -9943,7 +9329,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>518</integer>
+// CHECK-NEXT:       <key>line</key><integer>528</integer>
 // CHECK-NEXT:       <key>col</key><integer>7</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -9951,12 +9337,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>518</integer>
+// CHECK-NEXT:          <key>line</key><integer>528</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>518</integer>
+// CHECK-NEXT:          <key>line</key><integer>528</integer>
 // CHECK-NEXT:          <key>col</key><integer>7</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -9976,12 +9362,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>518</integer>
+// CHECK-NEXT:            <key>line</key><integer>528</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>518</integer>
+// CHECK-NEXT:            <key>line</key><integer>528</integer>
 // CHECK-NEXT:            <key>col</key><integer>7</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -9989,12 +9375,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>521</integer>
+// CHECK-NEXT:            <key>line</key><integer>531</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>521</integer>
+// CHECK-NEXT:            <key>line</key><integer>531</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -10010,12 +9396,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>521</integer>
+// CHECK-NEXT:            <key>line</key><integer>531</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>521</integer>
+// CHECK-NEXT:            <key>line</key><integer>531</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -10023,12 +9409,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>521</integer>
+// CHECK-NEXT:            <key>line</key><integer>531</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>521</integer>
+// CHECK-NEXT:            <key>line</key><integer>531</integer>
 // CHECK-NEXT:            <key>col</key><integer>7</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -10040,7 +9426,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>521</integer>
+// CHECK-NEXT:       <key>line</key><integer>531</integer>
 // CHECK-NEXT:       <key>col</key><integer>7</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -10048,12 +9434,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>521</integer>
+// CHECK-NEXT:          <key>line</key><integer>531</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>521</integer>
+// CHECK-NEXT:          <key>line</key><integer>531</integer>
 // CHECK-NEXT:          <key>col</key><integer>11</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -10073,12 +9459,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>521</integer>
+// CHECK-NEXT:            <key>line</key><integer>531</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>521</integer>
+// CHECK-NEXT:            <key>line</key><integer>531</integer>
 // CHECK-NEXT:            <key>col</key><integer>7</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -10086,12 +9472,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>522</integer>
+// CHECK-NEXT:            <key>line</key><integer>532</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>522</integer>
+// CHECK-NEXT:            <key>line</key><integer>532</integer>
 // CHECK-NEXT:            <key>col</key><integer>13</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -10103,7 +9489,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>522</integer>
+// CHECK-NEXT:       <key>line</key><integer>532</integer>
 // CHECK-NEXT:       <key>col</key><integer>5</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -10111,12 +9497,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>522</integer>
+// CHECK-NEXT:          <key>line</key><integer>532</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>522</integer>
+// CHECK-NEXT:          <key>line</key><integer>532</integer>
 // CHECK-NEXT:          <key>col</key><integer>15</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -10131,13 +9517,13 @@
 // CHECK-NEXT:    </array>
 // CHECK-NEXT:    <key>description</key><string>Null pointer argument in call to CFRelease</string>
 // CHECK-NEXT:    <key>category</key><string>API Misuse (Apple)</string>
-// CHECK-NEXT:    <key>type</key><string>null passed to CFRetain/CFRelease/CFMakeCollectable</string>
+// CHECK-NEXT:    <key>type</key><string>null passed to CF memory management function</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>f16</string>
 // CHECK-NEXT:   <key>issue_hash</key><string>5</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>522</integer>
+// CHECK-NEXT:    <key>line</key><integer>532</integer>
 // CHECK-NEXT:    <key>col</key><integer>5</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -10153,12 +9539,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>518</integer>
+// CHECK-NEXT:            <key>line</key><integer>528</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>518</integer>
+// CHECK-NEXT:            <key>line</key><integer>528</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -10166,12 +9552,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>518</integer>
+// CHECK-NEXT:            <key>line</key><integer>528</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>518</integer>
+// CHECK-NEXT:            <key>line</key><integer>528</integer>
 // CHECK-NEXT:            <key>col</key><integer>7</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -10183,7 +9569,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>518</integer>
+// CHECK-NEXT:       <key>line</key><integer>528</integer>
 // CHECK-NEXT:       <key>col</key><integer>7</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -10191,12 +9577,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>518</integer>
+// CHECK-NEXT:          <key>line</key><integer>528</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>518</integer>
+// CHECK-NEXT:          <key>line</key><integer>528</integer>
 // CHECK-NEXT:          <key>col</key><integer>7</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -10216,12 +9602,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>518</integer>
+// CHECK-NEXT:            <key>line</key><integer>528</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>518</integer>
+// CHECK-NEXT:            <key>line</key><integer>528</integer>
 // CHECK-NEXT:            <key>col</key><integer>7</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -10229,12 +9615,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>521</integer>
+// CHECK-NEXT:            <key>line</key><integer>531</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>521</integer>
+// CHECK-NEXT:            <key>line</key><integer>531</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -10250,12 +9636,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>521</integer>
+// CHECK-NEXT:            <key>line</key><integer>531</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>521</integer>
+// CHECK-NEXT:            <key>line</key><integer>531</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -10263,12 +9649,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>521</integer>
+// CHECK-NEXT:            <key>line</key><integer>531</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>521</integer>
+// CHECK-NEXT:            <key>line</key><integer>531</integer>
 // CHECK-NEXT:            <key>col</key><integer>7</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -10280,7 +9666,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>521</integer>
+// CHECK-NEXT:       <key>line</key><integer>531</integer>
 // CHECK-NEXT:       <key>col</key><integer>7</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -10288,12 +9674,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>521</integer>
+// CHECK-NEXT:          <key>line</key><integer>531</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>521</integer>
+// CHECK-NEXT:          <key>line</key><integer>531</integer>
 // CHECK-NEXT:          <key>col</key><integer>11</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -10313,12 +9699,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>521</integer>
+// CHECK-NEXT:            <key>line</key><integer>531</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>521</integer>
+// CHECK-NEXT:            <key>line</key><integer>531</integer>
 // CHECK-NEXT:            <key>col</key><integer>7</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -10326,12 +9712,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>524</integer>
+// CHECK-NEXT:            <key>line</key><integer>534</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>524</integer>
+// CHECK-NEXT:            <key>line</key><integer>534</integer>
 // CHECK-NEXT:            <key>col</key><integer>9</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -10347,12 +9733,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>524</integer>
+// CHECK-NEXT:            <key>line</key><integer>534</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>524</integer>
+// CHECK-NEXT:            <key>line</key><integer>534</integer>
 // CHECK-NEXT:            <key>col</key><integer>9</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -10360,12 +9746,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>524</integer>
+// CHECK-NEXT:            <key>line</key><integer>534</integer>
 // CHECK-NEXT:            <key>col</key><integer>12</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>524</integer>
+// CHECK-NEXT:            <key>line</key><integer>534</integer>
 // CHECK-NEXT:            <key>col</key><integer>12</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -10377,7 +9763,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>524</integer>
+// CHECK-NEXT:       <key>line</key><integer>534</integer>
 // CHECK-NEXT:       <key>col</key><integer>12</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -10385,12 +9771,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>524</integer>
+// CHECK-NEXT:          <key>line</key><integer>534</integer>
 // CHECK-NEXT:          <key>col</key><integer>12</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>524</integer>
+// CHECK-NEXT:          <key>line</key><integer>534</integer>
 // CHECK-NEXT:          <key>col</key><integer>16</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -10410,12 +9796,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>524</integer>
+// CHECK-NEXT:            <key>line</key><integer>534</integer>
 // CHECK-NEXT:            <key>col</key><integer>12</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>524</integer>
+// CHECK-NEXT:            <key>line</key><integer>534</integer>
 // CHECK-NEXT:            <key>col</key><integer>12</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -10423,12 +9809,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>525</integer>
+// CHECK-NEXT:            <key>line</key><integer>535</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>525</integer>
+// CHECK-NEXT:            <key>line</key><integer>535</integer>
 // CHECK-NEXT:            <key>col</key><integer>12</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -10440,7 +9826,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>525</integer>
+// CHECK-NEXT:       <key>line</key><integer>535</integer>
 // CHECK-NEXT:       <key>col</key><integer>5</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -10448,12 +9834,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>525</integer>
+// CHECK-NEXT:          <key>line</key><integer>535</integer>
 // CHECK-NEXT:          <key>col</key><integer>14</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>525</integer>
+// CHECK-NEXT:          <key>line</key><integer>535</integer>
 // CHECK-NEXT:          <key>col</key><integer>14</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -10468,13 +9854,13 @@
 // CHECK-NEXT:    </array>
 // CHECK-NEXT:    <key>description</key><string>Null pointer argument in call to CFRetain</string>
 // CHECK-NEXT:    <key>category</key><string>API Misuse (Apple)</string>
-// CHECK-NEXT:    <key>type</key><string>null passed to CFRetain/CFRelease/CFMakeCollectable</string>
+// CHECK-NEXT:    <key>type</key><string>null passed to CF memory management function</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>f16</string>
 // CHECK-NEXT:   <key>issue_hash</key><string>8</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>525</integer>
+// CHECK-NEXT:    <key>line</key><integer>535</integer>
 // CHECK-NEXT:    <key>col</key><integer>5</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -10490,12 +9876,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>518</integer>
+// CHECK-NEXT:            <key>line</key><integer>528</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>518</integer>
+// CHECK-NEXT:            <key>line</key><integer>528</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -10503,12 +9889,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>518</integer>
+// CHECK-NEXT:            <key>line</key><integer>528</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>518</integer>
+// CHECK-NEXT:            <key>line</key><integer>528</integer>
 // CHECK-NEXT:            <key>col</key><integer>7</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -10520,7 +9906,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>518</integer>
+// CHECK-NEXT:       <key>line</key><integer>528</integer>
 // CHECK-NEXT:       <key>col</key><integer>7</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -10528,12 +9914,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>518</integer>
+// CHECK-NEXT:          <key>line</key><integer>528</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>518</integer>
+// CHECK-NEXT:          <key>line</key><integer>528</integer>
 // CHECK-NEXT:          <key>col</key><integer>7</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -10553,12 +9939,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>518</integer>
+// CHECK-NEXT:            <key>line</key><integer>528</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>518</integer>
+// CHECK-NEXT:            <key>line</key><integer>528</integer>
 // CHECK-NEXT:            <key>col</key><integer>7</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -10566,12 +9952,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>521</integer>
+// CHECK-NEXT:            <key>line</key><integer>531</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>521</integer>
+// CHECK-NEXT:            <key>line</key><integer>531</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -10587,12 +9973,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>521</integer>
+// CHECK-NEXT:            <key>line</key><integer>531</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>521</integer>
+// CHECK-NEXT:            <key>line</key><integer>531</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -10600,12 +9986,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>521</integer>
+// CHECK-NEXT:            <key>line</key><integer>531</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>521</integer>
+// CHECK-NEXT:            <key>line</key><integer>531</integer>
 // CHECK-NEXT:            <key>col</key><integer>7</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -10617,7 +10003,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>521</integer>
+// CHECK-NEXT:       <key>line</key><integer>531</integer>
 // CHECK-NEXT:       <key>col</key><integer>7</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -10625,12 +10011,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>521</integer>
+// CHECK-NEXT:          <key>line</key><integer>531</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>521</integer>
+// CHECK-NEXT:          <key>line</key><integer>531</integer>
 // CHECK-NEXT:          <key>col</key><integer>11</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -10650,12 +10036,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>521</integer>
+// CHECK-NEXT:            <key>line</key><integer>531</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>521</integer>
+// CHECK-NEXT:            <key>line</key><integer>531</integer>
 // CHECK-NEXT:            <key>col</key><integer>7</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -10663,12 +10049,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>524</integer>
+// CHECK-NEXT:            <key>line</key><integer>534</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>524</integer>
+// CHECK-NEXT:            <key>line</key><integer>534</integer>
 // CHECK-NEXT:            <key>col</key><integer>9</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -10684,12 +10070,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>524</integer>
+// CHECK-NEXT:            <key>line</key><integer>534</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>524</integer>
+// CHECK-NEXT:            <key>line</key><integer>534</integer>
 // CHECK-NEXT:            <key>col</key><integer>9</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -10697,12 +10083,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>524</integer>
+// CHECK-NEXT:            <key>line</key><integer>534</integer>
 // CHECK-NEXT:            <key>col</key><integer>12</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>524</integer>
+// CHECK-NEXT:            <key>line</key><integer>534</integer>
 // CHECK-NEXT:            <key>col</key><integer>12</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -10714,7 +10100,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>524</integer>
+// CHECK-NEXT:       <key>line</key><integer>534</integer>
 // CHECK-NEXT:       <key>col</key><integer>12</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -10722,12 +10108,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>524</integer>
+// CHECK-NEXT:          <key>line</key><integer>534</integer>
 // CHECK-NEXT:          <key>col</key><integer>12</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>524</integer>
+// CHECK-NEXT:          <key>line</key><integer>534</integer>
 // CHECK-NEXT:          <key>col</key><integer>16</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -10747,12 +10133,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>524</integer>
+// CHECK-NEXT:            <key>line</key><integer>534</integer>
 // CHECK-NEXT:            <key>col</key><integer>12</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>524</integer>
+// CHECK-NEXT:            <key>line</key><integer>534</integer>
 // CHECK-NEXT:            <key>col</key><integer>12</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -10760,12 +10146,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>528</integer>
+// CHECK-NEXT:            <key>line</key><integer>538</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>528</integer>
+// CHECK-NEXT:            <key>line</key><integer>538</integer>
 // CHECK-NEXT:            <key>col</key><integer>21</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -10777,7 +10163,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>528</integer>
+// CHECK-NEXT:       <key>line</key><integer>538</integer>
 // CHECK-NEXT:       <key>col</key><integer>5</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -10785,12 +10171,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>528</integer>
+// CHECK-NEXT:          <key>line</key><integer>538</integer>
 // CHECK-NEXT:          <key>col</key><integer>23</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>528</integer>
+// CHECK-NEXT:          <key>line</key><integer>538</integer>
 // CHECK-NEXT:          <key>col</key><integer>23</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -10805,13 +10191,13 @@
 // CHECK-NEXT:    </array>
 // CHECK-NEXT:    <key>description</key><string>Null pointer argument in call to CFMakeCollectable</string>
 // CHECK-NEXT:    <key>category</key><string>API Misuse (Apple)</string>
-// CHECK-NEXT:    <key>type</key><string>null passed to CFRetain/CFRelease/CFMakeCollectable</string>
+// CHECK-NEXT:    <key>type</key><string>null passed to CF memory management function</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>f16</string>
 // CHECK-NEXT:   <key>issue_hash</key><string>11</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>528</integer>
+// CHECK-NEXT:    <key>line</key><integer>538</integer>
 // CHECK-NEXT:    <key>col</key><integer>5</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -10820,44 +10206,10 @@
 // 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>574</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>574</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>574</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>574</integer>
-// CHECK-NEXT:            <key>col</key><integer>17</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>574</integer>
+// CHECK-NEXT:       <key>line</key><integer>584</integer>
 // CHECK-NEXT:       <key>col</key><integer>17</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -10865,12 +10217,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>574</integer>
+// CHECK-NEXT:          <key>line</key><integer>584</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>574</integer>
+// CHECK-NEXT:          <key>line</key><integer>584</integer>
 // CHECK-NEXT:          <key>col</key><integer>55</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -10890,25 +10242,25 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>574</integer>
-// CHECK-NEXT:            <key>col</key><integer>17</integer>
+// CHECK-NEXT:            <key>line</key><integer>584</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>574</integer>
-// CHECK-NEXT:            <key>col</key><integer>17</integer>
+// CHECK-NEXT:            <key>line</key><integer>584</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>575</integer>
+// CHECK-NEXT:            <key>line</key><integer>585</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>575</integer>
+// CHECK-NEXT:            <key>line</key><integer>585</integer>
 // CHECK-NEXT:            <key>col</key><integer>8</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -10920,7 +10272,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>575</integer>
+// CHECK-NEXT:       <key>line</key><integer>585</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -10928,24 +10280,24 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>575</integer>
+// CHECK-NEXT:          <key>line</key><integer>585</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>575</integer>
+// CHECK-NEXT:          <key>line</key><integer>585</integer>
 // CHECK-NEXT:          <key>col</key><integer>10</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:        </array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>575</integer>
+// CHECK-NEXT:          <key>line</key><integer>585</integer>
 // CHECK-NEXT:          <key>col</key><integer>10</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>575</integer>
+// CHECK-NEXT:          <key>line</key><integer>585</integer>
 // CHECK-NEXT:          <key>col</key><integer>10</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -10961,7 +10313,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>575</integer>
+// CHECK-NEXT:       <key>line</key><integer>585</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -10969,12 +10321,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>575</integer>
+// CHECK-NEXT:          <key>line</key><integer>585</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>575</integer>
+// CHECK-NEXT:          <key>line</key><integer>585</integer>
 // CHECK-NEXT:          <key>col</key><integer>10</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -10995,7 +10347,7 @@
 // CHECK-NEXT:   <key>issue_hash</key><string>2</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>575</integer>
+// CHECK-NEXT:    <key>line</key><integer>585</integer>
 // CHECK-NEXT:    <key>col</key><integer>3</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -11004,44 +10356,10 @@
 // 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>588</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>588</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>588</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>588</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:     </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>588</integer>
+// CHECK-NEXT:       <key>line</key><integer>598</integer>
 // CHECK-NEXT:       <key>col</key><integer>20</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -11049,12 +10367,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>588</integer>
+// CHECK-NEXT:          <key>line</key><integer>598</integer>
 // CHECK-NEXT:          <key>col</key><integer>20</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>588</integer>
+// CHECK-NEXT:          <key>line</key><integer>598</integer>
 // CHECK-NEXT:          <key>col</key><integer>63</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -11074,25 +10392,25 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>588</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
+// CHECK-NEXT:            <key>line</key><integer>598</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>588</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
+// CHECK-NEXT:            <key>line</key><integer>598</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>595</integer>
+// CHECK-NEXT:            <key>line</key><integer>605</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>595</integer>
+// CHECK-NEXT:            <key>line</key><integer>605</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -11108,12 +10426,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>595</integer>
+// CHECK-NEXT:            <key>line</key><integer>605</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>595</integer>
+// CHECK-NEXT:            <key>line</key><integer>605</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -11121,12 +10439,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>595</integer>
+// CHECK-NEXT:            <key>line</key><integer>605</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>595</integer>
+// CHECK-NEXT:            <key>line</key><integer>605</integer>
 // CHECK-NEXT:            <key>col</key><integer>6</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -11138,7 +10456,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>595</integer>
+// CHECK-NEXT:       <key>line</key><integer>605</integer>
 // CHECK-NEXT:       <key>col</key><integer>6</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -11146,12 +10464,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>595</integer>
+// CHECK-NEXT:          <key>line</key><integer>605</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>595</integer>
+// CHECK-NEXT:          <key>line</key><integer>605</integer>
 // CHECK-NEXT:          <key>col</key><integer>10</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -11171,12 +10489,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>595</integer>
+// CHECK-NEXT:            <key>line</key><integer>605</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>595</integer>
+// CHECK-NEXT:            <key>line</key><integer>605</integer>
 // CHECK-NEXT:            <key>col</key><integer>6</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -11184,12 +10502,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>596</integer>
+// CHECK-NEXT:            <key>line</key><integer>606</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>596</integer>
+// CHECK-NEXT:            <key>line</key><integer>606</integer>
 // CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -11201,7 +10519,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>596</integer>
+// CHECK-NEXT:       <key>line</key><integer>606</integer>
 // CHECK-NEXT:       <key>col</key><integer>5</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -11209,12 +10527,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>596</integer>
+// CHECK-NEXT:          <key>line</key><integer>606</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>596</integer>
+// CHECK-NEXT:          <key>line</key><integer>606</integer>
 // CHECK-NEXT:          <key>col</key><integer>10</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -11232,10 +10550,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>rdar_6659160</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>13</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>5</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>596</integer>
+// CHECK-NEXT:    <key>line</key><integer>606</integer>
 // CHECK-NEXT:    <key>col</key><integer>5</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -11251,12 +10569,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>588</integer>
+// CHECK-NEXT:            <key>line</key><integer>598</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>588</integer>
+// CHECK-NEXT:            <key>line</key><integer>598</integer>
 // CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -11264,12 +10582,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>595</integer>
+// CHECK-NEXT:            <key>line</key><integer>605</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>595</integer>
+// CHECK-NEXT:            <key>line</key><integer>605</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -11285,12 +10603,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>595</integer>
+// CHECK-NEXT:            <key>line</key><integer>605</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>595</integer>
+// CHECK-NEXT:            <key>line</key><integer>605</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -11298,12 +10616,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>595</integer>
+// CHECK-NEXT:            <key>line</key><integer>605</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>595</integer>
+// CHECK-NEXT:            <key>line</key><integer>605</integer>
 // CHECK-NEXT:            <key>col</key><integer>6</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -11315,7 +10633,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>595</integer>
+// CHECK-NEXT:       <key>line</key><integer>605</integer>
 // CHECK-NEXT:       <key>col</key><integer>6</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -11323,12 +10641,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>595</integer>
+// CHECK-NEXT:          <key>line</key><integer>605</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>595</integer>
+// CHECK-NEXT:          <key>line</key><integer>605</integer>
 // CHECK-NEXT:          <key>col</key><integer>10</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -11348,12 +10666,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>595</integer>
+// CHECK-NEXT:            <key>line</key><integer>605</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>595</integer>
+// CHECK-NEXT:            <key>line</key><integer>605</integer>
 // CHECK-NEXT:            <key>col</key><integer>6</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -11361,12 +10679,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>598</integer>
+// CHECK-NEXT:            <key>line</key><integer>608</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>598</integer>
+// CHECK-NEXT:            <key>line</key><integer>608</integer>
 // CHECK-NEXT:            <key>col</key><integer>7</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -11378,7 +10696,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>598</integer>
+// CHECK-NEXT:       <key>line</key><integer>608</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -11386,12 +10704,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>598</integer>
+// CHECK-NEXT:          <key>line</key><integer>608</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>598</integer>
+// CHECK-NEXT:          <key>line</key><integer>608</integer>
 // CHECK-NEXT:          <key>col</key><integer>19</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -11399,9 +10717,9 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Variable &apos;kindC&apos; initialized to a null pointer value</string>
+// CHECK-NEXT:      <string>&apos;kindC&apos; initialized to a null pointer value</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Variable &apos;kindC&apos; initialized to a null pointer value</string>
+// CHECK-NEXT:      <string>&apos;kindC&apos; initialized to a null pointer value</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>control</string>
@@ -11411,12 +10729,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>598</integer>
+// CHECK-NEXT:            <key>line</key><integer>608</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>598</integer>
+// CHECK-NEXT:            <key>line</key><integer>608</integer>
 // CHECK-NEXT:            <key>col</key><integer>7</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -11424,12 +10742,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>606</integer>
+// CHECK-NEXT:            <key>line</key><integer>616</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>606</integer>
+// CHECK-NEXT:            <key>line</key><integer>616</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -11445,12 +10763,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>606</integer>
+// CHECK-NEXT:            <key>line</key><integer>616</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>606</integer>
+// CHECK-NEXT:            <key>line</key><integer>616</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -11458,12 +10776,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>606</integer>
+// CHECK-NEXT:            <key>line</key><integer>616</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>606</integer>
+// CHECK-NEXT:            <key>line</key><integer>616</integer>
 // CHECK-NEXT:            <key>col</key><integer>9</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -11475,7 +10793,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>606</integer>
+// CHECK-NEXT:       <key>line</key><integer>616</integer>
 // CHECK-NEXT:       <key>col</key><integer>6</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -11483,12 +10801,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>606</integer>
+// CHECK-NEXT:          <key>line</key><integer>616</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>606</integer>
+// CHECK-NEXT:          <key>line</key><integer>616</integer>
 // CHECK-NEXT:          <key>col</key><integer>9</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -11508,12 +10826,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>606</integer>
+// CHECK-NEXT:            <key>line</key><integer>616</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>606</integer>
+// CHECK-NEXT:            <key>line</key><integer>616</integer>
 // CHECK-NEXT:            <key>col</key><integer>9</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -11521,12 +10839,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>608</integer>
+// CHECK-NEXT:            <key>line</key><integer>618</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>608</integer>
+// CHECK-NEXT:            <key>line</key><integer>618</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -11542,12 +10860,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>608</integer>
+// CHECK-NEXT:            <key>line</key><integer>618</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>608</integer>
+// CHECK-NEXT:            <key>line</key><integer>618</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -11555,12 +10873,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>609</integer>
+// CHECK-NEXT:            <key>line</key><integer>619</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>609</integer>
+// CHECK-NEXT:            <key>line</key><integer>619</integer>
 // CHECK-NEXT:            <key>col</key><integer>9</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -11576,12 +10894,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>609</integer>
+// CHECK-NEXT:            <key>line</key><integer>619</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>609</integer>
+// CHECK-NEXT:            <key>line</key><integer>619</integer>
 // CHECK-NEXT:            <key>col</key><integer>9</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -11589,12 +10907,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>610</integer>
+// CHECK-NEXT:            <key>line</key><integer>620</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>610</integer>
+// CHECK-NEXT:            <key>line</key><integer>620</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -11610,12 +10928,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>610</integer>
+// CHECK-NEXT:            <key>line</key><integer>620</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>610</integer>
+// CHECK-NEXT:            <key>line</key><integer>620</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -11623,12 +10941,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>610</integer>
+// CHECK-NEXT:            <key>line</key><integer>620</integer>
 // CHECK-NEXT:            <key>col</key><integer>13</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>610</integer>
+// CHECK-NEXT:            <key>line</key><integer>620</integer>
 // CHECK-NEXT:            <key>col</key><integer>17</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -11640,7 +10958,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>610</integer>
+// CHECK-NEXT:       <key>line</key><integer>620</integer>
 // CHECK-NEXT:       <key>col</key><integer>13</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -11648,12 +10966,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>610</integer>
+// CHECK-NEXT:          <key>line</key><integer>620</integer>
 // CHECK-NEXT:          <key>col</key><integer>13</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>610</integer>
+// CHECK-NEXT:          <key>line</key><integer>620</integer>
 // CHECK-NEXT:          <key>col</key><integer>17</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -11674,7 +10992,7 @@
 // CHECK-NEXT:   <key>issue_hash</key><string>27</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>610</integer>
+// CHECK-NEXT:    <key>line</key><integer>620</integer>
 // CHECK-NEXT:    <key>col</key><integer>13</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -11690,12 +11008,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>588</integer>
+// CHECK-NEXT:            <key>line</key><integer>598</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>588</integer>
+// CHECK-NEXT:            <key>line</key><integer>598</integer>
 // CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -11703,12 +11021,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>594</integer>
+// CHECK-NEXT:            <key>line</key><integer>604</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>594</integer>
+// CHECK-NEXT:            <key>line</key><integer>604</integer>
 // CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -11717,44 +11035,10 @@
 // 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>594</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>594</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>594</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>594</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:     </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>594</integer>
+// CHECK-NEXT:       <key>line</key><integer>604</integer>
 // CHECK-NEXT:       <key>col</key><integer>20</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -11762,12 +11046,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>594</integer>
+// CHECK-NEXT:          <key>line</key><integer>604</integer>
 // CHECK-NEXT:          <key>col</key><integer>20</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>594</integer>
+// CHECK-NEXT:          <key>line</key><integer>604</integer>
 // CHECK-NEXT:          <key>col</key><integer>57</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -11787,25 +11071,25 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>594</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
+// CHECK-NEXT:            <key>line</key><integer>604</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>594</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
+// CHECK-NEXT:            <key>line</key><integer>604</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>595</integer>
+// CHECK-NEXT:            <key>line</key><integer>605</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>595</integer>
+// CHECK-NEXT:            <key>line</key><integer>605</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -11821,12 +11105,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>595</integer>
+// CHECK-NEXT:            <key>line</key><integer>605</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>595</integer>
+// CHECK-NEXT:            <key>line</key><integer>605</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -11834,12 +11118,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>595</integer>
+// CHECK-NEXT:            <key>line</key><integer>605</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>595</integer>
+// CHECK-NEXT:            <key>line</key><integer>605</integer>
 // CHECK-NEXT:            <key>col</key><integer>6</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -11851,7 +11135,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>595</integer>
+// CHECK-NEXT:       <key>line</key><integer>605</integer>
 // CHECK-NEXT:       <key>col</key><integer>6</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -11859,12 +11143,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>595</integer>
+// CHECK-NEXT:          <key>line</key><integer>605</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>595</integer>
+// CHECK-NEXT:          <key>line</key><integer>605</integer>
 // CHECK-NEXT:          <key>col</key><integer>10</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -11884,12 +11168,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>595</integer>
+// CHECK-NEXT:            <key>line</key><integer>605</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>595</integer>
+// CHECK-NEXT:            <key>line</key><integer>605</integer>
 // CHECK-NEXT:            <key>col</key><integer>6</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -11897,12 +11181,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>598</integer>
+// CHECK-NEXT:            <key>line</key><integer>608</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>598</integer>
+// CHECK-NEXT:            <key>line</key><integer>608</integer>
 // CHECK-NEXT:            <key>col</key><integer>7</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -11918,12 +11202,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>598</integer>
+// CHECK-NEXT:            <key>line</key><integer>608</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>598</integer>
+// CHECK-NEXT:            <key>line</key><integer>608</integer>
 // CHECK-NEXT:            <key>col</key><integer>7</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -11931,12 +11215,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>606</integer>
+// CHECK-NEXT:            <key>line</key><integer>616</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>606</integer>
+// CHECK-NEXT:            <key>line</key><integer>616</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -11952,12 +11236,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>606</integer>
+// CHECK-NEXT:            <key>line</key><integer>616</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>606</integer>
+// CHECK-NEXT:            <key>line</key><integer>616</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -11965,12 +11249,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>606</integer>
+// CHECK-NEXT:            <key>line</key><integer>616</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>606</integer>
+// CHECK-NEXT:            <key>line</key><integer>616</integer>
 // CHECK-NEXT:            <key>col</key><integer>9</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -11982,7 +11266,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>606</integer>
+// CHECK-NEXT:       <key>line</key><integer>616</integer>
 // CHECK-NEXT:       <key>col</key><integer>6</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -11990,12 +11274,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>606</integer>
+// CHECK-NEXT:          <key>line</key><integer>616</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>606</integer>
+// CHECK-NEXT:          <key>line</key><integer>616</integer>
 // CHECK-NEXT:          <key>col</key><integer>9</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -12015,229 +11299,229 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>606</integer>
+// CHECK-NEXT:            <key>line</key><integer>616</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>606</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>607</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>607</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>607</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>607</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>608</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>608</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>608</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>608</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>609</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>609</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>609</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>609</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>610</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>610</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>610</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>610</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>612</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>612</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>612</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>612</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>615</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>615</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>615</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>615</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>616</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>617</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>617</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>617</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>617</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>618</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>616</integer>
+// CHECK-NEXT:            <key>line</key><integer>618</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>618</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>618</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>619</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>619</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>619</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>619</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>620</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>620</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>620</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>620</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>622</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>622</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>622</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>622</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>625</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>625</integer>
+// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>control</string>
+// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:       <array>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>625</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>625</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>626</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>626</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -12249,7 +11533,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>616</integer>
+// CHECK-NEXT:       <key>line</key><integer>626</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -12257,12 +11541,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>616</integer>
+// CHECK-NEXT:          <key>line</key><integer>626</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>616</integer>
+// CHECK-NEXT:          <key>line</key><integer>626</integer>
 // CHECK-NEXT:          <key>col</key><integer>7</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -12283,7 +11567,7 @@
 // CHECK-NEXT:   <key>issue_hash</key><string>33</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>616</integer>
+// CHECK-NEXT:    <key>line</key><integer>626</integer>
 // CHECK-NEXT:    <key>col</key><integer>3</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -12292,360 +11576,11 @@
 // 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>638</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>638</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>638</integer>
-// CHECK-NEXT:            <key>col</key><integer>12</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>638</integer>
-// CHECK-NEXT:            <key>col</key><integer>12</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </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>638</integer>
-// CHECK-NEXT:       <key>col</key><integer>12</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>638</integer>
-// CHECK-NEXT:          <key>col</key><integer>12</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>638</integer>
-// CHECK-NEXT:          <key>col</key><integer>34</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>Method returns an Objective-C object 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:     </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>638</integer>
-// CHECK-NEXT:            <key>col</key><integer>12</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>638</integer>
-// CHECK-NEXT:            <key>col</key><integer>12</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>639</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>639</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>639</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>639</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>639</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:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>639</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>639</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:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Object released by directly sending the &apos;-dealloc&apos; message</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Object released by directly sending the &apos;-dealloc&apos; message</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>639</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>639</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>640</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>640</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>640</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>640</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>640</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:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Reference-counted object is used after it is released</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Reference-counted object is used after it is released</string>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:    </array>
-// CHECK-NEXT:    <key>description</key><string>Reference-counted object is used after it is released</string>
-// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
-// CHECK-NEXT:    <key>type</key><string>Use-after-release</string>
-// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT:   <key>issue_context</key><string>pr3820_ReleaseAfterDealloc</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>3</string>
-// CHECK-NEXT:   <key>location</key>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>640</integer>
-// CHECK-NEXT:    <key>col</key><integer>3</integer>
-// CHECK-NEXT:    <key>file</key><integer>0</integer>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>path</key>
-// CHECK-NEXT:    <array>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>646</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>646</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>647</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>647</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>647</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>647</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>647</integer>
-// CHECK-NEXT:            <key>col</key><integer>12</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>647</integer>
-// CHECK-NEXT:            <key>col</key><integer>12</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </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>647</integer>
-// CHECK-NEXT:       <key>col</key><integer>12</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>647</integer>
-// CHECK-NEXT:          <key>col</key><integer>12</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>647</integer>
-// CHECK-NEXT:          <key>col</key><integer>34</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>Method returns an Objective-C object 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:     </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>647</integer>
-// CHECK-NEXT:            <key>col</key><integer>12</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>647</integer>
-// CHECK-NEXT:            <key>col</key><integer>12</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>648</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>648</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
 // CHECK-NEXT:       <key>line</key><integer>648</integer>
-// CHECK-NEXT:       <key>col</key><integer>3</integer>
+// CHECK-NEXT:       <key>col</key><integer>12</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
 // CHECK-NEXT:      <key>ranges</key>
@@ -12653,33 +11588,21 @@
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
 // CHECK-NEXT:          <key>line</key><integer>648</integer>
-// CHECK-NEXT:          <key>col</key><integer>3</integer>
+// CHECK-NEXT:          <key>col</key><integer>12</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
 // CHECK-NEXT:          <key>line</key><integer>648</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:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>648</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>648</integer>
-// CHECK-NEXT:          <key>col</key><integer>6</integer>
+// CHECK-NEXT:          <key>col</key><integer>34</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>Object released</string>
+// CHECK-NEXT:      <string>Method returns an Objective-C object with a +1 retain count</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Object released</string>
+// CHECK-NEXT:      <string>Method returns an Objective-C object with a +1 retain count</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>control</string>
@@ -12695,7 +11618,7 @@
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
 // CHECK-NEXT:            <key>line</key><integer>648</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
@@ -12728,6 +11651,18 @@
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
 // CHECK-NEXT:          <key>line</key><integer>649</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>649</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:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>649</integer>
 // CHECK-NEXT:          <key>col</key><integer>4</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -12740,6 +11675,287 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Object released by directly sending the &apos;-dealloc&apos; message</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Object released by directly sending the &apos;-dealloc&apos; message</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>649</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>649</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>650</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>650</integer>
+// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>650</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>650</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>650</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:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Reference-counted object is used after it is released</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Reference-counted object is used after it is released</string>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:    </array>
+// CHECK-NEXT:    <key>description</key><string>Reference-counted object is used after it is released</string>
+// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK-NEXT:    <key>type</key><string>Use-after-release</string>
+// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT:   <key>issue_context</key><string>pr3820_ReleaseAfterDealloc</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>3</string>
+// CHECK-NEXT:   <key>location</key>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>line</key><integer>650</integer>
+// CHECK-NEXT:    <key>col</key><integer>3</integer>
+// CHECK-NEXT:    <key>file</key><integer>0</integer>
+// CHECK-NEXT:   </dict>
+// CHECK-NEXT:   </dict>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>path</key>
+// CHECK-NEXT:    <array>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>control</string>
+// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:       <array>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>656</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>656</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>657</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>657</integer>
+// CHECK-NEXT:            <key>col</key><integer>4</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>657</integer>
+// CHECK-NEXT:       <key>col</key><integer>12</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>657</integer>
+// CHECK-NEXT:          <key>col</key><integer>12</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>657</integer>
+// CHECK-NEXT:          <key>col</key><integer>34</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>Method returns an Objective-C object 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:     </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>657</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>657</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>658</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>658</integer>
+// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>658</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>658</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>658</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:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>658</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>658</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:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Object released</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Object released</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>658</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>658</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>659</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>659</integer>
+// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>659</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>659</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>659</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:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
 // CHECK-NEXT:      <string>Reference-counted object is used after it is released</string>
 // CHECK-NEXT:      <key>message</key>
 // CHECK-NEXT:      <string>Reference-counted object is used after it is released</string>
@@ -12753,7 +11969,7 @@
 // CHECK-NEXT:   <key>issue_hash</key><string>4</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>649</integer>
+// CHECK-NEXT:    <key>line</key><integer>659</integer>
 // CHECK-NEXT:    <key>col</key><integer>3</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -12769,12 +11985,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>701</integer>
+// CHECK-NEXT:            <key>line</key><integer>711</integer>
 // CHECK-NEXT:            <key>col</key><integer>2</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>701</integer>
+// CHECK-NEXT:            <key>line</key><integer>711</integer>
 // CHECK-NEXT:            <key>col</key><integer>20</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -12782,12 +11998,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>701</integer>
+// CHECK-NEXT:            <key>line</key><integer>711</integer>
 // CHECK-NEXT:            <key>col</key><integer>31</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>701</integer>
+// CHECK-NEXT:            <key>line</key><integer>711</integer>
 // CHECK-NEXT:            <key>col</key><integer>31</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -12799,7 +12015,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>701</integer>
+// CHECK-NEXT:       <key>line</key><integer>711</integer>
 // CHECK-NEXT:       <key>col</key><integer>31</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -12807,12 +12023,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>701</integer>
+// CHECK-NEXT:          <key>line</key><integer>711</integer>
 // CHECK-NEXT:          <key>col</key><integer>31</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>701</integer>
+// CHECK-NEXT:          <key>line</key><integer>711</integer>
 // CHECK-NEXT:          <key>col</key><integer>76</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -12825,44 +12041,10 @@
 // CHECK-NEXT:      <string>Method returns an Objective-C object with a +0 retain count</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>701</integer>
-// CHECK-NEXT:            <key>col</key><integer>31</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>701</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>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>701</integer>
-// CHECK-NEXT:            <key>col</key><integer>30</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>701</integer>
-// CHECK-NEXT:            <key>col</key><integer>30</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>701</integer>
+// CHECK-NEXT:       <key>line</key><integer>711</integer>
 // CHECK-NEXT:       <key>col</key><integer>30</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -12870,24 +12052,24 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>701</integer>
+// CHECK-NEXT:          <key>line</key><integer>711</integer>
 // CHECK-NEXT:          <key>col</key><integer>30</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>701</integer>
+// CHECK-NEXT:          <key>line</key><integer>711</integer>
 // CHECK-NEXT:          <key>col</key><integer>84</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:        </array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>701</integer>
+// CHECK-NEXT:          <key>line</key><integer>711</integer>
 // CHECK-NEXT:          <key>col</key><integer>31</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>701</integer>
+// CHECK-NEXT:          <key>line</key><integer>711</integer>
 // CHECK-NEXT:          <key>col</key><integer>76</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -12907,12 +12089,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>701</integer>
+// CHECK-NEXT:            <key>line</key><integer>711</integer>
 // CHECK-NEXT:            <key>col</key><integer>30</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>701</integer>
+// CHECK-NEXT:            <key>line</key><integer>711</integer>
 // CHECK-NEXT:            <key>col</key><integer>30</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -12920,13 +12102,13 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>706</integer>
-// CHECK-NEXT:            <key>col</key><integer>1</integer>
+// CHECK-NEXT:            <key>line</key><integer>711</integer>
+// CHECK-NEXT:            <key>col</key><integer>2</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>706</integer>
-// CHECK-NEXT:            <key>col</key><integer>1</integer>
+// CHECK-NEXT:            <key>line</key><integer>711</integer>
+// CHECK-NEXT:            <key>col</key><integer>20</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
@@ -12934,37 +12116,6 @@
 // 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>706</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>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;dict&apos; is not referenced later in this execution path and has a retain count of +1</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;dict&apos; is not referenced later in this execution path and has a retain count of +1</string>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:    </array>
-// CHECK-NEXT:    <key>description</key><string>Potential leak of an object stored into &apos;dict&apos;</string>
-// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
-// CHECK-NEXT:    <key>type</key><string>Leak</string>
-// CHECK-NEXT:   <key>issue_context_kind</key><string>Objective-C method</string>
-// CHECK-NEXT:   <key>issue_context</key><string>applicationDidFinishLaunching:</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>6</string>
-// CHECK-NEXT:   <key>location</key>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>706</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:   <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>
@@ -12972,12 +12123,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>713</integer>
+// CHECK-NEXT:            <key>line</key><integer>711</integer>
 // CHECK-NEXT:            <key>col</key><integer>2</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>713</integer>
+// CHECK-NEXT:            <key>line</key><integer>711</integer>
 // CHECK-NEXT:            <key>col</key><integer>20</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -12985,151 +12136,13 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>713</integer>
-// CHECK-NEXT:            <key>col</key><integer>31</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>713</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>line</key><integer>713</integer>
-// CHECK-NEXT:       <key>col</key><integer>31</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>713</integer>
-// CHECK-NEXT:          <key>col</key><integer>31</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>713</integer>
-// CHECK-NEXT:          <key>col</key><integer>76</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>Method returns an Objective-C object 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:     </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>713</integer>
-// CHECK-NEXT:            <key>col</key><integer>31</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>713</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>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>713</integer>
-// CHECK-NEXT:            <key>col</key><integer>30</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>713</integer>
-// CHECK-NEXT:            <key>col</key><integer>30</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>713</integer>
-// CHECK-NEXT:       <key>col</key><integer>30</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>713</integer>
-// CHECK-NEXT:          <key>col</key><integer>30</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>713</integer>
-// CHECK-NEXT:          <key>col</key><integer>84</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>713</integer>
-// CHECK-NEXT:          <key>col</key><integer>31</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>713</integer>
-// CHECK-NEXT:          <key>col</key><integer>76</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>Reference count incremented. The object now has a +1 retain count</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Reference count incremented. The object now has a +1 retain count</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>713</integer>
-// CHECK-NEXT:            <key>col</key><integer>30</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>713</integer>
-// CHECK-NEXT:            <key>col</key><integer>30</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>714</integer>
+// CHECK-NEXT:            <key>line</key><integer>715</integer>
 // CHECK-NEXT:            <key>col</key><integer>2</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>714</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>line</key><integer>715</integer>
+// CHECK-NEXT:            <key>col</key><integer>6</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
@@ -13144,13 +12157,13 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>714</integer>
+// CHECK-NEXT:            <key>line</key><integer>715</integer>
 // CHECK-NEXT:            <key>col</key><integer>2</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>714</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>line</key><integer>715</integer>
+// CHECK-NEXT:            <key>col</key><integer>6</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
@@ -13189,8 +12202,8 @@
 // CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>Objective-C method</string>
-// CHECK-NEXT:   <key>issue_context</key><string>radar10102244</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>4</string>
+// CHECK-NEXT:   <key>issue_context</key><string>applicationDidFinishLaunching:</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>1</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
 // CHECK-NEXT:    <key>line</key><integer>716</integer>
@@ -13209,26 +12222,130 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>724</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>line</key><integer>723</integer>
+// CHECK-NEXT:            <key>col</key><integer>2</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>724</integer>
-// CHECK-NEXT:            <key>col</key><integer>19</integer>
+// CHECK-NEXT:            <key>line</key><integer>723</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>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>725</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>line</key><integer>723</integer>
+// CHECK-NEXT:            <key>col</key><integer>31</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>725</integer>
-// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>line</key><integer>723</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>line</key><integer>723</integer>
+// CHECK-NEXT:       <key>col</key><integer>31</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>723</integer>
+// CHECK-NEXT:          <key>col</key><integer>31</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>723</integer>
+// CHECK-NEXT:          <key>col</key><integer>76</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>Method returns an Objective-C object 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:     </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>723</integer>
+// CHECK-NEXT:       <key>col</key><integer>30</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>723</integer>
+// CHECK-NEXT:          <key>col</key><integer>30</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>723</integer>
+// CHECK-NEXT:          <key>col</key><integer>84</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>723</integer>
+// CHECK-NEXT:          <key>col</key><integer>31</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>723</integer>
+// CHECK-NEXT:          <key>col</key><integer>76</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>Reference count incremented. The object now has a +1 retain count</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Reference count incremented. The object now has a +1 retain count</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>723</integer>
+// CHECK-NEXT:            <key>col</key><integer>30</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>723</integer>
+// CHECK-NEXT:            <key>col</key><integer>30</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>723</integer>
+// CHECK-NEXT:            <key>col</key><integer>2</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>723</integer>
+// CHECK-NEXT:            <key>col</key><integer>20</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
@@ -13243,26 +12360,94 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>725</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>line</key><integer>723</integer>
+// CHECK-NEXT:            <key>col</key><integer>2</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>725</integer>
-// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>line</key><integer>723</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>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>725</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
+// CHECK-NEXT:            <key>line</key><integer>724</integer>
+// CHECK-NEXT:            <key>col</key><integer>2</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>725</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
+// CHECK-NEXT:            <key>line</key><integer>724</integer>
+// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>control</string>
+// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:       <array>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>724</integer>
+// CHECK-NEXT:            <key>col</key><integer>2</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>724</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>724</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>724</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>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>724</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>724</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>726</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>726</integer>
+// CHECK-NEXT:            <key>col</key><integer>1</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
@@ -13273,7 +12458,72 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>725</integer>
+// CHECK-NEXT:       <key>line</key><integer>726</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>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;dict&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;dict&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:    </array>
+// CHECK-NEXT:    <key>description</key><string>Potential leak of an object stored into &apos;dict&apos;</string>
+// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK-NEXT:    <key>type</key><string>Leak</string>
+// CHECK-NEXT:   <key>issue_context_kind</key><string>Objective-C method</string>
+// CHECK-NEXT:   <key>issue_context</key><string>radar10102244</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>1</string>
+// CHECK-NEXT:   <key>location</key>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>line</key><integer>726</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:   <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>734</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>734</integer>
+// CHECK-NEXT:            <key>col</key><integer>19</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>735</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>735</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>735</integer>
 // CHECK-NEXT:       <key>col</key><integer>20</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -13281,12 +12531,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>725</integer>
+// CHECK-NEXT:          <key>line</key><integer>735</integer>
 // CHECK-NEXT:          <key>col</key><integer>20</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>725</integer>
+// CHECK-NEXT:          <key>line</key><integer>735</integer>
 // CHECK-NEXT:          <key>col</key><integer>34</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -13306,25 +12556,25 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>725</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
+// CHECK-NEXT:            <key>line</key><integer>735</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>725</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
+// CHECK-NEXT:            <key>line</key><integer>735</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>726</integer>
+// CHECK-NEXT:            <key>line</key><integer>736</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>726</integer>
+// CHECK-NEXT:            <key>line</key><integer>736</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -13336,7 +12586,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>726</integer>
+// CHECK-NEXT:       <key>line</key><integer>736</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -13344,12 +12594,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>726</integer>
+// CHECK-NEXT:          <key>line</key><integer>736</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>726</integer>
+// CHECK-NEXT:          <key>line</key><integer>736</integer>
 // CHECK-NEXT:          <key>col</key><integer>8</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -13370,7 +12620,7 @@
 // CHECK-NEXT:   <key>issue_hash</key><string>3</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>726</integer>
+// CHECK-NEXT:    <key>line</key><integer>736</integer>
 // CHECK-NEXT:    <key>col</key><integer>3</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -13386,12 +12636,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>801</integer>
+// CHECK-NEXT:            <key>line</key><integer>811</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>801</integer>
+// CHECK-NEXT:            <key>line</key><integer>811</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -13399,12 +12649,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>802</integer>
+// CHECK-NEXT:            <key>line</key><integer>812</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>802</integer>
+// CHECK-NEXT:            <key>line</key><integer>812</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -13416,7 +12666,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>802</integer>
+// CHECK-NEXT:       <key>line</key><integer>812</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -13424,12 +12674,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>802</integer>
+// CHECK-NEXT:          <key>line</key><integer>812</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>802</integer>
+// CHECK-NEXT:          <key>line</key><integer>812</integer>
 // CHECK-NEXT:          <key>col</key><integer>36</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -13449,12 +12699,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>802</integer>
+// CHECK-NEXT:            <key>line</key><integer>812</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>802</integer>
+// CHECK-NEXT:            <key>line</key><integer>812</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -13462,12 +12712,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>803</integer>
+// CHECK-NEXT:            <key>line</key><integer>813</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>803</integer>
+// CHECK-NEXT:            <key>line</key><integer>813</integer>
 // CHECK-NEXT:            <key>col</key><integer>8</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -13479,7 +12729,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>803</integer>
+// CHECK-NEXT:       <key>line</key><integer>813</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -13487,12 +12737,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>803</integer>
+// CHECK-NEXT:          <key>line</key><integer>813</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>803</integer>
+// CHECK-NEXT:          <key>line</key><integer>813</integer>
 // CHECK-NEXT:          <key>col</key><integer>13</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -13510,10 +12760,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>Objective-C method</string>
 // CHECK-NEXT:   <key>issue_context</key><string>_initReturningNewClassBad</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>3</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>2</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>803</integer>
+// CHECK-NEXT:    <key>line</key><integer>813</integer>
 // CHECK-NEXT:    <key>col</key><integer>3</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -13529,12 +12779,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>806</integer>
+// CHECK-NEXT:            <key>line</key><integer>816</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>806</integer>
+// CHECK-NEXT:            <key>line</key><integer>816</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -13542,12 +12792,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>807</integer>
+// CHECK-NEXT:            <key>line</key><integer>817</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>807</integer>
+// CHECK-NEXT:            <key>line</key><integer>817</integer>
 // CHECK-NEXT:            <key>col</key><integer>6</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -13556,44 +12806,10 @@
 // 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>807</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>807</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>807</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>807</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>807</integer>
+// CHECK-NEXT:       <key>line</key><integer>817</integer>
 // CHECK-NEXT:       <key>col</key><integer>10</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -13601,12 +12817,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>807</integer>
+// CHECK-NEXT:          <key>line</key><integer>817</integer>
 // CHECK-NEXT:          <key>col</key><integer>10</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>807</integer>
+// CHECK-NEXT:          <key>line</key><integer>817</integer>
 // CHECK-NEXT:          <key>col</key><integer>43</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -13626,25 +12842,25 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>807</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>line</key><integer>817</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>807</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>line</key><integer>817</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>808</integer>
+// CHECK-NEXT:            <key>line</key><integer>818</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>808</integer>
+// CHECK-NEXT:            <key>line</key><integer>818</integer>
 // CHECK-NEXT:            <key>col</key><integer>8</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -13653,44 +12869,10 @@
 // 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>808</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>808</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>808</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>808</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>808</integer>
+// CHECK-NEXT:       <key>line</key><integer>818</integer>
 // CHECK-NEXT:       <key>col</key><integer>10</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -13698,24 +12880,24 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>808</integer>
+// CHECK-NEXT:          <key>line</key><integer>818</integer>
 // CHECK-NEXT:          <key>col</key><integer>10</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>808</integer>
+// CHECK-NEXT:          <key>line</key><integer>818</integer>
 // CHECK-NEXT:          <key>col</key><integer>27</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:        </array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>808</integer>
+// CHECK-NEXT:          <key>line</key><integer>818</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>808</integer>
+// CHECK-NEXT:          <key>line</key><integer>818</integer>
 // CHECK-NEXT:          <key>col</key><integer>14</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -13728,44 +12910,10 @@
 // CHECK-NEXT:      <string>Object autoreleased</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>808</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>808</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>808</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>808</integer>
-// CHECK-NEXT:            <key>col</key><integer>8</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>808</integer>
+// CHECK-NEXT:       <key>line</key><integer>818</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -13773,12 +12921,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>808</integer>
+// CHECK-NEXT:          <key>line</key><integer>818</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>808</integer>
+// CHECK-NEXT:          <key>line</key><integer>818</integer>
 // CHECK-NEXT:          <key>col</key><integer>27</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -13799,7 +12947,7 @@
 // CHECK-NEXT:   <key>issue_hash</key><string>3</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>808</integer>
+// CHECK-NEXT:    <key>line</key><integer>818</integer>
 // CHECK-NEXT:    <key>col</key><integer>3</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -13808,44 +12956,10 @@
 // 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>846</integer>
-// CHECK-NEXT:            <key>col</key><integer>30</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>846</integer>
-// CHECK-NEXT:            <key>col</key><integer>35</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>846</integer>
-// CHECK-NEXT:            <key>col</key><integer>37</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>846</integer>
-// CHECK-NEXT:            <key>col</key><integer>37</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>846</integer>
+// CHECK-NEXT:       <key>line</key><integer>856</integer>
 // CHECK-NEXT:       <key>col</key><integer>37</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -13853,12 +12967,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>846</integer>
+// CHECK-NEXT:          <key>line</key><integer>856</integer>
 // CHECK-NEXT:          <key>col</key><integer>37</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>846</integer>
+// CHECK-NEXT:          <key>line</key><integer>856</integer>
 // CHECK-NEXT:          <key>col</key><integer>59</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -13871,44 +12985,10 @@
 // CHECK-NEXT:      <string>Method returns an Objective-C object with a +1 retain count</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>846</integer>
-// CHECK-NEXT:            <key>col</key><integer>37</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>846</integer>
-// CHECK-NEXT:            <key>col</key><integer>37</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>846</integer>
-// CHECK-NEXT:            <key>col</key><integer>30</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>846</integer>
-// CHECK-NEXT:            <key>col</key><integer>35</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>846</integer>
+// CHECK-NEXT:       <key>line</key><integer>856</integer>
 // CHECK-NEXT:       <key>col</key><integer>30</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -13916,24 +12996,24 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>846</integer>
+// CHECK-NEXT:          <key>line</key><integer>856</integer>
 // CHECK-NEXT:          <key>col</key><integer>30</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>846</integer>
+// CHECK-NEXT:          <key>line</key><integer>856</integer>
 // CHECK-NEXT:          <key>col</key><integer>59</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:        </array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>846</integer>
+// CHECK-NEXT:          <key>line</key><integer>856</integer>
 // CHECK-NEXT:          <key>col</key><integer>37</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>846</integer>
+// CHECK-NEXT:          <key>line</key><integer>856</integer>
 // CHECK-NEXT:          <key>col</key><integer>59</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -13949,7 +13029,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>846</integer>
+// CHECK-NEXT:       <key>line</key><integer>856</integer>
 // CHECK-NEXT:       <key>col</key><integer>30</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -13957,12 +13037,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>846</integer>
+// CHECK-NEXT:          <key>line</key><integer>856</integer>
 // CHECK-NEXT:          <key>col</key><integer>30</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>846</integer>
+// CHECK-NEXT:          <key>line</key><integer>856</integer>
 // CHECK-NEXT:          <key>col</key><integer>59</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -13983,7 +13063,7 @@
 // CHECK-NEXT:   <key>issue_hash</key><string>0</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>846</integer>
+// CHECK-NEXT:    <key>line</key><integer>856</integer>
 // CHECK-NEXT:    <key>col</key><integer>30</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -13992,44 +13072,10 @@
 // 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>847</integer>
-// CHECK-NEXT:            <key>col</key><integer>30</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>847</integer>
-// CHECK-NEXT:            <key>col</key><integer>35</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>847</integer>
-// CHECK-NEXT:            <key>col</key><integer>37</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>847</integer>
-// CHECK-NEXT:            <key>col</key><integer>37</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>847</integer>
+// CHECK-NEXT:       <key>line</key><integer>857</integer>
 // CHECK-NEXT:       <key>col</key><integer>37</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -14037,12 +13083,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>847</integer>
+// CHECK-NEXT:          <key>line</key><integer>857</integer>
 // CHECK-NEXT:          <key>col</key><integer>37</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>847</integer>
+// CHECK-NEXT:          <key>line</key><integer>857</integer>
 // CHECK-NEXT:          <key>col</key><integer>59</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -14055,44 +13101,10 @@
 // CHECK-NEXT:      <string>Method returns an Objective-C object with a +1 retain count</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>847</integer>
-// CHECK-NEXT:            <key>col</key><integer>37</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>847</integer>
-// CHECK-NEXT:            <key>col</key><integer>37</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>847</integer>
-// CHECK-NEXT:            <key>col</key><integer>30</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>847</integer>
-// CHECK-NEXT:            <key>col</key><integer>35</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>847</integer>
+// CHECK-NEXT:       <key>line</key><integer>857</integer>
 // CHECK-NEXT:       <key>col</key><integer>30</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -14100,24 +13112,24 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>847</integer>
+// CHECK-NEXT:          <key>line</key><integer>857</integer>
 // CHECK-NEXT:          <key>col</key><integer>30</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>847</integer>
+// CHECK-NEXT:          <key>line</key><integer>857</integer>
 // CHECK-NEXT:          <key>col</key><integer>59</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:        </array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>847</integer>
+// CHECK-NEXT:          <key>line</key><integer>857</integer>
 // CHECK-NEXT:          <key>col</key><integer>37</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>847</integer>
+// CHECK-NEXT:          <key>line</key><integer>857</integer>
 // CHECK-NEXT:          <key>col</key><integer>59</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -14133,7 +13145,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>847</integer>
+// CHECK-NEXT:       <key>line</key><integer>857</integer>
 // CHECK-NEXT:       <key>col</key><integer>30</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -14141,12 +13153,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>847</integer>
+// CHECK-NEXT:          <key>line</key><integer>857</integer>
 // CHECK-NEXT:          <key>col</key><integer>30</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>847</integer>
+// CHECK-NEXT:          <key>line</key><integer>857</integer>
 // CHECK-NEXT:          <key>col</key><integer>59</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -14167,7 +13179,7 @@
 // CHECK-NEXT:   <key>issue_hash</key><string>0</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>847</integer>
+// CHECK-NEXT:    <key>line</key><integer>857</integer>
 // CHECK-NEXT:    <key>col</key><integer>30</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -14179,7 +13191,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>851</integer>
+// CHECK-NEXT:       <key>line</key><integer>861</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -14187,12 +13199,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>851</integer>
+// CHECK-NEXT:          <key>line</key><integer>861</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>851</integer>
+// CHECK-NEXT:          <key>line</key><integer>861</integer>
 // CHECK-NEXT:          <key>col</key><integer>18</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -14208,7 +13220,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>846</integer>
+// CHECK-NEXT:       <key>line</key><integer>856</integer>
 // CHECK-NEXT:       <key>col</key><integer>1</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -14226,12 +13238,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>846</integer>
+// CHECK-NEXT:            <key>line</key><integer>856</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>846</integer>
+// CHECK-NEXT:            <key>line</key><integer>856</integer>
 // CHECK-NEXT:            <key>col</key><integer>1</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -14239,12 +13251,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>846</integer>
+// CHECK-NEXT:            <key>line</key><integer>856</integer>
 // CHECK-NEXT:            <key>col</key><integer>30</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>846</integer>
+// CHECK-NEXT:            <key>line</key><integer>856</integer>
 // CHECK-NEXT:            <key>col</key><integer>35</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -14253,44 +13265,10 @@
 // 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>846</integer>
-// CHECK-NEXT:            <key>col</key><integer>30</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>846</integer>
-// CHECK-NEXT:            <key>col</key><integer>35</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>846</integer>
-// CHECK-NEXT:            <key>col</key><integer>37</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>846</integer>
-// CHECK-NEXT:            <key>col</key><integer>37</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>846</integer>
+// CHECK-NEXT:       <key>line</key><integer>856</integer>
 // CHECK-NEXT:       <key>col</key><integer>37</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -14298,12 +13276,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>846</integer>
+// CHECK-NEXT:          <key>line</key><integer>856</integer>
 // CHECK-NEXT:          <key>col</key><integer>37</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>846</integer>
+// CHECK-NEXT:          <key>line</key><integer>856</integer>
 // CHECK-NEXT:          <key>col</key><integer>59</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -14319,7 +13297,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>851</integer>
+// CHECK-NEXT:       <key>line</key><integer>861</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -14327,18 +13305,18 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>851</integer>
+// CHECK-NEXT:          <key>line</key><integer>861</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>851</integer>
+// CHECK-NEXT:          <key>line</key><integer>861</integer>
 // CHECK-NEXT:          <key>col</key><integer>18</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:        </array>
 // CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>1</integer>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
 // CHECK-NEXT:      <string>Returning from &apos;NoCopyString&apos;</string>
 // CHECK-NEXT:      <key>message</key>
@@ -14352,12 +13330,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>851</integer>
+// CHECK-NEXT:            <key>line</key><integer>861</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>851</integer>
+// CHECK-NEXT:            <key>line</key><integer>861</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -14365,12 +13343,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>852</integer>
+// CHECK-NEXT:            <key>line</key><integer>862</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>852</integer>
+// CHECK-NEXT:            <key>line</key><integer>862</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -14382,7 +13360,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>852</integer>
+// CHECK-NEXT:       <key>line</key><integer>862</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -14390,12 +13368,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>852</integer>
+// CHECK-NEXT:          <key>line</key><integer>862</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>852</integer>
+// CHECK-NEXT:          <key>line</key><integer>862</integer>
 // CHECK-NEXT:          <key>col</key><integer>18</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -14413,10 +13391,259 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>test_RDar6859457</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>1</string>
+// CHECK-NEXT:   <key>location</key>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>line</key><integer>862</integer>
+// CHECK-NEXT:    <key>col</key><integer>3</integer>
+// CHECK-NEXT:    <key>file</key><integer>0</integer>
+// CHECK-NEXT:   </dict>
+// CHECK-NEXT:   </dict>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>path</key>
+// CHECK-NEXT:    <array>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>control</string>
+// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:       <array>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>861</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>861</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>862</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>862</integer>
+// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>862</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>862</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>862</integer>
+// CHECK-NEXT:          <key>col</key><integer>18</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Calling &apos;noCopyString&apos;</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Calling &apos;noCopyString&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>857</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_RDar6859457&apos;</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Entered call from &apos;test_RDar6859457&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>857</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>857</integer>
+// CHECK-NEXT:            <key>col</key><integer>1</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>857</integer>
+// CHECK-NEXT:            <key>col</key><integer>30</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>857</integer>
+// CHECK-NEXT:            <key>col</key><integer>35</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>857</integer>
+// CHECK-NEXT:       <key>col</key><integer>37</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>857</integer>
+// CHECK-NEXT:          <key>col</key><integer>37</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>857</integer>
+// CHECK-NEXT:          <key>col</key><integer>59</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>Method returns an Objective-C object 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:     </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>862</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>862</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>862</integer>
+// CHECK-NEXT:          <key>col</key><integer>18</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Returning from &apos;noCopyString&apos;</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Returning from &apos;noCopyString&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>862</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>862</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>863</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>863</integer>
+// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>863</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>863</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>863</integer>
+// CHECK-NEXT:          <key>col</key><integer>54</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>Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:    </array>
+// CHECK-NEXT:    <key>description</key><string>Potential leak of an object</string>
+// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK-NEXT:    <key>type</key><string>Leak</string>
+// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT:   <key>issue_context</key><string>test_RDar6859457</string>
 // CHECK-NEXT:   <key>issue_hash</key><string>2</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>852</integer>
+// CHECK-NEXT:    <key>line</key><integer>863</integer>
 // CHECK-NEXT:    <key>col</key><integer>3</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -14425,327 +13652,10 @@
 // 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>851</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>851</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>852</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>852</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>852</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>852</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>852</integer>
-// CHECK-NEXT:          <key>col</key><integer>18</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Calling &apos;noCopyString&apos;</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Calling &apos;noCopyString&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>847</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_RDar6859457&apos;</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Entered call from &apos;test_RDar6859457&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>847</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>847</integer>
-// CHECK-NEXT:            <key>col</key><integer>1</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>847</integer>
-// CHECK-NEXT:            <key>col</key><integer>30</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>847</integer>
-// CHECK-NEXT:            <key>col</key><integer>35</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>847</integer>
-// CHECK-NEXT:            <key>col</key><integer>30</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>847</integer>
-// CHECK-NEXT:            <key>col</key><integer>35</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>847</integer>
-// CHECK-NEXT:            <key>col</key><integer>37</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>847</integer>
-// CHECK-NEXT:            <key>col</key><integer>37</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>847</integer>
-// CHECK-NEXT:       <key>col</key><integer>37</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>847</integer>
-// CHECK-NEXT:          <key>col</key><integer>37</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>847</integer>
-// CHECK-NEXT:          <key>col</key><integer>59</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>Method returns an Objective-C object 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:     </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>852</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>852</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>852</integer>
-// CHECK-NEXT:          <key>col</key><integer>18</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>1</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Returning from &apos;noCopyString&apos;</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Returning from &apos;noCopyString&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>852</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>852</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>853</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>853</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>853</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>853</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>853</integer>
-// CHECK-NEXT:          <key>col</key><integer>54</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>Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1</string>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:    </array>
-// CHECK-NEXT:    <key>description</key><string>Potential leak of an object</string>
-// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
-// CHECK-NEXT:    <key>type</key><string>Leak</string>
-// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT:   <key>issue_context</key><string>test_RDar6859457</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>3</string>
-// CHECK-NEXT:   <key>location</key>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>853</integer>
-// CHECK-NEXT:    <key>col</key><integer>3</integer>
-// CHECK-NEXT:    <key>file</key><integer>0</integer>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>path</key>
-// CHECK-NEXT:    <array>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>886</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>886</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>886</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>886</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>886</integer>
+// CHECK-NEXT:       <key>line</key><integer>896</integer>
 // CHECK-NEXT:       <key>col</key><integer>10</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -14753,12 +13663,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>886</integer>
+// CHECK-NEXT:          <key>line</key><integer>896</integer>
 // CHECK-NEXT:          <key>col</key><integer>10</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>886</integer>
+// CHECK-NEXT:          <key>line</key><integer>896</integer>
 // CHECK-NEXT:          <key>col</key><integer>32</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -14771,44 +13681,10 @@
 // CHECK-NEXT:      <string>Method returns an Objective-C object with a +1 retain count</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>886</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>886</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>886</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>886</integer>
-// CHECK-NEXT:            <key>col</key><integer>8</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>886</integer>
+// CHECK-NEXT:       <key>line</key><integer>896</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -14816,24 +13692,24 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>886</integer>
+// CHECK-NEXT:          <key>line</key><integer>896</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>886</integer>
+// CHECK-NEXT:          <key>line</key><integer>896</integer>
 // CHECK-NEXT:          <key>col</key><integer>32</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:        </array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>886</integer>
+// CHECK-NEXT:          <key>line</key><integer>896</integer>
 // CHECK-NEXT:          <key>col</key><integer>10</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>886</integer>
+// CHECK-NEXT:          <key>line</key><integer>896</integer>
 // CHECK-NEXT:          <key>col</key><integer>32</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -14849,7 +13725,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>886</integer>
+// CHECK-NEXT:       <key>line</key><integer>896</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -14857,12 +13733,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>886</integer>
+// CHECK-NEXT:          <key>line</key><integer>896</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>886</integer>
+// CHECK-NEXT:          <key>line</key><integer>896</integer>
 // CHECK-NEXT:          <key>col</key><integer>32</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -14883,7 +13759,7 @@
 // CHECK-NEXT:   <key>issue_hash</key><string>1</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>886</integer>
+// CHECK-NEXT:    <key>line</key><integer>896</integer>
 // CHECK-NEXT:    <key>col</key><integer>3</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -14895,7 +13771,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>916</integer>
+// CHECK-NEXT:       <key>line</key><integer>926</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -14903,12 +13779,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>916</integer>
+// CHECK-NEXT:          <key>line</key><integer>926</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>916</integer>
+// CHECK-NEXT:          <key>line</key><integer>926</integer>
 // CHECK-NEXT:          <key>col</key><integer>38</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -14928,12 +13804,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>916</integer>
+// CHECK-NEXT:            <key>line</key><integer>926</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>916</integer>
+// CHECK-NEXT:            <key>line</key><integer>926</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -14941,12 +13817,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>917</integer>
+// CHECK-NEXT:            <key>line</key><integer>927</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>917</integer>
+// CHECK-NEXT:            <key>line</key><integer>927</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -14958,7 +13834,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>917</integer>
+// CHECK-NEXT:       <key>line</key><integer>927</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -14966,12 +13842,189 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>917</integer>
+// CHECK-NEXT:          <key>line</key><integer>927</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>917</integer>
+// CHECK-NEXT:          <key>line</key><integer>927</integer>
+// CHECK-NEXT:          <key>col</key><integer>42</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>Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:    </array>
+// CHECK-NEXT:    <key>description</key><string>Potential leak of an object</string>
+// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK-NEXT:    <key>type</key><string>Leak</string>
+// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT:   <key>issue_context</key><string>rdar6902710</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>1</string>
+// CHECK-NEXT:   <key>location</key>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>line</key><integer>927</integer>
+// CHECK-NEXT:    <key>col</key><integer>3</integer>
+// CHECK-NEXT:    <key>file</key><integer>0</integer>
+// CHECK-NEXT:   </dict>
+// CHECK-NEXT:   </dict>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>path</key>
+// CHECK-NEXT:    <array>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>control</string>
+// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:       <array>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>926</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>926</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>927</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>927</integer>
+// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>927</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>927</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>927</integer>
+// CHECK-NEXT:          <key>col</key><integer>42</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>Method returns an Objective-C object 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:     </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>927</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>927</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>928</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>928</integer>
+// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>control</string>
+// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:       <array>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>928</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>928</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>928</integer>
+// CHECK-NEXT:            <key>col</key><integer>12</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>928</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>928</integer>
+// CHECK-NEXT:       <key>col</key><integer>12</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>928</integer>
+// CHECK-NEXT:          <key>col</key><integer>12</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>928</integer>
 // CHECK-NEXT:          <key>col</key><integer>42</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -14992,8 +14045,8 @@
 // CHECK-NEXT:   <key>issue_hash</key><string>2</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>917</integer>
-// CHECK-NEXT:    <key>col</key><integer>3</integer>
+// CHECK-NEXT:    <key>line</key><integer>928</integer>
+// CHECK-NEXT:    <key>col</key><integer>12</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
 // CHECK-NEXT:   </dict>
@@ -15008,12 +14061,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>916</integer>
+// CHECK-NEXT:            <key>line</key><integer>926</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>916</integer>
+// CHECK-NEXT:            <key>line</key><integer>926</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -15021,12 +14074,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>917</integer>
+// CHECK-NEXT:            <key>line</key><integer>928</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>917</integer>
+// CHECK-NEXT:            <key>line</key><integer>928</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -15038,7 +14091,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>917</integer>
+// CHECK-NEXT:       <key>line</key><integer>928</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -15046,22 +14099,22 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>917</integer>
+// CHECK-NEXT:          <key>line</key><integer>928</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>917</integer>
-// CHECK-NEXT:          <key>col</key><integer>42</integer>
+// CHECK-NEXT:          <key>line</key><integer>928</integer>
+// CHECK-NEXT:          <key>col</key><integer>43</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>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK-NEXT:      <string>Method returns a Core Foundation object 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 a Core Foundation object with a +1 retain count</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>control</string>
@@ -15071,12 +14124,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>917</integer>
+// CHECK-NEXT:            <key>line</key><integer>928</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>917</integer>
+// CHECK-NEXT:            <key>line</key><integer>928</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -15084,12 +14137,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>918</integer>
+// CHECK-NEXT:            <key>line</key><integer>929</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>918</integer>
+// CHECK-NEXT:            <key>line</key><integer>929</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -15098,24 +14151,58 @@
 // 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>929</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>929</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>929</integer>
+// CHECK-NEXT:            <key>col</key><integer>12</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>929</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>918</integer>
-// CHECK-NEXT:       <key>col</key><integer>3</integer>
+// CHECK-NEXT:       <key>line</key><integer>929</integer>
+// CHECK-NEXT:       <key>col</key><integer>12</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>918</integer>
-// CHECK-NEXT:          <key>col</key><integer>3</integer>
+// CHECK-NEXT:          <key>line</key><integer>929</integer>
+// CHECK-NEXT:          <key>col</key><integer>12</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>918</integer>
-// CHECK-NEXT:          <key>col</key><integer>43</integer>
+// CHECK-NEXT:          <key>line</key><integer>929</integer>
+// CHECK-NEXT:          <key>col</key><integer>42</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:        </array>
@@ -15135,8 +14222,8 @@
 // CHECK-NEXT:   <key>issue_hash</key><string>3</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>918</integer>
-// CHECK-NEXT:    <key>col</key><integer>3</integer>
+// CHECK-NEXT:    <key>line</key><integer>929</integer>
+// CHECK-NEXT:    <key>col</key><integer>12</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
 // CHECK-NEXT:   </dict>
@@ -15151,12 +14238,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>916</integer>
+// CHECK-NEXT:            <key>line</key><integer>926</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>916</integer>
+// CHECK-NEXT:            <key>line</key><integer>926</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -15164,12 +14251,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>918</integer>
+// CHECK-NEXT:            <key>line</key><integer>929</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>918</integer>
+// CHECK-NEXT:            <key>line</key><integer>929</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -15181,7 +14268,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>918</integer>
+// CHECK-NEXT:       <key>line</key><integer>929</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -15189,155 +14276,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>918</integer>
+// CHECK-NEXT:          <key>line</key><integer>929</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>918</integer>
-// CHECK-NEXT:          <key>col</key><integer>43</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>Method returns a Core Foundation object with a +1 retain count</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Method returns a Core Foundation object with a +1 retain count</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>918</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>918</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>919</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>919</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>919</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>919</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>919</integer>
-// CHECK-NEXT:          <key>col</key><integer>69</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>Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1</string>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:    </array>
-// CHECK-NEXT:    <key>description</key><string>Potential leak of an object</string>
-// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
-// CHECK-NEXT:    <key>type</key><string>Leak</string>
-// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT:   <key>issue_context</key><string>rdar6902710</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>4</string>
-// CHECK-NEXT:   <key>location</key>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>919</integer>
-// CHECK-NEXT:    <key>col</key><integer>3</integer>
-// CHECK-NEXT:    <key>file</key><integer>0</integer>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>path</key>
-// CHECK-NEXT:    <array>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>916</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>916</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>919</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>919</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>919</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>919</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>919</integer>
+// CHECK-NEXT:          <key>line</key><integer>929</integer>
 // CHECK-NEXT:          <key>col</key><integer>69</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -15357,12 +14301,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>919</integer>
+// CHECK-NEXT:            <key>line</key><integer>929</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>919</integer>
+// CHECK-NEXT:            <key>line</key><integer>929</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -15370,12 +14314,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>920</integer>
+// CHECK-NEXT:            <key>line</key><integer>930</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>920</integer>
+// CHECK-NEXT:            <key>line</key><integer>930</integer>
 // CHECK-NEXT:            <key>col</key><integer>1</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -15387,7 +14331,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>920</integer>
+// CHECK-NEXT:       <key>line</key><integer>930</integer>
 // CHECK-NEXT:       <key>col</key><integer>1</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -15403,10 +14347,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>rdar6902710</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>5</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>4</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>920</integer>
+// CHECK-NEXT:    <key>line</key><integer>930</integer>
 // CHECK-NEXT:    <key>col</key><integer>1</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -15418,7 +14362,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>928</integer>
+// CHECK-NEXT:       <key>line</key><integer>938</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -15426,12 +14370,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>928</integer>
+// CHECK-NEXT:          <key>line</key><integer>938</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>928</integer>
+// CHECK-NEXT:          <key>line</key><integer>938</integer>
 // CHECK-NEXT:          <key>col</key><integer>45</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -15451,12 +14395,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>928</integer>
+// CHECK-NEXT:            <key>line</key><integer>938</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>928</integer>
+// CHECK-NEXT:            <key>line</key><integer>938</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -15464,12 +14408,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>929</integer>
+// CHECK-NEXT:            <key>line</key><integer>939</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>929</integer>
+// CHECK-NEXT:            <key>line</key><integer>939</integer>
 // CHECK-NEXT:            <key>col</key><integer>1</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -15481,7 +14425,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>929</integer>
+// CHECK-NEXT:       <key>line</key><integer>939</integer>
 // CHECK-NEXT:       <key>col</key><integer>1</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -15497,10 +14441,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>rdar6945561</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>2</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>1</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>929</integer>
+// CHECK-NEXT:    <key>line</key><integer>939</integer>
 // CHECK-NEXT:    <key>col</key><integer>1</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -15512,7 +14456,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>937</integer>
+// CHECK-NEXT:       <key>line</key><integer>947</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -15520,12 +14464,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>937</integer>
+// CHECK-NEXT:          <key>line</key><integer>947</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>937</integer>
+// CHECK-NEXT:          <key>line</key><integer>947</integer>
 // CHECK-NEXT:          <key>col</key><integer>49</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -15545,12 +14489,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>937</integer>
+// CHECK-NEXT:            <key>line</key><integer>947</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>937</integer>
+// CHECK-NEXT:            <key>line</key><integer>947</integer>
 // CHECK-NEXT:            <key>col</key><integer>19</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -15558,12 +14502,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>938</integer>
+// CHECK-NEXT:            <key>line</key><integer>948</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>938</integer>
+// CHECK-NEXT:            <key>line</key><integer>948</integer>
 // CHECK-NEXT:            <key>col</key><integer>1</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -15575,7 +14519,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>938</integer>
+// CHECK-NEXT:       <key>line</key><integer>948</integer>
 // CHECK-NEXT:       <key>col</key><integer>1</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -15591,10 +14535,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>IOBSDNameMatching_wrapper</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>2</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>1</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>938</integer>
+// CHECK-NEXT:    <key>line</key><integer>948</integer>
 // CHECK-NEXT:    <key>col</key><integer>1</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -15606,7 +14550,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>941</integer>
+// CHECK-NEXT:       <key>line</key><integer>951</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -15614,12 +14558,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>941</integer>
+// CHECK-NEXT:          <key>line</key><integer>951</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>941</integer>
+// CHECK-NEXT:          <key>line</key><integer>951</integer>
 // CHECK-NEXT:          <key>col</key><integer>25</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -15639,12 +14583,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>941</integer>
+// CHECK-NEXT:            <key>line</key><integer>951</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>941</integer>
+// CHECK-NEXT:            <key>line</key><integer>951</integer>
 // CHECK-NEXT:            <key>col</key><integer>19</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -15652,12 +14596,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>942</integer>
+// CHECK-NEXT:            <key>line</key><integer>952</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>942</integer>
+// CHECK-NEXT:            <key>line</key><integer>952</integer>
 // CHECK-NEXT:            <key>col</key><integer>1</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -15669,7 +14613,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>942</integer>
+// CHECK-NEXT:       <key>line</key><integer>952</integer>
 // CHECK-NEXT:       <key>col</key><integer>1</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -15685,10 +14629,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>IOServiceMatching_wrapper</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>2</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>1</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>942</integer>
+// CHECK-NEXT:    <key>line</key><integer>952</integer>
 // CHECK-NEXT:    <key>col</key><integer>1</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -15700,7 +14644,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>945</integer>
+// CHECK-NEXT:       <key>line</key><integer>955</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -15708,12 +14652,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>945</integer>
+// CHECK-NEXT:          <key>line</key><integer>955</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>945</integer>
+// CHECK-NEXT:          <key>line</key><integer>955</integer>
 // CHECK-NEXT:          <key>col</key><integer>29</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -15733,12 +14677,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>945</integer>
+// CHECK-NEXT:            <key>line</key><integer>955</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>945</integer>
+// CHECK-NEXT:            <key>line</key><integer>955</integer>
 // CHECK-NEXT:            <key>col</key><integer>23</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -15746,12 +14690,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>946</integer>
+// CHECK-NEXT:            <key>line</key><integer>956</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>946</integer>
+// CHECK-NEXT:            <key>line</key><integer>956</integer>
 // CHECK-NEXT:            <key>col</key><integer>1</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -15763,7 +14707,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>946</integer>
+// CHECK-NEXT:       <key>line</key><integer>956</integer>
 // CHECK-NEXT:       <key>col</key><integer>1</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -15779,10 +14723,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>IOServiceNameMatching_wrapper</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>2</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>1</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>946</integer>
+// CHECK-NEXT:    <key>line</key><integer>956</integer>
 // CHECK-NEXT:    <key>col</key><integer>1</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -15791,44 +14735,10 @@
 // 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>953</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>953</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>953</integer>
-// CHECK-NEXT:            <key>col</key><integer>30</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>953</integer>
-// CHECK-NEXT:            <key>col</key><integer>39</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>953</integer>
+// CHECK-NEXT:       <key>line</key><integer>963</integer>
 // CHECK-NEXT:       <key>col</key><integer>30</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -15836,12 +14746,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>953</integer>
+// CHECK-NEXT:          <key>line</key><integer>963</integer>
 // CHECK-NEXT:          <key>col</key><integer>30</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>953</integer>
+// CHECK-NEXT:          <key>line</key><integer>963</integer>
 // CHECK-NEXT:          <key>col</key><integer>41</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -15861,25 +14771,25 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>953</integer>
-// CHECK-NEXT:            <key>col</key><integer>30</integer>
+// CHECK-NEXT:            <key>line</key><integer>963</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>953</integer>
-// CHECK-NEXT:            <key>col</key><integer>39</integer>
+// CHECK-NEXT:            <key>line</key><integer>963</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>954</integer>
+// CHECK-NEXT:            <key>line</key><integer>964</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>954</integer>
+// CHECK-NEXT:            <key>line</key><integer>964</integer>
 // CHECK-NEXT:            <key>col</key><integer>11</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -15891,7 +14801,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>954</integer>
+// CHECK-NEXT:       <key>line</key><integer>964</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -15899,24 +14809,24 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>954</integer>
+// CHECK-NEXT:          <key>line</key><integer>964</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>954</integer>
+// CHECK-NEXT:          <key>line</key><integer>964</integer>
 // CHECK-NEXT:          <key>col</key><integer>21</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:        </array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>954</integer>
+// CHECK-NEXT:          <key>line</key><integer>964</integer>
 // CHECK-NEXT:          <key>col</key><integer>13</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>954</integer>
+// CHECK-NEXT:          <key>line</key><integer>964</integer>
 // CHECK-NEXT:          <key>col</key><integer>20</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -15936,12 +14846,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>954</integer>
+// CHECK-NEXT:            <key>line</key><integer>964</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>954</integer>
+// CHECK-NEXT:            <key>line</key><integer>964</integer>
 // CHECK-NEXT:            <key>col</key><integer>11</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -15949,12 +14859,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>955</integer>
+// CHECK-NEXT:            <key>line</key><integer>965</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>955</integer>
+// CHECK-NEXT:            <key>line</key><integer>965</integer>
 // CHECK-NEXT:            <key>col</key><integer>26</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -15966,7 +14876,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>955</integer>
+// CHECK-NEXT:       <key>line</key><integer>965</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -15974,12 +14884,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>955</integer>
+// CHECK-NEXT:          <key>line</key><integer>965</integer>
 // CHECK-NEXT:          <key>col</key><integer>58</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>955</integer>
+// CHECK-NEXT:          <key>line</key><integer>965</integer>
 // CHECK-NEXT:          <key>col</key><integer>65</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -16000,7 +14910,7 @@
 // CHECK-NEXT:   <key>issue_hash</key><string>4</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>955</integer>
+// CHECK-NEXT:    <key>line</key><integer>965</integer>
 // CHECK-NEXT:    <key>col</key><integer>3</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -16012,7 +14922,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>960</integer>
+// CHECK-NEXT:       <key>line</key><integer>970</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -16020,12 +14930,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>960</integer>
+// CHECK-NEXT:          <key>line</key><integer>970</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>960</integer>
+// CHECK-NEXT:          <key>line</key><integer>970</integer>
 // CHECK-NEXT:          <key>col</key><integer>36</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -16045,12 +14955,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>960</integer>
+// CHECK-NEXT:            <key>line</key><integer>970</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>960</integer>
+// CHECK-NEXT:            <key>line</key><integer>970</integer>
 // CHECK-NEXT:            <key>col</key><integer>27</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -16058,12 +14968,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>961</integer>
+// CHECK-NEXT:            <key>line</key><integer>971</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>961</integer>
+// CHECK-NEXT:            <key>line</key><integer>971</integer>
 // CHECK-NEXT:            <key>col</key><integer>1</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -16075,7 +14985,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>961</integer>
+// CHECK-NEXT:       <key>line</key><integer>971</integer>
 // CHECK-NEXT:       <key>col</key><integer>1</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -16091,10 +15001,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>IORegistryEntryIDMatching_wrapper</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>2</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>1</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>961</integer>
+// CHECK-NEXT:    <key>line</key><integer>971</integer>
 // CHECK-NEXT:    <key>col</key><integer>1</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -16106,7 +15016,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>965</integer>
+// CHECK-NEXT:       <key>line</key><integer>975</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -16114,12 +15024,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>965</integer>
+// CHECK-NEXT:          <key>line</key><integer>975</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>965</integer>
+// CHECK-NEXT:          <key>line</key><integer>975</integer>
 // CHECK-NEXT:          <key>col</key><integer>55</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -16139,12 +15049,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>965</integer>
+// CHECK-NEXT:            <key>line</key><integer>975</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>965</integer>
+// CHECK-NEXT:            <key>line</key><integer>975</integer>
 // CHECK-NEXT:            <key>col</key><integer>28</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -16152,12 +15062,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>966</integer>
+// CHECK-NEXT:            <key>line</key><integer>976</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>966</integer>
+// CHECK-NEXT:            <key>line</key><integer>976</integer>
 // CHECK-NEXT:            <key>col</key><integer>1</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -16169,7 +15079,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>966</integer>
+// CHECK-NEXT:       <key>line</key><integer>976</integer>
 // CHECK-NEXT:       <key>col</key><integer>1</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -16185,10 +15095,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>IOOpenFirmwarePathMatching_wrapper</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>2</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>1</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>966</integer>
+// CHECK-NEXT:    <key>line</key><integer>976</integer>
 // CHECK-NEXT:    <key>col</key><integer>1</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -16197,44 +15107,10 @@
 // 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>969</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>969</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>969</integer>
-// CHECK-NEXT:            <key>col</key><integer>30</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>969</integer>
-// CHECK-NEXT:            <key>col</key><integer>39</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>969</integer>
+// CHECK-NEXT:       <key>line</key><integer>979</integer>
 // CHECK-NEXT:       <key>col</key><integer>30</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -16242,12 +15118,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>969</integer>
+// CHECK-NEXT:          <key>line</key><integer>979</integer>
 // CHECK-NEXT:          <key>col</key><integer>30</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>969</integer>
+// CHECK-NEXT:          <key>line</key><integer>979</integer>
 // CHECK-NEXT:          <key>col</key><integer>41</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -16267,25 +15143,25 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>969</integer>
-// CHECK-NEXT:            <key>col</key><integer>30</integer>
+// CHECK-NEXT:            <key>line</key><integer>979</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>969</integer>
-// CHECK-NEXT:            <key>col</key><integer>39</integer>
+// CHECK-NEXT:            <key>line</key><integer>979</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>970</integer>
+// CHECK-NEXT:            <key>line</key><integer>980</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>970</integer>
+// CHECK-NEXT:            <key>line</key><integer>980</integer>
 // CHECK-NEXT:            <key>col</key><integer>29</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -16297,7 +15173,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>970</integer>
+// CHECK-NEXT:       <key>line</key><integer>980</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -16305,24 +15181,24 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>970</integer>
+// CHECK-NEXT:          <key>line</key><integer>980</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>970</integer>
+// CHECK-NEXT:          <key>line</key><integer>980</integer>
 // CHECK-NEXT:          <key>col</key><integer>51</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:        </array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>970</integer>
+// CHECK-NEXT:          <key>line</key><integer>980</integer>
 // CHECK-NEXT:          <key>col</key><integer>43</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>970</integer>
+// CHECK-NEXT:          <key>line</key><integer>980</integer>
 // CHECK-NEXT:          <key>col</key><integer>50</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -16342,12 +15218,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>970</integer>
+// CHECK-NEXT:            <key>line</key><integer>980</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>970</integer>
+// CHECK-NEXT:            <key>line</key><integer>980</integer>
 // CHECK-NEXT:            <key>col</key><integer>29</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -16355,12 +15231,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>971</integer>
+// CHECK-NEXT:            <key>line</key><integer>981</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>971</integer>
+// CHECK-NEXT:            <key>line</key><integer>981</integer>
 // CHECK-NEXT:            <key>col</key><integer>11</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -16372,7 +15248,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>971</integer>
+// CHECK-NEXT:       <key>line</key><integer>981</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -16380,12 +15256,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>971</integer>
+// CHECK-NEXT:          <key>line</key><integer>981</integer>
 // CHECK-NEXT:          <key>col</key><integer>13</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>971</integer>
+// CHECK-NEXT:          <key>line</key><integer>981</integer>
 // CHECK-NEXT:          <key>col</key><integer>20</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -16406,7 +15282,7 @@
 // CHECK-NEXT:   <key>issue_hash</key><string>3</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>971</integer>
+// CHECK-NEXT:    <key>line</key><integer>981</integer>
 // CHECK-NEXT:    <key>col</key><integer>3</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -16415,44 +15291,10 @@
 // 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>975</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>975</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>975</integer>
-// CHECK-NEXT:            <key>col</key><integer>30</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>975</integer>
-// CHECK-NEXT:            <key>col</key><integer>39</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>975</integer>
+// CHECK-NEXT:       <key>line</key><integer>985</integer>
 // CHECK-NEXT:       <key>col</key><integer>30</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -16460,12 +15302,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>975</integer>
+// CHECK-NEXT:          <key>line</key><integer>985</integer>
 // CHECK-NEXT:          <key>col</key><integer>30</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>975</integer>
+// CHECK-NEXT:          <key>line</key><integer>985</integer>
 // CHECK-NEXT:          <key>col</key><integer>41</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -16485,25 +15327,25 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>975</integer>
-// CHECK-NEXT:            <key>col</key><integer>30</integer>
+// CHECK-NEXT:            <key>line</key><integer>985</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>975</integer>
-// CHECK-NEXT:            <key>col</key><integer>39</integer>
+// CHECK-NEXT:            <key>line</key><integer>985</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>976</integer>
+// CHECK-NEXT:            <key>line</key><integer>986</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>976</integer>
+// CHECK-NEXT:            <key>line</key><integer>986</integer>
 // CHECK-NEXT:            <key>col</key><integer>30</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -16515,7 +15357,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>976</integer>
+// CHECK-NEXT:       <key>line</key><integer>986</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -16523,24 +15365,24 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>976</integer>
+// CHECK-NEXT:          <key>line</key><integer>986</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>976</integer>
+// CHECK-NEXT:          <key>line</key><integer>986</integer>
 // CHECK-NEXT:          <key>col</key><integer>62</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:        </array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>976</integer>
+// CHECK-NEXT:          <key>line</key><integer>986</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>976</integer>
+// CHECK-NEXT:          <key>line</key><integer>986</integer>
 // CHECK-NEXT:          <key>col</key><integer>51</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -16560,12 +15402,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>976</integer>
+// CHECK-NEXT:            <key>line</key><integer>986</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>976</integer>
+// CHECK-NEXT:            <key>line</key><integer>986</integer>
 // CHECK-NEXT:            <key>col</key><integer>30</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -16573,12 +15415,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>977</integer>
+// CHECK-NEXT:            <key>line</key><integer>987</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>977</integer>
+// CHECK-NEXT:            <key>line</key><integer>987</integer>
 // CHECK-NEXT:            <key>col</key><integer>11</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -16590,7 +15432,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>977</integer>
+// CHECK-NEXT:       <key>line</key><integer>987</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -16598,12 +15440,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>977</integer>
+// CHECK-NEXT:          <key>line</key><integer>987</integer>
 // CHECK-NEXT:          <key>col</key><integer>13</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>977</integer>
+// CHECK-NEXT:          <key>line</key><integer>987</integer>
 // CHECK-NEXT:          <key>col</key><integer>20</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -16624,7 +15466,7 @@
 // CHECK-NEXT:   <key>issue_hash</key><string>3</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>977</integer>
+// CHECK-NEXT:    <key>line</key><integer>987</integer>
 // CHECK-NEXT:    <key>col</key><integer>3</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -16633,44 +15475,10 @@
 // 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>983</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>983</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>983</integer>
-// CHECK-NEXT:            <key>col</key><integer>30</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>983</integer>
-// CHECK-NEXT:            <key>col</key><integer>39</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>983</integer>
+// CHECK-NEXT:       <key>line</key><integer>993</integer>
 // CHECK-NEXT:       <key>col</key><integer>30</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -16678,12 +15486,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>983</integer>
+// CHECK-NEXT:          <key>line</key><integer>993</integer>
 // CHECK-NEXT:          <key>col</key><integer>30</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>983</integer>
+// CHECK-NEXT:          <key>line</key><integer>993</integer>
 // CHECK-NEXT:          <key>col</key><integer>41</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -16703,25 +15511,25 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>983</integer>
-// CHECK-NEXT:            <key>col</key><integer>30</integer>
+// CHECK-NEXT:            <key>line</key><integer>993</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>983</integer>
-// CHECK-NEXT:            <key>col</key><integer>39</integer>
+// CHECK-NEXT:            <key>line</key><integer>993</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>984</integer>
+// CHECK-NEXT:            <key>line</key><integer>994</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>984</integer>
+// CHECK-NEXT:            <key>line</key><integer>994</integer>
 // CHECK-NEXT:            <key>col</key><integer>34</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -16733,7 +15541,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>984</integer>
+// CHECK-NEXT:       <key>line</key><integer>994</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -16741,24 +15549,24 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>984</integer>
+// CHECK-NEXT:          <key>line</key><integer>994</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>984</integer>
+// CHECK-NEXT:          <key>line</key><integer>994</integer>
 // CHECK-NEXT:          <key>col</key><integer>106</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:        </array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>984</integer>
+// CHECK-NEXT:          <key>line</key><integer>994</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>984</integer>
+// CHECK-NEXT:          <key>line</key><integer>994</integer>
 // CHECK-NEXT:          <key>col</key><integer>73</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -16778,12 +15586,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>984</integer>
+// CHECK-NEXT:            <key>line</key><integer>994</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>984</integer>
+// CHECK-NEXT:            <key>line</key><integer>994</integer>
 // CHECK-NEXT:            <key>col</key><integer>34</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -16791,12 +15599,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>985</integer>
+// CHECK-NEXT:            <key>line</key><integer>995</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>985</integer>
+// CHECK-NEXT:            <key>line</key><integer>995</integer>
 // CHECK-NEXT:            <key>col</key><integer>11</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -16808,7 +15616,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>985</integer>
+// CHECK-NEXT:       <key>line</key><integer>995</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -16816,12 +15624,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>985</integer>
+// CHECK-NEXT:          <key>line</key><integer>995</integer>
 // CHECK-NEXT:          <key>col</key><integer>13</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>985</integer>
+// CHECK-NEXT:          <key>line</key><integer>995</integer>
 // CHECK-NEXT:          <key>col</key><integer>20</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -16842,7 +15650,7 @@
 // CHECK-NEXT:   <key>issue_hash</key><string>4</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>985</integer>
+// CHECK-NEXT:    <key>line</key><integer>995</integer>
 // CHECK-NEXT:    <key>col</key><integer>3</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -16858,12 +15666,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1023</integer>
+// CHECK-NEXT:            <key>line</key><integer>1033</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>1023</integer>
+// CHECK-NEXT:            <key>line</key><integer>1033</integer>
 // CHECK-NEXT:            <key>col</key><integer>23</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -16871,12 +15679,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1026</integer>
+// CHECK-NEXT:            <key>line</key><integer>1036</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>1026</integer>
+// CHECK-NEXT:            <key>line</key><integer>1036</integer>
 // CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -16885,44 +15693,10 @@
 // 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>1026</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>1026</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1026</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>1026</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:     </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>1026</integer>
+// CHECK-NEXT:       <key>line</key><integer>1036</integer>
 // CHECK-NEXT:       <key>col</key><integer>22</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -16930,12 +15704,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1026</integer>
+// CHECK-NEXT:          <key>line</key><integer>1036</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>1026</integer>
+// CHECK-NEXT:          <key>line</key><integer>1036</integer>
 // CHECK-NEXT:          <key>col</key><integer>53</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -16955,59 +15729,25 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1026</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>1026</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>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1027</integer>
-// CHECK-NEXT:            <key>col</key><integer>46</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1027</integer>
-// CHECK-NEXT:            <key>col</key><integer>56</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>1027</integer>
-// CHECK-NEXT:            <key>col</key><integer>46</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1027</integer>
-// CHECK-NEXT:            <key>col</key><integer>56</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>1028</integer>
+// CHECK-NEXT:            <key>line</key><integer>1036</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>1028</integer>
+// CHECK-NEXT:            <key>line</key><integer>1036</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1038</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>1038</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -17019,7 +15759,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1028</integer>
+// CHECK-NEXT:       <key>line</key><integer>1038</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -17027,24 +15767,24 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1028</integer>
+// CHECK-NEXT:          <key>line</key><integer>1038</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>1028</integer>
+// CHECK-NEXT:          <key>line</key><integer>1038</integer>
 // CHECK-NEXT:          <key>col</key><integer>18</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:        </array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1028</integer>
+// CHECK-NEXT:          <key>line</key><integer>1038</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>1028</integer>
+// CHECK-NEXT:          <key>line</key><integer>1038</integer>
 // CHECK-NEXT:          <key>col</key><integer>9</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -17064,12 +15804,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1028</integer>
+// CHECK-NEXT:            <key>line</key><integer>1038</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>1028</integer>
+// CHECK-NEXT:            <key>line</key><integer>1038</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -17077,12 +15817,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1029</integer>
+// CHECK-NEXT:            <key>line</key><integer>1039</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>1029</integer>
+// CHECK-NEXT:            <key>line</key><integer>1039</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -17094,7 +15834,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1029</integer>
+// CHECK-NEXT:       <key>line</key><integer>1039</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -17102,24 +15842,24 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1029</integer>
+// CHECK-NEXT:          <key>line</key><integer>1039</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>1029</integer>
+// CHECK-NEXT:          <key>line</key><integer>1039</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:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1029</integer>
+// CHECK-NEXT:          <key>line</key><integer>1039</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>1029</integer>
+// CHECK-NEXT:          <key>line</key><integer>1039</integer>
 // CHECK-NEXT:          <key>col</key><integer>9</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -17139,12 +15879,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1029</integer>
+// CHECK-NEXT:            <key>line</key><integer>1039</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>1029</integer>
+// CHECK-NEXT:            <key>line</key><integer>1039</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -17152,12 +15892,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1030</integer>
+// CHECK-NEXT:            <key>line</key><integer>1040</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>1030</integer>
+// CHECK-NEXT:            <key>line</key><integer>1040</integer>
 // CHECK-NEXT:            <key>col</key><integer>11</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -17169,7 +15909,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1030</integer>
+// CHECK-NEXT:       <key>line</key><integer>1040</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -17177,12 +15917,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1030</integer>
+// CHECK-NEXT:          <key>line</key><integer>1040</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>1030</integer>
+// CHECK-NEXT:          <key>line</key><integer>1040</integer>
 // CHECK-NEXT:          <key>col</key><integer>23</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -17200,10 +15940,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>rdar_7152619</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>8</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>4</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1030</integer>
+// CHECK-NEXT:    <key>line</key><integer>1040</integer>
 // CHECK-NEXT:    <key>col</key><integer>3</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -17219,12 +15959,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1039</integer>
+// CHECK-NEXT:            <key>line</key><integer>1049</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>1039</integer>
+// CHECK-NEXT:            <key>line</key><integer>1049</integer>
 // CHECK-NEXT:            <key>col</key><integer>8</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -17232,12 +15972,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1050</integer>
+// CHECK-NEXT:            <key>line</key><integer>1060</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>1050</integer>
+// CHECK-NEXT:            <key>line</key><integer>1060</integer>
 // CHECK-NEXT:            <key>col</key><integer>15</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -17253,12 +15993,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1050</integer>
+// CHECK-NEXT:            <key>line</key><integer>1060</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>1050</integer>
+// CHECK-NEXT:            <key>line</key><integer>1060</integer>
 // CHECK-NEXT:            <key>col</key><integer>15</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -17266,12 +16006,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1051</integer>
+// CHECK-NEXT:            <key>line</key><integer>1061</integer>
 // CHECK-NEXT:            <key>col</key><integer>41</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1051</integer>
+// CHECK-NEXT:            <key>line</key><integer>1061</integer>
 // CHECK-NEXT:            <key>col</key><integer>67</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -17283,7 +16023,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1051</integer>
+// CHECK-NEXT:       <key>line</key><integer>1061</integer>
 // CHECK-NEXT:       <key>col</key><integer>41</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -17291,12 +16031,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1051</integer>
+// CHECK-NEXT:          <key>line</key><integer>1061</integer>
 // CHECK-NEXT:          <key>col</key><integer>41</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1051</integer>
+// CHECK-NEXT:          <key>line</key><integer>1061</integer>
 // CHECK-NEXT:          <key>col</key><integer>69</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -17316,12 +16056,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1051</integer>
+// CHECK-NEXT:            <key>line</key><integer>1061</integer>
 // CHECK-NEXT:            <key>col</key><integer>41</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1051</integer>
+// CHECK-NEXT:            <key>line</key><integer>1061</integer>
 // CHECK-NEXT:            <key>col</key><integer>67</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -17329,12 +16069,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1050</integer>
+// CHECK-NEXT:            <key>line</key><integer>1060</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>1050</integer>
+// CHECK-NEXT:            <key>line</key><integer>1060</integer>
 // CHECK-NEXT:            <key>col</key><integer>15</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -17346,7 +16086,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1050</integer>
+// CHECK-NEXT:       <key>line</key><integer>1060</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -17354,12 +16094,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1050</integer>
+// CHECK-NEXT:          <key>line</key><integer>1060</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>1050</integer>
+// CHECK-NEXT:          <key>line</key><integer>1060</integer>
 // CHECK-NEXT:          <key>col</key><integer>26</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -17377,10 +16117,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>rdar_7184450</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>12</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>13</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1050</integer>
+// CHECK-NEXT:    <key>line</key><integer>1060</integer>
 // CHECK-NEXT:    <key>col</key><integer>3</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -17396,12 +16136,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1061</integer>
+// CHECK-NEXT:            <key>line</key><integer>1071</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>1061</integer>
+// CHECK-NEXT:            <key>line</key><integer>1071</integer>
 // CHECK-NEXT:            <key>col</key><integer>8</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -17409,12 +16149,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1072</integer>
+// CHECK-NEXT:            <key>line</key><integer>1082</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>1072</integer>
+// CHECK-NEXT:            <key>line</key><integer>1082</integer>
 // CHECK-NEXT:            <key>col</key><integer>15</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -17430,12 +16170,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1072</integer>
+// CHECK-NEXT:            <key>line</key><integer>1082</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>1072</integer>
+// CHECK-NEXT:            <key>line</key><integer>1082</integer>
 // CHECK-NEXT:            <key>col</key><integer>15</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -17443,12 +16183,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1073</integer>
+// CHECK-NEXT:            <key>line</key><integer>1083</integer>
 // CHECK-NEXT:            <key>col</key><integer>40</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1073</integer>
+// CHECK-NEXT:            <key>line</key><integer>1083</integer>
 // CHECK-NEXT:            <key>col</key><integer>66</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -17460,7 +16200,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1073</integer>
+// CHECK-NEXT:       <key>line</key><integer>1083</integer>
 // CHECK-NEXT:       <key>col</key><integer>40</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -17468,12 +16208,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1073</integer>
+// CHECK-NEXT:          <key>line</key><integer>1083</integer>
 // CHECK-NEXT:          <key>col</key><integer>40</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1073</integer>
+// CHECK-NEXT:          <key>line</key><integer>1083</integer>
 // CHECK-NEXT:          <key>col</key><integer>68</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -17493,12 +16233,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1073</integer>
+// CHECK-NEXT:            <key>line</key><integer>1083</integer>
 // CHECK-NEXT:            <key>col</key><integer>40</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1073</integer>
+// CHECK-NEXT:            <key>line</key><integer>1083</integer>
 // CHECK-NEXT:            <key>col</key><integer>66</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -17506,12 +16246,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1072</integer>
+// CHECK-NEXT:            <key>line</key><integer>1082</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>1072</integer>
+// CHECK-NEXT:            <key>line</key><integer>1082</integer>
 // CHECK-NEXT:            <key>col</key><integer>15</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -17523,7 +16263,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1072</integer>
+// CHECK-NEXT:       <key>line</key><integer>1082</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -17531,12 +16271,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1072</integer>
+// CHECK-NEXT:          <key>line</key><integer>1082</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>1072</integer>
+// CHECK-NEXT:          <key>line</key><integer>1082</integer>
 // CHECK-NEXT:          <key>col</key><integer>26</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -17554,10 +16294,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>rdar_7184450_pos</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>12</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>13</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1072</integer>
+// CHECK-NEXT:    <key>line</key><integer>1082</integer>
 // CHECK-NEXT:    <key>col</key><integer>3</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -17573,12 +16313,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1061</integer>
+// CHECK-NEXT:            <key>line</key><integer>1071</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>1061</integer>
+// CHECK-NEXT:            <key>line</key><integer>1071</integer>
 // CHECK-NEXT:            <key>col</key><integer>8</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -17586,12 +16326,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1072</integer>
+// CHECK-NEXT:            <key>line</key><integer>1082</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>1072</integer>
+// CHECK-NEXT:            <key>line</key><integer>1082</integer>
 // CHECK-NEXT:            <key>col</key><integer>15</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -17607,12 +16347,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1072</integer>
+// CHECK-NEXT:            <key>line</key><integer>1082</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>1072</integer>
+// CHECK-NEXT:            <key>line</key><integer>1082</integer>
 // CHECK-NEXT:            <key>col</key><integer>15</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -17620,12 +16360,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1073</integer>
+// CHECK-NEXT:            <key>line</key><integer>1083</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>1073</integer>
+// CHECK-NEXT:            <key>line</key><integer>1083</integer>
 // CHECK-NEXT:            <key>col</key><integer>38</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -17637,7 +16377,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1073</integer>
+// CHECK-NEXT:       <key>line</key><integer>1083</integer>
 // CHECK-NEXT:       <key>col</key><integer>4</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -17645,12 +16385,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1073</integer>
+// CHECK-NEXT:          <key>line</key><integer>1083</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>1073</integer>
+// CHECK-NEXT:          <key>line</key><integer>1083</integer>
 // CHECK-NEXT:          <key>col</key><integer>107</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -17670,12 +16410,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1073</integer>
+// CHECK-NEXT:            <key>line</key><integer>1083</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>1073</integer>
+// CHECK-NEXT:            <key>line</key><integer>1083</integer>
 // CHECK-NEXT:            <key>col</key><integer>38</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -17683,12 +16423,46 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1077</integer>
+// CHECK-NEXT:            <key>line</key><integer>1085</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>1085</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:       </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>1085</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>1085</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:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1087</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>1077</integer>
+// CHECK-NEXT:            <key>line</key><integer>1087</integer>
 // CHECK-NEXT:            <key>col</key><integer>1</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -17700,7 +16474,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1077</integer>
+// CHECK-NEXT:       <key>line</key><integer>1087</integer>
 // CHECK-NEXT:       <key>col</key><integer>1</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -17716,10 +16490,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>rdar_7184450_pos</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>17</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>13</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1077</integer>
+// CHECK-NEXT:    <key>line</key><integer>1087</integer>
 // CHECK-NEXT:    <key>col</key><integer>1</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -17728,44 +16502,10 @@
 // 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>1111</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>1111</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1111</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>1111</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:     </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>1111</integer>
+// CHECK-NEXT:       <key>line</key><integer>1121</integer>
 // CHECK-NEXT:       <key>col</key><integer>22</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -17773,12 +16513,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1111</integer>
+// CHECK-NEXT:          <key>line</key><integer>1121</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>1111</integer>
+// CHECK-NEXT:          <key>line</key><integer>1121</integer>
 // CHECK-NEXT:          <key>col</key><integer>53</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -17798,25 +16538,25 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1111</integer>
-// CHECK-NEXT:            <key>col</key><integer>22</integer>
+// CHECK-NEXT:            <key>line</key><integer>1121</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>1111</integer>
-// CHECK-NEXT:            <key>col</key><integer>22</integer>
+// CHECK-NEXT:            <key>line</key><integer>1121</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1112</integer>
+// CHECK-NEXT:            <key>line</key><integer>1122</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>1112</integer>
+// CHECK-NEXT:            <key>line</key><integer>1122</integer>
 // CHECK-NEXT:            <key>col</key><integer>1</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -17828,7 +16568,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1112</integer>
+// CHECK-NEXT:       <key>line</key><integer>1122</integer>
 // CHECK-NEXT:       <key>col</key><integer>1</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -17844,10 +16584,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>rdar_7299394_positive</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>2</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>1</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1112</integer>
+// CHECK-NEXT:    <key>line</key><integer>1122</integer>
 // CHECK-NEXT:    <key>col</key><integer>1</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -17863,12 +16603,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1244</integer>
+// CHECK-NEXT:            <key>line</key><integer>1254</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>1244</integer>
+// CHECK-NEXT:            <key>line</key><integer>1254</integer>
 // CHECK-NEXT:            <key>col</key><integer>12</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -17876,12 +16616,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1246</integer>
+// CHECK-NEXT:            <key>line</key><integer>1256</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>1246</integer>
+// CHECK-NEXT:            <key>line</key><integer>1256</integer>
 // CHECK-NEXT:            <key>col</key><integer>31</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -17893,7 +16633,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1246</integer>
+// CHECK-NEXT:       <key>line</key><integer>1256</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -17901,12 +16641,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1246</integer>
+// CHECK-NEXT:          <key>line</key><integer>1256</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>1247</integer>
+// CHECK-NEXT:          <key>line</key><integer>1257</integer>
 // CHECK-NEXT:          <key>col</key><integer>60</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -17926,12 +16666,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1246</integer>
+// CHECK-NEXT:            <key>line</key><integer>1256</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>1246</integer>
+// CHECK-NEXT:            <key>line</key><integer>1256</integer>
 // CHECK-NEXT:            <key>col</key><integer>31</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -17939,12 +16679,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1248</integer>
+// CHECK-NEXT:            <key>line</key><integer>1258</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>1248</integer>
+// CHECK-NEXT:            <key>line</key><integer>1258</integer>
 // CHECK-NEXT:            <key>col</key><integer>1</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -17956,7 +16696,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1248</integer>
+// CHECK-NEXT:       <key>line</key><integer>1258</integer>
 // CHECK-NEXT:       <key>col</key><integer>1</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -17972,10 +16712,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>rdar_7358899</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>9</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>7</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1248</integer>
+// CHECK-NEXT:    <key>line</key><integer>1258</integer>
 // CHECK-NEXT:    <key>col</key><integer>1</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -17984,44 +16724,10 @@
 // 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>1264</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>1264</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>1264</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1264</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1264</integer>
+// CHECK-NEXT:       <key>line</key><integer>1274</integer>
 // CHECK-NEXT:       <key>col</key><integer>10</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -18029,12 +16735,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1264</integer>
+// CHECK-NEXT:          <key>line</key><integer>1274</integer>
 // CHECK-NEXT:          <key>col</key><integer>10</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1264</integer>
+// CHECK-NEXT:          <key>line</key><integer>1274</integer>
 // CHECK-NEXT:          <key>col</key><integer>22</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -18054,25 +16760,25 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1264</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>line</key><integer>1274</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>1264</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>line</key><integer>1274</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>1265</integer>
+// CHECK-NEXT:            <key>line</key><integer>1275</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>1265</integer>
+// CHECK-NEXT:            <key>line</key><integer>1275</integer>
 // CHECK-NEXT:            <key>col</key><integer>1</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -18084,7 +16790,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1265</integer>
+// CHECK-NEXT:       <key>line</key><integer>1275</integer>
 // CHECK-NEXT:       <key>col</key><integer>1</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -18100,10 +16806,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>rdar7265711_a</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>2</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>1</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1265</integer>
+// CHECK-NEXT:    <key>line</key><integer>1275</integer>
 // CHECK-NEXT:    <key>col</key><integer>1</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -18119,12 +16825,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1284</integer>
+// CHECK-NEXT:            <key>line</key><integer>1294</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>1284</integer>
+// CHECK-NEXT:            <key>line</key><integer>1294</integer>
 // CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -18132,12 +16838,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1285</integer>
+// CHECK-NEXT:            <key>line</key><integer>1295</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>1285</integer>
+// CHECK-NEXT:            <key>line</key><integer>1295</integer>
 // CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -18146,44 +16852,10 @@
 // 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>1285</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>1285</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1285</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>1285</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:     </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>1285</integer>
+// CHECK-NEXT:       <key>line</key><integer>1295</integer>
 // CHECK-NEXT:       <key>col</key><integer>22</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -18191,12 +16863,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1285</integer>
+// CHECK-NEXT:          <key>line</key><integer>1295</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>1285</integer>
+// CHECK-NEXT:          <key>line</key><integer>1295</integer>
 // CHECK-NEXT:          <key>col</key><integer>53</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -18216,25 +16888,25 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1285</integer>
-// CHECK-NEXT:            <key>col</key><integer>22</integer>
+// CHECK-NEXT:            <key>line</key><integer>1295</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>1285</integer>
-// CHECK-NEXT:            <key>col</key><integer>22</integer>
+// CHECK-NEXT:            <key>line</key><integer>1295</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1286</integer>
+// CHECK-NEXT:            <key>line</key><integer>1296</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>1286</integer>
+// CHECK-NEXT:            <key>line</key><integer>1296</integer>
 // CHECK-NEXT:            <key>col</key><integer>1</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -18246,7 +16918,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1286</integer>
+// CHECK-NEXT:       <key>line</key><integer>1296</integer>
 // CHECK-NEXT:       <key>col</key><integer>1</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -18262,10 +16934,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>rdar7306898</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>5</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>4</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1286</integer>
+// CHECK-NEXT:    <key>line</key><integer>1296</integer>
 // CHECK-NEXT:    <key>col</key><integer>1</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -18277,7 +16949,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1295</integer>
+// CHECK-NEXT:       <key>line</key><integer>1305</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -18285,12 +16957,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1295</integer>
+// CHECK-NEXT:          <key>line</key><integer>1305</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>1295</integer>
+// CHECK-NEXT:          <key>line</key><integer>1305</integer>
 // CHECK-NEXT:          <key>col</key><integer>23</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -18311,7 +16983,7 @@
 // CHECK-NEXT:   <key>issue_hash</key><string>1</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1295</integer>
+// CHECK-NEXT:    <key>line</key><integer>1305</integer>
 // CHECK-NEXT:    <key>col</key><integer>3</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -18327,12 +16999,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1295</integer>
+// CHECK-NEXT:            <key>line</key><integer>1305</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>1295</integer>
+// CHECK-NEXT:            <key>line</key><integer>1305</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -18340,12 +17012,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1296</integer>
+// CHECK-NEXT:            <key>line</key><integer>1306</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>1296</integer>
+// CHECK-NEXT:            <key>line</key><integer>1306</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -18357,7 +17029,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1296</integer>
+// CHECK-NEXT:       <key>line</key><integer>1306</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -18365,12 +17037,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1296</integer>
+// CHECK-NEXT:          <key>line</key><integer>1306</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>1296</integer>
+// CHECK-NEXT:          <key>line</key><integer>1306</integer>
 // CHECK-NEXT:          <key>col</key><integer>22</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -18391,7 +17063,7 @@
 // CHECK-NEXT:   <key>issue_hash</key><string>2</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1296</integer>
+// CHECK-NEXT:    <key>line</key><integer>1306</integer>
 // CHECK-NEXT:    <key>col</key><integer>3</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -18407,12 +17079,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1295</integer>
+// CHECK-NEXT:            <key>line</key><integer>1305</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>1295</integer>
+// CHECK-NEXT:            <key>line</key><integer>1305</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -18420,12 +17092,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1297</integer>
+// CHECK-NEXT:            <key>line</key><integer>1307</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>1297</integer>
+// CHECK-NEXT:            <key>line</key><integer>1307</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -18437,7 +17109,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1297</integer>
+// CHECK-NEXT:       <key>line</key><integer>1307</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -18445,12 +17117,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1297</integer>
+// CHECK-NEXT:          <key>line</key><integer>1307</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>1297</integer>
+// CHECK-NEXT:          <key>line</key><integer>1307</integer>
 // CHECK-NEXT:          <key>col</key><integer>27</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -18471,7 +17143,7 @@
 // CHECK-NEXT:   <key>issue_hash</key><string>3</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1297</integer>
+// CHECK-NEXT:    <key>line</key><integer>1307</integer>
 // CHECK-NEXT:    <key>col</key><integer>3</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -18487,12 +17159,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1295</integer>
+// CHECK-NEXT:            <key>line</key><integer>1305</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>1295</integer>
+// CHECK-NEXT:            <key>line</key><integer>1305</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -18500,12 +17172,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1298</integer>
+// CHECK-NEXT:            <key>line</key><integer>1308</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>1298</integer>
+// CHECK-NEXT:            <key>line</key><integer>1308</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -18517,7 +17189,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1298</integer>
+// CHECK-NEXT:       <key>line</key><integer>1308</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -18525,12 +17197,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1298</integer>
+// CHECK-NEXT:          <key>line</key><integer>1308</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>1298</integer>
+// CHECK-NEXT:          <key>line</key><integer>1308</integer>
 // CHECK-NEXT:          <key>col</key><integer>27</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -18551,7 +17223,7 @@
 // CHECK-NEXT:   <key>issue_hash</key><string>4</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1298</integer>
+// CHECK-NEXT:    <key>line</key><integer>1308</integer>
 // CHECK-NEXT:    <key>col</key><integer>3</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -18560,44 +17232,10 @@
 // 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>1325</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>1325</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1325</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>1325</integer>
-// CHECK-NEXT:            <key>col</key><integer>19</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>1325</integer>
+// CHECK-NEXT:       <key>line</key><integer>1335</integer>
 // CHECK-NEXT:       <key>col</key><integer>19</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -18605,12 +17243,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1325</integer>
+// CHECK-NEXT:          <key>line</key><integer>1335</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>1325</integer>
+// CHECK-NEXT:          <key>line</key><integer>1335</integer>
 // CHECK-NEXT:          <key>col</key><integer>42</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -18630,25 +17268,25 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1325</integer>
-// CHECK-NEXT:            <key>col</key><integer>19</integer>
+// CHECK-NEXT:            <key>line</key><integer>1335</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>1325</integer>
-// CHECK-NEXT:            <key>col</key><integer>19</integer>
+// CHECK-NEXT:            <key>line</key><integer>1335</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1326</integer>
+// CHECK-NEXT:            <key>line</key><integer>1336</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>1326</integer>
+// CHECK-NEXT:            <key>line</key><integer>1336</integer>
 // CHECK-NEXT:            <key>col</key><integer>1</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -18660,7 +17298,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1326</integer>
+// CHECK-NEXT:       <key>line</key><integer>1336</integer>
 // CHECK-NEXT:       <key>col</key><integer>1</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -18676,10 +17314,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>test_attr_1</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>2</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>1</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1326</integer>
+// CHECK-NEXT:    <key>line</key><integer>1336</integer>
 // CHECK-NEXT:    <key>col</key><integer>1</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -18688,44 +17326,10 @@
 // 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>1329</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>1329</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1329</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>1329</integer>
-// CHECK-NEXT:            <key>col</key><integer>19</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>1329</integer>
+// CHECK-NEXT:       <key>line</key><integer>1339</integer>
 // CHECK-NEXT:       <key>col</key><integer>19</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -18733,12 +17337,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1329</integer>
+// CHECK-NEXT:          <key>line</key><integer>1339</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>1329</integer>
+// CHECK-NEXT:          <key>line</key><integer>1339</integer>
 // CHECK-NEXT:          <key>col</key><integer>44</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -18758,25 +17362,25 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1329</integer>
-// CHECK-NEXT:            <key>col</key><integer>19</integer>
+// CHECK-NEXT:            <key>line</key><integer>1339</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>1329</integer>
-// CHECK-NEXT:            <key>col</key><integer>19</integer>
+// CHECK-NEXT:            <key>line</key><integer>1339</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1330</integer>
+// CHECK-NEXT:            <key>line</key><integer>1340</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>1330</integer>
+// CHECK-NEXT:            <key>line</key><integer>1340</integer>
 // CHECK-NEXT:            <key>col</key><integer>1</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -18788,7 +17392,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1330</integer>
+// CHECK-NEXT:       <key>line</key><integer>1340</integer>
 // CHECK-NEXT:       <key>col</key><integer>1</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -18804,10 +17408,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>test_attr_1b</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>2</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>1</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1330</integer>
+// CHECK-NEXT:    <key>line</key><integer>1340</integer>
 // CHECK-NEXT:    <key>col</key><integer>1</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -18823,12 +17427,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1333</integer>
+// CHECK-NEXT:            <key>line</key><integer>1343</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>1333</integer>
+// CHECK-NEXT:            <key>line</key><integer>1343</integer>
 // CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -18836,12 +17440,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1334</integer>
+// CHECK-NEXT:            <key>line</key><integer>1344</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>1334</integer>
+// CHECK-NEXT:            <key>line</key><integer>1344</integer>
 // CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -18850,44 +17454,10 @@
 // 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>1334</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>1334</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1334</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1334</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:     </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>1334</integer>
+// CHECK-NEXT:       <key>line</key><integer>1344</integer>
 // CHECK-NEXT:       <key>col</key><integer>20</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -18895,12 +17465,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1334</integer>
+// CHECK-NEXT:          <key>line</key><integer>1344</integer>
 // CHECK-NEXT:          <key>col</key><integer>20</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1334</integer>
+// CHECK-NEXT:          <key>line</key><integer>1344</integer>
 // CHECK-NEXT:          <key>col</key><integer>38</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -18920,25 +17490,25 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1334</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
+// CHECK-NEXT:            <key>line</key><integer>1344</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>1334</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
+// CHECK-NEXT:            <key>line</key><integer>1344</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1335</integer>
+// CHECK-NEXT:            <key>line</key><integer>1345</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>1335</integer>
+// CHECK-NEXT:            <key>line</key><integer>1345</integer>
 // CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -18954,12 +17524,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1335</integer>
+// CHECK-NEXT:            <key>line</key><integer>1345</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>1335</integer>
+// CHECK-NEXT:            <key>line</key><integer>1345</integer>
 // CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -18967,12 +17537,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1335</integer>
+// CHECK-NEXT:            <key>line</key><integer>1345</integer>
 // CHECK-NEXT:            <key>col</key><integer>20</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1335</integer>
+// CHECK-NEXT:            <key>line</key><integer>1345</integer>
 // CHECK-NEXT:            <key>col</key><integer>20</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -18984,7 +17554,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1335</integer>
+// CHECK-NEXT:       <key>line</key><integer>1345</integer>
 // CHECK-NEXT:       <key>col</key><integer>20</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -18992,12 +17562,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1335</integer>
+// CHECK-NEXT:          <key>line</key><integer>1345</integer>
 // CHECK-NEXT:          <key>col</key><integer>20</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1335</integer>
+// CHECK-NEXT:          <key>line</key><integer>1345</integer>
 // CHECK-NEXT:          <key>col</key><integer>37</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -19015,10 +17585,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>test_attr1c</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>3</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>2</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1335</integer>
+// CHECK-NEXT:    <key>line</key><integer>1345</integer>
 // CHECK-NEXT:    <key>col</key><integer>20</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -19034,12 +17604,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1333</integer>
+// CHECK-NEXT:            <key>line</key><integer>1343</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>1333</integer>
+// CHECK-NEXT:            <key>line</key><integer>1343</integer>
 // CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -19047,12 +17617,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1336</integer>
+// CHECK-NEXT:            <key>line</key><integer>1346</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>1336</integer>
+// CHECK-NEXT:            <key>line</key><integer>1346</integer>
 // CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -19068,12 +17638,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1336</integer>
+// CHECK-NEXT:            <key>line</key><integer>1346</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>1336</integer>
+// CHECK-NEXT:            <key>line</key><integer>1346</integer>
 // CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -19081,12 +17651,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1336</integer>
+// CHECK-NEXT:            <key>line</key><integer>1346</integer>
 // CHECK-NEXT:            <key>col</key><integer>21</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1336</integer>
+// CHECK-NEXT:            <key>line</key><integer>1346</integer>
 // CHECK-NEXT:            <key>col</key><integer>21</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -19098,7 +17668,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1336</integer>
+// CHECK-NEXT:       <key>line</key><integer>1346</integer>
 // CHECK-NEXT:       <key>col</key><integer>21</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -19106,12 +17676,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1336</integer>
+// CHECK-NEXT:          <key>line</key><integer>1346</integer>
 // CHECK-NEXT:          <key>col</key><integer>21</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1336</integer>
+// CHECK-NEXT:          <key>line</key><integer>1346</integer>
 // CHECK-NEXT:          <key>col</key><integer>38</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -19124,44 +17694,10 @@
 // CHECK-NEXT:      <string>Method returns an Objective-C object with a +0 retain count</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>1336</integer>
-// CHECK-NEXT:            <key>col</key><integer>21</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1336</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>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1336</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1336</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:     </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>1336</integer>
+// CHECK-NEXT:       <key>line</key><integer>1346</integer>
 // CHECK-NEXT:       <key>col</key><integer>20</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -19169,24 +17705,24 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1336</integer>
+// CHECK-NEXT:          <key>line</key><integer>1346</integer>
 // CHECK-NEXT:          <key>col</key><integer>20</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1336</integer>
+// CHECK-NEXT:          <key>line</key><integer>1346</integer>
 // CHECK-NEXT:          <key>col</key><integer>46</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:        </array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1336</integer>
+// CHECK-NEXT:          <key>line</key><integer>1346</integer>
 // CHECK-NEXT:          <key>col</key><integer>21</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1336</integer>
+// CHECK-NEXT:          <key>line</key><integer>1346</integer>
 // CHECK-NEXT:          <key>col</key><integer>38</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -19206,12 +17742,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1336</integer>
+// CHECK-NEXT:            <key>line</key><integer>1346</integer>
 // CHECK-NEXT:            <key>col</key><integer>20</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1336</integer>
+// CHECK-NEXT:            <key>line</key><integer>1346</integer>
 // CHECK-NEXT:            <key>col</key><integer>20</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -19219,12 +17755,46 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1337</integer>
+// CHECK-NEXT:            <key>line</key><integer>1346</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>1346</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>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>1346</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>1346</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1347</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>1337</integer>
+// CHECK-NEXT:            <key>line</key><integer>1347</integer>
 // CHECK-NEXT:            <key>col</key><integer>1</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -19236,7 +17806,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1337</integer>
+// CHECK-NEXT:       <key>line</key><integer>1347</integer>
 // CHECK-NEXT:       <key>col</key><integer>1</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -19252,10 +17822,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>test_attr1c</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>5</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>4</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1337</integer>
+// CHECK-NEXT:    <key>line</key><integer>1347</integer>
 // CHECK-NEXT:    <key>col</key><integer>1</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -19264,44 +17834,10 @@
 // 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>1340</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>1340</integer>
-// CHECK-NEXT:            <key>col</key><integer>19</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>1340</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>1340</integer>
-// CHECK-NEXT:            <key>col</key><integer>26</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1340</integer>
+// CHECK-NEXT:       <key>line</key><integer>1350</integer>
 // CHECK-NEXT:       <key>col</key><integer>26</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -19309,12 +17845,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1340</integer>
+// CHECK-NEXT:          <key>line</key><integer>1350</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>1340</integer>
+// CHECK-NEXT:          <key>line</key><integer>1350</integer>
 // CHECK-NEXT:          <key>col</key><integer>50</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -19334,25 +17870,25 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1340</integer>
-// CHECK-NEXT:            <key>col</key><integer>26</integer>
+// CHECK-NEXT:            <key>line</key><integer>1350</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>1340</integer>
-// CHECK-NEXT:            <key>col</key><integer>26</integer>
+// CHECK-NEXT:            <key>line</key><integer>1350</integer>
+// CHECK-NEXT:            <key>col</key><integer>19</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>1341</integer>
+// CHECK-NEXT:            <key>line</key><integer>1351</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>1341</integer>
+// CHECK-NEXT:            <key>line</key><integer>1351</integer>
 // CHECK-NEXT:            <key>col</key><integer>1</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -19364,7 +17900,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1341</integer>
+// CHECK-NEXT:       <key>line</key><integer>1351</integer>
 // CHECK-NEXT:       <key>col</key><integer>1</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -19380,10 +17916,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>testattr2_a</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>2</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>1</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1341</integer>
+// CHECK-NEXT:    <key>line</key><integer>1351</integer>
 // CHECK-NEXT:    <key>col</key><integer>1</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -19392,44 +17928,10 @@
 // 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>1344</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>1344</integer>
-// CHECK-NEXT:            <key>col</key><integer>19</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>1344</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>1344</integer>
-// CHECK-NEXT:            <key>col</key><integer>26</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1344</integer>
+// CHECK-NEXT:       <key>line</key><integer>1354</integer>
 // CHECK-NEXT:       <key>col</key><integer>26</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -19437,12 +17939,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1344</integer>
+// CHECK-NEXT:          <key>line</key><integer>1354</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>1344</integer>
+// CHECK-NEXT:          <key>line</key><integer>1354</integer>
 // CHECK-NEXT:          <key>col</key><integer>63</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -19462,25 +17964,25 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1344</integer>
-// CHECK-NEXT:            <key>col</key><integer>26</integer>
+// CHECK-NEXT:            <key>line</key><integer>1354</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>1344</integer>
-// CHECK-NEXT:            <key>col</key><integer>26</integer>
+// CHECK-NEXT:            <key>line</key><integer>1354</integer>
+// CHECK-NEXT:            <key>col</key><integer>19</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>1345</integer>
+// CHECK-NEXT:            <key>line</key><integer>1355</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>1345</integer>
+// CHECK-NEXT:            <key>line</key><integer>1355</integer>
 // CHECK-NEXT:            <key>col</key><integer>1</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -19492,7 +17994,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1345</integer>
+// CHECK-NEXT:       <key>line</key><integer>1355</integer>
 // CHECK-NEXT:       <key>col</key><integer>1</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -19508,10 +18010,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>testattr2_b</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>2</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>1</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1345</integer>
+// CHECK-NEXT:    <key>line</key><integer>1355</integer>
 // CHECK-NEXT:    <key>col</key><integer>1</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -19520,44 +18022,10 @@
 // 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>1348</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>1348</integer>
-// CHECK-NEXT:            <key>col</key><integer>19</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>1348</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>1348</integer>
-// CHECK-NEXT:            <key>col</key><integer>26</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1348</integer>
+// CHECK-NEXT:       <key>line</key><integer>1358</integer>
 // CHECK-NEXT:       <key>col</key><integer>26</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -19565,12 +18033,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1348</integer>
+// CHECK-NEXT:          <key>line</key><integer>1358</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>1348</integer>
+// CHECK-NEXT:          <key>line</key><integer>1358</integer>
 // CHECK-NEXT:          <key>col</key><integer>63</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -19590,25 +18058,59 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1348</integer>
-// CHECK-NEXT:            <key>col</key><integer>26</integer>
+// CHECK-NEXT:            <key>line</key><integer>1358</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>1348</integer>
-// CHECK-NEXT:            <key>col</key><integer>26</integer>
+// CHECK-NEXT:            <key>line</key><integer>1358</integer>
+// CHECK-NEXT:            <key>col</key><integer>19</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>1350</integer>
+// CHECK-NEXT:            <key>line</key><integer>1359</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>1359</integer>
+// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>control</string>
+// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:       <array>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1359</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>1359</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>1360</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>1350</integer>
+// CHECK-NEXT:            <key>line</key><integer>1360</integer>
 // CHECK-NEXT:            <key>col</key><integer>1</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -19620,7 +18122,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1350</integer>
+// CHECK-NEXT:       <key>line</key><integer>1360</integer>
 // CHECK-NEXT:       <key>col</key><integer>1</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -19636,10 +18138,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>testattr2_b_11358224_self_assign_looses_the_leak</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>3</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>1</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1350</integer>
+// CHECK-NEXT:    <key>line</key><integer>1360</integer>
 // CHECK-NEXT:    <key>col</key><integer>1</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -19648,44 +18150,10 @@
 // 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>1380</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>1380</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>1380</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1380</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1380</integer>
+// CHECK-NEXT:       <key>line</key><integer>1390</integer>
 // CHECK-NEXT:       <key>col</key><integer>10</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -19693,12 +18161,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1380</integer>
+// CHECK-NEXT:          <key>line</key><integer>1390</integer>
 // CHECK-NEXT:          <key>col</key><integer>10</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1380</integer>
+// CHECK-NEXT:          <key>line</key><integer>1390</integer>
 // CHECK-NEXT:          <key>col</key><integer>25</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -19711,44 +18179,10 @@
 // CHECK-NEXT:      <string>Method returns an Objective-C object with a +1 retain count</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>1380</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1380</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1380</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>1380</integer>
-// CHECK-NEXT:            <key>col</key><integer>8</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1380</integer>
+// CHECK-NEXT:       <key>line</key><integer>1390</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -19756,24 +18190,24 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1380</integer>
+// CHECK-NEXT:          <key>line</key><integer>1390</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>1380</integer>
+// CHECK-NEXT:          <key>line</key><integer>1390</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:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1380</integer>
+// CHECK-NEXT:          <key>line</key><integer>1390</integer>
 // CHECK-NEXT:          <key>col</key><integer>10</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1380</integer>
+// CHECK-NEXT:          <key>line</key><integer>1390</integer>
 // CHECK-NEXT:          <key>col</key><integer>25</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -19789,7 +18223,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1380</integer>
+// CHECK-NEXT:       <key>line</key><integer>1390</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -19797,12 +18231,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1380</integer>
+// CHECK-NEXT:          <key>line</key><integer>1390</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>1380</integer>
+// CHECK-NEXT:          <key>line</key><integer>1390</integer>
 // CHECK-NEXT:          <key>col</key><integer>25</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -19823,7 +18257,7 @@
 // CHECK-NEXT:   <key>issue_hash</key><string>1</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1380</integer>
+// CHECK-NEXT:    <key>line</key><integer>1390</integer>
 // CHECK-NEXT:    <key>col</key><integer>3</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -19839,12 +18273,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1413</integer>
+// CHECK-NEXT:            <key>line</key><integer>1423</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>1413</integer>
+// CHECK-NEXT:            <key>line</key><integer>1423</integer>
 // CHECK-NEXT:            <key>col</key><integer>8</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -19852,12 +18286,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1413</integer>
+// CHECK-NEXT:            <key>line</key><integer>1423</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>1413</integer>
+// CHECK-NEXT:            <key>line</key><integer>1423</integer>
 // CHECK-NEXT:            <key>col</key><integer>26</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -19869,7 +18303,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1413</integer>
+// CHECK-NEXT:       <key>line</key><integer>1423</integer>
 // CHECK-NEXT:       <key>col</key><integer>26</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -19877,12 +18311,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1413</integer>
+// CHECK-NEXT:          <key>line</key><integer>1423</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>1413</integer>
+// CHECK-NEXT:          <key>line</key><integer>1423</integer>
 // CHECK-NEXT:          <key>col</key><integer>53</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -19898,7 +18332,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1404</integer>
+// CHECK-NEXT:       <key>line</key><integer>1414</integer>
 // CHECK-NEXT:       <key>col</key><integer>1</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -19916,12 +18350,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1404</integer>
+// CHECK-NEXT:            <key>line</key><integer>1414</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>1404</integer>
+// CHECK-NEXT:            <key>line</key><integer>1414</integer>
 // CHECK-NEXT:            <key>col</key><integer>1</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -19929,12 +18363,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1405</integer>
+// CHECK-NEXT:            <key>line</key><integer>1415</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>1405</integer>
+// CHECK-NEXT:            <key>line</key><integer>1415</integer>
 // CHECK-NEXT:            <key>col</key><integer>8</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -19950,12 +18384,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1405</integer>
+// CHECK-NEXT:            <key>line</key><integer>1415</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>1405</integer>
+// CHECK-NEXT:            <key>line</key><integer>1415</integer>
 // CHECK-NEXT:            <key>col</key><integer>8</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -19963,12 +18397,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1405</integer>
+// CHECK-NEXT:            <key>line</key><integer>1415</integer>
 // CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1405</integer>
+// CHECK-NEXT:            <key>line</key><integer>1415</integer>
 // CHECK-NEXT:            <key>col</key><integer>30</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -19980,7 +18414,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1405</integer>
+// CHECK-NEXT:       <key>line</key><integer>1415</integer>
 // CHECK-NEXT:       <key>col</key><integer>10</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -19988,12 +18422,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1405</integer>
+// CHECK-NEXT:          <key>line</key><integer>1415</integer>
 // CHECK-NEXT:          <key>col</key><integer>10</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1405</integer>
+// CHECK-NEXT:          <key>line</key><integer>1415</integer>
 // CHECK-NEXT:          <key>col</key><integer>32</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -20009,7 +18443,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1394</integer>
+// CHECK-NEXT:       <key>line</key><integer>1404</integer>
 // CHECK-NEXT:       <key>col</key><integer>1</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -20027,26 +18461,26 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1396</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>line</key><integer>1404</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>1396</integer>
-// CHECK-NEXT:            <key>col</key><integer>8</integer>
+// CHECK-NEXT:            <key>line</key><integer>1404</integer>
+// CHECK-NEXT:            <key>col</key><integer>19</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>1396</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>line</key><integer>1406</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>1396</integer>
-// CHECK-NEXT:            <key>col</key><integer>21</integer>
+// CHECK-NEXT:            <key>line</key><integer>1406</integer>
+// CHECK-NEXT:            <key>col</key><integer>8</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
@@ -20057,7 +18491,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1396</integer>
+// CHECK-NEXT:       <key>line</key><integer>1406</integer>
 // CHECK-NEXT:       <key>col</key><integer>10</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -20065,12 +18499,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1396</integer>
+// CHECK-NEXT:          <key>line</key><integer>1406</integer>
 // CHECK-NEXT:          <key>col</key><integer>10</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1396</integer>
+// CHECK-NEXT:          <key>line</key><integer>1406</integer>
 // CHECK-NEXT:          <key>col</key><integer>52</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -20086,7 +18520,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1405</integer>
+// CHECK-NEXT:       <key>line</key><integer>1415</integer>
 // CHECK-NEXT:       <key>col</key><integer>10</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -20094,28 +18528,62 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1405</integer>
+// CHECK-NEXT:          <key>line</key><integer>1415</integer>
 // CHECK-NEXT:          <key>col</key><integer>10</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1405</integer>
+// CHECK-NEXT:          <key>line</key><integer>1415</integer>
 // CHECK-NEXT:          <key>col</key><integer>32</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>depth</key><integer>1</integer>
 // CHECK-NEXT:      <key>extended_message</key>
 // CHECK-NEXT:      <string>Returning from &apos;returnsRetainedCFDate&apos;</string>
 // CHECK-NEXT:      <key>message</key>
 // CHECK-NEXT:      <string>Returning from &apos;returnsRetainedCFDate&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>1415</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1415</integer>
+// CHECK-NEXT:            <key>col</key><integer>30</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>1415</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>1415</integer>
+// CHECK-NEXT:            <key>col</key><integer>8</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1413</integer>
+// CHECK-NEXT:       <key>line</key><integer>1423</integer>
 // CHECK-NEXT:       <key>col</key><integer>26</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -20123,18 +18591,18 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1413</integer>
+// CHECK-NEXT:          <key>line</key><integer>1423</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>1413</integer>
+// CHECK-NEXT:          <key>line</key><integer>1423</integer>
 // CHECK-NEXT:          <key>col</key><integer>53</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>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
 // CHECK-NEXT:      <string>Returning from &apos;returnsCFRetainedAsCF&apos;</string>
 // CHECK-NEXT:      <key>message</key>
@@ -20148,46 +18616,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1413</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>1413</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>1413</integer>
+// CHECK-NEXT:            <key>line</key><integer>1423</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>1413</integer>
-// CHECK-NEXT:            <key>col</key><integer>26</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>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>1413</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>1413</integer>
+// CHECK-NEXT:            <key>line</key><integer>1423</integer>
 // CHECK-NEXT:            <key>col</key><integer>26</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -20195,12 +18629,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1413</integer>
+// CHECK-NEXT:            <key>line</key><integer>1423</integer>
 // CHECK-NEXT:            <key>col</key><integer>21</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1413</integer>
+// CHECK-NEXT:            <key>line</key><integer>1423</integer>
 // CHECK-NEXT:            <key>col</key><integer>21</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -20212,7 +18646,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1413</integer>
+// CHECK-NEXT:       <key>line</key><integer>1423</integer>
 // CHECK-NEXT:       <key>col</key><integer>21</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -20220,24 +18654,24 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1413</integer>
+// CHECK-NEXT:          <key>line</key><integer>1423</integer>
 // CHECK-NEXT:          <key>col</key><integer>21</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1413</integer>
+// CHECK-NEXT:          <key>line</key><integer>1423</integer>
 // CHECK-NEXT:          <key>col</key><integer>66</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:        </array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1413</integer>
+// CHECK-NEXT:          <key>line</key><integer>1423</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>1413</integer>
+// CHECK-NEXT:          <key>line</key><integer>1423</integer>
 // CHECK-NEXT:          <key>col</key><integer>53</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -20257,12 +18691,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1413</integer>
+// CHECK-NEXT:            <key>line</key><integer>1423</integer>
 // CHECK-NEXT:            <key>col</key><integer>21</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1413</integer>
+// CHECK-NEXT:            <key>line</key><integer>1423</integer>
 // CHECK-NEXT:            <key>col</key><integer>21</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -20270,12 +18704,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1413</integer>
+// CHECK-NEXT:            <key>line</key><integer>1423</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>1413</integer>
+// CHECK-NEXT:            <key>line</key><integer>1423</integer>
 // CHECK-NEXT:            <key>col</key><integer>8</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -20287,7 +18721,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1413</integer>
+// CHECK-NEXT:       <key>line</key><integer>1423</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -20295,12 +18729,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1413</integer>
+// CHECK-NEXT:          <key>line</key><integer>1423</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>1413</integer>
+// CHECK-NEXT:          <key>line</key><integer>1423</integer>
 // CHECK-NEXT:          <key>col</key><integer>66</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -20321,7 +18755,7 @@
 // CHECK-NEXT:   <key>issue_hash</key><string>1</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1413</integer>
+// CHECK-NEXT:    <key>line</key><integer>1423</integer>
 // CHECK-NEXT:    <key>col</key><integer>3</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -20337,12 +18771,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1417</integer>
+// CHECK-NEXT:            <key>line</key><integer>1427</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>1417</integer>
+// CHECK-NEXT:            <key>line</key><integer>1427</integer>
 // CHECK-NEXT:            <key>col</key><integer>8</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -20350,12 +18784,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1417</integer>
+// CHECK-NEXT:            <key>line</key><integer>1427</integer>
 // CHECK-NEXT:            <key>col</key><integer>20</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1417</integer>
+// CHECK-NEXT:            <key>line</key><integer>1427</integer>
 // CHECK-NEXT:            <key>col</key><integer>40</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -20367,7 +18801,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1417</integer>
+// CHECK-NEXT:       <key>line</key><integer>1427</integer>
 // CHECK-NEXT:       <key>col</key><integer>20</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -20375,12 +18809,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1417</integer>
+// CHECK-NEXT:          <key>line</key><integer>1427</integer>
 // CHECK-NEXT:          <key>col</key><integer>20</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1417</integer>
+// CHECK-NEXT:          <key>line</key><integer>1427</integer>
 // CHECK-NEXT:          <key>col</key><integer>42</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -20396,7 +18830,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1394</integer>
+// CHECK-NEXT:       <key>line</key><integer>1404</integer>
 // CHECK-NEXT:       <key>col</key><integer>1</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -20414,26 +18848,26 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1396</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>line</key><integer>1404</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>1396</integer>
-// CHECK-NEXT:            <key>col</key><integer>8</integer>
+// CHECK-NEXT:            <key>line</key><integer>1404</integer>
+// CHECK-NEXT:            <key>col</key><integer>19</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>1396</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>line</key><integer>1406</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>1396</integer>
-// CHECK-NEXT:            <key>col</key><integer>21</integer>
+// CHECK-NEXT:            <key>line</key><integer>1406</integer>
+// CHECK-NEXT:            <key>col</key><integer>8</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
@@ -20444,7 +18878,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1396</integer>
+// CHECK-NEXT:       <key>line</key><integer>1406</integer>
 // CHECK-NEXT:       <key>col</key><integer>10</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -20452,12 +18886,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1396</integer>
+// CHECK-NEXT:          <key>line</key><integer>1406</integer>
 // CHECK-NEXT:          <key>col</key><integer>10</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1396</integer>
+// CHECK-NEXT:          <key>line</key><integer>1406</integer>
 // CHECK-NEXT:          <key>col</key><integer>52</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -20473,7 +18907,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1417</integer>
+// CHECK-NEXT:       <key>line</key><integer>1427</integer>
 // CHECK-NEXT:       <key>col</key><integer>20</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -20481,18 +18915,18 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1417</integer>
+// CHECK-NEXT:          <key>line</key><integer>1427</integer>
 // CHECK-NEXT:          <key>col</key><integer>20</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1417</integer>
+// CHECK-NEXT:          <key>line</key><integer>1427</integer>
 // CHECK-NEXT:          <key>col</key><integer>42</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>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
 // CHECK-NEXT:      <string>Returning from &apos;returnsRetainedCFDate&apos;</string>
 // CHECK-NEXT:      <key>message</key>
@@ -20506,46 +18940,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1417</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>1417</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>1417</integer>
+// CHECK-NEXT:            <key>line</key><integer>1427</integer>
 // CHECK-NEXT:            <key>col</key><integer>20</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1417</integer>
-// CHECK-NEXT:            <key>col</key><integer>40</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>1417</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1417</integer>
+// CHECK-NEXT:            <key>line</key><integer>1427</integer>
 // CHECK-NEXT:            <key>col</key><integer>40</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -20553,12 +18953,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1417</integer>
+// CHECK-NEXT:            <key>line</key><integer>1427</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>1417</integer>
+// CHECK-NEXT:            <key>line</key><integer>1427</integer>
 // CHECK-NEXT:            <key>col</key><integer>8</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -20570,7 +18970,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1417</integer>
+// CHECK-NEXT:       <key>line</key><integer>1427</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -20578,24 +18978,24 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1417</integer>
+// CHECK-NEXT:          <key>line</key><integer>1427</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>1417</integer>
+// CHECK-NEXT:          <key>line</key><integer>1427</integer>
 // CHECK-NEXT:          <key>col</key><integer>42</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:        </array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1417</integer>
+// CHECK-NEXT:          <key>line</key><integer>1427</integer>
 // CHECK-NEXT:          <key>col</key><integer>10</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1417</integer>
+// CHECK-NEXT:          <key>line</key><integer>1427</integer>
 // CHECK-NEXT:          <key>col</key><integer>42</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -20611,7 +19011,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1417</integer>
+// CHECK-NEXT:       <key>line</key><integer>1427</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -20619,12 +19019,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1417</integer>
+// CHECK-NEXT:          <key>line</key><integer>1427</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>1417</integer>
+// CHECK-NEXT:          <key>line</key><integer>1427</integer>
 // CHECK-NEXT:          <key>col</key><integer>42</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -20645,7 +19045,7 @@
 // CHECK-NEXT:   <key>issue_hash</key><string>1</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1417</integer>
+// CHECK-NEXT:    <key>line</key><integer>1427</integer>
 // CHECK-NEXT:    <key>col</key><integer>3</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -20661,12 +19061,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1421</integer>
+// CHECK-NEXT:            <key>line</key><integer>1431</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>1421</integer>
+// CHECK-NEXT:            <key>line</key><integer>1431</integer>
 // CHECK-NEXT:            <key>col</key><integer>8</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -20674,12 +19074,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1421</integer>
+// CHECK-NEXT:            <key>line</key><integer>1431</integer>
 // CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1421</integer>
+// CHECK-NEXT:            <key>line</key><integer>1431</integer>
 // CHECK-NEXT:            <key>col</key><integer>30</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -20691,7 +19091,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1421</integer>
+// CHECK-NEXT:       <key>line</key><integer>1431</integer>
 // CHECK-NEXT:       <key>col</key><integer>10</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -20699,12 +19099,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1421</integer>
+// CHECK-NEXT:          <key>line</key><integer>1431</integer>
 // CHECK-NEXT:          <key>col</key><integer>10</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1421</integer>
+// CHECK-NEXT:          <key>line</key><integer>1431</integer>
 // CHECK-NEXT:          <key>col</key><integer>32</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -20720,7 +19120,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1394</integer>
+// CHECK-NEXT:       <key>line</key><integer>1404</integer>
 // CHECK-NEXT:       <key>col</key><integer>1</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -20738,26 +19138,26 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1396</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>line</key><integer>1404</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>1396</integer>
-// CHECK-NEXT:            <key>col</key><integer>8</integer>
+// CHECK-NEXT:            <key>line</key><integer>1404</integer>
+// CHECK-NEXT:            <key>col</key><integer>19</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>1396</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>line</key><integer>1406</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>1396</integer>
-// CHECK-NEXT:            <key>col</key><integer>21</integer>
+// CHECK-NEXT:            <key>line</key><integer>1406</integer>
+// CHECK-NEXT:            <key>col</key><integer>8</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
@@ -20768,7 +19168,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1396</integer>
+// CHECK-NEXT:       <key>line</key><integer>1406</integer>
 // CHECK-NEXT:       <key>col</key><integer>10</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -20776,12 +19176,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1396</integer>
+// CHECK-NEXT:          <key>line</key><integer>1406</integer>
 // CHECK-NEXT:          <key>col</key><integer>10</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1396</integer>
+// CHECK-NEXT:          <key>line</key><integer>1406</integer>
 // CHECK-NEXT:          <key>col</key><integer>52</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -20797,7 +19197,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1421</integer>
+// CHECK-NEXT:       <key>line</key><integer>1431</integer>
 // CHECK-NEXT:       <key>col</key><integer>10</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -20805,18 +19205,18 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1421</integer>
+// CHECK-NEXT:          <key>line</key><integer>1431</integer>
 // CHECK-NEXT:          <key>col</key><integer>10</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1421</integer>
+// CHECK-NEXT:          <key>line</key><integer>1431</integer>
 // CHECK-NEXT:          <key>col</key><integer>32</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>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
 // CHECK-NEXT:      <string>Returning from &apos;returnsRetainedCFDate&apos;</string>
 // CHECK-NEXT:      <key>message</key>
@@ -20830,46 +19230,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1421</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>1421</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>1421</integer>
+// CHECK-NEXT:            <key>line</key><integer>1431</integer>
 // CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1421</integer>
-// CHECK-NEXT:            <key>col</key><integer>30</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>1421</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1421</integer>
+// CHECK-NEXT:            <key>line</key><integer>1431</integer>
 // CHECK-NEXT:            <key>col</key><integer>30</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -20877,12 +19243,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1421</integer>
+// CHECK-NEXT:            <key>line</key><integer>1431</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>1421</integer>
+// CHECK-NEXT:            <key>line</key><integer>1431</integer>
 // CHECK-NEXT:            <key>col</key><integer>8</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -20894,7 +19260,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1421</integer>
+// CHECK-NEXT:       <key>line</key><integer>1431</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -20902,24 +19268,24 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1421</integer>
+// CHECK-NEXT:          <key>line</key><integer>1431</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>1421</integer>
+// CHECK-NEXT:          <key>line</key><integer>1431</integer>
 // CHECK-NEXT:          <key>col</key><integer>32</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:        </array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1421</integer>
+// CHECK-NEXT:          <key>line</key><integer>1431</integer>
 // CHECK-NEXT:          <key>col</key><integer>10</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1421</integer>
+// CHECK-NEXT:          <key>line</key><integer>1431</integer>
 // CHECK-NEXT:          <key>col</key><integer>32</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -20935,7 +19301,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1421</integer>
+// CHECK-NEXT:       <key>line</key><integer>1431</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -20943,12 +19309,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1421</integer>
+// CHECK-NEXT:          <key>line</key><integer>1431</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>1421</integer>
+// CHECK-NEXT:          <key>line</key><integer>1431</integer>
 // CHECK-NEXT:          <key>col</key><integer>32</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -20969,7 +19335,7 @@
 // CHECK-NEXT:   <key>issue_hash</key><string>1</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1421</integer>
+// CHECK-NEXT:    <key>line</key><integer>1431</integer>
 // CHECK-NEXT:    <key>col</key><integer>3</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -20985,12 +19351,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1441</integer>
+// CHECK-NEXT:            <key>line</key><integer>1451</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>1441</integer>
+// CHECK-NEXT:            <key>line</key><integer>1451</integer>
 // CHECK-NEXT:            <key>col</key><integer>8</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -20998,12 +19364,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1442</integer>
+// CHECK-NEXT:            <key>line</key><integer>1452</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>1442</integer>
+// CHECK-NEXT:            <key>line</key><integer>1452</integer>
 // CHECK-NEXT:            <key>col</key><integer>13</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -21012,44 +19378,10 @@
 // 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>1442</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>1442</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:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1442</integer>
-// CHECK-NEXT:            <key>col</key><integer>23</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1442</integer>
-// CHECK-NEXT:            <key>col</key><integer>36</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>1442</integer>
+// CHECK-NEXT:       <key>line</key><integer>1452</integer>
 // CHECK-NEXT:       <key>col</key><integer>23</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -21057,12 +19389,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1442</integer>
+// CHECK-NEXT:          <key>line</key><integer>1452</integer>
 // CHECK-NEXT:          <key>col</key><integer>23</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1442</integer>
+// CHECK-NEXT:          <key>line</key><integer>1452</integer>
 // CHECK-NEXT:          <key>col</key><integer>82</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -21082,25 +19414,25 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1442</integer>
-// CHECK-NEXT:            <key>col</key><integer>23</integer>
+// CHECK-NEXT:            <key>line</key><integer>1452</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>1442</integer>
-// CHECK-NEXT:            <key>col</key><integer>36</integer>
+// CHECK-NEXT:            <key>line</key><integer>1452</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:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1443</integer>
+// CHECK-NEXT:            <key>line</key><integer>1453</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>1443</integer>
+// CHECK-NEXT:            <key>line</key><integer>1453</integer>
 // CHECK-NEXT:            <key>col</key><integer>1</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -21112,7 +19444,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1443</integer>
+// CHECK-NEXT:       <key>line</key><integer>1453</integer>
 // CHECK-NEXT:       <key>col</key><integer>1</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -21128,10 +19460,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>test_panic_negative</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>3</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>2</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1443</integer>
+// CHECK-NEXT:    <key>line</key><integer>1453</integer>
 // CHECK-NEXT:    <key>col</key><integer>1</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -21147,12 +19479,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1452</integer>
+// CHECK-NEXT:            <key>line</key><integer>1462</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>1452</integer>
+// CHECK-NEXT:            <key>line</key><integer>1462</integer>
 // CHECK-NEXT:            <key>col</key><integer>8</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -21160,12 +19492,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1453</integer>
+// CHECK-NEXT:            <key>line</key><integer>1463</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>1453</integer>
+// CHECK-NEXT:            <key>line</key><integer>1463</integer>
 // CHECK-NEXT:            <key>col</key><integer>13</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -21174,44 +19506,10 @@
 // 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>1453</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>1453</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:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1453</integer>
-// CHECK-NEXT:            <key>col</key><integer>23</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1453</integer>
-// CHECK-NEXT:            <key>col</key><integer>36</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>1453</integer>
+// CHECK-NEXT:       <key>line</key><integer>1463</integer>
 // CHECK-NEXT:       <key>col</key><integer>23</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -21219,12 +19517,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1453</integer>
+// CHECK-NEXT:          <key>line</key><integer>1463</integer>
 // CHECK-NEXT:          <key>col</key><integer>23</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1453</integer>
+// CHECK-NEXT:          <key>line</key><integer>1463</integer>
 // CHECK-NEXT:          <key>col</key><integer>82</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -21244,25 +19542,25 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1453</integer>
-// CHECK-NEXT:            <key>col</key><integer>23</integer>
+// CHECK-NEXT:            <key>line</key><integer>1463</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>1453</integer>
-// CHECK-NEXT:            <key>col</key><integer>36</integer>
+// CHECK-NEXT:            <key>line</key><integer>1463</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:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1454</integer>
+// CHECK-NEXT:            <key>line</key><integer>1464</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>1454</integer>
+// CHECK-NEXT:            <key>line</key><integer>1464</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -21278,12 +19576,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1454</integer>
+// CHECK-NEXT:            <key>line</key><integer>1464</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>1454</integer>
+// CHECK-NEXT:            <key>line</key><integer>1464</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -21291,12 +19589,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1454</integer>
+// CHECK-NEXT:            <key>line</key><integer>1464</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>1454</integer>
+// CHECK-NEXT:            <key>line</key><integer>1464</integer>
 // CHECK-NEXT:            <key>col</key><integer>7</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -21308,7 +19606,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1454</integer>
+// CHECK-NEXT:       <key>line</key><integer>1464</integer>
 // CHECK-NEXT:       <key>col</key><integer>7</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -21316,12 +19614,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1454</integer>
+// CHECK-NEXT:          <key>line</key><integer>1464</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>1454</integer>
+// CHECK-NEXT:          <key>line</key><integer>1464</integer>
 // CHECK-NEXT:          <key>col</key><integer>7</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -21341,12 +19639,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1454</integer>
+// CHECK-NEXT:            <key>line</key><integer>1464</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>1454</integer>
+// CHECK-NEXT:            <key>line</key><integer>1464</integer>
 // CHECK-NEXT:            <key>col</key><integer>7</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -21354,12 +19652,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1456</integer>
+// CHECK-NEXT:            <key>line</key><integer>1466</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>1456</integer>
+// CHECK-NEXT:            <key>line</key><integer>1466</integer>
 // CHECK-NEXT:            <key>col</key><integer>1</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -21371,7 +19669,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1456</integer>
+// CHECK-NEXT:       <key>line</key><integer>1466</integer>
 // CHECK-NEXT:       <key>col</key><integer>1</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -21387,10 +19685,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>test_panic_neg_2</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>5</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>2</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1456</integer>
+// CHECK-NEXT:    <key>line</key><integer>1466</integer>
 // CHECK-NEXT:    <key>col</key><integer>1</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -21399,44 +19697,10 @@
 // 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>1476</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>1476</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1476</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>1476</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:     </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>1476</integer>
+// CHECK-NEXT:       <key>line</key><integer>1486</integer>
 // CHECK-NEXT:       <key>col</key><integer>22</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -21444,12 +19708,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1476</integer>
+// CHECK-NEXT:          <key>line</key><integer>1486</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>1476</integer>
+// CHECK-NEXT:          <key>line</key><integer>1486</integer>
 // CHECK-NEXT:          <key>col</key><integer>53</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -21469,25 +19733,25 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1476</integer>
-// CHECK-NEXT:            <key>col</key><integer>22</integer>
+// CHECK-NEXT:            <key>line</key><integer>1486</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>1476</integer>
-// CHECK-NEXT:            <key>col</key><integer>22</integer>
+// CHECK-NEXT:            <key>line</key><integer>1486</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1477</integer>
+// CHECK-NEXT:            <key>line</key><integer>1487</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>1477</integer>
+// CHECK-NEXT:            <key>line</key><integer>1487</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -21499,7 +19763,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1477</integer>
+// CHECK-NEXT:       <key>line</key><integer>1487</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -21507,12 +19771,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1477</integer>
+// CHECK-NEXT:          <key>line</key><integer>1487</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>1477</integer>
+// CHECK-NEXT:          <key>line</key><integer>1487</integer>
 // CHECK-NEXT:          <key>col</key><integer>7</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -21530,10 +19794,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>test_blocks_1_pos</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>2</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>1</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1477</integer>
+// CHECK-NEXT:    <key>line</key><integer>1487</integer>
 // CHECK-NEXT:    <key>col</key><integer>3</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -21542,44 +19806,10 @@
 // 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>1497</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>1497</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1497</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>1497</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:     </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>1497</integer>
+// CHECK-NEXT:       <key>line</key><integer>1507</integer>
 // CHECK-NEXT:       <key>col</key><integer>22</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -21587,12 +19817,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1497</integer>
+// CHECK-NEXT:          <key>line</key><integer>1507</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>1497</integer>
+// CHECK-NEXT:          <key>line</key><integer>1507</integer>
 // CHECK-NEXT:          <key>col</key><integer>53</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -21612,25 +19842,25 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1497</integer>
-// CHECK-NEXT:            <key>col</key><integer>22</integer>
+// CHECK-NEXT:            <key>line</key><integer>1507</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>1497</integer>
-// CHECK-NEXT:            <key>col</key><integer>22</integer>
+// CHECK-NEXT:            <key>line</key><integer>1507</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1498</integer>
+// CHECK-NEXT:            <key>line</key><integer>1508</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>1498</integer>
+// CHECK-NEXT:            <key>line</key><integer>1508</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -21642,7 +19872,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1498</integer>
+// CHECK-NEXT:       <key>line</key><integer>1508</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -21650,12 +19880,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1498</integer>
+// CHECK-NEXT:          <key>line</key><integer>1508</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>1498</integer>
+// CHECK-NEXT:          <key>line</key><integer>1508</integer>
 // CHECK-NEXT:          <key>col</key><integer>39</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -21671,7 +19901,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1498</integer>
+// CHECK-NEXT:       <key>line</key><integer>1508</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -21689,12 +19919,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1498</integer>
+// CHECK-NEXT:            <key>line</key><integer>1508</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>1498</integer>
+// CHECK-NEXT:            <key>line</key><integer>1508</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -21702,12 +19932,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1498</integer>
+// CHECK-NEXT:            <key>line</key><integer>1508</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>1498</integer>
+// CHECK-NEXT:            <key>line</key><integer>1508</integer>
 // CHECK-NEXT:            <key>col</key><integer>19</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -21719,7 +19949,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1498</integer>
+// CHECK-NEXT:       <key>line</key><integer>1508</integer>
 // CHECK-NEXT:       <key>col</key><integer>19</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -21727,24 +19957,24 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1498</integer>
+// CHECK-NEXT:          <key>line</key><integer>1508</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>1498</integer>
+// CHECK-NEXT:          <key>line</key><integer>1508</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:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1498</integer>
+// CHECK-NEXT:          <key>line</key><integer>1508</integer>
 // CHECK-NEXT:          <key>col</key><integer>20</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1498</integer>
+// CHECK-NEXT:          <key>line</key><integer>1508</integer>
 // CHECK-NEXT:          <key>col</key><integer>20</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -21760,7 +19990,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1498</integer>
+// CHECK-NEXT:       <key>line</key><integer>1508</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -21768,18 +19998,18 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1498</integer>
+// CHECK-NEXT:          <key>line</key><integer>1508</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>1498</integer>
+// CHECK-NEXT:          <key>line</key><integer>1508</integer>
 // CHECK-NEXT:          <key>col</key><integer>39</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>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
 // CHECK-NEXT:      <string>Returning to caller</string>
 // CHECK-NEXT:      <key>message</key>
@@ -21793,12 +20023,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1498</integer>
+// CHECK-NEXT:            <key>line</key><integer>1508</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>1498</integer>
+// CHECK-NEXT:            <key>line</key><integer>1508</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -21806,12 +20036,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1499</integer>
+// CHECK-NEXT:            <key>line</key><integer>1509</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>1499</integer>
+// CHECK-NEXT:            <key>line</key><integer>1509</integer>
 // CHECK-NEXT:            <key>col</key><integer>1</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -21823,7 +20053,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1499</integer>
+// CHECK-NEXT:       <key>line</key><integer>1509</integer>
 // CHECK-NEXT:       <key>col</key><integer>1</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -21839,10 +20069,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>test_blocks_1_indirect_retain_via_call</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>3</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>1</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1499</integer>
+// CHECK-NEXT:    <key>line</key><integer>1509</integer>
 // CHECK-NEXT:    <key>col</key><integer>1</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -21858,12 +20088,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1549</integer>
+// CHECK-NEXT:            <key>line</key><integer>1559</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>1549</integer>
+// CHECK-NEXT:            <key>line</key><integer>1559</integer>
 // CHECK-NEXT:            <key>col</key><integer>14</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -21871,12 +20101,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1552</integer>
+// CHECK-NEXT:            <key>line</key><integer>1562</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>1552</integer>
+// CHECK-NEXT:            <key>line</key><integer>1562</integer>
 // CHECK-NEXT:            <key>col</key><integer>9</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -21885,112 +20115,107 @@
 // 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>1552</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>1552</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>1553</integer>
-// CHECK-NEXT:            <key>col</key><integer>9</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1553</integer>
-// CHECK-NEXT:            <key>col</key><integer>23</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </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>1553</integer>
-// CHECK-NEXT:            <key>col</key><integer>9</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1553</integer>
-// CHECK-NEXT:            <key>col</key><integer>23</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1555</integer>
-// CHECK-NEXT:            <key>col</key><integer>9</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1555</integer>
-// CHECK-NEXT:            <key>col</key><integer>12</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </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>1555</integer>
-// CHECK-NEXT:            <key>col</key><integer>9</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1555</integer>
-// CHECK-NEXT:            <key>col</key><integer>12</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1555</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>1555</integer>
-// CHECK-NEXT:            <key>col</key><integer>34</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>1555</integer>
+// CHECK-NEXT:       <key>line</key><integer>1562</integer>
+// CHECK-NEXT:       <key>col</key><integer>12</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>1562</integer>
+// CHECK-NEXT:          <key>col</key><integer>12</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>1562</integer>
+// CHECK-NEXT:          <key>col</key><integer>38</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>Entering loop body</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Entering loop body</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>1562</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>1562</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>1563</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1563</integer>
+// CHECK-NEXT:            <key>col</key><integer>23</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </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>1563</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1563</integer>
+// CHECK-NEXT:            <key>col</key><integer>23</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1565</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1565</integer>
+// CHECK-NEXT:            <key>col</key><integer>12</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </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>1565</integer>
 // CHECK-NEXT:       <key>col</key><integer>16</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -21998,12 +20223,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1555</integer>
+// CHECK-NEXT:          <key>line</key><integer>1565</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>1555</integer>
+// CHECK-NEXT:          <key>line</key><integer>1565</integer>
 // CHECK-NEXT:          <key>col</key><integer>49</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -22023,25 +20248,25 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1555</integer>
-// CHECK-NEXT:            <key>col</key><integer>16</integer>
+// CHECK-NEXT:            <key>line</key><integer>1565</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1555</integer>
-// CHECK-NEXT:            <key>col</key><integer>34</integer>
+// CHECK-NEXT:            <key>line</key><integer>1565</integer>
+// CHECK-NEXT:            <key>col</key><integer>12</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1557</integer>
+// CHECK-NEXT:            <key>line</key><integer>1567</integer>
 // CHECK-NEXT:            <key>col</key><integer>9</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1557</integer>
+// CHECK-NEXT:            <key>line</key><integer>1567</integer>
 // CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -22057,12 +20282,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1557</integer>
+// CHECK-NEXT:            <key>line</key><integer>1567</integer>
 // CHECK-NEXT:            <key>col</key><integer>9</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1557</integer>
+// CHECK-NEXT:            <key>line</key><integer>1567</integer>
 // CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -22070,12 +20295,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1557</integer>
+// CHECK-NEXT:            <key>line</key><integer>1567</integer>
 // CHECK-NEXT:            <key>col</key><integer>13</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1557</integer>
+// CHECK-NEXT:            <key>line</key><integer>1567</integer>
 // CHECK-NEXT:            <key>col</key><integer>16</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -22087,7 +20312,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1557</integer>
+// CHECK-NEXT:       <key>line</key><integer>1567</integer>
 // CHECK-NEXT:       <key>col</key><integer>13</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -22095,12 +20320,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1557</integer>
+// CHECK-NEXT:          <key>line</key><integer>1567</integer>
 // CHECK-NEXT:          <key>col</key><integer>13</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1557</integer>
+// CHECK-NEXT:          <key>line</key><integer>1567</integer>
 // CHECK-NEXT:          <key>col</key><integer>30</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -22120,12 +20345,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1557</integer>
+// CHECK-NEXT:            <key>line</key><integer>1567</integer>
 // CHECK-NEXT:            <key>col</key><integer>13</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1557</integer>
+// CHECK-NEXT:            <key>line</key><integer>1567</integer>
 // CHECK-NEXT:            <key>col</key><integer>16</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -22133,13 +20358,13 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1560</integer>
-// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>line</key><integer>1570</integer>
+// CHECK-NEXT:            <key>col</key><integer>23</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1560</integer>
-// CHECK-NEXT:            <key>col</key><integer>21</integer>
+// CHECK-NEXT:            <key>line</key><integer>1570</integer>
+// CHECK-NEXT:            <key>col</key><integer>23</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
@@ -22150,25 +20375,10 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1560</integer>
-// CHECK-NEXT:       <key>col</key><integer>9</integer>
+// CHECK-NEXT:       <key>line</key><integer>1570</integer>
+// CHECK-NEXT:       <key>col</key><integer>23</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>1560</integer>
-// CHECK-NEXT:          <key>col</key><integer>9</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1560</integer>
-// CHECK-NEXT:          <key>col</key><integer>91</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>Object leaked: object allocated and stored into &apos;info&apos; is not referenced later in this execution path and has a retain count of +1</string>
@@ -22181,11 +20391,11 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>rdar_8724287</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>12</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>7</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1560</integer>
-// CHECK-NEXT:    <key>col</key><integer>9</integer>
+// CHECK-NEXT:    <key>line</key><integer>1570</integer>
+// CHECK-NEXT:    <key>col</key><integer>23</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
 // CHECK-NEXT:   </dict>
@@ -22193,44 +20403,10 @@
 // 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>1605</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>1605</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>1605</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1605</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:       </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>1605</integer>
+// CHECK-NEXT:       <key>line</key><integer>1615</integer>
 // CHECK-NEXT:       <key>col</key><integer>10</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -22238,12 +20414,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1605</integer>
+// CHECK-NEXT:          <key>line</key><integer>1615</integer>
 // CHECK-NEXT:          <key>col</key><integer>10</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1605</integer>
+// CHECK-NEXT:          <key>line</key><integer>1615</integer>
 // CHECK-NEXT:          <key>col</key><integer>60</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -22256,44 +20432,10 @@
 // CHECK-NEXT:      <string>Call to function &apos;CFArrayCreateMutable&apos; returns a Core Foundation object with a +1 retain count</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>1605</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1605</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:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1605</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>1605</integer>
-// CHECK-NEXT:            <key>col</key><integer>8</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1605</integer>
+// CHECK-NEXT:       <key>line</key><integer>1615</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -22301,24 +20443,24 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1605</integer>
+// CHECK-NEXT:          <key>line</key><integer>1615</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>1605</integer>
+// CHECK-NEXT:          <key>line</key><integer>1615</integer>
 // CHECK-NEXT:          <key>col</key><integer>60</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:        </array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1605</integer>
+// CHECK-NEXT:          <key>line</key><integer>1615</integer>
 // CHECK-NEXT:          <key>col</key><integer>10</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1605</integer>
+// CHECK-NEXT:          <key>line</key><integer>1615</integer>
 // CHECK-NEXT:          <key>col</key><integer>60</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -22334,7 +20476,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1605</integer>
+// CHECK-NEXT:       <key>line</key><integer>1615</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -22342,12 +20484,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1605</integer>
+// CHECK-NEXT:          <key>line</key><integer>1615</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>1605</integer>
+// CHECK-NEXT:          <key>line</key><integer>1615</integer>
 // CHECK-NEXT:          <key>col</key><integer>60</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -22368,7 +20510,7 @@
 // CHECK-NEXT:   <key>issue_hash</key><string>1</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1605</integer>
+// CHECK-NEXT:    <key>line</key><integer>1615</integer>
 // CHECK-NEXT:    <key>col</key><integer>3</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -22377,44 +20519,10 @@
 // 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>1613</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>1613</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>1613</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1613</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:       </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>1613</integer>
+// CHECK-NEXT:       <key>line</key><integer>1623</integer>
 // CHECK-NEXT:       <key>col</key><integer>10</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -22422,12 +20530,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1613</integer>
+// CHECK-NEXT:          <key>line</key><integer>1623</integer>
 // CHECK-NEXT:          <key>col</key><integer>10</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1613</integer>
+// CHECK-NEXT:          <key>line</key><integer>1623</integer>
 // CHECK-NEXT:          <key>col</key><integer>60</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -22440,44 +20548,10 @@
 // CHECK-NEXT:      <string>Call to function &apos;CFArrayCreateMutable&apos; returns a Core Foundation object with a +1 retain count</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>1613</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1613</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:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1613</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>1613</integer>
-// CHECK-NEXT:            <key>col</key><integer>8</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1613</integer>
+// CHECK-NEXT:       <key>line</key><integer>1623</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -22485,24 +20559,24 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1613</integer>
+// CHECK-NEXT:          <key>line</key><integer>1623</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>1613</integer>
+// CHECK-NEXT:          <key>line</key><integer>1623</integer>
 // CHECK-NEXT:          <key>col</key><integer>60</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:        </array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1613</integer>
+// CHECK-NEXT:          <key>line</key><integer>1623</integer>
 // CHECK-NEXT:          <key>col</key><integer>10</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1613</integer>
+// CHECK-NEXT:          <key>line</key><integer>1623</integer>
 // CHECK-NEXT:          <key>col</key><integer>60</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -22518,7 +20592,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1613</integer>
+// CHECK-NEXT:       <key>line</key><integer>1623</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -22526,12 +20600,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1613</integer>
+// CHECK-NEXT:          <key>line</key><integer>1623</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>1613</integer>
+// CHECK-NEXT:          <key>line</key><integer>1623</integer>
 // CHECK-NEXT:          <key>col</key><integer>60</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -22552,7 +20626,7 @@
 // CHECK-NEXT:   <key>issue_hash</key><string>1</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1613</integer>
+// CHECK-NEXT:    <key>line</key><integer>1623</integer>
 // CHECK-NEXT:    <key>col</key><integer>3</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -22561,44 +20635,10 @@
 // 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>1634</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>1634</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>1634</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1634</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:       </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>1634</integer>
+// CHECK-NEXT:       <key>line</key><integer>1644</integer>
 // CHECK-NEXT:       <key>col</key><integer>10</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -22606,12 +20646,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1634</integer>
+// CHECK-NEXT:          <key>line</key><integer>1644</integer>
 // CHECK-NEXT:          <key>col</key><integer>10</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1634</integer>
+// CHECK-NEXT:          <key>line</key><integer>1644</integer>
 // CHECK-NEXT:          <key>col</key><integer>60</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -22624,44 +20664,10 @@
 // CHECK-NEXT:      <string>Call to function &apos;CFArrayCreateMutable&apos; returns a Core Foundation object with a +1 retain count</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>1634</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1634</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:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1634</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>1634</integer>
-// CHECK-NEXT:            <key>col</key><integer>8</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1634</integer>
+// CHECK-NEXT:       <key>line</key><integer>1644</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -22669,24 +20675,24 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1634</integer>
+// CHECK-NEXT:          <key>line</key><integer>1644</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>1634</integer>
+// CHECK-NEXT:          <key>line</key><integer>1644</integer>
 // CHECK-NEXT:          <key>col</key><integer>60</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:        </array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1634</integer>
+// CHECK-NEXT:          <key>line</key><integer>1644</integer>
 // CHECK-NEXT:          <key>col</key><integer>10</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1634</integer>
+// CHECK-NEXT:          <key>line</key><integer>1644</integer>
 // CHECK-NEXT:          <key>col</key><integer>60</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -22702,7 +20708,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1634</integer>
+// CHECK-NEXT:       <key>line</key><integer>1644</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -22710,12 +20716,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1634</integer>
+// CHECK-NEXT:          <key>line</key><integer>1644</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>1634</integer>
+// CHECK-NEXT:          <key>line</key><integer>1644</integer>
 // CHECK-NEXT:          <key>col</key><integer>60</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -22736,7 +20742,7 @@
 // CHECK-NEXT:   <key>issue_hash</key><string>1</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1634</integer>
+// CHECK-NEXT:    <key>line</key><integer>1644</integer>
 // CHECK-NEXT:    <key>col</key><integer>3</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -22745,44 +20751,10 @@
 // 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>1646</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>1646</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>1646</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1646</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:       </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>1646</integer>
+// CHECK-NEXT:       <key>line</key><integer>1656</integer>
 // CHECK-NEXT:       <key>col</key><integer>10</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -22790,12 +20762,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1646</integer>
+// CHECK-NEXT:          <key>line</key><integer>1656</integer>
 // CHECK-NEXT:          <key>col</key><integer>10</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1646</integer>
+// CHECK-NEXT:          <key>line</key><integer>1656</integer>
 // CHECK-NEXT:          <key>col</key><integer>60</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -22808,44 +20780,10 @@
 // CHECK-NEXT:      <string>Call to function &apos;CFArrayCreateMutable&apos; returns a Core Foundation object with a +1 retain count</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>1646</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1646</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:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1646</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>1646</integer>
-// CHECK-NEXT:            <key>col</key><integer>8</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1646</integer>
+// CHECK-NEXT:       <key>line</key><integer>1656</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -22853,24 +20791,24 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1646</integer>
+// CHECK-NEXT:          <key>line</key><integer>1656</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>1646</integer>
+// CHECK-NEXT:          <key>line</key><integer>1656</integer>
 // CHECK-NEXT:          <key>col</key><integer>60</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:        </array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1646</integer>
+// CHECK-NEXT:          <key>line</key><integer>1656</integer>
 // CHECK-NEXT:          <key>col</key><integer>10</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1646</integer>
+// CHECK-NEXT:          <key>line</key><integer>1656</integer>
 // CHECK-NEXT:          <key>col</key><integer>60</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -22886,7 +20824,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1646</integer>
+// CHECK-NEXT:       <key>line</key><integer>1656</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -22894,12 +20832,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1646</integer>
+// CHECK-NEXT:          <key>line</key><integer>1656</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>1646</integer>
+// CHECK-NEXT:          <key>line</key><integer>1656</integer>
 // CHECK-NEXT:          <key>col</key><integer>60</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -22920,7 +20858,7 @@
 // CHECK-NEXT:   <key>issue_hash</key><string>1</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1646</integer>
+// CHECK-NEXT:    <key>line</key><integer>1656</integer>
 // CHECK-NEXT:    <key>col</key><integer>3</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -22936,12 +20874,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1666</integer>
+// CHECK-NEXT:            <key>line</key><integer>1676</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>1666</integer>
+// CHECK-NEXT:            <key>line</key><integer>1676</integer>
 // CHECK-NEXT:            <key>col</key><integer>16</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -22949,12 +20887,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1667</integer>
+// CHECK-NEXT:            <key>line</key><integer>1677</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>1667</integer>
+// CHECK-NEXT:            <key>line</key><integer>1677</integer>
 // CHECK-NEXT:            <key>col</key><integer>11</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -22963,44 +20901,10 @@
 // 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>1667</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>1667</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>1667</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>1667</integer>
-// CHECK-NEXT:            <key>col</key><integer>35</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>1667</integer>
+// CHECK-NEXT:       <key>line</key><integer>1677</integer>
 // CHECK-NEXT:       <key>col</key><integer>24</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -23008,12 +20912,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1667</integer>
+// CHECK-NEXT:          <key>line</key><integer>1677</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>1667</integer>
+// CHECK-NEXT:          <key>line</key><integer>1677</integer>
 // CHECK-NEXT:          <key>col</key><integer>41</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -23033,25 +20937,25 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1667</integer>
-// CHECK-NEXT:            <key>col</key><integer>24</integer>
+// CHECK-NEXT:            <key>line</key><integer>1677</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>1667</integer>
-// CHECK-NEXT:            <key>col</key><integer>35</integer>
+// CHECK-NEXT:            <key>line</key><integer>1677</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>1668</integer>
+// CHECK-NEXT:            <key>line</key><integer>1678</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>1668</integer>
+// CHECK-NEXT:            <key>line</key><integer>1678</integer>
 // CHECK-NEXT:            <key>col</key><integer>1</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -23063,7 +20967,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1668</integer>
+// CHECK-NEXT:       <key>line</key><integer>1678</integer>
 // CHECK-NEXT:       <key>col</key><integer>1</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -23079,10 +20983,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>rdar6582778</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>3</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>2</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1668</integer>
+// CHECK-NEXT:    <key>line</key><integer>1678</integer>
 // CHECK-NEXT:    <key>col</key><integer>1</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -23098,12 +21002,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1692</integer>
+// CHECK-NEXT:            <key>line</key><integer>1702</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>1692</integer>
+// CHECK-NEXT:            <key>line</key><integer>1702</integer>
 // CHECK-NEXT:            <key>col</key><integer>16</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -23111,12 +21015,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1694</integer>
+// CHECK-NEXT:            <key>line</key><integer>1704</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>1694</integer>
+// CHECK-NEXT:            <key>line</key><integer>1704</integer>
 // CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -23125,44 +21029,10 @@
 // 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>1694</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>1694</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1694</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>1694</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:     </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>1694</integer>
+// CHECK-NEXT:       <key>line</key><integer>1704</integer>
 // CHECK-NEXT:       <key>col</key><integer>22</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -23170,12 +21040,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1694</integer>
+// CHECK-NEXT:          <key>line</key><integer>1704</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>1694</integer>
+// CHECK-NEXT:          <key>line</key><integer>1704</integer>
 // CHECK-NEXT:          <key>col</key><integer>64</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -23195,25 +21065,25 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1694</integer>
-// CHECK-NEXT:            <key>col</key><integer>22</integer>
+// CHECK-NEXT:            <key>line</key><integer>1704</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>1694</integer>
-// CHECK-NEXT:            <key>col</key><integer>22</integer>
+// CHECK-NEXT:            <key>line</key><integer>1704</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1695</integer>
+// CHECK-NEXT:            <key>line</key><integer>1705</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>1695</integer>
+// CHECK-NEXT:            <key>line</key><integer>1705</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -23225,7 +21095,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1695</integer>
+// CHECK-NEXT:       <key>line</key><integer>1705</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -23233,24 +21103,24 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1695</integer>
+// CHECK-NEXT:          <key>line</key><integer>1705</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>1695</integer>
+// CHECK-NEXT:          <key>line</key><integer>1705</integer>
 // CHECK-NEXT:          <key>col</key><integer>18</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:        </array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1695</integer>
+// CHECK-NEXT:          <key>line</key><integer>1705</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>1695</integer>
+// CHECK-NEXT:          <key>line</key><integer>1705</integer>
 // CHECK-NEXT:          <key>col</key><integer>9</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -23270,12 +21140,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1695</integer>
+// CHECK-NEXT:            <key>line</key><integer>1705</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>1695</integer>
+// CHECK-NEXT:            <key>line</key><integer>1705</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -23283,12 +21153,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1697</integer>
+// CHECK-NEXT:            <key>line</key><integer>1707</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>1697</integer>
+// CHECK-NEXT:            <key>line</key><integer>1707</integer>
 // CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -23304,12 +21174,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1697</integer>
+// CHECK-NEXT:            <key>line</key><integer>1707</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>1697</integer>
+// CHECK-NEXT:            <key>line</key><integer>1707</integer>
 // CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -23317,12 +21187,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1697</integer>
+// CHECK-NEXT:            <key>line</key><integer>1707</integer>
 // CHECK-NEXT:            <key>col</key><integer>27</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1697</integer>
+// CHECK-NEXT:            <key>line</key><integer>1707</integer>
 // CHECK-NEXT:            <key>col</key><integer>27</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -23334,7 +21204,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1697</integer>
+// CHECK-NEXT:       <key>line</key><integer>1707</integer>
 // CHECK-NEXT:       <key>col</key><integer>27</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -23342,12 +21212,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1697</integer>
+// CHECK-NEXT:          <key>line</key><integer>1707</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>1697</integer>
+// CHECK-NEXT:          <key>line</key><integer>1707</integer>
 // CHECK-NEXT:          <key>col</key><integer>33</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -23368,7 +21238,7 @@
 // CHECK-NEXT:   <key>issue_hash</key><string>6</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1697</integer>
+// CHECK-NEXT:    <key>line</key><integer>1707</integer>
 // CHECK-NEXT:    <key>col</key><integer>27</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -23384,46 +21254,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1816</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>1816</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>1817</integer>
+// CHECK-NEXT:            <key>line</key><integer>1834</integer>
 // CHECK-NEXT:            <key>col</key><integer>9</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1817</integer>
-// CHECK-NEXT:            <key>col</key><integer>16</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>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>1817</integer>
-// CHECK-NEXT:            <key>col</key><integer>9</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1817</integer>
+// CHECK-NEXT:            <key>line</key><integer>1834</integer>
 // CHECK-NEXT:            <key>col</key><integer>16</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -23431,12 +21267,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1818</integer>
+// CHECK-NEXT:            <key>line</key><integer>1835</integer>
 // CHECK-NEXT:            <key>col</key><integer>9</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1818</integer>
+// CHECK-NEXT:            <key>line</key><integer>1835</integer>
 // CHECK-NEXT:            <key>col</key><integer>15</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -23445,44 +21281,10 @@
 // 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>1818</integer>
-// CHECK-NEXT:            <key>col</key><integer>9</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1818</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>1818</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>1818</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:     </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>1818</integer>
+// CHECK-NEXT:       <key>line</key><integer>1835</integer>
 // CHECK-NEXT:       <key>col</key><integer>22</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -23490,12 +21292,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1818</integer>
+// CHECK-NEXT:          <key>line</key><integer>1835</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>1818</integer>
+// CHECK-NEXT:          <key>line</key><integer>1835</integer>
 // CHECK-NEXT:          <key>col</key><integer>66</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -23515,344 +21317,6 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1818</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>1818</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>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1821</integer>
-// CHECK-NEXT:            <key>col</key><integer>9</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1821</integer>
-// CHECK-NEXT:            <key>col</key><integer>9</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1821</integer>
-// CHECK-NEXT:       <key>col</key><integer>9</integer>
-// CHECK-NEXT:       <key>file</key><integer>0</integer>
-// CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>ranges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1821</integer>
-// CHECK-NEXT:          <key>col</key><integer>9</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1821</integer>
-// CHECK-NEXT:          <key>col</key><integer>23</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;a&apos; is not referenced later in this execution path and has a retain count of +1</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;a&apos; is not referenced later in this execution path and has a retain count of +1</string>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:    </array>
-// CHECK-NEXT:    <key>description</key><string>Potential leak of an object stored into &apos;a&apos;</string>
-// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
-// CHECK-NEXT:    <key>type</key><string>Leak</string>
-// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT:   <key>issue_context</key><string>test_objc_arrays</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>6</string>
-// CHECK-NEXT:   <key>location</key>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1821</integer>
-// CHECK-NEXT:    <key>col</key><integer>9</integer>
-// CHECK-NEXT:    <key>file</key><integer>0</integer>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>path</key>
-// CHECK-NEXT:    <array>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>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>1816</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>1816</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>1817</integer>
-// CHECK-NEXT:            <key>col</key><integer>9</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1817</integer>
-// CHECK-NEXT:            <key>col</key><integer>16</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>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>1817</integer>
-// CHECK-NEXT:            <key>col</key><integer>9</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1817</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>1827</integer>
-// CHECK-NEXT:            <key>col</key><integer>9</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1827</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>1827</integer>
-// CHECK-NEXT:            <key>col</key><integer>9</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1827</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>1827</integer>
-// CHECK-NEXT:            <key>col</key><integer>23</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1827</integer>
-// CHECK-NEXT:            <key>col</key><integer>23</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </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>1827</integer>
-// CHECK-NEXT:       <key>col</key><integer>23</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>1827</integer>
-// CHECK-NEXT:          <key>col</key><integer>23</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1827</integer>
-// CHECK-NEXT:          <key>col</key><integer>56</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>Method returns an Objective-C object 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:     </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>1827</integer>
-// CHECK-NEXT:            <key>col</key><integer>23</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1827</integer>
-// CHECK-NEXT:            <key>col</key><integer>23</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1830</integer>
-// CHECK-NEXT:            <key>col</key><integer>9</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1830</integer>
-// CHECK-NEXT:            <key>col</key><integer>9</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1830</integer>
-// CHECK-NEXT:       <key>col</key><integer>9</integer>
-// CHECK-NEXT:       <key>file</key><integer>0</integer>
-// CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>ranges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1830</integer>
-// CHECK-NEXT:          <key>col</key><integer>9</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1830</integer>
-// CHECK-NEXT:          <key>col</key><integer>23</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;a2&apos; is not referenced later in this execution path and has a retain count of +1</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;a2&apos; is not referenced later in this execution path and has a retain count of +1</string>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:    </array>
-// CHECK-NEXT:    <key>description</key><string>Potential leak of an object stored into &apos;a2&apos;</string>
-// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
-// CHECK-NEXT:    <key>type</key><string>Leak</string>
-// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT:   <key>issue_context</key><string>test_objc_arrays</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>15</string>
-// CHECK-NEXT:   <key>location</key>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1830</integer>
-// CHECK-NEXT:    <key>col</key><integer>9</integer>
-// CHECK-NEXT:    <key>file</key><integer>0</integer>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   </dict>
-// CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>path</key>
-// CHECK-NEXT:    <array>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>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>1816</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>1816</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>1817</integer>
-// CHECK-NEXT:            <key>col</key><integer>9</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1817</integer>
-// CHECK-NEXT:            <key>col</key><integer>16</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>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>1817</integer>
-// CHECK-NEXT:            <key>col</key><integer>9</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1817</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>1835</integer>
 // CHECK-NEXT:            <key>col</key><integer>9</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
@@ -23863,165 +21327,6 @@
 // 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>1835</integer>
-// CHECK-NEXT:            <key>col</key><integer>9</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1835</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>1835</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>1835</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>1835</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>1835</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>1835</integer>
-// CHECK-NEXT:          <key>col</key><integer>27</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>NSArray literal is an object with a +0 retain count</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>NSArray literal is an object with a +0 retain count</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>1835</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>1835</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>1835</integer>
-// CHECK-NEXT:            <key>col</key><integer>23</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1835</integer>
-// CHECK-NEXT:            <key>col</key><integer>23</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </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>1835</integer>
-// CHECK-NEXT:       <key>col</key><integer>23</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>1835</integer>
-// CHECK-NEXT:          <key>col</key><integer>23</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1835</integer>
-// CHECK-NEXT:          <key>col</key><integer>35</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1835</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>1835</integer>
-// CHECK-NEXT:          <key>col</key><integer>27</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>Reference count incremented. The object now has a +1 retain count</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Reference count incremented. The object now has a +1 retain count</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>1835</integer>
-// CHECK-NEXT:            <key>col</key><integer>23</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1835</integer>
-// CHECK-NEXT:            <key>col</key><integer>23</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
@@ -24063,17 +21368,17 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;a3&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;a&apos; is not referenced later in this execution path and has a retain count of +1</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;a3&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;a&apos; is not referenced later in this execution path and has a retain count of +1</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:    </array>
-// CHECK-NEXT:    <key>description</key><string>Potential leak of an object stored into &apos;a3&apos;</string>
+// CHECK-NEXT:    <key>description</key><string>Potential leak of an object stored into &apos;a&apos;</string>
 // CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>test_objc_arrays</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>23</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>3</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
 // CHECK-NEXT:    <key>line</key><integer>1838</integer>
@@ -24092,25 +21397,59 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1816</integer>
-// CHECK-NEXT:            <key>col</key><integer>5</integer>
+// CHECK-NEXT:            <key>line</key><integer>1834</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1816</integer>
-// CHECK-NEXT:            <key>col</key><integer>5</integer>
+// CHECK-NEXT:            <key>line</key><integer>1834</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>1817</integer>
+// CHECK-NEXT:            <key>line</key><integer>1838</integer>
 // CHECK-NEXT:            <key>col</key><integer>9</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1817</integer>
+// CHECK-NEXT:            <key>line</key><integer>1838</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>1838</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1838</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>1842</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1842</integer>
 // CHECK-NEXT:            <key>col</key><integer>16</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -24126,12 +21465,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1817</integer>
+// CHECK-NEXT:            <key>line</key><integer>1842</integer>
 // CHECK-NEXT:            <key>col</key><integer>9</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1817</integer>
+// CHECK-NEXT:            <key>line</key><integer>1842</integer>
 // CHECK-NEXT:            <key>col</key><integer>16</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -24139,12 +21478,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1843</integer>
+// CHECK-NEXT:            <key>line</key><integer>1844</integer>
 // CHECK-NEXT:            <key>col</key><integer>9</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1843</integer>
+// CHECK-NEXT:            <key>line</key><integer>1844</integer>
 // CHECK-NEXT:            <key>col</key><integer>15</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -24153,58 +21492,24 @@
 // 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>1843</integer>
-// CHECK-NEXT:            <key>col</key><integer>9</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1843</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>1843</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>1843</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:     </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>1843</integer>
-// CHECK-NEXT:       <key>col</key><integer>22</integer>
+// CHECK-NEXT:       <key>line</key><integer>1844</integer>
+// CHECK-NEXT:       <key>col</key><integer>23</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>1843</integer>
-// CHECK-NEXT:          <key>col</key><integer>22</integer>
+// CHECK-NEXT:          <key>line</key><integer>1844</integer>
+// CHECK-NEXT:          <key>col</key><integer>23</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1843</integer>
-// CHECK-NEXT:          <key>col</key><integer>57</integer>
+// CHECK-NEXT:          <key>line</key><integer>1844</integer>
+// CHECK-NEXT:          <key>col</key><integer>56</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:        </array>
@@ -24223,13 +21528,13 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1843</integer>
-// CHECK-NEXT:            <key>col</key><integer>22</integer>
+// CHECK-NEXT:            <key>line</key><integer>1844</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1843</integer>
-// CHECK-NEXT:            <key>col</key><integer>22</integer>
+// CHECK-NEXT:            <key>line</key><integer>1844</integer>
+// CHECK-NEXT:            <key>col</key><integer>15</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
@@ -24274,17 +21579,17 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;a&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;a2&apos; is not referenced later in this execution path and has a retain count of +1</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;a&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;a2&apos; is not referenced later in this execution path and has a retain count of +1</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:    </array>
-// CHECK-NEXT:    <key>description</key><string>Potential leak of an object stored into &apos;a&apos;</string>
+// CHECK-NEXT:    <key>description</key><string>Potential leak of an object stored into &apos;a2&apos;</string>
 // CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>test_objc_arrays</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>32</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>12</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
 // CHECK-NEXT:    <key>line</key><integer>1847</integer>
@@ -24303,25 +21608,59 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1816</integer>
-// CHECK-NEXT:            <key>col</key><integer>5</integer>
+// CHECK-NEXT:            <key>line</key><integer>1834</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1816</integer>
-// CHECK-NEXT:            <key>col</key><integer>5</integer>
+// CHECK-NEXT:            <key>line</key><integer>1834</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>1817</integer>
+// CHECK-NEXT:            <key>line</key><integer>1838</integer>
 // CHECK-NEXT:            <key>col</key><integer>9</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1817</integer>
+// CHECK-NEXT:            <key>line</key><integer>1838</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>1838</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1838</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>1842</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1842</integer>
 // CHECK-NEXT:            <key>col</key><integer>16</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -24337,12 +21676,80 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1817</integer>
+// CHECK-NEXT:            <key>line</key><integer>1842</integer>
 // CHECK-NEXT:            <key>col</key><integer>9</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1817</integer>
+// CHECK-NEXT:            <key>line</key><integer>1842</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>1847</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1847</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>1847</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1847</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>1851</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1851</integer>
+// CHECK-NEXT:            <key>col</key><integer>16</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>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>1851</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1851</integer>
 // CHECK-NEXT:            <key>col</key><integer>16</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -24356,7 +21763,7 @@
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
 // CHECK-NEXT:            <key>line</key><integer>1852</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
+// CHECK-NEXT:            <key>col</key><integer>15</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
@@ -24377,7 +21784,7 @@
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
 // CHECK-NEXT:            <key>line</key><integer>1852</integer>
-// CHECK-NEXT:            <key>col</key><integer>20</integer>
+// CHECK-NEXT:            <key>col</key><integer>15</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
@@ -24385,12 +21792,12 @@
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
 // CHECK-NEXT:            <key>line</key><integer>1852</integer>
-// CHECK-NEXT:            <key>col</key><integer>28</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>1852</integer>
-// CHECK-NEXT:            <key>col</key><integer>28</integer>
+// CHECK-NEXT:            <key>col</key><integer>24</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
@@ -24402,7 +21809,7 @@
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
 // CHECK-NEXT:       <key>line</key><integer>1852</integer>
-// CHECK-NEXT:       <key>col</key><integer>28</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>
@@ -24410,87 +21817,53 @@
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
 // CHECK-NEXT:          <key>line</key><integer>1852</integer>
-// CHECK-NEXT:          <key>col</key><integer>28</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>1852</integer>
-// CHECK-NEXT:          <key>col</key><integer>35</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>NSDictionary literal is an object with a +0 retain count</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>NSDictionary literal is an object with a +0 retain count</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>1852</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>1852</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:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1852</integer>
-// CHECK-NEXT:            <key>col</key><integer>27</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1852</integer>
-// CHECK-NEXT:            <key>col</key><integer>27</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>1852</integer>
-// CHECK-NEXT:       <key>col</key><integer>27</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>1852</integer>
 // CHECK-NEXT:          <key>col</key><integer>27</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>NSArray literal is an object with a +0 retain count</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>NSArray literal is an object with a +0 retain count</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>1852</integer>
+// CHECK-NEXT:       <key>col</key><integer>23</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>1852</integer>
-// CHECK-NEXT:          <key>col</key><integer>43</integer>
+// CHECK-NEXT:          <key>col</key><integer>23</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>1852</integer>
+// CHECK-NEXT:          <key>col</key><integer>35</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:        </array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
 // CHECK-NEXT:          <key>line</key><integer>1852</integer>
-// CHECK-NEXT:          <key>col</key><integer>28</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>1852</integer>
-// CHECK-NEXT:          <key>col</key><integer>35</integer>
+// CHECK-NEXT:          <key>col</key><integer>27</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:        </array>
@@ -24510,24 +21883,58 @@
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
 // CHECK-NEXT:            <key>line</key><integer>1852</integer>
-// CHECK-NEXT:            <key>col</key><integer>27</integer>
+// CHECK-NEXT:            <key>col</key><integer>23</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
 // CHECK-NEXT:            <key>line</key><integer>1852</integer>
-// CHECK-NEXT:            <key>col</key><integer>27</integer>
+// CHECK-NEXT:            <key>col</key><integer>23</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1856</integer>
+// CHECK-NEXT:            <key>line</key><integer>1852</integer>
 // CHECK-NEXT:            <key>col</key><integer>9</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1856</integer>
+// CHECK-NEXT:            <key>line</key><integer>1852</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>1852</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1852</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>1855</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1855</integer>
 // CHECK-NEXT:            <key>col</key><integer>9</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -24539,7 +21946,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1856</integer>
+// CHECK-NEXT:       <key>line</key><integer>1855</integer>
 // CHECK-NEXT:       <key>col</key><integer>9</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -24547,12 +21954,359 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1856</integer>
+// CHECK-NEXT:          <key>line</key><integer>1855</integer>
 // CHECK-NEXT:          <key>col</key><integer>9</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1856</integer>
+// CHECK-NEXT:          <key>line</key><integer>1855</integer>
+// CHECK-NEXT:          <key>col</key><integer>23</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;a3&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;a3&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:    </array>
+// CHECK-NEXT:    <key>description</key><string>Potential leak of an object stored into &apos;a3&apos;</string>
+// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK-NEXT:    <key>type</key><string>Leak</string>
+// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT:   <key>issue_context</key><string>test_objc_arrays</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>20</string>
+// CHECK-NEXT:   <key>location</key>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>line</key><integer>1855</integer>
+// CHECK-NEXT:    <key>col</key><integer>9</integer>
+// CHECK-NEXT:    <key>file</key><integer>0</integer>
+// CHECK-NEXT:   </dict>
+// CHECK-NEXT:   </dict>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>path</key>
+// CHECK-NEXT:    <array>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>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>1834</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1834</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>1838</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1838</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>1838</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1838</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>1842</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1842</integer>
+// CHECK-NEXT:            <key>col</key><integer>16</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>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>1842</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1842</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>1847</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1847</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>1847</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1847</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>1851</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1851</integer>
+// CHECK-NEXT:            <key>col</key><integer>16</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>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>1851</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1851</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>1855</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1855</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>1855</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1855</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>1859</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1859</integer>
+// CHECK-NEXT:            <key>col</key><integer>16</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>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>1859</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1859</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>1860</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1860</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>1860</integer>
+// CHECK-NEXT:       <key>col</key><integer>22</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>1860</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>1860</integer>
+// CHECK-NEXT:          <key>col</key><integer>57</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>Method returns an Objective-C object 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:     </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>1860</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1860</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>1864</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1864</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>1864</integer>
+// CHECK-NEXT:       <key>col</key><integer>9</integer>
+// CHECK-NEXT:       <key>file</key><integer>0</integer>
+// CHECK-NEXT:      </dict>
+// CHECK-NEXT:      <key>ranges</key>
+// CHECK-NEXT:      <array>
+// CHECK-NEXT:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>1864</integer>
+// CHECK-NEXT:          <key>col</key><integer>9</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>1864</integer>
 // CHECK-NEXT:          <key>col</key><integer>23</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -24570,10 +22324,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>test_objc_arrays</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>41</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>28</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1856</integer>
+// CHECK-NEXT:    <key>line</key><integer>1864</integer>
 // CHECK-NEXT:    <key>col</key><integer>9</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -24589,12 +22343,536 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1861</integer>
+// CHECK-NEXT:            <key>line</key><integer>1834</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1834</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>1838</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1838</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>1838</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1838</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>1842</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1842</integer>
+// CHECK-NEXT:            <key>col</key><integer>16</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>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>1842</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1842</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>1847</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1847</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>1847</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1847</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>1851</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1851</integer>
+// CHECK-NEXT:            <key>col</key><integer>16</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>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>1851</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1851</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>1855</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1855</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>1855</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1855</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>1859</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1859</integer>
+// CHECK-NEXT:            <key>col</key><integer>16</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>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>1859</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1859</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>1864</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1864</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>1864</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1864</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>1868</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1868</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>1868</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1868</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>1869</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1869</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:     </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>1869</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1869</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>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1869</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>1869</integer>
+// CHECK-NEXT:            <key>col</key><integer>28</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>1869</integer>
+// CHECK-NEXT:       <key>col</key><integer>28</integer>
+// CHECK-NEXT:       <key>file</key><integer>0</integer>
+// CHECK-NEXT:      </dict>
+// CHECK-NEXT:      <key>ranges</key>
+// CHECK-NEXT:      <array>
+// CHECK-NEXT:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>1869</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>1869</integer>
+// CHECK-NEXT:          <key>col</key><integer>35</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>NSDictionary literal is an object with a +0 retain count</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>NSDictionary literal is an object with a +0 retain count</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>1869</integer>
+// CHECK-NEXT:       <key>col</key><integer>27</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>1869</integer>
+// CHECK-NEXT:          <key>col</key><integer>27</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>1869</integer>
+// CHECK-NEXT:          <key>col</key><integer>43</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>1869</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>1869</integer>
+// CHECK-NEXT:          <key>col</key><integer>35</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>Reference count incremented. The object now has a +1 retain count</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Reference count incremented. The object now has a +1 retain count</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>1869</integer>
+// CHECK-NEXT:            <key>col</key><integer>27</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1869</integer>
+// CHECK-NEXT:            <key>col</key><integer>27</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>1869</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1869</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:     </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>1869</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1869</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>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1873</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1873</integer>
+// CHECK-NEXT:            <key>col</key><integer>9</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>1873</integer>
+// CHECK-NEXT:       <key>col</key><integer>9</integer>
+// CHECK-NEXT:       <key>file</key><integer>0</integer>
+// CHECK-NEXT:      </dict>
+// CHECK-NEXT:      <key>ranges</key>
+// CHECK-NEXT:      <array>
+// CHECK-NEXT:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>1873</integer>
+// CHECK-NEXT:          <key>col</key><integer>9</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>1873</integer>
+// CHECK-NEXT:          <key>col</key><integer>23</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;a&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;a&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:    </array>
+// CHECK-NEXT:    <key>description</key><string>Potential leak of an object stored into &apos;a&apos;</string>
+// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK-NEXT:    <key>type</key><string>Leak</string>
+// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT:   <key>issue_context</key><string>test_objc_arrays</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>37</string>
+// CHECK-NEXT:   <key>location</key>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>line</key><integer>1873</integer>
+// CHECK-NEXT:    <key>col</key><integer>9</integer>
+// CHECK-NEXT:    <key>file</key><integer>0</integer>
+// CHECK-NEXT:   </dict>
+// CHECK-NEXT:   </dict>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>path</key>
+// CHECK-NEXT:    <array>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>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>1878</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>1861</integer>
+// CHECK-NEXT:            <key>line</key><integer>1878</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -24602,12 +22880,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1861</integer>
+// CHECK-NEXT:            <key>line</key><integer>1878</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>1861</integer>
+// CHECK-NEXT:            <key>line</key><integer>1878</integer>
 // CHECK-NEXT:            <key>col</key><integer>15</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -24619,7 +22897,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1861</integer>
+// CHECK-NEXT:       <key>line</key><integer>1878</integer>
 // CHECK-NEXT:       <key>col</key><integer>15</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -24627,12 +22905,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1861</integer>
+// CHECK-NEXT:          <key>line</key><integer>1878</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>1861</integer>
+// CHECK-NEXT:          <key>line</key><integer>1878</integer>
 // CHECK-NEXT:          <key>col</key><integer>16</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -24645,44 +22923,10 @@
 // CHECK-NEXT:      <string>NSNumber literal is an object with a +0 retain count</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>1861</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>1861</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>1861</integer>
-// CHECK-NEXT:            <key>col</key><integer>14</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1861</integer>
-// CHECK-NEXT:            <key>col</key><integer>14</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1861</integer>
+// CHECK-NEXT:       <key>line</key><integer>1878</integer>
 // CHECK-NEXT:       <key>col</key><integer>14</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -24690,24 +22934,24 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1861</integer>
+// CHECK-NEXT:          <key>line</key><integer>1878</integer>
 // CHECK-NEXT:          <key>col</key><integer>14</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1861</integer>
+// CHECK-NEXT:          <key>line</key><integer>1878</integer>
 // CHECK-NEXT:          <key>col</key><integer>24</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:        </array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1861</integer>
+// CHECK-NEXT:          <key>line</key><integer>1878</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>1861</integer>
+// CHECK-NEXT:          <key>line</key><integer>1878</integer>
 // CHECK-NEXT:          <key>col</key><integer>16</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -24727,12 +22971,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1861</integer>
+// CHECK-NEXT:            <key>line</key><integer>1878</integer>
 // CHECK-NEXT:            <key>col</key><integer>14</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1861</integer>
+// CHECK-NEXT:            <key>line</key><integer>1878</integer>
 // CHECK-NEXT:            <key>col</key><integer>14</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -24740,12 +22984,80 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1863</integer>
+// CHECK-NEXT:            <key>line</key><integer>1878</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>1878</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>1878</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>1878</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>1879</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>1879</integer>
+// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>control</string>
+// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:       <array>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1879</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>1879</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>1880</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>1863</integer>
+// CHECK-NEXT:            <key>line</key><integer>1880</integer>
 // CHECK-NEXT:            <key>col</key><integer>1</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -24757,7 +23069,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1863</integer>
+// CHECK-NEXT:       <key>line</key><integer>1880</integer>
 // CHECK-NEXT:       <key>col</key><integer>1</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -24773,10 +23085,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>test_objc_integer_literals</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>3</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>1</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1863</integer>
+// CHECK-NEXT:    <key>line</key><integer>1880</integer>
 // CHECK-NEXT:    <key>col</key><integer>1</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -24792,12 +23104,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1866</integer>
+// CHECK-NEXT:            <key>line</key><integer>1883</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>1866</integer>
+// CHECK-NEXT:            <key>line</key><integer>1883</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -24805,12 +23117,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1866</integer>
+// CHECK-NEXT:            <key>line</key><integer>1883</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>1866</integer>
+// CHECK-NEXT:            <key>line</key><integer>1883</integer>
 // CHECK-NEXT:            <key>col</key><integer>15</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -24822,7 +23134,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1866</integer>
+// CHECK-NEXT:       <key>line</key><integer>1883</integer>
 // CHECK-NEXT:       <key>col</key><integer>15</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -24830,12 +23142,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1866</integer>
+// CHECK-NEXT:          <key>line</key><integer>1883</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>1866</integer>
+// CHECK-NEXT:          <key>line</key><integer>1883</integer>
 // CHECK-NEXT:          <key>col</key><integer>18</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -24848,44 +23160,10 @@
 // CHECK-NEXT:      <string>NSNumber boxed expression produces an object with a +0 retain count</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>1866</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>1866</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>1866</integer>
-// CHECK-NEXT:            <key>col</key><integer>14</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1866</integer>
-// CHECK-NEXT:            <key>col</key><integer>14</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1866</integer>
+// CHECK-NEXT:       <key>line</key><integer>1883</integer>
 // CHECK-NEXT:       <key>col</key><integer>14</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -24893,24 +23171,24 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1866</integer>
+// CHECK-NEXT:          <key>line</key><integer>1883</integer>
 // CHECK-NEXT:          <key>col</key><integer>14</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1866</integer>
+// CHECK-NEXT:          <key>line</key><integer>1883</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:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1866</integer>
+// CHECK-NEXT:          <key>line</key><integer>1883</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>1866</integer>
+// CHECK-NEXT:          <key>line</key><integer>1883</integer>
 // CHECK-NEXT:          <key>col</key><integer>18</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -24930,12 +23208,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1866</integer>
+// CHECK-NEXT:            <key>line</key><integer>1883</integer>
 // CHECK-NEXT:            <key>col</key><integer>14</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1866</integer>
+// CHECK-NEXT:            <key>line</key><integer>1883</integer>
 // CHECK-NEXT:            <key>col</key><integer>14</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -24943,12 +23221,46 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1870</integer>
+// CHECK-NEXT:            <key>line</key><integer>1883</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>1870</integer>
+// CHECK-NEXT:            <key>line</key><integer>1883</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>1883</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>1883</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>1887</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>1887</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -24960,7 +23272,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1870</integer>
+// CHECK-NEXT:       <key>line</key><integer>1887</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -24968,12 +23280,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1870</integer>
+// CHECK-NEXT:          <key>line</key><integer>1887</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>1870</integer>
+// CHECK-NEXT:          <key>line</key><integer>1887</integer>
 // CHECK-NEXT:          <key>col</key><integer>21</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -24991,10 +23303,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>test_objc_boxed_expressions</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>5</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>1</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1870</integer>
+// CHECK-NEXT:    <key>line</key><integer>1887</integer>
 // CHECK-NEXT:    <key>col</key><integer>3</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -25010,12 +23322,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1866</integer>
+// CHECK-NEXT:            <key>line</key><integer>1883</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>1866</integer>
+// CHECK-NEXT:            <key>line</key><integer>1883</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -25023,12 +23335,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1869</integer>
+// CHECK-NEXT:            <key>line</key><integer>1886</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>1869</integer>
+// CHECK-NEXT:            <key>line</key><integer>1886</integer>
 // CHECK-NEXT:            <key>col</key><integer>7</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -25044,12 +23356,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1869</integer>
+// CHECK-NEXT:            <key>line</key><integer>1886</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>1869</integer>
+// CHECK-NEXT:            <key>line</key><integer>1886</integer>
 // CHECK-NEXT:            <key>col</key><integer>7</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -25057,12 +23369,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1869</integer>
+// CHECK-NEXT:            <key>line</key><integer>1886</integer>
 // CHECK-NEXT:            <key>col</key><integer>12</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1869</integer>
+// CHECK-NEXT:            <key>line</key><integer>1886</integer>
 // CHECK-NEXT:            <key>col</key><integer>12</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -25074,7 +23386,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1869</integer>
+// CHECK-NEXT:       <key>line</key><integer>1886</integer>
 // CHECK-NEXT:       <key>col</key><integer>12</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -25082,12 +23394,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1869</integer>
+// CHECK-NEXT:          <key>line</key><integer>1886</integer>
 // CHECK-NEXT:          <key>col</key><integer>12</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1869</integer>
+// CHECK-NEXT:          <key>line</key><integer>1886</integer>
 // CHECK-NEXT:          <key>col</key><integer>15</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -25100,44 +23412,10 @@
 // CHECK-NEXT:      <string>NSString boxed expression produces an object with a +0 retain count</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>1869</integer>
-// CHECK-NEXT:            <key>col</key><integer>12</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1869</integer>
-// CHECK-NEXT:            <key>col</key><integer>12</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1869</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>1869</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>1869</integer>
+// CHECK-NEXT:       <key>line</key><integer>1886</integer>
 // CHECK-NEXT:       <key>col</key><integer>11</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -25145,24 +23423,24 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1869</integer>
+// CHECK-NEXT:          <key>line</key><integer>1886</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>1869</integer>
+// CHECK-NEXT:          <key>line</key><integer>1886</integer>
 // CHECK-NEXT:          <key>col</key><integer>23</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:        </array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1869</integer>
+// CHECK-NEXT:          <key>line</key><integer>1886</integer>
 // CHECK-NEXT:          <key>col</key><integer>12</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1869</integer>
+// CHECK-NEXT:          <key>line</key><integer>1886</integer>
 // CHECK-NEXT:          <key>col</key><integer>15</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -25182,12 +23460,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1869</integer>
+// CHECK-NEXT:            <key>line</key><integer>1886</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>1869</integer>
+// CHECK-NEXT:            <key>line</key><integer>1886</integer>
 // CHECK-NEXT:            <key>col</key><integer>11</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -25195,12 +23473,80 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1871</integer>
+// CHECK-NEXT:            <key>line</key><integer>1886</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>1886</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>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>1886</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>1886</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>1887</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>1887</integer>
+// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>control</string>
+// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:       <array>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1887</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>1887</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>1888</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>1871</integer>
+// CHECK-NEXT:            <key>line</key><integer>1888</integer>
 // CHECK-NEXT:            <key>col</key><integer>1</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -25212,7 +23558,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1871</integer>
+// CHECK-NEXT:       <key>line</key><integer>1888</integer>
 // CHECK-NEXT:       <key>col</key><integer>1</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -25228,10 +23574,10 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>test_objc_boxed_expressions</string>
-// CHECK-NEXT:   <key>issue_hash</key><string>6</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>4</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1871</integer>
+// CHECK-NEXT:    <key>line</key><integer>1888</integer>
 // CHECK-NEXT:    <key>col</key><integer>1</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -25247,46 +23593,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1876</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>1876</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>1877</integer>
+// CHECK-NEXT:            <key>line</key><integer>1894</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>1877</integer>
-// CHECK-NEXT:            <key>col</key><integer>12</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </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>1877</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>1877</integer>
+// CHECK-NEXT:            <key>line</key><integer>1894</integer>
 // CHECK-NEXT:            <key>col</key><integer>12</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -25294,12 +23606,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1878</integer>
+// CHECK-NEXT:            <key>line</key><integer>1895</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>1878</integer>
+// CHECK-NEXT:            <key>line</key><integer>1895</integer>
 // CHECK-NEXT:            <key>col</key><integer>6</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -25315,12 +23627,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1878</integer>
+// CHECK-NEXT:            <key>line</key><integer>1895</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>1878</integer>
+// CHECK-NEXT:            <key>line</key><integer>1895</integer>
 // CHECK-NEXT:            <key>col</key><integer>6</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -25328,12 +23640,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1878</integer>
+// CHECK-NEXT:            <key>line</key><integer>1895</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>1878</integer>
+// CHECK-NEXT:            <key>line</key><integer>1895</integer>
 // CHECK-NEXT:            <key>col</key><integer>8</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -25345,7 +23657,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1878</integer>
+// CHECK-NEXT:       <key>line</key><integer>1895</integer>
 // CHECK-NEXT:       <key>col</key><integer>8</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -25353,12 +23665,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1878</integer>
+// CHECK-NEXT:          <key>line</key><integer>1895</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>1878</integer>
+// CHECK-NEXT:          <key>line</key><integer>1895</integer>
 // CHECK-NEXT:          <key>col</key><integer>12</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -25378,12 +23690,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1878</integer>
+// CHECK-NEXT:            <key>line</key><integer>1895</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>1878</integer>
+// CHECK-NEXT:            <key>line</key><integer>1895</integer>
 // CHECK-NEXT:            <key>col</key><integer>8</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -25391,12 +23703,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1881</integer>
+// CHECK-NEXT:            <key>line</key><integer>1898</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>1881</integer>
+// CHECK-NEXT:            <key>line</key><integer>1898</integer>
 // CHECK-NEXT:            <key>col</key><integer>17</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -25405,44 +23717,10 @@
 // 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>1881</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>1881</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>1881</integer>
-// CHECK-NEXT:            <key>col</key><integer>21</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1881</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:     </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>1881</integer>
+// CHECK-NEXT:       <key>line</key><integer>1898</integer>
 // CHECK-NEXT:       <key>col</key><integer>21</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -25450,12 +23728,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1881</integer>
+// CHECK-NEXT:          <key>line</key><integer>1898</integer>
 // CHECK-NEXT:          <key>col</key><integer>21</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1881</integer>
+// CHECK-NEXT:          <key>line</key><integer>1898</integer>
 // CHECK-NEXT:          <key>col</key><integer>43</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -25475,25 +23753,25 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1881</integer>
-// CHECK-NEXT:            <key>col</key><integer>21</integer>
+// CHECK-NEXT:            <key>line</key><integer>1898</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>1881</integer>
-// CHECK-NEXT:            <key>col</key><integer>21</integer>
+// CHECK-NEXT:            <key>line</key><integer>1898</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>1882</integer>
+// CHECK-NEXT:            <key>line</key><integer>1899</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>1882</integer>
+// CHECK-NEXT:            <key>line</key><integer>1899</integer>
 // CHECK-NEXT:            <key>col</key><integer>9</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -25509,12 +23787,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1882</integer>
+// CHECK-NEXT:            <key>line</key><integer>1899</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>1882</integer>
+// CHECK-NEXT:            <key>line</key><integer>1899</integer>
 // CHECK-NEXT:            <key>col</key><integer>9</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -25522,12 +23800,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1883</integer>
+// CHECK-NEXT:            <key>line</key><integer>1900</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>1883</integer>
+// CHECK-NEXT:            <key>line</key><integer>1900</integer>
 // CHECK-NEXT:            <key>col</key><integer>5</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -25539,7 +23817,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1883</integer>
+// CHECK-NEXT:       <key>line</key><integer>1900</integer>
 // CHECK-NEXT:       <key>col</key><integer>5</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -25547,24 +23825,24 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1883</integer>
+// CHECK-NEXT:          <key>line</key><integer>1900</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>1883</integer>
+// CHECK-NEXT:          <key>line</key><integer>1900</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:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1883</integer>
+// CHECK-NEXT:          <key>line</key><integer>1900</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>1883</integer>
+// CHECK-NEXT:          <key>line</key><integer>1900</integer>
 // CHECK-NEXT:          <key>col</key><integer>16</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -25584,12 +23862,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1883</integer>
+// CHECK-NEXT:            <key>line</key><integer>1900</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>1883</integer>
+// CHECK-NEXT:            <key>line</key><integer>1900</integer>
 // CHECK-NEXT:            <key>col</key><integer>5</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -25597,12 +23875,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1884</integer>
+// CHECK-NEXT:            <key>line</key><integer>1901</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>1884</integer>
+// CHECK-NEXT:            <key>line</key><integer>1901</integer>
 // CHECK-NEXT:            <key>col</key><integer>9</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -25614,7 +23892,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1884</integer>
+// CHECK-NEXT:       <key>line</key><integer>1901</integer>
 // CHECK-NEXT:       <key>col</key><integer>5</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -25622,12 +23900,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1884</integer>
+// CHECK-NEXT:          <key>line</key><integer>1901</integer>
 // CHECK-NEXT:          <key>col</key><integer>25</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1884</integer>
+// CHECK-NEXT:          <key>line</key><integer>1901</integer>
 // CHECK-NEXT:          <key>col</key><integer>35</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -25648,7 +23926,7 @@
 // CHECK-NEXT:   <key>issue_hash</key><string>9</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1884</integer>
+// CHECK-NEXT:    <key>line</key><integer>1901</integer>
 // CHECK-NEXT:    <key>col</key><integer>5</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -25664,12 +23942,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1903</integer>
+// CHECK-NEXT:            <key>line</key><integer>1920</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>1903</integer>
+// CHECK-NEXT:            <key>line</key><integer>1920</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -25677,12 +23955,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1911</integer>
+// CHECK-NEXT:            <key>line</key><integer>1928</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>1911</integer>
+// CHECK-NEXT:            <key>line</key><integer>1928</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -25691,44 +23969,10 @@
 // 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>1911</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>1911</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>1911</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>1911</integer>
-// CHECK-NEXT:            <key>col</key><integer>19</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>1911</integer>
+// CHECK-NEXT:       <key>line</key><integer>1928</integer>
 // CHECK-NEXT:       <key>col</key><integer>19</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -25736,12 +23980,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1911</integer>
+// CHECK-NEXT:          <key>line</key><integer>1928</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>1911</integer>
+// CHECK-NEXT:          <key>line</key><integer>1928</integer>
 // CHECK-NEXT:          <key>col</key><integer>21</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -25761,25 +24005,25 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1911</integer>
-// CHECK-NEXT:            <key>col</key><integer>19</integer>
+// CHECK-NEXT:            <key>line</key><integer>1928</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>1911</integer>
-// CHECK-NEXT:            <key>col</key><integer>19</integer>
+// CHECK-NEXT:            <key>line</key><integer>1928</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>1912</integer>
+// CHECK-NEXT:            <key>line</key><integer>1929</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>1912</integer>
+// CHECK-NEXT:            <key>line</key><integer>1929</integer>
 // CHECK-NEXT:            <key>col</key><integer>24</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -25791,7 +24035,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1912</integer>
+// CHECK-NEXT:       <key>line</key><integer>1929</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -25799,12 +24043,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1912</integer>
+// CHECK-NEXT:          <key>line</key><integer>1929</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>1912</integer>
+// CHECK-NEXT:          <key>line</key><integer>1929</integer>
 // CHECK-NEXT:          <key>col</key><integer>35</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -25825,7 +24069,7 @@
 // CHECK-NEXT:   <key>issue_hash</key><string>10</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1912</integer>
+// CHECK-NEXT:    <key>line</key><integer>1929</integer>
 // CHECK-NEXT:    <key>col</key><integer>3</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -25841,12 +24085,12 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1916</integer>
+// CHECK-NEXT:            <key>line</key><integer>1933</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>1916</integer>
+// CHECK-NEXT:            <key>line</key><integer>1933</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -25854,12 +24098,12 @@
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1924</integer>
+// CHECK-NEXT:            <key>line</key><integer>1941</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>1924</integer>
+// CHECK-NEXT:            <key>line</key><integer>1941</integer>
 // CHECK-NEXT:            <key>col</key><integer>4</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -25868,44 +24112,10 @@
 // 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>1924</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>1924</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>1924</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>1924</integer>
-// CHECK-NEXT:            <key>col</key><integer>19</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>1924</integer>
+// CHECK-NEXT:       <key>line</key><integer>1941</integer>
 // CHECK-NEXT:       <key>col</key><integer>19</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -25913,12 +24123,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1924</integer>
+// CHECK-NEXT:          <key>line</key><integer>1941</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>1924</integer>
+// CHECK-NEXT:          <key>line</key><integer>1941</integer>
 // CHECK-NEXT:          <key>col</key><integer>21</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -25938,25 +24148,25 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1924</integer>
-// CHECK-NEXT:            <key>col</key><integer>19</integer>
+// CHECK-NEXT:            <key>line</key><integer>1941</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>1924</integer>
-// CHECK-NEXT:            <key>col</key><integer>19</integer>
+// CHECK-NEXT:            <key>line</key><integer>1941</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>1925</integer>
+// CHECK-NEXT:            <key>line</key><integer>1942</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>1925</integer>
+// CHECK-NEXT:            <key>line</key><integer>1942</integer>
 // CHECK-NEXT:            <key>col</key><integer>26</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -25968,7 +24178,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1925</integer>
+// CHECK-NEXT:       <key>line</key><integer>1942</integer>
 // CHECK-NEXT:       <key>col</key><integer>3</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -25976,12 +24186,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1925</integer>
+// CHECK-NEXT:          <key>line</key><integer>1942</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>1925</integer>
+// CHECK-NEXT:          <key>line</key><integer>1942</integer>
 // CHECK-NEXT:          <key>col</key><integer>48</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -26002,7 +24212,7 @@
 // CHECK-NEXT:   <key>issue_hash</key><string>10</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1925</integer>
+// CHECK-NEXT:    <key>line</key><integer>1942</integer>
 // CHECK-NEXT:    <key>col</key><integer>3</integer>
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
@@ -26011,44 +24221,10 @@
 // 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>1937</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>1937</integer>
-// CHECK-NEXT:            <key>col</key><integer>10</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1937</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>1937</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:       </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>1937</integer>
+// CHECK-NEXT:       <key>line</key><integer>1954</integer>
 // CHECK-NEXT:       <key>col</key><integer>16</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -26056,12 +24232,12 @@
 // CHECK-NEXT:      <array>
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>1937</integer>
+// CHECK-NEXT:          <key>line</key><integer>1954</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>1937</integer>
+// CHECK-NEXT:          <key>line</key><integer>1954</integer>
 // CHECK-NEXT:          <key>col</key><integer>31</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
@@ -26081,25 +24257,25 @@
 // CHECK-NEXT:         <key>start</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1937</integer>
-// CHECK-NEXT:            <key>col</key><integer>16</integer>
+// CHECK-NEXT:            <key>line</key><integer>1954</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>1937</integer>
-// CHECK-NEXT:            <key>col</key><integer>29</integer>
+// CHECK-NEXT:            <key>line</key><integer>1954</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>1938</integer>
+// CHECK-NEXT:            <key>line</key><integer>1955</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>1938</integer>
+// CHECK-NEXT:            <key>line</key><integer>1955</integer>
 // CHECK-NEXT:            <key>col</key><integer>1</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
@@ -26111,7 +24287,7 @@
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>1938</integer>
+// CHECK-NEXT:       <key>line</key><integer>1955</integer>
 // CHECK-NEXT:       <key>col</key><integer>1</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
@@ -26127,12 +24303,1881 @@
 // CHECK-NEXT:    <key>type</key><string>Leak</string>
 // CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
 // CHECK-NEXT:   <key>issue_context</key><string>test_custom_cf</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>1</string>
+// CHECK-NEXT:   <key>location</key>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>line</key><integer>1955</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:   <dict>
+// CHECK-NEXT:    <key>path</key>
+// CHECK-NEXT:    <array>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>1989</integer>
+// CHECK-NEXT:       <key>col</key><integer>18</integer>
+// CHECK-NEXT:       <key>file</key><integer>0</integer>
+// CHECK-NEXT:      </dict>
+// CHECK-NEXT:      <key>ranges</key>
+// CHECK-NEXT:      <array>
+// CHECK-NEXT:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>1989</integer>
+// CHECK-NEXT:          <key>col</key><integer>18</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>1989</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:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Call to function &apos;makeCustom&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Call to function &apos;makeCustom&apos; returns a Core Foundation object with a +1 retain count</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>1989</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>1989</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>1990</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>1990</integer>
+// CHECK-NEXT:            <key>col</key><integer>1</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </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>1990</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>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;obj&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;obj&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:    </array>
+// CHECK-NEXT:    <key>description</key><string>Potential leak of an object stored into &apos;obj&apos;</string>
+// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK-NEXT:    <key>type</key><string>Leak</string>
+// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT:   <key>issue_context</key><string>testCustomReturnsRetained</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>1</string>
+// CHECK-NEXT:   <key>location</key>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>line</key><integer>1990</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:   <dict>
+// CHECK-NEXT:    <key>path</key>
+// CHECK-NEXT:    <array>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>1993</integer>
+// CHECK-NEXT:       <key>col</key><integer>13</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>1993</integer>
+// CHECK-NEXT:          <key>col</key><integer>13</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>1993</integer>
+// CHECK-NEXT:          <key>col</key><integer>23</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Call to function &apos;getCustom&apos; returns a Core Foundation object with a +0 retain count</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Call to function &apos;getCustom&apos; returns a Core Foundation object with a +0 retain count</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>1993</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>1993</integer>
+// CHECK-NEXT:          <key>col</key><integer>13</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>1993</integer>
+// CHECK-NEXT:          <key>col</key><integer>23</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:    </array>
+// CHECK-NEXT:    <key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
+// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK-NEXT:    <key>type</key><string>Bad release</string>
+// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT:   <key>issue_context</key><string>testCustomReturnsNotRetained</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>1</string>
+// CHECK-NEXT:   <key>location</key>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>line</key><integer>1993</integer>
+// CHECK-NEXT:    <key>col</key><integer>3</integer>
+// CHECK-NEXT:    <key>file</key><integer>0</integer>
+// CHECK-NEXT:   </dict>
+// CHECK-NEXT:   </dict>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>path</key>
+// CHECK-NEXT:    <array>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>control</string>
+// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:       <array>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>2012</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>2012</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>2012</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>2012</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>2012</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>2012</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>2012</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:      </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:      <key>message</key>
+// CHECK-NEXT:      <string>Method returns an Objective-C object with a +1 retain count</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>2012</integer>
+// CHECK-NEXT:       <key>col</key><integer>10</integer>
+// CHECK-NEXT:       <key>file</key><integer>0</integer>
+// CHECK-NEXT:      </dict>
+// CHECK-NEXT:      <key>ranges</key>
+// CHECK-NEXT:      <array>
+// CHECK-NEXT:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>2012</integer>
+// CHECK-NEXT:          <key>col</key><integer>10</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>2012</integer>
+// CHECK-NEXT:          <key>col</key><integer>38</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;initX&apos;</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Calling &apos;initX&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>2005</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;test12706177&apos;</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Entered call from &apos;test12706177&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>2005</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>2005</integer>
+// CHECK-NEXT:            <key>col</key><integer>1</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>2006</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>2006</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>2006</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>2006</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>2006</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>2006</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>2006</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>2006</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>2006</integer>
+// CHECK-NEXT:          <key>col</key><integer>10</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>1</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Assuming &apos;Cond&apos; is not equal to 0</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Assuming &apos;Cond&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>2006</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>2006</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>2007</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>2007</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>2012</integer>
+// CHECK-NEXT:       <key>col</key><integer>10</integer>
+// CHECK-NEXT:       <key>file</key><integer>0</integer>
+// CHECK-NEXT:      </dict>
+// CHECK-NEXT:      <key>ranges</key>
+// CHECK-NEXT:      <array>
+// CHECK-NEXT:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>2012</integer>
+// CHECK-NEXT:          <key>col</key><integer>10</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>2012</integer>
+// CHECK-NEXT:          <key>col</key><integer>38</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Returning from &apos;initX&apos;</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Returning from &apos;initX&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>2012</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>2012</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>2012</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>2012</integer>
+// CHECK-NEXT:            <key>col</key><integer>4</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>2012</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>2012</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>2012</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:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:    </array>
+// CHECK-NEXT:    <key>description</key><string>Potential leak of an object</string>
+// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK-NEXT:    <key>type</key><string>Leak</string>
+// CHECK-NEXT:   <key>issue_context_kind</key><string>Objective-C method</string>
+// CHECK-NEXT:   <key>issue_context</key><string>test12706177</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>1</string>
+// CHECK-NEXT:   <key>location</key>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>line</key><integer>2012</integer>
+// CHECK-NEXT:    <key>col</key><integer>3</integer>
+// CHECK-NEXT:    <key>file</key><integer>0</integer>
+// CHECK-NEXT:   </dict>
+// CHECK-NEXT:   </dict>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>path</key>
+// CHECK-NEXT:    <array>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>control</string>
+// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:       <array>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>2028</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>2028</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>2028</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>2028</integer>
+// CHECK-NEXT:            <key>col</key><integer>37</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>2028</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>2028</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>2028</integer>
+// CHECK-NEXT:          <key>col</key><integer>39</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>Call to function &apos;CFGetSomething&apos; returns a Core Foundation object 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:     </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>2028</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>2028</integer>
+// CHECK-NEXT:            <key>col</key><integer>37</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>2028</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>2028</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:     </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>2028</integer>
+// CHECK-NEXT:       <key>col</key><integer>10</integer>
+// CHECK-NEXT:       <key>file</key><integer>0</integer>
+// CHECK-NEXT:      </dict>
+// CHECK-NEXT:      <key>ranges</key>
+// CHECK-NEXT:      <array>
+// CHECK-NEXT:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>2028</integer>
+// CHECK-NEXT:          <key>col</key><integer>10</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>2028</integer>
+// CHECK-NEXT:          <key>col</key><integer>40</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>2028</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>2028</integer>
+// CHECK-NEXT:          <key>col</key><integer>39</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>Object autoreleased</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Object autoreleased</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>2028</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>2028</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>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>2028</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>2028</integer>
+// CHECK-NEXT:            <key>col</key><integer>8</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>2028</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>2028</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>2028</integer>
+// CHECK-NEXT:          <key>col</key><integer>40</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>2028</integer>
+// CHECK-NEXT:          <key>col</key><integer>10</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>2028</integer>
+// CHECK-NEXT:          <key>col</key><integer>40</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>Object returned to caller with a +0 retain count</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Object returned to caller with a +0 retain count</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>2028</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>2028</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>2028</integer>
+// CHECK-NEXT:          <key>col</key><integer>40</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>Object was autoreleased but has a +0 retain count</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Object was autoreleased but has a +0 retain count</string>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:    </array>
+// CHECK-NEXT:    <key>description</key><string>Object autoreleased too many times</string>
+// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK-NEXT:    <key>type</key><string>Object autoreleased too many times</string>
+// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT:   <key>issue_context</key><string>getIncorrectlyAutoreleasedCFType</string>
 // CHECK-NEXT:   <key>issue_hash</key><string>2</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
-// CHECK-NEXT:    <key>line</key><integer>1938</integer>
+// CHECK-NEXT:    <key>line</key><integer>2028</integer>
+// CHECK-NEXT:    <key>col</key><integer>3</integer>
+// CHECK-NEXT:    <key>file</key><integer>0</integer>
+// CHECK-NEXT:   </dict>
+// CHECK-NEXT:   </dict>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>path</key>
+// CHECK-NEXT:    <array>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>control</string>
+// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:       <array>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>2033</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>2033</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>2033</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>2033</integer>
+// CHECK-NEXT:            <key>col</key><integer>40</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>2033</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>2033</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>2033</integer>
+// CHECK-NEXT:          <key>col</key><integer>42</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>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object 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:     </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>2033</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>2033</integer>
+// CHECK-NEXT:            <key>col</key><integer>40</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>2033</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>2033</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:     </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>2033</integer>
+// CHECK-NEXT:       <key>col</key><integer>10</integer>
+// CHECK-NEXT:       <key>file</key><integer>0</integer>
+// CHECK-NEXT:      </dict>
+// CHECK-NEXT:      <key>ranges</key>
+// CHECK-NEXT:      <array>
+// CHECK-NEXT:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>2033</integer>
+// CHECK-NEXT:          <key>col</key><integer>10</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>2033</integer>
+// CHECK-NEXT:          <key>col</key><integer>43</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>2033</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>2033</integer>
+// CHECK-NEXT:          <key>col</key><integer>42</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>Object autoreleased</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Object autoreleased</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>2033</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>2033</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>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>2033</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>2033</integer>
+// CHECK-NEXT:            <key>col</key><integer>8</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>2033</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>2033</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>2033</integer>
+// CHECK-NEXT:          <key>col</key><integer>43</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>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:    </array>
+// CHECK-NEXT:    <key>description</key><string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string>
+// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK-NEXT:    <key>type</key><string>Method should return an owned object</string>
+// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT:   <key>issue_context</key><string>createIncorrectlyAutoreleasedCFType</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>2</string>
+// CHECK-NEXT:   <key>location</key>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>line</key><integer>2033</integer>
+// CHECK-NEXT:    <key>col</key><integer>3</integer>
+// CHECK-NEXT:    <key>file</key><integer>0</integer>
+// CHECK-NEXT:   </dict>
+// CHECK-NEXT:   </dict>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>path</key>
+// CHECK-NEXT:    <array>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>2048</integer>
+// CHECK-NEXT:       <key>col</key><integer>19</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>2048</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>2048</integer>
+// CHECK-NEXT:          <key>col</key><integer>37</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>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object 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:     </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>2048</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>2048</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>2049</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>2049</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>2049</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>2049</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>2049</integer>
+// CHECK-NEXT:          <key>col</key><integer>16</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>2049</integer>
+// CHECK-NEXT:          <key>col</key><integer>13</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>2049</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>Object released</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Object released</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>2049</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>2049</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>2052</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>2052</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>2052</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>2052</integer>
+// CHECK-NEXT:          <key>col</key><integer>9</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>2052</integer>
+// CHECK-NEXT:          <key>col</key><integer>11</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Reference-counted object is used after it is released</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Reference-counted object is used after it is released</string>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:    </array>
+// CHECK-NEXT:    <key>description</key><string>Reference-counted object is used after it is released</string>
+// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK-NEXT:    <key>type</key><string>Use-after-release</string>
+// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT:   <key>issue_context</key><string>useAfterRelease</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>7</string>
+// CHECK-NEXT:   <key>location</key>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>line</key><integer>2052</integer>
+// CHECK-NEXT:    <key>col</key><integer>3</integer>
+// CHECK-NEXT:    <key>file</key><integer>0</integer>
+// CHECK-NEXT:   </dict>
+// CHECK-NEXT:   </dict>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>path</key>
+// CHECK-NEXT:    <array>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>2057</integer>
+// CHECK-NEXT:       <key>col</key><integer>19</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>2057</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>2057</integer>
+// CHECK-NEXT:          <key>col</key><integer>37</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>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object 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:     </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>2057</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>2057</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>2058</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>2058</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>2058</integer>
+// CHECK-NEXT:       <key>col</key><integer>22</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>2058</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>2058</integer>
+// CHECK-NEXT:          <key>col</key><integer>39</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>2058</integer>
+// CHECK-NEXT:          <key>col</key><integer>36</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>2058</integer>
+// CHECK-NEXT:          <key>col</key><integer>38</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>Object autoreleased</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Object autoreleased</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>2058</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>2058</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>2059</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>2059</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>2059</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>2059</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>2059</integer>
+// CHECK-NEXT:          <key>col</key><integer>18</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>2059</integer>
+// CHECK-NEXT:          <key>col</key><integer>12</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>2059</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:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Reference count incremented. The object now has a +2 retain count</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Reference count incremented. The object now has a +2 retain count</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>2059</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>2059</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>2060</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>2060</integer>
+// CHECK-NEXT:            <key>col</key><integer>1</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </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>2060</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>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;obj&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;obj&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:    </array>
+// CHECK-NEXT:    <key>description</key><string>Potential leak of an object stored into &apos;obj&apos;</string>
+// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK-NEXT:    <key>type</key><string>Leak</string>
+// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT:   <key>issue_context</key><string>testAutoreleaseReturnsInput</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>2</string>
+// CHECK-NEXT:   <key>location</key>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>line</key><integer>2060</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:   <dict>
+// CHECK-NEXT:    <key>path</key>
+// CHECK-NEXT:    <array>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>2077</integer>
+// CHECK-NEXT:       <key>col</key><integer>20</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>2077</integer>
+// CHECK-NEXT:          <key>col</key><integer>20</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>2077</integer>
+// CHECK-NEXT:          <key>col</key><integer>70</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>Call to function &apos;CFArrayCreateMutable&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Call to function &apos;CFArrayCreateMutable&apos; returns a Core Foundation object with a +1 retain count</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>2077</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>2077</integer>
+// CHECK-NEXT:            <key>col</key><integer>12</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>2078</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>2078</integer>
+// CHECK-NEXT:            <key>col</key><integer>12</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </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>2078</integer>
+// CHECK-NEXT:       <key>col</key><integer>34</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>2078</integer>
+// CHECK-NEXT:          <key>col</key><integer>34</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>2078</integer>
+// CHECK-NEXT:          <key>col</key><integer>62</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>2078</integer>
+// CHECK-NEXT:          <key>col</key><integer>48</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>2078</integer>
+// CHECK-NEXT:          <key>col</key><integer>61</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>Object autoreleased</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Object autoreleased</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>2078</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>2078</integer>
+// CHECK-NEXT:            <key>col</key><integer>12</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>2079</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>2079</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>2079</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>2079</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>2079</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:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>2079</integer>
+// CHECK-NEXT:          <key>col</key><integer>12</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>2079</integer>
+// CHECK-NEXT:          <key>col</key><integer>16</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Reference count incremented. The object now has a +2 retain count</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Reference count incremented. The object now has a +2 retain count</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>2079</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>2079</integer>
+// CHECK-NEXT:            <key>col</key><integer>10</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>2080</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>2080</integer>
+// CHECK-NEXT:            <key>col</key><integer>1</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </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>2080</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>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;arr&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Object leaked: object allocated and stored into &apos;arr&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:    </array>
+// CHECK-NEXT:    <key>description</key><string>Potential leak of an object stored into &apos;arr&apos;</string>
+// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK-NEXT:    <key>type</key><string>Leak</string>
+// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT:   <key>issue_context</key><string>autoreleaseReturningTypedObject</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>1</string>
+// CHECK-NEXT:   <key>location</key>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>line</key><integer>2080</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:   <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>2091</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>2091</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>2094</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>2094</integer>
+// CHECK-NEXT:            <key>col</key><integer>4</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>2094</integer>
+// CHECK-NEXT:       <key>col</key><integer>19</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>2094</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>2094</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:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>NSNumber literal is an object with a +0 retain count</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>NSNumber literal is an object with a +0 retain count</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>2094</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>2094</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>2095</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>2095</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>2095</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>2095</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>2095</integer>
+// CHECK-NEXT:          <key>col</key><integer>27</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>2095</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>2095</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:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Object autoreleased</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Object autoreleased</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>2095</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>2095</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>2096</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>2096</integer>
+// CHECK-NEXT:            <key>col</key><integer>1</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </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>2096</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>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Object was autoreleased but has a +0 retain count</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Object was autoreleased but has a +0 retain count</string>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:    </array>
+// CHECK-NEXT:    <key>description</key><string>Object autoreleased too many times</string>
+// CHECK-NEXT:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK-NEXT:    <key>type</key><string>Object autoreleased too many times</string>
+// CHECK-NEXT:   <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT:   <key>issue_context</key><string>autoreleaseObjC</string>
+// CHECK-NEXT:   <key>issue_hash</key><string>6</string>
+// CHECK-NEXT:   <key>location</key>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>line</key><integer>2096</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:  </array>
+// CHECK-NEXT: </dict>
+// CHECK-NEXT: </plist>
diff --git a/test/Analysis/stack-addr-ps.cpp b/test/Analysis/stack-addr-ps.cpp
index a39f9c7..a4ab2f3 100644
--- a/test/Analysis/stack-addr-ps.cpp
+++ b/test/Analysis/stack-addr-ps.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -verify %s -Wno-undefined-bool-conversion
 
 typedef __INTPTR_TYPE__ intptr_t;
 
diff --git a/test/Analysis/stackaddrleak.c b/test/Analysis/stackaddrleak.c
index 4f81f66..21a15d7 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 %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -x c++ %s
+// 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
 
 typedef __INTPTR_TYPE__ intptr_t;
 char const *p;
diff --git a/test/Analysis/superclass.m b/test/Analysis/superclass.m
index ba5ea40..d5d3c47 100644
--- a/test/Analysis/superclass.m
+++ b/test/Analysis/superclass.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fblocks -analyze -analyzer-checker=alpha.osx.cocoa.MissingSuperCall -verify -Wno-objc-root-class %s
+// RUN: %clang_cc1 -fblocks -analyze -analyzer-checker=osx.cocoa.MissingSuperCall -verify -Wno-objc-root-class %s
 
 // Define used Classes
 @protocol NSObject
diff --git a/test/Analysis/temp-obj-dtors-cfg-output.cpp b/test/Analysis/temp-obj-dtors-cfg-output.cpp
index ff68a87..5fb33d3 100644
--- a/test/Analysis/temp-obj-dtors-cfg-output.cpp
+++ b/test/Analysis/temp-obj-dtors-cfg-output.cpp
@@ -1,7 +1,6 @@
 // RUN: rm -f %t
 // RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -analyzer-config cfg-temporary-dtors=true %s > %t 2>&1
 // RUN: FileCheck --input-file=%t %s
-// XPASS: *
 
 class A {
 public:
@@ -52,6 +51,37 @@
   int b;
 }
 
+struct C {
+  C():b_(true) {}
+  ~C() {}
+
+  operator bool() { return b_; }
+  bool b_;
+};
+
+struct D {
+  D():b_(true) {}
+
+  operator bool() { return b_; }
+  bool b_;
+};
+
+int test_cond_unnamed_custom_destructor() {
+  if (C()) { return 1; } else { return 0; }
+}
+
+int test_cond_named_custom_destructor() {
+  if (C c = C()) { return 1; } else { return 0; }
+}
+
+int test_cond_unnamed_auto_destructor() {
+  if (D()) { return 1; } else { return 0; }
+}
+
+int test_cond_named_auto_destructor() {
+  if (D d = D()) { return 1; } else { return 0; }
+}
+
 void test_cond_cref() {
   const A& a = B() ? A() : A(B());
   foo(B() ? A() : A(B()));
@@ -126,6 +156,38 @@
   int b;
 }
 
+extern bool check(const NoReturn&);
+
+// PR16664 and PR18159
+int testConsistencyNestedSimple(bool value) {
+  if (value) {
+    if (!value || check(NoReturn())) {
+      return 1;
+    }
+  }
+  return 0;
+}
+
+// PR16664 and PR18159
+int testConsistencyNestedComplex(bool value) {
+  if (value) {
+    if (!value || !value || check(NoReturn())) {
+      return 1;
+    }
+  }
+  return 0;
+}
+
+// PR16664 and PR18159
+int testConsistencyNestedNormalReturn(bool value) {
+  if (value) {
+    if (!value || value || check(NoReturn())) {
+      return 1;
+    }
+  }
+  return 0;
+}
+
 // CHECK:   [B1 (ENTRY)]
 // CHECK:     Succs (1): B0
 // CHECK:   [B0 (EXIT)]
@@ -212,17 +274,17 @@
 // CHECK:     1: A() (CXXConstructExpr, class A)
 // CHECK:     2: [B1.1] (BindTemporary)
 // CHECK:     3: [B1.2].operator int
-// CHECK:     4: [B1.3]()
+// CHECK:     4: [B1.2]
 // CHECK:     5: [B1.4] (ImplicitCastExpr, UserDefinedConversion, int)
 // CHECK:     6: int([B1.5]) (CXXFunctionalCastExpr, NoOp, int)
 // CHECK:     7: B() (CXXConstructExpr, class B)
 // CHECK:     8: [B1.7] (BindTemporary)
 // CHECK:     9: [B1.8].operator int
-// CHECK:    10: [B1.9]()
+// CHECK:    10: [B1.8]
 // CHECK:    11: [B1.10] (ImplicitCastExpr, UserDefinedConversion, int)
 // CHECK:    12: int([B1.11]) (CXXFunctionalCastExpr, NoOp, int)
 // CHECK:    13: [B1.6] + [B1.12]
-// CHECK:    14: int a = int(A().operator int()) + int(B().operator int());
+// CHECK:    14: int a = int(A()) + int(B());
 // CHECK:    15: ~B() (Temporary object destructor)
 // CHECK:    16: ~A() (Temporary object destructor)
 // CHECK:    17: foo
@@ -230,13 +292,13 @@
 // CHECK:    19: A() (CXXConstructExpr, class A)
 // CHECK:    20: [B1.19] (BindTemporary)
 // CHECK:    21: [B1.20].operator int
-// CHECK:    22: [B1.21]()
+// CHECK:    22: [B1.20]
 // CHECK:    23: [B1.22] (ImplicitCastExpr, UserDefinedConversion, int)
 // CHECK:    24: int([B1.23]) (CXXFunctionalCastExpr, NoOp, int)
 // CHECK:    25: B() (CXXConstructExpr, class B)
 // CHECK:    26: [B1.25] (BindTemporary)
 // CHECK:    27: [B1.26].operator int
-// CHECK:    28: [B1.27]()
+// CHECK:    28: [B1.26]
 // CHECK:    29: [B1.28] (ImplicitCastExpr, UserDefinedConversion, int)
 // CHECK:    30: int([B1.29]) (CXXFunctionalCastExpr, NoOp, int)
 // CHECK:    31: [B1.24] + [B1.30]
@@ -262,14 +324,14 @@
 // CHECK:   [B3]
 // CHECK:     1: [B5.8] && [B4.5]
 // CHECK:     2: [B5.3]([B3.1])
-// CHECK:     T: [B5.8] && ...
+// CHECK:     T: (Temp Dtor) [B5.8] && ...
 // CHECK:     Preds (2): B4 B5
 // CHECK:     Succs (2): B2 B1
 // CHECK:   [B4]
 // CHECK:     1: B() (CXXConstructExpr, class B)
 // CHECK:     2: [B4.1] (BindTemporary)
-// CHECK:     3: [B4.2].operator _Bool
-// CHECK:     4: [B4.3]()
+// CHECK:     3: [B4.2].operator bool
+// CHECK:     4: [B4.2]
 // CHECK:     5: [B4.4] (ImplicitCastExpr, UserDefinedConversion, _Bool)
 // CHECK:     Preds (1): B5
 // CHECK:     Succs (1): B3
@@ -279,8 +341,8 @@
 // CHECK:     3: [B5.2] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(_Bool))
 // CHECK:     4: A() (CXXConstructExpr, class A)
 // CHECK:     5: [B5.4] (BindTemporary)
-// CHECK:     6: [B5.5].operator _Bool
-// CHECK:     7: [B5.6]()
+// CHECK:     6: [B5.5].operator bool
+// CHECK:     7: [B5.5]
 // CHECK:     8: [B5.7] (ImplicitCastExpr, UserDefinedConversion, _Bool)
 // CHECK:     T: [B5.8] && ...
 // CHECK:     Preds (2): B6 B7
@@ -291,23 +353,23 @@
 // CHECK:     Succs (1): B5
 // CHECK:   [B7]
 // CHECK:     1: [B9.5] && [B8.5]
-// CHECK:     2: bool a = A().operator _Bool() && B().operator _Bool();
-// CHECK:     T: [B9.5] && ...
+// CHECK:     2: bool a = A() && B();
+// CHECK:     T: (Temp Dtor) [B9.5] && ...
 // CHECK:     Preds (2): B8 B9
 // CHECK:     Succs (2): B6 B5
 // CHECK:   [B8]
 // CHECK:     1: B() (CXXConstructExpr, class B)
 // CHECK:     2: [B8.1] (BindTemporary)
-// CHECK:     3: [B8.2].operator _Bool
-// CHECK:     4: [B8.3]()
+// CHECK:     3: [B8.2].operator bool
+// CHECK:     4: [B8.2]
 // CHECK:     5: [B8.4] (ImplicitCastExpr, UserDefinedConversion, _Bool)
 // CHECK:     Preds (1): B9
 // CHECK:     Succs (1): B7
 // CHECK:   [B9]
 // CHECK:     1: A() (CXXConstructExpr, class A)
 // CHECK:     2: [B9.1] (BindTemporary)
-// CHECK:     3: [B9.2].operator _Bool
-// CHECK:     4: [B9.3]()
+// CHECK:     3: [B9.2].operator bool
+// CHECK:     4: [B9.2]
 // CHECK:     5: [B9.4] (ImplicitCastExpr, UserDefinedConversion, _Bool)
 // CHECK:     T: [B9.5] && ...
 // CHECK:     Preds (1): B10
@@ -328,14 +390,14 @@
 // CHECK:   [B3]
 // CHECK:     1: [B5.8] || [B4.5]
 // CHECK:     2: [B5.3]([B3.1])
-// CHECK:     T: [B5.8] || ...
+// CHECK:     T: (Temp Dtor) [B5.8] || ...
 // CHECK:     Preds (2): B4 B5
 // CHECK:     Succs (2): B1 B2
 // CHECK:   [B4]
 // CHECK:     1: B() (CXXConstructExpr, class B)
 // CHECK:     2: [B4.1] (BindTemporary)
-// CHECK:     3: [B4.2].operator _Bool
-// CHECK:     4: [B4.3]()
+// CHECK:     3: [B4.2].operator bool
+// CHECK:     4: [B4.2]
 // CHECK:     5: [B4.4] (ImplicitCastExpr, UserDefinedConversion, _Bool)
 // CHECK:     Preds (1): B5
 // CHECK:     Succs (1): B3
@@ -345,8 +407,8 @@
 // CHECK:     3: [B5.2] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(_Bool))
 // CHECK:     4: A() (CXXConstructExpr, class A)
 // CHECK:     5: [B5.4] (BindTemporary)
-// CHECK:     6: [B5.5].operator _Bool
-// CHECK:     7: [B5.6]()
+// CHECK:     6: [B5.5].operator bool
+// CHECK:     7: [B5.5]
 // CHECK:     8: [B5.7] (ImplicitCastExpr, UserDefinedConversion, _Bool)
 // CHECK:     T: [B5.8] || ...
 // CHECK:     Preds (2): B6 B7
@@ -357,23 +419,23 @@
 // CHECK:     Succs (1): B5
 // CHECK:   [B7]
 // CHECK:     1: [B9.5] || [B8.5]
-// CHECK:     2: bool a = A().operator _Bool() || B().operator _Bool();
-// CHECK:     T: [B9.5] || ...
+// CHECK:     2: bool a = A() || B();
+// CHECK:     T: (Temp Dtor) [B9.5] || ...
 // CHECK:     Preds (2): B8 B9
 // CHECK:     Succs (2): B5 B6
 // CHECK:   [B8]
 // CHECK:     1: B() (CXXConstructExpr, class B)
 // CHECK:     2: [B8.1] (BindTemporary)
-// CHECK:     3: [B8.2].operator _Bool
-// CHECK:     4: [B8.3]()
+// CHECK:     3: [B8.2].operator bool
+// CHECK:     4: [B8.2]
 // CHECK:     5: [B8.4] (ImplicitCastExpr, UserDefinedConversion, _Bool)
 // CHECK:     Preds (1): B9
 // CHECK:     Succs (1): B7
 // CHECK:   [B9]
 // CHECK:     1: A() (CXXConstructExpr, class A)
 // CHECK:     2: [B9.1] (BindTemporary)
-// CHECK:     3: [B9.2].operator _Bool
-// CHECK:     4: [B9.3]()
+// CHECK:     3: [B9.2].operator bool
+// CHECK:     4: [B9.2]
 // CHECK:     5: [B9.4] (ImplicitCastExpr, UserDefinedConversion, _Bool)
 // CHECK:     T: [B9.5] || ...
 // CHECK:     Preds (1): B10
@@ -405,8 +467,8 @@
 // CHECK:     1: ~B() (Temporary object destructor)
 // CHECK:     2: B() (CXXConstructExpr, class B)
 // CHECK:     3: [B4.2] (BindTemporary)
-// CHECK:     4: [B4.3].operator _Bool
-// CHECK:     5: [B4.4]()
+// CHECK:     4: [B4.3].operator bool
+// CHECK:     5: [B4.3]
 // CHECK:     6: [B4.5] (ImplicitCastExpr, UserDefinedConversion, _Bool)
 // CHECK:     7: ~B() (Temporary object destructor)
 // CHECK:     T: if [B4.6]
@@ -429,8 +491,8 @@
 // CHECK:     2: [B7.1] (ImplicitCastExpr, NoOp, const class A)
 // CHECK:     3: [B7.2]
 // CHECK:     4: [B7.3] (CXXConstructExpr, class A)
-// CHECK:     5: A a = B().operator _Bool() ? A() : A(B().operator A());
-// CHECK:     T: [B10.5] ? ... : ...
+// CHECK:     5: A a = B() ? A() : A(B());
+// CHECK:     T: (Temp Dtor) [B10.5] ? ... : ...
 // CHECK:     Preds (2): B8 B9
 // CHECK:     Succs (2): B5 B6
 // CHECK:   [B8]
@@ -446,7 +508,7 @@
 // CHECK:     1: B() (CXXConstructExpr, class B)
 // CHECK:     2: [B9.1] (BindTemporary)
 // CHECK:     3: [B9.2].operator A
-// CHECK:     4: [B9.3]()
+// CHECK:     4: [B9.2]
 // CHECK:     5: [B9.4] (ImplicitCastExpr, UserDefinedConversion, class A)
 // CHECK:     6: [B9.5] (BindTemporary)
 // CHECK:     7: [B9.6] (ImplicitCastExpr, NoOp, const class A)
@@ -463,14 +525,174 @@
 // CHECK:   [B10]
 // CHECK:     1: B() (CXXConstructExpr, class B)
 // CHECK:     2: [B10.1] (BindTemporary)
-// CHECK:     3: [B10.2].operator _Bool
-// CHECK:     4: [B10.3]()
+// CHECK:     3: [B10.2].operator bool
+// CHECK:     4: [B10.2]
 // CHECK:     5: [B10.4] (ImplicitCastExpr, UserDefinedConversion, _Bool)
 // CHECK:     T: [B10.5] ? ... : ...
 // CHECK:     Preds (1): B11
 // CHECK:     Succs (2): B8 B9
 // CHECK:   [B0 (EXIT)]
 // CHECK:     Preds (1): B1
+// CHECK:  C() : b_(true)
+// CHECK:   [B2 (ENTRY)]
+// CHECK:     Succs (1): B1
+// CHECK:   [B1]
+// CHECK:     1: true
+// CHECK:     2: b_([B1.1]) (Member initializer)
+// CHECK:     Preds (1): B2
+// CHECK:     Succs (1): B0
+// CHECK:   [B0 (EXIT)]
+// CHECK:     Preds (1): B1
+// CHECK:  ~C()
+// CHECK:   [B1 (ENTRY)]
+// CHECK:     Succs (1): B0
+// CHECK:   [B0 (EXIT)]
+// CHECK:     Preds (1): B1
+// CHECK:  operator bool()
+// CHECK:   [B2 (ENTRY)]
+// CHECK:     Succs (1): B1
+// CHECK:   [B1]
+// CHECK:     1: this
+// CHECK:     2: [B1.1]->b_
+// CHECK:     3: [B1.2] (ImplicitCastExpr, LValueToRValue, _Bool)
+// CHECK:     4: return [B1.3];
+// CHECK:     Preds (1): B2
+// CHECK:     Succs (1): B0
+// CHECK:   [B0 (EXIT)]
+// CHECK:     Preds (1): B1
+// CHECK:  D() : b_(true)
+// CHECK:   [B2 (ENTRY)]
+// CHECK:     Succs (1): B1
+// CHECK:   [B1]
+// CHECK:     1: true
+// CHECK:     2: b_([B1.1]) (Member initializer)
+// CHECK:     Preds (1): B2
+// CHECK:     Succs (1): B0
+// CHECK:   [B0 (EXIT)]
+// CHECK:     Preds (1): B1
+// CHECK:  operator bool()
+// CHECK:   [B2 (ENTRY)]
+// CHECK:     Succs (1): B1
+// CHECK:   [B1]
+// CHECK:     1: this
+// CHECK:     2: [B1.1]->b_
+// CHECK:     3: [B1.2] (ImplicitCastExpr, LValueToRValue, _Bool)
+// CHECK:     4: return [B1.3];
+// CHECK:     Preds (1): B2
+// CHECK:     Succs (1): B0
+// CHECK:   [B0 (EXIT)]
+// CHECK:     Preds (1): B1
+// CHECK:  int test_cond_unnamed_custom_destructor()
+// CHECK:   [B4 (ENTRY)]
+// CHECK:     Succs (1): B3
+// CHECK:   [B1]
+// CHECK:     1: 0
+// CHECK:     2: return [B1.1];
+// CHECK:     Preds (1): B3
+// CHECK:     Succs (1): B0
+// CHECK:   [B2]
+// CHECK:     1: 1
+// CHECK:     2: return [B2.1];
+// CHECK:     Preds (1): B3
+// CHECK:     Succs (1): B0
+// CHECK:   [B3]
+// CHECK:     1: C() (CXXConstructExpr, struct C)
+// CHECK:     2: [B3.1] (BindTemporary)
+// CHECK:     3: [B3.2].operator bool
+// CHECK:     4: [B3.2]
+// CHECK:     5: [B3.4] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CHECK:     6: ~C() (Temporary object destructor)
+// CHECK:     T: if [B3.5]
+// CHECK:     Preds (1): B4
+// CHECK:     Succs (2): B2 B1
+// CHECK:   [B0 (EXIT)]
+// CHECK:     Preds (2): B1 B2
+// CHECK:  int test_cond_named_custom_destructor()
+// CHECK:   [B5 (ENTRY)]
+// CHECK:     Succs (1): B4
+// CHECK:   [B1]
+// CHECK:     1: [B4.6].~C() (Implicit destructor)
+// CHECK:     Succs (1): B0
+// CHECK:   [B2]
+// CHECK:     1: 0
+// CHECK:     2: return [B2.1];
+// CHECK:     3: [B4.6].~C() (Implicit destructor)
+// CHECK:     Preds (1): B4
+// CHECK:     Succs (1): B0
+// CHECK:   [B3]
+// CHECK:     1: 1
+// CHECK:     2: return [B3.1];
+// CHECK:     3: [B4.6].~C() (Implicit destructor)
+// CHECK:     Preds (1): B4
+// CHECK:     Succs (1): B0
+// CHECK:   [B4]
+// CHECK:     1: C() (CXXConstructExpr, struct C)
+// CHECK:     2: [B4.1] (BindTemporary)
+// CHECK:     3: [B4.2] (ImplicitCastExpr, NoOp, const struct C)
+// CHECK:     4: [B4.3]
+// CHECK:     5: [B4.4] (CXXConstructExpr, struct C)
+// CHECK:     6: C c = C();
+// CHECK:     7: ~C() (Temporary object destructor)
+// CHECK:     8: c
+// CHECK:     9: [B4.8].operator bool
+// CHECK:    10: [B4.8]
+// CHECK:    11: [B4.10] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CHECK:     T: if [B4.11]
+// CHECK:     Preds (1): B5
+// CHECK:     Succs (2): B3 B2
+// CHECK:   [B0 (EXIT)]
+// CHECK:     Preds (3): B1 B2 B3
+// CHECK:  int test_cond_unnamed_auto_destructor()
+// CHECK:   [B4 (ENTRY)]
+// CHECK:     Succs (1): B3
+// CHECK:   [B1]
+// CHECK:     1: 0
+// CHECK:     2: return [B1.1];
+// CHECK:     Preds (1): B3
+// CHECK:     Succs (1): B0
+// CHECK:   [B2]
+// CHECK:     1: 1
+// CHECK:     2: return [B2.1];
+// CHECK:     Preds (1): B3
+// CHECK:     Succs (1): B0
+// CHECK:   [B3]
+// CHECK:     1: D() (CXXConstructExpr, struct D)
+// CHECK:     2: [B3.1].operator bool
+// CHECK:     3: [B3.1]
+// CHECK:     4: [B3.3] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CHECK:     T: if [B3.4]
+// CHECK:     Preds (1): B4
+// CHECK:     Succs (2): B2 B1
+// CHECK:   [B0 (EXIT)]
+// CHECK:     Preds (2): B1 B2
+// CHECK:  int test_cond_named_auto_destructor()
+// CHECK:   [B4 (ENTRY)]
+// CHECK:     Succs (1): B3
+// CHECK:   [B1]
+// CHECK:     1: 0
+// CHECK:     2: return [B1.1];
+// CHECK:     Preds (1): B3
+// CHECK:     Succs (1): B0
+// CHECK:   [B2]
+// CHECK:     1: 1
+// CHECK:     2: return [B2.1];
+// CHECK:     Preds (1): B3
+// CHECK:     Succs (1): B0
+// CHECK:   [B3]
+// CHECK:     1: D() (CXXConstructExpr, struct D)
+// CHECK:     2: [B3.1] (ImplicitCastExpr, NoOp, const struct D)
+// CHECK:     3: [B3.2]
+// CHECK:     4: [B3.3] (CXXConstructExpr, struct D)
+// CHECK:     5: D d = D();
+// CHECK:     6: d
+// CHECK:     7: [B3.6].operator bool
+// CHECK:     8: [B3.6]
+// CHECK:     9: [B3.8] (ImplicitCastExpr, UserDefinedConversion, _Bool)
+// CHECK:     T: if [B3.9]
+// CHECK:     Preds (1): B4
+// CHECK:     Succs (2): B2 B1
+// CHECK:   [B0 (EXIT)]
+// CHECK:     Preds (2): B1 B2
 // CHECK:   [B14 (ENTRY)]
 // CHECK:     Succs (1): B13
 // CHECK:   [B1]
@@ -496,7 +718,7 @@
 // CHECK:     2: [B4.1] (ImplicitCastExpr, NoOp, const class A)
 // CHECK:     3: [B4.2]
 // CHECK:     4: [B7.3]([B4.3])
-// CHECK:     T: [B7.8] ? ... : ...
+// CHECK:     T: (Temp Dtor) [B7.8] ? ... : ...
 // CHECK:     Preds (2): B5 B6
 // CHECK:     Succs (2): B2 B3
 // CHECK:   [B5]
@@ -512,7 +734,7 @@
 // CHECK:     1: B() (CXXConstructExpr, class B)
 // CHECK:     2: [B6.1] (BindTemporary)
 // CHECK:     3: [B6.2].operator A
-// CHECK:     4: [B6.3]()
+// CHECK:     4: [B6.2]
 // CHECK:     5: [B6.4] (ImplicitCastExpr, UserDefinedConversion, class A)
 // CHECK:     6: [B6.5] (BindTemporary)
 // CHECK:     7: [B6.6] (ImplicitCastExpr, NoOp, const class A)
@@ -532,8 +754,8 @@
 // CHECK:     3: [B7.2] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(const class A &))
 // CHECK:     4: B() (CXXConstructExpr, class B)
 // CHECK:     5: [B7.4] (BindTemporary)
-// CHECK:     6: [B7.5].operator _Bool
-// CHECK:     7: [B7.6]()
+// CHECK:     6: [B7.5].operator bool
+// CHECK:     7: [B7.5]
 // CHECK:     8: [B7.7] (ImplicitCastExpr, UserDefinedConversion, _Bool)
 // CHECK:     T: [B7.8] ? ... : ...
 // CHECK:     Preds (2): B8 B9
@@ -552,8 +774,8 @@
 // CHECK:     1: [B13.5] ? [B11.6] : [B12.15]
 // CHECK:     2: [B10.1] (ImplicitCastExpr, NoOp, const class A)
 // CHECK:     3: [B10.2]
-// CHECK:     4: const A &a = B().operator _Bool() ? A() : A(B().operator A());
-// CHECK:     T: [B13.5] ? ... : ...
+// CHECK:     4: const A &a = B() ? A() : A(B());
+// CHECK:     T: (Temp Dtor) [B13.5] ? ... : ...
 // CHECK:     Preds (2): B11 B12
 // CHECK:     Succs (2): B8 B9
 // CHECK:   [B11]
@@ -569,7 +791,7 @@
 // CHECK:     1: B() (CXXConstructExpr, class B)
 // CHECK:     2: [B12.1] (BindTemporary)
 // CHECK:     3: [B12.2].operator A
-// CHECK:     4: [B12.3]()
+// CHECK:     4: [B12.2]
 // CHECK:     5: [B12.4] (ImplicitCastExpr, UserDefinedConversion, class A)
 // CHECK:     6: [B12.5] (BindTemporary)
 // CHECK:     7: [B12.6] (ImplicitCastExpr, NoOp, const class A)
@@ -586,8 +808,8 @@
 // CHECK:   [B13]
 // CHECK:     1: B() (CXXConstructExpr, class B)
 // CHECK:     2: [B13.1] (BindTemporary)
-// CHECK:     3: [B13.2].operator _Bool
-// CHECK:     4: [B13.3]()
+// CHECK:     3: [B13.2].operator bool
+// CHECK:     4: [B13.2]
 // CHECK:     5: [B13.4] (ImplicitCastExpr, UserDefinedConversion, _Bool)
 // CHECK:     T: [B13.5] ? ... : ...
 // CHECK:     Preds (1): B14
@@ -617,7 +839,7 @@
 // CHECK:     3: [B4.2]
 // CHECK:     4: [B4.3] (CXXConstructExpr, class A)
 // CHECK:     5: A a = A() ?: A();
-// CHECK:     T: [B7.5] ? ... : ...
+// CHECK:     T: (Temp Dtor) [B7.5] ? ... : ...
 // CHECK:     Preds (2): B5 B6
 // CHECK:     Succs (2): B2 B3
 // CHECK:   [B5]
@@ -639,8 +861,8 @@
 // CHECK:   [B7]
 // CHECK:     1: A() (CXXConstructExpr, class A)
 // CHECK:     2: [B7.1] (BindTemporary)
-// CHECK:     3: [B7.2].operator _Bool
-// CHECK:     4: [B7.3]()
+// CHECK:     3: [B7.2].operator bool
+// CHECK:     4: [B7.2]
 // CHECK:     5: [B7.4] (ImplicitCastExpr, UserDefinedConversion, _Bool)
 // CHECK:     T: [B7.5] ? ... : ...
 // CHECK:     Preds (1): B8
@@ -669,7 +891,7 @@
 // CHECK:     2: [B4.1] (ImplicitCastExpr, NoOp, const class A)
 // CHECK:     3: [B4.2]
 // CHECK:     4: [B7.3]([B4.3])
-// CHECK:     T: [B7.8] ? ... : ...
+// CHECK:     T: (Temp Dtor) [B7.8] ? ... : ...
 // CHECK:     Preds (2): B5 B6
 // CHECK:     Succs (2): B2 B3
 // CHECK:   [B5]
@@ -694,8 +916,8 @@
 // CHECK:     3: [B7.2] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(const class A &))
 // CHECK:     4: A() (CXXConstructExpr, class A)
 // CHECK:     5: [B7.4] (BindTemporary)
-// CHECK:     6: [B7.5].operator _Bool
-// CHECK:     7: [B7.6]()
+// CHECK:     6: [B7.5].operator bool
+// CHECK:     7: [B7.5]
 // CHECK:     8: [B7.7] (ImplicitCastExpr, UserDefinedConversion, _Bool)
 // CHECK:     T: [B7.8] ? ... : ...
 // CHECK:     Preds (2): B9 B8
@@ -709,7 +931,7 @@
 // CHECK:     2: [B9.1] (ImplicitCastExpr, NoOp, const class A)
 // CHECK:     3: [B9.2]
 // CHECK:     4: const A &a = A() ?: A();
-// CHECK:     T: [B12.5] ? ... : ...
+// CHECK:     T: (Temp Dtor) [B12.5] ? ... : ...
 // CHECK:     Preds (2): B10 B11
 // CHECK:     Succs (2): B7 B8
 // CHECK:   [B10]
@@ -731,8 +953,8 @@
 // CHECK:   [B12]
 // CHECK:     1: A() (CXXConstructExpr, class A)
 // CHECK:     2: [B12.1] (BindTemporary)
-// CHECK:     3: [B12.2].operator _Bool
-// CHECK:     4: [B12.3]()
+// CHECK:     3: [B12.2].operator bool
+// CHECK:     4: [B12.2]
 // CHECK:     5: [B12.4] (ImplicitCastExpr, UserDefinedConversion, _Bool)
 // CHECK:     T: [B12.5] ? ... : ...
 // CHECK:     Preds (1): B13
@@ -828,7 +1050,7 @@
 // CHECK:     2: A() (CXXConstructExpr, class A)
 // CHECK:     3: [B1.2] (BindTemporary)
 // CHECK:     4: [B1.3].operator int
-// CHECK:     5: [B1.4]()
+// CHECK:     5: [B1.3]
 // CHECK:     6: [B1.5] (ImplicitCastExpr, UserDefinedConversion, int)
 // CHECK:     7: a
 // CHECK:     8: [B1.7] = [B1.6]
@@ -844,13 +1066,13 @@
 // CHECK:     1: A() (CXXConstructExpr, class A)
 // CHECK:     2: [B1.1] (BindTemporary)
 // CHECK:     3: [B1.2].operator int
-// CHECK:     4: [B1.3]()
+// CHECK:     4: [B1.2]
 // CHECK:     5: [B1.4] (ImplicitCastExpr, UserDefinedConversion, int)
 // CHECK:     6: int([B1.5]) (CXXFunctionalCastExpr, NoOp, int)
 // CHECK:     7: B() (CXXConstructExpr, class B)
 // CHECK:     8: [B1.7] (BindTemporary)
 // CHECK:     9: [B1.8].operator int
-// CHECK:    10: [B1.9]()
+// CHECK:    10: [B1.8]
 // CHECK:    11: [B1.10] (ImplicitCastExpr, UserDefinedConversion, int)
 // CHECK:    12: int([B1.11]) (CXXFunctionalCastExpr, NoOp, int)
 // CHECK:    13: [B1.6] + [B1.12]
@@ -863,13 +1085,12 @@
 // CHECK:     Succs (1): B0
 // CHECK:   [B0 (EXIT)]
 // CHECK:     Preds (1): B1
-
 // CHECK:   [B3 (ENTRY)]
 // CHECK:     Succs (1): B2
 // CHECK:   [B1]
 // CHECK:     1: int b;
 // CHECK:     Succs (1): B0
-// CHECK:   [B2]
+// CHECK:   [B2 (NORETURN)]
 // CHECK:     1: int a;
 // CHECK:     2: NoReturn() (CXXConstructExpr, class NoReturn)
 // CHECK:     3: [B2.2] (BindTemporary)
@@ -880,13 +1101,12 @@
 // CHECK:     Succs (1): B0
 // CHECK:   [B0 (EXIT)]
 // CHECK:     Preds (2): B1 B2
-
 // CHECK:   [B3 (ENTRY)]
 // CHECK:     Succs (1): B2
 // CHECK:   [B1]
 // CHECK:     1: int b;
 // CHECK:     Succs (1): B0
-// CHECK:   [B2]
+// CHECK:   [B2 (NORETURN)]
 // CHECK:     1: int a;
 // CHECK:     2: NoReturn() (CXXConstructExpr, class NoReturn)
 // CHECK:     3: [B2.2] (BindTemporary)
@@ -897,3 +1117,169 @@
 // CHECK:     Succs (1): B0
 // CHECK:   [B0 (EXIT)]
 // CHECK:     Preds (2): B1 B2
+// CHECK:  int testConsistencyNestedSimple(bool value)
+// CHECK:   [B9 (ENTRY)]
+// CHECK:     Succs (1): B8
+// CHECK:   [B1]
+// CHECK:     1: 0
+// CHECK:     2: return [B1.1];
+// CHECK:     Preds (2): B3 B8
+// CHECK:     Succs (1): B0
+// CHECK:   [B2]
+// CHECK:     1: 1
+// CHECK:     2: return [B2.1];
+// CHECK:     Preds (1): B3
+// CHECK:     Succs (1): B0
+// CHECK:   [B3]
+// CHECK:     T: if [B5.1]
+// CHECK:     Preds (1): B5
+// CHECK:     Succs (2): B2 B1
+// CHECK:   [B4 (NORETURN)]
+// CHECK:     1: ~NoReturn() (Temporary object destructor)
+// CHECK:     Preds (1): B5
+// CHECK:     Succs (1): B0
+// CHECK:   [B5]
+// CHECK:     1: [B7.3] || [B6.7]
+// CHECK:     T: (Temp Dtor) [B7.3] || ...
+// CHECK:     Preds (2): B6 B7
+// CHECK:     Succs (2): B3 B4
+// CHECK:   [B6]
+// CHECK:     1: check
+// CHECK:     2: [B6.1] (ImplicitCastExpr, FunctionToPointerDecay, _Bool (*)(const class NoReturn &))
+// CHECK:     3: NoReturn() (CXXConstructExpr, class NoReturn)
+// CHECK:     4: [B6.3] (BindTemporary)
+// CHECK:     5: [B6.4] (ImplicitCastExpr, NoOp, const class NoReturn)
+// CHECK:     6: [B6.5]
+// CHECK:     7: [B6.2]([B6.6])
+// CHECK:     Preds (1): B7
+// CHECK:     Succs (1): B5
+// CHECK:   [B7]
+// CHECK:     1: value
+// CHECK:     2: [B7.1] (ImplicitCastExpr, LValueToRValue, _Bool)
+// CHECK:     3: ![B7.2]
+// CHECK:     T: [B7.3] || ...
+// CHECK:     Preds (1): B8
+// CHECK:     Succs (2): B5 B6
+// CHECK:   [B8]
+// CHECK:     1: value
+// CHECK:     2: [B8.1] (ImplicitCastExpr, LValueToRValue, _Bool)
+// CHECK:     T: if [B8.2]
+// CHECK:     Preds (1): B9
+// CHECK:     Succs (2): B7 B1
+// CHECK:   [B0 (EXIT)]
+// CHECK:     Preds (3): B1 B2 B4
+// CHECK:  int testConsistencyNestedComplex(bool value)
+// CHECK:   [B10 (ENTRY)]
+// CHECK:     Succs (1): B9
+// CHECK:   [B1]
+// CHECK:     1: 0
+// CHECK:     2: return [B1.1];
+// CHECK:     Preds (2): B3 B9
+// CHECK:     Succs (1): B0
+// CHECK:   [B2]
+// CHECK:     1: 1
+// CHECK:     2: return [B2.1];
+// CHECK:     Preds (1): B3
+// CHECK:     Succs (1): B0
+// CHECK:   [B3]
+// CHECK:     T: if [B5.1]
+// CHECK:     Preds (1): B5
+// CHECK:     Succs (2): B2 B1
+// CHECK:   [B4 (NORETURN)]
+// CHECK:     1: ~NoReturn() (Temporary object destructor)
+// CHECK:     Preds (1): B5
+// CHECK:     Succs (1): B0
+// CHECK:   [B5]
+// CHECK:     1: [B8.3] || [B7.3] || [B6.7]
+// CHECK:     T: (Temp Dtor) [B8.3] || [B7.3] || ...
+// CHECK:     Preds (3): B6 B7 B8
+// CHECK:     Succs (2): B3 B4
+// CHECK:   [B6]
+// CHECK:     1: check
+// CHECK:     2: [B6.1] (ImplicitCastExpr, FunctionToPointerDecay, _Bool (*)(const class NoReturn &))
+// CHECK:     3: NoReturn() (CXXConstructExpr, class NoReturn)
+// CHECK:     4: [B6.3] (BindTemporary)
+// CHECK:     5: [B6.4] (ImplicitCastExpr, NoOp, const class NoReturn)
+// CHECK:     6: [B6.5]
+// CHECK:     7: [B6.2]([B6.6])
+// CHECK:     Preds (1): B7
+// CHECK:     Succs (1): B5
+// CHECK:   [B7]
+// CHECK:     1: value
+// CHECK:     2: [B7.1] (ImplicitCastExpr, LValueToRValue, _Bool)
+// CHECK:     3: ![B7.2]
+// CHECK:     T: [B8.3] || [B7.3] || ...
+// CHECK:     Preds (1): B8
+// CHECK:     Succs (2): B5 B6
+// CHECK:   [B8]
+// CHECK:     1: value
+// CHECK:     2: [B8.1] (ImplicitCastExpr, LValueToRValue, _Bool)
+// CHECK:     3: ![B8.2]
+// CHECK:     T: [B8.3] || ...
+// CHECK:     Preds (1): B9
+// CHECK:     Succs (2): B5 B7
+// CHECK:   [B9]
+// CHECK:     1: value
+// CHECK:     2: [B9.1] (ImplicitCastExpr, LValueToRValue, _Bool)
+// CHECK:     T: if [B9.2]
+// CHECK:     Preds (1): B10
+// CHECK:     Succs (2): B8 B1
+// CHECK:   [B0 (EXIT)]
+// CHECK:     Preds (3): B1 B2 B4
+// CHECK:  int testConsistencyNestedNormalReturn(bool value)
+// CHECK:   [B10 (ENTRY)]
+// CHECK:     Succs (1): B9
+// CHECK:   [B1]
+// CHECK:     1: 0
+// CHECK:     2: return [B1.1];
+// CHECK:     Preds (2): B3 B9
+// CHECK:     Succs (1): B0
+// CHECK:   [B2]
+// CHECK:     1: 1
+// CHECK:     2: return [B2.1];
+// CHECK:     Preds (1): B3
+// CHECK:     Succs (1): B0
+// CHECK:   [B3]
+// CHECK:     T: if [B5.1]
+// CHECK:     Preds (1): B5
+// CHECK:     Succs (2): B2 B1
+// CHECK:   [B4 (NORETURN)]
+// CHECK:     1: ~NoReturn() (Temporary object destructor)
+// CHECK:     Preds (1): B5
+// CHECK:     Succs (1): B0
+// CHECK:   [B5]
+// CHECK:     1: [B8.3] || [B7.2] || [B6.7]
+// CHECK:     T: (Temp Dtor) [B8.3] || [B7.2] || ...
+// CHECK:     Preds (3): B6 B7 B8
+// CHECK:     Succs (2): B3 B4
+// CHECK:   [B6]
+// CHECK:     1: check
+// CHECK:     2: [B6.1] (ImplicitCastExpr, FunctionToPointerDecay, _Bool (*)(const class NoReturn &))
+// CHECK:     3: NoReturn() (CXXConstructExpr, class NoReturn)
+// CHECK:     4: [B6.3] (BindTemporary)
+// CHECK:     5: [B6.4] (ImplicitCastExpr, NoOp, const class NoReturn)
+// CHECK:     6: [B6.5]
+// CHECK:     7: [B6.2]([B6.6])
+// CHECK:     Preds (1): B7
+// CHECK:     Succs (1): B5
+// CHECK:   [B7]
+// CHECK:     1: value
+// CHECK:     2: [B7.1] (ImplicitCastExpr, LValueToRValue, _Bool)
+// CHECK:     T: [B8.3] || [B7.2] || ...
+// CHECK:     Preds (1): B8
+// CHECK:     Succs (2): B5 B6
+// CHECK:   [B8]
+// CHECK:     1: value
+// CHECK:     2: [B8.1] (ImplicitCastExpr, LValueToRValue, _Bool)
+// CHECK:     3: ![B8.2]
+// CHECK:     T: [B8.3] || ...
+// CHECK:     Preds (1): B9
+// CHECK:     Succs (2): B5 B7
+// CHECK:   [B9]
+// CHECK:     1: value
+// CHECK:     2: [B9.1] (ImplicitCastExpr, LValueToRValue, _Bool)
+// CHECK:     T: if [B9.2]
+// CHECK:     Preds (1): B10
+// CHECK:     Succs (2): B8 B1
+// CHECK:   [B0 (EXIT)]
+// CHECK:     Preds (3): B1 B2 B4
diff --git a/test/Analysis/temporaries.cpp b/test/Analysis/temporaries.cpp
index d5237e5..c57d984 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 -verify -w -analyzer-config cfg-temporary-dtors=true %s -DTEMPORARY_DTORS
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -DTEMPORARY_DTORS -verify -w -analyzer-config cfg-temporary-dtors=true %s 
 
 extern bool clang_analyzer_eval(bool);
 
@@ -111,14 +111,15 @@
 }
 
 namespace destructors {
-  void testPR16664Crash() {
+  void testPR16664andPR18159Crash() {
     struct Dtor {
       ~Dtor();
     };
     extern bool coin();
     extern bool check(const Dtor &);
 
-    // Don't crash here.
+    // Regression test: we used to assert here when tmp dtors are enabled.
+    // PR16664 and PR18159
     if (coin() && (coin() || coin() || check(Dtor()))) {
       Dtor();
     }
@@ -147,9 +148,6 @@
   extern bool check(const NoReturnDtor &);
 
   void testConsistencyIf(int i) {
-    if (i == 5 && (i == 4 || i == 5 || check(NoReturnDtor())))
-      clang_analyzer_eval(true); // expected-warning{{TRUE}}
-
     if (i != 5)
       return;
     if (i == 5 && (i == 4 || check(NoReturnDtor()) || i == 5)) {
@@ -170,12 +168,17 @@
     clang_analyzer_eval(true); // no warning, unreachable code
   }
 
+  // Regression test: we used to assert here.
+  // PR16664 and PR18159
   void testConsistencyNested(int i) {
     extern bool compute(bool);
 
     if (i == 5 && (i == 4 || i == 5 || check(NoReturnDtor())))
       clang_analyzer_eval(true);  // expected-warning{{TRUE}}
 
+    if (i == 5 && (i == 4 || i == 5 || check(NoReturnDtor())))
+      clang_analyzer_eval(true);  // expected-warning{{TRUE}}
+
     if (i != 5)
       return;
 
@@ -183,16 +186,54 @@
                 (i == 4 || compute(true) ||
                  compute(i == 5 && (i == 4 || check(NoReturnDtor()))))) ||
         i != 4) {
-      clang_analyzer_eval(true); // expected-warning{{TRUE}}
+      clang_analyzer_eval(true);  // expected-warning{{TRUE}}
     }
 
     if (compute(i == 5 &&
                 (i == 4 || i == 4 ||
                  compute(i == 5 && (i == 4 || check(NoReturnDtor()))))) ||
         i != 4) {
-      clang_analyzer_eval(true); // no warning, unreachable code
+      // FIXME: This shouldn't cause a warning.
+      clang_analyzer_eval(true);  // expected-warning{{TRUE}}
     }
   }
+
+  // PR16664 and PR18159
+  void testConsistencyNestedSimple(bool value) {
+    if (value) {
+      if (!value || check(NoReturnDtor())) {
+        clang_analyzer_eval(true); // no warning, unreachable code
+      }
+    }
+  }
+
+  // PR16664 and PR18159
+  void testConsistencyNestedComplex(bool value) {
+    if (value) {
+      if (!value || !value || check(NoReturnDtor())) {
+        // FIXME: This shouldn't cause a warning.
+        clang_analyzer_eval(true); // expected-warning{{TRUE}}
+      }
+    }
+  }
+
+  // PR16664 and PR18159
+  void testConsistencyNestedWarning(bool value) {
+    if (value) {
+      if (!value || value || check(NoReturnDtor())) {
+        clang_analyzer_eval(true); // expected-warning{{TRUE}}
+      }
+    }
+  }
+
+  void testBinaryOperatorShortcut(bool value) {
+    if (value) {
+      if (false && false && check(NoReturnDtor()) && true) {
+        clang_analyzer_eval(true);
+      }
+    }
+  }
+
 #endif // TEMPORARY_DTORS
 }
 
diff --git a/test/Analysis/test-after-div-zero.c b/test/Analysis/test-after-div-zero.c
new file mode 100644
index 0000000..f34c4f7
--- /dev/null
+++ b/test/Analysis/test-after-div-zero.c
@@ -0,0 +1,204 @@
+// RUN: %clang_cc1 -std=c99 -Dbool=_Bool -analyze -analyzer-checker=core,alpha.core.TestAfterDivZero -analyzer-output=text -verify %s
+// RUN: %clang_cc1 -x c++ -analyze -analyzer-checker=core,alpha.core.TestAfterDivZero -analyzer-output=text -verify %s
+
+int var;
+
+void err_eq(int x) {
+  var = 77 / x; // expected-note {{Division with compared value made here}}
+  if (x == 0) { } // expected-warning {{Value being compared against zero has already been used for division}}
+} // expected-note@-1 {{Value being compared against zero has already been used for division}}
+
+void err_eq2(int x) {
+  var = 77 / x; // expected-note {{Division with compared value made here}}
+  if (0 == x) { } // expected-warning {{Value being compared against zero has already been used for division}}
+} // expected-note@-1 {{Value being compared against zero has already been used for division}}
+
+void err_ne(int x) {
+  var = 77 / x; // expected-note {{Division with compared value made here}}
+  if (x != 0) { } // expected-warning {{Value being compared against zero has already been used for division}}
+} // expected-note@-1 {{Value being compared against zero has already been used for division}}
+
+void err_ge(int x) {
+  var = 77 / x; // expected-note {{Division with compared value made here}}
+  if (x >= 0) { } // expected-warning {{Value being compared against zero has already been used for division}}
+} // expected-note@-1 {{Value being compared against zero has already been used for division}}
+
+void err_le(int x) {
+  var = 77 / x; // expected-note {{Division with compared value made here}}
+  if (x <= 0) {} // expected-warning {{Value being compared against zero has already been used for division}}
+} // expected-note@-1 {{Value being compared against zero has already been used for division}}
+
+void err_yes(int x) {
+  var = 77 / x; // expected-note {{Division with compared value made here}}
+  if (x) {} // expected-warning {{Value being compared against zero has already been used for division}}
+} // expected-note@-1 {{Value being compared against zero has already been used for division}}
+void err_not(int x) {
+  var = 77 / x; // expected-note {{Division with compared value made here}}
+  if (!x) {} // expected-warning {{Value being compared against zero has already been used for division}}
+} // expected-note@-1 {{Value being compared against zero has already been used for division}}
+
+void err_pnot(int x) {
+  int *y = &x;
+  var = 77 / *y; // expected-note {{Division with compared value made here}}
+  if (!x) {} // expected-warning {{Value being compared against zero has already been used for division}}
+} // expected-note@-1 {{Value being compared against zero has already been used for division}}
+
+void err_pnot2(int x) {
+  int *y = &x;
+  var = 77 / x; // expected-note {{Division with compared value made here}}
+  if (!*y) {} // expected-warning {{Value being compared against zero has already been used for division}}
+} // expected-note@-1 {{Value being compared against zero has already been used for division}}
+
+void err_ppnot(int x) {
+  int *y = &x;
+  int **z = &y;
+  var = 77 / **z; // expected-note {{Division with compared value made here}}
+  if (!x) {} // expected-warning {{Value being compared against zero has already been used for division}}
+} // expected-note@-1 {{Value being compared against zero has already been used for division}}
+
+void err_orig_checker(int x) {
+  if (x != 0) // expected-note {{Assuming 'x' is equal to 0}} expected-note {{Taking false branch}}
+    return;
+  var = 77 / x; // expected-warning {{Division by zero}} expected-note {{Division by zero}}
+  if (!x) {} // no-warning
+}
+
+void ok_other(int x, int y) {
+  var = 77 / y;
+  if (x == 0) {
+  }
+}
+
+void ok_assign(int x) {
+  var = 77 / x;
+  x = var / 77; // <- assignment => don't warn
+  if (x == 0) {
+  }
+}
+
+void ok_assign2(int x) {
+  var = 77 / x;
+  x = var / 77; // <- assignment => don't warn
+  if (0 == x) {
+  }
+}
+
+void ok_dec(int x) {
+  var = 77 / x;
+  x--; // <- assignment => don't warn
+  if (x == 0) {
+  }
+}
+
+void ok_inc(int x) {
+  var = 77 / x;
+  x++; // <- assignment => don't warn
+  if (x == 0) {
+  }
+}
+
+void do_something_ptr(int *x);
+void ok_callfunc_ptr(int x) {
+  var = 77 / x;
+  do_something_ptr(&x); // <- pass address of x to function => don't warn
+  if (x == 0) {
+  }
+}
+
+void do_something(int x);
+void nok_callfunc(int x) {
+  var = 77 / x; // expected-note {{Division with compared value made here}}
+  do_something(x);
+  if (x == 0) {} // expected-warning {{Value being compared against zero has already been used for division}}
+} // expected-note@-1 {{Value being compared against zero has already been used for division}}
+
+void ok_if(int x) {
+  if (x > 3)
+    var = 77 / x;
+  if (x == 0) {
+  }
+}
+
+void ok_if2(int x) {
+  if (x < 3)
+    var = 77 / x;
+  if (x == 0) {
+  } // TODO warn here
+}
+
+void ok_pif(int x) {
+  int *y = &x;
+  if (x < 3)
+    var = 77 / *y;
+  if (x == 0) {
+  } // TODO warn here
+}
+
+int getValue(bool *isPositive);
+void use(int a);
+void foo() {
+  bool isPositive;
+  int x = getValue(&isPositive);
+  if (isPositive) {
+    use(5 / x);
+  }
+
+  if (x == 0) {
+  }
+}
+
+int getValue2();
+void foo2() {
+  int x = getValue2();
+  int y = x;
+
+  use(5 / x); // expected-note {{Division with compared value made here}}
+  if (y == 0) {} // expected-warning {{Value being compared against zero has already been used for division}}
+} // expected-note@-1 {{Value being compared against zero has already been used for division}}
+
+void ok_while(int x) {
+  int n = 100 / x;
+  while (x != 0) { // <- do not warn
+    x--;
+  }
+}
+
+void err_not2(int x, int y) {
+  int v;
+  var = 77 / x;
+
+  if (y)
+    v = 0;
+
+  if (!x) {
+  } // TODO warn here
+}
+
+inline void inline_func(int x) {
+  var = 77 / x; // expected-note {{Division with compared value made here}}
+  if (x == 0) {} // expected-warning {{Value being compared against zero has already been used for division}}
+} // expected-note@-1 {{Value being compared against zero has already been used for division}}
+
+void err_inline(int x) {
+  var = 77 / x;
+  inline_func(x); // expected-note {{Calling 'inline_func'}}
+  if (x == 0) {
+  }
+}
+
+inline void inline_func2(int x) {}
+
+void err_inline2(int x) {
+  var = 77 / x; // expected-note {{Division with compared value made here}}
+  inline_func2(x);
+  if (x == 0) {} // expected-warning {{Value being compared against zero has already been used for division}}
+} // expected-note@-1 {{Value being compared against zero has already been used for division}}
+
+inline void inline_func3(int x) {
+  var = 77 / x;
+}
+void ok_inline(int x) {
+  var = 77 / x; // expected-note {{Division with compared value made here}}
+  inline_func3(x);
+  if (x == 0) {} // expected-warning {{Value being compared against zero has already been used for division}}
+} // expected-note@-1 {{Value being compared against zero has already been used for division}}
diff --git a/test/Analysis/uninit-const.c b/test/Analysis/uninit-const.c
new file mode 100644
index 0000000..9e42d23
--- /dev/null
+++ b/test/Analysis/uninit-const.c
@@ -0,0 +1,216 @@
+// RUN: %clang_cc1 -analyze -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"
+
+typedef __typeof(sizeof(int)) size_t;
+void *malloc(size_t);
+void *valloc(size_t);
+void free(void *);
+
+
+void doStuff3(const int y){}
+void doStuff2(int g){}
+void doStuff_pointerToConstInt(const int *u){};
+void doStuff_arrayOfConstInt(const int a[]){};
+
+void doStuff_constPointerToConstInt              (int const * const u){};
+void doStuff_constPointerToConstPointerToConstInt(int const * const * const u){};
+void doStuff_pointerToConstPointerToConstInt(int const * const * u){};
+void doStuff_pointerToPointerToConstInt       (int const **u){};
+void doStuff_constStaticSizedArray(const int a[static 10]) {}
+void doStuff_variadic(const int *u, ...){};
+
+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}}
+}
+
+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}}
+}
+
+
+int *f_2_sub(int *p) {
+  return p;
+}
+
+void f_2(void) {
+  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}}
+}
+
+int z;
+void f_3(void) {
+      doStuff_pointerToConstInt(&z);  // no warning
+}
+
+void f_4(void) {
+      int x=5;
+      doStuff_pointerToConstInt(&x);  // no warning
+}
+
+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}}
+}
+
+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}}
+}
+
+void f_6(void) {
+  int ta[5] = {1,2,3,4,5};
+  int* tp = ta;
+  doStuff_pointerToConstInt(tp); // no-warning
+}
+
+void f_6_1(void) {
+  int ta[5] = {1,2,3,4,5};
+  doStuff_pointerToConstInt(ta); // no-warning
+}
+
+void f_7(void) {
+      int z;        // expected-note {{'z' declared without an initial value}}
+      int y=z;      // expected-warning {{Assigned value is garbage or undefined}}
+                    // expected-note@-1 {{Assigned value is garbage or undefined}}
+      doStuff3(y);
+}
+
+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}}
+}
+
+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}}
+}
+
+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}}
+}
+
+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}}
+}
+
+void f_12(void) {
+  int t[10] = {0,1,2,3,4,5,6,7,8,9};
+  doStuff_constStaticSizedArray(t);  // no-warning
+
+}
+
+int f_malloc_1(void) {
+  int *ptr;
+
+  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}}
+  free(ptr);
+  return 0;
+}
+
+int f_malloc_2(void) {
+  int *ptr;
+
+  ptr = (int *)malloc(sizeof(int));
+  *ptr = 25;
+
+  doStuff_pointerToConstInt(ptr); // no warning
+  free(ptr);
+  return 0;
+}
+
+// uninit pointer, uninit val
+void f_variadic_unp_unv(void) {
+  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}}
+}
+// 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}}
+}
+
+// init pointer, uninit val
+void f_variadic_inp_unv(void) {
+  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}}
+}
+
+// init pointer, init val
+void f_variadic_inp_inv(void) {
+  int t=5;
+  int v = 3;
+  int* tp = &t;
+  doStuff_variadic(tp,v); // no-warning
+}
+
+// init pointer, init pointer
+void f_variadic_inp_inp(void) {
+  int t=5;
+  int u=3;
+  int *vp = &u ;
+  int *tp = &t;
+  doStuff_variadic(tp,vp); // no-warning
+}
+
+//uninit pointer, init pointer
+void f_variadic_unp_inp(void) {
+  int t;
+  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}}
+}
+
+//init pointer, uninit pointer
+void f_variadic_inp_unp(void) {
+  int t=5;
+  int u;
+  int *vp = &u ;
+  int *tp = &t;
+  doStuff_variadic(tp,vp); // no-warning
+}
+
+//uninit pointer, uninit pointer
+void f_variadic_unp_unp(void) {
+  int t;
+  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}}
+}
diff --git a/test/Analysis/uninit-const.cpp b/test/Analysis/uninit-const.cpp
new file mode 100644
index 0000000..56bfa08
--- /dev/null
+++ b/test/Analysis/uninit-const.cpp
@@ -0,0 +1,128 @@
+// RUN: %clang_cc1 -analyze -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"
+
+void doStuff6(const int& c);
+void doStuff4(const int y);
+void doStuff3(int& g);
+void doStuff_uninit(const int *u);
+
+
+int f10(void) {
+  int *ptr;
+
+  ptr = new int; //
+  if(*ptr) {
+    doStuff4(*ptr);
+  }
+  delete ptr;
+  return 0;
+}
+
+int f9(void) {
+  int *ptr;
+
+  ptr = new int; //
+
+  doStuff_uninit(ptr); // no warning
+  delete ptr;
+  return 0;
+}
+
+int f8(void) {
+  int *ptr;
+
+  ptr = new int;
+  *ptr = 25;
+
+  doStuff_uninit(ptr); // no warning?
+  delete ptr;
+  return 0;
+}
+
+void f7(void) {
+  int m = 3;
+  doStuff6(m); // no warning
+}
+
+
+int& f6_1_sub(int &p) {
+  return p;
+}
+
+void f6_1(void) {
+  int t;
+  int p = f6_1_sub(t); //expected-warning {{Assigned value is garbage or undefined}}
+                       //expected-note@-1 {{Calling 'f6_1_sub'}}
+                       //expected-note@-2 {{Returning from 'f6_1_sub'}}
+                       //expected-note@-3 {{Assigned value is garbage or undefined}}
+  int q = p;
+  doStuff6(q);
+}
+
+void f6_2(void) {
+  int t;       //expected-note {{'t' declared without an initial value}}
+  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}}
+}
+
+void doStuff6_3(int& q_, int *ptr_) {}
+
+void f6_3(void) {
+  int *ptr;    //expected-note {{'ptr' declared without an initial value}}
+  int t;
+  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}}
+
+}
+
+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}}
+
+}
+
+
+
+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}}
+}
+
+
+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}}
+}
+
+void f3(void) {
+      int g;
+      doStuff3(g); // no warning
+}
+
+int z;
+void f2(void) {
+      doStuff_uninit(&z);  // no warning
+}
+
+void f1(void) {
+      int x_=5;
+      doStuff_uninit(&x_);  // no warning
+}
+
+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}}
+}
diff --git a/test/Analysis/uninit-vals-ps-region.m b/test/Analysis/uninit-vals-ps-region.m
index a4aa5a1..87256b3 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,alpha.deadcode.IdempotentOperations -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-checker=core -verify %s
 
 struct s {
   int data;
@@ -42,7 +42,7 @@
 void test_uninit_neg() {
   struct TestUninit v1 = { 0, 0 };
   struct TestUninit v2 = test_uninit_aux();
-  test_unit_aux2(v2.x + v1.y); // expected-warning{{The right operand to '+' is always 0}}
+  test_unit_aux2(v2.x + v1.y);
 }
 
 extern void test_uninit_struct_arg_aux(struct TestUninit arg);
diff --git a/test/Analysis/weak-functions.c b/test/Analysis/weak-functions.c
index 96e3b44..a983f92 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 -analyzer-store=region -fblocks -verify %s
+// 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
 #define NULL 0
 void clang_analyzer_eval(int);
 void myFunc();
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index a11b83a..591a927 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -1,11 +1,13 @@
 # Test runner infrastructure for Clang. This configures the Clang test trees
 # for use by Lit, and delegates to LLVM's lit test handlers.
-#
-# If this is a stand-alone Clang build, we fake up our own Lit support here
-# rather than relying on LLVM's.
 
-set(CLANG_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/..")
-set(CLANG_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/..")
+if (CMAKE_CFG_INTDIR STREQUAL ".")
+  set(LLVM_BUILD_MODE ".")
+else ()
+  set(LLVM_BUILD_MODE "%(build_mode)s")
+endif ()
+
+string(REPLACE ${CMAKE_CFG_INTDIR} ${LLVM_BUILD_MODE} CLANG_TOOLS_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR})
 
 configure_lit_site_cfg(
   ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
@@ -17,81 +19,58 @@
   ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg
   )
 
-if( PATH_TO_LLVM_BUILD )
-  set(CLANG_TEST_EXTRA_ARGS "--path=${CLANG_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}")
-endif()
-
 option(CLANG_TEST_USE_VG "Run Clang tests under Valgrind" OFF)
 if(CLANG_TEST_USE_VG)
   set(CLANG_TEST_EXTRA_ARGS ${CLANG_TEST_EXTRA_ARGS} "--vg")
 endif ()
 
-set(CLANG_TEST_DEPS
+list(APPEND CLANG_TEST_DEPS
   clang clang-headers
-  c-index-test diagtool arcmt-test c-arcmt-test
   clang-check clang-format
+  c-index-test diagtool
+  clang-tblgen
   )
+
+if (CLANG_ENABLE_ARCMT)
+  list(APPEND CLANG_TEST_DEPS
+    arcmt-test
+    c-arcmt-test
+  )
+endif ()
+
+if (ENABLE_CLANG_EXAMPLES)
+  list(APPEND CLANG_TEST_DEPS
+    clang-interpreter
+    PrintFunctionNames
+    )
+endif ()
+
+if (ENABLE_CLANG_STATIC_ANALYZER AND ENABLE_CLANG_EXAMPLES)
+  list(APPEND CLANG_TEST_DEPS
+    SampleAnalyzerPlugin
+    )
+endif ()
+
 set(CLANG_TEST_PARAMS
   clang_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
   )
 
-if(CLANG_INCLUDE_TESTS)  
-  list(APPEND CLANG_TEST_DEPS ClangUnitTests)
-  list(APPEND CLANG_TEST_PARAMS
-    clang_unit_site_config=${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg
-    )
-endif()
-
 if( NOT CLANG_BUILT_STANDALONE )
   list(APPEND CLANG_TEST_DEPS
-    llc opt FileCheck count not llvm-symbolizer
+    llvm-config
+    llc opt FileCheck count not llvm-symbolizer llvm-profdata
     )
-
-  add_lit_testsuite(check-clang "Running the Clang regression tests"
-    ${CMAKE_CURRENT_BINARY_DIR}
-    PARAMS ${CLANG_TEST_PARAMS}
-    DEPENDS ${CLANG_TEST_DEPS}
-    ARGS ${CLANG_TEST_EXTRA_ARGS}
-    )
-  set_target_properties(check-clang PROPERTIES FOLDER "Clang tests")
-
-else()
-
-  include(FindPythonInterp)
-  if(PYTHONINTERP_FOUND)
-    if( LLVM_MAIN_SRC_DIR )
-      set(LIT "${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py")
-    else()
-      set(LIT "${PATH_TO_LLVM_BUILD}/bin/${CMAKE_CFG_INTDIR}/llvm-lit")
-      # Installed LLVM does not contain ${CMAKE_CFG_INTDIR} in paths.
-      if( NOT EXISTS ${LIT} )
-        set(LIT "${PATH_TO_LLVM_BUILD}/bin/llvm-lit")
-      endif()
-    endif()
-
-    set(LIT_ARGS "${CLANG_TEST_EXTRA_ARGS} ${LLVM_LIT_ARGS}")
-    separate_arguments(LIT_ARGS)
-    
-    list(APPEND CLANG_TEST_PARAMS build_mode=${CMAKE_CFG_INTDIR})
-
-    foreach(param ${CLANG_TEST_PARAMS})
-      list(APPEND LIT_ARGS --param ${param})
-    endforeach()
-
-    add_custom_target(check-clang
-      COMMAND ${PYTHON_EXECUTABLE}
-              ${LIT}
-              ${LIT_ARGS}
-              ${CMAKE_CURRENT_BINARY_DIR}
-              ${CLANG_TEST_EXTRA_ARGS}
-      COMMENT "Running Clang regression tests"
-      DEPENDS ${CLANG_TEST_DEPS}
-      )
-    set_target_properties(check-clang PROPERTIES FOLDER "Clang tests")
-  endif()
-
 endif()
 
+add_lit_testsuite(check-clang "Running the Clang regression tests"
+  ${CMAKE_CURRENT_BINARY_DIR}
+  #LIT ${LLVM_LIT}
+  PARAMS ${CLANG_TEST_PARAMS}
+  DEPENDS ${CLANG_TEST_DEPS}
+  ARGS ${CLANG_TEST_EXTRA_ARGS}
+  )
+set_target_properties(check-clang PROPERTIES FOLDER "Clang tests")
+
 # Add a legacy target spelling: clang-test
 add_custom_target(clang-test)
 add_dependencies(clang-test check-clang)
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 1f78a73..b9e8398 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
@@ -105,9 +105,10 @@
 
   };
 
+  // FIXME: Consider reusing the same diagnostic between dependent and non-dependent contexts
   typedef int I;
   struct UsingInt {
-    using I::I; // expected-error {{expected a class or namespace}}
+    using I::I; // expected-error {{'I' (aka 'int') is not a class, namespace, or scoped 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.lookup/basic.lookup.qual/namespace.qual/p2.cpp b/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p2.cpp
index 3039396..7918e9f 100644
--- a/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p2.cpp
+++ b/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p2.cpp
@@ -63,3 +63,14 @@
   Numbers2::f(f);
   Numbers2::g(f); // expected-error {{no viable conversion from 'float' to 'Numbers::Number'}}
 }
+
+namespace inline_ns {
+  int x; // expected-note 2{{found}}
+  inline namespace A { // expected-warning {{C++11}}
+    int x; // expected-note 2{{found}}
+    int y; // expected-note 2{{found}}
+  }
+  int y; // expected-note 2{{found}}
+  int k1 = x + y; // expected-error 2{{ambiguous}}
+  int k2 = inline_ns::x + inline_ns::y; // expected-error 2{{ambiguous}}
+}
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.qual/p6-0x.cpp b/test/CXX/basic/basic.lookup/basic.lookup.qual/p6-0x.cpp
index c745c84..c3be712 100644
--- a/test/CXX/basic/basic.lookup/basic.lookup.qual/p6-0x.cpp
+++ b/test/CXX/basic/basic.lookup/basic.lookup.qual/p6-0x.cpp
@@ -1,26 +1,25 @@
 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
-// XFAIL: *
-// Our C++0x doesn't currently have specialized destructor name handling,
-// since the specification is still in flux.
-struct C { 
-  typedef int I;
-}; 
+// expected-no-diagnostics
 
-typedef int I1, I2; 
-extern int* p; 
-extern int* q; 
+struct C {
+  typedef int I;
+};
+
+typedef int I1, I2;
+extern int* p;
+extern int* q;
 
 void f() {
-  p->C::I::~I(); 
+  p->C::I::~I();
   q->I1::~I2();
 }
 
-struct A { 
+struct A {
   ~A();
-}; 
+};
 
-typedef A AB; 
+typedef A AB;
 int main() {
-  AB *p; 
+  AB *p;
   p->AB::~AB();
 }
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp b/test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp
index 0956de3..83c8dd8 100644
--- a/test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp
+++ b/test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
+// expected-no-diagnostics
 
 struct C { 
   typedef int I;
@@ -20,5 +21,5 @@
 typedef A AB; 
 int main() {
   AB *p; 
-  p->AB::~AB(); // expected-error{{expected the class name after '~' to name a destructor}}
+  p->AB::~AB();
 }
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.unqual/p15.cpp b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p15.cpp
index 253d15e..c59c4a5 100644
--- a/test/CXX/basic/basic.lookup/basic.lookup.unqual/p15.cpp
+++ b/test/CXX/basic/basic.lookup/basic.lookup.unqual/p15.cpp
@@ -1,5 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-// XFAIL: *
+// RUN: %clang_cc1 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s
 
 class C {
 public:
@@ -10,8 +9,13 @@
      int b) // expected-note {{previous definition}}
 try {
   int c;
-
 } catch (int a) { // expected-error {{redefinition of 'a'}}
   int b; // expected-error {{redefinition of 'b'}}
   ++c; // expected-error {{use of undeclared identifier 'c'}}
 }
+
+void f(int i) {
+  struct S {
+    void g() try {} catch (int i) {}; // OK
+  };
+}
diff --git a/test/CXX/basic/basic.scope/basic.scope.local/p2.cpp b/test/CXX/basic/basic.scope/basic.scope.local/p2.cpp
index 7c7b84d..1b41991 100644
--- a/test/CXX/basic/basic.scope/basic.scope.local/p2.cpp
+++ b/test/CXX/basic/basic.scope/basic.scope.local/p2.cpp
@@ -9,8 +9,8 @@
 } catch (...) {
 }
 
-void func3(int i) try { // FIXME: note {{previous definition is here}}
-} catch (int i) { // FIXME: error {{redefinition of 'i'}}
+void func3(int i) try { // expected-note {{previous definition is here}}
+} catch (int i) { // expected-error {{redefinition of 'i'}}
 }
 
 void func4(int i) try { // expected-note{{previous definition is here}}
@@ -58,3 +58,9 @@
       int b; // FIXME: decide whether this is valid
     }
 }
+
+void func11(int a) {
+  try {
+  } catch (int a) {  // OK
+  }
+}
diff --git a/test/CXX/basic/basic.start/basic.start.init/p3.cpp b/test/CXX/basic/basic.start/basic.start.init/p3.cpp
new file mode 100644
index 0000000..506232e
--- /dev/null
+++ b/test/CXX/basic/basic.start/basic.start.init/p3.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -verify %s -pedantic-errors
+// RUN: %clang_cc1 -verify %s -pedantic-errors -DINLINE
+// RUN: %clang_cc1 -verify %s -pedantic-errors -DSTATIC
+// RUN: %clang_cc1 -verify %s -pedantic-errors -std=c++11 -DCONSTEXPR
+// RUN: %clang_cc1 -verify %s -std=c++11 -DDELETED
+
+#if INLINE
+inline // expected-error {{'main' is not allowed to be declared inline}}
+#elif STATIC
+static // expected-error {{'main' is not allowed to be declared static}}
+#elif CONSTEXPR
+constexpr // expected-error {{'main' is not allowed to be declared constexpr}}
+#endif
+int main(int argc, char **argv)
+#if DELETED
+  = delete; // expected-error {{'main' is not allowed to be deleted}}
+#else
+{
+  int (*pmain)(int, char**) = &main; // expected-error {{ISO C++ does not allow 'main' to be used by a program}}
+
+  if (argc)
+    main(0, 0); // expected-error {{ISO C++ does not allow 'main' to be used by a program}}
+}
+#endif
diff --git a/test/CXX/basic/basic.start/basic.start.main/p2.cpp b/test/CXX/basic/basic.start/basic.start.main/p2.cpp
index 5c7d60c..42e87e5 100644
--- a/test/CXX/basic/basic.start/basic.start.main/p2.cpp
+++ b/test/CXX/basic/basic.start/basic.start.main/p2.cpp
@@ -62,6 +62,8 @@
 ) {
 }
 
+const int main(); // expected-error {{'main' must return 'int'}}
+
 #elif TEST7
 
 // expected-no-diagnostics
diff --git a/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.allocation/p1.cpp b/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.allocation/p1.cpp
index 8a62ae8..3b77a62 100644
--- a/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.allocation/p1.cpp
+++ b/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.allocation/p1.cpp
@@ -9,7 +9,8 @@
   void *operator new(size_t);; // expected-error {{'operator new' cannot be declared inside a namespace}}
 }
 
-static void *operator new(size_t); // expected-error {{'operator new' cannot be declared static in global scope}}
+static void *operator new(size_t); // expected-error {{static declaration of 'operator new' follows non-static declaration}} expected-note {{previous}}
+static void *operator new(size_t, int, int); // expected-error {{'operator new' cannot be declared static in global scope}}
 
 struct B {
   void operator new(size_t);  // expected-error {{'operator new' must return type 'void *'}}
diff --git a/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.deallocation/p1.cpp b/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.deallocation/p1.cpp
index e00e948..09dde8e 100644
--- a/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.deallocation/p1.cpp
+++ b/test/CXX/basic/basic.stc/basic.stc.dynamic/basic.stc.dynamic.deallocation/p1.cpp
@@ -8,4 +8,5 @@
   void operator delete(void *); // expected-error {{'operator delete' cannot be declared inside a namespace}}
 }
 
-static void operator delete(void *); // expected-error {{'operator delete' cannot be declared static in global scope}}
+static void operator delete(void *); // expected-error {{follows non-static declaration}} expected-note {{implicit}}
+static void operator delete(void *, int, int); // expected-error {{'operator delete' cannot be declared static in global scope}}
diff --git a/test/CXX/class.access/class.access.base/p1.cpp b/test/CXX/class.access/class.access.base/p1.cpp
index 43cc99e..88e2688 100644
--- a/test/CXX/class.access/class.access.base/p1.cpp
+++ b/test/CXX/class.access/class.access.base/p1.cpp
@@ -153,3 +153,18 @@
     t->Base::spriv++; // expected-error 2 {{private member}}
   }
 }
+
+namespace PR12788 {
+  class A {
+  protected:
+    struct {
+      int x;
+    };
+  };
+  class B : A {
+    void f() {
+      ++x;
+      A::x++;
+    }
+  };
+}
diff --git a/test/CXX/class.access/p4.cpp b/test/CXX/class.access/p4.cpp
index 0564a52..435b099 100644
--- a/test/CXX/class.access/p4.cpp
+++ b/test/CXX/class.access/p4.cpp
@@ -79,8 +79,8 @@
     -ca;
     // These are all surrogate calls
     ca(pub);
-    ca(prot); // expected-error {{'operator void (*)(class Protected &)' is a protected member}}
-    ca(priv); // expected-error {{'operator void (*)(class Private &)' is a private member}}
+    ca(prot); // expected-error {{'operator void (*)(Protected &)' is a protected member}}
+    ca(priv); // expected-error {{'operator void (*)(Private &)' is a private member}}
   }
 }
 
diff --git a/test/CXX/class.access/p6.cpp b/test/CXX/class.access/p6.cpp
index 6a93658..f9b95f0 100644
--- a/test/CXX/class.access/p6.cpp
+++ b/test/CXX/class.access/p6.cpp
@@ -177,7 +177,7 @@
   };
 
   void test(A &a) {
-    if (a) return; // expected-error {{'operator void *(class test8::A::*)(void) const' is a private member of 'test8::A'}}
+    if (a) return; // expected-error-re {{'operator void *(test8::A::*)(){{( __attribute__\(\(thiscall\)\))?}} const' is a private member of 'test8::A'}}
   }
 }
 
diff --git a/test/CXX/class/class.static/class.static.data/p4.cpp b/test/CXX/class/class.static/class.static.data/p4.cpp
index 2b1eca7..85d18c6 100644
--- a/test/CXX/class/class.static/class.static.data/p4.cpp
+++ b/test/CXX/class/class.static/class.static.data/p4.cpp
@@ -10,15 +10,14 @@
 int const OutOfClassInitializerOnly::i = 0;
 
 struct InClassInitializerAndOutOfClassCopyInitializer {
-  static const int i = 0; // expected-note{{previous definition is here}}
+  static const int i = 0; // expected-note{{previous initialization is here}}
 };
-int const InClassInitializerAndOutOfClassCopyInitializer::i = 0; // expected-error{{redefinition of 'i'}}
+int const InClassInitializerAndOutOfClassCopyInitializer::i = 0; // expected-error{{static data member 'i' already has an initializer}}
 
 struct InClassInitializerAndOutOfClassDirectInitializer {
-  static const int i = 0; // expected-note{{previous definition is here}}
+  static const int i = 0; // expected-note{{previous initialization is here}}
 };
-int const InClassInitializerAndOutOfClassDirectInitializer::i(0); // expected-error{{redefinition of 'i'}}
-
+int const InClassInitializerAndOutOfClassDirectInitializer::i(0); // expected-error{{static data member 'i' already has an initializer}}
 
 
 int main() { }
diff --git a/test/CXX/class/class.union/p8.cpp b/test/CXX/class/class.union/p8.cpp
new file mode 100644
index 0000000..cc54ba4
--- /dev/null
+++ b/test/CXX/class/class.union/p8.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+union U {
+  int x = 0; // expected-note {{previous initialization is here}}
+  union {};
+  union {
+    int z;
+    int y = 1; // expected-error {{initializing multiple members of union}}
+  };
+};
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp
index c7966ce..4ffb93a 100644
--- a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp
@@ -1,14 +1,16 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 
-// C++03 [namespace.udecl]p11:
+// C++03 [namespace.udecl]p11: (per DR101)
 //   If a function declaration in namespace scope or block scope has
 //   the same name and the same parameter types as a function
-//   introduced by a using-declaration, the program is
-//   ill-formed. [Note: two using-declarations may introduce functions
-//   with the same name and the same parameter types. If, for a call
-//   to an unqualified function name, function overload resolution
-//   selects the functions introduced by such using-declarations, the
-//   function call is ill-formed.
+//   introduced by a using-declaration, and the declarations do not declare the
+//   same function, the program is ill-formed. [Note: two using-declarations may
+//   introduce functions with the same name and the same parameter types. If,
+//   for a call to an unqualified function name, function overload resolution
+//   selects the functions introduced by such using-declarations, the function
+//   call is ill-formed.]
+//
+// FIXME: DR565 introduces parallel wording here for function templates.
 
 namespace test0 {
   namespace ns { void foo(); } // expected-note {{target of using declaration}}
@@ -89,3 +91,19 @@
   template class Test0<int>;
   template class Test1<int>;
 }
+
+namespace test6 {
+  namespace ns { void foo(); } // expected-note {{target of using declaration}}
+  using ns::foo; // expected-note {{using declaration}}
+  namespace ns {
+    using test6::foo;
+    void foo() {}
+  }
+  void foo(); // expected-error {{declaration conflicts with target of using declaration already in scope}}
+}
+
+namespace test7 {
+  void foo();
+  using test7::foo;
+  void foo() {}
+}
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p5-cxx0x.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p5-cxx0x.cpp
index edaa975..35ef3b5 100644
--- a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p5-cxx0x.cpp
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p5-cxx0x.cpp
@@ -7,6 +7,6 @@
 };
 
 struct B : A {
-  using A::f<double>; // expected-error{{using declaration can not refer to a template specialization}}
-  using A::X<int>; // expected-error{{using declaration can not refer to a template specialization}}
+  using A::f<double>; // expected-error{{using declaration cannot refer to a template specialization}}
+  using A::X<int>; // expected-error{{using declaration cannot refer to a template specialization}}
 };
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx0x.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx0x.cpp
index c4b8849..c2fb959 100644
--- a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx0x.cpp
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx0x.cpp
@@ -5,4 +5,4 @@
   namespace B { }
 }
 
-using A::B; // expected-error{{using declaration can not refer to namespace}}
+using A::B; // expected-error{{using declaration cannot refer to namespace}}
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 78b5a41..4f89dcf 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,4 +1,7 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++98 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -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.
 
 struct X {
@@ -6,10 +9,101 @@
   static int a;
 };
 
-using X::i; // expected-error{{using declaration can not refer to class member}}
-using X::s; // expected-error{{using declaration can not refer to class member}}
+using X::i; // expected-error{{using declaration cannot refer to class member}}
+using X::s; // expected-error{{using declaration cannot refer to class member}}
 
 void f() {
-  using X::i; // expected-error{{using declaration can not refer to class member}}
-  using X::s; // expected-error{{using declaration can not refer to class member}}
+  using X::i; // expected-error{{using declaration cannot refer to class member}}
+  using X::s; // expected-error{{using declaration cannot refer to class member}}
+}
+
+struct S {
+  static int n;
+  struct Q {};
+  enum E {};
+  typedef Q T;
+  void f();
+  static void g();
+};
+
+using S::n; // expected-error{{class member}} expected-note {{use a reference instead}}
+#if __cplusplus < 201103L
+// CXX98-NOT: fix-it:"{{.*}}":{[[@LINE-2]]
+#else
+// CXX11: fix-it:"{{.*}}":{[[@LINE-4]]:1-[[@LINE-4]]:6}:"auto &n = "
+#endif
+
+using S::Q; // expected-error{{class member}}
+#if __cplusplus < 201103L
+// expected-note@-2 {{use a typedef declaration instead}}
+// CXX98: fix-it:"{{.*}}":{[[@LINE-3]]:1-[[@LINE-3]]:6}:"typedef"
+// CXX98: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:11}:" Q"
+#else
+// expected-note@-6 {{use an alias declaration instead}}
+// CXX11: fix-it:"{{.*}}":{[[@LINE-7]]:7-[[@LINE-7]]:7}:"Q = "
+#endif
+
+using S::E; // expected-error{{class member}}
+#if __cplusplus < 201103L
+// expected-note@-2 {{use a typedef declaration instead}}
+// CXX98: fix-it:"{{.*}}":{[[@LINE-3]]:1-[[@LINE-3]]:6}:"typedef"
+// CXX98: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:11}:" E"
+#else
+// expected-note@-6 {{use an alias declaration instead}}
+// CXX11: fix-it:"{{.*}}":{[[@LINE-7]]:7-[[@LINE-7]]:7}:"E = "
+#endif
+
+using S::T; // expected-error{{class member}}
+#if __cplusplus < 201103L
+// expected-note@-2 {{use a typedef declaration instead}}
+// CXX98: fix-it:"{{.*}}":{[[@LINE-3]]:1-[[@LINE-3]]:6}:"typedef"
+// CXX98: fix-it:"{{.*}}":{[[@LINE-4]]:11-[[@LINE-4]]:11}:" T"
+#else
+// expected-note@-6 {{use an alias declaration instead}}
+// CXX11: fix-it:"{{.*}}":{[[@LINE-7]]:7-[[@LINE-7]]:7}:"T = "
+#endif
+
+using S::f; // expected-error{{class member}}
+using S::g; // expected-error{{class member}}
+
+void h() {
+  using S::n; // expected-error{{class member}} expected-note {{use a reference instead}}
+#if __cplusplus < 201103L
+  // CXX98-NOT: fix-it:"{{.*}}":{[[@LINE-2]]
+#else
+  // CXX11: fix-it:"{{.*}}":{[[@LINE-4]]:3-[[@LINE-4]]:8}:"auto &n = "
+#endif
+
+  using S::Q; // expected-error{{class member}}
+#if __cplusplus < 201103L
+  // expected-note@-2 {{use a typedef declaration instead}}
+  // CXX98: fix-it:"{{.*}}":{[[@LINE-3]]:3-[[@LINE-3]]:8}:"typedef"
+  // CXX98: fix-it:"{{.*}}":{[[@LINE-4]]:13-[[@LINE-4]]:13}:" Q"
+#else
+  // expected-note@-6 {{use an alias declaration instead}}
+  // CXX11: fix-it:"{{.*}}":{[[@LINE-7]]:9-[[@LINE-7]]:9}:"Q = "
+#endif
+
+  using S::E; // expected-error{{class member}}
+#if __cplusplus < 201103L
+  // expected-note@-2 {{use a typedef declaration instead}}
+  // CXX98: fix-it:"{{.*}}":{[[@LINE-3]]:3-[[@LINE-3]]:8}:"typedef"
+  // CXX98: fix-it:"{{.*}}":{[[@LINE-4]]:13-[[@LINE-4]]:13}:" E"
+#else
+  // expected-note@-6 {{use an alias declaration instead}}
+  // CXX11: fix-it:"{{.*}}":{[[@LINE-7]]:9-[[@LINE-7]]:9}:"E = "
+#endif
+
+  using S::T; // expected-error{{class member}}
+#if __cplusplus < 201103L
+  // expected-note@-2 {{use a typedef declaration instead}}
+  // CXX98: fix-it:"{{.*}}":{[[@LINE-3]]:3-[[@LINE-3]]:8}:"typedef"
+  // CXX98: fix-it:"{{.*}}":{[[@LINE-4]]:13-[[@LINE-4]]:13}:" T"
+#else
+  // expected-note@-6 {{use an alias declaration instead}}
+  // CXX11: fix-it:"{{.*}}":{[[@LINE-7]]:9-[[@LINE-7]]:9}:"T = "
+#endif
+
+  using S::f; // expected-error{{class member}}
+  using S::g; // expected-error{{class member}}
 }
diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.align/p5.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.align/p5.cpp
index 10be98d..3c250f9 100644
--- a/test/CXX/dcl.dcl/dcl.attr/dcl.align/p5.cpp
+++ b/test/CXX/dcl.dcl/dcl.attr/dcl.align/p5.cpp
@@ -9,6 +9,7 @@
 alignas(1) int n7 alignas(2), // expected-error {{less than minimum alignment}}
                n8 alignas(4); // ok
 alignas(8) int n9 alignas(2); // ok, overaligned
+alignas(1) extern int n10; // expected-error {{less than minimum alignment}}
 
 enum alignas(1) E1 {}; // expected-error {{requested alignment is less than minimum alignment of 4 for type 'E1'}}
 enum alignas(1) E2 : char {}; // ok
diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp
index 2111939..3bbbf9e 100644
--- a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp
+++ b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp
@@ -1,25 +1,25 @@
 // RUN: %clang_cc1 -std=c++1y -verify %s
 
-class [[deprecated]] C {}; // expected-note {{declared here}}
+class [[deprecated]] C {}; // expected-note {{'C' has been explicitly marked deprecated here}}
 C c; // expected-warning {{'C' is deprecated}}
 
-typedef int t [[deprecated]]; // expected-note {{declared here}}
+typedef int t [[deprecated]]; // expected-note {{'t' has been explicitly marked deprecated here}}
 t x = 42; // expected-warning {{'t' is deprecated}}
 
-[[deprecated]] int old = 42; // expected-note {{declared here}}
+[[deprecated]] int old = 42; // expected-note {{'old' has been explicitly marked deprecated here}}
 int use = old; // expected-warning {{'old' is deprecated}}
 
-struct S { [[deprecated]] int member = 42; } s; // expected-note {{declared here}}
+struct S { [[deprecated]] int member = 42; } s; // expected-note {{'member' has been explicitly marked deprecated here}}
 int use2 = s.member; // expected-warning {{'member' is deprecated}}
 
-[[deprecated]] int f() { return 42; } // expected-note {{declared here}}
+[[deprecated]] int f() { return 42; } // expected-note {{'f' has been explicitly marked deprecated here}}
 int use3 = f(); // expected-warning {{'f' is deprecated}}
 
-enum [[deprecated]] e { E }; // expected-note {{declared here}}
+enum [[deprecated]] e { E }; // expected-note {{'e' has been explicitly marked deprecated here}}
 e my_enum; // expected-warning {{'e' is deprecated}}
 
 template <typename T> class X {};
-template <> class [[deprecated]] X<int> {}; // expected-note {{declared here}}
+template <> class [[deprecated]] X<int> {}; // expected-note {{'X<int>' has been explicitly marked deprecated here}}
 X<char> x1;
 // FIXME: The diagnostic here could be much better by mentioning X<int>.
 X<int> x2; // expected-warning {{'X' is deprecated}}
diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.noreturn/p1.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.noreturn/p1.cpp
index 0af241f..59cac36 100644
--- a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.noreturn/p1.cpp
+++ b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.noreturn/p1.cpp
@@ -13,7 +13,7 @@
 [[noreturn()]] void c(); // expected-error {{attribute 'noreturn' cannot have an argument list}}
 
 void d() [[noreturn]]; // expected-error {{'noreturn' attribute cannot be applied to types}}
-int d2 [[noreturn]]; // expected-error {{'noreturn' attribute only applies to functions and methods}}
+int d2 [[noreturn]]; // expected-error {{'noreturn' attribute only applies to functions}}
 
 [[noreturn]] int e() { b2(); } // ok
 
diff --git a/test/CXX/dcl.dcl/dcl.enum/p2.cpp b/test/CXX/dcl.dcl/dcl.enum/p2.cpp
new file mode 100644
index 0000000..de826d0
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.enum/p2.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+// expected-no-diagnostics
+enum class E : int const volatile { };
+using T = __underlying_type(E);
+using T = int;
diff --git a/test/CXX/dcl.dcl/dcl.link/p2.cpp b/test/CXX/dcl.dcl/dcl.link/p2.cpp
new file mode 100644
index 0000000..d1c3bcb
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.link/p2.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+extern "C" {
+  extern R"(C++)" { }
+}
+
+#define plusplus "++"
+extern "C" plusplus {
+}
+
+extern u8"C" {} // expected-error {{string literal in language linkage specifier cannot have an encoding-prefix}}
+extern L"C" {} // expected-error {{string literal in language linkage specifier cannot have an encoding-prefix}}
+extern u"C++" {} // expected-error {{string literal in language linkage specifier cannot have an encoding-prefix}}
+extern U"C" {} // expected-error {{string literal in language linkage specifier cannot have an encoding-prefix}}
diff --git a/test/CXX/dcl.dcl/dcl.link/p7.cpp b/test/CXX/dcl.dcl/dcl.link/p7.cpp
index bd9ff3c..7d80a22 100644
--- a/test/CXX/dcl.dcl/dcl.link/p7.cpp
+++ b/test/CXX/dcl.dcl/dcl.link/p7.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
 
 struct X { };
 
@@ -7,8 +7,6 @@
 // CHECK: @x2 = external global %struct.X
 // CHECK: @x3 = external global %struct.X
 extern "C" {
-
-
   X x1;
 }
 
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
index cf42297..08fefdc 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
@@ -27,7 +27,7 @@
 struct s2 {
   constexpr int mi1; // expected-error {{non-static data member cannot be constexpr; did you intend to make it const?}}
   static constexpr int mi2; // expected-error {{requires an initializer}}
-  mutable constexpr int mi3 = 3; // expected-error-re {{non-static data member cannot be constexpr$}} expected-error {{'mutable' and 'const' cannot be mixed}}
+  mutable constexpr int mi3 = 3; // expected-error-re {{non-static data member cannot be constexpr{{$}}}} expected-error {{'mutable' and 'const' cannot be mixed}}
 };
 // typedef
 typedef constexpr int CI; // expected-error {{typedef cannot be constexpr}}
@@ -73,7 +73,7 @@
 struct S {
   template<typename T> constexpr T f(); // expected-warning {{C++1y}}
   template <typename T>
-  T g() const; // expected-note {{candidate template ignored: could not match 'T () const' against 'char ()'}}
+  T g() const; // expected-note-re {{candidate template ignored: could not match 'T (){{( __attribute__\(\(thiscall\)\))?}} const' against 'char (){{( __attribute__\(\(thiscall\)\))?}}'}}
 };
 
 // explicit specialization can differ in constepxr
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p2.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p2.cpp
index 001a086..eeb5b6f 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p2.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p2.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm -triple %itanium_abi_triple %s -o - | FileCheck %s
 
 // constexpr functions and constexpr constructors are implicitly inline.
 struct S {
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp
index bb7f7ac..370f732 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p6.cpp
@@ -35,7 +35,7 @@
   constexpr R F() const { return 0; }
 };
 constexpr int d = ConstexprMember<int>().F(); // ok
-constexpr int e = ConstexprMember<NonLiteral>().F(); // expected-error {{constant expression}}
+constexpr int e = ConstexprMember<NonLiteral>().F(); // expected-error {{constant expression}} expected-note {{non-literal type 'const NonLiteral' cannot be used in a constant expression}}
 
 template<typename ...P> struct ConstexprCtor {
   constexpr ConstexprCtor(P...) {}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p4.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p4.cpp
index 07eec1e..12237a3 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p4.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p4.cpp
@@ -1,7 +1,6 @@
-// RUN: %clang_cc1 -verify %s
-// XFAIL: *
+// RUN: %clang_cc1 -fsyntax-only -verify %s
 
-void f0() {
+void f0() { // expected-note {{previous definition is here}}
 }
 
-inline void f0(); // expected-error {{function definition cannot precede inline declaration}}
+inline void f0(); // expected-error {{inline declaration of 'f0' follows non-inline definition}}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p6.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p6.cpp
index ee870d9..5d1e6fb 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p6.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.fct.spec/p6.cpp
@@ -14,3 +14,7 @@
 explicit A::A() { } // expected-error {{'explicit' can only be specified inside the class definition}}
 explicit A::operator bool() { return false; }  // expected-warning {{explicit conversion functions are a C++11 extension}}\
                                                // expected-error {{'explicit' can only be specified inside the class definition}}
+
+class B {
+  friend explicit A::A(); // expected-error {{'explicit' is invalid in friend declarations}}
+};
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p10.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p10.cpp
index fd86276..d7e7c52 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p10.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p10.cpp
@@ -1,5 +1,4 @@
-// RUN: %clang_cc1 -verify %s
-// XFAIL: *
+// RUN: %clang_cc1 -fsyntax-only -verify %s
 
 typedef const int T0;
 typedef int& T1;
@@ -9,6 +8,6 @@
   mutable T0 f1; // expected-error{{'mutable' and 'const' cannot be mixed}}
   mutable int &f2; // expected-error{{'mutable' cannot be applied to references}}
   mutable T1 f3; // expected-error{{'mutable' cannot be applied to references}}
-  mutable struct s1 {}; // expected-error{{'mutable' cannot be applied to non-data members}}
+  mutable struct s1 {}; // expected-error{{'mutable' can only be applied to member variables}}
   mutable void im0(); // expected-error{{'mutable' cannot be applied to functions}}
 };
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 84f9f9b..46c874f 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
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++1y
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -Wno-c++1y-extensions
 // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++98 -Wno-c++11-extensions
 
 template<typename T>
@@ -41,3 +42,25 @@
 };
 const int S::b;
 const auto S::c = 0;
+
+namespace std { template<typename T> struct initializer_list { initializer_list(); }; }
+
+// In an initializer of the form ( expression-list ), the expression-list
+// shall be a single assigment-expression.
+auto parens1(1);
+auto parens2(2, 3); // expected-error {{initializer for variable 'parens2' with type 'auto' contains multiple expressions}}
+#if __cplusplus >= 201103L
+auto parens3({4, 5, 6}); // expected-error {{cannot deduce type for variable 'parens3' with type 'auto' from parenthesized initializer list}}
+auto parens4 = [p4(1)] {};
+auto parens5 = [p5(2, 3)] {}; // expected-error {{initializer for lambda capture 'p5' contains multiple expressions}}
+auto parens6 = [p6({4, 5, 6})] {}; // expected-error {{cannot deduce type for lambda capture 'p6' from parenthesized initializer list}}
+#endif
+
+#if __cplusplus >= 201402L
+namespace std_example {
+  // The other half of this example is in p3.cpp
+  auto f() -> int;
+  auto g() { return 0.0; }
+  auto h();
+}
+#endif
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp
index 1ed93b1..7f1b3b0 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.simple/p5-cxx0x.cpp
@@ -30,29 +30,33 @@
   typedef int n;
 };
 
+PD pd();
+DD dd();
+
 struct A {
-  decltype(PD()) s; // ok
-  decltype(PD())::n n; // ok
-  decltype(DD()) *p = new decltype(DD()); // ok
+  decltype(pd()) s; // ok
+  decltype(pd())::n n; // ok
+  decltype(dd()) *p = new decltype(dd()); // ok
 };
+A a();
 
 // Two errors here: one for the decltype, one for the variable.
 decltype(
-    PD(), // expected-error {{private destructor}}
-    PD()) pd1; // expected-error {{private destructor}}
-decltype(DD(), // expected-error {{deleted function}}
-         DD()) dd1;
-decltype(A(),
-         DD()) dd2; // expected-error {{deleted function}}
+    pd(), // expected-error {{private destructor}}
+    pd()) pd1; // expected-error {{private destructor}}
+decltype(dd(), // expected-error {{deleted function}}
+         dd()) dd1;
+decltype(a(),
+         dd()) dd2; // expected-error {{deleted function}}
 decltype(
-    PD(), // expected-error {{temporary of type 'PD' has private destructor}}
+    pd(), // expected-error {{temporary of type 'PD' has private destructor}}
     0) pd2;
 
-decltype(((13, ((DD())))))::n dd_parens; // ok
-decltype(((((42)), PD())))::n pd_parens_comma; // ok
+decltype(((13, ((dd())))))::n dd_parens; // ok
+decltype(((((42)), pd())))::n pd_parens_comma; // ok
 
 // Ensure parens aren't stripped from a decltype node.
-extern decltype(PD()) pd_ref; // ok
+extern decltype(pd()) pd_ref; // ok
 decltype((pd_ref)) pd_ref3 = pd_ref; // ok, PD &
 decltype(pd_ref) pd_ref2 = pd_ref; // expected-error {{private destructor}}
 
@@ -107,7 +111,7 @@
 
 namespace Overload {
   DD operator+(PD &a, PD &b);
-  decltype(PD()) *pd_ptr;
+  decltype(pd()) *pd_ptr;
   decltype(*pd_ptr + *pd_ptr) *dd_ptr; // ok
 
   decltype(0, *pd_ptr) pd_ref2 = pd_ref; // ok
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp
index 02cc973..39d6e70 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp
@@ -2,12 +2,12 @@
 
 using X = struct { // ok
 };
-template<typename T> using Y = struct { // expected-error {{can not be defined in a type alias template}}
+template<typename T> using Y = struct { // expected-error {{cannot be defined in a type alias template}}
 };
 
 class K {
   virtual ~K();
-  operator struct S {} (); // expected-error{{'K::S' can not be defined in a type specifier}}
+  operator struct S {} (); // expected-error{{'K::S' cannot be defined in a type specifier}}
 };
 
 struct A {};
@@ -18,26 +18,26 @@
   for (struct S { S(int) {} } s : arr) { // expected-error {{types may not be defined in a for range declaration}}
   }
 
-  new struct T {}; // expected-error {{'T' can not be defined in a type specifier}}
-  new struct A {}; // expected-error {{'A' can not be defined in a type specifier}}
+  new struct T {}; // expected-error {{'T' cannot be defined in a type specifier}}
+  new struct A {}; // expected-error {{'A' cannot be defined in a type specifier}}
 
-  try {} catch (struct U {}) {} // expected-error {{'U' can not be defined in a type specifier}}
+  try {} catch (struct U {}) {} // expected-error {{'U' cannot be defined in a type specifier}}
 
-  (void)(struct V { V(int); })0; // expected-error {{'V' can not be defined in a type specifier}}
+  (void)(struct V { V(int); })0; // expected-error {{'V' cannot be defined in a type specifier}}
 
-  (void)dynamic_cast<struct W {}*>((K*)0); // expected-error {{'W' can not be defined in a type specifier}}
-  (void)static_cast<struct X {}*>(0); // expected-error {{'X' can not be defined in a type specifier}}
-  (void)reinterpret_cast<struct Y {}*>(0); // expected-error {{'Y' can not be defined in a type specifier}}
-  (void)const_cast<struct Z {}*>((const Z*)0); // expected-error {{'Z' can not be defined in a type specifier}}
+  (void)dynamic_cast<struct W {}*>((K*)0); // expected-error {{'W' cannot be defined in a type specifier}}
+  (void)static_cast<struct X {}*>(0); // expected-error {{'X' cannot be defined in a type specifier}}
+  (void)reinterpret_cast<struct Y {}*>(0); // expected-error {{'Y' cannot be defined in a type specifier}}
+  (void)const_cast<struct Z {}*>((const Z*)0); // expected-error {{'Z' cannot be defined in a type specifier}}
 }
 
-void g() throw (struct Ex {}) { // expected-error {{'Ex' can not be defined in a type specifier}}
+void g() throw (struct Ex {}) { // expected-error {{'Ex' cannot be defined in a type specifier}}
 }
 
-alignas(struct Aa {}) int x; // expected-error {{'Aa' can not be defined in a type specifier}}
+alignas(struct Aa {}) int x; // expected-error {{'Aa' cannot be defined in a type specifier}}
 
-int a = sizeof(struct So {}); // expected-error {{'So' can not be defined in a type specifier}}
-int b = alignof(struct Ao {}); // expected-error {{'Ao' can not be defined in a type specifier}}
+int a = sizeof(struct So {}); // expected-error {{'So' cannot be defined in a type specifier}}
+int b = alignof(struct Ao {}); // expected-error {{'Ao' cannot be defined in a type specifier}}
 
 namespace std { struct type_info; }
-const std::type_info &ti = typeid(struct Ti {}); // expected-error {{'Ti' can not be defined in a type specifier}}
+const std::type_info &ti = typeid(struct Ti {}); // expected-error {{'Ti' cannot be defined in a type specifier}}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp
index 89a28ad..cc44f74 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp
@@ -154,5 +154,5 @@
 namespace VoidArg {
   using V = void;
   V f(int); // ok
-  V g(V); // expected-error {{empty parameter list defined with a type alias of 'void' not allowed}}
+  V g(V); // ok (DR577)
 }
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.list/basic.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.list/basic.cpp
index b30e0ec..b44b2c7 100644
--- a/test/CXX/dcl.decl/dcl.init/dcl.init.list/basic.cpp
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.list/basic.cpp
@@ -8,9 +8,9 @@
   template<typename T>
   void f(int i) {
     T x{i}; // expected-error{{non-constant-expression cannot be narrowed from type 'int' to 'float' in initializer list}} \
-    // expected-note{{override this message by inserting an explicit cast}}
+    // expected-note{{insert an explicit cast to silence this issue}}
     T y{i}; // expected-error{{non-constant-expression cannot be narrowed from type 'int' to 'float' in initializer list}} \
-    // expected-note{{override this message by inserting an explicit cast}}
+    // expected-note{{insert an explicit cast to silence this issue}}
   }
 
   template void f<float>(int); // expected-note{{in instantiation of function template specialization 'PR12453::f<float>' requested here}}
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp
index 58d03836..971e0c1 100644
--- a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp
@@ -23,7 +23,7 @@
 
 namespace bullet1 {
   double ad[] = { 1, 2.0 };
-  int ai[] = { 1, 2.0 };  // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}}
+  int ai[] = { 1, 2.0 };  // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{silence}}
 
   struct S2 {
     int m1;
@@ -31,7 +31,7 @@
   };
 
   S2 s21 = { 1, 2, 3.0 };
-  S2 s22 { 1.0, 2, 3 };  // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}}
+  S2 s22 { 1.0, 2, 3 };  // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{silence}}
   S2 s23 { };
 }
 
@@ -62,13 +62,13 @@
   };
 
   S s1 = { 1, 2, 3.0 };
-  S s2 { 1.0, 2, 3 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}}
+  S s2 { 1.0, 2, 3 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{silence}}
   S s3 {};
 }
 
 namespace bullet5 {
   int x1 {2};
-  int x2 {2.0};  // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}}
+  int x2 {2.0};  // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{silence}}
 }
 
 namespace bullet6 {
@@ -81,7 +81,7 @@
   const S& r2 = { "Spinach" };
   S& r3 = { 1, 2, 3 };  // expected-error {{non-const lvalue reference to type 'bullet6::S' cannot bind to an initializer list temporary}}
   const int& i1 = { 1 };
-  const int& i2 = { 1.1 };  // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}} expected-warning {{implicit conversion}}
+  const int& i2 = { 1.1 };  // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{silence}} expected-warning {{implicit conversion}}
   const int (&iar)[2] = { 1, 2 };
 }
 
@@ -92,20 +92,20 @@
 namespace bullet8 {
   struct A { int i; int j; };
   A a1 { 1, 2 };
-  A a2 { 1.2 };  // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}} expected-warning {{implicit conversion}}
+  A a2 { 1.2 };  // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{silence}} expected-warning {{implicit conversion}}
 
   struct B {
     B(std::initializer_list<int> i) {}
   };
   B b1 { 1, 2 };
-  B b2 { 1, 2.0 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}}
+  B b2 { 1, 2.0 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{silence}}
 
   struct C {
     C(int i, double j) {}
   };
   C c1 = { 1, 2.2 };
   // FIXME: Suppress the narrowing warning in the cases where we issue a narrowing error.
-  C c2 = { 1.1, 2 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}} expected-warning {{implicit conversion}}
+  C c2 = { 1.1, 2 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{silence}} expected-warning {{implicit conversion}}
 
   int j { 1 };
   int k { };
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x-fixits.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x-fixits.cpp
index 0bea4ed..299611b 100644
--- a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x-fixits.cpp
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x-fixits.cpp
@@ -26,7 +26,7 @@
   maybe_shrink_int((char)3);
   // CHECK: warning:{{.*}} cannot be narrowed
   // CHECK: note:{{.*}} in instantiation
-  // CHECK: note:{{.*}} override
+  // CHECK: note:{{.*}} silence
   // FIXME: This should be static_cast<T>.
   // CHECK: fix-it:{{.*}}"static_cast<char>("
   // CHECK: fix-it:{{.*}}")"
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp
index 9b1727f..42dee92 100644
--- a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp
@@ -8,16 +8,16 @@
   const int y = 999;
   const int z = 99;
   char c1 = x;  // OK, though it might narrow (in this case, it does narrow)
-  char c2{x};  // expected-error {{ cannot be narrowed }} expected-note {{override}}
-  char c3{y};  // expected-error {{ cannot be narrowed }} expected-note {{override}} expected-warning {{changes value}}
+  char c2{x};  // expected-error {{ cannot be narrowed }} expected-note {{silence}}
+  char c3{y};  // expected-error {{ cannot be narrowed }} expected-note {{silence}} expected-warning {{changes value}}
   char c4{z};  // OK: no narrowing needed
   unsigned char uc1 = {5};  // OK: no narrowing needed
-  unsigned char uc2 = {-1};  // expected-error {{ cannot be narrowed }} expected-note {{override}}
-  unsigned int ui1 = {-1};  // expected-error {{ cannot be narrowed }} expected-note {{override}}
+  unsigned char uc2 = {-1};  // expected-error {{ cannot be narrowed }} expected-note {{silence}}
+  unsigned int ui1 = {-1};  // expected-error {{ cannot be narrowed }} expected-note {{silence}}
   signed int si1 =
-    { (unsigned int)-1 };  // expected-error {{ cannot be narrowed }} expected-note {{override}}
-  int ii = {2.0};  // expected-error {{ cannot be narrowed }} expected-note {{override}}
-  float f1 { x };  // expected-error {{ cannot be narrowed }} expected-note {{override}}
+    { (unsigned int)-1 };  // expected-error {{ cannot be narrowed }} expected-note {{silence}}
+  int ii = {2.0};  // expected-error {{ cannot be narrowed }} expected-note {{silence}}
+  float f1 { x };  // expected-error {{ cannot be narrowed }} expected-note {{silence}}
   float f2 { 7 };  // OK: 7 can be exactly represented as a float
   int f(int);
   int a[] =
@@ -44,19 +44,19 @@
 // * from a floating-point type to an integer type, or
 
 void float_to_int() {
-  Agg<char> a1 = {1.0F};  // expected-error {{type 'float' cannot be narrowed to 'char'}} expected-note {{override}}
-  Agg<char> a2 = {1.0};  // expected-error {{ cannot be narrowed }} expected-note {{override}}
-  Agg<char> a3 = {1.0L};  // expected-error {{ cannot be narrowed }} expected-note {{override}}
+  Agg<char> a1 = {1.0F};  // expected-error {{type 'float' cannot be narrowed to 'char'}} expected-note {{silence}}
+  Agg<char> a2 = {1.0};  // expected-error {{ cannot be narrowed }} expected-note {{silence}}
+  Agg<char> a3 = {1.0L};  // expected-error {{ cannot be narrowed }} expected-note {{silence}}
 
   float f = 1.0;
   double d = 1.0;
   long double ld = 1.0;
-  Agg<char> a4 = {f};  // expected-error {{ cannot be narrowed }} expected-note {{override}}
-  Agg<char> a5 = {d};  // expected-error {{ cannot be narrowed }} expected-note {{override}}
-  Agg<char> a6 = {ld};  // expected-error {{ cannot be narrowed }} expected-note {{override}}
+  Agg<char> a4 = {f};  // expected-error {{ cannot be narrowed }} expected-note {{silence}}
+  Agg<char> a5 = {d};  // expected-error {{ cannot be narrowed }} expected-note {{silence}}
+  Agg<char> a6 = {ld};  // expected-error {{ cannot be narrowed }} expected-note {{silence}}
 
-  Agg<char> ce1 = { Convert<float>(1.0) }; // expected-error {{type 'float' cannot be narrowed to 'char'}} expected-note {{override}}
-  Agg<char> ce2 = { ConvertVar<double>() }; // expected-error {{type 'double' cannot be narrowed to 'char'}} expected-note {{override}}
+  Agg<char> ce1 = { Convert<float>(1.0) }; // expected-error {{type 'float' cannot be narrowed to 'char'}} expected-note {{silence}}
+  Agg<char> ce2 = { ConvertVar<double>() }; // expected-error {{type 'double' cannot be narrowed to 'char'}} expected-note {{silence}}
 }
 
 // * from long double to double or float, or from double to float, except where
@@ -72,8 +72,8 @@
 
   // Variables.
   Agg<float> f1 = {f};  // OK  (no-op)
-  Agg<float> f2 = {d};  // expected-error {{non-constant-expression cannot be narrowed from type 'double' to 'float'}} expected-note {{override}}
-  Agg<float> f3 = {ld};  // expected-error {{ cannot be narrowed }} expected-note {{override}}
+  Agg<float> f2 = {d};  // expected-error {{non-constant-expression cannot be narrowed from type 'double' to 'float'}} expected-note {{silence}}
+  Agg<float> f3 = {ld};  // expected-error {{ cannot be narrowed }} expected-note {{silence}}
   // Exact constants.
   Agg<float> f4 = {1.0};  // OK  (double constant represented exactly)
   Agg<float> f5 = {1.0L};  // OK  (long double constant represented exactly)
@@ -81,8 +81,8 @@
   Agg<float> f6 = {0.1};  // OK (double constant in range but rounded)
   Agg<float> f7 = {0.1L};  // OK (long double constant in range but rounded)
   // Out of range constants.
-  Agg<float> f8 = {1E50};  // expected-error {{constant expression evaluates to 1.000000e+50 which cannot be narrowed to type 'float'}} expected-note {{override}}
-  Agg<float> f9 = {1E50L};  // expected-error {{ cannot be narrowed }} expected-note {{override}}
+  Agg<float> f8 = {1E50};  // expected-error {{constant expression evaluates to 1.000000e+50 which cannot be narrowed to type 'float'}} expected-note {{silence}}
+  Agg<float> f9 = {1E50L};  // expected-error {{ cannot be narrowed }} expected-note {{silence}}
   // More complex constant expression.
   constexpr long double e40 = 1E40L, e30 = 1E30L, e39 = 1E39L;
   Agg<float> f10 = {e40 - 5 * e39 + e30 - 5 * e39};  // OK
@@ -90,19 +90,19 @@
   // Variables.
   Agg<double> d1 = {f};  // OK  (widening)
   Agg<double> d2 = {d};  // OK  (no-op)
-  Agg<double> d3 = {ld};  // expected-error {{ cannot be narrowed }} expected-note {{override}}
+  Agg<double> d3 = {ld};  // expected-error {{ cannot be narrowed }} expected-note {{silence}}
   // Exact constant.
   Agg<double> d4 = {1.0L};  // OK  (long double constant represented exactly)
   // Inexact but in-range constant.
   Agg<double> d5 = {0.1L};  // OK (long double constant in range but rounded)
   // Out of range constant.
-  Agg<double> d6 = {1E315L};  // expected-error {{ cannot be narrowed }} expected-note {{override}}
+  Agg<double> d6 = {1E315L};  // expected-error {{ cannot be narrowed }} expected-note {{silence}}
   // More complex constant expression.
   constexpr long double e315 = 1E315L, e305 = 1E305L, e314 = 1E314L;
   Agg<double> d7 = {e315 - 5 * e314 + e305 - 5 * e314};  // OK
 
-  Agg<float> ce1 = { Convert<double>(1e300) }; // expected-error {{constant expression evaluates to 1.000000e+300 which cannot be narrowed to type 'float'}} expected-note {{override}}
-  Agg<double> ce2 = { ConvertVar<long double>() }; // expected-error {{non-constant-expression cannot be narrowed from type 'long double' to 'double'}} expected-note {{override}}
+  Agg<float> ce1 = { Convert<double>(1e300) }; // expected-error {{constant expression evaluates to 1.000000e+300 which cannot be narrowed to type 'float'}} expected-note {{silence}}
+  Agg<double> ce2 = { ConvertVar<long double>() }; // expected-error {{non-constant-expression cannot be narrowed from type 'long double' to 'double'}} expected-note {{silence}}
 }
 
 // * from an integer type or unscoped enumeration type to a floating-point type,
@@ -114,16 +114,16 @@
   char c = 1;
 
   // Variables.  Yes, even though all char's will fit into any floating type.
-  Agg<float> f1 = {c};  // expected-error {{ cannot be narrowed }} expected-note {{override}}
-  Agg<double> f2 = {c};  // expected-error {{ cannot be narrowed }} expected-note {{override}}
-  Agg<long double> f3 = {c};  // expected-error {{ cannot be narrowed }} expected-note {{override}}
+  Agg<float> f1 = {c};  // expected-error {{ cannot be narrowed }} expected-note {{silence}}
+  Agg<double> f2 = {c};  // expected-error {{ cannot be narrowed }} expected-note {{silence}}
+  Agg<long double> f3 = {c};  // expected-error {{ cannot be narrowed }} expected-note {{silence}}
 
   // Constants.
   Agg<float> f4 = {12345678};  // OK (exactly fits in a float)
-  Agg<float> f5 = {123456789};  // expected-error {{ cannot be narrowed }} expected-note {{override}}
+  Agg<float> f5 = {123456789};  // expected-error {{ cannot be narrowed }} expected-note {{silence}}
 
-  Agg<float> ce1 = { Convert<int>(123456789) }; // expected-error {{constant expression evaluates to 123456789 which cannot be narrowed to type 'float'}} expected-note {{override}}
-  Agg<double> ce2 = { ConvertVar<long long>() }; // expected-error {{non-constant-expression cannot be narrowed from type 'long long' to 'double'}} expected-note {{override}}
+  Agg<float> ce1 = { Convert<int>(123456789) }; // expected-error {{constant expression evaluates to 123456789 which cannot be narrowed to type 'float'}} expected-note {{silence}}
+  Agg<double> ce2 = { ConvertVar<long long>() }; // expected-error {{non-constant-expression cannot be narrowed from type 'long long' to 'double'}} expected-note {{silence}}
 }
 
 // * from an integer type or unscoped enumeration type to an integer type that
@@ -135,52 +135,53 @@
   // Not a constant expression.
   short s = 1;
   unsigned short us = 1;
-  Agg<char> c1 = {s};  // expected-error {{ cannot be narrowed }} expected-note {{override}}
-  Agg<unsigned short> s1 = {s};  // expected-error {{ cannot be narrowed }} expected-note {{override}}
-  Agg<short> s2 = {us};  // expected-error {{ cannot be narrowed }} expected-note {{override}}
+  Agg<char> c1 = {s};  // expected-error {{ cannot be narrowed }} expected-note {{silence}}
+  Agg<unsigned short> s1 = {s};  // expected-error {{ cannot be narrowed }} expected-note {{silence}}
+  Agg<short> s2 = {us};  // expected-error {{ cannot be narrowed }} expected-note {{silence}}
 
   // "that cannot represent all the values of the original type" means that the
   // validity of the program depends on the relative sizes of integral types.
   // This test compiles with -m64, so sizeof(int)<sizeof(long)==sizeof(long
   // long).
   long l1 = 1;
-  Agg<int> i1 = {l1};  // expected-error {{ cannot be narrowed }} expected-note {{override}}
+  Agg<int> i1 = {l1};  // expected-error {{ cannot be narrowed }} expected-note {{silence}}
   long long ll = 1;
   Agg<long> l2 = {ll};  // OK
 
   // Constants.
   Agg<char> c2 = {127};  // OK
-  Agg<char> c3 = {300};  // expected-error {{ cannot be narrowed }} expected-note {{override}} expected-warning {{changes value}}
+  Agg<char> c3 = {300};  // expected-error {{ cannot be narrowed }} expected-note {{silence}} expected-warning {{changes value}}
 
   Agg<int> i2 = {0x7FFFFFFFU};  // OK
-  Agg<int> i3 = {0x80000000U};  // expected-error {{ cannot be narrowed }} expected-note {{override}}
-  Agg<unsigned int> i4 = {-0x80000000L};  // expected-error {{ cannot be narrowed }} expected-note {{override}}
+  Agg<int> i3 = {0x80000000U};  // expected-error {{ cannot be narrowed }} expected-note {{silence}}
+  Agg<unsigned int> i4 = {-0x80000000L};  // expected-error {{ cannot be narrowed }} expected-note {{silence}}
 
   // Bool is also an integer type, but conversions to it are a different AST
   // node.
   Agg<bool> b1 = {0};  // OK
   Agg<bool> b2 = {1};  // OK
-  Agg<bool> b3 = {-1};  // expected-error {{ cannot be narrowed }} expected-note {{override}}
+  Agg<bool> b3 = {-1};  // expected-error {{ cannot be narrowed }} expected-note {{silence}}
 
   // Conversions from pointers to booleans aren't narrowing conversions.
-  Agg<bool> b = {&b1};  // OK
+  Agg<bool>* ptr = &b1;
+  Agg<bool> b = {ptr};  // OK
 
-  Agg<short> ce1 = { Convert<int>(100000) }; // expected-error {{constant expression evaluates to 100000 which cannot be narrowed to type 'short'}} expected-note {{override}} expected-warning {{changes value from 100000 to -31072}}
-  Agg<char> ce2 = { ConvertVar<short>() }; // expected-error {{non-constant-expression cannot be narrowed from type 'short' to 'char'}} expected-note {{override}}
+  Agg<short> ce1 = { Convert<int>(100000) }; // expected-error {{constant expression evaluates to 100000 which cannot be narrowed to type 'short'}} expected-note {{silence}} expected-warning {{changes value from 100000 to -31072}}
+  Agg<char> ce2 = { ConvertVar<short>() }; // expected-error {{non-constant-expression cannot be narrowed from type 'short' to 'char'}} expected-note {{silence}}
 
   // Negative -> larger unsigned type.
-  unsigned long long ll1 = { -1 }; // expected-error {{ -1 which cannot be narrowed}} expected-note {{override}}
+  unsigned long long ll1 = { -1 }; // expected-error {{ -1 which cannot be narrowed}} expected-note {{silence}}
   unsigned long long ll2 = { 1 }; // OK
-  unsigned long long ll3 = { s }; // expected-error {{cannot be narrowed from type 'short'}} expected-note {{override}}
+  unsigned long long ll3 = { s }; // expected-error {{cannot be narrowed from type 'short'}} expected-note {{silence}}
   unsigned long long ll4 = { us }; // OK
-  unsigned long long ll5 = { ll }; // expected-error {{cannot be narrowed from type 'long long'}} expected-note {{override}}
-  Agg<unsigned long long> ll6 = { -1 }; // expected-error {{ -1 which cannot be narrowed}} expected-note {{override}}
+  unsigned long long ll5 = { ll }; // expected-error {{cannot be narrowed from type 'long long'}} expected-note {{silence}}
+  Agg<unsigned long long> ll6 = { -1 }; // expected-error {{ -1 which cannot be narrowed}} expected-note {{silence}}
   Agg<unsigned long long> ll7 = { 18446744073709551615ULL }; // OK
-  Agg<unsigned long long> ll8 = { __int128(18446744073709551615ULL) + 1 }; // expected-error {{ 18446744073709551616 which cannot be narrowed}} expected-note {{override}} expected-warning {{changes value}}
+  Agg<unsigned long long> ll8 = { __int128(18446744073709551615ULL) + 1 }; // expected-error {{ 18446744073709551616 which cannot be narrowed}} expected-note {{silence}} expected-warning {{changes value}}
   signed char c = 'x';
-  unsigned short usc1 = { c }; // expected-error {{non-constant-expression cannot be narrowed from type 'signed char'}} expected-note {{override}}
+  unsigned short usc1 = { c }; // expected-error {{non-constant-expression cannot be narrowed from type 'signed char'}} expected-note {{silence}}
   unsigned short usc2 = { (signed char)'x' }; // OK
-  unsigned short usc3 = { (signed char)-1 }; // expected-error {{ -1 which cannot be narrowed}} expected-note {{override}}
+  unsigned short usc3 = { (signed char)-1 }; // expected-error {{ -1 which cannot be narrowed}} expected-note {{silence}}
 }
 
 // Be sure that type- and value-dependent expressions in templates get the error
@@ -188,9 +189,9 @@
 
 template<int I, typename T>
 void maybe_shrink_int(T t) {
-  Agg<short> s1 = {t};  // expected-error {{ cannot be narrowed }} expected-note {{override}}
-  Agg<short> s2 = {I};  // expected-error {{ cannot be narrowed }} expected-note {{override}} expected-warning {{changes value}}
-  Agg<T> t2 = {700};  // expected-error {{ cannot be narrowed }} expected-note {{override}} expected-warning {{changes value}}
+  Agg<short> s1 = {t};  // expected-error {{ cannot be narrowed }} expected-note {{silence}}
+  Agg<short> s2 = {I};  // expected-error {{ cannot be narrowed }} expected-note {{silence}} expected-warning {{changes value}}
+  Agg<T> t2 = {700};  // expected-error {{ cannot be narrowed }} expected-note {{silence}} expected-warning {{changes value}}
 }
 
 void test_template() {
@@ -203,9 +204,9 @@
 
 void test_qualifiers(int i) {
   const int j = i;
-  struct {const unsigned char c;} c1 = {j};  // expected-error {{from type 'int' to 'unsigned char' in}} expected-note {{override}}
+  struct {const unsigned char c;} c1 = {j};  // expected-error {{from type 'int' to 'unsigned char' in}} expected-note {{silence}}
   // Template arguments make it harder to avoid printing qualifiers:
-  Agg<const unsigned char> c2 = {j};  // expected-error {{from type 'int' to 'const unsigned char' in}} expected-note {{override}}
+  Agg<const unsigned char> c2 = {j};  // expected-error {{from type 'int' to 'const unsigned char' in}} expected-note {{silence}}
 }
 
 // Test SFINAE checks.
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-cxx11-nowarn.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-cxx11-nowarn.cpp
index 4bcf113..d4d8198 100644
--- a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-cxx11-nowarn.cpp
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-cxx11-nowarn.cpp
@@ -9,16 +9,16 @@
   const int y = 999;
   const int z = 99;
   char c1 = x;  // OK, though it might narrow (in this case, it does narrow)
-  char c2{x};  // expected-warning {{ cannot be narrowed }} expected-note {{override}}
-  char c3{y};  // expected-warning {{ cannot be narrowed }} expected-note {{override}} expected-warning {{changes value}}
+  char c2{x};  // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
+  char c3{y};  // expected-warning {{ cannot be narrowed }} expected-note {{silence}} expected-warning {{changes value}}
   char c4{z};  // OK: no narrowing needed
   unsigned char uc1 = {5};  // OK: no narrowing needed
-  unsigned char uc2 = {-1};  // expected-warning {{ cannot be narrowed }} expected-note {{override}}
-  unsigned int ui1 = {-1};  // expected-warning {{ cannot be narrowed }} expected-note {{override}}
+  unsigned char uc2 = {-1};  // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
+  unsigned int ui1 = {-1};  // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
   signed int si1 =
-    { (unsigned int)-1 };  // expected-warning {{ cannot be narrowed }} expected-note {{override}}
-  int ii = {2.0};  // expected-warning {{ cannot be narrowed }} expected-note {{override}}
-  float f1 { x };  // expected-warning {{ cannot be narrowed }} expected-note {{override}}
+    { (unsigned int)-1 };  // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
+  int ii = {2.0};  // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
+  float f1 { x };  // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
   float f2 { 7 };  // OK: 7 can be exactly represented as a float
   int f(int);
   int a[] =
@@ -45,19 +45,19 @@
 // * from a floating-point type to an integer type, or
 
 void float_to_int() {
-  Agg<char> a1 = {1.0F};  // expected-warning {{type 'float' cannot be narrowed to 'char'}} expected-note {{override}}
-  Agg<char> a2 = {1.0};  // expected-warning {{ cannot be narrowed }} expected-note {{override}}
-  Agg<char> a3 = {1.0L};  // expected-warning {{ cannot be narrowed }} expected-note {{override}}
+  Agg<char> a1 = {1.0F};  // expected-warning {{type 'float' cannot be narrowed to 'char'}} expected-note {{silence}}
+  Agg<char> a2 = {1.0};  // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
+  Agg<char> a3 = {1.0L};  // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
 
   float f = 1.0;
   double d = 1.0;
   long double ld = 1.0;
-  Agg<char> a4 = {f};  // expected-warning {{ cannot be narrowed }} expected-note {{override}}
-  Agg<char> a5 = {d};  // expected-warning {{ cannot be narrowed }} expected-note {{override}}
-  Agg<char> a6 = {ld};  // expected-warning {{ cannot be narrowed }} expected-note {{override}}
+  Agg<char> a4 = {f};  // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
+  Agg<char> a5 = {d};  // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
+  Agg<char> a6 = {ld};  // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
 
-  Agg<char> ce1 = { Convert<float>(1.0) }; // expected-warning {{type 'float' cannot be narrowed to 'char'}} expected-note {{override}}
-  Agg<char> ce2 = { ConvertVar<double>() }; // expected-warning {{type 'double' cannot be narrowed to 'char'}} expected-note {{override}}
+  Agg<char> ce1 = { Convert<float>(1.0) }; // expected-warning {{type 'float' cannot be narrowed to 'char'}} expected-note {{silence}}
+  Agg<char> ce2 = { ConvertVar<double>() }; // expected-warning {{type 'double' cannot be narrowed to 'char'}} expected-note {{silence}}
 }
 
 // * from long double to double or float, or from double to float, except where
@@ -73,8 +73,8 @@
 
   // Variables.
   Agg<float> f1 = {f};  // OK  (no-op)
-  Agg<float> f2 = {d};  // expected-warning {{non-constant-expression cannot be narrowed from type 'double' to 'float'}} expected-note {{override}}
-  Agg<float> f3 = {ld};  // expected-warning {{ cannot be narrowed }} expected-note {{override}}
+  Agg<float> f2 = {d};  // expected-warning {{non-constant-expression cannot be narrowed from type 'double' to 'float'}} expected-note {{silence}}
+  Agg<float> f3 = {ld};  // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
   // Exact constants.
   Agg<float> f4 = {1.0};  // OK  (double constant represented exactly)
   Agg<float> f5 = {1.0L};  // OK  (long double constant represented exactly)
@@ -82,8 +82,8 @@
   Agg<float> f6 = {0.1};  // OK (double constant in range but rounded)
   Agg<float> f7 = {0.1L};  // OK (long double constant in range but rounded)
   // Out of range constants.
-  Agg<float> f8 = {1E50};  // expected-warning {{constant expression evaluates to 1.000000e+50 which cannot be narrowed to type 'float'}} expected-note {{override}}
-  Agg<float> f9 = {1E50L};  // expected-warning {{ cannot be narrowed }} expected-note {{override}}
+  Agg<float> f8 = {1E50};  // expected-warning {{constant expression evaluates to 1.000000e+50 which cannot be narrowed to type 'float'}} expected-note {{silence}}
+  Agg<float> f9 = {1E50L};  // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
   // More complex constant expression.
   constexpr long double e40 = 1E40L, e30 = 1E30L, e39 = 1E39L;
   Agg<float> f10 = {e40 - 5 * e39 + e30 - 5 * e39};  // OK
@@ -91,19 +91,19 @@
   // Variables.
   Agg<double> d1 = {f};  // OK  (widening)
   Agg<double> d2 = {d};  // OK  (no-op)
-  Agg<double> d3 = {ld};  // expected-warning {{ cannot be narrowed }} expected-note {{override}}
+  Agg<double> d3 = {ld};  // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
   // Exact constant.
   Agg<double> d4 = {1.0L};  // OK  (long double constant represented exactly)
   // Inexact but in-range constant.
   Agg<double> d5 = {0.1L};  // OK (long double constant in range but rounded)
   // Out of range constant.
-  Agg<double> d6 = {1E315L};  // expected-warning {{ cannot be narrowed }} expected-note {{override}}
+  Agg<double> d6 = {1E315L};  // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
   // More complex constant expression.
   constexpr long double e315 = 1E315L, e305 = 1E305L, e314 = 1E314L;
   Agg<double> d7 = {e315 - 5 * e314 + e305 - 5 * e314};  // OK
 
-  Agg<float> ce1 = { Convert<double>(1e300) }; // expected-warning {{constant expression evaluates to 1.000000e+300 which cannot be narrowed to type 'float'}} expected-note {{override}}
-  Agg<double> ce2 = { ConvertVar<long double>() }; // expected-warning {{non-constant-expression cannot be narrowed from type 'long double' to 'double'}} expected-note {{override}}
+  Agg<float> ce1 = { Convert<double>(1e300) }; // expected-warning {{constant expression evaluates to 1.000000e+300 which cannot be narrowed to type 'float'}} expected-note {{silence}}
+  Agg<double> ce2 = { ConvertVar<long double>() }; // expected-warning {{non-constant-expression cannot be narrowed from type 'long double' to 'double'}} expected-note {{silence}}
 }
 
 // * from an integer type or unscoped enumeration type to a floating-point type,
@@ -115,16 +115,16 @@
   char c = 1;
 
   // Variables.  Yes, even though all char's will fit into any floating type.
-  Agg<float> f1 = {c};  // expected-warning {{ cannot be narrowed }} expected-note {{override}}
-  Agg<double> f2 = {c};  // expected-warning {{ cannot be narrowed }} expected-note {{override}}
-  Agg<long double> f3 = {c};  // expected-warning {{ cannot be narrowed }} expected-note {{override}}
+  Agg<float> f1 = {c};  // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
+  Agg<double> f2 = {c};  // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
+  Agg<long double> f3 = {c};  // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
 
   // Constants.
   Agg<float> f4 = {12345678};  // OK (exactly fits in a float)
-  Agg<float> f5 = {123456789};  // expected-warning {{ cannot be narrowed }} expected-note {{override}}
+  Agg<float> f5 = {123456789};  // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
 
-  Agg<float> ce1 = { Convert<int>(123456789) }; // expected-warning {{constant expression evaluates to 123456789 which cannot be narrowed to type 'float'}} expected-note {{override}}
-  Agg<double> ce2 = { ConvertVar<long long>() }; // expected-warning {{non-constant-expression cannot be narrowed from type 'long long' to 'double'}} expected-note {{override}}
+  Agg<float> ce1 = { Convert<int>(123456789) }; // expected-warning {{constant expression evaluates to 123456789 which cannot be narrowed to type 'float'}} expected-note {{silence}}
+  Agg<double> ce2 = { ConvertVar<long long>() }; // expected-warning {{non-constant-expression cannot be narrowed from type 'long long' to 'double'}} expected-note {{silence}}
 }
 
 // * from an integer type or unscoped enumeration type to an integer type that
@@ -136,38 +136,39 @@
   // Not a constant expression.
   short s = 1;
   unsigned short us = 1;
-  Agg<char> c1 = {s};  // expected-warning {{ cannot be narrowed }} expected-note {{override}}
-  Agg<unsigned short> s1 = {s};  // expected-warning {{ cannot be narrowed }} expected-note {{override}}
-  Agg<short> s2 = {us};  // expected-warning {{ cannot be narrowed }} expected-note {{override}}
+  Agg<char> c1 = {s};  // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
+  Agg<unsigned short> s1 = {s};  // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
+  Agg<short> s2 = {us};  // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
 
   // "that cannot represent all the values of the original type" means that the
   // validity of the program depends on the relative sizes of integral types.
   // This test compiles with -m64, so sizeof(int)<sizeof(long)==sizeof(long
   // long).
   long l1 = 1;
-  Agg<int> i1 = {l1};  // expected-warning {{ cannot be narrowed }} expected-note {{override}}
+  Agg<int> i1 = {l1};  // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
   long long ll = 1;
   Agg<long> l2 = {ll};  // OK
 
   // Constants.
   Agg<char> c2 = {127};  // OK
-  Agg<char> c3 = {300};  // expected-warning {{ cannot be narrowed }} expected-note {{override}} expected-warning {{changes value}}
+  Agg<char> c3 = {300};  // expected-warning {{ cannot be narrowed }} expected-note {{silence}} expected-warning {{changes value}}
 
   Agg<int> i2 = {0x7FFFFFFFU};  // OK
-  Agg<int> i3 = {0x80000000U};  // expected-warning {{ cannot be narrowed }} expected-note {{override}}
-  Agg<unsigned int> i4 = {-0x80000000L};  // expected-warning {{ cannot be narrowed }} expected-note {{override}}
+  Agg<int> i3 = {0x80000000U};  // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
+  Agg<unsigned int> i4 = {-0x80000000L};  // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
 
   // Bool is also an integer type, but conversions to it are a different AST
   // node.
   Agg<bool> b1 = {0};  // OK
   Agg<bool> b2 = {1};  // OK
-  Agg<bool> b3 = {-1};  // expected-warning {{ cannot be narrowed }} expected-note {{override}}
+  Agg<bool> b3 = {-1};  // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
 
   // Conversions from pointers to booleans aren't narrowing conversions.
-  Agg<bool> b = {&b1};  // OK
+  Agg<bool>* ptr = &b1;
+  Agg<bool> b = {ptr};  // OK
 
-  Agg<short> ce1 = { Convert<int>(100000) }; // expected-warning {{constant expression evaluates to 100000 which cannot be narrowed to type 'short'}} expected-note {{override}} expected-warning {{changes value from 100000 to -31072}}
-  Agg<char> ce2 = { ConvertVar<short>() }; // expected-warning {{non-constant-expression cannot be narrowed from type 'short' to 'char'}} expected-note {{override}}
+  Agg<short> ce1 = { Convert<int>(100000) }; // expected-warning {{constant expression evaluates to 100000 which cannot be narrowed to type 'short'}} expected-note {{silence}} expected-warning {{changes value from 100000 to -31072}}
+  Agg<char> ce2 = { ConvertVar<short>() }; // expected-warning {{non-constant-expression cannot be narrowed from type 'short' to 'char'}} expected-note {{silence}}
 }
 
 // Be sure that type- and value-dependent expressions in templates get the warning
@@ -175,9 +176,9 @@
 
 template<int I, typename T>
 void maybe_shrink_int(T t) {
-  Agg<short> s1 = {t};  // expected-warning {{ cannot be narrowed }} expected-note {{override}}
-  Agg<short> s2 = {I};  // expected-warning {{ cannot be narrowed }} expected-note {{override}} expected-warning {{changes value}}
-  Agg<T> t2 = {700};  // expected-warning {{ cannot be narrowed }} expected-note {{override}} expected-warning {{changes value}}
+  Agg<short> s1 = {t};  // expected-warning {{ cannot be narrowed }} expected-note {{silence}}
+  Agg<short> s2 = {I};  // expected-warning {{ cannot be narrowed }} expected-note {{silence}} expected-warning {{changes value}}
+  Agg<T> t2 = {700};  // expected-warning {{ cannot be narrowed }} expected-note {{silence}} expected-warning {{changes value}}
 }
 
 void test_template() {
@@ -190,9 +191,9 @@
 
 void test_qualifiers(int i) {
   const int j = i;
-  struct {const unsigned char c;} c1 = {j};  // expected-warning {{from type 'int' to 'unsigned char' in}} expected-note {{override}}
+  struct {const unsigned char c;} c1 = {j};  // expected-warning {{from type 'int' to 'unsigned char' in}} expected-note {{silence}}
   // Template arguments make it harder to avoid printing qualifiers:
-  Agg<const unsigned char> c2 = {j};  // expected-warning {{from type 'int' to 'const unsigned char' in}} expected-note {{override}}
+  Agg<const unsigned char> c2 = {j};  // expected-warning {{from type 'int' to 'const unsigned char' in}} expected-note {{silence}}
 }
 
 // Make sure we still get the right SFINAE behavior.
diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-0x.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-0x.cpp
index 2ec1454..cec747e 100644
--- a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-0x.cpp
+++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-0x.cpp
@@ -22,13 +22,13 @@
 
 template<typename T = func_type_lvalue> struct wrap {
   typedef T val;
-  typedef T *ptr;
-  typedef T &ref;
+  typedef T *ptr; // expected-error-re 2{{pointer to function type '{{.*}}' cannot have '{{&|&&}}' qualifier}}
+  typedef T &ref; // expected-error-re 2{{reference to function type '{{.*}}' cannot have '{{&|&&}}' qualifier}}
 };
 
-using func_type_lvalue = wrap<>::val;
+using func_type_lvalue = wrap<>::val; // expected-note{{in instantiation of}}
 using func_type_lvalue = wrap<func_type_lvalue>::val;
-using func_type_rvalue = wrap<func_type_rvalue>::val;
+using func_type_rvalue = wrap<func_type_rvalue>::val; // expected-note{{in instantiation of}}
 
 using func_type_lvalue_ptr = wrap<>::ptr;
 using func_type_lvalue_ptr = wrap<func_type_lvalue>::ptr;
@@ -51,3 +51,10 @@
 
 
 void (f() &&); // expected-error{{non-member function cannot have '&&' qualifier}}
+
+// FIXME: These are ill-formed.
+template<typename T> struct pass {
+  void f(T);
+};
+pass<func_type_lvalue> pass0;
+pass<func_type_lvalue> pass1;
diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6.cpp
index e2d94fb..a035086 100644
--- a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6.cpp
+++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6.cpp
@@ -18,3 +18,16 @@
   friend void X::f() const;
   friend void ::f() const; // expected-error {{non-member function cannot have 'const' qualifier}}
 };
+
+template<typename T> struct S {
+  typedef T F;
+  typedef T *P; // expected-error {{pointer to function type 'void () const' cannot have 'const' qualifier}}
+  typedef T &R; // expected-error {{reference to function type 'void () const' cannot have 'const' qualifier}}
+};
+S<F> s; // expected-note {{in instantiation of}}
+
+// FIXME: This is ill-formed.
+template<typename T> struct U {
+  void f(T);
+};
+U<F> u;
diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p8.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p8.cpp
index ec1ccbf..0454412 100644
--- a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p8.cpp
+++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p8.cpp
@@ -1,8 +1,8 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 
 struct A { };
-A::A (enum { e1 }) {} // expected-error{{can not be defined in a parameter}}
-void A::f(enum { e2 }) {} // expected-error{{can not be defined in a parameter}}
+A::A (enum { e1 }) {} // expected-error{{cannot be defined in a parameter}}
+void A::f(enum { e2 }) {} // expected-error{{cannot be defined in a parameter}}
 
-enum { e3 } A::g() { } // expected-error{{can not be defined in the result type}} \
+enum { e3 } A::g() { } // expected-error{{cannot be defined in the result type}} \
 // expected-error{{out-of-line definition}}
diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p3.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p3.cpp
index 7e35788..e159ab7 100644
--- a/test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p3.cpp
+++ b/test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p3.cpp
@@ -17,7 +17,7 @@
   A a(b); 
   
   int A::*ip = &A::s; // expected-error {{cannot initialize a variable of type 'int A::*' with an rvalue of type 'int *'}}
-  a.*&A::s = 10; // expected-error{{right hand operand to .* has non pointer-to-member type 'int *'}}
+  a.*&A::s = 10; // expected-error{{right hand operand to .* has non-pointer-to-member type 'int *'}}
   
   a.*&A::i = 10; // expected-error{{cannot form a pointer-to-member to member 'i' of reference type 'int &'}}
   ft(a); // expected-note{{in instantiation of function template specialization 'ft<A>' requested here}}
diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p6-0x.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p6-0x.cpp
index cd623df..0f76e1f 100644
--- a/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p6-0x.cpp
+++ b/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p6-0x.cpp
@@ -1,5 +1,4 @@
 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
-// expected-no-diagnostics
 
 template<typename T, typename U> 
 struct is_same {
@@ -20,8 +19,8 @@
 typedef int&& RRI;
 
 typedef LRI& r1; CHECK_EQUAL_TYPES(r1, int&);
-typedef const LRI& r2; CHECK_EQUAL_TYPES(r2, int&);
-typedef const LRI&& r3; CHECK_EQUAL_TYPES(r3, int&);
+typedef const LRI& r2; CHECK_EQUAL_TYPES(r2, int&); // expected-warning {{'const' qualifier on reference type 'LRI' (aka 'int &') has no effect}}
+typedef const LRI&& r3; CHECK_EQUAL_TYPES(r3, int&); // expected-warning {{'const' qualifier on reference type 'LRI' (aka 'int &') has no effect}}
 
 typedef RRI& r4; CHECK_EQUAL_TYPES(r4, int&);
 typedef RRI&& r5; CHECK_EQUAL_TYPES(r5, int&&);
diff --git a/test/CXX/dcl.decl/dcl.meaning/p1-0x.cpp b/test/CXX/dcl.decl/dcl.meaning/p1-0x.cpp
index 99334b84..1d04d7d 100644
--- a/test/CXX/dcl.decl/dcl.meaning/p1-0x.cpp
+++ b/test/CXX/dcl.decl/dcl.meaning/p1-0x.cpp
@@ -22,3 +22,83 @@
 template<typename T>
 void decltype(tfoo<T>())::func() { // expected-error{{nested name specifier 'decltype(tfoo<T>())::' for declaration does not refer into a class, class template or class template partial specialization}}
 }
+
+// An init-declarator named with a qualified-id can refer to an element of the
+// inline namespace set of the named namespace.
+namespace inline_namespaces {
+  namespace N {
+    inline namespace M {
+      void f(); // expected-note {{possible target}}
+      void g();
+      extern int m; // expected-note {{candidate}}
+      extern int n;
+      struct S; // expected-note {{candidate}}
+      struct T;
+      enum E : int; // expected-note {{candidate}}
+      enum F : int;
+      template<typename T> void ft(); // expected-note {{here}}
+      template<typename T> void gt(); // expected-note {{here}}
+      template<typename T> extern int mt; // expected-note {{here}} expected-warning {{extension}}
+      template<typename T> extern int nt; // expected-note {{here}} expected-warning {{extension}}
+      template<typename T> struct U; // expected-note {{here}}
+      template<typename T> struct V; // expected-note {{here}}
+    }
+
+    // When named by unqualified-id, we do *not* look in the inline namespace
+    // set.
+    void f() {} // expected-note {{possible target}}
+    int m; // expected-note {{candidate}}
+    struct S {}; // expected-note {{candidate}}
+    enum E : int {}; // expected-note {{candidate}}
+
+    static_assert(&f != &M::f, ""); // expected-error {{reference to overloaded function could not be resolved}}
+    static_assert(&m != &M::m, ""); // expected-error {{ambiguous}}
+    typedef S X; // expected-error {{ambiguous}}
+    typedef E Y; // expected-error {{ambiguous}}
+
+    // When named by (unqualified) template-id, we do look in the inline
+    // namespace set.  See [namespace.def]p8, [temp.explicit]p3,
+    // [temp.expl.spec]p2.
+    //
+    // This is not explicitly specified for partial specializations, but
+    // that is just a language defect.
+    template<> void ft<int>() {}
+    template void ft<char>(); // expected-error {{undefined}}
+
+    template<typename T> int mt<T*>;
+    template<> int mt<int>;
+    template int mt<int*>;
+    template int mt<char>; // expected-error {{undefined}}
+
+    template<typename T> struct U<T*> {};
+    template<> struct U<int> {};
+    template struct U<int*>;
+    template struct U<char>; // expected-error {{undefined}}
+  }
+
+  // When named by qualified-id, we *do* look in the inline namespace set.
+  void N::g() {}
+  int N::n;
+  struct N::T {};
+  enum N::F : int {};
+
+  static_assert(&N::g == &N::M::g, "");
+  static_assert(&N::n == &N::M::n, "");
+  typedef N::T X;
+  typedef N::M::T X;
+  typedef N::F Y;
+  typedef N::M::F Y;
+
+  template<> void N::gt<int>() {}
+  template void N::gt<char>(); // expected-error {{undefined}}
+
+  template<typename T> int N::nt<T*>;
+  template<> int N::nt<int>;
+  template int N::nt<int*>;
+  template int N::nt<char>; // expected-error {{undefined}}
+
+  template<typename T> struct N::V<T*> {};
+  template<> struct N::V<int> {};
+  template struct N::V<int*>;
+  template struct N::V<char>; // expected-error {{undefined}}
+}
diff --git a/test/CXX/dcl.decl/dcl.meaning/p1.cpp b/test/CXX/dcl.decl/dcl.meaning/p1.cpp
index ec9a261..5747380 100644
--- a/test/CXX/dcl.decl/dcl.meaning/p1.cpp
+++ b/test/CXX/dcl.decl/dcl.meaning/p1.cpp
@@ -29,9 +29,17 @@
   template<typename T> void wibble(T);
 }
 namespace NS {
-  void NS::foo() {} // expected-error{{extra qualification on member 'foo'}}
-  int NS::bar; // expected-error{{extra qualification on member 'bar'}}
-  struct NS::X { }; // expected-error{{extra qualification on member 'X'}}
-  template<typename T> struct NS::Y; // expected-error{{extra qualification on member 'Y'}}
-  template<typename T> void NS::wibble(T) { } // expected-error{{extra qualification on member 'wibble'}}
+  // Under DR482, these are all valid, except for forward-declaring a struct
+  // with a nested-name-specifier.
+  void NS::foo(); // expected-warning {{extra qualification}}
+  extern int NS::bar; // expected-warning {{extra qualification}}
+  struct NS::X; // expected-error {{forward declaration of struct cannot have a nested name specifier}} expected-warning {{extra qualification}}
+  template<typename T> struct NS::Y; // expected-error {{forward declaration of struct cannot have a nested name specifier}} expected-warning {{extra qualification}}
+  template<typename T> void NS::wibble(T); // expected-warning {{extra qualification}}
+
+  void NS::foo() {} // expected-warning{{extra qualification on member 'foo'}}
+  int NS::bar; // expected-warning{{extra qualification on member 'bar'}}
+  struct NS::X { }; // expected-warning{{extra qualification on member 'X'}}
+  template<typename T> struct NS::Y { }; // expected-warning{{extra qualification on member 'Y'}}
+  template<typename T> void NS::wibble(T) { } // expected-warning{{extra qualification on member 'wibble'}}
 }
diff --git a/test/CXX/drs/dr0xx.cpp b/test/CXX/drs/dr0xx.cpp
index 265a52d..29e1720 100644
--- a/test/CXX/drs/dr0xx.cpp
+++ b/test/CXX/drs/dr0xx.cpp
@@ -4,7 +4,7 @@
 
 namespace dr1 { // dr1: no
   namespace X { extern "C" void dr1_f(int a = 1); }
-  namespace Y { extern "C" void dr1_f(int a = 2); }
+  namespace Y { extern "C" void dr1_f(int a = 1); }
   using X::dr1_f; using Y::dr1_f;
   void g() {
     dr1_f(0);
@@ -25,7 +25,23 @@
   }
   void X::z(int = 1) {} // expected-note {{previous}}
   namespace X {
-    void z(int = 2); // expected-error {{redefinition of default argument}}
+    void z(int = 1); // expected-error {{redefinition of default argument}}
+  }
+
+  void i(int = 1);
+  void j() {
+    void i(int = 1);
+    using dr1::i;
+    i(0);
+    // FIXME: This should be rejected, due to the ambiguous default argument.
+    i();
+  }
+  void k() {
+    using dr1::i;
+    void i(int = 1);
+    i(0);
+    // FIXME: This should be rejected, due to the ambiguous default argument.
+    i();
   }
 }
 
@@ -141,6 +157,21 @@
   }
 }
 
+namespace dr13 { // dr13: no
+  extern "C" void f(int);
+  void g(char);
+
+  template<typename T> struct A {
+    A(void (*fp)(T));
+  };
+  template<typename T> int h(void (T));
+
+  A<int> a1(f); // FIXME: We should reject this.
+  A<char> a2(g);
+  int a3 = h(f); // FIXME: We should reject this.
+  int a4 = h(g);
+}
+
 namespace dr14 { // dr14: yes
   namespace X { extern "C" int dr14_f(); }
   namespace Y { extern "C" int dr14_f(); }
@@ -194,10 +225,7 @@
   };
 }
 
-namespace dr18 { // dr18: yes
-  typedef void Void;
-  void f(Void); // expected-error {{empty parameter list defined with a typedef of 'void'}}
-}
+// dr18: sup 577
 
 namespace dr19 { // dr19: yes
   struct A {
@@ -464,23 +492,15 @@
   template template struct A<int>::B<int>; // expected-error {{expected unqualified-id}}
 }
 
-namespace dr47 { // dr47: no
+namespace dr47 { // dr47: sup 329
   template<typename T> struct A {
-    friend void f() { T t; }
+    friend void f() { T t; } // expected-error {{redefinition}} expected-note {{previous}}
   };
   A<int> a;
-  A<float> b;
-#if __cplusplus < 201103L
-  // expected-error@-5 {{redefinition}} expected-note@-5 {{previous}}
-  // expected-note@-3 {{instantiation of}}
-#else
+  A<float> b; // expected-note {{instantiation of}}
+
   void f();
-  // FIXME: We should produce some kind of error here. C++11 [temp.friend]p4
-  // says we instantiate 'f' when it's odr-used, but that doesn't imply that
-  // this is valid; we still have multiple definitions of 'f' even if we never
-  // instantiate any of them.
   void g() { f(); }
-#endif
 }
 
 namespace dr48 { // dr48: yes
@@ -919,11 +939,10 @@
 
 namespace dr88 { // dr88: yes
   template<typename T> struct S {
-    static const int a = 1;
+    static const int a = 1; // expected-note {{previous}}
     static const int b;
   };
-  // FIXME: This diagnostic is pretty bad.
-  template<> const int S<int>::a = 4; // expected-error {{redefinition}} expected-note {{previous}}
+  template<> const int S<int>::a = 4; // expected-error {{already has an initializer}}
   template<> const int S<int>::b = 4;
 }
 
@@ -963,6 +982,22 @@
   int k = f(U());
 }
 
+namespace dr92 { // dr92: yes
+  void f() throw(int, float);
+  void (*p)() throw(int) = &f; // expected-error {{target exception specification is not superset of source}}
+  void (*q)() throw(int);
+  void (**pp)() throw() = &q; // expected-error {{exception specifications are not allowed}}
+
+  void g(void() throw());
+  void h() {
+    g(f); // expected-error {{is not superset}}
+    g(q); // expected-error {{is not superset}}
+  }
+
+  template<void() throw()> struct X {};
+  X<&f> xp; // ok
+}
+
 // dr93: na
 
 namespace dr94 { // dr94: yes
diff --git a/test/CXX/drs/dr10xx.cpp b/test/CXX/drs/dr10xx.cpp
new file mode 100644
index 0000000..64c71b2
--- /dev/null
+++ b/test/CXX/drs/dr10xx.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+
+// expected-no-diagnostics
+
+namespace std {
+  __extension__ typedef __SIZE_TYPE__ size_t;
+
+  template<typename T> struct initializer_list {
+    const T *p; size_t n;
+    initializer_list(const T *p, size_t n);
+  };
+}
+
+namespace dr1070 { // dr1070: 3.5
+#if __cplusplus >= 201103L
+  struct A {
+    A(std::initializer_list<int>);
+  };
+  struct B {
+    int i;
+    A a;
+  };
+  B b = {1};
+  struct C {
+    std::initializer_list<int> a;
+    B b;
+    std::initializer_list<double> c;
+  };
+  C c = {};
+#endif
+}
diff --git a/test/CXX/drs/dr13xx.cpp b/test/CXX/drs/dr13xx.cpp
new file mode 100644
index 0000000..5827291
--- /dev/null
+++ b/test/CXX/drs/dr13xx.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+
+namespace dr1346 { // dr1346: 3.5
+  auto a(1); // expected-error 0-1{{extension}}
+  auto b(1, 2); // expected-error {{multiple expressions}} expected-error 0-1{{extension}}
+#if __cplusplus >= 201103L
+  auto c({}); // expected-error {{parenthesized initializer list}} expected-error {{cannot deduce}}
+  auto d({1}); // expected-error {{parenthesized initializer list}} expected-error {{<initializer_list>}}
+  auto e({1, 2}); // expected-error {{parenthesized initializer list}} expected-error {{<initializer_list>}}
+#endif
+  template<typename...Ts> void f(Ts ...ts) { // expected-error 0-1{{extension}}
+    auto x(ts...); // expected-error {{empty}} expected-error 0-1{{extension}}
+  }
+  template void f(); // expected-note {{instantiation}}
+
+#if __cplusplus >= 201103L
+  void init_capture() {
+    [a(1)] {} (); // expected-error 0-1{{extension}}
+    [b(1, 2)] {} (); // expected-error {{multiple expressions}} expected-error 0-1{{extension}}
+#if __cplusplus >= 201103L
+    [c({})] {} (); // expected-error {{parenthesized initializer list}} expected-error {{cannot deduce}} expected-error 0-1{{extension}}
+    [d({1})] {} (); // expected-error {{parenthesized initializer list}} expected-error {{<initializer_list>}} expected-error 0-1{{extension}}
+    [e({1, 2})] {} (); // expected-error {{parenthesized initializer list}} expected-error {{<initializer_list>}} expected-error 0-1{{extension}}
+#endif
+  }
+#endif
+}
diff --git a/test/CXX/drs/dr14xx.cpp b/test/CXX/drs/dr14xx.cpp
new file mode 100644
index 0000000..8de1b8d
--- /dev/null
+++ b/test/CXX/drs/dr14xx.cpp
@@ -0,0 +1,196 @@
+// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+
+#if __cplusplus < 201103L
+// expected-no-diagnostics
+#endif
+
+namespace dr1460 { // dr1460: 3.5
+#if __cplusplus >= 201103L
+  namespace DRExample {
+    union A {
+      union {};
+      union {};
+      constexpr A() {}
+    };
+    constexpr A a = A();
+
+    union B {
+      union {};
+      union {};
+      constexpr B() = default;
+    };
+    constexpr B b = B();
+
+    union C {
+      union {};
+      union {};
+    };
+    constexpr C c = C();
+#if __cplusplus > 201103L
+    constexpr void f() { C c; }
+    static_assert((f(), true), "");
+#endif
+  }
+
+  union A {};
+  union B { int n; }; // expected-note +{{here}}
+  union C { int n = 0; };
+  struct D { union {}; };
+  struct E { union { int n; }; }; // expected-note +{{here}}
+  struct F { union { int n = 0; }; };
+
+  struct X {
+    friend constexpr A::A() noexcept;
+    friend constexpr B::B() noexcept; // expected-error {{follows non-constexpr declaration}}
+    friend constexpr C::C() noexcept;
+    friend constexpr D::D() noexcept;
+    friend constexpr E::E() noexcept; // expected-error {{follows non-constexpr declaration}}
+    friend constexpr F::F() noexcept;
+  };
+
+  // These are OK, because value-initialization doesn't actually invoke the
+  // constructor.
+  constexpr A a = A();
+  constexpr B b = B();
+  constexpr C c = C();
+  constexpr D d = D();
+  constexpr E e = E();
+  constexpr F f = F();
+
+  namespace Defaulted {
+    union A { constexpr A() = default; };
+    union B { int n; constexpr B() = default; }; // expected-error {{not constexpr}}
+    union C { int n = 0; constexpr C() = default; };
+    struct D { union {}; constexpr D() = default; };
+    struct E { union { int n; }; constexpr E() = default; }; // expected-error {{not constexpr}}
+    struct F { union { int n = 0; }; constexpr F() = default; };
+
+    struct G { union { int n = 0; }; union { int m; }; constexpr G() = default; }; // expected-error {{not constexpr}}
+    struct H {
+      union {
+        int n = 0;
+      };
+      union { // expected-note 2{{member not initialized}}
+        int m;
+      };
+      constexpr H() {} // expected-error {{must initialize all members}}
+      constexpr H(bool) : m(1) {}
+      constexpr H(char) : n(1) {} // expected-error {{must initialize all members}}
+      constexpr H(double) : m(1), n(1) {}
+    };
+  }
+
+#if __cplusplus > 201103L
+  template<typename T> constexpr bool check() {
+    T t; // expected-note-re 2{{non-constexpr constructor '{{[BE]}}'}}
+    return true;
+  }
+  static_assert(check<A>(), "");
+  static_assert(check<B>(), ""); // expected-error {{constant}} expected-note {{in call}}
+  static_assert(check<C>(), "");
+  static_assert(check<D>(), "");
+  static_assert(check<E>(), ""); // expected-error {{constant}} expected-note {{in call}}
+  static_assert(check<F>(), "");
+#endif
+
+  union G {
+    int a = 0; // expected-note {{previous initialization is here}}
+    int b = 0; // expected-error {{initializing multiple members of union}}
+  };
+  union H {
+    union {
+      int a = 0; // expected-note {{previous initialization is here}}
+    };
+    union {
+      int b = 0; // expected-error {{initializing multiple members of union}}
+    };
+  };
+  struct I {
+    union {
+      int a = 0; // expected-note {{previous initialization is here}}
+      int b = 0; // expected-error {{initializing multiple members of union}}
+    };
+  };
+  struct J {
+    union { int a = 0; };
+    union { int b = 0; };
+  };
+
+  namespace Overriding {
+    struct A {
+      int a = 1, b, c = 3;
+      constexpr A() : b(2) {}
+    };
+    static_assert(A().a == 1 && A().b == 2 && A().c == 3, "");
+
+    union B {
+      int a, b = 2, c;
+      constexpr B() : a(1) {}
+      constexpr B(char) : b(4) {}
+      constexpr B(int) : c(3) {}
+      constexpr B(const char*) {}
+    };
+    static_assert(B().a == 1, "");
+    static_assert(B().b == 2, ""); // expected-error {{constant}} expected-note {{read of}}
+    static_assert(B('x').a == 0, ""); // expected-error {{constant}} expected-note {{read of}}
+    static_assert(B('x').b == 4, "");
+    static_assert(B(123).b == 2, ""); // expected-error {{constant}} expected-note {{read of}}
+    static_assert(B(123).c == 3, "");
+    static_assert(B("").a == 1, ""); // expected-error {{constant}} expected-note {{read of}}
+    static_assert(B("").b == 2, "");
+    static_assert(B("").c == 3, ""); // expected-error {{constant}} expected-note {{read of}}
+
+    struct C {
+      union { int a, b = 2, c; };
+      union { int d, e = 5, f; };
+      constexpr C() : a(1) {}
+      constexpr C(char) : c(3) {}
+      constexpr C(int) : d(4) {}
+      constexpr C(float) : f(6) {}
+      constexpr C(const char*) {}
+    };
+
+    static_assert(C().a == 1, "");
+    static_assert(C().b == 2, ""); // expected-error {{constant}} expected-note {{read of}}
+    static_assert(C().d == 4, ""); // expected-error {{constant}} expected-note {{read of}}
+    static_assert(C().e == 5, "");
+
+    static_assert(C('x').b == 2, ""); // expected-error {{constant}} expected-note {{read of}}
+    static_assert(C('x').c == 3, "");
+    static_assert(C('x').d == 4, ""); // expected-error {{constant}} expected-note {{read of}}
+    static_assert(C('x').e == 5, "");
+
+    static_assert(C(1).b == 2, "");
+    static_assert(C(1).c == 3, ""); // expected-error {{constant}} expected-note {{read of}}
+    static_assert(C(1).d == 4, "");
+    static_assert(C(1).e == 5, ""); // expected-error {{constant}} expected-note {{read of}}
+
+    static_assert(C(1.f).b == 2, "");
+    static_assert(C(1.f).c == 3, ""); // expected-error {{constant}} expected-note {{read of}}
+    static_assert(C(1.f).e == 5, ""); // expected-error {{constant}} expected-note {{read of}}
+    static_assert(C(1.f).f == 6, "");
+
+    static_assert(C("").a == 1, ""); // expected-error {{constant}} expected-note {{read of}}
+    static_assert(C("").b == 2, "");
+    static_assert(C("").c == 3, ""); // expected-error {{constant}} expected-note {{read of}}
+    static_assert(C("").d == 4, ""); // expected-error {{constant}} expected-note {{read of}}
+    static_assert(C("").e == 5, "");
+    static_assert(C("").f == 6, ""); // expected-error {{constant}} expected-note {{read of}}
+
+    struct D;
+    extern const D d;
+    struct D {
+      int a;
+      union {
+        int b = const_cast<D&>(d).a = 1; // not evaluated
+        int c;
+      };
+      constexpr D() : a(0), c(0) {}
+    };
+    constexpr D d {};
+    static_assert(d.a == 0, "");
+  }
+#endif
+}
diff --git a/test/CXX/drs/dr15xx.cpp b/test/CXX/drs/dr15xx.cpp
new file mode 100644
index 0000000..66618c1
--- /dev/null
+++ b/test/CXX/drs/dr15xx.cpp
@@ -0,0 +1,20 @@
+// 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++1y -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+
+// expected-no-diagnostics
+
+namespace DR1550 { // dr1550: yes
+  int f(bool b, int n) {
+    return (b ? (throw 0) : n) + (b ? n : (throw 0));
+  }
+}
+
+namespace DR1560 { // dr1560: 3.5
+  void f(bool b, int n) {
+    (b ? throw 0 : n) = (b ? n : throw 0) = 0;
+  }
+  class X { X(const X&); };
+  const X &get();
+  const X &x = true ? get() : throw 0;
+}
diff --git a/test/CXX/drs/dr1xx.cpp b/test/CXX/drs/dr1xx.cpp
index 7045148..6aff43c 100644
--- a/test/CXX/drs/dr1xx.cpp
+++ b/test/CXX/drs/dr1xx.cpp
@@ -9,7 +9,7 @@
   B<"bar"> b; // expected-error {{does not refer to any declaration}}
 }
 
-namespace dr101 { // dr101: yes
+namespace dr101 { // dr101: 3.5
   extern "C" void dr101_f();
   typedef unsigned size_t;
   namespace X {
@@ -18,6 +18,8 @@
   }
   using X::dr101_f;
   using X::size_t;
+  extern "C" void dr101_f();
+  typedef unsigned size_t;
 }
 
 namespace dr102 { // dr102: yes
@@ -38,13 +40,13 @@
 namespace dr106 { // dr106: sup 540
   typedef int &r1;
   typedef r1 &r1;
-  typedef const r1 r1;
-  typedef const r1 &r1;
+  typedef const r1 r1; // expected-warning {{has no effect}}
+  typedef const r1 &r1; // expected-warning {{has no effect}}
 
   typedef const int &r2;
   typedef r2 &r2;
-  typedef const r2 r2;
-  typedef const r2 &r2;
+  typedef const r2 r2; // expected-warning {{has no effect}}
+  typedef const r2 &r2; // expected-warning {{has no effect}}
 }
 
 namespace dr107 { // dr107: yes
@@ -64,7 +66,7 @@
 namespace dr109 { // dr109: yes
   struct A { template<typename T> void f(T); };
   template<typename T> struct B : T {
-    using T::template f; // expected-error {{using declaration can not refer to a template}}
+    using T::template f; // expected-error {{using declaration cannot refer to a template}}
     void g() { this->f<int>(123); } // expected-error {{use 'template'}}
   };
 }
@@ -592,11 +594,12 @@
   struct S { int n; } s = { { 1 } }; // expected-warning {{braces around scalar initializer}}
 }
 
-namespace dr159 { // dr159: no
+// dr158 FIXME write codegen test
+
+namespace dr159 { // dr159: 3.5
   namespace X { void f(); }
   void f();
-  // FIXME: This should be accepted.
-  void dr159::f() {} // expected-error {{extra qualification}}
+  void dr159::f() {} // expected-warning {{extra qualification}}
   void dr159::X::f() {}
 }
 
@@ -719,9 +722,9 @@
   };
   struct D : A<int>, B {
     using A<int>::n;
-    using B::C<int>; // expected-error {{using declaration can not refer to a template specialization}}
-    using B::f<int>; // expected-error {{using declaration can not refer to a template specialization}}
-    using B::n<int>; // expected-error {{using declaration can not refer to a template specialization}}
+    using B::C<int>; // expected-error {{using declaration cannot refer to a template specialization}}
+    using B::f<int>; // expected-error {{using declaration cannot refer to a template specialization}}
+    using B::n<int>; // expected-error {{using declaration cannot refer to a template specialization}}
   };
 }
 
diff --git a/test/CXX/drs/dr2xx.cpp b/test/CXX/drs/dr2xx.cpp
index 2c32a9e..bb9af9f 100644
--- a/test/CXX/drs/dr2xx.cpp
+++ b/test/CXX/drs/dr2xx.cpp
@@ -3,7 +3,7 @@
 // RUN: %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
 
 // PR13819 -- __SIZE_TYPE__ is incompatible.
-// REQUIRES: LP64
+typedef __SIZE_TYPE__ size_t; // expected-error 0-1 {{extension}}
 
 #if __cplusplus < 201103L
 #define fold(x) (__builtin_constant_p(x) ? (x) : (x))
@@ -216,8 +216,22 @@
   }
 }
 
-// dr222 is a mystery -- it lists no changes to the standard, and yet was
-// apparently both voted into the WP and acted upon by the editor.
+namespace dr222 { // dr222: dup 637
+  void f(int a, int b, int c, int *x) {
+#pragma clang diagnostic push
+#pragma clang diagnostic warning "-Wunsequenced"
+    void((a += b) += c);
+    void((a += b) + (a += c)); // expected-warning {{multiple unsequenced modifications to 'a'}}
+
+    x[a++] = a; // expected-warning {{unsequenced modification and access to 'a'}}
+
+    a = b = 0; // ok, read and write of 'b' are sequenced
+
+    a = (b = a++); // expected-warning {{multiple unsequenced modifications to 'a'}}
+    a = (b = ++a);
+#pragma clang diagnostic pop
+  }
+}
 
 // dr223: na
 
@@ -363,6 +377,13 @@
   template<> void f<int>() {}
 }
 
+namespace dr230 { // dr230: yes
+  struct S {
+    S() { f(); } // expected-warning {{call to pure virtual member function}}
+    virtual void f() = 0; // expected-note {{declared here}}
+  };
+}
+
 namespace dr231 { // dr231: yes
   namespace outer {
     namespace inner {
@@ -445,7 +466,7 @@
   A a2 = b; // expected-error {{ambiguous}}
 }
 
-namespace dr244 { // dr244: no
+namespace dr244 { // dr244: 3.5
   struct B {}; struct D : B {}; // expected-note {{here}}
 
   D D_object;
@@ -459,7 +480,7 @@
     B_ptr->~B_alias();
     B_ptr->B_alias::~B();
     // This is valid under DR244.
-    B_ptr->B_alias::~B_alias(); // FIXME: expected-error {{expected the class name after '~' to name a destructor}}
+    B_ptr->B_alias::~B_alias();
     B_ptr->dr244::~B(); // expected-error {{refers to a member in namespace}}
     B_ptr->dr244::~B_alias(); // expected-error {{refers to a member in namespace}}
   }
@@ -552,21 +573,21 @@
 
   struct E {
     void operator delete(void*, int);
-    void operator delete(void*) = delete; // expected-error 0-1{{extension}} expected-note {{here}}
-    virtual ~E();
+    void operator delete(void*) = delete; // expected-error 0-1{{extension}} expected-note 1-2 {{here}}
+    virtual ~E(); // expected-error 0-1 {{attempt to use a deleted function}}
   };
-  E::~E() {} // expected-error {{deleted}}
+  E::~E() {} // expected-error {{attempt to use a deleted function}}
 
   struct F {
     // If both functions are available, the first one is a placement delete.
-    void operator delete(void*, __SIZE_TYPE__);
+    void operator delete(void*, size_t);
     void operator delete(void*) = delete; // expected-error 0-1{{extension}} expected-note {{here}}
     virtual ~F();
   };
-  F::~F() {} // expected-error {{deleted}}
+  F::~F() {} // expected-error {{attempt to use a deleted function}}
 
   struct G {
-    void operator delete(void*, __SIZE_TYPE__);
+    void operator delete(void*, size_t);
     virtual ~G();
   };
   G::~G() {}
@@ -665,6 +686,8 @@
 #endif
 }
 
+// FIXME: When dr260 is resolved, also add tests for DR507.
+
 namespace dr261 { // dr261: no
 #pragma clang diagnostic push
 #pragma clang diagnostic warning "-Wused-but-marked-unused"
@@ -674,7 +697,7 @@
   // translation unit.
   // We're also missing the -Wused-but-marked-unused diagnostic here.
   struct A {
-    inline void *operator new(__SIZE_TYPE__) __attribute__((unused));
+    inline void *operator new(size_t) __attribute__((unused));
     inline void operator delete(void*) __attribute__((unused));
     A() {}
   };
@@ -724,3 +747,293 @@
 // dr266: na
 // dr269: na
 // dr270: na
+
+namespace dr272 { // dr272: yes
+  struct X {
+    void f() {
+      this->~X();
+      X::~X();
+      ~X(); // expected-error {{unary expression}}
+    }
+  };
+}
+
+#include <stdarg.h>
+#include <stddef.h>
+namespace dr273 { // dr273: yes
+  struct A {
+    int n;
+  };
+  void operator&(A);
+  void f(A a, ...) {
+    offsetof(A, n);
+    va_list val;
+    va_start(val, a);
+    va_end(val);
+  }
+}
+
+// dr274: na
+
+namespace dr275 { // dr275: no
+  namespace N {
+    template <class T> void f(T) {} // expected-note 1-4{{here}}
+    template <class T> void g(T) {} // expected-note {{candidate}}
+    template <> void f(int);
+    template <> void f(char);
+    template <> void f(double);
+    template <> void g(char);
+  }
+
+  using namespace N;
+
+  namespace M {
+    template <> void N::f(char) {} // expected-error {{'M' does not enclose namespace 'N'}}
+    template <class T> void g(T) {}
+    template <> void g(char) {}
+    template void f(long);
+#if __cplusplus >= 201103L
+    // FIXME: this should be rejected in c++98 too
+    // expected-error@-3 {{must occur in namespace 'N'}}
+#endif
+    template void N::f(unsigned long);
+#if __cplusplus >= 201103L
+    // FIXME: this should be rejected in c++98 too
+    // expected-error@-3 {{not in a namespace enclosing 'N'}}
+#endif
+    template void h(long); // expected-error {{does not refer to a function template}}
+    template <> void f(double) {} // expected-error {{no function template matches}}
+  }
+
+  template <class T> void g(T) {} // expected-note {{candidate}}
+
+  template <> void N::f(char) {}
+  template <> void f(int) {} // expected-error {{no function template matches}}
+
+  template void f(short);
+#if __cplusplus >= 201103L
+  // FIXME: this should be rejected in c++98 too
+  // expected-error@-3 {{must occur in namespace 'N'}}
+#endif
+  template void N::f(unsigned short);
+
+  // FIXME: this should probably be valid. the wording from the issue
+  // doesn't clarify this, but it follows from the usual rules.
+  template void g(int); // expected-error {{ambiguous}}
+
+  // FIXME: likewise, this should also be valid.
+  template<typename T> void f(T) {} // expected-note {{candidate}}
+  template void f(short); // expected-error {{ambiguous}}
+}
+
+// dr276: na
+
+namespace dr277 { // dr277: yes
+  typedef int *intp;
+  int *p = intp();
+  int a[fold(intp() ? -1 : 1)];
+}
+
+namespace dr280 { // dr280: yes
+  typedef void f0();
+  typedef void f1(int);
+  typedef void f2(int, int);
+  typedef void f3(int, int, int);
+  struct A {
+    operator f1*(); // expected-note {{here}} expected-note {{candidate}}
+    operator f2*();
+  };
+  struct B {
+    operator f0*(); // expected-note {{candidate}}
+  private:
+    operator f3*(); // expected-note {{here}} expected-note {{candidate}}
+  };
+  struct C {
+    operator f0*(); // expected-note {{candidate}}
+    operator f1*(); // expected-note {{candidate}}
+    operator f2*(); // expected-note {{candidate}}
+    operator f3*(); // expected-note {{candidate}}
+  };
+  struct D : private A, B { // expected-note 2{{here}}
+    operator f2*(); // expected-note {{candidate}}
+  } d;
+  struct E : C, D {} e;
+  void g() {
+    d(); // ok, public
+    d(0); // expected-error {{private member of 'dr280::A'}} expected-error {{private base class 'dr280::A'}}
+    d(0, 0); // ok, suppressed by member in D
+    d(0, 0, 0); // expected-error {{private member of 'dr280::B'}}
+    e(); // expected-error {{ambiguous}}
+    e(0); // expected-error {{ambiguous}}
+    e(0, 0); // expected-error {{ambiguous}}
+    e(0, 0, 0); // expected-error {{ambiguous}}
+  }
+}
+
+namespace dr281 { // dr281: no
+  void a();
+  inline void b();
+
+  void d();
+  inline void e();
+
+  struct S {
+    friend inline void a(); // FIXME: ill-formed
+    friend inline void b();
+    friend inline void c(); // FIXME: ill-formed
+    friend inline void d() {}
+    friend inline void e() {}
+    friend inline void f() {}
+  };
+}
+
+namespace dr283 { // dr283: yes
+  template<typename T> // expected-note 2{{here}}
+  struct S {
+    friend class T; // expected-error {{shadows}}
+    class T; // expected-error {{shadows}}
+  };
+}
+
+namespace dr284 { // dr284: no
+  namespace A {
+    struct X;
+    enum Y {};
+    class Z {};
+  }
+  namespace B {
+    struct W;
+    using A::X;
+    using A::Y;
+    using A::Z;
+  }
+  struct B::V {}; // expected-error {{no struct named 'V'}}
+  struct B::W {};
+  struct B::X {}; // FIXME: ill-formed
+  enum B::Y e; // ok per dr417
+  class B::Z z; // ok per dr417
+
+  struct C {
+    struct X;
+    enum Y {};
+    class Z {};
+  };
+  struct D : C {
+    struct W;
+    using C::X;
+    using C::Y;
+    using C::Z;
+  };
+  struct D::V {}; // expected-error {{no struct named 'V'}}
+  struct D::W {};
+  struct D::X {}; // FIXME: ill-formed
+  enum D::Y e2; // ok per dr417
+  class D::Z z2; // ok per dr417
+}
+
+namespace dr285 { // dr285: yes
+  template<typename T> void f(T, int); // expected-note {{match}}
+  template<typename T> void f(int, T); // expected-note {{match}}
+  template<> void f<int>(int, int) {} // expected-error {{ambiguous}}
+}
+
+namespace dr286 { // dr286: yes
+  template<class T> struct A {
+    class C {
+      template<class T2> struct B {}; // expected-note {{here}}
+    };
+  };
+
+  template<class T>
+  template<class T2>
+  struct A<T>::C::B<T2*> { };
+
+  A<short>::C::B<int*> absip; // expected-error {{private}}
+}
+
+// dr288: na
+
+namespace dr289 { // dr289: yes
+  struct A; // expected-note {{forward}}
+  struct B : A {}; // expected-error {{incomplete}}
+
+  template<typename T> struct C { typename T::error error; }; // expected-error {{cannot be used prior to '::'}}
+  struct D : C<int> {}; // expected-note {{instantiation}}
+}
+
+// dr290: na
+// dr291: dup 391
+// dr292 FIXME: write a codegen test
+
+namespace dr294 { // dr294: no
+  void f() throw(int);
+  int main() {
+    // FIXME: we reject this for the wrong reason, because we don't implement
+    // dr87 yet.
+    (void)static_cast<void (*)() throw()>(f); // expected-error {{not superset}}
+    void (*p)() throw() = f; // expected-error {{not superset}}
+
+    (void)static_cast<void (*)() throw(int)>(f); // FIXME: ill-formed
+  }
+}
+
+namespace dr295 { // dr295: no
+  typedef int f();
+  // FIXME: This warning is incorrect.
+  const f g; // expected-warning {{unspecified behavior}}
+  const f &r = g; // expected-warning {{unspecified behavior}}
+  template<typename T> struct X {
+    const T &f;
+  };
+  X<f> x = {g}; // FIXME: expected-error {{drops qualifiers}}
+}
+
+namespace dr296 { // dr296: yes
+  struct A {
+    static operator int() { return 0; } // expected-error {{static}}
+  };
+}
+
+namespace dr298 { // dr298: yes
+  struct A {
+    typedef int type;
+    A();
+    ~A();
+  };
+  typedef A B; // expected-note {{here}}
+  typedef const A C; // expected-note {{here}}
+
+  A::type i1;
+  B::type i2;
+  C::type i3;
+
+  struct A a;
+  struct B b; // expected-error {{refers to a typedef}}
+  struct C c; // expected-error {{refers to a typedef}}
+
+  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}}
+
+  typedef struct D E; // expected-note {{here}}
+  struct E {}; // expected-error {{conflicts with typedef}}
+
+  struct F {
+    ~F();
+  };
+  typedef const F G;
+  G::~F() {} // ok
+}
+
+namespace dr299 { // dr299: yes c++11
+  struct S {
+    operator int();
+  };
+  struct T {
+    operator int(); // expected-note {{}}
+    operator unsigned short(); // expected-note {{}}
+  };
+  // FIXME: should this apply to c++98 mode?
+  int *p = new int[S()]; // expected-error 0-1{{extension}}
+  int *q = new int[T()]; // expected-error {{ambiguous}}
+}
diff --git a/test/CXX/drs/dr3xx.cpp b/test/CXX/drs/dr3xx.cpp
new file mode 100644
index 0000000..53fc20e
--- /dev/null
+++ b/test/CXX/drs/dr3xx.cpp
@@ -0,0 +1,1285 @@
+// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+
+namespace dr300 { // dr300: yes
+  template<typename R, typename A> void f(R (&)(A)) {}
+  int g(int);
+  void h() { f(g); }
+}
+
+namespace dr301 { // dr301: yes
+  // see also dr38
+  struct S;
+  template<typename T> void operator+(T, T);
+  void operator-(S, S);
+
+  void f() {
+    bool a = (void(*)(S, S))operator+<S> <
+             (void(*)(S, S))operator+<S>;
+    bool b = (void(*)(S, S))operator- <
+             (void(*)(S, S))operator-;
+    bool c = (void(*)(S, S))operator+ <
+             (void(*)(S, S))operator-; // expected-error {{expected '>'}}
+  }
+
+  template<typename T> void f() {
+    typename T::template operator+<int> a; // expected-error {{typename specifier refers to a non-type template}} expected-error +{{}}
+    // FIXME: This shouldn't say (null).
+    class T::template operator+<int> b; // expected-error {{identifier followed by '<' indicates a class template specialization but (null) refers to a function template}}
+    enum T::template operator+<int> c; // expected-error {{expected identifier}} expected-error {{does not declare anything}}
+    enum T::template operator+<int>::E d; // expected-error {{qualified name refers into a specialization of function template 'T::template operator +'}} expected-error {{forward reference}}
+    enum T::template X<int>::E e;
+    T::template operator+<int>::foobar(); // expected-error {{qualified name refers into a specialization of function template 'T::template operator +'}}
+    T::template operator+<int>(0); // ok
+  }
+
+  template<typename T> class operator&<T*> {}; // expected-error +{{}}
+  template<typename T> class T::operator& {}; // expected-error +{{}}
+  template<typename T> class S::operator&<T*> {}; // expected-error +{{}}
+}
+
+namespace dr302 { // dr302: yes
+  struct A { A(); ~A(); };
+#if __cplusplus < 201103L
+  struct B { // expected-error {{implicit default constructor for 'dr302::B' must explicitly initialize the const member 'n'}}
+    const int n; // expected-note {{declared here}}
+    A a;
+  } b = B(); // expected-note {{first required here}}
+  // Trivial default constructor C::C() is not called here.
+  struct C {
+    const int n;
+  } c = C();
+#else
+  struct B {
+    const int n; // expected-note {{deleted because field 'n' of const-qualified type 'const int' would not be initialized}}
+    A a;
+  } b = B(); // expected-error {{call to implicitly-deleted default constructor}}
+  // C::C() is called here, because even though it's trivial, it's deleted.
+  struct C {
+    const int n; // expected-note {{deleted because field 'n' of const-qualified type 'const int' would not be initialized}}
+  } c = C(); // expected-error {{call to implicitly-deleted default constructor}}
+  struct D {
+    const int n = 0;
+  } d = D();
+#endif
+}
+
+// dr303: na
+
+namespace dr304 { // dr304: yes
+  typedef int &a;
+  int n = a(); // expected-error {{requires an initializer}}
+
+  struct S { int &b; };
+  int m = S().b;
+#if __cplusplus < 201103L
+  // expected-error@-3 {{requires an initializer}}
+  // expected-note@-3 {{in value-initialization}}
+#else
+  // expected-error@-5 {{deleted}}
+  // expected-note@-7 {{reference}}
+#endif
+}
+
+namespace dr305 { // dr305: no
+  struct A {
+    typedef A C;
+  };
+  void f(A *a) {
+    struct A {};
+    a->~A();
+    a->~C();
+  }
+  typedef A B;
+  void g(B *b) {
+    b->~B();
+    b->~C();
+  }
+  void h(B *b) {
+    struct B {}; // expected-note {{declared here}}
+    b->~B(); // expected-error {{does not match}}
+  }
+
+  template<typename T> struct X {};
+  void i(X<int>* x) {
+    struct X {};
+    x->~X<int>();
+    x->~X();
+    x->~X<char>(); // expected-error {{no member named}}
+  }
+
+  // FIXME: This appears to be valid (but allowing the nested types might be a
+  // defect).
+  template<typename> struct Nested {
+    template<typename> struct Nested {};
+  };
+  void testNested(Nested<int> n) { n.~Nested<int>(); } // expected-error {{no member named}}
+#if __cplusplus < 201103L
+  // expected-error@-2 {{ambiguous}}
+  // expected-note@-6 {{here}}
+  // expected-note@-6 {{here}}
+#endif
+
+#if __cplusplus >= 201103L
+  struct Y {
+    template<typename T> using T1 = Y;
+  };
+  template<typename T> using T2 = Y;
+  void j(Y *y) {
+    y->~T1<int>();
+    y->~T2<int>();
+  }
+  struct Z {
+    template<typename T> using T2 = T;
+  };
+  void k(Z *z) {
+    // FIXME: This diagnostic is terrible.
+    z->~T1<int>(); // expected-error {{'T1' following the 'template' keyword does not refer to a template}} expected-error +{{}}
+    z->~T2<int>(); // expected-error {{no member named '~int'}}
+    z->~T2<Z>();
+  }
+
+  // FIXME: This is valid.
+  namespace Q {
+    template<typename A> struct R {};
+  }
+  template<typename A> using R = Q::R<int>;
+  void qr(Q::R<int> x) { x.~R<char>(); } // expected-error {{no member named}}
+#endif
+}
+
+namespace dr306 { // dr306: no
+  // FIXME: dup 39
+  // FIXME: This should be accepted.
+  struct A { struct B {}; }; // expected-note 2{{member}}
+  struct C { typedef A::B B; }; // expected-note {{member}}
+  struct D : A, A::B, C {};
+  D::B b; // expected-error {{found in multiple base classes of different types}}
+}
+
+// dr307: na
+
+namespace dr308 { // dr308: yes
+  // This is mostly an ABI library issue.
+  struct A {};
+  struct B : A {};
+  struct C : A {};
+  struct D : B, C {};
+  void f() {
+    try {
+      throw D();
+    } catch (const A&) {
+      // unreachable
+    } catch (const B&) {
+      // get here instead
+    }
+  }
+}
+
+// dr309: dup 485
+
+namespace dr311 { // dr311: yes
+  namespace X { namespace Y {} }
+  namespace X::Y {} // expected-error {{must define each namespace separately}}
+  namespace X {
+    namespace X::Y {} // expected-error {{must define each namespace separately}}
+  }
+  // FIXME: The diagnostics here are not very good.
+  namespace ::dr311::X {} // expected-error 2+{{}} // expected-warning {{extra qual}}
+}
+
+// dr312: dup 616
+
+namespace dr313 { // dr313: dup 299 c++11
+  struct A { operator int() const; };
+  int *p = new int[A()];
+#if __cplusplus < 201103L
+  // FIXME: should this be available in c++98 mode? expected-error@-2 {{extension}}
+#endif
+}
+
+namespace dr314 { // dr314: dup 1710
+  template<typename T> struct A {
+    template<typename U> struct B {};
+  };
+  template<typename T> struct C : public A<T>::template B<T> {
+    C() : A<T>::template B<T>() {}
+  };
+}
+
+// dr315: na
+// dr316: sup 1004
+
+namespace dr317 { // dr317: 3.5
+  void f() {} // expected-note {{previous}}
+  inline void f(); // expected-error {{inline declaration of 'f' follows non-inline definition}}
+
+  int g();
+  int n = g();
+  inline int g() { return 0; }
+
+  int h();
+  int m = h();
+  int h() { return 0; } // expected-note {{previous}}
+  inline int h(); // expected-error {{inline declaration of 'h' follows non-inline definition}}
+}
+
+namespace dr318 { // dr318: sup 1310
+  struct A {};
+  struct A::A a;
+}
+
+namespace dr319 { // dr319: no
+  // FIXME: dup dr389
+  // FIXME: We don't have a diagnostic for a name with linkage
+  //        having a type without linkage.
+  typedef struct {
+    int i;
+  } *ps;
+  extern "C" void f(ps);
+  void g(ps); // FIXME: ill-formed, type 'ps' has no linkage
+
+  static enum { e } a1;
+  enum { e2 } a2; // FIXME: ill-formed, enum type has no linkage
+
+  enum { n1 = 1u };
+  typedef int (*pa)[n1];
+  pa parr; // ok, type has linkage despite using 'n1'
+
+  template<typename> struct X {};
+
+  void f() {
+    struct A { int n; };
+    extern A a; // FIXME: ill-formed
+    X<A> xa;
+
+    typedef A B;
+    extern B b; // FIXME: ill-formed
+    X<B> xb;
+
+    const int n = 1;
+    typedef int (*C)[n];
+    extern C c; // ok
+    X<C> xc;
+  }
+#if __cplusplus < 201103L
+  // expected-error@-12 {{uses local type 'A'}}
+  // expected-error@-9 {{uses local type 'A'}}
+#endif
+}
+
+namespace dr320 { // dr320: yes
+#if __cplusplus >= 201103L
+  struct X {
+    constexpr X() {}
+    constexpr X(const X &x) : copies(x.copies + 1) {}
+    unsigned copies = 0;
+  };
+  constexpr X f(X x) { return x; }
+  constexpr unsigned g(X x) { return x.copies; }
+  static_assert(f(X()).copies == g(X()) + 1, "expected one extra copy for return value");
+#endif
+}
+
+namespace dr321 { // dr321: dup 557
+  namespace N {
+    template<int> struct A {
+      template<int> struct B;
+    };
+    template<> template<> struct A<0>::B<0>;
+    void f(A<0>::B<0>);
+  }
+  template<> template<> struct N::A<0>::B<0> {};
+
+  template<typename T> void g(T t) { f(t); }
+  template void g(N::A<0>::B<0>);
+
+  namespace N {
+    template<typename> struct I { friend bool operator==(const I&, const I&); };
+  }
+  N::I<int> i, j;
+  bool x = i == j;
+}
+
+namespace dr322 { // dr322: yes
+  struct A {
+    template<typename T> operator T&();
+  } a;
+  int &r = static_cast<int&>(a);
+  int &s = a;
+}
+
+// dr323: no
+
+namespace dr324 { // dr324: yes
+  struct S { int n : 1; } s; // expected-note 3{{bit-field is declared here}}
+  int &a = s.n; // expected-error {{non-const reference cannot bind to bit-field}}
+  int *b = &s.n; // expected-error {{address of bit-field}}
+  int &c = (s.n = 0); // expected-error {{non-const reference cannot bind to bit-field}}
+  int *d = &(s.n = 0); // expected-error {{address of bit-field}}
+  int &e = true ? s.n : s.n; // expected-error {{non-const reference cannot bind to bit-field}}
+  int *f = &(true ? s.n : s.n); // expected-error {{address of bit-field}}
+  int &g = (void(), s.n); // expected-error {{non-const reference cannot bind to bit-field}}
+  int *h = &(void(), s.n); // expected-error {{address of bit-field}}
+}
+
+namespace dr326 { // dr326: yes
+  struct S {};
+  int test[__is_trivially_constructible(S, const S&) ? 1 : -1];
+}
+
+namespace dr327 { // dr327: dup 538
+  struct A;
+  class A {};
+
+  class B;
+  struct B {};
+}
+
+namespace dr328 { // dr328: yes
+  struct A; // expected-note 3{{forward declaration}}
+  struct B { A a; }; // expected-error {{incomplete}}
+  template<typename> struct C { A a; }; // expected-error {{incomplete}}
+  A *p = new A[0]; // expected-error {{incomplete}}
+}
+
+namespace dr329 { // dr329: 3.5
+  struct B {};
+  template<typename T> struct A : B {
+    friend void f(A a) { g(a); }
+    friend void h(A a) { g(a); } // expected-error {{undeclared}}
+    friend void i(B b) {} // expected-error {{redefinition}} expected-note {{previous}}
+  };
+  A<int> a;
+  A<char> b; // expected-note {{instantiation}}
+
+  void test() {
+    h(a); // expected-note {{instantiation}}
+  }
+}
+
+namespace dr331 { // dr331: yes
+  struct A {
+    A(volatile A&); // expected-note {{candidate}}
+  } const a, b(a); // expected-error {{no matching constructor}}
+}
+
+namespace dr332 { // dr332: dup 557
+  void f(volatile void); // expected-error {{'void' as parameter must not have type qualifiers}}
+  void g(const void); // expected-error {{'void' as parameter must not have type qualifiers}}
+  void h(int n, volatile void); // expected-error {{'void' must be the first and only parameter}}
+}
+
+namespace dr333 { // dr333: yes
+  int n = 0;
+  int f(int(n));
+  int g((int(n)));
+  int h = f(g);
+}
+
+namespace dr334 { // dr334: yes
+  template<typename T> void f() {
+    T x;
+    f((x, 123));
+  }
+  struct S {
+    friend S operator,(S, int);
+    friend void f(S);
+  };
+  template void f<S>();
+}
+
+// dr335: no
+
+namespace dr336 { // dr336: yes
+  namespace Pre {
+    template<class T1> class A {
+      template<class T2> class B {
+        template<class T3> void mf1(T3);
+        void mf2();
+      };
+    };
+    template<> template<class X> class A<int>::B {};
+    template<> template<> template<class T> void A<int>::B<double>::mf1(T t) {} // expected-error {{does not match}}
+    template<class Y> template<> void A<Y>::B<double>::mf2() {} // expected-error {{does not refer into a class}}
+  }
+  namespace Post {
+    template<class T1> class A {
+      template<class T2> class B {
+        template<class T3> void mf1(T3);
+        void mf2();
+      };
+    };
+    template<> template<class X> class A<int>::B {
+      template<class T> void mf1(T);
+    };
+    template<> template<> template<class T> void A<int>::B<double>::mf1(T t) {}
+    // FIXME: This diagnostic isn't very good.
+    template<class Y> template<> void A<Y>::B<double>::mf2() {} // expected-error {{does not refer into a class}}
+  }
+}
+
+namespace dr337 { // dr337: yes
+  template<typename T> void f(T (*)[1]);
+  template<typename T> int &f(...);
+
+  struct A { virtual ~A() = 0; };
+  int &r = f<A>(0);
+
+  // FIXME: The language rules here are completely broken. We cannot determine
+  // whether an incomplete type is abstract. See DR1640, which will probably
+  // supersede this one and remove this rule.
+  struct B;
+  int &s = f<B>(0); // expected-error {{of type 'void'}}
+  struct B { virtual ~B() = 0; };
+}
+
+namespace dr339 { // dr339: yes
+  template <int I> struct A { static const int value = I; };
+
+  char xxx(int);
+  char (&xxx(float))[2];
+
+  template<class T> A<sizeof(xxx((T)0))> f(T) {} // expected-note {{candidate}}
+
+  void test() {
+    A<1> a = f(0);
+    A<2> b = f(0.0f);
+    A<3> c = f("foo"); // expected-error {{no matching function}}
+  }
+
+
+  char f(int);
+  int f(...);
+
+  template <class T> struct conv_int {
+    static const bool value = sizeof(f(T())) == 1;
+  };
+
+  template <class T> bool conv_int2(A<sizeof(f(T()))> p);
+
+  template<typename T> A<sizeof(f(T()))> make_A();
+
+  int a[conv_int<char>::value ? 1 : -1];
+  bool b = conv_int2<char>(A<1>());
+  A<1> c = make_A<char>();
+}
+
+namespace dr340 { // dr340: yes
+  struct A { A(int); };
+  struct B { B(A, A, int); };
+  int x, y;
+  B b(A(x), A(y), 3);
+}
+
+namespace dr341 { // dr341: sup 1708
+  namespace A {
+    int n;
+    extern "C" int &dr341_a = n; // expected-note {{previous}} expected-note {{declared with C language linkage here}}
+  }
+  namespace B {
+    extern "C" int &dr341_a = dr341_a; // expected-error {{redefinition}}
+  }
+  extern "C" void dr341_b(); // expected-note {{declared with C language linkage here}}
+}
+int dr341_a; // expected-error {{declaration of 'dr341_a' in global scope conflicts with declaration with C language linkage}}
+int dr341_b; // expected-error {{declaration of 'dr341_b' in global scope conflicts with declaration with C language linkage}}
+int dr341_c; // expected-note {{declared in global scope here}}
+int dr341_d; // expected-note {{declared in global scope here}}
+namespace dr341 {
+  extern "C" int dr341_c; // expected-error {{declaration of 'dr341_c' with C language linkage conflicts with declaration in global scope}}
+  extern "C" void dr341_d(); // expected-error {{declaration of 'dr341_d' with C language linkage conflicts with declaration in global scope}}
+
+  namespace A { extern "C" int dr341_e; } // expected-note {{previous}}
+  namespace B { extern "C" void dr341_e(); } // expected-error {{redefinition of 'dr341_e' as different kind of symbol}}
+}
+
+// dr342: na
+
+namespace dr343 { // dr343: no
+  // FIXME: dup 1710
+  template<typename T> struct A {
+    template<typename U> struct B {};
+  };
+  // FIXME: In these contexts, the 'template' keyword is optional.
+  template<typename T> struct C : public A<T>::B<T> { // expected-error {{use 'template'}}
+    C() : A<T>::B<T>() {} // expected-error {{use 'template'}}
+  };
+}
+
+namespace dr344 { // dr344: dup 1435
+  struct A { inline virtual ~A(); };
+  struct B { friend A::~A(); };
+}
+
+namespace dr345 { // dr345: yes
+  struct A {
+    struct X {};
+    int X; // expected-note {{here}}
+  };
+  struct B {
+    struct X {};
+  };
+  template <class T> void f(T t) { typename T::X x; } // expected-error {{refers to non-type member 'X'}}
+  void f(A a, B b) {
+    f(b);
+    f(a); // expected-note {{instantiation}}
+  }
+}
+
+// dr346: na
+
+namespace dr347 { // dr347: yes
+  struct base {
+    struct nested;
+    static int n;
+    static void f();
+    void g();
+  };
+
+  struct derived : base {};
+
+  struct derived::nested {}; // expected-error {{no struct named 'nested'}}
+  int derived::n; // expected-error {{no member named 'n'}}
+  void derived::f() {} // expected-error {{does not match any}}
+  void derived::g() {} // expected-error {{does not match any}}
+}
+
+// dr348: na
+
+namespace dr349 { // dr349: no
+  struct A {
+    template <class T> operator T ***() {
+      int ***p = 0;
+      return p; // expected-error {{cannot initialize return object of type 'const int ***' with an lvalue of type 'int ***'}}
+    }
+  };
+
+  // FIXME: This is valid.
+  A a;
+  const int *const *const *p1 = a; // expected-note {{in instantiation of}}
+
+  struct B {
+    template <class T> operator T ***() {
+      const int ***p = 0;
+      return p;
+    }
+  };
+
+  // FIXME: This is invalid.
+  B b;
+  const int *const *const *p2 = b;
+}
+
+// dr351: na
+
+namespace dr352 { // dr352: yes
+  namespace example1 {
+    namespace A {
+      enum E {};
+      template<typename R, typename A> void foo(E, R (*)(A)); // expected-note 2{{couldn't infer template argument 'R'}}
+    }
+
+    template<typename T> void arg(T);
+    template<typename T> int arg(T) = delete; // expected-note {{here}} expected-error 0-1{{extension}}
+
+    void f(A::E e) {
+      foo(e, &arg); // expected-error {{no matching function}}
+
+      using A::foo;
+      foo<int, int>(e, &arg); // expected-error {{deleted}}
+    }
+
+    int arg(int);
+
+    void g(A::E e) {
+      foo(e, &arg); // expected-error {{no matching function}}
+
+      using A::foo;
+      foo<int, int>(e, &arg); // ok, uses non-template
+    }
+  }
+
+  namespace contexts {
+    template<int I> void f1(int (&)[I]);
+    template<int I> void f2(int (&)[I+1]); // expected-note {{couldn't infer}}
+    template<int I> void f3(int (&)[I+1], int (&)[I]);
+    void f() {
+      int a[4];
+      int b[3];
+      f1(a);
+      f2(a); // expected-error {{no matching function}}
+      f3(a, b);
+    }
+
+    template<int I> struct S {};
+    template<int I> void g1(S<I>);
+    template<int I> void g2(S<I+1>); // expected-note {{couldn't infer}}
+    template<int I> void g3(S<I+1>, S<I>);
+    void g() {
+      S<4> a;
+      S<3> b;
+      g1(a);
+      g2(a); // expected-error {{no matching function}}
+      g3(a, b);
+    }
+
+    template<typename T> void h1(T = 0); // expected-note {{couldn't infer}}
+    template<typename T> void h2(T, T = 0);
+    void h() {
+      h1(); // expected-error {{no matching function}}
+      h1(0);
+      h1<int>();
+      h2(0);
+    }
+
+    template<typename T> int tmpl(T);
+    template<typename R, typename A> void i1(R (*)(A)); // expected-note 3{{couldn't infer}}
+    template<typename R, typename A> void i2(R, A, R (*)(A)); // expected-note {{not viable}}
+    void i() {
+      extern int single(int);
+      i1(single);
+      i2(0, 0, single);
+
+      extern int ambig(float), ambig(int);
+      i1(ambig); // expected-error {{no matching function}}
+      i2(0, 0, ambig);
+
+      extern void no_match(float), no_match(int);
+      i1(no_match); // expected-error {{no matching function}}
+      i2(0, 0, no_match); // expected-error {{no matching function}}
+
+      i1(tmpl); // expected-error {{no matching function}}
+      i2(0, 0, tmpl);
+    }
+  }
+
+  template<typename T> struct is_int;
+  template<> struct is_int<int> {};
+
+  namespace example2 {
+    template<typename T> int f(T (*p)(T)) { is_int<T>(); }
+    int g(int);
+    int g(char);
+    int i = f(g);
+  }
+
+  namespace example3 {
+    template<typename T> int f(T, T (*p)(T)) { is_int<T>(); }
+    int g(int);
+    char g(char);
+    int i = f(1, g);
+  }
+
+  namespace example4 {
+    template <class T> int f(T, T (*p)(T)) { is_int<T>(); }
+    char g(char);
+    template <class T> T g(T);
+    int i = f(1, g);
+  }
+
+  namespace example5 {
+    template<int I> class A {};
+    template<int I> void g(A<I+1>); // expected-note {{couldn't infer}}
+    template<int I> void f(A<I>, A<I+1>);
+    void h(A<1> a1, A<2> a2) {
+      g(a1); // expected-error {{no matching function}}
+      g<0>(a1);
+      f(a1, a2);
+    }
+  }
+}
+
+// dr353 needs an IRGen test.
+
+namespace dr354 { // dr354: yes c++11
+  // FIXME: Should we allow this in C++98 too?
+  struct S {};
+
+  template<int*> struct ptr {}; // expected-note +{{here}}
+  ptr<0> p0;
+  ptr<(int*)0> p1;
+  ptr<(float*)0> p2;
+  ptr<(int S::*)0> p3;
+#if __cplusplus < 201103L
+  // expected-error@-5 {{does not refer to any decl}}
+  // expected-error@-5 {{does not refer to any decl}}
+  // expected-error@-5 {{does not refer to any decl}}
+  // expected-error@-5 {{does not refer to any decl}}
+#else
+  // expected-error@-10 {{must be cast}}
+  // ok
+  // expected-error@-10 {{does not match}}
+  // expected-error@-10 {{does not match}}
+#endif
+
+  template<int*> int both();
+  template<int> int both();
+  int b0 = both<0>();
+  int b1 = both<(int*)0>();
+#if __cplusplus < 201103L
+  // expected-error@-2 {{no matching function}}
+  // expected-note@-6 {{candidate}}
+  // expected-note@-6 {{candidate}}
+#endif
+
+  template<int S::*> struct ptr_mem {}; // expected-note +{{here}}
+  ptr_mem<0> m0;
+  ptr_mem<(int S::*)0> m1;
+  ptr_mem<(float S::*)0> m2;
+  ptr_mem<(int *)0> m3;
+#if __cplusplus < 201103L
+  // expected-error@-5 {{cannot be converted}}
+  // expected-error@-5 {{is not a pointer to member constant}}
+  // expected-error@-5 {{cannot be converted}}
+  // expected-error@-5 {{cannot be converted}}
+#else
+  // expected-error@-10 {{must be cast}}
+  // ok
+  // expected-error@-10 {{does not match}}
+  // expected-error@-10 {{does not match}}
+#endif
+}
+
+struct dr355_S; // dr355: yes
+struct ::dr355_S {}; // expected-warning {{extra qualification}}
+namespace dr355 { struct ::dr355_S s; }
+
+// dr356: na
+
+namespace dr357 { // dr357: yes
+  template<typename T> struct A {
+    void f() const; // expected-note {{const qualified}}
+  };
+  template<typename T> void A<T>::f() {} // expected-error {{does not match}}
+
+  struct B {
+    template<typename T> void f();
+  };
+  template<typename T> void B::f() const {} // expected-error {{does not match}}
+}
+
+namespace dr358 { // dr358: yes
+  extern "C" void dr358_f();
+  namespace N {
+    int var;
+    extern "C" void dr358_f() { var = 10; }
+  }
+}
+
+namespace dr359 { // dr359: yes
+  // Note, the example in the DR is wrong; it doesn't contain an anonymous
+  // union.
+  struct E {
+    union {
+      struct {
+        int x;
+      } s;
+    } v;
+
+    union {
+      struct { // expected-error {{extension}}
+        int x;
+      } s;
+
+      struct S { // expected-error {{types cannot be declared in an anonymous union}}
+        int x;
+      } t;
+
+      union { // expected-error {{extension}}
+        int u;
+      };
+    };
+  };
+}
+
+// dr362: na
+// dr363: na
+
+namespace dr364 { // dr364: yes
+  struct S {
+    static void f(int);
+    void f(char);
+  };
+
+  void g() {
+    S::f('a'); // expected-error {{call to non-static}}
+    S::f(0);
+  }
+}
+
+#if "foo" // expected-error {{invalid token}} dr366: yes
+#endif
+
+namespace dr367 { // dr367: yes
+  // FIXME: These diagnostics are terrible. Don't diagnose an ill-formed global
+  // array as being a VLA!
+  int a[true ? throw 0 : 4]; // expected-error 2{{variable length array}}
+  int b[true ? 4 : throw 0];
+  int c[true ? *new int : 4]; // expected-error 2{{variable length array}}
+  int d[true ? 4 : *new int];
+#if __cplusplus < 201103L
+  // expected-error@-4 {{variable length array}} expected-error@-4 {{constant expression}}
+  // expected-error@-3 {{variable length array}} expected-error@-3 {{constant expression}}
+#endif
+}
+
+namespace dr368 { // dr368: yes
+  template<typename T, T> struct S {}; // expected-note {{here}}
+  template<typename T> int f(S<T, T()> *); // expected-error {{function type}}
+  //template<typename T> int g(S<T, (T())> *); // FIXME: crashes clang
+  template<typename T> int g(S<T, true ? T() : T()> *); // expected-note {{cannot have type 'dr368::X'}}
+  struct X {};
+  int n = g<X>(0); // expected-error {{no matching}}
+}
+
+// dr370: na
+
+namespace dr372 { // dr372: no
+  namespace example1 {
+    template<typename T> struct X {
+    protected:
+      typedef T Type; // expected-note 2{{protected}}
+    };
+    template<typename T> struct Y {};
+
+    // FIXME: These two are valid; deriving from T1<T> gives Z1 access to
+    // the protected member T1<T>::Type.
+    template<typename T,
+             template<typename> class T1,
+             template<typename> class T2> struct Z1 :
+      T1<T>,
+      T2<typename T1<T>::Type> {}; // expected-error {{protected}}
+
+    template<typename T,
+             template<typename> class T1,
+             template<typename> class T2> struct Z2 :
+      T2<typename T1<T>::Type>, // expected-error {{protected}}
+      T1<T> {};
+
+    Z1<int, X, Y> z1; // expected-note {{instantiation of}}
+    Z2<int, X, Y> z2; // expected-note {{instantiation of}}
+  }
+
+  namespace example2 {
+    struct X {
+    private:
+      typedef int Type; // expected-note {{private}}
+    };
+    template<typename T> struct A {
+      typename T::Type t; // expected-error {{private}}
+    };
+    A<X> ax; // expected-note {{instantiation of}}
+  }
+
+  namespace example3 {
+    struct A {
+    protected:
+      typedef int N; // expected-note 2{{protected}}
+    };
+
+    template<typename T> struct B {};
+    template<typename U> struct C : U, B<typename U::N> {}; // expected-error {{protected}}
+    template<typename U> struct D : B<typename U::N>, U {}; // expected-error {{protected}}
+
+    C<A> x; // expected-note {{instantiation of}}
+    D<A> y; // expected-note {{instantiation of}}
+  }
+
+  namespace example4 {
+    class A {
+      class B {};
+      friend class X;
+    };
+
+    struct X : A::B {
+      A::B mx;
+      class Y {
+        A::B my;
+      };
+    };
+  }
+}
+
+namespace dr373 { // dr373: no
+  // FIXME: This is valid.
+  namespace X { int dr373; } // expected-note 2{{here}}
+  struct dr373 { // expected-note {{here}}
+    void f() {
+      using namespace dr373::X; // expected-error {{no namespace named 'X' in 'dr373::dr373'}}
+      int k = dr373; // expected-error {{does not refer to a value}}
+
+      namespace Y = dr373::X; // expected-error {{no namespace named 'X' in 'dr373::dr373'}}
+      k = Y::dr373;
+    }
+  };
+}
+
+namespace dr374 { // dr374: yes c++11
+  namespace N {
+    template<typename T> void f();
+    template<typename T> struct A { void f(); };
+  }
+  template<> void N::f<char>() {}
+  template<> void N::A<char>::f() {}
+  template<> struct N::A<int> {};
+#if __cplusplus < 201103L
+  // expected-error@-4 {{extension}} expected-note@-7 {{here}}
+  // expected-error@-4 {{extension}} expected-note@-7 {{here}}
+  // expected-error@-4 {{extension}} expected-note@-8 {{here}}
+#endif
+}
+
+// dr375: dup 345
+// dr376: na
+
+namespace dr377 { // dr377: yes
+  enum E { // expected-error {{enumeration values exceed range of largest integer}}
+    a = -__LONG_LONG_MAX__ - 1, // expected-error 0-1{{extension}}
+    b = 2 * (unsigned long long)__LONG_LONG_MAX__ // expected-error 0-2{{extension}}
+  };
+}
+
+// dr378: dup 276
+// dr379: na
+
+namespace dr381 { // dr381: yes
+  struct A {
+    int a;
+  };
+  struct B : virtual A {};
+  struct C : B {};
+  struct D : B {};
+  struct E : public C, public D {};
+  struct F : public A {};
+  void f() {
+    E e;
+    e.B::a = 0; // expected-error {{ambiguous conversion}}
+    F f;
+    f.A::a = 1;
+  }
+}
+
+namespace dr382 { // dr382: yes c++11
+  // FIXME: Should we allow this in C++98 mode?
+  struct A { typedef int T; };
+  typename A::T t;
+  typename dr382::A a;
+#if __cplusplus < 201103L
+  // expected-error@-3 {{occurs outside of a template}}
+  // expected-error@-3 {{occurs outside of a template}}
+#endif
+  typename A b; // expected-error {{expected a qualified name}}
+}
+
+namespace dr383 { // dr383: yes
+  struct A { A &operator=(const A&); };
+  struct B { ~B(); };
+  union C { C &operator=(const C&); };
+  union D { ~D(); };
+  int check[(__is_pod(A) || __is_pod(B) || __is_pod(C) || __is_pod(D)) ? -1 : 1];
+}
+
+namespace dr384 { // dr384: yes
+  namespace N1 {
+    template<typename T> struct Base {};
+    template<typename T> struct X {
+      struct Y : public Base<T> {
+        Y operator+(int) const;
+      };
+      Y f(unsigned i) { return Y() + i; }
+    };
+  }
+
+  namespace N2 {
+    struct Z {};
+    template<typename T> int *operator+(T, unsigned);
+  }
+
+  int main() {
+    N1::X<N2::Z> v;
+    v.f(0);
+  }
+}
+
+namespace dr385 { // dr385: yes
+  struct A { protected: void f(); }; 
+  struct B : A { using A::f; };
+  struct C : A { void g(B b) { b.f(); } };
+  void h(B b) { b.f(); }
+
+  struct D { int n; }; // expected-note {{member}}
+  struct E : protected D {}; // expected-note 2{{protected}}
+  struct F : E { friend int i(E); };
+  int i(E e) { return e.n; } // expected-error {{protected base}} expected-error {{protected member}}
+}
+
+namespace dr387 { // dr387: yes
+  namespace old {
+    template<typename T> class number {
+      number(int); // expected-note 2{{here}}
+      friend number gcd(number &x, number &y) {}
+    };
+
+    void g() {
+      number<double> a(3), b(4); // expected-error 2{{private}}
+      a = gcd(a, b);
+      b = gcd(3, 4); // expected-error {{undeclared}}
+    }
+  }
+
+  namespace newer {
+    template <typename T> class number {
+    public:
+      number(int);
+      friend number gcd(number x, number y) { return 0; }
+    };
+
+    void g() {
+      number<double> a(3), b(4);
+      a = gcd(a, b);
+      b = gcd(3, 4); // expected-error {{undeclared}}
+    }
+  }
+}
+
+// FIXME: dr388 needs codegen test
+
+namespace dr389 { // dr389: no
+  struct S {
+    typedef struct {} A;
+    typedef enum {} B;
+    typedef struct {} const C; // expected-note 0-2{{here}}
+    typedef enum {} const D; // expected-note 0-1{{here}}
+  };
+  template<typename> struct T {};
+
+  struct WithLinkage1 {};
+  enum WithLinkage2 {};
+  typedef struct {} *WithLinkage3a, WithLinkage3b;
+  typedef enum {} WithLinkage4a, *WithLinkage4b;
+  typedef S::A WithLinkage5;
+  typedef const S::B WithLinkage6;
+  typedef int WithLinkage7;
+  typedef void (*WithLinkage8)(WithLinkage2 WithLinkage1::*, WithLinkage5 *);
+  typedef T<WithLinkage5> WithLinkage9;
+
+  typedef struct {} *WithoutLinkage1; // expected-note 0-1{{here}}
+  typedef enum {} const WithoutLinkage2; // expected-note 0-1{{here}}
+  // These two types don't have linkage even though they are externally visible
+  // and the ODR requires them to be merged across TUs.
+  typedef S::C WithoutLinkage3;
+  typedef S::D WithoutLinkage4;
+  typedef void (*WithoutLinkage5)(int (WithoutLinkage3::*)(char));
+
+#if __cplusplus >= 201103L
+  // This has linkage even though its template argument does not.
+  // FIXME: This is probably a defect.
+  typedef T<WithoutLinkage1> WithLinkage10;
+#else
+  typedef int WithLinkage10; // dummy
+
+  typedef T<WithLinkage1> GoodArg1;
+  typedef T<WithLinkage2> GoodArg2;
+  typedef T<WithLinkage3a> GoodArg3a;
+  typedef T<WithLinkage3b> GoodArg3b;
+  typedef T<WithLinkage4a> GoodArg4a;
+  typedef T<WithLinkage4b> GoodArg4b;
+  typedef T<WithLinkage5> GoodArg5;
+  typedef T<WithLinkage6> GoodArg6;
+  typedef T<WithLinkage7> GoodArg7;
+  typedef T<WithLinkage8> GoodArg8;
+  typedef T<WithLinkage9> GoodArg9;
+
+  typedef T<WithoutLinkage1> BadArg1; // expected-error{{template argument uses}}
+  typedef T<WithoutLinkage2> BadArg2; // expected-error{{template argument uses}}
+  typedef T<WithoutLinkage3> BadArg3; // expected-error{{template argument uses}}
+  typedef T<WithoutLinkage4> BadArg4; // expected-error{{template argument uses}}
+  typedef T<WithoutLinkage5> BadArg5; // expected-error{{template argument uses}}
+#endif
+
+  extern WithLinkage1 withLinkage1;
+  extern WithLinkage2 withLinkage2;
+  extern WithLinkage3a withLinkage3a;
+  extern WithLinkage3b withLinkage3b;
+  extern WithLinkage4a withLinkage4a;
+  extern WithLinkage4b withLinkage4b;
+  extern WithLinkage5 withLinkage5;
+  extern WithLinkage6 withLinkage6;
+  extern WithLinkage7 withLinkage7;
+  extern WithLinkage8 withLinkage8;
+  extern WithLinkage9 withLinkage9;
+  extern WithLinkage10 withLinkage10;
+
+  // FIXME: These are all ill-formed.
+  extern WithoutLinkage1 withoutLinkage1;
+  extern WithoutLinkage2 withoutLinkage2;
+  extern WithoutLinkage3 withoutLinkage3;
+  extern WithoutLinkage4 withoutLinkage4;
+  extern WithoutLinkage5 withoutLinkage5;
+
+  // OK, extern "C".
+  extern "C" {
+    extern WithoutLinkage1 dr389_withoutLinkage1;
+    extern WithoutLinkage2 dr389_withoutLinkage2;
+    extern WithoutLinkage3 dr389_withoutLinkage3;
+    extern WithoutLinkage4 dr389_withoutLinkage4;
+    extern WithoutLinkage5 dr389_withoutLinkage5;
+  }
+
+  // OK, defined.
+  WithoutLinkage1 withoutLinkageDef1;
+  WithoutLinkage2 withoutLinkageDef2 = WithoutLinkage2();
+  WithoutLinkage3 withoutLinkageDef3 = {};
+  WithoutLinkage4 withoutLinkageDef4 = WithoutLinkage4();
+  WithoutLinkage5 withoutLinkageDef5;
+
+  void use(const void *);
+  void use_all() {
+    use(&withLinkage1); use(&withLinkage2); use(&withLinkage3a); use(&withLinkage3b);
+    use(&withLinkage4a); use(&withLinkage4b); use(&withLinkage5); use(&withLinkage6);
+    use(&withLinkage7); use(&withLinkage8); use(&withLinkage9); use(&withLinkage10);
+
+    use(&withoutLinkage1); use(&withoutLinkage2); use(&withoutLinkage3);
+    use(&withoutLinkage4); use(&withoutLinkage5);
+
+    use(&dr389_withoutLinkage1); use(&dr389_withoutLinkage2);
+    use(&dr389_withoutLinkage3); use(&dr389_withoutLinkage4);
+    use(&dr389_withoutLinkage5);
+
+    use(&withoutLinkageDef1); use(&withoutLinkageDef2); use(&withoutLinkageDef3);
+    use(&withoutLinkageDef4); use(&withoutLinkageDef5);
+  }
+
+  void local() {
+    // FIXME: This is ill-formed.
+    extern WithoutLinkage1 withoutLinkageLocal;
+  }
+}
+
+namespace dr390 { // dr390: yes
+  template<typename T>
+  struct A {
+    A() { f(); } // expected-warning {{call to pure virt}}
+    virtual void f() = 0; // expected-note {{here}}
+    virtual ~A() = 0;
+  };
+  template<typename T> A<T>::~A() { T::error; } // expected-error {{cannot be used prior to}}
+  template<typename T> void A<T>::f() { T::error; } // ok, not odr-used
+  struct B : A<int> { // expected-note 2{{in instantiation of}}
+    void f() {}
+  } b;
+}
+
+namespace dr391 { // dr391: yes c++11
+  // FIXME: Should this apply to C++98 too?
+  class A { A(const A&); }; // expected-note 0-1{{here}}
+  A fa();
+  const A &a = fa();
+#if __cplusplus < 201103L
+  // expected-error@-2 {{C++98 requires an accessible copy constructor}}
+#endif
+
+  struct B { B(const B&) = delete; }; // expected-error 0-1{{extension}} expected-note 0-1{{here}}
+  B fb();
+  const B &b = fb();
+#if __cplusplus < 201103L
+  // expected-error@-2 {{deleted}}
+#endif
+
+  template<typename T>
+  struct C {
+    C(const C&) { T::error; }
+  };
+  C<int> fc();
+  const C<int> &c = fc();
+}
+
+// dr392 FIXME write codegen test
+// dr394: na
+
+namespace dr395 { // dr395: yes
+  struct S {
+    template <typename T, int N>(&operator T())[N]; // expected-error {{must use a typedef}}
+    template <typename T, int N> operator(T (&)[N])(); // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error +{{}}
+    template <typename T> operator T *() const { return 0; }
+    template <typename T, typename U> operator T U::*() const { return 0; }
+    template <typename T, typename U> operator T (U::*)()() const { return 0; } // expected-error +{{}}
+  };
+
+  struct null1_t {
+    template <class T, class U> struct ptr_mem_fun_t {
+      typedef T (U::*type)();
+    };
+
+    template <class T, class U>
+    operator typename ptr_mem_fun_t<T, U>::type() const { // expected-note {{couldn't infer}}
+      return 0;
+    }
+  } null1;
+  int (S::*p)() = null1; // expected-error {{no viable conversion}}
+
+  template <typename T> using id = T; // expected-error 0-1{{extension}}
+
+  struct T {
+    template <typename T, int N> operator id<T[N]> &();
+    template <typename T, typename U> operator id<T (U::*)()>() const;
+  };
+
+  struct null2_t {
+    template<class T, class U> using ptr_mem_fun_t = T (U::*)(); // expected-error 0-1{{extension}}
+    template<class T, class U> operator ptr_mem_fun_t<T, U>() const { return 0; };
+  } null2;
+  int (S::*q)() = null2;
+}
+
+namespace dr396 { // dr396: yes
+  void f() {
+    auto int a(); // expected-error {{storage class on function}}
+    int (i); // expected-note {{previous}}
+    auto int (i); // expected-error {{redefinition}}
+#if __cplusplus >= 201103L
+  // expected-error@-4 {{'auto' storage class}} expected-error@-2 {{'auto' storage class}}
+#endif
+  }
+}
+
+// dr397: sup 1823
+
+namespace dr398 { // dr398: yes
+  namespace example1 {
+    struct S {
+      static int const I = 42;
+    };
+    template <int N> struct X {};
+    template <typename T> void f(X<T::I> *) {}
+    template <typename T> void f(X<T::J> *) {}
+    void foo() { f<S>(0); }
+  }
+
+  namespace example2 {
+    template <int I> struct X {};
+    template <template <class T> class> struct Z {};
+    template <class T> void f(typename T::Y *) {} // expected-note 2{{substitution failure}}
+    template <class T> void g(X<T::N> *) {} // expected-note {{substitution failure}}
+    template <class T> void h(Z<T::template TT> *) {} // expected-note {{substitution failure}}
+    struct A {};
+    struct B {
+      int Y;
+    };
+    struct C {
+      typedef int N;
+    };
+    struct D {
+      typedef int TT;
+    };
+
+    void test() {
+      f<A>(0); // expected-error {{no matching function}}
+      f<B>(0); // expected-error {{no matching function}}
+      g<C>(0); // expected-error {{no matching function}}
+      h<D>(0); // expected-error {{no matching function}}
+    }
+  }
+}
diff --git a/test/CXX/drs/dr412.cpp b/test/CXX/drs/dr412.cpp
new file mode 100644
index 0000000..cb33e20
--- /dev/null
+++ b/test/CXX/drs/dr412.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -DNOEXCEPT="throw()" -DBAD_ALLOC="throw(std::bad_alloc)"
+// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -DNOEXCEPT=noexcept -DBAD_ALLOC=
+// RUN: %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -DNOEXCEPT=noexcept -DBAD_ALLOC=
+
+// dr412: yes
+// lwg404: yes
+// lwg2340: yes
+
+// FIXME: __SIZE_TYPE__ expands to 'long long' on some targets.
+__extension__ typedef __SIZE_TYPE__ size_t;
+namespace std { struct bad_alloc {}; }
+
+inline void* operator new(size_t) BAD_ALLOC; // expected-error {{cannot be declared 'inline'}}
+inline void* operator new[](size_t) BAD_ALLOC; // expected-error {{cannot be declared 'inline'}}
+inline void operator delete(void*) NOEXCEPT; // expected-error {{cannot be declared 'inline'}}
+inline void operator delete[](void*) NOEXCEPT; // expected-error {{cannot be declared 'inline'}}
+#if __cplusplus >= 201402L
+inline void operator delete(void*, size_t) NOEXCEPT; // expected-error {{cannot be declared 'inline'}}
+inline void operator delete[](void*, size_t) NOEXCEPT; // expected-error {{cannot be declared 'inline'}}
+#endif
diff --git a/test/CXX/drs/dr4xx.cpp b/test/CXX/drs/dr4xx.cpp
index 1d3b940..815dbfc 100644
--- a/test/CXX/drs/dr4xx.cpp
+++ b/test/CXX/drs/dr4xx.cpp
@@ -1,6 +1,140 @@
-// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
-// expected-no-diagnostics
+// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+
+// FIXME: __SIZE_TYPE__ expands to 'long long' on some targets.
+__extension__ typedef __SIZE_TYPE__ size_t;
+
+namespace std { struct type_info; }
+
+namespace dr400 { // dr400: yes
+  struct A { int a; struct a {}; }; // expected-note 2{{conflicting}} expected-note {{ambiguous}}
+  struct B { int a; struct a {}; }; // expected-note 2{{target}} expected-note {{ambiguous}}
+  struct C : A, B { using A::a; struct a b; };
+  struct D : A, B { using A::a; using B::a; struct a b; }; // expected-error 2{{conflicts}}
+  struct E : A, B { struct a b; }; // expected-error {{found in multiple base classes}}
+}
+
+namespace dr401 { // dr401: yes
+  template<class T, class U = typename T::type> class A : public T {}; // expected-error {{protected}} expected-error 2{{private}}
+
+  class B {
+  protected:
+    typedef int type; // expected-note {{protected}}
+  };
+
+  class C {
+    typedef int type; // expected-note {{private}}
+    friend class A<C>; // expected-note {{default argument}}
+  };
+
+  class D {
+    typedef int type; // expected-note {{private}}
+    friend class A<D, int>;
+  };
+
+  A<B> *b; // expected-note {{default argument}}
+  // FIXME: We're missing the "in instantiation of" note for the default
+  // argument here.
+  A<D> *d;
+
+  struct E {
+    template<class T, class U = typename T::type> class A : public T {};
+  };
+  class F {
+    typedef int type;
+    friend class E;
+  };
+  E::A<F> eaf; // ok, default argument is in befriended context
+
+  // FIXME: Why do we get different diagnostics in C++11 onwards here? We seem
+  // to not treat the default template argument as a SFINAE context in C++98.
+  template<class T, class U = typename T::type> void f(T) {}
+  void g(B b) { f(b); }
+#if __cplusplus < 201103L
+  // expected-error@-3 0-1{{extension}} expected-error@-3 {{protected}} expected-note@-3 {{instantiation}}
+  // expected-note@-3 {{substituting}}
+#else
+  // expected-error@-5 {{no matching}} expected-note@-6 {{protected}}
+#endif
+}
+
+namespace dr403 { // dr403: yes
+  namespace A {
+    struct S {};
+    int f(void*);
+  }
+  template<typename T> struct X {};
+  typedef struct X<A::S>::X XS;
+  XS *p;
+  int k = f(p); // ok, finds A::f, even though type XS is a typedef-name
+                // referring to an elaborated-type-specifier naming a
+                // injected-class-name, which is about as far from a
+                // template-id as we can make it.
+}
+
+// dr404: na
+// (NB: also sup 594)
+
+namespace dr406 { // dr406: yes
+  typedef struct {
+    static int n; // expected-error {{static data member 'n' not allowed in anonymous struct}}
+  } A;
+}
+
+namespace dr407 { // dr407: no
+  struct S;
+  typedef struct S S;
+  void f() {
+    struct S *p;
+    {
+      typedef struct S S; // expected-note {{here}}
+      struct S *p; // expected-error {{refers to a typedef}}
+    }
+  }
+  struct S {};
+
+  namespace UsingDir {
+    namespace A {
+      struct S {}; // expected-note {{found}}
+    }
+    namespace B {
+      typedef int S; // expected-note {{found}}
+    }
+    namespace C {
+      using namespace A;
+      using namespace B;
+      struct S s; // expected-error {{ambiguous}}
+    }
+    namespace D {
+      // FIXME: This is valid.
+      using A::S;
+      typedef struct S S; // expected-note {{here}}
+      struct S s; // expected-error {{refers to a typedef}}
+    }
+    namespace E {
+      // FIXME: The standard doesn't say whether this is valid.
+      typedef A::S S;
+      using A::S;
+      struct S s;
+    }
+    namespace F {
+      typedef A::S S; // expected-note {{here}}
+    }
+    // FIXME: The standard doesn't say what to do in these cases, but
+    // our behavior should not depend on the order of the using-directives.
+    namespace G {
+      using namespace A;
+      using namespace F;
+      struct S s;
+    }
+    namespace H {
+      using namespace F;
+      using namespace A;
+      struct S s; // expected-error {{refers to a typedef}}
+    }
+  }
+}
 
 namespace dr408 { // dr408: 3.4
   template<int N> void g() { int arr[N != 1 ? 1 : -1]; }
@@ -30,3 +164,1060 @@
   template<> int R<int>::arr[2];
   template void R<int>::f();
 }
+
+namespace dr409 { // dr409: yes
+  template<typename T> struct A {
+    typedef int B;
+    B b1;
+    A::B b2;
+    A<T>::B b3;
+    A<T*>::B b4; // expected-error {{missing 'typename'}}
+  };
+}
+
+namespace dr410 { // dr410: no
+  template<class T> void f(T);
+  void g(int);
+  namespace M {
+    template<class T> void h(T);
+    template<class T> void i(T);
+    struct A {
+      friend void f<>(int);
+      friend void h<>(int);
+      friend void g(int);
+      template<class T> void i(T);
+      friend void i<>(int);
+    private:
+      static void z(); // expected-note {{private}}
+    };
+
+    template<> void h(int) { A::z(); }
+    // FIXME: This should be ill-formed. The member A::i<> is befriended,
+    // not this function.
+    template<> void i(int) { A::z(); }
+  }
+  template<> void f(int) { M::A::z(); }
+  void g(int) { M::A::z(); } // expected-error {{private}}
+}
+
+// dr412 is in its own file.
+
+namespace dr413 { // dr413: yes
+  struct S {
+    int a;
+    int : 17;
+    int b;
+  };
+  S s = { 1, 2, 3 }; // expected-error {{excess elements}}
+
+  struct E {};
+  struct T { // expected-note {{here}}
+    int a;
+    E e;
+    int b;
+  };
+  T t1 = { 1, {}, 2 };
+  T t2 = { 1, 2 }; // expected-error {{aggregate with no elements requires explicit braces}}
+}
+
+namespace dr414 { // dr414: dup 305
+  struct X {};
+  void f() {
+    X x;
+    struct X {};
+    x.~X();
+  }
+}
+
+namespace dr415 { // dr415: yes
+  template<typename T> void f(T, ...) { T::error; }
+  void f(int, int);
+  void g() { f(0, 0); } // ok
+}
+
+namespace dr416 { // dr416: yes
+  extern struct A a;
+  int &operator+(const A&, const A&);
+  int &k = a + a;
+  struct A { float &operator+(A&); };
+  float &f = a + a;
+}
+
+namespace dr417 { // dr417: no
+  struct A;
+  struct dr417::A {}; // expected-warning {{extra qualification}}
+  struct B { struct X; };
+  struct C : B {};
+  struct C::X {}; // expected-error {{no struct named 'X' in 'dr417::C'}}
+  struct B::X { struct Y; };
+  struct C::X::Y {}; // ok!
+  namespace N {
+    struct D;
+    struct E;
+    struct F;
+    struct H;
+  }
+  // FIXME: This is ill-formed.
+  using N::D;
+  struct dr417::D {}; // expected-warning {{extra qualification}}
+  using namespace N;
+  struct dr417::E {}; // expected-warning {{extra qualification}} expected-error {{no struct named 'E'}}
+  struct N::F {};
+  struct G;
+  using N::H;
+  namespace M {
+    struct dr417::G {}; // expected-error {{namespace 'M' does not enclose}}
+    struct dr417::H {}; // expected-error {{namespace 'M' does not enclose}}
+  }
+}
+
+namespace dr420 { // dr420: yes
+  template<typename T> struct ptr {
+    T *operator->() const;
+    T &operator*() const;
+  };
+  template<typename T, typename P> void test(P p) {
+    p->~T();
+    p->T::~T();
+    (*p).~T();
+    (*p).T::~T();
+  }
+  struct X {};
+  template void test<int>(int*);
+  template void test<int>(ptr<int>);
+  template void test<X>(X*);
+  template void test<X>(ptr<X>);
+
+  template<typename T>
+  void test2(T p) {
+    p->template Y<int>::~Y<int>();
+    p->~Y<int>();
+    // FIXME: This is ill-formed, but this diagnostic is terrible. We should
+    // reject this in the parser.
+    p->template ~Y<int>(); // expected-error 2{{no member named '~typename Y<int>'}}
+  }
+  template<typename T> struct Y {};
+  template void test2(Y<int>*); // expected-note {{instantiation}}
+  template void test2(ptr<Y<int> >); // expected-note {{instantiation}}
+
+  void test3(int *p, ptr<int> q) {
+    typedef int Int;
+    p->~Int();
+    q->~Int();
+    p->Int::~Int();
+    q->Int::~Int();
+  }
+
+#if __cplusplus >= 201103L
+  template<typename T> using id = T;
+  struct A { template<typename T> using id = T; };
+  void test4(int *p, ptr<int> q) {
+    p->~id<int>();
+    q->~id<int>();
+    p->id<int>::~id<int>();
+    q->id<int>::~id<int>();
+    p->template id<int>::~id<int>(); // expected-error {{expected unqualified-id}}
+    q->template id<int>::~id<int>(); // expected-error {{expected unqualified-id}}
+    p->A::template id<int>::~id<int>();
+    q->A::template id<int>::~id<int>();
+  }
+#endif
+}
+
+namespace dr421 { // dr421: yes
+  struct X { X(); int n; int &r; };
+  int *p = &X().n; // expected-error {{taking the address of a temporary}}
+  int *q = &X().r;
+}
+
+namespace dr422 { // dr422: yes
+  template<typename T, typename U> void f() {
+    typedef T type; // expected-note {{prev}}
+    typedef U type; // expected-error {{redef}}
+  }
+  template void f<int, int>();
+  template void f<int, char>(); // expected-note {{instantiation}}
+}
+
+namespace dr423 { // dr423: yes
+  template<typename T> struct X { operator T&(); };
+  void f(X<int> x) { x += 1; }
+}
+
+namespace dr424 { // dr424: yes
+  struct A {
+    typedef int N; // expected-note {{previous}}
+    typedef int N; // expected-error {{redefinition}}
+
+    struct X;
+    typedef X X; // expected-note {{previous}}
+    struct X {};
+
+    struct X *p;
+    struct A::X *q;
+    X *r;
+
+    typedef X X; // expected-error {{redefinition}}
+  };
+  struct B {
+    typedef int N;
+  };
+  struct C : B {
+    typedef int N; // expected-note {{previous}}
+    typedef int N; // expected-error {{redefinition}}
+  };
+}
+
+namespace dr425 { // dr425: yes
+  struct A { template<typename T> operator T() const; } a;
+  float f = 1.0f * a; // expected-error {{ambiguous}} expected-note 5+{{built-in candidate}}
+
+  template<typename T> struct is_float;
+  template<> struct is_float<float> { typedef void type; };
+
+  struct B {
+    template<typename T, typename U = typename is_float<T>::type> operator T() const; // expected-error 0-1{{extension}}
+  } b;
+  float g = 1.0f * b; // ok
+}
+
+namespace dr427 { // dr427: yes
+  struct B {};
+  struct D : public B {
+    D(B &) = delete; // expected-error 0-1{{extension}} expected-note {{deleted}}
+  };
+
+  extern D d1;
+  B &b = d1;
+  const D &d2 = static_cast<const D&>(b);
+  const D &d3 = (const D&)b;
+  const D &d4(b); // expected-error {{deleted}}
+}
+
+namespace dr428 { // dr428: yes
+  template<typename T> T make();
+  extern struct X x; // expected-note 5{{forward declaration}}
+  void f() {
+    throw void(); // expected-error {{cannot throw}}
+    throw make<void*>();
+    throw make<const volatile void*>();
+    throw x; // expected-error {{cannot throw}}
+    throw make<X&>(); // expected-error {{cannot throw}}
+    throw make<X*>(); // expected-error {{cannot throw}}
+    throw make<const volatile X&>(); // expected-error {{cannot throw}}
+    throw make<const volatile X*>(); // expected-error {{cannot throw}}
+  }
+}
+
+namespace dr429 { // dr429: yes c++11
+  // FIXME: This rule is obviously intended to apply to C++98 as well.
+  struct A {
+    static void *operator new(size_t, size_t);
+    static void operator delete(void*, size_t);
+  } *a = new (0) A;
+#if __cplusplus >= 201103L
+  // expected-error@-2 {{'new' expression with placement arguments refers to non-placement 'operator delete'}}
+  // expected-note@-4 {{here}}
+#endif
+  struct B {
+    static void *operator new(size_t, size_t);
+    static void operator delete(void*);
+    static void operator delete(void*, size_t);
+  } *b = new (0) B; // ok, second delete is not a non-placement deallocation function
+}
+
+namespace dr430 { // dr430: yes c++11
+  // resolved by n2239
+  // FIXME: This should apply in C++98 too.
+  void f(int n) {
+    int a[] = { n++, n++, n++ };
+#if __cplusplus < 201103L
+    // expected-warning@-2 {{multiple unsequenced modifications to 'n'}}
+#endif
+  }
+}
+
+namespace dr431 { // dr431: yes
+  struct A {
+    template<typename T> T *get();
+    template<typename T> struct B {
+      template<typename U> U *get();
+    };
+  };
+
+  template<typename T> void f(A a) {
+    a.get<A>()->get<T>();
+    a.get<T>()
+        ->get<T>(); // expected-error {{use 'template'}}
+    a.get<T>()->template get<T>();
+    a.A::get<T>();
+    A::B<int> *b = a.get<A::B<int> >();
+    b->get<int>();
+    b->A::B<int>::get<int>();
+    b->A::B<int>::get<T>();
+    b->A::B<T>::get<int>(); // expected-error {{use 'template'}}
+    b->A::B<T>::template get<int>();
+    b->A::B<T>::get<T>(); // expected-error {{use 'template'}}
+    b->A::B<T>::template get<T>();
+    A::B<T> *c = a.get<A::B<T> >();
+    c->get<int>(); // expected-error {{use 'template'}}
+    c->template get<int>();
+  }
+}
+
+namespace dr432 { // dr432: yes
+  template<typename T> struct A {};
+  template<typename T> struct B : A<B> {}; // expected-error {{requires template arguments}} expected-note {{declared}}
+  template<typename T> struct C : A<C<T> > {};
+#if __cplusplus >= 201103L
+  template<typename T> struct D : decltype(A<D>()) {}; // expected-error {{requires template arguments}} expected-note {{declared}}
+#endif
+}
+
+namespace dr433 { // dr433: yes
+  template<class T> struct S {
+    void f(union U*);
+  };
+  U *p;
+  template<class T> void S<T>::f(union U*) {}
+
+  S<int> s;
+}
+
+namespace dr434 { // dr434: yes
+  void f() {
+    const int ci = 0;
+    int *pi = 0;
+    const int *&rpci = pi; // expected-error {{cannot bind}}
+    rpci = &ci;
+    *pi = 1;
+  }
+}
+
+// dr435: na
+
+namespace dr436 { // dr436: yes
+  enum E { f }; // expected-note {{previous}}
+  void f(); // expected-error {{redefinition}}
+}
+
+namespace dr437 { // dr437: no
+  // This is superseded by 1308, which is in turn superseded by 1330,
+  // which restores this rule.
+  template<typename U> struct T : U {}; // expected-error {{incomplete}}
+  struct S { // expected-note {{not complete}}
+    void f() throw(S);
+    void g() throw(T<S>); // expected-note {{in instantiation of}}
+    struct U; // expected-note {{forward}}
+    void h() throw(U); // expected-error {{incomplete}}
+    struct U {};
+  };
+}
+
+// dr438 FIXME write a codegen test
+// dr439 FIXME write a codegen test
+// dr441 FIXME write a codegen test
+// dr442: sup 348
+// dr443: na
+
+namespace dr444 { // dr444: yes
+  struct D;
+  struct B { // expected-note {{candidate is the implicit copy}} expected-note 0-1 {{implicit move}}
+    D &operator=(D &) = delete; // expected-error 0-1{{extension}} expected-note {{deleted}}
+  };
+  struct D : B { // expected-note {{candidate is the implicit}} expected-note 0-1 {{implicit move}}
+    using B::operator=;
+  } extern d;
+  void f() {
+    d = d; // expected-error {{deleted}}
+  }
+}
+
+namespace dr445 { // dr445: yes
+  class A { void f(); }; // expected-note {{private}}
+  struct B {
+    friend void A::f(); // expected-error {{private}}
+  };
+}
+
+namespace dr446 { // dr446: yes
+  struct C;
+  struct A {
+    A();
+    A(const A&) = delete; // expected-error 0-1{{extension}} expected-note +{{deleted}}
+    A(const C&);
+  };
+  struct C : A {};
+  void f(A a, bool b, C c) {
+    void(b ? a : a);
+    b ? A() : a; // expected-error {{deleted}}
+    b ? a : A(); // expected-error {{deleted}}
+    b ? A() : A(); // expected-error {{deleted}}
+
+    void(b ? a : c);
+    b ? a : C(); // expected-error {{deleted}}
+    b ? c : A(); // expected-error {{deleted}}
+    b ? A() : C(); // expected-error {{deleted}}
+  }
+}
+
+namespace dr447 { // dr447: yes
+  struct A { int n; int a[4]; };
+  template<int> struct U {
+    typedef int type;
+    template<typename V> static void h();
+  };
+  template<typename T> U<sizeof(T)> g(T);
+  template<typename T, int N> void f(int n) {
+    // ok, not type dependent
+    g(__builtin_offsetof(A, n)).h<int>();
+    g(__builtin_offsetof(T, n)).h<int>();
+    // value dependent if first argument is a dependent type
+    U<__builtin_offsetof(A, n)>::type a;
+    U<__builtin_offsetof(T, n)>::type b; // expected-error +{{}} expected-warning 0+{{}}
+    // as an extension, we allow the member-designator to include array indices
+    g(__builtin_offsetof(A, a[0])).h<int>(); // expected-error {{extension}}
+    g(__builtin_offsetof(A, a[N])).h<int>(); // expected-error {{extension}}
+    U<__builtin_offsetof(A, a[0])>::type c; // expected-error {{extension}}
+    U<__builtin_offsetof(A, a[N])>::type d; // expected-error {{extension}} expected-error +{{}} expected-warning 0+{{}}
+  }
+}
+
+namespace dr448 { // dr448: yes
+  template<typename T = int> void f(int); // expected-error 0-1{{extension}} expected-note {{no known conversion}}
+  template<typename T> void g(T t) {
+    f<T>(t); // expected-error {{neither visible in the template definition nor found by argument-dependent lookup}}
+    dr448::f(t); // expected-error {{no matching function}}
+  }
+  template<typename T> void f(T); // expected-note {{should be declared prior to the call site}}
+  namespace HideFromADL { struct X {}; }
+  template void g(int); // ok
+  template void g(HideFromADL::X); // expected-note {{instantiation of}}
+}
+
+// dr449: na
+
+namespace dr450 { // dr450: yes
+  typedef int A[3];
+  void f1(const A &);
+  void f2(A &); // expected-note +{{not viable}}
+  struct S { A n; };
+  void g() {
+    f1(S().n);
+    f2(S().n); // expected-error {{no match}}}
+  }
+#if __cplusplus >= 201103L
+  void h() {
+    f1(A{});
+    f2(A{}); // expected-error {{no match}}
+  }
+#endif
+}
+
+namespace dr451 { // dr451: yes
+  const int a = 1 / 0; // expected-warning {{undefined}}
+  const int b = 1 / 0; // expected-warning {{undefined}}
+  int arr[b]; // expected-error +{{variable length arr}}
+}
+
+namespace dr452 { // dr452: yes
+  struct A {
+    int a, b, c;
+    A *p;
+    int f();
+    A() : a(f()), b(this->f() + a), c(this->a), p(this) {}
+  };
+}
+
+// dr454 FIXME write a codegen test
+
+namespace dr456 { // dr456: yes
+  // sup 903 c++11
+  const int null = 0;
+  void *p = null;
+#if __cplusplus >= 201103L
+  // expected-error@-2 {{cannot initialize}}
+#else
+  // expected-warning@-4 {{null}}
+#endif
+
+  const bool f = false;
+  void *q = f;
+#if __cplusplus >= 201103L
+  // expected-error@-2 {{cannot initialize}}
+#else
+  // expected-warning@-4 {{null}}
+#endif
+}
+
+namespace dr457 { // dr457: yes
+  const int a = 1;
+  const volatile int b = 1;
+  int ax[a];
+  int bx[b]; // expected-error +{{variable length array}}
+
+  enum E {
+    ea = a,
+    eb = b // expected-error {{not an integral constant}} expected-note {{read of volatile-qualified}}
+  };
+}
+
+namespace dr458 { // dr458: no
+  struct A {
+    int T;
+    int f();
+    template<typename> int g();
+  };
+
+  template<typename> struct B : A {
+    int f();
+    template<typename> int g();
+    template<typename> int h();
+  };
+
+  int A::f() {
+    return T;
+  }
+  template<typename T>
+  int A::g() {
+    return T; // FIXME: this is invalid, it finds the template parameter
+  }
+
+  template<typename T>
+  int B<T>::f() {
+    return T;
+  }
+  template<typename T> template<typename U>
+  int B<T>::g() {
+    return T;
+  }
+  template<typename U> template<typename T>
+  int B<U>::h() {
+    return T; // FIXME: this is invalid, it finds the template parameter
+  }
+}
+
+namespace dr460 { // dr460: yes
+  namespace X { namespace Q { int n; } }
+  namespace Y {
+    using X; // expected-error {{requires a qualified name}}
+    using dr460::X; // expected-error {{cannot refer to namespace}}
+    using X::Q; // expected-error {{cannot refer to namespace}}
+  }
+}
+
+// dr461: na
+// dr462 FIXME write a codegen test
+// dr463: na
+// dr464: na
+// dr465: na
+
+namespace dr466 { // dr466: no
+  typedef int I;
+  typedef const int CI;
+  typedef volatile int VI;
+  void f(int *a, CI *b, VI *c) {
+    a->~I();
+    a->~CI();
+    a->~VI();
+    a->I::~I();
+    a->CI::~CI();
+    a->VI::~VI();
+
+    a->CI::~VI(); // FIXME: This is invalid; CI and VI are not the same scalar type.
+
+    b->~I();
+    b->~CI();
+    b->~VI();
+    b->I::~I();
+    b->CI::~CI();
+    b->VI::~VI();
+
+    c->~I();
+    c->~CI();
+    c->~VI();
+    c->I::~I();
+    c->CI::~CI();
+    c->VI::~VI();
+  }
+}
+
+namespace dr467 { // dr467: yes
+  int stuff();
+
+  int f() {
+    static bool done;
+    if (done)
+      goto later;
+    static int k = stuff();
+    done = true;
+  later:
+    return k;
+  }
+  int g() {
+    goto later; // expected-error {{protected scope}}
+    int k = stuff(); // expected-note {{bypasses variable initialization}}
+  later:
+    return k;
+  }
+}
+
+namespace dr468 { // dr468: yes c++11
+  // FIXME: Should we allow this in C++98 too?
+  template<typename> struct A {
+    template<typename> struct B {
+      static int C;
+    };
+  };
+  int k = dr468::template A<int>::template B<char>::C;
+#if __cplusplus < 201103L
+  // expected-error@-2 2{{'template' keyword outside of a template}}
+#endif
+}
+
+namespace dr469 { // dr469: no
+  // FIXME: The core issue here didn't really answer the question. We don't
+  // deduce 'const T' from a function or reference type in a class template...
+  template<typename T> struct X; // expected-note 2{{here}}
+  template<typename T> struct X<const T> {};
+  X<int&> x; // expected-error {{undefined}}
+  X<int()> y; // expected-error {{undefined}}
+
+  // ... but we do in a function template. GCC and EDG fail deduction of 'f'
+  // and the second 'h'.
+  template<typename T> void f(const T *);
+  template<typename T> void g(T *, const T * = 0);
+  template<typename T> void h(T *) { T::error; }
+  template<typename T> void h(const T *);
+  void i() {
+    f(&i);
+    g(&i);
+    h(&i);
+  }
+}
+
+namespace dr470 { // dr470: yes
+  template<typename T> struct A {
+    struct B {};
+  };
+  template<typename T> struct C {
+  };
+
+  template struct A<int>; // expected-note {{previous}}
+  template struct A<int>::B; // expected-error {{duplicate explicit instantiation}}
+
+  // ok, instantiating C<char> doesn't instantiate base class members.
+  template struct A<char>;
+  template struct C<char>;
+}
+
+namespace dr471 { // dr471: yes
+  struct A { int n; };
+  struct B : private virtual A {};
+  struct C : protected virtual A {};
+  struct D : B, C { int f() { return n; } };
+  struct E : private virtual A {
+    using A::n;
+  };
+  struct F : E, B { int f() { return n; } };
+  struct G : virtual A {
+  private:
+    using A::n; // expected-note {{here}}
+  };
+  struct H : B, G { int f() { return n; } }; // expected-error {{private}}
+}
+
+namespace dr474 { // dr474: yes
+  namespace N {
+    struct S {
+      void f();
+    };
+  }
+  void N::S::f() {
+    void g(); // expected-note {{previous}}
+  }
+  int g();
+  namespace N {
+    int g(); // expected-error {{cannot be overloaded}}
+  }
+}
+
+// dr475 FIXME write a codegen test
+
+namespace dr477 { // dr477: 3.5
+  struct A {
+    explicit A();
+    virtual void f();
+  };
+  struct B {
+    friend explicit A::A(); // expected-error {{'explicit' is invalid in friend declarations}}
+    friend virtual void A::f(); // expected-error {{'virtual' is invalid in friend declarations}}
+  };
+  explicit A::A() {} // expected-error {{can only be specified inside the class definition}}
+  virtual void A::f() {} // expected-error {{can only be specified inside the class definition}}
+}
+
+namespace dr478 { // dr478: yes
+  struct A { virtual void f() = 0; }; // expected-note {{unimplemented}}
+  void f(A *a);
+  void f(A a[10]); // expected-error {{array of abstract class type}}
+}
+
+namespace dr479 { // dr479: yes
+  struct S {
+    S();
+  private:
+    S(const S&); // expected-note +{{here}}
+    ~S(); // expected-note +{{here}}
+  };
+  void f() {
+    throw S();
+    // expected-error@-1 {{temporary of type 'dr479::S' has private destructor}}
+    // expected-error@-2 {{calling a private constructor}}
+    // expected-error@-3 {{exception object of type 'dr479::S' has private destructor}}
+#if __cplusplus < 201103L
+    // expected-error@-5 {{C++98 requires an accessible copy constructor}}
+#endif
+  }
+  void g() {
+    S s; // expected-error {{private destructor}}}
+    throw s;
+    // expected-error@-1 {{calling a private constructor}}
+    // expected-error@-2 {{exception object of type 'dr479::S' has private destructor}}
+  }
+  void h() {
+    try {
+      f();
+      g();
+    } catch (S s) {
+      // expected-error@-1 {{calling a private constructor}}
+      // expected-error@-2 {{variable of type 'dr479::S' has private destructor}}
+    }
+  }
+}
+
+namespace dr480 { // dr480: yes
+  struct A { int n; };
+  struct B : A {};
+  struct C : virtual B {};
+  struct D : C {};
+
+  int A::*a = &A::n;
+  int D::*b = a; // expected-error {{virtual base}}
+
+  extern int D::*c;
+  int A::*d = static_cast<int A::*>(c); // expected-error {{virtual base}}
+
+  D *e;
+  A *f = e;
+  D *g = static_cast<D*>(f); // expected-error {{virtual base}}
+
+  extern D &i;
+  A &j = i;
+  D &k = static_cast<D&>(j); // expected-error {{virtual base}}
+}
+
+namespace dr481 { // dr481: yes
+  template<class T, T U> class A { T *x; };
+  T *x; // expected-error {{unknown type}}
+
+  template<class T *U> class B { T *x; };
+  T *y; // ok
+
+  struct C {
+    template<class T> void f(class D *p);
+  };
+  D *z; // ok
+
+  template<typename A = C, typename C = A> struct E {
+    void f() {
+      typedef ::dr481::C c; // expected-note {{previous}}
+      typedef C c; // expected-error {{different type}}
+    }
+  };
+  template struct E<>; // ok
+  template struct E<int>; // expected-note {{instantiation of}}
+
+  template<template<typename U_no_typo_correction> class A,
+           A<int> *B,
+           U_no_typo_correction *C> // expected-error {{unknown type}}
+  struct F {
+    U_no_typo_correction *x; // expected-error {{unknown type}}
+  };
+
+  template<template<class H *> class> struct G {
+    H *x;
+  };
+  H *q;
+
+  typedef int N;
+  template<N X, typename N, template<N Y> class T> struct I;
+  template<char*> struct J;
+  I<123, char*, J> *j;
+}
+
+namespace dr482 { // dr482: 3.5
+  extern int a;
+  void f();
+
+  int dr482::a = 0; // expected-warning {{extra qualification}}
+  void dr482::f() {} // expected-warning {{extra qualification}}
+
+  inline namespace X { // expected-error 0-1{{C++11 feature}}
+    extern int b;
+    void g();
+    struct S;
+  }
+  int dr482::b = 0; // expected-warning {{extra qualification}}
+  void dr482::g() {} // expected-warning {{extra qualification}}
+  struct dr482::S {}; // expected-warning {{extra qualification}}
+
+  void dr482::f(); // expected-warning {{extra qualification}}
+  void dr482::g(); // expected-warning {{extra qualification}}
+
+  // FIXME: The following are valid in DR482's wording, but these are bugs in
+  // the wording which we deliberately don't implement.
+  namespace N { typedef int type; }
+  typedef int N::type; // expected-error {{typedef declarator cannot be qualified}}
+  struct A {
+    struct B;
+    struct A::B {}; // expected-error {{extra qualification}}
+
+#if __cplusplus >= 201103L
+    enum class C;
+    enum class A::C {}; // expected-error {{extra qualification}}
+#endif
+  };
+}
+
+namespace dr483 { // dr483: yes
+  namespace climits {
+    int check1[__SCHAR_MAX__ >= 127 ? 1 : -1];
+    int check2[__SHRT_MAX__ >= 32767 ? 1 : -1];
+    int check3[__INT_MAX__ >= 32767 ? 1 : -1];
+    int check4[__LONG_MAX__ >= 2147483647 ? 1 : -1];
+    int check5[__LONG_LONG_MAX__ >= 9223372036854775807 ? 1 : -1];
+#if __cplusplus < 201103L
+    // expected-error@-2 {{extension}}
+#endif
+  }
+  namespace cstdint {
+    int check1[__PTRDIFF_WIDTH__ >= 16 ? 1 : -1];
+    int check2[__SIG_ATOMIC_WIDTH__ >= 8 ? 1 : -1];
+    int check3[__SIZE_WIDTH__ >= 16 ? 1 : -1];
+    int check4[__WCHAR_WIDTH__ >= 8 ? 1 : -1];
+    int check5[__WINT_WIDTH__ >= 16 ? 1 : -1];
+  }
+}
+
+namespace dr484 { // dr484: yes
+  struct A {
+    A();
+    void f();
+  };
+  typedef const A CA;
+  void CA::f() {
+    this->~CA();
+    this->CA::~A();
+    this->CA::A::~A();
+  }
+  CA::A() {}
+
+  struct B : CA {
+    B() : CA() {}
+    void f() { return CA::f(); }
+  };
+
+  struct C;
+  typedef C CT; // expected-note {{here}}
+  struct CT {}; // expected-error {{conflicts with typedef}}
+
+  namespace N {
+    struct D;
+    typedef D DT; // expected-note {{here}}
+  }
+  struct N::DT {}; // expected-error {{conflicts with typedef}}
+
+  typedef struct {
+    S(); // expected-error {{requires a type}}
+  } S;
+}
+
+namespace dr485 { // dr485: yes
+  namespace N {
+    struct S {};
+    int operator+(S, S);
+    template<typename T> int f(S);
+  }
+  template<typename T> int f();
+
+  N::S s;
+  int a = operator+(s, s);
+  int b = f<int>(s);
+}
+
+namespace dr486 { // dr486: yes
+  template<typename T> T f(T *); // expected-note 2{{substitution failure}}
+  int &f(...);
+
+  void g();
+  int n[10];
+
+  void h() {
+    int &a = f(&g);
+    int &b = f(&n);
+    f<void()>(&g); // expected-error {{no match}}
+    f<int[10]>(&n); // expected-error {{no match}}
+  }
+}
+
+namespace dr487 { // dr487: yes
+  enum E { e };
+  int operator+(int, E);
+  int i[4 + e]; // expected-error 2{{variable length array}}
+}
+
+namespace dr488 { // dr488: yes c++11
+  template <typename T> void f(T);
+  void f(int);
+  void g() {
+    // FIXME: It seems CWG thought this should be a SFINAE failure prior to
+    // allowing local types as template arguments. In C++98, we should either
+    // allow local types as template arguments or treat this as a SFINAE
+    // failure.
+    enum E { e };
+    f(e);
+#if __cplusplus < 201103L
+    // expected-error@-2 {{local type}}
+#endif
+  }
+}
+
+// dr489: na
+
+namespace dr490 { // dr490: yes
+  template<typename T> struct X {};
+
+  struct A {
+    typedef int T;
+    struct K {}; // expected-note {{declared}}
+
+    int f(T);
+    int g(T);
+    int h(X<T>);
+    int X<T>::*i(); // expected-note {{previous}}
+    int K::*j();
+
+    template<typename T> T k();
+
+    operator X<T>();
+  };
+
+  struct B {
+    typedef char T;
+    typedef int U;
+    friend int A::f(T);
+    friend int A::g(U);
+    friend int A::h(X<T>);
+
+    // FIXME: Per this DR, these two are valid! That is another defect
+    // (no number yet...) which will eventually supersede this one.
+    friend int X<T>::*A::i(); // expected-error {{return type}}
+    friend int K::*A::j(); // expected-error {{undeclared identifier 'K'; did you mean 'A::K'?}}
+
+    // ok, lookup finds B::T, not A::T, so return type matches
+    friend char A::k<T>();
+    friend int A::k<U>();
+
+    // A conversion-type-id in a conversion-function-id is always looked up in
+    // the class of the conversion function first.
+    friend A::operator X<T>();
+  };
+}
+
+namespace dr491 { // dr491: dup 413
+  struct A {} a, b[3] = { a, {} };
+  A c[2] = { a, {}, b[1] }; // expected-error {{excess elements}}
+}
+
+// dr492 FIXME write a codegen test
+
+namespace dr493 { // dr493: dup 976
+  struct X {
+    template <class T> operator const T &() const;
+  };
+  void f() {
+    if (X()) {
+    }
+  }
+}
+
+namespace dr494 { // dr494: dup 372
+  class A {
+    class B {};
+    friend class C;
+  };
+  class C : A::B {
+    A::B x;
+    class D : A::B {
+      A::B y;
+    };
+  };
+}
+
+namespace dr495 { // dr495: 3.5
+  template<typename T>
+  struct S {
+    operator int() { return T::error; }
+    template<typename U> operator U();
+  };
+  S<int> s;
+  long n = s;
+
+  template<typename T>
+  struct S2 {
+    template<typename U> operator U();
+    operator int() { return T::error; }
+  };
+  S2<int> s2;
+  long n2 = s2;
+}
+
+namespace dr496 { // dr496: no
+  struct A { int n; };
+  struct B { volatile int n; };
+  int check1[ __is_trivially_copyable(const int) ? 1 : -1];
+  int check2[!__is_trivially_copyable(volatile int) ? 1 : -1];
+  int check3[ __is_trivially_constructible(A, const A&) ? 1 : -1];
+  // FIXME: This is wrong.
+  int check4[ __is_trivially_constructible(B, const B&) ? 1 : -1];
+  int check5[ __is_trivially_assignable(A, const A&) ? 1 : -1];
+  // FIXME: This is wrong.
+  int check6[ __is_trivially_assignable(B, const B&) ? 1 : -1];
+}
+
+namespace dr497 { // dr497: yes
+  void before() {
+    struct S {
+      mutable int i;
+    };
+    const S cs; // expected-error {{default initialization}}
+    int S::*pm = &S::i;
+    cs.*pm = 88;
+  }
+
+  void after() {
+    struct S {
+      S() : i(0) {}
+      mutable int i;
+    };
+    const S cs;
+    int S::*pm = &S::i;
+    cs.*pm = 88; // expected-error {{not assignable}}
+  }
+}
+
+namespace dr499 { // dr499: yes
+  extern char str[];
+  void f() { throw str; }
+}
diff --git a/test/CXX/drs/dr5xx.cpp b/test/CXX/drs/dr5xx.cpp
new file mode 100644
index 0000000..0c0d451
--- /dev/null
+++ b/test/CXX/drs/dr5xx.cpp
@@ -0,0 +1,212 @@
+// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+
+namespace dr500 { // dr500: dup 372
+  class D;
+  class A {
+    class B;
+    class C;
+    friend class D;
+  };
+  class A::B {};
+  class A::C : public A::B {};
+  class D : public A::B {};
+}
+
+namespace dr501 { // dr501: yes
+  struct A {
+    friend void f() {}
+    void g() {
+      void (*p)() = &f; // expected-error {{undeclared identifier}}
+    }
+  };
+}
+
+namespace dr502 { // dr502: yes
+  struct Q {};
+  template<typename T> struct A {
+    enum E { e = 1 };
+    void q1() { f(e); }
+    void q2() { Q arr[sizeof(E)]; f(arr); }
+    void q3() { Q arr[e]; f(arr); }
+    void sanity() { Q arr[1]; f(arr); } // expected-error {{undeclared identifier 'f'}}
+  };
+  int f(A<int>::E);
+  template<int N> int f(Q (&)[N]);
+  template struct A<int>;
+}
+
+namespace dr505 { // dr505: yes
+  const char *exts = "\e\(\{\[\%"; // expected-error 5{{use of non-standard escape}}
+  const char *unknown = "\Q"; // expected-error {{unknown escape sequence}}
+}
+
+namespace dr506 { // dr506: yes
+  struct NonPod { ~NonPod(); };
+  void f(...);
+  void g(NonPod np) { f(np); } // expected-error {{cannot pass}}
+}
+
+// FIXME: Add tests here once DR260 is resolved.
+// dr507: dup 260
+
+// dr508: na
+// dr509: na
+// dr510: na
+
+namespace dr512 { // dr512: yes
+  struct A {
+    A(int);
+  };
+  union U { A a; };
+#if __cplusplus < 201103L
+  // expected-error@-2 {{has a non-trivial constructor}}
+  // expected-note@-6 {{no default constructor}}
+  // expected-note@-6 {{suppressed by user-declared constructor}}
+#endif
+}
+
+// dr513: na
+
+namespace dr514 { // dr514: yes
+  namespace A { extern int x, y; }
+  int A::x = y;
+}
+
+namespace dr515 { // dr515: sup 1017
+  // FIXME: dr1017 reverses the wording of dr515, but the current draft has
+  // dr515's wording, with a different fix for dr1017.
+
+  struct X { int n; };
+  template<typename T> struct Y : T {
+    int f() { return X::n; }
+  };
+  int k = Y<X>().f();
+
+  struct A { int a; };
+  struct B { void f() { int k = sizeof(A::a); } };
+#if __cplusplus < 201103L
+  // expected-error@-2 {{invalid use of non-static data member}}
+#endif
+}
+
+// dr516: na
+
+namespace dr517 { // dr517: no
+  // This is NDR, but we should diagnose it anyway.
+  template<typename T> struct S {};
+  template<typename T> int v = 0; // expected-error 0-1{{extension}}
+
+  template struct S<int*>;
+  template int v<int*>;
+
+  S<char&> s;
+  int k = v<char&>;
+
+  // FIXME: These are both ill-formed.
+  template<typename T> struct S<T*> {};
+  template<typename T> int v<T*> = 0; // expected-error 0-1{{extension}}
+
+  // FIXME: These are both ill-formed.
+  template<typename T> struct S<T&> {};
+  template<typename T> int v<T&> = 0; // expected-error 0-1{{extension}}
+}
+
+namespace dr518 { // dr518: yes c++11
+  enum E { e, };
+#if __cplusplus < 201103L
+  // expected-error@-2 {{C++11 extension}}
+#endif
+}
+
+namespace dr519 { // dr519: yes
+// FIXME: Add a codegen test.
+#if __cplusplus >= 201103L
+#define fold(x) (__builtin_constant_p(x) ? (x) : (x))
+  int test[fold((int*)(void*)0) ? -1 : 1];
+#undef fold
+#endif
+}
+
+// dr520: na
+
+// dr521: no
+// FIXME: The wording here is broken. It's not reasonable to expect a
+// diagnostic here. Once the relevant DR gets a number, mark this as a dup.
+
+namespace dr522 { // dr522: yes
+  struct S {};
+  template<typename T> void b1(volatile T &);
+  template<typename T> void b2(volatile T * const *);
+  template<typename T> void b2(volatile T * const S::*);
+  template<typename T> void b2(volatile T * const S::* const *);
+  // FIXME: This diagnostic isn't very good. The problem is not substitution failure.
+  template<typename T> void b2a(volatile T *S::* const *); // expected-note {{substitution failure}}
+
+  template<typename T> struct Base {};
+  struct Derived : Base<int> {};
+  template<typename T> void b3(Base<T>);
+  template<typename T> void b3(Base<T> *);
+
+  void test(int n, const int cn, int **p, int *S::*pm) {
+    int *a[3], *S::*am[3]; 
+    const Derived cd = Derived();
+    Derived d[3];
+
+    b1(n);
+    b1(cn);
+    b2(p);
+    b2(pm);
+    b2(a);
+    b2(am);
+    b2a(am); // expected-error {{no matching function}}
+    b3(d);
+    b3(cd);
+  }
+}
+
+namespace dr524 { // dr524: yes
+  template<typename T> void f(T a, T b) { operator+(a, b); } // expected-error {{call}}
+
+  struct S {};
+  void operator+(S, S);
+  template void f(S, S);
+
+  namespace N { struct S {}; }
+  void operator+(N::S, N::S); // expected-note {{should be declared}}
+  template void f(N::S, N::S); // expected-note {{instantiation}}
+}
+
+namespace dr525 { // dr525: yes
+  namespace before {
+    // Note, the example was correct prior to the change; instantiation is
+    // required for cases like this:
+    template <class T> struct D { operator T*(); };
+    void g(D<double> ppp) {
+      delete ppp;
+    }
+  }
+  namespace after {
+    template <class T> struct D { typename T::error e; }; // expected-error {{prior to '::'}}
+    void g(D<double> *ppp) {
+      delete ppp; // expected-note {{instantiation of}}
+    }
+  }
+}
+
+// PR8130
+namespace dr532 { // dr532: 3.5
+  struct A { };
+
+  template<class T> struct B {
+    template<class R> int &operator*(R&);
+  };
+
+  template<class T, class R> float &operator*(T&, R&);
+  void test() {
+    A a;
+    B<A> b;
+    int &ir = b * a;
+  }
+}
diff --git a/test/CXX/drs/dr9xx.cpp b/test/CXX/drs/dr9xx.cpp
new file mode 100644
index 0000000..40dc282
--- /dev/null
+++ b/test/CXX/drs/dr9xx.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+
+#if __cplusplus < 201103L
+// expected-no-diagnostics
+#endif
+
+namespace std {
+  __extension__ typedef __SIZE_TYPE__ size_t;
+
+  template<typename T> struct initializer_list {
+    const T *p; size_t n;
+    initializer_list(const T *p, size_t n);
+  };
+}
+
+namespace dr990 { // dr990: 3.5
+#if __cplusplus >= 201103L
+  struct A { // expected-note 2{{candidate}}
+    A(std::initializer_list<int>); // expected-note {{candidate}}
+  };
+  struct B {
+    A a;
+  };
+  B b1 { };
+  B b2 { 1 }; // expected-error {{no viable conversion from 'int' to 'dr990::A'}}
+  B b3 { { 1 } };
+
+  struct C {
+    C();
+    C(int);
+    C(std::initializer_list<int>) = delete; // expected-note {{here}}
+  };
+  C c1[3] { 1 }; // ok
+  C c2[3] { 1, {2} }; // expected-error {{call to deleted}}
+
+  struct D {
+    D();
+    D(std::initializer_list<int>);
+    D(std::initializer_list<double>);
+  };
+  D d{};
+#endif
+}
diff --git a/test/CXX/except/except.spec/canonical.cpp b/test/CXX/except/except.spec/canonical.cpp
index b6d3e9c..d6dc258 100644
--- a/test/CXX/except/except.spec/canonical.cpp
+++ b/test/CXX/except/except.spec/canonical.cpp
@@ -9,7 +9,7 @@
 template <class _Tp> _Tp&& declval() noexcept;
 
 template <class _Tp, class... _Args>
-struct __is_nothrow_constructible
+struct _is_nothrow_constructible
 {
   static const bool value = noexcept(_Tp(declval<_Args>()...));
 };
@@ -22,7 +22,7 @@
   typedef _Allocator allocator_type;
 
   basic_string()
-      noexcept(__is_nothrow_constructible<allocator_type>::value);
+      noexcept(_is_nothrow_constructible<allocator_type>::value);
 };
 
 template <class, class, class _Compare>
@@ -30,7 +30,7 @@
 {
 public:
   __map_value_compare()
-      noexcept(__is_nothrow_constructible<_Compare>::value);
+      noexcept(_is_nothrow_constructible<_Compare>::value);
 };
 
 struct less
@@ -45,10 +45,10 @@
 
 
 template<class T, class _Traits, class _Allocator>
-basic_string<T, _Traits, _Allocator>::basic_string() noexcept(__is_nothrow_constructible<allocator_type>::value) {}
+basic_string<T, _Traits, _Allocator>::basic_string() noexcept(_is_nothrow_constructible<allocator_type>::value) {}
 
 template <class T, class Value, class _Compare>
 __map_value_compare<T, Value, _Compare>::__map_value_compare()
-  noexcept(__is_nothrow_constructible<_Compare>::value) {}
+  noexcept(_is_nothrow_constructible<_Compare>::value) {}
 
 }  // std
diff --git a/test/CXX/except/except.spec/p11.cpp b/test/CXX/except/except.spec/p11.cpp
index 1f6bf21..1d0a647 100644
--- a/test/CXX/except/except.spec/p11.cpp
+++ b/test/CXX/except/except.spec/p11.cpp
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -std=c++11 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s
 // expected-no-diagnostics
 
-// This is the "let the user shoot himself in the foot" clause.
+// This is the "let the user shoot themselves in the foot" clause.
 void f() noexcept {
   throw 0; // no-error
 }
diff --git a/test/CXX/except/except.spec/p14-ir.cpp b/test/CXX/except/except.spec/p14-ir.cpp
index 9b41f3d..e3b15e5 100644
--- a/test/CXX/except/except.spec/p14-ir.cpp
+++ b/test/CXX/except/except.spec/p14-ir.cpp
@@ -26,12 +26,12 @@
 struct X5 : X0, X4 { };
 
 void test(X2 x2, X3 x3, X5 x5) {
-  // CHECK: define linkonce_odr void @_ZN2X2C1ERKS_(%struct.X2* %this, %struct.X2*) unnamed_addr
+  // CHECK: define linkonce_odr void @_ZN2X2C1ERKS_(%struct.X2* %this, %struct.X2* dereferenceable({{[0-9]+}})) unnamed_addr
   // CHECK:      call void @_ZN2X2C2ERKS_({{.*}}) [[NUW:#[0-9]+]]
   // CHECK-NEXT: ret void
   // CHECK-NEXT: }
   X2 x2a(x2);
-  // CHECK: define linkonce_odr void @_ZN2X3C1ERKS_(%struct.X3* %this, %struct.X3*) unnamed_addr
+  // CHECK: define linkonce_odr void @_ZN2X3C1ERKS_(%struct.X3* %this, %struct.X3* dereferenceable({{[0-9]+}})) unnamed_addr
   // CHECK:      call void @_ZN2X3C2ERKS_({{.*}}) [[NUW]]
   // CHECK-NEXT: ret void
   // CHECK-NEXT: }
diff --git a/test/CXX/except/except.spec/p14.cpp b/test/CXX/except/except.spec/p14.cpp
index dda69e9..945a767 100644
--- a/test/CXX/except/except.spec/p14.cpp
+++ b/test/CXX/except/except.spec/p14.cpp
@@ -44,8 +44,8 @@
   struct NoThrowMove {
     NoThrowMove(const NoThrowMove &);
     NoThrowMove(NoThrowMove &&) noexcept;
-    NoThrowMove &operator=(const NoThrowMove &);
-    NoThrowMove &operator=(NoThrowMove &&) noexcept;
+    NoThrowMove &operator=(const NoThrowMove &) const;
+    NoThrowMove &operator=(NoThrowMove &&) const noexcept;
   };
   struct NoThrowMoveOnly {
     NoThrowMoveOnly(NoThrowMoveOnly &&) noexcept;
diff --git a/test/CXX/except/except.spec/p15.cpp b/test/CXX/except/except.spec/p15.cpp
index fcf1235..acf4426 100644
--- a/test/CXX/except/except.spec/p15.cpp
+++ b/test/CXX/except/except.spec/p15.cpp
@@ -1,16 +1,20 @@
 // RUN: %clang_cc1 -std=c++11 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s
+// RUN: %clang_cc1 -DUSE -std=c++11 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s
+
+// Maybe force the implicit declaration of 'operator delete' and 'operator
+// delete[]'. This should make no difference to anything!
+#ifdef USE
+void f(int *p) {
+  delete p;
+  delete [] p;
+}
+#endif
 
 // Deallocation functions are implicitly noexcept.
 // Thus, explicit specs aren't allowed to conflict.
 
-void f() {
-  // Force implicit declaration of delete.
-  delete new int;
-  delete[] new int[1];
-}
-
-void operator delete(void*);
-void operator delete[](void*);
+void operator delete(void*); // expected-warning {{function previously declared with an explicit exception specification redeclared with an implicit exception specification}}
+void operator delete[](void*); // expected-warning {{function previously declared with an explicit exception specification redeclared with an implicit exception specification}}
 
 static_assert(noexcept(operator delete(0)), "");
 static_assert(noexcept(operator delete[](0)), "");
diff --git a/test/CXX/expr/expr.const/p2-0x.cpp b/test/CXX/expr/expr.const/p2-0x.cpp
index f0b53c7..bcf45a0 100644
--- a/test/CXX/expr/expr.const/p2-0x.cpp
+++ b/test/CXX/expr/expr.const/p2-0x.cpp
@@ -138,7 +138,7 @@
     case (int)(unsigned)(long long)4.4e9: // ok
     case (int)(float)1e300: // expected-error {{constant expression}} expected-note {{value 1.0E+300 is outside the range of representable values of type 'float'}} expected-error {{duplicate case value '2147483647'}} expected-note {{previous case defined here}}
     case (int)((float)1e37 / 1e30): // ok
-    case (int)(__fp16)65536: // expected-error {{constant expression}} expected-note {{value 65536 is outside the range of representable values of type 'half'}} expected-error {{duplicate case value '2147483647'}}
+    case (int)(__fp16)65536: // expected-error {{constant expression}} expected-note {{value 65536 is outside the range of representable values of type '__fp16'}} expected-error {{duplicate case value '2147483647'}}
       break;
     }
   }
@@ -202,7 +202,9 @@
     static_assert((A*)nb == 0, "");
     static_assert((B*)na == 0, "");
     constexpr const int &nf = nb->n; // expected-error {{constant expression}} expected-note {{cannot access field of null pointer}}
-    constexpr const int &np = (*(int(*)[4])nullptr)[2]; // expected-error {{constant expression}} expected-note {{cannot access array element of null pointer}}
+    constexpr const int *np1 = (int*)nullptr + 0; // ok
+    constexpr const int *np2 = &(*(int(*)[4])nullptr)[0]; // ok
+    constexpr const int *np3 = &(*(int(*)[4])nullptr)[2]; // expected-error {{constant expression}} expected-note {{cannot perform pointer arithmetic on null pointer}}
 
     struct C {
       constexpr int f() const { return 0; }
diff --git a/test/CXX/expr/expr.const/p3-0x.cpp b/test/CXX/expr/expr.const/p3-0x.cpp
index e3e32df..d9d8485 100644
--- a/test/CXX/expr/expr.const/p3-0x.cpp
+++ b/test/CXX/expr/expr.const/p3-0x.cpp
@@ -97,7 +97,7 @@
 template int f<&S::operator int>(); // expected-error {{does not refer to a function template}}
 template int f<(bool)&S::operator int>();
 
-int n = Val<bool, &S::operator int>::value; // expected-error {{conversion from 'int (S::*)() const' to 'bool' is not allowed in a converted constant expression}}
+int n = Val<bool, &S::operator int>::value; // expected-error-re {{conversion from 'int (S::*)(){{( __attribute__\(\(thiscall\)\))?}} const' to 'bool' is not allowed in a converted constant expression}}
 
 namespace NonConstLValue {
   struct S {
diff --git a/test/CXX/expr/expr.mptr.oper/p5.cpp b/test/CXX/expr/expr.mptr.oper/p5.cpp
index 7380b5d..c26b30d 100644
--- a/test/CXX/expr/expr.mptr.oper/p5.cpp
+++ b/test/CXX/expr/expr.mptr.oper/p5.cpp
@@ -24,19 +24,19 @@
   (p->*pmv)();
   (p->*pmcv)();
 
-  (pc->*pm)(); // expected-error{{call to pointer to member function of type 'void ()' drops 'const' qualifier}}
+  (pc->*pm)(); // expected-error-re{{call to pointer to member function of type 'void (){{( __attribute__\(\(thiscall\)\))?}}' drops 'const' qualifier}}
   (pc->*pmc)();
-  (pc->*pmv)(); // expected-error{{call to pointer to member function of type 'void () volatile' drops 'const' qualifier}}
+  (pc->*pmv)(); // expected-error-re{{call to pointer to member function of type 'void (){{( __attribute__\(\(thiscall\)\))?}} volatile' drops 'const' qualifier}}
   (pc->*pmcv)();
 
-  (pv->*pm)(); // expected-error{{call to pointer to member function of type 'void ()' drops 'volatile' qualifier}}
-  (pv->*pmc)(); // expected-error{{call to pointer to member function of type 'void () const' drops 'volatile' qualifier}}
+  (pv->*pm)(); // expected-error-re{{call to pointer to member function of type 'void (){{( __attribute__\(\(thiscall\)\))?}}' drops 'volatile' qualifier}}
+  (pv->*pmc)(); // expected-error-re{{call to pointer to member function of type 'void (){{( __attribute__\(\(thiscall\)\))?}} const' drops 'volatile' qualifier}}
   (pv->*pmv)();
   (pv->*pmcv)();
 
-  (pcv->*pm)(); // expected-error{{call to pointer to member function of type 'void ()' drops 'const volatile' qualifiers}}
-  (pcv->*pmc)(); // expected-error{{call to pointer to member function of type 'void () const' drops 'volatile' qualifier}}
-  (pcv->*pmv)(); // expected-error{{call to pointer to member function of type 'void () volatile' drops 'const' qualifier}}
+  (pcv->*pm)(); // expected-error-re{{call to pointer to member function of type 'void (){{( __attribute__\(\(thiscall\)\))?}}' drops 'const volatile' qualifiers}}
+  (pcv->*pmc)(); // expected-error-re{{call to pointer to member function of type 'void (){{( __attribute__\(\(thiscall\)\))?}} const' drops 'volatile' qualifier}}
+  (pcv->*pmv)(); // expected-error-re{{call to pointer to member function of type 'void (){{( __attribute__\(\(thiscall\)\))?}} volatile' drops 'const' qualifier}}
   (pcv->*pmcv)();
 
   (o.*pm)();
@@ -44,18 +44,18 @@
   (o.*pmv)();
   (o.*pmcv)();
 
-  (oc.*pm)(); // expected-error{{call to pointer to member function of type 'void ()' drops 'const' qualifier}}
+  (oc.*pm)(); // expected-error-re{{call to pointer to member function of type 'void (){{( __attribute__\(\(thiscall\)\))?}}' drops 'const' qualifier}}
   (oc.*pmc)();
-  (oc.*pmv)(); // expected-error{{call to pointer to member function of type 'void () volatile' drops 'const' qualifier}}
+  (oc.*pmv)(); // expected-error-re{{call to pointer to member function of type 'void (){{( __attribute__\(\(thiscall\)\))?}} volatile' drops 'const' qualifier}}
   (oc.*pmcv)();
 
-  (ov.*pm)(); // expected-error{{call to pointer to member function of type 'void ()' drops 'volatile' qualifier}}
-  (ov.*pmc)(); // expected-error{{call to pointer to member function of type 'void () const' drops 'volatile' qualifier}}
+  (ov.*pm)(); // expected-error-re{{call to pointer to member function of type 'void (){{( __attribute__\(\(thiscall\)\))?}}' drops 'volatile' qualifier}}
+  (ov.*pmc)(); // expected-error-re{{call to pointer to member function of type 'void (){{( __attribute__\(\(thiscall\)\))?}} const' drops 'volatile' qualifier}}
   (ov.*pmv)();
   (ov.*pmcv)();
 
-  (ocv.*pm)(); // expected-error{{call to pointer to member function of type 'void ()' drops 'const volatile' qualifiers}}
-  (ocv.*pmc)(); // expected-error{{call to pointer to member function of type 'void () const' drops 'volatile' qualifier}}
-  (ocv.*pmv)(); // expected-error{{call to pointer to member function of type 'void () volatile' drops 'const' qualifier}}
+  (ocv.*pm)(); // expected-error-re{{call to pointer to member function of type 'void (){{( __attribute__\(\(thiscall\)\))?}}' drops 'const volatile' qualifiers}}
+  (ocv.*pmc)(); // expected-error-re{{call to pointer to member function of type 'void (){{( __attribute__\(\(thiscall\)\))?}} const' drops 'volatile' qualifier}}
+  (ocv.*pmv)(); // expected-error-re{{call to pointer to member function of type 'void (){{( __attribute__\(\(thiscall\)\))?}} volatile' drops 'const' qualifier}}
   (ocv.*pmcv)();
 }
diff --git a/test/CXX/expr/expr.mptr.oper/p6-0x.cpp b/test/CXX/expr/expr.mptr.oper/p6-0x.cpp
index 917b2da..b1823e5 100644
--- a/test/CXX/expr/expr.mptr.oper/p6-0x.cpp
+++ b/test/CXX/expr/expr.mptr.oper/p6-0x.cpp
@@ -22,13 +22,13 @@
 
   // Lvalue ref-qualifier.
   (lvalue<X>().*l_pmf)(17);
-  (xvalue<X>().*l_pmf)(17); // expected-error{{pointer-to-member function type 'int (X::*)(int) &' can only be called on an lvalue}}
-  (prvalue<X>().*l_pmf)(17); // expected-error{{pointer-to-member function type 'int (X::*)(int) &' can only be called on an lvalue}}
+  (xvalue<X>().*l_pmf)(17); // expected-error-re{{pointer-to-member function type 'int (X::*)(int){{( __attribute__\(\(thiscall\)\))?}} &' can only be called on an lvalue}}
+  (prvalue<X>().*l_pmf)(17); // expected-error-re{{pointer-to-member function type 'int (X::*)(int){{( __attribute__\(\(thiscall\)\))?}} &' can only be called on an lvalue}}
   (xp->*l_pmf)(17);
 
   // Rvalue ref-qualifier.
-  (lvalue<X>().*r_pmf)(17); // expected-error{{pointer-to-member function type 'int (X::*)(int) &&' can only be called on an rvalue}}
+  (lvalue<X>().*r_pmf)(17); // expected-error-re{{pointer-to-member function type 'int (X::*)(int){{( __attribute__\(\(thiscall\)\))?}} &&' can only be called on an rvalue}}
   (xvalue<X>().*r_pmf)(17);
   (prvalue<X>().*r_pmf)(17);
-  (xp->*r_pmf)(17);  // expected-error{{pointer-to-member function type 'int (X::*)(int) &&' can only be called on an rvalue}}
+  (xp->*r_pmf)(17);  // expected-error-re{{pointer-to-member function type 'int (X::*)(int){{( __attribute__\(\(thiscall\)\))?}} &&' can only be called on an rvalue}}
 }
diff --git a/test/CXX/expr/expr.prim/expr.prim.general/p4-0x.cpp b/test/CXX/expr/expr.prim/expr.prim.general/p4-0x.cpp
index 4e57b74..54b2ff5 100644
--- a/test/CXX/expr/expr.prim/expr.prim.general/p4-0x.cpp
+++ b/test/CXX/expr/expr.prim/expr.prim.general/p4-0x.cpp
@@ -6,6 +6,8 @@
 
   int arr[sizeof(this)]; // expected-error {{invalid use of 'this' outside of a non-static member function}}
   int sz = sizeof(this); // ok
+
+  typedef auto f() -> decltype(this); // expected-error {{invalid use of 'this' outside of a non-static member function}}
 };
 
 namespace CaptureThis {
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm b/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm
index 0db2bf5..96e8fcd 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -fblocks %s -verify
+// RUN: %clang_cc1 -triple i686-pc-linux -std=c++11 -fblocks %s -verify
 
 void block_capture_errors() {
   __block int var; // expected-note 2{{'var' declared here}}
@@ -85,6 +85,24 @@
   void call_with_lambda() {
     int &ir = accept_lambda_conv([](int x) { return x + 1; });
   }
+
+  template<typename T> using id = T;
+
+  auto a = [](){};
+  struct C : decltype(a) {
+    using decltype(a)::operator id<void(*)()>;
+  private:
+    using decltype(a)::operator id<void(^)()>;
+  } extern c;
+
+  struct D : decltype(a) {
+    using decltype(a)::operator id<void(^)()>;
+  private:
+    using decltype(a)::operator id<void(*)()>; // expected-note {{here}}
+  } extern d;
+
+  bool r1 = c;
+  bool r2 = d; // expected-error {{private}}
 }
 
 namespace PR13117 {
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/generic-lambda-unimplemented-1y.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/generic-lambda-unimplemented-1y.cpp
deleted file mode 100644
index 7f42c39..0000000
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/generic-lambda-unimplemented-1y.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -std=c++1y %s -verify
-//expected-no-diagnostics
-namespace lambda_capturing {
-// FIXME: Once return type deduction is implemented for generic lambdas
-// this will need to be updated.
-void test() {
-  int i = 10;
-  {
-    auto L = [=](auto a) -> int { 
-      return i + a;
-    };
-    L(3);
-  }
-  {
-    auto L = [i](auto a) -> int { 
-      return i + a;
-    };
-    L(3);
-  }  
-  {
-    auto L = [i=i](auto a) -> int { 
-      return i + a;
-    };
-    L(3);
-  }  
-
-  
-}
-
-}
-
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp
index 2ddcf18..551c100 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp
@@ -100,3 +100,12 @@
     [x]() {}(); // expected-error{{by-copy capture of value of abstract type 'rdar14468891::X'}}
   }
 }
+
+namespace rdar15560464 {
+  struct X; // expected-note{{forward declaration of 'rdar15560464::X'}}
+  void foo(const X& param) {
+    auto x = ([=]() {
+        auto& y = param; // expected-error{{by-copy capture of variable 'param' with incomplete type 'const rdar15560464::X'}}
+      });
+  }
+}
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 8a6e792..35b7789 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p19.cpp
@@ -10,7 +10,7 @@
   auto lambda1 = [i]() { }; // expected-note 2 {{lambda expression begins here}}
 
   // Default constructor
-  decltype(lambda1) lambda2; // expected-error{{call to implicitly-deleted default constructor of 'decltype(lambda1)' (aka '<lambda}}
+  decltype(lambda1) lambda2; // expected-error{{call to implicitly-deleted default constructor of 'decltype(lambda1)' (aka '(lambda}}
 
   // Copy assignment operator
   lambda1 = lambda1; // expected-error{{copy assignment operator is implicitly deleted}}
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p2-generic-lambda-1y.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p2-generic-lambda-1y.cpp
index d41c450..03147a6 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/p2-generic-lambda-1y.cpp
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p2-generic-lambda-1y.cpp
@@ -1,25 +1,25 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++1y -DCXX1Y

-

-// prvalue

-void prvalue() {

-  auto&& x = [](auto a)->void { };

-  auto& y = [](auto *a)->void { }; // expected-error{{cannot bind to a temporary of type}}

-}

-

-namespace std {

-  class type_info;

-}

-

-struct P {

-  virtual ~P();

-};

-

-void unevaluated_operand(P &p, int i) { //expected-note{{declared here}}

-  // FIXME: this should only emit one error.

-  int i2 = sizeof([](auto a, auto b)->void{}(3, '4')); // expected-error{{lambda expression in an unevaluated operand}} \

-                                                       // expected-error{{invalid application of 'sizeof'}}

-  const std::type_info &ti1 = typeid([](auto &a) -> P& { static P p; return p; }(i));

-  const std::type_info &ti2 = typeid([](auto) -> int { return i; }(i));  // expected-error{{lambda expression in an unevaluated operand}}\

-                                                                         // expected-error{{cannot be implicitly captured}}\

-                                                                         // expected-note{{begins here}}

-}

+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++1y -DCXX1Y
+
+// prvalue
+void prvalue() {
+  auto&& x = [](auto a)->void { };
+  auto& y = [](auto *a)->void { }; // expected-error{{cannot bind to a temporary of type}}
+}
+
+namespace std {
+  class type_info;
+}
+
+struct P {
+  virtual ~P();
+};
+
+void unevaluated_operand(P &p, int i) { //expected-note{{declared here}}
+  // FIXME: this should only emit one error.
+  int i2 = sizeof([](auto a, auto b)->void{}(3, '4')); // expected-error{{lambda expression in an unevaluated operand}} \
+                                                       // expected-error{{invalid application of 'sizeof'}}
+  const std::type_info &ti1 = typeid([](auto &a) -> P& { static P p; return p; }(i));
+  const std::type_info &ti2 = typeid([](auto) -> int { return i; }(i));  // expected-error{{lambda expression in an unevaluated operand}}\
+                                                                         // expected-error{{cannot be implicitly captured}}\
+                                                                         // expected-note{{begins here}}
+}
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p5-generic-lambda-1y.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p5-generic-lambda-1y.cpp
index c5d3bf6..415c3d8 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/p5-generic-lambda-1y.cpp
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p5-generic-lambda-1y.cpp
@@ -1,131 +1,131 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++1y -DCXX1Y 

-

-namespace test_factorial {

-

-auto Fact = [](auto Self, unsigned n) -> unsigned {

-    return !n ? 1 : Self(Self, n - 1) * n;

-};

-

-auto six = Fact(Fact, 3);

-

-}

-

-namespace overload_generic_lambda {

-  template <class F1, class F2> struct overload : F1, F2 {

-    using F1::operator();

-    using F2::operator();

-    overload(F1 f1, F2 f2) : F1(f1), F2(f2) { }

-  };

-

-  auto NumParams = [](auto Self, auto h, auto ... rest) -> unsigned {

-    return 1 + Self(Self, rest...);

-  };

-  auto Base = [](auto Self, auto h) -> unsigned {

-      return 1;

-  };

-  overload<decltype(Base), decltype(NumParams)> O(Base, NumParams);

-  int num_params =  O(O, 5, 3, "abc", 3.14, 'a');

-}

-

-

-namespace overload_generic_lambda_return_type_deduction {

-  template <class F1, class F2> struct overload : F1, F2 {

-    using F1::operator();

-    using F2::operator();

-    overload(F1 f1, F2 f2) : F1(f1), F2(f2) { }

-  };

-

-  auto NumParams = [](auto Self, auto h, auto ... rest) {

-    return 1 + Self(Self, rest...);

-  };

-  auto Base = [](auto Self, auto h) {

-      return 1;

-  };

-  overload<decltype(Base), decltype(NumParams)> O(Base, NumParams);

-  int num_params =  O(O, 5, 3, "abc", 3.14, 'a');

-}

-

-namespace test_standard_p5 {

-// FIXME: This test should eventually compile without an explicit trailing return type

-auto glambda = [](auto a, auto&& b) ->bool { return a < b; };

-bool b = glambda(3, 3.14); // OK

-

-}

-namespace test_deduction_failure {

- int test() {

-   auto g = [](auto *a) { //expected-note{{candidate template ignored}}

-    return a;

-   };

-   struct X { };

-   X *x;

-   g(x);

-   g(3); //expected-error{{no matching function}}

-   return 0;

- }

-

-}

-  

-namespace test_instantiation_or_sfinae_failure {

-int test2() {

-  {

-    auto L = [](auto *a) { 

-                return (*a)(a); }; //expected-error{{called object type 'double' is not a function}}

-    double d;

-    L(&d); //expected-note{{in instantiation of}}

-    auto M = [](auto b) { return b; };

-    L(&M); // ok

-  }

-  {

-    auto L = [](auto *a) ->decltype (a->foo()) { //expected-note2{{candidate template ignored:}}

-                return (*a)(a); }; 

-    double d;

-    L(&d); //expected-error{{no matching function for call}} 

-    auto M = [](auto b) { return b; };

-    L(&M); //expected-error{{no matching function for call}} 

- 

-  }

-  return 0;

-}

-

-

-}

-  

-namespace test_misc {

-auto GL = [](auto a, decltype(a) b) //expected-note{{candidate function}} 

-                -> int { return a + b; };

-

-void test() {

-   struct X { };

-   GL(3, X{}); //expected-error{{no matching function}}

-}

-

-void test2() {

-  auto l = [](auto *a) -> int { 

-              (*a)(a); return 0; }; //expected-error{{called object type 'double' is not a function}}

-  l(&l);

-  double d;

-  l(&d); //expected-note{{in instantiation of}}

-}

-

-}

-

-namespace nested_lambdas {

-  int test() {

-    auto L = [](auto a) {

-                 return [=](auto b) {  

-                           return a + b;

-                        };

-              };

-  }

-  auto get_lambda() {

-    return [](auto a) {

-      return a; 

-    };

-  };

-  

-  int test2() {

-    auto L = get_lambda();

-    L(3);

-  }

-}

-

+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++1y -DCXX1Y 
+
+namespace test_factorial {
+
+auto Fact = [](auto Self, unsigned n) -> unsigned {
+    return !n ? 1 : Self(Self, n - 1) * n;
+};
+
+auto six = Fact(Fact, 3);
+
+}
+
+namespace overload_generic_lambda {
+  template <class F1, class F2> struct overload : F1, F2 {
+    using F1::operator();
+    using F2::operator();
+    overload(F1 f1, F2 f2) : F1(f1), F2(f2) { }
+  };
+
+  auto NumParams = [](auto Self, auto h, auto ... rest) -> unsigned {
+    return 1 + Self(Self, rest...);
+  };
+  auto Base = [](auto Self, auto h) -> unsigned {
+      return 1;
+  };
+  overload<decltype(Base), decltype(NumParams)> O(Base, NumParams);
+  int num_params =  O(O, 5, 3, "abc", 3.14, 'a');
+}
+
+
+namespace overload_generic_lambda_return_type_deduction {
+  template <class F1, class F2> struct overload : F1, F2 {
+    using F1::operator();
+    using F2::operator();
+    overload(F1 f1, F2 f2) : F1(f1), F2(f2) { }
+  };
+
+  auto NumParams = [](auto Self, auto h, auto ... rest) {
+    return 1 + Self(Self, rest...);
+  };
+  auto Base = [](auto Self, auto h) {
+      return 1;
+  };
+  overload<decltype(Base), decltype(NumParams)> O(Base, NumParams);
+  int num_params =  O(O, 5, 3, "abc", 3.14, 'a');
+}
+
+namespace test_standard_p5 {
+// FIXME: This test should eventually compile without an explicit trailing return type
+auto glambda = [](auto a, auto&& b) ->bool { return a < b; };
+bool b = glambda(3, 3.14); // OK
+
+}
+namespace test_deduction_failure {
+ int test() {
+   auto g = [](auto *a) { //expected-note{{candidate template ignored}}
+    return a;
+   };
+   struct X { };
+   X *x;
+   g(x);
+   g(3); //expected-error{{no matching function}}
+   return 0;
+ }
+
+}
+  
+namespace test_instantiation_or_sfinae_failure {
+int test2() {
+  {
+    auto L = [](auto *a) { 
+                return (*a)(a); }; //expected-error{{called object type 'double' is not a function}}
+    double d;
+    L(&d); //expected-note{{in instantiation of}}
+    auto M = [](auto b) { return b; };
+    L(&M); // ok
+  }
+  {
+    auto L = [](auto *a) ->decltype (a->foo()) { //expected-note2{{candidate template ignored:}}
+                return (*a)(a); }; 
+    double d;
+    L(&d); //expected-error{{no matching function for call}} 
+    auto M = [](auto b) { return b; };
+    L(&M); //expected-error{{no matching function for call}} 
+ 
+  }
+  return 0;
+}
+
+
+}
+  
+namespace test_misc {
+auto GL = [](auto a, decltype(a) b) //expected-note{{candidate function}} 
+                -> int { return a + b; };
+
+void test() {
+   struct X { };
+   GL(3, X{}); //expected-error{{no matching function}}
+}
+
+void test2() {
+  auto l = [](auto *a) -> int { 
+              (*a)(a); return 0; }; //expected-error{{called object type 'double' is not a function}}
+  l(&l);
+  double d;
+  l(&d); //expected-note{{in instantiation of}}
+}
+
+}
+
+namespace nested_lambdas {
+  int test() {
+    auto L = [](auto a) {
+                 return [=](auto b) {  
+                           return a + b;
+                        };
+              };
+  }
+  auto get_lambda() {
+    return [](auto a) {
+      return a; 
+    };
+  };
+  
+  int test2() {
+    auto L = get_lambda();
+    L(3);
+  }
+}
+
diff --git a/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp b/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp
index 2e99b52..7305bd1 100644
--- a/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp
+++ b/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp
@@ -13,6 +13,8 @@
   new auto; // expected-error{{new expression for type 'auto' requires a constructor argument}}
   new (const auto)(); // expected-error{{new expression for type 'const auto' requires a constructor argument}}
   new (auto) (1,2,3); // expected-error{{new expression for type 'auto' contains multiple constructor arguments}}
+  new auto {1,2,3}; // expected-error{{new expression for type 'auto' cannot use list-initialization}}
+  new auto ({1,2,3}); // expected-error{{new expression for type 'auto' cannot use list-initialization}}
 }
 
 void p2example() {
diff --git a/test/CXX/expr/expr.unary/expr.unary.op/p4.cpp b/test/CXX/expr/expr.unary/expr.unary.op/p4.cpp
index cd55cc2..9babf87 100644
--- a/test/CXX/expr/expr.unary/expr.unary.op/p4.cpp
+++ b/test/CXX/expr/expr.unary/expr.unary.op/p4.cpp
@@ -7,7 +7,7 @@
     template<typename T> void g(T);
 
     void test() {
-      foo(&g<int>); // expected-error {{can't form member pointer of type 'void (test0::A::*)(int)' without '&' and class name}}
+      foo(&g<int>); // expected-error-re {{can't form member pointer of type 'void (test0::A::*)(int){{( __attribute__\(\(thiscall\)\))?}}' without '&' and class name}}
     }
   };
 }
diff --git a/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp b/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp
index 2646264..833a401 100644
--- a/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp
+++ b/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp
@@ -15,7 +15,7 @@
 bool b5 = !F;
 
 // --  pointer, 
-bool b6 = !&b4;
+bool b6 = !&b4; // expected-warning{{address of 'b4' will always evaluate to 'true'}}
 void f();
 bool b61 = !&f;
 
diff --git a/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3.cpp b/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3.cpp
index 35f8808..d88d5be 100644
--- a/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3.cpp
+++ b/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3.cpp
@@ -1,5 +1,27 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
-// expected-no-diagnostics
+
+namespace bullet2 {
+
+// For non-member candidates, if no operand has a class type, only those
+// non-member functions that have a matching enumeration parameter are
+// candidates.
+
+struct B { template<typename T> B(T); };
+int operator~(B);
+template<typename T> int operator%(B, T);
+enum class E { e };
+
+template<typename T> int f(T t) { return ~t; } // expected-error {{invalid argument type}}
+template<typename T, typename U> int f(T t, U u) { return t % u; } // expected-error {{invalid operands to}}
+
+int b1 = ~E::e; // expected-error {{invalid argument type}}
+int b2 = f(E::e); // expected-note {{in instantiation of}}
+int b3 = f(0, E::e);
+int b4 = f(E::e, 0); // expected-note {{in instantiation of}}
+
+}
+
+namespace bullet3 {
 
 // This is specifically testing the bullet:
 // "do not have the same parameter-type-list as any non-template
@@ -26,4 +48,6 @@
 extern decltype(a <= a) test2;
 
 extern A test3;
-extern decltype(a <= b) test3;
\ No newline at end of file
+extern decltype(a <= b) test3;
+
+}
diff --git a/test/CXX/special/class.copy/implicit-move-def.cpp b/test/CXX/special/class.copy/implicit-move-def.cpp
index 5696d1f..880268d 100644
--- a/test/CXX/special/class.copy/implicit-move-def.cpp
+++ b/test/CXX/special/class.copy/implicit-move-def.cpp
@@ -1,6 +1,6 @@
-// FIXME: %clang_cc1 -emit-llvm -o - -std=c++11 %s | FileCheck -check-prefix=CHECK %s
-// RUN: %clang_cc1 -emit-llvm -o - -std=c++11 %s | FileCheck -check-prefix=CHECK-ASSIGN %s
-// RUN: %clang_cc1 -emit-llvm -o - -std=c++11 %s | FileCheck -check-prefix=CHECK-CTOR %s
+// FIXME: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -o - -std=c++11 %s | FileCheck -check-prefix=CHECK %s
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -o - -std=c++11 %s | FileCheck -check-prefix=CHECK-ASSIGN %s
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -o - -std=c++11 %s | FileCheck -check-prefix=CHECK-CTOR %s
 
 // construct
 
diff --git a/test/CXX/special/class.copy/implicit-move.cpp b/test/CXX/special/class.copy/implicit-move.cpp
index 23ecf2e..a10d139 100644
--- a/test/CXX/special/class.copy/implicit-move.cpp
+++ b/test/CXX/special/class.copy/implicit-move.cpp
@@ -258,8 +258,8 @@
 
     template<typename T>
     struct F :
-      E<T, 0>, // expected-note-re 2{{'[BD]' is a virtual base class of base class 'E<}}
-      E<T, 1> {}; // expected-note-re 2{{'[BD]' is a virtual base class of base class 'E<}}
+      E<T, 0>, // expected-note-re 2{{'{{[BD]}}' is a virtual base class of base class 'E<}}
+      E<T, 1> {}; // expected-note-re 2{{'{{[BD]}}' is a virtual base class of base class 'E<}}
 
     template<typename T>
     struct G : E<T, 0, true>, E<T, 0> {};
@@ -272,11 +272,11 @@
 
     template<typename T>
     struct J :
-      E<T, 0>, // expected-note-re 2{{'[BD]' is a virtual base class of base class 'E<}}
-      virtual T {}; // expected-note-re 2{{virtual base class '[BD]' declared here}}
+      E<T, 0>, // expected-note-re 2{{'{{[BD]}}' is a virtual base class of base class 'E<}}
+      virtual T {}; // expected-note-re 2{{virtual base class '{{[BD]}}' declared here}}
 
     template<typename T> void move(T t) { t = static_cast<T&&>(t); }
-    // expected-warning-re@-1 4{{defaulted move assignment operator of .* will move assign virtual base class '[BD]' multiple times}}
+    // expected-warning-re@-1 4{{defaulted move assignment operator of {{.*}} will move assign virtual base class '{{[BD]}}' multiple times}}
     template void move(F<A>);
     template void move(F<B>); // expected-note {{in instantiation of}}
     template void move(F<C>);
diff --git a/test/CXX/special/class.copy/p11.0x.copy.cpp b/test/CXX/special/class.copy/p11.0x.copy.cpp
index 011c1e9..1ca0143 100644
--- a/test/CXX/special/class.copy/p11.0x.copy.cpp
+++ b/test/CXX/special/class.copy/p11.0x.copy.cpp
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
 
+struct Trivial {};
 struct NonTrivial {
   NonTrivial(const NonTrivial&);
 };
@@ -69,6 +70,12 @@
 Deleted Da;
 Deleted Db(Da); // expected-error{{call to implicitly-deleted copy constructor}}
 
+// It's implied (but not stated) that this also applies in the case where
+// overload resolution would fail.
+struct VolatileMember {
+  volatile Trivial vm; // expected-note {{has no copy}}
+} vm1, vm2(vm1); // expected-error {{deleted}}
+
 // -- a direct or virtual base class B that cannot be copied because overload
 //    resolution results in an ambiguity or a function that is deleted or
 //    inaccessible
@@ -132,3 +139,22 @@
   T &f();
   T t = f(); // expected-error{{call to implicitly-deleted copy constructor}}
 }
+
+namespace Mutable {
+  struct A {
+    A(const A &);
+    A(A &) = delete; // expected-note {{deleted here}}
+  };
+
+  struct B {
+    A a;
+    B(const B &);
+  };
+  B::B(const B &) = default;
+
+  struct C {
+    mutable A a; // expected-note {{deleted because field 'a' has a deleted copy constructor}}
+    C(const C &);
+  };
+  C::C(const C &) = default; // expected-error{{would delete}}
+}
diff --git a/test/CXX/special/class.copy/p11.0x.move.cpp b/test/CXX/special/class.copy/p11.0x.move.cpp
index ebcce49..514817d 100644
--- a/test/CXX/special/class.copy/p11.0x.move.cpp
+++ b/test/CXX/special/class.copy/p11.0x.move.cpp
@@ -1,21 +1,22 @@
 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
 
+struct Trivial {};
 struct NonTrivial {
-  NonTrivial(NonTrivial&&);
+  NonTrivial(NonTrivial&&); // expected-note{{copy constructor is implicitly deleted}}
 };
 
 // A defaulted move constructor for a class X is defined as deleted if X has:
 
 // -- a variant member with a non-trivial corresponding constructor
 union DeletedNTVariant {
-  NonTrivial NT;
+  NonTrivial NT; // expected-note{{deleted because variant field 'NT' has a non-trivial move constructor}}
   DeletedNTVariant(DeletedNTVariant&&);
 };
 DeletedNTVariant::DeletedNTVariant(DeletedNTVariant&&) = default; // expected-error{{would delete}}
 
 struct DeletedNTVariant2 {
   union {
-    NonTrivial NT;
+    NonTrivial NT; // expected-note{{deleted because variant field 'NT' has a non-trivial move constructor}}
   };
   DeletedNTVariant2(DeletedNTVariant2&&);
 };
@@ -33,7 +34,7 @@
 };
 
 struct HasNoAccess {
-  NoAccess NA;
+  NoAccess NA; // expected-note{{deleted because field 'NA' has an inaccessible move constructor}}
   HasNoAccess(HasNoAccess&&);
 };
 HasNoAccess::HasNoAccess(HasNoAccess&&) = default; // expected-error{{would delete}}
@@ -50,31 +51,55 @@
 };
 
 struct IsAmbiguous {
-  Ambiguity A;
-  IsAmbiguous(IsAmbiguous&&);
+  Ambiguity A; // expected-note{{deleted because field 'A' has multiple move constructors}}
+  IsAmbiguous(IsAmbiguous&&); // expected-note{{copy constructor is implicitly deleted because 'IsAmbiguous' has a user-declared move constructor}}
 };
 IsAmbiguous::IsAmbiguous(IsAmbiguous&&) = default; // expected-error{{would delete}}
 
 struct Deleted {
-  IsAmbiguous IA;
+  // FIXME: This diagnostic is slightly wrong: the constructor we select to move
+  // 'IA' is deleted, but we select the copy constructor (we ignore the move
+  // constructor, because it was defaulted and deleted).
+  IsAmbiguous IA; // expected-note{{deleted because field 'IA' has a deleted move constructor}}
   Deleted(Deleted&&);
 };
 Deleted::Deleted(Deleted&&) = default; // expected-error{{would delete}}
 
+// It's implied (but not stated) that this should also happen if overload
+// resolution fails.
+struct ConstMember {
+  const Trivial ct;
+  ConstMember(ConstMember&&);
+};
+ConstMember::ConstMember(ConstMember&&) = default; // ok, calls copy ctor
+struct ConstMoveOnlyMember {
+  // FIXME: This diagnostic is slightly wrong: the constructor we select to move
+  // 'cnt' is deleted, but we select the copy constructor, because the object is
+  // const.
+  const NonTrivial cnt; // expected-note{{deleted because field 'cnt' has a deleted move constructor}}
+  ConstMoveOnlyMember(ConstMoveOnlyMember&&);
+};
+ConstMoveOnlyMember::ConstMoveOnlyMember(ConstMoveOnlyMember&&) = default; // expected-error{{would delete}}
+struct VolatileMember {
+  volatile Trivial vt; // expected-note{{deleted because field 'vt' has no move constructor}}
+  VolatileMember(VolatileMember&&);
+};
+VolatileMember::VolatileMember(VolatileMember&&) = default; // expected-error{{would delete}}
+
 // -- a direct or virtual base class B that cannot be moved because overload
 //    resolution results in an ambiguity or a function that is deleted or
 //    inaccessible
-struct AmbiguousMoveBase : Ambiguity {
-  AmbiguousMoveBase(AmbiguousMoveBase&&);
+struct AmbiguousMoveBase : Ambiguity { // expected-note{{deleted because base class 'Ambiguity' has multiple move constructors}}
+  AmbiguousMoveBase(AmbiguousMoveBase&&); // expected-note{{copy constructor is implicitly deleted}}
 };
 AmbiguousMoveBase::AmbiguousMoveBase(AmbiguousMoveBase&&) = default; // expected-error{{would delete}}
 
-struct DeletedMoveBase : AmbiguousMoveBase {
+struct DeletedMoveBase : AmbiguousMoveBase { // expected-note{{deleted because base class 'AmbiguousMoveBase' has a deleted move constructor}}
   DeletedMoveBase(DeletedMoveBase&&);
 };
 DeletedMoveBase::DeletedMoveBase(DeletedMoveBase&&) = default; // expected-error{{would delete}}
 
-struct InaccessibleMoveBase : NoAccess {
+struct InaccessibleMoveBase : NoAccess { // expected-note{{deleted because base class 'NoAccess' has an inaccessible move constructor}}
   InaccessibleMoveBase(InaccessibleMoveBase&&);
 };
 InaccessibleMoveBase::InaccessibleMoveBase(InaccessibleMoveBase&&) = default; // expected-error{{would delete}}
@@ -89,7 +114,7 @@
 };
 
 struct HasNoAccessDtor {
-  NoAccessDtor NAD;
+  NoAccessDtor NAD; // expected-note {{deleted because field 'NAD' has an inaccessible destructor}}
   HasNoAccessDtor(HasNoAccessDtor&&);
 };
 HasNoAccessDtor::HasNoAccessDtor(HasNoAccessDtor&&) = default; // expected-error{{would delete}}
diff --git a/test/CXX/special/class.copy/p13-0x.cpp b/test/CXX/special/class.copy/p13-0x.cpp
index 5d43601..16c8a40 100644
--- a/test/CXX/special/class.copy/p13-0x.cpp
+++ b/test/CXX/special/class.copy/p13-0x.cpp
@@ -114,3 +114,18 @@
     friend constexpr S<W>::S(const S<W>&) noexcept;
   };
 }
+
+namespace Mutable {
+  struct A {
+    constexpr A(A &);
+    A(const A &);
+  };
+  struct B {
+    constexpr B(const B &) = default; // ok
+    mutable A a;
+  };
+  struct C {
+    constexpr C(const C &) = default; // expected-error {{not constexpr}}
+    A a;
+  };
+}
diff --git a/test/CXX/special/class.copy/p23-cxx11.cpp b/test/CXX/special/class.copy/p23-cxx11.cpp
index c55d6c2..ac21cc6 100644
--- a/test/CXX/special/class.copy/p23-cxx11.cpp
+++ b/test/CXX/special/class.copy/p23-cxx11.cpp
@@ -1,5 +1,7 @@
 // RUN: %clang_cc1 -verify %s -std=c++11
 
+struct Trivial {};
+
 template<typename T> struct CopyAssign {
   static T t;
   void test() {
@@ -28,8 +30,8 @@
   NonTrivialMoveAssign &operator=(NonTrivialMoveAssign &&);
 };
 struct AmbiguousCopyAssign {
-  AmbiguousCopyAssign &operator=(const AmbiguousCopyAssign &);
-  AmbiguousCopyAssign &operator=(volatile AmbiguousCopyAssign &);
+  AmbiguousCopyAssign &operator=(const AmbiguousCopyAssign &) volatile;
+  AmbiguousCopyAssign &operator=(const AmbiguousCopyAssign &) const;
 };
 struct AmbiguousMoveAssign {
   AmbiguousMoveAssign &operator=(const AmbiguousMoveAssign &&);
@@ -47,6 +49,9 @@
 class InaccessibleMoveAssign {
   InaccessibleMoveAssign &operator=(InaccessibleMoveAssign &&);
 };
+class NonConstCopyAssign {
+  NonConstCopyAssign &operator=(NonConstCopyAssign &);
+};
 
 // A defaulted copy/move assignment operator for class X is defined as deleted
 // if X has:
@@ -114,6 +119,12 @@
   D6 &operator=(D6 &&) = default; // expected-note {{here}} expected-note {{copy assignment operator is implicitly deleted}}
   InaccessibleMoveAssign a; // expected-note {{field 'a' has an inaccessible move}}
 };
+struct D7 {
+  const Trivial a; // expected-note 3{{field 'a' has no }}
+};
+struct D8 {
+  volatile Trivial a; // expected-note 3{{field 'a' has no }}
+};
 template struct CopyAssign<D1>; // expected-note {{here}}
 template struct MoveAssign<D2>; // expected-note {{here}}
 template struct MoveOrCopyAssign<D2>; // expected-note {{here}}
@@ -123,6 +134,12 @@
 template struct CopyAssign<D5>; // expected-note {{here}}
 template struct MoveAssign<D6>; // expected-note {{here}}
 template struct MoveOrCopyAssign<D6>; // expected-note {{here}}
+template struct CopyAssign<D7>; // expected-note {{here}}
+template struct MoveAssign<D7>; // expected-note {{here}}
+template struct MoveOrCopyAssign<D7>; // expected-note {{here}}
+template struct CopyAssign<D8>; // expected-note {{here}}
+template struct MoveAssign<D8>; // expected-note {{here}}
+template struct MoveOrCopyAssign<D8>; // expected-note {{here}}
 
 //   -- a direct or virtual base that cannot be copied/moved
 struct E1 : AmbiguousCopyAssign {}; // expected-note {{base class 'AmbiguousCopyAssign' has multiple copy}}
@@ -147,7 +164,7 @@
 namespace PR13381 {
   struct S {
     S &operator=(const S&);
-    S &operator=(const volatile S&) = delete; // expected-note{{deleted here}}
+    S &operator=(const volatile S&) volatile = delete; // expected-note{{deleted here}}
   };
   struct T {
     volatile S s; // expected-note{{field 's' has a deleted copy assignment}}
@@ -157,3 +174,18 @@
     t = T(); // expected-error{{object of type 'PR13381::T' cannot be assigned because its copy assignment operator is implicitly deleted}}
   }
 }
+
+namespace Mutable {
+  struct AmbiguousCopyAssign {
+    AmbiguousCopyAssign &operator=(const AmbiguousCopyAssign &);
+    AmbiguousCopyAssign &operator=(volatile AmbiguousCopyAssign &);
+  };
+  struct X {
+    AmbiguousCopyAssign a;
+  };
+  struct Y {
+    mutable AmbiguousCopyAssign a; // expected-note {{multiple copy assignment operators}}
+  };
+}
+template struct CopyAssign<Mutable::X>;
+template struct CopyAssign<Mutable::Y>; // expected-note {{here}}
diff --git a/test/CXX/special/class.copy/p33-0x.cpp b/test/CXX/special/class.copy/p33-0x.cpp
index b66e19a..28cd4f3 100644
--- a/test/CXX/special/class.copy/p33-0x.cpp
+++ b/test/CXX/special/class.copy/p33-0x.cpp
@@ -27,7 +27,7 @@
   struct X {
     X();
     X(X&&);
-    X(const X&) = delete; // expected-note 2{{function has been explicitly marked deleted here}}
+    X(const X&) = delete; // expected-note 2{{'X' has been explicitly marked deleted here}}
   };
 
   void f(int i) {
diff --git a/test/CXX/special/class.dtor/p10-0x.cpp b/test/CXX/special/class.dtor/p10-0x.cpp
index e10afb5..029cbd6 100644
--- a/test/CXX/special/class.dtor/p10-0x.cpp
+++ b/test/CXX/special/class.dtor/p10-0x.cpp
@@ -7,7 +7,7 @@
 void b(const T *x, const A *y) {
   x->~decltype(T())();
   x->~decltype(*x)(); // expected-error{{the type of object expression ('const int') does not match the type being destroyed ('decltype(*x)' (aka 'const int &')) in pseudo-destructor expression}} \
-                         expected-error{{no member named '~const struct A &' in 'A'}}
+                         expected-error{{no member named '~const A &' in 'A'}}
   x->~decltype(int())(); // expected-error{{no member named '~int' in 'A'}}
 
   y->~decltype(*y)(); // expected-error{{destructor type 'decltype(*y)' (aka 'const A &') in object destruction expression does not match the type 'const A' of the object being destroyed}}
diff --git a/test/CXX/special/class.dtor/p3-0x.cpp b/test/CXX/special/class.dtor/p3-0x.cpp
index dc76e00..2d7eba4 100644
--- a/test/CXX/special/class.dtor/p3-0x.cpp
+++ b/test/CXX/special/class.dtor/p3-0x.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s
 
 struct A {
   ~A();
diff --git a/test/CXX/special/class.dtor/p9.cpp b/test/CXX/special/class.dtor/p9.cpp
index 8b76a15..a03fcdb 100644
--- a/test/CXX/special/class.dtor/p9.cpp
+++ b/test/CXX/special/class.dtor/p9.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple %itanium_abi_triple -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple %ms_abi_triple -DMSABI -verify %s
 
 typedef typeof(sizeof(int)) size_t;
 
@@ -74,7 +75,13 @@
 // PR7346
 namespace test3 {
   struct A {
+#ifdef MSABI
+    // expected-error@+2 {{no suitable member 'operator delete' in 'A'}}
+#endif
     virtual ~A();
+#ifdef MSABI
+    // expected-note@+2 {{declared here}}
+#endif
     static void operator delete(void*, const int &);
   };
 
diff --git a/test/CXX/special/class.inhctor/elsewhere.cpp b/test/CXX/special/class.inhctor/elsewhere.cpp
index b986f65..c042834 100644
--- a/test/CXX/special/class.inhctor/elsewhere.cpp
+++ b/test/CXX/special/class.inhctor/elsewhere.cpp
@@ -9,7 +9,7 @@
   B1(int);
 };
 
-using B1::B1; // expected-error {{using declaration can not refer to class member}}
+using B1::B1; // expected-error {{using declaration cannot refer to class member}}
 
 // C++11 [namespace.udecl]p10:
 //   A using-declaration is a declaration and can therefore be used repeatedly
@@ -27,7 +27,7 @@
 //   shall name a direct base class of the class being defined.
 
 struct D1 : I1 {
-  using B1::B1; // expected-error {{'B1' is not a direct base of 'D1', can not inherit constructors}}
+  using B1::B1; // expected-error {{'B1' is not a direct base of 'D1', cannot inherit constructors}}
 };
 
 template<typename T> struct A {};
@@ -47,7 +47,7 @@
 
 template<typename T> struct D : A<T> {};
 template<typename T> struct E : D<T> {
-  using A<bool>::A; // expected-error {{'A<bool>' is not a direct base of 'E<bool>', can not inherit}}
+  using A<bool>::A; // expected-error {{'A<bool>' is not a direct base of 'E<bool>', cannot inherit}}
 };
 E<bool> eb; // expected-note {{here}}
 
diff --git a/test/CXX/special/class.inhctor/p4.cpp b/test/CXX/special/class.inhctor/p4.cpp
index 356cdef..ae1f7a5 100644
--- a/test/CXX/special/class.inhctor/p4.cpp
+++ b/test/CXX/special/class.inhctor/p4.cpp
@@ -43,8 +43,8 @@
 
 // It is deleted if the corresponding constructor [...] is deleted.
 struct G {
-  G(int) = delete; // expected-note {{function has been explicitly marked deleted here}}
-  template<typename T> G(T*) = delete; // expected-note {{function has been explicitly marked deleted here}}
+  G(int) = delete; // expected-note {{'G' has been explicitly marked deleted here}}
+  template<typename T> G(T*) = delete; // expected-note {{'G<const char>' has been explicitly marked deleted here}}
 };
 struct H : G {
   using G::G; // expected-note 2{{deleted constructor was inherited here}}
diff --git a/test/CXX/special/class.init/class.base.init/p8-0x.cpp b/test/CXX/special/class.init/class.base.init/p8-0x.cpp
index a108533..45755ca 100644
--- a/test/CXX/special/class.init/class.base.init/p8-0x.cpp
+++ b/test/CXX/special/class.init/class.base.init/p8-0x.cpp
@@ -16,16 +16,13 @@
 } s(0);
 
 union U {
-  int a = 0; // desired-note 5 {{previous initialization is here}}
-  char b = 'x';
+  int a = 0; // expected-note {{previous initialization}}
+  char b = 'x'; // expected-error {{initializing multiple members of union}}
 
-  // FIXME: these should all be rejected
-  U() {} // desired-error {{initializing multiple members of union}}
-  U(int) : a(1) {} // desired-error {{initializing multiple members of union}}
-  U(char) : b('y') {} // desired-error {{initializing multiple members of union}}
-  // this expected note should be removed & the note should appear on the 
-  // declaration of 'a' when this set of cases is handled correctly.
-  U(double) : a(1), // expected-note{{previous initialization is here}} desired-error {{initializing multiple members of union}}
+  U() {}
+  U(int) : a(1) {}
+  U(char) : b('y') {}
+  U(double) : a(1), // expected-note{{previous initialization is here}}
               b('y') {} // expected-error{{initializing multiple members of union}}
 };
 
diff --git a/test/CXX/special/class.temporary/p1.cpp b/test/CXX/special/class.temporary/p1.cpp
index 4f6ac0a..75a56df 100644
--- a/test/CXX/special/class.temporary/p1.cpp
+++ b/test/CXX/special/class.temporary/p1.cpp
@@ -6,7 +6,7 @@
     int x;
     int y;
 
-    A(const A&) = delete; // expected-note {{function has been explicitly marked deleted here}}
+    A(const A&) = delete; // expected-note {{'A' has been explicitly marked deleted here}}
   };
 
   void foo(...);
diff --git a/test/CXX/temp/p3.cpp b/test/CXX/temp/p3.cpp
index 11f72de..e9fd8a3 100644
--- a/test/CXX/temp/p3.cpp
+++ b/test/CXX/temp/p3.cpp
@@ -8,7 +8,8 @@
 
 template<typename T> struct A { static A a; } A<T>::a; // expected-error {{expected ';' after struct}} \
                                                           expected-error {{use of undeclared identifier 'T'}} \
-                                                          expected-error{{extra qualification}}
+                                                          expected-error {{no member named 'a'}} \
+                                                          expected-warning {{extra qualification}}
 
 template<typename T> struct B { } f(); // expected-error {{expected ';' after struct}} \
                                           expected-error {{requires a type specifier}}
diff --git a/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp b/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp
index 9b9b532..e87153b 100644
--- a/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp
+++ b/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp
@@ -184,7 +184,7 @@
   template<int (Y::*)(int)> struct X0 {}; // expected-note{{template parameter is declared here}}
   X0<&Y::f> x0a;
   X0<&Y::g> x0b;
-  X0<&Y::h> x0c; // expected-error{{non-type template argument of type 'float (pointer_to_member_function::Y::*)(float)' cannot be converted to a value of type 'int (pointer_to_member_function::Y::*)(int)'}}
+  X0<&Y::h> x0c; // expected-error-re{{non-type template argument of type 'float (pointer_to_member_function::Y::*)(float){{( __attribute__\(\(thiscall\)\))?}}' cannot be converted to a value of type 'int (pointer_to_member_function::Y::*)(int){{( __attribute__\(\(thiscall\)\))?}}'}}
 }
 
 //     -- For a non-type template-parameter of type pointer to data member,
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 a49db51..2651f99 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,10 +21,10 @@
 
 template<typename Outer> struct X {
   template<typename Inner> static int y;
-  template<typename Inner> static int y<Outer>; // expected-warning {{can not be deduced}} expected-note {{'Inner'}}
+  template<typename Inner> static int y<Outer>; // expected-warning {{cannot be deduced}} expected-note {{'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 {{can not be deduced}} expected-note {{'Inner'}}
+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
diff --git a/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp b/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp
deleted file mode 100644
index 60c60cb..0000000
--- a/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
-// expected-no-diagnostics
-
-// Core DR 532.
-namespace PR8130 {
-  struct A { };
-
-  template<class T> struct B {
-    template<class R> int &operator*(R&);
-  };
-
-  template<class T, class R> float &operator*(T&, R&);
-  void test() {
-    A a;
-    B<A> b;
-    int &ir = b * a;
-  }
-}
-
-namespace OperatorWithRefQualifier {
-  struct A { };
-  template<class T> struct B {
-    template<class R> int &operator*(R&) &&;
-  };
-
-  template<class T, class R> float &operator*(T&&, R&);
-  void test() {
-    A a;
-    B<A> b;
-    float &ir = b * a;
-    int &ir2 = B<A>() * a;
-  }
-}
-
-namespace OrderWithStaticMember {
-  struct A {
-    template<class T> int g(T**, int=0) { return 0; }
-    template<class T> static int g(T*) { return 1; }
-  };
-  void f() {
-    A a;
-    int **p;
-    a.g(p);
-  }
-}
-
-namespace PR17075 {
-  template <typename T> struct V {};
-  struct S { template<typename T> S &operator>>(T &t) = delete; };
-  template<typename T> S &operator>>(S &s, V<T> &v);
-  void f(S s, V<int> v) { s >> v; }
-}
diff --git a/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3.cpp b/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3.cpp
index 8212a12..db3952a 100644
--- a/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3.cpp
+++ b/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3.cpp
@@ -1,21 +1,7 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
 // expected-no-diagnostics
 
-namespace DeduceVsMember {
-  template<typename T>
-  struct X {
-    template<typename U>
-    int &operator==(const U& other) const;
-  };
-
-  template<typename T, typename U>
-  float &operator==(const T&, const X<U>&);
-
-  void test(X<int> xi, X<float> xf) {
-    float& ir = (xi == xf);
-  }
-}
-
 namespace OrderWithStaticMember {
   struct A {
     template<class T> int g(T**, int=0) { return 0; }
@@ -27,3 +13,27 @@
     a.g(p);
   }
 }
+
+#if __cplusplus >= 201103L
+namespace OperatorWithRefQualifier {
+  struct A { };
+  template<class T> struct B {
+    template<class R> int &operator*(R&) &&;
+  };
+
+  template<class T, class R> float &operator*(T&&, R&);
+  void test() {
+    A a;
+    B<A> b;
+    float &ir = b * a;
+    int &ir2 = B<A>() * a;
+  }
+}
+
+namespace PR17075 {
+  template <typename T> struct V {};
+  struct S { template<typename T> S &operator>>(T &t) = delete; };
+  template<typename T> S &operator>>(S &s, V<T> &v);
+  void f(S s, V<int> v) { s >> v; }
+}
+#endif
diff --git a/test/CXX/temp/temp.decls/temp.mem/p3.cpp b/test/CXX/temp/temp.decls/temp.mem/p3.cpp
index 0eb747b..7e13f2a 100644
--- a/test/CXX/temp/temp.decls/temp.mem/p3.cpp
+++ b/test/CXX/temp/temp.decls/temp.mem/p3.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 
 template <class T> struct AA { 
-  template <class C> virtual void g(C); // expected-error{{'virtual' can not be specified on member function templates}}
+  template <class C> virtual void g(C); // expected-error{{'virtual' cannot be specified on member function templates}}
   virtual void f();
 };
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 fb72754..a466be0 100644
--- a/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp
+++ b/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp
@@ -121,7 +121,16 @@
 
 namespace FixedAliasTemplate {
   template<typename,typename,typename> struct S {};
-  template<typename T, typename U> using U = S<T, int, U>;
-  template<typename...Ts> U<Ts...> &f(U<Ts...>, Ts...);
-  S<int, int, double> &s1 = f({}, 0, 0.0);
+  template<typename T, typename U> using U = S<T, int, U>; // expected-note 2{{template parameter is declared here}}
+  template<typename...Ts> U<Ts...> &f(U<Ts...>, Ts...); // expected-error 2{{pack expansion used as argument for non-pack parameter of alias template}}
+  S<int, int, double> &s1 = f({}, 0, 0.0); // expected-error {{no matching function}}
+}
+
+namespace PR18401 {
+  template<typename... Args> struct foo { };
+  template<typename T, typename... Args> using bar = foo<T, Args...>; // expected-note 2{{template parameter is declared here}} expected-note {{'bar' declared here}}
+  template<typename T, typename... Args> using baz = bar<Args..., T>; // expected-error {{pack expansion used as argument for non-pack parameter of alias template}}
+  // FIXME: We should still record the alias template, but mark it as invalid.
+  template<typename...T> void f(baz<T...>); // expected-error {{no template named 'baz'; did you mean 'bar'}} expected-error {{pack expansion used as argument for non-pack}}
+  void g() { f(foo<int, char, double>()); } // expected-error {{no matching function}}
 }
diff --git a/test/CXX/temp/temp.decls/temp.variadic/p5.cpp b/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
index 3681d77..dae6865 100644
--- a/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
+++ b/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
@@ -310,10 +310,10 @@
   t.~Types(); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
   t.Types::~T(); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
 
-  // UnaryTypeTraitExpr
+  // Unary TypeTraitExpr
   __is_pod(Types); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
 
-  // BinaryTypeTraitExpr
+  // Binary TypeTraitExpr
   __is_base_of(Types, T); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
   __is_base_of(T, Types); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
 
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 d7989e3..782057d 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 can not be deduced; this partial specialization will never be used}}
+  struct UselessPartialSpec<Types..., Tail>; // expected-warning{{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/p14.cpp b/test/CXX/temp/temp.param/p14.cpp
deleted file mode 100644
index a6c53c1..0000000
--- a/test/CXX/temp/temp.param/p14.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s 
-// XFAIL: *
-
-// A template-parameter shall not be used in its own default argument.
-template<typename T = typename T::type> struct X; // expected-error{{default}}
diff --git a/test/CXX/temp/temp.res/temp.local/p3.cpp b/test/CXX/temp/temp.res/temp.local/p3.cpp
index 54da885..e29ced1 100644
--- a/test/CXX/temp/temp.res/temp.local/p3.cpp
+++ b/test/CXX/temp/temp.res/temp.local/p3.cpp
@@ -15,7 +15,7 @@
     t->Base<T>::f();
     t->Base::f(); // expected-error{{member 'Base' found in multiple base classes of different types}} \
     // expected-error{{no member named 'f' in 'X0'}} \
-    // expected-error{{expected a class or namespace}}
+    // expected-error{{'Base' is not a class, namespace, or scoped enumeration}}
   }
 };
 
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 93f8ff1..7eb5e37 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
@@ -24,14 +24,14 @@
 #endif
 
 template<typename T> 
-T pi1 = T(3.1415926535897932385);
+T pi1 = T(3.1415926535897932385); // expected-note 0-2 {{here}}
 
 // Should recover as if specialization
 template float pi1<float> = 1.0;  // expected-error {{explicit template instantiation cannot have a definition; if this definition is meant to be an explicit specialization, add '<>' after the 'template' keyword}}
 #ifndef FIXING
 namespace expected_global {
-  template<> double pi1<double> = 1.5;  // expected-error {{no variable template matches specialization}}
+  template<> double pi1<double> = 1.5;  // expected-error {{variable template specialization of 'pi1' must originally be declared in the global scope}}
   template int pi1<int> = 10;  // expected-error {{explicit template instantiation cannot have a definition; if this definition is meant to be an explicit specialization, add '<>' after the 'template' keyword}} \
-                                  expected-error {{no variable template matches specialization}}
+                                  expected-error {{variable template specialization of 'pi1' must originally be declared in the global scope}}
 }
 #endif
diff --git a/test/CXX/temp/temp.spec/no-body.cpp b/test/CXX/temp/temp.spec/no-body.cpp
index a4d7914..61d285b 100644
--- a/test/CXX/temp/temp.spec/no-body.cpp
+++ b/test/CXX/temp/temp.spec/no-body.cpp
@@ -37,7 +37,7 @@
 namespace exp_spec {
 #ifndef FIXING
   template<> void f0<int>(int) { }  // expected-error {{no function template matches function template specialization 'f0'}}
-  template<> struct x0<int> { };    // expected-error {{class template specialization of 'x0' must originally be declared in the global scope}}
+  template<> struct x0<int> { };    // expected-error {{class template specialization of 'x0' must occur at global scope}}
 #endif
 }
 
@@ -51,7 +51,7 @@
   template void f1<int>(int) { }    // expected-error {{explicit template instantiation cannot have a definition; if this definition is meant to be an explicit specialization, add '<>' after the 'template' keyword}} \
                                        expected-error {{no function template matches function template specialization 'f1'}}
   template struct x1<int> { };      // expected-error {{explicit template instantiation cannot have a definition; if this definition is meant to be an explicit specialization, add '<>' after the 'template' keyword}} \
-                                       expected-error {{class template specialization of 'x1' must originally be declared in the global scope}}
+                                       expected-error {{class template specialization of 'x1' must occur at global scope}}
 #endif
 }
 
diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp
index 75b198e..d0e24f5 100644
--- a/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp
+++ b/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s -Wno-c++1y-extensions
 
 // This test creates cases where implicit instantiations of various entities
 // would cause a diagnostic, but provides expliict specializations for those
@@ -10,6 +10,8 @@
   NonDefaultConstructible(int);
 };
 
+// FIXME: The "must originally be declared in namespace" diagnostics throughout
+// this file are wrong.
 
 // C++ [temp.expl.spec]p1:
 //   An explicit specialization of any of the following:
@@ -79,7 +81,7 @@
 N0::X0<void> test_X0;
 
 namespace N1 {
-  template<> struct N0::X0<const void> { }; // expected-error{{class template specialization of 'X0' must originally be declared in namespace 'N0'}}
+  template<> struct N0::X0<const void> { }; // expected-error{{class template specialization of 'X0' not in a namespace enclosing 'N0'}}
 }
 
 namespace N0 {
@@ -90,6 +92,44 @@
   void f1(void *);
 };
 
+//     -- variable template [C++1y]
+namespace N0 {
+template<typename T> int v0; // expected-note +{{here}}
+template<> extern int v0<char[1]>;
+template<> extern int v0<char[2]>;
+template<> extern int v0<char[5]>;
+template<> extern int v0<char[6]>;
+}
+using N0::v0;
+
+template<typename T> int v1; // expected-note +{{here}}
+template<> extern int v1<char[3]>;
+template<> extern int v1<char[4]>;
+template<> extern int v1<char[7]>;
+template<> extern int v1<char[8]>;
+
+template<> int N0::v0<int[1]>;
+template<> int v0<int[2]>; // FIXME: ill-formed
+template<> int ::v1<int[3]>; // expected-warning {{extra qualification}}
+template<> int v1<int[4]>;
+
+template<> int N0::v0<char[1]>;
+template<> int v0<char[2]>; // FIXME: ill-formed
+template<> int ::v1<char[3]>; // expected-warning {{extra qualification}}
+template<> int v1<char[4]>;
+
+namespace N1 {
+template<> int N0::v0<int[5]>; // expected-error {{must originally be declared in namespace 'N0'}} expected-error {{does not enclose namespace}}
+template<> int v0<int[6]>; // expected-error {{must originally be declared in namespace 'N0'}}
+template<> int ::v1<int[7]>; // expected-error {{must originally be declared in the global scope}} expected-error {{cannot name the global scope}}
+template<> int v1<int[8]>; // expected-error {{must originally be declared in the global scope}}
+
+template<> int N0::v0<char[5]>; // expected-error {{does not enclose namespace 'N0'}}
+template<> int v0<char[6]>; // FIXME: ill-formed
+template<> int ::v1<char[7]>; // expected-error {{cannot name the global scope}}
+template<> int v1<char[8]>; // FIXME: ill-formed
+}
+
 //     -- member function of a class template
 template<> void N0::X0<void*>::f1(void *) { }
 
diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp
index c972bf7..4fbc45a 100644
--- a/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp
+++ b/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp
@@ -80,7 +80,7 @@
 N0::X0<void> test_X0;
 
 namespace N1 {
-  template<> struct N0::X0<const void> { }; // expected-error{{originally}}
+  template<> struct N0::X0<const void> { }; // expected-error{{not in a namespace enclosing 'N0'}}
 }
 
 namespace N0 {
diff --git a/test/CXX/temp/temp.spec/temp.explicit/p1-emit.cpp b/test/CXX/temp/temp.spec/temp.explicit/p1-emit.cpp
index d0df305..24f68a0 100644
--- a/test/CXX/temp/temp.spec/temp.explicit/p1-emit.cpp
+++ b/test/CXX/temp/temp.spec/temp.explicit/p1-emit.cpp
@@ -20,8 +20,8 @@
 
 // For implicit instantiation of 
 long& get(bool Cond1, bool Cond2) {
-  // CHECK: @_ZN1XIlE7member1E = weak_odr global i64 0
-  // CHECK: @_ZN1XIlE7member2E = weak_odr global i64 17
+  // CHECK: @_ZN1XIlE7member1E = linkonce_odr global i64 0
+  // CHECK: @_ZN1XIlE7member2E = linkonce_odr global i64 17
   // CHECK: @_ZN1XIlE7member3E = external global i64
   return Cond1? X<long>::member1 
        : Cond2? X<long>::member2
diff --git a/test/CXX/temp/temp.spec/temp.inst/p1.cpp b/test/CXX/temp/temp.spec/temp.inst/p1.cpp
index 8684fc4..adf812b 100644
--- a/test/CXX/temp/temp.spec/temp.inst/p1.cpp
+++ b/test/CXX/temp/temp.spec/temp.inst/p1.cpp
@@ -33,24 +33,23 @@
   ScopedEnum1<double>::E e1; // ok
   ScopedEnum1<double>::E e2 = decltype(e2)::e; // expected-note {{in instantiation of enumeration 'ScopedEnum::ScopedEnum1<double>::E' requested here}}
 
-  // The behavior for enums defined within function templates is not clearly
-  // specified by the standard. We follow the rules for enums defined within
-  // class templates.
+  // DR1484 specifies that enumerations cannot be separately instantiated,
+  // they will be instantiated with the rest of the template declaration.
   template<typename T>
   int f() {
     enum class E {
-      e = T::error
+      e = T::error // expected-error {{has no members}}
     };
     return (int)E();
   }
-  int test1 = f<int>();
+  int test1 = f<int>(); // expected-note {{here}}
 
   template<typename T>
   int g() {
     enum class E {
       e = T::error // expected-error {{has no members}}
     };
-    return E::e; // expected-note {{here}}
+    return E::e;
   }
   int test2 = g<int>(); // expected-note {{here}}
 }
diff --git a/test/CodeCompletion/objc-message.mm b/test/CodeCompletion/objc-message.mm
new file mode 100644
index 0000000..352a18e
--- /dev/null
+++ b/test/CodeCompletion/objc-message.mm
@@ -0,0 +1,46 @@
+// Note: the run lines follow their respective tests, since line/column
+// matter in this test.
+
+@protocol FooTestProtocol
++ protocolClassMethod;
+- protocolInstanceMethod;
+@end
+@interface Foo <FooTestProtocol> {
+  void *isa;
+}
++ (int)classMethod1:a withKeyword:b;
++ (void)classMethod2;
++ new;
+- instanceMethod1;
+@end
+
+@interface Foo (FooTestCategory)
++ categoryClassMethod;
+- categoryInstanceMethod;
+@end
+
+template<typename T> struct RetainPtr {
+  template <typename U> struct RemovePointer { typedef U Type; };
+  template <typename U> struct RemovePointer<U*> { typedef U Type; };
+    
+  typedef typename RemovePointer<T>::Type* PtrType;
+
+  explicit operator PtrType() const;
+};
+
+void func(const RetainPtr<Foo>& ptr)
+{
+  [ptr instanceMethod1];
+}
+
+void func(const RetainPtr<id <FooTestProtocol>>& ptr)
+{
+  [ptr instanceMethod1];
+}
+
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -code-completion-at=%s:33:7 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: categoryInstanceMethod : [#id#]categoryInstanceMethod
+// CHECK-CC1: instanceMethod1 : [#id#]instanceMethod1
+// CHECK-CC1: protocolInstanceMethod : [#id#]protocolInstanceMethod
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -code-completion-at=%s:38:7 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: protocolInstanceMethod : [#id#]protocolInstanceMethod
diff --git a/test/CodeGen/2007-06-18-SextAttrAggregate.c b/test/CodeGen/2007-06-18-SextAttrAggregate.c
index f548951..92171e2 100644
--- a/test/CodeGen/2007-06-18-SextAttrAggregate.c
+++ b/test/CodeGen/2007-06-18-SextAttrAggregate.c
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 %s -o - -emit-llvm | FileCheck %s
-// XFAIL: aarch64
+// XFAIL: aarch64, arm64
 
 // PR1513
 
diff --git a/test/CodeGen/2009-02-13-zerosize-union-field-ppc.c b/test/CodeGen/2009-02-13-zerosize-union-field-ppc.c
index 2bcc7c3..eabf463 100644
--- a/test/CodeGen/2009-02-13-zerosize-union-field-ppc.c
+++ b/test/CodeGen/2009-02-13-zerosize-union-field-ppc.c
@@ -1,4 +1,4 @@
-// REQUIRES: ppc32-registered-target
+// REQUIRES: powerpc-registered-target
 // RUN: %clang_cc1 %s -triple powerpc-pc-linux -emit-llvm -o - | grep {i32 32} | count 3
 // XFAIL: *
 //  Every printf has 'i32 0' for the GEP of the string; no point counting those.
diff --git a/test/CodeGen/2010-01-13-MemBarrier.c b/test/CodeGen/2010-01-13-MemBarrier.c
index c2b0acd..74d0cb0 100644
--- a/test/CodeGen/2010-01-13-MemBarrier.c
+++ b/test/CodeGen/2010-01-13-MemBarrier.c
@@ -1,5 +1,4 @@
 // RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
-// XFAIL: sparc
 // rdar://7536390
 
 typedef unsigned __INT32_TYPE__ uint32_t;
diff --git a/test/CodeGen/2010-06-17-asmcrash.c b/test/CodeGen/2010-06-17-asmcrash.c
index 1b5efd3..048e429 100644
--- a/test/CodeGen/2010-06-17-asmcrash.c
+++ b/test/CodeGen/2010-06-17-asmcrash.c
@@ -1,5 +1,6 @@
-// REQUIRES: x86-64-registered-target
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -O1 -S -o - %s | FileCheck %s
+// REQUIRES: x86-registered-target
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -O1 -no-integrated-as \
+// RUN:     -S -o - %s | FileCheck %s
 
 typedef long long int64_t;
 typedef unsigned char uint8_t;
diff --git a/test/CodeGen/Atomics.c b/test/CodeGen/Atomics.c
index 5798dff..684f36d 100644
--- a/test/CodeGen/Atomics.c
+++ b/test/CodeGen/Atomics.c
@@ -160,23 +160,70 @@
 
 void test_compare_and_swap (void)
 {
-  sc = __sync_val_compare_and_swap (&sc, uc, sc); // CHECK: cmpxchg i8
-  uc = __sync_val_compare_and_swap (&uc, uc, sc); // CHECK: cmpxchg i8
-  ss = __sync_val_compare_and_swap (&ss, uc, sc); // CHECK: cmpxchg i16
-  us = __sync_val_compare_and_swap (&us, uc, sc); // CHECK: cmpxchg i16
-  si = __sync_val_compare_and_swap (&si, uc, sc); // CHECK: cmpxchg i32
-  ui = __sync_val_compare_and_swap (&ui, uc, sc); // CHECK: cmpxchg i32
-  sll = __sync_val_compare_and_swap (&sll, uc, sc); // CHECK: cmpxchg i64
-  ull = __sync_val_compare_and_swap (&ull, uc, sc); // CHECK: cmpxchg i64
+  sc = __sync_val_compare_and_swap (&sc, uc, sc);
+  // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i8
+  // CHECK: extractvalue { i8, i1 } [[PAIR]], 0
 
-  ui = __sync_bool_compare_and_swap (&sc, uc, sc); // CHECK: cmpxchg
-  ui = __sync_bool_compare_and_swap (&uc, uc, sc); // CHECK: cmpxchg
-  ui = __sync_bool_compare_and_swap (&ss, uc, sc); // CHECK: cmpxchg
-  ui = __sync_bool_compare_and_swap (&us, uc, sc); // CHECK: cmpxchg
-  ui = __sync_bool_compare_and_swap (&si, uc, sc); // CHECK: cmpxchg
-  ui = __sync_bool_compare_and_swap (&ui, uc, sc); // CHECK: cmpxchg
-  ui = __sync_bool_compare_and_swap (&sll, uc, sc); // CHECK: cmpxchg
-  ui = __sync_bool_compare_and_swap (&ull, uc, sc); // CHECK: cmpxchg
+  uc = __sync_val_compare_and_swap (&uc, uc, sc);
+  // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i8
+  // CHECK: extractvalue { i8, i1 } [[PAIR]], 0
+
+  ss = __sync_val_compare_and_swap (&ss, uc, sc);
+  // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i16
+  // CHECK: extractvalue { i16, i1 } [[PAIR]], 0
+
+  us = __sync_val_compare_and_swap (&us, uc, sc);
+  // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i16
+  // CHECK: extractvalue { i16, i1 } [[PAIR]], 0
+
+  si = __sync_val_compare_and_swap (&si, uc, sc);
+  // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i32
+  // CHECK: extractvalue { i32, i1 } [[PAIR]], 0
+
+  ui = __sync_val_compare_and_swap (&ui, uc, sc);
+  // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i32
+  // CHECK: extractvalue { i32, i1 } [[PAIR]], 0
+
+  sll = __sync_val_compare_and_swap (&sll, uc, sc);
+  // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i64
+  // CHECK: extractvalue { i64, i1 } [[PAIR]], 0
+
+  ull = __sync_val_compare_and_swap (&ull, uc, sc);
+  // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i64
+  // CHECK: extractvalue { i64, i1 } [[PAIR]], 0
+
+
+  ui = __sync_bool_compare_and_swap (&sc, uc, sc);
+  // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i8
+  // CHECK: extractvalue { i8, i1 } [[PAIR]], 1
+
+  ui = __sync_bool_compare_and_swap (&uc, uc, sc);
+  // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i8
+  // CHECK: extractvalue { i8, i1 } [[PAIR]], 1
+
+  ui = __sync_bool_compare_and_swap (&ss, uc, sc);
+  // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i16
+  // CHECK: extractvalue { i16, i1 } [[PAIR]], 1
+
+  ui = __sync_bool_compare_and_swap (&us, uc, sc);
+  // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i16
+  // CHECK: extractvalue { i16, i1 } [[PAIR]], 1
+
+  ui = __sync_bool_compare_and_swap (&si, uc, sc);
+  // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i32
+  // CHECK: extractvalue { i32, i1 } [[PAIR]], 1
+
+  ui = __sync_bool_compare_and_swap (&ui, uc, sc);
+  // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i32
+  // CHECK: extractvalue { i32, i1 } [[PAIR]], 1
+
+  ui = __sync_bool_compare_and_swap (&sll, uc, sc);
+  // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i64
+  // CHECK: extractvalue { i64, i1 } [[PAIR]], 1
+
+  ui = __sync_bool_compare_and_swap (&ull, uc, sc);
+  // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i64
+  // CHECK: extractvalue { i64, i1 } [[PAIR]], 1
 }
 
 void test_lock (void)
diff --git a/test/CodeGen/PR4611-bitfield-layout.c b/test/CodeGen/PR4611-bitfield-layout.c
index a383f34..4f9abea 100644
--- a/test/CodeGen/PR4611-bitfield-layout.c
+++ b/test/CodeGen/PR4611-bitfield-layout.c
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s
 //
-// CHECK: struct.object_entry = type { [4 x i8] }
+// CHECK: struct.object_entry = type { i32 }
 
 struct object_entry {
        unsigned int type:3, pack_id:16, depth:13;
diff --git a/test/CodeGen/PR8880.c b/test/CodeGen/PR8880.c
new file mode 100644
index 0000000..e03d2a4
--- /dev/null
+++ b/test/CodeGen/PR8880.c
@@ -0,0 +1,173 @@
+// RUN: %clang_cc1 -Wno-gcc-compat -emit-llvm -o - %s | FileCheck %s
+
+void pr8880_cg_1(int *iptr) {
+// CHECK-LABEL: define void @pr8880_cg_1(
+  int i, j;
+// CHECK: br label %[[OUTER_COND:[0-9A-Za-z$._]+]]
+  for (i = 2; i != 10 ; i++ )
+// CHECK: [[OUTER_COND]]
+// CHECK: label %[[OUTER_BODY:[0-9A-Za-z$._]+]], label %[[OUTER_END:[0-9A-Za-z$._]+]]
+// CHECK: [[OUTER_BODY]]
+// CHECK: br label %[[INNER_COND:[0-9A-Za-z$._]+]]
+    for (j = 3 ; j < 22; (void)({ ++j; break; j;})) {
+// CHECK: [[INNER_COND]]
+// CHECK: label %[[INNER_BODY:[0-9A-Za-z$._]+]], label %[[INNER_END:[0-9A-Za-z$._]+]]
+// CHECK: [[INNER_BODY]]
+      *iptr = 7;
+// CHECK: store i32 7,
+// CHECK: br label %[[INNER_INC:[0-9A-Za-z$._]+]]
+// CHECK: [[INNER_INC]]
+
+// break in 3rd expression of inner loop causes branch to end of inner loop
+
+// CHECK: br label %[[INNER_END:[0-9A-Za-z$._]+]]
+// CHECK: [[INNER_END]]
+    }
+// CHECK: br label %[[OUTER_INC:[0-9A-Za-z$._]+]]
+// CHECK: [[OUTER_INC]]
+// CHECK: br label %[[OUTER_COND]]
+// CHECK: [[OUTER_END]]
+// CHECK: ret
+}
+
+void pr8880_cg_2(int *iptr) {
+// CHECK-LABEL: define void @pr8880_cg_2(
+  int i, j;
+// CHECK: br label %[[OUTER_COND:[0-9A-Za-z$._]+]]
+  for (i = 2; i != 10 ; i++ )
+// CHECK: [[OUTER_COND]]
+// CHECK: label %[[OUTER_BODY:[0-9A-Za-z$._]+]], label %[[OUTER_END:[0-9A-Za-z$._]+]]
+// CHECK: [[OUTER_BODY]]
+// CHECK: br label %[[INNER_COND:[0-9A-Za-z$._]+]]
+    for (j = 3 ; j < 22; (void)({ ++j; continue; j;})) {
+// CHECK: [[INNER_COND]]
+// CHECK: label %[[INNER_BODY:[0-9A-Za-z$._]+]], label %[[INNER_END:[0-9A-Za-z$._]+]]
+// CHECK: [[INNER_BODY]]
+      *iptr = 7;
+// CHECK: store i32 7,
+// CHECK: br label %[[INNER_INC:[0-9A-Za-z$._]+]]
+// CHECK: [[INNER_INC]]
+
+// continue in 3rd expression of inner loop causes branch to inc of inner loop
+
+// CHECK: br label %[[INNER_INC]]
+// CHECK: [[INNER_END]]
+    }
+// CHECK: br label %[[OUTER_INC:[0-9A-Za-z$._]+]]
+// CHECK: [[OUTER_INC]]
+// CHECK: br label %[[OUTER_COND]]
+// CHECK: [[OUTER_END]]
+// CHECK: ret
+}
+
+void pr8880_cg_3(int *iptr) {
+// CHECK-LABEL: define void @pr8880_cg_3(
+  int i, j;
+// CHECK: br label %[[OUTER_COND:[0-9A-Za-z$._]+]]
+  for (i = 2 ; i != 10 ; i++ )
+// CHECK: [[OUTER_COND]]
+// CHECK: label %[[OUTER_BODY:[0-9A-Za-z$._]+]], label %[[OUTER_END:[0-9A-Za-z$._]+]]
+// CHECK: [[OUTER_BODY]]
+// CHECK: br label %[[INNER_COND:[0-9A-Za-z$._]+]]
+    for (j = 3 ; ({break; j;}); j++) {
+
+// break in 2nd expression of inner loop causes branch to end of inner loop
+
+// CHECK: [[INNER_COND]]
+// CHECK: br label %[[INNER_END:[0-9A-Za-z$._]+]]
+// CHECK: label %[[INNER_BODY:[0-9A-Za-z$._]+]], label %[[INNER_END:[0-9A-Za-z$._]+]]
+// CHECK: [[INNER_BODY]]
+      *iptr = 7;
+// CHECK: store i32 7,
+// CHECK: br label %[[INNER_INC:[0-9A-Za-z$._]+]]
+// CHECK: [[INNER_INC]]
+// CHECK: br label %[[INNER_COND]]
+    }
+// CHECK: [[INNER_END]]
+// CHECK: br label %[[OUTER_INC:[0-9A-Za-z$._]+]]
+// CHECK: [[OUTER_INC]]
+// CHECK: br label %[[OUTER_COND]]
+// CHECK: [[OUTER_END]]
+// CHECK: ret
+}
+
+void pr8880_cg_4(int *iptr) {
+// CHECK-LABEL: define void @pr8880_cg_4(
+  int i, j;
+// CHECK: br label %[[OUTER_COND:[0-9A-Za-z$._]+]]
+  for (i = 2 ; i != 10 ; i++ )
+// CHECK: [[OUTER_COND]]
+// CHECK: label %[[OUTER_BODY:[0-9A-Za-z$._]+]], label %[[OUTER_END:[0-9A-Za-z$._]+]]
+// CHECK: [[OUTER_BODY]]
+// CHECK: br label %[[INNER_COND:[0-9A-Za-z$._]+]]
+    for (j = 3 ; ({continue; j;}); j++) {
+
+// continue in 2nd expression of inner loop causes branch to inc of inner loop
+
+// CHECK: [[INNER_COND]]
+// CHECK: br label %[[INNER_INC:[0-9A-Za-z$._]+]]
+// CHECK: label %[[INNER_BODY:[0-9A-Za-z$._]+]], label %[[INNER_END:[0-9A-Za-z$._]+]]
+// CHECK: [[INNER_BODY]]
+      *iptr = 7;
+// CHECK: store i32 7,
+// CHECK: br label %[[INNER_INC]]
+// CHECK: [[INNER_INC]]
+// CHECK: br label %[[INNER_COND]]
+    }
+// CHECK: [[INNER_END]]
+// CHECK: br label %[[OUTER_INC:[0-9A-Za-z$._]+]]
+// CHECK: [[OUTER_INC]]
+// CHECK: br label %[[OUTER_COND]]
+// CHECK: [[OUTER_END]]
+// CHECK: ret
+}
+
+void pr8880_cg_5(int x, int *iptr) {
+// CHECK-LABEL: define void @pr8880_cg_5(
+  int y = 5;
+// CHECK: br label %[[OUTER_COND:[0-9A-Za-z$._]+]]
+// CHECK: [[OUTER_COND]]
+  while(--x) {
+// CHECK: label %[[OUTER_BODY:[0-9A-Za-z$._]+]], label %[[OUTER_END:[0-9A-Za-z$._]+]]
+// CHECK: [[OUTER_BODY]]
+// CHECK: br label %[[INNER_COND:[0-9A-Za-z$._]+]]
+    while(({ break; --y; })) {
+// CHECK: [[INNER_COND]]
+// CHECK: br label %[[INNER_END:[0-9A-Za-z$._]+]]
+// CHECK: label %[[INNER_BODY:[0-9A-Za-z$._]+]], label %[[INNER_END:[0-9A-Za-z$._]+]]
+// CHECK: [[INNER_BODY]]
+      *iptr = 7;
+// CHECK: store i32 7,
+    }
+// CHECK: br label %[[INNER_COND]]
+  }
+// CHECK: [[INNER_END]]
+// CHECK: br label %[[OUTER_COND]]
+// CHECK: [[OUTER_END]]
+// CHECK: ret void
+}
+
+void pr8880_cg_6(int x, int *iptr) {
+// CHECK-LABEL: define void @pr8880_cg_6(
+  int y = 5;
+// CHECK: br label %[[OUTER_COND:[0-9A-Za-z$._]+]]
+// CHECK: [[OUTER_COND]]
+  while(--x) {
+// CHECK: label %[[OUTER_BODY:[0-9A-Za-z$._]+]], label %[[OUTER_END:[0-9A-Za-z$._]+]]
+// CHECK: [[OUTER_BODY]]
+// CHECK: br label %[[INNER_BODY:[0-9A-Za-z$._]+]]
+// CHECK: [[INNER_BODY]]
+    do {
+// CHECK: store i32 7,
+      *iptr = 7;
+// CHECK: br label %[[INNER_COND:[0-9A-Za-z$._]+]]
+    } while(({ break; --y; }));
+// CHECK: [[INNER_COND]]
+// CHECK: br label %[[INNER_END:[0-9A-Za-z$._]+]]
+// CHECK: label %[[INNER_BODY:[0-9A-Za-z$._]+]], label %[[INNER_END]]
+  }
+// CHECK: [[INNER_END]]
+// CHECK: br label %[[OUTER_COND]]
+// CHECK: [[OUTER_END]]
+// CHECK: ret void
+}
diff --git a/test/CodeGen/a15.c b/test/CodeGen/a15.c
deleted file mode 100644
index e4986d8..0000000
--- a/test/CodeGen/a15.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: %clang -target armv7-none-linux-gnueabi -mcpu=cortex-a15 -emit-llvm -S %s  -o /dev/null
-
-int main() {
-  return 0;
-}
diff --git a/test/CodeGen/a5.c b/test/CodeGen/a5.c
deleted file mode 100644
index b342d35..0000000
--- a/test/CodeGen/a5.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: %clang -target armv7-none-linux-gnueabi -mcpu=cortex-a5 -emit-llvm -S %s  -o /dev/null
-
-int main() {
-  return 0;
-}
diff --git a/test/CodeGen/aarch64-arguments.c b/test/CodeGen/aarch64-arguments.c
deleted file mode 100644
index a70dfb1..0000000
--- a/test/CodeGen/aarch64-arguments.c
+++ /dev/null
@@ -1,194 +0,0 @@
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -emit-llvm -w -o - %s | FileCheck -check-prefix=PCS %s
-
-// Sign extension is performed by the callee on AArch64, which means
-// that we *shouldn't* tag arguments and returns with their extension.
-
-// PCS-LABEL: define i8 @f0(i16 %a)
-char f0(short a) {
-  return a;
-}
-
-// PCS: define [1 x i64] @f1()
-struct s1 { char f0; };
-struct s1 f1(void) {}
-
-// PCS: define [1 x i64] @f2()
-struct s2 { short f0; };
-struct s2 f2(void) {}
-
-// PCS: define [1 x i64] @f3()
-struct s3 { int f0; };
-struct s3 f3(void) {}
-
-// PCS: define [1 x i64] @f4()
-struct s4 { struct s4_0 { int f0; } f0; };
-struct s4 f4(void) {}
-
-// PCS: define [1 x i64] @f5()
-struct s5 { struct { } f0; int f1; };
-struct s5 f5(void) {}
-
-// PCS: define  [1 x i64] @f6()
-struct s6 { int f0[1]; };
-struct s6 f6(void) {}
-
-// PCS-LABEL: define void @f7()
-struct s7 { struct { int : 0; } f0; };
-struct s7 f7(void) {}
-
-// PCS-LABEL: define  void @f8()
-struct s8 { struct { int : 0; } f0[1]; };
-struct s8 f8(void) {}
-
-// PCS: define [1 x i64] @f9()
-struct s9 { long f0; int : 0; };
-struct s9 f9(void) {}
-
-// PCS: define [1 x i64] @f10()
-struct s10 { long f0; int : 0; int : 0; };
-struct s10 f10(void) {}
-
-// PCS: define [1 x i64] @f11()
-struct s11 { int : 0; long f0; };
-struct s11 f11(void) {}
-
-// PCS: define [1 x i64] @f12()
-union u12 { char f0; short f1; int f2; long f3; };
-union u12 f12(void) {}
-
-// PCS-LABEL: define %struct.s13 @f13()
-struct s13 { float f0; };
-struct s13 f13(void) {}
-
-// PCS-LABEL: define %union.u14 @f14()
-union u14 { float f0; };
-union u14 f14(void) {}
-
-// PCS-LABEL: define void @f15()
-void f15(struct s7 a0) {}
-
-// PCS-LABEL: define void @f16()
-void f16(struct s8 a0) {}
-
-// PCS: define [1 x i64] @f17()
-struct s17 { short f0 : 13; char f1 : 4; };
-struct s17 f17(void) {}
-
-// PCS: define [1 x i64] @f18()
-struct s18 { short f0; char f1 : 4; };
-struct s18 f18(void) {}
-
-// PCS: define [1 x i64] @f19()
-struct s19 { long f0; struct s8 f1; };
-struct s19 f19(void) {}
-
-// PCS: define [1 x i64] @f20()
-struct s20 { struct s8 f1; long f0; };
-struct s20 f20(void) {}
-
-// PCS: define [1 x i64] @f21()
-struct s21 { struct {} f1; long f0 : 4; };
-struct s21 f21(void) {}
-
-// PCS: define { float, float } @f22()
-// PCS: define { double, double } @f23(
-_Complex float      f22(void) {}
-_Complex double     f23(void) {}
-
-// PCS: define [1 x i64] @f24()
-struct s24 { _Complex char f0; };
-struct s24 f24() {}
-
-// PCS: define [1 x i64] @f25()
-struct s25 { _Complex short f0; };
-struct s25 f25() {}
-
-// PCS: define [1 x i64] @f26()
-struct s26 { _Complex int f0; };
-struct s26 f26() {}
-
-// PCS: define [2 x i64] @f27()
-struct s27 { _Complex long f0; };
-struct s27 f27() {}
-
-// PCS-LABEL: define void @f28(i8 %a, i16 %b, i32 %c, i64 %d, float %e, double %f)
-void f28(char a, short b, int c, long d, float e, double f) {}
-
-// PCS: define void @f29([2 x i64] %a
-struct s29 { int arr[4]; };
-void f29(struct s29 a) {}
-
-// PCS-LABEL: define void @f30(%struct.s30* %a)
-struct s30 { int arr[4]; char c;};
-void f30(struct s30 a) {}
-
-// PCS: define void @f31([4 x double] %a
-struct s31 { double arr[4]; };
-void f31(struct s31 a) {}
-
-// PCS-LABEL: define void @f32(%struct.s32* %a)
-struct s32 { float arr[5]; };
-void f32(struct s32 a) {}
-
-// Not the only solution, but it *is* an HFA.
-// PCS: define void @f33([3 x float] %a.coerce0, float %a.coerce1)
-struct s33 { float arr[3]; float a; };
-void f33(struct s33 a) {}
-
-// PCS-LABEL: define void @f34(%struct.s34* noalias sret
-struct s34 { int a[4]; char b };
-struct s34 f34(void) {}
-
-// PCS-LABEL: define void @f35()
-struct s35 {};
-void f35(struct s35 a) {}
-
-// Check padding is added:
-// PCS: @f36(i32 %x0, i32 %x1, i32 %x2, i32 %x3, i32 %x4, i32 %x5, i32 %x6, [1 x i64], %struct.s36* byval align 8 %stacked)
-struct s36 { long a, b; };
-void f36(int x0, int x1, int x2, int x3, int x4, int x5, int x6, struct s36 stacked) {}
-
-// But only once:
-// PCS: @f37(i32 %x0, i32 %x1, i32 %x2, i32 %x3, i32 %x4, i32 %x5, i32 %x6, [1 x i64], %struct.s37* byval align 8 %stacked, %struct.s37* byval align 8 %stacked2)
-struct s37 { long a, b; };
-void f37(int x0, int x1, int x2, int x3, int x4, int x5, int x6, struct s37 stacked, struct s37 stacked2) {}
-
-// Check for HFA padding args. Also, they should not end up on the stack in a
-// way which will have holes in when lowered further by LLVM. In particular [3 x
-// float] would be unacceptable.
-
-// PCS: @f38(float %s0, double %d1, float %s2, float %s3, float %s4, float %s5, [2 x float], %struct.s38* byval align 4 %stacked)
-struct s38 { float a, b, c; };
-void f38(float s0, double d1, float s2, float s3, float s4, float s5, struct s38 stacked) {}
-
-// Check both VFP and integer arguments are padded (also that pointers and enums
-// get counted as integer types correctly).
-struct s39_int { long a, b; };
-struct s39_float { float a, b, c, d; };
-enum s39_enum { Val1, Val2 };
-// PCS: @f39(float %s0, i32 %x0, float %s1, i32* %x1, float %s2, i32 %x2, float %s3, float %s4, i32 %x3, [3 x float], %struct.s39_float* byval align 4 %stacked, i32 %x4, i32 %x5, i32 %x6, [1 x i64], %struct.s39_int* byval align 8 %stacked2)
-void f39(float s0, int x0, float s1, int *x1, float s2, enum s39_enum x2, float s3, float s4,
-         int x3, struct s39_float stacked, int x4, int x5, int x6,
-         struct s39_int stacked2) {}
-
-struct s40 { __int128 a; };
-// PCS: @f40(i32 %x0, [1 x i128] %x2_3.coerce, i32 %x4, i32 %x5, i32 %x6, [1 x i64], %struct.s40* byval align 16 %stacked)
-void f40(int x0, struct s40 x2_3, int x4, int x5, int x6, struct s40 stacked) {}
-
-// Checking: __int128 will get properly aligned type, with padding so big struct doesn't use x7.
-struct s41 { int arr[5]; };
-// PCS: @f41(i32 %x0, i32 %x1, i32 %x2, i32 %x3, i32 %x4, i32 %x5, i32 %x6, [1 x i64], i128* byval align 16, %struct.s41* %stacked2)
-int f41(int x0, int x1, int x2, int x3, int x4, int x5, int x6, __int128 stacked, struct s41 stacked2) {}
-
-// Checking: __int128 needing to be aligned in registers will consume correct
-// number. Previously padding was inserted before "stacked" because x6_7 was
-// "allocated" to x5 and x6 by clang.
-// PCS: @f42(i32 %x0, i32 %x1, i32 %x2, i32 %x3, i32 %x4, i128 %x6_7, i128* byval align 16)
-void f42(int x0, int x1, int x2, int x3, int x4, __int128 x6_7, __int128 stacked) {}
-
-// Checking: __fp16 is extended to double when calling variadic functions
-void variadic(int a, ...);
-void f43(__fp16 *in) {
-  variadic(42, *in);
-// CHECK: call void @variadic(i32 42, double
-}
diff --git a/test/CodeGen/aarch64-inline-asm.c b/test/CodeGen/aarch64-inline-asm.c
index ca39c6e..c7ce375 100644
--- a/test/CodeGen/aarch64-inline-asm.c
+++ b/test/CodeGen/aarch64-inline-asm.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-none-linux-gnu -emit-llvm -o - %s | FileCheck %s
 
 // The only part clang really deals with is the lvalue/rvalue
 // distinction on constraints. It's sufficient to emit llvm and make
diff --git a/test/CodeGen/aarch64-neon-2velem.c b/test/CodeGen/aarch64-neon-2velem.c
index 2a1eae4..fa910ff 100644
--- a/test/CodeGen/aarch64-neon-2velem.c
+++ b/test/CodeGen/aarch64-neon-2velem.c
@@ -1,817 +1,2452 @@
 // REQUIRES: aarch64-registered-target
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +neon \
-// RUN:   -ffp-contract=fast -S -O3 -o - %s | FileCheck %s
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +neon \
-// RUN:   -S -O3 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon -S -O3 -o - %s | FileCheck %s
 
 // Test new aarch64 intrinsics and types
 
 #include <arm_neon.h>
 
 int16x4_t test_vmla_lane_s16(int16x4_t a, int16x4_t b, int16x4_t v) {
-  // CHECK: test_vmla_lane_s16
-  return vmla_lane_s16(a, b, v, 1);
-  // CHECK: mla {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmla_lane_s16
+  return vmla_lane_s16(a, b, v, 3);
+  // CHECK: mla {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[3]
 }
 
 int16x8_t test_vmlaq_lane_s16(int16x8_t a, int16x8_t b, int16x4_t v) {
-  // CHECK: test_vmlaq_lane_s16
-  return vmlaq_lane_s16(a, b, v, 1);
-  // CHECK: mla {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmlaq_lane_s16
+  return vmlaq_lane_s16(a, b, v, 3);
+  // CHECK: mla {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[3]
 }
 
 int32x2_t test_vmla_lane_s32(int32x2_t a, int32x2_t b, int32x2_t v) {
-  // CHECK: test_vmla_lane_s32
+  // CHECK-LABEL: test_vmla_lane_s32
   return vmla_lane_s32(a, b, v, 1);
   // CHECK: mla {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
 }
 
 int32x4_t test_vmlaq_lane_s32(int32x4_t a, int32x4_t b, int32x2_t v) {
-  // CHECK: test_vmlaq_lane_s32
+  // CHECK-LABEL: test_vmlaq_lane_s32
   return vmlaq_lane_s32(a, b, v, 1);
   // CHECK: mla {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
 }
 
 int16x4_t test_vmla_laneq_s16(int16x4_t a, int16x4_t b, int16x8_t v) {
-  // CHECK: test_vmla_laneq_s16
-  return vmla_laneq_s16(a, b, v, 1);
-  // CHECK: mla {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmla_laneq_s16
+  return vmla_laneq_s16(a, b, v, 7);
+  // CHECK: mla {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[7]
 }
 
 int16x8_t test_vmlaq_laneq_s16(int16x8_t a, int16x8_t b, int16x8_t v) {
-  // CHECK: test_vmlaq_laneq_s16
-  return vmlaq_laneq_s16(a, b, v, 1);
-  // CHECK: mla {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmlaq_laneq_s16
+  return vmlaq_laneq_s16(a, b, v, 7);
+  // CHECK: mla {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[7]
 }
 
 int32x2_t test_vmla_laneq_s32(int32x2_t a, int32x2_t b, int32x4_t v) {
-  // CHECK: test_vmla_laneq_s32
-  return vmla_laneq_s32(a, b, v, 1);
-  // CHECK: mla {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
+  // CHECK-LABEL: test_vmla_laneq_s32
+  return vmla_laneq_s32(a, b, v, 3);
+  // CHECK: mla {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[3]
 }
 
 int32x4_t test_vmlaq_laneq_s32(int32x4_t a, int32x4_t b, int32x4_t v) {
-  // CHECK: test_vmlaq_laneq_s32
-  return vmlaq_laneq_s32(a, b, v, 1);
-  // CHECK: mla {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
+  // CHECK-LABEL: test_vmlaq_laneq_s32
+  return vmlaq_laneq_s32(a, b, v, 3);
+  // CHECK: mla {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[3]
 }
 
 int16x4_t test_vmls_lane_s16(int16x4_t a, int16x4_t b, int16x4_t v) {
-  // CHECK: test_vmls_lane_s16
-  return vmls_lane_s16(a, b, v, 1);
-  // CHECK: mls {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmls_lane_s16
+  return vmls_lane_s16(a, b, v, 3);
+  // CHECK: mls {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[3]
 }
 
 int16x8_t test_vmlsq_lane_s16(int16x8_t a, int16x8_t b, int16x4_t v) {
-  // CHECK: test_vmlsq_lane_s16
-  return vmlsq_lane_s16(a, b, v, 1);
-  // CHECK: mls {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmlsq_lane_s16
+  return vmlsq_lane_s16(a, b, v, 3);
+  // CHECK: mls {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[3]
 }
 
 int32x2_t test_vmls_lane_s32(int32x2_t a, int32x2_t b, int32x2_t v) {
-  // CHECK: test_vmls_lane_s32
+  // CHECK-LABEL: test_vmls_lane_s32
   return vmls_lane_s32(a, b, v, 1);
   // CHECK: mls {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
 }
 
 int32x4_t test_vmlsq_lane_s32(int32x4_t a, int32x4_t b, int32x2_t v) {
-  // CHECK: test_vmlsq_lane_s32
+  // CHECK-LABEL: test_vmlsq_lane_s32
   return vmlsq_lane_s32(a, b, v, 1);
   // CHECK: mls {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
 }
 
 int16x4_t test_vmls_laneq_s16(int16x4_t a, int16x4_t b, int16x8_t v) {
-  // CHECK: test_vmls_laneq_s16
-  return vmls_laneq_s16(a, b, v, 1);
-  // CHECK: mls {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmls_laneq_s16
+  return vmls_laneq_s16(a, b, v, 7);
+  // CHECK: mls {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[7]
 }
 
 int16x8_t test_vmlsq_laneq_s16(int16x8_t a, int16x8_t b, int16x8_t v) {
-  // CHECK: test_vmlsq_laneq_s16
-  return vmlsq_laneq_s16(a, b, v, 1);
-  // CHECK: mls {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmlsq_laneq_s16
+  return vmlsq_laneq_s16(a, b, v, 7);
+  // CHECK: mls {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[7]
 }
 
 int32x2_t test_vmls_laneq_s32(int32x2_t a, int32x2_t b, int32x4_t v) {
-  // CHECK: test_vmls_laneq_s32
-  return vmls_laneq_s32(a, b, v, 1);
-  // CHECK: mls {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
+  // CHECK-LABEL: test_vmls_laneq_s32
+  return vmls_laneq_s32(a, b, v, 3);
+  // CHECK: mls {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[3]
 }
 
 int32x4_t test_vmlsq_laneq_s32(int32x4_t a, int32x4_t b, int32x4_t v) {
-  // CHECK: test_vmlsq_laneq_s32
-  return vmlsq_laneq_s32(a, b, v, 1);
-  // CHECK: mls {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
+  // CHECK-LABEL: test_vmlsq_laneq_s32
+  return vmlsq_laneq_s32(a, b, v, 3);
+  // CHECK: mls {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[3]
 }
 
 int16x4_t test_vmul_lane_s16(int16x4_t a, int16x4_t v) {
-  // CHECK: test_vmul_lane_s16
-  return vmul_lane_s16(a, v, 1);
-  // CHECK: mul {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmul_lane_s16
+  return vmul_lane_s16(a, v, 3);
+  // CHECK: mul {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[3]
 }
 
 int16x8_t test_vmulq_lane_s16(int16x8_t a, int16x4_t v) {
-  // CHECK: test_vmulq_lane_s16
-  return vmulq_lane_s16(a, v, 1);
-  // CHECK: mul {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmulq_lane_s16
+  return vmulq_lane_s16(a, v, 3);
+  // CHECK: mul {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[3]
 }
 
 int32x2_t test_vmul_lane_s32(int32x2_t a, int32x2_t v) {
-  // CHECK: test_vmul_lane_s32
+  // CHECK-LABEL: test_vmul_lane_s32
   return vmul_lane_s32(a, v, 1);
   // CHECK: mul {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
 }
 
 int32x4_t test_vmulq_lane_s32(int32x4_t a, int32x2_t v) {
-  // CHECK: test_vmulq_lane_s32
+  // CHECK-LABEL: test_vmulq_lane_s32
   return vmulq_lane_s32(a, v, 1);
   // CHECK: mul {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
 }
 
 uint16x4_t test_vmul_lane_u16(uint16x4_t a, uint16x4_t v) {
-  // CHECK: test_vmul_lane_u16
-  return vmul_lane_u16(a, v, 1);
-  // CHECK: mul {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmul_lane_u16
+  return vmul_lane_u16(a, v, 3);
+  // CHECK: mul {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[3]
 }
 
 uint16x8_t test_vmulq_lane_u16(uint16x8_t a, uint16x4_t v) {
-  // CHECK: test_vmulq_lane_u16
-  return vmulq_lane_u16(a, v, 1);
-  // CHECK: mul {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmulq_lane_u16
+  return vmulq_lane_u16(a, v, 3);
+  // CHECK: mul {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[3]
 }
 
 uint32x2_t test_vmul_lane_u32(uint32x2_t a, uint32x2_t v) {
-  // CHECK: test_vmul_lane_u32
+  // CHECK-LABEL: test_vmul_lane_u32
   return vmul_lane_u32(a, v, 1);
   // CHECK: mul {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
 }
 
 uint32x4_t test_vmulq_lane_u32(uint32x4_t a, uint32x2_t v) {
-  // CHECK: test_vmulq_lane_u32
+  // CHECK-LABEL: test_vmulq_lane_u32
   return vmulq_lane_u32(a, v, 1);
   // CHECK: mul {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
 }
 
 int16x4_t test_vmul_laneq_s16(int16x4_t a, int16x8_t v) {
-  // CHECK: test_vmul_laneq_s16
-  return vmul_laneq_s16(a, v, 1);
-  // CHECK: mul {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmul_laneq_s16
+  return vmul_laneq_s16(a, v, 7);
+  // CHECK: mul {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[7]
 }
 
 int16x8_t test_vmulq_laneq_s16(int16x8_t a, int16x8_t v) {
-  // CHECK: test_vmulq_laneq_s16
-  return vmulq_laneq_s16(a, v, 1);
-  // CHECK: mul {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmulq_laneq_s16
+  return vmulq_laneq_s16(a, v, 7);
+  // CHECK: mul {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[7]
 }
 
 int32x2_t test_vmul_laneq_s32(int32x2_t a, int32x4_t v) {
-  // CHECK: test_vmul_laneq_s32
-  return vmul_laneq_s32(a, v, 1);
-  // CHECK: mul {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
+  // CHECK-LABEL: test_vmul_laneq_s32
+  return vmul_laneq_s32(a, v, 3);
+  // CHECK: mul {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[3]
 }
 
 int32x4_t test_vmulq_laneq_s32(int32x4_t a, int32x4_t v) {
-  // CHECK: test_vmulq_laneq_s32
-  return vmulq_laneq_s32(a, v, 1);
-  // CHECK: mul {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
+  // CHECK-LABEL: test_vmulq_laneq_s32
+  return vmulq_laneq_s32(a, v, 3);
+  // CHECK: mul {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[3]
 }
 
 uint16x4_t test_vmul_laneq_u16(uint16x4_t a, uint16x8_t v) {
-  // CHECK: test_vmul_laneq_u16
-  return vmul_laneq_u16(a, v, 1);
-  // CHECK: mul {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmul_laneq_u16
+  return vmul_laneq_u16(a, v, 7);
+  // CHECK: mul {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[7]
 }
 
 uint16x8_t test_vmulq_laneq_u16(uint16x8_t a, uint16x8_t v) {
-  // CHECK: test_vmulq_laneq_u16
-  return vmulq_laneq_u16(a, v, 1);
-  // CHECK: mul {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmulq_laneq_u16
+  return vmulq_laneq_u16(a, v, 7);
+  // CHECK: mul {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[7]
 }
 
 uint32x2_t test_vmul_laneq_u32(uint32x2_t a, uint32x4_t v) {
-  // CHECK: test_vmul_laneq_u32
-  return vmul_laneq_u32(a, v, 1);
-  // CHECK: mul {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
+  // CHECK-LABEL: test_vmul_laneq_u32
+  return vmul_laneq_u32(a, v, 3);
+  // CHECK: mul {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[3]
 }
 
 uint32x4_t test_vmulq_laneq_u32(uint32x4_t a, uint32x4_t v) {
-  // CHECK: test_vmulq_laneq_u32
-  return vmulq_laneq_u32(a, v, 1);
-  // CHECK: mul {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
+  // CHECK-LABEL: test_vmulq_laneq_u32
+  return vmulq_laneq_u32(a, v, 3);
+  // CHECK: mul {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[3]
 }
 
 float32x2_t test_vfma_lane_f32(float32x2_t a, float32x2_t b, float32x2_t v) {
-  // CHECK: test_vfma_lane_f32
+  // CHECK-LABEL: test_vfma_lane_f32
   return vfma_lane_f32(a, b, v, 1);
   // CHECK: fmla {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
 }
 
 float32x4_t test_vfmaq_lane_f32(float32x4_t a, float32x4_t b, float32x2_t v) {
-  // CHECK: test_vfmaq_lane_f32
+  // CHECK-LABEL: test_vfmaq_lane_f32
   return vfmaq_lane_f32(a, b, v, 1);
   // CHECK: fmla {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
 }
 
 float32x2_t test_vfma_laneq_f32(float32x2_t a, float32x2_t b, float32x4_t v) {
-  // CHECK: test_vfma_laneq_f32
-  return vfma_laneq_f32(a, b, v, 1);
-  // CHECK: fmla {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
+  // CHECK-LABEL: test_vfma_laneq_f32
+  return vfma_laneq_f32(a, b, v, 3);
+  // CHECK: fmla {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[3]
 }
 
 float32x4_t test_vfmaq_laneq_f32(float32x4_t a, float32x4_t b, float32x4_t v) {
-  // CHECK: test_vfmaq_laneq_f32
-  return vfmaq_laneq_f32(a, b, v, 1);
-  // CHECK: fmla {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
+  // CHECK-LABEL: test_vfmaq_laneq_f32
+  return vfmaq_laneq_f32(a, b, v, 3);
+  // CHECK: fmla {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[3]
 }
 
 float32x2_t test_vfms_lane_f32(float32x2_t a, float32x2_t b, float32x2_t v) {
-  // CHECK: test_vfms_lane_f32
+  // CHECK-LABEL: test_vfms_lane_f32
   return vfms_lane_f32(a, b, v, 1);
   // CHECK: fmls {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
 }
 
 float32x4_t test_vfmsq_lane_f32(float32x4_t a, float32x4_t b, float32x2_t v) {
-  // CHECK: test_vfmsq_lane_f32
+  // CHECK-LABEL: test_vfmsq_lane_f32
   return vfmsq_lane_f32(a, b, v, 1);
   // CHECK: fmls {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
 }
 
 float32x2_t test_vfms_laneq_f32(float32x2_t a, float32x2_t b, float32x4_t v) {
-  // CHECK: test_vfms_laneq_f32
-  return vfms_laneq_f32(a, b, v, 1);
-  // CHECK: fmls {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
+  // CHECK-LABEL: test_vfms_laneq_f32
+  return vfms_laneq_f32(a, b, v, 3);
+  // CHECK: fmls {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[3]
 }
 
 float32x4_t test_vfmsq_laneq_f32(float32x4_t a, float32x4_t b, float32x4_t v) {
-  // CHECK: test_vfmsq_laneq_f32
-  return vfmsq_laneq_f32(a, b, v, 1);
-  // CHECK: fmls {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
+  // CHECK-LABEL: test_vfmsq_laneq_f32
+  return vfmsq_laneq_f32(a, b, v, 3);
+  // CHECK: fmls {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[3]
 }
 
 float64x2_t test_vfmaq_lane_f64(float64x2_t a, float64x2_t b, float64x1_t v) {
-  // CHECK: test_vfmaq_lane_f64
+  // CHECK-LABEL: test_vfmaq_lane_f64
   return vfmaq_lane_f64(a, b, v, 0);
   // CHECK: fmla {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.d[0]
 }
 
-float64x2_t test_vfmaq_laneq_f64_0(float64x2_t a, float64x2_t b, float64x2_t v) {
-  // CHECK: test_vfmaq_laneq_f64
-  return vfmaq_laneq_f64(a, b, v, 0);
-  // CHECK: fmla {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.d[0]
-}
-
 float64x2_t test_vfmaq_laneq_f64(float64x2_t a, float64x2_t b, float64x2_t v) {
-  // CHECK: test_vfmaq_laneq_f64
+  // CHECK-LABEL: test_vfmaq_laneq_f64
   return vfmaq_laneq_f64(a, b, v, 1);
   // CHECK: fmla {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.d[1]
 }
 
 float64x2_t test_vfmsq_lane_f64(float64x2_t a, float64x2_t b, float64x1_t v) {
-  // CHECK: test_vfmsq_lane_f64
+  // CHECK-LABEL: test_vfmsq_lane_f64
   return vfmsq_lane_f64(a, b, v, 0);
   // CHECK: fmls {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.d[0]
 }
 
-float64x2_t test_vfmsq_laneq_f64_0(float64x2_t a, float64x2_t b, float64x2_t v) {
-  // CHECK: test_vfmsq_laneq_f64
-  return vfmsq_laneq_f64(a, b, v, 0);
-  // CHECK: fmls {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.d[0]
-}
-
 float64x2_t test_vfmsq_laneq_f64(float64x2_t a, float64x2_t b, float64x2_t v) {
-  // CHECK: test_vfmsq_laneq_f64
+  // CHECK-LABEL: test_vfmsq_laneq_f64
   return vfmsq_laneq_f64(a, b, v, 1);
   // CHECK: fmls {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.d[1]
 }
 
+float32_t test_vfmas_laneq_f32(float32_t a, float32_t b, float32x4_t v) {
+  // CHECK-LABEL: test_vfmas_laneq_f32
+  return vfmas_laneq_f32(a, b, v, 3);
+  // CHECK: fmla {{s[0-9]+}}, {{s[0-9]+}}, {{v[0-9]+}}.s[3]
+}
+
+float64_t test_vfmsd_lane_f64(float64_t a, float64_t b, float64x1_t v) {
+  // CHECK-LABEL: test_vfmsd_lane_f64
+  return vfmsd_lane_f64(a, b, v, 0);
+  // CHECK: {{fmls d[0-9]+, d[0-9]+, v[0-9]+\.d\[0\]|fmsub d[0-9]+, d[0-9]+, d[0-9]+}}
+}
+
+float32_t test_vfmss_laneq_f32(float32_t a, float32_t b, float32x4_t v) {
+  // CHECK-LABEL: test_vfmss_laneq_f32
+  return vfmss_laneq_f32(a, b, v, 3);
+  // CHECK: fmls {{s[0-9]+}}, {{s[0-9]+}}, {{v[0-9]+}}.s[3]
+}
+
+float64_t test_vfmsd_laneq_f64(float64_t a, float64_t b, float64x2_t v) {
+  // CHECK-LABEL: test_vfmsd_laneq_f64
+  return vfmsd_laneq_f64(a, b, v, 1);
+  // CHECK: fmls {{d[0-9]+}}, {{d[0-9]+}}, {{v[0-9]+}}.d[1]
+}
+
 int32x4_t test_vmlal_lane_s16(int32x4_t a, int16x4_t b, int16x4_t v) {
-  // CHECK: test_vmlal_lane_s16
-  return vmlal_lane_s16(a, b, v, 1);
-  // CHECK: smlal {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmlal_lane_s16
+  return vmlal_lane_s16(a, b, v, 3);
+  // CHECK: smlal {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[3]
 }
 
 int64x2_t test_vmlal_lane_s32(int64x2_t a, int32x2_t b, int32x2_t v) {
-  // CHECK: test_vmlal_lane_s32
+  // CHECK-LABEL: test_vmlal_lane_s32
   return vmlal_lane_s32(a, b, v, 1);
   // CHECK: smlal {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
 }
 
 int32x4_t test_vmlal_laneq_s16(int32x4_t a, int16x4_t b, int16x8_t v) {
-  // CHECK: test_vmlal_laneq_s16
-  return vmlal_laneq_s16(a, b, v, 1);
-  // CHECK: smlal {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmlal_laneq_s16
+  return vmlal_laneq_s16(a, b, v, 7);
+  // CHECK: smlal {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[7]
 }
 
 int64x2_t test_vmlal_laneq_s32(int64x2_t a, int32x2_t b, int32x4_t v) {
-  // CHECK: test_vmlal_laneq_s32
-  return vmlal_laneq_s32(a, b, v, 1);
-  // CHECK: smlal {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
+  // CHECK-LABEL: test_vmlal_laneq_s32
+  return vmlal_laneq_s32(a, b, v, 3);
+  // CHECK: smlal {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[3]
 }
 
 int32x4_t test_vmlal_high_lane_s16(int32x4_t a, int16x8_t b, int16x4_t v) {
-  // CHECK: test_vmlal_high_lane_s16
-  return vmlal_high_lane_s16(a, b, v, 1);
-  // CHECK: smlal2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmlal_high_lane_s16
+  return vmlal_high_lane_s16(a, b, v, 3);
+  // CHECK: smlal2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[3]
 }
 
 int64x2_t test_vmlal_high_lane_s32(int64x2_t a, int32x4_t b, int32x2_t v) {
-  // CHECK: test_vmlal_high_lane_s32
+  // CHECK-LABEL: test_vmlal_high_lane_s32
   return vmlal_high_lane_s32(a, b, v, 1);
   // CHECK: smlal2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
 }
 
 int32x4_t test_vmlal_high_laneq_s16(int32x4_t a, int16x8_t b, int16x8_t v) {
-  // CHECK: test_vmlal_high_laneq_s16
-  return vmlal_high_laneq_s16(a, b, v, 1);
-  // CHECK: smlal2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmlal_high_laneq_s16
+  return vmlal_high_laneq_s16(a, b, v, 7);
+  // CHECK: smlal2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[7]
 }
 
 int64x2_t test_vmlal_high_laneq_s32(int64x2_t a, int32x4_t b, int32x4_t v) {
-  // CHECK: test_vmlal_high_laneq_s32
-  return vmlal_high_laneq_s32(a, b, v, 1);
-  // CHECK: smlal2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
+  // CHECK-LABEL: test_vmlal_high_laneq_s32
+  return vmlal_high_laneq_s32(a, b, v, 3);
+  // CHECK: smlal2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[3]
 }
 
 int32x4_t test_vmlsl_lane_s16(int32x4_t a, int16x4_t b, int16x4_t v) {
-  // CHECK: test_vmlsl_lane_s16
-  return vmlsl_lane_s16(a, b, v, 1);
-  // CHECK: smlsl {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmlsl_lane_s16
+  return vmlsl_lane_s16(a, b, v, 3);
+  // CHECK: smlsl {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[3]
 }
 
 int64x2_t test_vmlsl_lane_s32(int64x2_t a, int32x2_t b, int32x2_t v) {
-  // CHECK: test_vmlsl_lane_s32
+  // CHECK-LABEL: test_vmlsl_lane_s32
   return vmlsl_lane_s32(a, b, v, 1);
   // CHECK: smlsl {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
 }
 
 int32x4_t test_vmlsl_laneq_s16(int32x4_t a, int16x4_t b, int16x8_t v) {
-  // CHECK: test_vmlsl_laneq_s16
-  return vmlsl_laneq_s16(a, b, v, 1);
-  // CHECK: smlsl {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmlsl_laneq_s16
+  return vmlsl_laneq_s16(a, b, v, 7);
+  // CHECK: smlsl {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[7]
 }
 
 int64x2_t test_vmlsl_laneq_s32(int64x2_t a, int32x2_t b, int32x4_t v) {
-  // CHECK: test_vmlsl_laneq_s32
-  return vmlsl_laneq_s32(a, b, v, 1);
-  // CHECK: smlsl {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
+  // CHECK-LABEL: test_vmlsl_laneq_s32
+  return vmlsl_laneq_s32(a, b, v, 3);
+  // CHECK: smlsl {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[3]
 }
 
 int32x4_t test_vmlsl_high_lane_s16(int32x4_t a, int16x8_t b, int16x4_t v) {
-  // CHECK: test_vmlsl_high_lane_s16
-  return vmlsl_high_lane_s16(a, b, v, 1);
-  // CHECK: smlsl2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmlsl_high_lane_s16
+  return vmlsl_high_lane_s16(a, b, v, 3);
+  // CHECK: smlsl2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[3]
 }
 
 int64x2_t test_vmlsl_high_lane_s32(int64x2_t a, int32x4_t b, int32x2_t v) {
-  // CHECK: test_vmlsl_high_lane_s32
+  // CHECK-LABEL: test_vmlsl_high_lane_s32
   return vmlsl_high_lane_s32(a, b, v, 1);
   // CHECK: smlsl2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
 }
 
 int32x4_t test_vmlsl_high_laneq_s16(int32x4_t a, int16x8_t b, int16x8_t v) {
-  // CHECK: test_vmlsl_high_laneq_s16
-  return vmlsl_high_laneq_s16(a, b, v, 1);
-  // CHECK: smlsl2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmlsl_high_laneq_s16
+  return vmlsl_high_laneq_s16(a, b, v, 7);
+  // CHECK: smlsl2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[7]
 }
 
 int64x2_t test_vmlsl_high_laneq_s32(int64x2_t a, int32x4_t b, int32x4_t v) {
-  // CHECK: test_vmlsl_high_laneq_s32
-  return vmlsl_high_laneq_s32(a, b, v, 1);
-  // CHECK: smlsl2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
+  // CHECK-LABEL: test_vmlsl_high_laneq_s32
+  return vmlsl_high_laneq_s32(a, b, v, 3);
+  // CHECK: smlsl2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[3]
 }
 
 int32x4_t test_vmlal_lane_u16(int32x4_t a, int16x4_t b, int16x4_t v) {
-  // CHECK: test_vmlal_lane_u16
-  return vmlal_lane_u16(a, b, v, 1);
-  // CHECK: umlal {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmlal_lane_u16
+  return vmlal_lane_u16(a, b, v, 3);
+  // CHECK: umlal {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[3]
 }
 
 int64x2_t test_vmlal_lane_u32(int64x2_t a, int32x2_t b, int32x2_t v) {
-  // CHECK: test_vmlal_lane_u32
+  // CHECK-LABEL: test_vmlal_lane_u32
   return vmlal_lane_u32(a, b, v, 1);
   // CHECK: umlal {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
 }
 
 int32x4_t test_vmlal_laneq_u16(int32x4_t a, int16x4_t b, int16x8_t v) {
-  // CHECK: test_vmlal_laneq_u16
-  return vmlal_laneq_u16(a, b, v, 1);
-  // CHECK: umlal {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmlal_laneq_u16
+  return vmlal_laneq_u16(a, b, v, 7);
+  // CHECK: umlal {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[7]
 }
 
 int64x2_t test_vmlal_laneq_u32(int64x2_t a, int32x2_t b, int32x4_t v) {
-  // CHECK: test_vmlal_laneq_u32
-  return vmlal_laneq_u32(a, b, v, 1);
-  // CHECK: umlal {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
+  // CHECK-LABEL: test_vmlal_laneq_u32
+  return vmlal_laneq_u32(a, b, v, 3);
+  // CHECK: umlal {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[3]
 }
 
 int32x4_t test_vmlal_high_lane_u16(int32x4_t a, int16x8_t b, int16x4_t v) {
-  // CHECK: test_vmlal_high_lane_u16
-  return vmlal_high_lane_u16(a, b, v, 1);
-  // CHECK: umlal2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmlal_high_lane_u16
+  return vmlal_high_lane_u16(a, b, v, 3);
+  // CHECK: umlal2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[3]
 }
 
 int64x2_t test_vmlal_high_lane_u32(int64x2_t a, int32x4_t b, int32x2_t v) {
-  // CHECK: test_vmlal_high_lane_u32
+  // CHECK-LABEL: test_vmlal_high_lane_u32
   return vmlal_high_lane_u32(a, b, v, 1);
   // CHECK: umlal2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
 }
 
 int32x4_t test_vmlal_high_laneq_u16(int32x4_t a, int16x8_t b, int16x8_t v) {
-  // CHECK: test_vmlal_high_laneq_u16
-  return vmlal_high_laneq_u16(a, b, v, 1);
-  // CHECK: umlal2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmlal_high_laneq_u16
+  return vmlal_high_laneq_u16(a, b, v, 7);
+  // CHECK: umlal2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[7]
 }
 
 int64x2_t test_vmlal_high_laneq_u32(int64x2_t a, int32x4_t b, int32x4_t v) {
-  // CHECK: test_vmlal_high_laneq_u32
-  return vmlal_high_laneq_u32(a, b, v, 1);
-  // CHECK: umlal2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
+  // CHECK-LABEL: test_vmlal_high_laneq_u32
+  return vmlal_high_laneq_u32(a, b, v, 3);
+  // CHECK: umlal2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[3]
 }
 
 int32x4_t test_vmlsl_lane_u16(int32x4_t a, int16x4_t b, int16x4_t v) {
-  // CHECK: test_vmlsl_lane_u16
-  return vmlsl_lane_u16(a, b, v, 1);
-  // CHECK: umlsl {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmlsl_lane_u16
+  return vmlsl_lane_u16(a, b, v, 3);
+  // CHECK: umlsl {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[3]
 }
 
 int64x2_t test_vmlsl_lane_u32(int64x2_t a, int32x2_t b, int32x2_t v) {
-  // CHECK: test_vmlsl_lane_u32
+  // CHECK-LABEL: test_vmlsl_lane_u32
   return vmlsl_lane_u32(a, b, v, 1);
   // CHECK: umlsl {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
 }
 
 int32x4_t test_vmlsl_laneq_u16(int32x4_t a, int16x4_t b, int16x8_t v) {
-  // CHECK: test_vmlsl_laneq_u16
-  return vmlsl_laneq_u16(a, b, v, 1);
-  // CHECK: umlsl {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmlsl_laneq_u16
+  return vmlsl_laneq_u16(a, b, v, 7);
+  // CHECK: umlsl {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[7]
 }
 
 int64x2_t test_vmlsl_laneq_u32(int64x2_t a, int32x2_t b, int32x4_t v) {
-  // CHECK: test_vmlsl_laneq_u32
-  return vmlsl_laneq_u32(a, b, v, 1);
-  // CHECK: umlsl {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
+  // CHECK-LABEL: test_vmlsl_laneq_u32
+  return vmlsl_laneq_u32(a, b, v, 3);
+  // CHECK: umlsl {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[3]
 }
 
 int32x4_t test_vmlsl_high_lane_u16(int32x4_t a, int16x8_t b, int16x4_t v) {
-  // CHECK: test_vmlsl_high_lane_u16
-  return vmlsl_high_lane_u16(a, b, v, 1);
-  // CHECK: umlsl2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmlsl_high_lane_u16
+  return vmlsl_high_lane_u16(a, b, v, 3);
+  // CHECK: umlsl2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[3]
 }
 
 int64x2_t test_vmlsl_high_lane_u32(int64x2_t a, int32x4_t b, int32x2_t v) {
-  // CHECK: test_vmlsl_high_lane_u32
+  // CHECK-LABEL: test_vmlsl_high_lane_u32
   return vmlsl_high_lane_u32(a, b, v, 1);
   // CHECK: umlsl2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
 }
 
 int32x4_t test_vmlsl_high_laneq_u16(int32x4_t a, int16x8_t b, int16x8_t v) {
-  // CHECK: test_vmlsl_high_laneq_u16
-  return vmlsl_high_laneq_u16(a, b, v, 1);
-  // CHECK: umlsl2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmlsl_high_laneq_u16
+  return vmlsl_high_laneq_u16(a, b, v, 7);
+  // CHECK: umlsl2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[7]
 }
 
 int64x2_t test_vmlsl_high_laneq_u32(int64x2_t a, int32x4_t b, int32x4_t v) {
-  // CHECK: test_vmlsl_high_laneq_u32
-  return vmlsl_high_laneq_u32(a, b, v, 1);
-  // CHECK: umlsl2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
+  // CHECK-LABEL: test_vmlsl_high_laneq_u32
+  return vmlsl_high_laneq_u32(a, b, v, 3);
+  // CHECK: umlsl2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[3]
 }
 
 int32x4_t test_vmull_lane_s16(int16x4_t a, int16x4_t v) {
-  // CHECK: test_vmull_lane_s16
-  return vmull_lane_s16(a, v, 1);
-  // CHECK: smull {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmull_lane_s16
+  return vmull_lane_s16(a, v, 3);
+  // CHECK: smull {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[3]
 }
 
 int64x2_t test_vmull_lane_s32(int32x2_t a, int32x2_t v) {
-  // CHECK: test_vmull_lane_s32
+  // CHECK-LABEL: test_vmull_lane_s32
   return vmull_lane_s32(a, v, 1);
   // CHECK: smull {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
 }
 
 uint32x4_t test_vmull_lane_u16(uint16x4_t a, uint16x4_t v) {
-  // CHECK: test_vmull_lane_u16
-  return vmull_lane_u16(a, v, 1);
-  // CHECK: umull {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmull_lane_u16
+  return vmull_lane_u16(a, v, 3);
+  // CHECK: umull {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[3]
 }
 
 uint64x2_t test_vmull_lane_u32(uint32x2_t a, uint32x2_t v) {
-  // CHECK: test_vmull_lane_u32
+  // CHECK-LABEL: test_vmull_lane_u32
   return vmull_lane_u32(a, v, 1);
   // CHECK: umull {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
 }
 
 int32x4_t test_vmull_high_lane_s16(int16x8_t a, int16x4_t v) {
-  // CHECK: test_vmull_high_lane_s16
-  return vmull_high_lane_s16(a, v, 1);
-  // CHECK: smull2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmull_high_lane_s16
+  return vmull_high_lane_s16(a, v, 3);
+  // CHECK: smull2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[3]
 }
 
 int64x2_t test_vmull_high_lane_s32(int32x4_t a, int32x2_t v) {
-  // CHECK: test_vmull_high_lane_s32
+  // CHECK-LABEL: test_vmull_high_lane_s32
   return vmull_high_lane_s32(a, v, 1);
   // CHECK: smull2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
 }
 
 uint32x4_t test_vmull_high_lane_u16(uint16x8_t a, uint16x4_t v) {
-  // CHECK: test_vmull_high_lane_u16
-  return vmull_high_lane_u16(a, v, 1);
-  // CHECK: umull2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmull_high_lane_u16
+  return vmull_high_lane_u16(a, v, 3);
+  // CHECK: umull2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[3]
 }
 
 uint64x2_t test_vmull_high_lane_u32(uint32x4_t a, uint32x2_t v) {
-  // CHECK: test_vmull_high_lane_u32
+  // CHECK-LABEL: test_vmull_high_lane_u32
   return vmull_high_lane_u32(a, v, 1);
   // CHECK: umull2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
 }
 
 int32x4_t test_vmull_laneq_s16(int16x4_t a, int16x8_t v) {
-  // CHECK: test_vmull_laneq_s16
-  return vmull_laneq_s16(a, v, 1);
-  // CHECK: smull {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmull_laneq_s16
+  return vmull_laneq_s16(a, v, 7);
+  // CHECK: smull {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[7]
 }
 
 int64x2_t test_vmull_laneq_s32(int32x2_t a, int32x4_t v) {
-  // CHECK: test_vmull_laneq_s32
-  return vmull_laneq_s32(a, v, 1);
-  // CHECK: smull {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
+  // CHECK-LABEL: test_vmull_laneq_s32
+  return vmull_laneq_s32(a, v, 3);
+  // CHECK: smull {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[3]
 }
 
 uint32x4_t test_vmull_laneq_u16(uint16x4_t a, uint16x8_t v) {
-  // CHECK: test_vmull_laneq_u16
-  return vmull_laneq_u16(a, v, 1);
-  // CHECK: umull {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmull_laneq_u16
+  return vmull_laneq_u16(a, v, 7);
+  // CHECK: umull {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[7]
 }
 
 uint64x2_t test_vmull_laneq_u32(uint32x2_t a, uint32x4_t v) {
-  // CHECK: test_vmull_laneq_u32
-  return vmull_laneq_u32(a, v, 1);
-  // CHECK: umull {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
+  // CHECK-LABEL: test_vmull_laneq_u32
+  return vmull_laneq_u32(a, v, 3);
+  // CHECK: umull {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[3]
 }
 
 int32x4_t test_vmull_high_laneq_s16(int16x8_t a, int16x8_t v) {
-  // CHECK: test_vmull_high_laneq_s16
-  return vmull_high_laneq_s16(a, v, 1);
-  // CHECK: smull2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmull_high_laneq_s16
+  return vmull_high_laneq_s16(a, v, 7);
+  // CHECK: smull2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[7]
 }
 
 int64x2_t test_vmull_high_laneq_s32(int32x4_t a, int32x4_t v) {
-  // CHECK: test_vmull_high_laneq_s32
-  return vmull_high_laneq_s32(a, v, 1);
-  // CHECK: smull2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
+  // CHECK-LABEL: test_vmull_high_laneq_s32
+  return vmull_high_laneq_s32(a, v, 3);
+  // CHECK: smull2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[3]
 }
 
 uint32x4_t test_vmull_high_laneq_u16(uint16x8_t a, uint16x8_t v) {
-  // CHECK: test_vmull_high_laneq_u16
-  return vmull_high_laneq_u16(a, v, 1);
-  // CHECK: umull2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vmull_high_laneq_u16
+  return vmull_high_laneq_u16(a, v, 7);
+  // CHECK: umull2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[7]
 }
 
 uint64x2_t test_vmull_high_laneq_u32(uint32x4_t a, uint32x4_t v) {
-  // CHECK: test_vmull_high_laneq_u32
-  return vmull_high_laneq_u32(a, v, 1);
-  // CHECK: umull2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
+  // CHECK-LABEL: test_vmull_high_laneq_u32
+  return vmull_high_laneq_u32(a, v, 3);
+  // CHECK: umull2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[3]
 }
 
 int32x4_t test_vqdmlal_lane_s16(int32x4_t a, int16x4_t b, int16x4_t v) {
-  // CHECK: test_vqdmlal_lane_s16
-  return vqdmlal_lane_s16(a, b, v, 1);
-  // CHECK: sqdmlal {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vqdmlal_lane_s16
+  return vqdmlal_lane_s16(a, b, v, 3);
+  // CHECK: sqdmlal {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[3]
 }
 
 int64x2_t test_vqdmlal_lane_s32(int64x2_t a, int32x2_t b, int32x2_t v) {
-  // CHECK: test_vqdmlal_lane_s32
+  // CHECK-LABEL: test_vqdmlal_lane_s32
   return vqdmlal_lane_s32(a, b, v, 1);
   // CHECK: sqdmlal {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
 }
 
 int32x4_t test_vqdmlal_high_lane_s16(int32x4_t a, int16x8_t b, int16x4_t v) {
-  // CHECK: test_vqdmlal_high_lane_s16
-  return vqdmlal_high_lane_s16(a, b, v, 1);
-  // CHECK: sqdmlal2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vqdmlal_high_lane_s16
+  return vqdmlal_high_lane_s16(a, b, v, 3);
+  // CHECK: sqdmlal2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[3]
 }
 
 int64x2_t test_vqdmlal_high_lane_s32(int64x2_t a, int32x4_t b, int32x2_t v) {
-  // CHECK: test_vqdmlal_high_lane_s32
+  // CHECK-LABEL: test_vqdmlal_high_lane_s32
   return vqdmlal_high_lane_s32(a, b, v, 1);
   // CHECK: sqdmlal2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
 }
 
 int32x4_t test_vqdmlsl_lane_s16(int32x4_t a, int16x4_t b, int16x4_t v) {
-  // CHECK: test_vqdmlsl_lane_s16
-  return vqdmlsl_lane_s16(a, b, v, 1);
-  // CHECK: sqdmlsl {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vqdmlsl_lane_s16
+  return vqdmlsl_lane_s16(a, b, v, 3);
+  // CHECK: sqdmlsl {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[3]
 }
 
 int64x2_t test_vqdmlsl_lane_s32(int64x2_t a, int32x2_t b, int32x2_t v) {
-  // CHECK: test_vqdmlsl_lane_s32
+  // CHECK-LABEL: test_vqdmlsl_lane_s32
   return vqdmlsl_lane_s32(a, b, v, 1);
   // CHECK: sqdmlsl {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
 }
 
 int32x4_t test_vqdmlsl_high_lane_s16(int32x4_t a, int16x8_t b, int16x4_t v) {
-  // CHECK: test_vqdmlsl_high_lane_s16
-  return vqdmlsl_high_lane_s16(a, b, v, 1);
-  // CHECK: sqdmlsl2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vqdmlsl_high_lane_s16
+  return vqdmlsl_high_lane_s16(a, b, v, 3);
+  // CHECK: sqdmlsl2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[3]
 }
 
 int64x2_t test_vqdmlsl_high_lane_s32(int64x2_t a, int32x4_t b, int32x2_t v) {
-  // CHECK: test_vqdmlsl_high_lane_s32
+  // CHECK-LABEL: test_vqdmlsl_high_lane_s32
   return vqdmlsl_high_lane_s32(a, b, v, 1);
   // CHECK: sqdmlsl2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
 }
 
 int32x4_t test_vqdmull_lane_s16(int16x4_t a, int16x4_t v) {
-  // CHECK: test_vqdmull_lane_s16
-  return vqdmull_lane_s16(a, v, 1);
-  // CHECK: sqdmull {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vqdmull_lane_s16
+  return vqdmull_lane_s16(a, v, 3);
+  // CHECK: sqdmull {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[3]
 }
 
 int64x2_t test_vqdmull_lane_s32(int32x2_t a, int32x2_t v) {
-  // CHECK: test_vqdmull_lane_s32
+  // CHECK-LABEL: test_vqdmull_lane_s32
   return vqdmull_lane_s32(a, v, 1);
   // CHECK: sqdmull {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
 }
 
 int32x4_t test_vqdmull_laneq_s16(int16x4_t a, int16x8_t v) {
-  // CHECK: test_vqdmull_laneq_s16
-  return vqdmull_laneq_s16(a, v, 1);
-  // CHECK: sqdmull {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vqdmull_laneq_s16
+  return vqdmull_laneq_s16(a, v, 3);
+  // CHECK: sqdmull {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[3]
 }
 
 int64x2_t test_vqdmull_laneq_s32(int32x2_t a, int32x4_t v) {
-  // CHECK: test_vqdmull_laneq_s32
-  return vqdmull_laneq_s32(a, v, 1);
-  // CHECK: sqdmull {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
+  // CHECK-LABEL: test_vqdmull_laneq_s32
+  return vqdmull_laneq_s32(a, v, 3);
+  // CHECK: sqdmull {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[3]
 }
 
 int32x4_t test_vqdmull_high_lane_s16(int16x8_t a, int16x4_t v) {
-  // CHECK: test_vqdmull_high_lane_s16
-  return vqdmull_high_lane_s16(a, v, 1);
-  // CHECK: sqdmull2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vqdmull_high_lane_s16
+  return vqdmull_high_lane_s16(a, v, 3);
+  // CHECK: sqdmull2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[3]
 }
 
 int64x2_t test_vqdmull_high_lane_s32(int32x4_t a, int32x2_t v) {
-  // CHECK: test_vqdmull_high_lane_s32
+  // CHECK-LABEL: test_vqdmull_high_lane_s32
   return vqdmull_high_lane_s32(a, v, 1);
   // CHECK: sqdmull2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
 }
 
 int32x4_t test_vqdmull_high_laneq_s16(int16x8_t a, int16x8_t v) {
-  // CHECK: test_vqdmull_high_laneq_s16
-  return vqdmull_high_laneq_s16(a, v, 1);
-  // CHECK: sqdmull2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vqdmull_high_laneq_s16
+  return vqdmull_high_laneq_s16(a, v, 7);
+  // CHECK: sqdmull2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[7]
 }
 
 int64x2_t test_vqdmull_high_laneq_s32(int32x4_t a, int32x4_t v) {
-  // CHECK: test_vqdmull_high_laneq_s32
-  return vqdmull_high_laneq_s32(a, v, 1);
-  // CHECK: sqdmull2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
+  // CHECK-LABEL: test_vqdmull_high_laneq_s32
+  return vqdmull_high_laneq_s32(a, v, 3);
+  // CHECK: sqdmull2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[3]
 }
 
 int16x4_t test_vqdmulh_lane_s16(int16x4_t a, int16x4_t v) {
-  // CHECK: test_vqdmulh_lane_s16
-  return vqdmulh_lane_s16(a, v, 1);
-  // CHECK: sqdmulh {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vqdmulh_lane_s16
+  return vqdmulh_lane_s16(a, v, 3);
+  // CHECK: sqdmulh {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[3]
 }
 
 int16x8_t test_vqdmulhq_lane_s16(int16x8_t a, int16x4_t v) {
-  // CHECK: test_vqdmulhq_lane_s16
-  return vqdmulhq_lane_s16(a, v, 1);
-  // CHECK: sqdmulh {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vqdmulhq_lane_s16
+  return vqdmulhq_lane_s16(a, v, 3);
+  // CHECK: sqdmulh {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[3]
 }
 
 int32x2_t test_vqdmulh_lane_s32(int32x2_t a, int32x2_t v) {
-  // CHECK: test_vqdmulh_lane_s32
+  // CHECK-LABEL: test_vqdmulh_lane_s32
   return vqdmulh_lane_s32(a, v, 1);
   // CHECK: sqdmulh {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
 }
 
 int32x4_t test_vqdmulhq_lane_s32(int32x4_t a, int32x2_t v) {
-  // CHECK: test_vqdmulhq_lane_s32
+  // CHECK-LABEL: test_vqdmulhq_lane_s32
   return vqdmulhq_lane_s32(a, v, 1);
   // CHECK: sqdmulh {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
 }
 
 int16x4_t test_vqrdmulh_lane_s16(int16x4_t a, int16x4_t v) {
-  // CHECK: test_vqrdmulh_lane_s16
-  return vqrdmulh_lane_s16(a, v, 1);
-  // CHECK: sqrdmulh {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vqrdmulh_lane_s16
+  return vqrdmulh_lane_s16(a, v, 3);
+  // CHECK: sqrdmulh {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[3]
 }
 
 int16x8_t test_vqrdmulhq_lane_s16(int16x8_t a, int16x4_t v) {
-  // CHECK: test_vqrdmulhq_lane_s16
-  return vqrdmulhq_lane_s16(a, v, 1);
-  // CHECK: sqrdmulh {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[1]
+  // CHECK-LABEL: test_vqrdmulhq_lane_s16
+  return vqrdmulhq_lane_s16(a, v, 3);
+  // CHECK: sqrdmulh {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[3]
 }
 
 int32x2_t test_vqrdmulh_lane_s32(int32x2_t a, int32x2_t v) {
-  // CHECK: test_vqrdmulh_lane_s32
+  // CHECK-LABEL: test_vqrdmulh_lane_s32
   return vqrdmulh_lane_s32(a, v, 1);
   // CHECK: sqrdmulh {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
 }
 
 int32x4_t test_vqrdmulhq_lane_s32(int32x4_t a, int32x2_t v) {
-  // CHECK: test_vqrdmulhq_lane_s32
+  // CHECK-LABEL: test_vqrdmulhq_lane_s32
   return vqrdmulhq_lane_s32(a, v, 1);
   // CHECK: sqrdmulh {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
 }
 
 float32x2_t test_vmul_lane_f32(float32x2_t a, float32x2_t v) {
-  // CHECK: test_vmul_lane_f32
+  // CHECK-LABEL: test_vmul_lane_f32
   return vmul_lane_f32(a, v, 1);
   // CHECK: fmul {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
 }
 
 
 float64x1_t test_vmul_lane_f64(float64x1_t a, float64x1_t v) {
-  // CHECK: test_vmul_lane_f64
+  // CHECK-LABEL: test_vmul_lane_f64
   return vmul_lane_f64(a, v, 0);
-  // CHECK: fmul {{d[0-9]+}}, {{d[0-9]+}}, {{v[0-9]+}}.d[0]
+  // CHECK: fmul {{d[0-9]+}}, {{d[0-9]+}}, {{v[0-9]+\.d\[0\]|d[0-9]+}}
 }
 
 
 float32x4_t test_vmulq_lane_f32(float32x4_t a, float32x2_t v) {
-  // CHECK: test_vmulq_lane_f32
+  // CHECK-LABEL: test_vmulq_lane_f32
   return vmulq_lane_f32(a, v, 1);
   // CHECK: fmul {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
 }
 
 float64x2_t test_vmulq_lane_f64(float64x2_t a, float64x1_t v) {
-  // CHECK: test_vmulq_lane_f64
+  // CHECK-LABEL: test_vmulq_lane_f64
   return vmulq_lane_f64(a, v, 0);
   // CHECK: fmul {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.d[0]
 }
 
 float32x2_t test_vmul_laneq_f32(float32x2_t a, float32x4_t v) {
-  // CHECK: test_vmul_laneq_f32
-  return vmul_laneq_f32(a, v, 1);
-  // CHECK: fmul {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
+  // CHECK-LABEL: test_vmul_laneq_f32
+  return vmul_laneq_f32(a, v, 3);
+  // CHECK: fmul {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[3]
 }
 
-float64x1_t test_vmul_laneq_f64_0(float64x1_t a, float64x2_t v) {
-  // CHECK: test_vmul_laneq_f64_0
-  return vmul_laneq_f64(a, v, 0);
-  // CHECK: fmul {{d[0-9]+}}, {{d[0-9]+}}, {{v[0-9]+}}.d[0]
+float64x1_t test_vmul_laneq_f64(float64x1_t a, float64x2_t v) {
+  // CHECK-LABEL: test_vmul_laneq_f64
+  return vmul_laneq_f64(a, v, 1);
+  // CHECK: fmul {{d[0-9]+}}, {{d[0-9]+}}, {{v[0-9]+}}.d[1]
 }
 
 
 float32x4_t test_vmulq_laneq_f32(float32x4_t a, float32x4_t v) {
-  // CHECK: test_vmulq_laneq_f32
-  return vmulq_laneq_f32(a, v, 1);
-  // CHECK: fmul {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
-}
-
-float64x2_t test_vmulq_laneq_f64_0(float64x2_t a, float64x2_t v) {
-  // CHECK: test_vmulq_laneq_f64
-  return vmulq_laneq_f64(a, v, 0);
-  // CHECK: fmul {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.d[0]
+  // CHECK-LABEL: test_vmulq_laneq_f32
+  return vmulq_laneq_f32(a, v, 3);
+  // CHECK: fmul {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[3]
 }
 
 float64x2_t test_vmulq_laneq_f64(float64x2_t a, float64x2_t v) {
-  // CHECK: test_vmulq_laneq_f64
+  // CHECK-LABEL: test_vmulq_laneq_f64
   return vmulq_laneq_f64(a, v, 1);
   // CHECK: fmul {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.d[1]
 }
 
 float32x2_t test_vmulx_lane_f32(float32x2_t a, float32x2_t v) {
-  // CHECK: test_vmulx_lane_f32
+  // CHECK-LABEL: test_vmulx_lane_f32
   return vmulx_lane_f32(a, v, 1);
   // CHECK: fmulx {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
 }
 
 float32x4_t test_vmulxq_lane_f32(float32x4_t a, float32x2_t v) {
-  // CHECK: test_vmulxq_lane_f32
+  // CHECK-LABEL: test_vmulxq_lane_f32
   return vmulxq_lane_f32(a, v, 1);
   // CHECK: fmulx {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
 }
 
 float64x2_t test_vmulxq_lane_f64(float64x2_t a, float64x1_t v) {
-  // CHECK: test_vmulxq_lane_f64
+  // CHECK-LABEL: test_vmulxq_lane_f64
   return vmulxq_lane_f64(a, v, 0);
   // CHECK: fmulx {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.d[0]
 }
 
 float32x2_t test_vmulx_laneq_f32(float32x2_t a, float32x4_t v) {
-  // CHECK: test_vmulx_laneq_f32
-  return vmulx_laneq_f32(a, v, 1);
-  // CHECK: fmulx {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
+  // CHECK-LABEL: test_vmulx_laneq_f32
+  return vmulx_laneq_f32(a, v, 3);
+  // CHECK: fmulx {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[3]
 }
 
 float32x4_t test_vmulxq_laneq_f32(float32x4_t a, float32x4_t v) {
-  // CHECK: test_vmulxq_laneq_f32
-  return vmulxq_laneq_f32(a, v, 1);
-  // CHECK: fmulx {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
+  // CHECK-LABEL: test_vmulxq_laneq_f32
+  return vmulxq_laneq_f32(a, v, 3);
+  // CHECK: fmulx {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[3]
+}
+
+float64x2_t test_vmulxq_laneq_f64(float64x2_t a, float64x2_t v) {
+  // CHECK-LABEL: test_vmulxq_laneq_f64
+  return vmulxq_laneq_f64(a, v, 1);
+  // CHECK: fmulx {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.d[1]
+}
+
+int16x4_t test_vmla_lane_s16_0(int16x4_t a, int16x4_t b, int16x4_t v) {
+  // CHECK-LABEL: test_vmla_lane_s16_0
+  return vmla_lane_s16(a, b, v, 0);
+  // CHECK: mla {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[0]
+}
+
+int16x8_t test_vmlaq_lane_s16_0(int16x8_t a, int16x8_t b, int16x4_t v) {
+  // CHECK-LABEL: test_vmlaq_lane_s16_0
+  return vmlaq_lane_s16(a, b, v, 0);
+  // CHECK: mla {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[0]
+}
+
+int32x2_t test_vmla_lane_s32_0(int32x2_t a, int32x2_t b, int32x2_t v) {
+  // CHECK-LABEL: test_vmla_lane_s32_0
+  return vmla_lane_s32(a, b, v, 0);
+  // CHECK: mla {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vmlaq_lane_s32_0(int32x4_t a, int32x4_t b, int32x2_t v) {
+  // CHECK-LABEL: test_vmlaq_lane_s32_0
+  return vmlaq_lane_s32(a, b, v, 0);
+  // CHECK: mla {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+int16x4_t test_vmla_laneq_s16_0(int16x4_t a, int16x4_t b, int16x8_t v) {
+  // CHECK-LABEL: test_vmla_laneq_s16_0
+  return vmla_laneq_s16(a, b, v, 0);
+  // CHECK: mla {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[0]
+}
+
+int16x8_t test_vmlaq_laneq_s16_0(int16x8_t a, int16x8_t b, int16x8_t v) {
+  // CHECK-LABEL: test_vmlaq_laneq_s16_0
+  return vmlaq_laneq_s16(a, b, v, 0);
+  // CHECK: mla {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[0]
+}
+
+int32x2_t test_vmla_laneq_s32_0(int32x2_t a, int32x2_t b, int32x4_t v) {
+  // CHECK-LABEL: test_vmla_laneq_s32_0
+  return vmla_laneq_s32(a, b, v, 0);
+  // CHECK: mla {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vmlaq_laneq_s32_0(int32x4_t a, int32x4_t b, int32x4_t v) {
+  // CHECK-LABEL: test_vmlaq_laneq_s32_0
+  return vmlaq_laneq_s32(a, b, v, 0);
+  // CHECK: mla {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+int16x4_t test_vmls_lane_s16_0(int16x4_t a, int16x4_t b, int16x4_t v) {
+  // CHECK-LABEL: test_vmls_lane_s16_0
+  return vmls_lane_s16(a, b, v, 0);
+  // CHECK: mls {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[0]
+}
+
+int16x8_t test_vmlsq_lane_s16_0(int16x8_t a, int16x8_t b, int16x4_t v) {
+  // CHECK-LABEL: test_vmlsq_lane_s16_0
+  return vmlsq_lane_s16(a, b, v, 0);
+  // CHECK: mls {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[0]
+}
+
+int32x2_t test_vmls_lane_s32_0(int32x2_t a, int32x2_t b, int32x2_t v) {
+  // CHECK-LABEL: test_vmls_lane_s32_0
+  return vmls_lane_s32(a, b, v, 0);
+  // CHECK: mls {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vmlsq_lane_s32_0(int32x4_t a, int32x4_t b, int32x2_t v) {
+  // CHECK-LABEL: test_vmlsq_lane_s32_0
+  return vmlsq_lane_s32(a, b, v, 0);
+  // CHECK: mls {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+int16x4_t test_vmls_laneq_s16_0(int16x4_t a, int16x4_t b, int16x8_t v) {
+  // CHECK-LABEL: test_vmls_laneq_s16_0
+  return vmls_laneq_s16(a, b, v, 0);
+  // CHECK: mls {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[0]
+}
+
+int16x8_t test_vmlsq_laneq_s16_0(int16x8_t a, int16x8_t b, int16x8_t v) {
+  // CHECK-LABEL: test_vmlsq_laneq_s16_0
+  return vmlsq_laneq_s16(a, b, v, 0);
+  // CHECK: mls {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[0]
+}
+
+int32x2_t test_vmls_laneq_s32_0(int32x2_t a, int32x2_t b, int32x4_t v) {
+  // CHECK-LABEL: test_vmls_laneq_s32_0
+  return vmls_laneq_s32(a, b, v, 0);
+  // CHECK: mls {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vmlsq_laneq_s32_0(int32x4_t a, int32x4_t b, int32x4_t v) {
+  // CHECK-LABEL: test_vmlsq_laneq_s32_0
+  return vmlsq_laneq_s32(a, b, v, 0);
+  // CHECK: mls {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+int16x4_t test_vmul_lane_s16_0(int16x4_t a, int16x4_t v) {
+  // CHECK-LABEL: test_vmul_lane_s16_0
+  return vmul_lane_s16(a, v, 0);
+  // CHECK: mul {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[0]
+}
+
+int16x8_t test_vmulq_lane_s16_0(int16x8_t a, int16x4_t v) {
+  // CHECK-LABEL: test_vmulq_lane_s16_0
+  return vmulq_lane_s16(a, v, 0);
+  // CHECK: mul {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[0]
+}
+
+int32x2_t test_vmul_lane_s32_0(int32x2_t a, int32x2_t v) {
+  // CHECK-LABEL: test_vmul_lane_s32_0
+  return vmul_lane_s32(a, v, 0);
+  // CHECK: mul {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vmulq_lane_s32_0(int32x4_t a, int32x2_t v) {
+  // CHECK-LABEL: test_vmulq_lane_s32_0
+  return vmulq_lane_s32(a, v, 0);
+  // CHECK: mul {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+uint16x4_t test_vmul_lane_u16_0(uint16x4_t a, uint16x4_t v) {
+  // CHECK-LABEL: test_vmul_lane_u16_0
+  return vmul_lane_u16(a, v, 0);
+  // CHECK: mul {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[0]
+}
+
+uint16x8_t test_vmulq_lane_u16_0(uint16x8_t a, uint16x4_t v) {
+  // CHECK-LABEL: test_vmulq_lane_u16_0
+  return vmulq_lane_u16(a, v, 0);
+  // CHECK: mul {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[0]
+}
+
+uint32x2_t test_vmul_lane_u32_0(uint32x2_t a, uint32x2_t v) {
+  // CHECK-LABEL: test_vmul_lane_u32_0
+  return vmul_lane_u32(a, v, 0);
+  // CHECK: mul {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+uint32x4_t test_vmulq_lane_u32_0(uint32x4_t a, uint32x2_t v) {
+  // CHECK-LABEL: test_vmulq_lane_u32_0
+  return vmulq_lane_u32(a, v, 0);
+  // CHECK: mul {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+int16x4_t test_vmul_laneq_s16_0(int16x4_t a, int16x8_t v) {
+  // CHECK-LABEL: test_vmul_laneq_s16_0
+  return vmul_laneq_s16(a, v, 0);
+  // CHECK: mul {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[0]
+}
+
+int16x8_t test_vmulq_laneq_s16_0(int16x8_t a, int16x8_t v) {
+  // CHECK-LABEL: test_vmulq_laneq_s16_0
+  return vmulq_laneq_s16(a, v, 0);
+  // CHECK: mul {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[0]
+}
+
+int32x2_t test_vmul_laneq_s32_0(int32x2_t a, int32x4_t v) {
+  // CHECK-LABEL: test_vmul_laneq_s32_0
+  return vmul_laneq_s32(a, v, 0);
+  // CHECK: mul {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vmulq_laneq_s32_0(int32x4_t a, int32x4_t v) {
+  // CHECK-LABEL: test_vmulq_laneq_s32_0
+  return vmulq_laneq_s32(a, v, 0);
+  // CHECK: mul {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+uint16x4_t test_vmul_laneq_u16_0(uint16x4_t a, uint16x8_t v) {
+  // CHECK-LABEL: test_vmul_laneq_u16_0
+  return vmul_laneq_u16(a, v, 0);
+  // CHECK: mul {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[0]
+}
+
+uint16x8_t test_vmulq_laneq_u16_0(uint16x8_t a, uint16x8_t v) {
+  // CHECK-LABEL: test_vmulq_laneq_u16_0
+  return vmulq_laneq_u16(a, v, 0);
+  // CHECK: mul {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[0]
+}
+
+uint32x2_t test_vmul_laneq_u32_0(uint32x2_t a, uint32x4_t v) {
+  // CHECK-LABEL: test_vmul_laneq_u32_0
+  return vmul_laneq_u32(a, v, 0);
+  // CHECK: mul {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+uint32x4_t test_vmulq_laneq_u32_0(uint32x4_t a, uint32x4_t v) {
+  // CHECK-LABEL: test_vmulq_laneq_u32_0
+  return vmulq_laneq_u32(a, v, 0);
+  // CHECK: mul {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+float32x2_t test_vfma_lane_f32_0(float32x2_t a, float32x2_t b, float32x2_t v) {
+  // CHECK-LABEL: test_vfma_lane_f32_0
+  return vfma_lane_f32(a, b, v, 0);
+  // CHECK: fmla {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+float32x4_t test_vfmaq_lane_f32_0(float32x4_t a, float32x4_t b, float32x2_t v) {
+  // CHECK-LABEL: test_vfmaq_lane_f32_0
+  return vfmaq_lane_f32(a, b, v, 0);
+  // CHECK: fmla {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+float32x2_t test_vfma_laneq_f32_0(float32x2_t a, float32x2_t b, float32x4_t v) {
+  // CHECK-LABEL: test_vfma_laneq_f32_0
+  return vfma_laneq_f32(a, b, v, 0);
+  // CHECK: fmla {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+float32x4_t test_vfmaq_laneq_f32_0(float32x4_t a, float32x4_t b, float32x4_t v) {
+  // CHECK-LABEL: test_vfmaq_laneq_f32_0
+  return vfmaq_laneq_f32(a, b, v, 0);
+  // CHECK: fmla {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+float32x2_t test_vfms_lane_f32_0(float32x2_t a, float32x2_t b, float32x2_t v) {
+  // CHECK-LABEL: test_vfms_lane_f32_0
+  return vfms_lane_f32(a, b, v, 0);
+  // CHECK: fmls {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+float32x4_t test_vfmsq_lane_f32_0(float32x4_t a, float32x4_t b, float32x2_t v) {
+  // CHECK-LABEL: test_vfmsq_lane_f32_0
+  return vfmsq_lane_f32(a, b, v, 0);
+  // CHECK: fmls {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+float32x2_t test_vfms_laneq_f32_0(float32x2_t a, float32x2_t b, float32x4_t v) {
+  // CHECK-LABEL: test_vfms_laneq_f32_0
+  return vfms_laneq_f32(a, b, v, 0);
+  // CHECK: fmls {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+float32x4_t test_vfmsq_laneq_f32_0(float32x4_t a, float32x4_t b, float32x4_t v) {
+  // CHECK-LABEL: test_vfmsq_laneq_f32_0
+  return vfmsq_laneq_f32(a, b, v, 0);
+  // CHECK: fmls {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+float64x2_t test_vfmaq_laneq_f64_0(float64x2_t a, float64x2_t b, float64x2_t v) {
+  // CHECK-LABEL: test_vfmaq_laneq_f64_0
+  return vfmaq_laneq_f64(a, b, v, 0);
+  // CHECK: fmla {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.d[0]
+}
+
+float64x2_t test_vfmsq_laneq_f64_0(float64x2_t a, float64x2_t b, float64x2_t v) {
+  // CHECK-LABEL: test_vfmsq_laneq_f64_0
+  return vfmsq_laneq_f64(a, b, v, 0);
+  // CHECK: fmls {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.d[0]
+}
+
+int32x4_t test_vmlal_lane_s16_0(int32x4_t a, int16x4_t b, int16x4_t v) {
+  // CHECK-LABEL: test_vmlal_lane_s16_0
+  return vmlal_lane_s16(a, b, v, 0);
+  // CHECK: smlal {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[0]
+}
+
+int64x2_t test_vmlal_lane_s32_0(int64x2_t a, int32x2_t b, int32x2_t v) {
+  // CHECK-LABEL: test_vmlal_lane_s32_0
+  return vmlal_lane_s32(a, b, v, 0);
+  // CHECK: smlal {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vmlal_laneq_s16_0(int32x4_t a, int16x4_t b, int16x8_t v) {
+  // CHECK-LABEL: test_vmlal_laneq_s16_0
+  return vmlal_laneq_s16(a, b, v, 0);
+  // CHECK: smlal {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[0]
+}
+
+int64x2_t test_vmlal_laneq_s32_0(int64x2_t a, int32x2_t b, int32x4_t v) {
+  // CHECK-LABEL: test_vmlal_laneq_s32_0
+  return vmlal_laneq_s32(a, b, v, 0);
+  // CHECK: smlal {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vmlal_high_lane_s16_0(int32x4_t a, int16x8_t b, int16x4_t v) {
+  // CHECK-LABEL: test_vmlal_high_lane_s16_0
+  return vmlal_high_lane_s16(a, b, v, 0);
+  // CHECK: smlal2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[0]
+}
+
+int64x2_t test_vmlal_high_lane_s32_0(int64x2_t a, int32x4_t b, int32x2_t v) {
+  // CHECK-LABEL: test_vmlal_high_lane_s32_0
+  return vmlal_high_lane_s32(a, b, v, 0);
+  // CHECK: smlal2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vmlal_high_laneq_s16_0(int32x4_t a, int16x8_t b, int16x8_t v) {
+  // CHECK-LABEL: test_vmlal_high_laneq_s16_0
+  return vmlal_high_laneq_s16(a, b, v, 0);
+  // CHECK: smlal2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[0]
+}
+
+int64x2_t test_vmlal_high_laneq_s32_0(int64x2_t a, int32x4_t b, int32x4_t v) {
+  // CHECK-LABEL: test_vmlal_high_laneq_s32_0
+  return vmlal_high_laneq_s32(a, b, v, 0);
+  // CHECK: smlal2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vmlsl_lane_s16_0(int32x4_t a, int16x4_t b, int16x4_t v) {
+  // CHECK-LABEL: test_vmlsl_lane_s16_0
+  return vmlsl_lane_s16(a, b, v, 0);
+  // CHECK: smlsl {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[0]
+}
+
+int64x2_t test_vmlsl_lane_s32_0(int64x2_t a, int32x2_t b, int32x2_t v) {
+  // CHECK-LABEL: test_vmlsl_lane_s32_0
+  return vmlsl_lane_s32(a, b, v, 0);
+  // CHECK: smlsl {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vmlsl_laneq_s16_0(int32x4_t a, int16x4_t b, int16x8_t v) {
+  // CHECK-LABEL: test_vmlsl_laneq_s16_0
+  return vmlsl_laneq_s16(a, b, v, 0);
+  // CHECK: smlsl {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[0]
+}
+
+int64x2_t test_vmlsl_laneq_s32_0(int64x2_t a, int32x2_t b, int32x4_t v) {
+  // CHECK-LABEL: test_vmlsl_laneq_s32_0
+  return vmlsl_laneq_s32(a, b, v, 0);
+  // CHECK: smlsl {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vmlsl_high_lane_s16_0(int32x4_t a, int16x8_t b, int16x4_t v) {
+  // CHECK-LABEL: test_vmlsl_high_lane_s16_0
+  return vmlsl_high_lane_s16(a, b, v, 0);
+  // CHECK: smlsl2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[0]
+}
+
+int64x2_t test_vmlsl_high_lane_s32_0(int64x2_t a, int32x4_t b, int32x2_t v) {
+  // CHECK-LABEL: test_vmlsl_high_lane_s32_0
+  return vmlsl_high_lane_s32(a, b, v, 0);
+  // CHECK: smlsl2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vmlsl_high_laneq_s16_0(int32x4_t a, int16x8_t b, int16x8_t v) {
+  // CHECK-LABEL: test_vmlsl_high_laneq_s16_0
+  return vmlsl_high_laneq_s16(a, b, v, 0);
+  // CHECK: smlsl2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[0]
+}
+
+int64x2_t test_vmlsl_high_laneq_s32_0(int64x2_t a, int32x4_t b, int32x4_t v) {
+  // CHECK-LABEL: test_vmlsl_high_laneq_s32_0
+  return vmlsl_high_laneq_s32(a, b, v, 0);
+  // CHECK: smlsl2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vmlal_lane_u16_0(int32x4_t a, int16x4_t b, int16x4_t v) {
+  // CHECK-LABEL: test_vmlal_lane_u16_0
+  return vmlal_lane_u16(a, b, v, 0);
+  // CHECK: umlal {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[0]
+}
+
+int64x2_t test_vmlal_lane_u32_0(int64x2_t a, int32x2_t b, int32x2_t v) {
+  // CHECK-LABEL: test_vmlal_lane_u32_0
+  return vmlal_lane_u32(a, b, v, 0);
+  // CHECK: umlal {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vmlal_laneq_u16_0(int32x4_t a, int16x4_t b, int16x8_t v) {
+  // CHECK-LABEL: test_vmlal_laneq_u16_0
+  return vmlal_laneq_u16(a, b, v, 0);
+  // CHECK: umlal {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[0]
+}
+
+int64x2_t test_vmlal_laneq_u32_0(int64x2_t a, int32x2_t b, int32x4_t v) {
+  // CHECK-LABEL: test_vmlal_laneq_u32_0
+  return vmlal_laneq_u32(a, b, v, 0);
+  // CHECK: umlal {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vmlal_high_lane_u16_0(int32x4_t a, int16x8_t b, int16x4_t v) {
+  // CHECK-LABEL: test_vmlal_high_lane_u16_0
+  return vmlal_high_lane_u16(a, b, v, 0);
+  // CHECK: umlal2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[0]
+}
+
+int64x2_t test_vmlal_high_lane_u32_0(int64x2_t a, int32x4_t b, int32x2_t v) {
+  // CHECK-LABEL: test_vmlal_high_lane_u32_0
+  return vmlal_high_lane_u32(a, b, v, 0);
+  // CHECK: umlal2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vmlal_high_laneq_u16_0(int32x4_t a, int16x8_t b, int16x8_t v) {
+  // CHECK-LABEL: test_vmlal_high_laneq_u16_0
+  return vmlal_high_laneq_u16(a, b, v, 0);
+  // CHECK: umlal2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[0]
+}
+
+int64x2_t test_vmlal_high_laneq_u32_0(int64x2_t a, int32x4_t b, int32x4_t v) {
+  // CHECK-LABEL: test_vmlal_high_laneq_u32_0
+  return vmlal_high_laneq_u32(a, b, v, 0);
+  // CHECK: umlal2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vmlsl_lane_u16_0(int32x4_t a, int16x4_t b, int16x4_t v) {
+  // CHECK-LABEL: test_vmlsl_lane_u16_0
+  return vmlsl_lane_u16(a, b, v, 0);
+  // CHECK: umlsl {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[0]
+}
+
+int64x2_t test_vmlsl_lane_u32_0(int64x2_t a, int32x2_t b, int32x2_t v) {
+  // CHECK-LABEL: test_vmlsl_lane_u32_0
+  return vmlsl_lane_u32(a, b, v, 0);
+  // CHECK: umlsl {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vmlsl_laneq_u16_0(int32x4_t a, int16x4_t b, int16x8_t v) {
+  // CHECK-LABEL: test_vmlsl_laneq_u16_0
+  return vmlsl_laneq_u16(a, b, v, 0);
+  // CHECK: umlsl {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[0]
+}
+
+int64x2_t test_vmlsl_laneq_u32_0(int64x2_t a, int32x2_t b, int32x4_t v) {
+  // CHECK-LABEL: test_vmlsl_laneq_u32_0
+  return vmlsl_laneq_u32(a, b, v, 0);
+  // CHECK: umlsl {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vmlsl_high_lane_u16_0(int32x4_t a, int16x8_t b, int16x4_t v) {
+  // CHECK-LABEL: test_vmlsl_high_lane_u16_0
+  return vmlsl_high_lane_u16(a, b, v, 0);
+  // CHECK: umlsl2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[0]
+}
+
+int64x2_t test_vmlsl_high_lane_u32_0(int64x2_t a, int32x4_t b, int32x2_t v) {
+  // CHECK-LABEL: test_vmlsl_high_lane_u32_0
+  return vmlsl_high_lane_u32(a, b, v, 0);
+  // CHECK: umlsl2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vmlsl_high_laneq_u16_0(int32x4_t a, int16x8_t b, int16x8_t v) {
+  // CHECK-LABEL: test_vmlsl_high_laneq_u16_0
+  return vmlsl_high_laneq_u16(a, b, v, 0);
+  // CHECK: umlsl2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[0]
+}
+
+int64x2_t test_vmlsl_high_laneq_u32_0(int64x2_t a, int32x4_t b, int32x4_t v) {
+  // CHECK-LABEL: test_vmlsl_high_laneq_u32_0
+  return vmlsl_high_laneq_u32(a, b, v, 0);
+  // CHECK: umlsl2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vmull_lane_s16_0(int16x4_t a, int16x4_t v) {
+  // CHECK-LABEL: test_vmull_lane_s16_0
+  return vmull_lane_s16(a, v, 0);
+  // CHECK: smull {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[0]
+}
+
+int64x2_t test_vmull_lane_s32_0(int32x2_t a, int32x2_t v) {
+  // CHECK-LABEL: test_vmull_lane_s32_0
+  return vmull_lane_s32(a, v, 0);
+  // CHECK: smull {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+uint32x4_t test_vmull_lane_u16_0(uint16x4_t a, uint16x4_t v) {
+  // CHECK-LABEL: test_vmull_lane_u16_0
+  return vmull_lane_u16(a, v, 0);
+  // CHECK: umull {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[0]
+}
+
+uint64x2_t test_vmull_lane_u32_0(uint32x2_t a, uint32x2_t v) {
+  // CHECK-LABEL: test_vmull_lane_u32_0
+  return vmull_lane_u32(a, v, 0);
+  // CHECK: umull {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vmull_high_lane_s16_0(int16x8_t a, int16x4_t v) {
+  // CHECK-LABEL: test_vmull_high_lane_s16_0
+  return vmull_high_lane_s16(a, v, 0);
+  // CHECK: smull2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[0]
+}
+
+int64x2_t test_vmull_high_lane_s32_0(int32x4_t a, int32x2_t v) {
+  // CHECK-LABEL: test_vmull_high_lane_s32_0
+  return vmull_high_lane_s32(a, v, 0);
+  // CHECK: smull2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+uint32x4_t test_vmull_high_lane_u16_0(uint16x8_t a, uint16x4_t v) {
+  // CHECK-LABEL: test_vmull_high_lane_u16_0
+  return vmull_high_lane_u16(a, v, 0);
+  // CHECK: umull2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[0]
+}
+
+uint64x2_t test_vmull_high_lane_u32_0(uint32x4_t a, uint32x2_t v) {
+  // CHECK-LABEL: test_vmull_high_lane_u32_0
+  return vmull_high_lane_u32(a, v, 0);
+  // CHECK: umull2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vmull_laneq_s16_0(int16x4_t a, int16x8_t v) {
+  // CHECK-LABEL: test_vmull_laneq_s16_0
+  return vmull_laneq_s16(a, v, 0);
+  // CHECK: smull {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[0]
+}
+
+int64x2_t test_vmull_laneq_s32_0(int32x2_t a, int32x4_t v) {
+  // CHECK-LABEL: test_vmull_laneq_s32_0
+  return vmull_laneq_s32(a, v, 0);
+  // CHECK: smull {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+uint32x4_t test_vmull_laneq_u16_0(uint16x4_t a, uint16x8_t v) {
+  // CHECK-LABEL: test_vmull_laneq_u16_0
+  return vmull_laneq_u16(a, v, 0);
+  // CHECK: umull {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[0]
+}
+
+uint64x2_t test_vmull_laneq_u32_0(uint32x2_t a, uint32x4_t v) {
+  // CHECK-LABEL: test_vmull_laneq_u32_0
+  return vmull_laneq_u32(a, v, 0);
+  // CHECK: umull {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vmull_high_laneq_s16_0(int16x8_t a, int16x8_t v) {
+  // CHECK-LABEL: test_vmull_high_laneq_s16_0
+  return vmull_high_laneq_s16(a, v, 0);
+  // CHECK: smull2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[0]
+}
+
+int64x2_t test_vmull_high_laneq_s32_0(int32x4_t a, int32x4_t v) {
+  // CHECK-LABEL: test_vmull_high_laneq_s32_0
+  return vmull_high_laneq_s32(a, v, 0);
+  // CHECK: smull2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+uint32x4_t test_vmull_high_laneq_u16_0(uint16x8_t a, uint16x8_t v) {
+  // CHECK-LABEL: test_vmull_high_laneq_u16_0
+  return vmull_high_laneq_u16(a, v, 0);
+  // CHECK: umull2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[0]
+}
+
+uint64x2_t test_vmull_high_laneq_u32_0(uint32x4_t a, uint32x4_t v) {
+  // CHECK-LABEL: test_vmull_high_laneq_u32_0
+  return vmull_high_laneq_u32(a, v, 0);
+  // CHECK: umull2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vqdmlal_lane_s16_0(int32x4_t a, int16x4_t b, int16x4_t v) {
+  // CHECK-LABEL: test_vqdmlal_lane_s16_0
+  return vqdmlal_lane_s16(a, b, v, 0);
+  // CHECK: sqdmlal {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[0]
+}
+
+int64x2_t test_vqdmlal_lane_s32_0(int64x2_t a, int32x2_t b, int32x2_t v) {
+  // CHECK-LABEL: test_vqdmlal_lane_s32_0
+  return vqdmlal_lane_s32(a, b, v, 0);
+  // CHECK: sqdmlal {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vqdmlal_high_lane_s16_0(int32x4_t a, int16x8_t b, int16x4_t v) {
+  // CHECK-LABEL: test_vqdmlal_high_lane_s16_0
+  return vqdmlal_high_lane_s16(a, b, v, 0);
+  // CHECK: sqdmlal2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[0]
+}
+
+int64x2_t test_vqdmlal_high_lane_s32_0(int64x2_t a, int32x4_t b, int32x2_t v) {
+  // CHECK-LABEL: test_vqdmlal_high_lane_s32_0
+  return vqdmlal_high_lane_s32(a, b, v, 0);
+  // CHECK: sqdmlal2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vqdmlsl_lane_s16_0(int32x4_t a, int16x4_t b, int16x4_t v) {
+  // CHECK-LABEL: test_vqdmlsl_lane_s16_0
+  return vqdmlsl_lane_s16(a, b, v, 0);
+  // CHECK: sqdmlsl {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[0]
+}
+
+int64x2_t test_vqdmlsl_lane_s32_0(int64x2_t a, int32x2_t b, int32x2_t v) {
+  // CHECK-LABEL: test_vqdmlsl_lane_s32_0
+  return vqdmlsl_lane_s32(a, b, v, 0);
+  // CHECK: sqdmlsl {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vqdmlsl_high_lane_s16_0(int32x4_t a, int16x8_t b, int16x4_t v) {
+  // CHECK-LABEL: test_vqdmlsl_high_lane_s16_0
+  return vqdmlsl_high_lane_s16(a, b, v, 0);
+  // CHECK: sqdmlsl2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[0]
+}
+
+int64x2_t test_vqdmlsl_high_lane_s32_0(int64x2_t a, int32x4_t b, int32x2_t v) {
+  // CHECK-LABEL: test_vqdmlsl_high_lane_s32_0
+  return vqdmlsl_high_lane_s32(a, b, v, 0);
+  // CHECK: sqdmlsl2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vqdmull_lane_s16_0(int16x4_t a, int16x4_t v) {
+  // CHECK-LABEL: test_vqdmull_lane_s16_0
+  return vqdmull_lane_s16(a, v, 0);
+  // CHECK: sqdmull {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[0]
+}
+
+int64x2_t test_vqdmull_lane_s32_0(int32x2_t a, int32x2_t v) {
+  // CHECK-LABEL: test_vqdmull_lane_s32_0
+  return vqdmull_lane_s32(a, v, 0);
+  // CHECK: sqdmull {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vqdmull_laneq_s16_0(int16x4_t a, int16x8_t v) {
+  // CHECK-LABEL: test_vqdmull_laneq_s16_0
+  return vqdmull_laneq_s16(a, v, 0);
+  // CHECK: sqdmull {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[0]
+}
+
+int64x2_t test_vqdmull_laneq_s32_0(int32x2_t a, int32x4_t v) {
+  // CHECK-LABEL: test_vqdmull_laneq_s32_0
+  return vqdmull_laneq_s32(a, v, 0);
+  // CHECK: sqdmull {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vqdmull_high_lane_s16_0(int16x8_t a, int16x4_t v) {
+  // CHECK-LABEL: test_vqdmull_high_lane_s16_0
+  return vqdmull_high_lane_s16(a, v, 0);
+  // CHECK: sqdmull2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[0]
+}
+
+int64x2_t test_vqdmull_high_lane_s32_0(int32x4_t a, int32x2_t v) {
+  // CHECK-LABEL: test_vqdmull_high_lane_s32_0
+  return vqdmull_high_lane_s32(a, v, 0);
+  // CHECK: sqdmull2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vqdmull_high_laneq_s16_0(int16x8_t a, int16x8_t v) {
+  // CHECK-LABEL: test_vqdmull_high_laneq_s16_0
+  return vqdmull_high_laneq_s16(a, v, 0);
+  // CHECK: sqdmull2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[0]
+}
+
+int64x2_t test_vqdmull_high_laneq_s32_0(int32x4_t a, int32x4_t v) {
+  // CHECK-LABEL: test_vqdmull_high_laneq_s32_0
+  return vqdmull_high_laneq_s32(a, v, 0);
+  // CHECK: sqdmull2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+int16x4_t test_vqdmulh_lane_s16_0(int16x4_t a, int16x4_t v) {
+  // CHECK-LABEL: test_vqdmulh_lane_s16_0
+  return vqdmulh_lane_s16(a, v, 0);
+  // CHECK: sqdmulh {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[0]
+}
+
+int16x8_t test_vqdmulhq_lane_s16_0(int16x8_t a, int16x4_t v) {
+  // CHECK-LABEL: test_vqdmulhq_lane_s16_0
+  return vqdmulhq_lane_s16(a, v, 0);
+  // CHECK: sqdmulh {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[0]
+}
+
+int32x2_t test_vqdmulh_lane_s32_0(int32x2_t a, int32x2_t v) {
+  // CHECK-LABEL: test_vqdmulh_lane_s32_0
+  return vqdmulh_lane_s32(a, v, 0);
+  // CHECK: sqdmulh {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vqdmulhq_lane_s32_0(int32x4_t a, int32x2_t v) {
+  // CHECK-LABEL: test_vqdmulhq_lane_s32_0
+  return vqdmulhq_lane_s32(a, v, 0);
+  // CHECK: sqdmulh {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+int16x4_t test_vqrdmulh_lane_s16_0(int16x4_t a, int16x4_t v) {
+  // CHECK-LABEL: test_vqrdmulh_lane_s16_0
+  return vqrdmulh_lane_s16(a, v, 0);
+  // CHECK: sqrdmulh {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[0]
+}
+
+int16x8_t test_vqrdmulhq_lane_s16_0(int16x8_t a, int16x4_t v) {
+  // CHECK-LABEL: test_vqrdmulhq_lane_s16_0
+  return vqrdmulhq_lane_s16(a, v, 0);
+  // CHECK: sqrdmulh {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[0]
+}
+
+int32x2_t test_vqrdmulh_lane_s32_0(int32x2_t a, int32x2_t v) {
+  // CHECK-LABEL: test_vqrdmulh_lane_s32_0
+  return vqrdmulh_lane_s32(a, v, 0);
+  // CHECK: sqrdmulh {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vqrdmulhq_lane_s32_0(int32x4_t a, int32x2_t v) {
+  // CHECK-LABEL: test_vqrdmulhq_lane_s32_0
+  return vqrdmulhq_lane_s32(a, v, 0);
+  // CHECK: sqrdmulh {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+float32x2_t test_vmul_lane_f32_0(float32x2_t a, float32x2_t v) {
+  // CHECK-LABEL: test_vmul_lane_f32_0
+  return vmul_lane_f32(a, v, 0);
+  // CHECK: fmul {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+float32x4_t test_vmulq_lane_f32_0(float32x4_t a, float32x2_t v) {
+  // CHECK-LABEL: test_vmulq_lane_f32_0
+  return vmulq_lane_f32(a, v, 0);
+  // CHECK: fmul {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+float32x2_t test_vmul_laneq_f32_0(float32x2_t a, float32x4_t v) {
+  // CHECK-LABEL: test_vmul_laneq_f32_0
+  return vmul_laneq_f32(a, v, 0);
+  // CHECK: fmul {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+float64x1_t test_vmul_laneq_f64_0(float64x1_t a, float64x2_t v) {
+  // CHECK-LABEL: test_vmul_laneq_f64_0
+  return vmul_laneq_f64(a, v, 0);
+  // CHECK: fmul {{d[0-9]+}}, {{d[0-9]+}}, {{v[0-9]+}}.d[0]
+}
+
+float32x4_t test_vmulq_laneq_f32_0(float32x4_t a, float32x4_t v) {
+  // CHECK-LABEL: test_vmulq_laneq_f32_0
+  return vmulq_laneq_f32(a, v, 0);
+  // CHECK: fmul {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+float64x2_t test_vmulq_laneq_f64_0(float64x2_t a, float64x2_t v) {
+  // CHECK-LABEL: test_vmulq_laneq_f64_0
+  return vmulq_laneq_f64(a, v, 0);
+  // CHECK: fmul {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.d[0]
+}
+
+float32x2_t test_vmulx_lane_f32_0(float32x2_t a, float32x2_t v) {
+  // CHECK-LABEL: test_vmulx_lane_f32_0
+  return vmulx_lane_f32(a, v, 0);
+  // CHECK: fmulx {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+float32x4_t test_vmulxq_lane_f32_0(float32x4_t a, float32x2_t v) {
+  // CHECK-LABEL: test_vmulxq_lane_f32_0
+  return vmulxq_lane_f32(a, v, 0);
+  // CHECK: fmulx {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+float64x2_t test_vmulxq_lane_f64_0(float64x2_t a, float64x1_t v) {
+  // CHECK-LABEL: test_vmulxq_lane_f64_0
+  return vmulxq_lane_f64(a, v, 0);
+  // CHECK: fmulx {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.d[0]
+}
+
+float32x2_t test_vmulx_laneq_f32_0(float32x2_t a, float32x4_t v) {
+  // CHECK-LABEL: test_vmulx_laneq_f32_0
+  return vmulx_laneq_f32(a, v, 0);
+  // CHECK: fmulx {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+float32x4_t test_vmulxq_laneq_f32_0(float32x4_t a, float32x4_t v) {
+  // CHECK-LABEL: test_vmulxq_laneq_f32_0
+  return vmulxq_laneq_f32(a, v, 0);
+  // CHECK: fmulx {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
 }
 
 float64x2_t test_vmulxq_laneq_f64_0(float64x2_t a, float64x2_t v) {
-  // CHECK: test_vmulxq_laneq_f64
+  // CHECK-LABEL: test_vmulxq_laneq_f64_0
   return vmulxq_laneq_f64(a, v, 0);
   // CHECK: fmulx {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.d[0]
 }
 
-float64x2_t test_vmulxq_laneq_f64(float64x2_t a, float64x2_t v) {
-  // CHECK: test_vmulxq_laneq_f64
-  return vmulxq_laneq_f64(a, v, 1);
-  // CHECK: fmulx {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.d[1]
+int32x4_t test_vmull_high_n_s16(int16x8_t a, int16_t b) {
+  // CHECK-LABEL: test_vmull_high_n_s16
+  return vmull_high_n_s16(a, b);
+  // CHECK: smull2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+\.h\[0\]|v[0-9]+\.8h}}
+}
+
+int64x2_t test_vmull_high_n_s32(int32x4_t a, int32_t b) {
+  // CHECK-LABEL: test_vmull_high_n_s32
+  return vmull_high_n_s32(a, b);
+  // CHECK: smull2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+\.s\[0\]|v[0-9]+\.4s}}
+}
+
+uint32x4_t test_vmull_high_n_u16(uint16x8_t a, uint16_t b) {
+  // CHECK-LABEL: test_vmull_high_n_u16
+  return vmull_high_n_u16(a, b);
+  // CHECK: umull2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+\.h\[0\]|v[0-9]+\.8h}}
+}
+
+uint64x2_t test_vmull_high_n_u32(uint32x4_t a, uint32_t b) {
+  // CHECK-LABEL: test_vmull_high_n_u32
+  return vmull_high_n_u32(a, b);
+  // CHECK: umull2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+\.s\[0\]|v[0-9]+\.4s}}
+}
+
+int32x4_t test_vqdmull_high_n_s16(int16x8_t a, int16_t b) {
+  // CHECK-LABEL: test_vqdmull_high_n_s16
+  return vqdmull_high_n_s16(a, b);
+  // CHECK: sqdmull2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+\.h\[0\]|v[0-9]+\.8h}}
+}
+
+int64x2_t test_vqdmull_high_n_s32(int32x4_t a, int32_t b) {
+  // CHECK-LABEL: test_vqdmull_high_n_s32
+  return vqdmull_high_n_s32(a, b);
+  // CHECK: sqdmull2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+\.s\[0\]|v[0-9]+\.4s}}
+}
+
+int32x4_t test_vmlal_high_n_s16(int32x4_t a, int16x8_t b, int16_t c) {
+  // CHECK-LABEL: test_vmlal_high_n_s16
+  return vmlal_high_n_s16(a, b, c);
+  // CHECK: smlal2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+\.h\[0\]|v[0-9]+\.8h}}
+}
+
+int64x2_t test_vmlal_high_n_s32(int64x2_t a, int32x4_t b, int32_t c) {
+  // CHECK-LABEL: test_vmlal_high_n_s32
+  return vmlal_high_n_s32(a, b, c);
+  // CHECK: smlal2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+\.s\[0\]|v[0-9]+\.4s}}
+}
+
+uint32x4_t test_vmlal_high_n_u16(uint32x4_t a, uint16x8_t b, uint16_t c) {
+  // CHECK-LABEL: test_vmlal_high_n_u16
+  return vmlal_high_n_u16(a, b, c);
+  // CHECK: umlal2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+\.h\[0\]|v[0-9]+\.8h}}
+}
+
+uint64x2_t test_vmlal_high_n_u32(uint64x2_t a, uint32x4_t b, uint32_t c) {
+  // CHECK-LABEL: test_vmlal_high_n_u32
+  return vmlal_high_n_u32(a, b, c);
+  // CHECK: umlal2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+\.s\[0\]|v[0-9]+\.4s}}
+}
+
+int32x4_t test_vqdmlal_high_n_s16(int32x4_t a, int16x8_t b, int16_t c) {
+  // CHECK-LABEL: test_vqdmlal_high_n_s16
+  return vqdmlal_high_n_s16(a, b, c);
+  // CHECK: sqdmlal2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+\.h\[0\]|v[0-9]+\.8h}}
+}
+
+int64x2_t test_vqdmlal_high_n_s32(int64x2_t a, int32x4_t b, int32_t c) {
+  // CHECK-LABEL: test_vqdmlal_high_n_s32
+  return vqdmlal_high_n_s32(a, b, c);
+  // CHECK: sqdmlal2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+\.s\[0\]|v[0-9]+\.4s}}
+}
+
+int32x4_t test_vmlsl_high_n_s16(int32x4_t a, int16x8_t b, int16_t c) {
+  // CHECK-LABEL: test_vmlsl_high_n_s16
+  return vmlsl_high_n_s16(a, b, c);
+  // CHECK: smlsl2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+\.h\[0\]|v[0-9]+\.8h}}
+}
+
+int64x2_t test_vmlsl_high_n_s32(int64x2_t a, int32x4_t b, int32_t c) {
+  // CHECK-LABEL: test_vmlsl_high_n_s32
+  return vmlsl_high_n_s32(a, b, c);
+  // CHECK: smlsl2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+\.s\[0\]|v[0-9]+\.4s}}
+}
+
+uint32x4_t test_vmlsl_high_n_u16(uint32x4_t a, uint16x8_t b, uint16_t c) {
+  // CHECK-LABEL: test_vmlsl_high_n_u16
+  return vmlsl_high_n_u16(a, b, c);
+  // CHECK: umlsl2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+\.h\[0\]|v[0-9]+\.8h}}
+}
+
+uint64x2_t test_vmlsl_high_n_u32(uint64x2_t a, uint32x4_t b, uint32_t c) {
+  // CHECK-LABEL: test_vmlsl_high_n_u32
+  return vmlsl_high_n_u32(a, b, c);
+  // CHECK: umlsl2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+\.s\[0\]|v[0-9]+\.4s}}
+}
+
+int32x4_t test_vqdmlsl_high_n_s16(int32x4_t a, int16x8_t b, int16_t c) {
+  // CHECK-LABEL: test_vqdmlsl_high_n_s16
+  return vqdmlsl_high_n_s16(a, b, c);
+  // CHECK: sqdmlsl2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+\.h\[0\]|v[0-9]+\.8h}}
+}
+
+int64x2_t test_vqdmlsl_high_n_s32(int64x2_t a, int32x4_t b, int32_t c) {
+  // CHECK-LABEL: test_vqdmlsl_high_n_s32
+  return vqdmlsl_high_n_s32(a, b, c);
+  // CHECK: sqdmlsl2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+\.s\[0\]|v[0-9]+\.4s}}
+}
+
+float32x2_t test_vmul_n_f32(float32x2_t a, float32_t b) {
+  // CHECK-LABEL: test_vmul_n_f32
+  return vmul_n_f32(a, b);
+  // CHECK: fmul {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+float32x4_t test_vmulq_n_f32(float32x4_t a, float32_t b) {
+  // CHECK-LABEL: test_vmulq_n_f32
+  return vmulq_n_f32(a, b);
+  // CHECK: fmul {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+float64x2_t test_vmulq_n_f64(float64x2_t a, float64_t b) {
+  // CHECK-LABEL: test_vmulq_n_f64
+  return vmulq_n_f64(a, b);
+  // CHECK: fmul {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.d[0]
+}
+
+float32x2_t test_vfma_n_f32(float32x2_t a, float32x2_t b, float32_t n) {
+  // CHECK-LABEL: test_vfma_n_f32
+  return vfma_n_f32(a, b, n);
+  // CHECK: fmla {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+float32x4_t test_vfmaq_n_f32(float32x4_t a, float32x4_t b, float32_t n) {
+  // CHECK-LABEL: test_vfmaq_n_f32
+  return vfmaq_n_f32(a, b, n);
+  // CHECK: fmla {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+float32x2_t test_vfms_n_f32(float32x2_t a, float32x2_t b, float32_t n) {
+  // CHECK-LABEL: test_vfms_n_f32
+  return vfms_n_f32(a, b, n);
+  // CHECK: fmls {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+float32x4_t test_vfmsq_n_f32(float32x4_t a, float32x4_t b, float32_t n) {
+  // CHECK-LABEL: test_vfmsq_n_f32
+  return vfmsq_n_f32(a, b, n);
+  // CHECK: fmls {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+int16x4_t test_vmul_n_s16(int16x4_t a, int16_t b) {
+  // CHECK-LABEL: test_vmul_n_s16
+  return vmul_n_s16(a, b);
+  // CHECK: dup {{v[0-9]+}}.4h, w0
+  // CHECK: mul {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
+}
+
+int16x8_t test_vmulq_n_s16(int16x8_t a, int16_t b) {
+  // CHECK-LABEL: test_vmulq_n_s16
+  return vmulq_n_s16(a, b);
+  // CHECK: dup {{v[0-9]+}}.8h, w0
+  // CHECK: mul {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
+}
+
+int32x2_t test_vmul_n_s32(int32x2_t a, int32_t b) {
+  // CHECK-LABEL: test_vmul_n_s32
+  return vmul_n_s32(a, b);
+  // CHECK: dup {{v[0-9]+}}.2s, w0
+  // CHECK: mul {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
+}
+
+int32x4_t test_vmulq_n_s32(int32x4_t a, int32_t b) {
+  // CHECK-LABEL: test_vmulq_n_s32
+  return vmulq_n_s32(a, b);
+  // CHECK: dup {{v[0-9]+}}.4s, w0
+  // CHECK: mul {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
+}
+
+uint16x4_t test_vmul_n_u16(uint16x4_t a, uint16_t b) {
+  // CHECK-LABEL: test_vmul_n_u16
+  return vmul_n_u16(a, b);
+  // CHECK: dup {{v[0-9]+}}.4h, w0
+  // CHECK: mul {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
+}
+
+uint16x8_t test_vmulq_n_u16(uint16x8_t a, uint16_t b) {
+  // CHECK-LABEL: test_vmulq_n_u16
+  return vmulq_n_u16(a, b);
+  // CHECK: dup {{v[0-9]+}}.8h, w0
+  // CHECK: mul {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
+}
+
+uint32x2_t test_vmul_n_u32(uint32x2_t a, uint32_t b) {
+  // CHECK-LABEL: test_vmul_n_u32
+  return vmul_n_u32(a, b);
+  // CHECK: dup {{v[0-9]+}}.2s, w0
+  // CHECK: mul {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
+}
+
+uint32x4_t test_vmulq_n_u32(uint32x4_t a, uint32_t b) {
+  // CHECK-LABEL: test_vmulq_n_u32
+  return vmulq_n_u32(a, b);
+  // CHECK: dup {{v[0-9]+}}.4s, w0
+  // CHECK: mul {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
+}
+
+int32x4_t test_vmull_n_s16(int16x4_t a, int16_t b) {
+  // CHECK-LABEL: test_vmull_n_s16
+  return vmull_n_s16(a, b);
+  // CHECK: dup {{v[0-9]+}}.4h, w0
+  // CHECK: smull {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
+}
+
+int64x2_t test_vmull_n_s32(int32x2_t a, int32_t b) {
+  // CHECK-LABEL: test_vmull_n_s32
+  return vmull_n_s32(a, b);
+  // CHECK: dup {{v[0-9]+}}.2s, w0
+  // CHECK: smull {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
+}
+
+uint32x4_t test_vmull_n_u16(uint16x4_t a, uint16_t b) {
+  // CHECK-LABEL: test_vmull_n_u16
+  return vmull_n_u16(a, b);
+  // CHECK: dup {{v[0-9]+}}.4h, w0
+  // CHECK: umull {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
+}
+
+uint64x2_t test_vmull_n_u32(uint32x2_t a, uint32_t b) {
+  // CHECK-LABEL: test_vmull_n_u32
+  return vmull_n_u32(a, b);
+  // CHECK: dup {{v[0-9]+}}.2s, w0
+  // CHECK: umull {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
+}
+
+int32x4_t test_vqdmull_n_s16(int16x4_t a, int16_t b) {
+  // CHECK-LABEL: test_vqdmull_n_s16
+  return vqdmull_n_s16(a, b);
+  // CHECK: dup {{v[0-9]+}}.4h, w0
+  // CHECK: sqdmull {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
+}
+
+int64x2_t test_vqdmull_n_s32(int32x2_t a, int32_t b) {
+  // CHECK-LABEL: test_vqdmull_n_s32
+  return vqdmull_n_s32(a, b);
+  // CHECK: dup {{v[0-9]+}}.2s, w0
+  // CHECK: sqdmull {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
+}
+
+int16x4_t test_vqdmulh_n_s16(int16x4_t a, int16_t b) {
+  // CHECK-LABEL: test_vqdmulh_n_s16
+  return vqdmulh_n_s16(a, b);
+  // CHECK: dup {{v[0-9]+}}.4h, w0
+  // CHECK: sqdmulh {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
+}
+
+int16x8_t test_vqdmulhq_n_s16(int16x8_t a, int16_t b) {
+  // CHECK-LABEL: test_vqdmulhq_n_s16
+  return vqdmulhq_n_s16(a, b);
+  // CHECK: dup {{v[0-9]+}}.8h, w0
+  // CHECK: sqdmulh {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
+}
+
+int32x2_t test_vqdmulh_n_s32(int32x2_t a, int32_t b) {
+  // CHECK-LABEL: test_vqdmulh_n_s32
+  return vqdmulh_n_s32(a, b);
+  // CHECK: dup {{v[0-9]+}}.2s, w0
+  // CHECK: sqdmulh {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
+}
+
+int32x4_t test_vqdmulhq_n_s32(int32x4_t a, int32_t b) {
+  // CHECK-LABEL: test_vqdmulhq_n_s32
+  return vqdmulhq_n_s32(a, b);
+  // CHECK: dup {{v[0-9]+}}.4s, w0
+  // CHECK: sqdmulh {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
+}
+
+int16x4_t test_vqrdmulh_n_s16(int16x4_t a, int16_t b) {
+  // CHECK-LABEL: test_vqrdmulh_n_s16
+  return vqrdmulh_n_s16(a, b);
+  // CHECK: dup {{v[0-9]+}}.4h, w0
+  // CHECK: sqrdmulh {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
+}
+
+int16x8_t test_vqrdmulhq_n_s16(int16x8_t a, int16_t b) {
+  // CHECK-LABEL: test_vqrdmulhq_n_s16
+  return vqrdmulhq_n_s16(a, b);
+  // CHECK: dup {{v[0-9]+}}.8h, w0
+  // CHECK: sqrdmulh {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
+}
+
+int32x2_t test_vqrdmulh_n_s32(int32x2_t a, int32_t b) {
+  // CHECK-LABEL: test_vqrdmulh_n_s32
+  return vqrdmulh_n_s32(a, b);
+  // CHECK: dup {{v[0-9]+}}.2s, w0
+  // CHECK: sqrdmulh {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
+}
+
+int32x4_t test_vqrdmulhq_n_s32(int32x4_t a, int32_t b) {
+  // CHECK-LABEL: test_vqrdmulhq_n_s32
+  return vqrdmulhq_n_s32(a, b);
+  // CHECK: dup {{v[0-9]+}}.4s, w0
+  // CHECK: sqrdmulh {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
+}
+
+int16x4_t test_vmla_n_s16(int16x4_t a, int16x4_t b, int16_t c) {
+  // CHECK-LABEL: test_vmla_n_s16
+  return vmla_n_s16(a, b, c);
+  // CHECK: dup {{v[0-9]+}}.4h, w0
+  // CHECK: mla {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
+}
+
+int16x8_t test_vmlaq_n_s16(int16x8_t a, int16x8_t b, int16_t c) {
+  // CHECK-LABEL: test_vmlaq_n_s16
+  return vmlaq_n_s16(a, b, c);
+  // CHECK: dup {{v[0-9]+}}.8h, w0
+  // CHECK: mla {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
+}
+
+int32x2_t test_vmla_n_s32(int32x2_t a, int32x2_t b, int32_t c) {
+  // CHECK-LABEL: test_vmla_n_s32
+  return vmla_n_s32(a, b, c);
+  // CHECK: dup {{v[0-9]+}}.2s, w0
+  // CHECK: mla {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
+}
+
+int32x4_t test_vmlaq_n_s32(int32x4_t a, int32x4_t b, int32_t c) {
+  // CHECK-LABEL: test_vmlaq_n_s32
+  return vmlaq_n_s32(a, b, c);
+  // CHECK: dup {{v[0-9]+}}.4s, w0
+  // CHECK: mla {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
+}
+
+uint16x4_t test_vmla_n_u16(uint16x4_t a, uint16x4_t b, uint16_t c) {
+  // CHECK-LABEL: test_vmla_n_u16
+  return vmla_n_u16(a, b, c);
+  // CHECK: dup {{v[0-9]+}}.4h, w0
+  // CHECK: mla {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
+}
+
+uint16x8_t test_vmlaq_n_u16(uint16x8_t a, uint16x8_t b, uint16_t c) {
+  // CHECK-LABEL: test_vmlaq_n_u16
+  return vmlaq_n_u16(a, b, c);
+  // CHECK: dup {{v[0-9]+}}.8h, w0
+  // CHECK: mla {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
+}
+
+uint32x2_t test_vmla_n_u32(uint32x2_t a, uint32x2_t b, uint32_t c) {
+  // CHECK-LABEL: test_vmla_n_u32
+  return vmla_n_u32(a, b, c);
+  // CHECK: dup {{v[0-9]+}}.2s, w0
+  // CHECK: mla {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
+}
+
+uint32x4_t test_vmlaq_n_u32(uint32x4_t a, uint32x4_t b, uint32_t c) {
+  // CHECK-LABEL: test_vmlaq_n_u32
+  return vmlaq_n_u32(a, b, c);
+  // CHECK: dup {{v[0-9]+}}.4s, w0
+  // CHECK: mla {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
+}
+
+int32x4_t test_vmlal_n_s16(int32x4_t a, int16x4_t b, int16_t c) {
+  // CHECK-LABEL: test_vmlal_n_s16
+  return vmlal_n_s16(a, b, c);
+  // CHECK: dup {{v[0-9]+}}.4h, w0
+  // CHECK: smlal {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
+}
+
+int64x2_t test_vmlal_n_s32(int64x2_t a, int32x2_t b, int32_t c) {
+  // CHECK-LABEL: test_vmlal_n_s32
+  return vmlal_n_s32(a, b, c);
+  // CHECK: dup {{v[0-9]+}}.2s, w0
+  // CHECK: smlal {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
+}
+
+uint32x4_t test_vmlal_n_u16(uint32x4_t a, uint16x4_t b, uint16_t c) {
+  // CHECK-LABEL: test_vmlal_n_u16
+  return vmlal_n_u16(a, b, c);
+  // CHECK: dup {{v[0-9]+}}.4h, w0
+  // CHECK: umlal {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
+}
+
+uint64x2_t test_vmlal_n_u32(uint64x2_t a, uint32x2_t b, uint32_t c) {
+  // CHECK-LABEL: test_vmlal_n_u32
+  return vmlal_n_u32(a, b, c);
+  // CHECK: dup {{v[0-9]+}}.2s, w0
+  // CHECK: umlal {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
+}
+
+int32x4_t test_vqdmlal_n_s16(int32x4_t a, int16x4_t b, int16_t c) {
+  // CHECK-LABEL: test_vqdmlal_n_s16
+  return vqdmlal_n_s16(a, b, c);
+  // CHECK: dup {{v[0-9]+}}.4h, w0
+  // CHECK: sqdmlal {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
+}
+
+int64x2_t test_vqdmlal_n_s32(int64x2_t a, int32x2_t b, int32_t c) {
+  // CHECK-LABEL: test_vqdmlal_n_s32
+  return vqdmlal_n_s32(a, b, c);
+  // CHECK: dup {{v[0-9]+}}.2s, w0
+  // CHECK: sqdmlal {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
+}
+
+int16x4_t test_vmls_n_s16(int16x4_t a, int16x4_t b, int16_t c) {
+  // CHECK-LABEL: test_vmls_n_s16
+  return vmls_n_s16(a, b, c);
+  // CHECK: dup {{v[0-9]+}}.4h, w0
+  // CHECK: mls {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
+}
+
+int16x8_t test_vmlsq_n_s16(int16x8_t a, int16x8_t b, int16_t c) {
+  // CHECK-LABEL: test_vmlsq_n_s16
+  return vmlsq_n_s16(a, b, c);
+  // CHECK: dup {{v[0-9]+}}.8h, w0
+  // CHECK: mls {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
+}
+
+int32x2_t test_vmls_n_s32(int32x2_t a, int32x2_t b, int32_t c) {
+  // CHECK-LABEL: test_vmls_n_s32
+  return vmls_n_s32(a, b, c);
+  // CHECK: dup {{v[0-9]+}}.2s, w0
+  // CHECK: mls {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
+}
+
+int32x4_t test_vmlsq_n_s32(int32x4_t a, int32x4_t b, int32_t c) {
+  // CHECK-LABEL: test_vmlsq_n_s32
+  return vmlsq_n_s32(a, b, c);
+  // CHECK: mls {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
+}
+
+uint16x4_t test_vmls_n_u16(uint16x4_t a, uint16x4_t b, uint16_t c) {
+  // CHECK-LABEL: test_vmls_n_u16
+  return vmls_n_u16(a, b, c);
+  // CHECK: dup {{v[0-9]+}}.4h, w0
+  // CHECK: mls {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
+}
+
+uint16x8_t test_vmlsq_n_u16(uint16x8_t a, uint16x8_t b, uint16_t c) {
+  // CHECK-LABEL: test_vmlsq_n_u16
+  return vmlsq_n_u16(a, b, c);
+  // CHECK: dup {{v[0-9]+}}.8h, w0
+  // CHECK: mls {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
+}
+
+uint32x2_t test_vmls_n_u32(uint32x2_t a, uint32x2_t b, uint32_t c) {
+  // CHECK-LABEL: test_vmls_n_u32
+  return vmls_n_u32(a, b, c);
+  // CHECK: dup {{v[0-9]+}}.2s, w0
+  // CHECK: mls {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
+}
+
+uint32x4_t test_vmlsq_n_u32(uint32x4_t a, uint32x4_t b, uint32_t c) {
+  // CHECK-LABEL: test_vmlsq_n_u32
+  return vmlsq_n_u32(a, b, c);
+  // CHECK: mls {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
+}
+
+int32x4_t test_vmlsl_n_s16(int32x4_t a, int16x4_t b, int16_t c) {
+  // CHECK-LABEL: test_vmlsl_n_s16
+  return vmlsl_n_s16(a, b, c);
+  // CHECK: dup {{v[0-9]+}}.4h, w0
+  // CHECK: smlsl {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
+}
+
+int64x2_t test_vmlsl_n_s32(int64x2_t a, int32x2_t b, int32_t c) {
+  // CHECK-LABEL: test_vmlsl_n_s32
+  return vmlsl_n_s32(a, b, c);
+  // CHECK: dup {{v[0-9]+}}.2s, w0
+  // CHECK: smlsl {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
+}
+
+uint32x4_t test_vmlsl_n_u16(uint32x4_t a, uint16x4_t b, uint16_t c) {
+  // CHECK-LABEL: test_vmlsl_n_u16
+  return vmlsl_n_u16(a, b, c);
+  // CHECK: dup {{v[0-9]+}}.4h, w0
+  // CHECK: umlsl {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
+}
+
+uint64x2_t test_vmlsl_n_u32(uint64x2_t a, uint32x2_t b, uint32_t c) {
+  // CHECK-LABEL: test_vmlsl_n_u32
+  return vmlsl_n_u32(a, b, c);
+  // CHECK: dup {{v[0-9]+}}.2s, w0
+  // CHECK: umlsl {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
+}
+
+int32x4_t test_vqdmlsl_n_s16(int32x4_t a, int16x4_t b, int16_t c) {
+  // CHECK-LABEL: test_vqdmlsl_n_s16
+  return vqdmlsl_n_s16(a, b, c);
+  // CHECK: dup {{v[0-9]+}}.4h, w0
+  // CHECK: sqdmlsl {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
+}
+
+int64x2_t test_vqdmlsl_n_s32(int64x2_t a, int32x2_t b, int32_t c) {
+  // CHECK-LABEL: test_vqdmlsl_n_s32
+  return vqdmlsl_n_s32(a, b, c);
+  // CHECK: dup {{v[0-9]+}}.2s, w0
+  // CHECK: sqdmlsl {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
+}
+
+uint16x4_t test_vmla_lane_u16_0(uint16x4_t a, uint16x4_t b, uint16x4_t v) {
+  // CHECK-LABEL: test_vmla_lane_u16_0
+  return vmla_lane_u16(a, b, v, 0);
+  // CHECK: mla {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[0]
+}
+
+uint16x8_t test_vmlaq_lane_u16_0(uint16x8_t a, uint16x8_t b, uint16x4_t v) {
+  // CHECK-LABEL: test_vmlaq_lane_u16_0
+  return vmlaq_lane_u16(a, b, v, 0);
+  // CHECK: mla {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[0]
+}
+
+uint32x2_t test_vmla_lane_u32_0(uint32x2_t a, uint32x2_t b, uint32x2_t v) {
+  // CHECK-LABEL: test_vmla_lane_u32_0
+  return vmla_lane_u32(a, b, v, 0);
+  // CHECK: mla {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+uint32x4_t test_vmlaq_lane_u32_0(uint32x4_t a, uint32x4_t b, uint32x2_t v) {
+  // CHECK-LABEL: test_vmlaq_lane_u32_0
+  return vmlaq_lane_u32(a, b, v, 0);
+  // CHECK: mla {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+uint16x4_t test_vmla_laneq_u16_0(uint16x4_t a, uint16x4_t b, uint16x8_t v) {
+  // CHECK-LABEL: test_vmla_laneq_u16_0
+  return vmla_laneq_u16(a, b, v, 0);
+  // CHECK: mla {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[0]
+}
+
+uint16x8_t test_vmlaq_laneq_u16_0(uint16x8_t a, uint16x8_t b, uint16x8_t v) {
+  // CHECK-LABEL: test_vmlaq_laneq_u16_0
+  return vmlaq_laneq_u16(a, b, v, 0);
+  // CHECK: mla {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[0]
+}
+
+uint32x2_t test_vmla_laneq_u32_0(uint32x2_t a, uint32x2_t b, uint32x4_t v) {
+  // CHECK-LABEL: test_vmla_laneq_u32_0
+  return vmla_laneq_u32(a, b, v, 0);
+  // CHECK: mla {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+uint32x4_t test_vmlaq_laneq_u32_0(uint32x4_t a, uint32x4_t b, uint32x4_t v) {
+  // CHECK-LABEL: test_vmlaq_laneq_u32_0
+  return vmlaq_laneq_u32(a, b, v, 0);
+  // CHECK: mla {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vqdmlal_laneq_s16_0(int32x4_t a, int16x4_t b, int16x8_t v) {
+  // CHECK-LABEL: test_vqdmlal_laneq_s16_0
+  return vqdmlal_laneq_s16(a, b, v, 0);
+  // CHECK: sqdmlal {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[0]
+}
+
+int64x2_t test_vqdmlal_laneq_s32_0(int64x2_t a, int32x2_t b, int32x4_t v) {
+  // CHECK-LABEL: test_vqdmlal_laneq_s32_0
+  return vqdmlal_laneq_s32(a, b, v, 0);
+  // CHECK: sqdmlal {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vqdmlal_high_laneq_s16_0(int32x4_t a, int16x8_t b, int16x8_t v) {
+  // CHECK-LABEL: test_vqdmlal_high_laneq_s16_0
+  return vqdmlal_high_laneq_s16(a, b, v, 0);
+  // CHECK: sqdmlal2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[0]
+}
+
+int64x2_t test_vqdmlal_high_laneq_s32_0(int64x2_t a, int32x4_t b, int32x4_t v) {
+  // CHECK-LABEL: test_vqdmlal_high_laneq_s32_0
+  return vqdmlal_high_laneq_s32(a, b, v, 0);
+  // CHECK: sqdmlal2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+uint16x4_t test_vmls_lane_u16_0(uint16x4_t a, uint16x4_t b, uint16x4_t v) {
+  // CHECK-LABEL: test_vmls_lane_u16_0
+  return vmls_lane_u16(a, b, v, 0);
+  // CHECK: mls {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[0]
+}
+
+uint16x8_t test_vmlsq_lane_u16_0(uint16x8_t a, uint16x8_t b, uint16x4_t v) {
+  // CHECK-LABEL: test_vmlsq_lane_u16_0
+  return vmlsq_lane_u16(a, b, v, 0);
+  // CHECK: mls {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[0]
+}
+
+uint32x2_t test_vmls_lane_u32_0(uint32x2_t a, uint32x2_t b, uint32x2_t v) {
+  // CHECK-LABEL: test_vmls_lane_u32_0
+  return vmls_lane_u32(a, b, v, 0);
+  // CHECK: mls {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+uint32x4_t test_vmlsq_lane_u32_0(uint32x4_t a, uint32x4_t b, uint32x2_t v) {
+  // CHECK-LABEL: test_vmlsq_lane_u32_0
+  return vmlsq_lane_u32(a, b, v, 0);
+  // CHECK: mls {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+uint16x4_t test_vmls_laneq_u16_0(uint16x4_t a, uint16x4_t b, uint16x8_t v) {
+  // CHECK-LABEL: test_vmls_laneq_u16_0
+  return vmls_laneq_u16(a, b, v, 0);
+  // CHECK: mls {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[0]
+}
+
+uint16x8_t test_vmlsq_laneq_u16_0(uint16x8_t a, uint16x8_t b, uint16x8_t v) {
+  // CHECK-LABEL: test_vmlsq_laneq_u16_0
+  return vmlsq_laneq_u16(a, b, v, 0);
+  // CHECK: mls {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[0]
+}
+
+uint32x2_t test_vmls_laneq_u32_0(uint32x2_t a, uint32x2_t b, uint32x4_t v) {
+  // CHECK-LABEL: test_vmls_laneq_u32_0
+  return vmls_laneq_u32(a, b, v, 0);
+  // CHECK: mls {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+uint32x4_t test_vmlsq_laneq_u32_0(uint32x4_t a, uint32x4_t b, uint32x4_t v) {
+  // CHECK-LABEL: test_vmlsq_laneq_u32_0
+  return vmlsq_laneq_u32(a, b, v, 0);
+  // CHECK: mls {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vqdmlsl_laneq_s16_0(int32x4_t a, int16x4_t b, int16x8_t v) {
+  // CHECK-LABEL: test_vqdmlsl_laneq_s16_0
+  return vqdmlsl_laneq_s16(a, b, v, 0);
+  // CHECK: sqdmlsl {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[0]
+}
+
+int64x2_t test_vqdmlsl_laneq_s32_0(int64x2_t a, int32x2_t b, int32x4_t v) {
+  // CHECK-LABEL: test_vqdmlsl_laneq_s32_0
+  return vqdmlsl_laneq_s32(a, b, v, 0);
+  // CHECK: sqdmlsl {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vqdmlsl_high_laneq_s16_0(int32x4_t a, int16x8_t b, int16x8_t v) {
+  // CHECK-LABEL: test_vqdmlsl_high_laneq_s16_0
+  return vqdmlsl_high_laneq_s16(a, b, v, 0);
+  // CHECK: sqdmlsl2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[0]
+}
+
+int64x2_t test_vqdmlsl_high_laneq_s32_0(int64x2_t a, int32x4_t b, int32x4_t v) {
+  // CHECK-LABEL: test_vqdmlsl_high_laneq_s32_0
+  return vqdmlsl_high_laneq_s32(a, b, v, 0);
+  // CHECK: sqdmlsl2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+int16x4_t test_vqdmulh_laneq_s16_0(int16x4_t a, int16x8_t v) {
+  // CHECK-LABEL: test_vqdmulh_laneq_s16_0
+  return vqdmulh_laneq_s16(a, v, 0);
+  // CHECK: sqdmulh {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[0]
+}
+
+int16x8_t test_vqdmulhq_laneq_s16_0(int16x8_t a, int16x8_t v) {
+  // CHECK-LABEL: test_vqdmulhq_laneq_s16_0
+  return vqdmulhq_laneq_s16(a, v, 0);
+  // CHECK: sqdmulh {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[0]
+}
+
+int32x2_t test_vqdmulh_laneq_s32_0(int32x2_t a, int32x4_t v) {
+  // CHECK-LABEL: test_vqdmulh_laneq_s32_0
+  return vqdmulh_laneq_s32(a, v, 0);
+  // CHECK: sqdmulh {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vqdmulhq_laneq_s32_0(int32x4_t a, int32x4_t v) {
+  // CHECK-LABEL: test_vqdmulhq_laneq_s32_0
+  return vqdmulhq_laneq_s32(a, v, 0);
+  // CHECK: sqdmulh {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+int16x4_t test_vqrdmulh_laneq_s16_0(int16x4_t a, int16x8_t v) {
+  // CHECK-LABEL: test_vqrdmulh_laneq_s16_0
+  return vqrdmulh_laneq_s16(a, v, 0);
+  // CHECK: sqrdmulh {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[0]
+}
+
+int16x8_t test_vqrdmulhq_laneq_s16_0(int16x8_t a, int16x8_t v) {
+  // CHECK-LABEL: test_vqrdmulhq_laneq_s16_0
+  return vqrdmulhq_laneq_s16(a, v, 0);
+  // CHECK: sqrdmulh {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[0]
+}
+
+int32x2_t test_vqrdmulh_laneq_s32_0(int32x2_t a, int32x4_t v) {
+  // CHECK-LABEL: test_vqrdmulh_laneq_s32_0
+  return vqrdmulh_laneq_s32(a, v, 0);
+  // CHECK: sqrdmulh {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+int32x4_t test_vqrdmulhq_laneq_s32_0(int32x4_t a, int32x4_t v) {
+  // CHECK-LABEL: test_vqrdmulhq_laneq_s32_0
+  return vqrdmulhq_laneq_s32(a, v, 0);
+  // CHECK: sqrdmulh {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+uint16x4_t test_vmla_lane_u16(uint16x4_t a, uint16x4_t b, uint16x4_t v) {
+  // CHECK-LABEL: test_vmla_lane_u16
+  return vmla_lane_u16(a, b, v, 3);
+  // CHECK: mla {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[3]
+}
+
+uint16x8_t test_vmlaq_lane_u16(uint16x8_t a, uint16x8_t b, uint16x4_t v) {
+  // CHECK-LABEL: test_vmlaq_lane_u16
+  return vmlaq_lane_u16(a, b, v, 3);
+  // CHECK: mla {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[3]
+}
+
+uint32x2_t test_vmla_lane_u32(uint32x2_t a, uint32x2_t b, uint32x2_t v) {
+  // CHECK-LABEL: test_vmla_lane_u32
+  return vmla_lane_u32(a, b, v, 1);
+  // CHECK: mla {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
+}
+
+uint32x4_t test_vmlaq_lane_u32(uint32x4_t a, uint32x4_t b, uint32x2_t v) {
+  // CHECK-LABEL: test_vmlaq_lane_u32
+  return vmlaq_lane_u32(a, b, v, 1);
+  // CHECK: mla {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
+}
+
+uint16x4_t test_vmla_laneq_u16(uint16x4_t a, uint16x4_t b, uint16x8_t v) {
+  // CHECK-LABEL: test_vmla_laneq_u16
+  return vmla_laneq_u16(a, b, v, 7);
+  // CHECK: mla {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[7]
+}
+
+uint16x8_t test_vmlaq_laneq_u16(uint16x8_t a, uint16x8_t b, uint16x8_t v) {
+  // CHECK-LABEL: test_vmlaq_laneq_u16
+  return vmlaq_laneq_u16(a, b, v, 7);
+  // CHECK: mla {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[7]
+}
+
+uint32x2_t test_vmla_laneq_u32(uint32x2_t a, uint32x2_t b, uint32x4_t v) {
+  // CHECK-LABEL: test_vmla_laneq_u32
+  return vmla_laneq_u32(a, b, v, 3);
+  // CHECK: mla {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[3]
+}
+
+uint32x4_t test_vmlaq_laneq_u32(uint32x4_t a, uint32x4_t b, uint32x4_t v) {
+  // CHECK-LABEL: test_vmlaq_laneq_u32
+  return vmlaq_laneq_u32(a, b, v, 3);
+  // CHECK: mla {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[3]
+}
+
+int32x4_t test_vqdmlal_laneq_s16(int32x4_t a, int16x4_t b, int16x8_t v) {
+  // CHECK-LABEL: test_vqdmlal_laneq_s16
+  return vqdmlal_laneq_s16(a, b, v, 7);
+  // CHECK: sqdmlal {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[7]
+}
+
+int64x2_t test_vqdmlal_laneq_s32(int64x2_t a, int32x2_t b, int32x4_t v) {
+  // CHECK-LABEL: test_vqdmlal_laneq_s32
+  return vqdmlal_laneq_s32(a, b, v, 3);
+  // CHECK: sqdmlal {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[3]
+}
+
+int32x4_t test_vqdmlal_high_laneq_s16(int32x4_t a, int16x8_t b, int16x8_t v) {
+  // CHECK-LABEL: test_vqdmlal_high_laneq_s16
+  return vqdmlal_high_laneq_s16(a, b, v, 7);
+  // CHECK: sqdmlal2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[7]
+}
+
+int64x2_t test_vqdmlal_high_laneq_s32(int64x2_t a, int32x4_t b, int32x4_t v) {
+  // CHECK-LABEL: test_vqdmlal_high_laneq_s32
+  return vqdmlal_high_laneq_s32(a, b, v, 3);
+  // CHECK: sqdmlal2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[3]
+}
+
+uint16x4_t test_vmls_lane_u16(uint16x4_t a, uint16x4_t b, uint16x4_t v) {
+  // CHECK-LABEL: test_vmls_lane_u16
+  return vmls_lane_u16(a, b, v, 3);
+  // CHECK: mls {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[3]
+}
+
+uint16x8_t test_vmlsq_lane_u16(uint16x8_t a, uint16x8_t b, uint16x4_t v) {
+  // CHECK-LABEL: test_vmlsq_lane_u16
+  return vmlsq_lane_u16(a, b, v, 3);
+  // CHECK: mls {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[3]
+}
+
+uint32x2_t test_vmls_lane_u32(uint32x2_t a, uint32x2_t b, uint32x2_t v) {
+  // CHECK-LABEL: test_vmls_lane_u32
+  return vmls_lane_u32(a, b, v, 1);
+  // CHECK: mls {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
+}
+
+uint32x4_t test_vmlsq_lane_u32(uint32x4_t a, uint32x4_t b, uint32x2_t v) {
+  // CHECK-LABEL: test_vmlsq_lane_u32
+  return vmlsq_lane_u32(a, b, v, 1);
+  // CHECK: mls {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
+}
+
+uint16x4_t test_vmls_laneq_u16(uint16x4_t a, uint16x4_t b, uint16x8_t v) {
+  // CHECK-LABEL: test_vmls_laneq_u16
+  return vmls_laneq_u16(a, b, v, 7);
+  // CHECK: mls {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[7]
+}
+
+uint16x8_t test_vmlsq_laneq_u16(uint16x8_t a, uint16x8_t b, uint16x8_t v) {
+  // CHECK-LABEL: test_vmlsq_laneq_u16
+  return vmlsq_laneq_u16(a, b, v, 7);
+  // CHECK: mls {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[7]
+}
+
+uint32x2_t test_vmls_laneq_u32(uint32x2_t a, uint32x2_t b, uint32x4_t v) {
+  // CHECK-LABEL: test_vmls_laneq_u32
+  return vmls_laneq_u32(a, b, v, 3);
+  // CHECK: mls {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[3]
+}
+
+uint32x4_t test_vmlsq_laneq_u32(uint32x4_t a, uint32x4_t b, uint32x4_t v) {
+  // CHECK-LABEL: test_vmlsq_laneq_u32
+  return vmlsq_laneq_u32(a, b, v, 3);
+  // CHECK: mls {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[3]
+}
+
+int32x4_t test_vqdmlsl_laneq_s16(int32x4_t a, int16x4_t b, int16x8_t v) {
+  // CHECK-LABEL: test_vqdmlsl_laneq_s16
+  return vqdmlsl_laneq_s16(a, b, v, 7);
+  // CHECK: sqdmlsl {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[7]
+}
+
+int64x2_t test_vqdmlsl_laneq_s32(int64x2_t a, int32x2_t b, int32x4_t v) {
+  // CHECK-LABEL: test_vqdmlsl_laneq_s32
+  return vqdmlsl_laneq_s32(a, b, v, 3);
+  // CHECK: sqdmlsl {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[3]
+}
+
+int32x4_t test_vqdmlsl_high_laneq_s16(int32x4_t a, int16x8_t b, int16x8_t v) {
+  // CHECK-LABEL: test_vqdmlsl_high_laneq_s16
+  return vqdmlsl_high_laneq_s16(a, b, v, 7);
+  // CHECK: sqdmlsl2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[7]
+}
+
+int64x2_t test_vqdmlsl_high_laneq_s32(int64x2_t a, int32x4_t b, int32x4_t v) {
+  // CHECK-LABEL: test_vqdmlsl_high_laneq_s32
+  return vqdmlsl_high_laneq_s32(a, b, v, 3);
+  // CHECK: sqdmlsl2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[3]
+}
+
+int16x4_t test_vqdmulh_laneq_s16(int16x4_t a, int16x8_t v) {
+  // CHECK-LABEL: test_vqdmulh_laneq_s16
+  return vqdmulh_laneq_s16(a, v, 7);
+  // CHECK: sqdmulh {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[7]
+}
+
+int16x8_t test_vqdmulhq_laneq_s16(int16x8_t a, int16x8_t v) {
+  // CHECK-LABEL: test_vqdmulhq_laneq_s16
+  return vqdmulhq_laneq_s16(a, v, 7);
+  // CHECK: sqdmulh {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[7]
+}
+
+int32x2_t test_vqdmulh_laneq_s32(int32x2_t a, int32x4_t v) {
+  // CHECK-LABEL: test_vqdmulh_laneq_s32
+  return vqdmulh_laneq_s32(a, v, 3);
+  // CHECK: sqdmulh {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[3]
+}
+
+int32x4_t test_vqdmulhq_laneq_s32(int32x4_t a, int32x4_t v) {
+  // CHECK-LABEL: test_vqdmulhq_laneq_s32
+  return vqdmulhq_laneq_s32(a, v, 3);
+  // CHECK: sqdmulh {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[3]
+}
+
+int16x4_t test_vqrdmulh_laneq_s16(int16x4_t a, int16x8_t v) {
+  // CHECK-LABEL: test_vqrdmulh_laneq_s16
+  return vqrdmulh_laneq_s16(a, v, 7);
+  // CHECK: sqrdmulh {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.h[7]
+}
+
+int16x8_t test_vqrdmulhq_laneq_s16(int16x8_t a, int16x8_t v) {
+  // CHECK-LABEL: test_vqrdmulhq_laneq_s16
+  return vqrdmulhq_laneq_s16(a, v, 7);
+  // CHECK: sqrdmulh {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.h[7]
+}
+
+int32x2_t test_vqrdmulh_laneq_s32(int32x2_t a, int32x4_t v) {
+  // CHECK-LABEL: test_vqrdmulh_laneq_s32
+  return vqrdmulh_laneq_s32(a, v, 3);
+  // CHECK: sqrdmulh {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[3]
+}
+
+int32x4_t test_vqrdmulhq_laneq_s32(int32x4_t a, int32x4_t v) {
+  // CHECK-LABEL: test_vqrdmulhq_laneq_s32
+  return vqrdmulhq_laneq_s32(a, v, 3);
+  // CHECK: sqrdmulh {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[3]
 }
 
diff --git a/test/CodeGen/aarch64-neon-3v.c b/test/CodeGen/aarch64-neon-3v.c
new file mode 100644
index 0000000..ca32652
--- /dev/null
+++ b/test/CodeGen/aarch64-neon-3v.c
@@ -0,0 +1,486 @@
+// REQUIRES: aarch64-registered-target
+// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon -S -O3 -o - %s | FileCheck %s
+
+// Test new aarch64 intrinsics and types
+
+#include <arm_neon.h>
+
+int8x8_t test_vand_s8(int8x8_t a, int8x8_t b) {
+  // CHECK-LABEL: test_vand_s8
+  return vand_s8(a, b);
+  // CHECK: and {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+int8x16_t test_vandq_s8(int8x16_t a, int8x16_t b) {
+  // CHECK-LABEL: test_vandq_s8
+  return vandq_s8(a, b);
+  // CHECK: and {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+int16x4_t test_vand_s16(int16x4_t a, int16x4_t b) {
+  // CHECK-LABEL: test_vand_s16
+  return vand_s16(a, b);
+  // CHECK: and {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+int16x8_t test_vandq_s16(int16x8_t a, int16x8_t b) {
+  // CHECK-LABEL: test_vandq_s16
+  return vandq_s16(a, b);
+  // CHECK: and {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+int32x2_t test_vand_s32(int32x2_t a, int32x2_t b) {
+  // CHECK-LABEL: test_vand_s32
+  return vand_s32(a, b);
+  // CHECK: and {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+int32x4_t test_vandq_s32(int32x4_t a, int32x4_t b) {
+  // CHECK-LABEL: test_vandq_s32
+  return vandq_s32(a, b);
+  // CHECK: and {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+int64x1_t test_vand_s64(int64x1_t a, int64x1_t b) {
+  // CHECK-LABEL: test_vand_s64
+  return vand_s64(a, b);
+  // CHECK: and {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+int64x2_t test_vandq_s64(int64x2_t a, int64x2_t b) {
+  // CHECK-LABEL: test_vandq_s64
+  return vandq_s64(a, b);
+  // CHECK: and {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+uint8x8_t test_vand_u8(uint8x8_t a, uint8x8_t b) {
+  // CHECK-LABEL: test_vand_u8
+  return vand_u8(a, b);
+  // CHECK: and {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+uint8x16_t test_vandq_u8(uint8x16_t a, uint8x16_t b) {
+  // CHECK-LABEL: test_vandq_u8
+  return vandq_u8(a, b);
+  // CHECK: and {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+uint16x4_t test_vand_u16(uint16x4_t a, uint16x4_t b) {
+  // CHECK-LABEL: test_vand_u16
+  return vand_u16(a, b);
+  // CHECK: and {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+uint16x8_t test_vandq_u16(uint16x8_t a, uint16x8_t b) {
+  // CHECK-LABEL: test_vandq_u16
+  return vandq_u16(a, b);
+  // CHECK: and {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+uint32x2_t test_vand_u32(uint32x2_t a, uint32x2_t b) {
+  // CHECK-LABEL: test_vand_u32
+  return vand_u32(a, b);
+  // CHECK: and {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+uint32x4_t test_vandq_u32(uint32x4_t a, uint32x4_t b) {
+  // CHECK-LABEL: test_vandq_u32
+  return vandq_u32(a, b);
+  // CHECK: and {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+uint64x1_t test_vand_u64(uint64x1_t a, uint64x1_t b) {
+  // CHECK-LABEL: test_vand_u64
+  return vand_u64(a, b);
+  // CHECK: and {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+uint64x2_t test_vandq_u64(uint64x2_t a, uint64x2_t b) {
+  // CHECK-LABEL: test_vandq_u64
+  return vandq_u64(a, b);
+  // CHECK: and {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+int8x8_t test_vorr_s8(int8x8_t a, int8x8_t b) {
+  // CHECK-LABEL: test_vorr_s8
+  return vorr_s8(a, b);
+  // CHECK: orr {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+int8x16_t test_vorrq_s8(int8x16_t a, int8x16_t b) {
+  // CHECK-LABEL: test_vorrq_s8
+  return vorrq_s8(a, b);
+  // CHECK: orr {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+int16x4_t test_vorr_s16(int16x4_t a, int16x4_t b) {
+  // CHECK-LABEL: test_vorr_s16
+  return vorr_s16(a, b);
+  // CHECK: orr {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+int16x8_t test_vorrq_s16(int16x8_t a, int16x8_t b) {
+  // CHECK-LABEL: test_vorrq_s16
+  return vorrq_s16(a, b);
+  // CHECK: orr {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+int32x2_t test_vorr_s32(int32x2_t a, int32x2_t b) {
+  // CHECK-LABEL: test_vorr_s32
+  return vorr_s32(a, b);
+  // CHECK: orr {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+int32x4_t test_vorrq_s32(int32x4_t a, int32x4_t b) {
+  // CHECK-LABEL: test_vorrq_s32
+  return vorrq_s32(a, b);
+  // CHECK: orr {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+int64x1_t test_vorr_s64(int64x1_t a, int64x1_t b) {
+  // CHECK-LABEL: test_vorr_s64
+  return vorr_s64(a, b);
+  // CHECK: orr {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+int64x2_t test_vorrq_s64(int64x2_t a, int64x2_t b) {
+  // CHECK-LABEL: test_vorrq_s64
+  return vorrq_s64(a, b);
+  // CHECK: orr {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+uint8x8_t test_vorr_u8(uint8x8_t a, uint8x8_t b) {
+  // CHECK-LABEL: test_vorr_u8
+  return vorr_u8(a, b);
+  // CHECK: orr {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+uint8x16_t test_vorrq_u8(uint8x16_t a, uint8x16_t b) {
+  // CHECK-LABEL: test_vorrq_u8
+  return vorrq_u8(a, b);
+  // CHECK: orr {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+uint16x4_t test_vorr_u16(uint16x4_t a, uint16x4_t b) {
+  // CHECK-LABEL: test_vorr_u16
+  return vorr_u16(a, b);
+  // CHECK: orr {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+uint16x8_t test_vorrq_u16(uint16x8_t a, uint16x8_t b) {
+  // CHECK-LABEL: test_vorrq_u16
+  return vorrq_u16(a, b);
+  // CHECK: orr {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+uint32x2_t test_vorr_u32(uint32x2_t a, uint32x2_t b) {
+  // CHECK-LABEL: test_vorr_u32
+  return vorr_u32(a, b);
+  // CHECK: orr {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+uint32x4_t test_vorrq_u32(uint32x4_t a, uint32x4_t b) {
+  // CHECK-LABEL: test_vorrq_u32
+  return vorrq_u32(a, b);
+  // CHECK: orr {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+uint64x1_t test_vorr_u64(uint64x1_t a, uint64x1_t b) {
+  // CHECK-LABEL: test_vorr_u64
+  return vorr_u64(a, b);
+  // CHECK: orr {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+uint64x2_t test_vorrq_u64(uint64x2_t a, uint64x2_t b) {
+  // CHECK-LABEL: test_vorrq_u64
+  return vorrq_u64(a, b);
+  // CHECK: orr {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+int8x8_t test_veor_s8(int8x8_t a, int8x8_t b) {
+  // CHECK-LABEL: test_veor_s8
+  return veor_s8(a, b);
+  // CHECK: eor {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+int8x16_t test_veorq_s8(int8x16_t a, int8x16_t b) {
+  // CHECK-LABEL: test_veorq_s8
+  return veorq_s8(a, b);
+  // CHECK: eor {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+int16x4_t test_veor_s16(int16x4_t a, int16x4_t b) {
+  // CHECK-LABEL: test_veor_s16
+  return veor_s16(a, b);
+  // CHECK: eor {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+int16x8_t test_veorq_s16(int16x8_t a, int16x8_t b) {
+  // CHECK-LABEL: test_veorq_s16
+  return veorq_s16(a, b);
+  // CHECK: eor {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+int32x2_t test_veor_s32(int32x2_t a, int32x2_t b) {
+  // CHECK-LABEL: test_veor_s32
+  return veor_s32(a, b);
+  // CHECK: eor {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+int32x4_t test_veorq_s32(int32x4_t a, int32x4_t b) {
+  // CHECK-LABEL: test_veorq_s32
+  return veorq_s32(a, b);
+  // CHECK: eor {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+int64x1_t test_veor_s64(int64x1_t a, int64x1_t b) {
+  // CHECK-LABEL: test_veor_s64
+  return veor_s64(a, b);
+  // CHECK: eor {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+int64x2_t test_veorq_s64(int64x2_t a, int64x2_t b) {
+  // CHECK-LABEL: test_veorq_s64
+  return veorq_s64(a, b);
+  // CHECK: eor {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+uint8x8_t test_veor_u8(uint8x8_t a, uint8x8_t b) {
+  // CHECK-LABEL: test_veor_u8
+  return veor_u8(a, b);
+  // CHECK: eor {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+uint8x16_t test_veorq_u8(uint8x16_t a, uint8x16_t b) {
+  // CHECK-LABEL: test_veorq_u8
+  return veorq_u8(a, b);
+  // CHECK: eor {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+uint16x4_t test_veor_u16(uint16x4_t a, uint16x4_t b) {
+  // CHECK-LABEL: test_veor_u16
+  return veor_u16(a, b);
+  // CHECK: eor {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+uint16x8_t test_veorq_u16(uint16x8_t a, uint16x8_t b) {
+  // CHECK-LABEL: test_veorq_u16
+  return veorq_u16(a, b);
+  // CHECK: eor {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+uint32x2_t test_veor_u32(uint32x2_t a, uint32x2_t b) {
+  // CHECK-LABEL: test_veor_u32
+  return veor_u32(a, b);
+  // CHECK: eor {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+uint32x4_t test_veorq_u32(uint32x4_t a, uint32x4_t b) {
+  // CHECK-LABEL: test_veorq_u32
+  return veorq_u32(a, b);
+  // CHECK: eor {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+uint64x1_t test_veor_u64(uint64x1_t a, uint64x1_t b) {
+  // CHECK-LABEL: test_veor_u64
+  return veor_u64(a, b);
+  // CHECK: eor {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+uint64x2_t test_veorq_u64(uint64x2_t a, uint64x2_t b) {
+  // CHECK-LABEL: test_veorq_u64
+  return veorq_u64(a, b);
+  // CHECK: eor {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+int8x8_t test_vbic_s8(int8x8_t a, int8x8_t b) {
+  // CHECK-LABEL: test_vbic_s8
+  return vbic_s8(a, b);
+  // CHECK: bic {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+int8x16_t test_vbicq_s8(int8x16_t a, int8x16_t b) {
+  // CHECK-LABEL: test_vbicq_s8
+  return vbicq_s8(a, b);
+  // CHECK: bic {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+int16x4_t test_vbic_s16(int16x4_t a, int16x4_t b) {
+  // CHECK-LABEL: test_vbic_s16
+  return vbic_s16(a, b);
+  // CHECK: bic {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+int16x8_t test_vbicq_s16(int16x8_t a, int16x8_t b) {
+  // CHECK-LABEL: test_vbicq_s16
+  return vbicq_s16(a, b);
+  // CHECK: bic {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+int32x2_t test_vbic_s32(int32x2_t a, int32x2_t b) {
+  // CHECK-LABEL: test_vbic_s32
+  return vbic_s32(a, b);
+  // CHECK: bic {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+int32x4_t test_vbicq_s32(int32x4_t a, int32x4_t b) {
+  // CHECK-LABEL: test_vbicq_s32
+  return vbicq_s32(a, b);
+  // CHECK: bic {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+int64x1_t test_vbic_s64(int64x1_t a, int64x1_t b) {
+  // CHECK-LABEL: test_vbic_s64
+  return vbic_s64(a, b);
+  // CHECK: bic {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+int64x2_t test_vbicq_s64(int64x2_t a, int64x2_t b) {
+  // CHECK-LABEL: test_vbicq_s64
+  return vbicq_s64(a, b);
+  // CHECK: bic {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+uint8x8_t test_vbic_u8(uint8x8_t a, uint8x8_t b) {
+  // CHECK-LABEL: test_vbic_u8
+  return vbic_u8(a, b);
+  // CHECK: bic {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+uint8x16_t test_vbicq_u8(uint8x16_t a, uint8x16_t b) {
+  // CHECK-LABEL: test_vbicq_u8
+  return vbicq_u8(a, b);
+  // CHECK: bic {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+uint16x4_t test_vbic_u16(uint16x4_t a, uint16x4_t b) {
+  // CHECK-LABEL: test_vbic_u16
+  return vbic_u16(a, b);
+  // CHECK: bic {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+uint16x8_t test_vbicq_u16(uint16x8_t a, uint16x8_t b) {
+  // CHECK-LABEL: test_vbicq_u16
+  return vbicq_u16(a, b);
+  // CHECK: bic {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+uint32x2_t test_vbic_u32(uint32x2_t a, uint32x2_t b) {
+  // CHECK-LABEL: test_vbic_u32
+  return vbic_u32(a, b);
+  // CHECK: bic {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+uint32x4_t test_vbicq_u32(uint32x4_t a, uint32x4_t b) {
+  // CHECK-LABEL: test_vbicq_u32
+  return vbicq_u32(a, b);
+  // CHECK: bic {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+uint64x1_t test_vbic_u64(uint64x1_t a, uint64x1_t b) {
+  // CHECK-LABEL: test_vbic_u64
+  return vbic_u64(a, b);
+  // CHECK: bic {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+uint64x2_t test_vbicq_u64(uint64x2_t a, uint64x2_t b) {
+  // CHECK-LABEL: test_vbicq_u64
+  return vbicq_u64(a, b);
+  // CHECK: bic {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+int8x8_t test_vorn_s8(int8x8_t a, int8x8_t b) {
+  // CHECK-LABEL: test_vorn_s8
+  return vorn_s8(a, b);
+  // CHECK: orn {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+int8x16_t test_vornq_s8(int8x16_t a, int8x16_t b) {
+  // CHECK-LABEL: test_vornq_s8
+  return vornq_s8(a, b);
+  // CHECK: orn {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+int16x4_t test_vorn_s16(int16x4_t a, int16x4_t b) {
+  // CHECK-LABEL: test_vorn_s16
+  return vorn_s16(a, b);
+  // CHECK: orn {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+int16x8_t test_vornq_s16(int16x8_t a, int16x8_t b) {
+  // CHECK-LABEL: test_vornq_s16
+  return vornq_s16(a, b);
+  // CHECK: orn {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+int32x2_t test_vorn_s32(int32x2_t a, int32x2_t b) {
+  // CHECK-LABEL: test_vorn_s32
+  return vorn_s32(a, b);
+  // CHECK: orn {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+int32x4_t test_vornq_s32(int32x4_t a, int32x4_t b) {
+  // CHECK-LABEL: test_vornq_s32
+  return vornq_s32(a, b);
+  // CHECK: orn {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+int64x1_t test_vorn_s64(int64x1_t a, int64x1_t b) {
+  // CHECK-LABEL: test_vorn_s64
+  return vorn_s64(a, b);
+  // CHECK: orn {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+int64x2_t test_vornq_s64(int64x2_t a, int64x2_t b) {
+  // CHECK-LABEL: test_vornq_s64
+  return vornq_s64(a, b);
+  // CHECK: orn {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+uint8x8_t test_vorn_u8(uint8x8_t a, uint8x8_t b) {
+  // CHECK-LABEL: test_vorn_u8
+  return vorn_u8(a, b);
+  // CHECK: orn {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+uint8x16_t test_vornq_u8(uint8x16_t a, uint8x16_t b) {
+  // CHECK-LABEL: test_vornq_u8
+  return vornq_u8(a, b);
+  // CHECK: orn {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+uint16x4_t test_vorn_u16(uint16x4_t a, uint16x4_t b) {
+  // CHECK-LABEL: test_vorn_u16
+  return vorn_u16(a, b);
+  // CHECK: orn {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+uint16x8_t test_vornq_u16(uint16x8_t a, uint16x8_t b) {
+  // CHECK-LABEL: test_vornq_u16
+  return vornq_u16(a, b);
+  // CHECK: orn {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+uint32x2_t test_vorn_u32(uint32x2_t a, uint32x2_t b) {
+  // CHECK-LABEL: test_vorn_u32
+  return vorn_u32(a, b);
+  // CHECK: orn {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+uint32x4_t test_vornq_u32(uint32x4_t a, uint32x4_t b) {
+  // CHECK-LABEL: test_vornq_u32
+  return vornq_u32(a, b);
+  // CHECK: orn {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+uint64x1_t test_vorn_u64(uint64x1_t a, uint64x1_t b) {
+  // CHECK-LABEL: test_vorn_u64
+  return vorn_u64(a, b);
+  // CHECK: orn {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+uint64x2_t test_vornq_u64(uint64x2_t a, uint64x2_t b) {
+  // CHECK-LABEL: test_vornq_u64
+  return vornq_u64(a, b);
+  // CHECK: orn {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
diff --git a/test/CodeGen/aarch64-neon-across.c b/test/CodeGen/aarch64-neon-across.c
index 257b839..00eb2e4 100644
--- a/test/CodeGen/aarch64-neon-across.c
+++ b/test/CodeGen/aarch64-neon-across.c
@@ -1,5 +1,5 @@
 // REQUIRES: aarch64-registered-target
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +neon \
+// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \
 // RUN:   -ffp-contract=fast -S -O3 -o - %s | FileCheck %s
 
 // Test new aarch64 intrinsics and types
@@ -7,265 +7,265 @@
 #include <arm_neon.h>
 
 int16_t test_vaddlv_s8(int8x8_t a) {
-  // CHECK: test_vaddlv_s8
+  // CHECK-LABEL: test_vaddlv_s8
   return vaddlv_s8(a);
   // CHECK: saddlv {{h[0-9]+}}, {{v[0-9]+}}.8b
 }
 
 int32_t test_vaddlv_s16(int16x4_t a) {
-  // CHECK: test_vaddlv_s16
+  // CHECK-LABEL: test_vaddlv_s16
   return vaddlv_s16(a);
   // CHECK: saddlv {{s[0-9]+}}, {{v[0-9]+}}.4h
 }
 
 uint16_t test_vaddlv_u8(uint8x8_t a) {
-  // CHECK: test_vaddlv_u8
+  // CHECK-LABEL: test_vaddlv_u8
   return vaddlv_u8(a);
   // CHECK: uaddlv {{h[0-9]+}}, {{v[0-9]+}}.8b
 }
 
 uint32_t test_vaddlv_u16(uint16x4_t a) {
-  // CHECK: test_vaddlv_u16
+  // CHECK-LABEL: test_vaddlv_u16
   return vaddlv_u16(a);
   // CHECK: uaddlv {{s[0-9]+}}, {{v[0-9]+}}.4h
 }
 
 int16_t test_vaddlvq_s8(int8x16_t a) {
-  // CHECK: test_vaddlvq_s8
+  // CHECK-LABEL: test_vaddlvq_s8
   return vaddlvq_s8(a);
   // CHECK: saddlv {{h[0-9]+}}, {{v[0-9]+}}.16b
 }
 
 int32_t test_vaddlvq_s16(int16x8_t a) {
-  // CHECK: test_vaddlvq_s16
+  // CHECK-LABEL: test_vaddlvq_s16
   return vaddlvq_s16(a);
   // CHECK: saddlv {{s[0-9]+}}, {{v[0-9]+}}.8h
 }
 
 int64_t test_vaddlvq_s32(int32x4_t a) {
-  // CHECK: test_vaddlvq_s32
+  // CHECK-LABEL: test_vaddlvq_s32
   return vaddlvq_s32(a);
   // CHECK: saddlv {{d[0-9]+}}, {{v[0-9]+}}.4s
 }
 
 uint16_t test_vaddlvq_u8(uint8x16_t a) {
-  // CHECK: test_vaddlvq_u8
+  // CHECK-LABEL: test_vaddlvq_u8
   return vaddlvq_u8(a);
   // CHECK: uaddlv {{h[0-9]+}}, {{v[0-9]+}}.16b
 }
 
 uint32_t test_vaddlvq_u16(uint16x8_t a) {
-  // CHECK: test_vaddlvq_u16
+  // CHECK-LABEL: test_vaddlvq_u16
   return vaddlvq_u16(a);
   // CHECK: uaddlv {{s[0-9]+}}, {{v[0-9]+}}.8h
 }
 
 uint64_t test_vaddlvq_u32(uint32x4_t a) {
-  // CHECK: test_vaddlvq_u32
+  // CHECK-LABEL: test_vaddlvq_u32
   return vaddlvq_u32(a);
   // CHECK: uaddlv {{d[0-9]+}}, {{v[0-9]+}}.4s
 }
 
 int8_t test_vmaxv_s8(int8x8_t a) {
-  // CHECK: test_vmaxv_s8
+  // CHECK-LABEL: test_vmaxv_s8
   return vmaxv_s8(a);
   // CHECK: smaxv {{b[0-9]+}}, {{v[0-9]+}}.8b
 }
 
 int16_t test_vmaxv_s16(int16x4_t a) {
-  // CHECK: test_vmaxv_s16
+  // CHECK-LABEL: test_vmaxv_s16
   return vmaxv_s16(a);
   // CHECK: smaxv {{h[0-9]+}}, {{v[0-9]+}}.4h
 }
 
 uint8_t test_vmaxv_u8(uint8x8_t a) {
-  // CHECK: test_vmaxv_u8
+  // CHECK-LABEL: test_vmaxv_u8
   return vmaxv_u8(a);
   // CHECK: umaxv {{b[0-9]+}}, {{v[0-9]+}}.8b
 }
 
 uint16_t test_vmaxv_u16(uint16x4_t a) {
-  // CHECK: test_vmaxv_u16
+  // CHECK-LABEL: test_vmaxv_u16
   return vmaxv_u16(a);
   // CHECK: umaxv {{h[0-9]+}}, {{v[0-9]+}}.4h
 }
 
 int8_t test_vmaxvq_s8(int8x16_t a) {
-  // CHECK: test_vmaxvq_s8
+  // CHECK-LABEL: test_vmaxvq_s8
   return vmaxvq_s8(a);
   // CHECK: smaxv {{b[0-9]+}}, {{v[0-9]+}}.16b
 }
 
 int16_t test_vmaxvq_s16(int16x8_t a) {
-  // CHECK: test_vmaxvq_s16
+  // CHECK-LABEL: test_vmaxvq_s16
   return vmaxvq_s16(a);
   // CHECK: smaxv {{h[0-9]+}}, {{v[0-9]+}}.8h
 }
 
 int32_t test_vmaxvq_s32(int32x4_t a) {
-  // CHECK: test_vmaxvq_s32
+  // CHECK-LABEL: test_vmaxvq_s32
   return vmaxvq_s32(a);
   // CHECK: smaxv {{s[0-9]+}}, {{v[0-9]+}}.4s
 }
 
 uint8_t test_vmaxvq_u8(uint8x16_t a) {
-  // CHECK: test_vmaxvq_u8
+  // CHECK-LABEL: test_vmaxvq_u8
   return vmaxvq_u8(a);
   // CHECK: umaxv {{b[0-9]+}}, {{v[0-9]+}}.16b
 }
 
 uint16_t test_vmaxvq_u16(uint16x8_t a) {
-  // CHECK: test_vmaxvq_u16
+  // CHECK-LABEL: test_vmaxvq_u16
   return vmaxvq_u16(a);
   // CHECK: umaxv {{h[0-9]+}}, {{v[0-9]+}}.8h
 }
 
 uint32_t test_vmaxvq_u32(uint32x4_t a) {
-  // CHECK: test_vmaxvq_u32
+  // CHECK-LABEL: test_vmaxvq_u32
   return vmaxvq_u32(a);
   // CHECK: umaxv {{s[0-9]+}}, {{v[0-9]+}}.4s
 }
 
 int8_t test_vminv_s8(int8x8_t a) {
-  // CHECK: test_vminv_s8
+  // CHECK-LABEL: test_vminv_s8
   return vminv_s8(a);
   // CHECK: sminv {{b[0-9]+}}, {{v[0-9]+}}.8b
 }
 
 int16_t test_vminv_s16(int16x4_t a) {
-  // CHECK: test_vminv_s16
+  // CHECK-LABEL: test_vminv_s16
   return vminv_s16(a);
   // CHECK: sminv {{h[0-9]+}}, {{v[0-9]+}}.4h
 }
 
 uint8_t test_vminv_u8(uint8x8_t a) {
-  // CHECK: test_vminv_u8
+  // CHECK-LABEL: test_vminv_u8
   return vminv_u8(a);
   // CHECK: uminv {{b[0-9]+}}, {{v[0-9]+}}.8b
 }
 
 uint16_t test_vminv_u16(uint16x4_t a) {
-  // CHECK: test_vminv_u16
+  // CHECK-LABEL: test_vminv_u16
   return vminv_u16(a);
   // CHECK: uminv {{h[0-9]+}}, {{v[0-9]+}}.4h
 }
 
 int8_t test_vminvq_s8(int8x16_t a) {
-  // CHECK: test_vminvq_s8
+  // CHECK-LABEL: test_vminvq_s8
   return vminvq_s8(a);
   // CHECK: sminv {{b[0-9]+}}, {{v[0-9]+}}.16b
 }
 
 int16_t test_vminvq_s16(int16x8_t a) {
-  // CHECK: test_vminvq_s16
+  // CHECK-LABEL: test_vminvq_s16
   return vminvq_s16(a);
   // CHECK: sminv {{h[0-9]+}}, {{v[0-9]+}}.8h
 }
 
 int32_t test_vminvq_s32(int32x4_t a) {
-  // CHECK: test_vminvq_s32
+  // CHECK-LABEL: test_vminvq_s32
   return vminvq_s32(a);
   // CHECK: sminv {{s[0-9]+}}, {{v[0-9]+}}.4s
 }
 
 uint8_t test_vminvq_u8(uint8x16_t a) {
-  // CHECK: test_vminvq_u8
+  // CHECK-LABEL: test_vminvq_u8
   return vminvq_u8(a);
   // CHECK: uminv {{b[0-9]+}}, {{v[0-9]+}}.16b
 }
 
 uint16_t test_vminvq_u16(uint16x8_t a) {
-  // CHECK: test_vminvq_u16
+  // CHECK-LABEL: test_vminvq_u16
   return vminvq_u16(a);
   // CHECK: uminv {{h[0-9]+}}, {{v[0-9]+}}.8h
 }
 
 uint32_t test_vminvq_u32(uint32x4_t a) {
-  // CHECK: test_vminvq_u32
+  // CHECK-LABEL: test_vminvq_u32
   return vminvq_u32(a);
   // CHECK: uminv {{s[0-9]+}}, {{v[0-9]+}}.4s
 }
 
 int8_t test_vaddv_s8(int8x8_t a) {
-  // CHECK: test_vaddv_s8
+  // CHECK-LABEL: test_vaddv_s8
   return vaddv_s8(a);
   // CHECK: addv {{b[0-9]+}}, {{v[0-9]+}}.8b
 }
 
 int16_t test_vaddv_s16(int16x4_t a) {
-  // CHECK: test_vaddv_s16
+  // CHECK-LABEL: test_vaddv_s16
   return vaddv_s16(a);
   // CHECK: addv {{h[0-9]+}}, {{v[0-9]+}}.4h
 }
 
 uint8_t test_vaddv_u8(uint8x8_t a) {
-  // CHECK: test_vaddv_u8
+  // CHECK-LABEL: test_vaddv_u8
   return vaddv_u8(a);
   // CHECK: addv {{b[0-9]+}}, {{v[0-9]+}}.8b
 }
 
 uint16_t test_vaddv_u16(uint16x4_t a) {
-  // CHECK: test_vaddv_u16
+  // CHECK-LABEL: test_vaddv_u16
   return vaddv_u16(a);
   // CHECK: addv {{h[0-9]+}}, {{v[0-9]+}}.4h
 }
 
 int8_t test_vaddvq_s8(int8x16_t a) {
-  // CHECK: test_vaddvq_s8
+  // CHECK-LABEL: test_vaddvq_s8
   return vaddvq_s8(a);
   // CHECK: addv {{b[0-9]+}}, {{v[0-9]+}}.16b
 }
 
 int16_t test_vaddvq_s16(int16x8_t a) {
-  // CHECK: test_vaddvq_s16
+  // CHECK-LABEL: test_vaddvq_s16
   return vaddvq_s16(a);
   // CHECK: addv {{h[0-9]+}}, {{v[0-9]+}}.8h
 }
 
 int32_t test_vaddvq_s32(int32x4_t a) {
-  // CHECK: test_vaddvq_s32
+  // CHECK-LABEL: test_vaddvq_s32
   return vaddvq_s32(a);
   // CHECK: addv {{s[0-9]+}}, {{v[0-9]+}}.4s
 }
 
 uint8_t test_vaddvq_u8(uint8x16_t a) {
-  // CHECK: test_vaddvq_u8
+  // CHECK-LABEL: test_vaddvq_u8
   return vaddvq_u8(a);
   // CHECK: addv {{b[0-9]+}}, {{v[0-9]+}}.16b
 }
 
 uint16_t test_vaddvq_u16(uint16x8_t a) {
-  // CHECK: test_vaddvq_u16
+  // CHECK-LABEL: test_vaddvq_u16
   return vaddvq_u16(a);
   // CHECK: addv {{h[0-9]+}}, {{v[0-9]+}}.8h
 }
 
 uint32_t test_vaddvq_u32(uint32x4_t a) {
-  // CHECK: test_vaddvq_u32
+  // CHECK-LABEL: test_vaddvq_u32
   return vaddvq_u32(a);
   // CHECK: addv {{s[0-9]+}}, {{v[0-9]+}}.4s
 }
 
 float32_t test_vmaxvq_f32(float32x4_t a) {
-  // CHECK: test_vmaxvq_f32
+  // CHECK-LABEL: test_vmaxvq_f32
   return vmaxvq_f32(a);
   // CHECK: fmaxv {{s[0-9]+}}, {{v[0-9]+}}.4s
 }
 
 float32_t test_vminvq_f32(float32x4_t a) {
-  // CHECK: test_vminvq_f32
+  // CHECK-LABEL: test_vminvq_f32
   return vminvq_f32(a);
   // CHECK: fminv {{s[0-9]+}}, {{v[0-9]+}}.4s
 }
 
 float32_t test_vmaxnmvq_f32(float32x4_t a) {
-  // CHECK: test_vmaxnmvq_f32
+  // CHECK-LABEL: test_vmaxnmvq_f32
   return vmaxnmvq_f32(a);
   // CHECK: fmaxnmv {{s[0-9]+}}, {{v[0-9]+}}.4s
 }
 
 float32_t test_vminnmvq_f32(float32x4_t a) {
-  // CHECK: test_vminnmvq_f32
+  // CHECK-LABEL: test_vminnmvq_f32
   return vminnmvq_f32(a);
   // CHECK: fminnmv {{s[0-9]+}}, {{v[0-9]+}}.4s
 }
diff --git a/test/CodeGen/aarch64-neon-copy.c b/test/CodeGen/aarch64-neon-copy.c
deleted file mode 100644
index 7c77b17..0000000
--- a/test/CodeGen/aarch64-neon-copy.c
+++ /dev/null
@@ -1,1194 +0,0 @@
-// REQUIRES: aarch64-registered-target
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +neon \
-// RUN:   -ffp-contract=fast -S -O3 -o - %s | FileCheck %s
-
-// Test new aarch64 intrinsics and types
-
-#include <arm_neon.h>
-
-uint8x8_t test_vset_lane_u8(uint8_t v1, uint8x8_t v2) {
-   // CHECK: test_vset_lane_u8
-  return vset_lane_u8(v1, v2, 6);
-  // CHECK: ins {{v[0-9]+}}.b[6], {{w[0-9]+}}
-}
-
-uint16x4_t test_vset_lane_u16(uint16_t v1, uint16x4_t v2) {
-   // CHECK: test_vset_lane_u16
-  return vset_lane_u16(v1, v2, 2);
-  // CHECK: ins {{v[0-9]+}}.h[2], {{w[0-9]+}}
-}
-
-uint32x2_t test_vset_lane_u32(uint32_t v1, uint32x2_t v2) {
-   // CHECK: test_vset_lane_u32
-  return vset_lane_u32(v1, v2, 1);
-  // CHECK: ins {{v[0-9]+}}.s[1], {{w[0-9]+}}
-}
-uint64x1_t test_vset_lane_u64(uint64_t v1, uint64x1_t v2) {
-   // CHECK: test_vset_lane_u64
-  return vset_lane_u64(v1, v2, 0);
-  // CHECK: fmov {{d[0-9]+}}, {{x[0-9]+}}
-}
-
-int8x8_t test_vset_lane_s8(int8_t v1, int8x8_t v2) {
-   // CHECK: test_vset_lane_s8
-  return vset_lane_s8(v1, v2, 6);
-  // CHECK: ins {{v[0-9]+}}.b[6], {{w[0-9]+}}
-}
-
-int16x4_t test_vset_lane_s16(int16_t v1, int16x4_t v2) {
-   // CHECK: test_vset_lane_s16
-  return vset_lane_s16(v1, v2, 2);
-  // CHECK: ins {{v[0-9]+}}.h[2], {{w[0-9]+}}
-}
-
-int32x2_t test_vset_lane_s32(int32_t v1, int32x2_t v2) {
-   // CHECK: test_vset_lane_s32
-  return vset_lane_s32(v1, v2, 1);
-  // CHECK: ins {{v[0-9]+}}.s[1], {{w[0-9]+}}
-}
-
-  int64x1_t test_vset_lane_s64(int64_t v1, int64x1_t v2) {
-   // CHECK: test_vset_lane_s64
-  return vset_lane_s64(v1, v2, 0);
-  // CHECK: fmov {{d[0-9]+}}, {{x[0-9]+}}
-}
-
-uint8x16_t test_vsetq_lane_u8(uint8_t v1, uint8x16_t v2) {
-   // CHECK: test_vsetq_lane_u8
-  return vsetq_lane_u8(v1, v2, 6);
-  // CHECK: ins {{v[0-9]+}}.b[6], {{w[0-9]+}}
-}
-
-uint16x8_t test_vsetq_lane_u16(uint16_t v1, uint16x8_t v2) {
-   // CHECK: test_vsetq_lane_u16
-  return vsetq_lane_u16(v1, v2, 2);
-  // CHECK: ins {{v[0-9]+}}.h[2], {{w[0-9]+}}
-}
-
-uint32x4_t test_vsetq_lane_u32(uint32_t v1, uint32x4_t v2) {
-   // CHECK: test_vsetq_lane_u32
-  return vsetq_lane_u32(v1, v2, 1);
-  // CHECK: ins {{v[0-9]+}}.s[1], {{w[0-9]+}}
-}
-
-  uint64x2_t test_vsetq_lane_u64(uint64_t v1, uint64x2_t v2) {
-   // CHECK: test_vsetq_lane_u64
-  return vsetq_lane_u64(v1, v2, 1);
-  // CHECK: ins {{v[0-9]+}}.d[1], {{x[0-9]+}}
-}
-
-int8x16_t test_vsetq_lane_s8(int8_t v1, int8x16_t v2) {
-   // CHECK: test_vsetq_lane_s8
-  return vsetq_lane_s8(v1, v2, 6);
-  // CHECK: ins {{v[0-9]+}}.b[6], {{w[0-9]+}}
-}
-
-int16x8_t test_vsetq_lane_s16(int16_t v1, int16x8_t v2) {
-   // CHECK: test_vsetq_lane_s16
-  return vsetq_lane_s16(v1, v2, 2);
-  // CHECK: ins {{v[0-9]+}}.h[2], {{w[0-9]+}}
-}
-
-int32x4_t test_vsetq_lane_s32(int32_t v1, int32x4_t v2) {
-   // CHECK: test_vsetq_lane_s32
-  return vsetq_lane_s32(v1, v2, 1);
-  // CHECK: ins {{v[0-9]+}}.s[1], {{w[0-9]+}}
-}
-
-int64x2_t test_vsetq_lane_s64(int64_t v1, int64x2_t v2) {
-   // CHECK: test_vsetq_lane_s64
-  return vsetq_lane_s64(v1, v2, 0);
-  // CHECK: ins {{v[0-9]+}}.d[0], {{x[0-9]+}}
-}
-
-poly8x8_t test_vset_lane_p8(poly8_t v1, poly8x8_t v2) {
-   // CHECK: test_vset_lane_p8
-  return vset_lane_p8(v1, v2, 6);
-  // CHECK: ins {{v[0-9]+}}.b[6], {{w[0-9]+}}
-}
-
-poly16x4_t test_vset_lane_p16(poly16_t v1, poly16x4_t v2) {
-   // CHECK: test_vset_lane_p16
-  return vset_lane_p16(v1, v2, 2);
-  // CHECK: ins {{v[0-9]+}}.h[2], {{w[0-9]+}}
-}
-
-poly8x16_t test_vsetq_lane_p8(poly8_t v1, poly8x16_t v2) {
-   // CHECK: test_vsetq_lane_p8
-  return vsetq_lane_p8(v1, v2, 6);
-  // CHECK: ins {{v[0-9]+}}.b[6], {{w[0-9]+}}
-}
-
-poly16x8_t test_vsetq_lane_p16(poly16_t v1, poly16x8_t v2) {
-   // CHECK: test_vsetq_lane_p16
-  return vsetq_lane_p16(v1, v2, 2);
-  // CHECK: ins {{v[0-9]+}}.h[2], {{w[0-9]+}}
-}
-
-float32x2_t test_vset_lane_f32(float32_t v1, float32x2_t v2) {
-   // CHECK: test_vset_lane_f32
-  return vset_lane_f32(v1, v2, 1);
-  // CHECK: ins {{v[0-9]+}}.s[1], {{v[0-9]+}}.s[0]
-}
-
-float32x4_t test_vsetq_lane_f32(float32_t v1, float32x4_t v2) {
-   // CHECK: test_vsetq_lane_f32
-  return vsetq_lane_f32(v1, v2, 1);
-  // CHECK: ins {{v[0-9]+}}.s[1], {{v[0-9]+}}.s[0]
-}
-
-float64x1_t test_vset_lane_f64(float64_t v1, float64x1_t v2) {
-   // CHECK: test_vset_lane_f64
-  return vset_lane_f64(v1, v2, 0);
-  // CHECK: ret
-}
-
-float64x2_t test_vsetq_lane_f64(float64_t v1, float64x2_t v2) {
-   // CHECK: test_vsetq_lane_f64
-  return vsetq_lane_f64(v1, v2, 0);
-  // CHECK: ins {{v[0-9]+}}.d[0], {{v[0-9]+}}.d[0]
-}
-
-uint8_t test_vget_lane_u8(uint8x8_t v1) {
-  // CHECK: test_vget_lane_u8
-  return vget_lane_u8(v1, 7);
-  // CHECK: umov {{w[0-9]+}}, {{v[0-9]+}}.b[7]
-}
-
-uint16_t test_vget_lane_u16(uint16x4_t v1) {
-  // CHECK: test_vget_lane_u16
-  return vget_lane_u16(v1, 3);
-  // CHECK: umov {{w[0-9]+}}, {{v[0-9]+}}.h[3]
-}
-
-uint32_t test_vget_lane_u32(uint32x2_t v1) {
-  // CHECK: test_vget_lane_u32
-  return vget_lane_u32(v1, 1);
-  // CHECK: umov {{w[0-9]+}}, {{v[0-9]+}}.s[1]
-}
-
-uint64_t test_vget_lane_u64(uint64x1_t v1) {
-  // CHECK: test_vget_lane_u64
-  return vget_lane_u64(v1, 0);
-  // CHECK: fmov {{x[0-9]+}}, {{d[0-9]+}}
-}
-
-uint8_t test_vgetq_lane_u8(uint8x16_t v1) {
-  // CHECK: test_vgetq_lane_u8
-  return vgetq_lane_u8(v1, 15);
-  // CHECK: umov {{w[0-9]+}}, {{v[0-9]+}}.b[15]
-}
-
-uint16_t test_vgetq_lane_u16(uint16x8_t v1) {
-  // CHECK: test_vgetq_lane_u16
-  return vgetq_lane_u16(v1, 6);
-  // CHECK: umov {{w[0-9]+}}, {{v[0-9]+}}.h[6]
-}
-
-uint32_t test_vgetq_lane_u32(uint32x4_t v1) {
-  // CHECK: test_vgetq_lane_u32
-  return vgetq_lane_u32(v1, 2);
-  // CHECK: umov {{w[0-9]+}}, {{v[0-9]+}}.s[2]
-}
-
-uint64_t test_vgetq_lane_u64(uint64x2_t v1) {
-  // CHECK: test_vgetq_lane_u64
-  return vgetq_lane_u64(v1, 1);
-  // CHECK: umov {{x[0-9]+}}, {{v[0-9]+}}.d[1]
-}
-
-poly8_t test_vget_lane_p8(poly8x8_t v1) {
-  // CHECK: test_vget_lane_p8
-  return vget_lane_p8(v1, 7);
-  // CHECK: umov {{w[0-9]+}}, {{v[0-9]+}}.b[7]
-}
-
-poly16_t test_vget_lane_p16(poly16x4_t v1) {
-  // CHECK: test_vget_lane_p16
-  return vget_lane_p16(v1, 3);
-  // CHECK: umov {{w[0-9]+}}, {{v[0-9]+}}.h[3]
-}
-
-poly8_t test_vgetq_lane_p8(poly8x16_t v1) {
-  // CHECK: test_vgetq_lane_p8
-  return vgetq_lane_p8(v1, 14);
-  // CHECK: umov {{w[0-9]+}}, {{v[0-9]+}}.b[14]
-}
-
-poly16_t test_vgetq_lane_p16(poly16x8_t v1) {
-  // CHECK: test_vgetq_lane_p16
-  return vgetq_lane_p16(v1, 6);
-  // CHECK: umov {{w[0-9]+}}, {{v[0-9]+}}.h[6]
-}
-
-int32_t test_vget_lane_s8(int8x8_t v1) {
-  // CHECK: test_vget_lane_s8
-  return vget_lane_s8(v1, 7)+1;
-  // CHECK: smov {{w[0-9]+}}, {{v[0-9]+}}.b[7]
-}
-
-int32_t test_vget_lane_s16(int16x4_t v1) {
-  // CHECK: test_vget_lane_s16
-  return vget_lane_s16(v1, 3)+1;
-  // CHECK: smov {{w[0-9]+}}, {{v[0-9]+}}.h[3]
-}
-
-int64_t test_vget_lane_s32(int32x2_t v1) {
-  // CHECK: test_vget_lane_s32
-  return vget_lane_s32(v1, 1);
-  // CHECK: smov {{x[0-9]+}}, {{v[0-9]+}}.s[1]
-}
-
-int64_t test_vget_lane_s64(int64x1_t v1) {
-  // CHECK: test_vget_lane_s64
-  return vget_lane_s64(v1, 0);
-  // CHECK: fmov {{x[0-9]+}}, {{d[0-9]+}}
-}
-
-int32_t test_vgetq_lane_s8(int8x16_t v1) {
-  // CHECK: test_vgetq_lane_s8
-  return vgetq_lane_s8(v1, 15)+1;
-  // CHECK: smov {{w[0-9]+}}, {{v[0-9]+}}.b[15]
-}
-
-int32_t test_vgetq_lane_s16(int16x8_t v1) {
-  // CHECK: test_vgetq_lane_s16
-  return vgetq_lane_s16(v1, 6)+1;
-  // CHECK: smov {{w[0-9]+}}, {{v[0-9]+}}.h[6]
-}
-
-int64_t test_vgetq_lane_s32(int32x4_t v1) {
-  // CHECK: test_vgetq_lane_s32
-  return vgetq_lane_s32(v1, 2);
-  // CHECK: smov {{x[0-9]+}}, {{v[0-9]+}}.s[2]
-}
-
-int64_t test_vgetq_lane_s64(int64x2_t v1) {
-  // CHECK: test_vgetq_lane_s64
-  return vgetq_lane_s64(v1, 1);
-  // CHECK: umov {{x[0-9]+}}, {{v[0-9]+}}.d[1]
-}
-
-int8x8_t test_vcopy_lane_s8(int8x8_t v1, int8x8_t v2) {
-  // CHECK: test_vcopy_lane_s8
-  return vcopy_lane_s8(v1, 5, v2, 3);
-  // CHECK: ins {{v[0-9]+}}.b[5], {{v[0-9]+}}.b[3]
-}
-
-int16x4_t test_vcopy_lane_s16(int16x4_t v1, int16x4_t v2) {
-  // CHECK: test_vcopy_lane_s16
-  return vcopy_lane_s16(v1, 2, v2, 3);
-  // CHECK: ins {{v[0-9]+}}.h[2], {{v[0-9]+}}.h[3]
-}
-
-poly8x8_t test_vcopy_lane_p8(poly8x8_t v1, poly8x8_t v2) {
-  // CHECK: test_vcopy_lane_p8
-  return vcopy_lane_p8(v1, 5, v2, 3);
-  // CHECK: ins {{v[0-9]+}}.b[5], {{v[0-9]+}}.b[3]
-}
-
-poly16x4_t test_vcopy_lane_p16(poly16x4_t v1, poly16x4_t v2) {
-  // CHECK: test_vcopy_lane_p16
-  return vcopy_lane_p16(v1, 2, v2, 3);
-  // CHECK: ins {{v[0-9]+}}.h[2], {{v[0-9]+}}.h[3]
-}
-
-int32x2_t test_vcopy_lane_s32(int32x2_t v1, int32x2_t v2) {
-  // CHECK: test_vcopy_lane_s32
-  return vcopy_lane_s32(v1, 0, v2, 1);
-  // CHECK: ins {{v[0-9]+}}.s[0], {{v[0-9]+}}.s[1]
-}
-
-float32x2_t test_vcopy_lane_f32(float32x2_t v1, float32x2_t v2) {
-  // CHECK: test_vcopy_lane_f32
-  return vcopy_lane_f32(v1, 0, v2, 1);
-  // CHECK: ins {{v[0-9]+}}.s[0], {{v[0-9]+}}.s[1]
-}
-
-uint8x8_t test_vcopy_lane_u8(uint8x8_t v1, uint8x8_t v2) {
-  // CHECK: test_vcopy_lane_u8
-  return vcopy_lane_u8(v1, 5, v2, 3);
-  // CHECK: ins {{v[0-9]+}}.b[5], {{v[0-9]+}}.b[3]
-}
-
-uint16x4_t test_vcopy_lane_u16(uint16x4_t v1, uint16x4_t v2) {
-  // CHECK: test_vcopy_lane_u16
-  return vcopy_lane_u16(v1, 2, v2, 3);
-  // CHECK: ins {{v[0-9]+}}.h[2], {{v[0-9]+}}.h[3]
-}
-
-uint32x2_t test_vcopy_lane_u32(uint32x2_t v1, uint32x2_t v2) {
-  // CHECK: test_vcopy_lane_u32
-  return vcopy_lane_u32(v1, 0, v2, 1);
-  // CHECK: ins {{v[0-9]+}}.s[0], {{v[0-9]+}}.s[1]
-}
-
-int8x8_t test_vcopy_laneq_s8(int8x8_t v1, int8x16_t v2) {
-  // CHECK: test_vcopy_laneq_s8
-  return vcopy_laneq_s8(v1, 5, v2, 3);
-  // CHECK: ins {{v[0-9]+}}.b[5], {{v[0-9]+}}.b[3]
-}
-
-int16x4_t test_vcopy_laneq_s16(int16x4_t v1, int16x8_t v2) {
-  // CHECK: test_vcopy_laneq_s16
-  return vcopy_laneq_s16(v1, 2, v2, 3);
-  // CHECK: ins {{v[0-9]+}}.h[2], {{v[0-9]+}}.h[3]
-}
-
-poly8x8_t test_vcopy_laneq_p8(poly8x8_t v1, poly8x16_t v2) {
-  // CHECK: test_vcopy_laneq_p8
-  return vcopy_laneq_p8(v1, 5, v2, 3);
-  // CHECK: ins {{v[0-9]+}}.b[5], {{v[0-9]+}}.b[3]
-}
-
-poly16x4_t test_vcopy_laneq_p16(poly16x4_t v1, poly16x8_t v2) {
-  // CHECK: test_vcopy_laneq_p16
-  return vcopy_laneq_p16(v1, 2, v2, 3);
-  // CHECK: ins {{v[0-9]+}}.h[2], {{v[0-9]+}}.h[3]
-}
-
-int32x2_t test_vcopy_laneq_s32(int32x2_t v1, int32x4_t v2) {
-  // CHECK: test_vcopy_laneq_s32
-  return vcopy_laneq_s32(v1, 0, v2, 1);
-  // CHECK: ins {{v[0-9]+}}.s[0], {{v[0-9]+}}.s[1]
-}
-
-float32x2_t test_vcopy_laneq_f32(float32x2_t v1, float32x4_t v2) {
-  // CHECK: test_vcopy_laneq_f32
-  return vcopy_laneq_f32(v1, 0, v2, 1);
-  // CHECK: ins {{v[0-9]+}}.s[0], {{v[0-9]+}}.s[1]
-}
-
-uint8x8_t test_vcopy_laneq_u8(uint8x8_t v1, uint8x16_t v2) {
-  // CHECK: test_vcopy_laneq_u8
-  return vcopy_laneq_u8(v1, 5, v2, 3);
-  // CHECK: ins {{v[0-9]+}}.b[5], {{v[0-9]+}}.b[3]
-}
-
-uint16x4_t test_vcopy_laneq_u16(uint16x4_t v1, uint16x8_t v2) {
-  // CHECK: test_vcopy_laneq_u16
-  return vcopy_laneq_u16(v1, 2, v2, 3);
-  // CHECK: ins {{v[0-9]+}}.h[2], {{v[0-9]+}}.h[3]
-}
-
-uint32x2_t test_vcopy_laneq_u32(uint32x2_t v1, uint32x4_t v2) {
-  // CHECK: test_vcopy_laneq_u32
-  return vcopy_laneq_u32(v1, 0, v2, 1);
-  // CHECK: ins {{v[0-9]+}}.s[0], {{v[0-9]+}}.s[1]
-}
-
-int8x16_t test_vcopyq_lane_s8(int8x16_t v1, int8x8_t v2) {
-  // CHECK: test_vcopyq_lane_s8
-  return vcopyq_lane_s8(v1, 5, v2, 3);
-  // CHECK: ins {{v[0-9]+}}.b[5], {{v[0-9]+}}.b[3]
-}
-
-int16x8_t test_vcopyq_lane_s16(int16x8_t v1, int16x4_t v2) {
-  // CHECK: test_vcopyq_lane_s16
-  return vcopyq_lane_s16(v1, 2, v2, 3);
-  // CHECK: ins {{v[0-9]+}}.h[2], {{v[0-9]+}}.h[3]
-}
-
-poly8x16_t test_vcopyq_lane_p8(poly8x16_t v1, poly8x8_t v2) {
-  // CHECK: test_vcopyq_lane_p8
-  return vcopyq_lane_p8(v1, 5, v2, 3);
-  // CHECK: ins {{v[0-9]+}}.b[5], {{v[0-9]+}}.b[3]
-}
-
-poly16x8_t test_vcopyq_lane_p16(poly16x8_t v1, poly16x4_t v2) {
-  // CHECK: test_vcopyq_lane_p16
-  return vcopyq_lane_p16(v1, 2, v2, 3);
-  // CHECK: ins {{v[0-9]+}}.h[2], {{v[0-9]+}}.h[3]
-}
-
-int32x4_t test_vcopyq_lane_s32(int32x4_t v1, int32x2_t v2) {
-  // CHECK: test_vcopyq_lane_s32
-  return vcopyq_lane_s32(v1, 0, v2, 1);
-  // CHECK: ins {{v[0-9]+}}.s[0], {{v[0-9]+}}.s[1]
-}
-
-int64x2_t test_vcopyq_lane_s64(int64x2_t v1, int64x1_t v2) {
-  // CHECK: test_vcopyq_lane_s64
-  return vcopyq_lane_s64(v1, 1, v2, 0);
-  // CHECK: ins {{v[0-9]+}}.d[1], {{v[0-9]+}}.d[0]
-}
-
-float32x4_t test_vcopyq_lane_f32(float32x4_t v1, float32x2_t v2) {
-  // CHECK: test_vcopyq_lane_f32
-  return vcopyq_lane_f32(v1, 0, v2, 1);
-  // CHECK: ins {{v[0-9]+}}.s[0], {{v[0-9]+}}.s[1]
-}
-
-float64x2_t test_vcopyq_lane_f64(float64x2_t v1, float64x1_t v2) {
-  // CHECK: test_vcopyq_lane_f64
-  return vcopyq_lane_f64(v1, 1, v2, 0);
-  // CHECK: ins {{v[0-9]+}}.d[1], {{v[0-9]+}}.d[0]
-}
-
-uint8x16_t test_vcopyq_lane_u8(uint8x16_t v1, uint8x8_t v2) {
-  // CHECK: test_vcopyq_lane_u8
-  return vcopyq_lane_u8(v1, 5, v2, 3);
-  // CHECK: ins {{v[0-9]+}}.b[5], {{v[0-9]+}}.b[3]
-}
-
-uint16x8_t test_vcopyq_lane_u16(uint16x8_t v1, uint16x4_t v2) {
-  // CHECK: test_vcopyq_lane_u16
-  return vcopyq_lane_u16(v1, 2, v2, 3);
-  // CHECK: ins {{v[0-9]+}}.h[2], {{v[0-9]+}}.h[3]
-}
-
-uint32x4_t test_vcopyq_lane_u32(uint32x4_t v1, uint32x2_t v2) {
-  // CHECK: test_vcopyq_lane_u32
-  return vcopyq_lane_u32(v1, 0, v2, 1);
-  // CHECK: ins {{v[0-9]+}}.s[0], {{v[0-9]+}}.s[1]
-}
-
-uint64x2_t test_vcopyq_lane_u64(uint64x2_t v1, uint64x1_t v2) {
-  // CHECK: test_vcopyq_lane_u64
-  return vcopyq_lane_u64(v1, 1, v2, 0);
-  // CHECK: ins {{v[0-9]+}}.d[1], {{v[0-9]+}}.d[0]
-}
-
-int8x16_t test_vcopyq_laneq_s8(int8x16_t v1, int8x16_t v2) {
-  // CHECK: test_vcopyq_laneq_s8
-  return vcopyq_laneq_s8(v1, 5, v2, 3);
-  // CHECK: ins {{v[0-9]+}}.b[5], {{v[0-9]+}}.b[3]
-}
-
-int16x8_t test_vcopyq_laneq_s16(int16x8_t v1, int16x8_t v2) {
-  // CHECK: test_vcopyq_laneq_s16
-  return vcopyq_laneq_s16(v1, 2, v2, 3);
-  // CHECK: ins {{v[0-9]+}}.h[2], {{v[0-9]+}}.h[3]
-}
-
-poly8x16_t test_vcopyq_laneq_p8(poly8x16_t v1, poly8x16_t v2) {
-  // CHECK: test_vcopyq_laneq_p8
-  return vcopyq_laneq_p8(v1, 5, v2, 3);
-  // CHECK: ins {{v[0-9]+}}.b[5], {{v[0-9]+}}.b[3]
-}
-
-poly16x8_t test_vcopyq_laneq_p16(poly16x8_t v1, poly16x8_t v2) {
-  // CHECK: test_vcopyq_laneq_p16
-  return vcopyq_laneq_p16(v1, 2, v2, 3);
-  // CHECK: ins {{v[0-9]+}}.h[2], {{v[0-9]+}}.h[3]
-}
-
-int32x4_t test_vcopyq_laneq_s32(int32x4_t v1, int32x4_t v2) {
-  // CHECK: test_vcopyq_laneq_s32
-  return vcopyq_laneq_s32(v1, 0, v2, 1);
-  // CHECK: ins {{v[0-9]+}}.s[0], {{v[0-9]+}}.s[1]
-}
-
-float32x4_t test_vcopyq_laneq_f32(float32x4_t v1, float32x4_t v2) {
-  // CHECK: test_vcopyq_laneq_f32
-  return vcopyq_laneq_f32(v1, 0, v2, 1);
-  // CHECK: ins {{v[0-9]+}}.s[0], {{v[0-9]+}}.s[1]
-}
-
-int64x2_t test_vcopyq_laneq_s64(int64x2_t v1, int64x2_t v2) {
-  // CHECK: test_vcopyq_laneq_s64
-  return vcopyq_laneq_s64(v1, 1, v2, 1);
-  // CHECK: ins {{v[0-9]+}}.d[1], {{v[0-9]+}}.d[1]
-}
-
-uint8x16_t test_vcopyq_laneq_u8(uint8x16_t v1, uint8x16_t v2) {
-  // CHECK: test_vcopyq_laneq_u8
-  return vcopyq_laneq_u8(v1, 5, v2, 3);
-  // CHECK: ins {{v[0-9]+}}.b[5], {{v[0-9]+}}.b[3]
-}
-
-uint16x8_t test_vcopyq_laneq_u16(uint16x8_t v1, uint16x8_t v2) {
-  // CHECK: test_vcopyq_laneq_u16
-  return vcopyq_laneq_u16(v1, 2, v2, 3);
-  // CHECK: ins {{v[0-9]+}}.h[2], {{v[0-9]+}}.h[3]
-}
-
-uint32x4_t test_vcopyq_laneq_u32(uint32x4_t v1, uint32x4_t v2) {
-  // CHECK: test_vcopyq_laneq_u32
-  return vcopyq_laneq_u32(v1, 0, v2, 1);
-  // CHECK: ins {{v[0-9]+}}.s[0], {{v[0-9]+}}.s[1]
-}
-
-uint64x2_t test_vcopyq_laneq_u64(uint64x2_t v1, uint64x2_t v2) {
-  // CHECK: test_vcopyq_laneq_u64
-  return vcopyq_laneq_u64(v1, 0, v2, 1);
-  // CHECK: ins {{v[0-9]+}}.d[0], {{v[0-9]+}}.d[1]
-}
-
-int8x8_t test_vcreate_s8(uint64_t v1) {
-  // CHECK: test_vcreate_s8
-  return vcreate_s8(v1);
-  // CHECK: fmov {{d[0-9]+}}, {{x[0-9]+}}
-}
-
-int16x4_t test_vcreate_s16(uint64_t v1) {
-  // CHECK: test_vcreate_s16
-  return vcreate_s16(v1);
-  // CHECK: fmov {{d[0-9]+}}, {{x[0-9]+}}
-}
-
-int32x2_t test_vcreate_s32(uint64_t v1) {
-  // CHECK: test_vcreate_s32
-  return vcreate_s32(v1);
-  // CHECK: fmov {{d[0-9]+}}, {{x[0-9]+}}
-}
-
-int64x1_t test_vcreate_s64(uint64_t v1) {
-  // CHECK: test_vcreate_s64
-  return vcreate_s64(v1);
-  // CHECK: fmov {{d[0-9]+}}, {{x[0-9]+}}
-}
-
-uint8x8_t test_vcreate_u8(uint64_t v1) {
-  // CHECK: test_vcreate_u8
-  return vcreate_u8(v1);
-  // CHECK: fmov {{d[0-9]+}}, {{x[0-9]+}}
-}
-
-uint16x4_t test_vcreate_u16(uint64_t v1) {
-  // CHECK: test_vcreate_u16
-  return vcreate_u16(v1);
-  // CHECK: fmov {{d[0-9]+}}, {{x[0-9]+}}
-}
-
-uint32x2_t test_vcreate_u32(uint64_t v1) {
-  // CHECK: test_vcreate_u32
-  return vcreate_u32(v1);
-  // CHECK: fmov {{d[0-9]+}}, {{x[0-9]+}}
-}
-
-uint64x1_t test_vcreate_u64(uint64_t v1) {
-  // CHECK: test_vcreate_u64
-  return vcreate_u64(v1);
-  // CHECK: fmov {{d[0-9]+}}, {{x[0-9]+}}
-}
-
-poly8x8_t test_vcreate_p8(uint64_t v1) {
-  // CHECK: test_vcreate_p8
-  return vcreate_p8(v1);
-  // CHECK: fmov {{d[0-9]+}}, {{x[0-9]+}}
-}
-
-poly16x4_t test_vcreate_p16(uint64_t v1) {
-  // CHECK: test_vcreate_p16
-  return vcreate_p16(v1);
-  // CHECK: fmov {{d[0-9]+}}, {{x[0-9]+}}
-}
-
-float16x4_t test_vcreate_f16(uint64_t v1) {
-  // CHECK: test_vcreate_f16
-  return vcreate_f16(v1);
-  // CHECK: fmov {{d[0-9]+}}, {{x[0-9]+}}
-}
-
-float32x2_t test_vcreate_f32(uint64_t v1) {
-  // CHECK: test_vcreate_f32
-  return vcreate_f32(v1);
-  // CHECK: fmov {{d[0-9]+}}, {{x[0-9]+}}
-}
-
-float64x1_t test_vcreate_f64(uint64_t v1) {
-  // CHECK: test_vcreate_f64
-  return vcreate_f64(v1);
-  // CHECK: fmov {{d[0-9]+}}, {{x[0-9]+}}
-}
-
-uint8x8_t test_vdup_n_u8(uint8_t v1) {
-  // CHECK: test_vdup_n_u8
-  return vdup_n_u8(v1);
-  // CHECK: dup {{v[0-9]+}}.8b, {{w[0-9]+}}
-}
-
-uint16x4_t test_vdup_n_u16(uint16_t v1) {
-  // CHECK: test_vdup_n_u16
-  return vdup_n_u16(v1);
-  // CHECK: dup {{v[0-9]+}}.4h, {{w[0-9]+}}
-}
-
-uint32x2_t test_vdup_n_u32(uint32_t v1) {
-  // CHECK: test_vdup_n_u32
-  return vdup_n_u32(v1);
-  // CHECK: dup {{v[0-9]+}}.2s, {{w[0-9]+}}
-}
-
-uint64x1_t test_vdup_n_u64(uint64_t v1) {
-  // CHECK: test_vdup_n_u64
-  return vdup_n_u64(v1);
-  // CHECK: fmov {{d[0-9]+}}, {{x[0-9]+}}
-}
-
-uint8x16_t test_vdupq_n_u8(uint8_t v1) {
-  // CHECK: test_vdupq_n_u8
-  return vdupq_n_u8(v1);
-  // CHECK: dup {{v[0-9]+}}.16b, {{w[0-9]+}}
-}
-
-uint16x8_t test_vdupq_n_u16(uint16_t v1) {
-  // CHECK: test_vdupq_n_u16
-  return vdupq_n_u16(v1);
-  // CHECK: dup {{v[0-9]+}}.8h, {{w[0-9]+}}
-}
-
-uint32x4_t test_vdupq_n_u32(uint32_t v1) {
-  // CHECK: test_vdupq_n_u32
-  return vdupq_n_u32(v1);
-  // CHECK: dup {{v[0-9]+}}.4s, {{w[0-9]+}}
-}
-
-uint64x2_t test_vdupq_n_u64(uint64_t v1) {
-  // CHECK: test_vdupq_n_u64
-  return vdupq_n_u64(v1);
-  // CHECK: dup {{v[0-9]+}}.2d, {{x[0-9]+}}
-}
-
-int8x8_t test_vdup_n_s8(int8_t v1) {
-  // CHECK: test_vdup_n_s8
-  return vdup_n_s8(v1);
-  // CHECK: dup {{v[0-9]+}}.8b, {{w[0-9]+}}
-}
-
-int16x4_t test_vdup_n_s16(int16_t v1) {
-  // CHECK: test_vdup_n_s16
-  return vdup_n_s16(v1);
-  // CHECK: dup {{v[0-9]+}}.4h, {{w[0-9]+}}
-}
-
-int32x2_t test_vdup_n_s32(int32_t v1) {
-  // CHECK: test_vdup_n_s32
-  return vdup_n_s32(v1);
-  // CHECK: dup {{v[0-9]+}}.2s, {{w[0-9]+}}
-}
-
-int64x1_t test_vdup_n_s64(int64_t v1) {
-  // CHECK: test_vdup_n_s64
-  return vdup_n_s64(v1);
-  // CHECK: fmov {{d[0-9]+}}, {{x[0-9]+}}
-}
-
-int8x16_t test_vdupq_n_s8(int8_t v1) {
-  // CHECK: test_vdupq_n_s8
-  return vdupq_n_s8(v1);
-  // CHECK: dup {{v[0-9]+}}.16b, {{w[0-9]+}}
-}
-
-int16x8_t test_vdupq_n_s16(int16_t v1) {
-  // CHECK: test_vdupq_n_s16
-  return vdupq_n_s16(v1);
-  // CHECK: dup {{v[0-9]+}}.8h, {{w[0-9]+}}
-}
-
-int32x4_t test_vdupq_n_s32(int32_t v1) {
-  // CHECK: test_vdupq_n_s32
-  return vdupq_n_s32(v1);
-  // CHECK: dup {{v[0-9]+}}.4s, {{w[0-9]+}}
-}
-
-int64x2_t test_vdupq_n_s64(int64_t v1) {
-  // CHECK: test_vdupq_n_s64
-  return vdupq_n_s64(v1);
-  // CHECK: dup {{v[0-9]+}}.2d, {{x[0-9]+}}
-}
-
-poly8x8_t test_vdup_n_p8(poly8_t v1) {
-  // CHECK: test_vdup_n_p8
-  return vdup_n_p8(v1);
-  // CHECK: dup {{v[0-9]+}}.8b, {{w[0-9]+}}
-}
-
-poly16x4_t test_vdup_n_p16(poly16_t v1) {
-  // CHECK: test_vdup_n_p16
-  return vdup_n_p16(v1);
-  // CHECK: dup {{v[0-9]+}}.4h, {{w[0-9]+}}
-}
-
-poly8x16_t test_vdupq_n_p8(poly8_t v1) {
-  // CHECK: test_vdupq_n_p8
-  return vdupq_n_p8(v1);
-  // CHECK: dup {{v[0-9]+}}.16b, {{w[0-9]+}}
-}
-
-poly16x8_t test_vdupq_n_p16(poly16_t v1) {
-  // CHECK: test_vdupq_n_p16
-  return vdupq_n_p16(v1);
-  // CHECK: dup {{v[0-9]+}}.8h, {{w[0-9]+}}
-}
-
-float32x2_t test_vdup_n_f32(float32_t v1) {
-  // CHECK: test_vdup_n_f32
-  return vdup_n_f32(v1);
-  // CHECK: dup {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
-}
-
-float64x1_t test_vdup_n_f64(float64_t v1) {
-  // CHECK: test_vdup_n_f64
-  return vdup_n_f64(v1);
-  // CHECK: ret
-}
-
-float32x4_t test_vdupq_n_f32(float32_t v1) {
-  // CHECK: test_vdupq_n_f32
-  return vdupq_n_f32(v1);
-  // CHECK: dup {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
-}
-
-float64x2_t test_vdupq_n_f64(float64_t v1) {
-  // CHECK: test_vdupq_n_f64
-  return vdupq_n_f64(v1);
-  // CHECK: dup {{v[0-9]+}}.2d, {{v[0-9]+}}.d[0]
-}
-
-int8x8_t test_vdup_lane_s8(int8x8_t v1) {
-  // CHECK: test_vdup_lane_s8
-  return vdup_lane_s8(v1, 5);
-  // CHECK: dup {{v[0-9]+}}.8b, {{v[0-9]+}}.b[5]
-}
-
-int16x4_t test_vdup_lane_s16(int16x4_t v1) {
-  // CHECK: test_vdup_lane_s16
-  return vdup_lane_s16(v1, 2);
-  // CHECK: dup {{v[0-9]+}}.4h, {{v[0-9]+}}.h[2]
-}
-
-int32x2_t test_vdup_lane_s32(int32x2_t v1) {
-  // CHECK: test_vdup_lane_s32
-  return vdup_lane_s32(v1, 1);
-  // CHECK: dup {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
-}
-
-int64x1_t test_vdup_lane_s64(int64x1_t v1) {
-  // CHECK: test_vdup_lane_s64
-  return vdup_lane_s64(v1, 0);
-  // CHECK: ret
-}
-
-int8x16_t test_vdupq_lane_s8(int8x8_t v1) {
-  // CHECK: test_vdupq_lane_s8
-  return vdupq_lane_s8(v1, 5);
-  // CHECK: dup {{v[0-9]+}}.16b, {{v[0-9]+}}.b[5]
-}
-
-int16x8_t test_vdupq_lane_s16(int16x4_t v1) {
-  // CHECK: test_vdupq_lane_s16
-  return vdupq_lane_s16(v1, 2);
-  // CHECK: dup {{v[0-9]+}}.8h, {{v[0-9]+}}.h[2]
-}
-
-int32x4_t test_vdupq_lane_s32(int32x2_t v1) {
-  // CHECK: test_vdupq_lane_s32
-  return vdupq_lane_s32(v1, 1);
-  // CHECK: dup {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
-}
-
-int64x2_t test_vdupq_lane_s64(int64x1_t v1) {
-  // CHECK: test_vdupq_lane_s64
-  return vdupq_lane_s64(v1, 0);
-  // CHECK: dup {{v[0-9]+}}.2d, {{v[0-9]+}}.d[0]
-}
-
-uint8x8_t test_vdup_lane_u8(uint8x8_t v1) {
-  // CHECK: test_vdup_lane_u8
-  return vdup_lane_u8(v1, 5);
-  // CHECK: dup {{v[0-9]+}}.8b, {{v[0-9]+}}.b[5]
-}
-
-uint16x4_t test_vdup_lane_u16(uint16x4_t v1) {
-  // CHECK: test_vdup_lane_u16
-  return vdup_lane_u16(v1, 2);
-  // CHECK: dup {{v[0-9]+}}.4h, {{v[0-9]+}}.h[2]
-}
-
-uint32x2_t test_vdup_lane_u32(uint32x2_t v1) {
-  // CHECK: test_vdup_lane_u32
-  return vdup_lane_u32(v1, 1);
-  // CHECK: dup {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
-}
-
-uint64x1_t test_vdup_lane_u64(uint64x1_t v1) {
-  // CHECK: test_vdup_lane_u64
-  return vdup_lane_u64(v1, 0);
-  // CHECK: ret
-}
-
-uint8x16_t test_vdupq_lane_u8(uint8x8_t v1) {
-  // CHECK: test_vdupq_lane_u8
-  return vdupq_lane_u8(v1, 5);
-  // CHECK: dup {{v[0-9]+}}.16b, {{v[0-9]+}}.b[5]
-}
-
-uint16x8_t test_vdupq_lane_u16(uint16x4_t v1) {
-  // CHECK: test_vdupq_lane_u16
-  return vdupq_lane_u16(v1, 2);
-  // CHECK: dup {{v[0-9]+}}.8h, {{v[0-9]+}}.h[2]
-}
-
-uint32x4_t test_vdupq_lane_u32(uint32x2_t v1) {
-  // CHECK: test_vdupq_lane_u32
-  return vdupq_lane_u32(v1, 1);
-  // CHECK: dup {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
-}
-
-uint64x2_t test_vdupq_lane_u64(uint64x1_t v1) {
-  // CHECK: test_vdupq_lane_u64
-  return vdupq_lane_u64(v1, 0);
-  // CHECK: dup {{v[0-9]+}}.2d, {{v[0-9]+}}.d[0]
-}
-
-int8x8_t test_vdup_laneq_s8(int8x16_t v1) {
-  // CHECK: test_vdup_laneq_s8
-  return vdup_laneq_s8(v1, 5);
-  // CHECK: dup {{v[0-9]+}}.8b, {{v[0-9]+}}.b[5]
-}
-
-int16x4_t test_vdup_laneq_s16(int16x8_t v1) {
-  // CHECK: test_vdup_laneq_s16
-  return vdup_laneq_s16(v1, 2);
-  // CHECK: dup {{v[0-9]+}}.4h, {{v[0-9]+}}.h[2]
-}
-
-int32x2_t test_vdup_laneq_s32(int32x4_t v1) {
-  // CHECK: test_vdup_laneq_s32
-  return vdup_laneq_s32(v1, 1);
-  // CHECK: dup {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
-}
-
-int64x1_t test_vdup_laneq_s64(int64x2_t v1) {
-  // CHECK: test_vdup_laneq_s64
-  return vdup_laneq_s64(v1, 0);
-  // CHECK: ret
-}
-
-int8x16_t test_vdupq_laneq_s8(int8x16_t v1) {
-  // CHECK: test_vdupq_laneq_s8
-  return vdupq_laneq_s8(v1, 5);
-  // CHECK: dup {{v[0-9]+}}.16b, {{v[0-9]+}}.b[5]
-}
-
-int16x8_t test_vdupq_laneq_s16(int16x8_t v1) {
-  // CHECK: test_vdupq_laneq_s16
-  return vdupq_laneq_s16(v1, 2);
-  // CHECK: dup {{v[0-9]+}}.8h, {{v[0-9]+}}.h[2]
-}
-
-int32x4_t test_vdupq_laneq_s32(int32x4_t v1) {
-  // CHECK: test_vdupq_laneq_s32
-  return vdupq_laneq_s32(v1, 1);
-  // CHECK: dup {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
-}
-
-int64x2_t test_vdupq_laneq_s64(int64x2_t v1) {
-  // CHECK: test_vdupq_laneq_s64
-  return vdupq_laneq_s64(v1, 0);
-  // CHECK: dup {{v[0-9]+}}.2d, {{v[0-9]+}}.d[0]
-}
-
-uint8x8_t test_vdup_laneq_u8(uint8x16_t v1) {
-  // CHECK: test_vdup_laneq_u8
-  return vdup_laneq_u8(v1, 5);
-  // CHECK: dup {{v[0-9]+}}.8b, {{v[0-9]+}}.b[5]
-}
-
-uint16x4_t test_vdup_laneq_u16(uint16x8_t v1) {
-  // CHECK: test_vdup_laneq_u16
-  return vdup_laneq_u16(v1, 2);
-  // CHECK: dup {{v[0-9]+}}.4h, {{v[0-9]+}}.h[2]
-}
-
-uint32x2_t test_vdup_laneq_u32(uint32x4_t v1) {
-  // CHECK: test_vdup_laneq_u32
-  return vdup_laneq_u32(v1, 1);
-  // CHECK: dup {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
-}
-
-uint64x1_t test_vdup_laneq_u64(uint64x2_t v1) {
-  // CHECK: test_vdup_laneq_u64
-  return vdup_laneq_u64(v1, 0);
-  // CHECK: ret
-}
-
-uint8x16_t test_vdupq_laneq_u8(uint8x16_t v1) {
-  // CHECK: test_vdupq_laneq_u8
-  return vdupq_laneq_u8(v1, 5);
-  // CHECK: dup {{v[0-9]+}}.16b, {{v[0-9]+}}.b[5]
-}
-
-uint16x8_t test_vdupq_laneq_u16(uint16x8_t v1) {
-  // CHECK: test_vdupq_laneq_u16
-  return vdupq_laneq_u16(v1, 2);
-  // CHECK: dup {{v[0-9]+}}.8h, {{v[0-9]+}}.h[2]
-}
-
-uint32x4_t test_vdupq_laneq_u32(uint32x4_t v1) {
-  // CHECK: test_vdupq_laneq_u32
-  return vdupq_laneq_u32(v1, 1);
-  // CHECK: dup {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
-}
-
-uint64x2_t test_vdupq_laneq_u64(uint64x2_t v1) {
-  // CHECK: test_vdupq_laneq_u64
-  return vdupq_laneq_u64(v1, 0);
-  // CHECK: dup {{v[0-9]+}}.2d, {{v[0-9]+}}.d[0]
-}
-
-poly8x8_t test_vdup_lane_p8(poly8x8_t v1) {
-  // CHECK: test_vdup_lane_p8
-  return vdup_lane_p8(v1, 5);
-  // CHECK: dup {{v[0-9]+}}.8b, {{v[0-9]+}}.b[5]
-}
-
-poly16x4_t test_vdup_lane_p16(poly16x4_t v1) {
-  // CHECK: test_vdup_lane_p16
-  return vdup_lane_p16(v1, 2);
-  // CHECK: dup {{v[0-9]+}}.4h, {{v[0-9]+}}.h[2]
-}
-
-poly8x16_t test_vdupq_lane_p8(poly8x8_t v1) {
-  // CHECK: test_vdupq_lane_p8
-  return vdupq_lane_p8(v1, 5);
-  // CHECK: dup {{v[0-9]+}}.16b, {{v[0-9]+}}.b[5]
-}
-
-poly16x8_t test_vdupq_lane_p16(poly16x4_t v1) {
-  // CHECK: test_vdupq_lane_p16
-  return vdupq_lane_p16(v1, 2);
-  // CHECK: dup {{v[0-9]+}}.8h, {{v[0-9]+}}.h[2]
-}
-
-poly8x8_t test_vdup_laneq_p8(poly8x16_t v1) {
-  // CHECK: test_vdup_laneq_p8
-  return vdup_laneq_p8(v1, 5);
-  // CHECK: dup {{v[0-9]+}}.8b, {{v[0-9]+}}.b[5]
-}
-
-poly16x4_t test_vdup_laneq_p16(poly16x8_t v1) {
-  // CHECK: test_vdup_laneq_p16
-  return vdup_laneq_p16(v1, 2);
-  // CHECK: dup {{v[0-9]+}}.4h, {{v[0-9]+}}.h[2]
-}
-
-poly8x16_t test_vdupq_laneq_p8(poly8x16_t v1) {
-  // CHECK: test_vdupq_laneq_p8
-  return vdupq_laneq_p8(v1, 5);
-  // CHECK: dup {{v[0-9]+}}.16b, {{v[0-9]+}}.b[5]
-}
-
-poly16x8_t test_vdupq_laneq_p16(poly16x8_t v1) {
-  // CHECK: test_vdupq_laneq_p16
-  return vdupq_laneq_p16(v1, 2);
-  // CHECK: dup {{v[0-9]+}}.8h, {{v[0-9]+}}.h[2]
-}
-
-float16x4_t test_vdup_lane_f16(float16x4_t v1) {
-  // CHECK: test_vdup_lane_f16
-  return vdup_lane_f16(v1, 2);
-  // CHECK: dup {{v[0-9]+}}.4h, {{v[0-9]+}}.h[2]
-}
-
-float32x2_t test_vdup_lane_f32(float32x2_t v1) {
-  // CHECK: test_vdup_lane_f32
-  return vdup_lane_f32(v1, 1);
-  // CHECK: dup {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
-}
-
-float64x1_t test_vdup_lane_f64(float64x1_t v1) {
-  // CHECK: test_vdup_lane_f64
-  return vdup_lane_f64(v1, 0);
-  // CHECK: ret
-}
-
-float16x4_t test_vdup_laneq_f16(float16x8_t v1) {
-  // CHECK: test_vdup_laneq_f16
-  return vdup_laneq_f16(v1, 2);
-  // CHECK: dup {{v[0-9]+}}.4h, {{v[0-9]+}}.h[2]
-}
-
-float32x2_t test_vdup_laneq_f32(float32x4_t v1) {
-  // CHECK: test_vdup_laneq_f32
-  return vdup_laneq_f32(v1, 1);
-  // CHECK: dup {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
-}
-
-float64x1_t test_vdup_laneq_f64(float64x2_t v1) {
-  // CHECK: test_vdup_laneq_f64
-  return vdup_laneq_f64(v1, 0);
-  // CHECK: ret
-}
-
-float16x8_t test_vdupq_lane_f16(float16x4_t v1) {
-  // CHECK: test_vdupq_lane_f16
-  return vdupq_lane_f16(v1, 2);
-  // CHECK: dup {{v[0-9]+}}.8h, {{v[0-9]+}}.h[2]
-}
-
-float32x4_t test_vdupq_lane_f32(float32x2_t v1) {
-  // CHECK: test_vdupq_lane_f32
-  return vdupq_lane_f32(v1, 1);
-  // CHECK: dup {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
-}
-
-float64x2_t test_vdupq_lane_f64(float64x1_t v1) {
-  // CHECK: test_vdupq_lane_f64
-  return vdupq_lane_f64(v1, 0);
-  // CHECK: dup {{v[0-9]+}}.2d, {{v[0-9]+}}.d[0]
-}
-
-float16x8_t test_vdupq_laneq_f16(float16x8_t v1) {
-  // CHECK: test_vdupq_laneq_f16
-  return vdupq_laneq_f16(v1, 2);
-  // CHECK: dup {{v[0-9]+}}.8h, {{v[0-9]+}}.h[2]
-}
-
-float32x4_t test_vdupq_laneq_f32(float32x4_t v1) {
-  // CHECK: test_vdupq_laneq_f32
-  return vdupq_laneq_f32(v1, 1);
-  // CHECK: dup {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
-}
-
-float64x2_t test_vdupq_laneq_f64(float64x2_t v1) {
-  // CHECK: test_vdupq_laneq_f64
-  return vdupq_laneq_f64(v1, 0);
-  // CHECK: dup {{v[0-9]+}}.2d, {{v[0-9]+}}.d[0]
-}
-
-int8x8_t test_vmov_n_s8(int8_t v1) {
-  // CHECK: test_vmov_n_s8
-  return vmov_n_s8(v1);
-  // CHECK: dup {{v[0-9]+}}.8b, {{w[0-9]+}}
-}
-
-int16x4_t test_vmov_n_s16(int16_t v1) {
-  // CHECK: test_vmov_n_s16
-  return vmov_n_s16(v1);
-  // CHECK: dup {{v[0-9]+}}.4h, {{w[0-9]+}}
-}
-
-int32x2_t test_vmov_n_s32(int32_t v1) {
-  // CHECK: test_vmov_n_s32
-  return vmov_n_s32(v1);
-  // CHECK: dup {{v[0-9]+}}.2s, {{w[0-9]+}}
-}
-
-int64x1_t test_vmov_n_s64(int64_t v1) {
-  // CHECK: test_vmov_n_s64
-  return vmov_n_s64(v1);
-  // CHECK: fmov {{d[0-9]+}}, {{x[0-9]+}}
-}
-
-int8x16_t test_vmovq_n_s8(int8_t v1) {
-  // CHECK: test_vmovq_n_s8
-  return vmovq_n_s8(v1);
-  // CHECK: dup {{v[0-9]+}}.16b, {{w[0-9]+}}
-}
-
-int16x8_t test_vmovq_n_s16(int16_t v1) {
-  // CHECK: test_vmovq_n_s16
-  return vmovq_n_s16(v1);
-  // CHECK: dup {{v[0-9]+}}.8h, {{w[0-9]+}}
-}
-
-int32x4_t test_vmovq_n_s32(int32_t v1) {
-  // CHECK: test_vmovq_n_s32
-  return vmovq_n_s32(v1);
-  // CHECK: dup {{v[0-9]+}}.4s, {{w[0-9]+}}
-}
-
-int64x2_t test_vmovq_n_s64(int64_t v1) {
-  // CHECK: test_vmovq_n_s64
-  return vmovq_n_s64(v1);
-  // CHECK: dup {{v[0-9]+}}.2d, {{x[0-9]+}}
-}
-
-uint8x8_t test_vmov_n_u8(uint8_t v1) {
-  // CHECK: test_vmov_n_u8
-  return vmov_n_u8(v1);
-  // CHECK: dup {{v[0-9]+}}.8b, {{w[0-9]+}}
-}
-
-uint16x4_t test_vmov_n_u16(uint16_t v1) {
-  // CHECK: test_vmov_n_u16
-  return vmov_n_u16(v1);
-  // CHECK: dup {{v[0-9]+}}.4h, {{w[0-9]+}}
-}
-
-uint32x2_t test_vmov_n_u32(uint32_t v1) {
-  // CHECK: test_vmov_n_u32
-  return vmov_n_u32(v1);
-  // CHECK: dup {{v[0-9]+}}.2s, {{w[0-9]+}}
-}
-
-uint64x1_t test_vmov_n_u64(uint64_t v1) {
-  // CHECK: test_vmov_n_u64
-  return vmov_n_u64(v1);
-  // CHECK: fmov {{d[0-9]+}}, {{x[0-9]+}}
-}
-
-uint8x16_t test_vmovq_n_u8(uint8_t v1) {
-  // CHECK: test_vmovq_n_u8
-  return vmovq_n_u8(v1);
-  // CHECK: dup {{v[0-9]+}}.16b, {{w[0-9]+}}
-}
-
-uint16x8_t test_vmovq_n_u16(uint16_t v1) {
-  // CHECK: test_vmovq_n_u16
-  return vmovq_n_u16(v1);
-  // CHECK: dup {{v[0-9]+}}.8h, {{w[0-9]+}}
-}
-
-uint32x4_t test_vmovq_n_u32(uint32_t v1) {
-  // CHECK: test_vmovq_n_u32
-  return vmovq_n_u32(v1);
-  // CHECK: dup {{v[0-9]+}}.4s, {{w[0-9]+}}
-}
-
-uint64x2_t test_vmovq_n_u64(uint64_t v1) {
-  // CHECK: test_vmovq_n_u64
-  return vmovq_n_u64(v1);
-  // CHECK: dup {{v[0-9]+}}.2d, {{x[0-9]+}}
-}
-
-poly8x8_t test_vmov_n_p8(poly8_t v1) {
-  // CHECK: test_vmov_n_p8
-  return vmov_n_p8(v1);
-  // CHECK: dup {{v[0-9]+}}.8b, {{w[0-9]+}}
-}
-
-poly16x4_t test_vmov_n_p16(poly16_t v1) {
-  // CHECK: test_vmov_n_p16
-  return vmov_n_p16(v1);
-  // CHECK: dup {{v[0-9]+}}.4h, {{w[0-9]+}}
-}
-
-poly8x16_t test_vmovq_n_p8(poly8_t v1) {
-  // CHECK: test_vmovq_n_p8
-  return vmovq_n_p8(v1);
-  // CHECK: dup {{v[0-9]+}}.16b, {{w[0-9]+}}
-}
-
-poly16x8_t test_vmovq_n_p16(poly16_t v1) {
-  // CHECK: test_vmovq_n_p16
-  return vmovq_n_p16(v1);
-  // CHECK: dup {{v[0-9]+}}.8h, {{w[0-9]+}}
-}
-
-float32x2_t test_vmov_n_f32(float32_t v1) {
-  // CHECK: test_vmov_n_f32
-  return vmov_n_f32(v1);
-  // CHECK: dup {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
-}
-
-float64x1_t test_vmov_n_f64(float64_t v1) {
-  // CHECK: test_vmov_n_f64
-  return vmov_n_f64(v1);
-  // CHECK: ret
-}
-
-float32x4_t test_vmovq_n_f32(float32_t v1) {
-  // CHECK: test_vmovq_n_f32
-  return vmovq_n_f32(v1);
-  // CHECK: dup {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
-}
-
-float64x2_t test_vmovq_n_f64(float64_t v1) {
-  // CHECK: test_vmovq_n_f64
-  return vmovq_n_f64(v1);
-  // CHECK: dup {{v[0-9]+}}.2d, {{v[0-9]+}}.d[0]
-}
diff --git a/test/CodeGen/aarch64-neon-crypto.c b/test/CodeGen/aarch64-neon-crypto.c
deleted file mode 100644
index 240f379..0000000
--- a/test/CodeGen/aarch64-neon-crypto.c
+++ /dev/null
@@ -1,94 +0,0 @@
-// REQUIRES: aarch64-registered-target
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +neon \
-// RUN:   -target-feature +crypto -S -O3 -o - %s | FileCheck %s
-// RUN: not %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +neon \
-// RUN:   -S -O3 -o - %s 2>&1 | FileCheck --check-prefix=CHECK-NO-CRYPTO %s
-
-// Test new aarch64 intrinsics and types
-
-#include <arm_neon.h>
-
-uint8x16_t test_vaeseq_u8(uint8x16_t data, uint8x16_t key) {
-  // CHECK: test_vaeseq_u8
-  // CHECK-NO-CRYPTO: warning: implicit declaration of function 'vaeseq_u8' is invalid in C99
-  return vaeseq_u8(data, key);
-  // CHECK: aese {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
-}
-
-uint8x16_t test_vaesdq_u8(uint8x16_t data, uint8x16_t key) {
-  // CHECK: test_vaesdq_u8
-  return vaesdq_u8(data, key);
-  // CHECK: aesd {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
-}
-
-uint8x16_t test_vaesmcq_u8(uint8x16_t data) {
-  // CHECK: test_vaesmcq_u8
-  return vaesmcq_u8(data);
-  // CHECK: aesmc {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
-}
-
-uint8x16_t test_vaesimcq_u8(uint8x16_t data) {
-  // CHECK: test_vaesimcq_u8
-  return vaesimcq_u8(data);
-  // CHECK: aesimc {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
-}
-
-uint32_t test_vsha1h_u32(uint32_t hash_e) {
-  // CHECK: test_vsha1h_u32
-  return vsha1h_u32(hash_e);
-  // CHECK: sha1h {{s[0-9]+}}, {{s[0-9]+}}
-}
-
-uint32x4_t test_vsha1su1q_u32(uint32x4_t tw0_3, uint32x4_t w12_15) {
-  // CHECK: test_vsha1su1q_u32
-  return vsha1su1q_u32(tw0_3, w12_15);
-  // CHECK: sha1su1 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
-}
-
-uint32x4_t test_vsha256su0q_u32(uint32x4_t w0_3, uint32x4_t w4_7) {
-  // CHECK: test_vsha256su0q_u32
-  return vsha256su0q_u32(w0_3, w4_7);
-  // CHECK: sha256su0 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
-}
-
-uint32x4_t test_vsha1cq_u32(uint32x4_t hash_abcd, uint32_t hash_e, uint32x4_t wk) {
-  // CHECK: test_vsha1cq_u32
-  return vsha1cq_u32(hash_abcd, hash_e, wk);
-  // CHECK: sha1c {{q[0-9]+}}, {{s[0-9]+}}, {{v[0-9]+}}.4s
-}
-
-uint32x4_t test_vsha1pq_u32(uint32x4_t hash_abcd, uint32_t hash_e, uint32x4_t wk) {
-  // CHECK: test_vsha1pq_u32
-  return vsha1pq_u32(hash_abcd, hash_e, wk);
-  // CHECK: sha1p {{q[0-9]+}}, {{s[0-9]+}}, {{v[0-9]+}}.4s
-}
-
-uint32x4_t test_vsha1mq_u32(uint32x4_t hash_abcd, uint32_t hash_e, uint32x4_t wk) {
-  // CHECK: test_vsha1mq_u32
-  return vsha1mq_u32(hash_abcd, hash_e, wk);
-  // CHECK: sha1m {{q[0-9]+}}, {{s[0-9]+}}, {{v[0-9]+}}.4s
-}
-
-uint32x4_t test_vsha1su0q_u32(uint32x4_t w0_3, uint32x4_t w4_7, uint32x4_t w8_11) {
-  // CHECK: test_vsha1su0q_u32
-  return vsha1su0q_u32(w0_3, w4_7, w8_11);
-  // CHECK: sha1su0 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
-}
-
-uint32x4_t test_vsha256hq_u32(uint32x4_t hash_abcd, uint32x4_t hash_efgh, uint32x4_t wk) {
-  // CHECK: test_vsha256hq_u32
-  return vsha256hq_u32(hash_abcd, hash_efgh, wk);
-  // CHECK: sha256h {{q[0-9]+}}, {{q[0-9]+}}, {{v[0-9]+}}.4s
-}
-
-uint32x4_t test_vsha256h2q_u32(uint32x4_t hash_efgh, uint32x4_t hash_abcd, uint32x4_t wk) {
-  // CHECK: test_vsha256h2q_u32
-  return vsha256h2q_u32(hash_efgh, hash_abcd, wk);
-  // CHECK: sha256h2 {{q[0-9]+}}, {{q[0-9]+}}, {{v[0-9]+}}.4s
-}
-
-uint32x4_t test_vsha256su1q_u32(uint32x4_t tw0_3, uint32x4_t w8_11, uint32x4_t w12_15) {
-  // CHECK: test_vsha256su1q_u32
-  return vsha256su1q_u32(tw0_3, w8_11, w12_15);
-  // CHECK: sha256su1 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
-}
diff --git a/test/CodeGen/aarch64-neon-extract.c b/test/CodeGen/aarch64-neon-extract.c
index faf35af..cc654cc 100644
--- a/test/CodeGen/aarch64-neon-extract.c
+++ b/test/CodeGen/aarch64-neon-extract.c
@@ -1,5 +1,5 @@
 // REQUIRES: aarch64-registered-target
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +neon \
+// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \
 // RUN:   -ffp-contract=fast -S -O3 -o - %s | FileCheck %s
 
 // Test new aarch64 intrinsics and types
@@ -7,142 +7,142 @@
 #include <arm_neon.h>
 
 int8x8_t test_vext_s8(int8x8_t a, int8x8_t b) {
-  // CHECK: test_vext_s8
+  // CHECK-LABEL: test_vext_s8
   return vext_s8(a, b, 2);
-  // CHECK: ext {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #0x2
+  // CHECK: ext {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #{{(0x)?2}}
 }
 
 int16x4_t test_vext_s16(int16x4_t a, int16x4_t b) {
-  // CHECK: test_vext_s16
+  // CHECK-LABEL: test_vext_s16
   return vext_s16(a, b, 3);
-  // CHECK: ext {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #0x6
+  // CHECK: ext {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #{{(0x)?6}}
 }
 
 int32x2_t test_vext_s32(int32x2_t a, int32x2_t b) {
-  // CHECK: test_vext_s32
+  // CHECK-LABEL: test_vext_s32
   return vext_s32(a, b, 1);
-  // CHECK: ext {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #0x4
+  // CHECK: ext {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #{{(0x)?4}}
 }
 
 int64x1_t test_vext_s64(int64x1_t a, int64x1_t b) {
-  // CHECK: test_vext_s64
+  // CHECK-LABEL: test_vext_s64
   return vext_s64(a, b, 0);
 }
 
 int8x16_t test_vextq_s8(int8x16_t a, int8x16_t b) {
-  // CHECK: test_vextq_s8
+  // CHECK-LABEL: test_vextq_s8
   return vextq_s8(a, b, 2);
-  // CHECK: ext {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #0x2
+  // CHECK: ext {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #{{(0x)?2}}
 }
 
 int16x8_t test_vextq_s16(int16x8_t a, int16x8_t b) {
-  // CHECK: test_vextq_s16
+  // CHECK-LABEL: test_vextq_s16
   return vextq_s16(a, b, 3);
-  // CHECK: ext {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #0x6
+  // CHECK: ext {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #{{(0x)?6}}
 }
 
 int32x4_t test_vextq_s32(int32x4_t a, int32x4_t b) {
-  // CHECK: test_vextq_s32
+  // CHECK-LABEL: test_vextq_s32
   return vextq_s32(a, b, 1);
-  // CHECK: ext {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #0x4
+  // CHECK: ext {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #{{(0x)?4}}
 }
 
 int64x2_t test_vextq_s64(int64x2_t a, int64x2_t b) {
-  // CHECK: test_vextq_s64
+  // CHECK-LABEL: test_vextq_s64
   return vextq_s64(a, b, 1);
-  // CHECK: ext {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #0x8
+  // CHECK: ext {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #{{(0x)?8}}
 }
 
 uint8x8_t test_vext_u8(uint8x8_t a, uint8x8_t b) {
-  // CHECK: test_vext_u8
+  // CHECK-LABEL: test_vext_u8
   return vext_u8(a, b, 2);
-  // CHECK: ext {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #0x2
+  // CHECK: ext {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #{{(0x)?2}}
 }
 
 uint16x4_t test_vext_u16(uint16x4_t a, uint16x4_t b) {
-  // CHECK: test_vext_u16
+  // CHECK-LABEL: test_vext_u16
   return vext_u16(a, b, 3);
-  // CHECK: ext {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #0x6
+  // CHECK: ext {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #{{(0x)?6}}
 }
 
 uint32x2_t test_vext_u32(uint32x2_t a, uint32x2_t b) {
-  // CHECK: test_vext_u32
+  // CHECK-LABEL: test_vext_u32
   return vext_u32(a, b, 1);
-  // CHECK: ext {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #0x4
+  // CHECK: ext {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #{{(0x)?4}}
 }
 
 uint64x1_t test_vext_u64(uint64x1_t a, uint64x1_t b) {
-  // CHECK: test_vext_u64
+  // CHECK-LABEL: test_vext_u64
   return vext_u64(a, b, 0);
 }
 
 uint8x16_t test_vextq_u8(uint8x16_t a, uint8x16_t b) {
-  // CHECK: test_vextq_u8
+  // CHECK-LABEL: test_vextq_u8
   return vextq_u8(a, b, 2);
-  // CHECK: ext {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #0x2
+  // CHECK: ext {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #{{(0x)?2}}
 }
 
 uint16x8_t test_vextq_u16(uint16x8_t a, uint16x8_t b) {
-  // CHECK: test_vextq_u16
+  // CHECK-LABEL: test_vextq_u16
   return vextq_u16(a, b, 3);
-  // CHECK: ext {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #0x6
+  // CHECK: ext {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #{{(0x)?6}}
 }
 
 uint32x4_t test_vextq_u32(uint32x4_t a, uint32x4_t b) {
-  // CHECK: test_vextq_u32
+  // CHECK-LABEL: test_vextq_u32
   return vextq_u32(a, b, 1);
-  // CHECK: ext {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #0x4
+  // CHECK: ext {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #{{(0x)?4}}
 }
 
 uint64x2_t test_vextq_u64(uint64x2_t a, uint64x2_t b) {
-  // CHECK: test_vextq_u64
+  // CHECK-LABEL: test_vextq_u64
   return vextq_u64(a, b, 1);
-  // CHECK: ext {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #0x8
+  // CHECK: ext {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #{{(0x)?8}}
 }
 
 float32x2_t test_vext_f32(float32x2_t a, float32x2_t b) {
-  // CHECK: test_vext_f32
+  // CHECK-LABEL: test_vext_f32
   return vext_f32(a, b, 1);
-  // CHECK: ext {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #0x4
+  // CHECK: ext {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #{{(0x)?4}}
 }
 
 float64x1_t test_vext_f64(float64x1_t a, float64x1_t b) {
-  // CHECK: test_vext_f64
+  // CHECK-LABEL: test_vext_f64
   return vext_f64(a, b, 0);
 }
 
 float32x4_t test_vextq_f32(float32x4_t a, float32x4_t b) {
-  // CHECK: test_vextq_f32
+  // CHECK-LABEL: test_vextq_f32
   return vextq_f32(a, b, 1);
-  // CHECK: ext {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #0x4
+  // CHECK: ext {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #{{(0x)?4}}
 }
 
 float64x2_t test_vextq_f64(float64x2_t a, float64x2_t b) {
-  // CHECK: test_vextq_f64
+  // CHECK-LABEL: test_vextq_f64
   return vextq_f64(a, b, 1);
-  // CHECK: ext {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #0x8
+  // CHECK: ext {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #{{(0x)?8}}
 }
 
 poly8x8_t test_vext_p8(poly8x8_t a, poly8x8_t b) {
-  // CHECK: test_vext_p8
+  // CHECK-LABEL: test_vext_p8
   return vext_p8(a, b, 2);
-  // CHECK: ext {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #0x2
+  // CHECK: ext {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #{{(0x)?2}}
 }
 
 poly16x4_t test_vext_p16(poly16x4_t a, poly16x4_t b) {
-  // CHECK: test_vext_p16
+  // CHECK-LABEL: test_vext_p16
   return vext_p16(a, b, 3);
-  // CHECK: ext {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #0x6
+  // CHECK: ext {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #{{(0x)?6}}
 }
 
 poly8x16_t test_vextq_p8(poly8x16_t a, poly8x16_t b) {
-  // CHECK: test_vextq_p8
+  // CHECK-LABEL: test_vextq_p8
   return vextq_p8(a, b, 2);
-  // CHECK: ext {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #0x2
+  // CHECK: ext {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #{{(0x)?2}}
 }
 
 poly16x8_t test_vextq_p16(poly16x8_t a, poly16x8_t b) {
-  // CHECK: test_vextq_p16
+  // CHECK-LABEL: test_vextq_p16
   return vextq_p16(a, b, 3);
-  // CHECK: ext {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #0x6
+  // CHECK: ext {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #{{(0x)?6}}
 }
diff --git a/test/CodeGen/aarch64-neon-fcvt-intrinsics.c b/test/CodeGen/aarch64-neon-fcvt-intrinsics.c
new file mode 100644
index 0000000..d1b9996
--- /dev/null
+++ b/test/CodeGen/aarch64-neon-fcvt-intrinsics.c
@@ -0,0 +1,133 @@
+// REQUIRES: aarch64-registered-target
+// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \
+// RUN:   -ffp-contract=fast -S -O3 -o - %s | FileCheck %s
+
+// Test new aarch64 intrinsics and types
+
+#include <arm_neon.h>
+
+float32_t test_vcvtxd_f32_f64(float64_t a) {
+// CHECK-LABEL: test_vcvtxd_f32_f64
+// CHECK: fcvtxn {{s[0-9]+}}, {{d[0-9]+}}
+  return (float32_t)vcvtxd_f32_f64(a);
+}
+
+int32_t test_vcvtas_s32_f32(float32_t a) {
+// CHECK-LABEL: test_vcvtas_s32_f32
+// CHECK: fcvtas {{[ws][0-9]+}}, {{s[0-9]+}}
+  return (int32_t)vcvtas_s32_f32(a);
+}
+
+int64_t test_test_vcvtad_s64_f64(float64_t a) {
+// CHECK-LABEL: test_test_vcvtad_s64_f64
+// CHECK: fcvtas {{[dx][0-9]+}}, {{d[0-9]+}}
+  return (int64_t)vcvtad_s64_f64(a);
+}
+
+uint32_t test_vcvtas_u32_f32(float32_t a) {
+// CHECK-LABEL: test_vcvtas_u32_f32
+// CHECK: fcvtau {{[ws][0-9]+}}, {{s[0-9]+}}
+  return (uint32_t)vcvtas_u32_f32(a);
+}
+
+uint64_t test_vcvtad_u64_f64(float64_t a) {
+// CHECK-LABEL: test_vcvtad_u64_f64
+// CHECK: fcvtau {{[xd][0-9]+}}, {{d[0-9]+}}
+  return (uint64_t)vcvtad_u64_f64(a);
+}
+
+int32_t test_vcvtms_s32_f32(float32_t a) {
+// CHECK-LABEL: test_vcvtms_s32_f32
+// CHECK: fcvtms {{[sw][0-9]+}}, {{s[0-9]+}}
+  return (int32_t)vcvtms_s32_f32(a);
+}
+
+int64_t test_vcvtmd_s64_f64(float64_t a) {
+// CHECK-LABEL: test_vcvtmd_s64_f64
+// CHECK: fcvtms {{[dx][0-9]+}}, {{d[0-9]+}}
+  return (int64_t)vcvtmd_s64_f64(a);
+}
+
+uint32_t test_vcvtms_u32_f32(float32_t a) {
+// CHECK-LABEL: test_vcvtms_u32_f32
+// CHECK: fcvtmu {{[ws][0-9]+}}, {{s[0-9]+}}
+  return (uint32_t)vcvtms_u32_f32(a);
+}
+
+uint64_t test_vcvtmd_u64_f64(float64_t a) {
+// CHECK-LABEL: test_vcvtmd_u64_f64
+// CHECK: fcvtmu {{[xd][0-9]+}}, {{d[0-9]+}}
+  return (uint64_t)vcvtmd_u64_f64(a);
+}
+
+int32_t test_vcvtns_s32_f32(float32_t a) {
+// CHECK-LABEL: test_vcvtns_s32_f32
+// CHECK: fcvtns {{[sw][0-9]+}}, {{s[0-9]+}}
+  return (int32_t)vcvtns_s32_f32(a);
+}
+
+int64_t test_vcvtnd_s64_f64(float64_t a) {
+// CHECK-LABEL: test_vcvtnd_s64_f64
+// CHECK: fcvtns {{[dx][0-9]+}}, {{d[0-9]+}}
+  return (int64_t)vcvtnd_s64_f64(a);
+}
+
+uint32_t test_vcvtns_u32_f32(float32_t a) {
+// CHECK-LABEL: test_vcvtns_u32_f32
+// CHECK: fcvtnu {{[sw][0-9]+}}, {{s[0-9]+}}
+  return (uint32_t)vcvtns_u32_f32(a);
+}
+
+uint64_t test_vcvtnd_u64_f64(float64_t a) {
+// CHECK-LABEL: test_vcvtnd_u64_f64
+// CHECK: fcvtnu {{[dx][0-9]+}}, {{d[0-9]+}}
+  return (uint64_t)vcvtnd_u64_f64(a);
+}
+
+int32_t test_vcvtps_s32_f32(float32_t a) {
+// CHECK-LABEL: test_vcvtps_s32_f32
+// CHECK: fcvtps {{[sw][0-9]+}}, {{s[0-9]+}}
+  return (int32_t)vcvtps_s32_f32(a);
+}
+
+int64_t test_vcvtpd_s64_f64(float64_t a) {
+// CHECK-LABEL: test_vcvtpd_s64_f64
+// CHECK: fcvtps {{[dx][0-9]+}}, {{d[0-9]+}}
+  return (int64_t)vcvtpd_s64_f64(a);
+}
+
+uint32_t test_vcvtps_u32_f32(float32_t a) {
+// CHECK-LABEL: test_vcvtps_u32_f32
+// CHECK: fcvtpu {{[sw][0-9]+}}, {{s[0-9]+}}
+  return (uint32_t)vcvtps_u32_f32(a);
+}
+
+uint64_t test_vcvtpd_u64_f64(float64_t a) {
+// CHECK-LABEL: test_vcvtpd_u64_f64
+// CHECK: fcvtpu {{[dx][0-9]+}}, {{d[0-9]+}}
+  return (uint64_t)vcvtpd_u64_f64(a);
+}
+
+int32_t test_vcvts_s32_f32(float32_t a) {
+// CHECK-LABEL: test_vcvts_s32_f32
+// CHECK: fcvtzs {{[sw][0-9]+}}, {{s[0-9]+}}
+  return (int32_t)vcvts_s32_f32(a);
+}
+
+int64_t test_vcvtd_s64_f64(float64_t a) {
+// CHECK-LABEL: test_vcvtd_s64_f64
+// CHECK: fcvtzs {{[dx][0-9]+}}, {{d[0-9]+}}
+  return (int64_t)vcvtd_s64_f64(a);
+}
+
+uint32_t test_vcvts_u32_f32(float32_t a) {
+// CHECK-LABEL: test_vcvts_u32_f32
+// CHECK: fcvtzu {{[sw][0-9]+}}, {{s[0-9]+}}
+  return (uint32_t)vcvts_u32_f32(a);
+}
+
+uint64_t test_vcvtd_u64_f64(float64_t a) {
+// CHECK-LABEL: test_vcvtd_u64_f64
+// CHECK: fcvtzu {{[dx][0-9]+}}, {{d[0-9]+}}
+  return (uint64_t)vcvtd_u64_f64(a);
+}
diff --git a/test/CodeGen/aarch64-neon-fma.c b/test/CodeGen/aarch64-neon-fma.c
new file mode 100644
index 0000000..ac80833
--- /dev/null
+++ b/test/CodeGen/aarch64-neon-fma.c
@@ -0,0 +1,199 @@
+// REQUIRES: aarch64-registered-target
+// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon -S -O3 -o - %s | FileCheck %s
+
+// Test new aarch64 intrinsics and types
+
+#include <arm_neon.h>
+
+float32x2_t test_vmla_n_f32(float32x2_t a, float32x2_t b, float32_t c) {
+  // CHECK-LABEL: test_vmla_n_f32
+  return vmla_n_f32(a, b, c);
+  // CHECK: fmul {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+  // CHECK: fadd {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
+  // CHECK-FMA: dup {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+  // CHECK-FMA: fmla {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
+}
+
+float32x4_t test_vmlaq_n_f32(float32x4_t a, float32x4_t b, float32_t c) {
+  // CHECK-LABEL: test_vmlaq_n_f32
+  return vmlaq_n_f32(a, b, c);
+  // CHECK: fmul {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+  // CHECK: fadd {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
+  // CHECK-FMA: dup {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+  // CHECK-FMA: fmla {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
+}
+
+float64x2_t test_vmlaq_n_f64(float64x2_t a, float64x2_t b, float64_t c) {
+  // CHECK-LABEL: test_vmlaq_n_f64
+  return vmlaq_n_f64(a, b, c);
+  // CHECK: fmul {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.d[0]
+  // CHECK: fadd {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
+  // CHECK-FMA: dup {{v[0-9]+}}.2d, {{v[0-9]+}}.d[0]
+  // CHECK-FMA: fmla {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
+}
+
+float32x4_t test_vmlsq_n_f32(float32x4_t a, float32x4_t b, float32_t c) {
+  // CHECK-LABEL: test_vmlsq_n_f32
+  return vmlsq_n_f32(a, b, c);
+  // CHECK: fmul {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+  // CHECK: fsub {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
+  // CHECK-FMA: dup {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+  // CHECK-FMA: fmls {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
+}
+
+float32x2_t test_vmls_n_f32(float32x2_t a, float32x2_t b, float32_t c) {
+  // CHECK-LABEL: test_vmls_n_f32
+  return vmls_n_f32(a, b, c);
+  // CHECK: fmul {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+  // CHECK: fsub {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
+  // CHECK-FMA: dup {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+  // CHECK-FMA: fmls {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
+}
+
+float64x2_t test_vmlsq_n_f64(float64x2_t a, float64x2_t b, float64_t c) {
+  // CHECK-LABEL: test_vmlsq_n_f64
+  return vmlsq_n_f64(a, b, c);
+  // CHECK: fmul {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.d[0]
+  // CHECK: fsub {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
+  // CHECK-FMA: dup {{v[0-9]+}}.2d, {{v[0-9]+}}.d[0]
+  // CHECK-FMA: fmls {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
+}
+
+float32x2_t test_vmla_lane_f32_0(float32x2_t a, float32x2_t b, float32x2_t v) {
+  // CHECK-LABEL: test_vmla_lane_f32_0
+  return vmla_lane_f32(a, b, v, 0);
+  // CHECK: fmul {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+  // CHECK: fadd {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
+  // CHECK-FMA: fmla {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+float32x4_t test_vmlaq_lane_f32_0(float32x4_t a, float32x4_t b, float32x2_t v) {
+  // CHECK-LABEL: test_vmlaq_lane_f32_0
+  return vmlaq_lane_f32(a, b, v, 0);
+  // CHECK: fmul {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+  // CHECK: fadd {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
+  // CHECK-FMA: fmla {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+float32x2_t test_vmla_laneq_f32_0(float32x2_t a, float32x2_t b, float32x4_t v) {
+  // CHECK-LABEL: test_vmla_laneq_f32_0
+  return vmla_laneq_f32(a, b, v, 0);
+  // CHECK: fmul {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+  // CHECK: fadd {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
+  // CHECK-FMA: fmla {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+float32x4_t test_vmlaq_laneq_f32_0(float32x4_t a, float32x4_t b, float32x4_t v) {
+  // CHECK-LABEL: test_vmlaq_laneq_f32_0
+  return vmlaq_laneq_f32(a, b, v, 0);
+  // CHECK: fmul {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+  // CHECK: fadd {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
+  // CHECK-FMA: fmla {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+float32x2_t test_vmls_lane_f32_0(float32x2_t a, float32x2_t b, float32x2_t v) {
+  // CHECK-LABEL: test_vmls_lane_f32_0
+  return vmls_lane_f32(a, b, v, 0);
+  // CHECK: fmul {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+  // CHECK: fsub {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
+  // CHECK-FMA: fmls {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+float32x4_t test_vmlsq_lane_f32_0(float32x4_t a, float32x4_t b, float32x2_t v) {
+  // CHECK-LABEL: test_vmlsq_lane_f32_0
+  return vmlsq_lane_f32(a, b, v, 0);
+  // CHECK: fmul {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+  // CHECK: fsub {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
+  // CHECK-FMA: fmls {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+float32x2_t test_vmls_laneq_f32_0(float32x2_t a, float32x2_t b, float32x4_t v) {
+  // CHECK-LABEL: test_vmls_laneq_f32_0
+  return vmls_laneq_f32(a, b, v, 0);
+  // CHECK: fmul {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+  // CHECK: fsub {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
+  // CHECK-FMA: fmls {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[0]
+}
+
+float32x4_t test_vmlsq_laneq_f32_0(float32x4_t a, float32x4_t b, float32x4_t v) {
+  // CHECK-LABEL: test_vmlsq_laneq_f32_0
+  return vmlsq_laneq_f32(a, b, v, 0);
+  // CHECK: fmul {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+  // CHECK: fsub {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
+  // CHECK-FMA: fmls {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[0]
+}
+
+float32x2_t test_vmla_lane_f32(float32x2_t a, float32x2_t b, float32x2_t v) {
+  // CHECK-LABEL: test_vmla_lane_f32
+  return vmla_lane_f32(a, b, v, 1);
+  // CHECK: fmul {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
+  // CHECK: fadd {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
+  // CHECK-FMA: fmla {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
+}
+
+float32x4_t test_vmlaq_lane_f32(float32x4_t a, float32x4_t b, float32x2_t v) {
+  // CHECK-LABEL: test_vmlaq_lane_f32
+  return vmlaq_lane_f32(a, b, v, 1);
+  // CHECK: fmul {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
+  // CHECK: fadd {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
+  // CHECK-FMA: fmla {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
+}
+
+float32x2_t test_vmla_laneq_f32(float32x2_t a, float32x2_t b, float32x4_t v) {
+  // CHECK-LABEL: test_vmla_laneq_f32
+  return vmla_laneq_f32(a, b, v, 3);
+  // CHECK: fmul {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[3]
+  // CHECK: fadd {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
+  // CHECK-FMA: fmla {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[3]
+}
+
+float32x4_t test_vmlaq_laneq_f32(float32x4_t a, float32x4_t b, float32x4_t v) {
+  // CHECK-LABEL: test_vmlaq_laneq_f32
+  return vmlaq_laneq_f32(a, b, v, 3);
+  // CHECK: fmul {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[3]
+  // CHECK: fadd {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
+  // CHECK-FMA: fmla {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[3]
+}
+
+float32x2_t test_vmls_lane_f32(float32x2_t a, float32x2_t b, float32x2_t v) {
+  // CHECK-LABEL: test_vmls_lane_f32
+  return vmls_lane_f32(a, b, v, 1);
+  // CHECK: fmul {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
+  // CHECK: fsub {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
+  // CHECK-FMA: fmls {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[1]
+}
+
+float32x4_t test_vmlsq_lane_f32(float32x4_t a, float32x4_t b, float32x2_t v) {
+  // CHECK-LABEL: test_vmlsq_lane_f32
+  return vmlsq_lane_f32(a, b, v, 1);
+  // CHECK: fmul {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
+  // CHECK: fsub {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
+  // CHECK-FMA: fmls {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[1]
+}
+float32x2_t test_vmls_laneq_f32(float32x2_t a, float32x2_t b, float32x4_t v) {
+  // CHECK-LABEL: test_vmls_laneq_f32
+  return vmls_laneq_f32(a, b, v, 3);
+  // CHECK: fmul {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[3]
+  // CHECK: fsub {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
+  // CHECK-FMA: fmls {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.s[3]
+}
+
+float32x4_t test_vmlsq_laneq_f32(float32x4_t a, float32x4_t b, float32x4_t v) {
+  // CHECK-LABEL: test_vmlsq_laneq_f32
+  return vmlsq_laneq_f32(a, b, v, 3);
+  // CHECK: fmul {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[3]
+  // CHECK: fsub {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
+  // CHECK-FMA: fmls {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.s[3]
+}
+
+float64x2_t test_vfmaq_n_f64(float64x2_t a, float64x2_t b, float64_t c) {
+  // CHECK-LABEL: test_vfmaq_n_f64:
+  return vfmaq_n_f64(a, b, c);
+  // CHECK: fmla {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+\.2d|v[0-9]+\.d\[0\]}}
+}
+
+float64x2_t test_vfmsq_n_f64(float64x2_t a, float64x2_t b, float64_t c) {
+  // CHECK-LABEL: test_vfmsq_n_f64:
+  return vfmsq_n_f64(a, b, c);
+  // CHECK: fmls {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+\.2d|v[0-9]+\.d\[0\]}}
+}
diff --git a/test/CodeGen/aarch64-neon-intrinsics.c b/test/CodeGen/aarch64-neon-intrinsics.c
index f0533cd..b120779 100644
--- a/test/CodeGen/aarch64-neon-intrinsics.c
+++ b/test/CodeGen/aarch64-neon-intrinsics.c
@@ -1,109 +1,109 @@
 // REQUIRES: aarch64-registered-target
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +neon \
-// RUN:   -ffp-contract=fast -S -O3 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \
+// RUN:   -ffp-contract=fast -S -O3 -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ARM64
 
 // Test new aarch64 intrinsics and types
 
 #include <arm_neon.h>
 
 int8x8_t test_vadd_s8(int8x8_t v1, int8x8_t v2) {
-   // CHECK: test_vadd_s8
+   // CHECK-LABEL: test_vadd_s8
   return vadd_s8(v1, v2);
   // CHECK: add {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 int16x4_t test_vadd_s16(int16x4_t v1, int16x4_t v2) {
-   // CHECK: test_vadd_s16
+   // CHECK-LABEL: test_vadd_s16
   return vadd_s16(v1, v2);
   // CHECK: add {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 int32x2_t test_vadd_s32(int32x2_t v1, int32x2_t v2) {
-   // CHECK: test_vadd_s32
+   // CHECK-LABEL: test_vadd_s32
   return vadd_s32(v1, v2);
   // CHECK: add {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 int64x1_t test_vadd_s64(int64x1_t v1, int64x1_t v2) {
-  // CHECK: test_vadd_s64
+  // CHECK-LABEL: test_vadd_s64
   return vadd_s64(v1, v2);
   // CHECK: add {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
 }
 
 float32x2_t test_vadd_f32(float32x2_t v1, float32x2_t v2) {
-   // CHECK: test_vadd_f32
+   // CHECK-LABEL: test_vadd_f32
   return vadd_f32(v1, v2);
   // CHECK: fadd {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 uint8x8_t test_vadd_u8(uint8x8_t v1, uint8x8_t v2) {
-   // CHECK: test_vadd_u8
+   // CHECK-LABEL: test_vadd_u8
   return vadd_u8(v1, v2);
   // CHECK: add {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint16x4_t test_vadd_u16(uint16x4_t v1, uint16x4_t v2) {
-   // CHECK: test_vadd_u16
+   // CHECK-LABEL: test_vadd_u16
   return vadd_u16(v1, v2);
   // CHECK: add {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint32x2_t test_vadd_u32(uint32x2_t v1, uint32x2_t v2) {
-   // CHECK: test_vadd_u32
+   // CHECK-LABEL: test_vadd_u32
   return vadd_u32(v1, v2);
   // CHECK: add {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 uint64x1_t test_vadd_u64(uint64x1_t v1, uint64x1_t v2) {
-   // CHECK: test_vadd_u64
+   // CHECK-LABEL: test_vadd_u64
   return vadd_u64(v1, v2);
   // CHECK: add {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
 }
 
 int8x16_t test_vaddq_s8(int8x16_t v1, int8x16_t v2) {
-   // CHECK: test_vaddq_s8
+   // CHECK-LABEL: test_vaddq_s8
   return vaddq_s8(v1, v2);
   // CHECK: add {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 int16x8_t test_vaddq_s16(int16x8_t v1, int16x8_t v2) {
-   // CHECK: test_vaddq_s16
+   // CHECK-LABEL: test_vaddq_s16
   return vaddq_s16(v1, v2);
   // CHECK: add {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int32x4_t test_vaddq_s32(int32x4_t v1,int32x4_t  v2) {
-   // CHECK: test_vaddq_s32
+   // CHECK-LABEL: test_vaddq_s32
   return vaddq_s32(v1, v2);
   // CHECK: add {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 int64x2_t test_vaddq_s64(int64x2_t v1, int64x2_t v2) {
-   // CHECK: test_vaddq_s64
+   // CHECK-LABEL: test_vaddq_s64
   return vaddq_s64(v1, v2);
   // CHECK: add {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 float32x4_t test_vaddq_f32(float32x4_t v1, float32x4_t v2) {
-   // CHECK: test_vaddq_f32
+   // CHECK-LABEL: test_vaddq_f32
   return vaddq_f32(v1, v2);
   // CHECK: fadd {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 float64x2_t test_vaddq_f64(float64x2_t v1, float64x2_t v2) {
-  // CHECK: test_vaddq_f64
+  // CHECK-LABEL: test_vaddq_f64
   return vaddq_f64(v1, v2);
   // CHECK: fadd {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 uint8x16_t test_vaddq_u8(uint8x16_t v1, uint8x16_t v2) {
-   // CHECK: test_vaddq_u8
+   // CHECK-LABEL: test_vaddq_u8
   return vaddq_u8(v1, v2);
   // CHECK: add {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint16x8_t test_vaddq_u16(uint16x8_t v1, uint16x8_t v2) {
-   // CHECK: test_vaddq_u16
+   // CHECK-LABEL: test_vaddq_u16
   return vaddq_u16(v1, v2);
   // CHECK: add {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
@@ -115,107 +115,107 @@
 }
 
 uint64x2_t test_vaddq_u64(uint64x2_t v1, uint64x2_t v2) {
-   // CHECK: test_vaddq_u64
+   // CHECK-LABEL: test_vaddq_u64
   return vaddq_u64(v1, v2);
   // CHECK: add {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 int8x8_t test_vsub_s8(int8x8_t v1, int8x8_t v2) {
-   // CHECK: test_vsub_s8
+   // CHECK-LABEL: test_vsub_s8
   return vsub_s8(v1, v2);
   // CHECK: sub {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 int16x4_t test_vsub_s16(int16x4_t v1, int16x4_t v2) {
-   // CHECK: test_vsub_s16
+   // CHECK-LABEL: test_vsub_s16
   return vsub_s16(v1, v2);
   // CHECK: sub {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 int32x2_t test_vsub_s32(int32x2_t v1, int32x2_t v2) {
-   // CHECK: test_vsub_s32
+   // CHECK-LABEL: test_vsub_s32
   return vsub_s32(v1, v2);
   // CHECK: sub {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 int64x1_t test_vsub_s64(int64x1_t v1, int64x1_t v2) {
-   // CHECK: test_vsub_s64
+   // CHECK-LABEL: test_vsub_s64
   return vsub_s64(v1, v2);
   // CHECK: sub {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
 }
 
 float32x2_t test_vsub_f32(float32x2_t v1, float32x2_t v2) {
-   // CHECK: test_vsub_f32
+   // CHECK-LABEL: test_vsub_f32
   return vsub_f32(v1, v2);
   // CHECK: fsub {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 uint8x8_t test_vsub_u8(uint8x8_t v1, uint8x8_t v2) {
-   // CHECK: test_vsub_u8
+   // CHECK-LABEL: test_vsub_u8
   return vsub_u8(v1, v2);
   // CHECK: sub {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint16x4_t test_vsub_u16(uint16x4_t v1, uint16x4_t v2) {
-   // CHECK: test_vsub_u16
+   // CHECK-LABEL: test_vsub_u16
   return vsub_u16(v1, v2);
   // CHECK: sub {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint32x2_t test_vsub_u32(uint32x2_t v1, uint32x2_t v2) {
-   // CHECK: test_vsub_u32
+   // CHECK-LABEL: test_vsub_u32
   return vsub_u32(v1, v2);
   // CHECK: sub {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 uint64x1_t test_vsub_u64(uint64x1_t v1, uint64x1_t v2) {
-   // CHECK: test_vsub_u64
+   // CHECK-LABEL: test_vsub_u64
   return vsub_u64(v1, v2);
   // CHECK: sub {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
 }
 
 int8x16_t test_vsubq_s8(int8x16_t v1, int8x16_t v2) {
-   // CHECK: test_vsubq_s8
+   // CHECK-LABEL: test_vsubq_s8
   return vsubq_s8(v1, v2);
   // CHECK: sub {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 int16x8_t test_vsubq_s16(int16x8_t v1, int16x8_t v2) {
-   // CHECK: test_vsubq_s16
+   // CHECK-LABEL: test_vsubq_s16
   return vsubq_s16(v1, v2);
   // CHECK: sub {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int32x4_t test_vsubq_s32(int32x4_t v1,int32x4_t  v2) {
-   // CHECK: test_vsubq_s32
+   // CHECK-LABEL: test_vsubq_s32
   return vsubq_s32(v1, v2);
   // CHECK: sub {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 int64x2_t test_vsubq_s64(int64x2_t v1, int64x2_t v2) {
-   // CHECK: test_vsubq_s64
+   // CHECK-LABEL: test_vsubq_s64
   return vsubq_s64(v1, v2);
   // CHECK: sub {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 float32x4_t test_vsubq_f32(float32x4_t v1, float32x4_t v2) {
-   // CHECK: test_vsubq_f32
+   // CHECK-LABEL: test_vsubq_f32
   return vsubq_f32(v1, v2);
   // CHECK: fsub {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 float64x2_t test_vsubq_f64(float64x2_t v1, float64x2_t v2) {
-  // CHECK: test_vsubq_f64
+  // CHECK-LABEL: test_vsubq_f64
   return vsubq_f64(v1, v2);
   // CHECK: fsub {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 uint8x16_t test_vsubq_u8(uint8x16_t v1, uint8x16_t v2) {
-   // CHECK: test_vsubq_u8
+   // CHECK-LABEL: test_vsubq_u8
   return vsubq_u8(v1, v2);
   // CHECK: sub {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint16x8_t test_vsubq_u16(uint16x8_t v1, uint16x8_t v2) {
-   // CHECK: test_vsubq_u16
+   // CHECK-LABEL: test_vsubq_u16
   return vsubq_u16(v1, v2);
   // CHECK: sub {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
@@ -227,98 +227,98 @@
 }
 
 uint64x2_t test_vsubq_u64(uint64x2_t v1, uint64x2_t v2) {
-   // CHECK: test_vsubq_u64
+   // CHECK-LABEL: test_vsubq_u64
   return vsubq_u64(v1, v2);
   // CHECK: sub {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 int8x8_t test_vmul_s8(int8x8_t v1, int8x8_t v2) {
-  // CHECK: test_vmul_s8
+  // CHECK-LABEL: test_vmul_s8
   return vmul_s8(v1, v2);
   // CHECK: mul {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 int16x4_t test_vmul_s16(int16x4_t v1, int16x4_t v2) {
-  // CHECK: test_vmul_s16
+  // CHECK-LABEL: test_vmul_s16
   return vmul_s16(v1, v2);
   // CHECK: mul {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 int32x2_t test_vmul_s32(int32x2_t v1, int32x2_t v2) {
-  // CHECK: test_vmul_s32
+  // CHECK-LABEL: test_vmul_s32
   return vmul_s32(v1, v2);
   // CHECK: mul {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 float32x2_t test_vmul_f32(float32x2_t v1, float32x2_t v2) {
-  // CHECK: test_vmul_f32
+  // CHECK-LABEL: test_vmul_f32
   return vmul_f32(v1, v2);
   // CHECK: fmul {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 
 uint8x8_t test_vmul_u8(uint8x8_t v1, uint8x8_t v2) {
-  // CHECK: test_vmul_u8
+  // CHECK-LABEL: test_vmul_u8
   return vmul_u8(v1, v2);
   // CHECK: mul {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint16x4_t test_vmul_u16(uint16x4_t v1, uint16x4_t v2) {
-  // CHECK: test_vmul_u16
+  // CHECK-LABEL: test_vmul_u16
   return vmul_u16(v1, v2);
   // CHECK: mul {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint32x2_t test_vmul_u32(uint32x2_t v1, uint32x2_t v2) {
-  // CHECK: test_vmul_u32
+  // CHECK-LABEL: test_vmul_u32
   return vmul_u32(v1, v2);
   // CHECK: mul {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 int8x16_t test_vmulq_s8(int8x16_t v1, int8x16_t v2) {
-  // CHECK: test_vmulq_s8
+  // CHECK-LABEL: test_vmulq_s8
   return vmulq_s8(v1, v2);
   // CHECK: mul {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 int16x8_t test_vmulq_s16(int16x8_t v1, int16x8_t v2) {
-  // CHECK: test_vmulq_s16
+  // CHECK-LABEL: test_vmulq_s16
   return vmulq_s16(v1, v2);
   // CHECK: mul {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int32x4_t test_vmulq_s32(int32x4_t v1, int32x4_t v2) {
-  // CHECK: test_vmulq_s32
+  // CHECK-LABEL: test_vmulq_s32
   return vmulq_s32(v1, v2);
   // CHECK: mul {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
     
 uint8x16_t test_vmulq_u8(uint8x16_t v1, uint8x16_t v2) {
-  // CHECK: test_vmulq_u8
+  // CHECK-LABEL: test_vmulq_u8
   return vmulq_u8(v1, v2);
   // CHECK: mul {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint16x8_t test_vmulq_u16(uint16x8_t v1, uint16x8_t v2) {
-  // CHECK: test_vmulq_u16
+  // CHECK-LABEL: test_vmulq_u16
   return vmulq_u16(v1, v2);
   // CHECK: mul {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint32x4_t test_vmulq_u32(uint32x4_t v1, uint32x4_t v2) {
-  // CHECK: test_vmulq_u32
+  // CHECK-LABEL: test_vmulq_u32
   return vmulq_u32(v1, v2);
   // CHECK: mul {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 float32x4_t test_vmulq_f32(float32x4_t v1, float32x4_t v2) {
-  // CHECK: test_vmulq_f32
+  // CHECK-LABEL: test_vmulq_f32
   return vmulq_f32(v1, v2);
   // CHECK: fmul {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 float64x2_t test_vmulq_f64(float64x2_t v1, float64x2_t v2) {
-  // CHECK: test_vmulq_f64
+  // CHECK-LABEL: test_vmulq_f64
   return vmulq_f64(v1, v2);
   // CHECK: fmul {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
@@ -337,971 +337,1048 @@
 
 
 int8x8_t test_vmla_s8(int8x8_t v1, int8x8_t v2, int8x8_t v3) {
-  // CHECK: test_vmla_s8
+  // CHECK-LABEL: test_vmla_s8
   return vmla_s8(v1, v2, v3);
   // CHECK: mla {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 int8x8_t test_vmla_s16(int16x4_t v1, int16x4_t v2, int16x4_t v3) {
-  // CHECK: test_vmla_s16
+  // CHECK-LABEL: test_vmla_s16
   return vmla_s16(v1, v2, v3);
   // CHECK: mla {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 int32x2_t test_vmla_s32(int32x2_t v1, int32x2_t v2, int32x2_t v3) {
-  // CHECK: test_vmla_s32
+  // CHECK-LABEL: test_vmla_s32
   return vmla_s32(v1, v2, v3);
   // CHECK: mla {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 float32x2_t test_vmla_f32(float32x2_t v1, float32x2_t v2, float32x2_t v3) {
-  // CHECK: test_vmla_f32
+  // CHECK-LABEL: test_vmla_f32
   return vmla_f32(v1, v2, v3);
   // CHECK: fmla {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 uint8x8_t test_vmla_u8(uint8x8_t v1, uint8x8_t v2, uint8x8_t v3) {
-  // CHECK: test_vmla_u8
+  // CHECK-LABEL: test_vmla_u8
   return vmla_u8(v1, v2, v3);
   // CHECK: mla {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint16x4_t test_vmla_u16(uint16x4_t v1, uint16x4_t v2, uint16x4_t v3) {
-  // CHECK: test_vmla_u16
+  // CHECK-LABEL: test_vmla_u16
   return vmla_u16(v1, v2, v3);
   // CHECK: mla {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint32x2_t test_vmla_u32(uint32x2_t v1, uint32x2_t v2, uint32x2_t v3) {
-  // CHECK: test_vmla_u32
+  // CHECK-LABEL: test_vmla_u32
   return vmla_u32(v1, v2, v3);
   // CHECK: mla {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 int8x16_t test_vmlaq_s8(int8x16_t v1, int8x16_t v2, int8x16_t v3) {
-  // CHECK: test_vmlaq_s8
+  // CHECK-LABEL: test_vmlaq_s8
   return vmlaq_s8(v1, v2, v3);
   // CHECK: mla {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 int16x8_t test_vmlaq_s16(int16x8_t v1, int16x8_t v2, int16x8_t v3) {
-  // CHECK: test_vmlaq_s16
+  // CHECK-LABEL: test_vmlaq_s16
   return vmlaq_s16(v1, v2, v3);
   // CHECK: mla {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int32x4_t test_vmlaq_s32(int32x4_t v1, int32x4_t v2, int32x4_t v3) {
-  // CHECK: test_vmlaq_s32
+  // CHECK-LABEL: test_vmlaq_s32
   return vmlaq_s32(v1, v2, v3);
   // CHECK: mla {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 } 
 
 float32x4_t test_vmlaq_f32(float32x4_t v1, float32x4_t v2, float32x4_t v3) {
-  // CHECK: test_vmlaq_f32
+  // CHECK-LABEL: test_vmlaq_f32
   return vmlaq_f32(v1, v2, v3);
   // CHECK: fmla {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint8x16_t test_vmlaq_u8(uint8x16_t v1, uint8x16_t v2, uint8x16_t v3) {
-   // CHECK: test_vmlaq_u8
+   // CHECK-LABEL: test_vmlaq_u8
   return vmlaq_u8(v1, v2, v3);
   // CHECK: mla {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint16x8_t test_vmlaq_u16(uint16x8_t v1, uint16x8_t v2, uint16x8_t v3) {
-  // CHECK: test_vmlaq_u16
+  // CHECK-LABEL: test_vmlaq_u16
   return vmlaq_u16(v1, v2, v3);
   // CHECK: mla {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint32x4_t test_vmlaq_u32(uint32x4_t v1, uint32x4_t v2, uint32x4_t v3) {
-  // CHECK: test_vmlaq_u32
+  // CHECK-LABEL: test_vmlaq_u32
   return vmlaq_u32(v1, v2, v3);
   // CHECK: mla {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 float64x2_t test_vmlaq_f64(float64x2_t v1, float64x2_t v2, float64x2_t v3) {
-  // CHECK: test_vmlaq_f64
+  // CHECK-LABEL: test_vmlaq_f64
   return vmlaq_f64(v1, v2, v3);
   // CHECK: fmla {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 int8x8_t test_vmls_s8(int8x8_t v1, int8x8_t v2, int8x8_t v3) {
-  // CHECK: test_vmls_s8
+  // CHECK-LABEL: test_vmls_s8
   return vmls_s8(v1, v2, v3);
   // CHECK: mls {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 int8x8_t test_vmls_s16(int16x4_t v1, int16x4_t v2, int16x4_t v3) {
-  // CHECK: test_vmls_s16
+  // CHECK-LABEL: test_vmls_s16
   return vmls_s16(v1, v2, v3);
   // CHECK: mls {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 int32x2_t test_vmls_s32(int32x2_t v1, int32x2_t v2, int32x2_t v3) {
-  // CHECK: test_vmls_s32
+  // CHECK-LABEL: test_vmls_s32
   return vmls_s32(v1, v2, v3);
   // CHECK: mls {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 float32x2_t test_vmls_f32(float32x2_t v1, float32x2_t v2, float32x2_t v3) {
-  // CHECK: test_vmls_f32
+  // CHECK-LABEL: test_vmls_f32
   return vmls_f32(v1, v2, v3);
   // CHECK: fmls {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 uint8x8_t test_vmls_u8(uint8x8_t v1, uint8x8_t v2, uint8x8_t v3) {
-  // CHECK: test_vmls_u8
+  // CHECK-LABEL: test_vmls_u8
   return vmls_u8(v1, v2, v3);
   // CHECK: mls {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint16x4_t test_vmls_u16(uint16x4_t v1, uint16x4_t v2, uint16x4_t v3) {
-  // CHECK: test_vmls_u16
+  // CHECK-LABEL: test_vmls_u16
   return vmls_u16(v1, v2, v3);
   // CHECK: mls {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint32x2_t test_vmls_u32(uint32x2_t v1, uint32x2_t v2, uint32x2_t v3) {
-  // CHECK: test_vmls_u32
+  // CHECK-LABEL: test_vmls_u32
   return vmls_u32(v1, v2, v3);
   // CHECK: mls {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 int8x16_t test_vmlsq_s8(int8x16_t v1, int8x16_t v2, int8x16_t v3) {
-  // CHECK: test_vmlsq_s8
+  // CHECK-LABEL: test_vmlsq_s8
   return vmlsq_s8(v1, v2, v3);
   // CHECK: mls {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 int16x8_t test_vmlsq_s16(int16x8_t v1, int16x8_t v2, int16x8_t v3) {
-  // CHECK: test_vmlsq_s16
+  // CHECK-LABEL: test_vmlsq_s16
   return vmlsq_s16(v1, v2, v3);
   // CHECK: mls {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int32x4_t test_vmlsq_s32(int32x4_t v1, int32x4_t v2, int32x4_t v3) {
-  // CHECK: test_vmlsq_s32
+  // CHECK-LABEL: test_vmlsq_s32
   return vmlsq_s32(v1, v2, v3);
   // CHECK: mls {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 float32x4_t test_vmlsq_f32(float32x4_t v1, float32x4_t v2, float32x4_t v3) {
-  // CHECK: test_vmlsq_f32
+  // CHECK-LABEL: test_vmlsq_f32
   return vmlsq_f32(v1, v2, v3);
   // CHECK: fmls {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 uint8x16_t test_vmlsq_u8(uint8x16_t v1, uint8x16_t v2, uint8x16_t v3) {
-  // CHECK: test_vmlsq_u8
+  // CHECK-LABEL: test_vmlsq_u8
   return vmlsq_u8(v1, v2, v3);
   // CHECK: mls {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint16x8_t test_vmlsq_u16(uint16x8_t v1, uint16x8_t v2, uint16x8_t v3) {
-  // CHECK: test_vmlsq_u16
+  // CHECK-LABEL: test_vmlsq_u16
   return vmlsq_u16(v1, v2, v3);
   // CHECK: mls {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint32x4_t test_vmlsq_u32(uint32x4_t v1, uint32x4_t v2, uint32x4_t v3) {
-  // CHECK: test_vmlsq_u32
+  // CHECK-LABEL: test_vmlsq_u32
   return vmlsq_u32(v1, v2, v3);
   // CHECK: mls {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 float64x2_t test_vmlsq_f64(float64x2_t v1, float64x2_t v2, float64x2_t v3) {
-  // CHECK: test_vmlsq_f64
+  // CHECK-LABEL: test_vmlsq_f64
   return vmlsq_f64(v1, v2, v3);
   // CHECK: fmls {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 float32x2_t test_vfma_f32(float32x2_t v1, float32x2_t v2, float32x2_t v3) {
-  // CHECK: test_vfma_f32
+  // CHECK-LABEL: test_vfma_f32
   return vfma_f32(v1, v2, v3);
   // CHECK: fmla {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 float32x4_t test_vfmaq_f32(float32x4_t v1, float32x4_t v2, float32x4_t v3) {
-  // CHECK: test_vfmaq_f32
+  // CHECK-LABEL: test_vfmaq_f32
   return vfmaq_f32(v1, v2, v3);
   // CHECK: fmla {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 float64x2_t test_vfmaq_f64(float64x2_t v1, float64x2_t v2, float64x2_t v3) {
-  // CHECK: test_vfmaq_f64
+  // CHECK-LABEL: test_vfmaq_f64
   return vfmaq_f64(v1, v2, v3);
   // CHECK: fmla {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 float32x2_t test_vfms_f32(float32x2_t v1, float32x2_t v2, float32x2_t v3) {
-  // CHECK: test_vfms_f32
+  // CHECK-LABEL: test_vfms_f32
   return vfms_f32(v1, v2, v3);
-  // CHECK: fmls v0.2s, v1.2s, v2.2s
+  // CHECK: fmls v0.2s, {{v1.2s, v2.2s|v2.2s, v1.2s}}
 }
 
 float32x4_t test_vfmsq_f32(float32x4_t v1, float32x4_t v2, float32x4_t v3) {
-  // CHECK: test_vfmsq_f32
+  // CHECK-LABEL: test_vfmsq_f32
   return vfmsq_f32(v1, v2, v3);
-  // CHECK: fmls v0.4s, v1.4s, v2.4s
+  // CHECK: fmls v0.4s, {{v1.4s, v2.4s|v2.4s, v1.4s}}
 }
 
 float64x2_t test_vfmsq_f64(float64x2_t v1, float64x2_t v2, float64x2_t v3) {
   // CHECK: vfmsq_f64
   return vfmsq_f64(v1, v2, v3);
-  // CHECK: fmls v0.2d, v1.2d, v2.2d
+  // CHECK: fmls v0.2d, {{v1.2d, v2.2d|v2.2d, v1.2d}}
 }
 
 float64x2_t test_vdivq_f64(float64x2_t v1, float64x2_t v2) {
-  // CHECK: test_vdivq_f64
+  // CHECK-LABEL: test_vdivq_f64
   return vdivq_f64(v1, v2);
   // CHECK: fdiv {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 float32x4_t test_vdivq_f32(float32x4_t v1, float32x4_t v2) {
-  // CHECK: test_vdivq_f32
+  // CHECK-LABEL: test_vdivq_f32
   return vdivq_f32(v1, v2);
   // CHECK: fdiv {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 float32x2_t test_vdiv_f32(float32x2_t v1, float32x2_t v2) {
-  // CHECK: test_vdiv_f32
+  // CHECK-LABEL: test_vdiv_f32
   return vdiv_f32(v1, v2);
   // CHECK: fdiv {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 int8x8_t test_vaba_s8(int8x8_t v1, int8x8_t v2, int8x8_t v3) {
-  // CHECK: test_vaba_s8
+  // CHECK-LABEL: test_vaba_s8
   return vaba_s8(v1, v2, v3);
   // CHECK: saba {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 int16x4_t test_vaba_s16(int16x4_t v1, int16x4_t v2, int16x4_t v3) {
-  // CHECK: test_vaba_s16
+  // CHECK-LABEL: test_vaba_s16
   return vaba_s16(v1, v2, v3);
   // CHECK: saba {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 int32x2_t test_vaba_s32(int32x2_t v1, int32x2_t v2, int32x2_t v3) {
-  // CHECK: test_vaba_s32
+  // CHECK-LABEL: test_vaba_s32
   return vaba_s32(v1, v2, v3);
   // CHECK: saba {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 uint8x8_t test_vaba_u8(uint8x8_t v1, uint8x8_t v2, uint8x8_t v3) {
-  // CHECK: test_vaba_u8
+  // CHECK-LABEL: test_vaba_u8
   return vaba_u8(v1, v2, v3);
   // CHECK: uaba {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint16x4_t test_vaba_u16(uint16x4_t v1, uint16x4_t v2, uint16x4_t v3) {
-  // CHECK: test_vaba_u16
+  // CHECK-LABEL: test_vaba_u16
   return vaba_u16(v1, v2, v3);
   // CHECK: uaba {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint32x2_t test_vaba_u32(uint32x2_t v1, uint32x2_t v2, uint32x2_t v3) {
-  // CHECK: test_vaba_u32
+  // CHECK-LABEL: test_vaba_u32
   return vaba_u32(v1, v2, v3);
   // CHECK: uaba {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 int8x16_t test_vabaq_s8(int8x16_t v1, int8x16_t v2, int8x16_t v3) {
-  // CHECK: test_vabaq_s8
+  // CHECK-LABEL: test_vabaq_s8
   return vabaq_s8(v1, v2, v3);
   // CHECK: saba {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 int16x8_t test_vabaq_s16(int16x8_t v1, int16x8_t v2, int16x8_t v3) {
-  // CHECK: test_vabaq_s16
+  // CHECK-LABEL: test_vabaq_s16
   return vabaq_s16(v1, v2, v3);
   // CHECK: saba {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int32x4_t test_vabaq_s32(int32x4_t v1, int32x4_t v2, int32x4_t v3) {
-  // CHECK: test_vabaq_s32
+  // CHECK-LABEL: test_vabaq_s32
   return vabaq_s32(v1, v2, v3);
   // CHECK: saba {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint8x16_t test_vabaq_u8(uint8x16_t v1, uint8x16_t v2, uint8x16_t v3) {
-  // CHECK: test_vabaq_u8
+  // CHECK-LABEL: test_vabaq_u8
   return vabaq_u8(v1, v2, v3);
   // CHECK: uaba {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint16x8_t test_vabaq_u16(uint16x8_t v1, uint16x8_t v2, uint16x8_t v3) {
-  // CHECK: test_vabaq_u16
+  // CHECK-LABEL: test_vabaq_u16
   return vabaq_u16(v1, v2, v3);
   // CHECK: uaba {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint32x4_t test_vabaq_u32(uint32x4_t v1, uint32x4_t v2, uint32x4_t v3) {
-  // CHECK: test_vabaq_u32
+  // CHECK-LABEL: test_vabaq_u32
   return vabaq_u32(v1, v2, v3);
   // CHECK: uaba {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 int8x8_t test_vabd_s8(int8x8_t v1, int8x8_t v2) {
-  // CHECK: test_vabd_s8
+  // CHECK-LABEL: test_vabd_s8
   return vabd_s8(v1, v2);
   // CHECK: sabd {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 int16x4_t test_vabd_s16(int16x4_t v1, int16x4_t v2) {
-  // CHECK: test_vabd_s16
+  // CHECK-LABEL: test_vabd_s16
   return vabd_s16(v1, v2);
   // CHECK: sabd {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 int32x2_t test_vabd_s32(int32x2_t v1, int32x2_t v2) {
-  // CHECK: test_vabd_s32
+  // CHECK-LABEL: test_vabd_s32
   return vabd_s32(v1, v2);
   // CHECK: sabd {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 uint8x8_t test_vabd_u8(uint8x8_t v1, uint8x8_t v2) {
-  // CHECK: test_vabd_u8
+  // CHECK-LABEL: test_vabd_u8
   return vabd_u8(v1, v2);
   // CHECK: uabd {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint16x4_t test_vabd_u16(uint16x4_t v1, uint16x4_t v2) {
-  // CHECK: test_vabd_u16
+  // CHECK-LABEL: test_vabd_u16
   return vabd_u16(v1, v2);
   // CHECK: uabd {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint32x2_t test_vabd_u32(uint32x2_t v1, uint32x2_t v2) {
-  // CHECK: test_vabd_u32
+  // CHECK-LABEL: test_vabd_u32
   return vabd_u32(v1, v2);
   // CHECK: uabd {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 float32x2_t test_vabd_f32(float32x2_t v1, float32x2_t v2) {
-  // CHECK: test_vabd_f32
+  // CHECK-LABEL: test_vabd_f32
   return vabd_f32(v1, v2);
   // CHECK: fabd {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 int8x16_t test_vabdq_s8(int8x16_t v1, int8x16_t v2) {
-  // CHECK: test_vabdq_s8
+  // CHECK-LABEL: test_vabdq_s8
   return vabdq_s8(v1, v2);
   // CHECK: sabd {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 int16x8_t test_vabdq_s16(int16x8_t v1, int16x8_t v2) {
-  // CHECK: test_vabdq_s16
+  // CHECK-LABEL: test_vabdq_s16
   return vabdq_s16(v1, v2);
   // CHECK: sabd {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int32x4_t test_vabdq_s32(int32x4_t v1, int32x4_t v2) {
-  // CHECK: test_vabdq_s32
+  // CHECK-LABEL: test_vabdq_s32
   return vabdq_s32(v1, v2);
   // CHECK: sabd {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint8x16_t test_vabdq_u8(uint8x16_t v1, uint8x16_t v2) {
-  // CHECK: test_vabdq_u8
+  // CHECK-LABEL: test_vabdq_u8
   return vabdq_u8(v1, v2);
   // CHECK: uabd {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint16x8_t test_vabdq_u16(uint16x8_t v1, uint16x8_t v2) {
-  // CHECK: test_vabdq_u16
+  // CHECK-LABEL: test_vabdq_u16
   return vabdq_u16(v1, v2);
   // CHECK: uabd {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint32x4_t test_vabdq_u32(uint32x4_t v1, uint32x4_t v2) {
-  // CHECK: test_vabdq_u32
+  // CHECK-LABEL: test_vabdq_u32
   return vabdq_u32(v1, v2);
   // CHECK: uabd {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 float32x4_t test_vabdq_f32(float32x4_t v1, float32x4_t v2) {
-  // CHECK: test_vabdq_f32
+  // CHECK-LABEL: test_vabdq_f32
   return vabdq_f32(v1, v2);
   // CHECK: fabd {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 float64x2_t test_vabdq_f64(float64x2_t v1, float64x2_t v2) {
-  // CHECK: test_vabdq_f64
+  // CHECK-LABEL: test_vabdq_f64
   return vabdq_f64(v1, v2);
   // CHECK: fabd {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 
 int8x8_t test_vbsl_s8(uint8x8_t v1, int8x8_t v2, int8x8_t v3) {
-  // CHECK: test_vbsl_s8
+  // CHECK-LABEL: test_vbsl_s8
   return vbsl_s8(v1, v2, v3);
   // CHECK: bsl {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 int8x8_t test_vbsl_s16(uint16x4_t v1, int16x4_t v2, int16x4_t v3) {
-  // CHECK: test_vbsl_s16
+  // CHECK-LABEL: test_vbsl_s16
   return vbsl_s16(v1, v2, v3);
   // CHECK: bsl {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 int32x2_t test_vbsl_s32(uint32x2_t v1, int32x2_t v2, int32x2_t v3) {
-  // CHECK: test_vbsl_s32
+  // CHECK-LABEL: test_vbsl_s32
   return vbsl_s32(v1, v2, v3);
   // CHECK: bsl {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint64x1_t test_vbsl_s64(uint64x1_t v1, uint64x1_t v2, uint64x1_t v3) {
-  // CHECK: test_vbsl_s64
+  // CHECK-LABEL: test_vbsl_s64
   return vbsl_s64(v1, v2, v3);
   // CHECK: bsl {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint8x8_t test_vbsl_u8(uint8x8_t v1, uint8x8_t v2, uint8x8_t v3) {
-  // CHECK: test_vbsl_u8
+  // CHECK-LABEL: test_vbsl_u8
   return vbsl_u8(v1, v2, v3);
   // CHECK: bsl {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint16x4_t test_vbsl_u16(uint16x4_t v1, uint16x4_t v2, uint16x4_t v3) {
-  // CHECK: test_vbsl_u16
+  // CHECK-LABEL: test_vbsl_u16
   return vbsl_u16(v1, v2, v3);
   // CHECK: bsl {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint32x2_t test_vbsl_u32(uint32x2_t v1, uint32x2_t v2, uint32x2_t v3) {
-  // CHECK: test_vbsl_u32
+  // CHECK-LABEL: test_vbsl_u32
   return vbsl_u32(v1, v2, v3);
   // CHECK: bsl {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint64x1_t test_vbsl_u64(uint64x1_t v1, uint64x1_t v2, uint64x1_t v3) {
-  // CHECK: test_vbsl_u64
+  // CHECK-LABEL: test_vbsl_u64
   return vbsl_u64(v1, v2, v3);
   // CHECK: bsl {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 float32x2_t test_vbsl_f32(float32x2_t v1, float32x2_t v2, float32x2_t v3) {
-  // CHECK: test_vbsl_f32
+  // CHECK-LABEL: test_vbsl_f32
   return vbsl_f32(v1, v2, v3);
   // CHECK: bsl {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
+float64x1_t test_vbsl_f64(uint64x1_t v1, float64x1_t v2, float64x1_t v3) {
+  // CHECK-LABEL: test_vbsl_f64
+  return vbsl_f64(v1, v2, v3);
+  // CHECK: bsl {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
 poly8x8_t test_vbsl_p8(uint8x8_t v1, poly8x8_t v2, poly8x8_t v3) {
-  // CHECK: test_vbsl_p8
+  // CHECK-LABEL: test_vbsl_p8
   return vbsl_p8(v1, v2, v3);
   // CHECK: bsl {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 poly16x4_t test_vbsl_p16(uint16x4_t v1, poly16x4_t v2, poly16x4_t v3) {
-  // CHECK: test_vbsl_p16
+  // CHECK-LABEL: test_vbsl_p16
   return vbsl_p16(v1, v2, v3);
   // CHECK: bsl {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 int8x16_t test_vbslq_s8(uint8x16_t v1, int8x16_t v2, int8x16_t v3) {
-  // CHECK: test_vbslq_s8
+  // CHECK-LABEL: test_vbslq_s8
   return vbslq_s8(v1, v2, v3);
   // CHECK: bsl {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 int16x8_t test_vbslq_s16(uint16x8_t v1, int16x8_t v2, int16x8_t v3) {
-  // CHECK: test_vbslq_s16
+  // CHECK-LABEL: test_vbslq_s16
   return vbslq_s16(v1, v2, v3);
   // CHECK: bsl {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 int32x4_t test_vbslq_s32(uint32x4_t v1, int32x4_t v2, int32x4_t v3) {
-  // CHECK: test_vbslq_s32
+  // CHECK-LABEL: test_vbslq_s32
   return vbslq_s32(v1, v2, v3);
   // CHECK: bsl {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 int64x2_t test_vbslq_s64(uint64x2_t v1, int64x2_t v2, int64x2_t v3) {
-  // CHECK: test_vbslq_s64
+  // CHECK-LABEL: test_vbslq_s64
   return vbslq_s64(v1, v2, v3);
   // CHECK: bsl {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint8x16_t test_vbslq_u8(uint8x16_t v1, uint8x16_t v2, uint8x16_t v3) {
-  // CHECK: test_vbslq_u8
+  // CHECK-LABEL: test_vbslq_u8
   return vbslq_u8(v1, v2, v3);
   // CHECK: bsl {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint16x8_t test_vbslq_u16(uint16x8_t v1, uint16x8_t v2, uint16x8_t v3) {
-  // CHECK: test_vbslq_u16
+  // CHECK-LABEL: test_vbslq_u16
   return vbslq_u16(v1, v2, v3);
   // CHECK: bsl {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 int32x4_t test_vbslq_u32(uint32x4_t v1, int32x4_t v2, int32x4_t v3) {
-  // CHECK: test_vbslq_u32
+  // CHECK-LABEL: test_vbslq_u32
   return vbslq_s32(v1, v2, v3);
   // CHECK: bsl {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint64x2_t test_vbslq_u64(uint64x2_t v1, uint64x2_t v2, uint64x2_t v3) {
-  // CHECK: test_vbslq_u64
+  // CHECK-LABEL: test_vbslq_u64
   return vbslq_u64(v1, v2, v3);
   // CHECK: bsl {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 float32x4_t test_vbslq_f32(uint32x4_t v1, float32x4_t v2, float32x4_t v3) {
-  // CHECK: test_vbslq_f32
+  // CHECK-LABEL: test_vbslq_f32
   return vbslq_f32(v1, v2, v3);
   // CHECK: bsl {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 poly8x16_t test_vbslq_p8(uint8x16_t v1, poly8x16_t v2, poly8x16_t v3) {
-  // CHECK: test_vbslq_p8
+  // CHECK-LABEL: test_vbslq_p8
   return vbslq_p8(v1, v2, v3);
   // CHECK: bsl {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 poly16x8_t test_vbslq_p16(uint16x8_t v1, poly16x8_t v2, poly16x8_t v3) {
-  // CHECK: test_vbslq_p16
+  // CHECK-LABEL: test_vbslq_p16
   return vbslq_p16(v1, v2, v3);
   // CHECK: bsl {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 float64x2_t test_vbslq_f64(uint64x2_t v1, float64x2_t v2, float64x2_t v3) {
-  // CHECK: test_vbslq_f64
+  // CHECK-LABEL: test_vbslq_f64
   return vbslq_f64(v1, v2, v3);
   // CHECK: bsl {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 float32x2_t test_vrecps_f32(float32x2_t v1, float32x2_t v2) {
-   // CHECK: test_vrecps_f32
+   // CHECK-LABEL: test_vrecps_f32
    return vrecps_f32(v1, v2);
    // CHECK: frecps {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 float32x4_t test_vrecpsq_f32(float32x4_t v1, float32x4_t v2) {
-   // CHECK: test_vrecpsq_f32
+   // CHECK-LABEL: test_vrecpsq_f32
    return vrecpsq_f32(v1, v2);
    // CHECK: frecps {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 float64x2_t test_vrecpsq_f64(float64x2_t v1, float64x2_t v2) {
-   // CHECK: test_vrecpsq_f64
+   // CHECK-LABEL: test_vrecpsq_f64
   return vrecpsq_f64(v1, v2);
   // CHECK: frecps {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 float32x2_t test_vrsqrts_f32(float32x2_t v1, float32x2_t v2) {
-   // CHECK: test_vrsqrts_f32
+   // CHECK-LABEL: test_vrsqrts_f32
   return vrsqrts_f32(v1, v2);
   // CHECK: frsqrts {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 float32x4_t test_vrsqrtsq_f32(float32x4_t v1, float32x4_t v2) {
-   // CHECK: test_vrsqrtsq_f32
+   // CHECK-LABEL: test_vrsqrtsq_f32
   return vrsqrtsq_f32(v1, v2);
   // CHECK: frsqrts {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 float64x2_t test_vrsqrtsq_f64(float64x2_t v1, float64x2_t v2) {
-   // CHECK: test_vrsqrtsq_f64
+   // CHECK-LABEL: test_vrsqrtsq_f64
   return vrsqrtsq_f64(v1, v2);
   // CHECK: frsqrts {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 uint32x2_t test_vcage_f32(float32x2_t v1, float32x2_t v2) {
-  // CHECK: test_vcage_f32
+  // CHECK-LABEL: test_vcage_f32
   return vcage_f32(v1, v2);
   // CHECK: facge {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
+uint64x1_t test_vcage_f64(float64x1_t a, float64x1_t b) {
+  // CHECK-LABEL: test_vcage_f64
+  return vcage_f64(a, b);
+  // CHECK: facge {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+}
+
 uint32x4_t test_vcageq_f32(float32x4_t v1, float32x4_t v2) {
-  // CHECK: test_vcageq_f32
+  // CHECK-LABEL: test_vcageq_f32
   return vcageq_f32(v1, v2);
   // CHECK: facge {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint64x2_t test_vcageq_f64(float64x2_t v1, float64x2_t v2) {
-  // CHECK: test_vcageq_f64
+  // CHECK-LABEL: test_vcageq_f64
   return vcageq_f64(v1, v2);
   // CHECK: facge {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 uint32x2_t test_vcagt_f32(float32x2_t v1, float32x2_t v2) {
-  // CHECK: test_vcagt_f32
+  // CHECK-LABEL: test_vcagt_f32
   return vcagt_f32(v1, v2);
   // CHECK: facgt {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
+uint64x1_t test_vcagt_f64(float64x1_t a, float64x1_t b) {
+  // CHECK-LABEL: test_vcagt_f64
+  return vcagt_f64(a, b);
+  // CHECK: facgt {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+}
+
 uint32x4_t test_vcagtq_f32(float32x4_t v1, float32x4_t v2) {
-  // CHECK: test_vcagtq_f32
+  // CHECK-LABEL: test_vcagtq_f32
   return vcagtq_f32(v1, v2);
   // CHECK: facgt {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint64x2_t test_vcagtq_f64(float64x2_t v1, float64x2_t v2) {
-  // CHECK: test_vcagtq_f64
+  // CHECK-LABEL: test_vcagtq_f64
   return vcagtq_f64(v1, v2);
   // CHECK: facgt {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 uint32x2_t test_vcale_f32(float32x2_t v1, float32x2_t v2) {
-  // CHECK: test_vcale_f32
+  // CHECK-LABEL: test_vcale_f32
   return vcale_f32(v1, v2);
- // Using registers other than v0, v1 are possible, but would be odd.
+  // Using registers other than v0, v1 are possible, but would be odd.
   // CHECK: facge {{v[0-9]+}}.2s, v1.2s, v0.2s
 }
 
+uint64x1_t test_vcale_f64(float64x1_t a, float64x1_t b) {
+  // CHECK-LABEL: test_vcale_f64
+  return vcale_f64(a, b);
+  // CHECK: facge {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+}
+
 uint32x4_t test_vcaleq_f32(float32x4_t v1, float32x4_t v2) {
-  // CHECK: test_vcaleq_f32
+  // CHECK-LABEL: test_vcaleq_f32
   return vcaleq_f32(v1, v2);
   // Using registers other than v0, v1 are possible, but would be odd.
   // CHECK: facge {{v[0-9]+}}.4s, v1.4s, v0.4s
 }
 
 uint64x2_t test_vcaleq_f64(float64x2_t v1, float64x2_t v2) {
-  // CHECK: test_vcaleq_f64
+  // CHECK-LABEL: test_vcaleq_f64
   return vcaleq_f64(v1, v2);
   // Using registers other than v0, v1 are possible, but would be odd.
   // CHECK: facge {{v[0-9]+}}.2d, v1.2d, v0.2d
 }
 
 uint32x2_t test_vcalt_f32(float32x2_t v1, float32x2_t v2) {
-  // CHECK: test_vcalt_f32
+  // CHECK-LABEL: test_vcalt_f32
   return vcalt_f32(v1, v2);
   // Using registers other than v0, v1 are possible, but would be odd.
   // CHECK: facgt {{v[0-9]+}}.2s, v1.2s, v0.2s
 }
 
+uint64x1_t test_vcalt_f64(float64x1_t a, float64x1_t b) {
+  // CHECK-LABEL: test_vcalt_f64
+  return vcalt_f64(a, b);
+  // CHECK: facgt {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+}
+
 uint32x4_t test_vcaltq_f32(float32x4_t v1, float32x4_t v2) {
-  // CHECK: test_vcaltq_f32
+  // CHECK-LABEL: test_vcaltq_f32
   return vcaltq_f32(v1, v2);
   // Using registers other than v0, v1 are possible, but would be odd.
   // CHECK: facgt {{v[0-9]+}}.4s, v1.4s, v0.4s
 }
 
 uint64x2_t test_vcaltq_f64(float64x2_t v1, float64x2_t v2) {
-  // CHECK: test_vcaltq_f64
+  // CHECK-LABEL: test_vcaltq_f64
   return vcaltq_f64(v1, v2);
   // Using registers other than v0, v1 are possible, but would be odd.
   // CHECK: facgt {{v[0-9]+}}.2d, v1.2d, v0.2d
 }
 
 uint8x8_t test_vtst_s8(int8x8_t v1, int8x8_t v2) {
-   // CHECK: test_vtst_s8
+   // CHECK-LABEL: test_vtst_s8
   return vtst_s8(v1, v2);
   // CHECK: cmtst {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint16x4_t test_vtst_s16(int16x4_t v1, int16x4_t v2) {
-   // CHECK: test_vtst_s16
+   // CHECK-LABEL: test_vtst_s16
   return vtst_s16(v1, v2);
   // CHECK: cmtst {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint32x2_t test_vtst_s32(int32x2_t v1, int32x2_t v2) {
-   // CHECK: test_vtst_s32
+   // CHECK-LABEL: test_vtst_s32
   return vtst_s32(v1, v2);
   // CHECK: cmtst {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 uint8x8_t test_vtst_u8(uint8x8_t v1, uint8x8_t v2) {
-   // CHECK: test_vtst_u8
+   // CHECK-LABEL: test_vtst_u8
   return vtst_u8(v1, v2);
   // CHECK: cmtst {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint16x4_t test_vtst_u16(uint16x4_t v1, uint16x4_t v2) {
-   // CHECK: test_vtst_u16
+   // CHECK-LABEL: test_vtst_u16
   return vtst_u16(v1, v2);
   // CHECK: cmtst {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint32x2_t test_vtst_u32(uint32x2_t v1, uint32x2_t v2) {
-   // CHECK: test_vtst_u32
+   // CHECK-LABEL: test_vtst_u32
   return vtst_u32(v1, v2);
   // CHECK: cmtst {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 uint8x16_t test_vtstq_s8(int8x16_t v1, int8x16_t v2) {
-   // CHECK: test_vtstq_s8
+   // CHECK-LABEL: test_vtstq_s8
   return vtstq_s8(v1, v2);
   // CHECK: cmtst {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint16x8_t test_vtstq_s16(int16x8_t v1, int16x8_t v2) {
-   // CHECK: test_vtstq_s16
+   // CHECK-LABEL: test_vtstq_s16
   return vtstq_s16(v1, v2);
   // CHECK: cmtst {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint32x4_t test_vtstq_s32(int32x4_t v1, int32x4_t v2) {
-   // CHECK: test_vtstq_s32
+   // CHECK-LABEL: test_vtstq_s32
   return vtstq_s32(v1, v2);
   // CHECK: cmtst {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint8x16_t test_vtstq_u8(uint8x16_t v1, uint8x16_t v2) {
-   // CHECK: test_vtstq_u8
+   // CHECK-LABEL: test_vtstq_u8
   return vtstq_u8(v1, v2);
   // CHECK: cmtst {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint16x8_t test_vtstq_u16(uint16x8_t v1, uint16x8_t v2) {
-   // CHECK: test_vtstq_u16
+   // CHECK-LABEL: test_vtstq_u16
   return vtstq_u16(v1, v2);
   // CHECK: cmtst {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint32x4_t test_vtstq_u32(uint32x4_t v1, uint32x4_t v2) {
-   // CHECK: test_vtstq_u32
+   // CHECK-LABEL: test_vtstq_u32
   return vtstq_u32(v1, v2);
   // CHECK: cmtst {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint64x2_t test_vtstq_s64(int64x2_t v1, int64x2_t v2) {
-   // CHECK: test_vtstq_s64
+   // CHECK-LABEL: test_vtstq_s64
   return vtstq_s64(v1, v2);
   // CHECK: cmtst {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 uint64x2_t test_vtstq_u64(uint64x2_t v1, uint64x2_t v2) {
-   // CHECK: test_vtstq_u64
+   // CHECK-LABEL: test_vtstq_u64
   return vtstq_u64(v1, v2);
   // CHECK: cmtst {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 uint8x8_t test_vtst_p8(poly8x8_t v1, poly8x8_t v2) {
-   // CHECK: test_vtst_p8
+   // CHECK-LABEL: test_vtst_p8
   return vtst_p8(v1, v2);
   // CHECK: cmtst {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint16x4_t test_vtst_p16(poly16x4_t v1, poly16x4_t v2) {
-   // CHECK: test_vtst_p16
+   // CHECK-LABEL: test_vtst_p16
   return vtst_p16(v1, v2);
   // CHECK: cmtst {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint8x16_t test_vtstq_p8(poly8x16_t v1, poly8x16_t v2) {
-   // CHECK: test_vtstq_p8
+   // CHECK-LABEL: test_vtstq_p8
   return vtstq_p8(v1, v2);
   // CHECK: cmtst {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint16x8_t test_vtstq_p16(poly16x8_t v1, poly16x8_t v2) {
-   // CHECK: test_vtstq_p16
+   // CHECK-LABEL: test_vtstq_p16
   return vtstq_p16(v1, v2);
   // CHECK: cmtst {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
+uint64x1_t test_vtst_s64(int64x1_t a, int64x1_t b) {
+  // CHECK-LABEL: test_vtst_s64
+  return vtst_s64(a, b);
+  // CHECK: cmtst {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+}
+
+uint64x1_t test_vtst_u64(uint64x1_t a, uint64x1_t b) {
+  // CHECK-LABEL: test_vtst_u64
+  return vtst_u64(a, b);
+  // CHECK: cmtst {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+}
 
 uint8x8_t test_vceq_s8(int8x8_t v1, int8x8_t v2) {
-  // CHECK: test_vceq_s8
+  // CHECK-LABEL: test_vceq_s8
   return vceq_s8(v1, v2);
   // CHECK: cmeq {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint16x4_t test_vceq_s16(int16x4_t v1, int16x4_t v2) {
-  // CHECK: test_vceq_s16
+  // CHECK-LABEL: test_vceq_s16
   return vceq_s16(v1, v2);
   // CHECK: cmeq {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint32x2_t test_vceq_s32(int32x2_t v1, int32x2_t v2) {
-  // CHECK: test_vceq_s32
+  // CHECK-LABEL: test_vceq_s32
   return vceq_s32(v1, v2);
   // CHECK: cmeq {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
+uint64x1_t test_vceq_s64(int64x1_t a, int64x1_t b) {
+  // CHECK-LABEL: test_vceq_s64
+  return vceq_s64(a, b);
+  // CHECK: cmeq {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+}
+
+uint64x1_t test_vceq_u64(uint64x1_t a, uint64x1_t b) {
+  // CHECK-LABEL: test_vceq_u64
+  return vceq_u64(a, b);
+  // CHECK: cmeq {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+}
+
 uint32x2_t test_vceq_f32(float32x2_t v1, float32x2_t v2) {
-  // CHECK: test_vceq_f32
+  // CHECK-LABEL: test_vceq_f32
   return vceq_f32(v1, v2);
   // CHECK: fcmeq {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
+uint64x1_t test_vceq_f64(float64x1_t a, float64x1_t b) {
+  // CHECK-LABEL: test_vceq_f64
+  return vceq_f64(a, b);
+  // CHECK: fcmeq {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+}
+
 uint8x8_t test_vceq_u8(uint8x8_t v1, uint8x8_t v2) {
-  // CHECK: test_vceq_u8
+  // CHECK-LABEL: test_vceq_u8
   return vceq_u8(v1, v2);
   // CHECK: cmeq {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint16x4_t test_vceq_u16(uint16x4_t v1, uint16x4_t v2) {
-  // CHECK: test_vceq_u16
+  // CHECK-LABEL: test_vceq_u16
   return vceq_u16(v1, v2);
   // CHECK: cmeq {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint32x2_t test_vceq_u32(uint32x2_t v1, uint32x2_t v2) {
-  // CHECK: test_vceq_u32
+  // CHECK-LABEL: test_vceq_u32
   return vceq_u32(v1, v2);
   // CHECK: cmeq {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 uint8x8_t test_vceq_p8(poly8x8_t v1, poly8x8_t v2) {
-  // CHECK: test_vceq_p8
+  // CHECK-LABEL: test_vceq_p8
   return vceq_p8(v1, v2);
   // CHECK: cmeq {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint8x16_t test_vceqq_s8(int8x16_t v1, int8x16_t v2) {
-  // CHECK: test_vceqq_s8
+  // CHECK-LABEL: test_vceqq_s8
   return vceqq_s8(v1, v2);
   // CHECK: cmeq {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint16x8_t test_vceqq_s16(int16x8_t v1, int16x8_t v2) {
-  // CHECK: test_vceqq_s16
+  // CHECK-LABEL: test_vceqq_s16
   return vceqq_s16(v1, v2);
   // CHECK: cmeq {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint32x4_t test_vceqq_s32(int32x4_t v1, int32x4_t v2) {
-  // CHECK: test_vceqq_s32
+  // CHECK-LABEL: test_vceqq_s32
   return vceqq_s32(v1, v2);
   // CHECK: cmeq {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint32x4_t test_vceqq_f32(float32x4_t v1, float32x4_t v2) {
-  // CHECK: test_vceqq_f32
+  // CHECK-LABEL: test_vceqq_f32
   return vceqq_f32(v1, v2);
   // CHECK: fcmeq {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint8x16_t test_vceqq_u8(uint8x16_t v1, uint8x16_t v2) {
-  // CHECK: test_vceqq_u8
+  // CHECK-LABEL: test_vceqq_u8
   return vceqq_u8(v1, v2);
   // CHECK: cmeq {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint16x8_t test_vceqq_u16(uint16x8_t v1, uint16x8_t v2) {
-  // CHECK: test_vceqq_u16
+  // CHECK-LABEL: test_vceqq_u16
   return vceqq_u16(v1, v2);
   // CHECK: cmeq {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint32x4_t test_vceqq_u32(uint32x4_t v1, uint32x4_t v2) {
-  // CHECK: test_vceqq_u32
+  // CHECK-LABEL: test_vceqq_u32
   return vceqq_u32(v1, v2);
   // CHECK: cmeq {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint8x16_t test_vceqq_p8(poly8x16_t v1, poly8x16_t v2) {
-  // CHECK: test_vceqq_p8
+  // CHECK-LABEL: test_vceqq_p8
   return vceqq_p8(v1, v2);
   // CHECK: cmeq {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 
 uint64x2_t test_vceqq_s64(int64x2_t v1, int64x2_t v2) {
-  // CHECK: test_vceqq_s64
+  // CHECK-LABEL: test_vceqq_s64
   return vceqq_s64(v1, v2);
   // CHECK: cmeq {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 uint64x2_t test_vceqq_u64(uint64x2_t v1, uint64x2_t v2) {
-  // CHECK: test_vceqq_u64
+  // CHECK-LABEL: test_vceqq_u64
   return vceqq_u64(v1, v2);
   // CHECK: cmeq {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 uint64x2_t test_vceqq_f64(float64x2_t v1, float64x2_t v2) {
-  // CHECK: test_vceqq_f64
+  // CHECK-LABEL: test_vceqq_f64
   return vceqq_f64(v1, v2);
   // CHECK: fcmeq {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 uint8x8_t test_vcge_s8(int8x8_t v1, int8x8_t v2) {
-// CHECK: test_vcge_s8
+// CHECK-LABEL: test_vcge_s8
   return vcge_s8(v1, v2);
 // CHECK: cmge {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint16x4_t test_vcge_s16(int16x4_t v1, int16x4_t v2) {
-// CHECK: test_vcge_s16
+// CHECK-LABEL: test_vcge_s16
   return vcge_s16(v1, v2);
 // CHECK: cmge {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint32x2_t test_vcge_s32(int32x2_t v1, int32x2_t v2) {
-// CHECK: test_vcge_s32
+// CHECK-LABEL: test_vcge_s32
   return vcge_s32(v1, v2);
 // CHECK: cmge {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
+uint64x1_t test_vcge_s64(int64x1_t a, int64x1_t b) {
+  // CHECK-LABEL: test_vcge_s64
+  return vcge_s64(a, b);
+  // CHECK: cmge {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+}
+
+uint64x1_t test_vcge_u64(uint64x1_t a, uint64x1_t b) {
+  // CHECK-LABEL: test_vcge_u64
+  return vcge_u64(a, b);
+  // CHECK: cmhs {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+}
+
 uint32x2_t test_vcge_f32(float32x2_t v1, float32x2_t v2) {
-// CHECK: test_vcge_f32
+// CHECK-LABEL: test_vcge_f32
   return vcge_f32(v1, v2);
 // CHECK: fcmge {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
+uint64x1_t test_vcge_f64(float64x1_t a, float64x1_t b) {
+  // CHECK-LABEL: test_vcge_f64
+  return vcge_f64(a, b);
+  // CHECK: fcmge {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+}
+
 uint8x8_t test_vcge_u8(uint8x8_t v1, uint8x8_t v2) {
-// CHECK: test_vcge_u8
+// CHECK-LABEL: test_vcge_u8
   return vcge_u8(v1, v2);
 // CHECK: cmhs {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint16x4_t test_vcge_u16(uint16x4_t v1, uint16x4_t v2) {
-// CHECK: test_vcge_u16
+// CHECK-LABEL: test_vcge_u16
   return vcge_u16(v1, v2);
 // CHECK: cmhs {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint32x2_t test_vcge_u32(uint32x2_t v1, uint32x2_t v2) {
-// CHECK: test_vcge_u32
+// CHECK-LABEL: test_vcge_u32
   return vcge_u32(v1, v2);
 // CHECK: cmhs {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 uint8x16_t test_vcgeq_s8(int8x16_t v1, int8x16_t v2) {
-// CHECK: test_vcgeq_s8
+// CHECK-LABEL: test_vcgeq_s8
   return vcgeq_s8(v1, v2);
 // CHECK: cmge {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint16x8_t test_vcgeq_s16(int16x8_t v1, int16x8_t v2) {
-// CHECK: test_vcgeq_s16
+// CHECK-LABEL: test_vcgeq_s16
   return vcgeq_s16(v1, v2);
 // CHECK: cmge {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint32x4_t test_vcgeq_s32(int32x4_t v1, int32x4_t v2) {
-// CHECK: test_vcgeq_s32
+// CHECK-LABEL: test_vcgeq_s32
   return vcgeq_s32(v1, v2);
 // CHECK: cmge {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint32x4_t test_vcgeq_f32(float32x4_t v1, float32x4_t v2) {
-// CHECK: test_vcgeq_f32
+// CHECK-LABEL: test_vcgeq_f32
   return vcgeq_f32(v1, v2);
 // CHECK: fcmge {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint8x16_t test_vcgeq_u8(uint8x16_t v1, uint8x16_t v2) {
-// CHECK: test_vcgeq_u8
+// CHECK-LABEL: test_vcgeq_u8
   return vcgeq_u8(v1, v2);
 // CHECK: cmhs {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint16x8_t test_vcgeq_u16(uint16x8_t v1, uint16x8_t v2) {
-// CHECK: test_vcgeq_u16
+// CHECK-LABEL: test_vcgeq_u16
   return vcgeq_u16(v1, v2);
 // CHECK: cmhs {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint32x4_t test_vcgeq_u32(uint32x4_t v1, uint32x4_t v2) {
-// CHECK: test_vcgeq_u32
+// CHECK-LABEL: test_vcgeq_u32
   return vcgeq_u32(v1, v2);
 // CHECK: cmhs {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint64x2_t test_vcgeq_s64(int64x2_t v1, int64x2_t v2) {
-// CHECK: test_vcgeq_s64
+// CHECK-LABEL: test_vcgeq_s64
   return vcgeq_s64(v1, v2);
 // CHECK: cmge {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 uint64x2_t test_vcgeq_u64(uint64x2_t v1, uint64x2_t v2) {
-// CHECK: test_vcgeq_u64
+// CHECK-LABEL: test_vcgeq_u64
   return vcgeq_u64(v1, v2);
 // CHECK: cmhs {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 uint64x2_t test_vcgeq_f64(float64x2_t v1, float64x2_t v2) {
-// CHECK: test_vcgeq_f64
+// CHECK-LABEL: test_vcgeq_f64
   return vcgeq_f64(v1, v2);
 // CHECK: fcmge {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
@@ -1310,206 +1387,242 @@
 // LE condition predicate implemented as GE, so check reversed operands.
 // Using registers other than v0, v1 are possible, but would be odd.
 uint8x8_t test_vcle_s8(int8x8_t v1, int8x8_t v2) {
-  // CHECK: test_vcle_s8
+  // CHECK-LABEL: test_vcle_s8
   return vcle_s8(v1, v2);
   // CHECK: cmge {{v[0-9]+}}.8b, v1.8b, v0.8b
 }
 
 uint16x4_t test_vcle_s16(int16x4_t v1, int16x4_t v2) {
-  // CHECK: test_vcle_s16
+  // CHECK-LABEL: test_vcle_s16
   return vcle_s16(v1, v2);
   // CHECK: cmge {{v[0-9]+}}.4h, v1.4h, v0.4h
 }
 
 uint32x2_t test_vcle_s32(int32x2_t v1, int32x2_t v2) {
-  // CHECK: test_vcle_s32
+  // CHECK-LABEL: test_vcle_s32
   return vcle_s32(v1, v2);
   // CHECK: cmge {{v[0-9]+}}.2s, v1.2s, v0.2s
 }
 
+uint64x1_t test_vcle_s64(int64x1_t a, int64x1_t b) {
+  // CHECK-LABEL: test_vcle_s64
+  return vcle_s64(a, b);
+  // CHECK: cmge {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+}
+
+uint64x1_t test_vcle_u64(uint64x1_t a, uint64x1_t b) {
+  // CHECK-LABEL: test_vcle_u64
+  return vcle_u64(a, b);
+  // CHECK: cmhs {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+}
+
 uint32x2_t test_vcle_f32(float32x2_t v1, float32x2_t v2) {
-  // CHECK: test_vcle_f32
+  // CHECK-LABEL: test_vcle_f32
   return vcle_f32(v1, v2);
   // CHECK: fcmge {{v[0-9]+}}.2s, v1.2s, v0.2s
 }
 
+uint64x1_t test_vcle_f64(float64x1_t a, float64x1_t b) {
+  // CHECK-LABEL: test_vcle_f64
+  return vcle_f64(a, b);
+  // CHECK: fcmge {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+}
+
 uint8x8_t test_vcle_u8(uint8x8_t v1, uint8x8_t v2) {
-  // CHECK: test_vcle_u8
+  // CHECK-LABEL: test_vcle_u8
   return vcle_u8(v1, v2);
   // CHECK: cmhs {{v[0-9]+}}.8b, v1.8b, v0.8b
 }
 
 uint16x4_t test_vcle_u16(uint16x4_t v1, uint16x4_t v2) {
-  // CHECK: test_vcle_u16
+  // CHECK-LABEL: test_vcle_u16
   return vcle_u16(v1, v2);
   // CHECK: cmhs {{v[0-9]+}}.4h, v1.4h, v0.4h
 }
 
 uint32x2_t test_vcle_u32(uint32x2_t v1, uint32x2_t v2) {
-  // CHECK: test_vcle_u32
+  // CHECK-LABEL: test_vcle_u32
   return vcle_u32(v1, v2);
   // CHECK: cmhs {{v[0-9]+}}.2s, v1.2s, v0.2s
 }
 
 uint8x16_t test_vcleq_s8(int8x16_t v1, int8x16_t v2) {
-  // CHECK: test_vcleq_s8
+  // CHECK-LABEL: test_vcleq_s8
   return vcleq_s8(v1, v2);
   // CHECK: cmge {{v[0-9]+}}.16b, v1.16b, v0.16b
 }
 
 uint16x8_t test_vcleq_s16(int16x8_t v1, int16x8_t v2) {
-  // CHECK: test_vcleq_s16
+  // CHECK-LABEL: test_vcleq_s16
   return vcleq_s16(v1, v2);
   // CHECK: cmge {{v[0-9]+}}.8h, v1.8h, v0.8h
 }
 
 uint32x4_t test_vcleq_s32(int32x4_t v1, int32x4_t v2) {
-  // CHECK: test_vcleq_s32
+  // CHECK-LABEL: test_vcleq_s32
   return vcleq_s32(v1, v2);
   // CHECK: cmge {{v[0-9]+}}.4s, v1.4s, v0.4s
 }
 
 uint32x4_t test_vcleq_f32(float32x4_t v1, float32x4_t v2) {
-  // CHECK: test_vcleq_f32
+  // CHECK-LABEL: test_vcleq_f32
   return vcleq_f32(v1, v2);
   // CHECK: fcmge {{v[0-9]+}}.4s, v1.4s, v0.4s
 }
 
 uint8x16_t test_vcleq_u8(uint8x16_t v1, uint8x16_t v2) {
-  // CHECK: test_vcleq_u8
+  // CHECK-LABEL: test_vcleq_u8
   return vcleq_u8(v1, v2);
   // CHECK: cmhs {{v[0-9]+}}.16b, v1.16b, v0.16b
 }
 
 uint16x8_t test_vcleq_u16(uint16x8_t v1, uint16x8_t v2) {
-  // CHECK: test_vcleq_u16
+  // CHECK-LABEL: test_vcleq_u16
   return vcleq_u16(v1, v2);
   // CHECK: cmhs {{v[0-9]+}}.8h, v1.8h, v0.8h
 }
 
 uint32x4_t test_vcleq_u32(uint32x4_t v1, uint32x4_t v2) {
-  // CHECK: test_vcleq_u32
+  // CHECK-LABEL: test_vcleq_u32
   return vcleq_u32(v1, v2);
   // CHECK: cmhs {{v[0-9]+}}.4s, v1.4s, v0.4s
 }
 
 uint64x2_t test_vcleq_s64(int64x2_t v1, int64x2_t v2) {
-  // CHECK: test_vcleq_s64
+  // CHECK-LABEL: test_vcleq_s64
   return vcleq_s64(v1, v2);
   // CHECK: cmge {{v[0-9]+}}.2d, v1.2d, v0.2d
 }
 
 uint64x2_t test_vcleq_u64(uint64x2_t v1, uint64x2_t v2) {
-  // CHECK: test_vcleq_u64
+  // CHECK-LABEL: test_vcleq_u64
   return vcleq_u64(v1, v2);
   // CHECK: cmhs {{v[0-9]+}}.2d, v1.2d, v0.2d
 }
 
 uint64x2_t test_vcleq_f64(float64x2_t v1, float64x2_t v2) {
-  // CHECK: test_vcleq_f64
+  // CHECK-LABEL: test_vcleq_f64
   return vcleq_f64(v1, v2);
   // CHECK: fcmge {{v[0-9]+}}.2d, v1.2d, v0.2d
 }
 
 
 uint8x8_t test_vcgt_s8(int8x8_t v1, int8x8_t v2) {
-  // CHECK: test_vcgt_s8
+  // CHECK-LABEL: test_vcgt_s8
   return vcgt_s8(v1, v2);
   // CHECK: cmgt {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint16x4_t test_vcgt_s16(int16x4_t v1, int16x4_t v2) {
-  // CHECK: test_vcgt_s16
+  // CHECK-LABEL: test_vcgt_s16
   return vcgt_s16(v1, v2);
   // CHECK: cmgt {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint32x2_t test_vcgt_s32(int32x2_t v1, int32x2_t v2) {
-  // CHECK: test_vcgt_s32
+  // CHECK-LABEL: test_vcgt_s32
   return vcgt_s32(v1, v2);
   // CHECK: cmgt {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
+uint64x1_t test_vcgt_s64(int64x1_t a, int64x1_t b) {
+  // CHECK-LABEL: test_vcgt_s64
+  return vcgt_s64(a, b);
+  // CHECK: cmgt {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+}
+
+uint64x1_t test_vcgt_u64(uint64x1_t a, uint64x1_t b) {
+  // CHECK-LABEL: test_vcgt_u64
+  return vcgt_u64(a, b);
+  // CHECK: cmhi {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+}
+
 uint32x2_t test_vcgt_f32(float32x2_t v1, float32x2_t v2) {
-  // CHECK: test_vcgt_f32
+  // CHECK-LABEL: test_vcgt_f32
   return vcgt_f32(v1, v2);
   // CHECK: fcmgt {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
+uint64x1_t test_vcgt_f64(float64x1_t a, float64x1_t b) {
+  // CHECK-LABEL: test_vcgt_f64
+  return vcgt_f64(a, b);
+  // CHECK: fcmgt {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+}
+
 uint8x8_t test_vcgt_u8(uint8x8_t v1, uint8x8_t v2) {
-  // CHECK: test_vcgt_u8
+  // CHECK-LABEL: test_vcgt_u8
   return vcgt_u8(v1, v2);
   // CHECK: cmhi {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint16x4_t test_vcgt_u16(uint16x4_t v1, uint16x4_t v2) {
-  // CHECK: test_vcgt_u16
+  // CHECK-LABEL: test_vcgt_u16
   return vcgt_u16(v1, v2);
   // CHECK: cmhi {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint32x2_t test_vcgt_u32(uint32x2_t v1, uint32x2_t v2) {
-  // CHECK: test_vcgt_u32
+  // CHECK-LABEL: test_vcgt_u32
   return vcgt_u32(v1, v2);
   // CHECK: cmhi {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 uint8x16_t test_vcgtq_s8(int8x16_t v1, int8x16_t v2) {
-  // CHECK: test_vcgtq_s8
+  // CHECK-LABEL: test_vcgtq_s8
   return vcgtq_s8(v1, v2);
   // CHECK: cmgt {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint16x8_t test_vcgtq_s16(int16x8_t v1, int16x8_t v2) {
-  // CHECK: test_vcgtq_s16
+  // CHECK-LABEL: test_vcgtq_s16
   return vcgtq_s16(v1, v2);
   // CHECK: cmgt {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint32x4_t test_vcgtq_s32(int32x4_t v1, int32x4_t v2) {
-  // CHECK: test_vcgtq_s32
+  // CHECK-LABEL: test_vcgtq_s32
   return vcgtq_s32(v1, v2);
   // CHECK: cmgt {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint32x4_t test_vcgtq_f32(float32x4_t v1, float32x4_t v2) {
-  // CHECK: test_vcgtq_f32
+  // CHECK-LABEL: test_vcgtq_f32
   return vcgtq_f32(v1, v2);
   // CHECK: fcmgt {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint8x16_t test_vcgtq_u8(uint8x16_t v1, uint8x16_t v2) {
-  // CHECK: test_vcgtq_u8
+  // CHECK-LABEL: test_vcgtq_u8
   return vcgtq_u8(v1, v2);
   // CHECK: cmhi {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint16x8_t test_vcgtq_u16(uint16x8_t v1, uint16x8_t v2) {
-  // CHECK: test_vcgtq_u16
+  // CHECK-LABEL: test_vcgtq_u16
   return vcgtq_u16(v1, v2);
   // CHECK: cmhi {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint32x4_t test_vcgtq_u32(uint32x4_t v1, uint32x4_t v2) {
-  // CHECK: test_vcgtq_u32
+  // CHECK-LABEL: test_vcgtq_u32
   return vcgtq_u32(v1, v2);
   // CHECK: cmhi {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint64x2_t test_vcgtq_s64(int64x2_t v1, int64x2_t v2) {
-  // CHECK: test_vcgtq_s64
+  // CHECK-LABEL: test_vcgtq_s64
   return vcgtq_s64(v1, v2);
   // CHECK: cmgt {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 uint64x2_t test_vcgtq_u64(uint64x2_t v1, uint64x2_t v2) {
-  // CHECK: test_vcgtq_u64
+  // CHECK-LABEL: test_vcgtq_u64
   return vcgtq_u64(v1, v2);
   // CHECK: cmhi {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 uint64x2_t test_vcgtq_f64(float64x2_t v1, float64x2_t v2) {
-  // CHECK: test_vcgtq_f64
+  // CHECK-LABEL: test_vcgtq_f64
   return vcgtq_f64(v1, v2);
   // CHECK: fcmgt {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
@@ -1520,363 +1633,381 @@
 // Using registers other than v0, v1 are possible, but would be odd.
 
 uint8x8_t test_vclt_s8(int8x8_t v1, int8x8_t v2) {
-  // CHECK: test_vclt_s8
+  // CHECK-LABEL: test_vclt_s8
   return vclt_s8(v1, v2);
   // CHECK: cmgt {{v[0-9]+}}.8b, v1.8b, v0.8b
 }
 
 uint16x4_t test_vclt_s16(int16x4_t v1, int16x4_t v2) {
-  // CHECK: test_vclt_s16
+  // CHECK-LABEL: test_vclt_s16
   return vclt_s16(v1, v2);
   // CHECK: cmgt {{v[0-9]+}}.4h, v1.4h, v0.4h
 }
 
 uint32x2_t test_vclt_s32(int32x2_t v1, int32x2_t v2) {
-  // CHECK: test_vclt_s32
+  // CHECK-LABEL: test_vclt_s32
   return vclt_s32(v1, v2);
   // CHECK: cmgt {{v[0-9]+}}.2s, v1.2s, v0.2s
 }
 
+uint64x1_t test_vclt_s64(int64x1_t a, int64x1_t b) {
+  // CHECK-LABEL: test_vclt_s64
+  return vclt_s64(a, b);
+  // CHECK: cmgt {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+}
+
+uint64x1_t test_vclt_u64(uint64x1_t a, uint64x1_t b) {
+  // CHECK-LABEL: test_vclt_u64
+  return vclt_u64(a, b);
+  // CHECK: cmhi {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+}
+
 uint32x2_t test_vclt_f32(float32x2_t v1, float32x2_t v2) {
-  // CHECK: test_vclt_f32
+  // CHECK-LABEL: test_vclt_f32
   return vclt_f32(v1, v2);
   // CHECK: fcmgt {{v[0-9]+}}.2s, v1.2s, v0.2s
 }
 
+uint64x1_t test_vclt_f64(float64x1_t a, float64x1_t b) {
+  // CHECK-LABEL: test_vclt_f64
+  return vclt_f64(a, b);
+  // CHECK: fcmgt {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+}
+
 uint8x8_t test_vclt_u8(uint8x8_t v1, uint8x8_t v2) {
-  // CHECK: test_vclt_u8
+  // CHECK-LABEL: test_vclt_u8
   return vclt_u8(v1, v2);
   // CHECK: cmhi {{v[0-9]+}}.8b, v1.8b, v0.8b
 }
 
 uint16x4_t test_vclt_u16(uint16x4_t v1, uint16x4_t v2) {
-  // CHECK: test_vclt_u16
+  // CHECK-LABEL: test_vclt_u16
   return vclt_u16(v1, v2);
   // CHECK: cmhi {{v[0-9]+}}.4h, v1.4h, v0.4h
 }
 
 uint32x2_t test_vclt_u32(uint32x2_t v1, uint32x2_t v2) {
-  // CHECK: test_vclt_u32
+  // CHECK-LABEL: test_vclt_u32
   return vclt_u32(v1, v2);
   // CHECK: cmhi {{v[0-9]+}}.2s, v1.2s, v0.2s
 }
 
 uint8x16_t test_vcltq_s8(int8x16_t v1, int8x16_t v2) {
-  // CHECK: test_vcltq_s8
+  // CHECK-LABEL: test_vcltq_s8
   return vcltq_s8(v1, v2);
   // CHECK: cmgt {{v[0-9]+}}.16b, v1.16b, v0.16b
 }
 
 uint16x8_t test_vcltq_s16(int16x8_t v1, int16x8_t v2) {
-  // CHECK: test_vcltq_s16
+  // CHECK-LABEL: test_vcltq_s16
   return vcltq_s16(v1, v2);
   // CHECK: cmgt {{v[0-9]+}}.8h, v1.8h, v0.8h
 }
 
 uint32x4_t test_vcltq_s32(int32x4_t v1, int32x4_t v2) {
-  // CHECK: test_vcltq_s32
+  // CHECK-LABEL: test_vcltq_s32
   return vcltq_s32(v1, v2);
   // CHECK: cmgt {{v[0-9]+}}.4s, v1.4s, v0.4s
 }
 
 uint32x4_t test_vcltq_f32(float32x4_t v1, float32x4_t v2) {
-  // CHECK: test_vcltq_f32
+  // CHECK-LABEL: test_vcltq_f32
   return vcltq_f32(v1, v2);
   // CHECK: fcmgt {{v[0-9]+}}.4s, v1.4s, v0.4s
 }
 
 uint8x16_t test_vcltq_u8(uint8x16_t v1, uint8x16_t v2) {
-  // CHECK: test_vcltq_u8
+  // CHECK-LABEL: test_vcltq_u8
   return vcltq_u8(v1, v2);
   // CHECK: cmhi {{v[0-9]+}}.16b, v1.16b, v0.16b
 }
 
 uint16x8_t test_vcltq_u16(uint16x8_t v1, uint16x8_t v2) {
-  // CHECK: test_vcltq_u16
+  // CHECK-LABEL: test_vcltq_u16
   return vcltq_u16(v1, v2);
   // CHECK: cmhi {{v[0-9]+}}.8h, v1.8h, v0.8h
 }
 
 uint32x4_t test_vcltq_u32(uint32x4_t v1, uint32x4_t v2) {
-  // CHECK: test_vcltq_u32
+  // CHECK-LABEL: test_vcltq_u32
   return vcltq_u32(v1, v2);
   // CHECK: cmhi {{v[0-9]+}}.4s, v1.4s, v0.4s
 }
 
 uint64x2_t test_vcltq_s64(int64x2_t v1, int64x2_t v2) {
-  // CHECK: test_vcltq_s64
+  // CHECK-LABEL: test_vcltq_s64
   return vcltq_s64(v1, v2);
   // CHECK: cmgt {{v[0-9]+}}.2d, v1.2d, v0.2d
 }
 
 uint64x2_t test_vcltq_u64(uint64x2_t v1, uint64x2_t v2) {
-  // CHECK: test_vcltq_u64
+  // CHECK-LABEL: test_vcltq_u64
   return vcltq_u64(v1, v2);
   // CHECK: cmhi {{v[0-9]+}}.2d, v1.2d, v0.2d
 }
 
 uint64x2_t test_vcltq_f64(float64x2_t v1, float64x2_t v2) {
-  // CHECK: test_vcltq_f64
+  // CHECK-LABEL: test_vcltq_f64
   return vcltq_f64(v1, v2);
   // CHECK: fcmgt {{v[0-9]+}}.2d, v1.2d, v0.2d
 }
 
 
 int8x8_t test_vhadd_s8(int8x8_t v1, int8x8_t v2) {
-// CHECK: test_vhadd_s8
+// CHECK-LABEL: test_vhadd_s8
   return vhadd_s8(v1, v2);
   // CHECK: shadd {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 int16x4_t test_vhadd_s16(int16x4_t v1, int16x4_t v2) {
-// CHECK: test_vhadd_s16
+// CHECK-LABEL: test_vhadd_s16
   return vhadd_s16(v1, v2);
   // CHECK: shadd {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 int32x2_t test_vhadd_s32(int32x2_t v1, int32x2_t v2) {
-// CHECK: test_vhadd_s32
+// CHECK-LABEL: test_vhadd_s32
   return vhadd_s32(v1, v2);
   // CHECK: shadd {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 uint8x8_t test_vhadd_u8(uint8x8_t v1, uint8x8_t v2) {
-// CHECK: test_vhadd_u8
+// CHECK-LABEL: test_vhadd_u8
   return vhadd_u8(v1, v2);
   // CHECK: uhadd {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint16x4_t test_vhadd_u16(uint16x4_t v1, uint16x4_t v2) {
-// CHECK: test_vhadd_u16
+// CHECK-LABEL: test_vhadd_u16
   return vhadd_u16(v1, v2);
   // CHECK: uhadd {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint32x2_t test_vhadd_u32(uint32x2_t v1, uint32x2_t v2) {
-// CHECK: test_vhadd_u32
+// CHECK-LABEL: test_vhadd_u32
   return vhadd_u32(v1, v2);
   // CHECK: uhadd {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 int8x16_t test_vhaddq_s8(int8x16_t v1, int8x16_t v2) {
-// CHECK: test_vhaddq_s8
+// CHECK-LABEL: test_vhaddq_s8
   return vhaddq_s8(v1, v2);
   // CHECK: shadd {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 int16x8_t test_vhaddq_s16(int16x8_t v1, int16x8_t v2) {
-// CHECK: test_vhaddq_s16
+// CHECK-LABEL: test_vhaddq_s16
   return vhaddq_s16(v1, v2);
   // CHECK: shadd {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int32x4_t test_vhaddq_s32(int32x4_t v1, int32x4_t v2) {
-// CHECK: test_vhaddq_s32
+// CHECK-LABEL: test_vhaddq_s32
   return vhaddq_s32(v1, v2);
   // CHECK: shadd {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint8x16_t test_vhaddq_u8(uint8x16_t v1, uint8x16_t v2) {
-// CHECK: test_vhaddq_u8
+// CHECK-LABEL: test_vhaddq_u8
   return vhaddq_u8(v1, v2);
   // CHECK: uhadd {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint16x8_t test_vhaddq_u16(uint16x8_t v1, uint16x8_t v2) {
-// CHECK: test_vhaddq_u16
+// CHECK-LABEL: test_vhaddq_u16
   return vhaddq_u16(v1, v2);
   // CHECK: uhadd {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint32x4_t test_vhaddq_u32(uint32x4_t v1, uint32x4_t v2) {
-// CHECK: test_vhaddq_u32
+// CHECK-LABEL: test_vhaddq_u32
   return vhaddq_u32(v1, v2);
   // CHECK: uhadd {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 
 int8x8_t test_vhsub_s8(int8x8_t v1, int8x8_t v2) {
-// CHECK: test_vhsub_s8
+// CHECK-LABEL: test_vhsub_s8
   return vhsub_s8(v1, v2);
   // CHECK: shsub {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 int16x4_t test_vhsub_s16(int16x4_t v1, int16x4_t v2) {
-// CHECK: test_vhsub_s16
+// CHECK-LABEL: test_vhsub_s16
   return vhsub_s16(v1, v2);
   // CHECK: shsub {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 int32x2_t test_vhsub_s32(int32x2_t v1, int32x2_t v2) {
-// CHECK: test_vhsub_s32
+// CHECK-LABEL: test_vhsub_s32
   return vhsub_s32(v1, v2);
   // CHECK: shsub {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 uint8x8_t test_vhsub_u8(uint8x8_t v1, uint8x8_t v2) {
-// CHECK: test_vhsub_u8
+// CHECK-LABEL: test_vhsub_u8
   return vhsub_u8(v1, v2);
   // CHECK: uhsub {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint16x4_t test_vhsub_u16(uint16x4_t v1, uint16x4_t v2) {
-// CHECK: test_vhsub_u16
+// CHECK-LABEL: test_vhsub_u16
   return vhsub_u16(v1, v2);
   // CHECK: uhsub {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint32x2_t test_vhsub_u32(uint32x2_t v1, uint32x2_t v2) {
-// CHECK: test_vhsub_u32
+// CHECK-LABEL: test_vhsub_u32
   return vhsub_u32(v1, v2);
   // CHECK: uhsub {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 int8x16_t test_vhsubq_s8(int8x16_t v1, int8x16_t v2) {
-// CHECK: test_vhsubq_s8
+// CHECK-LABEL: test_vhsubq_s8
   return vhsubq_s8(v1, v2);
   // CHECK: shsub {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 int16x8_t test_vhsubq_s16(int16x8_t v1, int16x8_t v2) {
-// CHECK: test_vhsubq_s16
+// CHECK-LABEL: test_vhsubq_s16
   return vhsubq_s16(v1, v2);
   // CHECK: shsub {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int32x4_t test_vhsubq_s32(int32x4_t v1, int32x4_t v2) {
-// CHECK: test_vhsubq_s32
+// CHECK-LABEL: test_vhsubq_s32
   return vhsubq_s32(v1, v2);
   // CHECK: shsub {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint8x16_t test_vhsubq_u8(uint8x16_t v1, uint8x16_t v2) {
-// CHECK: test_vhsubq_u8
+// CHECK-LABEL: test_vhsubq_u8
   return vhsubq_u8(v1, v2);
   // CHECK: uhsub {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint16x8_t test_vhsubq_u16(uint16x8_t v1, uint16x8_t v2) {
-// CHECK: test_vhsubq_u16
+// CHECK-LABEL: test_vhsubq_u16
   return vhsubq_u16(v1, v2);
   // CHECK: uhsub {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint32x4_t test_vhsubq_u32(uint32x4_t v1, uint32x4_t v2) {
-// CHECK: test_vhsubq_u32
+// CHECK-LABEL: test_vhsubq_u32
   return vhsubq_u32(v1, v2);
   // CHECK: uhsub {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 
 int8x8_t test_vrhadd_s8(int8x8_t v1, int8x8_t v2) {
-// CHECK: test_vrhadd_s8
+// CHECK-LABEL: test_vrhadd_s8
   return vrhadd_s8(v1, v2);
 // CHECK: srhadd {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 int16x4_t test_vrhadd_s16(int16x4_t v1, int16x4_t v2) {
-// CHECK: test_vrhadd_s16
+// CHECK-LABEL: test_vrhadd_s16
   return vrhadd_s16(v1, v2);
 // CHECK: srhadd {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 int32x2_t test_vrhadd_s32(int32x2_t v1, int32x2_t v2) {
-// CHECK: test_vrhadd_s32
+// CHECK-LABEL: test_vrhadd_s32
   return vrhadd_s32(v1, v2);
 // CHECK: srhadd {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 uint8x8_t test_vrhadd_u8(uint8x8_t v1, uint8x8_t v2) {
-// CHECK: test_vrhadd_u8
+// CHECK-LABEL: test_vrhadd_u8
   return vrhadd_u8(v1, v2);
 // CHECK: urhadd {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint16x4_t test_vrhadd_u16(uint16x4_t v1, uint16x4_t v2) {
-// CHECK: test_vrhadd_u16
+// CHECK-LABEL: test_vrhadd_u16
   return vrhadd_u16(v1, v2);
 // CHECK: urhadd {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint32x2_t test_vrhadd_u32(uint32x2_t v1, uint32x2_t v2) {
-// CHECK: test_vrhadd_u32
+// CHECK-LABEL: test_vrhadd_u32
   return vrhadd_u32(v1, v2);
 // CHECK: urhadd {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 int8x16_t test_vrhaddq_s8(int8x16_t v1, int8x16_t v2) {
-// CHECK: test_vrhaddq_s8
+// CHECK-LABEL: test_vrhaddq_s8
   return vrhaddq_s8(v1, v2);
 // CHECK: srhadd {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 int16x8_t test_vrhaddq_s16(int16x8_t v1, int16x8_t v2) {
-// CHECK: test_vrhaddq_s16
+// CHECK-LABEL: test_vrhaddq_s16
   return vrhaddq_s16(v1, v2);
 // CHECK: srhadd {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int32x4_t test_vrhaddq_s32(int32x4_t v1, int32x4_t v2) {
-// CHECK: test_vrhaddq_s32
+// CHECK-LABEL: test_vrhaddq_s32
   return vrhaddq_s32(v1, v2);
 // CHECK: srhadd {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint8x16_t test_vrhaddq_u8(uint8x16_t v1, uint8x16_t v2) {
-// CHECK: test_vrhaddq_u8
+// CHECK-LABEL: test_vrhaddq_u8
   return vrhaddq_u8(v1, v2);
 // CHECK: urhadd {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint16x8_t test_vrhaddq_u16(uint16x8_t v1, uint16x8_t v2) {
-// CHECK: test_vrhaddq_u16
+// CHECK-LABEL: test_vrhaddq_u16
   return vrhaddq_u16(v1, v2);
 // CHECK: urhadd {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint32x4_t test_vrhaddq_u32(uint32x4_t v1, uint32x4_t v2) {
-// CHECK: test_vrhaddq_u32
+// CHECK-LABEL: test_vrhaddq_u32
   return vrhaddq_u32(v1, v2);
 // CHECK: urhadd {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 int8x8_t test_vqadd_s8(int8x8_t a, int8x8_t b) {
-// CHECK: test_vqadd_s8
+// CHECK-LABEL: test_vqadd_s8
   return vqadd_s8(a, b);
   // CHECK: sqadd {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 int16x4_t test_vqadd_s16(int16x4_t a, int16x4_t b) {
-// CHECK: test_vqadd_s16
+// CHECK-LABEL: test_vqadd_s16
   return vqadd_s16(a, b);
   // CHECK: sqadd {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 int32x2_t test_vqadd_s32(int32x2_t a, int32x2_t b) {
-// CHECK: test_vqadd_s32
+// CHECK-LABEL: test_vqadd_s32
   return vqadd_s32(a, b);
   // CHECK: sqadd {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 int64x1_t test_vqadd_s64(int64x1_t a, int64x1_t b) {
-// CHECK: test_vqadd_s64
+// CHECK-LABEL: test_vqadd_s64
   return vqadd_s64(a, b);
 // CHECK:  sqadd {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
 }
 
 uint8x8_t test_vqadd_u8(uint8x8_t a, uint8x8_t b) {
-// CHECK: test_vqadd_u8
+// CHECK-LABEL: test_vqadd_u8
   return vqadd_u8(a, b);
   // CHECK: uqadd {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint16x4_t test_vqadd_u16(uint16x4_t a, uint16x4_t b) {
-// CHECK: test_vqadd_u16
+// CHECK-LABEL: test_vqadd_u16
   return vqadd_u16(a, b);
   // CHECK: uqadd {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint32x2_t test_vqadd_u32(uint32x2_t a, uint32x2_t b) {
-// CHECK: test_vqadd_u32
+// CHECK-LABEL: test_vqadd_u32
   return vqadd_u32(a, b);
   // CHECK: uqadd {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
@@ -1888,3764 +2019,3793 @@
 }
 
 int8x16_t test_vqaddq_s8(int8x16_t a, int8x16_t b) {
-// CHECK: test_vqaddq_s8
+// CHECK-LABEL: test_vqaddq_s8
   return vqaddq_s8(a, b);
   // CHECK: sqadd {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 int16x8_t test_vqaddq_s16(int16x8_t a, int16x8_t b) {
-// CHECK: test_vqaddq_s16
+// CHECK-LABEL: test_vqaddq_s16
   return vqaddq_s16(a, b);
   // CHECK: sqadd {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int32x4_t test_vqaddq_s32(int32x4_t a, int32x4_t b) {
-// CHECK: test_vqaddq_s32
+// CHECK-LABEL: test_vqaddq_s32
   return vqaddq_s32(a, b);
   // CHECK: sqadd {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 int64x2_t test_vqaddq_s64(int64x2_t a, int64x2_t b) {
-// CHECK: test_vqaddq_s64
+// CHECK-LABEL: test_vqaddq_s64
   return vqaddq_s64(a, b);
 // CHECK: sqadd {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 uint8x16_t test_vqaddq_u8(uint8x16_t a, uint8x16_t b) {
-// CHECK: test_vqaddq_u8
+// CHECK-LABEL: test_vqaddq_u8
   return vqaddq_u8(a, b);
   // CHECK: uqadd {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint16x8_t test_vqaddq_u16(uint16x8_t a, uint16x8_t b) {
-// CHECK: test_vqaddq_u16
+// CHECK-LABEL: test_vqaddq_u16
   return vqaddq_u16(a, b);
   // CHECK: uqadd {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint32x4_t test_vqaddq_u32(uint32x4_t a, uint32x4_t b) {
-// CHECK: test_vqaddq_u32
+// CHECK-LABEL: test_vqaddq_u32
   return vqaddq_u32(a, b);
   // CHECK: uqadd {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint64x2_t test_vqaddq_u64(uint64x2_t a, uint64x2_t b) {
-// CHECK: test_vqaddq_u64
+// CHECK-LABEL: test_vqaddq_u64
   return vqaddq_u64(a, b);
 // CHECK: uqadd {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 
 int8x8_t test_vqsub_s8(int8x8_t a, int8x8_t b) {
-// CHECK: test_vqsub_s8
+// CHECK-LABEL: test_vqsub_s8
   return vqsub_s8(a, b);
   // CHECK: sqsub {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 int16x4_t test_vqsub_s16(int16x4_t a, int16x4_t b) {
-// CHECK: test_vqsub_s16
+// CHECK-LABEL: test_vqsub_s16
   return vqsub_s16(a, b);
   // CHECK: sqsub {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 int32x2_t test_vqsub_s32(int32x2_t a, int32x2_t b) {
-// CHECK: test_vqsub_s32
+// CHECK-LABEL: test_vqsub_s32
   return vqsub_s32(a, b);
   // CHECK: sqsub {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 int64x1_t test_vqsub_s64(int64x1_t a, int64x1_t b) {
-// CHECK: test_vqsub_s64
+// CHECK-LABEL: test_vqsub_s64
   return vqsub_s64(a, b);
 // CHECK: sqsub {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
 }
 
 uint8x8_t test_vqsub_u8(uint8x8_t a, uint8x8_t b) {
-// CHECK: test_vqsub_u8
+// CHECK-LABEL: test_vqsub_u8
   return vqsub_u8(a, b);
   // CHECK: uqsub {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint16x4_t test_vqsub_u16(uint16x4_t a, uint16x4_t b) {
-// CHECK: test_vqsub_u16
+// CHECK-LABEL: test_vqsub_u16
   return vqsub_u16(a, b);
   // CHECK: uqsub {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint32x2_t test_vqsub_u32(uint32x2_t a, uint32x2_t b) {
-// CHECK: test_vqsub_u32
+// CHECK-LABEL: test_vqsub_u32
   return vqsub_u32(a, b);
   // CHECK: uqsub {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 uint64x1_t test_vqsub_u64(uint64x1_t a, uint64x1_t b) {
-// CHECK: test_vqsub_u64
+// CHECK-LABEL: test_vqsub_u64
   return vqsub_u64(a, b);
 // CHECK:  uqsub {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
 }
 
 int8x16_t test_vqsubq_s8(int8x16_t a, int8x16_t b) {
-// CHECK: test_vqsubq_s8
+// CHECK-LABEL: test_vqsubq_s8
   return vqsubq_s8(a, b);
   // CHECK: sqsub {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 int16x8_t test_vqsubq_s16(int16x8_t a, int16x8_t b) {
-// CHECK: test_vqsubq_s16
+// CHECK-LABEL: test_vqsubq_s16
   return vqsubq_s16(a, b);
   // CHECK: sqsub {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int32x4_t test_vqsubq_s32(int32x4_t a, int32x4_t b) {
-// CHECK: test_vqsubq_s32
+// CHECK-LABEL: test_vqsubq_s32
   return vqsubq_s32(a, b);
   // CHECK: sqsub {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 int64x2_t test_vqsubq_s64(int64x2_t a, int64x2_t b) {
-// CHECK: test_vqsubq_s64
+// CHECK-LABEL: test_vqsubq_s64
   return vqsubq_s64(a, b);
 // CHECK: sqsub {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 uint8x16_t test_vqsubq_u8(uint8x16_t a, uint8x16_t b) {
-// CHECK: test_vqsubq_u8
+// CHECK-LABEL: test_vqsubq_u8
   return vqsubq_u8(a, b);
   // CHECK: uqsub {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint16x8_t test_vqsubq_u16(uint16x8_t a, uint16x8_t b) {
-// CHECK: test_vqsubq_u16
+// CHECK-LABEL: test_vqsubq_u16
   return vqsubq_u16(a, b);
   // CHECK: uqsub {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint32x4_t test_vqsubq_u32(uint32x4_t a, uint32x4_t b) {
-// CHECK: test_vqsubq_u32
+// CHECK-LABEL: test_vqsubq_u32
   return vqsubq_u32(a, b);
   // CHECK: uqsub {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint64x2_t test_vqsubq_u64(uint64x2_t a, uint64x2_t b) {
-// CHECK: test_vqsubq_u64
+// CHECK-LABEL: test_vqsubq_u64
   return vqsubq_u64(a, b);
   // CHECK: uqsub {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 
 int8x8_t test_vshl_s8(int8x8_t a, int8x8_t b) {
-// CHECK: test_vshl_s8
+// CHECK-LABEL: test_vshl_s8
   return vshl_s8(a, b);
 // CHECK: sshl {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 int16x4_t test_vshl_s16(int16x4_t a, int16x4_t b) {
-// CHECK: test_vshl_s16
+// CHECK-LABEL: test_vshl_s16
   return vshl_s16(a, b);
 // CHECK: sshl {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 int32x2_t test_vshl_s32(int32x2_t a, int32x2_t b) {
-// CHECK: test_vshl_s32
+// CHECK-LABEL: test_vshl_s32
   return vshl_s32(a, b);
 // CHECK: sshl {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 int64x1_t test_vshl_s64(int64x1_t a, int64x1_t b) {
-// CHECK: test_vshl_s64
+// CHECK-LABEL: test_vshl_s64
   return vshl_s64(a, b);
 // CHECK: sshl {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
 }
 
 uint8x8_t test_vshl_u8(uint8x8_t a, int8x8_t b) {
-// CHECK: test_vshl_u8
+// CHECK-LABEL: test_vshl_u8
   return vshl_u8(a, b);
 // CHECK: ushl {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint16x4_t test_vshl_u16(uint16x4_t a, int16x4_t b) {
-// CHECK: test_vshl_u16
+// CHECK-LABEL: test_vshl_u16
   return vshl_u16(a, b);
 // CHECK: ushl {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint32x2_t test_vshl_u32(uint32x2_t a, int32x2_t b) {
-// CHECK: test_vshl_u32
+// CHECK-LABEL: test_vshl_u32
   return vshl_u32(a, b);
 // CHECK: ushl {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 uint64x1_t test_vshl_u64(uint64x1_t a, int64x1_t b) {
-// CHECK: test_vshl_u64
+// CHECK-LABEL: test_vshl_u64
   return vshl_u64(a, b);
 // CHECK: ushl {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
 }
 
 int8x16_t test_vshlq_s8(int8x16_t a, int8x16_t b) {
-// CHECK: test_vshlq_s8
+// CHECK-LABEL: test_vshlq_s8
   return vshlq_s8(a, b);
 // CHECK: sshl {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 int16x8_t test_vshlq_s16(int16x8_t a, int16x8_t b) {
-// CHECK: test_vshlq_s16
+// CHECK-LABEL: test_vshlq_s16
   return vshlq_s16(a, b);
 // CHECK: sshl {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int32x4_t test_vshlq_s32(int32x4_t a, int32x4_t b) {
-// CHECK: test_vshlq_s32
+// CHECK-LABEL: test_vshlq_s32
   return vshlq_s32(a, b);
 // CHECK: sshl {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 int64x2_t test_vshlq_s64(int64x2_t a, int64x2_t b) {
-// CHECK: test_vshlq_s64
+// CHECK-LABEL: test_vshlq_s64
   return vshlq_s64(a, b);
 // CHECK: sshl {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 uint8x16_t test_vshlq_u8(uint8x16_t a, int8x16_t b) {
-// CHECK: test_vshlq_u8
+// CHECK-LABEL: test_vshlq_u8
   return vshlq_u8(a, b);
 // CHECK: ushl {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint16x8_t test_vshlq_u16(uint16x8_t a, int16x8_t b) {
-// CHECK: test_vshlq_u16
+// CHECK-LABEL: test_vshlq_u16
   return vshlq_u16(a, b);
 // CHECK: ushl {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint32x4_t test_vshlq_u32(uint32x4_t a, int32x4_t b) {
-// CHECK: test_vshlq_u32
+// CHECK-LABEL: test_vshlq_u32
   return vshlq_u32(a, b);
 // CHECK: ushl {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint64x2_t test_vshlq_u64(uint64x2_t a, int64x2_t b) {
-// CHECK: test_vshlq_u64
+// CHECK-LABEL: test_vshlq_u64
   return vshlq_u64(a, b);
 // CHECK: ushl {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 
 int8x8_t test_vqshl_s8(int8x8_t a, int8x8_t b) {
-// CHECK: test_vqshl_s8
+// CHECK-LABEL: test_vqshl_s8
   return vqshl_s8(a, b);
 // CHECK: sqshl {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 int16x4_t test_vqshl_s16(int16x4_t a, int16x4_t b) {
-// CHECK: test_vqshl_s16
+// CHECK-LABEL: test_vqshl_s16
   return vqshl_s16(a, b);
 // CHECK: sqshl {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 int32x2_t test_vqshl_s32(int32x2_t a, int32x2_t b) {
-// CHECK: test_vqshl_s32
+// CHECK-LABEL: test_vqshl_s32
   return vqshl_s32(a, b);
 // CHECK: sqshl {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 int64x1_t test_vqshl_s64(int64x1_t a, int64x1_t b) {
-// CHECK: test_vqshl_s64
+// CHECK-LABEL: test_vqshl_s64
   return vqshl_s64(a, b);
 // CHECK: sqshl {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
 }
 
 uint8x8_t test_vqshl_u8(uint8x8_t a, int8x8_t b) {
-// CHECK: test_vqshl_u8
+// CHECK-LABEL: test_vqshl_u8
   return vqshl_u8(a, b);
 // CHECK: uqshl {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint16x4_t test_vqshl_u16(uint16x4_t a, int16x4_t b) {
-// CHECK: test_vqshl_u16
+// CHECK-LABEL: test_vqshl_u16
   return vqshl_u16(a, b);
 // CHECK: uqshl {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint32x2_t test_vqshl_u32(uint32x2_t a, int32x2_t b) {
-// CHECK: test_vqshl_u32
+// CHECK-LABEL: test_vqshl_u32
   return vqshl_u32(a, b);
 // CHECK: uqshl {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 uint64x1_t test_vqshl_u64(uint64x1_t a, int64x1_t b) {
-// CHECK: test_vqshl_u64
+// CHECK-LABEL: test_vqshl_u64
   return vqshl_u64(a, b);
 // CHECK: uqshl {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
 }
 
 int8x16_t test_vqshlq_s8(int8x16_t a, int8x16_t b) {
-// CHECK: test_vqshlq_s8
+// CHECK-LABEL: test_vqshlq_s8
   return vqshlq_s8(a, b);
 // CHECK: sqshl {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 int16x8_t test_vqshlq_s16(int16x8_t a, int16x8_t b) {
-// CHECK: test_vqshlq_s16
+// CHECK-LABEL: test_vqshlq_s16
   return vqshlq_s16(a, b);
 // CHECK: sqshl {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int32x4_t test_vqshlq_s32(int32x4_t a, int32x4_t b) {
-// CHECK: test_vqshlq_s32
+// CHECK-LABEL: test_vqshlq_s32
   return vqshlq_s32(a, b);
 // CHECK: sqshl {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 int64x2_t test_vqshlq_s64(int64x2_t a, int64x2_t b) {
-// CHECK: test_vqshlq_s64
+// CHECK-LABEL: test_vqshlq_s64
   return vqshlq_s64(a, b);
 // CHECK: sqshl {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 uint8x16_t test_vqshlq_u8(uint8x16_t a, int8x16_t b) {
-// CHECK: test_vqshlq_u8
+// CHECK-LABEL: test_vqshlq_u8
   return vqshlq_u8(a, b);
 // CHECK: uqshl {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint16x8_t test_vqshlq_u16(uint16x8_t a, int16x8_t b) {
-// CHECK: test_vqshlq_u16
+// CHECK-LABEL: test_vqshlq_u16
   return vqshlq_u16(a, b);
 // CHECK: uqshl {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint32x4_t test_vqshlq_u32(uint32x4_t a, int32x4_t b) {
-// CHECK: test_vqshlq_u32
+// CHECK-LABEL: test_vqshlq_u32
   return vqshlq_u32(a, b);
 // CHECK: uqshl {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint64x2_t test_vqshlq_u64(uint64x2_t a, int64x2_t b) {
-// CHECK: test_vqshlq_u32
+// CHECK-LABEL: test_vqshlq_u64
   return vqshlq_u64(a, b);
 // CHECK: uqshl {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 int8x8_t test_vrshl_s8(int8x8_t a, int8x8_t b) {
-// CHECK: test_vrshl_s8
+// CHECK-LABEL: test_vrshl_s8
   return vrshl_s8(a, b);
 // CHECK: srshl {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 int16x4_t test_vrshl_s16(int16x4_t a, int16x4_t b) {
-// CHECK: test_vrshl_s16
+// CHECK-LABEL: test_vrshl_s16
   return vrshl_s16(a, b);
 // CHECK: srshl {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 int32x2_t test_vrshl_s32(int32x2_t a, int32x2_t b) {
-// CHECK: test_vrshl_s32
+// CHECK-LABEL: test_vrshl_s32
   return vrshl_s32(a, b);
 // CHECK: srshl {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 int64x1_t test_vrshl_s64(int64x1_t a, int64x1_t b) {
-// CHECK: test_vrshl_s64
+// CHECK-LABEL: test_vrshl_s64
   return vrshl_s64(a, b);
 // CHECK: srshl {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
 }
 
 uint8x8_t test_vrshl_u8(uint8x8_t a, int8x8_t b) {
-// CHECK: test_vrshl_u8
+// CHECK-LABEL: test_vrshl_u8
   return vrshl_u8(a, b);
 // CHECK: urshl {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint16x4_t test_vrshl_u16(uint16x4_t a, int16x4_t b) {
-// CHECK: test_vrshl_u16
+// CHECK-LABEL: test_vrshl_u16
   return vrshl_u16(a, b);
 // CHECK: urshl {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint32x2_t test_vrshl_u32(uint32x2_t a, int32x2_t b) {
-// CHECK: test_vrshl_u32
+// CHECK-LABEL: test_vrshl_u32
   return vrshl_u32(a, b);
 // CHECK: urshl {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 uint64x1_t test_vrshl_u64(uint64x1_t a, int64x1_t b) {
-// CHECK: test_vrshl_u64
+// CHECK-LABEL: test_vrshl_u64
   return vrshl_u64(a, b);
 // CHECK: urshl {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
 }
 
 int8x16_t test_vrshlq_s8(int8x16_t a, int8x16_t b) {
-// CHECK: test_vrshlq_s8
+// CHECK-LABEL: test_vrshlq_s8
   return vrshlq_s8(a, b);
 // CHECK: srshl {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 int16x8_t test_vrshlq_s16(int16x8_t a, int16x8_t b) {
-// CHECK: test_vrshlq_s16
+// CHECK-LABEL: test_vrshlq_s16
   return vrshlq_s16(a, b);
 // CHECK: srshl {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int32x4_t test_vrshlq_s32(int32x4_t a, int32x4_t b) {
-// CHECK: test_vrshlq_s32
+// CHECK-LABEL: test_vrshlq_s32
   return vrshlq_s32(a, b);
 // CHECK: srshl {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 int64x2_t test_vrshlq_s64(int64x2_t a, int64x2_t b) {
-// CHECK: test_vrshlq_s64
+// CHECK-LABEL: test_vrshlq_s64
   return vrshlq_s64(a, b);
 // CHECK: srshl {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 uint8x16_t test_vrshlq_u8(uint8x16_t a, int8x16_t b) {
-// CHECK: test_vrshlq_u8
+// CHECK-LABEL: test_vrshlq_u8
   return vrshlq_u8(a, b);
 // CHECK: urshl {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint16x8_t test_vrshlq_u16(uint16x8_t a, int16x8_t b) {
-// CHECK: test_vrshlq_u16
+// CHECK-LABEL: test_vrshlq_u16
   return vrshlq_u16(a, b);
 // CHECK: urshl {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint32x4_t test_vrshlq_u32(uint32x4_t a, int32x4_t b) {
-// CHECK: test_vrshlq_u32
+// CHECK-LABEL: test_vrshlq_u32
   return vrshlq_u32(a, b);
 // CHECK: urshl {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint64x2_t test_vrshlq_u64(uint64x2_t a, int64x2_t b) {
-// CHECK: test_vrshlq_u64
+// CHECK-LABEL: test_vrshlq_u64
   return vrshlq_u64(a, b);
 // CHECK: urshl {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 
 int8x8_t test_vqrshl_s8(int8x8_t a, int8x8_t b) {
-// CHECK: test_vqrshl_s8
+// CHECK-LABEL: test_vqrshl_s8
   return vqrshl_s8(a, b);
 // CHECK: sqrshl {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 int16x4_t test_vqrshl_s16(int16x4_t a, int16x4_t b) {
-// CHECK: test_vqrshl_s16
+// CHECK-LABEL: test_vqrshl_s16
   return vqrshl_s16(a, b);
 // CHECK: sqrshl {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 int32x2_t test_vqrshl_s32(int32x2_t a, int32x2_t b) {
-// CHECK: test_vqrshl_s32
+// CHECK-LABEL: test_vqrshl_s32
   return vqrshl_s32(a, b);
 // CHECK: sqrshl {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 int64x1_t test_vqrshl_s64(int64x1_t a, int64x1_t b) {
-// CHECK: test_vqrshl_s64
+// CHECK-LABEL: test_vqrshl_s64
   return vqrshl_s64(a, b);
 // CHECK: sqrshl {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
 }
 
 uint8x8_t test_vqrshl_u8(uint8x8_t a, int8x8_t b) {
-// CHECK: test_vqrshl_u8
+// CHECK-LABEL: test_vqrshl_u8
   return vqrshl_u8(a, b);
 // CHECK: uqrshl {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint16x4_t test_vqrshl_u16(uint16x4_t a, int16x4_t b) {
-// CHECK: test_vqrshl_u16
+// CHECK-LABEL: test_vqrshl_u16
   return vqrshl_u16(a, b);
 // CHECK: uqrshl {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint32x2_t test_vqrshl_u32(uint32x2_t a, int32x2_t b) {
-// CHECK: test_vqrshl_u32
+// CHECK-LABEL: test_vqrshl_u32
   return vqrshl_u32(a, b);
 // CHECK: uqrshl {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 uint64x1_t test_vqrshl_u64(uint64x1_t a, int64x1_t b) {
-// CHECK: test_vqrshl_u64
+// CHECK-LABEL: test_vqrshl_u64
   return vqrshl_u64(a, b);
 // CHECK: uqrshl {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
 }
 
 int8x16_t test_vqrshlq_s8(int8x16_t a, int8x16_t b) {
-// CHECK: test_vqrshlq_s8
+// CHECK-LABEL: test_vqrshlq_s8
   return vqrshlq_s8(a, b);
 // CHECK: sqrshl {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 int16x8_t test_vqrshlq_s16(int16x8_t a, int16x8_t b) {
-// CHECK: test_vqrshlq_s16
+// CHECK-LABEL: test_vqrshlq_s16
   return vqrshlq_s16(a, b);
 // CHECK: sqrshl {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int32x4_t test_vqrshlq_s32(int32x4_t a, int32x4_t b) {
-// CHECK: test_vqrshlq_s32
+// CHECK-LABEL: test_vqrshlq_s32
   return vqrshlq_s32(a, b);
 // CHECK: sqrshl {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 int64x2_t test_vqrshlq_s64(int64x2_t a, int64x2_t b) {
-// CHECK: test_vqrshlq_s64
+// CHECK-LABEL: test_vqrshlq_s64
   return vqrshlq_s64(a, b);
 // CHECK: sqrshl {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
-// CHECK: test_vqrshlq_u8
+// CHECK-LABEL: test_vqrshlq_u8
 uint8x16_t test_vqrshlq_u8(uint8x16_t a, int8x16_t b) {
   return vqrshlq_u8(a, b);
 // CHECK: uqrshl {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint16x8_t test_vqrshlq_u16(uint16x8_t a, int16x8_t b) {
-// CHECK: test_vqrshlq_u16
+// CHECK-LABEL: test_vqrshlq_u16
   return vqrshlq_u16(a, b);
 // CHECK: uqrshl {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint32x4_t test_vqrshlq_u32(uint32x4_t a, int32x4_t b) {
-// CHECK: test_vqrshlq_u32
+// CHECK-LABEL: test_vqrshlq_u32
   return vqrshlq_u32(a, b);
 // CHECK: uqrshl {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint64x2_t test_vqrshlq_u64(uint64x2_t a, int64x2_t b) {
-// CHECK: test_vqrshlq_u64
+// CHECK-LABEL: test_vqrshlq_u64
   return vqrshlq_u64(a, b);
 // CHECK: uqrshl {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
+poly64x1_t test_vsli_n_p64(poly64x1_t a, poly64x1_t b) {
+// CHECK-LABEL: test_vsli_n_p64
+  return vsli_n_p64(a, b, 0); 
+// CHECK: sli {{d[0-9]+}}, {{d[0-9]+}}, #0
+}
+
+poly64x2_t test_vsliq_n_p64(poly64x2_t a, poly64x2_t b) {
+// CHECK-LABEL: test_vsliq_n_p64
+  return vsliq_n_p64(a, b, 0); 
+// CHECK: sli {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #0
+}
+
 int8x8_t test_vmax_s8(int8x8_t a, int8x8_t b) {
-// CHECK: test_vmax_s8
+// CHECK-LABEL: test_vmax_s8
   return vmax_s8(a, b);
 // CHECK: smax {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 int16x4_t test_vmax_s16(int16x4_t a, int16x4_t b) {
-// CHECK: test_vmax_s16
+// CHECK-LABEL: test_vmax_s16
   return vmax_s16(a, b);
 // CHECK: smax {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 int32x2_t test_vmax_s32(int32x2_t a, int32x2_t b) {
-// CHECK: test_vmax_s32
+// CHECK-LABEL: test_vmax_s32
   return vmax_s32(a, b);
 // CHECK: smax {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 uint8x8_t test_vmax_u8(uint8x8_t a, uint8x8_t b) {
-// CHECK: test_vmax_u8
+// CHECK-LABEL: test_vmax_u8
   return vmax_u8(a, b);
 // CHECK: umax {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint16x4_t test_vmax_u16(uint16x4_t a, uint16x4_t b) {
-// CHECK: test_vmax_u16
+// CHECK-LABEL: test_vmax_u16
   return vmax_u16(a, b);
 // CHECK: umax {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint32x2_t test_vmax_u32(uint32x2_t a, uint32x2_t b) {
-// CHECK: test_vmax_u32
+// CHECK-LABEL: test_vmax_u32
   return vmax_u32(a, b);
 // CHECK: umax {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 float32x2_t test_vmax_f32(float32x2_t a, float32x2_t b) {
-// CHECK: test_vmax_f32
+// CHECK-LABEL: test_vmax_f32
   return vmax_f32(a, b);
 // CHECK: fmax {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 int8x16_t test_vmaxq_s8(int8x16_t a, int8x16_t b) {
-// CHECK: test_vmaxq_s8
+// CHECK-LABEL: test_vmaxq_s8
   return vmaxq_s8(a, b);
 // CHECK: smax {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 int16x8_t test_vmaxq_s16(int16x8_t a, int16x8_t b) {
-// CHECK: test_vmaxq_s16
+// CHECK-LABEL: test_vmaxq_s16
   return vmaxq_s16(a, b);
 // CHECK: smax {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int32x4_t test_vmaxq_s32(int32x4_t a, int32x4_t b) {
-// CHECK: test_vmaxq_s32
+// CHECK-LABEL: test_vmaxq_s32
   return vmaxq_s32(a, b);
 // CHECK: smax {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint8x16_t test_vmaxq_u8(uint8x16_t a, uint8x16_t b) {
-// CHECK: test_vmaxq_u8
+// CHECK-LABEL: test_vmaxq_u8
   return vmaxq_u8(a, b);
 // CHECK: umax {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint16x8_t test_vmaxq_u16(uint16x8_t a, uint16x8_t b) {
-// CHECK: test_vmaxq_u16
+// CHECK-LABEL: test_vmaxq_u16
   return vmaxq_u16(a, b);
 // CHECK: umax {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint32x4_t test_vmaxq_u32(uint32x4_t a, uint32x4_t b) {
-// CHECK: test_vmaxq_u32
+// CHECK-LABEL: test_vmaxq_u32
   return vmaxq_u32(a, b);
 // CHECK: umax {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 float32x4_t test_vmaxq_f32(float32x4_t a, float32x4_t b) {
-// CHECK: test_vmaxq_f32
+// CHECK-LABEL: test_vmaxq_f32
   return vmaxq_f32(a, b);
 // CHECK: fmax {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 float64x2_t test_vmaxq_f64(float64x2_t a, float64x2_t b) {
-// CHECK: test_vmaxq_f64
+// CHECK-LABEL: test_vmaxq_f64
   return vmaxq_f64(a, b);
 // CHECK: fmax {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 
 int8x8_t test_vmin_s8(int8x8_t a, int8x8_t b) {
-// CHECK: test_vmin_s8
+// CHECK-LABEL: test_vmin_s8
   return vmin_s8(a, b);
 // CHECK: smin {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 int16x4_t test_vmin_s16(int16x4_t a, int16x4_t b) {
-// CHECK: test_vmin_s16
+// CHECK-LABEL: test_vmin_s16
   return vmin_s16(a, b);
 // CHECK: smin {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 int32x2_t test_vmin_s32(int32x2_t a, int32x2_t b) {
-// CHECK: test_vmin_s32
+// CHECK-LABEL: test_vmin_s32
   return vmin_s32(a, b);
 // CHECK: smin {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 uint8x8_t test_vmin_u8(uint8x8_t a, uint8x8_t b) {
-// CHECK: test_vmin_u8
+// CHECK-LABEL: test_vmin_u8
   return vmin_u8(a, b);
 // CHECK: umin {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint16x4_t test_vmin_u16(uint16x4_t a, uint16x4_t b) {
-// CHECK: test_vmin_u16
+// CHECK-LABEL: test_vmin_u16
   return vmin_u16(a, b);
 // CHECK: umin {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint32x2_t test_vmin_u32(uint32x2_t a, uint32x2_t b) {
-// CHECK: test_vmin_u32
+// CHECK-LABEL: test_vmin_u32
   return vmin_u32(a, b);
 // CHECK: umin {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 float32x2_t test_vmin_f32(float32x2_t a, float32x2_t b) {
-// CHECK: test_vmin_f32
+// CHECK-LABEL: test_vmin_f32
   return vmin_f32(a, b);
 // CHECK: fmin {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 int8x16_t test_vminq_s8(int8x16_t a, int8x16_t b) {
-// CHECK: test_vminq_s8
+// CHECK-LABEL: test_vminq_s8
   return vminq_s8(a, b);
 // CHECK: smin {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 int16x8_t test_vminq_s16(int16x8_t a, int16x8_t b) {
-// CHECK: test_vminq_s16
+// CHECK-LABEL: test_vminq_s16
   return vminq_s16(a, b);
 // CHECK: smin {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int32x4_t test_vminq_s32(int32x4_t a, int32x4_t b) {
-// CHECK: test_vminq_s32
+// CHECK-LABEL: test_vminq_s32
   return vminq_s32(a, b);
 // CHECK: smin {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint8x16_t test_vminq_u8(uint8x16_t a, uint8x16_t b) {
-// CHECK: test_vminq_u8
+// CHECK-LABEL: test_vminq_u8
   return vminq_u8(a, b);
 // CHECK: umin {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint16x8_t test_vminq_u16(uint16x8_t a, uint16x8_t b) {
-// CHECK: test_vminq_u16
+// CHECK-LABEL: test_vminq_u16
   return vminq_u16(a, b);
 // CHECK: umin {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint32x4_t test_vminq_u32(uint32x4_t a, uint32x4_t b) {
-// CHECK: test_vminq_u32
+// CHECK-LABEL: test_vminq_u32
   return vminq_u32(a, b);
 // CHECK: umin {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 float32x4_t test_vminq_f32(float32x4_t a, float32x4_t b) {
-// CHECK: test_vminq_f32
+// CHECK-LABEL: test_vminq_f32
   return vminq_f32(a, b);
 // CHECK: fmin {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 float64x2_t test_vminq_f64(float64x2_t a, float64x2_t b) {
-// CHECK: test_vminq_f64
+// CHECK-LABEL: test_vminq_f64
   return vminq_f64(a, b);
 // CHECK: fmin {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 float32x2_t test_vmaxnm_f32(float32x2_t a, float32x2_t b) {
-// CHECK: test_vmaxnm_f32
+// CHECK-LABEL: test_vmaxnm_f32
   return vmaxnm_f32(a, b);
 // CHECK: fmaxnm {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 float32x4_t test_vmaxnmq_f32(float32x4_t a, float32x4_t b) {
-// CHECK: test_vmaxnmq_f32
+// CHECK-LABEL: test_vmaxnmq_f32
   return vmaxnmq_f32(a, b);
 // CHECK: fmaxnm {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 float64x2_t test_vmaxnmq_f64(float64x2_t a, float64x2_t b) {
-// CHECK: test_vmaxnmq_f64
+// CHECK-LABEL: test_vmaxnmq_f64
   return vmaxnmq_f64(a, b);
 // CHECK: fmaxnm {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 float32x2_t test_vminnm_f32(float32x2_t a, float32x2_t b) {
-// CHECK: test_vminnm_f32
+// CHECK-LABEL: test_vminnm_f32
   return vminnm_f32(a, b);
 // CHECK: fminnm {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 float32x4_t test_vminnmq_f32(float32x4_t a, float32x4_t b) {
-// CHECK: test_vminnmq_f32
+// CHECK-LABEL: test_vminnmq_f32
   return vminnmq_f32(a, b);
 // CHECK: fminnm {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 float64x2_t test_vminnmq_f64(float64x2_t a, float64x2_t b) {
-// CHECK: test_vminnmq_f64
+// CHECK-LABEL: test_vminnmq_f64
   return vminnmq_f64(a, b);
 // CHECK: fminnm {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 int8x8_t test_vpmax_s8(int8x8_t a, int8x8_t b) {
-// CHECK: test_vpmax_s8
+// CHECK-LABEL: test_vpmax_s8
   return vpmax_s8(a, b);
 // CHECK: smaxp {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 int16x4_t test_vpmax_s16(int16x4_t a, int16x4_t b) {
-// CHECK: test_vpmax_s16
+// CHECK-LABEL: test_vpmax_s16
   return vpmax_s16(a, b);
 // CHECK: smaxp {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 int32x2_t test_vpmax_s32(int32x2_t a, int32x2_t b) {
-// CHECK: test_vpmax_s32
+// CHECK-LABEL: test_vpmax_s32
   return vpmax_s32(a, b);
 // CHECK: smaxp {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 uint8x8_t test_vpmax_u8(uint8x8_t a, uint8x8_t b) {
-// CHECK: test_vpmax_u8
+// CHECK-LABEL: test_vpmax_u8
   return vpmax_u8(a, b);
 // CHECK: umaxp {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint16x4_t test_vpmax_u16(uint16x4_t a, uint16x4_t b) {
-// CHECK: test_vpmax_u16
+// CHECK-LABEL: test_vpmax_u16
   return vpmax_u16(a, b);
 // CHECK: umaxp {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint32x2_t test_vpmax_u32(uint32x2_t a, uint32x2_t b) {
-// CHECK: test_vpmax_u32
+// CHECK-LABEL: test_vpmax_u32
   return vpmax_u32(a, b);
 // CHECK: umaxp {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 float32x2_t test_vpmax_f32(float32x2_t a, float32x2_t b) {
-// CHECK: test_vpmax_f32
+// CHECK-LABEL: test_vpmax_f32
   return vpmax_f32(a, b);
 // CHECK: fmaxp {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 int8x16_t test_vpmaxq_s8(int8x16_t a, int8x16_t b) {
-// CHECK: test_vpmaxq_s8
+// CHECK-LABEL: test_vpmaxq_s8
   return vpmaxq_s8(a, b);
 // CHECK: smaxp {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 int16x8_t test_vpmaxq_s16(int16x8_t a, int16x8_t b) {
-// CHECK: test_vpmaxq_s16
+// CHECK-LABEL: test_vpmaxq_s16
   return vpmaxq_s16(a, b);
 // CHECK: smaxp {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int32x4_t test_vpmaxq_s32(int32x4_t a, int32x4_t b) {
-// CHECK: test_vpmaxq_s32
+// CHECK-LABEL: test_vpmaxq_s32
   return vpmaxq_s32(a, b);
 // CHECK: smaxp {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint8x16_t test_vpmaxq_u8(uint8x16_t a, uint8x16_t b) {
-// CHECK: test_vpmaxq_u8
+// CHECK-LABEL: test_vpmaxq_u8
   return vpmaxq_u8(a, b);
 // CHECK: umaxp {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint16x8_t test_vpmaxq_u16(uint16x8_t a, uint16x8_t b) {
-// CHECK: test_vpmaxq_u16
+// CHECK-LABEL: test_vpmaxq_u16
   return vpmaxq_u16(a, b);
 // CHECK: umaxp {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint32x4_t test_vpmaxq_u32(uint32x4_t a, uint32x4_t b) {
-// CHECK: test_vpmaxq_u32
+// CHECK-LABEL: test_vpmaxq_u32
   return vpmaxq_u32(a, b);
 // CHECK: umaxp {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 float32x4_t test_vpmaxq_f32(float32x4_t a, float32x4_t b) {
-// CHECK: test_vpmaxq_f32
+// CHECK-LABEL: test_vpmaxq_f32
   return vpmaxq_f32(a, b);
 // CHECK: fmaxp {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 float64x2_t test_vpmaxq_f64(float64x2_t a, float64x2_t b) {
-// CHECK: test_vpmaxq_f64
+// CHECK-LABEL: test_vpmaxq_f64
   return vpmaxq_f64(a, b);
 // CHECK: fmaxp {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 int8x8_t test_vpmin_s8(int8x8_t a, int8x8_t b) {
-// CHECK: test_vpmin_s8
+// CHECK-LABEL: test_vpmin_s8
   return vpmin_s8(a, b);
 // CHECK: sminp {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 int16x4_t test_vpmin_s16(int16x4_t a, int16x4_t b) {
-// CHECK: test_vpmin_s16
+// CHECK-LABEL: test_vpmin_s16
   return vpmin_s16(a, b);
 // CHECK: sminp {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 int32x2_t test_vpmin_s32(int32x2_t a, int32x2_t b) {
-// CHECK: test_vpmin_s32
+// CHECK-LABEL: test_vpmin_s32
   return vpmin_s32(a, b);
 // CHECK: sminp {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 uint8x8_t test_vpmin_u8(uint8x8_t a, uint8x8_t b) {
-// CHECK: test_vpmin_u8
+// CHECK-LABEL: test_vpmin_u8
   return vpmin_u8(a, b);
 // CHECK: uminp {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint16x4_t test_vpmin_u16(uint16x4_t a, uint16x4_t b) {
-// CHECK: test_vpmin_u16
+// CHECK-LABEL: test_vpmin_u16
   return vpmin_u16(a, b);
 // CHECK: uminp {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint32x2_t test_vpmin_u32(uint32x2_t a, uint32x2_t b) {
-// CHECK: test_vpmin_u32
+// CHECK-LABEL: test_vpmin_u32
   return vpmin_u32(a, b);
 // CHECK: uminp {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 float32x2_t test_vpmin_f32(float32x2_t a, float32x2_t b) {
-// CHECK: test_vpmin_f32
+// CHECK-LABEL: test_vpmin_f32
   return vpmin_f32(a, b);
 // CHECK: fminp {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 int8x16_t test_vpminq_s8(int8x16_t a, int8x16_t b) {
-// CHECK: test_vpminq_s8
+// CHECK-LABEL: test_vpminq_s8
   return vpminq_s8(a, b);
 // CHECK: sminp {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 int16x8_t test_vpminq_s16(int16x8_t a, int16x8_t b) {
-// CHECK: test_vpminq_s16
+// CHECK-LABEL: test_vpminq_s16
   return vpminq_s16(a, b);
 // CHECK: sminp {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int32x4_t test_vpminq_s32(int32x4_t a, int32x4_t b) {
-// CHECK: test_vpminq_s32
+// CHECK-LABEL: test_vpminq_s32
   return vpminq_s32(a, b);
 // CHECK: sminp {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint8x16_t test_vpminq_u8(uint8x16_t a, uint8x16_t b) {
-// CHECK: test_vpminq_u8
+// CHECK-LABEL: test_vpminq_u8
   return vpminq_u8(a, b);
 // CHECK: uminp {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint16x8_t test_vpminq_u16(uint16x8_t a, uint16x8_t b) {
-// CHECK: test_vpminq_u16
+// CHECK-LABEL: test_vpminq_u16
   return vpminq_u16(a, b);
 // CHECK: uminp {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint32x4_t test_vpminq_u32(uint32x4_t a, uint32x4_t b) {
-// CHECK: test_vpminq_u32
+// CHECK-LABEL: test_vpminq_u32
   return vpminq_u32(a, b);
 // CHECK: uminp {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 float32x4_t test_vpminq_f32(float32x4_t a, float32x4_t b) {
-// CHECK: test_vpminq_f32
+// CHECK-LABEL: test_vpminq_f32
   return vpminq_f32(a, b);
 // CHECK: fminp {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 float64x2_t test_vpminq_f64(float64x2_t a, float64x2_t b) {
-// CHECK: test_vpminq_f64
+// CHECK-LABEL: test_vpminq_f64
   return vpminq_f64(a, b);
 // CHECK: fminp {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 float32x2_t test_vpmaxnm_f32(float32x2_t a, float32x2_t b) {
-// CHECK: test_vpmaxnm_f32
+// CHECK-LABEL: test_vpmaxnm_f32
   return vpmaxnm_f32(a, b);
 // CHECK: fmaxnmp {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 float32x4_t test_vpmaxnmq_f32(float32x4_t a, float32x4_t b) {
-// CHECK: test_vpmaxnmq_f32
+// CHECK-LABEL: test_vpmaxnmq_f32
   return vpmaxnmq_f32(a, b);
 // CHECK: fmaxnmp {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 float64x2_t test_vpmaxnmq_f64(float64x2_t a, float64x2_t b) {
-// CHECK: test_vpmaxnmq_f64
+// CHECK-LABEL: test_vpmaxnmq_f64
   return vpmaxnmq_f64(a, b);
 // CHECK: fmaxnmp {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 float32x2_t test_vpminnm_f32(float32x2_t a, float32x2_t b) {
-// CHECK: test_vpminnm_f32
+// CHECK-LABEL: test_vpminnm_f32
   return vpminnm_f32(a, b);
 // CHECK: fminnmp {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 float32x4_t test_vpminnmq_f32(float32x4_t a, float32x4_t b) {
-// CHECK: test_vpminnmq_f32
+// CHECK-LABEL: test_vpminnmq_f32
   return vpminnmq_f32(a, b);
 // CHECK: fminnmp {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 float64x2_t test_vpminnmq_f64(float64x2_t a, float64x2_t b) {
-// CHECK: test_vpminnmq_f64
+// CHECK-LABEL: test_vpminnmq_f64
   return vpminnmq_f64(a, b);
 // CHECK: fminnmp {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 int8x8_t test_vpadd_s8(int8x8_t a, int8x8_t b) {
-// CHECK: test_vpadd_s8
+// CHECK-LABEL: test_vpadd_s8
   return vpadd_s8(a, b);
 // CHECK: addp {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 int16x4_t test_vpadd_s16(int16x4_t a, int16x4_t b) {
-// CHECK: test_vpadd_s16
+// CHECK-LABEL: test_vpadd_s16
   return vpadd_s16(a, b);
 // CHECK: addp {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 int32x2_t test_vpadd_s32(int32x2_t a, int32x2_t b) {
-// CHECK: test_vpadd_s32
+// CHECK-LABEL: test_vpadd_s32
   return vpadd_s32(a, b);
 // CHECK: addp {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 uint8x8_t test_vpadd_u8(uint8x8_t a, uint8x8_t b) {
-// CHECK: test_vpadd_u8
+// CHECK-LABEL: test_vpadd_u8
   return vpadd_u8(a, b);
 // CHECK: addp {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint16x4_t test_vpadd_u16(uint16x4_t a, uint16x4_t b) {
-// CHECK: test_vpadd_u16
+// CHECK-LABEL: test_vpadd_u16
   return vpadd_u16(a, b);
 // CHECK: addp {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint32x2_t test_vpadd_u32(uint32x2_t a, uint32x2_t b) {
-// CHECK: test_vpadd_u32
+// CHECK-LABEL: test_vpadd_u32
   return vpadd_u32(a, b);
 // CHECK: addp {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 float32x2_t test_vpadd_f32(float32x2_t a, float32x2_t b) {
-// CHECK: test_vpadd_f32
+// CHECK-LABEL: test_vpadd_f32
   return vpadd_f32(a, b);
 // CHECK: faddp {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 int8x16_t test_vpaddq_s8(int8x16_t a, int8x16_t b) {
-// CHECK: test_vpaddq_s8
+// CHECK-LABEL: test_vpaddq_s8
   return vpaddq_s8(a, b);
 // CHECK: addp {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 int16x8_t test_vpaddq_s16(int16x8_t a, int16x8_t b) {
-// CHECK: test_vpaddq_s16
+// CHECK-LABEL: test_vpaddq_s16
   return vpaddq_s16(a, b);
 // CHECK: addp {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int32x4_t test_vpaddq_s32(int32x4_t a, int32x4_t b) {
-// CHECK: test_vpaddq_s32
+// CHECK-LABEL: test_vpaddq_s32
   return vpaddq_s32(a, b);
 // CHECK: addp {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint8x16_t test_vpaddq_u8(uint8x16_t a, uint8x16_t b) {
-// CHECK: test_vpaddq_u8
+// CHECK-LABEL: test_vpaddq_u8
   return vpaddq_u8(a, b);
 // CHECK: addp {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint16x8_t test_vpaddq_u16(uint16x8_t a, uint16x8_t b) {
-// CHECK: test_vpaddq_u16
+// CHECK-LABEL: test_vpaddq_u16
   return vpaddq_u16(a, b);
 // CHECK: addp {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint32x4_t test_vpaddq_u32(uint32x4_t a, uint32x4_t b) {
-// CHECK: test_vpaddq_u32
+// CHECK-LABEL: test_vpaddq_u32
   return vpaddq_u32(a, b);
 // CHECK: addp {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 float32x4_t test_vpaddq_f32(float32x4_t a, float32x4_t b) {
-// CHECK: test_vpaddq_f32
+// CHECK-LABEL: test_vpaddq_f32
   return vpaddq_f32(a, b);
 // CHECK: faddp {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 float64x2_t test_vpaddq_f64(float64x2_t a, float64x2_t b) {
-// CHECK: test_vpaddq_f64
+// CHECK-LABEL: test_vpaddq_f64
   return vpaddq_f64(a, b);
 // CHECK: faddp {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 int16x4_t test_vqdmulh_s16(int16x4_t a, int16x4_t b) {
-// CHECK: test_vqdmulh_s16
+// CHECK-LABEL: test_vqdmulh_s16
   return vqdmulh_s16(a, b);
 // CHECK: sqdmulh {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 int32x2_t test_vqdmulh_s32(int32x2_t a, int32x2_t b) {
-// CHECK: test_vqdmulh_s32
+// CHECK-LABEL: test_vqdmulh_s32
   return vqdmulh_s32(a, b);
 // CHECK: sqdmulh {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 int16x8_t test_vqdmulhq_s16(int16x8_t a, int16x8_t b) {
-// CHECK: test_vqdmulhq_s16
+// CHECK-LABEL: test_vqdmulhq_s16
   return vqdmulhq_s16(a, b);
 // CHECK: sqdmulh {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int32x4_t test_vqdmulhq_s32(int32x4_t a, int32x4_t b) {
-// CHECK: test_vqdmulhq_s32
+// CHECK-LABEL: test_vqdmulhq_s32
   return vqdmulhq_s32(a, b);
 // CHECK: sqdmulh {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 int16x4_t test_vqrdmulh_s16(int16x4_t a, int16x4_t b) {
-// CHECK: test_vqrdmulh_s16
+// CHECK-LABEL: test_vqrdmulh_s16
   return vqrdmulh_s16(a, b);
 // CHECK: sqrdmulh {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 int32x2_t test_vqrdmulh_s32(int32x2_t a, int32x2_t b) {
-// CHECK: test_vqrdmulh_s32
+// CHECK-LABEL: test_vqrdmulh_s32
   return vqrdmulh_s32(a, b);
 // CHECK: sqrdmulh {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 int16x8_t test_vqrdmulhq_s16(int16x8_t a, int16x8_t b) {
-// CHECK: test_vqrdmulhq_s16
+// CHECK-LABEL: test_vqrdmulhq_s16
   return vqrdmulhq_s16(a, b);
 // CHECK: sqrdmulh {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int32x4_t test_vqrdmulhq_s32(int32x4_t a, int32x4_t b) {
-// CHECK: test_vqrdmulhq_s32
+// CHECK-LABEL: test_vqrdmulhq_s32
   return vqrdmulhq_s32(a, b);
 // CHECK: sqrdmulh {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
-
 float32x2_t test_vmulx_f32(float32x2_t a, float32x2_t b) {
-// CHECK: test_vmulx_f32
+// CHECK-LABEL: test_vmulx_f32
   return vmulx_f32(a, b);
 // CHECK: fmulx {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 float32x4_t test_vmulxq_f32(float32x4_t a, float32x4_t b) {
-// CHECK: test_vmulxq_f32
+// CHECK-LABEL: test_vmulxq_f32
   return vmulxq_f32(a, b);
 // CHECK: fmulx {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 float64x2_t test_vmulxq_f64(float64x2_t a, float64x2_t b) {
-// CHECK: test_vmulxq_f64
+// CHECK-LABEL: test_vmulxq_f64
   return vmulxq_f64(a, b);
 // CHECK: fmulx {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 int8x8_t test_vshl_n_s8(int8x8_t a) {
-// CHECK: test_vshl_n_s8
+// CHECK-LABEL: test_vshl_n_s8
   return vshl_n_s8(a, 3);
 // CHECK: shl {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #3
 }
 
 int16x4_t test_vshl_n_s16(int16x4_t a) {
-// CHECK: test_vshl_n_s16
+// CHECK-LABEL: test_vshl_n_s16
   return vshl_n_s16(a, 3);
 // CHECK: shl {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, #3
 }
 
 int32x2_t test_vshl_n_s32(int32x2_t a) {
-// CHECK: test_vshl_n_s32
+// CHECK-LABEL: test_vshl_n_s32
   return vshl_n_s32(a, 3);
 // CHECK: shl {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #3
 }
 
 int8x16_t test_vshlq_n_s8(int8x16_t a) {
-// CHECK: test_vshlq_n_s8
+// CHECK-LABEL: test_vshlq_n_s8
   return vshlq_n_s8(a, 3);
 // CHECK: shl {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #3
 }
 
 int16x8_t test_vshlq_n_s16(int16x8_t a) {
-// CHECK: test_vshlq_n_s16
+// CHECK-LABEL: test_vshlq_n_s16
   return vshlq_n_s16(a, 3);
 // CHECK: shl {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, #3
 }
 
 int32x4_t test_vshlq_n_s32(int32x4_t a) {
-// CHECK: test_vshlq_n_s32
+// CHECK-LABEL: test_vshlq_n_s32
   return vshlq_n_s32(a, 3);
 // CHECK: shl {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #3
 }
 
 int64x2_t test_vshlq_n_s64(int64x2_t a) {
-// CHECK: test_vshlq_n_s64
+// CHECK-LABEL: test_vshlq_n_s64
   return vshlq_n_s64(a, 3);
 // CHECK: shl {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #3
 }
 
 int8x8_t test_vshl_n_u8(int8x8_t a) {
-// CHECK: test_vshl_n_u8
+// CHECK-LABEL: test_vshl_n_u8
   return vshl_n_u8(a, 3);
 // CHECK: shl {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #3
 }
 
 int16x4_t test_vshl_n_u16(int16x4_t a) {
-// CHECK: test_vshl_n_u16
+// CHECK-LABEL: test_vshl_n_u16
   return vshl_n_u16(a, 3);
 // CHECK: shl {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, #3
 }
 
 int32x2_t test_vshl_n_u32(int32x2_t a) {
-// CHECK: test_vshl_n_u32
+// CHECK-LABEL: test_vshl_n_u32
   return vshl_n_u32(a, 3);
 // CHECK: shl {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #3
 }
 
 int8x16_t test_vshlq_n_u8(int8x16_t a) {
-// CHECK: test_vshlq_n_u8
+// CHECK-LABEL: test_vshlq_n_u8
   return vshlq_n_u8(a, 3);
 // CHECK: shl {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #3
 }
 
 int16x8_t test_vshlq_n_u16(int16x8_t a) {
-// CHECK: test_vshlq_n_u16
+// CHECK-LABEL: test_vshlq_n_u16
   return vshlq_n_u16(a, 3);
 // CHECK: shl {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, #3
 }
 
 int32x4_t test_vshlq_n_u32(int32x4_t a) {
-// CHECK: test_vshlq_n_u32
+// CHECK-LABEL: test_vshlq_n_u32
   return vshlq_n_u32(a, 3);
 // CHECK: shl {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #3
 }
 
 int64x2_t test_vshlq_n_u64(int64x2_t a) {
-// CHECK: test_vshlq_n_u64
+// CHECK-LABEL: test_vshlq_n_u64
   return vshlq_n_u64(a, 3);
 // CHECK: shl {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #3
 }
 
 int8x8_t test_vshr_n_s8(int8x8_t a) {
-  // CHECK: test_vshr_n_s8
+  // CHECK-LABEL: test_vshr_n_s8
   return vshr_n_s8(a, 3);
   // CHECK: sshr {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #3
 }
 
 int16x4_t test_vshr_n_s16(int16x4_t a) {
-  // CHECK: test_vshr_n_s16
+  // CHECK-LABEL: test_vshr_n_s16
   return vshr_n_s16(a, 3);
   // CHECK: sshr {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, #3
 }
 
 int32x2_t test_vshr_n_s32(int32x2_t a) {
-  // CHECK: test_vshr_n_s32
+  // CHECK-LABEL: test_vshr_n_s32
   return vshr_n_s32(a, 3);
   // CHECK: sshr {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #3
 }
 
 int8x16_t test_vshrq_n_s8(int8x16_t a) {
-  // CHECK: test_vshrq_n_s8
+  // CHECK-LABEL: test_vshrq_n_s8
   return vshrq_n_s8(a, 3);
   // CHECK: sshr {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #3
 }
 
 int16x8_t test_vshrq_n_s16(int16x8_t a) {
-  // CHECK: test_vshrq_n_s16
+  // CHECK-LABEL: test_vshrq_n_s16
   return vshrq_n_s16(a, 3);
   // CHECK: sshr {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, #3
 }
 
 int32x4_t test_vshrq_n_s32(int32x4_t a) {
-  // CHECK: test_vshrq_n_s32
+  // CHECK-LABEL: test_vshrq_n_s32
   return vshrq_n_s32(a, 3);
   // CHECK: sshr {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #3
 }
 
 int64x2_t test_vshrq_n_s64(int64x2_t a) {
-  // CHECK: test_vshrq_n_s64
+  // CHECK-LABEL: test_vshrq_n_s64
   return vshrq_n_s64(a, 3);
   // CHECK: sshr {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #3
 }
 
 int8x8_t test_vshr_n_u8(int8x8_t a) {
-  // CHECK: test_vshr_n_u8
+  // CHECK-LABEL: test_vshr_n_u8
   return vshr_n_u8(a, 3);
   // CHECK: ushr {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #3
 }
 
 int16x4_t test_vshr_n_u16(int16x4_t a) {
-  // CHECK: test_vshr_n_u16
+  // CHECK-LABEL: test_vshr_n_u16
   return vshr_n_u16(a, 3);
   // CHECK: ushr {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, #3
 }
 
 int32x2_t test_vshr_n_u32(int32x2_t a) {
-  // CHECK: test_vshr_n_u32
+  // CHECK-LABEL: test_vshr_n_u32
   return vshr_n_u32(a, 3);
   // CHECK: ushr {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #3
 }
 
 int8x16_t test_vshrq_n_u8(int8x16_t a) {
-  // CHECK: test_vshrq_n_u8
+  // CHECK-LABEL: test_vshrq_n_u8
   return vshrq_n_u8(a, 3);
   // CHECK: ushr {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #3
 }
 
 int16x8_t test_vshrq_n_u16(int16x8_t a) {
-  // CHECK: test_vshrq_n_u16
+  // CHECK-LABEL: test_vshrq_n_u16
   return vshrq_n_u16(a, 3);
   // CHECK: ushr {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, #3
 }
 
 int32x4_t test_vshrq_n_u32(int32x4_t a) {
-  // CHECK: test_vshrq_n_u32
+  // CHECK-LABEL: test_vshrq_n_u32
   return vshrq_n_u32(a, 3);
   // CHECK: ushr {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #3
 }
 
 int64x2_t test_vshrq_n_u64(int64x2_t a) {
-  // CHECK: test_vshrq_n_u64
+  // CHECK-LABEL: test_vshrq_n_u64
   return vshrq_n_u64(a, 3);
   // CHECK: ushr {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #3
 }
 
 int8x8_t test_vsra_n_s8(int8x8_t a, int8x8_t b) {
-  // CHECK: test_vsra_n_s8
+  // CHECK-LABEL: test_vsra_n_s8
   return vsra_n_s8(a, b, 3);
   // CHECK: ssra {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #3
 }
 
 int16x4_t test_vsra_n_s16(int16x4_t a, int16x4_t b) {
-  // CHECK: test_vsra_n_s16
+  // CHECK-LABEL: test_vsra_n_s16
   return vsra_n_s16(a, b, 3);
   // CHECK: ssra {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, #3
 }
 
 int32x2_t test_vsra_n_s32(int32x2_t a, int32x2_t b) {
-  // CHECK: test_vsra_n_s32
+  // CHECK-LABEL: test_vsra_n_s32
   return vsra_n_s32(a, b, 3);
   // CHECK: ssra {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #3
 }
 
 int8x16_t test_vsraq_n_s8(int8x16_t a, int8x16_t b) {
-  // CHECK: test_vsraq_n_s8
+  // CHECK-LABEL: test_vsraq_n_s8
   return vsraq_n_s8(a, b, 3);
   // CHECK: ssra {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #3
 }
 
 int16x8_t test_vsraq_n_s16(int16x8_t a, int16x8_t b) {
-  // CHECK: test_vsraq_n_s16
+  // CHECK-LABEL: test_vsraq_n_s16
   return vsraq_n_s16(a, b, 3);
   // CHECK: ssra {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, #3
 }
 
 int32x4_t test_vsraq_n_s32(int32x4_t a, int32x4_t b) {
-  // CHECK: test_vsraq_n_s32
+  // CHECK-LABEL: test_vsraq_n_s32
   return vsraq_n_s32(a, b, 3);
   // CHECK: ssra {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #3
 }
 
 int64x2_t test_vsraq_n_s64(int64x2_t a, int64x2_t b) {
-  // CHECK: test_vsraq_n_s64
+  // CHECK-LABEL: test_vsraq_n_s64
   return vsraq_n_s64(a, b, 3);
   // CHECK: ssra {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #3
 }
 
 int8x8_t test_vsra_n_u8(int8x8_t a, int8x8_t b) {
-  // CHECK: test_vsra_n_u8
+  // CHECK-LABEL: test_vsra_n_u8
   return vsra_n_u8(a, b, 3);
   // CHECK: usra {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #3
 }
 
 int16x4_t test_vsra_n_u16(int16x4_t a, int16x4_t b) {
-  // CHECK: test_vsra_n_u16
+  // CHECK-LABEL: test_vsra_n_u16
   return vsra_n_u16(a, b, 3);
   // CHECK: usra {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, #3
 }
 
 int32x2_t test_vsra_n_u32(int32x2_t a, int32x2_t b) {
-  // CHECK: test_vsra_n_u32
+  // CHECK-LABEL: test_vsra_n_u32
   return vsra_n_u32(a, b, 3);
   // CHECK: usra {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #3
 }
 
 int8x16_t test_vsraq_n_u8(int8x16_t a, int8x16_t b) {
-  // CHECK: test_vsraq_n_u8
+  // CHECK-LABEL: test_vsraq_n_u8
   return vsraq_n_u8(a, b, 3);
   // CHECK: usra {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #3
 }
 
 int16x8_t test_vsraq_n_u16(int16x8_t a, int16x8_t b) {
-  // CHECK: test_vsraq_n_u16
+  // CHECK-LABEL: test_vsraq_n_u16
   return vsraq_n_u16(a, b, 3);
   // CHECK: usra {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, #3
 }
 
 int32x4_t test_vsraq_n_u32(int32x4_t a, int32x4_t b) {
-  // CHECK: test_vsraq_n_u32
+  // CHECK-LABEL: test_vsraq_n_u32
   return vsraq_n_u32(a, b, 3);
   // CHECK: usra {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #3
 }
 
 int64x2_t test_vsraq_n_u64(int64x2_t a, int64x2_t b) {
-  // CHECK: test_vsraq_n_u64
+  // CHECK-LABEL: test_vsraq_n_u64
   return vsraq_n_u64(a, b, 3);
   // CHECK: usra {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #3
 }
 
 int8x8_t test_vrshr_n_s8(int8x8_t a) {
-  // CHECK: test_vrshr_n_s8
+  // CHECK-LABEL: test_vrshr_n_s8
   return vrshr_n_s8(a, 3);
   // CHECK: srshr {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #3
 }
 
 int16x4_t test_vrshr_n_s16(int16x4_t a) {
-  // CHECK: test_vrshr_n_s16
+  // CHECK-LABEL: test_vrshr_n_s16
   return vrshr_n_s16(a, 3);
   // CHECK: srshr {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, #3
 }
 
 int32x2_t test_vrshr_n_s32(int32x2_t a) {
-  // CHECK: test_vrshr_n_s32
+  // CHECK-LABEL: test_vrshr_n_s32
   return vrshr_n_s32(a, 3);
   // CHECK: srshr {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #3
 }
 
 int8x16_t test_vrshrq_n_s8(int8x16_t a) {
-  // CHECK: test_vrshrq_n_s8
+  // CHECK-LABEL: test_vrshrq_n_s8
   return vrshrq_n_s8(a, 3);
   // CHECK: srshr {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #3
 }
 
 int16x8_t test_vrshrq_n_s16(int16x8_t a) {
-  // CHECK: test_vrshrq_n_s16
+  // CHECK-LABEL: test_vrshrq_n_s16
   return vrshrq_n_s16(a, 3);
   // CHECK: srshr {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, #3
 }
 
 int32x4_t test_vrshrq_n_s32(int32x4_t a) {
-  // CHECK: test_vrshrq_n_s32
+  // CHECK-LABEL: test_vrshrq_n_s32
   return vrshrq_n_s32(a, 3);
   // CHECK: srshr {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #3
 }
 
 int64x2_t test_vrshrq_n_s64(int64x2_t a) {
-  // CHECK: test_vrshrq_n_s64
+  // CHECK-LABEL: test_vrshrq_n_s64
   return vrshrq_n_s64(a, 3);
   // CHECK: srshr {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #3
 }
 
 int8x8_t test_vrshr_n_u8(int8x8_t a) {
-  // CHECK: test_vrshr_n_u8
+  // CHECK-LABEL: test_vrshr_n_u8
   return vrshr_n_u8(a, 3);
   // CHECK: urshr {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #3
 }
 
 int16x4_t test_vrshr_n_u16(int16x4_t a) {
-  // CHECK: test_vrshr_n_u16
+  // CHECK-LABEL: test_vrshr_n_u16
   return vrshr_n_u16(a, 3);
   // CHECK: urshr {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, #3
 }
 
 int32x2_t test_vrshr_n_u32(int32x2_t a) {
-  // CHECK: test_vrshr_n_u32
+  // CHECK-LABEL: test_vrshr_n_u32
   return vrshr_n_u32(a, 3);
   // CHECK: urshr {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #3
 }
 
 int8x16_t test_vrshrq_n_u8(int8x16_t a) {
-  // CHECK: test_vrshrq_n_u8
+  // CHECK-LABEL: test_vrshrq_n_u8
   return vrshrq_n_u8(a, 3);
   // CHECK: urshr {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #3
 }
 
 int16x8_t test_vrshrq_n_u16(int16x8_t a) {
-  // CHECK: test_vrshrq_n_u16
+  // CHECK-LABEL: test_vrshrq_n_u16
   return vrshrq_n_u16(a, 3);
   // CHECK: urshr {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, #3
 }
 
 int32x4_t test_vrshrq_n_u32(int32x4_t a) {
-  // CHECK: test_vrshrq_n_u32
+  // CHECK-LABEL: test_vrshrq_n_u32
   return vrshrq_n_u32(a, 3);
   // CHECK: urshr {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #3
 }
 
 int64x2_t test_vrshrq_n_u64(int64x2_t a) {
-  // CHECK: test_vrshrq_n_u64
+  // CHECK-LABEL: test_vrshrq_n_u64
   return vrshrq_n_u64(a, 3);
   // CHECK: urshr {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #3
 }
 
 int8x8_t test_vrsra_n_s8(int8x8_t a, int8x8_t b) {
-  // CHECK: test_vrsra_n_s8
+  // CHECK-LABEL: test_vrsra_n_s8
   return vrsra_n_s8(a, b, 3);
   // CHECK: srsra {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #3
 }
 
 int16x4_t test_vrsra_n_s16(int16x4_t a, int16x4_t b) {
-  // CHECK: test_vrsra_n_s16
+  // CHECK-LABEL: test_vrsra_n_s16
   return vrsra_n_s16(a, b, 3);
   // CHECK: srsra {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, #3
 }
 
 int32x2_t test_vrsra_n_s32(int32x2_t a, int32x2_t b) {
-  // CHECK: test_vrsra_n_s32
+  // CHECK-LABEL: test_vrsra_n_s32
   return vrsra_n_s32(a, b, 3);
   // CHECK: srsra {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #3
 }
 
 int8x16_t test_vrsraq_n_s8(int8x16_t a, int8x16_t b) {
-  // CHECK: test_vrsraq_n_s8
+  // CHECK-LABEL: test_vrsraq_n_s8
   return vrsraq_n_s8(a, b, 3);
   // CHECK: srsra {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #3
 }
 
 int16x8_t test_vrsraq_n_s16(int16x8_t a, int16x8_t b) {
-  // CHECK: test_vrsraq_n_s16
+  // CHECK-LABEL: test_vrsraq_n_s16
   return vrsraq_n_s16(a, b, 3);
   // CHECK: srsra {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, #3
 }
 
 int32x4_t test_vrsraq_n_s32(int32x4_t a, int32x4_t b) {
-  // CHECK: test_vrsraq_n_s32
+  // CHECK-LABEL: test_vrsraq_n_s32
   return vrsraq_n_s32(a, b, 3);
   // CHECK: srsra {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #3
 }
 
 int64x2_t test_vrsraq_n_s64(int64x2_t a, int64x2_t b) {
-  // CHECK: test_vrsraq_n_s64
+  // CHECK-LABEL: test_vrsraq_n_s64
   return vrsraq_n_s64(a, b, 3);
   // CHECK: srsra {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #3
 }
 
 int8x8_t test_vrsra_n_u8(int8x8_t a, int8x8_t b) {
-  // CHECK: test_vrsra_n_u8
+  // CHECK-LABEL: test_vrsra_n_u8
   return vrsra_n_u8(a, b, 3);
   // CHECK: ursra {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #3
 }
 
 int16x4_t test_vrsra_n_u16(int16x4_t a, int16x4_t b) {
-  // CHECK: test_vrsra_n_u16
+  // CHECK-LABEL: test_vrsra_n_u16
   return vrsra_n_u16(a, b, 3);
   // CHECK: ursra {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, #3
 }
 
 int32x2_t test_vrsra_n_u32(int32x2_t a, int32x2_t b) {
-  // CHECK: test_vrsra_n_u32
+  // CHECK-LABEL: test_vrsra_n_u32
   return vrsra_n_u32(a, b, 3);
   // CHECK: ursra {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #3
 }
 
 int8x16_t test_vrsraq_n_u8(int8x16_t a, int8x16_t b) {
-  // CHECK: test_vrsraq_n_u8
+  // CHECK-LABEL: test_vrsraq_n_u8
   return vrsraq_n_u8(a, b, 3);
   // CHECK: ursra {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #3
 }
 
 int16x8_t test_vrsraq_n_u16(int16x8_t a, int16x8_t b) {
-  // CHECK: test_vrsraq_n_u16
+  // CHECK-LABEL: test_vrsraq_n_u16
   return vrsraq_n_u16(a, b, 3);
   // CHECK: ursra {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, #3
 }
 
 int32x4_t test_vrsraq_n_u32(int32x4_t a, int32x4_t b) {
-  // CHECK: test_vrsraq_n_u32
+  // CHECK-LABEL: test_vrsraq_n_u32
   return vrsraq_n_u32(a, b, 3);
   // CHECK: ursra {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #3
 }
 
 int64x2_t test_vrsraq_n_u64(int64x2_t a, int64x2_t b) {
-  // CHECK: test_vrsraq_n_u64
+  // CHECK-LABEL: test_vrsraq_n_u64
   return vrsraq_n_u64(a, b, 3);
   // CHECK: ursra {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #3
 }
 
 int8x8_t test_vsri_n_s8(int8x8_t a, int8x8_t b) {
-  // CHECK: test_vsri_n_s8
+  // CHECK-LABEL: test_vsri_n_s8
   return vsri_n_s8(a, b, 3);
   // CHECK: sri {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #3
 }
 
 int16x4_t test_vsri_n_s16(int16x4_t a, int16x4_t b) {
-  // CHECK: test_vsri_n_s16
+  // CHECK-LABEL: test_vsri_n_s16
   return vsri_n_s16(a, b, 3);
   // CHECK: sri {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, #3
 }
 
 int32x2_t test_vsri_n_s32(int32x2_t a, int32x2_t b) {
-  // CHECK: test_vsri_n_s32
+  // CHECK-LABEL: test_vsri_n_s32
   return vsri_n_s32(a, b, 3);
   // CHECK: sri {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #3
 }
 
 int8x16_t test_vsriq_n_s8(int8x16_t a, int8x16_t b) {
-  // CHECK: test_vsriq_n_s8
+  // CHECK-LABEL: test_vsriq_n_s8
   return vsriq_n_s8(a, b, 3);
   // CHECK: sri {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #3
 }
 
 int16x8_t test_vsriq_n_s16(int16x8_t a, int16x8_t b) {
-  // CHECK: test_vsriq_n_s16
+  // CHECK-LABEL: test_vsriq_n_s16
   return vsriq_n_s16(a, b, 3);
   // CHECK: sri {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, #3
 }
 
 int32x4_t test_vsriq_n_s32(int32x4_t a, int32x4_t b) {
-  // CHECK: test_vsriq_n_s32
+  // CHECK-LABEL: test_vsriq_n_s32
   return vsriq_n_s32(a, b, 3);
   // CHECK: sri {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #3
 }
 
 int64x2_t test_vsriq_n_s64(int64x2_t a, int64x2_t b) {
-  // CHECK: test_vsriq_n_s64
+  // CHECK-LABEL: test_vsriq_n_s64
   return vsriq_n_s64(a, b, 3);
   // CHECK: sri {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #3
 }
 
 int8x8_t test_vsri_n_u8(int8x8_t a, int8x8_t b) {
-  // CHECK: test_vsri_n_u8
+  // CHECK-LABEL: test_vsri_n_u8
   return vsri_n_u8(a, b, 3);
   // CHECK: sri {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #3
 }
 
 int16x4_t test_vsri_n_u16(int16x4_t a, int16x4_t b) {
-  // CHECK: test_vsri_n_u16
+  // CHECK-LABEL: test_vsri_n_u16
   return vsri_n_u16(a, b, 3);
   // CHECK: sri {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, #3
 }
 
 int32x2_t test_vsri_n_u32(int32x2_t a, int32x2_t b) {
-  // CHECK: test_vsri_n_u32
+  // CHECK-LABEL: test_vsri_n_u32
   return vsri_n_u32(a, b, 3);
   // CHECK: sri {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #3
 }
 
 int8x16_t test_vsriq_n_u8(int8x16_t a, int8x16_t b) {
-  // CHECK: test_vsriq_n_u8
+  // CHECK-LABEL: test_vsriq_n_u8
   return vsriq_n_u8(a, b, 3);
   // CHECK: sri {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #3
 }
 
 int16x8_t test_vsriq_n_u16(int16x8_t a, int16x8_t b) {
-  // CHECK: test_vsriq_n_u16
+  // CHECK-LABEL: test_vsriq_n_u16
   return vsriq_n_u16(a, b, 3);
   // CHECK: sri {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, #3
 }
 
 int32x4_t test_vsriq_n_u32(int32x4_t a, int32x4_t b) {
-  // CHECK: test_vsriq_n_u32
+  // CHECK-LABEL: test_vsriq_n_u32
   return vsriq_n_u32(a, b, 3);
   // CHECK: sri {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #3
 }
 
 int64x2_t test_vsriq_n_u64(int64x2_t a, int64x2_t b) {
-  // CHECK: test_vsriq_n_u64
+  // CHECK-LABEL: test_vsriq_n_u64
   return vsriq_n_u64(a, b, 3);
   // CHECK: sri {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #3
 }
 
 poly8x8_t test_vsri_n_p8(poly8x8_t a, poly8x8_t b) {
-  // CHECK: test_vsri_n_p8
+  // CHECK-LABEL: test_vsri_n_p8
   return vsri_n_p8(a, b, 3);
   // CHECK: sri {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #3
 }
 
 poly16x4_t test_vsri_n_p16(poly16x4_t a, poly16x4_t b) {
-  // CHECK: test_vsri_n_p16
+  // CHECK-LABEL: test_vsri_n_p16
   return vsri_n_p16(a, b, 15);
   // CHECK: sri {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, #15
 }
 
 poly8x16_t test_vsriq_n_p8(poly8x16_t a, poly8x16_t b) {
-  // CHECK: test_vsriq_n_p8
+  // CHECK-LABEL: test_vsriq_n_p8
   return vsriq_n_p8(a, b, 3);
   // CHECK: sri {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #3
 }
 
 poly16x8_t test_vsriq_n_p16(poly16x8_t a, poly16x8_t b) {
-  // CHECK: test_vsriq_n_p16
+  // CHECK-LABEL: test_vsriq_n_p16
   return vsriq_n_p16(a, b, 15);
   // CHECK: sri {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, #15
 }
 
 int8x8_t test_vsli_n_s8(int8x8_t a, int8x8_t b) {
-  // CHECK: test_vsli_n_s8
+  // CHECK-LABEL: test_vsli_n_s8
   return vsli_n_s8(a, b, 3);
   // CHECK: sli {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #3
 }
 
 int16x4_t test_vsli_n_s16(int16x4_t a, int16x4_t b) {
-  // CHECK: test_vsli_n_s16
+  // CHECK-LABEL: test_vsli_n_s16
   return vsli_n_s16(a, b, 3);
   // CHECK: sli {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, #3
 }
 
 int32x2_t test_vsli_n_s32(int32x2_t a, int32x2_t b) {
-  // CHECK: test_vsli_n_s32
+  // CHECK-LABEL: test_vsli_n_s32
   return vsli_n_s32(a, b, 3);
   // CHECK: sli {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #3
 }
 
 int8x16_t test_vsliq_n_s8(int8x16_t a, int8x16_t b) {
-  // CHECK: test_vsliq_n_s8
+  // CHECK-LABEL: test_vsliq_n_s8
   return vsliq_n_s8(a, b, 3);
   // CHECK: sli {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #3
 }
 
 int16x8_t test_vsliq_n_s16(int16x8_t a, int16x8_t b) {
-  // CHECK: test_vsliq_n_s16
+  // CHECK-LABEL: test_vsliq_n_s16
   return vsliq_n_s16(a, b, 3);
   // CHECK: sli {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, #3
 }
 
 int32x4_t test_vsliq_n_s32(int32x4_t a, int32x4_t b) {
-  // CHECK: test_vsliq_n_s32
+  // CHECK-LABEL: test_vsliq_n_s32
   return vsliq_n_s32(a, b, 3);
   // CHECK: sli {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #3
 }
 
 int64x2_t test_vsliq_n_s64(int64x2_t a, int64x2_t b) {
-  // CHECK: test_vsliq_n_s64
+  // CHECK-LABEL: test_vsliq_n_s64
   return vsliq_n_s64(a, b, 3);
   // CHECK: sli {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #3
 }
 
 uint8x8_t test_vsli_n_u8(uint8x8_t a, uint8x8_t b) {
-  // CHECK: test_vsli_n_u8
+  // CHECK-LABEL: test_vsli_n_u8
   return vsli_n_u8(a, b, 3);
   // CHECK: sli {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #3
 }
 
 uint16x4_t test_vsli_n_u16(uint16x4_t a, uint16x4_t b) {
-  // CHECK: test_vsli_n_u16
+  // CHECK-LABEL: test_vsli_n_u16
   return vsli_n_u16(a, b, 3);
   // CHECK: sli {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, #3
 }
 
 uint32x2_t test_vsli_n_u32(uint32x2_t a, uint32x2_t b) {
-  // CHECK: test_vsli_n_u32
+  // CHECK-LABEL: test_vsli_n_u32
   return vsli_n_u32(a, b, 3);
   // CHECK: sli {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #3
 }
 
 uint8x16_t test_vsliq_n_u8(uint8x16_t a, uint8x16_t b) {
-  // CHECK: test_vsliq_n_u8
+  // CHECK-LABEL: test_vsliq_n_u8
   return vsliq_n_u8(a, b, 3);
   // CHECK: sli {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #3
 }
 
 uint16x8_t test_vsliq_n_u16(uint16x8_t a, uint16x8_t b) {
-  // CHECK: test_vsliq_n_u16
+  // CHECK-LABEL: test_vsliq_n_u16
   return vsliq_n_u16(a, b, 3);
   // CHECK: sli {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, #3
 }
 
 uint32x4_t test_vsliq_n_u32(uint32x4_t a, uint32x4_t b) {
-  // CHECK: test_vsliq_n_u32
+  // CHECK-LABEL: test_vsliq_n_u32
   return vsliq_n_u32(a, b, 3);
   // CHECK: sli {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #3
 }
 
 uint64x2_t test_vsliq_n_u64(uint64x2_t a, uint64x2_t b) {
-  // CHECK: test_vsliq_n_u64
+  // CHECK-LABEL: test_vsliq_n_u64
   return vsliq_n_u64(a, b, 3);
   // CHECK: sli {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #3
 }
 
 poly8x8_t test_vsli_n_p8(poly8x8_t a, poly8x8_t b) {
-  // CHECK: test_vsli_n_p8
+  // CHECK-LABEL: test_vsli_n_p8
   return vsli_n_p8(a, b, 3);
   // CHECK: sli {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #3
 }
 
 poly16x4_t test_vsli_n_p16(poly16x4_t a, poly16x4_t b) {
-  // CHECK: test_vsli_n_p16
+  // CHECK-LABEL: test_vsli_n_p16
   return vsli_n_p16(a, b, 15);
   // CHECK: sli {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, #15
 }
 
 poly8x16_t test_vsliq_n_p8(poly8x16_t a, poly8x16_t b) {
-  // CHECK: test_vsliq_n_p8
+  // CHECK-LABEL: test_vsliq_n_p8
   return vsliq_n_p8(a, b, 3);
   // CHECK: sli {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #3
 }
 
 poly16x8_t test_vsliq_n_p16(poly16x8_t a, poly16x8_t b) {
-  // CHECK: test_vsliq_n_p16
+  // CHECK-LABEL: test_vsliq_n_p16
   return vsliq_n_p16(a, b, 15);
   // CHECK: sli {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, #15
 }
 
 int8x8_t test_vqshlu_n_s8(int8x8_t a) {
-  // CHECK: test_vqshlu_n_s8
+  // CHECK-LABEL: test_vqshlu_n_s8
   return vqshlu_n_s8(a, 3);
   // CHECK: sqshlu {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #3
 }
 
 int16x4_t test_vqshlu_n_s16(int16x4_t a) {
-  // CHECK: test_vqshlu_n_s16
+  // CHECK-LABEL: test_vqshlu_n_s16
   return vqshlu_n_s16(a, 3);
   // CHECK: sqshlu {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, #3
 }
 
 int32x2_t test_vqshlu_n_s32(int32x2_t a) {
-  // CHECK: test_vqshlu_n_s32
+  // CHECK-LABEL: test_vqshlu_n_s32
   return vqshlu_n_s32(a, 3);
   // CHECK: sqshlu {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #3
 }
 
 int8x16_t test_vqshluq_n_s8(int8x16_t a) {
-  // CHECK: test_vqshluq_n_s8
+  // CHECK-LABEL: test_vqshluq_n_s8
   return vqshluq_n_s8(a, 3);
   // CHECK: sqshlu {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #3
 }
 
 int16x8_t test_vqshluq_n_s16(int16x8_t a) {
-  // CHECK: test_vqshluq_n_s16
+  // CHECK-LABEL: test_vqshluq_n_s16
   return vqshluq_n_s16(a, 3);
   // CHECK: sqshlu {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, #3
 }
 
 int32x4_t test_vqshluq_n_s32(int32x4_t a) {
-  // CHECK: test_vqshluq_n_s32
+  // CHECK-LABEL: test_vqshluq_n_s32
   return vqshluq_n_s32(a, 3);
   // CHECK: sqshlu {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #3
 }
 
 int64x2_t test_vqshluq_n_s64(int64x2_t a) {
-  // CHECK: test_vqshluq_n_s64
+  // CHECK-LABEL: test_vqshluq_n_s64
   return vqshluq_n_s64(a, 3);
   // CHECK: sqshlu {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #3
 }
 
 int8x8_t test_vshrn_n_s16(int16x8_t a) {
-  // CHECK: test_vshrn_n_s16
+  // CHECK-LABEL: test_vshrn_n_s16
   return vshrn_n_s16(a, 3);
   // CHECK: shrn {{v[0-9]+}}.8b, {{v[0-9]+}}.8h, #3
 }
 
 int16x4_t test_vshrn_n_s32(int32x4_t a) {
-  // CHECK: test_vshrn_n_s32
+  // CHECK-LABEL: test_vshrn_n_s32
   return vshrn_n_s32(a, 9);
   // CHECK: shrn {{v[0-9]+}}.4h, {{v[0-9]+}}.4s, #9
 }
 
 int32x2_t test_vshrn_n_s64(int64x2_t a) {
-  // CHECK: test_vshrn_n_s64
+  // CHECK-LABEL: test_vshrn_n_s64
   return vshrn_n_s64(a, 19);
   // CHECK: shrn {{v[0-9]+}}.2s, {{v[0-9]+}}.2d, #19
 }
 
 uint8x8_t test_vshrn_n_u16(uint16x8_t a) {
-  // CHECK: test_vshrn_n_u16
+  // CHECK-LABEL: test_vshrn_n_u16
   return vshrn_n_u16(a, 3);
   // CHECK: shrn {{v[0-9]+}}.8b, {{v[0-9]+}}.8h, #3
 }
 
 uint16x4_t test_vshrn_n_u32(uint32x4_t a) {
-  // CHECK: test_vshrn_n_u32
+  // CHECK-LABEL: test_vshrn_n_u32
   return vshrn_n_u32(a, 9);
   // CHECK: shrn {{v[0-9]+}}.4h, {{v[0-9]+}}.4s, #9
 }
 
 uint32x2_t test_vshrn_n_u64(uint64x2_t a) {
-  // CHECK: test_vshrn_n_u64
+  // CHECK-LABEL: test_vshrn_n_u64
   return vshrn_n_u64(a, 19);
   // CHECK: shrn {{v[0-9]+}}.2s, {{v[0-9]+}}.2d, #19
 }
 
 int8x16_t test_vshrn_high_n_s16(int8x8_t a, int16x8_t b) {
-  // CHECK: test_vshrn_high_n_s16
+  // CHECK-LABEL: test_vshrn_high_n_s16
   return vshrn_high_n_s16(a, b, 3);
   // CHECK: shrn2 {{v[0-9]+}}.16b, {{v[0-9]+}}.8h, #3
 }
 
 int16x8_t test_vshrn_high_n_s32(int16x4_t a, int32x4_t b) {
-  // CHECK: test_vshrn_high_n_s32
+  // CHECK-LABEL: test_vshrn_high_n_s32
   return vshrn_high_n_s32(a, b, 9);
   // CHECK: shrn2 {{v[0-9]+}}.8h, {{v[0-9]+}}.4s, #9
 }
 
 int32x4_t test_vshrn_high_n_s64(int32x2_t a, int64x2_t b) {
-  // CHECK: test_vshrn_high_n_s64
+  // CHECK-LABEL: test_vshrn_high_n_s64
   return vshrn_high_n_s64(a, b, 19);
   // CHECK: shrn2 {{v[0-9]+}}.4s, {{v[0-9]+}}.2d, #19
 }
 
 uint8x16_t test_vshrn_high_n_u16(uint8x8_t a, uint16x8_t b) {
-  // CHECK: test_vshrn_high_n_u16
+  // CHECK-LABEL: test_vshrn_high_n_u16
   return vshrn_high_n_u16(a, b, 3);
   // CHECK: shrn2 {{v[0-9]+}}.16b, {{v[0-9]+}}.8h, #3
 }
 
 uint16x8_t test_vshrn_high_n_u32(uint16x4_t a, uint32x4_t b) {
-  // CHECK: test_vshrn_high_n_u32
+  // CHECK-LABEL: test_vshrn_high_n_u32
   return vshrn_high_n_u32(a, b, 9);
   // CHECK: shrn2 {{v[0-9]+}}.8h, {{v[0-9]+}}.4s, #9
 }
 
 uint32x4_t test_vshrn_high_n_u64(uint32x2_t a, uint64x2_t b) {
-  // CHECK: test_vshrn_high_n_u64
+  // CHECK-LABEL: test_vshrn_high_n_u64
   return vshrn_high_n_u64(a, b, 19);
   // CHECK: shrn2 {{v[0-9]+}}.4s, {{v[0-9]+}}.2d, #19
 }
 
 int8x8_t test_vqshrun_n_s16(int16x8_t a) {
-  // CHECK: test_vqshrun_n_s16
+  // CHECK-LABEL: test_vqshrun_n_s16
   return vqshrun_n_s16(a, 3);
   // CHECK: sqshrun {{v[0-9]+}}.8b, {{v[0-9]+}}.8h, #3
 }
 
 int16x4_t test_vqshrun_n_s32(int32x4_t a) {
-  // CHECK: test_vqshrun_n_s32
+  // CHECK-LABEL: test_vqshrun_n_s32
   return vqshrun_n_s32(a, 9);
   // CHECK: sqshrun {{v[0-9]+}}.4h, {{v[0-9]+}}.4s, #9
 }
 
 int32x2_t test_vqshrun_n_s64(int64x2_t a) {
-  // CHECK: test_vqshrun_n_s64
+  // CHECK-LABEL: test_vqshrun_n_s64
   return vqshrun_n_s64(a, 19);
   // CHECK: sqshrun {{v[0-9]+}}.2s, {{v[0-9]+}}.2d, #19
 }
 
 int8x16_t test_vqshrun_high_n_s16(int8x8_t a, int16x8_t b) {
-  // CHECK: test_vqshrun_high_n_s16
+  // CHECK-LABEL: test_vqshrun_high_n_s16
   return vqshrun_high_n_s16(a, b, 3);
   // CHECK: sqshrun2 {{v[0-9]+}}.16b, {{v[0-9]+}}.8h, #3
 }
 
 int16x8_t test_vqshrun_high_n_s32(int16x4_t a, int32x4_t b) {
-  // CHECK: test_vqshrun_high_n_s32
+  // CHECK-LABEL: test_vqshrun_high_n_s32
   return vqshrun_high_n_s32(a, b, 9);
   // CHECK: sqshrun2 {{v[0-9]+}}.8h, {{v[0-9]+}}.4s, #9
 }
 
 int32x4_t test_vqshrun_high_n_s64(int32x2_t a, int64x2_t b) {
-  // CHECK: test_vqshrun_high_n_s64
+  // CHECK-LABEL: test_vqshrun_high_n_s64
   return vqshrun_high_n_s64(a, b, 19);
   // CHECK: sqshrun2 {{v[0-9]+}}.4s, {{v[0-9]+}}.2d, #19
 }
 
 int8x8_t test_vrshrn_n_s16(int16x8_t a) {
-  // CHECK: test_vrshrn_n_s16
+  // CHECK-LABEL: test_vrshrn_n_s16
   return vrshrn_n_s16(a, 3);
   // CHECK: rshrn {{v[0-9]+}}.8b, {{v[0-9]+}}.8h, #3
 }
 
 int16x4_t test_vrshrn_n_s32(int32x4_t a) {
-  // CHECK: test_vrshrn_n_s32
+  // CHECK-LABEL: test_vrshrn_n_s32
   return vrshrn_n_s32(a, 9);
   // CHECK: rshrn {{v[0-9]+}}.4h, {{v[0-9]+}}.4s, #9
 }
 
 int32x2_t test_vrshrn_n_s64(int64x2_t a) {
-  // CHECK: test_vrshrn_n_s64
+  // CHECK-LABEL: test_vrshrn_n_s64
   return vrshrn_n_s64(a, 19);
   // CHECK: rshrn {{v[0-9]+}}.2s, {{v[0-9]+}}.2d, #19
 }
 
 uint8x8_t test_vrshrn_n_u16(uint16x8_t a) {
-  // CHECK: test_vrshrn_n_u16
+  // CHECK-LABEL: test_vrshrn_n_u16
   return vrshrn_n_u16(a, 3);
   // CHECK: rshrn {{v[0-9]+}}.8b, {{v[0-9]+}}.8h, #3
 }
 
 uint16x4_t test_vrshrn_n_u32(uint32x4_t a) {
-  // CHECK: test_vrshrn_n_u32
+  // CHECK-LABEL: test_vrshrn_n_u32
   return vrshrn_n_u32(a, 9);
   // CHECK: rshrn {{v[0-9]+}}.4h, {{v[0-9]+}}.4s, #9
 }
 
 uint32x2_t test_vrshrn_n_u64(uint64x2_t a) {
-  // CHECK: test_vrshrn_n_u64
+  // CHECK-LABEL: test_vrshrn_n_u64
   return vrshrn_n_u64(a, 19);
   // CHECK: rshrn {{v[0-9]+}}.2s, {{v[0-9]+}}.2d, #19
 }
 
 int8x16_t test_vrshrn_high_n_s16(int8x8_t a, int16x8_t b) {
-  // CHECK: test_vrshrn_high_n_s16
+  // CHECK-LABEL: test_vrshrn_high_n_s16
   return vrshrn_high_n_s16(a, b, 3);
   // CHECK: rshrn2 {{v[0-9]+}}.16b, {{v[0-9]+}}.8h, #3
 }
 
 int16x8_t test_vrshrn_high_n_s32(int16x4_t a, int32x4_t b) {
-  // CHECK: test_vrshrn_high_n_s32
+  // CHECK-LABEL: test_vrshrn_high_n_s32
   return vrshrn_high_n_s32(a, b, 9);
   // CHECK: rshrn2 {{v[0-9]+}}.8h, {{v[0-9]+}}.4s, #9
 }
 
 int32x4_t test_vrshrn_high_n_s64(int32x2_t a, int64x2_t b) {
-  // CHECK: test_vrshrn_high_n_s64
+  // CHECK-LABEL: test_vrshrn_high_n_s64
   return vrshrn_high_n_s64(a, b, 19);
   // CHECK: rshrn2 {{v[0-9]+}}.4s, {{v[0-9]+}}.2d, #19
 }
 
 uint8x16_t test_vrshrn_high_n_u16(uint8x8_t a, uint16x8_t b) {
-  // CHECK: test_vrshrn_high_n_u16
+  // CHECK-LABEL: test_vrshrn_high_n_u16
   return vrshrn_high_n_u16(a, b, 3);
   // CHECK: rshrn2 {{v[0-9]+}}.16b, {{v[0-9]+}}.8h, #3
 }
 
 uint16x8_t test_vrshrn_high_n_u32(uint16x4_t a, uint32x4_t b) {
-  // CHECK: test_vrshrn_high_n_u32
+  // CHECK-LABEL: test_vrshrn_high_n_u32
   return vrshrn_high_n_u32(a, b, 9);
   // CHECK: rshrn2 {{v[0-9]+}}.8h, {{v[0-9]+}}.4s, #9
 }
 
 uint32x4_t test_vrshrn_high_n_u64(uint32x2_t a, uint64x2_t b) {
-  // CHECK: test_vrshrn_high_n_u64
+  // CHECK-LABEL: test_vrshrn_high_n_u64
   return vrshrn_high_n_u64(a, b, 19);
   // CHECK: rshrn2 {{v[0-9]+}}.4s, {{v[0-9]+}}.2d, #19
 }
 
 int8x8_t test_vqrshrun_n_s16(int16x8_t a) {
-  // CHECK: test_vqrshrun_n_s16
+  // CHECK-LABEL: test_vqrshrun_n_s16
   return vqrshrun_n_s16(a, 3);
   // CHECK: sqrshrun {{v[0-9]+}}.8b, {{v[0-9]+}}.8h, #3
 }
 
 int16x4_t test_vqrshrun_n_s32(int32x4_t a) {
-  // CHECK: test_vqrshrun_n_s32
+  // CHECK-LABEL: test_vqrshrun_n_s32
   return vqrshrun_n_s32(a, 9);
   // CHECK: sqrshrun {{v[0-9]+}}.4h, {{v[0-9]+}}.4s, #9
 }
 
 int32x2_t test_vqrshrun_n_s64(int64x2_t a) {
-  // CHECK: test_vqrshrun_n_s64
+  // CHECK-LABEL: test_vqrshrun_n_s64
   return vqrshrun_n_s64(a, 19);
   // CHECK: sqrshrun {{v[0-9]+}}.2s, {{v[0-9]+}}.2d, #19
 }
 
 int8x16_t test_vqrshrun_high_n_s16(int8x8_t a, int16x8_t b) {
-  // CHECK: test_vqrshrun_high_n_s16
+  // CHECK-LABEL: test_vqrshrun_high_n_s16
   return vqrshrun_high_n_s16(a, b, 3);
   // CHECK: sqrshrun2 {{v[0-9]+}}.16b, {{v[0-9]+}}.8h, #3
 }
 
 int16x8_t test_vqrshrun_high_n_s32(int16x4_t a, int32x4_t b) {
-  // CHECK: test_vqrshrun_high_n_s32
+  // CHECK-LABEL: test_vqrshrun_high_n_s32
   return vqrshrun_high_n_s32(a, b, 9);
   // CHECK: sqrshrun2 {{v[0-9]+}}.8h, {{v[0-9]+}}.4s, #9
 }
 
 int32x4_t test_vqrshrun_high_n_s64(int32x2_t a, int64x2_t b) {
-  // CHECK: test_vqrshrun_high_n_s64
+  // CHECK-LABEL: test_vqrshrun_high_n_s64
   return vqrshrun_high_n_s64(a, b, 19);
   // CHECK: sqrshrun2 {{v[0-9]+}}.4s, {{v[0-9]+}}.2d, #19
 }
 
 int8x8_t test_vqshrn_n_s16(int16x8_t a) {
-  // CHECK: test_vqshrn_n_s16
+  // CHECK-LABEL: test_vqshrn_n_s16
   return vqshrn_n_s16(a, 3);
   // CHECK: sqshrn {{v[0-9]+}}.8b, {{v[0-9]+}}.8h, #3
 }
 
 int16x4_t test_vqshrn_n_s32(int32x4_t a) {
-  // CHECK: test_vqshrn_n_s32
+  // CHECK-LABEL: test_vqshrn_n_s32
   return vqshrn_n_s32(a, 9);
   // CHECK: sqshrn {{v[0-9]+}}.4h, {{v[0-9]+}}.4s, #9
 }
 
 int32x2_t test_vqshrn_n_s64(int64x2_t a) {
-  // CHECK: test_vqshrn_n_s64
+  // CHECK-LABEL: test_vqshrn_n_s64
   return vqshrn_n_s64(a, 19);
   // CHECK: sqshrn {{v[0-9]+}}.2s, {{v[0-9]+}}.2d, #19
 }
 
 uint8x8_t test_vqshrn_n_u16(uint16x8_t a) {
-  // CHECK: test_vqshrn_n_u16
+  // CHECK-LABEL: test_vqshrn_n_u16
   return vqshrn_n_u16(a, 3);
   // CHECK: uqshrn {{v[0-9]+}}.8b, {{v[0-9]+}}.8h, #3
 }
 
 uint16x4_t test_vqshrn_n_u32(uint32x4_t a) {
-  // CHECK: test_vqshrn_n_u32
+  // CHECK-LABEL: test_vqshrn_n_u32
   return vqshrn_n_u32(a, 9);
   // CHECK: uqshrn {{v[0-9]+}}.4h, {{v[0-9]+}}.4s, #9
 }
 
 uint32x2_t test_vqshrn_n_u64(uint64x2_t a) {
-  // CHECK: test_vqshrn_n_u64
+  // CHECK-LABEL: test_vqshrn_n_u64
   return vqshrn_n_u64(a, 19);
   // CHECK: uqshrn {{v[0-9]+}}.2s, {{v[0-9]+}}.2d, #19
 }
 
 int8x16_t test_vqshrn_high_n_s16(int8x8_t a, int16x8_t b) {
-  // CHECK: test_vqshrn_high_n_s16
+  // CHECK-LABEL: test_vqshrn_high_n_s16
   return vqshrn_high_n_s16(a, b, 3);
   // CHECK: sqshrn2 {{v[0-9]+}}.16b, {{v[0-9]+}}.8h, #3
 }
 
 int16x8_t test_vqshrn_high_n_s32(int16x4_t a, int32x4_t b) {
-  // CHECK: test_vqshrn_high_n_s32
+  // CHECK-LABEL: test_vqshrn_high_n_s32
   return vqshrn_high_n_s32(a, b, 9);
   // CHECK: sqshrn2 {{v[0-9]+}}.8h, {{v[0-9]+}}.4s, #9
 }
 
 int32x4_t test_vqshrn_high_n_s64(int32x2_t a, int64x2_t b) {
-  // CHECK: test_vqshrn_high_n_s64
+  // CHECK-LABEL: test_vqshrn_high_n_s64
   return vqshrn_high_n_s64(a, b, 19);
   // CHECK: sqshrn2 {{v[0-9]+}}.4s, {{v[0-9]+}}.2d, #19
 }
 
 uint8x16_t test_vqshrn_high_n_u16(uint8x8_t a, uint16x8_t b) {
-  // CHECK: test_vqshrn_high_n_u16
+  // CHECK-LABEL: test_vqshrn_high_n_u16
   return vqshrn_high_n_u16(a, b, 3);
   // CHECK: uqshrn2 {{v[0-9]+}}.16b, {{v[0-9]+}}.8h, #3
 }
 
 uint16x8_t test_vqshrn_high_n_u32(uint16x4_t a, uint32x4_t b) {
-  // CHECK: test_vqshrn_high_n_u32
+  // CHECK-LABEL: test_vqshrn_high_n_u32
   return vqshrn_high_n_u32(a, b, 9);
   // CHECK: uqshrn2 {{v[0-9]+}}.8h, {{v[0-9]+}}.4s, #9
 }
 
 uint32x4_t test_vqshrn_high_n_u64(uint32x2_t a, uint64x2_t b) {
-  // CHECK: test_vqshrn_high_n_u64
+  // CHECK-LABEL: test_vqshrn_high_n_u64
   return vqshrn_high_n_u64(a, b, 19);
   // CHECK: uqshrn2 {{v[0-9]+}}.4s, {{v[0-9]+}}.2d, #19
 }
 
 int8x8_t test_vqrshrn_n_s16(int16x8_t a) {
-  // CHECK: test_vqrshrn_n_s16
+  // CHECK-LABEL: test_vqrshrn_n_s16
   return vqrshrn_n_s16(a, 3);
   // CHECK: sqrshrn {{v[0-9]+}}.8b, {{v[0-9]+}}.8h, #3
 }
 
 int16x4_t test_vqrshrn_n_s32(int32x4_t a) {
-  // CHECK: test_vqrshrn_n_s32
+  // CHECK-LABEL: test_vqrshrn_n_s32
   return vqrshrn_n_s32(a, 9);
   // CHECK: sqrshrn {{v[0-9]+}}.4h, {{v[0-9]+}}.4s, #9
 }
 
 int32x2_t test_vqrshrn_n_s64(int64x2_t a) {
-  // CHECK: test_vqrshrn_n_s64
+  // CHECK-LABEL: test_vqrshrn_n_s64
   return vqrshrn_n_s64(a, 19);
   // CHECK: sqrshrn {{v[0-9]+}}.2s, {{v[0-9]+}}.2d, #19
 }
 
 uint8x8_t test_vqrshrn_n_u16(uint16x8_t a) {
-  // CHECK: test_vqrshrn_n_u16
+  // CHECK-LABEL: test_vqrshrn_n_u16
   return vqrshrn_n_u16(a, 3);
   // CHECK: uqrshrn {{v[0-9]+}}.8b, {{v[0-9]+}}.8h, #3
 }
 
 uint16x4_t test_vqrshrn_n_u32(uint32x4_t a) {
-  // CHECK: test_vqrshrn_n_u32
+  // CHECK-LABEL: test_vqrshrn_n_u32
   return vqrshrn_n_u32(a, 9);
   // CHECK: uqrshrn {{v[0-9]+}}.4h, {{v[0-9]+}}.4s, #9
 }
 
 uint32x2_t test_vqrshrn_n_u64(uint64x2_t a) {
-  // CHECK: test_vqrshrn_n_u64
+  // CHECK-LABEL: test_vqrshrn_n_u64
   return vqrshrn_n_u64(a, 19);
   // CHECK: uqrshrn {{v[0-9]+}}.2s, {{v[0-9]+}}.2d, #19
 }
 
 int8x16_t test_vqrshrn_high_n_s16(int8x8_t a, int16x8_t b) {
-  // CHECK: test_vqrshrn_high_n_s16
+  // CHECK-LABEL: test_vqrshrn_high_n_s16
   return vqrshrn_high_n_s16(a, b, 3);
   // CHECK: sqrshrn2 {{v[0-9]+}}.16b, {{v[0-9]+}}.8h, #3
 }
 
 int16x8_t test_vqrshrn_high_n_s32(int16x4_t a, int32x4_t b) {
-  // CHECK: test_vqrshrn_high_n_s32
+  // CHECK-LABEL: test_vqrshrn_high_n_s32
   return vqrshrn_high_n_s32(a, b, 9);
   // CHECK: sqrshrn2 {{v[0-9]+}}.8h, {{v[0-9]+}}.4s, #9
 }
 
 int32x4_t test_vqrshrn_high_n_s64(int32x2_t a, int64x2_t b) {
-  // CHECK: test_vqrshrn_high_n_s64
+  // CHECK-LABEL: test_vqrshrn_high_n_s64
   return vqrshrn_high_n_s64(a, b, 19);
   // CHECK: sqrshrn2 {{v[0-9]+}}.4s, {{v[0-9]+}}.2d, #19
 }
 
 uint8x16_t test_vqrshrn_high_n_u16(uint8x8_t a, uint16x8_t b) {
-  // CHECK: test_vqrshrn_high_n_u16
+  // CHECK-LABEL: test_vqrshrn_high_n_u16
   return vqrshrn_high_n_u16(a, b, 3);
   // CHECK: uqrshrn2 {{v[0-9]+}}.16b, {{v[0-9]+}}.8h, #3
 }
 
 uint16x8_t test_vqrshrn_high_n_u32(uint16x4_t a, uint32x4_t b) {
-  // CHECK: test_vqrshrn_high_n_u32
+  // CHECK-LABEL: test_vqrshrn_high_n_u32
   return vqrshrn_high_n_u32(a, b, 9);
   // CHECK: uqrshrn2 {{v[0-9]+}}.8h, {{v[0-9]+}}.4s, #9
 }
 
 uint32x4_t test_vqrshrn_high_n_u64(uint32x2_t a, uint64x2_t b) {
-  // CHECK: test_vqrshrn_high_n_u64
+  // CHECK-LABEL: test_vqrshrn_high_n_u64
   return vqrshrn_high_n_u64(a, b, 19);
   // CHECK: uqrshrn2 {{v[0-9]+}}.4s, {{v[0-9]+}}.2d, #19
 }
 
 int16x8_t test_vshll_n_s8(int8x8_t a) {
-// CHECK: test_vshll_n_s8
+// CHECK-LABEL: test_vshll_n_s8
   return vshll_n_s8(a, 3);
 // CHECK: sshll {{v[0-9]+}}.8h, {{v[0-9]+}}.8b, #3
 }
 
 int32x4_t test_vshll_n_s16(int16x4_t a) {
-// CHECK: test_vshll_n_s16
+// CHECK-LABEL: test_vshll_n_s16
   return vshll_n_s16(a, 9);
 // CHECK: sshll {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, #9
 }
 
 int64x2_t test_vshll_n_s32(int32x2_t a) {
-// CHECK: test_vshll_n_s32
+// CHECK-LABEL: test_vshll_n_s32
   return vshll_n_s32(a, 19);
 // CHECK: sshll {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, #19
 }
 
 uint16x8_t test_vshll_n_u8(uint8x8_t a) {
-// CHECK: test_vshll_n_u8
+// CHECK-LABEL: test_vshll_n_u8
   return vshll_n_u8(a, 3);
 // CHECK: ushll {{v[0-9]+}}.8h, {{v[0-9]+}}.8b, #3
 }
 
 uint32x4_t test_vshll_n_u16(uint16x4_t a) {
-// CHECK: test_vshll_n_u16
+// CHECK-LABEL: test_vshll_n_u16
   return vshll_n_u16(a, 9);
 // CHECK: ushll {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, #9
 }
 
 uint64x2_t test_vshll_n_u32(uint32x2_t a) {
-// CHECK: test_vshll_n_u32
+// CHECK-LABEL: test_vshll_n_u32
   return vshll_n_u32(a, 19);
 // CHECK: ushll {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, #19
 }
 
 int16x8_t test_vshll_high_n_s8(int8x16_t a) {
-// CHECK: test_vshll_high_n_s8
+// CHECK-LABEL: test_vshll_high_n_s8
   return vshll_high_n_s8(a, 3);
 // CHECK: sshll2 {{v[0-9]+}}.8h, {{v[0-9]+}}.16b, #3
 }
 
 int32x4_t test_vshll_high_n_s16(int16x8_t a) {
-// CHECK: test_vshll_high_n_s16
+// CHECK-LABEL: test_vshll_high_n_s16
   return vshll_high_n_s16(a, 9);
 // CHECK: sshll2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, #9
 }
 
 int64x2_t test_vshll_high_n_s32(int32x4_t a) {
-// CHECK: test_vshll_high_n_s32
+// CHECK-LABEL: test_vshll_high_n_s32
   return vshll_high_n_s32(a, 19);
 // CHECK: sshll2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, #19
 }
 
 uint16x8_t test_vshll_high_n_u8(uint8x16_t a) {
-// CHECK: test_vshll_high_n_u8
+// CHECK-LABEL: test_vshll_high_n_u8
   return vshll_high_n_u8(a, 3);
 // CHECK: ushll2 {{v[0-9]+}}.8h, {{v[0-9]+}}.16b, #3
 }
 
 uint32x4_t test_vshll_high_n_u16(uint16x8_t a) {
-// CHECK: test_vshll_high_n_u16
+// CHECK-LABEL: test_vshll_high_n_u16
   return vshll_high_n_u16(a, 9);
 // CHECK: ushll2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, #9
 }
 
 uint64x2_t test_vshll_high_n_u32(uint32x4_t a) {
-// CHECK: test_vshll_high_n_u32
+// CHECK-LABEL: test_vshll_high_n_u32
   return vshll_high_n_u32(a, 19);
 // CHECK: ushll2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, #19
 }
 
 int16x8_t test_vmovl_s8(int8x8_t a) {
-// CHECK: test_vmovl_s8
+// CHECK-LABEL: test_vmovl_s8
   return vmovl_s8(a);
 // CHECK: sshll {{v[0-9]+}}.8h, {{v[0-9]+}}.8b, #0
 }
 
 int32x4_t test_vmovl_s16(int16x4_t a) {
-// CHECK: test_vmovl_s16
+// CHECK-LABEL: test_vmovl_s16
   return vmovl_s16(a);
 // CHECK: sshll {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, #0
 }
 
 int64x2_t test_vmovl_s32(int32x2_t a) {
-// CHECK: test_vmovl_s32
+// CHECK-LABEL: test_vmovl_s32
   return vmovl_s32(a);
 // CHECK: sshll {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, #0
 }
 
 uint16x8_t test_vmovl_u8(uint8x8_t a) {
-// CHECK: test_vmovl_u8
+// CHECK-LABEL: test_vmovl_u8
   return vmovl_u8(a);
 // CHECK: ushll {{v[0-9]+}}.8h, {{v[0-9]+}}.8b, #0
 }
 
 uint32x4_t test_vmovl_u16(uint16x4_t a) {
-// CHECK: test_vmovl_u16
+// CHECK-LABEL: test_vmovl_u16
   return vmovl_u16(a);
 // CHECK: ushll {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, #0
 }
 
 uint64x2_t test_vmovl_u32(uint32x2_t a) {
-// CHECK: test_vmovl_u32
+// CHECK-LABEL: test_vmovl_u32
   return vmovl_u32(a);
 // CHECK: ushll {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, #0
 }
 
 int16x8_t test_vmovl_high_s8(int8x16_t a) {
-// CHECK: test_vmovl_high_s8
+// CHECK-LABEL: test_vmovl_high_s8
   return vmovl_high_s8(a);
 // CHECK: sshll2 {{v[0-9]+}}.8h, {{v[0-9]+}}.16b, #0
 }
 
 int32x4_t test_vmovl_high_s16(int16x8_t a) {
-// CHECK: test_vmovl_high_s16
+// CHECK-LABEL: test_vmovl_high_s16
   return vmovl_high_s16(a);
 // CHECK: sshll2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, #0
 }
 
 int64x2_t test_vmovl_high_s32(int32x4_t a) {
-// CHECK: test_vmovl_high_s32
+// CHECK-LABEL: test_vmovl_high_s32
   return vmovl_high_s32(a);
 // CHECK: sshll2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, #0
 }
 
 uint16x8_t test_vmovl_high_u8(uint8x16_t a) {
-// CHECK: test_vmovl_high_u8
+// CHECK-LABEL: test_vmovl_high_u8
   return vmovl_high_u8(a);
 // CHECK: ushll2 {{v[0-9]+}}.8h, {{v[0-9]+}}.16b, #0
 }
 
 uint32x4_t test_vmovl_high_u16(uint16x8_t a) {
-// CHECK: test_vmovl_high_u16
+// CHECK-LABEL: test_vmovl_high_u16
   return vmovl_high_u16(a);
 // CHECK: ushll2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, #0
 }
 
 uint64x2_t test_vmovl_high_u32(uint32x4_t a) {
-// CHECK: test_vmovl_high_u32
+// CHECK-LABEL: test_vmovl_high_u32
   return vmovl_high_u32(a);
 // CHECK: ushll2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, #0
 }
 
 float32x2_t test_vcvt_n_f32_s32(int32x2_t a) {
-  // CHECK: test_vcvt_n_f32_s32
+  // CHECK-LABEL: test_vcvt_n_f32_s32
   return vcvt_n_f32_s32(a, 31);
   // CHECK: scvtf {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #31
 }
 
 float32x4_t test_vcvtq_n_f32_s32(int32x4_t a) {
-  // CHECK: test_vcvtq_n_f32_s32
+  // CHECK-LABEL: test_vcvtq_n_f32_s32
   return vcvtq_n_f32_s32(a, 31);
   // CHECK: scvtf {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #31
 }
 
 float64x2_t test_vcvtq_n_f64_s64(int64x2_t a) {
-  // CHECK: test_vcvtq_n_f64_s64
+  // CHECK-LABEL: test_vcvtq_n_f64_s64
   return vcvtq_n_f64_s64(a, 50);
   // CHECK: scvtf {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #50
 }
 
 float32x2_t test_vcvt_n_f32_u32(uint32x2_t a) {
-  // CHECK: test_vcvt_n_f32_u32
+  // CHECK-LABEL: test_vcvt_n_f32_u32
   return vcvt_n_f32_u32(a, 31);
   // CHECK: ucvtf {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #31
 }
 
 float32x4_t test_vcvtq_n_f32_u32(uint32x4_t a) {
-  // CHECK: test_vcvtq_n_f32_u32
+  // CHECK-LABEL: test_vcvtq_n_f32_u32
   return vcvtq_n_f32_u32(a, 31);
   // CHECK: ucvtf {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #31
 }
 
 float64x2_t test_vcvtq_n_f64_u64(uint64x2_t a) {
-  // CHECK: test_vcvtq_n_f64_u64
+  // CHECK-LABEL: test_vcvtq_n_f64_u64
   return vcvtq_n_f64_u64(a, 50);
   // CHECK: ucvtf {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #50
 }
 
 int32x2_t test_vcvt_n_s32_f32(float32x2_t a) {
-  // CHECK: test_vcvt_n_s32_f32
+  // CHECK-LABEL: test_vcvt_n_s32_f32
   return vcvt_n_s32_f32(a, 31);
   // CHECK: fcvtzs {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #31
 }
 
 int32x4_t test_vcvtq_n_s32_f32(float32x4_t a) {
-  // CHECK: test_vcvtq_n_s32_f32
+  // CHECK-LABEL: test_vcvtq_n_s32_f32
   return vcvtq_n_s32_f32(a, 31);
   // CHECK: fcvtzs {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #31
 }
 
 int64x2_t test_vcvtq_n_s64_f64(float64x2_t a) {
-  // CHECK: test_vcvtq_n_s64_f64
+  // CHECK-LABEL: test_vcvtq_n_s64_f64
   return vcvtq_n_s64_f64(a, 50);
   // CHECK: fcvtzs {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #50
 }
 
 uint32x2_t test_vcvt_n_u32_f32(float32x2_t a) {
-  // CHECK: test_vcvt_n_u32_f32
+  // CHECK-LABEL: test_vcvt_n_u32_f32
   return vcvt_n_u32_f32(a, 31);
   // CHECK: fcvtzu {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #31
 }
 
 uint32x4_t test_vcvtq_n_u32_f32(float32x4_t a) {
-  // CHECK: test_vcvt_n_u32_f32
+  // CHECK-LABEL: test_vcvtq_n_u32_f32
   return vcvtq_n_u32_f32(a, 31);
   // CHECK: fcvtzu {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #31
 }
 
 uint64x2_t test_vcvtq_n_u64_f64(float64x2_t a) {
-  // CHECK: test_vcvtq_n_u64_f64
+  // CHECK-LABEL: test_vcvtq_n_u64_f64
   return vcvtq_n_u64_f64(a, 50);
   // CHECK: fcvtzu {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #50
 }
 
 int16x8_t test_vaddl_s8(int8x8_t a, int8x8_t b) {
-  // CHECK: test_vaddl_s8
+  // CHECK-LABEL: test_vaddl_s8
   return vaddl_s8(a, b);
-  // CHECK: saddl {{v[0-31]+}}.8h, {{v[0-31]+}}.8b, {{v[0-31]+}}.8b
+  // CHECK: saddl {{v[0-9]+}}.8h, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 int32x4_t test_vaddl_s16(int16x4_t a, int16x4_t b) {
-  // CHECK: test_vaddl_s16
+  // CHECK-LABEL: test_vaddl_s16
   return vaddl_s16(a, b);
-  // CHECK: saddl {{v[0-31]+}}.4s, {{v[0-31]+}}.4h, {{v[0-31]+}}.4h
+  // CHECK: saddl {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 int64x2_t test_vaddl_s32(int32x2_t a, int32x2_t b) {
-  // CHECK: test_vaddl_s32
+  // CHECK-LABEL: test_vaddl_s32
   return vaddl_s32(a, b);
-  // CHECK: saddl {{v[0-31]+}}.2d, {{v[0-31]+}}.2s, {{v[0-31]+}}.2s
+  // CHECK: saddl {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 uint16x8_t test_vaddl_u8(uint8x8_t a, uint8x8_t b) {
-  // CHECK: test_vaddl_u8
+  // CHECK-LABEL: test_vaddl_u8
   return vaddl_u8(a, b);
-  // CHECK: uaddl {{v[0-31]+}}.8h, {{v[0-31]+}}.8b, {{v[0-31]+}}.8b
+  // CHECK: uaddl {{v[0-9]+}}.8h, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint32x4_t test_vaddl_u16(uint16x4_t a, uint16x4_t b) {
-  // CHECK: test_vaddl_u16
+  // CHECK-LABEL: test_vaddl_u16
   return vaddl_u16(a, b);
-  // CHECK: uaddl {{v[0-31]+}}.4s, {{v[0-31]+}}.4h, {{v[0-31]+}}.4h
+  // CHECK: uaddl {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint64x2_t test_vaddl_u32(uint32x2_t a, uint32x2_t b) {
-  // CHECK: test_vaddl_u32
+  // CHECK-LABEL: test_vaddl_u32
   return vaddl_u32(a, b);
-  // CHECK: uaddl {{v[0-31]+}}.2d, {{v[0-31]+}}.2s, {{v[0-31]+}}.2s
+  // CHECK: uaddl {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 int16x8_t test_vaddl_high_s8(int8x16_t a, int8x16_t b) {
-  // CHECK: test_vaddl_high_s8
+  // CHECK-LABEL: test_vaddl_high_s8
   return vaddl_high_s8(a, b);
-  // CHECK: saddl2 {{v[0-31]+}}.8h, {{v[0-31]+}}.16b, {{v[0-31]+}}.16b
+  // CHECK: saddl2 {{v[0-9]+}}.8h, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 int32x4_t test_vaddl_high_s16(int16x8_t a, int16x8_t b) {
-  // CHECK: test_vaddl_high_s16
+  // CHECK-LABEL: test_vaddl_high_s16
   return vaddl_high_s16(a, b);
-  // CHECK: saddl2 {{v[0-31]+}}.4s, {{v[0-31]+}}.8h, {{v[0-31]+}}.8h
+  // CHECK: saddl2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int64x2_t test_vaddl_high_s32(int32x4_t a, int32x4_t b) {
-  // CHECK: test_vaddl_high_s32
+  // CHECK-LABEL: test_vaddl_high_s32
   return vaddl_high_s32(a, b);
-  // CHECK: saddl2 {{v[0-31]+}}.2d, {{v[0-31]+}}.4s, {{v[0-31]+}}.4s
+  // CHECK: saddl2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint16x8_t test_vaddl_high_u8(uint8x16_t a, uint8x16_t b) {
-  // CHECK: test_vaddl_high_u8
+  // CHECK-LABEL: test_vaddl_high_u8
   return vaddl_high_u8(a, b);
-  // CHECK: uaddl2 {{v[0-31]+}}.8h, {{v[0-31]+}}.16b, {{v[0-31]+}}.16b
+  // CHECK: uaddl2 {{v[0-9]+}}.8h, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint32x4_t test_vaddl_high_u16(uint16x8_t a, uint16x8_t b) {
-  // CHECK: test_vaddl_high_u16
+  // CHECK-LABEL: test_vaddl_high_u16
   return vaddl_high_u16(a, b);
-  // CHECK: uaddl2 {{v[0-31]+}}.4s, {{v[0-31]+}}.8h, {{v[0-31]+}}.8h
+  // CHECK: uaddl2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint64x2_t test_vaddl_high_u32(uint32x4_t a, uint32x4_t b) {
-  // CHECK: test_vaddl_high_u32
+  // CHECK-LABEL: test_vaddl_high_u32
   return vaddl_high_u32(a, b);
-  // CHECK: uaddl2 {{v[0-31]+}}.2d, {{v[0-31]+}}.4s, {{v[0-31]+}}.4s
+  // CHECK: uaddl2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 int16x8_t test_vaddw_s8(int16x8_t a, int8x8_t b) {
-  // CHECK: test_vaddw_s8
+  // CHECK-LABEL: test_vaddw_s8
   return vaddw_s8(a, b);
-  // CHECK: saddw {{v[0-31]+}}.8h, {{v[0-31]+}}.8h, {{v[0-31]+}}.8b
+  // CHECK: saddw {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8b
 }
 
 int32x4_t test_vaddw_s16(int32x4_t a, int16x4_t b) {
-  // CHECK: test_vaddw_s16
+  // CHECK-LABEL: test_vaddw_s16
   return vaddw_s16(a, b);
-  // CHECK: saddw {{v[0-31]+}}.4s, {{v[0-31]+}}.4s, {{v[0-31]+}}.4h
+  // CHECK: saddw {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4h
 }
 
 int64x2_t test_vaddw_s32(int64x2_t a, int32x2_t b) {
-  // CHECK: test_vaddw_s32
+  // CHECK-LABEL: test_vaddw_s32
   return vaddw_s32(a, b);
-  // CHECK: saddw {{v[0-31]+}}.2d, {{v[0-31]+}}.2d, {{v[0-31]+}}.2s
+  // CHECK: saddw {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2s
 }
 
 uint16x8_t test_vaddw_u8(uint16x8_t a, uint8x8_t b) {
-  // CHECK: test_vaddw_u8
+  // CHECK-LABEL: test_vaddw_u8
   return vaddw_u8(a, b);
-  // CHECK: uaddw {{v[0-31]+}}.8h, {{v[0-31]+}}.8h, {{v[0-31]+}}.8b
+  // CHECK: uaddw {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8b
 }
 
 uint32x4_t test_vaddw_u16(uint32x4_t a, uint16x4_t b) {
-  // CHECK: test_vaddw_u16
+  // CHECK-LABEL: test_vaddw_u16
   return vaddw_u16(a, b);
-  // CHECK: uaddw {{v[0-31]+}}.4s, {{v[0-31]+}}.4s, {{v[0-31]+}}.4h
+  // CHECK: uaddw {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4h
 }
 
 uint64x2_t test_vaddw_u32(uint64x2_t a, uint32x2_t b) {
-  // CHECK: test_vaddw_u32
+  // CHECK-LABEL: test_vaddw_u32
   return vaddw_u32(a, b);
-  // CHECK: uaddw {{v[0-31]+}}.2d, {{v[0-31]+}}.2d, {{v[0-31]+}}.2s
+  // CHECK: uaddw {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2s
 }
 
 int16x8_t test_vaddw_high_s8(int16x8_t a, int8x16_t b) {
-  // CHECK: test_vaddw_high_s8
+  // CHECK-LABEL: test_vaddw_high_s8
   return vaddw_high_s8(a, b);
-  // CHECK: saddw2 {{v[0-31]+}}.8h, {{v[0-31]+}}.8h, {{v[0-31]+}}.16b
+  // CHECK: saddw2 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.16b
 }
 
 int32x4_t test_vaddw_high_s16(int32x4_t a, int16x8_t b) {
-  // CHECK: test_vaddw_high_s16
+  // CHECK-LABEL: test_vaddw_high_s16
   return vaddw_high_s16(a, b);
-  // CHECK: saddw2 {{v[0-31]+}}.4s, {{v[0-31]+}}.4s, {{v[0-31]+}}.8h
+  // CHECK: saddw2 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.8h
 }
 
 int64x2_t test_vaddw_high_s32(int64x2_t a, int32x4_t b) {
-  // CHECK: test_vaddw_high_s32
+  // CHECK-LABEL: test_vaddw_high_s32
   return vaddw_high_s32(a, b);
-  // CHECK: saddw2 {{v[0-31]+}}.2d, {{v[0-31]+}}.2d, {{v[0-31]+}}.4s
+  // CHECK: saddw2 {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.4s
 }
 
 uint16x8_t test_vaddw_high_u8(uint16x8_t a, uint8x16_t b) {
-  // CHECK: test_vaddw_high_u8
+  // CHECK-LABEL: test_vaddw_high_u8
   return vaddw_high_u8(a, b);
-  // CHECK: uaddw2 {{v[0-31]+}}.8h, {{v[0-31]+}}.8h, {{v[0-31]+}}.16b
+  // CHECK: uaddw2 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.16b
 }
 
 uint32x4_t test_vaddw_high_u16(uint32x4_t a, uint16x8_t b) {
-  // CHECK: test_vaddw_high_u16
+  // CHECK-LABEL: test_vaddw_high_u16
   return vaddw_high_u16(a, b);
-  // CHECK: uaddw2 {{v[0-31]+}}.4s, {{v[0-31]+}}.4s, {{v[0-31]+}}.8h
+  // CHECK: uaddw2 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.8h
 }
 
 uint64x2_t test_vaddw_high_u32(uint64x2_t a, uint32x4_t b) {
-  // CHECK: test_vaddw_high_u32
+  // CHECK-LABEL: test_vaddw_high_u32
   return vaddw_high_u32(a, b);
-  // CHECK: uaddw2 {{v[0-31]+}}.2d, {{v[0-31]+}}.2d, {{v[0-31]+}}.4s
+  // CHECK: uaddw2 {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.4s
 }
 
 int16x8_t test_vsubl_s8(int8x8_t a, int8x8_t b) {
-  // CHECK: test_vsubl_s8
+  // CHECK-LABEL: test_vsubl_s8
   return vsubl_s8(a, b);
-  // CHECK: ssubl {{v[0-31]+}}.8h, {{v[0-31]+}}.8b, {{v[0-31]+}}.8b
+  // CHECK: ssubl {{v[0-9]+}}.8h, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 int32x4_t test_vsubl_s16(int16x4_t a, int16x4_t b) {
-  // CHECK: test_vsubl_s16
+  // CHECK-LABEL: test_vsubl_s16
   return vsubl_s16(a, b);
-  // CHECK: ssubl {{v[0-31]+}}.4s, {{v[0-31]+}}.4h, {{v[0-31]+}}.4h
+  // CHECK: ssubl {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 int64x2_t test_vsubl_s32(int32x2_t a, int32x2_t b) {
-  // CHECK: test_vsubl_s32
+  // CHECK-LABEL: test_vsubl_s32
   return vsubl_s32(a, b);
-  // CHECK: ssubl {{v[0-31]+}}.2d, {{v[0-31]+}}.2s, {{v[0-31]+}}.2s
+  // CHECK: ssubl {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 uint16x8_t test_vsubl_u8(uint8x8_t a, uint8x8_t b) {
-  // CHECK: test_vsubl_u8
+  // CHECK-LABEL: test_vsubl_u8
   return vsubl_u8(a, b);
-  // CHECK: usubl {{v[0-31]+}}.8h, {{v[0-31]+}}.8b, {{v[0-31]+}}.8b
+  // CHECK: usubl {{v[0-9]+}}.8h, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint32x4_t test_vsubl_u16(uint16x4_t a, uint16x4_t b) {
-  // CHECK: test_vsubl_u16
+  // CHECK-LABEL: test_vsubl_u16
   return vsubl_u16(a, b);
-  // CHECK: usubl {{v[0-31]+}}.4s, {{v[0-31]+}}.4h, {{v[0-31]+}}.4h
+  // CHECK: usubl {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint64x2_t test_vsubl_u32(uint32x2_t a, uint32x2_t b) {
-  // CHECK: test_vsubl_u32
+  // CHECK-LABEL: test_vsubl_u32
   return vsubl_u32(a, b);
-  // CHECK: usubl {{v[0-31]+}}.2d, {{v[0-31]+}}.2s, {{v[0-31]+}}.2s
+  // CHECK: usubl {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 int16x8_t test_vsubl_high_s8(int8x16_t a, int8x16_t b) {
-  // CHECK: test_vsubl_high_s8
+  // CHECK-LABEL: test_vsubl_high_s8
   return vsubl_high_s8(a, b);
-  // CHECK: ssubl2 {{v[0-31]+}}.8h, {{v[0-31]+}}.16b, {{v[0-31]+}}.16b
+  // CHECK: ssubl2 {{v[0-9]+}}.8h, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 int32x4_t test_vsubl_high_s16(int16x8_t a, int16x8_t b) {
-  // CHECK: test_vsubl_high_s16
+  // CHECK-LABEL: test_vsubl_high_s16
   return vsubl_high_s16(a, b);
-  // CHECK: ssubl2 {{v[0-31]+}}.4s, {{v[0-31]+}}.8h, {{v[0-31]+}}.8h
+  // CHECK: ssubl2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int64x2_t test_vsubl_high_s32(int32x4_t a, int32x4_t b) {
-  // CHECK: test_vsubl_high_s32
+  // CHECK-LABEL: test_vsubl_high_s32
   return vsubl_high_s32(a, b);
-  // CHECK: ssubl2 {{v[0-31]+}}.2d, {{v[0-31]+}}.4s, {{v[0-31]+}}.4s
+  // CHECK: ssubl2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint16x8_t test_vsubl_high_u8(uint8x16_t a, uint8x16_t b) {
-  // CHECK: test_vsubl_high_u8
+  // CHECK-LABEL: test_vsubl_high_u8
   return vsubl_high_u8(a, b);
-  // CHECK: usubl2 {{v[0-31]+}}.8h, {{v[0-31]+}}.16b, {{v[0-31]+}}.16b
+  // CHECK: usubl2 {{v[0-9]+}}.8h, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint32x4_t test_vsubl_high_u16(uint16x8_t a, uint16x8_t b) {
-  // CHECK: test_vsubl_high_u16
+  // CHECK-LABEL: test_vsubl_high_u16
   return vsubl_high_u16(a, b);
-  // CHECK: usubl2 {{v[0-31]+}}.4s, {{v[0-31]+}}.8h, {{v[0-31]+}}.8h
+  // CHECK: usubl2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint64x2_t test_vsubl_high_u32(uint32x4_t a, uint32x4_t b) {
-  // CHECK: test_vsubl_high_u32
+  // CHECK-LABEL: test_vsubl_high_u32
   return vsubl_high_u32(a, b);
-  // CHECK: usubl2 {{v[0-31]+}}.2d, {{v[0-31]+}}.4s, {{v[0-31]+}}.4s
+  // CHECK: usubl2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 int16x8_t test_vsubw_s8(int16x8_t a, int8x8_t b) {
-  // CHECK: test_vsubw_s8
+  // CHECK-LABEL: test_vsubw_s8
   return vsubw_s8(a, b);
-  // CHECK: ssubw {{v[0-31]+}}.8h, {{v[0-31]+}}.8h, {{v[0-31]+}}.8b
+  // CHECK: ssubw {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8b
 }
 
 int32x4_t test_vsubw_s16(int32x4_t a, int16x4_t b) {
-  // CHECK: test_vsubw_s16
+  // CHECK-LABEL: test_vsubw_s16
   return vsubw_s16(a, b);
-  // CHECK: ssubw {{v[0-31]+}}.4s, {{v[0-31]+}}.4s, {{v[0-31]+}}.4h
+  // CHECK: ssubw {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4h
 }
 
 int64x2_t test_vsubw_s32(int64x2_t a, int32x2_t b) {
-  // CHECK: test_vsubw_s32
+  // CHECK-LABEL: test_vsubw_s32
   return vsubw_s32(a, b);
-  // CHECK: ssubw {{v[0-31]+}}.2d, {{v[0-31]+}}.2d, {{v[0-31]+}}.2s
+  // CHECK: ssubw {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2s
 }
 
 uint16x8_t test_vsubw_u8(uint16x8_t a, uint8x8_t b) {
-  // CHECK: test_vsubw_u8
+  // CHECK-LABEL: test_vsubw_u8
   return vsubw_u8(a, b);
-  // CHECK: usubw {{v[0-31]+}}.8h, {{v[0-31]+}}.8h, {{v[0-31]+}}.8b
+  // CHECK: usubw {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.8b
 }
 
 uint32x4_t test_vsubw_u16(uint32x4_t a, uint16x4_t b) {
-  // CHECK: test_vsubw_u16
+  // CHECK-LABEL: test_vsubw_u16
   return vsubw_u16(a, b);
-  // CHECK: usubw {{v[0-31]+}}.4s, {{v[0-31]+}}.4s, {{v[0-31]+}}.4h
+  // CHECK: usubw {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4h
 }
 
 uint64x2_t test_vsubw_u32(uint64x2_t a, uint32x2_t b) {
-  // CHECK: test_vsubw_u32
+  // CHECK-LABEL: test_vsubw_u32
   return vsubw_u32(a, b);
-  // CHECK: usubw {{v[0-31]+}}.2d, {{v[0-31]+}}.2d, {{v[0-31]+}}.2s
+  // CHECK: usubw {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2s
 }
 
 int16x8_t test_vsubw_high_s8(int16x8_t a, int8x16_t b) {
-  // CHECK: test_vsubw_high_s8
+  // CHECK-LABEL: test_vsubw_high_s8
   return vsubw_high_s8(a, b);
-  // CHECK: ssubw2 {{v[0-31]+}}.8h, {{v[0-31]+}}.8h, {{v[0-31]+}}.16b
+  // CHECK: ssubw2 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.16b
 }
 
 int32x4_t test_vsubw_high_s16(int32x4_t a, int16x8_t b) {
-  // CHECK: test_vsubw_high_s16
+  // CHECK-LABEL: test_vsubw_high_s16
   return vsubw_high_s16(a, b);
-  // CHECK: ssubw2 {{v[0-31]+}}.4s, {{v[0-31]+}}.4s, {{v[0-31]+}}.8h
+  // CHECK: ssubw2 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.8h
 }
 
 int64x2_t test_vsubw_high_s32(int64x2_t a, int32x4_t b) {
-  // CHECK: test_vsubw_high_s32
+  // CHECK-LABEL: test_vsubw_high_s32
   return vsubw_high_s32(a, b);
-  // CHECK: ssubw2 {{v[0-31]+}}.2d, {{v[0-31]+}}.2d, {{v[0-31]+}}.4s
+  // CHECK: ssubw2 {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.4s
 }
 
 uint16x8_t test_vsubw_high_u8(uint16x8_t a, uint8x16_t b) {
-  // CHECK: test_vsubw_high_u8
+  // CHECK-LABEL: test_vsubw_high_u8
   return vsubw_high_u8(a, b);
-  // CHECK: usubw2 {{v[0-31]+}}.8h, {{v[0-31]+}}.8h, {{v[0-31]+}}.16b
+  // CHECK: usubw2 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, {{v[0-9]+}}.16b
 }
 
 uint32x4_t test_vsubw_high_u16(uint32x4_t a, uint16x8_t b) {
-  // CHECK: test_vsubw_high_u16
+  // CHECK-LABEL: test_vsubw_high_u16
   return vsubw_high_u16(a, b);
-  // CHECK: usubw2 {{v[0-31]+}}.4s, {{v[0-31]+}}.4s, {{v[0-31]+}}.8h
+  // CHECK: usubw2 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.8h
 }
 
 uint64x2_t test_vsubw_high_u32(uint64x2_t a, uint32x4_t b) {
-  // CHECK: test_vsubw_high_u32
+  // CHECK-LABEL: test_vsubw_high_u32
   return vsubw_high_u32(a, b);
-  // CHECK: usubw2 {{v[0-31]+}}.2d, {{v[0-31]+}}.2d, {{v[0-31]+}}.4s
+  // CHECK: usubw2 {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.4s
 }
 
 int8x8_t test_vaddhn_s16(int16x8_t a, int16x8_t b) {
-  // CHECK: test_vaddhn_s16
+  // CHECK-LABEL: test_vaddhn_s16
   return vaddhn_s16(a, b);
-  // CHECK: addhn {{v[0-31]+}}.8b, {{v[0-31]+}}.8h, {{v[0-31]+}}.8h
+  // CHECK: addhn {{v[0-9]+}}.8b, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int16x4_t test_vaddhn_s32(int32x4_t a, int32x4_t b) {
-  // CHECK: test_vaddhn_s32
+  // CHECK-LABEL: test_vaddhn_s32
   return vaddhn_s32(a, b);
-  // CHECK: addhn {{v[0-31]+}}.4h, {{v[0-31]+}}.4s, {{v[0-31]+}}.4s
+  // CHECK: addhn {{v[0-9]+}}.4h, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 int32x2_t test_vaddhn_s64(int64x2_t a, int64x2_t b) {
-  // CHECK: test_vaddhn_s64
+  // CHECK-LABEL: test_vaddhn_s64
   return vaddhn_s64(a, b);
-  // CHECK: addhn {{v[0-31]+}}.2s, {{v[0-31]+}}.2d, {{v[0-31]+}}.2d
+  // CHECK: addhn {{v[0-9]+}}.2s, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 uint8x8_t test_vaddhn_u16(uint16x8_t a, uint16x8_t b) {
-  // CHECK: test_vaddhn_u16
+  // CHECK-LABEL: test_vaddhn_u16
   return vaddhn_u16(a, b);
-  // CHECK: addhn {{v[0-31]+}}.8b, {{v[0-31]+}}.8h, {{v[0-31]+}}.8h
+  // CHECK: addhn {{v[0-9]+}}.8b, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint16x4_t test_vaddhn_u32(uint32x4_t a, uint32x4_t b) {
-  // CHECK: test_vaddhn_u32
+  // CHECK-LABEL: test_vaddhn_u32
   return vaddhn_u32(a, b);
-  // CHECK: addhn {{v[0-31]+}}.4h, {{v[0-31]+}}.4s, {{v[0-31]+}}.4s
+  // CHECK: addhn {{v[0-9]+}}.4h, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint32x2_t test_vaddhn_u64(uint64x2_t a, uint64x2_t b) {
-  // CHECK: test_vaddhn_u64
+  // CHECK-LABEL: test_vaddhn_u64
   return vaddhn_u64(a, b);
-  // CHECK: addhn {{v[0-31]+}}.2s, {{v[0-31]+}}.2d, {{v[0-31]+}}.2d
+  // CHECK: addhn {{v[0-9]+}}.2s, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 int8x16_t test_vaddhn_high_s16(int8x8_t r, int16x8_t a, int16x8_t b) {
-  // CHECK: test_vaddhn_high_s16
+  // CHECK-LABEL: test_vaddhn_high_s16
   return vaddhn_high_s16(r, a, b);
-  // CHECK: addhn2 {{v[0-31]+}}.16b, {{v[0-31]+}}.8h, {{v[0-31]+}}.8h
+  // CHECK: addhn2 {{v[0-9]+}}.16b, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int16x8_t test_vaddhn_high_s32(int16x4_t r, int32x4_t a, int32x4_t b) {
-  // CHECK: test_vaddhn_high_s32
+  // CHECK-LABEL: test_vaddhn_high_s32
   return vaddhn_high_s32(r, a, b);
-  // CHECK: addhn2 {{v[0-31]+}}.8h, {{v[0-31]+}}.4s, {{v[0-31]+}}.4s
+  // CHECK: addhn2 {{v[0-9]+}}.8h, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 int32x4_t test_vaddhn_high_s64(int32x2_t r, int64x2_t a, int64x2_t b) {
-  // CHECK: test_vaddhn_high_s64
+  // CHECK-LABEL: test_vaddhn_high_s64
   return vaddhn_high_s64(r, a, b);
-  // CHECK: addhn2 {{v[0-31]+}}.4s, {{v[0-31]+}}.2d, {{v[0-31]+}}.2d
+  // CHECK: addhn2 {{v[0-9]+}}.4s, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 uint8x16_t test_vaddhn_high_u16(uint8x8_t r, uint16x8_t a, uint16x8_t b) {
-  // CHECK: test_vaddhn_high_u16
+  // CHECK-LABEL: test_vaddhn_high_u16
   return vaddhn_high_u16(r, a, b);
-  // CHECK: addhn2 {{v[0-31]+}}.16b, {{v[0-31]+}}.8h, {{v[0-31]+}}.8h
+  // CHECK: addhn2 {{v[0-9]+}}.16b, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint16x8_t test_vaddhn_high_u32(uint16x4_t r, uint32x4_t a, uint32x4_t b) {
-  // CHECK: test_vaddhn_high_u32
+  // CHECK-LABEL: test_vaddhn_high_u32
   return vaddhn_high_u32(r, a, b);
-  // CHECK: addhn2 {{v[0-31]+}}.8h, {{v[0-31]+}}.4s, {{v[0-31]+}}.4s
+  // CHECK: addhn2 {{v[0-9]+}}.8h, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint32x4_t test_vaddhn_high_u64(uint32x2_t r, uint64x2_t a, uint64x2_t b) {
-  // CHECK: test_vaddhn_high_u64
+  // CHECK-LABEL: test_vaddhn_high_u64
   return vaddhn_high_u64(r, a, b);
-  // CHECK: addhn2 {{v[0-31]+}}.4s, {{v[0-31]+}}.2d, {{v[0-31]+}}.2d
+  // CHECK: addhn2 {{v[0-9]+}}.4s, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 int8x8_t test_vraddhn_s16(int16x8_t a, int16x8_t b) {
-  // CHECK: test_vraddhn_s16
+  // CHECK-LABEL: test_vraddhn_s16
   return vraddhn_s16(a, b);
-  // CHECK: raddhn {{v[0-31]+}}.8b, {{v[0-31]+}}.8h, {{v[0-31]+}}.8h
+  // CHECK: raddhn {{v[0-9]+}}.8b, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int16x4_t test_vraddhn_s32(int32x4_t a, int32x4_t b) {
-  // CHECK: test_vraddhn_s32
+  // CHECK-LABEL: test_vraddhn_s32
   return vraddhn_s32(a, b);
-  // CHECK: raddhn {{v[0-31]+}}.4h, {{v[0-31]+}}.4s, {{v[0-31]+}}.4s
+  // CHECK: raddhn {{v[0-9]+}}.4h, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 int32x2_t test_vraddhn_s64(int64x2_t a, int64x2_t b) {
-  // CHECK: test_vraddhn_s64
+  // CHECK-LABEL: test_vraddhn_s64
   return vraddhn_s64(a, b);
-  // CHECK: raddhn {{v[0-31]+}}.2s, {{v[0-31]+}}.2d, {{v[0-31]+}}.2d
+  // CHECK: raddhn {{v[0-9]+}}.2s, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 uint8x8_t test_vraddhn_u16(uint16x8_t a, uint16x8_t b) {
-  // CHECK: test_vraddhn_u16
+  // CHECK-LABEL: test_vraddhn_u16
   return vraddhn_u16(a, b);
-  // CHECK: raddhn {{v[0-31]+}}.8b, {{v[0-31]+}}.8h, {{v[0-31]+}}.8h
+  // CHECK: raddhn {{v[0-9]+}}.8b, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint16x4_t test_vraddhn_u32(uint32x4_t a, uint32x4_t b) {
-  // CHECK: test_vraddhn_u32
+  // CHECK-LABEL: test_vraddhn_u32
   return vraddhn_u32(a, b);
-  // CHECK: raddhn {{v[0-31]+}}.4h, {{v[0-31]+}}.4s, {{v[0-31]+}}.4s
+  // CHECK: raddhn {{v[0-9]+}}.4h, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint32x2_t test_vraddhn_u64(uint64x2_t a, uint64x2_t b) {
-  // CHECK: test_vraddhn_u64
+  // CHECK-LABEL: test_vraddhn_u64
   return vraddhn_u64(a, b);
-  // CHECK: raddhn {{v[0-31]+}}.2s, {{v[0-31]+}}.2d, {{v[0-31]+}}.2d
+  // CHECK: raddhn {{v[0-9]+}}.2s, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 int8x16_t test_vraddhn_high_s16(int8x8_t r, int16x8_t a, int16x8_t b) {
-  // CHECK: test_vraddhn_high_s16
+  // CHECK-LABEL: test_vraddhn_high_s16
   return vraddhn_high_s16(r, a, b);
-  // CHECK: raddhn2 {{v[0-31]+}}.16b, {{v[0-31]+}}.8h, {{v[0-31]+}}.8h
+  // CHECK: raddhn2 {{v[0-9]+}}.16b, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int16x8_t test_vraddhn_high_s32(int16x4_t r, int32x4_t a, int32x4_t b) {
-  // CHECK: test_vraddhn_high_s32
+  // CHECK-LABEL: test_vraddhn_high_s32
   return vraddhn_high_s32(r, a, b);
-  // CHECK: raddhn2 {{v[0-31]+}}.8h, {{v[0-31]+}}.4s, {{v[0-31]+}}.4s
+  // CHECK: raddhn2 {{v[0-9]+}}.8h, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 int32x4_t test_vraddhn_high_s64(int32x2_t r, int64x2_t a, int64x2_t b) {
-  // CHECK: test_vraddhn_high_s64
+  // CHECK-LABEL: test_vraddhn_high_s64
   return vraddhn_high_s64(r, a, b);
-  // CHECK: raddhn2 {{v[0-31]+}}.4s, {{v[0-31]+}}.2d, {{v[0-31]+}}.2d
+  // CHECK: raddhn2 {{v[0-9]+}}.4s, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 uint8x16_t test_vraddhn_high_u16(uint8x8_t r, uint16x8_t a, uint16x8_t b) {
-  // CHECK: test_vraddhn_high_u16
+  // CHECK-LABEL: test_vraddhn_high_u16
   return vraddhn_high_u16(r, a, b);
-  // CHECK: raddhn2 {{v[0-31]+}}.16b, {{v[0-31]+}}.8h, {{v[0-31]+}}.8h
+  // CHECK: raddhn2 {{v[0-9]+}}.16b, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint16x8_t test_vraddhn_high_u32(uint16x4_t r, uint32x4_t a, uint32x4_t b) {
-  // CHECK: test_vraddhn_high_u32
+  // CHECK-LABEL: test_vraddhn_high_u32
   return vraddhn_high_u32(r, a, b);
-  // CHECK: raddhn2 {{v[0-31]+}}.8h, {{v[0-31]+}}.4s, {{v[0-31]+}}.4s
+  // CHECK: raddhn2 {{v[0-9]+}}.8h, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint32x4_t test_vraddhn_high_u64(uint32x2_t r, uint64x2_t a, uint64x2_t b) {
-  // CHECK: test_vraddhn_high_u64
+  // CHECK-LABEL: test_vraddhn_high_u64
   return vraddhn_high_u64(r, a, b);
-  // CHECK: raddhn2 {{v[0-31]+}}.4s, {{v[0-31]+}}.2d, {{v[0-31]+}}.2d
+  // CHECK: raddhn2 {{v[0-9]+}}.4s, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 int8x8_t test_vsubhn_s16(int16x8_t a, int16x8_t b) {
-  // CHECK: test_vsubhn_s16
+  // CHECK-LABEL: test_vsubhn_s16
   return vsubhn_s16(a, b);
-  // CHECK: subhn {{v[0-31]+}}.8b, {{v[0-31]+}}.8h, {{v[0-31]+}}.8h
+  // CHECK: subhn {{v[0-9]+}}.8b, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int16x4_t test_vsubhn_s32(int32x4_t a, int32x4_t b) {
-  // CHECK: test_vsubhn_s32
+  // CHECK-LABEL: test_vsubhn_s32
   return vsubhn_s32(a, b);
-  // CHECK: subhn {{v[0-31]+}}.4h, {{v[0-31]+}}.4s, {{v[0-31]+}}.4s
+  // CHECK: subhn {{v[0-9]+}}.4h, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 int32x2_t test_vsubhn_s64(int64x2_t a, int64x2_t b) {
-  // CHECK: test_vsubhn_s64
+  // CHECK-LABEL: test_vsubhn_s64
   return vsubhn_s64(a, b);
-  // CHECK: subhn {{v[0-31]+}}.2s, {{v[0-31]+}}.2d, {{v[0-31]+}}.2d
+  // CHECK: subhn {{v[0-9]+}}.2s, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 uint8x8_t test_vsubhn_u16(uint16x8_t a, uint16x8_t b) {
-  // CHECK: test_vsubhn_u16
+  // CHECK-LABEL: test_vsubhn_u16
   return vsubhn_u16(a, b);
-  // CHECK: subhn {{v[0-31]+}}.8b, {{v[0-31]+}}.8h, {{v[0-31]+}}.8h
+  // CHECK: subhn {{v[0-9]+}}.8b, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint16x4_t test_vsubhn_u32(uint32x4_t a, uint32x4_t b) {
-  // CHECK: test_vsubhn_u32
+  // CHECK-LABEL: test_vsubhn_u32
   return vsubhn_u32(a, b);
-  // CHECK: subhn {{v[0-31]+}}.4h, {{v[0-31]+}}.4s, {{v[0-31]+}}.4s
+  // CHECK: subhn {{v[0-9]+}}.4h, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint32x2_t test_vsubhn_u64(uint64x2_t a, uint64x2_t b) {
-  // CHECK: test_vsubhn_u64
+  // CHECK-LABEL: test_vsubhn_u64
   return vsubhn_u64(a, b);
-  // CHECK: subhn {{v[0-31]+}}.2s, {{v[0-31]+}}.2d, {{v[0-31]+}}.2d
+  // CHECK: subhn {{v[0-9]+}}.2s, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 int8x16_t test_vsubhn_high_s16(int8x8_t r, int16x8_t a, int16x8_t b) {
-  // CHECK: test_vsubhn_high_s16
+  // CHECK-LABEL: test_vsubhn_high_s16
   return vsubhn_high_s16(r, a, b);
-  // CHECK: subhn2 {{v[0-31]+}}.16b, {{v[0-31]+}}.8h, {{v[0-31]+}}.8h
+  // CHECK: subhn2 {{v[0-9]+}}.16b, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int16x8_t test_vsubhn_high_s32(int16x4_t r, int32x4_t a, int32x4_t b) {
-  // CHECK: test_vsubhn_high_s32
+  // CHECK-LABEL: test_vsubhn_high_s32
   return vsubhn_high_s32(r, a, b);
-  // CHECK: subhn2 {{v[0-31]+}}.8h, {{v[0-31]+}}.4s, {{v[0-31]+}}.4s
+  // CHECK: subhn2 {{v[0-9]+}}.8h, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 int32x4_t test_vsubhn_high_s64(int32x2_t r, int64x2_t a, int64x2_t b) {
-  // CHECK: test_vsubhn_high_s64
+  // CHECK-LABEL: test_vsubhn_high_s64
   return vsubhn_high_s64(r, a, b);
-  // CHECK: subhn2 {{v[0-31]+}}.4s, {{v[0-31]+}}.2d, {{v[0-31]+}}.2d
+  // CHECK: subhn2 {{v[0-9]+}}.4s, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 uint8x16_t test_vsubhn_high_u16(uint8x8_t r, uint16x8_t a, uint16x8_t b) {
-  // CHECK: test_vsubhn_high_u16
+  // CHECK-LABEL: test_vsubhn_high_u16
   return vsubhn_high_u16(r, a, b);
-  // CHECK: subhn2 {{v[0-31]+}}.16b, {{v[0-31]+}}.8h, {{v[0-31]+}}.8h
+  // CHECK: subhn2 {{v[0-9]+}}.16b, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint16x8_t test_vsubhn_high_u32(uint16x4_t r, uint32x4_t a, uint32x4_t b) {
-  // CHECK: test_vsubhn_high_u32
+  // CHECK-LABEL: test_vsubhn_high_u32
   return vsubhn_high_u32(r, a, b);
-  // CHECK: subhn2 {{v[0-31]+}}.8h, {{v[0-31]+}}.4s, {{v[0-31]+}}.4s
+  // CHECK: subhn2 {{v[0-9]+}}.8h, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint32x4_t test_vsubhn_high_u64(uint32x2_t r, uint64x2_t a, uint64x2_t b) {
-  // CHECK: test_vsubhn_high_u64
+  // CHECK-LABEL: test_vsubhn_high_u64
   return vsubhn_high_u64(r, a, b);
-  // CHECK: subhn2 {{v[0-31]+}}.4s, {{v[0-31]+}}.2d, {{v[0-31]+}}.2d
+  // CHECK: subhn2 {{v[0-9]+}}.4s, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 int8x8_t test_vrsubhn_s16(int16x8_t a, int16x8_t b) {
-  // CHECK: test_vrsubhn_s16
+  // CHECK-LABEL: test_vrsubhn_s16
   return vrsubhn_s16(a, b);
-  // CHECK: rsubhn {{v[0-31]+}}.8b, {{v[0-31]+}}.8h, {{v[0-31]+}}.8h
+  // CHECK: rsubhn {{v[0-9]+}}.8b, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int16x4_t test_vrsubhn_s32(int32x4_t a, int32x4_t b) {
-  // CHECK: test_vrsubhn_s32
+  // CHECK-LABEL: test_vrsubhn_s32
   return vrsubhn_s32(a, b);
-  // CHECK: rsubhn {{v[0-31]+}}.4h, {{v[0-31]+}}.4s, {{v[0-31]+}}.4s
+  // CHECK: rsubhn {{v[0-9]+}}.4h, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 int32x2_t test_vrsubhn_s64(int64x2_t a, int64x2_t b) {
-  // CHECK: test_vrsubhn_s64
+  // CHECK-LABEL: test_vrsubhn_s64
   return vrsubhn_s64(a, b);
-  // CHECK: rsubhn {{v[0-31]+}}.2s, {{v[0-31]+}}.2d, {{v[0-31]+}}.2d
+  // CHECK: rsubhn {{v[0-9]+}}.2s, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 uint8x8_t test_vrsubhn_u16(uint16x8_t a, uint16x8_t b) {
-  // CHECK: test_vrsubhn_u16
+  // CHECK-LABEL: test_vrsubhn_u16
   return vrsubhn_u16(a, b);
-  // CHECK: rsubhn {{v[0-31]+}}.8b, {{v[0-31]+}}.8h, {{v[0-31]+}}.8h
+  // CHECK: rsubhn {{v[0-9]+}}.8b, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint16x4_t test_vrsubhn_u32(uint32x4_t a, uint32x4_t b) {
-  // CHECK: test_vrsubhn_u32
+  // CHECK-LABEL: test_vrsubhn_u32
   return vrsubhn_u32(a, b);
-  // CHECK: rsubhn {{v[0-31]+}}.4h, {{v[0-31]+}}.4s, {{v[0-31]+}}.4s
+  // CHECK: rsubhn {{v[0-9]+}}.4h, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint32x2_t test_vrsubhn_u64(uint64x2_t a, uint64x2_t b) {
-  // CHECK: test_vrsubhn_u64
+  // CHECK-LABEL: test_vrsubhn_u64
   return vrsubhn_u64(a, b);
-  // CHECK: rsubhn {{v[0-31]+}}.2s, {{v[0-31]+}}.2d, {{v[0-31]+}}.2d
+  // CHECK: rsubhn {{v[0-9]+}}.2s, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 int8x16_t test_vrsubhn_high_s16(int8x8_t r, int16x8_t a, int16x8_t b) {
-  // CHECK: test_vrsubhn_high_s16
+  // CHECK-LABEL: test_vrsubhn_high_s16
   return vrsubhn_high_s16(r, a, b);
-  // CHECK: rsubhn2 {{v[0-31]+}}.16b, {{v[0-31]+}}.8h, {{v[0-31]+}}.8h
+  // CHECK: rsubhn2 {{v[0-9]+}}.16b, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int16x8_t test_vrsubhn_high_s32(int16x4_t r, int32x4_t a, int32x4_t b) {
-  // CHECK: test_vrsubhn_high_s32
+  // CHECK-LABEL: test_vrsubhn_high_s32
   return vrsubhn_high_s32(r, a, b);
-  // CHECK: rsubhn2 {{v[0-31]+}}.8h, {{v[0-31]+}}.4s, {{v[0-31]+}}.4s
+  // CHECK: rsubhn2 {{v[0-9]+}}.8h, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 int32x4_t test_vrsubhn_high_s64(int32x2_t r, int64x2_t a, int64x2_t b) {
-  // CHECK: test_vrsubhn_high_s64
+  // CHECK-LABEL: test_vrsubhn_high_s64
   return vrsubhn_high_s64(r, a, b);
-  // CHECK: rsubhn2 {{v[0-31]+}}.4s, {{v[0-31]+}}.2d, {{v[0-31]+}}.2d
+  // CHECK: rsubhn2 {{v[0-9]+}}.4s, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 uint8x16_t test_vrsubhn_high_u16(uint8x8_t r, uint16x8_t a, uint16x8_t b) {
-  // CHECK: test_vrsubhn_high_u16
+  // CHECK-LABEL: test_vrsubhn_high_u16
   return vrsubhn_high_u16(r, a, b);
-  // CHECK: rsubhn2 {{v[0-31]+}}.16b, {{v[0-31]+}}.8h, {{v[0-31]+}}.8h
+  // CHECK: rsubhn2 {{v[0-9]+}}.16b, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint16x8_t test_vrsubhn_high_u32(uint16x4_t r, uint32x4_t a, uint32x4_t b) {
-  // CHECK: test_vrsubhn_high_u32
+  // CHECK-LABEL: test_vrsubhn_high_u32
   return vrsubhn_high_u32(r, a, b);
-  // CHECK: rsubhn2 {{v[0-31]+}}.8h, {{v[0-31]+}}.4s, {{v[0-31]+}}.4s
+  // CHECK: rsubhn2 {{v[0-9]+}}.8h, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint32x4_t test_vrsubhn_high_u64(uint32x2_t r, uint64x2_t a, uint64x2_t b) {
-  // CHECK: test_vrsubhn_high_u64
+  // CHECK-LABEL: test_vrsubhn_high_u64
   return vrsubhn_high_u64(r, a, b);
-  // CHECK: rsubhn2 {{v[0-31]+}}.4s, {{v[0-31]+}}.2d, {{v[0-31]+}}.2d
+  // CHECK: rsubhn2 {{v[0-9]+}}.4s, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 int16x8_t test_vabdl_s8(int8x8_t a, int8x8_t b) {
-  // CHECK: test_vabdl_s8
+  // CHECK-LABEL: test_vabdl_s8
   return vabdl_s8(a, b);
-  // CHECK: sabdl {{v[0-31]+}}.8h, {{v[0-31]+}}.8b, {{v[0-31]+}}.8b
+  // CHECK: sabdl {{v[0-9]+}}.8h, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 int32x4_t test_vabdl_s16(int16x4_t a, int16x4_t b) {
-  // CHECK: test_vabdl_s16
+  // CHECK-LABEL: test_vabdl_s16
   return vabdl_s16(a, b);
-  // CHECK: sabdl {{v[0-31]+}}.4s, {{v[0-31]+}}.4h, {{v[0-31]+}}.4h
+  // CHECK: sabdl {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 int64x2_t test_vabdl_s32(int32x2_t a, int32x2_t b) {
-  // CHECK: test_vabdl_s32
+  // CHECK-LABEL: test_vabdl_s32
   return vabdl_s32(a, b);
-  // CHECK: sabdl {{v[0-31]+}}.2d, {{v[0-31]+}}.2s, {{v[0-31]+}}.2s
+  // CHECK: sabdl {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 uint16x8_t test_vabdl_u8(uint8x8_t a, uint8x8_t b) {
-  // CHECK: test_vabdl_u8
+  // CHECK-LABEL: test_vabdl_u8
   return vabdl_u8(a, b);
-  // CHECK: uabdl {{v[0-31]+}}.8h, {{v[0-31]+}}.8b, {{v[0-31]+}}.8b
+  // CHECK: uabdl {{v[0-9]+}}.8h, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 uint32x4_t test_vabdl_u16(uint16x4_t a, uint16x4_t b) {
-  // CHECK: test_vabdl_u16
+  // CHECK-LABEL: test_vabdl_u16
   return vabdl_u16(a, b);
-  // CHECK: uabdl {{v[0-31]+}}.4s, {{v[0-31]+}}.4h, {{v[0-31]+}}.4h
+  // CHECK: uabdl {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 uint64x2_t test_vabdl_u32(uint32x2_t a, uint32x2_t b) {
-  // CHECK: test_vabdl_u32
+  // CHECK-LABEL: test_vabdl_u32
   return vabdl_u32(a, b);
-  // CHECK: uabdl {{v[0-31]+}}.2d, {{v[0-31]+}}.2s, {{v[0-31]+}}.2s
+  // CHECK: uabdl {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 int16x8_t test_vabal_s8(int16x8_t a, int8x8_t b, int8x8_t c) {
-  // CHECK: test_vabal_s8
+  // CHECK-LABEL: test_vabal_s8
   return vabal_s8(a, b, c);
-  // CHECK: sabal {{v[0-31]+}}.8h, {{v[0-31]+}}.8b, {{v[0-31]+}}.8b
+  // CHECK: sabal {{v[0-9]+}}.8h, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 int32x4_t test_vabal_s16(int32x4_t a, int16x4_t b, int16x4_t c) {
-  // CHECK: test_vabal_s16
+  // CHECK-LABEL: test_vabal_s16
   return vabal_s16(a, b, c);
-  // CHECK: sabal {{v[0-31]+}}.4s, {{v[0-31]+}}.4h, {{v[0-31]+}}.4h
+  // CHECK: sabal {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 int64x2_t test_vabal_s32(int64x2_t a, int32x2_t b, int32x2_t c) {
-  // CHECK: test_vabal_s32
+  // CHECK-LABEL: test_vabal_s32
   return vabal_s32(a, b, c);
-  // CHECK: sabal {{v[0-31]+}}.2d, {{v[0-31]+}}.2s, {{v[0-31]+}}.2s
+  // CHECK: sabal {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 uint16x8_t test_vabal_u8(uint16x8_t a, uint8x8_t b, uint8x8_t c) {
-  // CHECK: test_vabal_u8
+  // CHECK-LABEL: test_vabal_u8
   return vabal_u8(a, b, c);
-  // CHECK: uabal {{v[0-31]+}}.8h, {{v[0-31]+}}.8b, {{v[0-31]+}}.8b
+  // CHECK: uabal {{v[0-9]+}}.8h, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 uint32x4_t test_vabal_u16(uint32x4_t a, uint16x4_t b, uint16x4_t c) {
-  // CHECK: test_vabal_u16
+  // CHECK-LABEL: test_vabal_u16
   return vabal_u16(a, b, c);
-  // CHECK: uabal {{v[0-31]+}}.4s, {{v[0-31]+}}.4h, {{v[0-31]+}}.4h
+  // CHECK: uabal {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 uint64x2_t test_vabal_u32(uint64x2_t a, uint32x2_t b, uint32x2_t c) {
-  // CHECK: test_vabal_u32
+  // CHECK-LABEL: test_vabal_u32
   return vabal_u32(a, b, c);
-  // CHECK: uabal {{v[0-31]+}}.2d, {{v[0-31]+}}.2s, {{v[0-31]+}}.2s
+  // CHECK: uabal {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 int16x8_t test_vabdl_high_s8(int8x16_t a, int8x16_t b) {
-  // CHECK: test_vabdl_high_s8
+  // CHECK-LABEL: test_vabdl_high_s8
   return vabdl_high_s8(a, b);
-  // CHECK: sabdl2 {{v[0-31]+}}.8h, {{v[0-31]+}}.16b, {{v[0-31]+}}.16b
+  // CHECK: sabdl2 {{v[0-9]+}}.8h, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 int32x4_t test_vabdl_high_s16(int16x8_t a, int16x8_t b) {
-  // CHECK: test_vabdl_high_s16
+  // CHECK-LABEL: test_vabdl_high_s16
   return vabdl_high_s16(a, b);
-  // CHECK: sabdl2 {{v[0-31]+}}.4s, {{v[0-31]+}}.8h, {{v[0-31]+}}.8h
+  // CHECK: sabdl2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 int64x2_t test_vabdl_high_s32(int32x4_t a, int32x4_t b) {
-  // CHECK: test_vabdl_high_s32
+  // CHECK-LABEL: test_vabdl_high_s32
   return vabdl_high_s32(a, b);
-  // CHECK: sabdl2 {{v[0-31]+}}.2d, {{v[0-31]+}}.4s, {{v[0-31]+}}.4s
+  // CHECK: sabdl2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 uint16x8_t test_vabdl_high_u8(uint8x16_t a, uint8x16_t b) {
-  // CHECK: test_vabdl_high_u8
+  // CHECK-LABEL: test_vabdl_high_u8
   return vabdl_high_u8(a, b);
-  // CHECK: uabdl2 {{v[0-31]+}}.8h, {{v[0-31]+}}.16b, {{v[0-31]+}}.16b
+  // CHECK: uabdl2 {{v[0-9]+}}.8h, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 uint32x4_t test_vabdl_high_u16(uint16x8_t a, uint16x8_t b) {
-  // CHECK: test_vabdl_high_u16
+  // CHECK-LABEL: test_vabdl_high_u16
   return vabdl_high_u16(a, b);
-  // CHECK: uabdl2 {{v[0-31]+}}.4s, {{v[0-31]+}}.8h, {{v[0-31]+}}.8h
+  // CHECK: uabdl2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 uint64x2_t test_vabdl_high_u32(uint32x4_t a, uint32x4_t b) {
-  // CHECK: test_vabdl_high_u32
+  // CHECK-LABEL: test_vabdl_high_u32
   return vabdl_high_u32(a, b);
-  // CHECK: uabdl2 {{v[0-31]+}}.2d, {{v[0-31]+}}.4s, {{v[0-31]+}}.4s
+  // CHECK: uabdl2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 int16x8_t test_vabal_high_s8(int16x8_t a, int8x16_t b, int8x16_t c) {
-  // CHECK: test_vabal_high_s8
+  // CHECK-LABEL: test_vabal_high_s8
   return vabal_high_s8(a, b, c);
-  // CHECK: sabal2 {{v[0-31]+}}.8h, {{v[0-31]+}}.16b, {{v[0-31]+}}.16b
+  // CHECK: sabal2 {{v[0-9]+}}.8h, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 int32x4_t test_vabal_high_s16(int32x4_t a, int16x8_t b, int16x8_t c) {
-  // CHECK: test_vabal_high_s16
+  // CHECK-LABEL: test_vabal_high_s16
   return vabal_high_s16(a, b, c);
-  // CHECK: sabal2 {{v[0-31]+}}.4s, {{v[0-31]+}}.8h, {{v[0-31]+}}.8h
+  // CHECK: sabal2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 int64x2_t test_vabal_high_s32(int64x2_t a, int32x4_t b, int32x4_t c) {
-  // CHECK: test_vabal_high_s32
+  // CHECK-LABEL: test_vabal_high_s32
   return vabal_high_s32(a, b, c);
-  // CHECK: sabal2 {{v[0-31]+}}.2d, {{v[0-31]+}}.4s, {{v[0-31]+}}.4s
+  // CHECK: sabal2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 uint16x8_t test_vabal_high_u8(uint16x8_t a, uint8x16_t b, uint8x16_t c) {
-  // CHECK: test_vabal_high_u8
+  // CHECK-LABEL: test_vabal_high_u8
   return vabal_high_u8(a, b, c);
-  // CHECK: uabal2 {{v[0-31]+}}.8h, {{v[0-31]+}}.16b, {{v[0-31]+}}.16b
+  // CHECK: uabal2 {{v[0-9]+}}.8h, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 uint32x4_t test_vabal_high_u16(uint32x4_t a, uint16x8_t b, uint16x8_t c) {
-  // CHECK: test_vabal_high_u16
+  // CHECK-LABEL: test_vabal_high_u16
   return vabal_high_u16(a, b, c);
-  // CHECK: uabal2 {{v[0-31]+}}.4s, {{v[0-31]+}}.8h, {{v[0-31]+}}.8h
+  // CHECK: uabal2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 uint64x2_t test_vabal_high_u32(uint64x2_t a, uint32x4_t b, uint32x4_t c) {
-  // CHECK: test_vabal_high_u32
+  // CHECK-LABEL: test_vabal_high_u32
   return vabal_high_u32(a, b, c);
-  // CHECK: uabal2 {{v[0-31]+}}.2d, {{v[0-31]+}}.4s, {{v[0-31]+}}.4s
+  // CHECK: uabal2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 int16x8_t test_vmull_s8(int8x8_t a, int8x8_t b) {
-  // CHECK: test_vmull_s8
+  // CHECK-LABEL: test_vmull_s8
   return vmull_s8(a, b);
-  // CHECK: smull {{v[0-31]+}}.8h, {{v[0-31]+}}.8b, {{v[0-31]+}}.8b
+  // CHECK: smull {{v[0-9]+}}.8h, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 int32x4_t test_vmull_s16(int16x4_t a, int16x4_t b) {
-  // CHECK: test_vmull_s16
+  // CHECK-LABEL: test_vmull_s16
   return vmull_s16(a, b);
-  // CHECK: smull {{v[0-31]+}}.4s, {{v[0-31]+}}.4h, {{v[0-31]+}}.4h
+  // CHECK: smull {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 int64x2_t test_vmull_s32(int32x2_t a, int32x2_t b) {
-  // CHECK: test_vmull_s32
+  // CHECK-LABEL: test_vmull_s32
   return vmull_s32(a, b);
-  // CHECK: smull {{v[0-31]+}}.2d, {{v[0-31]+}}.2s, {{v[0-31]+}}.2s
+  // CHECK: smull {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 uint16x8_t test_vmull_u8(uint8x8_t a, uint8x8_t b) {
-  // CHECK: test_vmull_u8
+  // CHECK-LABEL: test_vmull_u8
   return vmull_u8(a, b);
-  // CHECK: umull {{v[0-31]+}}.8h, {{v[0-31]+}}.8b, {{v[0-31]+}}.8b
+  // CHECK: umull {{v[0-9]+}}.8h, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 uint32x4_t test_vmull_u16(uint16x4_t a, uint16x4_t b) {
-  // CHECK: test_vmull_u16
+  // CHECK-LABEL: test_vmull_u16
   return vmull_u16(a, b);
-  // CHECK: umull {{v[0-31]+}}.4s, {{v[0-31]+}}.4h, {{v[0-31]+}}.4h
+  // CHECK: umull {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 uint64x2_t test_vmull_u32(uint32x2_t a, uint32x2_t b) {
-  // CHECK: test_vmull_u32
+  // CHECK-LABEL: test_vmull_u32
   return vmull_u32(a, b);
-  // CHECK: umull {{v[0-31]+}}.2d, {{v[0-31]+}}.2s, {{v[0-31]+}}.2s
+  // CHECK: umull {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 int16x8_t test_vmull_high_s8(int8x16_t a, int8x16_t b) {
-  // CHECK: test_vmull_high_s8
+  // CHECK-LABEL: test_vmull_high_s8
   return vmull_high_s8(a, b);
-  // CHECK: smull2 {{v[0-31]+}}.8h, {{v[0-31]+}}.16b, {{v[0-31]+}}.16b
+  // CHECK: smull2 {{v[0-9]+}}.8h, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 int32x4_t test_vmull_high_s16(int16x8_t a, int16x8_t b) {
-  // CHECK: test_vmull_high_s16
+  // CHECK-LABEL: test_vmull_high_s16
   return vmull_high_s16(a, b);
-  // CHECK: smull2 {{v[0-31]+}}.4s, {{v[0-31]+}}.8h, {{v[0-31]+}}.8h
+  // CHECK: smull2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 int64x2_t test_vmull_high_s32(int32x4_t a, int32x4_t b) {
-  // CHECK: test_vmull_high_s32
+  // CHECK-LABEL: test_vmull_high_s32
   return vmull_high_s32(a, b);
-  // CHECK: smull2 {{v[0-31]+}}.2d, {{v[0-31]+}}.4s, {{v[0-31]+}}.4s
+  // CHECK: smull2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 uint16x8_t test_vmull_high_u8(uint8x16_t a, uint8x16_t b) {
-  // CHECK: test_vmull_high_u8
+  // CHECK-LABEL: test_vmull_high_u8
   return vmull_high_u8(a, b);
-  // CHECK: umull2 {{v[0-31]+}}.8h, {{v[0-31]+}}.16b, {{v[0-31]+}}.16b
+  // CHECK: umull2 {{v[0-9]+}}.8h, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 uint32x4_t test_vmull_high_u16(uint16x8_t a, uint16x8_t b) {
-  // CHECK: test_vmull_high_u16
+  // CHECK-LABEL: test_vmull_high_u16
   return vmull_high_u16(a, b);
-  // CHECK: umull2 {{v[0-31]+}}.4s, {{v[0-31]+}}.8h, {{v[0-31]+}}.8h
+  // CHECK: umull2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 uint64x2_t test_vmull_high_u32(uint32x4_t a, uint32x4_t b) {
-  // CHECK: test_vmull_high_u32
+  // CHECK-LABEL: test_vmull_high_u32
   return vmull_high_u32(a, b);
-  // CHECK: umull2 {{v[0-31]+}}.2d, {{v[0-31]+}}.4s, {{v[0-31]+}}.4s
+  // CHECK: umull2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 int16x8_t test_vmlal_s8(int16x8_t a, int8x8_t b, int8x8_t c) {
-  // CHECK: test_vmlal_s8
+  // CHECK-LABEL: test_vmlal_s8
   return vmlal_s8(a, b, c);
-  // CHECK: smlal {{v[0-31]+}}.8h, {{v[0-31]+}}.8b, {{v[0-31]+}}.8b
+  // CHECK: smlal {{v[0-9]+}}.8h, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 int32x4_t test_vmlal_s16(int32x4_t a, int16x4_t b, int16x4_t c) {
-  // CHECK: test_vmlal_s16
+  // CHECK-LABEL: test_vmlal_s16
   return vmlal_s16(a, b, c);
-  // CHECK: smlal {{v[0-31]+}}.4s, {{v[0-31]+}}.4h, {{v[0-31]+}}.4h
+  // CHECK: smlal {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 int64x2_t test_vmlal_s32(int64x2_t a, int32x2_t b, int32x2_t c) {
-  // CHECK: test_vmlal_s32
+  // CHECK-LABEL: test_vmlal_s32
   return vmlal_s32(a, b, c);
-  // CHECK: smlal {{v[0-31]+}}.2d, {{v[0-31]+}}.2s, {{v[0-31]+}}.2s
+  // CHECK: smlal {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 uint16x8_t test_vmlal_u8(uint16x8_t a, uint8x8_t b, uint8x8_t c) {
-  // CHECK: test_vmlal_u8
+  // CHECK-LABEL: test_vmlal_u8
   return vmlal_u8(a, b, c);
-  // CHECK: umlal {{v[0-31]+}}.8h, {{v[0-31]+}}.8b, {{v[0-31]+}}.8b
+  // CHECK: umlal {{v[0-9]+}}.8h, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 uint32x4_t test_vmlal_u16(uint32x4_t a, uint16x4_t b, uint16x4_t c) {
-  // CHECK: test_vmlal_u16
+  // CHECK-LABEL: test_vmlal_u16
   return vmlal_u16(a, b, c);
-  // CHECK: umlal {{v[0-31]+}}.4s, {{v[0-31]+}}.4h, {{v[0-31]+}}.4h
+  // CHECK: umlal {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 uint64x2_t test_vmlal_u32(uint64x2_t a, uint32x2_t b, uint32x2_t c) {
-  // CHECK: test_vmlal_u32
+  // CHECK-LABEL: test_vmlal_u32
   return vmlal_u32(a, b, c);
-  // CHECK: umlal {{v[0-31]+}}.2d, {{v[0-31]+}}.2s, {{v[0-31]+}}.2s
+  // CHECK: umlal {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 int16x8_t test_vmlal_high_s8(int16x8_t a, int8x16_t b, int8x16_t c) {
-  // CHECK: test_vmlal_high_s8
+  // CHECK-LABEL: test_vmlal_high_s8
   return vmlal_high_s8(a, b, c);
-  // CHECK: smlal2 {{v[0-31]+}}.8h, {{v[0-31]+}}.16b, {{v[0-31]+}}.16b
+  // CHECK: smlal2 {{v[0-9]+}}.8h, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 int32x4_t test_vmlal_high_s16(int32x4_t a, int16x8_t b, int16x8_t c) {
-  // CHECK: test_vmlal_high_s16
+  // CHECK-LABEL: test_vmlal_high_s16
   return vmlal_high_s16(a, b, c);
-  // CHECK: smlal2 {{v[0-31]+}}.4s, {{v[0-31]+}}.8h, {{v[0-31]+}}.8h
+  // CHECK: smlal2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 int64x2_t test_vmlal_high_s32(int64x2_t a, int32x4_t b, int32x4_t c) {
-  // CHECK: test_vmlal_high_s32
+  // CHECK-LABEL: test_vmlal_high_s32
   return vmlal_high_s32(a, b, c);
-  // CHECK: smlal2 {{v[0-31]+}}.2d, {{v[0-31]+}}.4s, {{v[0-31]+}}.4s
+  // CHECK: smlal2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 uint16x8_t test_vmlal_high_u8(uint16x8_t a, uint8x16_t b, uint8x16_t c) {
-  // CHECK: test_vmlal_high_u8
+  // CHECK-LABEL: test_vmlal_high_u8
   return vmlal_high_u8(a, b, c);
-  // CHECK: umlal2 {{v[0-31]+}}.8h, {{v[0-31]+}}.16b, {{v[0-31]+}}.16b
+  // CHECK: umlal2 {{v[0-9]+}}.8h, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 uint32x4_t test_vmlal_high_u16(uint32x4_t a, uint16x8_t b, uint16x8_t c) {
-  // CHECK: test_vmlal_high_u16
+  // CHECK-LABEL: test_vmlal_high_u16
   return vmlal_high_u16(a, b, c);
-  // CHECK: umlal2 {{v[0-31]+}}.4s, {{v[0-31]+}}.8h, {{v[0-31]+}}.8h
+  // CHECK: umlal2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 uint64x2_t test_vmlal_high_u32(uint64x2_t a, uint32x4_t b, uint32x4_t c) {
-  // CHECK: test_vmlal_high_u32
+  // CHECK-LABEL: test_vmlal_high_u32
   return vmlal_high_u32(a, b, c);
-  // CHECK: umlal2 {{v[0-31]+}}.2d, {{v[0-31]+}}.4s, {{v[0-31]+}}.4s
+  // CHECK: umlal2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 int16x8_t test_vmlsl_s8(int16x8_t a, int8x8_t b, int8x8_t c) {
-  // CHECK: test_vmlsl_s8
+  // CHECK-LABEL: test_vmlsl_s8
   return vmlsl_s8(a, b, c);
-  // CHECK: smlsl {{v[0-31]+}}.8h, {{v[0-31]+}}.8b, {{v[0-31]+}}.8b
+  // CHECK: smlsl {{v[0-9]+}}.8h, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 int32x4_t test_vmlsl_s16(int32x4_t a, int16x4_t b, int16x4_t c) {
-  // CHECK: test_vmlsl_s16
+  // CHECK-LABEL: test_vmlsl_s16
   return vmlsl_s16(a, b, c);
-  // CHECK: smlsl {{v[0-31]+}}.4s, {{v[0-31]+}}.4h, {{v[0-31]+}}.4h
+  // CHECK: smlsl {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 int64x2_t test_vmlsl_s32(int64x2_t a, int32x2_t b, int32x2_t c) {
-  // CHECK: test_vmlsl_s32
+  // CHECK-LABEL: test_vmlsl_s32
   return vmlsl_s32(a, b, c);
-  // CHECK: smlsl {{v[0-31]+}}.2d, {{v[0-31]+}}.2s, {{v[0-31]+}}.2s
+  // CHECK: smlsl {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 uint16x8_t test_vmlsl_u8(uint16x8_t a, uint8x8_t b, uint8x8_t c) {
-  // CHECK: test_vmlsl_u8
+  // CHECK-LABEL: test_vmlsl_u8
   return vmlsl_u8(a, b, c);
-  // CHECK: umlsl {{v[0-31]+}}.8h, {{v[0-31]+}}.8b, {{v[0-31]+}}.8b
+  // CHECK: umlsl {{v[0-9]+}}.8h, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 uint32x4_t test_vmlsl_u16(uint32x4_t a, uint16x4_t b, uint16x4_t c) {
-  // CHECK: test_vmlsl_u16
+  // CHECK-LABEL: test_vmlsl_u16
   return vmlsl_u16(a, b, c);
-  // CHECK: umlsl {{v[0-31]+}}.4s, {{v[0-31]+}}.4h, {{v[0-31]+}}.4h
+  // CHECK: umlsl {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 uint64x2_t test_vmlsl_u32(uint64x2_t a, uint32x2_t b, uint32x2_t c) {
-  // CHECK: test_vmlsl_u32
+  // CHECK-LABEL: test_vmlsl_u32
   return vmlsl_u32(a, b, c);
-  // CHECK: umlsl {{v[0-31]+}}.2d, {{v[0-31]+}}.2s, {{v[0-31]+}}.2s
+  // CHECK: umlsl {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 int16x8_t test_vmlsl_high_s8(int16x8_t a, int8x16_t b, int8x16_t c) {
-  // CHECK: test_vmlsl_high_s8
+  // CHECK-LABEL: test_vmlsl_high_s8
   return vmlsl_high_s8(a, b, c);
-  // CHECK: smlsl2 {{v[0-31]+}}.8h, {{v[0-31]+}}.16b, {{v[0-31]+}}.16b
+  // CHECK: smlsl2 {{v[0-9]+}}.8h, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 int32x4_t test_vmlsl_high_s16(int32x4_t a, int16x8_t b, int16x8_t c) {
-  // CHECK: test_vmlsl_high_s16
+  // CHECK-LABEL: test_vmlsl_high_s16
   return vmlsl_high_s16(a, b, c);
-  // CHECK: smlsl2 {{v[0-31]+}}.4s, {{v[0-31]+}}.8h, {{v[0-31]+}}.8h
+  // CHECK: smlsl2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 int64x2_t test_vmlsl_high_s32(int64x2_t a, int32x4_t b, int32x4_t c) {
-  // CHECK: test_vmlsl_high_s32
+  // CHECK-LABEL: test_vmlsl_high_s32
   return vmlsl_high_s32(a, b, c);
-  // CHECK: smlsl2 {{v[0-31]+}}.2d, {{v[0-31]+}}.4s, {{v[0-31]+}}.4s
+  // CHECK: smlsl2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 uint16x8_t test_vmlsl_high_u8(uint16x8_t a, uint8x16_t b, uint8x16_t c) {
-  // CHECK: test_vmlsl_high_u8
+  // CHECK-LABEL: test_vmlsl_high_u8
   return vmlsl_high_u8(a, b, c);
-  // CHECK: umlsl2 {{v[0-31]+}}.8h, {{v[0-31]+}}.16b, {{v[0-31]+}}.16b
+  // CHECK: umlsl2 {{v[0-9]+}}.8h, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 uint32x4_t test_vmlsl_high_u16(uint32x4_t a, uint16x8_t b, uint16x8_t c) {
-  // CHECK: test_vmlsl_high_u16
+  // CHECK-LABEL: test_vmlsl_high_u16
   return vmlsl_high_u16(a, b, c);
-  // CHECK: umlsl2 {{v[0-31]+}}.4s, {{v[0-31]+}}.8h, {{v[0-31]+}}.8h
+  // CHECK: umlsl2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 uint64x2_t test_vmlsl_high_u32(uint64x2_t a, uint32x4_t b, uint32x4_t c) {
-  // CHECK: test_vmlsl_high_u32
+  // CHECK-LABEL: test_vmlsl_high_u32
   return vmlsl_high_u32(a, b, c);
-  // CHECK: umlsl2 {{v[0-31]+}}.2d, {{v[0-31]+}}.4s, {{v[0-31]+}}.4s
+  // CHECK: umlsl2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 int32x4_t test_vqdmull_s16(int16x4_t a, int16x4_t b) {
-  // CHECK: test_vqdmull_s16
+  // CHECK-LABEL: test_vqdmull_s16
   return vqdmull_s16(a, b);
-  // CHECK: sqdmull {{v[0-31]+}}.4s, {{v[0-31]+}}.4h, {{v[0-31]+}}.4h
+  // CHECK: sqdmull {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 int64x2_t test_vqdmull_s32(int32x2_t a, int32x2_t b) {
-  // CHECK: test_vqdmull_s32
+  // CHECK-LABEL: test_vqdmull_s32
   return vqdmull_s32(a, b);
-  // CHECK: sqdmull {{v[0-31]+}}.2d, {{v[0-31]+}}.2s, {{v[0-31]+}}.2s
+  // CHECK: sqdmull {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 int32x4_t test_vqdmlal_s16(int32x4_t a, int16x4_t b, int16x4_t c) {
-  // CHECK: test_vqdmlal_s16
+  // CHECK-LABEL: test_vqdmlal_s16
   return vqdmlal_s16(a, b, c);
-  // CHECK: sqdmlal {{v[0-31]+}}.4s, {{v[0-31]+}}.4h, {{v[0-31]+}}.4h
+  // CHECK: sqdmlal {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 int64x2_t test_vqdmlal_s32(int64x2_t a, int32x2_t b, int32x2_t c) {
-  // CHECK: test_vqdmlal_s32
+  // CHECK-LABEL: test_vqdmlal_s32
   return vqdmlal_s32(a, b, c);
-  // CHECK: sqdmlal {{v[0-31]+}}.2d, {{v[0-31]+}}.2s, {{v[0-31]+}}.2s
+  // CHECK: sqdmlal {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 int32x4_t test_vqdmlsl_s16(int32x4_t a, int16x4_t b, int16x4_t c) {
-  // CHECK: test_vqdmlsl_s16
+  // CHECK-LABEL: test_vqdmlsl_s16
   return vqdmlsl_s16(a, b, c);
-  // CHECK: sqdmlsl {{v[0-31]+}}.4s, {{v[0-31]+}}.4h, {{v[0-31]+}}.4h
+  // CHECK: sqdmlsl {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 int64x2_t test_vqdmlsl_s32(int64x2_t a, int32x2_t b, int32x2_t c) {
-  // CHECK: test_vqdmlsl_s32
+  // CHECK-LABEL: test_vqdmlsl_s32
   return vqdmlsl_s32(a, b, c);
-  // CHECK: sqdmlsl {{v[0-31]+}}.2d, {{v[0-31]+}}.2s, {{v[0-31]+}}.2s
+  // CHECK: sqdmlsl {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
 }
 
 int32x4_t test_vqdmull_high_s16(int16x8_t a, int16x8_t b) {
-  // CHECK: test_vqdmull_high_s16
+  // CHECK-LABEL: test_vqdmull_high_s16
   return vqdmull_high_s16(a, b);
-  // CHECK: sqdmull2 {{v[0-31]+}}.4s, {{v[0-31]+}}.8h, {{v[0-31]+}}.8h
+  // CHECK: sqdmull2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 int64x2_t test_vqdmull_high_s32(int32x4_t a, int32x4_t b) {
-  // CHECK: test_vqdmull_high_s32
+  // CHECK-LABEL: test_vqdmull_high_s32
   return vqdmull_high_s32(a, b);
-  // CHECK: sqdmull2 {{v[0-31]+}}.2d, {{v[0-31]+}}.4s, {{v[0-31]+}}.4s
+  // CHECK: sqdmull2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 int32x4_t test_vqdmlal_high_s16(int32x4_t a, int16x8_t b, int16x8_t c) {
-  // CHECK: test_vqdmlal_high_s16
+  // CHECK-LABEL: test_vqdmlal_high_s16
   return vqdmlal_high_s16(a, b, c);
-  // CHECK: sqdmlal2 {{v[0-31]+}}.4s, {{v[0-31]+}}.8h, {{v[0-31]+}}.8h
+  // CHECK: sqdmlal2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int64x2_t test_vqdmlal_high_s32(int64x2_t a, int32x4_t b, int32x4_t c) {
-  // CHECK: test_vqdmlal_high_s32
+  // CHECK-LABEL: test_vqdmlal_high_s32
   return vqdmlal_high_s32(a, b, c);
-  // CHECK: sqdmlal2 {{v[0-31]+}}.2d, {{v[0-31]+}}.4s, {{v[0-31]+}}.4s
+  // CHECK: sqdmlal2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 int32x4_t test_vqdmlsl_high_s16(int32x4_t a, int16x8_t b, int16x8_t c) {
-  // CHECK: test_vqdmlsl_high_s16
+  // CHECK-LABEL: test_vqdmlsl_high_s16
   return vqdmlsl_high_s16(a, b, c);
-  // CHECK: sqdmlsl2 {{v[0-31]+}}.4s, {{v[0-31]+}}.8h, {{v[0-31]+}}.8h
+  // CHECK: sqdmlsl2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int64x2_t test_vqdmlsl_high_s32(int64x2_t a, int32x4_t b, int32x4_t c) {
-  // CHECK: test_vqdmlsl_high_s32
+  // CHECK-LABEL: test_vqdmlsl_high_s32
   return vqdmlsl_high_s32(a, b, c);
-  // CHECK: sqdmlsl2 {{v[0-31]+}}.2d, {{v[0-31]+}}.4s, {{v[0-31]+}}.4s
+  // CHECK: sqdmlsl2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 poly16x8_t test_vmull_p8(poly8x8_t a, poly8x8_t b) {
-  // CHECK: test_vmull_p8
+  // CHECK-LABEL: test_vmull_p8
   return vmull_p8(a, b);
-  // CHECK: pmull {{v[0-31]+}}.8h, {{v[0-31]+}}.8b, {{v[0-31]+}}.8b
+  // CHECK: pmull {{v[0-9]+}}.8h, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 poly16x8_t test_vmull_high_p8(poly8x16_t a, poly8x16_t b) {
-  // CHECK: test_vmull_high_p8
+  // CHECK-LABEL: test_vmull_high_p8
   return vmull_high_p8(a, b);
-  // CHECK: pmull2 {{v[0-31]+}}.8h, {{v[0-31]+}}.16b, {{v[0-31]+}}.16b
+  // CHECK: pmull2 {{v[0-9]+}}.8h, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 int64_t test_vaddd_s64(int64_t a, int64_t b) {
-// CHECK: test_vaddd_s64
+// CHECK-LABEL: test_vaddd_s64
   return vaddd_s64(a, b);
-// CHECK: add {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+// CHECK: add {{[xd][0-9]+}}, {{[xd][0-9]+}}, {{[xd][0-9]+}}
 }
 
 uint64_t test_vaddd_u64(uint64_t a, uint64_t b) {
-// CHECK: test_vaddd_u64
+// CHECK-LABEL: test_vaddd_u64
   return vaddd_u64(a, b);
-// CHECK: add {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+// CHECK: add {{[xd][0-9]+}}, {{[xd][0-9]+}}, {{[xd][0-9]+}}
 }
 
 int64_t test_vsubd_s64(int64_t a, int64_t b) {
-// CHECK: test_vsubd_s64
+// CHECK-LABEL: test_vsubd_s64
   return vsubd_s64(a, b);
-// CHECK: sub {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+// CHECK: sub {{[xd][0-9]+}}, {{[xd][0-9]+}}, {{[xd][0-9]+}}
 }
 
 uint64_t test_vsubd_u64(uint64_t a, uint64_t b) {
-// CHECK: test_vsubd_u64
+// CHECK-LABEL: test_vsubd_u64
   return vsubd_u64(a, b);
-// CHECK: sub {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+// CHECK: sub {{[xd][0-9]+}}, {{[xd][0-9]+}}, {{[xd][0-9]+}}
 }
 
 int8_t test_vqaddb_s8(int8_t a, int8_t b) {
-// CHECK: test_vqaddb_s8
+// CHECK-LABEL: test_vqaddb_s8
   return vqaddb_s8(a, b);
-// CHECK: sqadd {{b[0-9]+}}, {{b[0-9]+}}, {{b[0-9]+}}
+// CHECK: sqadd {{b[0-9]+|v[0-9]+.8b}}, {{b[0-9]+|v[0-9]+.8b}}, {{b[0-9]+|v[0-9]+.8b}}
 }
 
 int16_t test_vqaddh_s16(int16_t a, int16_t b) {
-// CHECK: test_vqaddh_s16
+// CHECK-LABEL: test_vqaddh_s16
   return vqaddh_s16(a, b);
-// CHECK: sqadd {{h[0-9]+}}, {{h[0-9]+}}, {{h[0-9]+}}
+// CHECK: sqadd {{h[0-9]+|v[0-9]+.4h}}, {{h[0-9]+|v[0-9]+.4h}}, {{h[0-9]+|v[0-9]+.4h}}
 }
 
 int32_t test_vqadds_s32(int32_t a, int32_t b) {
-// CHECK: test_vqadds_s32
+// CHECK-LABEL: test_vqadds_s32
   return vqadds_s32(a, b);
 // CHECK: sqadd {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
 }
 
 int64_t test_vqaddd_s64(int64_t a, int64_t b) {
-// CHECK: test_vqaddd_s64
+// CHECK-LABEL: test_vqaddd_s64
   return vqaddd_s64(a, b);
 // CHECK: sqadd {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
 }
 
 uint8_t test_vqaddb_u8(uint8_t a, uint8_t b) {
-// CHECK: test_vqaddb_u8
+// CHECK-LABEL: test_vqaddb_u8
   return vqaddb_u8(a, b);
-// CHECK: uqadd {{b[0-9]+}}, {{b[0-9]+}}, {{b[0-9]+}}
+// CHECK: uqadd {{b[0-9]+|v[0-9]+.8b}}, {{b[0-9]+|v[0-9]+.8b}}, {{b[0-9]+|v[0-9]+.8b}}
 }
 
 uint16_t test_vqaddh_u16(uint16_t a, uint16_t b) {
-// CHECK: test_vqaddh_u16
+// CHECK-LABEL: test_vqaddh_u16
   return vqaddh_u16(a, b);
-// CHECK: uqadd {{h[0-9]+}}, {{h[0-9]+}}, {{h[0-9]+}}
+// CHECK: uqadd {{h[0-9]+|v[0-9]+.4h}}, {{h[0-9]+|v[0-9]+.4h}}, {{h[0-9]+|v[0-9]+.4h}}
 }
 
 uint32_t test_vqadds_u32(uint32_t a, uint32_t b) {
-// CHECK: test_vqadds_u32
+// CHECK-LABEL: test_vqadds_u32
   return vqadds_u32(a, b);
 // CHECK: uqadd {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
 }
 
 uint64_t test_vqaddd_u64(uint64_t a, uint64_t b) {
-// CHECK: test_vqaddd_u64
+// CHECK-LABEL: test_vqaddd_u64
   return vqaddd_u64(a, b);
 // CHECK: uqadd {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
 }
 
 int8_t test_vqsubb_s8(int8_t a, int8_t b) {
-// CHECK: test_vqsubb_s8
+// CHECK-LABEL: test_vqsubb_s8
   return vqsubb_s8(a, b);
-// CHECK: sqsub {{b[0-9]+}}, {{b[0-9]+}}, {{b[0-9]+}}
+// CHECK: sqsub {{b[0-9]+|v[0-9]+.8b}}, {{b[0-9]+|v[0-9]+.8b}}, {{b[0-9]+|v[0-9]+.8b}}
 }
 
 int16_t test_vqsubh_s16(int16_t a, int16_t b) {
-// CHECK: test_vqsubh_s16
+// CHECK-LABEL: test_vqsubh_s16
   return vqsubh_s16(a, b);
-// CHECK: sqsub {{h[0-9]+}}, {{h[0-9]+}}, {{h[0-9]+}}
+// CHECK: sqsub {{h[0-9]+|v[0-9]+.4h}}, {{h[0-9]+|v[0-9]+.4h}}, {{h[0-9]+|v[0-9]+.4h}}
 }
 
 int32_t test_vqsubs_s32(int32_t a, int32_t b) {
-  // CHECK: test_vqsubs_s32
+  // CHECK-LABEL: test_vqsubs_s32
   return vqsubs_s32(a, b);
 // CHECK: sqsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
 }
 
 int64_t test_vqsubd_s64(int64_t a, int64_t b) {
-// CHECK: test_vqsubd_s64
+// CHECK-LABEL: test_vqsubd_s64
   return vqsubd_s64(a, b);
 // CHECK: sqsub {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
 }
 
 uint8_t test_vqsubb_u8(uint8_t a, uint8_t b) {
-// CHECK: test_vqsubb_u8
+// CHECK-LABEL: test_vqsubb_u8
   return vqsubb_u8(a, b);
-// CHECK: uqsub {{b[0-9]+}}, {{b[0-9]+}}, {{b[0-9]+}}
+// CHECK: uqsub {{b[0-9]+|v[0-9]+.8b}}, {{b[0-9]+|v[0-9]+.8b}}, {{b[0-9]+|v[0-9]+.8b}}
 }
 
 uint16_t test_vqsubh_u16(uint16_t a, uint16_t b) {
-// CHECK: test_vqsubh_u16
+// CHECK-LABEL: test_vqsubh_u16
   return vqsubh_u16(a, b);
-// CHECK: uqsub {{h[0-9]+}}, {{h[0-9]+}}, {{h[0-9]+}}
+// CHECK: uqsub {{h[0-9]+|v[0-9]+.4h}}, {{h[0-9]+|v[0-9]+.4h}}, {{h[0-9]+|v[0-9]+.4h}}
 }
 
 uint32_t test_vqsubs_u32(uint32_t a, uint32_t b) {
-// CHECK: test_vqsubs_u32
+// CHECK-LABEL: test_vqsubs_u32
   return vqsubs_u32(a, b);
 // CHECK: uqsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
 }
 
 uint64_t test_vqsubd_u64(uint64_t a, uint64_t b) {
-// CHECK: test_vqsubd_u64
+// CHECK-LABEL: test_vqsubd_u64
   return vqsubd_u64(a, b);
 // CHECK: uqsub {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
 }
 
 int64_t test_vshld_s64(int64_t a, int64_t b) {
-// CHECK: test_vshld_s64
+// CHECK-LABEL: test_vshld_s64
   return vshld_s64(a, b);
 // CHECK: sshl {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
 }
 
 uint64_t test_vshld_u64(uint64_t a, uint64_t b) {
-// CHECK: test_vshld_u64
+// CHECK-LABEL: test_vshld_u64
   return vshld_u64(a, b);
 // CHECK: ushl {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
 }
 
-// CHECK: test_vqshlb_s8
+// CHECK-LABEL: test_vqshlb_s8
 int8_t test_vqshlb_s8(int8_t a, int8_t b) {
   return vqshlb_s8(a, b);
-// CHECK: sqshl {{b[0-9]+}}, {{b[0-9]+}}, {{b[0-9]+}}
+// CHECK: sqshl {{b[0-9]+|v[0-9]+.8b}}, {{b[0-9]+|v[0-9]+.8b}}, {{b[0-9]+|v[0-9]+.8b}}
 }
 
-// CHECK: test_vqshlh_s16
+// CHECK-LABEL: test_vqshlh_s16
 int16_t test_vqshlh_s16(int16_t a, int16_t b) {
   return vqshlh_s16(a, b);
-// CHECK: sqshl {{h[0-9]+}}, {{h[0-9]+}}, {{h[0-9]+}}
+// CHECK: sqshl {{h[0-9]+|v[0-9]+.4h}}, {{h[0-9]+|v[0-9]+.4h}}, {{h[0-9]+|v[0-9]+.4h}}
 }
 
-// CHECK: test_vqshls_s32
+// CHECK-LABEL: test_vqshls_s32
 int32_t test_vqshls_s32(int32_t a, int32_t b) {
   return vqshls_s32(a, b);
 // CHECK: sqshl {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
 }
 
-// CHECK: test_vqshld_s64
+// CHECK-LABEL: test_vqshld_s64
 int64_t test_vqshld_s64(int64_t a, int64_t b) {
   return vqshld_s64(a, b);
 // CHECK: sqshl {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
 }
 
-// CHECK: test_vqshlb_u8
+// CHECK-LABEL: test_vqshlb_u8
 uint8_t test_vqshlb_u8(uint8_t a, uint8_t b) {
   return vqshlb_u8(a, b);
-// CHECK: uqshl {{b[0-9]+}}, {{b[0-9]+}}, {{b[0-9]+}}
+// CHECK: uqshl {{b[0-9]+|v[0-9]+.8b}}, {{b[0-9]+|v[0-9]+.8b}}, {{b[0-9]+|v[0-9]+.8b}}
 }
 
-// CHECK: test_vqshlh_u16
+// CHECK-LABEL: test_vqshlh_u16
 uint16_t test_vqshlh_u16(uint16_t a, uint16_t b) {
   return vqshlh_u16(a, b);
-// CHECK: uqshl {{h[0-9]+}}, {{h[0-9]+}}, {{h[0-9]+}}
+// CHECK: uqshl {{h[0-9]+|v[0-9]+.4h}}, {{h[0-9]+|v[0-9]+.4h}}, {{h[0-9]+|v[0-9]+.4h}}
 }
 
-// CHECK: test_vqshls_u32
+// CHECK-LABEL: test_vqshls_u32
 uint32_t test_vqshls_u32(uint32_t a, uint32_t b) {
   return vqshls_u32(a, b);
 // CHECK: uqshl {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
 }
 
-// CHECK: test_vqshld_u64
+// CHECK-LABEL: test_vqshld_u64
 uint64_t test_vqshld_u64(uint64_t a, uint64_t b) {
   return vqshld_u64(a, b);
 // CHECK: uqshl {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
 }
 
-// CHECK: test_vrshld_s64
+// CHECK-LABEL: test_vrshld_s64
 int64_t test_vrshld_s64(int64_t a, int64_t b) {
   return vrshld_s64(a, b);
 // CHECK: srshl {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
 }
 
 
-// CHECK: test_vrshld_u64
+// CHECK-LABEL: test_vrshld_u64
 uint64_t test_vrshld_u64(uint64_t a, uint64_t b) {
   return vrshld_u64(a, b);
 // CHECK: urshl {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
 }
 
-// CHECK: test_vqrshlb_s8
+// CHECK-LABEL: test_vqrshlb_s8
 int8_t test_vqrshlb_s8(int8_t a, int8_t b) {
   return vqrshlb_s8(a, b);
-// CHECK: sqrshl {{b[0-9]+}}, {{b[0-9]+}}, {{b[0-9]+}}
+// CHECK: sqrshl {{b[0-9]+|v[0-9]+.8b}}, {{b[0-9]+|v[0-9]+.8b}}, {{b[0-9]+|v[0-9]+.8b}}
 }
 
-// CHECK: test_vqrshlh_s16
+// CHECK-LABEL: test_vqrshlh_s16
 int16_t test_vqrshlh_s16(int16_t a, int16_t b) {
   return vqrshlh_s16(a, b);
-// CHECK: sqrshl {{h[0-9]+}}, {{h[0-9]+}}, {{h[0-9]+}}
+// CHECK: sqrshl {{h[0-9]+|v[0-9]+.4h}}, {{h[0-9]+|v[0-9]+.4h}}, {{h[0-9]+|v[0-9]+.4h}}
 }
 
-// CHECK: test_vqrshls_s32
+// CHECK-LABEL: test_vqrshls_s32
 int32_t test_vqrshls_s32(int32_t a, int32_t b) {
   return vqrshls_s32(a, b);
 // CHECK: sqrshl {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
 }
 
-// CHECK: test_vqrshld_s64
+// CHECK-LABEL: test_vqrshld_s64
 int64_t test_vqrshld_s64(int64_t a, int64_t b) {
   return vqrshld_s64(a, b);
 // CHECK: sqrshl {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
 }
 
-// CHECK: test_vqrshlb_u8
+// CHECK-LABEL: test_vqrshlb_u8
 uint8_t test_vqrshlb_u8(uint8_t a, uint8_t b) {
   return vqrshlb_u8(a, b);
-// CHECK: uqrshl {{b[0-9]+}}, {{b[0-9]+}}, {{b[0-9]+}}
+// CHECK: uqrshl {{b[0-9]+|v[0-9]+.8b}}, {{b[0-9]+|v[0-9]+.8b}}, {{b[0-9]+|v[0-9]+.8b}}
 }
 
-// CHECK: test_vqrshlh_u16
+// CHECK-LABEL: test_vqrshlh_u16
 uint16_t test_vqrshlh_u16(uint16_t a, uint16_t b) {
   return vqrshlh_u16(a, b);
-// CHECK: uqrshl {{h[0-9]+}}, {{h[0-9]+}}, {{h[0-9]+}}
+// CHECK: uqrshl {{h[0-9]+|v[0-9]+.4h}}, {{h[0-9]+|v[0-9]+.4h}}, {{h[0-9]+|v[0-9]+.4h}}
 }
 
-// CHECK: test_vqrshls_u32
+// CHECK-LABEL: test_vqrshls_u32
 uint32_t test_vqrshls_u32(uint32_t a, uint32_t b) {
   return vqrshls_u32(a, b);
 // CHECK: uqrshl {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
 }
 
-// CHECK: test_vqrshld_u64
+// CHECK-LABEL: test_vqrshld_u64
 uint64_t test_vqrshld_u64(uint64_t a, uint64_t b) {
   return vqrshld_u64(a, b);
 // CHECK: uqrshl {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
 }
 
-// CHECK: test_vpaddd_s64
+// CHECK-LABEL: test_vpaddd_s64
 int64_t test_vpaddd_s64(int64x2_t a) {
   return vpaddd_s64(a);
 // CHECK: addp {{d[0-9]+}}, {{v[0-9]+}}.2d
 }
 
-// CHECK: test_vpadds_f32
+// CHECK-LABEL: test_vpadds_f32
 float32_t test_vpadds_f32(float32x2_t a) {
   return vpadds_f32(a);
 // CHECK: faddp {{s[0-9]+}}, {{v[0-9]+}}.2s
 }
 
-// CHECK: test_vpaddd_f64
+// CHECK-LABEL: test_vpaddd_f64
 float64_t test_vpaddd_f64(float64x2_t a) {
   return vpaddd_f64(a);
 // CHECK: faddp {{d[0-9]+}}, {{v[0-9]+}}.2d
 }
 
-// CHECK: test_vpmaxnms_f32
+// CHECK-LABEL: test_vpmaxnms_f32
 float32_t test_vpmaxnms_f32(float32x2_t a) {
   return vpmaxnms_f32(a);
 // CHECK: fmaxnmp {{s[0-9]+}}, {{v[0-9]+}}.2s
 }
 
-// CHECK: test_vpmaxnmqd_f64
+// CHECK-LABEL: test_vpmaxnmqd_f64
 float64_t test_vpmaxnmqd_f64(float64x2_t a) {
   return vpmaxnmqd_f64(a);
 // CHECK: fmaxnmp {{d[0-9]+}}, {{v[0-9]+}}.2d
 }
 
-// CHECK: test_vpmaxs_f32
+// CHECK-LABEL: test_vpmaxs_f32
 float32_t test_vpmaxs_f32(float32x2_t a) {
   return vpmaxs_f32(a);
 // CHECK: fmaxp {{s[0-9]+}}, {{v[0-9]+}}.2s
 }
 
-// CHECK: test_vpmaxqd_f64
+// CHECK-LABEL: test_vpmaxqd_f64
 float64_t test_vpmaxqd_f64(float64x2_t a) {
   return vpmaxqd_f64(a);
 // CHECK: fmaxp {{d[0-9]+}}, {{v[0-9]+}}.2d
 }
 
-// CHECK: test_vpminnms_f32
+// CHECK-LABEL: test_vpminnms_f32
 float32_t test_vpminnms_f32(float32x2_t a) {
   return vpminnms_f32(a);
 // CHECK: fminnmp {{s[0-9]+}}, {{v[0-9]+}}.2s
 }
 
-// CHECK: test_vpminnmqd_f64
+// CHECK-LABEL: test_vpminnmqd_f64
 float64_t test_vpminnmqd_f64(float64x2_t a) {
   return vpminnmqd_f64(a);
 // CHECK: fminnmp {{d[0-9]+}}, {{v[0-9]+}}.2d
 }
 
-// CHECK: test_vpmins_f32
+// CHECK-LABEL: test_vpmins_f32
 float32_t test_vpmins_f32(float32x2_t a) {
   return vpmins_f32(a);
 // CHECK: fminp {{s[0-9]+}}, {{v[0-9]+}}.2s
 }
 
-// CHECK: test_vpminqd_f64
+// CHECK-LABEL: test_vpminqd_f64
 float64_t test_vpminqd_f64(float64x2_t a) {
   return vpminqd_f64(a);
 // CHECK: fminp {{d[0-9]+}}, {{v[0-9]+}}.2d
 }
 
 int16_t test_vqdmulhh_s16(int16_t a, int16_t b) {
-// CHECK: test_vqdmulhh_s16
+// CHECK-LABEL: test_vqdmulhh_s16
   return vqdmulhh_s16(a, b);
-// CHECK: sqdmulh {{h[0-9]+}}, {{h[0-9]+}}, {{h[0-9]+}}
+// CHECK: sqdmulh {{h[0-9]+|v[0-9]+.4h}}, {{h[0-9]+|v[0-9]+.4h}}, {{h[0-9]+|v[0-9]+.4h}}
 }
 
 int32_t test_vqdmulhs_s32(int32_t a, int32_t b) {
-// CHECK: test_vqdmulhs_s32
+// CHECK-LABEL: test_vqdmulhs_s32
   return vqdmulhs_s32(a, b);
 // CHECK: sqdmulh {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
 }
 
 int16_t test_vqrdmulhh_s16(int16_t a, int16_t b) {
-// CHECK: test_vqrdmulhh_s16
+// CHECK-LABEL: test_vqrdmulhh_s16
   return vqrdmulhh_s16(a, b);
-// CHECK: sqrdmulh {{h[0-9]+}}, {{h[0-9]+}}, {{h[0-9]+}}
+// CHECK: sqrdmulh {{h[0-9]+|v[0-9]+.4h}}, {{h[0-9]+|v[0-9]+.4h}}, {{h[0-9]+|v[0-9]+.4h}}
 }
 
 int32_t test_vqrdmulhs_s32(int32_t a, int32_t b) {
-// CHECK: test_vqrdmulhs_s32
+// CHECK-LABEL: test_vqrdmulhs_s32
   return vqrdmulhs_s32(a, b);
 // CHECK: sqrdmulh {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
 }
 
 float32_t test_vmulxs_f32(float32_t a, float32_t b) {
-// CHECK: test_vmulxs_f32
+// CHECK-LABEL: test_vmulxs_f32
   return vmulxs_f32(a, b);
 // CHECK: fmulx {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
 }
 
 float64_t test_vmulxd_f64(float64_t a, float64_t b) {
-// CHECK: test_vmulxd_f64
+// CHECK-LABEL: test_vmulxd_f64
   return vmulxd_f64(a, b);
 // CHECK: fmulx {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
 }
 
+float64x1_t test_vmulx_f64(float64x1_t a, float64x1_t b) {
+// CHECK-LABEL: test_vmulx_f64
+  return vmulx_f64(a, b);
+// CHECK: fmulx {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+}
+
 float32_t test_vrecpss_f32(float32_t a, float32_t b) {
-// CHECK: test_vrecpss_f32
+// CHECK-LABEL: test_vrecpss_f32
   return vrecpss_f32(a, b);
 // CHECK: frecps {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
 }
 
 float64_t test_vrecpsd_f64(float64_t a, float64_t b) {
-// CHECK: test_vrecpsd_f64
+// CHECK-LABEL: test_vrecpsd_f64
   return vrecpsd_f64(a, b);
 // CHECK: frecps {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
 }
 
 float32_t test_vrsqrtss_f32(float32_t a, float32_t b) {
-// CHECK: test_vrsqrtss_f32
+// CHECK-LABEL: test_vrsqrtss_f32
   return vrsqrtss_f32(a, b);
 // CHECK: frsqrts {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
 }
 
 float64_t test_vrsqrtsd_f64(float64_t a, float64_t b) {
-// CHECK: test_vrsqrtsd_f64
+// CHECK-LABEL: test_vrsqrtsd_f64
   return vrsqrtsd_f64(a, b);
 // CHECK: frsqrts {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
 }
 
 float32_t test_vcvts_f32_s32(int32_t a) {
-// CHECK: test_vcvts_f32_s32
-// CHECK: scvtf {{s[0-9]+}}, {{s[0-9]+}}
+// CHECK-LABEL: test_vcvts_f32_s32
+// CHECK: scvtf {{s[0-9]+}}, {{[ws][0-9]+}}
   return vcvts_f32_s32(a);
 }
 
 float64_t test_vcvtd_f64_s64(int64_t a) {
-// CHECK: test_vcvtd_f64_s64
-// CHECK: scvtf {{d[0-9]+}}, {{d[0-9]+}}
+// CHECK-LABEL: test_vcvtd_f64_s64
+// CHECK: scvtf {{d[0-9]+}}, {{[dx][0-9]+}}
   return vcvtd_f64_s64(a);
 }
 
 float32_t test_vcvts_f32_u32(uint32_t a) {
-// CHECK: test_vcvts_f32_u32
-// CHECK: ucvtf {{s[0-9]+}}, {{s[0-9]+}}
+// CHECK-LABEL: test_vcvts_f32_u32
+// CHECK: ucvtf {{s[0-9]+}}, {{[ws][0-9]+}}
   return vcvts_f32_u32(a);
 }
 
 float64_t test_vcvtd_f64_u64(uint64_t a) {
-// CHECK: test_vcvtd_f64_u64
-// CHECK: ucvtf {{d[0-9]+}}, {{d[0-9]+}}
+// CHECK-LABEL: test_vcvtd_f64_u64
+// CHECK: ucvtf {{d[0-9]+}}, {{[xd][0-9]+}}
   return vcvtd_f64_u64(a);
 }
 
 float32_t test_vrecpes_f32(float32_t a) {
-// CHECK: test_vrecpes_f32
+// CHECK-LABEL: test_vrecpes_f32
 // CHECK: frecpe {{s[0-9]+}}, {{s[0-9]+}}
   return vrecpes_f32(a);
 }
  
 float64_t test_vrecped_f64(float64_t a) {
-// CHECK: test_vrecped_f64
+// CHECK-LABEL: test_vrecped_f64
 // CHECK: frecpe {{d[0-9]+}}, {{d[0-9]+}}
   return vrecped_f64(a);
 }
  
 float32_t test_vrecpxs_f32(float32_t a) {
-// CHECK: test_vrecpxs_f32
+// CHECK-LABEL: test_vrecpxs_f32
 // CHECK: frecpx {{s[0-9]+}}, {{s[0-9]+}}
   return vrecpxs_f32(a);
  }
  
 float64_t test_vrecpxd_f64(float64_t a) {
-// CHECK: test_vrecpxd_f64
+// CHECK-LABEL: test_vrecpxd_f64
 // CHECK: frecpx {{d[0-9]+}}, {{d[0-9]+}}
   return vrecpxd_f64(a);
 }
 
+uint32x2_t test_vrsqrte_u32(uint32x2_t a) {
+// CHECK-LABEL: test_vrsqrte_u32
+// CHECK: ursqrte {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
+  return vrsqrte_u32(a);
+}
+
+uint32x4_t test_vrsqrteq_u32(uint32x4_t a) {
+// CHECK-LABEL: test_vrsqrteq_u32
+// CHECK: ursqrte {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
+  return vrsqrteq_u32(a);
+}
+
 float32_t test_vrsqrtes_f32(float32_t a) {
 // CHECK: vrsqrtes_f32
 // CHECK: frsqrte {{s[0-9]+}}, {{s[0-9]+}}
@@ -5659,2954 +5819,2742 @@
 }
 
 uint8x16_t test_vld1q_u8(uint8_t const *a) {
-  // CHECK: test_vld1q_u8
+  // CHECK-LABEL: test_vld1q_u8
   return vld1q_u8(a);
-  // CHECK: ld1 {v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1 { v[0-9]+.16b }|ldr q[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 uint16x8_t test_vld1q_u16(uint16_t const *a) {
-  // CHECK: test_vld1q_u16
+  // CHECK-LABEL: test_vld1q_u16
   return vld1q_u16(a);
-  // CHECK: ld1 {v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1 { v[0-9]+.8h }|ldr q[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 uint32x4_t test_vld1q_u32(uint32_t const *a) {
-  // CHECK: test_vld1q_u32
+  // CHECK-LABEL: test_vld1q_u32
   return vld1q_u32(a);
-  // CHECK: ld1 {v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1 { v[0-9]+.4s }|ldr q[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 uint64x2_t test_vld1q_u64(uint64_t const *a) {
-  // CHECK: test_vld1q_u64
+  // CHECK-LABEL: test_vld1q_u64
   return vld1q_u64(a);
-  // CHECK: ld1 {v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1 { v[0-9]+.2d }|ldr q[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 int8x16_t test_vld1q_s8(int8_t const *a) {
-  // CHECK: test_vld1q_s8
+  // CHECK-LABEL: test_vld1q_s8
   return vld1q_s8(a);
-  // CHECK: ld1 {v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1 { v[0-9]+.16b }|ldr q[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 int16x8_t test_vld1q_s16(int16_t const *a) {
-  // CHECK: test_vld1q_s16
+  // CHECK-LABEL: test_vld1q_s16
   return vld1q_s16(a);
-  // CHECK: ld1 {v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1 { v[0-9]+.8h }|ldr q[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 int32x4_t test_vld1q_s32(int32_t const *a) {
-  // CHECK: test_vld1q_s32
+  // CHECK-LABEL: test_vld1q_s32
   return vld1q_s32(a);
-  // CHECK: ld1 {v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1 { v[0-9]+.4s }|ldr q[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 int64x2_t test_vld1q_s64(int64_t const *a) {
-  // CHECK: test_vld1q_s64
+  // CHECK-LABEL: test_vld1q_s64
   return vld1q_s64(a);
-  // CHECK: ld1 {v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1 { v[0-9]+.2d }|ldr q[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 float16x8_t test_vld1q_f16(float16_t const *a) {
-  // CHECK: test_vld1q_f16
+  // CHECK-LABEL: test_vld1q_f16
   return vld1q_f16(a);
-  // CHECK: ld1 {v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1 { v[0-9]+.8h }|ldr q[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 float32x4_t test_vld1q_f32(float32_t const *a) {
-  // CHECK: test_vld1q_f32
+  // CHECK-LABEL: test_vld1q_f32
   return vld1q_f32(a);
-  // CHECK: ld1 {v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1 { v[0-9]+.4s }|ldr q[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 float64x2_t test_vld1q_f64(float64_t const *a) {
-  // CHECK: test_vld1q_f64
+  // CHECK-LABEL: test_vld1q_f64
   return vld1q_f64(a);
-  // CHECK: ld1 {v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1 { v[0-9]+.2d }|ldr q[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 poly8x16_t test_vld1q_p8(poly8_t const *a) {
-  // CHECK: test_vld1q_p8
+  // CHECK-LABEL: test_vld1q_p8
   return vld1q_p8(a);
-  // CHECK: ld1 {v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1 { v[0-9]+.16b }|ldr q[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 poly16x8_t test_vld1q_p16(poly16_t const *a) {
-  // CHECK: test_vld1q_p16
+  // CHECK-LABEL: test_vld1q_p16
   return vld1q_p16(a);
-  // CHECK: ld1 {v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1 { v[0-9]+.8h }|ldr q[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 uint8x8_t test_vld1_u8(uint8_t const *a) {
-  // CHECK: test_vld1_u8
+  // CHECK-LABEL: test_vld1_u8
   return vld1_u8(a);
-  // CHECK: ld1 {v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1 { v[0-9]+.8b }|ldr d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 uint16x4_t test_vld1_u16(uint16_t const *a) {
-  // CHECK: test_vld1_u16
+  // CHECK-LABEL: test_vld1_u16
   return vld1_u16(a);
-  // CHECK: ld1 {v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1 { v[0-9]+.4h }|ldr d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 uint32x2_t test_vld1_u32(uint32_t const *a) {
-  // CHECK: test_vld1_u32
+  // CHECK-LABEL: test_vld1_u32
   return vld1_u32(a);
-  // CHECK: ld1 {v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1 { v[0-9]+.2s }|ldr d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 uint64x1_t test_vld1_u64(uint64_t const *a) {
-  // CHECK: test_vld1_u64
+  // CHECK-LABEL: test_vld1_u64
   return vld1_u64(a);
-  // CHECK: ld1 {v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1 { v[0-9]+.1d }|ldr d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 int8x8_t test_vld1_s8(int8_t const *a) {
-  // CHECK: test_vld1_s8
+  // CHECK-LABEL: test_vld1_s8
   return vld1_s8(a);
-  // CHECK: ld1 {v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1 { v[0-9]+.8b }|ldr d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 int16x4_t test_vld1_s16(int16_t const *a) {
-  // CHECK: test_vld1_s16
+  // CHECK-LABEL: test_vld1_s16
   return vld1_s16(a);
-  // CHECK: ld1 {v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1 { v[0-9]+.4h }|ldr d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 int32x2_t test_vld1_s32(int32_t const *a) {
-  // CHECK: test_vld1_s32
+  // CHECK-LABEL: test_vld1_s32
   return vld1_s32(a);
-  // CHECK: ld1 {v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1 { v[0-9]+.2s }|ldr d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 int64x1_t test_vld1_s64(int64_t const *a) {
-  // CHECK: test_vld1_s64
+  // CHECK-LABEL: test_vld1_s64
   return vld1_s64(a);
-  // CHECK: ld1 {v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1 { v[0-9]+.1d }|ldr d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 float16x4_t test_vld1_f16(float16_t const *a) {
-  // CHECK: test_vld1_f16
+  // CHECK-LABEL: test_vld1_f16
   return vld1_f16(a);
-  // CHECK: ld1 {v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1 { v[0-9]+.4h }|ldr d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 float32x2_t test_vld1_f32(float32_t const *a) {
-  // CHECK: test_vld1_f32
+  // CHECK-LABEL: test_vld1_f32
   return vld1_f32(a);
-  // CHECK: ld1 {v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1 { v[0-9]+.2s }|ldr d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 float64x1_t test_vld1_f64(float64_t const *a) {
-  // CHECK: test_vld1_f64
+  // CHECK-LABEL: test_vld1_f64
   return vld1_f64(a);
-  // CHECK: ld1 {v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1 { v[0-9]+.1d }|ldr d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 poly8x8_t test_vld1_p8(poly8_t const *a) {
-  // CHECK: test_vld1_p8
+  // CHECK-LABEL: test_vld1_p8
   return vld1_p8(a);
-  // CHECK: ld1 {v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1 { v[0-9]+.8b }|ldr d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 poly16x4_t test_vld1_p16(poly16_t const *a) {
-  // CHECK: test_vld1_p16
+  // CHECK-LABEL: test_vld1_p16
   return vld1_p16(a);
-  // CHECK: ld1 {v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1 { v[0-9]+.4h }|ldr d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 uint8x16x2_t test_vld2q_u8(uint8_t const *a) {
-  // CHECK: test_vld2q_u8
+  // CHECK-LABEL: test_vld2q_u8
   return vld2q_u8(a);
-  // CHECK: ld2 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ ?v[0-9]+.16b, v[0-9]+.16b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint16x8x2_t test_vld2q_u16(uint16_t const *a) {
-  // CHECK: test_vld2q_u16
+  // CHECK-LABEL: test_vld2q_u16
   return vld2q_u16(a);
-  // CHECK: ld2 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ ?v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint32x4x2_t test_vld2q_u32(uint32_t const *a) {
-  // CHECK: test_vld2q_u32
+  // CHECK-LABEL: test_vld2q_u32
   return vld2q_u32(a);
-  // CHECK: ld2 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ ?v[0-9]+.4s, v[0-9]+.4s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint64x2x2_t test_vld2q_u64(uint64_t const *a) {
-  // CHECK: test_vld2q_u64
+  // CHECK-LABEL: test_vld2q_u64
   return vld2q_u64(a);
-  // CHECK: ld2 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ ?v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int8x16x2_t test_vld2q_s8(int8_t const *a) {
-  // CHECK: test_vld2q_s8
+  // CHECK-LABEL: test_vld2q_s8
   return vld2q_s8(a);
-  // CHECK: ld2 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ ?v[0-9]+.16b, v[0-9]+.16b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int16x8x2_t test_vld2q_s16(int16_t const *a) {
-  // CHECK: test_vld2q_s16
+  // CHECK-LABEL: test_vld2q_s16
   return vld2q_s16(a);
-  // CHECK: ld2 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ ?v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int32x4x2_t test_vld2q_s32(int32_t const *a) {
-  // CHECK: test_vld2q_s32
+  // CHECK-LABEL: test_vld2q_s32
   return vld2q_s32(a);
-  // CHECK: ld2 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ ?v[0-9]+.4s, v[0-9]+.4s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int64x2x2_t test_vld2q_s64(int64_t const *a) {
-  // CHECK: test_vld2q_s64
+  // CHECK-LABEL: test_vld2q_s64
   return vld2q_s64(a);
-  // CHECK: ld2 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ ?v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 float16x8x2_t test_vld2q_f16(float16_t const *a) {
-  // CHECK: test_vld2q_f16
+  // CHECK-LABEL: test_vld2q_f16
   return vld2q_f16(a);
-  // CHECK: ld2 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ ?v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 float32x4x2_t test_vld2q_f32(float32_t const *a) {
-  // CHECK: test_vld2q_f32
+  // CHECK-LABEL: test_vld2q_f32
   return vld2q_f32(a);
-  // CHECK: ld2 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ ?v[0-9]+.4s, v[0-9]+.4s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 float64x2x2_t test_vld2q_f64(float64_t const *a) {
-  // CHECK: test_vld2q_f64
+  // CHECK-LABEL: test_vld2q_f64
   return vld2q_f64(a);
-  // CHECK: ld2 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ ?v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 poly8x16x2_t test_vld2q_p8(poly8_t const *a) {
-  // CHECK: test_vld2q_p8
+  // CHECK-LABEL: test_vld2q_p8
   return vld2q_p8(a);
-  // CHECK: ld2 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ ?v[0-9]+.16b, v[0-9]+.16b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 poly16x8x2_t test_vld2q_p16(poly16_t const *a) {
-  // CHECK: test_vld2q_p16
+  // CHECK-LABEL: test_vld2q_p16
   return vld2q_p16(a);
-  // CHECK: ld2 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ ?v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint8x8x2_t test_vld2_u8(uint8_t const *a) {
-  // CHECK: test_vld2_u8
+  // CHECK-LABEL: test_vld2_u8
   return vld2_u8(a);
-  // CHECK: ld2 {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ ?v[0-9]+.8b, v[0-9]+.8b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint16x4x2_t test_vld2_u16(uint16_t const *a) {
-  // CHECK: test_vld2_u16
+  // CHECK-LABEL: test_vld2_u16
   return vld2_u16(a);
-  // CHECK: ld2 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ ?v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint32x2x2_t test_vld2_u32(uint32_t const *a) {
-  // CHECK: test_vld2_u32
+  // CHECK-LABEL: test_vld2_u32
   return vld2_u32(a);
-  // CHECK: ld2 {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ ?v[0-9]+.2s, v[0-9]+.2s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint64x1x2_t test_vld2_u64(uint64_t const *a) {
-  // CHECK: test_vld2_u64
+  // CHECK-LABEL: test_vld2_u64
   return vld2_u64(a);
-  // CHECK: ld1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1|ld2}} {{{ ?v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int8x8x2_t test_vld2_s8(int8_t const *a) {
-  // CHECK: test_vld2_s8
+  // CHECK-LABEL: test_vld2_s8
   return vld2_s8(a);
-  // CHECK: ld2 {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ ?v[0-9]+.8b, v[0-9]+.8b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int16x4x2_t test_vld2_s16(int16_t const *a) {
-  // CHECK: test_vld2_s16
+  // CHECK-LABEL: test_vld2_s16
   return vld2_s16(a);
-  // CHECK: ld2 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ ?v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int32x2x2_t test_vld2_s32(int32_t const *a) {
-  // CHECK: test_vld2_s32
+  // CHECK-LABEL: test_vld2_s32
   return vld2_s32(a);
-  // CHECK: ld2 {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ ?v[0-9]+.2s, v[0-9]+.2s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int64x1x2_t test_vld2_s64(int64_t const *a) {
-  // CHECK: test_vld2_s64
+  // CHECK-LABEL: test_vld2_s64
   return vld2_s64(a);
-  // CHECK: ld1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1|ld2}} {{{ ?v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 float16x4x2_t test_vld2_f16(float16_t const *a) {
-  // CHECK: test_vld2_f16
+  // CHECK-LABEL: test_vld2_f16
   return vld2_f16(a);
-  // CHECK: ld2 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ ?v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 float32x2x2_t test_vld2_f32(float32_t const *a) {
-  // CHECK: test_vld2_f32
+  // CHECK-LABEL: test_vld2_f32
   return vld2_f32(a);
-  // CHECK: ld2 {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ ?v[0-9]+.2s, v[0-9]+.2s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 float64x1x2_t test_vld2_f64(float64_t const *a) {
-  // CHECK: test_vld2_f64
+  // CHECK-LABEL: test_vld2_f64
   return vld2_f64(a);
-  // CHECK: ld1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1|ld2}} {{{ ?v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 poly8x8x2_t test_vld2_p8(poly8_t const *a) {
-  // CHECK: test_vld2_p8
+  // CHECK-LABEL: test_vld2_p8
   return vld2_p8(a);
-  // CHECK: ld2 {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ ?v[0-9]+.8b, v[0-9]+.8b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 poly16x4x2_t test_vld2_p16(poly16_t const *a) {
-  // CHECK: test_vld2_p16
+  // CHECK-LABEL: test_vld2_p16
   return vld2_p16(a);
-  // CHECK: ld2 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ ?v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint8x16x3_t test_vld3q_u8(uint8_t const *a) {
-  // CHECK: test_vld3q_u8
+  // CHECK-LABEL: test_vld3q_u8
   return vld3q_u8(a);
-  // CHECK: ld3 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint16x8x3_t test_vld3q_u16(uint16_t const *a) {
-  // CHECK: test_vld3q_u16
+  // CHECK-LABEL: test_vld3q_u16
   return vld3q_u16(a);
-  // CHECK: ld3 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ ?v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint32x4x3_t test_vld3q_u32(uint32_t const *a) {
-  // CHECK: test_vld3q_u32
+  // CHECK-LABEL: test_vld3q_u32
   return vld3q_u32(a);
-  // CHECK: ld3 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s, v{{[0-9]+}}.4s},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ ?v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint64x2x3_t test_vld3q_u64(uint64_t const *a) {
-  // CHECK: test_vld3q_u64
+  // CHECK-LABEL: test_vld3q_u64
   return vld3q_u64(a);
-  // CHECK: ld3 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ ?v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int8x16x3_t test_vld3q_s8(int8_t const *a) {
-  // CHECK: test_vld3q_s8
+  // CHECK-LABEL: test_vld3q_s8
   return vld3q_s8(a);
-  // CHECK: ld3 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int16x8x3_t test_vld3q_s16(int16_t const *a) {
-  // CHECK: test_vld3q_s16
+  // CHECK-LABEL: test_vld3q_s16
   return vld3q_s16(a);
-  // CHECK: ld3 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ ?v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int32x4x3_t test_vld3q_s32(int32_t const *a) {
-  // CHECK: test_vld3q_s32
+  // CHECK-LABEL: test_vld3q_s32
   return vld3q_s32(a);
-  // CHECK: ld3 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s, v{{[0-9]+}}.4s},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ ?v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int64x2x3_t test_vld3q_s64(int64_t const *a) {
-  // CHECK: test_vld3q_s64
+  // CHECK-LABEL: test_vld3q_s64
   return vld3q_s64(a);
-  // CHECK: ld3 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ ?v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 float16x8x3_t test_vld3q_f16(float16_t const *a) {
-  // CHECK: test_vld3q_f16
+  // CHECK-LABEL: test_vld3q_f16
   return vld3q_f16(a);
-  // CHECK: ld3 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ ?v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 float32x4x3_t test_vld3q_f32(float32_t const *a) {
-  // CHECK: test_vld3q_f32
+  // CHECK-LABEL: test_vld3q_f32
   return vld3q_f32(a);
-  // CHECK: ld3 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s, v{{[0-9]+}}.4s},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ ?v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 float64x2x3_t test_vld3q_f64(float64_t const *a) {
-  // CHECK: test_vld3q_f64
+  // CHECK-LABEL: test_vld3q_f64
   return vld3q_f64(a);
-  // CHECK: ld3 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ ?v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 poly8x16x3_t test_vld3q_p8(poly8_t const *a) {
-  // CHECK: test_vld3q_p8
+  // CHECK-LABEL: test_vld3q_p8
   return vld3q_p8(a);
-  // CHECK: ld3 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 poly16x8x3_t test_vld3q_p16(poly16_t const *a) {
-  // CHECK: test_vld3q_p16
+  // CHECK-LABEL: test_vld3q_p16
   return vld3q_p16(a);
-  // CHECK: ld3 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ ?v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint8x8x3_t test_vld3_u8(uint8_t const *a) {
-  // CHECK: test_vld3_u8
+  // CHECK-LABEL: test_vld3_u8
   return vld3_u8(a);
-  // CHECK: ld3 {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b, v{{[0-9]+}}.8b},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ ?v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint16x4x3_t test_vld3_u16(uint16_t const *a) {
-  // CHECK: test_vld3_u16
+  // CHECK-LABEL: test_vld3_u16
   return vld3_u16(a);
-  // CHECK: ld3 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ ?v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint32x2x3_t test_vld3_u32(uint32_t const *a) {
-  // CHECK: test_vld3_u32
+  // CHECK-LABEL: test_vld3_u32
   return vld3_u32(a);
-  // CHECK: ld3 {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s, v{{[0-9]+}}.2s},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ ?v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint64x1x3_t test_vld3_u64(uint64_t const *a) {
-  // CHECK: test_vld3_u64
+  // CHECK-LABEL: test_vld3_u64
   return vld3_u64(a);
-  // CHECK: ld1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1|ld3}} {{{ ?v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int8x8x3_t test_vld3_s8(int8_t const *a) {
-  // CHECK: test_vld3_s8
+  // CHECK-LABEL: test_vld3_s8
   return vld3_s8(a);
-  // CHECK: ld3 {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b, v{{[0-9]+}}.8b},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ ?v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int16x4x3_t test_vld3_s16(int16_t const *a) {
-  // CHECK: test_vld3_s16
+  // CHECK-LABEL: test_vld3_s16
   return vld3_s16(a);
-  // CHECK: ld3 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ ?v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int32x2x3_t test_vld3_s32(int32_t const *a) {
-  // CHECK: test_vld3_s32
+  // CHECK-LABEL: test_vld3_s32
   return vld3_s32(a);
-  // CHECK: ld3 {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s, v{{[0-9]+}}.2s},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ ?v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int64x1x3_t test_vld3_s64(int64_t const *a) {
-  // CHECK: test_vld3_s64
+  // CHECK-LABEL: test_vld3_s64
   return vld3_s64(a);
-  // CHECK: ld1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1|ld3}} {{{ ?v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 float16x4x3_t test_vld3_f16(float16_t const *a) {
-  // CHECK: test_vld3_f16
+  // CHECK-LABEL: test_vld3_f16
   return vld3_f16(a);
-  // CHECK: ld3 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ ?v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 float32x2x3_t test_vld3_f32(float32_t const *a) {
-  // CHECK: test_vld3_f32
+  // CHECK-LABEL: test_vld3_f32
   return vld3_f32(a);
-  // CHECK: ld3 {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s, v{{[0-9]+}}.2s},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ ?v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 float64x1x3_t test_vld3_f64(float64_t const *a) {
-  // CHECK: test_vld3_f64
+  // CHECK-LABEL: test_vld3_f64
   return vld3_f64(a);
-  // CHECK: ld1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1|ld3}} {{{ ?v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 poly8x8x3_t test_vld3_p8(poly8_t const *a) {
-  // CHECK: test_vld3_p8
+  // CHECK-LABEL: test_vld3_p8
   return vld3_p8(a);
-  // CHECK: ld3 {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b, v{{[0-9]+}}.8b},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ ?v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 poly16x4x3_t test_vld3_p16(poly16_t const *a) {
-  // CHECK: test_vld3_p16
+  // CHECK-LABEL: test_vld3_p16
   return vld3_p16(a);
-  // CHECK: ld3 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ ?v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint8x16x4_t test_vld4q_u8(uint8_t const *a) {
-  // CHECK: test_vld4q_u8
+  // CHECK-LABEL: test_vld4q_u8
   return vld4q_u8(a);
-  // CHECK: ld4 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b,
-  // v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint16x8x4_t test_vld4q_u16(uint16_t const *a) {
-  // CHECK: test_vld4q_u16
+  // CHECK-LABEL: test_vld4q_u16
   return vld4q_u16(a);
-  // CHECK: ld4 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h,
-  // v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ ?v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint32x4x4_t test_vld4q_u32(uint32_t const *a) {
-  // CHECK: test_vld4q_u32
+  // CHECK-LABEL: test_vld4q_u32
   return vld4q_u32(a);
-  // CHECK: ld4 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s, v{{[0-9]+}}.4s,
-  // v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ ?v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint64x2x4_t test_vld4q_u64(uint64_t const *a) {
-  // CHECK: test_vld4q_u64
+  // CHECK-LABEL: test_vld4q_u64
   return vld4q_u64(a);
-  // CHECK: ld4 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d,
-  // v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ ?v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int8x16x4_t test_vld4q_s8(int8_t const *a) {
-  // CHECK: test_vld4q_s8
+  // CHECK-LABEL: test_vld4q_s8
   return vld4q_s8(a);
-  // CHECK: ld4 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b,
-  // v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int16x8x4_t test_vld4q_s16(int16_t const *a) {
-  // CHECK: test_vld4q_s16
+  // CHECK-LABEL: test_vld4q_s16
   return vld4q_s16(a);
-  // CHECK: ld4 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h,
-  // v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ ?v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int32x4x4_t test_vld4q_s32(int32_t const *a) {
-  // CHECK: test_vld4q_s32
+  // CHECK-LABEL: test_vld4q_s32
   return vld4q_s32(a);
-  // CHECK: ld4 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s, v{{[0-9]+}}.4s,
-  // v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ ?v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int64x2x4_t test_vld4q_s64(int64_t const *a) {
-  // CHECK: test_vld4q_s64
+  // CHECK-LABEL: test_vld4q_s64
   return vld4q_s64(a);
-  // CHECK: ld4 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d,
-  // v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ ?v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 float16x8x4_t test_vld4q_f16(float16_t const *a) {
-  // CHECK: test_vld4q_f16
+  // CHECK-LABEL: test_vld4q_f16
   return vld4q_f16(a);
-  // CHECK: ld4 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h,
-  // v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ ?v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 float32x4x4_t test_vld4q_f32(float32_t const *a) {
-  // CHECK: test_vld4q_f32
+  // CHECK-LABEL: test_vld4q_f32
   return vld4q_f32(a);
-  // CHECK: ld4 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s, v{{[0-9]+}}.4s,
-  // v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ ?v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 float64x2x4_t test_vld4q_f64(float64_t const *a) {
-  // CHECK: test_vld4q_f64
+  // CHECK-LABEL: test_vld4q_f64
   return vld4q_f64(a);
-  // CHECK: ld4 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d,
-  // v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ ?v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 poly8x16x4_t test_vld4q_p8(poly8_t const *a) {
-  // CHECK: test_vld4q_p8
+  // CHECK-LABEL: test_vld4q_p8
   return vld4q_p8(a);
-  // CHECK: ld4 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b,
-  // v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 poly16x8x4_t test_vld4q_p16(poly16_t const *a) {
-  // CHECK: test_vld4q_p16
+  // CHECK-LABEL: test_vld4q_p16
   return vld4q_p16(a);
-  // CHECK: ld4 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h,
-  // v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ ?v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint8x8x4_t test_vld4_u8(uint8_t const *a) {
-  // CHECK: test_vld4_u8
+  // CHECK-LABEL: test_vld4_u8
   return vld4_u8(a);
-  // CHECK: ld4 {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b, v{{[0-9]+}}.8b,
-  // v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ ?v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint16x4x4_t test_vld4_u16(uint16_t const *a) {
-  // CHECK: test_vld4_u16
+  // CHECK-LABEL: test_vld4_u16
   return vld4_u16(a);
-  // CHECK: ld4 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h,
-  // v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ ?v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint32x2x4_t test_vld4_u32(uint32_t const *a) {
-  // CHECK: test_vld4_u32
+  // CHECK-LABEL: test_vld4_u32
   return vld4_u32(a);
-  // CHECK: ld4 {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s, v{{[0-9]+}}.2s,
-  // v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ ?v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint64x1x4_t test_vld4_u64(uint64_t const *a) {
-  // CHECK: test_vld4_u64
+  // CHECK-LABEL: test_vld4_u64
   return vld4_u64(a);
-  // CHECK: ld1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d,
-  // v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1|ld4}} {{{ ?v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int8x8x4_t test_vld4_s8(int8_t const *a) {
-  // CHECK: test_vld4_s8
+  // CHECK-LABEL: test_vld4_s8
   return vld4_s8(a);
-  // CHECK: ld4 {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b, v{{[0-9]+}}.8b,
-  // v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ ?v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int16x4x4_t test_vld4_s16(int16_t const *a) {
-  // CHECK: test_vld4_s16
+  // CHECK-LABEL: test_vld4_s16
   return vld4_s16(a);
-  // CHECK: ld4 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h,
-  // v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ ?v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int32x2x4_t test_vld4_s32(int32_t const *a) {
-  // CHECK: test_vld4_s32
+  // CHECK-LABEL: test_vld4_s32
   return vld4_s32(a);
-  // CHECK: ld4 {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s, v{{[0-9]+}}.2s,
-  // v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ ?v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int64x1x4_t test_vld4_s64(int64_t const *a) {
-  // CHECK: test_vld4_s64
+  // CHECK-LABEL: test_vld4_s64
   return vld4_s64(a);
-  // CHECK: ld1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d,
-  // v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1|ld4}} {{{ ?v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 float16x4x4_t test_vld4_f16(float16_t const *a) {
-  // CHECK: test_vld4_f16
+  // CHECK-LABEL: test_vld4_f16
   return vld4_f16(a);
-  // CHECK: ld4 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h,
-  // v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ ?v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 float32x2x4_t test_vld4_f32(float32_t const *a) {
-  // CHECK: test_vld4_f32
+  // CHECK-LABEL: test_vld4_f32
   return vld4_f32(a);
-  // CHECK: ld4 {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s, v{{[0-9]+}}.2s,
-  // v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ ?v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 float64x1x4_t test_vld4_f64(float64_t const *a) {
-  // CHECK: test_vld4_f64
+  // CHECK-LABEL: test_vld4_f64
   return vld4_f64(a);
-  // CHECK: ld1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d,
-  // v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1|ld4}} {{{ ?v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 poly8x8x4_t test_vld4_p8(poly8_t const *a) {
-  // CHECK: test_vld4_p8
+  // CHECK-LABEL: test_vld4_p8
   return vld4_p8(a);
-  // CHECK: ld4 {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b, v{{[0-9]+}}.8b,
-  // v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ ?v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 poly16x4x4_t test_vld4_p16(poly16_t const *a) {
-  // CHECK: test_vld4_p16
+  // CHECK-LABEL: test_vld4_p16
   return vld4_p16(a);
-  // CHECK: ld4 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h,
-  // v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ ?v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_u8(uint8_t *a, uint8x16_t b) {
-  // CHECK: test_vst1q_u8
+  // CHECK-LABEL: test_vst1q_u8
   vst1q_u8(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: {{st1 { v[0-9]+.16b }|str q[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_u16(uint16_t *a, uint16x8_t b) {
-  // CHECK: test_vst1q_u16
+  // CHECK-LABEL: test_vst1q_u16
   vst1q_u16(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: {{st1 { v[0-9]+.8h }|str q[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_u32(uint32_t *a, uint32x4_t b) {
-  // CHECK: test_vst1q_u32
+  // CHECK-LABEL: test_vst1q_u32
   vst1q_u32(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: {{st1 { v[0-9]+.4s }|str q[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_u64(uint64_t *a, uint64x2_t b) {
-  // CHECK: test_vst1q_u64
+  // CHECK-LABEL: test_vst1q_u64
   vst1q_u64(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{st1 { v[0-9]+.2d }|str q[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_s8(int8_t *a, int8x16_t b) {
-  // CHECK: test_vst1q_s8
+  // CHECK-LABEL: test_vst1q_s8
   vst1q_s8(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: {{st1 { v[0-9]+.16b }|str q[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_s16(int16_t *a, int16x8_t b) {
-  // CHECK: test_vst1q_s16
+  // CHECK-LABEL: test_vst1q_s16
   vst1q_s16(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: {{st1 { v[0-9]+.8h }|str q[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_s32(int32_t *a, int32x4_t b) {
-  // CHECK: test_vst1q_s32
+  // CHECK-LABEL: test_vst1q_s32
   vst1q_s32(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: {{st1 { v[0-9]+.4s }|str q[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_s64(int64_t *a, int64x2_t b) {
-  // CHECK: test_vst1q_s64
+  // CHECK-LABEL: test_vst1q_s64
   vst1q_s64(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{st1 { v[0-9]+.2d }|str q[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_f16(float16_t *a, float16x8_t b) {
-  // CHECK: test_vst1q_f16
+  // CHECK-LABEL: test_vst1q_f16
   vst1q_f16(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: {{st1 { v[0-9]+.8h }|str q[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_f32(float32_t *a, float32x4_t b) {
-  // CHECK: test_vst1q_f32
+  // CHECK-LABEL: test_vst1q_f32
   vst1q_f32(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: {{st1 { v[0-9]+.4s }|str q[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_f64(float64_t *a, float64x2_t b) {
-  // CHECK: test_vst1q_f64
+  // CHECK-LABEL: test_vst1q_f64
   vst1q_f64(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{st1 { v[0-9]+.2d }|str q[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_p8(poly8_t *a, poly8x16_t b) {
-  // CHECK: test_vst1q_p8
+  // CHECK-LABEL: test_vst1q_p8
   vst1q_p8(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: {{st1 { v[0-9]+.16b }|str q[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_p16(poly16_t *a, poly16x8_t b) {
-  // CHECK: test_vst1q_p16
+  // CHECK-LABEL: test_vst1q_p16
   vst1q_p16(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: {{st1 { v[0-9]+.8h }|str q[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_u8(uint8_t *a, uint8x8_t b) {
-  // CHECK: test_vst1_u8
+  // CHECK-LABEL: test_vst1_u8
   vst1_u8(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: {{st1 { v[0-9]+.8b }|str d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_u16(uint16_t *a, uint16x4_t b) {
-  // CHECK: test_vst1_u16
+  // CHECK-LABEL: test_vst1_u16
   vst1_u16(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: {{st1 { v[0-9]+.4h }|str d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_u32(uint32_t *a, uint32x2_t b) {
-  // CHECK: test_vst1_u32
+  // CHECK-LABEL: test_vst1_u32
   vst1_u32(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: {{st1 { v[0-9]+.2s }|str d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_u64(uint64_t *a, uint64x1_t b) {
-  // CHECK: test_vst1_u64
+  // CHECK-LABEL: test_vst1_u64
   vst1_u64(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{st1 { v[0-9]+.1d }|str d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_s8(int8_t *a, int8x8_t b) {
-  // CHECK: test_vst1_s8
+  // CHECK-LABEL: test_vst1_s8
   vst1_s8(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: {{st1 { v[0-9]+.8b }|str d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_s16(int16_t *a, int16x4_t b) {
-  // CHECK: test_vst1_s16
+  // CHECK-LABEL: test_vst1_s16
   vst1_s16(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: {{st1 { v[0-9]+.4h }|str d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_s32(int32_t *a, int32x2_t b) {
-  // CHECK: test_vst1_s32
+  // CHECK-LABEL: test_vst1_s32
   vst1_s32(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: {{st1 { v[0-9]+.2s }|str d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_s64(int64_t *a, int64x1_t b) {
-  // CHECK: test_vst1_s64
+  // CHECK-LABEL: test_vst1_s64
   vst1_s64(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{st1 { v[0-9]+.1d }|str d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_f16(float16_t *a, float16x4_t b) {
-  // CHECK: test_vst1_f16
+  // CHECK-LABEL: test_vst1_f16
   vst1_f16(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: {{st1 { v[0-9]+.4h }|str d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_f32(float32_t *a, float32x2_t b) {
-  // CHECK: test_vst1_f32
+  // CHECK-LABEL: test_vst1_f32
   vst1_f32(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: {{st1 { v[0-9]+.2s }|str d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_f64(float64_t *a, float64x1_t b) {
-  // CHECK: test_vst1_f64
+  // CHECK-LABEL: test_vst1_f64
   vst1_f64(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{st1 { v[0-9]+.1d }|str d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_p8(poly8_t *a, poly8x8_t b) {
-  // CHECK: test_vst1_p8
+  // CHECK-LABEL: test_vst1_p8
   vst1_p8(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: {{st1 { v[0-9]+.8b }|str d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_p16(poly16_t *a, poly16x4_t b) {
-  // CHECK: test_vst1_p16
+  // CHECK-LABEL: test_vst1_p16
   vst1_p16(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: {{st1 { v[0-9]+.4h }|str d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst2q_u8(uint8_t *a, uint8x16x2_t b) {
-  // CHECK: test_vst2q_u8
+  // CHECK-LABEL: test_vst2q_u8
   vst2q_u8(a, b);
-  // CHECK: st2 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ ?v[0-9]+.16b, v[0-9]+.16b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst2q_u16(uint16_t *a, uint16x8x2_t b) {
-  // CHECK: test_vst2q_u16
+  // CHECK-LABEL: test_vst2q_u16
   vst2q_u16(a, b);
-  // CHECK: st2 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ ?v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst2q_u32(uint32_t *a, uint32x4x2_t b) {
-  // CHECK: test_vst2q_u32
+  // CHECK-LABEL: test_vst2q_u32
   vst2q_u32(a, b);
-  // CHECK: st2 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ ?v[0-9]+.4s, v[0-9]+.4s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst2q_u64(uint64_t *a, uint64x2x2_t b) {
-  // CHECK: test_vst2q_u64
+  // CHECK-LABEL: test_vst2q_u64
   vst2q_u64(a, b);
-  // CHECK: st2 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ ?v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst2q_s8(int8_t *a, int8x16x2_t b) {
-  // CHECK: test_vst2q_s8
+  // CHECK-LABEL: test_vst2q_s8
   vst2q_s8(a, b);
-  // CHECK: st2 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ ?v[0-9]+.16b, v[0-9]+.16b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst2q_s16(int16_t *a, int16x8x2_t b) {
-  // CHECK: test_vst2q_s16
+  // CHECK-LABEL: test_vst2q_s16
   vst2q_s16(a, b);
-  // CHECK: st2 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ ?v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst2q_s32(int32_t *a, int32x4x2_t b) {
-  // CHECK: test_vst2q_s32
+  // CHECK-LABEL: test_vst2q_s32
   vst2q_s32(a, b);
-  // CHECK: st2 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ ?v[0-9]+.4s, v[0-9]+.4s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst2q_s64(int64_t *a, int64x2x2_t b) {
-  // CHECK: test_vst2q_s64
+  // CHECK-LABEL: test_vst2q_s64
   vst2q_s64(a, b);
-  // CHECK: st2 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ ?v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst2q_f16(float16_t *a, float16x8x2_t b) {
-  // CHECK: test_vst2q_f16
+  // CHECK-LABEL: test_vst2q_f16
   vst2q_f16(a, b);
-  // CHECK: st2 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ ?v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst2q_f32(float32_t *a, float32x4x2_t b) {
-  // CHECK: test_vst2q_f32
+  // CHECK-LABEL: test_vst2q_f32
   vst2q_f32(a, b);
-  // CHECK: st2 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ ?v[0-9]+.4s, v[0-9]+.4s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst2q_f64(float64_t *a, float64x2x2_t b) {
-  // CHECK: test_vst2q_f64
+  // CHECK-LABEL: test_vst2q_f64
   vst2q_f64(a, b);
-  // CHECK: st2 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ ?v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst2q_p8(poly8_t *a, poly8x16x2_t b) {
-  // CHECK: test_vst2q_p8
+  // CHECK-LABEL: test_vst2q_p8
   vst2q_p8(a, b);
-  // CHECK: st2 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ ?v[0-9]+.16b, v[0-9]+.16b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst2q_p16(poly16_t *a, poly16x8x2_t b) {
-  // CHECK: test_vst2q_p16
+  // CHECK-LABEL: test_vst2q_p16
   vst2q_p16(a, b);
-  // CHECK: st2 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ ?v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst2_u8(uint8_t *a, uint8x8x2_t b) {
-  // CHECK: test_vst2_u8
+  // CHECK-LABEL: test_vst2_u8
   vst2_u8(a, b);
-  // CHECK: st2 {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ ?v[0-9]+.8b, v[0-9]+.8b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst2_u16(uint16_t *a, uint16x4x2_t b) {
-  // CHECK: test_vst2_u16
+  // CHECK-LABEL: test_vst2_u16
   vst2_u16(a, b);
-  // CHECK: st2 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ ?v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst2_u32(uint32_t *a, uint32x2x2_t b) {
-  // CHECK: test_vst2_u32
+  // CHECK-LABEL: test_vst2_u32
   vst2_u32(a, b);
-  // CHECK: st2 {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ ?v[0-9]+.2s, v[0-9]+.2s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst2_u64(uint64_t *a, uint64x1x2_t b) {
-  // CHECK: test_vst2_u64
+  // CHECK-LABEL: test_vst2_u64
   vst2_u64(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{st1|st2}} {{{ ?v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst2_s8(int8_t *a, int8x8x2_t b) {
-  // CHECK: test_vst2_s8
+  // CHECK-LABEL: test_vst2_s8
   vst2_s8(a, b);
-  // CHECK: st2 {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ ?v[0-9]+.8b, v[0-9]+.8b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst2_s16(int16_t *a, int16x4x2_t b) {
-  // CHECK: test_vst2_s16
+  // CHECK-LABEL: test_vst2_s16
   vst2_s16(a, b);
-  // CHECK: st2 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ ?v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst2_s32(int32_t *a, int32x2x2_t b) {
-  // CHECK: test_vst2_s32
+  // CHECK-LABEL: test_vst2_s32
   vst2_s32(a, b);
-  // CHECK: st2 {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ ?v[0-9]+.2s, v[0-9]+.2s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst2_s64(int64_t *a, int64x1x2_t b) {
-  // CHECK: test_vst2_s64
+  // CHECK-LABEL: test_vst2_s64
   vst2_s64(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{st1|st2}} {{{ ?v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst2_f16(float16_t *a, float16x4x2_t b) {
-  // CHECK: test_vst2_f16
+  // CHECK-LABEL: test_vst2_f16
   vst2_f16(a, b);
-  // CHECK: st2 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ ?v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst2_f32(float32_t *a, float32x2x2_t b) {
-  // CHECK: test_vst2_f32
+  // CHECK-LABEL: test_vst2_f32
   vst2_f32(a, b);
-  // CHECK: st2 {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ ?v[0-9]+.2s, v[0-9]+.2s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst2_f64(float64_t *a, float64x1x2_t b) {
-  // CHECK: test_vst2_f64
+  // CHECK-LABEL: test_vst2_f64
   vst2_f64(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{st1|st2}} {{{ ?v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst2_p8(poly8_t *a, poly8x8x2_t b) {
-  // CHECK: test_vst2_p8
+  // CHECK-LABEL: test_vst2_p8
   vst2_p8(a, b);
-  // CHECK: st2 {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ ?v[0-9]+.8b, v[0-9]+.8b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst2_p16(poly16_t *a, poly16x4x2_t b) {
-  // CHECK: test_vst2_p16
+  // CHECK-LABEL: test_vst2_p16
   vst2_p16(a, b);
-  // CHECK: st2 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ ?v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst3q_u8(uint8_t *a, uint8x16x3_t b) {
-  // CHECK: test_vst3q_u8
+  // CHECK-LABEL: test_vst3q_u8
   vst3q_u8(a, b);
-  // CHECK: st3 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst3q_u16(uint16_t *a, uint16x8x3_t b) {
-  // CHECK: test_vst3q_u16
+  // CHECK-LABEL: test_vst3q_u16
   vst3q_u16(a, b);
-  // CHECK: st3 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ ?v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst3q_u32(uint32_t *a, uint32x4x3_t b) {
-  // CHECK: test_vst3q_u32
+  // CHECK-LABEL: test_vst3q_u32
   vst3q_u32(a, b);
-  // CHECK: st3 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s, v{{[0-9]+}}.4s},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ ?v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst3q_u64(uint64_t *a, uint64x2x3_t b) {
-  // CHECK: test_vst3q_u64
+  // CHECK-LABEL: test_vst3q_u64
   vst3q_u64(a, b);
-  // CHECK: st3 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ ?v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst3q_s8(int8_t *a, int8x16x3_t b) {
-  // CHECK: test_vst3q_s8
+  // CHECK-LABEL: test_vst3q_s8
   vst3q_s8(a, b);
-  // CHECK: st3 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst3q_s16(int16_t *a, int16x8x3_t b) {
-  // CHECK: test_vst3q_s16
+  // CHECK-LABEL: test_vst3q_s16
   vst3q_s16(a, b);
-  // CHECK: st3 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ ?v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst3q_s32(int32_t *a, int32x4x3_t b) {
-  // CHECK: test_vst3q_s32
+  // CHECK-LABEL: test_vst3q_s32
   vst3q_s32(a, b);
-  // CHECK: st3 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s, v{{[0-9]+}}.4s},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ ?v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst3q_s64(int64_t *a, int64x2x3_t b) {
-  // CHECK: test_vst3q_s64
+  // CHECK-LABEL: test_vst3q_s64
   vst3q_s64(a, b);
-  // CHECK: st3 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ ?v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst3q_f16(float16_t *a, float16x8x3_t b) {
-  // CHECK: test_vst3q_f16
+  // CHECK-LABEL: test_vst3q_f16
   vst3q_f16(a, b);
-  // CHECK: st3 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ ?v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst3q_f32(float32_t *a, float32x4x3_t b) {
-  // CHECK: test_vst3q_f32
+  // CHECK-LABEL: test_vst3q_f32
   vst3q_f32(a, b);
-  // CHECK: st3 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s, v{{[0-9]+}}.4s},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ ?v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst3q_f64(float64_t *a, float64x2x3_t b) {
-  // CHECK: test_vst3q_f64
+  // CHECK-LABEL: test_vst3q_f64
   vst3q_f64(a, b);
-  // CHECK: st3 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ ?v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst3q_p8(poly8_t *a, poly8x16x3_t b) {
-  // CHECK: test_vst3q_p8
+  // CHECK-LABEL: test_vst3q_p8
   vst3q_p8(a, b);
-  // CHECK: st3 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst3q_p16(poly16_t *a, poly16x8x3_t b) {
-  // CHECK: test_vst3q_p16
+  // CHECK-LABEL: test_vst3q_p16
   vst3q_p16(a, b);
-  // CHECK: st3 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ ?v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst3_u8(uint8_t *a, uint8x8x3_t b) {
-  // CHECK: test_vst3_u8
+  // CHECK-LABEL: test_vst3_u8
   vst3_u8(a, b);
-  // CHECK: st3 {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b, v{{[0-9]+}}.8b},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ ?v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst3_u16(uint16_t *a, uint16x4x3_t b) {
-  // CHECK: test_vst3_u16
+  // CHECK-LABEL: test_vst3_u16
   vst3_u16(a, b);
-  // CHECK: st3 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ ?v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst3_u32(uint32_t *a, uint32x2x3_t b) {
-  // CHECK: test_vst3_u32
+  // CHECK-LABEL: test_vst3_u32
   vst3_u32(a, b);
-  // CHECK: st3 {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s, v{{[0-9]+}}.2s},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ ?v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst3_u64(uint64_t *a, uint64x1x3_t b) {
-  // CHECK: test_vst3_u64
+  // CHECK-LABEL: test_vst3_u64
   vst3_u64(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: {{st1|st3}} {{{ ?v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst3_s8(int8_t *a, int8x8x3_t b) {
-  // CHECK: test_vst3_s8
+  // CHECK-LABEL: test_vst3_s8
   vst3_s8(a, b);
-  // CHECK: st3 {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b, v{{[0-9]+}}.8b},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ ?v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst3_s16(int16_t *a, int16x4x3_t b) {
-  // CHECK: test_vst3_s16
+  // CHECK-LABEL: test_vst3_s16
   vst3_s16(a, b);
-  // CHECK: st3 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ ?v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst3_s32(int32_t *a, int32x2x3_t b) {
-  // CHECK: test_vst3_s32
+  // CHECK-LABEL: test_vst3_s32
   vst3_s32(a, b);
-  // CHECK: st3 {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s, v{{[0-9]+}}.2s},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ ?v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst3_s64(int64_t *a, int64x1x3_t b) {
-  // CHECK: test_vst3_s64
+  // CHECK-LABEL: test_vst3_s64
   vst3_s64(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: {{st1|st3}} {{{ ?v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst3_f16(float16_t *a, float16x4x3_t b) {
-  // CHECK: test_vst3_f16
+  // CHECK-LABEL: test_vst3_f16
   vst3_f16(a, b);
-  // CHECK: st3 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ ?v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst3_f32(float32_t *a, float32x2x3_t b) {
-  // CHECK: test_vst3_f32
+  // CHECK-LABEL: test_vst3_f32
   vst3_f32(a, b);
-  // CHECK: st3 {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s, v{{[0-9]+}}.2s},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ ?v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst3_f64(float64_t *a, float64x1x3_t b) {
-  // CHECK: test_vst3_f64
+  // CHECK-LABEL: test_vst3_f64
   vst3_f64(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: {{st1|st3}} {{{ ?v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst3_p8(poly8_t *a, poly8x8x3_t b) {
-  // CHECK: test_vst3_p8
+  // CHECK-LABEL: test_vst3_p8
   vst3_p8(a, b);
-  // CHECK: st3 {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b, v{{[0-9]+}}.8b},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ ?v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst3_p16(poly16_t *a, poly16x4x3_t b) {
-  // CHECK: test_vst3_p16
+  // CHECK-LABEL: test_vst3_p16
   vst3_p16(a, b);
-  // CHECK: st3 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ ?v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst4q_u8(uint8_t *a, uint8x16x4_t b) {
-  // CHECK: test_vst4q_u8
+  // CHECK-LABEL: test_vst4q_u8
   vst4q_u8(a, b);
-  // CHECK: st4 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b,
-  // v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst4q_u16(uint16_t *a, uint16x8x4_t b) {
-  // CHECK: test_vst4q_u16
+  // CHECK-LABEL: test_vst4q_u16
   vst4q_u16(a, b);
-  // CHECK: st4 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h,
-  // v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ ?v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst4q_u32(uint32_t *a, uint32x4x4_t b) {
-  // CHECK: test_vst4q_u32
+  // CHECK-LABEL: test_vst4q_u32
   vst4q_u32(a, b);
-  // CHECK: st4 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s, v{{[0-9]+}}.4s,
-  // v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ ?v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst4q_u64(uint64_t *a, uint64x2x4_t b) {
-  // CHECK: test_vst4q_u64
+  // CHECK-LABEL: test_vst4q_u64
   vst4q_u64(a, b);
-  // CHECK: st4 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d,
-  // v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ ?v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst4q_s8(int8_t *a, int8x16x4_t b) {
-  // CHECK: test_vst4q_s8
+  // CHECK-LABEL: test_vst4q_s8
   vst4q_s8(a, b);
-  // CHECK: st4 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b,
-  // v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst4q_s16(int16_t *a, int16x8x4_t b) {
-  // CHECK: test_vst4q_s16
+  // CHECK-LABEL: test_vst4q_s16
   vst4q_s16(a, b);
-  // CHECK: st4 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h,
-  // v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ ?v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst4q_s32(int32_t *a, int32x4x4_t b) {
-  // CHECK: test_vst4q_s32
+  // CHECK-LABEL: test_vst4q_s32
   vst4q_s32(a, b);
-  // CHECK: st4 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s, v{{[0-9]+}}.4s,
-  // v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ ?v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst4q_s64(int64_t *a, int64x2x4_t b) {
-  // CHECK: test_vst4q_s64
+  // CHECK-LABEL: test_vst4q_s64
   vst4q_s64(a, b);
-  // CHECK: st4 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d,
-  // v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ ?v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst4q_f16(float16_t *a, float16x8x4_t b) {
-  // CHECK: test_vst4q_f16
+  // CHECK-LABEL: test_vst4q_f16
   vst4q_f16(a, b);
-  // CHECK: st4 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h,
-  // v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ ?v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst4q_f32(float32_t *a, float32x4x4_t b) {
-  // CHECK: test_vst4q_f32
+  // CHECK-LABEL: test_vst4q_f32
   vst4q_f32(a, b);
-  // CHECK: st4 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s, v{{[0-9]+}}.4s,
-  // v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ ?v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst4q_f64(float64_t *a, float64x2x4_t b) {
-  // CHECK: test_vst4q_f64
+  // CHECK-LABEL: test_vst4q_f64
   vst4q_f64(a, b);
-  // CHECK: st4 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d,
-  // v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ ?v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst4q_p8(poly8_t *a, poly8x16x4_t b) {
-  // CHECK: test_vst4q_p8
+  // CHECK-LABEL: test_vst4q_p8
   vst4q_p8(a, b);
-  // CHECK: st4 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b,
-  // v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst4q_p16(poly16_t *a, poly16x8x4_t b) {
-  // CHECK: test_vst4q_p16
+  // CHECK-LABEL: test_vst4q_p16
   vst4q_p16(a, b);
-  // CHECK: st4 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h,
-  // v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ ?v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst4_u8(uint8_t *a, uint8x8x4_t b) {
-  // CHECK: test_vst4_u8
+  // CHECK-LABEL: test_vst4_u8
   vst4_u8(a, b);
-  // CHECK: st4 {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b, v{{[0-9]+}}.8b,
-  // v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ ?v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst4_u16(uint16_t *a, uint16x4x4_t b) {
-  // CHECK: test_vst4_u16
+  // CHECK-LABEL: test_vst4_u16
   vst4_u16(a, b);
-  // CHECK: st4 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h,
-  // v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ ?v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst4_u32(uint32_t *a, uint32x2x4_t b) {
-  // CHECK: test_vst4_u32
+  // CHECK-LABEL: test_vst4_u32
   vst4_u32(a, b);
-  // CHECK: st4 {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s, v{{[0-9]+}}.2s,
-  // v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ ?v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst4_u64(uint64_t *a, uint64x1x4_t b) {
-  // CHECK: test_vst4_u64
+  // CHECK-LABEL: test_vst4_u64
   vst4_u64(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d,
-  // v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{st1|st4}} {{{ ?v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst4_s8(int8_t *a, int8x8x4_t b) {
-  // CHECK: test_vst4_s8
+  // CHECK-LABEL: test_vst4_s8
   vst4_s8(a, b);
-  // CHECK: st4 {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b, v{{[0-9]+}}.8b,
-  // v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+// CHECK: st4 {{{ ?v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst4_s16(int16_t *a, int16x4x4_t b) {
-  // CHECK: test_vst4_s16
+  // CHECK-LABEL: test_vst4_s16
   vst4_s16(a, b);
-  // CHECK: st4 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h,
-  // v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ ?v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst4_s32(int32_t *a, int32x2x4_t b) {
-  // CHECK: test_vst4_s32
+  // CHECK-LABEL: test_vst4_s32
   vst4_s32(a, b);
-  // CHECK: st4 {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s, v{{[0-9]+}}.2s,
-  // v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ ?v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst4_s64(int64_t *a, int64x1x4_t b) {
-  // CHECK: test_vst4_s64
+  // CHECK-LABEL: test_vst4_s64
   vst4_s64(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d,
-  // v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{st1|st4}} {{{ ?v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst4_f16(float16_t *a, float16x4x4_t b) {
-  // CHECK: test_vst4_f16
+  // CHECK-LABEL: test_vst4_f16
   vst4_f16(a, b);
-  // CHECK: st4 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h,
-  // v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ ?v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst4_f32(float32_t *a, float32x2x4_t b) {
-  // CHECK: test_vst4_f32
+  // CHECK-LABEL: test_vst4_f32
   vst4_f32(a, b);
-  // CHECK: st4 {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s, v{{[0-9]+}}.2s,
-  // v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ ?v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst4_f64(float64_t *a, float64x1x4_t b) {
-  // CHECK: test_vst4_f64
+  // CHECK-LABEL: test_vst4_f64
   vst4_f64(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d,
-  // v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{st1|st4}} {{{ ?v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst4_p8(poly8_t *a, poly8x8x4_t b) {
-  // CHECK: test_vst4_p8
+  // CHECK-LABEL: test_vst4_p8
   vst4_p8(a, b);
-  // CHECK: st4 {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b, v{{[0-9]+}}.8b,
-  // v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ ?v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst4_p16(poly16_t *a, poly16x4x4_t b) {
-  // CHECK: test_vst4_p16
+  // CHECK-LABEL: test_vst4_p16
   vst4_p16(a, b);
-  // CHECK: st4 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h,
-  // v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ ?v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint8x16x2_t test_vld1q_u8_x2(uint8_t const *a) {
   // CHECK-LABEL: test_vld1q_u8_x2
   return vld1q_u8_x2(a);
-  // CHECK: ld1 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.16b, v[0-9]+.16b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint16x8x2_t test_vld1q_u16_x2(uint16_t const *a) {
   // CHECK-LABEL: test_vld1q_u16_x2
   return vld1q_u16_x2(a);
-  // CHECK: ld1 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint32x4x2_t test_vld1q_u32_x2(uint32_t const *a) {
   // CHECK-LABEL: test_vld1q_u32_x2
   return vld1q_u32_x2(a);
-  // CHECK: ld1 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.4s, v[0-9]+.4s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint64x2x2_t test_vld1q_u64_x2(uint64_t const *a) {
   // CHECK-LABEL: test_vld1q_u64_x2
   return vld1q_u64_x2(a);
-  // CHECK: ld1 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int8x16x2_t test_vld1q_s8_x2(int8_t const *a) {
   // CHECK-LABEL: test_vld1q_s8_x2
   return vld1q_s8_x2(a);
-  // CHECK: ld1 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.16b, v[0-9]+.16b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int16x8x2_t test_vld1q_s16_x2(int16_t const *a) {
   // CHECK-LABEL: test_vld1q_s16_x2
   return vld1q_s16_x2(a);
-  // CHECK: ld1 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int32x4x2_t test_vld1q_s32_x2(int32_t const *a) {
   // CHECK-LABEL: test_vld1q_s32_x2
   return vld1q_s32_x2(a);
-  // CHECK: ld1 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.4s, v[0-9]+.4s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int64x2x2_t test_vld1q_s64_x2(int64_t const *a) {
   // CHECK-LABEL: test_vld1q_s64_x2
   return vld1q_s64_x2(a);
-  // CHECK: ld1 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 float16x8x2_t test_vld1q_f16_x2(float16_t const *a) {
   // CHECK-LABEL: test_vld1q_f16_x2
   return vld1q_f16_x2(a);
-  // CHECK: ld1 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 float32x4x2_t test_vld1q_f32_x2(float32_t const *a) {
   // CHECK-LABEL: test_vld1q_f32_x2
   return vld1q_f32_x2(a);
-  // CHECK: ld1 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.4s, v[0-9]+.4s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 float64x2x2_t test_vld1q_f64_x2(float64_t const *a) {
   // CHECK-LABEL: test_vld1q_f64_x2
   return vld1q_f64_x2(a);
-  // CHECK: ld1 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 poly8x16x2_t test_vld1q_p8_x2(poly8_t const *a) {
   // CHECK-LABEL: test_vld1q_p8_x2
   return vld1q_p8_x2(a);
-  // CHECK: ld1 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.16b, v[0-9]+.16b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 poly16x8x2_t test_vld1q_p16_x2(poly16_t const *a) {
   // CHECK-LABEL: test_vld1q_p16_x2
   return vld1q_p16_x2(a);
-  // CHECK: ld1 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 poly64x2x2_t test_vld1q_p64_x2(poly64_t const *a) {
   // CHECK-LABEL: test_vld1q_p64_x2
   return vld1q_p64_x2(a);
-  // CHECK: ld1 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint8x8x2_t test_vld1_u8_x2(uint8_t const *a) {
   // CHECK-LABEL: test_vld1_u8_x2
   return vld1_u8_x2(a);
-  // CHECK: ld1 {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.8b, v[0-9]+.8b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint16x4x2_t test_vld1_u16_x2(uint16_t const *a) {
   // CHECK-LABEL: test_vld1_u16_x2
   return vld1_u16_x2(a);
-  // CHECK: ld1 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint32x2x2_t test_vld1_u32_x2(uint32_t const *a) {
   // CHECK-LABEL: test_vld1_u32_x2
   return vld1_u32_x2(a);
-  // CHECK: ld1 {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.2s, v[0-9]+.2s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint64x1x2_t test_vld1_u64_x2(uint64_t const *a) {
   // CHECK-LABEL: test_vld1_u64_x2
   return vld1_u64_x2(a);
-  // CHECK: ld1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int8x8x2_t test_vld1_s8_x2(int8_t const *a) {
   // CHECK-LABEL: test_vld1_s8_x2
   return vld1_s8_x2(a);
-  // CHECK: ld1 {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.8b, v[0-9]+.8b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int16x4x2_t test_vld1_s16_x2(int16_t const *a) {
   // CHECK-LABEL: test_vld1_s16_x2
   return vld1_s16_x2(a);
-  // CHECK: ld1 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int32x2x2_t test_vld1_s32_x2(int32_t const *a) {
   // CHECK-LABEL: test_vld1_s32_x2
   return vld1_s32_x2(a);
-  // CHECK: ld1 {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.2s, v[0-9]+.2s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int64x1x2_t test_vld1_s64_x2(int64_t const *a) {
   // CHECK-LABEL: test_vld1_s64_x2
   return vld1_s64_x2(a);
-  // CHECK: ld1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 float16x4x2_t test_vld1_f16_x2(float16_t const *a) {
   // CHECK-LABEL: test_vld1_f16_x2
   return vld1_f16_x2(a);
-  // CHECK: ld1 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 float32x2x2_t test_vld1_f32_x2(float32_t const *a) {
   // CHECK-LABEL: test_vld1_f32_x2
   return vld1_f32_x2(a);
-  // CHECK: ld1 {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.2s, v[0-9]+.2s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 float64x1x2_t test_vld1_f64_x2(float64_t const *a) {
   // CHECK-LABEL: test_vld1_f64_x2
   return vld1_f64_x2(a);
-  // CHECK: ld1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 poly8x8x2_t test_vld1_p8_x2(poly8_t const *a) {
   // CHECK-LABEL: test_vld1_p8_x2
   return vld1_p8_x2(a);
-  // CHECK: ld1 {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.8b, v[0-9]+.8b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 poly16x4x2_t test_vld1_p16_x2(poly16_t const *a) {
   // CHECK-LABEL: test_vld1_p16_x2
   return vld1_p16_x2(a);
-  // CHECK: ld1 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 poly64x1x2_t test_vld1_p64_x2(poly64_t const *a) {
   // CHECK-LABEL: test_vld1_p64_x2
   return vld1_p64_x2(a);
-  // CHECK: ld1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint8x16x3_t test_vld1q_u8_x3(uint8_t const *a) {
   // CHECK-LABEL: test_vld1q_u8_x3
   return vld1q_u8_x3(a);
-  // CHECK: ld1 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint16x8x3_t test_vld1q_u16_x3(uint16_t const *a) {
   // CHECK-LABEL: test_vld1q_u16_x3
   return vld1q_u16_x3(a);
-  // CHECK: ld1 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint32x4x3_t test_vld1q_u32_x3(uint32_t const *a) {
   // CHECK-LABEL: test_vld1q_u32_x3
   return vld1q_u32_x3(a);
-  // CHECK: ld1 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s, v{{[0-9]+}}.4s},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint64x2x3_t test_vld1q_u64_x3(uint64_t const *a) {
   // CHECK-LABEL: test_vld1q_u64_x3
   return vld1q_u64_x3(a);
-  // CHECK: ld1 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int8x16x3_t test_vld1q_s8_x3(int8_t const *a) {
   // CHECK-LABEL: test_vld1q_s8_x3
   return vld1q_s8_x3(a);
-  // CHECK: ld1 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int16x8x3_t test_vld1q_s16_x3(int16_t const *a) {
   // CHECK-LABEL: test_vld1q_s16_x3
   return vld1q_s16_x3(a);
-  // CHECK: ld1 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int32x4x3_t test_vld1q_s32_x3(int32_t const *a) {
   // CHECK-LABEL: test_vld1q_s32_x3
   return vld1q_s32_x3(a);
-  // CHECK: ld1 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s, v{{[0-9]+}}.4s},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int64x2x3_t test_vld1q_s64_x3(int64_t const *a) {
   // CHECK-LABEL: test_vld1q_s64_x3
   return vld1q_s64_x3(a);
-  // CHECK: ld1 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 float16x8x3_t test_vld1q_f16_x3(float16_t const *a) {
   // CHECK-LABEL: test_vld1q_f16_x3
   return vld1q_f16_x3(a);
-  // CHECK: ld1 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 float32x4x3_t test_vld1q_f32_x3(float32_t const *a) {
   // CHECK-LABEL: test_vld1q_f32_x3
   return vld1q_f32_x3(a);
-  // CHECK: ld1 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s, v{{[0-9]+}}.4s},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 float64x2x3_t test_vld1q_f64_x3(float64_t const *a) {
   // CHECK-LABEL: test_vld1q_f64_x3
   return vld1q_f64_x3(a);
-  // CHECK: ld1 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 poly8x16x3_t test_vld1q_p8_x3(poly8_t const *a) {
   // CHECK-LABEL: test_vld1q_p8_x3
   return vld1q_p8_x3(a);
-  // CHECK: ld1 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 poly16x8x3_t test_vld1q_p16_x3(poly16_t const *a) {
   // CHECK-LABEL: test_vld1q_p16_x3
   return vld1q_p16_x3(a);
-  // CHECK: ld1 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 poly64x2x3_t test_vld1q_p64_x3(poly64_t const *a) {
   // CHECK-LABEL: test_vld1q_p64_x3
   return vld1q_p64_x3(a);
-  // CHECK: ld1 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint8x8x3_t test_vld1_u8_x3(uint8_t const *a) {
   // CHECK-LABEL: test_vld1_u8_x3
   return vld1_u8_x3(a);
-  // CHECK: ld1 {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b, v{{[0-9]+}}.8b},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint16x4x3_t test_vld1_u16_x3(uint16_t const *a) {
   // CHECK-LABEL: test_vld1_u16_x3
   return vld1_u16_x3(a);
-  // CHECK: ld1 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint32x2x3_t test_vld1_u32_x3(uint32_t const *a) {
   // CHECK-LABEL: test_vld1_u32_x3
   return vld1_u32_x3(a);
-  // CHECK: ld1 {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s, v{{[0-9]+}}.2s},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint64x1x3_t test_vld1_u64_x3(uint64_t const *a) {
   // CHECK-LABEL: test_vld1_u64_x3
   return vld1_u64_x3(a);
-  // CHECK: ld1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int8x8x3_t test_vld1_s8_x3(int8_t const *a) {
   // CHECK-LABEL: test_vld1_s8_x3
   return vld1_s8_x3(a);
-  // CHECK: ld1 {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b, v{{[0-9]+}}.8b},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int16x4x3_t test_vld1_s16_x3(int16_t const *a) {
   // CHECK-LABEL: test_vld1_s16_x3
   return vld1_s16_x3(a);
-  // CHECK: ld1 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int32x2x3_t test_vld1_s32_x3(int32_t const *a) {
   // CHECK-LABEL: test_vld1_s32_x3
   return vld1_s32_x3(a);
-  // CHECK: ld1 {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s, v{{[0-9]+}}.2s},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int64x1x3_t test_vld1_s64_x3(int64_t const *a) {
   // CHECK-LABEL: test_vld1_s64_x3
   return vld1_s64_x3(a);
-  // CHECK: ld1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 float16x4x3_t test_vld1_f16_x3(float16_t const *a) {
   // CHECK-LABEL: test_vld1_f16_x3
   return vld1_f16_x3(a);
-  // CHECK: ld1 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 float32x2x3_t test_vld1_f32_x3(float32_t const *a) {
   // CHECK-LABEL: test_vld1_f32_x3
   return vld1_f32_x3(a);
-  // CHECK: ld1 {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s, v{{[0-9]+}}.2s},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 float64x1x3_t test_vld1_f64_x3(float64_t const *a) {
   // CHECK-LABEL: test_vld1_f64_x3
   return vld1_f64_x3(a);
-  // CHECK: ld1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 poly8x8x3_t test_vld1_p8_x3(poly8_t const *a) {
   // CHECK-LABEL: test_vld1_p8_x3
   return vld1_p8_x3(a);
-  // CHECK: ld1 {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b, v{{[0-9]+}}.8b},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 poly16x4x3_t test_vld1_p16_x3(poly16_t const *a) {
   // CHECK-LABEL: test_vld1_p16_x3
   return vld1_p16_x3(a);
-  // CHECK: ld1 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 poly64x1x3_t test_vld1_p64_x3(poly64_t const *a) {
   // CHECK-LABEL: test_vld1_p64_x3
   return vld1_p64_x3(a);
-  // CHECK: ld1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint8x16x4_t test_vld1q_u8_x4(uint8_t const *a) {
   // CHECK-LABEL: test_vld1q_u8_x4
   return vld1q_u8_x4(a);
-  // CHECK: ld1 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b,
-  // v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint16x8x4_t test_vld1q_u16_x4(uint16_t const *a) {
   // CHECK-LABEL: test_vld1q_u16_x4
   return vld1q_u16_x4(a);
-  // CHECK: ld1 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h,
-  // v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint32x4x4_t test_vld1q_u32_x4(uint32_t const *a) {
   // CHECK-LABEL: test_vld1q_u32_x4
   return vld1q_u32_x4(a);
-  // CHECK: ld1 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s, v{{[0-9]+}}.4s,
-  // v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint64x2x4_t test_vld1q_u64_x4(uint64_t const *a) {
   // CHECK-LABEL: test_vld1q_u64_x4
   return vld1q_u64_x4(a);
-  // CHECK: ld1 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d,
-  // v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int8x16x4_t test_vld1q_s8_x4(int8_t const *a) {
   // CHECK-LABEL: test_vld1q_s8_x4
   return vld1q_s8_x4(a);
-  // CHECK: ld1 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b,
-  // v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int16x8x4_t test_vld1q_s16_x4(int16_t const *a) {
   // CHECK-LABEL: test_vld1q_s16_x4
   return vld1q_s16_x4(a);
-  // CHECK: ld1 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h,
-  // v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int32x4x4_t test_vld1q_s32_x4(int32_t const *a) {
   // CHECK-LABEL: test_vld1q_s32_x4
   return vld1q_s32_x4(a);
-  // CHECK: ld1 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s, v{{[0-9]+}}.4s,
-  // v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int64x2x4_t test_vld1q_s64_x4(int64_t const *a) {
   // CHECK-LABEL: test_vld1q_s64_x4
   return vld1q_s64_x4(a);
-  // CHECK: ld1 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d,
-  // v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 float16x8x4_t test_vld1q_f16_x4(float16_t const *a) {
   // CHECK-LABEL: test_vld1q_f16_x4
   return vld1q_f16_x4(a);
-  // CHECK: ld1 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h,
-  // v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 float32x4x4_t test_vld1q_f32_x4(float32_t const *a) {
   // CHECK-LABEL: test_vld1q_f32_x4
   return vld1q_f32_x4(a);
-  // CHECK: ld1 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s, v{{[0-9]+}}.4s,
-  // v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 float64x2x4_t test_vld1q_f64_x4(float64_t const *a) {
   // CHECK-LABEL: test_vld1q_f64_x4
   return vld1q_f64_x4(a);
-  // CHECK: ld1 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d,
-  // v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 poly8x16x4_t test_vld1q_p8_x4(poly8_t const *a) {
   // CHECK-LABEL: test_vld1q_p8_x4
   return vld1q_p8_x4(a);
-  // CHECK: ld1 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b,
-  // v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 poly16x8x4_t test_vld1q_p16_x4(poly16_t const *a) {
   // CHECK-LABEL: test_vld1q_p16_x4
   return vld1q_p16_x4(a);
-  // CHECK: ld1 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h,
-  // v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 poly64x2x4_t test_vld1q_p64_x4(poly64_t const *a) {
   // CHECK-LABEL: test_vld1q_p64_x4
   return vld1q_p64_x4(a);
-  // CHECK: ld1 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d,
-  // v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint8x8x4_t test_vld1_u8_x4(uint8_t const *a) {
   // CHECK-LABEL: test_vld1_u8_x4
   return vld1_u8_x4(a);
-  // CHECK: ld1 {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b, v{{[0-9]+}}.8b,
-  // v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint16x4x4_t test_vld1_u16_x4(uint16_t const *a) {
   // CHECK-LABEL: test_vld1_u16_x4
   return vld1_u16_x4(a);
-  // CHECK: ld1 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h,
-  // v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint32x2x4_t test_vld1_u32_x4(uint32_t const *a) {
   // CHECK-LABEL: test_vld1_u32_x4
   return vld1_u32_x4(a);
-  // CHECK: ld1 {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s, v{{[0-9]+}}.2s,
-  // v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 uint64x1x4_t test_vld1_u64_x4(uint64_t const *a) {
   // CHECK-LABEL: test_vld1_u64_x4
   return vld1_u64_x4(a);
-  // CHECK: ld1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d,
-  // v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int8x8x4_t test_vld1_s8_x4(int8_t const *a) {
   // CHECK-LABEL: test_vld1_s8_x4
   return vld1_s8_x4(a);
-  // CHECK: ld1 {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b, v{{[0-9]+}}.8b,
-  // v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int16x4x4_t test_vld1_s16_x4(int16_t const *a) {
   // CHECK-LABEL: test_vld1_s16_x4
   return vld1_s16_x4(a);
-  // CHECK: ld1 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h,
-  // v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int32x2x4_t test_vld1_s32_x4(int32_t const *a) {
   // CHECK-LABEL: test_vld1_s32_x4
   return vld1_s32_x4(a);
-  // CHECK: ld1 {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s, v{{[0-9]+}}.2s,
-  // v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int64x1x4_t test_vld1_s64_x4(int64_t const *a) {
   // CHECK-LABEL: test_vld1_s64_x4
   return vld1_s64_x4(a);
-  // CHECK: ld1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d,
-  // v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 float16x4x4_t test_vld1_f16_x4(float16_t const *a) {
   // CHECK-LABEL: test_vld1_f16_x4
   return vld1_f16_x4(a);
-  // CHECK: ld1 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h,
-  // v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 float32x2x4_t test_vld1_f32_x4(float32_t const *a) {
   // CHECK-LABEL: test_vld1_f32_x4
   return vld1_f32_x4(a);
-  // CHECK: ld1 {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s, v{{[0-9]+}}.2s,
-  // v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 float64x1x4_t test_vld1_f64_x4(float64_t const *a) {
   // CHECK-LABEL: test_vld1_f64_x4
   return vld1_f64_x4(a);
-  // CHECK: ld1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d,
-  // v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 poly8x8x4_t test_vld1_p8_x4(poly8_t const *a) {
   // CHECK-LABEL: test_vld1_p8_x4
   return vld1_p8_x4(a);
-  // CHECK: ld1 {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b, v{{[0-9]+}}.8b,
-  // v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 poly16x4x4_t test_vld1_p16_x4(poly16_t const *a) {
   // CHECK-LABEL: test_vld1_p16_x4
   return vld1_p16_x4(a);
-  // CHECK: ld1 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h,
-  // v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 poly64x1x4_t test_vld1_p64_x4(poly64_t const *a) {
   // CHECK-LABEL: test_vld1_p64_x4
   return vld1_p64_x4(a);
-  // CHECK: ld1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d,
-  // v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ ?v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_u8_x2(uint8_t *a, uint8x16x2_t b) {
-  // CHECK: test_vst1q_u8_x2
+  // CHECK-LABEL: test_vst1q_u8_x2
   vst1q_u8_x2(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.16b, v[0-9]+.16b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_u16_x2(uint16_t *a, uint16x8x2_t b) {
-  // CHECK: test_vst1q_u16_x2
+  // CHECK-LABEL: test_vst1q_u16_x2
   vst1q_u16_x2(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_u32_x2(uint32_t *a, uint32x4x2_t b) {
-  // CHECK: test_vst1q_u32_x2
+  // CHECK-LABEL: test_vst1q_u32_x2
   vst1q_u32_x2(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.4s, v[0-9]+.4s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_u64_x2(uint64_t *a, uint64x2x2_t b) {
-  // CHECK: test_vst1q_u64_x2
+  // CHECK-LABEL: test_vst1q_u64_x2
   vst1q_u64_x2(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_s8_x2(int8_t *a, int8x16x2_t b) {
-  // CHECK: test_vst1q_s8_x2
+  // CHECK-LABEL: test_vst1q_s8_x2
   vst1q_s8_x2(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.16b, v[0-9]+.16b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_s16_x2(int16_t *a, int16x8x2_t b) {
-  // CHECK: test_vst1q_s16_x2
+  // CHECK-LABEL: test_vst1q_s16_x2
   vst1q_s16_x2(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_s32_x2(int32_t *a, int32x4x2_t b) {
-  // CHECK: test_vst1q_s32_x2
+  // CHECK-LABEL: test_vst1q_s32_x2
   vst1q_s32_x2(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.4s, v[0-9]+.4s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_s64_x2(int64_t *a, int64x2x2_t b) {
-  // CHECK: test_vst1q_s64_x2
+  // CHECK-LABEL: test_vst1q_s64_x2
   vst1q_s64_x2(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_f16_x2(float16_t *a, float16x8x2_t b) {
-  // CHECK: test_vst1q_f16_x2
+  // CHECK-LABEL: test_vst1q_f16_x2
   vst1q_f16_x2(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_f32_x2(float32_t *a, float32x4x2_t b) {
-  // CHECK: test_vst1q_f32_x2
+  // CHECK-LABEL: test_vst1q_f32_x2
   vst1q_f32_x2(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.4s, v[0-9]+.4s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_f64_x2(float64_t *a, float64x2x2_t b) {
-  // CHECK: test_vst1q_f64_x2
+  // CHECK-LABEL: test_vst1q_f64_x2
   vst1q_f64_x2(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_p8_x2(poly8_t *a, poly8x16x2_t b) {
-  // CHECK: test_vst1q_p8_x2
+  // CHECK-LABEL: test_vst1q_p8_x2
   vst1q_p8_x2(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.16b, v[0-9]+.16b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_p16_x2(poly16_t *a, poly16x8x2_t b) {
-  // CHECK: test_vst1q_p16_x2
+  // CHECK-LABEL: test_vst1q_p16_x2
   vst1q_p16_x2(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_p64_x2(poly64_t *a, poly64x2x2_t b) {
-  // CHECK: test_vst1q_p64_x2
+  // CHECK-LABEL: test_vst1q_p64_x2
   vst1q_p64_x2(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_u8_x2(uint8_t *a, uint8x8x2_t b) {
-  // CHECK: test_vst1_u8_x2
+  // CHECK-LABEL: test_vst1_u8_x2
   vst1_u8_x2(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.8b, v[0-9]+.8b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_u16_x2(uint16_t *a, uint16x4x2_t b) {
-  // CHECK: test_vst1_u16_x2
+  // CHECK-LABEL: test_vst1_u16_x2
   vst1_u16_x2(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_u32_x2(uint32_t *a, uint32x2x2_t b) {
-  // CHECK: test_vst1_u32_x2
+  // CHECK-LABEL: test_vst1_u32_x2
   vst1_u32_x2(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.2s, v[0-9]+.2s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_u64_x2(uint64_t *a, uint64x1x2_t b) {
-  // CHECK: test_vst1_u64_x2
+  // CHECK-LABEL: test_vst1_u64_x2
   vst1_u64_x2(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_s8_x2(int8_t *a, int8x8x2_t b) {
-  // CHECK: test_vst1_s8_x2
+  // CHECK-LABEL: test_vst1_s8_x2
   vst1_s8_x2(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.8b, v[0-9]+.8b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_s16_x2(int16_t *a, int16x4x2_t b) {
-  // CHECK: test_vst1_s16_x2
+  // CHECK-LABEL: test_vst1_s16_x2
   vst1_s16_x2(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_s32_x2(int32_t *a, int32x2x2_t b) {
-  // CHECK: test_vst1_s32_x2
+  // CHECK-LABEL: test_vst1_s32_x2
   vst1_s32_x2(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.2s, v[0-9]+.2s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_s64_x2(int64_t *a, int64x1x2_t b) {
-  // CHECK: test_vst1_s64_x2
+  // CHECK-LABEL: test_vst1_s64_x2
   vst1_s64_x2(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_f16_x2(float16_t *a, float16x4x2_t b) {
-  // CHECK: test_vst1_f16_x2
+  // CHECK-LABEL: test_vst1_f16_x2
   vst1_f16_x2(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_f32_x2(float32_t *a, float32x2x2_t b) {
-  // CHECK: test_vst1_f32_x2
+  // CHECK-LABEL: test_vst1_f32_x2
   vst1_f32_x2(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.2s, v[0-9]+.2s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_f64_x2(float64_t *a, float64x1x2_t b) {
-  // CHECK: test_vst1_f64_x2
+  // CHECK-LABEL: test_vst1_f64_x2
   vst1_f64_x2(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_p8_x2(poly8_t *a, poly8x8x2_t b) {
-  // CHECK: test_vst1_p8_x2
+  // CHECK-LABEL: test_vst1_p8_x2
   vst1_p8_x2(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.8b, v[0-9]+.8b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_p16_x2(poly16_t *a, poly16x4x2_t b) {
-  // CHECK: test_vst1_p16_x2
+  // CHECK-LABEL: test_vst1_p16_x2
   vst1_p16_x2(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_p64_x2(poly64_t *a, poly64x1x2_t b) {
-  // CHECK: test_vst1_p64_x2
+  // CHECK-LABEL: test_vst1_p64_x2
   vst1_p64_x2(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_u8_x3(uint8_t *a, uint8x16x3_t b) {
-  // CHECK: test_vst1q_u8_x3
+  // CHECK-LABEL: test_vst1q_u8_x3
   vst1q_u8_x3(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_u16_x3(uint16_t *a, uint16x8x3_t b) {
-  // CHECK: test_vst1q_u16_x3
+  // CHECK-LABEL: test_vst1q_u16_x3
   vst1q_u16_x3(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_u32_x3(uint32_t *a, uint32x4x3_t b) {
-  // CHECK: test_vst1q_u32_x3
+  // CHECK-LABEL: test_vst1q_u32_x3
   vst1q_u32_x3(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s, v{{[0-9]+}}.4s},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_u64_x3(uint64_t *a, uint64x2x3_t b) {
-  // CHECK: test_vst1q_u64_x3
+  // CHECK-LABEL: test_vst1q_u64_x3
   vst1q_u64_x3(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_s8_x3(int8_t *a, int8x16x3_t b) {
-  // CHECK: test_vst1q_s8_x3
+  // CHECK-LABEL: test_vst1q_s8_x3
   vst1q_s8_x3(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_s16_x3(int16_t *a, int16x8x3_t b) {
-  // CHECK: test_vst1q_s16_x3
+  // CHECK-LABEL: test_vst1q_s16_x3
   vst1q_s16_x3(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_s32_x3(int32_t *a, int32x4x3_t b) {
-  // CHECK: test_vst1q_s32_x3
+  // CHECK-LABEL: test_vst1q_s32_x3
   vst1q_s32_x3(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s, v{{[0-9]+}}.4s},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_s64_x3(int64_t *a, int64x2x3_t b) {
-  // CHECK: test_vst1q_s64_x3
+  // CHECK-LABEL: test_vst1q_s64_x3
   vst1q_s64_x3(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_f16_x3(float16_t *a, float16x8x3_t b) {
-  // CHECK: test_vst1q_f16_x3
+  // CHECK-LABEL: test_vst1q_f16_x3
   vst1q_f16_x3(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_f32_x3(float32_t *a, float32x4x3_t b) {
-  // CHECK: test_vst1q_f32_x3
+  // CHECK-LABEL: test_vst1q_f32_x3
   vst1q_f32_x3(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s, v{{[0-9]+}}.4s},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_f64_x3(float64_t *a, float64x2x3_t b) {
-  // CHECK: test_vst1q_f64_x3
+  // CHECK-LABEL: test_vst1q_f64_x3
   vst1q_f64_x3(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_p8_x3(poly8_t *a, poly8x16x3_t b) {
-  // CHECK: test_vst1q_p8_x3
+  // CHECK-LABEL: test_vst1q_p8_x3
   vst1q_p8_x3(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_p16_x3(poly16_t *a, poly16x8x3_t b) {
-  // CHECK: test_vst1q_p16_x3
+  // CHECK-LABEL: test_vst1q_p16_x3
   vst1q_p16_x3(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_p64_x3(poly64_t *a, poly64x2x3_t b) {
-  // CHECK: test_vst1q_p64_x3
+  // CHECK-LABEL: test_vst1q_p64_x3
   vst1q_p64_x3(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_u8_x3(uint8_t *a, uint8x8x3_t b) {
-  // CHECK: test_vst1_u8_x3
+  // CHECK-LABEL: test_vst1_u8_x3
   vst1_u8_x3(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b, v{{[0-9]+}}.8b},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_u16_x3(uint16_t *a, uint16x4x3_t b) {
-  // CHECK: test_vst1_u16_x3
+  // CHECK-LABEL: test_vst1_u16_x3
   vst1_u16_x3(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_u32_x3(uint32_t *a, uint32x2x3_t b) {
-  // CHECK: test_vst1_u32_x3
+  // CHECK-LABEL: test_vst1_u32_x3
   vst1_u32_x3(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s, v{{[0-9]+}}.2s},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_u64_x3(uint64_t *a, uint64x1x3_t b) {
-  // CHECK: test_vst1_u64_x3
+  // CHECK-LABEL: test_vst1_u64_x3
   vst1_u64_x3(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_s8_x3(int8_t *a, int8x8x3_t b) {
-  // CHECK: test_vst1_s8_x3
+  // CHECK-LABEL: test_vst1_s8_x3
   vst1_s8_x3(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b, v{{[0-9]+}}.8b},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_s16_x3(int16_t *a, int16x4x3_t b) {
-  // CHECK: test_vst1_s16_x3
+  // CHECK-LABEL: test_vst1_s16_x3
   vst1_s16_x3(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_s32_x3(int32_t *a, int32x2x3_t b) {
-  // CHECK: test_vst1_s32_x3
+  // CHECK-LABEL: test_vst1_s32_x3
   vst1_s32_x3(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s, v{{[0-9]+}}.2s},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_s64_x3(int64_t *a, int64x1x3_t b) {
-  // CHECK: test_vst1_s64_x3
+  // CHECK-LABEL: test_vst1_s64_x3
   vst1_s64_x3(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_f16_x3(float16_t *a, float16x4x3_t b) {
-  // CHECK: test_vst1_f16_x3
+  // CHECK-LABEL: test_vst1_f16_x3
   vst1_f16_x3(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_f32_x3(float32_t *a, float32x2x3_t b) {
-  // CHECK: test_vst1_f32_x3
+  // CHECK-LABEL: test_vst1_f32_x3
   vst1_f32_x3(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s, v{{[0-9]+}}.2s},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_f64_x3(float64_t *a, float64x1x3_t b) {
-  // CHECK: test_vst1_f64_x3
+  // CHECK-LABEL: test_vst1_f64_x3
   vst1_f64_x3(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_p8_x3(poly8_t *a, poly8x8x3_t b) {
-  // CHECK: test_vst1_p8_x3
+  // CHECK-LABEL: test_vst1_p8_x3
   vst1_p8_x3(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b, v{{[0-9]+}}.8b},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_p16_x3(poly16_t *a, poly16x4x3_t b) {
-  // CHECK: test_vst1_p16_x3
+  // CHECK-LABEL: test_vst1_p16_x3
   vst1_p16_x3(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_p64_x3(poly64_t *a, poly64x1x3_t b) {
-  // CHECK: test_vst1_p64_x3
+  // CHECK-LABEL: test_vst1_p64_x3
   vst1_p64_x3(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d},
-  // [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_u8_x4(uint8_t *a, uint8x16x4_t b) {
-  // CHECK: test_vst1q_u8_x4
+  // CHECK-LABEL: test_vst1q_u8_x4
   vst1q_u8_x4(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b,
-  // v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_u16_x4(uint16_t *a, uint16x8x4_t b) {
-  // CHECK: test_vst1q_u16_x4
+  // CHECK-LABEL: test_vst1q_u16_x4
   vst1q_u16_x4(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h,
-  // v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_u32_x4(uint32_t *a, uint32x4x4_t b) {
-  // CHECK: test_vst1q_u32_x4
+  // CHECK-LABEL: test_vst1q_u32_x4
   vst1q_u32_x4(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s, v{{[0-9]+}}.4s,
-  // v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_u64_x4(uint64_t *a, uint64x2x4_t b) {
-  // CHECK: test_vst1q_u64_x4
+  // CHECK-LABEL: test_vst1q_u64_x4
   vst1q_u64_x4(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d,
-  // v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_s8_x4(int8_t *a, int8x16x4_t b) {
-  // CHECK: test_vst1q_s8_x4
+  // CHECK-LABEL: test_vst1q_s8_x4
   vst1q_s8_x4(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b,
-  // v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_s16_x4(int16_t *a, int16x8x4_t b) {
-  // CHECK: test_vst1q_s16_x4
+  // CHECK-LABEL: test_vst1q_s16_x4
   vst1q_s16_x4(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h,
-  // v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_s32_x4(int32_t *a, int32x4x4_t b) {
-  // CHECK: test_vst1q_s32_x4
+  // CHECK-LABEL: test_vst1q_s32_x4
   vst1q_s32_x4(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s, v{{[0-9]+}}.4s,
-  // v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_s64_x4(int64_t *a, int64x2x4_t b) {
-  // CHECK: test_vst1q_s64_x4
+  // CHECK-LABEL: test_vst1q_s64_x4
   vst1q_s64_x4(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d,
-  // v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_f16_x4(float16_t *a, float16x8x4_t b) {
-  // CHECK: test_vst1q_f16_x4
+  // CHECK-LABEL: test_vst1q_f16_x4
   vst1q_f16_x4(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h,
-  // v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_f32_x4(float32_t *a, float32x4x4_t b) {
-  // CHECK: test_vst1q_f32_x4
+  // CHECK-LABEL: test_vst1q_f32_x4
   vst1q_f32_x4(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s, v{{[0-9]+}}.4s,
-  // v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_f64_x4(float64_t *a, float64x2x4_t b) {
-  // CHECK: test_vst1q_f64_x4
+  // CHECK-LABEL: test_vst1q_f64_x4
   vst1q_f64_x4(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d,
-  // v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_p8_x4(poly8_t *a, poly8x16x4_t b) {
-  // CHECK: test_vst1q_p8_x4
+  // CHECK-LABEL: test_vst1q_p8_x4
   vst1q_p8_x4(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b,
-  // v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_p16_x4(poly16_t *a, poly16x8x4_t b) {
-  // CHECK: test_vst1q_p16_x4
+  // CHECK-LABEL: test_vst1q_p16_x4
   vst1q_p16_x4(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h,
-  // v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_p64_x4(poly64_t *a, poly64x2x4_t b) {
-  // CHECK: test_vst1q_p64_x4
+  // CHECK-LABEL: test_vst1q_p64_x4
   vst1q_p64_x4(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d,
-  // v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_u8_x4(uint8_t *a, uint8x8x4_t b) {
-  // CHECK: test_vst1_u8_x4
+  // CHECK-LABEL: test_vst1_u8_x4
   vst1_u8_x4(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b, v{{[0-9]+}}.8b,
-  // v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_u16_x4(uint16_t *a, uint16x4x4_t b) {
-  // CHECK: test_vst1_u16_x4
+  // CHECK-LABEL: test_vst1_u16_x4
   vst1_u16_x4(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h,
-  // v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_u32_x4(uint32_t *a, uint32x2x4_t b) {
-  // CHECK: test_vst1_u32_x4
+  // CHECK-LABEL: test_vst1_u32_x4
   vst1_u32_x4(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s, v{{[0-9]+}}.2s,
-  // v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_u64_x4(uint64_t *a, uint64x1x4_t b) {
-  // CHECK: test_vst1_u64_x4
+  // CHECK-LABEL: test_vst1_u64_x4
   vst1_u64_x4(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d,
-  // v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_s8_x4(int8_t *a, int8x8x4_t b) {
-  // CHECK: test_vst1_s8_x4
+  // CHECK-LABEL: test_vst1_s8_x4
   vst1_s8_x4(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b, v{{[0-9]+}}.8b,
-  // v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_s16_x4(int16_t *a, int16x4x4_t b) {
-  // CHECK: test_vst1_s16_x4
+  // CHECK-LABEL: test_vst1_s16_x4
   vst1_s16_x4(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h,
-  // v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_s32_x4(int32_t *a, int32x2x4_t b) {
-  // CHECK: test_vst1_s32_x4
+  // CHECK-LABEL: test_vst1_s32_x4
   vst1_s32_x4(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s, v{{[0-9]+}}.2s,
-  // v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_s64_x4(int64_t *a, int64x1x4_t b) {
-  // CHECK: test_vst1_s64_x4
+  // CHECK-LABEL: test_vst1_s64_x4
   vst1_s64_x4(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d,
-  // v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_f16_x4(float16_t *a, float16x4x4_t b) {
-  // CHECK: test_vst1_f16_x4
+  // CHECK-LABEL: test_vst1_f16_x4
   vst1_f16_x4(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h,
-  // v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_f32_x4(float32_t *a, float32x2x4_t b) {
-  // CHECK: test_vst1_f32_x4
+  // CHECK-LABEL: test_vst1_f32_x4
   vst1_f32_x4(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s, v{{[0-9]+}}.2s,
-  // v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_f64_x4(float64_t *a, float64x1x4_t b) {
-  // CHECK: test_vst1_f64_x4
+  // CHECK-LABEL: test_vst1_f64_x4
   vst1_f64_x4(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d,
-  // v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_p8_x4(poly8_t *a, poly8x8x4_t b) {
-  // CHECK: test_vst1_p8_x4
+  // CHECK-LABEL: test_vst1_p8_x4
   vst1_p8_x4(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b, v{{[0-9]+}}.8b,
-  // v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_p16_x4(poly16_t *a, poly16x4x4_t b) {
-  // CHECK: test_vst1_p16_x4
+  // CHECK-LABEL: test_vst1_p16_x4
   vst1_p16_x4(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h,
-  // v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h ?}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_p64_x4(poly64_t *a, poly64x1x4_t b) {
-  // CHECK: test_vst1_p64_x4
+  // CHECK-LABEL: test_vst1_p64_x4
   vst1_p64_x4(a, b);
-  // CHECK: st1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d,
-  // v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ ?v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d ?}}}, [{{x[0-9]+|sp}}]
 }
 
 int64_t test_vceqd_s64(int64_t a, int64_t b) {
-// CHECK: test_vceqd_s64
-// CHECK: cmeq {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+// CHECK-LABEL: test_vceqd_s64
+// CHECK: {{cmeq d[0-9]+, d[0-9]+, d[0-9]+|cmp x0, x1}}
   return (int64_t)vceqd_s64(a, b);
 }
 
 uint64_t test_vceqd_u64(uint64_t a, uint64_t b) {
-// CHECK: test_vceqd_u64
-// CHECK: cmeq {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+// CHECK-LABEL: test_vceqd_u64
+// CHECK: {{cmeq d[0-9]+, d[0-9]+, d[0-9]+|cmp x0, x1}}
   return (int64_t)vceqd_u64(a, b);
-} 
+}
 
 int64_t test_vceqzd_s64(int64_t a) {
-// CHECK: test_vceqzd_s64
-// CHECK: cmeq {{d[0-9]+}}, {{d[0-9]+}}, #0x0
+// CHECK-LABEL: test_vceqzd_s64
+// CHECK: {{cmeq d[0-9]+, d[0-9]+, #0x0|cmp x0, #0}}
   return (int64_t)vceqzd_s64(a);
 }
 
 int64_t test_vceqzd_u64(int64_t a) {
-// CHECK: test_vceqzd_u64
-// CHECK: cmeq {{d[0-9]+}}, {{d[0-9]+}}, #0x0
+// CHECK-LABEL: test_vceqzd_u64
+// CHECK: {{cmeq d[0-9]+, d[0-9]+, #0x0|cmp x0, #0}}
   return (int64_t)vceqzd_u64(a);
 }
 
 int64_t test_vcged_s64(int64_t a, int64_t b) {
-// CHECK: test_vcged_s64
-// CHECK: cmge {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+// CHECK-LABEL: test_vcged_s64
+// CHECK: {{cmge d[0-9]+, d[0-9]+, d[0-9]+|cmp x0, x1}}
   return (int64_t)vcged_s64(a, b);
 }
 
 uint64_t test_vcged_u64(uint64_t a, uint64_t b) {
-// CHECK: test_vcged_u64
-// CHECK: cmhs {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+// CHECK-LABEL: test_vcged_u64
+// CHECK: {{cmhs d[0-9]+, d[0-9]+, d[0-9]+|cmp x0, x1}}
     return (uint64_t)vcged_u64(a, b);
 }
 
 int64_t test_vcgezd_s64(int64_t a) {
-// CHECK: test_vcgezd_s64
-// CHECK: cmge {{d[0-9]+}}, {{d[0-9]+}}, #0x0
+// CHECK-LABEL: test_vcgezd_s64
+// CHECK: {{cmge d[0-9]+, d[0-9]+, #0x0|eor x0, x[0-9]+, x0, asr #63}}
   return (int64_t)vcgezd_s64(a);
 }
 
 int64_t test_vcgtd_s64(int64_t a, int64_t b) {
-// CHECK: test_vcgtd_s64
-// CHECK: cmgt {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+// CHECK-LABEL: test_vcgtd_s64
+// CHECK: {{cmgt d[0-9]+, d[0-9]+, d[0-9]+|cmp x0, x1}}
   return (int64_t)vcgtd_s64(a, b);
 }
 
 uint64_t test_vcgtd_u64(uint64_t a, uint64_t b) {
-// CHECK: test_vcgtd_u64
-// CHECK: cmhi {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+// CHECK-LABEL: test_vcgtd_u64
+// CHECK: {{cmhi d[0-9]+, d[0-9]+, d[0-9]+|cmp x0, x1}}
   return (uint64_t)vcgtd_u64(a, b);
 }
 
 int64_t test_vcgtzd_s64(int64_t a) {
-// CHECK: test_vcgtzd_s64
-// CHECK: cmgt {{d[0-9]+}}, {{d[0-9]+}}, #0x0
+// CHECK-LABEL: test_vcgtzd_s64
+// CHECK: {{cmgt d[0-9]+, d[0-9]+, #0x0|cmp x0, #0}}
   return (int64_t)vcgtzd_s64(a);
 }
 
 int64_t test_vcled_s64(int64_t a, int64_t b) {
-// CHECK: test_vcled_s64
-// CHECK: cmge {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+// CHECK-LABEL: test_vcled_s64
+// CHECK: {{cmge d[0-9]+, d[0-9]+, d[0-9]+|cmp x0, x1}}
   return (int64_t)vcled_s64(a, b);
 }
 
 uint64_t test_vcled_u64(uint64_t a, uint64_t b) {
-// CHECK: test_vcled_u64
-// CHECK: cmhs {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
-  return (uint64_t)vcled_u64(a, 0);
+// CHECK-LABEL: test_vcled_u64
+// CHECK: {{cmhs d[0-9]+, d[0-9]+, d[0-9]+|cmp x0, x1}}
+  return (uint64_t)vcled_u64(a, b);
 }
 
 int64_t test_vclezd_s64(int64_t a) {
-// CHECK: test_vclezd_s64
-// CHECK: cmle {{d[0-9]+}}, {{d[0-9]+}}, #0x0
+// CHECK-LABEL: test_vclezd_s64
+// CHECK: {{cmle d[0-9]+, d[0-9]+, #0x0|cmp x0, #1}}
   return (int64_t)vclezd_s64(a);
 }
 
 int64_t test_vcltd_s64(int64_t a, int64_t b) {
-// CHECK: test_vcltd_s64
-// CHECK: cmgt {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+// CHECK-LABEL: test_vcltd_s64
+// CHECK: {{cmgt d[0-9]+, d[0-9]+, d[0-9]+|cmp x0, x1}}
   return (int64_t)vcltd_s64(a, b);
 }
 
 uint64_t test_vcltd_u64(uint64_t a, uint64_t b) {
-// CHECK: test_vcltd_u64
-// CHECK: cmhi {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+// CHECK-LABEL: test_vcltd_u64
+// CHECK: {{cmhi d[0-9]+, d[0-9]+, d[0-9]+|cmp x0, x1}}
   return (uint64_t)vcltd_u64(a, b);
 }
 
 int64_t test_vcltzd_s64(int64_t a) {
-// CHECK: test_vcltzd_s64
-// CHECK: cmlt {{d[0-9]+}}, {{d[0-9]+}}, #0x0
+// CHECK-LABEL: test_vcltzd_s64
+// CHECK: {{cmlt d[0-9]+, d[0-9]+, #0x0|asr x0, x0, #63}}
   return (int64_t)vcltzd_s64(a);
 }
 
 int64_t test_vtstd_s64(int64_t a, int64_t b) {
-// CHECK: test_vtstd_s64
-// CHECK: cmtst {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+// CHECK-LABEL: test_vtstd_s64
+// CHECK: {{cmtst d[0-9]+, d[0-9]+, d[0-9]+|tst x1, x0}}
   return (int64_t)vtstd_s64(a, b);
 }
 
 uint64_t test_vtstd_u64(uint64_t a, uint64_t b) {
-// CHECK: test_vtstd_u64
-// CHECK: cmtst {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+// CHECK-LABEL: test_vtstd_u64
+// CHECK: {{cmtst d[0-9]+, d[0-9]+, d[0-9]+|tst x1, x0}}
   return (uint64_t)vtstd_u64(a, b);
 }
 
 int64_t test_vabsd_s64(int64_t a) {
-// CHECK: test_vabsd_s64
+// CHECK-LABEL: test_vabsd_s64
 // CHECK: abs {{d[0-9]+}}, {{d[0-9]+}}
   return (int64_t)vabsd_s64(a);
 }
 
 int8_t test_vqabsb_s8(int8_t a) {
-// CHECK: test_vqabsb_s8
-// CHECK: sqabs {{b[0-9]+}}, {{b[0-9]+}}
+// CHECK-LABEL: test_vqabsb_s8
+// CHECK: sqabs {{b[0-9]+|v[0-9]+.8b}}, {{b[0-9]+|v[0-9]+.8b}}
   return (int8_t)vqabsb_s8(a);
 }
 
 int16_t test_vqabsh_s16(int16_t a) {
-// CHECK: test_vqabsh_s16
-// CHECK: sqabs {{h[0-9]+}}, {{h[0-9]+}}
+// CHECK-LABEL: test_vqabsh_s16
+// CHECK: sqabs {{h[0-9]+|v[0-9]+.4h}}, {{h[0-9]+|v[0-9]+.4h}}
   return (int16_t)vqabsh_s16(a);
 }
 
 int32_t test_vqabss_s32(int32_t a) {
-// CHECK: test_vqabss_s32
+// CHECK-LABEL: test_vqabss_s32
 // CHECK: sqabs {{s[0-9]+}}, {{s[0-9]+}}
   return (int32_t)vqabss_s32(a);
 }
 
 int64_t test_vqabsd_s64(int64_t a) {
-// CHECK: test_vqabsd_s64
+// CHECK-LABEL: test_vqabsd_s64
 // CHECK: sqabs {{d[0-9]+}}, {{d[0-9]+}}
   return (int64_t)vqabsd_s64(a);
 }
 
 int64_t test_vnegd_s64(int64_t a) {
-// CHECK: test_vnegd_s64
-// CHECK: neg {{d[0-9]+}}, {{d[0-9]+}}
+// CHECK-LABEL: test_vnegd_s64
+// CHECK: neg {{[xd][0-9]+}}, {{[xd][0-9]+}}
   return (int64_t)vnegd_s64(a);
 }
 
 int8_t test_vqnegb_s8(int8_t a) {
-// CHECK: test_vqnegb_s8
-// CHECK: sqneg {{b[0-9]+}}, {{b[0-9]+}}
+// CHECK-LABEL: test_vqnegb_s8
+// CHECK: sqneg {{b[0-9]+|v[0-9]+.8b}}, {{b[0-9]+|v[0-9]+.8b}}
   return (int8_t)vqnegb_s8(a);
 }
 
 int16_t test_vqnegh_s16(int16_t a) {
-// CHECK: test_vqnegh_s16
-// CHECK: sqneg {{h[0-9]+}}, {{h[0-9]+}}
+// CHECK-LABEL: test_vqnegh_s16
+// CHECK: sqneg {{h[0-9]+|v[0-9]+.4h}}, {{h[0-9]+|v[0-9]+.4h}}
   return (int16_t)vqnegh_s16(a);
 }
 
 int32_t test_vqnegs_s32(int32_t a) {
-// CHECK: test_vqnegs_s32
+// CHECK-LABEL: test_vqnegs_s32
 // CHECK: sqneg {{s[0-9]+}}, {{s[0-9]+}}
   return (int32_t)vqnegs_s32(a);
 }
 
 int64_t test_vqnegd_s64(int64_t a) {
-// CHECK: test_vqnegd_s64
+// CHECK-LABEL: test_vqnegd_s64
 // CHECK: sqneg {{d[0-9]+}}, {{d[0-9]+}}
   return (int64_t)vqnegd_s64(a);
 }
 
 int8_t test_vuqaddb_s8(int8_t a, int8_t b) {
-// CHECK: test_vuqaddb_s8
-// CHECK: suqadd {{b[0-9]+}}, {{b[0-9]+}}
+// CHECK-LABEL: test_vuqaddb_s8
+// CHECK: suqadd {{b[0-9]+|v[0-9]+.8b}}, {{b[0-9]+|v[0-9]+.8b}}
   return (int8_t)vuqaddb_s8(a, b);
 }
 
 int16_t test_vuqaddh_s16(int16_t a, int16_t b) {
-// CHECK: test_vuqaddh_s16
-// CHECK: suqadd {{h[0-9]+}}, {{h[0-9]+}}
+// CHECK-LABEL: test_vuqaddh_s16
+// CHECK: suqadd {{h[0-9]+|v[0-9]+.4h}}, {{h[0-9]+|v[0-9]+.4h}}
   return (int16_t)vuqaddh_s16(a, b);
 }
 
 int32_t test_vuqadds_s32(int32_t a, int32_t b) {
-// CHECK: test_vuqadds_s32
+// CHECK-LABEL: test_vuqadds_s32
 // CHECK: suqadd {{s[0-9]+}}, {{s[0-9]+}}
   return (int32_t)vuqadds_s32(a, b);
 }
 
 int64_t test_vuqaddd_s64(int64_t a, int64_t b) {
-// CHECK: test_vuqaddd_s64
+// CHECK-LABEL: test_vuqaddd_s64
 // CHECK: suqadd {{d[0-9]+}}, {{d[0-9]+}}
   return (int64_t)vuqaddd_s64(a, b);
 }
 
 uint8_t test_vsqaddb_u8(uint8_t a, uint8_t b) {
-// CHECK: test_vsqaddb_u8
-// CHECK: usqadd {{b[0-9]+}}, {{b[0-9]+}}
+// CHECK-LABEL: test_vsqaddb_u8
+// CHECK: usqadd {{b[0-9]+|v[0-9]+.8b}}, {{b[0-9]+|v[0-9]+.8b}}
   return (uint8_t)vsqaddb_u8(a, b);
 }
 
 uint16_t test_vsqaddh_u16(uint16_t a, uint16_t b) {
-// CHECK: test_vsqaddh_u16
-// CHECK: usqadd {{h[0-9]+}}, {{h[0-9]+}}
+// CHECK-LABEL: test_vsqaddh_u16
+// CHECK: usqadd {{h[0-9]+|v[0-9]+.4h}}, {{h[0-9]+|v[0-9]+.4h}}
   return (uint16_t)vsqaddh_u16(a, b);
 }
 
 uint32_t test_vsqadds_u32(uint32_t a, uint32_t b) {
-// CHECK: test_vsqadds_u32
+// CHECK-LABEL: test_vsqadds_u32
 // CHECK: usqadd {{s[0-9]+}}, {{s[0-9]+}}
   return (uint32_t)vsqadds_u32(a, b);
 }
 
 uint64_t test_vsqaddd_u64(uint64_t a, uint64_t b) {
-// CHECK: test_vsqaddd_u64
+// CHECK-LABEL: test_vsqaddd_u64
 // CHECK: usqadd {{d[0-9]+}}, {{d[0-9]+}}
   return (uint64_t)vsqaddd_u64(a, b);
 }
 
 int32_t test_vqdmlalh_s16(int32_t a, int16_t b, int16_t c) {
-// CHECK: test_vqdmlalh_s16
-// CHECK: sqdmlal {{s[0-9]+}}, {{h[0-9]+}}, {{h[0-9]+}}
+
+// CHECK-ARM64-LABEL: test_vqdmlalh_s16
+// CHECK-ARM64: sqdmull v[[PROD:[0-9]+]].4s, {{v[0-9]+.4h}}, {{v[0-9]+.4h}}
+// CHECK-ARM64: sqadd {{s[0-9]+}}, {{s[0-9]+}}, s[[PROD]]
   return (int32_t)vqdmlalh_s16(a, b, c);
 }
 
 int64_t test_vqdmlals_s32(int64_t a, int32_t b, int32_t c) {
-// CHECK: test_vqdmlals_s32
+// CHECK-LABEL: test_vqdmlals_s32
 // CHECK: sqdmlal {{d[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
   return (int64_t)vqdmlals_s32(a, b, c);
 }
 
 int32_t test_vqdmlslh_s16(int32_t a, int16_t b, int16_t c) {
-// CHECK: test_vqdmlslh_s16
-// CHECK: sqdmlsl {{s[0-9]+}}, {{h[0-9]+}}, {{h[0-9]+}}
+
+// CHECK-ARM64-LABEL: test_vqdmlslh_s16
+// CHECK-ARM64: sqdmull v[[PROD:[0-9]+]].4s, {{v[0-9]+.4h}}, {{v[0-9]+.4h}}
+// CHECK-ARM64: sqsub {{s[0-9]+}}, {{s[0-9]+}}, s[[PROD]]
   return (int32_t)vqdmlslh_s16(a, b, c);
 }
 
 int64_t test_vqdmlsls_s32(int64_t a, int32_t b, int32_t c) {
-// CHECK: test_vqdmlsls_s32
+// CHECK-LABEL: test_vqdmlsls_s32
 // CHECK: sqdmlsl {{d[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
   return (int64_t)vqdmlsls_s32(a, b, c);
 }
 
 int32_t test_vqdmullh_s16(int16_t a, int16_t b) {
-// CHECK: test_vqdmullh_s16
-// CHECK: sqdmull {{s[0-9]+}}, {{h[0-9]+}}, {{h[0-9]+}}
+// CHECK-LABEL: test_vqdmullh_s16
+// CHECK: sqdmull {{s[0-9]+|v[0-9]+.4s}}, {{h[0-9]+|v[0-9]+.4h}}, {{h[0-9]+|v[0-9]+.4h}}
   return (int32_t)vqdmullh_s16(a, b);
 }
 
 int64_t test_vqdmulls_s32(int32_t a, int32_t b) {
-// CHECK: test_vqdmulls_s32
+// CHECK-LABEL: test_vqdmulls_s32
 // CHECK: sqdmull {{d[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
   return (int64_t)vqdmulls_s32(a, b);
 }
 
 int8_t test_vqmovunh_s16(int16_t a) {
-// CHECK: test_vqmovunh_s16
-// CHECK: sqxtun {{b[0-9]+}}, {{h[0-9]+}}
+// CHECK-LABEL: test_vqmovunh_s16
+// CHECK: sqxtun {{b[0-9]+|v[0-9]+.8b}}, {{h[0-9]+|v[0-9]+.8h}}
   return (int8_t)vqmovunh_s16(a);
 }
 
 int16_t test_vqmovuns_s32(int32_t a) {
-// CHECK: test_vqmovuns_s32
-// CHECK: sqxtun {{h[0-9]+}}, {{s[0-9]+}}
+// CHECK-LABEL: test_vqmovuns_s32
+// CHECK: sqxtun {{h[0-9]+|v[0-9]+.4h}}, {{s[0-9]+|v[0-9]+.4s}}
   return (int16_t)vqmovuns_s32(a);
 }
 
 int32_t test_vqmovund_s64(int64_t a) {
-// CHECK: test_vqmovund_s64
+// CHECK-LABEL: test_vqmovund_s64
 // CHECK: sqxtun {{s[0-9]+}}, {{d[0-9]+}}
   return (int32_t)vqmovund_s64(a);
 }
 
 int8_t test_vqmovnh_s16(int16_t a) {
-// CHECK: test_vqmovnh_s16
-// CHECK: sqxtn {{b[0-9]+}}, {{h[0-9]+}}
+// CHECK-LABEL: test_vqmovnh_s16
+// CHECK: sqxtn {{b[0-9]+|v[0-9]+.8b}}, {{h[0-9]+|v[0-9]+.8h}}
   return (int8_t)vqmovnh_s16(a);
 }
 
 int16_t test_vqmovns_s32(int32_t a) {
-// CHECK: test_vqmovns_s32
-// CHECK: sqxtn {{h[0-9]+}}, {{s[0-9]+}}
+// CHECK-LABEL: test_vqmovns_s32
+// CHECK: sqxtn {{h[0-9]+|v[0-9]+.4h}}, {{s[0-9]+|v[0-9]+.4s}}
   return (int16_t)vqmovns_s32(a);
 }
 
 int32_t test_vqmovnd_s64(int64_t a) {
-// CHECK: test_vqmovnd_s64
+// CHECK-LABEL: test_vqmovnd_s64
 // CHECK: sqxtn {{s[0-9]+}}, {{d[0-9]+}}
   return (int32_t)vqmovnd_s64(a);
 }
 
 int8_t test_vqmovnh_u16(int16_t a) {
-// CHECK: test_vqmovnh_u16
-// CHECK: uqxtn {{b[0-9]+}}, {{h[0-9]+}}
+// CHECK-LABEL: test_vqmovnh_u16
+// CHECK: uqxtn {{b[0-9]+|v[0-9]+.8b}}, {{h[0-9]+|v[0-9]+.8h}}
   return (int8_t)vqmovnh_u16(a);
 }
 
 int16_t test_vqmovns_u32(int32_t a) {
-// CHECK: test_vqmovns_u32
-// CHECK: uqxtn {{h[0-9]+}}, {{s[0-9]+}}
+// CHECK-LABEL: test_vqmovns_u32
+// CHECK: uqxtn {{h[0-9]+|v[0-9]+.4h}}, {{s[0-9]+|v[0-9]+.4s}}
   return (int16_t)vqmovns_u32(a);
 }
 
 int32_t test_vqmovnd_u64(int64_t a) {
-// CHECK: test_vqmovnd_u64
+// CHECK-LABEL: test_vqmovnd_u64
 // CHECK: uqxtn {{s[0-9]+}}, {{d[0-9]+}}
   return (int32_t)vqmovnd_u64(a);
 }
 
 uint32_t test_vceqs_f32(float32_t a, float32_t b) {
-// CHECK: test_vceqs_f32
-// CHECK: fcmeq {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
+// CHECK-LABEL: test_vceqs_f32
+// CHECK: {{fcmeq s0, s0, s1|fcmp s0, s1}}
   return (uint32_t)vceqs_f32(a, b);
 }
 
 uint64_t test_vceqd_f64(float64_t a, float64_t b) {
-// CHECK: test_vceqd_f64
-// CHECK: fcmeq {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+// CHECK-LABEL: test_vceqd_f64
+// CHECK: {{fcmeq d0, d0, d1|fcmp d0, d1}}
   return (uint64_t)vceqd_f64(a, b);
 }
 
 uint32_t test_vceqzs_f32(float32_t a) {
-// CHECK: test_vceqzs_f32
-// CHECK: fcmeq {{s[0-9]+}}, {{s[0-9]+}}, #0.0
+// CHECK-LABEL: test_vceqzs_f32
+// CHECK: {{fcmeq s0, s0, #0.0|fcmp s0, #0.0}}
   return (uint32_t)vceqzs_f32(a);
 }
 
 uint64_t test_vceqzd_f64(float64_t a) {
-// CHECK: test_vceqzd_f64
-// CHECK: fcmeq {{d[0-9]+}}, {{d[0-9]+}}, #0.0
+// CHECK-LABEL: test_vceqzd_f64
+// CHECK: {{fcmeq d0, d0, #0.0|fcmp d0, #0.0}}
   return (uint64_t)vceqzd_f64(a);
 }
 
 uint32_t test_vcges_f32(float32_t a, float32_t b) {
-// CHECK: test_vcges_f32
-// CHECK: fcmge {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
+// CHECK-LABEL: test_vcges_f32
+// CHECK: {{fcmge s0, s0, s1|fcmp s0, s1}}
   return (uint32_t)vcges_f32(a, b);
 }
 
 uint64_t test_vcged_f64(float64_t a, float64_t b) {
-// CHECK: test_vcged_f64
-// CHECK: fcmge {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+// CHECK-LABEL: test_vcged_f64
+// CHECK: {{fcmge d0, d0, d1|fcmp d0, d1}}
   return (uint64_t)vcged_f64(a, b);
 }
 
 uint32_t test_vcgezs_f32(float32_t a) {
-// CHECK: test_vcgezs_f32
-// CHECK: fcmge {{s[0-9]+}}, {{s[0-9]+}}, #0.0
+// CHECK-LABEL: test_vcgezs_f32
+// CHECK: {{fcmge s0, s0, #0.0|fcmp s0, #0.0}}
   return (uint32_t)vcgezs_f32(a);
 }
 
 uint64_t test_vcgezd_f64(float64_t a) {
-// CHECK: test_vcgezd_f64
-// CHECK: fcmge {{d[0-9]+}}, {{d[0-9]+}}, #0.0
+// CHECK-LABEL: test_vcgezd_f64
+// CHECK: {{fcmge d0, d0, #0.0|fcmp d0, #0.0}}
   return (uint64_t)vcgezd_f64(a);
 }
 
 uint32_t test_vcgts_f32(float32_t a, float32_t b) {
-// CHECK: test_vcgts_f32
-// CHECK: fcmgt {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
+// CHECK-LABEL: test_vcgts_f32
+// CHECK: {{fcmgt s0, s0, s1|fcmp s0, s1}}
   return (uint32_t)vcgts_f32(a, b);
 }
 
 uint64_t test_vcgtd_f64(float64_t a, float64_t b) {
-// CHECK: test_vcgtd_f64
-// CHECK: fcmgt {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+// CHECK-LABEL: test_vcgtd_f64
+// CHECK: {{fcmgt d0, d0, d1|fcmp d0, d1}}
   return (uint64_t)vcgtd_f64(a, b);
 }
 
 uint32_t test_vcgtzs_f32(float32_t a) {
-// CHECK: test_vcgtzs_f32
-// CHECK: fcmgt {{s[0-9]+}}, {{s[0-9]+}}, #0.0
+// CHECK-LABEL: test_vcgtzs_f32
+// CHECK: {{fcmgt s0, s0, #0.0|fcmp s0, #0.0}}
   return (uint32_t)vcgtzs_f32(a);
 }
 
 uint64_t test_vcgtzd_f64(float64_t a) {
-// CHECK: test_vcgtzd_f64
-// CHECK: fcmgt {{d[0-9]+}}, {{d[0-9]+}}, #0.0
+// CHECK-LABEL: test_vcgtzd_f64
+// CHECK: {{fcmgt d0, d0, #0.0|fcmp d0, #0.0}}
   return (uint64_t)vcgtzd_f64(a);
 }
 
 uint32_t test_vcles_f32(float32_t a, float32_t b) {
-// CHECK: test_vcles_f32
-// CHECK: fcmge {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
+// CHECK-LABEL: test_vcles_f32
+// CHECK: {{fcmge s0, s1, s0|fcmp s0, s1}}
   return (uint32_t)vcles_f32(a, b);
 }
 
 uint64_t test_vcled_f64(float64_t a, float64_t b) {
-// CHECK: test_vcled_f64
-// CHECK: fcmge {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+// CHECK-LABEL: test_vcled_f64
+// CHECK: {{fcmge d0, d1, d0|fcmp d0, d1}}
   return (uint64_t)vcled_f64(a, b);
 }
 
 uint32_t test_vclezs_f32(float32_t a) {
-// CHECK: test_vclezs_f32
-// CHECK: fcmle {{s[0-9]+}}, {{s[0-9]+}}, #0.0
+// CHECK-LABEL: test_vclezs_f32
+// CHECK: {{fcmle s0, s0, #0.0|fcmp s0, #0.0}}
   return (uint32_t)vclezs_f32(a);
 }
 
 uint64_t test_vclezd_f64(float64_t a) {
-// CHECK: test_vclezd_f64
-// CHECK: fcmle {{d[0-9]+}}, {{d[0-9]+}}, #0.0
+// CHECK-LABEL: test_vclezd_f64
+// CHECK: {{fcmle d0, d0, #0.0|fcmp d0, #0.0}}
   return (uint64_t)vclezd_f64(a);
 }
 
 uint32_t test_vclts_f32(float32_t a, float32_t b) {
-// CHECK: test_vclts_f32
-// CHECK: fcmgt {{s[0-9]+}}, s1, s0
+// CHECK-LABEL: test_vclts_f32
+// CHECK: {{fcmgt s0, s1, s0|fcmp s0, s1}}
   return (uint32_t)vclts_f32(a, b);
 }
 
 uint64_t test_vcltd_f64(float64_t a, float64_t b) {
-// CHECK: test_vcltd_f64
-// CHECK: fcmgt {{d[0-9]+}}, d1, d0
+// CHECK-LABEL: test_vcltd_f64
+// CHECK: {{fcmgt d0, d1, d0|fcmp d0, d1}}
   return (uint64_t)vcltd_f64(a, b);
 }
 
 uint32_t test_vcltzs_f32(float32_t a) {
-// CHECK: test_vcltzs_f32
-// CHECK: fcmlt {{s[0-9]+}}, {{s[0-9]+}}, #0.0
+// CHECK-LABEL: test_vcltzs_f32
+// CHECK: {{fcmlt s0, s0, #0.0|fcmp s0, #0.0}}
   return (uint32_t)vcltzs_f32(a);
 }
 
 uint64_t test_vcltzd_f64(float64_t a) {
-// CHECK: test_vcltzd_f64
-// CHECK: fcmlt {{d[0-9]+}}, {{d[0-9]+}}, #0.0
+// CHECK-LABEL: test_vcltzd_f64
+// CHECK: {{fcmlt d0, d0, #0.0|fcmp d0, #0.0}}
   return (uint64_t)vcltzd_f64(a);
 }
 
 uint32_t test_vcages_f32(float32_t a, float32_t b) {
-// CHECK: test_vcages_f32
-// CHECK: facge {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
+// CHECK-LABEL: test_vcages_f32
+// CHECK: facge s0, s0, s1
   return (uint32_t)vcages_f32(a, b);
 }
 
 uint64_t test_vcaged_f64(float64_t a, float64_t b) {
-// CHECK: test_vcaged_f64
-// CHECK: facge {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+// CHECK-LABEL: test_vcaged_f64
+// CHECK: facge d0, d0, d1
   return (uint64_t)vcaged_f64(a, b);
 }
 
 uint32_t test_vcagts_f32(float32_t a, float32_t b) {
-// CHECK: test_vcagts_f32
-// CHECK: facgt {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
+// CHECK-LABEL: test_vcagts_f32
+// CHECK: facgt s0, s0, s1
   return (uint32_t)vcagts_f32(a, b);
 }
 
 uint64_t test_vcagtd_f64(float64_t a, float64_t b) {
-// CHECK: test_vcagtd_f64
-// CHECK: facgt {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+// CHECK-LABEL: test_vcagtd_f64
+// CHECK: facgt d0, d0, d1
   return (uint64_t)vcagtd_f64(a, b);
 }
 
 uint32_t test_vcales_f32(float32_t a, float32_t b) {
-// CHECK: test_vcales_f32
-// CHECK: facge {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
+// CHECK-LABEL: test_vcales_f32
+// CHECK: facge s0, s1, s0
   return (uint32_t)vcales_f32(a, b);
 }
 
 uint64_t test_vcaled_f64(float64_t a, float64_t b) {
-// CHECK: test_vcaled_f64
-// CHECK: facge {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+// CHECK-LABEL: test_vcaled_f64
+// CHECK: facge d0, d1, d0
   return (uint64_t)vcaled_f64(a, b);
 }
 
 uint32_t test_vcalts_f32(float32_t a, float32_t b) {
-// CHECK: test_vcalts_f32
-// CHECK: facgt {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
+// CHECK-LABEL: test_vcalts_f32
+// CHECK: facgt s0, s1, s0
   return (uint32_t)vcalts_f32(a, b);
 }
 
 uint64_t test_vcaltd_f64(float64_t a, float64_t b) {
-// CHECK: test_vcaltd_f64
-// CHECK: facgt {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+// CHECK-LABEL: test_vcaltd_f64
+// CHECK: facgt d0, d1, d0
   return (uint64_t)vcaltd_f64(a, b);
 }
 
 int64_t test_vshrd_n_s64(int64_t a) {
 // CHECK-LABEL: test_vshrd_n_s64
-// CHECK: sshr {{d[0-9]+}}, {{d[0-9]+}}, #1
+// CHECK: {{sshr d[0-9]+, d[0-9]+, #1|asr x0, x0, #1}}
   return (int64_t)vshrd_n_s64(a, 1);
 }
 
@@ -8617,11 +8565,20 @@
 }
 
 uint64_t test_vshrd_n_u64(uint64_t a) {
-// CHECK-LABEL: test_vshrd_n_u64
-// CHECK: ushr {{d[0-9]+}}, {{d[0-9]+}}, #64
+
+// CHECK-ARM64-LABEL: test_vshrd_n_u64
+// CHECK-ARM64: mov x0, xzr
   return (uint64_t)vshrd_n_u64(a, 64);
 }
 
+uint64_t test_vshrd_n_u64_2() {
+
+// CHECK-ARM64-LABEL: test_vshrd_n_u64_2
+// CHECK-ARM64: mov x0, xzr
+  uint64_t a = UINT64_C(0xf000000000000000);
+  return vshrd_n_u64(a, 64);
+}
+
 uint64x1_t test_vshr_n_u64(uint64x1_t a) {
 // CHECK-LABEL: test_vshr_n_u64
 // CHECK: ushr {{d[0-9]+}}, {{d[0-9]+}}, #1
@@ -8635,7 +8592,7 @@
 }
 
 int64x1_t test_vrshr_n_s64(int64x1_t a) {
-// CHECK: test_vrshr_n_s64
+// CHECK-LABEL: test_vrshr_n_s64
 // CHECK: srshr d{{[0-9]+}}, d{{[0-9]+}}, #1
   return vrshr_n_s64(a, 1);
 }
@@ -8647,43 +8604,50 @@
 }
 
 uint64x1_t test_vrshr_n_u64(uint64x1_t a) {
-// CHECK: test_vrshr_n_u64
+// CHECK-LABEL: test_vrshr_n_u64
 // CHECK: urshr d{{[0-9]+}}, d{{[0-9]+}}, #1
   return vrshr_n_u64(a, 1);
 }
 
 int64_t test_vsrad_n_s64(int64_t a, int64_t b) {
 // CHECK-LABEL: test_vsrad_n_s64
-// CHECK: ssra {{d[0-9]+}}, {{d[0-9]+}}, #63
+// CHECK: {{ssra d[0-9]+, d[0-9]+, #63|add x0, x0, x1, asr #63}}
   return (int64_t)vsrad_n_s64(a, b, 63);
 }
 
 int64x1_t test_vsra_n_s64(int64x1_t a, int64x1_t b) {
-// CHECK: test_vsra_n_s64
+// CHECK-LABEL: test_vsra_n_s64
 // CHECK: ssra d{{[0-9]+}}, d{{[0-9]+}}, #1
   return vsra_n_s64(a, b, 1);
 }
 
 uint64_t test_vsrad_n_u64(uint64_t a, uint64_t b) {
 // CHECK-LABEL: test_vsrad_n_u64
-// CHECK: usra {{d[0-9]+}}, {{d[0-9]+}}, #63
+// CHECK: {{usra d[0-9]+, d[0-9]+, #63|add x0, x0, x1, lsr #63}}
   return (uint64_t)vsrad_n_u64(a, b, 63);
 }
 
+uint64_t test_vsrad_n_u64_2(uint64_t a, uint64_t b) {
+
+// CHECK-ARM64-LABEL: test_vsrad_n_u64_2
+// CHECK-ARM64-NOT: add
+  return (uint64_t)vsrad_n_u64(a, b, 64);
+}
+
 uint64x1_t test_vsra_n_u64(uint64x1_t a, uint64x1_t b) {
-// CHECK: test_vsra_n_u64
+// CHECK-LABEL: test_vsra_n_u64
 // CHECK: usra d{{[0-9]+}}, d{{[0-9]+}}, #1
   return vsra_n_u64(a, b, 1);
 }
 
 int64_t test_vrsrad_n_s64(int64_t a, int64_t b) {
 // CHECK-LABEL: test_vrsrad_n_s64
-// CHECK: srsra {{d[0-9]+}}, {{d[0-9]+}}, #63
+// CHECK: {{srsra d[0-9]+, d[0-9]+, #63}}
   return (int64_t)vrsrad_n_s64(a, b, 63);
 }
 
 int64x1_t test_vrsra_n_s64(int64x1_t a, int64x1_t b) {
-// CHECK: test_vrsra_n_s64
+// CHECK-LABEL: test_vrsra_n_s64
 // CHECK: srsra d{{[0-9]+}}, d{{[0-9]+}}, #1
   return vrsra_n_s64(a, b, 1);
 }
@@ -8695,43 +8659,43 @@
 }
 
 uint64x1_t test_vrsra_n_u64(uint64x1_t a, uint64x1_t b) {
-// CHECK: test_vrsra_n_u64
+// CHECK-LABEL: test_vrsra_n_u64
 // CHECK: ursra d{{[0-9]+}}, d{{[0-9]+}}, #1
   return vrsra_n_u64(a, b, 1);
 }
 
 int64_t test_vshld_n_s64(int64_t a) {
 // CHECK-LABEL: test_vshld_n_s64
-// CHECK: shl {{d[0-9]+}}, {{d[0-9]+}}, #0
-  return (int64_t)vshld_n_s64(a, 0);
+// CHECK: {{shl d[0-9]+, d[0-9]+, #1|lsl x0, x0, #1}}
+  return (int64_t)vshld_n_s64(a, 1);
 }
 int64x1_t test_vshl_n_s64(int64x1_t a) {
-// CHECK: test_vshl_n_s64
+// CHECK-LABEL: test_vshl_n_s64
 // CHECK: shl d{{[0-9]+}}, d{{[0-9]+}}, #1
   return vshl_n_s64(a, 1);
 }
 
 uint64_t test_vshld_n_u64(uint64_t a) {
 // CHECK-LABEL: test_vshld_n_u64
-// CHECK: shl {{d[0-9]+}}, {{d[0-9]+}}, #63
+// CHECK: {{shl d[0-9]+, d[0-9]+, #63|lsl x0, x0, #63}}
   return (uint64_t)vshld_n_u64(a, 63);
 }
 
 uint64x1_t test_vshl_n_u64(uint64x1_t a) {
-// CHECK: test_vshl_n_u64
+// CHECK-LABEL: test_vshl_n_u64
 // CHECK: shl d{{[0-9]+}}, d{{[0-9]+}}, #1
   return vshl_n_u64(a, 1);
 }
 
 int8_t test_vqshlb_n_s8(int8_t a) {
 // CHECK-LABEL: test_vqshlb_n_s8
-// CHECK: sqshl {{b[0-9]+}}, {{b[0-9]+}}, #7
+// CHECK: sqshl {{b[0-9]+|v[0-9]+.8b}}, {{b[0-9]+|v[0-9]+.8b}}, #7
   return (int8_t)vqshlb_n_s8(a, 7);
 }
 
 int16_t test_vqshlh_n_s16(int16_t a) {
 // CHECK-LABEL: test_vqshlh_n_s16
-// CHECK: sqshl {{h[0-9]+}}, {{h[0-9]+}}, #15
+// CHECK: sqshl {{h[0-9]+|v[0-9]+.4h}}, {{h[0-9]+|v[0-9]+.4h}}, #15
   return (int16_t)vqshlh_n_s16(a, 15);
 }
 
@@ -8747,21 +8711,105 @@
   return (int64_t)vqshld_n_s64(a, 63);
 }
 
+int8x8_t test_vqshl_n_s8(int8x8_t a) {
+  // CHECK-LABEL: test_vqshl_n_s8
+  return vqshl_n_s8(a, 0);
+  // CHECK: sqshl {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #0
+}
+
+int8x16_t test_vqshlq_n_s8(int8x16_t a) {
+  // CHECK-LABEL: test_vqshlq_n_s8
+  return vqshlq_n_s8(a, 0);
+  // CHECK: sqshl {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #0
+}
+
+int16x4_t test_vqshl_n_s16(int16x4_t a) {
+  // CHECK-LABEL: test_vqshl_n_s16
+  return vqshl_n_s16(a, 0);
+  // CHECK: sqshl {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, #0
+}
+
+int16x8_t test_vqshlq_n_s16(int16x8_t a) {
+  // CHECK-LABEL: test_vqshlq_n_s16
+  return vqshlq_n_s16(a, 0);
+  // CHECK: sqshl {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, #0
+}
+
+int32x2_t test_vqshl_n_s32(int32x2_t a) {
+  // CHECK-LABEL: test_vqshl_n_s32
+  return vqshl_n_s32(a, 0);
+  // CHECK: sqshl {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #0
+}
+
+int32x4_t test_vqshlq_n_s32(int32x4_t a) {
+  // CHECK-LABEL: test_vqshlq_n_s32
+  return vqshlq_n_s32(a, 0);
+  // CHECK: sqshl {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #0
+}
+
+int64x2_t test_vqshlq_n_s64(int64x2_t a) {
+  // CHECK-LABEL: test_vqshlq_n_s64
+  return vqshlq_n_s64(a, 0);
+  // CHECK: sqshl {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #0
+}
+
+uint8x8_t test_vqshl_n_u8(uint8x8_t a) {
+  // CHECK-LABEL: test_vqshl_n_u8
+  return vqshl_n_u8(a, 0);
+  // CHECK: uqshl {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #0
+}
+
+uint8x16_t test_vqshlq_n_u8(uint8x16_t a) {
+  // CHECK-LABEL: test_vqshlq_n_u8
+  return vqshlq_n_u8(a, 0);
+  // CHECK: uqshl {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #0
+}
+
+uint16x4_t test_vqshl_n_u16(uint16x4_t a) {
+  // CHECK-LABEL: test_vqshl_n_u16
+  return vqshl_n_u16(a, 0);
+  // CHECK: uqshl {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, #0
+}
+
+uint16x8_t test_vqshlq_n_u16(uint16x8_t a) {
+  // CHECK-LABEL: test_vqshlq_n_u16
+  return vqshlq_n_u16(a, 0);
+  // CHECK: uqshl {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, #0
+}
+
+uint32x2_t test_vqshl_n_u32(uint32x2_t a) {
+  // CHECK-LABEL: test_vqshl_n_u32
+  return vqshl_n_u32(a, 0);
+  // CHECK: uqshl {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #0
+}
+
+uint32x4_t test_vqshlq_n_u32(uint32x4_t a) {
+  // CHECK-LABEL: test_vqshlq_n_u32
+  return vqshlq_n_u32(a, 0);
+  // CHECK: uqshl {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #0
+}
+
+uint64x2_t test_vqshlq_n_u64(uint64x2_t a) {
+  // CHECK-LABEL: test_vqshlq_n_u64
+  return vqshlq_n_u64(a, 0);
+  // CHECK: uqshl {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #0
+}
+
 int64x1_t test_vqshl_n_s64(int64x1_t a) {
-// CHECK: test_vqshl_n_s64
+// CHECK-LABEL: test_vqshl_n_s64
 // CHECK: sqshl d{{[0-9]+}}, d{{[0-9]+}}, #1
   return vqshl_n_s64(a, 1);
 }
 
 uint8_t test_vqshlb_n_u8(uint8_t a) {
 // CHECK-LABEL: test_vqshlb_n_u8
-// CHECK: uqshl {{b[0-9]+}}, {{b[0-9]+}}, #7
+// CHECK: uqshl {{b[0-9]+|v[0-9]+.8b}}, {{b[0-9]+|v[0-9]+.8b}}, #7
   return (uint8_t)vqshlb_n_u8(a, 7);
 }
 
 uint16_t test_vqshlh_n_u16(uint16_t a) {
 // CHECK-LABEL: test_vqshlh_n_u16
-// CHECK: uqshl {{h[0-9]+}}, {{h[0-9]+}}, #15
+// CHECK: uqshl {{h[0-9]+|v[0-9]+.4h}}, {{h[0-9]+|v[0-9]+.4h}}, #15
   return (uint16_t)vqshlh_n_u16(a, 15);
 }
 
@@ -8778,20 +8826,20 @@
 }
 
 uint64x1_t test_vqshl_n_u64(uint64x1_t a) {
-// CHECK: test_vqshl_n_u64
+// CHECK-LABEL: test_vqshl_n_u64
 // CHECK: uqshl d{{[0-9]+}}, d{{[0-9]+}}, #1
   return vqshl_n_u64(a, 1);
 }
 
 int8_t test_vqshlub_n_s8(int8_t a) {
 // CHECK-LABEL: test_vqshlub_n_s8
-// CHECK: sqshlu {{b[0-9]+}}, {{b[0-9]+}}, #7
+// CHECK: sqshlu {{b[0-9]+|v[0-9]+.8b}}, {{b[0-9]+|v[0-9]+.8b}}, #7
   return (int8_t)vqshlub_n_s8(a, 7);
 }
 
 int16_t test_vqshluh_n_s16(int16_t a) {
 // CHECK-LABEL: test_vqshluh_n_s16
-// CHECK: sqshlu {{h[0-9]+}}, {{h[0-9]+}}, #15
+// CHECK: sqshlu {{h[0-9]+|v[0-9]+.4h}}, {{h[0-9]+|v[0-9]+.4h}}, #15
   return (int16_t)vqshluh_n_s16(a, 15);
 }
 
@@ -8808,7 +8856,7 @@
 }
 
 uint64x1_t test_vqshlu_n_s64(int64x1_t a) {
-// CHECK: test_vqshlu_n_s64
+// CHECK-LABEL: test_vqshlu_n_s64
 // CHECK: sqshlu d{{[0-9]+}}, d{{[0-9]+}}, #1
   return vqshlu_n_s64(a, 1);
 }
@@ -8820,7 +8868,7 @@
 }
 
 int64x1_t test_vsri_n_s64(int64x1_t a, int64x1_t b) {
-// CHECK: test_vsri_n_s64
+// CHECK-LABEL: test_vsri_n_s64
 // CHECK: sri d{{[0-9]+}}, d{{[0-9]+}}, #1
   return vsri_n_s64(a, b, 1);
 }
@@ -8832,7 +8880,7 @@
 }
 
 uint64x1_t test_vsri_n_u64(uint64x1_t a, uint64x1_t b) {
-// CHECK: test_vsri_n_u64
+// CHECK-LABEL: test_vsri_n_u64
 // CHECK: sri d{{[0-9]+}}, d{{[0-9]+}}, #1
   return vsri_n_u64(a, b, 1);
 }
@@ -8844,7 +8892,7 @@
 }
 
 int64x1_t test_vsli_n_s64(int64x1_t a, int64x1_t b) {
-// CHECK: test_vsli_n_s64
+// CHECK-LABEL: test_vsli_n_s64
 // CHECK: sli d{{[0-9]+}}, d{{[0-9]+}}, #1
   return vsli_n_s64(a, b, 1);
 }
@@ -8856,2347 +8904,2840 @@
 }
 
 uint64x1_t test_vsli_n_u64(uint64x1_t a, uint64x1_t b) {
-// CHECK: test_vsli_n_u64
+// CHECK-LABEL: test_vsli_n_u64
 // CHECK: sli d{{[0-9]+}}, d{{[0-9]+}}, #1
   return vsli_n_u64(a, b, 1);
 }
 
 int8_t test_vqshrnh_n_s16(int16_t a) {
 // CHECK-LABEL: test_vqshrnh_n_s16
-// CHECK: sqshrn {{b[0-9]+}}, {{h[0-9]+}}, #15
-  return (int8_t)vqshrnh_n_s16(a, 15);
+// CHECK: sqshrn {{b[0-9]+|v[0-9]+.8b}}, {{h[0-9]+|v[0-9]+.8h}}, #8
+  return (int8_t)vqshrnh_n_s16(a, 8);
 }
 
 int16_t test_vqshrns_n_s32(int32_t a) {
 // CHECK-LABEL: test_vqshrns_n_s32
-// CHECK: sqshrn {{h[0-9]+}}, {{s[0-9]+}}, #31
-  return (int16_t)vqshrns_n_s32(a, 31);
+// CHECK: sqshrn {{h[0-9]+|v[0-9]+.4h}}, {{s[0-9]+|v[0-9]+.4s}}, #16
+  return (int16_t)vqshrns_n_s32(a, 16);
 }
 
 int32_t test_vqshrnd_n_s64(int64_t a) {
 // CHECK-LABEL: test_vqshrnd_n_s64
-// CHECK: sqshrn {{s[0-9]+}}, {{d[0-9]+}}, #63
-  return (int32_t)vqshrnd_n_s64(a, 63);
+// CHECK: sqshrn {{s[0-9]+}}, {{d[0-9]+}}, #32
+  return (int32_t)vqshrnd_n_s64(a, 32);
 }
 
 uint8_t test_vqshrnh_n_u16(uint16_t a) {
 // CHECK-LABEL: test_vqshrnh_n_u16
-// CHECK: uqshrn {{b[0-9]+}}, {{h[0-9]+}}, #15
-  return (uint8_t)vqshrnh_n_u16(a, 15);
+// CHECK: uqshrn {{b[0-9]+|v[0-9]+.8b}}, {{h[0-9]+|v[0-9]+.8h}}, #8
+  return (uint8_t)vqshrnh_n_u16(a, 8);
 }
 
 uint16_t test_vqshrns_n_u32(uint32_t a) {
 // CHECK-LABEL: test_vqshrns_n_u32
-// CHECK: uqshrn {{h[0-9]+}}, {{s[0-9]+}}, #31
-  return (uint16_t)vqshrns_n_u32(a, 31);
+// CHECK: uqshrn {{h[0-9]+|v[0-9]+.4h}}, {{s[0-9]+|v[0-9]+.4s}}, #16
+  return (uint16_t)vqshrns_n_u32(a, 16);
 }
 
 uint32_t test_vqshrnd_n_u64(uint64_t a) {
 // CHECK-LABEL: test_vqshrnd_n_u64
-// CHECK: uqshrn {{s[0-9]+}}, {{d[0-9]+}}, #63
-  return (uint32_t)vqshrnd_n_u64(a, 63);
+// CHECK: uqshrn {{s[0-9]+}}, {{d[0-9]+}}, #32
+  return (uint32_t)vqshrnd_n_u64(a, 32);
 }
 
 int8_t test_vqrshrnh_n_s16(int16_t a) {
 // CHECK-LABEL: test_vqrshrnh_n_s16
-// CHECK: sqrshrn {{b[0-9]+}}, {{h[0-9]+}}, #15
-  return (int8_t)vqrshrnh_n_s16(a, 15);
+// CHECK: sqrshrn {{b[0-9]+|v[0-9]+.8b}}, {{h[0-9]+|v[0-9]+.8h}}, #8
+  return (int8_t)vqrshrnh_n_s16(a, 8);
 }
 
 int16_t test_vqrshrns_n_s32(int32_t a) {
 // CHECK-LABEL: test_vqrshrns_n_s32
-// CHECK: sqrshrn {{h[0-9]+}}, {{s[0-9]+}}, #31
-  return (int16_t)vqrshrns_n_s32(a, 31);
+// CHECK: sqrshrn {{h[0-9]+|v[0-9]+.4h}}, {{s[0-9]+|v[0-9]+.4s}}, #16
+  return (int16_t)vqrshrns_n_s32(a, 16);
 }
 
 int32_t test_vqrshrnd_n_s64(int64_t a) {
 // CHECK-LABEL: test_vqrshrnd_n_s64
-// CHECK: sqrshrn {{s[0-9]+}}, {{d[0-9]+}}, #63
-  return (int32_t)vqrshrnd_n_s64(a, 63);
+// CHECK: sqrshrn {{s[0-9]+}}, {{d[0-9]+}}, #32
+  return (int32_t)vqrshrnd_n_s64(a, 32);
 }
 
 uint8_t test_vqrshrnh_n_u16(uint16_t a) {
 // CHECK-LABEL: test_vqrshrnh_n_u16
-// CHECK: uqrshrn {{b[0-9]+}}, {{h[0-9]+}}, #15
-  return (uint8_t)vqrshrnh_n_u16(a, 15);
+// CHECK: uqrshrn {{b[0-9]+|v[0-9]+.8b}}, {{h[0-9]+|v[0-9]+.8h}}, #8
+  return (uint8_t)vqrshrnh_n_u16(a, 8);
 }
 
 uint16_t test_vqrshrns_n_u32(uint32_t a) {
 // CHECK-LABEL: test_vqrshrns_n_u32
-// CHECK: uqrshrn {{h[0-9]+}}, {{s[0-9]+}}, #31
-  return (uint16_t)vqrshrns_n_u32(a, 31);
+// CHECK: uqrshrn {{h[0-9]+|v[0-9]+.4h}}, {{s[0-9]+|v[0-9]+.4s}}, #16
+  return (uint16_t)vqrshrns_n_u32(a, 16);
 }
 
 uint32_t test_vqrshrnd_n_u64(uint64_t a) {
 // CHECK-LABEL: test_vqrshrnd_n_u64
-// CHECK: uqrshrn {{s[0-9]+}}, {{d[0-9]+}}, #63
-  return (uint32_t)vqrshrnd_n_u64(a, 63);
+// CHECK: uqrshrn {{s[0-9]+}}, {{d[0-9]+}}, #32
+  return (uint32_t)vqrshrnd_n_u64(a, 32);
 }
 
 int8_t test_vqshrunh_n_s16(int16_t a) {
 // CHECK-LABEL: test_vqshrunh_n_s16
-// CHECK: sqshrun {{b[0-9]+}}, {{h[0-9]+}}, #15
-  return (int8_t)vqshrunh_n_s16(a, 15);
+// CHECK: sqshrun {{b[0-9]+|v[0-9]+.8b}}, {{h[0-9]+|v[0-9]+.8h}}, #8
+  return (int8_t)vqshrunh_n_s16(a, 8);
 }
 
 int16_t test_vqshruns_n_s32(int32_t a) {
 // CHECK-LABEL: test_vqshruns_n_s32
-// CHECK: sqshrun {{h[0-9]+}}, {{s[0-9]+}}, #31
-  return (int16_t)vqshruns_n_s32(a, 31);
+// CHECK: sqshrun {{h[0-9]+|v[0-9]+.4h}}, {{s[0-9]+|v[0-9]+.4s}}, #16
+  return (int16_t)vqshruns_n_s32(a, 16);
 }
 
 int32_t test_vqshrund_n_s64(int64_t a) {
 // CHECK-LABEL: test_vqshrund_n_s64
-// CHECK: sqshrun {{s[0-9]+}}, {{d[0-9]+}}, #63
-  return (int32_t)vqshrund_n_s64(a, 63);
+// CHECK: sqshrun {{s[0-9]+}}, {{d[0-9]+}}, #32
+  return (int32_t)vqshrund_n_s64(a, 32);
 }
 
 int8_t test_vqrshrunh_n_s16(int16_t a) {
 // CHECK-LABEL: test_vqrshrunh_n_s16
-// CHECK: sqrshrun {{b[0-9]+}}, {{h[0-9]+}}, #15
-  return (int8_t)vqrshrunh_n_s16(a, 15);
+// CHECK: sqrshrun {{b[0-9]+|v[0-9]+.8b}}, {{h[0-9]+|v[0-9]+.8h}}, #8
+  return (int8_t)vqrshrunh_n_s16(a, 8);
 }
 
 int16_t test_vqrshruns_n_s32(int32_t a) {
 // CHECK-LABEL: test_vqrshruns_n_s32
-// CHECK: sqrshrun {{h[0-9]+}}, {{s[0-9]+}}, #31
-  return (int16_t)vqrshruns_n_s32(a, 31);
+// CHECK: sqrshrun {{h[0-9]+|v[0-9]+.4h}}, {{s[0-9]+|v[0-9]+.4s}}, #16
+  return (int16_t)vqrshruns_n_s32(a, 16);
 }
 
 int32_t test_vqrshrund_n_s64(int64_t a) {
 // CHECK-LABEL: test_vqrshrund_n_s64
-// CHECK: sqrshrun {{s[0-9]+}}, {{d[0-9]+}}, #63
-  return (int32_t)vqrshrund_n_s64(a, 63);
+// CHECK: sqrshrun {{s[0-9]+}}, {{d[0-9]+}}, #32
+  return (int32_t)vqrshrund_n_s64(a, 32);
 }
 
 float32_t test_vcvts_n_f32_s32(int32_t a) {
-// CHECK: test_vcvts_n_f32_s32
+// CHECK-LABEL: test_vcvts_n_f32_s32
 // CHECK: scvtf {{s[0-9]+}}, {{s[0-9]+}}, #1
   return vcvts_n_f32_s32(a, 1);
 }
 
 float64_t test_vcvtd_n_f64_s64(int64_t a) {
-// CHECK: test_vcvtd_n_f64_s64
+// CHECK-LABEL: test_vcvtd_n_f64_s64
 // CHECK: scvtf {{d[0-9]+}}, {{d[0-9]+}}, #1
   return vcvtd_n_f64_s64(a, 1);
 }
 
 float32_t test_vcvts_n_f32_u32(uint32_t a) {
-// CHECK: test_vcvts_n_f32_u32
+// CHECK-LABEL: test_vcvts_n_f32_u32
 // CHECK: ucvtf {{s[0-9]+}}, {{s[0-9]+}}, #32
   return vcvts_n_f32_u32(a, 32);
 }
 
 float64_t test_vcvtd_n_f64_u64(uint64_t a) {
-// CHECK: test_vcvtd_n_f64_u64
+// CHECK-LABEL: test_vcvtd_n_f64_u64
 // CHECK: ucvtf {{d[0-9]+}}, {{d[0-9]+}}, #64
   return vcvtd_n_f64_u64(a, 64);
 }
 
 int32_t test_vcvts_n_s32_f32(float32_t a) {
-// CHECK: test_vcvts_n_s32_f32
+// CHECK-LABEL: test_vcvts_n_s32_f32
 // CHECK: fcvtzs {{s[0-9]+}}, {{s[0-9]+}}, #1
   return (int32_t)vcvts_n_s32_f32(a, 1);
 }
 
 int64_t test_vcvtd_n_s64_f64(float64_t a) {
-// CHECK: test_vcvtd_n_s64_f64
+// CHECK-LABEL: test_vcvtd_n_s64_f64
 // CHECK: fcvtzs {{d[0-9]+}}, {{d[0-9]+}}, #1
   return (int64_t)vcvtd_n_s64_f64(a, 1);
 }
 
 uint32_t test_vcvts_n_u32_f32(float32_t a) {
-// CHECK: test_vcvts_n_u32_f32
+// CHECK-LABEL: test_vcvts_n_u32_f32
 // CHECK: fcvtzu {{s[0-9]+}}, {{s[0-9]+}}, #32
   return (uint32_t)vcvts_n_u32_f32(a, 32);
 }
 
 uint64_t test_vcvtd_n_u64_f64(float64_t a) {
-// CHECK: test_vcvtd_n_u64_f64
+// CHECK-LABEL: test_vcvtd_n_u64_f64
 // CHECK: fcvtzu {{d[0-9]+}}, {{d[0-9]+}}, #64
   return (uint64_t)vcvtd_n_u64_f64(a, 64);
 }
 
-// CHECK-LABEL: test_vreinterpret_s8_s16
+// CHECK-LABEL: test_vreinterpret_s8_s16:
 // CHECK-NEXT: ret
 int8x8_t test_vreinterpret_s8_s16(int16x4_t a) {
   return vreinterpret_s8_s16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s8_s32
+// CHECK-LABEL: test_vreinterpret_s8_s32:
 // CHECK-NEXT: ret
 int8x8_t test_vreinterpret_s8_s32(int32x2_t a) {
   return vreinterpret_s8_s32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s8_s64
+// CHECK-LABEL: test_vreinterpret_s8_s64:
 // CHECK-NEXT: ret
 int8x8_t test_vreinterpret_s8_s64(int64x1_t a) {
   return vreinterpret_s8_s64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s8_u8
+// CHECK-LABEL: test_vreinterpret_s8_u8:
 // CHECK-NEXT: ret
 int8x8_t test_vreinterpret_s8_u8(uint8x8_t a) {
   return vreinterpret_s8_u8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s8_u16
+// CHECK-LABEL: test_vreinterpret_s8_u16:
 // CHECK-NEXT: ret
 int8x8_t test_vreinterpret_s8_u16(uint16x4_t a) {
   return vreinterpret_s8_u16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s8_u32
+// CHECK-LABEL: test_vreinterpret_s8_u32:
 // CHECK-NEXT: ret
 int8x8_t test_vreinterpret_s8_u32(uint32x2_t a) {
   return vreinterpret_s8_u32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s8_u64
+// CHECK-LABEL: test_vreinterpret_s8_u64:
 // CHECK-NEXT: ret
 int8x8_t test_vreinterpret_s8_u64(uint64x1_t a) {
   return vreinterpret_s8_u64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s8_f16
+// CHECK-LABEL: test_vreinterpret_s8_f16:
 // CHECK-NEXT: ret
 int8x8_t test_vreinterpret_s8_f16(float16x4_t a) {
   return vreinterpret_s8_f16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s8_f32
+// CHECK-LABEL: test_vreinterpret_s8_f32:
 // CHECK-NEXT: ret
 int8x8_t test_vreinterpret_s8_f32(float32x2_t a) {
   return vreinterpret_s8_f32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s8_f64
+// CHECK-LABEL: test_vreinterpret_s8_f64:
 // CHECK-NEXT: ret
 int8x8_t test_vreinterpret_s8_f64(float64x1_t a) {
   return vreinterpret_s8_f64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s8_p8
+// CHECK-LABEL: test_vreinterpret_s8_p8:
 // CHECK-NEXT: ret
 int8x8_t test_vreinterpret_s8_p8(poly8x8_t a) {
   return vreinterpret_s8_p8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s8_p16
+// CHECK-LABEL: test_vreinterpret_s8_p16:
 // CHECK-NEXT: ret
 int8x8_t test_vreinterpret_s8_p16(poly16x4_t a) {
   return vreinterpret_s8_p16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s8_p64
+// CHECK-LABEL: test_vreinterpret_s8_p64:
 // CHECK-NEXT: ret
 int8x8_t test_vreinterpret_s8_p64(poly64x1_t a) {
   return vreinterpret_s8_p64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s16_s8
+// CHECK-LABEL: test_vreinterpret_s16_s8:
 // CHECK-NEXT: ret
 int16x4_t test_vreinterpret_s16_s8(int8x8_t a) {
   return vreinterpret_s16_s8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s16_s32
+// CHECK-LABEL: test_vreinterpret_s16_s32:
 // CHECK-NEXT: ret
 int16x4_t test_vreinterpret_s16_s32(int32x2_t a) {
   return vreinterpret_s16_s32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s16_s64
+// CHECK-LABEL: test_vreinterpret_s16_s64:
 // CHECK-NEXT: ret
 int16x4_t test_vreinterpret_s16_s64(int64x1_t a) {
   return vreinterpret_s16_s64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s16_u8
+// CHECK-LABEL: test_vreinterpret_s16_u8:
 // CHECK-NEXT: ret
 int16x4_t test_vreinterpret_s16_u8(uint8x8_t a) {
   return vreinterpret_s16_u8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s16_u16
+// CHECK-LABEL: test_vreinterpret_s16_u16:
 // CHECK-NEXT: ret
 int16x4_t test_vreinterpret_s16_u16(uint16x4_t a) {
   return vreinterpret_s16_u16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s16_u32
+// CHECK-LABEL: test_vreinterpret_s16_u32:
 // CHECK-NEXT: ret
 int16x4_t test_vreinterpret_s16_u32(uint32x2_t a) {
   return vreinterpret_s16_u32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s16_u64
+// CHECK-LABEL: test_vreinterpret_s16_u64:
 // CHECK-NEXT: ret
 int16x4_t test_vreinterpret_s16_u64(uint64x1_t a) {
   return vreinterpret_s16_u64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s16_f16
+// CHECK-LABEL: test_vreinterpret_s16_f16:
 // CHECK-NEXT: ret
 int16x4_t test_vreinterpret_s16_f16(float16x4_t a) {
   return vreinterpret_s16_f16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s16_f32
+// CHECK-LABEL: test_vreinterpret_s16_f32:
 // CHECK-NEXT: ret
 int16x4_t test_vreinterpret_s16_f32(float32x2_t a) {
   return vreinterpret_s16_f32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s16_f64
+// CHECK-LABEL: test_vreinterpret_s16_f64:
 // CHECK-NEXT: ret
 int16x4_t test_vreinterpret_s16_f64(float64x1_t a) {
   return vreinterpret_s16_f64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s16_p8
+// CHECK-LABEL: test_vreinterpret_s16_p8:
 // CHECK-NEXT: ret
 int16x4_t test_vreinterpret_s16_p8(poly8x8_t a) {
   return vreinterpret_s16_p8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s16_p16
+// CHECK-LABEL: test_vreinterpret_s16_p16:
 // CHECK-NEXT: ret
 int16x4_t test_vreinterpret_s16_p16(poly16x4_t a) {
   return vreinterpret_s16_p16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s16_p64
+// CHECK-LABEL: test_vreinterpret_s16_p64:
 // CHECK-NEXT: ret
 int16x4_t test_vreinterpret_s16_p64(poly64x1_t a) {
   return vreinterpret_s16_p64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s32_s8
+// CHECK-LABEL: test_vreinterpret_s32_s8:
 // CHECK-NEXT: ret
 int32x2_t test_vreinterpret_s32_s8(int8x8_t a) {
   return vreinterpret_s32_s8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s32_s16
+// CHECK-LABEL: test_vreinterpret_s32_s16:
 // CHECK-NEXT: ret
 int32x2_t test_vreinterpret_s32_s16(int16x4_t a) {
   return vreinterpret_s32_s16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s32_s64
+// CHECK-LABEL: test_vreinterpret_s32_s64:
 // CHECK-NEXT: ret
 int32x2_t test_vreinterpret_s32_s64(int64x1_t a) {
   return vreinterpret_s32_s64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s32_u8
+// CHECK-LABEL: test_vreinterpret_s32_u8:
 // CHECK-NEXT: ret
 int32x2_t test_vreinterpret_s32_u8(uint8x8_t a) {
   return vreinterpret_s32_u8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s32_u16
+// CHECK-LABEL: test_vreinterpret_s32_u16:
 // CHECK-NEXT: ret
 int32x2_t test_vreinterpret_s32_u16(uint16x4_t a) {
   return vreinterpret_s32_u16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s32_u32
+// CHECK-LABEL: test_vreinterpret_s32_u32:
 // CHECK-NEXT: ret
 int32x2_t test_vreinterpret_s32_u32(uint32x2_t a) {
   return vreinterpret_s32_u32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s32_u64
+// CHECK-LABEL: test_vreinterpret_s32_u64:
 // CHECK-NEXT: ret
 int32x2_t test_vreinterpret_s32_u64(uint64x1_t a) {
   return vreinterpret_s32_u64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s32_f16
+// CHECK-LABEL: test_vreinterpret_s32_f16:
 // CHECK-NEXT: ret
 int32x2_t test_vreinterpret_s32_f16(float16x4_t a) {
   return vreinterpret_s32_f16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s32_f32
+// CHECK-LABEL: test_vreinterpret_s32_f32:
 // CHECK-NEXT: ret
 int32x2_t test_vreinterpret_s32_f32(float32x2_t a) {
   return vreinterpret_s32_f32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s32_f64
+// CHECK-LABEL: test_vreinterpret_s32_f64:
 // CHECK-NEXT: ret
 int32x2_t test_vreinterpret_s32_f64(float64x1_t a) {
   return vreinterpret_s32_f64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s32_p8
+// CHECK-LABEL: test_vreinterpret_s32_p8:
 // CHECK-NEXT: ret
 int32x2_t test_vreinterpret_s32_p8(poly8x8_t a) {
   return vreinterpret_s32_p8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s32_p16
+// CHECK-LABEL: test_vreinterpret_s32_p16:
 // CHECK-NEXT: ret
 int32x2_t test_vreinterpret_s32_p16(poly16x4_t a) {
   return vreinterpret_s32_p16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s32_p64
+// CHECK-LABEL: test_vreinterpret_s32_p64:
 // CHECK-NEXT: ret
 int32x2_t test_vreinterpret_s32_p64(poly64x1_t a) {
   return vreinterpret_s32_p64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s64_s8
+// CHECK-LABEL: test_vreinterpret_s64_s8:
 // CHECK-NEXT: ret
 int64x1_t test_vreinterpret_s64_s8(int8x8_t a) {
   return vreinterpret_s64_s8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s64_s16
+// CHECK-LABEL: test_vreinterpret_s64_s16:
 // CHECK-NEXT: ret
 int64x1_t test_vreinterpret_s64_s16(int16x4_t a) {
   return vreinterpret_s64_s16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s64_s32
+// CHECK-LABEL: test_vreinterpret_s64_s32:
 // CHECK-NEXT: ret
 int64x1_t test_vreinterpret_s64_s32(int32x2_t a) {
   return vreinterpret_s64_s32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s64_u8
+// CHECK-LABEL: test_vreinterpret_s64_u8:
 // CHECK-NEXT: ret
 int64x1_t test_vreinterpret_s64_u8(uint8x8_t a) {
   return vreinterpret_s64_u8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s64_u16
+// CHECK-LABEL: test_vreinterpret_s64_u16:
 // CHECK-NEXT: ret
 int64x1_t test_vreinterpret_s64_u16(uint16x4_t a) {
   return vreinterpret_s64_u16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s64_u32
+// CHECK-LABEL: test_vreinterpret_s64_u32:
 // CHECK-NEXT: ret
 int64x1_t test_vreinterpret_s64_u32(uint32x2_t a) {
   return vreinterpret_s64_u32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s64_u64
+// CHECK-LABEL: test_vreinterpret_s64_u64:
 // CHECK-NEXT: ret
 int64x1_t test_vreinterpret_s64_u64(uint64x1_t a) {
   return vreinterpret_s64_u64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s64_f16
+// CHECK-LABEL: test_vreinterpret_s64_f16:
 // CHECK-NEXT: ret
 int64x1_t test_vreinterpret_s64_f16(float16x4_t a) {
   return vreinterpret_s64_f16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s64_f32
+// CHECK-LABEL: test_vreinterpret_s64_f32:
 // CHECK-NEXT: ret
 int64x1_t test_vreinterpret_s64_f32(float32x2_t a) {
   return vreinterpret_s64_f32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s64_f64
+// CHECK-LABEL: test_vreinterpret_s64_f64:
 // CHECK-NEXT: ret
 int64x1_t test_vreinterpret_s64_f64(float64x1_t a) {
   return vreinterpret_s64_f64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s64_p8
+// CHECK-LABEL: test_vreinterpret_s64_p8:
 // CHECK-NEXT: ret
 int64x1_t test_vreinterpret_s64_p8(poly8x8_t a) {
   return vreinterpret_s64_p8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s64_p16
+// CHECK-LABEL: test_vreinterpret_s64_p16:
 // CHECK-NEXT: ret
 int64x1_t test_vreinterpret_s64_p16(poly16x4_t a) {
   return vreinterpret_s64_p16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_s64_p64
+// CHECK-LABEL: test_vreinterpret_s64_p64:
 // CHECK-NEXT: ret
 int64x1_t test_vreinterpret_s64_p64(poly64x1_t a) {
   return vreinterpret_s64_p64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u8_s8
+// CHECK-LABEL: test_vreinterpret_u8_s8:
 // CHECK-NEXT: ret
 uint8x8_t test_vreinterpret_u8_s8(int8x8_t a) {
   return vreinterpret_u8_s8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u8_s16
+// CHECK-LABEL: test_vreinterpret_u8_s16:
 // CHECK-NEXT: ret
 uint8x8_t test_vreinterpret_u8_s16(int16x4_t a) {
   return vreinterpret_u8_s16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u8_s32
+// CHECK-LABEL: test_vreinterpret_u8_s32:
 // CHECK-NEXT: ret
 uint8x8_t test_vreinterpret_u8_s32(int32x2_t a) {
   return vreinterpret_u8_s32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u8_s64
+// CHECK-LABEL: test_vreinterpret_u8_s64:
 // CHECK-NEXT: ret
 uint8x8_t test_vreinterpret_u8_s64(int64x1_t a) {
   return vreinterpret_u8_s64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u8_u16
+// CHECK-LABEL: test_vreinterpret_u8_u16:
 // CHECK-NEXT: ret
 uint8x8_t test_vreinterpret_u8_u16(uint16x4_t a) {
   return vreinterpret_u8_u16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u8_u32
+// CHECK-LABEL: test_vreinterpret_u8_u32:
 // CHECK-NEXT: ret
 uint8x8_t test_vreinterpret_u8_u32(uint32x2_t a) {
   return vreinterpret_u8_u32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u8_u64
+// CHECK-LABEL: test_vreinterpret_u8_u64:
 // CHECK-NEXT: ret
 uint8x8_t test_vreinterpret_u8_u64(uint64x1_t a) {
   return vreinterpret_u8_u64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u8_f16
+// CHECK-LABEL: test_vreinterpret_u8_f16:
 // CHECK-NEXT: ret
 uint8x8_t test_vreinterpret_u8_f16(float16x4_t a) {
   return vreinterpret_u8_f16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u8_f32
+// CHECK-LABEL: test_vreinterpret_u8_f32:
 // CHECK-NEXT: ret
 uint8x8_t test_vreinterpret_u8_f32(float32x2_t a) {
   return vreinterpret_u8_f32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u8_f64
+// CHECK-LABEL: test_vreinterpret_u8_f64:
 // CHECK-NEXT: ret
 uint8x8_t test_vreinterpret_u8_f64(float64x1_t a) {
   return vreinterpret_u8_f64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u8_p8
+// CHECK-LABEL: test_vreinterpret_u8_p8:
 // CHECK-NEXT: ret
 uint8x8_t test_vreinterpret_u8_p8(poly8x8_t a) {
   return vreinterpret_u8_p8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u8_p16
+// CHECK-LABEL: test_vreinterpret_u8_p16:
 // CHECK-NEXT: ret
 uint8x8_t test_vreinterpret_u8_p16(poly16x4_t a) {
   return vreinterpret_u8_p16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u8_p64
+// CHECK-LABEL: test_vreinterpret_u8_p64:
 // CHECK-NEXT: ret
 uint8x8_t test_vreinterpret_u8_p64(poly64x1_t a) {
   return vreinterpret_u8_p64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u16_s8
+// CHECK-LABEL: test_vreinterpret_u16_s8:
 // CHECK-NEXT: ret
 uint16x4_t test_vreinterpret_u16_s8(int8x8_t a) {
   return vreinterpret_u16_s8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u16_s16
+// CHECK-LABEL: test_vreinterpret_u16_s16:
 // CHECK-NEXT: ret
 uint16x4_t test_vreinterpret_u16_s16(int16x4_t a) {
   return vreinterpret_u16_s16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u16_s32
+// CHECK-LABEL: test_vreinterpret_u16_s32:
 // CHECK-NEXT: ret
 uint16x4_t test_vreinterpret_u16_s32(int32x2_t a) {
   return vreinterpret_u16_s32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u16_s64
+// CHECK-LABEL: test_vreinterpret_u16_s64:
 // CHECK-NEXT: ret
 uint16x4_t test_vreinterpret_u16_s64(int64x1_t a) {
   return vreinterpret_u16_s64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u16_u8
+// CHECK-LABEL: test_vreinterpret_u16_u8:
 // CHECK-NEXT: ret
 uint16x4_t test_vreinterpret_u16_u8(uint8x8_t a) {
   return vreinterpret_u16_u8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u16_u32
+// CHECK-LABEL: test_vreinterpret_u16_u32:
 // CHECK-NEXT: ret
 uint16x4_t test_vreinterpret_u16_u32(uint32x2_t a) {
   return vreinterpret_u16_u32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u16_u64
+// CHECK-LABEL: test_vreinterpret_u16_u64:
 // CHECK-NEXT: ret
 uint16x4_t test_vreinterpret_u16_u64(uint64x1_t a) {
   return vreinterpret_u16_u64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u16_f16
+// CHECK-LABEL: test_vreinterpret_u16_f16:
 // CHECK-NEXT: ret
 uint16x4_t test_vreinterpret_u16_f16(float16x4_t a) {
   return vreinterpret_u16_f16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u16_f32
+// CHECK-LABEL: test_vreinterpret_u16_f32:
 // CHECK-NEXT: ret
 uint16x4_t test_vreinterpret_u16_f32(float32x2_t a) {
   return vreinterpret_u16_f32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u16_f64
+// CHECK-LABEL: test_vreinterpret_u16_f64:
 // CHECK-NEXT: ret
 uint16x4_t test_vreinterpret_u16_f64(float64x1_t a) {
   return vreinterpret_u16_f64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u16_p8
+// CHECK-LABEL: test_vreinterpret_u16_p8:
 // CHECK-NEXT: ret
 uint16x4_t test_vreinterpret_u16_p8(poly8x8_t a) {
   return vreinterpret_u16_p8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u16_p16
+// CHECK-LABEL: test_vreinterpret_u16_p16:
 // CHECK-NEXT: ret
 uint16x4_t test_vreinterpret_u16_p16(poly16x4_t a) {
   return vreinterpret_u16_p16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u16_p64
+// CHECK-LABEL: test_vreinterpret_u16_p64:
 // CHECK-NEXT: ret
 uint16x4_t test_vreinterpret_u16_p64(poly64x1_t a) {
   return vreinterpret_u16_p64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u32_s8
+// CHECK-LABEL: test_vreinterpret_u32_s8:
 // CHECK-NEXT: ret
 uint32x2_t test_vreinterpret_u32_s8(int8x8_t a) {
   return vreinterpret_u32_s8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u32_s16
+// CHECK-LABEL: test_vreinterpret_u32_s16:
 // CHECK-NEXT: ret
 uint32x2_t test_vreinterpret_u32_s16(int16x4_t a) {
   return vreinterpret_u32_s16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u32_s32
+// CHECK-LABEL: test_vreinterpret_u32_s32:
 // CHECK-NEXT: ret
 uint32x2_t test_vreinterpret_u32_s32(int32x2_t a) {
   return vreinterpret_u32_s32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u32_s64
+// CHECK-LABEL: test_vreinterpret_u32_s64:
 // CHECK-NEXT: ret
 uint32x2_t test_vreinterpret_u32_s64(int64x1_t a) {
   return vreinterpret_u32_s64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u32_u8
+// CHECK-LABEL: test_vreinterpret_u32_u8:
 // CHECK-NEXT: ret
 uint32x2_t test_vreinterpret_u32_u8(uint8x8_t a) {
   return vreinterpret_u32_u8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u32_u16
+// CHECK-LABEL: test_vreinterpret_u32_u16:
 // CHECK-NEXT: ret
 uint32x2_t test_vreinterpret_u32_u16(uint16x4_t a) {
   return vreinterpret_u32_u16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u32_u64
+// CHECK-LABEL: test_vreinterpret_u32_u64:
 // CHECK-NEXT: ret
 uint32x2_t test_vreinterpret_u32_u64(uint64x1_t a) {
   return vreinterpret_u32_u64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u32_f16
+// CHECK-LABEL: test_vreinterpret_u32_f16:
 // CHECK-NEXT: ret
 uint32x2_t test_vreinterpret_u32_f16(float16x4_t a) {
   return vreinterpret_u32_f16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u32_f32
+// CHECK-LABEL: test_vreinterpret_u32_f32:
 // CHECK-NEXT: ret
 uint32x2_t test_vreinterpret_u32_f32(float32x2_t a) {
   return vreinterpret_u32_f32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u32_f64
+// CHECK-LABEL: test_vreinterpret_u32_f64:
 // CHECK-NEXT: ret
 uint32x2_t test_vreinterpret_u32_f64(float64x1_t a) {
   return vreinterpret_u32_f64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u32_p8
+// CHECK-LABEL: test_vreinterpret_u32_p8:
 // CHECK-NEXT: ret
 uint32x2_t test_vreinterpret_u32_p8(poly8x8_t a) {
   return vreinterpret_u32_p8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u32_p16
+// CHECK-LABEL: test_vreinterpret_u32_p16:
 // CHECK-NEXT: ret
 uint32x2_t test_vreinterpret_u32_p16(poly16x4_t a) {
   return vreinterpret_u32_p16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u32_p64
+// CHECK-LABEL: test_vreinterpret_u32_p64:
 // CHECK-NEXT: ret
 uint32x2_t test_vreinterpret_u32_p64(poly64x1_t a) {
   return vreinterpret_u32_p64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u64_s8
+// CHECK-LABEL: test_vreinterpret_u64_s8:
 // CHECK-NEXT: ret
 uint64x1_t test_vreinterpret_u64_s8(int8x8_t a) {
   return vreinterpret_u64_s8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u64_s16
+// CHECK-LABEL: test_vreinterpret_u64_s16:
 // CHECK-NEXT: ret
 uint64x1_t test_vreinterpret_u64_s16(int16x4_t a) {
   return vreinterpret_u64_s16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u64_s32
+// CHECK-LABEL: test_vreinterpret_u64_s32:
 // CHECK-NEXT: ret
 uint64x1_t test_vreinterpret_u64_s32(int32x2_t a) {
   return vreinterpret_u64_s32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u64_s64
+// CHECK-LABEL: test_vreinterpret_u64_s64:
 // CHECK-NEXT: ret
 uint64x1_t test_vreinterpret_u64_s64(int64x1_t a) {
   return vreinterpret_u64_s64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u64_u8
+// CHECK-LABEL: test_vreinterpret_u64_u8:
 // CHECK-NEXT: ret
 uint64x1_t test_vreinterpret_u64_u8(uint8x8_t a) {
   return vreinterpret_u64_u8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u64_u16
+// CHECK-LABEL: test_vreinterpret_u64_u16:
 // CHECK-NEXT: ret
 uint64x1_t test_vreinterpret_u64_u16(uint16x4_t a) {
   return vreinterpret_u64_u16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u64_u32
+// CHECK-LABEL: test_vreinterpret_u64_u32:
 // CHECK-NEXT: ret
 uint64x1_t test_vreinterpret_u64_u32(uint32x2_t a) {
   return vreinterpret_u64_u32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u64_f16
+// CHECK-LABEL: test_vreinterpret_u64_f16:
 // CHECK-NEXT: ret
 uint64x1_t test_vreinterpret_u64_f16(float16x4_t a) {
   return vreinterpret_u64_f16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u64_f32
+// CHECK-LABEL: test_vreinterpret_u64_f32:
 // CHECK-NEXT: ret
 uint64x1_t test_vreinterpret_u64_f32(float32x2_t a) {
   return vreinterpret_u64_f32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u64_f64
+// CHECK-LABEL: test_vreinterpret_u64_f64:
 // CHECK-NEXT: ret
 uint64x1_t test_vreinterpret_u64_f64(float64x1_t a) {
   return vreinterpret_u64_f64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u64_p8
+// CHECK-LABEL: test_vreinterpret_u64_p8:
 // CHECK-NEXT: ret
 uint64x1_t test_vreinterpret_u64_p8(poly8x8_t a) {
   return vreinterpret_u64_p8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u64_p16
+// CHECK-LABEL: test_vreinterpret_u64_p16:
 // CHECK-NEXT: ret
 uint64x1_t test_vreinterpret_u64_p16(poly16x4_t a) {
   return vreinterpret_u64_p16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_u64_p64
+// CHECK-LABEL: test_vreinterpret_u64_p64:
 // CHECK-NEXT: ret
 uint64x1_t test_vreinterpret_u64_p64(poly64x1_t a) {
   return vreinterpret_u64_p64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f16_s8
+// CHECK-LABEL: test_vreinterpret_f16_s8:
 // CHECK-NEXT: ret
 float16x4_t test_vreinterpret_f16_s8(int8x8_t a) {
   return vreinterpret_f16_s8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f16_s16
+// CHECK-LABEL: test_vreinterpret_f16_s16:
 // CHECK-NEXT: ret
 float16x4_t test_vreinterpret_f16_s16(int16x4_t a) {
   return vreinterpret_f16_s16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f16_s32
+// CHECK-LABEL: test_vreinterpret_f16_s32:
 // CHECK-NEXT: ret
 float16x4_t test_vreinterpret_f16_s32(int32x2_t a) {
   return vreinterpret_f16_s32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f16_s64
+// CHECK-LABEL: test_vreinterpret_f16_s64:
 // CHECK-NEXT: ret
 float16x4_t test_vreinterpret_f16_s64(int64x1_t a) {
   return vreinterpret_f16_s64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f16_u8
+// CHECK-LABEL: test_vreinterpret_f16_u8:
 // CHECK-NEXT: ret
 float16x4_t test_vreinterpret_f16_u8(uint8x8_t a) {
   return vreinterpret_f16_u8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f16_u16
+// CHECK-LABEL: test_vreinterpret_f16_u16:
 // CHECK-NEXT: ret
 float16x4_t test_vreinterpret_f16_u16(uint16x4_t a) {
   return vreinterpret_f16_u16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f16_u32
+// CHECK-LABEL: test_vreinterpret_f16_u32:
 // CHECK-NEXT: ret
 float16x4_t test_vreinterpret_f16_u32(uint32x2_t a) {
   return vreinterpret_f16_u32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f16_u64
+// CHECK-LABEL: test_vreinterpret_f16_u64:
 // CHECK-NEXT: ret
 float16x4_t test_vreinterpret_f16_u64(uint64x1_t a) {
   return vreinterpret_f16_u64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f16_f32
+// CHECK-LABEL: test_vreinterpret_f16_f32:
 // CHECK-NEXT: ret
 float16x4_t test_vreinterpret_f16_f32(float32x2_t a) {
   return vreinterpret_f16_f32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f16_f64
+// CHECK-LABEL: test_vreinterpret_f16_f64:
 // CHECK-NEXT: ret
 float16x4_t test_vreinterpret_f16_f64(float64x1_t a) {
   return vreinterpret_f16_f64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f16_p8
+// CHECK-LABEL: test_vreinterpret_f16_p8:
 // CHECK-NEXT: ret
 float16x4_t test_vreinterpret_f16_p8(poly8x8_t a) {
   return vreinterpret_f16_p8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f16_p16
+// CHECK-LABEL: test_vreinterpret_f16_p16:
 // CHECK-NEXT: ret
 float16x4_t test_vreinterpret_f16_p16(poly16x4_t a) {
   return vreinterpret_f16_p16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f16_p64
+// CHECK-LABEL: test_vreinterpret_f16_p64:
 // CHECK-NEXT: ret
 float16x4_t test_vreinterpret_f16_p64(poly64x1_t a) {
   return vreinterpret_f16_p64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f32_s8
+// CHECK-LABEL: test_vreinterpret_f32_s8:
 // CHECK-NEXT: ret
 float32x2_t test_vreinterpret_f32_s8(int8x8_t a) {
   return vreinterpret_f32_s8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f32_s16
+// CHECK-LABEL: test_vreinterpret_f32_s16:
 // CHECK-NEXT: ret
 float32x2_t test_vreinterpret_f32_s16(int16x4_t a) {
   return vreinterpret_f32_s16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f32_s32
+// CHECK-LABEL: test_vreinterpret_f32_s32:
 // CHECK-NEXT: ret
 float32x2_t test_vreinterpret_f32_s32(int32x2_t a) {
   return vreinterpret_f32_s32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f32_s64
+// CHECK-LABEL: test_vreinterpret_f32_s64:
 // CHECK-NEXT: ret
 float32x2_t test_vreinterpret_f32_s64(int64x1_t a) {
   return vreinterpret_f32_s64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f32_u8
+// CHECK-LABEL: test_vreinterpret_f32_u8:
 // CHECK-NEXT: ret
 float32x2_t test_vreinterpret_f32_u8(uint8x8_t a) {
   return vreinterpret_f32_u8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f32_u16
+// CHECK-LABEL: test_vreinterpret_f32_u16:
 // CHECK-NEXT: ret
 float32x2_t test_vreinterpret_f32_u16(uint16x4_t a) {
   return vreinterpret_f32_u16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f32_u32
+// CHECK-LABEL: test_vreinterpret_f32_u32:
 // CHECK-NEXT: ret
 float32x2_t test_vreinterpret_f32_u32(uint32x2_t a) {
   return vreinterpret_f32_u32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f32_u64
+// CHECK-LABEL: test_vreinterpret_f32_u64:
 // CHECK-NEXT: ret
 float32x2_t test_vreinterpret_f32_u64(uint64x1_t a) {
   return vreinterpret_f32_u64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f32_f16
+// CHECK-LABEL: test_vreinterpret_f32_f16:
 // CHECK-NEXT: ret
 float32x2_t test_vreinterpret_f32_f16(float16x4_t a) {
   return vreinterpret_f32_f16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f32_f64
+// CHECK-LABEL: test_vreinterpret_f32_f64:
 // CHECK-NEXT: ret
 float32x2_t test_vreinterpret_f32_f64(float64x1_t a) {
   return vreinterpret_f32_f64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f32_p8
+// CHECK-LABEL: test_vreinterpret_f32_p8:
 // CHECK-NEXT: ret
 float32x2_t test_vreinterpret_f32_p8(poly8x8_t a) {
   return vreinterpret_f32_p8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f32_p16
+// CHECK-LABEL: test_vreinterpret_f32_p16:
 // CHECK-NEXT: ret
 float32x2_t test_vreinterpret_f32_p16(poly16x4_t a) {
   return vreinterpret_f32_p16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f32_p64
+// CHECK-LABEL: test_vreinterpret_f32_p64:
 // CHECK-NEXT: ret
 float32x2_t test_vreinterpret_f32_p64(poly64x1_t a) {
   return vreinterpret_f32_p64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f64_s8
+// CHECK-LABEL: test_vreinterpret_f64_s8:
 // CHECK-NEXT: ret
 float64x1_t test_vreinterpret_f64_s8(int8x8_t a) {
   return vreinterpret_f64_s8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f64_s16
+// CHECK-LABEL: test_vreinterpret_f64_s16:
 // CHECK-NEXT: ret
 float64x1_t test_vreinterpret_f64_s16(int16x4_t a) {
   return vreinterpret_f64_s16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f64_s32
+// CHECK-LABEL: test_vreinterpret_f64_s32:
 // CHECK-NEXT: ret
 float64x1_t test_vreinterpret_f64_s32(int32x2_t a) {
   return vreinterpret_f64_s32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f64_s64
+// CHECK-LABEL: test_vreinterpret_f64_s64:
 // CHECK-NEXT: ret
 float64x1_t test_vreinterpret_f64_s64(int64x1_t a) {
   return vreinterpret_f64_s64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f64_u8
+// CHECK-LABEL: test_vreinterpret_f64_u8:
 // CHECK-NEXT: ret
 float64x1_t test_vreinterpret_f64_u8(uint8x8_t a) {
   return vreinterpret_f64_u8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f64_u16
+// CHECK-LABEL: test_vreinterpret_f64_u16:
 // CHECK-NEXT: ret
 float64x1_t test_vreinterpret_f64_u16(uint16x4_t a) {
   return vreinterpret_f64_u16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f64_u32
+// CHECK-LABEL: test_vreinterpret_f64_u32:
 // CHECK-NEXT: ret
 float64x1_t test_vreinterpret_f64_u32(uint32x2_t a) {
   return vreinterpret_f64_u32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f64_u64
+// CHECK-LABEL: test_vreinterpret_f64_u64:
 // CHECK-NEXT: ret
 float64x1_t test_vreinterpret_f64_u64(uint64x1_t a) {
   return vreinterpret_f64_u64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f64_f16
+// CHECK-LABEL: test_vreinterpret_f64_f16:
 // CHECK-NEXT: ret
 float64x1_t test_vreinterpret_f64_f16(float16x4_t a) {
   return vreinterpret_f64_f16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f64_f32
+// CHECK-LABEL: test_vreinterpret_f64_f32:
 // CHECK-NEXT: ret
 float64x1_t test_vreinterpret_f64_f32(float32x2_t a) {
   return vreinterpret_f64_f32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f64_p8
+// CHECK-LABEL: test_vreinterpret_f64_p8:
 // CHECK-NEXT: ret
 float64x1_t test_vreinterpret_f64_p8(poly8x8_t a) {
   return vreinterpret_f64_p8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f64_p16
+// CHECK-LABEL: test_vreinterpret_f64_p16:
 // CHECK-NEXT: ret
 float64x1_t test_vreinterpret_f64_p16(poly16x4_t a) {
   return vreinterpret_f64_p16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_f64_p64
+// CHECK-LABEL: test_vreinterpret_f64_p64:
 // CHECK-NEXT: ret
 float64x1_t test_vreinterpret_f64_p64(poly64x1_t a) {
   return vreinterpret_f64_p64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p8_s8
+// CHECK-LABEL: test_vreinterpret_p8_s8:
 // CHECK-NEXT: ret
 poly8x8_t test_vreinterpret_p8_s8(int8x8_t a) {
   return vreinterpret_p8_s8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p8_s16
+// CHECK-LABEL: test_vreinterpret_p8_s16:
 // CHECK-NEXT: ret
 poly8x8_t test_vreinterpret_p8_s16(int16x4_t a) {
   return vreinterpret_p8_s16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p8_s32
+// CHECK-LABEL: test_vreinterpret_p8_s32:
 // CHECK-NEXT: ret
 poly8x8_t test_vreinterpret_p8_s32(int32x2_t a) {
   return vreinterpret_p8_s32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p8_s64
+// CHECK-LABEL: test_vreinterpret_p8_s64:
 // CHECK-NEXT: ret
 poly8x8_t test_vreinterpret_p8_s64(int64x1_t a) {
   return vreinterpret_p8_s64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p8_u8
+// CHECK-LABEL: test_vreinterpret_p8_u8:
 // CHECK-NEXT: ret
 poly8x8_t test_vreinterpret_p8_u8(uint8x8_t a) {
   return vreinterpret_p8_u8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p8_u16
+// CHECK-LABEL: test_vreinterpret_p8_u16:
 // CHECK-NEXT: ret
 poly8x8_t test_vreinterpret_p8_u16(uint16x4_t a) {
   return vreinterpret_p8_u16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p8_u32
+// CHECK-LABEL: test_vreinterpret_p8_u32:
 // CHECK-NEXT: ret
 poly8x8_t test_vreinterpret_p8_u32(uint32x2_t a) {
   return vreinterpret_p8_u32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p8_u64
+// CHECK-LABEL: test_vreinterpret_p8_u64:
 // CHECK-NEXT: ret
 poly8x8_t test_vreinterpret_p8_u64(uint64x1_t a) {
   return vreinterpret_p8_u64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p8_f16
+// CHECK-LABEL: test_vreinterpret_p8_f16:
 // CHECK-NEXT: ret
 poly8x8_t test_vreinterpret_p8_f16(float16x4_t a) {
   return vreinterpret_p8_f16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p8_f32
+// CHECK-LABEL: test_vreinterpret_p8_f32:
 // CHECK-NEXT: ret
 poly8x8_t test_vreinterpret_p8_f32(float32x2_t a) {
   return vreinterpret_p8_f32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p8_f64
+// CHECK-LABEL: test_vreinterpret_p8_f64:
 // CHECK-NEXT: ret
 poly8x8_t test_vreinterpret_p8_f64(float64x1_t a) {
   return vreinterpret_p8_f64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p8_p16
+// CHECK-LABEL: test_vreinterpret_p8_p16:
 // CHECK-NEXT: ret
 poly8x8_t test_vreinterpret_p8_p16(poly16x4_t a) {
   return vreinterpret_p8_p16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p8_p64
+// CHECK-LABEL: test_vreinterpret_p8_p64:
 // CHECK-NEXT: ret
 poly8x8_t test_vreinterpret_p8_p64(poly64x1_t a) {
   return vreinterpret_p8_p64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p16_s8
+// CHECK-LABEL: test_vreinterpret_p16_s8:
 // CHECK-NEXT: ret
 poly16x4_t test_vreinterpret_p16_s8(int8x8_t a) {
   return vreinterpret_p16_s8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p16_s16
+// CHECK-LABEL: test_vreinterpret_p16_s16:
 // CHECK-NEXT: ret
 poly16x4_t test_vreinterpret_p16_s16(int16x4_t a) {
   return vreinterpret_p16_s16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p16_s32
+// CHECK-LABEL: test_vreinterpret_p16_s32:
 // CHECK-NEXT: ret
 poly16x4_t test_vreinterpret_p16_s32(int32x2_t a) {
   return vreinterpret_p16_s32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p16_s64
+// CHECK-LABEL: test_vreinterpret_p16_s64:
 // CHECK-NEXT: ret
 poly16x4_t test_vreinterpret_p16_s64(int64x1_t a) {
   return vreinterpret_p16_s64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p16_u8
+// CHECK-LABEL: test_vreinterpret_p16_u8:
 // CHECK-NEXT: ret
 poly16x4_t test_vreinterpret_p16_u8(uint8x8_t a) {
   return vreinterpret_p16_u8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p16_u16
+// CHECK-LABEL: test_vreinterpret_p16_u16:
 // CHECK-NEXT: ret
 poly16x4_t test_vreinterpret_p16_u16(uint16x4_t a) {
   return vreinterpret_p16_u16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p16_u32
+// CHECK-LABEL: test_vreinterpret_p16_u32:
 // CHECK-NEXT: ret
 poly16x4_t test_vreinterpret_p16_u32(uint32x2_t a) {
   return vreinterpret_p16_u32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p16_u64
+// CHECK-LABEL: test_vreinterpret_p16_u64:
 // CHECK-NEXT: ret
 poly16x4_t test_vreinterpret_p16_u64(uint64x1_t a) {
   return vreinterpret_p16_u64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p16_f16
+// CHECK-LABEL: test_vreinterpret_p16_f16:
 // CHECK-NEXT: ret
 poly16x4_t test_vreinterpret_p16_f16(float16x4_t a) {
   return vreinterpret_p16_f16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p16_f32
+// CHECK-LABEL: test_vreinterpret_p16_f32:
 // CHECK-NEXT: ret
 poly16x4_t test_vreinterpret_p16_f32(float32x2_t a) {
   return vreinterpret_p16_f32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p16_f64
+// CHECK-LABEL: test_vreinterpret_p16_f64:
 // CHECK-NEXT: ret
 poly16x4_t test_vreinterpret_p16_f64(float64x1_t a) {
   return vreinterpret_p16_f64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p16_p8
+// CHECK-LABEL: test_vreinterpret_p16_p8:
 // CHECK-NEXT: ret
 poly16x4_t test_vreinterpret_p16_p8(poly8x8_t a) {
   return vreinterpret_p16_p8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p16_p64
+// CHECK-LABEL: test_vreinterpret_p16_p64:
 // CHECK-NEXT: ret
 poly16x4_t test_vreinterpret_p16_p64(poly64x1_t a) {
   return vreinterpret_p16_p64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p64_s8
+// CHECK-LABEL: test_vreinterpret_p64_s8:
 // CHECK-NEXT: ret
 poly64x1_t test_vreinterpret_p64_s8(int8x8_t a) {
   return vreinterpret_p64_s8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p64_s16
+// CHECK-LABEL: test_vreinterpret_p64_s16:
 // CHECK-NEXT: ret
 poly64x1_t test_vreinterpret_p64_s16(int16x4_t a) {
   return vreinterpret_p64_s16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p64_s32
+// CHECK-LABEL: test_vreinterpret_p64_s32:
 // CHECK-NEXT: ret
 poly64x1_t test_vreinterpret_p64_s32(int32x2_t a) {
   return vreinterpret_p64_s32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p64_s64
+// CHECK-LABEL: test_vreinterpret_p64_s64:
 // CHECK-NEXT: ret
 poly64x1_t test_vreinterpret_p64_s64(int64x1_t a) {
   return vreinterpret_p64_s64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p64_u8
+// CHECK-LABEL: test_vreinterpret_p64_u8:
 // CHECK-NEXT: ret
 poly64x1_t test_vreinterpret_p64_u8(uint8x8_t a) {
   return vreinterpret_p64_u8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p64_u16
+// CHECK-LABEL: test_vreinterpret_p64_u16:
 // CHECK-NEXT: ret
 poly64x1_t test_vreinterpret_p64_u16(uint16x4_t a) {
   return vreinterpret_p64_u16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p64_u32
+// CHECK-LABEL: test_vreinterpret_p64_u32:
 // CHECK-NEXT: ret
 poly64x1_t test_vreinterpret_p64_u32(uint32x2_t a) {
   return vreinterpret_p64_u32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p64_u64
+// CHECK-LABEL: test_vreinterpret_p64_u64:
 // CHECK-NEXT: ret
 poly64x1_t test_vreinterpret_p64_u64(uint64x1_t a) {
   return vreinterpret_p64_u64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p64_f16
+// CHECK-LABEL: test_vreinterpret_p64_f16:
 // CHECK-NEXT: ret
 poly64x1_t test_vreinterpret_p64_f16(float16x4_t a) {
   return vreinterpret_p64_f16(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p64_f32
+// CHECK-LABEL: test_vreinterpret_p64_f32:
 // CHECK-NEXT: ret
 poly64x1_t test_vreinterpret_p64_f32(float32x2_t a) {
   return vreinterpret_p64_f32(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p64_f64
+// CHECK-LABEL: test_vreinterpret_p64_f64:
 // CHECK-NEXT: ret
 poly64x1_t test_vreinterpret_p64_f64(float64x1_t a) {
   return vreinterpret_p64_f64(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p64_p8
+// CHECK-LABEL: test_vreinterpret_p64_p8:
 // CHECK-NEXT: ret
 poly64x1_t test_vreinterpret_p64_p8(poly8x8_t a) {
   return vreinterpret_p64_p8(a);
 }
 
-// CHECK-LABEL: test_vreinterpret_p64_p16
+// CHECK-LABEL: test_vreinterpret_p64_p16:
 // CHECK-NEXT: ret
 poly64x1_t test_vreinterpret_p64_p16(poly16x4_t a) {
   return vreinterpret_p64_p16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s8_s16
+// CHECK-LABEL: test_vreinterpretq_s8_s16:
 // CHECK-NEXT: ret
 int8x16_t test_vreinterpretq_s8_s16(int16x8_t a) {
   return vreinterpretq_s8_s16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s8_s32
+// CHECK-LABEL: test_vreinterpretq_s8_s32:
 // CHECK-NEXT: ret
 int8x16_t test_vreinterpretq_s8_s32(int32x4_t a) {
   return vreinterpretq_s8_s32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s8_s64
+// CHECK-LABEL: test_vreinterpretq_s8_s64:
 // CHECK-NEXT: ret
 int8x16_t test_vreinterpretq_s8_s64(int64x2_t a) {
   return vreinterpretq_s8_s64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s8_u8
+// CHECK-LABEL: test_vreinterpretq_s8_u8:
 // CHECK-NEXT: ret
 int8x16_t test_vreinterpretq_s8_u8(uint8x16_t a) {
   return vreinterpretq_s8_u8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s8_u16
+// CHECK-LABEL: test_vreinterpretq_s8_u16:
 // CHECK-NEXT: ret
 int8x16_t test_vreinterpretq_s8_u16(uint16x8_t a) {
   return vreinterpretq_s8_u16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s8_u32
+// CHECK-LABEL: test_vreinterpretq_s8_u32:
 // CHECK-NEXT: ret
 int8x16_t test_vreinterpretq_s8_u32(uint32x4_t a) {
   return vreinterpretq_s8_u32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s8_u64
+// CHECK-LABEL: test_vreinterpretq_s8_u64:
 // CHECK-NEXT: ret
 int8x16_t test_vreinterpretq_s8_u64(uint64x2_t a) {
   return vreinterpretq_s8_u64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s8_f16
+// CHECK-LABEL: test_vreinterpretq_s8_f16:
 // CHECK-NEXT: ret
 int8x16_t test_vreinterpretq_s8_f16(float16x8_t a) {
   return vreinterpretq_s8_f16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s8_f32
+// CHECK-LABEL: test_vreinterpretq_s8_f32:
 // CHECK-NEXT: ret
 int8x16_t test_vreinterpretq_s8_f32(float32x4_t a) {
   return vreinterpretq_s8_f32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s8_f64
+// CHECK-LABEL: test_vreinterpretq_s8_f64:
 // CHECK-NEXT: ret
 int8x16_t test_vreinterpretq_s8_f64(float64x2_t a) {
   return vreinterpretq_s8_f64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s8_p8
+// CHECK-LABEL: test_vreinterpretq_s8_p8:
 // CHECK-NEXT: ret
 int8x16_t test_vreinterpretq_s8_p8(poly8x16_t a) {
   return vreinterpretq_s8_p8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s8_p16
+// CHECK-LABEL: test_vreinterpretq_s8_p16:
 // CHECK-NEXT: ret
 int8x16_t test_vreinterpretq_s8_p16(poly16x8_t a) {
   return vreinterpretq_s8_p16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s8_p64
+// CHECK-LABEL: test_vreinterpretq_s8_p64:
 // CHECK-NEXT: ret
 int8x16_t test_vreinterpretq_s8_p64(poly64x2_t a) {
   return vreinterpretq_s8_p64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s16_s8
+// CHECK-LABEL: test_vreinterpretq_s16_s8:
 // CHECK-NEXT: ret
 int16x8_t test_vreinterpretq_s16_s8(int8x16_t a) {
   return vreinterpretq_s16_s8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s16_s32
+// CHECK-LABEL: test_vreinterpretq_s16_s32:
 // CHECK-NEXT: ret
 int16x8_t test_vreinterpretq_s16_s32(int32x4_t a) {
   return vreinterpretq_s16_s32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s16_s64
+// CHECK-LABEL: test_vreinterpretq_s16_s64:
 // CHECK-NEXT: ret
 int16x8_t test_vreinterpretq_s16_s64(int64x2_t a) {
   return vreinterpretq_s16_s64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s16_u8
+// CHECK-LABEL: test_vreinterpretq_s16_u8:
 // CHECK-NEXT: ret
 int16x8_t test_vreinterpretq_s16_u8(uint8x16_t a) {
   return vreinterpretq_s16_u8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s16_u16
+// CHECK-LABEL: test_vreinterpretq_s16_u16:
 // CHECK-NEXT: ret
 int16x8_t test_vreinterpretq_s16_u16(uint16x8_t a) {
   return vreinterpretq_s16_u16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s16_u32
+// CHECK-LABEL: test_vreinterpretq_s16_u32:
 // CHECK-NEXT: ret
 int16x8_t test_vreinterpretq_s16_u32(uint32x4_t a) {
   return vreinterpretq_s16_u32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s16_u64
+// CHECK-LABEL: test_vreinterpretq_s16_u64:
 // CHECK-NEXT: ret
 int16x8_t test_vreinterpretq_s16_u64(uint64x2_t a) {
   return vreinterpretq_s16_u64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s16_f16
+// CHECK-LABEL: test_vreinterpretq_s16_f16:
 // CHECK-NEXT: ret
 int16x8_t test_vreinterpretq_s16_f16(float16x8_t a) {
   return vreinterpretq_s16_f16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s16_f32
+// CHECK-LABEL: test_vreinterpretq_s16_f32:
 // CHECK-NEXT: ret
 int16x8_t test_vreinterpretq_s16_f32(float32x4_t a) {
   return vreinterpretq_s16_f32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s16_f64
+// CHECK-LABEL: test_vreinterpretq_s16_f64:
 // CHECK-NEXT: ret
 int16x8_t test_vreinterpretq_s16_f64(float64x2_t a) {
   return vreinterpretq_s16_f64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s16_p8
+// CHECK-LABEL: test_vreinterpretq_s16_p8:
 // CHECK-NEXT: ret
 int16x8_t test_vreinterpretq_s16_p8(poly8x16_t a) {
   return vreinterpretq_s16_p8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s16_p16
+// CHECK-LABEL: test_vreinterpretq_s16_p16:
 // CHECK-NEXT: ret
 int16x8_t test_vreinterpretq_s16_p16(poly16x8_t a) {
   return vreinterpretq_s16_p16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s16_p64
+// CHECK-LABEL: test_vreinterpretq_s16_p64:
 // CHECK-NEXT: ret
 int16x8_t test_vreinterpretq_s16_p64(poly64x2_t a) {
   return vreinterpretq_s16_p64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s32_s8
+// CHECK-LABEL: test_vreinterpretq_s32_s8:
 // CHECK-NEXT: ret
 int32x4_t test_vreinterpretq_s32_s8(int8x16_t a) {
   return vreinterpretq_s32_s8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s32_s16
+// CHECK-LABEL: test_vreinterpretq_s32_s16:
 // CHECK-NEXT: ret
 int32x4_t test_vreinterpretq_s32_s16(int16x8_t a) {
   return vreinterpretq_s32_s16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s32_s64
+// CHECK-LABEL: test_vreinterpretq_s32_s64:
 // CHECK-NEXT: ret
 int32x4_t test_vreinterpretq_s32_s64(int64x2_t a) {
   return vreinterpretq_s32_s64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s32_u8
+// CHECK-LABEL: test_vreinterpretq_s32_u8:
 // CHECK-NEXT: ret
 int32x4_t test_vreinterpretq_s32_u8(uint8x16_t a) {
   return vreinterpretq_s32_u8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s32_u16
+// CHECK-LABEL: test_vreinterpretq_s32_u16:
 // CHECK-NEXT: ret
 int32x4_t test_vreinterpretq_s32_u16(uint16x8_t a) {
   return vreinterpretq_s32_u16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s32_u32
+// CHECK-LABEL: test_vreinterpretq_s32_u32:
 // CHECK-NEXT: ret
 int32x4_t test_vreinterpretq_s32_u32(uint32x4_t a) {
   return vreinterpretq_s32_u32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s32_u64
+// CHECK-LABEL: test_vreinterpretq_s32_u64:
 // CHECK-NEXT: ret
 int32x4_t test_vreinterpretq_s32_u64(uint64x2_t a) {
   return vreinterpretq_s32_u64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s32_f16
+// CHECK-LABEL: test_vreinterpretq_s32_f16:
 // CHECK-NEXT: ret
 int32x4_t test_vreinterpretq_s32_f16(float16x8_t a) {
   return vreinterpretq_s32_f16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s32_f32
+// CHECK-LABEL: test_vreinterpretq_s32_f32:
 // CHECK-NEXT: ret
 int32x4_t test_vreinterpretq_s32_f32(float32x4_t a) {
   return vreinterpretq_s32_f32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s32_f64
+// CHECK-LABEL: test_vreinterpretq_s32_f64:
 // CHECK-NEXT: ret
 int32x4_t test_vreinterpretq_s32_f64(float64x2_t a) {
   return vreinterpretq_s32_f64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s32_p8
+// CHECK-LABEL: test_vreinterpretq_s32_p8:
 // CHECK-NEXT: ret
 int32x4_t test_vreinterpretq_s32_p8(poly8x16_t a) {
   return vreinterpretq_s32_p8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s32_p16
+// CHECK-LABEL: test_vreinterpretq_s32_p16:
 // CHECK-NEXT: ret
 int32x4_t test_vreinterpretq_s32_p16(poly16x8_t a) {
   return vreinterpretq_s32_p16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s32_p64
+// CHECK-LABEL: test_vreinterpretq_s32_p64:
 // CHECK-NEXT: ret
 int32x4_t test_vreinterpretq_s32_p64(poly64x2_t a) {
   return vreinterpretq_s32_p64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s64_s8
+// CHECK-LABEL: test_vreinterpretq_s64_s8:
 // CHECK-NEXT: ret
 int64x2_t test_vreinterpretq_s64_s8(int8x16_t a) {
   return vreinterpretq_s64_s8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s64_s16
+// CHECK-LABEL: test_vreinterpretq_s64_s16:
 // CHECK-NEXT: ret
 int64x2_t test_vreinterpretq_s64_s16(int16x8_t a) {
   return vreinterpretq_s64_s16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s64_s32
+// CHECK-LABEL: test_vreinterpretq_s64_s32:
 // CHECK-NEXT: ret
 int64x2_t test_vreinterpretq_s64_s32(int32x4_t a) {
   return vreinterpretq_s64_s32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s64_u8
+// CHECK-LABEL: test_vreinterpretq_s64_u8:
 // CHECK-NEXT: ret
 int64x2_t test_vreinterpretq_s64_u8(uint8x16_t a) {
   return vreinterpretq_s64_u8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s64_u16
+// CHECK-LABEL: test_vreinterpretq_s64_u16:
 // CHECK-NEXT: ret
 int64x2_t test_vreinterpretq_s64_u16(uint16x8_t a) {
   return vreinterpretq_s64_u16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s64_u32
+// CHECK-LABEL: test_vreinterpretq_s64_u32:
 // CHECK-NEXT: ret
 int64x2_t test_vreinterpretq_s64_u32(uint32x4_t a) {
   return vreinterpretq_s64_u32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s64_u64
+// CHECK-LABEL: test_vreinterpretq_s64_u64:
 // CHECK-NEXT: ret
 int64x2_t test_vreinterpretq_s64_u64(uint64x2_t a) {
   return vreinterpretq_s64_u64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s64_f16
+// CHECK-LABEL: test_vreinterpretq_s64_f16:
 // CHECK-NEXT: ret
 int64x2_t test_vreinterpretq_s64_f16(float16x8_t a) {
   return vreinterpretq_s64_f16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s64_f32
+// CHECK-LABEL: test_vreinterpretq_s64_f32:
 // CHECK-NEXT: ret
 int64x2_t test_vreinterpretq_s64_f32(float32x4_t a) {
   return vreinterpretq_s64_f32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s64_f64
+// CHECK-LABEL: test_vreinterpretq_s64_f64:
 // CHECK-NEXT: ret
 int64x2_t test_vreinterpretq_s64_f64(float64x2_t a) {
   return vreinterpretq_s64_f64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s64_p8
+// CHECK-LABEL: test_vreinterpretq_s64_p8:
 // CHECK-NEXT: ret
 int64x2_t test_vreinterpretq_s64_p8(poly8x16_t a) {
   return vreinterpretq_s64_p8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s64_p16
+// CHECK-LABEL: test_vreinterpretq_s64_p16:
 // CHECK-NEXT: ret
 int64x2_t test_vreinterpretq_s64_p16(poly16x8_t a) {
   return vreinterpretq_s64_p16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_s64_p64
+// CHECK-LABEL: test_vreinterpretq_s64_p64:
 // CHECK-NEXT: ret
 int64x2_t test_vreinterpretq_s64_p64(poly64x2_t a) {
   return vreinterpretq_s64_p64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u8_s8
+// CHECK-LABEL: test_vreinterpretq_u8_s8:
 // CHECK-NEXT: ret
 uint8x16_t test_vreinterpretq_u8_s8(int8x16_t a) {
   return vreinterpretq_u8_s8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u8_s16
+// CHECK-LABEL: test_vreinterpretq_u8_s16:
 // CHECK-NEXT: ret
 uint8x16_t test_vreinterpretq_u8_s16(int16x8_t a) {
   return vreinterpretq_u8_s16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u8_s32
+// CHECK-LABEL: test_vreinterpretq_u8_s32:
 // CHECK-NEXT: ret
 uint8x16_t test_vreinterpretq_u8_s32(int32x4_t a) {
   return vreinterpretq_u8_s32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u8_s64
+// CHECK-LABEL: test_vreinterpretq_u8_s64:
 // CHECK-NEXT: ret
 uint8x16_t test_vreinterpretq_u8_s64(int64x2_t a) {
   return vreinterpretq_u8_s64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u8_u16
+// CHECK-LABEL: test_vreinterpretq_u8_u16:
 // CHECK-NEXT: ret
 uint8x16_t test_vreinterpretq_u8_u16(uint16x8_t a) {
   return vreinterpretq_u8_u16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u8_u32
+// CHECK-LABEL: test_vreinterpretq_u8_u32:
 // CHECK-NEXT: ret
 uint8x16_t test_vreinterpretq_u8_u32(uint32x4_t a) {
   return vreinterpretq_u8_u32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u8_u64
+// CHECK-LABEL: test_vreinterpretq_u8_u64:
 // CHECK-NEXT: ret
 uint8x16_t test_vreinterpretq_u8_u64(uint64x2_t a) {
   return vreinterpretq_u8_u64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u8_f16
+// CHECK-LABEL: test_vreinterpretq_u8_f16:
 // CHECK-NEXT: ret
 uint8x16_t test_vreinterpretq_u8_f16(float16x8_t a) {
   return vreinterpretq_u8_f16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u8_f32
+// CHECK-LABEL: test_vreinterpretq_u8_f32:
 // CHECK-NEXT: ret
 uint8x16_t test_vreinterpretq_u8_f32(float32x4_t a) {
   return vreinterpretq_u8_f32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u8_f64
+// CHECK-LABEL: test_vreinterpretq_u8_f64:
 // CHECK-NEXT: ret
 uint8x16_t test_vreinterpretq_u8_f64(float64x2_t a) {
   return vreinterpretq_u8_f64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u8_p8
+// CHECK-LABEL: test_vreinterpretq_u8_p8:
 // CHECK-NEXT: ret
 uint8x16_t test_vreinterpretq_u8_p8(poly8x16_t a) {
   return vreinterpretq_u8_p8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u8_p16
+// CHECK-LABEL: test_vreinterpretq_u8_p16:
 // CHECK-NEXT: ret
 uint8x16_t test_vreinterpretq_u8_p16(poly16x8_t a) {
   return vreinterpretq_u8_p16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u8_p64
+// CHECK-LABEL: test_vreinterpretq_u8_p64:
 // CHECK-NEXT: ret
 uint8x16_t test_vreinterpretq_u8_p64(poly64x2_t a) {
   return vreinterpretq_u8_p64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u16_s8
+// CHECK-LABEL: test_vreinterpretq_u16_s8:
 // CHECK-NEXT: ret
 uint16x8_t test_vreinterpretq_u16_s8(int8x16_t a) {
   return vreinterpretq_u16_s8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u16_s16
+// CHECK-LABEL: test_vreinterpretq_u16_s16:
 // CHECK-NEXT: ret
 uint16x8_t test_vreinterpretq_u16_s16(int16x8_t a) {
   return vreinterpretq_u16_s16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u16_s32
+// CHECK-LABEL: test_vreinterpretq_u16_s32:
 // CHECK-NEXT: ret
 uint16x8_t test_vreinterpretq_u16_s32(int32x4_t a) {
   return vreinterpretq_u16_s32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u16_s64
+// CHECK-LABEL: test_vreinterpretq_u16_s64:
 // CHECK-NEXT: ret
 uint16x8_t test_vreinterpretq_u16_s64(int64x2_t a) {
   return vreinterpretq_u16_s64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u16_u8
+// CHECK-LABEL: test_vreinterpretq_u16_u8:
 // CHECK-NEXT: ret
 uint16x8_t test_vreinterpretq_u16_u8(uint8x16_t a) {
   return vreinterpretq_u16_u8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u16_u32
+// CHECK-LABEL: test_vreinterpretq_u16_u32:
 // CHECK-NEXT: ret
 uint16x8_t test_vreinterpretq_u16_u32(uint32x4_t a) {
   return vreinterpretq_u16_u32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u16_u64
+// CHECK-LABEL: test_vreinterpretq_u16_u64:
 // CHECK-NEXT: ret
 uint16x8_t test_vreinterpretq_u16_u64(uint64x2_t a) {
   return vreinterpretq_u16_u64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u16_f16
+// CHECK-LABEL: test_vreinterpretq_u16_f16:
 // CHECK-NEXT: ret
 uint16x8_t test_vreinterpretq_u16_f16(float16x8_t a) {
   return vreinterpretq_u16_f16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u16_f32
+// CHECK-LABEL: test_vreinterpretq_u16_f32:
 // CHECK-NEXT: ret
 uint16x8_t test_vreinterpretq_u16_f32(float32x4_t a) {
   return vreinterpretq_u16_f32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u16_f64
+// CHECK-LABEL: test_vreinterpretq_u16_f64:
 // CHECK-NEXT: ret
 uint16x8_t test_vreinterpretq_u16_f64(float64x2_t a) {
   return vreinterpretq_u16_f64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u16_p8
+// CHECK-LABEL: test_vreinterpretq_u16_p8:
 // CHECK-NEXT: ret
 uint16x8_t test_vreinterpretq_u16_p8(poly8x16_t a) {
   return vreinterpretq_u16_p8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u16_p16
+// CHECK-LABEL: test_vreinterpretq_u16_p16:
 // CHECK-NEXT: ret
 uint16x8_t test_vreinterpretq_u16_p16(poly16x8_t a) {
   return vreinterpretq_u16_p16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u16_p64
+// CHECK-LABEL: test_vreinterpretq_u16_p64:
 // CHECK-NEXT: ret
 uint16x8_t test_vreinterpretq_u16_p64(poly64x2_t a) {
   return vreinterpretq_u16_p64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u32_s8
+// CHECK-LABEL: test_vreinterpretq_u32_s8:
 // CHECK-NEXT: ret
 uint32x4_t test_vreinterpretq_u32_s8(int8x16_t a) {
   return vreinterpretq_u32_s8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u32_s16
+// CHECK-LABEL: test_vreinterpretq_u32_s16:
 // CHECK-NEXT: ret
 uint32x4_t test_vreinterpretq_u32_s16(int16x8_t a) {
   return vreinterpretq_u32_s16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u32_s32
+// CHECK-LABEL: test_vreinterpretq_u32_s32:
 // CHECK-NEXT: ret
 uint32x4_t test_vreinterpretq_u32_s32(int32x4_t a) {
   return vreinterpretq_u32_s32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u32_s64
+// CHECK-LABEL: test_vreinterpretq_u32_s64:
 // CHECK-NEXT: ret
 uint32x4_t test_vreinterpretq_u32_s64(int64x2_t a) {
   return vreinterpretq_u32_s64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u32_u8
+// CHECK-LABEL: test_vreinterpretq_u32_u8:
 // CHECK-NEXT: ret
 uint32x4_t test_vreinterpretq_u32_u8(uint8x16_t a) {
   return vreinterpretq_u32_u8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u32_u16
+// CHECK-LABEL: test_vreinterpretq_u32_u16:
 // CHECK-NEXT: ret
 uint32x4_t test_vreinterpretq_u32_u16(uint16x8_t a) {
   return vreinterpretq_u32_u16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u32_u64
+// CHECK-LABEL: test_vreinterpretq_u32_u64:
 // CHECK-NEXT: ret
 uint32x4_t test_vreinterpretq_u32_u64(uint64x2_t a) {
   return vreinterpretq_u32_u64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u32_f16
+// CHECK-LABEL: test_vreinterpretq_u32_f16:
 // CHECK-NEXT: ret
 uint32x4_t test_vreinterpretq_u32_f16(float16x8_t a) {
   return vreinterpretq_u32_f16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u32_f32
+// CHECK-LABEL: test_vreinterpretq_u32_f32:
 // CHECK-NEXT: ret
 uint32x4_t test_vreinterpretq_u32_f32(float32x4_t a) {
   return vreinterpretq_u32_f32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u32_f64
+// CHECK-LABEL: test_vreinterpretq_u32_f64:
 // CHECK-NEXT: ret
 uint32x4_t test_vreinterpretq_u32_f64(float64x2_t a) {
   return vreinterpretq_u32_f64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u32_p8
+// CHECK-LABEL: test_vreinterpretq_u32_p8:
 // CHECK-NEXT: ret
 uint32x4_t test_vreinterpretq_u32_p8(poly8x16_t a) {
   return vreinterpretq_u32_p8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u32_p16
+// CHECK-LABEL: test_vreinterpretq_u32_p16:
 // CHECK-NEXT: ret
 uint32x4_t test_vreinterpretq_u32_p16(poly16x8_t a) {
   return vreinterpretq_u32_p16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u32_p64
+// CHECK-LABEL: test_vreinterpretq_u32_p64:
 // CHECK-NEXT: ret
 uint32x4_t test_vreinterpretq_u32_p64(poly64x2_t a) {
   return vreinterpretq_u32_p64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u64_s8
+// CHECK-LABEL: test_vreinterpretq_u64_s8:
 // CHECK-NEXT: ret
 uint64x2_t test_vreinterpretq_u64_s8(int8x16_t a) {
   return vreinterpretq_u64_s8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u64_s16
+// CHECK-LABEL: test_vreinterpretq_u64_s16:
 // CHECK-NEXT: ret
 uint64x2_t test_vreinterpretq_u64_s16(int16x8_t a) {
   return vreinterpretq_u64_s16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u64_s32
+// CHECK-LABEL: test_vreinterpretq_u64_s32:
 // CHECK-NEXT: ret
 uint64x2_t test_vreinterpretq_u64_s32(int32x4_t a) {
   return vreinterpretq_u64_s32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u64_s64
+// CHECK-LABEL: test_vreinterpretq_u64_s64:
 // CHECK-NEXT: ret
 uint64x2_t test_vreinterpretq_u64_s64(int64x2_t a) {
   return vreinterpretq_u64_s64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u64_u8
+// CHECK-LABEL: test_vreinterpretq_u64_u8:
 // CHECK-NEXT: ret
 uint64x2_t test_vreinterpretq_u64_u8(uint8x16_t a) {
   return vreinterpretq_u64_u8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u64_u16
+// CHECK-LABEL: test_vreinterpretq_u64_u16:
 // CHECK-NEXT: ret
 uint64x2_t test_vreinterpretq_u64_u16(uint16x8_t a) {
   return vreinterpretq_u64_u16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u64_u32
+// CHECK-LABEL: test_vreinterpretq_u64_u32:
 // CHECK-NEXT: ret
 uint64x2_t test_vreinterpretq_u64_u32(uint32x4_t a) {
   return vreinterpretq_u64_u32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u64_f16
+// CHECK-LABEL: test_vreinterpretq_u64_f16:
 // CHECK-NEXT: ret
 uint64x2_t test_vreinterpretq_u64_f16(float16x8_t a) {
   return vreinterpretq_u64_f16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u64_f32
+// CHECK-LABEL: test_vreinterpretq_u64_f32:
 // CHECK-NEXT: ret
 uint64x2_t test_vreinterpretq_u64_f32(float32x4_t a) {
   return vreinterpretq_u64_f32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u64_f64
+// CHECK-LABEL: test_vreinterpretq_u64_f64:
 // CHECK-NEXT: ret
 uint64x2_t test_vreinterpretq_u64_f64(float64x2_t a) {
   return vreinterpretq_u64_f64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u64_p8
+// CHECK-LABEL: test_vreinterpretq_u64_p8:
 // CHECK-NEXT: ret
 uint64x2_t test_vreinterpretq_u64_p8(poly8x16_t a) {
   return vreinterpretq_u64_p8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u64_p16
+// CHECK-LABEL: test_vreinterpretq_u64_p16:
 // CHECK-NEXT: ret
 uint64x2_t test_vreinterpretq_u64_p16(poly16x8_t a) {
   return vreinterpretq_u64_p16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_u64_p64
+// CHECK-LABEL: test_vreinterpretq_u64_p64:
 // CHECK-NEXT: ret
 uint64x2_t test_vreinterpretq_u64_p64(poly64x2_t a) {
   return vreinterpretq_u64_p64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f16_s8
+// CHECK-LABEL: test_vreinterpretq_f16_s8:
 // CHECK-NEXT: ret
 float16x8_t test_vreinterpretq_f16_s8(int8x16_t a) {
   return vreinterpretq_f16_s8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f16_s16
+// CHECK-LABEL: test_vreinterpretq_f16_s16:
 // CHECK-NEXT: ret
 float16x8_t test_vreinterpretq_f16_s16(int16x8_t a) {
   return vreinterpretq_f16_s16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f16_s32
+// CHECK-LABEL: test_vreinterpretq_f16_s32:
 // CHECK-NEXT: ret
 float16x8_t test_vreinterpretq_f16_s32(int32x4_t a) {
   return vreinterpretq_f16_s32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f16_s64
+// CHECK-LABEL: test_vreinterpretq_f16_s64:
 // CHECK-NEXT: ret
 float16x8_t test_vreinterpretq_f16_s64(int64x2_t a) {
   return vreinterpretq_f16_s64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f16_u8
+// CHECK-LABEL: test_vreinterpretq_f16_u8:
 // CHECK-NEXT: ret
 float16x8_t test_vreinterpretq_f16_u8(uint8x16_t a) {
   return vreinterpretq_f16_u8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f16_u16
+// CHECK-LABEL: test_vreinterpretq_f16_u16:
 // CHECK-NEXT: ret
 float16x8_t test_vreinterpretq_f16_u16(uint16x8_t a) {
   return vreinterpretq_f16_u16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f16_u32
+// CHECK-LABEL: test_vreinterpretq_f16_u32:
 // CHECK-NEXT: ret
 float16x8_t test_vreinterpretq_f16_u32(uint32x4_t a) {
   return vreinterpretq_f16_u32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f16_u64
+// CHECK-LABEL: test_vreinterpretq_f16_u64:
 // CHECK-NEXT: ret
 float16x8_t test_vreinterpretq_f16_u64(uint64x2_t a) {
   return vreinterpretq_f16_u64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f16_f32
+// CHECK-LABEL: test_vreinterpretq_f16_f32:
 // CHECK-NEXT: ret
 float16x8_t test_vreinterpretq_f16_f32(float32x4_t a) {
   return vreinterpretq_f16_f32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f16_f64
+// CHECK-LABEL: test_vreinterpretq_f16_f64:
 // CHECK-NEXT: ret
 float16x8_t test_vreinterpretq_f16_f64(float64x2_t a) {
   return vreinterpretq_f16_f64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f16_p8
+// CHECK-LABEL: test_vreinterpretq_f16_p8:
 // CHECK-NEXT: ret
 float16x8_t test_vreinterpretq_f16_p8(poly8x16_t a) {
   return vreinterpretq_f16_p8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f16_p16
+// CHECK-LABEL: test_vreinterpretq_f16_p16:
 // CHECK-NEXT: ret
 float16x8_t test_vreinterpretq_f16_p16(poly16x8_t a) {
   return vreinterpretq_f16_p16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f16_p64
+// CHECK-LABEL: test_vreinterpretq_f16_p64:
 // CHECK-NEXT: ret
 float16x8_t test_vreinterpretq_f16_p64(poly64x2_t a) {
   return vreinterpretq_f16_p64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f32_s8
+// CHECK-LABEL: test_vreinterpretq_f32_s8:
 // CHECK-NEXT: ret
 float32x4_t test_vreinterpretq_f32_s8(int8x16_t a) {
   return vreinterpretq_f32_s8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f32_s16
+// CHECK-LABEL: test_vreinterpretq_f32_s16:
 // CHECK-NEXT: ret
 float32x4_t test_vreinterpretq_f32_s16(int16x8_t a) {
   return vreinterpretq_f32_s16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f32_s32
+// CHECK-LABEL: test_vreinterpretq_f32_s32:
 // CHECK-NEXT: ret
 float32x4_t test_vreinterpretq_f32_s32(int32x4_t a) {
   return vreinterpretq_f32_s32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f32_s64
+// CHECK-LABEL: test_vreinterpretq_f32_s64:
 // CHECK-NEXT: ret
 float32x4_t test_vreinterpretq_f32_s64(int64x2_t a) {
   return vreinterpretq_f32_s64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f32_u8
+// CHECK-LABEL: test_vreinterpretq_f32_u8:
 // CHECK-NEXT: ret
 float32x4_t test_vreinterpretq_f32_u8(uint8x16_t a) {
   return vreinterpretq_f32_u8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f32_u16
+// CHECK-LABEL: test_vreinterpretq_f32_u16:
 // CHECK-NEXT: ret
 float32x4_t test_vreinterpretq_f32_u16(uint16x8_t a) {
   return vreinterpretq_f32_u16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f32_u32
+// CHECK-LABEL: test_vreinterpretq_f32_u32:
 // CHECK-NEXT: ret
 float32x4_t test_vreinterpretq_f32_u32(uint32x4_t a) {
   return vreinterpretq_f32_u32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f32_u64
+// CHECK-LABEL: test_vreinterpretq_f32_u64:
 // CHECK-NEXT: ret
 float32x4_t test_vreinterpretq_f32_u64(uint64x2_t a) {
   return vreinterpretq_f32_u64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f32_f16
+// CHECK-LABEL: test_vreinterpretq_f32_f16:
 // CHECK-NEXT: ret
 float32x4_t test_vreinterpretq_f32_f16(float16x8_t a) {
   return vreinterpretq_f32_f16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f32_f64
+// CHECK-LABEL: test_vreinterpretq_f32_f64:
 // CHECK-NEXT: ret
 float32x4_t test_vreinterpretq_f32_f64(float64x2_t a) {
   return vreinterpretq_f32_f64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f32_p8
+// CHECK-LABEL: test_vreinterpretq_f32_p8:
 // CHECK-NEXT: ret
 float32x4_t test_vreinterpretq_f32_p8(poly8x16_t a) {
   return vreinterpretq_f32_p8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f32_p16
+// CHECK-LABEL: test_vreinterpretq_f32_p16:
 // CHECK-NEXT: ret
 float32x4_t test_vreinterpretq_f32_p16(poly16x8_t a) {
   return vreinterpretq_f32_p16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f32_p64
+// CHECK-LABEL: test_vreinterpretq_f32_p64:
 // CHECK-NEXT: ret
 float32x4_t test_vreinterpretq_f32_p64(poly64x2_t a) {
   return vreinterpretq_f32_p64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f64_s8
+// CHECK-LABEL: test_vreinterpretq_f64_s8:
 // CHECK-NEXT: ret
 float64x2_t test_vreinterpretq_f64_s8(int8x16_t a) {
   return vreinterpretq_f64_s8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f64_s16
+// CHECK-LABEL: test_vreinterpretq_f64_s16:
 // CHECK-NEXT: ret
 float64x2_t test_vreinterpretq_f64_s16(int16x8_t a) {
   return vreinterpretq_f64_s16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f64_s32
+// CHECK-LABEL: test_vreinterpretq_f64_s32:
 // CHECK-NEXT: ret
 float64x2_t test_vreinterpretq_f64_s32(int32x4_t a) {
   return vreinterpretq_f64_s32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f64_s64
+// CHECK-LABEL: test_vreinterpretq_f64_s64:
 // CHECK-NEXT: ret
 float64x2_t test_vreinterpretq_f64_s64(int64x2_t a) {
   return vreinterpretq_f64_s64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f64_u8
+// CHECK-LABEL: test_vreinterpretq_f64_u8:
 // CHECK-NEXT: ret
 float64x2_t test_vreinterpretq_f64_u8(uint8x16_t a) {
   return vreinterpretq_f64_u8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f64_u16
+// CHECK-LABEL: test_vreinterpretq_f64_u16:
 // CHECK-NEXT: ret
 float64x2_t test_vreinterpretq_f64_u16(uint16x8_t a) {
   return vreinterpretq_f64_u16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f64_u32
+// CHECK-LABEL: test_vreinterpretq_f64_u32:
 // CHECK-NEXT: ret
 float64x2_t test_vreinterpretq_f64_u32(uint32x4_t a) {
   return vreinterpretq_f64_u32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f64_u64
+// CHECK-LABEL: test_vreinterpretq_f64_u64:
 // CHECK-NEXT: ret
 float64x2_t test_vreinterpretq_f64_u64(uint64x2_t a) {
   return vreinterpretq_f64_u64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f64_f16
+// CHECK-LABEL: test_vreinterpretq_f64_f16:
 // CHECK-NEXT: ret
 float64x2_t test_vreinterpretq_f64_f16(float16x8_t a) {
   return vreinterpretq_f64_f16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f64_f32
+// CHECK-LABEL: test_vreinterpretq_f64_f32:
 // CHECK-NEXT: ret
 float64x2_t test_vreinterpretq_f64_f32(float32x4_t a) {
   return vreinterpretq_f64_f32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f64_p8
+// CHECK-LABEL: test_vreinterpretq_f64_p8:
 // CHECK-NEXT: ret
 float64x2_t test_vreinterpretq_f64_p8(poly8x16_t a) {
   return vreinterpretq_f64_p8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f64_p16
+// CHECK-LABEL: test_vreinterpretq_f64_p16:
 // CHECK-NEXT: ret
 float64x2_t test_vreinterpretq_f64_p16(poly16x8_t a) {
   return vreinterpretq_f64_p16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_f64_p64
+// CHECK-LABEL: test_vreinterpretq_f64_p64:
 // CHECK-NEXT: ret
 float64x2_t test_vreinterpretq_f64_p64(poly64x2_t a) {
   return vreinterpretq_f64_p64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p8_s8
+// CHECK-LABEL: test_vreinterpretq_p8_s8:
 // CHECK-NEXT: ret
 poly8x16_t test_vreinterpretq_p8_s8(int8x16_t a) {
   return vreinterpretq_p8_s8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p8_s16
+// CHECK-LABEL: test_vreinterpretq_p8_s16:
 // CHECK-NEXT: ret
 poly8x16_t test_vreinterpretq_p8_s16(int16x8_t a) {
   return vreinterpretq_p8_s16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p8_s32
+// CHECK-LABEL: test_vreinterpretq_p8_s32:
 // CHECK-NEXT: ret
 poly8x16_t test_vreinterpretq_p8_s32(int32x4_t a) {
   return vreinterpretq_p8_s32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p8_s64
+// CHECK-LABEL: test_vreinterpretq_p8_s64:
 // CHECK-NEXT: ret
 poly8x16_t test_vreinterpretq_p8_s64(int64x2_t a) {
   return vreinterpretq_p8_s64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p8_u8
+// CHECK-LABEL: test_vreinterpretq_p8_u8:
 // CHECK-NEXT: ret
 poly8x16_t test_vreinterpretq_p8_u8(uint8x16_t a) {
   return vreinterpretq_p8_u8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p8_u16
+// CHECK-LABEL: test_vreinterpretq_p8_u16:
 // CHECK-NEXT: ret
 poly8x16_t test_vreinterpretq_p8_u16(uint16x8_t a) {
   return vreinterpretq_p8_u16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p8_u32
+// CHECK-LABEL: test_vreinterpretq_p8_u32:
 // CHECK-NEXT: ret
 poly8x16_t test_vreinterpretq_p8_u32(uint32x4_t a) {
   return vreinterpretq_p8_u32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p8_u64
+// CHECK-LABEL: test_vreinterpretq_p8_u64:
 // CHECK-NEXT: ret
 poly8x16_t test_vreinterpretq_p8_u64(uint64x2_t a) {
   return vreinterpretq_p8_u64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p8_f16
+// CHECK-LABEL: test_vreinterpretq_p8_f16:
 // CHECK-NEXT: ret
 poly8x16_t test_vreinterpretq_p8_f16(float16x8_t a) {
   return vreinterpretq_p8_f16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p8_f32
+// CHECK-LABEL: test_vreinterpretq_p8_f32:
 // CHECK-NEXT: ret
 poly8x16_t test_vreinterpretq_p8_f32(float32x4_t a) {
   return vreinterpretq_p8_f32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p8_f64
+// CHECK-LABEL: test_vreinterpretq_p8_f64:
 // CHECK-NEXT: ret
 poly8x16_t test_vreinterpretq_p8_f64(float64x2_t a) {
   return vreinterpretq_p8_f64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p8_p16
+// CHECK-LABEL: test_vreinterpretq_p8_p16:
 // CHECK-NEXT: ret
 poly8x16_t test_vreinterpretq_p8_p16(poly16x8_t a) {
   return vreinterpretq_p8_p16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p8_p64
+// CHECK-LABEL: test_vreinterpretq_p8_p64:
 // CHECK-NEXT: ret
 poly8x16_t test_vreinterpretq_p8_p64(poly64x2_t a) {
   return vreinterpretq_p8_p64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p16_s8
+// CHECK-LABEL: test_vreinterpretq_p16_s8:
 // CHECK-NEXT: ret
 poly16x8_t test_vreinterpretq_p16_s8(int8x16_t a) {
   return vreinterpretq_p16_s8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p16_s16
+// CHECK-LABEL: test_vreinterpretq_p16_s16:
 // CHECK-NEXT: ret
 poly16x8_t test_vreinterpretq_p16_s16(int16x8_t a) {
   return vreinterpretq_p16_s16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p16_s32
+// CHECK-LABEL: test_vreinterpretq_p16_s32:
 // CHECK-NEXT: ret
 poly16x8_t test_vreinterpretq_p16_s32(int32x4_t a) {
   return vreinterpretq_p16_s32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p16_s64
+// CHECK-LABEL: test_vreinterpretq_p16_s64:
 // CHECK-NEXT: ret
 poly16x8_t test_vreinterpretq_p16_s64(int64x2_t a) {
   return vreinterpretq_p16_s64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p16_u8
+// CHECK-LABEL: test_vreinterpretq_p16_u8:
 // CHECK-NEXT: ret
 poly16x8_t test_vreinterpretq_p16_u8(uint8x16_t a) {
   return vreinterpretq_p16_u8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p16_u16
+// CHECK-LABEL: test_vreinterpretq_p16_u16:
 // CHECK-NEXT: ret
 poly16x8_t test_vreinterpretq_p16_u16(uint16x8_t a) {
   return vreinterpretq_p16_u16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p16_u32
+// CHECK-LABEL: test_vreinterpretq_p16_u32:
 // CHECK-NEXT: ret
 poly16x8_t test_vreinterpretq_p16_u32(uint32x4_t a) {
   return vreinterpretq_p16_u32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p16_u64
+// CHECK-LABEL: test_vreinterpretq_p16_u64:
 // CHECK-NEXT: ret
 poly16x8_t test_vreinterpretq_p16_u64(uint64x2_t a) {
   return vreinterpretq_p16_u64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p16_f16
+// CHECK-LABEL: test_vreinterpretq_p16_f16:
 // CHECK-NEXT: ret
 poly16x8_t test_vreinterpretq_p16_f16(float16x8_t a) {
   return vreinterpretq_p16_f16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p16_f32
+// CHECK-LABEL: test_vreinterpretq_p16_f32:
 // CHECK-NEXT: ret
 poly16x8_t test_vreinterpretq_p16_f32(float32x4_t a) {
   return vreinterpretq_p16_f32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p16_f64
+// CHECK-LABEL: test_vreinterpretq_p16_f64:
 // CHECK-NEXT: ret
 poly16x8_t test_vreinterpretq_p16_f64(float64x2_t a) {
   return vreinterpretq_p16_f64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p16_p8
+// CHECK-LABEL: test_vreinterpretq_p16_p8:
 // CHECK-NEXT: ret
 poly16x8_t test_vreinterpretq_p16_p8(poly8x16_t a) {
   return vreinterpretq_p16_p8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p16_p64
+// CHECK-LABEL: test_vreinterpretq_p16_p64:
 // CHECK-NEXT: ret
 poly16x8_t test_vreinterpretq_p16_p64(poly64x2_t a) {
   return vreinterpretq_p16_p64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p64_s8
+// CHECK-LABEL: test_vreinterpretq_p64_s8:
 // CHECK-NEXT: ret
 poly64x2_t test_vreinterpretq_p64_s8(int8x16_t a) {
   return vreinterpretq_p64_s8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p64_s16
+// CHECK-LABEL: test_vreinterpretq_p64_s16:
 // CHECK-NEXT: ret
 poly64x2_t test_vreinterpretq_p64_s16(int16x8_t a) {
   return vreinterpretq_p64_s16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p64_s32
+// CHECK-LABEL: test_vreinterpretq_p64_s32:
 // CHECK-NEXT: ret
 poly64x2_t test_vreinterpretq_p64_s32(int32x4_t a) {
   return vreinterpretq_p64_s32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p64_s64
+// CHECK-LABEL: test_vreinterpretq_p64_s64:
 // CHECK-NEXT: ret
 poly64x2_t test_vreinterpretq_p64_s64(int64x2_t a) {
   return vreinterpretq_p64_s64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p64_u8
+// CHECK-LABEL: test_vreinterpretq_p64_u8:
 // CHECK-NEXT: ret
 poly64x2_t test_vreinterpretq_p64_u8(uint8x16_t a) {
   return vreinterpretq_p64_u8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p64_u16
+// CHECK-LABEL: test_vreinterpretq_p64_u16:
 // CHECK-NEXT: ret
 poly64x2_t test_vreinterpretq_p64_u16(uint16x8_t a) {
   return vreinterpretq_p64_u16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p64_u32
+// CHECK-LABEL: test_vreinterpretq_p64_u32:
 // CHECK-NEXT: ret
 poly64x2_t test_vreinterpretq_p64_u32(uint32x4_t a) {
   return vreinterpretq_p64_u32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p64_u64
+// CHECK-LABEL: test_vreinterpretq_p64_u64:
 // CHECK-NEXT: ret
 poly64x2_t test_vreinterpretq_p64_u64(uint64x2_t a) {
   return vreinterpretq_p64_u64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p64_f16
+// CHECK-LABEL: test_vreinterpretq_p64_f16:
 // CHECK-NEXT: ret
 poly64x2_t test_vreinterpretq_p64_f16(float16x8_t a) {
   return vreinterpretq_p64_f16(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p64_f32
+// CHECK-LABEL: test_vreinterpretq_p64_f32:
 // CHECK-NEXT: ret
 poly64x2_t test_vreinterpretq_p64_f32(float32x4_t a) {
   return vreinterpretq_p64_f32(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p64_f64
+// CHECK-LABEL: test_vreinterpretq_p64_f64:
 // CHECK-NEXT: ret
 poly64x2_t test_vreinterpretq_p64_f64(float64x2_t a) {
   return vreinterpretq_p64_f64(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p64_p8
+// CHECK-LABEL: test_vreinterpretq_p64_p8:
 // CHECK-NEXT: ret
 poly64x2_t test_vreinterpretq_p64_p8(poly8x16_t a) {
   return vreinterpretq_p64_p8(a);
 }
 
-// CHECK-LABEL: test_vreinterpretq_p64_p16
+// CHECK-LABEL: test_vreinterpretq_p64_p16:
 // CHECK-NEXT: ret
 poly64x2_t test_vreinterpretq_p64_p16(poly16x8_t a) {
   return vreinterpretq_p64_p16(a);
 }
+
+float32_t test_vabds_f32(float32_t a, float32_t b) {
+// CHECK-LABEL: test_vabds_f32
+// CHECK: fabd {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
+  return vabds_f32(a, b);
+}
+
+float64_t test_vabdd_f64(float64_t a, float64_t b) {
+// CHECK-LABEL: test_vabdd_f64
+// CHECK: fabd {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+  return vabdd_f64(a, b);
+}
+
+int64x1_t test_vuqadd_s64(int64x1_t a, uint64x1_t b) {
+  // CHECK-LABEL: test_vuqadd_s64
+  return vuqadd_s64(a, b);
+  // CHECK: suqadd d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+uint64x1_t test_vsqadd_u64(uint64x1_t a, int64x1_t b) {
+  // CHECK-LABEL: test_vsqadd_u64
+  return vsqadd_u64(a, b);
+  // CHECK: usqadd d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+uint8x8_t test_vsqadd_u8(uint8x8_t a, int8x8_t b) {
+  // CHECK-LABEL: test_vsqadd_u8
+  return vsqadd_u8(a, b);
+  // CHECK: usqadd {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
+}
+
+uint8x16_t test_vsqaddq_u8(uint8x16_t a, int8x16_t b) {
+  // CHECK-LABEL: test_vsqaddq_u8
+  return vsqaddq_u8(a, b);
+  // CHECK: usqadd {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
+}
+
+uint16x4_t test_vsqadd_u16(uint16x4_t a, int16x4_t b) {
+  // CHECK-LABEL: test_vsqadd_u16
+  return vsqadd_u16(a, b);
+  // CHECK: usqadd {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
+}
+
+uint16x8_t test_vsqaddq_u16(uint16x8_t a, int16x8_t b) {
+  // CHECK-LABEL: test_vsqaddq_u16
+  return vsqaddq_u16(a, b);
+  // CHECK: usqadd {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
+}
+
+uint32x2_t test_vsqadd_u32(uint32x2_t a, int32x2_t b) {
+  // CHECK-LABEL: test_vsqadd_u32
+  return vsqadd_u32(a, b);
+  // CHECK: usqadd {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
+}
+
+uint32x4_t test_vsqaddq_u32(uint32x4_t a, int32x4_t b) {
+  // CHECK-LABEL: test_vsqaddq_u32
+  return vsqaddq_u32(a, b);
+  // CHECK: usqadd {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
+}
+
+uint64x2_t test_vsqaddq_u64(uint64x2_t a, int64x2_t b) {
+  // CHECK-LABEL: test_vsqaddq_u64
+  return vsqaddq_u64(a, b);
+  // CHECK: usqadd {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
+}
+
+int64x1_t test_vabs_s64(int64x1_t a) {
+  // CHECK-LABEL: test_vabs_s64
+  return vabs_s64(a);
+  // CHECK: abs d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+int64x1_t test_vqabs_s64(int64x1_t a) {
+  // CHECK-LABEL: test_vqabs_s64
+  return vqabs_s64(a);
+  // CHECK: sqabs d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+int64x1_t test_vqneg_s64(int64x1_t a) {
+  // CHECK-LABEL: test_vqneg_s64
+  return vqneg_s64(a);
+  // CHECK: sqneg d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+int64x1_t test_vneg_s64(int64x1_t a) {
+  // CHECK-LABEL: test_vneg_s64
+  return vneg_s64(a);
+  // CHECK: neg d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+float32_t test_vaddv_f32(float32x2_t a) {
+  // CHECK-LABEL: test_vaddv_f32
+  return vaddv_f32(a);
+  // CHECK: faddp {{s[0-9]+}}, {{v[0-9]+}}.2s
+}
+
+float32_t test_vaddvq_f32(float32x4_t a) {
+  // CHECK-LABEL: test_vaddvq_f32
+  return vaddvq_f32(a);
+  // CHECK: faddp {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
+  // CHECK: faddp {{s[0-9]+}}, {{v[0-9]+}}.2s
+}
+
+float64_t test_vaddvq_f64(float64x2_t a) {
+  // CHECK-LABEL: test_vaddvq_f64
+  return vaddvq_f64(a);
+  // CHECK: faddp {{d[0-9]+}}, {{v[0-9]+}}.2d
+}
+
+float32_t test_vmaxv_f32(float32x2_t a) {
+  // CHECK-LABEL: test_vmaxv_f32
+  return vmaxv_f32(a);
+  // CHECK: fmaxp {{s[0-9]+}}, {{v[0-9]+}}.2s
+}
+
+float64_t test_vmaxvq_f64(float64x2_t a) {
+  // CHECK-LABEL: test_vmaxvq_f64
+  return vmaxvq_f64(a);
+  // CHECK: fmaxp {{d[0-9]+}}, {{v[0-9]+}}.2d
+}
+
+float32_t test_vminv_f32(float32x2_t a) {
+  // CHECK-LABEL: test_vminv_f32
+  return vminv_f32(a);
+  // CHECK: fminp {{s[0-9]+}}, {{v[0-9]+}}.2s
+}
+
+float64_t test_vminvq_f64(float64x2_t a) {
+  // CHECK-LABEL: test_vminvq_f64
+  return vminvq_f64(a);
+  // CHECK: fminp {{d[0-9]+}}, {{v[0-9]+}}.2d
+}
+
+float64_t test_vmaxnmvq_f64(float64x2_t a) {
+  // CHECK-LABEL: test_vmaxnmvq_f64
+  return vmaxnmvq_f64(a);
+  // CHECK: fmaxnmp {{d[0-9]+}}, {{v[0-9]+}}.2d
+}
+
+float32_t test_vmaxnmv_f32(float32x2_t a) {
+  // CHECK-LABEL: test_vmaxnmv_f32
+  return vmaxnmv_f32(a);
+  // CHECK: fmaxnmp {{s[0-9]+}}, {{v[0-9]+}}.2s
+}
+
+float64_t test_vminnmvq_f64(float64x2_t a) {
+  // CHECK-LABEL: test_vminnmvq_f64
+  return vminnmvq_f64(a);
+  // CHECK: fminnmp {{d[0-9]+}}, {{v[0-9]+}}.2d
+}
+
+float32_t test_vminnmv_f32(float32x2_t a) {
+  // CHECK-LABEL: test_vminnmv_f32
+  return vminnmv_f32(a);
+  // CHECK: fminnmp {{s[0-9]+}}, {{v[0-9]+}}.2s
+}
+
+int64x2_t test_vpaddq_s64(int64x2_t a, int64x2_t b) {
+  // CHECK-LABEL: test_vpaddq_s64
+  return vpaddq_s64(a, b);
+  // CHECK: addp {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
+}
+
+uint64x2_t test_vpaddq_u64(uint64x2_t a, uint64x2_t b) {
+  // CHECK-LABEL: test_vpaddq_u64
+  return vpaddq_u64(a, b);
+  // CHECK: addp {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
+}
+
+uint64_t test_vpaddd_u64(uint64x2_t a) {
+  // CHECK-LABEL: test_vpaddd_u64
+  return vpaddd_u64(a);
+  // CHECK: addp {{d[0-9]+}}, {{v[0-9]+}}.2d
+}
+
+int64_t test_vaddvq_s64(int64x2_t a) {
+  // CHECK-LABEL: test_vaddvq_s64
+  return vaddvq_s64(a);
+  // CHECK: addp {{d[0-9]+}}, {{v[0-9]+}}.2d
+}
+
+uint64_t test_vaddvq_u64(uint64x2_t a) {
+  // CHECK-LABEL: test_vaddvq_u64
+  return vaddvq_u64(a);
+  // CHECK: addp {{d[0-9]+}}, {{v[0-9]+}}.2d
+}
+
+float64x1_t test_vadd_f64(float64x1_t a, float64x1_t b) {
+  // CHECK-LABEL: test_vadd_f64
+  return vadd_f64(a, b);
+  // CHECK: fadd d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+float64x1_t test_vmul_f64(float64x1_t a, float64x1_t b) {
+  // CHECK-LABEL: test_vmul_f64
+  return vmul_f64(a, b);
+  // CHECK: fmul d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+float64x1_t test_vdiv_f64(float64x1_t a, float64x1_t b) {
+  // CHECK-LABEL: test_vdiv_f64
+  return vdiv_f64(a, b);
+  // CHECK: fdiv d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+float64x1_t test_vmla_f64(float64x1_t a, float64x1_t b, float64x1_t c) {
+  // CHECK-LABEL: test_vmla_f64
+  return vmla_f64(a, b, c);
+  // CHECK: fmadd d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+float64x1_t test_vmls_f64(float64x1_t a, float64x1_t b, float64x1_t c) {
+  // CHECK-LABEL: test_vmls_f64
+  return vmls_f64(a, b, c);
+  // CHECK: fmsub d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+float64x1_t test_vfma_f64(float64x1_t a, float64x1_t b, float64x1_t c) {
+  // CHECK-LABEL: test_vfma_f64
+  return vfma_f64(a, b, c);
+  // CHECK: fmadd d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+float64x1_t test_vfms_f64(float64x1_t a, float64x1_t b, float64x1_t c) {
+  // CHECK-LABEL: test_vfms_f64
+  return vfms_f64(a, b, c);
+  // CHECK: fmsub d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+float64x1_t test_vsub_f64(float64x1_t a, float64x1_t b) {
+  // CHECK-LABEL: test_vsub_f64
+  return vsub_f64(a, b);
+  // CHECK: fsub d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+float64x1_t test_vabd_f64(float64x1_t a, float64x1_t b) {
+  // CHECK-LABEL: test_vabd_f64
+  return vabd_f64(a, b);
+  // CHECK: fabd d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+float64x1_t test_vmax_f64(float64x1_t a, float64x1_t b) {
+// CHECK-LABEL: test_vmax_f64
+  return vmax_f64(a, b);
+// CHECK: fmax d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+float64x1_t test_vmin_f64(float64x1_t a, float64x1_t b) {
+// CHECK-LABEL: test_vmin_f64
+  return vmin_f64(a, b);
+// CHECK: fmin d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+float64x1_t test_vmaxnm_f64(float64x1_t a, float64x1_t b) {
+// CHECK-LABEL: test_vmaxnm_f64
+  return vmaxnm_f64(a, b);
+// CHECK: fmaxnm d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+float64x1_t test_vminnm_f64(float64x1_t a, float64x1_t b) {
+// CHECK-LABEL: test_vminnm_f64
+  return vminnm_f64(a, b);
+// CHECK: fminnm d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+float64x1_t test_vabs_f64(float64x1_t a) {
+  // CHECK-LABEL: test_vabs_f64
+  return vabs_f64(a);
+  // CHECK: fabs d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+float64x1_t test_vneg_f64(float64x1_t a) {
+  // CHECK-LABEL: test_vneg_f64
+  return vneg_f64(a);
+  // CHECK: fneg d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+int64x1_t test_vcvt_s64_f64(float64x1_t a) {
+  // CHECK-LABEL: test_vcvt_s64_f64
+  return vcvt_s64_f64(a);
+  // CHECK: fcvtzs {{[xd][0-9]+}}, d{{[0-9]+}}
+}
+
+uint64x1_t test_vcvt_u64_f64(float64x1_t a) {
+  // CHECK-LABEL: test_vcvt_u64_f64
+  return vcvt_u64_f64(a);
+  // CHECK: fcvtzu {{[xd][0-9]+}}, d{{[0-9]+}}
+}
+
+int64x1_t test_vcvtn_s64_f64(float64x1_t a) {
+  // CHECK-LABEL: test_vcvtn_s64_f64
+  return vcvtn_s64_f64(a);
+  // CHECK: fcvtns d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+uint64x1_t test_vcvtn_u64_f64(float64x1_t a) {
+  // CHECK-LABEL: test_vcvtn_u64_f64
+  return vcvtn_u64_f64(a);
+  // CHECK: fcvtnu d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+int64x1_t test_vcvtp_s64_f64(float64x1_t a) {
+  // CHECK-LABEL: test_vcvtp_s64_f64
+  return vcvtp_s64_f64(a);
+  // CHECK: fcvtps d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+uint64x1_t test_vcvtp_u64_f64(float64x1_t a) {
+  // CHECK-LABEL: test_vcvtp_u64_f64
+  return vcvtp_u64_f64(a);
+  // CHECK: fcvtpu d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+int64x1_t test_vcvtm_s64_f64(float64x1_t a) {
+  // CHECK-LABEL: test_vcvtm_s64_f64
+  return vcvtm_s64_f64(a);
+  // CHECK: fcvtms d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+uint64x1_t test_vcvtm_u64_f64(float64x1_t a) {
+  // CHECK-LABEL: test_vcvtm_u64_f64
+  return vcvtm_u64_f64(a);
+  // CHECK: fcvtmu d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+int64x1_t test_vcvta_s64_f64(float64x1_t a) {
+  // CHECK-LABEL: test_vcvta_s64_f64
+  return vcvta_s64_f64(a);
+  // CHECK: fcvtas d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+uint64x1_t test_vcvta_u64_f64(float64x1_t a) {
+  // CHECK-LABEL: test_vcvta_u64_f64
+  return vcvta_u64_f64(a);
+  // CHECK: fcvtau d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+float64x1_t test_vcvt_f64_s64(int64x1_t a) {
+  // CHECK-LABEL: test_vcvt_f64_s64
+  return vcvt_f64_s64(a);
+  // CHECK: scvtf d{{[0-9]+}}, {{[xd][0-9]+}}
+}
+
+float64x1_t test_vcvt_f64_u64(uint64x1_t a) {
+  // CHECK-LABEL: test_vcvt_f64_u64
+  return vcvt_f64_u64(a);
+  // CHECK: ucvtf d{{[0-9]+}}, {{[xd][0-9]+}}
+}
+
+int64x1_t test_vcvt_n_s64_f64(float64x1_t a) {
+  // CHECK-LABEL: test_vcvt_n_s64_f64
+  return vcvt_n_s64_f64(a, 64);
+  // CHECK: fcvtzs d{{[0-9]+}}, d{{[0-9]+}}, #64
+}
+
+uint64x1_t test_vcvt_n_u64_f64(float64x1_t a) {
+  // CHECK-LABEL: test_vcvt_n_u64_f64
+  return vcvt_n_u64_f64(a, 64);
+  // CHECK: fcvtzu d{{[0-9]+}}, d{{[0-9]+}}, #64
+}
+
+float64x1_t test_vcvt_n_f64_s64(int64x1_t a) {
+  // CHECK-LABEL: test_vcvt_n_f64_s64
+  return vcvt_n_f64_s64(a, 64);
+  // CHECK: scvtf d{{[0-9]+}}, d{{[0-9]+}}, #64
+}
+
+float64x1_t test_vcvt_n_f64_u64(uint64x1_t a) {
+  // CHECK-LABEL: test_vcvt_n_f64_u64
+  return vcvt_n_f64_u64(a, 64);
+  // CHECK: ucvtf d{{[0-9]+}}, d{{[0-9]+}}, #64
+}
+
+float64x1_t test_vrndn_f64(float64x1_t a) {
+  // CHECK-LABEL: test_vrndn_f64
+  return vrndn_f64(a);
+  // CHECK: frintn d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+float64x1_t test_vrnda_f64(float64x1_t a) {
+  // CHECK-LABEL: test_vrnda_f64
+  return vrnda_f64(a);
+  // CHECK: frinta d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+float64x1_t test_vrndp_f64(float64x1_t a) {
+  // CHECK-LABEL: test_vrndp_f64
+  return vrndp_f64(a);
+  // CHECK: frintp d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+float64x1_t test_vrndm_f64(float64x1_t a) {
+  // CHECK-LABEL: test_vrndm_f64
+  return vrndm_f64(a);
+  // CHECK: frintm d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+float64x1_t test_vrndx_f64(float64x1_t a) {
+  // CHECK-LABEL: test_vrndx_f64
+  return vrndx_f64(a);
+  // CHECK: frintx d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+float64x1_t test_vrnd_f64(float64x1_t a) {
+  // CHECK-LABEL: test_vrnd_f64
+  return vrnd_f64(a);
+  // CHECK: frintz d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+float64x1_t test_vrndi_f64(float64x1_t a) {
+  // CHECK-LABEL: test_vrndi_f64
+  return vrndi_f64(a);
+  // CHECK: frinti d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+float64x1_t test_vrsqrte_f64(float64x1_t a) {
+  // CHECK-LABEL: test_vrsqrte_f64
+  return vrsqrte_f64(a);
+  // CHECK: frsqrte d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+float64x1_t test_vrecpe_f64(float64x1_t a) {
+  // CHECK-LABEL: test_vrecpe_f64
+  return vrecpe_f64(a);
+  // CHECK: frecpe d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+float64x1_t test_vsqrt_f64(float64x1_t a) {
+  // CHECK-LABEL: test_vsqrt_f64
+  return vsqrt_f64(a);
+  // CHECK: fsqrt d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+float64x1_t test_vrecps_f64(float64x1_t a, float64x1_t b) {
+  // CHECK-LABEL: test_vrecps_f64
+  return vrecps_f64(a, b);
+  // CHECK: frecps d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+float64x1_t test_vrsqrts_f64(float64x1_t a, float64x1_t b) {
+  // CHECK-LABEL: test_vrsqrts_f64
+  return vrsqrts_f64(a, b);
+  // CHECK: frsqrts d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
+}
+
+int32_t test_vminv_s32(int32x2_t a) {
+  // CHECK-LABEL: test_vminv_s32
+  return vminv_s32(a);
+  // CHECK: sminp {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
+}
+
+uint32_t test_vminv_u32(uint32x2_t a) {
+  // CHECK-LABEL: test_vminv_u32
+  return vminv_u32(a);
+  // CHECK: uminp {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
+}
+
+int32_t test_vmaxv_s32(int32x2_t a) {
+  // CHECK-LABEL: test_vmaxv_s32
+  return vmaxv_s32(a);
+  // CHECK: smaxp {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
+}
+
+uint32_t test_vmaxv_u32(uint32x2_t a) {
+  // CHECK-LABEL: test_vmaxv_u32
+  return vmaxv_u32(a);
+  // CHECK: umaxp {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
+}
+
+int32_t test_vaddv_s32(int32x2_t a) {
+  // CHECK-LABEL: test_vaddv_s32
+  return vaddv_s32(a);
+  // CHECK: addp {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
+}
+
+uint32_t test_vaddv_u32(uint32x2_t a) {
+  // CHECK-LABEL: test_vaddv_u32
+  return vaddv_u32(a);
+  // CHECK: addp {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, {{v[0-9]+}}.2s
+}
+
+int64_t test_vaddlv_s32(int32x2_t a) {
+  // CHECK-LABEL: test_vaddlv_s32
+  return vaddlv_s32(a);
+  // CHECK: saddlp {{v[0-9]+}}.1d, {{v[0-9]+}}.2s
+}
+
+uint64_t test_vaddlv_u32(uint32x2_t a) {
+  // CHECK-LABEL: test_vaddlv_u32
+  return vaddlv_u32(a);
+  // CHECK: uaddlp {{v[0-9]+}}.1d, {{v[0-9]+}}.2s
+}
diff --git a/test/CodeGen/aarch64-neon-ldst-one.c b/test/CodeGen/aarch64-neon-ldst-one.c
index f629260..dc888c2 100644
--- a/test/CodeGen/aarch64-neon-ldst-one.c
+++ b/test/CodeGen/aarch64-neon-ldst-one.c
@@ -1,2047 +1,2049 @@
 // REQUIRES: aarch64-registered-target
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +neon \
+// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \
 // RUN:   -ffp-contract=fast -S -O3 -o - %s | FileCheck %s
 
 #include <arm_neon.h>
 
-uint8x16_t test_vld1q_dup_u8(uint8_t const *a) {
+uint8x16_t test_vld1q_dup_u8(uint8_t  *a) {
   // CHECK-LABEL: test_vld1q_dup_u8
   return vld1q_dup_u8(a);
-  // CHECK: ld1r {v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1r {{{ *v[0-9]+.16b *}}}, [{{x[0-9]+|sp}}]
 }
 
-uint16x8_t test_vld1q_dup_u16(uint16_t const *a) {
+uint16x8_t test_vld1q_dup_u16(uint16_t  *a) {
   // CHECK-LABEL: test_vld1q_dup_u16
   return vld1q_dup_u16(a);
-  // CHECK: ld1r {v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1r {{{ *v[0-9]+.8h *}}}, [{{x[0-9]+|sp}}]
 }
 
-uint32x4_t test_vld1q_dup_u32(uint32_t const *a) {
+uint32x4_t test_vld1q_dup_u32(uint32_t  *a) {
   // CHECK-LABEL: test_vld1q_dup_u32
   return vld1q_dup_u32(a);
-  // CHECK: ld1r {v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1r {{{ *v[0-9]+.4s *}}}, [{{x[0-9]+|sp}}]
 }
 
-uint64x2_t test_vld1q_dup_u64(uint64_t const *a) {
+uint64x2_t test_vld1q_dup_u64(uint64_t  *a) {
   // CHECK-LABEL: test_vld1q_dup_u64
   return vld1q_dup_u64(a);
-  // CHECK: ld1r {v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1r {{{ *v[0-9]+.2d *}}}, [{{x[0-9]+|sp}}]
 }
 
-int8x16_t test_vld1q_dup_s8(int8_t const *a) {
+int8x16_t test_vld1q_dup_s8(int8_t  *a) {
   // CHECK-LABEL: test_vld1q_dup_s8
   return vld1q_dup_s8(a);
-  // CHECK: ld1r {v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1r {{{ *v[0-9]+.16b *}}}, [{{x[0-9]+|sp}}]
 }
 
-int16x8_t test_vld1q_dup_s16(int16_t const *a) {
+int16x8_t test_vld1q_dup_s16(int16_t  *a) {
   // CHECK-LABEL: test_vld1q_dup_s16
   return vld1q_dup_s16(a);
-  // CHECK: ld1r {v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1r {{{ *v[0-9]+.8h *}}}, [{{x[0-9]+|sp}}]
 }
 
-int32x4_t test_vld1q_dup_s32(int32_t const *a) {
+int32x4_t test_vld1q_dup_s32(int32_t  *a) {
   // CHECK-LABEL: test_vld1q_dup_s32
   return vld1q_dup_s32(a);
-  // CHECK: ld1r {v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1r {{{ *v[0-9]+.4s *}}}, [{{x[0-9]+|sp}}]
 }
 
-int64x2_t test_vld1q_dup_s64(int64_t const *a) {
+int64x2_t test_vld1q_dup_s64(int64_t  *a) {
   // CHECK-LABEL: test_vld1q_dup_s64
   return vld1q_dup_s64(a);
-  // CHECK: ld1r {v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1r {{{ *v[0-9]+.2d *}}}, [{{x[0-9]+|sp}}]
 }
 
-float16x8_t test_vld1q_dup_f16(float16_t const *a) {
+float16x8_t test_vld1q_dup_f16(float16_t  *a) {
   // CHECK-LABEL: test_vld1q_dup_f16
   return vld1q_dup_f16(a);
-  // CHECK: ld1r {v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1r {{{ *v[0-9]+.8h *}}}, [{{x[0-9]+|sp}}]
 }
 
-float32x4_t test_vld1q_dup_f32(float32_t const *a) {
+float32x4_t test_vld1q_dup_f32(float32_t  *a) {
   // CHECK-LABEL: test_vld1q_dup_f32
   return vld1q_dup_f32(a);
-  // CHECK: ld1r {v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1r {{{ *v[0-9]+.4s *}}}, [{{x[0-9]+|sp}}]
 }
 
-float64x2_t test_vld1q_dup_f64(float64_t const *a) {
+float64x2_t test_vld1q_dup_f64(float64_t  *a) {
   // CHECK-LABEL: test_vld1q_dup_f64
   return vld1q_dup_f64(a);
-  // CHECK: ld1r {v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1r {{{ *v[0-9]+.2d *}}}, [{{x[0-9]+|sp}}]
 }
 
-poly8x16_t test_vld1q_dup_p8(poly8_t const *a) {
+poly8x16_t test_vld1q_dup_p8(poly8_t  *a) {
   // CHECK-LABEL: test_vld1q_dup_p8
   return vld1q_dup_p8(a);
-  // CHECK: ld1r {v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1r {{{ *v[0-9]+.16b *}}}, [{{x[0-9]+|sp}}]
 }
 
-poly16x8_t test_vld1q_dup_p16(poly16_t const *a) {
+poly16x8_t test_vld1q_dup_p16(poly16_t  *a) {
   // CHECK-LABEL: test_vld1q_dup_p16
   return vld1q_dup_p16(a);
-  // CHECK: ld1r {v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1r {{{ *v[0-9]+.8h *}}}, [{{x[0-9]+|sp}}]
 }
 
-poly64x2_t test_vld1q_dup_p64(poly64_t const *a) {
+poly64x2_t test_vld1q_dup_p64(poly64_t  *a) {
   // CHECK-LABEL: test_vld1q_dup_p64
   return vld1q_dup_p64(a);
-  // CHECK: ld1r {v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1r {{{ *v[0-9]+.2d *}}}, [{{x[0-9]+|sp}}]
 }
 
-uint8x8_t test_vld1_dup_u8(uint8_t const *a) {
+uint8x8_t test_vld1_dup_u8(uint8_t  *a) {
   // CHECK-LABEL: test_vld1_dup_u8
   return vld1_dup_u8(a);
-  // CHECK: ld1r {v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1r {{{ *v[0-9]+.8b *}}}, [{{x[0-9]+|sp}}]
 }
 
-uint16x4_t test_vld1_dup_u16(uint16_t const *a) {
+uint16x4_t test_vld1_dup_u16(uint16_t  *a) {
   // CHECK-LABEL: test_vld1_dup_u16
   return vld1_dup_u16(a);
-  // CHECK: ld1r {v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1r {{{ *v[0-9]+.4h *}}}, [{{x[0-9]+|sp}}]
 }
 
-uint32x2_t test_vld1_dup_u32(uint32_t const *a) {
+uint32x2_t test_vld1_dup_u32(uint32_t  *a) {
   // CHECK-LABEL: test_vld1_dup_u32
   return vld1_dup_u32(a);
-  // CHECK: ld1r {v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1r {{{ *v[0-9]+.2s *}}}, [{{x[0-9]+|sp}}]
 }
 
-uint64x1_t test_vld1_dup_u64(uint64_t const *a) {
+uint64x1_t test_vld1_dup_u64(uint64_t  *a) {
   // CHECK-LABEL: test_vld1_dup_u64
   return vld1_dup_u64(a);
-  // CHECK: ld1r {v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1r { v[0-9]+.1d }|ldr d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
-int8x8_t test_vld1_dup_s8(int8_t const *a) {
+int8x8_t test_vld1_dup_s8(int8_t  *a) {
   // CHECK-LABEL: test_vld1_dup_s8
   return vld1_dup_s8(a);
-  // CHECK: ld1r {v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1r {{{ *v[0-9]+.8b *}}}, [{{x[0-9]+|sp}}]
 }
 
-int16x4_t test_vld1_dup_s16(int16_t const *a) {
+int16x4_t test_vld1_dup_s16(int16_t  *a) {
   // CHECK-LABEL: test_vld1_dup_s16
   return vld1_dup_s16(a);
-  // CHECK: ld1r {v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1r {{{ *v[0-9]+.4h *}}}, [{{x[0-9]+|sp}}]
 }
 
-int32x2_t test_vld1_dup_s32(int32_t const *a) {
+int32x2_t test_vld1_dup_s32(int32_t  *a) {
   // CHECK-LABEL: test_vld1_dup_s32
   return vld1_dup_s32(a);
-  // CHECK: ld1r {v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1r {{{ *v[0-9]+.2s *}}}, [{{x[0-9]+|sp}}]
 }
 
-int64x1_t test_vld1_dup_s64(int64_t const *a) {
+int64x1_t test_vld1_dup_s64(int64_t  *a) {
   // CHECK-LABEL: test_vld1_dup_s64
   return vld1_dup_s64(a);
-  // CHECK: ld1r {v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1r { v[0-9]+.1d }|ldr d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
-float16x4_t test_vld1_dup_f16(float16_t const *a) {
+float16x4_t test_vld1_dup_f16(float16_t  *a) {
   // CHECK-LABEL: test_vld1_dup_f16
   return vld1_dup_f16(a);
-  // CHECK: ld1r {v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1r {{{ *v[0-9]+.4h *}}}, [{{x[0-9]+|sp}}]
 }
 
-float32x2_t test_vld1_dup_f32(float32_t const *a) {
+float32x2_t test_vld1_dup_f32(float32_t  *a) {
   // CHECK-LABEL: test_vld1_dup_f32
   return vld1_dup_f32(a);
-  // CHECK: ld1r {v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1r {{{ *v[0-9]+.2s *}}}, [{{x[0-9]+|sp}}]
 }
 
-float64x1_t test_vld1_dup_f64(float64_t const *a) {
+float64x1_t test_vld1_dup_f64(float64_t  *a) {
   // CHECK-LABEL: test_vld1_dup_f64
   return vld1_dup_f64(a);
-  // CHECK: ld1r {v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1r { v[0-9]+.1d }|ldr d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
-poly8x8_t test_vld1_dup_p8(poly8_t const *a) {
+poly8x8_t test_vld1_dup_p8(poly8_t  *a) {
   // CHECK-LABEL: test_vld1_dup_p8
   return vld1_dup_p8(a);
-  // CHECK: ld1r {v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1r {{{ *v[0-9]+.8b *}}}, [{{x[0-9]+|sp}}]
 }
 
-poly16x4_t test_vld1_dup_p16(poly16_t const *a) {
+poly16x4_t test_vld1_dup_p16(poly16_t  *a) {
   // CHECK-LABEL: test_vld1_dup_p16
   return vld1_dup_p16(a);
-  // CHECK: ld1r {v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1r {{{ *v[0-9]+.4h *}}}, [{{x[0-9]+|sp}}]
 }
 
-poly64x1_t test_vld1_dup_p64(poly64_t const *a) {
+poly64x1_t test_vld1_dup_p64(poly64_t  *a) {
   // CHECK-LABEL: test_vld1_dup_p64
   return vld1_dup_p64(a);
-  // CHECK: ld1r {v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1r { v[0-9]+.1d }|ldr d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
-uint8x16x2_t test_vld2q_dup_u8(uint8_t const *a) {
+uint8x16x2_t test_vld2q_dup_u8(uint8_t  *a) {
   // CHECK-LABEL: test_vld2q_dup_u8
   return vld2q_dup_u8(a);
-  // CHECK: ld2r {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2r {{{ *v[0-9]+.16b, v[0-9]+.16b *}}}, [{{x[0-9]+|sp}}]
 }
 
-uint16x8x2_t test_vld2q_dup_u16(uint16_t const *a) {
+uint16x8x2_t test_vld2q_dup_u16(uint16_t  *a) {
   // CHECK-LABEL: test_vld2q_dup_u16
   return vld2q_dup_u16(a);
-  // CHECK: ld2r {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2r {{{ *v[0-9]+.8h, v[0-9]+.8h *}}}, [{{x[0-9]+|sp}}]
 }
 
-uint32x4x2_t test_vld2q_dup_u32(uint32_t const *a) {
+uint32x4x2_t test_vld2q_dup_u32(uint32_t  *a) {
   // CHECK-LABEL: test_vld2q_dup_u32
   return vld2q_dup_u32(a);
-  // CHECK: ld2r {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2r {{{ *v[0-9]+.4s, v[0-9]+.4s *}}}, [{{x[0-9]+|sp}}]
 }
 
-uint64x2x2_t test_vld2q_dup_u64(uint64_t const *a) {
+uint64x2x2_t test_vld2q_dup_u64(uint64_t  *a) {
   // CHECK-LABEL: test_vld2q_dup_u64
   return vld2q_dup_u64(a);
-  // CHECK: ld2r {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2r {{{ *v[0-9]+.2d, v[0-9]+.2d *}}}, [{{x[0-9]+|sp}}]
 }
 
-int8x16x2_t test_vld2q_dup_s8(int8_t const *a) {
+int8x16x2_t test_vld2q_dup_s8(int8_t  *a) {
   // CHECK-LABEL: test_vld2q_dup_s8
   return vld2q_dup_s8(a);
-  // CHECK: ld2r {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2r {{{ *v[0-9]+.16b, v[0-9]+.16b *}}}, [{{x[0-9]+|sp}}]
 }
 
-int16x8x2_t test_vld2q_dup_s16(int16_t const *a) {
+int16x8x2_t test_vld2q_dup_s16(int16_t  *a) {
   // CHECK-LABEL: test_vld2q_dup_s16
   return vld2q_dup_s16(a);
-  // CHECK: ld2r {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2r {{{ *v[0-9]+.8h, v[0-9]+.8h *}}}, [{{x[0-9]+|sp}}]
 }
 
-int32x4x2_t test_vld2q_dup_s32(int32_t const *a) {
+int32x4x2_t test_vld2q_dup_s32(int32_t  *a) {
   // CHECK-LABEL: test_vld2q_dup_s32
   return vld2q_dup_s32(a);
-  // CHECK: ld2r {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2r {{{ *v[0-9]+.4s, v[0-9]+.4s *}}}, [{{x[0-9]+|sp}}]
 }
 
-int64x2x2_t test_vld2q_dup_s64(int64_t const *a) {
+int64x2x2_t test_vld2q_dup_s64(int64_t  *a) {
   // CHECK-LABEL: test_vld2q_dup_s64
   return vld2q_dup_s64(a);
-  // CHECK: ld2r {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2r {{{ *v[0-9]+.2d, v[0-9]+.2d *}}}, [{{x[0-9]+|sp}}]
 }
 
-float16x8x2_t test_vld2q_dup_f16(float16_t const *a) {
+float16x8x2_t test_vld2q_dup_f16(float16_t  *a) {
   // CHECK-LABEL: test_vld2q_dup_f16
   return vld2q_dup_f16(a);
-  // CHECK: ld2r {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2r {{{ *v[0-9]+.8h, v[0-9]+.8h *}}}, [{{x[0-9]+|sp}}]
 }
 
-float32x4x2_t test_vld2q_dup_f32(float32_t const *a) {
+float32x4x2_t test_vld2q_dup_f32(float32_t  *a) {
   // CHECK-LABEL: test_vld2q_dup_f32
   return vld2q_dup_f32(a);
-  // CHECK: ld2r {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2r {{{ *v[0-9]+.4s, v[0-9]+.4s *}}}, [{{x[0-9]+|sp}}]
 }
 
-float64x2x2_t test_vld2q_dup_f64(float64_t const *a) {
+float64x2x2_t test_vld2q_dup_f64(float64_t  *a) {
   // CHECK-LABEL: test_vld2q_dup_f64
   return vld2q_dup_f64(a);
-  // CHECK: ld2r {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2r {{{ *v[0-9]+.2d, v[0-9]+.2d *}}}, [{{x[0-9]+|sp}}]
 }
 
-poly8x16x2_t test_vld2q_dup_p8(poly8_t const *a) {
+poly8x16x2_t test_vld2q_dup_p8(poly8_t  *a) {
   // CHECK-LABEL: test_vld2q_dup_p8
   return vld2q_dup_p8(a);
-  // CHECK: ld2r {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2r {{{ *v[0-9]+.16b, v[0-9]+.16b *}}}, [{{x[0-9]+|sp}}]
 }
 
-poly16x8x2_t test_vld2q_dup_p16(poly16_t const *a) {
+poly16x8x2_t test_vld2q_dup_p16(poly16_t  *a) {
   // CHECK-LABEL: test_vld2q_dup_p16
   return vld2q_dup_p16(a);
-  // CHECK: ld2r {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2r {{{ *v[0-9]+.8h, v[0-9]+.8h *}}}, [{{x[0-9]+|sp}}]
 }
 
-poly64x2x2_t test_vld2q_dup_p64(poly64_t const *a) {
+poly64x2x2_t test_vld2q_dup_p64(poly64_t  *a) {
   // CHECK-LABEL: test_vld2q_dup_p64
   return vld2q_dup_p64(a);
-  // CHECK: ld2r {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2r {{{ *v[0-9]+.2d, v[0-9]+.2d *}}}, [{{x[0-9]+|sp}}]
 }
 
-uint8x8x2_t test_vld2_dup_u8(uint8_t const *a) {
+uint8x8x2_t test_vld2_dup_u8(uint8_t  *a) {
   // CHECK-LABEL: test_vld2_dup_u8
   return vld2_dup_u8(a);
-  // CHECK: ld2r {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2r {{{ *v[0-9]+.8b, v[0-9]+.8b *}}}, [{{x[0-9]+|sp}}]
 }
 
-uint16x4x2_t test_vld2_dup_u16(uint16_t const *a) {
+uint16x4x2_t test_vld2_dup_u16(uint16_t  *a) {
   // CHECK-LABEL: test_vld2_dup_u16
   return vld2_dup_u16(a);
-  // CHECK: ld2r {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2r {{{ *v[0-9]+.4h, v[0-9]+.4h *}}}, [{{x[0-9]+|sp}}]
 }
 
-uint32x2x2_t test_vld2_dup_u32(uint32_t const *a) {
+uint32x2x2_t test_vld2_dup_u32(uint32_t  *a) {
   // CHECK-LABEL: test_vld2_dup_u32
   return vld2_dup_u32(a);
-  // CHECK: ld2r {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2r {{{ *v[0-9]+.2s, v[0-9]+.2s *}}}, [{{x[0-9]+|sp}}]
 }
 
-uint64x1x2_t test_vld2_dup_u64(uint64_t const *a) {
+uint64x1x2_t test_vld2_dup_u64(uint64_t  *a) {
   // CHECK-LABEL: test_vld2_dup_u64
   return vld2_dup_u64(a);
-  // CHECK: ld1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1|ld2r}} {{{ *v[0-9]+.1d, v[0-9]+.1d *}}}, [{{x[0-9]+|sp}}]
 }
 
-int8x8x2_t test_vld2_dup_s8(int8_t const *a) {
+int8x8x2_t test_vld2_dup_s8(int8_t  *a) {
   // CHECK-LABEL: test_vld2_dup_s8
   return vld2_dup_s8(a);
-  // CHECK: ld2r {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2r {{{ *v[0-9]+.8b, v[0-9]+.8b *}}}, [{{x[0-9]+|sp}}]
 }
 
-int16x4x2_t test_vld2_dup_s16(int16_t const *a) {
+int16x4x2_t test_vld2_dup_s16(int16_t  *a) {
   // CHECK-LABEL: test_vld2_dup_s16
   return vld2_dup_s16(a);
-  // CHECK: ld2r {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2r {{{ *v[0-9]+.4h, v[0-9]+.4h *}}}, [{{x[0-9]+|sp}}]
 }
 
-int32x2x2_t test_vld2_dup_s32(int32_t const *a) {
+int32x2x2_t test_vld2_dup_s32(int32_t  *a) {
   // CHECK-LABEL: test_vld2_dup_s32
   return vld2_dup_s32(a);
-  // CHECK: ld2r {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2r {{{ *v[0-9]+.2s, v[0-9]+.2s *}}}, [{{x[0-9]+|sp}}]
 }
 
-int64x1x2_t test_vld2_dup_s64(int64_t const *a) {
+int64x1x2_t test_vld2_dup_s64(int64_t  *a) {
   // CHECK-LABEL: test_vld2_dup_s64
   return vld2_dup_s64(a);
-  // CHECK: ld1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1|ld2r}} {{{ *v[0-9]+.1d, v[0-9]+.1d *}}}, [{{x[0-9]+|sp}}]
 }
 
-float16x4x2_t test_vld2_dup_f16(float16_t const *a) {
+float16x4x2_t test_vld2_dup_f16(float16_t  *a) {
   // CHECK-LABEL: test_vld2_dup_f16
   return vld2_dup_f16(a);
-  // CHECK: ld2r {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2r {{{ *v[0-9]+.4h, v[0-9]+.4h *}}}, [{{x[0-9]+|sp}}]
 }
 
-float32x2x2_t test_vld2_dup_f32(float32_t const *a) {
+float32x2x2_t test_vld2_dup_f32(float32_t  *a) {
   // CHECK-LABEL: test_vld2_dup_f32
   return vld2_dup_f32(a);
-  // CHECK: ld2r {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2r {{{ *v[0-9]+.2s, v[0-9]+.2s *}}}, [{{x[0-9]+|sp}}]
 }
 
-float64x1x2_t test_vld2_dup_f64(float64_t const *a) {
+float64x1x2_t test_vld2_dup_f64(float64_t  *a) {
   // CHECK-LABEL: test_vld2_dup_f64
   return vld2_dup_f64(a);
-  // CHECK: ld1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1|ld2r}} {{{ *v[0-9]+.1d, v[0-9]+.1d *}}}, [{{x[0-9]+|sp}}]
 }
 
-poly8x8x2_t test_vld2_dup_p8(poly8_t const *a) {
+poly8x8x2_t test_vld2_dup_p8(poly8_t  *a) {
   // CHECK-LABEL: test_vld2_dup_p8
   return vld2_dup_p8(a);
-  // CHECK: ld2r {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2r {{{ *v[0-9]+.8b, v[0-9]+.8b *}}}, [{{x[0-9]+|sp}}]
 }
 
-poly16x4x2_t test_vld2_dup_p16(poly16_t const *a) {
+poly16x4x2_t test_vld2_dup_p16(poly16_t  *a) {
   // CHECK-LABEL: test_vld2_dup_p16
   return vld2_dup_p16(a);
-  // CHECK: ld2r {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2r {{{ *v[0-9]+.4h, v[0-9]+.4h *}}}, [{{x[0-9]+|sp}}]
 }
 
-poly64x1x2_t test_vld2_dup_p64(poly64_t const *a) {
+poly64x1x2_t test_vld2_dup_p64(poly64_t  *a) {
   // CHECK-LABEL: test_vld2_dup_p64
   return vld2_dup_p64(a);
-  // CHECK: ld1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1|ld2r}} {{{ *v[0-9]+.1d, v[0-9]+.1d *}}}, [{{x[0-9]+|sp}}]
 }
 
-uint8x16x3_t test_vld3q_dup_u8(uint8_t const *a) {
+uint8x16x3_t test_vld3q_dup_u8(uint8_t  *a) {
   // CHECK-LABEL: test_vld3q_dup_u8
   return vld3q_dup_u8(a);
-  // CHECK: ld3r {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b},
+  // CHECK: ld3r {{{ *v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b *}}},
   // [{{x[0-9]+|sp}}]
 }
 
-uint16x8x3_t test_vld3q_dup_u16(uint16_t const *a) {
+uint16x8x3_t test_vld3q_dup_u16(uint16_t  *a) {
   // CHECK-LABEL: test_vld3q_dup_u16
   return vld3q_dup_u16(a);
-  // CHECK: ld3r {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h},
+  // CHECK: ld3r {{{ *v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h *}}},
   // [{{x[0-9]+|sp}}]
 }
 
-uint32x4x3_t test_vld3q_dup_u32(uint32_t const *a) {
+uint32x4x3_t test_vld3q_dup_u32(uint32_t  *a) {
   // CHECK-LABEL: test_vld3q_dup_u32
   return vld3q_dup_u32(a);
-  // CHECK: ld3r {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s, v{{[0-9]+}}.4s},
+  // CHECK: ld3r {{{ *v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s *}}},
   // [{{x[0-9]+|sp}}]
 }
 
-uint64x2x3_t test_vld3q_dup_u64(uint64_t const *a) {
+uint64x2x3_t test_vld3q_dup_u64(uint64_t  *a) {
   // CHECK-LABEL: test_vld3q_dup_u64
   return vld3q_dup_u64(a);
-  // CHECK: ld3r {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d},
+  // CHECK: ld3r {{{ *v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d *}}},
   // [{{x[0-9]+|sp}}]
 }
 
-int8x16x3_t test_vld3q_dup_s8(int8_t const *a) {
+int8x16x3_t test_vld3q_dup_s8(int8_t  *a) {
   // CHECK-LABEL: test_vld3q_dup_s8
   return vld3q_dup_s8(a);
-  // CHECK: ld3r {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b},
+  // CHECK: ld3r {{{ *v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b *}}},
   // [{{x[0-9]+|sp}}]
 }
 
-int16x8x3_t test_vld3q_dup_s16(int16_t const *a) {
+int16x8x3_t test_vld3q_dup_s16(int16_t  *a) {
   // CHECK-LABEL: test_vld3q_dup_s16
   return vld3q_dup_s16(a);
-  // CHECK: ld3r {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h},
+  // CHECK: ld3r {{{ *v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h *}}},
   // [{{x[0-9]+|sp}}]
 }
 
-int32x4x3_t test_vld3q_dup_s32(int32_t const *a) {
+int32x4x3_t test_vld3q_dup_s32(int32_t  *a) {
   // CHECK-LABEL: test_vld3q_dup_s32
   return vld3q_dup_s32(a);
-  // CHECK: ld3r {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s, v{{[0-9]+}}.4s},
+  // CHECK: ld3r {{{ *v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s *}}},
   // [{{x[0-9]+|sp}}]
 }
 
-int64x2x3_t test_vld3q_dup_s64(int64_t const *a) {
+int64x2x3_t test_vld3q_dup_s64(int64_t  *a) {
   // CHECK-LABEL: test_vld3q_dup_s64
   return vld3q_dup_s64(a);
-  // CHECK: ld3r {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d},
+  // CHECK: ld3r {{{ *v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d *}}},
   // [{{x[0-9]+|sp}}]
 }
 
-float16x8x3_t test_vld3q_dup_f16(float16_t const *a) {
+float16x8x3_t test_vld3q_dup_f16(float16_t  *a) {
   // CHECK-LABEL: test_vld3q_dup_f16
   return vld3q_dup_f16(a);
-  // CHECK: ld3r {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h},
+  // CHECK: ld3r {{{ *v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h *}}},
   // [{{x[0-9]+|sp}}]
 }
 
-float32x4x3_t test_vld3q_dup_f32(float32_t const *a) {
+float32x4x3_t test_vld3q_dup_f32(float32_t  *a) {
   // CHECK-LABEL: test_vld3q_dup_f32
   return vld3q_dup_f32(a);
-  // CHECK: ld3r {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s, v{{[0-9]+}}.4s},
+  // CHECK: ld3r {{{ *v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s *}}},
   // [{{x[0-9]+|sp}}]
 }
 
-float64x2x3_t test_vld3q_dup_f64(float64_t const *a) {
+float64x2x3_t test_vld3q_dup_f64(float64_t  *a) {
   // CHECK-LABEL: test_vld3q_dup_f64
   return vld3q_dup_f64(a);
-  // CHECK: ld3r {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d},
+  // CHECK: ld3r {{{ *v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d *}}},
   // [{{x[0-9]+|sp}}]
 }
 
-poly8x16x3_t test_vld3q_dup_p8(poly8_t const *a) {
+poly8x16x3_t test_vld3q_dup_p8(poly8_t  *a) {
   // CHECK-LABEL: test_vld3q_dup_p8
   return vld3q_dup_p8(a);
-  // CHECK: ld3r {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b},
+  // CHECK: ld3r {{{ *v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b *}}},
   // [{{x[0-9]+|sp}}]
 }
 
-poly16x8x3_t test_vld3q_dup_p16(poly16_t const *a) {
+poly16x8x3_t test_vld3q_dup_p16(poly16_t  *a) {
   // CHECK-LABEL: test_vld3q_dup_p16
   return vld3q_dup_p16(a);
-  // CHECK: ld3r {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h},
+  // CHECK: ld3r {{{ *v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h *}}},
   // [{{x[0-9]+|sp}}]
 }
 
-poly64x2x3_t test_vld3q_dup_p64(poly64_t const *a) {
+poly64x2x3_t test_vld3q_dup_p64(poly64_t  *a) {
   // CHECK-LABEL: test_vld3q_dup_p64
   return vld3q_dup_p64(a);
-  // CHECK: ld3r {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d},
+  // CHECK: ld3r {{{ *v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d *}}},
   // [{{x[0-9]+|sp}}]
 }
 
-uint8x8x3_t test_vld3_dup_u8(uint8_t const *a) {
+uint8x8x3_t test_vld3_dup_u8(uint8_t  *a) {
   // CHECK-LABEL: test_vld3_dup_u8
   return vld3_dup_u8(a);
-  // CHECK: ld3r {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b, v{{[0-9]+}}.8b},
+  // CHECK: ld3r {{{ *v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b *}}},
   // [{{x[0-9]+|sp}}]
 }
 
-uint16x4x3_t test_vld3_dup_u16(uint16_t const *a) {
+uint16x4x3_t test_vld3_dup_u16(uint16_t  *a) {
   // CHECK-LABEL: test_vld3_dup_u16
   return vld3_dup_u16(a);
-  // CHECK: ld3r {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h},
+  // CHECK: ld3r {{{ *v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h *}}},
   // [{{x[0-9]+|sp}}]
 }
 
-uint32x2x3_t test_vld3_dup_u32(uint32_t const *a) {
+uint32x2x3_t test_vld3_dup_u32(uint32_t  *a) {
   // CHECK-LABEL: test_vld3_dup_u32
   return vld3_dup_u32(a);
-  // CHECK: ld3r {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s, v{{[0-9]+}}.2s},
+  // CHECK: ld3r {{{ *v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s *}}},
   // [{{x[0-9]+|sp}}]
 }
 
-uint64x1x3_t test_vld3_dup_u64(uint64_t const *a) {
+uint64x1x3_t test_vld3_dup_u64(uint64_t  *a) {
   // CHECK-LABEL: test_vld3_dup_u64
   return vld3_dup_u64(a);
-  // CHECK: ld1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d},
+  // CHECK: {{ld1|ld3r}} {{{ *v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d *}}},
   // [{{x[0-9]+|sp}}]
 }
 
-int8x8x3_t test_vld3_dup_s8(int8_t const *a) {
+int8x8x3_t test_vld3_dup_s8(int8_t  *a) {
   // CHECK-LABEL: test_vld3_dup_s8
   return vld3_dup_s8(a);
-  // CHECK: ld3r {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b, v{{[0-9]+}}.8b},
+  // CHECK: ld3r {{{ *v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b *}}},
   // [{{x[0-9]+|sp}}]
 }
 
-int16x4x3_t test_vld3_dup_s16(int16_t const *a) {
+int16x4x3_t test_vld3_dup_s16(int16_t  *a) {
   // CHECK-LABEL: test_vld3_dup_s16
   return vld3_dup_s16(a);
-  // CHECK: ld3r {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h},
+  // CHECK: ld3r {{{ *v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h *}}},
   // [{{x[0-9]+|sp}}]
 }
 
-int32x2x3_t test_vld3_dup_s32(int32_t const *a) {
+int32x2x3_t test_vld3_dup_s32(int32_t  *a) {
   // CHECK-LABEL: test_vld3_dup_s32
   return vld3_dup_s32(a);
-  // CHECK: ld3r {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s, v{{[0-9]+}}.2s},
+  // CHECK: ld3r {{{ *v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s *}}},
   // [{{x[0-9]+|sp}}]
 }
 
-int64x1x3_t test_vld3_dup_s64(int64_t const *a) {
+int64x1x3_t test_vld3_dup_s64(int64_t  *a) {
   // CHECK-LABEL: test_vld3_dup_s64
   return vld3_dup_s64(a);
-  // CHECK: ld1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d},
+  // CHECK: {{ld1|ld3r}} {{{ *v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d *}}},
   // [{{x[0-9]+|sp}}]
 }
 
-float16x4x3_t test_vld3_dup_f16(float16_t const *a) {
+float16x4x3_t test_vld3_dup_f16(float16_t  *a) {
   // CHECK-LABEL: test_vld3_dup_f16
   return vld3_dup_f16(a);
-  // CHECK: ld3r {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h},
+  // CHECK: ld3r {{{ *v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h *}}},
   // [{{x[0-9]+|sp}}]
 }
 
-float32x2x3_t test_vld3_dup_f32(float32_t const *a) {
+float32x2x3_t test_vld3_dup_f32(float32_t  *a) {
   // CHECK-LABEL: test_vld3_dup_f32
   return vld3_dup_f32(a);
-  // CHECK: ld3r {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s, v{{[0-9]+}}.2s},
+  // CHECK: ld3r {{{ *v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s *}}},
   // [{{x[0-9]+|sp}}]
 }
 
-float64x1x3_t test_vld3_dup_f64(float64_t const *a) {
+float64x1x3_t test_vld3_dup_f64(float64_t  *a) {
   // CHECK-LABEL: test_vld3_dup_f64
   return vld3_dup_f64(a);
-  // CHECK: ld1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d},
+  // CHECK: {{ld1|ld3r}} {{{ *v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d *}}},
   // [{{x[0-9]+|sp}}]
 }
 
-poly8x8x3_t test_vld3_dup_p8(poly8_t const *a) {
+poly8x8x3_t test_vld3_dup_p8(poly8_t  *a) {
   // CHECK-LABEL: test_vld3_dup_p8
   return vld3_dup_p8(a);
-  // CHECK: ld3r {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b, v{{[0-9]+}}.8b},
+  // CHECK: ld3r {{{ *v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b *}}},
   // [{{x[0-9]+|sp}}]
 }
 
-poly16x4x3_t test_vld3_dup_p16(poly16_t const *a) {
+poly16x4x3_t test_vld3_dup_p16(poly16_t  *a) {
   // CHECK-LABEL: test_vld3_dup_p16
   return vld3_dup_p16(a);
-  // CHECK: ld3r {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h},
+  // CHECK: ld3r {{{ *v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h *}}},
   // [{{x[0-9]+|sp}}]
 }
 
-poly64x1x3_t test_vld3_dup_p64(poly64_t const *a) {
+poly64x1x3_t test_vld3_dup_p64(poly64_t  *a) {
   // CHECK-LABEL: test_vld3_dup_p64
   return vld3_dup_p64(a);
-  // CHECK: ld1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d},
+  // CHECK: {{ld1|ld3r}} {{{ *v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d *}}},
   // [{{x[0-9]+|sp}}]
 }
 
-uint8x16x4_t test_vld4q_dup_u8(uint8_t const *a) {
+uint8x16x4_t test_vld4q_dup_u8(uint8_t  *a) {
   // CHECK-LABEL: test_vld4q_dup_u8
   return vld4q_dup_u8(a);
-  // CHECK: ld4r {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b,
-  // v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4r {{{ *v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b *}}}, [{{x[0-9]+|sp}}]
 }
 
-uint16x8x4_t test_vld4q_dup_u16(uint16_t const *a) {
+uint16x8x4_t test_vld4q_dup_u16(uint16_t  *a) {
   // CHECK-LABEL: test_vld4q_dup_u16
   return vld4q_dup_u16(a);
-  // CHECK: ld4r {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h,
-  // v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4r {{{ *v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h *}}}, [{{x[0-9]+|sp}}]
 }
 
-uint32x4x4_t test_vld4q_dup_u32(uint32_t const *a) {
+uint32x4x4_t test_vld4q_dup_u32(uint32_t  *a) {
   // CHECK-LABEL: test_vld4q_dup_u32
   return vld4q_dup_u32(a);
-  // CHECK: ld4r {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s, v{{[0-9]+}}.4s,
-  // v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4r {{{ *v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s *}}}, [{{x[0-9]+|sp}}]
 }
 
-uint64x2x4_t test_vld4q_dup_u64(uint64_t const *a) {
+uint64x2x4_t test_vld4q_dup_u64(uint64_t  *a) {
   // CHECK-LABEL: test_vld4q_dup_u64
   return vld4q_dup_u64(a);
-  // CHECK: ld4r {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d,
-  // v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4r {{{ *v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d *}}}, [{{x[0-9]+|sp}}]
 }
 
-int8x16x4_t test_vld4q_dup_s8(int8_t const *a) {
+int8x16x4_t test_vld4q_dup_s8(int8_t  *a) {
   // CHECK-LABEL: test_vld4q_dup_s8
   return vld4q_dup_s8(a);
-  // CHECK: ld4r {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b,
-  // v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4r {{{ *v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b *}}}, [{{x[0-9]+|sp}}]
 }
 
-int16x8x4_t test_vld4q_dup_s16(int16_t const *a) {
+int16x8x4_t test_vld4q_dup_s16(int16_t  *a) {
   // CHECK-LABEL: test_vld4q_dup_s16
   return vld4q_dup_s16(a);
-  // CHECK: ld4r {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h,
-  // v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4r {{{ *v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h *}}}, [{{x[0-9]+|sp}}]
 }
 
-int32x4x4_t test_vld4q_dup_s32(int32_t const *a) {
+int32x4x4_t test_vld4q_dup_s32(int32_t  *a) {
   // CHECK-LABEL: test_vld4q_dup_s32
   return vld4q_dup_s32(a);
-  // CHECK: ld4r {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s, v{{[0-9]+}}.4s,
-  // v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4r {{{ *v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s *}}}, [{{x[0-9]+|sp}}]
 }
 
-int64x2x4_t test_vld4q_dup_s64(int64_t const *a) {
+int64x2x4_t test_vld4q_dup_s64(int64_t  *a) {
   // CHECK-LABEL: test_vld4q_dup_s64
   return vld4q_dup_s64(a);
-  // CHECK: ld4r {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d,
-  // v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4r {{{ *v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d *}}}, [{{x[0-9]+|sp}}]
 }
 
-float16x8x4_t test_vld4q_dup_f16(float16_t const *a) {
+float16x8x4_t test_vld4q_dup_f16(float16_t  *a) {
   // CHECK-LABEL: test_vld4q_dup_f16
   return vld4q_dup_f16(a);
-  // CHECK: ld4r {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h,
-  // v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4r {{{ *v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h *}}}, [{{x[0-9]+|sp}}]
 }
 
-float32x4x4_t test_vld4q_dup_f32(float32_t const *a) {
+float32x4x4_t test_vld4q_dup_f32(float32_t  *a) {
   // CHECK-LABEL: test_vld4q_dup_f32
   return vld4q_dup_f32(a);
-  // CHECK: ld4r {v{{[0-9]+}}.4s, v{{[0-9]+}}.4s, v{{[0-9]+}}.4s,
-  // v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4r {{{ *v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s, v[0-9]+.4s *}}}, [{{x[0-9]+|sp}}]
 }
 
-float64x2x4_t test_vld4q_dup_f64(float64_t const *a) {
+float64x2x4_t test_vld4q_dup_f64(float64_t  *a) {
   // CHECK-LABEL: test_vld4q_dup_f64
   return vld4q_dup_f64(a);
-  // CHECK: ld4r {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d,
-  // v{{[0-9]+}}.4s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4r {{{ *v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d *}}}, [{{x[0-9]+|sp}}]
 }
 
-poly8x16x4_t test_vld4q_dup_p8(poly8_t const *a) {
+poly8x16x4_t test_vld4q_dup_p8(poly8_t  *a) {
   // CHECK-LABEL: test_vld4q_dup_p8
   return vld4q_dup_p8(a);
-  // CHECK: ld4r {v{{[0-9]+}}.16b, v{{[0-9]+}}.16b, v{{[0-9]+}}.16b,
-  // v{{[0-9]+}}.16b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4r {{{ *v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b *}}}, [{{x[0-9]+|sp}}]
 }
 
-poly16x8x4_t test_vld4q_dup_p16(poly16_t const *a) {
+poly16x8x4_t test_vld4q_dup_p16(poly16_t  *a) {
   // CHECK-LABEL: test_vld4q_dup_p16
   return vld4q_dup_p16(a);
-  // CHECK: ld4r {v{{[0-9]+}}.8h, v{{[0-9]+}}.8h, v{{[0-9]+}}.8h,
-  // v{{[0-9]+}}.8h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4r {{{ *v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h, v[0-9]+.8h *}}}, [{{x[0-9]+|sp}}]
 }
 
-poly64x2x4_t test_vld4q_dup_p64(poly64_t const *a) {
+poly64x2x4_t test_vld4q_dup_p64(poly64_t  *a) {
   // CHECK-LABEL: test_vld4q_dup_p64
   return vld4q_dup_p64(a);
-  // CHECK: ld4r {v{{[0-9]+}}.2d, v{{[0-9]+}}.2d, v{{[0-9]+}}.2d,
-  // v{{[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4r {{{ *v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d *}}}, [{{x[0-9]+|sp}}]
 }
 
-uint8x8x4_t test_vld4_dup_u8(uint8_t const *a) {
+uint8x8x4_t test_vld4_dup_u8(uint8_t  *a) {
   // CHECK-LABEL: test_vld4_dup_u8
   return vld4_dup_u8(a);
-  // CHECK: ld4r {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b, v{{[0-9]+}}.8b,
-  // v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4r {{{ *v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b *}}}, [{{x[0-9]+|sp}}]
 }
 
-uint16x4x4_t test_vld4_dup_u16(uint16_t const *a) {
+uint16x4x4_t test_vld4_dup_u16(uint16_t  *a) {
   // CHECK-LABEL: test_vld4_dup_u16
   return vld4_dup_u16(a);
-  // CHECK: ld4r {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h,
-  // v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4r {{{ *v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h *}}}, [{{x[0-9]+|sp}}]
 }
 
-uint32x2x4_t test_vld4_dup_u32(uint32_t const *a) {
+uint32x2x4_t test_vld4_dup_u32(uint32_t  *a) {
   // CHECK-LABEL: test_vld4_dup_u32
   return vld4_dup_u32(a);
-  // CHECK: ld4r {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s, v{{[0-9]+}}.2s,
-  // v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4r {{{ *v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s *}}}, [{{x[0-9]+|sp}}]
 }
 
-uint64x1x4_t test_vld4_dup_u64(uint64_t const *a) {
+uint64x1x4_t test_vld4_dup_u64(uint64_t  *a) {
   // CHECK-LABEL: test_vld4_dup_u64
   return vld4_dup_u64(a);
-  // CHECK: ld1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d,
-  // v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1|ld4r}} {{{ *v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d *}}}, [{{x[0-9]+|sp}}]
 }
 
-int8x8x4_t test_vld4_dup_s8(int8_t const *a) {
+int8x8x4_t test_vld4_dup_s8(int8_t  *a) {
   // CHECK-LABEL: test_vld4_dup_s8
   return vld4_dup_s8(a);
-  // CHECK: ld4r {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b, v{{[0-9]+}}.8b,
-  // v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4r {{{ *v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b *}}}, [{{x[0-9]+|sp}}]
 }
 
-int16x4x4_t test_vld4_dup_s16(int16_t const *a) {
+int16x4x4_t test_vld4_dup_s16(int16_t  *a) {
   // CHECK-LABEL: test_vld4_dup_s16
   return vld4_dup_s16(a);
-  // CHECK: ld4r {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h,
-  // v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4r {{{ *v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h *}}}, [{{x[0-9]+|sp}}]
 }
 
-int32x2x4_t test_vld4_dup_s32(int32_t const *a) {
+int32x2x4_t test_vld4_dup_s32(int32_t  *a) {
   // CHECK-LABEL: test_vld4_dup_s32
   return vld4_dup_s32(a);
-  // CHECK: ld4r {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s, v{{[0-9]+}}.2s,
-  // v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4r {{{ *v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s *}}}, [{{x[0-9]+|sp}}]
 }
 
-int64x1x4_t test_vld4_dup_s64(int64_t const *a) {
+int64x1x4_t test_vld4_dup_s64(int64_t  *a) {
   // CHECK-LABEL: test_vld4_dup_s64
   return vld4_dup_s64(a);
-  // CHECK: ld1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d,
-  // v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1|ld4r}} {{{ *v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d *}}}, [{{x[0-9]+|sp}}]
 }
 
-float16x4x4_t test_vld4_dup_f16(float16_t const *a) {
+float16x4x4_t test_vld4_dup_f16(float16_t  *a) {
   // CHECK-LABEL: test_vld4_dup_f16
   return vld4_dup_f16(a);
-  // CHECK: ld4r {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h,
-  // v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4r {{{ *v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h *}}}, [{{x[0-9]+|sp}}]
 }
 
-float32x2x4_t test_vld4_dup_f32(float32_t const *a) {
+float32x2x4_t test_vld4_dup_f32(float32_t  *a) {
   // CHECK-LABEL: test_vld4_dup_f32
   return vld4_dup_f32(a);
-  // CHECK: ld4r {v{{[0-9]+}}.2s, v{{[0-9]+}}.2s, v{{[0-9]+}}.2s,
-  // v{{[0-9]+}}.2s}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4r {{{ *v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s, v[0-9]+.2s *}}}, [{{x[0-9]+|sp}}]
 }
 
-float64x1x4_t test_vld4_dup_f64(float64_t const *a) {
+float64x1x4_t test_vld4_dup_f64(float64_t  *a) {
   // CHECK-LABEL: test_vld4_dup_f64
   return vld4_dup_f64(a);
-  // CHECK: ld1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d,
-  // v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1|ld4r}} {{{ *v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d *}}}, [{{x[0-9]+|sp}}]
 }
 
-poly8x8x4_t test_vld4_dup_p8(poly8_t const *a) {
+poly8x8x4_t test_vld4_dup_p8(poly8_t  *a) {
   // CHECK-LABEL: test_vld4_dup_p8
   return vld4_dup_p8(a);
-  // CHECK: ld4r {v{{[0-9]+}}.8b, v{{[0-9]+}}.8b, v{{[0-9]+}}.8b,
-  // v{{[0-9]+}}.8b}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4r {{{ *v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b, v[0-9]+.8b *}}}, [{{x[0-9]+|sp}}]
 }
 
-poly16x4x4_t test_vld4_dup_p16(poly16_t const *a) {
+poly16x4x4_t test_vld4_dup_p16(poly16_t  *a) {
   // CHECK-LABEL: test_vld4_dup_p16
   return vld4_dup_p16(a);
-  // CHECK: ld4r {v{{[0-9]+}}.4h, v{{[0-9]+}}.4h, v{{[0-9]+}}.4h,
-  // v{{[0-9]+}}.4h}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4r {{{ *v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h, v[0-9]+.4h *}}}, [{{x[0-9]+|sp}}]
 }
 
-poly64x1x4_t test_vld4_dup_p64(poly64_t const *a) {
+poly64x1x4_t test_vld4_dup_p64(poly64_t  *a) {
   // CHECK-LABEL: test_vld4_dup_p64
   return vld4_dup_p64(a);
-  // CHECK: ld1 {v{{[0-9]+}}.1d, v{{[0-9]+}}.1d, v{{[0-9]+}}.1d,
-  // v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1|ld4r}} {{{ *v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d *}}}, [{{x[0-9]+|sp}}]
 }
 
-uint8x16_t test_vld1q_lane_u8(uint8_t const *a, uint8x16_t b) {
+uint8x16_t test_vld1q_lane_u8(uint8_t  *a, uint8x16_t b) {
   // CHECK-LABEL: test_vld1q_lane_u8
   return vld1q_lane_u8(a, b, 15);
-  // CHECK: ld1 {v{{[0-9]+}}.b}[15], [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ *v[0-9]+.b *}}}[15], [{{x[0-9]+|sp}}]
 }
 
-uint16x8_t test_vld1q_lane_u16(uint16_t const *a, uint16x8_t b) {
+uint16x8_t test_vld1q_lane_u16(uint16_t  *a, uint16x8_t b) {
   // CHECK-LABEL: test_vld1q_lane_u16
   return vld1q_lane_u16(a, b, 7);
-  // CHECK: ld1 {v{{[0-9]+}}.h}[7], [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ *v[0-9]+.h *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-uint32x4_t test_vld1q_lane_u32(uint32_t const *a, uint32x4_t b) {
+uint32x4_t test_vld1q_lane_u32(uint32_t  *a, uint32x4_t b) {
   // CHECK-LABEL: test_vld1q_lane_u32
   return vld1q_lane_u32(a, b, 3);
-  // CHECK: ld1 {v{{[0-9]+}}.s}[3], [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ *v[0-9]+.s *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-uint64x2_t test_vld1q_lane_u64(uint64_t const *a, uint64x2_t b) {
+uint64x2_t test_vld1q_lane_u64(uint64_t  *a, uint64x2_t b) {
   // CHECK-LABEL: test_vld1q_lane_u64
   return vld1q_lane_u64(a, b, 1);
-  // CHECK: ld1 {v{{[0-9]+}}.d}[1], [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ *v[0-9]+.d *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-int8x16_t test_vld1q_lane_s8(int8_t const *a, int8x16_t b) {
+int8x16_t test_vld1q_lane_s8(int8_t  *a, int8x16_t b) {
   // CHECK-LABEL: test_vld1q_lane_s8
   return vld1q_lane_s8(a, b, 15);
-  // CHECK: ld1 {v{{[0-9]+}}.b}[15], [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ *v[0-9]+.b *}}}[15], [{{x[0-9]+|sp}}]
 }
 
-int16x8_t test_vld1q_lane_s16(int16_t const *a, int16x8_t b) {
+int16x8_t test_vld1q_lane_s16(int16_t  *a, int16x8_t b) {
   // CHECK-LABEL: test_vld1q_lane_s16
   return vld1q_lane_s16(a, b, 7);
-  // CHECK: ld1 {v{{[0-9]+}}.h}[7], [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ *v[0-9]+.h *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-int32x4_t test_vld1q_lane_s32(int32_t const *a, int32x4_t b) {
+int32x4_t test_vld1q_lane_s32(int32_t  *a, int32x4_t b) {
   // CHECK-LABEL: test_vld1q_lane_s32
   return vld1q_lane_s32(a, b, 3);
-  // CHECK: ld1 {v{{[0-9]+}}.s}[3], [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ *v[0-9]+.s *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-int64x2_t test_vld1q_lane_s64(int64_t const *a, int64x2_t b) {
+int64x2_t test_vld1q_lane_s64(int64_t  *a, int64x2_t b) {
   // CHECK-LABEL: test_vld1q_lane_s64
   return vld1q_lane_s64(a, b, 1);
-  // CHECK: ld1 {v{{[0-9]+}}.d}[1], [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ *v[0-9]+.d *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-float16x8_t test_vld1q_lane_f16(float16_t const *a, float16x8_t b) {
+float16x8_t test_vld1q_lane_f16(float16_t  *a, float16x8_t b) {
   // CHECK-LABEL: test_vld1q_lane_f16
   return vld1q_lane_f16(a, b, 7);
-  // CHECK: ld1 {v{{[0-9]+}}.h}[7], [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ *v[0-9]+.h *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-float32x4_t test_vld1q_lane_f32(float32_t const *a, float32x4_t b) {
+float32x4_t test_vld1q_lane_f32(float32_t  *a, float32x4_t b) {
   // CHECK-LABEL: test_vld1q_lane_f32
   return vld1q_lane_f32(a, b, 3);
-  // CHECK: ld1 {v{{[0-9]+}}.s}[3], [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ *v[0-9]+.s *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-float64x2_t test_vld1q_lane_f64(float64_t const *a, float64x2_t b) {
+float64x2_t test_vld1q_lane_f64(float64_t  *a, float64x2_t b) {
   // CHECK-LABEL: test_vld1q_lane_f64
   return vld1q_lane_f64(a, b, 1);
-  // CHECK: ld1 {v{{[0-9]+}}.d}[1], [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ *v[0-9]+.d *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-poly8x16_t test_vld1q_lane_p8(poly8_t const *a, poly8x16_t b) {
+poly8x16_t test_vld1q_lane_p8(poly8_t  *a, poly8x16_t b) {
   // CHECK-LABEL: test_vld1q_lane_p8
   return vld1q_lane_p8(a, b, 15);
-  // CHECK: ld1 {v{{[0-9]+}}.b}[15], [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ *v[0-9]+.b *}}}[15], [{{x[0-9]+|sp}}]
 }
 
-poly16x8_t test_vld1q_lane_p16(poly16_t const *a, poly16x8_t b) {
+poly16x8_t test_vld1q_lane_p16(poly16_t  *a, poly16x8_t b) {
   // CHECK-LABEL: test_vld1q_lane_p16
   return vld1q_lane_p16(a, b, 7);
-  // CHECK: ld1 {v{{[0-9]+}}.h}[7], [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ *v[0-9]+.h *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-poly64x2_t test_vld1q_lane_p64(poly64_t const *a, poly64x2_t b) {
+poly64x2_t test_vld1q_lane_p64(poly64_t  *a, poly64x2_t b) {
   // CHECK-LABEL: test_vld1q_lane_p64
   return vld1q_lane_p64(a, b, 1);
-  // CHECK: ld1 {v{{[0-9]+}}.d}[1], [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ *v[0-9]+.d *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-uint8x8_t test_vld1_lane_u8(uint8_t const *a, uint8x8_t b) {
+uint8x8_t test_vld1_lane_u8(uint8_t  *a, uint8x8_t b) {
   // CHECK-LABEL: test_vld1_lane_u8
   return vld1_lane_u8(a, b, 7);
-  // CHECK: ld1 {v{{[0-9]+}}.b}[7], [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ *v[0-9]+.b *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-uint16x4_t test_vld1_lane_u16(uint16_t const *a, uint16x4_t b) {
+uint16x4_t test_vld1_lane_u16(uint16_t  *a, uint16x4_t b) {
   // CHECK-LABEL: test_vld1_lane_u16
   return vld1_lane_u16(a, b, 3);
-  // CHECK: ld1 {v{{[0-9]+}}.h}[3], [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ *v[0-9]+.h *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-uint32x2_t test_vld1_lane_u32(uint32_t const *a, uint32x2_t b) {
+uint32x2_t test_vld1_lane_u32(uint32_t  *a, uint32x2_t b) {
   // CHECK-LABEL: test_vld1_lane_u32
   return vld1_lane_u32(a, b, 1);
-  // CHECK: ld1 {v{{[0-9]+}}.s}[1], [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ *v[0-9]+.s *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-uint64x1_t test_vld1_lane_u64(uint64_t const *a, uint64x1_t b) {
+uint64x1_t test_vld1_lane_u64(uint64_t  *a, uint64x1_t b) {
   // CHECK-LABEL: test_vld1_lane_u64
   return vld1_lane_u64(a, b, 0);
-  // CHECK: ld1r {v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1r { v[0-9]+.1d }|ldr d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
-int8x8_t test_vld1_lane_s8(int8_t const *a, int8x8_t b) {
+int8x8_t test_vld1_lane_s8(int8_t  *a, int8x8_t b) {
   // CHECK-LABEL: test_vld1_lane_s8
   return vld1_lane_s8(a, b, 7);
-  // CHECK: ld1 {v{{[0-9]+}}.b}[7], [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ *v[0-9]+.b *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-int16x4_t test_vld1_lane_s16(int16_t const *a, int16x4_t b) {
+int16x4_t test_vld1_lane_s16(int16_t  *a, int16x4_t b) {
   // CHECK-LABEL: test_vld1_lane_s16
   return vld1_lane_s16(a, b, 3);
-  // CHECK: ld1 {v{{[0-9]+}}.h}[3], [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ *v[0-9]+.h *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-int32x2_t test_vld1_lane_s32(int32_t const *a, int32x2_t b) {
+int32x2_t test_vld1_lane_s32(int32_t  *a, int32x2_t b) {
   // CHECK-LABEL: test_vld1_lane_s32
   return vld1_lane_s32(a, b, 1);
-  // CHECK: ld1 {v{{[0-9]+}}.s}[1], [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ *v[0-9]+.s *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-int64x1_t test_vld1_lane_s64(int64_t const *a, int64x1_t b) {
+int64x1_t test_vld1_lane_s64(int64_t  *a, int64x1_t b) {
   // CHECK-LABEL: test_vld1_lane_s64
   return vld1_lane_s64(a, b, 0);
-  // CHECK: ld1r {v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1r { v[0-9]+.1d }|ldr d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
-float16x4_t test_vld1_lane_f16(float16_t const *a, float16x4_t b) {
+float16x4_t test_vld1_lane_f16(float16_t  *a, float16x4_t b) {
   // CHECK-LABEL: test_vld1_lane_f16
   return vld1_lane_f16(a, b, 3);
-  // CHECK: ld1 {v{{[0-9]+}}.h}[3], [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ *v[0-9]+.h *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-float32x2_t test_vld1_lane_f32(float32_t const *a, float32x2_t b) {
+float32x2_t test_vld1_lane_f32(float32_t  *a, float32x2_t b) {
   // CHECK-LABEL: test_vld1_lane_f32
   return vld1_lane_f32(a, b, 1);
-  // CHECK: ld1 {v{{[0-9]+}}.s}[1], [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ *v[0-9]+.s *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-float64x1_t test_vld1_lane_f64(float64_t const *a, float64x1_t b) {
+float64x1_t test_vld1_lane_f64(float64_t  *a, float64x1_t b) {
   // CHECK-LABEL: test_vld1_lane_f64
   return vld1_lane_f64(a, b, 0);
-  // CHECK: ld1r {v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1r { v[0-9]+.1d }|ldr d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
-poly8x8_t test_vld1_lane_p8(poly8_t const *a, poly8x8_t b) {
+poly8x8_t test_vld1_lane_p8(poly8_t  *a, poly8x8_t b) {
   // CHECK-LABEL: test_vld1_lane_p8
   return vld1_lane_p8(a, b, 7);
-  // CHECK: ld1 {v{{[0-9]+}}.b}[7], [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ *v[0-9]+.b *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-poly16x4_t test_vld1_lane_p16(poly16_t const *a, poly16x4_t b) {
+poly16x4_t test_vld1_lane_p16(poly16_t  *a, poly16x4_t b) {
   // CHECK-LABEL: test_vld1_lane_p16
   return vld1_lane_p16(a, b, 3);
-  // CHECK: ld1 {v{{[0-9]+}}.h}[3], [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ *v[0-9]+.h *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-poly64x1_t test_vld1_lane_p64(poly64_t const *a, poly64x1_t b) {
+poly64x1_t test_vld1_lane_p64(poly64_t  *a, poly64x1_t b) {
   // CHECK-LABEL: test_vld1_lane_p64
   return vld1_lane_p64(a, b, 0);
-  // CHECK: ld1r {v{{[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: {{ld1r { v[0-9]+.1d }|ldr d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
-uint16x8x2_t test_vld2q_lane_u16(uint16_t const *a, uint16x8x2_t b) {
+int8x16x2_t test_vld2q_lane_s8(int8_t const * ptr, int8x16x2_t src) {
+  // CHECK-LABEL: test_vld2q_lane_s8
+  return vld2q_lane_s8(ptr, src, 15);
+  // CHECK: ld2 {{{ *v[0-9]+.b,  v[0-9]+.b *}}}[15], [x0]
+}
+
+uint8x16x2_t test_vld2q_lane_u8(uint8_t const * ptr, uint8x16x2_t src) {
+  // CHECK-LABEL: test_vld2q_lane_u8
+  return vld2q_lane_u8(ptr, src, 15);
+  // CHECK: ld2 {{{ *v[0-9]+.b, v[0-9]+.b *}}}[15], [x0]
+}
+
+poly8x16x2_t test_vld2q_lane_p8(poly8_t const * ptr, poly8x16x2_t src) {
+  // CHECK-LABEL: test_vld2q_lane_p8
+  return vld2q_lane_p8(ptr, src, 15);
+  // CHECK: ld2 {{{ *v[0-9]+.b, v[0-9]+.b *}}}[15], [x0]
+}
+
+int8x16x3_t test_vld3q_lane_s8(int8_t const * ptr, int8x16x3_t src) {
+  // CHECK-LABEL: test_vld3q_lane_s8
+  return vld3q_lane_s8(ptr, src, 15);
+  // CHECK: ld3 {{{ *v[0-9]+.b, v[0-9]+.b, v[0-9]+.b *}}}[15], [x0]
+}
+
+uint8x16x3_t test_vld3q_lane_u8(uint8_t const * ptr, uint8x16x3_t src) {
+  // CHECK-LABEL: test_vld3q_lane_u8
+  return vld3q_lane_u8(ptr, src, 15);
+  // CHECK: ld3 {{{ *v[0-9]+.b, v[0-9]+.b, v[0-9]+.b *}}}[15], [x0]
+}
+
+uint16x8x2_t test_vld2q_lane_u16(uint16_t  *a, uint16x8x2_t b) {
   // CHECK-LABEL: test_vld2q_lane_u16
   return vld2q_lane_u16(a, b, 7);
-  // CHECK: ld2 {v{{[0-9]+}}.h, v{{[0-9]+}}.h}[7], [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ *v[0-9]+.h, v[0-9]+.h *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-uint32x4x2_t test_vld2q_lane_u32(uint32_t const *a, uint32x4x2_t b) {
+uint32x4x2_t test_vld2q_lane_u32(uint32_t  *a, uint32x4x2_t b) {
   // CHECK-LABEL: test_vld2q_lane_u32
   return vld2q_lane_u32(a, b, 3);
-  // CHECK: ld2 {v{{[0-9]+}}.s, v{{[0-9]+}}.s}[3], [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ *v[0-9]+.s, v[0-9]+.s *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-uint64x2x2_t test_vld2q_lane_u64(uint64_t const *a, uint64x2x2_t b) {
+uint64x2x2_t test_vld2q_lane_u64(uint64_t  *a, uint64x2x2_t b) {
   // CHECK-LABEL: test_vld2q_lane_u64
   return vld2q_lane_u64(a, b, 1);
-  // CHECK: ld2 {v{{[0-9]+}}.d, v{{[0-9]+}}.d}[1], [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ *v[0-9]+.d, v[0-9]+.d *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-int16x8x2_t test_vld2q_lane_s16(int16_t const *a, int16x8x2_t b) {
+int16x8x2_t test_vld2q_lane_s16(int16_t  *a, int16x8x2_t b) {
   // CHECK-LABEL: test_vld2q_lane_s16
   return vld2q_lane_s16(a, b, 7);
-  // CHECK: ld2 {v{{[0-9]+}}.h, v{{[0-9]+}}.h}[7], [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ *v[0-9]+.h, v[0-9]+.h *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-int32x4x2_t test_vld2q_lane_s32(int32_t const *a, int32x4x2_t b) {
+int32x4x2_t test_vld2q_lane_s32(int32_t  *a, int32x4x2_t b) {
   // CHECK-LABEL: test_vld2q_lane_s32
   return vld2q_lane_s32(a, b, 3);
-  // CHECK: ld2 {v{{[0-9]+}}.s, v{{[0-9]+}}.s}[3], [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ *v[0-9]+.s, v[0-9]+.s *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-int64x2x2_t test_vld2q_lane_s64(int64_t const *a, int64x2x2_t b) {
+int64x2x2_t test_vld2q_lane_s64(int64_t  *a, int64x2x2_t b) {
   // CHECK-LABEL: test_vld2q_lane_s64
   return vld2q_lane_s64(a, b, 1);
-  // CHECK: ld2 {v{{[0-9]+}}.d, v{{[0-9]+}}.d}[1], [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ *v[0-9]+.d, v[0-9]+.d *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-float16x8x2_t test_vld2q_lane_f16(float16_t const *a, float16x8x2_t b) {
+float16x8x2_t test_vld2q_lane_f16(float16_t  *a, float16x8x2_t b) {
   // CHECK-LABEL: test_vld2q_lane_f16
   return vld2q_lane_f16(a, b, 7);
-  // CHECK: ld2 {v{{[0-9]+}}.h, v{{[0-9]+}}.h}[7], [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ *v[0-9]+.h, v[0-9]+.h *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-float32x4x2_t test_vld2q_lane_f32(float32_t const *a, float32x4x2_t b) {
+float32x4x2_t test_vld2q_lane_f32(float32_t  *a, float32x4x2_t b) {
   // CHECK-LABEL: test_vld2q_lane_f32
   return vld2q_lane_f32(a, b, 3);
-  // CHECK: ld2 {v{{[0-9]+}}.s, v{{[0-9]+}}.s}[3], [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ *v[0-9]+.s, v[0-9]+.s *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-float64x2x2_t test_vld2q_lane_f64(float64_t const *a, float64x2x2_t b) {
+float64x2x2_t test_vld2q_lane_f64(float64_t  *a, float64x2x2_t b) {
   // CHECK-LABEL: test_vld2q_lane_f64
   return vld2q_lane_f64(a, b, 1);
-  // CHECK: ld2 {v{{[0-9]+}}.d, v{{[0-9]+}}.d}[1], [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ *v[0-9]+.d, v[0-9]+.d *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-poly16x8x2_t test_vld2q_lane_p16(poly16_t const *a, poly16x8x2_t b) {
+poly16x8x2_t test_vld2q_lane_p16(poly16_t  *a, poly16x8x2_t b) {
   // CHECK-LABEL: test_vld2q_lane_p16
   return vld2q_lane_p16(a, b, 7);
-  // CHECK: ld2 {v{{[0-9]+}}.h, v{{[0-9]+}}.h}[7], [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ *v[0-9]+.h, v[0-9]+.h *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-poly64x2x2_t test_vld2q_lane_p64(poly64_t const *a, poly64x2x2_t b) {
+poly64x2x2_t test_vld2q_lane_p64(poly64_t  *a, poly64x2x2_t b) {
   // CHECK-LABEL: test_vld2q_lane_p64
   return vld2q_lane_p64(a, b, 1);
-  // CHECK: ld2 {v{{[0-9]+}}.d, v{{[0-9]+}}.d}[1], [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ *v[0-9]+.d, v[0-9]+.d *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-uint8x8x2_t test_vld2_lane_u8(uint8_t const *a, uint8x8x2_t b) {
+uint8x8x2_t test_vld2_lane_u8(uint8_t  *a, uint8x8x2_t b) {
   // CHECK-LABEL: test_vld2_lane_u8
   return vld2_lane_u8(a, b, 7);
-  // CHECK: ld2 {v{{[0-9]+}}.b, v{{[0-9]+}}.b}[7], [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ *v[0-9]+.b, v[0-9]+.b *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-uint16x4x2_t test_vld2_lane_u16(uint16_t const *a, uint16x4x2_t b) {
+uint16x4x2_t test_vld2_lane_u16(uint16_t  *a, uint16x4x2_t b) {
   // CHECK-LABEL: test_vld2_lane_u16
   return vld2_lane_u16(a, b, 3);
-  // CHECK: ld2 {v{{[0-9]+}}.h, v{{[0-9]+}}.h}[3], [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ *v[0-9]+.h, v[0-9]+.h *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-uint32x2x2_t test_vld2_lane_u32(uint32_t const *a, uint32x2x2_t b) {
+uint32x2x2_t test_vld2_lane_u32(uint32_t  *a, uint32x2x2_t b) {
   // CHECK-LABEL: test_vld2_lane_u32
   return vld2_lane_u32(a, b, 1);
-  // CHECK: ld2 {v{{[0-9]+}}.s, v{{[0-9]+}}.s}[1], [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ *v[0-9]+.s, v[0-9]+.s *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-uint64x1x2_t test_vld2_lane_u64(uint64_t const *a, uint64x1x2_t b) {
+uint64x1x2_t test_vld2_lane_u64(uint64_t  *a, uint64x1x2_t b) {
   // CHECK-LABEL: test_vld2_lane_u64
   return vld2_lane_u64(a, b, 0);
-  // CHECK: ld2 {v{{[0-9]+}}.d, v{{[0-9]+}}.d}[0], [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ *v[0-9]+.d, v[0-9]+.d *}}}[0], [{{x[0-9]+|sp}}]
 }
 
-int8x8x2_t test_vld2_lane_s8(int8_t const *a, int8x8x2_t b) {
+int8x8x2_t test_vld2_lane_s8(int8_t  *a, int8x8x2_t b) {
   // CHECK-LABEL: test_vld2_lane_s8
   return vld2_lane_s8(a, b, 7);
-  // CHECK: ld2 {v{{[0-9]+}}.b, v{{[0-9]+}}.b}[7], [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ *v[0-9]+.b, v[0-9]+.b *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-int16x4x2_t test_vld2_lane_s16(int16_t const *a, int16x4x2_t b) {
+int16x4x2_t test_vld2_lane_s16(int16_t  *a, int16x4x2_t b) {
   // CHECK-LABEL: test_vld2_lane_s16
   return vld2_lane_s16(a, b, 3);
-  // CHECK: ld2 {v{{[0-9]+}}.h, v{{[0-9]+}}.h}[3], [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ *v[0-9]+.h, v[0-9]+.h *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-int32x2x2_t test_vld2_lane_s32(int32_t const *a, int32x2x2_t b) {
+int32x2x2_t test_vld2_lane_s32(int32_t  *a, int32x2x2_t b) {
   // CHECK-LABEL: test_vld2_lane_s32
   return vld2_lane_s32(a, b, 1);
-  // CHECK: ld2 {v{{[0-9]+}}.s, v{{[0-9]+}}.s}[1], [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ *v[0-9]+.s, v[0-9]+.s *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-int64x1x2_t test_vld2_lane_s64(int64_t const *a, int64x1x2_t b) {
+int64x1x2_t test_vld2_lane_s64(int64_t  *a, int64x1x2_t b) {
   // CHECK-LABEL: test_vld2_lane_s64
   return vld2_lane_s64(a, b, 0);
-  // CHECK: ld2 {v{{[0-9]+}}.d, v{{[0-9]+}}.d}[0], [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ *v[0-9]+.d, v[0-9]+.d *}}}[0], [{{x[0-9]+|sp}}]
 }
 
-float16x4x2_t test_vld2_lane_f16(float16_t const *a, float16x4x2_t b) {
+float16x4x2_t test_vld2_lane_f16(float16_t  *a, float16x4x2_t b) {
   // CHECK-LABEL: test_vld2_lane_f16
   return vld2_lane_f16(a, b, 3);
-  // CHECK: ld2 {v{{[0-9]+}}.h, v{{[0-9]+}}.h}[3], [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ *v[0-9]+.h, v[0-9]+.h *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-float32x2x2_t test_vld2_lane_f32(float32_t const *a, float32x2x2_t b) {
+float32x2x2_t test_vld2_lane_f32(float32_t  *a, float32x2x2_t b) {
   // CHECK-LABEL: test_vld2_lane_f32
   return vld2_lane_f32(a, b, 1);
-  // CHECK: ld2 {v{{[0-9]+}}.s, v{{[0-9]+}}.s}[1], [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ *v[0-9]+.s, v[0-9]+.s *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-float64x1x2_t test_vld2_lane_f64(float64_t const *a, float64x1x2_t b) {
+float64x1x2_t test_vld2_lane_f64(float64_t  *a, float64x1x2_t b) {
   // CHECK-LABEL: test_vld2_lane_f64
   return vld2_lane_f64(a, b, 0);
-  // CHECK: ld2 {v{{[0-9]+}}.d, v{{[0-9]+}}.d}[0], [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ *v[0-9]+.d, v[0-9]+.d *}}}[0], [{{x[0-9]+|sp}}]
 }
 
-poly8x8x2_t test_vld2_lane_p8(poly8_t const *a, poly8x8x2_t b) {
+poly8x8x2_t test_vld2_lane_p8(poly8_t  *a, poly8x8x2_t b) {
   // CHECK-LABEL: test_vld2_lane_p8
   return vld2_lane_p8(a, b, 7);
-  // CHECK: ld2 {v{{[0-9]+}}.b, v{{[0-9]+}}.b}[7], [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ *v[0-9]+.b, v[0-9]+.b *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-poly16x4x2_t test_vld2_lane_p16(poly16_t const *a, poly16x4x2_t b) {
+poly16x4x2_t test_vld2_lane_p16(poly16_t  *a, poly16x4x2_t b) {
   // CHECK-LABEL: test_vld2_lane_p16
   return vld2_lane_p16(a, b, 3);
-  // CHECK: ld2 {v{{[0-9]+}}.h, v{{[0-9]+}}.h}[3], [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ *v[0-9]+.h, v[0-9]+.h *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-poly64x1x2_t test_vld2_lane_p64(poly64_t const *a, poly64x1x2_t b) {
+poly64x1x2_t test_vld2_lane_p64(poly64_t  *a, poly64x1x2_t b) {
   // CHECK-LABEL: test_vld2_lane_p64
   return vld2_lane_p64(a, b, 0);
-  // CHECK: ld2 {v{{[0-9]+}}.d, v{{[0-9]+}}.d}[0], [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ *v[0-9]+.d, v[0-9]+.d *}}}[0], [{{x[0-9]+|sp}}]
 }
 
-uint16x8x3_t test_vld3q_lane_u16(uint16_t const *a, uint16x8x3_t b) {
+uint16x8x3_t test_vld3q_lane_u16(uint16_t  *a, uint16x8x3_t b) {
   // CHECK-LABEL: test_vld3q_lane_u16
   return vld3q_lane_u16(a, b, 7);
-  // CHECK: ld3 {v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h}[7], [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ *v[0-9]+.h, v[0-9]+.h, v[0-9]+.h *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-uint32x4x3_t test_vld3q_lane_u32(uint32_t const *a, uint32x4x3_t b) {
+uint32x4x3_t test_vld3q_lane_u32(uint32_t  *a, uint32x4x3_t b) {
   // CHECK-LABEL: test_vld3q_lane_u32
   return vld3q_lane_u32(a, b, 3);
-  // CHECK: ld3 {v{{[0-9]+}}.s, v{{[0-9]+}}.s, v{{[0-9]+}}.s}[3], [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ *v[0-9]+.s, v[0-9]+.s, v[0-9]+.s *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-uint64x2x3_t test_vld3q_lane_u64(uint64_t const *a, uint64x2x3_t b) {
+uint64x2x3_t test_vld3q_lane_u64(uint64_t  *a, uint64x2x3_t b) {
   // CHECK-LABEL: test_vld3q_lane_u64
   return vld3q_lane_u64(a, b, 1);
-  // CHECK: ld3 {v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d}[1], [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ *v[0-9]+.d, v[0-9]+.d, v[0-9]+.d *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-int16x8x3_t test_vld3q_lane_s16(int16_t const *a, int16x8x3_t b) {
+int16x8x3_t test_vld3q_lane_s16(int16_t  *a, int16x8x3_t b) {
   // CHECK-LABEL: test_vld3q_lane_s16
   return vld3q_lane_s16(a, b, 7);
-  // CHECK: ld3 {v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h}[7], [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ *v[0-9]+.h, v[0-9]+.h, v[0-9]+.h *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-int32x4x3_t test_vld3q_lane_s32(int32_t const *a, int32x4x3_t b) {
+int32x4x3_t test_vld3q_lane_s32(int32_t  *a, int32x4x3_t b) {
   // CHECK-LABEL: test_vld3q_lane_s32
   return vld3q_lane_s32(a, b, 3);
-  // CHECK: ld3 {v{{[0-9]+}}.s, v{{[0-9]+}}.s, v{{[0-9]+}}.s}[3], [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ *v[0-9]+.s, v[0-9]+.s, v[0-9]+.s *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-int64x2x3_t test_vld3q_lane_s64(int64_t const *a, int64x2x3_t b) {
+int64x2x3_t test_vld3q_lane_s64(int64_t  *a, int64x2x3_t b) {
   // CHECK-LABEL: test_vld3q_lane_s64
   return vld3q_lane_s64(a, b, 1);
-  // CHECK: ld3 {v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d}[1], [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ *v[0-9]+.d, v[0-9]+.d, v[0-9]+.d *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-float16x8x3_t test_vld3q_lane_f16(float16_t const *a, float16x8x3_t b) {
+float16x8x3_t test_vld3q_lane_f16(float16_t  *a, float16x8x3_t b) {
   // CHECK-LABEL: test_vld3q_lane_f16
   return vld3q_lane_f16(a, b, 7);
-  // CHECK: ld3 {v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h}[7], [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ *v[0-9]+.h, v[0-9]+.h, v[0-9]+.h *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-float32x4x3_t test_vld3q_lane_f32(float32_t const *a, float32x4x3_t b) {
+float32x4x3_t test_vld3q_lane_f32(float32_t  *a, float32x4x3_t b) {
   // CHECK-LABEL: test_vld3q_lane_f32
   return vld3q_lane_f32(a, b, 3);
-  // CHECK: ld3 {v{{[0-9]+}}.s, v{{[0-9]+}}.s, v{{[0-9]+}}.s}[3], [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ *v[0-9]+.s, v[0-9]+.s, v[0-9]+.s *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-float64x2x3_t test_vld3q_lane_f64(float64_t const *a, float64x2x3_t b) {
+float64x2x3_t test_vld3q_lane_f64(float64_t  *a, float64x2x3_t b) {
   // CHECK-LABEL: test_vld3q_lane_f64
   return vld3q_lane_f64(a, b, 1);
-  // CHECK: ld3 {v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d}[1], [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ *v[0-9]+.d, v[0-9]+.d, v[0-9]+.d *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-poly8x16x3_t test_vld3q_lane_p8(poly8_t const *a, poly8x16x3_t b) {
+poly8x16x3_t test_vld3q_lane_p8(poly8_t  *a, poly8x16x3_t b) {
   // CHECK-LABEL: test_vld3q_lane_p8
   return vld3q_lane_p8(a, b, 15);
-  // CHECK: ld3 {v{{[0-9]+}}.b, v{{[0-9]+}}.b, v{{[0-9]+}}.b}[15], [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ *v[0-9]+.b, v[0-9]+.b, v[0-9]+.b *}}}[15], [{{x[0-9]+|sp}}]
 }
 
-poly16x8x3_t test_vld3q_lane_p16(poly16_t const *a, poly16x8x3_t b) {
+poly16x8x3_t test_vld3q_lane_p16(poly16_t  *a, poly16x8x3_t b) {
   // CHECK-LABEL: test_vld3q_lane_p16
   return vld3q_lane_p16(a, b, 7);
-  // CHECK: ld3 {v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h}[7], [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ *v[0-9]+.h, v[0-9]+.h, v[0-9]+.h *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-poly64x2x3_t test_vld3q_lane_p64(poly64_t const *a, poly64x2x3_t b) {
+poly64x2x3_t test_vld3q_lane_p64(poly64_t  *a, poly64x2x3_t b) {
   // CHECK-LABEL: test_vld3q_lane_p64
   return vld3q_lane_p64(a, b, 1);
-  // CHECK: ld3 {v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d}[1], [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ *v[0-9]+.d, v[0-9]+.d, v[0-9]+.d *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-uint8x8x3_t test_vld3_lane_u8(uint8_t const *a, uint8x8x3_t b) {
+uint8x8x3_t test_vld3_lane_u8(uint8_t  *a, uint8x8x3_t b) {
   // CHECK-LABEL: test_vld3_lane_u8
   return vld3_lane_u8(a, b, 7);
-  // CHECK: ld3 {v{{[0-9]+}}.b, v{{[0-9]+}}.b, v{{[0-9]+}}.b}[7], [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ *v[0-9]+.b, v[0-9]+.b, v[0-9]+.b *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-uint16x4x3_t test_vld3_lane_u16(uint16_t const *a, uint16x4x3_t b) {
+uint16x4x3_t test_vld3_lane_u16(uint16_t  *a, uint16x4x3_t b) {
   // CHECK-LABEL: test_vld3_lane_u16
   return vld3_lane_u16(a, b, 3);
-  // CHECK: ld3 {v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h}[3], [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ *v[0-9]+.h, v[0-9]+.h, v[0-9]+.h *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-uint32x2x3_t test_vld3_lane_u32(uint32_t const *a, uint32x2x3_t b) {
+uint32x2x3_t test_vld3_lane_u32(uint32_t  *a, uint32x2x3_t b) {
   // CHECK-LABEL: test_vld3_lane_u32
   return vld3_lane_u32(a, b, 1);
-  // CHECK: ld3 {v{{[0-9]+}}.s, v{{[0-9]+}}.s, v{{[0-9]+}}.s}[1], [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ *v[0-9]+.s, v[0-9]+.s, v[0-9]+.s *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-uint64x1x3_t test_vld3_lane_u64(uint64_t const *a, uint64x1x3_t b) {
+uint64x1x3_t test_vld3_lane_u64(uint64_t  *a, uint64x1x3_t b) {
   // CHECK-LABEL: test_vld3_lane_u64
   return vld3_lane_u64(a, b, 0);
-  // CHECK: ld3 {v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d}[0], [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ *v[0-9]+.d, v[0-9]+.d, v[0-9]+.d *}}}[0], [{{x[0-9]+|sp}}]
 }
 
-int8x8x3_t test_vld3_lane_s8(int8_t const *a, int8x8x3_t b) {
+int8x8x3_t test_vld3_lane_s8(int8_t  *a, int8x8x3_t b) {
   // CHECK-LABEL: test_vld3_lane_s8
   return vld3_lane_s8(a, b, 7);
-  // CHECK: ld3 {v{{[0-9]+}}.b, v{{[0-9]+}}.b, v{{[0-9]+}}.b}[7], [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ *v[0-9]+.b, v[0-9]+.b, v[0-9]+.b *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-int16x4x3_t test_vld3_lane_s16(int16_t const *a, int16x4x3_t b) {
+int16x4x3_t test_vld3_lane_s16(int16_t  *a, int16x4x3_t b) {
   // CHECK-LABEL: test_vld3_lane_s16
   return vld3_lane_s16(a, b, 3);
-  // CHECK: ld3 {v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h}[3], [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ *v[0-9]+.h, v[0-9]+.h, v[0-9]+.h *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-int32x2x3_t test_vld3_lane_s32(int32_t const *a, int32x2x3_t b) {
+int32x2x3_t test_vld3_lane_s32(int32_t  *a, int32x2x3_t b) {
   // CHECK-LABEL: test_vld3_lane_s32
   return vld3_lane_s32(a, b, 1);
-  // CHECK: ld3 {v{{[0-9]+}}.s, v{{[0-9]+}}.s, v{{[0-9]+}}.s}[1], [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ *v[0-9]+.s, v[0-9]+.s, v[0-9]+.s *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-int64x1x3_t test_vld3_lane_s64(int64_t const *a, int64x1x3_t b) {
+int64x1x3_t test_vld3_lane_s64(int64_t  *a, int64x1x3_t b) {
   // CHECK-LABEL: test_vld3_lane_s64
   return vld3_lane_s64(a, b, 0);
-  // CHECK: ld3 {v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d}[0], [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ *v[0-9]+.d, v[0-9]+.d, v[0-9]+.d *}}}[0], [{{x[0-9]+|sp}}]
 }
 
-float16x4x3_t test_vld3_lane_f16(float16_t const *a, float16x4x3_t b) {
+float16x4x3_t test_vld3_lane_f16(float16_t  *a, float16x4x3_t b) {
   // CHECK-LABEL: test_vld3_lane_f16
   return vld3_lane_f16(a, b, 3);
-  // CHECK: ld3 {v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h}[3], [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ *v[0-9]+.h, v[0-9]+.h, v[0-9]+.h *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-float32x2x3_t test_vld3_lane_f32(float32_t const *a, float32x2x3_t b) {
+float32x2x3_t test_vld3_lane_f32(float32_t  *a, float32x2x3_t b) {
   // CHECK-LABEL: test_vld3_lane_f32
   return vld3_lane_f32(a, b, 1);
-  // CHECK: ld3 {v{{[0-9]+}}.s, v{{[0-9]+}}.s, v{{[0-9]+}}.s}[1], [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ *v[0-9]+.s, v[0-9]+.s, v[0-9]+.s *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-float64x1x3_t test_vld3_lane_f64(float64_t const *a, float64x1x3_t b) {
+float64x1x3_t test_vld3_lane_f64(float64_t  *a, float64x1x3_t b) {
   // CHECK-LABEL: test_vld3_lane_f64
   return vld3_lane_f64(a, b, 0);
-  // CHECK: ld3 {v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d}[0], [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ *v[0-9]+.d, v[0-9]+.d, v[0-9]+.d *}}}[0], [{{x[0-9]+|sp}}]
 }
 
-poly8x8x3_t test_vld3_lane_p8(poly8_t const *a, poly8x8x3_t b) {
+poly8x8x3_t test_vld3_lane_p8(poly8_t  *a, poly8x8x3_t b) {
   // CHECK-LABEL: test_vld3_lane_p8
   return vld3_lane_p8(a, b, 7);
-  // CHECK: ld3 {v{{[0-9]+}}.b, v{{[0-9]+}}.b, v{{[0-9]+}}.b}[7], [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ *v[0-9]+.b, v[0-9]+.b, v[0-9]+.b *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-poly16x4x3_t test_vld3_lane_p16(poly16_t const *a, poly16x4x3_t b) {
+poly16x4x3_t test_vld3_lane_p16(poly16_t  *a, poly16x4x3_t b) {
   // CHECK-LABEL: test_vld3_lane_p16
   return vld3_lane_p16(a, b, 3);
-  // CHECK: ld3 {v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h}[3], [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ *v[0-9]+.h, v[0-9]+.h, v[0-9]+.h *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-poly64x1x3_t test_vld3_lane_p64(poly64_t const *a, poly64x1x3_t b) {
+poly64x1x3_t test_vld3_lane_p64(poly64_t  *a, poly64x1x3_t b) {
   // CHECK-LABEL: test_vld3_lane_p64
   return vld3_lane_p64(a, b, 0);
-  // CHECK: ld3 {v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d}[0], [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ *v[0-9]+.d, v[0-9]+.d, v[0-9]+.d *}}}[0], [{{x[0-9]+|sp}}]
 }
 
-uint8x16x4_t test_vld4q_lane_u8(uint8_t const *a, uint8x16x4_t b) {
+uint8x16x4_t test_vld4q_lane_u8(uint8_t  *a, uint8x16x4_t b) {
   // CHECK-LABEL: test_vld4q_lane_u8
   return vld4q_lane_u8(a, b, 15);
-  // CHECK: ld4 {v{{[0-9]+}}.b, v{{[0-9]+}}.b, v{{[0-9]+}}.b, v{{[0-9]+}}.b}[15], [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ *v[0-9]+.b, v[0-9]+.b, v[0-9]+.b, v[0-9]+.b *}}}[15], [{{x[0-9]+|sp}}]
 }
 
-uint16x8x4_t test_vld4q_lane_u16(uint16_t const *a, uint16x8x4_t b) {
+uint16x8x4_t test_vld4q_lane_u16(uint16_t  *a, uint16x8x4_t b) {
   // CHECK-LABEL: test_vld4q_lane_u16
   return vld4q_lane_u16(a, b, 7);
-  // CHECK: ld4 {v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h}[7], [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ *v[0-9]+.h, v[0-9]+.h, v[0-9]+.h, v[0-9]+.h *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-uint32x4x4_t test_vld4q_lane_u32(uint32_t const *a, uint32x4x4_t b) {
+uint32x4x4_t test_vld4q_lane_u32(uint32_t  *a, uint32x4x4_t b) {
   // CHECK-LABEL: test_vld4q_lane_u32
   return vld4q_lane_u32(a, b, 3);
-  // CHECK: ld4 {v{{[0-9]+}}.s, v{{[0-9]+}}.s, v{{[0-9]+}}.s, v{{[0-9]+}}.s}[3], [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ *v[0-9]+.s, v[0-9]+.s, v[0-9]+.s, v[0-9]+.s *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-uint64x2x4_t test_vld4q_lane_u64(uint64_t const *a, uint64x2x4_t b) {
+uint64x2x4_t test_vld4q_lane_u64(uint64_t  *a, uint64x2x4_t b) {
   // CHECK-LABEL: test_vld4q_lane_u64
   return vld4q_lane_u64(a, b, 1);
-  // CHECK: ld4 {v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d}[1], [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ *v[0-9]+.d, v[0-9]+.d, v[0-9]+.d, v[0-9]+.d *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-int8x16x4_t test_vld4q_lane_s8(int8_t const *a, int8x16x4_t b) {
+int8x16x4_t test_vld4q_lane_s8(int8_t  *a, int8x16x4_t b) {
   // CHECK-LABEL: test_vld4q_lane_s8
   return vld4q_lane_s8(a, b, 15);
-  // CHECK: ld4 {v{{[0-9]+}}.b, v{{[0-9]+}}.b, v{{[0-9]+}}.b, v{{[0-9]+}}.b}[15], [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ *v[0-9]+.b, v[0-9]+.b, v[0-9]+.b, v[0-9]+.b *}}}[15], [{{x[0-9]+|sp}}]
 }
 
-int16x8x4_t test_vld4q_lane_s16(int16_t const *a, int16x8x4_t b) {
+int16x8x4_t test_vld4q_lane_s16(int16_t  *a, int16x8x4_t b) {
   // CHECK-LABEL: test_vld4q_lane_s16
   return vld4q_lane_s16(a, b, 7);
-  // CHECK: ld4 {v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h}[7], [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ *v[0-9]+.h, v[0-9]+.h, v[0-9]+.h, v[0-9]+.h *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-int32x4x4_t test_vld4q_lane_s32(int32_t const *a, int32x4x4_t b) {
+int32x4x4_t test_vld4q_lane_s32(int32_t  *a, int32x4x4_t b) {
   // CHECK-LABEL: test_vld4q_lane_s32
   return vld4q_lane_s32(a, b, 3);
-  // CHECK: ld4 {v{{[0-9]+}}.s, v{{[0-9]+}}.s, v{{[0-9]+}}.s, v{{[0-9]+}}.s}[3], [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ *v[0-9]+.s, v[0-9]+.s, v[0-9]+.s, v[0-9]+.s *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-int64x2x4_t test_vld4q_lane_s64(int64_t const *a, int64x2x4_t b) {
+int64x2x4_t test_vld4q_lane_s64(int64_t  *a, int64x2x4_t b) {
   // CHECK-LABEL: test_vld4q_lane_s64
   return vld4q_lane_s64(a, b, 1);
-  // CHECK: ld4 {v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d}[1], [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ *v[0-9]+.d, v[0-9]+.d, v[0-9]+.d, v[0-9]+.d *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-float16x8x4_t test_vld4q_lane_f16(float16_t const *a, float16x8x4_t b) {
+float16x8x4_t test_vld4q_lane_f16(float16_t  *a, float16x8x4_t b) {
   // CHECK-LABEL: test_vld4q_lane_f16
   return vld4q_lane_f16(a, b, 7);
-  // CHECK: ld4 {v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h}[7], [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ *v[0-9]+.h, v[0-9]+.h, v[0-9]+.h, v[0-9]+.h *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-float32x4x4_t test_vld4q_lane_f32(float32_t const *a, float32x4x4_t b) {
+float32x4x4_t test_vld4q_lane_f32(float32_t  *a, float32x4x4_t b) {
   // CHECK-LABEL: test_vld4q_lane_f32
   return vld4q_lane_f32(a, b, 3);
-  // CHECK: ld4 {v{{[0-9]+}}.s, v{{[0-9]+}}.s, v{{[0-9]+}}.s, v{{[0-9]+}}.s}[3], [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ *v[0-9]+.s, v[0-9]+.s, v[0-9]+.s, v[0-9]+.s *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-float64x2x4_t test_vld4q_lane_f64(float64_t const *a, float64x2x4_t b) {
+float64x2x4_t test_vld4q_lane_f64(float64_t  *a, float64x2x4_t b) {
   // CHECK-LABEL: test_vld4q_lane_f64
   return vld4q_lane_f64(a, b, 1);
-  // CHECK: ld4 {v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d}[1], [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ *v[0-9]+.d, v[0-9]+.d, v[0-9]+.d, v[0-9]+.d *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-poly8x16x4_t test_vld4q_lane_p8(poly8_t const *a, poly8x16x4_t b) {
+poly8x16x4_t test_vld4q_lane_p8(poly8_t  *a, poly8x16x4_t b) {
   // CHECK-LABEL: test_vld4q_lane_p8
   return vld4q_lane_p8(a, b, 15);
-  // CHECK: ld4 {v{{[0-9]+}}.b, v{{[0-9]+}}.b, v{{[0-9]+}}.b, v{{[0-9]+}}.b}[15], [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ *v[0-9]+.b, v[0-9]+.b, v[0-9]+.b, v[0-9]+.b *}}}[15], [{{x[0-9]+|sp}}]
 }
 
-poly16x8x4_t test_vld4q_lane_p16(poly16_t const *a, poly16x8x4_t b) {
+poly16x8x4_t test_vld4q_lane_p16(poly16_t  *a, poly16x8x4_t b) {
   // CHECK-LABEL: test_vld4q_lane_p16
   return vld4q_lane_p16(a, b, 7);
-  // CHECK: ld4 {v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h}[7], [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ *v[0-9]+.h, v[0-9]+.h, v[0-9]+.h, v[0-9]+.h *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-poly64x2x4_t test_vld4q_lane_p64(poly64_t const *a, poly64x2x4_t b) {
+poly64x2x4_t test_vld4q_lane_p64(poly64_t  *a, poly64x2x4_t b) {
   // CHECK-LABEL: test_vld4q_lane_p64
   return vld4q_lane_p64(a, b, 1);
-  // CHECK: ld4 {v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d}[1], [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ *v[0-9]+.d, v[0-9]+.d, v[0-9]+.d, v[0-9]+.d *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-uint8x8x4_t test_vld4_lane_u8(uint8_t const *a, uint8x8x4_t b) {
+uint8x8x4_t test_vld4_lane_u8(uint8_t  *a, uint8x8x4_t b) {
   // CHECK-LABEL: test_vld4_lane_u8
   return vld4_lane_u8(a, b, 7);
-  // CHECK: ld4 {v{{[0-9]+}}.b, v{{[0-9]+}}.b, v{{[0-9]+}}.b, v{{[0-9]+}}.b}[7], [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ *v[0-9]+.b, v[0-9]+.b, v[0-9]+.b, v[0-9]+.b *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-uint16x4x4_t test_vld4_lane_u16(uint16_t const *a, uint16x4x4_t b) {
+uint16x4x4_t test_vld4_lane_u16(uint16_t  *a, uint16x4x4_t b) {
   // CHECK-LABEL: test_vld4_lane_u16
   return vld4_lane_u16(a, b, 3);
-  // CHECK: ld4 {v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h}[3], [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ *v[0-9]+.h, v[0-9]+.h, v[0-9]+.h, v[0-9]+.h *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-uint32x2x4_t test_vld4_lane_u32(uint32_t const *a, uint32x2x4_t b) {
+uint32x2x4_t test_vld4_lane_u32(uint32_t  *a, uint32x2x4_t b) {
   // CHECK-LABEL: test_vld4_lane_u32
   return vld4_lane_u32(a, b, 1);
-  // CHECK: ld4 {v{{[0-9]+}}.s, v{{[0-9]+}}.s, v{{[0-9]+}}.s, v{{[0-9]+}}.s}[1], [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ *v[0-9]+.s, v[0-9]+.s, v[0-9]+.s, v[0-9]+.s *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-uint64x1x4_t test_vld4_lane_u64(uint64_t const *a, uint64x1x4_t b) {
+uint64x1x4_t test_vld4_lane_u64(uint64_t  *a, uint64x1x4_t b) {
   // CHECK-LABEL: test_vld4_lane_u64
   return vld4_lane_u64(a, b, 0);
-  // CHECK: ld4 {v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d}[0], [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ *v[0-9]+.d, v[0-9]+.d, v[0-9]+.d, v[0-9]+.d *}}}[0], [{{x[0-9]+|sp}}]
 }
 
-int8x8x4_t test_vld4_lane_s8(int8_t const *a, int8x8x4_t b) {
+int8x8x4_t test_vld4_lane_s8(int8_t  *a, int8x8x4_t b) {
   // CHECK-LABEL: test_vld4_lane_s8
   return vld4_lane_s8(a, b, 7);
-  // CHECK: ld4 {v{{[0-9]+}}.b, v{{[0-9]+}}.b, v{{[0-9]+}}.b, v{{[0-9]+}}.b}[7], [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ *v[0-9]+.b, v[0-9]+.b, v[0-9]+.b, v[0-9]+.b *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-int16x4x4_t test_vld4_lane_s16(int16_t const *a, int16x4x4_t b) {
+int16x4x4_t test_vld4_lane_s16(int16_t  *a, int16x4x4_t b) {
   // CHECK-LABEL: test_vld4_lane_s16
   return vld4_lane_s16(a, b, 3);
-  // CHECK: ld4 {v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h}[3], [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ *v[0-9]+.h, v[0-9]+.h, v[0-9]+.h, v[0-9]+.h *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-int32x2x4_t test_vld4_lane_s32(int32_t const *a, int32x2x4_t b) {
+int32x2x4_t test_vld4_lane_s32(int32_t  *a, int32x2x4_t b) {
   // CHECK-LABEL: test_vld4_lane_s32
   return vld4_lane_s32(a, b, 1);
-  // CHECK: ld4 {v{{[0-9]+}}.s, v{{[0-9]+}}.s, v{{[0-9]+}}.s, v{{[0-9]+}}.s}[1], [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ *v[0-9]+.s, v[0-9]+.s, v[0-9]+.s, v[0-9]+.s *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-int64x1x4_t test_vld4_lane_s64(int64_t const *a, int64x1x4_t b) {
+int64x1x4_t test_vld4_lane_s64(int64_t  *a, int64x1x4_t b) {
   // CHECK-LABEL: test_vld4_lane_s64
   return vld4_lane_s64(a, b, 0);
-  // CHECK: ld4 {v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d}[0], [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ *v[0-9]+.d, v[0-9]+.d, v[0-9]+.d, v[0-9]+.d *}}}[0], [{{x[0-9]+|sp}}]
 }
 
-float16x4x4_t test_vld4_lane_f16(float16_t const *a, float16x4x4_t b) {
+float16x4x4_t test_vld4_lane_f16(float16_t  *a, float16x4x4_t b) {
   // CHECK-LABEL: test_vld4_lane_f16
   return vld4_lane_f16(a, b, 3);
-  // CHECK: ld4 {v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h}[3], [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ *v[0-9]+.h, v[0-9]+.h, v[0-9]+.h, v[0-9]+.h *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-float32x2x4_t test_vld4_lane_f32(float32_t const *a, float32x2x4_t b) {
+float32x2x4_t test_vld4_lane_f32(float32_t  *a, float32x2x4_t b) {
   // CHECK-LABEL: test_vld4_lane_f32
   return vld4_lane_f32(a, b, 1);
-  // CHECK: ld4 {v{{[0-9]+}}.s, v{{[0-9]+}}.s, v{{[0-9]+}}.s, v{{[0-9]+}}.s}[1], [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ *v[0-9]+.s, v[0-9]+.s, v[0-9]+.s, v[0-9]+.s *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-float64x1x4_t test_vld4_lane_f64(float64_t const *a, float64x1x4_t b) {
+float64x1x4_t test_vld4_lane_f64(float64_t  *a, float64x1x4_t b) {
   // CHECK-LABEL: test_vld4_lane_f64
   return vld4_lane_f64(a, b, 0);
-  // CHECK: ld4 {v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d}[0], [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ *v[0-9]+.d, v[0-9]+.d, v[0-9]+.d, v[0-9]+.d *}}}[0], [{{x[0-9]+|sp}}]
 }
 
-poly8x8x4_t test_vld4_lane_p8(poly8_t const *a, poly8x8x4_t b) {
+poly8x8x4_t test_vld4_lane_p8(poly8_t  *a, poly8x8x4_t b) {
   // CHECK-LABEL: test_vld4_lane_p8
   return vld4_lane_p8(a, b, 7);
-  // CHECK: ld4 {v{{[0-9]+}}.b, v{{[0-9]+}}.b, v{{[0-9]+}}.b, v{{[0-9]+}}.b}[7], [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ *v[0-9]+.b, v[0-9]+.b, v[0-9]+.b, v[0-9]+.b *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-poly16x4x4_t test_vld4_lane_p16(poly16_t const *a, poly16x4x4_t b) {
+poly16x4x4_t test_vld4_lane_p16(poly16_t  *a, poly16x4x4_t b) {
   // CHECK-LABEL: test_vld4_lane_p16
   return vld4_lane_p16(a, b, 3);
-  // CHECK: ld4 {v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h}[3], [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ *v[0-9]+.h, v[0-9]+.h, v[0-9]+.h, v[0-9]+.h *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-poly64x1x4_t test_vld4_lane_p64(poly64_t const *a, poly64x1x4_t b) {
+poly64x1x4_t test_vld4_lane_p64(poly64_t  *a, poly64x1x4_t b) {
   // CHECK-LABEL: test_vld4_lane_p64
   return vld4_lane_p64(a, b, 0);
-  // CHECK: ld4 {v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d}[0], [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ *v[0-9]+.d, v[0-9]+.d, v[0-9]+.d, v[0-9]+.d *}}}[0], [{{x[0-9]+|sp}}]
 }
 
-void test_vst1q_lane_u8(uint8_t const *a, uint8x16_t b) {
+void test_vst1q_lane_u8(uint8_t  *a, uint8x16_t b) {
   // CHECK-LABEL: test_vst1q_lane_u8
   vst1q_lane_u8(a, b, 15);
-  // CHECK: st1 {v{{[0-9]+}}.b}[15], [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ *v[0-9]+.b *}}}[15], [{{x[0-9]+|sp}}]
 }
 
-void test_vst1q_lane_u16(uint16_t const *a, uint16x8_t b) {
+void test_vst1q_lane_u16(uint16_t  *a, uint16x8_t b) {
   // CHECK-LABEL: test_vst1q_lane_u16
   vst1q_lane_u16(a, b, 7);
-  // CHECK: st1 {v{{[0-9]+}}.h}[7], [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ *v[0-9]+.h *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-void test_vst1q_lane_u32(uint32_t const *a, uint32x4_t b) {
+void test_vst1q_lane_u32(uint32_t  *a, uint32x4_t b) {
   // CHECK-LABEL: test_vst1q_lane_u32
   vst1q_lane_u32(a, b, 3);
-  // CHECK: st1 {v{{[0-9]+}}.s}[3], [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ *v[0-9]+.s *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-void test_vst1q_lane_u64(uint64_t const *a, uint64x2_t b) {
+void test_vst1q_lane_u64(uint64_t  *a, uint64x2_t b) {
   // CHECK-LABEL: test_vst1q_lane_u64
   vst1q_lane_u64(a, b, 1);
-  // CHECK: st1 {v{{[0-9]+}}.d}[1], [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ *v[0-9]+.d *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-void test_vst1q_lane_s8(int8_t const *a, int8x16_t b) {
+void test_vst1q_lane_s8(int8_t  *a, int8x16_t b) {
   // CHECK-LABEL: test_vst1q_lane_s8
   vst1q_lane_s8(a, b, 15);
-  // CHECK: st1 {v{{[0-9]+}}.b}[15], [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ *v[0-9]+.b *}}}[15], [{{x[0-9]+|sp}}]
 }
 
-void test_vst1q_lane_s16(int16_t const *a, int16x8_t b) {
+void test_vst1q_lane_s16(int16_t  *a, int16x8_t b) {
   // CHECK-LABEL: test_vst1q_lane_s16
   vst1q_lane_s16(a, b, 7);
-  // CHECK: st1 {v{{[0-9]+}}.h}[7], [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ *v[0-9]+.h *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-void test_vst1q_lane_s32(int32_t const *a, int32x4_t b) {
+void test_vst1q_lane_s32(int32_t  *a, int32x4_t b) {
   // CHECK-LABEL: test_vst1q_lane_s32
   vst1q_lane_s32(a, b, 3);
-  // CHECK: st1 {v{{[0-9]+}}.s}[3], [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ *v[0-9]+.s *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-void test_vst1q_lane_s64(int64_t const *a, int64x2_t b) {
+void test_vst1q_lane_s64(int64_t  *a, int64x2_t b) {
   // CHECK-LABEL: test_vst1q_lane_s64
   vst1q_lane_s64(a, b, 1);
-  // CHECK: st1 {v{{[0-9]+}}.d}[1], [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ *v[0-9]+.d *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-void test_vst1q_lane_f16(float16_t const *a, float16x8_t b) {
+void test_vst1q_lane_f16(float16_t  *a, float16x8_t b) {
   // CHECK-LABEL: test_vst1q_lane_f16
   vst1q_lane_f16(a, b, 7);
-  // CHECK: st1 {v{{[0-9]+}}.h}[7], [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ *v[0-9]+.h *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-void test_vst1q_lane_f32(float32_t const *a, float32x4_t b) {
+void test_vst1q_lane_f32(float32_t  *a, float32x4_t b) {
   // CHECK-LABEL: test_vst1q_lane_f32
   vst1q_lane_f32(a, b, 3);
-  // CHECK: st1 {v{{[0-9]+}}.s}[3], [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ *v[0-9]+.s *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-void test_vst1q_lane_f64(float64_t const *a, float64x2_t b) {
+void test_vst1q_lane_f64(float64_t  *a, float64x2_t b) {
   // CHECK-LABEL: test_vst1q_lane_f64
   vst1q_lane_f64(a, b, 1);
-  // CHECK: st1 {v{{[0-9]+}}.d}[1], [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ *v[0-9]+.d *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-poly8x16_t test_vst1q_lane_p8(poly8_t const *a, poly8x16_t b) {
+void test_vst1q_lane_p8(poly8_t  *a, poly8x16_t b) {
   // CHECK-LABEL: test_vst1q_lane_p8
   vst1q_lane_p8(a, b, 15);
-  // CHECK: st1 {v{{[0-9]+}}.b}[15], [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ *v[0-9]+.b *}}}[15], [{{x[0-9]+|sp}}]
 }
 
-void test_vst1q_lane_p16(poly16_t const *a, poly16x8_t b) {
+void test_vst1q_lane_p16(poly16_t  *a, poly16x8_t b) {
   // CHECK-LABEL: test_vst1q_lane_p16
   vst1q_lane_p16(a, b, 7);
-  // CHECK: st1 {v{{[0-9]+}}.h}[7], [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ *v[0-9]+.h *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-void test_vst1q_lane_p64(poly64_t const *a, poly64x2_t b) {
+void test_vst1q_lane_p64(poly64_t  *a, poly64x2_t b) {
   // CHECK-LABEL: test_vst1q_lane_p64
   vst1q_lane_p64(a, b, 1);
-  // CHECK: st1 {v{{[0-9]+}}.d}[1], [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ *v[0-9]+.d *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-void test_vst1_lane_u8(uint8_t const *a, uint8x8_t b) {
+void test_vst1_lane_u8(uint8_t  *a, uint8x8_t b) {
   // CHECK-LABEL: test_vst1_lane_u8
   vst1_lane_u8(a, b, 7);
-  // CHECK: st1 {v{{[0-9]+}}.b}[7], [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ *v[0-9]+.b *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-void test_vst1_lane_u16(uint16_t const *a, uint16x4_t b) {
+void test_vst1_lane_u16(uint16_t  *a, uint16x4_t b) {
   // CHECK-LABEL: test_vst1_lane_u16
   vst1_lane_u16(a, b, 3);
-  // CHECK: st1 {v{{[0-9]+}}.h}[3], [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ *v[0-9]+.h *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-void test_vst1_lane_u32(uint32_t const *a, uint32x2_t b) {
+void test_vst1_lane_u32(uint32_t  *a, uint32x2_t b) {
   // CHECK-LABEL: test_vst1_lane_u32
   vst1_lane_u32(a, b, 1);
-  // CHECK: st1 {v{{[0-9]+}}.s}[1], [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ *v[0-9]+.s *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-void test_vst1_lane_u64(uint64_t const *a, uint64x1_t b) {
+void test_vst1_lane_u64(uint64_t  *a, uint64x1_t b) {
   // CHECK-LABEL: test_vst1_lane_u64
   vst1_lane_u64(a, b, 0);
-  // CHECK: st1 {v{{[0-9]+}}.d}[0], [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ *v[0-9]+.d *}}}[0], [{{x[0-9]+|sp}}]
 }
 
-void test_vst1_lane_s8(int8_t const *a, int8x8_t b) {
+void test_vst1_lane_s8(int8_t  *a, int8x8_t b) {
   // CHECK-LABEL: test_vst1_lane_s8
   vst1_lane_s8(a, b, 7);
-  // CHECK: st1 {v{{[0-9]+}}.b}[7], [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ *v[0-9]+.b *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-void test_vst1_lane_s16(int16_t const *a, int16x4_t b) {
+void test_vst1_lane_s16(int16_t  *a, int16x4_t b) {
   // CHECK-LABEL: test_vst1_lane_s16
   vst1_lane_s16(a, b, 3);
-  // CHECK: st1 {v{{[0-9]+}}.h}[3], [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ *v[0-9]+.h *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-void test_vst1_lane_s32(int32_t const *a, int32x2_t b) {
+void test_vst1_lane_s32(int32_t  *a, int32x2_t b) {
   // CHECK-LABEL: test_vst1_lane_s32
   vst1_lane_s32(a, b, 1);
-  // CHECK: st1 {v{{[0-9]+}}.s}[1], [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ *v[0-9]+.s *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-void test_vst1_lane_s64(int64_t const *a, int64x1_t b) {
+void test_vst1_lane_s64(int64_t  *a, int64x1_t b) {
   // CHECK-LABEL: test_vst1_lane_s64
   vst1_lane_s64(a, b, 0);
-  // CHECK: st1 {v{{[0-9]+}}.d}[0], [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ *v[0-9]+.d *}}}[0], [{{x[0-9]+|sp}}]
 }
 
-void test_vst1_lane_f16(float16_t const *a, float16x4_t b) {
+void test_vst1_lane_f16(float16_t  *a, float16x4_t b) {
   // CHECK-LABEL: test_vst1_lane_f16
   vst1_lane_f16(a, b, 3);
-  // CHECK: st1 {v{{[0-9]+}}.h}[3], [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ *v[0-9]+.h *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-void test_vst1_lane_f32(float32_t const *a, float32x2_t b) {
+void test_vst1_lane_f32(float32_t  *a, float32x2_t b) {
   // CHECK-LABEL: test_vst1_lane_f32
   vst1_lane_f32(a, b, 1);
-  // CHECK: st1 {v{{[0-9]+}}.s}[1], [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ *v[0-9]+.s *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-void test_vst1_lane_f64(float64_t const *a, float64x1_t b) {
+void test_vst1_lane_f64(float64_t  *a, float64x1_t b) {
   // CHECK-LABEL: test_vst1_lane_f64
   vst1_lane_f64(a, b, 0);
-  // CHECK: st1 {v{{[0-9]+}}.d}[0], [{{x[0-9]+|sp}}]
+  // CHECK: {{st1 { v[0-9]+.d }\[0]|str d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
-void test_vst1_lane_p8(poly8_t const *a, poly8x8_t b) {
+void test_vst1_lane_p8(poly8_t  *a, poly8x8_t b) {
   // CHECK-LABEL: test_vst1_lane_p8
   vst1_lane_p8(a, b, 7);
-  // CHECK: st1 {v{{[0-9]+}}.b}[7], [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ *v[0-9]+.b *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-void test_vst1_lane_p16(poly16_t const *a, poly16x4_t b) {
+void test_vst1_lane_p16(poly16_t  *a, poly16x4_t b) {
   // CHECK-LABEL: test_vst1_lane_p16
   vst1_lane_p16(a, b, 3);
-  // CHECK: st1 {v{{[0-9]+}}.h}[3], [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ *v[0-9]+.h *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-void test_vst1_lane_p64(poly64_t const *a, poly64x1_t b) {
+void test_vst1_lane_p64(poly64_t  *a, poly64x1_t b) {
   // CHECK-LABEL: test_vst1_lane_p64
   vst1_lane_p64(a, b, 0);
-  // CHECK: st1 {v{{[0-9]+}}.d}[0], [{{x[0-9]+|sp}}]
+  // CHECK: st1 {{{ *v[0-9]+.d *}}}[0], [{{x[0-9]+|sp}}]
 }
 
-void test_vst2q_lane_u8(uint8_t const *a, uint8x16x2_t b) {
+void test_vst2q_lane_u8(uint8_t  *a, uint8x16x2_t b) {
   // CHECK-LABEL: test_vst2q_lane_u8
   vst2q_lane_u8(a, b, 15);
-  // CHECK: st2 {v{{[0-9]+}}.b, v{{[0-9]+}}.b}[15], [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ *v[0-9]+.b, v[0-9]+.b *}}}[15], [{{x[0-9]+|sp}}]
 }
 
-void test_vst2q_lane_u16(uint16_t const *a, uint16x8x2_t b) {
+void test_vst2q_lane_u16(uint16_t  *a, uint16x8x2_t b) {
   // CHECK-LABEL: test_vst2q_lane_u16
   vst2q_lane_u16(a, b, 7);
-  // CHECK: st2 {v{{[0-9]+}}.h, v{{[0-9]+}}.h}[7], [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ *v[0-9]+.h, v[0-9]+.h *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-void test_vst2q_lane_u32(uint32_t const *a, uint32x4x2_t b) {
+void test_vst2q_lane_u32(uint32_t  *a, uint32x4x2_t b) {
   // CHECK-LABEL: test_vst2q_lane_u32
   vst2q_lane_u32(a, b, 3);
-  // CHECK: st2 {v{{[0-9]+}}.s, v{{[0-9]+}}.s}[3], [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ *v[0-9]+.s, v[0-9]+.s *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-void test_vst2q_lane_u64(uint64_t const *a, uint64x2x2_t b) {
+void test_vst2q_lane_u64(uint64_t  *a, uint64x2x2_t b) {
   // CHECK-LABEL: test_vst2q_lane_u64
   vst2q_lane_u64(a, b, 1);
-  // CHECK: st2 {v{{[0-9]+}}.d, v{{[0-9]+}}.d}[1], [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ *v[0-9]+.d, v[0-9]+.d *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-void test_vst2q_lane_s8(int8_t const *a, int8x16x2_t b) {
+void test_vst2q_lane_s8(int8_t  *a, int8x16x2_t b) {
   // CHECK-LABEL: test_vst2q_lane_s8
   vst2q_lane_s8(a, b, 15);
-  // CHECK: st2 {v{{[0-9]+}}.b, v{{[0-9]+}}.b}[15], [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ *v[0-9]+.b, v[0-9]+.b *}}}[15], [{{x[0-9]+|sp}}]
 }
 
-void test_vst2q_lane_s16(int16_t const *a, int16x8x2_t b) {
+void test_vst2q_lane_s16(int16_t  *a, int16x8x2_t b) {
   // CHECK-LABEL: test_vst2q_lane_s16
   vst2q_lane_s16(a, b, 7);
-  // CHECK: st2 {v{{[0-9]+}}.h, v{{[0-9]+}}.h}[7], [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ *v[0-9]+.h, v[0-9]+.h *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-void test_vst2q_lane_s32(int32_t const *a, int32x4x2_t b) {
+void test_vst2q_lane_s32(int32_t  *a, int32x4x2_t b) {
   // CHECK-LABEL: test_vst2q_lane_s32
   vst2q_lane_s32(a, b, 3);
-  // CHECK: st2 {v{{[0-9]+}}.s, v{{[0-9]+}}.s}[3], [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ *v[0-9]+.s, v[0-9]+.s *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-void test_vst2q_lane_s64(int64_t const *a, int64x2x2_t b) {
+void test_vst2q_lane_s64(int64_t  *a, int64x2x2_t b) {
   // CHECK-LABEL: test_vst2q_lane_s64
   vst2q_lane_s64(a, b, 1);
-  // CHECK: st2 {v{{[0-9]+}}.d, v{{[0-9]+}}.d}[1], [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ *v[0-9]+.d, v[0-9]+.d *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-void test_vst2q_lane_f16(float16_t const *a, float16x8x2_t b) {
+void test_vst2q_lane_f16(float16_t  *a, float16x8x2_t b) {
   // CHECK-LABEL: test_vst2q_lane_f16
   vst2q_lane_f16(a, b, 7);
-  // CHECK: st2 {v{{[0-9]+}}.h, v{{[0-9]+}}.h}[7], [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ *v[0-9]+.h, v[0-9]+.h *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-void test_vst2q_lane_f32(float32_t const *a, float32x4x2_t b) {
+void test_vst2q_lane_f32(float32_t  *a, float32x4x2_t b) {
   // CHECK-LABEL: test_vst2q_lane_f32
   vst2q_lane_f32(a, b, 3);
-  // CHECK: st2 {v{{[0-9]+}}.s, v{{[0-9]+}}.s}[3], [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ *v[0-9]+.s, v[0-9]+.s *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-void test_vst2q_lane_f64(float64_t const *a, float64x2x2_t b) {
+void test_vst2q_lane_f64(float64_t  *a, float64x2x2_t b) {
   // CHECK-LABEL: test_vst2q_lane_f64
   vst2q_lane_f64(a, b, 1);
-  // CHECK: st2 {v{{[0-9]+}}.d, v{{[0-9]+}}.d}[1], [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ *v[0-9]+.d, v[0-9]+.d *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-void test_vst2q_lane_p8(poly8_t const *a, poly8x16x2_t b) {
+void test_vst2q_lane_p8(poly8_t  *a, poly8x16x2_t b) {
   // CHECK-LABEL: test_vst2q_lane_p8
   vst2q_lane_p8(a, b, 15);
-  // CHECK: st2 {v{{[0-9]+}}.b, v{{[0-9]+}}.b}[15], [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ *v[0-9]+.b, v[0-9]+.b *}}}[15], [{{x[0-9]+|sp}}]
 }
 
-void test_vst2q_lane_p16(poly16_t const *a, poly16x8x2_t b) {
+void test_vst2q_lane_p16(poly16_t  *a, poly16x8x2_t b) {
   // CHECK-LABEL: test_vst2q_lane_p16
   vst2q_lane_p16(a, b, 7);
-  // CHECK: st2 {v{{[0-9]+}}.h, v{{[0-9]+}}.h}[7], [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ *v[0-9]+.h, v[0-9]+.h *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-void test_vst2q_lane_p64(poly64_t const *a, poly64x2x2_t b) {
+void test_vst2q_lane_p64(poly64_t  *a, poly64x2x2_t b) {
   // CHECK-LABEL: test_vst2q_lane_p64
   vst2q_lane_p64(a, b, 1);
-  // CHECK: st2 {v{{[0-9]+}}.d, v{{[0-9]+}}.d}[1], [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ *v[0-9]+.d, v[0-9]+.d *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-void test_vst2_lane_u8(uint8_t const *a, uint8x8x2_t b) {
+void test_vst2_lane_u8(uint8_t  *a, uint8x8x2_t b) {
   // CHECK-LABEL: test_vst2_lane_u8
   vst2_lane_u8(a, b, 7);
-  // CHECK: st2 {v{{[0-9]+}}.b, v{{[0-9]+}}.b}[7], [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ *v[0-9]+.b, v[0-9]+.b *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-void test_vst2_lane_u16(uint16_t const *a, uint16x4x2_t b) {
+void test_vst2_lane_u16(uint16_t  *a, uint16x4x2_t b) {
   // CHECK-LABEL: test_vst2_lane_u16
   vst2_lane_u16(a, b, 3);
-  // CHECK: st2 {v{{[0-9]+}}.h, v{{[0-9]+}}.h}[3], [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ *v[0-9]+.h, v[0-9]+.h *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-void test_vst2_lane_u32(uint32_t const *a, uint32x2x2_t b) {
+void test_vst2_lane_u32(uint32_t  *a, uint32x2x2_t b) {
   // CHECK-LABEL: test_vst2_lane_u32
   vst2_lane_u32(a, b, 1);
-  // CHECK: st2 {v{{[0-9]+}}.s, v{{[0-9]+}}.s}[1], [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ *v[0-9]+.s, v[0-9]+.s *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-void test_vst2_lane_u64(uint64_t const *a, uint64x1x2_t b) {
+void test_vst2_lane_u64(uint64_t  *a, uint64x1x2_t b) {
   // CHECK-LABEL: test_vst2_lane_u64
   vst2_lane_u64(a, b, 0);
-  // CHECK: st2 {v{{[0-9]+}}.d, v{{[0-9]+}}.d}[0], [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ *v[0-9]+.d, v[0-9]+.d *}}}[0], [{{x[0-9]+|sp}}]
 }
 
-void test_vst2_lane_s8(int8_t const *a, int8x8x2_t b) {
+void test_vst2_lane_s8(int8_t  *a, int8x8x2_t b) {
   // CHECK-LABEL: test_vst2_lane_s8
   vst2_lane_s8(a, b, 7);
-  // CHECK: st2 {v{{[0-9]+}}.b, v{{[0-9]+}}.b}[7], [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ *v[0-9]+.b, v[0-9]+.b *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-void test_vst2_lane_s16(int16_t const *a, int16x4x2_t b) {
+void test_vst2_lane_s16(int16_t  *a, int16x4x2_t b) {
   // CHECK-LABEL: test_vst2_lane_s16
   vst2_lane_s16(a, b, 3);
-  // CHECK: st2 {v{{[0-9]+}}.h, v{{[0-9]+}}.h}[3], [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ *v[0-9]+.h, v[0-9]+.h *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-void test_vst2_lane_s32(int32_t const *a, int32x2x2_t b) {
+void test_vst2_lane_s32(int32_t  *a, int32x2x2_t b) {
   // CHECK-LABEL: test_vst2_lane_s32
   vst2_lane_s32(a, b, 1);
-  // CHECK: st2 {v{{[0-9]+}}.s, v{{[0-9]+}}.s}[1], [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ *v[0-9]+.s, v[0-9]+.s *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-void test_vst2_lane_s64(int64_t const *a, int64x1x2_t b) {
+void test_vst2_lane_s64(int64_t  *a, int64x1x2_t b) {
   // CHECK-LABEL: test_vst2_lane_s64
   vst2_lane_s64(a, b, 0);
-  // CHECK: st2 {v{{[0-9]+}}.d, v{{[0-9]+}}.d}[0], [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ *v[0-9]+.d, v[0-9]+.d *}}}[0], [{{x[0-9]+|sp}}]
 }
 
-void test_vst2_lane_f16(float16_t const *a, float16x4x2_t b) {
+void test_vst2_lane_f16(float16_t  *a, float16x4x2_t b) {
   // CHECK-LABEL: test_vst2_lane_f16
   vst2_lane_f16(a, b, 3);
-  // CHECK: st2 {v{{[0-9]+}}.h, v{{[0-9]+}}.h}[3], [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ *v[0-9]+.h, v[0-9]+.h *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-void test_vst2_lane_f32(float32_t const *a, float32x2x2_t b) {
+void test_vst2_lane_f32(float32_t  *a, float32x2x2_t b) {
   // CHECK-LABEL: test_vst2_lane_f32
   vst2_lane_f32(a, b, 1);
-  // CHECK: st2 {v{{[0-9]+}}.s, v{{[0-9]+}}.s}[1], [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ *v[0-9]+.s, v[0-9]+.s *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-void test_vst2_lane_f64(float64_t const *a, float64x1x2_t b) {
+void test_vst2_lane_f64(float64_t  *a, float64x1x2_t b) {
   // CHECK-LABEL: test_vst2_lane_f64
   vst2_lane_f64(a, b, 0);
-  // CHECK: st2 {v{{[0-9]+}}.d, v{{[0-9]+}}.d}[0], [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ *v[0-9]+.d, v[0-9]+.d *}}}[0], [{{x[0-9]+|sp}}]
 }
 
-void test_vst2_lane_p8(poly8_t const *a, poly8x8x2_t b) {
+void test_vst2_lane_p8(poly8_t  *a, poly8x8x2_t b) {
   // CHECK-LABEL: test_vst2_lane_p8
   vst2_lane_p8(a, b, 7);
-  // CHECK: st2 {v{{[0-9]+}}.b, v{{[0-9]+}}.b}[7], [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ *v[0-9]+.b, v[0-9]+.b *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-void test_vst2_lane_p16(poly16_t const *a, poly16x4x2_t b) {
+void test_vst2_lane_p16(poly16_t  *a, poly16x4x2_t b) {
   // CHECK-LABEL: test_vst2_lane_p16
   vst2_lane_p16(a, b, 3);
-  // CHECK: st2 {v{{[0-9]+}}.h, v{{[0-9]+}}.h}[3], [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ *v[0-9]+.h, v[0-9]+.h *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-void test_vst2_lane_p64(poly64_t const *a, poly64x1x2_t b) {
+void test_vst2_lane_p64(poly64_t  *a, poly64x1x2_t b) {
   // CHECK-LABEL: test_vst2_lane_p64
   vst2_lane_p64(a, b, 0);
-  // CHECK: st2 {v{{[0-9]+}}.d, v{{[0-9]+}}.d}[0], [{{x[0-9]+|sp}}]
+  // CHECK: st2 {{{ *v[0-9]+.d, v[0-9]+.d *}}}[0], [{{x[0-9]+|sp}}]
 }
 
-void test_vst3q_lane_u8(uint8_t const *a, uint8x16x3_t b) {
+void test_vst3q_lane_u8(uint8_t  *a, uint8x16x3_t b) {
   // CHECK-LABEL: test_vst3q_lane_u8
   vst3q_lane_u8(a, b, 15);
-  // CHECK: st3 {v{{[0-9]+}}.b, v{{[0-9]+}}.b, v{{[0-9]+}}.b}[15], [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ *v[0-9]+.b, v[0-9]+.b, v[0-9]+.b *}}}[15], [{{x[0-9]+|sp}}]
 }
 
-void test_vst3q_lane_u16(uint16_t const *a, uint16x8x3_t b) {
+void test_vst3q_lane_u16(uint16_t  *a, uint16x8x3_t b) {
   // CHECK-LABEL: test_vst3q_lane_u16
   vst3q_lane_u16(a, b, 7);
-  // CHECK: st3 {v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h}[7], [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ *v[0-9]+.h, v[0-9]+.h, v[0-9]+.h *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-void test_vst3q_lane_u32(uint32_t const *a, uint32x4x3_t b) {
+void test_vst3q_lane_u32(uint32_t  *a, uint32x4x3_t b) {
   // CHECK-LABEL: test_vst3q_lane_u32
   vst3q_lane_u32(a, b, 3);
-  // CHECK: st3 {v{{[0-9]+}}.s, v{{[0-9]+}}.s, v{{[0-9]+}}.s}[3], [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ *v[0-9]+.s, v[0-9]+.s, v[0-9]+.s *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-void test_vst3q_lane_u64(uint64_t const *a, uint64x2x3_t b) {
+void test_vst3q_lane_u64(uint64_t  *a, uint64x2x3_t b) {
   // CHECK-LABEL: test_vst3q_lane_u64
   vst3q_lane_u64(a, b, 1);
-  // CHECK: st3 {v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d}[1], [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ *v[0-9]+.d, v[0-9]+.d, v[0-9]+.d *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-void test_vst3q_lane_s8(int8_t const *a, int8x16x3_t b) {
+void test_vst3q_lane_s8(int8_t  *a, int8x16x3_t b) {
   // CHECK-LABEL: test_vst3q_lane_s8
   vst3q_lane_s8(a, b, 15);
-  // CHECK: st3 {v{{[0-9]+}}.b, v{{[0-9]+}}.b, v{{[0-9]+}}.b}[15], [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ *v[0-9]+.b, v[0-9]+.b, v[0-9]+.b *}}}[15], [{{x[0-9]+|sp}}]
 }
 
-void test_vst3q_lane_s16(int16_t const *a, int16x8x3_t b) {
+void test_vst3q_lane_s16(int16_t  *a, int16x8x3_t b) {
   // CHECK-LABEL: test_vst3q_lane_s16
   vst3q_lane_s16(a, b, 7);
-  // CHECK: st3 {v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h}[7], [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ *v[0-9]+.h, v[0-9]+.h, v[0-9]+.h *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-void test_vst3q_lane_s32(int32_t const *a, int32x4x3_t b) {
+void test_vst3q_lane_s32(int32_t  *a, int32x4x3_t b) {
   // CHECK-LABEL: test_vst3q_lane_s32
   vst3q_lane_s32(a, b, 3);
-  // CHECK: st3 {v{{[0-9]+}}.s, v{{[0-9]+}}.s, v{{[0-9]+}}.s}[3], [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ *v[0-9]+.s, v[0-9]+.s, v[0-9]+.s *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-void test_vst3q_lane_s64(int64_t const *a, int64x2x3_t b) {
+void test_vst3q_lane_s64(int64_t  *a, int64x2x3_t b) {
   // CHECK-LABEL: test_vst3q_lane_s64
   vst3q_lane_s64(a, b, 1);
-  // CHECK: st3 {v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d}[1], [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ *v[0-9]+.d, v[0-9]+.d, v[0-9]+.d *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-void test_vst3q_lane_f16(float16_t const *a, float16x8x3_t b) {
+void test_vst3q_lane_f16(float16_t  *a, float16x8x3_t b) {
   // CHECK-LABEL: test_vst3q_lane_f16
   vst3q_lane_f16(a, b, 7);
-  // CHECK: st3 {v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h}[7], [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ *v[0-9]+.h, v[0-9]+.h, v[0-9]+.h *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-void test_vst3q_lane_f32(float32_t const *a, float32x4x3_t b) {
+void test_vst3q_lane_f32(float32_t  *a, float32x4x3_t b) {
   // CHECK-LABEL: test_vst3q_lane_f32
   vst3q_lane_f32(a, b, 3);
-  // CHECK: st3 {v{{[0-9]+}}.s, v{{[0-9]+}}.s, v{{[0-9]+}}.s}[3], [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ *v[0-9]+.s, v[0-9]+.s, v[0-9]+.s *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-void test_vst3q_lane_f64(float64_t const *a, float64x2x3_t b) {
+void test_vst3q_lane_f64(float64_t  *a, float64x2x3_t b) {
   // CHECK-LABEL: test_vst3q_lane_f64
   vst3q_lane_f64(a, b, 1);
-  // CHECK: st3 {v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d}[1], [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ *v[0-9]+.d, v[0-9]+.d, v[0-9]+.d *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-void test_vst3q_lane_p8(poly8_t const *a, poly8x16x3_t b) {
+void test_vst3q_lane_p8(poly8_t  *a, poly8x16x3_t b) {
   // CHECK-LABEL: test_vst3q_lane_p8
   vst3q_lane_p8(a, b, 15);
-  // CHECK: st3 {v{{[0-9]+}}.b, v{{[0-9]+}}.b, v{{[0-9]+}}.b}[15], [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ *v[0-9]+.b, v[0-9]+.b, v[0-9]+.b *}}}[15], [{{x[0-9]+|sp}}]
 }
 
-void test_vst3q_lane_p16(poly16_t const *a, poly16x8x3_t b) {
+void test_vst3q_lane_p16(poly16_t  *a, poly16x8x3_t b) {
   // CHECK-LABEL: test_vst3q_lane_p16
   vst3q_lane_p16(a, b, 7);
-  // CHECK: st3 {v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h}[7], [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ *v[0-9]+.h, v[0-9]+.h, v[0-9]+.h *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-void test_vst3q_lane_p64(poly64_t const *a, poly64x2x3_t b) {
+void test_vst3q_lane_p64(poly64_t  *a, poly64x2x3_t b) {
   // CHECK-LABEL: test_vst3q_lane_p64
   vst3q_lane_p64(a, b, 1);
-  // CHECK: st3 {v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d}[1], [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ *v[0-9]+.d, v[0-9]+.d, v[0-9]+.d *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-void test_vst3_lane_u8(uint8_t const *a, uint8x8x3_t b) {
+void test_vst3_lane_u8(uint8_t  *a, uint8x8x3_t b) {
   // CHECK-LABEL: test_vst3_lane_u8
   vst3_lane_u8(a, b, 7);
-  // CHECK: st3 {v{{[0-9]+}}.b, v{{[0-9]+}}.b, v{{[0-9]+}}.b}[7], [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ *v[0-9]+.b, v[0-9]+.b, v[0-9]+.b *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-void test_vst3_lane_u16(uint16_t const *a, uint16x4x3_t b) {
+void test_vst3_lane_u16(uint16_t  *a, uint16x4x3_t b) {
   // CHECK-LABEL: test_vst3_lane_u16
   vst3_lane_u16(a, b, 3);
-  // CHECK: st3 {v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h}[3], [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ *v[0-9]+.h, v[0-9]+.h, v[0-9]+.h *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-void test_vst3_lane_u32(uint32_t const *a, uint32x2x3_t b) {
+void test_vst3_lane_u32(uint32_t  *a, uint32x2x3_t b) {
   // CHECK-LABEL: test_vst3_lane_u32
   vst3_lane_u32(a, b, 1);
-  // CHECK: st3 {v{{[0-9]+}}.s, v{{[0-9]+}}.s, v{{[0-9]+}}.s}[1], [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ *v[0-9]+.s, v[0-9]+.s, v[0-9]+.s *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-void test_vst3_lane_u64(uint64_t const *a, uint64x1x3_t b) {
+void test_vst3_lane_u64(uint64_t  *a, uint64x1x3_t b) {
   // CHECK-LABEL: test_vst3_lane_u64
   vst3_lane_u64(a, b, 0);
-  // CHECK: st3 {v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d}[0], [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ *v[0-9]+.d, v[0-9]+.d, v[0-9]+.d *}}}[0], [{{x[0-9]+|sp}}]
 }
 
-void test_vst3_lane_s8(int8_t const *a, int8x8x3_t b) {
+void test_vst3_lane_s8(int8_t  *a, int8x8x3_t b) {
   // CHECK-LABEL: test_vst3_lane_s8
   vst3_lane_s8(a, b, 7);
-  // CHECK: st3 {v{{[0-9]+}}.b, v{{[0-9]+}}.b, v{{[0-9]+}}.b}[7], [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ *v[0-9]+.b, v[0-9]+.b, v[0-9]+.b *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-void test_vst3_lane_s16(int16_t const *a, int16x4x3_t b) {
+void test_vst3_lane_s16(int16_t  *a, int16x4x3_t b) {
   // CHECK-LABEL: test_vst3_lane_s16
   vst3_lane_s16(a, b, 3);
-  // CHECK: st3 {v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h}[3], [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ *v[0-9]+.h, v[0-9]+.h, v[0-9]+.h *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-void test_vst3_lane_s32(int32_t const *a, int32x2x3_t b) {
+void test_vst3_lane_s32(int32_t  *a, int32x2x3_t b) {
   // CHECK-LABEL: test_vst3_lane_s32
   vst3_lane_s32(a, b, 1);
-  // CHECK: st3 {v{{[0-9]+}}.s, v{{[0-9]+}}.s, v{{[0-9]+}}.s}[1], [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ *v[0-9]+.s, v[0-9]+.s, v[0-9]+.s *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-void test_vst3_lane_s64(int64_t const *a, int64x1x3_t b) {
+void test_vst3_lane_s64(int64_t  *a, int64x1x3_t b) {
   // CHECK-LABEL: test_vst3_lane_s64
   vst3_lane_s64(a, b, 0);
-  // CHECK: st3 {v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d}[0], [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ *v[0-9]+.d, v[0-9]+.d, v[0-9]+.d *}}}[0], [{{x[0-9]+|sp}}]
 }
 
-void test_vst3_lane_f16(float16_t const *a, float16x4x3_t b) {
+void test_vst3_lane_f16(float16_t  *a, float16x4x3_t b) {
   // CHECK-LABEL: test_vst3_lane_f16
   vst3_lane_f16(a, b, 3);
-  // CHECK: st3 {v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h}[3], [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ *v[0-9]+.h, v[0-9]+.h, v[0-9]+.h *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-void test_vst3_lane_f32(float32_t const *a, float32x2x3_t b) {
+void test_vst3_lane_f32(float32_t  *a, float32x2x3_t b) {
   // CHECK-LABEL: test_vst3_lane_f32
   vst3_lane_f32(a, b, 1);
-  // CHECK: st3 {v{{[0-9]+}}.s, v{{[0-9]+}}.s, v{{[0-9]+}}.s}[1], [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ *v[0-9]+.s, v[0-9]+.s, v[0-9]+.s *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-void test_vst3_lane_f64(float64_t const *a, float64x1x3_t b) {
+void test_vst3_lane_f64(float64_t  *a, float64x1x3_t b) {
   // CHECK-LABEL: test_vst3_lane_f64
   vst3_lane_f64(a, b, 0);
-  // CHECK: st3 {v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d}[0], [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ *v[0-9]+.d, v[0-9]+.d, v[0-9]+.d *}}}[0], [{{x[0-9]+|sp}}]
 }
 
-void test_vst3_lane_p8(poly8_t const *a, poly8x8x3_t b) {
+void test_vst3_lane_p8(poly8_t  *a, poly8x8x3_t b) {
   // CHECK-LABEL: test_vst3_lane_p8
   vst3_lane_p8(a, b, 7);
-  // CHECK: st3 {v{{[0-9]+}}.b, v{{[0-9]+}}.b, v{{[0-9]+}}.b}[7], [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ *v[0-9]+.b, v[0-9]+.b, v[0-9]+.b *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-void test_vst3_lane_p16(poly16_t const *a, poly16x4x3_t b) {
+void test_vst3_lane_p16(poly16_t  *a, poly16x4x3_t b) {
   // CHECK-LABEL: test_vst3_lane_p16
   vst3_lane_p16(a, b, 3);
-  // CHECK: st3 {v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h}[3], [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ *v[0-9]+.h, v[0-9]+.h, v[0-9]+.h *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-void test_vst3_lane_p64(poly64_t const *a, poly64x1x3_t b) {
+void test_vst3_lane_p64(poly64_t  *a, poly64x1x3_t b) {
   // CHECK-LABEL: test_vst3_lane_p64
   vst3_lane_p64(a, b, 0);
-  // CHECK: st3 {v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d}[0], [{{x[0-9]+|sp}}]
+  // CHECK: st3 {{{ *v[0-9]+.d, v[0-9]+.d, v[0-9]+.d *}}}[0], [{{x[0-9]+|sp}}]
 }
 
-void test_vst4q_lane_u8(uint16_t const *a, uint8x16x4_t b) {
+void test_vst4q_lane_u8(uint8_t  *a, uint8x16x4_t b) {
   // CHECK-LABEL: test_vst4q_lane_u8
   vst4q_lane_u8(a, b, 15);
-  // CHECK: st4 {v{{[0-9]+}}.b, v{{[0-9]+}}.b, v{{[0-9]+}}.b, v{{[0-9]+}}.b}[15], [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ *v[0-9]+.b, v[0-9]+.b, v[0-9]+.b, v[0-9]+.b *}}}[15], [{{x[0-9]+|sp}}]
 }
 
-void test_vst4q_lane_u16(uint16_t const *a, uint16x8x4_t b) {
+void test_vst4q_lane_u16(uint16_t  *a, uint16x8x4_t b) {
   // CHECK-LABEL: test_vst4q_lane_u16
   vst4q_lane_u16(a, b, 7);
-  // CHECK: st4 {v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h}[7], [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ *v[0-9]+.h, v[0-9]+.h, v[0-9]+.h, v[0-9]+.h *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-void test_vst4q_lane_u32(uint32_t const *a, uint32x4x4_t b) {
+void test_vst4q_lane_u32(uint32_t  *a, uint32x4x4_t b) {
   // CHECK-LABEL: test_vst4q_lane_u32
   vst4q_lane_u32(a, b, 3);
-  // CHECK: st4 {v{{[0-9]+}}.s, v{{[0-9]+}}.s, v{{[0-9]+}}.s, v{{[0-9]+}}.s}[3], [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ *v[0-9]+.s, v[0-9]+.s, v[0-9]+.s, v[0-9]+.s *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-void test_vst4q_lane_u64(uint64_t const *a, uint64x2x4_t b) {
+void test_vst4q_lane_u64(uint64_t  *a, uint64x2x4_t b) {
   // CHECK-LABEL: test_vst4q_lane_u64
   vst4q_lane_u64(a, b, 1);
-  // CHECK: st4 {v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d}[1], [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ *v[0-9]+.d, v[0-9]+.d, v[0-9]+.d, v[0-9]+.d *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-void test_vst4q_lane_s8(int16_t const *a, int8x16x4_t b) {
+void test_vst4q_lane_s8(int8_t  *a, int8x16x4_t b) {
   // CHECK-LABEL: test_vst4q_lane_s8
   vst4q_lane_s8(a, b, 15);
-  // CHECK: st4 {v{{[0-9]+}}.b, v{{[0-9]+}}.b, v{{[0-9]+}}.b, v{{[0-9]+}}.b}[15], [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ *v[0-9]+.b, v[0-9]+.b, v[0-9]+.b, v[0-9]+.b *}}}[15], [{{x[0-9]+|sp}}]
 }
 
-void test_vst4q_lane_s16(int16_t const *a, int16x8x4_t b) {
+void test_vst4q_lane_s16(int16_t  *a, int16x8x4_t b) {
   // CHECK-LABEL: test_vst4q_lane_s16
   vst4q_lane_s16(a, b, 7);
-  // CHECK: st4 {v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h}[7], [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ *v[0-9]+.h, v[0-9]+.h, v[0-9]+.h, v[0-9]+.h *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-void test_vst4q_lane_s32(int32_t const *a, int32x4x4_t b) {
+void test_vst4q_lane_s32(int32_t  *a, int32x4x4_t b) {
   // CHECK-LABEL: test_vst4q_lane_s32
   vst4q_lane_s32(a, b, 3);
-  // CHECK: st4 {v{{[0-9]+}}.s, v{{[0-9]+}}.s, v{{[0-9]+}}.s, v{{[0-9]+}}.s}[3], [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ *v[0-9]+.s, v[0-9]+.s, v[0-9]+.s, v[0-9]+.s *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-void test_vst4q_lane_s64(int64_t const *a, int64x2x4_t b) {
+void test_vst4q_lane_s64(int64_t  *a, int64x2x4_t b) {
   // CHECK-LABEL: test_vst4q_lane_s64
   vst4q_lane_s64(a, b, 1);
-  // CHECK: st4 {v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d}[1], [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ *v[0-9]+.d, v[0-9]+.d, v[0-9]+.d, v[0-9]+.d *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-void test_vst4q_lane_f16(float16_t const *a, float16x8x4_t b) {
+void test_vst4q_lane_f16(float16_t  *a, float16x8x4_t b) {
   // CHECK-LABEL: test_vst4q_lane_f16
   vst4q_lane_f16(a, b, 7);
-  // CHECK: st4 {v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h}[7], [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ *v[0-9]+.h, v[0-9]+.h, v[0-9]+.h, v[0-9]+.h *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-void test_vst4q_lane_f32(float32_t const *a, float32x4x4_t b) {
+void test_vst4q_lane_f32(float32_t  *a, float32x4x4_t b) {
   // CHECK-LABEL: test_vst4q_lane_f32
   vst4q_lane_f32(a, b, 3);
-  // CHECK: st4 {v{{[0-9]+}}.s, v{{[0-9]+}}.s, v{{[0-9]+}}.s, v{{[0-9]+}}.s}[3], [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ *v[0-9]+.s, v[0-9]+.s, v[0-9]+.s, v[0-9]+.s *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-void test_vst4q_lane_f64(float64_t const *a, float64x2x4_t b) {
+void test_vst4q_lane_f64(float64_t  *a, float64x2x4_t b) {
   // CHECK-LABEL: test_vst4q_lane_f64
   vst4q_lane_f64(a, b, 1);
-  // CHECK: st4 {v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d}[1], [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ *v[0-9]+.d, v[0-9]+.d, v[0-9]+.d, v[0-9]+.d *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-void test_vst4q_lane_p8(poly16_t const *a, poly8x16x4_t b) {
+void test_vst4q_lane_p8(poly8_t  *a, poly8x16x4_t b) {
   // CHECK-LABEL: test_vst4q_lane_p8
   vst4q_lane_p8(a, b, 15);
-  // CHECK: st4 {v{{[0-9]+}}.b, v{{[0-9]+}}.b, v{{[0-9]+}}.b, v{{[0-9]+}}.b}[15], [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ *v[0-9]+.b, v[0-9]+.b, v[0-9]+.b, v[0-9]+.b *}}}[15], [{{x[0-9]+|sp}}]
 }
 
-void test_vst4q_lane_p16(poly16_t const *a, poly16x8x4_t b) {
+void test_vst4q_lane_p16(poly16_t  *a, poly16x8x4_t b) {
   // CHECK-LABEL: test_vst4q_lane_p16
   vst4q_lane_p16(a, b, 7);
-  // CHECK: st4 {v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h}[7], [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ *v[0-9]+.h, v[0-9]+.h, v[0-9]+.h, v[0-9]+.h *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-void test_vst4q_lane_p64(poly64_t const *a, poly64x2x4_t b) {
+void test_vst4q_lane_p64(poly64_t  *a, poly64x2x4_t b) {
   // CHECK-LABEL: test_vst4q_lane_p64
   vst4q_lane_p64(a, b, 1);
-  // CHECK: st4 {v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d}[1], [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ *v[0-9]+.d, v[0-9]+.d, v[0-9]+.d, v[0-9]+.d *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-void test_vst4_lane_u8(uint8_t const *a, uint8x8x4_t b) {
+void test_vst4_lane_u8(uint8_t  *a, uint8x8x4_t b) {
   // CHECK-LABEL: test_vst4_lane_u8
   vst4_lane_u8(a, b, 7);
-  // CHECK: st4 {v{{[0-9]+}}.b, v{{[0-9]+}}.b, v{{[0-9]+}}.b, v{{[0-9]+}}.b}[7], [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ *v[0-9]+.b, v[0-9]+.b, v[0-9]+.b, v[0-9]+.b *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-void test_vst4_lane_u16(uint16_t const *a, uint16x4x4_t b) {
+void test_vst4_lane_u16(uint16_t  *a, uint16x4x4_t b) {
   // CHECK-LABEL: test_vst4_lane_u16
   vst4_lane_u16(a, b, 3);
-  // CHECK: st4 {v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h}[3], [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ *v[0-9]+.h, v[0-9]+.h, v[0-9]+.h, v[0-9]+.h *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-void test_vst4_lane_u32(uint32_t const *a, uint32x2x4_t b) {
+void test_vst4_lane_u32(uint32_t  *a, uint32x2x4_t b) {
   // CHECK-LABEL: test_vst4_lane_u32
   vst4_lane_u32(a, b, 1);
-  // CHECK: st4 {v{{[0-9]+}}.s, v{{[0-9]+}}.s, v{{[0-9]+}}.s, v{{[0-9]+}}.s}[1], [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ *v[0-9]+.s, v[0-9]+.s, v[0-9]+.s, v[0-9]+.s *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-void test_vst4_lane_u64(uint64_t const *a, uint64x1x4_t b) {
+void test_vst4_lane_u64(uint64_t  *a, uint64x1x4_t b) {
   // CHECK-LABEL: test_vst4_lane_u64
   vst4_lane_u64(a, b, 0);
-  // CHECK: st4 {v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d}[0], [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ *v[0-9]+.d, v[0-9]+.d, v[0-9]+.d, v[0-9]+.d *}}}[0], [{{x[0-9]+|sp}}]
 }
 
-void test_vst4_lane_s8(int8_t const *a, int8x8x4_t b) {
+void test_vst4_lane_s8(int8_t  *a, int8x8x4_t b) {
   // CHECK-LABEL: test_vst4_lane_s8
   vst4_lane_s8(a, b, 7);
-  // CHECK: st4 {v{{[0-9]+}}.b, v{{[0-9]+}}.b, v{{[0-9]+}}.b, v{{[0-9]+}}.b}[7], [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ *v[0-9]+.b, v[0-9]+.b, v[0-9]+.b, v[0-9]+.b *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-void test_vst4_lane_s16(int16_t const *a, int16x4x4_t b) {
+void test_vst4_lane_s16(int16_t  *a, int16x4x4_t b) {
   // CHECK-LABEL: test_vst4_lane_s16
   vst4_lane_s16(a, b, 3);
-  // CHECK: st4 {v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h}[3], [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ *v[0-9]+.h, v[0-9]+.h, v[0-9]+.h, v[0-9]+.h *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-void test_vst4_lane_s32(int32_t const *a, int32x2x4_t b) {
+void test_vst4_lane_s32(int32_t  *a, int32x2x4_t b) {
   // CHECK-LABEL: test_vst4_lane_s32
   vst4_lane_s32(a, b, 1);
-  // CHECK: st4 {v{{[0-9]+}}.s, v{{[0-9]+}}.s, v{{[0-9]+}}.s, v{{[0-9]+}}.s}[1], [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ *v[0-9]+.s, v[0-9]+.s, v[0-9]+.s, v[0-9]+.s *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-void test_vst4_lane_s64(int64_t const *a, int64x1x4_t b) {
+void test_vst4_lane_s64(int64_t  *a, int64x1x4_t b) {
   // CHECK-LABEL: test_vst4_lane_s64
   vst4_lane_s64(a, b, 0);
-  // CHECK: st4 {v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d}[0], [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ *v[0-9]+.d, v[0-9]+.d, v[0-9]+.d, v[0-9]+.d *}}}[0], [{{x[0-9]+|sp}}]
 }
 
-void test_vst4_lane_f16(float16_t const *a, float16x4x4_t b) {
+void test_vst4_lane_f16(float16_t  *a, float16x4x4_t b) {
   // CHECK-LABEL: test_vst4_lane_f16
   vst4_lane_f16(a, b, 3);
-  // CHECK: st4 {v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h}[3], [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ *v[0-9]+.h, v[0-9]+.h, v[0-9]+.h, v[0-9]+.h *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-void test_vst4_lane_f32(float32_t const *a, float32x2x4_t b) {
+void test_vst4_lane_f32(float32_t  *a, float32x2x4_t b) {
   // CHECK-LABEL: test_vst4_lane_f32
   vst4_lane_f32(a, b, 1);
-  // CHECK: st4 {v{{[0-9]+}}.s, v{{[0-9]+}}.s, v{{[0-9]+}}.s, v{{[0-9]+}}.s}[1], [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ *v[0-9]+.s, v[0-9]+.s, v[0-9]+.s, v[0-9]+.s *}}}[1], [{{x[0-9]+|sp}}]
 }
 
-void test_vst4_lane_f64(float64_t const *a, float64x1x4_t b) {
+void test_vst4_lane_f64(float64_t  *a, float64x1x4_t b) {
   // CHECK-LABEL: test_vst4_lane_f64
   vst4_lane_f64(a, b, 0);
-  // CHECK: st4 {v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d}[0], [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ *v[0-9]+.d, v[0-9]+.d, v[0-9]+.d, v[0-9]+.d *}}}[0], [{{x[0-9]+|sp}}]
 }
 
-void test_vst4_lane_p8(poly8_t const *a, poly8x8x4_t b) {
+void test_vst4_lane_p8(poly8_t  *a, poly8x8x4_t b) {
   // CHECK-LABEL: test_vst4_lane_p8
   vst4_lane_p8(a, b, 7);
-  // CHECK: st4 {v{{[0-9]+}}.b, v{{[0-9]+}}.b, v{{[0-9]+}}.b, v{{[0-9]+}}.b}[7], [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ *v[0-9]+.b, v[0-9]+.b, v[0-9]+.b, v[0-9]+.b *}}}[7], [{{x[0-9]+|sp}}]
 }
 
-void test_vst4_lane_p16(poly16_t const *a, poly16x4x4_t b) {
+void test_vst4_lane_p16(poly16_t  *a, poly16x4x4_t b) {
   // CHECK-LABEL: test_vst4_lane_p16
   vst4_lane_p16(a, b, 3);
-  // CHECK: st4 {v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h, v{{[0-9]+}}.h}[3], [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ *v[0-9]+.h, v[0-9]+.h, v[0-9]+.h, v[0-9]+.h *}}}[3], [{{x[0-9]+|sp}}]
 }
 
-void test_vst4_lane_p64(poly64_t const *a, poly64x1x4_t b) {
+void test_vst4_lane_p64(poly64_t  *a, poly64x1x4_t b) {
   // CHECK-LABEL: test_vst4_lane_p64
   vst4_lane_p64(a, b, 0);
-  // CHECK: st4 {v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d, v{{[0-9]+}}.d}[0], [{{x[0-9]+|sp}}]
+  // CHECK: st4 {{{ *v[0-9]+.d, v[0-9]+.d, v[0-9]+.d, v[0-9]+.d *}}}[0], [{{x[0-9]+|sp}}]
 }
diff --git a/test/CodeGen/aarch64-neon-misc.c b/test/CodeGen/aarch64-neon-misc.c
index 8c2476b..a251197 100644
--- a/test/CodeGen/aarch64-neon-misc.c
+++ b/test/CodeGen/aarch64-neon-misc.c
@@ -1,1951 +1,2041 @@
 // REQUIRES: aarch64-registered-target
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +neon \
+// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \
 // RUN:   -ffp-contract=fast -S -O3 -o - %s | FileCheck %s
 
 // Test new aarch64 intrinsics and types
 
 #include <arm_neon.h>
 
-// CHECK: test_vceqz_s8
-// CHECK: cmeq  {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #0x0
+// CHECK-LABEL: test_vceqz_s8
+// CHECK: cmeq  {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #{{0x0|0}}
 uint8x8_t test_vceqz_s8(int8x8_t a) {
   return vceqz_s8(a);
 }
 
-// CHECK: test_vceqz_s16
-// CHECK: cmeq  {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, #0x0
+// CHECK-LABEL: test_vceqz_s16
+// CHECK: cmeq  {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, #{{0x0|0}}
 uint16x4_t test_vceqz_s16(int16x4_t a) {
   return vceqz_s16(a);
 }
 
-// CHECK: test_vceqz_s32
-// CHECK: cmeq  {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #0x0
+// CHECK-LABEL: test_vceqz_s32
+// CHECK: cmeq  {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #{{0x0|0}}
 uint32x2_t test_vceqz_s32(int32x2_t a) {
   return vceqz_s32(a);
 }
 
-// CHECK: test_vceqzq_s8
-// CHECK: cmeq  {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #0x0
+// CHECK-LABEL: test_vceqz_s64
+// CHECK: cmeq {{d[0-9]+}}, {{d[0-9]+}}, #{{0x0|0}}
+uint64x1_t test_vceqz_s64(int64x1_t a) {
+  return vceqz_s64(a);
+}
+
+// CHECK-LABEL: test_vceqz_u64
+// CHECK: cmeq {{d[0-9]+}}, {{d[0-9]+}}, #{{0x0|0}}
+uint64x1_t test_vceqz_u64(uint64x1_t a) {
+  return vceqz_u64(a);
+}
+
+// CHECK-LABEL: test_vceqz_p64
+// CHECK: cmeq {{d[0-9]+}}, {{d[0-9]+}}, #{{0x0|0}}
+uint64x1_t test_vceqz_p64(poly64x1_t a) {
+  return vceqz_p64(a);
+}
+
+// CHECK-LABEL: test_vceqzq_s8
+// CHECK: cmeq  {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #{{0x0|0}}
 uint8x16_t test_vceqzq_s8(int8x16_t a) {
   return vceqzq_s8(a);
 }
 
-// CHECK: test_vceqzq_s16
-// CHECK: cmeq  {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, #0x0
+// CHECK-LABEL: test_vceqzq_s16
+// CHECK: cmeq  {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, #{{0x0|0}}
 uint16x8_t test_vceqzq_s16(int16x8_t a) {
   return vceqzq_s16(a);
 }
 
-// CHECK: test_vceqzq_s32
-// CHECK: cmeq  {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #0x0
+// CHECK-LABEL: test_vceqzq_s32
+// CHECK: cmeq  {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #{{0x0|0}}
 uint32x4_t test_vceqzq_s32(int32x4_t a) {
   return vceqzq_s32(a);
 }
 
-// CHECK: test_vceqzq_s64
-// CHECK: cmeq  {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #0x0
+// CHECK-LABEL: test_vceqzq_s64
+// CHECK: cmeq  {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #{{0x0|0}}
 uint64x2_t test_vceqzq_s64(int64x2_t a) {
   return vceqzq_s64(a);
 }
 
-// CHECK: test_vceqz_u8
-// CHECK: cmeq  {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #0x0
+// CHECK-LABEL: test_vceqz_u8
+// CHECK: cmeq  {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #{{0x0|0}}
 uint8x8_t test_vceqz_u8(uint8x8_t a) {
   return vceqz_u8(a);
 }
 
-// CHECK: test_vceqz_u16
-// CHECK: cmeq  {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, #0x0
+// CHECK-LABEL: test_vceqz_u16
+// CHECK: cmeq  {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, #{{0x0|0}}
 uint16x4_t test_vceqz_u16(uint16x4_t a) {
   return vceqz_u16(a);
 }
 
-// CHECK: test_vceqz_u32
-// CHECK: cmeq  {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #0x0
+// CHECK-LABEL: test_vceqz_u32
+// CHECK: cmeq  {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #{{0x0|0}}
 uint32x2_t test_vceqz_u32(uint32x2_t a) {
   return vceqz_u32(a);
 }
 
-// CHECK: test_vceqzq_u8
-// CHECK: cmeq  {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #0x0
+// CHECK-LABEL: test_vceqzq_u8
+// CHECK: cmeq  {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #{{0x0|0}}
 uint8x16_t test_vceqzq_u8(uint8x16_t a) {
   return vceqzq_u8(a);
 }
 
-// CHECK: test_vceqzq_u16
-// CHECK: cmeq  {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, #0x0
+// CHECK-LABEL: test_vceqzq_u16
+// CHECK: cmeq  {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, #{{0x0|0}}
 uint16x8_t test_vceqzq_u16(uint16x8_t a) {
   return vceqzq_u16(a);
 }
 
-// CHECK: test_vceqzq_u32
-// CHECK: cmeq  {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #0x0
+// CHECK-LABEL: test_vceqzq_u32
+// CHECK: cmeq  {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #{{0x0|0}}
 uint32x4_t test_vceqzq_u32(uint32x4_t a) {
   return vceqzq_u32(a);
 }
 
-// CHECK: test_vceqzq_u64
-// CHECK: cmeq  {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #0x0
+// CHECK-LABEL: test_vceqzq_u64
+// CHECK: cmeq  {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #{{0x0|0}}
 uint64x2_t test_vceqzq_u64(uint64x2_t a) {
   return vceqzq_u64(a);
 }
 
-// CHECK: test_vceqz_f32
+// CHECK-LABEL: test_vceqz_f32
 // CHECK: fcmeq  {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #0
 uint32x2_t test_vceqz_f32(float32x2_t a) {
   return vceqz_f32(a);
 }
 
-// CHECK: test_vceqzq_f32
+// CHECK-LABEL: test_vceqz_f64
+// CHECK: fcmeq  {{d[0-9]+}}, {{d[0-9]+}}, #0
+uint64x1_t test_vceqz_f64(float64x1_t a) {
+  return vceqz_f64(a);
+}
+
+// CHECK-LABEL: test_vceqzq_f32
 // CHECK: fcmeq  {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #0
 uint32x4_t test_vceqzq_f32(float32x4_t a) {
   return vceqzq_f32(a);
 }
 
-// CHECK: test_vceqz_p16
-// CHECK: cmeq  {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, #0x0
+// CHECK-LABEL: test_vceqz_p8
+// CHECK: cmeq  {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #{{0x0|0}}
+uint8x8_t test_vceqz_p8(poly8x8_t a) {
+  return vceqz_p8(a);
+}
+
+// CHECK-LABEL: test_vceqzq_p8
+// CHECK: cmeq  {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #{{0x0|0}}
+uint8x16_t test_vceqzq_p8(poly8x16_t a) {
+  return vceqzq_p8(a);
+}
+
+// CHECK-LABEL: test_vceqz_p16
+// CHECK: cmeq  {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, #{{0x0|0}}
 uint16x4_t test_vceqz_p16(poly16x4_t a) {
   return vceqz_p16(a);
 }
 
-// CHECK: test_vceqzq_p16
-// CHECK: cmeq  {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, #0x0
+// CHECK-LABEL: test_vceqzq_p16
+// CHECK: cmeq  {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, #{{0x0|0}}
 uint16x8_t test_vceqzq_p16(poly16x8_t a) {
   return vceqzq_p16(a);
 }
 
-// CHECK: test_vceqzq_f64
+// CHECK-LABEL: test_vceqzq_f64
 // CHECK: fcmeq  {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #0
 uint64x2_t test_vceqzq_f64(float64x2_t a) {
   return vceqzq_f64(a);
 }
 
-// CHECK: test_vcgez_s8
-// CHECK: cmge  {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #0x0
+// CHECK-LABEL: test_vceqzq_p64
+// CHECK: cmeq  {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #0
+uint64x2_t test_vceqzq_p64(poly64x2_t a) {
+  return vceqzq_p64(a);
+}
+
+// CHECK-LABEL: test_vcgez_s8
+// CHECK: cmge  {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #{{0x0|0}}
 uint8x8_t test_vcgez_s8(int8x8_t a) {
   return vcgez_s8(a);
 }
 
-// CHECK: test_vcgez_s16
-// CHECK: cmge  {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, #0x0
+// CHECK-LABEL: test_vcgez_s16
+// CHECK: cmge  {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, #{{0x0|0}}
 uint16x4_t test_vcgez_s16(int16x4_t a) {
   return vcgez_s16(a);
 }
 
-// CHECK: test_vcgez_s32
-// CHECK: cmge  {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #0x0
+// CHECK-LABEL: test_vcgez_s32
+// CHECK: cmge  {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #{{0x0|0}}
 uint32x2_t test_vcgez_s32(int32x2_t a) {
   return vcgez_s32(a);
 }
 
-// CHECK: test_vcgezq_s8
-// CHECK: cmge  {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #0x0
+// CHECK-LABEL: test_vcgez_s64
+// CHECK: cmge {{d[0-9]+}}, {{d[0-9]+}}, #{{0x0|0}}
+uint64x1_t test_vcgez_s64(int64x1_t a) {
+  return vcgez_s64(a);
+}
+
+// CHECK-LABEL: test_vcgezq_s8
+// CHECK: cmge  {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #{{0x0|0}}
 uint8x16_t test_vcgezq_s8(int8x16_t a) {
   return vcgezq_s8(a);
 }
 
-// CHECK: test_vcgezq_s16
-// CHECK: cmge  {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, #0x0
+// CHECK-LABEL: test_vcgezq_s16
+// CHECK: cmge  {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, #{{0x0|0}}
 uint16x8_t test_vcgezq_s16(int16x8_t a) {
   return vcgezq_s16(a);
 }
 
-// CHECK: test_vcgezq_s32
-// CHECK: cmge  {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #0x0
+// CHECK-LABEL: test_vcgezq_s32
+// CHECK: cmge  {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #{{0x0|0}}
 uint32x4_t test_vcgezq_s32(int32x4_t a) {
   return vcgezq_s32(a);
 }
 
-// CHECK: test_vcgezq_s64
-// CHECK: cmge  {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #0x0
+// CHECK-LABEL: test_vcgezq_s64
+// CHECK: cmge  {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #{{0x0|0}}
 uint64x2_t test_vcgezq_s64(int64x2_t a) {
   return vcgezq_s64(a);
 }
 
-// CHECK: test_vcgez_f32
+// CHECK-LABEL: test_vcgez_f32
 // CHECK: fcmge  {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #0
 uint32x2_t test_vcgez_f32(float32x2_t a) {
   return vcgez_f32(a);
 }
 
-// CHECK: test_vcgezq_f32
+// CHECK-LABEL: test_vcgez_f64
+// CHECK: fcmge  {{d[0-9]+}}, {{d[0-9]+}}, #0
+uint64x1_t test_vcgez_f64(float64x1_t a) {
+  return vcgez_f64(a);
+}
+
+// CHECK-LABEL: test_vcgezq_f32
 // CHECK: fcmge  {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #0
 uint32x4_t test_vcgezq_f32(float32x4_t a) {
   return vcgezq_f32(a);
 }
 
-// CHECK: test_vcgezq_f64
+// CHECK-LABEL: test_vcgezq_f64
 // CHECK: fcmge  {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #0
 uint64x2_t test_vcgezq_f64(float64x2_t a) {
   return vcgezq_f64(a);
 }
 
-// CHECK: test_vclez_s8
-// CHECK: cmle  {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #0x0
+// CHECK-LABEL: test_vclez_s8
+// CHECK: cmle  {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #{{0x0|0}}
 uint8x8_t test_vclez_s8(int8x8_t a) {
   return vclez_s8(a);
 }
 
-// CHECK: test_vclez_s16
-// CHECK: cmle  {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, #0x0
+// CHECK-LABEL: test_vclez_s16
+// CHECK: cmle  {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, #{{0x0|0}}
 uint16x4_t test_vclez_s16(int16x4_t a) {
   return vclez_s16(a);
 }
 
-// CHECK: test_vclez_s32
-// CHECK: cmle  {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #0x0
+// CHECK-LABEL: test_vclez_s32
+// CHECK: cmle  {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #{{0x0|0}}
 uint32x2_t test_vclez_s32(int32x2_t a) {
   return vclez_s32(a);
 }
 
-// CHECK: test_vclezq_s8
-// CHECK: cmle  {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #0x0
+// CHECK-LABEL: test_vclez_s64
+// CHECK: cmle {{d[0-9]+}}, {{d[0-9]+}}, #{{0x0|0}}
+uint64x1_t test_vclez_s64(int64x1_t a) {
+  return vclez_s64(a);
+}
+
+// CHECK-LABEL: test_vclezq_s8
+// CHECK: cmle  {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #{{0x0|0}}
 uint8x16_t test_vclezq_s8(int8x16_t a) {
   return vclezq_s8(a);
 }
 
-// CHECK: test_vclezq_s16
-// CHECK: cmle  {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, #0x0
+// CHECK-LABEL: test_vclezq_s16
+// CHECK: cmle  {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, #{{0x0|0}}
 uint16x8_t test_vclezq_s16(int16x8_t a) {
   return vclezq_s16(a);
 }
 
-// CHECK: test_vclezq_s32
-// CHECK: cmle  {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #0x0
+// CHECK-LABEL: test_vclezq_s32
+// CHECK: cmle  {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #{{0x0|0}}
 uint32x4_t test_vclezq_s32(int32x4_t a) {
   return vclezq_s32(a);
 }
 
-// CHECK: test_vclezq_s64
-// CHECK: cmle  {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #0x0
+// CHECK-LABEL: test_vclezq_s64
+// CHECK: cmle  {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #{{0x0|0}}
 uint64x2_t test_vclezq_s64(int64x2_t a) {
   return vclezq_s64(a);
 }
 
-// CHECK: test_vclez_f32
+// CHECK-LABEL: test_vclez_f32
 // CHECK: fcmle  {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #0
 uint32x2_t test_vclez_f32(float32x2_t a) {
   return vclez_f32(a);
 }
 
-// CHECK: test_vclezq_f32
+// CHECK-LABEL: test_vclez_f64
+// CHECK: fcmle  {{d[0-9]+}}, {{d[0-9]+}}, #0
+uint64x1_t test_vclez_f64(float64x1_t a) {
+  return vclez_f64(a);
+}
+
+// CHECK-LABEL: test_vclezq_f32
 // CHECK: fcmle  {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #0
 uint32x4_t test_vclezq_f32(float32x4_t a) {
   return vclezq_f32(a);
 }
 
-// CHECK: test_vclezq_f64
+// CHECK-LABEL: test_vclezq_f64
 // CHECK: fcmle  {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #0
 uint64x2_t test_vclezq_f64(float64x2_t a) {
   return vclezq_f64(a);
 }
 
-// CHECK: test_vcgtz_s8
-// CHECK: cmgt  {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #0x0
+// CHECK-LABEL: test_vcgtz_s8
+// CHECK: cmgt  {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #{{0x0|0}}
 uint8x8_t test_vcgtz_s8(int8x8_t a) {
   return vcgtz_s8(a);
 }
 
-// CHECK: test_vcgtz_s16
-// CHECK: cmgt  {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, #0x0
+// CHECK-LABEL: test_vcgtz_s16
+// CHECK: cmgt  {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, #{{0x0|0}}
 uint16x4_t test_vcgtz_s16(int16x4_t a) {
   return vcgtz_s16(a);
 }
 
-// CHECK: test_vcgtz_s32
-// CHECK: cmgt  {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #0x0
+// CHECK-LABEL: test_vcgtz_s32
+// CHECK: cmgt  {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #{{0x0|0}}
 uint32x2_t test_vcgtz_s32(int32x2_t a) {
   return vcgtz_s32(a);
 }
 
-// CHECK: test_vcgtzq_s8
-// CHECK: cmgt  {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #0x0
+// CHECK-LABEL: test_vcgtz_s64
+// CHECK: cmgt {{d[0-9]+}}, {{d[0-9]+}}, #{{0x0|0}}
+uint64x1_t test_vcgtz_s64(int64x1_t a) {
+  return vcgtz_s64(a);
+}
+
+// CHECK-LABEL: test_vcgtzq_s8
+// CHECK: cmgt  {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #{{0x0|0}}
 uint8x16_t test_vcgtzq_s8(int8x16_t a) {
   return vcgtzq_s8(a);
 }
 
-// CHECK: test_vcgtzq_s16
-// CHECK: cmgt  {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, #0x0
+// CHECK-LABEL: test_vcgtzq_s16
+// CHECK: cmgt  {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, #{{0x0|0}}
 uint16x8_t test_vcgtzq_s16(int16x8_t a) {
   return vcgtzq_s16(a);
 }
 
-// CHECK: test_vcgtzq_s32
-// CHECK: cmgt  {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #0x0
+// CHECK-LABEL: test_vcgtzq_s32
+// CHECK: cmgt  {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #{{0x0|0}}
 uint32x4_t test_vcgtzq_s32(int32x4_t a) {
   return vcgtzq_s32(a);
 }
 
-// CHECK: test_vcgtzq_s64
-// CHECK: cmgt  {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #0x0
+// CHECK-LABEL: test_vcgtzq_s64
+// CHECK: cmgt  {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #{{0x0|0}}
 uint64x2_t test_vcgtzq_s64(int64x2_t a) {
   return vcgtzq_s64(a);
 }
 
-// CHECK: test_vcgtz_f32
+// CHECK-LABEL: test_vcgtz_f32
 // CHECK: fcmgt  {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #0
 uint32x2_t test_vcgtz_f32(float32x2_t a) {
   return vcgtz_f32(a);
 }
 
-// CHECK: test_vcgtzq_f32
+// CHECK-LABEL: test_vcgtz_f64
+// CHECK: fcmgt  {{d[0-9]+}}, {{d[0-9]+}}, #0
+uint64x1_t test_vcgtz_f64(float64x1_t a) {
+  return vcgtz_f64(a);
+}
+
+// CHECK-LABEL: test_vcgtzq_f32
 // CHECK: fcmgt  {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #0
 uint32x4_t test_vcgtzq_f32(float32x4_t a) {
   return vcgtzq_f32(a);
 }
 
-// CHECK: test_vcgtzq_f64
+// CHECK-LABEL: test_vcgtzq_f64
 // CHECK: fcmgt  {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #0
 uint64x2_t test_vcgtzq_f64(float64x2_t a) {
   return vcgtzq_f64(a);
 }
 
-// CHECK: test_vcltz_s8
-// CHECK: cmlt  {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #0
+// CHECK-LABEL: test_vcltz_s8
+// CHECK: sshr  {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, #7
 uint8x8_t test_vcltz_s8(int8x8_t a) {
   return vcltz_s8(a);
 }
 
-// CHECK: test_vcltz_s16
-// CHECK: cmlt  {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, #0
+// CHECK-LABEL: test_vcltz_s16
+// CHECK: sshr  {{v[0-9]+}}.4h, {{v[0-9]+}}.4h, #15
 uint16x4_t test_vcltz_s16(int16x4_t a) {
   return vcltz_s16(a);
 }
 
-// CHECK: test_vcltz_s32
-// CHECK: cmlt  {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #0
+// CHECK-LABEL: test_vcltz_s32
+// CHECK: sshr  {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #31
 uint32x2_t test_vcltz_s32(int32x2_t a) {
   return vcltz_s32(a);
 }
 
-// CHECK: test_vcltzq_s8
-// CHECK: cmlt  {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #0
+// CHECK-LABEL: test_vcltz_s64
+// CHECK: sshr {{d[0-9]+}}, {{d[0-9]+}}, #63
+uint64x1_t test_vcltz_s64(int64x1_t a) {
+  return vcltz_s64(a);
+}
+
+// CHECK-LABEL: test_vcltzq_s8
+// CHECK: sshr  {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #7
 uint8x16_t test_vcltzq_s8(int8x16_t a) {
   return vcltzq_s8(a);
 }
 
-// CHECK: test_vcltzq_s16
-// CHECK: cmlt  {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, #0
+// CHECK-LABEL: test_vcltzq_s16
+// CHECK: sshr  {{v[0-9]+}}.8h, {{v[0-9]+}}.8h, #15
 uint16x8_t test_vcltzq_s16(int16x8_t a) {
   return vcltzq_s16(a);
 }
 
-// CHECK: test_vcltzq_s32
-// CHECK: cmlt  {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #0
+// CHECK-LABEL: test_vcltzq_s32
+// CHECK: sshr  {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #31
 uint32x4_t test_vcltzq_s32(int32x4_t a) {
   return vcltzq_s32(a);
 }
 
-// CHECK: test_vcltzq_s64
-// CHECK: cmlt  {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #0
+// CHECK-LABEL: test_vcltzq_s64
+// CHECK: sshr  {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #63
 uint64x2_t test_vcltzq_s64(int64x2_t a) {
   return vcltzq_s64(a);
 }
 
-// CHECK: test_vcltz_f32
+// CHECK-LABEL: test_vcltz_f32
 // CHECK: fcmlt  {{v[0-9]+}}.2s, {{v[0-9]+}}.2s, #0
 uint32x2_t test_vcltz_f32(float32x2_t a) {
   return vcltz_f32(a);
 }
+ 
+// CHECK-LABEL: test_vcltz_f64
+// CHECK: fcmlt  {{d[0-9]+}}, {{d[0-9]+}}, #0
+uint64x1_t test_vcltz_f64(float64x1_t a) {
+  return vcltz_f64(a);
+}
 
-// CHECK: test_vcltzq_f32
+// CHECK-LABEL: test_vcltzq_f32
 // CHECK: fcmlt  {{v[0-9]+}}.4s, {{v[0-9]+}}.4s, #0
 uint32x4_t test_vcltzq_f32(float32x4_t a) {
   return vcltzq_f32(a);
 }
 
-// CHECK: test_vcltzq_f64
+// CHECK-LABEL: test_vcltzq_f64
 // CHECK: fcmlt  {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #0
 uint64x2_t test_vcltzq_f64(float64x2_t a) {
   return vcltzq_f64(a);
 }
 
-// CHECK: test_vrev16_s8
+// CHECK-LABEL: test_vrev16_s8
 // CHECK: rev16 v{{[0-9]+}}.8b, v{{[0-9]+}}.8b
 int8x8_t test_vrev16_s8(int8x8_t a) {
   return vrev16_s8(a);
 }
 
-// CHECK: test_vrev16_u8
+// CHECK-LABEL: test_vrev16_u8
 // CHECK: rev16 v{{[0-9]+}}.8b, v{{[0-9]+}}.8b
 uint8x8_t test_vrev16_u8(uint8x8_t a) {
   return vrev16_u8(a);
 }
 
-// CHECK: test_vrev16_p8
+// CHECK-LABEL: test_vrev16_p8
 // CHECK: rev16 v{{[0-9]+}}.8b, v{{[0-9]+}}.8b
 poly8x8_t test_vrev16_p8(poly8x8_t a) {
   return vrev16_p8(a);
 }
 
-// CHECK: test_vrev16q_s8
+// CHECK-LABEL: test_vrev16q_s8
 // CHECK: rev16 v{{[0-9]+}}.16b, v{{[0-9]+}}.16b
 int8x16_t test_vrev16q_s8(int8x16_t a) {
   return vrev16q_s8(a);
 }
 
-// CHECK: test_vrev16q_u8
+// CHECK-LABEL: test_vrev16q_u8
 // CHECK: rev16 v{{[0-9]+}}.16b, v{{[0-9]+}}.16b
 uint8x16_t test_vrev16q_u8(uint8x16_t a) {
   return vrev16q_u8(a);
 }
 
-// CHECK: test_vrev16q_p8
+// CHECK-LABEL: test_vrev16q_p8
 // CHECK: rev16 v{{[0-9]+}}.16b, v{{[0-9]+}}.16b
 poly8x16_t test_vrev16q_p8(poly8x16_t a) {
   return vrev16q_p8(a);
 }
 
-// CHECK: test_vrev32_s8
+// CHECK-LABEL: test_vrev32_s8
 // CHECK: rev32 v{{[0-9]+}}.8b, v{{[0-9]+}}.8b
 int8x8_t test_vrev32_s8(int8x8_t a) {
   return vrev32_s8(a);
 }
 
-// CHECK: test_vrev32_s16
+// CHECK-LABEL: test_vrev32_s16
 // CHECK: rev32 v{{[0-9]+}}.4h, v{{[0-9]+}}.4h
 int16x4_t test_vrev32_s16(int16x4_t a) {
   return vrev32_s16(a);
 }
 
-// CHECK: test_vrev32_u8
+// CHECK-LABEL: test_vrev32_u8
 // CHECK: rev32 v{{[0-9]+}}.8b, v{{[0-9]+}}.8b
 uint8x8_t test_vrev32_u8(uint8x8_t a) {
   return vrev32_u8(a);
 }
 
-// CHECK: test_vrev32_u16
+// CHECK-LABEL: test_vrev32_u16
 // CHECK: rev32 v{{[0-9]+}}.4h, v{{[0-9]+}}.4h
 uint16x4_t test_vrev32_u16(uint16x4_t a) {
   return vrev32_u16(a);
 }
 
-// CHECK: test_vrev32_p8
+// CHECK-LABEL: test_vrev32_p8
 // CHECK: rev32 v{{[0-9]+}}.8b, v{{[0-9]+}}.8b
 poly8x8_t test_vrev32_p8(poly8x8_t a) {
   return vrev32_p8(a);
 }
 
-// CHECK: test_vrev32_p16
+// CHECK-LABEL: test_vrev32_p16
 // CHECK: rev32 v{{[0-9]+}}.4h, v{{[0-9]+}}.4h
 poly16x4_t test_vrev32_p16(poly16x4_t a) {
   return vrev32_p16(a);
 }
 
-// CHECK: test_vrev32q_s8
+// CHECK-LABEL: test_vrev32q_s8
 // CHECK: rev32 v{{[0-9]+}}.16b, v{{[0-9]+}}.16b
 int8x16_t test_vrev32q_s8(int8x16_t a) {
   return vrev32q_s8(a);
 }
 
-// CHECK: test_vrev32q_s16
+// CHECK-LABEL: test_vrev32q_s16
 // CHECK: rev32 v{{[0-9]+}}.8h, v{{[0-9]+}}.8h
 int16x8_t test_vrev32q_s16(int16x8_t a) {
   return vrev32q_s16(a);
 }
 
-// CHECK: test_vrev32q_u8
+// CHECK-LABEL: test_vrev32q_u8
 // CHECK: rev32 v{{[0-9]+}}.16b, v{{[0-9]+}}.16b
 uint8x16_t test_vrev32q_u8(uint8x16_t a) {
   return vrev32q_u8(a);
 }
 
-// CHECK: test_vrev32q_u16
+// CHECK-LABEL: test_vrev32q_u16
 // CHECK: rev32 v{{[0-9]+}}.8h, v{{[0-9]+}}.8h
 uint16x8_t test_vrev32q_u16(uint16x8_t a) {
   return vrev32q_u16(a);
 }
 
-// CHECK: test_vrev32q_p8
+// CHECK-LABEL: test_vrev32q_p8
 // CHECK: rev32 v{{[0-9]+}}.16b, v{{[0-9]+}}.16b
 poly8x16_t test_vrev32q_p8(poly8x16_t a) {
   return vrev32q_p8(a);
 }
 
-// CHECK: test_vrev32q_p16
+// CHECK-LABEL: test_vrev32q_p16
 // CHECK: rev32 v{{[0-9]+}}.8h, v{{[0-9]+}}.8h
 poly16x8_t test_vrev32q_p16(poly16x8_t a) {
   return vrev32q_p16(a);
 }
 
-// CHECK: test_vrev64_s8
+// CHECK-LABEL: test_vrev64_s8
 // CHECK: rev64 v{{[0-9]+}}.8b, v{{[0-9]+}}.8b
 int8x8_t test_vrev64_s8(int8x8_t a) {
   return vrev64_s8(a);
 }
 
-// CHECK: test_vrev64_s16
+// CHECK-LABEL: test_vrev64_s16
 // CHECK: rev64 v{{[0-9]+}}.4h, v{{[0-9]+}}.4h
 int16x4_t test_vrev64_s16(int16x4_t a) {
   return vrev64_s16(a);
 }
 
-// CHECK: test_vrev64_s32
+// CHECK-LABEL: test_vrev64_s32
 // CHECK: rev64 v{{[0-9]+}}.2s, v{{[0-9]+}}.2s
 int32x2_t test_vrev64_s32(int32x2_t a) {
   return vrev64_s32(a);
 }
 
-// CHECK: test_vrev64_u8
+// CHECK-LABEL: test_vrev64_u8
 // CHECK: rev64 v{{[0-9]+}}.8b, v{{[0-9]+}}.8b
 uint8x8_t test_vrev64_u8(uint8x8_t a) {
   return vrev64_u8(a);
 }
 
-// CHECK: test_vrev64_u16
+// CHECK-LABEL: test_vrev64_u16
 // CHECK: rev64 v{{[0-9]+}}.4h, v{{[0-9]+}}.4h
 uint16x4_t test_vrev64_u16(uint16x4_t a) {
   return vrev64_u16(a);
 }
 
-// CHECK: test_vrev64_u32
+// CHECK-LABEL: test_vrev64_u32
 // CHECK: rev64 v{{[0-9]+}}.2s, v{{[0-9]+}}.2s
 uint32x2_t test_vrev64_u32(uint32x2_t a) {
   return vrev64_u32(a);
 }
 
-// CHECK: test_vrev64_p8
+// CHECK-LABEL: test_vrev64_p8
 // CHECK: rev64 v{{[0-9]+}}.8b, v{{[0-9]+}}.8b
 poly8x8_t test_vrev64_p8(poly8x8_t a) {
   return vrev64_p8(a);
 }
 
-// CHECK: test_vrev64_p16
+// CHECK-LABEL: test_vrev64_p16
 // CHECK: rev64 v{{[0-9]+}}.4h, v{{[0-9]+}}.4h
 poly16x4_t test_vrev64_p16(poly16x4_t a) {
   return vrev64_p16(a);
 }
 
-// CHECK: test_vrev64_f32
+// CHECK-LABEL: test_vrev64_f32
 // CHECK: rev64 v{{[0-9]+}}.2s, v{{[0-9]+}}.2s
 float32x2_t test_vrev64_f32(float32x2_t a) {
   return vrev64_f32(a);
 }
 
-// CHECK: test_vrev64q_s8
+// CHECK-LABEL: test_vrev64q_s8
 // CHECK: rev64 v{{[0-9]+}}.16b, v{{[0-9]+}}.16b
 int8x16_t test_vrev64q_s8(int8x16_t a) {
   return vrev64q_s8(a);
 }
 
-// CHECK: test_vrev64q_s16
+// CHECK-LABEL: test_vrev64q_s16
 // CHECK: rev64 v{{[0-9]+}}.8h, v{{[0-9]+}}.8h
 int16x8_t test_vrev64q_s16(int16x8_t a) {
   return vrev64q_s16(a);
 }
 
-// CHECK: test_vrev64q_s32
+// CHECK-LABEL: test_vrev64q_s32
 // CHECK: rev64 v{{[0-9]+}}.4s, v{{[0-9]+}}.4s
 int32x4_t test_vrev64q_s32(int32x4_t a) {
   return vrev64q_s32(a);
 }
 
-// CHECK: test_vrev64q_u8
+// CHECK-LABEL: test_vrev64q_u8
 // CHECK: rev64 v{{[0-9]+}}.16b, v{{[0-9]+}}.16b
 uint8x16_t test_vrev64q_u8(uint8x16_t a) {
   return vrev64q_u8(a);
 }
 
-// CHECK: test_vrev64q_u16
+// CHECK-LABEL: test_vrev64q_u16
 // CHECK: rev64 v{{[0-9]+}}.8h, v{{[0-9]+}}.8h
 uint16x8_t test_vrev64q_u16(uint16x8_t a) {
   return vrev64q_u16(a);
 }
 
-// CHECK: test_vrev64q_u32
+// CHECK-LABEL: test_vrev64q_u32
 // CHECK: rev64 v{{[0-9]+}}.4s, v{{[0-9]+}}.4s
 uint32x4_t test_vrev64q_u32(uint32x4_t a) {
   return vrev64q_u32(a);
 }
 
-// CHECK: test_vrev64q_p8
+// CHECK-LABEL: test_vrev64q_p8
 // CHECK: rev64 v{{[0-9]+}}.16b, v{{[0-9]+}}.16b
 poly8x16_t test_vrev64q_p8(poly8x16_t a) {
   return vrev64q_p8(a);
 }
 
-// CHECK: test_vrev64q_p16
+// CHECK-LABEL: test_vrev64q_p16
 // CHECK: rev64 v{{[0-9]+}}.8h, v{{[0-9]+}}.8h
 poly16x8_t test_vrev64q_p16(poly16x8_t a) {
   return vrev64q_p16(a);
 }
 
-// CHECK: test_vrev64q_f32
+// CHECK-LABEL: test_vrev64q_f32
 // CHECK: rev64 v{{[0-9]+}}.4s, v{{[0-9]+}}.4s
 float32x4_t test_vrev64q_f32(float32x4_t a) {
   return vrev64q_f32(a);
 }
 
 int16x4_t test_vpaddl_s8(int8x8_t a) {
-  // CHECK: test_vpaddl_s8
+  // CHECK-LABEL: test_vpaddl_s8
   return vpaddl_s8(a);
   // CHECK: saddlp v{{[0-9]+}}.4h, v{{[0-9]+}}.8b
 }
 
 int32x2_t test_vpaddl_s16(int16x4_t a) {
-  // CHECK: test_vpaddl_s16
+  // CHECK-LABEL: test_vpaddl_s16
   return vpaddl_s16(a);
   // CHECK: saddlp v{{[0-9]+}}.2s, v{{[0-9]+}}.4h
 }
 
 int64x1_t test_vpaddl_s32(int32x2_t a) {
-  // CHECK: test_vpaddl_s32
+  // CHECK-LABEL: test_vpaddl_s32
   return vpaddl_s32(a);
   // CHECK: saddlp v{{[0-9]+}}.1d, v{{[0-9]+}}.2s
 }
 
 uint16x4_t test_vpaddl_u8(uint8x8_t a) {
-  // CHECK: test_vpaddl_u8
+  // CHECK-LABEL: test_vpaddl_u8
   return vpaddl_u8(a);
   // CHECK: uaddlp v{{[0-9]+}}.4h, v{{[0-9]+}}.8b
 }
 
 uint32x2_t test_vpaddl_u16(uint16x4_t a) {
-  // CHECK: test_vpaddl_u16
+  // CHECK-LABEL: test_vpaddl_u16
   return vpaddl_u16(a);
   // CHECK: uaddlp v{{[0-9]+}}.2s, v{{[0-9]+}}.4h
 }
 
 uint64x1_t test_vpaddl_u32(uint32x2_t a) {
-  // CHECK: test_vpaddl_u32
+  // CHECK-LABEL: test_vpaddl_u32
   return vpaddl_u32(a);
   // CHECK: uaddlp v{{[0-9]+}}.1d, v{{[0-9]+}}.2s
 }
 
 int16x8_t test_vpaddlq_s8(int8x16_t a) {
-  // CHECK: test_vpaddlq_s8
+  // CHECK-LABEL: test_vpaddlq_s8
   return vpaddlq_s8(a);
   // CHECK: saddlp v{{[0-9]+}}.8h, v{{[0-9]+}}.16b
 }
 
 int32x4_t test_vpaddlq_s16(int16x8_t a) {
-  // CHECK: test_vpaddlq_s16
+  // CHECK-LABEL: test_vpaddlq_s16
   return vpaddlq_s16(a);
   // CHECK: saddlp v{{[0-9]+}}.4s, v{{[0-9]+}}.8h
 }
 
 int64x2_t test_vpaddlq_s32(int32x4_t a) {
-  // CHECK: test_vpaddlq_s32
+  // CHECK-LABEL: test_vpaddlq_s32
   return vpaddlq_s32(a);
   // CHECK: saddlp v{{[0-9]+}}.2d, v{{[0-9]+}}.4s
 }
 
 uint16x8_t test_vpaddlq_u8(uint8x16_t a) {
-  // CHECK: test_vpaddlq_u8
+  // CHECK-LABEL: test_vpaddlq_u8
   return vpaddlq_u8(a);
   // CHECK: uaddlp v{{[0-9]+}}.8h, v{{[0-9]+}}.16b
 }
 
 uint32x4_t test_vpaddlq_u16(uint16x8_t a) {
-  // CHECK: test_vpaddlq_u16
+  // CHECK-LABEL: test_vpaddlq_u16
   return vpaddlq_u16(a);
   // CHECK: uaddlp v{{[0-9]+}}.4s, v{{[0-9]+}}.8h
 }
 
 uint64x2_t test_vpaddlq_u32(uint32x4_t a) {
-  // CHECK: test_vpaddlq_u32
+  // CHECK-LABEL: test_vpaddlq_u32
   return vpaddlq_u32(a);
   // CHECK: uaddlp v{{[0-9]+}}.2d, v{{[0-9]+}}.4s
 }
 
 int16x4_t test_vpadal_s8(int16x4_t a, int8x8_t b) {
-  // CHECK: test_vpadal_s8
+  // CHECK-LABEL: test_vpadal_s8
   return vpadal_s8(a, b);
   // CHECK: sadalp v{{[0-9]+}}.4h, v{{[0-9]+}}.8b
 }
 
 int32x2_t test_vpadal_s16(int32x2_t a, int16x4_t b) {
-  // CHECK: test_vpadal_s16
+  // CHECK-LABEL: test_vpadal_s16
   return vpadal_s16(a, b);
   // CHECK: sadalp v{{[0-9]+}}.2s, v{{[0-9]+}}.4h
 }
 
 int64x1_t test_vpadal_s32(int64x1_t a, int32x2_t b) {
-  // CHECK: test_vpadal_s32
+  // CHECK-LABEL: test_vpadal_s32
   return vpadal_s32(a, b);
   // CHECK: sadalp v{{[0-9]+}}.1d, v{{[0-9]+}}.2s
 }
 
 uint16x4_t test_vpadal_u8(uint16x4_t a, uint8x8_t b) {
-  // CHECK: test_vpadal_u8
+  // CHECK-LABEL: test_vpadal_u8
   return vpadal_u8(a, b);
   // CHECK: uadalp v{{[0-9]+}}.4h, v{{[0-9]+}}.8b
 }
 
 uint32x2_t test_vpadal_u16(uint32x2_t a, uint16x4_t b) {
-  // CHECK: test_vpadal_u16
+  // CHECK-LABEL: test_vpadal_u16
   return vpadal_u16(a, b);
   // CHECK: uadalp v{{[0-9]+}}.2s, v{{[0-9]+}}.4h
 }
 
 uint64x1_t test_vpadal_u32(uint64x1_t a, uint32x2_t b) {
-  // CHECK: test_vpadal_u32
+  // CHECK-LABEL: test_vpadal_u32
   return vpadal_u32(a, b);
   // CHECK: uadalp v{{[0-9]+}}.1d, v{{[0-9]+}}.2s
 }
 
 int16x8_t test_vpadalq_s8(int16x8_t a, int8x16_t b) {
-  // CHECK: test_vpadalq_s8
+  // CHECK-LABEL: test_vpadalq_s8
   return vpadalq_s8(a, b);
   // CHECK: sadalp v{{[0-9]+}}.8h, v{{[0-9]+}}.16b
 }
 
 int32x4_t test_vpadalq_s16(int32x4_t a, int16x8_t b) {
-  // CHECK: test_vpadalq_s16
+  // CHECK-LABEL: test_vpadalq_s16
   return vpadalq_s16(a, b);
   // CHECK: sadalp v{{[0-9]+}}.4s, v{{[0-9]+}}.8h
 }
 
 int64x2_t test_vpadalq_s32(int64x2_t a, int32x4_t b) {
-  // CHECK: test_vpadalq_s32
+  // CHECK-LABEL: test_vpadalq_s32
   return vpadalq_s32(a, b);
   // CHECK: sadalp v{{[0-9]+}}.2d, v{{[0-9]+}}.4s
 }
 
 uint16x8_t test_vpadalq_u8(uint16x8_t a, uint8x16_t b) {
-  // CHECK: test_vpadalq_u8
+  // CHECK-LABEL: test_vpadalq_u8
   return vpadalq_u8(a, b);
   // CHECK: uadalp v{{[0-9]+}}.8h, v{{[0-9]+}}.16b
 }
 
 uint32x4_t test_vpadalq_u16(uint32x4_t a, uint16x8_t b) {
-  // CHECK: test_vpadalq_u16
+  // CHECK-LABEL: test_vpadalq_u16
   return vpadalq_u16(a, b);
   // CHECK: uadalp v{{[0-9]+}}.4s, v{{[0-9]+}}.8h
 }
 
 uint64x2_t test_vpadalq_u32(uint64x2_t a, uint32x4_t b) {
-  // CHECK: test_vpadalq_u32
+  // CHECK-LABEL: test_vpadalq_u32
   return vpadalq_u32(a, b);
   // CHECK: uadalp v{{[0-9]+}}.2d, v{{[0-9]+}}.4s
 }
 
 int8x8_t test_vqabs_s8(int8x8_t a) {
-  // CHECK: test_vqabs_s8
+  // CHECK-LABEL: test_vqabs_s8
   return vqabs_s8(a);
   // CHECK: sqabs v{{[0-9]+}}.8b, v{{[0-9]+}}.8b
 }
 
 int8x16_t test_vqabsq_s8(int8x16_t a) {
-  // CHECK: test_vqabsq_s8
+  // CHECK-LABEL: test_vqabsq_s8
   return vqabsq_s8(a);
   // CHECK: sqabs v{{[0-9]+}}.16b, v{{[0-9]+}}.16b
 }
 
 int16x4_t test_vqabs_s16(int16x4_t a) {
-  // CHECK: test_vqabs_s16
+  // CHECK-LABEL: test_vqabs_s16
   return vqabs_s16(a);
   // CHECK: sqabs v{{[0-9]+}}.4h, v{{[0-9]+}}.4h
 }
 
 int16x8_t test_vqabsq_s16(int16x8_t a) {
-  // CHECK: test_vqabsq_s16
+  // CHECK-LABEL: test_vqabsq_s16
   return vqabsq_s16(a);
   // CHECK: sqabs v{{[0-9]+}}.8h, v{{[0-9]+}}.8h
 }
 
 int32x2_t test_vqabs_s32(int32x2_t a) {
-  // CHECK: test_vqabs_s32
+  // CHECK-LABEL: test_vqabs_s32
   return vqabs_s32(a);
   // CHECK: sqabs v{{[0-9]+}}.2s, v{{[0-9]+}}.2s
 }
 
 int32x4_t test_vqabsq_s32(int32x4_t a) {
-  // CHECK: test_vqabsq_s32
+  // CHECK-LABEL: test_vqabsq_s32
   return vqabsq_s32(a);
   // CHECK: sqabs v{{[0-9]+}}.4s, v{{[0-9]+}}.4s
 }
 
 int64x2_t test_vqabsq_s64(int64x2_t a) {
-  // CHECK: test_vqabsq_s64
+  // CHECK-LABEL: test_vqabsq_s64
   return vqabsq_s64(a);
   // CHECK: sqabs v{{[0-9]+}}.2d, v{{[0-9]+}}.2d
 }
 
 int8x8_t test_vqneg_s8(int8x8_t a) {
-  // CHECK: test_vqneg_s8
+  // CHECK-LABEL: test_vqneg_s8
   return vqneg_s8(a);
   // CHECK: sqneg v{{[0-9]+}}.8b, v{{[0-9]+}}.8b
 }
 
 int8x16_t test_vqnegq_s8(int8x16_t a) {
-  // CHECK: test_vqnegq_s8
+  // CHECK-LABEL: test_vqnegq_s8
   return vqnegq_s8(a);
   // CHECK: sqneg v{{[0-9]+}}.16b, v{{[0-9]+}}.16b
 }
 
 int16x4_t test_vqneg_s16(int16x4_t a) {
-  // CHECK: test_vqneg_s16
+  // CHECK-LABEL: test_vqneg_s16
   return vqneg_s16(a);
   // CHECK: sqneg v{{[0-9]+}}.4h, v{{[0-9]+}}.4h
 }
 
 int16x8_t test_vqnegq_s16(int16x8_t a) {
-  // CHECK: test_vqnegq_s16
+  // CHECK-LABEL: test_vqnegq_s16
   return vqnegq_s16(a);
   // CHECK: sqneg v{{[0-9]+}}.8h, v{{[0-9]+}}.8h
 }
 
 int32x2_t test_vqneg_s32(int32x2_t a) {
-  // CHECK: test_vqneg_s32
+  // CHECK-LABEL: test_vqneg_s32
   return vqneg_s32(a);
   // CHECK: sqneg v{{[0-9]+}}.2s, v{{[0-9]+}}.2s
 }
 
 int32x4_t test_vqnegq_s32(int32x4_t a) {
-  // CHECK: test_vqnegq_s32
+  // CHECK-LABEL: test_vqnegq_s32
   return vqnegq_s32(a);
   // CHECK: sqneg v{{[0-9]+}}.4s, v{{[0-9]+}}.4s
 }
 
 int64x2_t test_vqnegq_s64(int64x2_t a) {
-  // CHECK: test_vqnegq_s64
+  // CHECK-LABEL: test_vqnegq_s64
   return vqnegq_s64(a);
   // CHECK: sqneg v{{[0-9]+}}.2d, v{{[0-9]+}}.2d
 }
 
 int8x8_t test_vneg_s8(int8x8_t a) {
-  // CHECK: test_vneg_s8
+  // CHECK-LABEL: test_vneg_s8
   return vneg_s8(a);
   // CHECK: neg v{{[0-9]+}}.8b, v{{[0-9]+}}.8b
 }
 
 int8x16_t test_vnegq_s8(int8x16_t a) {
-  // CHECK: test_vnegq_s8
+  // CHECK-LABEL: test_vnegq_s8
   return vnegq_s8(a);
   // CHECK: neg v{{[0-9]+}}.16b, v{{[0-9]+}}.16b
 }
 
 int16x4_t test_vneg_s16(int16x4_t a) {
-  // CHECK: test_vneg_s16
+  // CHECK-LABEL: test_vneg_s16
   return vneg_s16(a);
   // CHECK: neg v{{[0-9]+}}.4h, v{{[0-9]+}}.4h
 }
 
 int16x8_t test_vnegq_s16(int16x8_t a) {
-  // CHECK: test_vnegq_s16
+  // CHECK-LABEL: test_vnegq_s16
   return vnegq_s16(a);
   // CHECK: neg v{{[0-9]+}}.8h, v{{[0-9]+}}.8h
 }
 
 int32x2_t test_vneg_s32(int32x2_t a) {
-  // CHECK: test_vneg_s32
+  // CHECK-LABEL: test_vneg_s32
   return vneg_s32(a);
   // CHECK: neg v{{[0-9]+}}.2s, v{{[0-9]+}}.2s
 }
 
 int32x4_t test_vnegq_s32(int32x4_t a) {
-  // CHECK: test_vnegq_s32
+  // CHECK-LABEL: test_vnegq_s32
   return vnegq_s32(a);
   // CHECK: neg v{{[0-9]+}}.4s, v{{[0-9]+}}.4s
 }
 
 int64x2_t test_vnegq_s64(int64x2_t a) {
-  // CHECK: test_vnegq_s64
+  // CHECK-LABEL: test_vnegq_s64
   return vnegq_s64(a);
   // CHECK: neg v{{[0-9]+}}.2d, v{{[0-9]+}}.2d
 }
 
 float32x2_t test_vneg_f32(float32x2_t a) {
-  // CHECK: test_vneg_f32
+  // CHECK-LABEL: test_vneg_f32
   return vneg_f32(a);
   // CHECK: fneg v{{[0-9]+}}.2s, v{{[0-9]+}}.2s
 }
 
 float32x4_t test_vnegq_f32(float32x4_t a) {
-  // CHECK: test_vnegq_f32
+  // CHECK-LABEL: test_vnegq_f32
   return vnegq_f32(a);
   // CHECK: fneg v{{[0-9]+}}.4s, v{{[0-9]+}}.4s
 }
 
 float64x2_t test_vnegq_f64(float64x2_t a) {
-  // CHECK: test_vnegq_f64
+  // CHECK-LABEL: test_vnegq_f64
   return vnegq_f64(a);
   // CHECK: fneg v{{[0-9]+}}.2d, v{{[0-9]+}}.2d
 }
 
 int8x8_t test_vabs_s8(int8x8_t a) {
-  // CHECK: test_vabs_s8
+  // CHECK-LABEL: test_vabs_s8
   return vabs_s8(a);
   // CHECK: abs v{{[0-9]+}}.8b, v{{[0-9]+}}.8b
 }
 
 int8x16_t test_vabsq_s8(int8x16_t a) {
-  // CHECK: test_vabsq_s8
+  // CHECK-LABEL: test_vabsq_s8
   return vabsq_s8(a);
   // CHECK: abs v{{[0-9]+}}.16b, v{{[0-9]+}}.16b
 }
 
 int16x4_t test_vabs_s16(int16x4_t a) {
-  // CHECK: test_vabs_s16
+  // CHECK-LABEL: test_vabs_s16
   return vabs_s16(a);
   // CHECK: abs v{{[0-9]+}}.4h, v{{[0-9]+}}.4h
 }
 
 int16x8_t test_vabsq_s16(int16x8_t a) {
-  // CHECK: test_vabsq_s16
+  // CHECK-LABEL: test_vabsq_s16
   return vabsq_s16(a);
   // CHECK: abs v{{[0-9]+}}.8h, v{{[0-9]+}}.8h
 }
 
 int32x2_t test_vabs_s32(int32x2_t a) {
-  // CHECK: test_vabs_s32
+  // CHECK-LABEL: test_vabs_s32
   return vabs_s32(a);
   // CHECK: abs v{{[0-9]+}}.2s, v{{[0-9]+}}.2s
 }
 
 int32x4_t test_vabsq_s32(int32x4_t a) {
-  // CHECK: test_vabsq_s32
+  // CHECK-LABEL: test_vabsq_s32
   return vabsq_s32(a);
   // CHECK: abs v{{[0-9]+}}.4s, v{{[0-9]+}}.4s
 }
 
 int64x2_t test_vabsq_s64(int64x2_t a) {
-  // CHECK: test_vabsq_s64
+  // CHECK-LABEL: test_vabsq_s64
   return vabsq_s64(a);
   // CHECK: abs v{{[0-9]+}}.2d, v{{[0-9]+}}.2d
 }
 
 float32x2_t test_vabs_f32(float32x2_t a) {
-  // CHECK: test_vabs_f32
+  // CHECK-LABEL: test_vabs_f32
   return vabs_f32(a);
   // CHECK: fabs v{{[0-9]+}}.2s, v{{[0-9]+}}.2s
 }
 
 float32x4_t test_vabsq_f32(float32x4_t a) {
-  // CHECK: test_vabsq_f32
+  // CHECK-LABEL: test_vabsq_f32
   return vabsq_f32(a);
   // CHECK: fabs v{{[0-9]+}}.4s, v{{[0-9]+}}.4s
 }
 
 float64x2_t test_vabsq_f64(float64x2_t a) {
-  // CHECK: test_vabsq_f64
+  // CHECK-LABEL: test_vabsq_f64
   return vabsq_f64(a);
   // CHECK: fabs v{{[0-9]+}}.2d, v{{[0-9]+}}.2d
 }
 
 int8x8_t test_vuqadd_s8(int8x8_t a, int8x8_t b) {
-  // CHECK: test_vuqadd_s8
+  // CHECK-LABEL: test_vuqadd_s8
   return vuqadd_s8(a, b);
   // CHECK: suqadd v{{[0-9]+}}.8b, v{{[0-9]+}}.8b
 }
 
 int8x16_t test_vuqaddq_s8(int8x16_t a, int8x16_t b) {
-  // CHECK: test_vuqaddq_s8
+  // CHECK-LABEL: test_vuqaddq_s8
   return vuqaddq_s8(a, b);
   // CHECK: suqadd v{{[0-9]+}}.16b, v{{[0-9]+}}.16b
 }
 
 int16x4_t test_vuqadd_s16(int16x4_t a, int16x4_t b) {
-  // CHECK: test_vuqadd_s16
+  // CHECK-LABEL: test_vuqadd_s16
   return vuqadd_s16(a, b);
   // CHECK: suqadd v{{[0-9]+}}.4h, v{{[0-9]+}}.4h
 }
 
 int16x8_t test_vuqaddq_s16(int16x8_t a, int16x8_t b) {
-  // CHECK: test_vuqaddq_s16
+  // CHECK-LABEL: test_vuqaddq_s16
   return vuqaddq_s16(a, b);
   // CHECK: suqadd v{{[0-9]+}}.8h, v{{[0-9]+}}.8h
 }
 
 int32x2_t test_vuqadd_s32(int32x2_t a, int32x2_t b) {
-  // CHECK: test_vuqadd_s32
+  // CHECK-LABEL: test_vuqadd_s32
   return vuqadd_s32(a, b);
   // CHECK: suqadd v{{[0-9]+}}.2s, v{{[0-9]+}}.2s
 }
 
 int32x4_t test_vuqaddq_s32(int32x4_t a, int32x4_t b) {
-  // CHECK: test_vuqaddq_s32
+  // CHECK-LABEL: test_vuqaddq_s32
   return vuqaddq_s32(a, b);
   // CHECK: suqadd v{{[0-9]+}}.4s, v{{[0-9]+}}.4s
 }
 
 int64x2_t test_vuqaddq_s64(int64x2_t a, int64x2_t b) {
-  // CHECK: test_vuqaddq_s64
+  // CHECK-LABEL: test_vuqaddq_s64
   return vuqaddq_s64(a, b);
   // CHECK: suqadd v{{[0-9]+}}.2d, v{{[0-9]+}}.2d
 }
 
 int8x8_t test_vcls_s8(int8x8_t a) {
-  // CHECK: test_vcls_s8
+  // CHECK-LABEL: test_vcls_s8
   return vcls_s8(a);
   // CHECK: cls v{{[0-9]+}}.8b, v{{[0-9]+}}.8b
 }
 
 int8x16_t test_vclsq_s8(int8x16_t a) {
-  // CHECK: test_vclsq_s8
+  // CHECK-LABEL: test_vclsq_s8
   return vclsq_s8(a);
   // CHECK: cls v{{[0-9]+}}.16b, v{{[0-9]+}}.16b
 }
 
 int16x4_t test_vcls_s16(int16x4_t a) {
-  // CHECK: test_vcls_s16
+  // CHECK-LABEL: test_vcls_s16
   return vcls_s16(a);
   // CHECK: cls v{{[0-9]+}}.4h, v{{[0-9]+}}.4h
 }
 
 int16x8_t test_vclsq_s16(int16x8_t a) {
-  // CHECK: test_vclsq_s16
+  // CHECK-LABEL: test_vclsq_s16
   return vclsq_s16(a);
   // CHECK: cls v{{[0-9]+}}.8h, v{{[0-9]+}}.8h
 }
 
 int32x2_t test_vcls_s32(int32x2_t a) {
-  // CHECK: test_vcls_s32
+  // CHECK-LABEL: test_vcls_s32
   return vcls_s32(a);
   // CHECK: cls v{{[0-9]+}}.2s, v{{[0-9]+}}.2s
 }
 
 int32x4_t test_vclsq_s32(int32x4_t a) {
-  // CHECK: test_vclsq_s32
+  // CHECK-LABEL: test_vclsq_s32
   return vclsq_s32(a);
   // CHECK: cls v{{[0-9]+}}.4s, v{{[0-9]+}}.4s
 }
 
 int8x8_t test_vclz_s8(int8x8_t a) {
-  // CHECK: test_vclz_s8
+  // CHECK-LABEL: test_vclz_s8
   return vclz_s8(a);
   // CHECK: clz v{{[0-9]+}}.8b, v{{[0-9]+}}.8b
 }
 
 int8x16_t test_vclzq_s8(int8x16_t a) {
-  // CHECK: test_vclzq_s8
+  // CHECK-LABEL: test_vclzq_s8
   return vclzq_s8(a);
   // CHECK: clz v{{[0-9]+}}.16b, v{{[0-9]+}}.16b
 }
 
 int16x4_t test_vclz_s16(int16x4_t a) {
-  // CHECK: test_vclz_s16
+  // CHECK-LABEL: test_vclz_s16
   return vclz_s16(a);
   // CHECK: clz v{{[0-9]+}}.4h, v{{[0-9]+}}.4h
 }
 
 int16x8_t test_vclzq_s16(int16x8_t a) {
-  // CHECK: test_vclzq_s16
+  // CHECK-LABEL: test_vclzq_s16
   return vclzq_s16(a);
   // CHECK: clz v{{[0-9]+}}.8h, v{{[0-9]+}}.8h
 }
 
 int32x2_t test_vclz_s32(int32x2_t a) {
-  // CHECK: test_vclz_s32
+  // CHECK-LABEL: test_vclz_s32
   return vclz_s32(a);
   // CHECK: clz v{{[0-9]+}}.2s, v{{[0-9]+}}.2s
 }
 
 int32x4_t test_vclzq_s32(int32x4_t a) {
-  // CHECK: test_vclzq_s32
+  // CHECK-LABEL: test_vclzq_s32
   return vclzq_s32(a);
   // CHECK: clz v{{[0-9]+}}.4s, v{{[0-9]+}}.4s
 }
 
 uint8x8_t test_vclz_u8(uint8x8_t a) {
-  // CHECK: test_vclz_u8
+  // CHECK-LABEL: test_vclz_u8
   return vclz_u8(a);
   // CHECK: clz v{{[0-9]+}}.8b, v{{[0-9]+}}.8b
 }
 
 uint8x16_t test_vclzq_u8(uint8x16_t a) {
-  // CHECK: test_vclzq_u8
+  // CHECK-LABEL: test_vclzq_u8
   return vclzq_u8(a);
   // CHECK: clz v{{[0-9]+}}.16b, v{{[0-9]+}}.16b
 }
 
 uint16x4_t test_vclz_u16(uint16x4_t a) {
-  // CHECK: test_vclz_u16
+  // CHECK-LABEL: test_vclz_u16
   return vclz_u16(a);
   // CHECK: clz v{{[0-9]+}}.4h, v{{[0-9]+}}.4h
 }
 
 uint16x8_t test_vclzq_u16(uint16x8_t a) {
-  // CHECK: test_vclzq_u16
+  // CHECK-LABEL: test_vclzq_u16
   return vclzq_u16(a);
   // CHECK: clz v{{[0-9]+}}.8h, v{{[0-9]+}}.8h
 }
 
 uint32x2_t test_vclz_u32(uint32x2_t a) {
-  // CHECK: test_vclz_u32
+  // CHECK-LABEL: test_vclz_u32
   return vclz_u32(a);
   // CHECK: clz v{{[0-9]+}}.2s, v{{[0-9]+}}.2s
 }
 
 uint32x4_t test_vclzq_u32(uint32x4_t a) {
-  // CHECK: test_vclzq_u32
+  // CHECK-LABEL: test_vclzq_u32
   return vclzq_u32(a);
   // CHECK: clz v{{[0-9]+}}.4s, v{{[0-9]+}}.4s
 }
 
 int8x8_t test_vcnt_s8(int8x8_t a) {
-  // CHECK: test_vcnt_s8
+  // CHECK-LABEL: test_vcnt_s8
   return vcnt_s8(a);
   // CHECK: cnt v{{[0-9]+}}.8b, v{{[0-9]+}}.8b
 }
 
 int8x16_t test_vcntq_s8(int8x16_t a) {
-  // CHECK: test_vcntq_s8
+  // CHECK-LABEL: test_vcntq_s8
   return vcntq_s8(a);
   // CHECK: cnt v{{[0-9]+}}.16b, v{{[0-9]+}}.16b
 }
 
 uint8x8_t test_vcnt_u8(uint8x8_t a) {
-  // CHECK: test_vcnt_u8
+  // CHECK-LABEL: test_vcnt_u8
   return vcnt_u8(a);
   // CHECK: cnt v{{[0-9]+}}.8b, v{{[0-9]+}}.8b
 }
 
 uint8x16_t test_vcntq_u8(uint8x16_t a) {
-  // CHECK: test_vcntq_u8
+  // CHECK-LABEL: test_vcntq_u8
   return vcntq_u8(a);
   // CHECK: cnt v{{[0-9]+}}.16b, v{{[0-9]+}}.16b
 }
 
 poly8x8_t test_vcnt_p8(poly8x8_t a) {
-  // CHECK: test_vcnt_p8
+  // CHECK-LABEL: test_vcnt_p8
   return vcnt_p8(a);
   // CHECK: cnt v{{[0-9]+}}.8b, v{{[0-9]+}}.8b
 }
 
 poly8x16_t test_vcntq_p8(poly8x16_t a) {
-  // CHECK: test_vcntq_p8
+  // CHECK-LABEL: test_vcntq_p8
   return vcntq_p8(a);
   // CHECK: cnt v{{[0-9]+}}.16b, v{{[0-9]+}}.16b
 }
 
 int8x8_t test_vmvn_s8(int8x8_t a) {
-  // CHECK: test_vmvn_s8
+  // CHECK-LABEL: test_vmvn_s8
   return vmvn_s8(a);
-  // CHECK: not v{{[0-9]+}}.8b, v{{[0-9]+}}.8b
+  // CHECK: {{mvn|not}} v{{[0-9]+}}.8b, v{{[0-9]+}}.8b
 }
 
 int8x16_t test_vmvnq_s8(int8x16_t a) {
-  // CHECK: test_vmvnq_s8
+  // CHECK-LABEL: test_vmvnq_s8
   return vmvnq_s8(a);
-  // CHECK: not v{{[0-9]+}}.16b, v{{[0-9]+}}.16b
+  // CHECK: {{mvn|not}} v{{[0-9]+}}.16b, v{{[0-9]+}}.16b
 }
 
 int16x4_t test_vmvn_s16(int16x4_t a) {
-  // CHECK: test_vmvn_s16
+  // CHECK-LABEL: test_vmvn_s16
   return vmvn_s16(a);
-  // CHECK: not v{{[0-9]+}}.8b, v{{[0-9]+}}.8b
+  // CHECK: {{mvn|not}} v{{[0-9]+}}.8b, v{{[0-9]+}}.8b
 }
 
 int16x8_t test_vmvnq_s16(int16x8_t a) {
-  // CHECK: test_vmvnq_s16
+  // CHECK-LABEL: test_vmvnq_s16
   return vmvnq_s16(a);
-  // CHECK: not v{{[0-9]+}}.16b, v{{[0-9]+}}.16b
+  // CHECK: {{mvn|not}} v{{[0-9]+}}.16b, v{{[0-9]+}}.16b
 }
 
 int32x2_t test_vmvn_s32(int32x2_t a) {
-  // CHECK: test_vmvn_s32
+  // CHECK-LABEL: test_vmvn_s32
   return vmvn_s32(a);
-  // CHECK: not v{{[0-9]+}}.8b, v{{[0-9]+}}.8b
+  // CHECK: {{mvn|not}} v{{[0-9]+}}.8b, v{{[0-9]+}}.8b
 }
 
 int32x4_t test_vmvnq_s32(int32x4_t a) {
-  // CHECK: test_vmvnq_s32
+  // CHECK-LABEL: test_vmvnq_s32
   return vmvnq_s32(a);
-  // CHECK: not v{{[0-9]+}}.16b, v{{[0-9]+}}.16b
+  // CHECK: {{mvn|not}} v{{[0-9]+}}.16b, v{{[0-9]+}}.16b
 }
 
 uint8x8_t test_vmvn_u8(uint8x8_t a) {
-  // CHECK: test_vmvn_u8
+  // CHECK-LABEL: test_vmvn_u8
   return vmvn_u8(a);
-  // CHECK: not v{{[0-9]+}}.8b, v{{[0-9]+}}.8b
+  // CHECK: {{mvn|not}} v{{[0-9]+}}.8b, v{{[0-9]+}}.8b
 }
 
 uint8x16_t test_vmvnq_u8(uint8x16_t a) {
-  // CHECK: test_vmvnq_u8
+  // CHECK-LABEL: test_vmvnq_u8
   return vmvnq_u8(a);
-  // CHECK: not v{{[0-9]+}}.16b, v{{[0-9]+}}.16b
+  // CHECK: {{mvn|not}} v{{[0-9]+}}.16b, v{{[0-9]+}}.16b
 }
 
 uint16x4_t test_vmvn_u16(uint16x4_t a) {
-  // CHECK: test_vmvn_u16
+  // CHECK-LABEL: test_vmvn_u16
   return vmvn_u16(a);
-  // CHECK: not v{{[0-9]+}}.8b, v{{[0-9]+}}.8b
+  // CHECK: {{mvn|not}} v{{[0-9]+}}.8b, v{{[0-9]+}}.8b
 }
 
 uint16x8_t test_vmvnq_u16(uint16x8_t a) {
-  // CHECK: test_vmvnq_u16
+  // CHECK-LABEL: test_vmvnq_u16
   return vmvnq_u16(a);
-  // CHECK: not v{{[0-9]+}}.16b, v{{[0-9]+}}.16b
+  // CHECK: {{mvn|not}} v{{[0-9]+}}.16b, v{{[0-9]+}}.16b
 }
 
 uint32x2_t test_vmvn_u32(uint32x2_t a) {
-  // CHECK: test_vmvn_u32
+  // CHECK-LABEL: test_vmvn_u32
   return vmvn_u32(a);
-  // CHECK: not v{{[0-9]+}}.8b, v{{[0-9]+}}.8b
+  // CHECK: {{mvn|not}} v{{[0-9]+}}.8b, v{{[0-9]+}}.8b
 }
 
 uint32x4_t test_vmvnq_u32(uint32x4_t a) {
-  // CHECK: test_vmvnq_u32
+  // CHECK-LABEL: test_vmvnq_u32
   return vmvnq_u32(a);
-  // CHECK: not v{{[0-9]+}}.16b, v{{[0-9]+}}.16b
+  // CHECK: {{mvn|not}} v{{[0-9]+}}.16b, v{{[0-9]+}}.16b
 }
 
 poly8x8_t test_vmvn_p8(poly8x8_t a) {
-  // CHECK: test_vmvn_p8
+  // CHECK-LABEL: test_vmvn_p8
   return vmvn_p8(a);
-  // CHECK: not v{{[0-9]+}}.8b, v{{[0-9]+}}.8b
+  // CHECK: {{mvn|not}} v{{[0-9]+}}.8b, v{{[0-9]+}}.8b
 }
 
 poly8x16_t test_vmvnq_p8(poly8x16_t a) {
-  // CHECK: test_vmvnq_p8
+  // CHECK-LABEL: test_vmvnq_p8
   return vmvnq_p8(a);
-  // CHECK: not v{{[0-9]+}}.16b, v{{[0-9]+}}.16b
+  // CHECK: {{mvn|not}} v{{[0-9]+}}.16b, v{{[0-9]+}}.16b
 }
 
 int8x8_t test_vrbit_s8(int8x8_t a) {
-  // CHECK: test_vrbit_s8
+  // CHECK-LABEL: test_vrbit_s8
   return vrbit_s8(a);
   // CHECK: rbit v{{[0-9]+}}.8b, v{{[0-9]+}}.8b
 }
 
 int8x16_t test_vrbitq_s8(int8x16_t a) {
-  // CHECK: test_vrbitq_s8
+  // CHECK-LABEL: test_vrbitq_s8
   return vrbitq_s8(a);
   // CHECK: rbit v{{[0-9]+}}.16b, v{{[0-9]+}}.16b
 }
 
 uint8x8_t test_vrbit_u8(uint8x8_t a) {
-  // CHECK: test_vrbit_u8
+  // CHECK-LABEL: test_vrbit_u8
   return vrbit_u8(a);
   // CHECK: rbit v{{[0-9]+}}.8b, v{{[0-9]+}}.8b
 }
 
 uint8x16_t test_vrbitq_u8(uint8x16_t a) {
-  // CHECK: test_vrbitq_u8
+  // CHECK-LABEL: test_vrbitq_u8
   return vrbitq_u8(a);
   // CHECK: rbit v{{[0-9]+}}.16b, v{{[0-9]+}}.16b
 }
 
 poly8x8_t test_vrbit_p8(poly8x8_t a) {
-  // CHECK: test_vrbit_p8
+  // CHECK-LABEL: test_vrbit_p8
   return vrbit_p8(a);
   // CHECK: rbit v{{[0-9]+}}.8b, v{{[0-9]+}}.8b
 }
 
 poly8x16_t test_vrbitq_p8(poly8x16_t a) {
-  // CHECK: test_vrbitq_p8
+  // CHECK-LABEL: test_vrbitq_p8
   return vrbitq_p8(a);
   // CHECK: rbit v{{[0-9]+}}.16b, v{{[0-9]+}}.16b
 }
 
 int8x8_t test_vmovn_s16(int16x8_t a) {
-  // CHECK: test_vmovn_s16
+  // CHECK-LABEL: test_vmovn_s16
   return vmovn_s16(a);
   // CHECK: xtn v{{[0-9]+}}.8b, v{{[0-9]+}}.8h
 }
 
 int16x4_t test_vmovn_s32(int32x4_t a) {
-  // CHECK: test_vmovn_s32
+  // CHECK-LABEL: test_vmovn_s32
   return vmovn_s32(a);
   // CHECK: xtn v{{[0-9]+}}.4h, v{{[0-9]+}}.4s
 }
 
 int32x2_t test_vmovn_s64(int64x2_t a) {
-  // CHECK: test_vmovn_s64
+  // CHECK-LABEL: test_vmovn_s64
   return vmovn_s64(a);
   // CHECK: xtn v{{[0-9]+}}.2s, v{{[0-9]+}}.2d
 }
 
 uint8x8_t test_vmovn_u16(uint16x8_t a) {
-  // CHECK: test_vmovn_u16
+  // CHECK-LABEL: test_vmovn_u16
   return vmovn_u16(a);
   // CHECK: xtn v{{[0-9]+}}.8b, v{{[0-9]+}}.8h
 }
 
 uint16x4_t test_vmovn_u32(uint32x4_t a) {
-  // CHECK: test_vmovn_u32
+  // CHECK-LABEL: test_vmovn_u32
   return vmovn_u32(a);
   // CHECK: xtn v{{[0-9]+}}.4h, v{{[0-9]+}}.4s
 }
 
 uint32x2_t test_vmovn_u64(uint64x2_t a) {
-  // CHECK: test_vmovn_u64
+  // CHECK-LABEL: test_vmovn_u64
   return vmovn_u64(a);
   // CHECK: xtn v{{[0-9]+}}.2s, v{{[0-9]+}}.2d
 }
 
 int8x16_t test_vmovn_high_s16(int8x8_t a, int16x8_t b) {
-  // CHECK: test_vmovn_high_s16
+  // CHECK-LABEL: test_vmovn_high_s16
   return vmovn_high_s16(a, b);
   // CHECK: xtn2 v{{[0-9]+}}.16b, v{{[0-9]+}}.8h
 }
 
 int16x8_t test_vmovn_high_s32(int16x4_t a, int32x4_t b) {
-  // CHECK: test_vmovn_high_s32
+  // CHECK-LABEL: test_vmovn_high_s32
   return vmovn_high_s32(a, b);
   // CHECK: xtn2 v{{[0-9]+}}.8h, v{{[0-9]+}}.4s
 }
 
 int32x4_t test_vmovn_high_s64(int32x2_t a, int64x2_t b) {
-  // CHECK: test_vmovn_high_s64
+  // CHECK-LABEL: test_vmovn_high_s64
   return vmovn_high_s64(a, b);
   // CHECK: xtn2 v{{[0-9]+}}.4s, v{{[0-9]+}}.2d
 }
 
 int8x16_t test_vmovn_high_u16(int8x8_t a, int16x8_t b) {
-  // CHECK: test_vmovn_high_u16
+  // CHECK-LABEL: test_vmovn_high_u16
   return vmovn_high_u16(a, b);
   // CHECK: xtn2 v{{[0-9]+}}.16b, v{{[0-9]+}}.8h
 }
 
 int16x8_t test_vmovn_high_u32(int16x4_t a, int32x4_t b) {
-  // CHECK: test_vmovn_high_u32
+  // CHECK-LABEL: test_vmovn_high_u32
   return vmovn_high_u32(a, b);
   // CHECK: xtn2 v{{[0-9]+}}.8h, v{{[0-9]+}}.4s
 }
 
 int32x4_t test_vmovn_high_u64(int32x2_t a, int64x2_t b) {
-  // CHECK: test_vmovn_high_u64
+  // CHECK-LABEL: test_vmovn_high_u64
   return vmovn_high_u64(a, b);
   // CHECK: xtn2 v{{[0-9]+}}.4s, v{{[0-9]+}}.2d
 }
 
 int8x8_t test_vqmovun_s16(int16x8_t a) {
-  // CHECK: test_vqmovun_s16
+  // CHECK-LABEL: test_vqmovun_s16
   return vqmovun_s16(a);
   // CHECK: sqxtun v{{[0-9]+}}.8b, v{{[0-9]+}}.8h
 }
 
 int16x4_t test_vqmovun_s32(int32x4_t a) {
-  // CHECK: test_vqmovun_s32
+  // CHECK-LABEL: test_vqmovun_s32
   return vqmovun_s32(a);
   // CHECK: sqxtun v{{[0-9]+}}.4h, v{{[0-9]+}}.4s
 }
 
 int32x2_t test_vqmovun_s64(int64x2_t a) {
-  // CHECK: test_vqmovun_s64
+  // CHECK-LABEL: test_vqmovun_s64
   return vqmovun_s64(a);
   // CHECK: sqxtun v{{[0-9]+}}.2s, v{{[0-9]+}}.2d
 }
 
 int8x16_t test_vqmovun_high_s16(int8x8_t a, int16x8_t b) {
-  // CHECK: test_vqmovun_high_s16
+  // CHECK-LABEL: test_vqmovun_high_s16
   return vqmovun_high_s16(a, b);
   // CHECK: sqxtun2 v{{[0-9]+}}.16b, v{{[0-9]+}}.8h
 }
 
 int16x8_t test_vqmovun_high_s32(int16x4_t a, int32x4_t b) {
-  // CHECK: test_vqmovun_high_s32
+  // CHECK-LABEL: test_vqmovun_high_s32
   return vqmovun_high_s32(a, b);
   // CHECK: sqxtun2 v{{[0-9]+}}.8h, v{{[0-9]+}}.4s
 }
 
 int32x4_t test_vqmovun_high_s64(int32x2_t a, int64x2_t b) {
-  // CHECK: test_vqmovun_high_s64
+  // CHECK-LABEL: test_vqmovun_high_s64
   return vqmovun_high_s64(a, b);
   // CHECK: sqxtun2 v{{[0-9]+}}.4s, v{{[0-9]+}}.2d
 }
 
 int8x8_t test_vqmovn_s16(int16x8_t a) {
-  // CHECK: test_vqmovn_s16
+  // CHECK-LABEL: test_vqmovn_s16
   return vqmovn_s16(a);
   // CHECK: sqxtn v{{[0-9]+}}.8b, v{{[0-9]+}}.8h
 }
 
 int16x4_t test_vqmovn_s32(int32x4_t a) {
-  // CHECK: test_vqmovn_s32
+  // CHECK-LABEL: test_vqmovn_s32
   return vqmovn_s32(a);
   // CHECK: sqxtn v{{[0-9]+}}.4h, v{{[0-9]+}}.4s
 }
 
 int32x2_t test_vqmovn_s64(int64x2_t a) {
-  // CHECK: test_vqmovn_s64
+  // CHECK-LABEL: test_vqmovn_s64
   return vqmovn_s64(a);
   // CHECK: sqxtn v{{[0-9]+}}.2s, v{{[0-9]+}}.2d
 }
 
 int8x16_t test_vqmovn_high_s16(int8x8_t a, int16x8_t b) {
-  // CHECK: test_vqmovn_high_s16
+  // CHECK-LABEL: test_vqmovn_high_s16
   return vqmovn_high_s16(a, b);
   // CHECK: sqxtn2 v{{[0-9]+}}.16b, v{{[0-9]+}}.8h
 }
 
 int16x8_t test_vqmovn_high_s32(int16x4_t a, int32x4_t b) {
-  // CHECK: test_vqmovn_high_s32
+  // CHECK-LABEL: test_vqmovn_high_s32
   return vqmovn_high_s32(a, b);
   // CHECK: sqxtn2 v{{[0-9]+}}.8h, v{{[0-9]+}}.4s
 }
 
 int32x4_t test_vqmovn_high_s64(int32x2_t a, int64x2_t b) {
-  // CHECK: test_vqmovn_high_s64
+  // CHECK-LABEL: test_vqmovn_high_s64
   return vqmovn_high_s64(a, b);
   // CHECK: sqxtn2 v{{[0-9]+}}.4s, v{{[0-9]+}}.2d
 }
 
 uint8x8_t test_vqmovn_u16(uint16x8_t a) {
-  // CHECK: test_vqmovn_u16
+  // CHECK-LABEL: test_vqmovn_u16
   return vqmovn_u16(a);
   // CHECK: uqxtn v{{[0-9]+}}.8b, v{{[0-9]+}}.8h
 }
 
 uint16x4_t test_vqmovn_u32(uint32x4_t a) {
-  // CHECK: test_vqmovn_u32
+  // CHECK-LABEL: test_vqmovn_u32
   return vqmovn_u32(a);
   // CHECK: uqxtn v{{[0-9]+}}.4h, v{{[0-9]+}}.4s
 }
 
 uint32x2_t test_vqmovn_u64(uint64x2_t a) {
-  // CHECK: test_vqmovn_u64
+  // CHECK-LABEL: test_vqmovn_u64
   return vqmovn_u64(a);
   // CHECK: uqxtn v{{[0-9]+}}.2s, v{{[0-9]+}}.2d
 }
 
 uint8x16_t test_vqmovn_high_u16(uint8x8_t a, uint16x8_t b) {
-  // CHECK: test_vqmovn_high_u16
+  // CHECK-LABEL: test_vqmovn_high_u16
   return vqmovn_high_u16(a, b);
   // CHECK: uqxtn2 v{{[0-9]+}}.16b, v{{[0-9]+}}.8h
 }
 
 uint16x8_t test_vqmovn_high_u32(uint16x4_t a, uint32x4_t b) {
-  // CHECK: test_vqmovn_high_u32
+  // CHECK-LABEL: test_vqmovn_high_u32
   return vqmovn_high_u32(a, b);
   // CHECK: uqxtn2 v{{[0-9]+}}.8h, v{{[0-9]+}}.4s
 }
 
 uint32x4_t test_vqmovn_high_u64(uint32x2_t a, uint64x2_t b) {
-  // CHECK: test_vqmovn_high_u64
+  // CHECK-LABEL: test_vqmovn_high_u64
   return vqmovn_high_u64(a, b);
   // CHECK: uqxtn2 v{{[0-9]+}}.4s, v{{[0-9]+}}.2d
 }
 
 int16x8_t test_vshll_n_s8(int8x8_t a) {
-  // CHECK: test_vshll_n_s8
+  // CHECK-LABEL: test_vshll_n_s8
   return vshll_n_s8(a, 8);
   // CHECK: shll {{v[0-9]+}}.8h, {{v[0-9]+}}.8b, #8
 }
 
 int32x4_t test_vshll_n_s16(int16x4_t a) {
-  // CHECK: test_vshll_n_s16
+  // CHECK-LABEL: test_vshll_n_s16
   return vshll_n_s16(a, 16);
   // CHECK: shll {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, #16
 }
 
 int64x2_t test_vshll_n_s32(int32x2_t a) {
-  // CHECK: test_vshll_n_s32
+  // CHECK-LABEL: test_vshll_n_s32
   return vshll_n_s32(a, 32);
   // CHECK: shll {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, #32
 }
 
 uint16x8_t test_vshll_n_u8(uint8x8_t a) {
-  // CHECK: test_vshll_n_u8
+  // CHECK-LABEL: test_vshll_n_u8
   return vshll_n_u8(a, 8);
   // CHECK: shll {{v[0-9]+}}.8h, {{v[0-9]+}}.8b, #8
 }
 
 uint32x4_t test_vshll_n_u16(uint16x4_t a) {
-  // CHECK: test_vshll_n_u16
+  // CHECK-LABEL: test_vshll_n_u16
   return vshll_n_u16(a, 16);
   // CHECK: shll {{v[0-9]+}}.4s, {{v[0-9]+}}.4h, #16
 }
 
 uint64x2_t test_vshll_n_u32(uint32x2_t a) {
-  // CHECK: test_vshll_n_u32
+  // CHECK-LABEL: test_vshll_n_u32
   return vshll_n_u32(a, 32);
   // CHECK: shll {{v[0-9]+}}.2d, {{v[0-9]+}}.2s, #32
 }
 
 int16x8_t test_vshll_high_n_s8(int8x16_t a) {
-  // CHECK: test_vshll_high_n_s8
+  // CHECK-LABEL: test_vshll_high_n_s8
   return vshll_high_n_s8(a, 8);
   // CHECK: shll2 {{v[0-9]+}}.8h, {{v[0-9]+}}.16b, #8
 }
 
 int32x4_t test_vshll_high_n_s16(int16x8_t a) {
-  // CHECK: test_vshll_high_n_s16
+  // CHECK-LABEL: test_vshll_high_n_s16
   return vshll_high_n_s16(a, 16);
   // CHECK: shll2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, #16
 }
 
 int64x2_t test_vshll_high_n_s32(int32x4_t a) {
-  // CHECK: test_vshll_high_n_s32
+  // CHECK-LABEL: test_vshll_high_n_s32
   return vshll_high_n_s32(a, 32);
   // CHECK: shll2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, #32
 }
 
 uint16x8_t test_vshll_high_n_u8(uint8x16_t a) {
-  // CHECK: test_vshll_high_n_u8
+  // CHECK-LABEL: test_vshll_high_n_u8
   return vshll_high_n_u8(a, 8);
   // CHECK: shll2 {{v[0-9]+}}.8h, {{v[0-9]+}}.16b, #8
 }
 
 uint32x4_t test_vshll_high_n_u16(uint16x8_t a) {
-  // CHECK: test_vshll_high_n_u16
+  // CHECK-LABEL: test_vshll_high_n_u16
   return vshll_high_n_u16(a, 16);
   // CHECK: shll2 {{v[0-9]+}}.4s, {{v[0-9]+}}.8h, #16
 }
 
 uint64x2_t test_vshll_high_n_u32(uint32x4_t a) {
-  // CHECK: test_vshll_high_n_u32
+  // CHECK-LABEL: test_vshll_high_n_u32
   return vshll_high_n_u32(a, 32);
   // CHECK: shll2 {{v[0-9]+}}.2d, {{v[0-9]+}}.4s, #32
 }
 
 float16x4_t test_vcvt_f16_f32(float32x4_t a) {
-  //CHECK: test_vcvt_f16_f32
+  //CHECK-LABEL: test_vcvt_f16_f32
   return vcvt_f16_f32(a);
   // CHECK: fcvtn v{{[0-9]+}}.4h, v{{[0-9]+}}.4s
 }
 
 float16x8_t test_vcvt_high_f16_f32(float16x4_t a, float32x4_t b) {
-  //CHECK: test_vcvt_high_f16_f32
+  //CHECK-LABEL: test_vcvt_high_f16_f32
   return vcvt_high_f16_f32(a, b);
   // CHECK: fcvtn2 v{{[0-9]+}}.8h, v{{[0-9]+}}.4s
 }
 
 float32x2_t test_vcvt_f32_f64(float64x2_t a) {
-  //CHECK: test_vcvt_f32_f64
+  //CHECK-LABEL: test_vcvt_f32_f64
   return vcvt_f32_f64(a);
   // CHECK: fcvtn v{{[0-9]+}}.2s, v{{[0-9]+}}.2d
 }
 
 float32x4_t test_vcvt_high_f32_f64(float32x2_t a, float64x2_t b) {
-  //CHECK: test_vcvt_high_f32_f64
+  //CHECK-LABEL: test_vcvt_high_f32_f64
   return vcvt_high_f32_f64(a, b);
   // CHECK: fcvtn2 v{{[0-9]+}}.4s, v{{[0-9]+}}.2d
 }
 
 float32x2_t test_vcvtx_f32_f64(float64x2_t a) {
-  //CHECK: test_vcvtx_f32_f64
+  //CHECK-LABEL: test_vcvtx_f32_f64
   return vcvtx_f32_f64(a);
   // CHECK: fcvtxn v{{[0-9]+}}.2s, v{{[0-9]+}}.2d
 }
 
 float32x4_t test_vcvtx_high_f32_f64(float32x2_t a, float64x2_t b) {
-  //CHECK: test_vcvtx_high_f32_f64
+  //CHECK-LABEL: test_vcvtx_high_f32_f64
   return vcvtx_high_f32_f64(a, b);
   // CHECK: fcvtxn2 v{{[0-9]+}}.4s, v{{[0-9]+}}.2d
 }
 
 float32x4_t test_vcvt_f32_f16(float16x4_t a) {
-  //CHECK: test_vcvt_f32_f16
+  //CHECK-LABEL: test_vcvt_f32_f16
   return vcvt_f32_f16(a);
   // CHECK: fcvtl v{{[0-9]+}}.4s, v{{[0-9]+}}.4h
 }
 
 float32x4_t test_vcvt_high_f32_f16(float16x8_t a) {
-  //CHECK: test_vcvt_high_f32_f16
+  //CHECK-LABEL: test_vcvt_high_f32_f16
   return vcvt_high_f32_f16(a);
   // CHECK: fcvtl2 v{{[0-9]+}}.4s, v{{[0-9]+}}.8h
 }
 
 float64x2_t test_vcvt_f64_f32(float32x2_t a) {
-  //CHECK: test_vcvt_f64_f32
+  //CHECK-LABEL: test_vcvt_f64_f32
   return vcvt_f64_f32(a);
   // CHECK: fcvtl v{{[0-9]+}}.2d, v{{[0-9]+}}.2s
 }
 
 float64x2_t test_vcvt_high_f64_f32(float32x4_t a) {
-  //CHECK: test_vcvt_high_f64_f32
+  //CHECK-LABEL: test_vcvt_high_f64_f32
   return vcvt_high_f64_f32(a);
   // CHECK: fcvtl2 v{{[0-9]+}}.2d, v{{[0-9]+}}.4s
 }
 
 float32x2_t test_vrndn_f32(float32x2_t a) {
-  //CHECK: test_vrndn_f32
+  //CHECK-LABEL: test_vrndn_f32
   return vrndn_f32(a);
   // CHECK: frintn v{{[0-9]+}}.2s, v{{[0-9]+}}.2s
 }
 
 float32x4_t test_vrndnq_f32(float32x4_t a) {
-  //CHECK: test_vrndnq_f32
+  //CHECK-LABEL: test_vrndnq_f32
   return vrndnq_f32(a);
   // CHECK: frintn v{{[0-9]+}}.4s, v{{[0-9]+}}.4s
 }
 
 float64x2_t test_vrndnq_f64(float64x2_t a) {
-  //CHECK: test_vrndnq_f64
+  //CHECK-LABEL: test_vrndnq_f64
   return vrndnq_f64(a);
   // CHECK: frintn v{{[0-9]+}}.2d, v{{[0-9]+}}.2d
 }
 
 float32x2_t test_vrnda_f32(float32x2_t a) {
-  //CHECK: test_vrnda_f32
+  //CHECK-LABEL: test_vrnda_f32
   return vrnda_f32(a);
   // CHECK: frinta v{{[0-9]+}}.2s, v{{[0-9]+}}.2s
 }
 
 float32x4_t test_vrndaq_f32(float32x4_t a) {
-  //CHECK: test_vrndaq_f32
+  //CHECK-LABEL: test_vrndaq_f32
   return vrndaq_f32(a);
   // CHECK: frinta v{{[0-9]+}}.4s, v{{[0-9]+}}.4s
 }
 
 float64x2_t test_vrndaq_f64(float64x2_t a) {
-  //CHECK: test_vrndaq_f64
+  //CHECK-LABEL: test_vrndaq_f64
   return vrndaq_f64(a);
   // CHECK: frinta v{{[0-9]+}}.2d, v{{[0-9]+}}.2d
 }
 
 float32x2_t test_vrndp_f32(float32x2_t a) {
-  //CHECK: test_vrndp_f32
+  //CHECK-LABEL: test_vrndp_f32
   return vrndp_f32(a);
   // CHECK: frintp v{{[0-9]+}}.2s, v{{[0-9]+}}.2s
 }
 
 float32x4_t test_vrndpq_f32(float32x4_t a) {
-  //CHECK: test_vrndpq_f32
+  //CHECK-LABEL: test_vrndpq_f32
   return vrndpq_f32(a);
   // CHECK: frintp v{{[0-9]+}}.4s, v{{[0-9]+}}.4s
 }
 
 float64x2_t test_vrndpq_f64(float64x2_t a) {
-  //CHECK: test_vrndpq_f64
+  //CHECK-LABEL: test_vrndpq_f64
   return vrndpq_f64(a);
   // CHECK: frintp v{{[0-9]+}}.2d, v{{[0-9]+}}.2d
 }
 
 float32x2_t test_vrndm_f32(float32x2_t a) {
-  //CHECK: test_vrndm_f32
+  //CHECK-LABEL: test_vrndm_f32
   return vrndm_f32(a);
   // CHECK: frintm v{{[0-9]+}}.2s, v{{[0-9]+}}.2s
 }
 
 float32x4_t test_vrndmq_f32(float32x4_t a) {
-  //CHECK: test_vrndmq_f32
+  //CHECK-LABEL: test_vrndmq_f32
   return vrndmq_f32(a);
   // CHECK: frintm v{{[0-9]+}}.4s, v{{[0-9]+}}.4s
 }
 
 float64x2_t test_vrndmq_f64(float64x2_t a) {
-  //CHECK: test_vrndmq_f64
+  //CHECK-LABEL: test_vrndmq_f64
   return vrndmq_f64(a);
   // CHECK: frintm v{{[0-9]+}}.2d, v{{[0-9]+}}.2d
 }
 
 float32x2_t test_vrndx_f32(float32x2_t a) {
-  //CHECK: test_vrndx_f32
+  //CHECK-LABEL: test_vrndx_f32
   return vrndx_f32(a);
   // CHECK: frintx v{{[0-9]+}}.2s, v{{[0-9]+}}.2s
 }
 
 float32x4_t test_vrndxq_f32(float32x4_t a) {
-  //CHECK: test_vrndxq_f32
+  //CHECK-LABEL: test_vrndxq_f32
   return vrndxq_f32(a);
   // CHECK: frintx v{{[0-9]+}}.4s, v{{[0-9]+}}.4s
 }
 
 float64x2_t test_vrndxq_f64(float64x2_t a) {
-  //CHECK: test_vrndxq_f64
+  //CHECK-LABEL: test_vrndxq_f64
   return vrndxq_f64(a);
   // CHECK: frintx v{{[0-9]+}}.2d, v{{[0-9]+}}.2d
 }
 
 float32x2_t test_vrnd_f32(float32x2_t a) {
-  //CHECK: test_vrnd_f32
+  //CHECK-LABEL: test_vrnd_f32
   return vrnd_f32(a);
   // CHECK: frintz v{{[0-9]+}}.2s, v{{[0-9]+}}.2s
 }
 
 float32x4_t test_vrndq_f32(float32x4_t a) {
-  //CHECK: test_vrndq_f32
+  //CHECK-LABEL: test_vrndq_f32
   return vrndq_f32(a);
   // CHECK: frintz v{{[0-9]+}}.4s, v{{[0-9]+}}.4s
 }
 
 float64x2_t test_vrndq_f64(float64x2_t a) {
-  //CHECK: test_vrndq_f64
+  //CHECK-LABEL: test_vrndq_f64
   return vrndq_f64(a);
   // CHECK: frintz v{{[0-9]+}}.2d, v{{[0-9]+}}.2d
 }
 
 float32x2_t test_vrndi_f32(float32x2_t a) {
-  //CHECK: test_vrndi_f32
+  //CHECK-LABEL: test_vrndi_f32
   return vrndi_f32(a);
   // CHECK: frinti v{{[0-9]+}}.2s, v{{[0-9]+}}.2s
 }
 
 float32x4_t test_vrndiq_f32(float32x4_t a) {
-  //CHECK: test_vrndiq_f32
+  //CHECK-LABEL: test_vrndiq_f32
   return vrndiq_f32(a);
   // CHECK: frinti v{{[0-9]+}}.4s, v{{[0-9]+}}.4s
 }
 
 float64x2_t test_vrndiq_f64(float64x2_t a) {
-  //CHECK: test_vrndiq_f64
+  //CHECK-LABEL: test_vrndiq_f64
   return vrndiq_f64(a);
   // CHECK: frinti v{{[0-9]+}}.2d, v{{[0-9]+}}.2d
 }
 
 int32x2_t test_vcvt_s32_f32(float32x2_t a) {
-  //CHECK: test_vcvt_s32_f32
+  //CHECK-LABEL: test_vcvt_s32_f32
   return vcvt_s32_f32(a);
   // CHECK: fcvtzs v{{[0-9]+}}.2s, v{{[0-9]+}}.2s
 }
 
 int32x4_t test_vcvtq_s32_f32(float32x4_t a) {
-  //CHECK: test_vcvtq_s32_f32
+  //CHECK-LABEL: test_vcvtq_s32_f32
   return vcvtq_s32_f32(a);
   // CHECK: fcvtzs v{{[0-9]+}}.4s, v{{[0-9]+}}.4s
 }
 
 int64x2_t test_vcvtq_s64_f64(float64x2_t a) {
-  //CHECK: test_vcvtq_s64_f64
+  //CHECK-LABEL: test_vcvtq_s64_f64
   return vcvtq_s64_f64(a);
   // CHECK: fcvtzs v{{[0-9]+}}.2d, v{{[0-9]+}}.2d
 }
 
 uint32x2_t test_vcvt_u32_f32(float32x2_t a) {
-  //CHECK: test_vcvt_u32_f32
+  //CHECK-LABEL: test_vcvt_u32_f32
   return vcvt_u32_f32(a);
   // CHECK: fcvtzu v{{[0-9]+}}.2s, v{{[0-9]+}}.2s
 }
 
 uint32x4_t test_vcvtq_u32_f32(float32x4_t a) {
-  //CHECK: test_vcvtq_u32_f32
+  //CHECK-LABEL: test_vcvtq_u32_f32
   return vcvtq_u32_f32(a);
   // CHECK: fcvtzu v{{[0-9]+}}.4s, v{{[0-9]+}}.4s
 }
 
 uint64x2_t test_vcvtq_u64_f64(float64x2_t a) {
-  //CHECK: test_vcvtq_u64_f64
+  //CHECK-LABEL: test_vcvtq_u64_f64
   return vcvtq_u64_f64(a);
   // CHECK: fcvtzu v{{[0-9]+}}.2d, v{{[0-9]+}}.2d
 }
 
 int32x2_t test_vcvtn_s32_f32(float32x2_t a) {
-  //CHECK: test_vcvtn_s32_f32
+  //CHECK-LABEL: test_vcvtn_s32_f32
   return vcvtn_s32_f32(a);
   // CHECK: fcvtns v{{[0-9]+}}.2s, v{{[0-9]+}}.2s
 }
 
 int32x4_t test_vcvtnq_s32_f32(float32x4_t a) {
-  //CHECK: test_vcvtnq_s32_f32
+  //CHECK-LABEL: test_vcvtnq_s32_f32
   return vcvtnq_s32_f32(a);
   // CHECK: fcvtns v{{[0-9]+}}.4s, v{{[0-9]+}}.4s
 }
 
 int64x2_t test_vcvtnq_s64_f64(float64x2_t a) {
-  //CHECK: test_vcvtnq_s64_f64
+  //CHECK-LABEL: test_vcvtnq_s64_f64
   return vcvtnq_s64_f64(a);
   // CHECK: fcvtns v{{[0-9]+}}.2d, v{{[0-9]+}}.2d
 }
 
 uint32x2_t test_vcvtn_u32_f32(float32x2_t a) {
-  //CHECK: test_vcvtn_u32_f32
+  //CHECK-LABEL: test_vcvtn_u32_f32
   return vcvtn_u32_f32(a);
   // CHECK: fcvtnu v{{[0-9]+}}.2s, v{{[0-9]+}}.2s
 }
 
 uint32x4_t test_vcvtnq_u32_f32(float32x4_t a) {
-  //CHECK: test_vcvtnq_u32_f32
+  //CHECK-LABEL: test_vcvtnq_u32_f32
   return vcvtnq_u32_f32(a);
   // CHECK: fcvtnu v{{[0-9]+}}.4s, v{{[0-9]+}}.4s
 }
 
 uint64x2_t test_vcvtnq_u64_f64(float64x2_t a) {
-  //CHECK: test_vcvtnq_u64_f64
+  //CHECK-LABEL: test_vcvtnq_u64_f64
   return vcvtnq_u64_f64(a);
   // CHECK: fcvtnu v{{[0-9]+}}.2d, v{{[0-9]+}}.2d
 }
 
 int32x2_t test_vcvtp_s32_f32(float32x2_t a) {
-  //CHECK: test_vcvtp_s32_f32
+  //CHECK-LABEL: test_vcvtp_s32_f32
   return vcvtp_s32_f32(a);
   // CHECK: fcvtps v{{[0-9]+}}.2s, v{{[0-9]+}}.2s
 }
 
 int32x4_t test_vcvtpq_s32_f32(float32x4_t a) {
-  //CHECK: test_vcvtpq_s32_f32
+  //CHECK-LABEL: test_vcvtpq_s32_f32
   return vcvtpq_s32_f32(a);
   // CHECK: fcvtps v{{[0-9]+}}.4s, v{{[0-9]+}}.4s
 }
 
 int64x2_t test_vcvtpq_s64_f64(float64x2_t a) {
-  //CHECK: test_vcvtpq_s64_f64
+  //CHECK-LABEL: test_vcvtpq_s64_f64
   return vcvtpq_s64_f64(a);
   // CHECK: fcvtps v{{[0-9]+}}.2d, v{{[0-9]+}}.2d
 }
 
 uint32x2_t test_vcvtp_u32_f32(float32x2_t a) {
-  //CHECK: test_vcvtp_u32_f32
+  //CHECK-LABEL: test_vcvtp_u32_f32
   return vcvtp_u32_f32(a);
   // CHECK: fcvtpu v{{[0-9]+}}.2s, v{{[0-9]+}}.2s
 }
 
 uint32x4_t test_vcvtpq_u32_f32(float32x4_t a) {
-  //CHECK: test_vcvtpq_u32_f32
+  //CHECK-LABEL: test_vcvtpq_u32_f32
   return vcvtpq_u32_f32(a);
   // CHECK: fcvtpu v{{[0-9]+}}.4s, v{{[0-9]+}}.4s
 }
 
 uint64x2_t test_vcvtpq_u64_f64(float64x2_t a) {
-  //CHECK: test_vcvtpq_u64_f64
+  //CHECK-LABEL: test_vcvtpq_u64_f64
   return vcvtpq_u64_f64(a);
   // CHECK: fcvtpu v{{[0-9]+}}.2d, v{{[0-9]+}}.2d
 }
 
 int32x2_t test_vcvtm_s32_f32(float32x2_t a) {
-  //CHECK: test_vcvtm_s32_f32
+  //CHECK-LABEL: test_vcvtm_s32_f32
   return vcvtm_s32_f32(a);
   // CHECK: fcvtms v{{[0-9]+}}.2s, v{{[0-9]+}}.2s
 }
 
 int32x4_t test_vcvtmq_s32_f32(float32x4_t a) {
-  //CHECK: test_vcvtmq_s32_f32
+  //CHECK-LABEL: test_vcvtmq_s32_f32
   return vcvtmq_s32_f32(a);
   // CHECK: fcvtms v{{[0-9]+}}.4s, v{{[0-9]+}}.4s
 }
 
 int64x2_t test_vcvtmq_s64_f64(float64x2_t a) {
-  //CHECK: test_vcvtmq_s64_f64
+  //CHECK-LABEL: test_vcvtmq_s64_f64
   return vcvtmq_s64_f64(a);
   // CHECK: fcvtms v{{[0-9]+}}.2d, v{{[0-9]+}}.2d
 }
 
 uint32x2_t test_vcvtm_u32_f32(float32x2_t a) {
-  //CHECK: test_vcvtm_u32_f32
+  //CHECK-LABEL: test_vcvtm_u32_f32
   return vcvtm_u32_f32(a);
   // CHECK: fcvtmu v{{[0-9]+}}.2s, v{{[0-9]+}}.2s
 }
 
 uint32x4_t test_vcvtmq_u32_f32(float32x4_t a) {
-  //CHECK: test_vcvtmq_u32_f32
+  //CHECK-LABEL: test_vcvtmq_u32_f32
   return vcvtmq_u32_f32(a);
   // CHECK: fcvtmu v{{[0-9]+}}.4s, v{{[0-9]+}}.4s
 }
 
 uint64x2_t test_vcvtmq_u64_f64(float64x2_t a) {
-  //CHECK: test_vcvtmq_u64_f64
+  //CHECK-LABEL: test_vcvtmq_u64_f64
   return vcvtmq_u64_f64(a);
   // CHECK: fcvtmu v{{[0-9]+}}.2d, v{{[0-9]+}}.2d
 }
 
 int32x2_t test_vcvta_s32_f32(float32x2_t a) {
-  //CHECK: test_vcvta_s32_f32
+  //CHECK-LABEL: test_vcvta_s32_f32
   return vcvta_s32_f32(a);
   // CHECK: fcvtas v{{[0-9]+}}.2s, v{{[0-9]+}}.2s
 }
 
 int32x4_t test_vcvtaq_s32_f32(float32x4_t a) {
-  //CHECK: test_vcvtaq_s32_f32
+  //CHECK-LABEL: test_vcvtaq_s32_f32
   return vcvtaq_s32_f32(a);
   // CHECK: fcvtas v{{[0-9]+}}.4s, v{{[0-9]+}}.4s
 }
 
 int64x2_t test_vcvtaq_s64_f64(float64x2_t a) {
-  //CHECK: test_vcvtaq_s64_f64
+  //CHECK-LABEL: test_vcvtaq_s64_f64
   return vcvtaq_s64_f64(a);
   // CHECK: fcvtas v{{[0-9]+}}.2d, v{{[0-9]+}}.2d
 }
 
 uint32x2_t test_vcvta_u32_f32(float32x2_t a) {
-  //CHECK: test_vcvta_u32_f32
+  //CHECK-LABEL: test_vcvta_u32_f32
   return vcvta_u32_f32(a);
   // CHECK: fcvtau v{{[0-9]+}}.2s, v{{[0-9]+}}.2s
 }
 
 uint32x4_t test_vcvtaq_u32_f32(float32x4_t a) {
-  //CHECK: test_vcvtaq_u32_f32
+  //CHECK-LABEL: test_vcvtaq_u32_f32
   return vcvtaq_u32_f32(a);
   // CHECK: fcvtau v{{[0-9]+}}.4s, v{{[0-9]+}}.4s
 }
 
 uint64x2_t test_vcvtaq_u64_f64(float64x2_t a) {
-  //CHECK: test_vcvtaq_u64_f64
+  //CHECK-LABEL: test_vcvtaq_u64_f64
   return vcvtaq_u64_f64(a);
   // CHECK: fcvtau v{{[0-9]+}}.2d, v{{[0-9]+}}.2d
 }
 
 float32x2_t test_vrsqrte_f32(float32x2_t a) {
-  //CHECK: test_vrsqrte_f32
+  //CHECK-LABEL: test_vrsqrte_f32
   return vrsqrte_f32(a);
   // CHECK: frsqrte v{{[0-9]+}}.2s, v{{[0-9]+}}.2s
 }
 
 float32x4_t test_vrsqrteq_f32(float32x4_t a) {
-  //CHECK: test_vrsqrteq_f32
+  //CHECK-LABEL: test_vrsqrteq_f32
   return vrsqrteq_f32(a);
   // CHECK: frsqrte v{{[0-9]+}}.4s, v{{[0-9]+}}.4s
 }
 
 float64x2_t test_vrsqrteq_f64(float64x2_t a) {
-  //CHECK: test_vrsqrteq_f64
+  //CHECK-LABEL: test_vrsqrteq_f64
   return vrsqrteq_f64(a);
   // CHECK: frsqrte v{{[0-9]+}}.2d, v{{[0-9]+}}.2d
 }
 
 float32x2_t test_vrecpe_f32(float32x2_t a) {
-  //CHECK: test_vrecpe_f32
+  //CHECK-LABEL: test_vrecpe_f32
   return vrecpe_f32(a);
   // CHECK: frecpe v{{[0-9]+}}.2s, v{{[0-9]+}}.2s
 }
 
 float32x4_t test_vrecpeq_f32(float32x4_t a) {
-  //CHECK: test_vrecpeq_f32
+  //CHECK-LABEL: test_vrecpeq_f32
   return vrecpeq_f32(a);
   // CHECK: frecpe v{{[0-9]+}}.4s, v{{[0-9]+}}.4s
 }
 
 float64x2_t test_vrecpeq_f64(float64x2_t a) {
-  //CHECK: test_vrecpeq_f64
+  //CHECK-LABEL: test_vrecpeq_f64
   return vrecpeq_f64(a);
   // CHECK: frecpe v{{[0-9]+}}.2d, v{{[0-9]+}}.2d
 }
 
 uint32x2_t test_vrecpe_u32(uint32x2_t a) {
-  //CHECK: test_vrecpe_u32
+  //CHECK-LABEL: test_vrecpe_u32
   return vrecpe_u32(a);
   // CHECK: urecpe v{{[0-9]+}}.2s, v{{[0-9]+}}.2s
 }
 
 uint32x4_t test_vrecpeq_u32(uint32x4_t a) {
-  //CHECK: test_vrecpeq_u32
+  //CHECK-LABEL: test_vrecpeq_u32
   return vrecpeq_u32(a);
   // CHECK: urecpe v{{[0-9]+}}.4s, v{{[0-9]+}}.4s
 }
 
 float32x2_t test_vsqrt_f32(float32x2_t a) {
-  //CHECK: test_vsqrt_f32
+  //CHECK-LABEL: test_vsqrt_f32
   return vsqrt_f32(a);
   // CHECK: fsqrt v{{[0-9]+}}.2s, v{{[0-9]+}}.2s
 }
 
 float32x4_t test_vsqrtq_f32(float32x4_t a) {
-  //CHECK: test_vsqrtq_f32
+  //CHECK-LABEL: test_vsqrtq_f32
   return vsqrtq_f32(a);
   // CHECK: fsqrt v{{[0-9]+}}.4s, v{{[0-9]+}}.4s
 }
 
 float64x2_t test_vsqrtq_f64(float64x2_t a) {
-  //CHECK: test_vsqrtq_f64
+  //CHECK-LABEL: test_vsqrtq_f64
   return vsqrtq_f64(a);
   // CHECK: fsqrt v{{[0-9]+}}.2d, v{{[0-9]+}}.2d
 }
 
 float32x2_t test_vcvt_f32_s32(int32x2_t a) {
-  //CHECK: test_vcvt_f32_s32
+  //CHECK-LABEL: test_vcvt_f32_s32
   return vcvt_f32_s32(a);
   //CHECK: scvtf v{{[0-9]+}}.2s, v{{[0-9]+}}.2s
 }
 
 float32x2_t test_vcvt_f32_u32(uint32x2_t a) {
-  //CHECK: test_vcvt_f32_u32
+  //CHECK-LABEL: test_vcvt_f32_u32
   return vcvt_f32_u32(a);
   //CHECK: ucvtf v{{[0-9]+}}.2s, v{{[0-9]+}}.2s
 }
 
 float32x4_t test_vcvtq_f32_s32(int32x4_t a) {
-  //CHECK: test_vcvtq_f32_s32
+  //CHECK-LABEL: test_vcvtq_f32_s32
   return vcvtq_f32_s32(a);
   //CHECK: scvtf v{{[0-9]+}}.4s, v{{[0-9]+}}.4s
 }
 
 float32x4_t test_vcvtq_f32_u32(uint32x4_t a) {
-  //CHECK: test_vcvtq_f32_u32
+  //CHECK-LABEL: test_vcvtq_f32_u32
   return vcvtq_f32_u32(a);
   //CHECK: ucvtf v{{[0-9]+}}.4s, v{{[0-9]+}}.4s
 }
 
 float64x2_t test_vcvtq_f64_s64(int64x2_t a) {
-  //CHECK: test_vcvtq_f64_s64
+  //CHECK-LABEL: test_vcvtq_f64_s64
   return vcvtq_f64_s64(a);
   //CHECK: scvtf v{{[0-9]+}}.2d, v{{[0-9]+}}.2d
 }
 
 float64x2_t test_vcvtq_f64_u64(uint64x2_t a) {
-  //CHECK: test_vcvtq_f64_u64
+  //CHECK-LABEL: test_vcvtq_f64_u64
   return vcvtq_f64_u64(a);
   //CHECK: ucvtf v{{[0-9]+}}.2d, v{{[0-9]+}}.2d
 }
diff --git a/test/CodeGen/aarch64-neon-perm.c b/test/CodeGen/aarch64-neon-perm.c
index 903570b..07edc11 100644
--- a/test/CodeGen/aarch64-neon-perm.c
+++ b/test/CodeGen/aarch64-neon-perm.c
@@ -1,1092 +1,1091 @@
 // REQUIRES: aarch64-registered-target
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +neon \
+// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \
 // RUN:   -ffp-contract=fast -S -O3 -o - %s | FileCheck %s
 
 // Test new aarch64 intrinsics and types
-
 #include <arm_neon.h>
 
 int8x8_t test_vuzp1_s8(int8x8_t a, int8x8_t b) {
-  // CHECK: test_vuzp1_s8
+  // CHECK-LABEL: test_vuzp1_s8
   return vuzp1_s8(a, b);
   // CHECK: uzp1 {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 int8x16_t test_vuzp1q_s8(int8x16_t a, int8x16_t b) {
-  // CHECK: test_vuzp1q_s8
+  // CHECK-LABEL: test_vuzp1q_s8
   return vuzp1q_s8(a, b);
   // CHECK: uzp1 {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 int16x4_t test_vuzp1_s16(int16x4_t a, int16x4_t b) {
-  // CHECK: test_vuzp1_s16
+  // CHECK-LABEL: test_vuzp1_s16
   return vuzp1_s16(a, b);
   // CHECK: uzp1 {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 int16x8_t test_vuzp1q_s16(int16x8_t a, int16x8_t b) {
-  // CHECK: test_vuzp1q_s16
+  // CHECK-LABEL: test_vuzp1q_s16
   return vuzp1q_s16(a, b);
   // CHECK: uzp1 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int32x2_t test_vuzp1_s32(int32x2_t a, int32x2_t b) {
-  // CHECK: test_vuzp1_s32
+  // CHECK-LABEL: test_vuzp1_s32
   return vuzp1_s32(a, b);
-  // CHECK: ins {{v[0-9]+}}.s[1], {{v[0-9]+}}.s[0]
+  // CHECK: {{ins v[0-9]+.s\[1\], v[0-9]+.s\[0\]|zip1 v0.2s, v0.2s, v1.2s}}
 }
 
 int32x4_t test_vuzp1q_s32(int32x4_t a, int32x4_t b) {
-  // CHECK: test_vuzp1q_s32
+  // CHECK-LABEL: test_vuzp1q_s32
   return vuzp1q_s32(a, b);
   // CHECK: uzp1 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 int64x2_t test_vuzp1q_s64(int64x2_t a, int64x2_t b) {
-  // CHECK: test_vuzp1q_s64
+  // CHECK-LABEL: test_vuzp1q_s64
   return vuzp1q_s64(a, b);
-  // CHECK: ins {{v[0-9]+}}.d[1], {{v[0-9]+}}.d[0]
+  // CHECK: {{ins v[0-9]+.d\[1\], v[0-9]+.d\[0\]|zip1 v0.2d, v0.2d, v1.2d}}
 }
 
 uint8x8_t test_vuzp1_u8(uint8x8_t a, uint8x8_t b) {
-  // CHECK: test_vuzp1_u8
+  // CHECK-LABEL: test_vuzp1_u8
   return vuzp1_u8(a, b);
   // CHECK: uzp1 {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint8x16_t test_vuzp1q_u8(uint8x16_t a, uint8x16_t b) {
-  // CHECK: test_vuzp1q_u8
+  // CHECK-LABEL: test_vuzp1q_u8
   return vuzp1q_u8(a, b);
   // CHECK: uzp1 {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint16x4_t test_vuzp1_u16(uint16x4_t a, uint16x4_t b) {
-  // CHECK: test_vuzp1_u16
+  // CHECK-LABEL: test_vuzp1_u16
   return vuzp1_u16(a, b);
   // CHECK: uzp1 {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint16x8_t test_vuzp1q_u16(uint16x8_t a, uint16x8_t b) {
-  // CHECK: test_vuzp1q_u16
+  // CHECK-LABEL: test_vuzp1q_u16
   return vuzp1q_u16(a, b);
   // CHECK: uzp1 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint32x2_t test_vuzp1_u32(uint32x2_t a, uint32x2_t b) {
-  // CHECK: test_vuzp1_u32
+  // CHECK-LABEL: test_vuzp1_u32
   return vuzp1_u32(a, b);
-  // CHECK: ins {{v[0-9]+}}.s[1], {{v[0-9]+}}.s[0]
+  // CHECK: {{ins v[0-9]+.s\[1\], v[0-9]+.s\[0\]|zip1 v0.2s, v0.2s, v1.2s}}
 }
 
 uint32x4_t test_vuzp1q_u32(uint32x4_t a, uint32x4_t b) {
-  // CHECK: test_vuzp1q_u32
+  // CHECK-LABEL: test_vuzp1q_u32
   return vuzp1q_u32(a, b);
   // CHECK: uzp1 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint64x2_t test_vuzp1q_u64(uint64x2_t a, uint64x2_t b) {
-  // CHECK: test_vuzp1q_u64
+  // CHECK-LABEL: test_vuzp1q_u64
   return vuzp1q_u64(a, b);
-  // CHECK: ins {{v[0-9]+}}.d[1], {{v[0-9]+}}.d[0]
+  // CHECK: {{ins v[0-9]+.d\[1\], v[0-9]+.d\[0\]|zip1 v0.2d, v0.2d, v1.2d}}
 }
 
 float32x2_t test_vuzp1_f32(float32x2_t a, float32x2_t b) {
-  // CHECK: test_vuzp1_f32
+  // CHECK-LABEL: test_vuzp1_f32
   return vuzp1_f32(a, b);
-  // CHECK: ins {{v[0-9]+}}.s[1], {{v[0-9]+}}.s[0]
+  // CHECK: {{ins v[0-9]+.s\[1\], v[0-9]+.s\[0\]|zip1 v0.2s, v0.2s, v1.2s}}
 }
 
 float32x4_t test_vuzp1q_f32(float32x4_t a, float32x4_t b) {
-  // CHECK: test_vuzp1q_f32
+  // CHECK-LABEL: test_vuzp1q_f32
   return vuzp1q_f32(a, b);
   // CHECK: uzp1 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 float64x2_t test_vuzp1q_f64(float64x2_t a, float64x2_t b) {
-  // CHECK: test_vuzp1q_f64
+  // CHECK-LABEL: test_vuzp1q_f64
   return vuzp1q_f64(a, b);
-  // CHECK: ins {{v[0-9]+}}.d[1], {{v[0-9]+}}.d[0]
+  // CHECK: {{ins v[0-9]+.d\[1\], v[0-9]+.d\[0\]|zip1 v0.2d, v0.2d, v1.2d}}
 }
 
 poly8x8_t test_vuzp1_p8(poly8x8_t a, poly8x8_t b) {
-  // CHECK: test_vuzp1_p8
+  // CHECK-LABEL: test_vuzp1_p8
   return vuzp1_p8(a, b);
   // CHECK: uzp1 {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 poly8x16_t test_vuzp1q_p8(poly8x16_t a, poly8x16_t b) {
-  // CHECK: test_vuzp1q_p8
+  // CHECK-LABEL: test_vuzp1q_p8
   return vuzp1q_p8(a, b);
   // CHECK: uzp1 {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 poly16x4_t test_vuzp1_p16(poly16x4_t a, poly16x4_t b) {
-  // CHECK: test_vuzp1_p16
+  // CHECK-LABEL: test_vuzp1_p16
   return vuzp1_p16(a, b);
   // CHECK: uzp1 {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 poly16x8_t test_vuzp1q_p16(poly16x8_t a, poly16x8_t b) {
-  // CHECK: test_vuzp1q_p16
+  // CHECK-LABEL: test_vuzp1q_p16
   return vuzp1q_p16(a, b);
   // CHECK: uzp1 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int8x8_t test_vuzp2_s8(int8x8_t a, int8x8_t b) {
-  // CHECK: test_vuzp2_s8
+  // CHECK-LABEL: test_vuzp2_s8
   return vuzp2_s8(a, b);
   // CHECK: uzp2 {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 int8x16_t test_vuzp2q_s8(int8x16_t a, int8x16_t b) {
-  // CHECK: test_vuzp2q_s8
+  // CHECK-LABEL: test_vuzp2q_s8
   return vuzp2q_s8(a, b);
   // CHECK: uzp2 {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 int16x4_t test_vuzp2_s16(int16x4_t a, int16x4_t b) {
-  // CHECK: test_vuzp2_s16
+  // CHECK-LABEL: test_vuzp2_s16
   return vuzp2_s16(a, b);
   // CHECK: uzp2 {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 int16x8_t test_vuzp2q_s16(int16x8_t a, int16x8_t b) {
-  // CHECK: test_vuzp2q_s16
+  // CHECK-LABEL: test_vuzp2q_s16
   return vuzp2q_s16(a, b);
   // CHECK: uzp2 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int32x2_t test_vuzp2_s32(int32x2_t a, int32x2_t b) {
-  // CHECK: test_vuzp2_s32
+  // CHECK-LABEL: test_vuzp2_s32
   return vuzp2_s32(a, b);
-  // CHECK: ins {{v[0-9]+}}.s[0], {{v[0-9]+}}.s[1]
+  // CHECK: {{ins v[0-9]+.s\[0\], v[0-9]+.s\[1\]|zip2 v0.2s, v0.2s, v1.2s}}
 }
 
 int32x4_t test_vuzp2q_s32(int32x4_t a, int32x4_t b) {
-  // CHECK: test_vuzp2q_s32
+  // CHECK-LABEL: test_vuzp2q_s32
   return vuzp2q_s32(a, b);
   // CHECK: uzp2 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 int64x2_t test_vuzp2q_s64(int64x2_t a, int64x2_t b) {
-  // CHECK: test_vuzp2q_s64
+  // CHECK-LABEL: test_vuzp2q_s64
   return vuzp2q_s64(a, b);
-  // CHECK: ins {{v[0-9]+}}.d[0], {{v[0-9]+}}.d[1]
+  // CHECK: {{ins v[0-9]+.d\[0\], v[0-9]+.d\[1\]|zip2 v0.2d, v0.2d, v1.2d}}
 }
 
 uint8x8_t test_vuzp2_u8(uint8x8_t a, uint8x8_t b) {
-  // CHECK: test_vuzp2_u8
+  // CHECK-LABEL: test_vuzp2_u8
   return vuzp2_u8(a, b);
   // CHECK: uzp2 {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint8x16_t test_vuzp2q_u8(uint8x16_t a, uint8x16_t b) {
-  // CHECK: test_vuzp2q_u8
+  // CHECK-LABEL: test_vuzp2q_u8
   return vuzp2q_u8(a, b);
   // CHECK: uzp2 {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint16x4_t test_vuzp2_u16(uint16x4_t a, uint16x4_t b) {
-  // CHECK: test_vuzp2_u16
+  // CHECK-LABEL: test_vuzp2_u16
   return vuzp2_u16(a, b);
   // CHECK: uzp2 {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint16x8_t test_vuzp2q_u16(uint16x8_t a, uint16x8_t b) {
-  // CHECK: test_vuzp2q_u16
+  // CHECK-LABEL: test_vuzp2q_u16
   return vuzp2q_u16(a, b);
   // CHECK: uzp2 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint32x2_t test_vuzp2_u32(uint32x2_t a, uint32x2_t b) {
-  // CHECK: test_vuzp2_u32
+  // CHECK-LABEL: test_vuzp2_u32
   return vuzp2_u32(a, b);
-  // CHECK: ins {{v[0-9]+}}.s[0], {{v[0-9]+}}.s[1]
+  // CHECK: {{ins v[0-9]+.s\[0\], v[0-9]+.s\[1\]|zip2 v0.2s, v0.2s, v1.2s}}
 }
 
 uint32x4_t test_vuzp2q_u32(uint32x4_t a, uint32x4_t b) {
-  // CHECK: test_vuzp2q_u32
+  // CHECK-LABEL: test_vuzp2q_u32
   return vuzp2q_u32(a, b);
   // CHECK: uzp2 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint64x2_t test_vuzp2q_u64(uint64x2_t a, uint64x2_t b) {
-  // CHECK: test_vuzp2q_u64
+  // CHECK-LABEL: test_vuzp2q_u64
   return vuzp2q_u64(a, b);
-  // CHECK: ins {{v[0-9]+}}.d[0], {{v[0-9]+}}.d[1]
+  // CHECK: {{ins v[0-9]+.d\[0\], v[0-9]+.d\[1\]|zip2 v0.2d, v0.2d, v1.2d}}
 }
 
 float32x2_t test_vuzp2_f32(float32x2_t a, float32x2_t b) {
-  // CHECK: test_vuzp2_f32
+  // CHECK-LABEL: test_vuzp2_f32
   return vuzp2_f32(a, b);
-  // CHECK: ins {{v[0-9]+}}.s[0], {{v[0-9]+}}.s[1]
+  // CHECK: {{ins v[0-9]+.s\[0\], v[0-9]+.s\[1\]|zip2 v0.2s, v0.2s, v1.2s}}
 }
 
 float32x4_t test_vuzp2q_f32(float32x4_t a, float32x4_t b) {
-  // CHECK: test_vuzp2q_f32
+  // CHECK-LABEL: test_vuzp2q_f32
   return vuzp2q_f32(a, b);
   // CHECK: uzp2 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 float64x2_t test_vuzp2q_f64(float64x2_t a, float64x2_t b) {
-  // CHECK: test_vuzp2q_f64
+  // CHECK-LABEL: test_vuzp2q_f64
   return vuzp2q_f64(a, b);
-  // CHECK: ins {{v[0-9]+}}.d[0], {{v[0-9]+}}.d[1]
+  // CHECK: {{ins v[0-9]+.d\[0\], v[0-9]+.d\[1\]|zip2 v0.2d, v0.2d, v1.2d}}
 }
 
 poly8x8_t test_vuzp2_p8(poly8x8_t a, poly8x8_t b) {
-  // CHECK: test_vuzp2_p8
+  // CHECK-LABEL: test_vuzp2_p8
   return vuzp2_p8(a, b);
   // CHECK: uzp2 {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 poly8x16_t test_vuzp2q_p8(poly8x16_t a, poly8x16_t b) {
-  // CHECK: test_vuzp2q_p8
+  // CHECK-LABEL: test_vuzp2q_p8
   return vuzp2q_p8(a, b);
   // CHECK: uzp2 {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 poly16x4_t test_vuzp2_p16(poly16x4_t a, poly16x4_t b) {
-  // CHECK: test_vuzp2_p16
+  // CHECK-LABEL: test_vuzp2_p16
   return vuzp2_p16(a, b);
   // CHECK: uzp2 {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 poly16x8_t test_vuzp2q_p16(poly16x8_t a, poly16x8_t b) {
-  // CHECK: test_vuzp2q_p16
+  // CHECK-LABEL: test_vuzp2q_p16
   return vuzp2q_p16(a, b);
   // CHECK: uzp2 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int8x8_t test_vzip1_s8(int8x8_t a, int8x8_t b) {
-  // CHECK: test_vzip1_s8
+  // CHECK-LABEL: test_vzip1_s8
   return vzip1_s8(a, b);
   // CHECK: zip1 {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 int8x16_t test_vzip1q_s8(int8x16_t a, int8x16_t b) {
-  // CHECK: test_vzip1q_s8
+  // CHECK-LABEL: test_vzip1q_s8
   return vzip1q_s8(a, b);
   // CHECK: zip1 {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 int16x4_t test_vzip1_s16(int16x4_t a, int16x4_t b) {
-  // CHECK: test_vzip1_s16
+  // CHECK-LABEL: test_vzip1_s16
   return vzip1_s16(a, b);
   // CHECK: zip1 {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 int16x8_t test_vzip1q_s16(int16x8_t a, int16x8_t b) {
-  // CHECK: test_vzip1q_s16
+  // CHECK-LABEL: test_vzip1q_s16
   return vzip1q_s16(a, b);
   // CHECK: zip1 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int32x2_t test_vzip1_s32(int32x2_t a, int32x2_t b) {
-  // CHECK: test_vzip1_s32
+  // CHECK-LABEL: test_vzip1_s32
   return vzip1_s32(a, b);
-  // CHECK: ins {{v[0-9]+}}.s[1], {{v[0-9]+}}.s[0]
+  // CHECK: {{ins v[0-9]+.s\[1\], v[0-9]+.s\[0\]|zip1 v0.2s, v0.2s, v1.2s}}
 }
 
 int32x4_t test_vzip1q_s32(int32x4_t a, int32x4_t b) {
-  // CHECK: test_vzip1q_s32
+  // CHECK-LABEL: test_vzip1q_s32
   return vzip1q_s32(a, b);
   // CHECK: zip1 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 int64x2_t test_vzip1q_s64(int64x2_t a, int64x2_t b) {
-  // CHECK: test_vzip1q_s64
+  // CHECK-LABEL: test_vzip1q_s64
   return vzip1q_s64(a, b);
-  // CHECK: ins {{v[0-9]+}}.d[1], {{v[0-9]+}}.d[0]
+  // CHECK: {{ins v[0-9]+.d\[1\], v[0-9]+.d\[0\]|zip1 v0.2d, v0.2d, v1.2d}}
 }
 
 uint8x8_t test_vzip1_u8(uint8x8_t a, uint8x8_t b) {
-  // CHECK: test_vzip1_u8
+  // CHECK-LABEL: test_vzip1_u8
   return vzip1_u8(a, b);
   // CHECK: zip1 {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint8x16_t test_vzip1q_u8(uint8x16_t a, uint8x16_t b) {
-  // CHECK: test_vzip1q_u8
+  // CHECK-LABEL: test_vzip1q_u8
   return vzip1q_u8(a, b);
   // CHECK: zip1 {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint16x4_t test_vzip1_u16(uint16x4_t a, uint16x4_t b) {
-  // CHECK: test_vzip1_u16
+  // CHECK-LABEL: test_vzip1_u16
   return vzip1_u16(a, b);
   // CHECK: zip1 {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint16x8_t test_vzip1q_u16(uint16x8_t a, uint16x8_t b) {
-  // CHECK: test_vzip1q_u16
+  // CHECK-LABEL: test_vzip1q_u16
   return vzip1q_u16(a, b);
   // CHECK: zip1 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint32x2_t test_vzip1_u32(uint32x2_t a, uint32x2_t b) {
-  // CHECK: test_vzip1_u32
+  // CHECK-LABEL: test_vzip1_u32
   return vzip1_u32(a, b);
-  // CHECK: ins {{v[0-9]+}}.s[1], {{v[0-9]+}}.s[0]
+  // CHECK: {{ins v[0-9]+.s\[1\], v[0-9]+.s\[0\]|zip1 v0.2s, v0.2s, v1.2s}}
 }
 
 uint32x4_t test_vzip1q_u32(uint32x4_t a, uint32x4_t b) {
-  // CHECK: test_vzip1q_u32
+  // CHECK-LABEL: test_vzip1q_u32
   return vzip1q_u32(a, b);
   // CHECK: zip1 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint64x2_t test_vzip1q_u64(uint64x2_t a, uint64x2_t b) {
-  // CHECK: test_vzip1q_u64
+  // CHECK-LABEL: test_vzip1q_u64
   return vzip1q_u64(a, b);
-  // CHECK: ins {{v[0-9]+}}.d[1], {{v[0-9]+}}.d[0]
+  // CHECK: {{ins v[0-9]+.d\[1\], v[0-9]+.d\[0\]|zip1 v0.2d, v0.2d, v1.2d}}
 }
 
 float32x2_t test_vzip1_f32(float32x2_t a, float32x2_t b) {
-  // CHECK: test_vzip1_f32
+  // CHECK-LABEL: test_vzip1_f32
   return vzip1_f32(a, b);
-  // CHECK: ins {{v[0-9]+}}.s[1], {{v[0-9]+}}.s[0]
+  // CHECK: {{ins v[0-9]+.s\[1\], v[0-9]+.s\[0\]|zip1 v0.2s, v0.2s, v1.2s}}
 }
 
 float32x4_t test_vzip1q_f32(float32x4_t a, float32x4_t b) {
-  // CHECK: test_vzip1q_f32
+  // CHECK-LABEL: test_vzip1q_f32
   return vzip1q_f32(a, b);
   // CHECK: zip1 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 float64x2_t test_vzip1q_f64(float64x2_t a, float64x2_t b) {
-  // CHECK: test_vzip1q_f64
+  // CHECK-LABEL: test_vzip1q_f64
   return vzip1q_f64(a, b);
-  // CHECK: ins {{v[0-9]+}}.d[1], {{v[0-9]+}}.d[0]
+  // CHECK: {{ins v[0-9]+.d\[1\], v[0-9]+.d\[0\]|zip1 v0.2d, v0.2d, v1.2d}}
 }
 
 poly8x8_t test_vzip1_p8(poly8x8_t a, poly8x8_t b) {
-  // CHECK: test_vzip1_p8
+  // CHECK-LABEL: test_vzip1_p8
   return vzip1_p8(a, b);
   // CHECK: zip1 {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 poly8x16_t test_vzip1q_p8(poly8x16_t a, poly8x16_t b) {
-  // CHECK: test_vzip1q_p8
+  // CHECK-LABEL: test_vzip1q_p8
   return vzip1q_p8(a, b);
   // CHECK: zip1 {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 poly16x4_t test_vzip1_p16(poly16x4_t a, poly16x4_t b) {
-  // CHECK: test_vzip1_p16
+  // CHECK-LABEL: test_vzip1_p16
   return vzip1_p16(a, b);
   // CHECK: zip1 {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 poly16x8_t test_vzip1q_p16(poly16x8_t a, poly16x8_t b) {
-  // CHECK: test_vzip1q_p16
+  // CHECK-LABEL: test_vzip1q_p16
   return vzip1q_p16(a, b);
   // CHECK: zip1 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int8x8_t test_vzip2_s8(int8x8_t a, int8x8_t b) {
-  // CHECK: test_vzip2_s8
+  // CHECK-LABEL: test_vzip2_s8
   return vzip2_s8(a, b);
   // CHECK: zip2 {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 int8x16_t test_vzip2q_s8(int8x16_t a, int8x16_t b) {
-  // CHECK: test_vzip2q_s8
+  // CHECK-LABEL: test_vzip2q_s8
   return vzip2q_s8(a, b);
   // CHECK: zip2 {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 int16x4_t test_vzip2_s16(int16x4_t a, int16x4_t b) {
-  // CHECK: test_vzip2_s16
+  // CHECK-LABEL: test_vzip2_s16
   return vzip2_s16(a, b);
   // CHECK: zip2 {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 int16x8_t test_vzip2q_s16(int16x8_t a, int16x8_t b) {
-  // CHECK: test_vzip2q_s16
+  // CHECK-LABEL: test_vzip2q_s16
   return vzip2q_s16(a, b);
   // CHECK: zip2 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int32x2_t test_vzip2_s32(int32x2_t a, int32x2_t b) {
-  // CHECK: test_vzip2_s32
+  // CHECK-LABEL: test_vzip2_s32
   return vzip2_s32(a, b);
-  // CHECK: ins {{v[0-9]+}}.s[0], {{v[0-9]+}}.s[1]
+  // CHECK: {{ins v[0-9]+.s\[0\], v[0-9]+.s\[1\]|zip2 v0.2s, v0.2s, v1.2s}}
 }
 
 int32x4_t test_vzip2q_s32(int32x4_t a, int32x4_t b) {
-  // CHECK: test_vzip2q_s32
+  // CHECK-LABEL: test_vzip2q_s32
   return vzip2q_s32(a, b);
   // CHECK: zip2 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 int64x2_t test_vzip2q_s64(int64x2_t a, int64x2_t b) {
-  // CHECK: test_vzip2q_s64
+  // CHECK-LABEL: test_vzip2q_s64
   return vzip2q_s64(a, b);
-  // CHECK: ins {{v[0-9]+}}.d[0], {{v[0-9]+}}.d[1]
+  // CHECK: {{ins v[0-9]+.d\[0\], v[0-9]+.d\[1\]|zip2 v0.2d, v0.2d, v1.2d}}
 }
 
 uint8x8_t test_vzip2_u8(uint8x8_t a, uint8x8_t b) {
-  // CHECK: test_vzip2_u8
+  // CHECK-LABEL: test_vzip2_u8
   return vzip2_u8(a, b);
   // CHECK: zip2 {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint8x16_t test_vzip2q_u8(uint8x16_t a, uint8x16_t b) {
-  // CHECK: test_vzip2q_u8
+  // CHECK-LABEL: test_vzip2q_u8
   return vzip2q_u8(a, b);
   // CHECK: zip2 {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint16x4_t test_vzip2_u16(uint16x4_t a, uint16x4_t b) {
-  // CHECK: test_vzip2_u16
+  // CHECK-LABEL: test_vzip2_u16
   return vzip2_u16(a, b);
   // CHECK: zip2 {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint16x8_t test_vzip2q_u16(uint16x8_t a, uint16x8_t b) {
-  // CHECK: test_vzip2q_u16
+  // CHECK-LABEL: test_vzip2q_u16
   return vzip2q_u16(a, b);
   // CHECK: zip2 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint32x2_t test_vzip2_u32(uint32x2_t a, uint32x2_t b) {
-  // CHECK: test_vzip2_u32
+  // CHECK-LABEL: test_vzip2_u32
   return vzip2_u32(a, b);
-  // CHECK: ins {{v[0-9]+}}.s[0], {{v[0-9]+}}.s[1]
+  // CHECK: {{ins v[0-9]+.s\[0\], v[0-9]+.s\[1\]|zip2 v0.2s, v0.2s, v1.2s}}
 }
 
 uint32x4_t test_vzip2q_u32(uint32x4_t a, uint32x4_t b) {
-  // CHECK: test_vzip2q_u32
+  // CHECK-LABEL: test_vzip2q_u32
   return vzip2q_u32(a, b);
   // CHECK: zip2 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint64x2_t test_vzip2q_u64(uint64x2_t a, uint64x2_t b) {
-  // CHECK: test_vzip2q_u64
+  // CHECK-LABEL: test_vzip2q_u64
   return vzip2q_u64(a, b);
-  // CHECK: ins {{v[0-9]+}}.d[0], {{v[0-9]+}}.d[1]
+  // CHECK: {{ins v[0-9]+.d\[0\], v[0-9]+.d\[1\]|zip2 v0.2d, v0.2d, v1.2d}}
 }
 
 float32x2_t test_vzip2_f32(float32x2_t a, float32x2_t b) {
-  // CHECK: test_vzip2_f32
+  // CHECK-LABEL: test_vzip2_f32
   return vzip2_f32(a, b);
-  // CHECK: ins {{v[0-9]+}}.s[0], {{v[0-9]+}}.s[1]
+  // CHECK: {{ins v[0-9]+.s\[0\], v[0-9]+.s\[1\]|zip2 v0.2s, v0.2s, v1.2s}}
 }
 
 float32x4_t test_vzip2q_f32(float32x4_t a, float32x4_t b) {
-  // CHECK: test_vzip2q_f32
+  // CHECK-LABEL: test_vzip2q_f32
   return vzip2q_f32(a, b);
   // CHECK: zip2 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 float64x2_t test_vzip2q_f64(float64x2_t a, float64x2_t b) {
-  // CHECK: test_vzip2q_f64
+  // CHECK-LABEL: test_vzip2q_f64
   return vzip2q_f64(a, b);
-  // CHECK: ins {{v[0-9]+}}.d[0], {{v[0-9]+}}.d[1]
+  // CHECK: {{ins v[0-9]+.d\[0\], v[0-9]+.d\[1\]|zip2 v0.2d, v0.2d, v1.2d}}
 }
 
 poly8x8_t test_vzip2_p8(poly8x8_t a, poly8x8_t b) {
-  // CHECK: test_vzip2_p8
+  // CHECK-LABEL: test_vzip2_p8
   return vzip2_p8(a, b);
   // CHECK: zip2 {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 poly8x16_t test_vzip2q_p8(poly8x16_t a, poly8x16_t b) {
-  // CHECK: test_vzip2q_p8
+  // CHECK-LABEL: test_vzip2q_p8
   return vzip2q_p8(a, b);
   // CHECK: zip2 {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 poly16x4_t test_vzip2_p16(poly16x4_t a, poly16x4_t b) {
-  // CHECK: test_vzip2_p16
+  // CHECK-LABEL: test_vzip2_p16
   return vzip2_p16(a, b);
   // CHECK: zip2 {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 poly16x8_t test_vzip2q_p16(poly16x8_t a, poly16x8_t b) {
-  // CHECK: test_vzip2q_p16
+  // CHECK-LABEL: test_vzip2q_p16
   return vzip2q_p16(a, b);
   // CHECK: zip2 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int8x8_t test_vtrn1_s8(int8x8_t a, int8x8_t b) {
-  // CHECK: test_vtrn1_s8
+  // CHECK-LABEL: test_vtrn1_s8
   return vtrn1_s8(a, b);
   // CHECK: trn1 {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 int8x16_t test_vtrn1q_s8(int8x16_t a, int8x16_t b) {
-  // CHECK: test_vtrn1q_s8
+  // CHECK-LABEL: test_vtrn1q_s8
   return vtrn1q_s8(a, b);
   // CHECK: trn1 {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 int16x4_t test_vtrn1_s16(int16x4_t a, int16x4_t b) {
-  // CHECK: test_vtrn1_s16
+  // CHECK-LABEL: test_vtrn1_s16
   return vtrn1_s16(a, b);
   // CHECK: trn1 {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 int16x8_t test_vtrn1q_s16(int16x8_t a, int16x8_t b) {
-  // CHECK: test_vtrn1q_s16
+  // CHECK-LABEL: test_vtrn1q_s16
   return vtrn1q_s16(a, b);
   // CHECK: trn1 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int32x2_t test_vtrn1_s32(int32x2_t a, int32x2_t b) {
-  // CHECK: test_vtrn1_s32
+  // CHECK-LABEL: test_vtrn1_s32
   return vtrn1_s32(a, b);
-  // CHECK: ins {{v[0-9]+}}.s[1], {{v[0-9]+}}.s[0]
+  // CHECK: {{ins v[0-9]+.s\[1\], v[0-9]+.s\[0\]|zip1 v0.2s, v0.2s, v1.2s}}
 }
 
 int32x4_t test_vtrn1q_s32(int32x4_t a, int32x4_t b) {
-  // CHECK: test_vtrn1q_s32
+  // CHECK-LABEL: test_vtrn1q_s32
   return vtrn1q_s32(a, b);
   // CHECK: trn1 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 int64x2_t test_vtrn1q_s64(int64x2_t a, int64x2_t b) {
-  // CHECK: test_vtrn1q_s64
+  // CHECK-LABEL: test_vtrn1q_s64
   return vtrn1q_s64(a, b);
-  // CHECK: ins {{v[0-9]+}}.d[1], {{v[0-9]+}}.d[0]
+  // CHECK: {{ins v[0-9]+.d\[1\], v[0-9]+.d\[0\]|zip1 v0.2d, v0.2d, v1.2d}}
 }
 
 uint8x8_t test_vtrn1_u8(uint8x8_t a, uint8x8_t b) {
-  // CHECK: test_vtrn1_u8
+  // CHECK-LABEL: test_vtrn1_u8
   return vtrn1_u8(a, b);
   // CHECK: trn1 {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint8x16_t test_vtrn1q_u8(uint8x16_t a, uint8x16_t b) {
-  // CHECK: test_vtrn1q_u8
+  // CHECK-LABEL: test_vtrn1q_u8
   return vtrn1q_u8(a, b);
   // CHECK: trn1 {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint16x4_t test_vtrn1_u16(uint16x4_t a, uint16x4_t b) {
-  // CHECK: test_vtrn1_u16
+  // CHECK-LABEL: test_vtrn1_u16
   return vtrn1_u16(a, b);
   // CHECK: trn1 {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint16x8_t test_vtrn1q_u16(uint16x8_t a, uint16x8_t b) {
-  // CHECK: test_vtrn1q_u16
+  // CHECK-LABEL: test_vtrn1q_u16
   return vtrn1q_u16(a, b);
   // CHECK: trn1 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint32x2_t test_vtrn1_u32(uint32x2_t a, uint32x2_t b) {
-  // CHECK: test_vtrn1_u32
+  // CHECK-LABEL: test_vtrn1_u32
   return vtrn1_u32(a, b);
-  // CHECK: ins {{v[0-9]+}}.s[1], {{v[0-9]+}}.s[0]
+  // CHECK: {{ins v[0-9]+.s\[1\], v[0-9]+.s\[0\]|zip1 v0.2s, v0.2s, v1.2s}}
 }
 
 uint32x4_t test_vtrn1q_u32(uint32x4_t a, uint32x4_t b) {
-  // CHECK: test_vtrn1q_u32
+  // CHECK-LABEL: test_vtrn1q_u32
   return vtrn1q_u32(a, b);
   // CHECK: trn1 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint64x2_t test_vtrn1q_u64(uint64x2_t a, uint64x2_t b) {
-  // CHECK: test_vtrn1q_u64
+  // CHECK-LABEL: test_vtrn1q_u64
   return vtrn1q_u64(a, b);
-  // CHECK: ins {{v[0-9]+}}.d[1], {{v[0-9]+}}.d[0]
+  // CHECK: {{ins v[0-9]+.d\[1\], v[0-9]+.d\[0\]|zip1 v0.2d, v0.2d, v1.2d}}
 }
 
 float32x2_t test_vtrn1_f32(float32x2_t a, float32x2_t b) {
-  // CHECK: test_vtrn1_f32
+  // CHECK-LABEL: test_vtrn1_f32
   return vtrn1_f32(a, b);
-  // CHECK: ins {{v[0-9]+}}.s[1], {{v[0-9]+}}.s[0]
+  // CHECK: {{ins v[0-9]+.s\[1\], v[0-9]+.s\[0\]|zip1 v0.2s, v0.2s, v1.2s}}
 }
 
 float32x4_t test_vtrn1q_f32(float32x4_t a, float32x4_t b) {
-  // CHECK: test_vtrn1q_f32
+  // CHECK-LABEL: test_vtrn1q_f32
   return vtrn1q_f32(a, b);
   // CHECK: trn1 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 float64x2_t test_vtrn1q_f64(float64x2_t a, float64x2_t b) {
-  // CHECK: test_vtrn1q_f64
+  // CHECK-LABEL: test_vtrn1q_f64
   return vtrn1q_f64(a, b);
-  // CHECK: ins {{v[0-9]+}}.d[1], {{v[0-9]+}}.d[0]
+  // CHECK: {{ins v[0-9]+.d\[1\], v[0-9]+.d\[0\]|zip1 v0.2d, v0.2d, v1.2d}}
 }
 
 poly8x8_t test_vtrn1_p8(poly8x8_t a, poly8x8_t b) {
-  // CHECK: test_vtrn1_p8
+  // CHECK-LABEL: test_vtrn1_p8
   return vtrn1_p8(a, b);
   // CHECK: trn1 {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 poly8x16_t test_vtrn1q_p8(poly8x16_t a, poly8x16_t b) {
-  // CHECK: test_vtrn1q_p8
+  // CHECK-LABEL: test_vtrn1q_p8
   return vtrn1q_p8(a, b);
   // CHECK: trn1 {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 poly16x4_t test_vtrn1_p16(poly16x4_t a, poly16x4_t b) {
-  // CHECK: test_vtrn1_p16
+  // CHECK-LABEL: test_vtrn1_p16
   return vtrn1_p16(a, b);
   // CHECK: trn1 {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 poly16x8_t test_vtrn1q_p16(poly16x8_t a, poly16x8_t b) {
-  // CHECK: test_vtrn1q_p16
+  // CHECK-LABEL: test_vtrn1q_p16
   return vtrn1q_p16(a, b);
   // CHECK: trn1 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int8x8_t test_vtrn2_s8(int8x8_t a, int8x8_t b) {
-  // CHECK: test_vtrn2_s8
+  // CHECK-LABEL: test_vtrn2_s8
   return vtrn2_s8(a, b);
   // CHECK: trn2 {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 int8x16_t test_vtrn2q_s8(int8x16_t a, int8x16_t b) {
-  // CHECK: test_vtrn2q_s8
+  // CHECK-LABEL: test_vtrn2q_s8
   return vtrn2q_s8(a, b);
   // CHECK: trn2 {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 int16x4_t test_vtrn2_s16(int16x4_t a, int16x4_t b) {
-  // CHECK: test_vtrn2_s16
+  // CHECK-LABEL: test_vtrn2_s16
   return vtrn2_s16(a, b);
   // CHECK: trn2 {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 int16x8_t test_vtrn2q_s16(int16x8_t a, int16x8_t b) {
-  // CHECK: test_vtrn2q_s16
+  // CHECK-LABEL: test_vtrn2q_s16
   return vtrn2q_s16(a, b);
   // CHECK: trn2 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int32x2_t test_vtrn2_s32(int32x2_t a, int32x2_t b) {
-  // CHECK: test_vtrn2_s32
+  // CHECK-LABEL: test_vtrn2_s32
   return vtrn2_s32(a, b);
-  // CHECK: ins {{v[0-9]+}}.s[0], {{v[0-9]+}}.s[1]
+  // CHECK: {{ins v[0-9]+.s\[0\], v[0-9]+.s\[1\]|zip2 v0.2s, v0.2s, v1.2s}}
 }
 
 int32x4_t test_vtrn2q_s32(int32x4_t a, int32x4_t b) {
-  // CHECK: test_vtrn2q_s32
+  // CHECK-LABEL: test_vtrn2q_s32
   return vtrn2q_s32(a, b);
   // CHECK: trn2 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 int64x2_t test_vtrn2q_s64(int64x2_t a, int64x2_t b) {
-  // CHECK: test_vtrn2q_s64
+  // CHECK-LABEL: test_vtrn2q_s64
   return vtrn2q_s64(a, b);
-  // CHECK: ins {{v[0-9]+}}.d[0], {{v[0-9]+}}.d[1]
+  // CHECK: {{ins v[0-9]+.d\[0\], v[0-9]+.d\[1\]|zip2 v0.2d, v0.2d, v1.2d}}
 }
 
 uint8x8_t test_vtrn2_u8(uint8x8_t a, uint8x8_t b) {
-  // CHECK: test_vtrn2_u8
+  // CHECK-LABEL: test_vtrn2_u8
   return vtrn2_u8(a, b);
   // CHECK: trn2 {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint8x16_t test_vtrn2q_u8(uint8x16_t a, uint8x16_t b) {
-  // CHECK: test_vtrn2q_u8
+  // CHECK-LABEL: test_vtrn2q_u8
   return vtrn2q_u8(a, b);
   // CHECK: trn2 {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 uint16x4_t test_vtrn2_u16(uint16x4_t a, uint16x4_t b) {
-  // CHECK: test_vtrn2_u16
+  // CHECK-LABEL: test_vtrn2_u16
   return vtrn2_u16(a, b);
   // CHECK: trn2 {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 uint16x8_t test_vtrn2q_u16(uint16x8_t a, uint16x8_t b) {
-  // CHECK: test_vtrn2q_u16
+  // CHECK-LABEL: test_vtrn2q_u16
   return vtrn2q_u16(a, b);
   // CHECK: trn2 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 uint32x2_t test_vtrn2_u32(uint32x2_t a, uint32x2_t b) {
-  // CHECK: test_vtrn2_u32
+  // CHECK-LABEL: test_vtrn2_u32
   return vtrn2_u32(a, b);
-  // CHECK: ins {{v[0-9]+}}.s[0], {{v[0-9]+}}.s[1]
+  // CHECK: {{ins v[0-9]+.s\[0\], v[0-9]+.s\[1\]|zip2 v0.2s, v0.2s, v1.2s}}
 }
 
 uint32x4_t test_vtrn2q_u32(uint32x4_t a, uint32x4_t b) {
-  // CHECK: test_vtrn2q_u32
+  // CHECK-LABEL: test_vtrn2q_u32
   return vtrn2q_u32(a, b);
   // CHECK: trn2 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 uint64x2_t test_vtrn2q_u64(uint64x2_t a, uint64x2_t b) {
-  // CHECK: test_vtrn2q_u64
+  // CHECK-LABEL: test_vtrn2q_u64
   return vtrn2q_u64(a, b);
-  // CHECK: ins {{v[0-9]+}}.d[0], {{v[0-9]+}}.d[1]
+  // CHECK: {{ins v[0-9]+.d\[0\], v[0-9]+.d\[1\]|zip2 v0.2d, v0.2d, v1.2d}}
 }
 
 float32x2_t test_vtrn2_f32(float32x2_t a, float32x2_t b) {
-  // CHECK: test_vtrn2_f32
+  // CHECK-LABEL: test_vtrn2_f32
   return vtrn2_f32(a, b);
-  // CHECK: ins {{v[0-9]+}}.s[0], {{v[0-9]+}}.s[1]
+  // CHECK: {{ins v[0-9]+.s\[0\], v[0-9]+.s\[1\]|zip2 v0.2s, v0.2s, v1.2s}}
 }
 
 float32x4_t test_vtrn2q_f32(float32x4_t a, float32x4_t b) {
-  // CHECK: test_vtrn2q_f32
+  // CHECK-LABEL: test_vtrn2q_f32
   return vtrn2q_f32(a, b);
   // CHECK: trn2 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 
 float64x2_t test_vtrn2q_f64(float64x2_t a, float64x2_t b) {
-  // CHECK: test_vtrn2q_f64
+  // CHECK-LABEL: test_vtrn2q_f64
   return vtrn2q_f64(a, b);
-  // CHECK: ins {{v[0-9]+}}.d[0], {{v[0-9]+}}.d[1]
+  // CHECK: {{ins v[0-9]+.d\[0\], v[0-9]+.d\[1\]|zip2 v0.2d, v0.2d, v1.2d}}
 }
 
 poly8x8_t test_vtrn2_p8(poly8x8_t a, poly8x8_t b) {
-  // CHECK: test_vtrn2_p8
+  // CHECK-LABEL: test_vtrn2_p8
   return vtrn2_p8(a, b);
   // CHECK: trn2 {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 poly8x16_t test_vtrn2q_p8(poly8x16_t a, poly8x16_t b) {
-  // CHECK: test_vtrn2q_p8
+  // CHECK-LABEL: test_vtrn2q_p8
   return vtrn2q_p8(a, b);
   // CHECK: trn2 {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 poly16x4_t test_vtrn2_p16(poly16x4_t a, poly16x4_t b) {
-  // CHECK: test_vtrn2_p16
+  // CHECK-LABEL: test_vtrn2_p16
   return vtrn2_p16(a, b);
   // CHECK: trn2 {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 
 poly16x8_t test_vtrn2q_p16(poly16x8_t a, poly16x8_t b) {
-  // CHECK: test_vtrn2q_p16
+  // CHECK-LABEL: test_vtrn2q_p16
   return vtrn2q_p16(a, b);
   // CHECK: trn2 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int8x8x2_t test_vuzp_s8(int8x8_t a, int8x8_t b) {
-  // CHECK: test_vuzp_s8
+  // CHECK-LABEL: test_vuzp_s8
   return vuzp_s8(a, b);
   // CHECK: uzp1 {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
   // CHECK: uzp2 {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 int16x4x2_t test_vuzp_s16(int16x4_t a, int16x4_t b) {
-  // CHECK: test_vuzp_s16
+  // CHECK-LABEL: test_vuzp_s16
   return vuzp_s16(a, b);
   // CHECK: uzp1 {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
   // CHECK: uzp2 {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 int32x2x2_t test_vuzp_s32(int32x2_t a, int32x2_t b) {
-  // CHECK: test_vuzp_s32
+  // CHECK-LABEL: test_vuzp_s32
   return vuzp_s32(a, b);
-  // CHECK: ins {{v[0-9]+}}.s[1], {{v[0-9]+}}.s[0]
-  // CHECK: ins {{v[0-9]+}}.s[0], {{v[0-9]+}}.s[1]
+  // CHECK: {{ins v[0-9]+.s\[1\], v[0-9]+.s\[0\]|zip1 v2.2s, v0.2s, v1.2s}}
+  // CHECK: {{ins v[0-9]+.s\[0\], v[0-9]+.s\[1\]|zip2 v1.2s, v0.2s, v1.2s}}
 }
 uint8x8x2_t test_vuzp_u8(uint8x8_t a, uint8x8_t b) {
-  // CHECK: test_vuzp_u8
+  // CHECK-LABEL: test_vuzp_u8
   return vuzp_u8(a, b);
   // CHECK: uzp1 {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
   // CHECK: uzp2 {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 uint16x4x2_t test_vuzp_u16(uint16x4_t a, uint16x4_t b) {
-  // CHECK: test_vuzp_u16
+  // CHECK-LABEL: test_vuzp_u16
   return vuzp_u16(a, b);
   // CHECK: uzp1 {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
   // CHECK: uzp2 {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 uint32x2x2_t test_vuzp_u32(uint32x2_t a, uint32x2_t b) {
-  // CHECK: test_vuzp_u32
+  // CHECK-LABEL: test_vuzp_u32
   return vuzp_u32(a, b);
-  // CHECK: ins {{v[0-9]+}}.s[1], {{v[0-9]+}}.s[0]
-  // CHECK: ins {{v[0-9]+}}.s[0], {{v[0-9]+}}.s[1]
+  // CHECK: {{ins v[0-9]+.s\[1\], v[0-9]+.s\[0\]|zip1 v2.2s, v0.2s, v1.2s}}
+  // CHECK: {{ins v[0-9]+.s\[0\], v[0-9]+.s\[1\]|zip2 v1.2s, v0.2s, v1.2s}}
 }
 float32x2x2_t test_vuzp_f32(float32x2_t a, float32x2_t b) {
-  // CHECK: test_vuzp_f32
+  // CHECK-LABEL: test_vuzp_f32
   return vuzp_f32(a, b);
-  // CHECK: ins {{v[0-9]+}}.s[1], {{v[0-9]+}}.s[0]
-  // CHECK: ins {{v[0-9]+}}.s[0], {{v[0-9]+}}.s[1]
+  // CHECK: {{ins v[0-9]+.s\[1\], v[0-9]+.s\[0\]|zip1 v2.2s, v0.2s, v1.2s}}
+  // CHECK: {{ins v[0-9]+.s\[0\], v[0-9]+.s\[1\]|zip2 v1.2s, v0.2s, v1.2s}}
 }
 poly8x8x2_t test_vuzp_p8(poly8x8_t a, poly8x8_t b) {
-  // CHECK: test_vuzp_p8
+  // CHECK-LABEL: test_vuzp_p8
   return vuzp_p8(a, b);
   // CHECK: uzp1 {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
   // CHECK: uzp2 {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 poly16x4x2_t test_vuzp_p16(poly16x4_t a, poly16x4_t b) {
-  // CHECK: test_vuzp_p16
+  // CHECK-LABEL: test_vuzp_p16
   return vuzp_p16(a, b);
   // CHECK: uzp1 {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
   // CHECK: uzp2 {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 int8x16x2_t test_vuzpq_s8(int8x16_t a, int8x16_t b) {
-  // CHECK: test_vuzpq_s8
+  // CHECK-LABEL: test_vuzpq_s8
   return vuzpq_s8(a, b);
   // CHECK: uzp1 {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
   // CHECK: uzp2 {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 int16x8x2_t test_vuzpq_s16(int16x8_t a, int16x8_t b) {
-  // CHECK: test_vuzpq_s16
+  // CHECK-LABEL: test_vuzpq_s16
   return vuzpq_s16(a, b);
   // CHECK: uzp1 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
   // CHECK: uzp2 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 int32x4x2_t test_vuzpq_s32(int32x4_t a, int32x4_t b) {
-  // CHECK: test_vuzpq_s32
+  // CHECK-LABEL: test_vuzpq_s32
   return vuzpq_s32(a, b);
   // CHECK: uzp1 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
   // CHECK: uzp2 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 uint8x16x2_t test_vuzpq_u8(uint8x16_t a, uint8x16_t b) {
-  // CHECK: test_vuzpq_u8
+  // CHECK-LABEL: test_vuzpq_u8
   return vuzpq_u8(a, b);
   // CHECK: uzp1 {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
   // CHECK: uzp2 {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 uint16x8x2_t test_vuzpq_u16(uint16x8_t a, uint16x8_t b) {
-  // CHECK: test_vuzpq_u16
+  // CHECK-LABEL: test_vuzpq_u16
   return vuzpq_u16(a, b);
   // CHECK: uzp1 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
   // CHECK: uzp2 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 uint32x4x2_t test_vuzpq_u32(uint32x4_t a, uint32x4_t b) {
-  // CHECK: test_vuzpq_u32
+  // CHECK-LABEL: test_vuzpq_u32
   return vuzpq_u32(a, b);
   // CHECK: uzp1 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
   // CHECK: uzp2 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 float32x4x2_t test_vuzpq_f32(float32x4_t a, float32x4_t b) {
-  // CHECK: test_vuzpq_f32
+  // CHECK-LABEL: test_vuzpq_f32
   return vuzpq_f32(a, b);
   // CHECK: uzp1 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
   // CHECK: uzp2 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 poly8x16x2_t test_vuzpq_p8(poly8x16_t a, poly8x16_t b) {
-  // CHECK: test_vuzpq_p8
+  // CHECK-LABEL: test_vuzpq_p8
   return vuzpq_p8(a, b);
   // CHECK: uzp1 {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
   // CHECK: uzp2 {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 poly16x8x2_t test_vuzpq_p16(poly16x8_t a, poly16x8_t b) {
-  // CHECK: test_vuzpq_p16
+  // CHECK-LABEL: test_vuzpq_p16
   return vuzpq_p16(a, b);
   // CHECK: uzp1 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
   // CHECK: uzp2 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int8x8x2_t test_vzip_s8(int8x8_t a, int8x8_t b) {
-  // CHECK: test_vzip_s8
+  // CHECK-LABEL: test_vzip_s8
   return vzip_s8(a, b);
   // CHECK: zip1 {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
   // CHECK: zip2 {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 int16x4x2_t test_vzip_s16(int16x4_t a, int16x4_t b) {
-  // CHECK: test_vzip_s16
+  // CHECK-LABEL: test_vzip_s16
   return vzip_s16(a, b);
   // CHECK: zip1 {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
   // CHECK: zip2 {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 int32x2x2_t test_vzip_s32(int32x2_t a, int32x2_t b) {
-  // CHECK: test_vzip_s32
+  // CHECK-LABEL: test_vzip_s32
   return vzip_s32(a, b);
-  // CHECK: ins {{v[0-9]+}}.s[1], {{v[0-9]+}}.s[0]
-  // CHECK: ins {{v[0-9]+}}.s[0], {{v[0-9]+}}.s[1]
+  // CHECK: {{ins v[0-9]+.s\[1\], v[0-9]+.s\[0\]|zip1 v2.2s, v0.2s, v1.2s}}
+  // CHECK: {{ins v[0-9]+.s\[0\], v[0-9]+.s\[1\]|zip2 v1.2s, v0.2s, v1.2s}}
 }
 uint8x8x2_t test_vzip_u8(uint8x8_t a, uint8x8_t b) {
-  // CHECK: test_vzip_u8
+  // CHECK-LABEL: test_vzip_u8
   return vzip_u8(a, b);
   // CHECK: zip1 {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
   // CHECK: zip2 {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 uint16x4x2_t test_vzip_u16(uint16x4_t a, uint16x4_t b) {
-  // CHECK: test_vzip_u16
+  // CHECK-LABEL: test_vzip_u16
   return vzip_u16(a, b);
   // CHECK: zip1 {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
   // CHECK: zip2 {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 uint32x2x2_t test_vzip_u32(uint32x2_t a, uint32x2_t b) {
-  // CHECK: test_vzip_u32
+  // CHECK-LABEL: test_vzip_u32
   return vzip_u32(a, b);
-  // CHECK: ins {{v[0-9]+}}.s[1], {{v[0-9]+}}.s[0]
-  // CHECK: ins {{v[0-9]+}}.s[0], {{v[0-9]+}}.s[1]
+  // CHECK: {{ins v[0-9]+.s\[1\], v[0-9]+.s\[0\]|zip1 v2.2s, v0.2s, v1.2s}}
+  // CHECK: {{ins v[0-9]+.s\[0\], v[0-9]+.s\[1\]|zip2 v1.2s, v0.2s, v1.2s}}
 }
 float32x2x2_t test_vzip_f32(float32x2_t a, float32x2_t b) {
-  // CHECK: test_vzip_f32
+  // CHECK-LABEL: test_vzip_f32
   return vzip_f32(a, b);
-  // CHECK: ins {{v[0-9]+}}.s[1], {{v[0-9]+}}.s[0]
-  // CHECK: ins {{v[0-9]+}}.s[0], {{v[0-9]+}}.s[1]
+  // CHECK: {{ins v[0-9]+.s\[1\], v[0-9]+.s\[0\]|zip1 v2.2s, v0.2s, v1.2s}}
+  // CHECK: {{ins v[0-9]+.s\[0\], v[0-9]+.s\[1\]|zip2 v1.2s, v0.2s, v1.2s}}
 }
 poly8x8x2_t test_vzip_p8(poly8x8_t a, poly8x8_t b) {
-  // CHECK: test_vzip_p8
+  // CHECK-LABEL: test_vzip_p8
   return vzip_p8(a, b);
   // CHECK: zip1 {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
   // CHECK: zip2 {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 poly16x4x2_t test_vzip_p16(poly16x4_t a, poly16x4_t b) {
-  // CHECK: test_vzip_p16
+  // CHECK-LABEL: test_vzip_p16
   return vzip_p16(a, b);
   // CHECK: zip1 {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
   // CHECK: zip2 {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 int8x16x2_t test_vzipq_s8(int8x16_t a, int8x16_t b) {
-  // CHECK: test_vzipq_s8
+  // CHECK-LABEL: test_vzipq_s8
   return vzipq_s8(a, b);
   // CHECK: zip1 {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
   // CHECK: zip2 {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 int16x8x2_t test_vzipq_s16(int16x8_t a, int16x8_t b) {
-  // CHECK: test_vzipq_s16
+  // CHECK-LABEL: test_vzipq_s16
   return vzipq_s16(a, b);
   // CHECK: zip1 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
   // CHECK: zip2 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 int32x4x2_t test_vzipq_s32(int32x4_t a, int32x4_t b) {
-  // CHECK: test_vzipq_s32
+  // CHECK-LABEL: test_vzipq_s32
   return vzipq_s32(a, b);
   // CHECK: zip1 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
   // CHECK: zip2 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 uint8x16x2_t test_vzipq_u8(uint8x16_t a, uint8x16_t b) {
-  // CHECK: test_vzipq_u8
+  // CHECK-LABEL: test_vzipq_u8
   return vzipq_u8(a, b);
   // CHECK: zip1 {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
   // CHECK: zip2 {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 uint16x8x2_t test_vzipq_u16(uint16x8_t a, uint16x8_t b) {
-  // CHECK: test_vzipq_u16
+  // CHECK-LABEL: test_vzipq_u16
   return vzipq_u16(a, b);
   // CHECK: zip1 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
   // CHECK: zip2 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 uint32x4x2_t test_vzipq_u32(uint32x4_t a, uint32x4_t b) {
-  // CHECK: test_vzipq_u32
+  // CHECK-LABEL: test_vzipq_u32
   return vzipq_u32(a, b);
   // CHECK: zip1 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
   // CHECK: zip2 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 float32x4x2_t test_vzipq_f32(float32x4_t a, float32x4_t b) {
-  // CHECK: test_vzipq_f32
+  // CHECK-LABEL: test_vzipq_f32
   return vzipq_f32(a, b);
   // CHECK: zip1 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
   // CHECK: zip2 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 poly8x16x2_t test_vzipq_p8(poly8x16_t a, poly8x16_t b) {
-  // CHECK: test_vzipq_p8
+  // CHECK-LABEL: test_vzipq_p8
   return vzipq_p8(a, b);
   // CHECK: zip1 {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
   // CHECK: zip2 {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 poly16x8x2_t test_vzipq_p16(poly16x8_t a, poly16x8_t b) {
-  // CHECK: test_vzipq_p16
+  // CHECK-LABEL: test_vzipq_p16
   return vzipq_p16(a, b);
   // CHECK: zip1 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
   // CHECK: zip2 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 
 int8x8x2_t test_vtrn_s8(int8x8_t a, int8x8_t b) {
-  // CHECK: test_vtrn_s8
+  // CHECK-LABEL: test_vtrn_s8
   return vtrn_s8(a, b);
   // CHECK: trn1 {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
   // CHECK: trn2 {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 int16x4x2_t test_vtrn_s16(int16x4_t a, int16x4_t b) {
-  // CHECK: test_vtrn_s16
+  // CHECK-LABEL: test_vtrn_s16
   return vtrn_s16(a, b);
   // CHECK: trn1 {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
   // CHECK: trn2 {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 int32x2x2_t test_vtrn_s32(int32x2_t a, int32x2_t b) {
-  // CHECK: test_vtrn_s32
+  // CHECK-LABEL: test_vtrn_s32
   return vtrn_s32(a, b);
-  // CHECK: ins {{v[0-9]+}}.s[1], {{v[0-9]+}}.s[0]
-  // CHECK: ins {{v[0-9]+}}.s[0], {{v[0-9]+}}.s[1]
+  // CHECK: {{ins v[0-9]+.s\[1\], v[0-9]+.s\[0\]|zip1 v2.2s, v0.2s, v1.2s}}
+  // CHECK: {{ins v[0-9]+.s\[0\], v[0-9]+.s\[1\]|zip2 v1.2s, v0.2s, v1.2s}}
 }
 uint8x8x2_t test_vtrn_u8(uint8x8_t a, uint8x8_t b) {
-  // CHECK: test_vtrn_u8
+  // CHECK-LABEL: test_vtrn_u8
   return vtrn_u8(a, b);
   // CHECK: trn1 {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
   // CHECK: trn2 {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 uint16x4x2_t test_vtrn_u16(uint16x4_t a, uint16x4_t b) {
-  // CHECK: test_vtrn_u16
+  // CHECK-LABEL: test_vtrn_u16
   return vtrn_u16(a, b);
   // CHECK: trn1 {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
   // CHECK: trn2 {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 uint32x2x2_t test_vtrn_u32(uint32x2_t a, uint32x2_t b) {
-  // CHECK: test_vtrn_u32
+  // CHECK-LABEL: test_vtrn_u32
   return vtrn_u32(a, b);
-  // CHECK: ins {{v[0-9]+}}.s[1], {{v[0-9]+}}.s[0]
-  // CHECK: ins {{v[0-9]+}}.s[0], {{v[0-9]+}}.s[1]
+  // CHECK: {{ins v[0-9]+.s\[1\], v[0-9]+.s\[0\]|zip1 v2.2s, v0.2s, v1.2s}}
+  // CHECK: {{ins v[0-9]+.s\[0\], v[0-9]+.s\[1\]|zip2 v1.2s, v0.2s, v1.2s}}
 }
 float32x2x2_t test_vtrn_f32(float32x2_t a, float32x2_t b) {
-  // CHECK: test_vtrn_f32
+  // CHECK-LABEL: test_vtrn_f32
   return vtrn_f32(a, b);
-  // CHECK: ins {{v[0-9]+}}.s[1], {{v[0-9]+}}.s[0]
-  // CHECK: ins {{v[0-9]+}}.s[0], {{v[0-9]+}}.s[1]
+  // CHECK: {{ins v[0-9]+.s\[1\], v[0-9]+.s\[0\]|zip1 v2.2s, v0.2s, v1.2s}}
+  // CHECK: {{ins v[0-9]+.s\[0\], v[0-9]+.s\[1\]|zip2 v1.2s, v0.2s, v1.2s}}
 }
 poly8x8x2_t test_vtrn_p8(poly8x8_t a, poly8x8_t b) {
-  // CHECK: test_vtrn_p8
+  // CHECK-LABEL: test_vtrn_p8
   return vtrn_p8(a, b);
   // CHECK: trn1 {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
   // CHECK: trn2 {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 poly16x4x2_t test_vtrn_p16(poly16x4_t a, poly16x4_t b) {
-  // CHECK: test_vtrn_p16
+  // CHECK-LABEL: test_vtrn_p16
   return vtrn_p16(a, b);
   // CHECK: trn1 {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
   // CHECK: trn2 {{v[0-9]+}}.4h, {{v[0-9]+}}.4h
 }
 int8x16x2_t test_vtrnq_s8(int8x16_t a, int8x16_t b) {
-  // CHECK: test_vtrnq_s8
+  // CHECK-LABEL: test_vtrnq_s8
   return vtrnq_s8(a, b);
   // CHECK: trn1 {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
   // CHECK: trn2 {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 int16x8x2_t test_vtrnq_s16(int16x8_t a, int16x8_t b) {
-  // CHECK: test_vtrnq_s16
+  // CHECK-LABEL: test_vtrnq_s16
   return vtrnq_s16(a, b);
   // CHECK: trn1 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
   // CHECK: trn2 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 int32x4x2_t test_vtrnq_s32(int32x4_t a, int32x4_t b) {
-  // CHECK: test_vtrnq_s32
+  // CHECK-LABEL: test_vtrnq_s32
   return vtrnq_s32(a, b);
   // CHECK: trn1 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
   // CHECK: trn2 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 uint8x16x2_t test_vtrnq_u8(uint8x16_t a, uint8x16_t b) {
-  // CHECK: test_vtrnq_u8
+  // CHECK-LABEL: test_vtrnq_u8
   return vtrnq_u8(a, b);
   // CHECK: trn1 {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
   // CHECK: trn2 {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 uint16x8x2_t test_vtrnq_u16(uint16x8_t a, uint16x8_t b) {
-  // CHECK: test_vtrnq_u16
+  // CHECK-LABEL: test_vtrnq_u16
   return vtrnq_u16(a, b);
   // CHECK: trn1 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
   // CHECK: trn2 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
 }
 uint32x4x2_t test_vtrnq_u32(uint32x4_t a, uint32x4_t b) {
-  // CHECK: test_vtrnq_u32
+  // CHECK-LABEL: test_vtrnq_u32
   return vtrnq_u32(a, b);
   // CHECK: trn1 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
   // CHECK: trn2 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 float32x4x2_t test_vtrnq_f32(float32x4_t a, float32x4_t b) {
-  // CHECK: test_vtrnq_f32
+  // CHECK-LABEL: test_vtrnq_f32
   return vtrnq_f32(a, b);
   // CHECK: trn1 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
   // CHECK: trn2 {{v[0-9]+}}.4s, {{v[0-9]+}}.4s
 }
 poly8x16x2_t test_vtrnq_p8(poly8x16_t a, poly8x16_t b) {
-  // CHECK: test_vtrnq_p8
+  // CHECK-LABEL: test_vtrnq_p8
   return vtrnq_p8(a, b);
   // CHECK: trn1 {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
   // CHECK: trn2 {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 poly16x8x2_t test_vtrnq_p16(poly16x8_t a, poly16x8_t b) {
-  // CHECK: test_vtrnq_p16
+  // CHECK-LABEL: test_vtrnq_p16
   return vtrnq_p16(a, b);
   // CHECK: trn1 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
   // CHECK: trn2 {{v[0-9]+}}.8h, {{v[0-9]+}}.8h
diff --git a/test/CodeGen/aarch64-neon-scalar-copy.c b/test/CodeGen/aarch64-neon-scalar-copy.c
new file mode 100644
index 0000000..a50a0b9
--- /dev/null
+++ b/test/CodeGen/aarch64-neon-scalar-copy.c
@@ -0,0 +1,173 @@
+// REQUIRES: aarch64-registered-target
+// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \
+// RUN:   -ffp-contract=fast -S -O3 -o - %s | FileCheck %s
+
+
+#include <arm_neon.h>
+
+// CHECK-LABEL: test_vdups_lane_f32
+float32_t test_vdups_lane_f32(float32x2_t a) {
+  return vdups_lane_f32(a, 1);
+// CHECK: ret
+// CHECK-NOT: dup {{s[0-9]+}}, {{v[0-9]+}}.s[1]
+}
+
+
+// CHECK-LABEL: test_vdupd_lane_f64
+float64_t test_vdupd_lane_f64(float64x1_t a) {
+  return vdupd_lane_f64(a, 0);
+// CHECK: ret
+// CHECK-NOT: dup {{d[0-9]+}}, {{v[0-9]+}}.d[0]
+}
+
+
+// CHECK-LABEL: test_vdups_laneq_f32
+float32_t test_vdups_laneq_f32(float32x4_t a) {
+  return vdups_laneq_f32(a, 3);
+// CHECK: ret
+// CHECK-NOT: dup {{s[0-9]+}}, {{v[0-9]+}}.s[3]
+}
+
+
+// CHECK-LABEL: test_vdupd_laneq_f64
+float64_t test_vdupd_laneq_f64(float64x2_t a) {
+  return vdupd_laneq_f64(a, 1);
+// CHECK: ret
+// CHECK-NOT: dup {{d[0-9]+}}, {{v[0-9]+}}.d[1]
+}
+
+
+// CHECK-LABEL: test_vdupb_lane_s8
+int8_t test_vdupb_lane_s8(int8x8_t a) {
+  return vdupb_lane_s8(a, 7);
+// CHECK: {{umov|smov}} {{w[0-9]+}}, {{v[0-9]+}}.b[7]
+}
+
+
+// CHECK-LABEL: test_vduph_lane_s16
+int16_t test_vduph_lane_s16(int16x4_t a) {
+  return vduph_lane_s16(a, 3);
+// CHECK: {{umov|smov}} {{w[0-9]+}}, {{v[0-9]+}}.h[3]
+}
+
+
+// CHECK-LABEL: test_vdups_lane_s32
+int32_t test_vdups_lane_s32(int32x2_t a) {
+  return vdups_lane_s32(a, 1);
+// CHECK: {{mov|umov}} {{w[0-9]+}}, {{v[0-9]+}}.s[1]
+}
+
+
+// CHECK-LABEL: test_vdupd_lane_s64
+int64_t test_vdupd_lane_s64(int64x1_t a) {
+  return vdupd_lane_s64(a, 0);
+// CHECK: fmov {{x[0-9]+}}, {{d[0-9]+}}
+}
+
+
+// CHECK-LABEL: test_vdupb_lane_u8
+uint8_t test_vdupb_lane_u8(uint8x8_t a) {
+  return vdupb_lane_u8(a, 7);
+// CHECK: {{mov|umov}} {{w[0-9]+}}, {{v[0-9]+}}.b[7]
+}
+
+
+// CHECK-LABEL: test_vduph_lane_u16
+uint16_t test_vduph_lane_u16(uint16x4_t a) {
+  return vduph_lane_u16(a, 3);
+// CHECK: {{mov|umov}} {{w[0-9]+}}, {{v[0-9]+}}.h[3]
+}
+
+
+// CHECK-LABEL: test_vdups_lane_u32
+uint32_t test_vdups_lane_u32(uint32x2_t a) {
+  return vdups_lane_u32(a, 1);
+// CHECK: {{mov|umov}} {{w[0-9]+}}, {{v[0-9]+}}.s[1]
+}
+
+
+// CHECK-LABEL: test_vdupd_lane_u64
+uint64_t test_vdupd_lane_u64(uint64x1_t a) {
+  return vdupd_lane_u64(a, 0);
+// CHECK: fmov {{x[0-9]+}}, {{d[0-9]+}}
+}
+
+// CHECK-LABEL: test_vdupb_laneq_s8
+int8_t test_vdupb_laneq_s8(int8x16_t a) {
+  return vdupb_laneq_s8(a, 15);
+// CHECK: {{umov|smov}} {{w[0-9]+}}, {{v[0-9]+}}.b[15]
+}
+
+
+// CHECK-LABEL: test_vduph_laneq_s16
+int16_t test_vduph_laneq_s16(int16x8_t a) {
+  return vduph_laneq_s16(a, 7);
+// CHECK: {{umov|smov}} {{w[0-9]+}}, {{v[0-9]+}}.h[7]
+}
+
+
+// CHECK-LABEL: test_vdups_laneq_s32
+int32_t test_vdups_laneq_s32(int32x4_t a) {
+  return vdups_laneq_s32(a, 3);
+// CHECK: {{mov|umov}} {{w[0-9]+}}, {{v[0-9]+}}.s[3]
+}
+
+
+// CHECK-LABEL: test_vdupd_laneq_s64
+int64_t test_vdupd_laneq_s64(int64x2_t a) {
+  return vdupd_laneq_s64(a, 1);
+// CHECK: {{mov|umov}} {{x[0-9]+}}, {{v[0-9]+}}.d[1]
+}
+
+
+// CHECK-LABEL: test_vdupb_laneq_u8
+uint8_t test_vdupb_laneq_u8(uint8x16_t a) {
+  return vdupb_laneq_u8(a, 15);
+// CHECK: {{mov|umov}} {{w[0-9]+}}, {{v[0-9]+}}.b[15]
+}
+
+
+// CHECK-LABEL: test_vduph_laneq_u16
+uint16_t test_vduph_laneq_u16(uint16x8_t a) {
+  return vduph_laneq_u16(a, 7);
+// CHECK: {{mov|umov}} {{w[0-9]+}}, {{v[0-9]+}}.h[7]
+}
+
+
+// CHECK-LABEL: test_vdups_laneq_u32
+uint32_t test_vdups_laneq_u32(uint32x4_t a) {
+  return vdups_laneq_u32(a, 3);
+// CHECK: {{mov|umov}} {{w[0-9]+}}, {{v[0-9]+}}.s[3]
+}
+
+
+// CHECK-LABEL: test_vdupd_laneq_u64
+uint64_t test_vdupd_laneq_u64(uint64x2_t a) {
+  return vdupd_laneq_u64(a, 1);
+// CHECK: {{mov|umov}} {{x[0-9]+}}, {{v[0-9]+}}.d[1]
+}
+
+// CHECK-LABEL: test_vdupb_lane_p8
+poly8_t test_vdupb_lane_p8(poly8x8_t a) {
+  return vdupb_lane_p8(a, 7);
+// CHECK: {{mov|umov}} {{w[0-9]+}}, {{v[0-9]+}}.b[7]
+}
+
+// CHECK-LABEL: test_vduph_lane_p16
+poly16_t test_vduph_lane_p16(poly16x4_t a) {
+  return vduph_lane_p16(a, 3);
+// CHECK: {{mov|umov}} {{w[0-9]+}}, {{v[0-9]+}}.h[3]
+}
+
+// CHECK-LABEL: test_vdupb_laneq_p8
+poly8_t test_vdupb_laneq_p8(poly8x16_t a) {
+  return vdupb_laneq_p8(a, 15);
+// CHECK: {{mov|umov}} {{w[0-9]+}}, {{v[0-9]+}}.b[15]
+}
+
+// CHECK-LABEL: test_vduph_laneq_p16
+poly16_t test_vduph_laneq_p16(poly16x8_t a) {
+  return vduph_laneq_p16(a, 7);
+// CHECK: {{mov|umov}} {{w[0-9]+}}, {{v[0-9]+}}.h[7]
+}
+
diff --git a/test/CodeGen/aarch64-neon-scalar-x-indexed-elem.c b/test/CodeGen/aarch64-neon-scalar-x-indexed-elem.c
index 33cd487..4c2f4d7 100644
--- a/test/CodeGen/aarch64-neon-scalar-x-indexed-elem.c
+++ b/test/CodeGen/aarch64-neon-scalar-x-indexed-elem.c
@@ -1,5 +1,5 @@
 // REQUIRES: aarch64-registered-target
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +neon \
+// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon -target-cpu cyclone \
 // RUN:   -ffp-contract=fast -S -O3 -o - %s | FileCheck %s
 
 // Test new aarch64 intrinsics and types
@@ -8,124 +8,283 @@
 
 
 float32_t test_vmuls_lane_f32(float32_t a, float32x2_t b) {
-  // CHECK: test_vmuls_lane_f32
+  // CHECK-LABEL: test_vmuls_lane_f32
   return vmuls_lane_f32(a, b, 1);
   // CHECK: fmul {{s[0-9]+}}, {{s[0-9]+}}, {{v[0-9]+}}.s[1]
 }
 
 float64_t test_vmuld_lane_f64(float64_t a, float64x1_t b) {
-  // CHECK: test_vmuld_lane_f64
+  // CHECK-LABEL: test_vmuld_lane_f64
   return vmuld_lane_f64(a, b, 0);
-  // CHECK: fmul {{d[0-9]+}}, {{d[0-9]+}}, {{v[0-9]+}}.d[0]
+  // CHECK: fmul {{d[0-9]+}}, {{d[0-9]+}}, {{v[0-9]+.d\[0\]|d[0-9]+}}
 }
 
 float32_t test_vmuls_laneq_f32(float32_t a, float32x4_t b) {
-  // CHECK: test_vmuls_laneq_f32
+  // CHECK-LABEL: test_vmuls_laneq_f32
   return vmuls_laneq_f32(a, b, 3);
   // CHECK: fmul {{s[0-9]+}}, {{s[0-9]+}}, {{v[0-9]+}}.s[3]
 }
 
 float64_t test_vmuld_laneq_f64(float64_t a, float64x2_t b) {
-  // CHECK: test_vmuld_laneq_f64
+  // CHECK-LABEL: test_vmuld_laneq_f64
   return vmuld_laneq_f64(a, b, 1);
   // CHECK: fmul {{d[0-9]+}}, {{d[0-9]+}}, {{v[0-9]+}}.d[1]
 }
 
 float64x1_t test_vmul_n_f64(float64x1_t a, float64_t b) {
-  // CHECK: test_vmul_n_f64
+  // CHECK-LABEL: test_vmul_n_f64
   return vmul_n_f64(a, b);
-  // CHECK: fmul {{d[0-9]+}}, {{d[0-9]+}}, {{v[0-9]+}}.d[0]
+  // CHECK: fmul {{d[0-9]+}}, {{d[0-9]+}}, {{v[0-9]+.d\[0\]|d[0-9]+}}
 }
 
 float32_t test_vmulxs_lane_f32(float32_t a, float32x2_t b) {
-// CHECK: test_vmulxs_lane_f32
+// CHECK-LABEL: test_vmulxs_lane_f32
   return vmulxs_lane_f32(a, b, 1);
 // CHECK: fmulx {{s[0-9]+}}, {{s[0-9]+}}, {{v[0-9]+}}.s[1]
 }
 
 float32_t test_vmulxs_laneq_f32(float32_t a, float32x4_t b) {
-// CHECK: test_vmulxs_laneq_f32
+// CHECK-LABEL: test_vmulxs_laneq_f32
   return vmulxs_laneq_f32(a, b, 3);
 // CHECK: fmulx {{s[0-9]+}}, {{s[0-9]+}}, {{v[0-9]+}}.s[3]
 }
 
 float64_t test_vmulxd_lane_f64(float64_t a, float64x1_t b) {
-// CHECK: test_vmulxd_lane_f64
+// CHECK-LABEL: test_vmulxd_lane_f64
   return vmulxd_lane_f64(a, b, 0);
-// CHECK: fmulx {{d[0-9]+}}, {{d[0-9]+}}, {{v[0-9]+}}.d[0]
+// CHECK: fmulx {{d[0-9]+}}, {{d[0-9]+}}, {{v[0-9]+.d\[0\]|d[0-9]+}}
 }
 
 float64_t test_vmulxd_laneq_f64(float64_t a, float64x2_t b) {
-// CHECK: test_vmulxd_laneq_f64
+// CHECK-LABEL: test_vmulxd_laneq_f64
   return vmulxd_laneq_f64(a, b, 1);
 // CHECK: fmulx {{d[0-9]+}}, {{d[0-9]+}}, {{v[0-9]+}}.d[1]
 }
 
-// CHECK_AARCH64: test_vmulx_lane_f64
+// CHECK-LABEL: test_vmulx_lane_f64
 float64x1_t test_vmulx_lane_f64(float64x1_t a, float64x1_t b) {
   return vmulx_lane_f64(a, b, 0);
-  // CHECK: fmulx {{d[0-9]+}}, {{d[0-9]+}}, {{v[0-9]+}}.d[0]
+  // CHECK: fmulx {{d[0-9]+}}, {{d[0-9]+}}, {{v[0-9]+.d\[0\]|d[0-9]+}}
 }
 
 
-// CHECK_AARCH64: test_vmulx_laneq_f64_0
+// CHECK-LABEL: test_vmulx_laneq_f64_0
 float64x1_t test_vmulx_laneq_f64_0(float64x1_t a, float64x2_t b) {
   return vmulx_laneq_f64(a, b, 0);
   // CHECK: fmulx {{d[0-9]+}}, {{d[0-9]+}}, {{v[0-9]+}}.d[0]
 }
 
-// CHECK_AARCH64: test_vmulx_laneq_f64_1
+// CHECK-LABEL: test_vmulx_laneq_f64_1
 float64x1_t test_vmulx_laneq_f64_1(float64x1_t a, float64x2_t b) {
   return vmulx_laneq_f64(a, b, 1);
   // CHECK: fmulx {{d[0-9]+}}, {{d[0-9]+}}, {{v[0-9]+}}.d[1]
 }
 
 
-// CHECK_AARCH64: test_vfmas_lane_f32
+// CHECK-LABEL: test_vfmas_lane_f32
 float32_t test_vfmas_lane_f32(float32_t a, float32_t b, float32x2_t c) {
   return vfmas_lane_f32(a, b, c, 1);
   // CHECK: fmla {{s[0-9]+}}, {{s[0-9]+}}, {{v[0-9]+}}.s[1]
 }
 
-// CHECK_AARCH64: test_vfmad_lane_f64
+// CHECK-LABEL: test_vfmad_lane_f64
 float64_t test_vfmad_lane_f64(float64_t a, float64_t b, float64x1_t c) {
   return vfmad_lane_f64(a, b, c, 0);
-  // CHECK: fmla {{d[0-9]+}}, {{d[0-9]+}}, {{v[0-9]+}}.d[0]
+  // CHECK: {{fmla|fmadd}} {{d[0-9]+}}, {{d[0-9]+}}, {{v[0-9]+.d\[0\]|d[0-9]+}}
 }
 
-// CHECK_AARCH64: test_vfmad_laneq_f64
+// CHECK-LABEL: test_vfmad_laneq_f64
 float64_t test_vfmad_laneq_f64(float64_t a, float64_t b, float64x2_t c) {
   return vfmad_laneq_f64(a, b, c, 1);
   // CHECK: fmla {{d[0-9]+}}, {{d[0-9]+}}, {{v[0-9]+}}.d[1]
 }
 
-// CHECK_AARCH64: test_vfmss_lane_f32
+// CHECK-LABEL: test_vfmss_lane_f32
 float32_t test_vfmss_lane_f32(float32_t a, float32_t b, float32x2_t c) {
   return vfmss_lane_f32(a, b, c, 1);
   // CHECK: fmls {{s[0-9]+}}, {{s[0-9]+}}, {{v[0-9]+}}.s[1]
 }
 
-// CHECK_AARCH64: test_vfma_lane_f64
+// CHECK-LABEL: test_vfma_lane_f64
 float64x1_t test_vfma_lane_f64(float64x1_t a, float64x1_t b, float64x1_t v) {
   return vfma_lane_f64(a, b, v, 0);
-  // CHECK: fmla {{d[0-9]+}}, {{d[0-9]+}}, {{v[0-9]+}}.d[0]
+  // CHECK: {{fmla|fmadd}} {{d[0-9]+}}, {{d[0-9]+}}, {{v[0-9]+.d\[0\]|d[0-9]+}}
 }
 
-// CHECK_AARCH64: test_vfms_lane_f64
+// CHECK-LABEL: test_vfms_lane_f64
 float64x1_t test_vfms_lane_f64(float64x1_t a, float64x1_t b, float64x1_t v) {
   return vfms_lane_f64(a, b, v, 0);
-  // CHECK: fmls {{d[0-9]+}}, {{d[0-9]+}}, {{v[0-9]+}}.d[0]
+  // CHECK: {{fmls|fmsub}} {{d[0-9]+}}, {{d[0-9]+}}, {{v[0-9]+.d\[0\]|d[0-9]+}}
 }
 
-// CHECK_AARCH64: test_vfma_laneq_f64
+// CHECK-LABEL: test_vfma_laneq_f64
 float64x1_t test_vfma_laneq_f64(float64x1_t a, float64x1_t b, float64x2_t v) {
   return vfma_laneq_f64(a, b, v, 0);
   // CHECK: fmla {{d[0-9]+}}, {{d[0-9]+}}, {{v[0-9]+}}.d[0]
 }
 
-// CHECK_AARCH64: test_vfms_laneq_f64
+// CHECK-LABEL: test_vfms_laneq_f64
 float64x1_t test_vfms_laneq_f64(float64x1_t a, float64x1_t b, float64x2_t v) {
   return vfms_laneq_f64(a, b, v, 0);
   // CHECK: fmls {{d[0-9]+}}, {{d[0-9]+}}, {{v[0-9]+}}.d[0]
 }
 
+// CHECK-LABEL: test_vqdmullh_lane_s16
+int32_t test_vqdmullh_lane_s16(int16_t a, int16x4_t b) {
+  return vqdmullh_lane_s16(a, b, 3);
+  // CHECK: sqdmull {{s[0-9]+|v[0-9]+.4s}}, {{h[0-9]+|v[0-9].4h}}, {{v[0-9]+}}.h[3]
+}
+
+// CHECK-LABEL: test_vqdmulls_lane_s32
+int64_t test_vqdmulls_lane_s32(int32_t a, int32x2_t b) {
+  return vqdmulls_lane_s32(a, b, 1);
+  // CHECK: sqdmull {{d[0-9]+}}, {{s[0-9]+}}, {{v[0-9]+}}.s[1]
+}
+
+// CHECK-LABEL: test_vqdmullh_laneq_s16
+int32_t test_vqdmullh_laneq_s16(int16_t a, int16x8_t b) {
+  return vqdmullh_laneq_s16(a, b, 7);
+  // CHECK: sqdmull {{s[0-9]+|v[0-9]+.4s}}, {{h[0-9]+|v[0-9]+.4h}}, {{v[0-9]+}}.h[7]
+}
+
+// CHECK-LABEL: test_vqdmulls_laneq_s32
+int64_t test_vqdmulls_laneq_s32(int32_t a, int32x4_t b) {
+  return vqdmulls_laneq_s32(a, b, 3);
+  // CHECK: sqdmull {{d[0-9]+}}, {{s[0-9]+}}, {{v[0-9]+}}.s[3]
+}
+
+// CHECK-LABEL: test_vqdmulhh_lane_s16
+int16_t test_vqdmulhh_lane_s16(int16_t a, int16x4_t b) {
+  return vqdmulhh_lane_s16(a, b, 3);
+// CHECK: sqdmulh {{h[0-9]+|v[0-9]+.4h}}, {{h[0-9]+|v[0-9]+.4h}}, {{v[0-9]+}}.h[3]
+}
+
+// CHECK-LABEL: test_vqdmulhs_lane_s32
+int32_t test_vqdmulhs_lane_s32(int32_t a, int32x2_t b) {
+  return vqdmulhs_lane_s32(a, b, 1);
+// CHECK: sqdmulh {{s[0-9]+}}, {{s[0-9]+}}, {{v[0-9]+}}.s[1]
+}
+
+
+// CHECK-LABEL: test_vqdmulhh_laneq_s16
+int16_t test_vqdmulhh_laneq_s16(int16_t a, int16x8_t b) {
+  return vqdmulhh_laneq_s16(a, b, 7);
+// CHECK: sqdmulh {{h[0-9]+|v[0-9]+.4h}}, {{h[0-9]+|v[0-9]+.4h}}, {{v[0-9]+}}.h[7]
+}
+
+
+// CHECK-LABEL: test_vqdmulhs_laneq_s32
+int32_t test_vqdmulhs_laneq_s32(int32_t a, int32x4_t b) {
+  return vqdmulhs_laneq_s32(a, b, 3);
+// CHECK: sqdmulh {{s[0-9]+}}, {{s[0-9]+}}, {{v[0-9]+}}.s[3]
+}
+
+// CHECK-LABEL: test_vqrdmulhh_lane_s16
+int16_t test_vqrdmulhh_lane_s16(int16_t a, int16x4_t b) {
+  return vqrdmulhh_lane_s16(a, b, 3);
+// CHECK: sqrdmulh {{h[0-9]+|v[0-9]+.4h}}, {{h[0-9]+|v[0-9]+.4h}}, {{v[0-9]+}}.h[3]
+}
+
+// CHECK-LABEL: test_vqrdmulhs_lane_s32
+int32_t test_vqrdmulhs_lane_s32(int32_t a, int32x2_t b) {
+  return vqrdmulhs_lane_s32(a, b, 1);
+// CHECK: sqrdmulh {{s[0-9]+}}, {{s[0-9]+}}, {{v[0-9]+}}.s[1]
+}
+
+
+// CHECK-LABEL: test_vqrdmulhh_laneq_s16
+int16_t test_vqrdmulhh_laneq_s16(int16_t a, int16x8_t b) {
+  return vqrdmulhh_laneq_s16(a, b, 7);
+// CHECK: sqrdmulh {{h[0-9]+|v[0-9]+.4h}}, {{h[0-9]+|v[0-9]+.4h}}, {{v[0-9]+}}.h[7]
+}
+
+
+// CHECK-LABEL: test_vqrdmulhs_laneq_s32
+int32_t test_vqrdmulhs_laneq_s32(int32_t a, int32x4_t b) {
+  return vqrdmulhs_laneq_s32(a, b, 3);
+// CHECK: sqrdmulh {{s[0-9]+}}, {{s[0-9]+}}, {{v[0-9]+}}.s[3]
+}
+
+// CHECK-LABEL: test_vqdmlalh_lane_s16
+int32_t test_vqdmlalh_lane_s16(int32_t a, int16_t b, int16x4_t c) {
+  return vqdmlalh_lane_s16(a, b, c, 3);
+// CHECK: sqdmlal {{s[0-9]+|v[0-9]+.4s}}, {{h[0-9]+|v[0-9]+.4h}}, {{v[0-9]+}}.h[3]
+}
+
+// CHECK-LABEL: test_vqdmlals_lane_s32
+int64_t test_vqdmlals_lane_s32(int64_t a, int32_t b, int32x2_t c) {
+  return vqdmlals_lane_s32(a, b, c, 1);
+// CHECK: sqdmlal {{d[0-9]+}}, {{s[0-9]+}}, {{v[0-9]+}}.s[1]
+}
+
+// CHECK-LABEL: test_vqdmlalh_laneq_s16
+int32_t test_vqdmlalh_laneq_s16(int32_t a, int16_t b, int16x8_t c) {
+  return vqdmlalh_laneq_s16(a, b, c, 7);
+// CHECK: sqdmlal {{s[0-9]+|v[0-9]+.4s}}, {{h[0-9]+|v[0-9]+.4h}}, {{v[0-9]+}}.h[7]
+}
+
+// CHECK-LABEL: test_vqdmlals_laneq_s32
+int64_t test_vqdmlals_laneq_s32(int64_t a, int32_t b, int32x4_t c) {
+  return vqdmlals_laneq_s32(a, b, c, 3);
+// CHECK: sqdmlal {{d[0-9]+}}, {{s[0-9]+}}, {{v[0-9]+}}.s[3]
+}
+
+// CHECK-LABEL: test_vqdmlslh_lane_s16
+int32_t test_vqdmlslh_lane_s16(int32_t a, int16_t b, int16x4_t c) {
+  return vqdmlslh_lane_s16(a, b, c, 3);
+// CHECK: sqdmlsl {{s[0-9]+|v[0-9]+.4s}}, {{h[0-9]+|v[0-9]+.4h}}, {{v[0-9]+}}.h[3]
+}
+
+// CHECK-LABEL: test_vqdmlsls_lane_s32
+int64_t test_vqdmlsls_lane_s32(int64_t a, int32_t b, int32x2_t c) {
+  return vqdmlsls_lane_s32(a, b, c, 1);
+// CHECK: sqdmlsl {{d[0-9]+}}, {{s[0-9]+}}, {{v[0-9]+}}.s[1]
+}
+
+// CHECK-LABEL: test_vqdmlslh_laneq_s16
+int32_t test_vqdmlslh_laneq_s16(int32_t a, int16_t b, int16x8_t c) {
+  return vqdmlslh_laneq_s16(a, b, c, 7);
+// CHECK: sqdmlsl {{s[0-9]+|v[0-9]+.4s}}, {{h[0-9]+|v[0-9]+.4h}}, {{v[0-9]+}}.h[7]
+}
+
+// CHECK-LABEL: test_vqdmlsls_laneq_s32
+int64_t test_vqdmlsls_laneq_s32(int64_t a, int32_t b, int32x4_t c) {
+  return vqdmlsls_laneq_s32(a, b, c, 3);
+// CHECK: sqdmlsl {{d[0-9]+}}, {{s[0-9]+}}, {{v[0-9]+}}.s[3]
+}
+
+// CHECK-LABEL: test_vmulx_lane_f64_0:
+float64x1_t test_vmulx_lane_f64_0() {
+      float64x1_t arg1;
+      float64x1_t arg2;
+      float64x1_t result;
+      float64_t sarg1, sarg2, sres;
+      arg1 = vcreate_f64(UINT64_C(0x3fd6304bc43ab5c2));
+      arg2 = vcreate_f64(UINT64_C(0x3fee211e215aeef3));
+      result = vmulx_lane_f64(arg1, arg2, 0);
+// CHECK: adrp x[[ADDRLO:[0-9]+]]
+// CHECK: ldr d0, [x[[ADDRLO]],
+// CHECK: adrp x[[ADDRLO:[0-9]+]]
+// CHECK: ldr d1, [x[[ADDRLO]],
+// CHECK: fmulx d0, d1, d0
+      return result;
+}
+
+// CHECK-LABEL: test_vmulx_laneq_f64_2:
+float64x1_t test_vmulx_laneq_f64_2() {
+      float64x1_t arg1;
+      float64x1_t arg2;
+      float64x2_t arg3;
+      float64x1_t result;
+      float64_t sarg1, sarg2, sres;
+      arg1 = vcreate_f64(UINT64_C(0x3fd6304bc43ab5c2));
+      arg2 = vcreate_f64(UINT64_C(0x3fee211e215aeef3));
+      arg3 = vcombine_f64(arg1, arg2);
+      result = vmulx_laneq_f64(arg1, arg3, 1);
+// CHECK: adrp x[[ADDRLO:[0-9]+]]
+// CHECK: ldr d0, [x[[ADDRLO]],
+// CHECK: adrp x[[ADDRLO:[0-9]+]]
+// CHECK: ldr d1, [x[[ADDRLO]],
+// CHECK: fmulx d0, d1, d0
+      return result;
+}
diff --git a/test/CodeGen/aarch64-neon-shifts.c b/test/CodeGen/aarch64-neon-shifts.c
index 4777f18..02d8ca1 100644
--- a/test/CodeGen/aarch64-neon-shifts.c
+++ b/test/CodeGen/aarch64-neon-shifts.c
@@ -1,5 +1,5 @@
 // REQUIRES: aarch64-registered-target
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +neon \
+// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \
 // RUN:   -ffp-contract=fast -S -emit-llvm -O1 -o - %s | FileCheck %s
 
 #include <arm_neon.h>
diff --git a/test/CodeGen/aarch64-neon-tbl.c b/test/CodeGen/aarch64-neon-tbl.c
index db78a7a..902fc45 100644
--- a/test/CodeGen/aarch64-neon-tbl.c
+++ b/test/CodeGen/aarch64-neon-tbl.c
@@ -1,5 +1,5 @@
 // REQUIRES: aarch64-registered-target
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +neon \
+// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \
 // RUN:   -ffp-contract=fast -S -O3 -o - %s | FileCheck %s
 
 // Test new aarch64 intrinsics and types
@@ -7,457 +7,457 @@
 #include <arm_neon.h>
 
 int8x8_t test_vtbl1_s8(int8x8_t a, int8x8_t b) {
-  // CHECK: test_vtbl1_s8
+  // CHECK-LABEL: test_vtbl1_s8
   return vtbl1_s8(a, b);
-  // CHECK: tbl {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbl {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 int8x8_t test_vqtbl1_s8(int8x16_t a, int8x8_t b) {
-  // CHECK: test_vqtbl1_s8
+  // CHECK-LABEL: test_vqtbl1_s8
   return vqtbl1_s8(a, b);
-  // CHECK: tbl {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbl {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 int8x8_t test_vtbl2_s8(int8x8x2_t a, int8x8_t b) {
-  // CHECK: test_vtbl2_s8
+  // CHECK-LABEL: test_vtbl2_s8
   return vtbl2_s8(a, b);
-  // CHECK: tbl {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbl {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 int8x8_t test_vqtbl2_s8(int8x16x2_t a, int8x8_t b) {
-  // CHECK: test_vqtbl2_s8
+  // CHECK-LABEL: test_vqtbl2_s8
   return vqtbl2_s8(a, b);
-  // CHECK: tbl {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbl {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 int8x8_t test_vtbl3_s8(int8x8x3_t a, int8x8_t b) {
-  // CHECK: test_vtbl3_s8
+  // CHECK-LABEL: test_vtbl3_s8
   return vtbl3_s8(a, b);
-  // CHECK: tbl {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbl {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 int8x8_t test_vqtbl3_s8(int8x16x3_t a, int8x8_t b) {
-  // CHECK: test_vqtbl3_s8
+  // CHECK-LABEL: test_vqtbl3_s8
   return vqtbl3_s8(a, b);
-  // CHECK: tbl {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbl {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 int8x8_t test_vtbl4_s8(int8x8x4_t a, int8x8_t b) {
-  // CHECK: test_vtbl4_s8
+  // CHECK-LABEL: test_vtbl4_s8
   return vtbl4_s8(a, b);
-  // CHECK: tbl {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbl {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 int8x8_t test_vqtbl4_s8(int8x16x4_t a, int8x8_t b) {
-  // CHECK: test_vqtbl4_s8
+  // CHECK-LABEL: test_vqtbl4_s8
   return vqtbl4_s8(a, b);
-  // CHECK: tbl {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbl {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 int8x16_t test_vqtbl1q_s8(int8x16_t a, int8x16_t b) {
-  // CHECK: test_vqtbl1q_s8
+  // CHECK-LABEL: test_vqtbl1q_s8
   return vqtbl1q_s8(a, b);
-  // CHECK: tbl {{v[0-9]+}}.16b, {{{v[0-9]+}}.16b}, {{v[0-9]+}}.16b
+  // CHECK: tbl {{v[0-9]+}}.16b, {{{ ?v[0-9]+.16b ?}}}, {{v[0-9]+}}.16b
 }
 
 int8x16_t test_vqtbl2q_s8(int8x16x2_t a, int8x16_t b) {
-  // CHECK: test_vqtbl2q_s8
+  // CHECK-LABEL: test_vqtbl2q_s8
   return vqtbl2q_s8(a, b);
-  // CHECK: tbl {{v[0-9]+}}.16b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.16b
+  // CHECK: tbl {{v[0-9]+}}.16b, {{{ ?v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.16b
 }
 
 int8x16_t test_vqtbl3q_s8(int8x16x3_t a, int8x16_t b) {
-  // CHECK: test_vqtbl3q_s8
+  // CHECK-LABEL: test_vqtbl3q_s8
   return vqtbl3q_s8(a, b);
-  // CHECK: tbl {{v[0-9]+}}.16b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.16b
+  // CHECK: tbl {{v[0-9]+}}.16b, {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.16b
 }
 
 int8x16_t test_vqtbl4q_s8(int8x16x4_t a, int8x16_t b) {
-  // CHECK: test_vqtbl4q_s8
+  // CHECK-LABEL: test_vqtbl4q_s8
   return vqtbl4q_s8(a, b);
-  // CHECK: tbl {{v[0-9]+}}.16b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.16b
+  // CHECK: tbl {{v[0-9]+}}.16b, {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.16b
 }
 
 int8x8_t test_vtbx1_s8(int8x8_t a, int8x8_t b, int8x8_t c) {
-  // CHECK: test_vtbx1_s8
+  // CHECK-LABEL: test_vtbx1_s8
   return vtbx1_s8(a, b, c);
-  // CHECK: movi {{v[0-9]+}}.8b, #0
+  // CHECK: movi {{v[0-9]+.8b|d[0-9]+}}, #0
   // CHECK: ins {{v[0-9]+}}.d[1], {{v[0-9]+}}.d[0]
-  // CHECK: tbl {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbl {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
   // CHECK: cmhs {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
   // CHECK: bsl {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 int8x8_t test_vtbx2_s8(int8x8_t a, int8x8x2_t b, int8x8_t c) {
-  // CHECK: test_vtbx2_s8
+  // CHECK-LABEL: test_vtbx2_s8
   return vtbx2_s8(a, b, c);
-  // CHECK: tbx {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbx {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 int8x8_t test_vtbx3_s8(int8x8_t a, int8x8x3_t b, int8x8_t c) {
-  // CHECK: test_vtbx3_s8
+  // CHECK-LABEL: test_vtbx3_s8
   return vtbx3_s8(a, b, c);
-  // CHECK: movi {{v[0-9]+}}.8b, #0
+  // CHECK: movi {{v[0-9]+.8b|d[0-9]+}}, #0
   // CHECK: ins {{v[0-9]+}}.d[1], {{v[0-9]+}}.d[0]
-  // CHECK: tbl {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbl {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
   // CHECK: cmhs {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
   // CHECK: bsl {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 int8x8_t test_vtbx4_s8(int8x8_t a, int8x8x4_t b, int8x8_t c) {
-  // CHECK: test_vtbx4_s8
+  // CHECK-LABEL: test_vtbx4_s8
   return vtbx4_s8(a, b, c);
-  // CHECK: tbx {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbx {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 int8x8_t test_vqtbx1_s8(int8x8_t a, int8x16_t b, int8x8_t c) {
-  // CHECK: test_vqtbx1_s8
+  // CHECK-LABEL: test_vqtbx1_s8
   return vqtbx1_s8(a, b, c);
-  // CHECK: tbx {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbx {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 int8x8_t test_vqtbx2_s8(int8x8_t a, int8x16x2_t b, int8x8_t c) {
-  // CHECK: test_vqtbx2_s8
+  // CHECK-LABEL: test_vqtbx2_s8
   return vqtbx2_s8(a, b, c);
-  // CHECK: tbx {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbx {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 int8x8_t test_vqtbx3_s8(int8x8_t a, int8x16x3_t b, int8x8_t c) {
-  // CHECK: test_vqtbx3_s8
+  // CHECK-LABEL: test_vqtbx3_s8
   return vqtbx3_s8(a, b, c);
-  // CHECK: tbx {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbx {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 int8x8_t test_vqtbx4_s8(int8x8_t a, int8x16x4_t b, int8x8_t c) {
-  // CHECK: test_vqtbx4_s8
+  // CHECK-LABEL: test_vqtbx4_s8
   return vqtbx4_s8(a, b, c);
-  // CHECK: tbx {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbx {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 int8x16_t test_vqtbx1q_s8(int8x16_t a, int8x16_t b, int8x16_t c) {
-  // CHECK: test_vqtbx1q_s8
+  // CHECK-LABEL: test_vqtbx1q_s8
   return vqtbx1q_s8(a, b, c);
-  // CHECK: tbx {{v[0-9]+}}.16b, {{{v[0-9]+}}.16b}, {{v[0-9]+}}.16b
+  // CHECK: tbx {{v[0-9]+}}.16b, {{{ ?v[0-9]+.16b ?}}}, {{v[0-9]+}}.16b
 }
 
 int8x16_t test_vqtbx2q_s8(int8x16_t a, int8x16x2_t b, int8x16_t c) {
-  // CHECK: test_vqtbx2q_s8
+  // CHECK-LABEL: test_vqtbx2q_s8
   return vqtbx2q_s8(a, b, c);
-  // CHECK: tbx {{v[0-9]+}}.16b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.16b
+  // CHECK: tbx {{v[0-9]+}}.16b, {{{ ?v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.16b
 }
 
 int8x16_t test_vqtbx3q_s8(int8x16_t a, int8x16x3_t b, int8x16_t c) {
-  // CHECK: test_vqtbx3q_s8
+  // CHECK-LABEL: test_vqtbx3q_s8
   return vqtbx3q_s8(a, b, c);
-  // CHECK: tbx {{v[0-9]+}}.16b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.16b
+  // CHECK: tbx {{v[0-9]+}}.16b, {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.16b
 }
 
 int8x16_t test_vqtbx4q_s8(int8x16_t a, int8x16x4_t b, int8x16_t c) {
-  // CHECK: test_vqtbx4q_s8
+  // CHECK-LABEL: test_vqtbx4q_s8
   return vqtbx4q_s8(a, b, c);
-  // CHECK: tbx {{v[0-9]+}}.16b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.16b
+  // CHECK: tbx {{v[0-9]+}}.16b, {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.16b
 }
 
 uint8x8_t test_vtbl1_u8(uint8x8_t a, uint8x8_t b) {
-  // CHECK: test_vtbl1_u8
+  // CHECK-LABEL: test_vtbl1_u8
   return vtbl1_u8(a, b);
-  // CHECK: tbl {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbl {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 uint8x8_t test_vqtbl1_u8(uint8x16_t a, uint8x8_t b) {
-  // CHECK: test_vqtbl1_u8
+  // CHECK-LABEL: test_vqtbl1_u8
   return vqtbl1_u8(a, b);
-  // CHECK: tbl {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbl {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 uint8x8_t test_vtbl2_u8(uint8x8x2_t a, uint8x8_t b) {
-  // CHECK: test_vtbl2_u8
+  // CHECK-LABEL: test_vtbl2_u8
   return vtbl2_u8(a, b);
-  // CHECK: tbl {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbl {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 uint8x8_t test_vqtbl2_u8(uint8x16x2_t a, uint8x8_t b) {
-  // CHECK: test_vqtbl2_u8
+  // CHECK-LABEL: test_vqtbl2_u8
   return vqtbl2_u8(a, b);
-  // CHECK: tbl {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbl {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 uint8x8_t test_vtbl3_u8(uint8x8x3_t a, uint8x8_t b) {
-  // CHECK: test_vtbl3_u8
+  // CHECK-LABEL: test_vtbl3_u8
   return vtbl3_u8(a, b);
-  // CHECK: tbl {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbl {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 uint8x8_t test_vqtbl3_u8(uint8x16x3_t a, uint8x8_t b) {
-  // CHECK: test_vqtbl3_u8
+  // CHECK-LABEL: test_vqtbl3_u8
   return vqtbl3_u8(a, b);
-  // CHECK: tbl {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbl {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 uint8x8_t test_vtbl4_u8(uint8x8x4_t a, uint8x8_t b) {
-  // CHECK: test_vtbl4_u8
+  // CHECK-LABEL: test_vtbl4_u8
   return vtbl4_u8(a, b);
-  // CHECK: tbl {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbl {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 uint8x8_t test_vqtbl4_u8(uint8x16x4_t a, uint8x8_t b) {
-  // CHECK: test_vqtbl4_u8
+  // CHECK-LABEL: test_vqtbl4_u8
   return vqtbl4_u8(a, b);
-  // CHECK: tbl {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbl {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 uint8x16_t test_vqtbl1q_u8(uint8x16_t a, uint8x16_t b) {
-  // CHECK: test_vqtbl1q_u8
+  // CHECK-LABEL: test_vqtbl1q_u8
   return vqtbl1q_u8(a, b);
-  // CHECK: tbl {{v[0-9]+}}.16b, {{{v[0-9]+}}.16b}, {{v[0-9]+}}.16b
+  // CHECK: tbl {{v[0-9]+}}.16b, {{{ ?v[0-9]+.16b ?}}}, {{v[0-9]+}}.16b
 }
 
 uint8x16_t test_vqtbl2q_u8(uint8x16x2_t a, uint8x16_t b) {
-  // CHECK: test_vqtbl2q_u8
+  // CHECK-LABEL: test_vqtbl2q_u8
   return vqtbl2q_u8(a, b);
-  // CHECK: tbl {{v[0-9]+}}.16b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.16b
+  // CHECK: tbl {{v[0-9]+}}.16b, {{{ ?v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.16b
 }
 
 uint8x16_t test_vqtbl3q_u8(uint8x16x3_t a, uint8x16_t b) {
-  // CHECK: test_vqtbl3q_u8
+  // CHECK-LABEL: test_vqtbl3q_u8
   return vqtbl3q_u8(a, b);
-  // CHECK: tbl {{v[0-9]+}}.16b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.16b
+  // CHECK: tbl {{v[0-9]+}}.16b, {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.16b
 }
 
 uint8x16_t test_vqtbl4q_u8(uint8x16x4_t a, uint8x16_t b) {
-  // CHECK: test_vqtbl4q_u8
+  // CHECK-LABEL: test_vqtbl4q_u8
   return vqtbl4q_u8(a, b);
-  // CHECK: tbl {{v[0-9]+}}.16b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.16b
+  // CHECK: tbl {{v[0-9]+}}.16b, {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.16b
 }
 
 uint8x8_t test_vtbx1_u8(uint8x8_t a, uint8x8_t b, uint8x8_t c) {
-  // CHECK: test_vtbx1_u8
+  // CHECK-LABEL: test_vtbx1_u8
   return vtbx1_u8(a, b, c);
-  // CHECK: movi {{v[0-9]+}}.8b, #0
+  // CHECK: movi {{v[0-9]+.8b|d[0-9]+}}, #0
   // CHECK: ins {{v[0-9]+}}.d[1], {{v[0-9]+}}.d[0]
-  // CHECK: tbl {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbl {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
   // CHECK: cmhs {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
   // CHECK: bsl {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint8x8_t test_vtbx2_u8(uint8x8_t a, uint8x8x2_t b, uint8x8_t c) {
-  // CHECK: test_vtbx2_u8
+  // CHECK-LABEL: test_vtbx2_u8
   return vtbx2_u8(a, b, c);
-  // CHECK: tbx {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbx {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 uint8x8_t test_vtbx3_u8(uint8x8_t a, uint8x8x3_t b, uint8x8_t c) {
-  // CHECK: test_vtbx3_u8
+  // CHECK-LABEL: test_vtbx3_u8
   return vtbx3_u8(a, b, c);
-  // CHECK: movi {{v[0-9]+}}.8b, #0
+  // CHECK: movi {{v[0-9]+.8b|d[0-9]+}}, #0
   // CHECK: ins {{v[0-9]+}}.d[1], {{v[0-9]+}}.d[0]
-  // CHECK: tbl {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbl {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
   // CHECK: cmhs {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
   // CHECK: bsl {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 uint8x8_t test_vtbx4_u8(uint8x8_t a, uint8x8x4_t b, uint8x8_t c) {
-  // CHECK: test_vtbx4_u8
+  // CHECK-LABEL: test_vtbx4_u8
   return vtbx4_u8(a, b, c);
-  // CHECK: tbx {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbx {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 uint8x8_t test_vqtbx1_u8(uint8x8_t a, uint8x16_t b, uint8x8_t c) {
-  // CHECK: test_vqtbx1_u8
+  // CHECK-LABEL: test_vqtbx1_u8
   return vqtbx1_u8(a, b, c);
-  // CHECK: tbx {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbx {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 uint8x8_t test_vqtbx2_u8(uint8x8_t a, uint8x16x2_t b, uint8x8_t c) {
-  // CHECK: test_vqtbx2_u8
+  // CHECK-LABEL: test_vqtbx2_u8
   return vqtbx2_u8(a, b, c);
-  // CHECK: tbx {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbx {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 uint8x8_t test_vqtbx3_u8(uint8x8_t a, uint8x16x3_t b, uint8x8_t c) {
-  // CHECK: test_vqtbx3_u8
+  // CHECK-LABEL: test_vqtbx3_u8
   return vqtbx3_u8(a, b, c);
-  // CHECK: tbx {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbx {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 uint8x8_t test_vqtbx4_u8(uint8x8_t a, uint8x16x4_t b, uint8x8_t c) {
-  // CHECK: test_vqtbx4_u8
+  // CHECK-LABEL: test_vqtbx4_u8
   return vqtbx4_u8(a, b, c);
-  // CHECK: tbx {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbx {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 uint8x16_t test_vqtbx1q_u8(uint8x16_t a, uint8x16_t b, uint8x16_t c) {
-  // CHECK: test_vqtbx1q_u8
+  // CHECK-LABEL: test_vqtbx1q_u8
   return vqtbx1q_u8(a, b, c);
-  // CHECK: tbx {{v[0-9]+}}.16b, {{{v[0-9]+}}.16b}, {{v[0-9]+}}.16b
+  // CHECK: tbx {{v[0-9]+}}.16b, {{{ ?v[0-9]+.16b ?}}}, {{v[0-9]+}}.16b
 }
 
 uint8x16_t test_vqtbx2q_u8(uint8x16_t a, uint8x16x2_t b, uint8x16_t c) {
-  // CHECK: test_vqtbx2q_u8
+  // CHECK-LABEL: test_vqtbx2q_u8
   return vqtbx2q_u8(a, b, c);
-  // CHECK: tbx {{v[0-9]+}}.16b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.16b
+  // CHECK: tbx {{v[0-9]+}}.16b, {{{ ?v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.16b
 }
 
 uint8x16_t test_vqtbx3q_u8(uint8x16_t a, uint8x16x3_t b, uint8x16_t c) {
-  // CHECK: test_vqtbx3q_u8
+  // CHECK-LABEL: test_vqtbx3q_u8
   return vqtbx3q_u8(a, b, c);
-  // CHECK: tbx {{v[0-9]+}}.16b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.16b
+  // CHECK: tbx {{v[0-9]+}}.16b, {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.16b
 }
 
 uint8x16_t test_vqtbx4q_u8(uint8x16_t a, uint8x16x4_t b, uint8x16_t c) {
-  // CHECK: test_vqtbx4q_u8
+  // CHECK-LABEL: test_vqtbx4q_u8
   return vqtbx4q_u8(a, b, c);
-  // CHECK: tbx {{v[0-9]+}}.16b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.16b
+  // CHECK: tbx {{v[0-9]+}}.16b, {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.16b
 }
 
 poly8x8_t test_vtbl1_p8(poly8x8_t a, uint8x8_t b) {
-  // CHECK: test_vtbl1_p8
+  // CHECK-LABEL: test_vtbl1_p8
   return vtbl1_p8(a, b);
-  // CHECK: tbl {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbl {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 poly8x8_t test_vqtbl1_p8(poly8x16_t a, uint8x8_t b) {
-  // CHECK: test_vqtbl1_p8
+  // CHECK-LABEL: test_vqtbl1_p8
   return vqtbl1_p8(a, b);
-  // CHECK: tbl {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbl {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 poly8x8_t test_vtbl2_p8(poly8x8x2_t a, uint8x8_t b) {
-  // CHECK: test_vtbl2_p8
+  // CHECK-LABEL: test_vtbl2_p8
   return vtbl2_p8(a, b);
-  // CHECK: tbl {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbl {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 poly8x8_t test_vqtbl2_p8(poly8x16x2_t a, uint8x8_t b) {
-  // CHECK: test_vqtbl2_p8
+  // CHECK-LABEL: test_vqtbl2_p8
   return vqtbl2_p8(a, b);
-  // CHECK: tbl {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbl {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 poly8x8_t test_vtbl3_p8(poly8x8x3_t a, uint8x8_t b) {
-  // CHECK: test_vtbl3_p8
+  // CHECK-LABEL: test_vtbl3_p8
   return vtbl3_p8(a, b);
-  // CHECK: tbl {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbl {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 poly8x8_t test_vqtbl3_p8(poly8x16x3_t a, uint8x8_t b) {
-  // CHECK: test_vqtbl3_p8
+  // CHECK-LABEL: test_vqtbl3_p8
   return vqtbl3_p8(a, b);
-  // CHECK: tbl {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbl {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 poly8x8_t test_vtbl4_p8(poly8x8x4_t a, uint8x8_t b) {
-  // CHECK: test_vtbl4_p8
+  // CHECK-LABEL: test_vtbl4_p8
   return vtbl4_p8(a, b);
-  // CHECK: tbl {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbl {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 poly8x8_t test_vqtbl4_p8(poly8x16x4_t a, uint8x8_t b) {
-  // CHECK: test_vqtbl4_p8
+  // CHECK-LABEL: test_vqtbl4_p8
   return vqtbl4_p8(a, b);
-  // CHECK: tbl {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbl {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 poly8x16_t test_vqtbl1q_p8(poly8x16_t a, uint8x16_t b) {
-  // CHECK: test_vqtbl1q_p8
+  // CHECK-LABEL: test_vqtbl1q_p8
   return vqtbl1q_p8(a, b);
-  // CHECK: tbl {{v[0-9]+}}.16b, {{{v[0-9]+}}.16b}, {{v[0-9]+}}.16b
+  // CHECK: tbl {{v[0-9]+}}.16b, {{{ ?v[0-9]+.16b ?}}}, {{v[0-9]+}}.16b
 }
 
 poly8x16_t test_vqtbl2q_p8(poly8x16x2_t a, uint8x16_t b) {
-  // CHECK: test_vqtbl2q_p8
+  // CHECK-LABEL: test_vqtbl2q_p8
   return vqtbl2q_p8(a, b);
-  // CHECK: tbl {{v[0-9]+}}.16b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.16b
+  // CHECK: tbl {{v[0-9]+}}.16b, {{{ ?v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.16b
 }
 
 poly8x16_t test_vqtbl3q_p8(poly8x16x3_t a, uint8x16_t b) {
-  // CHECK: test_vqtbl3q_p8
+  // CHECK-LABEL: test_vqtbl3q_p8
   return vqtbl3q_p8(a, b);
-  // CHECK: tbl {{v[0-9]+}}.16b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.16b
+  // CHECK: tbl {{v[0-9]+}}.16b, {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.16b
 }
 
 poly8x16_t test_vqtbl4q_p8(poly8x16x4_t a, uint8x16_t b) {
-  // CHECK: test_vqtbl4q_p8
+  // CHECK-LABEL: test_vqtbl4q_p8
   return vqtbl4q_p8(a, b);
-  // CHECK: tbl {{v[0-9]+}}.16b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.16b
+  // CHECK: tbl {{v[0-9]+}}.16b, {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.16b
 }
 
 poly8x8_t test_vtbx1_p8(poly8x8_t a, poly8x8_t b, uint8x8_t c) {
-  // CHECK: test_vtbx1_p8
+  // CHECK-LABEL: test_vtbx1_p8
   return vtbx1_p8(a, b, c);
-  // CHECK: movi {{v[0-9]+}}.8b, #0
+  // CHECK: movi {{v[0-9]+.8b|d[0-9]+}}, #0
   // CHECK: ins {{v[0-9]+}}.d[1], {{v[0-9]+}}.d[0]
-  // CHECK: tbl {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbl {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
   // CHECK: cmhs {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
   // CHECK: bsl {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 poly8x8_t test_vtbx2_p8(poly8x8_t a, poly8x8x2_t b, uint8x8_t c) {
-  // CHECK: test_vtbx2_p8
+  // CHECK-LABEL: test_vtbx2_p8
   return vtbx2_p8(a, b, c);
-  // CHECK: tbx {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbx {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 poly8x8_t test_vtbx3_p8(poly8x8_t a, poly8x8x3_t b, uint8x8_t c) {
-  // CHECK: test_vtbx3_p8
+  // CHECK-LABEL: test_vtbx3_p8
   return vtbx3_p8(a, b, c);
-  // CHECK: movi {{v[0-9]+}}.8b, #0
+  // CHECK: movi {{v[0-9]+.8b|d[0-9]+}}, #0
   // CHECK: ins {{v[0-9]+}}.d[1], {{v[0-9]+}}.d[0]
-  // CHECK: tbl {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbl {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
   // CHECK: cmhs {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
   // CHECK: bsl {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 poly8x8_t test_vtbx4_p8(poly8x8_t a, poly8x8x4_t b, uint8x8_t c) {
-  // CHECK: test_vtbx4_p8
+  // CHECK-LABEL: test_vtbx4_p8
   return vtbx4_p8(a, b, c);
-  // CHECK: tbx {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbx {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 poly8x8_t test_vqtbx1_p8(poly8x8_t a, uint8x16_t b, uint8x8_t c) {
-  // CHECK: test_vqtbx1_p8
+  // CHECK-LABEL: test_vqtbx1_p8
   return vqtbx1_p8(a, b, c);
-  // CHECK: tbx {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbx {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 poly8x8_t test_vqtbx2_p8(poly8x8_t a, poly8x16x2_t b, uint8x8_t c) {
-  // CHECK: test_vqtbx2_p8
+  // CHECK-LABEL: test_vqtbx2_p8
   return vqtbx2_p8(a, b, c);
-  // CHECK: tbx {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbx {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 poly8x8_t test_vqtbx3_p8(poly8x8_t a, poly8x16x3_t b, uint8x8_t c) {
-  // CHECK: test_vqtbx3_p8
+  // CHECK-LABEL: test_vqtbx3_p8
   return vqtbx3_p8(a, b, c);
-  // CHECK: tbx {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbx {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 poly8x8_t test_vqtbx4_p8(poly8x8_t a, poly8x16x4_t b, uint8x8_t c) {
-  // CHECK: test_vqtbx4_p8
+  // CHECK-LABEL: test_vqtbx4_p8
   return vqtbx4_p8(a, b, c);
-  // CHECK: tbx {{v[0-9]+}}.8b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.8b
+  // CHECK: tbx {{v[0-9]+}}.8b, {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.8b
 }
 
 poly8x16_t test_vqtbx1q_p8(poly8x16_t a, uint8x16_t b, uint8x16_t c) {
-  // CHECK: test_vqtbx1q_p8
+  // CHECK-LABEL: test_vqtbx1q_p8
   return vqtbx1q_p8(a, b, c);
-  // CHECK: tbx {{v[0-9]+}}.16b, {{{v[0-9]+}}.16b}, {{v[0-9]+}}.16b
+  // CHECK: tbx {{v[0-9]+}}.16b, {{{ ?v[0-9]+.16b ?}}}, {{v[0-9]+}}.16b
 }
 
 poly8x16_t test_vqtbx2q_p8(poly8x16_t a, poly8x16x2_t b, uint8x16_t c) {
-  // CHECK: test_vqtbx2q_p8
+  // CHECK-LABEL: test_vqtbx2q_p8
   return vqtbx2q_p8(a, b, c);
-  // CHECK: tbx {{v[0-9]+}}.16b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.16b
+  // CHECK: tbx {{v[0-9]+}}.16b, {{{ ?v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.16b
 }
 
 poly8x16_t test_vqtbx3q_p8(poly8x16_t a, poly8x16x3_t b, uint8x16_t c) {
-  // CHECK: test_vqtbx3q_p8
+  // CHECK-LABEL: test_vqtbx3q_p8
   return vqtbx3q_p8(a, b, c);
-  // CHECK: tbx {{v[0-9]+}}.16b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.16b
+  // CHECK: tbx {{v[0-9]+}}.16b, {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.16b
 }
 
 poly8x16_t test_vqtbx4q_p8(poly8x16_t a, poly8x16x4_t b, uint8x16_t c) {
-  // CHECK: test_vqtbx4q_p8
+  // CHECK-LABEL: test_vqtbx4q_p8
   return vqtbx4q_p8(a, b, c);
-  // CHECK: tbx {{v[0-9]+}}.16b, {{{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b}, {{v[0-9]+}}.16b
+  // CHECK: tbx {{v[0-9]+}}.16b, {{{ ?v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b, v[0-9]+.16b ?}}}, {{v[0-9]+}}.16b
 }
diff --git a/test/CodeGen/aarch64-neon-vcombine.c b/test/CodeGen/aarch64-neon-vcombine.c
new file mode 100644
index 0000000..a750b8e
--- /dev/null
+++ b/test/CodeGen/aarch64-neon-vcombine.c
@@ -0,0 +1,90 @@
+// REQUIRES: aarch64-registered-target
+// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon -S -O3 -o - %s | FileCheck %s
+
+// Test new aarch64 intrinsics and types
+
+#include <arm_neon.h>
+
+int8x16_t test_vcombine_s8(int8x8_t low, int8x8_t high) {
+  // CHECK-LABEL: test_vcombine_s8:
+  return vcombine_s8(low, high);
+  // CHECK: ins	v0.d[1], v1.d[0]
+}
+
+int16x8_t test_vcombine_s16(int16x4_t low, int16x4_t high) {
+  // CHECK-LABEL: test_vcombine_s16:
+  return vcombine_s16(low, high);
+  // CHECK: ins	v0.d[1], v1.d[0]
+}
+
+int32x4_t test_vcombine_s32(int32x2_t low, int32x2_t high) {
+  // CHECK-LABEL: test_vcombine_s32:
+  return vcombine_s32(low, high);
+  // CHECK: ins	v0.d[1], v1.d[0]
+}
+
+int64x2_t test_vcombine_s64(int64x1_t low, int64x1_t high) {
+  // CHECK-LABEL: test_vcombine_s64:
+  return vcombine_s64(low, high);
+  // CHECK: ins	v0.d[1], v1.d[0]
+}
+
+uint8x16_t test_vcombine_u8(uint8x8_t low, uint8x8_t high) {
+  // CHECK-LABEL: test_vcombine_u8:
+  return vcombine_u8(low, high);
+  // CHECK: ins	v0.d[1], v1.d[0]
+}
+
+uint16x8_t test_vcombine_u16(uint16x4_t low, uint16x4_t high) {
+  // CHECK-LABEL: test_vcombine_u16:
+  return vcombine_u16(low, high);
+  // CHECK: ins	v0.d[1], v1.d[0]
+}
+
+uint32x4_t test_vcombine_u32(uint32x2_t low, uint32x2_t high) {
+  // CHECK-LABEL: test_vcombine_u32:
+  return vcombine_u32(low, high);
+  // CHECK: ins	v0.d[1], v1.d[0]
+}
+
+uint64x2_t test_vcombine_u64(uint64x1_t low, uint64x1_t high) {
+  // CHECK-LABEL: test_vcombine_u64:
+  return vcombine_u64(low, high);
+  // CHECK: ins	v0.d[1], v1.d[0]
+}
+
+poly64x2_t test_vcombine_p64(poly64x1_t low, poly64x1_t high) {
+  // CHECK-LABEL: test_vcombine_p64:
+  return vcombine_p64(low, high);
+  // CHECK: ins	v0.d[1], v1.d[0]
+}
+
+float16x8_t test_vcombine_f16(float16x4_t low, float16x4_t high) {
+  // CHECK-LABEL: test_vcombine_f16:
+  return vcombine_f16(low, high);
+  // CHECK: ins	v0.d[1], v1.d[0]
+}
+
+float32x4_t test_vcombine_f32(float32x2_t low, float32x2_t high) {
+  // CHECK-LABEL: test_vcombine_f32:
+  return vcombine_f32(low, high);
+  // CHECK: ins	v0.d[1], v1.d[0]
+}
+
+poly8x16_t test_vcombine_p8(poly8x8_t low, poly8x8_t high) {
+  // CHECK-LABEL: test_vcombine_p8:
+  return vcombine_p8(low, high);
+  // CHECK: ins	v0.d[1], v1.d[0]
+}
+
+poly16x8_t test_vcombine_p16(poly16x4_t low, poly16x4_t high) {
+  // CHECK-LABEL: test_vcombine_p16:
+  return vcombine_p16(low, high);
+  // CHECK: ins	v0.d[1], v1.d[0]
+}
+
+float64x2_t test_vcombine_f64(float64x1_t low, float64x1_t high) {
+  // CHECK-LABEL: test_vcombine_f64:
+  return vcombine_f64(low, high);
+  // CHECK: ins	v0.d[1], v1.d[0]
+}
diff --git a/test/CodeGen/aarch64-neon-vget-hilo.c b/test/CodeGen/aarch64-neon-vget-hilo.c
index 9edd31a..0959d09 100644
--- a/test/CodeGen/aarch64-neon-vget-hilo.c
+++ b/test/CodeGen/aarch64-neon-vget-hilo.c
@@ -1,176 +1,176 @@
 // REQUIRES: aarch64-registered-target
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +neon \
-// RUN:   -ffp-contract=fast -S -O3 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \
+// RUN:   -ffp-contract=fast -S -O3 -o - %s | FileCheck %s --check-prefix CHECK-COMMON --check-prefix CHECK-ARM64
 
 // Test new aarch64 intrinsics and types
 
 #include <arm_neon.h>
 
 int8x8_t test_vget_high_s8(int8x16_t a) {
-   // CHECK: test_vget_high_s8
+  // CHECK-COMMON-LABEL: test_vget_high_s8:
   return vget_high_s8(a);
-  // CHECK: dup d0, {{v[0-9]+}}.d[1]
+  // CHECK-ARM64: ext v0.16b, v0.16b, v0.16b, #8
 }
 
 int16x4_t test_vget_high_s16(int16x8_t a) {
-   // CHECK: test_vget_high_s16
+  // CHECK-COMMON-LABEL: test_vget_high_s16:
   return vget_high_s16(a);
-  // CHECK: dup d0, {{v[0-9]+}}.d[1]
+  // CHECK-ARM64: ext v0.16b, v0.16b, v0.16b, #8
 }
 
 int32x2_t test_vget_high_s32(int32x4_t a) {
-   // CHECK: test_vget_high_s32
+  // CHECK-COMMON-LABEL: test_vget_high_s32:
   return vget_high_s32(a);
-  // CHECK: dup d0, {{v[0-9]+}}.d[1]
+  // CHECK-ARM64: ext v0.16b, v0.16b, v0.16b, #8
 }
 
 int64x1_t test_vget_high_s64(int64x2_t a) {
-   // CHECK: test_vget_high_s64
+  // CHECK-COMMON-LABEL: test_vget_high_s64:
   return vget_high_s64(a);
-  // CHECK: dup d0, {{v[0-9]+}}.d[1]
+  // CHECK-ARM64: ext v0.16b, v0.16b, v0.16b, #8
 }
 
 uint8x8_t test_vget_high_u8(uint8x16_t a) {
-   // CHECK: test_vget_high_u8
+  // CHECK-COMMON-LABEL: test_vget_high_u8:
   return vget_high_u8(a);
-  // CHECK: dup d0, {{v[0-9]+}}.d[1]
+  // CHECK-ARM64: ext v0.16b, v0.16b, v0.16b, #8
 }
 
 uint16x4_t test_vget_high_u16(uint16x8_t a) {
-   // CHECK: test_vget_high_u16
+  // CHECK-COMMON-LABEL: test_vget_high_u16:
   return vget_high_u16(a);
-  // CHECK: dup d0, {{v[0-9]+}}.d[1]
+  // CHECK-ARM64: ext v0.16b, v0.16b, v0.16b, #8
 }
 
 uint32x2_t test_vget_high_u32(uint32x4_t a) {
-   // CHECK: test_vget_high_u32
+  // CHECK-COMMON-LABEL: test_vget_high_u32:
   return vget_high_u32(a);
-  // CHECK: dup d0, {{v[0-9]+}}.d[1]
+  // CHECK-ARM64: ext v0.16b, v0.16b, v0.16b, #8
 }
 
 uint64x1_t test_vget_high_u64(uint64x2_t a) {
-   // CHECK: test_vget_high_u64
+  // CHECK-COMMON-LABEL: test_vget_high_u64:
   return vget_high_u64(a);
-  // CHECK: dup d0, {{v[0-9]+}}.d[1]
+  // CHECK-ARM64: ext v0.16b, v0.16b, v0.16b, #8
 }
 
 poly64x1_t test_vget_high_p64(poly64x2_t a) {
-   // CHECK: test_vget_high_p64
+  // CHECK-COMMON-LABEL: test_vget_high_p64:
   return vget_high_p64(a);
-  // CHECK: dup d0, {{v[0-9]+}}.d[1]
+  // CHECK-ARM64: ext v0.16b, v0.16b, v0.16b, #8
 }
 
 float16x4_t test_vget_high_f16(float16x8_t a) {
-   // CHECK: test_vget_high_f16
+  // CHECK-COMMON-LABEL: test_vget_high_f16:
   return vget_high_f16(a);
-  // CHECK: dup d0, {{v[0-9]+}}.d[1]
+  // CHECK-ARM64: ext v0.16b, v0.16b, v0.16b, #8
 }
 
 float32x2_t test_vget_high_f32(float32x4_t a) {
-   // CHECK: test_vget_high_f32
+  // CHECK-COMMON-LABEL: test_vget_high_f32:
   return vget_high_f32(a);
-  // CHECK: dup d0, {{v[0-9]+}}.d[1]
+  // CHECK-ARM64: ext v0.16b, v0.16b, v0.16b, #8
 }
 
 poly8x8_t test_vget_high_p8(poly8x16_t a) {
-   // CHECK: test_vget_high_p8
+  // CHECK-COMMON-LABEL: test_vget_high_p8:
   return vget_high_p8(a);
-  // CHECK: dup d0, {{v[0-9]+}}.d[1]
+  // CHECK-ARM64: ext v0.16b, v0.16b, v0.16b, #8
 }
 
 poly16x4_t test_vget_high_p16(poly16x8_t a) {
-   // CHECK: test_vget_high_p16
+  // CHECK-COMMON-LABEL: test_vget_high_p16
   return vget_high_p16(a);
-  // CHECK: dup d0, {{v[0-9]+}}.d[1]
+  // CHECK-ARM64: ext v0.16b, v0.16b, v0.16b, #8
 }
 
 float64x1_t test_vget_high_f64(float64x2_t a) {
-   // CHECK: test_vget_high_f64
+  // CHECK-COMMON-LABEL: test_vget_high_f64
   return vget_high_f64(a);
-  // CHECK: dup d0, {{v[0-9]+}}.d[1]
+  // CHECK-ARM64: ext v0.16b, v0.16b, v0.16b, #8
 }
 
 int8x8_t test_vget_low_s8(int8x16_t a) {
-   // CHECK: test_vget_low_s8
+  // CHECK-COMMON-LABEL: test_vget_low_s8:
   return vget_low_s8(a);
-  // CHECK: dup d0, {{v[0-9]+}}.d[0]
+  // CHECK-COMMON-NEXT: ret
 }
 
 int16x4_t test_vget_low_s16(int16x8_t a) {
-   // CHECK: test_vget_low_s16
+  // CHECK-COMMON-LABEL: test_vget_low_s16:
   return vget_low_s16(a);
-  // CHECK: dup d0, {{v[0-9]+}}.d[0]
+  // CHECK-COMMON-NEXT: ret
 }
 
 int32x2_t test_vget_low_s32(int32x4_t a) {
-   // CHECK: test_vget_low_s32
+  // CHECK-COMMON-LABEL: test_vget_low_s32:
   return vget_low_s32(a);
-  // CHECK: dup d0, {{v[0-9]+}}.d[0]
+  // CHECK-COMMON-NEXT: ret
 }
 
 int64x1_t test_vget_low_s64(int64x2_t a) {
-   // CHECK: test_vget_low_s64
+  // CHECK-COMMON-LABEL: test_vget_low_s64:
   return vget_low_s64(a);
-  // CHECK: dup d0, {{v[0-9]+}}.d[0]
+  // CHECK-COMMON-NEXT: ret
 }
 
 uint8x8_t test_vget_low_u8(uint8x16_t a) {
-   // CHECK: test_vget_low_u8
+  // CHECK-COMMON-LABEL: test_vget_low_u8:
   return vget_low_u8(a);
-  // CHECK: dup d0, {{v[0-9]+}}.d[0]
+  // CHECK-COMMON-NEXT: ret
 }
 
 uint16x4_t test_vget_low_u16(uint16x8_t a) {
-   // CHECK: test_vget_low_u16
+  // CHECK-COMMON-LABEL: test_vget_low_u16:
   return vget_low_u16(a);
-  // CHECK: dup d0, {{v[0-9]+}}.d[0]
+  // CHECK-COMMON-NEXT: ret
 }
 
 uint32x2_t test_vget_low_u32(uint32x4_t a) {
-   // CHECK: test_vget_low_u32
+  // CHECK-COMMON-LABEL: test_vget_low_u32:
   return vget_low_u32(a);
-  // CHECK: dup d0, {{v[0-9]+}}.d[0]
+  // CHECK-COMMON-NEXT: ret
 }
 
 uint64x1_t test_vget_low_u64(uint64x2_t a) {
-   // CHECK: test_vget_low_u64
+  // CHECK-COMMON-LABEL: test_vget_low_u64:
   return vget_low_u64(a);
-  // CHECK: dup d0, {{v[0-9]+}}.d[0]
+  // CHECK-COMMON-NEXT: ret
 }
 
 poly64x1_t test_vget_low_p64(poly64x2_t a) {
-   // CHECK: test_vget_low_p64
+  // CHECK-COMMON-LABEL: test_vget_low_p64:
   return vget_low_p64(a);
-  // CHECK: dup d0, {{v[0-9]+}}.d[0]
+  // CHECK-COMMON-NEXT: ret
 }
 
 float16x4_t test_vget_low_f16(float16x8_t a) {
-   // CHECK: test_vget_low_f16
+  // CHECK-COMMON-LABEL: test_vget_low_f16:
   return vget_low_f16(a);
-  // CHECK: dup d0, {{v[0-9]+}}.d[0]
+  // CHECK-COMMON-NEXT: ret
 }
 
 float32x2_t test_vget_low_f32(float32x4_t a) {
-   // CHECK: test_vget_low_f32
+  // CHECK-COMMON-LABEL: test_vget_low_f32:
   return vget_low_f32(a);
-  // CHECK: dup d0, {{v[0-9]+}}.d[0]
+  // CHECK-COMMON-NEXT: ret
 }
 
 poly8x8_t test_vget_low_p8(poly8x16_t a) {
-   // CHECK: test_vget_low_p8
+  // CHECK-COMMON-LABEL: test_vget_low_p8:
   return vget_low_p8(a);
-  // CHECK: dup d0, {{v[0-9]+}}.d[0]
+  // CHECK-COMMON-NEXT: ret
 }
 
 poly16x4_t test_vget_low_p16(poly16x8_t a) {
-   // CHECK: test_vget_low_p16
+  // CHECK-COMMON-LABEL: test_vget_low_p16:
   return vget_low_p16(a);
-  // CHECK: dup d0, {{v[0-9]+}}.d[0]
+  // CHECK-COMMON-NEXT: ret
 }
 
 float64x1_t test_vget_low_f64(float64x2_t a) {
-   // CHECK: test_vget_low_f64
+  // CHECK-COMMON-LABEL: test_vget_low_f64:
   return vget_low_f64(a);
-  // CHECK: dup d0, {{v[0-9]+}}.d[0]
+  // CHECK-COMMON-NEXT: ret
 }
 
diff --git a/test/CodeGen/aarch64-poly128.c b/test/CodeGen/aarch64-poly128.c
new file mode 100644
index 0000000..eebecf7
--- /dev/null
+++ b/test/CodeGen/aarch64-poly128.c
@@ -0,0 +1,205 @@
+// REQUIRES: aarch64-registered-target
+// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \
+// RUN:  -ffp-contract=fast -S -O3 -o - %s | FileCheck %s --check-prefix=CHECK \
+// RUN:  --check-prefix=CHECK-ARM64
+
+// Test new aarch64 intrinsics with poly128
+// FIXME: Currently, poly128_t equals to uint128, which will be spilt into
+// two 64-bit GPR(eg X0, X1). Now moving data from X0, X1 to FPR128 will
+// introduce 2 store and 1 load instructions(store X0, X1 to memory and
+// then load back to Q0). If target has NEON, this is better replaced by
+// FMOV or INS.
+
+#include <arm_neon.h>
+
+void test_vstrq_p128(poly128_t * ptr, poly128_t val) {
+  // CHECK-LABEL: test_vstrq_p128
+  vstrq_p128(ptr, val);
+
+  // CHECK-ARM64: stp {{x[0-9]+}}, {{x[0-9]+}}, [x0]
+}
+
+poly128_t test_vldrq_p128(poly128_t * ptr) {
+  // CHECK-LABEL: test_vldrq_p128
+  return vldrq_p128(ptr);
+
+  // CHECK-ARM64: ldp {{x[0-9]+}}, {{x[0-9]+}}, [x0]
+}
+
+void test_ld_st_p128(poly128_t * ptr) {
+  // CHECK-LABEL: test_ld_st_p128
+   vstrq_p128(ptr+1, vldrq_p128(ptr));
+
+ // CHECK-ARM64: ldp [[PLO:x[0-9]+]], [[PHI:x[0-9]+]], [{{x[0-9]+}}]
+ // CHECK-ARM64-NEXT: stp [[PLO]], [[PHI]], [{{x[0-9]+}}, #16]
+}
+
+poly128_t test_vmull_p64(poly64_t a, poly64_t b) {
+  // CHECK-LABEL: test_vmull_p64
+  return vmull_p64(a, b);
+  // CHECK: pmull {{v[0-9]+}}.1q, {{v[0-9]+}}.1d, {{v[0-9]+}}.1d
+}
+
+poly128_t test_vmull_high_p64(poly64x2_t a, poly64x2_t b) {
+  // CHECK-LABEL: test_vmull_high_p64
+  return vmull_high_p64(a, b);
+  // CHECK: pmull2 {{v[0-9]+}}.1q, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
+}
+
+// CHECK-LABEL: test_vreinterpretq_p128_s8
+// CHECK: ret
+poly128_t test_vreinterpretq_p128_s8(int8x16_t a) {
+  return vreinterpretq_p128_s8(a);
+}
+
+// CHECK-LABEL: test_vreinterpretq_p128_s16
+// CHECK: ret
+poly128_t test_vreinterpretq_p128_s16(int16x8_t a) {
+  return vreinterpretq_p128_s16(a);
+}
+
+// CHECK-LABEL: test_vreinterpretq_p128_s32
+// CHECK: ret
+poly128_t test_vreinterpretq_p128_s32(int32x4_t a) {
+  return vreinterpretq_p128_s32(a);
+}
+
+// CHECK-LABEL: test_vreinterpretq_p128_s64
+// CHECK: ret
+poly128_t test_vreinterpretq_p128_s64(int64x2_t a) {
+  return vreinterpretq_p128_s64(a);
+}
+
+// CHECK-LABEL: test_vreinterpretq_p128_u8
+// CHECK: ret
+poly128_t test_vreinterpretq_p128_u8(uint8x16_t a) {
+  return vreinterpretq_p128_u8(a);
+}
+
+// CHECK-LABEL: test_vreinterpretq_p128_u16
+// CHECK: ret
+poly128_t test_vreinterpretq_p128_u16(uint16x8_t a) {
+  return vreinterpretq_p128_u16(a);
+}
+
+// CHECK-LABEL: test_vreinterpretq_p128_u32
+// CHECK: ret
+poly128_t test_vreinterpretq_p128_u32(uint32x4_t a) {
+  return vreinterpretq_p128_u32(a);
+}
+
+// CHECK-LABEL: test_vreinterpretq_p128_u64
+// CHECK: ret
+poly128_t test_vreinterpretq_p128_u64(uint64x2_t a) {
+  return vreinterpretq_p128_u64(a);
+}
+
+// CHECK-LABEL: test_vreinterpretq_p128_f32
+// CHECK: ret
+poly128_t test_vreinterpretq_p128_f32(float32x4_t a) {
+  return vreinterpretq_p128_f32(a);
+}
+
+// CHECK-LABEL: test_vreinterpretq_p128_f64
+// CHECK: ret
+poly128_t test_vreinterpretq_p128_f64(float64x2_t a) {
+  return vreinterpretq_p128_f64(a);
+}
+
+// CHECK-LABEL: test_vreinterpretq_p128_p8
+// CHECK: ret
+poly128_t test_vreinterpretq_p128_p8(poly8x16_t a) {
+  return vreinterpretq_p128_p8(a);
+}
+
+// CHECK-LABEL: test_vreinterpretq_p128_p16
+// CHECK: ret
+poly128_t test_vreinterpretq_p128_p16(poly16x8_t a) {
+  return vreinterpretq_p128_p16(a);
+}
+
+// CHECK-LABEL: test_vreinterpretq_p128_p64
+// CHECK: ret
+poly128_t test_vreinterpretq_p128_p64(poly64x2_t a) {
+  return vreinterpretq_p128_p64(a);
+}
+
+// CHECK-LABEL: test_vreinterpretq_s8_p128
+// CHECK: ret
+int8x16_t test_vreinterpretq_s8_p128(poly128_t a) {
+  return vreinterpretq_s8_p128(a);
+}
+
+// CHECK-LABEL: test_vreinterpretq_s16_p128
+// CHECK: ret
+int16x8_t test_vreinterpretq_s16_p128(poly128_t  a) {
+  return vreinterpretq_s16_p128(a);
+}
+
+// CHECK-LABEL: test_vreinterpretq_s32_p128
+// CHECK: ret
+int32x4_t test_vreinterpretq_s32_p128(poly128_t a) {
+  return vreinterpretq_s32_p128(a);
+}
+
+// CHECK-LABEL: test_vreinterpretq_s64_p128
+// CHECK: ret
+int64x2_t test_vreinterpretq_s64_p128(poly128_t  a) {
+  return vreinterpretq_s64_p128(a);
+}
+
+// CHECK-LABEL: test_vreinterpretq_u8_p128
+// CHECK: ret
+uint8x16_t test_vreinterpretq_u8_p128(poly128_t  a) {
+  return vreinterpretq_u8_p128(a);
+}
+
+// CHECK-LABEL: test_vreinterpretq_u16_p128
+// CHECK: ret
+uint16x8_t test_vreinterpretq_u16_p128(poly128_t  a) {
+  return vreinterpretq_u16_p128(a);
+}
+
+// CHECK-LABEL: test_vreinterpretq_u32_p128
+// CHECK: ret
+uint32x4_t test_vreinterpretq_u32_p128(poly128_t  a) {
+  return vreinterpretq_u32_p128(a);
+}
+
+// CHECK-LABEL: test_vreinterpretq_u64_p128
+// CHECK: ret
+uint64x2_t test_vreinterpretq_u64_p128(poly128_t  a) {
+  return vreinterpretq_u64_p128(a);
+}
+
+// CHECK-LABEL: test_vreinterpretq_f32_p128
+// CHECK: ret
+float32x4_t test_vreinterpretq_f32_p128(poly128_t  a) {
+  return vreinterpretq_f32_p128(a);
+}
+
+// CHECK-LABEL: test_vreinterpretq_f64_p128
+// CHECK: ret
+float64x2_t test_vreinterpretq_f64_p128(poly128_t  a) {
+  return vreinterpretq_f64_p128(a);
+}
+
+// CHECK-LABEL: test_vreinterpretq_p8_p128
+// CHECK: ret
+poly8x16_t test_vreinterpretq_p8_p128(poly128_t  a) {
+  return vreinterpretq_p8_p128(a);
+}
+
+// CHECK-LABEL: test_vreinterpretq_p16_p128
+// CHECK: ret
+poly16x8_t test_vreinterpretq_p16_p128(poly128_t  a) {
+  return vreinterpretq_p16_p128(a);
+}
+
+// CHECK-LABEL: test_vreinterpretq_p64_p128
+// CHECK: ret
+poly64x2_t test_vreinterpretq_p64_p128(poly128_t  a) {
+  return vreinterpretq_p64_p128(a);
+}
+
+
diff --git a/test/CodeGen/aarch64-poly64.c b/test/CodeGen/aarch64-poly64.c
index 3e19501..290cc69 100644
--- a/test/CodeGen/aarch64-poly64.c
+++ b/test/CodeGen/aarch64-poly64.c
@@ -1,282 +1,283 @@
 // REQUIRES: aarch64-registered-target
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +neon \
-// RUN:   -ffp-contract=fast -S -O3 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \
+// RUN:  -ffp-contract=fast -S -O3 -o - %s | FileCheck %s --check-prefix=CHECK \
+// RUN:  --check-prefix=CHECK-ARM64
 
 // Test new aarch64 intrinsics with poly64
 
 #include <arm_neon.h>
 
 uint64x1_t test_vceq_p64(poly64x1_t a, poly64x1_t b) {
-  // CHECK: test_vceq_p64
+  // CHECK-LABEL: test_vceq_p64
   return vceq_p64(a, b);
   // CHECK: cmeq {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
 }
 
 uint64x2_t test_vceqq_p64(poly64x2_t a, poly64x2_t b) {
-  // CHECK: test_vceqq_p64
+  // CHECK-LABEL: test_vceqq_p64
   return vceqq_p64(a, b);
   // CHECK: cmeq {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 uint64x1_t test_vtst_p64(poly64x1_t a, poly64x1_t b) {
-  // CHECK: test_vtst_p64
+  // CHECK-LABEL: test_vtst_p64
   return vtst_p64(a, b);
   // CHECK: cmtst {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
 }
 
 uint64x2_t test_vtstq_p64(poly64x2_t a, poly64x2_t b) {
-  // CHECK: test_vtstq_p64
+  // CHECK-LABEL: test_vtstq_p64
   return vtstq_p64(a, b);
   // CHECK: cmtst {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 poly64x1_t test_vbsl_p64(poly64x1_t a, poly64x1_t b, poly64x1_t c) {
-  // CHECK: test_vbsl_p64
+  // CHECK-LABEL: test_vbsl_p64
   return vbsl_p64(a, b, c);
   // CHECK: bsl {{v[0-9]+}}.8b, {{v[0-9]+}}.8b, {{v[0-9]+}}.8b
 }
 
 poly64x2_t test_vbslq_p64(poly64x2_t a, poly64x2_t b, poly64x2_t c) {
-  // CHECK: test_vbslq_p64
+  // CHECK-LABEL: test_vbslq_p64
   return vbslq_p64(a, b, c);
   // CHECK: bsl {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b
 }
 
 poly64_t test_vget_lane_p64(poly64x1_t v) {
-  // CHECK: test_vget_lane_p64
+  // CHECK-LABEL: test_vget_lane_p64
   return vget_lane_p64(v, 0);
   // CHECK: fmov  {{x[0-9]+}}, {{d[0-9]+}}
 }
 
 poly64_t test_vgetq_lane_p64(poly64x2_t v) {
-  // CHECK: test_vgetq_lane_p64
+  // CHECK-LABEL: test_vgetq_lane_p64
   return vgetq_lane_p64(v, 1);
-  // CHECK: umov  {{x[0-9]+}}, {{v[0-9]+}}.d[1]
+  // CHECK: {{mov|umov}}  {{x[0-9]+}}, {{v[0-9]+}}.d[1]
 }
 
 poly64x1_t test_vset_lane_p64(poly64_t a, poly64x1_t v) {
-  // CHECK: test_vset_lane_p64
+  // CHECK-LABEL: test_vset_lane_p64
   return vset_lane_p64(a, v, 0);
   // CHECK: fmov  {{d[0-9]+}}, {{x[0-9]+}}
 }
 
 poly64x2_t test_vsetq_lane_p64(poly64_t a, poly64x2_t v) {
-  // CHECK: test_vsetq_lane_p64
+  // CHECK-LABEL: test_vsetq_lane_p64
   return vsetq_lane_p64(a, v, 1);
   // CHECK: ins  {{v[0-9]+}}.d[1], {{x[0-9]+}}
 }
 
 poly64x1_t test_vcopy_lane_p64(poly64x1_t a, poly64x1_t b) {
-  // CHECK: test_vcopy_lane_p64
+  // CHECK-LABEL: test_vcopy_lane_p64
   return vcopy_lane_p64(a, 0, b, 0);
-  // CHECK: fmov  {{d[0-9]+}}, {{d[0-9]+}}
+
+  // CHECK-ARM64: mov v0.16b, v1.16b
 }
 
 poly64x2_t test_vcopyq_lane_p64(poly64x2_t a, poly64x1_t b) {
-  // CHECK: test_vcopyq_lane_p64
+  // CHECK-LABEL: test_vcopyq_lane_p64
   return vcopyq_lane_p64(a, 1, b, 0);
   // CHECK: ins  {{v[0-9]+}}.d[1], {{v[0-9]+}}.d[0]
 }
 
 poly64x2_t test_vcopyq_laneq_p64(poly64x2_t a, poly64x2_t b) {
-  // CHECK: test_vcopyq_laneq_p64
+  // CHECK-LABEL: test_vcopyq_laneq_p64
   return vcopyq_laneq_p64(a, 1, b, 1);
-  // CHECK: ins  {{v[0-9]+}}.d[1], {{v[0-9]+}}.d[1]
 }
 
 poly64x1_t test_vcreate_p64(uint64_t a) {
-  // CHECK: test_vcreate_p64
+  // CHECK-LABEL: test_vcreate_p64
   return vcreate_p64(a);
   // CHECK: fmov  {{d[0-9]+}}, {{x[0-9]+}}
 }
 
 poly64x1_t test_vdup_n_p64(poly64_t a) {
-  // CHECK: test_vdup_n_p64
+  // CHECK-LABEL: test_vdup_n_p64
   return vdup_n_p64(a);
   // CHECK: fmov {{d[0-9]+}}, {{x[0-9]+}}
 }
 poly64x2_t test_vdupq_n_p64(poly64_t a) {
-  // CHECK: test_vdup_n_p64
+  // CHECK-LABEL: test_vdupq_n_p64
   return vdupq_n_p64(a);
   // CHECK: dup {{v[0-9]+}}.2d, {{x[0-9]+}}
 }
 
 poly64x1_t test_vdup_lane_p64(poly64x1_t vec) {
-  // CHECK: test_vdup_lane_p64
+  // CHECK-LABEL: test_vdup_lane_p64
   return vdup_lane_p64(vec, 0);
   // CHECK: ret
 }
 
 poly64x2_t test_vdupq_lane_p64(poly64x1_t vec) {
-  // CHECK: test_vdupq_lane_p64
+  // CHECK-LABEL: test_vdupq_lane_p64
   return vdupq_lane_p64(vec, 0);
   // CHECK: dup {{v[0-9]+}}.2d, {{v[0-9]+}}.d[0]
 }
 
 poly64x2_t test_vdupq_laneq_p64(poly64x2_t vec) {
-  // CHECK: test_vdupq_laneq_p64
+  // CHECK-LABEL: test_vdupq_laneq_p64
   return vdupq_laneq_p64(vec, 1);
   // CHECK: dup {{v[0-9]+}}.2d, {{v[0-9]+}}.d[1]
 }
 
 poly64x2_t test_vcombine_p64(poly64x1_t low, poly64x1_t high) {
-  // CHECK: test_vcombine_p64
+  // CHECK-LABEL: test_vcombine_p64
   return vcombine_p64(low, high);
   // CHECK: ins {{v[0-9]+}}.d[1], {{v[0-9]+}}.d[0]
 }
 
 poly64x1_t test_vld1_p64(poly64_t const * ptr) {
-  // CHECK: test_vld1_p64
+  // CHECK-LABEL: test_vld1_p64
   return vld1_p64(ptr);
-  // CHECK:  ld1 {{{v[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK-ARM64: ldr {{d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 poly64x2_t test_vld1q_p64(poly64_t const * ptr) {
-  // CHECK: test_vld1q_p64
+  // CHECK-LABEL: test_vld1q_p64
   return vld1q_p64(ptr);
-  // CHECK:  ld1 {{{v[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK-ARM64: ldr {{q[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1_p64(poly64_t * ptr, poly64x1_t val) {
-  // CHECK: test_vst1_p64
+  // CHECK-LABEL: test_vst1_p64
   return vst1_p64(ptr, val);
-  // CHECK:  st1 {{{v[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK-ARM64: str {{d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst1q_p64(poly64_t * ptr, poly64x2_t val) {
-  // CHECK: test_vst1q_p64
+  // CHECK-LABEL: test_vst1q_p64
   return vst1q_p64(ptr, val);
-  // CHECK:  st1 {{{v[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK-ARM64: str {{q[0-9]+}}, [{{x[0-9]+|sp}}]
 }
 
 poly64x1x2_t test_vld2_p64(poly64_t const * ptr) {
-  // CHECK: test_vld2_p64
+  // CHECK-LABEL: test_vld2_p64
   return vld2_p64(ptr);
-  // CHECK: ld1 {{{v[0-9]+}}.1d, {{v[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ *v[0-9]+.1d, v[0-9]+.1d *}}}, [{{x[0-9]+|sp}}]
 }
 
 poly64x2x2_t test_vld2q_p64(poly64_t const * ptr) {
-  // CHECK: test_vld2q_p64
+  // CHECK-LABEL: test_vld2q_p64
   return vld2q_p64(ptr);
-  // CHECK: ld2 {{{v[0-9]+}}.2d, {{v[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: ld2 {{{ *v[0-9]+.2d, v[0-9]+.2d *}}}, [{{x[0-9]+|sp}}]
 }
 
 poly64x1x3_t test_vld3_p64(poly64_t const * ptr) {
-  // CHECK: test_vld3_p64
+  // CHECK-LABEL: test_vld3_p64
   return vld3_p64(ptr);
-  // CHECK: ld1 {{{v[0-9]+}}.1d, {{v[0-9]+}}.1d, {{v[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ *v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d *}}}, [{{x[0-9]+|sp}}]
 }
 
 poly64x2x3_t test_vld3q_p64(poly64_t const * ptr) {
-  // CHECK: test_vld3q_p64
+  // CHECK-LABEL: test_vld3q_p64
   return vld3q_p64(ptr);
-  // CHECK: ld3 {{{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: ld3 {{{ *v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d *}}}, [{{x[0-9]+|sp}}]
 }
 
 poly64x1x4_t test_vld4_p64(poly64_t const * ptr) {
-  // CHECK: test_vld4_p64
+  // CHECK-LABEL: test_vld4_p64
   return vld4_p64(ptr);
-  // CHECK: ld1 {{{v[0-9]+}}.1d, {{v[0-9]+}}.1d, {{v[0-9]+}}.1d, {{v[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK: ld1 {{{ *v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d *}}}, [{{x[0-9]+|sp}}]
 }
 
 poly64x2x4_t test_vld4q_p64(poly64_t const * ptr) {
-  // CHECK: test_vld4q_p64
+  // CHECK-LABEL: test_vld4q_p64
   return vld4q_p64(ptr);
-  // CHECK: ld4 {{{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK: ld4 {{{ *v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d *}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst2_p64(poly64_t * ptr, poly64x1x2_t val) {
-  // CHECK: test_vst2_p64
+  // CHECK-LABEL: test_vst2_p64
   return vst2_p64(ptr, val);
-  // CHECK:  st1 {{{v[0-9]+}}.1d, {{v[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK:  st1 {{{ *v[0-9]+.1d, v[0-9]+.1d *}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst2q_p64(poly64_t * ptr, poly64x2x2_t val) {
-  // CHECK: test_vst2q_p64
+  // CHECK-LABEL: test_vst2q_p64
   return vst2q_p64(ptr, val);
-  // CHECK:  st2 {{{v[0-9]+}}.2d, {{v[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK:  st2 {{{ *v[0-9]+.2d, v[0-9]+.2d *}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst3_p64(poly64_t * ptr, poly64x1x3_t val) {
-  // CHECK: test_vst3_p64
+  // CHECK-LABEL: test_vst3_p64
   return vst3_p64(ptr, val);
-  // CHECK:  st1 {{{v[0-9]+}}.1d, {{v[0-9]+}}.1d, {{v[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK:  st1 {{{ *v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d *}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst3q_p64(poly64_t * ptr, poly64x2x3_t val) {
-  // CHECK: test_vst3q_p64
+  // CHECK-LABEL: test_vst3q_p64
   return vst3q_p64(ptr, val);
-  // CHECK:  st3 {{{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK:  st3 {{{ *v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d *}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst4_p64(poly64_t * ptr, poly64x1x4_t val) {
-  // CHECK: test_vst4_p64
+  // CHECK-LABEL: test_vst4_p64
   return vst4_p64(ptr, val);
-  // CHECK:  st1 {{{v[0-9]+}}.1d, {{v[0-9]+}}.1d, {{v[0-9]+}}.1d, {{v[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK:  st1 {{{ *v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d, v[0-9]+.1d *}}}, [{{x[0-9]+|sp}}]
 }
 
 void test_vst4q_p64(poly64_t * ptr, poly64x2x4_t val) {
-  // CHECK: test_vst4q_p64
+  // CHECK-LABEL: test_vst4q_p64
   return vst4q_p64(ptr, val);
-  // CHECK:  st4 {{{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d}, [{{x[0-9]+|sp}}]
+  // CHECK:  st4 {{{ *v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d *}}}, [{{x[0-9]+|sp}}]
 }
 
 poly64x1_t test_vext_p64(poly64x1_t a, poly64x1_t b) {
-  // CHECK: test_vext_p64
+  // CHECK-LABEL: test_vext_p64
   return vext_u64(a, b, 0);
 
 }
 
 poly64x2_t test_vextq_p64(poly64x2_t a, poly64x2_t b) {
-  // CHECK: test_vextq_p64
+  // CHECK-LABEL: test_vextq_p64
   return vextq_p64(a, b, 1);
-  // CHECK: ext {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, #0x8
+  // CHECK: ext {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{v[0-9]+}}.16b, {{#0x8|#8}}
 }
 
 poly64x2_t test_vzip1q_p64(poly64x2_t a, poly64x2_t b) {
-  // CHECK: test_vzip1q_p64
+  // CHECK-LABEL: test_vzip1q_p64
   return vzip1q_p64(a, b);
-  // CHECK: ins {{v[0-9]+}}.d[1], {{v[0-9]+}}.d[0]
+  // CHECK-ARM64: zip1 {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 poly64x2_t test_vzip2q_p64(poly64x2_t a, poly64x2_t b) {
-  // CHECK: test_vzip2q_p64
+  // CHECK-LABEL: test_vzip2q_p64
   return vzip2q_u64(a, b);
-  // CHECK: ins {{v[0-9]+}}.d[0], {{v[0-9]+}}.d[1]
+  // CHECK-ARM64: zip2 {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 poly64x2_t test_vuzp1q_p64(poly64x2_t a, poly64x2_t b) {
-  // CHECK: test_vuzp1q_p64
+  // CHECK-LABEL: test_vuzp1q_p64
   return vuzp1q_p64(a, b);
-  // CHECK: ins {{v[0-9]+}}.d[1], {{v[0-9]+}}.d[0]
+  // CHECK-ARM64: zip1 {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 poly64x2_t test_vuzp2q_p64(poly64x2_t a, poly64x2_t b) {
-  // CHECK: test_vuzp2q_p64
+  // CHECK-LABEL: test_vuzp2q_p64
   return vuzp2q_u64(a, b);
-  // CHECK: ins {{v[0-9]+}}.d[0], {{v[0-9]+}}.d[1]
+  // CHECK-ARM64: zip2 {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 poly64x2_t test_vtrn1q_p64(poly64x2_t a, poly64x2_t b) {
-  // CHECK: test_vtrn1q_p64
+  // CHECK-LABEL: test_vtrn1q_p64
   return vtrn1q_p64(a, b);
-  // CHECK: ins {{v[0-9]+}}.d[1], {{v[0-9]+}}.d[0]
+  // CHECK-ARM64: zip1 {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 poly64x2_t test_vtrn2q_p64(poly64x2_t a, poly64x2_t b) {
-  // CHECK: test_vtrn2q_p64
+  // CHECK-LABEL: test_vtrn2q_p64
   return vtrn2q_u64(a, b);
-  // CHECK: ins {{v[0-9]+}}.d[0], {{v[0-9]+}}.d[1]
+  // CHECK-ARM64: zip2 {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, {{v[0-9]+}}.2d
 }
 
 poly64x1_t test_vsri_n_p64(poly64x1_t a, poly64x1_t b) {
-  // CHECK: test_vsri_n_p64
+  // CHECK-LABEL: test_vsri_n_p64
   return vsri_n_p64(a, b, 33);
   // CHECK: sri {{d[0-9]+}}, {{d[0-9]+}}, #33
 }
 
 poly64x2_t test_vsriq_n_p64(poly64x2_t a, poly64x2_t b) {
-  // CHECK: test_vsriq_n_p64
+  // CHECK-LABEL: test_vsriq_n_p64
   return vsriq_n_p64(a, b, 64);
   // CHECK: sri {{v[0-9]+}}.2d, {{v[0-9]+}}.2d, #64
 }
diff --git a/test/CodeGen/aarch64-type-sizes.c b/test/CodeGen/aarch64-type-sizes.c
index 3b9c9fc..b331b6c 100644
--- a/test/CodeGen/aarch64-type-sizes.c
+++ b/test/CodeGen/aarch64-type-sizes.c
@@ -1,7 +1,9 @@
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -emit-llvm -w -o - %s | FileCheck %s
-
+// RUN: %clang_cc1 -triple arm64_be-none-linux-gnu -emit-llvm -w -o - %s | FileCheck --check-prefix=CHECK --check-prefix=CHECK-BE %s
 // char by definition has size 1
 
+// CHECK-LE: target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"
+// CHECK-BE: target datalayout = "E-m:e-i64:64-i128:128-n32:64-S128"
+
 int check_short() {
   return sizeof(short);
 // CHECK: ret i32 2
diff --git a/test/CodeGen/aarch64-varargs.c b/test/CodeGen/aarch64-varargs.c
index 3d9cd86..f787afe 100644
--- a/test/CodeGen/aarch64-varargs.c
+++ b/test/CodeGen/aarch64-varargs.c
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -triple aarch64 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-linux-gnu -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=CHECK-LE %s
+// RUN: %clang_cc1 -triple arm64_be-linux-gnu -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=CHECK-BE %s
+
 #include <stdarg.h>
 
 // Obviously there's more than one way to implement va_arg. This test should at
@@ -22,6 +24,9 @@
 // CHECK: [[VAARG_IN_REG]]
 // CHECK: [[REG_TOP:%[a-z_0-9]+]] = load i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 1)
 // CHECK: [[REG_ADDR:%[a-z_0-9]+]] = getelementptr i8* [[REG_TOP]], i32 [[GR_OFFS]]
+// CHECK-BE: [[REG_ADDR_VAL:%[0-9]+]] = ptrtoint i8* [[REG_ADDR]] to i64
+// CHECK-BE: [[REG_ADDR_VAL_ALIGNED:%[a-z_0-9]*]] = add i64 [[REG_ADDR_VAL]], 4
+// CHECK-BE: [[REG_ADDR:%[0-9]+]] = inttoptr i64 [[REG_ADDR_VAL_ALIGNED]] to i8*
 // CHECK: [[FROMREG_ADDR:%[a-z_0-9]+]] = bitcast i8* [[REG_ADDR]] to i32*
 // CHECK: br label %[[VAARG_END:[a-z._0-9]+]]
 
@@ -29,6 +34,9 @@
 // CHECK: [[STACK:%[a-z_0-9]+]] = load i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 0)
 // CHECK: [[NEW_STACK:%[a-z_0-9]+]] = getelementptr i8* [[STACK]], i32 8
 // CHECK: store i8* [[NEW_STACK]], i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 0)
+// CHECK-BE: [[STACK_VAL:%[0-9]+]] = ptrtoint i8* [[STACK]] to i64
+// CHECK-BE: [[STACK_VAL_ALIGNED:%[a-z_0-9]*]] = add i64 [[STACK_VAL]], 4
+// CHECK-BE: [[STACK:%[0-9]+]] = inttoptr i64 [[STACK_VAL_ALIGNED]] to i8*
 // CHECK: [[FROMSTACK_ADDR:%[a-z_0-9]+]] = bitcast i8* [[STACK]] to i32*
 // CHECK: br label %[[VAARG_END]]
 
@@ -154,7 +162,7 @@
   return va_arg(the_list, double);
 // CHECK: [[VR_OFFS:%[a-z_0-9]+]] = load i32* getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 4)
 // CHECK: [[EARLY_ONSTACK:%[a-z_0-9]+]] = icmp sge i32 [[VR_OFFS]], 0
-// CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK]], label %[[VAARG_MAYBE_REG]]
+// CHECK: br i1 [[EARLY_ONSTACK]], label %[[VAARG_ON_STACK:[a-z_.0-9]+]], label %[[VAARG_MAYBE_REG]]
 
 // CHECK: [[VAARG_MAYBE_REG]]
 // CHECK: [[NEW_REG_OFFS:%[a-z_0-9]+]] = add i32 [[VR_OFFS]], 16
@@ -165,8 +173,11 @@
 // CHECK: [[VAARG_IN_REG]]
 // CHECK: [[REG_TOP:%[a-z_0-9]+]] = load i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 2)
 // CHECK: [[REG_ADDR:%[a-z_0-9]+]] = getelementptr i8* [[REG_TOP]], i32 [[VR_OFFS]]
+// CHECK-BE: [[REG_ADDR_VAL:%[0-9]+]] = ptrtoint i8* [[REG_ADDR]] to i64
+// CHECK-BE: [[REG_ADDR_VAL_ALIGNED:%[a-z_0-9]*]] = add i64 [[REG_ADDR_VAL]], 8
+// CHECK-BE: [[REG_ADDR:%[0-9]+]] = inttoptr i64 [[REG_ADDR_VAL_ALIGNED]] to i8*
 // CHECK: [[FROMREG_ADDR:%[a-z_0-9]+]] = bitcast i8* [[REG_ADDR]] to double*
-// CHECK: br label %[[VAARG_END]]
+// CHECK: br label %[[VAARG_END:[a-z._0-9]+]]
 
 // CHECK: [[VAARG_ON_STACK]]
 // CHECK: [[STACK:%[a-z_0-9]+]] = load i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 0)
@@ -201,12 +212,14 @@
 // CHECK: [[VAARG_IN_REG]]
 // CHECK: [[REG_TOP:%[a-z_0-9]+]] = load i8** getelementptr inbounds (%struct.__va_list* @the_list, i32 0, i32 2)
 // CHECK: [[FIRST_REG:%[a-z_0-9]+]] = getelementptr i8* [[REG_TOP]], i32 [[VR_OFFS]]
-// CHECK: [[EL_ADDR:%[a-z_0-9]+]] = getelementptr i8* [[FIRST_REG]], i32 0
+// CHECK-LE: [[EL_ADDR:%[a-z_0-9]+]] = getelementptr i8* [[FIRST_REG]], i32 0
+// CHECK-BE: [[EL_ADDR:%[a-z_0-9]+]] = getelementptr i8* [[FIRST_REG]], i32 12
 // CHECK: [[EL_TYPED:%[a-z_0-9]+]] = bitcast i8* [[EL_ADDR]] to float*
 // CHECK: [[EL_TMPADDR:%[a-z_0-9]+]] = getelementptr inbounds [2 x float]* %[[TMP_HFA:[a-z_.0-9]+]], i32 0, i32 0
 // CHECK: [[EL:%[a-z_0-9]+]] = load float* [[EL_TYPED]]
 // CHECK: store float [[EL]], float* [[EL_TMPADDR]]
-// CHECK: [[EL_ADDR:%[a-z_0-9]+]] = getelementptr i8* [[FIRST_REG]], i32 16
+// CHECK-LE: [[EL_ADDR:%[a-z_0-9]+]] = getelementptr i8* [[FIRST_REG]], i32 16
+// CHECK-BE: [[EL_ADDR:%[a-z_0-9]+]] = getelementptr i8* [[FIRST_REG]], i32 28
 // CHECK: [[EL_TYPED:%[a-z_0-9]+]] = bitcast i8* [[EL_ADDR]] to float*
 // CHECK: [[EL_TMPADDR:%[a-z_0-9]+]] = getelementptr inbounds [2 x float]* %[[TMP_HFA]], i32 0, i32 1
 // CHECK: [[EL:%[a-z_0-9]+]] = load float* [[EL_TYPED]]
diff --git a/test/CodeGen/alias.c b/test/CodeGen/alias.c
index efa94b3..98449d3 100644
--- a/test/CodeGen/alias.c
+++ b/test/CodeGen/alias.c
@@ -14,6 +14,9 @@
 extern void f1(void);
 extern void f1(void) __attribute((alias("f0")));
 // CHECKBASIC-DAG: @f1 = alias void ()* @f0
+// CHECKBASIC-DAG: @test8_foo = alias weak bitcast (void ()* @test8_bar to void (...)*)
+// CHECKBASIC-DAG: @test8_zed = alias bitcast (void ()* @test8_bar to void (...)*)
+// CHECKBASIC-DAG: @test9_zed = alias void ()* @test9_bar
 // CHECKBASIC: define void @f0() [[NUW:#[0-9]+]] {
 
 // Make sure that aliases cause referenced values to be emitted.
@@ -48,3 +51,11 @@
 // CHECKBASIC: attributes [[NUW]] = { nounwind{{.*}} }
 
 // CHECKCC: attributes [[NUW]] = { nounwind{{.*}} }
+
+void test8_bar() {}
+void test8_foo() __attribute__((weak, alias("test8_bar")));
+void test8_zed() __attribute__((alias("test8_foo")));
+
+void test9_bar(void) { }
+void test9_zed(void) __attribute__((section("test")));
+void test9_zed(void) __attribute__((alias("test9_bar")));
diff --git a/test/CodeGen/altivec.c b/test/CodeGen/altivec.c
index 6c924a7..2982303 100644
--- a/test/CodeGen/altivec.c
+++ b/test/CodeGen/altivec.c
@@ -1,4 +1,3 @@
-// REQUIRES: ppc32-registered-target
 // RUN: %clang_cc1 -faltivec -triple powerpc-unknown-unknown -emit-llvm %s -o - | FileCheck %s
 
 // Check initialization
diff --git a/test/CodeGen/arm-aapcs-vfp.c b/test/CodeGen/arm-aapcs-vfp.c
index 0e102f3..eea6ab2 100644
--- a/test/CodeGen/arm-aapcs-vfp.c
+++ b/test/CodeGen/arm-aapcs-vfp.c
@@ -12,37 +12,53 @@
 // RUN:  -ffreestanding \
 // RUN:  -emit-llvm -w -o - %s | FileCheck %s
 
+// RUN: %clang_cc1 -triple arm64-apple-darwin9 -target-feature +neon \
+// RUN:   -ffreestanding \
+// RUN:   -emit-llvm -w -o - %s | FileCheck -check-prefix=CHECK64 %s
+
+#ifdef __arm64__
 #include <arm_neon.h>
+#else
+#include <arm_neon.h>
+#endif
 
 struct homogeneous_struct {
   float f[2];
   float f3;
   float f4;
 };
-// CHECK: define arm_aapcs_vfpcc %struct.homogeneous_struct @test_struct(float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}})
+// CHECK: define arm_aapcs_vfpcc %struct.homogeneous_struct @test_struct(%struct.homogeneous_struct %{{.*}})
+// CHECK64: define %struct.homogeneous_struct @test_struct(float %{{.*}}, float %{{.*}}, float %{{.*}}, float %{{.*}})
 extern struct homogeneous_struct struct_callee(struct homogeneous_struct);
 struct homogeneous_struct test_struct(struct homogeneous_struct arg) {
   return struct_callee(arg);
 }
 
+// CHECK: define arm_aapcs_vfpcc void @test_struct_variadic(%struct.homogeneous_struct* {{.*}}, ...)
+struct homogeneous_struct test_struct_variadic(struct homogeneous_struct arg, ...) {
+  return struct_callee(arg);
+}
+
 struct nested_array {
   double d[4];
 };
-// CHECK: define arm_aapcs_vfpcc void @test_array(double %{{.*}}, double %{{.*}}, double %{{.*}}, double %{{.*}})
+// CHECK: define arm_aapcs_vfpcc void @test_array(%struct.nested_array %{{.*}})
+// CHECK64: define void @test_array(double %{{.*}}, double %{{.*}}, double %{{.*}}, double %{{.*}})
 extern void array_callee(struct nested_array);
 void test_array(struct nested_array arg) {
   array_callee(arg);
 }
 
 extern void complex_callee(__complex__ double);
-// CHECK: define arm_aapcs_vfpcc void @test_complex(double %{{.*}}, double %{{.*}})
+// CHECK: define arm_aapcs_vfpcc void @test_complex({ double, double } %{{.*}})
+// CHECK64: define void @test_complex(double %{{.*}}, double %{{.*}})
 void test_complex(__complex__ double cd) {
   complex_callee(cd);
 }
 
 // Long double is the same as double on AAPCS, it should be homogeneous.
 extern void complex_long_callee(__complex__ long double);
-// CHECK: define arm_aapcs_vfpcc void @test_complex_long(double %{{.*}}, double %{{.*}})
+// CHECK: define arm_aapcs_vfpcc void @test_complex_long({ double, double } %{{.*}})
 void test_complex_long(__complex__ long double cd) {
   complex_callee(cd);
 }
@@ -56,7 +72,10 @@
   float f3;
   float f4;
 };
-// CHECK: define arm_aapcs_vfpcc void @test_big([5 x i32] %{{.*}})
+// CHECK: define arm_aapcs_vfpcc void @test_big({ [5 x i32] } %{{.*}})
+// CHECK64: define void @test_big(%struct.big_struct* %{{.*}})
+// CHECK64: call void @llvm.memcpy
+// CHECK64: call void @big_callee(%struct.big_struct*
 extern void big_callee(struct big_struct);
 void test_big(struct big_struct arg) {
   big_callee(arg);
@@ -69,14 +88,16 @@
   float f1;
   int i2;
 };
-// CHECK: define arm_aapcs_vfpcc void @test_hetero([2 x i32] %{{.*}})
+// CHECK: define arm_aapcs_vfpcc void @test_hetero({ [2 x i32] } %{{.*}})
+// CHECK64: define void @test_hetero(i64 %{{.*}})
 extern void hetero_callee(struct heterogeneous_struct);
 void test_hetero(struct heterogeneous_struct arg) {
   hetero_callee(arg);
 }
 
 // Neon multi-vector types are homogeneous aggregates.
-// CHECK: define arm_aapcs_vfpcc <16 x i8> @f0(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+// CHECK: define arm_aapcs_vfpcc <16 x i8> @f0(%struct.int8x16x4_t %{{.*}})
+// CHECK64: define <16 x i8> @f0(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}})
 int8x16_t f0(int8x16x4_t v4) {
   return vaddq_s8(v4.val[0], v4.val[3]);
 }
@@ -89,12 +110,43 @@
   int32x2_t v3;
   int16x4_t v4;
 };
-// CHECK: define arm_aapcs_vfpcc void @test_neon(<8 x i8> %{{.*}}, <8 x i8> %{{.*}}, <2 x i32> %{{.*}}, <4 x i16> %{{.*}})
+// CHECK: define arm_aapcs_vfpcc void @test_neon(%struct.neon_struct %{{.*}})
+// CHECK64: define void @test_neon(<8 x i8> %{{.*}}, <8 x i8> %{{.*}}, <2 x i32> %{{.*}}, <4 x i16> %{{.*}})
 extern void neon_callee(struct neon_struct);
 void test_neon(struct neon_struct arg) {
   neon_callee(arg);
 }
 
-// CHECK-LABEL: define arm_aapcs_vfpcc void @f33(%struct.s33* byval %s)
+// CHECK-LABEL: define arm_aapcs_vfpcc void @f33(%struct.s33* byval align 1 %s)
 struct s33 { char buf[32*32]; };
 void f33(struct s33 s) { }
+
+typedef struct { long long x; int y; } struct_long_long_int;
+// CHECK: define arm_aapcs_vfpcc void @test_vfp_stack_gpr_split_1(double %a, double %b, double %c, double %d, double %e, double %f, double %g, double %h, double %i, i32 %j, i64 %k, i32 %l)
+void test_vfp_stack_gpr_split_1(double a, double b, double c, double d, double e, double f, double g, double h, double i, int j, long long k, int l) {}
+
+// CHECK: define arm_aapcs_vfpcc void @test_vfp_stack_gpr_split_2(double %a, double %b, double %c, double %d, double %e, double %f, double %g, double %h, double %i, i32 %j, [3 x i32], { [2 x i64] } %k.coerce)
+void test_vfp_stack_gpr_split_2(double a, double b, double c, double d, double e, double f, double g, double h, double i, int j, struct_long_long_int k) {}
+
+// CHECK: define arm_aapcs_vfpcc void @test_vfp_stack_gpr_split_3(%struct.struct_long_long_int* noalias sret %agg.result, double %a, double %b, double %c, double %d, double %e, double %f, double %g, double %h, double %i, [3 x i32], { [2 x i64] } %k.coerce)
+struct_long_long_int test_vfp_stack_gpr_split_3(double a, double b, double c, double d, double e, double f, double g, double h, double i, struct_long_long_int k) {}
+
+typedef struct { int a; int b:4; int c; } struct_int_bitfield_int;
+// CHECK: define arm_aapcs_vfpcc void @test_test_vfp_stack_gpr_split_bitfield(double %a, double %b, double %c, double %d, double %e, double %f, double %g, double %h, double %i, i32 %j, i32 %k, [2 x i32], { [3 x i32] } %l.coerce)
+void test_test_vfp_stack_gpr_split_bitfield(double a, double b, double c, double d, double e, double f, double g, double h, double i, int j, int k, struct_int_bitfield_int l) {}
+
+// Note: this struct requires internal padding
+typedef struct { int x; long long y; } struct_int_long_long;
+// CHECK: define arm_aapcs_vfpcc void @test_vfp_stack_gpr_split_4(double %a, double %b, double %c, double %d, double %e, double %f, double %g, double %h, double %i, i32 %j, [3 x i32], { [2 x i64] } %k.coerce)
+void test_vfp_stack_gpr_split_4(double a, double b, double c, double d, double e, double f, double g, double h, double i, int j, struct_int_long_long k) {}
+
+// This very large struct (passed byval) uses up the GPRs, so no padding is needed
+typedef struct { int x[17]; } struct_seventeen_ints;
+typedef struct { int x[4]; } struct_four_ints;
+// CHECK: define arm_aapcs_vfpcc void @test_vfp_stack_gpr_split_5(%struct.struct_seventeen_ints* byval align 4 %a, double %b, double %c, double %d, double %e, double %f, double %g, double %h, double %i, double %j, { [4 x i32] } %k.coerce)
+void test_vfp_stack_gpr_split_5(struct_seventeen_ints a, double b, double c, double d, double e, double f, double g, double h, double i, double j, struct_four_ints k) {}
+
+// Here, parameter k would need padding to prevent it from being split, but it
+// is passed ByVal (due to being > 64 bytes), so the backend handles this instead.
+void test_vfp_stack_gpr_split_6(double a, double b, double c, double d, double e, double f, double g, double h, double i, int j, struct_seventeen_ints k) {}
+// CHECK: define arm_aapcs_vfpcc void @test_vfp_stack_gpr_split_6(double %a, double %b, double %c, double %d, double %e, double %f, double %g, double %h, double %i, i32 %j, %struct.struct_seventeen_ints* byval align 4 %k)
diff --git a/test/CodeGen/arm-arguments.c b/test/CodeGen/arm-arguments.c
index b6bac9a..2c5df91 100644
--- a/test/CodeGen/arm-arguments.c
+++ b/test/CodeGen/arm-arguments.c
@@ -176,8 +176,8 @@
 // PR13350
 struct s33 { char buf[32*32]; };
 void f33(struct s33 s) { }
-// APCS-GNU-LABEL: define void @f33(%struct.s33* byval %s)
-// AAPCS-LABEL: define arm_aapcscc void @f33(%struct.s33* byval %s)
+// APCS-GNU-LABEL: define void @f33(%struct.s33* byval align 1 %s)
+// AAPCS-LABEL: define arm_aapcscc void @f33(%struct.s33* byval align 1 %s)
 
 // PR14048
 struct s34 { char c; };
@@ -209,14 +209,14 @@
                             *(float32x4_t *)&s2);
   return v;
 }
-// APCS-GNU-LABEL: define <4 x float> @f35(i32 %i, %struct.s35* byval, %struct.s35* byval)
+// APCS-GNU-LABEL: define <4 x float> @f35(i32 %i, %struct.s35* byval align 16, %struct.s35* byval align 16)
 // APCS-GNU: %[[a:.*]] = alloca %struct.s35, align 16
 // APCS-GNU: %[[b:.*]] = bitcast %struct.s35* %[[a]] to i8*
 // APCS-GNU: %[[c:.*]] = bitcast %struct.s35* %0 to i8*
 // APCS-GNU: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %[[b]], i8* %[[c]]
 // APCS-GNU: %[[d:.*]] = bitcast %struct.s35* %[[a]] to <4 x float>*
 // APCS-GNU: load <4 x float>* %[[d]], align 16
-// AAPCS-LABEL: define arm_aapcscc <4 x float> @f35(i32 %i, %struct.s35* byval, %struct.s35* byval)
+// AAPCS-LABEL: define arm_aapcscc <4 x float> @f35(i32 %i, %struct.s35* byval align 16, %struct.s35* byval align 16)
 // AAPCS: %[[a:.*]] = alloca %struct.s35, align 16
 // AAPCS: %[[b:.*]] = bitcast %struct.s35* %[[a]] to i8*
 // AAPCS: %[[c:.*]] = bitcast %struct.s35* %0 to i8*
diff --git a/test/CodeGen/arm-asm-deprecated.c b/test/CodeGen/arm-asm-deprecated.c
new file mode 100644
index 0000000..1d7399a
--- /dev/null
+++ b/test/CodeGen/arm-asm-deprecated.c
@@ -0,0 +1,13 @@
+// REQUIRES: arm-registered-target
+// RUN: %clang_cc1 -triple armv8 -target-feature +neon %s -S -o /dev/null -verify -DWARN
+// RUN: %clang_cc1 -triple armv8 -target-feature +neon %s -S -o /dev/null -Werror -verify
+
+void set_endian() {
+  asm("setend be");
+// expected-note@1 {{instantiated into assembly here}}
+#ifdef WARN
+// expected-warning@-3 {{deprecated}}
+#else
+// expected-error@-5 {{deprecated}}
+#endif
+}
diff --git a/test/CodeGen/arm-atomics-m.c b/test/CodeGen/arm-atomics-m.c
new file mode 100644
index 0000000..51e2d1d
--- /dev/null
+++ b/test/CodeGen/arm-atomics-m.c
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=thumbv7m-none--eabi -target-cpu cortex-m3 | FileCheck %s
+
+int i;
+long long l;
+
+typedef enum memory_order {
+  memory_order_relaxed, memory_order_consume, memory_order_acquire,
+  memory_order_release, memory_order_acq_rel, memory_order_seq_cst
+} memory_order;
+
+void test_presence(void)
+{
+  // CHECK-LABEL: @test_presence
+  // CHECK: atomicrmw add i32* {{.*}} seq_cst
+  __atomic_fetch_add(&i, 1, memory_order_seq_cst);
+  // CHECK: atomicrmw sub i32* {{.*}} seq_cst
+  __atomic_fetch_sub(&i, 1, memory_order_seq_cst);
+  // CHECK: load atomic i32* {{.*}} seq_cst
+  int r;
+  __atomic_load(&i, &r, memory_order_seq_cst);
+  // CHECK: store atomic i32 {{.*}} seq_cst
+  r = 0;
+  __atomic_store(&i, &r, memory_order_seq_cst);
+
+  // CHECK: __atomic_fetch_add_8
+  __atomic_fetch_add(&l, 1, memory_order_seq_cst);
+  // CHECK: __atomic_fetch_sub_8
+  __atomic_fetch_sub(&l, 1, memory_order_seq_cst);
+  // CHECK: __atomic_load_8
+  long long rl;
+  __atomic_load(&l, &rl, memory_order_seq_cst);
+  // CHECK: __atomic_store_8
+  rl = 0;
+  __atomic_store(&l, &rl, memory_order_seq_cst);
+}
diff --git a/test/CodeGen/arm-atomics-m0.c b/test/CodeGen/arm-atomics-m0.c
new file mode 100644
index 0000000..335a1d2
--- /dev/null
+++ b/test/CodeGen/arm-atomics-m0.c
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=thumbv6m-none--eabi -target-cpu cortex-m0 | FileCheck %s
+
+int i;
+long long l;
+
+typedef enum memory_order {
+  memory_order_relaxed, memory_order_consume, memory_order_acquire,
+  memory_order_release, memory_order_acq_rel, memory_order_seq_cst
+} memory_order;
+
+void test_presence(void)
+{
+  // CHECK-LABEL: @test_presence
+  // CHECK: __atomic_fetch_add_4
+  __atomic_fetch_add(&i, 1, memory_order_seq_cst);
+  // CHECK: __atomic_fetch_sub_4
+  __atomic_fetch_sub(&i, 1, memory_order_seq_cst);
+  // CHECK: __atomic_load_4
+  int r;
+  __atomic_load(&i, &r, memory_order_seq_cst);
+  // CHECK: __atomic_store_4
+  r = 0;
+  __atomic_store(&i, &r, memory_order_seq_cst);
+
+  // CHECK: __atomic_fetch_add_8
+  __atomic_fetch_add(&l, 1, memory_order_seq_cst);
+  // CHECK: __atomic_fetch_sub_8
+  __atomic_fetch_sub(&l, 1, memory_order_seq_cst);
+  // CHECK: __atomic_load_8
+  long long rl;
+  __atomic_load(&l, &rl, memory_order_seq_cst);
+  // CHECK: __atomic_store_8
+  rl = 0;
+  __atomic_store(&l, &rl, memory_order_seq_cst);
+}
diff --git a/test/CodeGen/arm-atomics.c b/test/CodeGen/arm-atomics.c
new file mode 100644
index 0000000..b54e277
--- /dev/null
+++ b/test/CodeGen/arm-atomics.c
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=thumbv7-none--eabi | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=armv6-none--eabi | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=armv7-unknown-openbsd | FileCheck %s
+
+int i;
+long long l;
+
+typedef enum memory_order {
+  memory_order_relaxed, memory_order_consume, memory_order_acquire,
+  memory_order_release, memory_order_acq_rel, memory_order_seq_cst
+} memory_order;
+
+void test_presence(void)
+{
+  // CHECK-LABEL: @test_presence
+  // CHECK: atomicrmw add i32* {{.*}} seq_cst
+  __atomic_fetch_add(&i, 1, memory_order_seq_cst);
+  // CHECK: atomicrmw sub i32* {{.*}} seq_cst
+  __atomic_fetch_sub(&i, 1, memory_order_seq_cst);
+  // CHECK: load atomic i32* {{.*}} seq_cst
+  int r;
+  __atomic_load(&i, &r, memory_order_seq_cst);
+  // CHECK: store atomic i32 {{.*}} seq_cst
+  r = 0;
+  __atomic_store(&i, &r, memory_order_seq_cst);
+
+  // CHECK: atomicrmw add i64* {{.*}} seq_cst
+  __atomic_fetch_add(&l, 1, memory_order_seq_cst);
+  // CHECK: atomicrmw sub i64* {{.*}} seq_cst
+  __atomic_fetch_sub(&l, 1, memory_order_seq_cst);
+  // CHECK: load atomic i64* {{.*}} seq_cst
+  long long rl;
+  __atomic_load(&l, &rl, memory_order_seq_cst);
+  // CHECK: store atomic i64 {{.*}} seq_cst
+  rl = 0;
+  __atomic_store(&l, &rl, memory_order_seq_cst);
+}
diff --git a/test/CodeGen/arm-be-result-return.c b/test/CodeGen/arm-be-result-return.c
new file mode 100644
index 0000000..aadc4e1
--- /dev/null
+++ b/test/CodeGen/arm-be-result-return.c
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -triple armebv7-arm-none-eabi -emit-llvm -w -o - %s | FileCheck %s
+
+// this tests for AAPCS section 5.4:
+// A Composite Type not larger than 4 bytes is returned in r0.
+// The format is as if the result had been stored in memory at a
+// word-aligned address and then loaded into r0 with an LDR instruction
+
+extern union Us { short s; } us;
+union Us callee_us() { return us; }
+// CHECK-LABEL: callee_us()
+// CHECK: zext i16
+// CHECK: shl 
+// CHECK: ret i32
+
+void caller_us() {
+  us = callee_us();
+// CHECK-LABEL: caller_us()
+// CHECK: call i32
+// CHECK: lshr i32
+// CHECK: trunc i32
+}
+
+extern struct Ss { short s; } ss;
+struct Ss callee_ss() { return ss; }
+// CHECK-LABEL: callee_ss()
+// CHECK: zext i16
+// CHECK: shl 
+// CHECK: ret i32
+
+void caller_ss() {
+  ss = callee_ss();
+// CHECK-LABEL: caller_ss()
+// CHECK: call i32
+// CHECK: lshr i32
+// CHECK: trunc i32
+}
+
diff --git a/test/CodeGen/arm-byval-align.c b/test/CodeGen/arm-byval-align.c
new file mode 100644
index 0000000..aa22503
--- /dev/null
+++ b/test/CodeGen/arm-byval-align.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -triple=armv7-none-eabi < %s -S -emit-llvm | FileCheck %s
+
+struct foo {
+  long long a;
+  char b;
+  int c:16;
+  int d[16];
+};
+
+// CHECK: %struct.foo* byval align 8 %z
+long long bar(int a, int b, int c, int d, int e,
+              struct foo z) {
+  return z.a;
+}
diff --git a/test/CodeGen/arm-cortex-cpus.c b/test/CodeGen/arm-cortex-cpus.c
new file mode 100644
index 0000000..d8d9830
--- /dev/null
+++ b/test/CodeGen/arm-cortex-cpus.c
@@ -0,0 +1,11 @@
+// REQUIRES: arm-registered-target
+
+// Check that Cortex-M cores don't enable hwdiv-arm (and don't emit Tag_DIV_use)
+//
+// This target feature doesn't affect C predefines, nor the generated IR;
+// only the build attributes in generated assembly and object files are affected.
+
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-m3 -S %s -o - | FileCheck %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-m4 -S %s -o - | FileCheck %s
+// CHECK-NOT: .eabi_attribute	44
+
diff --git a/test/CodeGen/arm-homogenous.c b/test/CodeGen/arm-homogenous.c
index 5d21088..d1b4897 100644
--- a/test/CodeGen/arm-homogenous.c
+++ b/test/CodeGen/arm-homogenous.c
@@ -1,6 +1,11 @@
 // REQUIRES: arm-registered-target
 // RUN: %clang_cc1 -triple armv7---eabi -target-abi aapcs -mfloat-abi hard -emit-llvm %s -o - | FileCheck %s
 
+// RUN: %clang_cc1 -triple arm64-apple-darwin9 -target-abi darwinpcs \
+// RUN:  -ffreestanding -emit-llvm -w -o - %s | FileCheck -check-prefix=CHECK64 %s
+
+// RUN: %clang_cc1 -triple arm64-linux-gnu -ffreestanding -emit-llvm -w -o - %s \
+// RUN:   | FileCheck --check-prefix=CHECK64-AAPCS %s
 typedef long long int64_t;
 typedef unsigned int uint32_t;
 
@@ -17,7 +22,7 @@
 void test_union_with_first_floats(void) {
   takes_union_with_first_floats(g_u_f);
 }
-// CHECK: declare arm_aapcs_vfpcc void @takes_union_with_first_floats([4 x i32])
+// CHECK: declare arm_aapcs_vfpcc void @takes_union_with_first_floats({ [4 x i32] })
 
 void test_return_union_with_first_floats(void) {
   g_u_f = returns_union_with_first_floats();
@@ -37,7 +42,7 @@
 void test_union_with_non_first_floats(void) {
   takes_union_with_non_first_floats(g_u_nf_f);
 }
-// CHECK: declare arm_aapcs_vfpcc void @takes_union_with_non_first_floats([4 x i32])
+// CHECK: declare arm_aapcs_vfpcc void @takes_union_with_non_first_floats({ [4 x i32] })
 
 void test_return_union_with_non_first_floats(void) {
   g_u_nf_f = returns_union_with_non_first_floats();
@@ -57,7 +62,7 @@
 void test_struct_with_union_with_first_floats(void) {
   takes_struct_with_union_with_first_floats(g_s_f);
 }
-// CHECK: declare arm_aapcs_vfpcc void @takes_struct_with_union_with_first_floats([5 x i32])
+// CHECK: declare arm_aapcs_vfpcc void @takes_struct_with_union_with_first_floats({ [5 x i32] })
 
 void test_return_struct_with_union_with_first_floats(void) {
   g_s_f = returns_struct_with_union_with_first_floats();
@@ -77,7 +82,7 @@
 void test_struct_with_union_with_non_first_floats(void) {
   takes_struct_with_union_with_non_first_floats(g_s_nf_f);
 }
-// CHECK: declare arm_aapcs_vfpcc void @takes_struct_with_union_with_non_first_floats([5 x i32])
+// CHECK: declare arm_aapcs_vfpcc void @takes_struct_with_union_with_non_first_floats({ [5 x i32] })
 
 void test_return_struct_with_union_with_non_first_floats(void) {
   g_s_nf_f = returns_struct_with_union_with_non_first_floats();
@@ -103,9 +108,9 @@
 
 void test_struct_with_fundamental_elems(void) {
   takes_struct_with_fundamental_elems(g_s);
-// CHECK:  call arm_aapcs_vfpcc  void @takes_struct_with_fundamental_elems(float {{.*}}, float {{.*}}, float{{.*}}, float {{.*}})
+// CHECK:  call arm_aapcs_vfpcc  void @takes_struct_with_fundamental_elems(%struct.struct_with_fundamental_elems {{.*}})
 }
-// CHECK: declare arm_aapcs_vfpcc void @takes_struct_with_fundamental_elems(float, float, float, float)
+// CHECK: declare arm_aapcs_vfpcc void @takes_struct_with_fundamental_elems(%struct.struct_with_fundamental_elems)
 
 void test_return_struct_with_fundamental_elems(void) {
   g_s = returns_struct_with_fundamental_elems();
@@ -124,9 +129,9 @@
 
 void test_struct_with_array(void) {
   takes_struct_with_array(g_s_a);
-// CHECK:   call arm_aapcs_vfpcc  void @takes_struct_with_array(float {{.*}}, float {{.*}}, float {{.*}}, float {{.*}})
+// CHECK:   call arm_aapcs_vfpcc  void @takes_struct_with_array(%struct.struct_with_array {{.*}})
 }
-// CHECK: declare arm_aapcs_vfpcc void @takes_struct_with_array(float, float, float, float)
+// CHECK: declare arm_aapcs_vfpcc void @takes_struct_with_array(%struct.struct_with_array)
 
 void test_return_struct_with_array(void) {
   g_s_a = returns_struct_with_array();
@@ -146,9 +151,9 @@
 
 void test_union_with_struct_with_fundamental_elems(void) {
   takes_union_with_struct_with_fundamental_elems(g_u_s_fe);
-// CHECK: call arm_aapcs_vfpcc  void @takes_union_with_struct_with_fundamental_elems(float {{.*}}, float {{.*}}, float {{.*}}, float {{.*}})
+// CHECK: call arm_aapcs_vfpcc  void @takes_union_with_struct_with_fundamental_elems(%union.union_with_struct_with_fundamental_elems {{.*}})
 }
-// CHECK: declare arm_aapcs_vfpcc void @takes_union_with_struct_with_fundamental_elems(float, float, float, float)
+// CHECK: declare arm_aapcs_vfpcc void @takes_union_with_struct_with_fundamental_elems(%union.union_with_struct_with_fundamental_elems)
 
 void test_return_union_with_struct_with_fundamental_elems(void) {
   g_u_s_fe = returns_union_with_struct_with_fundamental_elems();
@@ -169,14 +174,26 @@
 
 void test_struct_of_four_doubles(void) {
 // CHECK: test_struct_of_four_doubles
-// CHECK: call arm_aapcs_vfpcc void @takes_struct_of_four_doubles(double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}, [6 x float] undef, double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}})
+// CHECK: call arm_aapcs_vfpcc void @takes_struct_of_four_doubles(double {{.*}}, %struct.struct_of_four_doubles {{.*}}, %struct.struct_of_four_doubles {{.*}}, double {{.*}})
+// CHECK64: test_struct_of_four_doubles
+// CHECK64: call void @takes_struct_of_four_doubles(double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}, [3 x float] undef, double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}})
+// CHECK64-AAPCS: test_struct_of_four_doubles
+// CHECK64-AAPCS: call void @takes_struct_of_four_doubles(double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}, [3 x float] undef, double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}})
   takes_struct_of_four_doubles(3.0, g_s4d, g_s4d, 4.0);
 }
 
+extern void takes_struct_of_four_doubles_variadic(double a, struct_of_four_doubles b, struct_of_four_doubles c, double d, ...);
+
+void test_struct_of_four_doubles_variadic(void) {
+// CHECK: test_struct_of_four_doubles_variadic
+// CHECK: call arm_aapcs_vfpcc void (double, { [4 x i64] }, { [4 x i64] }, double, ...)* @takes_struct_of_four_doubles_variadic(double {{.*}}, { [4 x i64] } {{.*}}, { [4 x i64] } {{.*}}, double {{.*}})
+  takes_struct_of_four_doubles_variadic(3.0, g_s4d, g_s4d, 4.0);
+}
+
 extern void takes_struct_with_backfill(float f1, double a, float f2, struct_of_four_doubles b, struct_of_four_doubles c, double d);
 void test_struct_with_backfill(void) {
 // CHECK: test_struct_with_backfill
-// CHECK: call arm_aapcs_vfpcc void @takes_struct_with_backfill(float {{.*}}, double {{.*}}, float {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}, [4 x float] undef, double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}}, double {{.*}})
+// CHECK: call arm_aapcs_vfpcc void @takes_struct_with_backfill(float {{.*}}, double {{.*}}, float {{.*}}, %struct.struct_of_four_doubles {{.*}}, %struct.struct_of_four_doubles {{.*}}, double {{.*}})
   takes_struct_with_backfill(3.0, 3.1, 3.2, g_s4d, g_s4d, 4.0);
 }
 
@@ -193,10 +210,25 @@
 
 void test_struct_of_vecs(void) {
 // CHECK: test_struct_of_vecs
-// CHECK: call arm_aapcs_vfpcc void @takes_struct_of_vecs(double {{.*}}, <8 x i8> {{.*}}, <4 x i16> {{.*}}, <8 x i8> {{.*}}, <4 x i16> {{.*}}, [6 x float] undef, <8 x i8> {{.*}}, <4 x i16> {{.*}}, <8 x i8> {{.*}}, <4 x i16> {{.*}}, double {{.*}})
+// CHECK: call arm_aapcs_vfpcc void @takes_struct_of_vecs(double {{.*}}, %struct.struct_of_vecs {{.*}}, %struct.struct_of_vecs {{.*}}, double {{.*}})
+// CHECK64: test_struct_of_vecs
+// CHECK64: call void @takes_struct_of_vecs(double {{.*}}, <8 x i8> {{.*}}, <4 x i16> {{.*}}, <8 x i8> {{.*}}, <4 x i16> {{.*}}, [3 x float] undef, <8 x i8> {{.*}}, <4 x i16> {{.*}}, <8 x i8> {{.*}}, <4 x i16> {{.*}}, double {{.*}})
+// CHECK64-AAPCS: test_struct_of_vecs
+// CHECK64-AAPCS: call void @takes_struct_of_vecs(double {{.*}}, <8 x i8> {{.*}}, <4 x i16> {{.*}}, <8 x i8> {{.*}}, <4 x i16> {{.*}}, [3 x float] undef, <8 x i8> {{.*}}, <4 x i16> {{.*}}, <8 x i8> {{.*}}, <4 x i16> {{.*}}, double {{.*}})
   takes_struct_of_vecs(3.0, g_vec, g_vec, 4.0);
 }
 
+typedef struct {
+  double a;
+  long double b;
+} struct_of_double_and_long_double;
+struct_of_double_and_long_double g_dld;
+
+struct_of_double_and_long_double test_struct_of_double_and_long_double(void) {
+  return g_dld;
+}
+// CHECK: define arm_aapcs_vfpcc %struct.struct_of_double_and_long_double @test_struct_of_double_and_long_double()
+
 // FIXME: Tests necessary:
 //         - Vectors
 //         - C++ stuff
diff --git a/test/CodeGen/arm-metadata.c b/test/CodeGen/arm-metadata.c
new file mode 100644
index 0000000..1cd9880
--- /dev/null
+++ b/test/CodeGen/arm-metadata.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -triple armv7a-linux-gnueabi -emit-llvm -o - %s | FileCheck -check-prefix=DEFAULT %s
+// RUN: %clang_cc1 -triple armv7a-linux-gnueabi -emit-llvm -o - %s -fshort-enums | FileCheck -check-prefix=SHORT-ENUM %s
+// RUN: %clang_cc1 -triple armv7a-linux-gnueabi -emit-llvm -o - %s -fshort-wchar | FileCheck -check-prefix=SHORT-WCHAR %s
+
+// DEFAULT:  !{{[0-9]+}} = metadata !{i32 1, metadata !"wchar_size", i32 4}
+// DEFAULT:   !{{[0-9]+}} = metadata !{i32 1, metadata !"min_enum_size", i32 4}
+
+// SHORT-WCHAR: !{{[0-9]+}} = metadata !{i32 1, metadata !"wchar_size", i32 2}
+// SHORT-WCHAR:   !{{[0-9]+}} = metadata !{i32 1, metadata !"min_enum_size", i32 4}
+
+// SHORT_ENUM:  !{{[0-9]+}} = metadata !{i32 1, metadata !"wchar_size", i32 4}
+// SHORT-ENUM:  !{{[0-9]+}} = metadata !{i32 1, metadata !"min_enum_size", i32 1}
diff --git a/test/CodeGen/arm-microsoft-intrinsics.c b/test/CodeGen/arm-microsoft-intrinsics.c
new file mode 100644
index 0000000..5f19e5e
--- /dev/null
+++ b/test/CodeGen/arm-microsoft-intrinsics.c
@@ -0,0 +1,63 @@
+// RUN: %clang_cc1 -triple thumbv7-windows -fms-compatibility -emit-llvm -o - %s \
+// RUN:    | FileCheck %s -check-prefix CHECK-MSVC
+
+// RUN: not %clang_cc1 -triple armv7-eabi -Werror -S -o /dev/null %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-EABI
+
+void check__dmb(void) {
+  __dmb(0);
+}
+
+// CHECK-MSVC: @llvm.arm.dmb(i32 0)
+// CHECK-EABI: error: implicit declaration of function '__dmb'
+
+void check__dsb(void) {
+  __dsb(0);
+}
+
+// CHECK-MSVC: @llvm.arm.dsb(i32 0)
+// CHECK-EABI: error: implicit declaration of function '__dsb'
+
+void check__isb(void) {
+  __isb(0);
+}
+
+// CHECK-MSVC: @llvm.arm.isb(i32 0)
+// CHECK-EABI: error: implicit declaration of function '__isb'
+
+__INT64_TYPE__ check__ldrexd(void) {
+  __INT64_TYPE__ i64;
+  return __ldrexd(&i64);
+}
+
+// CHECK-MSVC: @llvm.arm.ldrexd(i8* {{.*}})
+// CHECK-EABI: error: implicit declaration of function '__ldrexd'
+
+unsigned int check_MoveFromCoprocessor(void) {
+  return _MoveFromCoprocessor(0, 0, 0, 0, 0);
+}
+
+// CHECK-MSVC: @llvm.arm.mrc(i32 0, i32 0, i32 0, i32 0, i32 0)
+// CHECK-EABI: error: implicit declaration of function '_MoveFromCoprocessor'
+
+unsigned int check_MoveFromCoprocessor2(void) {
+  return _MoveFromCoprocessor2(0, 0, 0, 0, 0);
+}
+
+// CHECK-MSVC: @llvm.arm.mrc2(i32 0, i32 0, i32 0, i32 0, i32 0)
+// CHECK-EABI: error: implicit declaration of function '_MoveFromCoprocessor2'
+
+void check_MoveToCoprocessor(void) {
+  _MoveToCoprocessor(0, 0, 0, 0, 0, 0);
+}
+
+// CHECK-MSVC: @llvm.arm.mcr(i32 0, i32 0, i32 0, i32 0, i32 0, i32 0)
+// CHECK-EABI: error: implicit declaration of function '_MoveToCoprocessor'
+
+void check_MoveToCoprocessor2(void) {
+  _MoveToCoprocessor2(0, 0, 0, 0, 0, 0);
+}
+
+// CHECK-MSVC: @llvm.arm.mcr2(i32 0, i32 0, i32 0, i32 0, i32 0, i32 0)
+// CHECK-EABI: error: implicit declaration of function '_MoveToCoprocessor2'
+
diff --git a/test/CodeGen/arm-neon-vcvtX.c b/test/CodeGen/arm-neon-vcvtX.c
new file mode 100644
index 0000000..ff8ce7e
--- /dev/null
+++ b/test/CodeGen/arm-neon-vcvtX.c
@@ -0,0 +1,99 @@
+// RUN: %clang_cc1 -triple thumbv8-linux-gnueabihf -target-cpu cortex-a57 -ffreestanding -O1 -emit-llvm %s -o - | FileCheck %s
+
+#include <arm_neon.h>
+
+int32x2_t test_vcvta_s32_f32(float32x2_t a) {
+  // CHECK-LABEL: test_vcvta_s32_f32
+  // CHECK-LABEL: call <2 x i32> @llvm.arm.neon.vcvtas.v2i32.v2f32(<2 x float> %a)
+  return vcvta_s32_f32(a);
+}
+
+uint32x2_t test_vcvta_u32_f32(float32x2_t a) {
+  // CHECK-LABEL: test_vcvta_u32_f32
+  // CHECK-LABEL: call <2 x i32> @llvm.arm.neon.vcvtau.v2i32.v2f32(<2 x float> %a)
+  return vcvta_u32_f32(a);
+}
+
+int32x4_t test_vcvtaq_s32_f32(float32x4_t a) {
+  // CHECK-LABEL: test_vcvtaq_s32_f32
+  // CHECK-LABEL: call <4 x i32> @llvm.arm.neon.vcvtas.v4i32.v4f32(<4 x float> %a)
+  return vcvtaq_s32_f32(a);
+}
+
+uint32x4_t test_vcvtaq_u32_f32(float32x4_t a) {
+  // CHECK-LABEL: test_vcvtaq_u32_f32
+  // CHECK-LABEL: call <4 x i32> @llvm.arm.neon.vcvtau.v4i32.v4f32(<4 x float> %a)
+  return vcvtaq_u32_f32(a);
+}
+
+int32x2_t test_vcvtn_s32_f32(float32x2_t a) {
+  // CHECK-LABEL: test_vcvtn_s32_f32
+  // CHECK-LABEL: call <2 x i32> @llvm.arm.neon.vcvtns.v2i32.v2f32(<2 x float> %a)
+  return vcvtn_s32_f32(a);
+}
+
+uint32x2_t test_vcvtn_u32_f32(float32x2_t a) {
+  // CHECK-LABEL: test_vcvtn_u32_f32
+  // CHECK-LABEL: call <2 x i32> @llvm.arm.neon.vcvtnu.v2i32.v2f32(<2 x float> %a)
+  return vcvtn_u32_f32(a);
+}
+
+int32x4_t test_vcvtnq_s32_f32(float32x4_t a) {
+  // CHECK-LABEL: test_vcvtnq_s32_f32
+  // CHECK-LABEL: call <4 x i32> @llvm.arm.neon.vcvtns.v4i32.v4f32(<4 x float> %a)
+  return vcvtnq_s32_f32(a);
+}
+
+uint32x4_t test_vcvtnq_u32_f32(float32x4_t a) {
+  // CHECK-LABEL: test_vcvtnq_u32_f32
+  // CHECK-LABEL: call <4 x i32> @llvm.arm.neon.vcvtnu.v4i32.v4f32(<4 x float> %a)
+  return vcvtnq_u32_f32(a);
+}
+
+int32x2_t test_vcvtp_s32_f32(float32x2_t a) {
+  // CHECK-LABEL: test_vcvtp_s32_f32
+  // CHECK-LABEL: call <2 x i32> @llvm.arm.neon.vcvtps.v2i32.v2f32(<2 x float> %a)
+  return vcvtp_s32_f32(a);
+}
+
+uint32x2_t test_vcvtp_u32_f32(float32x2_t a) {
+  // CHECK-LABEL: test_vcvtp_u32_f32
+  // CHECK-LABEL: call <2 x i32> @llvm.arm.neon.vcvtpu.v2i32.v2f32(<2 x float> %a)
+  return vcvtp_u32_f32(a);
+}
+
+int32x4_t test_vcvtpq_s32_f32(float32x4_t a) {
+  // CHECK-LABEL: test_vcvtpq_s32_f32
+  // CHECK-LABEL: call <4 x i32> @llvm.arm.neon.vcvtps.v4i32.v4f32(<4 x float> %a)
+  return vcvtpq_s32_f32(a);
+}
+
+uint32x4_t test_vcvtpq_u32_f32(float32x4_t a) {
+  // CHECK-LABEL: test_vcvtpq_u32_f32
+  // CHECK-LABEL: call <4 x i32> @llvm.arm.neon.vcvtpu.v4i32.v4f32(<4 x float> %a)
+  return vcvtpq_u32_f32(a);
+}
+
+int32x2_t test_vcvtm_s32_f32(float32x2_t a) {
+  // CHECK-LABEL: test_vcvtm_s32_f32
+  // CHECK-LABEL: call <2 x i32> @llvm.arm.neon.vcvtms.v2i32.v2f32(<2 x float> %a)
+  return vcvtm_s32_f32(a);
+}
+
+uint32x2_t test_vcvtm_u32_f32(float32x2_t a) {
+  // CHECK-LABEL: test_vcvtm_u32_f32
+  // CHECK-LABEL: call <2 x i32> @llvm.arm.neon.vcvtmu.v2i32.v2f32(<2 x float> %a)
+  return vcvtm_u32_f32(a);
+}
+
+int32x4_t test_vcvtmq_s32_f32(float32x4_t a) {
+  // CHECK-LABEL: test_vcvtmq_s32_f32
+  // CHECK-LABEL: call <4 x i32> @llvm.arm.neon.vcvtms.v4i32.v4f32(<4 x float> %a)
+  return vcvtmq_s32_f32(a);
+}
+
+uint32x4_t test_vcvtmq_u32_f32(float32x4_t a) {
+  // CHECK-LABEL: test_vcvtmq_u32_f32
+  // CHECK-LABEL: call <4 x i32> @llvm.arm.neon.vcvtmu.v4i32.v4f32(<4 x float> %a)
+  return vcvtmq_u32_f32(a);
+}
diff --git a/test/CodeGen/arm64-aapcs-arguments.c b/test/CodeGen/arm64-aapcs-arguments.c
new file mode 100644
index 0000000..b430630
--- /dev/null
+++ b/test/CodeGen/arm64-aapcs-arguments.c
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -triple arm64-linux-gnu -target-feature +neon -target-abi aapcs -ffreestanding -emit-llvm -w -o - %s | FileCheck %s
+
+// AAPCS clause C.8 says: If the argument has an alignment of 16 then the NGRN
+// is rounded up to the next even number.
+
+// CHECK: void @test1(i32 %x0, i128 %x2_x3, i128 %x4_x5, i128 %x6_x7, i128 %sp.coerce)
+typedef union { __int128 a; } Small;
+void test1(int x0, __int128 x2_x3, __int128 x4_x5, __int128 x6_x7, Small sp) {
+}
+
+
+// CHECK: void @test2(i32 %x0, i128 %x2_x3.coerce, i32 %x4, i128 %x6_x7.coerce, i32 %sp, i128 %sp16.coerce)
+void test2(int x0, Small x2_x3, int x4, Small x6_x7, int sp, Small sp16) {
+}
+
+// We coerce HFAs into a contiguous [N x double] type if they're going on the
+// stack in order to avoid holes. Make sure we get all of them, and not just the
+// first:
+
+// CHECK: void @test3(float %s0_s3.0, float %s0_s3.1, float %s0_s3.2, float %s0_s3.3, float %s4, [3 x float], [2 x double] %sp.coerce, [2 x double] %sp16.coerce)
+typedef struct { float arr[4]; } HFA;
+void test3(HFA s0_s3, float s4, HFA sp, HFA sp16) {
+}
+
+
+// However, we shouldn't perform the [N x double] coercion on types which have
+// sufficient alignment to avoid holes on their own. We could coerce to [N x
+// fp128] or something, but leaving them as-is retains more information for
+// users to debug.
+
+//  CHECK: void @test4(<16 x i8> %v0_v2.0, <16 x i8> %v0_v2.1, <16 x i8> %v0_v2.2, <16 x i8> %v3_v5.0, <16 x i8> %v3_v5.1, <16 x i8> %v3_v5.2, [2 x float], <16 x i8> %sp.0, <16 x i8> %sp.1, <16 x i8> %sp.2, double %sp48, <16 x i8> %sp64.0, <16 x i8> %sp64.1, <16 x i8> %sp64.2)
+typedef __attribute__((neon_vector_type(16))) signed char int8x16_t;
+typedef struct { int8x16_t arr[3]; } BigHFA;
+void test4(BigHFA v0_v2, BigHFA v3_v5, BigHFA sp, double sp48, BigHFA sp64) {
+}
+
+// It's the job of the argument *consumer* to perform the required sign & zero
+// extensions under AAPCS. There shouldn't be
+
+// CHECK: define i8 @test5(i8 %a, i16 %b)
+unsigned char test5(unsigned char a, signed short b) {
+}
diff --git a/test/CodeGen/arm64-abi-vector.c b/test/CodeGen/arm64-abi-vector.c
new file mode 100644
index 0000000..502fb08
--- /dev/null
+++ b/test/CodeGen/arm64-abi-vector.c
@@ -0,0 +1,430 @@
+// RUN: %clang_cc1 -triple arm64-apple-ios7 -target-abi darwinpcs -emit-llvm -o - %s | FileCheck %s
+
+#include <stdarg.h>
+
+typedef __attribute__(( ext_vector_type(3) ))  char __char3;
+typedef __attribute__(( ext_vector_type(4) ))  char __char4;
+typedef __attribute__(( ext_vector_type(5) ))  char __char5;
+typedef __attribute__(( ext_vector_type(9) ))  char __char9;
+typedef __attribute__(( ext_vector_type(19) )) char __char19;
+typedef __attribute__(( ext_vector_type(3) ))  short __short3;
+typedef __attribute__(( ext_vector_type(5) ))  short __short5;
+typedef __attribute__(( ext_vector_type(3) ))  int __int3;
+typedef __attribute__(( ext_vector_type(5) ))  int __int5;
+typedef __attribute__(( ext_vector_type(3) ))  double __double3;
+
+double varargs_vec_3c(int fixed, ...) {
+// CHECK: varargs_vec_3c
+// CHECK: alloca <3 x i8>, align 4
+// CHECK: [[AP_NEXT:%.*]] = getelementptr i8* [[AP_CUR:%.*]], i32 8
+// CHECK: bitcast i8* [[AP_CUR]] to <3 x i8>*
+  va_list ap;
+  double sum = fixed;
+  va_start(ap, fixed);
+  __char3 c3 = va_arg(ap, __char3);
+  sum = sum + c3.x + c3.y;
+  va_end(ap);
+  return sum;
+}
+
+double test_3c(__char3 *in) {
+// CHECK: test_3c
+// CHECK: call double (i32, ...)* @varargs_vec_3c(i32 3, i32 {{%.*}})
+  return varargs_vec_3c(3, *in);
+}
+
+double varargs_vec_4c(int fixed, ...) {
+// CHECK: varargs_vec_4c
+// CHECK: alloca <4 x i8>, align 4
+// CHECK: [[AP_NEXT:%.*]] = getelementptr i8* [[AP_CUR:%.*]], i32 8
+// CHECK: bitcast i8* [[AP_CUR]] to <4 x i8>*
+  va_list ap;
+  double sum = fixed;
+  va_start(ap, fixed);
+  __char4 c4 = va_arg(ap, __char4);
+  sum = sum + c4.x + c4.y;
+  va_end(ap);
+  return sum;
+}
+
+double test_4c(__char4 *in) {
+// CHECK: test_4c
+// CHECK: call double (i32, ...)* @varargs_vec_4c(i32 4, i32 {{%.*}})
+  return varargs_vec_4c(4, *in);
+}
+
+double varargs_vec_5c(int fixed, ...) {
+// CHECK: varargs_vec_5c
+// CHECK: alloca <5 x i8>, align 8
+// CHECK: [[AP_NEXT:%.*]] = getelementptr i8* [[AP_CUR:%.*]], i32 8
+// CHECK: bitcast i8* [[AP_CUR]] to <5 x i8>*
+  va_list ap;
+  double sum = fixed;
+  va_start(ap, fixed);
+  __char5 c5 = va_arg(ap, __char5);
+  sum = sum + c5.x + c5.y;
+  va_end(ap);
+  return sum;
+}
+
+double test_5c(__char5 *in) {
+// CHECK: test_5c
+// CHECK: call double (i32, ...)* @varargs_vec_5c(i32 5, <2 x i32> {{%.*}})
+  return varargs_vec_5c(5, *in);
+}
+
+double varargs_vec_9c(int fixed, ...) {
+// CHECK: varargs_vec_9c
+// CHECK: alloca <9 x i8>, align 16
+// CHECK: [[ALIGN:%.*]] = and i64 {{%.*}}, -16
+// CHECK: [[AP_ALIGN:%.*]] = inttoptr i64 [[ALIGN]] to i8*
+// CHECK: [[AP_NEXT:%.*]] = getelementptr i8* [[AP_ALIGN]], i32 16
+// CHECK: bitcast i8* [[AP_ALIGN]] to <9 x i8>*
+  va_list ap;
+  double sum = fixed;
+  va_start(ap, fixed);
+  __char9 c9 = va_arg(ap, __char9);
+  sum = sum + c9.x + c9.y;
+  va_end(ap);
+  return sum;
+}
+
+double test_9c(__char9 *in) {
+// CHECK: test_9c
+// CHECK: call double (i32, ...)* @varargs_vec_9c(i32 9, <4 x i32> {{%.*}})
+  return varargs_vec_9c(9, *in);
+}
+
+double varargs_vec_19c(int fixed, ...) {
+// CHECK: varargs_vec_19c
+// CHECK: [[AP_NEXT:%.*]] = getelementptr i8* [[AP_CUR:%.*]], i32 8
+// CHECK: [[VAR:%.*]] = bitcast i8* [[AP_CUR]] to i8**
+// CHECK: [[VAR2:%.*]] = load i8** [[VAR]]
+// CHECK: bitcast i8* [[VAR2]] to <19 x i8>*
+  va_list ap;
+  double sum = fixed;
+  va_start(ap, fixed);
+  __char19 c19 = va_arg(ap, __char19);
+  sum = sum + c19.x + c19.y;
+  va_end(ap);
+  return sum;
+}
+
+double test_19c(__char19 *in) {
+// CHECK: test_19c
+// CHECK: call double (i32, ...)* @varargs_vec_19c(i32 19, <19 x i8>* {{%.*}})
+  return varargs_vec_19c(19, *in);
+}
+
+double varargs_vec_3s(int fixed, ...) {
+// CHECK: varargs_vec_3s
+// CHECK: alloca <3 x i16>, align 8
+// CHECK: [[AP_NEXT:%.*]] = getelementptr i8* [[AP_CUR:%.*]], i32 8
+// CHECK: bitcast i8* [[AP_CUR]] to <3 x i16>*
+  va_list ap;
+  double sum = fixed;
+  va_start(ap, fixed);
+  __short3 c3 = va_arg(ap, __short3);
+  sum = sum + c3.x + c3.y;
+  va_end(ap);
+  return sum;
+}
+
+double test_3s(__short3 *in) {
+// CHECK: test_3s
+// CHECK: call double (i32, ...)* @varargs_vec_3s(i32 3, <2 x i32> {{%.*}})
+  return varargs_vec_3s(3, *in);
+}
+
+double varargs_vec_5s(int fixed, ...) {
+// CHECK: varargs_vec_5s
+// CHECK: alloca <5 x i16>, align 16
+// CHECK: [[ALIGN:%.*]] = and i64 {{%.*}}, -16
+// CHECK: [[AP_ALIGN:%.*]] = inttoptr i64 [[ALIGN]] to i8*
+// CHECK: [[AP_NEXT:%.*]] = getelementptr i8* [[AP_ALIGN]], i32 16
+// CHECK: bitcast i8* [[AP_ALIGN]] to <5 x i16>*
+  va_list ap;
+  double sum = fixed;
+  va_start(ap, fixed);
+  __short5 c5 = va_arg(ap, __short5);
+  sum = sum + c5.x + c5.y;
+  va_end(ap);
+  return sum;
+}
+
+double test_5s(__short5 *in) {
+// CHECK: test_5s
+// CHECK: call double (i32, ...)* @varargs_vec_5s(i32 5, <4 x i32> {{%.*}})
+  return varargs_vec_5s(5, *in);
+}
+
+double varargs_vec_3i(int fixed, ...) {
+// CHECK: varargs_vec_3i
+// CHECK: alloca <3 x i32>, align 16
+// CHECK: [[ALIGN:%.*]] = and i64 {{%.*}}, -16
+// CHECK: [[AP_ALIGN:%.*]] = inttoptr i64 [[ALIGN]] to i8*
+// CHECK: [[AP_NEXT:%.*]] = getelementptr i8* [[AP_ALIGN]], i32 16
+// CHECK: bitcast i8* [[AP_ALIGN]] to <3 x i32>*
+  va_list ap;
+  double sum = fixed;
+  va_start(ap, fixed);
+  __int3 c3 = va_arg(ap, __int3);
+  sum = sum + c3.x + c3.y;
+  va_end(ap);
+  return sum;
+}
+
+double test_3i(__int3 *in) {
+// CHECK: test_3i
+// CHECK: call double (i32, ...)* @varargs_vec_3i(i32 3, <4 x i32> {{%.*}})
+  return varargs_vec_3i(3, *in);
+}
+
+double varargs_vec_5i(int fixed, ...) {
+// CHECK: varargs_vec_5i
+// CHECK: alloca <5 x i32>, align 16
+// CHECK: [[AP_NEXT:%.*]] = getelementptr i8* [[AP_CUR:%.*]], i32 8
+// CHECK: [[VAR:%.*]] = bitcast i8* [[AP_CUR]] to i8**
+// CHECK: [[VAR2:%.*]] = load i8** [[VAR]]
+// CHECK: bitcast i8* [[VAR2]] to <5 x i32>*
+  va_list ap;
+  double sum = fixed;
+  va_start(ap, fixed);
+  __int5 c5 = va_arg(ap, __int5);
+  sum = sum + c5.x + c5.y;
+  va_end(ap);
+  return sum;
+}
+
+double test_5i(__int5 *in) {
+// CHECK: test_5i
+// CHECK: call double (i32, ...)* @varargs_vec_5i(i32 5, <5 x i32>* {{%.*}})
+  return varargs_vec_5i(5, *in);
+}
+
+double varargs_vec_3d(int fixed, ...) {
+// CHECK: varargs_vec_3d
+// CHECK: alloca <3 x double>, align 16
+// CHECK: [[AP_NEXT:%.*]] = getelementptr i8* [[AP_CUR:%.*]], i32 8
+// CHECK: [[VAR:%.*]] = bitcast i8* [[AP_CUR]] to i8**
+// CHECK: [[VAR2:%.*]] = load i8** [[VAR]]
+// CHECK: bitcast i8* [[VAR2]] to <3 x double>*
+  va_list ap;
+  double sum = fixed;
+  va_start(ap, fixed);
+  __double3 c3 = va_arg(ap, __double3);
+  sum = sum + c3.x + c3.y;
+  va_end(ap);
+  return sum;
+}
+
+double test_3d(__double3 *in) {
+// CHECK: test_3d
+// CHECK: call double (i32, ...)* @varargs_vec_3d(i32 3, <3 x double>* {{%.*}})
+  return varargs_vec_3d(3, *in);
+}
+
+double varargs_vec(int fixed, ...) {
+// CHECK: varargs_vec
+  va_list ap;
+  double sum = fixed;
+  va_start(ap, fixed);
+  __char3 c3 = va_arg(ap, __char3);
+// CHECK: [[AP_NEXT:%.*]] = getelementptr i8* [[AP_CUR:%.*]], i32 8
+// CHECK: bitcast i8* [[AP_CUR]] to <3 x i8>*
+  sum = sum + c3.x + c3.y;
+  __char5 c5 = va_arg(ap, __char5);
+// CHECK: [[AP_NEXT:%.*]] = getelementptr i8* [[AP_CUR:%.*]], i32 8
+// CHECK: bitcast i8* [[AP_CUR]] to <5 x i8>*
+  sum = sum + c5.x + c5.y;
+  __char9 c9 = va_arg(ap, __char9);
+// CHECK: [[ALIGN:%.*]] = and i64 {{%.*}}, -16
+// CHECK: [[AP_ALIGN:%.*]] = inttoptr i64 [[ALIGN]] to i8*
+// CHECK: [[AP_NEXT:%.*]] = getelementptr i8* [[AP_ALIGN]], i32 16
+// CHECK: bitcast i8* [[AP_ALIGN]] to <9 x i8>*
+  sum = sum + c9.x + c9.y;
+  __char19 c19 = va_arg(ap, __char19);
+// CHECK: [[AP_NEXT:%.*]] = getelementptr i8* [[AP_CUR:%.*]], i32 8
+// CHECK: [[VAR:%.*]] = bitcast i8* [[AP_CUR]] to i8**
+// CHECK: [[VAR2:%.*]] = load i8** [[VAR]]
+// CHECK: bitcast i8* [[VAR2]] to <19 x i8>*
+  sum = sum + c19.x + c19.y;
+  __short3 s3 = va_arg(ap, __short3);
+// CHECK: [[AP_NEXT:%.*]] = getelementptr i8* [[AP_CUR:%.*]], i32 8
+// CHECK: bitcast i8* [[AP_CUR]] to <3 x i16>*
+  sum = sum + s3.x + s3.y;
+  __short5 s5 = va_arg(ap, __short5);
+// CHECK: [[ALIGN:%.*]] = and i64 {{%.*}}, -16
+// CHECK: [[AP_ALIGN:%.*]] = inttoptr i64 [[ALIGN]] to i8*
+// CHECK: [[AP_NEXT:%.*]] = getelementptr i8* [[AP_ALIGN]], i32 16
+// CHECK: bitcast i8* [[AP_ALIGN]] to <5 x i16>*
+  sum = sum + s5.x + s5.y;
+  __int3 i3 = va_arg(ap, __int3);
+// CHECK: [[ALIGN:%.*]] = and i64 {{%.*}}, -16
+// CHECK: [[AP_ALIGN:%.*]] = inttoptr i64 [[ALIGN]] to i8*
+// CHECK: [[AP_NEXT:%.*]] = getelementptr i8* [[AP_ALIGN]], i32 16
+// CHECK: bitcast i8* [[AP_ALIGN]] to <3 x i32>*
+  sum = sum + i3.x + i3.y;
+  __int5 i5 = va_arg(ap, __int5);
+// CHECK: [[AP_NEXT:%.*]] = getelementptr i8* [[AP_CUR:%.*]], i32 8
+// CHECK: [[VAR:%.*]] = bitcast i8* [[AP_CUR]] to i8**
+// CHECK: [[VAR2:%.*]] = load i8** [[VAR]]
+// CHECK: bitcast i8* [[VAR2]] to <5 x i32>*
+  sum = sum + i5.x + i5.y;
+  __double3 d3 = va_arg(ap, __double3);
+// CHECK: [[AP_NEXT:%.*]] = getelementptr i8* [[AP_CUR:%.*]], i32 8
+// CHECK: [[VAR:%.*]] = bitcast i8* [[AP_CUR]] to i8**
+// CHECK: [[VAR2:%.*]] = load i8** [[VAR]]
+// CHECK: bitcast i8* [[VAR2]] to <3 x double>*
+  sum = sum + d3.x + d3.y;
+  va_end(ap);
+  return sum;
+}
+
+double test(__char3 *c3, __char5 *c5, __char9 *c9, __char19 *c19,
+            __short3 *s3, __short5 *s5, __int3 *i3, __int5 *i5,
+            __double3 *d3) {
+  double ret = varargs_vec(3, *c3, *c5, *c9, *c19, *s3, *s5, *i3, *i5, *d3);
+// CHECK: call double (i32, ...)* @varargs_vec(i32 3, i32 {{%.*}}, <2 x i32> {{%.*}}, <4 x i32> {{%.*}}, <19 x i8>* {{%.*}}, <2 x i32> {{%.*}}, <4 x i32> {{%.*}}, <4 x i32> {{%.*}}, <5 x i32>* {{%.*}}, <3 x double>* {{%.*}})
+  return ret;
+}
+
+__attribute__((noinline)) double args_vec_3c(int fixed, __char3 c3) {
+// CHECK: args_vec_3c
+// CHECK: [[C3:%.*]] = alloca <3 x i8>, align 4
+// CHECK: [[TMP:%.*]] = bitcast <3 x i8>* [[C3]] to i32*
+// CHECK: store i32 {{%.*}}, i32* [[TMP]]
+  double sum = fixed;
+  sum = sum + c3.x + c3.y;
+  return sum;
+}
+
+double fixed_3c(__char3 *in) {
+// CHECK: fixed_3c
+// CHECK: call double @args_vec_3c(i32 3, i32 {{%.*}})
+  return args_vec_3c(3, *in);
+}
+
+__attribute__((noinline)) double args_vec_5c(int fixed, __char5 c5) {
+// CHECK: args_vec_5c
+// CHECK: [[C5:%.*]] = alloca <5 x i8>, align 8
+// CHECK: [[TMP:%.*]] = bitcast <5 x i8>* [[C5]] to <2 x i32>*
+// CHECK: store <2 x i32> {{%.*}}, <2 x i32>* [[TMP]], align 1
+  double sum = fixed;
+  sum = sum + c5.x + c5.y;
+  return sum;
+}
+
+double fixed_5c(__char5 *in) {
+// CHECK: fixed_5c
+// CHECK: call double @args_vec_5c(i32 5, <2 x i32> {{%.*}})
+  return args_vec_5c(5, *in);
+}
+
+__attribute__((noinline)) double args_vec_9c(int fixed, __char9 c9) {
+// CHECK: args_vec_9c
+// CHECK: [[C9:%.*]] = alloca <9 x i8>, align 16
+// CHECK: [[TMP:%.*]] = bitcast <9 x i8>* [[C9]] to <4 x i32>*
+// CHECK: store <4 x i32> {{%.*}}, <4 x i32>* [[TMP]], align 1
+  double sum = fixed;
+  sum = sum + c9.x + c9.y;
+  return sum;
+}
+
+double fixed_9c(__char9 *in) {
+// CHECK: fixed_9c
+// CHECK: call double @args_vec_9c(i32 9, <4 x i32> {{%.*}})
+  return args_vec_9c(9, *in);
+}
+
+__attribute__((noinline)) double args_vec_19c(int fixed, __char19 c19) {
+// CHECK: args_vec_19c
+// CHECK: [[C19:%.*]] = load <19 x i8>* {{.*}}, align 16
+  double sum = fixed;
+  sum = sum + c19.x + c19.y;
+  return sum;
+}
+
+double fixed_19c(__char19 *in) {
+// CHECK: fixed_19c
+// CHECK: call double @args_vec_19c(i32 19, <19 x i8>* {{%.*}})
+  return args_vec_19c(19, *in);
+}
+
+__attribute__((noinline)) double args_vec_3s(int fixed, __short3 c3) {
+// CHECK: args_vec_3s
+// CHECK: [[C3:%.*]] = alloca <3 x i16>, align 8
+// CHECK: [[TMP:%.*]] = bitcast <3 x i16>* [[C3]] to <2 x i32>*
+// CHECK: store <2 x i32> {{%.*}}, <2 x i32>* [[TMP]], align 1
+  double sum = fixed;
+  sum = sum + c3.x + c3.y;
+  return sum;
+}
+
+double fixed_3s(__short3 *in) {
+// CHECK: fixed_3s
+// CHECK: call double @args_vec_3s(i32 3, <2 x i32> {{%.*}})
+  return args_vec_3s(3, *in);
+}
+
+__attribute__((noinline)) double args_vec_5s(int fixed, __short5 c5) {
+// CHECK: args_vec_5s
+// CHECK: [[C5:%.*]] = alloca <5 x i16>, align 16
+// CHECK: [[TMP:%.*]] = bitcast <5 x i16>* [[C5]] to <4 x i32>*
+// CHECK: store <4 x i32> {{%.*}}, <4 x i32>* [[TMP]], align 1
+  double sum = fixed;
+  sum = sum + c5.x + c5.y;
+  return sum;
+}
+
+double fixed_5s(__short5 *in) {
+// CHECK: fixed_5s
+// CHECK: call double @args_vec_5s(i32 5, <4 x i32> {{%.*}})
+  return args_vec_5s(5, *in);
+}
+
+__attribute__((noinline)) double args_vec_3i(int fixed, __int3 c3) {
+// CHECK: args_vec_3i
+// CHECK: [[C3:%.*]] = alloca <3 x i32>, align 16
+// CHECK: [[TMP:%.*]] = bitcast <3 x i32>* [[C3]] to <4 x i32>*
+// CHECK: store <4 x i32> {{%.*}}, <4 x i32>* [[TMP]], align 1
+  double sum = fixed;
+  sum = sum + c3.x + c3.y;
+  return sum;
+}
+
+double fixed_3i(__int3 *in) {
+// CHECK: fixed_3i
+// CHECK: call double @args_vec_3i(i32 3, <4 x i32> {{%.*}})
+  return args_vec_3i(3, *in);
+}
+
+__attribute__((noinline)) double args_vec_5i(int fixed, __int5 c5) {
+// CHECK: args_vec_5i
+// CHECK: [[C5:%.*]] = load <5 x i32>* {{%.*}}, align 16
+  double sum = fixed;
+  sum = sum + c5.x + c5.y;
+  return sum;
+}
+
+double fixed_5i(__int5 *in) {
+// CHECK: fixed_5i
+// CHECK: call double @args_vec_5i(i32 5, <5 x i32>* {{%.*}})
+  return args_vec_5i(5, *in);
+}
+
+__attribute__((noinline)) double args_vec_3d(int fixed, __double3 c3) {
+// CHECK: args_vec_3d
+// CHECK: [[CAST:%.*]] = bitcast <3 x double>* {{%.*}} to <4 x double>*
+// CHECK: [[LOAD:%.*]] = load <4 x double>* [[CAST]]
+// CHECK: shufflevector <4 x double> [[LOAD]], <4 x double> undef, <3 x i32> <i32 0, i32 1, i32 2>
+  double sum = fixed;
+  sum = sum + c3.x + c3.y;
+  return sum;
+}
+
+double fixed_3d(__double3 *in) {
+// CHECK: fixed_3d
+// CHECK: call double @args_vec_3d(i32 3, <3 x double>* {{%.*}})
+  return args_vec_3d(3, *in);
+}
diff --git a/test/CodeGen/arm64-arguments.c b/test/CodeGen/arm64-arguments.c
new file mode 100644
index 0000000..b2de08d
--- /dev/null
+++ b/test/CodeGen/arm64-arguments.c
@@ -0,0 +1,719 @@
+// RUN: %clang_cc1 -triple arm64-apple-ios7 -target-feature +neon -target-abi darwinpcs -ffreestanding -emit-llvm -w -o - %s | FileCheck %s
+
+// CHECK: define signext i8 @f0()
+char f0(void) {
+  return 0;
+}
+
+// Struct as return type. Aggregates <= 16 bytes are passed directly and round
+// up to multiple of 8 bytes.
+// CHECK: define i64 @f1()
+struct s1 { char f0; };
+struct s1 f1(void) {}
+
+// CHECK: define i64 @f2()
+struct s2 { short f0; };
+struct s2 f2(void) {}
+
+// CHECK: define i64 @f3()
+struct s3 { int f0; };
+struct s3 f3(void) {}
+
+// CHECK: define i64 @f4()
+struct s4 { struct s4_0 { int f0; } f0; };
+struct s4 f4(void) {}
+
+// CHECK: define i64 @f5()
+struct s5 { struct { } f0; int f1; };
+struct s5 f5(void) {}
+
+// CHECK: define i64 @f6()
+struct s6 { int f0[1]; };
+struct s6 f6(void) {}
+
+// CHECK: define void @f7()
+struct s7 { struct { int : 0; } f0; };
+struct s7 f7(void) {}
+
+// CHECK: define void @f8()
+struct s8 { struct { int : 0; } f0[1]; };
+struct s8 f8(void) {}
+
+// CHECK: define i64 @f9()
+struct s9 { int f0; int : 0; };
+struct s9 f9(void) {}
+
+// CHECK: define i64 @f10()
+struct s10 { int f0; int : 0; int : 0; };
+struct s10 f10(void) {}
+
+// CHECK: define i64 @f11()
+struct s11 { int : 0; int f0; };
+struct s11 f11(void) {}
+
+// CHECK: define i64 @f12()
+union u12 { char f0; short f1; int f2; };
+union u12 f12(void) {}
+
+// Homogeneous Aggregate as return type will be passed directly.
+// CHECK: define %struct.s13 @f13()
+struct s13 { float f0; };
+struct s13 f13(void) {}
+// CHECK: define %union.u14 @f14()
+union u14 { float f0; };
+union u14 f14(void) {}
+
+// CHECK: define void @f15()
+void f15(struct s7 a0) {}
+
+// CHECK: define void @f16()
+void f16(struct s8 a0) {}
+
+// CHECK: define i64 @f17()
+struct s17 { short f0 : 13; char f1 : 4; };
+struct s17 f17(void) {}
+
+// CHECK: define i64 @f18()
+struct s18 { short f0; char f1 : 4; };
+struct s18 f18(void) {}
+
+// CHECK: define i64 @f19()
+struct s19 { int f0; struct s8 f1; };
+struct s19 f19(void) {}
+
+// CHECK: define i64 @f20()
+struct s20 { struct s8 f1; int f0; };
+struct s20 f20(void) {}
+
+// CHECK: define i64 @f21()
+struct s21 { struct {} f1; int f0 : 4; };
+struct s21 f21(void) {}
+
+// CHECK: define i64 @f22()
+// CHECK: define i64 @f23()
+// CHECK: define i64 @f24()
+// CHECK: define i128 @f25()
+// CHECK: define { float, float } @f26()
+// CHECK: define { double, double } @f27()
+_Complex char       f22(void) {}
+_Complex short      f23(void) {}
+_Complex int        f24(void) {}
+_Complex long long  f25(void) {}
+_Complex float      f26(void) {}
+_Complex double     f27(void) {}
+
+// CHECK: define i64 @f28()
+struct s28 { _Complex char f0; };
+struct s28 f28() {}
+
+// CHECK: define i64 @f29()
+struct s29 { _Complex short f0; };
+struct s29 f29() {}
+
+// CHECK: define i64 @f30()
+struct s30 { _Complex int f0; };
+struct s30 f30() {}
+
+struct s31 { char x; };
+void f31(struct s31 s) { }
+// CHECK: define void @f31(i64 %s.coerce)
+// CHECK: %s = alloca %struct.s31, align 8
+// CHECK: trunc i64 %s.coerce to i8
+// CHECK: store i8 %{{.*}},
+
+struct s32 { double x; };
+void f32(struct s32 s) { }
+// Expand Homogeneous Aggregate.
+// CHECK: @f32(double %{{.*}})
+
+// A composite type larger than 16 bytes should be passed indirectly.
+struct s33 { char buf[32*32]; };
+void f33(struct s33 s) { }
+// CHECK: define void @f33(%struct.s33* %s)
+
+struct s34 { char c; };
+void f34(struct s34 s);
+void g34(struct s34 *s) { f34(*s); }
+// CHECK: @g34(%struct.s34* %s)
+// CHECK: %[[a:.*]] = load i8* %{{.*}}
+// CHECK: zext i8 %[[a]] to i64
+// CHECK: call void @f34(i64 %{{.*}})
+
+/*
+ * Check that va_arg accesses stack according to ABI alignment
+ */
+long long t1(int i, ...) {
+    // CHECK: t1
+    __builtin_va_list ap;
+    __builtin_va_start(ap, i);
+    // CHECK-NOT: add i32 %{{.*}} 7
+    // CHECK-NOT: and i32 %{{.*}} -8
+    long long ll = __builtin_va_arg(ap, long long);
+    __builtin_va_end(ap);
+    return ll;
+}
+double t2(int i, ...) {
+    // CHECK: t2
+    __builtin_va_list ap;
+    __builtin_va_start(ap, i);
+    // CHECK-NOT: add i32 %{{.*}} 7
+    // CHECK-NOT: and i32 %{{.*}} -8
+    double ll = __builtin_va_arg(ap, double);
+    __builtin_va_end(ap);
+    return ll;
+}
+
+#include <arm_neon.h>
+
+// Homogeneous Vector Aggregate as return type and argument type.
+// CHECK: define %struct.int8x16x2_t @f0_0(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+int8x16x2_t f0_0(int8x16_t a0, int8x16_t a1) {
+  return vzipq_s8(a0, a1);
+}
+
+// Test direct vector passing.
+typedef float T_float32x2 __attribute__ ((__vector_size__ (8)));
+typedef float T_float32x4 __attribute__ ((__vector_size__ (16)));
+typedef float T_float32x8 __attribute__ ((__vector_size__ (32)));
+typedef float T_float32x16 __attribute__ ((__vector_size__ (64)));
+
+// CHECK: define <2 x float> @f1_0(<2 x float> %{{.*}})
+T_float32x2 f1_0(T_float32x2 a0) { return a0; }
+// CHECK: define <4 x float> @f1_1(<4 x float> %{{.*}})
+T_float32x4 f1_1(T_float32x4 a0) { return a0; }
+// Vector with length bigger than 16-byte is illegal and is passed indirectly.
+// CHECK: define void @f1_2(<8 x float>* noalias sret  %{{.*}}, <8 x float>*)
+T_float32x8 f1_2(T_float32x8 a0) { return a0; }
+// CHECK: define void @f1_3(<16 x float>* noalias sret %{{.*}}, <16 x float>*)
+T_float32x16 f1_3(T_float32x16 a0) { return a0; }
+
+// Testing alignment with aggregates: HFA, aggregates with size <= 16 bytes and
+// aggregates with size > 16 bytes.
+struct s35
+{
+   float v[4]; //Testing HFA.
+} __attribute__((aligned(16)));
+typedef struct s35 s35_with_align;
+
+typedef __attribute__((neon_vector_type(4))) float float32x4_t;
+float32x4_t f35(int i, s35_with_align s1, s35_with_align s2) {
+// CHECK: define <4 x float> @f35(i32 %i, float %s1.0, float %s1.1, float %s1.2, float %s1.3, float %s2.0, float %s2.1, float %s2.2, float %s2.3)
+// CHECK: %s1 = alloca %struct.s35, align 16
+// CHECK: %s2 = alloca %struct.s35, align 16
+// CHECK: %[[a:.*]] = bitcast %struct.s35* %s1 to <4 x float>*
+// CHECK: load <4 x float>* %[[a]], align 16
+// CHECK: %[[b:.*]] = bitcast %struct.s35* %s2 to <4 x float>*
+// CHECK: load <4 x float>* %[[b]], align 16
+  float32x4_t v = vaddq_f32(*(float32x4_t *)&s1,
+                            *(float32x4_t *)&s2);
+  return v;
+}
+
+struct s36
+{
+   int v[4]; //Testing 16-byte aggregate.
+} __attribute__((aligned(16)));
+typedef struct s36 s36_with_align;
+
+typedef __attribute__((neon_vector_type(4))) int int32x4_t;
+int32x4_t f36(int i, s36_with_align s1, s36_with_align s2) {
+// CHECK: define <4 x i32> @f36(i32 %i, i128 %s1.coerce, i128 %s2.coerce)
+// CHECK: %s1 = alloca %struct.s36, align 16
+// CHECK: %s2 = alloca %struct.s36, align 16
+// CHECK: store i128 %s1.coerce, i128* %{{.*}}, align 1
+// CHECK: store i128 %s2.coerce, i128* %{{.*}}, align 1
+// CHECK: %[[a:.*]] = bitcast %struct.s36* %s1 to <4 x i32>*
+// CHECK: load <4 x i32>* %[[a]], align 16
+// CHECK: %[[b:.*]] = bitcast %struct.s36* %s2 to <4 x i32>*
+// CHECK: load <4 x i32>* %[[b]], align 16
+  int32x4_t v = vaddq_s32(*(int32x4_t *)&s1,
+                          *(int32x4_t *)&s2);
+  return v;
+}
+
+struct s37
+{
+   int v[18]; //Testing large aggregate.
+} __attribute__((aligned(16)));
+typedef struct s37 s37_with_align;
+
+int32x4_t f37(int i, s37_with_align s1, s37_with_align s2) {
+// CHECK: define <4 x i32> @f37(i32 %i, %struct.s37* %s1, %struct.s37* %s2)
+// CHECK: %[[a:.*]] = bitcast %struct.s37* %s1 to <4 x i32>*
+// CHECK: load <4 x i32>* %[[a]], align 16
+// CHECK: %[[b:.*]] = bitcast %struct.s37* %s2 to <4 x i32>*
+// CHECK: load <4 x i32>* %[[b]], align 16
+  int32x4_t v = vaddq_s32(*(int32x4_t *)&s1,
+                          *(int32x4_t *)&s2);
+  return v;
+}
+s37_with_align g37;
+int32x4_t caller37() {
+// CHECK: caller37
+// CHECK: %[[a:.*]] = alloca %struct.s37, align 16
+// CHECK: %[[b:.*]] = alloca %struct.s37, align 16
+// CHECK: call void @llvm.memcpy
+// CHECK: call void @llvm.memcpy
+// CHECK: call <4 x i32> @f37(i32 3, %struct.s37* %[[a]], %struct.s37* %[[b]])
+  return f37(3, g37, g37);
+}
+
+// rdar://problem/12648441
+// Test passing structs with size < 8, < 16 and > 16
+// with alignment of 16 and without
+
+// structs with size <= 8 bytes, without alignment attribute
+// passed as i64 regardless of the align attribute
+struct s38
+{
+  int i;
+  short s;
+};
+typedef struct s38 s38_no_align;
+// passing structs in registers
+__attribute__ ((noinline))
+int f38(int i, s38_no_align s1, s38_no_align s2) {
+// CHECK: define i32 @f38(i32 %i, i64 %s1.coerce, i64 %s2.coerce)
+// CHECK: %s1 = alloca %struct.s38, align 8
+// CHECK: %s2 = alloca %struct.s38, align 8
+// CHECK: store i64 %s1.coerce, i64* %{{.*}}, align 1
+// CHECK: store i64 %s2.coerce, i64* %{{.*}}, align 1
+// CHECK: getelementptr inbounds %struct.s38* %s1, i32 0, i32 0
+// CHECK: getelementptr inbounds %struct.s38* %s2, i32 0, i32 0
+// CHECK: getelementptr inbounds %struct.s38* %s1, i32 0, i32 1
+// CHECK: getelementptr inbounds %struct.s38* %s2, i32 0, i32 1
+  return s1.i + s2.i + i + s1.s + s2.s;
+}
+s38_no_align g38;
+s38_no_align g38_2;
+int caller38() {
+// CHECK: define i32 @caller38()
+// CHECK: %[[a:.*]] = load i64* bitcast (%struct.s38* @g38 to i64*), align 1
+// CHECK: %[[b:.*]] = load i64* bitcast (%struct.s38* @g38_2 to i64*), align 1
+// CHECK: call i32 @f38(i32 3, i64 %[[a]], i64 %[[b]])
+  return f38(3, g38, g38_2);
+}
+// passing structs on stack
+__attribute__ ((noinline))
+int f38_stack(int i, int i2, int i3, int i4, int i5, int i6, int i7, int i8,
+              int i9, s38_no_align s1, s38_no_align s2) {
+// CHECK: define i32 @f38_stack(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i64 %s1.coerce, i64 %s2.coerce)
+// CHECK: %s1 = alloca %struct.s38, align 8
+// CHECK: %s2 = alloca %struct.s38, align 8
+// CHECK: store i64 %s1.coerce, i64* %{{.*}}, align 1
+// CHECK: store i64 %s2.coerce, i64* %{{.*}}, align 1
+// CHECK: getelementptr inbounds %struct.s38* %s1, i32 0, i32 0
+// CHECK: getelementptr inbounds %struct.s38* %s2, i32 0, i32 0
+// CHECK: getelementptr inbounds %struct.s38* %s1, i32 0, i32 1
+// CHECK: getelementptr inbounds %struct.s38* %s2, i32 0, i32 1
+  return s1.i + s2.i + i + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9 + s1.s + s2.s;
+}
+int caller38_stack() {
+// CHECK: define i32 @caller38_stack()
+// CHECK: %[[a:.*]] = load i64* bitcast (%struct.s38* @g38 to i64*), align 1
+// CHECK: %[[b:.*]] = load i64* bitcast (%struct.s38* @g38_2 to i64*), align 1
+// CHECK: call i32 @f38_stack(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i64 %[[a]], i64 %[[b]])
+  return f38_stack(1, 2, 3, 4, 5, 6, 7, 8, 9, g38, g38_2);
+}
+
+// structs with size <= 8 bytes, with alignment attribute
+struct s39
+{
+  int i;
+  short s;
+} __attribute__((aligned(16)));
+typedef struct s39 s39_with_align;
+// passing aligned structs in registers
+__attribute__ ((noinline))
+int f39(int i, s39_with_align s1, s39_with_align s2) {
+// CHECK: define i32 @f39(i32 %i, i128 %s1.coerce, i128 %s2.coerce)
+// CHECK: %s1 = alloca %struct.s39, align 16
+// CHECK: %s2 = alloca %struct.s39, align 16
+// CHECK: store i128 %s1.coerce, i128* %{{.*}}, align 1
+// CHECK: store i128 %s2.coerce, i128* %{{.*}}, align 1
+// CHECK: getelementptr inbounds %struct.s39* %s1, i32 0, i32 0
+// CHECK: getelementptr inbounds %struct.s39* %s2, i32 0, i32 0
+// CHECK: getelementptr inbounds %struct.s39* %s1, i32 0, i32 1
+// CHECK: getelementptr inbounds %struct.s39* %s2, i32 0, i32 1
+  return s1.i + s2.i + i + s1.s + s2.s;
+}
+s39_with_align g39;
+s39_with_align g39_2;
+int caller39() {
+// CHECK: define i32 @caller39()
+// CHECK: %[[a:.*]] = load i128* bitcast (%struct.s39* @g39 to i128*), align 1
+// CHECK: %[[b:.*]] = load i128* bitcast (%struct.s39* @g39_2 to i128*), align 1
+// CHECK: call i32 @f39(i32 3, i128 %[[a]], i128 %[[b]])
+  return f39(3, g39, g39_2);
+}
+// passing aligned structs on stack
+__attribute__ ((noinline))
+int f39_stack(int i, int i2, int i3, int i4, int i5, int i6, int i7, int i8,
+              int i9, s39_with_align s1, s39_with_align s2) {
+// CHECK: define i32 @f39_stack(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i128 %s1.coerce, i128 %s2.coerce)
+// CHECK: %s1 = alloca %struct.s39, align 16
+// CHECK: %s2 = alloca %struct.s39, align 16
+// CHECK: store i128 %s1.coerce, i128* %{{.*}}, align 1
+// CHECK: store i128 %s2.coerce, i128* %{{.*}}, align 1
+// CHECK: getelementptr inbounds %struct.s39* %s1, i32 0, i32 0
+// CHECK: getelementptr inbounds %struct.s39* %s2, i32 0, i32 0
+// CHECK: getelementptr inbounds %struct.s39* %s1, i32 0, i32 1
+// CHECK: getelementptr inbounds %struct.s39* %s2, i32 0, i32 1
+  return s1.i + s2.i + i + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9 + s1.s + s2.s;
+}
+int caller39_stack() {
+// CHECK: define i32 @caller39_stack()
+// CHECK: %[[a:.*]] = load i128* bitcast (%struct.s39* @g39 to i128*), align 1
+// CHECK: %[[b:.*]] = load i128* bitcast (%struct.s39* @g39_2 to i128*), align 1
+// CHECK: call i32 @f39_stack(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i128 %[[a]], i128 %[[b]])
+  return f39_stack(1, 2, 3, 4, 5, 6, 7, 8, 9, g39, g39_2);
+}
+
+// structs with size <= 16 bytes, without alignment attribute
+struct s40
+{
+  int i;
+  short s;
+  int i2;
+  short s2;
+};
+typedef struct s40 s40_no_align;
+// passing structs in registers
+__attribute__ ((noinline))
+int f40(int i, s40_no_align s1, s40_no_align s2) {
+// CHECK: define i32 @f40(i32 %i, [2 x i64] %s1.coerce, [2 x i64] %s2.coerce)
+// CHECK: %s1 = alloca %struct.s40, align 8
+// CHECK: %s2 = alloca %struct.s40, align 8
+// CHECK: store [2 x i64] %s1.coerce, [2 x i64]* %{{.*}}, align 1
+// CHECK: store [2 x i64] %s2.coerce, [2 x i64]* %{{.*}}, align 1
+// CHECK: getelementptr inbounds %struct.s40* %s1, i32 0, i32 0
+// CHECK: getelementptr inbounds %struct.s40* %s2, i32 0, i32 0
+// CHECK: getelementptr inbounds %struct.s40* %s1, i32 0, i32 1
+// CHECK: getelementptr inbounds %struct.s40* %s2, i32 0, i32 1
+  return s1.i + s2.i + i + s1.s + s2.s;
+}
+s40_no_align g40;
+s40_no_align g40_2;
+int caller40() {
+// CHECK: define i32 @caller40()
+// CHECK: %[[a:.*]] = load [2 x i64]* bitcast (%struct.s40* @g40 to [2 x i64]*), align 1
+// CHECK: %[[b:.*]] = load [2 x i64]* bitcast (%struct.s40* @g40_2 to [2 x i64]*), align 1
+// CHECK: call i32 @f40(i32 3, [2 x i64] %[[a]], [2 x i64] %[[b]])
+  return f40(3, g40, g40_2);
+}
+// passing structs on stack
+__attribute__ ((noinline))
+int f40_stack(int i, int i2, int i3, int i4, int i5, int i6, int i7, int i8,
+              int i9, s40_no_align s1, s40_no_align s2) {
+// CHECK: define i32 @f40_stack(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, [2 x i64] %s1.coerce, [2 x i64] %s2.coerce)
+// CHECK: %s1 = alloca %struct.s40, align 8
+// CHECK: %s2 = alloca %struct.s40, align 8
+// CHECK: store [2 x i64] %s1.coerce, [2 x i64]* %{{.*}}, align 1
+// CHECK: store [2 x i64] %s2.coerce, [2 x i64]* %{{.*}}, align 1
+// CHECK: getelementptr inbounds %struct.s40* %s1, i32 0, i32 0
+// CHECK: getelementptr inbounds %struct.s40* %s2, i32 0, i32 0
+// CHECK: getelementptr inbounds %struct.s40* %s1, i32 0, i32 1
+// CHECK: getelementptr inbounds %struct.s40* %s2, i32 0, i32 1
+  return s1.i + s2.i + i + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9 + s1.s + s2.s;
+}
+int caller40_stack() {
+// CHECK: define i32 @caller40_stack()
+// CHECK: %[[a:.*]] = load [2 x i64]* bitcast (%struct.s40* @g40 to [2 x i64]*), align 1
+// CHECK: %[[b:.*]] = load [2 x i64]* bitcast (%struct.s40* @g40_2 to [2 x i64]*), align 1
+// CHECK: call i32 @f40_stack(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, [2 x i64] %[[a]], [2 x i64] %[[b]])
+  return f40_stack(1, 2, 3, 4, 5, 6, 7, 8, 9, g40, g40_2);
+}
+
+// structs with size <= 16 bytes, with alignment attribute
+struct s41
+{
+  int i;
+  short s;
+  int i2;
+  short s2;
+} __attribute__((aligned(16)));
+typedef struct s41 s41_with_align;
+// passing aligned structs in registers
+__attribute__ ((noinline))
+int f41(int i, s41_with_align s1, s41_with_align s2) {
+// CHECK: define i32 @f41(i32 %i, i128 %s1.coerce, i128 %s2.coerce)
+// CHECK: %s1 = alloca %struct.s41, align 16
+// CHECK: %s2 = alloca %struct.s41, align 16
+// CHECK: store i128 %s1.coerce, i128* %{{.*}}, align 1
+// CHECK: store i128 %s2.coerce, i128* %{{.*}}, align 1
+// CHECK: getelementptr inbounds %struct.s41* %s1, i32 0, i32 0
+// CHECK: getelementptr inbounds %struct.s41* %s2, i32 0, i32 0
+// CHECK: getelementptr inbounds %struct.s41* %s1, i32 0, i32 1
+// CHECK: getelementptr inbounds %struct.s41* %s2, i32 0, i32 1
+  return s1.i + s2.i + i + s1.s + s2.s;
+}
+s41_with_align g41;
+s41_with_align g41_2;
+int caller41() {
+// CHECK: define i32 @caller41()
+// CHECK: %[[a:.*]] = load i128* bitcast (%struct.s41* @g41 to i128*), align 1
+// CHECK: %[[b:.*]] = load i128* bitcast (%struct.s41* @g41_2 to i128*), align 1
+// CHECK: call i32 @f41(i32 3, i128 %[[a]], i128 %[[b]])
+  return f41(3, g41, g41_2);
+}
+// passing aligned structs on stack
+__attribute__ ((noinline))
+int f41_stack(int i, int i2, int i3, int i4, int i5, int i6, int i7, int i8,
+              int i9, s41_with_align s1, s41_with_align s2) {
+// CHECK: define i32 @f41_stack(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, i128 %s1.coerce, i128 %s2.coerce)
+// CHECK: %s1 = alloca %struct.s41, align 16
+// CHECK: %s2 = alloca %struct.s41, align 16
+// CHECK: store i128 %s1.coerce, i128* %{{.*}}, align 1
+// CHECK: store i128 %s2.coerce, i128* %{{.*}}, align 1
+// CHECK: getelementptr inbounds %struct.s41* %s1, i32 0, i32 0
+// CHECK: getelementptr inbounds %struct.s41* %s2, i32 0, i32 0
+// CHECK: getelementptr inbounds %struct.s41* %s1, i32 0, i32 1
+// CHECK: getelementptr inbounds %struct.s41* %s2, i32 0, i32 1
+  return s1.i + s2.i + i + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9 + s1.s + s2.s;
+}
+int caller41_stack() {
+// CHECK: define i32 @caller41_stack()
+// CHECK: %[[a:.*]] = load i128* bitcast (%struct.s41* @g41 to i128*), align 1
+// CHECK: %[[b:.*]] = load i128* bitcast (%struct.s41* @g41_2 to i128*), align 1
+// CHECK: call i32 @f41_stack(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i128 %[[a]], i128 %[[b]])
+  return f41_stack(1, 2, 3, 4, 5, 6, 7, 8, 9, g41, g41_2);
+}
+
+// structs with size > 16 bytes, without alignment attribute
+struct s42
+{
+  int i;
+  short s;
+  int i2;
+  short s2;
+  int i3;
+  short s3;
+};
+typedef struct s42 s42_no_align;
+// passing structs in registers
+__attribute__ ((noinline))
+int f42(int i, s42_no_align s1, s42_no_align s2) {
+// CHECK: define i32 @f42(i32 %i, %struct.s42* %s1, %struct.s42* %s2)
+// CHECK: getelementptr inbounds %struct.s42* %s1, i32 0, i32 0
+// CHECK: getelementptr inbounds %struct.s42* %s2, i32 0, i32 0
+// CHECK: getelementptr inbounds %struct.s42* %s1, i32 0, i32 1
+// CHECK: getelementptr inbounds %struct.s42* %s2, i32 0, i32 1
+  return s1.i + s2.i + i + s1.s + s2.s;
+}
+s42_no_align g42;
+s42_no_align g42_2;
+int caller42() {
+// CHECK: define i32 @caller42()
+// CHECK: %[[a:.*]] = alloca %struct.s42, align 4
+// CHECK: %[[b:.*]] = alloca %struct.s42, align 4
+// CHECK: %[[c:.*]] = bitcast %struct.s42* %[[a]] to i8*
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+// CHECK: %[[d:.*]] = bitcast %struct.s42* %[[b]] to i8*
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+// CHECK: call i32 @f42(i32 3, %struct.s42* %[[a]], %struct.s42* %[[b]])
+  return f42(3, g42, g42_2);
+}
+// passing structs on stack
+__attribute__ ((noinline))
+int f42_stack(int i, int i2, int i3, int i4, int i5, int i6, int i7, int i8,
+              int i9, s42_no_align s1, s42_no_align s2) {
+// CHECK: define i32 @f42_stack(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, %struct.s42* %s1, %struct.s42* %s2)
+// CHECK: getelementptr inbounds %struct.s42* %s1, i32 0, i32 0
+// CHECK: getelementptr inbounds %struct.s42* %s2, i32 0, i32 0
+// CHECK: getelementptr inbounds %struct.s42* %s1, i32 0, i32 1
+// CHECK: getelementptr inbounds %struct.s42* %s2, i32 0, i32 1
+  return s1.i + s2.i + i + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9 + s1.s + s2.s;
+}
+int caller42_stack() {
+// CHECK: define i32 @caller42_stack()
+// CHECK: %[[a:.*]] = alloca %struct.s42, align 4
+// CHECK: %[[b:.*]] = alloca %struct.s42, align 4
+// CHECK: %[[c:.*]] = bitcast %struct.s42* %[[a]] to i8*
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+// CHECK: %[[d:.*]] = bitcast %struct.s42* %[[b]] to i8*
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+// CHECK: call i32 @f42_stack(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, %struct.s42* %[[a]], %struct.s42* %[[b]])
+  return f42_stack(1, 2, 3, 4, 5, 6, 7, 8, 9, g42, g42_2);
+}
+
+// structs with size > 16 bytes, with alignment attribute
+struct s43
+{
+  int i;
+  short s;
+  int i2;
+  short s2;
+  int i3;
+  short s3;
+} __attribute__((aligned(16)));
+typedef struct s43 s43_with_align;
+// passing aligned structs in registers
+__attribute__ ((noinline))
+int f43(int i, s43_with_align s1, s43_with_align s2) {
+// CHECK: define i32 @f43(i32 %i, %struct.s43* %s1, %struct.s43* %s2)
+// CHECK: getelementptr inbounds %struct.s43* %s1, i32 0, i32 0
+// CHECK: getelementptr inbounds %struct.s43* %s2, i32 0, i32 0
+// CHECK: getelementptr inbounds %struct.s43* %s1, i32 0, i32 1
+// CHECK: getelementptr inbounds %struct.s43* %s2, i32 0, i32 1
+  return s1.i + s2.i + i + s1.s + s2.s;
+}
+s43_with_align g43;
+s43_with_align g43_2;
+int caller43() {
+// CHECK: define i32 @caller43()
+// CHECK: %[[a:.*]] = alloca %struct.s43, align 16
+// CHECK: %[[b:.*]] = alloca %struct.s43, align 16
+// CHECK: %[[c:.*]] = bitcast %struct.s43* %[[a]] to i8*
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+// CHECK: %[[d:.*]] = bitcast %struct.s43* %[[b]] to i8*
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+// CHECK: call i32 @f43(i32 3, %struct.s43* %[[a]], %struct.s43* %[[b]])
+  return f43(3, g43, g43_2);
+}
+// passing aligned structs on stack
+__attribute__ ((noinline))
+int f43_stack(int i, int i2, int i3, int i4, int i5, int i6, int i7, int i8,
+              int i9, s43_with_align s1, s43_with_align s2) {
+// CHECK: define i32 @f43_stack(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, i32 %i8, i32 %i9, %struct.s43* %s1, %struct.s43* %s2)
+// CHECK: getelementptr inbounds %struct.s43* %s1, i32 0, i32 0
+// CHECK: getelementptr inbounds %struct.s43* %s2, i32 0, i32 0
+// CHECK: getelementptr inbounds %struct.s43* %s1, i32 0, i32 1
+// CHECK: getelementptr inbounds %struct.s43* %s2, i32 0, i32 1
+  return s1.i + s2.i + i + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9 + s1.s + s2.s;
+}
+int caller43_stack() {
+// CHECK: define i32 @caller43_stack()
+// CHECK: %[[a:.*]] = alloca %struct.s43, align 16
+// CHECK: %[[b:.*]] = alloca %struct.s43, align 16
+// CHECK: %[[c:.*]] = bitcast %struct.s43* %[[a]] to i8*
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+// CHECK: %[[d:.*]] = bitcast %struct.s43* %[[b]] to i8*
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+// CHECK: call i32 @f43_stack(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, %struct.s43* %[[a]], %struct.s43* %[[b]])
+  return f43_stack(1, 2, 3, 4, 5, 6, 7, 8, 9, g43, g43_2);
+}
+
+// rdar://13668927
+// We should not split argument s1 between registers and stack.
+__attribute__ ((noinline))
+int f40_split(int i, int i2, int i3, int i4, int i5, int i6, int i7,
+              s40_no_align s1, s40_no_align s2) {
+// CHECK: define i32 @f40_split(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, [1 x i32], [2 x i64] %s1.coerce, [2 x i64] %s2.coerce)
+  return s1.i + s2.i + i + i2 + i3 + i4 + i5 + i6 + i7 + s1.s + s2.s;
+}
+int caller40_split() {
+// CHECK: define i32 @caller40_split()
+// CHECK: call i32 @f40_split(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, [1 x i32] undef, [2 x i64] %{{.*}} [2 x i64] %{{.*}})
+  return f40_split(1, 2, 3, 4, 5, 6, 7, g40, g40_2);
+}
+
+__attribute__ ((noinline))
+int f41_split(int i, int i2, int i3, int i4, int i5, int i6, int i7,
+              s41_with_align s1, s41_with_align s2) {
+// CHECK: define i32 @f41_split(i32 %i, i32 %i2, i32 %i3, i32 %i4, i32 %i5, i32 %i6, i32 %i7, [1 x i32], i128 %s1.coerce, i128 %s2.coerce)
+  return s1.i + s2.i + i + i2 + i3 + i4 + i5 + i6 + i7 + s1.s + s2.s;
+}
+int caller41_split() {
+// CHECK: define i32 @caller41_split()
+// CHECK: call i32 @f41_split(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, [1 x i32] undef, i128 %{{.*}}, i128 %{{.*}})
+  return f41_split(1, 2, 3, 4, 5, 6, 7, g41, g41_2);
+}
+
+// Handle homogeneous aggregates properly in variadic functions.
+struct HFA {
+  float a, b, c, d;
+};
+
+float test_hfa(int n, ...) {
+// CHECK-LABEL: define float @test_hfa(i32 %n, ...)
+// CHECK: [[THELIST:%.*]] = alloca i8*
+// CHECK: [[CURLIST:%.*]] = load i8** [[THELIST]]
+
+  // HFA is not indirect, so occupies its full 16 bytes on the stack.
+// CHECK: [[NEXTLIST:%.*]] = getelementptr i8* [[CURLIST]], i32 16
+// CHECK: store i8* [[NEXTLIST]], i8** [[THELIST]]
+
+// CHECK: bitcast i8* [[CURLIST]] to %struct.HFA*
+  __builtin_va_list thelist;
+  __builtin_va_start(thelist, n);
+  struct HFA h = __builtin_va_arg(thelist, struct HFA);
+  return h.d;
+}
+
+float test_hfa_call(struct HFA *a) {
+// CHECK-LABEL: define float @test_hfa_call(%struct.HFA* %a)
+// CHECK: call float (i32, ...)* @test_hfa(i32 1, [2 x double] {{.*}})
+  test_hfa(1, *a);
+}
+
+struct TooBigHFA {
+  float a, b, c, d, e;
+};
+
+float test_toobig_hfa(int n, ...) {
+// CHECK-LABEL: define float @test_toobig_hfa(i32 %n, ...)
+// CHECK: [[THELIST:%.*]] = alloca i8*
+// CHECK: [[CURLIST:%.*]] = load i8** [[THELIST]]
+
+  // TooBigHFA is not actually an HFA, so gets passed indirectly. Only 8 bytes
+  // of stack consumed.
+// CHECK: [[NEXTLIST:%.*]] = getelementptr i8* [[CURLIST]], i32 8
+// CHECK: store i8* [[NEXTLIST]], i8** [[THELIST]]
+
+// CHECK: [[HFAPTRPTR:%.*]] = bitcast i8* [[CURLIST]] to i8**
+// CHECK: [[HFAPTR:%.*]] = load i8** [[HFAPTRPTR]]
+// CHECK: bitcast i8* [[HFAPTR]] to %struct.TooBigHFA*
+  __builtin_va_list thelist;
+  __builtin_va_start(thelist, n);
+  struct TooBigHFA h = __builtin_va_arg(thelist, struct TooBigHFA);
+  return h.d;
+}
+
+struct HVA {
+  int32x4_t a, b;
+};
+
+int32x4_t test_hva(int n, ...) {
+// CHECK-LABEL: define <4 x i32> @test_hva(i32 %n, ...)
+// CHECK: [[THELIST:%.*]] = alloca i8*
+// CHECK: [[CURLIST:%.*]] = load i8** [[THELIST]]
+
+  // HVA is not indirect, so occupies its full 16 bytes on the stack. but it
+  // must be properly aligned.
+// CHECK: [[ALIGN0:%.*]] = getelementptr i8* [[CURLIST]], i32 15
+// CHECK: [[ALIGN1:%.*]] = ptrtoint i8* [[ALIGN0]] to i64
+// CHECK: [[ALIGN2:%.*]] = and i64 [[ALIGN1]], -16
+// CHECK: [[ALIGNED_LIST:%.*]] = inttoptr i64 [[ALIGN2]] to i8*
+
+// CHECK: [[NEXTLIST:%.*]] = getelementptr i8* [[ALIGNED_LIST]], i32 32
+// CHECK: store i8* [[NEXTLIST]], i8** [[THELIST]]
+
+// CHECK: bitcast i8* [[ALIGNED_LIST]] to %struct.HVA*
+  __builtin_va_list thelist;
+  __builtin_va_start(thelist, n);
+  struct HVA h = __builtin_va_arg(thelist, struct HVA);
+  return h.b;
+}
+
+struct TooBigHVA {
+  int32x4_t a, b, c, d, e;
+};
+
+int32x4_t test_toobig_hva(int n, ...) {
+// CHECK-LABEL: define <4 x i32> @test_toobig_hva(i32 %n, ...)
+// CHECK: [[THELIST:%.*]] = alloca i8*
+// CHECK: [[CURLIST:%.*]] = load i8** [[THELIST]]
+
+  // TooBigHVA is not actually an HVA, so gets passed indirectly. Only 8 bytes
+  // of stack consumed.
+// CHECK: [[NEXTLIST:%.*]] = getelementptr i8* [[CURLIST]], i32 8
+// CHECK: store i8* [[NEXTLIST]], i8** [[THELIST]]
+
+// CHECK: [[HVAPTRPTR:%.*]] = bitcast i8* [[CURLIST]] to i8**
+// CHECK: [[HVAPTR:%.*]] = load i8** [[HVAPTRPTR]]
+// CHECK: bitcast i8* [[HVAPTR]] to %struct.TooBigHVA*
+  __builtin_va_list thelist;
+  __builtin_va_start(thelist, n);
+  struct TooBigHVA h = __builtin_va_arg(thelist, struct TooBigHVA);
+  return h.d;
+}
diff --git a/test/CodeGen/arm64-be-bitfield.c b/test/CodeGen/arm64-be-bitfield.c
new file mode 100644
index 0000000..f563596
--- /dev/null
+++ b/test/CodeGen/arm64-be-bitfield.c
@@ -0,0 +1,9 @@
+// RUN:  %clang_cc1 -triple arm64_be-linux-gnu -ffreestanding -emit-llvm -O0 -o - %s | FileCheck %s
+
+struct bt3 { signed b2:10; signed b3:10; } b16;
+
+// The correct right-shift amount is 40 bits for big endian.
+signed callee_b0f(struct bt3 bp11) {
+// CHECK: = lshr i64 %{{.*}}, 40
+  return bp11.b2;
+}
diff --git a/test/CodeGen/arm64-be-hfa-vararg.c b/test/CodeGen/arm64-be-hfa-vararg.c
new file mode 100644
index 0000000..c9d6507
--- /dev/null
+++ b/test/CodeGen/arm64-be-hfa-vararg.c
@@ -0,0 +1,13 @@
+// RUN:  %clang_cc1 -triple arm64_be-linux-gnu -ffreestanding -emit-llvm -O0 -o - %s | FileCheck %s
+
+#include <stdarg.h>
+
+// A single member HFA must be aligned just like a non-HFA register argument.
+double callee(int a, ...) {
+// CHECK: = add i64 %{{.*}}, 8
+  va_list vl;
+  va_start(vl, a);
+  double result = va_arg(vl, struct { double a; }).a;
+  va_end(vl);
+  return result;
+}
diff --git a/test/CodeGen/arm64-crc32.c b/test/CodeGen/arm64-crc32.c
new file mode 100644
index 0000000..37ced18
--- /dev/null
+++ b/test/CodeGen/arm64-crc32.c
@@ -0,0 +1,55 @@
+// REQUIRES: aarch64-registered-target
+// RUN: %clang_cc1 -triple arm64-none-linux-gnu \
+// RUN:   -O3 -S -emit-llvm -o - %s | FileCheck %s
+
+int crc32b(int a, char b)
+{
+        return __builtin_arm_crc32b(a,b);
+// CHECK: [[T0:%[0-9]+]] = zext i8 %b to i32
+// CHECK: call i32 @llvm.aarch64.crc32b(i32 %a, i32 [[T0]])
+}
+
+int crc32cb(int a, char b)
+{
+        return __builtin_arm_crc32cb(a,b);
+// CHECK: [[T0:%[0-9]+]] = zext i8 %b to i32
+// CHECK: call i32 @llvm.aarch64.crc32cb(i32 %a, i32 [[T0]])
+}
+
+int crc32h(int a, short b)
+{
+        return __builtin_arm_crc32h(a,b);
+// CHECK: [[T0:%[0-9]+]] = zext i16 %b to i32
+// CHECK: call i32 @llvm.aarch64.crc32h(i32 %a, i32 [[T0]])
+}
+
+int crc32ch(int a, short b)
+{
+        return __builtin_arm_crc32ch(a,b);
+// CHECK: [[T0:%[0-9]+]] = zext i16 %b to i32
+// CHECK: call i32 @llvm.aarch64.crc32ch(i32 %a, i32 [[T0]])
+}
+
+int crc32w(int a, int b)
+{
+        return __builtin_arm_crc32w(a,b);
+// CHECK: call i32 @llvm.aarch64.crc32w(i32 %a, i32 %b)
+}
+
+int crc32cw(int a, int b)
+{
+        return __builtin_arm_crc32cw(a,b);
+// CHECK: call i32 @llvm.aarch64.crc32cw(i32 %a, i32 %b)
+}
+
+int crc32d(int a, long b)
+{
+        return __builtin_arm_crc32d(a,b);
+// CHECK: call i32 @llvm.aarch64.crc32x(i32 %a, i64 %b)
+}
+
+int crc32cd(int a, long b)
+{
+        return __builtin_arm_crc32cd(a,b);
+// CHECK: call i32 @llvm.aarch64.crc32cx(i32 %a, i64 %b)
+}
diff --git a/test/CodeGen/arm64-lanes.c b/test/CodeGen/arm64-lanes.c
new file mode 100644
index 0000000..8ab2bd4
--- /dev/null
+++ b/test/CodeGen/arm64-lanes.c
@@ -0,0 +1,74 @@
+// RUN: %clang_cc1 -O3 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O3 -triple arm64_be-linux-gnu -target-feature +neon -ffreestanding -emit-llvm -o - %s | FileCheck %s --check-prefix CHECK-BE
+
+#include <arm_neon.h>
+
+// CHECK-LABEL: @test_vdupb_lane_s8
+int8_t test_vdupb_lane_s8(int8x8_t src) {
+  return vdupb_lane_s8(src, 2);
+  // CHECK: extractelement <8 x i8> %src, i32 2
+  // CHECK-BE: extractelement <8 x i8> %src, i32 5
+}
+
+// CHECK-LABEL: @test_vdupb_lane_u8
+uint8_t test_vdupb_lane_u8(uint8x8_t src) {
+  return vdupb_lane_u8(src, 2);
+  // CHECK: extractelement <8 x i8> %src, i32 2
+  // CHECK-BE: extractelement <8 x i8> %src, i32 5
+}
+
+// CHECK-LABEL: @test_vduph_lane_s16
+int16_t test_vduph_lane_s16(int16x4_t src) {
+  return vduph_lane_s16(src, 2);
+  // CHECK: extractelement <4 x i16> %src, i32 2
+  // CHECK-BE: extractelement <4 x i16> %src, i32 1
+}
+
+// CHECK-LABEL: @test_vduph_lane_u16
+uint16_t test_vduph_lane_u16(uint16x4_t src) {
+  return vduph_lane_u16(src, 2);
+  // CHECK: extractelement <4 x i16> %src, i32 2
+  // CHECK-BE: extractelement <4 x i16> %src, i32 1
+}
+
+// CHECK-LABEL: @test_vdups_lane_s32
+int32_t test_vdups_lane_s32(int32x2_t src) {
+  return vdups_lane_s32(src, 0);
+  // CHECK: extractelement <2 x i32> %src, i32 0
+  // CHECK-BE: extractelement <2 x i32> %src, i32 1
+}
+
+// CHECK-LABEL: @test_vdups_lane_u32
+uint32_t test_vdups_lane_u32(uint32x2_t src) {
+  return vdups_lane_u32(src, 0);
+  // CHECK: extractelement <2 x i32> %src, i32 0
+  // CHECK-BE: extractelement <2 x i32> %src, i32 1
+}
+
+// CHECK-LABEL: @test_vdups_lane_f32
+float32_t test_vdups_lane_f32(float32x2_t src) {
+  return vdups_lane_f32(src, 0);
+  // CHECK: extractelement <2 x float> %src, i32 0
+  // CHECK-BE: extractelement <2 x float> %src, i32 1
+}
+
+// CHECK-LABEL: @test_vdupd_lane_s64
+int64_t test_vdupd_lane_s64(int64x1_t src) {
+  return vdupd_lane_s64(src, 0);
+  // CHECK: extractelement <1 x i64> %src, i32 0
+  // CHECK-BE: extractelement <1 x i64> %src, i32 0
+}
+
+// CHECK-LABEL: @test_vdupd_lane_u64
+uint64_t test_vdupd_lane_u64(uint64x1_t src) {
+  return vdupd_lane_u64(src, 0);
+  // CHECK: extractelement <1 x i64> %src, i32 0
+  // CHECK-BE: extractelement <1 x i64> %src, i32 0
+}
+
+// CHECK-LABEL: @test_vdupd_lane_f64
+float64_t test_vdupd_lane_f64(float64x1_t src) {
+  return vdupd_lane_f64(src, 0);
+  // CHECK: extractelement <1 x double> %src, i32 0
+  // CHECK-BE: extractelement <1 x double> %src, i32 0
+}
diff --git a/test/CodeGen/arm64-scalar-test.c b/test/CodeGen/arm64-scalar-test.c
new file mode 100644
index 0000000..e2328b1
--- /dev/null
+++ b/test/CodeGen/arm64-scalar-test.c
@@ -0,0 +1,547 @@
+// REQUIRES: aarch64-registered-target
+// RUN: %clang_cc1 -triple arm64-apple-ios7.0 -target-feature +neon  \
+// RUN:   -S -O1 -o - -ffreestanding %s | FileCheck %s
+
+// We're explicitly using arm_neon.h here: some types probably don't match
+// the ACLE definitions, but we want to check current codegen.
+#include <arm_neon.h>
+
+float test_vrsqrtss_f32(float a, float b) {
+// CHECK: test_vrsqrtss_f32
+  return vrsqrtss_f32(a, b);
+// CHECK: frsqrts {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
+}
+
+double test_vrsqrtsd_f64(double a, double b) {
+// CHECK: test_vrsqrtsd_f64
+  return vrsqrtsd_f64(a, b);
+// CHECK: frsqrts {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+}
+
+int64x1_t test_vrshl_s64(int64x1_t a, int64x1_t b) {
+// CHECK: test_vrshl_s64
+  return vrshl_s64(a, b);
+// CHECK: srshl {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+}
+
+uint64x1_t test_vrshl_u64(uint64x1_t a, int64x1_t b) {
+// CHECK: test_vrshl_u64
+  return vrshl_u64(a, b);
+// CHECK: urshl {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+}
+
+// CHECK: test_vrshld_s64
+int64_t test_vrshld_s64(int64_t a, int64_t b) {
+  return vrshld_s64(a, b);
+// CHECK: srshl {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+}
+
+// CHECK: test_vrshld_u64
+uint64_t test_vrshld_u64(uint64_t a, uint64_t b) {
+  return vrshld_u64(a, b);
+// CHECK: urshl {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+}
+
+// CHECK: test_vqrshlb_s8
+int8_t test_vqrshlb_s8(int8_t a, int8_t b) {
+  return vqrshlb_s8(a, b);
+// CHECK: sqrshl.8b {{v[0-9]+}}, {{v[0-9]+}}, {{v[0-9]+}}
+}
+
+// CHECK: test_vqrshlh_s16
+int16_t test_vqrshlh_s16(int16_t a, int16_t b) {
+  return vqrshlh_s16(a, b);
+// CHECK: sqrshl.4h {{v[0-9]+}}, {{v[0-9]+}}, {{v[0-9]+}}
+}
+
+// CHECK: test_vqrshls_s32
+int32_t test_vqrshls_s32(int32_t a, int32_t b) {
+  return vqrshls_s32(a, b);
+// CHECK: sqrshl {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
+}
+
+// CHECK: test_vqrshld_s64
+int64_t test_vqrshld_s64(int64_t a, int64_t b) {
+  return vqrshld_s64(a, b);
+// CHECK: sqrshl {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+}
+
+// CHECK: test_vqrshlb_u8
+uint8_t test_vqrshlb_u8(uint8_t a, uint8_t b) {
+  return vqrshlb_u8(a, b);
+// CHECK: uqrshl.8b {{v[0-9]+}}, {{v[0-9]+}}, {{v[0-9]+}}
+}
+
+// CHECK: test_vqrshlh_u16
+uint16_t test_vqrshlh_u16(uint16_t a, uint16_t b) {
+  return vqrshlh_u16(a, b);
+// CHECK: uqrshl.4h {{v[0-9]+}}, {{v[0-9]+}}, {{v[0-9]+}}
+}
+
+// CHECK: test_vqrshls_u32
+uint32_t test_vqrshls_u32(uint32_t a, uint32_t b) {
+  return vqrshls_u32(a, b);
+// CHECK: uqrshl {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
+}
+
+// CHECK: test_vqrshld_u64
+uint64_t test_vqrshld_u64(uint64_t a, uint64_t b) {
+  return vqrshld_u64(a, b);
+// CHECK: uqrshl {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+}
+
+// CHECK: test_vqshlb_s8
+int8_t test_vqshlb_s8(int8_t a, int8_t b) {
+  return vqshlb_s8(a, b);
+// CHECK: sqshl.8b {{v[0-9]+}}, {{v[0-9]+}}, {{v[0-9]+}}
+}
+
+// CHECK: test_vqshlh_s16
+int16_t test_vqshlh_s16(int16_t a, int16_t b) {
+  return vqshlh_s16(a, b);
+// CHECK: sqshl.4h {{v[0-9]+}}, {{v[0-9]+}}, {{v[0-9]+}}
+}
+
+// CHECK: test_vqshls_s32
+int32_t test_vqshls_s32(int32_t a, int32_t b) {
+  return vqshls_s32(a, b);
+// CHECK: sqshl {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
+}
+
+// CHECK: test_vqshld_s64
+int64_t test_vqshld_s64(int64_t a, int64_t b) {
+  return vqshld_s64(a, b);
+// CHECK: sqshl {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+}
+
+// CHECK: test_vqshld_s64_i
+int64_t test_vqshld_s64_i(int64_t a) {
+  return vqshld_s64(a, 36);
+// CHECK: sqshl {{d[0-9]+}}, {{d[0-9]+}}, #36
+}
+
+// CHECK: test_vqshlb_u8
+uint8_t test_vqshlb_u8(uint8_t a, uint8_t b) {
+  return vqshlb_u8(a, b);
+// CHECK: uqshl.8b {{v[0-9]+}}, {{v[0-9]+}}, {{v[0-9]+}}
+}
+
+// CHECK: test_vqshlh_u16
+uint16_t test_vqshlh_u16(uint16_t a, uint16_t b) {
+  return vqshlh_u16(a, b);
+// CHECK: uqshl.4h {{v[0-9]+}}, {{v[0-9]+}}, {{v[0-9]+}}
+}
+
+// CHECK: test_vqshls_u32
+uint32_t test_vqshls_u32(uint32_t a, uint32_t b) {
+  return vqshls_u32(a, b);
+// CHECK: uqshl {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
+}
+
+// CHECK: test_vqshld_u64
+uint64_t test_vqshld_u64(uint64_t a, uint64_t b) {
+  return vqshld_u64(a, b);
+// CHECK: uqshl {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+}
+
+// CHECK: test_vqshld_u64_i
+uint64_t test_vqshld_u64_i(uint64_t a) {
+  return vqshld_u64(a, 36);
+// CHECK: uqshl {{d[0-9]+}}, {{d[0-9]+}}, #36
+}
+
+// CHECK: test_vshld_u64
+uint64_t test_vshld_u64(uint64_t a, uint64_t b) {
+  return vshld_u64(a, b);
+// CHECK: ushl {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+}
+
+// CHECK: test_vshld_s64
+int64_t test_vshld_s64(int64_t a, int64_t b) {
+  return vshld_s64(a, b);
+// CHECK: sshl {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+}
+
+// CHECK: test_vqdmullh_s16
+int32_t test_vqdmullh_s16(int16_t a, int16_t b) {
+  return vqdmullh_s16(a, b);
+// CHECK: sqdmull.4s {{v[0-9]+}}, {{v[0-9]+}}, {{v[0-9]+}}
+}
+
+// CHECK: test_vqdmulls_s32
+int64_t test_vqdmulls_s32(int32_t a, int32_t b) {
+  return vqdmulls_s32(a, b);
+// CHECK: sqdmull {{d[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
+}
+
+// CHECK: test_vqaddb_s8
+int8_t test_vqaddb_s8(int8_t a, int8_t b) {
+  return vqaddb_s8(a, b);
+// CHECK: sqadd.8b {{v[0-9]+}}, {{v[0-9]+}}, {{v[0-9]+}}
+}
+
+// CHECK: test_vqaddh_s16
+int16_t test_vqaddh_s16(int16_t a, int16_t b) {
+  return vqaddh_s16(a, b);
+// CHECK: sqadd.4h {{v[0-9]+}}, {{v[0-9]+}}, {{v[0-9]+}}
+}
+
+// CHECK: test_vqadds_s32
+int32_t test_vqadds_s32(int32_t a, int32_t b) {
+  return vqadds_s32(a, b);
+// CHECK: sqadd {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
+}
+
+// CHECK: test_vqaddd_s64
+int64_t test_vqaddd_s64(int64_t a, int64_t b) {
+  return vqaddd_s64(a, b);
+// CHECK: sqadd {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+}
+
+// CHECK: test_vqaddb_u8
+uint8_t test_vqaddb_u8(uint8_t a, uint8_t b) {
+  return vqaddb_u8(a, b);
+// CHECK: uqadd.8b {{v[0-9]+}}, {{v[0-9]+}}, {{v[0-9]+}}
+}
+
+// CHECK: test_vqaddh_u16
+uint16_t test_vqaddh_u16(uint16_t a, uint16_t b) {
+  return vqaddh_u16(a, b);
+// CHECK: uqadd.4h {{v[0-9]+}}, {{v[0-9]+}}, {{v[0-9]+}}
+}
+
+// CHECK: test_vqadds_u32
+uint32_t test_vqadds_u32(uint32_t a, uint32_t b) {
+  return vqadds_u32(a, b);
+// CHECK: uqadd {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
+}
+
+// CHECK: test_vqaddd_u64
+uint64_t test_vqaddd_u64(uint64_t a, uint64_t b) {
+  return vqaddd_u64(a, b);
+// CHECK: uqadd {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+}
+
+// CHECK: test_vqsubb_s8
+int8_t test_vqsubb_s8(int8_t a, int8_t b) {
+  return vqsubb_s8(a, b);
+// CHECK: sqsub.8b {{v[0-9]+}}, {{v[0-9]+}}, {{v[0-9]+}}
+}
+
+// CHECK: test_vqsubh_s16
+int16_t test_vqsubh_s16(int16_t a, int16_t b) {
+  return vqsubh_s16(a, b);
+// CHECK: sqsub.4h {{v[0-9]+}}, {{v[0-9]+}}, {{v[0-9]+}}
+}
+
+// CHECK: test_vqsubs_s32
+int32_t test_vqsubs_s32(int32_t a, int32_t b) {
+  return vqsubs_s32(a, b);
+// CHECK: sqsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
+}
+
+// CHECK: test_vqsubd_s64
+int64_t test_vqsubd_s64(int64_t a, int64_t b) {
+  return vqsubd_s64(a, b);
+// CHECK: sqsub {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+}
+
+// CHECK: test_vqsubb_u8
+uint8_t test_vqsubb_u8(uint8_t a, uint8_t b) {
+  return vqsubb_u8(a, b);
+// CHECK: uqsub.8b {{v[0-9]+}}, {{v[0-9]+}}, {{v[0-9]+}}
+}
+
+// CHECK: test_vqsubh_u16
+uint16_t test_vqsubh_u16(uint16_t a, uint16_t b) {
+  return vqsubh_u16(a, b);
+// CHECK: uqsub.4h {{v[0-9]+}}, {{v[0-9]+}}, {{v[0-9]+}}
+}
+
+// CHECK: test_vqsubs_u32
+uint32_t test_vqsubs_u32(uint32_t a, uint32_t b) {
+  return vqsubs_u32(a, b);
+// CHECK: uqsub {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
+}
+
+// CHECK: test_vqsubd_u64
+uint64_t test_vqsubd_u64(uint64_t a, uint64_t b) {
+  return vqsubd_u64(a, b);
+// CHECK: uqsub {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+}
+
+// CHECK: test_vqmovnh_s16
+int8_t test_vqmovnh_s16(int16_t a) {
+  return vqmovnh_s16(a);
+// CHECK: sqxtn.8b {{v[0-9]+}}, {{v[0-9]+}}
+}
+
+// CHECK: test_vqmovnh_u16
+uint8_t test_vqmovnh_u16(uint16_t a) {
+  return vqmovnh_u16(a);
+// CHECK: uqxtn.8b {{v[0-9]+}}, {{v[0-9]+}}
+}
+
+// CHECK: test_vqmovns_s32
+int16_t test_vqmovns_s32(int32_t a) {
+  return vqmovns_s32(a);
+// CHECK: sqxtn.4h {{v[0-9]+}}, {{v[0-9]+}}
+}
+
+// CHECK: test_vqmovns_u32
+uint16_t test_vqmovns_u32(uint32_t a) {
+  return vqmovns_u32(a);
+// CHECK: uqxtn.4h {{v[0-9]+}}, {{v[0-9]+}}
+}
+
+// CHECK: test_vqmovnd_s64
+int32_t test_vqmovnd_s64(int64_t a) {
+  return vqmovnd_s64(a);
+// CHECK: sqxtn {{s[0-9]+}}, {{d[0-9]+}}
+}
+
+// CHECK: test_vqmovnd_u64
+uint32_t test_vqmovnd_u64(uint64_t a) {
+  return vqmovnd_u64(a);
+// CHECK: uqxtn {{s[0-9]+}}, {{d[0-9]+}}
+}
+
+// CHECK: test_vqmovunh_s16
+int8_t test_vqmovunh_s16(int16_t a) {
+  return vqmovunh_s16(a);
+// CHECK: sqxtun.8b {{v[0-9]+}}, {{v[0-9]+}}
+}
+
+// CHECK: test_vqmovuns_s32
+int16_t test_vqmovuns_s32(int32_t a) {
+  return vqmovuns_s32(a);
+// CHECK: sqxtun.4h {{v[0-9]+}}, {{v[0-9]+}}
+}
+
+// CHECK: test_vqmovund_s64
+int32_t test_vqmovund_s64(int64_t a) {
+  return vqmovund_s64(a);
+// CHECK: sqxtun {{s[0-9]+}}, {{d[0-9]+}}
+}
+
+// CHECK: test_vqabsb_s8
+int8_t test_vqabsb_s8(int8_t a) {
+  return vqabsb_s8(a);
+// CHECK: sqabs.8b {{v[0-9]+}}, {{v[0-9]+}}
+}
+
+// CHECK: test_vqabsh_s16
+int16_t test_vqabsh_s16(int16_t a) {
+  return vqabsh_s16(a);
+// CHECK: sqabs.4h {{v[0-9]+}}, {{v[0-9]+}}
+}
+
+// CHECK: test_vqabss_s32
+int32_t test_vqabss_s32(int32_t a) {
+  return vqabss_s32(a);
+// CHECK: sqabs {{s[0-9]+}}, {{s[0-9]+}}
+}
+
+// CHECK: test_vqabsd_s64
+int64_t test_vqabsd_s64(int64_t a) {
+  return vqabsd_s64(a);
+// CHECK: sqabs {{d[0-9]+}}, {{d[0-9]+}}
+}
+
+// CHECK: test_vqnegb_s8
+int8_t test_vqnegb_s8(int8_t a) {
+  return vqnegb_s8(a);
+// CHECK: sqneg.8b {{v[0-9]+}}, {{v[0-9]+}}
+}
+
+// CHECK: test_vqnegh_s16
+int16_t test_vqnegh_s16(int16_t a) {
+  return vqnegh_s16(a);
+// CHECK: sqneg.4h {{v[0-9]+}}, {{v[0-9]+}}
+}
+
+// CHECK: test_vqnegs_s32
+int32_t test_vqnegs_s32(int32_t a) {
+  return vqnegs_s32(a);
+// CHECK: sqneg {{s[0-9]+}}, {{s[0-9]+}}
+}
+
+// CHECK: test_vqnegd_s64
+int64_t test_vqnegd_s64(int64_t a) {
+  return vqnegd_s64(a);
+// CHECK: sqneg {{d[0-9]+}}, {{d[0-9]+}}
+}
+
+// CHECK: test_vcvts_n_f32_s32
+float32_t test_vcvts_n_f32_s32(int32_t a) {
+  return vcvts_n_f32_s32(a, 3);
+// CHECK: scvtf {{s[0-9]+}}, {{s[0-9]+}}, #3
+}
+
+// CHECK: test_vcvts_n_f32_u32
+float32_t test_vcvts_n_f32_u32(uint32_t a) {
+  return vcvts_n_f32_u32(a, 3);
+// CHECK: ucvtf {{s[0-9]+}}, {{s[0-9]+}}, #3
+}
+
+// CHECK: test_vcvtd_n_f64_s64
+float64_t test_vcvtd_n_f64_s64(int64_t a) {
+  return vcvtd_n_f64_s64(a, 3);
+// CHECK: scvtf {{d[0-9]+}}, {{d[0-9]+}}, #3
+}
+
+// CHECK: test_vcvtd_n_f64_u64
+float64_t test_vcvtd_n_f64_u64(uint64_t a) {
+  return vcvtd_n_f64_u64(a, 3);
+// CHECK: ucvtf {{d[0-9]+}}, {{d[0-9]+}}, #3
+}
+
+// CHECK: test_vcvts_n_s32_f32
+int32_t test_vcvts_n_s32_f32(float32_t a) {
+  return vcvts_n_s32_f32(a, 3);
+// CHECK: fcvtzs {{s[0-9]+}}, {{s[0-9]+}}, #3
+}
+
+// CHECK: test_vcvts_n_u32_f32
+uint32_t test_vcvts_n_u32_f32(float32_t a) {
+  return vcvts_n_u32_f32(a, 3);
+// CHECK: fcvtzu {{s[0-9]+}}, {{s[0-9]+}}, #3
+}
+
+// CHECK: test_vcvtd_n_s64_f64
+int64_t test_vcvtd_n_s64_f64(float64_t a) {
+  return vcvtd_n_s64_f64(a, 3);
+// CHECK: fcvtzs {{d[0-9]+}}, {{d[0-9]+}}, #3
+}
+
+// CHECK: test_vcvtd_n_u64_f64
+uint64_t test_vcvtd_n_u64_f64(float64_t a) {
+  return vcvtd_n_u64_f64(a, 3);
+// CHECK: fcvtzu {{d[0-9]+}}, {{d[0-9]+}}, #3
+}
+
+// CHECK: test_vcvtas_s32_f32
+int32_t test_vcvtas_s32_f32(float32_t a) {
+  return vcvtas_s32_f32(a);
+// CHECK: fcvtas {{w[0-9]+}}, {{s[0-9]+}}
+}
+
+// CHECK: test_vcvtas_u32_f32
+uint32_t test_vcvtas_u32_f32(float32_t a) {
+  return vcvtas_u32_f32(a);
+// CHECK: fcvtau {{w[0-9]+}}, {{s[0-9]+}}
+}
+
+// CHECK: test_vcvtad_s64_f64
+int64_t test_vcvtad_s64_f64(float64_t a) {
+  return vcvtad_s64_f64(a);
+// CHECK: fcvtas {{x[0-9]+}}, {{d[0-9]+}}
+}
+
+// CHECK: test_vcvtad_u64_f64
+uint64_t test_vcvtad_u64_f64(float64_t a) {
+  return vcvtad_u64_f64(a);
+// CHECK: fcvtau {{x[0-9]+}}, {{d[0-9]+}}
+}
+
+// CHECK: test_vcvtms_s32_f32
+int32_t test_vcvtms_s32_f32(float32_t a) {
+  return vcvtms_s32_f32(a);
+// CHECK: fcvtms {{w[0-9]+}}, {{s[0-9]+}}
+}
+
+// CHECK: test_vcvtms_u32_f32
+uint32_t test_vcvtms_u32_f32(float32_t a) {
+  return vcvtms_u32_f32(a);
+// CHECK: fcvtmu {{w[0-9]+}}, {{s[0-9]+}}
+}
+
+// CHECK: test_vcvtmd_s64_f64
+int64_t test_vcvtmd_s64_f64(float64_t a) {
+  return vcvtmd_s64_f64(a);
+// CHECK: fcvtms {{x[0-9]+}}, {{d[0-9]+}}
+}
+
+// CHECK: test_vcvtmd_u64_f64
+uint64_t test_vcvtmd_u64_f64(float64_t a) {
+  return vcvtmd_u64_f64(a);
+// CHECK: fcvtmu {{x[0-9]+}}, {{d[0-9]+}}
+}
+
+// CHECK: test_vcvtns_s32_f32
+int32_t test_vcvtns_s32_f32(float32_t a) {
+  return vcvtns_s32_f32(a);
+// CHECK: fcvtns {{w[0-9]+}}, {{s[0-9]+}}
+}
+
+// CHECK: test_vcvtns_u32_f32
+uint32_t test_vcvtns_u32_f32(float32_t a) {
+  return vcvtns_u32_f32(a);
+// CHECK: fcvtnu {{w[0-9]+}}, {{s[0-9]+}}
+}
+
+// CHECK: test_vcvtnd_s64_f64
+int64_t test_vcvtnd_s64_f64(float64_t a) {
+  return vcvtnd_s64_f64(a);
+// CHECK: fcvtns {{x[0-9]+}}, {{d[0-9]+}}
+}
+
+// CHECK: test_vcvtnd_u64_f64
+uint64_t test_vcvtnd_u64_f64(float64_t a) {
+  return vcvtnd_u64_f64(a);
+// CHECK: fcvtnu {{x[0-9]+}}, {{d[0-9]+}}
+}
+
+// CHECK: test_vcvtps_s32_f32
+int32_t test_vcvtps_s32_f32(float32_t a) {
+  return vcvtps_s32_f32(a);
+// CHECK: fcvtps {{w[0-9]+}}, {{s[0-9]+}}
+}
+
+// CHECK: test_vcvtps_u32_f32
+uint32_t test_vcvtps_u32_f32(float32_t a) {
+  return vcvtps_u32_f32(a);
+// CHECK: fcvtpu {{w[0-9]+}}, {{s[0-9]+}}
+}
+
+// CHECK: test_vcvtpd_s64_f64
+int64_t test_vcvtpd_s64_f64(float64_t a) {
+  return vcvtpd_s64_f64(a);
+// CHECK: fcvtps {{x[0-9]+}}, {{d[0-9]+}}
+}
+
+// CHECK: test_vcvtpd_u64_f64
+uint64_t test_vcvtpd_u64_f64(float64_t a) {
+  return vcvtpd_u64_f64(a);
+// CHECK: fcvtpu {{x[0-9]+}}, {{d[0-9]+}}
+}
+
+// CHECK: test_vcvtxd_f32_f64
+float32_t test_vcvtxd_f32_f64(float64_t a) {
+  return vcvtxd_f32_f64(a);
+// CHECK: fcvtxn {{s[0-9]+}}, {{d[0-9]+}}
+}
+
+// CHECK: test_vabds_f32
+float32_t test_vabds_f32(float32_t a, float32_t b) {
+  return vabds_f32(a, b);
+  // CHECK: fabd {{s[0-9]+}}, {{s[0-9]+}}
+}
+
+// CHECK: test_vabdd_f64
+float64_t test_vabdd_f64(float64_t a, float64_t b) {
+  return vabdd_f64(a, b);
+  // CHECK: fabd {{d[0-9]+}}, {{d[0-9]+}}
+}
+
+// CHECK: test_vmulxs_f32
+float32_t test_vmulxs_f32(float32_t a, float32_t b) {
+  return vmulxs_f32(a, b);
+  // CHECK: fmulx {{s[0-9]+}}, {{s[0-9]+}}
+}
+
+// CHECK: test_vmulxd_f64
+float64_t test_vmulxd_f64(float64_t a, float64_t b) {
+  return vmulxd_f64(a, b);
+  // CHECK: fmulx {{d[0-9]+}}, {{d[0-9]+}}
+}
diff --git a/test/CodeGen/arm64-vrnd.c b/test/CodeGen/arm64-vrnd.c
new file mode 100644
index 0000000..2c1bb8f
--- /dev/null
+++ b/test/CodeGen/arm64-vrnd.c
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -emit-llvm -o - %s | FileCheck %s
+
+#include <arm_neon.h>
+
+int32x2_t rnd1(float32x2_t a) { return vrnd_f32(a); }
+// CHECK: call <2 x float> @llvm.trunc.v2f32(<2 x float>
+int32x4_t rnd3(float32x4_t a) { return vrndq_f32(a); }
+// CHECK: call <4 x float> @llvm.trunc.v4f32(<4 x float>
+int64x2_t rnd5(float64x2_t a) { return vrndq_f64(a); }
+// CHECK: call <2 x double> @llvm.trunc.v2f64(<2 x double>
+
+
+int32x2_t rnd7(float32x2_t a) { return vrndn_f32(a); }
+// CHECK: call <2 x float> @llvm.aarch64.neon.frintn.v2f32(<2 x float>
+int32x4_t rnd8(float32x4_t a) { return vrndnq_f32(a); }
+// CHECK: call <4 x float> @llvm.aarch64.neon.frintn.v4f32(<4 x float>
+int64x2_t rnd9(float64x2_t a) { return vrndnq_f64(a); }
+// CHECK: call <2 x double> @llvm.aarch64.neon.frintn.v2f64(<2 x double>
+int64x2_t rnd10(float64x2_t a) { return vrndnq_f64(a); }
+// CHECK: call <2 x double> @llvm.aarch64.neon.frintn.v2f64(<2 x double>
+
+int32x2_t rnd11(float32x2_t a) { return vrndm_f32(a); }
+// CHECK: call <2 x float> @llvm.floor.v2f32(<2 x float>
+int32x4_t rnd12(float32x4_t a) { return vrndmq_f32(a); }
+// CHECK: call <4 x float> @llvm.floor.v4f32(<4 x float>
+int64x2_t rnd13(float64x2_t a) { return vrndmq_f64(a); }
+// CHECK: call <2 x double> @llvm.floor.v2f64(<2 x double>
+int64x2_t rnd14(float64x2_t a) { return vrndmq_f64(a); }
+// CHECK: call <2 x double> @llvm.floor.v2f64(<2 x double>
+
+int32x2_t rnd15(float32x2_t a) { return vrndp_f32(a); }
+// CHECK: call <2 x float> @llvm.ceil.v2f32(<2 x float>
+int32x4_t rnd16(float32x4_t a) { return vrndpq_f32(a); }
+// CHECK: call <4 x float> @llvm.ceil.v4f32(<4 x float>
+int64x2_t rnd18(float64x2_t a) { return vrndpq_f64(a); }
+// CHECK: call <2 x double> @llvm.ceil.v2f64(<2 x double>
+
+int32x2_t rnd19(float32x2_t a) { return vrnda_f32(a); }
+// CHECK: call <2 x float> @llvm.round.v2f32(<2 x float>
+int32x4_t rnd20(float32x4_t a) { return vrndaq_f32(a); }
+// CHECK: call <4 x float> @llvm.round.v4f32(<4 x float>
+int64x2_t rnd22(float64x2_t a) { return vrndaq_f64(a); }
+// CHECK: call <2 x double> @llvm.round.v2f64(<2 x double>
+
+int32x2_t rnd23(float32x2_t a) { return vrndx_f32(a); }
+// CHECK: call <2 x float> @llvm.rint.v2f32(<2 x float>
+int32x4_t rnd24(float32x4_t a) { return vrndxq_f32(a); }
+// CHECK: call <4 x float> @llvm.rint.v4f32(<4 x float>
+int64x2_t rnd25(float64x2_t a) { return vrndxq_f64(a); }
+// CHECK: call <2 x double> @llvm.rint.v2f64(<2 x double>
+
diff --git a/test/CodeGen/arm64-vrsqrt.c b/test/CodeGen/arm64-vrsqrt.c
new file mode 100644
index 0000000..821c23c
--- /dev/null
+++ b/test/CodeGen/arm64-vrsqrt.c
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -triple arm64-apple-ios7.0 -target-feature +neon -ffreestanding -emit-llvm -O1 -o - %s | FileCheck %s
+
+#include <arm_neon.h>
+
+uint32x2_t test_vrsqrte_u32(uint32x2_t in) {
+  // CHECK-LABEL: @test_vrsqrte_u32
+  // CHECK: call <2 x i32> @llvm.aarch64.neon.ursqrte.v2i32(<2 x i32> %in)
+  return vrsqrte_u32(in);
+}
+
+float32x2_t test_vrsqrte_f32(float32x2_t in) {
+  // CHECK-LABEL: @test_vrsqrte_f32
+  // CHECK: call <2 x float> @llvm.aarch64.neon.frsqrte.v2f32(<2 x float> %in)
+  return vrsqrte_f32(in);
+}
+
+
+uint32x4_t test_vrsqrteq_u32(uint32x4_t in) {
+  // CHECK-LABEL: @test_vrsqrteq_u32
+  // CHECK: call <4 x i32> @llvm.aarch64.neon.ursqrte.v4i32(<4 x i32> %in)
+  return vrsqrteq_u32(in);
+}
+
+float32x4_t test_vrsqrteq_f32(float32x4_t in) {
+  // CHECK-LABEL: @test_vrsqrteq_f32
+  // CHECK: call <4 x float> @llvm.aarch64.neon.frsqrte.v4f32(<4 x float> %in)
+  return vrsqrteq_f32(in);
+}
+
+
+float32x2_t test_vrsqrts_f32(float32x2_t est, float32x2_t val) {
+  // CHECK-LABEL: @test_vrsqrts_f32
+  // CHECK: call <2 x float> @llvm.aarch64.neon.frsqrts.v2f32(<2 x float> %est, <2 x float> %val)
+  return vrsqrts_f32(est, val);
+}
+
+
+float32x4_t test_vrsqrtsq_f32(float32x4_t est, float32x4_t val) {
+  // CHECK-LABEL: @test_vrsqrtsq_f32
+  // CHECK: call <4 x float> @llvm.aarch64.neon.frsqrts.v4f32(<4 x float> %est, <4 x float> %val)
+  return vrsqrtsq_f32(est, val);
+}
+
diff --git a/test/CodeGen/arm64_crypto.c b/test/CodeGen/arm64_crypto.c
new file mode 100644
index 0000000..e63009a
--- /dev/null
+++ b/test/CodeGen/arm64_crypto.c
@@ -0,0 +1,93 @@
+// RUN: %clang_cc1 -triple arm64-apple-ios7.0 -target-feature +neon -target-feature +crypto -ffreestanding -Os -S -o - %s | FileCheck %s
+// REQUIRES: aarch64-registered-target
+
+#include <arm_neon.h>
+
+uint8x16_t test_aese(uint8x16_t data, uint8x16_t key) {
+  // CHECK-LABEL: test_aese:
+  // CHECK: aese.16b v0, v1
+  return vaeseq_u8(data, key);
+}
+
+uint8x16_t test_aesd(uint8x16_t data, uint8x16_t key) {
+  // CHECK-LABEL: test_aesd:
+  // CHECK: aesd.16b v0, v1
+  return vaesdq_u8(data, key);
+}
+
+uint8x16_t test_aesmc(uint8x16_t data, uint8x16_t key) {
+  // CHECK-LABEL: test_aesmc:
+  // CHECK: aesmc.16b v0, v0
+  return vaesmcq_u8(data);
+}
+
+uint8x16_t test_aesimc(uint8x16_t data, uint8x16_t key) {
+  // CHECK-LABEL: test_aesimc:
+  // CHECK: aesimc.16b v0, v0
+  return vaesimcq_u8(data);
+}
+
+uint32x4_t test_sha1c(uint32x4_t hash_abcd, uint32_t hash_e, uint32x4_t wk) {
+  // CHECK-LABEL: test_sha1c:
+  // CHECK: fmov [[HASH_E:s[0-9]+]], w0
+  // CHECK: sha1c.4s q0, [[HASH_E]], v1
+  return vsha1cq_u32(hash_abcd, hash_e, wk);
+}
+
+uint32x4_t test_sha1p(uint32x4_t hash_abcd, uint32_t hash_e, uint32x4_t wk) {
+  // CHECK-LABEL: test_sha1p:
+  // CHECK: fmov [[HASH_E:s[0-9]+]], w0
+  // CHECK: sha1p.4s q0, [[HASH_E]], v1
+  return vsha1pq_u32(hash_abcd, hash_e, wk);
+}
+
+uint32x4_t test_sha1m(uint32x4_t hash_abcd, uint32_t hash_e, uint32x4_t wk) {
+  // CHECK-LABEL: test_sha1m:
+  // CHECK: fmov [[HASH_E:s[0-9]+]], w0
+  // CHECK: sha1m.4s q0, [[HASH_E]], v1
+  return vsha1mq_u32(hash_abcd, hash_e, wk);
+}
+
+uint32_t test_sha1h(uint32_t hash_e) {
+  // CHECK-LABEL: test_sha1h:
+  // CHECK: fmov [[HASH_E:s[0-9]+]], w0
+  // CHECK: sha1h [[RES:s[0-9]+]], [[HASH_E]]
+  // CHECK: fmov w0, [[RES]]
+  return vsha1h_u32(hash_e);
+}
+
+uint32x4_t test_sha1su0(uint32x4_t wk0_3, uint32x4_t wk4_7, uint32x4_t wk8_11) {
+  // CHECK-LABEL: test_sha1su0:
+  // CHECK: sha1su0.4s v0, v1, v2
+  return vsha1su0q_u32(wk0_3, wk4_7, wk8_11);
+}
+
+uint32x4_t test_sha1su1(uint32x4_t wk0_3, uint32x4_t wk12_15) {
+  // CHECK-LABEL: test_sha1su1:
+  // CHECK: sha1su1.4s v0, v1
+  return vsha1su1q_u32(wk0_3, wk12_15);
+}
+
+uint32x4_t test_sha256h(uint32x4_t hash_abcd, uint32x4_t hash_efgh, uint32x4_t wk) {
+  // CHECK-LABEL: test_sha256h:
+  // CHECK: sha256h.4s q0, q1, v2
+  return vsha256hq_u32(hash_abcd, hash_efgh, wk);
+}
+
+uint32x4_t test_sha256h2(uint32x4_t hash_efgh, uint32x4_t hash_abcd, uint32x4_t wk) {
+  // CHECK-LABEL: test_sha256h2:
+  // CHECK: sha256h2.4s q0, q1, v2
+  return vsha256h2q_u32(hash_efgh, hash_abcd, wk);
+}
+
+uint32x4_t test_sha256su0(uint32x4_t w0_3, uint32x4_t w4_7) {
+  // CHECK-LABEL: test_sha256su0:
+  // CHECK: sha256su0.4s v0, v1
+  return vsha256su0q_u32(w0_3, w4_7);
+}
+
+uint32x4_t test_sha256su1(uint32x4_t w0_3, uint32x4_t w8_11, uint32x4_t w12_15) {
+  // CHECK-LABEL: test_sha256su1:
+  // CHECK: sha256su1.4s v0, v1, v2
+  return vsha256su1q_u32(w0_3, w8_11, w12_15);
+}
diff --git a/test/CodeGen/arm64_neon_high_half.c b/test/CodeGen/arm64_neon_high_half.c
new file mode 100644
index 0000000..577a09e
--- /dev/null
+++ b/test/CodeGen/arm64_neon_high_half.c
@@ -0,0 +1,559 @@
+// RUN: %clang_cc1 -triple arm64-apple-ios7.0 -target-feature +neon -ffreestanding -Os -S -o - %s | FileCheck %s
+// REQUIRES: aarch64-registered-target
+
+#include <arm_neon.h>
+
+int16x8_t test_vaddw_high_s8(int16x8_t lhs, int8x16_t rhs) {
+  // CHECK: saddw2.8h
+  return vaddw_high_s8(lhs, rhs);
+}
+
+int32x4_t test_vaddw_high_s16(int32x4_t lhs, int16x8_t rhs) {
+  // CHECK: saddw2.4s
+  return vaddw_high_s16(lhs, rhs);
+}
+
+int64x2_t test_vaddw_high_s32(int64x2_t lhs, int32x4_t rhs) {
+  // CHECK: saddw2.2d
+  return vaddw_high_s32(lhs, rhs);
+}
+
+uint16x8_t test_vaddw_high_u8(uint16x8_t lhs, uint8x16_t rhs) {
+  // CHECK: uaddw2.8h
+  return vaddw_high_u8(lhs, rhs);
+}
+
+uint32x4_t test_vaddw_high_u16(uint32x4_t lhs, uint16x8_t rhs) {
+  // CHECK: uaddw2.4s
+  return vaddw_high_u16(lhs, rhs);
+}
+
+uint64x2_t test_vaddw_high_u32(uint64x2_t lhs, uint32x4_t rhs) {
+  // CHECK: uaddw2.2d
+  return vaddw_high_u32(lhs, rhs);
+}
+
+int16x8_t test_vsubw_high_s8(int16x8_t lhs, int8x16_t rhs) {
+  // CHECK: ssubw2.8h
+  return vsubw_high_s8(lhs, rhs);
+}
+
+int32x4_t test_vsubw_high_s16(int32x4_t lhs, int16x8_t rhs) {
+  // CHECK: ssubw2.4s
+  return vsubw_high_s16(lhs, rhs);
+}
+
+int64x2_t test_vsubw_high_s32(int64x2_t lhs, int32x4_t rhs) {
+  // CHECK: ssubw2.2d
+  return vsubw_high_s32(lhs, rhs);
+}
+
+uint16x8_t test_vsubw_high_u8(uint16x8_t lhs, uint8x16_t rhs) {
+  // CHECK: usubw2.8h
+  return vsubw_high_u8(lhs, rhs);
+}
+
+uint32x4_t test_vsubw_high_u16(uint32x4_t lhs, uint16x8_t rhs) {
+  // CHECK: usubw2.4s
+  return vsubw_high_u16(lhs, rhs);
+}
+
+uint64x2_t test_vsubw_high_u32(uint64x2_t lhs, uint32x4_t rhs) {
+  // CHECK: usubw2.2d
+  return vsubw_high_u32(lhs, rhs);
+}
+
+int16x8_t test_vabdl_high_s8(int8x16_t lhs, int8x16_t rhs) {
+  // CHECK: sabdl2.8h
+  return vabdl_high_s8(lhs, rhs);
+}
+
+int32x4_t test_vabdl_high_s16(int16x8_t lhs, int16x8_t rhs) {
+  // CHECK: sabdl2.4s
+  return vabdl_high_s16(lhs, rhs);
+}
+
+int64x2_t test_vabdl_high_s32(int32x4_t lhs, int32x4_t rhs) {
+  // CHECK: sabdl2.2d
+  return vabdl_high_s32(lhs, rhs);
+}
+
+uint16x8_t test_vabdl_high_u8(uint8x16_t lhs, uint8x16_t rhs) {
+  // CHECK: uabdl2.8h
+  return vabdl_high_u8(lhs, rhs);
+}
+
+uint32x4_t test_vabdl_high_u16(uint16x8_t lhs, uint16x8_t rhs) {
+  // CHECK: uabdl2.4s
+  return vabdl_high_u16(lhs, rhs);
+}
+
+uint64x2_t test_vabdl_high_u32(uint32x4_t lhs, uint32x4_t rhs) {
+  // CHECK: uabdl2.2d
+  return vabdl_high_u32(lhs, rhs);
+}
+
+int16x8_t test_vabal_high_s8(int16x8_t accum, int8x16_t lhs, int8x16_t rhs) {
+  // CHECK: sabal2.8h
+  return vabal_high_s8(accum, lhs, rhs);
+}
+
+int32x4_t test_vabal_high_s16(int32x4_t accum, int16x8_t lhs, int16x8_t rhs) {
+  // CHECK: sabal2.4s
+  return vabal_high_s16(accum, lhs, rhs);
+}
+
+int64x2_t test_vabal_high_s32(int64x2_t accum, int32x4_t lhs, int32x4_t rhs) {
+  // CHECK: sabal2.2d
+  return vabal_high_s32(accum, lhs, rhs);
+}
+
+uint16x8_t test_vabal_high_u8(uint16x8_t accum, uint8x16_t lhs, uint8x16_t rhs) {
+  // CHECK: uabal2.8h
+  return vabal_high_u8(accum, lhs, rhs);
+}
+
+uint32x4_t test_vabal_high_u16(uint32x4_t accum, uint16x8_t lhs, uint16x8_t rhs) {
+  // CHECK: uabal2.4s
+  return vabal_high_u16(accum, lhs, rhs);
+}
+
+uint64x2_t test_vabal_high_u32(uint64x2_t accum, uint32x4_t lhs, uint32x4_t rhs) {
+  // CHECK: uabal2.2d
+  return vabal_high_u32(accum, lhs, rhs);
+}
+
+int32x4_t test_vqdmlal_high_s16(int32x4_t accum, int16x8_t lhs, int16x8_t rhs) {
+  // CHECK: sqdmlal2.4s
+  return vqdmlal_high_s16(accum, lhs, rhs);
+}
+
+int64x2_t test_vqdmlal_high_s32(int64x2_t accum, int32x4_t lhs, int32x4_t rhs) {
+  // CHECK: sqdmlal2.2d
+  return vqdmlal_high_s32(accum, lhs, rhs);
+}
+
+int32x4_t test_vqdmlsl_high_s16(int32x4_t accum, int16x8_t lhs, int16x8_t rhs) {
+  // CHECK: sqdmlsl2.4s
+  return vqdmlsl_high_s16(accum, lhs, rhs);
+}
+
+int64x2_t test_vqdmlsl_high_s32(int64x2_t accum, int32x4_t lhs, int32x4_t rhs) {
+  // CHECK: sqdmlsl2.2d
+  return vqdmlsl_high_s32(accum, lhs, rhs);
+}
+
+int32x4_t test_vqdmull_high_s16(int16x8_t lhs, int16x8_t rhs) {
+  // CHECK: sqdmull2.4s
+  return vqdmull_high_s16(lhs, rhs);
+}
+
+int64x2_t test_vqdmull_high_s32(int32x4_t lhs, int32x4_t rhs) {
+  // CHECK: sqdmull2.2d
+  return vqdmull_high_s32(lhs, rhs);
+}
+
+int16x8_t test_vshll_high_n_s8(int8x16_t in) {
+  // CHECK: sshll2.8h
+  return vshll_high_n_s8(in, 7);
+}
+
+int32x4_t test_vshll_high_n_s16(int16x8_t in) {
+  // CHECK: sshll2.4s
+  return vshll_high_n_s16(in, 15);
+}
+
+int64x2_t test_vshll_high_n_s32(int32x4_t in) {
+  // CHECK: sshll2.2d
+  return vshll_high_n_s32(in, 31);
+}
+
+int16x8_t test_vshll_high_n_u8(int8x16_t in) {
+  // CHECK: ushll2.8h
+  return vshll_high_n_u8(in, 7);
+}
+
+int32x4_t test_vshll_high_n_u16(int16x8_t in) {
+  // CHECK: ushll2.4s
+  return vshll_high_n_u16(in, 15);
+}
+
+int64x2_t test_vshll_high_n_u32(int32x4_t in) {
+  // CHECK: ushll2.2d
+  return vshll_high_n_u32(in, 31);
+}
+
+int16x8_t test_vshll_high_n_s8_max(int8x16_t in) {
+  // CHECK: shll2.8h
+  return vshll_high_n_s8(in, 8);
+}
+
+int32x4_t test_vshll_high_n_s16_max(int16x8_t in) {
+  // CHECK: shll2.4s
+  return vshll_high_n_s16(in, 16);
+}
+
+int64x2_t test_vshll_high_n_s32_max(int32x4_t in) {
+  // CHECK: shll2.2d
+  return vshll_high_n_s32(in, 32);
+}
+
+int16x8_t test_vshll_high_n_u8_max(int8x16_t in) {
+  // CHECK: shll2.8h
+  return vshll_high_n_u8(in, 8);
+}
+
+int32x4_t test_vshll_high_n_u16_max(int16x8_t in) {
+  // CHECK: shll2.4s
+  return vshll_high_n_u16(in, 16);
+}
+
+int64x2_t test_vshll_high_n_u32_max(int32x4_t in) {
+  // CHECK: shll2.2d
+  return vshll_high_n_u32(in, 32);
+}
+
+int16x8_t test_vsubl_high_s8(int8x16_t lhs, int8x16_t rhs) {
+  // CHECK: ssubl2.8h
+  return vsubl_high_s8(lhs, rhs);
+}
+
+int32x4_t test_vsubl_high_s16(int16x8_t lhs, int16x8_t rhs) {
+  // CHECK: ssubl2.4s
+  return vsubl_high_s16(lhs, rhs);
+}
+
+int64x2_t test_vsubl_high_s32(int32x4_t lhs, int32x4_t rhs) {
+  // CHECK: ssubl2.2d
+  return vsubl_high_s32(lhs, rhs);
+}
+
+uint16x8_t test_vsubl_high_u8(uint8x16_t lhs, uint8x16_t rhs) {
+  // CHECK: usubl2.8h
+  return vsubl_high_u8(lhs, rhs);
+}
+
+uint32x4_t test_vsubl_high_u16(uint16x8_t lhs, uint16x8_t rhs) {
+  // CHECK: usubl2.4s
+  return vsubl_high_u16(lhs, rhs);
+}
+
+uint64x2_t test_vsubl_high_u32(uint32x4_t lhs, uint32x4_t rhs) {
+  // CHECK: usubl2.2d
+  return vsubl_high_u32(lhs, rhs);
+}
+
+int8x16_t test_vrshrn_high_n_s16(int8x8_t lowpart, int16x8_t input) {
+  // CHECK: rshrn2.16b
+  return vrshrn_high_n_s16(lowpart, input, 2);
+}
+
+int16x8_t test_vrshrn_high_n_s32(int16x4_t lowpart, int32x4_t input) {
+  // CHECK: rshrn2.8h
+  return vrshrn_high_n_s32(lowpart, input, 2);
+}
+
+int32x4_t test_vrshrn_high_n_s64(int32x2_t lowpart, int64x2_t input) {
+  // CHECK: shrn2.4s
+  return vrshrn_high_n_s64(lowpart, input, 2);
+}
+
+uint8x16_t test_vrshrn_high_n_u16(uint8x8_t lowpart, uint16x8_t input) {
+  // CHECK: rshrn2.16b
+  return vrshrn_high_n_u16(lowpart, input, 2);
+}
+
+uint16x8_t test_vrshrn_high_n_u32(uint16x4_t lowpart, uint32x4_t input) {
+  // CHECK: rshrn2.8h
+  return vrshrn_high_n_u32(lowpart, input, 2);
+}
+
+uint32x4_t test_vrshrn_high_n_u64(uint32x2_t lowpart, uint64x2_t input) {
+  // CHECK: rshrn2.4s
+  return vrshrn_high_n_u64(lowpart, input, 2);
+}
+
+int8x16_t test_vshrn_high_n_s16(int8x8_t lowpart, int16x8_t input) {
+  // CHECK: shrn2.16b
+  return vshrn_high_n_s16(lowpart, input, 2);
+}
+
+int16x8_t test_vshrn_high_n_s32(int16x4_t lowpart, int32x4_t input) {
+  // CHECK: shrn2.8h
+  return vshrn_high_n_s32(lowpart, input, 2);
+}
+
+int32x4_t test_vshrn_high_n_s64(int32x2_t lowpart, int64x2_t input) {
+  // CHECK: shrn2.4s
+  return vshrn_high_n_s64(lowpart, input, 2);
+}
+
+uint8x16_t test_vshrn_high_n_u16(uint8x8_t lowpart, uint16x8_t input) {
+  // CHECK: shrn2.16b
+  return vshrn_high_n_u16(lowpart, input, 2);
+}
+
+uint16x8_t test_vshrn_high_n_u32(uint16x4_t lowpart, uint32x4_t input) {
+  // CHECK: shrn2.8h
+  return vshrn_high_n_u32(lowpart, input, 2);
+}
+
+uint32x4_t test_vshrn_high_n_u64(uint32x2_t lowpart, uint64x2_t input) {
+  // CHECK: shrn2.4s
+  return vshrn_high_n_u64(lowpart, input, 2);
+}
+
+uint8x16_t test_vqshrun_high_n_s16(uint8x8_t lowpart, int16x8_t input) {
+  // CHECK: sqshrun2.16b
+  return vqshrun_high_n_s16(lowpart, input, 2);
+}
+
+uint16x8_t test_vqshrun_high_n_s32(uint16x4_t lowpart, int32x4_t input) {
+  // CHECK: sqshrun2.8h
+  return vqshrun_high_n_s32(lowpart, input, 2);
+}
+
+uint32x4_t test_vqshrun_high_n_s64(uint32x2_t lowpart, int64x2_t input) {
+  // CHECK: sqshrun2.4s
+  return vqshrun_high_n_s64(lowpart, input, 2);
+}
+
+uint8x16_t test_vqrshrun_high_n_s16(uint8x8_t lowpart, int16x8_t input) {
+  // CHECK: sqrshrun2.16b
+  return vqrshrun_high_n_s16(lowpart, input, 2);
+}
+
+uint16x8_t test_vqrshrun_high_n_s32(uint16x4_t lowpart, int32x4_t input) {
+  // CHECK: sqrshrun2.8h
+  return vqrshrun_high_n_s32(lowpart, input, 2);
+}
+
+uint32x4_t test_vqrshrun_high_n_s64(uint32x2_t lowpart, int64x2_t input) {
+  // CHECK: sqrshrun2.4s
+  return vqrshrun_high_n_s64(lowpart, input, 2);
+}
+
+int8x16_t test_vqshrn_high_n_s16(int8x8_t lowpart, int16x8_t input) {
+  // CHECK: sqshrn2.16b
+  return vqshrn_high_n_s16(lowpart, input, 2);
+}
+
+int16x8_t test_vqshrn_high_n_s32(int16x4_t lowpart, int32x4_t input) {
+  // CHECK: sqshrn2.8h
+  return vqshrn_high_n_s32(lowpart, input, 2);
+}
+
+int32x4_t test_vqshrn_high_n_s64(int32x2_t lowpart, int64x2_t input) {
+  // CHECK: sqshrn2.4s
+  return vqshrn_high_n_s64(lowpart, input, 2);
+}
+
+uint8x16_t test_vqshrn_high_n_u16(uint8x8_t lowpart, uint16x8_t input) {
+  // CHECK: uqshrn2.16b
+  return vqshrn_high_n_u16(lowpart, input, 2);
+}
+
+uint16x8_t test_vqshrn_high_n_u32(uint16x4_t lowpart, uint32x4_t input) {
+  // CHECK: uqshrn2.8h
+  return vqshrn_high_n_u32(lowpart, input, 2);
+}
+
+uint32x4_t test_vqshrn_high_n_u64(uint32x2_t lowpart, uint64x2_t input) {
+  // CHECK: uqshrn2.4s
+  return vqshrn_high_n_u64(lowpart, input, 2);
+}
+
+int8x16_t test_vqrshrn_high_n_s16(int8x8_t lowpart, int16x8_t input) {
+  // CHECK: sqrshrn2.16b
+  return vqrshrn_high_n_s16(lowpart, input, 2);
+}
+
+int16x8_t test_vqrshrn_high_n_s32(int16x4_t lowpart, int32x4_t input) {
+  // CHECK: sqrshrn2.8h
+  return vqrshrn_high_n_s32(lowpart, input, 2);
+}
+
+int32x4_t test_vqrshrn_high_n_s64(int32x2_t lowpart, int64x2_t input) {
+  // CHECK: sqrshrn2.4s
+  return vqrshrn_high_n_s64(lowpart, input, 2);
+}
+
+uint8x16_t test_vqrshrn_high_n_u16(uint8x8_t lowpart, uint16x8_t input) {
+  // CHECK: uqrshrn2.16b
+  return vqrshrn_high_n_u16(lowpart, input, 2);
+}
+
+uint16x8_t test_vqrshrn_high_n_u32(uint16x4_t lowpart, uint32x4_t input) {
+  // CHECK: uqrshrn2.8h
+  return vqrshrn_high_n_u32(lowpart, input, 2);
+}
+
+uint32x4_t test_vqrshrn_high_n_u64(uint32x2_t lowpart, uint64x2_t input) {
+  // CHECK: uqrshrn2.4s
+  return vqrshrn_high_n_u64(lowpart, input, 2);
+}
+
+int8x16_t test_vaddhn_high_s16(int8x8_t lowpart, int16x8_t lhs, int16x8_t rhs) {
+  // CHECK: addhn2.16b v0, v1, v2
+  return vaddhn_high_s16(lowpart, lhs, rhs);
+}
+
+int16x8_t test_vaddhn_high_s32(int16x4_t lowpart, int32x4_t lhs, int32x4_t rhs) {
+  // CHECK: addhn2.8h v0, v1, v2
+  return vaddhn_high_s32(lowpart, lhs, rhs);
+}
+
+int32x4_t test_vaddhn_high_s64(int32x2_t lowpart, int64x2_t lhs, int64x2_t rhs) {
+  // CHECK: addhn2.4s v0, v1, v2
+  return vaddhn_high_s64(lowpart, lhs, rhs);
+}
+
+uint8x16_t test_vaddhn_high_u16(uint8x8_t lowpart, uint16x8_t lhs, uint16x8_t rhs) {
+  // CHECK: addhn2.16b v0, v1, v2
+  return vaddhn_high_s16(lowpart, lhs, rhs);
+}
+
+uint16x8_t test_vaddhn_high_u32(uint16x4_t lowpart, uint32x4_t lhs, uint32x4_t rhs) {
+  // CHECK: addhn2.8h v0, v1, v2
+  return vaddhn_high_s32(lowpart, lhs, rhs);
+}
+
+uint32x4_t test_vaddhn_high_u64(uint32x2_t lowpart, uint64x2_t lhs, uint64x2_t rhs) {
+  // CHECK: addhn2.4s v0, v1, v2
+  return vaddhn_high_s64(lowpart, lhs, rhs);
+}
+
+int8x16_t test_vraddhn_high_s16(int8x8_t lowpart, int16x8_t lhs, int16x8_t rhs) {
+  // CHECK: raddhn2.16b v0, v1, v2
+  return vraddhn_high_s16(lowpart, lhs, rhs);
+}
+
+int16x8_t test_vraddhn_high_s32(int16x4_t lowpart, int32x4_t lhs, int32x4_t rhs) {
+  // CHECK: raddhn2.8h v0, v1, v2
+  return vraddhn_high_s32(lowpart, lhs, rhs);
+}
+
+int32x4_t test_vraddhn_high_s64(int32x2_t lowpart, int64x2_t lhs, int64x2_t rhs) {
+  // CHECK: raddhn2.4s v0, v1, v2
+  return vraddhn_high_s64(lowpart, lhs, rhs);
+}
+
+uint8x16_t test_vraddhn_high_u16(uint8x8_t lowpart, uint16x8_t lhs, uint16x8_t rhs) {
+  // CHECK: raddhn2.16b v0, v1, v2
+  return vraddhn_high_s16(lowpart, lhs, rhs);
+}
+
+uint16x8_t test_vraddhn_high_u32(uint16x4_t lowpart, uint32x4_t lhs, uint32x4_t rhs) {
+  // CHECK: raddhn2.8h v0, v1, v2
+  return vraddhn_high_s32(lowpart, lhs, rhs);
+}
+
+uint32x4_t test_vraddhn_high_u64(uint32x2_t lowpart, uint64x2_t lhs, uint64x2_t rhs) {
+  // CHECK: raddhn2.4s v0, v1, v2
+  return vraddhn_high_s64(lowpart, lhs, rhs);
+}
+
+int8x16_t test_vmovn_high_s16(int8x8_t lowpart, int16x8_t wide) {
+  // CHECK: xtn2.16b v0, v1
+  return vmovn_high_s16(lowpart, wide);
+}
+
+int16x8_t test_vmovn_high_s32(int16x4_t lowpart, int32x4_t wide) {
+  // CHECK: xtn2.8h v0, v1
+  return vmovn_high_s32(lowpart, wide);
+}
+
+int32x4_t test_vmovn_high_s64(int32x2_t lowpart, int64x2_t wide) {
+  // CHECK: xtn2.4s v0, v1
+  return vmovn_high_s64(lowpart, wide);
+}
+
+uint8x16_t test_vmovn_high_u16(uint8x8_t lowpart, uint16x8_t wide) {
+  // CHECK: xtn2.16b v0, v1
+  return vmovn_high_u16(lowpart, wide);
+}
+
+uint16x8_t test_vmovn_high_u32(uint16x4_t lowpart, uint32x4_t wide) {
+  // CHECK: xtn2.8h v0, v1
+  return vmovn_high_u32(lowpart, wide);
+}
+
+uint32x4_t test_vmovn_high_u64(uint32x2_t lowpart, uint64x2_t wide) {
+  // CHECK: xtn2.4s v0, v1
+  return vmovn_high_u64(lowpart, wide);
+}
+
+int8x16_t test_vqmovn_high_s16(int8x8_t lowpart, int16x8_t wide) {
+  // CHECK: sqxtn2.16b v0, v1
+  return vqmovn_high_s16(lowpart, wide);
+}
+
+int16x8_t test_vqmovn_high_s32(int16x4_t lowpart, int32x4_t wide) {
+  // CHECK: sqxtn2.8h v0, v1
+  return vqmovn_high_s32(lowpart, wide);
+}
+
+int32x4_t test_vqmovn_high_s64(int32x2_t lowpart, int64x2_t wide) {
+  // CHECK: sqxtn2.4s v0, v1
+  return vqmovn_high_s64(lowpart, wide);
+}
+
+uint8x16_t test_vqmovn_high_u16(uint8x8_t lowpart, int16x8_t wide) {
+  // CHECK: uqxtn2.16b v0, v1
+  return vqmovn_high_u16(lowpart, wide);
+}
+
+uint16x8_t test_vqmovn_high_u32(uint16x4_t lowpart, int32x4_t wide) {
+  // CHECK: uqxtn2.8h v0, v1
+  return vqmovn_high_u32(lowpart, wide);
+}
+
+uint32x4_t test_vqmovn_high_u64(uint32x2_t lowpart, int64x2_t wide) {
+  // CHECK: uqxtn2.4s v0, v1
+  return vqmovn_high_u64(lowpart, wide);
+}
+
+uint8x16_t test_vqmovun_high_s16(uint8x8_t lowpart, int16x8_t wide) {
+  // CHECK: sqxtun2.16b v0, v1
+  return vqmovun_high_s16(lowpart, wide);
+}
+
+uint16x8_t test_vqmovun_high_s32(uint16x4_t lowpart, int32x4_t wide) {
+  // CHECK: sqxtun2.8h v0, v1
+  return vqmovun_high_s32(lowpart, wide);
+}
+
+uint32x4_t test_vqmovun_high_s64(uint32x2_t lowpart, int64x2_t wide) {
+  // CHECK: sqxtun2.4s v0, v1
+  return vqmovun_high_s64(lowpart, wide);
+}
+
+float32x4_t test_vcvtx_high_f32_f64(float32x2_t lowpart, float64x2_t wide) {
+  // CHECK: fcvtxn2 v0.4s, v1.2d
+  return vcvtx_high_f32_f64(lowpart, wide);
+}
+
+float64x2_t test_vcvt_f64_f32(float32x2_t x) {
+  // CHECK: fcvtl v0.2d, v0.2s
+  return vcvt_f64_f32(x);
+}
+
+float64x2_t test_vcvt_high_f64_f32(float32x4_t x) {
+  // CHECK: fcvtl2 v0.2d, v0.4s
+  return vcvt_high_f64_f32(x);
+}
+
+float32x2_t test_vcvt_f32_f64(float64x2_t v) {
+  // CHECK: fcvtn v0.2s, v0.2d
+  return vcvt_f32_f64(v);
+}
+
+float32x4_t test_vcvt_high_f32_f64(float32x2_t x, float64x2_t v) {
+  // CHECK: fcvtn2 v0.4s, v1.2d
+  return vcvt_high_f32_f64(x, v);
+}
+
+float32x2_t test_vcvtx_f32_f64(float64x2_t v) {
+  // CHECK: fcvtxn v0.2s, v0.2d
+  return vcvtx_f32_f64(v);
+}
diff --git a/test/CodeGen/arm64_vCMP.c b/test/CodeGen/arm64_vCMP.c
new file mode 100644
index 0000000..a302128
--- /dev/null
+++ b/test/CodeGen/arm64_vCMP.c
@@ -0,0 +1,108 @@
+// RUN: %clang_cc1 -O1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -S -o - -emit-llvm %s | FileCheck %s
+
+// Test ARM64 SIMD fused multiply add intrinsics
+
+#include <arm_neon.h>
+
+int64x2_t test_vabsq_s64(int64x2_t a1) {
+  // CHECK: test_vabsq_s64
+  return vabsq_s64(a1);
+  // CHECK: llvm.aarch64.neon.abs.v2i64
+  // CHECK-NEXT: ret
+}
+
+int64_t test_vceqd_s64(int64_t a1, int64_t a2) {
+  // CHECK: test_vceqd_s64
+  return vceqd_s64(a1, a2);
+  // CHECK: [[BIT:%[0-9a-zA-Z.]+]] = icmp eq i64 %a1, %a2
+  // CHECK: sext i1 [[BIT]] to i64
+}
+
+int64_t test_vceqd_f64(float64_t a1, float64_t a2) {
+  // CHECK: test_vceqd_f64
+  return vceqd_f64(a1, a2);
+  // CHECK: [[BIT:%[0-9a-zA-Z.]+]] = fcmp oeq double %a1, %a2
+  // CHECK: sext i1 [[BIT]] to i64
+}
+
+uint64_t test_vcgtd_u64(uint64_t a1, uint64_t a2) {
+  // CHECK: test_vcgtd_u64
+  return vcgtd_u64(a1, a2);
+  // CHECK: [[BIT:%[0-9a-zA-Z.]+]] = icmp ugt i64 %a1, %a2
+  // CHECK: sext i1 [[BIT]] to i64
+}
+
+uint64_t test_vcled_u64(uint64_t a1, uint64_t a2) {
+  // CHECK: test_vcled_u64
+  return vcled_u64(a1, a2);
+  // CHECK: [[BIT:%[0-9a-zA-Z.]+]] = icmp ule i64 %a1, %a2
+  // CHECK: sext i1 [[BIT]] to i64
+}
+
+int64_t test_vceqzd_s64(int64_t a1) {
+  // CHECK: test_vceqzd_s64
+  return vceqzd_s64(a1);
+  // CHECK: [[BIT:%[0-9a-zA-Z.]+]] = icmp eq i64 %a1, 0
+  // CHECK: sext i1 [[BIT]] to i64
+}
+
+uint64x2_t test_vceqq_u64(uint64x2_t a1, uint64x2_t a2) {
+  // CHECK: test_vceqq_u64
+  return vceqq_u64(a1, a2);
+  // CHECK:  icmp eq <2 x i64> %a1, %a2
+}
+
+uint64x2_t test_vcgeq_s64(int64x2_t a1, int64x2_t a2) {
+  // CHECK: test_vcgeq_s64
+  return vcgeq_s64(a1, a2);
+  // CHECK:  icmp sge <2 x i64> %a1, %a2
+}
+
+uint64x2_t test_vcgeq_u64(uint64x2_t a1, uint64x2_t a2) {
+  // CHECK: test_vcgeq_u64
+  return vcgeq_u64(a1, a2);
+  // CHECK:  icmp uge <2 x i64> %a1, %a2
+}
+
+uint64x2_t test_vcgtq_s64(int64x2_t a1, int64x2_t a2) {
+  // CHECK: test_vcgtq_s64
+  return vcgtq_s64(a1, a2);
+  // CHECK: icmp sgt <2 x i64> %a1, %a2
+}
+
+uint64x2_t test_vcgtq_u64(uint64x2_t a1, uint64x2_t a2) {
+  // CHECK: test_vcgtq_u64
+  return vcgtq_u64(a1, a2);
+  // CHECK: icmp ugt <2 x i64> %a1, %a2
+}
+
+uint64x2_t test_vcleq_s64(int64x2_t a1, int64x2_t a2) {
+  // CHECK: test_vcleq_s64
+  return vcleq_s64(a1, a2);
+  // CHECK: icmp sle <2 x i64> %a1, %a2
+}
+
+uint64x2_t test_vcleq_u64(uint64x2_t a1, uint64x2_t a2) {
+  // CHECK: test_vcleq_u64
+  return vcleq_u64(a1, a2);
+  // CHECK: icmp ule <2 x i64> %a1, %a2
+}
+
+uint64x2_t test_vcltq_s64(int64x2_t a1, int64x2_t a2) {
+  // CHECK: test_vcltq_s64
+  return vcltq_s64(a1, a2);
+  // CHECK: icmp slt <2 x i64> %a1, %a2
+}
+
+uint64x2_t test_vcltq_u64(uint64x2_t a1, uint64x2_t a2) {
+  // CHECK: test_vcltq_u64
+  return vcltq_u64(a1, a2);
+  // CHECK: icmp ult <2 x i64> %a1, %a2
+}
+
+int64x2_t test_vqabsq_s64(int64x2_t a1) {
+  // CHECK: test_vqabsq_s64
+  return vqabsq_s64(a1);
+  // CHECK: llvm.aarch64.neon.sqabs.v2i64(<2 x i64> %a1)
+  // CHECK-NEXT: ret
+}
diff --git a/test/CodeGen/arm64_vLdStNum_lane.c b/test/CodeGen/arm64_vLdStNum_lane.c
new file mode 100644
index 0000000..85229d5
--- /dev/null
+++ b/test/CodeGen/arm64_vLdStNum_lane.c
@@ -0,0 +1,141 @@
+// RUN: %clang_cc1 -O1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -S -o - -emit-llvm %s | FileCheck %s
+// Test ARM64 SIMD load and stores of an N-element structure  intrinsics
+
+#include <arm_neon.h>
+
+int64x2x2_t test_vld2q_lane_s64(const void * a1, int64x2x2_t a2) {
+  // CHECK: test_vld2q_lane_s64
+  return vld2q_lane_s64(a1, a2, 1);
+  // CHECK: llvm.aarch64.neon.ld2lane.v2i64.p0i8
+}
+
+uint64x2x2_t test_vld2q_lane_u64(const void * a1, uint64x2x2_t a2) {
+  // CHECK: test_vld2q_lane_u64
+  return vld2q_lane_u64(a1, a2, 1);
+  // CHECK: llvm.aarch64.neon.ld2lane.v2i64.p0i8
+}
+
+int64x1x2_t test_vld2_lane_s64(const void * a1, int64x1x2_t a2) {
+  // CHECK: test_vld2_lane_s64
+  return vld2_lane_s64(a1, a2, 0);
+  // CHECK: llvm.aarch64.neon.ld2lane.v1i64.p0i8
+}
+
+uint64x1x2_t test_vld2_lane_u64(const void * a1, uint64x1x2_t a2) {
+  // CHECK: test_vld2_lane_u64
+  return vld2_lane_u64(a1, a2, 0);
+  // CHECK: llvm.aarch64.neon.ld2lane.v1i64.p0i8
+}
+
+poly8x16x2_t test_vld2q_lane_p8(const void * a1, poly8x16x2_t a2) {
+  // CHECK: test_vld2q_lane_p8
+  return vld2q_lane_p8(a1, a2, 0);
+  // CHECK: extractvalue {{.*}} 0{{ *$}}
+  // CHECK: extractvalue {{.*}} 1{{ *$}}
+}
+
+uint8x16x2_t test_vld2q_lane_u8(const void * a1, uint8x16x2_t a2) {
+  // CHECK: test_vld2q_lane_u8
+  return vld2q_lane_u8(a1, a2, 0);
+  // CHECK: llvm.aarch64.neon.ld2lane.v16i8.p0i8
+}
+
+int64x2x3_t test_vld3q_lane_s64(const void * a1, int64x2x3_t a2) {
+  // CHECK: test_vld3q_lane_s64
+  return vld3q_lane_s64(a1, a2, 1);
+  // CHECK: llvm.aarch64.neon.ld3lane.v2i64.p0i8
+}
+
+uint64x2x3_t test_vld3q_lane_u64(const void * a1, uint64x2x3_t a2) {
+  // CHECK: test_vld3q_lane_u64
+  return vld3q_lane_u64(a1, a2, 1);
+  // CHECK: llvm.aarch64.neon.ld3lane.v2i64.p0i8
+}
+
+int64x1x3_t test_vld3_lane_s64(const void * a1, int64x1x3_t a2) {
+  // CHECK: test_vld3_lane_s64
+  return vld3_lane_s64(a1, a2, 0);
+  // CHECK: llvm.aarch64.neon.ld3lane.v1i64.p0i8
+}
+
+uint64x1x3_t test_vld3_lane_u64(const void * a1, uint64x1x3_t a2) {
+  // CHECK: test_vld3_lane_u64
+  return vld3_lane_u64(a1, a2, 0);
+  // CHECK: llvm.aarch64.neon.ld3lane.v1i64.p0i8
+}
+
+int8x8x3_t test_vld3_lane_s8(const void * a1, int8x8x3_t a2) {
+  // CHECK: test_vld3_lane_s8
+  return vld3_lane_s8(a1, a2, 0);
+  // CHECK: llvm.aarch64.neon.ld3lane.v8i8.p0i8
+}
+
+poly8x16x3_t test_vld3q_lane_p8(const void * a1, poly8x16x3_t a2) {
+  // CHECK: test_vld3q_lane_p8
+  return vld3q_lane_p8(a1, a2, 0);
+  // CHECK: llvm.aarch64.neon.ld3lane.v16i8.p0i8
+}
+
+uint8x16x3_t test_vld3q_lane_u8(const void * a1, uint8x16x3_t a2) {
+  // CHECK: test_vld3q_lane_u8
+  return vld3q_lane_u8(a1, a2, 0);
+  // CHECK: llvm.aarch64.neon.ld3lane.v16i8.p0i8
+}
+
+int64x2x4_t test_vld4q_lane_s64(const void * a1, int64x2x4_t a2) {
+  // CHECK: test_vld4q_lane_s64
+  return vld4q_lane_s64(a1, a2, 0);
+  // CHECK: llvm.aarch64.neon.ld4lane.v2i64.p0i8
+}
+
+uint64x2x4_t test_vld4q_lane_u64(const void * a1, uint64x2x4_t a2) {
+  // CHECK: test_vld4q_lane_u64
+  return vld4q_lane_u64(a1, a2, 0);
+  // CHECK: llvm.aarch64.neon.ld4lane.v2i64.p0i8
+}
+
+int64x1x4_t test_vld4_lane_s64(const void * a1, int64x1x4_t a2) {
+  // CHECK: test_vld4_lane_s64
+  return vld4_lane_s64(a1, a2, 0);
+  // CHECK: llvm.aarch64.neon.ld4lane.v1i64.p0i8
+}
+
+uint64x1x4_t test_vld4_lane_u64(const void * a1, uint64x1x4_t a2) {
+  // CHECK: test_vld4_lane_u64
+  return vld4_lane_u64(a1, a2, 0);
+  // CHECK: llvm.aarch64.neon.ld4lane.v1i64.p0i8
+}
+
+int8x8x4_t test_vld4_lane_s8(const void * a1, int8x8x4_t a2) {
+  // CHECK: test_vld4_lane_s8
+  return vld4_lane_s8(a1, a2, 0);
+  // CHECK: llvm.aarch64.neon.ld4lane.v8i8.p0i8
+}
+
+uint8x8x4_t test_vld4_lane_u8(const void * a1, uint8x8x4_t a2) {
+  // CHECK: test_vld4_lane_u8
+  return vld4_lane_u8(a1, a2, 0);
+  // CHECK: llvm.aarch64.neon.ld4lane.v8i8.p0i8
+}
+
+poly8x16x4_t test_vld4q_lane_p8(const void * a1, poly8x16x4_t a2) {
+  // CHECK: test_vld4q_lane_p8
+  return vld4q_lane_p8(a1, a2, 0);
+  // CHECK: llvm.aarch64.neon.ld4lane.v16i8.p0i8
+}
+
+int8x16x4_t test_vld4q_lane_s8(const void * a1, int8x16x4_t a2) {
+  // CHECK: test_vld4q_lane_s8
+  return vld4q_lane_s8(a1, a2, 0);
+  // CHECK: extractvalue {{.*}} 0{{ *$}}
+  // CHECK: extractvalue {{.*}} 1{{ *$}}
+  // CHECK: extractvalue {{.*}} 2{{ *$}}
+  // CHECK: extractvalue {{.*}} 3{{ *$}}
+}
+
+uint8x16x4_t test_vld4q_lane_u8(const void * a1, uint8x16x4_t a2) {
+  // CHECK: test_vld4q_lane_u8
+  return vld4q_lane_u8(a1, a2, 0);
+  // CHECK: llvm.aarch64.neon.ld4lane.v16i8.p0i8
+}
+
diff --git a/test/CodeGen/arm64_vMaxMin.c b/test/CodeGen/arm64_vMaxMin.c
new file mode 100644
index 0000000..5f77b6c
--- /dev/null
+++ b/test/CodeGen/arm64_vMaxMin.c
@@ -0,0 +1,207 @@
+// RUN: %clang_cc1 -O1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -S -o - -emit-llvm %s | FileCheck %s
+// RUN: %clang_cc1 -O1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -S -o - %s | FileCheck -check-prefix=CHECK-CODEGEN %s
+// REQUIRES: aarch64-registered-target
+// Test ARM64 SIMD max/min intrinsics
+
+#include <arm_neon.h>
+
+// Test a represntative sample of 8 and 16, signed and unsigned, 64 and 128 bit reduction
+int8_t test_vmaxv_s8(int8x8_t a1) {
+  // CHECK: test_vmaxv_s8
+  return vmaxv_s8(a1);
+  // CHECK @llvm.aarch64.neon.smaxv.i32.v8i8
+}
+
+uint16_t test_vminvq_u16(uint16x8_t a1) {
+  // CHECK: test_vminvq_u16
+  return vminvq_u16(a1);
+  // CHECK llvm.aarch64.neon.uminv.i16.v8i16
+}
+
+// Test a represntative sample of 8 and 16, signed and unsigned, 64 and 128 bit pairwise
+uint8x8_t test_vmin_u8(uint8x8_t a1, uint8x8_t a2) {
+  // CHECK: test_vmin_u8
+  return vmin_u8(a1, a2);
+  // CHECK llvm.aarch64.neon.umin.v8i8
+}
+
+uint8x16_t test_vminq_u8(uint8x16_t a1, uint8x16_t a2) {
+  // CHECK: test_vminq_u8
+  return vminq_u8(a1, a2);
+  // CHECK llvm.aarch64.neon.umin.v16i8
+}
+
+int16x8_t test_vmaxq_s16(int16x8_t a1, int16x8_t a2) {
+  // CHECK: test_vmaxq_s16
+  return vmaxq_s16(a1, a2);
+  // CHECK llvm.aarch64.neon.smax.v8i16
+}
+
+// Test the more complicated cases of [suf]32 and f64
+float64x2_t test_vmaxq_f64(float64x2_t a1, float64x2_t a2) {
+  // CHECK: test_vmaxq_f64
+  return vmaxq_f64(a1, a2);
+  // CHECK llvm.aarch64.neon.fmax.v2f64
+}
+
+float32x4_t test_vmaxq_f32(float32x4_t a1, float32x4_t a2) {
+  // CHECK: test_vmaxq_f32
+  return vmaxq_f32(a1, a2);
+  // CHECK llvm.aarch64.neon.fmax.v4f32
+}
+
+float64x2_t test_vminq_f64(float64x2_t a1, float64x2_t a2) {
+  // CHECK: test_vminq_f64
+  return vminq_f64(a1, a2);
+  // CHECK llvm.aarch64.neon.fmin.v2f64
+}
+
+float32x2_t test_vmax_f32(float32x2_t a1, float32x2_t a2) {
+  // CHECK: test_vmax_f32
+  return vmax_f32(a1, a2);
+  // CHECK llvm.aarch64.neon.fmax.v2f32
+}
+
+int32x2_t test_vmax_s32(int32x2_t a1, int32x2_t a2) {
+  // CHECK: test_vmax_s32
+  return vmax_s32(a1, a2);
+  // CHECK llvm.aarch64.neon.smax.v2i32
+}
+
+uint32x2_t test_vmin_u32(uint32x2_t a1, uint32x2_t a2) {
+  // CHECK: test_vmin_u32
+  return vmin_u32(a1, a2);
+  // CHECK llvm.aarch64.neon.umin.v2i32
+}
+
+float32_t test_vmaxnmv_f32(float32x2_t a1) {
+  // CHECK: test_vmaxnmv_f32
+  return vmaxnmv_f32(a1);
+  // CHECK: llvm.aarch64.neon.fmaxnmv.f32.v2f32
+  // CHECK-NEXT: ret
+}
+
+// this doesn't translate into a valid instruction, regardless of what the
+// ARM doc says.
+#if 0
+float64_t test_vmaxnmvq_f64(float64x2_t a1) {
+  // CHECK@ test_vmaxnmvq_f64
+  return vmaxnmvq_f64(a1);
+  // CHECK@ llvm.aarch64.neon.saddlv.i64.v2i32
+  // CHECK-NEXT@ ret
+}
+#endif
+
+float32_t test_vmaxnmvq_f32(float32x4_t a1) {
+  // CHECK: test_vmaxnmvq_f32
+  return vmaxnmvq_f32(a1);
+  // CHECK: llvm.aarch64.neon.fmaxnmv.f32.v4f32
+  // CHECK-NEXT: ret
+}
+
+float32_t test_vmaxv_f32(float32x2_t a1) {
+  // CHECK: test_vmaxv_f32
+  return vmaxv_f32(a1);
+  // CHECK: llvm.aarch64.neon.fmaxv.f32.v2f32
+  // FIXME check that the 2nd and 3rd arguments are the same V register below
+  // CHECK-CODEGEN: fmaxp.2s
+  // CHECK-NEXT: ret
+}
+
+int32_t test_vmaxv_s32(int32x2_t a1) {
+  // CHECK: test_vmaxv_s32
+  return vmaxv_s32(a1);
+  // CHECK: llvm.aarch64.neon.smaxv.i32.v2i32
+  // FIXME check that the 2nd and 3rd arguments are the same V register below
+  // CHECK-CODEGEN: smaxp.2s
+  // CHECK-NEXT: ret
+}
+
+uint32_t test_vmaxv_u32(uint32x2_t a1) {
+  // CHECK: test_vmaxv_u32
+  return vmaxv_u32(a1);
+  // CHECK: llvm.aarch64.neon.umaxv.i32.v2i32
+  // FIXME check that the 2nd and 3rd arguments are the same V register below
+  // CHECK-CODEGEN: umaxp.2s
+  // CHECK-NEXT: ret
+}
+
+// FIXME punt on this for now; don't forget to fix CHECKs
+#if 0
+float64_t test_vmaxvq_f64(float64x2_t a1) {
+  // CHECK@ test_vmaxvq_f64
+  return vmaxvq_f64(a1);
+  // CHECK@ llvm.aarch64.neon.fmaxv.i64.v2f64
+  // CHECK-NEXT@ ret
+}
+#endif
+
+float32_t test_vmaxvq_f32(float32x4_t a1) {
+  // CHECK: test_vmaxvq_f32
+  return vmaxvq_f32(a1);
+  // CHECK: llvm.aarch64.neon.fmaxv.f32.v4f32
+  // CHECK-NEXT: ret
+}
+
+float32_t test_vminnmv_f32(float32x2_t a1) {
+  // CHECK: test_vminnmv_f32
+  return vminnmv_f32(a1);
+  // CHECK: llvm.aarch64.neon.fminnmv.f32.v2f32
+  // CHECK-NEXT: ret
+}
+
+float32_t test_vminvq_f32(float32x4_t a1) {
+  // CHECK: test_vminvq_f32
+  return vminvq_f32(a1);
+  // CHECK: llvm.aarch64.neon.fminv.f32.v4f32
+  // CHECK-NEXT: ret
+}
+
+// this doesn't translate into a valid instruction, regardless of what the ARM
+// doc says.
+#if 0
+float64_t test_vminnmvq_f64(float64x2_t a1) {
+  // CHECK@ test_vminnmvq_f64
+  return vminnmvq_f64(a1);
+  // CHECK@ llvm.aarch64.neon.saddlv.i64.v2i32
+  // CHECK-NEXT@ ret
+}
+#endif
+
+float32_t test_vminnmvq_f32(float32x4_t a1) {
+  // CHECK: test_vminnmvq_f32
+  return vminnmvq_f32(a1);
+  // CHECK: llvm.aarch64.neon.fminnmv.f32.v4f32
+  // CHECK-NEXT: ret
+}
+
+float32_t test_vminv_f32(float32x2_t a1) {
+  // CHECK: test_vminv_f32
+  return vminv_f32(a1);
+  // CHECK: llvm.aarch64.neon.fminv.f32.v2f32
+  // CHECK-NEXT: ret
+}
+
+int32_t test_vminv_s32(int32x2_t a1) {
+  // CHECK: test_vminv_s32
+  return vminv_s32(a1);
+  // CHECK: llvm.aarch64.neon.sminv.i32.v2i32
+  // CHECK-CODEGEN: sminp.2s
+  // CHECK-NEXT: ret
+}
+
+uint32_t test_vminv_u32(uint32x2_t a1) {
+  // CHECK: test_vminv_u32
+  return vminv_u32(a1);
+  // CHECK: llvm.aarch64.neon.fminv.f32.v2f32
+}
+
+// FIXME punt on this for now; don't forget to fix CHECKs
+#if 0
+float64_t test_vminvq_f64(float64x2_t a1) {
+  // CHECK@ test_vminvq_f64
+  return vminvq_f64(a1);
+  // CHECK@ llvm.aarch64.neon.saddlv.i64.v2i32
+  // CHECK-NEXT@ ret
+}
+#endif
diff --git a/test/CodeGen/arm64_vadd.c b/test/CodeGen/arm64_vadd.c
new file mode 100644
index 0000000..7b2913f
--- /dev/null
+++ b/test/CodeGen/arm64_vadd.c
@@ -0,0 +1,102 @@
+// RUN: %clang_cc1 -O1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -S -o - -emit-llvm %s | FileCheck %s
+// Test ARM64 SIMD add intrinsics
+
+#include <arm_neon.h>
+int64_t test_vaddlv_s32(int32x2_t a1) {
+  // CHECK: test_vaddlv_s32
+  return vaddlv_s32(a1);
+  // CHECK: llvm.aarch64.neon.saddlv.i64.v2i32
+  // CHECK-NEXT: ret
+}
+
+uint64_t test_vaddlv_u32(uint32x2_t a1) {
+  // CHECK: test_vaddlv_u32
+  return vaddlv_u32(a1);
+  // CHECK: llvm.aarch64.neon.uaddlv.i64.v2i32
+  // CHECK-NEXT: ret
+}
+
+int8_t test_vaddv_s8(int8x8_t a1) {
+  // CHECK: test_vaddv_s8
+  return vaddv_s8(a1);
+  // CHECK: llvm.aarch64.neon.saddv.i32.v8i8
+  // don't check for return here (there's a trunc?)
+}
+
+int16_t test_vaddv_s16(int16x4_t a1) {
+  // CHECK: test_vaddv_s16
+  return vaddv_s16(a1);
+  // CHECK: llvm.aarch64.neon.saddv.i32.v4i16
+  // don't check for return here (there's a trunc?)
+}
+
+int32_t test_vaddv_s32(int32x2_t a1) {
+  // CHECK: test_vaddv_s32
+  return vaddv_s32(a1);
+  // CHECK: llvm.aarch64.neon.saddv.i32.v2i32
+  // CHECK-NEXT: ret
+}
+
+uint8_t test_vaddv_u8(int8x8_t a1) {
+  // CHECK: test_vaddv_u8
+  return vaddv_u8(a1);
+  // CHECK: llvm.aarch64.neon.uaddv.i32.v8i8
+  // don't check for return here (there's a trunc?)
+}
+
+uint16_t test_vaddv_u16(int16x4_t a1) {
+  // CHECK: test_vaddv_u16
+  return vaddv_u16(a1);
+  // CHECK: llvm.aarch64.neon.uaddv.i32.v4i16
+  // don't check for return here (there's a trunc?)
+}
+
+uint32_t test_vaddv_u32(int32x2_t a1) {
+  // CHECK: test_vaddv_u32
+  return vaddv_u32(a1);
+  // CHECK: llvm.aarch64.neon.uaddv.i32.v2i32
+  // CHECK-NEXT: ret
+}
+
+int8_t test_vaddvq_s8(int8x16_t a1) {
+  // CHECK: test_vaddvq_s8
+  return vaddvq_s8(a1);
+  // CHECK: llvm.aarch64.neon.saddv.i32.v16i8
+  // don't check for return here (there's a trunc?)
+}
+
+int16_t test_vaddvq_s16(int16x8_t a1) {
+  // CHECK: test_vaddvq_s16
+  return vaddvq_s16(a1);
+  // CHECK: llvm.aarch64.neon.saddv.i32.v8i16
+  // don't check for return here (there's a trunc?)
+}
+
+int32_t test_vaddvq_s32(int32x4_t a1) {
+  // CHECK: test_vaddvq_s32
+  return vaddvq_s32(a1);
+  // CHECK: llvm.aarch64.neon.saddv.i32.v4i32
+  // CHECK-NEXT: ret
+}
+
+uint8_t test_vaddvq_u8(int8x16_t a1) {
+  // CHECK: test_vaddvq_u8
+  return vaddvq_u8(a1);
+  // CHECK: llvm.aarch64.neon.uaddv.i32.v16i8
+  // don't check for return here (there's a trunc?)
+}
+
+uint16_t test_vaddvq_u16(int16x8_t a1) {
+  // CHECK: test_vaddvq_u16
+  return vaddvq_u16(a1);
+  // CHECK: llvm.aarch64.neon.uaddv.i32.v8i16
+  // don't check for return here (there's a trunc?)
+}
+
+uint32_t test_vaddvq_u32(int32x4_t a1) {
+  // CHECK: test_vaddvq_u32
+  return vaddvq_u32(a1);
+  // CHECK: llvm.aarch64.neon.uaddv.i32.v4i32
+  // CHECK-NEXT: ret
+}
+
diff --git a/test/CodeGen/arm64_vca.c b/test/CodeGen/arm64_vca.c
new file mode 100644
index 0000000..00cc283
--- /dev/null
+++ b/test/CodeGen/arm64_vca.c
@@ -0,0 +1,59 @@
+// RUN: %clang_cc1 -O1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -S -o - -emit-llvm %s | FileCheck %s
+// Test ARM64 vector compare absolute intrinsics
+
+#include <arm_neon.h>
+
+uint32x2_t test_vcale_f32(float32x2_t a1, float32x2_t a2) {
+  // CHECK: test_vcale_f32
+  return vcale_f32(a1, a2);
+  // CHECK: llvm.aarch64.neon.facge.v2i32.v2f32
+  // no check for ret here, as there is a bitcast
+}
+
+uint32x4_t test_vcaleq_f32(float32x4_t a1, float32x4_t a2) {
+  // CHECK: test_vcaleq_f32
+  return vcaleq_f32(a1, a2);
+  // CHECK: llvm.aarch64.neon.facge.v4i32.v4f32{{.*a2,.*a1}}
+  // no check for ret here, as there is a bitcast
+}
+
+uint32x2_t test_vcalt_f32(float32x2_t a1, float32x2_t a2) {
+  // CHECK: test_vcalt_f32
+  return vcalt_f32(a1, a2);
+  // CHECK: llvm.aarch64.neon.facgt.v2i32.v2f32{{.*a2,.*a1}}
+  // no check for ret here, as there is a bitcast
+}
+
+uint32x4_t test_vcaltq_f32(float32x4_t a1, float32x4_t a2) {
+  // CHECK: test_vcaltq_f32
+  return vcaltq_f32(a1, a2);
+  // CHECK: llvm.aarch64.neon.facgt.v4i32.v4f32{{.*a2,.*a1}}
+}
+
+uint64x2_t test_vcagtq_f64(float64x2_t a1, float64x2_t a2) {
+  // CHECK: test_vcagtq_f64
+  return vcagtq_f64(a1, a2);
+  // CHECK: llvm.aarch64.neon.facgt.v2i64.v2f64{{.*a1,.*a2}}
+  // no check for ret here, as there is a bitcast
+}
+
+uint64x2_t test_vcaltq_f64(float64x2_t a1, float64x2_t a2) {
+  // CHECK: test_vcaltq_f64
+  return vcaltq_f64(a1, a2);
+  // CHECK: llvm.aarch64.neon.facgt.v2i64.v2f64{{.*a2,.*a1}}
+  // no check for ret here, as there is a bitcast
+}
+
+uint64x2_t test_vcageq_f64(float64x2_t a1, float64x2_t a2) {
+  // CHECK: test_vcageq_f64
+  return vcageq_f64(a1, a2);
+  // CHECK: llvm.aarch64.neon.facge.v2i64.v2f64{{.*a1,.*a2}}
+  // no check for ret here, as there is a bitcast
+}
+
+uint64x2_t test_vcaleq_f64(float64x2_t a1, float64x2_t a2) {
+  // CHECK: test_vcaleq_f64
+  return vcaleq_f64(a1, a2);
+  // CHECK: llvm.aarch64.neon.facge.v2i64.v2f64{{.*a2,.*a1}}
+  // no check for ret here, as there is a bitcast
+}
diff --git a/test/CodeGen/arm64_vcopy.c b/test/CodeGen/arm64_vcopy.c
new file mode 100644
index 0000000..990d4f6
--- /dev/null
+++ b/test/CodeGen/arm64_vcopy.c
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -O1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -S -o - -emit-llvm %s | FileCheck %s
+
+// Test ARM64 SIMD copy vector element to vector element: vcopyq_lane*
+
+#include <arm_neon.h>
+
+int8x16_t test_vcopyq_laneq_s8(int8x16_t a1, int8x16_t a2) {
+  // CHECK-LABEL: test_vcopyq_laneq_s8
+  return vcopyq_laneq_s8(a1, (int64_t) 3, a2, (int64_t) 13);
+  // CHECK: shufflevector <16 x i8> %a1, <16 x i8> %a2, <16 x i32> <i32 0, i32 1, i32 2, i32 29, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
+}
+
+uint8x16_t test_vcopyq_laneq_u8(uint8x16_t a1, uint8x16_t a2) {
+  // CHECK-LABEL: test_vcopyq_laneq_u8
+  return vcopyq_laneq_u8(a1, (int64_t) 3, a2, (int64_t) 13);
+  // CHECK: shufflevector <16 x i8> %a1, <16 x i8> %a2, <16 x i32> <i32 0, i32 1, i32 2, i32 29, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
+
+}
+
+int16x8_t test_vcopyq_laneq_s16(int16x8_t a1, int16x8_t a2) {
+  // CHECK-LABEL: test_vcopyq_laneq_s16
+  return vcopyq_laneq_s16(a1, (int64_t) 3, a2, (int64_t) 7);
+  // CHECK: shufflevector <8 x i16> %a1, <8 x i16> %a2, <8 x i32> <i32 0, i32 1, i32 2, i32 15, i32 4, i32 5, i32 6, i32 7>
+
+}
+
+uint16x8_t test_vcopyq_laneq_u16(uint16x8_t a1, uint16x8_t a2) {
+  // CHECK-LABEL: test_vcopyq_laneq_u16
+  return vcopyq_laneq_u16(a1, (int64_t) 3, a2, (int64_t) 7);
+  // CHECK: shufflevector <8 x i16> %a1, <8 x i16> %a2, <8 x i32> <i32 0, i32 1, i32 2, i32 15, i32 4, i32 5, i32 6, i32 7>
+
+}
+
+int32x4_t test_vcopyq_laneq_s32(int32x4_t a1, int32x4_t a2) {
+  // CHECK-LABEL: test_vcopyq_laneq_s32
+  return vcopyq_laneq_s32(a1, (int64_t) 3, a2, (int64_t) 3);
+  // CHECK: shufflevector <4 x i32> %a1, <4 x i32> %a2, <4 x i32> <i32 0, i32 1, i32 2, i32 7>
+}
+
+uint32x4_t test_vcopyq_laneq_u32(uint32x4_t a1, uint32x4_t a2) {
+  // CHECK-LABEL: test_vcopyq_laneq_u32
+  return vcopyq_laneq_u32(a1, (int64_t) 3, a2, (int64_t) 3);
+  // CHECK: shufflevector <4 x i32> %a1, <4 x i32> %a2, <4 x i32> <i32 0, i32 1, i32 2, i32 7>
+}
+
+int64x2_t test_vcopyq_laneq_s64(int64x2_t a1, int64x2_t a2) {
+  // CHECK-LABEL: test_vcopyq_laneq_s64
+  return vcopyq_laneq_s64(a1, (int64_t) 0, a2, (int64_t) 1);
+  // CHECK: shufflevector <2 x i64> %a1, <2 x i64> %a2, <2 x i32> <i32 3, i32 1>
+}
+
+uint64x2_t test_vcopyq_laneq_u64(uint64x2_t a1, uint64x2_t a2) {
+  // CHECK-LABEL: test_vcopyq_laneq_u64
+  return vcopyq_laneq_u64(a1, (int64_t) 0, a2, (int64_t) 1);
+  // CHECK: shufflevector <2 x i64> %a1, <2 x i64> %a2, <2 x i32> <i32 3, i32 1>
+}
+
+float32x4_t test_vcopyq_laneq_f32(float32x4_t a1, float32x4_t a2) {
+  // CHECK-LABEL: test_vcopyq_laneq_f32
+  return vcopyq_laneq_f32(a1, 0, a2, 3);
+  // CHECK: shufflevector <4 x float> %a1, <4 x float> %a2, <4 x i32> <i32 7, i32 1, i32 2, i32 3>
+}
+
+float64x2_t test_vcopyq_laneq_f64(float64x2_t a1, float64x2_t a2) {
+  // CHECK-LABEL: test_vcopyq_laneq_f64
+  return vcopyq_laneq_f64(a1, 0, a2, 1);
+  // CHECK: shufflevector <2 x double> %a1, <2 x double> %a2, <2 x i32> <i32 3, i32 1>
+}
+
diff --git a/test/CodeGen/arm64_vcreate.c b/test/CodeGen/arm64_vcreate.c
new file mode 100644
index 0000000..b974752
--- /dev/null
+++ b/test/CodeGen/arm64_vcreate.c
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -O1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -S -o - -emit-llvm %s | FileCheck %s
+// Test ARM64 SIMD vcreate intrinsics
+
+/*#include <arm_neon.h>*/
+#include <arm_neon.h>
+
+float32x2_t test_vcreate_f32(uint64_t a1) {
+  // CHECK: test_vcreate_f32
+  return vcreate_f32(a1);
+  // CHECK: bitcast {{.*}} to <2 x float>
+  // CHECK-NEXT: ret
+}
+
+// FIXME enable when scalar_to_vector in backend is fixed.  Also, change
+// CHECK@ to CHECK<colon> and CHECK-NEXT@ to CHECK-NEXT<colon>
+/*
+float64x1_t test_vcreate_f64(uint64_t a1) {
+  // CHECK@ test_vcreate_f64
+  return vcreate_f64(a1);
+  // CHECK@ llvm.aarch64.neon.saddlv.i64.v2i32
+  // CHECK-NEXT@ ret
+}
+*/
diff --git a/test/CodeGen/arm64_vcvtfp.c b/test/CodeGen/arm64_vcvtfp.c
new file mode 100644
index 0000000..e3dca81
--- /dev/null
+++ b/test/CodeGen/arm64_vcvtfp.c
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -O1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -S -o - -emit-llvm %s | FileCheck %s
+
+#include <arm_neon.h>
+
+float64x2_t test_vcvt_f64_f32(float32x2_t x) {
+  // CHECK-LABEL: test_vcvt_f64_f32
+  return vcvt_f64_f32(x);
+  // CHECK: fpext <2 x float> {{%.*}} to <2 x double>
+  // CHECK-NEXT: ret
+}
+
+float64x2_t test_vcvt_high_f64_f32(float32x4_t x) {
+  // CHECK-LABEL: test_vcvt_high_f64_f32
+  return vcvt_high_f64_f32(x);
+  // CHECK: [[HIGH:%.*]] = shufflevector <4 x float> {{%.*}}, <4 x float> undef, <2 x i32> <i32 2, i32 3>
+  // CHECK-NEXT: fpext <2 x float> [[HIGH]] to <2 x double>
+  // CHECK-NEXT: ret
+}
+
+float32x2_t test_vcvt_f32_f64(float64x2_t v) {
+  // CHECK: test_vcvt_f32_f64
+  return vcvt_f32_f64(v);
+  // CHECK: fptrunc <2 x double> {{%.*}} to <2 x float>
+  // CHECK-NEXT: ret
+}
+
+float32x4_t test_vcvt_high_f32_f64(float32x2_t x, float64x2_t v) {
+  // CHECK: test_vcvt_high_f32_f64
+  return vcvt_high_f32_f64(x, v);
+  // CHECK: [[TRUNC:%.*]] = fptrunc <2 x double> {{.*}} to <2 x float>
+  // CHECK-NEXT: shufflevector <2 x float> {{.*}}, <2 x float> [[TRUNC]], <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+  // CHECK-NEXT: ret
+}
+
+float32x2_t test_vcvtx_f32_f64(float64x2_t v) {
+  // CHECK: test_vcvtx_f32_f64
+  return vcvtx_f32_f64(v);
+  // CHECK: llvm.aarch64.neon.fcvtxn.v2f32.v2f64
+  // CHECK-NEXT: ret
+}
+
+float32x4_t test_vcvtx_high_f32_f64(float32x2_t x, float64x2_t v) {
+  // CHECK: test_vcvtx_high_f32_f64
+  return vcvtx_high_f32_f64(x, v);
+  // CHECK: llvm.aarch64.neon.fcvtxn.v2f32.v2f64
+  // CHECK: shufflevector
+  // CHECK: ret
+}
diff --git a/test/CodeGen/arm64_vdup.c b/test/CodeGen/arm64_vdup.c
new file mode 100644
index 0000000..8419828
--- /dev/null
+++ b/test/CodeGen/arm64_vdup.c
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -S -o - -emit-llvm %s | FileCheck %s
+// Test ARM64 SIMD duplicate lane and n intrinsics
+
+#include <arm_neon.h>
+
+void test_vdup_lane_s64(int64x1_t a1) {
+  // CHECK-LABEL: test_vdup_lane_s64
+  vdup_lane_s64(a1, 0);
+  // CHECK: shufflevector
+}
+
+void test_vdup_lane_u64(uint64x1_t a1) {
+  // CHECK-LABEL: test_vdup_lane_u64
+  vdup_lane_u64(a1, 0);
+  // CHECK: shufflevector
+}
+
+// uncomment out the following code once scalar_to_vector in the backend
+// works (for 64 bit?).  Change the "CHECK@" to "CHECK<colon>"
+/*
+float64x1_t test_vdup_n_f64(float64_t a1) {
+  // CHECK-LABEL@ test_vdup_n_f64
+  return vdup_n_f64(a1);
+  // match that an element is inserted into part 0
+  // CHECK@ insertelement {{.*, i32 0 *$}}
+}
+*/
+
+float16x8_t test_vdupq_n_f16(float16_t *a1) {
+  // CHECK-LABEL: test_vdupq_n_f16
+  return vdupq_n_f16(*a1);
+  // match that an element is inserted into parts 0-7.  The backend better
+  // turn that into a single dup intruction
+  // CHECK: insertelement {{.*, i32 0 *$}}
+  // CHECK: insertelement {{.*, i32 1 *$}}
+  // CHECK: insertelement {{.*, i32 2 *$}}
+  // CHECK: insertelement {{.*, i32 3 *$}}
+  // CHECK: insertelement {{.*, i32 4 *$}}
+  // CHECK: insertelement {{.*, i32 5 *$}}
+  // CHECK: insertelement {{.*, i32 6 *$}}
+  // CHECK: insertelement {{.*, i32 7 *$}}
+}
diff --git a/test/CodeGen/arm64_vdupq_n_f64.c b/test/CodeGen/arm64_vdupq_n_f64.c
new file mode 100644
index 0000000..ffba55c
--- /dev/null
+++ b/test/CodeGen/arm64_vdupq_n_f64.c
@@ -0,0 +1,88 @@
+// RUN: %clang_cc1 -O3 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -S -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O3 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -S -o - -emit-llvm %s | \
+// RUN:   FileCheck -check-prefix=CHECK-IR %s
+// REQUIRES: aarch64-registered-target
+
+/// Test vdupq_n_f64 and vmovq_nf64 ARM64 intrinsics
+// <rdar://problem/11778405> ARM64: vdupq_n_f64 and vdupq_lane_f64 intrinsics
+// missing
+
+
+#include <arm_neon.h>
+
+// vdupq_n_f64 -> dup.2d v0, v0[0]
+//
+float64x2_t test_vdupq_n_f64(float64_t w)
+{
+    return vdupq_n_f64(w);
+  // CHECK-LABEL: test_vdupq_n_f64:
+  // CHECK: dup.2d v0, v0[0]
+  // CHECK-NEXT: ret
+}
+
+// might as well test this while we're here
+// vdupq_n_f32 -> dup.4s v0, v0[0]
+float32x4_t test_vdupq_n_f32(float32_t w)
+{
+    return vdupq_n_f32(w);
+  // CHECK-LABEL: test_vdupq_n_f32:
+  // CHECK: dup.4s v0, v0[0]
+  // CHECK-NEXT: ret
+}
+
+// vdupq_lane_f64 -> dup.2d v0, v0[0]
+// this was in <rdar://problem/11778405>, but had already been implemented,
+// test anyway
+float64x2_t test_vdupq_lane_f64(float64x1_t V)
+{
+    return vdupq_lane_f64(V, 0);
+  // CHECK-LABEL: test_vdupq_lane_f64:
+  // CHECK: dup.2d v0, v0[0]
+  // CHECK-NEXT: ret
+}
+
+// vmovq_n_f64 -> dup Vd.2d,X0
+// this wasn't in <rdar://problem/11778405>, but it was between the vdups
+float64x2_t test_vmovq_n_f64(float64_t w)
+{
+  return vmovq_n_f64(w);
+  // CHECK-LABEL: test_vmovq_n_f64:
+  // CHECK: dup.2d v0, v0[0]
+  // CHECK-NEXT: ret
+}
+
+float16x4_t test_vmov_n_f16(float16_t *a1)
+{
+  // CHECK-IR-LABEL: test_vmov_n_f16
+  return vmov_n_f16(*a1);
+  // CHECK-IR: insertelement {{.*}} i32 0{{ *$}}
+  // CHECK-IR: insertelement {{.*}} i32 1{{ *$}}
+  // CHECK-IR: insertelement {{.*}} i32 2{{ *$}}
+  // CHECK-IR: insertelement {{.*}} i32 3{{ *$}}
+}
+
+// Disable until scalar problem in backend is fixed. Change CHECK-IR@ to
+// CHECK-IR<colon>
+/*
+float64x1_t test_vmov_n_f64(float64_t a1)
+{
+  // CHECK-IR@ test_vmov_n_f64
+  return vmov_n_f64(a1);
+  // CHECK-IR@ insertelement {{.*}} i32 0{{ *$}}
+}
+*/
+
+float16x8_t test_vmovq_n_f16(float16_t *a1)
+{
+  // CHECK-IR-LABEL: test_vmovq_n_f16
+  return vmovq_n_f16(*a1);
+  // CHECK-IR: insertelement {{.*}} i32 0{{ *$}}
+  // CHECK-IR: insertelement {{.*}} i32 1{{ *$}}
+  // CHECK-IR: insertelement {{.*}} i32 2{{ *$}}
+  // CHECK-IR: insertelement {{.*}} i32 3{{ *$}}
+  // CHECK-IR: insertelement {{.*}} i32 4{{ *$}}
+  // CHECK-IR: insertelement {{.*}} i32 5{{ *$}}
+  // CHECK-IR: insertelement {{.*}} i32 6{{ *$}}
+  // CHECK-IR: insertelement {{.*}} i32 7{{ *$}}
+}
+
diff --git a/test/CodeGen/arm64_vecCmpBr.c b/test/CodeGen/arm64_vecCmpBr.c
new file mode 100644
index 0000000..3ae7433
--- /dev/null
+++ b/test/CodeGen/arm64_vecCmpBr.c
@@ -0,0 +1,111 @@
+// RUN: %clang_cc1 -O3 -triple arm64-apple-ios7 -target-feature +neon -S -ffreestanding %s -o - -target-cpu cyclone | FileCheck %s
+// REQUIRES: aarch64-registered-target
+// test code generation for <rdar://problem/11487757>
+#include <arm_neon.h>
+
+unsigned bar();
+
+// Branch if any lane of V0 is zero; 64 bit => !min
+unsigned anyZero64(uint16x4_t a) {
+// CHECK: anyZero64:
+// CHECK: uminv.8b b[[REGNO1:[0-9]+]], v0
+// CHECK-NEXT: fmov w[[REGNO2:[0-9]+]], s[[REGNO1]]
+// CHECK-NEXT: cbz w[[REGNO2]], [[LABEL:[.A-Z_0-9]+]]
+// CHECK: [[LABEL]]:
+// CHECK-NEXT: b {{_bar|bar}}
+  if (!vminv_u8(a))
+    return bar();
+  return 0;
+}
+
+// Branch if any lane of V0 is zero; 128 bit => !min
+unsigned anyZero128(uint16x8_t a) {
+// CHECK: anyZero128:
+// CHECK: uminv.16b b[[REGNO1:[0-9]+]], v0
+// CHECK-NEXT: fmov w[[REGNO2:[0-9]+]], s[[REGNO1]]
+// CHECK-NEXT: cbz w[[REGNO2]], [[LABEL:[.A-Z_0-9]+]]
+// CHECK: [[LABEL]]:
+// CHECK-NEXT: b {{_bar|bar}}
+  if (!vminvq_u8(a))
+    return bar();
+  return 0;
+}
+
+// Branch if any lane of V0 is non-zero; 64 bit => max
+unsigned anyNonZero64(uint16x4_t a) {
+// CHECK: anyNonZero64:
+// CHECK: umaxv.8b b[[REGNO1:[0-9]+]], v0
+// CHECK-NEXT: fmov w[[REGNO2:[0-9]+]], s[[REGNO1]]
+// CHECK-NEXT: cbz w[[REGNO2]], [[LABEL:[.A-Z_0-9]+]]
+// CHECK: [[LABEL]]:
+// CHECK-NEXT: movz w0, #0
+  if (vmaxv_u8(a))
+    return bar();
+  return 0;
+}
+
+// Branch if any lane of V0 is non-zero; 128 bit => max
+unsigned anyNonZero128(uint16x8_t a) {
+// CHECK: anyNonZero128:
+// CHECK: umaxv.16b b[[REGNO1:[0-9]+]], v0
+// CHECK-NEXT: fmov w[[REGNO2:[0-9]+]], s[[REGNO1]]
+// CHECK-NEXT: cbz w[[REGNO2]], [[LABEL:[.A-Z_0-9]+]]
+// CHECK: [[LABEL]]:
+// CHECK-NEXT: movz w0, #0
+  if (vmaxvq_u8(a))
+    return bar();
+  return 0;
+}
+
+// Branch if all lanes of V0 are zero; 64 bit => !max
+unsigned allZero64(uint16x4_t a) {
+// CHECK: allZero64:
+// CHECK: umaxv.8b b[[REGNO1:[0-9]+]], v0
+// CHECK-NEXT: fmov w[[REGNO2:[0-9]+]], s[[REGNO1]]
+// CHECK-NEXT: cbz w[[REGNO2]], [[LABEL:[.A-Z_0-9]+]]
+// CHECK: [[LABEL]]:
+// CHECK-NEXT: b {{_bar|bar}}
+  if (!vmaxv_u8(a))
+    return bar();
+  return 0;
+}
+
+// Branch if all lanes of V0 are zero; 128 bit => !max
+unsigned allZero128(uint16x8_t a) {
+// CHECK: allZero128:
+// CHECK: umaxv.16b b[[REGNO1:[0-9]+]], v0
+// CHECK-NEXT: fmov w[[REGNO2:[0-9]+]], s[[REGNO1]]
+// CHECK-NEXT: cbz w[[REGNO2]], [[LABEL:[.A-Z_0-9]+]]
+// CHECK: [[LABEL]]:
+// CHECK-NEXT: b {{_bar|bar}}
+  if (!vmaxvq_u8(a))
+    return bar();
+  return 0;
+}
+
+// Branch if all lanes of V0 are non-zero; 64 bit => min
+unsigned allNonZero64(uint16x4_t a) {
+// CHECK: allNonZero64:
+// CHECK: uminv.8b b[[REGNO1:[0-9]+]], v0
+// CHECK-NEXT: fmov w[[REGNO2:[0-9]+]], s[[REGNO1]]
+// CHECK-NEXT: cbz w[[REGNO2]], [[LABEL:[.A-Z_0-9]+]]
+// CHECK: [[LABEL]]:
+// CHECK-NEXT: movz w0, #0
+  if (vminv_u8(a))
+    return bar();
+  return 0;
+}
+
+// Branch if all lanes of V0 are non-zero; 128 bit => min
+unsigned allNonZero128(uint16x8_t a) {
+// CHECK: allNonZero128:
+// CHECK: uminv.16b b[[REGNO1:[0-9]+]], v0
+// CHECK-NEXT: fmov w[[REGNO2:[0-9]+]], s[[REGNO1]]
+// CHECK-NEXT: cbz w[[REGNO2]], [[LABEL:[.A-Z_0-9]+]]
+// CHECK: [[LABEL]]:
+// CHECK-NEXT: movz w0, #0
+  if (vminvq_u8(a))
+    return bar();
+  return 0;
+}
+
diff --git a/test/CodeGen/arm64_vext.c b/test/CodeGen/arm64_vext.c
new file mode 100644
index 0000000..6c3fe73
--- /dev/null
+++ b/test/CodeGen/arm64_vext.c
@@ -0,0 +1,239 @@
+// RUN: %clang_cc1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -S -o - -emit-llvm %s | FileCheck %s
+
+// Test ARM64 extract intrinsics
+// can use as back end test by adding a run line with
+// -check-prefix=CHECK-CODEGEN on the FileCheck
+
+#include <arm_neon.h>
+
+void test_vext_s8()
+{
+  // CHECK: test_vext_s8
+  int8x8_t xS8x8;
+  xS8x8 = vext_s8(xS8x8, xS8x8, 1);
+  // CHECK: shufflevector
+  // CHECK-CODEGEN: test_vext_s8:
+  // CHECK-CODEGEN: {{ext.8.*#1}}
+}
+
+void test_vext_u8()
+{
+  // CHECK: test_vext_u8
+  uint8x8_t xU8x8;
+  xU8x8 = vext_u8(xU8x8, xU8x8, 2);
+  // CHECK: shufflevector
+  // CHECK-CODEGEN: test_vext_u8:
+  // CHECK-CODEGEN: {{ext.8.*#2}}
+}
+
+void test_vext_p8()
+{
+  // CHECK: test_vext_p8
+  poly8x8_t xP8x8;
+  xP8x8 = vext_p8(xP8x8, xP8x8, 3);
+  // CHECK: shufflevector
+  // CHECK-CODEGEN: test_vext_p8:
+  // CHECK-CODEGEN: {{ext.8.*#3}}
+}
+
+void test_vext_s16()
+{
+  // CHECK: test_vext_s16
+  int16x4_t xS16x4;
+  xS16x4 = vext_s16(xS16x4, xS16x4, 1);
+  // CHECK: shufflevector
+  // CHECK-CODEGEN: test_vext_s16:
+  // CHECK-CODEGEN: {{ext.8.*#2}}
+}
+
+void test_vext_u16()
+{
+  // CHECK: test_vext_u16
+  uint16x4_t xU16x4;
+  xU16x4 = vext_u16(xU16x4, xU16x4, 2);
+  // CHECK: shufflevector
+  // CHECK-CODEGEN: test_vext_u16:
+  // CHECK-CODEGEN: {{ext.8.*#4}}
+}
+
+void test_vext_p16()
+{
+  // CHECK: test_vext_p16
+  poly16x4_t xP16x4;
+  xP16x4 = vext_p16(xP16x4, xP16x4, 3);
+  // CHECK: shufflevector
+  // CHECK-CODEGEN: test_vext_p16:
+  // CHECK-CODEGEN: {{ext.8.*#6}}
+}
+
+void test_vext_s32()
+{
+  // CHECK: test_vext_s32
+  int32x2_t xS32x2;
+  xS32x2 = vext_s32(xS32x2, xS32x2, 1);
+  // CHECK: shufflevector
+  // CHECK-CODEGEN: test_vext_s32:
+  // CHECK-CODEGEN: {{ext.8.*#4}}
+}
+
+void test_vext_u32()
+{
+  // CHECK: test_vext_u32
+  uint32x2_t xU32x2;
+  xU32x2 = vext_u32(xU32x2, xU32x2, 1);
+  // CHECK: shufflevector
+  // CHECK-CODEGEN: test_vext_u32:
+  // CHECK-CODEGEN: {{ext.8.*#4}}
+}
+
+void test_vext_f32()
+{
+  // CHECK: test_vext_f32
+  float32x2_t xF32x2;
+  xF32x2 = vext_f32(xF32x2, xF32x2, 1);
+  // CHECK: shufflevector
+  // CHECK-CODEGEN: test_vext_f32:
+  // CHECK-CODEGEN: {{ext.8.*#4}}
+}
+
+void test_vext_s64()
+{
+  // CHECK: test_vext_s64
+  int64x1_t xS64x1;
+  // FIXME don't use 1 as index or check for now, clang has a bug?
+  xS64x1 = vext_s64(xS64x1, xS64x1, /*1*/0);
+  // CHECK: shufflevector
+  // CHECK-CODEGEN: test_vext_s64:
+  // CHECK_FIXME: {{ext.8.*#0}}
+}
+
+void test_vext_u64()
+{
+  // CHECK: test_vext_u64
+  uint64x1_t xU64x1;
+  // FIXME don't use 1 as index or check for now, clang has a bug?
+  xU64x1 = vext_u64(xU64x1, xU64x1, /*1*/0);
+  // CHECK: shufflevector
+  // CHECK-CODEGEN: test_vext_u64:
+  // CHECK_FIXME: {{ext.8.*#0}}
+}
+
+void test_vextq_s8()
+{
+  // CHECK: test_vextq_s8
+  int8x16_t xS8x16;
+  xS8x16 = vextq_s8(xS8x16, xS8x16, 4);
+  // CHECK: shufflevector
+  // CHECK-CODEGEN: test_vextq_s8:
+  // CHECK-CODEGEN: {{ext.16.*#4}}
+}
+
+void test_vextq_u8()
+{
+  // CHECK: test_vextq_u8
+  uint8x16_t xU8x16;
+  xU8x16 = vextq_u8(xU8x16, xU8x16, 5);
+  // CHECK: shufflevector
+  // CHECK-CODEGEN: test_vextq_u8:
+  // CHECK-CODEGEN: {{ext.16.*#5}}
+}
+
+void test_vextq_p8()
+{
+  // CHECK: test_vextq_p8
+  poly8x16_t xP8x16;
+  xP8x16 = vextq_p8(xP8x16, xP8x16, 6);
+  // CHECK: shufflevector
+  // CHECK-CODEGEN: test_vextq_p8:
+  // CHECK-CODEGEN: {{ext.16.*#6}}
+}
+
+void test_vextq_s16()
+{
+  // CHECK: test_vextq_s16
+  int16x8_t xS16x8;
+  xS16x8 = vextq_s16(xS16x8, xS16x8, 7);
+  // CHECK: shufflevector
+  // CHECK-CODEGEN: test_vextq_s16:
+  // CHECK-CODEGEN: {{ext.16.*#14}}
+}
+
+void test_vextq_u16()
+{
+  // CHECK: test_vextq_u16
+  uint16x8_t xU16x8;
+  xU16x8 = vextq_u16(xU16x8, xU16x8, 4);
+  // CHECK: shufflevector
+  // CHECK-CODEGEN: test_vextq_u16:
+  // CHECK-CODEGEN: {{ext.16.*#8}}
+}
+
+void test_vextq_p16()
+{
+  // CHECK: test_vextq_p16
+  poly16x8_t xP16x8;
+  xP16x8 = vextq_p16(xP16x8, xP16x8, 5);
+  // CHECK: shufflevector
+  // CHECK-CODEGEN: test_vextq_p16:
+  // CHECK-CODEGEN: {{ext.16.*#10}}
+}
+
+void test_vextq_s32()
+{
+  // CHECK: test_vextq_s32
+  int32x4_t xS32x4;
+  xS32x4 = vextq_s32(xS32x4, xS32x4, 1);
+  // CHECK: shufflevector
+  // CHECK-CODEGEN: test_vextq_s32:
+  // CHECK-CODEGEN: {{ext.16.*#4}}
+}
+
+void test_vextq_u32()
+{
+  // CHECK: test_vextq_u32
+  uint32x4_t xU32x4;
+  xU32x4 = vextq_u32(xU32x4, xU32x4, 2);
+  // CHECK: shufflevector
+  // CHECK-CODEGEN: test_vextq_u32:
+  // CHECK-CODEGEN: {{ext.16.*#8}}
+}
+
+void test_vextq_f32()
+{
+  // CHECK: test_vextq_f32
+  float32x4_t xF32x4;
+  xF32x4 = vextq_f32(xF32x4, xF32x4, 3);
+  // CHECK: shufflevector
+  // CHECK-CODEGEN: test_vextq_f32:
+  // CHECK-CODEGEN: {{ext.16.*#12}}
+}
+
+void test_vextq_s64()
+{
+  // CHECK: test_vextq_s64
+  int64x2_t xS64x2;
+  xS64x2 = vextq_s64(xS64x2, xS64x2, 1);
+  // CHECK: shufflevector
+  // CHECK-CODEGEN: test_vextq_s64:
+  // CHECK-CODEGEN: {{ext.16.*#8}}
+}
+
+void test_vextq_u64()
+{
+  // CHECK: test_vextq_u64
+  uint64x2_t xU64x2;
+  xU64x2 = vextq_u64(xU64x2, xU64x2, 1);
+  // CHECK: shufflevector
+  // CHECK-CODEGEN: test_vextq_u64:
+  // CHECK-CODEGEN: {{ext.16.*#8}}
+}
+
+void test_vextq_f64()
+{
+  // CHECK: test_vextq_f64
+  float64x2_t xF64x2;
+  xF64x2 = vextq_f64(xF64x2, xF64x2, 1);
+  // CHECK: shufflevector
+  // CHECK-CODEGEN: test_vextq_u64:
+  // CHECK-CODEGEN: {{ext.16.*#8}}
+}
diff --git a/test/CodeGen/arm64_vfma.c b/test/CodeGen/arm64_vfma.c
new file mode 100644
index 0000000..bfa5687
--- /dev/null
+++ b/test/CodeGen/arm64_vfma.c
@@ -0,0 +1,136 @@
+// RUN: %clang_cc1 -O1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -S -o - -emit-llvm %s | FileCheck %s
+// Test ARM64 SIMD fused multiply add intrinsics
+
+#include <arm_neon.h>
+
+float32x2_t test_vfma_f32(float32x2_t a1, float32x2_t a2, float32x2_t a3) {
+  // CHECK: test_vfma_f32
+  return vfma_f32(a1, a2, a3);
+  // CHECK: llvm.fma.v2f32({{.*a2, .*a3, .*a1}})
+  // CHECK-NEXT: ret
+}
+
+float32x4_t test_vfmaq_f32(float32x4_t a1, float32x4_t a2, float32x4_t a3) {
+  // CHECK: test_vfmaq_f32
+  return vfmaq_f32(a1, a2, a3);
+  // CHECK: llvm.fma.v4f32({{.*a2, .*a3, .*a1}})
+  // CHECK-NEXT: ret
+}
+
+float64x2_t test_vfmaq_f64(float64x2_t a1, float64x2_t a2, float64x2_t a3) {
+  // CHECK: test_vfmaq_f64
+  return vfmaq_f64(a1, a2, a3);
+  // CHECK: llvm.fma.v2f64({{.*a2, .*a3, .*a1}})
+  // CHECK-NEXT: ret
+}
+
+float32x2_t test_vfma_lane_f32(float32x2_t a1, float32x2_t a2, float32x2_t a3) {
+  // CHECK: test_vfma_lane_f32
+  return vfma_lane_f32(a1, a2, a3, 1);
+  // NB: the test below is deliberately lose, so that we don't depend too much
+  // upon the exact IR used to select lane 1 (usually a shufflevector)
+  // CHECK: llvm.fma.v2f32(<2 x float> %a2, <2 x float> {{.*}}, <2 x float> %a1)
+  // CHECK-NEXT: ret
+}
+
+float32x4_t test_vfmaq_lane_f32(float32x4_t a1, float32x4_t a2, float32x2_t a3) {
+  // CHECK: test_vfmaq_lane_f32
+  return vfmaq_lane_f32(a1, a2, a3, 1);
+  // NB: the test below is deliberately lose, so that we don't depend too much
+  // upon the exact IR used to select lane 1 (usually a shufflevector)
+  // CHECK: llvm.fma.v4f32(<4 x float> %a2, <4 x float> {{.*}}, <4 x float> %a1)
+  // CHECK-NEXT: ret
+}
+
+float64x2_t test_vfmaq_lane_f64(float64x2_t a1, float64x2_t a2, float64x1_t a3) {
+  // CHECK: test_vfmaq_lane_f64
+  return vfmaq_lane_f64(a1, a2, a3, 0);
+  // NB: the test below is deliberately lose, so that we don't depend too much
+  // upon the exact IR used to select lane 1 (usually a shufflevector)
+  // CHECK: llvm.fma.v2f64(<2 x double> %a2, <2 x double> {{.*}}, <2 x double> %a1)
+  // CHECK-NEXT: ret
+}
+
+float32x2_t test_vfma_n_f32(float32x2_t a1, float32x2_t a2, float32_t a3) {
+  // CHECK: test_vfma_n_f32
+  return vfma_n_f32(a1, a2, a3);
+  // NB: the test below is deliberately lose, so that we don't depend too much
+  // upon the exact IR used to select lane 0 (usually two insertelements)
+  // CHECK: llvm.fma.v2f32
+  // CHECK-NEXT: ret
+}
+
+float32x4_t test_vfmaq_n_f32(float32x4_t a1, float32x4_t a2, float32_t a3) {
+  // CHECK: test_vfmaq_n_f32
+  return vfmaq_n_f32(a1, a2, a3);
+  // NB: the test below is deliberately lose, so that we don't depend too much
+  // upon the exact IR used to select lane 0 (usually four insertelements)
+  // CHECK: llvm.fma.v4f32
+  // CHECK-NEXT: ret
+}
+
+float64x2_t test_vfmaq_n_f64(float64x2_t a1, float64x2_t a2, float64_t a3) {
+  // CHECK: test_vfmaq_n_f64
+  return vfmaq_n_f64(a1, a2, a3);
+  // NB: the test below is deliberately lose, so that we don't depend too much
+  // upon the exact IR used to select lane 0 (usually two insertelements)
+  // CHECK: llvm.fma.v2f64
+  // CHECK-NEXT: ret
+}
+
+float32x2_t test_vfms_f32(float32x2_t a1, float32x2_t a2, float32x2_t a3) {
+  // CHECK: test_vfms_f32
+  return vfms_f32(a1, a2, a3);
+  // CHECK: [[NEG:%.*]] = fsub <2 x float> {{.*}}, %a2
+  // CHECK: llvm.fma.v2f32(<2 x float> %a3, <2 x float> [[NEG]], <2 x float> %a1)
+  // CHECK-NEXT: ret
+}
+
+float32x4_t test_vfmsq_f32(float32x4_t a1, float32x4_t a2, float32x4_t a3) {
+  // CHECK: test_vfmsq_f32
+  return vfmsq_f32(a1, a2, a3);
+  // CHECK: [[NEG:%.*]] = fsub <4 x float> {{.*}}, %a2
+  // CHECK: llvm.fma.v4f32(<4 x float> %a3, <4 x float> [[NEG]], <4 x float> %a1)
+  // CHECK-NEXT: ret
+}
+
+float64x2_t test_vfmsq_f64(float64x2_t a1, float64x2_t a2, float64x2_t a3) {
+  // CHECK: test_vfmsq_f64
+  return vfmsq_f64(a1, a2, a3);
+  // CHECK: [[NEG:%.*]] = fsub <2 x double> {{.*}}, %a2
+  // CHECK: llvm.fma.v2f64(<2 x double> %a3, <2 x double> [[NEG]], <2 x double> %a1)
+  // CHECK-NEXT: ret
+}
+
+float32x2_t test_vfms_lane_f32(float32x2_t a1, float32x2_t a2, float32x2_t a3) {
+  // CHECK: test_vfms_lane_f32
+  return vfms_lane_f32(a1, a2, a3, 1);
+  // NB: the test below is deliberately lose, so that we don't depend too much
+  // upon the exact IR used to select lane 1 (usually a shufflevector)
+  // CHECK: [[NEG:%.*]] = fsub <2 x float> {{.*}}, %a3
+  // CHECK: [[LANE:%.*]] = shufflevector <2 x float> [[NEG]]
+  // CHECK: llvm.fma.v2f32(<2 x float> {{.*}}, <2 x float> [[LANE]], <2 x float> %a1)
+  // CHECK-NEXT: ret
+}
+
+float32x4_t test_vfmsq_lane_f32(float32x4_t a1, float32x4_t a2, float32x2_t a3) {
+  // CHECK: test_vfmsq_lane_f32
+  return vfmsq_lane_f32(a1, a2, a3, 1);
+  // NB: the test below is deliberately lose, so that we don't depend too much
+  // upon the exact IR used to select lane 1 (usually a shufflevector)
+  // CHECK: [[NEG:%.*]] = fsub <2 x float> {{.*}}, %a3
+  // CHECK: [[LANE:%.*]] = shufflevector <2 x float> [[NEG]]
+  // CHECK: llvm.fma.v4f32(<4 x float> {{.*}}, <4 x float> [[LANE]], <4 x float> %a1)
+  // CHECK-NEXT: ret
+}
+
+float64x2_t test_vfmsq_lane_f64(float64x2_t a1, float64x2_t a2, float64x1_t a3) {
+  // CHECK: test_vfmsq_lane_f64
+  return vfmsq_lane_f64(a1, a2, a3, 0);
+  // NB: the test below is deliberately lose, so that we don't depend too much
+  // upon the exact IR used to select lane 1 (usually a shufflevector)
+  // CHECK: [[NEG:%.*]] = fsub <1 x double> {{.*}}, %a3
+  // CHECK: [[LANE:%.*]] = shufflevector <1 x double> [[NEG]]
+  // CHECK: llvm.fma.v2f64(<2 x double> {{.*}}, <2 x double> [[LANE]], <2 x double> %a1)
+  // CHECK-NEXT: ret
+}
diff --git a/test/CodeGen/arm64_vget.c b/test/CodeGen/arm64_vget.c
new file mode 100644
index 0000000..62b68ef
--- /dev/null
+++ b/test/CodeGen/arm64_vget.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -O1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -S -o - -emit-llvm %s | FileCheck %s
+// Test ARM64 SIMD vget intrinsics
+
+#include <arm_neon.h>
+
+float64_t test_vget_lane_f64(float64x1_t a1) {
+  // CHECK: test_vget_lane_f64
+  // why isn't 1 allowed as second argument?
+  return vget_lane_f64(a1, 0);
+  // CHECK: extractelement {{.*}} i32 0
+  // CHECK-NEXT: ret
+}
+
diff --git a/test/CodeGen/arm64_vneg.c b/test/CodeGen/arm64_vneg.c
new file mode 100644
index 0000000..d520ebd
--- /dev/null
+++ b/test/CodeGen/arm64_vneg.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -O1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -S -o - -emit-llvm %s | FileCheck %s
+// Test ARM64 SIMD negate and saturating negate intrinsics
+
+#include <arm_neon.h>
+
+int64x2_t test_vnegq_s64(int64x2_t a1) {
+  // CHECK: test_vnegq_s64
+  return vnegq_s64(a1);
+  // CHECK: sub <2 x i64> zeroinitializer, %a1
+  // CHECK-NEXT: ret
+}
+
+int64x2_t test_vqnegq_s64(int64x2_t a1) {
+  // CHECK: test_vqnegq_s64
+  return vqnegq_s64(a1);
+  // CHECK: llvm.aarch64.neon.sqneg.v2i64
+  // CHECK-NEXT: ret
+}
diff --git a/test/CodeGen/arm64_vqmov.c b/test/CodeGen/arm64_vqmov.c
new file mode 100644
index 0000000..6480e66
--- /dev/null
+++ b/test/CodeGen/arm64_vqmov.c
@@ -0,0 +1,77 @@
+// RUN: %clang_cc1 -O3 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -S -o - %s | FileCheck %s
+// REQUIRES: aarch64-registered-target
+/// Test vqmov[u]n_high_<su>{16,32,64) ARM64 intrinsics
+
+#include <arm_neon.h>
+
+// vqmovn_high_s16 -> UQXTN2 Vd.16b,Vn.8h
+int8x16_t test_vqmovn_high_s16(int8x8_t Vdlow, int16x8_t Vn)
+{
+    return vqmovn_high_s16(Vdlow, Vn);
+  // CHECK: test_vqmovn_high_s16:
+  // CHECK: sqxtn2.16b {{v[0-9][0-9]*}}, {{v[0-9][0-9]*}}
+}
+
+// vqmovun_high_s16 -> UQXTN2 Vd.16b,Vn.8h
+uint8x16_t test_vqmovun_high_s16(uint8x8_t Vdlow, uint16x8_t Vn)
+{
+    return vqmovun_high_s16(Vdlow, Vn);
+  // CHECK: test_vqmovun_high_s16:
+  // CHECK: sqxtun2.16b {{v[0-9][0-9]*}}, {{v[0-9][0-9]*}}
+}
+
+// vqmovn_high_s32 -> SQXTN2 Vd.8h,Vn.4s
+int16x8_t test_vqmovn_high_s32(int16x4_t Vdlow, int32x4_t Vn)
+{
+    return vqmovn_high_s32(Vdlow, Vn);
+  // CHECK: test_vqmovn_high_s32:
+  // CHECK: sqxtn2.8h {{v[0-9][0-9]*}}, {{v[0-9][0-9]*}}
+}
+
+// vqmovn_high_u32 -> UQXTN2 Vd.8h,Vn.4s
+uint16x8_t test_vqmovn_high_u32(uint16x4_t Vdlow, uint32x4_t Vn)
+{
+    return vqmovn_high_u32(Vdlow, Vn);
+  // CHECK: test_vqmovn_high_u32:
+  // CHECK: uqxtn2.8h {{v[0-9][0-9]*}}, {{v[0-9][0-9]*}}
+}
+
+// vqmovn_high_s64 -> SQXTN2 Vd.4s,Vn.2d
+int32x4_t test_vqmovn_high_s64(int32x2_t Vdlow, int64x2_t Vn)
+{
+    return vqmovn_high_s64(Vdlow, Vn);
+  // CHECK: test_vqmovn_high_s64:
+  // CHECK: sqxtn2.4s {{v[0-9][0-9]*}}, {{v[0-9][0-9]*}}
+}
+
+// vqmovn_high_u64 -> UQXTN2 Vd.4s,Vn.2d
+uint32x4_t test_vqmovn_high_u64(uint32x2_t Vdlow, uint64x2_t Vn)
+{
+    return vqmovn_high_u64(Vdlow, Vn);
+  // CHECK: test_vqmovn_high_u64:
+  // CHECK: uqxtn2.4s {{v[0-9][0-9]*}}, {{v[0-9][0-9]*}}
+}
+
+// vqmovn_high_u16 -> UQXTN2 Vd.16b,Vn.8h
+uint8x16_t test_vqmovn_high_u16(uint8x8_t Vdlow, uint16x8_t Vn)
+{
+    return vqmovn_high_u16(Vdlow, Vn);
+  // CHECK: test_vqmovn_high_u16:
+  // CHECK: uqxtn2.16b {{v[0-9][0-9]*}}, {{v[0-9][0-9]*}}
+}
+
+// vqmovun_high_s32 -> SQXTUN2 Vd.8h,Vn.4s
+uint16x8_t test_vqmovun_high_s32(uint16x4_t Vdlow, uint32x4_t Vn)
+{
+    return vqmovun_high_s32(Vdlow, Vn);
+  // CHECK: test_vqmovun_high_s32:
+  // CHECK: sqxtun2.8h {{v[0-9][0-9]*}}, {{v[0-9][0-9]*}}
+}
+
+// vqmovun_high_s64 -> SQXTUN2  Vd.4s,Vn.2d
+uint32x4_t test_vqmovun_high_s64(uint32x2_t Vdlow, uint64x2_t Vn)
+{
+    return vqmovun_high_s64(Vdlow, Vn);
+  // CHECK: test_vqmovun_high_s64:
+  // CHECK: sqxtun2.4s {{v[0-9][0-9]*}}, {{v[0-9][0-9]*}}
+}
diff --git a/test/CodeGen/arm64_vrecps.c b/test/CodeGen/arm64_vrecps.c
new file mode 100644
index 0000000..a3af13c
--- /dev/null
+++ b/test/CodeGen/arm64_vrecps.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -O3 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -S -o - %s | FileCheck %s
+// REQUIRES: aarch64-registered-target
+/// Test vrecpss_f32, vrecpsd_f64 ARM64 intrinsics
+
+
+#include <arm_neon.h>
+
+// vrecpss_f32 -> FRECPS Sd,Sa,Sb
+//
+float32_t test_vrecpss_f32(float32_t Vdlow, float32_t Vn)
+{
+    return vrecpss_f32(Vdlow, Vn);
+  // CHECK: test_vrecpss_f32:
+  // CHECK: frecps  s0, s0, s1
+  // CHECK-NEXT: ret
+}
+
+// vrecpsd_f64 -> FRECPS Dd,Da,Db
+//
+float64_t test_vrecpsd_f64(float64_t Vdlow, float64_t Vn)
+{
+    return vrecpsd_f64(Vdlow, Vn);
+  // CHECK: test_vrecpsd_f64:
+  // CHECK: frecps d0, d0, d1
+  // CHECK-NEXT: ret
+}
diff --git a/test/CodeGen/arm64_vset_lane.c b/test/CodeGen/arm64_vset_lane.c
new file mode 100644
index 0000000..6fbaaa7
--- /dev/null
+++ b/test/CodeGen/arm64_vset_lane.c
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -O1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -S -o - -emit-llvm %s | FileCheck %s
+// Test ARM64 SIMD set lane intrinsics INCOMPLETE
+
+#include <arm_neon.h>
+
+float16x4_t test_vset_lane_f16(float16_t *a1, float16x4_t a2) {
+  // CHECK-LABEL: test_vset_lane_f16
+  return vset_lane_f16(*a1, a2, 1);
+  // CHECK insertelement <4 x i16> %a2, i16 %a1, i32 1
+}
+
+float16x8_t test_vsetq_lane_f16(float16_t *a1, float16x8_t a2) {
+  // CHECK-LABEL: test_vsetq_lane_f16
+  return vsetq_lane_f16(*a1, a2, 4);
+  // CHECK insertelement <8 x i16> %a2, i16 %a1, i32 4
+}
+
+// problem with scalar_to_vector in backend.  Punt for now
+#if 0
+float64x1_t test_vset_lane_f64(float64_t a1, float64x1_t a2) {
+  // CHECK-LABEL@ test_vset_lane_f64
+  return vset_lane_f64(a1, a2, 0);
+  // CHECK@ @llvm.aarch64.neon.smaxv.i32.v8i8
+}
+#endif
+
+float64x2_t test_vsetq_lane_f64(float64_t a1, float64x2_t a2) {
+  // CHECK-LABEL: test_vsetq_lane_f64
+  return vsetq_lane_f64(a1, a2, 0);
+  // CHECK insertelement <2 x double> %a2, double %a1, i32 0
+}
diff --git a/test/CodeGen/arm64_vshift.c b/test/CodeGen/arm64_vshift.c
new file mode 100644
index 0000000..af02899
--- /dev/null
+++ b/test/CodeGen/arm64_vshift.c
@@ -0,0 +1,357 @@
+// RUN: %clang_cc1 -triple arm64-apple-ios7.0 -target-feature +neon -ffreestanding -emit-llvm -o - -O1 %s | FileCheck %s
+#include <arm_neon.h>
+
+int8x8_t test_vqshl_n_s8(int8x8_t in) {
+  // CHECK-LABEL: @test_vqshl_n_s8
+  // CHECK: call <8 x i8> @llvm.aarch64.neon.sqshl.v8i8(<8 x i8> %in, <8 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>)
+  return vqshl_n_s8(in, 1);
+}
+
+int16x4_t test_vqshl_n_s16(int16x4_t in) {
+  // CHECK-LABEL: @test_vqshl_n_s16
+  // CHECK: call <4 x i16> @llvm.aarch64.neon.sqshl.v4i16(<4 x i16> %in, <4 x i16> <i16 1, i16 1, i16 1, i16 1>)
+  return vqshl_n_s16(in, 1);
+}
+
+int32x2_t test_vqshl_n_s32(int32x2_t in) {
+  // CHECK-LABEL: @test_vqshl_n_s32
+  // CHECK: call <2 x i32> @llvm.aarch64.neon.sqshl.v2i32(<2 x i32> %in, <2 x i32> <i32 1, i32 1>)
+  return vqshl_n_s32(in, 1);
+}
+
+int64x1_t test_vqshl_n_s64(int64x1_t in) {
+  // CHECK-LABEL: @test_vqshl_n_s64
+  // CHECK: call <1 x i64> @llvm.aarch64.neon.sqshl.v1i64(<1 x i64> %in, <1 x i64> <i64 1>)
+  return vqshl_n_s64(in, 1);
+}
+
+
+int8x16_t test_vqshlq_n_s8(int8x16_t in) {
+  // CHECK-LABEL: @test_vqshlq_n_s8
+  // CHECK: call <16 x i8> @llvm.aarch64.neon.sqshl.v16i8(<16 x i8> %in, <16 x i8> <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>)
+  return vqshlq_n_s8(in, 1);
+}
+
+int16x8_t test_vqshlq_n_s16(int16x8_t in) {
+  // CHECK-LABEL: @test_vqshlq_n_s16
+  // CHECK: call <8 x i16> @llvm.aarch64.neon.sqshl.v8i16(<8 x i16> %in, <8 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>)
+  return vqshlq_n_s16(in, 1);
+}
+
+int32x4_t test_vqshlq_n_s32(int32x4_t in) {
+  // CHECK-LABEL: @test_vqshlq_n_s32
+  // CHECK: call <4 x i32> @llvm.aarch64.neon.sqshl.v4i32(<4 x i32> %in, <4 x i32> <i32 1, i32 1, i32 1, i32 1>)
+  return vqshlq_n_s32(in, 1);
+}
+
+int64x2_t test_vqshlq_n_s64(int64x2_t in) {
+  // CHECK-LABEL: @test_vqshlq_n_s64
+  // CHECK: call <2 x i64> @llvm.aarch64.neon.sqshl.v2i64(<2 x i64> %in, <2 x i64> <i64 1, i64 1>
+  return vqshlq_n_s64(in, 1);
+}
+
+uint8x8_t test_vqshl_n_u8(uint8x8_t in) {
+  // CHECK-LABEL: @test_vqshl_n_u8
+  // CHECK: call <8 x i8> @llvm.aarch64.neon.uqshl.v8i8(<8 x i8> %in, <8 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>)
+  return vqshl_n_u8(in, 1);
+}
+
+uint16x4_t test_vqshl_n_u16(uint16x4_t in) {
+  // CHECK-LABEL: @test_vqshl_n_u16
+  // CHECK: call <4 x i16> @llvm.aarch64.neon.uqshl.v4i16(<4 x i16> %in, <4 x i16> <i16 1, i16 1, i16 1, i16 1>)
+  return vqshl_n_u16(in, 1);
+}
+
+uint32x2_t test_vqshl_n_u32(uint32x2_t in) {
+  // CHECK-LABEL: @test_vqshl_n_u32
+  // CHECK: call <2 x i32> @llvm.aarch64.neon.uqshl.v2i32(<2 x i32> %in, <2 x i32> <i32 1, i32 1>)
+  return vqshl_n_u32(in, 1);
+}
+
+uint64x1_t test_vqshl_n_u64(uint64x1_t in) {
+  // CHECK-LABEL: @test_vqshl_n_u64
+  // CHECK: call <1 x i64> @llvm.aarch64.neon.uqshl.v1i64(<1 x i64> %in, <1 x i64> <i64 1>)
+  return vqshl_n_u64(in, 1);
+}
+
+uint8x16_t test_vqshlq_n_u8(uint8x16_t in) {
+  // CHECK-LABEL: @test_vqshlq_n_u8
+  // CHECK: call <16 x i8> @llvm.aarch64.neon.uqshl.v16i8(<16 x i8> %in, <16 x i8> <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>)
+  return vqshlq_n_u8(in, 1);
+}
+
+uint16x8_t test_vqshlq_n_u16(uint16x8_t in) {
+  // CHECK-LABEL: @test_vqshlq_n_u16
+  // CHECK: call <8 x i16> @llvm.aarch64.neon.uqshl.v8i16(<8 x i16> %in, <8 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>)
+  return vqshlq_n_u16(in, 1);
+}
+
+uint32x4_t test_vqshlq_n_u32(uint32x4_t in) {
+  // CHECK-LABEL: @test_vqshlq_n_u32
+  // CHECK: call <4 x i32> @llvm.aarch64.neon.uqshl.v4i32(<4 x i32> %in, <4 x i32> <i32 1, i32 1, i32 1, i32 1>)
+  return vqshlq_n_u32(in, 1);
+}
+
+uint64x2_t test_vqshlq_n_u64(uint64x2_t in) {
+  // CHECK-LABEL: @test_vqshlq_n_u64
+  // CHECK: call <2 x i64> @llvm.aarch64.neon.uqshl.v2i64(<2 x i64> %in, <2 x i64> <i64 1, i64 1>
+  return vqshlq_n_u64(in, 1);
+}
+
+int8x8_t test_vrshr_n_s8(int8x8_t in) {
+  // CHECK-LABEL: @test_vrshr_n_s8
+  // CHECK: call <8 x i8> @llvm.aarch64.neon.srshl.v8i8(<8 x i8> %in, <8 x i8> <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>)
+  return vrshr_n_s8(in, 1);
+}
+
+int16x4_t test_vrshr_n_s16(int16x4_t in) {
+  // CHECK-LABEL: @test_vrshr_n_s16
+  // CHECK: call <4 x i16> @llvm.aarch64.neon.srshl.v4i16(<4 x i16> %in, <4 x i16> <i16 -1, i16 -1, i16 -1, i16 -1>)
+  return vrshr_n_s16(in, 1);
+}
+
+int32x2_t test_vrshr_n_s32(int32x2_t in) {
+  // CHECK-LABEL: @test_vrshr_n_s32
+  // CHECK: call <2 x i32> @llvm.aarch64.neon.srshl.v2i32(<2 x i32> %in, <2 x i32> <i32 -1, i32 -1>)
+  return vrshr_n_s32(in, 1);
+}
+
+int64x1_t test_vrshr_n_s64(int64x1_t in) {
+  // CHECK-LABEL: @test_vrshr_n_s64
+  // CHECK: call <1 x i64> @llvm.aarch64.neon.srshl.v1i64(<1 x i64> %in, <1 x i64> <i64 -1>)
+  return vrshr_n_s64(in, 1);
+}
+
+
+int8x16_t test_vrshrq_n_s8(int8x16_t in) {
+  // CHECK-LABEL: @test_vrshrq_n_s8
+  // CHECK: call <16 x i8> @llvm.aarch64.neon.srshl.v16i8(<16 x i8> %in, <16 x i8> <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>)
+  return vrshrq_n_s8(in, 1);
+}
+
+int16x8_t test_vrshrq_n_s16(int16x8_t in) {
+  // CHECK-LABEL: @test_vrshrq_n_s16
+  // CHECK: call <8 x i16> @llvm.aarch64.neon.srshl.v8i16(<8 x i16> %in, <8 x i16> <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>)
+  return vrshrq_n_s16(in, 1);
+}
+
+int32x4_t test_vrshrq_n_s32(int32x4_t in) {
+  // CHECK-LABEL: @test_vrshrq_n_s32
+  // CHECK: call <4 x i32> @llvm.aarch64.neon.srshl.v4i32(<4 x i32> %in, <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>)
+  return vrshrq_n_s32(in, 1);
+}
+
+int64x2_t test_vrshrq_n_s64(int64x2_t in) {
+  // CHECK-LABEL: @test_vrshrq_n_s64
+  // CHECK: call <2 x i64> @llvm.aarch64.neon.srshl.v2i64(<2 x i64> %in, <2 x i64> <i64 -1, i64 -1>
+  return vrshrq_n_s64(in, 1);
+}
+
+uint8x8_t test_vrshr_n_u8(uint8x8_t in) {
+  // CHECK-LABEL: @test_vrshr_n_u8
+  // CHECK: call <8 x i8> @llvm.aarch64.neon.urshl.v8i8(<8 x i8> %in, <8 x i8> <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>)
+  return vrshr_n_u8(in, 1);
+}
+
+uint16x4_t test_vrshr_n_u16(uint16x4_t in) {
+  // CHECK-LABEL: @test_vrshr_n_u16
+  // CHECK: call <4 x i16> @llvm.aarch64.neon.urshl.v4i16(<4 x i16> %in, <4 x i16> <i16 -1, i16 -1, i16 -1, i16 -1>)
+  return vrshr_n_u16(in, 1);
+}
+
+uint32x2_t test_vrshr_n_u32(uint32x2_t in) {
+  // CHECK-LABEL: @test_vrshr_n_u32
+  // CHECK: call <2 x i32> @llvm.aarch64.neon.urshl.v2i32(<2 x i32> %in, <2 x i32> <i32 -1, i32 -1>)
+  return vrshr_n_u32(in, 1);
+}
+
+uint64x1_t test_vrshr_n_u64(uint64x1_t in) {
+  // CHECK-LABEL: @test_vrshr_n_u64
+  // CHECK: call <1 x i64> @llvm.aarch64.neon.urshl.v1i64(<1 x i64> %in, <1 x i64> <i64 -1>)
+  return vrshr_n_u64(in, 1);
+}
+
+uint8x16_t test_vrshrq_n_u8(uint8x16_t in) {
+  // CHECK-LABEL: @test_vrshrq_n_u8
+  // CHECK: call <16 x i8> @llvm.aarch64.neon.urshl.v16i8(<16 x i8> %in, <16 x i8> <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>)
+  return vrshrq_n_u8(in, 1);
+}
+
+uint16x8_t test_vrshrq_n_u16(uint16x8_t in) {
+  // CHECK-LABEL: @test_vrshrq_n_u16
+  // CHECK: call <8 x i16> @llvm.aarch64.neon.urshl.v8i16(<8 x i16> %in, <8 x i16> <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>)
+  return vrshrq_n_u16(in, 1);
+}
+
+uint32x4_t test_vrshrq_n_u32(uint32x4_t in) {
+  // CHECK-LABEL: @test_vrshrq_n_u32
+  // CHECK: call <4 x i32> @llvm.aarch64.neon.urshl.v4i32(<4 x i32> %in, <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>)
+  return vrshrq_n_u32(in, 1);
+}
+
+uint64x2_t test_vrshrq_n_u64(uint64x2_t in) {
+  // CHECK-LABEL: @test_vrshrq_n_u64
+  // CHECK: call <2 x i64> @llvm.aarch64.neon.urshl.v2i64(<2 x i64> %in, <2 x i64> <i64 -1, i64 -1>
+  return vrshrq_n_u64(in, 1);
+}
+
+int8x8_t test_vqshlu_n_s8(int8x8_t in) {
+  // CHECK-LABEL: @test_vqshlu_n_s8
+  // CHECK: call <8 x i8> @llvm.aarch64.neon.sqshlu.v8i8(<8 x i8> %in, <8 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>)
+  return vqshlu_n_s8(in, 1);
+}
+
+int16x4_t test_vqshlu_n_s16(int16x4_t in) {
+  // CHECK-LABEL: @test_vqshlu_n_s16
+  // CHECK: call <4 x i16> @llvm.aarch64.neon.sqshlu.v4i16(<4 x i16> %in, <4 x i16> <i16 1, i16 1, i16 1, i16 1>)
+  return vqshlu_n_s16(in, 1);
+}
+
+int32x2_t test_vqshlu_n_s32(int32x2_t in) {
+  // CHECK-LABEL: @test_vqshlu_n_s32
+  // CHECK: call <2 x i32> @llvm.aarch64.neon.sqshlu.v2i32(<2 x i32> %in, <2 x i32> <i32 1, i32 1>)
+  return vqshlu_n_s32(in, 1);
+}
+
+int64x1_t test_vqshlu_n_s64(int64x1_t in) {
+  // CHECK-LABEL: @test_vqshlu_n_s64
+  // CHECK: call <1 x i64> @llvm.aarch64.neon.sqshlu.v1i64(<1 x i64> %in, <1 x i64> <i64 1>)
+  return vqshlu_n_s64(in, 1);
+}
+
+
+int8x16_t test_vqshluq_n_s8(int8x16_t in) {
+  // CHECK-LABEL: @test_vqshluq_n_s8
+  // CHECK: call <16 x i8> @llvm.aarch64.neon.sqshlu.v16i8(<16 x i8> %in, <16 x i8> <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>)
+  return vqshluq_n_s8(in, 1);
+}
+
+int16x8_t test_vqshluq_n_s16(int16x8_t in) {
+  // CHECK-LABEL: @test_vqshluq_n_s16
+  // CHECK: call <8 x i16> @llvm.aarch64.neon.sqshlu.v8i16(<8 x i16> %in, <8 x i16> <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>)
+  return vqshluq_n_s16(in, 1);
+}
+
+int32x4_t test_vqshluq_n_s32(int32x4_t in) {
+  // CHECK-LABEL: @test_vqshluq_n_s32
+  // CHECK: call <4 x i32> @llvm.aarch64.neon.sqshlu.v4i32(<4 x i32> %in, <4 x i32> <i32 1, i32 1, i32 1, i32 1>)
+  return vqshluq_n_s32(in, 1);
+}
+
+int64x2_t test_vqshluq_n_s64(int64x2_t in) {
+  // CHECK-LABEL: @test_vqshluq_n_s64
+  // CHECK: call <2 x i64> @llvm.aarch64.neon.sqshlu.v2i64(<2 x i64> %in, <2 x i64> <i64 1, i64 1>
+  return vqshluq_n_s64(in, 1);
+}
+
+int8x8_t test_vrsra_n_s8(int8x8_t acc, int8x8_t in) {
+  // CHECK-LABEL: @test_vrsra_n_s8
+  // CHECK: [[TMP:%[0-9a-zA-Z._]+]] = tail call <8 x i8> @llvm.aarch64.neon.srshl.v8i8(<8 x i8> %in, <8 x i8> <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>)
+  // CHECK: add <8 x i8> [[TMP]], %acc
+  return vrsra_n_s8(acc, in, 1);
+}
+
+int16x4_t test_vrsra_n_s16(int16x4_t acc, int16x4_t in) {
+  // CHECK-LABEL: @test_vrsra_n_s16
+  // CHECK: [[TMP:%[0-9a-zA-Z._]+]] = tail call <4 x i16> @llvm.aarch64.neon.srshl.v4i16(<4 x i16> %in, <4 x i16> <i16 -1, i16 -1, i16 -1, i16 -1>)
+  // CHECK: add <4 x i16> [[TMP]], %acc
+  return vrsra_n_s16(acc, in, 1);
+}
+
+int32x2_t test_vrsra_n_s32(int32x2_t acc, int32x2_t in) {
+  // CHECK-LABEL: @test_vrsra_n_s32
+  // CHECK: [[TMP:%[0-9a-zA-Z._]+]] = tail call <2 x i32> @llvm.aarch64.neon.srshl.v2i32(<2 x i32> %in, <2 x i32> <i32 -1, i32 -1>)
+  // CHECK: add <2 x i32> [[TMP]], %acc
+  return vrsra_n_s32(acc, in, 1);
+}
+
+int64x1_t test_vrsra_n_s64(int64x1_t acc, int64x1_t in) {
+  // CHECK-LABEL: @test_vrsra_n_s64
+  // CHECK: [[TMP:%[0-9a-zA-Z._]+]] = tail call <1 x i64> @llvm.aarch64.neon.srshl.v1i64(<1 x i64> %in, <1 x i64> <i64 -1>)
+  // CHECK: add <1 x i64> [[TMP]], %acc
+  return vrsra_n_s64(acc, in, 1);
+}
+
+int8x16_t test_vrsraq_n_s8(int8x16_t acc, int8x16_t in) {
+  // CHECK-LABEL: @test_vrsraq_n_s8
+  // CHECK: [[TMP:%[0-9a-zA-Z._]+]] = tail call <16 x i8> @llvm.aarch64.neon.srshl.v16i8(<16 x i8> %in, <16 x i8> <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: add <16 x i8> [[TMP]], %acc
+  return vrsraq_n_s8(acc, in, 1);
+}
+
+int16x8_t test_vrsraq_n_s16(int16x8_t acc, int16x8_t in) {
+  // CHECK-LABEL: @test_vrsraq_n_s16
+  // CHECK: [[TMP:%[0-9a-zA-Z._]+]] = tail call <8 x i16> @llvm.aarch64.neon.srshl.v8i16(<8 x i16> %in, <8 x i16> <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>)
+  // CHECK: add <8 x i16> [[TMP]], %acc
+  return vrsraq_n_s16(acc, in, 1);
+}
+
+int32x4_t test_vrsraq_n_s32(int32x4_t acc, int32x4_t in) {
+  // CHECK-LABEL: @test_vrsraq_n_s32
+  // CHECK: [[TMP:%[0-9a-zA-Z._]+]] = tail call <4 x i32> @llvm.aarch64.neon.srshl.v4i32(<4 x i32> %in, <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>)
+  // CHECK: add <4 x i32> [[TMP]], %acc
+  return vrsraq_n_s32(acc, in, 1);
+}
+
+int64x2_t test_vrsraq_n_s64(int64x2_t acc, int64x2_t in) {
+  // CHECK-LABEL: @test_vrsraq_n_s64
+  // CHECK: [[TMP:%[0-9a-zA-Z._]+]] = tail call <2 x i64> @llvm.aarch64.neon.srshl.v2i64(<2 x i64> %in, <2 x i64> <i64 -1, i64 -1>)
+  // CHECK: add <2 x i64> [[TMP]], %acc
+  return vrsraq_n_s64(acc, in, 1);
+}
+
+uint8x8_t test_vrsra_n_u8(uint8x8_t acc, uint8x8_t in) {
+  // CHECK-LABEL: @test_vrsra_n_u8
+  // CHECK: [[TMP:%[0-9a-zA-Z._]+]] = tail call <8 x i8> @llvm.aarch64.neon.urshl.v8i8(<8 x i8> %in, <8 x i8> <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>)
+  // CHECK: add <8 x i8> [[TMP]], %acc
+  return vrsra_n_u8(acc, in, 1);
+}
+
+uint16x4_t test_vrsra_n_u16(uint16x4_t acc, uint16x4_t in) {
+  // CHECK-LABEL: @test_vrsra_n_u16
+  // CHECK: [[TMP:%[0-9a-zA-Z._]+]] = tail call <4 x i16> @llvm.aarch64.neon.urshl.v4i16(<4 x i16> %in, <4 x i16> <i16 -1, i16 -1, i16 -1, i16 -1>)
+  // CHECK: add <4 x i16> [[TMP]], %acc
+  return vrsra_n_u16(acc, in, 1);
+}
+
+uint32x2_t test_vrsra_n_u32(uint32x2_t acc, uint32x2_t in) {
+  // CHECK-LABEL: @test_vrsra_n_u32
+  // CHECK: [[TMP:%[0-9a-zA-Z._]+]] = tail call <2 x i32> @llvm.aarch64.neon.urshl.v2i32(<2 x i32> %in, <2 x i32> <i32 -1, i32 -1>)
+  // CHECK: add <2 x i32> [[TMP]], %acc
+  return vrsra_n_u32(acc, in, 1);
+}
+
+uint64x1_t test_vrsra_n_u64(uint64x1_t acc, uint64x1_t in) {
+  // CHECK-LABEL: @test_vrsra_n_u64
+  // CHECK: [[TMP:%[0-9a-zA-Z._]+]] = tail call <1 x i64> @llvm.aarch64.neon.urshl.v1i64(<1 x i64> %in, <1 x i64> <i64 -1>)
+  // CHECK: add <1 x i64> [[TMP]], %acc
+  return vrsra_n_u64(acc, in, 1);
+}
+
+uint8x16_t test_vrsraq_n_u8(uint8x16_t acc, uint8x16_t in) {
+  // CHECK-LABEL: @test_vrsraq_n_u8
+  // CHECK: [[TMP:%[0-9a-zA-Z._]+]] = tail call <16 x i8> @llvm.aarch64.neon.urshl.v16i8(<16 x i8> %in, <16 x i8> <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: add <16 x i8> [[TMP]], %acc
+  return vrsraq_n_u8(acc, in, 1);
+}
+
+uint16x8_t test_vrsraq_n_u16(uint16x8_t acc, uint16x8_t in) {
+  // CHECK-LABEL: @test_vrsraq_n_u16
+  // CHECK: [[TMP:%[0-9a-zA-Z._]+]] = tail call <8 x i16> @llvm.aarch64.neon.urshl.v8i16(<8 x i16> %in, <8 x i16> <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>)
+  // CHECK: add <8 x i16> [[TMP]], %acc
+  return vrsraq_n_u16(acc, in, 1);
+}
+
+uint32x4_t test_vrsraq_n_u32(uint32x4_t acc, uint32x4_t in) {
+  // CHECK-LABEL: @test_vrsraq_n_u32
+  // CHECK: [[TMP:%[0-9a-zA-Z._]+]] = tail call <4 x i32> @llvm.aarch64.neon.urshl.v4i32(<4 x i32> %in, <4 x i32> <i32 -1, i32 -1, i32 -1, i32 -1>)
+  // CHECK: add <4 x i32> [[TMP]], %acc
+  return vrsraq_n_u32(acc, in, 1);
+}
+
+uint64x2_t test_vrsraq_n_u64(uint64x2_t acc, uint64x2_t in) {
+  // CHECK-LABEL: @test_vrsraq_n_u64
+  // CHECK: [[TMP:%[0-9a-zA-Z._]+]] = tail call <2 x i64> @llvm.aarch64.neon.urshl.v2i64(<2 x i64> %in, <2 x i64> <i64 -1, i64 -1>)
+  // CHECK: add <2 x i64> [[TMP]], %acc
+  return vrsraq_n_u64(acc, in, 1);
+}
diff --git a/test/CodeGen/arm64_vsli.c b/test/CodeGen/arm64_vsli.c
new file mode 100644
index 0000000..b2a30ab
--- /dev/null
+++ b/test/CodeGen/arm64_vsli.c
@@ -0,0 +1,148 @@
+// RUN: %clang_cc1 -O1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -S -o - -emit-llvm %s | FileCheck %s
+// RUN: %clang_cc1 -O1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -S -o - %s | \
+// RUN:   FileCheck -check-prefix=CHECK_CODEGEN %s
+// REQUIRES: aarch64-registered-target
+// Test
+
+#include <arm_neon.h>
+
+int8x8_t test_vsli_n_s8(int8x8_t a1, int8x8_t a2) {
+  // CHECK: test_vsli_n_s8
+  return vsli_n_s8(a1, a2, 3);
+  // CHECK: llvm.aarch64.neon.vsli.v8i8
+  // CHECK_CODEGEN: sli.8b  v0, v1, #3
+}
+
+int16x4_t test_vsli_n_s16(int16x4_t a1, int16x4_t a2) {
+  // CHECK: test_vsli_n_s16
+  return vsli_n_s16(a1, a2, 3);
+  // CHECK: llvm.aarch64.neon.vsli.v4i16
+  // CHECK_CODEGEN: sli.4h  v0, v1, #3
+}
+
+int32x2_t test_vsli_n_s32(int32x2_t a1, int32x2_t a2) {
+  // CHECK: test_vsli_n_s32
+  return vsli_n_s32(a1, a2, 1);
+  // CHECK: llvm.aarch64.neon.vsli.v2i32
+  // CHECK_CODEGEN: sli.2s  v0, v1, #1
+}
+
+int64x1_t test_vsli_n_s64(int64x1_t a1, int64x1_t a2) {
+  // CHECK: test_vsli_n_s64
+  return vsli_n_s64(a1, a2, 1);
+  // CHECK: llvm.aarch64.neon.vsli.v1i64
+  // CHECK_CODEGEN: sli     d0, d1, #1
+}
+
+uint8x8_t test_vsli_n_u8(uint8x8_t a1, uint8x8_t a2) {
+  // CHECK: test_vsli_n_u8
+  return vsli_n_u8(a1, a2, 3);
+  // CHECK: llvm.aarch64.neon.vsli.v8i8
+  // CHECK_CODEGEN: sli.8b  v0, v1, #3
+}
+
+uint16x4_t test_vsli_n_u16(uint16x4_t a1, uint16x4_t a2) {
+  // CHECK: test_vsli_n_u16
+  return vsli_n_u16(a1, a2, 3);
+  // CHECK: llvm.aarch64.neon.vsli.v4i16
+  // CHECK_CODEGEN: sli.4h  v0, v1, #3
+}
+
+uint32x2_t test_vsli_n_u32(uint32x2_t a1, uint32x2_t a2) {
+  // CHECK: test_vsli_n_u32
+  return vsli_n_u32(a1, a2, 1);
+  // CHECK: llvm.aarch64.neon.vsli.v2i32
+  // CHECK_CODEGEN: sli.2s  v0, v1, #1
+}
+
+uint64x1_t test_vsli_n_u64(uint64x1_t a1, uint64x1_t a2) {
+  // CHECK: test_vsli_n_u64
+  return vsli_n_u64(a1, a2, 1);
+  // CHECK: llvm.aarch64.neon.vsli.v1i64
+  // CHECK_CODEGEN: sli     d0, d1, #1
+}
+
+poly8x8_t test_vsli_n_p8(poly8x8_t a1, poly8x8_t a2) {
+  // CHECK: test_vsli_n_p8
+  return vsli_n_p8(a1, a2, 1);
+  // CHECK: llvm.aarch64.neon.vsli.v8i8
+  // CHECK_CODEGEN: sli.8b  v0, v1, #1
+}
+
+poly16x4_t test_vsli_n_p16(poly16x4_t a1, poly16x4_t a2) {
+  // CHECK: test_vsli_n_p16
+  return vsli_n_p16(a1, a2, 1);
+  // CHECK: llvm.aarch64.neon.vsli.v4i16
+  // CHECK_CODEGEN: sli.4h  v0, v1, #1
+}
+
+int8x16_t test_vsliq_n_s8(int8x16_t a1, int8x16_t a2) {
+  // CHECK: test_vsliq_n_s8
+  return vsliq_n_s8(a1, a2, 3);
+  // CHECK: llvm.aarch64.neon.vsli.v16i8
+  // CHECK_CODEGEN: sli.16b v0, v1, #3
+}
+
+int16x8_t test_vsliq_n_s16(int16x8_t a1, int16x8_t a2) {
+  // CHECK: test_vsliq_n_s16
+  return vsliq_n_s16(a1, a2, 3);
+  // CHECK: llvm.aarch64.neon.vsli.v8i16
+  // CHECK_CODEGEN: sli.8h  v0, v1, #3
+}
+
+int32x4_t test_vsliq_n_s32(int32x4_t a1, int32x4_t a2) {
+  // CHECK: test_vsliq_n_s32
+  return vsliq_n_s32(a1, a2, 1);
+  // CHECK: llvm.aarch64.neon.vsli.v4i32
+  // CHECK_CODEGEN: sli.4s  v0, v1, #1
+}
+
+int64x2_t test_vsliq_n_s64(int64x2_t a1, int64x2_t a2) {
+  // CHECK: test_vsliq_n_s64
+  return vsliq_n_s64(a1, a2, 1);
+  // CHECK: llvm.aarch64.neon.vsli.v2i64
+  // CHECK_CODEGEN: sli.2d  v0, v1, #1
+}
+
+uint8x16_t test_vsliq_n_u8(uint8x16_t a1, uint8x16_t a2) {
+  // CHECK: test_vsliq_n_u8
+  return vsliq_n_u8(a1, a2, 3);
+  // CHECK: llvm.aarch64.neon.vsli.v16i8
+  // CHECK_CODEGEN: sli.16b v0, v1, #3
+}
+
+uint16x8_t test_vsliq_n_u16(uint16x8_t a1, uint16x8_t a2) {
+  // CHECK: test_vsliq_n_u16
+  return vsliq_n_u16(a1, a2, 3);
+  // CHECK: llvm.aarch64.neon.vsli.v8i16
+  // CHECK_CODEGEN: sli.8h  v0, v1, #3
+}
+
+uint32x4_t test_vsliq_n_u32(uint32x4_t a1, uint32x4_t a2) {
+  // CHECK: test_vsliq_n_u32
+  return vsliq_n_u32(a1, a2, 1);
+  // CHECK: llvm.aarch64.neon.vsli.v4i32
+  // CHECK_CODEGEN: sli.4s  v0, v1, #1
+}
+
+uint64x2_t test_vsliq_n_u64(uint64x2_t a1, uint64x2_t a2) {
+  // CHECK: test_vsliq_n_u64
+  return vsliq_n_u64(a1, a2, 1);
+  // CHECK: llvm.aarch64.neon.vsli.v2i64
+  // CHECK_CODEGEN: sli.2d  v0, v1, #1
+}
+
+poly8x16_t test_vsliq_n_p8(poly8x16_t a1, poly8x16_t a2) {
+  // CHECK: test_vsliq_n_p8
+  return vsliq_n_p8(a1, a2, 1);
+  // CHECK: llvm.aarch64.neon.vsli.v16i8
+  // CHECK_CODEGEN: sli.16b v0, v1, #1
+}
+
+poly16x8_t test_vsliq_n_p16(poly16x8_t a1, poly16x8_t a2) {
+  // CHECK: test_vsliq_n_p16
+  return vsliq_n_p16(a1, a2, 1);
+  // CHECK: llvm.aarch64.neon.vsli.v8i16
+  // CHECK_CODEGEN: sli.8h  v0, v1, #1
+}
+
diff --git a/test/CodeGen/arm64_vsri.c b/test/CodeGen/arm64_vsri.c
new file mode 100644
index 0000000..579431d
--- /dev/null
+++ b/test/CodeGen/arm64_vsri.c
@@ -0,0 +1,149 @@
+// RUN: %clang_cc1 -O1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -S -o - -emit-llvm %s | FileCheck %s
+// RUN: %clang_cc1 -O1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -S -o - %s | \
+// RUN:   FileCheck -check-prefix=CHECK_CODEGEN %s
+// REQUIRES: aarch64-registered-target
+
+// Test ARM64 SIMD vector shift right and insert: vsri[q]_n_*
+
+#include <arm_neon.h>
+
+int8x8_t test_vsri_n_s8(int8x8_t a1, int8x8_t a2) {
+  // CHECK: test_vsri_n_s8
+  return vsri_n_s8(a1, a2, 3);
+  // CHECK: llvm.aarch64.neon.vsri.v8i8
+  // CHECK_CODEGEN: sri.8b  v0, v1, #3
+}
+
+int16x4_t test_vsri_n_s16(int16x4_t a1, int16x4_t a2) {
+  // CHECK: test_vsri_n_s16
+  return vsri_n_s16(a1, a2, 3);
+  // CHECK: llvm.aarch64.neon.vsri.v4i16
+  // CHECK_CODEGEN: sri.4h  v0, v1, #3
+}
+
+int32x2_t test_vsri_n_s32(int32x2_t a1, int32x2_t a2) {
+  // CHECK: test_vsri_n_s32
+  return vsri_n_s32(a1, a2, 1);
+  // CHECK: llvm.aarch64.neon.vsri.v2i32
+  // CHECK_CODEGEN: sri.2s  v0, v1, #1
+}
+
+int64x1_t test_vsri_n_s64(int64x1_t a1, int64x1_t a2) {
+  // CHECK: test_vsri_n_s64
+  return vsri_n_s64(a1, a2, 1);
+  // CHECK: llvm.aarch64.neon.vsri.v1i64
+  // CHECK_CODEGEN: sri     d0, d1, #1
+}
+
+uint8x8_t test_vsri_n_u8(uint8x8_t a1, uint8x8_t a2) {
+  // CHECK: test_vsri_n_u8
+  return vsri_n_u8(a1, a2, 3);
+  // CHECK: llvm.aarch64.neon.vsri.v8i8
+  // CHECK_CODEGEN: sri.8b  v0, v1, #3
+}
+
+uint16x4_t test_vsri_n_u16(uint16x4_t a1, uint16x4_t a2) {
+  // CHECK: test_vsri_n_u16
+  return vsri_n_u16(a1, a2, 3);
+  // CHECK: llvm.aarch64.neon.vsri.v4i16
+  // CHECK_CODEGEN: sri.4h  v0, v1, #3
+}
+
+uint32x2_t test_vsri_n_u32(uint32x2_t a1, uint32x2_t a2) {
+  // CHECK: test_vsri_n_u32
+  return vsri_n_u32(a1, a2, 1);
+  // CHECK: llvm.aarch64.neon.vsri.v2i32
+  // CHECK_CODEGEN: sri.2s  v0, v1, #1
+}
+
+uint64x1_t test_vsri_n_u64(uint64x1_t a1, uint64x1_t a2) {
+  // CHECK: test_vsri_n_u64
+  return vsri_n_u64(a1, a2, 1);
+  // CHECK: llvm.aarch64.neon.vsri.v1i64
+  // CHECK_CODEGEN: sri     d0, d1, #1
+}
+
+poly8x8_t test_vsri_n_p8(poly8x8_t a1, poly8x8_t a2) {
+  // CHECK: test_vsri_n_p8
+  return vsri_n_p8(a1, a2, 1);
+  // CHECK: llvm.aarch64.neon.vsri.v8i8
+  // CHECK_CODEGEN: sri.8b  v0, v1, #1
+}
+
+poly16x4_t test_vsri_n_p16(poly16x4_t a1, poly16x4_t a2) {
+  // CHECK: test_vsri_n_p16
+  return vsri_n_p16(a1, a2, 1);
+  // CHECK: llvm.aarch64.neon.vsri.v4i16
+  // CHECK_CODEGEN: sri.4h  v0, v1, #1
+}
+
+int8x16_t test_vsriq_n_s8(int8x16_t a1, int8x16_t a2) {
+  // CHECK: test_vsriq_n_s8
+  return vsriq_n_s8(a1, a2, 3);
+  // CHECK: llvm.aarch64.neon.vsri.v16i8
+  // CHECK_CODEGEN: sri.16b v0, v1, #3
+}
+
+int16x8_t test_vsriq_n_s16(int16x8_t a1, int16x8_t a2) {
+  // CHECK: test_vsriq_n_s16
+  return vsriq_n_s16(a1, a2, 3);
+  // CHECK: llvm.aarch64.neon.vsri.v8i16
+  // CHECK_CODEGEN: sri.8h  v0, v1, #3
+}
+
+int32x4_t test_vsriq_n_s32(int32x4_t a1, int32x4_t a2) {
+  // CHECK: test_vsriq_n_s32
+  return vsriq_n_s32(a1, a2, 1);
+  // CHECK: llvm.aarch64.neon.vsri.v4i32
+  // CHECK_CODEGEN: sri.4s  v0, v1, #1
+}
+
+int64x2_t test_vsriq_n_s64(int64x2_t a1, int64x2_t a2) {
+  // CHECK: test_vsriq_n_s64
+  return vsriq_n_s64(a1, a2, 1);
+  // CHECK: llvm.aarch64.neon.vsri.v2i64
+  // CHECK_CODEGEN: sri.2d  v0, v1, #1
+}
+
+uint8x16_t test_vsriq_n_u8(uint8x16_t a1, uint8x16_t a2) {
+  // CHECK: test_vsriq_n_u8
+  return vsriq_n_u8(a1, a2, 3);
+  // CHECK: llvm.aarch64.neon.vsri.v16i8
+  // CHECK_CODEGEN: sri.16b v0, v1, #3
+}
+
+uint16x8_t test_vsriq_n_u16(uint16x8_t a1, uint16x8_t a2) {
+  // CHECK: test_vsriq_n_u16
+  return vsriq_n_u16(a1, a2, 3);
+  // CHECK: llvm.aarch64.neon.vsri.v8i16
+  // CHECK_CODEGEN: sri.8h  v0, v1, #3
+}
+
+uint32x4_t test_vsriq_n_u32(uint32x4_t a1, uint32x4_t a2) {
+  // CHECK: test_vsriq_n_u32
+  return vsriq_n_u32(a1, a2, 1);
+  // CHECK: llvm.aarch64.neon.vsri.v4i32
+  // CHECK_CODEGEN: sri.4s  v0, v1, #1
+}
+
+uint64x2_t test_vsriq_n_u64(uint64x2_t a1, uint64x2_t a2) {
+  // CHECK: test_vsriq_n_u64
+  return vsriq_n_u64(a1, a2, 1);
+  // CHECK: llvm.aarch64.neon.vsri.v2i64
+  // CHECK_CODEGEN: sri.2d  v0, v1, #1
+}
+
+poly8x16_t test_vsriq_n_p8(poly8x16_t a1, poly8x16_t a2) {
+  // CHECK: test_vsriq_n_p8
+  return vsriq_n_p8(a1, a2, 1);
+  // CHECK: llvm.aarch64.neon.vsri.v16i8
+  // CHECK_CODEGEN: sri.16b v0, v1, #1
+}
+
+poly16x8_t test_vsriq_n_p16(poly16x8_t a1, poly16x8_t a2) {
+  // CHECK: test_vsriq_n_p16
+  return vsriq_n_p16(a1, a2, 1);
+  // CHECK: llvm.aarch64.neon.vsri.v8i16
+  // CHECK_CODEGEN: sri.8h  v0, v1, #1
+}
+
diff --git a/test/CodeGen/arm64_vtst.c b/test/CodeGen/arm64_vtst.c
new file mode 100644
index 0000000..f40c62c
--- /dev/null
+++ b/test/CodeGen/arm64_vtst.c
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -O1 -triple arm64-apple-ios7 -target-feature +neon -ffreestanding -S -o - -emit-llvm %s | FileCheck %s
+// Test ARM64 SIMD comparison test intrinsics
+
+#include <arm_neon.h>
+
+uint64x2_t test_vtstq_s64(int64x2_t a1, int64x2_t a2) {
+  // CHECK: test_vtstq_s64
+  return vtstq_s64(a1, a2);
+  // CHECK: [[COMMONBITS:%[A-Za-z0-9.]+]] = and <2 x i64> %a1, %a2
+  // CHECK: [[MASK:%[A-Za-z0-9.]+]] = icmp ne <2 x i64> [[COMMONBITS]], zeroinitializer
+  // CHECK: [[RES:%[A-Za-z0-9.]+]] = sext <2 x i1> [[MASK]] to <2 x i64>
+  // CHECK: ret <2 x i64> [[RES]]
+}
+
+uint64x2_t test_vtstq_u64(uint64x2_t a1, uint64x2_t a2) {
+  // CHECK: test_vtstq_u64
+  return vtstq_u64(a1, a2);
+  // CHECK: [[COMMONBITS:%[A-Za-z0-9.]+]] = and <2 x i64> %a1, %a2
+  // CHECK: [[MASK:%[A-Za-z0-9.]+]] = icmp ne <2 x i64> [[COMMONBITS]], zeroinitializer
+  // CHECK: [[RES:%[A-Za-z0-9.]+]] = sext <2 x i1> [[MASK]] to <2 x i64>
+  // CHECK: ret <2 x i64> [[RES]]
+}
diff --git a/test/CodeGen/arm_acle.c b/test/CodeGen/arm_acle.c
new file mode 100644
index 0000000..8550c58
--- /dev/null
+++ b/test/CodeGen/arm_acle.c
@@ -0,0 +1,209 @@
+// RUN: %clang_cc1 -ffreestanding -triple armv8-eabi -target-cpu cortex-a57 -O -S -emit-llvm -o - %s | FileCheck %s -check-prefix=ARM -check-prefix=AArch32
+// RUN: %clang_cc1 -ffreestanding -triple aarch64-eabi -target-cpu cortex-a57 -target-feature +neon -target-feature +crc -target-feature +crypto -O -S -emit-llvm -o - %s | FileCheck %s -check-prefix=ARM -check-prefix=AArch64
+
+#include <arm_acle.h>
+
+/* 8 SYNCHRONIZATION, BARRIER AND HINT INTRINSICS */
+/* 8.3 Memory Barriers */
+// ARM-LABEL: test_dmb
+// AArch32: call void @llvm.arm.dmb(i32 1)
+// AArch64: call void @llvm.aarch64.dmb(i32 1)
+void test_dmb(void) {
+  __dmb(1);
+}
+
+// ARM-LABEL: test_dsb
+// AArch32: call void @llvm.arm.dsb(i32 2)
+// AArch64: call void @llvm.aarch64.dsb(i32 2)
+void test_dsb(void) {
+  __dsb(2);
+}
+
+// ARM-LABEL: test_isb
+// AArch32: call void @llvm.arm.isb(i32 3)
+// AArch64: call void @llvm.aarch64.isb(i32 3)
+void test_isb(void) {
+  __isb(3);
+}
+
+/* 8.4 Hints */
+// ARM-LABEL: test_yield
+// AArch32: call void @llvm.arm.hint(i32 1)
+// AArch64: call void @llvm.aarch64.hint(i32 1)
+void test_yield(void) {
+  __yield();
+}
+
+// ARM-LABEL: test_wfe
+// AArch32: call void @llvm.arm.hint(i32 2)
+// AArch64: call void @llvm.aarch64.hint(i32 2)
+void test_wfe(void) {
+  __wfe();
+}
+
+// ARM-LABEL: test_wfi
+// AArch32: call void @llvm.arm.hint(i32 3)
+// AArch64: call void @llvm.aarch64.hint(i32 3)
+void test_wfi(void) {
+  __wfi();
+}
+
+// ARM-LABEL: test_sev
+// AArch32: call void @llvm.arm.hint(i32 4)
+// AArch64: call void @llvm.aarch64.hint(i32 4)
+void test_sev(void) {
+  __sev();
+}
+
+// ARM-LABEL: test_sevl
+// AArch32: call void @llvm.arm.hint(i32 5)
+// AArch64: call void @llvm.aarch64.hint(i32 5)
+void test_sevl(void) {
+  __sevl();
+}
+
+/* 8.7 NOP */
+// ARM-LABEL: test_nop
+// AArch32: call void @llvm.arm.hint(i32 0)
+// AArch64: call void @llvm.aarch64.hint(i32 0)
+void test_nop(void) {
+  __nop();
+}
+
+/* 9 DATA-PROCESSING INTRINSICS */
+/* 9.2 Miscellaneous data-processing intrinsics */
+// ARM-LABEL: test_rev
+// ARM: call i32 @llvm.bswap.i32(i32 %t)
+uint32_t test_rev(uint32_t t) {
+  return __rev(t);
+}
+
+// ARM-LABEL: test_revl
+// AArch32: call i32 @llvm.bswap.i32(i32 %t)
+// AArch64: call i64 @llvm.bswap.i64(i64 %t)
+long test_revl(long t) {
+  return __revl(t);
+}
+
+// ARM-LABEL: test_revll
+// ARM: call i64 @llvm.bswap.i64(i64 %t)
+uint64_t test_revll(uint64_t t) {
+  return __revll(t);
+}
+
+// ARM-LABEL: test_clz
+// ARM: call i32 @llvm.ctlz.i32(i32 %t, i1 false)
+uint32_t test_clz(uint32_t t) {
+  return __clz(t);
+}
+
+// ARM-LABEL: test_clzl
+// AArch32: call i32 @llvm.ctlz.i32(i32 %t, i1 false)
+// AArch64: call i64 @llvm.ctlz.i64(i64 %t, i1 false)
+long test_clzl(long t) {
+  return __clzl(t);
+}
+
+// ARM-LABEL: test_clzll
+// ARM: call i64 @llvm.ctlz.i64(i64 %t, i1 false)
+uint64_t test_clzll(uint64_t t) {
+  return __clzll(t);
+}
+
+/* 9.4 Saturating intrinsics */
+#ifdef __ARM_32BIT_STATE
+
+/* 9.4.1 Width-specified saturation intrinsics */
+// AArch32-LABEL: test_ssat
+// AArch32: call i32 @llvm.arm.ssat(i32 %t, i32 1)
+int32_t test_ssat(int32_t t) {
+  return __ssat(t, 1);
+}
+
+// AArch32-LABEL: test_usat
+// AArch32: call i32 @llvm.arm.usat(i32 %t, i32 2)
+int32_t test_usat(int32_t t) {
+  return __usat(t, 2);
+}
+
+/* 9.4.2 Saturating addition and subtraction intrinsics */
+// AArch32-LABEL: test_qadd
+// AArch32: call i32 @llvm.arm.qadd(i32 %a, i32 %b)
+int32_t test_qadd(int32_t a, int32_t b) {
+  return __qadd(a, b);
+}
+
+// AArch32-LABEL: test_qsub
+// AArch32: call i32 @llvm.arm.qsub(i32 %a, i32 %b)
+int32_t test_qsub(int32_t a, int32_t b) {
+  return __qsub(a, b);
+}
+
+extern int32_t f();
+// AArch32-LABEL: test_qdbl
+// AArch32: [[VAR:%[a-z0-9]+]] = {{.*}} call {{.*}} @f
+// AArch32-NOT: call {{.*}} @f
+// AArch32: call i32 @llvm.arm.qadd(i32 [[VAR]], i32 [[VAR]])
+int32_t test_qdbl() {
+  return __qdbl(f());
+}
+#endif
+
+/* 9.7 CRC32 intrinsics */
+// ARM-LABEL: test_crc32b
+// AArch32: call i32 @llvm.arm.crc32b
+// AArch64: call i32 @llvm.aarch64.crc32b
+uint32_t test_crc32b(uint32_t a, uint8_t b) {
+  return __crc32b(a, b);
+}
+
+// ARM-LABEL: test_crc32h
+// AArch32: call i32 @llvm.arm.crc32h
+// AArch64: call i32 @llvm.aarch64.crc32h
+uint32_t test_crc32h(uint32_t a, uint16_t b) {
+  return __crc32h(a, b);
+}
+
+// ARM-LABEL: test_crc32w
+// AArch32: call i32 @llvm.arm.crc32w
+// AArch64: call i32 @llvm.aarch64.crc32w
+uint32_t test_crc32w(uint32_t a, uint32_t b) {
+  return __crc32w(a, b);
+}
+
+// ARM-LABEL: test_crc32d
+// AArch32: call i32 @llvm.arm.crc32w
+// AArch32: call i32 @llvm.arm.crc32w
+// AArch64: call i32 @llvm.aarch64.crc32x
+uint32_t test_crc32d(uint32_t a, uint64_t b) {
+  return __crc32d(a, b);
+}
+
+// ARM-LABEL: test_crc32cb
+// AArch32: call i32 @llvm.arm.crc32cb
+// AArch64: call i32 @llvm.aarch64.crc32cb
+uint32_t test_crc32cb(uint32_t a, uint8_t b) {
+  return __crc32cb(a, b);
+}
+
+// ARM-LABEL: test_crc32ch
+// AArch32: call i32 @llvm.arm.crc32ch
+// AArch64: call i32 @llvm.aarch64.crc32ch
+uint32_t test_crc32ch(uint32_t a, uint16_t b) {
+  return __crc32ch(a, b);
+}
+
+// ARM-LABEL: test_crc32cw
+// AArch32: call i32 @llvm.arm.crc32cw
+// AArch64: call i32 @llvm.aarch64.crc32cw
+uint32_t test_crc32cw(uint32_t a, uint32_t b) {
+  return __crc32cw(a, b);
+}
+
+// ARM-LABEL: test_crc32cd
+// AArch32: call i32 @llvm.arm.crc32cw
+// AArch32: call i32 @llvm.arm.crc32cw
+// AArch64: call i32 @llvm.aarch64.crc32cx
+uint32_t test_crc32cd(uint32_t a, uint64_t b) {
+  return __crc32cd(a, b);
+}
diff --git a/test/CodeGen/arm_neon_intrinsics.c b/test/CodeGen/arm_neon_intrinsics.c
index 1d76e8a..a084d8b 100644
--- a/test/CodeGen/arm_neon_intrinsics.c
+++ b/test/CodeGen/arm_neon_intrinsics.c
@@ -1,11633 +1,11673 @@
 // RUN: %clang_cc1 -triple thumbv7s-apple-darwin -target-abi apcs-gnu\
 // RUN:  -target-cpu swift -ffreestanding -Os -S -o - %s\
-// RUN:  | FileCheck %s
+// RUN:  | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-SWIFT
+// RUN: %clang_cc1 -triple armv8-linux-gnu \
+// RUN:  -target-cpu cortex-a57 -mfloat-abi soft -ffreestanding -Os -S -o - %s\
+// RUN:  | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-A57
 
 // REQUIRES: long_tests
 
 #include <arm_neon.h>
 
-// CHECK: test_vaba_s8
+// CHECK-LABEL: test_vaba_s8
 // CHECK: vaba.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vaba_s8(int8x8_t a, int8x8_t b, int8x8_t c) {
   return vaba_s8(a, b, c);
 }
 
-// CHECK: test_vaba_s16
+// CHECK-LABEL: test_vaba_s16
 // CHECK: vaba.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vaba_s16(int16x4_t a, int16x4_t b, int16x4_t c) {
   return vaba_s16(a, b, c);
 }
 
-// CHECK: test_vaba_s32
+// CHECK-LABEL: test_vaba_s32
 // CHECK: vaba.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vaba_s32(int32x2_t a, int32x2_t b, int32x2_t c) {
   return vaba_s32(a, b, c);
 }
 
-// CHECK: test_vaba_u8
+// CHECK-LABEL: test_vaba_u8
 // CHECK: vaba.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vaba_u8(uint8x8_t a, uint8x8_t b, uint8x8_t c) {
   return vaba_u8(a, b, c);
 }
 
-// CHECK: test_vaba_u16
+// CHECK-LABEL: test_vaba_u16
 // CHECK: vaba.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vaba_u16(uint16x4_t a, uint16x4_t b, uint16x4_t c) {
   return vaba_u16(a, b, c);
 }
 
-// CHECK: test_vaba_u32
+// CHECK-LABEL: test_vaba_u32
 // CHECK: vaba.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vaba_u32(uint32x2_t a, uint32x2_t b, uint32x2_t c) {
   return vaba_u32(a, b, c);
 }
 
-// CHECK: test_vabaq_s8
+// CHECK-LABEL: test_vabaq_s8
 // CHECK: vaba.s8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vabaq_s8(int8x16_t a, int8x16_t b, int8x16_t c) {
   return vabaq_s8(a, b, c);
 }
 
-// CHECK: test_vabaq_s16
+// CHECK-LABEL: test_vabaq_s16
 // CHECK: vaba.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vabaq_s16(int16x8_t a, int16x8_t b, int16x8_t c) {
   return vabaq_s16(a, b, c);
 }
 
-// CHECK: test_vabaq_s32
+// CHECK-LABEL: test_vabaq_s32
 // CHECK: vaba.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vabaq_s32(int32x4_t a, int32x4_t b, int32x4_t c) {
   return vabaq_s32(a, b, c);
 }
 
-// CHECK: test_vabaq_u8
+// CHECK-LABEL: test_vabaq_u8
 // CHECK: vaba.u8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vabaq_u8(uint8x16_t a, uint8x16_t b, uint8x16_t c) {
   return vabaq_u8(a, b, c);
 }
 
-// CHECK: test_vabaq_u16
+// CHECK-LABEL: test_vabaq_u16
 // CHECK: vaba.u16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vabaq_u16(uint16x8_t a, uint16x8_t b, uint16x8_t c) {
   return vabaq_u16(a, b, c);
 }
 
-// CHECK: test_vabaq_u32
+// CHECK-LABEL: test_vabaq_u32
 // CHECK: vaba.u32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vabaq_u32(uint32x4_t a, uint32x4_t b, uint32x4_t c) {
   return vabaq_u32(a, b, c);
 }
 
 
-// CHECK: test_vabal_s8
+// CHECK-LABEL: test_vabal_s8
 // CHECK: vabal.s8 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x8_t test_vabal_s8(int16x8_t a, int8x8_t b, int8x8_t c) {
   return vabal_s8(a, b, c);
 }
 
-// CHECK: test_vabal_s16
+// CHECK-LABEL: test_vabal_s16
 // CHECK: vabal.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vabal_s16(int32x4_t a, int16x4_t b, int16x4_t c) {
   return vabal_s16(a, b, c);
 }
 
-// CHECK: test_vabal_s32
+// CHECK-LABEL: test_vabal_s32
 // CHECK: vabal.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vabal_s32(int64x2_t a, int32x2_t b, int32x2_t c) {
   return vabal_s32(a, b, c);
 }
 
-// CHECK: test_vabal_u8
+// CHECK-LABEL: test_vabal_u8
 // CHECK: vabal.u8 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x8_t test_vabal_u8(uint16x8_t a, uint8x8_t b, uint8x8_t c) {
   return vabal_u8(a, b, c);
 }
 
-// CHECK: test_vabal_u16
+// CHECK-LABEL: test_vabal_u16
 // CHECK: vabal.u16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x4_t test_vabal_u16(uint32x4_t a, uint16x4_t b, uint16x4_t c) {
   return vabal_u16(a, b, c);
 }
 
-// CHECK: test_vabal_u32
+// CHECK-LABEL: test_vabal_u32
 // CHECK: vabal.u32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x2_t test_vabal_u32(uint64x2_t a, uint32x2_t b, uint32x2_t c) {
   return vabal_u32(a, b, c);
 }
 
 
-// CHECK: test_vabd_s8
+// CHECK-LABEL: test_vabd_s8
 // CHECK: vabd.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vabd_s8(int8x8_t a, int8x8_t b) {
   return vabd_s8(a, b);
 }
 
-// CHECK: test_vabd_s16
+// CHECK-LABEL: test_vabd_s16
 // CHECK: vabd.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vabd_s16(int16x4_t a, int16x4_t b) {
   return vabd_s16(a, b);
 }
 
-// CHECK: test_vabd_s32
+// CHECK-LABEL: test_vabd_s32
 // CHECK: vabd.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vabd_s32(int32x2_t a, int32x2_t b) {
   return vabd_s32(a, b);
 }
 
-// CHECK: test_vabd_u8
+// CHECK-LABEL: test_vabd_u8
 // CHECK: vabd.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vabd_u8(uint8x8_t a, uint8x8_t b) {
   return vabd_u8(a, b);
 }
 
-// CHECK: test_vabd_u16
+// CHECK-LABEL: test_vabd_u16
 // CHECK: vabd.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vabd_u16(uint16x4_t a, uint16x4_t b) {
   return vabd_u16(a, b);
 }
 
-// CHECK: test_vabd_u32
+// CHECK-LABEL: test_vabd_u32
 // CHECK: vabd.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vabd_u32(uint32x2_t a, uint32x2_t b) {
   return vabd_u32(a, b);
 }
 
-// CHECK: test_vabd_f32
+// CHECK-LABEL: test_vabd_f32
 // CHECK: vabd.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vabd_f32(float32x2_t a, float32x2_t b) {
   return vabd_f32(a, b);
 }
 
-// CHECK: test_vabdq_s8
+// CHECK-LABEL: test_vabdq_s8
 // CHECK: vabd.s8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vabdq_s8(int8x16_t a, int8x16_t b) {
   return vabdq_s8(a, b);
 }
 
-// CHECK: test_vabdq_s16
+// CHECK-LABEL: test_vabdq_s16
 // CHECK: vabd.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vabdq_s16(int16x8_t a, int16x8_t b) {
   return vabdq_s16(a, b);
 }
 
-// CHECK: test_vabdq_s32
+// CHECK-LABEL: test_vabdq_s32
 // CHECK: vabd.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vabdq_s32(int32x4_t a, int32x4_t b) {
   return vabdq_s32(a, b);
 }
 
-// CHECK: test_vabdq_u8
+// CHECK-LABEL: test_vabdq_u8
 // CHECK: vabd.u8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vabdq_u8(uint8x16_t a, uint8x16_t b) {
   return vabdq_u8(a, b);
 }
 
-// CHECK: test_vabdq_u16
+// CHECK-LABEL: test_vabdq_u16
 // CHECK: vabd.u16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vabdq_u16(uint16x8_t a, uint16x8_t b) {
   return vabdq_u16(a, b);
 }
 
-// CHECK: test_vabdq_u32
+// CHECK-LABEL: test_vabdq_u32
 // CHECK: vabd.u32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vabdq_u32(uint32x4_t a, uint32x4_t b) {
   return vabdq_u32(a, b);
 }
 
-// CHECK: test_vabdq_f32
+// CHECK-LABEL: test_vabdq_f32
 // CHECK: vabd.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vabdq_f32(float32x4_t a, float32x4_t b) {
   return vabdq_f32(a, b);
 }
 
 
-// CHECK: test_vabdl_s8
+// CHECK-LABEL: test_vabdl_s8
 // CHECK: vabdl.s8 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x8_t test_vabdl_s8(int8x8_t a, int8x8_t b) {
   return vabdl_s8(a, b);
 }
 
-// CHECK: test_vabdl_s16
+// CHECK-LABEL: test_vabdl_s16
 // CHECK: vabdl.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vabdl_s16(int16x4_t a, int16x4_t b) {
   return vabdl_s16(a, b);
 }
 
-// CHECK: test_vabdl_s32
+// CHECK-LABEL: test_vabdl_s32
 // CHECK: vabdl.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vabdl_s32(int32x2_t a, int32x2_t b) {
   return vabdl_s32(a, b);
 }
 
-// CHECK: test_vabdl_u8
+// CHECK-LABEL: test_vabdl_u8
 // CHECK: vabdl.u8 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x8_t test_vabdl_u8(uint8x8_t a, uint8x8_t b) {
   return vabdl_u8(a, b);
 }
 
-// CHECK: test_vabdl_u16
+// CHECK-LABEL: test_vabdl_u16
 // CHECK: vabdl.u16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x4_t test_vabdl_u16(uint16x4_t a, uint16x4_t b) {
   return vabdl_u16(a, b);
 }
 
-// CHECK: test_vabdl_u32
+// CHECK-LABEL: test_vabdl_u32
 // CHECK: vabdl.u32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x2_t test_vabdl_u32(uint32x2_t a, uint32x2_t b) {
   return vabdl_u32(a, b);
 }
 
 
-// CHECK: test_vabs_s8
+// CHECK-LABEL: test_vabs_s8
 // CHECK: vabs.s8 d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vabs_s8(int8x8_t a) {
   return vabs_s8(a);
 }
 
-// CHECK: test_vabs_s16
+// CHECK-LABEL: test_vabs_s16
 // CHECK: vabs.s16 d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vabs_s16(int16x4_t a) {
   return vabs_s16(a);
 }
 
-// CHECK: test_vabs_s32
+// CHECK-LABEL: test_vabs_s32
 // CHECK: vabs.s32 d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vabs_s32(int32x2_t a) {
   return vabs_s32(a);
 }
 
-// CHECK: test_vabs_f32
+// CHECK-LABEL: test_vabs_f32
 // CHECK: vabs.f32 d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vabs_f32(float32x2_t a) {
   return vabs_f32(a);
 }
 
-// CHECK: test_vabsq_s8
+// CHECK-LABEL: test_vabsq_s8
 // CHECK: vabs.s8 q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vabsq_s8(int8x16_t a) {
   return vabsq_s8(a);
 }
 
-// CHECK: test_vabsq_s16
+// CHECK-LABEL: test_vabsq_s16
 // CHECK: vabs.s16 q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vabsq_s16(int16x8_t a) {
   return vabsq_s16(a);
 }
 
-// CHECK: test_vabsq_s32
+// CHECK-LABEL: test_vabsq_s32
 // CHECK: vabs.s32 q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vabsq_s32(int32x4_t a) {
   return vabsq_s32(a);
 }
 
-// CHECK: test_vabsq_f32
+// CHECK-LABEL: test_vabsq_f32
 // CHECK: vabs.f32 q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vabsq_f32(float32x4_t a) {
   return vabsq_f32(a);
 }
 
 
-// CHECK: test_vadd_s8
+// CHECK-LABEL: test_vadd_s8
 // CHECK: vadd.i8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vadd_s8(int8x8_t a, int8x8_t b) {
   return vadd_s8(a, b);
 }
 
-// CHECK: test_vadd_s16
+// CHECK-LABEL: test_vadd_s16
 // CHECK: vadd.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vadd_s16(int16x4_t a, int16x4_t b) {
   return vadd_s16(a, b);
 }
 
-// CHECK: test_vadd_s32
+// CHECK-LABEL: test_vadd_s32
 // CHECK: vadd.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vadd_s32(int32x2_t a, int32x2_t b) {
   return vadd_s32(a, b);
 }
 
-// CHECK: test_vadd_s64
+// CHECK-LABEL: test_vadd_s64
 // CHECK: vadd.i64 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x1_t test_vadd_s64(int64x1_t a, int64x1_t b) {
   return vadd_s64(a, b);
 }
 
-// CHECK: test_vadd_f32
+// CHECK-LABEL: test_vadd_f32
 // CHECK: vadd.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vadd_f32(float32x2_t a, float32x2_t b) {
   return vadd_f32(a, b);
 }
 
-// CHECK: test_vadd_u8
+// CHECK-LABEL: test_vadd_u8
 // CHECK: vadd.i8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vadd_u8(uint8x8_t a, uint8x8_t b) {
   return vadd_u8(a, b);
 }
 
-// CHECK: test_vadd_u16
+// CHECK-LABEL: test_vadd_u16
 // CHECK: vadd.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vadd_u16(uint16x4_t a, uint16x4_t b) {
   return vadd_u16(a, b);
 }
 
-// CHECK: test_vadd_u32
+// CHECK-LABEL: test_vadd_u32
 // CHECK: vadd.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vadd_u32(uint32x2_t a, uint32x2_t b) {
   return vadd_u32(a, b);
 }
 
-// CHECK: test_vadd_u64
+// CHECK-LABEL: test_vadd_u64
 // CHECK: vadd.i64 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x1_t test_vadd_u64(uint64x1_t a, uint64x1_t b) {
   return vadd_u64(a, b);
 }
 
-// CHECK: test_vaddq_s8
+// CHECK-LABEL: test_vaddq_s8
 // CHECK: vadd.i8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vaddq_s8(int8x16_t a, int8x16_t b) {
   return vaddq_s8(a, b);
 }
 
-// CHECK: test_vaddq_s16
+// CHECK-LABEL: test_vaddq_s16
 // CHECK: vadd.i16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vaddq_s16(int16x8_t a, int16x8_t b) {
   return vaddq_s16(a, b);
 }
 
-// CHECK: test_vaddq_s32
+// CHECK-LABEL: test_vaddq_s32
 // CHECK: vadd.i32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vaddq_s32(int32x4_t a, int32x4_t b) {
   return vaddq_s32(a, b);
 }
 
-// CHECK: test_vaddq_s64
+// CHECK-LABEL: test_vaddq_s64
 // CHECK: vadd.i64 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int64x2_t test_vaddq_s64(int64x2_t a, int64x2_t b) {
   return vaddq_s64(a, b);
 }
 
-// CHECK: test_vaddq_f32
+// CHECK-LABEL: test_vaddq_f32
 // CHECK: vadd.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vaddq_f32(float32x4_t a, float32x4_t b) {
   return vaddq_f32(a, b);
 }
 
-// CHECK: test_vaddq_u8
+// CHECK-LABEL: test_vaddq_u8
 // CHECK: vadd.i8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vaddq_u8(uint8x16_t a, uint8x16_t b) {
   return vaddq_u8(a, b);
 }
 
-// CHECK: test_vaddq_u16
+// CHECK-LABEL: test_vaddq_u16
 // CHECK: vadd.i16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vaddq_u16(uint16x8_t a, uint16x8_t b) {
   return vaddq_u16(a, b);
 }
 
-// CHECK: test_vaddq_u32
+// CHECK-LABEL: test_vaddq_u32
 // CHECK: vadd.i32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vaddq_u32(uint32x4_t a, uint32x4_t b) {
   return vaddq_u32(a, b);
 }
 
-// CHECK: test_vaddq_u64
+// CHECK-LABEL: test_vaddq_u64
 // CHECK: vadd.i64 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint64x2_t test_vaddq_u64(uint64x2_t a, uint64x2_t b) {
   return vaddq_u64(a, b);
 }
 
 
-// CHECK: test_vaddhn_s16
+// CHECK-LABEL: test_vaddhn_s16
 // CHECK: vaddhn.i16 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x8_t test_vaddhn_s16(int16x8_t a, int16x8_t b) {
   return vaddhn_s16(a, b);
 }
 
-// CHECK: test_vaddhn_s32
+// CHECK-LABEL: test_vaddhn_s32
 // CHECK: vaddhn.i32 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x4_t test_vaddhn_s32(int32x4_t a, int32x4_t b) {
   return vaddhn_s32(a, b);
 }
 
-// CHECK: test_vaddhn_s64
+// CHECK-LABEL: test_vaddhn_s64
 // CHECK: vaddhn.i64 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x2_t test_vaddhn_s64(int64x2_t a, int64x2_t b) {
   return vaddhn_s64(a, b);
 }
 
-// CHECK: test_vaddhn_u16
+// CHECK-LABEL: test_vaddhn_u16
 // CHECK: vaddhn.i16 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x8_t test_vaddhn_u16(uint16x8_t a, uint16x8_t b) {
   return vaddhn_u16(a, b);
 }
 
-// CHECK: test_vaddhn_u32
+// CHECK-LABEL: test_vaddhn_u32
 // CHECK: vaddhn.i32 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x4_t test_vaddhn_u32(uint32x4_t a, uint32x4_t b) {
   return vaddhn_u32(a, b);
 }
 
-// CHECK: test_vaddhn_u64
+// CHECK-LABEL: test_vaddhn_u64
 // CHECK: vaddhn.i64 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x2_t test_vaddhn_u64(uint64x2_t a, uint64x2_t b) {
   return vaddhn_u64(a, b);
 }
 
 
-// CHECK: test_vaddl_s8
+// CHECK-LABEL: test_vaddl_s8
 // CHECK: vaddl.s8 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x8_t test_vaddl_s8(int8x8_t a, int8x8_t b) {
   return vaddl_s8(a, b);
 }
 
-// CHECK: test_vaddl_s16
+// CHECK-LABEL: test_vaddl_s16
 // CHECK: vaddl.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vaddl_s16(int16x4_t a, int16x4_t b) {
   return vaddl_s16(a, b);
 }
 
-// CHECK: test_vaddl_s32
+// CHECK-LABEL: test_vaddl_s32
 // CHECK: vaddl.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vaddl_s32(int32x2_t a, int32x2_t b) {
   return vaddl_s32(a, b);
 }
 
-// CHECK: test_vaddl_u8
+// CHECK-LABEL: test_vaddl_u8
 // CHECK: vaddl.u8 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x8_t test_vaddl_u8(uint8x8_t a, uint8x8_t b) {
   return vaddl_u8(a, b);
 }
 
-// CHECK: test_vaddl_u16
+// CHECK-LABEL: test_vaddl_u16
 // CHECK: vaddl.u16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x4_t test_vaddl_u16(uint16x4_t a, uint16x4_t b) {
   return vaddl_u16(a, b);
 }
 
-// CHECK: test_vaddl_u32
+// CHECK-LABEL: test_vaddl_u32
 // CHECK: vaddl.u32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x2_t test_vaddl_u32(uint32x2_t a, uint32x2_t b) {
   return vaddl_u32(a, b);
 }
 
 
-// CHECK: test_vaddw_s8
+// CHECK-LABEL: test_vaddw_s8
 // CHECK: vaddw.s8 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}
 int16x8_t test_vaddw_s8(int16x8_t a, int8x8_t b) {
   return vaddw_s8(a, b);
 }
 
-// CHECK: test_vaddw_s16
+// CHECK-LABEL: test_vaddw_s16
 // CHECK: vaddw.s16 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vaddw_s16(int32x4_t a, int16x4_t b) {
   return vaddw_s16(a, b);
 }
 
-// CHECK: test_vaddw_s32
+// CHECK-LABEL: test_vaddw_s32
 // CHECK: vaddw.s32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vaddw_s32(int64x2_t a, int32x2_t b) {
   return vaddw_s32(a, b);
 }
 
-// CHECK: test_vaddw_u8
+// CHECK-LABEL: test_vaddw_u8
 // CHECK: vaddw.u8 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}
 uint16x8_t test_vaddw_u8(uint16x8_t a, uint8x8_t b) {
   return vaddw_u8(a, b);
 }
 
-// CHECK: test_vaddw_u16
+// CHECK-LABEL: test_vaddw_u16
 // CHECK: vaddw.u16 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}
 uint32x4_t test_vaddw_u16(uint32x4_t a, uint16x4_t b) {
   return vaddw_u16(a, b);
 }
 
-// CHECK: test_vaddw_u32
+// CHECK-LABEL: test_vaddw_u32
 // CHECK: vaddw.u32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}
 uint64x2_t test_vaddw_u32(uint64x2_t a, uint32x2_t b) {
   return vaddw_u32(a, b);
 }
 
 
-// CHECK: test_vand_s8
+// CHECK-LABEL: test_vand_s8
 // CHECK: vand d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vand_s8(int8x8_t a, int8x8_t b) {
   return vand_s8(a, b);
 }
 
-// CHECK: test_vand_s16
+// CHECK-LABEL: test_vand_s16
 // CHECK: vand d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vand_s16(int16x4_t a, int16x4_t b) {
   return vand_s16(a, b);
 }
 
-// CHECK: test_vand_s32
+// CHECK-LABEL: test_vand_s32
 // CHECK: vand d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vand_s32(int32x2_t a, int32x2_t b) {
   return vand_s32(a, b);
 }
 
-// CHECK: test_vand_s64
+// CHECK-LABEL: test_vand_s64
 // CHECK: vand d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x1_t test_vand_s64(int64x1_t a, int64x1_t b) {
   return vand_s64(a, b);
 }
 
-// CHECK: test_vand_u8
+// CHECK-LABEL: test_vand_u8
 // CHECK: vand d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vand_u8(uint8x8_t a, uint8x8_t b) {
   return vand_u8(a, b);
 }
 
-// CHECK: test_vand_u16
+// CHECK-LABEL: test_vand_u16
 // CHECK: vand d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vand_u16(uint16x4_t a, uint16x4_t b) {
   return vand_u16(a, b);
 }
 
-// CHECK: test_vand_u32
+// CHECK-LABEL: test_vand_u32
 // CHECK: vand d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vand_u32(uint32x2_t a, uint32x2_t b) {
   return vand_u32(a, b);
 }
 
-// CHECK: test_vand_u64
+// CHECK-LABEL: test_vand_u64
 // CHECK: vand d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x1_t test_vand_u64(uint64x1_t a, uint64x1_t b) {
   return vand_u64(a, b);
 }
 
-// CHECK: test_vandq_s8
+// CHECK-LABEL: test_vandq_s8
 // CHECK: vand q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vandq_s8(int8x16_t a, int8x16_t b) {
   return vandq_s8(a, b);
 }
 
-// CHECK: test_vandq_s16
+// CHECK-LABEL: test_vandq_s16
 // CHECK: vand q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vandq_s16(int16x8_t a, int16x8_t b) {
   return vandq_s16(a, b);
 }
 
-// CHECK: test_vandq_s32
+// CHECK-LABEL: test_vandq_s32
 // CHECK: vand q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vandq_s32(int32x4_t a, int32x4_t b) {
   return vandq_s32(a, b);
 }
 
-// CHECK: test_vandq_s64
+// CHECK-LABEL: test_vandq_s64
 // CHECK: vand q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int64x2_t test_vandq_s64(int64x2_t a, int64x2_t b) {
   return vandq_s64(a, b);
 }
 
-// CHECK: test_vandq_u8
+// CHECK-LABEL: test_vandq_u8
 // CHECK: vand q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vandq_u8(uint8x16_t a, uint8x16_t b) {
   return vandq_u8(a, b);
 }
 
-// CHECK: test_vandq_u16
+// CHECK-LABEL: test_vandq_u16
 // CHECK: vand q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vandq_u16(uint16x8_t a, uint16x8_t b) {
   return vandq_u16(a, b);
 }
 
-// CHECK: test_vandq_u32
+// CHECK-LABEL: test_vandq_u32
 // CHECK: vand q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vandq_u32(uint32x4_t a, uint32x4_t b) {
   return vandq_u32(a, b);
 }
 
-// CHECK: test_vandq_u64
+// CHECK-LABEL: test_vandq_u64
 // CHECK: vand q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint64x2_t test_vandq_u64(uint64x2_t a, uint64x2_t b) {
   return vandq_u64(a, b);
 }
 
 
-// CHECK: test_vbic_s8
+// CHECK-LABEL: test_vbic_s8
 // CHECK: vbic d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vbic_s8(int8x8_t a, int8x8_t b) {
   return vbic_s8(a, b);
 }
 
-// CHECK: test_vbic_s16
+// CHECK-LABEL: test_vbic_s16
 // CHECK: vbic d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vbic_s16(int16x4_t a, int16x4_t b) {
   return vbic_s16(a, b);
 }
 
-// CHECK: test_vbic_s32
+// CHECK-LABEL: test_vbic_s32
 // CHECK: vbic d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vbic_s32(int32x2_t a, int32x2_t b) {
   return vbic_s32(a, b);
 }
 
-// CHECK: test_vbic_s64
+// CHECK-LABEL: test_vbic_s64
 // CHECK: vbic d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x1_t test_vbic_s64(int64x1_t a, int64x1_t b) {
   return vbic_s64(a, b);
 }
 
-// CHECK: test_vbic_u8
+// CHECK-LABEL: test_vbic_u8
 // CHECK: vbic d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vbic_u8(uint8x8_t a, uint8x8_t b) {
   return vbic_u8(a, b);
 }
 
-// CHECK: test_vbic_u16
+// CHECK-LABEL: test_vbic_u16
 // CHECK: vbic d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vbic_u16(uint16x4_t a, uint16x4_t b) {
   return vbic_u16(a, b);
 }
 
-// CHECK: test_vbic_u32
+// CHECK-LABEL: test_vbic_u32
 // CHECK: vbic d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vbic_u32(uint32x2_t a, uint32x2_t b) {
   return vbic_u32(a, b);
 }
 
-// CHECK: test_vbic_u64
+// CHECK-LABEL: test_vbic_u64
 // CHECK: vbic d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x1_t test_vbic_u64(uint64x1_t a, uint64x1_t b) {
   return vbic_u64(a, b);
 }
 
-// CHECK: test_vbicq_s8
+// CHECK-LABEL: test_vbicq_s8
 // CHECK: vbic q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vbicq_s8(int8x16_t a, int8x16_t b) {
   return vbicq_s8(a, b);
 }
 
-// CHECK: test_vbicq_s16
+// CHECK-LABEL: test_vbicq_s16
 // CHECK: vbic q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vbicq_s16(int16x8_t a, int16x8_t b) {
   return vbicq_s16(a, b);
 }
 
-// CHECK: test_vbicq_s32
+// CHECK-LABEL: test_vbicq_s32
 // CHECK: vbic q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vbicq_s32(int32x4_t a, int32x4_t b) {
   return vbicq_s32(a, b);
 }
 
-// CHECK: test_vbicq_s64
+// CHECK-LABEL: test_vbicq_s64
 // CHECK: vbic q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int64x2_t test_vbicq_s64(int64x2_t a, int64x2_t b) {
   return vbicq_s64(a, b);
 }
 
-// CHECK: test_vbicq_u8
+// CHECK-LABEL: test_vbicq_u8
 // CHECK: vbic q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vbicq_u8(uint8x16_t a, uint8x16_t b) {
   return vbicq_u8(a, b);
 }
 
-// CHECK: test_vbicq_u16
+// CHECK-LABEL: test_vbicq_u16
 // CHECK: vbic q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vbicq_u16(uint16x8_t a, uint16x8_t b) {
   return vbicq_u16(a, b);
 }
 
-// CHECK: test_vbicq_u32
+// CHECK-LABEL: test_vbicq_u32
 // CHECK: vbic q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vbicq_u32(uint32x4_t a, uint32x4_t b) {
   return vbicq_u32(a, b);
 }
 
-// CHECK: test_vbicq_u64
+// CHECK-LABEL: test_vbicq_u64
 // CHECK: vbic q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint64x2_t test_vbicq_u64(uint64x2_t a, uint64x2_t b) {
   return vbicq_u64(a, b);
 }
 
 
-// CHECK: test_vbsl_s8
+// CHECK-LABEL: test_vbsl_s8
 // CHECK: vbsl d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vbsl_s8(uint8x8_t a, int8x8_t b, int8x8_t c) {
   return vbsl_s8(a, b, c);
 }
 
-// CHECK: test_vbsl_s16
+// CHECK-LABEL: test_vbsl_s16
 // CHECK: vbsl d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vbsl_s16(uint16x4_t a, int16x4_t b, int16x4_t c) {
   return vbsl_s16(a, b, c);
 }
 
-// CHECK: test_vbsl_s32
+// CHECK-LABEL: test_vbsl_s32
 // CHECK: vbsl d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vbsl_s32(uint32x2_t a, int32x2_t b, int32x2_t c) {
   return vbsl_s32(a, b, c);
 }
 
-// CHECK: test_vbsl_s64
+// CHECK-LABEL: test_vbsl_s64
 // CHECK: vbsl d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x1_t test_vbsl_s64(uint64x1_t a, int64x1_t b, int64x1_t c) {
   return vbsl_s64(a, b, c);
 }
 
-// CHECK: test_vbsl_u8
+// CHECK-LABEL: test_vbsl_u8
 // CHECK: vbsl d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vbsl_u8(uint8x8_t a, uint8x8_t b, uint8x8_t c) {
   return vbsl_u8(a, b, c);
 }
 
-// CHECK: test_vbsl_u16
+// CHECK-LABEL: test_vbsl_u16
 // CHECK: vbsl d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vbsl_u16(uint16x4_t a, uint16x4_t b, uint16x4_t c) {
   return vbsl_u16(a, b, c);
 }
 
-// CHECK: test_vbsl_u32
+// CHECK-LABEL: test_vbsl_u32
 // CHECK: vbsl d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vbsl_u32(uint32x2_t a, uint32x2_t b, uint32x2_t c) {
   return vbsl_u32(a, b, c);
 }
 
-// CHECK: test_vbsl_u64
+// CHECK-LABEL: test_vbsl_u64
 // CHECK: vbsl d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x1_t test_vbsl_u64(uint64x1_t a, uint64x1_t b, uint64x1_t c) {
   return vbsl_u64(a, b, c);
 }
 
-// CHECK: test_vbsl_f32
+// CHECK-LABEL: test_vbsl_f32
 // CHECK: vbsl d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vbsl_f32(uint32x2_t a, float32x2_t b, float32x2_t c) {
   return vbsl_f32(a, b, c);
 }
 
-// CHECK: test_vbsl_p8
+// CHECK-LABEL: test_vbsl_p8
 // CHECK: vbsl d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 poly8x8_t test_vbsl_p8(uint8x8_t a, poly8x8_t b, poly8x8_t c) {
   return vbsl_p8(a, b, c);
 }
 
-// CHECK: test_vbsl_p16
+// CHECK-LABEL: test_vbsl_p16
 // CHECK: vbsl d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 poly16x4_t test_vbsl_p16(uint16x4_t a, poly16x4_t b, poly16x4_t c) {
   return vbsl_p16(a, b, c);
 }
 
-// CHECK: test_vbslq_s8
+// CHECK-LABEL: test_vbslq_s8
 // CHECK: vbsl q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vbslq_s8(uint8x16_t a, int8x16_t b, int8x16_t c) {
   return vbslq_s8(a, b, c);
 }
 
-// CHECK: test_vbslq_s16
+// CHECK-LABEL: test_vbslq_s16
 // CHECK: vbsl q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vbslq_s16(uint16x8_t a, int16x8_t b, int16x8_t c) {
   return vbslq_s16(a, b, c);
 }
 
-// CHECK: test_vbslq_s32
+// CHECK-LABEL: test_vbslq_s32
 // CHECK: vbsl q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vbslq_s32(uint32x4_t a, int32x4_t b, int32x4_t c) {
   return vbslq_s32(a, b, c);
 }
 
-// CHECK: test_vbslq_s64
+// CHECK-LABEL: test_vbslq_s64
 // CHECK: vbsl q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int64x2_t test_vbslq_s64(uint64x2_t a, int64x2_t b, int64x2_t c) {
   return vbslq_s64(a, b, c);
 }
 
-// CHECK: test_vbslq_u8
+// CHECK-LABEL: test_vbslq_u8
 // CHECK: vbsl q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vbslq_u8(uint8x16_t a, uint8x16_t b, uint8x16_t c) {
   return vbslq_u8(a, b, c);
 }
 
-// CHECK: test_vbslq_u16
+// CHECK-LABEL: test_vbslq_u16
 // CHECK: vbsl q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vbslq_u16(uint16x8_t a, uint16x8_t b, uint16x8_t c) {
   return vbslq_u16(a, b, c);
 }
 
-// CHECK: test_vbslq_u32
+// CHECK-LABEL: test_vbslq_u32
 // CHECK: vbsl q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vbslq_u32(uint32x4_t a, uint32x4_t b, uint32x4_t c) {
   return vbslq_u32(a, b, c);
 }
 
-// CHECK: test_vbslq_u64
+// CHECK-LABEL: test_vbslq_u64
 // CHECK: vbsl q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint64x2_t test_vbslq_u64(uint64x2_t a, uint64x2_t b, uint64x2_t c) {
   return vbslq_u64(a, b, c);
 }
 
-// CHECK: test_vbslq_f32
+// CHECK-LABEL: test_vbslq_f32
 // CHECK: vbsl q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vbslq_f32(uint32x4_t a, float32x4_t b, float32x4_t c) {
   return vbslq_f32(a, b, c);
 }
 
-// CHECK: test_vbslq_p8
+// CHECK-LABEL: test_vbslq_p8
 // CHECK: vbsl q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 poly8x16_t test_vbslq_p8(uint8x16_t a, poly8x16_t b, poly8x16_t c) {
   return vbslq_p8(a, b, c);
 }
 
-// CHECK: test_vbslq_p16
+// CHECK-LABEL: test_vbslq_p16
 // CHECK: vbsl q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 poly16x8_t test_vbslq_p16(uint16x8_t a, poly16x8_t b, poly16x8_t c) {
   return vbslq_p16(a, b, c);
 }
 
 
-// CHECK: test_vcage_f32
+// CHECK-LABEL: test_vcage_f32
 // CHECK: vacge.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vcage_f32(float32x2_t a, float32x2_t b) {
   return vcage_f32(a, b);
 }
 
-// CHECK: test_vcageq_f32
+// CHECK-LABEL: test_vcageq_f32
 // CHECK: vacge.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vcageq_f32(float32x4_t a, float32x4_t b) {
   return vcageq_f32(a, b);
 }
 
 
-// CHECK: test_vcagt_f32
+// CHECK-LABEL: test_vcagt_f32
 // CHECK: vacgt.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vcagt_f32(float32x2_t a, float32x2_t b) {
   return vcagt_f32(a, b);
 }
 
-// CHECK: test_vcagtq_f32
+// CHECK-LABEL: test_vcagtq_f32
 // CHECK: vacgt.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vcagtq_f32(float32x4_t a, float32x4_t b) {
   return vcagtq_f32(a, b);
 }
 
 
-// CHECK: test_vcale_f32
+// CHECK-LABEL: test_vcale_f32
 // CHECK: vacge.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vcale_f32(float32x2_t a, float32x2_t b) {
   return vcale_f32(a, b);
 }
 
-// CHECK: test_vcaleq_f32
+// CHECK-LABEL: test_vcaleq_f32
 // CHECK: vacge.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vcaleq_f32(float32x4_t a, float32x4_t b) {
   return vcaleq_f32(a, b);
 }
 
 
-// CHECK: test_vcalt_f32
+// CHECK-LABEL: test_vcalt_f32
 // CHECK: vacgt.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vcalt_f32(float32x2_t a, float32x2_t b) {
   return vcalt_f32(a, b);
 }
 
-// CHECK: test_vcaltq_f32
+// CHECK-LABEL: test_vcaltq_f32
 // CHECK: vacgt.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vcaltq_f32(float32x4_t a, float32x4_t b) {
   return vcaltq_f32(a, b);
 }
 
 
-// CHECK: test_vceq_s8
+// CHECK-LABEL: test_vceq_s8
 // CHECK: vceq.i8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vceq_s8(int8x8_t a, int8x8_t b) {
   return vceq_s8(a, b);
 }
 
-// CHECK: test_vceq_s16
+// CHECK-LABEL: test_vceq_s16
 // CHECK: vceq.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vceq_s16(int16x4_t a, int16x4_t b) {
   return vceq_s16(a, b);
 }
 
-// CHECK: test_vceq_s32
+// CHECK-LABEL: test_vceq_s32
 // CHECK: vceq.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vceq_s32(int32x2_t a, int32x2_t b) {
   return vceq_s32(a, b);
 }
 
-// CHECK: test_vceq_f32
+// CHECK-LABEL: test_vceq_f32
 // CHECK: vceq.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vceq_f32(float32x2_t a, float32x2_t b) {
   return vceq_f32(a, b);
 }
 
-// CHECK: test_vceq_u8
+// CHECK-LABEL: test_vceq_u8
 // CHECK: vceq.i8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vceq_u8(uint8x8_t a, uint8x8_t b) {
   return vceq_u8(a, b);
 }
 
-// CHECK: test_vceq_u16
+// CHECK-LABEL: test_vceq_u16
 // CHECK: vceq.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vceq_u16(uint16x4_t a, uint16x4_t b) {
   return vceq_u16(a, b);
 }
 
-// CHECK: test_vceq_u32
+// CHECK-LABEL: test_vceq_u32
 // CHECK: vceq.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vceq_u32(uint32x2_t a, uint32x2_t b) {
   return vceq_u32(a, b);
 }
 
-// CHECK: test_vceq_p8
+// CHECK-LABEL: test_vceq_p8
 // CHECK: vceq.i8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vceq_p8(poly8x8_t a, poly8x8_t b) {
   return vceq_p8(a, b);
 }
 
-// CHECK: test_vceqq_s8
+// CHECK-LABEL: test_vceqq_s8
 // CHECK: vceq.i8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vceqq_s8(int8x16_t a, int8x16_t b) {
   return vceqq_s8(a, b);
 }
 
-// CHECK: test_vceqq_s16
+// CHECK-LABEL: test_vceqq_s16
 // CHECK: vceq.i16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vceqq_s16(int16x8_t a, int16x8_t b) {
   return vceqq_s16(a, b);
 }
 
-// CHECK: test_vceqq_s32
+// CHECK-LABEL: test_vceqq_s32
 // CHECK: vceq.i32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vceqq_s32(int32x4_t a, int32x4_t b) {
   return vceqq_s32(a, b);
 }
 
-// CHECK: test_vceqq_f32
+// CHECK-LABEL: test_vceqq_f32
 // CHECK: vceq.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vceqq_f32(float32x4_t a, float32x4_t b) {
   return vceqq_f32(a, b);
 }
 
-// CHECK: test_vceqq_u8
+// CHECK-LABEL: test_vceqq_u8
 // CHECK: vceq.i8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vceqq_u8(uint8x16_t a, uint8x16_t b) {
   return vceqq_u8(a, b);
 }
 
-// CHECK: test_vceqq_u16
+// CHECK-LABEL: test_vceqq_u16
 // CHECK: vceq.i16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vceqq_u16(uint16x8_t a, uint16x8_t b) {
   return vceqq_u16(a, b);
 }
 
-// CHECK: test_vceqq_u32
+// CHECK-LABEL: test_vceqq_u32
 // CHECK: vceq.i32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vceqq_u32(uint32x4_t a, uint32x4_t b) {
   return vceqq_u32(a, b);
 }
 
-// CHECK: test_vceqq_p8
+// CHECK-LABEL: test_vceqq_p8
 // CHECK: vceq.i8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vceqq_p8(poly8x16_t a, poly8x16_t b) {
   return vceqq_p8(a, b);
 }
 
 
-// CHECK: test_vcge_s8
+// CHECK-LABEL: test_vcge_s8
 // CHECK: vcge.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vcge_s8(int8x8_t a, int8x8_t b) {
   return vcge_s8(a, b);
 }
 
-// CHECK: test_vcge_s16
+// CHECK-LABEL: test_vcge_s16
 // CHECK: vcge.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vcge_s16(int16x4_t a, int16x4_t b) {
   return vcge_s16(a, b);
 }
 
-// CHECK: test_vcge_s32
+// CHECK-LABEL: test_vcge_s32
 // CHECK: vcge.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vcge_s32(int32x2_t a, int32x2_t b) {
   return vcge_s32(a, b);
 }
 
-// CHECK: test_vcge_f32
+// CHECK-LABEL: test_vcge_f32
 // CHECK: vcge.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vcge_f32(float32x2_t a, float32x2_t b) {
   return vcge_f32(a, b);
 }
 
-// CHECK: test_vcge_u8
+// CHECK-LABEL: test_vcge_u8
 // CHECK: vcge.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vcge_u8(uint8x8_t a, uint8x8_t b) {
   return vcge_u8(a, b);
 }
 
-// CHECK: test_vcge_u16
+// CHECK-LABEL: test_vcge_u16
 // CHECK: vcge.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vcge_u16(uint16x4_t a, uint16x4_t b) {
   return vcge_u16(a, b);
 }
 
-// CHECK: test_vcge_u32
+// CHECK-LABEL: test_vcge_u32
 // CHECK: vcge.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vcge_u32(uint32x2_t a, uint32x2_t b) {
   return vcge_u32(a, b);
 }
 
-// CHECK: test_vcgeq_s8
+// CHECK-LABEL: test_vcgeq_s8
 // CHECK: vcge.s8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vcgeq_s8(int8x16_t a, int8x16_t b) {
   return vcgeq_s8(a, b);
 }
 
-// CHECK: test_vcgeq_s16
+// CHECK-LABEL: test_vcgeq_s16
 // CHECK: vcge.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vcgeq_s16(int16x8_t a, int16x8_t b) {
   return vcgeq_s16(a, b);
 }
 
-// CHECK: test_vcgeq_s32
+// CHECK-LABEL: test_vcgeq_s32
 // CHECK: vcge.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vcgeq_s32(int32x4_t a, int32x4_t b) {
   return vcgeq_s32(a, b);
 }
 
-// CHECK: test_vcgeq_f32
+// CHECK-LABEL: test_vcgeq_f32
 // CHECK: vcge.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vcgeq_f32(float32x4_t a, float32x4_t b) {
   return vcgeq_f32(a, b);
 }
 
-// CHECK: test_vcgeq_u8
+// CHECK-LABEL: test_vcgeq_u8
 // CHECK: vcge.u8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vcgeq_u8(uint8x16_t a, uint8x16_t b) {
   return vcgeq_u8(a, b);
 }
 
-// CHECK: test_vcgeq_u16
+// CHECK-LABEL: test_vcgeq_u16
 // CHECK: vcge.u16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vcgeq_u16(uint16x8_t a, uint16x8_t b) {
   return vcgeq_u16(a, b);
 }
 
-// CHECK: test_vcgeq_u32
+// CHECK-LABEL: test_vcgeq_u32
 // CHECK: vcge.u32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vcgeq_u32(uint32x4_t a, uint32x4_t b) {
   return vcgeq_u32(a, b);
 }
 
 
-// CHECK: test_vcgt_s8
+// CHECK-LABEL: test_vcgt_s8
 // CHECK: vcgt.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vcgt_s8(int8x8_t a, int8x8_t b) {
   return vcgt_s8(a, b);
 }
 
-// CHECK: test_vcgt_s16
+// CHECK-LABEL: test_vcgt_s16
 // CHECK: vcgt.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vcgt_s16(int16x4_t a, int16x4_t b) {
   return vcgt_s16(a, b);
 }
 
-// CHECK: test_vcgt_s32
+// CHECK-LABEL: test_vcgt_s32
 // CHECK: vcgt.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vcgt_s32(int32x2_t a, int32x2_t b) {
   return vcgt_s32(a, b);
 }
 
-// CHECK: test_vcgt_f32
+// CHECK-LABEL: test_vcgt_f32
 // CHECK: vcgt.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vcgt_f32(float32x2_t a, float32x2_t b) {
   return vcgt_f32(a, b);
 }
 
-// CHECK: test_vcgt_u8
+// CHECK-LABEL: test_vcgt_u8
 // CHECK: vcgt.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vcgt_u8(uint8x8_t a, uint8x8_t b) {
   return vcgt_u8(a, b);
 }
 
-// CHECK: test_vcgt_u16
+// CHECK-LABEL: test_vcgt_u16
 // CHECK: vcgt.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vcgt_u16(uint16x4_t a, uint16x4_t b) {
   return vcgt_u16(a, b);
 }
 
-// CHECK: test_vcgt_u32
+// CHECK-LABEL: test_vcgt_u32
 // CHECK: vcgt.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vcgt_u32(uint32x2_t a, uint32x2_t b) {
   return vcgt_u32(a, b);
 }
 
-// CHECK: test_vcgtq_s8
+// CHECK-LABEL: test_vcgtq_s8
 // CHECK: vcgt.s8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vcgtq_s8(int8x16_t a, int8x16_t b) {
   return vcgtq_s8(a, b);
 }
 
-// CHECK: test_vcgtq_s16
+// CHECK-LABEL: test_vcgtq_s16
 // CHECK: vcgt.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vcgtq_s16(int16x8_t a, int16x8_t b) {
   return vcgtq_s16(a, b);
 }
 
-// CHECK: test_vcgtq_s32
+// CHECK-LABEL: test_vcgtq_s32
 // CHECK: vcgt.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vcgtq_s32(int32x4_t a, int32x4_t b) {
   return vcgtq_s32(a, b);
 }
 
-// CHECK: test_vcgtq_f32
+// CHECK-LABEL: test_vcgtq_f32
 // CHECK: vcgt.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vcgtq_f32(float32x4_t a, float32x4_t b) {
   return vcgtq_f32(a, b);
 }
 
-// CHECK: test_vcgtq_u8
+// CHECK-LABEL: test_vcgtq_u8
 // CHECK: vcgt.u8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vcgtq_u8(uint8x16_t a, uint8x16_t b) {
   return vcgtq_u8(a, b);
 }
 
-// CHECK: test_vcgtq_u16
+// CHECK-LABEL: test_vcgtq_u16
 // CHECK: vcgt.u16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vcgtq_u16(uint16x8_t a, uint16x8_t b) {
   return vcgtq_u16(a, b);
 }
 
-// CHECK: test_vcgtq_u32
+// CHECK-LABEL: test_vcgtq_u32
 // CHECK: vcgt.u32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vcgtq_u32(uint32x4_t a, uint32x4_t b) {
   return vcgtq_u32(a, b);
 }
 
 
-// CHECK: test_vcle_s8
+// CHECK-LABEL: test_vcle_s8
 // CHECK: vcge.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vcle_s8(int8x8_t a, int8x8_t b) {
   return vcle_s8(a, b);
 }
 
-// CHECK: test_vcle_s16
+// CHECK-LABEL: test_vcle_s16
 // CHECK: vcge.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vcle_s16(int16x4_t a, int16x4_t b) {
   return vcle_s16(a, b);
 }
 
-// CHECK: test_vcle_s32
+// CHECK-LABEL: test_vcle_s32
 // CHECK: vcge.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vcle_s32(int32x2_t a, int32x2_t b) {
   return vcle_s32(a, b);
 }
 
-// CHECK: test_vcle_f32
+// CHECK-LABEL: test_vcle_f32
 // CHECK: vcge.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vcle_f32(float32x2_t a, float32x2_t b) {
   return vcle_f32(a, b);
 }
 
-// CHECK: test_vcle_u8
+// CHECK-LABEL: test_vcle_u8
 // CHECK: vcge.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vcle_u8(uint8x8_t a, uint8x8_t b) {
   return vcle_u8(a, b);
 }
 
-// CHECK: test_vcle_u16
+// CHECK-LABEL: test_vcle_u16
 // CHECK: vcge.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vcle_u16(uint16x4_t a, uint16x4_t b) {
   return vcle_u16(a, b);
 }
 
-// CHECK: test_vcle_u32
+// CHECK-LABEL: test_vcle_u32
 // CHECK: vcge.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vcle_u32(uint32x2_t a, uint32x2_t b) {
   return vcle_u32(a, b);
 }
 
-// CHECK: test_vcleq_s8
+// CHECK-LABEL: test_vcleq_s8
 // CHECK: vcge.s8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vcleq_s8(int8x16_t a, int8x16_t b) {
   return vcleq_s8(a, b);
 }
 
-// CHECK: test_vcleq_s16
+// CHECK-LABEL: test_vcleq_s16
 // CHECK: vcge.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vcleq_s16(int16x8_t a, int16x8_t b) {
   return vcleq_s16(a, b);
 }
 
-// CHECK: test_vcleq_s32
+// CHECK-LABEL: test_vcleq_s32
 // CHECK: vcge.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vcleq_s32(int32x4_t a, int32x4_t b) {
   return vcleq_s32(a, b);
 }
 
-// CHECK: test_vcleq_f32
+// CHECK-LABEL: test_vcleq_f32
 // CHECK: vcge.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vcleq_f32(float32x4_t a, float32x4_t b) {
   return vcleq_f32(a, b);
 }
 
-// CHECK: test_vcleq_u8
+// CHECK-LABEL: test_vcleq_u8
 // CHECK: vcge.u8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vcleq_u8(uint8x16_t a, uint8x16_t b) {
   return vcleq_u8(a, b);
 }
 
-// CHECK: test_vcleq_u16
+// CHECK-LABEL: test_vcleq_u16
 // CHECK: vcge.u16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vcleq_u16(uint16x8_t a, uint16x8_t b) {
   return vcleq_u16(a, b);
 }
 
-// CHECK: test_vcleq_u32
+// CHECK-LABEL: test_vcleq_u32
 // CHECK: vcge.u32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vcleq_u32(uint32x4_t a, uint32x4_t b) {
   return vcleq_u32(a, b);
 }
 
 
-// CHECK: test_vcls_s8
+// CHECK-LABEL: test_vcls_s8
 // CHECK: vcls.s8 d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vcls_s8(int8x8_t a) {
   return vcls_s8(a);
 }
 
-// CHECK: test_vcls_s16
+// CHECK-LABEL: test_vcls_s16
 // CHECK: vcls.s16 d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vcls_s16(int16x4_t a) {
   return vcls_s16(a);
 }
 
-// CHECK: test_vcls_s32
+// CHECK-LABEL: test_vcls_s32
 // CHECK: vcls.s32 d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vcls_s32(int32x2_t a) {
   return vcls_s32(a);
 }
 
-// CHECK: test_vclsq_s8
+// CHECK-LABEL: test_vclsq_s8
 // CHECK: vcls.s8 q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vclsq_s8(int8x16_t a) {
   return vclsq_s8(a);
 }
 
-// CHECK: test_vclsq_s16
+// CHECK-LABEL: test_vclsq_s16
 // CHECK: vcls.s16 q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vclsq_s16(int16x8_t a) {
   return vclsq_s16(a);
 }
 
-// CHECK: test_vclsq_s32
+// CHECK-LABEL: test_vclsq_s32
 // CHECK: vcls.s32 q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vclsq_s32(int32x4_t a) {
   return vclsq_s32(a);
 }
 
 
-// CHECK: test_vclt_s8
+// CHECK-LABEL: test_vclt_s8
 // CHECK: vcgt.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vclt_s8(int8x8_t a, int8x8_t b) {
   return vclt_s8(a, b);
 }
 
-// CHECK: test_vclt_s16
+// CHECK-LABEL: test_vclt_s16
 // CHECK: vcgt.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vclt_s16(int16x4_t a, int16x4_t b) {
   return vclt_s16(a, b);
 }
 
-// CHECK: test_vclt_s32
+// CHECK-LABEL: test_vclt_s32
 // CHECK: vcgt.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vclt_s32(int32x2_t a, int32x2_t b) {
   return vclt_s32(a, b);
 }
 
-// CHECK: test_vclt_f32
+// CHECK-LABEL: test_vclt_f32
 // CHECK: vcgt.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vclt_f32(float32x2_t a, float32x2_t b) {
   return vclt_f32(a, b);
 }
 
-// CHECK: test_vclt_u8
+// CHECK-LABEL: test_vclt_u8
 // CHECK: vcgt.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vclt_u8(uint8x8_t a, uint8x8_t b) {
   return vclt_u8(a, b);
 }
 
-// CHECK: test_vclt_u16
+// CHECK-LABEL: test_vclt_u16
 // CHECK: vcgt.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vclt_u16(uint16x4_t a, uint16x4_t b) {
   return vclt_u16(a, b);
 }
 
-// CHECK: test_vclt_u32
+// CHECK-LABEL: test_vclt_u32
 // CHECK: vcgt.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vclt_u32(uint32x2_t a, uint32x2_t b) {
   return vclt_u32(a, b);
 }
 
-// CHECK: test_vcltq_s8
+// CHECK-LABEL: test_vcltq_s8
 // CHECK: vcgt.s8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vcltq_s8(int8x16_t a, int8x16_t b) {
   return vcltq_s8(a, b);
 }
 
-// CHECK: test_vcltq_s16
+// CHECK-LABEL: test_vcltq_s16
 // CHECK: vcgt.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vcltq_s16(int16x8_t a, int16x8_t b) {
   return vcltq_s16(a, b);
 }
 
-// CHECK: test_vcltq_s32
+// CHECK-LABEL: test_vcltq_s32
 // CHECK: vcgt.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vcltq_s32(int32x4_t a, int32x4_t b) {
   return vcltq_s32(a, b);
 }
 
-// CHECK: test_vcltq_f32
+// CHECK-LABEL: test_vcltq_f32
 // CHECK: vcgt.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vcltq_f32(float32x4_t a, float32x4_t b) {
   return vcltq_f32(a, b);
 }
 
-// CHECK: test_vcltq_u8
+// CHECK-LABEL: test_vcltq_u8
 // CHECK: vcgt.u8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vcltq_u8(uint8x16_t a, uint8x16_t b) {
   return vcltq_u8(a, b);
 }
 
-// CHECK: test_vcltq_u16
+// CHECK-LABEL: test_vcltq_u16
 // CHECK: vcgt.u16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vcltq_u16(uint16x8_t a, uint16x8_t b) {
   return vcltq_u16(a, b);
 }
 
-// CHECK: test_vcltq_u32
+// CHECK-LABEL: test_vcltq_u32
 // CHECK: vcgt.u32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vcltq_u32(uint32x4_t a, uint32x4_t b) {
   return vcltq_u32(a, b);
 }
 
 
-// CHECK: test_vclz_s8
+// CHECK-LABEL: test_vclz_s8
 // CHECK: vclz.i8 d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vclz_s8(int8x8_t a) {
   return vclz_s8(a);
 }
 
-// CHECK: test_vclz_s16
+// CHECK-LABEL: test_vclz_s16
 // CHECK: vclz.i16 d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vclz_s16(int16x4_t a) {
   return vclz_s16(a);
 }
 
-// CHECK: test_vclz_s32
+// CHECK-LABEL: test_vclz_s32
 // CHECK: vclz.i32 d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vclz_s32(int32x2_t a) {
   return vclz_s32(a);
 }
 
-// CHECK: test_vclz_u8
+// CHECK-LABEL: test_vclz_u8
 // CHECK: vclz.i8 d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vclz_u8(uint8x8_t a) {
   return vclz_u8(a);
 }
 
-// CHECK: test_vclz_u16
+// CHECK-LABEL: test_vclz_u16
 // CHECK: vclz.i16 d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vclz_u16(uint16x4_t a) {
   return vclz_u16(a);
 }
 
-// CHECK: test_vclz_u32
+// CHECK-LABEL: test_vclz_u32
 // CHECK: vclz.i32 d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vclz_u32(uint32x2_t a) {
   return vclz_u32(a);
 }
 
-// CHECK: test_vclzq_s8
+// CHECK-LABEL: test_vclzq_s8
 // CHECK: vclz.i8 q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vclzq_s8(int8x16_t a) {
   return vclzq_s8(a);
 }
 
-// CHECK: test_vclzq_s16
+// CHECK-LABEL: test_vclzq_s16
 // CHECK: vclz.i16 q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vclzq_s16(int16x8_t a) {
   return vclzq_s16(a);
 }
 
-// CHECK: test_vclzq_s32
+// CHECK-LABEL: test_vclzq_s32
 // CHECK: vclz.i32 q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vclzq_s32(int32x4_t a) {
   return vclzq_s32(a);
 }
 
-// CHECK: test_vclzq_u8
+// CHECK-LABEL: test_vclzq_u8
 // CHECK: vclz.i8 q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vclzq_u8(uint8x16_t a) {
   return vclzq_u8(a);
 }
 
-// CHECK: test_vclzq_u16
+// CHECK-LABEL: test_vclzq_u16
 // CHECK: vclz.i16 q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vclzq_u16(uint16x8_t a) {
   return vclzq_u16(a);
 }
 
-// CHECK: test_vclzq_u32
+// CHECK-LABEL: test_vclzq_u32
 // CHECK: vclz.i32 q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vclzq_u32(uint32x4_t a) {
   return vclzq_u32(a);
 }
 
 
-// CHECK: test_vcnt_u8
+// CHECK-LABEL: test_vcnt_u8
 // CHECK: vcnt.8 d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vcnt_u8(uint8x8_t a) {
   return vcnt_u8(a);
 }
 
-// CHECK: test_vcnt_s8
+// CHECK-LABEL: test_vcnt_s8
 // CHECK: vcnt.8 d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vcnt_s8(int8x8_t a) {
   return vcnt_s8(a);
 }
 
-// CHECK: test_vcnt_p8
+// CHECK-LABEL: test_vcnt_p8
 // CHECK: vcnt.8 d{{[0-9]+}}, d{{[0-9]+}}
 poly8x8_t test_vcnt_p8(poly8x8_t a) {
   return vcnt_p8(a);
 }
 
-// CHECK: test_vcntq_u8
+// CHECK-LABEL: test_vcntq_u8
 // CHECK: vcnt.8 q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vcntq_u8(uint8x16_t a) {
   return vcntq_u8(a);
 }
 
-// CHECK: test_vcntq_s8
+// CHECK-LABEL: test_vcntq_s8
 // CHECK: vcnt.8 q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vcntq_s8(int8x16_t a) {
   return vcntq_s8(a);
 }
 
-// CHECK: test_vcntq_p8
+// CHECK-LABEL: test_vcntq_p8
 // CHECK: vcnt.8 q{{[0-9]+}}, q{{[0-9]+}}
 poly8x16_t test_vcntq_p8(poly8x16_t a) {
   return vcntq_p8(a);
 }
 
 
-// CHECK: test_vcombine_s8
+// CHECK-LABEL: test_vcombine_s8
 int8x16_t test_vcombine_s8(int8x8_t a, int8x8_t b) {
   return vcombine_s8(a, b);
 }
 
-// CHECK: test_vcombine_s16
+// CHECK-LABEL: test_vcombine_s16
 int16x8_t test_vcombine_s16(int16x4_t a, int16x4_t b) {
   return vcombine_s16(a, b);
 }
 
-// CHECK: test_vcombine_s32
+// CHECK-LABEL: test_vcombine_s32
 int32x4_t test_vcombine_s32(int32x2_t a, int32x2_t b) {
   return vcombine_s32(a, b);
 }
 
-// CHECK: test_vcombine_s64
+// CHECK-LABEL: test_vcombine_s64
 int64x2_t test_vcombine_s64(int64x1_t a, int64x1_t b) {
   return vcombine_s64(a, b);
 }
 
-// CHECK: test_vcombine_f16
+// CHECK-LABEL: test_vcombine_f16
 float16x8_t test_vcombine_f16(float16x4_t a, float16x4_t b) {
   return vcombine_f16(a, b);
 }
 
-// CHECK: test_vcombine_f32
+// CHECK-LABEL: test_vcombine_f32
 float32x4_t test_vcombine_f32(float32x2_t a, float32x2_t b) {
   return vcombine_f32(a, b);
 }
 
-// CHECK: test_vcombine_u8
+// CHECK-LABEL: test_vcombine_u8
 uint8x16_t test_vcombine_u8(uint8x8_t a, uint8x8_t b) {
   return vcombine_u8(a, b);
 }
 
-// CHECK: test_vcombine_u16
+// CHECK-LABEL: test_vcombine_u16
 uint16x8_t test_vcombine_u16(uint16x4_t a, uint16x4_t b) {
   return vcombine_u16(a, b);
 }
 
-// CHECK: test_vcombine_u32
+// CHECK-LABEL: test_vcombine_u32
 uint32x4_t test_vcombine_u32(uint32x2_t a, uint32x2_t b) {
   return vcombine_u32(a, b);
 }
 
-// CHECK: test_vcombine_u64
+// CHECK-LABEL: test_vcombine_u64
 uint64x2_t test_vcombine_u64(uint64x1_t a, uint64x1_t b) {
   return vcombine_u64(a, b);
 }
 
-// CHECK: test_vcombine_p8
+// CHECK-LABEL: test_vcombine_p8
 poly8x16_t test_vcombine_p8(poly8x8_t a, poly8x8_t b) {
   return vcombine_p8(a, b);
 }
 
-// CHECK: test_vcombine_p16
+// CHECK-LABEL: test_vcombine_p16
 poly16x8_t test_vcombine_p16(poly16x4_t a, poly16x4_t b) {
   return vcombine_p16(a, b);
 }
 
 
-// CHECK: test_vcreate_s8
+// CHECK-LABEL: test_vcreate_s8
 int8x8_t test_vcreate_s8(uint64_t a) {
   return vcreate_s8(a);
 }
 
-// CHECK: test_vcreate_s16
+// CHECK-LABEL: test_vcreate_s16
 int16x4_t test_vcreate_s16(uint64_t a) {
   return vcreate_s16(a);
 }
 
-// CHECK: test_vcreate_s32
+// CHECK-LABEL: test_vcreate_s32
 int32x2_t test_vcreate_s32(uint64_t a) {
   return vcreate_s32(a);
 }
 
-// CHECK: test_vcreate_f16
+// CHECK-LABEL: test_vcreate_f16
 float16x4_t test_vcreate_f16(uint64_t a) {
   return vcreate_f16(a);
 }
 
-// CHECK: test_vcreate_f32
+// CHECK-LABEL: test_vcreate_f32
 float32x2_t test_vcreate_f32(uint64_t a) {
   return vcreate_f32(a);
 }
 
-// CHECK: test_vcreate_u8
+// CHECK-LABEL: test_vcreate_u8
 uint8x8_t test_vcreate_u8(uint64_t a) {
   return vcreate_u8(a);
 }
 
-// CHECK: test_vcreate_u16
+// CHECK-LABEL: test_vcreate_u16
 uint16x4_t test_vcreate_u16(uint64_t a) {
   return vcreate_u16(a);
 }
 
-// CHECK: test_vcreate_u32
+// CHECK-LABEL: test_vcreate_u32
 uint32x2_t test_vcreate_u32(uint64_t a) {
   return vcreate_u32(a);
 }
 
-// CHECK: test_vcreate_u64
+// CHECK-LABEL: test_vcreate_u64
 uint64x1_t test_vcreate_u64(uint64_t a) {
   return vcreate_u64(a);
 }
 
-// CHECK: test_vcreate_p8
+// CHECK-LABEL: test_vcreate_p8
 poly8x8_t test_vcreate_p8(uint64_t a) {
   return vcreate_p8(a);
 }
 
-// CHECK: test_vcreate_p16
+// CHECK-LABEL: test_vcreate_p16
 poly16x4_t test_vcreate_p16(uint64_t a) {
   return vcreate_p16(a);
 }
 
-// CHECK: test_vcreate_s64
+// CHECK-LABEL: test_vcreate_s64
 int64x1_t test_vcreate_s64(uint64_t a) {
   return vcreate_s64(a);
 }
 
 
-// CHECK: test_vcvt_f16_f32
+// CHECK-LABEL: test_vcvt_f16_f32
 // CHECK: vcvt.f16.f32 d{{[0-9]+}}, q{{[0-9]+}}
 float16x4_t test_vcvt_f16_f32(float32x4_t a) {
   return vcvt_f16_f32(a);
 }
 
 
-// CHECK: test_vcvt_f32_s32
+// CHECK-LABEL: test_vcvt_f32_s32
 // CHECK: vcvt.f32.s32 d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vcvt_f32_s32(int32x2_t a) {
   return vcvt_f32_s32(a);
 }
 
-// CHECK: test_vcvt_f32_u32
+// CHECK-LABEL: test_vcvt_f32_u32
 // CHECK: vcvt.f32.u32 d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vcvt_f32_u32(uint32x2_t a) {
   return vcvt_f32_u32(a);
 }
 
-// CHECK: test_vcvtq_f32_s32
+// CHECK-LABEL: test_vcvtq_f32_s32
 // CHECK: vcvt.f32.s32 q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vcvtq_f32_s32(int32x4_t a) {
   return vcvtq_f32_s32(a);
 }
 
-// CHECK: test_vcvtq_f32_u32
+// CHECK-LABEL: test_vcvtq_f32_u32
 // CHECK: vcvt.f32.u32 q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vcvtq_f32_u32(uint32x4_t a) {
   return vcvtq_f32_u32(a);
 }
 
 
-// CHECK: test_vcvt_f32_f16
+// CHECK-LABEL: test_vcvt_f32_f16
 // CHECK: vcvt.f32.f16
 float32x4_t test_vcvt_f32_f16(float16x4_t a) {
   return vcvt_f32_f16(a);
 }
 
 
-// CHECK: test_vcvt_n_f32_s32
+// CHECK-LABEL: test_vcvt_n_f32_s32
 // CHECK: vcvt.f32.s32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 float32x2_t test_vcvt_n_f32_s32(int32x2_t a) {
   return vcvt_n_f32_s32(a, 1);
 }
 
-// CHECK: test_vcvt_n_f32_u32
+// CHECK-LABEL: test_vcvt_n_f32_u32
 // CHECK: vcvt.f32.u32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 float32x2_t test_vcvt_n_f32_u32(uint32x2_t a) {
   return vcvt_n_f32_u32(a, 1);
 }
 
-// CHECK: test_vcvtq_n_f32_s32
+// CHECK-LABEL: test_vcvtq_n_f32_s32
 // CHECK: vcvt.f32.s32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 float32x4_t test_vcvtq_n_f32_s32(int32x4_t a) {
   return vcvtq_n_f32_s32(a, 3);
 }
 
-// CHECK: test_vcvtq_n_f32_u32
+// CHECK-LABEL: test_vcvtq_n_f32_u32
 // CHECK: vcvt.f32.u32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 float32x4_t test_vcvtq_n_f32_u32(uint32x4_t a) {
   return vcvtq_n_f32_u32(a, 3);
 }
 
 
-// CHECK: test_vcvt_n_s32_f32
+// CHECK-LABEL: test_vcvt_n_s32_f32
 // CHECK: vcvt.s32.f32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int32x2_t test_vcvt_n_s32_f32(float32x2_t a) {
   return vcvt_n_s32_f32(a, 1);
 }
 
-// CHECK: test_vcvtq_n_s32_f32
+// CHECK-LABEL: test_vcvtq_n_s32_f32
 // CHECK: vcvt.s32.f32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int32x4_t test_vcvtq_n_s32_f32(float32x4_t a) {
   return vcvtq_n_s32_f32(a, 3);
 }
 
 
-// CHECK: test_vcvt_n_u32_f32
+// CHECK-LABEL: test_vcvt_n_u32_f32
 // CHECK: vcvt.u32.f32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint32x2_t test_vcvt_n_u32_f32(float32x2_t a) {
   return vcvt_n_u32_f32(a, 1);
 }
 
-// CHECK: test_vcvtq_n_u32_f32
+// CHECK-LABEL: test_vcvtq_n_u32_f32
 // CHECK: vcvt.u32.f32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint32x4_t test_vcvtq_n_u32_f32(float32x4_t a) {
   return vcvtq_n_u32_f32(a, 3);
 }
 
 
-// CHECK: test_vcvt_s32_f32
+// CHECK-LABEL: test_vcvt_s32_f32
 // CHECK: vcvt.s32.f32 d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vcvt_s32_f32(float32x2_t a) {
   return vcvt_s32_f32(a);
 }
 
-// CHECK: test_vcvtq_s32_f32
+// CHECK-LABEL: test_vcvtq_s32_f32
 // CHECK: vcvt.s32.f32 q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vcvtq_s32_f32(float32x4_t a) {
   return vcvtq_s32_f32(a);
 }
 
 
-// CHECK: test_vcvt_u32_f32
+// CHECK-LABEL: test_vcvt_u32_f32
 // CHECK: vcvt.u32.f32 d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vcvt_u32_f32(float32x2_t a) {
   return vcvt_u32_f32(a);
 }
 
-// CHECK: test_vcvtq_u32_f32
+// CHECK-LABEL: test_vcvtq_u32_f32
 // CHECK: vcvt.u32.f32 q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vcvtq_u32_f32(float32x4_t a) {
   return vcvtq_u32_f32(a);
 }
 
 
-// CHECK: test_vdup_lane_u8
+// CHECK-LABEL: test_vdup_lane_u8
 // CHECK: vdup.8 d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint8x8_t test_vdup_lane_u8(uint8x8_t a) {
   return vdup_lane_u8(a, 7);
 }
 
-// CHECK: test_vdup_lane_u16
+// CHECK-LABEL: test_vdup_lane_u16
 // CHECK: vdup.16 d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint16x4_t test_vdup_lane_u16(uint16x4_t a) {
   return vdup_lane_u16(a, 3);
 }
 
-// CHECK: test_vdup_lane_u32
+// CHECK-LABEL: test_vdup_lane_u32
 // CHECK: vdup.32 d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint32x2_t test_vdup_lane_u32(uint32x2_t a) {
   return vdup_lane_u32(a, 1);
 }
 
-// CHECK: test_vdup_lane_s8
+// CHECK-LABEL: test_vdup_lane_s8
 // CHECK: vdup.8 d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int8x8_t test_vdup_lane_s8(int8x8_t a) {
   return vdup_lane_s8(a, 7);
 }
 
-// CHECK: test_vdup_lane_s16
+// CHECK-LABEL: test_vdup_lane_s16
 // CHECK: vdup.16 d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int16x4_t test_vdup_lane_s16(int16x4_t a) {
   return vdup_lane_s16(a, 3);
 }
 
-// CHECK: test_vdup_lane_s32
+// CHECK-LABEL: test_vdup_lane_s32
 // CHECK: vdup.32 d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int32x2_t test_vdup_lane_s32(int32x2_t a) {
   return vdup_lane_s32(a, 1);
 }
 
-// CHECK: test_vdup_lane_p8
+// CHECK-LABEL: test_vdup_lane_p8
 // CHECK: vdup.8 d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 poly8x8_t test_vdup_lane_p8(poly8x8_t a) {
   return vdup_lane_p8(a, 7);
 }
 
-// CHECK: test_vdup_lane_p16
+// CHECK-LABEL: test_vdup_lane_p16
 // CHECK: vdup.16 d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 poly16x4_t test_vdup_lane_p16(poly16x4_t a) {
   return vdup_lane_p16(a, 3);
 }
 
-// CHECK: test_vdup_lane_f32
+// CHECK-LABEL: test_vdup_lane_f32
 // CHECK: vdup.32 d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 float32x2_t test_vdup_lane_f32(float32x2_t a) {
   return vdup_lane_f32(a, 1);
 }
 
-// CHECK: test_vdupq_lane_u8
+// CHECK-LABEL: test_vdupq_lane_u8
 // CHECK: vdup.8 q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint8x16_t test_vdupq_lane_u8(uint8x8_t a) {
   return vdupq_lane_u8(a, 7);
 }
 
-// CHECK: test_vdupq_lane_u16
+// CHECK-LABEL: test_vdupq_lane_u16
 // CHECK: vdup.16 q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint16x8_t test_vdupq_lane_u16(uint16x4_t a) {
   return vdupq_lane_u16(a, 3);
 }
 
-// CHECK: test_vdupq_lane_u32
+// CHECK-LABEL: test_vdupq_lane_u32
 // CHECK: vdup.32 q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint32x4_t test_vdupq_lane_u32(uint32x2_t a) {
   return vdupq_lane_u32(a, 1);
 }
 
-// CHECK: test_vdupq_lane_s8
+// CHECK-LABEL: test_vdupq_lane_s8
 // CHECK: vdup.8 q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int8x16_t test_vdupq_lane_s8(int8x8_t a) {
   return vdupq_lane_s8(a, 7);
 }
 
-// CHECK: test_vdupq_lane_s16
+// CHECK-LABEL: test_vdupq_lane_s16
 // CHECK: vdup.16 q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int16x8_t test_vdupq_lane_s16(int16x4_t a) {
   return vdupq_lane_s16(a, 3);
 }
 
-// CHECK: test_vdupq_lane_s32
+// CHECK-LABEL: test_vdupq_lane_s32
 // CHECK: vdup.32 q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int32x4_t test_vdupq_lane_s32(int32x2_t a) {
   return vdupq_lane_s32(a, 1);
 }
 
-// CHECK: test_vdupq_lane_p8
+// CHECK-LABEL: test_vdupq_lane_p8
 // CHECK: vdup.8 q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 poly8x16_t test_vdupq_lane_p8(poly8x8_t a) {
   return vdupq_lane_p8(a, 7);
 }
 
-// CHECK: test_vdupq_lane_p16
+// CHECK-LABEL: test_vdupq_lane_p16
 // CHECK: vdup.16 q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 poly16x8_t test_vdupq_lane_p16(poly16x4_t a) {
   return vdupq_lane_p16(a, 3);
 }
 
-// CHECK: test_vdupq_lane_f32
+// CHECK-LABEL: test_vdupq_lane_f32
 // CHECK: vdup.32 q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 float32x4_t test_vdupq_lane_f32(float32x2_t a) {
   return vdupq_lane_f32(a, 1);
 }
 
-// CHECK: test_vdup_lane_s64
+// CHECK-LABEL: test_vdup_lane_s64
 int64x1_t test_vdup_lane_s64(int64x1_t a) {
   return vdup_lane_s64(a, 0);
 }
 
-// CHECK: test_vdup_lane_u64
+// CHECK-LABEL: test_vdup_lane_u64
 uint64x1_t test_vdup_lane_u64(uint64x1_t a) {
   return vdup_lane_u64(a, 0);
 }
 
-// CHECK: test_vdupq_lane_s64
+// CHECK-LABEL: test_vdupq_lane_s64
 // CHECK: {{vmov|vdup}}
 int64x2_t test_vdupq_lane_s64(int64x1_t a) {
   return vdupq_lane_s64(a, 0);
 }
 
-// CHECK: test_vdupq_lane_u64
+// CHECK-LABEL: test_vdupq_lane_u64
 // CHECK: {{vmov|vdup}}
 uint64x2_t test_vdupq_lane_u64(uint64x1_t a) {
   return vdupq_lane_u64(a, 0);
 }
 
 
-// CHECK: test_vdup_n_u8
+// CHECK-LABEL: test_vdup_n_u8
 // CHECK: vmov 
 uint8x8_t test_vdup_n_u8(uint8_t a) {
   return vdup_n_u8(a);
 }
 
-// CHECK: test_vdup_n_u16
+// CHECK-LABEL: test_vdup_n_u16
 // CHECK: vmov 
 uint16x4_t test_vdup_n_u16(uint16_t a) {
   return vdup_n_u16(a);
 }
 
-// CHECK: test_vdup_n_u32
+// CHECK-LABEL: test_vdup_n_u32
 // CHECK: vmov 
 uint32x2_t test_vdup_n_u32(uint32_t a) {
   return vdup_n_u32(a);
 }
 
-// CHECK: test_vdup_n_s8
+// CHECK-LABEL: test_vdup_n_s8
 // CHECK: vmov 
 int8x8_t test_vdup_n_s8(int8_t a) {
   return vdup_n_s8(a);
 }
 
-// CHECK: test_vdup_n_s16
+// CHECK-LABEL: test_vdup_n_s16
 // CHECK: vmov 
 int16x4_t test_vdup_n_s16(int16_t a) {
   return vdup_n_s16(a);
 }
 
-// CHECK: test_vdup_n_s32
+// CHECK-LABEL: test_vdup_n_s32
 // CHECK: vmov 
 int32x2_t test_vdup_n_s32(int32_t a) {
   return vdup_n_s32(a);
 }
 
-// CHECK: test_vdup_n_p8
+// CHECK-LABEL: test_vdup_n_p8
 // CHECK: vmov 
 poly8x8_t test_vdup_n_p8(poly8_t a) {
   return vdup_n_p8(a);
 }
 
-// CHECK: test_vdup_n_p16
+// CHECK-LABEL: test_vdup_n_p16
 // CHECK: vmov 
 poly16x4_t test_vdup_n_p16(poly16_t a) {
   return vdup_n_p16(a);
 }
 
-// CHECK: test_vdup_n_f32
+// CHECK-LABEL: test_vdup_n_f16
+// CHECK: vld1.16 {{{d[0-9]+\[\]}}}
+float16x4_t test_vdup_n_f16(float16_t *a) {
+  return vdup_n_f16(*a);
+}
+
+// CHECK-LABEL: test_vdup_n_f32
 // CHECK: vmov 
 float32x2_t test_vdup_n_f32(float32_t a) {
   return vdup_n_f32(a);
 }
 
-// CHECK: test_vdupq_n_u8
+// CHECK-LABEL: test_vdupq_n_u8
 // CHECK: vmov 
 uint8x16_t test_vdupq_n_u8(uint8_t a) {
   return vdupq_n_u8(a);
 }
 
-// CHECK: test_vdupq_n_u16
+// CHECK-LABEL: test_vdupq_n_u16
 // CHECK: vmov 
 uint16x8_t test_vdupq_n_u16(uint16_t a) {
   return vdupq_n_u16(a);
 }
 
-// CHECK: test_vdupq_n_u32
+// CHECK-LABEL: test_vdupq_n_u32
 // CHECK: vmov 
 uint32x4_t test_vdupq_n_u32(uint32_t a) {
   return vdupq_n_u32(a);
 }
 
-// CHECK: test_vdupq_n_s8
+// CHECK-LABEL: test_vdupq_n_s8
 // CHECK: vmov 
 int8x16_t test_vdupq_n_s8(int8_t a) {
   return vdupq_n_s8(a);
 }
 
-// CHECK: test_vdupq_n_s16
+// CHECK-LABEL: test_vdupq_n_s16
 // CHECK: vmov 
 int16x8_t test_vdupq_n_s16(int16_t a) {
   return vdupq_n_s16(a);
 }
 
-// CHECK: test_vdupq_n_s32
+// CHECK-LABEL: test_vdupq_n_s32
 // CHECK: vmov 
 int32x4_t test_vdupq_n_s32(int32_t a) {
   return vdupq_n_s32(a);
 }
 
-// CHECK: test_vdupq_n_p8
+// CHECK-LABEL: test_vdupq_n_p8
 // CHECK: vmov 
 poly8x16_t test_vdupq_n_p8(poly8_t a) {
   return vdupq_n_p8(a);
 }
 
-// CHECK: test_vdupq_n_p16
+// CHECK-LABEL: test_vdupq_n_p16
 // CHECK: vmov 
 poly16x8_t test_vdupq_n_p16(poly16_t a) {
   return vdupq_n_p16(a);
 }
 
-// CHECK: test_vdupq_n_f32
+// CHECK-LABEL: test_vdupq_n_f16
+// CHECK: vld1.16 {{{d[0-9]+\[\], d[0-9]+\[\]}}}
+float16x8_t test_vdupq_n_f16(float16_t *a) {
+  return vdupq_n_f16(*a);
+}
+
+// CHECK-LABEL: test_vdupq_n_f32
 // CHECK: vmov 
 float32x4_t test_vdupq_n_f32(float32_t a) {
   return vdupq_n_f32(a);
 }
 
-// CHECK: test_vdup_n_s64
+// CHECK-LABEL: test_vdup_n_s64
 // CHECK: vmov 
 int64x1_t test_vdup_n_s64(int64_t a) {
   return vdup_n_s64(a);
 }
 
-// CHECK: test_vdup_n_u64
+// CHECK-LABEL: test_vdup_n_u64
 // CHECK: vmov 
 uint64x1_t test_vdup_n_u64(uint64_t a) {
   return vdup_n_u64(a);
 }
 
-// CHECK: test_vdupq_n_s64
+// CHECK-LABEL: test_vdupq_n_s64
 // CHECK: vmov 
 int64x2_t test_vdupq_n_s64(int64_t a) {
   return vdupq_n_s64(a);
 }
 
-// CHECK: test_vdupq_n_u64
+// CHECK-LABEL: test_vdupq_n_u64
 // CHECK: vmov 
 uint64x2_t test_vdupq_n_u64(uint64_t a) {
   return vdupq_n_u64(a);
 }
 
 
-// CHECK: test_veor_s8
+// CHECK-LABEL: test_veor_s8
 // CHECK: veor d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_veor_s8(int8x8_t a, int8x8_t b) {
   return veor_s8(a, b);
 }
 
-// CHECK: test_veor_s16
+// CHECK-LABEL: test_veor_s16
 // CHECK: veor d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_veor_s16(int16x4_t a, int16x4_t b) {
   return veor_s16(a, b);
 }
 
-// CHECK: test_veor_s32
+// CHECK-LABEL: test_veor_s32
 // CHECK: veor d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_veor_s32(int32x2_t a, int32x2_t b) {
   return veor_s32(a, b);
 }
 
-// CHECK: test_veor_s64
+// CHECK-LABEL: test_veor_s64
 // CHECK: veor d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x1_t test_veor_s64(int64x1_t a, int64x1_t b) {
   return veor_s64(a, b);
 }
 
-// CHECK: test_veor_u8
+// CHECK-LABEL: test_veor_u8
 // CHECK: veor d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_veor_u8(uint8x8_t a, uint8x8_t b) {
   return veor_u8(a, b);
 }
 
-// CHECK: test_veor_u16
+// CHECK-LABEL: test_veor_u16
 // CHECK: veor d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_veor_u16(uint16x4_t a, uint16x4_t b) {
   return veor_u16(a, b);
 }
 
-// CHECK: test_veor_u32
+// CHECK-LABEL: test_veor_u32
 // CHECK: veor d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_veor_u32(uint32x2_t a, uint32x2_t b) {
   return veor_u32(a, b);
 }
 
-// CHECK: test_veor_u64
+// CHECK-LABEL: test_veor_u64
 // CHECK: veor d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x1_t test_veor_u64(uint64x1_t a, uint64x1_t b) {
   return veor_u64(a, b);
 }
 
-// CHECK: test_veorq_s8
+// CHECK-LABEL: test_veorq_s8
 // CHECK: veor q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_veorq_s8(int8x16_t a, int8x16_t b) {
   return veorq_s8(a, b);
 }
 
-// CHECK: test_veorq_s16
+// CHECK-LABEL: test_veorq_s16
 // CHECK: veor q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_veorq_s16(int16x8_t a, int16x8_t b) {
   return veorq_s16(a, b);
 }
 
-// CHECK: test_veorq_s32
+// CHECK-LABEL: test_veorq_s32
 // CHECK: veor q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_veorq_s32(int32x4_t a, int32x4_t b) {
   return veorq_s32(a, b);
 }
 
-// CHECK: test_veorq_s64
+// CHECK-LABEL: test_veorq_s64
 // CHECK: veor q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int64x2_t test_veorq_s64(int64x2_t a, int64x2_t b) {
   return veorq_s64(a, b);
 }
 
-// CHECK: test_veorq_u8
+// CHECK-LABEL: test_veorq_u8
 // CHECK: veor q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_veorq_u8(uint8x16_t a, uint8x16_t b) {
   return veorq_u8(a, b);
 }
 
-// CHECK: test_veorq_u16
+// CHECK-LABEL: test_veorq_u16
 // CHECK: veor q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_veorq_u16(uint16x8_t a, uint16x8_t b) {
   return veorq_u16(a, b);
 }
 
-// CHECK: test_veorq_u32
+// CHECK-LABEL: test_veorq_u32
 // CHECK: veor q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_veorq_u32(uint32x4_t a, uint32x4_t b) {
   return veorq_u32(a, b);
 }
 
-// CHECK: test_veorq_u64
+// CHECK-LABEL: test_veorq_u64
 // CHECK: veor q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint64x2_t test_veorq_u64(uint64x2_t a, uint64x2_t b) {
   return veorq_u64(a, b);
 }
 
 
-// CHECK: test_vext_s8
+// CHECK-LABEL: test_vext_s8
 // CHECK: vext.8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int8x8_t test_vext_s8(int8x8_t a, int8x8_t b) {
   return vext_s8(a, b, 7);
 }
 
-// CHECK: test_vext_u8
+// CHECK-LABEL: test_vext_u8
 // CHECK: vext.8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint8x8_t test_vext_u8(uint8x8_t a, uint8x8_t b) {
   return vext_u8(a, b, 7);
 }
 
-// CHECK: test_vext_p8
+// CHECK-LABEL: test_vext_p8
 // CHECK: vext.8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 poly8x8_t test_vext_p8(poly8x8_t a, poly8x8_t b) {
   return vext_p8(a, b, 7);
 }
 
-// CHECK: test_vext_s16
+// CHECK-LABEL: test_vext_s16
 // CHECK: vext.16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int16x4_t test_vext_s16(int16x4_t a, int16x4_t b) {
   return vext_s16(a, b, 3);
 }
 
-// CHECK: test_vext_u16
+// CHECK-LABEL: test_vext_u16
 // CHECK: vext.16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint16x4_t test_vext_u16(uint16x4_t a, uint16x4_t b) {
   return vext_u16(a, b, 3);
 }
 
-// CHECK: test_vext_p16
+// CHECK-LABEL: test_vext_p16
 // CHECK: vext.16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 poly16x4_t test_vext_p16(poly16x4_t a, poly16x4_t b) {
   return vext_p16(a, b, 3);
 }
 
-// CHECK: test_vext_s32
+// CHECK-LABEL: test_vext_s32
 // CHECK: vext.32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int32x2_t test_vext_s32(int32x2_t a, int32x2_t b) {
   return vext_s32(a, b, 1);
 }
 
-// CHECK: test_vext_u32
+// CHECK-LABEL: test_vext_u32
 // CHECK: vext.32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint32x2_t test_vext_u32(uint32x2_t a, uint32x2_t b) {
   return vext_u32(a, b, 1);
 }
 
-// CHECK: test_vext_s64
+// CHECK-LABEL: test_vext_s64
 int64x1_t test_vext_s64(int64x1_t a, int64x1_t b) {
   return vext_s64(a, b, 0);
 }
 
-// CHECK: test_vext_u64
+// CHECK-LABEL: test_vext_u64
 uint64x1_t test_vext_u64(uint64x1_t a, uint64x1_t b) {
   return vext_u64(a, b, 0);
 }
 
-// CHECK: test_vext_f32
+// CHECK-LABEL: test_vext_f32
 // CHECK: vext.32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 float32x2_t test_vext_f32(float32x2_t a, float32x2_t b) {
   return vext_f32(a, b, 1);
 }
 
-// CHECK: test_vextq_s8
+// CHECK-LABEL: test_vextq_s8
 // CHECK: vext.8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int8x16_t test_vextq_s8(int8x16_t a, int8x16_t b) {
   return vextq_s8(a, b, 15);
 }
 
-// CHECK: test_vextq_u8
+// CHECK-LABEL: test_vextq_u8
 // CHECK: vext.8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint8x16_t test_vextq_u8(uint8x16_t a, uint8x16_t b) {
   return vextq_u8(a, b, 15);
 }
 
-// CHECK: test_vextq_p8
+// CHECK-LABEL: test_vextq_p8
 // CHECK: vext.8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 poly8x16_t test_vextq_p8(poly8x16_t a, poly8x16_t b) {
   return vextq_p8(a, b, 15);
 }
 
-// CHECK: test_vextq_s16
+// CHECK-LABEL: test_vextq_s16
 // CHECK: vext.16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int16x8_t test_vextq_s16(int16x8_t a, int16x8_t b) {
   return vextq_s16(a, b, 7);
 }
 
-// CHECK: test_vextq_u16
+// CHECK-LABEL: test_vextq_u16
 // CHECK: vext.16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint16x8_t test_vextq_u16(uint16x8_t a, uint16x8_t b) {
   return vextq_u16(a, b, 7);
 }
 
-// CHECK: test_vextq_p16
+// CHECK-LABEL: test_vextq_p16
 // CHECK: vext.16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 poly16x8_t test_vextq_p16(poly16x8_t a, poly16x8_t b) {
   return vextq_p16(a, b, 7);
 }
 
-// CHECK: test_vextq_s32
+// CHECK-LABEL: test_vextq_s32
 // CHECK: vext.32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int32x4_t test_vextq_s32(int32x4_t a, int32x4_t b) {
   return vextq_s32(a, b, 3);
 }
 
-// CHECK: test_vextq_u32
+// CHECK-LABEL: test_vextq_u32
 // CHECK: vext.32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint32x4_t test_vextq_u32(uint32x4_t a, uint32x4_t b) {
   return vextq_u32(a, b, 3);
 }
 
-// CHECK: test_vextq_s64
+// CHECK-LABEL: test_vextq_s64
 // CHECK: {{vmov|vdup}}
 int64x2_t test_vextq_s64(int64x2_t a, int64x2_t b) {
   return vextq_s64(a, b, 1);
 }
 
-// CHECK: test_vextq_u64
+// CHECK-LABEL: test_vextq_u64
 // CHECK: {{vmov|vdup}}
 uint64x2_t test_vextq_u64(uint64x2_t a, uint64x2_t b) {
   return vextq_u64(a, b, 1);
 }
 
-// CHECK: test_vextq_f32
+// CHECK-LABEL: test_vextq_f32
 // CHECK: vext.32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 float32x4_t test_vextq_f32(float32x4_t a, float32x4_t b) {
   return vextq_f32(a, b, 3);
 }
 
 
-// CHECK: test_vfma_f32
+// CHECK-LABEL: test_vfma_f32
 // CHECK: vfma.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vfma_f32(float32x2_t a, float32x2_t b, float32x2_t c) {
   return vfma_f32(a, b, c);
 }
 
-// CHECK: test_vfmaq_f32
+// CHECK-LABEL: test_vfmaq_f32
 // CHECK: vfma.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vfmaq_f32(float32x4_t a, float32x4_t b, float32x4_t c) {
   return vfmaq_f32(a, b, c);
 }
 
 
-// CHECK: test_vget_high_s8
+// CHECK-LABEL: test_vget_high_s8
 int8x8_t test_vget_high_s8(int8x16_t a) {
   return vget_high_s8(a);
 }
 
-// CHECK: test_vget_high_s16
+// CHECK-LABEL: test_vget_high_s16
 int16x4_t test_vget_high_s16(int16x8_t a) {
   return vget_high_s16(a);
 }
 
-// CHECK: test_vget_high_s32
+// CHECK-LABEL: test_vget_high_s32
 int32x2_t test_vget_high_s32(int32x4_t a) {
   return vget_high_s32(a);
 }
 
-// CHECK: test_vget_high_s64
+// CHECK-LABEL: test_vget_high_s64
 int64x1_t test_vget_high_s64(int64x2_t a) {
   return vget_high_s64(a);
 }
 
-// CHECK: test_vget_high_f16
+// CHECK-LABEL: test_vget_high_f16
 float16x4_t test_vget_high_f16(float16x8_t a) {
   return vget_high_f16(a);
 }
 
-// CHECK: test_vget_high_f32
+// CHECK-LABEL: test_vget_high_f32
 float32x2_t test_vget_high_f32(float32x4_t a) {
   return vget_high_f32(a);
 }
 
-// CHECK: test_vget_high_u8
+// CHECK-LABEL: test_vget_high_u8
 uint8x8_t test_vget_high_u8(uint8x16_t a) {
   return vget_high_u8(a);
 }
 
-// CHECK: test_vget_high_u16
+// CHECK-LABEL: test_vget_high_u16
 uint16x4_t test_vget_high_u16(uint16x8_t a) {
   return vget_high_u16(a);
 }
 
-// CHECK: test_vget_high_u32
+// CHECK-LABEL: test_vget_high_u32
 uint32x2_t test_vget_high_u32(uint32x4_t a) {
   return vget_high_u32(a);
 }
 
-// CHECK: test_vget_high_u64
+// CHECK-LABEL: test_vget_high_u64
 uint64x1_t test_vget_high_u64(uint64x2_t a) {
   return vget_high_u64(a);
 }
 
-// CHECK: test_vget_high_p8
+// CHECK-LABEL: test_vget_high_p8
 poly8x8_t test_vget_high_p8(poly8x16_t a) {
   return vget_high_p8(a);
 }
 
-// CHECK: test_vget_high_p16
+// CHECK-LABEL: test_vget_high_p16
 poly16x4_t test_vget_high_p16(poly16x8_t a) {
   return vget_high_p16(a);
 }
 
 
-// CHECK: test_vget_lane_u8
+// CHECK-LABEL: test_vget_lane_u8
 // CHECK: vmov 
 uint8_t test_vget_lane_u8(uint8x8_t a) {
   return vget_lane_u8(a, 7);
 }
 
-// CHECK: test_vget_lane_u16
+// CHECK-LABEL: test_vget_lane_u16
 // CHECK: vmov 
 uint16_t test_vget_lane_u16(uint16x4_t a) {
   return vget_lane_u16(a, 3);
 }
 
-// CHECK: test_vget_lane_u32
+// CHECK-LABEL: test_vget_lane_u32
 // CHECK: vmov 
 uint32_t test_vget_lane_u32(uint32x2_t a) {
   return vget_lane_u32(a, 1);
 }
 
-// CHECK: test_vget_lane_s8
+// CHECK-LABEL: test_vget_lane_s8
 // CHECK: vmov 
 int8_t test_vget_lane_s8(int8x8_t a) {
   return vget_lane_s8(a, 7);
 }
 
-// CHECK: test_vget_lane_s16
+// CHECK-LABEL: test_vget_lane_s16
 // CHECK: vmov 
 int16_t test_vget_lane_s16(int16x4_t a) {
   return vget_lane_s16(a, 3);
 }
 
-// CHECK: test_vget_lane_s32
+// CHECK-LABEL: test_vget_lane_s32
 // CHECK: vmov 
 int32_t test_vget_lane_s32(int32x2_t a) {
   return vget_lane_s32(a, 1);
 }
 
-// CHECK: test_vget_lane_p8
+// CHECK-LABEL: test_vget_lane_p8
 // CHECK: vmov 
 poly8_t test_vget_lane_p8(poly8x8_t a) {
   return vget_lane_p8(a, 7);
 }
 
-// CHECK: test_vget_lane_p16
+// CHECK-LABEL: test_vget_lane_p16
 // CHECK: vmov 
 poly16_t test_vget_lane_p16(poly16x4_t a) {
   return vget_lane_p16(a, 3);
 }
 
-// CHECK: test_vget_lane_f32
+// CHECK-LABEL: test_vget_lane_f32
 // CHECK: vmov 
 float32_t test_vget_lane_f32(float32x2_t a) {
   return vget_lane_f32(a, 1);
 }
 
-// CHECK: test_vgetq_lane_u8
+// CHECK-LABEL: test_vgetq_lane_u8
 // CHECK: vmov 
 uint8_t test_vgetq_lane_u8(uint8x16_t a) {
   return vgetq_lane_u8(a, 15);
 }
 
-// CHECK: test_vgetq_lane_u16
+// CHECK-LABEL: test_vgetq_lane_u16
 // CHECK: vmov 
 uint16_t test_vgetq_lane_u16(uint16x8_t a) {
   return vgetq_lane_u16(a, 7);
 }
 
-// CHECK: test_vgetq_lane_u32
+// CHECK-LABEL: test_vgetq_lane_u32
 // CHECK: vmov 
 uint32_t test_vgetq_lane_u32(uint32x4_t a) {
   return vgetq_lane_u32(a, 3);
 }
 
-// CHECK: test_vgetq_lane_s8
+// CHECK-LABEL: test_vgetq_lane_s8
 // CHECK: vmov 
 int8_t test_vgetq_lane_s8(int8x16_t a) {
   return vgetq_lane_s8(a, 15);
 }
 
-// CHECK: test_vgetq_lane_s16
+// CHECK-LABEL: test_vgetq_lane_s16
 // CHECK: vmov 
 int16_t test_vgetq_lane_s16(int16x8_t a) {
   return vgetq_lane_s16(a, 7);
 }
 
-// CHECK: test_vgetq_lane_s32
+// CHECK-LABEL: test_vgetq_lane_s32
 // CHECK: vmov 
 int32_t test_vgetq_lane_s32(int32x4_t a) {
   return vgetq_lane_s32(a, 3);
 }
 
-// CHECK: test_vgetq_lane_p8
+// CHECK-LABEL: test_vgetq_lane_p8
 // CHECK: vmov 
 poly8_t test_vgetq_lane_p8(poly8x16_t a) {
   return vgetq_lane_p8(a, 15);
 }
 
-// CHECK: test_vgetq_lane_p16
+// CHECK-LABEL: test_vgetq_lane_p16
 // CHECK: vmov 
 poly16_t test_vgetq_lane_p16(poly16x8_t a) {
   return vgetq_lane_p16(a, 7);
 }
 
-// CHECK: test_vgetq_lane_f32
+// CHECK-LABEL: test_vgetq_lane_f32
 // CHECK: vmov 
 float32_t test_vgetq_lane_f32(float32x4_t a) {
   return vgetq_lane_f32(a, 3);
 }
 
-// CHECK: test_vget_lane_s64
+// CHECK-LABEL: test_vget_lane_s64
 // CHECK: vmov 
 int64_t test_vget_lane_s64(int64x1_t a) {
   return vget_lane_s64(a, 0);
 }
 
-// CHECK: test_vget_lane_u64
+// CHECK-LABEL: test_vget_lane_u64
 // CHECK: vmov 
 uint64_t test_vget_lane_u64(uint64x1_t a) {
   return vget_lane_u64(a, 0);
 }
 
-// CHECK: test_vgetq_lane_s64
+// CHECK-LABEL: test_vgetq_lane_s64
 // CHECK: vmov 
 int64_t test_vgetq_lane_s64(int64x2_t a) {
   return vgetq_lane_s64(a, 1);
 }
 
-// CHECK: test_vgetq_lane_u64
+// CHECK-LABEL: test_vgetq_lane_u64
 // CHECK: vmov 
 uint64_t test_vgetq_lane_u64(uint64x2_t a) {
   return vgetq_lane_u64(a, 1);
 }
 
 
-// CHECK: test_vget_low_s8
+// CHECK-LABEL: test_vget_low_s8
 int8x8_t test_vget_low_s8(int8x16_t a) {
   return vget_low_s8(a);
 }
 
-// CHECK: test_vget_low_s16
+// CHECK-LABEL: test_vget_low_s16
 int16x4_t test_vget_low_s16(int16x8_t a) {
   return vget_low_s16(a);
 }
 
-// CHECK: test_vget_low_s32
+// CHECK-LABEL: test_vget_low_s32
 int32x2_t test_vget_low_s32(int32x4_t a) {
   return vget_low_s32(a);
 }
 
-// CHECK: test_vget_low_s64
+// CHECK-LABEL: test_vget_low_s64
 int64x1_t test_vget_low_s64(int64x2_t a) {
   return vget_low_s64(a);
 }
 
-// CHECK: test_vget_low_f16
+// CHECK-LABEL: test_vget_low_f16
 float16x4_t test_vget_low_f16(float16x8_t a) {
   return vget_low_f16(a);
 }
 
-// CHECK: test_vget_low_f32
+// CHECK-LABEL: test_vget_low_f32
 float32x2_t test_vget_low_f32(float32x4_t a) {
   return vget_low_f32(a);
 }
 
-// CHECK: test_vget_low_u8
+// CHECK-LABEL: test_vget_low_u8
 uint8x8_t test_vget_low_u8(uint8x16_t a) {
   return vget_low_u8(a);
 }
 
-// CHECK: test_vget_low_u16
+// CHECK-LABEL: test_vget_low_u16
 uint16x4_t test_vget_low_u16(uint16x8_t a) {
   return vget_low_u16(a);
 }
 
-// CHECK: test_vget_low_u32
+// CHECK-LABEL: test_vget_low_u32
 uint32x2_t test_vget_low_u32(uint32x4_t a) {
   return vget_low_u32(a);
 }
 
-// CHECK: test_vget_low_u64
+// CHECK-LABEL: test_vget_low_u64
 uint64x1_t test_vget_low_u64(uint64x2_t a) {
   return vget_low_u64(a);
 }
 
-// CHECK: test_vget_low_p8
+// CHECK-LABEL: test_vget_low_p8
 poly8x8_t test_vget_low_p8(poly8x16_t a) {
   return vget_low_p8(a);
 }
 
-// CHECK: test_vget_low_p16
+// CHECK-LABEL: test_vget_low_p16
 poly16x4_t test_vget_low_p16(poly16x8_t a) {
   return vget_low_p16(a);
 }
 
 
-// CHECK: test_vhadd_s8
+// CHECK-LABEL: test_vhadd_s8
 // CHECK: vhadd.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vhadd_s8(int8x8_t a, int8x8_t b) {
   return vhadd_s8(a, b);
 }
 
-// CHECK: test_vhadd_s16
+// CHECK-LABEL: test_vhadd_s16
 // CHECK: vhadd.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vhadd_s16(int16x4_t a, int16x4_t b) {
   return vhadd_s16(a, b);
 }
 
-// CHECK: test_vhadd_s32
+// CHECK-LABEL: test_vhadd_s32
 // CHECK: vhadd.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vhadd_s32(int32x2_t a, int32x2_t b) {
   return vhadd_s32(a, b);
 }
 
-// CHECK: test_vhadd_u8
+// CHECK-LABEL: test_vhadd_u8
 // CHECK: vhadd.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vhadd_u8(uint8x8_t a, uint8x8_t b) {
   return vhadd_u8(a, b);
 }
 
-// CHECK: test_vhadd_u16
+// CHECK-LABEL: test_vhadd_u16
 // CHECK: vhadd.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vhadd_u16(uint16x4_t a, uint16x4_t b) {
   return vhadd_u16(a, b);
 }
 
-// CHECK: test_vhadd_u32
+// CHECK-LABEL: test_vhadd_u32
 // CHECK: vhadd.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vhadd_u32(uint32x2_t a, uint32x2_t b) {
   return vhadd_u32(a, b);
 }
 
-// CHECK: test_vhaddq_s8
+// CHECK-LABEL: test_vhaddq_s8
 // CHECK: vhadd.s8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vhaddq_s8(int8x16_t a, int8x16_t b) {
   return vhaddq_s8(a, b);
 }
 
-// CHECK: test_vhaddq_s16
+// CHECK-LABEL: test_vhaddq_s16
 // CHECK: vhadd.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vhaddq_s16(int16x8_t a, int16x8_t b) {
   return vhaddq_s16(a, b);
 }
 
-// CHECK: test_vhaddq_s32
+// CHECK-LABEL: test_vhaddq_s32
 // CHECK: vhadd.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vhaddq_s32(int32x4_t a, int32x4_t b) {
   return vhaddq_s32(a, b);
 }
 
-// CHECK: test_vhaddq_u8
+// CHECK-LABEL: test_vhaddq_u8
 // CHECK: vhadd.u8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vhaddq_u8(uint8x16_t a, uint8x16_t b) {
   return vhaddq_u8(a, b);
 }
 
-// CHECK: test_vhaddq_u16
+// CHECK-LABEL: test_vhaddq_u16
 // CHECK: vhadd.u16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vhaddq_u16(uint16x8_t a, uint16x8_t b) {
   return vhaddq_u16(a, b);
 }
 
-// CHECK: test_vhaddq_u32
+// CHECK-LABEL: test_vhaddq_u32
 // CHECK: vhadd.u32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vhaddq_u32(uint32x4_t a, uint32x4_t b) {
   return vhaddq_u32(a, b);
 }
 
 
-// CHECK: test_vhsub_s8
+// CHECK-LABEL: test_vhsub_s8
 // CHECK: vhsub.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vhsub_s8(int8x8_t a, int8x8_t b) {
   return vhsub_s8(a, b);
 }
 
-// CHECK: test_vhsub_s16
+// CHECK-LABEL: test_vhsub_s16
 // CHECK: vhsub.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vhsub_s16(int16x4_t a, int16x4_t b) {
   return vhsub_s16(a, b);
 }
 
-// CHECK: test_vhsub_s32
+// CHECK-LABEL: test_vhsub_s32
 // CHECK: vhsub.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vhsub_s32(int32x2_t a, int32x2_t b) {
   return vhsub_s32(a, b);
 }
 
-// CHECK: test_vhsub_u8
+// CHECK-LABEL: test_vhsub_u8
 // CHECK: vhsub.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vhsub_u8(uint8x8_t a, uint8x8_t b) {
   return vhsub_u8(a, b);
 }
 
-// CHECK: test_vhsub_u16
+// CHECK-LABEL: test_vhsub_u16
 // CHECK: vhsub.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vhsub_u16(uint16x4_t a, uint16x4_t b) {
   return vhsub_u16(a, b);
 }
 
-// CHECK: test_vhsub_u32
+// CHECK-LABEL: test_vhsub_u32
 // CHECK: vhsub.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vhsub_u32(uint32x2_t a, uint32x2_t b) {
   return vhsub_u32(a, b);
 }
 
-// CHECK: test_vhsubq_s8
+// CHECK-LABEL: test_vhsubq_s8
 // CHECK: vhsub.s8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vhsubq_s8(int8x16_t a, int8x16_t b) {
   return vhsubq_s8(a, b);
 }
 
-// CHECK: test_vhsubq_s16
+// CHECK-LABEL: test_vhsubq_s16
 // CHECK: vhsub.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vhsubq_s16(int16x8_t a, int16x8_t b) {
   return vhsubq_s16(a, b);
 }
 
-// CHECK: test_vhsubq_s32
+// CHECK-LABEL: test_vhsubq_s32
 // CHECK: vhsub.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vhsubq_s32(int32x4_t a, int32x4_t b) {
   return vhsubq_s32(a, b);
 }
 
-// CHECK: test_vhsubq_u8
+// CHECK-LABEL: test_vhsubq_u8
 // CHECK: vhsub.u8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vhsubq_u8(uint8x16_t a, uint8x16_t b) {
   return vhsubq_u8(a, b);
 }
 
-// CHECK: test_vhsubq_u16
+// CHECK-LABEL: test_vhsubq_u16
 // CHECK: vhsub.u16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vhsubq_u16(uint16x8_t a, uint16x8_t b) {
   return vhsubq_u16(a, b);
 }
 
-// CHECK: test_vhsubq_u32
+// CHECK-LABEL: test_vhsubq_u32
 // CHECK: vhsub.u32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vhsubq_u32(uint32x4_t a, uint32x4_t b) {
   return vhsubq_u32(a, b);
 }
 
 
-// CHECK: test_vld1q_u8
+// CHECK-LABEL: test_vld1q_u8
 // CHECK: vld1.8 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 uint8x16_t test_vld1q_u8(uint8_t const * a) {
   return vld1q_u8(a);
 }
 
-// CHECK: test_vld1q_u16
+// CHECK-LABEL: test_vld1q_u16
 // CHECK: vld1.16 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 uint16x8_t test_vld1q_u16(uint16_t const * a) {
   return vld1q_u16(a);
 }
 
-// CHECK: test_vld1q_u32
+// CHECK-LABEL: test_vld1q_u32
 // CHECK: vld1.32 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 uint32x4_t test_vld1q_u32(uint32_t const * a) {
   return vld1q_u32(a);
 }
 
-// CHECK: test_vld1q_u64
-// CHECK: vld1.64 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
+// CHECK-LABEL: test_vld1q_u64
+// CHECK: vld1.64 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}{{(:64)?}}]
 uint64x2_t test_vld1q_u64(uint64_t const * a) {
   return vld1q_u64(a);
 }
 
-// CHECK: test_vld1q_s8
+// CHECK-LABEL: test_vld1q_s8
 // CHECK: vld1.8 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 int8x16_t test_vld1q_s8(int8_t const * a) {
   return vld1q_s8(a);
 }
 
-// CHECK: test_vld1q_s16
+// CHECK-LABEL: test_vld1q_s16
 // CHECK: vld1.16 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 int16x8_t test_vld1q_s16(int16_t const * a) {
   return vld1q_s16(a);
 }
 
-// CHECK: test_vld1q_s32
+// CHECK-LABEL: test_vld1q_s32
 // CHECK: vld1.32 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 int32x4_t test_vld1q_s32(int32_t const * a) {
   return vld1q_s32(a);
 }
 
-// CHECK: test_vld1q_s64
-// CHECK: vld1.64 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
+// CHECK-LABEL: test_vld1q_s64
+// CHECK: vld1.64 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}{{(:64)?}}]
 int64x2_t test_vld1q_s64(int64_t const * a) {
   return vld1q_s64(a);
 }
 
-// CHECK: test_vld1q_f16
+// CHECK-LABEL: test_vld1q_f16
 // CHECK: vld1.16 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 float16x8_t test_vld1q_f16(float16_t const * a) {
   return vld1q_f16(a);
 }
 
-// CHECK: test_vld1q_f32
+// CHECK-LABEL: test_vld1q_f32
 // CHECK: vld1.32 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 float32x4_t test_vld1q_f32(float32_t const * a) {
   return vld1q_f32(a);
 }
 
-// CHECK: test_vld1q_p8
+// CHECK-LABEL: test_vld1q_p8
 // CHECK: vld1.8 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 poly8x16_t test_vld1q_p8(poly8_t const * a) {
   return vld1q_p8(a);
 }
 
-// CHECK: test_vld1q_p16
+// CHECK-LABEL: test_vld1q_p16
 // CHECK: vld1.16 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 poly16x8_t test_vld1q_p16(poly16_t const * a) {
   return vld1q_p16(a);
 }
 
-// CHECK: test_vld1_u8
+// CHECK-LABEL: test_vld1_u8
 // CHECK: vld1.8 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 uint8x8_t test_vld1_u8(uint8_t const * a) {
   return vld1_u8(a);
 }
 
-// CHECK: test_vld1_u16
+// CHECK-LABEL: test_vld1_u16
 // CHECK: vld1.16 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 uint16x4_t test_vld1_u16(uint16_t const * a) {
   return vld1_u16(a);
 }
 
-// CHECK: test_vld1_u32
+// CHECK-LABEL: test_vld1_u32
 // CHECK: vld1.32 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 uint32x2_t test_vld1_u32(uint32_t const * a) {
   return vld1_u32(a);
 }
 
-// CHECK: test_vld1_u64
-// CHECK: vld1.64 {d{{[0-9]+}}}, [r{{[0-9]+}}]
+// CHECK-LABEL: test_vld1_u64
+// CHECK: vld1.64 {d{{[0-9]+}}}, [r{{[0-9]+}}{{(:64)?}}]
 uint64x1_t test_vld1_u64(uint64_t const * a) {
   return vld1_u64(a);
 }
 
-// CHECK: test_vld1_s8
+// CHECK-LABEL: test_vld1_s8
 // CHECK: vld1.8 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 int8x8_t test_vld1_s8(int8_t const * a) {
   return vld1_s8(a);
 }
 
-// CHECK: test_vld1_s16
+// CHECK-LABEL: test_vld1_s16
 // CHECK: vld1.16 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 int16x4_t test_vld1_s16(int16_t const * a) {
   return vld1_s16(a);
 }
 
-// CHECK: test_vld1_s32
+// CHECK-LABEL: test_vld1_s32
 // CHECK: vld1.32 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 int32x2_t test_vld1_s32(int32_t const * a) {
   return vld1_s32(a);
 }
 
-// CHECK: test_vld1_s64
-// CHECK: vld1.64 {d{{[0-9]+}}}, [r{{[0-9]+}}]
+// CHECK-LABEL: test_vld1_s64
+// CHECK: vld1.64 {d{{[0-9]+}}}, [r{{[0-9]+}}{{(:64)?}}]
 int64x1_t test_vld1_s64(int64_t const * a) {
   return vld1_s64(a);
 }
 
-// CHECK: test_vld1_f16
+// CHECK-LABEL: test_vld1_f16
 // CHECK: vld1.16 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 float16x4_t test_vld1_f16(float16_t const * a) {
   return vld1_f16(a);
 }
 
-// CHECK: test_vld1_f32
+// CHECK-LABEL: test_vld1_f32
 // CHECK: vld1.32 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 float32x2_t test_vld1_f32(float32_t const * a) {
   return vld1_f32(a);
 }
 
-// CHECK: test_vld1_p8
+// CHECK-LABEL: test_vld1_p8
 // CHECK: vld1.8 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 poly8x8_t test_vld1_p8(poly8_t const * a) {
   return vld1_p8(a);
 }
 
-// CHECK: test_vld1_p16
+// CHECK-LABEL: test_vld1_p16
 // CHECK: vld1.16 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 poly16x4_t test_vld1_p16(poly16_t const * a) {
   return vld1_p16(a);
 }
 
 
-// CHECK: test_vld1q_dup_u8
+// CHECK-LABEL: test_vld1q_dup_u8
 // CHECK: vld1.8 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 uint8x16_t test_vld1q_dup_u8(uint8_t const * a) {
   return vld1q_dup_u8(a);
 }
 
-// CHECK: test_vld1q_dup_u16
+// CHECK-LABEL: test_vld1q_dup_u16
 // CHECK: vld1.16 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}:16]
 uint16x8_t test_vld1q_dup_u16(uint16_t const * a) {
   return vld1q_dup_u16(a);
 }
 
-// CHECK: test_vld1q_dup_u32
+// CHECK-LABEL: test_vld1q_dup_u32
 // CHECK: vld1.32 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}:32]
 uint32x4_t test_vld1q_dup_u32(uint32_t const * a) {
   return vld1q_dup_u32(a);
 }
 
-// CHECK: test_vld1q_dup_u64
+// CHECK-LABEL: test_vld1q_dup_u64
 // CHECK: {{ldr|vldr|vmov}}
 uint64x2_t test_vld1q_dup_u64(uint64_t const * a) {
   return vld1q_dup_u64(a);
 }
 
-// CHECK: test_vld1q_dup_s8
+// CHECK-LABEL: test_vld1q_dup_s8
 // CHECK: vld1.8 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 int8x16_t test_vld1q_dup_s8(int8_t const * a) {
   return vld1q_dup_s8(a);
 }
 
-// CHECK: test_vld1q_dup_s16
+// CHECK-LABEL: test_vld1q_dup_s16
 // CHECK: vld1.16 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}:16]
 int16x8_t test_vld1q_dup_s16(int16_t const * a) {
   return vld1q_dup_s16(a);
 }
 
-// CHECK: test_vld1q_dup_s32
+// CHECK-LABEL: test_vld1q_dup_s32
 // CHECK: vld1.32 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}:32]
 int32x4_t test_vld1q_dup_s32(int32_t const * a) {
   return vld1q_dup_s32(a);
 }
 
-// CHECK: test_vld1q_dup_s64
+// CHECK-LABEL: test_vld1q_dup_s64
 // CHECK: {{ldr|vldr|vmov}}
 int64x2_t test_vld1q_dup_s64(int64_t const * a) {
   return vld1q_dup_s64(a);
 }
 
-// CHECK: test_vld1q_dup_f16
+// CHECK-LABEL: test_vld1q_dup_f16
 // CHECK: vld1.16 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}:16]
 float16x8_t test_vld1q_dup_f16(float16_t const * a) {
   return vld1q_dup_f16(a);
 }
 
-// CHECK: test_vld1q_dup_f32
+// CHECK-LABEL: test_vld1q_dup_f32
 // CHECK: vld1.32 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}:32]
 float32x4_t test_vld1q_dup_f32(float32_t const * a) {
   return vld1q_dup_f32(a);
 }
 
-// CHECK: test_vld1q_dup_p8
+// CHECK-LABEL: test_vld1q_dup_p8
 // CHECK: vld1.8 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 poly8x16_t test_vld1q_dup_p8(poly8_t const * a) {
   return vld1q_dup_p8(a);
 }
 
-// CHECK: test_vld1q_dup_p16
+// CHECK-LABEL: test_vld1q_dup_p16
 // CHECK: vld1.16 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}:16]
 poly16x8_t test_vld1q_dup_p16(poly16_t const * a) {
   return vld1q_dup_p16(a);
 }
 
-// CHECK: test_vld1_dup_u8
+// CHECK-LABEL: test_vld1_dup_u8
 // CHECK: vld1.8 {d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 uint8x8_t test_vld1_dup_u8(uint8_t const * a) {
   return vld1_dup_u8(a);
 }
 
-// CHECK: test_vld1_dup_u16
+// CHECK-LABEL: test_vld1_dup_u16
 // CHECK: vld1.16 {d{{[0-9]+}}[]}, [r{{[0-9]+}}:16]
 uint16x4_t test_vld1_dup_u16(uint16_t const * a) {
   return vld1_dup_u16(a);
 }
 
-// CHECK: test_vld1_dup_u32
+// CHECK-LABEL: test_vld1_dup_u32
 // CHECK: vld1.32 {d{{[0-9]+}}[]}, [r{{[0-9]+}}:32]
 uint32x2_t test_vld1_dup_u32(uint32_t const * a) {
   return vld1_dup_u32(a);
 }
 
-// CHECK: test_vld1_dup_u64
+// CHECK-LABEL: test_vld1_dup_u64
 // CHECK: {{ldr|vldr|vmov}}
 uint64x1_t test_vld1_dup_u64(uint64_t const * a) {
   return vld1_dup_u64(a);
 }
 
-// CHECK: test_vld1_dup_s8
+// CHECK-LABEL: test_vld1_dup_s8
 // CHECK: vld1.8 {d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 int8x8_t test_vld1_dup_s8(int8_t const * a) {
   return vld1_dup_s8(a);
 }
 
-// CHECK: test_vld1_dup_s16
+// CHECK-LABEL: test_vld1_dup_s16
 // CHECK: vld1.16 {d{{[0-9]+}}[]}, [r{{[0-9]+}}:16]
 int16x4_t test_vld1_dup_s16(int16_t const * a) {
   return vld1_dup_s16(a);
 }
 
-// CHECK: test_vld1_dup_s32
+// CHECK-LABEL: test_vld1_dup_s32
 // CHECK: vld1.32 {d{{[0-9]+}}[]}, [r{{[0-9]+}}:32]
 int32x2_t test_vld1_dup_s32(int32_t const * a) {
   return vld1_dup_s32(a);
 }
 
-// CHECK: test_vld1_dup_s64
+// CHECK-LABEL: test_vld1_dup_s64
 // CHECK: {{ldr|vldr|vmov}}
 int64x1_t test_vld1_dup_s64(int64_t const * a) {
   return vld1_dup_s64(a);
 }
 
-// CHECK: test_vld1_dup_f16
+// CHECK-LABEL: test_vld1_dup_f16
 // CHECK: vld1.16 {d{{[0-9]+}}[]}, [r{{[0-9]+}}:16]
 float16x4_t test_vld1_dup_f16(float16_t const * a) {
   return vld1_dup_f16(a);
 }
 
-// CHECK: test_vld1_dup_f32
+// CHECK-LABEL: test_vld1_dup_f32
 // CHECK: vld1.32 {d{{[0-9]+}}[]}, [r{{[0-9]+}}:32]
 float32x2_t test_vld1_dup_f32(float32_t const * a) {
   return vld1_dup_f32(a);
 }
 
-// CHECK: test_vld1_dup_p8
+// CHECK-LABEL: test_vld1_dup_p8
 // CHECK: vld1.8 {d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 poly8x8_t test_vld1_dup_p8(poly8_t const * a) {
   return vld1_dup_p8(a);
 }
 
-// CHECK: test_vld1_dup_p16
+// CHECK-LABEL: test_vld1_dup_p16
 // CHECK: vld1.16 {d{{[0-9]+}}[]}, [r{{[0-9]+}}:16]
 poly16x4_t test_vld1_dup_p16(poly16_t const * a) {
   return vld1_dup_p16(a);
 }
 
 
-// CHECK: test_vld1q_lane_u8
+// CHECK-LABEL: test_vld1q_lane_u8
 // CHECK: vld1.8 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 uint8x16_t test_vld1q_lane_u8(uint8_t const * a, uint8x16_t b) {
   return vld1q_lane_u8(a, b, 15);
 }
 
-// CHECK: test_vld1q_lane_u16
+// CHECK-LABEL: test_vld1q_lane_u16
 // CHECK: vld1.16 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:16]
 uint16x8_t test_vld1q_lane_u16(uint16_t const * a, uint16x8_t b) {
   return vld1q_lane_u16(a, b, 7);
 }
 
-// CHECK: test_vld1q_lane_u32
+// CHECK-LABEL: test_vld1q_lane_u32
 // CHECK: vld1.32 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:32]
 uint32x4_t test_vld1q_lane_u32(uint32_t const * a, uint32x4_t b) {
   return vld1q_lane_u32(a, b, 3);
 }
 
-// CHECK: test_vld1q_lane_u64
+// CHECK-LABEL: test_vld1q_lane_u64
 // CHECK: {{ldr|vldr|vmov}}
 uint64x2_t test_vld1q_lane_u64(uint64_t const * a, uint64x2_t b) {
   return vld1q_lane_u64(a, b, 1);
 }
 
-// CHECK: test_vld1q_lane_s8
+// CHECK-LABEL: test_vld1q_lane_s8
 // CHECK: vld1.8 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 int8x16_t test_vld1q_lane_s8(int8_t const * a, int8x16_t b) {
   return vld1q_lane_s8(a, b, 15);
 }
 
-// CHECK: test_vld1q_lane_s16
+// CHECK-LABEL: test_vld1q_lane_s16
 // CHECK: vld1.16 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:16]
 int16x8_t test_vld1q_lane_s16(int16_t const * a, int16x8_t b) {
   return vld1q_lane_s16(a, b, 7);
 }
 
-// CHECK: test_vld1q_lane_s32
+// CHECK-LABEL: test_vld1q_lane_s32
 // CHECK: vld1.32 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:32]
 int32x4_t test_vld1q_lane_s32(int32_t const * a, int32x4_t b) {
   return vld1q_lane_s32(a, b, 3);
 }
 
-// CHECK: test_vld1q_lane_s64
+// CHECK-LABEL: test_vld1q_lane_s64
 // CHECK: {{ldr|vldr|vmov}}
 int64x2_t test_vld1q_lane_s64(int64_t const * a, int64x2_t b) {
   return vld1q_lane_s64(a, b, 1);
 }
 
-// CHECK: test_vld1q_lane_f16
+// CHECK-LABEL: test_vld1q_lane_f16
 // CHECK: vld1.16 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:16]
 float16x8_t test_vld1q_lane_f16(float16_t const * a, float16x8_t b) {
   return vld1q_lane_f16(a, b, 7);
 }
 
-// CHECK: test_vld1q_lane_f32
+// CHECK-LABEL: test_vld1q_lane_f32
 // CHECK: vld1.32 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:32]
 float32x4_t test_vld1q_lane_f32(float32_t const * a, float32x4_t b) {
   return vld1q_lane_f32(a, b, 3);
 }
 
-// CHECK: test_vld1q_lane_p8
+// CHECK-LABEL: test_vld1q_lane_p8
 // CHECK: vld1.8 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 poly8x16_t test_vld1q_lane_p8(poly8_t const * a, poly8x16_t b) {
   return vld1q_lane_p8(a, b, 15);
 }
 
-// CHECK: test_vld1q_lane_p16
+// CHECK-LABEL: test_vld1q_lane_p16
 // CHECK: vld1.16 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:16]
 poly16x8_t test_vld1q_lane_p16(poly16_t const * a, poly16x8_t b) {
   return vld1q_lane_p16(a, b, 7);
 }
 
-// CHECK: test_vld1_lane_u8
+// CHECK-LABEL: test_vld1_lane_u8
 // CHECK: vld1.8 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 uint8x8_t test_vld1_lane_u8(uint8_t const * a, uint8x8_t b) {
   return vld1_lane_u8(a, b, 7);
 }
 
-// CHECK: test_vld1_lane_u16
+// CHECK-LABEL: test_vld1_lane_u16
 // CHECK: vld1.16 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:16]
 uint16x4_t test_vld1_lane_u16(uint16_t const * a, uint16x4_t b) {
   return vld1_lane_u16(a, b, 3);
 }
 
-// CHECK: test_vld1_lane_u32
+// CHECK-LABEL: test_vld1_lane_u32
 // CHECK: vld1.32 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:32]
 uint32x2_t test_vld1_lane_u32(uint32_t const * a, uint32x2_t b) {
   return vld1_lane_u32(a, b, 1);
 }
 
-// CHECK: test_vld1_lane_u64
+// CHECK-LABEL: test_vld1_lane_u64
 // CHECK: {{ldr|vldr|vmov}}
 uint64x1_t test_vld1_lane_u64(uint64_t const * a, uint64x1_t b) {
   return vld1_lane_u64(a, b, 0);
 }
 
-// CHECK: test_vld1_lane_s8
+// CHECK-LABEL: test_vld1_lane_s8
 // CHECK: vld1.8 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 int8x8_t test_vld1_lane_s8(int8_t const * a, int8x8_t b) {
   return vld1_lane_s8(a, b, 7);
 }
 
-// CHECK: test_vld1_lane_s16
+// CHECK-LABEL: test_vld1_lane_s16
 // CHECK: vld1.16 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:16]
 int16x4_t test_vld1_lane_s16(int16_t const * a, int16x4_t b) {
   return vld1_lane_s16(a, b, 3);
 }
 
-// CHECK: test_vld1_lane_s32
+// CHECK-LABEL: test_vld1_lane_s32
 // CHECK: vld1.32 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:32]
 int32x2_t test_vld1_lane_s32(int32_t const * a, int32x2_t b) {
   return vld1_lane_s32(a, b, 1);
 }
 
-// CHECK: test_vld1_lane_s64
+// CHECK-LABEL: test_vld1_lane_s64
 // CHECK: {{ldr|vldr|vmov}}
 int64x1_t test_vld1_lane_s64(int64_t const * a, int64x1_t b) {
   return vld1_lane_s64(a, b, 0);
 }
 
-// CHECK: test_vld1_lane_f16
+// CHECK-LABEL: test_vld1_lane_f16
 // CHECK: vld1.16 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:16]
 float16x4_t test_vld1_lane_f16(float16_t const * a, float16x4_t b) {
   return vld1_lane_f16(a, b, 3);
 }
 
-// CHECK: test_vld1_lane_f32
+// CHECK-LABEL: test_vld1_lane_f32
 // CHECK: vld1.32 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:32]
 float32x2_t test_vld1_lane_f32(float32_t const * a, float32x2_t b) {
   return vld1_lane_f32(a, b, 1);
 }
 
-// CHECK: test_vld1_lane_p8
+// CHECK-LABEL: test_vld1_lane_p8
 // CHECK: vld1.8 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 poly8x8_t test_vld1_lane_p8(poly8_t const * a, poly8x8_t b) {
   return vld1_lane_p8(a, b, 7);
 }
 
-// CHECK: test_vld1_lane_p16
+// CHECK-LABEL: test_vld1_lane_p16
 // CHECK: vld1.16 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:16]
 poly16x4_t test_vld1_lane_p16(poly16_t const * a, poly16x4_t b) {
   return vld1_lane_p16(a, b, 3);
 }
 
 
-// CHECK: test_vld2q_u8
+// CHECK-LABEL: test_vld2q_u8
 // CHECK: vld2.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 uint8x16x2_t test_vld2q_u8(uint8_t const * a) {
   return vld2q_u8(a);
 }
 
-// CHECK: test_vld2q_u16
+// CHECK-LABEL: test_vld2q_u16
 // CHECK: vld2.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 uint16x8x2_t test_vld2q_u16(uint16_t const * a) {
   return vld2q_u16(a);
 }
 
-// CHECK: test_vld2q_u32
+// CHECK-LABEL: test_vld2q_u32
 // CHECK: vld2.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 uint32x4x2_t test_vld2q_u32(uint32_t const * a) {
   return vld2q_u32(a);
 }
 
-// CHECK: test_vld2q_s8
+// CHECK-LABEL: test_vld2q_s8
 // CHECK: vld2.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 int8x16x2_t test_vld2q_s8(int8_t const * a) {
   return vld2q_s8(a);
 }
 
-// CHECK: test_vld2q_s16
+// CHECK-LABEL: test_vld2q_s16
 // CHECK: vld2.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 int16x8x2_t test_vld2q_s16(int16_t const * a) {
   return vld2q_s16(a);
 }
 
-// CHECK: test_vld2q_s32
+// CHECK-LABEL: test_vld2q_s32
 // CHECK: vld2.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 int32x4x2_t test_vld2q_s32(int32_t const * a) {
   return vld2q_s32(a);
 }
 
-// CHECK: test_vld2q_f16
+// CHECK-LABEL: test_vld2q_f16
 // CHECK: vld2.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 float16x8x2_t test_vld2q_f16(float16_t const * a) {
   return vld2q_f16(a);
 }
 
-// CHECK: test_vld2q_f32
+// CHECK-LABEL: test_vld2q_f32
 // CHECK: vld2.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 float32x4x2_t test_vld2q_f32(float32_t const * a) {
   return vld2q_f32(a);
 }
 
-// CHECK: test_vld2q_p8
+// CHECK-LABEL: test_vld2q_p8
 // CHECK: vld2.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 poly8x16x2_t test_vld2q_p8(poly8_t const * a) {
   return vld2q_p8(a);
 }
 
-// CHECK: test_vld2q_p16
+// CHECK-LABEL: test_vld2q_p16
 // CHECK: vld2.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 poly16x8x2_t test_vld2q_p16(poly16_t const * a) {
   return vld2q_p16(a);
 }
 
-// CHECK: test_vld2_u8
+// CHECK-LABEL: test_vld2_u8
 // CHECK: vld2.8 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 uint8x8x2_t test_vld2_u8(uint8_t const * a) {
   return vld2_u8(a);
 }
 
-// CHECK: test_vld2_u16
+// CHECK-LABEL: test_vld2_u16
 // CHECK: vld2.16 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 uint16x4x2_t test_vld2_u16(uint16_t const * a) {
   return vld2_u16(a);
 }
 
-// CHECK: test_vld2_u32
+// CHECK-LABEL: test_vld2_u32
 // CHECK: vld2.32 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 uint32x2x2_t test_vld2_u32(uint32_t const * a) {
   return vld2_u32(a);
 }
 
-// CHECK: test_vld2_u64
+// CHECK-LABEL: test_vld2_u64
 // CHECK: vld1.64
 uint64x1x2_t test_vld2_u64(uint64_t const * a) {
   return vld2_u64(a);
 }
 
-// CHECK: test_vld2_s8
+// CHECK-LABEL: test_vld2_s8
 // CHECK: vld2.8 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 int8x8x2_t test_vld2_s8(int8_t const * a) {
   return vld2_s8(a);
 }
 
-// CHECK: test_vld2_s16
+// CHECK-LABEL: test_vld2_s16
 // CHECK: vld2.16 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 int16x4x2_t test_vld2_s16(int16_t const * a) {
   return vld2_s16(a);
 }
 
-// CHECK: test_vld2_s32
+// CHECK-LABEL: test_vld2_s32
 // CHECK: vld2.32 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 int32x2x2_t test_vld2_s32(int32_t const * a) {
   return vld2_s32(a);
 }
 
-// CHECK: test_vld2_s64
+// CHECK-LABEL: test_vld2_s64
 // CHECK: vld1.64
 int64x1x2_t test_vld2_s64(int64_t const * a) {
   return vld2_s64(a);
 }
 
-// CHECK: test_vld2_f16
+// CHECK-LABEL: test_vld2_f16
 // CHECK: vld2.16 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 float16x4x2_t test_vld2_f16(float16_t const * a) {
   return vld2_f16(a);
 }
 
-// CHECK: test_vld2_f32
+// CHECK-LABEL: test_vld2_f32
 // CHECK: vld2.32 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 float32x2x2_t test_vld2_f32(float32_t const * a) {
   return vld2_f32(a);
 }
 
-// CHECK: test_vld2_p8
+// CHECK-LABEL: test_vld2_p8
 // CHECK: vld2.8 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 poly8x8x2_t test_vld2_p8(poly8_t const * a) {
   return vld2_p8(a);
 }
 
-// CHECK: test_vld2_p16
+// CHECK-LABEL: test_vld2_p16
 // CHECK: vld2.16 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 poly16x4x2_t test_vld2_p16(poly16_t const * a) {
   return vld2_p16(a);
 }
 
 
-// CHECK: test_vld2_dup_u8
+// CHECK-LABEL: test_vld2_dup_u8
 // CHECK: vld2.8 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 uint8x8x2_t test_vld2_dup_u8(uint8_t const * a) {
   return vld2_dup_u8(a);
 }
 
-// CHECK: test_vld2_dup_u16
+// CHECK-LABEL: test_vld2_dup_u16
 // CHECK: vld2.16 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 uint16x4x2_t test_vld2_dup_u16(uint16_t const * a) {
   return vld2_dup_u16(a);
 }
 
-// CHECK: test_vld2_dup_u32
+// CHECK-LABEL: test_vld2_dup_u32
 // CHECK: vld2.32 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 uint32x2x2_t test_vld2_dup_u32(uint32_t const * a) {
   return vld2_dup_u32(a);
 }
 
-// CHECK: test_vld2_dup_u64
+// CHECK-LABEL: test_vld2_dup_u64
 // CHECK: vld1.64
 uint64x1x2_t test_vld2_dup_u64(uint64_t const * a) {
   return vld2_dup_u64(a);
 }
 
-// CHECK: test_vld2_dup_s8
+// CHECK-LABEL: test_vld2_dup_s8
 // CHECK: vld2.8 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 int8x8x2_t test_vld2_dup_s8(int8_t const * a) {
   return vld2_dup_s8(a);
 }
 
-// CHECK: test_vld2_dup_s16
+// CHECK-LABEL: test_vld2_dup_s16
 // CHECK: vld2.16 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 int16x4x2_t test_vld2_dup_s16(int16_t const * a) {
   return vld2_dup_s16(a);
 }
 
-// CHECK: test_vld2_dup_s32
+// CHECK-LABEL: test_vld2_dup_s32
 // CHECK: vld2.32 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 int32x2x2_t test_vld2_dup_s32(int32_t const * a) {
   return vld2_dup_s32(a);
 }
 
-// CHECK: test_vld2_dup_s64
+// CHECK-LABEL: test_vld2_dup_s64
 // CHECK: vld1.64
 int64x1x2_t test_vld2_dup_s64(int64_t const * a) {
   return vld2_dup_s64(a);
 }
 
-// CHECK: test_vld2_dup_f16
+// CHECK-LABEL: test_vld2_dup_f16
 // CHECK: vld2.16 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 float16x4x2_t test_vld2_dup_f16(float16_t const * a) {
   return vld2_dup_f16(a);
 }
 
-// CHECK: test_vld2_dup_f32
+// CHECK-LABEL: test_vld2_dup_f32
 // CHECK: vld2.32 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 float32x2x2_t test_vld2_dup_f32(float32_t const * a) {
   return vld2_dup_f32(a);
 }
 
-// CHECK: test_vld2_dup_p8
+// CHECK-LABEL: test_vld2_dup_p8
 // CHECK: vld2.8 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 poly8x8x2_t test_vld2_dup_p8(poly8_t const * a) {
   return vld2_dup_p8(a);
 }
 
-// CHECK: test_vld2_dup_p16
+// CHECK-LABEL: test_vld2_dup_p16
 // CHECK: vld2.16 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 poly16x4x2_t test_vld2_dup_p16(poly16_t const * a) {
   return vld2_dup_p16(a);
 }
 
 
-// CHECK: test_vld2q_lane_u16
+// CHECK-LABEL: test_vld2q_lane_u16
 // CHECK: vld2.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 uint16x8x2_t test_vld2q_lane_u16(uint16_t const * a, uint16x8x2_t b) {
   return vld2q_lane_u16(a, b, 7);
 }
 
-// CHECK: test_vld2q_lane_u32
+// CHECK-LABEL: test_vld2q_lane_u32
 // CHECK: vld2.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 uint32x4x2_t test_vld2q_lane_u32(uint32_t const * a, uint32x4x2_t b) {
   return vld2q_lane_u32(a, b, 3);
 }
 
-// CHECK: test_vld2q_lane_s16
+// CHECK-LABEL: test_vld2q_lane_s16
 // CHECK: vld2.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 int16x8x2_t test_vld2q_lane_s16(int16_t const * a, int16x8x2_t b) {
   return vld2q_lane_s16(a, b, 7);
 }
 
-// CHECK: test_vld2q_lane_s32
+// CHECK-LABEL: test_vld2q_lane_s32
 // CHECK: vld2.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 int32x4x2_t test_vld2q_lane_s32(int32_t const * a, int32x4x2_t b) {
   return vld2q_lane_s32(a, b, 3);
 }
 
-// CHECK: test_vld2q_lane_f16
+// CHECK-LABEL: test_vld2q_lane_f16
 // CHECK: vld2.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 float16x8x2_t test_vld2q_lane_f16(float16_t const * a, float16x8x2_t b) {
   return vld2q_lane_f16(a, b, 7);
 }
 
-// CHECK: test_vld2q_lane_f32
+// CHECK-LABEL: test_vld2q_lane_f32
 // CHECK: vld2.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 float32x4x2_t test_vld2q_lane_f32(float32_t const * a, float32x4x2_t b) {
   return vld2q_lane_f32(a, b, 3);
 }
 
-// CHECK: test_vld2q_lane_p16
+// CHECK-LABEL: test_vld2q_lane_p16
 // CHECK: vld2.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 poly16x8x2_t test_vld2q_lane_p16(poly16_t const * a, poly16x8x2_t b) {
   return vld2q_lane_p16(a, b, 7);
 }
 
-// CHECK: test_vld2_lane_u8
+// CHECK-LABEL: test_vld2_lane_u8
 // CHECK: vld2.8 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 uint8x8x2_t test_vld2_lane_u8(uint8_t const * a, uint8x8x2_t b) {
   return vld2_lane_u8(a, b, 7);
 }
 
-// CHECK: test_vld2_lane_u16
+// CHECK-LABEL: test_vld2_lane_u16
 // CHECK: vld2.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 uint16x4x2_t test_vld2_lane_u16(uint16_t const * a, uint16x4x2_t b) {
   return vld2_lane_u16(a, b, 3);
 }
 
-// CHECK: test_vld2_lane_u32
+// CHECK-LABEL: test_vld2_lane_u32
 // CHECK: vld2.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 uint32x2x2_t test_vld2_lane_u32(uint32_t const * a, uint32x2x2_t b) {
   return vld2_lane_u32(a, b, 1);
 }
 
-// CHECK: test_vld2_lane_s8
+// CHECK-LABEL: test_vld2_lane_s8
 // CHECK: vld2.8 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 int8x8x2_t test_vld2_lane_s8(int8_t const * a, int8x8x2_t b) {
   return vld2_lane_s8(a, b, 7);
 }
 
-// CHECK: test_vld2_lane_s16
+// CHECK-LABEL: test_vld2_lane_s16
 // CHECK: vld2.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 int16x4x2_t test_vld2_lane_s16(int16_t const * a, int16x4x2_t b) {
   return vld2_lane_s16(a, b, 3);
 }
 
-// CHECK: test_vld2_lane_s32
+// CHECK-LABEL: test_vld2_lane_s32
 // CHECK: vld2.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 int32x2x2_t test_vld2_lane_s32(int32_t const * a, int32x2x2_t b) {
   return vld2_lane_s32(a, b, 1);
 }
 
-// CHECK: test_vld2_lane_f16
+// CHECK-LABEL: test_vld2_lane_f16
 // CHECK: vld2.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 float16x4x2_t test_vld2_lane_f16(float16_t const * a, float16x4x2_t b) {
   return vld2_lane_f16(a, b, 3);
 }
 
-// CHECK: test_vld2_lane_f32
+// CHECK-LABEL: test_vld2_lane_f32
 // CHECK: vld2.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 float32x2x2_t test_vld2_lane_f32(float32_t const * a, float32x2x2_t b) {
   return vld2_lane_f32(a, b, 1);
 }
 
-// CHECK: test_vld2_lane_p8
+// CHECK-LABEL: test_vld2_lane_p8
 // CHECK: vld2.8 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 poly8x8x2_t test_vld2_lane_p8(poly8_t const * a, poly8x8x2_t b) {
   return vld2_lane_p8(a, b, 7);
 }
 
-// CHECK: test_vld2_lane_p16
+// CHECK-LABEL: test_vld2_lane_p16
 // CHECK: vld2.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 poly16x4x2_t test_vld2_lane_p16(poly16_t const * a, poly16x4x2_t b) {
   return vld2_lane_p16(a, b, 3);
 }
 
 
-// CHECK: test_vld3q_u8
+// CHECK-LABEL: test_vld3q_u8
 // CHECK: vld3.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 uint8x16x3_t test_vld3q_u8(uint8_t const * a) {
   return vld3q_u8(a);
 }
 
-// CHECK: test_vld3q_u16
+// CHECK-LABEL: test_vld3q_u16
 // CHECK: vld3.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 uint16x8x3_t test_vld3q_u16(uint16_t const * a) {
   return vld3q_u16(a);
 }
 
-// CHECK: test_vld3q_u32
+// CHECK-LABEL: test_vld3q_u32
 // CHECK: vld3.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 uint32x4x3_t test_vld3q_u32(uint32_t const * a) {
   return vld3q_u32(a);
 }
 
-// CHECK: test_vld3q_s8
+// CHECK-LABEL: test_vld3q_s8
 // CHECK: vld3.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 int8x16x3_t test_vld3q_s8(int8_t const * a) {
   return vld3q_s8(a);
 }
 
-// CHECK: test_vld3q_s16
+// CHECK-LABEL: test_vld3q_s16
 // CHECK: vld3.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 int16x8x3_t test_vld3q_s16(int16_t const * a) {
   return vld3q_s16(a);
 }
 
-// CHECK: test_vld3q_s32
+// CHECK-LABEL: test_vld3q_s32
 // CHECK: vld3.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 int32x4x3_t test_vld3q_s32(int32_t const * a) {
   return vld3q_s32(a);
 }
 
-// CHECK: test_vld3q_f16
+// CHECK-LABEL: test_vld3q_f16
 // CHECK: vld3.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 float16x8x3_t test_vld3q_f16(float16_t const * a) {
   return vld3q_f16(a);
 }
 
-// CHECK: test_vld3q_f32
+// CHECK-LABEL: test_vld3q_f32
 // CHECK: vld3.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 float32x4x3_t test_vld3q_f32(float32_t const * a) {
   return vld3q_f32(a);
 }
 
-// CHECK: test_vld3q_p8
+// CHECK-LABEL: test_vld3q_p8
 // CHECK: vld3.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 poly8x16x3_t test_vld3q_p8(poly8_t const * a) {
   return vld3q_p8(a);
 }
 
-// CHECK: test_vld3q_p16
+// CHECK-LABEL: test_vld3q_p16
 // CHECK: vld3.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 poly16x8x3_t test_vld3q_p16(poly16_t const * a) {
   return vld3q_p16(a);
 }
 
-// CHECK: test_vld3_u8
+// CHECK-LABEL: test_vld3_u8
 // CHECK: vld3.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 uint8x8x3_t test_vld3_u8(uint8_t const * a) {
   return vld3_u8(a);
 }
 
-// CHECK: test_vld3_u16
+// CHECK-LABEL: test_vld3_u16
 // CHECK: vld3.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 uint16x4x3_t test_vld3_u16(uint16_t const * a) {
   return vld3_u16(a);
 }
 
-// CHECK: test_vld3_u32
+// CHECK-LABEL: test_vld3_u32
 // CHECK: vld3.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 uint32x2x3_t test_vld3_u32(uint32_t const * a) {
   return vld3_u32(a);
 }
 
-// CHECK: test_vld3_u64
+// CHECK-LABEL: test_vld3_u64
 // CHECK: vld1.64
 uint64x1x3_t test_vld3_u64(uint64_t const * a) {
   return vld3_u64(a);
 }
 
-// CHECK: test_vld3_s8
+// CHECK-LABEL: test_vld3_s8
 // CHECK: vld3.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 int8x8x3_t test_vld3_s8(int8_t const * a) {
   return vld3_s8(a);
 }
 
-// CHECK: test_vld3_s16
+// CHECK-LABEL: test_vld3_s16
 // CHECK: vld3.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 int16x4x3_t test_vld3_s16(int16_t const * a) {
   return vld3_s16(a);
 }
 
-// CHECK: test_vld3_s32
+// CHECK-LABEL: test_vld3_s32
 // CHECK: vld3.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 int32x2x3_t test_vld3_s32(int32_t const * a) {
   return vld3_s32(a);
 }
 
-// CHECK: test_vld3_s64
+// CHECK-LABEL: test_vld3_s64
 // CHECK: vld1.64
 int64x1x3_t test_vld3_s64(int64_t const * a) {
   return vld3_s64(a);
 }
 
-// CHECK: test_vld3_f16
+// CHECK-LABEL: test_vld3_f16
 // CHECK: vld3.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 float16x4x3_t test_vld3_f16(float16_t const * a) {
   return vld3_f16(a);
 }
 
-// CHECK: test_vld3_f32
+// CHECK-LABEL: test_vld3_f32
 // CHECK: vld3.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 float32x2x3_t test_vld3_f32(float32_t const * a) {
   return vld3_f32(a);
 }
 
-// CHECK: test_vld3_p8
+// CHECK-LABEL: test_vld3_p8
 // CHECK: vld3.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 poly8x8x3_t test_vld3_p8(poly8_t const * a) {
   return vld3_p8(a);
 }
 
-// CHECK: test_vld3_p16
+// CHECK-LABEL: test_vld3_p16
 // CHECK: vld3.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 poly16x4x3_t test_vld3_p16(poly16_t const * a) {
   return vld3_p16(a);
 }
 
 
-// CHECK: test_vld3_dup_u8
+// CHECK-LABEL: test_vld3_dup_u8
 // CHECK: vld3.8 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 uint8x8x3_t test_vld3_dup_u8(uint8_t const * a) {
   return vld3_dup_u8(a);
 }
 
-// CHECK: test_vld3_dup_u16
+// CHECK-LABEL: test_vld3_dup_u16
 // CHECK: vld3.16 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 uint16x4x3_t test_vld3_dup_u16(uint16_t const * a) {
   return vld3_dup_u16(a);
 }
 
-// CHECK: test_vld3_dup_u32
+// CHECK-LABEL: test_vld3_dup_u32
 // CHECK: vld3.32 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 uint32x2x3_t test_vld3_dup_u32(uint32_t const * a) {
   return vld3_dup_u32(a);
 }
 
-// CHECK: test_vld3_dup_u64
+// CHECK-LABEL: test_vld3_dup_u64
 // CHECK: vld1.64
 uint64x1x3_t test_vld3_dup_u64(uint64_t const * a) {
   return vld3_dup_u64(a);
 }
 
-// CHECK: test_vld3_dup_s8
+// CHECK-LABEL: test_vld3_dup_s8
 // CHECK: vld3.8 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 int8x8x3_t test_vld3_dup_s8(int8_t const * a) {
   return vld3_dup_s8(a);
 }
 
-// CHECK: test_vld3_dup_s16
+// CHECK-LABEL: test_vld3_dup_s16
 // CHECK: vld3.16 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 int16x4x3_t test_vld3_dup_s16(int16_t const * a) {
   return vld3_dup_s16(a);
 }
 
-// CHECK: test_vld3_dup_s32
+// CHECK-LABEL: test_vld3_dup_s32
 // CHECK: vld3.32 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 int32x2x3_t test_vld3_dup_s32(int32_t const * a) {
   return vld3_dup_s32(a);
 }
 
-// CHECK: test_vld3_dup_s64
+// CHECK-LABEL: test_vld3_dup_s64
 // CHECK: vld1.64
 int64x1x3_t test_vld3_dup_s64(int64_t const * a) {
   return vld3_dup_s64(a);
 }
 
-// CHECK: test_vld3_dup_f16
+// CHECK-LABEL: test_vld3_dup_f16
 // CHECK: vld3.16 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 float16x4x3_t test_vld3_dup_f16(float16_t const * a) {
   return vld3_dup_f16(a);
 }
 
-// CHECK: test_vld3_dup_f32
+// CHECK-LABEL: test_vld3_dup_f32
 // CHECK: vld3.32 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 float32x2x3_t test_vld3_dup_f32(float32_t const * a) {
   return vld3_dup_f32(a);
 }
 
-// CHECK: test_vld3_dup_p8
+// CHECK-LABEL: test_vld3_dup_p8
 // CHECK: vld3.8 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 poly8x8x3_t test_vld3_dup_p8(poly8_t const * a) {
   return vld3_dup_p8(a);
 }
 
-// CHECK: test_vld3_dup_p16
+// CHECK-LABEL: test_vld3_dup_p16
 // CHECK: vld3.16 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 poly16x4x3_t test_vld3_dup_p16(poly16_t const * a) {
   return vld3_dup_p16(a);
 }
 
 
-// CHECK: test_vld3q_lane_u16
+// CHECK-LABEL: test_vld3q_lane_u16
 // CHECK: vld3.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 uint16x8x3_t test_vld3q_lane_u16(uint16_t const * a, uint16x8x3_t b) {
   return vld3q_lane_u16(a, b, 7);
 }
 
-// CHECK: test_vld3q_lane_u32
+// CHECK-LABEL: test_vld3q_lane_u32
 // CHECK: vld3.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 uint32x4x3_t test_vld3q_lane_u32(uint32_t const * a, uint32x4x3_t b) {
   return vld3q_lane_u32(a, b, 3);
 }
 
-// CHECK: test_vld3q_lane_s16
+// CHECK-LABEL: test_vld3q_lane_s16
 // CHECK: vld3.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 int16x8x3_t test_vld3q_lane_s16(int16_t const * a, int16x8x3_t b) {
   return vld3q_lane_s16(a, b, 7);
 }
 
-// CHECK: test_vld3q_lane_s32
+// CHECK-LABEL: test_vld3q_lane_s32
 // CHECK: vld3.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 int32x4x3_t test_vld3q_lane_s32(int32_t const * a, int32x4x3_t b) {
   return vld3q_lane_s32(a, b, 3);
 }
 
-// CHECK: test_vld3q_lane_f16
+// CHECK-LABEL: test_vld3q_lane_f16
 // CHECK: vld3.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 float16x8x3_t test_vld3q_lane_f16(float16_t const * a, float16x8x3_t b) {
   return vld3q_lane_f16(a, b, 7);
 }
 
-// CHECK: test_vld3q_lane_f32
+// CHECK-LABEL: test_vld3q_lane_f32
 // CHECK: vld3.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 float32x4x3_t test_vld3q_lane_f32(float32_t const * a, float32x4x3_t b) {
   return vld3q_lane_f32(a, b, 3);
 }
 
-// CHECK: test_vld3q_lane_p16
+// CHECK-LABEL: test_vld3q_lane_p16
 // CHECK: vld3.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 poly16x8x3_t test_vld3q_lane_p16(poly16_t const * a, poly16x8x3_t b) {
   return vld3q_lane_p16(a, b, 7);
 }
 
-// CHECK: test_vld3_lane_u8
+// CHECK-LABEL: test_vld3_lane_u8
 // CHECK: vld3.8 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 uint8x8x3_t test_vld3_lane_u8(uint8_t const * a, uint8x8x3_t b) {
   return vld3_lane_u8(a, b, 7);
 }
 
-// CHECK: test_vld3_lane_u16
+// CHECK-LABEL: test_vld3_lane_u16
 // CHECK: vld3.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 uint16x4x3_t test_vld3_lane_u16(uint16_t const * a, uint16x4x3_t b) {
   return vld3_lane_u16(a, b, 3);
 }
 
-// CHECK: test_vld3_lane_u32
+// CHECK-LABEL: test_vld3_lane_u32
 // CHECK: vld3.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 uint32x2x3_t test_vld3_lane_u32(uint32_t const * a, uint32x2x3_t b) {
   return vld3_lane_u32(a, b, 1);
 }
 
-// CHECK: test_vld3_lane_s8
+// CHECK-LABEL: test_vld3_lane_s8
 // CHECK: vld3.8 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 int8x8x3_t test_vld3_lane_s8(int8_t const * a, int8x8x3_t b) {
   return vld3_lane_s8(a, b, 7);
 }
 
-// CHECK: test_vld3_lane_s16
+// CHECK-LABEL: test_vld3_lane_s16
 // CHECK: vld3.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 int16x4x3_t test_vld3_lane_s16(int16_t const * a, int16x4x3_t b) {
   return vld3_lane_s16(a, b, 3);
 }
 
-// CHECK: test_vld3_lane_s32
+// CHECK-LABEL: test_vld3_lane_s32
 // CHECK: vld3.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 int32x2x3_t test_vld3_lane_s32(int32_t const * a, int32x2x3_t b) {
   return vld3_lane_s32(a, b, 1);
 }
 
-// CHECK: test_vld3_lane_f16
+// CHECK-LABEL: test_vld3_lane_f16
 // CHECK: vld3.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 float16x4x3_t test_vld3_lane_f16(float16_t const * a, float16x4x3_t b) {
   return vld3_lane_f16(a, b, 3);
 }
 
-// CHECK: test_vld3_lane_f32
+// CHECK-LABEL: test_vld3_lane_f32
 // CHECK: vld3.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 float32x2x3_t test_vld3_lane_f32(float32_t const * a, float32x2x3_t b) {
   return vld3_lane_f32(a, b, 1);
 }
 
-// CHECK: test_vld3_lane_p8
+// CHECK-LABEL: test_vld3_lane_p8
 // CHECK: vld3.8 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 poly8x8x3_t test_vld3_lane_p8(poly8_t const * a, poly8x8x3_t b) {
   return vld3_lane_p8(a, b, 7);
 }
 
-// CHECK: test_vld3_lane_p16
+// CHECK-LABEL: test_vld3_lane_p16
 // CHECK: vld3.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 poly16x4x3_t test_vld3_lane_p16(poly16_t const * a, poly16x4x3_t b) {
   return vld3_lane_p16(a, b, 3);
 }
 
 
-// CHECK: test_vld4q_u8
+// CHECK-LABEL: test_vld4q_u8
 // CHECK: vld4.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 uint8x16x4_t test_vld4q_u8(uint8_t const * a) {
   return vld4q_u8(a);
 }
 
-// CHECK: test_vld4q_u16
+// CHECK-LABEL: test_vld4q_u16
 // CHECK: vld4.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 uint16x8x4_t test_vld4q_u16(uint16_t const * a) {
   return vld4q_u16(a);
 }
 
-// CHECK: test_vld4q_u32
+// CHECK-LABEL: test_vld4q_u32
 // CHECK: vld4.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 uint32x4x4_t test_vld4q_u32(uint32_t const * a) {
   return vld4q_u32(a);
 }
 
-// CHECK: test_vld4q_s8
+// CHECK-LABEL: test_vld4q_s8
 // CHECK: vld4.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 int8x16x4_t test_vld4q_s8(int8_t const * a) {
   return vld4q_s8(a);
 }
 
-// CHECK: test_vld4q_s16
+// CHECK-LABEL: test_vld4q_s16
 // CHECK: vld4.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 int16x8x4_t test_vld4q_s16(int16_t const * a) {
   return vld4q_s16(a);
 }
 
-// CHECK: test_vld4q_s32
+// CHECK-LABEL: test_vld4q_s32
 // CHECK: vld4.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 int32x4x4_t test_vld4q_s32(int32_t const * a) {
   return vld4q_s32(a);
 }
 
-// CHECK: test_vld4q_f16
+// CHECK-LABEL: test_vld4q_f16
 // CHECK: vld4.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 float16x8x4_t test_vld4q_f16(float16_t const * a) {
   return vld4q_f16(a);
 }
 
-// CHECK: test_vld4q_f32
+// CHECK-LABEL: test_vld4q_f32
 // CHECK: vld4.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 float32x4x4_t test_vld4q_f32(float32_t const * a) {
   return vld4q_f32(a);
 }
 
-// CHECK: test_vld4q_p8
+// CHECK-LABEL: test_vld4q_p8
 // CHECK: vld4.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 poly8x16x4_t test_vld4q_p8(poly8_t const * a) {
   return vld4q_p8(a);
 }
 
-// CHECK: test_vld4q_p16
+// CHECK-LABEL: test_vld4q_p16
 // CHECK: vld4.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 poly16x8x4_t test_vld4q_p16(poly16_t const * a) {
   return vld4q_p16(a);
 }
 
-// CHECK: test_vld4_u8
+// CHECK-LABEL: test_vld4_u8
 // CHECK: vld4.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 uint8x8x4_t test_vld4_u8(uint8_t const * a) {
   return vld4_u8(a);
 }
 
-// CHECK: test_vld4_u16
+// CHECK-LABEL: test_vld4_u16
 // CHECK: vld4.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 uint16x4x4_t test_vld4_u16(uint16_t const * a) {
   return vld4_u16(a);
 }
 
-// CHECK: test_vld4_u32
+// CHECK-LABEL: test_vld4_u32
 // CHECK: vld4.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 uint32x2x4_t test_vld4_u32(uint32_t const * a) {
   return vld4_u32(a);
 }
 
-// CHECK: test_vld4_u64
+// CHECK-LABEL: test_vld4_u64
 // CHECK: vld1.64
 uint64x1x4_t test_vld4_u64(uint64_t const * a) {
   return vld4_u64(a);
 }
 
-// CHECK: test_vld4_s8
+// CHECK-LABEL: test_vld4_s8
 // CHECK: vld4.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 int8x8x4_t test_vld4_s8(int8_t const * a) {
   return vld4_s8(a);
 }
 
-// CHECK: test_vld4_s16
+// CHECK-LABEL: test_vld4_s16
 // CHECK: vld4.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 int16x4x4_t test_vld4_s16(int16_t const * a) {
   return vld4_s16(a);
 }
 
-// CHECK: test_vld4_s32
+// CHECK-LABEL: test_vld4_s32
 // CHECK: vld4.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 int32x2x4_t test_vld4_s32(int32_t const * a) {
   return vld4_s32(a);
 }
 
-// CHECK: test_vld4_s64
+// CHECK-LABEL: test_vld4_s64
 // CHECK: vld1.64
 int64x1x4_t test_vld4_s64(int64_t const * a) {
   return vld4_s64(a);
 }
 
-// CHECK: test_vld4_f16
+// CHECK-LABEL: test_vld4_f16
 // CHECK: vld4.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 float16x4x4_t test_vld4_f16(float16_t const * a) {
   return vld4_f16(a);
 }
 
-// CHECK: test_vld4_f32
+// CHECK-LABEL: test_vld4_f32
 // CHECK: vld4.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 float32x2x4_t test_vld4_f32(float32_t const * a) {
   return vld4_f32(a);
 }
 
-// CHECK: test_vld4_p8
+// CHECK-LABEL: test_vld4_p8
 // CHECK: vld4.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 poly8x8x4_t test_vld4_p8(poly8_t const * a) {
   return vld4_p8(a);
 }
 
-// CHECK: test_vld4_p16
+// CHECK-LABEL: test_vld4_p16
 // CHECK: vld4.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 poly16x4x4_t test_vld4_p16(poly16_t const * a) {
   return vld4_p16(a);
 }
 
 
-// CHECK: test_vld4_dup_u8
+// CHECK-LABEL: test_vld4_dup_u8
 // CHECK: vld4.8 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 uint8x8x4_t test_vld4_dup_u8(uint8_t const * a) {
   return vld4_dup_u8(a);
 }
 
-// CHECK: test_vld4_dup_u16
+// CHECK-LABEL: test_vld4_dup_u16
 // CHECK: vld4.16 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 uint16x4x4_t test_vld4_dup_u16(uint16_t const * a) {
   return vld4_dup_u16(a);
 }
 
-// CHECK: test_vld4_dup_u32
+// CHECK-LABEL: test_vld4_dup_u32
 // CHECK: vld4.32 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 uint32x2x4_t test_vld4_dup_u32(uint32_t const * a) {
   return vld4_dup_u32(a);
 }
 
-// CHECK: test_vld4_dup_u64
+// CHECK-LABEL: test_vld4_dup_u64
 // CHECK: vld1.64
 uint64x1x4_t test_vld4_dup_u64(uint64_t const * a) {
   return vld4_dup_u64(a);
 }
 
-// CHECK: test_vld4_dup_s8
+// CHECK-LABEL: test_vld4_dup_s8
 // CHECK: vld4.8 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 int8x8x4_t test_vld4_dup_s8(int8_t const * a) {
   return vld4_dup_s8(a);
 }
 
-// CHECK: test_vld4_dup_s16
+// CHECK-LABEL: test_vld4_dup_s16
 // CHECK: vld4.16 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 int16x4x4_t test_vld4_dup_s16(int16_t const * a) {
   return vld4_dup_s16(a);
 }
 
-// CHECK: test_vld4_dup_s32
+// CHECK-LABEL: test_vld4_dup_s32
 // CHECK: vld4.32 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 int32x2x4_t test_vld4_dup_s32(int32_t const * a) {
   return vld4_dup_s32(a);
 }
 
-// CHECK: test_vld4_dup_s64
+// CHECK-LABEL: test_vld4_dup_s64
 // CHECK: vld1.64
 int64x1x4_t test_vld4_dup_s64(int64_t const * a) {
   return vld4_dup_s64(a);
 }
 
-// CHECK: test_vld4_dup_f16
+// CHECK-LABEL: test_vld4_dup_f16
 // CHECK: vld4.16 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 float16x4x4_t test_vld4_dup_f16(float16_t const * a) {
   return vld4_dup_f16(a);
 }
 
-// CHECK: test_vld4_dup_f32
+// CHECK-LABEL: test_vld4_dup_f32
 // CHECK: vld4.32 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 float32x2x4_t test_vld4_dup_f32(float32_t const * a) {
   return vld4_dup_f32(a);
 }
 
-// CHECK: test_vld4_dup_p8
+// CHECK-LABEL: test_vld4_dup_p8
 // CHECK: vld4.8 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 poly8x8x4_t test_vld4_dup_p8(poly8_t const * a) {
   return vld4_dup_p8(a);
 }
 
-// CHECK: test_vld4_dup_p16
+// CHECK-LABEL: test_vld4_dup_p16
 // CHECK: vld4.16 {d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[], d{{[0-9]+}}[]}, [r{{[0-9]+}}]
 poly16x4x4_t test_vld4_dup_p16(poly16_t const * a) {
   return vld4_dup_p16(a);
 }
 
 
-// CHECK: test_vld4q_lane_u16
+// CHECK-LABEL: test_vld4q_lane_u16
 // CHECK: vld4.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 uint16x8x4_t test_vld4q_lane_u16(uint16_t const * a, uint16x8x4_t b) {
   return vld4q_lane_u16(a, b, 7);
 }
 
-// CHECK: test_vld4q_lane_u32
+// CHECK-LABEL: test_vld4q_lane_u32
 // CHECK: vld4.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 uint32x4x4_t test_vld4q_lane_u32(uint32_t const * a, uint32x4x4_t b) {
   return vld4q_lane_u32(a, b, 3);
 }
 
-// CHECK: test_vld4q_lane_s16
+// CHECK-LABEL: test_vld4q_lane_s16
 // CHECK: vld4.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 int16x8x4_t test_vld4q_lane_s16(int16_t const * a, int16x8x4_t b) {
   return vld4q_lane_s16(a, b, 7);
 }
 
-// CHECK: test_vld4q_lane_s32
+// CHECK-LABEL: test_vld4q_lane_s32
 // CHECK: vld4.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 int32x4x4_t test_vld4q_lane_s32(int32_t const * a, int32x4x4_t b) {
   return vld4q_lane_s32(a, b, 3);
 }
 
-// CHECK: test_vld4q_lane_f16
+// CHECK-LABEL: test_vld4q_lane_f16
 // CHECK: vld4.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 float16x8x4_t test_vld4q_lane_f16(float16_t const * a, float16x8x4_t b) {
   return vld4q_lane_f16(a, b, 7);
 }
 
-// CHECK: test_vld4q_lane_f32
+// CHECK-LABEL: test_vld4q_lane_f32
 // CHECK: vld4.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 float32x4x4_t test_vld4q_lane_f32(float32_t const * a, float32x4x4_t b) {
   return vld4q_lane_f32(a, b, 3);
 }
 
-// CHECK: test_vld4q_lane_p16
+// CHECK-LABEL: test_vld4q_lane_p16
 // CHECK: vld4.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 poly16x8x4_t test_vld4q_lane_p16(poly16_t const * a, poly16x8x4_t b) {
   return vld4q_lane_p16(a, b, 7);
 }
 
-// CHECK: test_vld4_lane_u8
+// CHECK-LABEL: test_vld4_lane_u8
 // CHECK: vld4.8 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 uint8x8x4_t test_vld4_lane_u8(uint8_t const * a, uint8x8x4_t b) {
   return vld4_lane_u8(a, b, 7);
 }
 
-// CHECK: test_vld4_lane_u16
+// CHECK-LABEL: test_vld4_lane_u16
 // CHECK: vld4.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 uint16x4x4_t test_vld4_lane_u16(uint16_t const * a, uint16x4x4_t b) {
   return vld4_lane_u16(a, b, 3);
 }
 
-// CHECK: test_vld4_lane_u32
+// CHECK-LABEL: test_vld4_lane_u32
 // CHECK: vld4.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 uint32x2x4_t test_vld4_lane_u32(uint32_t const * a, uint32x2x4_t b) {
   return vld4_lane_u32(a, b, 1);
 }
 
-// CHECK: test_vld4_lane_s8
+// CHECK-LABEL: test_vld4_lane_s8
 // CHECK: vld4.8 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 int8x8x4_t test_vld4_lane_s8(int8_t const * a, int8x8x4_t b) {
   return vld4_lane_s8(a, b, 7);
 }
 
-// CHECK: test_vld4_lane_s16
+// CHECK-LABEL: test_vld4_lane_s16
 // CHECK: vld4.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 int16x4x4_t test_vld4_lane_s16(int16_t const * a, int16x4x4_t b) {
   return vld4_lane_s16(a, b, 3);
 }
 
-// CHECK: test_vld4_lane_s32
+// CHECK-LABEL: test_vld4_lane_s32
 // CHECK: vld4.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 int32x2x4_t test_vld4_lane_s32(int32_t const * a, int32x2x4_t b) {
   return vld4_lane_s32(a, b, 1);
 }
 
-// CHECK: test_vld4_lane_f16
+// CHECK-LABEL: test_vld4_lane_f16
 // CHECK: vld4.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 float16x4x4_t test_vld4_lane_f16(float16_t const * a, float16x4x4_t b) {
   return vld4_lane_f16(a, b, 3);
 }
 
-// CHECK: test_vld4_lane_f32
+// CHECK-LABEL: test_vld4_lane_f32
 // CHECK: vld4.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 float32x2x4_t test_vld4_lane_f32(float32_t const * a, float32x2x4_t b) {
   return vld4_lane_f32(a, b, 1);
 }
 
-// CHECK: test_vld4_lane_p8
+// CHECK-LABEL: test_vld4_lane_p8
 // CHECK: vld4.8 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 poly8x8x4_t test_vld4_lane_p8(poly8_t const * a, poly8x8x4_t b) {
   return vld4_lane_p8(a, b, 7);
 }
 
-// CHECK: test_vld4_lane_p16
+// CHECK-LABEL: test_vld4_lane_p16
 // CHECK: vld4.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 poly16x4x4_t test_vld4_lane_p16(poly16_t const * a, poly16x4x4_t b) {
   return vld4_lane_p16(a, b, 3);
 }
 
 
-// CHECK: test_vmax_s8
+// CHECK-LABEL: test_vmax_s8
 // CHECK: vmax.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vmax_s8(int8x8_t a, int8x8_t b) {
   return vmax_s8(a, b);
 }
 
-// CHECK: test_vmax_s16
+// CHECK-LABEL: test_vmax_s16
 // CHECK: vmax.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vmax_s16(int16x4_t a, int16x4_t b) {
   return vmax_s16(a, b);
 }
 
-// CHECK: test_vmax_s32
+// CHECK-LABEL: test_vmax_s32
 // CHECK: vmax.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vmax_s32(int32x2_t a, int32x2_t b) {
   return vmax_s32(a, b);
 }
 
-// CHECK: test_vmax_u8
+// CHECK-LABEL: test_vmax_u8
 // CHECK: vmax.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vmax_u8(uint8x8_t a, uint8x8_t b) {
   return vmax_u8(a, b);
 }
 
-// CHECK: test_vmax_u16
+// CHECK-LABEL: test_vmax_u16
 // CHECK: vmax.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vmax_u16(uint16x4_t a, uint16x4_t b) {
   return vmax_u16(a, b);
 }
 
-// CHECK: test_vmax_u32
+// CHECK-LABEL: test_vmax_u32
 // CHECK: vmax.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vmax_u32(uint32x2_t a, uint32x2_t b) {
   return vmax_u32(a, b);
 }
 
-// CHECK: test_vmax_f32
+// CHECK-LABEL: test_vmax_f32
 // CHECK: vmax.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vmax_f32(float32x2_t a, float32x2_t b) {
   return vmax_f32(a, b);
 }
 
-// CHECK: test_vmaxq_s8
+// CHECK-LABEL: test_vmaxq_s8
 // CHECK: vmax.s8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vmaxq_s8(int8x16_t a, int8x16_t b) {
   return vmaxq_s8(a, b);
 }
 
-// CHECK: test_vmaxq_s16
+// CHECK-LABEL: test_vmaxq_s16
 // CHECK: vmax.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vmaxq_s16(int16x8_t a, int16x8_t b) {
   return vmaxq_s16(a, b);
 }
 
-// CHECK: test_vmaxq_s32
+// CHECK-LABEL: test_vmaxq_s32
 // CHECK: vmax.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vmaxq_s32(int32x4_t a, int32x4_t b) {
   return vmaxq_s32(a, b);
 }
 
-// CHECK: test_vmaxq_u8
+// CHECK-LABEL: test_vmaxq_u8
 // CHECK: vmax.u8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vmaxq_u8(uint8x16_t a, uint8x16_t b) {
   return vmaxq_u8(a, b);
 }
 
-// CHECK: test_vmaxq_u16
+// CHECK-LABEL: test_vmaxq_u16
 // CHECK: vmax.u16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vmaxq_u16(uint16x8_t a, uint16x8_t b) {
   return vmaxq_u16(a, b);
 }
 
-// CHECK: test_vmaxq_u32
+// CHECK-LABEL: test_vmaxq_u32
 // CHECK: vmax.u32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vmaxq_u32(uint32x4_t a, uint32x4_t b) {
   return vmaxq_u32(a, b);
 }
 
-// CHECK: test_vmaxq_f32
+// CHECK-LABEL: test_vmaxq_f32
 // CHECK: vmax.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vmaxq_f32(float32x4_t a, float32x4_t b) {
   return vmaxq_f32(a, b);
 }
 
 
-// CHECK: test_vmin_s8
+// CHECK-LABEL: test_vmin_s8
 // CHECK: vmin.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vmin_s8(int8x8_t a, int8x8_t b) {
   return vmin_s8(a, b);
 }
 
-// CHECK: test_vmin_s16
+// CHECK-LABEL: test_vmin_s16
 // CHECK: vmin.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vmin_s16(int16x4_t a, int16x4_t b) {
   return vmin_s16(a, b);
 }
 
-// CHECK: test_vmin_s32
+// CHECK-LABEL: test_vmin_s32
 // CHECK: vmin.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vmin_s32(int32x2_t a, int32x2_t b) {
   return vmin_s32(a, b);
 }
 
-// CHECK: test_vmin_u8
+// CHECK-LABEL: test_vmin_u8
 // CHECK: vmin.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vmin_u8(uint8x8_t a, uint8x8_t b) {
   return vmin_u8(a, b);
 }
 
-// CHECK: test_vmin_u16
+// CHECK-LABEL: test_vmin_u16
 // CHECK: vmin.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vmin_u16(uint16x4_t a, uint16x4_t b) {
   return vmin_u16(a, b);
 }
 
-// CHECK: test_vmin_u32
+// CHECK-LABEL: test_vmin_u32
 // CHECK: vmin.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vmin_u32(uint32x2_t a, uint32x2_t b) {
   return vmin_u32(a, b);
 }
 
-// CHECK: test_vmin_f32
+// CHECK-LABEL: test_vmin_f32
 // CHECK: vmin.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vmin_f32(float32x2_t a, float32x2_t b) {
   return vmin_f32(a, b);
 }
 
-// CHECK: test_vminq_s8
+// CHECK-LABEL: test_vminq_s8
 // CHECK: vmin.s8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vminq_s8(int8x16_t a, int8x16_t b) {
   return vminq_s8(a, b);
 }
 
-// CHECK: test_vminq_s16
+// CHECK-LABEL: test_vminq_s16
 // CHECK: vmin.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vminq_s16(int16x8_t a, int16x8_t b) {
   return vminq_s16(a, b);
 }
 
-// CHECK: test_vminq_s32
+// CHECK-LABEL: test_vminq_s32
 // CHECK: vmin.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vminq_s32(int32x4_t a, int32x4_t b) {
   return vminq_s32(a, b);
 }
 
-// CHECK: test_vminq_u8
+// CHECK-LABEL: test_vminq_u8
 // CHECK: vmin.u8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vminq_u8(uint8x16_t a, uint8x16_t b) {
   return vminq_u8(a, b);
 }
 
-// CHECK: test_vminq_u16
+// CHECK-LABEL: test_vminq_u16
 // CHECK: vmin.u16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vminq_u16(uint16x8_t a, uint16x8_t b) {
   return vminq_u16(a, b);
 }
 
-// CHECK: test_vminq_u32
+// CHECK-LABEL: test_vminq_u32
 // CHECK: vmin.u32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vminq_u32(uint32x4_t a, uint32x4_t b) {
   return vminq_u32(a, b);
 }
 
-// CHECK: test_vminq_f32
+// CHECK-LABEL: test_vminq_f32
 // CHECK: vmin.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vminq_f32(float32x4_t a, float32x4_t b) {
   return vminq_f32(a, b);
 }
 
 
-// CHECK: test_vmla_s8
+// CHECK-LABEL: test_vmla_s8
 // CHECK: vmla.i8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vmla_s8(int8x8_t a, int8x8_t b, int8x8_t c) {
   return vmla_s8(a, b, c);
 }
 
-// CHECK: test_vmla_s16
+// CHECK-LABEL: test_vmla_s16
 // CHECK: vmla.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vmla_s16(int16x4_t a, int16x4_t b, int16x4_t c) {
   return vmla_s16(a, b, c);
 }
 
-// CHECK: test_vmla_s32
+// CHECK-LABEL: test_vmla_s32
 // CHECK: vmla.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vmla_s32(int32x2_t a, int32x2_t b, int32x2_t c) {
   return vmla_s32(a, b, c);
 }
 
-// CHECK: test_vmla_f32
-// CHECK: vmul.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
-// CHECK: vadd.f32
+// CHECK-LABEL: test_vmla_f32
+// CHECK-SWIFT: vmul.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
+// CHECK-SWIFT: vadd.f32
+// CHECK-A57: vmla.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vmla_f32(float32x2_t a, float32x2_t b, float32x2_t c) {
   return vmla_f32(a, b, c);
 }
 
-// CHECK: test_vmla_u8
+// CHECK-LABEL: test_vmla_u8
 // CHECK: vmla.i8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vmla_u8(uint8x8_t a, uint8x8_t b, uint8x8_t c) {
   return vmla_u8(a, b, c);
 }
 
-// CHECK: test_vmla_u16
+// CHECK-LABEL: test_vmla_u16
 // CHECK: vmla.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vmla_u16(uint16x4_t a, uint16x4_t b, uint16x4_t c) {
   return vmla_u16(a, b, c);
 }
 
-// CHECK: test_vmla_u32
+// CHECK-LABEL: test_vmla_u32
 // CHECK: vmla.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vmla_u32(uint32x2_t a, uint32x2_t b, uint32x2_t c) {
   return vmla_u32(a, b, c);
 }
 
-// CHECK: test_vmlaq_s8
+// CHECK-LABEL: test_vmlaq_s8
 // CHECK: vmla.i8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vmlaq_s8(int8x16_t a, int8x16_t b, int8x16_t c) {
   return vmlaq_s8(a, b, c);
 }
 
-// CHECK: test_vmlaq_s16
+// CHECK-LABEL: test_vmlaq_s16
 // CHECK: vmla.i16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vmlaq_s16(int16x8_t a, int16x8_t b, int16x8_t c) {
   return vmlaq_s16(a, b, c);
 }
 
-// CHECK: test_vmlaq_s32
+// CHECK-LABEL: test_vmlaq_s32
 // CHECK: vmla.i32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vmlaq_s32(int32x4_t a, int32x4_t b, int32x4_t c) {
   return vmlaq_s32(a, b, c);
 }
 
-// CHECK: test_vmlaq_f32
-// CHECK: vmul.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
-// CHECK: vadd.f32
+// CHECK-LABEL: test_vmlaq_f32
+// CHECK-SWIFT: vmul.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
+// CHECK-SWIFT: vadd.f32
+// CHECK-A57: vmla.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vmlaq_f32(float32x4_t a, float32x4_t b, float32x4_t c) {
   return vmlaq_f32(a, b, c);
 }
 
-// CHECK: test_vmlaq_u8
+// CHECK-LABEL: test_vmlaq_u8
 // CHECK: vmla.i8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vmlaq_u8(uint8x16_t a, uint8x16_t b, uint8x16_t c) {
   return vmlaq_u8(a, b, c);
 }
 
-// CHECK: test_vmlaq_u16
+// CHECK-LABEL: test_vmlaq_u16
 // CHECK: vmla.i16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vmlaq_u16(uint16x8_t a, uint16x8_t b, uint16x8_t c) {
   return vmlaq_u16(a, b, c);
 }
 
-// CHECK: test_vmlaq_u32
+// CHECK-LABEL: test_vmlaq_u32
 // CHECK: vmla.i32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vmlaq_u32(uint32x4_t a, uint32x4_t b, uint32x4_t c) {
   return vmlaq_u32(a, b, c);
 }
 
 
-// CHECK: test_vmlal_s8
+// CHECK-LABEL: test_vmlal_s8
 // CHECK: vmlal.s8 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x8_t test_vmlal_s8(int16x8_t a, int8x8_t b, int8x8_t c) {
   return vmlal_s8(a, b, c);
 }
 
-// CHECK: test_vmlal_s16
+// CHECK-LABEL: test_vmlal_s16
 // CHECK: vmlal.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vmlal_s16(int32x4_t a, int16x4_t b, int16x4_t c) {
   return vmlal_s16(a, b, c);
 }
 
-// CHECK: test_vmlal_s32
+// CHECK-LABEL: test_vmlal_s32
 // CHECK: vmlal.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vmlal_s32(int64x2_t a, int32x2_t b, int32x2_t c) {
   return vmlal_s32(a, b, c);
 }
 
-// CHECK: test_vmlal_u8
+// CHECK-LABEL: test_vmlal_u8
 // CHECK: vmlal.u8 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x8_t test_vmlal_u8(uint16x8_t a, uint8x8_t b, uint8x8_t c) {
   return vmlal_u8(a, b, c);
 }
 
-// CHECK: test_vmlal_u16
+// CHECK-LABEL: test_vmlal_u16
 // CHECK: vmlal.u16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x4_t test_vmlal_u16(uint32x4_t a, uint16x4_t b, uint16x4_t c) {
   return vmlal_u16(a, b, c);
 }
 
-// CHECK: test_vmlal_u32
+// CHECK-LABEL: test_vmlal_u32
 // CHECK: vmlal.u32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x2_t test_vmlal_u32(uint64x2_t a, uint32x2_t b, uint32x2_t c) {
   return vmlal_u32(a, b, c);
 }
 
 
-// CHECK: test_vmlal_lane_s16
+// CHECK-LABEL: test_vmlal_lane_s16
 // CHECK: vmlal.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int32x4_t test_vmlal_lane_s16(int32x4_t a, int16x4_t b, int16x4_t c) {
   return vmlal_lane_s16(a, b, c, 3);
 }
 
-// CHECK: test_vmlal_lane_s32
+// CHECK-LABEL: test_vmlal_lane_s32
 // CHECK: vmlal.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int64x2_t test_vmlal_lane_s32(int64x2_t a, int32x2_t b, int32x2_t c) {
   return vmlal_lane_s32(a, b, c, 1);
 }
 
-// CHECK: test_vmlal_lane_u16
+// CHECK-LABEL: test_vmlal_lane_u16
 // CHECK: vmlal.u16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint32x4_t test_vmlal_lane_u16(uint32x4_t a, uint16x4_t b, uint16x4_t c) {
   return vmlal_lane_u16(a, b, c, 3);
 }
 
-// CHECK: test_vmlal_lane_u32
+// CHECK-LABEL: test_vmlal_lane_u32
 // CHECK: vmlal.u32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint64x2_t test_vmlal_lane_u32(uint64x2_t a, uint32x2_t b, uint32x2_t c) {
   return vmlal_lane_u32(a, b, c, 1);
 }
 
 
-// CHECK: test_vmlal_n_s16
+// CHECK-LABEL: test_vmlal_n_s16
 // CHECK: vmlal.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vmlal_n_s16(int32x4_t a, int16x4_t b, int16_t c) {
   return vmlal_n_s16(a, b, c);
 }
 
-// CHECK: test_vmlal_n_s32
+// CHECK-LABEL: test_vmlal_n_s32
 // CHECK: vmlal.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vmlal_n_s32(int64x2_t a, int32x2_t b, int32_t c) {
   return vmlal_n_s32(a, b, c);
 }
 
-// CHECK: test_vmlal_n_u16
+// CHECK-LABEL: test_vmlal_n_u16
 // CHECK: vmlal.u16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x4_t test_vmlal_n_u16(uint32x4_t a, uint16x4_t b, uint16_t c) {
   return vmlal_n_u16(a, b, c);
 }
 
-// CHECK: test_vmlal_n_u32
+// CHECK-LABEL: test_vmlal_n_u32
 // CHECK: vmlal.u32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x2_t test_vmlal_n_u32(uint64x2_t a, uint32x2_t b, uint32_t c) {
   return vmlal_n_u32(a, b, c);
 }
 
 
-// CHECK: test_vmla_lane_s16
+// CHECK-LABEL: test_vmla_lane_s16
 // CHECK: vmla.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int16x4_t test_vmla_lane_s16(int16x4_t a, int16x4_t b, int16x4_t c) {
   return vmla_lane_s16(a, b, c, 3);
 }
 
-// CHECK: test_vmla_lane_s32
+// CHECK-LABEL: test_vmla_lane_s32
 // CHECK: vmla.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int32x2_t test_vmla_lane_s32(int32x2_t a, int32x2_t b, int32x2_t c) {
   return vmla_lane_s32(a, b, c, 1);
 }
 
-// CHECK: test_vmla_lane_u16
+// CHECK-LABEL: test_vmla_lane_u16
 // CHECK: vmla.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint16x4_t test_vmla_lane_u16(uint16x4_t a, uint16x4_t b, uint16x4_t c) {
   return vmla_lane_u16(a, b, c, 3);
 }
 
-// CHECK: test_vmla_lane_u32
+// CHECK-LABEL: test_vmla_lane_u32
 // CHECK: vmla.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint32x2_t test_vmla_lane_u32(uint32x2_t a, uint32x2_t b, uint32x2_t c) {
   return vmla_lane_u32(a, b, c, 1);
 }
 
-// CHECK: test_vmla_lane_f32
-// CHECK: vmul.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
-// CHECK: vadd.f32
+// CHECK-LABEL: test_vmla_lane_f32
+// CHECK-SWIFT: vmul.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
+// CHECK-SWIFT: vadd.f32
+// CHECK-A57: vmla.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 float32x2_t test_vmla_lane_f32(float32x2_t a, float32x2_t b, float32x2_t c) {
   return vmla_lane_f32(a, b, c, 1);
 }
 
-// CHECK: test_vmlaq_lane_s16
+// CHECK-LABEL: test_vmlaq_lane_s16
 // CHECK: vmla.i16 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int16x8_t test_vmlaq_lane_s16(int16x8_t a, int16x8_t b, int16x4_t c) {
   return vmlaq_lane_s16(a, b, c, 3);
 }
 
-// CHECK: test_vmlaq_lane_s32
+// CHECK-LABEL: test_vmlaq_lane_s32
 // CHECK: vmla.i32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int32x4_t test_vmlaq_lane_s32(int32x4_t a, int32x4_t b, int32x2_t c) {
   return vmlaq_lane_s32(a, b, c, 1);
 }
 
-// CHECK: test_vmlaq_lane_u16
+// CHECK-LABEL: test_vmlaq_lane_u16
 // CHECK: vmla.i16 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint16x8_t test_vmlaq_lane_u16(uint16x8_t a, uint16x8_t b, uint16x4_t c) {
   return vmlaq_lane_u16(a, b, c, 3);
 }
 
-// CHECK: test_vmlaq_lane_u32
+// CHECK-LABEL: test_vmlaq_lane_u32
 // CHECK: vmla.i32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint32x4_t test_vmlaq_lane_u32(uint32x4_t a, uint32x4_t b, uint32x2_t c) {
   return vmlaq_lane_u32(a, b, c, 1);
 }
 
-// CHECK: test_vmlaq_lane_f32
-// CHECK: vmul.f32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
-// CHECK: vadd.f32
+// CHECK-LABEL: test_vmlaq_lane_f32
+// CHECK-SWIFT: vmul.f32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
+// CHECK-SWIFT: vadd.f32
+// CHECK-A57: vmla.f32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 float32x4_t test_vmlaq_lane_f32(float32x4_t a, float32x4_t b, float32x2_t c) {
   return vmlaq_lane_f32(a, b, c, 1);
 }
 
 
-// CHECK: test_vmla_n_s16
+// CHECK-LABEL: test_vmla_n_s16
 // CHECK: vmla.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vmla_n_s16(int16x4_t a, int16x4_t b, int16_t c) {
   return vmla_n_s16(a, b, c);
 }
 
-// CHECK: test_vmla_n_s32
+// CHECK-LABEL: test_vmla_n_s32
 // CHECK: vmla.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vmla_n_s32(int32x2_t a, int32x2_t b, int32_t c) {
   return vmla_n_s32(a, b, c);
 }
 
-// CHECK: test_vmla_n_u16
+// CHECK-LABEL: test_vmla_n_u16
 // CHECK: vmla.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vmla_n_u16(uint16x4_t a, uint16x4_t b, uint16_t c) {
   return vmla_n_u16(a, b, c);
 }
 
-// CHECK: test_vmla_n_u32
+// CHECK-LABEL: test_vmla_n_u32
 // CHECK: vmla.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vmla_n_u32(uint32x2_t a, uint32x2_t b, uint32_t c) {
   return vmla_n_u32(a, b, c);
 }
 
-// CHECK: test_vmla_n_f32
-// CHECK: vmul.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
-// CHECK: vadd.f32
+// CHECK-LABEL: test_vmla_n_f32
+// CHECK-SWIFT: vmul.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
+// CHECK-SWIFT: vadd.f32
+// CHECK-A57: vmla.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vmla_n_f32(float32x2_t a, float32x2_t b, float32_t c) {
   return vmla_n_f32(a, b, c);
 }
 
-// CHECK: test_vmlaq_n_s16
+// CHECK-LABEL: test_vmlaq_n_s16
 // CHECK: vmla.i16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vmlaq_n_s16(int16x8_t a, int16x8_t b, int16_t c) {
   return vmlaq_n_s16(a, b, c);
 }
 
-// CHECK: test_vmlaq_n_s32
+// CHECK-LABEL: test_vmlaq_n_s32
 // CHECK: vmla.i32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vmlaq_n_s32(int32x4_t a, int32x4_t b, int32_t c) {
   return vmlaq_n_s32(a, b, c);
 }
 
-// CHECK: test_vmlaq_n_u16
+// CHECK-LABEL: test_vmlaq_n_u16
 // CHECK: vmla.i16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vmlaq_n_u16(uint16x8_t a, uint16x8_t b, uint16_t c) {
   return vmlaq_n_u16(a, b, c);
 }
 
-// CHECK: test_vmlaq_n_u32
+// CHECK-LABEL: test_vmlaq_n_u32
 // CHECK: vmla.i32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vmlaq_n_u32(uint32x4_t a, uint32x4_t b, uint32_t c) {
   return vmlaq_n_u32(a, b, c);
 }
 
-// CHECK: test_vmlaq_n_f32
-// CHECK: vmul.f32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[0]
-// CHECK: vadd.f32
+// CHECK-LABEL: test_vmlaq_n_f32
+// CHECK-SWIFT: vmul.f32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[0]
+// CHECK-SWIFT: vadd.f32
+// CHECK-A57: vld1.32 {d{{[0-9]+}}[], d{{[0-9]+}}[]}, 
+// CHECK-A57: vmla.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vmlaq_n_f32(float32x4_t a, float32x4_t b, float32_t c) {
   return vmlaq_n_f32(a, b, c);
 }
 
 
-// CHECK: test_vmls_s8
+// CHECK-LABEL: test_vmls_s8
 // CHECK: vmls.i8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vmls_s8(int8x8_t a, int8x8_t b, int8x8_t c) {
   return vmls_s8(a, b, c);
 }
 
-// CHECK: test_vmls_s16
+// CHECK-LABEL: test_vmls_s16
 // CHECK: vmls.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vmls_s16(int16x4_t a, int16x4_t b, int16x4_t c) {
   return vmls_s16(a, b, c);
 }
 
-// CHECK: test_vmls_s32
+// CHECK-LABEL: test_vmls_s32
 // CHECK: vmls.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vmls_s32(int32x2_t a, int32x2_t b, int32x2_t c) {
   return vmls_s32(a, b, c);
 }
 
-// CHECK: test_vmls_f32
-// CHECK: vmul.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
-// CHECK: vsub.f32
+// CHECK-LABEL: test_vmls_f32
+// CHECK-SWIFT: vmul.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
+// CHECK-SWIFT: vsub.f32
+// CHECK-A57: vmls.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vmls_f32(float32x2_t a, float32x2_t b, float32x2_t c) {
   return vmls_f32(a, b, c);
 }
 
-// CHECK: test_vmls_u8
+// CHECK-LABEL: test_vmls_u8
 // CHECK: vmls.i8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vmls_u8(uint8x8_t a, uint8x8_t b, uint8x8_t c) {
   return vmls_u8(a, b, c);
 }
 
-// CHECK: test_vmls_u16
+// CHECK-LABEL: test_vmls_u16
 // CHECK: vmls.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vmls_u16(uint16x4_t a, uint16x4_t b, uint16x4_t c) {
   return vmls_u16(a, b, c);
 }
 
-// CHECK: test_vmls_u32
+// CHECK-LABEL: test_vmls_u32
 // CHECK: vmls.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vmls_u32(uint32x2_t a, uint32x2_t b, uint32x2_t c) {
   return vmls_u32(a, b, c);
 }
 
-// CHECK: test_vmlsq_s8
+// CHECK-LABEL: test_vmlsq_s8
 // CHECK: vmls.i8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vmlsq_s8(int8x16_t a, int8x16_t b, int8x16_t c) {
   return vmlsq_s8(a, b, c);
 }
 
-// CHECK: test_vmlsq_s16
+// CHECK-LABEL: test_vmlsq_s16
 // CHECK: vmls.i16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vmlsq_s16(int16x8_t a, int16x8_t b, int16x8_t c) {
   return vmlsq_s16(a, b, c);
 }
 
-// CHECK: test_vmlsq_s32
+// CHECK-LABEL: test_vmlsq_s32
 // CHECK: vmls.i32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vmlsq_s32(int32x4_t a, int32x4_t b, int32x4_t c) {
   return vmlsq_s32(a, b, c);
 }
 
-// CHECK: test_vmlsq_f32
-// CHECK: vmul.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
-// CHECK: vsub.f32
+// CHECK-LABEL: test_vmlsq_f32
+// CHECK-SWIFT: vmul.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
+// CHECK-SWIFT: vsub.f32
+// CHECK-A57: vmls.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vmlsq_f32(float32x4_t a, float32x4_t b, float32x4_t c) {
   return vmlsq_f32(a, b, c);
 }
 
-// CHECK: test_vmlsq_u8
+// CHECK-LABEL: test_vmlsq_u8
 // CHECK: vmls.i8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vmlsq_u8(uint8x16_t a, uint8x16_t b, uint8x16_t c) {
   return vmlsq_u8(a, b, c);
 }
 
-// CHECK: test_vmlsq_u16
+// CHECK-LABEL: test_vmlsq_u16
 // CHECK: vmls.i16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vmlsq_u16(uint16x8_t a, uint16x8_t b, uint16x8_t c) {
   return vmlsq_u16(a, b, c);
 }
 
-// CHECK: test_vmlsq_u32
+// CHECK-LABEL: test_vmlsq_u32
 // CHECK: vmls.i32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vmlsq_u32(uint32x4_t a, uint32x4_t b, uint32x4_t c) {
   return vmlsq_u32(a, b, c);
 }
 
 
-// CHECK: test_vmlsl_s8
+// CHECK-LABEL: test_vmlsl_s8
 // CHECK: vmlsl.s8 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x8_t test_vmlsl_s8(int16x8_t a, int8x8_t b, int8x8_t c) {
   return vmlsl_s8(a, b, c);
 }
 
-// CHECK: test_vmlsl_s16
+// CHECK-LABEL: test_vmlsl_s16
 // CHECK: vmlsl.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vmlsl_s16(int32x4_t a, int16x4_t b, int16x4_t c) {
   return vmlsl_s16(a, b, c);
 }
 
-// CHECK: test_vmlsl_s32
+// CHECK-LABEL: test_vmlsl_s32
 // CHECK: vmlsl.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vmlsl_s32(int64x2_t a, int32x2_t b, int32x2_t c) {
   return vmlsl_s32(a, b, c);
 }
 
-// CHECK: test_vmlsl_u8
+// CHECK-LABEL: test_vmlsl_u8
 // CHECK: vmlsl.u8 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x8_t test_vmlsl_u8(uint16x8_t a, uint8x8_t b, uint8x8_t c) {
   return vmlsl_u8(a, b, c);
 }
 
-// CHECK: test_vmlsl_u16
+// CHECK-LABEL: test_vmlsl_u16
 // CHECK: vmlsl.u16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x4_t test_vmlsl_u16(uint32x4_t a, uint16x4_t b, uint16x4_t c) {
   return vmlsl_u16(a, b, c);
 }
 
-// CHECK: test_vmlsl_u32
+// CHECK-LABEL: test_vmlsl_u32
 // CHECK: vmlsl.u32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x2_t test_vmlsl_u32(uint64x2_t a, uint32x2_t b, uint32x2_t c) {
   return vmlsl_u32(a, b, c);
 }
 
 
-// CHECK: test_vmlsl_lane_s16
+// CHECK-LABEL: test_vmlsl_lane_s16
 // CHECK: vmlsl.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int32x4_t test_vmlsl_lane_s16(int32x4_t a, int16x4_t b, int16x4_t c) {
   return vmlsl_lane_s16(a, b, c, 3);
 }
 
-// CHECK: test_vmlsl_lane_s32
+// CHECK-LABEL: test_vmlsl_lane_s32
 // CHECK: vmlsl.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int64x2_t test_vmlsl_lane_s32(int64x2_t a, int32x2_t b, int32x2_t c) {
   return vmlsl_lane_s32(a, b, c, 1);
 }
 
-// CHECK: test_vmlsl_lane_u16
+// CHECK-LABEL: test_vmlsl_lane_u16
 // CHECK: vmlsl.u16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint32x4_t test_vmlsl_lane_u16(uint32x4_t a, uint16x4_t b, uint16x4_t c) {
   return vmlsl_lane_u16(a, b, c, 3);
 }
 
-// CHECK: test_vmlsl_lane_u32
+// CHECK-LABEL: test_vmlsl_lane_u32
 // CHECK: vmlsl.u32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint64x2_t test_vmlsl_lane_u32(uint64x2_t a, uint32x2_t b, uint32x2_t c) {
   return vmlsl_lane_u32(a, b, c, 1);
 }
 
 
-// CHECK: test_vmlsl_n_s16
+// CHECK-LABEL: test_vmlsl_n_s16
 // CHECK: vmlsl.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vmlsl_n_s16(int32x4_t a, int16x4_t b, int16_t c) {
   return vmlsl_n_s16(a, b, c);
 }
 
-// CHECK: test_vmlsl_n_s32
+// CHECK-LABEL: test_vmlsl_n_s32
 // CHECK: vmlsl.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vmlsl_n_s32(int64x2_t a, int32x2_t b, int32_t c) {
   return vmlsl_n_s32(a, b, c);
 }
 
-// CHECK: test_vmlsl_n_u16
+// CHECK-LABEL: test_vmlsl_n_u16
 // CHECK: vmlsl.u16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x4_t test_vmlsl_n_u16(uint32x4_t a, uint16x4_t b, uint16_t c) {
   return vmlsl_n_u16(a, b, c);
 }
 
-// CHECK: test_vmlsl_n_u32
+// CHECK-LABEL: test_vmlsl_n_u32
 // CHECK: vmlsl.u32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x2_t test_vmlsl_n_u32(uint64x2_t a, uint32x2_t b, uint32_t c) {
   return vmlsl_n_u32(a, b, c);
 }
 
 
-// CHECK: test_vmls_lane_s16
+// CHECK-LABEL: test_vmls_lane_s16
 // CHECK: vmls.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int16x4_t test_vmls_lane_s16(int16x4_t a, int16x4_t b, int16x4_t c) {
   return vmls_lane_s16(a, b, c, 3);
 }
 
-// CHECK: test_vmls_lane_s32
+// CHECK-LABEL: test_vmls_lane_s32
 // CHECK: vmls.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int32x2_t test_vmls_lane_s32(int32x2_t a, int32x2_t b, int32x2_t c) {
   return vmls_lane_s32(a, b, c, 1);
 }
 
-// CHECK: test_vmls_lane_u16
+// CHECK-LABEL: test_vmls_lane_u16
 // CHECK: vmls.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint16x4_t test_vmls_lane_u16(uint16x4_t a, uint16x4_t b, uint16x4_t c) {
   return vmls_lane_u16(a, b, c, 3);
 }
 
-// CHECK: test_vmls_lane_u32
+// CHECK-LABEL: test_vmls_lane_u32
 // CHECK: vmls.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint32x2_t test_vmls_lane_u32(uint32x2_t a, uint32x2_t b, uint32x2_t c) {
   return vmls_lane_u32(a, b, c, 1);
 }
 
-// CHECK: test_vmls_lane_f32
-// CHECK: vmul.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
-// CHECK: vsub.f32
+// CHECK-LABEL: test_vmls_lane_f32
+// CHECK-SWIFT: vmul.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
+// CHECK-SWIFT: vsub.f32
+// CHECK-A57: vmls.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 float32x2_t test_vmls_lane_f32(float32x2_t a, float32x2_t b, float32x2_t c) {
   return vmls_lane_f32(a, b, c, 1);
 }
 
-// CHECK: test_vmlsq_lane_s16
+// CHECK-LABEL: test_vmlsq_lane_s16
 // CHECK: vmls.i16 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int16x8_t test_vmlsq_lane_s16(int16x8_t a, int16x8_t b, int16x4_t c) {
   return vmlsq_lane_s16(a, b, c, 3);
 }
 
-// CHECK: test_vmlsq_lane_s32
+// CHECK-LABEL: test_vmlsq_lane_s32
 // CHECK: vmls.i32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int32x4_t test_vmlsq_lane_s32(int32x4_t a, int32x4_t b, int32x2_t c) {
   return vmlsq_lane_s32(a, b, c, 1);
 }
 
-// CHECK: test_vmlsq_lane_u16
+// CHECK-LABEL: test_vmlsq_lane_u16
 // CHECK: vmls.i16 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint16x8_t test_vmlsq_lane_u16(uint16x8_t a, uint16x8_t b, uint16x4_t c) {
   return vmlsq_lane_u16(a, b, c, 3);
 }
 
-// CHECK: test_vmlsq_lane_u32
+// CHECK-LABEL: test_vmlsq_lane_u32
 // CHECK: vmls.i32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint32x4_t test_vmlsq_lane_u32(uint32x4_t a, uint32x4_t b, uint32x2_t c) {
   return vmlsq_lane_u32(a, b, c, 1);
 }
 
-// CHECK: test_vmlsq_lane_f32
-// CHECK: vmul.f32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
-// CHECK: vsub.f32
+// CHECK-LABEL: test_vmlsq_lane_f32
+// CHECK-SWIFT: vmul.f32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
+// CHECK-SWIFT: vsub.f32
+// CHECK-A57: vmls.f32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 float32x4_t test_vmlsq_lane_f32(float32x4_t a, float32x4_t b, float32x2_t c) {
   return vmlsq_lane_f32(a, b, c, 1);
 }
 
 
-// CHECK: test_vmls_n_s16
+// CHECK-LABEL: test_vmls_n_s16
 // CHECK: vmls.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vmls_n_s16(int16x4_t a, int16x4_t b, int16_t c) {
   return vmls_n_s16(a, b, c);
 }
 
-// CHECK: test_vmls_n_s32
+// CHECK-LABEL: test_vmls_n_s32
 // CHECK: vmls.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vmls_n_s32(int32x2_t a, int32x2_t b, int32_t c) {
   return vmls_n_s32(a, b, c);
 }
 
-// CHECK: test_vmls_n_u16
+// CHECK-LABEL: test_vmls_n_u16
 // CHECK: vmls.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vmls_n_u16(uint16x4_t a, uint16x4_t b, uint16_t c) {
   return vmls_n_u16(a, b, c);
 }
 
-// CHECK: test_vmls_n_u32
+// CHECK-LABEL: test_vmls_n_u32
 // CHECK: vmls.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vmls_n_u32(uint32x2_t a, uint32x2_t b, uint32_t c) {
   return vmls_n_u32(a, b, c);
 }
 
-// CHECK: test_vmls_n_f32
-// CHECK: vmul.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
-// CHECK: vsub.f32
+// CHECK-LABEL: test_vmls_n_f32
+// CHECK-SWIFT: vmul.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
+// CHECK-SWIFT: vsub.f32
+// CHECK-A57: vmls.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vmls_n_f32(float32x2_t a, float32x2_t b, float32_t c) {
   return vmls_n_f32(a, b, c);
 }
 
-// CHECK: test_vmlsq_n_s16
+// CHECK-LABEL: test_vmlsq_n_s16
 // CHECK: vmls.i16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vmlsq_n_s16(int16x8_t a, int16x8_t b, int16_t c) {
   return vmlsq_n_s16(a, b, c);
 }
 
-// CHECK: test_vmlsq_n_s32
+// CHECK-LABEL: test_vmlsq_n_s32
 // CHECK: vmls.i32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vmlsq_n_s32(int32x4_t a, int32x4_t b, int32_t c) {
   return vmlsq_n_s32(a, b, c);
 }
 
-// CHECK: test_vmlsq_n_u16
+// CHECK-LABEL: test_vmlsq_n_u16
 // CHECK: vmls.i16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vmlsq_n_u16(uint16x8_t a, uint16x8_t b, uint16_t c) {
   return vmlsq_n_u16(a, b, c);
 }
 
-// CHECK: test_vmlsq_n_u32
+// CHECK-LABEL: test_vmlsq_n_u32
 // CHECK: vmls.i32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vmlsq_n_u32(uint32x4_t a, uint32x4_t b, uint32_t c) {
   return vmlsq_n_u32(a, b, c);
 }
 
-// CHECK: test_vmlsq_n_f32
-// CHECK: vmul.f32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[0]
-// CHECK: vsub.f32
+// CHECK-LABEL: test_vmlsq_n_f32
+// CHECK-SWIFT: vmul.f32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[0]
+// CHECK-SWIFT: vsub.f32
+// CHECK-A57: vmls.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vmlsq_n_f32(float32x4_t a, float32x4_t b, float32_t c) {
   return vmlsq_n_f32(a, b, c);
 }
 
 
-// CHECK: test_vmovl_s8
+// CHECK-LABEL: test_vmovl_s8
 // CHECK: vmovl.s8 q{{[0-9]+}}, d{{[0-9]+}}
 int16x8_t test_vmovl_s8(int8x8_t a) {
   return vmovl_s8(a);
 }
 
-// CHECK: test_vmovl_s16
+// CHECK-LABEL: test_vmovl_s16
 // CHECK: vmovl.s16 q{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vmovl_s16(int16x4_t a) {
   return vmovl_s16(a);
 }
 
-// CHECK: test_vmovl_s32
+// CHECK-LABEL: test_vmovl_s32
 // CHECK: vmovl.s32 q{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vmovl_s32(int32x2_t a) {
   return vmovl_s32(a);
 }
 
-// CHECK: test_vmovl_u8
+// CHECK-LABEL: test_vmovl_u8
 // CHECK: vmovl.u8 q{{[0-9]+}}, d{{[0-9]+}}
 uint16x8_t test_vmovl_u8(uint8x8_t a) {
   return vmovl_u8(a);
 }
 
-// CHECK: test_vmovl_u16
+// CHECK-LABEL: test_vmovl_u16
 // CHECK: vmovl.u16 q{{[0-9]+}}, d{{[0-9]+}}
 uint32x4_t test_vmovl_u16(uint16x4_t a) {
   return vmovl_u16(a);
 }
 
-// CHECK: test_vmovl_u32
+// CHECK-LABEL: test_vmovl_u32
 // CHECK: vmovl.u32 q{{[0-9]+}}, d{{[0-9]+}}
 uint64x2_t test_vmovl_u32(uint32x2_t a) {
   return vmovl_u32(a);
 }
 
 
-// CHECK: test_vmovn_s16
+// CHECK-LABEL: test_vmovn_s16
 // CHECK: vmovn.i16 d{{[0-9]+}}, q{{[0-9]+}}
 int8x8_t test_vmovn_s16(int16x8_t a) {
   return vmovn_s16(a);
 }
 
-// CHECK: test_vmovn_s32
+// CHECK-LABEL: test_vmovn_s32
 // CHECK: vmovn.i32 d{{[0-9]+}}, q{{[0-9]+}}
 int16x4_t test_vmovn_s32(int32x4_t a) {
   return vmovn_s32(a);
 }
 
-// CHECK: test_vmovn_s64
+// CHECK-LABEL: test_vmovn_s64
 // CHECK: vmovn.i64 d{{[0-9]+}}, q{{[0-9]+}}
 int32x2_t test_vmovn_s64(int64x2_t a) {
   return vmovn_s64(a);
 }
 
-// CHECK: test_vmovn_u16
+// CHECK-LABEL: test_vmovn_u16
 // CHECK: vmovn.i16 d{{[0-9]+}}, q{{[0-9]+}}
 uint8x8_t test_vmovn_u16(uint16x8_t a) {
   return vmovn_u16(a);
 }
 
-// CHECK: test_vmovn_u32
+// CHECK-LABEL: test_vmovn_u32
 // CHECK: vmovn.i32 d{{[0-9]+}}, q{{[0-9]+}}
 uint16x4_t test_vmovn_u32(uint32x4_t a) {
   return vmovn_u32(a);
 }
 
-// CHECK: test_vmovn_u64
+// CHECK-LABEL: test_vmovn_u64
 // CHECK: vmovn.i64 d{{[0-9]+}}, q{{[0-9]+}}
 uint32x2_t test_vmovn_u64(uint64x2_t a) {
   return vmovn_u64(a);
 }
 
 
-// CHECK: test_vmov_n_u8
+// CHECK-LABEL: test_vmov_n_u8
 // CHECK: vmov 
 uint8x8_t test_vmov_n_u8(uint8_t a) {
   return vmov_n_u8(a);
 }
 
-// CHECK: test_vmov_n_u16
+// CHECK-LABEL: test_vmov_n_u16
 // CHECK: vmov 
 uint16x4_t test_vmov_n_u16(uint16_t a) {
   return vmov_n_u16(a);
 }
 
-// CHECK: test_vmov_n_u32
+// CHECK-LABEL: test_vmov_n_u32
 // CHECK: vmov 
 uint32x2_t test_vmov_n_u32(uint32_t a) {
   return vmov_n_u32(a);
 }
 
-// CHECK: test_vmov_n_s8
+// CHECK-LABEL: test_vmov_n_s8
 // CHECK: vmov 
 int8x8_t test_vmov_n_s8(int8_t a) {
   return vmov_n_s8(a);
 }
 
-// CHECK: test_vmov_n_s16
+// CHECK-LABEL: test_vmov_n_s16
 // CHECK: vmov 
 int16x4_t test_vmov_n_s16(int16_t a) {
   return vmov_n_s16(a);
 }
 
-// CHECK: test_vmov_n_s32
+// CHECK-LABEL: test_vmov_n_s32
 // CHECK: vmov 
 int32x2_t test_vmov_n_s32(int32_t a) {
   return vmov_n_s32(a);
 }
 
-// CHECK: test_vmov_n_p8
+// CHECK-LABEL: test_vmov_n_p8
 // CHECK: vmov 
 poly8x8_t test_vmov_n_p8(poly8_t a) {
   return vmov_n_p8(a);
 }
 
-// CHECK: test_vmov_n_p16
+// CHECK-LABEL: test_vmov_n_p16
 // CHECK: vmov 
 poly16x4_t test_vmov_n_p16(poly16_t a) {
   return vmov_n_p16(a);
 }
 
-// CHECK: test_vmov_n_f32
+// CHECK-LABEL: test_vmov_n_f16
+// CHECK: vld1.16 {{{d[0-9]+\[\]}}}
+float16x4_t test_vmov_n_f16(float16_t *a) {
+  return vmov_n_f16(*a);
+}
+
+// CHECK-LABEL: test_vmov_n_f32
 // CHECK: vmov 
 float32x2_t test_vmov_n_f32(float32_t a) {
   return vmov_n_f32(a);
 }
 
-// CHECK: test_vmovq_n_u8
+// CHECK-LABEL: test_vmovq_n_u8
 // CHECK: vmov 
 uint8x16_t test_vmovq_n_u8(uint8_t a) {
   return vmovq_n_u8(a);
 }
 
-// CHECK: test_vmovq_n_u16
+// CHECK-LABEL: test_vmovq_n_u16
 // CHECK: vmov 
 uint16x8_t test_vmovq_n_u16(uint16_t a) {
   return vmovq_n_u16(a);
 }
 
-// CHECK: test_vmovq_n_u32
+// CHECK-LABEL: test_vmovq_n_u32
 // CHECK: vmov 
 uint32x4_t test_vmovq_n_u32(uint32_t a) {
   return vmovq_n_u32(a);
 }
 
-// CHECK: test_vmovq_n_s8
+// CHECK-LABEL: test_vmovq_n_s8
 // CHECK: vmov 
 int8x16_t test_vmovq_n_s8(int8_t a) {
   return vmovq_n_s8(a);
 }
 
-// CHECK: test_vmovq_n_s16
+// CHECK-LABEL: test_vmovq_n_s16
 // CHECK: vmov 
 int16x8_t test_vmovq_n_s16(int16_t a) {
   return vmovq_n_s16(a);
 }
 
-// CHECK: test_vmovq_n_s32
+// CHECK-LABEL: test_vmovq_n_s32
 // CHECK: vmov 
 int32x4_t test_vmovq_n_s32(int32_t a) {
   return vmovq_n_s32(a);
 }
 
-// CHECK: test_vmovq_n_p8
+// CHECK-LABEL: test_vmovq_n_p8
 // CHECK: vmov 
 poly8x16_t test_vmovq_n_p8(poly8_t a) {
   return vmovq_n_p8(a);
 }
 
-// CHECK: test_vmovq_n_p16
+// CHECK-LABEL: test_vmovq_n_p16
 // CHECK: vmov 
 poly16x8_t test_vmovq_n_p16(poly16_t a) {
   return vmovq_n_p16(a);
 }
 
-// CHECK: test_vmovq_n_f32
+// CHECK-LABEL: test_vmovq_n_f16
+// CHECK: vld1.16 {{{d[0-9]+\[\], d[0-9]+\[\]}}}
+float16x8_t test_vmovq_n_f16(float16_t *a) {
+  return vmovq_n_f16(*a);
+}
+
+// CHECK-LABEL: test_vmovq_n_f32
 // CHECK: vmov 
 float32x4_t test_vmovq_n_f32(float32_t a) {
   return vmovq_n_f32(a);
 }
 
-// CHECK: test_vmov_n_s64
+// CHECK-LABEL: test_vmov_n_s64
 // CHECK: vmov 
 int64x1_t test_vmov_n_s64(int64_t a) {
   return vmov_n_s64(a);
 }
 
-// CHECK: test_vmov_n_u64
+// CHECK-LABEL: test_vmov_n_u64
 // CHECK: vmov 
 uint64x1_t test_vmov_n_u64(uint64_t a) {
   return vmov_n_u64(a);
 }
 
-// CHECK: test_vmovq_n_s64
+// CHECK-LABEL: test_vmovq_n_s64
 // CHECK: vmov 
 int64x2_t test_vmovq_n_s64(int64_t a) {
   return vmovq_n_s64(a);
 }
 
-// CHECK: test_vmovq_n_u64
+// CHECK-LABEL: test_vmovq_n_u64
 // CHECK: vmov 
 uint64x2_t test_vmovq_n_u64(uint64_t a) {
   return vmovq_n_u64(a);
 }
 
 
-// CHECK: test_vmul_s8
+// CHECK-LABEL: test_vmul_s8
 // CHECK: vmul.i8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vmul_s8(int8x8_t a, int8x8_t b) {
   return vmul_s8(a, b);
 }
 
-// CHECK: test_vmul_s16
+// CHECK-LABEL: test_vmul_s16
 // CHECK: vmul.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vmul_s16(int16x4_t a, int16x4_t b) {
   return vmul_s16(a, b);
 }
 
-// CHECK: test_vmul_s32
+// CHECK-LABEL: test_vmul_s32
 // CHECK: vmul.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vmul_s32(int32x2_t a, int32x2_t b) {
   return vmul_s32(a, b);
 }
 
-// CHECK: test_vmul_f32
+// CHECK-LABEL: test_vmul_f32
 // CHECK: vmul.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vmul_f32(float32x2_t a, float32x2_t b) {
   return vmul_f32(a, b);
 }
 
-// CHECK: test_vmul_u8
+// CHECK-LABEL: test_vmul_u8
 // CHECK: vmul.i8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vmul_u8(uint8x8_t a, uint8x8_t b) {
   return vmul_u8(a, b);
 }
 
-// CHECK: test_vmul_u16
+// CHECK-LABEL: test_vmul_u16
 // CHECK: vmul.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vmul_u16(uint16x4_t a, uint16x4_t b) {
   return vmul_u16(a, b);
 }
 
-// CHECK: test_vmul_u32
+// CHECK-LABEL: test_vmul_u32
 // CHECK: vmul.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vmul_u32(uint32x2_t a, uint32x2_t b) {
   return vmul_u32(a, b);
 }
 
-// CHECK: test_vmulq_s8
+// CHECK-LABEL: test_vmulq_s8
 // CHECK: vmul.i8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vmulq_s8(int8x16_t a, int8x16_t b) {
   return vmulq_s8(a, b);
 }
 
-// CHECK: test_vmulq_s16
+// CHECK-LABEL: test_vmulq_s16
 // CHECK: vmul.i16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vmulq_s16(int16x8_t a, int16x8_t b) {
   return vmulq_s16(a, b);
 }
 
-// CHECK: test_vmulq_s32
+// CHECK-LABEL: test_vmulq_s32
 // CHECK: vmul.i32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vmulq_s32(int32x4_t a, int32x4_t b) {
   return vmulq_s32(a, b);
 }
 
-// CHECK: test_vmulq_f32
+// CHECK-LABEL: test_vmulq_f32
 // CHECK: vmul.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vmulq_f32(float32x4_t a, float32x4_t b) {
   return vmulq_f32(a, b);
 }
 
-// CHECK: test_vmulq_u8
+// CHECK-LABEL: test_vmulq_u8
 // CHECK: vmul.i8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vmulq_u8(uint8x16_t a, uint8x16_t b) {
   return vmulq_u8(a, b);
 }
 
-// CHECK: test_vmulq_u16
+// CHECK-LABEL: test_vmulq_u16
 // CHECK: vmul.i16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vmulq_u16(uint16x8_t a, uint16x8_t b) {
   return vmulq_u16(a, b);
 }
 
-// CHECK: test_vmulq_u32
+// CHECK-LABEL: test_vmulq_u32
 // CHECK: vmul.i32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vmulq_u32(uint32x4_t a, uint32x4_t b) {
   return vmulq_u32(a, b);
 }
 
 
-// CHECK: test_vmull_s8
+// CHECK-LABEL: test_vmull_s8
 // CHECK: vmull.s8 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x8_t test_vmull_s8(int8x8_t a, int8x8_t b) {
   return vmull_s8(a, b);
 }
 
-// CHECK: test_vmull_s16
+// CHECK-LABEL: test_vmull_s16
 // CHECK: vmull.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vmull_s16(int16x4_t a, int16x4_t b) {
   return vmull_s16(a, b);
 }
 
-// CHECK: test_vmull_s32
+// CHECK-LABEL: test_vmull_s32
 // CHECK: vmull.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vmull_s32(int32x2_t a, int32x2_t b) {
   return vmull_s32(a, b);
 }
 
-// CHECK: test_vmull_u8
+// CHECK-LABEL: test_vmull_u8
 // CHECK: vmull.u8 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x8_t test_vmull_u8(uint8x8_t a, uint8x8_t b) {
   return vmull_u8(a, b);
 }
 
-// CHECK: test_vmull_u16
+// CHECK-LABEL: test_vmull_u16
 // CHECK: vmull.u16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x4_t test_vmull_u16(uint16x4_t a, uint16x4_t b) {
   return vmull_u16(a, b);
 }
 
-// CHECK: test_vmull_u32
+// CHECK-LABEL: test_vmull_u32
 // CHECK: vmull.u32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x2_t test_vmull_u32(uint32x2_t a, uint32x2_t b) {
   return vmull_u32(a, b);
 }
 
-// CHECK: test_vmull_p8
+// CHECK-LABEL: test_vmull_p8
 // CHECK: vmull.p8 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 poly16x8_t test_vmull_p8(poly8x8_t a, poly8x8_t b) {
   return vmull_p8(a, b);
 }
 
 
-// CHECK: test_vmull_lane_s16
+// CHECK-LABEL: test_vmull_lane_s16
 // CHECK: vmull.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int32x4_t test_vmull_lane_s16(int16x4_t a, int16x4_t b) {
   return vmull_lane_s16(a, b, 3);
 }
 
-// CHECK: test_vmull_lane_s32
+// CHECK-LABEL: test_vmull_lane_s32
 // CHECK: vmull.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int64x2_t test_vmull_lane_s32(int32x2_t a, int32x2_t b) {
   return vmull_lane_s32(a, b, 1);
 }
 
-// CHECK: test_vmull_lane_u16
+// CHECK-LABEL: test_vmull_lane_u16
 // CHECK: vmull.u16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint32x4_t test_vmull_lane_u16(uint16x4_t a, uint16x4_t b) {
   return vmull_lane_u16(a, b, 3);
 }
 
-// CHECK: test_vmull_lane_u32
+// CHECK-LABEL: test_vmull_lane_u32
 // CHECK: vmull.u32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint64x2_t test_vmull_lane_u32(uint32x2_t a, uint32x2_t b) {
   return vmull_lane_u32(a, b, 1);
 }
 
 
-// CHECK: test_vmull_n_s16
+// CHECK-LABEL: test_vmull_n_s16
 // CHECK: vmull.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vmull_n_s16(int16x4_t a, int16_t b) {
   return vmull_n_s16(a, b);
 }
 
-// CHECK: test_vmull_n_s32
+// CHECK-LABEL: test_vmull_n_s32
 // CHECK: vmull.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vmull_n_s32(int32x2_t a, int32_t b) {
   return vmull_n_s32(a, b);
 }
 
-// CHECK: test_vmull_n_u16
+// CHECK-LABEL: test_vmull_n_u16
 // CHECK: vmull.u16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x4_t test_vmull_n_u16(uint16x4_t a, uint16_t b) {
   return vmull_n_u16(a, b);
 }
 
-// CHECK: test_vmull_n_u32
+// CHECK-LABEL: test_vmull_n_u32
 // CHECK: vmull.u32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x2_t test_vmull_n_u32(uint32x2_t a, uint32_t b) {
   return vmull_n_u32(a, b);
 }
 
 
-// CHECK: test_vmul_p8
+// CHECK-LABEL: test_vmul_p8
 // CHECK: vmul.p8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 poly8x8_t test_vmul_p8(poly8x8_t a, poly8x8_t b) {
   return vmul_p8(a, b);
 }
 
-// CHECK: test_vmulq_p8
+// CHECK-LABEL: test_vmulq_p8
 // CHECK: vmul.p8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 poly8x16_t test_vmulq_p8(poly8x16_t a, poly8x16_t b) {
   return vmulq_p8(a, b);
 }
 
 
-// CHECK: test_vmul_lane_s16
+// CHECK-LABEL: test_vmul_lane_s16
 // CHECK: vmul.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int16x4_t test_vmul_lane_s16(int16x4_t a, int16x4_t b) {
   return vmul_lane_s16(a, b, 3);
 }
 
-// CHECK: test_vmul_lane_s32
+// CHECK-LABEL: test_vmul_lane_s32
 // CHECK: vmul.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int32x2_t test_vmul_lane_s32(int32x2_t a, int32x2_t b) {
   return vmul_lane_s32(a, b, 1);
 }
 
-// CHECK: test_vmul_lane_f32
+// CHECK-LABEL: test_vmul_lane_f32
 // CHECK: vmul.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 float32x2_t test_vmul_lane_f32(float32x2_t a, float32x2_t b) {
   return vmul_lane_f32(a, b, 1);
 }
 
-// CHECK: test_vmul_lane_u16
+// CHECK-LABEL: test_vmul_lane_u16
 // CHECK: vmul.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint16x4_t test_vmul_lane_u16(uint16x4_t a, uint16x4_t b) {
   return vmul_lane_u16(a, b, 3);
 }
 
-// CHECK: test_vmul_lane_u32
+// CHECK-LABEL: test_vmul_lane_u32
 // CHECK: vmul.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint32x2_t test_vmul_lane_u32(uint32x2_t a, uint32x2_t b) {
   return vmul_lane_u32(a, b, 1);
 }
 
-// CHECK: test_vmulq_lane_s16
+// CHECK-LABEL: test_vmulq_lane_s16
 // CHECK: vmul.i16 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int16x8_t test_vmulq_lane_s16(int16x8_t a, int16x4_t b) {
   return vmulq_lane_s16(a, b, 3);
 }
 
-// CHECK: test_vmulq_lane_s32
+// CHECK-LABEL: test_vmulq_lane_s32
 // CHECK: vmul.i32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int32x4_t test_vmulq_lane_s32(int32x4_t a, int32x2_t b) {
   return vmulq_lane_s32(a, b, 1);
 }
 
-// CHECK: test_vmulq_lane_f32
+// CHECK-LABEL: test_vmulq_lane_f32
 // CHECK: vmul.f32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 float32x4_t test_vmulq_lane_f32(float32x4_t a, float32x2_t b) {
   return vmulq_lane_f32(a, b, 1);
 }
 
-// CHECK: test_vmulq_lane_u16
+// CHECK-LABEL: test_vmulq_lane_u16
 // CHECK: vmul.i16 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint16x8_t test_vmulq_lane_u16(uint16x8_t a, uint16x4_t b) {
   return vmulq_lane_u16(a, b, 3);
 }
 
-// CHECK: test_vmulq_lane_u32
+// CHECK-LABEL: test_vmulq_lane_u32
 // CHECK: vmul.i32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 uint32x4_t test_vmulq_lane_u32(uint32x4_t a, uint32x2_t b) {
   return vmulq_lane_u32(a, b, 1);
 }
 
 
-// CHECK: test_vmul_n_s16
+// CHECK-LABEL: test_vmul_n_s16
 // CHECK: vmul.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vmul_n_s16(int16x4_t a, int16_t b) {
   return vmul_n_s16(a, b);
 }
 
-// CHECK: test_vmul_n_s32
+// CHECK-LABEL: test_vmul_n_s32
 // CHECK: vmul.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vmul_n_s32(int32x2_t a, int32_t b) {
   return vmul_n_s32(a, b);
 }
 
-// CHECK: test_vmul_n_f32
+// CHECK-LABEL: test_vmul_n_f32
 // CHECK: vmul.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vmul_n_f32(float32x2_t a, float32_t b) {
   return vmul_n_f32(a, b);
 }
 
-// CHECK: test_vmul_n_u16
+// CHECK-LABEL: test_vmul_n_u16
 // CHECK: vmul.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vmul_n_u16(uint16x4_t a, uint16_t b) {
   return vmul_n_u16(a, b);
 }
 
-// CHECK: test_vmul_n_u32
+// CHECK-LABEL: test_vmul_n_u32
 // CHECK: vmul.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vmul_n_u32(uint32x2_t a, uint32_t b) {
   return vmul_n_u32(a, b);
 }
 
-// CHECK: test_vmulq_n_s16
+// CHECK-LABEL: test_vmulq_n_s16
 // CHECK: vmul.i16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vmulq_n_s16(int16x8_t a, int16_t b) {
   return vmulq_n_s16(a, b);
 }
 
-// CHECK: test_vmulq_n_s32
+// CHECK-LABEL: test_vmulq_n_s32
 // CHECK: vmul.i32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vmulq_n_s32(int32x4_t a, int32_t b) {
   return vmulq_n_s32(a, b);
 }
 
-// CHECK: test_vmulq_n_f32
+// CHECK-LABEL: test_vmulq_n_f32
 // CHECK: vmul.f32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[0]
 float32x4_t test_vmulq_n_f32(float32x4_t a, float32_t b) {
   return vmulq_n_f32(a, b);
 }
 
-// CHECK: test_vmulq_n_u16
+// CHECK-LABEL: test_vmulq_n_u16
 // CHECK: vmul.i16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vmulq_n_u16(uint16x8_t a, uint16_t b) {
   return vmulq_n_u16(a, b);
 }
 
-// CHECK: test_vmulq_n_u32
+// CHECK-LABEL: test_vmulq_n_u32
 // CHECK: vmul.i32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vmulq_n_u32(uint32x4_t a, uint32_t b) {
   return vmulq_n_u32(a, b);
 }
 
 
-// CHECK: test_vmvn_s8
+// CHECK-LABEL: test_vmvn_s8
 // CHECK: vmvn d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vmvn_s8(int8x8_t a) {
   return vmvn_s8(a);
 }
 
-// CHECK: test_vmvn_s16
+// CHECK-LABEL: test_vmvn_s16
 // CHECK: vmvn d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vmvn_s16(int16x4_t a) {
   return vmvn_s16(a);
 }
 
-// CHECK: test_vmvn_s32
+// CHECK-LABEL: test_vmvn_s32
 // CHECK: vmvn d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vmvn_s32(int32x2_t a) {
   return vmvn_s32(a);
 }
 
-// CHECK: test_vmvn_u8
+// CHECK-LABEL: test_vmvn_u8
 // CHECK: vmvn d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vmvn_u8(uint8x8_t a) {
   return vmvn_u8(a);
 }
 
-// CHECK: test_vmvn_u16
+// CHECK-LABEL: test_vmvn_u16
 // CHECK: vmvn d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vmvn_u16(uint16x4_t a) {
   return vmvn_u16(a);
 }
 
-// CHECK: test_vmvn_u32
+// CHECK-LABEL: test_vmvn_u32
 // CHECK: vmvn d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vmvn_u32(uint32x2_t a) {
   return vmvn_u32(a);
 }
 
-// CHECK: test_vmvn_p8
+// CHECK-LABEL: test_vmvn_p8
 // CHECK: vmvn d{{[0-9]+}}, d{{[0-9]+}}
 poly8x8_t test_vmvn_p8(poly8x8_t a) {
   return vmvn_p8(a);
 }
 
-// CHECK: test_vmvnq_s8
+// CHECK-LABEL: test_vmvnq_s8
 // CHECK: vmvn q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vmvnq_s8(int8x16_t a) {
   return vmvnq_s8(a);
 }
 
-// CHECK: test_vmvnq_s16
+// CHECK-LABEL: test_vmvnq_s16
 // CHECK: vmvn q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vmvnq_s16(int16x8_t a) {
   return vmvnq_s16(a);
 }
 
-// CHECK: test_vmvnq_s32
+// CHECK-LABEL: test_vmvnq_s32
 // CHECK: vmvn q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vmvnq_s32(int32x4_t a) {
   return vmvnq_s32(a);
 }
 
-// CHECK: test_vmvnq_u8
+// CHECK-LABEL: test_vmvnq_u8
 // CHECK: vmvn q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vmvnq_u8(uint8x16_t a) {
   return vmvnq_u8(a);
 }
 
-// CHECK: test_vmvnq_u16
+// CHECK-LABEL: test_vmvnq_u16
 // CHECK: vmvn q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vmvnq_u16(uint16x8_t a) {
   return vmvnq_u16(a);
 }
 
-// CHECK: test_vmvnq_u32
+// CHECK-LABEL: test_vmvnq_u32
 // CHECK: vmvn q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vmvnq_u32(uint32x4_t a) {
   return vmvnq_u32(a);
 }
 
-// CHECK: test_vmvnq_p8
+// CHECK-LABEL: test_vmvnq_p8
 // CHECK: vmvn q{{[0-9]+}}, q{{[0-9]+}}
 poly8x16_t test_vmvnq_p8(poly8x16_t a) {
   return vmvnq_p8(a);
 }
 
 
-// CHECK: test_vneg_s8
+// CHECK-LABEL: test_vneg_s8
 // CHECK: vneg.s8 d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vneg_s8(int8x8_t a) {
   return vneg_s8(a);
 }
 
-// CHECK: test_vneg_s16
+// CHECK-LABEL: test_vneg_s16
 // CHECK: vneg.s16 d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vneg_s16(int16x4_t a) {
   return vneg_s16(a);
 }
 
-// CHECK: test_vneg_s32
+// CHECK-LABEL: test_vneg_s32
 // CHECK: vneg.s32 d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vneg_s32(int32x2_t a) {
   return vneg_s32(a);
 }
 
-// CHECK: test_vneg_f32
+// CHECK-LABEL: test_vneg_f32
 // CHECK: vneg.f32 d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vneg_f32(float32x2_t a) {
   return vneg_f32(a);
 }
 
-// CHECK: test_vnegq_s8
+// CHECK-LABEL: test_vnegq_s8
 // CHECK: vneg.s8 q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vnegq_s8(int8x16_t a) {
   return vnegq_s8(a);
 }
 
-// CHECK: test_vnegq_s16
+// CHECK-LABEL: test_vnegq_s16
 // CHECK: vneg.s16 q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vnegq_s16(int16x8_t a) {
   return vnegq_s16(a);
 }
 
-// CHECK: test_vnegq_s32
+// CHECK-LABEL: test_vnegq_s32
 // CHECK: vneg.s32 q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vnegq_s32(int32x4_t a) {
   return vnegq_s32(a);
 }
 
-// CHECK: test_vnegq_f32
+// CHECK-LABEL: test_vnegq_f32
 // CHECK: vneg.f32 q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vnegq_f32(float32x4_t a) {
   return vnegq_f32(a);
 }
 
 
-// CHECK: test_vorn_s8
+// CHECK-LABEL: test_vorn_s8
 // CHECK: vorn d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vorn_s8(int8x8_t a, int8x8_t b) {
   return vorn_s8(a, b);
 }
 
-// CHECK: test_vorn_s16
+// CHECK-LABEL: test_vorn_s16
 // CHECK: vorn d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vorn_s16(int16x4_t a, int16x4_t b) {
   return vorn_s16(a, b);
 }
 
-// CHECK: test_vorn_s32
+// CHECK-LABEL: test_vorn_s32
 // CHECK: vorn d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vorn_s32(int32x2_t a, int32x2_t b) {
   return vorn_s32(a, b);
 }
 
-// CHECK: test_vorn_s64
+// CHECK-LABEL: test_vorn_s64
 // CHECK: vorn d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x1_t test_vorn_s64(int64x1_t a, int64x1_t b) {
   return vorn_s64(a, b);
 }
 
-// CHECK: test_vorn_u8
+// CHECK-LABEL: test_vorn_u8
 // CHECK: vorn d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vorn_u8(uint8x8_t a, uint8x8_t b) {
   return vorn_u8(a, b);
 }
 
-// CHECK: test_vorn_u16
+// CHECK-LABEL: test_vorn_u16
 // CHECK: vorn d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vorn_u16(uint16x4_t a, uint16x4_t b) {
   return vorn_u16(a, b);
 }
 
-// CHECK: test_vorn_u32
+// CHECK-LABEL: test_vorn_u32
 // CHECK: vorn d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vorn_u32(uint32x2_t a, uint32x2_t b) {
   return vorn_u32(a, b);
 }
 
-// CHECK: test_vorn_u64
+// CHECK-LABEL: test_vorn_u64
 // CHECK: vorn d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x1_t test_vorn_u64(uint64x1_t a, uint64x1_t b) {
   return vorn_u64(a, b);
 }
 
-// CHECK: test_vornq_s8
+// CHECK-LABEL: test_vornq_s8
 // CHECK: vorn q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vornq_s8(int8x16_t a, int8x16_t b) {
   return vornq_s8(a, b);
 }
 
-// CHECK: test_vornq_s16
+// CHECK-LABEL: test_vornq_s16
 // CHECK: vorn q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vornq_s16(int16x8_t a, int16x8_t b) {
   return vornq_s16(a, b);
 }
 
-// CHECK: test_vornq_s32
+// CHECK-LABEL: test_vornq_s32
 // CHECK: vorn q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vornq_s32(int32x4_t a, int32x4_t b) {
   return vornq_s32(a, b);
 }
 
-// CHECK: test_vornq_s64
+// CHECK-LABEL: test_vornq_s64
 // CHECK: vorn q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int64x2_t test_vornq_s64(int64x2_t a, int64x2_t b) {
   return vornq_s64(a, b);
 }
 
-// CHECK: test_vornq_u8
+// CHECK-LABEL: test_vornq_u8
 // CHECK: vorn q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vornq_u8(uint8x16_t a, uint8x16_t b) {
   return vornq_u8(a, b);
 }
 
-// CHECK: test_vornq_u16
+// CHECK-LABEL: test_vornq_u16
 // CHECK: vorn q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vornq_u16(uint16x8_t a, uint16x8_t b) {
   return vornq_u16(a, b);
 }
 
-// CHECK: test_vornq_u32
+// CHECK-LABEL: test_vornq_u32
 // CHECK: vorn q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vornq_u32(uint32x4_t a, uint32x4_t b) {
   return vornq_u32(a, b);
 }
 
-// CHECK: test_vornq_u64
+// CHECK-LABEL: test_vornq_u64
 // CHECK: vorn q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint64x2_t test_vornq_u64(uint64x2_t a, uint64x2_t b) {
   return vornq_u64(a, b);
 }
 
 
-// CHECK: test_vorr_s8
+// CHECK-LABEL: test_vorr_s8
 // CHECK: vorr d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vorr_s8(int8x8_t a, int8x8_t b) {
   return vorr_s8(a, b);
 }
 
-// CHECK: test_vorr_s16
+// CHECK-LABEL: test_vorr_s16
 // CHECK: vorr d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vorr_s16(int16x4_t a, int16x4_t b) {
   return vorr_s16(a, b);
 }
 
-// CHECK: test_vorr_s32
+// CHECK-LABEL: test_vorr_s32
 // CHECK: vorr d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vorr_s32(int32x2_t a, int32x2_t b) {
   return vorr_s32(a, b);
 }
 
-// CHECK: test_vorr_s64
+// CHECK-LABEL: test_vorr_s64
 // CHECK: vorr d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x1_t test_vorr_s64(int64x1_t a, int64x1_t b) {
   return vorr_s64(a, b);
 }
 
-// CHECK: test_vorr_u8
+// CHECK-LABEL: test_vorr_u8
 // CHECK: vorr d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vorr_u8(uint8x8_t a, uint8x8_t b) {
   return vorr_u8(a, b);
 }
 
-// CHECK: test_vorr_u16
+// CHECK-LABEL: test_vorr_u16
 // CHECK: vorr d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vorr_u16(uint16x4_t a, uint16x4_t b) {
   return vorr_u16(a, b);
 }
 
-// CHECK: test_vorr_u32
+// CHECK-LABEL: test_vorr_u32
 // CHECK: vorr d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vorr_u32(uint32x2_t a, uint32x2_t b) {
   return vorr_u32(a, b);
 }
 
-// CHECK: test_vorr_u64
+// CHECK-LABEL: test_vorr_u64
 // CHECK: vorr d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x1_t test_vorr_u64(uint64x1_t a, uint64x1_t b) {
   return vorr_u64(a, b);
 }
 
-// CHECK: test_vorrq_s8
+// CHECK-LABEL: test_vorrq_s8
 // CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vorrq_s8(int8x16_t a, int8x16_t b) {
   return vorrq_s8(a, b);
 }
 
-// CHECK: test_vorrq_s16
+// CHECK-LABEL: test_vorrq_s16
 // CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vorrq_s16(int16x8_t a, int16x8_t b) {
   return vorrq_s16(a, b);
 }
 
-// CHECK: test_vorrq_s32
+// CHECK-LABEL: test_vorrq_s32
 // CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vorrq_s32(int32x4_t a, int32x4_t b) {
   return vorrq_s32(a, b);
 }
 
-// CHECK: test_vorrq_s64
+// CHECK-LABEL: test_vorrq_s64
 // CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int64x2_t test_vorrq_s64(int64x2_t a, int64x2_t b) {
   return vorrq_s64(a, b);
 }
 
-// CHECK: test_vorrq_u8
+// CHECK-LABEL: test_vorrq_u8
 // CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vorrq_u8(uint8x16_t a, uint8x16_t b) {
   return vorrq_u8(a, b);
 }
 
-// CHECK: test_vorrq_u16
+// CHECK-LABEL: test_vorrq_u16
 // CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vorrq_u16(uint16x8_t a, uint16x8_t b) {
   return vorrq_u16(a, b);
 }
 
-// CHECK: test_vorrq_u32
+// CHECK-LABEL: test_vorrq_u32
 // CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vorrq_u32(uint32x4_t a, uint32x4_t b) {
   return vorrq_u32(a, b);
 }
 
-// CHECK: test_vorrq_u64
+// CHECK-LABEL: test_vorrq_u64
 // CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint64x2_t test_vorrq_u64(uint64x2_t a, uint64x2_t b) {
   return vorrq_u64(a, b);
 }
 
 
-// CHECK: test_vpadal_s8
+// CHECK-LABEL: test_vpadal_s8
 // CHECK: vpadal.s8 d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vpadal_s8(int16x4_t a, int8x8_t b) {
   return vpadal_s8(a, b);
 }
 
-// CHECK: test_vpadal_s16
+// CHECK-LABEL: test_vpadal_s16
 // CHECK: vpadal.s16 d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vpadal_s16(int32x2_t a, int16x4_t b) {
   return vpadal_s16(a, b);
 }
 
-// CHECK: test_vpadal_s32
+// CHECK-LABEL: test_vpadal_s32
 // CHECK: vpadal.s32 d{{[0-9]+}}, d{{[0-9]+}}
 int64x1_t test_vpadal_s32(int64x1_t a, int32x2_t b) {
   return vpadal_s32(a, b);
 }
 
-// CHECK: test_vpadal_u8
+// CHECK-LABEL: test_vpadal_u8
 // CHECK: vpadal.u8 d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vpadal_u8(uint16x4_t a, uint8x8_t b) {
   return vpadal_u8(a, b);
 }
 
-// CHECK: test_vpadal_u16
+// CHECK-LABEL: test_vpadal_u16
 // CHECK: vpadal.u16 d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vpadal_u16(uint32x2_t a, uint16x4_t b) {
   return vpadal_u16(a, b);
 }
 
-// CHECK: test_vpadal_u32
+// CHECK-LABEL: test_vpadal_u32
 // CHECK: vpadal.u32 d{{[0-9]+}}, d{{[0-9]+}}
 uint64x1_t test_vpadal_u32(uint64x1_t a, uint32x2_t b) {
   return vpadal_u32(a, b);
 }
 
-// CHECK: test_vpadalq_s8
+// CHECK-LABEL: test_vpadalq_s8
 // CHECK: vpadal.s8 q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vpadalq_s8(int16x8_t a, int8x16_t b) {
   return vpadalq_s8(a, b);
 }
 
-// CHECK: test_vpadalq_s16
+// CHECK-LABEL: test_vpadalq_s16
 // CHECK: vpadal.s16 q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vpadalq_s16(int32x4_t a, int16x8_t b) {
   return vpadalq_s16(a, b);
 }
 
-// CHECK: test_vpadalq_s32
+// CHECK-LABEL: test_vpadalq_s32
 // CHECK: vpadal.s32 q{{[0-9]+}}, q{{[0-9]+}}
 int64x2_t test_vpadalq_s32(int64x2_t a, int32x4_t b) {
   return vpadalq_s32(a, b);
 }
 
-// CHECK: test_vpadalq_u8
+// CHECK-LABEL: test_vpadalq_u8
 // CHECK: vpadal.u8 q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vpadalq_u8(uint16x8_t a, uint8x16_t b) {
   return vpadalq_u8(a, b);
 }
 
-// CHECK: test_vpadalq_u16
+// CHECK-LABEL: test_vpadalq_u16
 // CHECK: vpadal.u16 q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vpadalq_u16(uint32x4_t a, uint16x8_t b) {
   return vpadalq_u16(a, b);
 }
 
-// CHECK: test_vpadalq_u32
+// CHECK-LABEL: test_vpadalq_u32
 // CHECK: vpadal.u32 q{{[0-9]+}}, q{{[0-9]+}}
 uint64x2_t test_vpadalq_u32(uint64x2_t a, uint32x4_t b) {
   return vpadalq_u32(a, b);
 }
 
 
-// CHECK: test_vpadd_s8
+// CHECK-LABEL: test_vpadd_s8
 // CHECK: vpadd.i8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vpadd_s8(int8x8_t a, int8x8_t b) {
   return vpadd_s8(a, b);
 }
 
-// CHECK: test_vpadd_s16
+// CHECK-LABEL: test_vpadd_s16
 // CHECK: vpadd.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vpadd_s16(int16x4_t a, int16x4_t b) {
   return vpadd_s16(a, b);
 }
 
-// CHECK: test_vpadd_s32
+// CHECK-LABEL: test_vpadd_s32
 // CHECK: vpadd.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vpadd_s32(int32x2_t a, int32x2_t b) {
   return vpadd_s32(a, b);
 }
 
-// CHECK: test_vpadd_u8
+// CHECK-LABEL: test_vpadd_u8
 // CHECK: vpadd.i8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vpadd_u8(uint8x8_t a, uint8x8_t b) {
   return vpadd_u8(a, b);
 }
 
-// CHECK: test_vpadd_u16
+// CHECK-LABEL: test_vpadd_u16
 // CHECK: vpadd.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vpadd_u16(uint16x4_t a, uint16x4_t b) {
   return vpadd_u16(a, b);
 }
 
-// CHECK: test_vpadd_u32
+// CHECK-LABEL: test_vpadd_u32
 // CHECK: vpadd.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vpadd_u32(uint32x2_t a, uint32x2_t b) {
   return vpadd_u32(a, b);
 }
 
-// CHECK: test_vpadd_f32
+// CHECK-LABEL: test_vpadd_f32
 // CHECK: vpadd.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vpadd_f32(float32x2_t a, float32x2_t b) {
   return vpadd_f32(a, b);
 }
 
 
-// CHECK: test_vpaddl_s8
+// CHECK-LABEL: test_vpaddl_s8
 // CHECK: vpaddl.s8 d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vpaddl_s8(int8x8_t a) {
   return vpaddl_s8(a);
 }
 
-// CHECK: test_vpaddl_s16
+// CHECK-LABEL: test_vpaddl_s16
 // CHECK: vpaddl.s16 d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vpaddl_s16(int16x4_t a) {
   return vpaddl_s16(a);
 }
 
-// CHECK: test_vpaddl_s32
+// CHECK-LABEL: test_vpaddl_s32
 // CHECK: vpaddl.s32 d{{[0-9]+}}, d{{[0-9]+}}
 int64x1_t test_vpaddl_s32(int32x2_t a) {
   return vpaddl_s32(a);
 }
 
-// CHECK: test_vpaddl_u8
+// CHECK-LABEL: test_vpaddl_u8
 // CHECK: vpaddl.u8 d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vpaddl_u8(uint8x8_t a) {
   return vpaddl_u8(a);
 }
 
-// CHECK: test_vpaddl_u16
+// CHECK-LABEL: test_vpaddl_u16
 // CHECK: vpaddl.u16 d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vpaddl_u16(uint16x4_t a) {
   return vpaddl_u16(a);
 }
 
-// CHECK: test_vpaddl_u32
+// CHECK-LABEL: test_vpaddl_u32
 // CHECK: vpaddl.u32 d{{[0-9]+}}, d{{[0-9]+}}
 uint64x1_t test_vpaddl_u32(uint32x2_t a) {
   return vpaddl_u32(a);
 }
 
-// CHECK: test_vpaddlq_s8
+// CHECK-LABEL: test_vpaddlq_s8
 // CHECK: vpaddl.s8 q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vpaddlq_s8(int8x16_t a) {
   return vpaddlq_s8(a);
 }
 
-// CHECK: test_vpaddlq_s16
+// CHECK-LABEL: test_vpaddlq_s16
 // CHECK: vpaddl.s16 q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vpaddlq_s16(int16x8_t a) {
   return vpaddlq_s16(a);
 }
 
-// CHECK: test_vpaddlq_s32
+// CHECK-LABEL: test_vpaddlq_s32
 // CHECK: vpaddl.s32 q{{[0-9]+}}, q{{[0-9]+}}
 int64x2_t test_vpaddlq_s32(int32x4_t a) {
   return vpaddlq_s32(a);
 }
 
-// CHECK: test_vpaddlq_u8
+// CHECK-LABEL: test_vpaddlq_u8
 // CHECK: vpaddl.u8 q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vpaddlq_u8(uint8x16_t a) {
   return vpaddlq_u8(a);
 }
 
-// CHECK: test_vpaddlq_u16
+// CHECK-LABEL: test_vpaddlq_u16
 // CHECK: vpaddl.u16 q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vpaddlq_u16(uint16x8_t a) {
   return vpaddlq_u16(a);
 }
 
-// CHECK: test_vpaddlq_u32
+// CHECK-LABEL: test_vpaddlq_u32
 // CHECK: vpaddl.u32 q{{[0-9]+}}, q{{[0-9]+}}
 uint64x2_t test_vpaddlq_u32(uint32x4_t a) {
   return vpaddlq_u32(a);
 }
 
 
-// CHECK: test_vpmax_s8
+// CHECK-LABEL: test_vpmax_s8
 // CHECK: vpmax.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vpmax_s8(int8x8_t a, int8x8_t b) {
   return vpmax_s8(a, b);
 }
 
-// CHECK: test_vpmax_s16
+// CHECK-LABEL: test_vpmax_s16
 // CHECK: vpmax.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vpmax_s16(int16x4_t a, int16x4_t b) {
   return vpmax_s16(a, b);
 }
 
-// CHECK: test_vpmax_s32
+// CHECK-LABEL: test_vpmax_s32
 // CHECK: vpmax.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vpmax_s32(int32x2_t a, int32x2_t b) {
   return vpmax_s32(a, b);
 }
 
-// CHECK: test_vpmax_u8
+// CHECK-LABEL: test_vpmax_u8
 // CHECK: vpmax.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vpmax_u8(uint8x8_t a, uint8x8_t b) {
   return vpmax_u8(a, b);
 }
 
-// CHECK: test_vpmax_u16
+// CHECK-LABEL: test_vpmax_u16
 // CHECK: vpmax.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vpmax_u16(uint16x4_t a, uint16x4_t b) {
   return vpmax_u16(a, b);
 }
 
-// CHECK: test_vpmax_u32
+// CHECK-LABEL: test_vpmax_u32
 // CHECK: vpmax.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vpmax_u32(uint32x2_t a, uint32x2_t b) {
   return vpmax_u32(a, b);
 }
 
-// CHECK: test_vpmax_f32
+// CHECK-LABEL: test_vpmax_f32
 // CHECK: vpmax.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vpmax_f32(float32x2_t a, float32x2_t b) {
   return vpmax_f32(a, b);
 }
 
 
-// CHECK: test_vpmin_s8
+// CHECK-LABEL: test_vpmin_s8
 // CHECK: vpmin.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vpmin_s8(int8x8_t a, int8x8_t b) {
   return vpmin_s8(a, b);
 }
 
-// CHECK: test_vpmin_s16
+// CHECK-LABEL: test_vpmin_s16
 // CHECK: vpmin.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vpmin_s16(int16x4_t a, int16x4_t b) {
   return vpmin_s16(a, b);
 }
 
-// CHECK: test_vpmin_s32
+// CHECK-LABEL: test_vpmin_s32
 // CHECK: vpmin.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vpmin_s32(int32x2_t a, int32x2_t b) {
   return vpmin_s32(a, b);
 }
 
-// CHECK: test_vpmin_u8
+// CHECK-LABEL: test_vpmin_u8
 // CHECK: vpmin.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vpmin_u8(uint8x8_t a, uint8x8_t b) {
   return vpmin_u8(a, b);
 }
 
-// CHECK: test_vpmin_u16
+// CHECK-LABEL: test_vpmin_u16
 // CHECK: vpmin.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vpmin_u16(uint16x4_t a, uint16x4_t b) {
   return vpmin_u16(a, b);
 }
 
-// CHECK: test_vpmin_u32
+// CHECK-LABEL: test_vpmin_u32
 // CHECK: vpmin.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vpmin_u32(uint32x2_t a, uint32x2_t b) {
   return vpmin_u32(a, b);
 }
 
-// CHECK: test_vpmin_f32
+// CHECK-LABEL: test_vpmin_f32
 // CHECK: vpmin.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vpmin_f32(float32x2_t a, float32x2_t b) {
   return vpmin_f32(a, b);
 }
 
 
-// CHECK: test_vqabs_s8
+// CHECK-LABEL: test_vqabs_s8
 // CHECK: vqabs.s8 d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vqabs_s8(int8x8_t a) {
   return vqabs_s8(a);
 }
 
-// CHECK: test_vqabs_s16
+// CHECK-LABEL: test_vqabs_s16
 // CHECK: vqabs.s16 d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vqabs_s16(int16x4_t a) {
   return vqabs_s16(a);
 }
 
-// CHECK: test_vqabs_s32
+// CHECK-LABEL: test_vqabs_s32
 // CHECK: vqabs.s32 d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vqabs_s32(int32x2_t a) {
   return vqabs_s32(a);
 }
 
-// CHECK: test_vqabsq_s8
+// CHECK-LABEL: test_vqabsq_s8
 // CHECK: vqabs.s8 q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vqabsq_s8(int8x16_t a) {
   return vqabsq_s8(a);
 }
 
-// CHECK: test_vqabsq_s16
+// CHECK-LABEL: test_vqabsq_s16
 // CHECK: vqabs.s16 q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vqabsq_s16(int16x8_t a) {
   return vqabsq_s16(a);
 }
 
-// CHECK: test_vqabsq_s32
+// CHECK-LABEL: test_vqabsq_s32
 // CHECK: vqabs.s32 q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vqabsq_s32(int32x4_t a) {
   return vqabsq_s32(a);
 }
 
 
-// CHECK: test_vqadd_s8
+// CHECK-LABEL: test_vqadd_s8
 // CHECK: vqadd.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vqadd_s8(int8x8_t a, int8x8_t b) {
   return vqadd_s8(a, b);
 }
 
-// CHECK: test_vqadd_s16
+// CHECK-LABEL: test_vqadd_s16
 // CHECK: vqadd.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vqadd_s16(int16x4_t a, int16x4_t b) {
   return vqadd_s16(a, b);
 }
 
-// CHECK: test_vqadd_s32
+// CHECK-LABEL: test_vqadd_s32
 // CHECK: vqadd.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vqadd_s32(int32x2_t a, int32x2_t b) {
   return vqadd_s32(a, b);
 }
 
-// CHECK: test_vqadd_s64
+// CHECK-LABEL: test_vqadd_s64
 // CHECK: vqadd.s64 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x1_t test_vqadd_s64(int64x1_t a, int64x1_t b) {
   return vqadd_s64(a, b);
 }
 
-// CHECK: test_vqadd_u8
+// CHECK-LABEL: test_vqadd_u8
 // CHECK: vqadd.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vqadd_u8(uint8x8_t a, uint8x8_t b) {
   return vqadd_u8(a, b);
 }
 
-// CHECK: test_vqadd_u16
+// CHECK-LABEL: test_vqadd_u16
 // CHECK: vqadd.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vqadd_u16(uint16x4_t a, uint16x4_t b) {
   return vqadd_u16(a, b);
 }
 
-// CHECK: test_vqadd_u32
+// CHECK-LABEL: test_vqadd_u32
 // CHECK: vqadd.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vqadd_u32(uint32x2_t a, uint32x2_t b) {
   return vqadd_u32(a, b);
 }
 
-// CHECK: test_vqadd_u64
+// CHECK-LABEL: test_vqadd_u64
 // CHECK: vqadd.u64 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x1_t test_vqadd_u64(uint64x1_t a, uint64x1_t b) {
   return vqadd_u64(a, b);
 }
 
-// CHECK: test_vqaddq_s8
+// CHECK-LABEL: test_vqaddq_s8
 // CHECK: vqadd.s8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vqaddq_s8(int8x16_t a, int8x16_t b) {
   return vqaddq_s8(a, b);
 }
 
-// CHECK: test_vqaddq_s16
+// CHECK-LABEL: test_vqaddq_s16
 // CHECK: vqadd.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vqaddq_s16(int16x8_t a, int16x8_t b) {
   return vqaddq_s16(a, b);
 }
 
-// CHECK: test_vqaddq_s32
+// CHECK-LABEL: test_vqaddq_s32
 // CHECK: vqadd.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vqaddq_s32(int32x4_t a, int32x4_t b) {
   return vqaddq_s32(a, b);
 }
 
-// CHECK: test_vqaddq_s64
+// CHECK-LABEL: test_vqaddq_s64
 // CHECK: vqadd.s64 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int64x2_t test_vqaddq_s64(int64x2_t a, int64x2_t b) {
   return vqaddq_s64(a, b);
 }
 
-// CHECK: test_vqaddq_u8
+// CHECK-LABEL: test_vqaddq_u8
 // CHECK: vqadd.u8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vqaddq_u8(uint8x16_t a, uint8x16_t b) {
   return vqaddq_u8(a, b);
 }
 
-// CHECK: test_vqaddq_u16
+// CHECK-LABEL: test_vqaddq_u16
 // CHECK: vqadd.u16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vqaddq_u16(uint16x8_t a, uint16x8_t b) {
   return vqaddq_u16(a, b);
 }
 
-// CHECK: test_vqaddq_u32
+// CHECK-LABEL: test_vqaddq_u32
 // CHECK: vqadd.u32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vqaddq_u32(uint32x4_t a, uint32x4_t b) {
   return vqaddq_u32(a, b);
 }
 
-// CHECK: test_vqaddq_u64
+// CHECK-LABEL: test_vqaddq_u64
 // CHECK: vqadd.u64 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint64x2_t test_vqaddq_u64(uint64x2_t a, uint64x2_t b) {
   return vqaddq_u64(a, b);
 }
 
 
-// CHECK: test_vqdmlal_s16
+// CHECK-LABEL: test_vqdmlal_s16
 // CHECK: vqdmlal.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vqdmlal_s16(int32x4_t a, int16x4_t b, int16x4_t c) {
   return vqdmlal_s16(a, b, c);
 }
 
-// CHECK: test_vqdmlal_s32
+// CHECK-LABEL: test_vqdmlal_s32
 // CHECK: vqdmlal.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vqdmlal_s32(int64x2_t a, int32x2_t b, int32x2_t c) {
   return vqdmlal_s32(a, b, c);
 }
 
 
-// CHECK: test_vqdmlal_lane_s16
+// CHECK-LABEL: test_vqdmlal_lane_s16
 // CHECK: vqdmlal.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int32x4_t test_vqdmlal_lane_s16(int32x4_t a, int16x4_t b, int16x4_t c) {
   return vqdmlal_lane_s16(a, b, c, 3);
 }
 
-// CHECK: test_vqdmlal_lane_s32
+// CHECK-LABEL: test_vqdmlal_lane_s32
 // CHECK: vqdmlal.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int64x2_t test_vqdmlal_lane_s32(int64x2_t a, int32x2_t b, int32x2_t c) {
   return vqdmlal_lane_s32(a, b, c, 1);
 }
 
 
-// CHECK: test_vqdmlal_n_s16
+// CHECK-LABEL: test_vqdmlal_n_s16
 // CHECK: vqdmlal.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vqdmlal_n_s16(int32x4_t a, int16x4_t b, int16_t c) {
   return vqdmlal_n_s16(a, b, c);
 }
 
-// CHECK: test_vqdmlal_n_s32
+// CHECK-LABEL: test_vqdmlal_n_s32
 // CHECK: vqdmlal.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vqdmlal_n_s32(int64x2_t a, int32x2_t b, int32_t c) {
   return vqdmlal_n_s32(a, b, c);
 }
 
 
-// CHECK: test_vqdmlsl_s16
+// CHECK-LABEL: test_vqdmlsl_s16
 // CHECK: vqdmlsl.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vqdmlsl_s16(int32x4_t a, int16x4_t b, int16x4_t c) {
   return vqdmlsl_s16(a, b, c);
 }
 
-// CHECK: test_vqdmlsl_s32
+// CHECK-LABEL: test_vqdmlsl_s32
 // CHECK: vqdmlsl.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vqdmlsl_s32(int64x2_t a, int32x2_t b, int32x2_t c) {
   return vqdmlsl_s32(a, b, c);
 }
 
 
-// CHECK: test_vqdmlsl_lane_s16
+// CHECK-LABEL: test_vqdmlsl_lane_s16
 // CHECK: vqdmlsl.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int32x4_t test_vqdmlsl_lane_s16(int32x4_t a, int16x4_t b, int16x4_t c) {
   return vqdmlsl_lane_s16(a, b, c, 3);
 }
 
-// CHECK: test_vqdmlsl_lane_s32
+// CHECK-LABEL: test_vqdmlsl_lane_s32
 // CHECK: vqdmlsl.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int64x2_t test_vqdmlsl_lane_s32(int64x2_t a, int32x2_t b, int32x2_t c) {
   return vqdmlsl_lane_s32(a, b, c, 1);
 }
 
 
-// CHECK: test_vqdmlsl_n_s16
+// CHECK-LABEL: test_vqdmlsl_n_s16
 // CHECK: vqdmlsl.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vqdmlsl_n_s16(int32x4_t a, int16x4_t b, int16_t c) {
   return vqdmlsl_n_s16(a, b, c);
 }
 
-// CHECK: test_vqdmlsl_n_s32
+// CHECK-LABEL: test_vqdmlsl_n_s32
 // CHECK: vqdmlsl.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vqdmlsl_n_s32(int64x2_t a, int32x2_t b, int32_t c) {
   return vqdmlsl_n_s32(a, b, c);
 }
 
 
-// CHECK: test_vqdmulh_s16
+// CHECK-LABEL: test_vqdmulh_s16
 // CHECK: vqdmulh.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vqdmulh_s16(int16x4_t a, int16x4_t b) {
   return vqdmulh_s16(a, b);
 }
 
-// CHECK: test_vqdmulh_s32
+// CHECK-LABEL: test_vqdmulh_s32
 // CHECK: vqdmulh.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vqdmulh_s32(int32x2_t a, int32x2_t b) {
   return vqdmulh_s32(a, b);
 }
 
-// CHECK: test_vqdmulhq_s16
+// CHECK-LABEL: test_vqdmulhq_s16
 // CHECK: vqdmulh.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vqdmulhq_s16(int16x8_t a, int16x8_t b) {
   return vqdmulhq_s16(a, b);
 }
 
-// CHECK: test_vqdmulhq_s32
+// CHECK-LABEL: test_vqdmulhq_s32
 // CHECK: vqdmulh.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vqdmulhq_s32(int32x4_t a, int32x4_t b) {
   return vqdmulhq_s32(a, b);
 }
 
 
-// CHECK: test_vqdmulh_lane_s16
+// CHECK-LABEL: test_vqdmulh_lane_s16
 // CHECK: vqdmulh.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int16x4_t test_vqdmulh_lane_s16(int16x4_t a, int16x4_t b) {
   return vqdmulh_lane_s16(a, b, 3);
 }
 
-// CHECK: test_vqdmulh_lane_s32
+// CHECK-LABEL: test_vqdmulh_lane_s32
 // CHECK: vqdmulh.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int32x2_t test_vqdmulh_lane_s32(int32x2_t a, int32x2_t b) {
   return vqdmulh_lane_s32(a, b, 1);
 }
 
-// CHECK: test_vqdmulhq_lane_s16
+// CHECK-LABEL: test_vqdmulhq_lane_s16
 // CHECK: vqdmulh.s16 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int16x8_t test_vqdmulhq_lane_s16(int16x8_t a, int16x4_t b) {
   return vqdmulhq_lane_s16(a, b, 3);
 }
 
-// CHECK: test_vqdmulhq_lane_s32
+// CHECK-LABEL: test_vqdmulhq_lane_s32
 // CHECK: vqdmulh.s32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int32x4_t test_vqdmulhq_lane_s32(int32x4_t a, int32x2_t b) {
   return vqdmulhq_lane_s32(a, b, 1);
 }
 
 
-// CHECK: test_vqdmulh_n_s16
+// CHECK-LABEL: test_vqdmulh_n_s16
 // CHECK: vqdmulh.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vqdmulh_n_s16(int16x4_t a, int16_t b) {
   return vqdmulh_n_s16(a, b);
 }
 
-// CHECK: test_vqdmulh_n_s32
+// CHECK-LABEL: test_vqdmulh_n_s32
 // CHECK: vqdmulh.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vqdmulh_n_s32(int32x2_t a, int32_t b) {
   return vqdmulh_n_s32(a, b);
 }
 
-// CHECK: test_vqdmulhq_n_s16
+// CHECK-LABEL: test_vqdmulhq_n_s16
 // CHECK: vqdmulh.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vqdmulhq_n_s16(int16x8_t a, int16_t b) {
   return vqdmulhq_n_s16(a, b);
 }
 
-// CHECK: test_vqdmulhq_n_s32
+// CHECK-LABEL: test_vqdmulhq_n_s32
 // CHECK: vqdmulh.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vqdmulhq_n_s32(int32x4_t a, int32_t b) {
   return vqdmulhq_n_s32(a, b);
 }
 
 
-// CHECK: test_vqdmull_s16
+// CHECK-LABEL: test_vqdmull_s16
 // CHECK: vqdmull.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vqdmull_s16(int16x4_t a, int16x4_t b) {
   return vqdmull_s16(a, b);
 }
 
-// CHECK: test_vqdmull_s32
+// CHECK-LABEL: test_vqdmull_s32
 // CHECK: vqdmull.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vqdmull_s32(int32x2_t a, int32x2_t b) {
   return vqdmull_s32(a, b);
 }
 
 
-// CHECK: test_vqdmull_lane_s16
+// CHECK-LABEL: test_vqdmull_lane_s16
 // CHECK: vqdmull.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int32x4_t test_vqdmull_lane_s16(int16x4_t a, int16x4_t b) {
   return vqdmull_lane_s16(a, b, 3);
 }
 
-// CHECK: test_vqdmull_lane_s32
+// CHECK-LABEL: test_vqdmull_lane_s32
 // CHECK: vqdmull.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int64x2_t test_vqdmull_lane_s32(int32x2_t a, int32x2_t b) {
   return vqdmull_lane_s32(a, b, 1);
 }
 
 
-// CHECK: test_vqdmull_n_s16
+// CHECK-LABEL: test_vqdmull_n_s16
 // CHECK: vqdmull.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vqdmull_n_s16(int16x4_t a, int16_t b) {
   return vqdmull_n_s16(a, b);
 }
 
-// CHECK: test_vqdmull_n_s32
+// CHECK-LABEL: test_vqdmull_n_s32
 // CHECK: vqdmull.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vqdmull_n_s32(int32x2_t a, int32_t b) {
   return vqdmull_n_s32(a, b);
 }
 
 
-// CHECK: test_vqmovn_s16
+// CHECK-LABEL: test_vqmovn_s16
 // CHECK: vqmovn.s16 d{{[0-9]+}}, q{{[0-9]+}}
 int8x8_t test_vqmovn_s16(int16x8_t a) {
   return vqmovn_s16(a);
 }
 
-// CHECK: test_vqmovn_s32
+// CHECK-LABEL: test_vqmovn_s32
 // CHECK: vqmovn.s32 d{{[0-9]+}}, q{{[0-9]+}}
 int16x4_t test_vqmovn_s32(int32x4_t a) {
   return vqmovn_s32(a);
 }
 
-// CHECK: test_vqmovn_s64
+// CHECK-LABEL: test_vqmovn_s64
 // CHECK: vqmovn.s64 d{{[0-9]+}}, q{{[0-9]+}}
 int32x2_t test_vqmovn_s64(int64x2_t a) {
   return vqmovn_s64(a);
 }
 
-// CHECK: test_vqmovn_u16
+// CHECK-LABEL: test_vqmovn_u16
 // CHECK: vqmovn.u16 d{{[0-9]+}}, q{{[0-9]+}}
 uint8x8_t test_vqmovn_u16(uint16x8_t a) {
   return vqmovn_u16(a);
 }
 
-// CHECK: test_vqmovn_u32
+// CHECK-LABEL: test_vqmovn_u32
 // CHECK: vqmovn.u32 d{{[0-9]+}}, q{{[0-9]+}}
 uint16x4_t test_vqmovn_u32(uint32x4_t a) {
   return vqmovn_u32(a);
 }
 
-// CHECK: test_vqmovn_u64
+// CHECK-LABEL: test_vqmovn_u64
 // CHECK: vqmovn.u64 d{{[0-9]+}}, q{{[0-9]+}}
 uint32x2_t test_vqmovn_u64(uint64x2_t a) {
   return vqmovn_u64(a);
 }
 
 
-// CHECK: test_vqmovun_s16
+// CHECK-LABEL: test_vqmovun_s16
 // CHECK: vqmovun.s16 d{{[0-9]+}}, q{{[0-9]+}}
 uint8x8_t test_vqmovun_s16(int16x8_t a) {
   return vqmovun_s16(a);
 }
 
-// CHECK: test_vqmovun_s32
+// CHECK-LABEL: test_vqmovun_s32
 // CHECK: vqmovun.s32 d{{[0-9]+}}, q{{[0-9]+}}
 uint16x4_t test_vqmovun_s32(int32x4_t a) {
   return vqmovun_s32(a);
 }
 
-// CHECK: test_vqmovun_s64
+// CHECK-LABEL: test_vqmovun_s64
 // CHECK: vqmovun.s64 d{{[0-9]+}}, q{{[0-9]+}}
 uint32x2_t test_vqmovun_s64(int64x2_t a) {
   return vqmovun_s64(a);
 }
 
 
-// CHECK: test_vqneg_s8
+// CHECK-LABEL: test_vqneg_s8
 // CHECK: vqneg.s8 d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vqneg_s8(int8x8_t a) {
   return vqneg_s8(a);
 }
 
-// CHECK: test_vqneg_s16
+// CHECK-LABEL: test_vqneg_s16
 // CHECK: vqneg.s16 d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vqneg_s16(int16x4_t a) {
   return vqneg_s16(a);
 }
 
-// CHECK: test_vqneg_s32
+// CHECK-LABEL: test_vqneg_s32
 // CHECK: vqneg.s32 d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vqneg_s32(int32x2_t a) {
   return vqneg_s32(a);
 }
 
-// CHECK: test_vqnegq_s8
+// CHECK-LABEL: test_vqnegq_s8
 // CHECK: vqneg.s8 q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vqnegq_s8(int8x16_t a) {
   return vqnegq_s8(a);
 }
 
-// CHECK: test_vqnegq_s16
+// CHECK-LABEL: test_vqnegq_s16
 // CHECK: vqneg.s16 q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vqnegq_s16(int16x8_t a) {
   return vqnegq_s16(a);
 }
 
-// CHECK: test_vqnegq_s32
+// CHECK-LABEL: test_vqnegq_s32
 // CHECK: vqneg.s32 q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vqnegq_s32(int32x4_t a) {
   return vqnegq_s32(a);
 }
 
 
-// CHECK: test_vqrdmulh_s16
+// CHECK-LABEL: test_vqrdmulh_s16
 // CHECK: vqrdmulh.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vqrdmulh_s16(int16x4_t a, int16x4_t b) {
   return vqrdmulh_s16(a, b);
 }
 
-// CHECK: test_vqrdmulh_s32
+// CHECK-LABEL: test_vqrdmulh_s32
 // CHECK: vqrdmulh.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vqrdmulh_s32(int32x2_t a, int32x2_t b) {
   return vqrdmulh_s32(a, b);
 }
 
-// CHECK: test_vqrdmulhq_s16
+// CHECK-LABEL: test_vqrdmulhq_s16
 // CHECK: vqrdmulh.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vqrdmulhq_s16(int16x8_t a, int16x8_t b) {
   return vqrdmulhq_s16(a, b);
 }
 
-// CHECK: test_vqrdmulhq_s32
+// CHECK-LABEL: test_vqrdmulhq_s32
 // CHECK: vqrdmulh.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vqrdmulhq_s32(int32x4_t a, int32x4_t b) {
   return vqrdmulhq_s32(a, b);
 }
 
 
-// CHECK: test_vqrdmulh_lane_s16
+// CHECK-LABEL: test_vqrdmulh_lane_s16
 // CHECK: vqrdmulh.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int16x4_t test_vqrdmulh_lane_s16(int16x4_t a, int16x4_t b) {
   return vqrdmulh_lane_s16(a, b, 3);
 }
 
-// CHECK: test_vqrdmulh_lane_s32
+// CHECK-LABEL: test_vqrdmulh_lane_s32
 // CHECK: vqrdmulh.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int32x2_t test_vqrdmulh_lane_s32(int32x2_t a, int32x2_t b) {
   return vqrdmulh_lane_s32(a, b, 1);
 }
 
-// CHECK: test_vqrdmulhq_lane_s16
+// CHECK-LABEL: test_vqrdmulhq_lane_s16
 // CHECK: vqrdmulh.s16 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int16x8_t test_vqrdmulhq_lane_s16(int16x8_t a, int16x4_t b) {
   return vqrdmulhq_lane_s16(a, b, 3);
 }
 
-// CHECK: test_vqrdmulhq_lane_s32
+// CHECK-LABEL: test_vqrdmulhq_lane_s32
 // CHECK: vqrdmulh.s32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}[{{[0-9]}}]
 int32x4_t test_vqrdmulhq_lane_s32(int32x4_t a, int32x2_t b) {
   return vqrdmulhq_lane_s32(a, b, 1);
 }
 
 
-// CHECK: test_vqrdmulh_n_s16
+// CHECK-LABEL: test_vqrdmulh_n_s16
 // CHECK: vqrdmulh.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vqrdmulh_n_s16(int16x4_t a, int16_t b) {
   return vqrdmulh_n_s16(a, b);
 }
 
-// CHECK: test_vqrdmulh_n_s32
+// CHECK-LABEL: test_vqrdmulh_n_s32
 // CHECK: vqrdmulh.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vqrdmulh_n_s32(int32x2_t a, int32_t b) {
   return vqrdmulh_n_s32(a, b);
 }
 
-// CHECK: test_vqrdmulhq_n_s16
+// CHECK-LABEL: test_vqrdmulhq_n_s16
 // CHECK: vqrdmulh.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vqrdmulhq_n_s16(int16x8_t a, int16_t b) {
   return vqrdmulhq_n_s16(a, b);
 }
 
-// CHECK: test_vqrdmulhq_n_s32
+// CHECK-LABEL: test_vqrdmulhq_n_s32
 // CHECK: vqrdmulh.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vqrdmulhq_n_s32(int32x4_t a, int32_t b) {
   return vqrdmulhq_n_s32(a, b);
 }
 
 
-// CHECK: test_vqrshl_s8
+// CHECK-LABEL: test_vqrshl_s8
 // CHECK: vqrshl.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vqrshl_s8(int8x8_t a, int8x8_t b) {
   return vqrshl_s8(a, b);
 }
 
-// CHECK: test_vqrshl_s16
+// CHECK-LABEL: test_vqrshl_s16
 // CHECK: vqrshl.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vqrshl_s16(int16x4_t a, int16x4_t b) {
   return vqrshl_s16(a, b);
 }
 
-// CHECK: test_vqrshl_s32
+// CHECK-LABEL: test_vqrshl_s32
 // CHECK: vqrshl.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vqrshl_s32(int32x2_t a, int32x2_t b) {
   return vqrshl_s32(a, b);
 }
 
-// CHECK: test_vqrshl_s64
+// CHECK-LABEL: test_vqrshl_s64
 // CHECK: vqrshl.s64 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x1_t test_vqrshl_s64(int64x1_t a, int64x1_t b) {
   return vqrshl_s64(a, b);
 }
 
-// CHECK: test_vqrshl_u8
+// CHECK-LABEL: test_vqrshl_u8
 // CHECK: vqrshl.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vqrshl_u8(uint8x8_t a, int8x8_t b) {
   return vqrshl_u8(a, b);
 }
 
-// CHECK: test_vqrshl_u16
+// CHECK-LABEL: test_vqrshl_u16
 // CHECK: vqrshl.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vqrshl_u16(uint16x4_t a, int16x4_t b) {
   return vqrshl_u16(a, b);
 }
 
-// CHECK: test_vqrshl_u32
+// CHECK-LABEL: test_vqrshl_u32
 // CHECK: vqrshl.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vqrshl_u32(uint32x2_t a, int32x2_t b) {
   return vqrshl_u32(a, b);
 }
 
-// CHECK: test_vqrshl_u64
+// CHECK-LABEL: test_vqrshl_u64
 // CHECK: vqrshl.u64 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x1_t test_vqrshl_u64(uint64x1_t a, int64x1_t b) {
   return vqrshl_u64(a, b);
 }
 
-// CHECK: test_vqrshlq_s8
+// CHECK-LABEL: test_vqrshlq_s8
 // CHECK: vqrshl.s8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vqrshlq_s8(int8x16_t a, int8x16_t b) {
   return vqrshlq_s8(a, b);
 }
 
-// CHECK: test_vqrshlq_s16
+// CHECK-LABEL: test_vqrshlq_s16
 // CHECK: vqrshl.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vqrshlq_s16(int16x8_t a, int16x8_t b) {
   return vqrshlq_s16(a, b);
 }
 
-// CHECK: test_vqrshlq_s32
+// CHECK-LABEL: test_vqrshlq_s32
 // CHECK: vqrshl.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vqrshlq_s32(int32x4_t a, int32x4_t b) {
   return vqrshlq_s32(a, b);
 }
 
-// CHECK: test_vqrshlq_s64
+// CHECK-LABEL: test_vqrshlq_s64
 // CHECK: vqrshl.s64 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int64x2_t test_vqrshlq_s64(int64x2_t a, int64x2_t b) {
   return vqrshlq_s64(a, b);
 }
 
-// CHECK: test_vqrshlq_u8
+// CHECK-LABEL: test_vqrshlq_u8
 // CHECK: vqrshl.u8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vqrshlq_u8(uint8x16_t a, int8x16_t b) {
   return vqrshlq_u8(a, b);
 }
 
-// CHECK: test_vqrshlq_u16
+// CHECK-LABEL: test_vqrshlq_u16
 // CHECK: vqrshl.u16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vqrshlq_u16(uint16x8_t a, int16x8_t b) {
   return vqrshlq_u16(a, b);
 }
 
-// CHECK: test_vqrshlq_u32
+// CHECK-LABEL: test_vqrshlq_u32
 // CHECK: vqrshl.u32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vqrshlq_u32(uint32x4_t a, int32x4_t b) {
   return vqrshlq_u32(a, b);
 }
 
-// CHECK: test_vqrshlq_u64
+// CHECK-LABEL: test_vqrshlq_u64
 // CHECK: vqrshl.u64 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint64x2_t test_vqrshlq_u64(uint64x2_t a, int64x2_t b) {
   return vqrshlq_u64(a, b);
 }
 
 
-// CHECK: test_vqrshrn_n_s16
+// CHECK-LABEL: test_vqrshrn_n_s16
 // CHECK: vqrshrn.s16 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int8x8_t test_vqrshrn_n_s16(int16x8_t a) {
   return vqrshrn_n_s16(a, 1);
 }
 
-// CHECK: test_vqrshrn_n_s32
+// CHECK-LABEL: test_vqrshrn_n_s32
 // CHECK: vqrshrn.s32 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int16x4_t test_vqrshrn_n_s32(int32x4_t a) {
   return vqrshrn_n_s32(a, 1);
 }
 
-// CHECK: test_vqrshrn_n_s64
+// CHECK-LABEL: test_vqrshrn_n_s64
 // CHECK: vqrshrn.s64 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int32x2_t test_vqrshrn_n_s64(int64x2_t a) {
   return vqrshrn_n_s64(a, 1);
 }
 
-// CHECK: test_vqrshrn_n_u16
+// CHECK-LABEL: test_vqrshrn_n_u16
 // CHECK: vqrshrn.u16 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint8x8_t test_vqrshrn_n_u16(uint16x8_t a) {
   return vqrshrn_n_u16(a, 1);
 }
 
-// CHECK: test_vqrshrn_n_u32
+// CHECK-LABEL: test_vqrshrn_n_u32
 // CHECK: vqrshrn.u32 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint16x4_t test_vqrshrn_n_u32(uint32x4_t a) {
   return vqrshrn_n_u32(a, 1);
 }
 
-// CHECK: test_vqrshrn_n_u64
+// CHECK-LABEL: test_vqrshrn_n_u64
 // CHECK: vqrshrn.u64 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint32x2_t test_vqrshrn_n_u64(uint64x2_t a) {
   return vqrshrn_n_u64(a, 1);
 }
 
 
-// CHECK: test_vqrshrun_n_s16
+// CHECK-LABEL: test_vqrshrun_n_s16
 // CHECK: vqrshrun.s16 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint8x8_t test_vqrshrun_n_s16(int16x8_t a) {
   return vqrshrun_n_s16(a, 1);
 }
 
-// CHECK: test_vqrshrun_n_s32
+// CHECK-LABEL: test_vqrshrun_n_s32
 // CHECK: vqrshrun.s32 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint16x4_t test_vqrshrun_n_s32(int32x4_t a) {
   return vqrshrun_n_s32(a, 1);
 }
 
-// CHECK: test_vqrshrun_n_s64
+// CHECK-LABEL: test_vqrshrun_n_s64
 // CHECK: vqrshrun.s64 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint32x2_t test_vqrshrun_n_s64(int64x2_t a) {
   return vqrshrun_n_s64(a, 1);
 }
 
 
-// CHECK: test_vqshl_s8
+// CHECK-LABEL: test_vqshl_s8
 // CHECK: vqshl.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vqshl_s8(int8x8_t a, int8x8_t b) {
   return vqshl_s8(a, b);
 }
 
-// CHECK: test_vqshl_s16
+// CHECK-LABEL: test_vqshl_s16
 // CHECK: vqshl.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vqshl_s16(int16x4_t a, int16x4_t b) {
   return vqshl_s16(a, b);
 }
 
-// CHECK: test_vqshl_s32
+// CHECK-LABEL: test_vqshl_s32
 // CHECK: vqshl.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vqshl_s32(int32x2_t a, int32x2_t b) {
   return vqshl_s32(a, b);
 }
 
-// CHECK: test_vqshl_s64
+// CHECK-LABEL: test_vqshl_s64
 // CHECK: vqshl.s64 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x1_t test_vqshl_s64(int64x1_t a, int64x1_t b) {
   return vqshl_s64(a, b);
 }
 
-// CHECK: test_vqshl_u8
+// CHECK-LABEL: test_vqshl_u8
 // CHECK: vqshl.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vqshl_u8(uint8x8_t a, int8x8_t b) {
   return vqshl_u8(a, b);
 }
 
-// CHECK: test_vqshl_u16
+// CHECK-LABEL: test_vqshl_u16
 // CHECK: vqshl.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vqshl_u16(uint16x4_t a, int16x4_t b) {
   return vqshl_u16(a, b);
 }
 
-// CHECK: test_vqshl_u32
+// CHECK-LABEL: test_vqshl_u32
 // CHECK: vqshl.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vqshl_u32(uint32x2_t a, int32x2_t b) {
   return vqshl_u32(a, b);
 }
 
-// CHECK: test_vqshl_u64
+// CHECK-LABEL: test_vqshl_u64
 // CHECK: vqshl.u64 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x1_t test_vqshl_u64(uint64x1_t a, int64x1_t b) {
   return vqshl_u64(a, b);
 }
 
-// CHECK: test_vqshlq_s8
+// CHECK-LABEL: test_vqshlq_s8
 // CHECK: vqshl.s8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vqshlq_s8(int8x16_t a, int8x16_t b) {
   return vqshlq_s8(a, b);
 }
 
-// CHECK: test_vqshlq_s16
+// CHECK-LABEL: test_vqshlq_s16
 // CHECK: vqshl.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vqshlq_s16(int16x8_t a, int16x8_t b) {
   return vqshlq_s16(a, b);
 }
 
-// CHECK: test_vqshlq_s32
+// CHECK-LABEL: test_vqshlq_s32
 // CHECK: vqshl.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vqshlq_s32(int32x4_t a, int32x4_t b) {
   return vqshlq_s32(a, b);
 }
 
-// CHECK: test_vqshlq_s64
+// CHECK-LABEL: test_vqshlq_s64
 // CHECK: vqshl.s64 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int64x2_t test_vqshlq_s64(int64x2_t a, int64x2_t b) {
   return vqshlq_s64(a, b);
 }
 
-// CHECK: test_vqshlq_u8
+// CHECK-LABEL: test_vqshlq_u8
 // CHECK: vqshl.u8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vqshlq_u8(uint8x16_t a, int8x16_t b) {
   return vqshlq_u8(a, b);
 }
 
-// CHECK: test_vqshlq_u16
+// CHECK-LABEL: test_vqshlq_u16
 // CHECK: vqshl.u16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vqshlq_u16(uint16x8_t a, int16x8_t b) {
   return vqshlq_u16(a, b);
 }
 
-// CHECK: test_vqshlq_u32
+// CHECK-LABEL: test_vqshlq_u32
 // CHECK: vqshl.u32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vqshlq_u32(uint32x4_t a, int32x4_t b) {
   return vqshlq_u32(a, b);
 }
 
-// CHECK: test_vqshlq_u64
+// CHECK-LABEL: test_vqshlq_u64
 // CHECK: vqshl.u64 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint64x2_t test_vqshlq_u64(uint64x2_t a, int64x2_t b) {
   return vqshlq_u64(a, b);
 }
 
 
-// CHECK: test_vqshlu_n_s8
+// CHECK-LABEL: test_vqshlu_n_s8
 // CHECK: vqshlu.s8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint8x8_t test_vqshlu_n_s8(int8x8_t a) {
   return vqshlu_n_s8(a, 1);
 }
 
-// CHECK: test_vqshlu_n_s16
+// CHECK-LABEL: test_vqshlu_n_s16
 // CHECK: vqshlu.s16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint16x4_t test_vqshlu_n_s16(int16x4_t a) {
   return vqshlu_n_s16(a, 1);
 }
 
-// CHECK: test_vqshlu_n_s32
+// CHECK-LABEL: test_vqshlu_n_s32
 // CHECK: vqshlu.s32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint32x2_t test_vqshlu_n_s32(int32x2_t a) {
   return vqshlu_n_s32(a, 1);
 }
 
-// CHECK: test_vqshlu_n_s64
+// CHECK-LABEL: test_vqshlu_n_s64
 // CHECK: vqshlu.s64 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint64x1_t test_vqshlu_n_s64(int64x1_t a) {
   return vqshlu_n_s64(a, 1);
 }
 
-// CHECK: test_vqshluq_n_s8
+// CHECK-LABEL: test_vqshluq_n_s8
 // CHECK: vqshlu.s8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint8x16_t test_vqshluq_n_s8(int8x16_t a) {
   return vqshluq_n_s8(a, 1);
 }
 
-// CHECK: test_vqshluq_n_s16
+// CHECK-LABEL: test_vqshluq_n_s16
 // CHECK: vqshlu.s16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint16x8_t test_vqshluq_n_s16(int16x8_t a) {
   return vqshluq_n_s16(a, 1);
 }
 
-// CHECK: test_vqshluq_n_s32
+// CHECK-LABEL: test_vqshluq_n_s32
 // CHECK: vqshlu.s32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint32x4_t test_vqshluq_n_s32(int32x4_t a) {
   return vqshluq_n_s32(a, 1);
 }
 
-// CHECK: test_vqshluq_n_s64
+// CHECK-LABEL: test_vqshluq_n_s64
 // CHECK: vqshlu.s64 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint64x2_t test_vqshluq_n_s64(int64x2_t a) {
   return vqshluq_n_s64(a, 1);
 }
 
 
-// CHECK: test_vqshl_n_s8
+// CHECK-LABEL: test_vqshl_n_s8
 // CHECK: vqshl.s8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int8x8_t test_vqshl_n_s8(int8x8_t a) {
   return vqshl_n_s8(a, 1);
 }
 
-// CHECK: test_vqshl_n_s16
+// CHECK-LABEL: test_vqshl_n_s16
 // CHECK: vqshl.s16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int16x4_t test_vqshl_n_s16(int16x4_t a) {
   return vqshl_n_s16(a, 1);
 }
 
-// CHECK: test_vqshl_n_s32
+// CHECK-LABEL: test_vqshl_n_s32
 // CHECK: vqshl.s32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int32x2_t test_vqshl_n_s32(int32x2_t a) {
   return vqshl_n_s32(a, 1);
 }
 
-// CHECK: test_vqshl_n_s64
+// CHECK-LABEL: test_vqshl_n_s64
 // CHECK: vqshl.s64 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int64x1_t test_vqshl_n_s64(int64x1_t a) {
   return vqshl_n_s64(a, 1);
 }
 
-// CHECK: test_vqshl_n_u8
+// CHECK-LABEL: test_vqshl_n_u8
 // CHECK: vqshl.u8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint8x8_t test_vqshl_n_u8(uint8x8_t a) {
   return vqshl_n_u8(a, 1);
 }
 
-// CHECK: test_vqshl_n_u16
+// CHECK-LABEL: test_vqshl_n_u16
 // CHECK: vqshl.u16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint16x4_t test_vqshl_n_u16(uint16x4_t a) {
   return vqshl_n_u16(a, 1);
 }
 
-// CHECK: test_vqshl_n_u32
+// CHECK-LABEL: test_vqshl_n_u32
 // CHECK: vqshl.u32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint32x2_t test_vqshl_n_u32(uint32x2_t a) {
   return vqshl_n_u32(a, 1);
 }
 
-// CHECK: test_vqshl_n_u64
+// CHECK-LABEL: test_vqshl_n_u64
 // CHECK: vqshl.u64 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint64x1_t test_vqshl_n_u64(uint64x1_t a) {
   return vqshl_n_u64(a, 1);
 }
 
-// CHECK: test_vqshlq_n_s8
+// CHECK-LABEL: test_vqshlq_n_s8
 // CHECK: vqshl.s8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int8x16_t test_vqshlq_n_s8(int8x16_t a) {
   return vqshlq_n_s8(a, 1);
 }
 
-// CHECK: test_vqshlq_n_s16
+// CHECK-LABEL: test_vqshlq_n_s16
 // CHECK: vqshl.s16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int16x8_t test_vqshlq_n_s16(int16x8_t a) {
   return vqshlq_n_s16(a, 1);
 }
 
-// CHECK: test_vqshlq_n_s32
+// CHECK-LABEL: test_vqshlq_n_s32
 // CHECK: vqshl.s32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int32x4_t test_vqshlq_n_s32(int32x4_t a) {
   return vqshlq_n_s32(a, 1);
 }
 
-// CHECK: test_vqshlq_n_s64
+// CHECK-LABEL: test_vqshlq_n_s64
 // CHECK: vqshl.s64 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int64x2_t test_vqshlq_n_s64(int64x2_t a) {
   return vqshlq_n_s64(a, 1);
 }
 
-// CHECK: test_vqshlq_n_u8
+// CHECK-LABEL: test_vqshlq_n_u8
 // CHECK: vqshl.u8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint8x16_t test_vqshlq_n_u8(uint8x16_t a) {
   return vqshlq_n_u8(a, 1);
 }
 
-// CHECK: test_vqshlq_n_u16
+// CHECK-LABEL: test_vqshlq_n_u16
 // CHECK: vqshl.u16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint16x8_t test_vqshlq_n_u16(uint16x8_t a) {
   return vqshlq_n_u16(a, 1);
 }
 
-// CHECK: test_vqshlq_n_u32
+// CHECK-LABEL: test_vqshlq_n_u32
 // CHECK: vqshl.u32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint32x4_t test_vqshlq_n_u32(uint32x4_t a) {
   return vqshlq_n_u32(a, 1);
 }
 
-// CHECK: test_vqshlq_n_u64
+// CHECK-LABEL: test_vqshlq_n_u64
 // CHECK: vqshl.u64 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint64x2_t test_vqshlq_n_u64(uint64x2_t a) {
   return vqshlq_n_u64(a, 1);
 }
 
 
-// CHECK: test_vqshrn_n_s16
+// CHECK-LABEL: test_vqshrn_n_s16
 // CHECK: vqshrn.s16 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int8x8_t test_vqshrn_n_s16(int16x8_t a) {
   return vqshrn_n_s16(a, 1);
 }
 
-// CHECK: test_vqshrn_n_s32
+// CHECK-LABEL: test_vqshrn_n_s32
 // CHECK: vqshrn.s32 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int16x4_t test_vqshrn_n_s32(int32x4_t a) {
   return vqshrn_n_s32(a, 1);
 }
 
-// CHECK: test_vqshrn_n_s64
+// CHECK-LABEL: test_vqshrn_n_s64
 // CHECK: vqshrn.s64 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int32x2_t test_vqshrn_n_s64(int64x2_t a) {
   return vqshrn_n_s64(a, 1);
 }
 
-// CHECK: test_vqshrn_n_u16
+// CHECK-LABEL: test_vqshrn_n_u16
 // CHECK: vqshrn.u16 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint8x8_t test_vqshrn_n_u16(uint16x8_t a) {
   return vqshrn_n_u16(a, 1);
 }
 
-// CHECK: test_vqshrn_n_u32
+// CHECK-LABEL: test_vqshrn_n_u32
 // CHECK: vqshrn.u32 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint16x4_t test_vqshrn_n_u32(uint32x4_t a) {
   return vqshrn_n_u32(a, 1);
 }
 
-// CHECK: test_vqshrn_n_u64
+// CHECK-LABEL: test_vqshrn_n_u64
 // CHECK: vqshrn.u64 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint32x2_t test_vqshrn_n_u64(uint64x2_t a) {
   return vqshrn_n_u64(a, 1);
 }
 
 
-// CHECK: test_vqshrun_n_s16
+// CHECK-LABEL: test_vqshrun_n_s16
 // CHECK: vqshrun.s16 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint8x8_t test_vqshrun_n_s16(int16x8_t a) {
   return vqshrun_n_s16(a, 1);
 }
 
-// CHECK: test_vqshrun_n_s32
+// CHECK-LABEL: test_vqshrun_n_s32
 // CHECK: vqshrun.s32 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint16x4_t test_vqshrun_n_s32(int32x4_t a) {
   return vqshrun_n_s32(a, 1);
 }
 
-// CHECK: test_vqshrun_n_s64
+// CHECK-LABEL: test_vqshrun_n_s64
 // CHECK: vqshrun.s64 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint32x2_t test_vqshrun_n_s64(int64x2_t a) {
   return vqshrun_n_s64(a, 1);
 }
 
 
-// CHECK: test_vqsub_s8
+// CHECK-LABEL: test_vqsub_s8
 // CHECK: vqsub.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vqsub_s8(int8x8_t a, int8x8_t b) {
   return vqsub_s8(a, b);
 }
 
-// CHECK: test_vqsub_s16
+// CHECK-LABEL: test_vqsub_s16
 // CHECK: vqsub.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vqsub_s16(int16x4_t a, int16x4_t b) {
   return vqsub_s16(a, b);
 }
 
-// CHECK: test_vqsub_s32
+// CHECK-LABEL: test_vqsub_s32
 // CHECK: vqsub.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vqsub_s32(int32x2_t a, int32x2_t b) {
   return vqsub_s32(a, b);
 }
 
-// CHECK: test_vqsub_s64
+// CHECK-LABEL: test_vqsub_s64
 // CHECK: vqsub.s64 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x1_t test_vqsub_s64(int64x1_t a, int64x1_t b) {
   return vqsub_s64(a, b);
 }
 
-// CHECK: test_vqsub_u8
+// CHECK-LABEL: test_vqsub_u8
 // CHECK: vqsub.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vqsub_u8(uint8x8_t a, uint8x8_t b) {
   return vqsub_u8(a, b);
 }
 
-// CHECK: test_vqsub_u16
+// CHECK-LABEL: test_vqsub_u16
 // CHECK: vqsub.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vqsub_u16(uint16x4_t a, uint16x4_t b) {
   return vqsub_u16(a, b);
 }
 
-// CHECK: test_vqsub_u32
+// CHECK-LABEL: test_vqsub_u32
 // CHECK: vqsub.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vqsub_u32(uint32x2_t a, uint32x2_t b) {
   return vqsub_u32(a, b);
 }
 
-// CHECK: test_vqsub_u64
+// CHECK-LABEL: test_vqsub_u64
 // CHECK: vqsub.u64 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x1_t test_vqsub_u64(uint64x1_t a, uint64x1_t b) {
   return vqsub_u64(a, b);
 }
 
-// CHECK: test_vqsubq_s8
+// CHECK-LABEL: test_vqsubq_s8
 // CHECK: vqsub.s8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vqsubq_s8(int8x16_t a, int8x16_t b) {
   return vqsubq_s8(a, b);
 }
 
-// CHECK: test_vqsubq_s16
+// CHECK-LABEL: test_vqsubq_s16
 // CHECK: vqsub.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vqsubq_s16(int16x8_t a, int16x8_t b) {
   return vqsubq_s16(a, b);
 }
 
-// CHECK: test_vqsubq_s32
+// CHECK-LABEL: test_vqsubq_s32
 // CHECK: vqsub.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vqsubq_s32(int32x4_t a, int32x4_t b) {
   return vqsubq_s32(a, b);
 }
 
-// CHECK: test_vqsubq_s64
+// CHECK-LABEL: test_vqsubq_s64
 // CHECK: vqsub.s64 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int64x2_t test_vqsubq_s64(int64x2_t a, int64x2_t b) {
   return vqsubq_s64(a, b);
 }
 
-// CHECK: test_vqsubq_u8
+// CHECK-LABEL: test_vqsubq_u8
 // CHECK: vqsub.u8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vqsubq_u8(uint8x16_t a, uint8x16_t b) {
   return vqsubq_u8(a, b);
 }
 
-// CHECK: test_vqsubq_u16
+// CHECK-LABEL: test_vqsubq_u16
 // CHECK: vqsub.u16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vqsubq_u16(uint16x8_t a, uint16x8_t b) {
   return vqsubq_u16(a, b);
 }
 
-// CHECK: test_vqsubq_u32
+// CHECK-LABEL: test_vqsubq_u32
 // CHECK: vqsub.u32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vqsubq_u32(uint32x4_t a, uint32x4_t b) {
   return vqsubq_u32(a, b);
 }
 
-// CHECK: test_vqsubq_u64
+// CHECK-LABEL: test_vqsubq_u64
 // CHECK: vqsub.u64 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint64x2_t test_vqsubq_u64(uint64x2_t a, uint64x2_t b) {
   return vqsubq_u64(a, b);
 }
 
 
-// CHECK: test_vraddhn_s16
+// CHECK-LABEL: test_vraddhn_s16
 // CHECK: vraddhn.i16 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x8_t test_vraddhn_s16(int16x8_t a, int16x8_t b) {
   return vraddhn_s16(a, b);
 }
 
-// CHECK: test_vraddhn_s32
+// CHECK-LABEL: test_vraddhn_s32
 // CHECK: vraddhn.i32 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x4_t test_vraddhn_s32(int32x4_t a, int32x4_t b) {
   return vraddhn_s32(a, b);
 }
 
-// CHECK: test_vraddhn_s64
+// CHECK-LABEL: test_vraddhn_s64
 // CHECK: vraddhn.i64 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x2_t test_vraddhn_s64(int64x2_t a, int64x2_t b) {
   return vraddhn_s64(a, b);
 }
 
-// CHECK: test_vraddhn_u16
+// CHECK-LABEL: test_vraddhn_u16
 // CHECK: vraddhn.i16 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x8_t test_vraddhn_u16(uint16x8_t a, uint16x8_t b) {
   return vraddhn_u16(a, b);
 }
 
-// CHECK: test_vraddhn_u32
+// CHECK-LABEL: test_vraddhn_u32
 // CHECK: vraddhn.i32 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x4_t test_vraddhn_u32(uint32x4_t a, uint32x4_t b) {
   return vraddhn_u32(a, b);
 }
 
-// CHECK: test_vraddhn_u64
+// CHECK-LABEL: test_vraddhn_u64
 // CHECK: vraddhn.i64 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x2_t test_vraddhn_u64(uint64x2_t a, uint64x2_t b) {
   return vraddhn_u64(a, b);
 }
 
 
-// CHECK: test_vrecpe_f32
+// CHECK-LABEL: test_vrecpe_f32
 // CHECK: vrecpe.f32 d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vrecpe_f32(float32x2_t a) {
   return vrecpe_f32(a);
 }
 
-// CHECK: test_vrecpe_u32
+// CHECK-LABEL: test_vrecpe_u32
 // CHECK: vrecpe.u32 d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vrecpe_u32(uint32x2_t a) {
   return vrecpe_u32(a);
 }
 
-// CHECK: test_vrecpeq_f32
+// CHECK-LABEL: test_vrecpeq_f32
 // CHECK: vrecpe.f32 q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vrecpeq_f32(float32x4_t a) {
   return vrecpeq_f32(a);
 }
 
-// CHECK: test_vrecpeq_u32
+// CHECK-LABEL: test_vrecpeq_u32
 // CHECK: vrecpe.u32 q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vrecpeq_u32(uint32x4_t a) {
   return vrecpeq_u32(a);
 }
 
 
-// CHECK: test_vrecps_f32
+// CHECK-LABEL: test_vrecps_f32
 // CHECK: vrecps.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vrecps_f32(float32x2_t a, float32x2_t b) {
   return vrecps_f32(a, b);
 }
 
-// CHECK: test_vrecpsq_f32
+// CHECK-LABEL: test_vrecpsq_f32
 // CHECK: vrecps.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vrecpsq_f32(float32x4_t a, float32x4_t b) {
   return vrecpsq_f32(a, b);
 }
 
 
-// CHECK: test_vreinterpret_s8_s16
+// CHECK-LABEL: test_vreinterpret_s8_s16
 int8x8_t test_vreinterpret_s8_s16(int16x4_t a) {
   return vreinterpret_s8_s16(a);
 }
 
-// CHECK: test_vreinterpret_s8_s32
+// CHECK-LABEL: test_vreinterpret_s8_s32
 int8x8_t test_vreinterpret_s8_s32(int32x2_t a) {
   return vreinterpret_s8_s32(a);
 }
 
-// CHECK: test_vreinterpret_s8_s64
+// CHECK-LABEL: test_vreinterpret_s8_s64
 int8x8_t test_vreinterpret_s8_s64(int64x1_t a) {
   return vreinterpret_s8_s64(a);
 }
 
-// CHECK: test_vreinterpret_s8_u8
+// CHECK-LABEL: test_vreinterpret_s8_u8
 int8x8_t test_vreinterpret_s8_u8(uint8x8_t a) {
   return vreinterpret_s8_u8(a);
 }
 
-// CHECK: test_vreinterpret_s8_u16
+// CHECK-LABEL: test_vreinterpret_s8_u16
 int8x8_t test_vreinterpret_s8_u16(uint16x4_t a) {
   return vreinterpret_s8_u16(a);
 }
 
-// CHECK: test_vreinterpret_s8_u32
+// CHECK-LABEL: test_vreinterpret_s8_u32
 int8x8_t test_vreinterpret_s8_u32(uint32x2_t a) {
   return vreinterpret_s8_u32(a);
 }
 
-// CHECK: test_vreinterpret_s8_u64
+// CHECK-LABEL: test_vreinterpret_s8_u64
 int8x8_t test_vreinterpret_s8_u64(uint64x1_t a) {
   return vreinterpret_s8_u64(a);
 }
 
-// CHECK: test_vreinterpret_s8_f16
+// CHECK-LABEL: test_vreinterpret_s8_f16
 int8x8_t test_vreinterpret_s8_f16(float16x4_t a) {
   return vreinterpret_s8_f16(a);
 }
 
-// CHECK: test_vreinterpret_s8_f32
+// CHECK-LABEL: test_vreinterpret_s8_f32
 int8x8_t test_vreinterpret_s8_f32(float32x2_t a) {
   return vreinterpret_s8_f32(a);
 }
 
-// CHECK: test_vreinterpret_s8_p8
+// CHECK-LABEL: test_vreinterpret_s8_p8
 int8x8_t test_vreinterpret_s8_p8(poly8x8_t a) {
   return vreinterpret_s8_p8(a);
 }
 
-// CHECK: test_vreinterpret_s8_p16
+// CHECK-LABEL: test_vreinterpret_s8_p16
 int8x8_t test_vreinterpret_s8_p16(poly16x4_t a) {
   return vreinterpret_s8_p16(a);
 }
 
-// CHECK: test_vreinterpret_s16_s8
+// CHECK-LABEL: test_vreinterpret_s16_s8
 int16x4_t test_vreinterpret_s16_s8(int8x8_t a) {
   return vreinterpret_s16_s8(a);
 }
 
-// CHECK: test_vreinterpret_s16_s32
+// CHECK-LABEL: test_vreinterpret_s16_s32
 int16x4_t test_vreinterpret_s16_s32(int32x2_t a) {
   return vreinterpret_s16_s32(a);
 }
 
-// CHECK: test_vreinterpret_s16_s64
+// CHECK-LABEL: test_vreinterpret_s16_s64
 int16x4_t test_vreinterpret_s16_s64(int64x1_t a) {
   return vreinterpret_s16_s64(a);
 }
 
-// CHECK: test_vreinterpret_s16_u8
+// CHECK-LABEL: test_vreinterpret_s16_u8
 int16x4_t test_vreinterpret_s16_u8(uint8x8_t a) {
   return vreinterpret_s16_u8(a);
 }
 
-// CHECK: test_vreinterpret_s16_u16
+// CHECK-LABEL: test_vreinterpret_s16_u16
 int16x4_t test_vreinterpret_s16_u16(uint16x4_t a) {
   return vreinterpret_s16_u16(a);
 }
 
-// CHECK: test_vreinterpret_s16_u32
+// CHECK-LABEL: test_vreinterpret_s16_u32
 int16x4_t test_vreinterpret_s16_u32(uint32x2_t a) {
   return vreinterpret_s16_u32(a);
 }
 
-// CHECK: test_vreinterpret_s16_u64
+// CHECK-LABEL: test_vreinterpret_s16_u64
 int16x4_t test_vreinterpret_s16_u64(uint64x1_t a) {
   return vreinterpret_s16_u64(a);
 }
 
-// CHECK: test_vreinterpret_s16_f16
+// CHECK-LABEL: test_vreinterpret_s16_f16
 int16x4_t test_vreinterpret_s16_f16(float16x4_t a) {
   return vreinterpret_s16_f16(a);
 }
 
-// CHECK: test_vreinterpret_s16_f32
+// CHECK-LABEL: test_vreinterpret_s16_f32
 int16x4_t test_vreinterpret_s16_f32(float32x2_t a) {
   return vreinterpret_s16_f32(a);
 }
 
-// CHECK: test_vreinterpret_s16_p8
+// CHECK-LABEL: test_vreinterpret_s16_p8
 int16x4_t test_vreinterpret_s16_p8(poly8x8_t a) {
   return vreinterpret_s16_p8(a);
 }
 
-// CHECK: test_vreinterpret_s16_p16
+// CHECK-LABEL: test_vreinterpret_s16_p16
 int16x4_t test_vreinterpret_s16_p16(poly16x4_t a) {
   return vreinterpret_s16_p16(a);
 }
 
-// CHECK: test_vreinterpret_s32_s8
+// CHECK-LABEL: test_vreinterpret_s32_s8
 int32x2_t test_vreinterpret_s32_s8(int8x8_t a) {
   return vreinterpret_s32_s8(a);
 }
 
-// CHECK: test_vreinterpret_s32_s16
+// CHECK-LABEL: test_vreinterpret_s32_s16
 int32x2_t test_vreinterpret_s32_s16(int16x4_t a) {
   return vreinterpret_s32_s16(a);
 }
 
-// CHECK: test_vreinterpret_s32_s64
+// CHECK-LABEL: test_vreinterpret_s32_s64
 int32x2_t test_vreinterpret_s32_s64(int64x1_t a) {
   return vreinterpret_s32_s64(a);
 }
 
-// CHECK: test_vreinterpret_s32_u8
+// CHECK-LABEL: test_vreinterpret_s32_u8
 int32x2_t test_vreinterpret_s32_u8(uint8x8_t a) {
   return vreinterpret_s32_u8(a);
 }
 
-// CHECK: test_vreinterpret_s32_u16
+// CHECK-LABEL: test_vreinterpret_s32_u16
 int32x2_t test_vreinterpret_s32_u16(uint16x4_t a) {
   return vreinterpret_s32_u16(a);
 }
 
-// CHECK: test_vreinterpret_s32_u32
+// CHECK-LABEL: test_vreinterpret_s32_u32
 int32x2_t test_vreinterpret_s32_u32(uint32x2_t a) {
   return vreinterpret_s32_u32(a);
 }
 
-// CHECK: test_vreinterpret_s32_u64
+// CHECK-LABEL: test_vreinterpret_s32_u64
 int32x2_t test_vreinterpret_s32_u64(uint64x1_t a) {
   return vreinterpret_s32_u64(a);
 }
 
-// CHECK: test_vreinterpret_s32_f16
+// CHECK-LABEL: test_vreinterpret_s32_f16
 int32x2_t test_vreinterpret_s32_f16(float16x4_t a) {
   return vreinterpret_s32_f16(a);
 }
 
-// CHECK: test_vreinterpret_s32_f32
+// CHECK-LABEL: test_vreinterpret_s32_f32
 int32x2_t test_vreinterpret_s32_f32(float32x2_t a) {
   return vreinterpret_s32_f32(a);
 }
 
-// CHECK: test_vreinterpret_s32_p8
+// CHECK-LABEL: test_vreinterpret_s32_p8
 int32x2_t test_vreinterpret_s32_p8(poly8x8_t a) {
   return vreinterpret_s32_p8(a);
 }
 
-// CHECK: test_vreinterpret_s32_p16
+// CHECK-LABEL: test_vreinterpret_s32_p16
 int32x2_t test_vreinterpret_s32_p16(poly16x4_t a) {
   return vreinterpret_s32_p16(a);
 }
 
-// CHECK: test_vreinterpret_s64_s8
+// CHECK-LABEL: test_vreinterpret_s64_s8
 int64x1_t test_vreinterpret_s64_s8(int8x8_t a) {
   return vreinterpret_s64_s8(a);
 }
 
-// CHECK: test_vreinterpret_s64_s16
+// CHECK-LABEL: test_vreinterpret_s64_s16
 int64x1_t test_vreinterpret_s64_s16(int16x4_t a) {
   return vreinterpret_s64_s16(a);
 }
 
-// CHECK: test_vreinterpret_s64_s32
+// CHECK-LABEL: test_vreinterpret_s64_s32
 int64x1_t test_vreinterpret_s64_s32(int32x2_t a) {
   return vreinterpret_s64_s32(a);
 }
 
-// CHECK: test_vreinterpret_s64_u8
+// CHECK-LABEL: test_vreinterpret_s64_u8
 int64x1_t test_vreinterpret_s64_u8(uint8x8_t a) {
   return vreinterpret_s64_u8(a);
 }
 
-// CHECK: test_vreinterpret_s64_u16
+// CHECK-LABEL: test_vreinterpret_s64_u16
 int64x1_t test_vreinterpret_s64_u16(uint16x4_t a) {
   return vreinterpret_s64_u16(a);
 }
 
-// CHECK: test_vreinterpret_s64_u32
+// CHECK-LABEL: test_vreinterpret_s64_u32
 int64x1_t test_vreinterpret_s64_u32(uint32x2_t a) {
   return vreinterpret_s64_u32(a);
 }
 
-// CHECK: test_vreinterpret_s64_u64
+// CHECK-LABEL: test_vreinterpret_s64_u64
 int64x1_t test_vreinterpret_s64_u64(uint64x1_t a) {
   return vreinterpret_s64_u64(a);
 }
 
-// CHECK: test_vreinterpret_s64_f16
+// CHECK-LABEL: test_vreinterpret_s64_f16
 int64x1_t test_vreinterpret_s64_f16(float16x4_t a) {
   return vreinterpret_s64_f16(a);
 }
 
-// CHECK: test_vreinterpret_s64_f32
+// CHECK-LABEL: test_vreinterpret_s64_f32
 int64x1_t test_vreinterpret_s64_f32(float32x2_t a) {
   return vreinterpret_s64_f32(a);
 }
 
-// CHECK: test_vreinterpret_s64_p8
+// CHECK-LABEL: test_vreinterpret_s64_p8
 int64x1_t test_vreinterpret_s64_p8(poly8x8_t a) {
   return vreinterpret_s64_p8(a);
 }
 
-// CHECK: test_vreinterpret_s64_p16
+// CHECK-LABEL: test_vreinterpret_s64_p16
 int64x1_t test_vreinterpret_s64_p16(poly16x4_t a) {
   return vreinterpret_s64_p16(a);
 }
 
-// CHECK: test_vreinterpret_u8_s8
+// CHECK-LABEL: test_vreinterpret_u8_s8
 uint8x8_t test_vreinterpret_u8_s8(int8x8_t a) {
   return vreinterpret_u8_s8(a);
 }
 
-// CHECK: test_vreinterpret_u8_s16
+// CHECK-LABEL: test_vreinterpret_u8_s16
 uint8x8_t test_vreinterpret_u8_s16(int16x4_t a) {
   return vreinterpret_u8_s16(a);
 }
 
-// CHECK: test_vreinterpret_u8_s32
+// CHECK-LABEL: test_vreinterpret_u8_s32
 uint8x8_t test_vreinterpret_u8_s32(int32x2_t a) {
   return vreinterpret_u8_s32(a);
 }
 
-// CHECK: test_vreinterpret_u8_s64
+// CHECK-LABEL: test_vreinterpret_u8_s64
 uint8x8_t test_vreinterpret_u8_s64(int64x1_t a) {
   return vreinterpret_u8_s64(a);
 }
 
-// CHECK: test_vreinterpret_u8_u16
+// CHECK-LABEL: test_vreinterpret_u8_u16
 uint8x8_t test_vreinterpret_u8_u16(uint16x4_t a) {
   return vreinterpret_u8_u16(a);
 }
 
-// CHECK: test_vreinterpret_u8_u32
+// CHECK-LABEL: test_vreinterpret_u8_u32
 uint8x8_t test_vreinterpret_u8_u32(uint32x2_t a) {
   return vreinterpret_u8_u32(a);
 }
 
-// CHECK: test_vreinterpret_u8_u64
+// CHECK-LABEL: test_vreinterpret_u8_u64
 uint8x8_t test_vreinterpret_u8_u64(uint64x1_t a) {
   return vreinterpret_u8_u64(a);
 }
 
-// CHECK: test_vreinterpret_u8_f16
+// CHECK-LABEL: test_vreinterpret_u8_f16
 uint8x8_t test_vreinterpret_u8_f16(float16x4_t a) {
   return vreinterpret_u8_f16(a);
 }
 
-// CHECK: test_vreinterpret_u8_f32
+// CHECK-LABEL: test_vreinterpret_u8_f32
 uint8x8_t test_vreinterpret_u8_f32(float32x2_t a) {
   return vreinterpret_u8_f32(a);
 }
 
-// CHECK: test_vreinterpret_u8_p8
+// CHECK-LABEL: test_vreinterpret_u8_p8
 uint8x8_t test_vreinterpret_u8_p8(poly8x8_t a) {
   return vreinterpret_u8_p8(a);
 }
 
-// CHECK: test_vreinterpret_u8_p16
+// CHECK-LABEL: test_vreinterpret_u8_p16
 uint8x8_t test_vreinterpret_u8_p16(poly16x4_t a) {
   return vreinterpret_u8_p16(a);
 }
 
-// CHECK: test_vreinterpret_u16_s8
+// CHECK-LABEL: test_vreinterpret_u16_s8
 uint16x4_t test_vreinterpret_u16_s8(int8x8_t a) {
   return vreinterpret_u16_s8(a);
 }
 
-// CHECK: test_vreinterpret_u16_s16
+// CHECK-LABEL: test_vreinterpret_u16_s16
 uint16x4_t test_vreinterpret_u16_s16(int16x4_t a) {
   return vreinterpret_u16_s16(a);
 }
 
-// CHECK: test_vreinterpret_u16_s32
+// CHECK-LABEL: test_vreinterpret_u16_s32
 uint16x4_t test_vreinterpret_u16_s32(int32x2_t a) {
   return vreinterpret_u16_s32(a);
 }
 
-// CHECK: test_vreinterpret_u16_s64
+// CHECK-LABEL: test_vreinterpret_u16_s64
 uint16x4_t test_vreinterpret_u16_s64(int64x1_t a) {
   return vreinterpret_u16_s64(a);
 }
 
-// CHECK: test_vreinterpret_u16_u8
+// CHECK-LABEL: test_vreinterpret_u16_u8
 uint16x4_t test_vreinterpret_u16_u8(uint8x8_t a) {
   return vreinterpret_u16_u8(a);
 }
 
-// CHECK: test_vreinterpret_u16_u32
+// CHECK-LABEL: test_vreinterpret_u16_u32
 uint16x4_t test_vreinterpret_u16_u32(uint32x2_t a) {
   return vreinterpret_u16_u32(a);
 }
 
-// CHECK: test_vreinterpret_u16_u64
+// CHECK-LABEL: test_vreinterpret_u16_u64
 uint16x4_t test_vreinterpret_u16_u64(uint64x1_t a) {
   return vreinterpret_u16_u64(a);
 }
 
-// CHECK: test_vreinterpret_u16_f16
+// CHECK-LABEL: test_vreinterpret_u16_f16
 uint16x4_t test_vreinterpret_u16_f16(float16x4_t a) {
   return vreinterpret_u16_f16(a);
 }
 
-// CHECK: test_vreinterpret_u16_f32
+// CHECK-LABEL: test_vreinterpret_u16_f32
 uint16x4_t test_vreinterpret_u16_f32(float32x2_t a) {
   return vreinterpret_u16_f32(a);
 }
 
-// CHECK: test_vreinterpret_u16_p8
+// CHECK-LABEL: test_vreinterpret_u16_p8
 uint16x4_t test_vreinterpret_u16_p8(poly8x8_t a) {
   return vreinterpret_u16_p8(a);
 }
 
-// CHECK: test_vreinterpret_u16_p16
+// CHECK-LABEL: test_vreinterpret_u16_p16
 uint16x4_t test_vreinterpret_u16_p16(poly16x4_t a) {
   return vreinterpret_u16_p16(a);
 }
 
-// CHECK: test_vreinterpret_u32_s8
+// CHECK-LABEL: test_vreinterpret_u32_s8
 uint32x2_t test_vreinterpret_u32_s8(int8x8_t a) {
   return vreinterpret_u32_s8(a);
 }
 
-// CHECK: test_vreinterpret_u32_s16
+// CHECK-LABEL: test_vreinterpret_u32_s16
 uint32x2_t test_vreinterpret_u32_s16(int16x4_t a) {
   return vreinterpret_u32_s16(a);
 }
 
-// CHECK: test_vreinterpret_u32_s32
+// CHECK-LABEL: test_vreinterpret_u32_s32
 uint32x2_t test_vreinterpret_u32_s32(int32x2_t a) {
   return vreinterpret_u32_s32(a);
 }
 
-// CHECK: test_vreinterpret_u32_s64
+// CHECK-LABEL: test_vreinterpret_u32_s64
 uint32x2_t test_vreinterpret_u32_s64(int64x1_t a) {
   return vreinterpret_u32_s64(a);
 }
 
-// CHECK: test_vreinterpret_u32_u8
+// CHECK-LABEL: test_vreinterpret_u32_u8
 uint32x2_t test_vreinterpret_u32_u8(uint8x8_t a) {
   return vreinterpret_u32_u8(a);
 }
 
-// CHECK: test_vreinterpret_u32_u16
+// CHECK-LABEL: test_vreinterpret_u32_u16
 uint32x2_t test_vreinterpret_u32_u16(uint16x4_t a) {
   return vreinterpret_u32_u16(a);
 }
 
-// CHECK: test_vreinterpret_u32_u64
+// CHECK-LABEL: test_vreinterpret_u32_u64
 uint32x2_t test_vreinterpret_u32_u64(uint64x1_t a) {
   return vreinterpret_u32_u64(a);
 }
 
-// CHECK: test_vreinterpret_u32_f16
+// CHECK-LABEL: test_vreinterpret_u32_f16
 uint32x2_t test_vreinterpret_u32_f16(float16x4_t a) {
   return vreinterpret_u32_f16(a);
 }
 
-// CHECK: test_vreinterpret_u32_f32
+// CHECK-LABEL: test_vreinterpret_u32_f32
 uint32x2_t test_vreinterpret_u32_f32(float32x2_t a) {
   return vreinterpret_u32_f32(a);
 }
 
-// CHECK: test_vreinterpret_u32_p8
+// CHECK-LABEL: test_vreinterpret_u32_p8
 uint32x2_t test_vreinterpret_u32_p8(poly8x8_t a) {
   return vreinterpret_u32_p8(a);
 }
 
-// CHECK: test_vreinterpret_u32_p16
+// CHECK-LABEL: test_vreinterpret_u32_p16
 uint32x2_t test_vreinterpret_u32_p16(poly16x4_t a) {
   return vreinterpret_u32_p16(a);
 }
 
-// CHECK: test_vreinterpret_u64_s8
+// CHECK-LABEL: test_vreinterpret_u64_s8
 uint64x1_t test_vreinterpret_u64_s8(int8x8_t a) {
   return vreinterpret_u64_s8(a);
 }
 
-// CHECK: test_vreinterpret_u64_s16
+// CHECK-LABEL: test_vreinterpret_u64_s16
 uint64x1_t test_vreinterpret_u64_s16(int16x4_t a) {
   return vreinterpret_u64_s16(a);
 }
 
-// CHECK: test_vreinterpret_u64_s32
+// CHECK-LABEL: test_vreinterpret_u64_s32
 uint64x1_t test_vreinterpret_u64_s32(int32x2_t a) {
   return vreinterpret_u64_s32(a);
 }
 
-// CHECK: test_vreinterpret_u64_s64
+// CHECK-LABEL: test_vreinterpret_u64_s64
 uint64x1_t test_vreinterpret_u64_s64(int64x1_t a) {
   return vreinterpret_u64_s64(a);
 }
 
-// CHECK: test_vreinterpret_u64_u8
+// CHECK-LABEL: test_vreinterpret_u64_u8
 uint64x1_t test_vreinterpret_u64_u8(uint8x8_t a) {
   return vreinterpret_u64_u8(a);
 }
 
-// CHECK: test_vreinterpret_u64_u16
+// CHECK-LABEL: test_vreinterpret_u64_u16
 uint64x1_t test_vreinterpret_u64_u16(uint16x4_t a) {
   return vreinterpret_u64_u16(a);
 }
 
-// CHECK: test_vreinterpret_u64_u32
+// CHECK-LABEL: test_vreinterpret_u64_u32
 uint64x1_t test_vreinterpret_u64_u32(uint32x2_t a) {
   return vreinterpret_u64_u32(a);
 }
 
-// CHECK: test_vreinterpret_u64_f16
+// CHECK-LABEL: test_vreinterpret_u64_f16
 uint64x1_t test_vreinterpret_u64_f16(float16x4_t a) {
   return vreinterpret_u64_f16(a);
 }
 
-// CHECK: test_vreinterpret_u64_f32
+// CHECK-LABEL: test_vreinterpret_u64_f32
 uint64x1_t test_vreinterpret_u64_f32(float32x2_t a) {
   return vreinterpret_u64_f32(a);
 }
 
-// CHECK: test_vreinterpret_u64_p8
+// CHECK-LABEL: test_vreinterpret_u64_p8
 uint64x1_t test_vreinterpret_u64_p8(poly8x8_t a) {
   return vreinterpret_u64_p8(a);
 }
 
-// CHECK: test_vreinterpret_u64_p16
+// CHECK-LABEL: test_vreinterpret_u64_p16
 uint64x1_t test_vreinterpret_u64_p16(poly16x4_t a) {
   return vreinterpret_u64_p16(a);
 }
 
-// CHECK: test_vreinterpret_f16_s8
+// CHECK-LABEL: test_vreinterpret_f16_s8
 float16x4_t test_vreinterpret_f16_s8(int8x8_t a) {
   return vreinterpret_f16_s8(a);
 }
 
-// CHECK: test_vreinterpret_f16_s16
+// CHECK-LABEL: test_vreinterpret_f16_s16
 float16x4_t test_vreinterpret_f16_s16(int16x4_t a) {
   return vreinterpret_f16_s16(a);
 }
 
-// CHECK: test_vreinterpret_f16_s32
+// CHECK-LABEL: test_vreinterpret_f16_s32
 float16x4_t test_vreinterpret_f16_s32(int32x2_t a) {
   return vreinterpret_f16_s32(a);
 }
 
-// CHECK: test_vreinterpret_f16_s64
+// CHECK-LABEL: test_vreinterpret_f16_s64
 float16x4_t test_vreinterpret_f16_s64(int64x1_t a) {
   return vreinterpret_f16_s64(a);
 }
 
-// CHECK: test_vreinterpret_f16_u8
+// CHECK-LABEL: test_vreinterpret_f16_u8
 float16x4_t test_vreinterpret_f16_u8(uint8x8_t a) {
   return vreinterpret_f16_u8(a);
 }
 
-// CHECK: test_vreinterpret_f16_u16
+// CHECK-LABEL: test_vreinterpret_f16_u16
 float16x4_t test_vreinterpret_f16_u16(uint16x4_t a) {
   return vreinterpret_f16_u16(a);
 }
 
-// CHECK: test_vreinterpret_f16_u32
+// CHECK-LABEL: test_vreinterpret_f16_u32
 float16x4_t test_vreinterpret_f16_u32(uint32x2_t a) {
   return vreinterpret_f16_u32(a);
 }
 
-// CHECK: test_vreinterpret_f16_u64
+// CHECK-LABEL: test_vreinterpret_f16_u64
 float16x4_t test_vreinterpret_f16_u64(uint64x1_t a) {
   return vreinterpret_f16_u64(a);
 }
 
-// CHECK: test_vreinterpret_f16_f32
+// CHECK-LABEL: test_vreinterpret_f16_f32
 float16x4_t test_vreinterpret_f16_f32(float32x2_t a) {
   return vreinterpret_f16_f32(a);
 }
 
-// CHECK: test_vreinterpret_f16_p8
+// CHECK-LABEL: test_vreinterpret_f16_p8
 float16x4_t test_vreinterpret_f16_p8(poly8x8_t a) {
   return vreinterpret_f16_p8(a);
 }
 
-// CHECK: test_vreinterpret_f16_p16
+// CHECK-LABEL: test_vreinterpret_f16_p16
 float16x4_t test_vreinterpret_f16_p16(poly16x4_t a) {
   return vreinterpret_f16_p16(a);
 }
 
-// CHECK: test_vreinterpret_f32_s8
+// CHECK-LABEL: test_vreinterpret_f32_s8
 float32x2_t test_vreinterpret_f32_s8(int8x8_t a) {
   return vreinterpret_f32_s8(a);
 }
 
-// CHECK: test_vreinterpret_f32_s16
+// CHECK-LABEL: test_vreinterpret_f32_s16
 float32x2_t test_vreinterpret_f32_s16(int16x4_t a) {
   return vreinterpret_f32_s16(a);
 }
 
-// CHECK: test_vreinterpret_f32_s32
+// CHECK-LABEL: test_vreinterpret_f32_s32
 float32x2_t test_vreinterpret_f32_s32(int32x2_t a) {
   return vreinterpret_f32_s32(a);
 }
 
-// CHECK: test_vreinterpret_f32_s64
+// CHECK-LABEL: test_vreinterpret_f32_s64
 float32x2_t test_vreinterpret_f32_s64(int64x1_t a) {
   return vreinterpret_f32_s64(a);
 }
 
-// CHECK: test_vreinterpret_f32_u8
+// CHECK-LABEL: test_vreinterpret_f32_u8
 float32x2_t test_vreinterpret_f32_u8(uint8x8_t a) {
   return vreinterpret_f32_u8(a);
 }
 
-// CHECK: test_vreinterpret_f32_u16
+// CHECK-LABEL: test_vreinterpret_f32_u16
 float32x2_t test_vreinterpret_f32_u16(uint16x4_t a) {
   return vreinterpret_f32_u16(a);
 }
 
-// CHECK: test_vreinterpret_f32_u32
+// CHECK-LABEL: test_vreinterpret_f32_u32
 float32x2_t test_vreinterpret_f32_u32(uint32x2_t a) {
   return vreinterpret_f32_u32(a);
 }
 
-// CHECK: test_vreinterpret_f32_u64
+// CHECK-LABEL: test_vreinterpret_f32_u64
 float32x2_t test_vreinterpret_f32_u64(uint64x1_t a) {
   return vreinterpret_f32_u64(a);
 }
 
-// CHECK: test_vreinterpret_f32_f16
+// CHECK-LABEL: test_vreinterpret_f32_f16
 float32x2_t test_vreinterpret_f32_f16(float16x4_t a) {
   return vreinterpret_f32_f16(a);
 }
 
-// CHECK: test_vreinterpret_f32_p8
+// CHECK-LABEL: test_vreinterpret_f32_p8
 float32x2_t test_vreinterpret_f32_p8(poly8x8_t a) {
   return vreinterpret_f32_p8(a);
 }
 
-// CHECK: test_vreinterpret_f32_p16
+// CHECK-LABEL: test_vreinterpret_f32_p16
 float32x2_t test_vreinterpret_f32_p16(poly16x4_t a) {
   return vreinterpret_f32_p16(a);
 }
 
-// CHECK: test_vreinterpret_p8_s8
+// CHECK-LABEL: test_vreinterpret_p8_s8
 poly8x8_t test_vreinterpret_p8_s8(int8x8_t a) {
   return vreinterpret_p8_s8(a);
 }
 
-// CHECK: test_vreinterpret_p8_s16
+// CHECK-LABEL: test_vreinterpret_p8_s16
 poly8x8_t test_vreinterpret_p8_s16(int16x4_t a) {
   return vreinterpret_p8_s16(a);
 }
 
-// CHECK: test_vreinterpret_p8_s32
+// CHECK-LABEL: test_vreinterpret_p8_s32
 poly8x8_t test_vreinterpret_p8_s32(int32x2_t a) {
   return vreinterpret_p8_s32(a);
 }
 
-// CHECK: test_vreinterpret_p8_s64
+// CHECK-LABEL: test_vreinterpret_p8_s64
 poly8x8_t test_vreinterpret_p8_s64(int64x1_t a) {
   return vreinterpret_p8_s64(a);
 }
 
-// CHECK: test_vreinterpret_p8_u8
+// CHECK-LABEL: test_vreinterpret_p8_u8
 poly8x8_t test_vreinterpret_p8_u8(uint8x8_t a) {
   return vreinterpret_p8_u8(a);
 }
 
-// CHECK: test_vreinterpret_p8_u16
+// CHECK-LABEL: test_vreinterpret_p8_u16
 poly8x8_t test_vreinterpret_p8_u16(uint16x4_t a) {
   return vreinterpret_p8_u16(a);
 }
 
-// CHECK: test_vreinterpret_p8_u32
+// CHECK-LABEL: test_vreinterpret_p8_u32
 poly8x8_t test_vreinterpret_p8_u32(uint32x2_t a) {
   return vreinterpret_p8_u32(a);
 }
 
-// CHECK: test_vreinterpret_p8_u64
+// CHECK-LABEL: test_vreinterpret_p8_u64
 poly8x8_t test_vreinterpret_p8_u64(uint64x1_t a) {
   return vreinterpret_p8_u64(a);
 }
 
-// CHECK: test_vreinterpret_p8_f16
+// CHECK-LABEL: test_vreinterpret_p8_f16
 poly8x8_t test_vreinterpret_p8_f16(float16x4_t a) {
   return vreinterpret_p8_f16(a);
 }
 
-// CHECK: test_vreinterpret_p8_f32
+// CHECK-LABEL: test_vreinterpret_p8_f32
 poly8x8_t test_vreinterpret_p8_f32(float32x2_t a) {
   return vreinterpret_p8_f32(a);
 }
 
-// CHECK: test_vreinterpret_p8_p16
+// CHECK-LABEL: test_vreinterpret_p8_p16
 poly8x8_t test_vreinterpret_p8_p16(poly16x4_t a) {
   return vreinterpret_p8_p16(a);
 }
 
-// CHECK: test_vreinterpret_p16_s8
+// CHECK-LABEL: test_vreinterpret_p16_s8
 poly16x4_t test_vreinterpret_p16_s8(int8x8_t a) {
   return vreinterpret_p16_s8(a);
 }
 
-// CHECK: test_vreinterpret_p16_s16
+// CHECK-LABEL: test_vreinterpret_p16_s16
 poly16x4_t test_vreinterpret_p16_s16(int16x4_t a) {
   return vreinterpret_p16_s16(a);
 }
 
-// CHECK: test_vreinterpret_p16_s32
+// CHECK-LABEL: test_vreinterpret_p16_s32
 poly16x4_t test_vreinterpret_p16_s32(int32x2_t a) {
   return vreinterpret_p16_s32(a);
 }
 
-// CHECK: test_vreinterpret_p16_s64
+// CHECK-LABEL: test_vreinterpret_p16_s64
 poly16x4_t test_vreinterpret_p16_s64(int64x1_t a) {
   return vreinterpret_p16_s64(a);
 }
 
-// CHECK: test_vreinterpret_p16_u8
+// CHECK-LABEL: test_vreinterpret_p16_u8
 poly16x4_t test_vreinterpret_p16_u8(uint8x8_t a) {
   return vreinterpret_p16_u8(a);
 }
 
-// CHECK: test_vreinterpret_p16_u16
+// CHECK-LABEL: test_vreinterpret_p16_u16
 poly16x4_t test_vreinterpret_p16_u16(uint16x4_t a) {
   return vreinterpret_p16_u16(a);
 }
 
-// CHECK: test_vreinterpret_p16_u32
+// CHECK-LABEL: test_vreinterpret_p16_u32
 poly16x4_t test_vreinterpret_p16_u32(uint32x2_t a) {
   return vreinterpret_p16_u32(a);
 }
 
-// CHECK: test_vreinterpret_p16_u64
+// CHECK-LABEL: test_vreinterpret_p16_u64
 poly16x4_t test_vreinterpret_p16_u64(uint64x1_t a) {
   return vreinterpret_p16_u64(a);
 }
 
-// CHECK: test_vreinterpret_p16_f16
+// CHECK-LABEL: test_vreinterpret_p16_f16
 poly16x4_t test_vreinterpret_p16_f16(float16x4_t a) {
   return vreinterpret_p16_f16(a);
 }
 
-// CHECK: test_vreinterpret_p16_f32
+// CHECK-LABEL: test_vreinterpret_p16_f32
 poly16x4_t test_vreinterpret_p16_f32(float32x2_t a) {
   return vreinterpret_p16_f32(a);
 }
 
-// CHECK: test_vreinterpret_p16_p8
+// CHECK-LABEL: test_vreinterpret_p16_p8
 poly16x4_t test_vreinterpret_p16_p8(poly8x8_t a) {
   return vreinterpret_p16_p8(a);
 }
 
-// CHECK: test_vreinterpretq_s8_s16
+// CHECK-LABEL: test_vreinterpretq_s8_s16
 int8x16_t test_vreinterpretq_s8_s16(int16x8_t a) {
   return vreinterpretq_s8_s16(a);
 }
 
-// CHECK: test_vreinterpretq_s8_s32
+// CHECK-LABEL: test_vreinterpretq_s8_s32
 int8x16_t test_vreinterpretq_s8_s32(int32x4_t a) {
   return vreinterpretq_s8_s32(a);
 }
 
-// CHECK: test_vreinterpretq_s8_s64
+// CHECK-LABEL: test_vreinterpretq_s8_s64
 int8x16_t test_vreinterpretq_s8_s64(int64x2_t a) {
   return vreinterpretq_s8_s64(a);
 }
 
-// CHECK: test_vreinterpretq_s8_u8
+// CHECK-LABEL: test_vreinterpretq_s8_u8
 int8x16_t test_vreinterpretq_s8_u8(uint8x16_t a) {
   return vreinterpretq_s8_u8(a);
 }
 
-// CHECK: test_vreinterpretq_s8_u16
+// CHECK-LABEL: test_vreinterpretq_s8_u16
 int8x16_t test_vreinterpretq_s8_u16(uint16x8_t a) {
   return vreinterpretq_s8_u16(a);
 }
 
-// CHECK: test_vreinterpretq_s8_u32
+// CHECK-LABEL: test_vreinterpretq_s8_u32
 int8x16_t test_vreinterpretq_s8_u32(uint32x4_t a) {
   return vreinterpretq_s8_u32(a);
 }
 
-// CHECK: test_vreinterpretq_s8_u64
+// CHECK-LABEL: test_vreinterpretq_s8_u64
 int8x16_t test_vreinterpretq_s8_u64(uint64x2_t a) {
   return vreinterpretq_s8_u64(a);
 }
 
-// CHECK: test_vreinterpretq_s8_f16
+// CHECK-LABEL: test_vreinterpretq_s8_f16
 int8x16_t test_vreinterpretq_s8_f16(float16x8_t a) {
   return vreinterpretq_s8_f16(a);
 }
 
-// CHECK: test_vreinterpretq_s8_f32
+// CHECK-LABEL: test_vreinterpretq_s8_f32
 int8x16_t test_vreinterpretq_s8_f32(float32x4_t a) {
   return vreinterpretq_s8_f32(a);
 }
 
-// CHECK: test_vreinterpretq_s8_p8
+// CHECK-LABEL: test_vreinterpretq_s8_p8
 int8x16_t test_vreinterpretq_s8_p8(poly8x16_t a) {
   return vreinterpretq_s8_p8(a);
 }
 
-// CHECK: test_vreinterpretq_s8_p16
+// CHECK-LABEL: test_vreinterpretq_s8_p16
 int8x16_t test_vreinterpretq_s8_p16(poly16x8_t a) {
   return vreinterpretq_s8_p16(a);
 }
 
-// CHECK: test_vreinterpretq_s16_s8
+// CHECK-LABEL: test_vreinterpretq_s16_s8
 int16x8_t test_vreinterpretq_s16_s8(int8x16_t a) {
   return vreinterpretq_s16_s8(a);
 }
 
-// CHECK: test_vreinterpretq_s16_s32
+// CHECK-LABEL: test_vreinterpretq_s16_s32
 int16x8_t test_vreinterpretq_s16_s32(int32x4_t a) {
   return vreinterpretq_s16_s32(a);
 }
 
-// CHECK: test_vreinterpretq_s16_s64
+// CHECK-LABEL: test_vreinterpretq_s16_s64
 int16x8_t test_vreinterpretq_s16_s64(int64x2_t a) {
   return vreinterpretq_s16_s64(a);
 }
 
-// CHECK: test_vreinterpretq_s16_u8
+// CHECK-LABEL: test_vreinterpretq_s16_u8
 int16x8_t test_vreinterpretq_s16_u8(uint8x16_t a) {
   return vreinterpretq_s16_u8(a);
 }
 
-// CHECK: test_vreinterpretq_s16_u16
+// CHECK-LABEL: test_vreinterpretq_s16_u16
 int16x8_t test_vreinterpretq_s16_u16(uint16x8_t a) {
   return vreinterpretq_s16_u16(a);
 }
 
-// CHECK: test_vreinterpretq_s16_u32
+// CHECK-LABEL: test_vreinterpretq_s16_u32
 int16x8_t test_vreinterpretq_s16_u32(uint32x4_t a) {
   return vreinterpretq_s16_u32(a);
 }
 
-// CHECK: test_vreinterpretq_s16_u64
+// CHECK-LABEL: test_vreinterpretq_s16_u64
 int16x8_t test_vreinterpretq_s16_u64(uint64x2_t a) {
   return vreinterpretq_s16_u64(a);
 }
 
-// CHECK: test_vreinterpretq_s16_f16
+// CHECK-LABEL: test_vreinterpretq_s16_f16
 int16x8_t test_vreinterpretq_s16_f16(float16x8_t a) {
   return vreinterpretq_s16_f16(a);
 }
 
-// CHECK: test_vreinterpretq_s16_f32
+// CHECK-LABEL: test_vreinterpretq_s16_f32
 int16x8_t test_vreinterpretq_s16_f32(float32x4_t a) {
   return vreinterpretq_s16_f32(a);
 }
 
-// CHECK: test_vreinterpretq_s16_p8
+// CHECK-LABEL: test_vreinterpretq_s16_p8
 int16x8_t test_vreinterpretq_s16_p8(poly8x16_t a) {
   return vreinterpretq_s16_p8(a);
 }
 
-// CHECK: test_vreinterpretq_s16_p16
+// CHECK-LABEL: test_vreinterpretq_s16_p16
 int16x8_t test_vreinterpretq_s16_p16(poly16x8_t a) {
   return vreinterpretq_s16_p16(a);
 }
 
-// CHECK: test_vreinterpretq_s32_s8
+// CHECK-LABEL: test_vreinterpretq_s32_s8
 int32x4_t test_vreinterpretq_s32_s8(int8x16_t a) {
   return vreinterpretq_s32_s8(a);
 }
 
-// CHECK: test_vreinterpretq_s32_s16
+// CHECK-LABEL: test_vreinterpretq_s32_s16
 int32x4_t test_vreinterpretq_s32_s16(int16x8_t a) {
   return vreinterpretq_s32_s16(a);
 }
 
-// CHECK: test_vreinterpretq_s32_s64
+// CHECK-LABEL: test_vreinterpretq_s32_s64
 int32x4_t test_vreinterpretq_s32_s64(int64x2_t a) {
   return vreinterpretq_s32_s64(a);
 }
 
-// CHECK: test_vreinterpretq_s32_u8
+// CHECK-LABEL: test_vreinterpretq_s32_u8
 int32x4_t test_vreinterpretq_s32_u8(uint8x16_t a) {
   return vreinterpretq_s32_u8(a);
 }
 
-// CHECK: test_vreinterpretq_s32_u16
+// CHECK-LABEL: test_vreinterpretq_s32_u16
 int32x4_t test_vreinterpretq_s32_u16(uint16x8_t a) {
   return vreinterpretq_s32_u16(a);
 }
 
-// CHECK: test_vreinterpretq_s32_u32
+// CHECK-LABEL: test_vreinterpretq_s32_u32
 int32x4_t test_vreinterpretq_s32_u32(uint32x4_t a) {
   return vreinterpretq_s32_u32(a);
 }
 
-// CHECK: test_vreinterpretq_s32_u64
+// CHECK-LABEL: test_vreinterpretq_s32_u64
 int32x4_t test_vreinterpretq_s32_u64(uint64x2_t a) {
   return vreinterpretq_s32_u64(a);
 }
 
-// CHECK: test_vreinterpretq_s32_f16
+// CHECK-LABEL: test_vreinterpretq_s32_f16
 int32x4_t test_vreinterpretq_s32_f16(float16x8_t a) {
   return vreinterpretq_s32_f16(a);
 }
 
-// CHECK: test_vreinterpretq_s32_f32
+// CHECK-LABEL: test_vreinterpretq_s32_f32
 int32x4_t test_vreinterpretq_s32_f32(float32x4_t a) {
   return vreinterpretq_s32_f32(a);
 }
 
-// CHECK: test_vreinterpretq_s32_p8
+// CHECK-LABEL: test_vreinterpretq_s32_p8
 int32x4_t test_vreinterpretq_s32_p8(poly8x16_t a) {
   return vreinterpretq_s32_p8(a);
 }
 
-// CHECK: test_vreinterpretq_s32_p16
+// CHECK-LABEL: test_vreinterpretq_s32_p16
 int32x4_t test_vreinterpretq_s32_p16(poly16x8_t a) {
   return vreinterpretq_s32_p16(a);
 }
 
-// CHECK: test_vreinterpretq_s64_s8
+// CHECK-LABEL: test_vreinterpretq_s64_s8
 int64x2_t test_vreinterpretq_s64_s8(int8x16_t a) {
   return vreinterpretq_s64_s8(a);
 }
 
-// CHECK: test_vreinterpretq_s64_s16
+// CHECK-LABEL: test_vreinterpretq_s64_s16
 int64x2_t test_vreinterpretq_s64_s16(int16x8_t a) {
   return vreinterpretq_s64_s16(a);
 }
 
-// CHECK: test_vreinterpretq_s64_s32
+// CHECK-LABEL: test_vreinterpretq_s64_s32
 int64x2_t test_vreinterpretq_s64_s32(int32x4_t a) {
   return vreinterpretq_s64_s32(a);
 }
 
-// CHECK: test_vreinterpretq_s64_u8
+// CHECK-LABEL: test_vreinterpretq_s64_u8
 int64x2_t test_vreinterpretq_s64_u8(uint8x16_t a) {
   return vreinterpretq_s64_u8(a);
 }
 
-// CHECK: test_vreinterpretq_s64_u16
+// CHECK-LABEL: test_vreinterpretq_s64_u16
 int64x2_t test_vreinterpretq_s64_u16(uint16x8_t a) {
   return vreinterpretq_s64_u16(a);
 }
 
-// CHECK: test_vreinterpretq_s64_u32
+// CHECK-LABEL: test_vreinterpretq_s64_u32
 int64x2_t test_vreinterpretq_s64_u32(uint32x4_t a) {
   return vreinterpretq_s64_u32(a);
 }
 
-// CHECK: test_vreinterpretq_s64_u64
+// CHECK-LABEL: test_vreinterpretq_s64_u64
 int64x2_t test_vreinterpretq_s64_u64(uint64x2_t a) {
   return vreinterpretq_s64_u64(a);
 }
 
-// CHECK: test_vreinterpretq_s64_f16
+// CHECK-LABEL: test_vreinterpretq_s64_f16
 int64x2_t test_vreinterpretq_s64_f16(float16x8_t a) {
   return vreinterpretq_s64_f16(a);
 }
 
-// CHECK: test_vreinterpretq_s64_f32
+// CHECK-LABEL: test_vreinterpretq_s64_f32
 int64x2_t test_vreinterpretq_s64_f32(float32x4_t a) {
   return vreinterpretq_s64_f32(a);
 }
 
-// CHECK: test_vreinterpretq_s64_p8
+// CHECK-LABEL: test_vreinterpretq_s64_p8
 int64x2_t test_vreinterpretq_s64_p8(poly8x16_t a) {
   return vreinterpretq_s64_p8(a);
 }
 
-// CHECK: test_vreinterpretq_s64_p16
+// CHECK-LABEL: test_vreinterpretq_s64_p16
 int64x2_t test_vreinterpretq_s64_p16(poly16x8_t a) {
   return vreinterpretq_s64_p16(a);
 }
 
-// CHECK: test_vreinterpretq_u8_s8
+// CHECK-LABEL: test_vreinterpretq_u8_s8
 uint8x16_t test_vreinterpretq_u8_s8(int8x16_t a) {
   return vreinterpretq_u8_s8(a);
 }
 
-// CHECK: test_vreinterpretq_u8_s16
+// CHECK-LABEL: test_vreinterpretq_u8_s16
 uint8x16_t test_vreinterpretq_u8_s16(int16x8_t a) {
   return vreinterpretq_u8_s16(a);
 }
 
-// CHECK: test_vreinterpretq_u8_s32
+// CHECK-LABEL: test_vreinterpretq_u8_s32
 uint8x16_t test_vreinterpretq_u8_s32(int32x4_t a) {
   return vreinterpretq_u8_s32(a);
 }
 
-// CHECK: test_vreinterpretq_u8_s64
+// CHECK-LABEL: test_vreinterpretq_u8_s64
 uint8x16_t test_vreinterpretq_u8_s64(int64x2_t a) {
   return vreinterpretq_u8_s64(a);
 }
 
-// CHECK: test_vreinterpretq_u8_u16
+// CHECK-LABEL: test_vreinterpretq_u8_u16
 uint8x16_t test_vreinterpretq_u8_u16(uint16x8_t a) {
   return vreinterpretq_u8_u16(a);
 }
 
-// CHECK: test_vreinterpretq_u8_u32
+// CHECK-LABEL: test_vreinterpretq_u8_u32
 uint8x16_t test_vreinterpretq_u8_u32(uint32x4_t a) {
   return vreinterpretq_u8_u32(a);
 }
 
-// CHECK: test_vreinterpretq_u8_u64
+// CHECK-LABEL: test_vreinterpretq_u8_u64
 uint8x16_t test_vreinterpretq_u8_u64(uint64x2_t a) {
   return vreinterpretq_u8_u64(a);
 }
 
-// CHECK: test_vreinterpretq_u8_f16
+// CHECK-LABEL: test_vreinterpretq_u8_f16
 uint8x16_t test_vreinterpretq_u8_f16(float16x8_t a) {
   return vreinterpretq_u8_f16(a);
 }
 
-// CHECK: test_vreinterpretq_u8_f32
+// CHECK-LABEL: test_vreinterpretq_u8_f32
 uint8x16_t test_vreinterpretq_u8_f32(float32x4_t a) {
   return vreinterpretq_u8_f32(a);
 }
 
-// CHECK: test_vreinterpretq_u8_p8
+// CHECK-LABEL: test_vreinterpretq_u8_p8
 uint8x16_t test_vreinterpretq_u8_p8(poly8x16_t a) {
   return vreinterpretq_u8_p8(a);
 }
 
-// CHECK: test_vreinterpretq_u8_p16
+// CHECK-LABEL: test_vreinterpretq_u8_p16
 uint8x16_t test_vreinterpretq_u8_p16(poly16x8_t a) {
   return vreinterpretq_u8_p16(a);
 }
 
-// CHECK: test_vreinterpretq_u16_s8
+// CHECK-LABEL: test_vreinterpretq_u16_s8
 uint16x8_t test_vreinterpretq_u16_s8(int8x16_t a) {
   return vreinterpretq_u16_s8(a);
 }
 
-// CHECK: test_vreinterpretq_u16_s16
+// CHECK-LABEL: test_vreinterpretq_u16_s16
 uint16x8_t test_vreinterpretq_u16_s16(int16x8_t a) {
   return vreinterpretq_u16_s16(a);
 }
 
-// CHECK: test_vreinterpretq_u16_s32
+// CHECK-LABEL: test_vreinterpretq_u16_s32
 uint16x8_t test_vreinterpretq_u16_s32(int32x4_t a) {
   return vreinterpretq_u16_s32(a);
 }
 
-// CHECK: test_vreinterpretq_u16_s64
+// CHECK-LABEL: test_vreinterpretq_u16_s64
 uint16x8_t test_vreinterpretq_u16_s64(int64x2_t a) {
   return vreinterpretq_u16_s64(a);
 }
 
-// CHECK: test_vreinterpretq_u16_u8
+// CHECK-LABEL: test_vreinterpretq_u16_u8
 uint16x8_t test_vreinterpretq_u16_u8(uint8x16_t a) {
   return vreinterpretq_u16_u8(a);
 }
 
-// CHECK: test_vreinterpretq_u16_u32
+// CHECK-LABEL: test_vreinterpretq_u16_u32
 uint16x8_t test_vreinterpretq_u16_u32(uint32x4_t a) {
   return vreinterpretq_u16_u32(a);
 }
 
-// CHECK: test_vreinterpretq_u16_u64
+// CHECK-LABEL: test_vreinterpretq_u16_u64
 uint16x8_t test_vreinterpretq_u16_u64(uint64x2_t a) {
   return vreinterpretq_u16_u64(a);
 }
 
-// CHECK: test_vreinterpretq_u16_f16
+// CHECK-LABEL: test_vreinterpretq_u16_f16
 uint16x8_t test_vreinterpretq_u16_f16(float16x8_t a) {
   return vreinterpretq_u16_f16(a);
 }
 
-// CHECK: test_vreinterpretq_u16_f32
+// CHECK-LABEL: test_vreinterpretq_u16_f32
 uint16x8_t test_vreinterpretq_u16_f32(float32x4_t a) {
   return vreinterpretq_u16_f32(a);
 }
 
-// CHECK: test_vreinterpretq_u16_p8
+// CHECK-LABEL: test_vreinterpretq_u16_p8
 uint16x8_t test_vreinterpretq_u16_p8(poly8x16_t a) {
   return vreinterpretq_u16_p8(a);
 }
 
-// CHECK: test_vreinterpretq_u16_p16
+// CHECK-LABEL: test_vreinterpretq_u16_p16
 uint16x8_t test_vreinterpretq_u16_p16(poly16x8_t a) {
   return vreinterpretq_u16_p16(a);
 }
 
-// CHECK: test_vreinterpretq_u32_s8
+// CHECK-LABEL: test_vreinterpretq_u32_s8
 uint32x4_t test_vreinterpretq_u32_s8(int8x16_t a) {
   return vreinterpretq_u32_s8(a);
 }
 
-// CHECK: test_vreinterpretq_u32_s16
+// CHECK-LABEL: test_vreinterpretq_u32_s16
 uint32x4_t test_vreinterpretq_u32_s16(int16x8_t a) {
   return vreinterpretq_u32_s16(a);
 }
 
-// CHECK: test_vreinterpretq_u32_s32
+// CHECK-LABEL: test_vreinterpretq_u32_s32
 uint32x4_t test_vreinterpretq_u32_s32(int32x4_t a) {
   return vreinterpretq_u32_s32(a);
 }
 
-// CHECK: test_vreinterpretq_u32_s64
+// CHECK-LABEL: test_vreinterpretq_u32_s64
 uint32x4_t test_vreinterpretq_u32_s64(int64x2_t a) {
   return vreinterpretq_u32_s64(a);
 }
 
-// CHECK: test_vreinterpretq_u32_u8
+// CHECK-LABEL: test_vreinterpretq_u32_u8
 uint32x4_t test_vreinterpretq_u32_u8(uint8x16_t a) {
   return vreinterpretq_u32_u8(a);
 }
 
-// CHECK: test_vreinterpretq_u32_u16
+// CHECK-LABEL: test_vreinterpretq_u32_u16
 uint32x4_t test_vreinterpretq_u32_u16(uint16x8_t a) {
   return vreinterpretq_u32_u16(a);
 }
 
-// CHECK: test_vreinterpretq_u32_u64
+// CHECK-LABEL: test_vreinterpretq_u32_u64
 uint32x4_t test_vreinterpretq_u32_u64(uint64x2_t a) {
   return vreinterpretq_u32_u64(a);
 }
 
-// CHECK: test_vreinterpretq_u32_f16
+// CHECK-LABEL: test_vreinterpretq_u32_f16
 uint32x4_t test_vreinterpretq_u32_f16(float16x8_t a) {
   return vreinterpretq_u32_f16(a);
 }
 
-// CHECK: test_vreinterpretq_u32_f32
+// CHECK-LABEL: test_vreinterpretq_u32_f32
 uint32x4_t test_vreinterpretq_u32_f32(float32x4_t a) {
   return vreinterpretq_u32_f32(a);
 }
 
-// CHECK: test_vreinterpretq_u32_p8
+// CHECK-LABEL: test_vreinterpretq_u32_p8
 uint32x4_t test_vreinterpretq_u32_p8(poly8x16_t a) {
   return vreinterpretq_u32_p8(a);
 }
 
-// CHECK: test_vreinterpretq_u32_p16
+// CHECK-LABEL: test_vreinterpretq_u32_p16
 uint32x4_t test_vreinterpretq_u32_p16(poly16x8_t a) {
   return vreinterpretq_u32_p16(a);
 }
 
-// CHECK: test_vreinterpretq_u64_s8
+// CHECK-LABEL: test_vreinterpretq_u64_s8
 uint64x2_t test_vreinterpretq_u64_s8(int8x16_t a) {
   return vreinterpretq_u64_s8(a);
 }
 
-// CHECK: test_vreinterpretq_u64_s16
+// CHECK-LABEL: test_vreinterpretq_u64_s16
 uint64x2_t test_vreinterpretq_u64_s16(int16x8_t a) {
   return vreinterpretq_u64_s16(a);
 }
 
-// CHECK: test_vreinterpretq_u64_s32
+// CHECK-LABEL: test_vreinterpretq_u64_s32
 uint64x2_t test_vreinterpretq_u64_s32(int32x4_t a) {
   return vreinterpretq_u64_s32(a);
 }
 
-// CHECK: test_vreinterpretq_u64_s64
+// CHECK-LABEL: test_vreinterpretq_u64_s64
 uint64x2_t test_vreinterpretq_u64_s64(int64x2_t a) {
   return vreinterpretq_u64_s64(a);
 }
 
-// CHECK: test_vreinterpretq_u64_u8
+// CHECK-LABEL: test_vreinterpretq_u64_u8
 uint64x2_t test_vreinterpretq_u64_u8(uint8x16_t a) {
   return vreinterpretq_u64_u8(a);
 }
 
-// CHECK: test_vreinterpretq_u64_u16
+// CHECK-LABEL: test_vreinterpretq_u64_u16
 uint64x2_t test_vreinterpretq_u64_u16(uint16x8_t a) {
   return vreinterpretq_u64_u16(a);
 }
 
-// CHECK: test_vreinterpretq_u64_u32
+// CHECK-LABEL: test_vreinterpretq_u64_u32
 uint64x2_t test_vreinterpretq_u64_u32(uint32x4_t a) {
   return vreinterpretq_u64_u32(a);
 }
 
-// CHECK: test_vreinterpretq_u64_f16
+// CHECK-LABEL: test_vreinterpretq_u64_f16
 uint64x2_t test_vreinterpretq_u64_f16(float16x8_t a) {
   return vreinterpretq_u64_f16(a);
 }
 
-// CHECK: test_vreinterpretq_u64_f32
+// CHECK-LABEL: test_vreinterpretq_u64_f32
 uint64x2_t test_vreinterpretq_u64_f32(float32x4_t a) {
   return vreinterpretq_u64_f32(a);
 }
 
-// CHECK: test_vreinterpretq_u64_p8
+// CHECK-LABEL: test_vreinterpretq_u64_p8
 uint64x2_t test_vreinterpretq_u64_p8(poly8x16_t a) {
   return vreinterpretq_u64_p8(a);
 }
 
-// CHECK: test_vreinterpretq_u64_p16
+// CHECK-LABEL: test_vreinterpretq_u64_p16
 uint64x2_t test_vreinterpretq_u64_p16(poly16x8_t a) {
   return vreinterpretq_u64_p16(a);
 }
 
-// CHECK: test_vreinterpretq_f16_s8
+// CHECK-LABEL: test_vreinterpretq_f16_s8
 float16x8_t test_vreinterpretq_f16_s8(int8x16_t a) {
   return vreinterpretq_f16_s8(a);
 }
 
-// CHECK: test_vreinterpretq_f16_s16
+// CHECK-LABEL: test_vreinterpretq_f16_s16
 float16x8_t test_vreinterpretq_f16_s16(int16x8_t a) {
   return vreinterpretq_f16_s16(a);
 }
 
-// CHECK: test_vreinterpretq_f16_s32
+// CHECK-LABEL: test_vreinterpretq_f16_s32
 float16x8_t test_vreinterpretq_f16_s32(int32x4_t a) {
   return vreinterpretq_f16_s32(a);
 }
 
-// CHECK: test_vreinterpretq_f16_s64
+// CHECK-LABEL: test_vreinterpretq_f16_s64
 float16x8_t test_vreinterpretq_f16_s64(int64x2_t a) {
   return vreinterpretq_f16_s64(a);
 }
 
-// CHECK: test_vreinterpretq_f16_u8
+// CHECK-LABEL: test_vreinterpretq_f16_u8
 float16x8_t test_vreinterpretq_f16_u8(uint8x16_t a) {
   return vreinterpretq_f16_u8(a);
 }
 
-// CHECK: test_vreinterpretq_f16_u16
+// CHECK-LABEL: test_vreinterpretq_f16_u16
 float16x8_t test_vreinterpretq_f16_u16(uint16x8_t a) {
   return vreinterpretq_f16_u16(a);
 }
 
-// CHECK: test_vreinterpretq_f16_u32
+// CHECK-LABEL: test_vreinterpretq_f16_u32
 float16x8_t test_vreinterpretq_f16_u32(uint32x4_t a) {
   return vreinterpretq_f16_u32(a);
 }
 
-// CHECK: test_vreinterpretq_f16_u64
+// CHECK-LABEL: test_vreinterpretq_f16_u64
 float16x8_t test_vreinterpretq_f16_u64(uint64x2_t a) {
   return vreinterpretq_f16_u64(a);
 }
 
-// CHECK: test_vreinterpretq_f16_f32
+// CHECK-LABEL: test_vreinterpretq_f16_f32
 float16x8_t test_vreinterpretq_f16_f32(float32x4_t a) {
   return vreinterpretq_f16_f32(a);
 }
 
-// CHECK: test_vreinterpretq_f16_p8
+// CHECK-LABEL: test_vreinterpretq_f16_p8
 float16x8_t test_vreinterpretq_f16_p8(poly8x16_t a) {
   return vreinterpretq_f16_p8(a);
 }
 
-// CHECK: test_vreinterpretq_f16_p16
+// CHECK-LABEL: test_vreinterpretq_f16_p16
 float16x8_t test_vreinterpretq_f16_p16(poly16x8_t a) {
   return vreinterpretq_f16_p16(a);
 }
 
-// CHECK: test_vreinterpretq_f32_s8
+// CHECK-LABEL: test_vreinterpretq_f32_s8
 float32x4_t test_vreinterpretq_f32_s8(int8x16_t a) {
   return vreinterpretq_f32_s8(a);
 }
 
-// CHECK: test_vreinterpretq_f32_s16
+// CHECK-LABEL: test_vreinterpretq_f32_s16
 float32x4_t test_vreinterpretq_f32_s16(int16x8_t a) {
   return vreinterpretq_f32_s16(a);
 }
 
-// CHECK: test_vreinterpretq_f32_s32
+// CHECK-LABEL: test_vreinterpretq_f32_s32
 float32x4_t test_vreinterpretq_f32_s32(int32x4_t a) {
   return vreinterpretq_f32_s32(a);
 }
 
-// CHECK: test_vreinterpretq_f32_s64
+// CHECK-LABEL: test_vreinterpretq_f32_s64
 float32x4_t test_vreinterpretq_f32_s64(int64x2_t a) {
   return vreinterpretq_f32_s64(a);
 }
 
-// CHECK: test_vreinterpretq_f32_u8
+// CHECK-LABEL: test_vreinterpretq_f32_u8
 float32x4_t test_vreinterpretq_f32_u8(uint8x16_t a) {
   return vreinterpretq_f32_u8(a);
 }
 
-// CHECK: test_vreinterpretq_f32_u16
+// CHECK-LABEL: test_vreinterpretq_f32_u16
 float32x4_t test_vreinterpretq_f32_u16(uint16x8_t a) {
   return vreinterpretq_f32_u16(a);
 }
 
-// CHECK: test_vreinterpretq_f32_u32
+// CHECK-LABEL: test_vreinterpretq_f32_u32
 float32x4_t test_vreinterpretq_f32_u32(uint32x4_t a) {
   return vreinterpretq_f32_u32(a);
 }
 
-// CHECK: test_vreinterpretq_f32_u64
+// CHECK-LABEL: test_vreinterpretq_f32_u64
 float32x4_t test_vreinterpretq_f32_u64(uint64x2_t a) {
   return vreinterpretq_f32_u64(a);
 }
 
-// CHECK: test_vreinterpretq_f32_f16
+// CHECK-LABEL: test_vreinterpretq_f32_f16
 float32x4_t test_vreinterpretq_f32_f16(float16x8_t a) {
   return vreinterpretq_f32_f16(a);
 }
 
-// CHECK: test_vreinterpretq_f32_p8
+// CHECK-LABEL: test_vreinterpretq_f32_p8
 float32x4_t test_vreinterpretq_f32_p8(poly8x16_t a) {
   return vreinterpretq_f32_p8(a);
 }
 
-// CHECK: test_vreinterpretq_f32_p16
+// CHECK-LABEL: test_vreinterpretq_f32_p16
 float32x4_t test_vreinterpretq_f32_p16(poly16x8_t a) {
   return vreinterpretq_f32_p16(a);
 }
 
-// CHECK: test_vreinterpretq_p8_s8
+// CHECK-LABEL: test_vreinterpretq_p8_s8
 poly8x16_t test_vreinterpretq_p8_s8(int8x16_t a) {
   return vreinterpretq_p8_s8(a);
 }
 
-// CHECK: test_vreinterpretq_p8_s16
+// CHECK-LABEL: test_vreinterpretq_p8_s16
 poly8x16_t test_vreinterpretq_p8_s16(int16x8_t a) {
   return vreinterpretq_p8_s16(a);
 }
 
-// CHECK: test_vreinterpretq_p8_s32
+// CHECK-LABEL: test_vreinterpretq_p8_s32
 poly8x16_t test_vreinterpretq_p8_s32(int32x4_t a) {
   return vreinterpretq_p8_s32(a);
 }
 
-// CHECK: test_vreinterpretq_p8_s64
+// CHECK-LABEL: test_vreinterpretq_p8_s64
 poly8x16_t test_vreinterpretq_p8_s64(int64x2_t a) {
   return vreinterpretq_p8_s64(a);
 }
 
-// CHECK: test_vreinterpretq_p8_u8
+// CHECK-LABEL: test_vreinterpretq_p8_u8
 poly8x16_t test_vreinterpretq_p8_u8(uint8x16_t a) {
   return vreinterpretq_p8_u8(a);
 }
 
-// CHECK: test_vreinterpretq_p8_u16
+// CHECK-LABEL: test_vreinterpretq_p8_u16
 poly8x16_t test_vreinterpretq_p8_u16(uint16x8_t a) {
   return vreinterpretq_p8_u16(a);
 }
 
-// CHECK: test_vreinterpretq_p8_u32
+// CHECK-LABEL: test_vreinterpretq_p8_u32
 poly8x16_t test_vreinterpretq_p8_u32(uint32x4_t a) {
   return vreinterpretq_p8_u32(a);
 }
 
-// CHECK: test_vreinterpretq_p8_u64
+// CHECK-LABEL: test_vreinterpretq_p8_u64
 poly8x16_t test_vreinterpretq_p8_u64(uint64x2_t a) {
   return vreinterpretq_p8_u64(a);
 }
 
-// CHECK: test_vreinterpretq_p8_f16
+// CHECK-LABEL: test_vreinterpretq_p8_f16
 poly8x16_t test_vreinterpretq_p8_f16(float16x8_t a) {
   return vreinterpretq_p8_f16(a);
 }
 
-// CHECK: test_vreinterpretq_p8_f32
+// CHECK-LABEL: test_vreinterpretq_p8_f32
 poly8x16_t test_vreinterpretq_p8_f32(float32x4_t a) {
   return vreinterpretq_p8_f32(a);
 }
 
-// CHECK: test_vreinterpretq_p8_p16
+// CHECK-LABEL: test_vreinterpretq_p8_p16
 poly8x16_t test_vreinterpretq_p8_p16(poly16x8_t a) {
   return vreinterpretq_p8_p16(a);
 }
 
-// CHECK: test_vreinterpretq_p16_s8
+// CHECK-LABEL: test_vreinterpretq_p16_s8
 poly16x8_t test_vreinterpretq_p16_s8(int8x16_t a) {
   return vreinterpretq_p16_s8(a);
 }
 
-// CHECK: test_vreinterpretq_p16_s16
+// CHECK-LABEL: test_vreinterpretq_p16_s16
 poly16x8_t test_vreinterpretq_p16_s16(int16x8_t a) {
   return vreinterpretq_p16_s16(a);
 }
 
-// CHECK: test_vreinterpretq_p16_s32
+// CHECK-LABEL: test_vreinterpretq_p16_s32
 poly16x8_t test_vreinterpretq_p16_s32(int32x4_t a) {
   return vreinterpretq_p16_s32(a);
 }
 
-// CHECK: test_vreinterpretq_p16_s64
+// CHECK-LABEL: test_vreinterpretq_p16_s64
 poly16x8_t test_vreinterpretq_p16_s64(int64x2_t a) {
   return vreinterpretq_p16_s64(a);
 }
 
-// CHECK: test_vreinterpretq_p16_u8
+// CHECK-LABEL: test_vreinterpretq_p16_u8
 poly16x8_t test_vreinterpretq_p16_u8(uint8x16_t a) {
   return vreinterpretq_p16_u8(a);
 }
 
-// CHECK: test_vreinterpretq_p16_u16
+// CHECK-LABEL: test_vreinterpretq_p16_u16
 poly16x8_t test_vreinterpretq_p16_u16(uint16x8_t a) {
   return vreinterpretq_p16_u16(a);
 }
 
-// CHECK: test_vreinterpretq_p16_u32
+// CHECK-LABEL: test_vreinterpretq_p16_u32
 poly16x8_t test_vreinterpretq_p16_u32(uint32x4_t a) {
   return vreinterpretq_p16_u32(a);
 }
 
-// CHECK: test_vreinterpretq_p16_u64
+// CHECK-LABEL: test_vreinterpretq_p16_u64
 poly16x8_t test_vreinterpretq_p16_u64(uint64x2_t a) {
   return vreinterpretq_p16_u64(a);
 }
 
-// CHECK: test_vreinterpretq_p16_f16
+// CHECK-LABEL: test_vreinterpretq_p16_f16
 poly16x8_t test_vreinterpretq_p16_f16(float16x8_t a) {
   return vreinterpretq_p16_f16(a);
 }
 
-// CHECK: test_vreinterpretq_p16_f32
+// CHECK-LABEL: test_vreinterpretq_p16_f32
 poly16x8_t test_vreinterpretq_p16_f32(float32x4_t a) {
   return vreinterpretq_p16_f32(a);
 }
 
-// CHECK: test_vreinterpretq_p16_p8
+// CHECK-LABEL: test_vreinterpretq_p16_p8
 poly16x8_t test_vreinterpretq_p16_p8(poly8x16_t a) {
   return vreinterpretq_p16_p8(a);
 }
 
 
-// CHECK: test_vrev16_s8
+// CHECK-LABEL: test_vrev16_s8
 // CHECK: vrev16.8 d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vrev16_s8(int8x8_t a) {
   return vrev16_s8(a);
 }
 
-// CHECK: test_vrev16_u8
+// CHECK-LABEL: test_vrev16_u8
 // CHECK: vrev16.8 d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vrev16_u8(uint8x8_t a) {
   return vrev16_u8(a);
 }
 
-// CHECK: test_vrev16_p8
+// CHECK-LABEL: test_vrev16_p8
 // CHECK: vrev16.8 d{{[0-9]+}}, d{{[0-9]+}}
 poly8x8_t test_vrev16_p8(poly8x8_t a) {
   return vrev16_p8(a);
 }
 
-// CHECK: test_vrev16q_s8
+// CHECK-LABEL: test_vrev16q_s8
 // CHECK: vrev16.8 q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vrev16q_s8(int8x16_t a) {
   return vrev16q_s8(a);
 }
 
-// CHECK: test_vrev16q_u8
+// CHECK-LABEL: test_vrev16q_u8
 // CHECK: vrev16.8 q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vrev16q_u8(uint8x16_t a) {
   return vrev16q_u8(a);
 }
 
-// CHECK: test_vrev16q_p8
+// CHECK-LABEL: test_vrev16q_p8
 // CHECK: vrev16.8 q{{[0-9]+}}, q{{[0-9]+}}
 poly8x16_t test_vrev16q_p8(poly8x16_t a) {
   return vrev16q_p8(a);
 }
 
 
-// CHECK: test_vrev32_s8
+// CHECK-LABEL: test_vrev32_s8
 // CHECK: vrev32.8 d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vrev32_s8(int8x8_t a) {
   return vrev32_s8(a);
 }
 
-// CHECK: test_vrev32_s16
+// CHECK-LABEL: test_vrev32_s16
 // CHECK: vrev32.16 d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vrev32_s16(int16x4_t a) {
   return vrev32_s16(a);
 }
 
-// CHECK: test_vrev32_u8
+// CHECK-LABEL: test_vrev32_u8
 // CHECK: vrev32.8 d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vrev32_u8(uint8x8_t a) {
   return vrev32_u8(a);
 }
 
-// CHECK: test_vrev32_u16
+// CHECK-LABEL: test_vrev32_u16
 // CHECK: vrev32.16 d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vrev32_u16(uint16x4_t a) {
   return vrev32_u16(a);
 }
 
-// CHECK: test_vrev32_p8
+// CHECK-LABEL: test_vrev32_p8
 // CHECK: vrev32.8 d{{[0-9]+}}, d{{[0-9]+}}
 poly8x8_t test_vrev32_p8(poly8x8_t a) {
   return vrev32_p8(a);
 }
 
-// CHECK: test_vrev32_p16
+// CHECK-LABEL: test_vrev32_p16
 // CHECK: vrev32.16 d{{[0-9]+}}, d{{[0-9]+}}
 poly16x4_t test_vrev32_p16(poly16x4_t a) {
   return vrev32_p16(a);
 }
 
-// CHECK: test_vrev32q_s8
+// CHECK-LABEL: test_vrev32q_s8
 // CHECK: vrev32.8 q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vrev32q_s8(int8x16_t a) {
   return vrev32q_s8(a);
 }
 
-// CHECK: test_vrev32q_s16
+// CHECK-LABEL: test_vrev32q_s16
 // CHECK: vrev32.16 q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vrev32q_s16(int16x8_t a) {
   return vrev32q_s16(a);
 }
 
-// CHECK: test_vrev32q_u8
+// CHECK-LABEL: test_vrev32q_u8
 // CHECK: vrev32.8 q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vrev32q_u8(uint8x16_t a) {
   return vrev32q_u8(a);
 }
 
-// CHECK: test_vrev32q_u16
+// CHECK-LABEL: test_vrev32q_u16
 // CHECK: vrev32.16 q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vrev32q_u16(uint16x8_t a) {
   return vrev32q_u16(a);
 }
 
-// CHECK: test_vrev32q_p8
+// CHECK-LABEL: test_vrev32q_p8
 // CHECK: vrev32.8 q{{[0-9]+}}, q{{[0-9]+}}
 poly8x16_t test_vrev32q_p8(poly8x16_t a) {
   return vrev32q_p8(a);
 }
 
-// CHECK: test_vrev32q_p16
+// CHECK-LABEL: test_vrev32q_p16
 // CHECK: vrev32.16 q{{[0-9]+}}, q{{[0-9]+}}
 poly16x8_t test_vrev32q_p16(poly16x8_t a) {
   return vrev32q_p16(a);
 }
 
 
-// CHECK: test_vrev64_s8
+// CHECK-LABEL: test_vrev64_s8
 // CHECK: vrev64.8 d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vrev64_s8(int8x8_t a) {
   return vrev64_s8(a);
 }
 
-// CHECK: test_vrev64_s16
+// CHECK-LABEL: test_vrev64_s16
 // CHECK: vrev64.16 d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vrev64_s16(int16x4_t a) {
   return vrev64_s16(a);
 }
 
-// CHECK: test_vrev64_s32
+// CHECK-LABEL: test_vrev64_s32
 // CHECK: vrev64.32 d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vrev64_s32(int32x2_t a) {
   return vrev64_s32(a);
 }
 
-// CHECK: test_vrev64_u8
+// CHECK-LABEL: test_vrev64_u8
 // CHECK: vrev64.8 d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vrev64_u8(uint8x8_t a) {
   return vrev64_u8(a);
 }
 
-// CHECK: test_vrev64_u16
+// CHECK-LABEL: test_vrev64_u16
 // CHECK: vrev64.16 d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vrev64_u16(uint16x4_t a) {
   return vrev64_u16(a);
 }
 
-// CHECK: test_vrev64_u32
+// CHECK-LABEL: test_vrev64_u32
 // CHECK: vrev64.32 d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vrev64_u32(uint32x2_t a) {
   return vrev64_u32(a);
 }
 
-// CHECK: test_vrev64_p8
+// CHECK-LABEL: test_vrev64_p8
 // CHECK: vrev64.8 d{{[0-9]+}}, d{{[0-9]+}}
 poly8x8_t test_vrev64_p8(poly8x8_t a) {
   return vrev64_p8(a);
 }
 
-// CHECK: test_vrev64_p16
+// CHECK-LABEL: test_vrev64_p16
 // CHECK: vrev64.16 d{{[0-9]+}}, d{{[0-9]+}}
 poly16x4_t test_vrev64_p16(poly16x4_t a) {
   return vrev64_p16(a);
 }
 
-// CHECK: test_vrev64_f32
+// CHECK-LABEL: test_vrev64_f32
 // CHECK: vrev64.32 d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vrev64_f32(float32x2_t a) {
   return vrev64_f32(a);
 }
 
-// CHECK: test_vrev64q_s8
+// CHECK-LABEL: test_vrev64q_s8
 // CHECK: vrev64.8 q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vrev64q_s8(int8x16_t a) {
   return vrev64q_s8(a);
 }
 
-// CHECK: test_vrev64q_s16
+// CHECK-LABEL: test_vrev64q_s16
 // CHECK: vrev64.16 q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vrev64q_s16(int16x8_t a) {
   return vrev64q_s16(a);
 }
 
-// CHECK: test_vrev64q_s32
+// CHECK-LABEL: test_vrev64q_s32
 // CHECK: vrev64.32 q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vrev64q_s32(int32x4_t a) {
   return vrev64q_s32(a);
 }
 
-// CHECK: test_vrev64q_u8
+// CHECK-LABEL: test_vrev64q_u8
 // CHECK: vrev64.8 q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vrev64q_u8(uint8x16_t a) {
   return vrev64q_u8(a);
 }
 
-// CHECK: test_vrev64q_u16
+// CHECK-LABEL: test_vrev64q_u16
 // CHECK: vrev64.16 q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vrev64q_u16(uint16x8_t a) {
   return vrev64q_u16(a);
 }
 
-// CHECK: test_vrev64q_u32
+// CHECK-LABEL: test_vrev64q_u32
 // CHECK: vrev64.32 q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vrev64q_u32(uint32x4_t a) {
   return vrev64q_u32(a);
 }
 
-// CHECK: test_vrev64q_p8
+// CHECK-LABEL: test_vrev64q_p8
 // CHECK: vrev64.8 q{{[0-9]+}}, q{{[0-9]+}}
 poly8x16_t test_vrev64q_p8(poly8x16_t a) {
   return vrev64q_p8(a);
 }
 
-// CHECK: test_vrev64q_p16
+// CHECK-LABEL: test_vrev64q_p16
 // CHECK: vrev64.16 q{{[0-9]+}}, q{{[0-9]+}}
 poly16x8_t test_vrev64q_p16(poly16x8_t a) {
   return vrev64q_p16(a);
 }
 
-// CHECK: test_vrev64q_f32
+// CHECK-LABEL: test_vrev64q_f32
 // CHECK: vrev64.32 q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vrev64q_f32(float32x4_t a) {
   return vrev64q_f32(a);
 }
 
 
-// CHECK: test_vrhadd_s8
+// CHECK-LABEL: test_vrhadd_s8
 // CHECK: vrhadd.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vrhadd_s8(int8x8_t a, int8x8_t b) {
   return vrhadd_s8(a, b);
 }
 
-// CHECK: test_vrhadd_s16
+// CHECK-LABEL: test_vrhadd_s16
 // CHECK: vrhadd.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vrhadd_s16(int16x4_t a, int16x4_t b) {
   return vrhadd_s16(a, b);
 }
 
-// CHECK: test_vrhadd_s32
+// CHECK-LABEL: test_vrhadd_s32
 // CHECK: vrhadd.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vrhadd_s32(int32x2_t a, int32x2_t b) {
   return vrhadd_s32(a, b);
 }
 
-// CHECK: test_vrhadd_u8
+// CHECK-LABEL: test_vrhadd_u8
 // CHECK: vrhadd.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vrhadd_u8(uint8x8_t a, uint8x8_t b) {
   return vrhadd_u8(a, b);
 }
 
-// CHECK: test_vrhadd_u16
+// CHECK-LABEL: test_vrhadd_u16
 // CHECK: vrhadd.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vrhadd_u16(uint16x4_t a, uint16x4_t b) {
   return vrhadd_u16(a, b);
 }
 
-// CHECK: test_vrhadd_u32
+// CHECK-LABEL: test_vrhadd_u32
 // CHECK: vrhadd.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vrhadd_u32(uint32x2_t a, uint32x2_t b) {
   return vrhadd_u32(a, b);
 }
 
-// CHECK: test_vrhaddq_s8
+// CHECK-LABEL: test_vrhaddq_s8
 // CHECK: vrhadd.s8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vrhaddq_s8(int8x16_t a, int8x16_t b) {
   return vrhaddq_s8(a, b);
 }
 
-// CHECK: test_vrhaddq_s16
+// CHECK-LABEL: test_vrhaddq_s16
 // CHECK: vrhadd.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vrhaddq_s16(int16x8_t a, int16x8_t b) {
   return vrhaddq_s16(a, b);
 }
 
-// CHECK: test_vrhaddq_s32
+// CHECK-LABEL: test_vrhaddq_s32
 // CHECK: vrhadd.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vrhaddq_s32(int32x4_t a, int32x4_t b) {
   return vrhaddq_s32(a, b);
 }
 
-// CHECK: test_vrhaddq_u8
+// CHECK-LABEL: test_vrhaddq_u8
 // CHECK: vrhadd.u8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vrhaddq_u8(uint8x16_t a, uint8x16_t b) {
   return vrhaddq_u8(a, b);
 }
 
-// CHECK: test_vrhaddq_u16
+// CHECK-LABEL: test_vrhaddq_u16
 // CHECK: vrhadd.u16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vrhaddq_u16(uint16x8_t a, uint16x8_t b) {
   return vrhaddq_u16(a, b);
 }
 
-// CHECK: test_vrhaddq_u32
+// CHECK-LABEL: test_vrhaddq_u32
 // CHECK: vrhadd.u32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vrhaddq_u32(uint32x4_t a, uint32x4_t b) {
   return vrhaddq_u32(a, b);
 }
 
 
-// CHECK: test_vrshl_s8
+// CHECK-LABEL: test_vrshl_s8
 // CHECK: vrshl.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vrshl_s8(int8x8_t a, int8x8_t b) {
   return vrshl_s8(a, b);
 }
 
-// CHECK: test_vrshl_s16
+// CHECK-LABEL: test_vrshl_s16
 // CHECK: vrshl.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vrshl_s16(int16x4_t a, int16x4_t b) {
   return vrshl_s16(a, b);
 }
 
-// CHECK: test_vrshl_s32
+// CHECK-LABEL: test_vrshl_s32
 // CHECK: vrshl.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vrshl_s32(int32x2_t a, int32x2_t b) {
   return vrshl_s32(a, b);
 }
 
-// CHECK: test_vrshl_s64
+// CHECK-LABEL: test_vrshl_s64
 // CHECK: vrshl.s64 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x1_t test_vrshl_s64(int64x1_t a, int64x1_t b) {
   return vrshl_s64(a, b);
 }
 
-// CHECK: test_vrshl_u8
+// CHECK-LABEL: test_vrshl_u8
 // CHECK: vrshl.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vrshl_u8(uint8x8_t a, int8x8_t b) {
   return vrshl_u8(a, b);
 }
 
-// CHECK: test_vrshl_u16
+// CHECK-LABEL: test_vrshl_u16
 // CHECK: vrshl.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vrshl_u16(uint16x4_t a, int16x4_t b) {
   return vrshl_u16(a, b);
 }
 
-// CHECK: test_vrshl_u32
+// CHECK-LABEL: test_vrshl_u32
 // CHECK: vrshl.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vrshl_u32(uint32x2_t a, int32x2_t b) {
   return vrshl_u32(a, b);
 }
 
-// CHECK: test_vrshl_u64
+// CHECK-LABEL: test_vrshl_u64
 // CHECK: vrshl.u64 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x1_t test_vrshl_u64(uint64x1_t a, int64x1_t b) {
   return vrshl_u64(a, b);
 }
 
-// CHECK: test_vrshlq_s8
+// CHECK-LABEL: test_vrshlq_s8
 // CHECK: vrshl.s8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vrshlq_s8(int8x16_t a, int8x16_t b) {
   return vrshlq_s8(a, b);
 }
 
-// CHECK: test_vrshlq_s16
+// CHECK-LABEL: test_vrshlq_s16
 // CHECK: vrshl.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vrshlq_s16(int16x8_t a, int16x8_t b) {
   return vrshlq_s16(a, b);
 }
 
-// CHECK: test_vrshlq_s32
+// CHECK-LABEL: test_vrshlq_s32
 // CHECK: vrshl.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vrshlq_s32(int32x4_t a, int32x4_t b) {
   return vrshlq_s32(a, b);
 }
 
-// CHECK: test_vrshlq_s64
+// CHECK-LABEL: test_vrshlq_s64
 // CHECK: vrshl.s64 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int64x2_t test_vrshlq_s64(int64x2_t a, int64x2_t b) {
   return vrshlq_s64(a, b);
 }
 
-// CHECK: test_vrshlq_u8
+// CHECK-LABEL: test_vrshlq_u8
 // CHECK: vrshl.u8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vrshlq_u8(uint8x16_t a, int8x16_t b) {
   return vrshlq_u8(a, b);
 }
 
-// CHECK: test_vrshlq_u16
+// CHECK-LABEL: test_vrshlq_u16
 // CHECK: vrshl.u16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vrshlq_u16(uint16x8_t a, int16x8_t b) {
   return vrshlq_u16(a, b);
 }
 
-// CHECK: test_vrshlq_u32
+// CHECK-LABEL: test_vrshlq_u32
 // CHECK: vrshl.u32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vrshlq_u32(uint32x4_t a, int32x4_t b) {
   return vrshlq_u32(a, b);
 }
 
-// CHECK: test_vrshlq_u64
+// CHECK-LABEL: test_vrshlq_u64
 // CHECK: vrshl.u64 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint64x2_t test_vrshlq_u64(uint64x2_t a, int64x2_t b) {
   return vrshlq_u64(a, b);
 }
 
 
-// CHECK: test_vrshrn_n_s16
+// CHECK-LABEL: test_vrshrn_n_s16
 // CHECK: vrshrn.i16 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int8x8_t test_vrshrn_n_s16(int16x8_t a) {
   return vrshrn_n_s16(a, 1);
 }
 
-// CHECK: test_vrshrn_n_s32
+// CHECK-LABEL: test_vrshrn_n_s32
 // CHECK: vrshrn.i32 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int16x4_t test_vrshrn_n_s32(int32x4_t a) {
   return vrshrn_n_s32(a, 1);
 }
 
-// CHECK: test_vrshrn_n_s64
+// CHECK-LABEL: test_vrshrn_n_s64
 // CHECK: vrshrn.i64 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int32x2_t test_vrshrn_n_s64(int64x2_t a) {
   return vrshrn_n_s64(a, 1);
 }
 
-// CHECK: test_vrshrn_n_u16
+// CHECK-LABEL: test_vrshrn_n_u16
 // CHECK: vrshrn.i16 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint8x8_t test_vrshrn_n_u16(uint16x8_t a) {
   return vrshrn_n_u16(a, 1);
 }
 
-// CHECK: test_vrshrn_n_u32
+// CHECK-LABEL: test_vrshrn_n_u32
 // CHECK: vrshrn.i32 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint16x4_t test_vrshrn_n_u32(uint32x4_t a) {
   return vrshrn_n_u32(a, 1);
 }
 
-// CHECK: test_vrshrn_n_u64
+// CHECK-LABEL: test_vrshrn_n_u64
 // CHECK: vrshrn.i64 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint32x2_t test_vrshrn_n_u64(uint64x2_t a) {
   return vrshrn_n_u64(a, 1);
 }
 
 
-// CHECK: test_vrshr_n_s8
+// CHECK-LABEL: test_vrshr_n_s8
 // CHECK: vrshr.s8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int8x8_t test_vrshr_n_s8(int8x8_t a) {
   return vrshr_n_s8(a, 1);
 }
 
-// CHECK: test_vrshr_n_s16
+// CHECK-LABEL: test_vrshr_n_s16
 // CHECK: vrshr.s16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int16x4_t test_vrshr_n_s16(int16x4_t a) {
   return vrshr_n_s16(a, 1);
 }
 
-// CHECK: test_vrshr_n_s32
+// CHECK-LABEL: test_vrshr_n_s32
 // CHECK: vrshr.s32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int32x2_t test_vrshr_n_s32(int32x2_t a) {
   return vrshr_n_s32(a, 1);
 }
 
-// CHECK: test_vrshr_n_s64
+// CHECK-LABEL: test_vrshr_n_s64
 // CHECK: vrshr.s64 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int64x1_t test_vrshr_n_s64(int64x1_t a) {
   return vrshr_n_s64(a, 1);
 }
 
-// CHECK: test_vrshr_n_u8
+// CHECK-LABEL: test_vrshr_n_u8
 // CHECK: vrshr.u8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint8x8_t test_vrshr_n_u8(uint8x8_t a) {
   return vrshr_n_u8(a, 1);
 }
 
-// CHECK: test_vrshr_n_u16
+// CHECK-LABEL: test_vrshr_n_u16
 // CHECK: vrshr.u16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint16x4_t test_vrshr_n_u16(uint16x4_t a) {
   return vrshr_n_u16(a, 1);
 }
 
-// CHECK: test_vrshr_n_u32
+// CHECK-LABEL: test_vrshr_n_u32
 // CHECK: vrshr.u32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint32x2_t test_vrshr_n_u32(uint32x2_t a) {
   return vrshr_n_u32(a, 1);
 }
 
-// CHECK: test_vrshr_n_u64
+// CHECK-LABEL: test_vrshr_n_u64
 // CHECK: vrshr.u64 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint64x1_t test_vrshr_n_u64(uint64x1_t a) {
   return vrshr_n_u64(a, 1);
 }
 
-// CHECK: test_vrshrq_n_s8
+// CHECK-LABEL: test_vrshrq_n_s8
 // CHECK: vrshr.s8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int8x16_t test_vrshrq_n_s8(int8x16_t a) {
   return vrshrq_n_s8(a, 1);
 }
 
-// CHECK: test_vrshrq_n_s16
+// CHECK-LABEL: test_vrshrq_n_s16
 // CHECK: vrshr.s16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int16x8_t test_vrshrq_n_s16(int16x8_t a) {
   return vrshrq_n_s16(a, 1);
 }
 
-// CHECK: test_vrshrq_n_s32
+// CHECK-LABEL: test_vrshrq_n_s32
 // CHECK: vrshr.s32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int32x4_t test_vrshrq_n_s32(int32x4_t a) {
   return vrshrq_n_s32(a, 1);
 }
 
-// CHECK: test_vrshrq_n_s64
+// CHECK-LABEL: test_vrshrq_n_s64
 // CHECK: vrshr.s64 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int64x2_t test_vrshrq_n_s64(int64x2_t a) {
   return vrshrq_n_s64(a, 1);
 }
 
-// CHECK: test_vrshrq_n_u8
+// CHECK-LABEL: test_vrshrq_n_u8
 // CHECK: vrshr.u8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint8x16_t test_vrshrq_n_u8(uint8x16_t a) {
   return vrshrq_n_u8(a, 1);
 }
 
-// CHECK: test_vrshrq_n_u16
+// CHECK-LABEL: test_vrshrq_n_u16
 // CHECK: vrshr.u16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint16x8_t test_vrshrq_n_u16(uint16x8_t a) {
   return vrshrq_n_u16(a, 1);
 }
 
-// CHECK: test_vrshrq_n_u32
+// CHECK-LABEL: test_vrshrq_n_u32
 // CHECK: vrshr.u32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint32x4_t test_vrshrq_n_u32(uint32x4_t a) {
   return vrshrq_n_u32(a, 1);
 }
 
-// CHECK: test_vrshrq_n_u64
+// CHECK-LABEL: test_vrshrq_n_u64
 // CHECK: vrshr.u64 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint64x2_t test_vrshrq_n_u64(uint64x2_t a) {
   return vrshrq_n_u64(a, 1);
 }
 
 
-// CHECK: test_vrsqrte_f32
+// CHECK-LABEL: test_vrsqrte_f32
 // CHECK: vrsqrte.f32 d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vrsqrte_f32(float32x2_t a) {
   return vrsqrte_f32(a);
 }
 
-// CHECK: test_vrsqrte_u32
+// CHECK-LABEL: test_vrsqrte_u32
 // CHECK: vrsqrte.u32 d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vrsqrte_u32(uint32x2_t a) {
   return vrsqrte_u32(a);
 }
 
-// CHECK: test_vrsqrteq_f32
+// CHECK-LABEL: test_vrsqrteq_f32
 // CHECK: vrsqrte.f32 q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vrsqrteq_f32(float32x4_t a) {
   return vrsqrteq_f32(a);
 }
 
-// CHECK: test_vrsqrteq_u32
+// CHECK-LABEL: test_vrsqrteq_u32
 // CHECK: vrsqrte.u32 q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vrsqrteq_u32(uint32x4_t a) {
   return vrsqrteq_u32(a);
 }
 
 
-// CHECK: test_vrsqrts_f32
+// CHECK-LABEL: test_vrsqrts_f32
 // CHECK: vrsqrts.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vrsqrts_f32(float32x2_t a, float32x2_t b) {
   return vrsqrts_f32(a, b);
 }
 
-// CHECK: test_vrsqrtsq_f32
+// CHECK-LABEL: test_vrsqrtsq_f32
 // CHECK: vrsqrts.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vrsqrtsq_f32(float32x4_t a, float32x4_t b) {
   return vrsqrtsq_f32(a, b);
 }
 
 
-// CHECK: test_vrsra_n_s8
+// CHECK-LABEL: test_vrsra_n_s8
 // CHECK: vrsra.s8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int8x8_t test_vrsra_n_s8(int8x8_t a, int8x8_t b) {
   return vrsra_n_s8(a, b, 1);
 }
 
-// CHECK: test_vrsra_n_s16
+// CHECK-LABEL: test_vrsra_n_s16
 // CHECK: vrsra.s16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int16x4_t test_vrsra_n_s16(int16x4_t a, int16x4_t b) {
   return vrsra_n_s16(a, b, 1);
 }
 
-// CHECK: test_vrsra_n_s32
+// CHECK-LABEL: test_vrsra_n_s32
 // CHECK: vrsra.s32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int32x2_t test_vrsra_n_s32(int32x2_t a, int32x2_t b) {
   return vrsra_n_s32(a, b, 1);
 }
 
-// CHECK: test_vrsra_n_s64
+// CHECK-LABEL: test_vrsra_n_s64
 // CHECK: vrsra.s64 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int64x1_t test_vrsra_n_s64(int64x1_t a, int64x1_t b) {
   return vrsra_n_s64(a, b, 1);
 }
 
-// CHECK: test_vrsra_n_u8
+// CHECK-LABEL: test_vrsra_n_u8
 // CHECK: vrsra.u8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint8x8_t test_vrsra_n_u8(uint8x8_t a, uint8x8_t b) {
   return vrsra_n_u8(a, b, 1);
 }
 
-// CHECK: test_vrsra_n_u16
+// CHECK-LABEL: test_vrsra_n_u16
 // CHECK: vrsra.u16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint16x4_t test_vrsra_n_u16(uint16x4_t a, uint16x4_t b) {
   return vrsra_n_u16(a, b, 1);
 }
 
-// CHECK: test_vrsra_n_u32
+// CHECK-LABEL: test_vrsra_n_u32
 // CHECK: vrsra.u32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint32x2_t test_vrsra_n_u32(uint32x2_t a, uint32x2_t b) {
   return vrsra_n_u32(a, b, 1);
 }
 
-// CHECK: test_vrsra_n_u64
+// CHECK-LABEL: test_vrsra_n_u64
 // CHECK: vrsra.u64 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint64x1_t test_vrsra_n_u64(uint64x1_t a, uint64x1_t b) {
   return vrsra_n_u64(a, b, 1);
 }
 
-// CHECK: test_vrsraq_n_s8
+// CHECK-LABEL: test_vrsraq_n_s8
 // CHECK: vrsra.s8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int8x16_t test_vrsraq_n_s8(int8x16_t a, int8x16_t b) {
   return vrsraq_n_s8(a, b, 1);
 }
 
-// CHECK: test_vrsraq_n_s16
+// CHECK-LABEL: test_vrsraq_n_s16
 // CHECK: vrsra.s16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int16x8_t test_vrsraq_n_s16(int16x8_t a, int16x8_t b) {
   return vrsraq_n_s16(a, b, 1);
 }
 
-// CHECK: test_vrsraq_n_s32
+// CHECK-LABEL: test_vrsraq_n_s32
 // CHECK: vrsra.s32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int32x4_t test_vrsraq_n_s32(int32x4_t a, int32x4_t b) {
   return vrsraq_n_s32(a, b, 1);
 }
 
-// CHECK: test_vrsraq_n_s64
+// CHECK-LABEL: test_vrsraq_n_s64
 // CHECK: vrsra.s64 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int64x2_t test_vrsraq_n_s64(int64x2_t a, int64x2_t b) {
   return vrsraq_n_s64(a, b, 1);
 }
 
-// CHECK: test_vrsraq_n_u8
+// CHECK-LABEL: test_vrsraq_n_u8
 // CHECK: vrsra.u8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint8x16_t test_vrsraq_n_u8(uint8x16_t a, uint8x16_t b) {
   return vrsraq_n_u8(a, b, 1);
 }
 
-// CHECK: test_vrsraq_n_u16
+// CHECK-LABEL: test_vrsraq_n_u16
 // CHECK: vrsra.u16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint16x8_t test_vrsraq_n_u16(uint16x8_t a, uint16x8_t b) {
   return vrsraq_n_u16(a, b, 1);
 }
 
-// CHECK: test_vrsraq_n_u32
+// CHECK-LABEL: test_vrsraq_n_u32
 // CHECK: vrsra.u32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint32x4_t test_vrsraq_n_u32(uint32x4_t a, uint32x4_t b) {
   return vrsraq_n_u32(a, b, 1);
 }
 
-// CHECK: test_vrsraq_n_u64
+// CHECK-LABEL: test_vrsraq_n_u64
 // CHECK: vrsra.u64 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint64x2_t test_vrsraq_n_u64(uint64x2_t a, uint64x2_t b) {
   return vrsraq_n_u64(a, b, 1);
 }
 
 
-// CHECK: test_vrsubhn_s16
+// CHECK-LABEL: test_vrsubhn_s16
 // CHECK: vrsubhn.i16 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x8_t test_vrsubhn_s16(int16x8_t a, int16x8_t b) {
   return vrsubhn_s16(a, b);
 }
 
-// CHECK: test_vrsubhn_s32
+// CHECK-LABEL: test_vrsubhn_s32
 // CHECK: vrsubhn.i32 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x4_t test_vrsubhn_s32(int32x4_t a, int32x4_t b) {
   return vrsubhn_s32(a, b);
 }
 
-// CHECK: test_vrsubhn_s64
+// CHECK-LABEL: test_vrsubhn_s64
 // CHECK: vrsubhn.i64 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x2_t test_vrsubhn_s64(int64x2_t a, int64x2_t b) {
   return vrsubhn_s64(a, b);
 }
 
-// CHECK: test_vrsubhn_u16
+// CHECK-LABEL: test_vrsubhn_u16
 // CHECK: vrsubhn.i16 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x8_t test_vrsubhn_u16(uint16x8_t a, uint16x8_t b) {
   return vrsubhn_u16(a, b);
 }
 
-// CHECK: test_vrsubhn_u32
+// CHECK-LABEL: test_vrsubhn_u32
 // CHECK: vrsubhn.i32 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x4_t test_vrsubhn_u32(uint32x4_t a, uint32x4_t b) {
   return vrsubhn_u32(a, b);
 }
 
-// CHECK: test_vrsubhn_u64
+// CHECK-LABEL: test_vrsubhn_u64
 // CHECK: vrsubhn.i64 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x2_t test_vrsubhn_u64(uint64x2_t a, uint64x2_t b) {
   return vrsubhn_u64(a, b);
 }
 
 
-// CHECK: test_vset_lane_u8
+// CHECK-LABEL: test_vset_lane_u8
 // CHECK: vmov 
 uint8x8_t test_vset_lane_u8(uint8_t a, uint8x8_t b) {
   return vset_lane_u8(a, b, 7);
 }
 
-// CHECK: test_vset_lane_u16
+// CHECK-LABEL: test_vset_lane_u16
 // CHECK: vmov 
 uint16x4_t test_vset_lane_u16(uint16_t a, uint16x4_t b) {
   return vset_lane_u16(a, b, 3);
 }
 
-// CHECK: test_vset_lane_u32
+// CHECK-LABEL: test_vset_lane_u32
 // CHECK: vmov 
 uint32x2_t test_vset_lane_u32(uint32_t a, uint32x2_t b) {
   return vset_lane_u32(a, b, 1);
 }
 
-// CHECK: test_vset_lane_s8
+// CHECK-LABEL: test_vset_lane_s8
 // CHECK: vmov 
 int8x8_t test_vset_lane_s8(int8_t a, int8x8_t b) {
   return vset_lane_s8(a, b, 7);
 }
 
-// CHECK: test_vset_lane_s16
+// CHECK-LABEL: test_vset_lane_s16
 // CHECK: vmov 
 int16x4_t test_vset_lane_s16(int16_t a, int16x4_t b) {
   return vset_lane_s16(a, b, 3);
 }
 
-// CHECK: test_vset_lane_s32
+// CHECK-LABEL: test_vset_lane_s32
 // CHECK: vmov 
 int32x2_t test_vset_lane_s32(int32_t a, int32x2_t b) {
   return vset_lane_s32(a, b, 1);
 }
 
-// CHECK: test_vset_lane_p8
+// CHECK-LABEL: test_vset_lane_p8
 // CHECK: vmov 
 poly8x8_t test_vset_lane_p8(poly8_t a, poly8x8_t b) {
   return vset_lane_p8(a, b, 7);
 }
 
-// CHECK: test_vset_lane_p16
+// CHECK-LABEL: test_vset_lane_p16
 // CHECK: vmov 
 poly16x4_t test_vset_lane_p16(poly16_t a, poly16x4_t b) {
   return vset_lane_p16(a, b, 3);
 }
 
-// CHECK: test_vset_lane_f32
+// CHECK-LABEL: test_vset_lane_f32
 // CHECK: vmov 
 float32x2_t test_vset_lane_f32(float32_t a, float32x2_t b) {
   return vset_lane_f32(a, b, 1);
 }
 
-// CHECK: test_vsetq_lane_u8
+// CHECK-LABEL: test_vsetq_lane_u8
 // CHECK: vmov 
 uint8x16_t test_vsetq_lane_u8(uint8_t a, uint8x16_t b) {
   return vsetq_lane_u8(a, b, 15);
 }
 
-// CHECK: test_vsetq_lane_u16
+// CHECK-LABEL: test_vsetq_lane_u16
 // CHECK: vmov 
 uint16x8_t test_vsetq_lane_u16(uint16_t a, uint16x8_t b) {
   return vsetq_lane_u16(a, b, 7);
 }
 
-// CHECK: test_vsetq_lane_u32
+// CHECK-LABEL: test_vsetq_lane_u32
 // CHECK: vmov 
 uint32x4_t test_vsetq_lane_u32(uint32_t a, uint32x4_t b) {
   return vsetq_lane_u32(a, b, 3);
 }
 
-// CHECK: test_vsetq_lane_s8
+// CHECK-LABEL: test_vsetq_lane_s8
 // CHECK: vmov 
 int8x16_t test_vsetq_lane_s8(int8_t a, int8x16_t b) {
   return vsetq_lane_s8(a, b, 15);
 }
 
-// CHECK: test_vsetq_lane_s16
+// CHECK-LABEL: test_vsetq_lane_s16
 // CHECK: vmov 
 int16x8_t test_vsetq_lane_s16(int16_t a, int16x8_t b) {
   return vsetq_lane_s16(a, b, 7);
 }
 
-// CHECK: test_vsetq_lane_s32
+// CHECK-LABEL: test_vsetq_lane_s32
 // CHECK: vmov 
 int32x4_t test_vsetq_lane_s32(int32_t a, int32x4_t b) {
   return vsetq_lane_s32(a, b, 3);
 }
 
-// CHECK: test_vsetq_lane_p8
+// CHECK-LABEL: test_vsetq_lane_p8
 // CHECK: vmov 
 poly8x16_t test_vsetq_lane_p8(poly8_t a, poly8x16_t b) {
   return vsetq_lane_p8(a, b, 15);
 }
 
-// CHECK: test_vsetq_lane_p16
+// CHECK-LABEL: test_vsetq_lane_p16
 // CHECK: vmov 
 poly16x8_t test_vsetq_lane_p16(poly16_t a, poly16x8_t b) {
   return vsetq_lane_p16(a, b, 7);
 }
 
-// CHECK: test_vsetq_lane_f32
+// CHECK-LABEL: test_vsetq_lane_f32
 // CHECK: vmov 
 float32x4_t test_vsetq_lane_f32(float32_t a, float32x4_t b) {
   return vsetq_lane_f32(a, b, 3);
 }
 
-// CHECK: test_vset_lane_s64
+// CHECK-LABEL: test_vset_lane_s64
 // CHECK: vmov 
 int64x1_t test_vset_lane_s64(int64_t a, int64x1_t b) {
   return vset_lane_s64(a, b, 0);
 }
 
-// CHECK: test_vset_lane_u64
+// CHECK-LABEL: test_vset_lane_u64
 // CHECK: vmov 
 uint64x1_t test_vset_lane_u64(uint64_t a, uint64x1_t b) {
   return vset_lane_u64(a, b, 0);
 }
 
-// CHECK: test_vsetq_lane_s64
+// CHECK-LABEL: test_vsetq_lane_s64
 // CHECK: vmov 
 int64x2_t test_vsetq_lane_s64(int64_t a, int64x2_t b) {
   return vsetq_lane_s64(a, b, 1);
 }
 
-// CHECK: test_vsetq_lane_u64
+// CHECK-LABEL: test_vsetq_lane_u64
 // CHECK: vmov 
 uint64x2_t test_vsetq_lane_u64(uint64_t a, uint64x2_t b) {
   return vsetq_lane_u64(a, b, 1);
 }
 
 
-// CHECK: test_vshl_s8
+// CHECK-LABEL: test_vshl_s8
 // CHECK: vshl.s8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vshl_s8(int8x8_t a, int8x8_t b) {
   return vshl_s8(a, b);
 }
 
-// CHECK: test_vshl_s16
+// CHECK-LABEL: test_vshl_s16
 // CHECK: vshl.s16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vshl_s16(int16x4_t a, int16x4_t b) {
   return vshl_s16(a, b);
 }
 
-// CHECK: test_vshl_s32
+// CHECK-LABEL: test_vshl_s32
 // CHECK: vshl.s32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vshl_s32(int32x2_t a, int32x2_t b) {
   return vshl_s32(a, b);
 }
 
-// CHECK: test_vshl_s64
+// CHECK-LABEL: test_vshl_s64
 // CHECK: vshl.s64 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x1_t test_vshl_s64(int64x1_t a, int64x1_t b) {
   return vshl_s64(a, b);
 }
 
-// CHECK: test_vshl_u8
+// CHECK-LABEL: test_vshl_u8
 // CHECK: vshl.u8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vshl_u8(uint8x8_t a, int8x8_t b) {
   return vshl_u8(a, b);
 }
 
-// CHECK: test_vshl_u16
+// CHECK-LABEL: test_vshl_u16
 // CHECK: vshl.u16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vshl_u16(uint16x4_t a, int16x4_t b) {
   return vshl_u16(a, b);
 }
 
-// CHECK: test_vshl_u32
+// CHECK-LABEL: test_vshl_u32
 // CHECK: vshl.u32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vshl_u32(uint32x2_t a, int32x2_t b) {
   return vshl_u32(a, b);
 }
 
-// CHECK: test_vshl_u64
+// CHECK-LABEL: test_vshl_u64
 // CHECK: vshl.u64 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x1_t test_vshl_u64(uint64x1_t a, int64x1_t b) {
   return vshl_u64(a, b);
 }
 
-// CHECK: test_vshlq_s8
+// CHECK-LABEL: test_vshlq_s8
 // CHECK: vshl.s8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vshlq_s8(int8x16_t a, int8x16_t b) {
   return vshlq_s8(a, b);
 }
 
-// CHECK: test_vshlq_s16
+// CHECK-LABEL: test_vshlq_s16
 // CHECK: vshl.s16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vshlq_s16(int16x8_t a, int16x8_t b) {
   return vshlq_s16(a, b);
 }
 
-// CHECK: test_vshlq_s32
+// CHECK-LABEL: test_vshlq_s32
 // CHECK: vshl.s32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vshlq_s32(int32x4_t a, int32x4_t b) {
   return vshlq_s32(a, b);
 }
 
-// CHECK: test_vshlq_s64
+// CHECK-LABEL: test_vshlq_s64
 // CHECK: vshl.s64 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int64x2_t test_vshlq_s64(int64x2_t a, int64x2_t b) {
   return vshlq_s64(a, b);
 }
 
-// CHECK: test_vshlq_u8
+// CHECK-LABEL: test_vshlq_u8
 // CHECK: vshl.u8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vshlq_u8(uint8x16_t a, int8x16_t b) {
   return vshlq_u8(a, b);
 }
 
-// CHECK: test_vshlq_u16
+// CHECK-LABEL: test_vshlq_u16
 // CHECK: vshl.u16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vshlq_u16(uint16x8_t a, int16x8_t b) {
   return vshlq_u16(a, b);
 }
 
-// CHECK: test_vshlq_u32
+// CHECK-LABEL: test_vshlq_u32
 // CHECK: vshl.u32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vshlq_u32(uint32x4_t a, int32x4_t b) {
   return vshlq_u32(a, b);
 }
 
-// CHECK: test_vshlq_u64
+// CHECK-LABEL: test_vshlq_u64
 // CHECK: vshl.u64 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint64x2_t test_vshlq_u64(uint64x2_t a, int64x2_t b) {
   return vshlq_u64(a, b);
 }
 
 
-// CHECK: test_vshll_n_s8
+// CHECK-LABEL: test_vshll_n_s8
 // CHECK: vshll.s8 q{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int16x8_t test_vshll_n_s8(int8x8_t a) {
   return vshll_n_s8(a, 1);
 }
 
-// CHECK: test_vshll_n_s16
+// CHECK-LABEL: test_vshll_n_s16
 // CHECK: vshll.s16 q{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int32x4_t test_vshll_n_s16(int16x4_t a) {
   return vshll_n_s16(a, 1);
 }
 
-// CHECK: test_vshll_n_s32
+// CHECK-LABEL: test_vshll_n_s32
 // CHECK: vshll.s32 q{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int64x2_t test_vshll_n_s32(int32x2_t a) {
   return vshll_n_s32(a, 1);
 }
 
-// CHECK: test_vshll_n_u8
+// CHECK-LABEL: test_vshll_n_u8
 // CHECK: vshll.u8 q{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint16x8_t test_vshll_n_u8(uint8x8_t a) {
   return vshll_n_u8(a, 1);
 }
 
-// CHECK: test_vshll_n_u16
+// CHECK-LABEL: test_vshll_n_u16
 // CHECK: vshll.u16 q{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint32x4_t test_vshll_n_u16(uint16x4_t a) {
   return vshll_n_u16(a, 1);
 }
 
-// CHECK: test_vshll_n_u32
+// CHECK-LABEL: test_vshll_n_u32
 // CHECK: vshll.u32 q{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint64x2_t test_vshll_n_u32(uint32x2_t a) {
   return vshll_n_u32(a, 1);
 }
 
 
-// CHECK: test_vshl_n_s8
+// CHECK-LABEL: test_vshl_n_s8
 // CHECK: vshl.i8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int8x8_t test_vshl_n_s8(int8x8_t a) {
   return vshl_n_s8(a, 1);
 }
 
-// CHECK: test_vshl_n_s16
+// CHECK-LABEL: test_vshl_n_s16
 // CHECK: vshl.i16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int16x4_t test_vshl_n_s16(int16x4_t a) {
   return vshl_n_s16(a, 1);
 }
 
-// CHECK: test_vshl_n_s32
+// CHECK-LABEL: test_vshl_n_s32
 // CHECK: vshl.i32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int32x2_t test_vshl_n_s32(int32x2_t a) {
   return vshl_n_s32(a, 1);
 }
 
-// CHECK: test_vshl_n_s64
+// CHECK-LABEL: test_vshl_n_s64
 // CHECK: vshl.i64 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int64x1_t test_vshl_n_s64(int64x1_t a) {
   return vshl_n_s64(a, 1);
 }
 
-// CHECK: test_vshl_n_u8
+// CHECK-LABEL: test_vshl_n_u8
 // CHECK: vshl.i8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint8x8_t test_vshl_n_u8(uint8x8_t a) {
   return vshl_n_u8(a, 1);
 }
 
-// CHECK: test_vshl_n_u16
+// CHECK-LABEL: test_vshl_n_u16
 // CHECK: vshl.i16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint16x4_t test_vshl_n_u16(uint16x4_t a) {
   return vshl_n_u16(a, 1);
 }
 
-// CHECK: test_vshl_n_u32
+// CHECK-LABEL: test_vshl_n_u32
 // CHECK: vshl.i32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint32x2_t test_vshl_n_u32(uint32x2_t a) {
   return vshl_n_u32(a, 1);
 }
 
-// CHECK: test_vshl_n_u64
+// CHECK-LABEL: test_vshl_n_u64
 // CHECK: vshl.i64 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint64x1_t test_vshl_n_u64(uint64x1_t a) {
   return vshl_n_u64(a, 1);
 }
 
-// CHECK: test_vshlq_n_s8
+// CHECK-LABEL: test_vshlq_n_s8
 // CHECK: vshl.i8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int8x16_t test_vshlq_n_s8(int8x16_t a) {
   return vshlq_n_s8(a, 1);
 }
 
-// CHECK: test_vshlq_n_s16
+// CHECK-LABEL: test_vshlq_n_s16
 // CHECK: vshl.i16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int16x8_t test_vshlq_n_s16(int16x8_t a) {
   return vshlq_n_s16(a, 1);
 }
 
-// CHECK: test_vshlq_n_s32
+// CHECK-LABEL: test_vshlq_n_s32
 // CHECK: vshl.i32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int32x4_t test_vshlq_n_s32(int32x4_t a) {
   return vshlq_n_s32(a, 1);
 }
 
-// CHECK: test_vshlq_n_s64
+// CHECK-LABEL: test_vshlq_n_s64
 // CHECK: vshl.i64 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int64x2_t test_vshlq_n_s64(int64x2_t a) {
   return vshlq_n_s64(a, 1);
 }
 
-// CHECK: test_vshlq_n_u8
+// CHECK-LABEL: test_vshlq_n_u8
 // CHECK: vshl.i8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint8x16_t test_vshlq_n_u8(uint8x16_t a) {
   return vshlq_n_u8(a, 1);
 }
 
-// CHECK: test_vshlq_n_u16
+// CHECK-LABEL: test_vshlq_n_u16
 // CHECK: vshl.i16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint16x8_t test_vshlq_n_u16(uint16x8_t a) {
   return vshlq_n_u16(a, 1);
 }
 
-// CHECK: test_vshlq_n_u32
+// CHECK-LABEL: test_vshlq_n_u32
 // CHECK: vshl.i32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint32x4_t test_vshlq_n_u32(uint32x4_t a) {
   return vshlq_n_u32(a, 1);
 }
 
-// CHECK: test_vshlq_n_u64
+// CHECK-LABEL: test_vshlq_n_u64
 // CHECK: vshl.i64 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint64x2_t test_vshlq_n_u64(uint64x2_t a) {
   return vshlq_n_u64(a, 1);
 }
 
 
-// CHECK: test_vshrn_n_s16
+// CHECK-LABEL: test_vshrn_n_s16
 // CHECK: vshrn.i16 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int8x8_t test_vshrn_n_s16(int16x8_t a) {
   return vshrn_n_s16(a, 1);
 }
 
-// CHECK: test_vshrn_n_s32
+// CHECK-LABEL: test_vshrn_n_s32
 // CHECK: vshrn.i32 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int16x4_t test_vshrn_n_s32(int32x4_t a) {
   return vshrn_n_s32(a, 1);
 }
 
-// CHECK: test_vshrn_n_s64
+// CHECK-LABEL: test_vshrn_n_s64
 // CHECK: vshrn.i64 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int32x2_t test_vshrn_n_s64(int64x2_t a) {
   return vshrn_n_s64(a, 1);
 }
 
-// CHECK: test_vshrn_n_u16
+// CHECK-LABEL: test_vshrn_n_u16
 // CHECK: vshrn.i16 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint8x8_t test_vshrn_n_u16(uint16x8_t a) {
   return vshrn_n_u16(a, 1);
 }
 
-// CHECK: test_vshrn_n_u32
+// CHECK-LABEL: test_vshrn_n_u32
 // CHECK: vshrn.i32 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint16x4_t test_vshrn_n_u32(uint32x4_t a) {
   return vshrn_n_u32(a, 1);
 }
 
-// CHECK: test_vshrn_n_u64
+// CHECK-LABEL: test_vshrn_n_u64
 // CHECK: vshrn.i64 d{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint32x2_t test_vshrn_n_u64(uint64x2_t a) {
   return vshrn_n_u64(a, 1);
 }
 
 
-// CHECK: test_vshr_n_s8
+// CHECK-LABEL: test_vshr_n_s8
 // CHECK: vshr.s8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int8x8_t test_vshr_n_s8(int8x8_t a) {
   return vshr_n_s8(a, 1);
 }
 
-// CHECK: test_vshr_n_s16
+// CHECK-LABEL: test_vshr_n_s16
 // CHECK: vshr.s16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int16x4_t test_vshr_n_s16(int16x4_t a) {
   return vshr_n_s16(a, 1);
 }
 
-// CHECK: test_vshr_n_s32
+// CHECK-LABEL: test_vshr_n_s32
 // CHECK: vshr.s32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int32x2_t test_vshr_n_s32(int32x2_t a) {
   return vshr_n_s32(a, 1);
 }
 
-// CHECK: test_vshr_n_s64
+// CHECK-LABEL: test_vshr_n_s64
 // CHECK: vshr.s64 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int64x1_t test_vshr_n_s64(int64x1_t a) {
   return vshr_n_s64(a, 1);
 }
 
-// CHECK: test_vshr_n_u8
+// CHECK-LABEL: test_vshr_n_u8
 // CHECK: vshr.u8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint8x8_t test_vshr_n_u8(uint8x8_t a) {
   return vshr_n_u8(a, 1);
 }
 
-// CHECK: test_vshr_n_u16
+// CHECK-LABEL: test_vshr_n_u16
 // CHECK: vshr.u16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint16x4_t test_vshr_n_u16(uint16x4_t a) {
   return vshr_n_u16(a, 1);
 }
 
-// CHECK: test_vshr_n_u32
+// CHECK-LABEL: test_vshr_n_u32
 // CHECK: vshr.u32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint32x2_t test_vshr_n_u32(uint32x2_t a) {
   return vshr_n_u32(a, 1);
 }
 
-// CHECK: test_vshr_n_u64
+// CHECK-LABEL: test_vshr_n_u64
 // CHECK: vshr.u64 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint64x1_t test_vshr_n_u64(uint64x1_t a) {
   return vshr_n_u64(a, 1);
 }
 
-// CHECK: test_vshrq_n_s8
+// CHECK-LABEL: test_vshrq_n_s8
 // CHECK: vshr.s8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int8x16_t test_vshrq_n_s8(int8x16_t a) {
   return vshrq_n_s8(a, 1);
 }
 
-// CHECK: test_vshrq_n_s16
+// CHECK-LABEL: test_vshrq_n_s16
 // CHECK: vshr.s16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int16x8_t test_vshrq_n_s16(int16x8_t a) {
   return vshrq_n_s16(a, 1);
 }
 
-// CHECK: test_vshrq_n_s32
+// CHECK-LABEL: test_vshrq_n_s32
 // CHECK: vshr.s32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int32x4_t test_vshrq_n_s32(int32x4_t a) {
   return vshrq_n_s32(a, 1);
 }
 
-// CHECK: test_vshrq_n_s64
+// CHECK-LABEL: test_vshrq_n_s64
 // CHECK: vshr.s64 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int64x2_t test_vshrq_n_s64(int64x2_t a) {
   return vshrq_n_s64(a, 1);
 }
 
-// CHECK: test_vshrq_n_u8
+// CHECK-LABEL: test_vshrq_n_u8
 // CHECK: vshr.u8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint8x16_t test_vshrq_n_u8(uint8x16_t a) {
   return vshrq_n_u8(a, 1);
 }
 
-// CHECK: test_vshrq_n_u16
+// CHECK-LABEL: test_vshrq_n_u16
 // CHECK: vshr.u16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint16x8_t test_vshrq_n_u16(uint16x8_t a) {
   return vshrq_n_u16(a, 1);
 }
 
-// CHECK: test_vshrq_n_u32
+// CHECK-LABEL: test_vshrq_n_u32
 // CHECK: vshr.u32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint32x4_t test_vshrq_n_u32(uint32x4_t a) {
   return vshrq_n_u32(a, 1);
 }
 
-// CHECK: test_vshrq_n_u64
+// CHECK-LABEL: test_vshrq_n_u64
 // CHECK: vshr.u64 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint64x2_t test_vshrq_n_u64(uint64x2_t a) {
   return vshrq_n_u64(a, 1);
 }
 
 
-// CHECK: test_vsli_n_s8
+// CHECK-LABEL: test_vsli_n_s8
 // CHECK: vsli.8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int8x8_t test_vsli_n_s8(int8x8_t a, int8x8_t b) {
   return vsli_n_s8(a, b, 1);
 }
 
-// CHECK: test_vsli_n_s16
+// CHECK-LABEL: test_vsli_n_s16
 // CHECK: vsli.16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int16x4_t test_vsli_n_s16(int16x4_t a, int16x4_t b) {
   return vsli_n_s16(a, b, 1);
 }
 
-// CHECK: test_vsli_n_s32
+// CHECK-LABEL: test_vsli_n_s32
 // CHECK: vsli.32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int32x2_t test_vsli_n_s32(int32x2_t a, int32x2_t b) {
   return vsli_n_s32(a, b, 1);
 }
 
-// CHECK: test_vsli_n_s64
+// CHECK-LABEL: test_vsli_n_s64
 // CHECK: vsli.64 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int64x1_t test_vsli_n_s64(int64x1_t a, int64x1_t b) {
   return vsli_n_s64(a, b, 1);
 }
 
-// CHECK: test_vsli_n_u8
+// CHECK-LABEL: test_vsli_n_u8
 // CHECK: vsli.8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint8x8_t test_vsli_n_u8(uint8x8_t a, uint8x8_t b) {
   return vsli_n_u8(a, b, 1);
 }
 
-// CHECK: test_vsli_n_u16
+// CHECK-LABEL: test_vsli_n_u16
 // CHECK: vsli.16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint16x4_t test_vsli_n_u16(uint16x4_t a, uint16x4_t b) {
   return vsli_n_u16(a, b, 1);
 }
 
-// CHECK: test_vsli_n_u32
+// CHECK-LABEL: test_vsli_n_u32
 // CHECK: vsli.32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint32x2_t test_vsli_n_u32(uint32x2_t a, uint32x2_t b) {
   return vsli_n_u32(a, b, 1);
 }
 
-// CHECK: test_vsli_n_u64
+// CHECK-LABEL: test_vsli_n_u64
 // CHECK: vsli.64 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint64x1_t test_vsli_n_u64(uint64x1_t a, uint64x1_t b) {
   return vsli_n_u64(a, b, 1);
 }
 
-// CHECK: test_vsli_n_p8
+// CHECK-LABEL: test_vsli_n_p8
 // CHECK: vsli.8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 poly8x8_t test_vsli_n_p8(poly8x8_t a, poly8x8_t b) {
   return vsli_n_p8(a, b, 1);
 }
 
-// CHECK: test_vsli_n_p16
+// CHECK-LABEL: test_vsli_n_p16
 // CHECK: vsli.16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 poly16x4_t test_vsli_n_p16(poly16x4_t a, poly16x4_t b) {
   return vsli_n_p16(a, b, 1);
 }
 
-// CHECK: test_vsliq_n_s8
+// CHECK-LABEL: test_vsliq_n_s8
 // CHECK: vsli.8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int8x16_t test_vsliq_n_s8(int8x16_t a, int8x16_t b) {
   return vsliq_n_s8(a, b, 1);
 }
 
-// CHECK: test_vsliq_n_s16
+// CHECK-LABEL: test_vsliq_n_s16
 // CHECK: vsli.16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int16x8_t test_vsliq_n_s16(int16x8_t a, int16x8_t b) {
   return vsliq_n_s16(a, b, 1);
 }
 
-// CHECK: test_vsliq_n_s32
+// CHECK-LABEL: test_vsliq_n_s32
 // CHECK: vsli.32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int32x4_t test_vsliq_n_s32(int32x4_t a, int32x4_t b) {
   return vsliq_n_s32(a, b, 1);
 }
 
-// CHECK: test_vsliq_n_s64
+// CHECK-LABEL: test_vsliq_n_s64
 // CHECK: vsli.64 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int64x2_t test_vsliq_n_s64(int64x2_t a, int64x2_t b) {
   return vsliq_n_s64(a, b, 1);
 }
 
-// CHECK: test_vsliq_n_u8
+// CHECK-LABEL: test_vsliq_n_u8
 // CHECK: vsli.8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint8x16_t test_vsliq_n_u8(uint8x16_t a, uint8x16_t b) {
   return vsliq_n_u8(a, b, 1);
 }
 
-// CHECK: test_vsliq_n_u16
+// CHECK-LABEL: test_vsliq_n_u16
 // CHECK: vsli.16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint16x8_t test_vsliq_n_u16(uint16x8_t a, uint16x8_t b) {
   return vsliq_n_u16(a, b, 1);
 }
 
-// CHECK: test_vsliq_n_u32
+// CHECK-LABEL: test_vsliq_n_u32
 // CHECK: vsli.32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint32x4_t test_vsliq_n_u32(uint32x4_t a, uint32x4_t b) {
   return vsliq_n_u32(a, b, 1);
 }
 
-// CHECK: test_vsliq_n_u64
+// CHECK-LABEL: test_vsliq_n_u64
 // CHECK: vsli.64 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint64x2_t test_vsliq_n_u64(uint64x2_t a, uint64x2_t b) {
   return vsliq_n_u64(a, b, 1);
 }
 
-// CHECK: test_vsliq_n_p8
+// CHECK-LABEL: test_vsliq_n_p8
 // CHECK: vsli.8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 poly8x16_t test_vsliq_n_p8(poly8x16_t a, poly8x16_t b) {
   return vsliq_n_p8(a, b, 1);
 }
 
-// CHECK: test_vsliq_n_p16
+// CHECK-LABEL: test_vsliq_n_p16
 // CHECK: vsli.16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 poly16x8_t test_vsliq_n_p16(poly16x8_t a, poly16x8_t b) {
   return vsliq_n_p16(a, b, 1);
 }
 
 
-// CHECK: test_vsra_n_s8
+// CHECK-LABEL: test_vsra_n_s8
 // CHECK: vsra.s8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int8x8_t test_vsra_n_s8(int8x8_t a, int8x8_t b) {
   return vsra_n_s8(a, b, 1);
 }
 
-// CHECK: test_vsra_n_s16
+// CHECK-LABEL: test_vsra_n_s16
 // CHECK: vsra.s16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int16x4_t test_vsra_n_s16(int16x4_t a, int16x4_t b) {
   return vsra_n_s16(a, b, 1);
 }
 
-// CHECK: test_vsra_n_s32
+// CHECK-LABEL: test_vsra_n_s32
 // CHECK: vsra.s32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int32x2_t test_vsra_n_s32(int32x2_t a, int32x2_t b) {
   return vsra_n_s32(a, b, 1);
 }
 
-// CHECK: test_vsra_n_s64
+// CHECK-LABEL: test_vsra_n_s64
 // CHECK: vsra.s64 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int64x1_t test_vsra_n_s64(int64x1_t a, int64x1_t b) {
   return vsra_n_s64(a, b, 1);
 }
 
-// CHECK: test_vsra_n_u8
+// CHECK-LABEL: test_vsra_n_u8
 // CHECK: vsra.u8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint8x8_t test_vsra_n_u8(uint8x8_t a, uint8x8_t b) {
   return vsra_n_u8(a, b, 1);
 }
 
-// CHECK: test_vsra_n_u16
+// CHECK-LABEL: test_vsra_n_u16
 // CHECK: vsra.u16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint16x4_t test_vsra_n_u16(uint16x4_t a, uint16x4_t b) {
   return vsra_n_u16(a, b, 1);
 }
 
-// CHECK: test_vsra_n_u32
+// CHECK-LABEL: test_vsra_n_u32
 // CHECK: vsra.u32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint32x2_t test_vsra_n_u32(uint32x2_t a, uint32x2_t b) {
   return vsra_n_u32(a, b, 1);
 }
 
-// CHECK: test_vsra_n_u64
+// CHECK-LABEL: test_vsra_n_u64
 // CHECK: vsra.u64 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint64x1_t test_vsra_n_u64(uint64x1_t a, uint64x1_t b) {
   return vsra_n_u64(a, b, 1);
 }
 
-// CHECK: test_vsraq_n_s8
+// CHECK-LABEL: test_vsraq_n_s8
 // CHECK: vsra.s8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int8x16_t test_vsraq_n_s8(int8x16_t a, int8x16_t b) {
   return vsraq_n_s8(a, b, 1);
 }
 
-// CHECK: test_vsraq_n_s16
+// CHECK-LABEL: test_vsraq_n_s16
 // CHECK: vsra.s16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int16x8_t test_vsraq_n_s16(int16x8_t a, int16x8_t b) {
   return vsraq_n_s16(a, b, 1);
 }
 
-// CHECK: test_vsraq_n_s32
+// CHECK-LABEL: test_vsraq_n_s32
 // CHECK: vsra.s32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int32x4_t test_vsraq_n_s32(int32x4_t a, int32x4_t b) {
   return vsraq_n_s32(a, b, 1);
 }
 
-// CHECK: test_vsraq_n_s64
+// CHECK-LABEL: test_vsraq_n_s64
 // CHECK: vsra.s64 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int64x2_t test_vsraq_n_s64(int64x2_t a, int64x2_t b) {
   return vsraq_n_s64(a, b, 1);
 }
 
-// CHECK: test_vsraq_n_u8
+// CHECK-LABEL: test_vsraq_n_u8
 // CHECK: vsra.u8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint8x16_t test_vsraq_n_u8(uint8x16_t a, uint8x16_t b) {
   return vsraq_n_u8(a, b, 1);
 }
 
-// CHECK: test_vsraq_n_u16
+// CHECK-LABEL: test_vsraq_n_u16
 // CHECK: vsra.u16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint16x8_t test_vsraq_n_u16(uint16x8_t a, uint16x8_t b) {
   return vsraq_n_u16(a, b, 1);
 }
 
-// CHECK: test_vsraq_n_u32
+// CHECK-LABEL: test_vsraq_n_u32
 // CHECK: vsra.u32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint32x4_t test_vsraq_n_u32(uint32x4_t a, uint32x4_t b) {
   return vsraq_n_u32(a, b, 1);
 }
 
-// CHECK: test_vsraq_n_u64
+// CHECK-LABEL: test_vsraq_n_u64
 // CHECK: vsra.u64 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint64x2_t test_vsraq_n_u64(uint64x2_t a, uint64x2_t b) {
   return vsraq_n_u64(a, b, 1);
 }
 
 
-// CHECK: test_vsri_n_s8
+// CHECK-LABEL: test_vsri_n_s8
 // CHECK: vsri.8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int8x8_t test_vsri_n_s8(int8x8_t a, int8x8_t b) {
   return vsri_n_s8(a, b, 1);
 }
 
-// CHECK: test_vsri_n_s16
+// CHECK-LABEL: test_vsri_n_s16
 // CHECK: vsri.16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int16x4_t test_vsri_n_s16(int16x4_t a, int16x4_t b) {
   return vsri_n_s16(a, b, 1);
 }
 
-// CHECK: test_vsri_n_s32
+// CHECK-LABEL: test_vsri_n_s32
 // CHECK: vsri.32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int32x2_t test_vsri_n_s32(int32x2_t a, int32x2_t b) {
   return vsri_n_s32(a, b, 1);
 }
 
-// CHECK: test_vsri_n_s64
+// CHECK-LABEL: test_vsri_n_s64
 // CHECK: vsri.64 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 int64x1_t test_vsri_n_s64(int64x1_t a, int64x1_t b) {
   return vsri_n_s64(a, b, 1);
 }
 
-// CHECK: test_vsri_n_u8
+// CHECK-LABEL: test_vsri_n_u8
 // CHECK: vsri.8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint8x8_t test_vsri_n_u8(uint8x8_t a, uint8x8_t b) {
   return vsri_n_u8(a, b, 1);
 }
 
-// CHECK: test_vsri_n_u16
+// CHECK-LABEL: test_vsri_n_u16
 // CHECK: vsri.16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint16x4_t test_vsri_n_u16(uint16x4_t a, uint16x4_t b) {
   return vsri_n_u16(a, b, 1);
 }
 
-// CHECK: test_vsri_n_u32
+// CHECK-LABEL: test_vsri_n_u32
 // CHECK: vsri.32 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint32x2_t test_vsri_n_u32(uint32x2_t a, uint32x2_t b) {
   return vsri_n_u32(a, b, 1);
 }
 
-// CHECK: test_vsri_n_u64
+// CHECK-LABEL: test_vsri_n_u64
 // CHECK: vsri.64 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 uint64x1_t test_vsri_n_u64(uint64x1_t a, uint64x1_t b) {
   return vsri_n_u64(a, b, 1);
 }
 
-// CHECK: test_vsri_n_p8
+// CHECK-LABEL: test_vsri_n_p8
 // CHECK: vsri.8 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 poly8x8_t test_vsri_n_p8(poly8x8_t a, poly8x8_t b) {
   return vsri_n_p8(a, b, 1);
 }
 
-// CHECK: test_vsri_n_p16
+// CHECK-LABEL: test_vsri_n_p16
 // CHECK: vsri.16 d{{[0-9]+}}, d{{[0-9]+}}, #{{[0-9]+}}
 poly16x4_t test_vsri_n_p16(poly16x4_t a, poly16x4_t b) {
   return vsri_n_p16(a, b, 1);
 }
 
-// CHECK: test_vsriq_n_s8
+// CHECK-LABEL: test_vsriq_n_s8
 // CHECK: vsri.8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int8x16_t test_vsriq_n_s8(int8x16_t a, int8x16_t b) {
   return vsriq_n_s8(a, b, 1);
 }
 
-// CHECK: test_vsriq_n_s16
+// CHECK-LABEL: test_vsriq_n_s16
 // CHECK: vsri.16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int16x8_t test_vsriq_n_s16(int16x8_t a, int16x8_t b) {
   return vsriq_n_s16(a, b, 1);
 }
 
-// CHECK: test_vsriq_n_s32
+// CHECK-LABEL: test_vsriq_n_s32
 // CHECK: vsri.32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int32x4_t test_vsriq_n_s32(int32x4_t a, int32x4_t b) {
   return vsriq_n_s32(a, b, 1);
 }
 
-// CHECK: test_vsriq_n_s64
+// CHECK-LABEL: test_vsriq_n_s64
 // CHECK: vsri.64 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 int64x2_t test_vsriq_n_s64(int64x2_t a, int64x2_t b) {
   return vsriq_n_s64(a, b, 1);
 }
 
-// CHECK: test_vsriq_n_u8
+// CHECK-LABEL: test_vsriq_n_u8
 // CHECK: vsri.8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint8x16_t test_vsriq_n_u8(uint8x16_t a, uint8x16_t b) {
   return vsriq_n_u8(a, b, 1);
 }
 
-// CHECK: test_vsriq_n_u16
+// CHECK-LABEL: test_vsriq_n_u16
 // CHECK: vsri.16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint16x8_t test_vsriq_n_u16(uint16x8_t a, uint16x8_t b) {
   return vsriq_n_u16(a, b, 1);
 }
 
-// CHECK: test_vsriq_n_u32
+// CHECK-LABEL: test_vsriq_n_u32
 // CHECK: vsri.32 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint32x4_t test_vsriq_n_u32(uint32x4_t a, uint32x4_t b) {
   return vsriq_n_u32(a, b, 1);
 }
 
-// CHECK: test_vsriq_n_u64
+// CHECK-LABEL: test_vsriq_n_u64
 // CHECK: vsri.64 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 uint64x2_t test_vsriq_n_u64(uint64x2_t a, uint64x2_t b) {
   return vsriq_n_u64(a, b, 1);
 }
 
-// CHECK: test_vsriq_n_p8
+// CHECK-LABEL: test_vsriq_n_p8
 // CHECK: vsri.8 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 poly8x16_t test_vsriq_n_p8(poly8x16_t a, poly8x16_t b) {
   return vsriq_n_p8(a, b, 1);
 }
 
-// CHECK: test_vsriq_n_p16
+// CHECK-LABEL: test_vsriq_n_p16
 // CHECK: vsri.16 q{{[0-9]+}}, q{{[0-9]+}}, #{{[0-9]+}}
 poly16x8_t test_vsriq_n_p16(poly16x8_t a, poly16x8_t b) {
   return vsriq_n_p16(a, b, 1);
 }
 
 
-// CHECK: test_vst1q_u8
+// CHECK-LABEL: test_vst1q_u8
 // CHECK: vst1.8 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1q_u8(uint8_t * a, uint8x16_t b) {
   vst1q_u8(a, b);
 }
 
-// CHECK: test_vst1q_u16
+// CHECK-LABEL: test_vst1q_u16
 // CHECK: vst1.16 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1q_u16(uint16_t * a, uint16x8_t b) {
   vst1q_u16(a, b);
 }
 
-// CHECK: test_vst1q_u32
+// CHECK-LABEL: test_vst1q_u32
 // CHECK: vst1.32 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1q_u32(uint32_t * a, uint32x4_t b) {
   vst1q_u32(a, b);
 }
 
-// CHECK: test_vst1q_u64
-// CHECK: vst1.64 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
+// CHECK-LABEL: test_vst1q_u64
+// CHECK: vst1.64 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}{{(:64)?}}]
 void test_vst1q_u64(uint64_t * a, uint64x2_t b) {
   vst1q_u64(a, b);
 }
 
-// CHECK: test_vst1q_s8
+// CHECK-LABEL: test_vst1q_s8
 // CHECK: vst1.8 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1q_s8(int8_t * a, int8x16_t b) {
   vst1q_s8(a, b);
 }
 
-// CHECK: test_vst1q_s16
+// CHECK-LABEL: test_vst1q_s16
 // CHECK: vst1.16 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1q_s16(int16_t * a, int16x8_t b) {
   vst1q_s16(a, b);
 }
 
-// CHECK: test_vst1q_s32
+// CHECK-LABEL: test_vst1q_s32
 // CHECK: vst1.32 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1q_s32(int32_t * a, int32x4_t b) {
   vst1q_s32(a, b);
 }
 
-// CHECK: test_vst1q_s64
-// CHECK: vst1.64 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
+// CHECK-LABEL: test_vst1q_s64
+// CHECK: vst1.64 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}{{(:64)?}}]
 void test_vst1q_s64(int64_t * a, int64x2_t b) {
   vst1q_s64(a, b);
 }
 
-// CHECK: test_vst1q_f16
+// CHECK-LABEL: test_vst1q_f16
 // CHECK: vst1.16 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1q_f16(float16_t * a, float16x8_t b) {
   vst1q_f16(a, b);
 }
 
-// CHECK: test_vst1q_f32
+// CHECK-LABEL: test_vst1q_f32
 // CHECK: vst1.32 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1q_f32(float32_t * a, float32x4_t b) {
   vst1q_f32(a, b);
 }
 
-// CHECK: test_vst1q_p8
+// CHECK-LABEL: test_vst1q_p8
 // CHECK: vst1.8 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1q_p8(poly8_t * a, poly8x16_t b) {
   vst1q_p8(a, b);
 }
 
-// CHECK: test_vst1q_p16
+// CHECK-LABEL: test_vst1q_p16
 // CHECK: vst1.16 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1q_p16(poly16_t * a, poly16x8_t b) {
   vst1q_p16(a, b);
 }
 
-// CHECK: test_vst1_u8
+// CHECK-LABEL: test_vst1_u8
 // CHECK: vst1.8 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1_u8(uint8_t * a, uint8x8_t b) {
   vst1_u8(a, b);
 }
 
-// CHECK: test_vst1_u16
+// CHECK-LABEL: test_vst1_u16
 // CHECK: vst1.16 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1_u16(uint16_t * a, uint16x4_t b) {
   vst1_u16(a, b);
 }
 
-// CHECK: test_vst1_u32
+// CHECK-LABEL: test_vst1_u32
 // CHECK: vst1.32 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1_u32(uint32_t * a, uint32x2_t b) {
   vst1_u32(a, b);
 }
 
-// CHECK: test_vst1_u64
-// CHECK: vst1.64 {d{{[0-9]+}}}, [r{{[0-9]+}}]
+// CHECK-LABEL: test_vst1_u64
+// CHECK: vst1.64 {d{{[0-9]+}}}, [r{{[0-9]+}}{{(:64)?}}]
 void test_vst1_u64(uint64_t * a, uint64x1_t b) {
   vst1_u64(a, b);
 }
 
-// CHECK: test_vst1_s8
+// CHECK-LABEL: test_vst1_s8
 // CHECK: vst1.8 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1_s8(int8_t * a, int8x8_t b) {
   vst1_s8(a, b);
 }
 
-// CHECK: test_vst1_s16
+// CHECK-LABEL: test_vst1_s16
 // CHECK: vst1.16 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1_s16(int16_t * a, int16x4_t b) {
   vst1_s16(a, b);
 }
 
-// CHECK: test_vst1_s32
+// CHECK-LABEL: test_vst1_s32
 // CHECK: vst1.32 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1_s32(int32_t * a, int32x2_t b) {
   vst1_s32(a, b);
 }
 
-// CHECK: test_vst1_s64
-// CHECK: vst1.64 {d{{[0-9]+}}}, [r{{[0-9]+}}]
+// CHECK-LABEL: test_vst1_s64
+// CHECK: vst1.64 {d{{[0-9]+}}}, [r{{[0-9]+}}{{(:64)?}}]
 void test_vst1_s64(int64_t * a, int64x1_t b) {
   vst1_s64(a, b);
 }
 
-// CHECK: test_vst1_f16
+// CHECK-LABEL: test_vst1_f16
 // CHECK: vst1.16 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1_f16(float16_t * a, float16x4_t b) {
   vst1_f16(a, b);
 }
 
-// CHECK: test_vst1_f32
+// CHECK-LABEL: test_vst1_f32
 // CHECK: vst1.32 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1_f32(float32_t * a, float32x2_t b) {
   vst1_f32(a, b);
 }
 
-// CHECK: test_vst1_p8
+// CHECK-LABEL: test_vst1_p8
 // CHECK: vst1.8 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1_p8(poly8_t * a, poly8x8_t b) {
   vst1_p8(a, b);
 }
 
-// CHECK: test_vst1_p16
+// CHECK-LABEL: test_vst1_p16
 // CHECK: vst1.16 {d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst1_p16(poly16_t * a, poly16x4_t b) {
   vst1_p16(a, b);
 }
 
 
-// CHECK: test_vst1q_lane_u8
+// CHECK-LABEL: test_vst1q_lane_u8
 // CHECK: vst1.8 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst1q_lane_u8(uint8_t * a, uint8x16_t b) {
   vst1q_lane_u8(a, b, 15);
 }
 
-// CHECK: test_vst1q_lane_u16
+// CHECK-LABEL: test_vst1q_lane_u16
 // CHECK: vst1.16 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:16]
 void test_vst1q_lane_u16(uint16_t * a, uint16x8_t b) {
   vst1q_lane_u16(a, b, 7);
 }
 
-// CHECK: test_vst1q_lane_u32
+// CHECK-LABEL: test_vst1q_lane_u32
 // CHECK: vst1.32 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:32]
 void test_vst1q_lane_u32(uint32_t * a, uint32x4_t b) {
   vst1q_lane_u32(a, b, 3);
 }
 
-// CHECK: test_vst1q_lane_u64
+// CHECK-LABEL: test_vst1q_lane_u64
 // CHECK: {{str|vstr|vmov}}
 void test_vst1q_lane_u64(uint64_t * a, uint64x2_t b) {
   vst1q_lane_u64(a, b, 1);
 }
 
-// CHECK: test_vst1q_lane_s8
+// CHECK-LABEL: test_vst1q_lane_s8
 // CHECK: vst1.8 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst1q_lane_s8(int8_t * a, int8x16_t b) {
   vst1q_lane_s8(a, b, 15);
 }
 
-// CHECK: test_vst1q_lane_s16
+// CHECK-LABEL: test_vst1q_lane_s16
 // CHECK: vst1.16 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:16]
 void test_vst1q_lane_s16(int16_t * a, int16x8_t b) {
   vst1q_lane_s16(a, b, 7);
 }
 
-// CHECK: test_vst1q_lane_s32
+// CHECK-LABEL: test_vst1q_lane_s32
 // CHECK: vst1.32 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:32]
 void test_vst1q_lane_s32(int32_t * a, int32x4_t b) {
   vst1q_lane_s32(a, b, 3);
 }
 
-// CHECK: test_vst1q_lane_s64
+// CHECK-LABEL: test_vst1q_lane_s64
 // CHECK: {{str|vstr|vmov}}
 void test_vst1q_lane_s64(int64_t * a, int64x2_t b) {
   vst1q_lane_s64(a, b, 1);
 }
 
-// CHECK: test_vst1q_lane_f16
+// CHECK-LABEL: test_vst1q_lane_f16
 // CHECK: vst1.16 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:16]
 void test_vst1q_lane_f16(float16_t * a, float16x8_t b) {
   vst1q_lane_f16(a, b, 7);
 }
 
-// CHECK: test_vst1q_lane_f32
+// CHECK-LABEL: test_vst1q_lane_f32
 // CHECK: vst1.32 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:32]
 void test_vst1q_lane_f32(float32_t * a, float32x4_t b) {
   vst1q_lane_f32(a, b, 3);
 }
 
-// CHECK: test_vst1q_lane_p8
+// CHECK-LABEL: test_vst1q_lane_p8
 // CHECK: vst1.8 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst1q_lane_p8(poly8_t * a, poly8x16_t b) {
   vst1q_lane_p8(a, b, 15);
 }
 
-// CHECK: test_vst1q_lane_p16
+// CHECK-LABEL: test_vst1q_lane_p16
 // CHECK: vst1.16 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:16]
 void test_vst1q_lane_p16(poly16_t * a, poly16x8_t b) {
   vst1q_lane_p16(a, b, 7);
 }
 
-// CHECK: test_vst1_lane_u8
+// CHECK-LABEL: test_vst1_lane_u8
 // CHECK: vst1.8 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst1_lane_u8(uint8_t * a, uint8x8_t b) {
   vst1_lane_u8(a, b, 7);
 }
 
-// CHECK: test_vst1_lane_u16
+// CHECK-LABEL: test_vst1_lane_u16
 // CHECK: vst1.16 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:16]
 void test_vst1_lane_u16(uint16_t * a, uint16x4_t b) {
   vst1_lane_u16(a, b, 3);
 }
 
-// CHECK: test_vst1_lane_u32
+// CHECK-LABEL: test_vst1_lane_u32
 // CHECK: vst1.32 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:32]
 void test_vst1_lane_u32(uint32_t * a, uint32x2_t b) {
   vst1_lane_u32(a, b, 1);
 }
 
-// CHECK: test_vst1_lane_u64
+// CHECK-LABEL: test_vst1_lane_u64
 // CHECK: {{str|vstr|vmov}}
 void test_vst1_lane_u64(uint64_t * a, uint64x1_t b) {
   vst1_lane_u64(a, b, 0);
 }
 
-// CHECK: test_vst1_lane_s8
+// CHECK-LABEL: test_vst1_lane_s8
 // CHECK: vst1.8 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst1_lane_s8(int8_t * a, int8x8_t b) {
   vst1_lane_s8(a, b, 7);
 }
 
-// CHECK: test_vst1_lane_s16
+// CHECK-LABEL: test_vst1_lane_s16
 // CHECK: vst1.16 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:16]
 void test_vst1_lane_s16(int16_t * a, int16x4_t b) {
   vst1_lane_s16(a, b, 3);
 }
 
-// CHECK: test_vst1_lane_s32
+// CHECK-LABEL: test_vst1_lane_s32
 // CHECK: vst1.32 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:32]
 void test_vst1_lane_s32(int32_t * a, int32x2_t b) {
   vst1_lane_s32(a, b, 1);
 }
 
-// CHECK: test_vst1_lane_s64
+// CHECK-LABEL: test_vst1_lane_s64
 // CHECK: {{str|vstr|vmov}}
 void test_vst1_lane_s64(int64_t * a, int64x1_t b) {
   vst1_lane_s64(a, b, 0);
 }
 
-// CHECK: test_vst1_lane_f16
+// CHECK-LABEL: test_vst1_lane_f16
 // CHECK: vst1.16 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:16]
 void test_vst1_lane_f16(float16_t * a, float16x4_t b) {
   vst1_lane_f16(a, b, 3);
 }
 
-// CHECK: test_vst1_lane_f32
+// CHECK-LABEL: test_vst1_lane_f32
 // CHECK: vst1.32 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:32]
 void test_vst1_lane_f32(float32_t * a, float32x2_t b) {
   vst1_lane_f32(a, b, 1);
 }
 
-// CHECK: test_vst1_lane_p8
+// CHECK-LABEL: test_vst1_lane_p8
 // CHECK: vst1.8 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst1_lane_p8(poly8_t * a, poly8x8_t b) {
   vst1_lane_p8(a, b, 7);
 }
 
-// CHECK: test_vst1_lane_p16
+// CHECK-LABEL: test_vst1_lane_p16
 // CHECK: vst1.16 {d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}:16]
 void test_vst1_lane_p16(poly16_t * a, poly16x4_t b) {
   vst1_lane_p16(a, b, 3);
 }
 
 
-// CHECK: test_vst2q_u8
+// CHECK-LABEL: test_vst2q_u8
 // CHECK: vst2.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2q_u8(uint8_t * a, uint8x16x2_t b) {
   vst2q_u8(a, b);
 }
 
-// CHECK: test_vst2q_u16
+// CHECK-LABEL: test_vst2q_u16
 // CHECK: vst2.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2q_u16(uint16_t * a, uint16x8x2_t b) {
   vst2q_u16(a, b);
 }
 
-// CHECK: test_vst2q_u32
+// CHECK-LABEL: test_vst2q_u32
 // CHECK: vst2.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2q_u32(uint32_t * a, uint32x4x2_t b) {
   vst2q_u32(a, b);
 }
 
-// CHECK: test_vst2q_s8
+// CHECK-LABEL: test_vst2q_s8
 // CHECK: vst2.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2q_s8(int8_t * a, int8x16x2_t b) {
   vst2q_s8(a, b);
 }
 
-// CHECK: test_vst2q_s16
+// CHECK-LABEL: test_vst2q_s16
 // CHECK: vst2.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2q_s16(int16_t * a, int16x8x2_t b) {
   vst2q_s16(a, b);
 }
 
-// CHECK: test_vst2q_s32
+// CHECK-LABEL: test_vst2q_s32
 // CHECK: vst2.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2q_s32(int32_t * a, int32x4x2_t b) {
   vst2q_s32(a, b);
 }
 
-// CHECK: test_vst2q_f16
+// CHECK-LABEL: test_vst2q_f16
 // CHECK: vst2.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2q_f16(float16_t * a, float16x8x2_t b) {
   vst2q_f16(a, b);
 }
 
-// CHECK: test_vst2q_f32
+// CHECK-LABEL: test_vst2q_f32
 // CHECK: vst2.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2q_f32(float32_t * a, float32x4x2_t b) {
   vst2q_f32(a, b);
 }
 
-// CHECK: test_vst2q_p8
+// CHECK-LABEL: test_vst2q_p8
 // CHECK: vst2.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2q_p8(poly8_t * a, poly8x16x2_t b) {
   vst2q_p8(a, b);
 }
 
-// CHECK: test_vst2q_p16
+// CHECK-LABEL: test_vst2q_p16
 // CHECK: vst2.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2q_p16(poly16_t * a, poly16x8x2_t b) {
   vst2q_p16(a, b);
 }
 
-// CHECK: test_vst2_u8
+// CHECK-LABEL: test_vst2_u8
 // CHECK: vst2.8 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2_u8(uint8_t * a, uint8x8x2_t b) {
   vst2_u8(a, b);
 }
 
-// CHECK: test_vst2_u16
+// CHECK-LABEL: test_vst2_u16
 // CHECK: vst2.16 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2_u16(uint16_t * a, uint16x4x2_t b) {
   vst2_u16(a, b);
 }
 
-// CHECK: test_vst2_u32
+// CHECK-LABEL: test_vst2_u32
 // CHECK: vst2.32 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2_u32(uint32_t * a, uint32x2x2_t b) {
   vst2_u32(a, b);
 }
 
-// CHECK: test_vst2_u64
+// CHECK-LABEL: test_vst2_u64
 // CHECK: vst1.64
 void test_vst2_u64(uint64_t * a, uint64x1x2_t b) {
   vst2_u64(a, b);
 }
 
-// CHECK: test_vst2_s8
+// CHECK-LABEL: test_vst2_s8
 // CHECK: vst2.8 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2_s8(int8_t * a, int8x8x2_t b) {
   vst2_s8(a, b);
 }
 
-// CHECK: test_vst2_s16
+// CHECK-LABEL: test_vst2_s16
 // CHECK: vst2.16 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2_s16(int16_t * a, int16x4x2_t b) {
   vst2_s16(a, b);
 }
 
-// CHECK: test_vst2_s32
+// CHECK-LABEL: test_vst2_s32
 // CHECK: vst2.32 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2_s32(int32_t * a, int32x2x2_t b) {
   vst2_s32(a, b);
 }
 
-// CHECK: test_vst2_s64
+// CHECK-LABEL: test_vst2_s64
 // CHECK: vst1.64
 void test_vst2_s64(int64_t * a, int64x1x2_t b) {
   vst2_s64(a, b);
 }
 
-// CHECK: test_vst2_f16
+// CHECK-LABEL: test_vst2_f16
 // CHECK: vst2.16 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2_f16(float16_t * a, float16x4x2_t b) {
   vst2_f16(a, b);
 }
 
-// CHECK: test_vst2_f32
+// CHECK-LABEL: test_vst2_f32
 // CHECK: vst2.32 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2_f32(float32_t * a, float32x2x2_t b) {
   vst2_f32(a, b);
 }
 
-// CHECK: test_vst2_p8
+// CHECK-LABEL: test_vst2_p8
 // CHECK: vst2.8 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2_p8(poly8_t * a, poly8x8x2_t b) {
   vst2_p8(a, b);
 }
 
-// CHECK: test_vst2_p16
+// CHECK-LABEL: test_vst2_p16
 // CHECK: vst2.16 {d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst2_p16(poly16_t * a, poly16x4x2_t b) {
   vst2_p16(a, b);
 }
 
 
-// CHECK: test_vst2q_lane_u16
+// CHECK-LABEL: test_vst2q_lane_u16
 // CHECK: vst2.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst2q_lane_u16(uint16_t * a, uint16x8x2_t b) {
   vst2q_lane_u16(a, b, 7);
 }
 
-// CHECK: test_vst2q_lane_u32
+// CHECK-LABEL: test_vst2q_lane_u32
 // CHECK: vst2.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst2q_lane_u32(uint32_t * a, uint32x4x2_t b) {
   vst2q_lane_u32(a, b, 3);
 }
 
-// CHECK: test_vst2q_lane_s16
+// CHECK-LABEL: test_vst2q_lane_s16
 // CHECK: vst2.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst2q_lane_s16(int16_t * a, int16x8x2_t b) {
   vst2q_lane_s16(a, b, 7);
 }
 
-// CHECK: test_vst2q_lane_s32
+// CHECK-LABEL: test_vst2q_lane_s32
 // CHECK: vst2.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst2q_lane_s32(int32_t * a, int32x4x2_t b) {
   vst2q_lane_s32(a, b, 3);
 }
 
-// CHECK: test_vst2q_lane_f16
+// CHECK-LABEL: test_vst2q_lane_f16
 // CHECK: vst2.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst2q_lane_f16(float16_t * a, float16x8x2_t b) {
   vst2q_lane_f16(a, b, 7);
 }
 
-// CHECK: test_vst2q_lane_f32
+// CHECK-LABEL: test_vst2q_lane_f32
 // CHECK: vst2.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst2q_lane_f32(float32_t * a, float32x4x2_t b) {
   vst2q_lane_f32(a, b, 3);
 }
 
-// CHECK: test_vst2q_lane_p16
+// CHECK-LABEL: test_vst2q_lane_p16
 // CHECK: vst2.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst2q_lane_p16(poly16_t * a, poly16x8x2_t b) {
   vst2q_lane_p16(a, b, 7);
 }
 
-// CHECK: test_vst2_lane_u8
+// CHECK-LABEL: test_vst2_lane_u8
 // CHECK: vst2.8 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst2_lane_u8(uint8_t * a, uint8x8x2_t b) {
   vst2_lane_u8(a, b, 7);
 }
 
-// CHECK: test_vst2_lane_u16
+// CHECK-LABEL: test_vst2_lane_u16
 // CHECK: vst2.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst2_lane_u16(uint16_t * a, uint16x4x2_t b) {
   vst2_lane_u16(a, b, 3);
 }
 
-// CHECK: test_vst2_lane_u32
+// CHECK-LABEL: test_vst2_lane_u32
 // CHECK: vst2.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst2_lane_u32(uint32_t * a, uint32x2x2_t b) {
   vst2_lane_u32(a, b, 1);
 }
 
-// CHECK: test_vst2_lane_s8
+// CHECK-LABEL: test_vst2_lane_s8
 // CHECK: vst2.8 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst2_lane_s8(int8_t * a, int8x8x2_t b) {
   vst2_lane_s8(a, b, 7);
 }
 
-// CHECK: test_vst2_lane_s16
+// CHECK-LABEL: test_vst2_lane_s16
 // CHECK: vst2.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst2_lane_s16(int16_t * a, int16x4x2_t b) {
   vst2_lane_s16(a, b, 3);
 }
 
-// CHECK: test_vst2_lane_s32
+// CHECK-LABEL: test_vst2_lane_s32
 // CHECK: vst2.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst2_lane_s32(int32_t * a, int32x2x2_t b) {
   vst2_lane_s32(a, b, 1);
 }
 
-// CHECK: test_vst2_lane_f16
+// CHECK-LABEL: test_vst2_lane_f16
 // CHECK: vst2.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst2_lane_f16(float16_t * a, float16x4x2_t b) {
   vst2_lane_f16(a, b, 3);
 }
 
-// CHECK: test_vst2_lane_f32
+// CHECK-LABEL: test_vst2_lane_f32
 // CHECK: vst2.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst2_lane_f32(float32_t * a, float32x2x2_t b) {
   vst2_lane_f32(a, b, 1);
 }
 
-// CHECK: test_vst2_lane_p8
+// CHECK-LABEL: test_vst2_lane_p8
 // CHECK: vst2.8 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst2_lane_p8(poly8_t * a, poly8x8x2_t b) {
   vst2_lane_p8(a, b, 7);
 }
 
-// CHECK: test_vst2_lane_p16
+// CHECK-LABEL: test_vst2_lane_p16
 // CHECK: vst2.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst2_lane_p16(poly16_t * a, poly16x4x2_t b) {
   vst2_lane_p16(a, b, 3);
 }
 
 
-// CHECK: test_vst3q_u8
+// CHECK-LABEL: test_vst3q_u8
 // CHECK: vst3.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst3q_u8(uint8_t * a, uint8x16x3_t b) {
   vst3q_u8(a, b);
 }
 
-// CHECK: test_vst3q_u16
+// CHECK-LABEL: test_vst3q_u16
 // CHECK: vst3.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst3q_u16(uint16_t * a, uint16x8x3_t b) {
   vst3q_u16(a, b);
 }
 
-// CHECK: test_vst3q_u32
+// CHECK-LABEL: test_vst3q_u32
 // CHECK: vst3.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst3q_u32(uint32_t * a, uint32x4x3_t b) {
   vst3q_u32(a, b);
 }
 
-// CHECK: test_vst3q_s8
+// CHECK-LABEL: test_vst3q_s8
 // CHECK: vst3.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst3q_s8(int8_t * a, int8x16x3_t b) {
   vst3q_s8(a, b);
 }
 
-// CHECK: test_vst3q_s16
+// CHECK-LABEL: test_vst3q_s16
 // CHECK: vst3.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst3q_s16(int16_t * a, int16x8x3_t b) {
   vst3q_s16(a, b);
 }
 
-// CHECK: test_vst3q_s32
+// CHECK-LABEL: test_vst3q_s32
 // CHECK: vst3.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst3q_s32(int32_t * a, int32x4x3_t b) {
   vst3q_s32(a, b);
 }
 
-// CHECK: test_vst3q_f16
+// CHECK-LABEL: test_vst3q_f16
 // CHECK: vst3.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst3q_f16(float16_t * a, float16x8x3_t b) {
   vst3q_f16(a, b);
 }
 
-// CHECK: test_vst3q_f32
+// CHECK-LABEL: test_vst3q_f32
 // CHECK: vst3.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst3q_f32(float32_t * a, float32x4x3_t b) {
   vst3q_f32(a, b);
 }
 
-// CHECK: test_vst3q_p8
+// CHECK-LABEL: test_vst3q_p8
 // CHECK: vst3.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst3q_p8(poly8_t * a, poly8x16x3_t b) {
   vst3q_p8(a, b);
 }
 
-// CHECK: test_vst3q_p16
+// CHECK-LABEL: test_vst3q_p16
 // CHECK: vst3.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst3q_p16(poly16_t * a, poly16x8x3_t b) {
   vst3q_p16(a, b);
 }
 
-// CHECK: test_vst3_u8
+// CHECK-LABEL: test_vst3_u8
 // CHECK: vst3.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst3_u8(uint8_t * a, uint8x8x3_t b) {
   vst3_u8(a, b);
 }
 
-// CHECK: test_vst3_u16
+// CHECK-LABEL: test_vst3_u16
 // CHECK: vst3.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst3_u16(uint16_t * a, uint16x4x3_t b) {
   vst3_u16(a, b);
 }
 
-// CHECK: test_vst3_u32
+// CHECK-LABEL: test_vst3_u32
 // CHECK: vst3.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst3_u32(uint32_t * a, uint32x2x3_t b) {
   vst3_u32(a, b);
 }
 
-// CHECK: test_vst3_u64
+// CHECK-LABEL: test_vst3_u64
 // CHECK: vst1.64
 void test_vst3_u64(uint64_t * a, uint64x1x3_t b) {
   vst3_u64(a, b);
 }
 
-// CHECK: test_vst3_s8
+// CHECK-LABEL: test_vst3_s8
 // CHECK: vst3.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst3_s8(int8_t * a, int8x8x3_t b) {
   vst3_s8(a, b);
 }
 
-// CHECK: test_vst3_s16
+// CHECK-LABEL: test_vst3_s16
 // CHECK: vst3.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst3_s16(int16_t * a, int16x4x3_t b) {
   vst3_s16(a, b);
 }
 
-// CHECK: test_vst3_s32
+// CHECK-LABEL: test_vst3_s32
 // CHECK: vst3.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst3_s32(int32_t * a, int32x2x3_t b) {
   vst3_s32(a, b);
 }
 
-// CHECK: test_vst3_s64
+// CHECK-LABEL: test_vst3_s64
 // CHECK: vst1.64
 void test_vst3_s64(int64_t * a, int64x1x3_t b) {
   vst3_s64(a, b);
 }
 
-// CHECK: test_vst3_f16
+// CHECK-LABEL: test_vst3_f16
 // CHECK: vst3.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst3_f16(float16_t * a, float16x4x3_t b) {
   vst3_f16(a, b);
 }
 
-// CHECK: test_vst3_f32
+// CHECK-LABEL: test_vst3_f32
 // CHECK: vst3.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst3_f32(float32_t * a, float32x2x3_t b) {
   vst3_f32(a, b);
 }
 
-// CHECK: test_vst3_p8
+// CHECK-LABEL: test_vst3_p8
 // CHECK: vst3.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst3_p8(poly8_t * a, poly8x8x3_t b) {
   vst3_p8(a, b);
 }
 
-// CHECK: test_vst3_p16
+// CHECK-LABEL: test_vst3_p16
 // CHECK: vst3.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst3_p16(poly16_t * a, poly16x4x3_t b) {
   vst3_p16(a, b);
 }
 
 
-// CHECK: test_vst3q_lane_u16
+// CHECK-LABEL: test_vst3q_lane_u16
 // CHECK: vst3.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 void test_vst3q_lane_u16(uint16_t * a, uint16x8x3_t b) {
   vst3q_lane_u16(a, b, 7);
 }
 
-// CHECK: test_vst3q_lane_u32
+// CHECK-LABEL: test_vst3q_lane_u32
 // CHECK: vst3.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 void test_vst3q_lane_u32(uint32_t * a, uint32x4x3_t b) {
   vst3q_lane_u32(a, b, 3);
 }
 
-// CHECK: test_vst3q_lane_s16
+// CHECK-LABEL: test_vst3q_lane_s16
 // CHECK: vst3.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 void test_vst3q_lane_s16(int16_t * a, int16x8x3_t b) {
   vst3q_lane_s16(a, b, 7);
 }
 
-// CHECK: test_vst3q_lane_s32
+// CHECK-LABEL: test_vst3q_lane_s32
 // CHECK: vst3.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 void test_vst3q_lane_s32(int32_t * a, int32x4x3_t b) {
   vst3q_lane_s32(a, b, 3);
 }
 
-// CHECK: test_vst3q_lane_f16
+// CHECK-LABEL: test_vst3q_lane_f16
 // CHECK: vst3.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 void test_vst3q_lane_f16(float16_t * a, float16x8x3_t b) {
   vst3q_lane_f16(a, b, 7);
 }
 
-// CHECK: test_vst3q_lane_f32
+// CHECK-LABEL: test_vst3q_lane_f32
 // CHECK: vst3.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 void test_vst3q_lane_f32(float32_t * a, float32x4x3_t b) {
   vst3q_lane_f32(a, b, 3);
 }
 
-// CHECK: test_vst3q_lane_p16
+// CHECK-LABEL: test_vst3q_lane_p16
 // CHECK: vst3.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 void test_vst3q_lane_p16(poly16_t * a, poly16x8x3_t b) {
   vst3q_lane_p16(a, b, 7);
 }
 
-// CHECK: test_vst3_lane_u8
+// CHECK-LABEL: test_vst3_lane_u8
 // CHECK: vst3.8 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst3_lane_u8(uint8_t * a, uint8x8x3_t b) {
   vst3_lane_u8(a, b, 7);
 }
 
-// CHECK: test_vst3_lane_u16
+// CHECK-LABEL: test_vst3_lane_u16
 // CHECK: vst3.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst3_lane_u16(uint16_t * a, uint16x4x3_t b) {
   vst3_lane_u16(a, b, 3);
 }
 
-// CHECK: test_vst3_lane_u32
+// CHECK-LABEL: test_vst3_lane_u32
 // CHECK: vst3.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst3_lane_u32(uint32_t * a, uint32x2x3_t b) {
   vst3_lane_u32(a, b, 1);
 }
 
-// CHECK: test_vst3_lane_s8
+// CHECK-LABEL: test_vst3_lane_s8
 // CHECK: vst3.8 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst3_lane_s8(int8_t * a, int8x8x3_t b) {
   vst3_lane_s8(a, b, 7);
 }
 
-// CHECK: test_vst3_lane_s16
+// CHECK-LABEL: test_vst3_lane_s16
 // CHECK: vst3.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst3_lane_s16(int16_t * a, int16x4x3_t b) {
   vst3_lane_s16(a, b, 3);
 }
 
-// CHECK: test_vst3_lane_s32
+// CHECK-LABEL: test_vst3_lane_s32
 // CHECK: vst3.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst3_lane_s32(int32_t * a, int32x2x3_t b) {
   vst3_lane_s32(a, b, 1);
 }
 
-// CHECK: test_vst3_lane_f16
+// CHECK-LABEL: test_vst3_lane_f16
 // CHECK: vst3.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst3_lane_f16(float16_t * a, float16x4x3_t b) {
   vst3_lane_f16(a, b, 3);
 }
 
-// CHECK: test_vst3_lane_f32
+// CHECK-LABEL: test_vst3_lane_f32
 // CHECK: vst3.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst3_lane_f32(float32_t * a, float32x2x3_t b) {
   vst3_lane_f32(a, b, 1);
 }
 
-// CHECK: test_vst3_lane_p8
+// CHECK-LABEL: test_vst3_lane_p8
 // CHECK: vst3.8 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst3_lane_p8(poly8_t * a, poly8x8x3_t b) {
   vst3_lane_p8(a, b, 7);
 }
 
-// CHECK: test_vst3_lane_p16
+// CHECK-LABEL: test_vst3_lane_p16
 // CHECK: vst3.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst3_lane_p16(poly16_t * a, poly16x4x3_t b) {
   vst3_lane_p16(a, b, 3);
 }
 
 
-// CHECK: test_vst4q_u8
+// CHECK-LABEL: test_vst4q_u8
 // CHECK: vst4.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst4q_u8(uint8_t * a, uint8x16x4_t b) {
   vst4q_u8(a, b);
 }
 
-// CHECK: test_vst4q_u16
+// CHECK-LABEL: test_vst4q_u16
 // CHECK: vst4.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst4q_u16(uint16_t * a, uint16x8x4_t b) {
   vst4q_u16(a, b);
 }
 
-// CHECK: test_vst4q_u32
+// CHECK-LABEL: test_vst4q_u32
 // CHECK: vst4.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst4q_u32(uint32_t * a, uint32x4x4_t b) {
   vst4q_u32(a, b);
 }
 
-// CHECK: test_vst4q_s8
+// CHECK-LABEL: test_vst4q_s8
 // CHECK: vst4.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst4q_s8(int8_t * a, int8x16x4_t b) {
   vst4q_s8(a, b);
 }
 
-// CHECK: test_vst4q_s16
+// CHECK-LABEL: test_vst4q_s16
 // CHECK: vst4.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst4q_s16(int16_t * a, int16x8x4_t b) {
   vst4q_s16(a, b);
 }
 
-// CHECK: test_vst4q_s32
+// CHECK-LABEL: test_vst4q_s32
 // CHECK: vst4.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst4q_s32(int32_t * a, int32x4x4_t b) {
   vst4q_s32(a, b);
 }
 
-// CHECK: test_vst4q_f16
+// CHECK-LABEL: test_vst4q_f16
 // CHECK: vst4.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst4q_f16(float16_t * a, float16x8x4_t b) {
   vst4q_f16(a, b);
 }
 
-// CHECK: test_vst4q_f32
+// CHECK-LABEL: test_vst4q_f32
 // CHECK: vst4.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst4q_f32(float32_t * a, float32x4x4_t b) {
   vst4q_f32(a, b);
 }
 
-// CHECK: test_vst4q_p8
+// CHECK-LABEL: test_vst4q_p8
 // CHECK: vst4.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst4q_p8(poly8_t * a, poly8x16x4_t b) {
   vst4q_p8(a, b);
 }
 
-// CHECK: test_vst4q_p16
+// CHECK-LABEL: test_vst4q_p16
 // CHECK: vst4.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}
 void test_vst4q_p16(poly16_t * a, poly16x8x4_t b) {
   vst4q_p16(a, b);
 }
 
-// CHECK: test_vst4_u8
+// CHECK-LABEL: test_vst4_u8
 // CHECK: vst4.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst4_u8(uint8_t * a, uint8x8x4_t b) {
   vst4_u8(a, b);
 }
 
-// CHECK: test_vst4_u16
+// CHECK-LABEL: test_vst4_u16
 // CHECK: vst4.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst4_u16(uint16_t * a, uint16x4x4_t b) {
   vst4_u16(a, b);
 }
 
-// CHECK: test_vst4_u32
+// CHECK-LABEL: test_vst4_u32
 // CHECK: vst4.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst4_u32(uint32_t * a, uint32x2x4_t b) {
   vst4_u32(a, b);
 }
 
-// CHECK: test_vst4_u64
+// CHECK-LABEL: test_vst4_u64
 // CHECK: vst1.64
 void test_vst4_u64(uint64_t * a, uint64x1x4_t b) {
   vst4_u64(a, b);
 }
 
-// CHECK: test_vst4_s8
+// CHECK-LABEL: test_vst4_s8
 // CHECK: vst4.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst4_s8(int8_t * a, int8x8x4_t b) {
   vst4_s8(a, b);
 }
 
-// CHECK: test_vst4_s16
+// CHECK-LABEL: test_vst4_s16
 // CHECK: vst4.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst4_s16(int16_t * a, int16x4x4_t b) {
   vst4_s16(a, b);
 }
 
-// CHECK: test_vst4_s32
+// CHECK-LABEL: test_vst4_s32
 // CHECK: vst4.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst4_s32(int32_t * a, int32x2x4_t b) {
   vst4_s32(a, b);
 }
 
-// CHECK: test_vst4_s64
+// CHECK-LABEL: test_vst4_s64
 // CHECK: vst1.64
 void test_vst4_s64(int64_t * a, int64x1x4_t b) {
   vst4_s64(a, b);
 }
 
-// CHECK: test_vst4_f16
+// CHECK-LABEL: test_vst4_f16
 // CHECK: vst4.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst4_f16(float16_t * a, float16x4x4_t b) {
   vst4_f16(a, b);
 }
 
-// CHECK: test_vst4_f32
+// CHECK-LABEL: test_vst4_f32
 // CHECK: vst4.32 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst4_f32(float32_t * a, float32x2x4_t b) {
   vst4_f32(a, b);
 }
 
-// CHECK: test_vst4_p8
+// CHECK-LABEL: test_vst4_p8
 // CHECK: vst4.8 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst4_p8(poly8_t * a, poly8x8x4_t b) {
   vst4_p8(a, b);
 }
 
-// CHECK: test_vst4_p16
+// CHECK-LABEL: test_vst4_p16
 // CHECK: vst4.16 {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, [r{{[0-9]+}}]
 void test_vst4_p16(poly16_t * a, poly16x4x4_t b) {
   vst4_p16(a, b);
 }
 
 
-// CHECK: test_vst4q_lane_u16
+// CHECK-LABEL: test_vst4q_lane_u16
 // CHECK: vst4.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 void test_vst4q_lane_u16(uint16_t * a, uint16x8x4_t b) {
   vst4q_lane_u16(a, b, 7);
 }
 
-// CHECK: test_vst4q_lane_u32
+// CHECK-LABEL: test_vst4q_lane_u32
 // CHECK: vst4.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 void test_vst4q_lane_u32(uint32_t * a, uint32x4x4_t b) {
   vst4q_lane_u32(a, b, 3);
 }
 
-// CHECK: test_vst4q_lane_s16
+// CHECK-LABEL: test_vst4q_lane_s16
 // CHECK: vst4.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 void test_vst4q_lane_s16(int16_t * a, int16x8x4_t b) {
   vst4q_lane_s16(a, b, 7);
 }
 
-// CHECK: test_vst4q_lane_s32
+// CHECK-LABEL: test_vst4q_lane_s32
 // CHECK: vst4.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 void test_vst4q_lane_s32(int32_t * a, int32x4x4_t b) {
   vst4q_lane_s32(a, b, 3);
 }
 
-// CHECK: test_vst4q_lane_f16
+// CHECK-LABEL: test_vst4q_lane_f16
 // CHECK: vst4.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 void test_vst4q_lane_f16(float16_t * a, float16x8x4_t b) {
   vst4q_lane_f16(a, b, 7);
 }
 
-// CHECK: test_vst4q_lane_f32
+// CHECK-LABEL: test_vst4q_lane_f32
 // CHECK: vst4.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 void test_vst4q_lane_f32(float32_t * a, float32x4x4_t b) {
   vst4q_lane_f32(a, b, 3);
 }
 
-// CHECK: test_vst4q_lane_p16
+// CHECK-LABEL: test_vst4q_lane_p16
 // CHECK: vst4.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}
 void test_vst4q_lane_p16(poly16_t * a, poly16x8x4_t b) {
   vst4q_lane_p16(a, b, 7);
 }
 
-// CHECK: test_vst4_lane_u8
+// CHECK-LABEL: test_vst4_lane_u8
 // CHECK: vst4.8 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst4_lane_u8(uint8_t * a, uint8x8x4_t b) {
   vst4_lane_u8(a, b, 7);
 }
 
-// CHECK: test_vst4_lane_u16
+// CHECK-LABEL: test_vst4_lane_u16
 // CHECK: vst4.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst4_lane_u16(uint16_t * a, uint16x4x4_t b) {
   vst4_lane_u16(a, b, 3);
 }
 
-// CHECK: test_vst4_lane_u32
+// CHECK-LABEL: test_vst4_lane_u32
 // CHECK: vst4.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst4_lane_u32(uint32_t * a, uint32x2x4_t b) {
   vst4_lane_u32(a, b, 1);
 }
 
-// CHECK: test_vst4_lane_s8
+// CHECK-LABEL: test_vst4_lane_s8
 // CHECK: vst4.8 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst4_lane_s8(int8_t * a, int8x8x4_t b) {
   vst4_lane_s8(a, b, 7);
 }
 
-// CHECK: test_vst4_lane_s16
+// CHECK-LABEL: test_vst4_lane_s16
 // CHECK: vst4.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst4_lane_s16(int16_t * a, int16x4x4_t b) {
   vst4_lane_s16(a, b, 3);
 }
 
-// CHECK: test_vst4_lane_s32
+// CHECK-LABEL: test_vst4_lane_s32
 // CHECK: vst4.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst4_lane_s32(int32_t * a, int32x2x4_t b) {
   vst4_lane_s32(a, b, 1);
 }
 
-// CHECK: test_vst4_lane_f16
+// CHECK-LABEL: test_vst4_lane_f16
 // CHECK: vst4.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst4_lane_f16(float16_t * a, float16x4x4_t b) {
   vst4_lane_f16(a, b, 3);
 }
 
-// CHECK: test_vst4_lane_f32
+// CHECK-LABEL: test_vst4_lane_f32
 // CHECK: vst4.32 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst4_lane_f32(float32_t * a, float32x2x4_t b) {
   vst4_lane_f32(a, b, 1);
 }
 
-// CHECK: test_vst4_lane_p8
+// CHECK-LABEL: test_vst4_lane_p8
 // CHECK: vst4.8 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst4_lane_p8(poly8_t * a, poly8x8x4_t b) {
   vst4_lane_p8(a, b, 7);
 }
 
-// CHECK: test_vst4_lane_p16
+// CHECK-LABEL: test_vst4_lane_p16
 // CHECK: vst4.16 {d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}], d{{[0-9]+}}[{{[0-9]+}}]}, [r{{[0-9]+}}]
 void test_vst4_lane_p16(poly16_t * a, poly16x4x4_t b) {
   vst4_lane_p16(a, b, 3);
 }
 
 
-// CHECK: test_vsub_s8
+// CHECK-LABEL: test_vsub_s8
 // CHECK: vsub.i8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int8x8_t test_vsub_s8(int8x8_t a, int8x8_t b) {
   return vsub_s8(a, b);
 }
 
-// CHECK: test_vsub_s16
+// CHECK-LABEL: test_vsub_s16
 // CHECK: vsub.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x4_t test_vsub_s16(int16x4_t a, int16x4_t b) {
   return vsub_s16(a, b);
 }
 
-// CHECK: test_vsub_s32
+// CHECK-LABEL: test_vsub_s32
 // CHECK: vsub.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x2_t test_vsub_s32(int32x2_t a, int32x2_t b) {
   return vsub_s32(a, b);
 }
 
-// CHECK: test_vsub_s64
+// CHECK-LABEL: test_vsub_s64
 // CHECK: vsub.i64 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x1_t test_vsub_s64(int64x1_t a, int64x1_t b) {
   return vsub_s64(a, b);
 }
 
-// CHECK: test_vsub_f32
+// CHECK-LABEL: test_vsub_f32
 // CHECK: vsub.f32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 float32x2_t test_vsub_f32(float32x2_t a, float32x2_t b) {
   return vsub_f32(a, b);
 }
 
-// CHECK: test_vsub_u8
+// CHECK-LABEL: test_vsub_u8
 // CHECK: vsub.i8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vsub_u8(uint8x8_t a, uint8x8_t b) {
   return vsub_u8(a, b);
 }
 
-// CHECK: test_vsub_u16
+// CHECK-LABEL: test_vsub_u16
 // CHECK: vsub.i16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vsub_u16(uint16x4_t a, uint16x4_t b) {
   return vsub_u16(a, b);
 }
 
-// CHECK: test_vsub_u32
+// CHECK-LABEL: test_vsub_u32
 // CHECK: vsub.i32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vsub_u32(uint32x2_t a, uint32x2_t b) {
   return vsub_u32(a, b);
 }
 
-// CHECK: test_vsub_u64
+// CHECK-LABEL: test_vsub_u64
 // CHECK: vsub.i64 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x1_t test_vsub_u64(uint64x1_t a, uint64x1_t b) {
   return vsub_u64(a, b);
 }
 
-// CHECK: test_vsubq_s8
+// CHECK-LABEL: test_vsubq_s8
 // CHECK: vsub.i8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x16_t test_vsubq_s8(int8x16_t a, int8x16_t b) {
   return vsubq_s8(a, b);
 }
 
-// CHECK: test_vsubq_s16
+// CHECK-LABEL: test_vsubq_s16
 // CHECK: vsub.i16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x8_t test_vsubq_s16(int16x8_t a, int16x8_t b) {
   return vsubq_s16(a, b);
 }
 
-// CHECK: test_vsubq_s32
+// CHECK-LABEL: test_vsubq_s32
 // CHECK: vsub.i32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x4_t test_vsubq_s32(int32x4_t a, int32x4_t b) {
   return vsubq_s32(a, b);
 }
 
-// CHECK: test_vsubq_s64
+// CHECK-LABEL: test_vsubq_s64
 // CHECK: vsub.i64 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int64x2_t test_vsubq_s64(int64x2_t a, int64x2_t b) {
   return vsubq_s64(a, b);
 }
 
-// CHECK: test_vsubq_f32
+// CHECK-LABEL: test_vsubq_f32
 // CHECK: vsub.f32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 float32x4_t test_vsubq_f32(float32x4_t a, float32x4_t b) {
   return vsubq_f32(a, b);
 }
 
-// CHECK: test_vsubq_u8
+// CHECK-LABEL: test_vsubq_u8
 // CHECK: vsub.i8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vsubq_u8(uint8x16_t a, uint8x16_t b) {
   return vsubq_u8(a, b);
 }
 
-// CHECK: test_vsubq_u16
+// CHECK-LABEL: test_vsubq_u16
 // CHECK: vsub.i16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vsubq_u16(uint16x8_t a, uint16x8_t b) {
   return vsubq_u16(a, b);
 }
 
-// CHECK: test_vsubq_u32
+// CHECK-LABEL: test_vsubq_u32
 // CHECK: vsub.i32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vsubq_u32(uint32x4_t a, uint32x4_t b) {
   return vsubq_u32(a, b);
 }
 
-// CHECK: test_vsubq_u64
+// CHECK-LABEL: test_vsubq_u64
 // CHECK: vsub.i64 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint64x2_t test_vsubq_u64(uint64x2_t a, uint64x2_t b) {
   return vsubq_u64(a, b);
 }
 
 
-// CHECK: test_vsubhn_s16
+// CHECK-LABEL: test_vsubhn_s16
 // CHECK: vsubhn.i16 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int8x8_t test_vsubhn_s16(int16x8_t a, int16x8_t b) {
   return vsubhn_s16(a, b);
 }
 
-// CHECK: test_vsubhn_s32
+// CHECK-LABEL: test_vsubhn_s32
 // CHECK: vsubhn.i32 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int16x4_t test_vsubhn_s32(int32x4_t a, int32x4_t b) {
   return vsubhn_s32(a, b);
 }
 
-// CHECK: test_vsubhn_s64
+// CHECK-LABEL: test_vsubhn_s64
 // CHECK: vsubhn.i64 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 int32x2_t test_vsubhn_s64(int64x2_t a, int64x2_t b) {
   return vsubhn_s64(a, b);
 }
 
-// CHECK: test_vsubhn_u16
+// CHECK-LABEL: test_vsubhn_u16
 // CHECK: vsubhn.i16 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x8_t test_vsubhn_u16(uint16x8_t a, uint16x8_t b) {
   return vsubhn_u16(a, b);
 }
 
-// CHECK: test_vsubhn_u32
+// CHECK-LABEL: test_vsubhn_u32
 // CHECK: vsubhn.i32 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x4_t test_vsubhn_u32(uint32x4_t a, uint32x4_t b) {
   return vsubhn_u32(a, b);
 }
 
-// CHECK: test_vsubhn_u64
+// CHECK-LABEL: test_vsubhn_u64
 // CHECK: vsubhn.i64 d{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x2_t test_vsubhn_u64(uint64x2_t a, uint64x2_t b) {
   return vsubhn_u64(a, b);
 }
 
 
-// CHECK: test_vsubl_s8
+// CHECK-LABEL: test_vsubl_s8
 // CHECK: vsubl.s8 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int16x8_t test_vsubl_s8(int8x8_t a, int8x8_t b) {
   return vsubl_s8(a, b);
 }
 
-// CHECK: test_vsubl_s16
+// CHECK-LABEL: test_vsubl_s16
 // CHECK: vsubl.s16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vsubl_s16(int16x4_t a, int16x4_t b) {
   return vsubl_s16(a, b);
 }
 
-// CHECK: test_vsubl_s32
+// CHECK-LABEL: test_vsubl_s32
 // CHECK: vsubl.s32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vsubl_s32(int32x2_t a, int32x2_t b) {
   return vsubl_s32(a, b);
 }
 
-// CHECK: test_vsubl_u8
+// CHECK-LABEL: test_vsubl_u8
 // CHECK: vsubl.u8 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x8_t test_vsubl_u8(uint8x8_t a, uint8x8_t b) {
   return vsubl_u8(a, b);
 }
 
-// CHECK: test_vsubl_u16
+// CHECK-LABEL: test_vsubl_u16
 // CHECK: vsubl.u16 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x4_t test_vsubl_u16(uint16x4_t a, uint16x4_t b) {
   return vsubl_u16(a, b);
 }
 
-// CHECK: test_vsubl_u32
+// CHECK-LABEL: test_vsubl_u32
 // CHECK: vsubl.u32 q{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint64x2_t test_vsubl_u32(uint32x2_t a, uint32x2_t b) {
   return vsubl_u32(a, b);
 }
 
 
-// CHECK: test_vsubw_s8
+// CHECK-LABEL: test_vsubw_s8
 // CHECK: vsubw.s8 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}
 int16x8_t test_vsubw_s8(int16x8_t a, int8x8_t b) {
   return vsubw_s8(a, b);
 }
 
-// CHECK: test_vsubw_s16
+// CHECK-LABEL: test_vsubw_s16
 // CHECK: vsubw.s16 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}
 int32x4_t test_vsubw_s16(int32x4_t a, int16x4_t b) {
   return vsubw_s16(a, b);
 }
 
-// CHECK: test_vsubw_s32
+// CHECK-LABEL: test_vsubw_s32
 // CHECK: vsubw.s32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}
 int64x2_t test_vsubw_s32(int64x2_t a, int32x2_t b) {
   return vsubw_s32(a, b);
 }
 
-// CHECK: test_vsubw_u8
+// CHECK-LABEL: test_vsubw_u8
 // CHECK: vsubw.u8 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}
 uint16x8_t test_vsubw_u8(uint16x8_t a, uint8x8_t b) {
   return vsubw_u8(a, b);
 }
 
-// CHECK: test_vsubw_u16
+// CHECK-LABEL: test_vsubw_u16
 // CHECK: vsubw.u16 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}
 uint32x4_t test_vsubw_u16(uint32x4_t a, uint16x4_t b) {
   return vsubw_u16(a, b);
 }
 
-// CHECK: test_vsubw_u32
+// CHECK-LABEL: test_vsubw_u32
 // CHECK: vsubw.u32 q{{[0-9]+}}, q{{[0-9]+}}, d{{[0-9]+}}
 uint64x2_t test_vsubw_u32(uint64x2_t a, uint32x2_t b) {
   return vsubw_u32(a, b);
 }
 
 
-// CHECK: test_vtbl1_u8
+// CHECK-LABEL: test_vtbl1_u8
 // CHECK: vtbl.8 d{{[0-9]+}}, {d{{[0-9]+}}}, d{{[0-9]+}}
 uint8x8_t test_vtbl1_u8(uint8x8_t a, uint8x8_t b) {
   return vtbl1_u8(a, b);
 }
 
-// CHECK: test_vtbl1_s8
+// CHECK-LABEL: test_vtbl1_s8
 // CHECK: vtbl.8 d{{[0-9]+}}, {d{{[0-9]+}}}, d{{[0-9]+}}
 int8x8_t test_vtbl1_s8(int8x8_t a, int8x8_t b) {
   return vtbl1_s8(a, b);
 }
 
-// CHECK: test_vtbl1_p8
+// CHECK-LABEL: test_vtbl1_p8
 // CHECK: vtbl.8 d{{[0-9]+}}, {d{{[0-9]+}}}, d{{[0-9]+}}
 poly8x8_t test_vtbl1_p8(poly8x8_t a, uint8x8_t b) {
   return vtbl1_p8(a, b);
 }
 
 
-// CHECK: test_vtbl2_u8
+// CHECK-LABEL: test_vtbl2_u8
 // CHECK: vtbl.8 d{{[0-9]+}}, {d{{[0-9]+}}, d{{[0-9]+}}}, d{{[0-9]+}}
 uint8x8_t test_vtbl2_u8(uint8x8x2_t a, uint8x8_t b) {
   return vtbl2_u8(a, b);
 }
 
-// CHECK: test_vtbl2_s8
+// CHECK-LABEL: test_vtbl2_s8
 // CHECK: vtbl.8 d{{[0-9]+}}, {d{{[0-9]+}}, d{{[0-9]+}}}, d{{[0-9]+}}
 int8x8_t test_vtbl2_s8(int8x8x2_t a, int8x8_t b) {
   return vtbl2_s8(a, b);
 }
 
-// CHECK: test_vtbl2_p8
+// CHECK-LABEL: test_vtbl2_p8
 // CHECK: vtbl.8 d{{[0-9]+}}, {d{{[0-9]+}}, d{{[0-9]+}}}, d{{[0-9]+}}
 poly8x8_t test_vtbl2_p8(poly8x8x2_t a, uint8x8_t b) {
   return vtbl2_p8(a, b);
 }
 
 
-// CHECK: test_vtbl3_u8
+// CHECK-LABEL: test_vtbl3_u8
 // CHECK: vtbl.8 d{{[0-9]+}}, {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, d{{[0-9]+}}
 uint8x8_t test_vtbl3_u8(uint8x8x3_t a, uint8x8_t b) {
   return vtbl3_u8(a, b);
 }
 
-// CHECK: test_vtbl3_s8
+// CHECK-LABEL: test_vtbl3_s8
 // CHECK: vtbl.8 d{{[0-9]+}}, {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, d{{[0-9]+}}
 int8x8_t test_vtbl3_s8(int8x8x3_t a, int8x8_t b) {
   return vtbl3_s8(a, b);
 }
 
-// CHECK: test_vtbl3_p8
+// CHECK-LABEL: test_vtbl3_p8
 // CHECK: vtbl.8 d{{[0-9]+}}, {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, d{{[0-9]+}}
 poly8x8_t test_vtbl3_p8(poly8x8x3_t a, uint8x8_t b) {
   return vtbl3_p8(a, b);
 }
 
 
-// CHECK: test_vtbl4_u8
+// CHECK-LABEL: test_vtbl4_u8
 // CHECK: vtbl.8 d{{[0-9]+}}, {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, d{{[0-9]+}}
 uint8x8_t test_vtbl4_u8(uint8x8x4_t a, uint8x8_t b) {
   return vtbl4_u8(a, b);
 }
 
-// CHECK: test_vtbl4_s8
+// CHECK-LABEL: test_vtbl4_s8
 // CHECK: vtbl.8 d{{[0-9]+}}, {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, d{{[0-9]+}}
 int8x8_t test_vtbl4_s8(int8x8x4_t a, int8x8_t b) {
   return vtbl4_s8(a, b);
 }
 
-// CHECK: test_vtbl4_p8
+// CHECK-LABEL: test_vtbl4_p8
 // CHECK: vtbl.8 d{{[0-9]+}}, {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, d{{[0-9]+}}
 poly8x8_t test_vtbl4_p8(poly8x8x4_t a, uint8x8_t b) {
   return vtbl4_p8(a, b);
 }
 
 
-// CHECK: test_vtbx1_u8
+// CHECK-LABEL: test_vtbx1_u8
 // CHECK: vtbx.8 d{{[0-9]+}}, {d{{[0-9]+}}}, d{{[0-9]+}}
 uint8x8_t test_vtbx1_u8(uint8x8_t a, uint8x8_t b, uint8x8_t c) {
   return vtbx1_u8(a, b, c);
 }
 
-// CHECK: test_vtbx1_s8
+// CHECK-LABEL: test_vtbx1_s8
 // CHECK: vtbx.8 d{{[0-9]+}}, {d{{[0-9]+}}}, d{{[0-9]+}}
 int8x8_t test_vtbx1_s8(int8x8_t a, int8x8_t b, int8x8_t c) {
   return vtbx1_s8(a, b, c);
 }
 
-// CHECK: test_vtbx1_p8
+// CHECK-LABEL: test_vtbx1_p8
 // CHECK: vtbx.8 d{{[0-9]+}}, {d{{[0-9]+}}}, d{{[0-9]+}}
 poly8x8_t test_vtbx1_p8(poly8x8_t a, poly8x8_t b, uint8x8_t c) {
   return vtbx1_p8(a, b, c);
 }
 
 
-// CHECK: test_vtbx2_u8
+// CHECK-LABEL: test_vtbx2_u8
 // CHECK: vtbx.8 d{{[0-9]+}}, {d{{[0-9]+}}, d{{[0-9]+}}}, d{{[0-9]+}}
 uint8x8_t test_vtbx2_u8(uint8x8_t a, uint8x8x2_t b, uint8x8_t c) {
   return vtbx2_u8(a, b, c);
 }
 
-// CHECK: test_vtbx2_s8
+// CHECK-LABEL: test_vtbx2_s8
 // CHECK: vtbx.8 d{{[0-9]+}}, {d{{[0-9]+}}, d{{[0-9]+}}}, d{{[0-9]+}}
 int8x8_t test_vtbx2_s8(int8x8_t a, int8x8x2_t b, int8x8_t c) {
   return vtbx2_s8(a, b, c);
 }
 
-// CHECK: test_vtbx2_p8
+// CHECK-LABEL: test_vtbx2_p8
 // CHECK: vtbx.8 d{{[0-9]+}}, {d{{[0-9]+}}, d{{[0-9]+}}}, d{{[0-9]+}}
 poly8x8_t test_vtbx2_p8(poly8x8_t a, poly8x8x2_t b, uint8x8_t c) {
   return vtbx2_p8(a, b, c);
 }
 
 
-// CHECK: test_vtbx3_u8
+// CHECK-LABEL: test_vtbx3_u8
 // CHECK: vtbx.8 d{{[0-9]+}}, {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, d{{[0-9]+}}
 uint8x8_t test_vtbx3_u8(uint8x8_t a, uint8x8x3_t b, uint8x8_t c) {
   return vtbx3_u8(a, b, c);
 }
 
-// CHECK: test_vtbx3_s8
+// CHECK-LABEL: test_vtbx3_s8
 // CHECK: vtbx.8 d{{[0-9]+}}, {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, d{{[0-9]+}}
 int8x8_t test_vtbx3_s8(int8x8_t a, int8x8x3_t b, int8x8_t c) {
   return vtbx3_s8(a, b, c);
 }
 
-// CHECK: test_vtbx3_p8
+// CHECK-LABEL: test_vtbx3_p8
 // CHECK: vtbx.8 d{{[0-9]+}}, {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, d{{[0-9]+}}
 poly8x8_t test_vtbx3_p8(poly8x8_t a, poly8x8x3_t b, uint8x8_t c) {
   return vtbx3_p8(a, b, c);
 }
 
 
-// CHECK: test_vtbx4_u8
+// CHECK-LABEL: test_vtbx4_u8
 // CHECK: vtbx.8 d{{[0-9]+}}, {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, d{{[0-9]+}}
 uint8x8_t test_vtbx4_u8(uint8x8_t a, uint8x8x4_t b, uint8x8_t c) {
   return vtbx4_u8(a, b, c);
 }
 
-// CHECK: test_vtbx4_s8
+// CHECK-LABEL: test_vtbx4_s8
 // CHECK: vtbx.8 d{{[0-9]+}}, {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, d{{[0-9]+}}
 int8x8_t test_vtbx4_s8(int8x8_t a, int8x8x4_t b, int8x8_t c) {
   return vtbx4_s8(a, b, c);
 }
 
-// CHECK: test_vtbx4_p8
+// CHECK-LABEL: test_vtbx4_p8
 // CHECK: vtbx.8 d{{[0-9]+}}, {d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}}, d{{[0-9]+}}
 poly8x8_t test_vtbx4_p8(poly8x8_t a, poly8x8x4_t b, uint8x8_t c) {
   return vtbx4_p8(a, b, c);
 }
 
 
-// CHECK: test_vtrn_s8
+// CHECK-LABEL: test_vtrn_s8
 // CHECK: vtrn.8 d{{[0-9]+}}, d{{[0-9]+}}
 int8x8x2_t test_vtrn_s8(int8x8_t a, int8x8_t b) {
   return vtrn_s8(a, b);
 }
 
-// CHECK: test_vtrn_s16
+// CHECK-LABEL: test_vtrn_s16
 // CHECK: vtrn.16 d{{[0-9]+}}, d{{[0-9]+}}
 int16x4x2_t test_vtrn_s16(int16x4_t a, int16x4_t b) {
   return vtrn_s16(a, b);
 }
 
-// CHECK: test_vtrn_s32
+// CHECK-LABEL: test_vtrn_s32
 // CHECK: vtrn.32 d{{[0-9]+}}, d{{[0-9]+}}
 int32x2x2_t test_vtrn_s32(int32x2_t a, int32x2_t b) {
   return vtrn_s32(a, b);
 }
 
-// CHECK: test_vtrn_u8
+// CHECK-LABEL: test_vtrn_u8
 // CHECK: vtrn.8 d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8x2_t test_vtrn_u8(uint8x8_t a, uint8x8_t b) {
   return vtrn_u8(a, b);
 }
 
-// CHECK: test_vtrn_u16
+// CHECK-LABEL: test_vtrn_u16
 // CHECK: vtrn.16 d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4x2_t test_vtrn_u16(uint16x4_t a, uint16x4_t b) {
   return vtrn_u16(a, b);
 }
 
-// CHECK: test_vtrn_u32
+// CHECK-LABEL: test_vtrn_u32
 // CHECK: vtrn.32 d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2x2_t test_vtrn_u32(uint32x2_t a, uint32x2_t b) {
   return vtrn_u32(a, b);
 }
 
-// CHECK: test_vtrn_f32
+// CHECK-LABEL: test_vtrn_f32
 // CHECK: vtrn.32 d{{[0-9]+}}, d{{[0-9]+}}
 float32x2x2_t test_vtrn_f32(float32x2_t a, float32x2_t b) {
   return vtrn_f32(a, b);
 }
 
-// CHECK: test_vtrn_p8
+// CHECK-LABEL: test_vtrn_p8
 // CHECK: vtrn.8 d{{[0-9]+}}, d{{[0-9]+}}
 poly8x8x2_t test_vtrn_p8(poly8x8_t a, poly8x8_t b) {
   return vtrn_p8(a, b);
 }
 
-// CHECK: test_vtrn_p16
+// CHECK-LABEL: test_vtrn_p16
 // CHECK: vtrn.16 d{{[0-9]+}}, d{{[0-9]+}}
 poly16x4x2_t test_vtrn_p16(poly16x4_t a, poly16x4_t b) {
   return vtrn_p16(a, b);
 }
 
-// CHECK: test_vtrnq_s8
+// CHECK-LABEL: test_vtrnq_s8
 // CHECK: vtrn.8 q{{[0-9]+}}, q{{[0-9]+}}
 int8x16x2_t test_vtrnq_s8(int8x16_t a, int8x16_t b) {
   return vtrnq_s8(a, b);
 }
 
-// CHECK: test_vtrnq_s16
+// CHECK-LABEL: test_vtrnq_s16
 // CHECK: vtrn.16 q{{[0-9]+}}, q{{[0-9]+}}
 int16x8x2_t test_vtrnq_s16(int16x8_t a, int16x8_t b) {
   return vtrnq_s16(a, b);
 }
 
-// CHECK: test_vtrnq_s32
+// CHECK-LABEL: test_vtrnq_s32
 // CHECK: vtrn.32 q{{[0-9]+}}, q{{[0-9]+}}
 int32x4x2_t test_vtrnq_s32(int32x4_t a, int32x4_t b) {
   return vtrnq_s32(a, b);
 }
 
-// CHECK: test_vtrnq_u8
+// CHECK-LABEL: test_vtrnq_u8
 // CHECK: vtrn.8 q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16x2_t test_vtrnq_u8(uint8x16_t a, uint8x16_t b) {
   return vtrnq_u8(a, b);
 }
 
-// CHECK: test_vtrnq_u16
+// CHECK-LABEL: test_vtrnq_u16
 // CHECK: vtrn.16 q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8x2_t test_vtrnq_u16(uint16x8_t a, uint16x8_t b) {
   return vtrnq_u16(a, b);
 }
 
-// CHECK: test_vtrnq_u32
+// CHECK-LABEL: test_vtrnq_u32
 // CHECK: vtrn.32 q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4x2_t test_vtrnq_u32(uint32x4_t a, uint32x4_t b) {
   return vtrnq_u32(a, b);
 }
 
-// CHECK: test_vtrnq_f32
+// CHECK-LABEL: test_vtrnq_f32
 // CHECK: vtrn.32 q{{[0-9]+}}, q{{[0-9]+}}
 float32x4x2_t test_vtrnq_f32(float32x4_t a, float32x4_t b) {
   return vtrnq_f32(a, b);
 }
 
-// CHECK: test_vtrnq_p8
+// CHECK-LABEL: test_vtrnq_p8
 // CHECK: vtrn.8 q{{[0-9]+}}, q{{[0-9]+}}
 poly8x16x2_t test_vtrnq_p8(poly8x16_t a, poly8x16_t b) {
   return vtrnq_p8(a, b);
 }
 
-// CHECK: test_vtrnq_p16
+// CHECK-LABEL: test_vtrnq_p16
 // CHECK: vtrn.16 q{{[0-9]+}}, q{{[0-9]+}}
 poly16x8x2_t test_vtrnq_p16(poly16x8_t a, poly16x8_t b) {
   return vtrnq_p16(a, b);
 }
 
 
-// CHECK: test_vtst_s8
+// CHECK-LABEL: test_vtst_s8
 // CHECK: vtst.8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vtst_s8(int8x8_t a, int8x8_t b) {
   return vtst_s8(a, b);
 }
 
-// CHECK: test_vtst_s16
+// CHECK-LABEL: test_vtst_s16
 // CHECK: vtst.16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vtst_s16(int16x4_t a, int16x4_t b) {
   return vtst_s16(a, b);
 }
 
-// CHECK: test_vtst_s32
+// CHECK-LABEL: test_vtst_s32
 // CHECK: vtst.32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vtst_s32(int32x2_t a, int32x2_t b) {
   return vtst_s32(a, b);
 }
 
-// CHECK: test_vtst_u8
+// CHECK-LABEL: test_vtst_u8
 // CHECK: vtst.8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vtst_u8(uint8x8_t a, uint8x8_t b) {
   return vtst_u8(a, b);
 }
 
-// CHECK: test_vtst_u16
+// CHECK-LABEL: test_vtst_u16
 // CHECK: vtst.16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vtst_u16(uint16x4_t a, uint16x4_t b) {
   return vtst_u16(a, b);
 }
 
-// CHECK: test_vtst_u32
+// CHECK-LABEL: test_vtst_u32
 // CHECK: vtst.32 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2_t test_vtst_u32(uint32x2_t a, uint32x2_t b) {
   return vtst_u32(a, b);
 }
 
-// CHECK: test_vtst_p8
+// CHECK-LABEL: test_vtst_p8
 // CHECK: vtst.8 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8_t test_vtst_p8(poly8x8_t a, poly8x8_t b) {
   return vtst_p8(a, b);
 }
 
-// CHECK: test_vtst_p16
+// CHECK-LABEL: test_vtst_p16
 // CHECK: vtst.16 d{{[0-9]+}}, d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4_t test_vtst_p16(poly16x4_t a, poly16x4_t b) {
   return vtst_p16(a, b);
 }
 
-// CHECK: test_vtstq_s8
+// CHECK-LABEL: test_vtstq_s8
 // CHECK: vtst.8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vtstq_s8(int8x16_t a, int8x16_t b) {
   return vtstq_s8(a, b);
 }
 
-// CHECK: test_vtstq_s16
+// CHECK-LABEL: test_vtstq_s16
 // CHECK: vtst.16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vtstq_s16(int16x8_t a, int16x8_t b) {
   return vtstq_s16(a, b);
 }
 
-// CHECK: test_vtstq_s32
+// CHECK-LABEL: test_vtstq_s32
 // CHECK: vtst.32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vtstq_s32(int32x4_t a, int32x4_t b) {
   return vtstq_s32(a, b);
 }
 
-// CHECK: test_vtstq_u8
+// CHECK-LABEL: test_vtstq_u8
 // CHECK: vtst.8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vtstq_u8(uint8x16_t a, uint8x16_t b) {
   return vtstq_u8(a, b);
 }
 
-// CHECK: test_vtstq_u16
+// CHECK-LABEL: test_vtstq_u16
 // CHECK: vtst.16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vtstq_u16(uint16x8_t a, uint16x8_t b) {
   return vtstq_u16(a, b);
 }
 
-// CHECK: test_vtstq_u32
+// CHECK-LABEL: test_vtstq_u32
 // CHECK: vtst.32 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4_t test_vtstq_u32(uint32x4_t a, uint32x4_t b) {
   return vtstq_u32(a, b);
 }
 
-// CHECK: test_vtstq_p8
+// CHECK-LABEL: test_vtstq_p8
 // CHECK: vtst.8 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16_t test_vtstq_p8(poly8x16_t a, poly8x16_t b) {
   return vtstq_p8(a, b);
 }
 
-// CHECK: test_vtstq_p16
+// CHECK-LABEL: test_vtstq_p16
 // CHECK: vtst.16 q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8_t test_vtstq_p16(poly16x8_t a, poly16x8_t b) {
   return vtstq_p16(a, b);
 }
 
 
-// CHECK: test_vuzp_s8
+// CHECK-LABEL: test_vuzp_s8
 // CHECK: vuzp.8 d{{[0-9]+}}, d{{[0-9]+}}
 int8x8x2_t test_vuzp_s8(int8x8_t a, int8x8_t b) {
   return vuzp_s8(a, b);
 }
 
-// CHECK: test_vuzp_s16
+// CHECK-LABEL: test_vuzp_s16
 // CHECK: vuzp.16 d{{[0-9]+}}, d{{[0-9]+}}
 int16x4x2_t test_vuzp_s16(int16x4_t a, int16x4_t b) {
   return vuzp_s16(a, b);
 }
 
-// CHECK: test_vuzp_s32
+// CHECK-LABEL: test_vuzp_s32
 // CHECK: {{vtrn|vuzp}}.32 d{{[0-9]+}}, d{{[0-9]+}}
 int32x2x2_t test_vuzp_s32(int32x2_t a, int32x2_t b) {
   return vuzp_s32(a, b);
 }
 
-// CHECK: test_vuzp_u8
+// CHECK-LABEL: test_vuzp_u8
 // CHECK: vuzp.8 d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8x2_t test_vuzp_u8(uint8x8_t a, uint8x8_t b) {
   return vuzp_u8(a, b);
 }
 
-// CHECK: test_vuzp_u16
+// CHECK-LABEL: test_vuzp_u16
 // CHECK: vuzp.16 d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4x2_t test_vuzp_u16(uint16x4_t a, uint16x4_t b) {
   return vuzp_u16(a, b);
 }
 
-// CHECK: test_vuzp_u32
+// CHECK-LABEL: test_vuzp_u32
 // CHECK: {{vtrn|vuzp}}.32 d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2x2_t test_vuzp_u32(uint32x2_t a, uint32x2_t b) {
   return vuzp_u32(a, b);
 }
 
-// CHECK: test_vuzp_f32
+// CHECK-LABEL: test_vuzp_f32
 // CHECK: {{vtrn|vuzp}}.32 d{{[0-9]+}}, d{{[0-9]+}}
 float32x2x2_t test_vuzp_f32(float32x2_t a, float32x2_t b) {
   return vuzp_f32(a, b);
 }
 
-// CHECK: test_vuzp_p8
+// CHECK-LABEL: test_vuzp_p8
 // CHECK: vuzp.8 d{{[0-9]+}}, d{{[0-9]+}}
 poly8x8x2_t test_vuzp_p8(poly8x8_t a, poly8x8_t b) {
   return vuzp_p8(a, b);
 }
 
-// CHECK: test_vuzp_p16
+// CHECK-LABEL: test_vuzp_p16
 // CHECK: vuzp.16 d{{[0-9]+}}, d{{[0-9]+}}
 poly16x4x2_t test_vuzp_p16(poly16x4_t a, poly16x4_t b) {
   return vuzp_p16(a, b);
 }
 
-// CHECK: test_vuzpq_s8
+// CHECK-LABEL: test_vuzpq_s8
 // CHECK: vuzp.8 q{{[0-9]+}}, q{{[0-9]+}}
 int8x16x2_t test_vuzpq_s8(int8x16_t a, int8x16_t b) {
   return vuzpq_s8(a, b);
 }
 
-// CHECK: test_vuzpq_s16
+// CHECK-LABEL: test_vuzpq_s16
 // CHECK: vuzp.16 q{{[0-9]+}}, q{{[0-9]+}}
 int16x8x2_t test_vuzpq_s16(int16x8_t a, int16x8_t b) {
   return vuzpq_s16(a, b);
 }
 
-// CHECK: test_vuzpq_s32
+// CHECK-LABEL: test_vuzpq_s32
 // CHECK: {{vtrn|vuzp}}.32 q{{[0-9]+}}, q{{[0-9]+}}
 int32x4x2_t test_vuzpq_s32(int32x4_t a, int32x4_t b) {
   return vuzpq_s32(a, b);
 }
 
-// CHECK: test_vuzpq_u8
+// CHECK-LABEL: test_vuzpq_u8
 // CHECK: vuzp.8 q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16x2_t test_vuzpq_u8(uint8x16_t a, uint8x16_t b) {
   return vuzpq_u8(a, b);
 }
 
-// CHECK: test_vuzpq_u16
+// CHECK-LABEL: test_vuzpq_u16
 // CHECK: vuzp.16 q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8x2_t test_vuzpq_u16(uint16x8_t a, uint16x8_t b) {
   return vuzpq_u16(a, b);
 }
 
-// CHECK: test_vuzpq_u32
+// CHECK-LABEL: test_vuzpq_u32
 // CHECK: {{vtrn|vuzp}}.32 q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4x2_t test_vuzpq_u32(uint32x4_t a, uint32x4_t b) {
   return vuzpq_u32(a, b);
 }
 
-// CHECK: test_vuzpq_f32
+// CHECK-LABEL: test_vuzpq_f32
 // CHECK: {{vtrn|vuzp}}.32 q{{[0-9]+}}, q{{[0-9]+}}
 float32x4x2_t test_vuzpq_f32(float32x4_t a, float32x4_t b) {
   return vuzpq_f32(a, b);
 }
 
-// CHECK: test_vuzpq_p8
+// CHECK-LABEL: test_vuzpq_p8
 // CHECK: vuzp.8 q{{[0-9]+}}, q{{[0-9]+}}
 poly8x16x2_t test_vuzpq_p8(poly8x16_t a, poly8x16_t b) {
   return vuzpq_p8(a, b);
 }
 
-// CHECK: test_vuzpq_p16
+// CHECK-LABEL: test_vuzpq_p16
 // CHECK: vuzp.16 q{{[0-9]+}}, q{{[0-9]+}}
 poly16x8x2_t test_vuzpq_p16(poly16x8_t a, poly16x8_t b) {
   return vuzpq_p16(a, b);
 }
 
 
-// CHECK: test_vzip_s8
+// CHECK-LABEL: test_vzip_s8
 // CHECK: vzip.8 d{{[0-9]+}}, d{{[0-9]+}}
 int8x8x2_t test_vzip_s8(int8x8_t a, int8x8_t b) {
   return vzip_s8(a, b);
 }
 
-// CHECK: test_vzip_s16
+// CHECK-LABEL: test_vzip_s16
 // CHECK: vzip.16 d{{[0-9]+}}, d{{[0-9]+}}
 int16x4x2_t test_vzip_s16(int16x4_t a, int16x4_t b) {
   return vzip_s16(a, b);
 }
 
-// CHECK: test_vzip_s32
+// CHECK-LABEL: test_vzip_s32
 // CHECK: {{vtrn|vzip}}.32 d{{[0-9]+}}, d{{[0-9]+}}
 int32x2x2_t test_vzip_s32(int32x2_t a, int32x2_t b) {
   return vzip_s32(a, b);
 }
 
-// CHECK: test_vzip_u8
+// CHECK-LABEL: test_vzip_u8
 // CHECK: vzip.8 d{{[0-9]+}}, d{{[0-9]+}}
 uint8x8x2_t test_vzip_u8(uint8x8_t a, uint8x8_t b) {
   return vzip_u8(a, b);
 }
 
-// CHECK: test_vzip_u16
+// CHECK-LABEL: test_vzip_u16
 // CHECK: vzip.16 d{{[0-9]+}}, d{{[0-9]+}}
 uint16x4x2_t test_vzip_u16(uint16x4_t a, uint16x4_t b) {
   return vzip_u16(a, b);
 }
 
-// CHECK: test_vzip_u32
+// CHECK-LABEL: test_vzip_u32
 // CHECK: {{vtrn|vzip}}.32 d{{[0-9]+}}, d{{[0-9]+}}
 uint32x2x2_t test_vzip_u32(uint32x2_t a, uint32x2_t b) {
   return vzip_u32(a, b);
 }
 
-// CHECK: test_vzip_f32
+// CHECK-LABEL: test_vzip_f32
 // CHECK: {{vtrn|vzip}}.32 d{{[0-9]+}}, d{{[0-9]+}}
 float32x2x2_t test_vzip_f32(float32x2_t a, float32x2_t b) {
   return vzip_f32(a, b);
 }
 
-// CHECK: test_vzip_p8
+// CHECK-LABEL: test_vzip_p8
 // CHECK: vzip.8 d{{[0-9]+}}, d{{[0-9]+}}
 poly8x8x2_t test_vzip_p8(poly8x8_t a, poly8x8_t b) {
   return vzip_p8(a, b);
 }
 
-// CHECK: test_vzip_p16
+// CHECK-LABEL: test_vzip_p16
 // CHECK: vzip.16 d{{[0-9]+}}, d{{[0-9]+}}
 poly16x4x2_t test_vzip_p16(poly16x4_t a, poly16x4_t b) {
   return vzip_p16(a, b);
 }
 
-// CHECK: test_vzipq_s8
+// CHECK-LABEL: test_vzipq_s8
 // CHECK: vzip.8 q{{[0-9]+}}, q{{[0-9]+}}
 int8x16x2_t test_vzipq_s8(int8x16_t a, int8x16_t b) {
   return vzipq_s8(a, b);
 }
 
-// CHECK: test_vzipq_s16
+// CHECK-LABEL: test_vzipq_s16
 // CHECK: vzip.16 q{{[0-9]+}}, q{{[0-9]+}}
 int16x8x2_t test_vzipq_s16(int16x8_t a, int16x8_t b) {
   return vzipq_s16(a, b);
 }
 
-// CHECK: test_vzipq_s32
+// CHECK-LABEL: test_vzipq_s32
 // CHECK: {{vtrn|vzip}}.32 q{{[0-9]+}}, q{{[0-9]+}}
 int32x4x2_t test_vzipq_s32(int32x4_t a, int32x4_t b) {
   return vzipq_s32(a, b);
 }
 
-// CHECK: test_vzipq_u8
+// CHECK-LABEL: test_vzipq_u8
 // CHECK: vzip.8 q{{[0-9]+}}, q{{[0-9]+}}
 uint8x16x2_t test_vzipq_u8(uint8x16_t a, uint8x16_t b) {
   return vzipq_u8(a, b);
 }
 
-// CHECK: test_vzipq_u16
+// CHECK-LABEL: test_vzipq_u16
 // CHECK: vzip.16 q{{[0-9]+}}, q{{[0-9]+}}
 uint16x8x2_t test_vzipq_u16(uint16x8_t a, uint16x8_t b) {
   return vzipq_u16(a, b);
 }
 
-// CHECK: test_vzipq_u32
+// CHECK-LABEL: test_vzipq_u32
 // CHECK: {{vtrn|vzip}}.32 q{{[0-9]+}}, q{{[0-9]+}}
 uint32x4x2_t test_vzipq_u32(uint32x4_t a, uint32x4_t b) {
   return vzipq_u32(a, b);
 }
 
-// CHECK: test_vzipq_f32
+// CHECK-LABEL: test_vzipq_f32
 // CHECK: {{vtrn|vzip}}.32 q{{[0-9]+}}, q{{[0-9]+}}
 float32x4x2_t test_vzipq_f32(float32x4_t a, float32x4_t b) {
   return vzipq_f32(a, b);
 }
 
-// CHECK: test_vzipq_p8
+// CHECK-LABEL: test_vzipq_p8
 // CHECK: vzip.8 q{{[0-9]+}}, q{{[0-9]+}}
 poly8x16x2_t test_vzipq_p8(poly8x16_t a, poly8x16_t b) {
   return vzipq_p8(a, b);
 }
 
-// CHECK: test_vzipq_p16
+// CHECK-LABEL: test_vzipq_p16
 // CHECK: vzip.16 q{{[0-9]+}}, q{{[0-9]+}}
 poly16x8x2_t test_vzipq_p16(poly16x8_t a, poly16x8_t b) {
   return vzipq_p16(a, b);
diff --git a/test/CodeGen/asan-globals.cpp b/test/CodeGen/asan-globals.cpp
new file mode 100644
index 0000000..d9ecc64
--- /dev/null
+++ b/test/CodeGen/asan-globals.cpp
@@ -0,0 +1,36 @@
+// RUN: echo "global:*blacklisted_global*" > %t.blacklist
+// RUN: %clang_cc1 -fsanitize=address -fsanitize-blacklist=%t.blacklist -emit-llvm -o - %s | FileCheck %s
+// RUN: echo "src:%s" > %t.blacklist-src
+// RUN: %clang_cc1 -fsanitize=address -fsanitize-blacklist=%t.blacklist-src -emit-llvm -o - %s | FileCheck %s --check-prefix=BLACKLIST-SRC
+// REQUIRES: shell
+
+int global;
+// CHECK: [[GLOBAL_LOC:@.asan_loc_descr[0-9]*]] = private unnamed_addr constant {{.*}} i32 [[@LINE-1]], i32 5
+// CHECK: [[GLOBAL_NAME:@.str[0-9]+]] = private unnamed_addr constant {{.*}} c"global\00"
+int dyn_init_global = global;
+// CHECK: [[DYN_INIT_LOC:@.asan_loc_descr[0-9]*]] = {{.*}} i32 [[@LINE-1]], i32 5
+// CHECK: [[DYN_INIT_NAME:@.str[0-9]+]] = private unnamed_addr constant {{.*}} c"dyn_init_global\00"
+int blacklisted_global;
+
+void func() {
+  static int static_var = 0;
+  // CHECK: [[STATIC_LOC:@.asan_loc_descr[0-9]*]] = {{.*}} i32 [[@LINE-1]], i32 14
+  // CHECK: [[STATIC_NAME:@.str[0-9]+]] = private unnamed_addr constant {{.*}} c"static_var\00"
+  const char *literal = "Hello, world!";
+  // CHECK: [[LITERAL_LOC:@.asan_loc_descr[0-9]*]] = {{.*}} i32 [[@LINE-1]], i32 25
+  // CHECK: [[LITERAL_NAME:@.str[0-9]+]] = private unnamed_addr constant {{.*}} c"<string literal>\00"
+}
+
+// CHECK: !llvm.asan.globals = !{![[GLOBAL:[0-9]+]], ![[DYN_INIT_GLOBAL:[0-9]+]], ![[BLACKLISTED_GLOBAL:[0-9]+]], ![[STATIC_VAR:[0-9]+]], ![[LITERAL:[0-9]+]]}
+// CHECK: ![[GLOBAL]] = metadata !{{{.*}} [[GLOBAL_LOC]], {{.*}} [[GLOBAL_NAME]], i1 false, i1 false}
+// CHECK: ![[DYN_INIT_GLOBAL]] = metadata !{{{.*}} [[DYN_INIT_LOC]], {{.*}} [[DYN_INIT_NAME]], i1 true, i1 false}
+// CHECK: ![[BLACKLISTED_GLOBAL]] = metadata !{{{.*}}, null, null, i1 false, i1 true}
+// CHECK: ![[STATIC_VAR]] = metadata !{{{.*}} [[STATIC_LOC]], {{.*}} [[STATIC_NAME]], i1 false, i1 false}
+// CHECK: ![[LITERAL]] = metadata !{{{.*}} [[LITERAL_LOC]], {{.*}} [[LITERAL_NAME]], i1 false, i1 false}
+
+// BLACKLIST-SRC: !llvm.asan.globals = !{![[GLOBAL:[0-9]+]], ![[DYN_INIT_GLOBAL:[0-9]+]], ![[BLACKLISTED_GLOBAL:[0-9]+]], ![[STATIC_VAR:[0-9]+]], ![[LITERAL:[0-9]+]]}
+// BLACKLIST-SRC: ![[GLOBAL]] = metadata !{{{.*}} null, null, i1 false, i1 true}
+// BLACKLIST-SRC: ![[DYN_INIT_GLOBAL]] = metadata !{{{.*}} null, null, i1 true, i1 true}
+// BLACKLIST-SRC: ![[BLACKLISTED_GLOBAL]] = metadata !{{{.*}}, null, null, i1 false, i1 true}
+// BLACKLIST-SRC: ![[STATIC_VAR]] = metadata !{{{.*}} null, null, i1 false, i1 true}
+// BLACKLIST-SRC: ![[LITERAL]] = metadata !{{{.*}} null, null, i1 false, i1 true}
diff --git a/test/CodeGen/asm.c b/test/CodeGen/asm.c
index 670c244..5dbc01b 100644
--- a/test/CodeGen/asm.c
+++ b/test/CodeGen/asm.c
@@ -239,3 +239,12 @@
 // CHECK: call void asm sideeffect "/* $0 */", "i|r,~{dirflag},~{fpsr},~{flags}"(i32 1)
 }
 
+static unsigned t29_var[1];
+
+void t29(void) {
+  asm volatile("movl %%eax, %0"
+               :
+               : "m"(t29_var));
+  // CHECK: @t29
+  // CHECK: call void asm sideeffect "movl %eax, $0", "*m,~{dirflag},~{fpsr},~{flags}"([1 x i32]* @t29_var)
+}
diff --git a/test/CodeGen/asm_arm64.c b/test/CodeGen/asm_arm64.c
new file mode 100644
index 0000000..0eaa347
--- /dev/null
+++ b/test/CodeGen/asm_arm64.c
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -triple arm64-apple-ios -emit-llvm -o - %s | FileCheck %s
+
+// rdar://9167275
+
+int t1()
+{
+  int x;
+  __asm__("mov %0, 7" : "=r" (x));
+  return x;
+}
+
+long t2()
+{
+  long x;
+  __asm__("mov %0, 7" : "=r" (x));
+  return x;
+}
+
+long t3()
+{
+  long x;
+  __asm__("mov %w0, 7" : "=r" (x));
+  return x;
+}
+
+// rdar://9281206
+
+void t4(long op) {
+  long x1;
+  asm ("mov x0, %1; svc #0;" : "=r"(x1) :"r"(op),"r"(x1) :"x0" );
+}
+
+// rdar://9394290
+
+float t5(float x) {
+  __asm__("fadd %0, %0, %0" : "+w" (x));
+  return x;
+}
+
+// rdar://9865712
+void t6 (void *f, int g) {
+  // CHECK: t6
+  // CHECK: call void asm "str $1, $0", "=*Q,r"
+  asm("str %1, %0" : "=Q"(f) : "r"(g));
+}
diff --git a/test/CodeGen/atomic-arm64.c b/test/CodeGen/atomic-arm64.c
new file mode 100644
index 0000000..147b570
--- /dev/null
+++ b/test/CodeGen/atomic-arm64.c
@@ -0,0 +1,73 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=arm64-apple-ios7 | FileCheck %s
+
+// Memory ordering values.
+enum {
+  memory_order_relaxed = 0,
+  memory_order_consume = 1,
+  memory_order_acquire = 2,
+  memory_order_release = 3,
+  memory_order_acq_rel = 4,
+  memory_order_seq_cst = 5
+};
+
+typedef struct { void *a, *b; } pointer_pair_t;
+typedef struct { void *a, *b, *c, *d; } pointer_quad_t;
+
+// rdar://13489679
+
+extern _Atomic(_Bool) a_bool;
+extern _Atomic(float) a_float;
+extern _Atomic(void*) a_pointer;
+extern _Atomic(pointer_pair_t) a_pointer_pair;
+extern _Atomic(pointer_quad_t) a_pointer_quad;
+
+// CHECK:    define void @test0()
+// CHECK:      [[TEMP:%.*]] = alloca i8, align 1
+// CHECK-NEXT: store i8 1, i8* [[TEMP]]
+// CHECK-NEXT: [[T0:%.*]] = load i8* [[TEMP]], align 1
+// CHECK-NEXT: store atomic i8 [[T0]], i8* @a_bool seq_cst, align 1
+void test0() {
+  __c11_atomic_store(&a_bool, 1, memory_order_seq_cst);
+}
+
+// CHECK:    define void @test1()
+// CHECK:      [[TEMP:%.*]] = alloca float, align 4
+// CHECK-NEXT: store float 3.000000e+00, float* [[TEMP]]
+// CHECK-NEXT: [[T0:%.*]] = bitcast float* [[TEMP]] to i32*
+// CHECK-NEXT: [[T1:%.*]] = load i32* [[T0]], align 4
+// CHECK-NEXT: store atomic i32 [[T1]], i32* bitcast (float* @a_float to i32*) seq_cst, align 4
+void test1() {
+  __c11_atomic_store(&a_float, 3, memory_order_seq_cst);
+}
+
+// CHECK:    define void @test2()
+// CHECK:      [[TEMP:%.*]] = alloca i8*, align 8
+// CHECK-NEXT: store i8* @a_bool, i8** [[TEMP]]
+// CHECK-NEXT: [[T0:%.*]] = bitcast i8** [[TEMP]] to i64*
+// CHECK-NEXT: [[T1:%.*]] = load i64* [[T0]], align 8
+// CHECK-NEXT: store atomic i64 [[T1]], i64* bitcast (i8** @a_pointer to i64*) seq_cst, align 8
+void test2() {
+  __c11_atomic_store(&a_pointer, &a_bool, memory_order_seq_cst);
+}
+
+// CHECK:    define void @test3(
+// CHECK:      [[PAIR:%.*]] = alloca [[PAIR_T:%.*]], align 8
+// CHECK-NEXT: [[TEMP:%.*]] = alloca [[PAIR_T]], align 8
+// CHECK:      llvm.memcpy
+// CHECK-NEXT: [[T0:%.*]] = bitcast [[PAIR_T]]* [[TEMP]] to i128*
+// CHECK-NEXT: [[T1:%.*]] = load i128* [[T0]], align 16
+// CHECK-NEXT: store atomic i128 [[T1]], i128* bitcast ([[PAIR_T]]* @a_pointer_pair to i128*) seq_cst, align 16
+void test3(pointer_pair_t pair) {
+  __c11_atomic_store(&a_pointer_pair, pair, memory_order_seq_cst);
+}
+
+// CHECK:    define void @test4([[QUAD_T:%.*]]*
+// CHECK:      [[TEMP:%.*]] = alloca [[QUAD_T:%.*]], align 8
+// CHECK-NEXT: [[T0:%.*]] = bitcast [[QUAD_T]]* [[TEMP]] to i8*
+// CHECK-NEXT: [[T1:%.*]] = bitcast [[QUAD_T]]* {{%.*}} to i8*
+// CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[T0]], i8* [[T1]], i64 32, i32 8, i1 false)
+// CHECK-NEXT: [[T0:%.*]] = bitcast [[QUAD_T]]* [[TEMP]] to i8*
+// CHECK-NEXT: call void @__atomic_store(i64 32, i8* bitcast ([[QUAD_T]]* @a_pointer_quad to i8*), i8* [[T0]], i32 5)
+void test4(pointer_quad_t quad) {
+  __c11_atomic_store(&a_pointer_quad, quad, memory_order_seq_cst);
+}
diff --git a/test/CodeGen/atomic-ops-libcall.c b/test/CodeGen/atomic-ops-libcall.c
new file mode 100644
index 0000000..2a2ff5e
--- /dev/null
+++ b/test/CodeGen/atomic-ops-libcall.c
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 < %s -triple armv5e-none-linux-gnueabi -emit-llvm -O1 | FileCheck %s
+
+enum memory_order {
+  memory_order_relaxed, memory_order_consume, memory_order_acquire,
+  memory_order_release, memory_order_acq_rel, memory_order_seq_cst
+};
+
+int *test_c11_atomic_fetch_add_int_ptr(_Atomic(int *) *p) {
+  // CHECK: test_c11_atomic_fetch_add_int_ptr
+  // CHECK: {{%[^ ]*}} = tail call i32* @__atomic_fetch_add_4(i8* {{%[0-9]+}}, i32 12, i32 5)
+  return __c11_atomic_fetch_add(p, 3, memory_order_seq_cst);
+}
+
+int *test_c11_atomic_fetch_sub_int_ptr(_Atomic(int *) *p) {
+  // CHECK: test_c11_atomic_fetch_sub_int_ptr
+  // CHECK: {{%[^ ]*}} = tail call i32* @__atomic_fetch_sub_4(i8* {{%[0-9]+}}, i32 20, i32 5)
+  return __c11_atomic_fetch_sub(p, 5, memory_order_seq_cst);
+}
+
+int test_c11_atomic_fetch_add_int(_Atomic(int) *p) {
+  // CHECK: test_c11_atomic_fetch_add_int
+  // CHECK: {{%[^ ]*}} = tail call i32 bitcast (i32* (i8*, i32, i32)* @__atomic_fetch_add_4 to i32 (i8*, i32, i32)*)(i8* {{%[0-9]+}}, i32 3, i32 5)
+  return __c11_atomic_fetch_add(p, 3, memory_order_seq_cst);
+}
+
+int test_c11_atomic_fetch_sub_int(_Atomic(int) *p) {
+  // CHECK: test_c11_atomic_fetch_sub_int
+  // CHECK: {{%[^ ]*}} = tail call i32 bitcast (i32* (i8*, i32, i32)* @__atomic_fetch_sub_4 to i32 (i8*, i32, i32)*)(i8* {{%[0-9]+}}, i32 5, i32 5)
+  return __c11_atomic_fetch_sub(p, 5, memory_order_seq_cst);
+}
+
+int *fp2a(int **p) {
+  // CHECK: @fp2a
+  // CHECK: {{%[^ ]*}} = tail call i32* @__atomic_fetch_sub_4(i8* {{%[0-9]+}}, i32 4, i32 0)
+  // Note, the GNU builtins do not multiply by sizeof(T)!
+  return __atomic_fetch_sub(p, 4, memory_order_relaxed);
+}
diff --git a/test/CodeGen/atomic-ops.c b/test/CodeGen/atomic-ops.c
index 830f21a..9e6b480 100644
--- a/test/CodeGen/atomic-ops.c
+++ b/test/CodeGen/atomic-ops.c
@@ -15,13 +15,13 @@
 } memory_order;
 
 int fi1(_Atomic(int) *i) {
-  // CHECK: @fi1
+  // CHECK-LABEL: @fi1
   // CHECK: load atomic i32* {{.*}} seq_cst
   return __c11_atomic_load(i, memory_order_seq_cst);
 }
 
 int fi1a(int *i) {
-  // CHECK: @fi1a
+  // CHECK-LABEL: @fi1a
   // CHECK: load atomic i32* {{.*}} seq_cst
   int v;
   __atomic_load(i, &v, memory_order_seq_cst);
@@ -29,60 +29,60 @@
 }
 
 int fi1b(int *i) {
-  // CHECK: @fi1b
+  // CHECK-LABEL: @fi1b
   // CHECK: load atomic i32* {{.*}} seq_cst
   return __atomic_load_n(i, memory_order_seq_cst);
 }
 
 void fi2(_Atomic(int) *i) {
-  // CHECK: @fi2
+  // CHECK-LABEL: @fi2
   // CHECK: store atomic i32 {{.*}} seq_cst
   __c11_atomic_store(i, 1, memory_order_seq_cst);
 }
 
 void fi2a(int *i) {
-  // CHECK: @fi2a
+  // CHECK-LABEL: @fi2a
   // CHECK: store atomic i32 {{.*}} seq_cst
   int v = 1;
   __atomic_store(i, &v, memory_order_seq_cst);
 }
 
 void fi2b(int *i) {
-  // CHECK: @fi2b
+  // CHECK-LABEL: @fi2b
   // CHECK: store atomic i32 {{.*}} seq_cst
   __atomic_store_n(i, 1, memory_order_seq_cst);
 }
 
 int fi3(_Atomic(int) *i) {
-  // CHECK: @fi3
+  // CHECK-LABEL: @fi3
   // CHECK: atomicrmw and
   // CHECK-NOT: and
   return __c11_atomic_fetch_and(i, 1, memory_order_seq_cst);
 }
 
 int fi3a(int *i) {
-  // CHECK: @fi3a
+  // CHECK-LABEL: @fi3a
   // CHECK: atomicrmw xor
   // CHECK-NOT: xor
   return __atomic_fetch_xor(i, 1, memory_order_seq_cst);
 }
 
 int fi3b(int *i) {
-  // CHECK: @fi3b
+  // CHECK-LABEL: @fi3b
   // CHECK: atomicrmw add
   // CHECK: add
   return __atomic_add_fetch(i, 1, memory_order_seq_cst);
 }
 
 int fi3c(int *i) {
-  // CHECK: @fi3c
+  // CHECK-LABEL: @fi3c
   // CHECK: atomicrmw nand
   // CHECK-NOT: and
   return __atomic_fetch_nand(i, 1, memory_order_seq_cst);
 }
 
 int fi3d(int *i) {
-  // CHECK: @fi3d
+  // CHECK-LABEL: @fi3d
   // CHECK: atomicrmw nand
   // CHECK: and
   // CHECK: xor
@@ -90,35 +90,47 @@
 }
 
 _Bool fi4(_Atomic(int) *i) {
-  // CHECK: @fi4
-  // CHECK: cmpxchg i32*
+  // CHECK-LABEL: @fi4
+  // CHECK: [[PAIR:%[.0-9A-Z_a-z]+]] = cmpxchg i32* [[PTR:%[.0-9A-Z_a-z]+]], i32 [[EXPECTED:%[.0-9A-Z_a-z]+]], i32 [[DESIRED:%[.0-9A-Z_a-z]+]]
+  // CHECK: [[OLD:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 0
+  // CHECK: [[CMP:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 1
+  // CHECK: br i1 [[CMP]], label %[[STORE_EXPECTED:[.0-9A-Z_a-z]+]], label %[[CONTINUE:[.0-9A-Z_a-z]+]]
+  // CHECK: store i32 [[OLD]]
   int cmp = 0;
   return __c11_atomic_compare_exchange_strong(i, &cmp, 1, memory_order_acquire, memory_order_acquire);
 }
 
 _Bool fi4a(int *i) {
-  // CHECK: @fi4
-  // CHECK: cmpxchg i32*
+  // CHECK-LABEL: @fi4
+  // CHECK: [[PAIR:%[.0-9A-Z_a-z]+]] = cmpxchg i32* [[PTR:%[.0-9A-Z_a-z]+]], i32 [[EXPECTED:%[.0-9A-Z_a-z]+]], i32 [[DESIRED:%[.0-9A-Z_a-z]+]]
+  // CHECK: [[OLD:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 0
+  // CHECK: [[CMP:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 1
+  // CHECK: br i1 [[CMP]], label %[[STORE_EXPECTED:[.0-9A-Z_a-z]+]], label %[[CONTINUE:[.0-9A-Z_a-z]+]]
+  // CHECK: store i32 [[OLD]]
   int cmp = 0;
   int desired = 1;
   return __atomic_compare_exchange(i, &cmp, &desired, 0, memory_order_acquire, memory_order_acquire);
 }
 
 _Bool fi4b(int *i) {
-  // CHECK: @fi4
-  // CHECK: cmpxchg i32*
+  // CHECK-LABEL: @fi4
+  // CHECK: [[PAIR:%[.0-9A-Z_a-z]+]] = cmpxchg weak i32* [[PTR:%[.0-9A-Z_a-z]+]], i32 [[EXPECTED:%[.0-9A-Z_a-z]+]], i32 [[DESIRED:%[.0-9A-Z_a-z]+]]
+  // CHECK: [[OLD:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 0
+  // CHECK: [[CMP:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 1
+  // CHECK: br i1 [[CMP]], label %[[STORE_EXPECTED:[.0-9A-Z_a-z]+]], label %[[CONTINUE:[.0-9A-Z_a-z]+]]
+  // CHECK: store i32 [[OLD]]
   int cmp = 0;
   return __atomic_compare_exchange_n(i, &cmp, 1, 1, memory_order_acquire, memory_order_acquire);
 }
 
 float ff1(_Atomic(float) *d) {
-  // CHECK: @ff1
+  // CHECK-LABEL: @ff1
   // CHECK: load atomic i32* {{.*}} monotonic
   return __c11_atomic_load(d, memory_order_relaxed);
 }
 
 void ff2(_Atomic(float) *d) {
-  // CHECK: @ff2
+  // CHECK-LABEL: @ff2
   // CHECK: store atomic i32 {{.*}} release
   __c11_atomic_store(d, 1, memory_order_release);
 }
@@ -128,20 +140,20 @@
 }
 
 int* fp1(_Atomic(int*) *p) {
-  // CHECK: @fp1
+  // CHECK-LABEL: @fp1
   // CHECK: load atomic i32* {{.*}} seq_cst
   return __c11_atomic_load(p, memory_order_seq_cst);
 }
 
 int* fp2(_Atomic(int*) *p) {
-  // CHECK: @fp2
+  // CHECK-LABEL: @fp2
   // CHECK: store i32 4
   // CHECK: atomicrmw add {{.*}} monotonic
   return __c11_atomic_fetch_add(p, 1, memory_order_relaxed);
 }
 
 int *fp2a(int **p) {
-  // CHECK: @fp2a
+  // CHECK-LABEL: @fp2a
   // CHECK: store i32 4
   // CHECK: atomicrmw sub {{.*}} monotonic
   // Note, the GNU builtins do not multiply by sizeof(T)!
@@ -149,20 +161,20 @@
 }
 
 _Complex float fc(_Atomic(_Complex float) *c) {
-  // CHECK: @fc
+  // CHECK-LABEL: @fc
   // CHECK: atomicrmw xchg i64*
   return __c11_atomic_exchange(c, 2, memory_order_seq_cst);
 }
 
 typedef struct X { int x; } X;
 X fs(_Atomic(X) *c) {
-  // CHECK: @fs
+  // CHECK-LABEL: @fs
   // CHECK: atomicrmw xchg i32*
   return __c11_atomic_exchange(c, (X){2}, memory_order_seq_cst);
 }
 
 X fsa(X *c, X *d) {
-  // CHECK: @fsa
+  // CHECK-LABEL: @fsa
   // CHECK: atomicrmw xchg i32*
   X ret;
   __atomic_exchange(c, d, &ret, memory_order_seq_cst);
@@ -170,7 +182,7 @@
 }
 
 _Bool fsb(_Bool *c) {
-  // CHECK: @fsb
+  // CHECK-LABEL: @fsb
   // CHECK: atomicrmw xchg i8*
   return __atomic_exchange_n(c, 1, memory_order_seq_cst);
 }
@@ -196,7 +208,7 @@
 } seventeen;
 
 int lock_free(struct Incomplete *incomplete) {
-  // CHECK: @lock_free
+  // CHECK-LABEL: @lock_free
 
   // CHECK: call i32 @__atomic_is_lock_free(i32 3, i8* null)
   __c11_atomic_is_lock_free(3);
@@ -244,7 +256,7 @@
 _Atomic(struct foo) bigAtomic;
 
 void structAtomicStore() {
-  // CHECK: @structAtomicStore
+  // CHECK-LABEL: @structAtomicStore
   struct foo f = {0};
   struct bar b = {0};
   __atomic_store(&smallThing, &b, 5);
@@ -254,7 +266,7 @@
   // CHECK: call void @__atomic_store(i32 512, i8* {{.*}} @bigThing
 }
 void structAtomicLoad() {
-  // CHECK: @structAtomicLoad
+  // CHECK-LABEL: @structAtomicLoad
   struct bar b;
   __atomic_load(&smallThing, &b, 5);
   // CHECK: call void @__atomic_load(i32 3, i8* {{.*}} @smallThing
@@ -264,7 +276,7 @@
   // CHECK: call void @__atomic_load(i32 512, i8* {{.*}} @bigThing
 }
 struct foo structAtomicExchange() {
-  // CHECK: @structAtomicExchange
+  // CHECK-LABEL: @structAtomicExchange
   struct foo f = {0};
   struct foo old;
   __atomic_exchange(&f, &bigThing, &old, 5);
@@ -274,7 +286,7 @@
   // CHECK: call void @__atomic_exchange(i32 512, i8* bitcast ({{.*}} @bigAtomic to i8*),
 }
 int structAtomicCmpExchange() {
-  // CHECK: @structAtomicCmpExchange
+  // CHECK-LABEL: @structAtomicCmpExchange
   _Bool x = __atomic_compare_exchange(&smallThing, &thing1, &thing2, 1, 5, 5);
   // CHECK: call zeroext i1 @__atomic_compare_exchange(i32 3, {{.*}} @smallThing{{.*}} @thing1{{.*}} @thing2
 
@@ -289,7 +301,7 @@
 // types.
 _Atomic(int) atomic_init_i = 42;
 
-// CHECK: @atomic_init_foo
+// CHECK-LABEL: @atomic_init_foo
 void atomic_init_foo()
 {
   // CHECK-NOT: }
@@ -306,13 +318,133 @@
   // CHECK: }
 }
 
-// CHECK: @invalid_atomic
-void invalid_atomic(_Atomic(int) *i) {
-  __c11_atomic_store(i, 1, memory_order_consume);
-  __c11_atomic_store(i, 1, memory_order_acquire);
-  __c11_atomic_store(i, 1, memory_order_acq_rel);
-  __c11_atomic_load(i, memory_order_release);
-  __c11_atomic_load(i, memory_order_acq_rel);
+// CHECK-LABEL: @failureOrder
+void failureOrder(_Atomic(int) *ptr, int *ptr2) {
+  __c11_atomic_compare_exchange_strong(ptr, ptr2, 43, memory_order_acquire, memory_order_relaxed);
+  // CHECK: cmpxchg i32* {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z_.]+}} acquire monotonic
+
+  __c11_atomic_compare_exchange_weak(ptr, ptr2, 43, memory_order_seq_cst, memory_order_acquire);
+  // CHECK: cmpxchg weak i32* {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z_.]+}} seq_cst acquire
+
+  // Unknown ordering: conservatively pick strongest valid option (for now!).
+  __atomic_compare_exchange(ptr2, ptr2, ptr2, 0, memory_order_acq_rel, *ptr2);
+  // CHECK: cmpxchg i32* {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z_.]+}} acq_rel acquire
+
+  // Undefined behaviour: don't really care what that last ordering is so leave
+  // it out:
+  __atomic_compare_exchange_n(ptr2, ptr2, 43, 1, memory_order_seq_cst, 42);
+  // CHECK: cmpxchg weak i32* {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z_.]+}} seq_cst
+}
+
+// CHECK-LABEL: @generalFailureOrder
+void generalFailureOrder(_Atomic(int) *ptr, int *ptr2, int success, int fail) {
+  __c11_atomic_compare_exchange_strong(ptr, ptr2, 42, success, fail);
+  // CHECK: switch i32 {{.*}}, label %[[MONOTONIC:[0-9a-zA-Z._]+]] [
+  // CHECK-NEXT: i32 1, label %[[ACQUIRE:[0-9a-zA-Z._]+]]
+  // CHECK-NEXT: i32 2, label %[[ACQUIRE]]
+  // CHECK-NEXT: i32 3, label %[[RELEASE:[0-9a-zA-Z._]+]]
+  // CHECK-NEXT: i32 4, label %[[ACQREL:[0-9a-zA-Z._]+]]
+  // CHECK-NEXT: i32 5, label %[[SEQCST:[0-9a-zA-Z._]+]]
+
+  // CHECK: [[MONOTONIC]]
+  // CHECK: switch {{.*}}, label %[[MONOTONIC_MONOTONIC:[0-9a-zA-Z._]+]] [
+  // CHECK-NEXT: ]
+
+  // CHECK: [[ACQUIRE]]
+  // CHECK: switch {{.*}}, label %[[ACQUIRE_MONOTONIC:[0-9a-zA-Z._]+]] [
+  // CHECK-NEXT: i32 1, label %[[ACQUIRE_ACQUIRE:[0-9a-zA-Z._]+]]
+  // CHECK-NEXT: i32 2, label %[[ACQUIRE_ACQUIRE:[0-9a-zA-Z._]+]]
+  // CHECK-NEXT: ]
+
+  // CHECK: [[RELEASE]]
+  // CHECK: switch {{.*}}, label %[[RELEASE_MONOTONIC:[0-9a-zA-Z._]+]] [
+  // CHECK-NEXT: ]
+
+  // CHECK: [[ACQREL]]
+  // CHECK: switch {{.*}}, label %[[ACQREL_MONOTONIC:[0-9a-zA-Z._]+]] [
+  // CHECK-NEXT: i32 1, label %[[ACQREL_ACQUIRE:[0-9a-zA-Z._]+]]
+  // CHECK-NEXT: i32 2, label %[[ACQREL_ACQUIRE:[0-9a-zA-Z._]+]]
+  // CHECK-NEXT: ]
+
+  // CHECK: [[SEQCST]]
+  // CHECK: switch {{.*}}, label %[[SEQCST_MONOTONIC:[0-9a-zA-Z._]+]] [
+  // CHECK-NEXT: i32 1, label %[[SEQCST_ACQUIRE:[0-9a-zA-Z._]+]]
+  // CHECK-NEXT: i32 2, label %[[SEQCST_ACQUIRE:[0-9a-zA-Z._]+]]
+  // CHECK-NEXT: i32 5, label %[[SEQCST_SEQCST:[0-9a-zA-Z._]+]]
+  // CHECK-NEXT: ]
+
+  // CHECK: [[MONOTONIC_MONOTONIC]]
+  // CHECK: cmpxchg {{.*}} monotonic monotonic
+  // CHECK: br
+
+  // CHECK: [[ACQUIRE_MONOTONIC]]
+  // CHECK: cmpxchg {{.*}} acquire monotonic
+  // CHECK: br
+
+  // CHECK: [[ACQUIRE_ACQUIRE]]
+  // CHECK: cmpxchg {{.*}} acquire acquire
+  // CHECK: br
+
+  // CHECK: [[ACQREL_MONOTONIC]]
+  // CHECK: cmpxchg {{.*}} acq_rel monotonic
+  // CHECK: br
+
+  // CHECK: [[ACQREL_ACQUIRE]]
+  // CHECK: cmpxchg {{.*}} acq_rel acquire
+  // CHECK: br
+
+  // CHECK: [[SEQCST_MONOTONIC]]
+  // CHECK: cmpxchg {{.*}} seq_cst monotonic
+  // CHECK: br
+
+  // CHECK: [[SEQCST_ACQUIRE]]
+  // CHECK: cmpxchg {{.*}} seq_cst acquire
+  // CHECK: br
+
+  // CHECK: [[SEQCST_SEQCST]]
+  // CHECK: cmpxchg {{.*}} seq_cst seq_cst
+  // CHECK: br
+}
+
+void generalWeakness(int *ptr, int *ptr2, _Bool weak) {
+  __atomic_compare_exchange_n(ptr, ptr2, 42, weak, memory_order_seq_cst, memory_order_seq_cst);
+  // CHECK: switch i1 {{.*}}, label %[[WEAK:[0-9a-zA-Z._]+]] [
+  // CHECK-NEXT: i1 false, label %[[STRONG:[0-9a-zA-Z._]+]]
+
+  // CHECK: [[STRONG]]
+  // CHECK-NOT: br
+  // CHECK: cmpxchg {{.*}} seq_cst seq_cst
+  // CHECK: br
+
+  // CHECK: [[WEAK]]
+  // CHECK-NOT: br
+  // CHECK: cmpxchg weak {{.*}} seq_cst seq_cst
+  // CHECK: br
+}
+
+// Having checked the flow in the previous two cases, we'll trust clang to
+// combine them sanely.
+void EMIT_ALL_THE_THINGS(int *ptr, int *ptr2, int new, _Bool weak, int success, int fail) {
+  __atomic_compare_exchange(ptr, ptr2, &new, weak, success, fail);
+
+  // CHECK: = cmpxchg {{.*}} monotonic monotonic
+  // CHECK: = cmpxchg weak {{.*}} monotonic monotonic
+  // CHECK: = cmpxchg {{.*}} acquire monotonic
+  // CHECK: = cmpxchg {{.*}} acquire acquire
+  // CHECK: = cmpxchg weak {{.*}} acquire monotonic
+  // CHECK: = cmpxchg weak {{.*}} acquire acquire
+  // CHECK: = cmpxchg {{.*}} release monotonic
+  // CHECK: = cmpxchg weak {{.*}} release monotonic
+  // CHECK: = cmpxchg {{.*}} acq_rel monotonic
+  // CHECK: = cmpxchg {{.*}} acq_rel acquire
+  // CHECK: = cmpxchg weak {{.*}} acq_rel monotonic
+  // CHECK: = cmpxchg weak {{.*}} acq_rel acquire
+  // CHECK: = cmpxchg {{.*}} seq_cst monotonic
+  // CHECK: = cmpxchg {{.*}} seq_cst acquire
+  // CHECK: = cmpxchg {{.*}} seq_cst seq_cst
+  // CHECK: = cmpxchg weak {{.*}} seq_cst monotonic
+  // CHECK: = cmpxchg weak {{.*}} seq_cst acquire
+  // CHECK: = cmpxchg weak {{.*}} seq_cst seq_cst
 }
 
 #endif
diff --git a/test/CodeGen/atomic.c b/test/CodeGen/atomic.c
index ac3848f..43f5bc8 100644
--- a/test/CodeGen/atomic.c
+++ b/test/CodeGen/atomic.c
@@ -35,10 +35,12 @@
   // CHECK: atomicrmw xchg i32* %val, i32 8 seq_cst
   
   old = __sync_val_compare_and_swap(&val, 4, 1976);
-  // CHECK: cmpxchg i32* %val, i32 4, i32 1976 seq_cst
-  
+  // CHECK: [[PAIR:%[a-z0-9_.]+]] = cmpxchg i32* %val, i32 4, i32 1976 seq_cst
+  // CHECK: extractvalue { i32, i1 } [[PAIR]], 0
+
   old = __sync_bool_compare_and_swap(&val, 4, 1976);
-  // CHECK: cmpxchg i32* %val, i32 4, i32 1976 seq_cst
+  // CHECK: [[PAIR:%[a-z0-9_.]+]] = cmpxchg i32* %val, i32 4, i32 1976 seq_cst
+  // CHECK: extractvalue { i32, i1 } [[PAIR]], 1
 
   old = __sync_fetch_and_and(&val, 0x9);
   // CHECK: atomicrmw and i32* %val, i32 9 seq_cst
@@ -65,10 +67,13 @@
   // CHECK: atomicrmw xor i8* %valc, i8 5 seq_cst  
   
   __sync_val_compare_and_swap((void **)0, (void *)0, (void *)0);
-  // CHECK: cmpxchg i32* null, i32 0, i32 0 seq_cst
+  // CHECK: [[PAIR:%[a-z0-9_.]+]] = cmpxchg i32* null, i32 0, i32 0 seq_cst
+  // CHECK: extractvalue { i32, i1 } [[PAIR]], 0
 
   if ( __sync_val_compare_and_swap(&valb, 0, 1)) {
-    // CHECK: cmpxchg i8* %valb, i8 0, i8 1 seq_cst
+    // CHECK: [[PAIR:%[a-z0-9_.]+]] = cmpxchg i8* %valb, i8 0, i8 1 seq_cst
+    // CHECK: [[VAL:%[a-z0-9_.]+]] = extractvalue { i8, i1 } [[PAIR]], 0
+    // CHECK: trunc i8 [[VAL]] to i1
     old = 42;
   }
   
diff --git a/test/CodeGen/attr-optnone.c b/test/CodeGen/attr-optnone.c
new file mode 100644
index 0000000..e7069b1
--- /dev/null
+++ b/test/CodeGen/attr-optnone.c
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -emit-llvm < %s > %t
+// RUN: FileCheck %s --check-prefix=PRESENT < %t
+// RUN: FileCheck %s --check-prefix=ABSENT  < %t
+
+__attribute__((always_inline))
+int test2() { return 0; }
+// PRESENT-DAG: @test2{{.*}}[[ATTR2:#[0-9]+]]
+
+__attribute__((optnone)) __attribute__((minsize))
+int test3() { return 0; }
+// PRESENT-DAG: @test3{{.*}}[[ATTR3:#[0-9]+]]
+
+__attribute__((optnone)) __attribute__((cold))
+int test4() { return test2(); }
+// PRESENT-DAG: @test4{{.*}}[[ATTR4:#[0-9]+]]
+// Also check that test2 is inlined into test4 (always_inline still works).
+// PRESENT-NOT: call i32 @test2
+
+// Check for both noinline and optnone on each optnone function.
+// PRESENT-DAG: attributes [[ATTR3]] = { {{.*}}noinline{{.*}}optnone{{.*}} }
+// PRESENT-DAG: attributes [[ATTR4]] = { {{.*}}noinline{{.*}}optnone{{.*}} }
+
+// Check that no 'optsize' or 'minsize' attributes appear.
+// ABSENT-NOT: optsize
+// ABSENT-NOT: minsize
diff --git a/test/CodeGen/avx-builtins.c b/test/CodeGen/avx-builtins.c
index c88946f..5b5b6a5 100644
--- a/test/CodeGen/avx-builtins.c
+++ b/test/CodeGen/avx-builtins.c
@@ -111,3 +111,15 @@
   // CHECK: extractelement <32 x i8> %{{.*}}, i32 0
   return _mm256_extract_epi8(__a, 32);
 }
+
+__m256d test_256_blend_pd(__m256d __a, __m256d __b) {
+  // CHECK-LABEL: @test_256_blend_pd
+  // CHECK: shufflevector <4 x double> %{{.*}}, <4 x double> %{{.*}}, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
+  return _mm256_blend_pd(__a, __b, 0x35);
+}
+
+__m256 test_256_blend_ps(__m256 __a, __m256 __b) {
+  // CHECK-LABEL: @test_256_blend_ps
+  // CHECK: shufflevector <8 x float> %{{.*}}, <8 x float> %{{.*}}, <8 x i32> <i32 8, i32 1, i32 10, i32 3, i32 12, i32 13, i32 6, i32 7>
+  return _mm256_blend_ps(__a, __b, 0x35);
+}
diff --git a/test/CodeGen/avx-shuffle-builtins.c b/test/CodeGen/avx-shuffle-builtins.c
index d071f82..76e2395 100644
--- a/test/CodeGen/avx-shuffle-builtins.c
+++ b/test/CodeGen/avx-shuffle-builtins.c
@@ -63,3 +63,37 @@
   // CHECK: @llvm.x86.avx.vperm2f128.si.256
   return _mm256_permute2f128_si256(a, b, 0x20);
 }
+
+__m128
+test_mm_broadcast_ss(float const *__a) {
+  // CHECK-LABEL: @test_mm_broadcast_ss
+  // CHECK: insertelement <4 x float> {{.*}}, i32 0
+  // CHECK: insertelement <4 x float> {{.*}}, i32 1
+  // CHECK: insertelement <4 x float> {{.*}}, i32 2
+  // CHECK: insertelement <4 x float> {{.*}}, i32 3
+  return _mm_broadcast_ss(__a);
+}
+
+__m256d
+test_mm256_broadcast_sd(double const *__a) {
+  // CHECK-LABEL: @test_mm256_broadcast_sd
+  // CHECK: insertelement <4 x double> {{.*}}, i32 0
+  // CHECK: insertelement <4 x double> {{.*}}, i32 1
+  // CHECK: insertelement <4 x double> {{.*}}, i32 2
+  // CHECK: insertelement <4 x double> {{.*}}, i32 3
+  return _mm256_broadcast_sd(__a);
+}
+
+__m256
+test_mm256_broadcast_ss(float const *__a) {
+  // CHECK-LABEL: @test_mm256_broadcast_ss
+  // CHECK: insertelement <8 x float> {{.*}}, i32 0
+  // CHECK: insertelement <8 x float> {{.*}}, i32 1
+  // CHECK: insertelement <8 x float> {{.*}}, i32 2
+  // CHECK: insertelement <8 x float> {{.*}}, i32 3
+  // CHECK: insertelement <8 x float> {{.*}}, i32 4
+  // CHECK: insertelement <8 x float> {{.*}}, i32 5
+  // CHECK: insertelement <8 x float> {{.*}}, i32 6
+  // CHECK: insertelement <8 x float> {{.*}}, i32 7
+  return _mm256_broadcast_ss(__a);
+}
diff --git a/test/CodeGen/avx2-builtins.c b/test/CodeGen/avx2-builtins.c
index 5024d94..10c3a1b 100644
--- a/test/CodeGen/avx2-builtins.c
+++ b/test/CodeGen/avx2-builtins.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -O3 -triple=x86_64-apple-darwin -target-feature +avx2 -emit-llvm -o - -Werror | FileCheck %s
+// RUN: %clang_cc1 %s -O0 -triple=x86_64-apple-darwin -target-feature +avx2 -emit-llvm -o - -Werror | FileCheck %s
 
 // Don't include mm_malloc.h, it's system specific.
 #define __MM_MALLOC_H
@@ -176,8 +176,13 @@
   return _mm256_blendv_epi8(a, b, m);
 }
 
+// FIXME: We should also lower the __builtin_ia32_pblendw128 (and similar)
+// functions to this IR. In the future we could delete the corresponding
+// intrinsic in LLVM if it's not being used anymore.
 __m256i test_mm256_blend_epi16(__m256i a, __m256i b) {
-  // CHECK: @llvm.x86.avx2.pblendw(<16 x i16> %{{.*}}, <16 x i16> %{{.*}}, i32 2)
+  // CHECK-LABEL: test_mm256_blend_epi16
+  // CHECK-NOT: @llvm.x86.avx2.pblendw
+  // CHECK: shufflevector <16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i32> <i32 0, i32 17, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 25, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
   return _mm256_blend_epi16(a, b, 2);
 }
 
@@ -427,17 +432,17 @@
 }
 
 __m256i test_mm256_shuffle_epi32(__m256i a) {
-  // CHECK: shufflevector <8 x i32> %{{.*}}, <8 x i32> undef, <8 x i32> <i32 3, i32 3, i32 0, i32 0, i32 7, i32 7, i32 4, i32 4>
+  // CHECK: shufflevector <8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> <i32 3, i32 3, i32 0, i32 0, i32 7, i32 7, i32 4, i32 4>
   return _mm256_shuffle_epi32(a, 15);
 }
 
 __m256i test_mm256_shufflehi_epi16(__m256i a) {
-  // CHECK: shufflevector <16 x i16> %{{.*}}, <16 x i16> undef, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 7, i32 6, i32 6, i32 5, i32 8, i32 9, i32 10, i32 11, i32 15, i32 14, i32 14, i32 13>
+  // CHECK: shufflevector <16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 7, i32 6, i32 6, i32 5, i32 8, i32 9, i32 10, i32 11, i32 15, i32 14, i32 14, i32 13>
   return _mm256_shufflehi_epi16(a, 107);
 }
 
 __m256i test_mm256_shufflelo_epi16(__m256i a) {
-  // CHECK: shufflevector <16 x i16> %{{.*}}, <16 x i16> undef, <16 x i32> <i32 3, i32 0, i32 1, i32 1, i32 4, i32 5, i32 6, i32 7, i32 11, i32 8, i32 9, i32 9, i32 12, i32 13, i32 14, i32 15>
+  // CHECK: shufflevector <16 x i16> %{{.*}}, <16 x i16> %{{.*}}, <16 x i32> <i32 3, i32 0, i32 1, i32 1, i32 4, i32 5, i32 6, i32 7, i32 11, i32 8, i32 9, i32 9, i32 12, i32 13, i32 14, i32 15>
   return _mm256_shufflelo_epi16(a, 83);
 }
 
@@ -612,13 +617,17 @@
 }
 
 __m128i test_mm_blend_epi32(__m128i a, __m128i b) {
-  // CHECK: @llvm.x86.avx2.pblendd.128
-  return _mm_blend_epi32(a, b, 57);
+  // CHECK-LABEL: test_mm_blend_epi32
+  // CHECK-NOT: @llvm.x86.avx2.pblendd.128
+  // CHECK: shufflevector <4 x i32> %{{.*}}, <4 x i32> %{{.*}}, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
+  return _mm_blend_epi32(a, b, 0x35);
 }
 
 __m256i test_mm256_blend_epi32(__m256i a, __m256i b) {
-  // CHECK: @llvm.x86.avx2.pblendd.256
-  return _mm256_blend_epi32(a, b, 57);
+  // CHECK-LABEL: test_mm256_blend_epi32
+  // CHECK-NOT: @llvm.x86.avx2.pblendd.256
+  // CHECK: shufflevector <8 x i32> %{{.*}}, <8 x i32> %{{.*}}, <8 x i32> <i32 8, i32 1, i32 10, i32 3, i32 12, i32 13, i32 6, i32 7>
+  return _mm256_blend_epi32(a, b, 0x35);
 }
 
 __m256i test_mm256_broadcastb_epi8(__m128i a) {
diff --git a/test/CodeGen/big-atomic-ops.c b/test/CodeGen/big-atomic-ops.c
index b09aede..7409661 100644
--- a/test/CodeGen/big-atomic-ops.c
+++ b/test/CodeGen/big-atomic-ops.c
@@ -106,7 +106,7 @@
 
 _Bool fi4b(int *i) {
   // CHECK: @fi4
-  // CHECK: cmpxchg i32*
+  // CHECK: cmpxchg weak i32*
   int cmp = 0;
   return __atomic_compare_exchange_n(i, &cmp, 1, 1, memory_order_acquire, memory_order_acquire);
 }
@@ -311,13 +311,4 @@
   // CHECK: }
 }
 
-// CHECK: @invalid_atomic
-void invalid_atomic(_Atomic(int) *i) {
-  __c11_atomic_store(i, 1, memory_order_consume);
-  __c11_atomic_store(i, 1, memory_order_acquire);
-  __c11_atomic_store(i, 1, memory_order_acq_rel);
-  __c11_atomic_load(i, memory_order_release);
-  __c11_atomic_load(i, memory_order_acq_rel);
-}
-
 #endif
diff --git a/test/CodeGen/bitfield-2.c b/test/CodeGen/bitfield-2.c
index 58b17f1..c5154fc 100644
--- a/test/CodeGen/bitfield-2.c
+++ b/test/CodeGen/bitfield-2.c
@@ -11,7 +11,7 @@
 // CHECK-RECORD: *** Dumping IRgen Record Layout
 // CHECK-RECORD: Record: RecordDecl{{.*}}s0
 // CHECK-RECORD: Layout: <CGRecordLayout
-// CHECK-RECORD:   LLVMType:%struct.s0 = type <{ [3 x i8] }>
+// CHECK-RECORD:   LLVMType:%struct.s0 = type { [3 x i8] }
 // CHECK-RECORD:   IsZeroInitializable:1
 // CHECK-RECORD:   BitFields:[
 // CHECK-RECORD:     <CGBitFieldInfo Offset:0 Size:24 IsSigned:1 StorageSize:24 StorageAlignment:1>
@@ -51,7 +51,7 @@
 // CHECK-RECORD: *** Dumping IRgen Record Layout
 // CHECK-RECORD: Record: RecordDecl{{.*}}s1
 // CHECK-RECORD: Layout: <CGRecordLayout
-// CHECK-RECORD:   LLVMType:%struct.s1 = type <{ [3 x i8] }>
+// CHECK-RECORD:   LLVMType:%struct.s1 = type { [3 x i8] }
 // CHECK-RECORD:   IsZeroInitializable:1
 // CHECK-RECORD:   BitFields:[
 // CHECK-RECORD:     <CGBitFieldInfo Offset:0 Size:10 IsSigned:1 StorageSize:24 StorageAlignment:1>
@@ -99,7 +99,7 @@
 // CHECK-RECORD: *** Dumping IRgen Record Layout
 // CHECK-RECORD: Record: RecordDecl{{.*}}u2
 // CHECK-RECORD: Layout: <CGRecordLayout
-// CHECK-RECORD:   LLVMType:%union.u2 = type <{ i8 }>
+// CHECK-RECORD:   LLVMType:%union.u2 = type { i8 }
 // CHECK-RECORD:   IsZeroInitializable:1
 // CHECK-RECORD:   BitFields:[
 // CHECK-RECORD:     <CGBitFieldInfo Offset:0 Size:3 IsSigned:0 StorageSize:8 StorageAlignment:1>
@@ -271,7 +271,7 @@
 // CHECK-RECORD: *** Dumping IRgen Record Layout
 // CHECK-RECORD: Record: RecordDecl{{.*}}s7
 // CHECK-RECORD: Layout: <CGRecordLayout
-// CHECK-RECORD:   LLVMType:%struct.s7 = type { i32, i32, i32, i8, [3 x i8], [4 x i8], [12 x i8] }
+// CHECK-RECORD:   LLVMType:%struct.s7 = type { i32, i32, i32, i8, i32, [12 x i8] }
 // CHECK-RECORD:   IsZeroInitializable:1
 // CHECK-RECORD:   BitFields:[
 // CHECK-RECORD:     <CGBitFieldInfo Offset:0 Size:5 IsSigned:1 StorageSize:8 StorageAlignment:4>
diff --git a/test/CodeGen/blocks-opencl.cl b/test/CodeGen/blocks-opencl.cl
new file mode 100644
index 0000000..ab80f5e
--- /dev/null
+++ b/test/CodeGen/blocks-opencl.cl
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -O0 %s -ffake-address-space-map -emit-llvm -o - -fblocks -triple x86_64-unknown-unknown | FileCheck %s
+// This used to crash due to trying to generate a bitcase from a cstring
+// in the constant address space to i8* in AS0.
+
+void dummy(float (^op)(float))
+{
+}
+
+// CHECK: i8 addrspace(3)* getelementptr inbounds ([9 x i8] addrspace(3)* @.str, i32 0, i32 0)
+
+kernel void test_block()
+{
+  float (^X)(float) = ^(float x) { return x + 42.0f; };
+  dummy(X);
+}
+
diff --git a/test/CodeGen/blockstret.c b/test/CodeGen/blockstret.c
index d5dae6f..edd1218 100644
--- a/test/CodeGen/blockstret.c
+++ b/test/CodeGen/blockstret.c
@@ -1,13 +1,20 @@
 // RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin9 %s -emit-llvm -o - | FileCheck %s -check-prefix=X64
 // RUN: %clang_cc1 -fblocks -triple i686-apple-darwin9 %s -emit-llvm -o - | FileCheck %s -check-prefix=X32
+// RUN: %clang_cc1 -fblocks -triple arm64-apple-darwin %s -emit-llvm -o - | FileCheck %s -check-prefix=ARM64
 
 // X64:   internal constant {{.*}} { i8** @_NSConcreteGlobalBlock, i32 1879048192
-// X64:     store i32 1610612736, i32* %want
+// X64:   store i32 1610612736, i32* %want
 
 // X32:   @_NSConcreteGlobalBlock, i32 1879048192, i32 0,
 // X32:   store i32 1610612736, i32* %want
 
 // rdar://7677537
+
+// ARM64: @_NSConcreteGlobalBlock, i32 1342177280, i32 0,
+// ARM64: store i32 1610612736, i32* %want
+
+// rdar://9757126
+
 int printf(const char *, ...);
 void *malloc(__SIZE_TYPE__ size);
 
diff --git a/test/CodeGen/bmi-builtins.c b/test/CodeGen/bmi-builtins.c
index 2e1ba12..92332e3 100644
--- a/test/CodeGen/bmi-builtins.c
+++ b/test/CodeGen/bmi-builtins.c
@@ -5,6 +5,14 @@
 
 #include <x86intrin.h>
 
+// The double underscore intrinsics are for compatibility with 
+// AMD's BMI interface. The single underscore intrinsics
+// are for compatibility with Intel's BMI interface.
+// Apart from the underscores, the interfaces are identical
+// except in one case: although the 'bextr' register-form 
+// instruction is identical in hardware, the AMD and Intel 
+// intrinsics are different! 
+
 unsigned short test__tzcnt_u16(unsigned short __X) {
   // CHECK: @llvm.cttz.i16
   return __tzcnt_u16(__X);
@@ -39,7 +47,7 @@
   return __blsr_u32(__X);
 }
 
-unsigned int test_tzcnt_u32(unsigned int __X) {
+unsigned int test__tzcnt_u32(unsigned int __X) {
   // CHECK: @llvm.cttz.i32
   return __tzcnt_u32(__X);
 }
@@ -77,3 +85,80 @@
   // CHECK: @llvm.cttz.i64
   return __tzcnt_u64(__X);
 }
+
+// Intel intrinsics
+
+unsigned short test_tzcnt_u16(unsigned short __X) {
+  // CHECK: @llvm.cttz.i16
+  return _tzcnt_u16(__X);
+}
+
+unsigned int test_andn_u32(unsigned int __X, unsigned int __Y) {
+  // CHECK: [[DEST:%.*]] = xor i32 %{{.*}}, -1
+  // CHECK-NEXT: %{{.*}} = and i32 %{{.*}}, [[DEST]]
+  return _andn_u32(__X, __Y);
+}
+
+unsigned int test_bextr_u32(unsigned int __X, unsigned int __Y, 
+                            unsigned int __Z) {
+  // CHECK: @llvm.x86.bmi.bextr.32
+  return _bextr_u32(__X, __Y, __Z);
+}
+
+unsigned int test_blsi_u32(unsigned int __X) {
+  // CHECK: [[DEST:%.*]] = sub i32 0, [[SRC:%.*]]
+  // CHECK-NEXT: %{{.*}} = and i32 [[SRC]], [[DEST]]
+  return _blsi_u32(__X);
+}
+
+unsigned int test_blsmsk_u32(unsigned int __X) {
+  // CHECK: [[DEST:%.*]] = add i32 [[SRC:%.*]], -1
+  // CHECK-NEXT: %{{.*}} = xor i32 [[DEST]], [[SRC]]
+  return _blsmsk_u32(__X);
+}
+
+unsigned int test_blsr_u32(unsigned int __X) {
+  // CHECK: [[DEST:%.*]] = add i32 [[SRC:%.*]], -1
+  // CHECK-NEXT: %{{.*}} = and i32 [[DEST]], [[SRC]]
+  return _blsr_u32(__X);
+}
+
+unsigned int test_tzcnt_u32(unsigned int __X) {
+  // CHECK: @llvm.cttz.i32
+  return _tzcnt_u32(__X);
+}
+
+unsigned long long test_andn_u64(unsigned long __X, unsigned long __Y) {
+  // CHECK: [[DEST:%.*]] = xor i64 %{{.*}}, -1
+  // CHECK-NEXT: %{{.*}} = and i64 %{{.*}}, [[DEST]]
+  return _andn_u64(__X, __Y);
+}
+
+unsigned long long test_bextr_u64(unsigned long __X, unsigned int __Y, 
+                                  unsigned int __Z) {
+  // CHECK: @llvm.x86.bmi.bextr.64
+  return _bextr_u64(__X, __Y, __Z);
+}
+
+unsigned long long test_blsi_u64(unsigned long long __X) {
+  // CHECK: [[DEST:%.*]] = sub i64 0, [[SRC:%.*]]
+  // CHECK-NEXT: %{{.*}} = and i64 [[SRC]], [[DEST]]
+  return _blsi_u64(__X);
+}
+
+unsigned long long test_blsmsk_u64(unsigned long long __X) {
+  // CHECK: [[DEST:%.*]] = add i64 [[SRC:%.*]], -1
+  // CHECK-NEXT: %{{.*}} = xor i64 [[DEST]], [[SRC]]
+  return _blsmsk_u64(__X);
+}
+
+unsigned long long test_blsr_u64(unsigned long long __X) {
+  // CHECK: [[DEST:%.*]] = add i64 [[SRC:%.*]], -1
+  // CHECK-NEXT: %{{.*}} = and i64 [[DEST]], [[SRC]]
+  return _blsr_u64(__X);
+}
+
+unsigned long long test_tzcnt_u64(unsigned long long __X) {
+  // CHECK: @llvm.cttz.i64
+  return _tzcnt_u64(__X);
+}
diff --git a/test/CodeGen/bool-convert.c b/test/CodeGen/bool-convert.c
index 8bde837..344fb6b 100644
--- a/test/CodeGen/bool-convert.c
+++ b/test/CodeGen/bool-convert.c
@@ -1,10 +1,24 @@
-// RUN: %clang_cc1 -emit-llvm < %s | grep i1 | count 1
+// RUN: %clang_cc1 -triple i686-pc-linux -emit-llvm < %s | FileCheck %s
 // All of these should uses the memory representation of _Bool
+
+// CHECK-LABEL: %struct.teststruct1 = type { i8, i8 }
+// CHECK-LABEL: @test1 = common global %struct.teststruct1
 struct teststruct1 {_Bool a, b;} test1;
+
+// CHECK-LABEL: @test2 = common global i8* null
 _Bool* test2;
+
+// CHECK-LABEL: @test3 = common global [10 x i8]
 _Bool test3[10];
+
+// CHECK-LABEL: @test4 = common global [0 x i8]* null
 _Bool (*test4)[];
+
+// CHECK-LABEL: define void @f(i32 %x)
 void f(int x) {
+  // CHECK: alloca i8, align 1
   _Bool test5;
+
+  // CHECK: alloca i8, i32 %{{.*}}, align 1
   _Bool test6[x];
 }
diff --git a/test/CodeGen/bool-init.c b/test/CodeGen/bool-init.c
index 1a8f127..09b4a87 100644
--- a/test/CodeGen/bool-init.c
+++ b/test/CodeGen/bool-init.c
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -emit-llvm < %s | grep i1 | count 1
+// RUN: %clang_cc1 -triple x86_64-pc-linux -emit-llvm < %s | FileCheck %s
 
 // Check that the type of this global isn't i1
+// CHECK: @test = global i8 1
 _Bool test = &test;
diff --git a/test/CodeGen/bool_test.c b/test/CodeGen/bool_test.c
index a4aa669..c836b98 100644
--- a/test/CodeGen/bool_test.c
+++ b/test/CodeGen/bool_test.c
@@ -1,4 +1,4 @@
-// REQUIRES: ppc32-registered-target
+// REQUIRES: powerpc-registered-target
 // RUN: %clang_cc1 -triple powerpc-apple-macosx10.4.0 -emit-llvm -o - %s -O2 -disable-llvm-optzns | FileCheck %s
 
 int boolsize = sizeof(_Bool);
diff --git a/test/CodeGen/branch-on-bool.c b/test/CodeGen/branch-on-bool.c
index 78dae1b..98a3845 100644
--- a/test/CodeGen/branch-on-bool.c
+++ b/test/CodeGen/branch-on-bool.c
@@ -12,11 +12,3 @@
   else
     bar();
 }
-
-void fold_for(int a, int b) {
-  // CHECK: define {{.*}} @fold_for(
-  // CHECK-NOT: = phi
-  // CHECK: }
-  for (int i = 0; a && i < b; ++i) foo();
-  for (int i = 0; a || i < b; ++i) bar();
-}
diff --git a/test/CodeGen/builtin-assume.c b/test/CodeGen/builtin-assume.c
new file mode 100644
index 0000000..a381a4c
--- /dev/null
+++ b/test/CodeGen/builtin-assume.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -triple i386-mingw32 -fms-extensions -emit-llvm -o - %s | FileCheck %s
+
+// CHECK-LABEL: @test1
+int test1(int *a) {
+  __assume(a != 0);
+  return a[0];
+}
+
diff --git a/test/CodeGen/builtin-ms-noop.cpp b/test/CodeGen/builtin-ms-noop.cpp
index 7c5068d..76c6c13 100644
--- a/test/CodeGen/builtin-ms-noop.cpp
+++ b/test/CodeGen/builtin-ms-noop.cpp
@@ -1,14 +1,30 @@
-// RUN: %clang_cc1 -fms-extensions -triple i686-pc-win32 -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fms-extensions -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s
 
-class A {
- public:
+struct A {
   ~A() {}
 };
 
-void f() {
-// CHECK: @_Z1fv
+extern "C" int f() {
+// CHECK: define i32 @f()
 // CHECK-NOT: call void @_ZN1AD1Ev
-// CHECK: ret void
-  __noop(A());
+// CHECK: ret i32 0
+  return __noop(A());
 };
 
+extern "C" int g() {
+  return __noop;
+// CHECK: define i32 @g()
+// CHECK: ret i32 0
+}
+
+extern "C" int h() {
+  return (__noop);
+// CHECK: define i32 @h()
+// CHECK: ret i32 0
+}
+
+extern "C" int i() {
+  return __noop + 1;
+// CHECK: define i32 @i()
+// CHECK: ret i32 1
+}
diff --git a/test/CodeGen/builtins-aarch64.c b/test/CodeGen/builtins-aarch64.c
deleted file mode 100644
index 8a93cb4..0000000
--- a/test/CodeGen/builtins-aarch64.c
+++ /dev/null
@@ -1,6 +0,0 @@
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -O3 -emit-llvm -o - %s | FileCheck %s
-
-void f0(char *a, char *b) {
-	__clear_cache(a,b);
-// CHECK: call {{.*}} @__clear_cache
-}
diff --git a/test/CodeGen/builtins-arm-exclusive.c b/test/CodeGen/builtins-arm-exclusive.c
index 7eccb9e..2b10238 100644
--- a/test/CodeGen/builtins-arm-exclusive.c
+++ b/test/CodeGen/builtins-arm-exclusive.c
@@ -1,5 +1,6 @@
 // REQUIRES: arm-registered-target
-// RUN: %clang_cc1 -Wall -Werror -triple thumbv7-linux-gnueabi -fno-signed-char -O3 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -Wall -Werror -triple thumbv8-linux-gnueabi -fno-signed-char -O3 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -Wall -Werror -triple arm64-apple-ios7.0 -O3 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-ARM64
 
 // Make sure the canonical use works before going into smaller details:
 int atomic_inc(int *addr) {
@@ -12,46 +13,80 @@
   return OldVal;
 }
 
-// CHECK: @atomic_inc
+// CHECK-LABEL: @atomic_inc
 // CHECK:   [[OLDVAL:%.*]] = tail call i32 @llvm.arm.ldrex.p0i32(i32* %addr)
 // CHECK:   [[INC:%.*]] = add nsw i32 [[OLDVAL]], 1
 // CHECK:   [[FAILURE:%.*]] = tail call i32 @llvm.arm.strex.p0i32(i32 [[INC]], i32* %addr)
 // CHECK:   [[TST:%.*]] = icmp eq i32 [[FAILURE]], 0
 // CHECK:   br i1 [[TST]], label {{%[a-zA-Z0-9.]+}}, label {{%[a-zA-Z0-9.]+}}
 
+// CHECK-ARM64-LABEL: @atomic_inc
+// CHECK-ARM64:   [[OLDVAL:%.*]] = tail call i64 @llvm.aarch64.ldxr.p0i32(i32* %addr)
+// CHECK-ARM64:   [[INC:%.*]] = add i64 [[OLDVAL]], 1
+// CHECK-ARM64:   [[TRUNC:%.*]] = and i64 [[INC]], 4294967295
+// CHECK-ARM64:   [[FAILURE:%.*]] = tail call i32 @llvm.aarch64.stxr.p0i32(i64 [[TRUNC]], i32* %addr)
+// CHECK-ARM64:   [[TST:%.*]] = icmp eq i32 [[FAILURE]], 0
+// CHECK-ARM64:   br i1 [[TST]], label {{%[a-zA-Z0-9.]+}}, label {{%[a-zA-Z0-9.]+}}
+
 struct Simple {
   char a, b;
 };
 
 int test_ldrex(char *addr, long long *addr64, float *addrfloat) {
-// CHECK: @test_ldrex
+// CHECK-LABEL: @test_ldrex
+// CHECK-ARM64-LABEL: @test_ldrex
   int sum = 0;
   sum += __builtin_arm_ldrex(addr);
 // CHECK: [[INTRES:%.*]] = tail call i32 @llvm.arm.ldrex.p0i8(i8* %addr)
 // CHECK: and i32 [[INTRES]], 255
 
+// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldxr.p0i8(i8* %addr)
+// CHECK-ARM64: [[TRUNCRES:%.*]] = trunc i64 [[INTRES]] to i32
+// CHECK-ARM64: [[SEXTTMP:%.*]] = shl i32 [[TRUNCRES]], 24
+// CHECK-ARM64: ashr exact i32 [[SEXTTMP]], 24
+
   sum += __builtin_arm_ldrex((short *)addr);
 // CHECK: [[ADDR16:%.*]] = bitcast i8* %addr to i16*
 // CHECK: [[INTRES:%.*]] = tail call i32 @llvm.arm.ldrex.p0i16(i16* [[ADDR16]])
 // CHECK: [[TMPSEXT:%.*]] = shl i32 [[INTRES]], 16
 // CHECK: ashr exact i32 [[TMPSEXT]], 16
 
+// CHECK-ARM64: [[ADDR16:%.*]] = bitcast i8* %addr to i16*
+// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldxr.p0i16(i16* [[ADDR16]])
+// CHECK-ARM64: [[TRUNCRES:%.*]] = trunc i64 [[INTRES]] to i32
+// CHECK-ARM64: [[TMPSEXT:%.*]] = shl i32 [[TRUNCRES]], 16
+// CHECK-ARM64: ashr exact i32 [[TMPSEXT]], 16
+
   sum += __builtin_arm_ldrex((int *)addr);
 // CHECK: [[ADDR32:%.*]] = bitcast i8* %addr to i32*
 // CHECK:  call i32 @llvm.arm.ldrex.p0i32(i32* [[ADDR32]])
 
+// CHECK-ARM64: [[ADDR32:%.*]] = bitcast i8* %addr to i32*
+// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldxr.p0i32(i32* [[ADDR32]])
+// CHECK-ARM64: trunc i64 [[INTRES]] to i32
+
   sum += __builtin_arm_ldrex((long long *)addr);
 // CHECK: call { i32, i32 } @llvm.arm.ldrexd(i8* %addr)
 
+// CHECK-ARM64: [[ADDR64:%.*]] = bitcast i8* %addr to i64*
+// CHECK-ARM64: call i64 @llvm.aarch64.ldxr.p0i64(i64* [[ADDR64]])
+
   sum += __builtin_arm_ldrex(addr64);
 // CHECK: [[ADDR64_AS8:%.*]] = bitcast i64* %addr64 to i8*
 // CHECK: call { i32, i32 } @llvm.arm.ldrexd(i8* [[ADDR64_AS8]])
 
+// CHECK-ARM64: call i64 @llvm.aarch64.ldxr.p0i64(i64* %addr64)
+
   sum += __builtin_arm_ldrex(addrfloat);
 // CHECK: [[INTADDR:%.*]] = bitcast float* %addrfloat to i32*
 // CHECK: [[INTRES:%.*]] = tail call i32 @llvm.arm.ldrex.p0i32(i32* [[INTADDR]])
 // CHECK: bitcast i32 [[INTRES]] to float
 
+// CHECK-ARM64: [[INTADDR:%.*]] = bitcast float* %addrfloat to i32*
+// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldxr.p0i32(i32* [[INTADDR]])
+// CHECK-ARM64: [[TRUNCRES:%.*]] = trunc i64 [[INTRES]] to i32
+// CHECK-ARM64: bitcast i32 [[TRUNCRES]] to float
+
   sum += __builtin_arm_ldrex((double *)addr);
 // CHECK: [[STRUCTRES:%.*]] = tail call { i32, i32 } @llvm.arm.ldrexd(i8* %addr)
 // CHECK: [[RESHI:%.*]] = extractvalue { i32, i32 } [[STRUCTRES]], 1
@@ -62,51 +97,271 @@
 // CHECK: [[INTRES:%.*]] = or i64 [[RESHIHI]], [[RESLO64]]
 // CHECK: bitcast i64 [[INTRES]] to double
 
+// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldxr.p0i64(i64* [[ADDR64]])
+// CHECK-ARM64: bitcast i64 [[INTRES]] to double
+
   sum += *__builtin_arm_ldrex((int **)addr);
 // CHECK: [[INTRES:%.*]] = tail call i32 @llvm.arm.ldrex.p0i32(i32* [[ADDR32]])
 // CHECK: inttoptr i32 [[INTRES]] to i32*
 
+// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldxr.p0i64(i64* [[ADDR64]])
+// CHECK-ARM64: inttoptr i64 [[INTRES]] to i32*
+
   sum += __builtin_arm_ldrex((struct Simple **)addr)->a;
 // CHECK: [[INTRES:%.*]] = tail call i32 @llvm.arm.ldrex.p0i32(i32* [[ADDR32]])
 // CHECK: inttoptr i32 [[INTRES]] to %struct.Simple*
 
+// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldxr.p0i64(i64* [[ADDR64]])
+// CHECK-ARM64: inttoptr i64 [[INTRES]] to %struct.Simple*
+  return sum;
+}
+
+int test_ldaex(char *addr, long long *addr64, float *addrfloat) {
+// CHECK-LABEL: @test_ldaex
+// CHECK-ARM64-LABEL: @test_ldaex
+  int sum = 0;
+  sum += __builtin_arm_ldaex(addr);
+// CHECK: [[INTRES:%.*]] = tail call i32 @llvm.arm.ldaex.p0i8(i8* %addr)
+// CHECK: and i32 [[INTRES]], 255
+
+// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldaxr.p0i8(i8* %addr)
+// CHECK-ARM64: [[TRUNCRES:%.*]] = trunc i64 [[INTRES]] to i32
+// CHECK-ARM64: [[SEXTTMP:%.*]] = shl i32 [[TRUNCRES]], 24
+// CHECK-ARM64: ashr exact i32 [[SEXTTMP]], 24
+
+  sum += __builtin_arm_ldaex((short *)addr);
+// CHECK: [[ADDR16:%.*]] = bitcast i8* %addr to i16*
+// CHECK: [[INTRES:%.*]] = tail call i32 @llvm.arm.ldaex.p0i16(i16* [[ADDR16]])
+// CHECK: [[TMPSEXT:%.*]] = shl i32 [[INTRES]], 16
+// CHECK: ashr exact i32 [[TMPSEXT]], 16
+
+// CHECK-ARM64: [[ADDR16:%.*]] = bitcast i8* %addr to i16*
+// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldaxr.p0i16(i16* [[ADDR16]])
+// CHECK-ARM64: [[TRUNCRES:%.*]] = trunc i64 [[INTRES]] to i32
+// CHECK-ARM64: [[TMPSEXT:%.*]] = shl i32 [[TRUNCRES]], 16
+// CHECK-ARM64: ashr exact i32 [[TMPSEXT]], 16
+
+  sum += __builtin_arm_ldaex((int *)addr);
+// CHECK: [[ADDR32:%.*]] = bitcast i8* %addr to i32*
+// CHECK:  call i32 @llvm.arm.ldaex.p0i32(i32* [[ADDR32]])
+
+// CHECK-ARM64: [[ADDR32:%.*]] = bitcast i8* %addr to i32*
+// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldaxr.p0i32(i32* [[ADDR32]])
+// CHECK-ARM64: trunc i64 [[INTRES]] to i32
+
+  sum += __builtin_arm_ldaex((long long *)addr);
+// CHECK: call { i32, i32 } @llvm.arm.ldaexd(i8* %addr)
+
+// CHECK-ARM64: [[ADDR64:%.*]] = bitcast i8* %addr to i64*
+// CHECK-ARM64: call i64 @llvm.aarch64.ldaxr.p0i64(i64* [[ADDR64]])
+
+  sum += __builtin_arm_ldaex(addr64);
+// CHECK: [[ADDR64_AS8:%.*]] = bitcast i64* %addr64 to i8*
+// CHECK: call { i32, i32 } @llvm.arm.ldaexd(i8* [[ADDR64_AS8]])
+
+// CHECK-ARM64: call i64 @llvm.aarch64.ldaxr.p0i64(i64* %addr64)
+
+  sum += __builtin_arm_ldaex(addrfloat);
+// CHECK: [[INTADDR:%.*]] = bitcast float* %addrfloat to i32*
+// CHECK: [[INTRES:%.*]] = tail call i32 @llvm.arm.ldaex.p0i32(i32* [[INTADDR]])
+// CHECK: bitcast i32 [[INTRES]] to float
+
+// CHECK-ARM64: [[INTADDR:%.*]] = bitcast float* %addrfloat to i32*
+// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldaxr.p0i32(i32* [[INTADDR]])
+// CHECK-ARM64: [[TRUNCRES:%.*]] = trunc i64 [[INTRES]] to i32
+// CHECK-ARM64: bitcast i32 [[TRUNCRES]] to float
+
+  sum += __builtin_arm_ldaex((double *)addr);
+// CHECK: [[STRUCTRES:%.*]] = tail call { i32, i32 } @llvm.arm.ldaexd(i8* %addr)
+// CHECK: [[RESHI:%.*]] = extractvalue { i32, i32 } [[STRUCTRES]], 1
+// CHECK: [[RESLO:%.*]] = extractvalue { i32, i32 } [[STRUCTRES]], 0
+// CHECK: [[RESHI64:%.*]] = zext i32 [[RESHI]] to i64
+// CHECK: [[RESLO64:%.*]] = zext i32 [[RESLO]] to i64
+// CHECK: [[RESHIHI:%.*]] = shl nuw i64 [[RESHI64]], 32
+// CHECK: [[INTRES:%.*]] = or i64 [[RESHIHI]], [[RESLO64]]
+// CHECK: bitcast i64 [[INTRES]] to double
+
+// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldaxr.p0i64(i64* [[ADDR64]])
+// CHECK-ARM64: bitcast i64 [[INTRES]] to double
+
+  sum += *__builtin_arm_ldaex((int **)addr);
+// CHECK: [[INTRES:%.*]] = tail call i32 @llvm.arm.ldaex.p0i32(i32* [[ADDR32]])
+// CHECK: inttoptr i32 [[INTRES]] to i32*
+
+// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldaxr.p0i64(i64* [[ADDR64]])
+// CHECK-ARM64: inttoptr i64 [[INTRES]] to i32*
+
+  sum += __builtin_arm_ldaex((struct Simple **)addr)->a;
+// CHECK: [[INTRES:%.*]] = tail call i32 @llvm.arm.ldaex.p0i32(i32* [[ADDR32]])
+// CHECK: inttoptr i32 [[INTRES]] to %struct.Simple*
+
+// CHECK-ARM64: [[INTRES:%.*]] = tail call i64 @llvm.aarch64.ldaxr.p0i64(i64* [[ADDR64]])
+// CHECK-ARM64: inttoptr i64 [[INTRES]] to %struct.Simple*
   return sum;
 }
 
 int test_strex(char *addr) {
-// CHECK: @test_strex
+// CHECK-LABEL: @test_strex
+// CHECK-ARM64-LABEL: @test_strex
   int res = 0;
   struct Simple var = {0};
   res |= __builtin_arm_strex(4, addr);
 // CHECK: call i32 @llvm.arm.strex.p0i8(i32 4, i8* %addr)
 
+// CHECK-ARM64: call i32 @llvm.aarch64.stxr.p0i8(i64 4, i8* %addr)
+
   res |= __builtin_arm_strex(42, (short *)addr);
 // CHECK: [[ADDR16:%.*]] = bitcast i8* %addr to i16*
 // CHECK:  call i32 @llvm.arm.strex.p0i16(i32 42, i16* [[ADDR16]])
 
+// CHECK-ARM64: [[ADDR16:%.*]] = bitcast i8* %addr to i16*
+// CHECK-ARM64:  call i32 @llvm.aarch64.stxr.p0i16(i64 42, i16* [[ADDR16]])
+
   res |= __builtin_arm_strex(42, (int *)addr);
 // CHECK: [[ADDR32:%.*]] = bitcast i8* %addr to i32*
 // CHECK: call i32 @llvm.arm.strex.p0i32(i32 42, i32* [[ADDR32]])
 
+// CHECK-ARM64: [[ADDR32:%.*]] = bitcast i8* %addr to i32*
+// CHECK-ARM64: call i32 @llvm.aarch64.stxr.p0i32(i64 42, i32* [[ADDR32]])
+
   res |= __builtin_arm_strex(42, (long long *)addr);
 // CHECK: call i32 @llvm.arm.strexd(i32 42, i32 0, i8* %addr)
 
+// CHECK-ARM64: [[ADDR64:%.*]] = bitcast i8* %addr to i64*
+// CHECK-ARM64: call i32 @llvm.aarch64.stxr.p0i64(i64 42, i64* [[ADDR64]])
+
   res |= __builtin_arm_strex(2.71828f, (float *)addr);
 // CHECK: call i32 @llvm.arm.strex.p0i32(i32 1076754509, i32* [[ADDR32]])
 
+// CHECK-ARM64: call i32 @llvm.aarch64.stxr.p0i32(i64 1076754509, i32* [[ADDR32]])
+
   res |= __builtin_arm_strex(3.14159, (double *)addr);
 // CHECK: call i32 @llvm.arm.strexd(i32 -266631570, i32 1074340345, i8* %addr)
 
+// CHECK-ARM64: call i32 @llvm.aarch64.stxr.p0i64(i64 4614256650576692846, i64* [[ADDR64]])
+
   res |= __builtin_arm_strex(&var, (struct Simple **)addr);
 // CHECK: [[INTVAL:%.*]] = ptrtoint i16* %var to i32
 // CHECK: call i32 @llvm.arm.strex.p0i32(i32 [[INTVAL]], i32* [[ADDR32]])
 
+// CHECK-ARM64: [[INTVAL:%.*]] = ptrtoint i16* %var to i64
+// CHECK-ARM64: call i32 @llvm.aarch64.stxr.p0i64(i64 [[INTVAL]], i64* [[ADDR64]])
+
+  return res;
+}
+
+int test_stlex(char *addr) {
+// CHECK-LABEL: @test_stlex
+// CHECK-ARM64-LABEL: @test_stlex
+  int res = 0;
+  struct Simple var = {0};
+  res |= __builtin_arm_stlex(4, addr);
+// CHECK: call i32 @llvm.arm.stlex.p0i8(i32 4, i8* %addr)
+
+// CHECK-ARM64: call i32 @llvm.aarch64.stlxr.p0i8(i64 4, i8* %addr)
+
+  res |= __builtin_arm_stlex(42, (short *)addr);
+// CHECK: [[ADDR16:%.*]] = bitcast i8* %addr to i16*
+// CHECK:  call i32 @llvm.arm.stlex.p0i16(i32 42, i16* [[ADDR16]])
+
+// CHECK-ARM64: [[ADDR16:%.*]] = bitcast i8* %addr to i16*
+// CHECK-ARM64:  call i32 @llvm.aarch64.stlxr.p0i16(i64 42, i16* [[ADDR16]])
+
+  res |= __builtin_arm_stlex(42, (int *)addr);
+// CHECK: [[ADDR32:%.*]] = bitcast i8* %addr to i32*
+// CHECK: call i32 @llvm.arm.stlex.p0i32(i32 42, i32* [[ADDR32]])
+
+// CHECK-ARM64: [[ADDR32:%.*]] = bitcast i8* %addr to i32*
+// CHECK-ARM64: call i32 @llvm.aarch64.stlxr.p0i32(i64 42, i32* [[ADDR32]])
+
+  res |= __builtin_arm_stlex(42, (long long *)addr);
+// CHECK: call i32 @llvm.arm.stlexd(i32 42, i32 0, i8* %addr)
+
+// CHECK-ARM64: [[ADDR64:%.*]] = bitcast i8* %addr to i64*
+// CHECK-ARM64: call i32 @llvm.aarch64.stlxr.p0i64(i64 42, i64* [[ADDR64]])
+
+  res |= __builtin_arm_stlex(2.71828f, (float *)addr);
+// CHECK: call i32 @llvm.arm.stlex.p0i32(i32 1076754509, i32* [[ADDR32]])
+
+// CHECK-ARM64: call i32 @llvm.aarch64.stlxr.p0i32(i64 1076754509, i32* [[ADDR32]])
+
+  res |= __builtin_arm_stlex(3.14159, (double *)addr);
+// CHECK: call i32 @llvm.arm.stlexd(i32 -266631570, i32 1074340345, i8* %addr)
+
+// CHECK-ARM64: call i32 @llvm.aarch64.stlxr.p0i64(i64 4614256650576692846, i64* [[ADDR64]])
+
+  res |= __builtin_arm_stlex(&var, (struct Simple **)addr);
+// CHECK: [[INTVAL:%.*]] = ptrtoint i16* %var to i32
+// CHECK: call i32 @llvm.arm.stlex.p0i32(i32 [[INTVAL]], i32* [[ADDR32]])
+
+// CHECK-ARM64: [[INTVAL:%.*]] = ptrtoint i16* %var to i64
+// CHECK-ARM64: call i32 @llvm.aarch64.stlxr.p0i64(i64 [[INTVAL]], i64* [[ADDR64]])
+
   return res;
 }
 
 void test_clrex() {
-// CHECK: @test_clrex
+// CHECK-LABEL: @test_clrex
+// CHECK-ARM64-LABEL: @test_clrex
 
   __builtin_arm_clrex();
 // CHECK: call void @llvm.arm.clrex()
+// CHECK-ARM64: call void @llvm.aarch64.clrex()
 }
+
+#ifdef __aarch64__
+// 128-bit tests
+
+__int128 test_ldrex_128(__int128 *addr) {
+// CHECK-ARM64-LABEL: @test_ldrex_128
+
+  return __builtin_arm_ldrex(addr);
+// CHECK-ARM64: [[ADDR8:%.*]] = bitcast i128* %addr to i8*
+// CHECK-ARM64: [[STRUCTRES:%.*]] = tail call { i64, i64 } @llvm.aarch64.ldxp(i8* [[ADDR8]])
+// CHECK-ARM64: [[RESHI:%.*]] = extractvalue { i64, i64 } [[STRUCTRES]], 1
+// CHECK-ARM64: [[RESLO:%.*]] = extractvalue { i64, i64 } [[STRUCTRES]], 0
+// CHECK-ARM64: [[RESHI64:%.*]] = zext i64 [[RESHI]] to i128
+// CHECK-ARM64: [[RESLO64:%.*]] = zext i64 [[RESLO]] to i128
+// CHECK-ARM64: [[RESHIHI:%.*]] = shl nuw i128 [[RESHI64]], 64
+// CHECK-ARM64: [[INTRES:%.*]] = or i128 [[RESHIHI]], [[RESLO64]]
+// CHECK-ARM64: ret i128 [[INTRES]]
+}
+
+int test_strex_128(__int128 *addr, __int128 val) {
+// CHECK-ARM64-LABEL: @test_strex_128
+
+  return __builtin_arm_strex(val, addr);
+// CHECK-ARM64: [[VALLO:%.*]] = trunc i128 %val to i64
+// CHECK-ARM64: [[VALHI128:%.*]] = lshr i128 %val, 64
+// CHECK-ARM64: [[VALHI:%.*]] = trunc i128 [[VALHI128]] to i64
+// CHECK-ARM64: [[ADDR8:%.*]] = bitcast i128* %addr to i8*
+// CHECK-ARM64: [[RES:%.*]] = tail call i32 @llvm.aarch64.stxp(i64 [[VALLO]], i64 [[VALHI]], i8* [[ADDR8]])
+}
+
+__int128 test_ldaex_128(__int128 *addr) {
+// CHECK-ARM64-LABEL: @test_ldaex_128
+
+  return __builtin_arm_ldaex(addr);
+// CHECK-ARM64: [[ADDR8:%.*]] = bitcast i128* %addr to i8*
+// CHECK-ARM64: [[STRUCTRES:%.*]] = tail call { i64, i64 } @llvm.aarch64.ldaxp(i8* [[ADDR8]])
+// CHECK-ARM64: [[RESHI:%.*]] = extractvalue { i64, i64 } [[STRUCTRES]], 1
+// CHECK-ARM64: [[RESLO:%.*]] = extractvalue { i64, i64 } [[STRUCTRES]], 0
+// CHECK-ARM64: [[RESHI64:%.*]] = zext i64 [[RESHI]] to i128
+// CHECK-ARM64: [[RESLO64:%.*]] = zext i64 [[RESLO]] to i128
+// CHECK-ARM64: [[RESHIHI:%.*]] = shl nuw i128 [[RESHI64]], 64
+// CHECK-ARM64: [[INTRES:%.*]] = or i128 [[RESHIHI]], [[RESLO64]]
+// CHECK-ARM64: ret i128 [[INTRES]]
+}
+
+int test_stlex_128(__int128 *addr, __int128 val) {
+// CHECK-ARM64-LABEL: @test_stlex_128
+
+  return __builtin_arm_stlex(val, addr);
+// CHECK-ARM64: [[VALLO:%.*]] = trunc i128 %val to i64
+// CHECK-ARM64: [[VALHI128:%.*]] = lshr i128 %val, 64
+// CHECK-ARM64: [[VALHI:%.*]] = trunc i128 [[VALHI128]] to i64
+// CHECK-ARM64: [[ADDR8:%.*]] = bitcast i128* %addr to i8*
+// CHECK-ARM64: [[RES:%.*]] = tail call i32 @llvm.aarch64.stlxp(i64 [[VALLO]], i64 [[VALHI]], i8* [[ADDR8]])
+}
+
+#endif
diff --git a/test/CodeGen/builtins-arm-microsoft.c b/test/CodeGen/builtins-arm-microsoft.c
new file mode 100644
index 0000000..6f7b3ea
--- /dev/null
+++ b/test/CodeGen/builtins-arm-microsoft.c
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -triple thumbv7-windows -fms-compatibility -emit-llvm -o - %s \
+// RUN:     | FileCheck %s -check-prefix CHECK-MSVC
+// RUN: %clang_cc1 -triple armv7-eabi -emit-llvm %s -o - \
+// RUN:     | FileCheck %s -check-prefix CHECK-EABI
+// REQUIRES: arm-registered-target
+
+void test_yield_intrinsic() {
+  __yield();
+}
+
+// CHECK-MSVC: call void @llvm.arm.hint(i32 1)
+// CHECK-EABI-NOT: call void @llvm.arm.hint(i32 1)
+
+void wfe() {
+  __wfe();
+}
+
+// CHECK-MSVC: call {{.*}} @llvm.arm.hint(i32 2)
+// CHECK-EABI-NOT: call {{.*}} @llvm.arm.hint(i32 2)
+
+void wfi() {
+  __wfi();
+}
+
+// CHECK-MSVC: call {{.*}} @llvm.arm.hint(i32 3)
+// CHECK-EABI-NOT: call {{.*}} @llvm.arm.hint(i32 3)
+
+void sev() {
+  __sev();
+}
+
+// CHECK-MSVC: call {{.*}} @llvm.arm.hint(i32 4)
+// CHECK-EABI-NOT: call {{.*}} @llvm.arm.hint(i32 4)
+
+void sevl() {
+  __sevl();
+}
+
+// CHECK-MSVC: call {{.*}} @llvm.arm.hint(i32 5)
+// CHECK-EABI-NOT: call {{.*}} @llvm.arm.hint(i32 5)
+
diff --git a/test/CodeGen/builtins-arm.c b/test/CodeGen/builtins-arm.c
index 937e1d9..a51df15 100644
--- a/test/CodeGen/builtins-arm.c
+++ b/test/CodeGen/builtins-arm.c
@@ -19,12 +19,50 @@
   res = __builtin_eh_return_data_regno(1);  // CHECK: store volatile i32 1
 }
 
+void nop() {
+  __builtin_arm_nop();
+}
+
+// CHECK: call {{.*}} @llvm.arm.hint(i32 0)
+
+void yield() {
+  __builtin_arm_yield();
+}
+
+// CHECK: call {{.*}} @llvm.arm.hint(i32 1)
+
+void wfe() {
+  __builtin_arm_wfe();
+}
+
+// CHECK: call {{.*}} @llvm.arm.hint(i32 2)
+
+void wfi() {
+  __builtin_arm_wfi();
+}
+
+// CHECK: call {{.*}} @llvm.arm.hint(i32 3)
+
+void sev() {
+  __builtin_arm_sev();
+}
+
+// CHECK: call {{.*}} @llvm.arm.hint(i32 4)
+
 void sevl() {
   __builtin_arm_sevl();
 }
-// CHECK: call {{.*}} @llvm.arm.sevl
+
+// CHECK: call {{.*}} @llvm.arm.hint(i32 5)
 
 void test_barrier() {
   __builtin_arm_dmb(1); //CHECK: call {{.*}} @llvm.arm.dmb(i32 1)
   __builtin_arm_dsb(2); //CHECK: call {{.*}} @llvm.arm.dsb(i32 2)
+  __builtin_arm_isb(3); //CHECK: call {{.*}} @llvm.arm.isb(i32 3)
+}
+
+// CHECK: call {{.*}} @llvm.arm.rbit(i32 %a)
+
+unsigned rbit(unsigned a) {
+  return __builtin_arm_rbit(a);
 }
diff --git a/test/CodeGen/builtins-arm64.c b/test/CodeGen/builtins-arm64.c
new file mode 100644
index 0000000..cfa1181
--- /dev/null
+++ b/test/CodeGen/builtins-arm64.c
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -triple arm64-apple-ios -O3 -emit-llvm -o - %s | FileCheck %s
+
+void f0(void *a, void *b) {
+	__clear_cache(a,b);
+// CHECK: call {{.*}} @__clear_cache
+}
+
+// CHECK: call {{.*}} @llvm.aarch64.rbit.i32(i32 %a)
+unsigned rbit(unsigned a) {
+  return __builtin_arm_rbit(a);
+}
+
+// CHECK: call {{.*}} @llvm.aarch64.rbit.i64(i64 %a)
+unsigned long long rbit64(unsigned long long a) {
+  return __builtin_arm_rbit64(a);
+}
+
+void hints() {
+  __builtin_arm_nop();    //CHECK: call {{.*}} @llvm.aarch64.hint(i32 0)
+  __builtin_arm_yield();  //CHECK: call {{.*}} @llvm.aarch64.hint(i32 1)
+  __builtin_arm_wfe();    //CHECK: call {{.*}} @llvm.aarch64.hint(i32 2)
+  __builtin_arm_wfi();    //CHECK: call {{.*}} @llvm.aarch64.hint(i32 3)
+  __builtin_arm_sev();    //CHECK: call {{.*}} @llvm.aarch64.hint(i32 4)
+  __builtin_arm_sevl();   //CHECK: call {{.*}} @llvm.aarch64.hint(i32 5)
+}
+
+void barriers() {
+  __builtin_arm_dmb(1);  //CHECK: call {{.*}} @llvm.aarch64.dmb(i32 1)
+  __builtin_arm_dsb(2);  //CHECK: call {{.*}} @llvm.aarch64.dsb(i32 2)
+  __builtin_arm_isb(3);  //CHECK: call {{.*}} @llvm.aarch64.isb(i32 3)
+}
diff --git a/test/CodeGen/builtins-mips-msa.c b/test/CodeGen/builtins-mips-msa.c
index 69cb8e2..38aea04 100644
--- a/test/CodeGen/builtins-mips-msa.c
+++ b/test/CodeGen/builtins-mips-msa.c
@@ -701,15 +701,15 @@
   v8i16_r = __builtin_msa_shf_h(v8i16_a, 3); // CHECK: call <8  x i16> @llvm.mips.shf.h(
   v4i32_r = __builtin_msa_shf_w(v4i32_a, 3); // CHECK: call <4  x i32> @llvm.mips.shf.w(
 
-  v16i8_r = __builtin_msa_sld_b(v16i8_a, 10); // CHECK: call <16 x i8>  @llvm.mips.sld.b(
-  v8i16_r = __builtin_msa_sld_h(v8i16_a, 10); // CHECK: call <8  x i16> @llvm.mips.sld.h(
-  v4i32_r = __builtin_msa_sld_w(v4i32_a, 10); // CHECK: call <4  x i32> @llvm.mips.sld.w(
-  v2i64_r = __builtin_msa_sld_d(v2i64_a, 10); // CHECK: call <2  x i64> @llvm.mips.sld.d(
+  v16i8_r = __builtin_msa_sld_b(v16i8_r, v16i8_a, 10); // CHECK: call <16 x i8>  @llvm.mips.sld.b(
+  v8i16_r = __builtin_msa_sld_h(v8i16_r, v8i16_a, 10); // CHECK: call <8  x i16> @llvm.mips.sld.h(
+  v4i32_r = __builtin_msa_sld_w(v4i32_r, v4i32_a, 10); // CHECK: call <4  x i32> @llvm.mips.sld.w(
+  v2i64_r = __builtin_msa_sld_d(v2i64_r, v2i64_a, 10); // CHECK: call <2  x i64> @llvm.mips.sld.d(
 
-  v16i8_r = __builtin_msa_sldi_b(v16i8_a, 3); // CHECK: call <16 x i8>  @llvm.mips.sldi.b(
-  v8i16_r = __builtin_msa_sldi_h(v8i16_a, 3); // CHECK: call <8  x i16> @llvm.mips.sldi.h(
-  v4i32_r = __builtin_msa_sldi_w(v4i32_a, 3); // CHECK: call <4  x i32> @llvm.mips.sldi.w(
-  v2i64_r = __builtin_msa_sldi_d(v2i64_a, 3); // CHECK: call <2  x i64> @llvm.mips.sldi.d(
+  v16i8_r = __builtin_msa_sldi_b(v16i8_r, v16i8_a, 3); // CHECK: call <16 x i8>  @llvm.mips.sldi.b(
+  v8i16_r = __builtin_msa_sldi_h(v8i16_r, v8i16_a, 3); // CHECK: call <8  x i16> @llvm.mips.sldi.h(
+  v4i32_r = __builtin_msa_sldi_w(v4i32_r, v4i32_a, 3); // CHECK: call <4  x i32> @llvm.mips.sldi.w(
+  v2i64_r = __builtin_msa_sldi_d(v2i64_r, v2i64_a, 3); // CHECK: call <2  x i64> @llvm.mips.sldi.d(
 
   v16i8_r = __builtin_msa_sll_b(v16i8_a, v16i8_b); // CHECK: call <16 x i8>  @llvm.mips.sll.b(
   v8i16_r = __builtin_msa_sll_h(v8i16_a, v8i16_b); // CHECK: call <8  x i16> @llvm.mips.sll.h(
diff --git a/test/CodeGen/builtins-nvptx.c b/test/CodeGen/builtins-nvptx.c
index 7deee8e..cee9061 100644
--- a/test/CodeGen/builtins-nvptx.c
+++ b/test/CodeGen/builtins-nvptx.c
@@ -1,5 +1,4 @@
 // REQUIRES: nvptx-registered-target
-// REQUIRES: nvptx64-registered-target
 // RUN: %clang_cc1 -triple nvptx-unknown-unknown -S -emit-llvm -o - %s | FileCheck %s
 // RUN: %clang_cc1 -triple nvptx64-unknown-unknown -S -emit-llvm -o - %s | FileCheck %s
 
diff --git a/test/CodeGen/builtins-ppc-altivec.c b/test/CodeGen/builtins-ppc-altivec.c
index 47a198f..3149107 100644
--- a/test/CodeGen/builtins-ppc-altivec.c
+++ b/test/CodeGen/builtins-ppc-altivec.c
@@ -1,5 +1,7 @@
-// REQUIRES: ppc32-registered-target
+// REQUIRES: powerpc-registered-target
 // RUN: %clang_cc1 -faltivec -triple powerpc-unknown-unknown -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -faltivec -triple powerpc64-unknown-unknown -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -faltivec -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK-LE
 
 vector bool char vbc = { 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 };
 vector signed char vsc = { 1, -2, 3, -4, 5, -6, 7, -8, 9, -10, 11, -12, 13, -14, 15, -16 };
@@ -45,1267 +47,3737 @@
 void test1() {
 
   /* vec_abs */
-  vsc = vec_abs(vsc);                           // CHECK: sub <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vmaxsb
+  vsc = vec_abs(vsc);
+// CHECK: sub <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vmaxsb
+// CHECK-LE: sub <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vmaxsb
 
-  vs = vec_abs(vs);                             // CHECK: sub <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vmaxsh
+  vs = vec_abs(vs);
+// CHECK: sub <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vmaxsh
+// CHECK-LE: sub <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vmaxsh
 
-  vi = vec_abs(vi);                             // CHECK: sub <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vmaxsw
+  vi = vec_abs(vi);
+// CHECK: sub <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vmaxsw
+// CHECK-LE: sub <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vmaxsw
 
-  vf = vec_abs(vf);                             // CHECK: and <4 x i32>
+  vf = vec_abs(vf);
+// CHECK: and <4 x i32>
+// CHECK-LE: and <4 x i32>
 
   /* vec_abs */
-  vsc = vec_abss(vsc);                          // CHECK: @llvm.ppc.altivec.vsubsbs
-                                                // CHECK: @llvm.ppc.altivec.vmaxsb
+  vsc = vec_abss(vsc);
+// CHECK: @llvm.ppc.altivec.vsubsbs
+// CHECK: @llvm.ppc.altivec.vmaxsb
+// CHECK-LE: @llvm.ppc.altivec.vsubsbs
+// CHECK-LE: @llvm.ppc.altivec.vmaxsb
 
-  vs = vec_abss(vs);                            // CHECK: @llvm.ppc.altivec.vsubshs
-                                                // CHECK: @llvm.ppc.altivec.vmaxsh
+  vs = vec_abss(vs);
+// CHECK: @llvm.ppc.altivec.vsubshs
+// CHECK: @llvm.ppc.altivec.vmaxsh
+// CHECK-LE: @llvm.ppc.altivec.vsubshs
+// CHECK-LE: @llvm.ppc.altivec.vmaxsh
 
-  vi = vec_abss(vi);                            // CHECK: @llvm.ppc.altivec.vsubsws
-                                                // CHECK: @llvm.ppc.altivec.vmaxsw
+  vi = vec_abss(vi);
+// CHECK: @llvm.ppc.altivec.vsubsws
+// CHECK: @llvm.ppc.altivec.vmaxsw
+// CHECK-LE: @llvm.ppc.altivec.vsubsws
+// CHECK-LE: @llvm.ppc.altivec.vmaxsw
 
   /*  vec_add */
-  res_vsc = vec_add(vsc, vsc);                  // CHECK: add <16 x i8>
-  res_vsc = vec_add(vbc, vsc);                  // CHECK: add <16 x i8>
-  res_vsc = vec_add(vsc, vbc);                  // CHECK: add <16 x i8>
-  res_vuc = vec_add(vuc, vuc);                  // CHECK: add <16 x i8>
-  res_vuc = vec_add(vbc, vuc);                  // CHECK: add <16 x i8>
-  res_vuc = vec_add(vuc, vbc);                  // CHECK: add <16 x i8>
-  res_vs  = vec_add(vs, vs);                    // CHECK: add <8 x i16>
-  res_vs  = vec_add(vbs, vs);                   // CHECK: add <8 x i16>
-  res_vs  = vec_add(vs, vbs);                   // CHECK: add <8 x i16>
-  res_vus = vec_add(vus, vus);                  // CHECK: add <8 x i16>
-  res_vus = vec_add(vbs, vus);                  // CHECK: add <8 x i16>
-  res_vus = vec_add(vus, vbs);                  // CHECK: add <8 x i16>
-  res_vi  = vec_add(vi, vi);                    // CHECK: add <4 x i32>
-  res_vi  = vec_add(vbi, vi);                   // CHECK: add <4 x i32>
-  res_vi  = vec_add(vi, vbi);                   // CHECK: add <4 x i32>
-  res_vui = vec_add(vui, vui);                  // CHECK: add <4 x i32>
-  res_vui = vec_add(vbi, vui);                  // CHECK: add <4 x i32>
-  res_vui = vec_add(vui, vbi);                  // CHECK: add <4 x i32>
-  res_vf  = vec_add(vf, vf);                    // CHECK: fadd <4 x float>
-  res_vsc = vec_vaddubm(vsc, vsc);              // CHECK: add <16 x i8>
-  res_vsc = vec_vaddubm(vbc, vsc);              // CHECK: add <16 x i8>
-  res_vsc = vec_vaddubm(vsc, vbc);              // CHECK: add <16 x i8>
-  res_vuc = vec_vaddubm(vuc, vuc);              // CHECK: add <16 x i8>
-  res_vuc = vec_vaddubm(vbc, vuc);              // CHECK: add <16 x i8>
-  res_vuc = vec_vaddubm(vuc, vbc);              // CHECK: add <16 x i8>
-  res_vs  = vec_vadduhm(vs, vs);                // CHECK: add <8 x i16>
-  res_vs  = vec_vadduhm(vbs, vs);               // CHECK: add <8 x i16>
-  res_vs  = vec_vadduhm(vs, vbs);               // CHECK: add <8 x i16>
-  res_vus = vec_vadduhm(vus, vus);              // CHECK: add <8 x i16>
-  res_vus = vec_vadduhm(vbs, vus);              // CHECK: add <8 x i16>
-  res_vus = vec_vadduhm(vus, vbs);              // CHECK: add <8 x i16>
-  res_vi  = vec_vadduwm(vi, vi);                // CHECK: add <4 x i32>
-  res_vi  = vec_vadduwm(vbi, vi);               // CHECK: add <4 x i32>
-  res_vi  = vec_vadduwm(vi, vbi);               // CHECK: add <4 x i32>
-  res_vui = vec_vadduwm(vui, vui);              // CHECK: add <4 x i32>
-  res_vui = vec_vadduwm(vbi, vui);              // CHECK: add <4 x i32>
-  res_vui = vec_vadduwm(vui, vbi);              // CHECK: add <4 x i32>
-  res_vf  = vec_vaddfp(vf, vf);                 // CHECK: fadd <4 x float>
+  res_vsc = vec_add(vsc, vsc);
+// CHECK: add <16 x i8>
+// CHECK-LE: add <16 x i8>
+
+  res_vsc = vec_add(vbc, vsc);
+// CHECK: add <16 x i8>
+// CHECK-LE: add <16 x i8>
+
+  res_vsc = vec_add(vsc, vbc);
+// CHECK: add <16 x i8>
+// CHECK-LE: add <16 x i8>
+
+  res_vuc = vec_add(vuc, vuc);
+// CHECK: add <16 x i8>
+// CHECK-LE: add <16 x i8>
+
+  res_vuc = vec_add(vbc, vuc);
+// CHECK: add <16 x i8>
+// CHECK-LE: add <16 x i8>
+
+  res_vuc = vec_add(vuc, vbc);
+// CHECK: add <16 x i8>
+// CHECK-LE: add <16 x i8>
+
+  res_vs  = vec_add(vs, vs);
+// CHECK: add <8 x i16>
+// CHECK-LE: add <8 x i16>
+
+  res_vs  = vec_add(vbs, vs);
+// CHECK: add <8 x i16>
+// CHECK-LE: add <8 x i16>
+
+  res_vs  = vec_add(vs, vbs);
+// CHECK: add <8 x i16>
+// CHECK-LE: add <8 x i16>
+
+  res_vus = vec_add(vus, vus);
+// CHECK: add <8 x i16>
+// CHECK-LE: add <8 x i16>
+
+  res_vus = vec_add(vbs, vus);
+// CHECK: add <8 x i16>
+// CHECK-LE: add <8 x i16>
+
+  res_vus = vec_add(vus, vbs);
+// CHECK: add <8 x i16>
+// CHECK-LE: add <8 x i16>
+
+  res_vi  = vec_add(vi, vi);
+// CHECK: add <4 x i32>
+// CHECK-LE: add <4 x i32>
+
+  res_vi  = vec_add(vbi, vi);
+// CHECK: add <4 x i32>
+// CHECK-LE: add <4 x i32>
+
+  res_vi  = vec_add(vi, vbi);
+// CHECK: add <4 x i32>
+// CHECK-LE: add <4 x i32>
+
+  res_vui = vec_add(vui, vui);
+// CHECK: add <4 x i32>
+// CHECK-LE: add <4 x i32>
+
+  res_vui = vec_add(vbi, vui);
+// CHECK: add <4 x i32>
+// CHECK-LE: add <4 x i32>
+
+  res_vui = vec_add(vui, vbi);
+// CHECK: add <4 x i32>
+// CHECK-LE: add <4 x i32>
+
+  res_vf  = vec_add(vf, vf);
+// CHECK: fadd <4 x float>
+// CHECK-LE: fadd <4 x float>
+
+  res_vsc = vec_vaddubm(vsc, vsc);
+// CHECK: add <16 x i8>
+// CHECK-LE: add <16 x i8>
+
+  res_vsc = vec_vaddubm(vbc, vsc);
+// CHECK: add <16 x i8>
+// CHECK-LE: add <16 x i8>
+
+  res_vsc = vec_vaddubm(vsc, vbc);
+// CHECK: add <16 x i8>
+// CHECK-LE: add <16 x i8>
+
+  res_vuc = vec_vaddubm(vuc, vuc);
+// CHECK: add <16 x i8>
+// CHECK-LE: add <16 x i8>
+
+  res_vuc = vec_vaddubm(vbc, vuc);
+// CHECK: add <16 x i8>
+// CHECK-LE: add <16 x i8>
+
+  res_vuc = vec_vaddubm(vuc, vbc);
+// CHECK: add <16 x i8>
+// CHECK-LE: add <16 x i8>
+
+  res_vs  = vec_vadduhm(vs, vs);
+// CHECK: add <8 x i16>
+// CHECK-LE: add <8 x i16>
+
+  res_vs  = vec_vadduhm(vbs, vs);
+// CHECK: add <8 x i16>
+// CHECK-LE: add <8 x i16>
+
+  res_vs  = vec_vadduhm(vs, vbs);
+// CHECK: add <8 x i16>
+// CHECK-LE: add <8 x i16>
+
+  res_vus = vec_vadduhm(vus, vus);
+// CHECK: add <8 x i16>
+// CHECK-LE: add <8 x i16>
+
+  res_vus = vec_vadduhm(vbs, vus);
+// CHECK: add <8 x i16>
+// CHECK-LE: add <8 x i16>
+
+  res_vus = vec_vadduhm(vus, vbs);
+// CHECK: add <8 x i16>
+// CHECK-LE: add <8 x i16>
+
+  res_vi  = vec_vadduwm(vi, vi);
+// CHECK: add <4 x i32>
+// CHECK-LE: add <4 x i32>
+
+  res_vi  = vec_vadduwm(vbi, vi);
+// CHECK: add <4 x i32>
+// CHECK-LE: add <4 x i32>
+
+  res_vi  = vec_vadduwm(vi, vbi);
+// CHECK: add <4 x i32>
+// CHECK-LE: add <4 x i32>
+
+  res_vui = vec_vadduwm(vui, vui);
+// CHECK: add <4 x i32>
+// CHECK-LE: add <4 x i32>
+
+  res_vui = vec_vadduwm(vbi, vui);
+// CHECK: add <4 x i32>
+// CHECK-LE: add <4 x i32>
+
+  res_vui = vec_vadduwm(vui, vbi);
+// CHECK: add <4 x i32>
+// CHECK-LE: add <4 x i32>
+
+  res_vf  = vec_vaddfp(vf, vf);
+// CHECK: fadd <4 x float>
+// CHECK-LE: fadd <4 x float>
 
   /* vec_addc */
-  res_vui = vec_addc(vui, vui);                 // HECK: @llvm.ppc.altivec.vaddcuw
-  res_vui = vec_vaddcuw(vui, vui);              // HECK: @llvm.ppc.altivec.vaddcuw
+  res_vui = vec_addc(vui, vui);
+// CHECK: @llvm.ppc.altivec.vaddcuw
+// CHECK-LE: @llvm.ppc.altivec.vaddcuw
+
+  res_vui = vec_vaddcuw(vui, vui);
+// CHECK: @llvm.ppc.altivec.vaddcuw
+// CHECK-LE: @llvm.ppc.altivec.vaddcuw
 
   /* vec_adds */
-  res_vsc = vec_adds(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vaddsbs
-  res_vsc = vec_adds(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vaddsbs
-  res_vsc = vec_adds(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vaddsbs
-  res_vuc = vec_adds(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vaddubs
-  res_vuc = vec_adds(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vaddubs
-  res_vuc = vec_adds(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vaddubs
-  res_vs  = vec_adds(vs, vs);                   // CHECK: @llvm.ppc.altivec.vaddshs
-  res_vs  = vec_adds(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vaddshs
-  res_vs  = vec_adds(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vaddshs
-  res_vus = vec_adds(vus, vus);                 // CHECK: @llvm.ppc.altivec.vadduhs
-  res_vus = vec_adds(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vadduhs
-  res_vus = vec_adds(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vadduhs
-  res_vi  = vec_adds(vi, vi);                   // CHECK: @llvm.ppc.altivec.vaddsws
-  res_vi  = vec_adds(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vaddsws
-  res_vi  = vec_adds(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vaddsws
-  res_vui = vec_adds(vui, vui);                 // CHECK: @llvm.ppc.altivec.vadduws
-  res_vui = vec_adds(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vadduws
-  res_vui = vec_adds(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vadduws
-  res_vsc = vec_vaddsbs(vsc, vsc);              // CHECK: @llvm.ppc.altivec.vaddsbs
-  res_vsc = vec_vaddsbs(vbc, vsc);              // CHECK: @llvm.ppc.altivec.vaddsbs
-  res_vsc = vec_vaddsbs(vsc, vbc);              // CHECK: @llvm.ppc.altivec.vaddsbs
-  res_vuc = vec_vaddubs(vuc, vuc);              // CHECK: @llvm.ppc.altivec.vaddubs
-  res_vuc = vec_vaddubs(vbc, vuc);              // CHECK: @llvm.ppc.altivec.vaddubs
-  res_vuc = vec_vaddubs(vuc, vbc);              // CHECK: @llvm.ppc.altivec.vaddubs
-  res_vs  = vec_vaddshs(vs, vs);                // CHECK: @llvm.ppc.altivec.vaddshs
-  res_vs  = vec_vaddshs(vbs, vs);               // CHECK: @llvm.ppc.altivec.vaddshs
-  res_vs  = vec_vaddshs(vs, vbs);               // CHECK: @llvm.ppc.altivec.vaddshs
-  res_vus = vec_vadduhs(vus, vus);              // CHECK: @llvm.ppc.altivec.vadduhs
-  res_vus = vec_vadduhs(vbs, vus);              // CHECK: @llvm.ppc.altivec.vadduhs
-  res_vus = vec_vadduhs(vus, vbs);              // CHECK: @llvm.ppc.altivec.vadduhs
-  res_vi  = vec_vaddsws(vi, vi);                // CHECK: @llvm.ppc.altivec.vaddsws
-  res_vi  = vec_vaddsws(vbi, vi);               // CHECK: @llvm.ppc.altivec.vaddsws
-  res_vi  = vec_vaddsws(vi, vbi);               // CHECK: @llvm.ppc.altivec.vaddsws
-  res_vui = vec_vadduws(vui, vui);              // CHECK: @llvm.ppc.altivec.vadduws
-  res_vui = vec_vadduws(vbi, vui);              // CHECK: @llvm.ppc.altivec.vadduws
-  res_vui = vec_vadduws(vui, vbi);              // CHECK: @llvm.ppc.altivec.vadduws
+  res_vsc = vec_adds(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vaddsbs
+// CHECK-LE: @llvm.ppc.altivec.vaddsbs
+
+  res_vsc = vec_adds(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vaddsbs
+// CHECK-LE: @llvm.ppc.altivec.vaddsbs
+
+  res_vsc = vec_adds(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vaddsbs
+// CHECK-LE: @llvm.ppc.altivec.vaddsbs
+
+  res_vuc = vec_adds(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vaddubs
+// CHECK-LE: @llvm.ppc.altivec.vaddubs
+
+  res_vuc = vec_adds(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vaddubs
+// CHECK-LE: @llvm.ppc.altivec.vaddubs
+
+  res_vuc = vec_adds(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vaddubs
+// CHECK-LE: @llvm.ppc.altivec.vaddubs
+
+  res_vs  = vec_adds(vs, vs);
+// CHECK: @llvm.ppc.altivec.vaddshs
+// CHECK-LE: @llvm.ppc.altivec.vaddshs
+
+  res_vs  = vec_adds(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vaddshs
+// CHECK-LE: @llvm.ppc.altivec.vaddshs
+
+  res_vs  = vec_adds(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vaddshs
+// CHECK-LE: @llvm.ppc.altivec.vaddshs
+
+  res_vus = vec_adds(vus, vus);
+// CHECK: @llvm.ppc.altivec.vadduhs
+// CHECK-LE: @llvm.ppc.altivec.vadduhs
+
+  res_vus = vec_adds(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vadduhs
+// CHECK-LE: @llvm.ppc.altivec.vadduhs
+
+  res_vus = vec_adds(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vadduhs
+// CHECK-LE: @llvm.ppc.altivec.vadduhs
+
+  res_vi  = vec_adds(vi, vi);
+// CHECK: @llvm.ppc.altivec.vaddsws
+// CHECK-LE: @llvm.ppc.altivec.vaddsws
+
+  res_vi  = vec_adds(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vaddsws
+// CHECK-LE: @llvm.ppc.altivec.vaddsws
+
+  res_vi  = vec_adds(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vaddsws
+// CHECK-LE: @llvm.ppc.altivec.vaddsws
+
+  res_vui = vec_adds(vui, vui);
+// CHECK: @llvm.ppc.altivec.vadduws
+// CHECK-LE: @llvm.ppc.altivec.vadduws
+
+  res_vui = vec_adds(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vadduws
+// CHECK-LE: @llvm.ppc.altivec.vadduws
+
+  res_vui = vec_adds(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vadduws
+// CHECK-LE: @llvm.ppc.altivec.vadduws
+
+  res_vsc = vec_vaddsbs(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vaddsbs
+// CHECK-LE: @llvm.ppc.altivec.vaddsbs
+
+  res_vsc = vec_vaddsbs(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vaddsbs
+// CHECK-LE: @llvm.ppc.altivec.vaddsbs
+
+  res_vsc = vec_vaddsbs(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vaddsbs
+// CHECK-LE: @llvm.ppc.altivec.vaddsbs
+
+  res_vuc = vec_vaddubs(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vaddubs
+// CHECK-LE: @llvm.ppc.altivec.vaddubs
+
+  res_vuc = vec_vaddubs(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vaddubs
+// CHECK-LE: @llvm.ppc.altivec.vaddubs
+
+  res_vuc = vec_vaddubs(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vaddubs
+// CHECK-LE: @llvm.ppc.altivec.vaddubs
+
+  res_vs  = vec_vaddshs(vs, vs);
+// CHECK: @llvm.ppc.altivec.vaddshs
+// CHECK-LE: @llvm.ppc.altivec.vaddshs
+
+  res_vs  = vec_vaddshs(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vaddshs
+// CHECK-LE: @llvm.ppc.altivec.vaddshs
+
+  res_vs  = vec_vaddshs(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vaddshs
+// CHECK-LE: @llvm.ppc.altivec.vaddshs
+
+  res_vus = vec_vadduhs(vus, vus);
+// CHECK: @llvm.ppc.altivec.vadduhs
+// CHECK-LE: @llvm.ppc.altivec.vadduhs
+
+  res_vus = vec_vadduhs(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vadduhs
+// CHECK-LE: @llvm.ppc.altivec.vadduhs
+
+  res_vus = vec_vadduhs(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vadduhs
+// CHECK-LE: @llvm.ppc.altivec.vadduhs
+
+  res_vi  = vec_vaddsws(vi, vi);
+// CHECK: @llvm.ppc.altivec.vaddsws
+// CHECK-LE: @llvm.ppc.altivec.vaddsws
+
+  res_vi  = vec_vaddsws(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vaddsws
+// CHECK-LE: @llvm.ppc.altivec.vaddsws
+
+  res_vi  = vec_vaddsws(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vaddsws
+// CHECK-LE: @llvm.ppc.altivec.vaddsws
+
+  res_vui = vec_vadduws(vui, vui);
+// CHECK: @llvm.ppc.altivec.vadduws
+// CHECK-LE: @llvm.ppc.altivec.vadduws
+
+  res_vui = vec_vadduws(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vadduws
+// CHECK-LE: @llvm.ppc.altivec.vadduws
+
+  res_vui = vec_vadduws(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vadduws
+// CHECK-LE: @llvm.ppc.altivec.vadduws
 
   /* vec_and */
-  res_vsc = vec_and(vsc, vsc);                  // CHECK: and <16 x i8>
-  res_vsc = vec_and(vbc, vsc);                  // CHECK: and <16 x i8>
-  res_vsc = vec_and(vsc, vbc);                  // CHECK: and <16 x i8>
-  res_vuc = vec_and(vuc, vuc);                  // CHECK: and <16 x i8>
-  res_vuc = vec_and(vbc, vuc);                  // CHECK: and <16 x i8>
-  res_vuc = vec_and(vuc, vbc);                  // CHECK: and <16 x i8>
-  res_vbc = vec_and(vbc, vbc);                  // CHECK: and <16 x i8>
-  res_vs  = vec_and(vs, vs);                    // CHECK: and <8 x i16>
-  res_vs  = vec_and(vbs, vs);                   // CHECK: and <8 x i16>
-  res_vs  = vec_and(vs, vbs);                   // CHECK: and <8 x i16>
-  res_vus = vec_and(vus, vus);                  // CHECK: and <8 x i16>
-  res_vus = vec_and(vbs, vus);                  // CHECK: and <8 x i16>
-  res_vus = vec_and(vus, vbs);                  // CHECK: and <8 x i16>
-  res_vbs = vec_and(vbs, vbs);                  // CHECK: and <8 x i16>
-  res_vi  = vec_and(vi, vi);                    // CHECK: and <4 x i32>
-  res_vi  = vec_and(vbi, vi);                   // CHECK: and <4 x i32>
-  res_vi  = vec_and(vi, vbi);                   // CHECK: and <4 x i32>
-  res_vui = vec_and(vui, vui);                  // CHECK: and <4 x i32>
-  res_vui = vec_and(vbi, vui);                  // CHECK: and <4 x i32>
-  res_vui = vec_and(vui, vbi);                  // CHECK: and <4 x i32>
-  res_vbi = vec_and(vbi, vbi);                  // CHECK: and <4 x i32>
-  res_vsc = vec_vand(vsc, vsc);                 // CHECK: and <16 x i8>
-  res_vsc = vec_vand(vbc, vsc);                 // CHECK: and <16 x i8>
-  res_vsc = vec_vand(vsc, vbc);                 // CHECK: and <16 x i8>
-  res_vuc = vec_vand(vuc, vuc);                 // CHECK: and <16 x i8>
-  res_vuc = vec_vand(vbc, vuc);                 // CHECK: and <16 x i8>
-  res_vuc = vec_vand(vuc, vbc);                 // CHECK: and <16 x i8>
-  res_vbc = vec_vand(vbc, vbc);                 // CHECK: and <16 x i8>
-  res_vs  = vec_vand(vs, vs);                   // CHECK: and <8 x i16>
-  res_vs  = vec_vand(vbs, vs);                  // CHECK: and <8 x i16>
-  res_vs  = vec_vand(vs, vbs);                  // CHECK: and <8 x i16>
-  res_vus = vec_vand(vus, vus);                 // CHECK: and <8 x i16>
-  res_vus = vec_vand(vbs, vus);                 // CHECK: and <8 x i16>
-  res_vus = vec_vand(vus, vbs);                 // CHECK: and <8 x i16>
-  res_vbs = vec_vand(vbs, vbs);                 // CHECK: and <8 x i16>
-  res_vi  = vec_vand(vi, vi);                   // CHECK: and <4 x i32>
-  res_vi  = vec_vand(vbi, vi);                  // CHECK: and <4 x i32>
-  res_vi  = vec_vand(vi, vbi);                  // CHECK: and <4 x i32>
-  res_vui = vec_vand(vui, vui);                 // CHECK: and <4 x i32>
-  res_vui = vec_vand(vbi, vui);                 // CHECK: and <4 x i32>
-  res_vui = vec_vand(vui, vbi);                 // CHECK: and <4 x i32>
-  res_vbi = vec_vand(vbi, vbi);                 // CHECK: and <4 x i32>
+  res_vsc = vec_and(vsc, vsc);
+// CHECK: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+
+  res_vsc = vec_and(vbc, vsc);
+// CHECK: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+
+  res_vsc = vec_and(vsc, vbc);
+// CHECK: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+
+  res_vuc = vec_and(vuc, vuc);
+// CHECK: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+
+  res_vuc = vec_and(vbc, vuc);
+// CHECK: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+
+  res_vuc = vec_and(vuc, vbc);
+// CHECK: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+
+  res_vbc = vec_and(vbc, vbc);
+// CHECK: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+
+  res_vs  = vec_and(vs, vs);
+// CHECK: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+
+  res_vs  = vec_and(vbs, vs);
+// CHECK: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+
+  res_vs  = vec_and(vs, vbs);
+// CHECK: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+
+  res_vus = vec_and(vus, vus);
+// CHECK: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+
+  res_vus = vec_and(vbs, vus);
+// CHECK: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+
+  res_vus = vec_and(vus, vbs);
+// CHECK: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+
+  res_vbs = vec_and(vbs, vbs);
+// CHECK: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+
+  res_vi  = vec_and(vi, vi);
+// CHECK: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+
+  res_vi  = vec_and(vbi, vi);
+// CHECK: and <4 x i32>
+// CHECK-le: and <4 x i32>
+
+  res_vi  = vec_and(vi, vbi);
+// CHECK: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+
+  res_vui = vec_and(vui, vui);
+// CHECK: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+
+  res_vui = vec_and(vbi, vui);
+// CHECK: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+
+  res_vui = vec_and(vui, vbi);
+// CHECK: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+
+  res_vbi = vec_and(vbi, vbi);
+// CHECK: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+
+  res_vsc = vec_vand(vsc, vsc);
+// CHECK: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+
+  res_vsc = vec_vand(vbc, vsc);
+// CHECK: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+
+  res_vsc = vec_vand(vsc, vbc);
+// CHECK: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+
+  res_vuc = vec_vand(vuc, vuc);
+// CHECK: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+
+  res_vuc = vec_vand(vbc, vuc);
+// CHECK: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+
+  res_vuc = vec_vand(vuc, vbc);
+// CHECK: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+
+  res_vbc = vec_vand(vbc, vbc);
+// CHECK: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+
+  res_vs  = vec_vand(vs, vs);
+// CHECK: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+
+  res_vs  = vec_vand(vbs, vs);
+// CHECK: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+
+  res_vs  = vec_vand(vs, vbs);
+// CHECK: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+
+  res_vus = vec_vand(vus, vus);
+// CHECK: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+
+  res_vus = vec_vand(vbs, vus);
+// CHECK: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+
+  res_vus = vec_vand(vus, vbs);
+// CHECK: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+
+  res_vbs = vec_vand(vbs, vbs);
+// CHECK: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+
+  res_vi  = vec_vand(vi, vi);
+// CHECK: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+
+  res_vi  = vec_vand(vbi, vi);
+// CHECK: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+
+  res_vi  = vec_vand(vi, vbi);
+// CHECK: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+
+  res_vui = vec_vand(vui, vui);
+// CHECK: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+
+  res_vui = vec_vand(vbi, vui);
+// CHECK: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+
+  res_vui = vec_vand(vui, vbi);
+// CHECK: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+
+  res_vbi = vec_vand(vbi, vbi);
+// CHECK: and <4 x i32>
+// CHECK-LE: and <4 x i32>
 
   /* vec_andc */
-  res_vsc = vec_andc(vsc, vsc);                 // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
+  res_vsc = vec_andc(vsc, vsc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
 
-  res_vsc = vec_andc(vbc, vsc);                 // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
+  res_vsc = vec_andc(vbc, vsc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
 
-  res_vsc = vec_andc(vsc, vbc);                 // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
+  res_vsc = vec_andc(vsc, vbc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
 
-  res_vuc = vec_andc(vuc, vuc);                 // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
+  res_vuc = vec_andc(vuc, vuc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
 
-  res_vuc = vec_andc(vbc, vuc);                 // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
+  res_vuc = vec_andc(vbc, vuc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
 
-  res_vuc = vec_andc(vuc, vbc);                 // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
+  res_vuc = vec_andc(vuc, vbc);
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
 
-  res_vbc = vec_andc(vbc, vbc);                 // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
+  res_vbc = vec_andc(vbc, vbc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
 
-  res_vs  = vec_andc(vs, vs);                   // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
+  res_vs  = vec_andc(vs, vs);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
 
-  res_vs  = vec_andc(vbs, vs);                  // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
+  res_vs  = vec_andc(vbs, vs);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
 
-  res_vs  = vec_andc(vs, vbs);                  // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
+  res_vs  = vec_andc(vs, vbs);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
 
-  res_vus = vec_andc(vus, vus);                 // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
+  res_vus = vec_andc(vus, vus);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
 
-  res_vus = vec_andc(vbs, vus);                 // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
+  res_vus = vec_andc(vbs, vus);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
 
-  res_vus = vec_andc(vus, vbs);                 // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
+  res_vus = vec_andc(vus, vbs);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
 
-  res_vbs = vec_andc(vbs, vbs);                 // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
+  res_vbs = vec_andc(vbs, vbs);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
 
-  res_vi  = vec_andc(vi, vi);                   // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
+  res_vi  = vec_andc(vi, vi);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
 
-  res_vi  = vec_andc(vbi, vi);                  // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
+  res_vi  = vec_andc(vbi, vi);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
 
-  res_vi  = vec_andc(vi, vbi);                  // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
+  res_vi  = vec_andc(vi, vbi);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
 
-  res_vui = vec_andc(vui, vui);                 // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
+  res_vui = vec_andc(vui, vui);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
 
-  res_vui = vec_andc(vbi, vui);                 // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
+  res_vui = vec_andc(vbi, vui);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
 
-  res_vui = vec_andc(vui, vbi);                 // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
+  res_vui = vec_andc(vui, vbi);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
 
-  res_vf = vec_andc(vf, vf);                    // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
+  res_vf = vec_andc(vf, vf);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
 
-  res_vf = vec_andc(vbi, vf);                   // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
+  res_vf = vec_andc(vbi, vf);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
 
-  res_vf = vec_andc(vf, vbi);                   // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
+  res_vf = vec_andc(vf, vbi);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
 
-  res_vsc = vec_vandc(vsc, vsc);                // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
+  res_vsc = vec_vandc(vsc, vsc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
 
-  res_vsc = vec_vandc(vbc, vsc);                // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
+  res_vsc = vec_vandc(vbc, vsc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
 
-  res_vsc = vec_vandc(vsc, vbc);                // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
+  res_vsc = vec_vandc(vsc, vbc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
 
-  res_vuc = vec_vandc(vuc, vuc);                // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
+  res_vuc = vec_vandc(vuc, vuc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
 
-  res_vuc = vec_vandc(vbc, vuc);                // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
+  res_vuc = vec_vandc(vbc, vuc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
 
-  res_vuc = vec_vandc(vuc, vbc);                // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
+  res_vuc = vec_vandc(vuc, vbc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
 
-  res_vbc = vec_vandc(vbc, vbc);                // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
+  res_vbc = vec_vandc(vbc, vbc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
 
-  res_vs  = vec_vandc(vs, vs);                  // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
+  res_vs  = vec_vandc(vs, vs);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
 
-  res_vs  = vec_vandc(vbs, vs);                 // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
+  res_vs  = vec_vandc(vbs, vs);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
 
-  res_vs  = vec_vandc(vs, vbs);                 // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
+  res_vs  = vec_vandc(vs, vbs);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
 
-  res_vus = vec_vandc(vus, vus);                // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
+  res_vus = vec_vandc(vus, vus);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
 
-  res_vus = vec_vandc(vbs, vus);                // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
+  res_vus = vec_vandc(vbs, vus);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
 
-  res_vus = vec_vandc(vus, vbs);                // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
+  res_vus = vec_vandc(vus, vbs);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
 
-  res_vbs = vec_vandc(vbs, vbs);                // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
+  res_vbs = vec_vandc(vbs, vbs);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
 
-  res_vi  = vec_vandc(vi, vi);                  // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
+  res_vi  = vec_vandc(vi, vi);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
 
-  res_vi  = vec_vandc(vbi, vi);                 // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
+  res_vi  = vec_vandc(vbi, vi);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
 
-  res_vi  = vec_vandc(vi, vbi);                 // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
+  res_vi  = vec_vandc(vi, vbi);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
 
-  res_vui = vec_vandc(vui, vui);                // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
+  res_vui = vec_vandc(vui, vui);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
 
-  res_vui = vec_vandc(vbi, vui);                // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
+  res_vui = vec_vandc(vbi, vui);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
 
-  res_vui = vec_vandc(vui, vbi);                // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
+  res_vui = vec_vandc(vui, vbi);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
 
-  res_vf = vec_vandc(vf, vf);                   // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
+  res_vf = vec_vandc(vf, vf);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
 
-  res_vf = vec_vandc(vbi, vf);                  // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
+  res_vf = vec_vandc(vbi, vf);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
 
-  res_vf = vec_vandc(vf, vbi);                  // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
+  res_vf = vec_vandc(vf, vbi);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
 
 }
 
 // CHECK-LABEL: define void @test2
 void test2() {
   /* vec_avg */
-  res_vsc = vec_avg(vsc, vsc);                  // CHECK: @llvm.ppc.altivec.vavgsb
-  res_vuc = vec_avg(vuc, vuc);                  // CHECK: @llvm.ppc.altivec.vavgub
-  res_vs  = vec_avg(vs, vs);                    // CHECK: @llvm.ppc.altivec.vavgsh
-  res_vus = vec_avg(vus, vus);                  // CHECK: @llvm.ppc.altivec.vavguh
-  res_vi  = vec_avg(vi, vi);                    // CHECK: @llvm.ppc.altivec.vavgsw
-  res_vui = vec_avg(vui, vui);                  // CHECK: @llvm.ppc.altivec.vavguw
-  res_vsc = vec_vavgsb(vsc, vsc);               // CHECK: @llvm.ppc.altivec.vavgsb
-  res_vuc = vec_vavgub(vuc, vuc);               // CHECK: @llvm.ppc.altivec.vavgub
-  res_vs  = vec_vavgsh(vs, vs);                 // CHECK: @llvm.ppc.altivec.vavgsh
-  res_vus = vec_vavguh(vus, vus);               // CHECK: @llvm.ppc.altivec.vavguh
-  res_vi  = vec_vavgsw(vi, vi);                 // CHECK: @llvm.ppc.altivec.vavgsw
-  res_vui = vec_vavguw(vui, vui);               // CHECK: @llvm.ppc.altivec.vavguw
+  res_vsc = vec_avg(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vavgsb
+// CHECK-LE: @llvm.ppc.altivec.vavgsb
+
+  res_vuc = vec_avg(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vavgub
+// CHECK-LE: @llvm.ppc.altivec.vavgub
+
+  res_vs  = vec_avg(vs, vs);
+// CHECK: @llvm.ppc.altivec.vavgsh
+// CHECK-LE: @llvm.ppc.altivec.vavgsh
+
+  res_vus = vec_avg(vus, vus);
+// CHECK: @llvm.ppc.altivec.vavguh
+// CHECK-LE: @llvm.ppc.altivec.vavguh
+
+  res_vi  = vec_avg(vi, vi);
+// CHECK: @llvm.ppc.altivec.vavgsw
+// CHECK-LE: @llvm.ppc.altivec.vavgsw
+
+  res_vui = vec_avg(vui, vui);
+// CHECK: @llvm.ppc.altivec.vavguw
+// CHECK-LE: @llvm.ppc.altivec.vavguw
+
+  res_vsc = vec_vavgsb(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vavgsb
+// CHECK-LE: @llvm.ppc.altivec.vavgsb
+
+  res_vuc = vec_vavgub(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vavgub
+// CHECK-LE: @llvm.ppc.altivec.vavgub
+
+  res_vs  = vec_vavgsh(vs, vs);
+// CHECK: @llvm.ppc.altivec.vavgsh
+// CHECK-LE: @llvm.ppc.altivec.vavgsh
+
+  res_vus = vec_vavguh(vus, vus);
+// CHECK: @llvm.ppc.altivec.vavguh
+// CHECK-LE: @llvm.ppc.altivec.vavguh
+
+  res_vi  = vec_vavgsw(vi, vi);
+// CHECK: @llvm.ppc.altivec.vavgsw
+// CHECK-LE: @llvm.ppc.altivec.vavgsw
+
+  res_vui = vec_vavguw(vui, vui);
+// CHECK: @llvm.ppc.altivec.vavguw
+// CHECK-LE: @llvm.ppc.altivec.vavguw
 
   /* vec_ceil */
-  res_vf = vec_ceil(vf);                        // CHECK: @llvm.ppc.altivec.vrfip
-  res_vf = vec_vrfip(vf);                       // CHECK: @llvm.ppc.altivec.vrfip
+  res_vf = vec_ceil(vf);
+// CHECK: @llvm.ppc.altivec.vrfip
+// CHECK-LE: @llvm.ppc.altivec.vrfip
+
+  res_vf = vec_vrfip(vf);
+// CHECK: @llvm.ppc.altivec.vrfip
+// CHECK-LE: @llvm.ppc.altivec.vrfip
 
   /* vec_cmpb */
-  res_vi = vec_cmpb(vf, vf);                    // CHECK: @llvm.ppc.altivec.vcmpbfp
-  res_vi = vec_vcmpbfp(vf, vf);                 // CHECK: @llvm.ppc.altivec.vcmpbfp
+  res_vi = vec_cmpb(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpbfp
+// CHECK-LE: @llvm.ppc.altivec.vcmpbfp
+
+  res_vi = vec_vcmpbfp(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpbfp
+// CHECK-LE: @llvm.ppc.altivec.vcmpbfp
 
   /* vec_cmpeq */
-  res_vbc = vec_cmpeq(vsc, vsc);                // CHECK: @llvm.ppc.altivec.vcmpequb
-  res_vbc = vec_cmpeq(vuc, vuc);                // CHECK: @llvm.ppc.altivec.vcmpequb
-  res_vbs = vec_cmpeq(vs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpequh
-  res_vbs = vec_cmpeq(vus, vus);                // CHECK: @llvm.ppc.altivec.vcmpequh
-  res_vbi = vec_cmpeq(vi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpequw
-  res_vbi = vec_cmpeq(vui, vui);                // CHECK: @llvm.ppc.altivec.vcmpequw
-  res_vbi = vec_cmpeq(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpeqfp
+  res_vbc = vec_cmpeq(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpequb
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb
+
+  res_vbc = vec_cmpeq(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpequb
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb
+
+  res_vbs = vec_cmpeq(vs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpequh
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh
+
+  res_vbs = vec_cmpeq(vus, vus);
+// CHECK: @llvm.ppc.altivec.vcmpequh
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh
+
+  res_vbi = vec_cmpeq(vi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpequw
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw
+
+  res_vbi = vec_cmpeq(vui, vui);
+// CHECK: @llvm.ppc.altivec.vcmpequw
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw
+
+  res_vbi = vec_cmpeq(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpeqfp
+// CHECK-LE: @llvm.ppc.altivec.vcmpeqfp
 
   /* vec_cmpge */
-  res_vbi = vec_cmpge(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpgefp
-  res_vbi = vec_vcmpgefp(vf, vf);               // CHECK: @llvm.ppc.altivec.vcmpgefp
+  res_vbi = vec_cmpge(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgefp
+// CHECK-LE: @llvm.ppc.altivec.vcmpgefp
+
+  res_vbi = vec_vcmpgefp(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgefp
+// CHECK-LE: @llvm.ppc.altivec.vcmpgefp
 }
 
 // CHECK-LABEL: define void @test5
 void test5() {
-  
+
   /* vec_cmpgt */
-  res_vbc = vec_cmpgt(vsc, vsc);                // CHECK: @llvm.ppc.altivec.vcmpgtsb
-  res_vbc = vec_cmpgt(vuc, vuc);                // CHECK: @llvm.ppc.altivec.vcmpgtub
-  res_vbs = vec_cmpgt(vs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpgtsh
-  res_vbs = vec_cmpgt(vus, vus);                // CHECK: @llvm.ppc.altivec.vcmpgtuh
-  res_vbi = vec_cmpgt(vi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpgtsw
-  res_vbi = vec_cmpgt(vui, vui);                // CHECK: @llvm.ppc.altivec.vcmpgtuw
-  res_vbi = vec_cmpgt(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpgtfp
-  res_vbc = vec_vcmpgtsb(vsc, vsc);             // CHECK: @llvm.ppc.altivec.vcmpgtsb
-  res_vbc = vec_vcmpgtub(vuc, vuc);             // CHECK: @llvm.ppc.altivec.vcmpgtub
-  res_vbs = vec_vcmpgtsh(vs, vs);               // CHECK: @llvm.ppc.altivec.vcmpgtsh
-  res_vbs = vec_vcmpgtuh(vus, vus);             // CHECK: @llvm.ppc.altivec.vcmpgtuh
-  res_vbi = vec_vcmpgtsw(vi, vi);               // CHECK: @llvm.ppc.altivec.vcmpgtsw
-  res_vbi = vec_vcmpgtuw(vui, vui);             // CHECK: @llvm.ppc.altivec.vcmpgtuw
-  res_vbi = vec_vcmpgtfp(vf, vf);               // CHECK: @llvm.ppc.altivec.vcmpgtfp
+  res_vbc = vec_cmpgt(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb
+
+  res_vbc = vec_cmpgt(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub
+
+  res_vbs = vec_cmpgt(vs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh
+
+  res_vbs = vec_cmpgt(vus, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh
+
+  res_vbi = vec_cmpgt(vi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw
+
+  res_vbi = vec_cmpgt(vui, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw
+
+  res_vbi = vec_cmpgt(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgtfp
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtfp
+
+  res_vbc = vec_vcmpgtsb(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb
+
+  res_vbc = vec_vcmpgtub(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub
+
+  res_vbs = vec_vcmpgtsh(vs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh
+
+  res_vbs = vec_vcmpgtuh(vus, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh
+
+  res_vbi = vec_vcmpgtsw(vi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw
+
+  res_vbi = vec_vcmpgtuw(vui, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw
+
+  res_vbi = vec_vcmpgtfp(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgtfp
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtfp
 
   /* vec_cmple */
-  res_vbi = vec_cmple(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpgefp
+  res_vbi = vec_cmple(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgefp
+// CHECK-LE: @llvm.ppc.altivec.vcmpgefp
 }
 
 // CHECK-LABEL: define void @test6
 void test6() {
   /* vec_cmplt */
-  res_vbc = vec_cmplt(vsc, vsc);                // CHECK: @llvm.ppc.altivec.vcmpgtsb
-  res_vbc = vec_cmplt(vuc, vuc);                // CHECK: @llvm.ppc.altivec.vcmpgtub
-  res_vbs = vec_cmplt(vs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpgtsh
-  res_vbs = vec_cmplt(vus, vus);                // CHECK: @llvm.ppc.altivec.vcmpgtuh
-  res_vbi = vec_cmplt(vi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpgtsw
-  res_vbi = vec_cmplt(vui, vui);                // CHECK: @llvm.ppc.altivec.vcmpgtuw
-  res_vbi = vec_cmplt(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpgtfp
+  res_vbc = vec_cmplt(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb
+
+  res_vbc = vec_cmplt(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub
+
+  res_vbs = vec_cmplt(vs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh
+
+  res_vbs = vec_cmplt(vus, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh
+
+  res_vbi = vec_cmplt(vi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw
+
+  res_vbi = vec_cmplt(vui, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw
+
+  res_vbi = vec_cmplt(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgtfp
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtfp
 
   /* vec_ctf */
-  res_vf  = vec_ctf(vi, param_i);               // CHECK: @llvm.ppc.altivec.vcfsx
-  res_vf  = vec_ctf(vui, 0);                    // CHECK: @llvm.ppc.altivec.vcfux
-  res_vf  = vec_vcfsx(vi, 0);                   // CHECK: @llvm.ppc.altivec.vcfsx
-  res_vf  = vec_vcfux(vui, 0);                  // CHECK: @llvm.ppc.altivec.vcfux
+  res_vf  = vec_ctf(vi, param_i);
+// CHECK: @llvm.ppc.altivec.vcfsx
+// CHECK-LE: @llvm.ppc.altivec.vcfsx
+
+  res_vf  = vec_ctf(vui, 0);
+// CHECK: @llvm.ppc.altivec.vcfux
+// CHECK-LE: @llvm.ppc.altivec.vcfux
+
+  res_vf  = vec_vcfsx(vi, 0);
+// CHECK: @llvm.ppc.altivec.vcfsx
+// CHECK-LE: @llvm.ppc.altivec.vcfsx
+
+  res_vf  = vec_vcfux(vui, 0);
+// CHECK: @llvm.ppc.altivec.vcfux
+// CHECK-LE: @llvm.ppc.altivec.vcfux
 
   /* vec_cts */
-  res_vi = vec_cts(vf, 0);                      // CHECK: @llvm.ppc.altivec.vctsxs
-  res_vi = vec_vctsxs(vf, 0);                   // CHECK: @llvm.ppc.altivec.vctsxs
+  res_vi = vec_cts(vf, 0);
+// CHECK: @llvm.ppc.altivec.vctsxs
+// CHECK-LE: @llvm.ppc.altivec.vctsxs
+
+  res_vi = vec_vctsxs(vf, 0);
+// CHECK: @llvm.ppc.altivec.vctsxs
+// CHECK-LE: @llvm.ppc.altivec.vctsxs
 
   /* vec_ctu */
-  res_vui = vec_ctu(vf, 0);                     // CHECK: @llvm.ppc.altivec.vctuxs
-  res_vui = vec_vctuxs(vf, 0);                  // CHECK: @llvm.ppc.altivec.vctuxs
+  res_vui = vec_ctu(vf, 0);
+// CHECK: @llvm.ppc.altivec.vctuxs
+// CHECK-LE: @llvm.ppc.altivec.vctuxs
+
+  res_vui = vec_vctuxs(vf, 0);
+// CHECK: @llvm.ppc.altivec.vctuxs
+// CHECK-LE: @llvm.ppc.altivec.vctuxs
 
   /* vec_dss */
-  vec_dss(param_i);                             // CHECK: @llvm.ppc.altivec.dss
+  vec_dss(param_i);
+// CHECK: @llvm.ppc.altivec.dss
+// CHECK-LE: @llvm.ppc.altivec.dss
 
   /* vec_dssall */
-  vec_dssall();                                 // CHECK: @llvm.ppc.altivec.dssall
+  vec_dssall();
+// CHECK: @llvm.ppc.altivec.dssall
+// CHECK-LE: @llvm.ppc.altivec.dssall
 
   /* vec_dst */
-  vec_dst(&vsc, 0, 0);                          // CHECK: @llvm.ppc.altivec.dst
+  vec_dst(&vsc, 0, 0);
+// CHECK: @llvm.ppc.altivec.dst
+// CHECK-LE: @llvm.ppc.altivec.dst
 
   /* vec_dstst */
-  vec_dstst(&vs, 0, 0);                         // CHECK: @llvm.ppc.altivec.dstst
+  vec_dstst(&vs, 0, 0);
+// CHECK: @llvm.ppc.altivec.dstst
+// CHECK-LE: @llvm.ppc.altivec.dstst
 
   /* vec_dststt */
-  vec_dststt(&param_i, 0, 0);                   // CHECK: @llvm.ppc.altivec.dststt
+  vec_dststt(&param_i, 0, 0);
+// CHECK: @llvm.ppc.altivec.dststt
+// CHECK-LE: @llvm.ppc.altivec.dststt
 
   /* vec_dstt */
-  vec_dstt(&vf, 0, 0);                          // CHECK: @llvm.ppc.altivec.dstt
+  vec_dstt(&vf, 0, 0);
+// CHECK: @llvm.ppc.altivec.dstt
+// CHECK-LE: @llvm.ppc.altivec.dstt
 
   /* vec_expte */
-  res_vf = vec_expte(vf);                       // CHECK: @llvm.ppc.altivec.vexptefp
-  res_vf = vec_vexptefp(vf);                    // CHECK: @llvm.ppc.altivec.vexptefp
+  res_vf = vec_expte(vf);
+// CHECK: @llvm.ppc.altivec.vexptefp
+// CHECK-LE: @llvm.ppc.altivec.vexptefp
+
+  res_vf = vec_vexptefp(vf);
+// CHECK: @llvm.ppc.altivec.vexptefp
+// CHECK-LE: @llvm.ppc.altivec.vexptefp
 
   /* vec_floor */
-  res_vf = vec_floor(vf);                       // CHECK: @llvm.ppc.altivec.vrfim
-  res_vf = vec_vrfim(vf);                       // CHECK: @llvm.ppc.altivec.vrfim
+  res_vf = vec_floor(vf);
+// CHECK: @llvm.ppc.altivec.vrfim
+// CHECK-LE: @llvm.ppc.altivec.vrfim
+
+  res_vf = vec_vrfim(vf);
+// CHECK: @llvm.ppc.altivec.vrfim
+// CHECK-LE: @llvm.ppc.altivec.vrfim
 
   /* vec_ld */
-  res_vsc = vec_ld(0, &vsc);                    // CHECK: @llvm.ppc.altivec.lvx
-  res_vsc = vec_ld(0, &param_sc);               // CHECK: @llvm.ppc.altivec.lvx
-  res_vuc = vec_ld(0, &vuc);                    // CHECK: @llvm.ppc.altivec.lvx
-  res_vuc = vec_ld(0, &param_uc);               // CHECK: @llvm.ppc.altivec.lvx
-  res_vbc = vec_ld(0, &vbc);                    // CHECK: @llvm.ppc.altivec.lvx
-  res_vs  = vec_ld(0, &vs);                     // CHECK: @llvm.ppc.altivec.lvx
-  res_vs  = vec_ld(0, &param_s);                // CHECK: @llvm.ppc.altivec.lvx
-  res_vus = vec_ld(0, &vus);                    // CHECK: @llvm.ppc.altivec.lvx
-  res_vus = vec_ld(0, &param_us);               // CHECK: @llvm.ppc.altivec.lvx
-  res_vbs = vec_ld(0, &vbs);                    // CHECK: @llvm.ppc.altivec.lvx
-  res_vp  = vec_ld(0, &vp);                     // CHECK: @llvm.ppc.altivec.lvx
-  res_vi  = vec_ld(0, &vi);                     // CHECK: @llvm.ppc.altivec.lvx
-  res_vi  = vec_ld(0, &param_i);                // CHECK: @llvm.ppc.altivec.lvx
-  res_vui = vec_ld(0, &vui);                    // CHECK: @llvm.ppc.altivec.lvx
-  res_vui = vec_ld(0, &param_ui);               // CHECK: @llvm.ppc.altivec.lvx
-  res_vbi = vec_ld(0, &vbi);                    // CHECK: @llvm.ppc.altivec.lvx
-  res_vf  = vec_ld(0, &vf);                     // CHECK: @llvm.ppc.altivec.lvx
-  res_vf  = vec_ld(0, &param_f);                // CHECK: @llvm.ppc.altivec.lvx
-  res_vsc = vec_lvx(0, &vsc);                   // CHECK: @llvm.ppc.altivec.lvx
-  res_vsc = vec_lvx(0, &param_sc);              // CHECK: @llvm.ppc.altivec.lvx
-  res_vuc = vec_lvx(0, &vuc);                   // CHECK: @llvm.ppc.altivec.lvx
-  res_vuc = vec_lvx(0, &param_uc);              // CHECK: @llvm.ppc.altivec.lvx
-  res_vbc = vec_lvx(0, &vbc);                   // CHECK: @llvm.ppc.altivec.lvx
-  res_vs  = vec_lvx(0, &vs);                    // CHECK: @llvm.ppc.altivec.lvx
-  res_vs  = vec_lvx(0, &param_s);               // CHECK: @llvm.ppc.altivec.lvx
-  res_vus = vec_lvx(0, &vus);                   // CHECK: @llvm.ppc.altivec.lvx
-  res_vus = vec_lvx(0, &param_us);              // CHECK: @llvm.ppc.altivec.lvx
-  res_vbs = vec_lvx(0, &vbs);                   // CHECK: @llvm.ppc.altivec.lvx
-  res_vp  = vec_lvx(0, &vp);                    // CHECK: @llvm.ppc.altivec.lvx
-  res_vi  = vec_lvx(0, &vi);                    // CHECK: @llvm.ppc.altivec.lvx
-  res_vi  = vec_lvx(0, &param_i);               // CHECK: @llvm.ppc.altivec.lvx
-  res_vui = vec_lvx(0, &vui);                   // CHECK: @llvm.ppc.altivec.lvx
-  res_vui = vec_lvx(0, &param_ui);              // CHECK: @llvm.ppc.altivec.lvx
-  res_vbi = vec_lvx(0, &vbi);                   // CHECK: @llvm.ppc.altivec.lvx
-  res_vf  = vec_lvx(0, &vf);                    // CHECK: @llvm.ppc.altivec.lvx
-  res_vf  = vec_lvx(0, &param_f);               // CHECK: @llvm.ppc.altivec.lvx
+  res_vsc = vec_ld(0, &vsc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vsc = vec_ld(0, &param_sc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vuc = vec_ld(0, &vuc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vuc = vec_ld(0, &param_uc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vbc = vec_ld(0, &vbc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vs  = vec_ld(0, &vs);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vs  = vec_ld(0, &param_s);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vus = vec_ld(0, &vus);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vus = vec_ld(0, &param_us);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vbs = vec_ld(0, &vbs);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vp  = vec_ld(0, &vp);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vi  = vec_ld(0, &vi);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vi  = vec_ld(0, &param_i);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vui = vec_ld(0, &vui);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vui = vec_ld(0, &param_ui);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vbi = vec_ld(0, &vbi);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vf  = vec_ld(0, &vf);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vf  = vec_ld(0, &param_f);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vsc = vec_lvx(0, &vsc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vsc = vec_lvx(0, &param_sc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vuc = vec_lvx(0, &vuc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vuc = vec_lvx(0, &param_uc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vbc = vec_lvx(0, &vbc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vs  = vec_lvx(0, &vs);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vs  = vec_lvx(0, &param_s);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vus = vec_lvx(0, &vus);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vus = vec_lvx(0, &param_us);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vbs = vec_lvx(0, &vbs);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vp  = vec_lvx(0, &vp);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vi  = vec_lvx(0, &vi);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vi  = vec_lvx(0, &param_i);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vui = vec_lvx(0, &vui);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vui = vec_lvx(0, &param_ui);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vbi = vec_lvx(0, &vbi);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vf  = vec_lvx(0, &vf);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+
+  res_vf  = vec_lvx(0, &param_f);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
 
   /* vec_lde */
-  res_vsc = vec_lde(0, &param_sc);              // CHECK: @llvm.ppc.altivec.lvebx
-  res_vuc = vec_lde(0, &param_uc);              // CHECK: @llvm.ppc.altivec.lvebx
-  res_vs  = vec_lde(0, &param_s);               // CHECK: @llvm.ppc.altivec.lvehx
-  res_vus = vec_lde(0, &param_us);              // CHECK: @llvm.ppc.altivec.lvehx
-  res_vi  = vec_lde(0, &param_i);               // CHECK: @llvm.ppc.altivec.lvewx
-  res_vui = vec_lde(0, &param_ui);              // CHECK: @llvm.ppc.altivec.lvewx
-  res_vf  = vec_lde(0, &param_f);               // CHECK: @llvm.ppc.altivec.lvewx
-  res_vsc = vec_lvebx(0, &param_sc);            // CHECK: @llvm.ppc.altivec.lvebx
-  res_vuc = vec_lvebx(0, &param_uc);            // CHECK: @llvm.ppc.altivec.lvebx
-  res_vs  = vec_lvehx(0, &param_s);             // CHECK: @llvm.ppc.altivec.lvehx
-  res_vus = vec_lvehx(0, &param_us);            // CHECK: @llvm.ppc.altivec.lvehx
-  res_vi  = vec_lvewx(0, &param_i);             // CHECK: @llvm.ppc.altivec.lvewx
-  res_vui = vec_lvewx(0, &param_ui);            // CHECK: @llvm.ppc.altivec.lvewx
-  res_vf  = vec_lvewx(0, &param_f);             // CHECK: @llvm.ppc.altivec.lvewx
+  res_vsc = vec_lde(0, &param_sc);
+// CHECK: @llvm.ppc.altivec.lvebx
+// CHECK-LE: @llvm.ppc.altivec.lvebx
+
+  res_vuc = vec_lde(0, &param_uc);
+// CHECK: @llvm.ppc.altivec.lvebx
+// CHECK-LE: @llvm.ppc.altivec.lvebx
+
+  res_vs  = vec_lde(0, &param_s);
+// CHECK: @llvm.ppc.altivec.lvehx
+// CHECK-LE: @llvm.ppc.altivec.lvehx
+
+  res_vus = vec_lde(0, &param_us);
+// CHECK: @llvm.ppc.altivec.lvehx
+// CHECK-LE: @llvm.ppc.altivec.lvehx
+
+  res_vi  = vec_lde(0, &param_i);
+// CHECK: @llvm.ppc.altivec.lvewx
+// CHECK-LE: @llvm.ppc.altivec.lvewx
+
+  res_vui = vec_lde(0, &param_ui);
+// CHECK: @llvm.ppc.altivec.lvewx
+// CHECK-LE: @llvm.ppc.altivec.lvewx
+
+  res_vf  = vec_lde(0, &param_f);
+// CHECK: @llvm.ppc.altivec.lvewx
+// CHECK-LE: @llvm.ppc.altivec.lvewx
+
+  res_vsc = vec_lvebx(0, &param_sc);
+// CHECK: @llvm.ppc.altivec.lvebx
+// CHECK-LE: @llvm.ppc.altivec.lvebx
+
+  res_vuc = vec_lvebx(0, &param_uc);
+// CHECK: @llvm.ppc.altivec.lvebx
+// CHECK-LE: @llvm.ppc.altivec.lvebx
+
+  res_vs  = vec_lvehx(0, &param_s);
+// CHECK: @llvm.ppc.altivec.lvehx
+// CHECK-LE: @llvm.ppc.altivec.lvehx
+
+  res_vus = vec_lvehx(0, &param_us);
+// CHECK: @llvm.ppc.altivec.lvehx
+// CHECK-LE: @llvm.ppc.altivec.lvehx
+
+  res_vi  = vec_lvewx(0, &param_i);
+// CHECK: @llvm.ppc.altivec.lvewx
+// CHECK-LE: @llvm.ppc.altivec.lvewx
+
+  res_vui = vec_lvewx(0, &param_ui);
+// CHECK: @llvm.ppc.altivec.lvewx
+// CHECK-LE: @llvm.ppc.altivec.lvewx
+
+  res_vf  = vec_lvewx(0, &param_f);
+// CHECK: @llvm.ppc.altivec.lvewx
+// CHECK-LE: @llvm.ppc.altivec.lvewx
 
   /* vec_ldl */
-  res_vsc = vec_ldl(0, &vsc);                   // CHECK: @llvm.ppc.altivec.lvxl
-  res_vsc = vec_ldl(0, &param_sc);              // CHECK: @llvm.ppc.altivec.lvxl
-  res_vuc = vec_ldl(0, &vuc);                   // CHECK: @llvm.ppc.altivec.lvxl
-  res_vuc = vec_ldl(0, &param_uc);              // CHECK: @llvm.ppc.altivec.lvxl
-  res_vbc = vec_ldl(0, &vbc);                   // CHECK: @llvm.ppc.altivec.lvxl
-  res_vs  = vec_ldl(0, &vs);                    // CHECK: @llvm.ppc.altivec.lvxl
-  res_vs  = vec_ldl(0, &param_s);               // CHECK: @llvm.ppc.altivec.lvxl
-  res_vus = vec_ldl(0, &vus);                   // CHECK: @llvm.ppc.altivec.lvxl
-  res_vus = vec_ldl(0, &param_us);              // CHECK: @llvm.ppc.altivec.lvxl
-  res_vbs = vec_ldl(0, &vbs);                   // CHECK: @llvm.ppc.altivec.lvxl
-  res_vp  = vec_ldl(0, &vp);                    // CHECK: @llvm.ppc.altivec.lvxl
-  res_vi  = vec_ldl(0, &vi);                    // CHECK: @llvm.ppc.altivec.lvxl
-  res_vi  = vec_ldl(0, &param_i);               // CHECK: @llvm.ppc.altivec.lvxl
-  res_vui = vec_ldl(0, &vui);                   // CHECK: @llvm.ppc.altivec.lvxl
-  res_vui = vec_ldl(0, &param_ui);              // CHECK: @llvm.ppc.altivec.lvxl
-  res_vbi = vec_ldl(0, &vbi);                   // CHECK: @llvm.ppc.altivec.lvxl
-  res_vf  = vec_ldl(0, &vf);                    // CHECK: @llvm.ppc.altivec.lvxl
-  res_vf  = vec_ldl(0, &param_f);               // CHECK: @llvm.ppc.altivec.lvxl
-  res_vsc = vec_lvxl(0, &vsc);                  // CHECK: @llvm.ppc.altivec.lvxl
-  res_vsc = vec_lvxl(0, &param_sc);             // CHECK: @llvm.ppc.altivec.lvxl
-  res_vuc = vec_lvxl(0, &vuc);                  // CHECK: @llvm.ppc.altivec.lvxl
-  res_vbc = vec_lvxl(0, &vbc);                  // CHECK: @llvm.ppc.altivec.lvxl
-  res_vuc = vec_lvxl(0, &param_uc);             // CHECK: @llvm.ppc.altivec.lvxl
-  res_vs  = vec_lvxl(0, &vs);                   // CHECK: @llvm.ppc.altivec.lvxl
-  res_vs  = vec_lvxl(0, &param_s);              // CHECK: @llvm.ppc.altivec.lvxl
-  res_vus = vec_lvxl(0, &vus);                  // CHECK: @llvm.ppc.altivec.lvxl
-  res_vus = vec_lvxl(0, &param_us);             // CHECK: @llvm.ppc.altivec.lvxl
-  res_vbs = vec_lvxl(0, &vbs);                  // CHECK: @llvm.ppc.altivec.lvxl
-  res_vp  = vec_lvxl(0, &vp);                   // CHECK: @llvm.ppc.altivec.lvxl
-  res_vi  = vec_lvxl(0, &vi);                   // CHECK: @llvm.ppc.altivec.lvxl
-  res_vi  = vec_lvxl(0, &param_i);              // CHECK: @llvm.ppc.altivec.lvxl
-  res_vui = vec_lvxl(0, &vui);                  // CHECK: @llvm.ppc.altivec.lvxl
-  res_vui = vec_lvxl(0, &param_ui);             // CHECK: @llvm.ppc.altivec.lvxl
-  res_vbi = vec_lvxl(0, &vbi);                  // CHECK: @llvm.ppc.altivec.lvxl
-  res_vf  = vec_lvxl(0, &vf);                   // CHECK: @llvm.ppc.altivec.lvxl
-  res_vf  = vec_lvxl(0, &param_f);              // CHECK: @llvm.ppc.altivec.lvxl
+  res_vsc = vec_ldl(0, &vsc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vsc = vec_ldl(0, &param_sc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vuc = vec_ldl(0, &vuc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vuc = vec_ldl(0, &param_uc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vbc = vec_ldl(0, &vbc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vs  = vec_ldl(0, &vs);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vs  = vec_ldl(0, &param_s);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vus = vec_ldl(0, &vus);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vus = vec_ldl(0, &param_us);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vbs = vec_ldl(0, &vbs);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vp  = vec_ldl(0, &vp);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vi  = vec_ldl(0, &vi);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vi  = vec_ldl(0, &param_i);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vui = vec_ldl(0, &vui);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vui = vec_ldl(0, &param_ui);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vbi = vec_ldl(0, &vbi);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vf  = vec_ldl(0, &vf);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vf  = vec_ldl(0, &param_f);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vsc = vec_lvxl(0, &vsc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vsc = vec_lvxl(0, &param_sc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vuc = vec_lvxl(0, &vuc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vbc = vec_lvxl(0, &vbc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vuc = vec_lvxl(0, &param_uc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vs  = vec_lvxl(0, &vs);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vs  = vec_lvxl(0, &param_s);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vus = vec_lvxl(0, &vus);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vus = vec_lvxl(0, &param_us);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vbs = vec_lvxl(0, &vbs);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vp  = vec_lvxl(0, &vp);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vi  = vec_lvxl(0, &vi);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vi  = vec_lvxl(0, &param_i);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vui = vec_lvxl(0, &vui);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vui = vec_lvxl(0, &param_ui);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vbi = vec_lvxl(0, &vbi);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vf  = vec_lvxl(0, &vf);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+
+  res_vf  = vec_lvxl(0, &param_f);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvxl
 
   /* vec_loge */
-  res_vf = vec_loge(vf);                        // CHECK: @llvm.ppc.altivec.vlogefp
-  res_vf = vec_vlogefp(vf);                     // CHECK: @llvm.ppc.altivec.vlogefp
+  res_vf = vec_loge(vf);
+// CHECK: @llvm.ppc.altivec.vlogefp
+// CHECK-LE: @llvm.ppc.altivec.vlogefp
+
+  res_vf = vec_vlogefp(vf);
+// CHECK: @llvm.ppc.altivec.vlogefp
+// CHECK-LE: @llvm.ppc.altivec.vlogefp
 
   /* vec_lvsl */
-  res_vuc = vec_lvsl(0, &param_i);              // CHECK: @llvm.ppc.altivec.lvsl
+  res_vuc = vec_lvsl(0, &param_i);
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
 
   /* vec_lvsr */
-  res_vuc = vec_lvsr(0, &param_i);              // CHECK: @llvm.ppc.altivec.lvsr
+  res_vuc = vec_lvsr(0, &param_i);
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.lvsr
 
   /* vec_madd */
-  res_vf =vec_madd(vf, vf, vf);                 // CHECK: @llvm.ppc.altivec.vmaddfp
-  res_vf = vec_vmaddfp(vf, vf, vf);             // CHECK: @llvm.ppc.altivec.vmaddfp
+  res_vf =vec_madd(vf, vf, vf);
+// CHECK: @llvm.ppc.altivec.vmaddfp
+// CHECK-LE: @llvm.ppc.altivec.vmaddfp
+
+  res_vf = vec_vmaddfp(vf, vf, vf);
+// CHECK: @llvm.ppc.altivec.vmaddfp
+// CHECK-LE: @llvm.ppc.altivec.vmaddfp
 
   /* vec_madds */
-  res_vs = vec_madds(vs, vs, vs);               // CHECK: @llvm.ppc.altivec.vmhaddshs
-  res_vs = vec_vmhaddshs(vs, vs, vs);           // CHECK: @llvm.ppc.altivec.vmhaddshs
+  res_vs = vec_madds(vs, vs, vs);
+// CHECK: @llvm.ppc.altivec.vmhaddshs
+// CHECK-LE: @llvm.ppc.altivec.vmhaddshs
+
+  res_vs = vec_vmhaddshs(vs, vs, vs);
+// CHECK: @llvm.ppc.altivec.vmhaddshs
+// CHECK-LE: @llvm.ppc.altivec.vmhaddshs
 
   /* vec_max */
-  res_vsc = vec_max(vsc, vsc);                  // CHECK: @llvm.ppc.altivec.vmaxsb
-  res_vsc = vec_max(vbc, vsc);                  // CHECK: @llvm.ppc.altivec.vmaxsb
-  res_vsc = vec_max(vsc, vbc);                  // CHECK: @llvm.ppc.altivec.vmaxsb
-  res_vuc = vec_max(vuc, vuc);                  // CHECK: @llvm.ppc.altivec.vmaxub
-  res_vuc = vec_max(vbc, vuc);                  // CHECK: @llvm.ppc.altivec.vmaxub
-  res_vuc = vec_max(vuc, vbc);                  // CHECK: @llvm.ppc.altivec.vmaxub
-  res_vs  = vec_max(vs, vs);                    // CHECK: @llvm.ppc.altivec.vmaxsh
-  res_vs  = vec_max(vbs, vs);                   // CHECK: @llvm.ppc.altivec.vmaxsh
-  res_vs  = vec_max(vs, vbs);                   // CHECK: @llvm.ppc.altivec.vmaxsh
-  res_vus = vec_max(vus, vus);                  // CHECK: @llvm.ppc.altivec.vmaxuh
-  res_vus = vec_max(vbs, vus);                  // CHECK: @llvm.ppc.altivec.vmaxuh
-  res_vus = vec_max(vus, vbs);                  // CHECK: @llvm.ppc.altivec.vmaxuh
-  res_vi  = vec_max(vi, vi);                    // CHECK: @llvm.ppc.altivec.vmaxsw
-  res_vi  = vec_max(vbi, vi);                   // CHECK: @llvm.ppc.altivec.vmaxsw
-  res_vi  = vec_max(vi, vbi);                   // CHECK: @llvm.ppc.altivec.vmaxsw
-  res_vui = vec_max(vui, vui);                  // CHECK: @llvm.ppc.altivec.vmaxuw
-  res_vui = vec_max(vbi, vui);                  // CHECK: @llvm.ppc.altivec.vmaxuw
-  res_vui = vec_max(vui, vbi);                  // CHECK: @llvm.ppc.altivec.vmaxuw
-  res_vf  = vec_max(vf, vf);                    // CHECK: @llvm.ppc.altivec.vmaxfp
-  res_vsc = vec_vmaxsb(vsc, vsc);               // CHECK: @llvm.ppc.altivec.vmaxsb
-  res_vsc = vec_vmaxsb(vbc, vsc);               // CHECK: @llvm.ppc.altivec.vmaxsb
-  res_vsc = vec_vmaxsb(vsc, vbc);               // CHECK: @llvm.ppc.altivec.vmaxsb
-  res_vuc = vec_vmaxub(vuc, vuc);               // CHECK: @llvm.ppc.altivec.vmaxub
-  res_vuc = vec_vmaxub(vbc, vuc);               // CHECK: @llvm.ppc.altivec.vmaxub
-  res_vuc = vec_vmaxub(vuc, vbc);               // CHECK: @llvm.ppc.altivec.vmaxub
-  res_vs  = vec_vmaxsh(vs, vs);                 // CHECK: @llvm.ppc.altivec.vmaxsh
-  res_vs  = vec_vmaxsh(vbs, vs);                // CHECK: @llvm.ppc.altivec.vmaxsh
-  res_vs  = vec_vmaxsh(vs, vbs);                // CHECK: @llvm.ppc.altivec.vmaxsh
-  res_vus = vec_vmaxuh(vus, vus);               // CHECK: @llvm.ppc.altivec.vmaxuh
-  res_vus = vec_vmaxuh(vbs, vus);               // CHECK: @llvm.ppc.altivec.vmaxuh
-  res_vus = vec_vmaxuh(vus, vbs);               // CHECK: @llvm.ppc.altivec.vmaxuh
-  res_vi  = vec_vmaxsw(vi, vi);                 // CHECK: @llvm.ppc.altivec.vmaxsw
-  res_vi  = vec_vmaxsw(vbi, vi);                // CHECK: @llvm.ppc.altivec.vmaxsw
-  res_vi  = vec_vmaxsw(vi, vbi);                // CHECK: @llvm.ppc.altivec.vmaxsw
-  res_vui = vec_vmaxuw(vui, vui);               // CHECK: @llvm.ppc.altivec.vmaxuw
-  res_vui = vec_vmaxuw(vbi, vui);               // CHECK: @llvm.ppc.altivec.vmaxuw
-  res_vui = vec_vmaxuw(vui, vbi);               // CHECK: @llvm.ppc.altivec.vmaxuw
-  res_vf  = vec_vmaxfp(vf, vf);                 // CHECK: @llvm.ppc.altivec.vmaxfp
+  res_vsc = vec_max(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vmaxsb
+// CHECK-LE: @llvm.ppc.altivec.vmaxsb
+
+  res_vsc = vec_max(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vmaxsb
+// CHECK-LE: @llvm.ppc.altivec.vmaxsb
+
+  res_vsc = vec_max(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vmaxsb
+// CHECK-LE: @llvm.ppc.altivec.vmaxsb
+
+  res_vuc = vec_max(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vmaxub
+// CHECK-LE: @llvm.ppc.altivec.vmaxub
+
+  res_vuc = vec_max(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vmaxub
+// CHECK-LE: @llvm.ppc.altivec.vmaxub
+
+  res_vuc = vec_max(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vmaxub
+// CHECK-LE: @llvm.ppc.altivec.vmaxub
+
+  res_vs  = vec_max(vs, vs);
+// CHECK: @llvm.ppc.altivec.vmaxsh
+// CHECK-LE: @llvm.ppc.altivec.vmaxsh
+
+  res_vs  = vec_max(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vmaxsh
+// CHECK-LE: @llvm.ppc.altivec.vmaxsh
+
+  res_vs  = vec_max(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vmaxsh
+// CHECK-LE: @llvm.ppc.altivec.vmaxsh
+
+  res_vus = vec_max(vus, vus);
+// CHECK: @llvm.ppc.altivec.vmaxuh
+// CHECK-LE: @llvm.ppc.altivec.vmaxuh
+
+  res_vus = vec_max(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vmaxuh
+// CHECK-LE: @llvm.ppc.altivec.vmaxuh
+
+  res_vus = vec_max(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vmaxuh
+// CHECK-LE: @llvm.ppc.altivec.vmaxuh
+
+  res_vi  = vec_max(vi, vi);
+// CHECK: @llvm.ppc.altivec.vmaxsw
+// CHECK-LE: @llvm.ppc.altivec.vmaxsw
+
+  res_vi  = vec_max(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vmaxsw
+// CHECK-LE: @llvm.ppc.altivec.vmaxsw
+
+  res_vi  = vec_max(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vmaxsw
+// CHECK-LE: @llvm.ppc.altivec.vmaxsw
+
+  res_vui = vec_max(vui, vui);
+// CHECK: @llvm.ppc.altivec.vmaxuw
+// CHECK-LE: @llvm.ppc.altivec.vmaxuw
+
+  res_vui = vec_max(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vmaxuw
+// CHECK-LE: @llvm.ppc.altivec.vmaxuw
+
+  res_vui = vec_max(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vmaxuw
+// CHECK-LE: @llvm.ppc.altivec.vmaxuw
+
+  res_vf  = vec_max(vf, vf);
+// CHECK: @llvm.ppc.altivec.vmaxfp
+// CHECK-LE: @llvm.ppc.altivec.vmaxfp
+
+  res_vsc = vec_vmaxsb(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vmaxsb
+// CHECK-LE: @llvm.ppc.altivec.vmaxsb
+
+  res_vsc = vec_vmaxsb(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vmaxsb
+// CHECK-LE: @llvm.ppc.altivec.vmaxsb
+
+  res_vsc = vec_vmaxsb(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vmaxsb
+// CHECK-LE: @llvm.ppc.altivec.vmaxsb
+
+  res_vuc = vec_vmaxub(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vmaxub
+// CHECK-LE: @llvm.ppc.altivec.vmaxub
+
+  res_vuc = vec_vmaxub(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vmaxub
+// CHECK-LE: @llvm.ppc.altivec.vmaxub
+
+  res_vuc = vec_vmaxub(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vmaxub
+// CHECK-LE: @llvm.ppc.altivec.vmaxub
+
+  res_vs  = vec_vmaxsh(vs, vs);
+// CHECK: @llvm.ppc.altivec.vmaxsh
+// CHECK-LE: @llvm.ppc.altivec.vmaxsh
+
+  res_vs  = vec_vmaxsh(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vmaxsh
+// CHECK-LE: @llvm.ppc.altivec.vmaxsh
+
+  res_vs  = vec_vmaxsh(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vmaxsh
+// CHECK-LE: @llvm.ppc.altivec.vmaxsh
+
+  res_vus = vec_vmaxuh(vus, vus);
+// CHECK: @llvm.ppc.altivec.vmaxuh
+// CHECK-LE: @llvm.ppc.altivec.vmaxuh
+
+  res_vus = vec_vmaxuh(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vmaxuh
+// CHECK-LE: @llvm.ppc.altivec.vmaxuh
+
+  res_vus = vec_vmaxuh(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vmaxuh
+// CHECK-LE: @llvm.ppc.altivec.vmaxuh
+
+  res_vi  = vec_vmaxsw(vi, vi);
+// CHECK: @llvm.ppc.altivec.vmaxsw
+// CHECK-LE: @llvm.ppc.altivec.vmaxsw
+
+  res_vi  = vec_vmaxsw(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vmaxsw
+// CHECK-LE: @llvm.ppc.altivec.vmaxsw
+
+  res_vi  = vec_vmaxsw(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vmaxsw
+// CHECK-LE: @llvm.ppc.altivec.vmaxsw
+
+  res_vui = vec_vmaxuw(vui, vui);
+// CHECK: @llvm.ppc.altivec.vmaxuw
+// CHECK-LE: @llvm.ppc.altivec.vmaxuw
+
+  res_vui = vec_vmaxuw(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vmaxuw
+// CHECK-LE: @llvm.ppc.altivec.vmaxuw
+
+  res_vui = vec_vmaxuw(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vmaxuw
+// CHECK-LE: @llvm.ppc.altivec.vmaxuw
+
+  res_vf  = vec_vmaxfp(vf, vf);
+// CHECK: @llvm.ppc.altivec.vmaxfp
+// CHECK-LE: @llvm.ppc.altivec.vmaxfp
 
   /* vec_mergeh */
-  res_vsc = vec_mergeh(vsc, vsc);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vuc = vec_mergeh(vuc, vuc);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vbc = vec_mergeh(vbc, vbc);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vs  = vec_mergeh(vs, vs);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vp  = vec_mergeh(vp, vp);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vus = vec_mergeh(vus, vus);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vbs = vec_mergeh(vbs, vbs);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vi  = vec_mergeh(vi, vi);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vui = vec_mergeh(vui, vui);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vbi = vec_mergeh(vbi, vbi);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vf  = vec_mergeh(vf, vf);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vsc = vec_vmrghb(vsc, vsc);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vuc = vec_vmrghb(vuc, vuc);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vbc = vec_vmrghb(vbc, vbc);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vs  = vec_vmrghh(vs, vs);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vp  = vec_vmrghh(vp, vp);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vus = vec_vmrghh(vus, vus);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vbs = vec_vmrghh(vbs, vbs);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vi  = vec_vmrghw(vi, vi);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vui = vec_vmrghw(vui, vui);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vbi = vec_vmrghw(vbi, vbi);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vf  = vec_vmrghw(vf, vf);                 // CHECK: @llvm.ppc.altivec.vperm
+  res_vsc = vec_mergeh(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vuc = vec_mergeh(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbc = vec_mergeh(vbc, vbc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vs  = vec_mergeh(vs, vs);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vp  = vec_mergeh(vp, vp);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vus = vec_mergeh(vus, vus);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbs = vec_mergeh(vbs, vbs);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vi  = vec_mergeh(vi, vi);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vui = vec_mergeh(vui, vui);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbi = vec_mergeh(vbi, vbi);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vf  = vec_mergeh(vf, vf);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vsc = vec_vmrghb(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vuc = vec_vmrghb(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbc = vec_vmrghb(vbc, vbc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vs  = vec_vmrghh(vs, vs);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vp  = vec_vmrghh(vp, vp);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vus = vec_vmrghh(vus, vus);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbs = vec_vmrghh(vbs, vbs);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vi  = vec_vmrghw(vi, vi);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vui = vec_vmrghw(vui, vui);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbi = vec_vmrghw(vbi, vbi);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vf  = vec_vmrghw(vf, vf);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
   /* vec_mergel */
-  res_vsc = vec_mergel(vsc, vsc);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vuc = vec_mergel(vuc, vuc);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vbc = vec_mergel(vbc, vbc);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vs  = vec_mergel(vs, vs);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vp  = vec_mergeh(vp, vp);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vus = vec_mergel(vus, vus);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vbs = vec_mergel(vbs, vbs);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vi  = vec_mergel(vi, vi);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vui = vec_mergel(vui, vui);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vbi = vec_mergel(vbi, vbi);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vf  = vec_mergel(vf, vf);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vsc = vec_vmrglb(vsc, vsc);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vuc = vec_vmrglb(vuc, vuc);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vbc = vec_vmrglb(vbc, vbc);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vs  = vec_vmrglh(vs, vs);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vp  = vec_vmrglh(vp, vp);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vus = vec_vmrglh(vus, vus);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vbs = vec_vmrglh(vbs, vbs);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vi  = vec_vmrglw(vi, vi);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vui = vec_vmrglw(vui, vui);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vbi = vec_vmrglw(vbi, vbi);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vf  = vec_vmrglw(vf, vf);                 // CHECK: @llvm.ppc.altivec.vperm
+  res_vsc = vec_mergel(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vuc = vec_mergel(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbc = vec_mergel(vbc, vbc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vs  = vec_mergel(vs, vs);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vp  = vec_mergeh(vp, vp);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vus = vec_mergel(vus, vus);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbs = vec_mergel(vbs, vbs);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vi  = vec_mergel(vi, vi);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vui = vec_mergel(vui, vui);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbi = vec_mergel(vbi, vbi);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vf  = vec_mergel(vf, vf);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vsc = vec_vmrglb(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vuc = vec_vmrglb(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbc = vec_vmrglb(vbc, vbc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vs  = vec_vmrglh(vs, vs);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vp  = vec_vmrglh(vp, vp);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vus = vec_vmrglh(vus, vus);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbs = vec_vmrglh(vbs, vbs);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vi  = vec_vmrglw(vi, vi);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vui = vec_vmrglw(vui, vui);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbi = vec_vmrglw(vbi, vbi);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vf  = vec_vmrglw(vf, vf);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
   /* vec_mfvscr */
-  vus = vec_mfvscr();                           // CHECK: @llvm.ppc.altivec.mfvscr
+  vus = vec_mfvscr();
+// CHECK: @llvm.ppc.altivec.mfvscr
+// CHECK-LE: @llvm.ppc.altivec.mfvscr
 
   /* vec_min */
-  res_vsc = vec_min(vsc, vsc);                  // CHECK: @llvm.ppc.altivec.vminsb
-  res_vsc = vec_min(vbc, vsc);                  // CHECK: @llvm.ppc.altivec.vminsb
-  res_vsc = vec_min(vsc, vbc);                  // CHECK: @llvm.ppc.altivec.vminsb
-  res_vuc = vec_min(vuc, vuc);                  // CHECK: @llvm.ppc.altivec.vminub
-  res_vuc = vec_min(vbc, vuc);                  // CHECK: @llvm.ppc.altivec.vminub
-  res_vuc = vec_min(vuc, vbc);                  // CHECK: @llvm.ppc.altivec.vminub
-  res_vs  = vec_min(vs, vs);                    // CHECK: @llvm.ppc.altivec.vminsh
-  res_vs  = vec_min(vbs, vs);                   // CHECK: @llvm.ppc.altivec.vminsh
-  res_vs  = vec_min(vs, vbs);                   // CHECK: @llvm.ppc.altivec.vminsh
-  res_vus = vec_min(vus, vus);                  // CHECK: @llvm.ppc.altivec.vminuh
-  res_vus = vec_min(vbs, vus);                  // CHECK: @llvm.ppc.altivec.vminuh
-  res_vus = vec_min(vus, vbs);                  // CHECK: @llvm.ppc.altivec.vminuh
-  res_vi  = vec_min(vi, vi);                    // CHECK: @llvm.ppc.altivec.vminsw
-  res_vi  = vec_min(vbi, vi);                   // CHECK: @llvm.ppc.altivec.vminsw
-  res_vi  = vec_min(vi, vbi);                   // CHECK: @llvm.ppc.altivec.vminsw
-  res_vui = vec_min(vui, vui);                  // CHECK: @llvm.ppc.altivec.vminuw
-  res_vui = vec_min(vbi, vui);                  // CHECK: @llvm.ppc.altivec.vminuw
-  res_vui = vec_min(vui, vbi);                  // CHECK: @llvm.ppc.altivec.vminuw
-  res_vf  = vec_min(vf, vf);                    // CHECK: @llvm.ppc.altivec.vminfp
-  res_vsc = vec_vminsb(vsc, vsc);               // CHECK: @llvm.ppc.altivec.vminsb
-  res_vsc = vec_vminsb(vbc, vsc);               // CHECK: @llvm.ppc.altivec.vminsb
-  res_vsc = vec_vminsb(vsc, vbc);               // CHECK: @llvm.ppc.altivec.vminsb
-  res_vuc = vec_vminub(vuc, vuc);               // CHECK: @llvm.ppc.altivec.vminub
-  res_vuc = vec_vminub(vbc, vuc);               // CHECK: @llvm.ppc.altivec.vminub
-  res_vuc = vec_vminub(vuc, vbc);               // CHECK: @llvm.ppc.altivec.vminub
-  res_vs  = vec_vminsh(vs, vs);                 // CHECK: @llvm.ppc.altivec.vminsh
-  res_vs  = vec_vminsh(vbs, vs);                // CHECK: @llvm.ppc.altivec.vminsh
-  res_vs  = vec_vminsh(vs, vbs);                // CHECK: @llvm.ppc.altivec.vminsh
-  res_vus = vec_vminuh(vus, vus);               // CHECK: @llvm.ppc.altivec.vminuh
-  res_vus = vec_vminuh(vbs, vus);               // CHECK: @llvm.ppc.altivec.vminuh
-  res_vus = vec_vminuh(vus, vbs);               // CHECK: @llvm.ppc.altivec.vminuh
-  res_vi  = vec_vminsw(vi, vi);                 // CHECK: @llvm.ppc.altivec.vminsw
-  res_vi  = vec_vminsw(vbi, vi);                // CHECK: @llvm.ppc.altivec.vminsw
-  res_vi  = vec_vminsw(vi, vbi);                // CHECK: @llvm.ppc.altivec.vminsw
-  res_vui = vec_vminuw(vui, vui);               // CHECK: @llvm.ppc.altivec.vminuw
-  res_vui = vec_vminuw(vbi, vui);               // CHECK: @llvm.ppc.altivec.vminuw
-  res_vui = vec_vminuw(vui, vbi);               // CHECK: @llvm.ppc.altivec.vminuw
-  res_vf  = vec_vminfp(vf, vf);                 // CHECK: @llvm.ppc.altivec.vminfp
+  res_vsc = vec_min(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vminsb
+// CHECK-LE: @llvm.ppc.altivec.vminsb
+
+  res_vsc = vec_min(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vminsb
+// CHECK-LE: @llvm.ppc.altivec.vminsb
+
+  res_vsc = vec_min(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vminsb
+// CHECK-LE: @llvm.ppc.altivec.vminsb
+
+  res_vuc = vec_min(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vminub
+// CHECK-LE: @llvm.ppc.altivec.vminub
+
+  res_vuc = vec_min(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vminub
+// CHECK-LE: @llvm.ppc.altivec.vminub
+
+  res_vuc = vec_min(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vminub
+// CHECK-LE: @llvm.ppc.altivec.vminub
+
+  res_vs  = vec_min(vs, vs);
+// CHECK: @llvm.ppc.altivec.vminsh
+// CHECK-LE: @llvm.ppc.altivec.vminsh
+
+  res_vs  = vec_min(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vminsh
+// CHECK-LE: @llvm.ppc.altivec.vminsh
+
+  res_vs  = vec_min(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vminsh
+// CHECK-LE: @llvm.ppc.altivec.vminsh
+
+  res_vus = vec_min(vus, vus);
+// CHECK: @llvm.ppc.altivec.vminuh
+// CHECK-LE: @llvm.ppc.altivec.vminuh
+
+  res_vus = vec_min(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vminuh
+// CHECK-LE: @llvm.ppc.altivec.vminuh
+
+  res_vus = vec_min(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vminuh
+// CHECK-LE: @llvm.ppc.altivec.vminuh
+
+  res_vi  = vec_min(vi, vi);
+// CHECK: @llvm.ppc.altivec.vminsw
+// CHECK-LE: @llvm.ppc.altivec.vminsw
+
+  res_vi  = vec_min(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vminsw
+// CHECK-LE: @llvm.ppc.altivec.vminsw
+
+  res_vi  = vec_min(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vminsw
+// CHECK-LE: @llvm.ppc.altivec.vminsw
+
+  res_vui = vec_min(vui, vui);
+// CHECK: @llvm.ppc.altivec.vminuw
+// CHECK-LE: @llvm.ppc.altivec.vminuw
+
+  res_vui = vec_min(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vminuw
+// CHECK-LE: @llvm.ppc.altivec.vminuw
+
+  res_vui = vec_min(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vminuw
+// CHECK-LE: @llvm.ppc.altivec.vminuw
+
+  res_vf  = vec_min(vf, vf);
+// CHECK: @llvm.ppc.altivec.vminfp
+// CHECK-LE: @llvm.ppc.altivec.vminfp
+
+  res_vsc = vec_vminsb(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vminsb
+// CHECK-LE: @llvm.ppc.altivec.vminsb
+
+  res_vsc = vec_vminsb(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vminsb
+// CHECK-LE: @llvm.ppc.altivec.vminsb
+
+  res_vsc = vec_vminsb(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vminsb
+// CHECK-LE: @llvm.ppc.altivec.vminsb
+
+  res_vuc = vec_vminub(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vminub
+// CHECK-LE: @llvm.ppc.altivec.vminub
+
+  res_vuc = vec_vminub(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vminub
+// CHECK-LE: @llvm.ppc.altivec.vminub
+
+  res_vuc = vec_vminub(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vminub
+// CHECK-LE: @llvm.ppc.altivec.vminub
+
+  res_vs  = vec_vminsh(vs, vs);
+// CHECK: @llvm.ppc.altivec.vminsh
+// CHECK-LE: @llvm.ppc.altivec.vminsh
+
+  res_vs  = vec_vminsh(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vminsh
+// CHECK-LE: @llvm.ppc.altivec.vminsh
+
+  res_vs  = vec_vminsh(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vminsh
+// CHECK-LE: @llvm.ppc.altivec.vminsh
+
+  res_vus = vec_vminuh(vus, vus);
+// CHECK: @llvm.ppc.altivec.vminuh
+// CHECK-LE: @llvm.ppc.altivec.vminuh
+
+  res_vus = vec_vminuh(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vminuh
+// CHECK-LE: @llvm.ppc.altivec.vminuh
+
+  res_vus = vec_vminuh(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vminuh
+// CHECK-LE: @llvm.ppc.altivec.vminuh
+
+  res_vi  = vec_vminsw(vi, vi);
+// CHECK: @llvm.ppc.altivec.vminsw
+// CHECK-LE: @llvm.ppc.altivec.vminsw
+
+  res_vi  = vec_vminsw(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vminsw
+// CHECK-LE: @llvm.ppc.altivec.vminsw
+
+  res_vi  = vec_vminsw(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vminsw
+// CHECK-LE: @llvm.ppc.altivec.vminsw
+
+  res_vui = vec_vminuw(vui, vui);
+// CHECK: @llvm.ppc.altivec.vminuw
+// CHECK-LE: @llvm.ppc.altivec.vminuw
+
+  res_vui = vec_vminuw(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vminuw
+// CHECK-LE: @llvm.ppc.altivec.vminuw
+
+  res_vui = vec_vminuw(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vminuw
+// CHECK-LE: @llvm.ppc.altivec.vminuw
+
+  res_vf  = vec_vminfp(vf, vf);
+// CHECK: @llvm.ppc.altivec.vminfp
+// CHECK-LE: @llvm.ppc.altivec.vminfp
 
   /* vec_mladd */
-  res_vus = vec_mladd(vus, vus, vus);           // CHECK: mul <8 x i16>
-                                                // CHECK: add <8 x i16>
+  res_vus = vec_mladd(vus, vus, vus);
+// CHECK: mul <8 x i16>
+// CHECK: add <8 x i16>
+// CHECK-LE: mul <8 x i16>
+// CHECK-LE: add <8 x i16>
 
-  res_vs = vec_mladd(vus, vs, vs);              // CHECK: mul <8 x i16>
-                                                // CHECK: add <8 x i16>
+  res_vs = vec_mladd(vus, vs, vs);
+// CHECK: mul <8 x i16>
+// CHECK: add <8 x i16>
+// CHECK-LE: mul <8 x i16>
+// CHECK-LE: add <8 x i16>
 
-  res_vs = vec_mladd(vs, vus, vus);             // CHECK: mul <8 x i16>
-                                                // CHECK: add <8 x i16>
+  res_vs = vec_mladd(vs, vus, vus);
+// CHECK: mul <8 x i16>
+// CHECK: add <8 x i16>
+// CHECK-LE: mul <8 x i16>
+// CHECK-LE: add <8 x i16>
 
-  res_vs = vec_mladd(vs, vs, vs);               // CHECK: mul <8 x i16>
-                                                // CHECK: add <8 x i16>
+  res_vs = vec_mladd(vs, vs, vs);
+// CHECK: mul <8 x i16>
+// CHECK: add <8 x i16>
+// CHECK-LE: mul <8 x i16>
+// CHECK-LE: add <8 x i16>
 
   /* vec_mradds */
-  res_vs = vec_mradds(vs, vs, vs);              // CHECK: @llvm.ppc.altivec.vmhraddshs
-  res_vs = vec_vmhraddshs(vs, vs, vs);          // CHECK: @llvm.ppc.altivec.vmhraddshs
- 
+  res_vs = vec_mradds(vs, vs, vs);
+// CHECK: @llvm.ppc.altivec.vmhraddshs
+// CHECK-LE: @llvm.ppc.altivec.vmhraddshs
+
+  res_vs = vec_vmhraddshs(vs, vs, vs);
+// CHECK: @llvm.ppc.altivec.vmhraddshs
+// CHECK-LE: @llvm.ppc.altivec.vmhraddshs
+
   /* vec_msum */
-  res_vi  = vec_msum(vsc, vuc, vi);             // CHECK: @llvm.ppc.altivec.vmsummbm
-  res_vui = vec_msum(vuc, vuc, vui);            // CHECK: @llvm.ppc.altivec.vmsumubm
-  res_vi  = vec_msum(vs, vs, vi);               // CHECK: @llvm.ppc.altivec.vmsumshm
-  res_vui = vec_msum(vus, vus, vui);            // CHECK: @llvm.ppc.altivec.vmsumuhm
-  res_vi  = vec_vmsummbm(vsc, vuc, vi);         // CHECK: @llvm.ppc.altivec.vmsummbm
-  res_vui = vec_vmsumubm(vuc, vuc, vui);        // CHECK: @llvm.ppc.altivec.vmsumubm
-  res_vi  = vec_vmsumshm(vs, vs, vi);           // CHECK: @llvm.ppc.altivec.vmsumshm
-  res_vui = vec_vmsumuhm(vus, vus, vui);        // CHECK: @llvm.ppc.altivec.vmsumuhm
+  res_vi  = vec_msum(vsc, vuc, vi);
+// CHECK: @llvm.ppc.altivec.vmsummbm
+// CHECK-LE: @llvm.ppc.altivec.vmsummbm
+
+  res_vui = vec_msum(vuc, vuc, vui);
+// CHECK: @llvm.ppc.altivec.vmsumubm
+// CHECK-LE: @llvm.ppc.altivec.vmsumubm
+
+  res_vi  = vec_msum(vs, vs, vi);
+// CHECK: @llvm.ppc.altivec.vmsumshm
+// CHECK-LE: @llvm.ppc.altivec.vmsumshm
+
+  res_vui = vec_msum(vus, vus, vui);
+// CHECK: @llvm.ppc.altivec.vmsumuhm
+// CHECK-LE: @llvm.ppc.altivec.vmsumuhm
+
+  res_vi  = vec_vmsummbm(vsc, vuc, vi);
+// CHECK: @llvm.ppc.altivec.vmsummbm
+// CHECK-LE: @llvm.ppc.altivec.vmsummbm
+
+  res_vui = vec_vmsumubm(vuc, vuc, vui);
+// CHECK: @llvm.ppc.altivec.vmsumubm
+// CHECK-LE: @llvm.ppc.altivec.vmsumubm
+
+  res_vi  = vec_vmsumshm(vs, vs, vi);
+// CHECK: @llvm.ppc.altivec.vmsumshm
+// CHECK-LE: @llvm.ppc.altivec.vmsumshm
+
+  res_vui = vec_vmsumuhm(vus, vus, vui);
+// CHECK: @llvm.ppc.altivec.vmsumuhm
+// CHECK-LE: @llvm.ppc.altivec.vmsumuhm
 
   /* vec_msums */
-  res_vi  = vec_msums(vs, vs, vi);              // CHECK: @llvm.ppc.altivec.vmsumshs
-  res_vui = vec_msums(vus, vus, vui);           // CHECK: @llvm.ppc.altivec.vmsumuhs
-  res_vi  = vec_vmsumshs(vs, vs, vi);           // CHECK: @llvm.ppc.altivec.vmsumshs
-  res_vui = vec_vmsumuhs(vus, vus, vui);        // CHECK: @llvm.ppc.altivec.vmsumuhs
+  res_vi  = vec_msums(vs, vs, vi);
+// CHECK: @llvm.ppc.altivec.vmsumshs
+// CHECK-LE: @llvm.ppc.altivec.vmsumshs
+
+  res_vui = vec_msums(vus, vus, vui);
+// CHECK: @llvm.ppc.altivec.vmsumuhs
+// CHECK-LE: @llvm.ppc.altivec.vmsumuhs
+
+  res_vi  = vec_vmsumshs(vs, vs, vi);
+// CHECK: @llvm.ppc.altivec.vmsumshs
+// CHECK-LE: @llvm.ppc.altivec.vmsumshs
+
+  res_vui = vec_vmsumuhs(vus, vus, vui);
+// CHECK: @llvm.ppc.altivec.vmsumuhs
+// CHECK-LE: @llvm.ppc.altivec.vmsumuhs
 
   /* vec_mtvscr */
-  vec_mtvscr(vsc);                              // CHECK: @llvm.ppc.altivec.mtvscr
-  vec_mtvscr(vuc);                              // CHECK: @llvm.ppc.altivec.mtvscr
-  vec_mtvscr(vbc);                              // CHECK: @llvm.ppc.altivec.mtvscr
-  vec_mtvscr(vs);                               // CHECK: @llvm.ppc.altivec.mtvscr
-  vec_mtvscr(vus);                              // CHECK: @llvm.ppc.altivec.mtvscr
-  vec_mtvscr(vbs);                              // CHECK: @llvm.ppc.altivec.mtvscr
-  vec_mtvscr(vp);                               // CHECK: @llvm.ppc.altivec.mtvscr
-  vec_mtvscr(vi);                               // CHECK: @llvm.ppc.altivec.mtvscr
-  vec_mtvscr(vui);                              // CHECK: @llvm.ppc.altivec.mtvscr
-  vec_mtvscr(vbi);                              // CHECK: @llvm.ppc.altivec.mtvscr
+  vec_mtvscr(vsc);
+// CHECK: @llvm.ppc.altivec.mtvscr
+// CHECK-LE: @llvm.ppc.altivec.mtvscr
+
+  vec_mtvscr(vuc);
+// CHECK: @llvm.ppc.altivec.mtvscr
+// CHECK-LE: @llvm.ppc.altivec.mtvscr
+
+  vec_mtvscr(vbc);
+// CHECK: @llvm.ppc.altivec.mtvscr
+// CHECK-LE: @llvm.ppc.altivec.mtvscr
+
+  vec_mtvscr(vs);
+// CHECK: @llvm.ppc.altivec.mtvscr
+// CHECK-LE: @llvm.ppc.altivec.mtvscr
+
+  vec_mtvscr(vus);
+// CHECK: @llvm.ppc.altivec.mtvscr
+// CHECK-LE: @llvm.ppc.altivec.mtvscr
+
+  vec_mtvscr(vbs);
+// CHECK: @llvm.ppc.altivec.mtvscr
+// CHECK-LE: @llvm.ppc.altivec.mtvscr
+
+  vec_mtvscr(vp);
+// CHECK: @llvm.ppc.altivec.mtvscr
+// CHECK-LE: @llvm.ppc.altivec.mtvscr
+
+  vec_mtvscr(vi);
+// CHECK: @llvm.ppc.altivec.mtvscr
+// CHECK-LE: @llvm.ppc.altivec.mtvscr
+
+  vec_mtvscr(vui);
+// CHECK: @llvm.ppc.altivec.mtvscr
+// CHECK-LE: @llvm.ppc.altivec.mtvscr
+
+  vec_mtvscr(vbi);
+// CHECK: @llvm.ppc.altivec.mtvscr
+// CHECK-LE: @llvm.ppc.altivec.mtvscr
 
   /* vec_mule */
-  res_vs  = vec_mule(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vmulesb
-  res_vus = vec_mule(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vmuleub
-  res_vi  = vec_mule(vs, vs);                   // CHECK: @llvm.ppc.altivec.vmulesh
-  res_vui = vec_mule(vus, vus);                 // CHECK: @llvm.ppc.altivec.vmuleuh
-  res_vs  = vec_vmulesb(vsc, vsc);              // CHECK: @llvm.ppc.altivec.vmulesb
-  res_vus = vec_vmuleub(vuc, vuc);              // CHECK: @llvm.ppc.altivec.vmuleub
-  res_vi  = vec_vmulesh(vs, vs);                // CHECK: @llvm.ppc.altivec.vmulesh
-  res_vui = vec_vmuleuh(vus, vus);              // CHECK: @llvm.ppc.altivec.vmuleuh
+  res_vs  = vec_mule(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vmulesb
+// CHECK-LE: @llvm.ppc.altivec.vmulosb
+
+  res_vus = vec_mule(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vmuleub
+// CHECK-LE: @llvm.ppc.altivec.vmuloub
+
+  res_vi  = vec_mule(vs, vs);
+// CHECK: @llvm.ppc.altivec.vmulesh
+// CHECK-LE: @llvm.ppc.altivec.vmulosh
+
+  res_vui = vec_mule(vus, vus);
+// CHECK: @llvm.ppc.altivec.vmuleuh
+// CHECK-LE: @llvm.ppc.altivec.vmulouh
+
+  res_vs  = vec_vmulesb(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vmulesb
+// CHECK-LE: @llvm.ppc.altivec.vmulosb
+
+  res_vus = vec_vmuleub(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vmuleub
+// CHECK-LE: @llvm.ppc.altivec.vmuloub
+
+  res_vi  = vec_vmulesh(vs, vs);
+// CHECK: @llvm.ppc.altivec.vmulesh
+// CHECK-LE: @llvm.ppc.altivec.vmulosh
+
+  res_vui = vec_vmuleuh(vus, vus);
+// CHECK: @llvm.ppc.altivec.vmuleuh
+// CHECK-LE: @llvm.ppc.altivec.vmulouh
 
   /* vec_mulo */
-  res_vs  = vec_mulo(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vmulosb
-  res_vus = vec_mulo(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vmuloub
-  res_vi  = vec_mulo(vs, vs);                   // CHECK: @llvm.ppc.altivec.vmulosh
-  res_vui = vec_mulo(vus, vus);                 // CHECK: @llvm.ppc.altivec.vmulouh
-  res_vs  = vec_vmulosb(vsc, vsc);              // CHECK: @llvm.ppc.altivec.vmulosb
-  res_vus = vec_vmuloub(vuc, vuc);              // CHECK: @llvm.ppc.altivec.vmuloub
-  res_vi  = vec_vmulosh(vs, vs);                // CHECK: @llvm.ppc.altivec.vmulosh
-  res_vui = vec_vmulouh(vus, vus);              // CHECK: @llvm.ppc.altivec.vmulouh
+  res_vs  = vec_mulo(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vmulosb
+// CHECK-LE: @llvm.ppc.altivec.vmulesb
+
+  res_vus = vec_mulo(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vmuloub
+// CHECK-LE: @llvm.ppc.altivec.vmuleub
+
+  res_vi  = vec_mulo(vs, vs);
+// CHECK: @llvm.ppc.altivec.vmulosh
+// CHECK-LE: @llvm.ppc.altivec.vmulesh
+
+  res_vui = vec_mulo(vus, vus);
+// CHECK: @llvm.ppc.altivec.vmulouh
+// CHECK-LE: @llvm.ppc.altivec.vmuleuh
+
+  res_vs  = vec_vmulosb(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vmulosb
+// CHECK-LE: @llvm.ppc.altivec.vmulesb
+
+  res_vus = vec_vmuloub(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vmuloub
+// CHECK-LE: @llvm.ppc.altivec.vmuleub
+
+  res_vi  = vec_vmulosh(vs, vs);
+// CHECK: @llvm.ppc.altivec.vmulosh
+// CHECK-LE: @llvm.ppc.altivec.vmulesh
+
+  res_vui = vec_vmulouh(vus, vus);
+// CHECK: @llvm.ppc.altivec.vmulouh
+// CHECK-LE: @llvm.ppc.altivec.vmuleuh
 
   /* vec_nmsub */
-  res_vf = vec_nmsub(vf, vf, vf);               // CHECK: @llvm.ppc.altivec.vnmsubfp
-  res_vf = vec_vnmsubfp(vf, vf, vf);            // CHECK: @llvm.ppc.altivec.vnmsubfp
+  res_vf = vec_nmsub(vf, vf, vf);
+// CHECK: @llvm.ppc.altivec.vnmsubfp
+// CHECK-LE: @llvm.ppc.altivec.vnmsubfp
+
+  res_vf = vec_vnmsubfp(vf, vf, vf);
+// CHECK: @llvm.ppc.altivec.vnmsubfp
+// CHECK-LE: @llvm.ppc.altivec.vnmsubfp
 
   /* vec_nor */
-  res_vsc = vec_nor(vsc, vsc);                  // CHECK: or <16 x i8>
-                                                // CHECK: xor <16 x i8>
+  res_vsc = vec_nor(vsc, vsc);
+// CHECK: or <16 x i8>
+// CHECK: xor <16 x i8>
+// CHECK-LE: or <16 x i8>
+// CHECK-LE: xor <16 x i8>
 
-  res_vuc = vec_nor(vuc, vuc);                  // CHECK: or <16 x i8>
-                                                // CHECK: xor <16 x i8>
+  res_vuc = vec_nor(vuc, vuc);
+// CHECK: or <16 x i8>
+// CHECK: xor <16 x i8>
+// CHECK-LE: or <16 x i8>
+// CHECK-LE: xor <16 x i8>
 
-  res_vuc = vec_nor(vbc, vbc);                  // CHECK: or <16 x i8>
-                                                // CHECK: xor <16 x i8>
+  res_vuc = vec_nor(vbc, vbc);
+// CHECK: or <16 x i8>
+// CHECK: xor <16 x i8>
+// CHECK-LE: or <16 x i8>
+// CHECK-LE: xor <16 x i8>
 
-  res_vs  = vec_nor(vs, vs);                    // CHECK: or <8 x i16>
-                                                // CHECK: xor <8 x i16>
+  res_vs  = vec_nor(vs, vs);
+// CHECK: or <8 x i16>
+// CHECK: xor <8 x i16>
+// CHECK-LE: or <8 x i16>
+// CHECK-LE: xor <8 x i16>
 
-  res_vus = vec_nor(vus, vus);                  // CHECK: or <8 x i16>
-                                                // CHECK: xor <8 x i16>
+  res_vus = vec_nor(vus, vus);
+// CHECK: or <8 x i16>
+// CHECK: xor <8 x i16>
+// CHECK-LE: or <8 x i16>
+// CHECK-LE: xor <8 x i16>
 
-  res_vus = vec_nor(vbs, vbs);                  // CHECK: or <8 x i16>
-                                                // CHECK: xor <8 x i16>
+  res_vus = vec_nor(vbs, vbs);
+// CHECK: or <8 x i16>
+// CHECK: xor <8 x i16>
+// CHECK-LE: or <8 x i16>
+// CHECK-LE: xor <8 x i16>
 
-  res_vi  = vec_nor(vi, vi);                    // CHECK: or <4 x i32>
-                                                // CHECK: xor <4 x i32>
+  res_vi  = vec_nor(vi, vi);
+// CHECK: or <4 x i32>
+// CHECK: xor <4 x i32>
+// CHECK-LE: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
 
-  res_vui = vec_nor(vui, vui);                  // CHECK: or <4 x i32>
-                                                // CHECK: xor <4 x i32>
+  res_vui = vec_nor(vui, vui);
+// CHECK: or <4 x i32>
+// CHECK: xor <4 x i32>
+// CHECK-LE: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
 
-  res_vui = vec_nor(vbi, vbi);                  // CHECK: or <4 x i32>
-                                                // CHECK: xor <4 x i32>
+  res_vui = vec_nor(vbi, vbi);
+// CHECK: or <4 x i32>
+// CHECK: xor <4 x i32>
+// CHECK-LE: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
 
-  res_vf  = vec_nor(vf, vf);                    // CHECK: or <4 x i32>
-                                                // CHECK: xor <4 x i32>
+  res_vf  = vec_nor(vf, vf);
+// CHECK: or <4 x i32>
+// CHECK: xor <4 x i32>
+// CHECK-LE: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
 
-  res_vsc = vec_vnor(vsc, vsc);                 // CHECK: or <16 x i8>
-                                                // CHECK: xor <16 x i8>
+  res_vsc = vec_vnor(vsc, vsc);
+// CHECK: or <16 x i8>
+// CHECK: xor <16 x i8>
+// CHECK-LE: or <16 x i8>
+// CHECK-LE: xor <16 x i8>
 
-  res_vuc = vec_vnor(vuc, vuc);                 // CHECK: or <16 x i8>
-                                                // CHECK: xor <16 x i8>
+  res_vuc = vec_vnor(vuc, vuc);
+// CHECK: or <16 x i8>
+// CHECK: xor <16 x i8>
+// CHECK-LE: or <16 x i8>
+// CHECK-LE: xor <16 x i8>
 
-  res_vuc = vec_vnor(vbc, vbc);                 // CHECK: or <16 x i8>
-                                                // CHECK: xor <16 x i8>
+  res_vuc = vec_vnor(vbc, vbc);
+// CHECK: or <16 x i8>
+// CHECK: xor <16 x i8>
+// CHECK-LE: or <16 x i8>
+// CHECK-LE: xor <16 x i8>
 
-  res_vs  = vec_vnor(vs, vs);                   // CHECK: or <8 x i16>
-                                                // CHECK: xor <8 x i16>
+  res_vs  = vec_vnor(vs, vs);
+// CHECK: or <8 x i16>
+// CHECK: xor <8 x i16>
+// CHECK-LE: or <8 x i16>
+// CHECK-LE: xor <8 x i16>
 
-  res_vus = vec_vnor(vus, vus);                 // CHECK: or <8 x i16>
-                                                // CHECK: xor <8 x i16>
+  res_vus = vec_vnor(vus, vus);
+// CHECK: or <8 x i16>
+// CHECK: xor <8 x i16>
+// CHECK-LE: or <8 x i16>
+// CHECK-LE: xor <8 x i16>
 
-  res_vus = vec_vnor(vbs, vbs);                 // CHECK: or <8 x i16>
-                                                // CHECK: xor <8 x i16>
+  res_vus = vec_vnor(vbs, vbs);
+// CHECK: or <8 x i16>
+// CHECK: xor <8 x i16>
+// CHECK-LE: or <8 x i16>
+// CHECK-LE: xor <8 x i16>
 
-  res_vi  = vec_vnor(vi, vi);                   // CHECK: or <4 x i32>
-                                                // CHECK: xor <4 x i32>
+  res_vi  = vec_vnor(vi, vi);
+// CHECK: or <4 x i32>
+// CHECK: xor <4 x i32>
+// CHECK-LE: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
 
-  res_vui = vec_vnor(vui, vui);                 // CHECK: or <4 x i32>
-                                                // CHECK: xor <4 x i32>
+  res_vui = vec_vnor(vui, vui);
+// CHECK: or <4 x i32>
+// CHECK: xor <4 x i32>
+// CHECK-LE: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
 
-  res_vui = vec_vnor(vbi, vbi);                 // CHECK: or <4 x i32>
-                                                // CHECK: xor <4 x i32>
+  res_vui = vec_vnor(vbi, vbi);
+// CHECK: or <4 x i32>
+// CHECK: xor <4 x i32>
+// CHECK-LE: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
 
-  res_vf  = vec_vnor(vf, vf);                   // CHECK: or <4 x i32>
-                                                // CHECK: xor <4 x i32>
+  res_vf  = vec_vnor(vf, vf);
+// CHECK: or <4 x i32>
+// CHECK: xor <4 x i32>
+// CHECK-LE: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
 
   /* vec_or */
-  res_vsc = vec_or(vsc, vsc);                   // CHECK: or <16 x i8>
-  res_vsc = vec_or(vbc, vsc);                   // CHECK: or <16 x i8>
-  res_vsc = vec_or(vsc, vbc);                   // CHECK: or <16 x i8>
-  res_vuc = vec_or(vuc, vuc);                   // CHECK: or <16 x i8>
-  res_vuc = vec_or(vbc, vuc);                   // CHECK: or <16 x i8>
-  res_vuc = vec_or(vuc, vbc);                   // CHECK: or <16 x i8>
-  res_vbc = vec_or(vbc, vbc);                   // CHECK: or <16 x i8>
-  res_vs  = vec_or(vs, vs);                     // CHECK: or <8 x i16>
-  res_vs  = vec_or(vbs, vs);                    // CHECK: or <8 x i16>
-  res_vs  = vec_or(vs, vbs);                    // CHECK: or <8 x i16>
-  res_vus = vec_or(vus, vus);                   // CHECK: or <8 x i16>
-  res_vus = vec_or(vbs, vus);                   // CHECK: or <8 x i16>
-  res_vus = vec_or(vus, vbs);                   // CHECK: or <8 x i16>
-  res_vbs = vec_or(vbs, vbs);                   // CHECK: or <8 x i16>
-  res_vi  = vec_or(vi, vi);                     // CHECK: or <4 x i32>
-  res_vi  = vec_or(vbi, vi);                    // CHECK: or <4 x i32>
-  res_vi  = vec_or(vi, vbi);                    // CHECK: or <4 x i32>
-  res_vui = vec_or(vui, vui);                   // CHECK: or <4 x i32>
-  res_vui = vec_or(vbi, vui);                   // CHECK: or <4 x i32>
-  res_vui = vec_or(vui, vbi);                   // CHECK: or <4 x i32>
-  res_vbi = vec_or(vbi, vbi);                   // CHECK: or <4 x i32>
-  res_vf  = vec_or(vf, vf);                     // CHECK: or <4 x i32>
-  res_vf  = vec_or(vbi, vf);                    // CHECK: or <4 x i32>
-  res_vf  = vec_or(vf, vbi);                    // CHECK: or <4 x i32>
-  res_vsc = vec_vor(vsc, vsc);                  // CHECK: or <16 x i8>
-  res_vsc = vec_vor(vbc, vsc);                  // CHECK: or <16 x i8>
-  res_vsc = vec_vor(vsc, vbc);                  // CHECK: or <16 x i8>
-  res_vuc = vec_vor(vuc, vuc);                  // CHECK: or <16 x i8>
-  res_vuc = vec_vor(vbc, vuc);                  // CHECK: or <16 x i8>
-  res_vuc = vec_vor(vuc, vbc);                  // CHECK: or <16 x i8>
-  res_vbc = vec_vor(vbc, vbc);                  // CHECK: or <16 x i8>
-  res_vs  = vec_vor(vs, vs);                    // CHECK: or <8 x i16>
-  res_vs  = vec_vor(vbs, vs);                   // CHECK: or <8 x i16>
-  res_vs  = vec_vor(vs, vbs);                   // CHECK: or <8 x i16>
-  res_vus = vec_vor(vus, vus);                  // CHECK: or <8 x i16>
-  res_vus = vec_vor(vbs, vus);                  // CHECK: or <8 x i16>
-  res_vus = vec_vor(vus, vbs);                  // CHECK: or <8 x i16>
-  res_vbs = vec_vor(vbs, vbs);                  // CHECK: or <8 x i16>
-  res_vi  = vec_vor(vi, vi);                    // CHECK: or <4 x i32>
-  res_vi  = vec_vor(vbi, vi);                   // CHECK: or <4 x i32>
-  res_vi  = vec_vor(vi, vbi);                   // CHECK: or <4 x i32>
-  res_vui = vec_vor(vui, vui);                  // CHECK: or <4 x i32>
-  res_vui = vec_vor(vbi, vui);                  // CHECK: or <4 x i32>
-  res_vui = vec_vor(vui, vbi);                  // CHECK: or <4 x i32>
-  res_vbi = vec_vor(vbi, vbi);                  // CHECK: or <4 x i32>
-  res_vf  = vec_vor(vf, vf);                    // CHECK: or <4 x i32>
-  res_vf  = vec_vor(vbi, vf);                   // CHECK: or <4 x i32>
-  res_vf  = vec_vor(vf, vbi);                   // CHECK: or <4 x i32>
+  res_vsc = vec_or(vsc, vsc);
+// CHECK: or <16 x i8>
+// CHECK-LE: or <16 x i8>
+
+  res_vsc = vec_or(vbc, vsc);
+// CHECK: or <16 x i8>
+// CHECK-LE: or <16 x i8>
+
+  res_vsc = vec_or(vsc, vbc);
+// CHECK: or <16 x i8>
+// CHECK-LE: or <16 x i8>
+
+  res_vuc = vec_or(vuc, vuc);
+// CHECK: or <16 x i8>
+// CHECK-LE: or <16 x i8>
+
+  res_vuc = vec_or(vbc, vuc);
+// CHECK: or <16 x i8>
+// CHECK-LE: or <16 x i8>
+
+  res_vuc = vec_or(vuc, vbc);
+// CHECK: or <16 x i8>
+// CHECK-LE: or <16 x i8>
+
+  res_vbc = vec_or(vbc, vbc);
+// CHECK: or <16 x i8>
+// CHECK-LE: or <16 x i8>
+
+  res_vs  = vec_or(vs, vs);
+// CHECK: or <8 x i16>
+// CHECK-LE: or <8 x i16>
+
+  res_vs  = vec_or(vbs, vs);
+// CHECK: or <8 x i16>
+// CHECK-LE: or <8 x i16>
+
+  res_vs  = vec_or(vs, vbs);
+// CHECK: or <8 x i16>
+// CHECK-LE: or <8 x i16>
+
+  res_vus = vec_or(vus, vus);
+// CHECK: or <8 x i16>
+// CHECK-LE: or <8 x i16>
+
+  res_vus = vec_or(vbs, vus);
+// CHECK: or <8 x i16>
+// CHECK-LE: or <8 x i16>
+
+  res_vus = vec_or(vus, vbs);
+// CHECK: or <8 x i16>
+// CHECK-LE: or <8 x i16>
+
+  res_vbs = vec_or(vbs, vbs);
+// CHECK: or <8 x i16>
+// CHECK-LE: or <8 x i16>
+
+  res_vi  = vec_or(vi, vi);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vi  = vec_or(vbi, vi);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vi  = vec_or(vi, vbi);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vui = vec_or(vui, vui);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vui = vec_or(vbi, vui);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vui = vec_or(vui, vbi);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vbi = vec_or(vbi, vbi);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vf  = vec_or(vf, vf);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vf  = vec_or(vbi, vf);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vf  = vec_or(vf, vbi);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vsc = vec_vor(vsc, vsc);
+// CHECK: or <16 x i8>
+// CHECK-LE: or <16 x i8>
+
+  res_vsc = vec_vor(vbc, vsc);
+// CHECK: or <16 x i8>
+// CHECK-LE: or <16 x i8>
+
+  res_vsc = vec_vor(vsc, vbc);
+// CHECK: or <16 x i8>
+// CHECK-LE: or <16 x i8>
+
+  res_vuc = vec_vor(vuc, vuc);
+// CHECK: or <16 x i8>
+// CHECK-LE: or <16 x i8>
+
+  res_vuc = vec_vor(vbc, vuc);
+// CHECK: or <16 x i8>
+// CHECK-LE: or <16 x i8>
+
+  res_vuc = vec_vor(vuc, vbc);
+// CHECK: or <16 x i8>
+// CHECK-LE: or <16 x i8>
+
+  res_vbc = vec_vor(vbc, vbc);
+// CHECK: or <16 x i8>
+// CHECK-LE: or <16 x i8>
+
+  res_vs  = vec_vor(vs, vs);
+// CHECK: or <8 x i16>
+// CHECK-LE: or <8 x i16>
+
+  res_vs  = vec_vor(vbs, vs);
+// CHECK: or <8 x i16>
+// CHECK-LE: or <8 x i16>
+
+  res_vs  = vec_vor(vs, vbs);
+// CHECK: or <8 x i16>
+// CHECK-LE: or <8 x i16>
+
+  res_vus = vec_vor(vus, vus);
+// CHECK: or <8 x i16>
+// CHECK-LE: or <8 x i16>
+
+  res_vus = vec_vor(vbs, vus);
+// CHECK: or <8 x i16>
+// CHECK-LE: or <8 x i16>
+
+  res_vus = vec_vor(vus, vbs);
+// CHECK: or <8 x i16>
+// CHECK-LE: or <8 x i16>
+
+  res_vbs = vec_vor(vbs, vbs);
+// CHECK: or <8 x i16>
+// CHECK-LE: or <8 x i16>
+
+  res_vi  = vec_vor(vi, vi);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vi  = vec_vor(vbi, vi);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vi  = vec_vor(vi, vbi);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vui = vec_vor(vui, vui);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vui = vec_vor(vbi, vui);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vui = vec_vor(vui, vbi);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vbi = vec_vor(vbi, vbi);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vf  = vec_vor(vf, vf);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vf  = vec_vor(vbi, vf);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
+
+  res_vf  = vec_vor(vf, vbi);
+// CHECK: or <4 x i32>
+// CHECK-LE: or <4 x i32>
 
   /* vec_pack */
-  res_vsc = vec_pack(vs, vs);                   // CHECK: @llvm.ppc.altivec.vperm
-  res_vuc = vec_pack(vus, vus);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vbc = vec_pack(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vs  = vec_pack(vi, vi);                   // CHECK: @llvm.ppc.altivec.vperm
-  res_vus = vec_pack(vui, vui);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vbs = vec_pack(vbi, vbi);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vsc = vec_vpkuhum(vs, vs);                // CHECK: @llvm.ppc.altivec.vperm
-  res_vuc = vec_vpkuhum(vus, vus);              // CHECK: @llvm.ppc.altivec.vperm
-  res_vbc = vec_vpkuhum(vbs, vbs);              // CHECK: @llvm.ppc.altivec.vperm
-  res_vs  = vec_vpkuwum(vi, vi);                // CHECK: @llvm.ppc.altivec.vperm
-  res_vus = vec_vpkuwum(vui, vui);              // CHECK: @llvm.ppc.altivec.vperm
-  res_vbs = vec_vpkuwum(vbi, vbi);              // CHECK: @llvm.ppc.altivec.vperm
+  res_vsc = vec_pack(vs, vs);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vuc = vec_pack(vus, vus);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbc = vec_pack(vbs, vbs);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vs  = vec_pack(vi, vi);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vus = vec_pack(vui, vui);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbs = vec_pack(vbi, vbi);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vsc = vec_vpkuhum(vs, vs);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vuc = vec_vpkuhum(vus, vus);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbc = vec_vpkuhum(vbs, vbs);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vs  = vec_vpkuwum(vi, vi);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vus = vec_vpkuwum(vui, vui);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbs = vec_vpkuwum(vbi, vbi);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
   /* vec_packpx */
-  res_vp = vec_packpx(vui, vui);                // CHECK: @llvm.ppc.altivec.vpkpx
-  res_vp = vec_vpkpx(vui, vui);                 // CHECK: @llvm.ppc.altivec.vpkpx
+  res_vp = vec_packpx(vui, vui);
+// CHECK: @llvm.ppc.altivec.vpkpx
+// CHECK-LE: @llvm.ppc.altivec.vpkpx
+
+  res_vp = vec_vpkpx(vui, vui);
+// CHECK: @llvm.ppc.altivec.vpkpx
+// CHECK-LE: @llvm.ppc.altivec.vpkpx
 
   /* vec_packs */
-  res_vsc = vec_packs(vs, vs);                  // CHECK: @llvm.ppc.altivec.vpkshss
-  res_vuc = vec_packs(vus, vus);                // CHECK: @llvm.ppc.altivec.vpkuhus
-  res_vs  = vec_packs(vi, vi);                  // CHECK: @llvm.ppc.altivec.vpkswss
-  res_vus = vec_packs(vui, vui);                // CHECK: @llvm.ppc.altivec.vpkuwus
-  res_vsc = vec_vpkshss(vs, vs);                // CHECK: @llvm.ppc.altivec.vpkshss
-  res_vuc = vec_vpkuhus(vus, vus);              // CHECK: @llvm.ppc.altivec.vpkuhus
-  res_vs  = vec_vpkswss(vi, vi);                // CHECK: @llvm.ppc.altivec.vpkswss
-  res_vus = vec_vpkuwus(vui, vui);              // CHECK: @llvm.ppc.altivec.vpkuwus
+  res_vsc = vec_packs(vs, vs);
+// CHECK: @llvm.ppc.altivec.vpkshss
+// CHECK-LE: @llvm.ppc.altivec.vpkshss
+
+  res_vuc = vec_packs(vus, vus);
+// CHECK: @llvm.ppc.altivec.vpkuhus
+// CHECK-LE: @llvm.ppc.altivec.vpkuhus
+
+  res_vs  = vec_packs(vi, vi);
+// CHECK: @llvm.ppc.altivec.vpkswss
+// CHECK-LE: @llvm.ppc.altivec.vpkswss
+
+  res_vus = vec_packs(vui, vui);
+// CHECK: @llvm.ppc.altivec.vpkuwus
+// CHECK-LE: @llvm.ppc.altivec.vpkuwus
+
+  res_vsc = vec_vpkshss(vs, vs);
+// CHECK: @llvm.ppc.altivec.vpkshss
+// CHECK-LE: @llvm.ppc.altivec.vpkshss
+
+  res_vuc = vec_vpkuhus(vus, vus);
+// CHECK: @llvm.ppc.altivec.vpkuhus
+// CHECK-LE: @llvm.ppc.altivec.vpkuhus
+
+  res_vs  = vec_vpkswss(vi, vi);
+// CHECK: @llvm.ppc.altivec.vpkswss
+// CHECK-LE: @llvm.ppc.altivec.vpkswss
+
+  res_vus = vec_vpkuwus(vui, vui);
+// CHECK: @llvm.ppc.altivec.vpkuwus
+// CHECK-LE: @llvm.ppc.altivec.vpkuwus
 
   /* vec_packsu */
-  res_vuc = vec_packsu(vs, vs);                 // CHECK: @llvm.ppc.altivec.vpkshus
-  res_vuc = vec_packsu(vus, vus);               // CHECK: @llvm.ppc.altivec.vpkuhus
-  res_vus = vec_packsu(vi, vi);                 // CHECK: @llvm.ppc.altivec.vpkswus
-  res_vus = vec_packsu(vui, vui);               // CHECK: @llvm.ppc.altivec.vpkuwus
-  res_vuc = vec_vpkshus(vs, vs);                // CHECK: @llvm.ppc.altivec.vpkshus
-  res_vuc = vec_vpkshus(vus, vus);              // CHECK: @llvm.ppc.altivec.vpkuhus
-  res_vus = vec_vpkswus(vi, vi);                // CHECK: @llvm.ppc.altivec.vpkswus
-  res_vus = vec_vpkswus(vui, vui);              // CHECK: @llvm.ppc.altivec.vpkuwus
+  res_vuc = vec_packsu(vs, vs);
+// CHECK: @llvm.ppc.altivec.vpkshus
+// CHECK-LE: @llvm.ppc.altivec.vpkshus
+
+  res_vuc = vec_packsu(vus, vus);
+// CHECK: @llvm.ppc.altivec.vpkuhus
+// CHECK-LE: @llvm.ppc.altivec.vpkuhus
+
+  res_vus = vec_packsu(vi, vi);
+// CHECK: @llvm.ppc.altivec.vpkswus
+// CHECK-LE: @llvm.ppc.altivec.vpkswus
+
+  res_vus = vec_packsu(vui, vui);
+// CHECK: @llvm.ppc.altivec.vpkuwus
+// CHECK-LE: @llvm.ppc.altivec.vpkuwus
+
+  res_vuc = vec_vpkshus(vs, vs);
+// CHECK: @llvm.ppc.altivec.vpkshus
+// CHECK-LE: @llvm.ppc.altivec.vpkshus
+
+  res_vuc = vec_vpkshus(vus, vus);
+// CHECK: @llvm.ppc.altivec.vpkuhus
+// CHECK-LE: @llvm.ppc.altivec.vpkuhus
+
+  res_vus = vec_vpkswus(vi, vi);
+// CHECK: @llvm.ppc.altivec.vpkswus
+// CHECK-LE: @llvm.ppc.altivec.vpkswus
+
+  res_vus = vec_vpkswus(vui, vui);
+// CHECK: @llvm.ppc.altivec.vpkuwus
+// CHECK-LE: @llvm.ppc.altivec.vpkuwus
 
   /* vec_perm */
-  res_vsc = vec_perm(vsc, vsc, vuc);            // CHECK: @llvm.ppc.altivec.vperm
-  res_vuc = vec_perm(vuc, vuc, vuc);            // CHECK: @llvm.ppc.altivec.vperm
-  res_vbc = vec_perm(vbc, vbc, vuc);            // CHECK: @llvm.ppc.altivec.vperm
-  res_vs  = vec_perm(vs, vs, vuc);              // CHECK: @llvm.ppc.altivec.vperm
-  res_vus = vec_perm(vus, vus, vuc);            // CHECK: @llvm.ppc.altivec.vperm
-  res_vbs = vec_perm(vbs, vbs, vuc);            // CHECK: @llvm.ppc.altivec.vperm
-  res_vp  = vec_perm(vp, vp, vuc);              // CHECK: @llvm.ppc.altivec.vperm
-  res_vi  = vec_perm(vi, vi, vuc);              // CHECK: @llvm.ppc.altivec.vperm
-  res_vui = vec_perm(vui, vui, vuc);            // CHECK: @llvm.ppc.altivec.vperm
-  res_vbi = vec_perm(vbi, vbi, vuc);            // CHECK: @llvm.ppc.altivec.vperm
-  res_vf  = vec_perm(vf, vf, vuc);              // CHECK: @llvm.ppc.altivec.vperm
-  res_vsc = vec_vperm(vsc, vsc, vuc);           // CHECK: @llvm.ppc.altivec.vperm
-  res_vuc = vec_vperm(vuc, vuc, vuc);           // CHECK: @llvm.ppc.altivec.vperm
-  res_vbc = vec_vperm(vbc, vbc, vuc);           // CHECK: @llvm.ppc.altivec.vperm
-  res_vs  = vec_vperm(vs, vs, vuc);             // CHECK: @llvm.ppc.altivec.vperm
-  res_vus = vec_vperm(vus, vus, vuc);           // CHECK: @llvm.ppc.altivec.vperm
-  res_vbs = vec_vperm(vbs, vbs, vuc);           // CHECK: @llvm.ppc.altivec.vperm
-  res_vp  = vec_vperm(vp, vp, vuc);             // CHECK: @llvm.ppc.altivec.vperm
-  res_vi  = vec_vperm(vi, vi, vuc);             // CHECK: @llvm.ppc.altivec.vperm
-  res_vui = vec_vperm(vui, vui, vuc);           // CHECK: @llvm.ppc.altivec.vperm
-  res_vbi = vec_vperm(vbi, vbi, vuc);           // CHECK: @llvm.ppc.altivec.vperm
-  res_vf  = vec_vperm(vf, vf, vuc);             // CHECK: @llvm.ppc.altivec.vperm
+  res_vsc = vec_perm(vsc, vsc, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vuc = vec_perm(vuc, vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbc = vec_perm(vbc, vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vs  = vec_perm(vs, vs, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vus = vec_perm(vus, vus, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbs = vec_perm(vbs, vbs, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vp  = vec_perm(vp, vp, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vi  = vec_perm(vi, vi, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vui = vec_perm(vui, vui, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbi = vec_perm(vbi, vbi, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vf  = vec_perm(vf, vf, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vsc = vec_vperm(vsc, vsc, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vuc = vec_vperm(vuc, vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbc = vec_vperm(vbc, vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vs  = vec_vperm(vs, vs, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vus = vec_vperm(vus, vus, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbs = vec_vperm(vbs, vbs, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vp  = vec_vperm(vp, vp, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vi  = vec_vperm(vi, vi, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vui = vec_vperm(vui, vui, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbi = vec_vperm(vbi, vbi, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vf  = vec_vperm(vf, vf, vuc);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
   /* vec_re */
-  res_vf = vec_re(vf);                          // CHECK: @llvm.ppc.altivec.vrefp
-  res_vf = vec_vrefp(vf);                       // CHECK: @llvm.ppc.altivec.vrefp
+  res_vf = vec_re(vf);
+// CHECK: @llvm.ppc.altivec.vrefp
+// CHECK-LE: @llvm.ppc.altivec.vrefp
+
+  res_vf = vec_vrefp(vf);
+// CHECK: @llvm.ppc.altivec.vrefp
+// CHECK-LE: @llvm.ppc.altivec.vrefp
 
   /* vec_rl */
-  res_vsc = vec_rl(vsc, vuc);                   // CHECK: @llvm.ppc.altivec.vrlb
-  res_vuc = vec_rl(vuc, vuc);                   // CHECK: @llvm.ppc.altivec.vrlb
-  res_vs  = vec_rl(vs, vus);                    // CHECK: @llvm.ppc.altivec.vrlh
-  res_vus = vec_rl(vus, vus);                   // CHECK: @llvm.ppc.altivec.vrlh
-  res_vi  = vec_rl(vi, vui);                    // CHECK: @llvm.ppc.altivec.vrlw
-  res_vui = vec_rl(vui, vui);                   // CHECK: @llvm.ppc.altivec.vrlw
-  res_vsc = vec_vrlb(vsc, vuc);                 // CHECK: @llvm.ppc.altivec.vrlb
-  res_vuc = vec_vrlb(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vrlb
-  res_vs  = vec_vrlh(vs, vus);                  // CHECK: @llvm.ppc.altivec.vrlh
-  res_vus = vec_vrlh(vus, vus);                 // CHECK: @llvm.ppc.altivec.vrlh
-  res_vi  = vec_vrlw(vi, vui);                  // CHECK: @llvm.ppc.altivec.vrlw
-  res_vui = vec_vrlw(vui, vui);                 // CHECK: @llvm.ppc.altivec.vrlw
+  res_vsc = vec_rl(vsc, vuc);
+// CHECK: @llvm.ppc.altivec.vrlb
+// CHECK-LE: @llvm.ppc.altivec.vrlb
+
+  res_vuc = vec_rl(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vrlb
+// CHECK-LE: @llvm.ppc.altivec.vrlb
+
+  res_vs  = vec_rl(vs, vus);
+// CHECK: @llvm.ppc.altivec.vrlh
+// CHECK-LE: @llvm.ppc.altivec.vrlh
+
+  res_vus = vec_rl(vus, vus);
+// CHECK: @llvm.ppc.altivec.vrlh
+// CHECK-LE: @llvm.ppc.altivec.vrlh
+
+  res_vi  = vec_rl(vi, vui);
+// CHECK: @llvm.ppc.altivec.vrlw
+// CHECK-LE: @llvm.ppc.altivec.vrlw
+
+  res_vui = vec_rl(vui, vui);
+// CHECK: @llvm.ppc.altivec.vrlw
+// CHECK-LE: @llvm.ppc.altivec.vrlw
+
+  res_vsc = vec_vrlb(vsc, vuc);
+// CHECK: @llvm.ppc.altivec.vrlb
+// CHECK-LE: @llvm.ppc.altivec.vrlb
+
+  res_vuc = vec_vrlb(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vrlb
+// CHECK-LE: @llvm.ppc.altivec.vrlb
+
+  res_vs  = vec_vrlh(vs, vus);
+// CHECK: @llvm.ppc.altivec.vrlh
+// CHECK-LE: @llvm.ppc.altivec.vrlh
+
+  res_vus = vec_vrlh(vus, vus);
+// CHECK: @llvm.ppc.altivec.vrlh
+// CHECK-LE: @llvm.ppc.altivec.vrlh
+
+  res_vi  = vec_vrlw(vi, vui);
+// CHECK: @llvm.ppc.altivec.vrlw
+// CHECK-LE: @llvm.ppc.altivec.vrlw
+
+  res_vui = vec_vrlw(vui, vui);
+// CHECK: @llvm.ppc.altivec.vrlw
+// CHECK-LE: @llvm.ppc.altivec.vrlw
 
   /* vec_round */
-  res_vf = vec_round(vf);                       // CHECK: @llvm.ppc.altivec.vrfin
-  res_vf = vec_vrfin(vf);                       // CHECK: @llvm.ppc.altivec.vrfin
+  res_vf = vec_round(vf);
+// CHECK: @llvm.ppc.altivec.vrfin
+// CHECK-LE: @llvm.ppc.altivec.vrfin
+
+  res_vf = vec_vrfin(vf);
+// CHECK: @llvm.ppc.altivec.vrfin
+// CHECK-LE: @llvm.ppc.altivec.vrfin
 
   /* vec_rsqrte */
-  res_vf = vec_rsqrte(vf);                      // CHECK: @llvm.ppc.altivec.vrsqrtefp
-  res_vf = vec_vrsqrtefp(vf);                   // CHECK: @llvm.ppc.altivec.vrsqrtefp
+  res_vf = vec_rsqrte(vf);
+// CHECK: @llvm.ppc.altivec.vrsqrtefp
+// CHECK-LE: @llvm.ppc.altivec.vrsqrtefp
+
+  res_vf = vec_vrsqrtefp(vf);
+// CHECK: @llvm.ppc.altivec.vrsqrtefp
+// CHECK-LE: @llvm.ppc.altivec.vrsqrtefp
 
   /* vec_sel */
-  res_vsc = vec_sel(vsc, vsc, vuc);             // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: or <16 x i8>
+  res_vsc = vec_sel(vsc, vsc, vuc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: or <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: or <16 x i8>
 
-  res_vsc = vec_sel(vsc, vsc, vbc);             // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: or <16 x i8>
+  res_vsc = vec_sel(vsc, vsc, vbc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: or <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: or <16 x i8>
 
-  res_vuc = vec_sel(vuc, vuc, vuc);             // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: or <16 x i8>
+  res_vuc = vec_sel(vuc, vuc, vuc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: or <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: or <16 x i8>
 
-  res_vuc = vec_sel(vuc, vuc, vbc);             // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: or <16 x i8>
+  res_vuc = vec_sel(vuc, vuc, vbc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: or <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: or <16 x i8>
 
-  res_vbc = vec_sel(vbc, vbc, vuc);             // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: or <16 x i8>
+  res_vbc = vec_sel(vbc, vbc, vuc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: or <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: or <16 x i8>
 
-  res_vbc = vec_sel(vbc, vbc, vbc);             // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: or <16 x i8>
+  res_vbc = vec_sel(vbc, vbc, vbc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: or <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: or <16 x i8>
 
-  res_vs  = vec_sel(vs, vs, vus);               // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: or <8 x i16>
+  res_vs  = vec_sel(vs, vs, vus);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: or <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: or <8 x i16>
 
-  res_vs  = vec_sel(vs, vs, vbs);               // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: or <8 x i16>
+  res_vs  = vec_sel(vs, vs, vbs);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: or <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: or <8 x i16>
 
-  res_vus = vec_sel(vus, vus, vus);             // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: or <8 x i16>
+  res_vus = vec_sel(vus, vus, vus);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: or <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: or <8 x i16>
 
-  res_vus = vec_sel(vus, vus, vbs);             // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: or <8 x i16>
+  res_vus = vec_sel(vus, vus, vbs);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: or <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: or <8 x i16>
 
-  res_vbs = vec_sel(vbs, vbs, vus);             // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: or <8 x i16>
+  res_vbs = vec_sel(vbs, vbs, vus);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: or <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: or <8 x i16>
 
-  res_vbs = vec_sel(vbs, vbs, vbs);             // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: or <8 x i16>
+  res_vbs = vec_sel(vbs, vbs, vbs);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: or <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: or <8 x i16>
 
-  res_vi  = vec_sel(vi, vi, vui);               // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: or <4 x i32>
+  res_vi  = vec_sel(vi, vi, vui);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: or <4 x i32>
 
-  res_vi  = vec_sel(vi, vi, vbi);               // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: or <4 x i32>
+  res_vi  = vec_sel(vi, vi, vbi);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: or <4 x i32>
 
-  res_vui = vec_sel(vui, vui, vui);             // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: or <4 x i32>
+  res_vui = vec_sel(vui, vui, vui);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: or <4 x i32>
 
-  res_vui = vec_sel(vui, vui, vbi);             // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: or <4 x i32>
+  res_vui = vec_sel(vui, vui, vbi);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: or <4 x i32>
 
-  res_vbi = vec_sel(vbi, vbi, vui);             // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: or <4 x i32>
+  res_vbi = vec_sel(vbi, vbi, vui);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: or <4 x i32>
 
-  res_vbi = vec_sel(vbi, vbi, vbi);             // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: or <4 x i32>
+  res_vbi = vec_sel(vbi, vbi, vbi);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: or <4 x i32>
 
-  res_vf  = vec_sel(vf, vf, vui);               // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: or <4 x i32>
+  res_vf  = vec_sel(vf, vf, vui);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: or <4 x i32>
 
-  res_vf  = vec_sel(vf, vf, vbi);               // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: or <4 x i32>
+  res_vf  = vec_sel(vf, vf, vbi);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: or <4 x i32>
 
-  res_vsc = vec_vsel(vsc, vsc, vuc);            // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: or <16 x i8>
+  res_vsc = vec_vsel(vsc, vsc, vuc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: or <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: or <16 x i8>
 
-  res_vsc = vec_vsel(vsc, vsc, vbc);            // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: or <16 x i8>
+  res_vsc = vec_vsel(vsc, vsc, vbc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: or <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: or <16 x i8>
 
-  res_vuc = vec_vsel(vuc, vuc, vuc);            // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: or <16 x i8>
+  res_vuc = vec_vsel(vuc, vuc, vuc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: or <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: or <16 x i8>
 
-  res_vuc = vec_vsel(vuc, vuc, vbc);            // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: or <16 x i8>
+  res_vuc = vec_vsel(vuc, vuc, vbc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: or <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: or <16 x i8>
 
-  res_vbc = vec_vsel(vbc, vbc, vuc);            // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: or <16 x i8>
+  res_vbc = vec_vsel(vbc, vbc, vuc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: or <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: or <16 x i8>
 
-  res_vbc = vec_vsel(vbc, vbc, vbc);            // CHECK: xor <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: and <16 x i8>
-                                                // CHECK: or <16 x i8>
+  res_vbc = vec_vsel(vbc, vbc, vbc);
+// CHECK: xor <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: and <16 x i8>
+// CHECK: or <16 x i8>
+// CHECK-LE: xor <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: and <16 x i8>
+// CHECK-LE: or <16 x i8>
 
-  res_vs  = vec_vsel(vs, vs, vus);              // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: or <8 x i16>
+  res_vs  = vec_vsel(vs, vs, vus);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: or <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: or <8 x i16>
 
-  res_vs  = vec_vsel(vs, vs, vbs);              // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: or <8 x i16>
+  res_vs  = vec_vsel(vs, vs, vbs);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: or <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: or <8 x i16>
 
-  res_vus = vec_vsel(vus, vus, vus);            // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: or <8 x i16>
+  res_vus = vec_vsel(vus, vus, vus);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: or <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: or <8 x i16>
 
-  res_vus = vec_vsel(vus, vus, vbs);            // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: or <8 x i16>
+  res_vus = vec_vsel(vus, vus, vbs);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: or <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: or <8 x i16>
 
-  res_vbs = vec_vsel(vbs, vbs, vus);            // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: or <8 x i16>
+  res_vbs = vec_vsel(vbs, vbs, vus);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: or <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: or <8 x i16>
 
-  res_vbs = vec_vsel(vbs, vbs, vbs);            // CHECK: xor <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: and <8 x i16>
-                                                // CHECK: or <8 x i16>
+  res_vbs = vec_vsel(vbs, vbs, vbs);
+// CHECK: xor <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: and <8 x i16>
+// CHECK: or <8 x i16>
+// CHECK-LE: xor <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: and <8 x i16>
+// CHECK-LE: or <8 x i16>
 
-  res_vi  = vec_vsel(vi, vi, vui);              // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: or <4 x i32>
+  res_vi  = vec_vsel(vi, vi, vui);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: or <4 x i32>
 
-  res_vi  = vec_vsel(vi, vi, vbi);              // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: or <4 x i32>
+  res_vi  = vec_vsel(vi, vi, vbi);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: or <4 x i32>
 
-  res_vui = vec_vsel(vui, vui, vui);            // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: or <4 x i32>
+  res_vui = vec_vsel(vui, vui, vui);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: or <4 x i32>
 
-  res_vui = vec_vsel(vui, vui, vbi);            // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: or <4 x i32>
+  res_vui = vec_vsel(vui, vui, vbi);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: or <4 x i32>
 
-  res_vbi = vec_vsel(vbi, vbi, vui);            // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: or <4 x i32>
+  res_vbi = vec_vsel(vbi, vbi, vui);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: or <4 x i32>
 
-  res_vbi = vec_vsel(vbi, vbi, vbi);            // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: or <4 x i32>
+  res_vbi = vec_vsel(vbi, vbi, vbi);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: or <4 x i32>
 
-  res_vf  = vec_vsel(vf, vf, vui);              // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: or <4 x i32>
+  res_vf  = vec_vsel(vf, vf, vui);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: or <4 x i32>
 
-  res_vf  = vec_vsel(vf, vf, vbi);              // CHECK: xor <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: and <4 x i32>
-                                                // CHECK: or <4 x i32>
+  res_vf  = vec_vsel(vf, vf, vbi);
+// CHECK: xor <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: and <4 x i32>
+// CHECK: or <4 x i32>
+// CHECK-LE: xor <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: and <4 x i32>
+// CHECK-LE: or <4 x i32>
 
   /* vec_sl */
-  res_vsc = vec_sl(vsc, vuc);                   // CHECK: shl <16 x i8>
-  res_vuc = vec_sl(vuc, vuc);                   // CHECK: shl <16 x i8>
-  res_vs  = vec_sl(vs, vus);                    // CHECK: shl <8 x i16>
-  res_vus = vec_sl(vus, vus);                   // CHECK: shl <8 x i16>
-  res_vi  = vec_sl(vi, vui);                    // CHECK: shl <4 x i32>
-  res_vui = vec_sl(vui, vui);                   // CHECK: shl <4 x i32>
-  res_vsc = vec_vslb(vsc, vuc);                 // CHECK: shl <16 x i8>
-  res_vuc = vec_vslb(vuc, vuc);                 // CHECK: shl <16 x i8>
-  res_vs  = vec_vslh(vs, vus);                  // CHECK: shl <8 x i16>
-  res_vus = vec_vslh(vus, vus);                 // CHECK: shl <8 x i16>
-  res_vi  = vec_vslw(vi, vui);                  // CHECK: shl <4 x i32>
-  res_vui = vec_vslw(vui, vui);                 // CHECK: shl <4 x i32>
+  res_vsc = vec_sl(vsc, vuc);
+// CHECK: shl <16 x i8>
+// CHECK-LE: shl <16 x i8>
+
+  res_vuc = vec_sl(vuc, vuc);
+// CHECK: shl <16 x i8>
+// CHECK-LE: shl <16 x i8>
+
+  res_vs  = vec_sl(vs, vus);
+// CHECK: shl <8 x i16>
+// CHECK-LE: shl <8 x i16>
+
+  res_vus = vec_sl(vus, vus);
+// CHECK: shl <8 x i16>
+// CHECK-LE: shl <8 x i16>
+
+  res_vi  = vec_sl(vi, vui);
+// CHECK: shl <4 x i32>
+// CHECK-LE: shl <4 x i32>
+
+  res_vui = vec_sl(vui, vui);
+// CHECK: shl <4 x i32>
+// CHECK-LE: shl <4 x i32>
+
+  res_vsc = vec_vslb(vsc, vuc);
+// CHECK: shl <16 x i8>
+// CHECK-LE: shl <16 x i8>
+
+  res_vuc = vec_vslb(vuc, vuc);
+// CHECK: shl <16 x i8>
+// CHECK-LE: shl <16 x i8>
+
+  res_vs  = vec_vslh(vs, vus);
+// CHECK: shl <8 x i16>
+// CHECK-LE: shl <8 x i16>
+
+  res_vus = vec_vslh(vus, vus);
+// CHECK: shl <8 x i16>
+// CHECK-LE: shl <8 x i16>
+
+  res_vi  = vec_vslw(vi, vui);
+// CHECK: shl <4 x i32>
+// CHECK-LE: shl <4 x i32>
+
+  res_vui = vec_vslw(vui, vui);
+// CHECK: shl <4 x i32>
+// CHECK-LE: shl <4 x i32>
 
   /* vec_sld */
-  res_vsc = vec_sld(vsc, vsc, 0);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vuc = vec_sld(vuc, vuc, 0);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vs  = vec_sld(vs, vs, 0);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vus = vec_sld(vus, vus, 0);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vp  = vec_sld(vp, vp, 0);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vi  = vec_sld(vi, vi, 0);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vui = vec_sld(vui, vui, 0);               // CHECK: @llvm.ppc.altivec.vperm
-  res_vf  = vec_sld(vf, vf, 0);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vsc = vec_vsldoi(vsc, vsc, 0);            // CHECK: @llvm.ppc.altivec.vperm
-  res_vuc = vec_vsldoi(vuc, vuc, 0);            // CHECK: @llvm.ppc.altivec.vperm
-  res_vs  = vec_vsldoi(vs, vs, 0);              // CHECK: @llvm.ppc.altivec.vperm
-  res_vus = vec_vsldoi(vus, vus, 0);            // CHECK: @llvm.ppc.altivec.vperm
-  res_vp  = vec_vsldoi(vp, vp, 0);              // CHECK: @llvm.ppc.altivec.vperm
-  res_vi  = vec_vsldoi(vi, vi, 0);              // CHECK: @llvm.ppc.altivec.vperm
-  res_vui = vec_vsldoi(vui, vui, 0);            // CHECK: @llvm.ppc.altivec.vperm
-  res_vf  = vec_vsldoi(vf, vf, 0);              // CHECK: @llvm.ppc.altivec.vperm
+  res_vsc = vec_sld(vsc, vsc, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vuc = vec_sld(vuc, vuc, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vs  = vec_sld(vs, vs, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vus = vec_sld(vus, vus, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vp  = vec_sld(vp, vp, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vi  = vec_sld(vi, vi, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vui = vec_sld(vui, vui, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vf  = vec_sld(vf, vf, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vsc = vec_vsldoi(vsc, vsc, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vuc = vec_vsldoi(vuc, vuc, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vs  = vec_vsldoi(vs, vs, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vus = vec_vsldoi(vus, vus, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vp  = vec_vsldoi(vp, vp, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vi  = vec_vsldoi(vi, vi, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vui = vec_vsldoi(vui, vui, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vf  = vec_vsldoi(vf, vf, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
   /* vec_sll */
-  res_vsc = vec_sll(vsc, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vsc = vec_sll(vsc, vus);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vsc = vec_sll(vsc, vui);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vuc = vec_sll(vuc, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vuc = vec_sll(vuc, vus);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vuc = vec_sll(vuc, vui);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vbc = vec_sll(vbc, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vbc = vec_sll(vbc, vus);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vbc = vec_sll(vbc, vui);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vs  = vec_sll(vs, vuc);                   // CHECK: @llvm.ppc.altivec.vsl
-  res_vs  = vec_sll(vs, vus);                   // CHECK: @llvm.ppc.altivec.vsl
-  res_vs  = vec_sll(vs, vui);                   // CHECK: @llvm.ppc.altivec.vsl
-  res_vus = vec_sll(vus, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vus = vec_sll(vus, vus);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vus = vec_sll(vus, vui);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vbs = vec_sll(vbs, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vbs = vec_sll(vbs, vus);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vbs = vec_sll(vbs, vui);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vp  = vec_sll(vp, vuc);                   // CHECK: @llvm.ppc.altivec.vsl
-  res_vp  = vec_sll(vp, vus);                   // CHECK: @llvm.ppc.altivec.vsl
-  res_vp  = vec_sll(vp, vui);                   // CHECK: @llvm.ppc.altivec.vsl
-  res_vi  = vec_sll(vi, vuc);                   // CHECK: @llvm.ppc.altivec.vsl
-  res_vi  = vec_sll(vi, vus);                   // CHECK: @llvm.ppc.altivec.vsl
-  res_vi  = vec_sll(vi, vui);                   // CHECK: @llvm.ppc.altivec.vsl
-  res_vui = vec_sll(vui, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vui = vec_sll(vui, vus);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vui = vec_sll(vui, vui);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vbi = vec_sll(vbi, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vbi = vec_sll(vbi, vus);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vbi = vec_sll(vbi, vui);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vsc = vec_vsl(vsc, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vsc = vec_vsl(vsc, vus);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vsc = vec_vsl(vsc, vui);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vuc = vec_vsl(vuc, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vuc = vec_vsl(vuc, vus);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vuc = vec_vsl(vuc, vui);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vbc = vec_vsl(vbc, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vbc = vec_vsl(vbc, vus);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vbc = vec_vsl(vbc, vui);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vs  = vec_vsl(vs, vuc);                   // CHECK: @llvm.ppc.altivec.vsl
-  res_vs  = vec_vsl(vs, vus);                   // CHECK: @llvm.ppc.altivec.vsl
-  res_vs  = vec_vsl(vs, vui);                   // CHECK: @llvm.ppc.altivec.vsl
-  res_vus = vec_vsl(vus, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vus = vec_vsl(vus, vus);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vus = vec_vsl(vus, vui);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vbs = vec_vsl(vbs, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vbs = vec_vsl(vbs, vus);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vbs = vec_vsl(vbs, vui);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vp  = vec_vsl(vp, vuc);                   // CHECK: @llvm.ppc.altivec.vsl
-  res_vp  = vec_vsl(vp, vus);                   // CHECK: @llvm.ppc.altivec.vsl
-  res_vp  = vec_vsl(vp, vui);                   // CHECK: @llvm.ppc.altivec.vsl
-  res_vi  = vec_vsl(vi, vuc);                   // CHECK: @llvm.ppc.altivec.vsl
-  res_vi  = vec_vsl(vi, vus);                   // CHECK: @llvm.ppc.altivec.vsl
-  res_vi  = vec_vsl(vi, vui);                   // CHECK: @llvm.ppc.altivec.vsl
-  res_vui = vec_vsl(vui, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vui = vec_vsl(vui, vus);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vui = vec_vsl(vui, vui);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vbi = vec_vsl(vbi, vuc);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vbi = vec_vsl(vbi, vus);                  // CHECK: @llvm.ppc.altivec.vsl
-  res_vbi = vec_vsl(vbi, vui);                  // CHECK: @llvm.ppc.altivec.vsl
+  res_vsc = vec_sll(vsc, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vsc = vec_sll(vsc, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vsc = vec_sll(vsc, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vuc = vec_sll(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vuc = vec_sll(vuc, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vuc = vec_sll(vuc, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vbc = vec_sll(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vbc = vec_sll(vbc, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vbc = vec_sll(vbc, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vs  = vec_sll(vs, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vs  = vec_sll(vs, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vs  = vec_sll(vs, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vus = vec_sll(vus, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vus = vec_sll(vus, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vus = vec_sll(vus, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vbs = vec_sll(vbs, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vbs = vec_sll(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vbs = vec_sll(vbs, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vp  = vec_sll(vp, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vp  = vec_sll(vp, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vp  = vec_sll(vp, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vi  = vec_sll(vi, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vi  = vec_sll(vi, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vi  = vec_sll(vi, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vui = vec_sll(vui, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vui = vec_sll(vui, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vui = vec_sll(vui, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vbi = vec_sll(vbi, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vbi = vec_sll(vbi, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vbi = vec_sll(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vsc = vec_vsl(vsc, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vsc = vec_vsl(vsc, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vsc = vec_vsl(vsc, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vuc = vec_vsl(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vuc = vec_vsl(vuc, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vuc = vec_vsl(vuc, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vbc = vec_vsl(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vbc = vec_vsl(vbc, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vbc = vec_vsl(vbc, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vs  = vec_vsl(vs, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vs  = vec_vsl(vs, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vs  = vec_vsl(vs, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vus = vec_vsl(vus, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vus = vec_vsl(vus, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vus = vec_vsl(vus, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vbs = vec_vsl(vbs, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vbs = vec_vsl(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vbs = vec_vsl(vbs, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vp  = vec_vsl(vp, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vp  = vec_vsl(vp, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vp  = vec_vsl(vp, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vi  = vec_vsl(vi, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vi  = vec_vsl(vi, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vi  = vec_vsl(vi, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vui = vec_vsl(vui, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vui = vec_vsl(vui, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vui = vec_vsl(vui, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vbi = vec_vsl(vbi, vuc);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vbi = vec_vsl(vbi, vus);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
+
+  res_vbi = vec_vsl(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vsl
+// CHECK-LE: @llvm.ppc.altivec.vsl
 
   /* vec_slo */
-  res_vsc = vec_slo(vsc, vsc);                  // CHECK: @llvm.ppc.altivec.vslo
-  res_vsc = vec_slo(vsc, vuc);                  // CHECK: @llvm.ppc.altivec.vslo
-  res_vuc = vec_slo(vuc, vsc);                  // CHECK: @llvm.ppc.altivec.vslo
-  res_vuc = vec_slo(vuc, vuc);                  // CHECK: @llvm.ppc.altivec.vslo
-  res_vs  = vec_slo(vs, vsc);                   // CHECK: @llvm.ppc.altivec.vslo
-  res_vs  = vec_slo(vs, vuc);                   // CHECK: @llvm.ppc.altivec.vslo
-  res_vus = vec_slo(vus, vsc);                  // CHECK: @llvm.ppc.altivec.vslo
-  res_vus = vec_slo(vus, vuc);                  // CHECK: @llvm.ppc.altivec.vslo
-  res_vp  = vec_slo(vp, vsc);                   // CHECK: @llvm.ppc.altivec.vslo
-  res_vp  = vec_slo(vp, vuc);                   // CHECK: @llvm.ppc.altivec.vslo
-  res_vi  = vec_slo(vi, vsc);                   // CHECK: @llvm.ppc.altivec.vslo
-  res_vi  = vec_slo(vi, vuc);                   // CHECK: @llvm.ppc.altivec.vslo
-  res_vui = vec_slo(vui, vsc);                  // CHECK: @llvm.ppc.altivec.vslo
-  res_vui = vec_slo(vui, vuc);                  // CHECK: @llvm.ppc.altivec.vslo
-  res_vf  = vec_slo(vf, vsc);                   // CHECK: @llvm.ppc.altivec.vslo
-  res_vf  = vec_slo(vf, vuc);                   // CHECK: @llvm.ppc.altivec.vslo
-  res_vsc = vec_vslo(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vslo
-  res_vsc = vec_vslo(vsc, vuc);                 // CHECK: @llvm.ppc.altivec.vslo
-  res_vuc = vec_vslo(vuc, vsc);                 // CHECK: @llvm.ppc.altivec.vslo
-  res_vuc = vec_vslo(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vslo
-  res_vs  = vec_vslo(vs, vsc);                  // CHECK: @llvm.ppc.altivec.vslo
-  res_vs  = vec_vslo(vs, vuc);                  // CHECK: @llvm.ppc.altivec.vslo
-  res_vus = vec_vslo(vus, vsc);                 // CHECK: @llvm.ppc.altivec.vslo
-  res_vus = vec_vslo(vus, vuc);                 // CHECK: @llvm.ppc.altivec.vslo
-  res_vp  = vec_vslo(vp, vsc);                  // CHECK: @llvm.ppc.altivec.vslo
-  res_vp  = vec_vslo(vp, vuc);                  // CHECK: @llvm.ppc.altivec.vslo
-  res_vi  = vec_vslo(vi, vsc);                  // CHECK: @llvm.ppc.altivec.vslo
-  res_vi  = vec_vslo(vi, vuc);                  // CHECK: @llvm.ppc.altivec.vslo
-  res_vui = vec_vslo(vui, vsc);                 // CHECK: @llvm.ppc.altivec.vslo
-  res_vui = vec_vslo(vui, vuc);                 // CHECK: @llvm.ppc.altivec.vslo
-  res_vf  = vec_vslo(vf, vsc);                  // CHECK: @llvm.ppc.altivec.vslo
-  res_vf  = vec_vslo(vf, vuc);                  // CHECK: @llvm.ppc.altivec.vslo
+  res_vsc = vec_slo(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vsc = vec_slo(vsc, vuc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vuc = vec_slo(vuc, vsc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vuc = vec_slo(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vs  = vec_slo(vs, vsc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vs  = vec_slo(vs, vuc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vus = vec_slo(vus, vsc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vus = vec_slo(vus, vuc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vp  = vec_slo(vp, vsc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vp  = vec_slo(vp, vuc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vi  = vec_slo(vi, vsc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vi  = vec_slo(vi, vuc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vui = vec_slo(vui, vsc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vui = vec_slo(vui, vuc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vf  = vec_slo(vf, vsc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vf  = vec_slo(vf, vuc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vsc = vec_vslo(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vsc = vec_vslo(vsc, vuc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vuc = vec_vslo(vuc, vsc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vuc = vec_vslo(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vs  = vec_vslo(vs, vsc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vs  = vec_vslo(vs, vuc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vus = vec_vslo(vus, vsc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vus = vec_vslo(vus, vuc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vp  = vec_vslo(vp, vsc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vp  = vec_vslo(vp, vuc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vi  = vec_vslo(vi, vsc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vi  = vec_vslo(vi, vuc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vui = vec_vslo(vui, vsc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vui = vec_vslo(vui, vuc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vf  = vec_vslo(vf, vsc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
+
+  res_vf  = vec_vslo(vf, vuc);
+// CHECK: @llvm.ppc.altivec.vslo
+// CHECK-LE: @llvm.ppc.altivec.vslo
 
   /* vec_splat */
-  res_vsc = vec_splat(vsc, 0);                  // CHECK: @llvm.ppc.altivec.vperm
-  res_vuc = vec_splat(vuc, 0);                  // CHECK: @llvm.ppc.altivec.vperm
-  res_vbc = vec_splat(vbc, 0);                  // CHECK: @llvm.ppc.altivec.vperm
-  res_vs  = vec_splat(vs, 0);                   // CHECK: @llvm.ppc.altivec.vperm
-  res_vus = vec_splat(vus, 0);                  // CHECK: @llvm.ppc.altivec.vperm
-  res_vbs = vec_splat(vbs, 0);                  // CHECK: @llvm.ppc.altivec.vperm
-  res_vp  = vec_splat(vp, 0);                   // CHECK: @llvm.ppc.altivec.vperm
-  res_vi  = vec_splat(vi, 0);                   // CHECK: @llvm.ppc.altivec.vperm
-  res_vui = vec_splat(vui, 0);                  // CHECK: @llvm.ppc.altivec.vperm
-  res_vbi = vec_splat(vbi, 0);                  // CHECK: @llvm.ppc.altivec.vperm
-  res_vf  = vec_splat(vf, 0);                   // CHECK: @llvm.ppc.altivec.vperm
-  res_vsc = vec_vspltb(vsc, 0);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vuc = vec_vspltb(vuc, 0);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vbc = vec_vspltb(vbc, 0);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vs  = vec_vsplth(vs, 0);                  // CHECK: @llvm.ppc.altivec.vperm
-  res_vus = vec_vsplth(vus, 0);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vbs = vec_vsplth(vbs, 0);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vp  = vec_vsplth(vp, 0);                  // CHECK: @llvm.ppc.altivec.vperm
-  res_vi  = vec_vspltw(vi, 0);                  // CHECK: @llvm.ppc.altivec.vperm
-  res_vui = vec_vspltw(vui, 0);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vbi = vec_vspltw(vbi, 0);                 // CHECK: @llvm.ppc.altivec.vperm
-  res_vf  = vec_vspltw(vf, 0);                  // CHECK: @llvm.ppc.altivec.vperm
+  res_vsc = vec_splat(vsc, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vuc = vec_splat(vuc, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbc = vec_splat(vbc, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vs  = vec_splat(vs, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vus = vec_splat(vus, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbs = vec_splat(vbs, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vp  = vec_splat(vp, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vi  = vec_splat(vi, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vui = vec_splat(vui, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbi = vec_splat(vbi, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vf  = vec_splat(vf, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vsc = vec_vspltb(vsc, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vuc = vec_vspltb(vuc, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbc = vec_vspltb(vbc, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vs  = vec_vsplth(vs, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vus = vec_vsplth(vus, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbs = vec_vsplth(vbs, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vp  = vec_vsplth(vp, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vi  = vec_vspltw(vi, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vui = vec_vspltw(vui, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vbi = vec_vspltw(vbi, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vf  = vec_vspltw(vf, 0);
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
   /* vec_splat_s8 */
   res_vsc = vec_splat_s8(0x09);                 // TODO: add check
@@ -1329,1729 +3801,4715 @@
   res_vui = vec_splat_u32(0x09);                // TODO: add check
 
   /* vec_sr */
-  res_vsc = vec_sr(vsc, vuc);                   // CHECK: shr <16 x i8>
-  res_vuc = vec_sr(vuc, vuc);                   // CHECK: shr <16 x i8>
-  res_vs  = vec_sr(vs, vus);                    // CHECK: shr <8 x i16>
-  res_vus = vec_sr(vus, vus);                   // CHECK: shr <8 x i16>
-  res_vi  = vec_sr(vi, vui);                    // CHECK: shr <4 x i32>
-  res_vui = vec_sr(vui, vui);                   // CHECK: shr <4 x i32>
-  res_vsc = vec_vsrb(vsc, vuc);                 // CHECK: shr <16 x i8>
-  res_vuc = vec_vsrb(vuc, vuc);                 // CHECK: shr <16 x i8>
-  res_vs  = vec_vsrh(vs, vus);                  // CHECK: shr <8 x i16>
-  res_vus = vec_vsrh(vus, vus);                 // CHECK: shr <8 x i16>
-  res_vi  = vec_vsrw(vi, vui);                  // CHECK: shr <4 x i32>
-  res_vui = vec_vsrw(vui, vui);                 // CHECK: shr <4 x i32>
+  res_vsc = vec_sr(vsc, vuc);
+// CHECK: shr <16 x i8>
+// CHECK-LE: shr <16 x i8>
+
+  res_vuc = vec_sr(vuc, vuc);
+// CHECK: shr <16 x i8>
+// CHECK-LE: shr <16 x i8>
+
+  res_vs  = vec_sr(vs, vus);
+// CHECK: shr <8 x i16>
+// CHECK-LE: shr <8 x i16>
+
+  res_vus = vec_sr(vus, vus);
+// CHECK: shr <8 x i16>
+// CHECK-LE: shr <8 x i16>
+
+  res_vi  = vec_sr(vi, vui);
+// CHECK: shr <4 x i32>
+// CHECK-LE: shr <4 x i32>
+
+  res_vui = vec_sr(vui, vui);
+// CHECK: shr <4 x i32>
+// CHECK-LE: shr <4 x i32>
+
+  res_vsc = vec_vsrb(vsc, vuc);
+// CHECK: shr <16 x i8>
+// CHECK-LE: shr <16 x i8>
+
+  res_vuc = vec_vsrb(vuc, vuc);
+// CHECK: shr <16 x i8>
+// CHECK-LE: shr <16 x i8>
+
+  res_vs  = vec_vsrh(vs, vus);
+// CHECK: shr <8 x i16>
+// CHECK-LE: shr <8 x i16>
+
+  res_vus = vec_vsrh(vus, vus);
+// CHECK: shr <8 x i16>
+// CHECK-LE: shr <8 x i16>
+
+  res_vi  = vec_vsrw(vi, vui);
+// CHECK: shr <4 x i32>
+// CHECK-LE: shr <4 x i32>
+
+  res_vui = vec_vsrw(vui, vui);
+// CHECK: shr <4 x i32>
+// CHECK-LE: shr <4 x i32>
 
   /* vec_sra */
-  res_vsc = vec_sra(vsc, vuc);                  // CHECK: @llvm.ppc.altivec.vsrab
-  res_vuc = vec_sra(vuc, vuc);                  // CHECK: @llvm.ppc.altivec.vsrab
-  res_vs  = vec_sra(vs, vus);                   // CHECK: @llvm.ppc.altivec.vsrah
-  res_vus = vec_sra(vus, vus);                  // CHECK: @llvm.ppc.altivec.vsrah
-  res_vi  = vec_sra(vi, vui);                   // CHECK: @llvm.ppc.altivec.vsraw
-  res_vui = vec_sra(vui, vui);                  // CHECK: @llvm.ppc.altivec.vsraw
-  res_vsc = vec_vsrab(vsc, vuc);                // CHECK: @llvm.ppc.altivec.vsrab
-  res_vuc = vec_vsrab(vuc, vuc);                // CHECK: @llvm.ppc.altivec.vsrab
-  res_vs  = vec_vsrah(vs, vus);                 // CHECK: @llvm.ppc.altivec.vsrah
-  res_vus = vec_vsrah(vus, vus);                // CHECK: @llvm.ppc.altivec.vsrah
-  res_vi  = vec_vsraw(vi, vui);                 // CHECK: @llvm.ppc.altivec.vsraw
-  res_vui = vec_vsraw(vui, vui);                // CHECK: @llvm.ppc.altivec.vsraw
+  res_vsc = vec_sra(vsc, vuc);
+// CHECK: @llvm.ppc.altivec.vsrab
+// CHECK-LE: @llvm.ppc.altivec.vsrab
+
+  res_vuc = vec_sra(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vsrab
+// CHECK-LE: @llvm.ppc.altivec.vsrab
+
+  res_vs  = vec_sra(vs, vus);
+// CHECK: @llvm.ppc.altivec.vsrah
+// CHECK-LE: @llvm.ppc.altivec.vsrah
+
+  res_vus = vec_sra(vus, vus);
+// CHECK: @llvm.ppc.altivec.vsrah
+// CHECK-LE: @llvm.ppc.altivec.vsrah
+
+  res_vi  = vec_sra(vi, vui);
+// CHECK: @llvm.ppc.altivec.vsraw
+// CHECK-LE: @llvm.ppc.altivec.vsraw
+
+  res_vui = vec_sra(vui, vui);
+// CHECK: @llvm.ppc.altivec.vsraw
+// CHECK-LE: @llvm.ppc.altivec.vsraw
+
+  res_vsc = vec_vsrab(vsc, vuc);
+// CHECK: @llvm.ppc.altivec.vsrab
+// CHECK-LE: @llvm.ppc.altivec.vsrab
+
+  res_vuc = vec_vsrab(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vsrab
+// CHECK-LE: @llvm.ppc.altivec.vsrab
+
+  res_vs  = vec_vsrah(vs, vus);
+// CHECK: @llvm.ppc.altivec.vsrah
+// CHECK-LE: @llvm.ppc.altivec.vsrah
+
+  res_vus = vec_vsrah(vus, vus);
+// CHECK: @llvm.ppc.altivec.vsrah
+// CHECK-LE: @llvm.ppc.altivec.vsrah
+
+  res_vi  = vec_vsraw(vi, vui);
+// CHECK: @llvm.ppc.altivec.vsraw
+// CHECK-LE: @llvm.ppc.altivec.vsraw
+
+  res_vui = vec_vsraw(vui, vui);
+// CHECK: @llvm.ppc.altivec.vsraw
+// CHECK-LE: @llvm.ppc.altivec.vsraw
 
   /* vec_srl */
-  res_vsc = vec_srl(vsc, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vsc = vec_srl(vsc, vus);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vsc = vec_srl(vsc, vui);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vuc = vec_srl(vuc, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vuc = vec_srl(vuc, vus);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vuc = vec_srl(vuc, vui);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vbc = vec_srl(vbc, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vbc = vec_srl(vbc, vus);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vbc = vec_srl(vbc, vui);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vs  = vec_srl(vs, vuc);                   // CHECK: @llvm.ppc.altivec.vsr
-  res_vs  = vec_srl(vs, vus);                   // CHECK: @llvm.ppc.altivec.vsr
-  res_vs  = vec_srl(vs, vui);                   // CHECK: @llvm.ppc.altivec.vsr
-  res_vus = vec_srl(vus, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vus = vec_srl(vus, vus);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vus = vec_srl(vus, vui);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vbs = vec_srl(vbs, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vbs = vec_srl(vbs, vus);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vbs = vec_srl(vbs, vui);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vp  = vec_srl(vp, vuc);                   // CHECK: @llvm.ppc.altivec.vsr
-  res_vp  = vec_srl(vp, vus);                   // CHECK: @llvm.ppc.altivec.vsr
-  res_vp  = vec_srl(vp, vui);                   // CHECK: @llvm.ppc.altivec.vsr
-  res_vi  = vec_srl(vi, vuc);                   // CHECK: @llvm.ppc.altivec.vsr
-  res_vi  = vec_srl(vi, vus);                   // CHECK: @llvm.ppc.altivec.vsr
-  res_vi  = vec_srl(vi, vui);                   // CHECK: @llvm.ppc.altivec.vsr
-  res_vui = vec_srl(vui, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vui = vec_srl(vui, vus);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vui = vec_srl(vui, vui);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vbi = vec_srl(vbi, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vbi = vec_srl(vbi, vus);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vbi = vec_srl(vbi, vui);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vsc = vec_vsr(vsc, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vsc = vec_vsr(vsc, vus);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vsc = vec_vsr(vsc, vui);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vuc = vec_vsr(vuc, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vuc = vec_vsr(vuc, vus);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vuc = vec_vsr(vuc, vui);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vbc = vec_vsr(vbc, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vbc = vec_vsr(vbc, vus);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vbc = vec_vsr(vbc, vui);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vs  = vec_vsr(vs, vuc);                   // CHECK: @llvm.ppc.altivec.vsr
-  res_vs  = vec_vsr(vs, vus);                   // CHECK: @llvm.ppc.altivec.vsr
-  res_vs  = vec_vsr(vs, vui);                   // CHECK: @llvm.ppc.altivec.vsr
-  res_vus = vec_vsr(vus, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vus = vec_vsr(vus, vus);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vus = vec_vsr(vus, vui);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vbs = vec_vsr(vbs, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vbs = vec_vsr(vbs, vus);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vbs = vec_vsr(vbs, vui);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vp  = vec_vsr(vp, vuc);                   // CHECK: @llvm.ppc.altivec.vsr
-  res_vp  = vec_vsr(vp, vus);                   // CHECK: @llvm.ppc.altivec.vsr
-  res_vp  = vec_vsr(vp, vui);                   // CHECK: @llvm.ppc.altivec.vsr
-  res_vi  = vec_vsr(vi, vuc);                   // CHECK: @llvm.ppc.altivec.vsr
-  res_vi  = vec_vsr(vi, vus);                   // CHECK: @llvm.ppc.altivec.vsr
-  res_vi  = vec_vsr(vi, vui);                   // CHECK: @llvm.ppc.altivec.vsr
-  res_vui = vec_vsr(vui, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vui = vec_vsr(vui, vus);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vui = vec_vsr(vui, vui);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vbi = vec_vsr(vbi, vuc);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vbi = vec_vsr(vbi, vus);                  // CHECK: @llvm.ppc.altivec.vsr
-  res_vbi = vec_vsr(vbi, vui);                  // CHECK: @llvm.ppc.altivec.vsr
+  res_vsc = vec_srl(vsc, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vsc = vec_srl(vsc, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vsc = vec_srl(vsc, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vuc = vec_srl(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vuc = vec_srl(vuc, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vuc = vec_srl(vuc, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vbc = vec_srl(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vbc = vec_srl(vbc, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vbc = vec_srl(vbc, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vs  = vec_srl(vs, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vs  = vec_srl(vs, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vs  = vec_srl(vs, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vus = vec_srl(vus, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vus = vec_srl(vus, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vus = vec_srl(vus, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vbs = vec_srl(vbs, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vbs = vec_srl(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vbs = vec_srl(vbs, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vp  = vec_srl(vp, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vp  = vec_srl(vp, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vp  = vec_srl(vp, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vi  = vec_srl(vi, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vi  = vec_srl(vi, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vi  = vec_srl(vi, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vui = vec_srl(vui, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vui = vec_srl(vui, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vui = vec_srl(vui, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vbi = vec_srl(vbi, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vbi = vec_srl(vbi, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vbi = vec_srl(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vsc = vec_vsr(vsc, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vsc = vec_vsr(vsc, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vsc = vec_vsr(vsc, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vuc = vec_vsr(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vuc = vec_vsr(vuc, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vuc = vec_vsr(vuc, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vbc = vec_vsr(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vbc = vec_vsr(vbc, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vbc = vec_vsr(vbc, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vs  = vec_vsr(vs, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vs  = vec_vsr(vs, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vs  = vec_vsr(vs, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vus = vec_vsr(vus, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vus = vec_vsr(vus, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vus = vec_vsr(vus, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vbs = vec_vsr(vbs, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vbs = vec_vsr(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vbs = vec_vsr(vbs, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vp  = vec_vsr(vp, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vp  = vec_vsr(vp, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vp  = vec_vsr(vp, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vi  = vec_vsr(vi, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vi  = vec_vsr(vi, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vi  = vec_vsr(vi, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vui = vec_vsr(vui, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vui = vec_vsr(vui, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vui = vec_vsr(vui, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vbi = vec_vsr(vbi, vuc);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vbi = vec_vsr(vbi, vus);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
+
+  res_vbi = vec_vsr(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vsr
+// CHECK-LE: @llvm.ppc.altivec.vsr
 
   /* vec_sro */
-  res_vsc = vec_sro(vsc, vsc);                  // CHECK: @llvm.ppc.altivec.vsro
-  res_vsc = vec_sro(vsc, vuc);                  // CHECK: @llvm.ppc.altivec.vsro
-  res_vuc = vec_sro(vuc, vsc);                  // CHECK: @llvm.ppc.altivec.vsro
-  res_vuc = vec_sro(vuc, vuc);                  // CHECK: @llvm.ppc.altivec.vsro
-  res_vs  = vec_sro(vs, vsc);                   // CHECK: @llvm.ppc.altivec.vsro
-  res_vs  = vec_sro(vs, vuc);                   // CHECK: @llvm.ppc.altivec.vsro
-  res_vus = vec_sro(vus, vsc);                  // CHECK: @llvm.ppc.altivec.vsro
-  res_vus = vec_sro(vus, vuc);                  // CHECK: @llvm.ppc.altivec.vsro
-  res_vp  = vec_sro(vp, vsc);                   // CHECK: @llvm.ppc.altivec.vsro
-  res_vp  = vec_sro(vp, vuc);                   // CHECK: @llvm.ppc.altivec.vsro
-  res_vi  = vec_sro(vi, vsc);                   // CHECK: @llvm.ppc.altivec.vsro
-  res_vi  = vec_sro(vi, vuc);                   // CHECK: @llvm.ppc.altivec.vsro
-  res_vui = vec_sro(vui, vsc);                  // CHECK: @llvm.ppc.altivec.vsro
-  res_vui = vec_sro(vui, vuc);                  // CHECK: @llvm.ppc.altivec.vsro
-  res_vf  = vec_sro(vf, vsc);                   // CHECK: @llvm.ppc.altivec.vsro
-  res_vf  = vec_sro(vf, vuc);                   // CHECK: @llvm.ppc.altivec.vsro
-  res_vsc = vec_vsro(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vsro
-  res_vsc = vec_vsro(vsc, vuc);                 // CHECK: @llvm.ppc.altivec.vsro
-  res_vuc = vec_vsro(vuc, vsc);                 // CHECK: @llvm.ppc.altivec.vsro
-  res_vuc = vec_vsro(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vsro
-  res_vs  = vec_vsro(vs, vsc);                  // CHECK: @llvm.ppc.altivec.vsro
-  res_vs  = vec_vsro(vs, vuc);                  // CHECK: @llvm.ppc.altivec.vsro
-  res_vus = vec_vsro(vus, vsc);                 // CHECK: @llvm.ppc.altivec.vsro
-  res_vus = vec_vsro(vus, vuc);                 // CHECK: @llvm.ppc.altivec.vsro
-  res_vp  = vec_vsro(vp, vsc);                  // CHECK: @llvm.ppc.altivec.vsro
-  res_vp  = vec_vsro(vp, vuc);                  // CHECK: @llvm.ppc.altivec.vsro
-  res_vi  = vec_vsro(vi, vsc);                  // CHECK: @llvm.ppc.altivec.vsro
-  res_vi  = vec_vsro(vi, vuc);                  // CHECK: @llvm.ppc.altivec.vsro
-  res_vui = vec_vsro(vui, vsc);                 // CHECK: @llvm.ppc.altivec.vsro
-  res_vui = vec_vsro(vui, vuc);                 // CHECK: @llvm.ppc.altivec.vsro
-  res_vf  = vec_vsro(vf, vsc);                  // CHECK: @llvm.ppc.altivec.vsro
-  res_vf  = vec_vsro(vf, vuc);                  // CHECK: @llvm.ppc.altivec.vsro
+  res_vsc = vec_sro(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vsc = vec_sro(vsc, vuc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vuc = vec_sro(vuc, vsc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vuc = vec_sro(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vs  = vec_sro(vs, vsc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vs  = vec_sro(vs, vuc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vus = vec_sro(vus, vsc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vus = vec_sro(vus, vuc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vp  = vec_sro(vp, vsc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vp  = vec_sro(vp, vuc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vi  = vec_sro(vi, vsc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vi  = vec_sro(vi, vuc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vui = vec_sro(vui, vsc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vui = vec_sro(vui, vuc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vf  = vec_sro(vf, vsc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vf  = vec_sro(vf, vuc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vsc = vec_vsro(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vsc = vec_vsro(vsc, vuc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vuc = vec_vsro(vuc, vsc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vuc = vec_vsro(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vs  = vec_vsro(vs, vsc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vs  = vec_vsro(vs, vuc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vus = vec_vsro(vus, vsc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vus = vec_vsro(vus, vuc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vp  = vec_vsro(vp, vsc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vp  = vec_vsro(vp, vuc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vi  = vec_vsro(vi, vsc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vi  = vec_vsro(vi, vuc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vui = vec_vsro(vui, vsc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vui = vec_vsro(vui, vuc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vf  = vec_vsro(vf, vsc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
+
+  res_vf  = vec_vsro(vf, vuc);
+// CHECK: @llvm.ppc.altivec.vsro
+// CHECK-LE: @llvm.ppc.altivec.vsro
 
   /* vec_st */
-  vec_st(vsc, 0, &vsc);                        // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vsc, 0, &param_sc);                   // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vuc, 0, &vuc);                        // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vuc, 0, &param_uc);                   // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vbc, 0, &param_uc);                   // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vbc, 0, &param_uc);                   // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vbc, 0, &vbc);                        // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vs, 0, &vs);                          // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vs, 0, &param_s);                     // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vus, 0, &vus);                        // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vus, 0, &param_us);                   // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vbs, 0, &param_s);                    // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vbs, 0, &param_us);                   // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vbs, 0, &vbs);                        // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vp, 0, &param_s);                     // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vp, 0, &param_us);                    // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vp, 0, &vp);                          // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vi, 0, &vi);                          // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vi, 0, &param_i);                     // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vui, 0, &vui);                        // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vui, 0, &param_ui);                   // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vbi, 0, &param_i);                    // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vbi, 0, &param_ui);                   // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vbi, 0, &vbi);                        // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vf, 0, &vf);                          // CHECK: @llvm.ppc.altivec.stvx
-  vec_st(vf, 0, &param_f);                     // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vsc, 0, &vsc);                      // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vsc, 0, &param_sc);                 // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vuc, 0, &vuc);                      // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vuc, 0, &param_uc);                 // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vbc, 0, &param_uc);                 // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vbc, 0, &param_uc);                 // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vbc, 0, &vbc);                      // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vs, 0, &vs);                        // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vs, 0, &param_s);                   // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vus, 0, &vus);                      // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vus, 0, &param_us);                 // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vbs, 0, &param_s);                  // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vbs, 0, &param_us);                 // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vbs, 0, &vbs);                      // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vp, 0, &param_s);                   // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vp, 0, &param_us);                  // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vp, 0, &vp);                        // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vi, 0, &vi);                        // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vi, 0, &param_i);                   // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vui, 0, &vui);                      // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vui, 0, &param_ui);                 // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vbi, 0, &param_i);                  // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vbi, 0, &param_ui);                 // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vbi, 0, &vbi);                      // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vf, 0, &vf);                        // CHECK: @llvm.ppc.altivec.stvx
-  vec_stvx(vf, 0, &param_f);                   // CHECK: @llvm.ppc.altivec.stvx
+  vec_st(vsc, 0, &vsc);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vsc, 0, &param_sc);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vuc, 0, &vuc);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vuc, 0, &param_uc);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vbc, 0, &param_uc);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vbc, 0, &param_uc);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vbc, 0, &vbc);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vs, 0, &vs);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vs, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vus, 0, &vus);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vus, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vbs, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vbs, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vbs, 0, &vbs);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vp, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vp, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vp, 0, &vp);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vi, 0, &vi);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vi, 0, &param_i);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vui, 0, &vui);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vui, 0, &param_ui);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vbi, 0, &param_i);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vbi, 0, &param_ui);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vbi, 0, &vbi);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vf, 0, &vf);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_st(vf, 0, &param_f);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vsc, 0, &vsc);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vsc, 0, &param_sc);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vuc, 0, &vuc);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vuc, 0, &param_uc);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vbc, 0, &param_uc);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vbc, 0, &param_uc);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vbc, 0, &vbc);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vs, 0, &vs);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vs, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vus, 0, &vus);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vus, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vbs, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vbs, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vbs, 0, &vbs);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vp, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vp, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vp, 0, &vp);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vi, 0, &vi);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vi, 0, &param_i);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vui, 0, &vui);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vui, 0, &param_ui);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vbi, 0, &param_i);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vbi, 0, &param_ui);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vbi, 0, &vbi);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vf, 0, &vf);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
+
+  vec_stvx(vf, 0, &param_f);
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
   /* vec_ste */
-  vec_ste(vsc, 0, &param_sc);                  // CHECK: @llvm.ppc.altivec.stvebx
-  vec_ste(vuc, 0, &param_uc);                  // CHECK: @llvm.ppc.altivec.stvebx
-  vec_ste(vbc, 0, &param_sc);                  // CHECK: @llvm.ppc.altivec.stvebx
-  vec_ste(vbc, 0, &param_uc);                  // CHECK: @llvm.ppc.altivec.stvebx
-  vec_ste(vs, 0, &param_s);                    // CHECK: @llvm.ppc.altivec.stvehx
-  vec_ste(vus, 0, &param_us);                  // CHECK: @llvm.ppc.altivec.stvehx
-  vec_ste(vbs, 0, &param_s);                   // CHECK: @llvm.ppc.altivec.stvehx
-  vec_ste(vbs, 0, &param_us);                  // CHECK: @llvm.ppc.altivec.stvehx
-  vec_ste(vp, 0, &param_s);                    // CHECK: @llvm.ppc.altivec.stvehx
-  vec_ste(vp, 0, &param_us);                   // CHECK: @llvm.ppc.altivec.stvehx
-  vec_ste(vi, 0, &param_i);                    // CHECK: @llvm.ppc.altivec.stvewx
-  vec_ste(vui, 0, &param_ui);                  // CHECK: @llvm.ppc.altivec.stvewx
-  vec_ste(vbi, 0, &param_i);                   // CHECK: @llvm.ppc.altivec.stvewx
-  vec_ste(vbi, 0, &param_ui);                  // CHECK: @llvm.ppc.altivec.stvewx
-  vec_ste(vf, 0, &param_f);                    // CHECK: @llvm.ppc.altivec.stvewx
-  vec_stvebx(vsc, 0, &param_sc);               // CHECK: @llvm.ppc.altivec.stvebx
-  vec_stvebx(vuc, 0, &param_uc);               // CHECK: @llvm.ppc.altivec.stvebx
-  vec_stvebx(vbc, 0, &param_sc);               // CHECK: @llvm.ppc.altivec.stvebx
-  vec_stvebx(vbc, 0, &param_uc);               // CHECK: @llvm.ppc.altivec.stvebx
-  vec_stvehx(vs, 0, &param_s);                 // CHECK: @llvm.ppc.altivec.stvehx
-  vec_stvehx(vus, 0, &param_us);               // CHECK: @llvm.ppc.altivec.stvehx
-  vec_stvehx(vbs, 0, &param_s);                // CHECK: @llvm.ppc.altivec.stvehx
-  vec_stvehx(vbs, 0, &param_us);               // CHECK: @llvm.ppc.altivec.stvehx
-  vec_stvehx(vp, 0, &param_s);                 // CHECK: @llvm.ppc.altivec.stvehx
-  vec_stvehx(vp, 0, &param_us);                // CHECK: @llvm.ppc.altivec.stvehx
-  vec_stvewx(vi, 0, &param_i);                 // CHECK: @llvm.ppc.altivec.stvewx
-  vec_stvewx(vui, 0, &param_ui);               // CHECK: @llvm.ppc.altivec.stvewx
-  vec_stvewx(vbi, 0, &param_i);                // CHECK: @llvm.ppc.altivec.stvewx
-  vec_stvewx(vbi, 0, &param_ui);               // CHECK: @llvm.ppc.altivec.stvewx
-  vec_stvewx(vf, 0, &param_f);                 // CHECK: @llvm.ppc.altivec.stvewx
+  vec_ste(vsc, 0, &param_sc);
+// CHECK: @llvm.ppc.altivec.stvebx
+// CHECK-LE: @llvm.ppc.altivec.stvebx
+
+  vec_ste(vuc, 0, &param_uc);
+// CHECK: @llvm.ppc.altivec.stvebx
+// CHECK-LE: @llvm.ppc.altivec.stvebx
+
+  vec_ste(vbc, 0, &param_sc);
+// CHECK: @llvm.ppc.altivec.stvebx
+// CHECK-LE: @llvm.ppc.altivec.stvebx
+
+  vec_ste(vbc, 0, &param_uc);
+// CHECK: @llvm.ppc.altivec.stvebx
+// CHECK-LE: @llvm.ppc.altivec.stvebx
+
+  vec_ste(vs, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.stvehx
+// CHECK-LE: @llvm.ppc.altivec.stvehx
+
+  vec_ste(vus, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.stvehx
+// CHECK-LE: @llvm.ppc.altivec.stvehx
+
+  vec_ste(vbs, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.stvehx
+// CHECK-LE: @llvm.ppc.altivec.stvehx
+
+  vec_ste(vbs, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.stvehx
+// CHECK-LE: @llvm.ppc.altivec.stvehx
+
+  vec_ste(vp, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.stvehx
+// CHECK-LE: @llvm.ppc.altivec.stvehx
+
+  vec_ste(vp, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.stvehx
+// CHECK-LE: @llvm.ppc.altivec.stvehx
+
+  vec_ste(vi, 0, &param_i);
+// CHECK: @llvm.ppc.altivec.stvewx
+// CHECK-LE: @llvm.ppc.altivec.stvewx
+
+  vec_ste(vui, 0, &param_ui);
+// CHECK: @llvm.ppc.altivec.stvewx
+// CHECK-LE: @llvm.ppc.altivec.stvewx
+
+  vec_ste(vbi, 0, &param_i);
+// CHECK: @llvm.ppc.altivec.stvewx
+// CHECK-LE: @llvm.ppc.altivec.stvewx
+
+  vec_ste(vbi, 0, &param_ui);
+// CHECK: @llvm.ppc.altivec.stvewx
+// CHECK-LE: @llvm.ppc.altivec.stvewx
+
+  vec_ste(vf, 0, &param_f);
+// CHECK: @llvm.ppc.altivec.stvewx
+// CHECK-LE: @llvm.ppc.altivec.stvewx
+
+  vec_stvebx(vsc, 0, &param_sc);
+// CHECK: @llvm.ppc.altivec.stvebx
+// CHECK-LE: @llvm.ppc.altivec.stvebx
+
+  vec_stvebx(vuc, 0, &param_uc);
+// CHECK: @llvm.ppc.altivec.stvebx
+// CHECK-LE: @llvm.ppc.altivec.stvebx
+
+  vec_stvebx(vbc, 0, &param_sc);
+// CHECK: @llvm.ppc.altivec.stvebx
+// CHECK-LE: @llvm.ppc.altivec.stvebx
+
+  vec_stvebx(vbc, 0, &param_uc);
+// CHECK: @llvm.ppc.altivec.stvebx
+// CHECK-LE: @llvm.ppc.altivec.stvebx
+
+  vec_stvehx(vs, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.stvehx
+// CHECK-LE: @llvm.ppc.altivec.stvehx
+
+  vec_stvehx(vus, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.stvehx
+// CHECK-LE: @llvm.ppc.altivec.stvehx
+
+  vec_stvehx(vbs, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.stvehx
+// CHECK-LE: @llvm.ppc.altivec.stvehx
+
+  vec_stvehx(vbs, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.stvehx
+// CHECK-LE: @llvm.ppc.altivec.stvehx
+
+  vec_stvehx(vp, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.stvehx
+// CHECK-LE: @llvm.ppc.altivec.stvehx
+
+  vec_stvehx(vp, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.stvehx
+// CHECK-LE: @llvm.ppc.altivec.stvehx
+
+  vec_stvewx(vi, 0, &param_i);
+// CHECK: @llvm.ppc.altivec.stvewx
+// CHECK-LE: @llvm.ppc.altivec.stvewx
+
+  vec_stvewx(vui, 0, &param_ui);
+// CHECK: @llvm.ppc.altivec.stvewx
+// CHECK-LE: @llvm.ppc.altivec.stvewx
+
+  vec_stvewx(vbi, 0, &param_i);
+// CHECK: @llvm.ppc.altivec.stvewx
+// CHECK-LE: @llvm.ppc.altivec.stvewx
+
+  vec_stvewx(vbi, 0, &param_ui);
+// CHECK: @llvm.ppc.altivec.stvewx
+// CHECK-LE: @llvm.ppc.altivec.stvewx
+
+  vec_stvewx(vf, 0, &param_f);
+// CHECK: @llvm.ppc.altivec.stvewx
+// CHECK-LE: @llvm.ppc.altivec.stvewx
 
   /* vec_stl */
-  vec_stl(vsc, 0, &vsc);                        // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vsc, 0, &param_sc);                   // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vuc, 0, &vuc);                        // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vuc, 0, &param_uc);                   // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vbc, 0, &param_sc);                   // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vbc, 0, &param_uc);                   // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vbc, 0, &vbc);                        // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vs, 0, &vs);                          // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vs, 0, &param_s);                     // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vus, 0, &vus);                        // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vus, 0, &param_us);                   // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vbs, 0, &param_s);                    // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vbs, 0, &param_us);                   // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vbs, 0, &vbs);                        // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vp, 0, &param_s);                     // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vp, 0, &param_us);                    // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vp, 0, &vp);                          // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vi, 0, &vi);                          // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vi, 0, &param_i);                     // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vui, 0, &vui);                        // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vui, 0, &param_ui);                   // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vbi, 0, &param_i);                    // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vbi, 0, &param_ui);                   // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vbi, 0, &vbi);                        // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vf, 0, &vf);                          // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stl(vf, 0, &param_f);                     // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vsc, 0, &vsc);                      // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vsc, 0, &param_sc);                 // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vuc, 0, &vuc);                      // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vuc, 0, &param_uc);                 // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vbc, 0, &param_sc);                 // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vbc, 0, &param_uc);                 // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vbc, 0, &vbc);                      // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vs, 0, &vs);                        // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vs, 0, &param_s);                   // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vus, 0, &vus);                      // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vus, 0, &param_us);                 // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vbs, 0, &param_s);                  // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vbs, 0, &param_us);                 // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vbs, 0, &vbs);                      // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vp, 0, &param_s);                  // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vp, 0, &param_us);                 // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vp, 0, &vp);                      // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vi, 0, &vi);                        // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vi, 0, &param_i);                   // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vui, 0, &vui);                      // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vui, 0, &param_ui);                 // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vbi, 0, &param_i);                  // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vbi, 0, &param_ui);                 // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vbi, 0, &vbi);                      // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vf, 0, &vf);                        // CHECK: @llvm.ppc.altivec.stvxl
-  vec_stvxl(vf, 0, &param_f);                   // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stl(vsc, 0, &vsc);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vsc, 0, &param_sc);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vuc, 0, &vuc);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vuc, 0, &param_uc);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vbc, 0, &param_sc);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vbc, 0, &param_uc);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vbc, 0, &vbc);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vs, 0, &vs);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vs, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vus, 0, &vus);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vus, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vbs, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vbs, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vbs, 0, &vbs);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vp, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vp, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vp, 0, &vp);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vi, 0, &vi);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vi, 0, &param_i);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vui, 0, &vui);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vui, 0, &param_ui);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vbi, 0, &param_i);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vbi, 0, &param_ui);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vbi, 0, &vbi);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vf, 0, &vf);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stl(vf, 0, &param_f);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vsc, 0, &vsc);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vsc, 0, &param_sc);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vuc, 0, &vuc);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vuc, 0, &param_uc);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vbc, 0, &param_sc);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vbc, 0, &param_uc);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vbc, 0, &vbc);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vs, 0, &vs);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vs, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vus, 0, &vus);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vus, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vbs, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vbs, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vbs, 0, &vbs);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vp, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vp, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vp, 0, &vp);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vi, 0, &vi);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vi, 0, &param_i);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vui, 0, &vui);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vui, 0, &param_ui);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vbi, 0, &param_i);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vbi, 0, &param_ui);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vbi, 0, &vbi);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vf, 0, &vf);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
+
+  vec_stvxl(vf, 0, &param_f);
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
   /* vec_sub */
-  res_vsc = vec_sub(vsc, vsc);                  // CHECK: sub <16 x i8>
-  res_vsc = vec_sub(vbc, vsc);                  // CHECK: sub <16 x i8>
-  res_vsc = vec_sub(vsc, vbc);                  // CHECK: sub <16 x i8>
-  res_vuc = vec_sub(vuc, vuc);                  // CHECK: sub <16 x i8>
-  res_vuc = vec_sub(vbc, vuc);                  // CHECK: sub <16 x i8>
-  res_vuc = vec_sub(vuc, vbc);                  // CHECK: sub <16 x i8>
-  res_vs  = vec_sub(vs, vs);                    // CHECK: sub <8 x i16>
-  res_vs  = vec_sub(vbs, vs);                   // CHECK: sub <8 x i16>
-  res_vs  = vec_sub(vs, vbs);                   // CHECK: sub <8 x i16>
-  res_vus = vec_sub(vus, vus);                  // CHECK: sub <8 x i16>
-  res_vus = vec_sub(vbs, vus);                  // CHECK: sub <8 x i16>
-  res_vus = vec_sub(vus, vbs);                  // CHECK: sub <8 x i16>
-  res_vi  = vec_sub(vi, vi);                    // CHECK: sub <4 x i32>
-  res_vi  = vec_sub(vbi, vi);                   // CHECK: sub <4 x i32>
-  res_vi  = vec_sub(vi, vbi);                   // CHECK: sub <4 x i32>
-  res_vui = vec_sub(vui, vui);                  // CHECK: sub <4 x i32>
-  res_vui = vec_sub(vbi, vui);                  // CHECK: sub <4 x i32>
-  res_vui = vec_sub(vui, vbi);                  // CHECK: sub <4 x i32>
-  res_vf  = vec_sub(vf, vf);                    // CHECK: fsub <4 x float>
-  res_vsc = vec_vsububm(vsc, vsc);              // CHECK: sub <16 x i8>
-  res_vsc = vec_vsububm(vbc, vsc);              // CHECK: sub <16 x i8>
-  res_vsc = vec_vsububm(vsc, vbc);              // CHECK: sub <16 x i8>
-  res_vuc = vec_vsububm(vuc, vuc);              // CHECK: sub <16 x i8>
-  res_vuc = vec_vsububm(vbc, vuc);              // CHECK: sub <16 x i8>
-  res_vuc = vec_vsububm(vuc, vbc);              // CHECK: sub <16 x i8>
-  res_vs  = vec_vsubuhm(vs, vs);                // CHECK: sub <8 x i16>
-  res_vs  = vec_vsubuhm(vbs, vus);              // CHECK: sub <8 x i16>
-  res_vs  = vec_vsubuhm(vus, vbs);              // CHECK: sub <8 x i16>
-  res_vus = vec_vsubuhm(vus, vus);              // CHECK: sub <8 x i16>
-  res_vus = vec_vsubuhm(vbs, vus);              // CHECK: sub <8 x i16>
-  res_vus = vec_vsubuhm(vus, vbs);              // CHECK: sub <8 x i16>
-  res_vi  = vec_vsubuwm(vi, vi);                // CHECK: sub <4 x i32>
-  res_vi  = vec_vsubuwm(vbi, vi);               // CHECK: sub <4 x i32>
-  res_vi  = vec_vsubuwm(vi, vbi);               // CHECK: sub <4 x i32>
-  res_vui = vec_vsubuwm(vui, vui);              // CHECK: sub <4 x i32>
-  res_vui = vec_vsubuwm(vbi, vui);              // CHECK: sub <4 x i32>
-  res_vui = vec_vsubuwm(vui, vbi);              // CHECK: sub <4 x i32>
-  res_vf  = vec_vsubfp(vf, vf);                 // CHECK: fsub <4 x float>
+  res_vsc = vec_sub(vsc, vsc);
+// CHECK: sub <16 x i8>
+// CHECK-LE: sub <16 x i8>
+
+  res_vsc = vec_sub(vbc, vsc);
+// CHECK: sub <16 x i8>
+// CHECK-LE: sub <16 x i8>
+
+  res_vsc = vec_sub(vsc, vbc);
+// CHECK: sub <16 x i8>
+// CHECK-LE: sub <16 x i8>
+
+  res_vuc = vec_sub(vuc, vuc);
+// CHECK: sub <16 x i8>
+// CHECK-LE: sub <16 x i8>
+
+  res_vuc = vec_sub(vbc, vuc);
+// CHECK: sub <16 x i8>
+// CHECK-LE: sub <16 x i8>
+
+  res_vuc = vec_sub(vuc, vbc);
+// CHECK: sub <16 x i8>
+// CHECK-LE: sub <16 x i8>
+
+  res_vs  = vec_sub(vs, vs);
+// CHECK: sub <8 x i16>
+// CHECK-LE: sub <8 x i16>
+
+  res_vs  = vec_sub(vbs, vs);
+// CHECK: sub <8 x i16>
+// CHECK-LE: sub <8 x i16>
+
+  res_vs  = vec_sub(vs, vbs);
+// CHECK: sub <8 x i16>
+// CHECK-LE: sub <8 x i16>
+
+  res_vus = vec_sub(vus, vus);
+// CHECK: sub <8 x i16>
+// CHECK-LE: sub <8 x i16>
+
+  res_vus = vec_sub(vbs, vus);
+// CHECK: sub <8 x i16>
+// CHECK-LE: sub <8 x i16>
+
+  res_vus = vec_sub(vus, vbs);
+// CHECK: sub <8 x i16>
+// CHECK-LE: sub <8 x i16>
+
+  res_vi  = vec_sub(vi, vi);
+// CHECK: sub <4 x i32>
+// CHECK-LE: sub <4 x i32>
+
+  res_vi  = vec_sub(vbi, vi);
+// CHECK: sub <4 x i32>
+// CHECK-LE: sub <4 x i32>
+
+  res_vi  = vec_sub(vi, vbi);
+// CHECK: sub <4 x i32>
+// CHECK-LE: sub <4 x i32>
+
+  res_vui = vec_sub(vui, vui);
+// CHECK: sub <4 x i32>
+// CHECK-LE: sub <4 x i32>
+
+  res_vui = vec_sub(vbi, vui);
+// CHECK: sub <4 x i32>
+// CHECK-LE: sub <4 x i32>
+
+  res_vui = vec_sub(vui, vbi);
+// CHECK: sub <4 x i32>
+// CHECK-LE: sub <4 x i32>
+
+  res_vf  = vec_sub(vf, vf);
+// CHECK: fsub <4 x float>
+// CHECK-LE: fsub <4 x float>
+
+  res_vsc = vec_vsububm(vsc, vsc);
+// CHECK: sub <16 x i8>
+// CHECK-LE: sub <16 x i8>
+
+  res_vsc = vec_vsububm(vbc, vsc);
+// CHECK: sub <16 x i8>
+// CHECK-LE: sub <16 x i8>
+
+  res_vsc = vec_vsububm(vsc, vbc);
+// CHECK: sub <16 x i8>
+// CHECK-LE: sub <16 x i8>
+
+  res_vuc = vec_vsububm(vuc, vuc);
+// CHECK: sub <16 x i8>
+// CHECK-LE: sub <16 x i8>
+
+  res_vuc = vec_vsububm(vbc, vuc);
+// CHECK: sub <16 x i8>
+// CHECK-LE: sub <16 x i8>
+
+  res_vuc = vec_vsububm(vuc, vbc);
+// CHECK: sub <16 x i8>
+// CHECK-LE: sub <16 x i8>
+
+  res_vs  = vec_vsubuhm(vs, vs);
+// CHECK: sub <8 x i16>
+// CHECK-LE: sub <8 x i16>
+
+  res_vs  = vec_vsubuhm(vbs, vus);
+// CHECK: sub <8 x i16>
+// CHECK-LE: sub <8 x i16>
+
+  res_vs  = vec_vsubuhm(vus, vbs);
+// CHECK: sub <8 x i16>
+// CHECK-LE: sub <8 x i16>
+
+  res_vus = vec_vsubuhm(vus, vus);
+// CHECK: sub <8 x i16>
+// CHECK-LE: sub <8 x i16>
+
+  res_vus = vec_vsubuhm(vbs, vus);
+// CHECK: sub <8 x i16>
+// CHECK-LE: sub <8 x i16>
+
+  res_vus = vec_vsubuhm(vus, vbs);
+// CHECK: sub <8 x i16>
+// CHECK-LE: sub <8 x i16>
+
+  res_vi  = vec_vsubuwm(vi, vi);
+// CHECK: sub <4 x i32>
+// CHECK-LE: sub <4 x i32>
+
+  res_vi  = vec_vsubuwm(vbi, vi);
+// CHECK: sub <4 x i32>
+// CHECK-LE: sub <4 x i32>
+
+  res_vi  = vec_vsubuwm(vi, vbi);
+// CHECK: sub <4 x i32>
+// CHECK-LE: sub <4 x i32>
+
+  res_vui = vec_vsubuwm(vui, vui);
+// CHECK: sub <4 x i32>
+// CHECK-LE: sub <4 x i32>
+
+  res_vui = vec_vsubuwm(vbi, vui);
+// CHECK: sub <4 x i32>
+// CHECK-LE: sub <4 x i32>
+
+  res_vui = vec_vsubuwm(vui, vbi);
+// CHECK: sub <4 x i32>
+// CHECK-LE: sub <4 x i32>
+
+  res_vf  = vec_vsubfp(vf, vf);
+// CHECK: fsub <4 x float>
+// CHECK-LE: fsub <4 x float>
 
   /* vec_subc */
-  res_vui = vec_subc(vui, vui);                 // CHECK: @llvm.ppc.altivec.vsubcuw
-  res_vui = vec_vsubcuw(vui, vui);              // CHECK: @llvm.ppc.altivec.vsubcuw
+  res_vui = vec_subc(vui, vui);
+// CHECK: @llvm.ppc.altivec.vsubcuw
+// CHECK-LE: @llvm.ppc.altivec.vsubcuw
+
+  res_vui = vec_vsubcuw(vui, vui);
+// CHECK: @llvm.ppc.altivec.vsubcuw
+// CHECK-LE: @llvm.ppc.altivec.vsubcuw
 
   /* vec_subs */
-  res_vsc = vec_subs(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vsubsbs
-  res_vsc = vec_subs(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vsubsbs
-  res_vsc = vec_subs(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vsubsbs
-  res_vuc = vec_subs(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vsububs
-  res_vuc = vec_subs(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vsububs
-  res_vuc = vec_subs(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vsububs
-  res_vs  = vec_subs(vs, vs);                   // CHECK: @llvm.ppc.altivec.vsubshs
-  res_vs  = vec_subs(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vsubshs
-  res_vs  = vec_subs(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vsubshs
-  res_vus = vec_subs(vus, vus);                 // CHECK: @llvm.ppc.altivec.vsubuhs
-  res_vus = vec_subs(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vsubuhs
-  res_vus = vec_subs(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vsubuhs
-  res_vi  = vec_subs(vi, vi);                   // CHECK: @llvm.ppc.altivec.vsubsws
-  res_vi  = vec_subs(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vsubsws
-  res_vi  = vec_subs(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vsubsws
-  res_vui = vec_subs(vui, vui);                 // CHECK: @llvm.ppc.altivec.vsubuws
-  res_vui = vec_subs(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vsubuws
-  res_vui = vec_subs(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vsubuws
-  res_vsc = vec_vsubsbs(vsc, vsc);              // CHECK: @llvm.ppc.altivec.vsubsbs
-  res_vsc = vec_vsubsbs(vbc, vsc);              // CHECK: @llvm.ppc.altivec.vsubsbs
-  res_vsc = vec_vsubsbs(vsc, vbc);              // CHECK: @llvm.ppc.altivec.vsubsbs
-  res_vuc = vec_vsububs(vuc, vuc);              // CHECK: @llvm.ppc.altivec.vsububs
-  res_vuc = vec_vsububs(vbc, vuc);              // CHECK: @llvm.ppc.altivec.vsububs
-  res_vuc = vec_vsububs(vuc, vbc);              // CHECK: @llvm.ppc.altivec.vsububs
-  res_vs  = vec_vsubshs(vs, vs);                // CHECK: @llvm.ppc.altivec.vsubshs
-  res_vs  = vec_vsubshs(vbs, vs);               // CHECK: @llvm.ppc.altivec.vsubshs
-  res_vs  = vec_vsubshs(vs, vbs);               // CHECK: @llvm.ppc.altivec.vsubshs
-  res_vus = vec_vsubuhs(vus, vus);              // CHECK: @llvm.ppc.altivec.vsubuhs
-  res_vus = vec_vsubuhs(vbs, vus);              // CHECK: @llvm.ppc.altivec.vsubuhs
-  res_vus = vec_vsubuhs(vus, vbs);              // CHECK: @llvm.ppc.altivec.vsubuhs
-  res_vi  = vec_vsubsws(vi, vi);                // CHECK: @llvm.ppc.altivec.vsubsws
-  res_vi  = vec_vsubsws(vbi, vi);               // CHECK: @llvm.ppc.altivec.vsubsws
-  res_vi  = vec_vsubsws(vi, vbi);               // CHECK: @llvm.ppc.altivec.vsubsws
-  res_vui = vec_vsubuws(vui, vui);              // CHECK: @llvm.ppc.altivec.vsubuws
-  res_vui = vec_vsubuws(vbi, vui);              // CHECK: @llvm.ppc.altivec.vsubuws
-  res_vui = vec_vsubuws(vui, vbi);              // CHECK: @llvm.ppc.altivec.vsubuws
+  res_vsc = vec_subs(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vsubsbs
+// CHECK-LE: @llvm.ppc.altivec.vsubsbs
+
+  res_vsc = vec_subs(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vsubsbs
+// CHECK-LE: @llvm.ppc.altivec.vsubsbs
+
+  res_vsc = vec_subs(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vsubsbs
+// CHECK-LE: @llvm.ppc.altivec.vsubsbs
+
+  res_vuc = vec_subs(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vsububs
+// CHECK-LE: @llvm.ppc.altivec.vsububs
+
+  res_vuc = vec_subs(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vsububs
+// CHECK-LE: @llvm.ppc.altivec.vsububs
+
+  res_vuc = vec_subs(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vsububs
+// CHECK-LE: @llvm.ppc.altivec.vsububs
+
+  res_vs  = vec_subs(vs, vs);
+// CHECK: @llvm.ppc.altivec.vsubshs
+// CHECK-LE: @llvm.ppc.altivec.vsubshs
+
+  res_vs  = vec_subs(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vsubshs
+// CHECK-LE: @llvm.ppc.altivec.vsubshs
+
+  res_vs  = vec_subs(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vsubshs
+// CHECK-LE: @llvm.ppc.altivec.vsubshs
+
+  res_vus = vec_subs(vus, vus);
+// CHECK: @llvm.ppc.altivec.vsubuhs
+// CHECK-LE: @llvm.ppc.altivec.vsubuhs
+
+  res_vus = vec_subs(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vsubuhs
+// CHECK-LE: @llvm.ppc.altivec.vsubuhs
+
+  res_vus = vec_subs(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vsubuhs
+// CHECK-LE: @llvm.ppc.altivec.vsubuhs
+
+  res_vi  = vec_subs(vi, vi);
+// CHECK: @llvm.ppc.altivec.vsubsws
+// CHECK-LE: @llvm.ppc.altivec.vsubsws
+
+  res_vi  = vec_subs(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vsubsws
+// CHECK-LE: @llvm.ppc.altivec.vsubsws
+
+  res_vi  = vec_subs(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vsubsws
+// CHECK-LE: @llvm.ppc.altivec.vsubsws
+
+  res_vui = vec_subs(vui, vui);
+// CHECK: @llvm.ppc.altivec.vsubuws
+// CHECK-LE: @llvm.ppc.altivec.vsubuws
+
+  res_vui = vec_subs(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vsubuws
+// CHECK-LE: @llvm.ppc.altivec.vsubuws
+
+  res_vui = vec_subs(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vsubuws
+// CHECK-LE: @llvm.ppc.altivec.vsubuws
+
+  res_vsc = vec_vsubsbs(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vsubsbs
+// CHECK-LE: @llvm.ppc.altivec.vsubsbs
+
+  res_vsc = vec_vsubsbs(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vsubsbs
+// CHECK-LE: @llvm.ppc.altivec.vsubsbs
+
+  res_vsc = vec_vsubsbs(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vsubsbs
+// CHECK-LE: @llvm.ppc.altivec.vsubsbs
+
+  res_vuc = vec_vsububs(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vsububs
+// CHECK-LE: @llvm.ppc.altivec.vsububs
+
+  res_vuc = vec_vsububs(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vsububs
+// CHECK-LE: @llvm.ppc.altivec.vsububs
+
+  res_vuc = vec_vsububs(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vsububs
+// CHECK-LE: @llvm.ppc.altivec.vsububs
+
+  res_vs  = vec_vsubshs(vs, vs);
+// CHECK: @llvm.ppc.altivec.vsubshs
+// CHECK-LE: @llvm.ppc.altivec.vsubshs
+
+  res_vs  = vec_vsubshs(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vsubshs
+// CHECK-LE: @llvm.ppc.altivec.vsubshs
+
+  res_vs  = vec_vsubshs(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vsubshs
+// CHECK-LE: @llvm.ppc.altivec.vsubshs
+
+  res_vus = vec_vsubuhs(vus, vus);
+// CHECK: @llvm.ppc.altivec.vsubuhs
+// CHECK-LE: @llvm.ppc.altivec.vsubuhs
+
+  res_vus = vec_vsubuhs(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vsubuhs
+// CHECK-LE: @llvm.ppc.altivec.vsubuhs
+
+  res_vus = vec_vsubuhs(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vsubuhs
+// CHECK-LE: @llvm.ppc.altivec.vsubuhs
+
+  res_vi  = vec_vsubsws(vi, vi);
+// CHECK: @llvm.ppc.altivec.vsubsws
+// CHECK-LE: @llvm.ppc.altivec.vsubsws
+
+  res_vi  = vec_vsubsws(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vsubsws
+// CHECK-LE: @llvm.ppc.altivec.vsubsws
+
+  res_vi  = vec_vsubsws(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vsubsws
+// CHECK-LE: @llvm.ppc.altivec.vsubsws
+
+  res_vui = vec_vsubuws(vui, vui);
+// CHECK: @llvm.ppc.altivec.vsubuws
+// CHECK-LE: @llvm.ppc.altivec.vsubuws
+
+  res_vui = vec_vsubuws(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vsubuws
+// CHECK-LE: @llvm.ppc.altivec.vsubuws
+
+  res_vui = vec_vsubuws(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vsubuws
+// CHECK-LE: @llvm.ppc.altivec.vsubuws
 
   /* vec_sum4s */
-  res_vi  = vec_sum4s(vsc, vi);                 // CHECK: @llvm.ppc.altivec.vsum4sbs
-  res_vui = vec_sum4s(vuc, vui);                // CHECK: @llvm.ppc.altivec.vsum4ubs
-  res_vi  = vec_sum4s(vs, vi);                  // CHECK: @llvm.ppc.altivec.vsum4shs
-  res_vi  = vec_vsum4sbs(vsc, vi);              // CHECK: @llvm.ppc.altivec.vsum4sbs
-  res_vui = vec_vsum4ubs(vuc, vui);             // CHECK: @llvm.ppc.altivec.vsum4ubs
-  res_vi  = vec_vsum4shs(vs, vi);               // CHECK: @llvm.ppc.altivec.vsum4shs
+  res_vi  = vec_sum4s(vsc, vi);
+// CHECK: @llvm.ppc.altivec.vsum4sbs
+// CHECK-LE: @llvm.ppc.altivec.vsum4sbs
+
+  res_vui = vec_sum4s(vuc, vui);
+// CHECK: @llvm.ppc.altivec.vsum4ubs
+// CHECK-LE: @llvm.ppc.altivec.vsum4ubs
+
+  res_vi  = vec_sum4s(vs, vi);
+// CHECK: @llvm.ppc.altivec.vsum4shs
+// CHECK-LE: @llvm.ppc.altivec.vsum4shs
+
+  res_vi  = vec_vsum4sbs(vsc, vi);
+// CHECK: @llvm.ppc.altivec.vsum4sbs
+// CHECK-LE: @llvm.ppc.altivec.vsum4sbs
+
+  res_vui = vec_vsum4ubs(vuc, vui);
+// CHECK: @llvm.ppc.altivec.vsum4ubs
+// CHECK-LE: @llvm.ppc.altivec.vsum4ubs
+
+  res_vi  = vec_vsum4shs(vs, vi);
+// CHECK: @llvm.ppc.altivec.vsum4shs
+// CHECK-LE: @llvm.ppc.altivec.vsum4shs
 
   /* vec_sum2s */
-  res_vi = vec_sum2s(vi, vi);                   // CHECK: @llvm.ppc.altivec.vsum2sws
-  res_vi = vec_vsum2sws(vi, vi);                // CHECK: @llvm.ppc.altivec.vsum2sws
+  res_vi = vec_sum2s(vi, vi);
+// CHECK: @llvm.ppc.altivec.vsum2sws
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vsum2sws
+// CHECK-LE: @llvm.ppc.altivec.vperm
+
+  res_vi = vec_vsum2sws(vi, vi);
+// CHECK: @llvm.ppc.altivec.vsum2sws
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vsum2sws
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
   /* vec_sums */
-  res_vi = vec_sums(vi, vi);                    // CHECK: @llvm.ppc.altivec.vsumsws
-  res_vi = vec_vsumsws(vi, vi);                 // CHECK: @llvm.ppc.altivec.vsumsws
+  res_vi = vec_sums(vi, vi);
+// CHECK: @llvm.ppc.altivec.vsumsws
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vsumsws
+
+  res_vi = vec_vsumsws(vi, vi);
+// CHECK: @llvm.ppc.altivec.vsumsws
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.vsumsws
 
   /* vec_trunc */
-  res_vf = vec_trunc(vf);                       // CHECK: @llvm.ppc.altivec.vrfiz
-  res_vf = vec_vrfiz(vf);                       // CHECK: @llvm.ppc.altivec.vrfiz
+  res_vf = vec_trunc(vf);
+// CHECK: @llvm.ppc.altivec.vrfiz
+// CHECK-LE: @llvm.ppc.altivec.vrfiz
+
+  res_vf = vec_vrfiz(vf);
+// CHECK: @llvm.ppc.altivec.vrfiz
+// CHECK-LE: @llvm.ppc.altivec.vrfiz
 
   /* vec_unpackh */
-  res_vs  = vec_unpackh(vsc);                   // CHECK: @llvm.ppc.altivec.vupkhsb
-  res_vbs = vec_unpackh(vbc);                   // CHECK: @llvm.ppc.altivec.vupkhsb
-  res_vi  = vec_unpackh(vs);                    // CHECK: @llvm.ppc.altivec.vupkhsh
-  res_vbi = vec_unpackh(vbs);                   // CHECK: @llvm.ppc.altivec.vupkhsh
-  res_vui = vec_unpackh(vp);                    // CHECK: @llvm.ppc.altivec.vupkhsh
-  res_vs  = vec_vupkhsb(vsc);                   // CHECK: @llvm.ppc.altivec.vupkhsb
-  res_vbs = vec_vupkhsb(vbc);                   // CHECK: @llvm.ppc.altivec.vupkhsb
-  res_vi  = vec_vupkhsh(vs);                    // CHECK: @llvm.ppc.altivec.vupkhsh
-  res_vbi = vec_vupkhsh(vbs);                   // CHECK: @llvm.ppc.altivec.vupkhsh
-  res_vui = vec_vupkhsh(vp);                    // CHECK: @llvm.ppc.altivec.vupkhsh
+  res_vs  = vec_unpackh(vsc);
+// CHECK: @llvm.ppc.altivec.vupkhsb
+// CHECK-LE: @llvm.ppc.altivec.vupklsb
+
+  res_vbs = vec_unpackh(vbc);
+// CHECK: @llvm.ppc.altivec.vupkhsb
+// CHECK-LE: @llvm.ppc.altivec.vupklsb
+
+  res_vi  = vec_unpackh(vs);
+// CHECK: @llvm.ppc.altivec.vupkhsh
+// CHECK-LE: @llvm.ppc.altivec.vupklsh
+
+  res_vbi = vec_unpackh(vbs);
+// CHECK: @llvm.ppc.altivec.vupkhsh
+// CHECK-LE: @llvm.ppc.altivec.vupklsh
+
+  res_vui = vec_unpackh(vp);
+// CHECK: @llvm.ppc.altivec.vupkhpx
+// CHECK-LE: @llvm.ppc.altivec.vupklpx
+
+  res_vs  = vec_vupkhsb(vsc);
+// CHECK: @llvm.ppc.altivec.vupkhsb
+// CHECK-LE: @llvm.ppc.altivec.vupklsb
+
+  res_vbs = vec_vupkhsb(vbc);
+// CHECK: @llvm.ppc.altivec.vupkhsb
+// CHECK-LE: @llvm.ppc.altivec.vupklsb
+
+  res_vi  = vec_vupkhsh(vs);
+// CHECK: @llvm.ppc.altivec.vupkhsh
+// CHECK-LE: @llvm.ppc.altivec.vupklsh
+
+  res_vbi = vec_vupkhsh(vbs);
+// CHECK: @llvm.ppc.altivec.vupkhsh
+// CHECK-LE: @llvm.ppc.altivec.vupklsh
+
+  res_vui = vec_vupkhsh(vp);
+// CHECK: @llvm.ppc.altivec.vupkhpx
+// CHECK-LE: @llvm.ppc.altivec.vupklpx
 
   /* vec_unpackl */
-  res_vs  = vec_unpackl(vsc);                   // CHECK: @llvm.ppc.altivec.vupklsb
-  res_vbs = vec_unpackl(vbc);                   // CHECK: @llvm.ppc.altivec.vupklsb
-  res_vi  = vec_unpackl(vs);                    // CHECK: @llvm.ppc.altivec.vupklsh
-  res_vbi = vec_unpackl(vbs);                   // CHECK: @llvm.ppc.altivec.vupklsh
-  res_vui = vec_unpackl(vp);                    // CHECK: @llvm.ppc.altivec.vupklsh
-  res_vs  = vec_vupklsb(vsc);                   // CHECK: @llvm.ppc.altivec.vupklsb
-  res_vbs = vec_vupklsb(vbc);                   // CHECK: @llvm.ppc.altivec.vupklsb
-  res_vi  = vec_vupklsh(vs);                    // CHECK: @llvm.ppc.altivec.vupklsh
-  res_vbi = vec_vupklsh(vbs);                   // CHECK: @llvm.ppc.altivec.vupklsh
-  res_vui = vec_vupklsh(vp);                    // CHECK: @llvm.ppc.altivec.vupklsh
+  res_vs  = vec_unpackl(vsc);
+// CHECK: @llvm.ppc.altivec.vupklsb
+// CHECK-LE: @llvm.ppc.altivec.vupkhsb
+
+  res_vbs = vec_unpackl(vbc);
+// CHECK: @llvm.ppc.altivec.vupklsb
+// CHECK-LE: @llvm.ppc.altivec.vupkhsb
+
+  res_vi  = vec_unpackl(vs);
+// CHECK: @llvm.ppc.altivec.vupklsh
+// CHECK-LE: @llvm.ppc.altivec.vupkhsh
+
+  res_vbi = vec_unpackl(vbs);
+// CHECK: @llvm.ppc.altivec.vupklsh
+// CHECK-LE: @llvm.ppc.altivec.vupkhsh
+
+  res_vui = vec_unpackl(vp);
+// CHECK: @llvm.ppc.altivec.vupklpx
+// CHECK-LE: @llvm.ppc.altivec.vupkhpx
+
+  res_vs  = vec_vupklsb(vsc);
+// CHECK: @llvm.ppc.altivec.vupklsb
+// CHECK-LE: @llvm.ppc.altivec.vupkhsb
+
+  res_vbs = vec_vupklsb(vbc);
+// CHECK: @llvm.ppc.altivec.vupklsb
+// CHECK-LE: @llvm.ppc.altivec.vupkhsb
+
+  res_vi  = vec_vupklsh(vs);
+// CHECK: @llvm.ppc.altivec.vupklsh
+// CHECK-LE: @llvm.ppc.altivec.vupkhsh
+
+  res_vbi = vec_vupklsh(vbs);
+// CHECK: @llvm.ppc.altivec.vupklsh
+// CHECK-LE: @llvm.ppc.altivec.vupkhsh
+
+  res_vui = vec_vupklsh(vp);
+// CHECK: @llvm.ppc.altivec.vupklpx
+// CHECK-LE: @llvm.ppc.altivec.vupkhpx
 
   /* vec_xor */
-  res_vsc = vec_xor(vsc, vsc);                  // CHECK: xor <16 x i8>
-  res_vsc = vec_xor(vbc, vsc);                  // CHECK: xor <16 x i8>
-  res_vsc = vec_xor(vsc, vbc);                  // CHECK: xor <16 x i8>
-  res_vuc = vec_xor(vuc, vuc);                  // CHECK: xor <16 x i8>
-  res_vuc = vec_xor(vbc, vuc);                  // CHECK: xor <16 x i8>
-  res_vuc = vec_xor(vuc, vbc);                  // CHECK: xor <16 x i8>
-  res_vbc = vec_xor(vbc, vbc);                  // CHECK: xor <16 x i8>
-  res_vs  = vec_xor(vs, vs);                    // CHECK: xor <8 x i16>
-  res_vs  = vec_xor(vbs, vs);                   // CHECK: xor <8 x i16>
-  res_vs  = vec_xor(vs, vbs);                   // CHECK: xor <8 x i16>
-  res_vus = vec_xor(vus, vus);                  // CHECK: xor <8 x i16>
-  res_vus = vec_xor(vbs, vus);                  // CHECK: xor <8 x i16>
-  res_vus = vec_xor(vus, vbs);                  // CHECK: xor <8 x i16>
-  res_vbs = vec_xor(vbs, vbs);                  // CHECK: xor <8 x i16>
-  res_vi  = vec_xor(vi, vi);                    // CHECK: xor <4 x i32>
-  res_vi  = vec_xor(vbi, vi);                   // CHECK: xor <4 x i32>
-  res_vi  = vec_xor(vi, vbi);                   // CHECK: xor <4 x i32>
-  res_vui = vec_xor(vui, vui);                  // CHECK: xor <4 x i32>
-  res_vui = vec_xor(vbi, vui);                  // CHECK: xor <4 x i32>
-  res_vui = vec_xor(vui, vbi);                  // CHECK: xor <4 x i32>
-  res_vbi = vec_xor(vbi, vbi);                  // CHECK: xor <4 x i32>
-  res_vf  = vec_xor(vf, vf);                    // CHECK: xor <4 x i32>
-  res_vf  = vec_xor(vbi, vf);                   // CHECK: xor <4 x i32>
-  res_vf  = vec_xor(vf, vbi);                   // CHECK: xor <4 x i32>
-  res_vsc = vec_vxor(vsc, vsc);                 // CHECK: xor <16 x i8>
-  res_vsc = vec_vxor(vbc, vsc);                 // CHECK: xor <16 x i8>
-  res_vsc = vec_vxor(vsc, vbc);                 // CHECK: xor <16 x i8>
-  res_vuc = vec_vxor(vuc, vuc);                 // CHECK: xor <16 x i8>
-  res_vuc = vec_vxor(vbc, vuc);                 // CHECK: xor <16 x i8>
-  res_vuc = vec_vxor(vuc, vbc);                 // CHECK: xor <16 x i8>
-  res_vbc = vec_vxor(vbc, vbc);                 // CHECK: xor <16 x i8>
-  res_vs  = vec_vxor(vs, vs);                   // CHECK: xor <8 x i16>
-  res_vs  = vec_vxor(vbs, vs);                  // CHECK: xor <8 x i16>
-  res_vs  = vec_vxor(vs, vbs);                  // CHECK: xor <8 x i16>
-  res_vus = vec_vxor(vus, vus);                 // CHECK: xor <8 x i16>
-  res_vus = vec_vxor(vbs, vus);                 // CHECK: xor <8 x i16>
-  res_vus = vec_vxor(vus, vbs);                 // CHECK: xor <8 x i16>
-  res_vbs = vec_vxor(vbs, vbs);                 // CHECK: xor <8 x i16>
-  res_vi  = vec_vxor(vi, vi);                   // CHECK: xor <4 x i32>
-  res_vi  = vec_vxor(vbi, vi);                  // CHECK: xor <4 x i32>
-  res_vi  = vec_vxor(vi, vbi);                  // CHECK: xor <4 x i32>
-  res_vui = vec_vxor(vui, vui);                 // CHECK: xor <4 x i32>
-  res_vui = vec_vxor(vbi, vui);                 // CHECK: xor <4 x i32>
-  res_vui = vec_vxor(vui, vbi);                 // CHECK: xor <4 x i32>
-  res_vbi = vec_vxor(vbi, vbi);                 // CHECK: xor <4 x i32>
-  res_vf  = vec_vxor(vf, vf);                   // CHECK: xor <4 x i32>
-  res_vf  = vec_vxor(vbi, vf);                  // CHECK: xor <4 x i32>
-  res_vf  = vec_vxor(vf, vbi);                  // CHECK: xor <4 x i32>
+  res_vsc = vec_xor(vsc, vsc);
+// CHECK: xor <16 x i8>
+// CHECK-LE: xor <16 x i8>
+
+  res_vsc = vec_xor(vbc, vsc);
+// CHECK: xor <16 x i8>
+// CHECK-LE: xor <16 x i8>
+
+  res_vsc = vec_xor(vsc, vbc);
+// CHECK: xor <16 x i8>
+// CHECK-LE: xor <16 x i8>
+
+  res_vuc = vec_xor(vuc, vuc);
+// CHECK: xor <16 x i8>
+// CHECK-LE: xor <16 x i8>
+
+  res_vuc = vec_xor(vbc, vuc);
+// CHECK: xor <16 x i8>
+// CHECK-LE: xor <16 x i8>
+
+  res_vuc = vec_xor(vuc, vbc);
+// CHECK: xor <16 x i8>
+// CHECK-LE: xor <16 x i8>
+
+  res_vbc = vec_xor(vbc, vbc);
+// CHECK: xor <16 x i8>
+// CHECK-LE: xor <16 x i8>
+
+  res_vs  = vec_xor(vs, vs);
+// CHECK: xor <8 x i16>
+// CHECK-LE: xor <8 x i16>
+
+  res_vs  = vec_xor(vbs, vs);
+// CHECK: xor <8 x i16>
+// CHECK-LE: xor <8 x i16>
+
+  res_vs  = vec_xor(vs, vbs);
+// CHECK: xor <8 x i16>
+// CHECK-LE: xor <8 x i16>
+
+  res_vus = vec_xor(vus, vus);
+// CHECK: xor <8 x i16>
+// CHECK-LE: xor <8 x i16>
+
+  res_vus = vec_xor(vbs, vus);
+// CHECK: xor <8 x i16>
+// CHECK-LE: xor <8 x i16>
+
+  res_vus = vec_xor(vus, vbs);
+// CHECK: xor <8 x i16>
+// CHECK-LE: xor <8 x i16>
+
+  res_vbs = vec_xor(vbs, vbs);
+// CHECK: xor <8 x i16>
+// CHECK-LE: xor <8 x i16>
+
+  res_vi  = vec_xor(vi, vi);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vi  = vec_xor(vbi, vi);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vi  = vec_xor(vi, vbi);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vui = vec_xor(vui, vui);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vui = vec_xor(vbi, vui);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vui = vec_xor(vui, vbi);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vbi = vec_xor(vbi, vbi);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vf  = vec_xor(vf, vf);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vf  = vec_xor(vbi, vf);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vf  = vec_xor(vf, vbi);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vsc = vec_vxor(vsc, vsc);
+// CHECK: xor <16 x i8>
+// CHECK-LE: xor <16 x i8>
+
+  res_vsc = vec_vxor(vbc, vsc);
+// CHECK: xor <16 x i8>
+// CHECK-LE: xor <16 x i8>
+
+  res_vsc = vec_vxor(vsc, vbc);
+// CHECK: xor <16 x i8>
+// CHECK-LE: xor <16 x i8>
+
+  res_vuc = vec_vxor(vuc, vuc);
+// CHECK: xor <16 x i8>
+// CHECK-LE: xor <16 x i8>
+
+  res_vuc = vec_vxor(vbc, vuc);
+// CHECK: xor <16 x i8>
+// CHECK-LE: xor <16 x i8>
+
+  res_vuc = vec_vxor(vuc, vbc);
+// CHECK: xor <16 x i8>
+// CHECK-LE: xor <16 x i8>
+
+  res_vbc = vec_vxor(vbc, vbc);
+// CHECK: xor <16 x i8>
+// CHECK-LE: xor <16 x i8>
+
+  res_vs  = vec_vxor(vs, vs);
+// CHECK: xor <8 x i16>
+// CHECK-LE: xor <8 x i16>
+
+  res_vs  = vec_vxor(vbs, vs);
+// CHECK: xor <8 x i16>
+// CHECK-LE: xor <8 x i16>
+
+  res_vs  = vec_vxor(vs, vbs);
+// CHECK: xor <8 x i16>
+// CHECK-LE: xor <8 x i16>
+
+  res_vus = vec_vxor(vus, vus);
+// CHECK: xor <8 x i16>
+// CHECK-LE: xor <8 x i16>
+
+  res_vus = vec_vxor(vbs, vus);
+// CHECK: xor <8 x i16>
+// CHECK-LE: xor <8 x i16>
+
+  res_vus = vec_vxor(vus, vbs);
+// CHECK: xor <8 x i16>
+// CHECK-LE: xor <8 x i16>
+
+  res_vbs = vec_vxor(vbs, vbs);
+// CHECK: xor <8 x i16>
+// CHECK-LE: xor <8 x i16>
+
+  res_vi  = vec_vxor(vi, vi);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vi  = vec_vxor(vbi, vi);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vi  = vec_vxor(vi, vbi);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vui = vec_vxor(vui, vui);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vui = vec_vxor(vbi, vui);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vui = vec_vxor(vui, vbi);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vbi = vec_vxor(vbi, vbi);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vf  = vec_vxor(vf, vf);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vf  = vec_vxor(vbi, vf);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
+
+  res_vf  = vec_vxor(vf, vbi);
+// CHECK: xor <4 x i32>
+// CHECK-LE: xor <4 x i32>
 
   /* ------------------------------ extensions -------------------------------------- */
 
   /* vec_extract */
-  res_sc = vec_extract(vsc, param_i);           // CHECK: extractelement <16 x i8>
-  res_uc = vec_extract(vuc, param_i);           // CHECK: extractelement <16 x i8>
-  res_s  = vec_extract(vs, param_i);            // CHECK: extractelement <8 x i16>
-  res_us = vec_extract(vus, param_i);           // CHECK: extractelement <8 x i16>
-  res_i  = vec_extract(vi, param_i);            // CHECK: extractelement <4 x i32>
-  res_ui = vec_extract(vui, param_i);           // CHECK: extractelement <4 x i32>
-  res_f  = vec_extract(vf, param_i);            // CHECK: extractelement <4 x float>
+  res_sc = vec_extract(vsc, param_i);
+// CHECK: extractelement <16 x i8>
+// CHECK-LE: extractelement <16 x i8>
+
+  res_uc = vec_extract(vuc, param_i);
+// CHECK: extractelement <16 x i8>
+// CHECK-LE: extractelement <16 x i8>
+
+  res_s  = vec_extract(vs, param_i);
+// CHECK: extractelement <8 x i16>
+// CHECK-LE: extractelement <8 x i16>
+
+  res_us = vec_extract(vus, param_i);
+// CHECK: extractelement <8 x i16>
+// CHECK-LE: extractelement <8 x i16>
+
+  res_i  = vec_extract(vi, param_i);
+// CHECK: extractelement <4 x i32>
+// CHECK-LE: extractelement <4 x i32>
+
+  res_ui = vec_extract(vui, param_i);
+// CHECK: extractelement <4 x i32>
+// CHECK-LE: extractelement <4 x i32>
+
+  res_f  = vec_extract(vf, param_i);
+// CHECK: extractelement <4 x float>
+// CHECK-LE: extractelement <4 x float>
 
   /* vec_insert */
-  res_vsc = vec_insert(param_sc, vsc, param_i); // CHECK: insertelement <16 x i8>
-  res_vuc = vec_insert(param_uc, vuc, param_i); // CHECK: insertelement <16 x i8>
-  res_vs  = vec_insert(param_s, vs, param_i);   // CHECK: insertelement <8 x i16>
-  res_vus = vec_insert(param_us, vus, param_i); // CHECK: insertelement <8 x i16>
-  res_vi  = vec_insert(param_i, vi, param_i);   // CHECK: insertelement <4 x i32>
-  res_vui = vec_insert(param_ui, vui, param_i); // CHECK: insertelement <4 x i32>
-  res_vf  = vec_insert(param_f, vf, param_i);   // CHECK: insertelement <4 x float>
+  res_vsc = vec_insert(param_sc, vsc, param_i);
+// CHECK: insertelement <16 x i8>
+// CHECK-LE: insertelement <16 x i8>
+
+  res_vuc = vec_insert(param_uc, vuc, param_i);
+// CHECK: insertelement <16 x i8>
+// CHECK-LE: insertelement <16 x i8>
+
+  res_vs  = vec_insert(param_s, vs, param_i);
+// CHECK: insertelement <8 x i16>
+// CHECK-LE: insertelement <8 x i16>
+
+  res_vus = vec_insert(param_us, vus, param_i);
+// CHECK: insertelement <8 x i16>
+// CHECK-LE: insertelement <8 x i16>
+
+  res_vi  = vec_insert(param_i, vi, param_i);
+// CHECK: insertelement <4 x i32>
+// CHECK-LE: insertelement <4 x i32>
+
+  res_vui = vec_insert(param_ui, vui, param_i);
+// CHECK: insertelement <4 x i32>
+// CHECK-LE: insertelement <4 x i32>
+
+  res_vf  = vec_insert(param_f, vf, param_i);
+// CHECK: insertelement <4 x float>
+// CHECK-LE: insertelement <4 x float>
 
   /* vec_lvlx */
-  res_vsc = vec_lvlx(0, &param_sc);             // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vsc = vec_lvlx(0, &param_sc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vsc = vec_lvlx(0, &vsc);                  // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vsc = vec_lvlx(0, &vsc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vuc = vec_lvlx(0, &param_uc);             // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vuc = vec_lvlx(0, &param_uc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vuc = vec_lvlx(0, &vuc);                  // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vuc = vec_lvlx(0, &vuc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vbc = vec_lvlx(0, &vbc);                  // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vbc = vec_lvlx(0, &vbc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vs  = vec_lvlx(0, &param_s);              // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vs  = vec_lvlx(0, &param_s);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vs  = vec_lvlx(0, &vs);                   // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vs  = vec_lvlx(0, &vs);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vus = vec_lvlx(0, &param_us);             // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vus = vec_lvlx(0, &param_us);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vus = vec_lvlx(0, &vus);                  // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vus = vec_lvlx(0, &vus);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vbs = vec_lvlx(0, &vbs);                  // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vbs = vec_lvlx(0, &vbs);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vp  = vec_lvlx(0, &vp);                   // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vp  = vec_lvlx(0, &vp);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vi  = vec_lvlx(0, &param_i);              // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vi  = vec_lvlx(0, &param_i);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vi  = vec_lvlx(0, &vi);                   // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vi  = vec_lvlx(0, &vi);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vui = vec_lvlx(0, &param_ui);             // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vui = vec_lvlx(0, &param_ui);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vui = vec_lvlx(0, &vui);                  // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vui = vec_lvlx(0, &vui);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vbi = vec_lvlx(0, &vbi);                  // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vbi = vec_lvlx(0, &vbi);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vf  = vec_lvlx(0, &vf);                   // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x float> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vf  = vec_lvlx(0, &vf);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x float> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x float> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
   /* vec_lvlxl */
-  res_vsc = vec_lvlxl(0, &param_sc);            // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vsc = vec_lvlxl(0, &param_sc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vsc = vec_lvlxl(0, &vsc);                 // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vsc = vec_lvlxl(0, &vsc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vuc = vec_lvlxl(0, &param_uc);            // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vuc = vec_lvlxl(0, &param_uc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vuc = vec_lvlxl(0, &vuc);                 // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vuc = vec_lvlxl(0, &vuc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vbc = vec_lvlxl(0, &vbc);                 // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vbc = vec_lvlxl(0, &vbc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vs  = vec_lvlxl(0, &param_s);             // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vs  = vec_lvlxl(0, &param_s);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vs  = vec_lvlxl(0, &vs);                  // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vs  = vec_lvlxl(0, &vs);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vus = vec_lvlxl(0, &param_us);            // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vus = vec_lvlxl(0, &param_us);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vus = vec_lvlxl(0, &vus);                 // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vus = vec_lvlxl(0, &vus);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vbs = vec_lvlxl(0, &vbs);                 // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vbs = vec_lvlxl(0, &vbs);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vp  = vec_lvlxl(0, &vp);                  // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vp  = vec_lvlxl(0, &vp);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vi  = vec_lvlxl(0, &param_i);             // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vi  = vec_lvlxl(0, &param_i);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vi  = vec_lvlxl(0, &vi);                  // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vi  = vec_lvlxl(0, &vi);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vui = vec_lvlxl(0, &param_ui);            // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vui = vec_lvlxl(0, &param_ui);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vui = vec_lvlxl(0, &vui);                 // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vui = vec_lvlxl(0, &vui);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vbi = vec_lvlxl(0, &vbi);                 // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vbi = vec_lvlxl(0, &vbi);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vf  = vec_lvlxl(0, &vf);                  // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x float> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vf  = vec_lvlxl(0, &vf);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x float> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x float> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
   /* vec_lvrx */
-  res_vsc = vec_lvrx(0, &param_sc);             // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vsc = vec_lvrx(0, &param_sc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vsc = vec_lvrx(0, &vsc);                  // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vsc = vec_lvrx(0, &vsc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vuc = vec_lvrx(0, &param_uc);             // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vuc = vec_lvrx(0, &param_uc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vuc = vec_lvrx(0, &vuc);                  // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vuc = vec_lvrx(0, &vuc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vbc = vec_lvrx(0, &vbc);                  // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vbc = vec_lvrx(0, &vbc);
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vs  = vec_lvrx(0, &param_s);              // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vs  = vec_lvrx(0, &param_s);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vs  = vec_lvrx(0, &vs);                   // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vs  = vec_lvrx(0, &vs);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vus = vec_lvrx(0, &param_us);             // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vus = vec_lvrx(0, &param_us);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vus = vec_lvrx(0, &vus);                  // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vus = vec_lvrx(0, &vus);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vbs = vec_lvrx(0, &vbs);                  // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vbs = vec_lvrx(0, &vbs);
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vp  = vec_lvrx(0, &vp);                   // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vp  = vec_lvrx(0, &vp);
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vi  = vec_lvrx(0, &param_i);              // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vi  = vec_lvrx(0, &param_i);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vi  = vec_lvrx(0, &vi);                   // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vi  = vec_lvrx(0, &vi);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vui = vec_lvrx(0, &param_ui);             // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vui = vec_lvrx(0, &param_ui);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vui = vec_lvrx(0, &vui);                  // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vui = vec_lvrx(0, &vui);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vbi = vec_lvrx(0, &vbi);                  // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vbi = vec_lvrx(0, &vbi);
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vf  = vec_lvrx(0, &vf);                   // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x float> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vf  = vec_lvrx(0, &vf);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x float> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x float> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
   /* vec_lvrxl */
-  res_vsc = vec_lvrxl(0, &param_sc);            // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vsc = vec_lvrxl(0, &param_sc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vsc = vec_lvrxl(0, &vsc);                 // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vsc = vec_lvrxl(0, &vsc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vuc = vec_lvrxl(0, &param_uc);            // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vuc = vec_lvrxl(0, &param_uc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vuc = vec_lvrxl(0, &vuc);                 // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vuc = vec_lvrxl(0, &vuc);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vbc = vec_lvrxl(0, &vbc);                 // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vbc = vec_lvrxl(0, &vbc);
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vs  = vec_lvrxl(0, &param_s);             // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vs  = vec_lvrxl(0, &param_s);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vs  = vec_lvrxl(0, &vs);                  // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vs  = vec_lvrxl(0, &vs);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vus = vec_lvrxl(0, &param_us);            // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vus = vec_lvrxl(0, &param_us);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vus = vec_lvrxl(0, &vus);                 // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vus = vec_lvrxl(0, &vus);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vbs = vec_lvrxl(0, &vbs);                 // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vbs = vec_lvrxl(0, &vbs);
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vp  = vec_lvrxl(0, &vp);                  // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vp  = vec_lvrxl(0, &vp);
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vi  = vec_lvrxl(0, &param_i);             // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vi  = vec_lvrxl(0, &param_i);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vi  = vec_lvrxl(0, &vi);                  // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vi  = vec_lvrxl(0, &vi);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vui = vec_lvrxl(0, &param_ui);            // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vui = vec_lvrxl(0, &param_ui);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vui = vec_lvrxl(0, &vui);                 // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vui = vec_lvrxl(0, &vui);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vbi = vec_lvrxl(0, &vbi);                 // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vbi = vec_lvrxl(0, &vbi);
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
-  res_vf  = vec_lvrxl(0, &vf);                  // CHECK: @llvm.ppc.altivec.lvxl
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x float> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
+  res_vf  = vec_lvrxl(0, &vf);
+// CHECK: @llvm.ppc.altivec.lvxl
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x float> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvxl
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x float> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
 
   /* vec_stvlx */
-  vec_stvlx(vsc, 0, &param_sc);                 // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvlx(vsc, 0, &param_sc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvlx(vsc, 0, &vsc);                      // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvlx(vsc, 0, &vsc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvlx(vuc, 0, &param_uc);                 // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvlx(vuc, 0, &param_uc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvlx(vuc, 0, &vuc);                      // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvlx(vuc, 0, &vuc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvlx(vbc, 0, &vbc);                      // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvlx(vbc, 0, &vbc);
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvlx(vs, 0, &param_s);                   // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvlx(vs, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvlx(vs, 0, &vs);                        // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvlx(vs, 0, &vs);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvlx(vus, 0, &param_us);                 // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvlx(vus, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvlx(vus, 0, &vus);                      // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvlx(vus, 0, &vus);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvlx(vbs, 0, &vbs);                      // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvlx(vbs, 0, &vbs);
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvlx(vp, 0, &vp);                        // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvlx(vp, 0, &vp);
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvlx(vi, 0, &param_i);                   // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvlx(vi, 0, &param_i);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvlx(vi, 0, &vi);                        // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvlx(vi, 0, &vi);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvlx(vui, 0, &param_ui);                 // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvlx(vui, 0, &param_ui);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvlx(vui, 0, &vui);                      // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvlx(vui, 0, &vui);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvlx(vbi, 0, &vbi);                      // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvlx(vbi, 0, &vbi);
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvlx(vf, 0, &vf);                        // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x float> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvlx(vf, 0, &vf);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x float> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x float> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
   /* vec_stvlxl */
-  vec_stvlxl(vsc, 0, &param_sc);                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvlxl(vsc, 0, &param_sc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvlxl(vsc, 0, &vsc);                     // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvlxl(vsc, 0, &vsc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvlxl(vuc, 0, &param_uc);                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvlxl(vuc, 0, &param_uc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvlxl(vuc, 0, &vuc);                     // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvlxl(vuc, 0, &vuc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvlxl(vbc, 0, &vbc);                     // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvlxl(vbc, 0, &vbc);
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvlxl(vs, 0, &param_s);                  // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvlxl(vs, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvlxl(vs, 0, &vs);                       // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvlxl(vs, 0, &vs);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvlxl(vus, 0, &param_us);                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvlxl(vus, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvlxl(vus, 0, &vus);                     // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvlxl(vus, 0, &vus);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvlxl(vbs, 0, &vbs);                     // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvlxl(vbs, 0, &vbs);
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvlxl(vp, 0, &vp);                       // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvlxl(vp, 0, &vp);
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvlxl(vi, 0, &param_i);                  // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvlxl(vi, 0, &param_i);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvlxl(vi, 0, &vi);                       // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvlxl(vi, 0, &vi);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvlxl(vui, 0, &param_ui);                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvlxl(vui, 0, &param_ui);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvlxl(vui, 0, &vui);                     // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvlxl(vui, 0, &vui);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvlxl(vbi, 0, &vbi);                     // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvlxl(vbi, 0, &vbi);
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvlxl(vf, 0, &vf);                       // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x float> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvlxl(vf, 0, &vf);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x float> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x float> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
   /* vec_stvrx */
-  vec_stvrx(vsc, 0, &param_sc);                 // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvrx(vsc, 0, &param_sc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvrx(vsc, 0, &vsc);                      // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvrx(vsc, 0, &vsc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvrx(vuc, 0, &param_uc);                 // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvrx(vuc, 0, &param_uc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvrx(vuc, 0, &vuc);                      // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvrx(vuc, 0, &vuc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvrx(vbc, 0, &vbc);                      // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvrx(vbc, 0, &vbc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvrx(vs, 0, &param_s);                   // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvrx(vs, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvrx(vs, 0, &vs);                        // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvrx(vs, 0, &vs);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvrx(vus, 0, &param_us);                 // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvrx(vus, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvrx(vus, 0, &vus);                      // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvrx(vus, 0, &vus);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvrx(vbs, 0, &vbs);                      // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvrx(vbs, 0, &vbs);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvrx(vp, 0, &vp);                        // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvrx(vp, 0, &vp);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvrx(vi, 0, &param_i);                   // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvrx(vi, 0, &param_i);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvrx(vi, 0, &vi);                        // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvrx(vi, 0, &vi);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvrx(vui, 0, &param_ui);                 // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvrx(vui, 0, &param_ui);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvrx(vui, 0, &vui);                      // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvrx(vui, 0, &vui);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvrx(vbi, 0, &vbi);                      // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvrx(vbi, 0, &vbi);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
-  vec_stvrx(vf, 0, &vf);                        // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x float> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvx
+  vec_stvrx(vf, 0, &vf);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x float> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvx
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x float> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvx
 
   /* vec_stvrxl */
-  vec_stvrxl(vsc, 0, &param_sc);                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvrxl(vsc, 0, &param_sc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvrxl(vsc, 0, &vsc);                     // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvrxl(vsc, 0, &vsc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvrxl(vuc, 0, &param_uc);                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvrxl(vuc, 0, &param_uc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvrxl(vuc, 0, &vuc);                     // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvrxl(vuc, 0, &vuc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvrxl(vbc, 0, &vbc);                     // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvrxl(vbc, 0, &vbc);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvrxl(vs, 0, &param_s);                  // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvrxl(vs, 0, &param_s);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvrxl(vs, 0, &vs);                       // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvrxl(vs, 0, &vs);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvrxl(vus, 0, &param_us);                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvrxl(vus, 0, &param_us);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvrxl(vus, 0, &vus);                     // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvrxl(vus, 0, &vus);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvrxl(vbs, 0, &vbs);                     // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvrxl(vbs, 0, &vbs);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvrxl(vp, 0, &vp);                       // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvrxl(vp, 0, &vp);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvrxl(vi, 0, &param_i);                  // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvrxl(vi, 0, &param_i);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvrxl(vi, 0, &vi);                       // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvrxl(vi, 0, &vi);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvrxl(vui, 0, &param_ui);                // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvrxl(vui, 0, &param_ui);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvrxl(vui, 0, &vui);                     // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvrxl(vui, 0, &vui);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvrxl(vbi, 0, &vbi);                     // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvrxl(vbi, 0, &vbi);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
-  vec_stvrxl(vf, 0, &vf);                       // CHECK: @llvm.ppc.altivec.lvx
-                                                // CHECK: @llvm.ppc.altivec.lvsl
-                                                // CHECK: store <4 x float> zeroinitializer
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.lvsr
-                                                // CHECK: @llvm.ppc.altivec.vperm
-                                                // CHECK: @llvm.ppc.altivec.stvxl
+  vec_stvrxl(vf, 0, &vf);
+// CHECK: @llvm.ppc.altivec.lvx
+// CHECK: @llvm.ppc.altivec.lvsl
+// CHECK: store <4 x float> zeroinitializer
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.lvsr
+// CHECK: @llvm.ppc.altivec.vperm
+// CHECK: @llvm.ppc.altivec.stvxl
+// CHECK-LE: @llvm.ppc.altivec.lvx
+// CHECK-LE: @llvm.ppc.altivec.lvsl
+// CHECK-LE: store <4 x float> zeroinitializer
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.lvsr
+// CHECK-LE: @llvm.ppc.altivec.vperm
+// CHECK-LE: @llvm.ppc.altivec.stvxl
 
   /* vec_promote */
-  res_vsc = vec_promote(param_sc, 0);           // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: insertelement <16 x i8>
+  res_vsc = vec_promote(param_sc, 0);
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: insertelement <16 x i8>
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: insertelement <16 x i8>
 
-  res_vuc = vec_promote(param_uc, 0);           // CHECK: store <16 x i8> zeroinitializer
-                                                // CHECK: insertelement <16 x i8>
+  res_vuc = vec_promote(param_uc, 0);
+// CHECK: store <16 x i8> zeroinitializer
+// CHECK: insertelement <16 x i8>
+// CHECK-LE: store <16 x i8> zeroinitializer
+// CHECK-LE: insertelement <16 x i8>
 
-  res_vs  = vec_promote(param_s, 0);            // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: insertelement <8 x i16>
+  res_vs  = vec_promote(param_s, 0);
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: insertelement <8 x i16>
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: insertelement <8 x i16>
 
-  res_vus = vec_promote(param_us, 0);           // CHECK: store <8 x i16> zeroinitializer
-                                                // CHECK: insertelement <8 x i16>
+  res_vus = vec_promote(param_us, 0);
+// CHECK: store <8 x i16> zeroinitializer
+// CHECK: insertelement <8 x i16>
+// CHECK-LE: store <8 x i16> zeroinitializer
+// CHECK-LE: insertelement <8 x i16>
 
-  res_vi  = vec_promote(param_i, 0);            // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: insertelement <4 x i32>
+  res_vi  = vec_promote(param_i, 0);
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: insertelement <4 x i32>
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: insertelement <4 x i32>
 
-  res_vui = vec_promote(param_ui, 0);           // CHECK: store <4 x i32> zeroinitializer
-                                                // CHECK: insertelement <4 x i32>
+  res_vui = vec_promote(param_ui, 0);
+// CHECK: store <4 x i32> zeroinitializer
+// CHECK: insertelement <4 x i32>
+// CHECK-LE: store <4 x i32> zeroinitializer
+// CHECK-LE: insertelement <4 x i32>
 
-  res_vf  = vec_promote(param_f, 0);            // CHECK: store <4 x float> zeroinitializer
-                                                // CHECK: insertelement <4 x float>
+  res_vf  = vec_promote(param_f, 0);
+// CHECK: store <4 x float> zeroinitializer
+// CHECK: insertelement <4 x float>
+// CHECK-LE: store <4 x float> zeroinitializer
+// CHECK-LE: insertelement <4 x float>
 
   /* vec_splats */
-  res_vsc = vec_splats(param_sc);               // CHECK: insertelement <16 x i8>
+  res_vsc = vec_splats(param_sc);
+// CHECK: insertelement <16 x i8>
+// CHECK-LE: insertelement <16 x i8>
 
-  res_vuc = vec_splats(param_uc);               // CHECK: insertelement <16 x i8>
+  res_vuc = vec_splats(param_uc);
+// CHECK: insertelement <16 x i8>
+// CHECK-LE: insertelement <16 x i8>
 
-  res_vs  = vec_splats(param_s);                // CHECK: insertelement <8 x i16>
+  res_vs  = vec_splats(param_s);
+// CHECK: insertelement <8 x i16>
+// CHECK-LE: insertelement <8 x i16>
 
-  res_vus = vec_splats(param_us);               // CHECK: insertelement <8 x i16>
+  res_vus = vec_splats(param_us);
+// CHECK: insertelement <8 x i16>
+// CHECK-LE: insertelement <8 x i16>
 
-  res_vi  = vec_splats(param_i);                // CHECK: insertelement <4 x i32>
+  res_vi  = vec_splats(param_i);
+// CHECK: insertelement <4 x i32>
+// CHECK-LE: insertelement <4 x i32>
 
-  res_vui = vec_splats(param_ui);               // CHECK: insertelement <4 x i32>
+  res_vui = vec_splats(param_ui);
+// CHECK: insertelement <4 x i32>
+// CHECK-LE: insertelement <4 x i32>
 
-  res_vf  = vec_splats(param_f);                // CHECK: insertelement <4 x float>
+  res_vf  = vec_splats(param_f);
+// CHECK: insertelement <4 x float>
+// CHECK-LE: insertelement <4 x float>
 
   /* ------------------------------ predicates -------------------------------------- */
 
   /* vec_all_eq */
-  res_i = vec_all_eq(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_all_eq(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_all_eq(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_all_eq(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_all_eq(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_all_eq(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_all_eq(vbc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_all_eq(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_all_eq(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_all_eq(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_all_eq(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_all_eq(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_all_eq(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_all_eq(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_all_eq(vp, vp);                   // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_all_eq(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_all_eq(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_all_eq(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_all_eq(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_all_eq(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_all_eq(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_all_eq(vbi, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_all_eq(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+  res_i = vec_all_eq(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_all_eq(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_all_eq(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_all_eq(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_all_eq(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_all_eq(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_all_eq(vbc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_all_eq(vs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_all_eq(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_all_eq(vus, vus);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_all_eq(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_all_eq(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_all_eq(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_all_eq(vbs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_all_eq(vp, vp);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_all_eq(vi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_all_eq(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_all_eq(vui, vui);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_all_eq(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_all_eq(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_all_eq(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_all_eq(vbi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_all_eq(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpeqfp.p
 
   /* vec_all_ge */
-  res_i = vec_all_ge(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
-  res_i = vec_all_ge(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
-  res_i = vec_all_ge(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_ge(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_ge(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_ge(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_ge(vbc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_ge(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
-  res_i = vec_all_ge(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
-  res_i = vec_all_ge(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_ge(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_ge(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_ge(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_ge(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_ge(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
-  res_i = vec_all_ge(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
-  res_i = vec_all_ge(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_ge(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_ge(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_ge(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_ge(vbi, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_ge(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpgefp.p
+  res_i = vec_all_ge(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p
+
+  res_i = vec_all_ge(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p
+
+  res_i = vec_all_ge(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_ge(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_ge(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_ge(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_ge(vbc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_ge(vs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p
+
+  res_i = vec_all_ge(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p
+
+  res_i = vec_all_ge(vus, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_ge(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_ge(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_ge(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_ge(vbs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_ge(vi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p
+
+  res_i = vec_all_ge(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p
+
+  res_i = vec_all_ge(vui, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_ge(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_ge(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_ge(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_ge(vbi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_ge(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgefp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgefp.p
 
   /* vec_all_gt */
-  res_i = vec_all_gt(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
-  res_i = vec_all_gt(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
-  res_i = vec_all_gt(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_gt(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_gt(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_gt(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_gt(vbc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_gt(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
-  res_i = vec_all_gt(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
-  res_i = vec_all_gt(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_gt(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_gt(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_gt(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_gt(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_gt(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
-  res_i = vec_all_gt(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
-  res_i = vec_all_gt(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_gt(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_gt(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_gt(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_gt(vbi, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_gt(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+  res_i = vec_all_gt(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p
+
+  res_i = vec_all_gt(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p
+
+  res_i = vec_all_gt(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_gt(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_gt(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_gt(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_gt(vbc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_gt(vs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p
+
+  res_i = vec_all_gt(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p
+
+  res_i = vec_all_gt(vus, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_gt(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_gt(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_gt(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_gt(vbs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_gt(vi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p
+
+  res_i = vec_all_gt(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p
+
+  res_i = vec_all_gt(vui, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_gt(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_gt(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_gt(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_gt(vbi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_gt(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtfp.p
 
   /* vec_all_in */
-  res_i = vec_all_in(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpbfp.p
+  res_i = vec_all_in(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpbfp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpbfp.p
 
   /* vec_all_le */
-  res_i = vec_all_le(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
-  res_i = vec_all_le(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
-  res_i = vec_all_le(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_le(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_le(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_le(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_le(vbc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_le(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
-  res_i = vec_all_le(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
-  res_i = vec_all_le(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_le(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_le(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_le(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_le(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_le(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
-  res_i = vec_all_le(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
-  res_i = vec_all_le(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_le(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_le(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_le(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_le(vbi, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_le(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpgefp.p
+  res_i = vec_all_le(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p
+
+  res_i = vec_all_le(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p
+
+  res_i = vec_all_le(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_le(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_le(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_le(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_le(vbc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_le(vs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p
+
+  res_i = vec_all_le(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p
+
+  res_i = vec_all_le(vus, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_le(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_le(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_le(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_le(vbs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_le(vi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p
+
+  res_i = vec_all_le(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p
+
+  res_i = vec_all_le(vui, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_le(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_le(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_le(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_le(vbi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_le(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgefp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgefp.p
 
   /* vec_all_lt */
-  res_i = vec_all_lt(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
-  res_i = vec_all_lt(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
-  res_i = vec_all_lt(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_lt(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_lt(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_lt(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_lt(vbc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_all_lt(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
-  res_i = vec_all_lt(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
-  res_i = vec_all_lt(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_lt(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_lt(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_lt(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_lt(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_all_lt(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
-  res_i = vec_all_lt(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
-  res_i = vec_all_lt(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_lt(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_lt(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_lt(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_lt(vbi, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_all_lt(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+  res_i = vec_all_lt(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p
+
+  res_i = vec_all_lt(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p
+
+  res_i = vec_all_lt(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_lt(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_lt(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_lt(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_lt(vbc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_all_lt(vs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p
+
+  res_i = vec_all_lt(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p
+
+  res_i = vec_all_lt(vus, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_lt(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_lt(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_lt(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_lt(vbs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_all_lt(vi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p
+
+  res_i = vec_all_lt(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p
+
+  res_i = vec_all_lt(vui, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_lt(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_lt(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_lt(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_lt(vbi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_all_lt(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtfp.p
 
   /* vec_all_nan */
-  res_i = vec_all_nan(vf);                      // CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+  res_i = vec_all_nan(vf);
+// CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpeqfp.p
 
   /*  vec_all_ne */
-  res_i = vec_all_ne(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_all_ne(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_all_ne(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_all_ne(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_all_ne(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_all_ne(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_all_ne(vbc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_all_ne(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_all_ne(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_all_ne(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_all_ne(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_all_ne(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_all_ne(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_all_ne(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_all_ne(vp, vp);                   // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_all_ne(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_all_ne(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_all_ne(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_all_ne(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_all_ne(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_all_ne(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_all_ne(vbi, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_all_ne(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+  res_i = vec_all_ne(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_all_ne(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_all_ne(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_all_ne(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_all_ne(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_all_ne(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_all_ne(vbc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_all_ne(vs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_all_ne(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_all_ne(vus, vus);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_all_ne(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_all_ne(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_all_ne(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_all_ne(vbs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_all_ne(vp, vp);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_all_ne(vi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_all_ne(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_all_ne(vui, vui);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_all_ne(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_all_ne(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_all_ne(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_all_ne(vbi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_all_ne(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpeqfp.p
 
   /* vec_all_nge */
-  res_i = vec_all_nge(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpgefp.p
+  res_i = vec_all_nge(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgefp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgefp.p
 
   /* vec_all_ngt */
-  res_i = vec_all_ngt(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+  res_i = vec_all_ngt(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtfp.p
 
   /* vec_all_nle */
-  res_i = vec_all_nle(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpgefp.p
+  res_i = vec_all_nle(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgefp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgefp.p
 
   /* vec_all_nlt */
-  res_i = vec_all_nlt(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+  res_i = vec_all_nlt(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtfp.p
 
   /* vec_all_numeric */
-  res_i = vec_all_numeric(vf);                  // CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+  res_i = vec_all_numeric(vf);
+// CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpeqfp.p
 
   /*  vec_any_eq */
-  res_i = vec_any_eq(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_any_eq(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_any_eq(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_any_eq(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_any_eq(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_any_eq(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_any_eq(vbc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_any_eq(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_any_eq(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_any_eq(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_any_eq(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_any_eq(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_any_eq(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_any_eq(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_any_eq(vp, vp);                   // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_any_eq(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_any_eq(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_any_eq(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_any_eq(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_any_eq(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_any_eq(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_any_eq(vbi, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_any_eq(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+  res_i = vec_any_eq(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_any_eq(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_any_eq(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_any_eq(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_any_eq(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_any_eq(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_any_eq(vbc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_any_eq(vs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_any_eq(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_any_eq(vus, vus);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_any_eq(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_any_eq(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_any_eq(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_any_eq(vbs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_any_eq(vp, vp);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_any_eq(vi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_any_eq(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_any_eq(vui, vui);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_any_eq(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_any_eq(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_any_eq(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_any_eq(vbi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_any_eq(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpeqfp.p
 
   /* vec_any_ge */
-  res_i = vec_any_ge(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
-  res_i = vec_any_ge(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
-  res_i = vec_any_ge(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_ge(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_ge(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_ge(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_ge(vbc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_ge(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
-  res_i = vec_any_ge(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
-  res_i = vec_any_ge(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_ge(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_ge(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_ge(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_ge(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_ge(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
-  res_i = vec_any_ge(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
-  res_i = vec_any_ge(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_ge(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_ge(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_ge(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_ge(vbi, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_ge(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpgefp.p
+  res_i = vec_any_ge(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p
+
+  res_i = vec_any_ge(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p
+
+  res_i = vec_any_ge(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_ge(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_ge(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_ge(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_ge(vbc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_ge(vs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p
+
+  res_i = vec_any_ge(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p
+
+  res_i = vec_any_ge(vus, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_ge(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_ge(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_ge(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_ge(vbs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_ge(vi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p
+
+  res_i = vec_any_ge(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p
+
+  res_i = vec_any_ge(vui, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_ge(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_ge(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_ge(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_ge(vbi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_ge(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgefp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgefp.p
 
   /* vec_any_gt */
-  res_i = vec_any_gt(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
-  res_i = vec_any_gt(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
-  res_i = vec_any_gt(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_gt(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_gt(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_gt(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_gt(vbc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_gt(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
-  res_i = vec_any_gt(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
-  res_i = vec_any_gt(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_gt(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_gt(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_gt(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_gt(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_gt(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
-  res_i = vec_any_gt(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
-  res_i = vec_any_gt(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_gt(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_gt(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_gt(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_gt(vbi, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_gt(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+  res_i = vec_any_gt(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p
+
+  res_i = vec_any_gt(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p
+
+  res_i = vec_any_gt(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_gt(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_gt(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_gt(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_gt(vbc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_gt(vs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p
+
+  res_i = vec_any_gt(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p
+
+  res_i = vec_any_gt(vus, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_gt(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_gt(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_gt(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_gt(vbs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_gt(vi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p
+
+  res_i = vec_any_gt(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p
+
+  res_i = vec_any_gt(vui, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_gt(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_gt(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_gt(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_gt(vbi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_gt(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtfp.p
 
   /* vec_any_le */
-  res_i = vec_any_le(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
-  res_i = vec_any_le(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
-  res_i = vec_any_le(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_le(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_le(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_le(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_le(vbc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_le(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
-  res_i = vec_any_le(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
-  res_i = vec_any_le(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_le(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_le(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_le(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_le(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_le(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
-  res_i = vec_any_le(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
-  res_i = vec_any_le(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_le(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_le(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_le(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_le(vbi, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_le(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpgefp.p
+  res_i = vec_any_le(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p
+
+  res_i = vec_any_le(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p
+
+  res_i = vec_any_le(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_le(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_le(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_le(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_le(vbc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_le(vs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p
+
+  res_i = vec_any_le(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p
+
+  res_i = vec_any_le(vus, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_le(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_le(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_le(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_le(vbs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_le(vi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p
+
+  res_i = vec_any_le(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p
+
+  res_i = vec_any_le(vui, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_le(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_le(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_le(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_le(vbi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_le(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgefp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgefp.p
 
   /* vec_any_lt */
-  res_i = vec_any_lt(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
-  res_i = vec_any_lt(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtsb.p
-  res_i = vec_any_lt(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_lt(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_lt(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_lt(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_lt(vbc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpgtub.p
-  res_i = vec_any_lt(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
-  res_i = vec_any_lt(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vcmpgtsh.p
-  res_i = vec_any_lt(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_lt(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_lt(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_lt(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_lt(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpgtuh.p
-  res_i = vec_any_lt(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
-  res_i = vec_any_lt(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vcmpgtsw.p
-  res_i = vec_any_lt(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_lt(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_lt(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_lt(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_lt(vbi, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpgtuw.p
-  res_i = vec_any_lt(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+  res_i = vec_any_lt(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p
+
+  res_i = vec_any_lt(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p
+
+  res_i = vec_any_lt(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_lt(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_lt(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_lt(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_lt(vbc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p
+
+  res_i = vec_any_lt(vs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p
+
+  res_i = vec_any_lt(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p
+
+  res_i = vec_any_lt(vus, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_lt(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_lt(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_lt(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_lt(vbs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p
+
+  res_i = vec_any_lt(vi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p
+
+  res_i = vec_any_lt(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p
+
+  res_i = vec_any_lt(vui, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_lt(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_lt(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_lt(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_lt(vbi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p
+
+  res_i = vec_any_lt(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtfp.p
 
   /* vec_any_nan */
-  res_i = vec_any_nan(vf);                      // CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+  res_i = vec_any_nan(vf);
+// CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpeqfp.p
 
   /* vec_any_ne */
-  res_i = vec_any_ne(vsc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_any_ne(vsc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_any_ne(vuc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_any_ne(vuc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_any_ne(vbc, vsc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_any_ne(vbc, vuc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_any_ne(vbc, vbc);                 // CHECK: @llvm.ppc.altivec.vcmpequb.p
-  res_i = vec_any_ne(vs, vs);                   // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_any_ne(vs, vbs);                  // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_any_ne(vus, vus);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_any_ne(vus, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_any_ne(vbs, vs);                  // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_any_ne(vbs, vus);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_any_ne(vbs, vbs);                 // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_any_ne(vp, vp);                   // CHECK: @llvm.ppc.altivec.vcmpequh.p
-  res_i = vec_any_ne(vi, vi);                   // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_any_ne(vi, vbi);                  // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_any_ne(vui, vui);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_any_ne(vui, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_any_ne(vbi, vi);                  // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_any_ne(vbi, vui);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_any_ne(vbi, vbi);                 // CHECK: @llvm.ppc.altivec.vcmpequw.p
-  res_i = vec_any_ne(vf, vf);                   // CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+  res_i = vec_any_ne(vsc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_any_ne(vsc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_any_ne(vuc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_any_ne(vuc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_any_ne(vbc, vsc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_any_ne(vbc, vuc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_any_ne(vbc, vbc);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p
+
+  res_i = vec_any_ne(vs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_any_ne(vs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_any_ne(vus, vus);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_any_ne(vus, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_any_ne(vbs, vs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_any_ne(vbs, vus);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_any_ne(vbs, vbs);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_any_ne(vp, vp);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p
+
+  res_i = vec_any_ne(vi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_any_ne(vi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_any_ne(vui, vui);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_any_ne(vui, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_any_ne(vbi, vi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_any_ne(vbi, vui);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_any_ne(vbi, vbi);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p
+
+  res_i = vec_any_ne(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpeqfp.p
 
   /* vec_any_nge */
-  res_i = vec_any_nge(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpgefp.p
+  res_i = vec_any_nge(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgefp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgefp.p
 
   /* vec_any_ngt */
-  res_i = vec_any_ngt(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+  res_i = vec_any_ngt(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtfp.p
 
   /* vec_any_nle */
-  res_i = vec_any_nle(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpgefp.p
+  res_i = vec_any_nle(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgefp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgefp.p
 
   /* vec_any_nlt */
-  res_i = vec_any_nlt(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+  res_i = vec_any_nlt(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpgtfp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtfp.p
 
   /* vec_any_numeric */
-  res_i = vec_any_numeric(vf);                  // CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+  res_i = vec_any_numeric(vf);
+// CHECK: @llvm.ppc.altivec.vcmpeqfp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpeqfp.p
 
   /* vec_any_out */
-  res_i = vec_any_out(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpbfp.p
+  res_i = vec_any_out(vf, vf);
+// CHECK: @llvm.ppc.altivec.vcmpbfp.p
+// CHECK-LE: @llvm.ppc.altivec.vcmpbfp.p
 }
 
 /* ------------------------------ Relational Operators ------------------------------ */
@@ -3059,58 +8517,183 @@
 void test7() {
   vector signed char vsc1 = (vector signed char)(-1);
   vector signed char vsc2 = (vector signed char)(-2);
-  res_i = (vsc1 == vsc2);                  // CHECK: @llvm.ppc.altivec.vcmpequb.p(i32 2
-  res_i = (vsc1 != vsc2);                  // CHECK: @llvm.ppc.altivec.vcmpequb.p(i32 0
-  res_i = (vsc1 <  vsc2);                  // CHECK: @llvm.ppc.altivec.vcmpgtsb.p(i32 2
-  res_i = (vsc1 >  vsc2);                  // CHECK: @llvm.ppc.altivec.vcmpgtsb.p(i32 2
-  res_i = (vsc1 <= vsc2);                  // CHECK: @llvm.ppc.altivec.vcmpgtsb.p(i32 0
-  res_i = (vsc1 >= vsc2);                  // CHECK: @llvm.ppc.altivec.vcmpgtsb.p(i32 0
+  res_i = (vsc1 == vsc2);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p(i32 2
+
+  res_i = (vsc1 != vsc2);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p(i32 0
+
+  res_i = (vsc1 <  vsc2);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p(i32 2
+
+  res_i = (vsc1 >  vsc2);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p(i32 2
+
+  res_i = (vsc1 <= vsc2);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p(i32 0
+
+  res_i = (vsc1 >= vsc2);
+// CHECK: @llvm.ppc.altivec.vcmpgtsb.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb.p(i32 0
+
   vector unsigned char vuc1 = (vector unsigned char)(1);
   vector unsigned char vuc2 = (vector unsigned char)(2);
-  res_i = (vuc1 == vuc2);                  // CHECK: @llvm.ppc.altivec.vcmpequb.p(i32 2
-  res_i = (vuc1 != vuc2);                  // CHECK: @llvm.ppc.altivec.vcmpequb.p(i32 0
-  res_i = (vuc1 <  vuc2);                  // CHECK: @llvm.ppc.altivec.vcmpgtub.p(i32 2
-  res_i = (vuc1 >  vuc2);                  // CHECK: @llvm.ppc.altivec.vcmpgtub.p(i32 2
-  res_i = (vuc1 <= vuc2);                  // CHECK: @llvm.ppc.altivec.vcmpgtub.p(i32 0
-  res_i = (vuc1 >= vuc2);                  // CHECK: @llvm.ppc.altivec.vcmpgtub.p(i32 0
+  res_i = (vuc1 == vuc2);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p(i32 2
+
+  res_i = (vuc1 != vuc2);
+// CHECK: @llvm.ppc.altivec.vcmpequb.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpequb.p(i32 0
+
+  res_i = (vuc1 <  vuc2);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p(i32 2
+
+  res_i = (vuc1 >  vuc2);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p(i32 2
+
+  res_i = (vuc1 <= vuc2);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p(i32 0
+
+  res_i = (vuc1 >= vuc2);
+// CHECK: @llvm.ppc.altivec.vcmpgtub.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtub.p(i32 0
+
   vector short vs1 = (vector short)(-1);
   vector short vs2 = (vector short)(-2);
-  res_i = (vs1 == vs2);                    // CHECK: @llvm.ppc.altivec.vcmpequh.p(i32 2
-  res_i = (vs1 != vs2);                    // CHECK: @llvm.ppc.altivec.vcmpequh.p(i32 0
-  res_i = (vs1 <  vs2);                    // CHECK: @llvm.ppc.altivec.vcmpgtsh.p(i32 2
-  res_i = (vs1 >  vs2);                    // CHECK: @llvm.ppc.altivec.vcmpgtsh.p(i32 2
-  res_i = (vs1 <= vs2);                    // CHECK: @llvm.ppc.altivec.vcmpgtsh.p(i32 0
-  res_i = (vs1 >= vs2);                    // CHECK: @llvm.ppc.altivec.vcmpgtsh.p(i32 0
+  res_i = (vs1 == vs2);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p(i32 2
+
+  res_i = (vs1 != vs2);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p(i32 0
+
+  res_i = (vs1 <  vs2);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p(i32 2
+
+  res_i = (vs1 >  vs2);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p(i32 2
+
+  res_i = (vs1 <= vs2);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p(i32 0
+
+  res_i = (vs1 >= vs2);
+// CHECK: @llvm.ppc.altivec.vcmpgtsh.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh.p(i32 0
+
   vector unsigned short vus1 = (vector unsigned short)(1);
   vector unsigned short vus2 = (vector unsigned short)(2);
-  res_i = (vus1 == vus2);                  // CHECK: @llvm.ppc.altivec.vcmpequh.p(i32 2
-  res_i = (vus1 != vus2);                  // CHECK: @llvm.ppc.altivec.vcmpequh.p(i32 0
-  res_i = (vus1 <  vus2);                  // CHECK: @llvm.ppc.altivec.vcmpgtuh.p(i32 2
-  res_i = (vus1 >  vus2);                  // CHECK: @llvm.ppc.altivec.vcmpgtuh.p(i32 2
-  res_i = (vus1 <= vus2);                  // CHECK: @llvm.ppc.altivec.vcmpgtuh.p(i32 0
-  res_i = (vus1 >= vus2);                  // CHECK: @llvm.ppc.altivec.vcmpgtuh.p(i32 0
+  res_i = (vus1 == vus2);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p(i32 2
+
+  res_i = (vus1 != vus2);
+// CHECK: @llvm.ppc.altivec.vcmpequh.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpequh.p(i32 0
+
+  res_i = (vus1 <  vus2);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p(i32 2
+
+  res_i = (vus1 >  vus2);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p(i32 2
+
+  res_i = (vus1 <= vus2);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p(i32 0
+
+  res_i = (vus1 >= vus2);
+// CHECK: @llvm.ppc.altivec.vcmpgtuh.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh.p(i32 0
+
   vector int vi1 = (vector int)(-1);
   vector int vi2 = (vector int)(-2);
-  res_i = (vi1 == vi2);                    // CHECK: @llvm.ppc.altivec.vcmpequw.p(i32 2
-  res_i = (vi1 != vi2);                    // CHECK: @llvm.ppc.altivec.vcmpequw.p(i32 0
-  res_i = (vi1 <  vi2);                    // CHECK: @llvm.ppc.altivec.vcmpgtsw.p(i32 2
-  res_i = (vi1 >  vi2);                    // CHECK: @llvm.ppc.altivec.vcmpgtsw.p(i32 2
-  res_i = (vi1 <= vi2);                    // CHECK: @llvm.ppc.altivec.vcmpgtsw.p(i32 0
-  res_i = (vi1 >= vi2);                    // CHECK: @llvm.ppc.altivec.vcmpgtsw.p(i32 0
+  res_i = (vi1 == vi2);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p(i32 2
+
+  res_i = (vi1 != vi2);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p(i32 0
+
+  res_i = (vi1 <  vi2);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p(i32 2
+
+  res_i = (vi1 >  vi2);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p(i32 2
+
+  res_i = (vi1 <= vi2);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p(i32 0
+
+  res_i = (vi1 >= vi2);
+// CHECK: @llvm.ppc.altivec.vcmpgtsw.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw.p(i32 0
+
   vector unsigned int vui1 = (vector unsigned int)(1);
   vector unsigned int vui2 = (vector unsigned int)(2);
-  res_i = (vui1 == vui2);                  // CHECK: @llvm.ppc.altivec.vcmpequw.p(i32 2
-  res_i = (vui1 != vui2);                  // CHECK: @llvm.ppc.altivec.vcmpequw.p(i32 0
-  res_i = (vui1 <  vui2);                  // CHECK: @llvm.ppc.altivec.vcmpgtuw.p(i32 2
-  res_i = (vui1 >  vui2);                  // CHECK: @llvm.ppc.altivec.vcmpgtuw.p(i32 2
-  res_i = (vui1 <= vui2);                  // CHECK: @llvm.ppc.altivec.vcmpgtuw.p(i32 0
-  res_i = (vui1 >= vui2);                  // CHECK: @llvm.ppc.altivec.vcmpgtuw.p(i32 0
+  res_i = (vui1 == vui2);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p(i32 2
+
+  res_i = (vui1 != vui2);
+// CHECK: @llvm.ppc.altivec.vcmpequw.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpequw.p(i32 0
+
+  res_i = (vui1 <  vui2);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p(i32 2
+
+  res_i = (vui1 >  vui2);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p(i32 2
+
+  res_i = (vui1 <= vui2);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p(i32 0
+
+  res_i = (vui1 >= vui2);
+// CHECK: @llvm.ppc.altivec.vcmpgtuw.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw.p(i32 0
+
   vector float vf1 = (vector float)(1.0);
   vector float vf2 = (vector float)(2.0);
-  res_i = (vf1 == vf2);                    // CHECK: @llvm.ppc.altivec.vcmpeqfp.p(i32 2
-  res_i = (vf1 != vf2);                    // CHECK: @llvm.ppc.altivec.vcmpeqfp.p(i32 0
-  res_i = (vf1 <  vf2);                    // CHECK: @llvm.ppc.altivec.vcmpgtfp.p(i32 2
-  res_i = (vf1 >  vf2);                    // CHECK: @llvm.ppc.altivec.vcmpgtfp.p(i32 2
-  res_i = (vf1 <= vf2);                    // CHECK: @llvm.ppc.altivec.vcmpgefp.p(i32 2
-  res_i = (vf1 >= vf2);                    // CHECK: @llvm.ppc.altivec.vcmpgefp.p(i32 2
+  res_i = (vf1 == vf2);
+// CHECK: @llvm.ppc.altivec.vcmpeqfp.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpeqfp.p(i32 2
+
+  res_i = (vf1 != vf2);
+// CHECK: @llvm.ppc.altivec.vcmpeqfp.p(i32 0
+// CHECK-LE: @llvm.ppc.altivec.vcmpeqfp.p(i32 0
+
+  res_i = (vf1 <  vf2);
+// CHECK: @llvm.ppc.altivec.vcmpgtfp.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtfp.p(i32 2
+
+  res_i = (vf1 >  vf2);
+// CHECK: @llvm.ppc.altivec.vcmpgtfp.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpgtfp.p(i32 2
+
+  res_i = (vf1 <= vf2);
+// CHECK: @llvm.ppc.altivec.vcmpgefp.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpgefp.p(i32 2
+
+  res_i = (vf1 >= vf2);
+// CHECK: @llvm.ppc.altivec.vcmpgefp.p(i32 2
+// CHECK-LE: @llvm.ppc.altivec.vcmpgefp.p(i32 2
 }
diff --git a/test/CodeGen/builtins-ppc.c b/test/CodeGen/builtins-ppc.c
index ee27a4c..9ef5e37 100644
--- a/test/CodeGen/builtins-ppc.c
+++ b/test/CodeGen/builtins-ppc.c
@@ -1,4 +1,4 @@
-// REQUIRES: ppc32-registered-target
+// REQUIRES: powerpc-registered-target
 // RUN: %clang_cc1 -triple powerpc-unknown-unknown -emit-llvm %s -o - | FileCheck %s
 
 void test_eh_return_data_regno()
diff --git a/test/CodeGen/builtins-x86.c b/test/CodeGen/builtins-x86.c
index 261bf2f..0f038b8 100644
--- a/test/CodeGen/builtins-x86.c
+++ b/test/CodeGen/builtins-x86.c
@@ -263,6 +263,10 @@
   tmp_V4f = __builtin_ia32_cvtpi2ps(tmp_V4f, tmp_V2i);
   tmp_V2i = __builtin_ia32_cvtps2pi(tmp_V4f);
   tmp_i = __builtin_ia32_cvtss2si(tmp_V4f);
+
+  tmp_i = __builtin_ia32_rdtsc();
+  tmp_i = __builtin_ia32_rdtscp(&tmp_Ui);
+  tmp_LLi = __builtin_ia32_rdpmc(tmp_i);
 #ifdef USE_64
   tmp_LLi = __builtin_ia32_cvtss2si64(tmp_V4f);
 #endif
@@ -448,9 +452,6 @@
   tmp_i = __builtin_ia32_movmskps256(tmp_V8f);
   __builtin_ia32_vzeroall();
   __builtin_ia32_vzeroupper();
-  tmp_V4f = __builtin_ia32_vbroadcastss(tmp_fCp);
-  tmp_V4d = __builtin_ia32_vbroadcastsd256(tmp_dCp);
-  tmp_V8f = __builtin_ia32_vbroadcastss256(tmp_fCp);
   tmp_V4d = __builtin_ia32_vbroadcastf128_pd256(tmp_V2dCp);
   tmp_V8f = __builtin_ia32_vbroadcastf128_ps256(tmp_V4fCp);
   __builtin_ia32_storeupd256(tmp_dp, tmp_V4d);
diff --git a/test/CodeGen/builtinshufflevector2.c b/test/CodeGen/builtinshufflevector2.c
index 04405b5..8712c99 100644
--- a/test/CodeGen/builtinshufflevector2.c
+++ b/test/CodeGen/builtinshufflevector2.c
@@ -6,23 +6,23 @@
 // CHECK-LABEL: define void @clang_shufflevector_v_v(
 void clang_shufflevector_v_v( float4* A, float4 x, uint4 mask ) {
 // CHECK: [[MASK:%.*]] = and <4 x i32> {{%.*}}, <i32 3, i32 3, i32 3, i32 3>
-// CHECK: [[I:%.*]] = extractelement <4 x i32> [[MASK]], i32 0
-// CHECK: [[E:%.*]] = extractelement <4 x float> [[X:%.*]], i32 [[I]]
+// CHECK: [[I:%.*]] = extractelement <4 x i32> [[MASK]], i{{[0-9]+}} 0
+// CHECK: [[E:%.*]] = extractelement <4 x float> [[X:%.*]], i{{[0-9]+}} [[I]]
 //
 // Here is where ToT Clang code generation makes a mistake.  
 // It uses [[I]] as the insertion index instead of 0.
 // Similarly on the remaining insertelement.
-// CHECK: [[V:%[a-zA-Z0-9._]+]] = insertelement <4 x float> undef, float [[E]], i32 0
+// CHECK: [[V:%[a-zA-Z0-9._]+]] = insertelement <4 x float> undef, float [[E]], i{{[0-9]+}} 0
 
-// CHECK: [[I:%.*]] = extractelement <4 x i32> [[MASK]], i32 1
-// CHECK: [[E:%.*]] = extractelement <4 x float> [[X]], i32 [[I]]
-// CHECK: [[V2:%.*]] = insertelement <4 x float> [[V]], float [[E]], i32 1
-// CHECK: [[I:%.*]] = extractelement <4 x i32> [[MASK]], i32 2
-// CHECK: [[E:%.*]] = extractelement <4 x float> [[X]], i32 [[I]]
-// CHECK: [[V3:%.*]] = insertelement <4 x float> [[V2]], float [[E]], i32 2
-// CHECK: [[I:%.*]] = extractelement <4 x i32> [[MASK]], i32 3
-// CHECK: [[E:%.*]] = extractelement <4 x float> [[X]], i32 [[I]]
-// CHECK: [[V4:%.*]] = insertelement <4 x float> [[V3]], float [[E]], i32 3
+// CHECK: [[I:%.*]] = extractelement <4 x i32> [[MASK]], i{{[0-9]+}} 1
+// CHECK: [[E:%.*]] = extractelement <4 x float> [[X]], i{{[0-9]+}} [[I]]
+// CHECK: [[V2:%.*]] = insertelement <4 x float> [[V]], float [[E]], i{{[0-9]+}} 1
+// CHECK: [[I:%.*]] = extractelement <4 x i32> [[MASK]], i{{[0-9]+}} 2
+// CHECK: [[E:%.*]] = extractelement <4 x float> [[X]], i{{[0-9]+}} [[I]]
+// CHECK: [[V3:%.*]] = insertelement <4 x float> [[V2]], float [[E]], i{{[0-9]+}} 2
+// CHECK: [[I:%.*]] = extractelement <4 x i32> [[MASK]], i{{[0-9]+}} 3
+// CHECK: [[E:%.*]] = extractelement <4 x float> [[X]], i{{[0-9]+}} [[I]]
+// CHECK: [[V4:%.*]] = insertelement <4 x float> [[V3]], float [[E]], i{{[0-9]+}} 3
 // CHECK: store <4 x float> [[V4]], <4 x float>* {{%.*}},
   *A = __builtin_shufflevector( x, mask );
 }
diff --git a/test/CodeGen/c-strings.c b/test/CodeGen/c-strings.c
index ff86619..d82bc25 100644
--- a/test/CodeGen/c-strings.c
+++ b/test/CodeGen/c-strings.c
@@ -1,14 +1,18 @@
-// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=ITANIUM
+// RUN: %clang_cc1 -triple %ms_abi_triple -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=MSABI
 
 // Should be 3 hello strings, two global (of different sizes), the rest are
 // shared.
 
 // CHECK: @align = global i8 [[ALIGN:[0-9]+]]
-// CHECK: @.str = private unnamed_addr constant [6 x i8] c"hello\00"
-// CHECK: @f1.x = internal global i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0)
+// ITANIUM: @.str = private unnamed_addr constant [6 x i8] c"hello\00"
+// MSABI: @"\01??_C@_05CJBACGMB@hello?$AA@" = linkonce_odr unnamed_addr constant [6 x i8] c"hello\00", align 1
+// ITANIUM: @f1.x = internal global i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0)
+// MSABI: @f1.x = internal global i8* getelementptr inbounds ([6 x i8]* @"\01??_C@_05CJBACGMB@hello?$AA@", i32 0, i32 0)
 // CHECK: @f2.x = internal global [6 x i8] c"hello\00", align [[ALIGN]]
 // CHECK: @f3.x = internal global [8 x i8] c"hello\00\00\00", align [[ALIGN]]
-// CHECK: @f4.x = internal global %struct.s { i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0) }
+// ITANIUM: @f4.x = internal global %struct.s { i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0) }
+// MSABI: @f4.x = internal global %struct.s { i8* getelementptr inbounds ([6 x i8]* @"\01??_C@_05CJBACGMB@hello?$AA@", i32 0, i32 0) }
 // CHECK: @x = global [3 x i8] c"ola", align [[ALIGN]]
 
 #if defined(__s390x__)
@@ -22,7 +26,8 @@
 // CHECK-LABEL: define void @f0()
 void f0() {
   bar("hello");
-  // CHECK: call void @bar({{.*}} @.str
+  // ITANIUM: call void @bar({{.*}} @.str
+  // MSABI: call void @bar({{.*}} @"\01??_C@_05CJBACGMB@hello?$AA@"
 }
 
 // CHECK-LABEL: define void @f1()
diff --git a/test/CodeGen/c11atomics.c b/test/CodeGen/c11atomics.c
index 5c761b1..f4c9522 100644
--- a/test/CodeGen/c11atomics.c
+++ b/test/CodeGen/c11atomics.c
@@ -12,6 +12,9 @@
 // they're sufficiently rare that it's not worth making sure that the semantics
 // are correct.
 
+// CHECK: @testStructGlobal = global {{.*}} { i16 1, i16 2, i16 3, i16 4 }
+// CHECK: @testPromotedStructGlobal = global {{.*}} { %{{.*}} { i16 1, i16 2, i16 3 }, [2 x i8] zeroinitializer }
+
 typedef int __attribute__((vector_size(16))) vector;
 
 _Atomic(_Bool) b;
@@ -224,6 +227,7 @@
 }
 
 typedef struct { short x, y, z, w; } S;
+_Atomic S testStructGlobal = (S){1, 2, 3, 4};
 // CHECK: define arm_aapcscc void @testStruct([[S:.*]]*
 void testStruct(_Atomic(S) *fp) {
 // CHECK:      [[FP:%.*]] = alloca [[S]]*, align 4
@@ -272,6 +276,7 @@
 }
 
 typedef struct { short x, y, z; } PS;
+_Atomic PS testPromotedStructGlobal = (PS){1, 2, 3};
 // CHECK: define arm_aapcscc void @testPromotedStruct([[APS:.*]]*
 void testPromotedStruct(_Atomic(PS) *fp) {
 // CHECK:      [[FP:%.*]] = alloca [[APS]]*, align 4
diff --git a/test/CodeGen/captured-statements-nested.c b/test/CodeGen/captured-statements-nested.c
index d8ec746..2ff9ee9 100644
--- a/test/CodeGen/captured-statements-nested.c
+++ b/test/CodeGen/captured-statements-nested.c
@@ -8,11 +8,12 @@
   char c;
 };
 
-void test_nest_captured_stmt(int param) {
+void test_nest_captured_stmt(int param, int size, int param_arr[size]) {
   int w;
-  // CHECK1: %struct.anon{{.*}} = type { i32*, i32* }
-  // CHECK1: %struct.anon{{.*}} = type { i32*, i32*, i32**, i32* }
-  // CHECK1: [[T:%struct.anon.*]] = type { i32*, i32*, %struct.A*, i32**, i32* }
+  int arr[param][size];
+  // CHECK1: %struct.anon{{.*}} = type { i32*, i32*, i{{.+}}*, i32**, i32* }
+  // CHECK1: %struct.anon{{.*}} = type { i32*, i32*, i32**, i32*, i{{.+}}*, i32**, i32* }
+  // CHECK1: [[T:%struct.anon.*]] = type { i32*, i32*, %struct.A*, i32**, i32*, i{{.+}}*, i32**, i32* }
   #pragma clang __debug captured
   {
     int x;
@@ -26,13 +27,15 @@
         *y = param;
         z.b = 0.1f;
         z.c = 'c';
+        param_arr[size - 1] = 2;
+        arr[10][z.a] = 12;
 
         // CHECK1: define internal void @__captured_stmt{{.*}}([[T]]
         //
         // CHECK1: getelementptr inbounds [[T]]* {{.*}}, i32 0, i32 2
         // CHECK1-NEXT: load %struct.A**
         // CHECK1-NEXT: getelementptr inbounds %struct.A*
-        // CHECK1-NEXT: store i32 1
+        // CHECK1-NEXT: store i{{.+}} 1
         //
         // CHECK1: getelementptr inbounds [[T]]* {{.*}}, i32 0, i32 1
         // CHECK1-NEXT: load i32**
@@ -59,6 +62,27 @@
         // CHECK1-NEXT: load %struct.A**
         // CHECK1-NEXT: getelementptr inbounds %struct.A*
         // CHECK1-NEXT: store i8 99
+        //
+        // CHECK1: [[SIZE_ADDR_REF:%.*]] = getelementptr inbounds [[T]]* {{.*}}, i{{.+}} 0, i{{.+}} 5
+        // CHECK1-DAG: [[SIZE_ADDR:%.*]] = load i{{.+}}** [[SIZE_ADDR_REF]]
+        // CHECK1-DAG: [[SIZE:%.*]] = load i{{.+}}* [[SIZE_ADDR]]
+        // CHECK1-DAG: [[PARAM_ARR_IDX:%.*]] = sub nsw i{{.+}} [[SIZE]], 1
+        // CHECK1-DAG: [[PARAM_ARR_ADDR_REF:%.*]] = getelementptr inbounds [[T]]* {{.*}}, i{{.+}} 0, i{{.+}} 6
+        // CHECK1-DAG: [[PARAM_ARR_ADDR:%.*]] = load i{{.+}}*** [[PARAM_ARR_ADDR_REF]]
+        // CHECK1-DAG: [[PARAM_ARR:%.*]] = load i{{.+}}** [[PARAM_ARR_ADDR]]
+        // CHECK1-DAG: [[PARAM_ARR_SIZE_MINUS_1_ADDR:%.*]] = getelementptr inbounds i{{.+}}* [[PARAM_ARR]], i{{.*}}
+        // CHECK1: store i{{.+}} 2, i{{.+}}* [[PARAM_ARR_SIZE_MINUS_1_ADDR]]
+        //
+        // CHECK1: [[Z_ADDR_REF:%.*]] = getelementptr inbounds [[T]]* {{.*}}, i{{.+}} 0, i{{.+}} 2
+        // CHECK1-DAG: [[Z_ADDR:%.*]] = load %struct.A** [[Z_ADDR_REF]]
+        // CHECK1-DAG: [[Z_A_ADDR:%.*]] = getelementptr inbounds %struct.A* [[Z_ADDR]], i{{.+}} 0, i{{.+}} 0
+        // CHECK1-DAG: [[ARR_IDX_2:%.*]] = load i{{.+}}* [[Z_A_ADDR]]
+        // CHECK1-DAG: [[ARR_ADDR_REF:%.*]] = getelementptr inbounds [[T]]* {{.*}}, i{{.+}} 0, i{{.+}} 7
+        // CHECK1-DAG: [[ARR_ADDR:%.*]] = load i{{.+}}** [[ARR_ADDR_REF]]
+        // CHECK1-DAG: [[ARR_IDX_1:%.*]] = mul {{.*}} 10
+        // CHECK1-DAG: [[ARR_10_ADDR:%.*]] = getelementptr inbounds i{{.+}}* [[ARR_ADDR]], i{{.*}} [[ARR_IDX_1]]
+        // CHECK1-DAG: [[ARR_10_Z_A_ADDR:%.*]] = getelementptr inbounds i{{.+}}* [[ARR_10_ADDR]], i{{.*}}
+        // CHECK1: store i{{.+}} 12, i{{.+}}* [[ARR_10_Z_A_ADDR]]
       }
     }
   }
diff --git a/test/CodeGen/captured-statements.c b/test/CodeGen/captured-statements.c
index c87c187..85d597a 100644
--- a/test/CodeGen/captured-statements.c
+++ b/test/CodeGen/captured-statements.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -o %t
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm %s -o %t
 // RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-GLOBALS
 // RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-1
 // RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-2
@@ -48,17 +48,31 @@
 // CHECK-2:   %i = alloca i32
 
 // Capture array
-void test3() {
+void test3(int size) {
   int arr[] = {1, 2, 3, 4, 5};
+  int vla_arr[size];
   #pragma clang __debug captured
   {
-    arr[2] = arr[1];
+    arr[2] = vla_arr[size - 1];
   }
   // CHECK-3: test3
   // CHECK-3: alloca [5 x i32]
   // CHECK-3: call void @__captured_stmt
 }
 
+// Capture VLA array
+void test4(int size, int vla_arr[size]) {
+  #pragma clang __debug captured
+  {
+    vla_arr[0] = 1;
+  }
+  // CHECK-3: test4([[INT:i.+]] {{.*}}[[SIZE:%.+]], [[INT]]*
+  // CHECK-3: store [[INT]] {{.*}}[[SIZE]], [[INT]]* [[SIZE_ADDR:%.+]],
+  // CHECK-3: [[REF:%.+]] = getelementptr inbounds
+  // CHECK-3: store [[INT]]* [[SIZE_ADDR]], [[INT]]** [[REF]]
+  // CHECK-3: call void @__captured_stmt
+}
+
 void dont_capture_global() {
   static int s;
   extern int e;
diff --git a/test/CodeGen/catch-undef-behavior.c b/test/CodeGen/catch-undef-behavior.c
index 9be2614..00962e4 100644
--- a/test/CodeGen/catch-undef-behavior.c
+++ b/test/CodeGen/catch-undef-behavior.c
@@ -22,9 +22,9 @@
 // CHECK-NULL: @[[LINE_100:.*]] = private unnamed_addr global {{.*}}, i32 100, i32 5 {{.*}}
 
 // PR6805
-// CHECK: @foo
-// CHECK-NULL: @foo
-// CHECK-TRAP: @foo
+// CHECK-LABEL: @foo
+// CHECK-NULL-LABEL: @foo
+// CHECK-TRAP-LABEL: @foo
 void foo() {
   union { int i; } u;
   // CHECK:      %[[CHECK0:.*]] = icmp ne {{.*}}* %[[PTR:.*]], null
@@ -49,7 +49,7 @@
   // CHECK-TRAP-NEXT: %[[CHECK2:.*]] = icmp eq i64 %[[MISALIGN]], 0
 
   // CHECK:      %[[OK:.*]] = and i1 %[[CHECK01]], %[[CHECK2]]
-  // CHECK-NEXT: br i1 %[[OK]], {{.*}} !prof ![[WEIGHT_MD:.*]]
+  // CHECK-NEXT: br i1 %[[OK]], {{.*}} !prof ![[WEIGHT_MD:.*]], !nosanitize
 
   // CHECK-TRAP:      %[[OK:.*]] = and i1 %[[CHECK01]], %[[CHECK2]]
   // CHECK-TRAP-NEXT: br i1 %[[OK]], {{.*}}
@@ -68,8 +68,8 @@
   u.i=1;
 }
 
-// CHECK: @bar
-// CHECK-TRAP: @bar
+// CHECK-LABEL: @bar
+// CHECK-TRAP-LABEL: @bar
 int bar(int *a) {
   // CHECK:      %[[SIZE:.*]] = call i64 @llvm.objectsize.i64
   // CHECK-NEXT: icmp uge i64 %[[SIZE]], 4
@@ -95,14 +95,14 @@
   return *a;
 }
 
-// CHECK: @addr_space
+// CHECK-LABEL: @addr_space
 int addr_space(int __attribute__((address_space(256))) *a) {
   // CHECK-NOT: __ubsan
   return *a;
 }
 
-// CHECK: @lsh_overflow
-// CHECK-TRAP: @lsh_overflow
+// CHECK-LABEL: @lsh_overflow
+// CHECK-TRAP-LABEL: @lsh_overflow
 int lsh_overflow(int a, int b) {
   // CHECK:      %[[INBOUNDS:.*]] = icmp ule i32 %[[RHS:.*]], 31
   // CHECK-NEXT: br i1 %[[INBOUNDS]], label %[[CHECKBB:.*]], label %[[CONTBB:.*]]
@@ -145,8 +145,8 @@
   return a << b;
 }
 
-// CHECK: @rsh_inbounds
-// CHECK-TRAP: @rsh_inbounds
+// CHECK-LABEL: @rsh_inbounds
+// CHECK-TRAP-LABEL: @rsh_inbounds
 int rsh_inbounds(int a, int b) {
   // CHECK:      %[[INBOUNDS:.*]] = icmp ule i32 %[[RHS:.*]], 31
   // CHECK:      br i1 %[[INBOUNDS]]
@@ -170,8 +170,8 @@
   return a >> b;
 }
 
-// CHECK: @load
-// CHECK-TRAP: @load
+// CHECK-LABEL: @load
+// CHECK-TRAP-LABEL: @load
 int load(int *p) {
   // CHECK: call void @__ubsan_handle_type_mismatch(i8* bitcast ({{.*}} @[[LINE_500]] to i8*), i64 %{{.*}})
 
@@ -181,8 +181,8 @@
   return *p;
 }
 
-// CHECK: @store
-// CHECK-TRAP: @store
+// CHECK-LABEL: @store
+// CHECK-TRAP-LABEL: @store
 void store(int *p, int q) {
   // CHECK: call void @__ubsan_handle_type_mismatch(i8* bitcast ({{.*}} @[[LINE_600]] to i8*), i64 %{{.*}})
 
@@ -194,8 +194,8 @@
 
 struct S { int k; };
 
-// CHECK: @member_access
-// CHECK-TRAP: @member_access
+// CHECK-LABEL: @member_access
+// CHECK-TRAP-LABEL: @member_access
 int *member_access(struct S *p) {
   // CHECK: call void @__ubsan_handle_type_mismatch(i8* bitcast ({{.*}} @[[LINE_700]] to i8*), i64 %{{.*}})
 
@@ -205,8 +205,8 @@
   return &p->k;
 }
 
-// CHECK: @signed_overflow
-// CHECK-TRAP: @signed_overflow
+// CHECK-LABEL: @signed_overflow
+// CHECK-TRAP-LABEL: @signed_overflow
 int signed_overflow(int a, int b) {
   // CHECK:      %[[ARG1:.*]] = zext
   // CHECK-NEXT: %[[ARG2:.*]] = zext
@@ -218,8 +218,8 @@
   return a + b;
 }
 
-// CHECK: @no_return
-// CHECK-TRAP: @no_return
+// CHECK-LABEL: @no_return
+// CHECK-TRAP-LABEL: @no_return
 int no_return() {
   // Reaching the end of a noreturn function is fine in C.
   // FIXME: If the user explicitly requests -fsanitize=return, we should catch
@@ -233,7 +233,7 @@
   // CHECK-TRAP: ret i32
 }
 
-// CHECK: @vla_bound
+// CHECK-LABEL: @vla_bound
 void vla_bound(int n) {
   // CHECK:      icmp sgt i32 %[[PARAM:.*]], 0
   //
@@ -243,14 +243,14 @@
   int arr[n * 3];
 }
 
-// CHECK: @int_float_no_overflow
+// CHECK-LABEL: @int_float_no_overflow
 float int_float_no_overflow(__int128 n) {
   // CHECK-NOT: call void @__ubsan_handle
   return n;
 }
 
-// CHECK: @int_float_overflow
-// CHECK-TRAP: @int_float_overflow
+// CHECK-LABEL: @int_float_overflow
+// CHECK-TRAP-LABEL: @int_float_overflow
 float int_float_overflow(unsigned __int128 n) {
   // This is 2**104. FLT_MAX is 2**128 - 2**104.
   // CHECK: icmp ule i128 %{{.*}}, -20282409603651670423947251286016
@@ -264,8 +264,8 @@
   return n;
 }
 
-// CHECK: @int_fp16_overflow
-// CHECK-TRAP: @int_fp16_overflow
+// CHECK-LABEL: @int_fp16_overflow
+// CHECK-TRAP-LABEL: @int_fp16_overflow
 void int_fp16_overflow(int n, __fp16 *p) {
   // CHECK: %[[GE:.*]] = icmp sge i32 %{{.*}}, -65504
   // CHECK: %[[LE:.*]] = icmp sle i32 %{{.*}}, 65504
@@ -282,8 +282,8 @@
   *p = n;
 }
 
-// CHECK: @float_int_overflow
-// CHECK-TRAP: @float_int_overflow
+// CHECK-LABEL: @float_int_overflow
+// CHECK-TRAP-LABEL: @float_int_overflow
 int float_int_overflow(float f) {
   // CHECK: %[[GE:.*]] = fcmp ogt float %[[F:.*]], 0xC1E0000020000000
   // CHECK: %[[LE:.*]] = fcmp olt float %[[F]], 0x41E0000000000000
@@ -303,15 +303,15 @@
   return f;
 }
 
-// CHECK: @long_double_int_overflow
-// CHECK-TRAP: @long_double_int_overflow
+// CHECK-LABEL: @long_double_int_overflow
+// CHECK-TRAP-LABEL: @long_double_int_overflow
 int long_double_int_overflow(long double ld) {
   // CHECK: alloca x86_fp80
   // CHECK: %[[GE:.*]] = fcmp ogt x86_fp80 %[[F:.*]], 0xKC01E8000000100000000
   // CHECK: %[[LE:.*]] = fcmp olt x86_fp80 %[[F]], 0xK401E8000000000000000
   // CHECK: and i1 %[[GE]], %[[LE]]
 
-  // CHECK: store x86_fp80 %[[F]], x86_fp80* %[[ALLOCA:.*]]
+  // CHECK: store x86_fp80 %[[F]], x86_fp80* %[[ALLOCA:.*]], !nosanitize
   // CHECK: %[[ARG:.*]] = ptrtoint x86_fp80* %[[ALLOCA]] to i64
   // CHECK: call void @__ubsan_handle_float_cast_overflow({{.*}}, i64 %[[ARG]]
 
@@ -325,8 +325,8 @@
   return ld;
 }
 
-// CHECK: @float_uint_overflow
-// CHECK-TRAP: @float_uint_overflow
+// CHECK-LABEL: @float_uint_overflow
+// CHECK-TRAP-LABEL: @float_uint_overflow
 unsigned float_uint_overflow(float f) {
   // CHECK: %[[GE:.*]] = fcmp ogt float %[[F:.*]], -1.{{0*}}e+00
   // CHECK: %[[LE:.*]] = fcmp olt float %[[F]], 0x41F0000000000000
@@ -343,8 +343,8 @@
   return f;
 }
 
-// CHECK: @fp16_char_overflow
-// CHECK-TRAP: @fp16_char_overflow
+// CHECK-LABEL: @fp16_char_overflow
+// CHECK-TRAP-LABEL: @fp16_char_overflow
 signed char fp16_char_overflow(__fp16 *p) {
   // CHECK: %[[GE:.*]] = fcmp ogt float %[[F:.*]], -1.29{{0*}}e+02
   // CHECK: %[[LE:.*]] = fcmp olt float %[[F]], 1.28{{0*}}e+02
@@ -361,8 +361,8 @@
   return *p;
 }
 
-// CHECK: @float_float_overflow
-// CHECK-TRAP: @float_float_overflow
+// CHECK-LABEL: @float_float_overflow
+// CHECK-TRAP-LABEL: @float_float_overflow
 float float_float_overflow(double f) {
   // CHECK: %[[F:.*]] = call double @llvm.fabs.f64(
   // CHECK: %[[GE:.*]] = fcmp ogt double %[[F]], 0x47EFFFFFE0000000
@@ -382,8 +382,8 @@
   return f;
 }
 
-// CHECK:          @int_divide_overflow
-// CHECK-OVERFLOW: @int_divide_overflow
+// CHECK-LABEL:          @int_divide_overflow
+// CHECK-OVERFLOW-LABEL: @int_divide_overflow
 int int_divide_overflow(int a, int b) {
   // CHECK:               %[[ZERO:.*]] = icmp ne i32 %[[B:.*]], 0
   // CHECK-OVERFLOW-NOT:  icmp ne i32 %{{.*}}, 0
@@ -418,7 +418,7 @@
   // CHECK-TRAP:     }
 }
 
-// CHECK: @sour_bool
+// CHECK-LABEL: @sour_bool
 _Bool sour_bool(_Bool *p) {
   // CHECK: %[[OK:.*]] = icmp ule i8 {{.*}}, 1
   // CHECK: br i1 %[[OK]]
diff --git a/test/CodeGen/cfstring.c b/test/CodeGen/cfstring.c
index 9d98b56..fc86e42 100644
--- a/test/CodeGen/cfstring.c
+++ b/test/CodeGen/cfstring.c
@@ -5,9 +5,9 @@
 //
 // RUN: %clang_cc1 -fwritable-strings -emit-llvm %s -o - | FileCheck %s
 //
-// CHECK: @.str = linker_private unnamed_addr constant [14 x i8] c"Hello, World!\00", align 1
-// CHECK: @.str1 = linker_private unnamed_addr constant [7 x i8] c"yo joe\00", align 1
-// CHECK: @.str3 = linker_private unnamed_addr constant [16 x i8] c"Goodbye, World!\00", align 1
+// CHECK: @.str = private unnamed_addr constant [14 x i8] c"Hello, World!\00", section "__TEXT,__cstring,cstring_literals", align 1
+// CHECK: @.str1 = private unnamed_addr constant [7 x i8] c"yo joe\00", section "__TEXT,__cstring,cstring_literals", align 1
+// CHECK: @.str3 = private unnamed_addr constant [16 x i8] c"Goodbye, World!\00", section "__TEXT,__cstring,cstring_literals", align 1
 
 #define CFSTR __builtin___CFStringMakeConstantString
 
diff --git a/test/CodeGen/clear_cache.c b/test/CodeGen/clear_cache.c
new file mode 100644
index 0000000..f859d7f
--- /dev/null
+++ b/test/CodeGen/clear_cache.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+
+char buffer[32] = "This is a largely unused buffer";
+
+// __builtin___clear_cache always maps to @llvm.clear_cache, but what
+// each back-end produces is different, and this is tested in LLVM
+
+int main() {
+  __builtin___clear_cache(buffer, buffer+32);
+// CHECK: @llvm.clear_cache(i8* getelementptr {{.*}}, i8* getelementptr {{.*}} (i8* getelementptr {{.*}} 32))
+  return 0;
+}
diff --git a/test/CodeGen/complex-convert.c b/test/CodeGen/complex-convert.c
index e35be9c..6ecb884 100644
--- a/test/CodeGen/complex-convert.c
+++ b/test/CodeGen/complex-convert.c
@@ -22,9 +22,14 @@
   _Complex signed long long csll1;
   _Complex unsigned long long cull1;
   // CHECK-LABEL: define void @foo(
-  // CHECK: alloca i[[CHSIZE:[0-9]+]], align [[CHALIGN:[0-9]+]]
-  // CHECK-NEXT: alloca i[[CHSIZE]], align [[CHALIGN]]
-  // CHECK-NEXT: alloca i[[LLSIZE:[0-9]+]], align [[LLALIGN:[0-9]+]]
+  // Match the prototype to pick up the size of sc and sll.
+  // CHECK: i[[CHSIZE:[0-9]+]]{{[^,]*}},
+  // CHECK: i[[CHSIZE]]{{[^,]*}},
+  // CHECK: i[[LLSIZE:[0-9]+]]
+
+  // Match against the allocas to pick up the alignments.
+  // CHECK: alloca i[[CHSIZE]], align [[CHALIGN:[0-9]+]]
+  // CHECK: alloca i[[LLSIZE]], align [[LLALIGN:[0-9]+]]
 
   sc1 = csc;
   // CHECK: %[[VAR1:[A-Za-z0-9.]+]] = getelementptr inbounds { i[[CHSIZE]], i[[CHSIZE]]  }* %[[CSC:[A-Za-z0-9.]+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
diff --git a/test/CodeGen/cxx-default-arg.cpp b/test/CodeGen/cxx-default-arg.cpp
index 12e2666..7688e79 100644
--- a/test/CodeGen/cxx-default-arg.cpp
+++ b/test/CodeGen/cxx-default-arg.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -o %t
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm %s -o %t
 
 // Note-LABEL: define CLANG_GENERATE_KNOWN_GOOD and compile to generate code
 // that makes all of the defaulted arguments explicit. The resulting
diff --git a/test/CodeGen/darwin-string-literals.c b/test/CodeGen/darwin-string-literals.c
index c7d9ff9..41e59cb 100644
--- a/test/CodeGen/darwin-string-literals.c
+++ b/test/CodeGen/darwin-string-literals.c
@@ -1,17 +1,17 @@
 // RUN: %clang_cc1 -triple i386-apple-darwin9 -emit-llvm %s -o - | FileCheck -check-prefix CHECK-LSB %s
 
 // CHECK-LSB: @.str = private unnamed_addr constant [8 x i8] c"string0\00"
-// CHECK-LSB: @.str1 = linker_private unnamed_addr constant [8 x i8] c"string1\00"
-// CHECK-LSB: @.str2 = internal unnamed_addr constant [18 x i16] [i16 104, i16 101, i16 108, i16 108, i16 111, i16 32, i16 8594, i16 32, i16 9731, i16 32, i16 8592, i16 32, i16 119, i16 111, i16 114, i16 108, i16 100, i16 0], align 2
-// CHECK-LSB: @.str4 = internal unnamed_addr constant [6 x i16] [i16 116, i16 101, i16 115, i16 116, i16 8482, i16 0], align 2
+// CHECK-LSB: @.str1 = private unnamed_addr constant [8 x i8] c"string1\00"
+// CHECK-LSB: @.str2 = private unnamed_addr constant [18 x i16] [i16 104, i16 101, i16 108, i16 108, i16 111, i16 32, i16 8594, i16 32, i16 9731, i16 32, i16 8592, i16 32, i16 119, i16 111, i16 114, i16 108, i16 100, i16 0], section "__TEXT,__ustring", align 2
+// CHECK-LSB: @.str4 = private unnamed_addr constant [6 x i16] [i16 116, i16 101, i16 115, i16 116, i16 8482, i16 0], section "__TEXT,__ustring", align 2
 
 
 // RUN: %clang_cc1 -triple powerpc-apple-darwin9 -emit-llvm %s -o - | FileCheck -check-prefix CHECK-MSB %s
 
 // CHECK-MSB: @.str = private unnamed_addr constant [8 x i8] c"string0\00"
-// CHECK-MSB: @.str1 = linker_private unnamed_addr constant [8 x i8] c"string1\00"
-// CHECK-MSB: @.str2 = internal unnamed_addr constant [18 x i16] [i16 104, i16 101, i16 108, i16 108, i16 111, i16 32, i16 8594, i16 32, i16 9731, i16 32, i16 8592, i16 32, i16 119, i16 111, i16 114, i16 108, i16 100, i16 0], align 2
-// CHECK-MSB: @.str4 = internal unnamed_addr constant [6 x i16] [i16 116, i16 101, i16 115, i16 116, i16 8482, i16 0], align 2
+// CHECK-MSB: @.str1 = private unnamed_addr constant [8 x i8] c"string1\00"
+// CHECK-MSB: @.str2 = private unnamed_addr constant [18 x i16] [i16 104, i16 101, i16 108, i16 108, i16 111, i16 32, i16 8594, i16 32, i16 9731, i16 32, i16 8592, i16 32, i16 119, i16 111, i16 114, i16 108, i16 100, i16 0], section "__TEXT,__ustring", align 2
+// CHECK-MSB: @.str4 = private unnamed_addr constant [6 x i16] [i16 116, i16 101, i16 115, i16 116, i16 8482, i16 0], section "__TEXT,__ustring", align 2
 
 const char *g0 = "string0";
 const void *g1 = __builtin___CFStringMakeConstantString("string1");
diff --git a/test/CodeGen/debug-dead-local-var.c b/test/CodeGen/debug-dead-local-var.c
deleted file mode 100644
index f9ca8f2..0000000
--- a/test/CodeGen/debug-dead-local-var.c
+++ /dev/null
@@ -1,14 +0,0 @@
-// RUN: %clang_cc1 -mllvm -asm-verbose -S -O2 -g %s -o - | FileCheck %s
-// Radar 8122864
-
-// Code is not generated for function foo, but preserve type information of
-// local variable xyz.
-static void foo() {
-// CHECK: DW_TAG_structure_type 
-  struct X { int a; int b; } xyz;
-}
-
-int bar() {
-  foo();
-  return 1;
-}
diff --git a/test/CodeGen/debug-info-block.c b/test/CodeGen/debug-info-block.c
index 403e4aa..35ee0dd 100644
--- a/test/CodeGen/debug-info-block.c
+++ b/test/CodeGen/debug-info-block.c
@@ -1,5 +1,4 @@
 // RUN: %clang_cc1 -fblocks -g -emit-llvm -o - %s | FileCheck %s
-// APPLE LOCAL file 5939894 */
 // Verify that the desired debugging type is generated for a structure
 //  member that is a pointer to a block. 
 
diff --git a/test/CodeGen/debug-info-enum.c b/test/CodeGen/debug-info-enum.c
new file mode 100644
index 0000000..acf3f52
--- /dev/null
+++ b/test/CodeGen/debug-info-enum.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -emit-llvm -g %s -o - | FileCheck %s
+
+// CHECK: metadata [[TEST3_ENUMS:![0-9]*]], {{[^,]*}}, null, null, null} ; [ DW_TAG_enumeration_type ] [e]
+// CHECK: [[TEST3_ENUMS]] = metadata !{metadata [[TEST3_E:![0-9]*]]}
+// CHECK: [[TEST3_E]] = {{.*}}, metadata !"E", i64 -1} ; [ DW_TAG_enumerator ] [E :: -1]
+
+enum e;
+void func(enum e *p) {
+}
+enum e { E = -1 };
diff --git a/test/CodeGen/debug-info-iv.c b/test/CodeGen/debug-info-iv.c
deleted file mode 100644
index aafd71d..0000000
--- a/test/CodeGen/debug-info-iv.c
+++ /dev/null
@@ -1,36 +0,0 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -Os -S -g  -o - %s | FileCheck %s
-// REQUIRES: x86-registered-target
-
-int calculate(int);
-static void test_indvars(int *Array1, int Array2[100][200]) {
-  unsigned i, j;
-  Array1[1] = Array2[3][6] = 12345;
-
-  for (i = 0; i < 100; i+=2)
-    Array1[i] = i;           /* Step by non unit amount */
-
-  for (i = 3; i < 103; i++)
-    Array1[i] = i+4;         /* Step with an offset */
-
-  for (i = 13; i < 100; i++)
-    for (j = 0; j < 100; j+=3)       /* 2d array access */
-      Array2[i][j/3] = Array2[i][i];
-}
-
-
-int main() {
-  int Array[100][200], i, j;
-  double sum = 0.0;
-
-  for (i=0; i < 100; i+=2)
-    for (j=0; j < 200; j++)
-      Array[i][j] = 0;
-  test_indvars(Array[0], Array);
-
-//CHECK:	.loc	2 31
-  for (i=0; i < 100; i+=2)
-    for (j=0; j < 200; j++)
-      sum += Array[i][j];
-
-  return calculate(sum);
-}
diff --git a/test/CodeGen/debug-info-scope-file.c b/test/CodeGen/debug-info-scope-file.c
new file mode 100644
index 0000000..3479ade
--- /dev/null
+++ b/test/CodeGen/debug-info-scope-file.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -g -emit-llvm < %s | FileCheck %s
+
+// Check that, just because we emitted a function from a different file doesn't
+// mean we insert a file-change inside the next function.
+
+// CHECK: ret void, !dbg [[F1_LINE:![0-9]*]]
+// CHECK: ret void, !dbg [[F2_LINE:![0-9]*]]
+// CHECK: [[F1:![0-9]*]] = {{.*}} ; [ DW_TAG_subprogram ] {{.*}} [def] [f1]
+// CHECK: [[F2:![0-9]*]] = {{.*}} ; [ DW_TAG_subprogram ] {{.*}} [def] [f2]
+// CHECK: [[F1_LINE]] = {{.*}}, metadata [[F1]], null}
+// CHECK: [[F2_LINE]] = {{.*}}, metadata [[F2]], null}
+
+void f1() {
+}
+
+# 2 "foo.c"
+
+void f2() {
+}
+
diff --git a/test/CodeGen/debug-info-typedef.c b/test/CodeGen/debug-info-typedef.c
new file mode 100644
index 0000000..51ebcc4
--- /dev/null
+++ b/test/CodeGen/debug-info-typedef.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -emit-llvm -g -I%p %s -o - | FileCheck %s
+// Test that the location of the typedef points to the header file.
+#line 1 "a.c"
+#line 2 "b.h"
+typedef int MyType;
+#line 2 "a.c"
+
+MyType a;
+
+// CHECK: metadata ![[HEADER:[0-9]+]], null, metadata !"MyType"{{.*}} ; [ DW_TAG_typedef ] [MyType] [line 2, size 0, align 0, offset 0] [from int]
+// CHECK: ![[HEADER]] = metadata !{metadata !"b.h",
diff --git a/test/CodeGen/debug-info-var-location.c b/test/CodeGen/debug-info-var-location.c
index 12edb08..41da7d3 100644
--- a/test/CodeGen/debug-info-var-location.c
+++ b/test/CodeGen/debug-info-var-location.c
@@ -1,4 +1,5 @@
-// RUN: %clang -S -g -fverbose-asm %s -o - | FileCheck %s
+// FIXME: Check IR rather than asm, then triple is not needed.
+// RUN: %clang -Xclang -triple=%itanium_abi_triple -S -g -fverbose-asm %s -o - | FileCheck %s
 // Radar 8461032
 // CHECK: DW_AT_location
 // CHECK-NEXT: byte 145
diff --git a/test/CodeGen/debug-info-version.c b/test/CodeGen/debug-info-version.c
new file mode 100644
index 0000000..325345f
--- /dev/null
+++ b/test/CodeGen/debug-info-version.c
@@ -0,0 +1,8 @@
+// RUN: %clang -g -S -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang -S -emit-llvm -o - %s | FileCheck %s --check-prefix=NO_DEBUG
+int main (void) {
+  return 0;
+}
+
+// CHECK: metadata !{i32 2, metadata !"Debug Info Version", i32 1}
+// NO_DEBUG-NOT: metadata !"Debug Info Version"
diff --git a/test/CodeGen/dependent-lib.c b/test/CodeGen/dependent-lib.c
index df4aaf0..20913d3 100644
--- a/test/CodeGen/dependent-lib.c
+++ b/test/CodeGen/dependent-lib.c
@@ -2,13 +2,13 @@
 // RUN: %clang_cc1 %s --dependent-lib=msvcrt -triple x86_64-pc-win32 -emit-llvm -o - | FileCheck %s
 // RUN: %clang_cc1 %s --dependent-lib=msvcrt -triple i686-pc-linux -emit-llvm -o - | FileCheck -check-prefix LINUX %s
 
-// CHECK: !llvm.module.flags = !{!0}
-// CHECK: !0 = metadata !{i32 6, metadata !"Linker Options", metadata ![[link_opts:[0-9]+]]}
+// CHECK: !llvm.module.flags = !{{{.*}}}
+// CHECK: !{{[0-9]+}} = metadata !{i32 6, metadata !"Linker Options", metadata ![[link_opts:[0-9]+]]}
 // CHECK: ![[link_opts]] = metadata !{metadata ![[msvcrt:[0-9]+]]}
 // CHECK: ![[msvcrt]] = metadata !{metadata !"/DEFAULTLIB:msvcrt.lib"}
 
-// LINUX: !llvm.module.flags = !{!0}
-// LINUX: !0 = metadata !{i32 6, metadata !"Linker Options", metadata ![[link_opts:[0-9]+]]}
+// LINUX: !llvm.module.flags = !{{{.*}}}
+// LINUX: !{{[0-9]+}} = metadata !{i32 6, metadata !"Linker Options", metadata ![[link_opts:[0-9]+]]}
 // LINUX: ![[link_opts]] = metadata !{metadata ![[msvcrt:[0-9]+]]}
 // LINUX: ![[msvcrt]] = metadata !{metadata !"-lmsvcrt"}
 
diff --git a/test/CodeGen/disable-tail-calls.c b/test/CodeGen/disable-tail-calls.c
new file mode 100644
index 0000000..b066100
--- /dev/null
+++ b/test/CodeGen/disable-tail-calls.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9.0 -emit-llvm -O1 -mdisable-tail-calls -o - < %s | FileCheck %s
+
+typedef struct List {
+  struct List *next;
+  int data;
+} List;
+
+// CHECK-LABEL: define %struct.List* @find
+List *find(List *head, int data) {
+  if (!head)
+    return 0;
+  if (head->data == data)
+    return head;
+  // CHECK: call %struct.List* @find
+  return find(head->next, data);
+}
diff --git a/test/CodeGen/dllexport.c b/test/CodeGen/dllexport.c
new file mode 100644
index 0000000..4389994
--- /dev/null
+++ b/test/CodeGen/dllexport.c
@@ -0,0 +1,115 @@
+// RUN: %clang_cc1 -triple i686-windows-msvc   -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple i686-windows-gnu    -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-windows-gnu  -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s
+
+
+
+//===----------------------------------------------------------------------===//
+// Globals
+//===----------------------------------------------------------------------===//
+
+// Declarations are not exported.
+// CHECK-NOT: @ExternGlobalDecl
+__declspec(dllexport) extern int ExternGlobalDecl;
+
+// dllexport implies a definition.
+// CHECK-DAG: @GlobalDef = common dllexport global i32 0, align 4
+__declspec(dllexport) int GlobalDef;
+
+// Export definition.
+// CHECK-DAG: @GlobalInit = dllexport global i32 1, align 4
+__declspec(dllexport) int GlobalInit = 1;
+
+// Declare, then export definition.
+// CHECK-DAG: @GlobalDeclInit = dllexport global i32 1, align 4
+__declspec(dllexport) extern int GlobalDeclInit;
+int GlobalDeclInit = 1;
+
+// Redeclarations
+// CHECK-DAG: @GlobalRedecl1 = common dllexport global i32 0, align 4
+__declspec(dllexport) extern int GlobalRedecl1;
+__declspec(dllexport)        int GlobalRedecl1;
+
+// CHECK-DAG: @GlobalRedecl2 = common dllexport global i32 0, align 4
+__declspec(dllexport) extern int GlobalRedecl2;
+                             int GlobalRedecl2;
+
+
+
+//===----------------------------------------------------------------------===//
+// Functions
+//===----------------------------------------------------------------------===//
+
+// Declarations are not exported.
+
+// Export function definition.
+// CHECK-DAG: define dllexport void @def()
+__declspec(dllexport) void def(void) {}
+
+// Export inline function.
+// CHECK-DAG: define weak_odr dllexport void @inlineFunc()
+// CHECK-DAG: define weak_odr dllexport void @externInlineFunc()
+__declspec(dllexport) inline void inlineFunc(void) {}
+__declspec(dllexport) inline void externInlineFunc(void) {}
+extern void externInlineFunc(void);
+
+// Redeclarations
+// CHECK-DAG: define dllexport void @redecl1()
+__declspec(dllexport) void redecl1(void);
+__declspec(dllexport) void redecl1(void) {}
+
+// CHECK-DAG: define dllexport void @redecl2()
+__declspec(dllexport) void redecl2(void);
+                      void redecl2(void) {}
+
+
+
+//===----------------------------------------------------------------------===//
+// Precedence
+//===----------------------------------------------------------------------===//
+
+// dllexport takes precedence over the dllimport if both are specified.
+// CHECK-DAG: @PrecedenceGlobal1A = common dllexport global i32 0, align 4
+// CHECK-DAG: @PrecedenceGlobal1B = common dllexport global i32 0, align 4
+__attribute__((dllimport, dllexport))       int PrecedenceGlobal1A;
+__declspec(dllimport) __declspec(dllexport) int PrecedenceGlobal1B;
+
+// CHECK-DAG: @PrecedenceGlobal2A = common dllexport global i32 0, align 4
+// CHECK-DAG: @PrecedenceGlobal2B = common dllexport global i32 0, align 4
+__attribute__((dllexport, dllimport))       int PrecedenceGlobal2A;
+__declspec(dllexport) __declspec(dllimport) int PrecedenceGlobal2B;
+
+// CHECK-DAG: @PrecedenceGlobalRedecl1 = dllexport global i32 0, align 4
+__declspec(dllexport) extern int PrecedenceGlobalRedecl1;
+__declspec(dllimport)        int PrecedenceGlobalRedecl1 = 0;
+
+// CHECK-DAG: @PrecedenceGlobalRedecl2 = common dllexport global i32 0, align 4
+__declspec(dllimport) extern int PrecedenceGlobalRedecl2;
+__declspec(dllexport)        int PrecedenceGlobalRedecl2;
+
+// CHECK-DAG: @PrecedenceGlobalMixed1 = dllexport global i32 1, align 4
+__attribute__((dllexport)) extern int PrecedenceGlobalMixed1;
+__declspec(dllimport)             int PrecedenceGlobalMixed1 = 1;
+
+// CHECK-DAG: @PrecedenceGlobalMixed2 = common dllexport global i32 0, align 4
+__attribute__((dllimport)) extern int PrecedenceGlobalMixed2;
+__declspec(dllexport)             int PrecedenceGlobalMixed2;
+
+// CHECK-DAG: define dllexport void @precedence1A()
+// CHECK-DAG: define dllexport void @precedence1B()
+void __attribute__((dllimport, dllexport))       precedence1A(void) {}
+void __declspec(dllimport) __declspec(dllexport) precedence1B(void) {}
+
+// CHECK-DAG: define dllexport void @precedence2A()
+// CHECK-DAG: define dllexport void @precedence2B()
+void __attribute__((dllexport, dllimport))       precedence2A(void) {}
+void __declspec(dllexport) __declspec(dllimport) precedence2B(void) {}
+
+// CHECK-DAG: define dllexport void @precedenceRedecl1()
+void __declspec(dllimport) precedenceRedecl1(void);
+void __declspec(dllexport) precedenceRedecl1(void) {}
+
+// CHECK-DAG: define dllexport void @precedenceRedecl2()
+void __declspec(dllexport) precedenceRedecl2(void);
+void __declspec(dllimport) precedenceRedecl2(void) {}
diff --git a/test/CodeGen/dllimport-dllexport.c b/test/CodeGen/dllimport-dllexport.c
deleted file mode 100644
index e70ac03..0000000
--- a/test/CodeGen/dllimport-dllexport.c
+++ /dev/null
@@ -1,12 +0,0 @@
-// RUN: %clang_cc1 -triple i386-mingw32 -emit-llvm < %s | FileCheck %s
-
-void __attribute__((dllimport)) foo1();
-void __attribute__((dllexport)) foo1(){}
-// CHECK-LABEL: define dllexport void @foo1
-void __attribute__((dllexport)) foo2();
-
-// PR6269
-__declspec(dllimport) void foo3();
-__declspec(dllexport) void foo3(){}
-// CHECK-LABEL: define dllexport void @foo3
-__declspec(dllexport) void foo4();
diff --git a/test/CodeGen/dllimport.c b/test/CodeGen/dllimport.c
new file mode 100644
index 0000000..32ee81f
--- /dev/null
+++ b/test/CodeGen/dllimport.c
@@ -0,0 +1,93 @@
+// RUN: %clang_cc1 -triple i686-windows-msvc   -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple i686-windows-gnu    -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-windows-gnu  -emit-llvm -std=c11 -O0 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple i686-windows-msvc   -emit-llvm -std=c11 -O1 -o - %s | FileCheck --check-prefix=O1 %s
+// RUN: %clang_cc1 -triple i686-windows-gnu    -emit-llvm -std=c11 -O1 -o - %s | FileCheck --check-prefix=O1 %s
+
+#define JOIN2(x, y) x##y
+#define JOIN(x, y) JOIN2(x, y)
+#define USEVAR(var) int JOIN(use, __LINE__)() { return var; }
+#define USE(func) void JOIN(use, __LINE__)() { func(); }
+
+
+
+//===----------------------------------------------------------------------===//
+// Globals
+//===----------------------------------------------------------------------===//
+
+// Import declaration.
+// CHECK: @ExternGlobalDecl = external dllimport global i32
+__declspec(dllimport) extern int ExternGlobalDecl;
+USEVAR(ExternGlobalDecl)
+
+// dllimport implies a declaration.
+// CHECK: @GlobalDecl = external dllimport global i32
+__declspec(dllimport) int GlobalDecl;
+USEVAR(GlobalDecl)
+
+// Redeclarations
+// CHECK: @GlobalRedecl1 = external dllimport global i32
+__declspec(dllimport) extern int GlobalRedecl1;
+__declspec(dllimport) extern int GlobalRedecl1;
+USEVAR(GlobalRedecl1)
+
+// CHECK: @GlobalRedecl2 = external dllimport global i32
+__declspec(dllimport) int GlobalRedecl2;
+__declspec(dllimport) int GlobalRedecl2;
+USEVAR(GlobalRedecl2)
+
+// NB: MSVC issues a warning and makes GlobalRedecl3 dllexport. We follow GCC
+// and drop the dllimport with a warning.
+// CHECK: @GlobalRedecl3 = external global i32
+__declspec(dllimport) extern int GlobalRedecl3;
+                      extern int GlobalRedecl3; // dllimport ignored
+USEVAR(GlobalRedecl3)
+
+
+
+//===----------------------------------------------------------------------===//
+// Functions
+//===----------------------------------------------------------------------===//
+
+// Import function declaration.
+// CHECK-DAG: declare dllimport void @decl()
+__declspec(dllimport) void decl(void);
+
+// Initialize use_decl with the address of the thunk.
+// CHECK-DAG: @use_decl = global void ()* @decl
+void (*use_decl)(void) = &decl;
+
+// Import inline function.
+// CHECK-DAG: declare dllimport void @inlineFunc()
+// O1-DAG: define available_externally dllimport void @inlineFunc()
+__declspec(dllimport) inline void inlineFunc(void) {}
+USE(inlineFunc)
+
+// inline attributes
+// CHECK-DAG: declare dllimport void @noinline()
+// O1-DAG: define available_externally dllimport void @noinline()
+// CHECK-NOT: @alwaysInline()
+// O1-NOT: @alwaysInline()
+__declspec(dllimport) __attribute__((noinline)) inline void noinline(void) {}
+__declspec(dllimport) __attribute__((always_inline)) inline void alwaysInline(void) {}
+USE(noinline)
+USE(alwaysInline)
+
+// Redeclarations
+// CHECK-DAG: declare dllimport void @redecl1()
+__declspec(dllimport) void redecl1(void);
+__declspec(dllimport) void redecl1(void);
+USE(redecl1)
+
+// NB: MSVC issues a warning and makes redecl2/redecl3 dllexport. We follow GCC
+// and drop the dllimport with a warning.
+// CHECK-DAG: declare void @redecl2()
+__declspec(dllimport) void redecl2(void);
+                      void redecl2(void);
+USE(redecl2)
+
+// CHECK-DAG: define void @redecl3()
+__declspec(dllimport) void redecl3(void);
+                      void redecl3(void) {} // dllimport ignored
+USE(redecl3)
diff --git a/test/CodeGen/dwarf-version.c b/test/CodeGen/dwarf-version.c
index 6c0f097..0c67b4f 100644
--- a/test/CodeGen/dwarf-version.c
+++ b/test/CodeGen/dwarf-version.c
@@ -1,14 +1,14 @@
-// RUN: %clang -target x86_64-linux-gnu -gdwarf-2 -S -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang -target x86_64-linux-gnu -gdwarf-2 -S -emit-llvm -o - %s | FileCheck %s --check-prefix=VER2
 // RUN: %clang -target x86_64-linux-gnu -gdwarf-3 -S -emit-llvm -o - %s | FileCheck %s --check-prefix=VER3
 // RUN: %clang -target x86_64-linux-gnu -gdwarf-4 -S -emit-llvm -o - %s | FileCheck %s --check-prefix=VER4
-// RUN: %clang -target x86_64-linux-gnu -g -S -emit-llvm -o - %s | FileCheck %s --check-prefix=LINUX
-// RUN: %clang -target x86_64-apple-darwin -g -S -emit-llvm -o - %s | FileCheck %s --check-prefix=DARWIN
+// RUN: %clang -target x86_64-linux-gnu -g -S -emit-llvm -o - %s | FileCheck %s --check-prefix=VER4
+// RUN: %clang -target x86_64-apple-darwin -g -S -emit-llvm -o - %s | FileCheck %s --check-prefix=VER2
+// RUN: %clang -target powerpc-unknown-openbsd -g -S -emit-llvm -o - %s | FileCheck %s --check-prefix=VER2
+// RUN: %clang -target powerpc-unknown-freebsd -g -S -emit-llvm -o - %s | FileCheck %s --check-prefix=VER2
 int main (void) {
   return 0;
 }
 
-// CHECK: metadata !{i32 2, metadata !"Dwarf Version", i32 2}
+// VER2: metadata !{i32 2, metadata !"Dwarf Version", i32 2}
 // VER3: metadata !{i32 2, metadata !"Dwarf Version", i32 3}
 // VER4: metadata !{i32 2, metadata !"Dwarf Version", i32 4}
-// LINUX: metadata !{i32 2, metadata !"Dwarf Version", i32 4}
-// DARWIN: metadata !{i32 2, metadata !"Dwarf Version", i32 2}
diff --git a/test/CodeGen/exceptions-seh.c b/test/CodeGen/exceptions-seh.c
index eadbe15..0a82e37 100644
--- a/test/CodeGen/exceptions-seh.c
+++ b/test/CodeGen/exceptions-seh.c
@@ -7,12 +7,13 @@
   int myres = 0;
   __try {
     myres = numerator / denominator;
+    __leave;
   } __except (1) {
     return 0;
   }
   *res = myres;
   return 1;
 }
-// CHECK-NOT error
+// CHECK-NOT: error:
 // CHECK: error: cannot compile this SEH __try yet
-// CHECK-NOT error
+// CHECK-NOT: error:
diff --git a/test/CodeGen/ffp-contract-option.c b/test/CodeGen/ffp-contract-option.c
index eb95f1e..61913b0 100644
--- a/test/CodeGen/ffp-contract-option.c
+++ b/test/CodeGen/ffp-contract-option.c
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -O3 -ffp-contract=fast -triple=powerpc-apple-darwin10 -S -o - %s | FileCheck %s
-// REQUIRES: ppc32-registered-target
+// REQUIRES: powerpc-registered-target
 
 float fma_test1(float a, float b, float c) {
 // CHECK: fmadds
diff --git a/test/CodeGen/flatten.c b/test/CodeGen/flatten.c
new file mode 100644
index 0000000..d766d54
--- /dev/null
+++ b/test/CodeGen/flatten.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple=x86_64-linux-gnu %s -emit-llvm -o - | FileCheck %s
+
+void f(void) {}
+
+__attribute__((noinline)) void ni(void) {}
+
+__attribute__((flatten))
+// CHECK: define void @g()
+void g(void) {
+  // CHECK-NOT: call {{.*}} @f
+  f();
+  // CHECK: call {{.*}} @ni
+  ni();
+}
+
+void h(void) {
+  // CHECK: call {{.*}} @f
+  f();
+}
diff --git a/test/CodeGen/fp-contract-pragma.cpp b/test/CodeGen/fp-contract-pragma.cpp
index afd8c43..b4e24b9 100644
--- a/test/CodeGen/fp-contract-pragma.cpp
+++ b/test/CodeGen/fp-contract-pragma.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -O3 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -O3 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
 
 // Is FP_CONTRACT is honored in a simple case?
 float fp_contract_1(float a, float b, float c) {
diff --git a/test/CodeGen/fp16-ops.c b/test/CodeGen/fp16-ops.c
index a848ed1..b269cf8 100644
--- a/test/CodeGen/fp16-ops.c
+++ b/test/CodeGen/fp16-ops.c
@@ -11,274 +11,274 @@
 
   // Check unary ops
 
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK fptoi float
   test = (h0);
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fcmp une float
   test = (!h1);
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fsub float
-  // CHECK: call i16 @llvm.convert.to.fp16
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
   h1 = -h1;
-  // CHECK: call float @llvm.convert.from.fp16
-  // CHECK: call i16 @llvm.convert.to.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
   h1 = +h1;
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fadd float
-  // CHECK: call i16 @llvm.convert.to.fp16
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
   h1++;
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fadd float
-  // CHECK: call i16 @llvm.convert.to.fp16
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
   ++h1;
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fadd float
-  // CHECK: call i16 @llvm.convert.to.fp16
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
   --h1;
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fadd float
-  // CHECK: call i16 @llvm.convert.to.fp16
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
   h1--;
 
   // Check binary ops with various operands
-  // CHECK: call float @llvm.convert.from.fp16
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fmul float
-  // CHECK: call i16 @llvm.convert.to.fp16
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
   h1 = h0 * h2;
-  // CHECK: call float @llvm.convert.from.fp16
-  // CHECK: call i16 @llvm.convert.to.fp16
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fmul float
-  // CHECK: call i16 @llvm.convert.to.fp16
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
   h1 = h0 * (__fp16) -2.0;
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fmul float
-  // CHECK: call i16 @llvm.convert.to.fp16
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
   h1 = h0 * f2;
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fmul float
-  // CHECK: call i16 @llvm.convert.to.fp16
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
   h1 = f0 * h2;
 
-  // CHECK: call float @llvm.convert.from.fp16
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fdiv float
-  // CHECK: call i16 @llvm.convert.to.fp16
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
   h1 = (h0 / h2);
-  // CHECK: call float @llvm.convert.from.fp16
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fdiv float
-  // CHECK: call i16 @llvm.convert.to.fp16
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
   h1 = (h0 / (__fp16) -2.0);
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fdiv float
-  // CHECK: call i16 @llvm.convert.to.fp16
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
   h1 = (h0 / f2);
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fdiv float
-  // CHECK: call i16 @llvm.convert.to.fp16
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
   h1 = (f0 / h2);
 
-  // CHECK: call float @llvm.convert.from.fp16
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fadd float
-  // CHECK: call i16 @llvm.convert.to.fp16
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
   h1 = (h2 + h0);
-  // CHECK: call float @llvm.convert.from.fp16
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fadd float
-  // CHECK: call i16 @llvm.convert.to.fp16
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
   h1 = ((__fp16)-2.0 + h0);
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fadd float
-  // CHECK: call i16 @llvm.convert.to.fp16
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
   h1 = (h2 + f0);
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fadd float
-  // CHECK: call i16 @llvm.convert.to.fp16
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
   h1 = (f2 + h0);
 
-  // CHECK: call float @llvm.convert.from.fp16
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fsub float
-  // CHECK: call i16 @llvm.convert.to.fp16
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
   h1 = (h2 - h0);
-  // CHECK: call float @llvm.convert.from.fp16
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fsub float
-  // CHECK: call i16 @llvm.convert.to.fp16
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
   h1 = ((__fp16)-2.0 - h0);
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fsub float
-  // CHECK: call i16 @llvm.convert.to.fp16
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
   h1 = (h2 - f0);
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fsub float
-  // CHECK: call i16 @llvm.convert.to.fp16
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
   h1 = (f2 - h0);
 
-  // CHECK: call float @llvm.convert.from.fp16
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fcmp olt
   test = (h2 < h0);
-  // CHECK: call float @llvm.convert.from.fp16
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fcmp olt
   test = (h2 < (__fp16)42.0);
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fcmp olt
   test = (h2 < f0);
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fcmp olt
   test = (f2 < h0);
 
-  // CHECK: call float @llvm.convert.from.fp16
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fcmp ogt
   test = (h0 > h2);
-  // CHECK: call float @llvm.convert.from.fp16
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fcmp ogt
   test = ((__fp16)42.0 > h2);
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fcmp ogt
   test = (h0 > f2);
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fcmp ogt
   test = (f0 > h2);
 
-  // CHECK: call float @llvm.convert.from.fp16
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fcmp ole
   test = (h2 <= h0);
-  // CHECK: call float @llvm.convert.from.fp16
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fcmp ole
   test = (h2 <= (__fp16)42.0);
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fcmp ole
   test = (h2 <= f0);
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fcmp ole
   test = (f2 <= h0);
 
-  // CHECK: call float @llvm.convert.from.fp16
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fcmp oge
   test = (h0 >= h2);
-  // CHECK: call float @llvm.convert.from.fp16
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fcmp oge
   test = (h0 >= (__fp16)-2.0);
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fcmp oge
   test = (h0 >= f2);
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fcmp oge
   test = (f0 >= h2);
 
-  // CHECK: call float @llvm.convert.from.fp16
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fcmp oeq
   test = (h1 == h2);
-  // CHECK: call float @llvm.convert.from.fp16
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fcmp oeq
   test = (h1 == (__fp16)1.0);
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fcmp oeq
   test = (h1 == f1);
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fcmp oeq
   test = (f1 == h1);
 
-  // CHECK: call float @llvm.convert.from.fp16
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fcmp une
   test = (h1 != h2);
-  // CHECK: call float @llvm.convert.from.fp16
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fcmp une
   test = (h1 != (__fp16)1.0);
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fcmp une
   test = (h1 != f1);
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fcmp une
   test = (f1 != h1);
 
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fcmp une
-  // CHECK: call float @llvm.convert.from.fp16
-  // CHECK: call float @llvm.convert.from.fp16
-  // CHECK: call i16 @llvm.convert.to.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
+  // CHECK: call float @llvm.convert.from.fp16.f32(
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
   h1 = (h1 ? h2 : h0);
   // Check assignments (inc. compound)
   h0 = h1;
-  // CHECK: call i16 @llvm.convert.to.fp16
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
   h0 = (__fp16)-2.0;
-  // CHECK: call i16 @llvm.convert.to.fp16
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
   h0 = f0;
 
-  // CHECK: call float @llvm.convert.from.fp16
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fadd float
-  // CHECK: call i16 @llvm.convert.to.fp16
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
   h0 += h1;
-  // CHECK: call float @llvm.convert.from.fp16
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fadd
-  // CHECK: call i16 @llvm.convert.to.fp16
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
   h0 += (__fp16)1.0;
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fadd
-  // CHECK: call i16 @llvm.convert.to.fp16
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
   h0 += f2;
 
-  // CHECK: call float @llvm.convert.from.fp16
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fsub
-  // CHECK: call i16 @llvm.convert.to.fp16
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
   h0 -= h1;
-  // CHECK: call float @llvm.convert.from.fp16
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fsub
-  // CHECK: call i16 @llvm.convert.to.fp16
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
   h0 -= (__fp16)1.0;
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fsub
-  // CHECK: call i16 @llvm.convert.to.fp16
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
   h0 -= f2;
 
-  // CHECK: call float @llvm.convert.from.fp16
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fmul
-  // CHECK: call i16 @llvm.convert.to.fp16
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
   h0 *= h1;
-  // CHECK: call float @llvm.convert.from.fp16
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fmul
-  // CHECK: call i16 @llvm.convert.to.fp16
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
   h0 *= (__fp16)1.0;
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fmul
-  // CHECK: call i16 @llvm.convert.to.fp16
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
   h0 *= f2;
 
-  // CHECK: call float @llvm.convert.from.fp16
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fdiv
-  // CHECK: call i16 @llvm.convert.to.fp16
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
   h0 /= h1;
-  // CHECK: call float @llvm.convert.from.fp16
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fdiv
-  // CHECK: call i16 @llvm.convert.to.fp16
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
   h0 /= (__fp16)1.0;
-  // CHECK: call float @llvm.convert.from.fp16
+  // CHECK: call float @llvm.convert.from.fp16.f32(
   // CHECK: fdiv
-  // CHECK: call i16 @llvm.convert.to.fp16
+  // CHECK: call i16 @llvm.convert.to.fp16.f32(
   h0 /= f2;
 }
diff --git a/test/CodeGen/function-attributes.c b/test/CodeGen/function-attributes.c
index 47a0568..177ad84 100644
--- a/test/CodeGen/function-attributes.c
+++ b/test/CodeGen/function-attributes.c
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -Os -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -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]]
@@ -117,6 +118,16 @@
   setjmp(0);
 }
 
+// CHECK-LABEL: define void @f20()
+// CHECK: {
+// CHECK: call i32 @_setjmp(i32* null)
+// CHECK: [[RT_CALL]]
+// CHECK: ret void
+int _setjmp(jmp_buf);
+void f20(void) {
+  _setjmp(0);
+}
+
 // CHECK: attributes [[NUW]] = { nounwind optsize readnone{{.*}} }
 // CHECK: attributes [[AI]] = { alwaysinline nounwind optsize readnone{{.*}} }
 // CHECK: attributes [[ALIGN]] = { nounwind optsize readnone alignstack=16{{.*}} }
diff --git a/test/CodeGen/function-sections.c b/test/CodeGen/function-sections.c
new file mode 100644
index 0000000..7994acf
--- /dev/null
+++ b/test/CodeGen/function-sections.c
@@ -0,0 +1,28 @@
+// REQUIRES: x86-registered-target
+
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -S -o - < %s | FileCheck %s --check-prefix=PLAIN
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -S -ffunction-sections -fno-function-sections -o - < %s | FileCheck %s --check-prefix=PLAIN
+
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -S -ffunction-sections -o - < %s | FileCheck %s --check-prefix=FUNC_SECT
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -S -fno-function-sections -ffunction-sections -o - < %s | FileCheck %s --check-prefix=FUNC_SECT
+
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -S -fdata-sections -o - < %s | FileCheck %s --check-prefix=DATA_SECT
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -S -fno-data-sections -fdata-sections -o - < %s | FileCheck %s --check-prefix=DATA_SECT
+
+const int hello = 123;
+void world() {}
+
+// PLAIN-NOT: section
+// PLAIN: world:
+// PLAIN: section .rodata,
+// PLAIN: hello:
+
+// FUNC_SECT: section .text.world,
+// FUNC_SECT: world:
+// FUNC_SECT: section .rodata,
+// FUNC_SECT: hello:
+
+// DATA_SECT-NOT: section
+// DATA_SECT: world:
+// DATA_SECT: .section .rodata.hello,
+// DATA_SECT: hello:
diff --git a/test/CodeGen/hidden-alias-to-internal-function.c b/test/CodeGen/hidden-alias-to-internal-function.c
new file mode 100644
index 0000000..e939228
--- /dev/null
+++ b/test/CodeGen/hidden-alias-to-internal-function.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -o - -x c %s | FileCheck %s
+// Reproduce the crash in PR19760.
+static void foo(void) {}
+void bar(void) __attribute__((alias("foo")))
+__attribute__((visibility("hidden")));
+
+// CHECK: @bar = hidden alias void ()* @foo
+// CHECK: define internal void @foo()
diff --git a/test/CodeGen/indirect-goto.c b/test/CodeGen/indirect-goto.c
index 7a3d717..a3b45e4 100644
--- a/test/CodeGen/indirect-goto.c
+++ b/test/CodeGen/indirect-goto.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i386-unknown-unknown -O3 -emit-llvm -o - %s | grep "ret i32 2520"
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -O3 -emit-llvm -o - %s | grep "ret i32 2520"
 
 static int foo(unsigned i) {
   void *addrs[] = { &&L1, &&L2, &&L3, &&L4, &&L5 };
diff --git a/test/CodeGen/init.c b/test/CodeGen/init.c
index 1b0beae..b396c3b 100644
--- a/test/CodeGen/init.c
+++ b/test/CodeGen/init.c
@@ -132,3 +132,11 @@
   // CHECK: @test13
   // CHECK: and i16 {{.*}}, -1024
 }
+
+// CHECK-LABEL: @PR20473
+void PR20473() {
+  // CHECK: memcpy{{.*}}([2 x i8]* @
+  bar((char[2]) {""});
+  // CHECK: memcpy{{.*}}([3 x i8]* @
+  bar((char[3]) {""});
+}
diff --git a/test/CodeGen/inline.c b/test/CodeGen/inline.c
index 70ab696..96c9a86 100644
--- a/test/CodeGen/inline.c
+++ b/test/CodeGen/inline.c
@@ -53,12 +53,13 @@
 
 // RUN: echo "MS C Mode tests:"
 // RUN: %clang_cc1 %s -triple i386-unknown-unknown -O1 -disable-llvm-optzns -emit-llvm -o - -std=c99 -fms-compatibility | FileCheck %s --check-prefix=CHECK4
+// CHECK4-LABEL: define weak_odr i32 @ei()
 // CHECK4-LABEL: define i32 @bar()
+// CHECK4-NOT: unreferenced1
+// CHECK4-LABEL: define weak_odr void @unreferenced2()
 // CHECK4-LABEL: define void @gnu_inline()
 // CHECK4-LABEL: define available_externally void @gnu_ei_inline()
 // CHECK4-LABEL: define linkonce_odr i32 @foo()
-// CHECK4-NOT: unreferenced
-// CHECK4-LABEL: define linkonce_odr i32 @ei()
 
 extern __inline int ei() { return 123; }
 
diff --git a/test/CodeGen/inline2.c b/test/CodeGen/inline2.c
index 670ae20..84cd4db 100644
--- a/test/CodeGen/inline2.c
+++ b/test/CodeGen/inline2.c
@@ -39,6 +39,9 @@
 // CHECK-GNU89-LABEL: define i32 @fA()
 inline int fA(void) { return 0; }
 
+// CHECK-GNU89-LABEL: define i32 @fB()
+inline int fB() { return 0; }
+
 // CHECK-GNU89-LABEL: define available_externally i32 @f4()
 // CHECK-C99-LABEL: define i32 @f4()
 int f4(void);
@@ -56,7 +59,11 @@
 
 // CHECK-C99-LABEL: define available_externally i32 @fA()
 
+// CHECK-C99-LABEL: define i32 @fB()
+
 int test_all() { 
   return f0() + f1() + f2() + f3() + f4() + f5() + f6() + f7() + f8() + f9() 
-    + fA();
+    + fA() + fB();
 }
+
+int fB(void);
diff --git a/test/CodeGen/libcall-declarations.c b/test/CodeGen/libcall-declarations.c
index 6442e29..345b74f 100644
--- a/test/CodeGen/libcall-declarations.c
+++ b/test/CodeGen/libcall-declarations.c
@@ -244,6 +244,16 @@
 double _Complex ctanh(double _Complex);
 float _Complex ctanhf(float _Complex);
 long double _Complex ctanhl(long double _Complex);
+
+double __sinpi(double);
+float __sinpif(float);
+double __cospi(double);
+float __cospif(float);
+double __tanpi(double);
+float __tanpif(float);
+
+double __exp10(double);
+float __exp10f(float);
 #ifdef __cplusplus
 }
 #endif
@@ -298,7 +308,8 @@
   F(crealf),     F(creall),     F(csin),       F(csinf),       F(csinl),
   F(csinh),      F(csinhf),     F(csinhl),     F(csqrt),       F(csqrtf),
   F(csqrtl),     F(ctan),       F(ctanf),      F(ctanl),       F(ctanh),
-  F(ctanhf),     F(ctanhl)
+  F(ctanhf),     F(ctanhl),     F(__sinpi),    F(__sinpif),    F(__cospi),
+  F(__cospif),   F(__tanpi),    F(__tanpif),   F(__exp10),     F(__exp10f)
 };
 
 // CHECK-NOERRNO: declare double @atan2(double, double) [[NUW:#[0-9]+]]
@@ -510,6 +521,14 @@
 // CHECK-NOERRNO: declare <2 x float> @ctanf(<2 x float>) [[NUW]]
 // CHECK-NOERRNO: declare { double, double } @ctanh(double, double) [[NUW]]
 // CHECK-NOERRNO: declare <2 x float> @ctanhf(<2 x float>) [[NUW]]
+// CHECK-NOERRNO: declare double @__sinpi(double) [[NUW]]
+// CHECK-NOERRNO: declare float @__sinpif(float) [[NUW]]
+// CHECK-NOERRNO: declare double @__cospi(double) [[NUW]]
+// CHECK-NOERRNO: declare float @__cospif(float) [[NUW]]
+// CHECK-NOERRNO: declare double @__tanpi(double) [[NUW]]
+// CHECK-NOERRNO: declare float @__tanpif(float) [[NUW]]
+// CHECK-NOERRNO: declare double @__exp10(double) [[NUW]]
+// CHECK-NOERRNO: declare float @__exp10f(float) [[NUW]]
 
 // CHECK-ERRNO: declare i32 @abs(i32) [[NUW:#[0-9]+]]
 // CHECK-ERRNO: declare i64 @labs(i64) [[NUW]]
diff --git a/test/CodeGen/libcalls.c b/test/CodeGen/libcalls.c
index 3112c87..8120b75 100644
--- a/test/CodeGen/libcalls.c
+++ b/test/CodeGen/libcalls.c
@@ -52,9 +52,9 @@
 // CHECK-YES: declare float @powf(float, float)
 // CHECK-YES: declare double @pow(double, double)
 // CHECK-YES: declare x86_fp80 @powl(x86_fp80, x86_fp80)
-// CHECK-NO: declare float @llvm.pow.f32(float, float) [[NUW_RO:#[0-9]+]]
-// CHECK-NO: declare double @llvm.pow.f64(double, double) [[NUW_RO]]
-// CHECK-NO: declare x86_fp80 @llvm.pow.f80(x86_fp80, x86_fp80) [[NUW_RO]]
+// CHECK-NO: declare float @llvm.pow.f32(float, float) [[NUW_RNI:#[0-9]+]]
+// CHECK-NO: declare double @llvm.pow.f64(double, double) [[NUW_RNI]]
+// CHECK-NO: declare x86_fp80 @llvm.pow.f80(x86_fp80, x86_fp80) [[NUW_RNI]]
 
 // CHECK-YES-LABEL: define void @test_fma
 // CHECK-NO-LABEL: define void @test_fma
@@ -81,8 +81,8 @@
 
 // Just checking to make sure these library functions are marked readnone
 void test_builtins(double d, float f, long double ld) {
-// CHEC-NO: @test_builtins
-// CHEC-YES: @test_builtins
+// CHECK-NO: @test_builtins
+// CHECK-YES: @test_builtins
   double atan_ = atan(d);
   long double atanl_ = atanl(ld);
   float atanf_ = atanf(f);
@@ -127,4 +127,4 @@
 // CHECK-YES: attributes [[NUW_RN]] = { nounwind readnone }
 
 // CHECK-NO: attributes [[NUW_RN]] = { nounwind readnone{{.*}} }
-// CHECK-NO: attributes [[NUW_RO]] = { nounwind readonly }
+// CHECK-NO: attributes [[NUW_RNI]] = { nounwind readnone }
diff --git a/test/CodeGen/lineno-dbginfo.c b/test/CodeGen/lineno-dbginfo.c
index 72fa337..1f9b7a5 100644
--- a/test/CodeGen/lineno-dbginfo.c
+++ b/test/CodeGen/lineno-dbginfo.c
@@ -1,5 +1,5 @@
 // RUN: echo "#include <stddef.h>" > %t.h
-// RUN: %clang -S -g -include %t.h %s -emit-llvm -o %t.ll
+// RUN: %clang_cc1 -S -g -include %t.h %s -emit-llvm -o %t.ll
 // RUN: grep "i32 5" %t.ll
 // outer is at line number 5.
 int outer = 42;
diff --git a/test/CodeGen/malign-double-x86-nacl.c b/test/CodeGen/malign-double-x86-nacl.c
index ff9084a..d673155 100644
--- a/test/CodeGen/malign-double-x86-nacl.c
+++ b/test/CodeGen/malign-double-x86-nacl.c
@@ -5,7 +5,7 @@
 int checksize[sizeof(long double) == 8 ? 1 : -1];
 int checkalign[__alignof(long double) == 8 ? 1 : -1];
 
-// CHECK: define void @s1(double %a)
+// CHECK-LABEL: define void @s1(double %a)
 void s1(long double a) {}
 
 struct st_ld {
@@ -18,7 +18,7 @@
 int checksize3[sizeof(double) == 8 ? 1 : -1];
 int checkalign3[__alignof(double) == 8 ? 1 : -1];
 
-// CHECK: define void @s2(double %a)
+// CHECK-LABEL: define void @s2(double %a)
 void s2(double a) {}
 
 struct st_d {
@@ -32,7 +32,7 @@
 int checksize5[sizeof(long long) == 8 ? 1 : -1];
 int checkalign5[__alignof(long long) == 8 ? 1 : -1];
 
-// CHECK: define void @s3(i64 %a)
+// CHECK-LABEL: define void @s3(i64 %a)
 void s3(long long a) {}
 
 struct st_ll {
diff --git a/test/CodeGen/mangle-windows.c b/test/CodeGen/mangle-windows.c
index 6706492..37d1018 100644
--- a/test/CodeGen/mangle-windows.c
+++ b/test/CodeGen/mangle-windows.c
@@ -1,5 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -cxx-abi microsoft \
-// RUN:     -triple=i386-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
 // RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-mingw32 | FileCheck %s
 
 void __stdcall f1(void) {}
diff --git a/test/CodeGen/mcount.c b/test/CodeGen/mcount.c
index 1cf3d6a..5c608bc 100644
--- a/test/CodeGen/mcount.c
+++ b/test/CodeGen/mcount.c
@@ -1,4 +1,8 @@
 // RUN: %clang_cc1 -pg -triple i386-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -pg -triple powerpc-unknown-gnu-linux -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-PPC %s
+// RUN: %clang_cc1 -pg -triple powerpc64-unknown-gnu-linux -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-PPC %s
+// RUN: %clang_cc1 -pg -triple powerpc64le-unknown-gnu-linux -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-PPC %s
 void foo(void) {
 // CHECK: call void @mcount()
+// CHECK-PPC: call void @_mcount()
 }
diff --git a/test/CodeGen/mips-count-builtins.c b/test/CodeGen/mips-count-builtins.c
new file mode 100644
index 0000000..7c9a257
--- /dev/null
+++ b/test/CodeGen/mips-count-builtins.c
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 %s -triple mips-unknown-linux-gnu -emit-llvm -o - | FileCheck %s
+//
+// Test that the ctlz and cttz builtins are defined for zero.
+// Based on count-builtin.c
+
+int leading, trailing, pop;
+
+void test_i16(short P) {
+  leading = __builtin_clzs(P);
+  trailing = __builtin_ctzs(P);
+
+// CHECK: @test_i16
+// CHECK: call i16 @llvm.ctlz.i16(i16 {{.*}}, i1 false)
+// CHECK: call i16 @llvm.cttz.i16(i16 {{.*}}, i1 false)
+}
+
+void test_i32(int P) {
+  leading = __builtin_clz(P);
+  trailing = __builtin_ctz(P);
+
+// CHECK: @test_i32
+// CHECK: call i32 @llvm.ctlz.i32(i32 {{.*}}, i1 false)
+// CHECK: call i32 @llvm.cttz.i32(i32 {{.*}}, i1 false)
+}
+
+void test_i64(float P) {
+  leading = __builtin_clzll(P);
+  trailing = __builtin_ctzll(P);
+// CHECK: @test_i64
+// CHECK: call i64 @llvm.ctlz.i64(i64 {{.*}}, i1 false)
+// CHECK: call i64 @llvm.cttz.i64(i64 {{.*}}, i1 false)
+}
diff --git a/test/CodeGen/mips-target-data.c b/test/CodeGen/mips-target-data.c
deleted file mode 100644
index 6475ccb..0000000
--- a/test/CodeGen/mips-target-data.c
+++ /dev/null
@@ -1,16 +0,0 @@
-// RUN: %clang -target mipsel-linux-gnu -o - -emit-llvm -S %s |\
-// RUN: FileCheck %s -check-prefix=32EL
-// RUN: %clang -target mips-linux-gnu -o - -emit-llvm -S %s |\
-// RUN: FileCheck %s -check-prefix=32EB
-// RUN: %clang -target mips64el-linux-gnu -o - -emit-llvm -S %s |\
-// RUN: FileCheck %s -check-prefix=64EL
-// RUN: %clang -target mips64-linux-gnu -o - -emit-llvm -S %s |\
-// RUN: FileCheck %s -check-prefix=64EB
-// RUN: %clang -target mipsel-linux-gnu -o - -emit-llvm -S -mfp64 %s |\
-// RUN: FileCheck %s -check-prefix=32EL
-
-// 32EL: e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32-S64
-// 32EB: E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32-S64
-// 64EL: e-p:64:64:64-i1:8:8-i8:8:32-i16:16:32-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v64:64:64-n32:64-S128
-// 64EB: E-p:64:64:64-i1:8:8-i8:8:32-i16:16:32-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v64:64:64-n32:64-S128
-
diff --git a/test/CodeGen/mips-type-sizes-int128.c b/test/CodeGen/mips-type-sizes-int128.c
new file mode 100644
index 0000000..85ad73d
--- /dev/null
+++ b/test/CodeGen/mips-type-sizes-int128.c
@@ -0,0 +1,13 @@
+// RUN: not %clang_cc1 -triple mips-none-linux-gnu -emit-llvm -w -o - %s 2> %t1
+// RUN: FileCheck --check-prefix=O32 %s < %t1
+
+// RUN: %clang_cc1 -triple mips64-none-linux-gnu -emit-llvm -w -target-abi n32 -o - %s | FileCheck --check-prefix=NEW %s
+// RUN: %clang_cc1 -triple mips64-none-linux-gnu -emit-llvm -w -o - %s | FileCheck --check-prefix=NEW %s
+
+// O32 does not support __int128 so it must be tested separately
+// N32/N64 behave the same way so their tests have been combined into NEW
+
+int check_int128() {
+  return sizeof(__int128); // O32: :[[@LINE]]:17: error: __int128 is not supported on this target
+// NEW: ret i32 16
+}
diff --git a/test/CodeGen/mips-type-sizes.c b/test/CodeGen/mips-type-sizes.c
new file mode 100644
index 0000000..963b282
--- /dev/null
+++ b/test/CodeGen/mips-type-sizes.c
@@ -0,0 +1,92 @@
+// RUN: %clang_cc1 -triple mips-none-linux-gnu -emit-llvm -w -o - %s | FileCheck --check-prefix=ALL --check-prefix=O32 %s
+// RUN: %clang_cc1 -triple mips64-none-linux-gnu -emit-llvm -w -target-abi n32 -o - %s | FileCheck --check-prefix=ALL --check-prefix=N32 %s
+// RUN: %clang_cc1 -triple mips64-none-linux-gnu -emit-llvm -w -o - %s | FileCheck --check-prefix=ALL --check-prefix=N64 %s
+
+int check_char() {
+  return sizeof(char);
+// ALL: ret i32 1
+}
+
+int check_short() {
+  return sizeof(short);
+// ALL: ret i32 2
+}
+
+int check_int() {
+  return sizeof(int);
+// ALL: ret i32 4
+}
+
+int check_long() {
+  return sizeof(long);
+// O32: ret i32 4
+// N32: ret i32 4
+// N64: ret i32 8
+}
+
+int check_longlong() {
+  return sizeof(long long);
+// ALL: ret i32 8
+}
+
+int check_fp16() {
+  return sizeof(__fp16);
+// ALL: ret i32 2
+}
+
+int check_float() {
+  return sizeof(float);
+// ALL: ret i32 4
+}
+
+int check_double() {
+  return sizeof(double);
+// ALL: ret i32 8
+}
+
+int check_longdouble() {
+  return sizeof(long double);
+// O32: ret i32 8
+// N32: ret i32 16
+// N64: ret i32 16
+}
+
+int check_floatComplex() {
+  return sizeof(float _Complex);
+// ALL: ret i32 8
+}
+
+int check_doubleComplex() {
+  return sizeof(double _Complex);
+// ALL: ret i32 16
+}
+
+int check_longdoubleComplex() {
+  return sizeof(long double _Complex);
+// O32: ret i32 16
+// N32: ret i32 32
+// N64: ret i32 32
+}
+
+int check_bool() {
+  return sizeof(_Bool);
+// ALL: ret i32 1
+}
+
+int check_wchar() {
+  return sizeof(__WCHAR_TYPE__);
+// ALL: ret i32 4
+}
+
+int check_wchar_is_unsigned() {
+  return (__WCHAR_TYPE__)-1 > (__WCHAR_TYPE__)0;
+// ALL: ret i32 0
+}
+
+int check_ptr() {
+  return sizeof(void *);
+// O32: ret i32 4
+// N32: ret i32 4
+// N64: ret i32 8
+}
+
diff --git a/test/CodeGen/mmx-builtins.c b/test/CodeGen/mmx-builtins.c
index b142684..346676c 100644
--- a/test/CodeGen/mmx-builtins.c
+++ b/test/CodeGen/mmx-builtins.c
@@ -1,4 +1,4 @@
-// REQUIRES: x86-64-registered-target
+// REQUIRES: x86-registered-target
 // RUN: %clang_cc1 %s -O3 -triple=x86_64-apple-darwin -target-feature +ssse3 -S -o - | FileCheck %s
 
 // FIXME: Disable inclusion of mm_malloc.h, our current implementation is broken
diff --git a/test/CodeGen/mmx-inline-asm-error.c b/test/CodeGen/mmx-inline-asm-error.c
index a639368..876c664 100644
--- a/test/CodeGen/mmx-inline-asm-error.c
+++ b/test/CodeGen/mmx-inline-asm-error.c
@@ -4,9 +4,9 @@
 vec256 foo(vec256 in) {
   vec256 out;
 
-  asm("something %0" : : "y"(in)); // expected-error {{invalid type 'vec256' in asm input for constraint 'y'}}
-  asm("something %0" : "=y"(out)); // expected-error {{invalid type 'vec256' in asm input for constraint 'y'}}
-  asm("something %0, %0" : "+y"(out)); // expected-error {{invalid type 'vec256' in asm input for constraint 'y'}}
+  asm("something %0" : : "y"(in)); // expected-error {{invalid type 'vec256' (vector of 8 'int' values) in asm input for constraint 'y'}}
+  asm("something %0" : "=y"(out)); // expected-error {{invalid type 'vec256' (vector of 8 'int' values) in asm input for constraint 'y'}}
+  asm("something %0, %0" : "+y"(out)); // expected-error {{invalid type 'vec256' (vector of 8 'int' values) in asm input for constraint 'y'}}
 
   return out;
 }
diff --git a/test/CodeGen/mozilla-ms-inline-asm.c b/test/CodeGen/mozilla-ms-inline-asm.c
new file mode 100644
index 0000000..0f541d7
--- /dev/null
+++ b/test/CodeGen/mozilla-ms-inline-asm.c
@@ -0,0 +1,61 @@
+// REQUIRES: x86-registered-target
+// RUN: %clang_cc1 %s -triple i386-apple-darwin10 -fasm-blocks -emit-llvm -o - | opt -strip -S | FileCheck %s
+
+// Some test cases for MS inline asm support from Mozilla code base.
+
+void invoke(void* that, unsigned methodIndex,
+            unsigned paramCount, void* params)
+{
+// CHECK: @invoke
+// CHECK: %5 = alloca i8*, align 4
+// CHECK: %6 = alloca i32, align 4
+// CHECK: %7 = alloca i32, align 4
+// CHECK: %8 = alloca i8*, align 4
+// CHECK: store i8* %0, i8** %5, align 4
+// CHECK: store i32 %1, i32* %6, align 4
+// CHECK: store i32 %2, i32* %7, align 4
+// CHECK: store i8* %3, i8** %8, align 4
+// CHECK: call void asm sideeffect inteldialect
+// CHECK: mov edx,dword ptr $1
+// CHECK: test edx,edx
+// CHECK: jz noparams
+// CHECK: mov eax,edx
+// CHECK: shl eax,$$3
+// CHECK: sub esp,eax
+// CHECK: mov ecx,esp
+// CHECK: push dword ptr $0
+// CHECK: call invoke_copy_to_stack
+// CHECK: noparams:
+// CHECK: mov ecx,dword ptr $2
+// CHECK: push ecx
+// CHECK: mov edx,[ecx]
+// CHECK: mov eax,dword ptr $3
+// CHECK: call dword ptr[edx+eax*$$4]
+// CHECK: mov esp,ebp
+// CHECK: pop ebp
+// CHECK: ret
+// CHECK: "=*m,*m,*m,*m,~{eax},~{ebp},~{ecx},~{edx},~{flags},~{esp},~{dirflag},~{fpsr},~{flags}"
+// CHECK: (i8** %8, i32* %7, i8** %5, i32* %6)
+// CHECK: ret void
+    __asm {
+        mov     edx,paramCount
+        test    edx,edx
+        jz      noparams
+        mov     eax,edx
+        shl     eax,3
+        sub     esp,eax
+        mov     ecx,esp
+        push    params
+        call    invoke_copy_to_stack
+noparams:
+        mov     ecx,that
+        push    ecx
+        mov     edx,[ecx]
+        mov     eax,methodIndex
+        call    dword ptr[edx+eax*4]
+        mov     esp,ebp
+        pop     ebp
+        ret
+    }
+}
+
diff --git a/test/CodeGen/ms-inline-asm-64.c b/test/CodeGen/ms-inline-asm-64.c
index f667708..d6f6e2e 100644
--- a/test/CodeGen/ms-inline-asm-64.c
+++ b/test/CodeGen/ms-inline-asm-64.c
@@ -1,4 +1,4 @@
-// REQUIRES: x86-64-registered-target
+// REQUIRES: x86-registered-target
 // RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -fasm-blocks -emit-llvm -o - | FileCheck %s
 
 void t1() {
@@ -37,7 +37,9 @@
   foo.b = 2;
   __asm {
      lea ebx, foo
-     mov eax, [ebx].foo.a
+     {
+       mov eax, [ebx].foo.a
+     }
      mov [ebx].foo.b, ecx
   }
   return foo.b;
diff --git a/test/CodeGen/ms-inline-asm.c b/test/CodeGen/ms-inline-asm.c
index c4486f6..2c67106 100644
--- a/test/CodeGen/ms-inline-asm.c
+++ b/test/CodeGen/ms-inline-asm.c
@@ -1,4 +1,4 @@
-// REQUIRES: x86-64-registered-target
+// REQUIRES: x86-registered-target
 // RUN: %clang_cc1 %s -triple i386-apple-darwin10 -fasm-blocks -emit-llvm -o - | FileCheck %s
 
 void t1() {
@@ -52,6 +52,11 @@
   __asm {
     int 0x2c ; } asm comments are fun! }{
   }
+  __asm {
+    {
+      int 0x2c ; } asm comments are fun! }{
+    }
+  }
   __asm {}
 // CHECK: t7
 // CHECK: call void asm sideeffect inteldialect "int $$0x2c", "~{dirflag},~{fpsr},~{flags}"()
@@ -73,11 +78,11 @@
 void t9() {
   __asm {
     push ebx
-    mov ebx, 0x07
-    pop ebx
+    { mov ebx, 0x07 }
+    __asm { pop ebx }
   }
 // CHECK: t9
-// CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, $$0x07\0A\09pop ebx", "~{ebx},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, $$0x07\0A\09pop ebx", "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"()
 }
 
 unsigned t10(void) {
@@ -129,7 +134,7 @@
   unsigned i = 1, j = 2;
   __asm {
     .if 1
-    mov eax, i
+    { mov eax, i }
     .else
     mov ebx, j
     .endif
@@ -211,7 +216,7 @@
     __asm pop ebx
   }
 // CHECK: t21
-// CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, $$0x07\0A\09pop ebx", "~{ebx},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, $$0x07\0A\09pop ebx", "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"()
 }
 
 extern void t22_helper(int x);
@@ -227,7 +232,7 @@
     __asm pop ebx
   }
 // CHECK: t22
-// CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, esp", "~{ebx},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, esp", "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"()
 // CHECK: call void @t22_helper
 // CHECK: call void asm sideeffect inteldialect "mov esp, ebx\0A\09pop ebx", "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"()
 }
@@ -268,13 +273,14 @@
   __asm __emit 0a2h
   __asm __EMIT 0a2h
   __asm popad
+// FIXME: These all need to be merged into the same asm blob.
 // CHECK: t26
-// CHECK: call void asm sideeffect inteldialect "pushad", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "pushad", "~{esp},~{dirflag},~{fpsr},~{flags}"()
 // CHECK: call void asm sideeffect inteldialect "mov eax, $$0", "~{eax},~{dirflag},~{fpsr},~{flags}"()
 // CHECK: call void asm sideeffect inteldialect ".byte 0fh", "~{dirflag},~{fpsr},~{flags}"()
 // CHECK: call void asm sideeffect inteldialect ".byte 0a2h", "~{dirflag},~{fpsr},~{flags}"()
 // CHECK: call void asm sideeffect inteldialect ".byte 0a2h", "~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "popad", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "popad", "~{eax},~{ebp},~{ebx},~{ecx},~{edi},~{edx},~{esi},~{esp},~{dirflag},~{fpsr},~{flags}"()
 }
 
 void t27() {
@@ -323,8 +329,8 @@
   __asm pushad
   __asm popad
 // CHECK: t31
-// CHECK: call void asm sideeffect inteldialect "pushad", "~{dirflag},~{fpsr},~{flags}"()
-// CHECK: call void asm sideeffect inteldialect "popad", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "pushad", "~{esp},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "popad", "~{eax},~{ebp},~{ebx},~{ecx},~{edi},~{edx},~{esi},~{esp},~{dirflag},~{fpsr},~{flags}"()
 }
 
 void t32() {
@@ -408,6 +414,7 @@
   __asm mov eax, 4 + 8 * -16
   __asm mov eax, 4 + 16 / -8
   __asm mov eax, (16 + 16) / -8
+  __asm mov eax, ~15
 // CHECK: t37
 // CHECK: call void asm sideeffect inteldialect "mov eax, $$12", "~{eax},~{dirflag},~{fpsr},~{flags}"()
 // CHECK: call void asm sideeffect inteldialect "mov eax, $$132", "~{eax},~{dirflag},~{fpsr},~{flags}"()
@@ -416,6 +423,7 @@
 // CHECK: call void asm sideeffect inteldialect "mov eax, $$4294967172", "~{eax},~{dirflag},~{fpsr},~{flags}"()
 // CHECK: call void asm sideeffect inteldialect "mov eax, $$2", "~{eax},~{dirflag},~{fpsr},~{flags}"()
 // CHECK: call void asm sideeffect inteldialect "mov eax, $$4294967292", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "mov eax, $$4294967280", "~{eax},~{dirflag},~{fpsr},~{flags}"()
 }
 
 void t38() {
@@ -438,3 +446,51 @@
 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$8$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
 // CHECK: call void asm sideeffect inteldialect "mov eax, dword ptr $$0$0", "*m,~{eax},~{dirflag},~{fpsr},~{flags}"([4 x i32]* %{{.*}})
 }
+
+void cpuid() {
+  __asm cpuid
+// CHECK-LABEL: define void @cpuid
+// CHECK: call void asm sideeffect inteldialect "cpuid", "~{eax},~{ebx},~{ecx},~{edx},~{dirflag},~{fpsr},~{flags}"()
+}
+
+typedef struct {
+  int a;
+  int b;
+} A;
+
+void t39() {
+  __asm mov eax, [eax].A.b
+  __asm mov eax, [eax] A.b
+  __asm mov eax, fs:[0] A.b
+  // CHECK-LABEL: define void @t39
+  // CHECK: call void asm sideeffect inteldialect "mov eax, [eax].4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+  // CHECK: call void asm sideeffect inteldialect "mov eax, [eax] .4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+  // CHECK: call void asm sideeffect inteldialect "mov eax, fs:[$$0] .4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+}
+
+void t40(float a) {
+  int i;
+  __asm fld a
+  __asm fistp i
+  // CHECK-LABEL: define void @t40
+  // CHECK: call void asm sideeffect inteldialect "fld dword ptr $0", "*m,~{dirflag},~{fpsr},~{flags}"(float* {{.*}})
+  // CHECK: call void asm sideeffect inteldialect "fistp dword ptr $0", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* {{.*}})
+}
+
+void t41(unsigned short a) {
+  __asm mov cs, a;
+  __asm mov ds, a;
+  __asm mov es, a;
+  __asm mov fs, a;
+  __asm mov gs, a;
+  __asm mov ss, a;
+  // CHECK-LABEL: define void @t41(i16 zeroext %a)
+  // CHECK: [[T41_A_ADDR:%.+]] = alloca i16
+  // CHECK: store i16 %a, i16* [[T41_A_ADDR]]
+  // CHECK: call void asm sideeffect inteldialect "mov cs, word ptr $0", "*m,~{dirflag},~{fpsr},~{flags}"(i16* [[T41_A_ADDR]])
+  // CHECK: call void asm sideeffect inteldialect "mov ds, word ptr $0", "*m,~{dirflag},~{fpsr},~{flags}"(i16* [[T41_A_ADDR]])
+  // CHECK: call void asm sideeffect inteldialect "mov es, word ptr $0", "*m,~{dirflag},~{fpsr},~{flags}"(i16* [[T41_A_ADDR]])
+  // CHECK: call void asm sideeffect inteldialect "mov fs, word ptr $0", "*m,~{dirflag},~{fpsr},~{flags}"(i16* [[T41_A_ADDR]])
+  // CHECK: call void asm sideeffect inteldialect "mov gs, word ptr $0", "*m,~{dirflag},~{fpsr},~{flags}"(i16* [[T41_A_ADDR]])
+  // CHECK: call void asm sideeffect inteldialect "mov ss, word ptr $0", "*m,~{dirflag},~{fpsr},~{flags}"(i16* [[T41_A_ADDR]])
+}
diff --git a/test/CodeGen/ms-inline-asm.cpp b/test/CodeGen/ms-inline-asm.cpp
index 64b8558..83fe107 100644
--- a/test/CodeGen/ms-inline-asm.cpp
+++ b/test/CodeGen/ms-inline-asm.cpp
@@ -1,5 +1,5 @@
-// REQUIRES: x86-64-registered-target
-// RUN: %clang_cc1 -x c++ %s -triple i386-apple-darwin10 -fasm-blocks -emit-llvm -o - | FileCheck %s
+// REQUIRES: x86-registered-target
+// RUN: %clang_cc1 -x c++ %s -triple i386-apple-darwin10 -fasm-blocks -emit-llvm -o - -std=c++11 | FileCheck %s
 
 // rdar://13645930
 
@@ -97,7 +97,7 @@
   // CHECK: [[Y:%.*]] = alloca i32
   int x, y;
   __asm push y
-  // CHECK: call void asm sideeffect inteldialect "push dword ptr $0", "=*m,~{dirflag},~{fpsr},~{flags}"(i32* [[Y]])
+  // CHECK: call void asm sideeffect inteldialect "push dword ptr $0", "=*m,~{esp},~{dirflag},~{fpsr},~{flags}"(i32* [[Y]])
   __asm call T5<int>::create<float>
   // CHECK: call void asm sideeffect inteldialect "call $0", "r,~{dirflag},~{fpsr},~{flags}"(i32 (float)* @_ZN2T5IiE6createIfEEiT_)
   __asm mov x, eax
@@ -111,3 +111,33 @@
    jmp a
   }
 }
+
+void t7_struct() {
+  struct A {
+    int a;
+    int b;
+  };
+  __asm mov eax, [eax].A.b
+  // CHECK-LABEL: define void @_Z9t7_structv
+  // CHECK: call void asm sideeffect inteldialect "mov eax, [eax].4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+}
+
+void t7_typedef() {
+  typedef struct {
+    int a;
+    int b;
+  } A;
+  __asm mov eax, [eax].A.b
+  // CHECK-LABEL: define void @_Z10t7_typedefv
+  // CHECK: call void asm sideeffect inteldialect "mov eax, [eax].4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+}
+
+void t7_using() {
+  using A = struct {
+    int a;
+    int b;
+  };
+  __asm mov eax, [eax].A.b
+  // CHECK-LABEL: define void @_Z8t7_usingv
+  // CHECK: call void asm sideeffect inteldialect "mov eax, [eax].4", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+}
diff --git a/test/CodeGen/ms-intrinsics.c b/test/CodeGen/ms-intrinsics.c
new file mode 100644
index 0000000..fb0f62c
--- /dev/null
+++ b/test/CodeGen/ms-intrinsics.c
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -triple i686--windows -fms-compatibility -Oz -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple thumbv7--windows -fms-compatibility -Oz -emit-llvm %s -o - | FileCheck %s
+
+void *test_InterlockedExchangePointer(void * volatile *Target, void *Value) {
+  return _InterlockedExchangePointer(Target, Value);
+}
+
+// CHECK: define{{.*}}i8* @test_InterlockedExchangePointer(i8** %Target, i8* %Value){{.*}}{
+// CHECK:   %[[TARGET:[0-9]+]] = bitcast i8** %Target to i32*
+// CHECK:   %[[VALUE:[0-9]+]] = ptrtoint i8* %Value to i32
+// CHECK:   %[[EXCHANGE:[0-9]+]] = atomicrmw xchg i32* %[[TARGET]], i32 %[[VALUE]] seq_cst
+// CHECK:   %[[RESULT:[0-9]+]] = inttoptr i32 %[[EXCHANGE]] to i8*
+// CHECK:   ret i8* %[[RESULT]]
+// CHECK: }
+
+void *test_InterlockedCompareExchangePointer(void * volatile *Destination,
+                                             void *Exchange, void *Comparand) {
+  return _InterlockedCompareExchangePointer(Destination, Exchange, Comparand);
+}
+
+// CHECK: define{{.*}}i8* @test_InterlockedCompareExchangePointer(i8** %Destination, i8* %Exchange, i8* %Comparand){{.*}}{
+// CHECK:   %[[DEST:[0-9]+]] = bitcast i8** %Destination to i32*
+// CHECK:   %[[EXCHANGE:[0-9]+]] = ptrtoint i8* %Exchange to i32
+// CHECK:   %[[COMPARAND:[0-9]+]] = ptrtoint i8* %Comparand to i32
+// CHECK:   %[[XCHG:[0-9]+]] = cmpxchg volatile i32* %[[DEST:[0-9]+]], i32 %[[COMPARAND:[0-9]+]], i32 %[[EXCHANGE:[0-9]+]] seq_cst seq_cst
+// CHECK:   %[[EXTRACT:[0-9]+]] = extractvalue { i32, i1 } %[[XCHG]], 0
+// CHECK:   %[[RESULT:[0-9]+]] = inttoptr i32 %[[EXTRACT]] to i8*
+// CHECK:   ret i8* %[[RESULT:[0-9]+]]
+// CHECK: }
+
+long test_InterlockedExchange(long *Target, long Value) {
+  return _InterlockedExchange(Target, Value);
+}
+
+// CHECK: define{{.*}}i32 @test_InterlockedExchange(i32* %Target, i32 %Value){{.*}}{
+// CHECK:   %[[EXCHANGE:[0-9]+]] = atomicrmw xchg i32* %Target, i32 %Value seq_cst
+// CHECK:   ret i32 %[[EXCHANGE:[0-9]+]]
+// CHECK: }
diff --git a/test/CodeGen/ms_struct-bitfield.c b/test/CodeGen/ms_struct-bitfield.c
index a8f4c91..08f2a5b 100644
--- a/test/CodeGen/ms_struct-bitfield.c
+++ b/test/CodeGen/ms_struct-bitfield.c
@@ -1,6 +1,11 @@
-// RUN: %clang_cc1 -emit-llvm-only  -triple x86_64-apple-darwin9 %s
+// RUN: %clang_cc1 -emit-llvm -o - -triple x86_64-apple-darwin9 %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -o - -triple thumbv7-apple-ios -target-abi apcs-gnu %s | FileCheck %s -check-prefix=CHECK-ARM
+
 // rdar://8823265
 
+// Note that we're declaring global variables with these types,
+// triggering both Sema and IRGen struct layout.
+
 #define ATTR __attribute__((__ms_struct__))
 
 struct
@@ -9,6 +14,9 @@
    long : 0;
    char bar;
 } ATTR t1;
+int s1 = sizeof(t1);
+// CHECK: @s1 = global i32 2
+// CHECK-ARM: @s1 = global i32 2
 
 struct
 {
@@ -18,6 +26,9 @@
    int : 0;
    char bar;
 } ATTR t2;
+int s2 = sizeof(t2);
+// CHECK: @s2 = global i32 2
+// CHECK-ARM: @s2 = global i32 2
 
 struct
 {
@@ -29,12 +40,18 @@
    long : 0;
    char : 0;
 } ATTR t3;
+int s3 = sizeof(t3);
+// CHECK: @s3 = global i32 2
+// CHECK-ARM: @s3 = global i32 2
 
 struct
 {
    long : 0;
    char bar;
 } ATTR t4;
+int s4 = sizeof(t4);
+// CHECK: @s4 = global i32 1
+// CHECK-ARM: @s4 = global i32 1
 
 struct
 {
@@ -43,6 +60,9 @@
    char : 0;
    char bar;
 } ATTR t5;
+int s5 = sizeof(t5);
+// CHECK: @s5 = global i32 1
+// CHECK-ARM: @s5 = global i32 1
 
 struct
 {
@@ -51,6 +71,9 @@
    char : 0;
    char bar;
 } ATTR t6;
+int s6 = sizeof(t6);
+// CHECK: @s6 = global i32 1
+// CHECK-ARM: @s6 = global i32 1
 
 struct
 {
@@ -69,6 +92,9 @@
    char bar6;
    char bar7;
 } ATTR t7;
+int s7 = sizeof(t7);
+// CHECK: @s7 = global i32 9
+// CHECK-ARM: @s7 = global i32 9
 
 struct
 {
@@ -76,6 +102,9 @@
    long : 0;
    char : 0;
 } ATTR t8;
+int s8 = sizeof(t8);
+// CHECK: @s8 = global i32 0
+// CHECK-ARM: @s8 = global i32 0
 
 struct
 {
@@ -106,6 +135,9 @@
    long : 0;
    char :4;
 } ATTR t9;
+int s9 = sizeof(t9);
+// CHECK: @s9 = global i32 28
+// CHECK-ARM: @s9 = global i32 28
 
 struct
 {
@@ -113,19 +145,35 @@
    long : 0;
    char bar;
 } ATTR t10;
+int s10 = sizeof(t10);
+// CHECK: @s10 = global i32 16
+// CHECK-ARM: @s10 = global i32 8
 
-static int arr1[(sizeof(t1) == 2) -1];
-static int arr2[(sizeof(t2) == 2) -1];
-static int arr3[(sizeof(t3) == 2) -1];
-static int arr4[(sizeof(t4) == 1) -1];
-static int arr5[(sizeof(t5) == 1) -1];
-static int arr6[(sizeof(t6) == 1) -1];
-static int arr7[(sizeof(t7) == 9) -1];
-static int arr8[(sizeof(t8) == 0) -1];
-static int arr9[(sizeof(t9) == 28) -1];
-static int arr10[(sizeof(t10) == 16) -1];
+// rdar://16041826 - ensure that ms_structs work correctly on a
+// !useBitFieldTypeAlignment() target
+struct {
+  unsigned int a : 31;
+  unsigned int b : 2;
+  unsigned int c;
+} ATTR t11;
+int s11 = sizeof(t11);
+// CHECK: @s11 = global i32 12
+// CHECK-ARM: @s11 = global i32 12
 
-int main() {
-  return 0;
-}
+struct {
+  unsigned char a : 3;
+  unsigned char b : 4;
+  unsigned short c : 6;
+} ATTR t12;
+int s12 = sizeof(t12);
+// CHECK: @s12 = global i32 4
+// CHECK-ARM: @s12 = global i32 4
 
+struct {
+  unsigned char a : 3;
+  unsigned char b : 4;
+  __attribute__((packed)) unsigned short c : 6;
+} ATTR t13;
+int s13 = sizeof(t13);
+// CHECK: @s13 = global i32 4
+// CHECK-ARM: @s13 = global i32 4
diff --git a/test/CodeGen/ms_struct-pack.c b/test/CodeGen/ms_struct-pack.c
index da94f54..6486f29 100644
--- a/test/CodeGen/ms_struct-pack.c
+++ b/test/CodeGen/ms_struct-pack.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm-only  -triple i386-apple-darwin9 %s
+// RUN: %clang_cc1 -emit-llvm-only  -triple i386-apple-darwin9 -fdump-record-layouts %s | FileCheck %s
 // rdar://8823265
 
 #pragma pack(1)
@@ -123,3 +123,22 @@
 
 static int a8[(sizeof(eight_ms) == 48) - 1];
 
+// rdar://15926990
+#pragma pack(2)
+struct test0 {
+  unsigned long a : 8;
+  unsigned long b : 8;
+  unsigned long c : 8;
+  unsigned long d : 10;
+  unsigned long e : 1;
+} __attribute__((__ms_struct__));
+
+// CHECK:      Type: struct test0
+// CHECK-NEXT: Record:
+// CHECK-NEXT: Layout:
+// CHECK-NEXT:   Size:64
+// CHECK-NEXT:   DataSize:64
+// CHECK-NEXT:   Alignment:16
+// CHECK-NEXT:   FieldOffsets: [0, 8, 16, 32, 42]>
+
+static int test0[(sizeof(struct test0) == 8) ? 1 : -1];
diff --git a/test/CodeGen/named_reg_global.c b/test/CodeGen/named_reg_global.c
new file mode 100644
index 0000000..8117dae
--- /dev/null
+++ b/test/CodeGen/named_reg_global.c
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -S -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-linux-gnu -S -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple armv7-linux-gnu -S -emit-llvm %s -o - | FileCheck %s
+
+// CHECK-NOT: @sp = common global
+register unsigned long current_stack_pointer asm("sp");
+struct p4_Thread {
+  struct {
+    int len;
+  } word;
+};
+// Testing pointer types as well
+register struct p4_Thread *p4TH asm("sp");
+
+// CHECK: define{{.*}} i[[bits:[0-9]+]] @get_stack_pointer_addr()
+// CHECK: [[ret:%[0-9]+]] = call i[[bits]] @llvm.read_register.i[[bits]](metadata !0)
+// CHECK: ret i[[bits]] [[ret]]
+unsigned long get_stack_pointer_addr() {
+  return current_stack_pointer;
+}
+// CHECK: declare{{.*}} i[[bits]] @llvm.read_register.i[[bits]](metadata)
+
+// CHECK: define{{.*}} void @set_stack_pointer_addr(i[[bits]] %addr) #0 {
+// CHECK: [[sto:%[0-9]+]] = load i[[bits]]* %
+// CHECK: call void @llvm.write_register.i[[bits]](metadata !0, i[[bits]] [[sto]])
+// CHECK: ret void
+void set_stack_pointer_addr(unsigned long addr) {
+  current_stack_pointer = addr;
+}
+// CHECK: declare{{.*}} void @llvm.write_register.i[[bits]](metadata, i[[bits]])
+
+// CHECK: define {{.*}}@fn1
+int fn1() {
+  return (*p4TH).word.len;
+}
+// CHECK: %[[regr:[0-9]+]] = call i[[bits]] @llvm.read_register.i[[bits]](metadata !0)
+// CHECK: inttoptr i[[bits]] %[[regr]] to %struct.p4_Thread*
+
+// CHECK: define {{.*}}@fn2
+void fn2(struct p4_Thread *val) {
+  p4TH = val;
+}
+// CHECK: %[[regw:[0-9]+]] = ptrtoint %struct.p4_Thread* %{{.*}} to i[[bits]]
+// CHECK: call void @llvm.write_register.i[[bits]](metadata !0, i[[bits]] %[[regw]])
+
+// CHECK: !llvm.named.register.sp = !{!0}
+// CHECK: !0 = metadata !{metadata !"sp"}
diff --git a/test/CodeGen/neon-crypto.c b/test/CodeGen/neon-crypto.c
new file mode 100644
index 0000000..ee80710
--- /dev/null
+++ b/test/CodeGen/neon-crypto.c
@@ -0,0 +1,96 @@
+// RUN: %clang_cc1 -triple arm-none-linux-gnueabi -target-feature +neon \
+// RUN:  -target-feature +crypto -target-cpu cortex-a57 -emit-llvm -O1 -o - %s | FileCheck %s
+
+// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \
+// RUN:   -target-feature +crypto -emit-llvm -O1 -o - %s | FileCheck %s
+// RUN: not %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \
+// RUN:   -S -O3 -o - %s 2>&1 | FileCheck --check-prefix=CHECK-NO-CRYPTO %s
+
+// Test new aarch64 intrinsics and types
+
+#include <arm_neon.h>
+
+uint8x16_t test_vaeseq_u8(uint8x16_t data, uint8x16_t key) {
+  // CHECK-LABEL: @test_vaeseq_u8
+  // CHECK-NO-CRYPTO: warning: implicit declaration of function 'vaeseq_u8' is invalid in C99
+  return vaeseq_u8(data, key);
+  // CHECK: call <16 x i8> @llvm.{{arm.neon|aarch64.crypto}}.aese(<16 x i8> %data, <16 x i8> %key)
+}
+
+uint8x16_t test_vaesdq_u8(uint8x16_t data, uint8x16_t key) {
+  // CHECK-LABEL: @test_vaesdq_u8
+  return vaesdq_u8(data, key);
+  // CHECK: call <16 x i8> @llvm.{{arm.neon|aarch64.crypto}}.aesd(<16 x i8> %data, <16 x i8> %key)
+}
+
+uint8x16_t test_vaesmcq_u8(uint8x16_t data) {
+  // CHECK-LABEL: @test_vaesmcq_u8
+  return vaesmcq_u8(data);
+  // CHECK: call <16 x i8> @llvm.{{arm.neon|aarch64.crypto}}.aesmc(<16 x i8> %data)
+}
+
+uint8x16_t test_vaesimcq_u8(uint8x16_t data) {
+  // CHECK-LABEL: @test_vaesimcq_u8
+  return vaesimcq_u8(data);
+  // CHECK: call <16 x i8> @llvm.{{arm.neon|aarch64.crypto}}.aesimc(<16 x i8> %data)
+}
+
+uint32_t test_vsha1h_u32(uint32_t hash_e) {
+  // CHECK-LABEL: @test_vsha1h_u32
+  return vsha1h_u32(hash_e);
+  // CHECK: call i32 @llvm.{{arm.neon|aarch64.crypto}}.sha1h(i32 %hash_e)
+}
+
+uint32x4_t test_vsha1su1q_u32(uint32x4_t w0_3, uint32x4_t w12_15) {
+  // CHECK-LABEL: @test_vsha1su1q_u32
+  return vsha1su1q_u32(w0_3, w12_15);
+  // CHECK: call <4 x i32> @llvm.{{arm.neon|aarch64.crypto}}.sha1su1(<4 x i32> %w0_3, <4 x i32> %w12_15)
+}
+
+uint32x4_t test_vsha256su0q_u32(uint32x4_t w0_3, uint32x4_t w4_7) {
+  // CHECK-LABEL: @test_vsha256su0q_u32
+  return vsha256su0q_u32(w0_3, w4_7);
+  // CHECK: call <4 x i32> @llvm.{{arm.neon|aarch64.crypto}}.sha256su0(<4 x i32> %w0_3, <4 x i32> %w4_7)
+}
+
+uint32x4_t test_vsha1cq_u32(uint32x4_t hash_abcd, uint32_t hash_e, uint32x4_t wk) {
+  // CHECK-LABEL: @test_vsha1cq_u32
+  return vsha1cq_u32(hash_abcd, hash_e, wk);
+  // CHECK: call <4 x i32> @llvm.{{arm.neon|aarch64.crypto}}.sha1c(<4 x i32> %hash_abcd, i32 %hash_e, <4 x i32> %wk)
+}
+
+uint32x4_t test_vsha1pq_u32(uint32x4_t hash_abcd, uint32_t hash_e, uint32x4_t wk) {
+  // CHECK-LABEL: @test_vsha1pq_u32
+  return vsha1pq_u32(hash_abcd, hash_e, wk);
+  // CHECK: call <4 x i32> @llvm.{{arm.neon|aarch64.crypto}}.sha1p(<4 x i32> %hash_abcd, i32 %hash_e, <4 x i32> %wk)
+}
+
+uint32x4_t test_vsha1mq_u32(uint32x4_t hash_abcd, uint32_t hash_e, uint32x4_t wk) {
+  // CHECK-LABEL: @test_vsha1mq_u32
+  return vsha1mq_u32(hash_abcd, hash_e, wk);
+  // CHECK: call <4 x i32> @llvm.{{arm.neon|aarch64.crypto}}.sha1m(<4 x i32> %hash_abcd, i32 %hash_e, <4 x i32> %wk)
+}
+
+uint32x4_t test_vsha1su0q_u32(uint32x4_t w0_3, uint32x4_t w4_7, uint32x4_t w8_11) {
+  // CHECK-LABEL: @test_vsha1su0q_u32
+  return vsha1su0q_u32(w0_3, w4_7, w8_11);
+  // CHECK: call <4 x i32> @llvm.{{arm.neon|aarch64.crypto}}.sha1su0(<4 x i32> %w0_3, <4 x i32> %w4_7, <4 x i32> %w8_11)
+}
+
+uint32x4_t test_vsha256hq_u32(uint32x4_t hash_abcd, uint32x4_t hash_efgh, uint32x4_t wk) {
+  // CHECK-LABEL: @test_vsha256hq_u32
+  return vsha256hq_u32(hash_abcd, hash_efgh, wk);
+  // CHECK: call <4 x i32> @llvm.{{arm.neon|aarch64.crypto}}.sha256h(<4 x i32> %hash_abcd, <4 x i32> %hash_efgh, <4 x i32> %wk)
+}
+
+uint32x4_t test_vsha256h2q_u32(uint32x4_t hash_efgh, uint32x4_t hash_abcd, uint32x4_t wk) {
+  // CHECK-LABEL: @test_vsha256h2q_u32
+  return vsha256h2q_u32(hash_efgh, hash_abcd, wk);
+  // CHECK: call <4 x i32> @llvm.{{arm.neon|aarch64.crypto}}.sha256h2(<4 x i32> %hash_efgh, <4 x i32> %hash_abcd, <4 x i32> %wk)
+}
+
+uint32x4_t test_vsha256su1q_u32(uint32x4_t w0_3, uint32x4_t w8_11, uint32x4_t w12_15) {
+  // CHECK-LABEL: @test_vsha256su1q_u32
+  return vsha256su1q_u32(w0_3, w8_11, w12_15);
+  // CHECK: call <4 x i32> @llvm.{{arm.neon|aarch64.crypto}}.sha256su1(<4 x i32> %w0_3, <4 x i32> %w8_11, <4 x i32> %w12_15)
+}
diff --git a/test/CodeGen/noduplicate-cxx11-test.cpp b/test/CodeGen/noduplicate-cxx11-test.cpp
new file mode 100644
index 0000000..0127863
--- /dev/null
+++ b/test/CodeGen/noduplicate-cxx11-test.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple=i686-pc-unknown -std=c++11 %s  -emit-llvm -o - | FileCheck %s
+
+// This was a problem in Sema, but only shows up as noinline missing
+// in CodeGen.
+
+// CHECK: define i32 @_Z15noduplicatedfuni(i32 %a) [[NI:#[0-9]+]]
+
+int noduplicatedfun [[clang::noduplicate]] (int a) {
+
+  return a+1;
+
+}
+
+int main() {
+
+  return noduplicatedfun(5);
+
+}
+
+// CHECK: attributes [[NI]] = { noduplicate nounwind{{.*}} }
diff --git a/test/CodeGen/noinline.c b/test/CodeGen/noinline.c
index e64a1a5..bd5a9d8 100644
--- a/test/CodeGen/noinline.c
+++ b/test/CodeGen/noinline.c
@@ -5,10 +5,17 @@
 
 inline int dont_inline_me(int a, int b) { return(a+b); }
 
+inline __attribute__ ((__always_inline__)) int inline_me(int a, int b) { return(a*b); }
+
 volatile int *pa = (int*) 0x1000;
 void foo() {
 // NOINLINE: @foo
 // NOINLINE: dont_inline_me
 // NOINLINE-NOT: inlinehint
     pa[0] = dont_inline_me(pa[1],pa[2]);	
+// NOINLINE-NOT: inline_me
+    pa[3] = inline_me(pa[4],pa[5]);
 }
+
+// NOINLINE: Function Attrs: noinline
+// NOINLINE: @dont_inline_me
diff --git a/test/CodeGen/nonnull.c b/test/CodeGen/nonnull.c
new file mode 100644
index 0000000..4d6cc45
--- /dev/null
+++ b/test/CodeGen/nonnull.c
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm < %s | FileCheck %s
+
+// CHECK: define void @foo(i32* nonnull %x)
+void foo(int * __attribute__((nonnull)) x) {
+  *x = 0;
+}
+
+// CHECK: define void @bar(i32* nonnull %x)
+void bar(int * x) __attribute__((nonnull(1)))  {
+  *x = 0;
+}
+
+// CHECK: define void @bar2(i32* %x, i32* nonnull %y)
+void bar2(int * x, int * y) __attribute__((nonnull(2)))  {
+  *x = 0;
+}
+
+static int a;
+// CHECK: define nonnull i32* @bar3()
+int * bar3() __attribute__((returns_nonnull))  {
+  return &a;
+}
+
diff --git a/test/CodeGen/nvptx-abi.c b/test/CodeGen/nvptx-abi.c
new file mode 100644
index 0000000..f846def
--- /dev/null
+++ b/test/CodeGen/nvptx-abi.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple nvptx-unknown-unknown -S -o - %s -emit-llvm | FileCheck %s
+// RUN: %clang_cc1 -triple nvptx64-unknown-unknown -S -o - %s -emit-llvm | FileCheck %s
+
+typedef struct float4_s {
+  float x, y, z, w;
+} float4_t;
+
+float4_t my_function(void);
+
+// CHECK-DAG: declare %struct.float4_s @my_function
+
+float bar(void) {
+  float4_t ret;
+// CHECK-DAG: call %struct.float4_s @my_function
+  ret = my_function();
+  return ret.x;
+}
diff --git a/test/CodeGen/overloadable.c b/test/CodeGen/overloadable.c
index 1ed72b1..8b40e4d 100644
--- a/test/CodeGen/overloadable.c
+++ b/test/CodeGen/overloadable.c
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - | grep _Z1fPA10_1X
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
+// CHECK: _Z1fPA10_1X
+
 int __attribute__((overloadable)) f(int x) { return x; }
 float __attribute__((overloadable)) f(float x) { return x; }
 double __attribute__((overloadable)) f(double x) { return x; }
diff --git a/test/CodeGen/packed-nest-unpacked.c b/test/CodeGen/packed-nest-unpacked.c
index 3931741..ea45660 100644
--- a/test/CodeGen/packed-nest-unpacked.c
+++ b/test/CodeGen/packed-nest-unpacked.c
@@ -60,6 +60,6 @@
 
 unsigned test7() {
   // CHECK: @test7
-  // CHECK: load i32* bitcast (%struct.XBitfield* getelementptr inbounds (%struct.YBitfield* @gbitfield, i32 0, i32 1) to i32*), align 4
+  // CHECK: load i32* getelementptr inbounds (%struct.YBitfield* @gbitfield, i32 0, i32 1, i32 0), align 4
   return gbitfield.y.b2;
 }
diff --git a/test/CodeGen/packed-union.c b/test/CodeGen/packed-union.c
index 31ce614..cb49999 100644
--- a/test/CodeGen/packed-union.c
+++ b/test/CodeGen/packed-union.c
@@ -1,11 +1,11 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm %s -o %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s
 
 typedef struct _attrs {
         unsigned file_attributes;
         unsigned char filename_length;
 } __attribute__((__packed__)) attrs;
 
-// RUN: grep "union._attr_union = type <{ i32, i8 }>" %t
+// CHECK: %union._attr_union = type <{ i32, i8 }>
 typedef union _attr_union {
   attrs file_attrs;
   unsigned owner_id;
diff --git a/test/CodeGen/powerpc_types.c b/test/CodeGen/powerpc_types.c
index b4de318..b7d0f5d 100644
--- a/test/CodeGen/powerpc_types.c
+++ b/test/CodeGen/powerpc_types.c
@@ -1,4 +1,3 @@
-// REQUIRES: ppc32-registered-target
 // RUN: %clang_cc1 -triple powerpc-unknown-freebsd -emit-llvm -o - %s| FileCheck -check-prefix=SVR4-CHECK %s
 
 #include <stdarg.h>
diff --git a/test/CodeGen/ppc64-align-long-double.c b/test/CodeGen/ppc64-align-long-double.c
index c4dcfa0..6d07f70 100644
--- a/test/CodeGen/ppc64-align-long-double.c
+++ b/test/CodeGen/ppc64-align-long-double.c
@@ -1,8 +1,6 @@
-// REQUIRES: ppc64-registered-target
+// REQUIRES: powerpc-registered-target
 // RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
 
-// CHECK: -f128:128:128-
-
 struct S {
   double a;
   long double b;
diff --git a/test/CodeGen/ppc64-align-struct.c b/test/CodeGen/ppc64-align-struct.c
new file mode 100644
index 0000000..a50c849
--- /dev/null
+++ b/test/CodeGen/ppc64-align-struct.c
@@ -0,0 +1,154 @@
+// RUN: %clang_cc1 -faltivec -triple powerpc64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
+
+#include <stdarg.h>
+
+struct test1 { int x; int y; };
+struct test2 { int x; int y; } __attribute__((aligned (16)));
+struct test3 { int x; int y; } __attribute__((aligned (32)));
+struct test4 { int x; int y; int z; };
+struct test5 { int x[17]; };
+struct test6 { int x[17]; } __attribute__((aligned (16)));
+struct test7 { int x[17]; } __attribute__((aligned (32)));
+
+// CHECK: define void @test1(i32 signext %x, i64 %y.coerce)
+void test1 (int x, struct test1 y)
+{
+}
+
+// CHECK: define void @test2(i32 signext %x, [1 x i128] %y.coerce)
+void test2 (int x, struct test2 y)
+{
+}
+
+// CHECK: define void @test3(i32 signext %x, [2 x i128] %y.coerce)
+void test3 (int x, struct test3 y)
+{
+}
+
+// CHECK: define void @test4(i32 signext %x, [2 x i64] %y.coerce)
+void test4 (int x, struct test4 y)
+{
+}
+
+// CHECK: define void @test5(i32 signext %x, %struct.test5* byval align 8 %y)
+void test5 (int x, struct test5 y)
+{
+}
+
+// CHECK: define void @test6(i32 signext %x, %struct.test6* byval align 16 %y)
+void test6 (int x, struct test6 y)
+{
+}
+
+// This case requires run-time realignment of the incoming struct
+// CHECK: define void @test7(i32 signext %x, %struct.test7* byval align 16)
+// CHECK: %y = alloca %struct.test7, align 32
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
+void test7 (int x, struct test7 y)
+{
+}
+
+// CHECK: define void @test1va(%struct.test1* noalias sret %agg.result, i32 signext %x, ...)
+// CHECK: %[[CUR:[^ ]+]] = load i8** %ap
+// CHECK: %[[NEXT:[^ ]+]] = getelementptr i8* %[[CUR]], i64 8
+// CHECK: store i8* %[[NEXT]], i8** %ap
+// CHECK: bitcast i8* %[[CUR]] to %struct.test1*
+struct test1 test1va (int x, ...)
+{
+  struct test1 y;
+  va_list ap;
+  va_start(ap, x);
+  y = va_arg (ap, struct test1);
+  va_end(ap);
+  return y;
+}
+
+// CHECK: define void @test2va(%struct.test2* noalias sret %agg.result, i32 signext %x, ...)
+// CHECK: %[[CUR:[^ ]+]] = load i8** %ap
+// CHECK: %[[TMP0:[^ ]+]] = ptrtoint i8* %[[CUR]] to i64
+// CHECK: %[[TMP1:[^ ]+]] = add i64 %[[TMP0]], 15
+// CHECK: %[[TMP2:[^ ]+]] = and i64 %[[TMP1]], -16
+// CHECK: %[[ALIGN:[^ ]+]] = inttoptr i64 %[[TMP2]] to i8*
+// CHECK: %[[NEXT:[^ ]+]] = getelementptr i8* %[[ALIGN]], i64 16
+// CHECK: store i8* %[[NEXT]], i8** %ap
+// CHECK: bitcast i8* %[[ALIGN]] to %struct.test2*
+struct test2 test2va (int x, ...)
+{
+  struct test2 y;
+  va_list ap;
+  va_start(ap, x);
+  y = va_arg (ap, struct test2);
+  va_end(ap);
+  return y;
+}
+
+// CHECK: define void @test3va(%struct.test3* noalias sret %agg.result, i32 signext %x, ...)
+// CHECK: %[[CUR:[^ ]+]] = load i8** %ap
+// CHECK: %[[TMP0:[^ ]+]] = ptrtoint i8* %[[CUR]] to i64
+// CHECK: %[[TMP1:[^ ]+]] = add i64 %[[TMP0]], 15
+// CHECK: %[[TMP2:[^ ]+]] = and i64 %[[TMP1]], -16
+// CHECK: %[[ALIGN:[^ ]+]] = inttoptr i64 %[[TMP2]] to i8*
+// CHECK: %[[NEXT:[^ ]+]] = getelementptr i8* %[[ALIGN]], i64 32
+// CHECK: store i8* %[[NEXT]], i8** %ap
+// CHECK: bitcast i8* %[[ALIGN]] to %struct.test3*
+struct test3 test3va (int x, ...)
+{
+  struct test3 y;
+  va_list ap;
+  va_start(ap, x);
+  y = va_arg (ap, struct test3);
+  va_end(ap);
+  return y;
+}
+
+// CHECK: define void @test4va(%struct.test4* noalias sret %agg.result, i32 signext %x, ...)
+// CHECK: %[[CUR:[^ ]+]] = load i8** %ap
+// CHECK: %[[NEXT:[^ ]+]] = getelementptr i8* %[[CUR]], i64 16
+// CHECK: store i8* %[[NEXT]], i8** %ap
+// CHECK: bitcast i8* %[[CUR]] to %struct.test4*
+struct test4 test4va (int x, ...)
+{
+  struct test4 y;
+  va_list ap;
+  va_start(ap, x);
+  y = va_arg (ap, struct test4);
+  va_end(ap);
+  return y;
+}
+
+// CHECK: define void @testva_longdouble(%struct.test_longdouble* noalias sret %agg.result, i32 signext %x, ...)
+// CHECK: %[[CUR:[^ ]+]] = load i8** %ap
+// CHECK: %[[NEXT:[^ ]+]] = getelementptr i8* %[[CUR]], i64 16
+// CHECK: store i8* %[[NEXT]], i8** %ap
+// CHECK: bitcast i8* %[[CUR]] to %struct.test_longdouble*
+struct test_longdouble { long double x; };
+struct test_longdouble testva_longdouble (int x, ...)
+{
+  struct test_longdouble y;
+  va_list ap;
+  va_start(ap, x);
+  y = va_arg (ap, struct test_longdouble);
+  va_end(ap);
+  return y;
+}
+
+// CHECK: define void @testva_vector(%struct.test_vector* noalias sret %agg.result, i32 signext %x, ...)
+// CHECK: %[[CUR:[^ ]+]] = load i8** %ap
+// CHECK: %[[TMP0:[^ ]+]] = ptrtoint i8* %[[CUR]] to i64
+// CHECK: %[[TMP1:[^ ]+]] = add i64 %[[TMP0]], 15
+// CHECK: %[[TMP2:[^ ]+]] = and i64 %[[TMP1]], -16
+// CHECK: %[[ALIGN:[^ ]+]] = inttoptr i64 %[[TMP2]] to i8*
+// CHECK: %[[NEXT:[^ ]+]] = getelementptr i8* %[[ALIGN]], i64 16
+// CHECK: store i8* %[[NEXT]], i8** %ap
+// CHECK: bitcast i8* %[[ALIGN]] to %struct.test_vector*
+struct test_vector { vector int x; };
+struct test_vector testva_vector (int x, ...)
+{
+  struct test_vector y;
+  va_list ap;
+  va_start(ap, x);
+  y = va_arg (ap, struct test_vector);
+  va_end(ap);
+  return y;
+}
+
diff --git a/test/CodeGen/ppc64-complex-parms.c b/test/CodeGen/ppc64-complex-parms.c
index 92a6fa5..fe3025a 100644
--- a/test/CodeGen/ppc64-complex-parms.c
+++ b/test/CodeGen/ppc64-complex-parms.c
@@ -1,4 +1,3 @@
-// REQUIRES: ppc64-registered-target
 // RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
 
 float crealf(_Complex float);
diff --git a/test/CodeGen/ppc64-complex-return.c b/test/CodeGen/ppc64-complex-return.c
index b3fd549..cdb0ed6 100644
--- a/test/CodeGen/ppc64-complex-return.c
+++ b/test/CodeGen/ppc64-complex-return.c
@@ -1,4 +1,4 @@
-// REQUIRES: ppc64-registered-target
+// REQUIRES: powerpc-registered-target
 // RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
 
 float crealf(_Complex float);
diff --git a/test/CodeGen/ppc64-extend.c b/test/CodeGen/ppc64-extend.c
index d46b651..52e5f13 100644
--- a/test/CodeGen/ppc64-extend.c
+++ b/test/CodeGen/ppc64-extend.c
@@ -1,4 +1,4 @@
-// REQUIRES: ppc64-registered-target
+// REQUIRES: powerpc-registered-target
 // RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
 
 void f1(int x) { return; }
diff --git a/test/CodeGen/ppc64-inline-asm.c b/test/CodeGen/ppc64-inline-asm.c
new file mode 100644
index 0000000..552fe28
--- /dev/null
+++ b/test/CodeGen/ppc64-inline-asm.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu -O2 -emit-llvm -o - %s | FileCheck %s
+
+_Bool test_wc_i1(_Bool b1, _Bool b2) {
+  _Bool o;
+  asm("crand %0, %1, %2" : "=wc"(o) : "wc"(b1), "wc"(b2) : );
+  return o;
+// CHECK-LABEL: define zeroext i1 @test_wc_i1(i1 zeroext %b1, i1 zeroext %b2)
+// CHECK: call i8 asm "crand $0, $1, $2", "=^wc,^wc,^wc"(i1 %b1, i1 %b2)
+}
+
+int test_wc_i32(int b1, int b2) {
+  int o;
+  asm("crand %0, %1, %2" : "=wc"(o) : "wc"(b1), "wc"(b2) : );
+  return o;
+// CHECK-LABEL: signext i32 @test_wc_i32(i32 signext %b1, i32 signext %b2)
+// CHECK: call i32 asm "crand $0, $1, $2", "=^wc,^wc,^wc"(i32 %b1, i32 %b2)
+}
+
+unsigned char test_wc_i8(unsigned char b1, unsigned char b2) {
+  unsigned char o;
+  asm("crand %0, %1, %2" : "=wc"(o) : "wc"(b1), "wc"(b2) : );
+  return o;
+// CHECK-LABEL: zeroext i8 @test_wc_i8(i8 zeroext %b1, i8 zeroext %b2)
+// CHECK: call i8 asm "crand $0, $1, $2", "=^wc,^wc,^wc"(i8 %b1, i8 %b2)
+}
+
diff --git a/test/CodeGen/ppc64-struct-onefloat.c b/test/CodeGen/ppc64-struct-onefloat.c
index e26987f..11b16a4 100644
--- a/test/CodeGen/ppc64-struct-onefloat.c
+++ b/test/CodeGen/ppc64-struct-onefloat.c
@@ -1,4 +1,4 @@
-// REQUIRES: ppc64-registered-target
+// REQUIRES: powerpc-registered-target
 // RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
 
 typedef struct s1 { float f; } Sf;
diff --git a/test/CodeGen/ppc64-struct-onevect.c b/test/CodeGen/ppc64-struct-onevect.c
index a5a1232..34f4cc0 100644
--- a/test/CodeGen/ppc64-struct-onevect.c
+++ b/test/CodeGen/ppc64-struct-onevect.c
@@ -1,4 +1,4 @@
-// REQUIRES: ppc64-registered-target
+// REQUIRES: powerpc-registered-target
 // RUN: %clang_cc1 -O2 -triple powerpc64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
 
 typedef float v4sf __attribute__ ((vector_size (16)));
diff --git a/test/CodeGen/ppc64-varargs-complex.c b/test/CodeGen/ppc64-varargs-complex.c
index b65a773..8fc8839 100644
--- a/test/CodeGen/ppc64-varargs-complex.c
+++ b/test/CodeGen/ppc64-varargs-complex.c
@@ -1,4 +1,4 @@
-// REQUIRES: ppc64-registered-target
+// REQUIRES: powerpc-registered-target
 // RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
 
 #include <stdarg.h>
diff --git a/test/CodeGen/ppc64-varargs-struct.c b/test/CodeGen/ppc64-varargs-struct.c
index 61c33b0..70b242c 100644
--- a/test/CodeGen/ppc64-varargs-struct.c
+++ b/test/CodeGen/ppc64-varargs-struct.c
@@ -1,4 +1,4 @@
-// REQUIRES: ppc64-registered-target
+// REQUIRES: powerpc-registered-target
 // RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
 
 #include <stdarg.h>
diff --git a/test/CodeGen/ppc64-vector.c b/test/CodeGen/ppc64-vector.c
new file mode 100644
index 0000000..f0211f0
--- /dev/null
+++ b/test/CodeGen/ppc64-vector.c
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -faltivec -triple powerpc64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
+
+typedef short v2i16 __attribute__((vector_size (4)));
+typedef short v3i16 __attribute__((vector_size (6)));
+typedef short v4i16 __attribute__((vector_size (8)));
+typedef short v6i16 __attribute__((vector_size (12)));
+typedef short v8i16 __attribute__((vector_size (16)));
+typedef short v16i16 __attribute__((vector_size (32)));
+
+struct v16i16 { v16i16 x; };
+
+// CHECK: define i32 @test_v2i16(i32 %x.coerce)
+v2i16 test_v2i16(v2i16 x)
+{
+  return x;
+}
+
+// CHECK: define i64 @test_v3i16(i64 %x.coerce)
+v3i16 test_v3i16(v3i16 x)
+{
+  return x;
+}
+
+// CHECK: define i64 @test_v4i16(i64 %x.coerce)
+v4i16 test_v4i16(v4i16 x)
+{
+  return x;
+}
+
+// CHECK: define <6 x i16> @test_v6i16(<6 x i16> %x)
+v6i16 test_v6i16(v6i16 x)
+{
+  return x;
+}
+
+// CHECK: define <8 x i16> @test_v8i16(<8 x i16> %x)
+v8i16 test_v8i16(v8i16 x)
+{
+  return x;
+}
+
+// CHECK: define void @test_v16i16(<16 x i16>* noalias sret %agg.result, <16 x i16>*)
+v16i16 test_v16i16(v16i16 x)
+{
+  return x;
+}
+
+// CHECK: define void @test_struct_v16i16(%struct.v16i16* noalias sret %agg.result, [2 x i128] %x.coerce)
+struct v16i16 test_struct_v16i16(struct v16i16 x)
+{
+  return x;
+}
diff --git a/test/CodeGen/ppc64le-aggregates.c b/test/CodeGen/ppc64le-aggregates.c
new file mode 100644
index 0000000..acf34a8
--- /dev/null
+++ b/test/CodeGen/ppc64le-aggregates.c
@@ -0,0 +1,423 @@
+// REQUIRES: powerpc-registered-target
+// RUN: %clang_cc1 -faltivec -triple powerpc64le-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
+
+// Test homogeneous float aggregate passing and returning.
+
+struct f1 { float f[1]; };
+struct f2 { float f[2]; };
+struct f3 { float f[3]; };
+struct f4 { float f[4]; };
+struct f5 { float f[5]; };
+struct f6 { float f[6]; };
+struct f7 { float f[7]; };
+struct f8 { float f[8]; };
+struct f9 { float f[9]; };
+
+struct fab { float a; float b; };
+struct fabc { float a; float b; float c; };
+
+// CHECK: define [1 x float] @func_f1(float inreg %x.coerce)
+struct f1 func_f1(struct f1 x) { return x; }
+
+// CHECK: define [2 x float] @func_f2([2 x float] %x.coerce)
+struct f2 func_f2(struct f2 x) { return x; }
+
+// CHECK: define [3 x float] @func_f3([3 x float] %x.coerce)
+struct f3 func_f3(struct f3 x) { return x; }
+
+// CHECK: define [4 x float] @func_f4([4 x float] %x.coerce)
+struct f4 func_f4(struct f4 x) { return x; }
+
+// CHECK: define [5 x float] @func_f5([5 x float] %x.coerce)
+struct f5 func_f5(struct f5 x) { return x; }
+
+// CHECK: define [6 x float] @func_f6([6 x float] %x.coerce)
+struct f6 func_f6(struct f6 x) { return x; }
+
+// CHECK: define [7 x float] @func_f7([7 x float] %x.coerce)
+struct f7 func_f7(struct f7 x) { return x; }
+
+// CHECK: define [8 x float] @func_f8([8 x float] %x.coerce)
+struct f8 func_f8(struct f8 x) { return x; }
+
+// CHECK: define void @func_f9(%struct.f9* noalias sret %agg.result, [5 x i64] %x.coerce)
+struct f9 func_f9(struct f9 x) { return x; }
+
+// CHECK: define [2 x float] @func_fab([2 x float] %x.coerce)
+struct fab func_fab(struct fab x) { return x; }
+
+// CHECK: define [3 x float] @func_fabc([3 x float] %x.coerce)
+struct fabc func_fabc(struct fabc x) { return x; }
+
+// CHECK-LABEL: @call_f1
+// CHECK: %[[TMP:[^ ]+]] = load float* getelementptr inbounds (%struct.f1* @global_f1, i32 0, i32 0, i32 0), align 1
+// CHECK: call [1 x float] @func_f1(float inreg %[[TMP]])
+struct f1 global_f1;
+void call_f1(void) { global_f1 = func_f1(global_f1); }
+
+// CHECK-LABEL: @call_f2
+// CHECK: %[[TMP:[^ ]+]] = load [2 x float]* getelementptr inbounds (%struct.f2* @global_f2, i32 0, i32 0), align 1
+// CHECK: call [2 x float] @func_f2([2 x float] %[[TMP]])
+struct f2 global_f2;
+void call_f2(void) { global_f2 = func_f2(global_f2); }
+
+// CHECK-LABEL: @call_f3
+// CHECK: %[[TMP:[^ ]+]] = load [3 x float]* getelementptr inbounds (%struct.f3* @global_f3, i32 0, i32 0), align 1
+// CHECK: call [3 x float] @func_f3([3 x float] %[[TMP]])
+struct f3 global_f3;
+void call_f3(void) { global_f3 = func_f3(global_f3); }
+
+// CHECK-LABEL: @call_f4
+// CHECK: %[[TMP:[^ ]+]] = load [4 x float]* getelementptr inbounds (%struct.f4* @global_f4, i32 0, i32 0), align 1
+// CHECK: call [4 x float] @func_f4([4 x float] %[[TMP]])
+struct f4 global_f4;
+void call_f4(void) { global_f4 = func_f4(global_f4); }
+
+// CHECK-LABEL: @call_f5
+// CHECK: %[[TMP:[^ ]+]] = load [5 x float]* getelementptr inbounds (%struct.f5* @global_f5, i32 0, i32 0), align 1
+// CHECK: call [5 x float] @func_f5([5 x float] %[[TMP]])
+struct f5 global_f5;
+void call_f5(void) { global_f5 = func_f5(global_f5); }
+
+// CHECK-LABEL: @call_f6
+// CHECK: %[[TMP:[^ ]+]] = load [6 x float]* getelementptr inbounds (%struct.f6* @global_f6, i32 0, i32 0), align 1
+// CHECK: call [6 x float] @func_f6([6 x float] %[[TMP]])
+struct f6 global_f6;
+void call_f6(void) { global_f6 = func_f6(global_f6); }
+
+// CHECK-LABEL: @call_f7
+// CHECK: %[[TMP:[^ ]+]] = load [7 x float]* getelementptr inbounds (%struct.f7* @global_f7, i32 0, i32 0), align 1
+// CHECK: call [7 x float] @func_f7([7 x float] %[[TMP]])
+struct f7 global_f7;
+void call_f7(void) { global_f7 = func_f7(global_f7); }
+
+// CHECK-LABEL: @call_f8
+// CHECK: %[[TMP:[^ ]+]] = load [8 x float]* getelementptr inbounds (%struct.f8* @global_f8, i32 0, i32 0), align 1
+// CHECK: call [8 x float] @func_f8([8 x float] %[[TMP]])
+struct f8 global_f8;
+void call_f8(void) { global_f8 = func_f8(global_f8); }
+
+// CHECK-LABEL: @call_f9
+// CHECK: %[[TMP1:[^ ]+]] = alloca [5 x i64]
+// CHECK: %[[TMP2:[^ ]+]] = bitcast [5 x i64]* %[[TMP1]] to i8*
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %[[TMP2]], i8* bitcast (%struct.f9* @global_f9 to i8*), i64 36, i32 1, i1 false)
+// CHECK: %[[TMP3:[^ ]+]] = load [5 x i64]* %[[TMP1]]
+// CHECK: call void @func_f9(%struct.f9* sret %{{[^ ]+}}, [5 x i64] %[[TMP3]])
+struct f9 global_f9;
+void call_f9(void) { global_f9 = func_f9(global_f9); }
+
+// CHECK-LABEL: @call_fab
+// CHECK: %[[TMP:[^ ]+]] = load [2 x float]* bitcast (%struct.fab* @global_fab to [2 x float]*)
+// CHECK: call [2 x float] @func_fab([2 x float] %[[TMP]])
+struct fab global_fab;
+void call_fab(void) { global_fab = func_fab(global_fab); }
+
+// CHECK-LABEL: @call_fabc
+// CHECK: %[[TMP:[^ ]+]] = load [3 x float]* bitcast (%struct.fabc* @global_fabc to [3 x float]*)
+// CHECK: call [3 x float] @func_fabc([3 x float] %[[TMP]])
+struct fabc global_fabc;
+void call_fabc(void) { global_fabc = func_fabc(global_fabc); }
+
+
+// Test homogeneous vector aggregate passing and returning.
+
+struct v1 { vector int v[1]; };
+struct v2 { vector int v[2]; };
+struct v3 { vector int v[3]; };
+struct v4 { vector int v[4]; };
+struct v5 { vector int v[5]; };
+struct v6 { vector int v[6]; };
+struct v7 { vector int v[7]; };
+struct v8 { vector int v[8]; };
+struct v9 { vector int v[9]; };
+
+struct vab { vector int a; vector int b; };
+struct vabc { vector int a; vector int b; vector int c; };
+
+// CHECK: define [1 x <4 x i32>] @func_v1(<4 x i32> inreg %x.coerce)
+struct v1 func_v1(struct v1 x) { return x; }
+
+// CHECK: define [2 x <4 x i32>] @func_v2([2 x <4 x i32>] %x.coerce)
+struct v2 func_v2(struct v2 x) { return x; }
+
+// CHECK: define [3 x <4 x i32>] @func_v3([3 x <4 x i32>] %x.coerce)
+struct v3 func_v3(struct v3 x) { return x; }
+
+// CHECK: define [4 x <4 x i32>] @func_v4([4 x <4 x i32>] %x.coerce)
+struct v4 func_v4(struct v4 x) { return x; }
+
+// CHECK: define [5 x <4 x i32>] @func_v5([5 x <4 x i32>] %x.coerce)
+struct v5 func_v5(struct v5 x) { return x; }
+
+// CHECK: define [6 x <4 x i32>] @func_v6([6 x <4 x i32>] %x.coerce)
+struct v6 func_v6(struct v6 x) { return x; }
+
+// CHECK: define [7 x <4 x i32>] @func_v7([7 x <4 x i32>] %x.coerce)
+struct v7 func_v7(struct v7 x) { return x; }
+
+// CHECK: define [8 x <4 x i32>] @func_v8([8 x <4 x i32>] %x.coerce)
+struct v8 func_v8(struct v8 x) { return x; }
+
+// CHECK: define void @func_v9(%struct.v9* noalias sret %agg.result, %struct.v9* byval align 16 %x)
+struct v9 func_v9(struct v9 x) { return x; }
+
+// CHECK: define [2 x <4 x i32>] @func_vab([2 x <4 x i32>] %x.coerce)
+struct vab func_vab(struct vab x) { return x; }
+
+// CHECK: define [3 x <4 x i32>] @func_vabc([3 x <4 x i32>] %x.coerce)
+struct vabc func_vabc(struct vabc x) { return x; }
+
+// CHECK-LABEL: @call_v1
+// CHECK: %[[TMP:[^ ]+]] = load <4 x i32>* getelementptr inbounds (%struct.v1* @global_v1, i32 0, i32 0, i32 0), align 1
+// CHECK: call [1 x <4 x i32>] @func_v1(<4 x i32> inreg %[[TMP]])
+struct v1 global_v1;
+void call_v1(void) { global_v1 = func_v1(global_v1); }
+
+// CHECK-LABEL: @call_v2
+// CHECK: %[[TMP:[^ ]+]] = load [2 x <4 x i32>]* getelementptr inbounds (%struct.v2* @global_v2, i32 0, i32 0), align 1
+// CHECK: call [2 x <4 x i32>] @func_v2([2 x <4 x i32>] %[[TMP]])
+struct v2 global_v2;
+void call_v2(void) { global_v2 = func_v2(global_v2); }
+
+// CHECK-LABEL: @call_v3
+// CHECK: %[[TMP:[^ ]+]] = load [3 x <4 x i32>]* getelementptr inbounds (%struct.v3* @global_v3, i32 0, i32 0), align 1
+// CHECK: call [3 x <4 x i32>] @func_v3([3 x <4 x i32>] %[[TMP]])
+struct v3 global_v3;
+void call_v3(void) { global_v3 = func_v3(global_v3); }
+
+// CHECK-LABEL: @call_v4
+// CHECK: %[[TMP:[^ ]+]] = load [4 x <4 x i32>]* getelementptr inbounds (%struct.v4* @global_v4, i32 0, i32 0), align 1
+// CHECK: call [4 x <4 x i32>] @func_v4([4 x <4 x i32>] %[[TMP]])
+struct v4 global_v4;
+void call_v4(void) { global_v4 = func_v4(global_v4); }
+
+// CHECK-LABEL: @call_v5
+// CHECK: %[[TMP:[^ ]+]] = load [5 x <4 x i32>]* getelementptr inbounds (%struct.v5* @global_v5, i32 0, i32 0), align 1
+// CHECK: call [5 x <4 x i32>] @func_v5([5 x <4 x i32>] %[[TMP]])
+struct v5 global_v5;
+void call_v5(void) { global_v5 = func_v5(global_v5); }
+
+// CHECK-LABEL: @call_v6
+// CHECK: %[[TMP:[^ ]+]] = load [6 x <4 x i32>]* getelementptr inbounds (%struct.v6* @global_v6, i32 0, i32 0), align 1
+// CHECK: call [6 x <4 x i32>] @func_v6([6 x <4 x i32>] %[[TMP]])
+struct v6 global_v6;
+void call_v6(void) { global_v6 = func_v6(global_v6); }
+
+// CHECK-LABEL: @call_v7
+// CHECK: %[[TMP:[^ ]+]] = load [7 x <4 x i32>]* getelementptr inbounds (%struct.v7* @global_v7, i32 0, i32 0), align 1
+// CHECK: call [7 x <4 x i32>] @func_v7([7 x <4 x i32>] %[[TMP]])
+struct v7 global_v7;
+void call_v7(void) { global_v7 = func_v7(global_v7); }
+
+// CHECK-LABEL: @call_v8
+// CHECK: %[[TMP:[^ ]+]] = load [8 x <4 x i32>]* getelementptr inbounds (%struct.v8* @global_v8, i32 0, i32 0), align 1
+// CHECK: call [8 x <4 x i32>] @func_v8([8 x <4 x i32>] %[[TMP]])
+struct v8 global_v8;
+void call_v8(void) { global_v8 = func_v8(global_v8); }
+
+// CHECK-LABEL: @call_v9
+// CHECK: call void @func_v9(%struct.v9* sret %{{[^ ]+}}, %struct.v9* byval align 16 @global_v9)
+struct v9 global_v9;
+void call_v9(void) { global_v9 = func_v9(global_v9); }
+
+// CHECK-LABEL: @call_vab
+// CHECK: %[[TMP:[^ ]+]] = load [2 x <4 x i32>]* bitcast (%struct.vab* @global_vab to [2 x <4 x i32>]*)
+// CHECK: call [2 x <4 x i32>] @func_vab([2 x <4 x i32>] %[[TMP]])
+struct vab global_vab;
+void call_vab(void) { global_vab = func_vab(global_vab); }
+
+// CHECK-LABEL: @call_vabc
+// CHECK: %[[TMP:[^ ]+]] = load [3 x <4 x i32>]* bitcast (%struct.vabc* @global_vabc to [3 x <4 x i32>]*)
+// CHECK: call [3 x <4 x i32>] @func_vabc([3 x <4 x i32>] %[[TMP]])
+struct vabc global_vabc;
+void call_vabc(void) { global_vabc = func_vabc(global_vabc); }
+
+
+// As clang extension, non-power-of-two vectors may also be part of
+// homogeneous aggregates.
+
+typedef float float3 __attribute__((vector_size (12)));
+
+struct v3f1 { float3 v[1]; };
+struct v3f2 { float3 v[2]; };
+struct v3f3 { float3 v[3]; };
+struct v3f4 { float3 v[4]; };
+struct v3f5 { float3 v[5]; };
+struct v3f6 { float3 v[6]; };
+struct v3f7 { float3 v[7]; };
+struct v3f8 { float3 v[8]; };
+struct v3f9 { float3 v[9]; };
+
+struct v3fab { float3 a; float3 b; };
+struct v3fabc { float3 a; float3 b; float3 c; };
+
+// CHECK: define [1 x <3 x float>] @func_v3f1(<3 x float> inreg %x.coerce)
+struct v3f1 func_v3f1(struct v3f1 x) { return x; }
+
+// CHECK: define [2 x <3 x float>] @func_v3f2([2 x <3 x float>] %x.coerce)
+struct v3f2 func_v3f2(struct v3f2 x) { return x; }
+
+// CHECK: define [3 x <3 x float>] @func_v3f3([3 x <3 x float>] %x.coerce)
+struct v3f3 func_v3f3(struct v3f3 x) { return x; }
+
+// CHECK: define [4 x <3 x float>] @func_v3f4([4 x <3 x float>] %x.coerce)
+struct v3f4 func_v3f4(struct v3f4 x) { return x; }
+
+// CHECK: define [5 x <3 x float>] @func_v3f5([5 x <3 x float>] %x.coerce)
+struct v3f5 func_v3f5(struct v3f5 x) { return x; }
+
+// CHECK: define [6 x <3 x float>] @func_v3f6([6 x <3 x float>] %x.coerce)
+struct v3f6 func_v3f6(struct v3f6 x) { return x; }
+
+// CHECK: define [7 x <3 x float>] @func_v3f7([7 x <3 x float>] %x.coerce)
+struct v3f7 func_v3f7(struct v3f7 x) { return x; }
+
+// CHECK: define [8 x <3 x float>] @func_v3f8([8 x <3 x float>] %x.coerce)
+struct v3f8 func_v3f8(struct v3f8 x) { return x; }
+
+// CHECK: define void @func_v3f9(%struct.v3f9* noalias sret %agg.result, %struct.v3f9* byval align 16 %x)
+struct v3f9 func_v3f9(struct v3f9 x) { return x; }
+
+// CHECK: define [2 x <3 x float>] @func_v3fab([2 x <3 x float>] %x.coerce)
+struct v3fab func_v3fab(struct v3fab x) { return x; }
+
+// CHECK: define [3 x <3 x float>] @func_v3fabc([3 x <3 x float>] %x.coerce)
+struct v3fabc func_v3fabc(struct v3fabc x) { return x; }
+
+// CHECK-LABEL: @call_v3f1
+// CHECK: %[[TMP:[^ ]+]] = load <3 x float>* getelementptr inbounds (%struct.v3f1* @global_v3f1, i32 0, i32 0, i32 0), align 1
+// CHECK: call [1 x <3 x float>] @func_v3f1(<3 x float> inreg %[[TMP]])
+struct v3f1 global_v3f1;
+void call_v3f1(void) { global_v3f1 = func_v3f1(global_v3f1); }
+
+// CHECK-LABEL: @call_v3f2
+// CHECK: %[[TMP:[^ ]+]] = load [2 x <3 x float>]* getelementptr inbounds (%struct.v3f2* @global_v3f2, i32 0, i32 0), align 1
+// CHECK: call [2 x <3 x float>] @func_v3f2([2 x <3 x float>] %[[TMP]])
+struct v3f2 global_v3f2;
+void call_v3f2(void) { global_v3f2 = func_v3f2(global_v3f2); }
+
+// CHECK-LABEL: @call_v3f3
+// CHECK: %[[TMP:[^ ]+]] = load [3 x <3 x float>]* getelementptr inbounds (%struct.v3f3* @global_v3f3, i32 0, i32 0), align 1
+// CHECK: call [3 x <3 x float>] @func_v3f3([3 x <3 x float>] %[[TMP]])
+struct v3f3 global_v3f3;
+void call_v3f3(void) { global_v3f3 = func_v3f3(global_v3f3); }
+
+// CHECK-LABEL: @call_v3f4
+// CHECK: %[[TMP:[^ ]+]] = load [4 x <3 x float>]* getelementptr inbounds (%struct.v3f4* @global_v3f4, i32 0, i32 0), align 1
+// CHECK: call [4 x <3 x float>] @func_v3f4([4 x <3 x float>] %[[TMP]])
+struct v3f4 global_v3f4;
+void call_v3f4(void) { global_v3f4 = func_v3f4(global_v3f4); }
+
+// CHECK-LABEL: @call_v3f5
+// CHECK: %[[TMP:[^ ]+]] = load [5 x <3 x float>]* getelementptr inbounds (%struct.v3f5* @global_v3f5, i32 0, i32 0), align 1
+// CHECK: call [5 x <3 x float>] @func_v3f5([5 x <3 x float>] %[[TMP]])
+struct v3f5 global_v3f5;
+void call_v3f5(void) { global_v3f5 = func_v3f5(global_v3f5); }
+
+// CHECK-LABEL: @call_v3f6
+// CHECK: %[[TMP:[^ ]+]] = load [6 x <3 x float>]* getelementptr inbounds (%struct.v3f6* @global_v3f6, i32 0, i32 0), align 1
+// CHECK: call [6 x <3 x float>] @func_v3f6([6 x <3 x float>] %[[TMP]])
+struct v3f6 global_v3f6;
+void call_v3f6(void) { global_v3f6 = func_v3f6(global_v3f6); }
+
+// CHECK-LABEL: @call_v3f7
+// CHECK: %[[TMP:[^ ]+]] = load [7 x <3 x float>]* getelementptr inbounds (%struct.v3f7* @global_v3f7, i32 0, i32 0), align 1
+// CHECK: call [7 x <3 x float>] @func_v3f7([7 x <3 x float>] %[[TMP]])
+struct v3f7 global_v3f7;
+void call_v3f7(void) { global_v3f7 = func_v3f7(global_v3f7); }
+
+// CHECK-LABEL: @call_v3f8
+// CHECK: %[[TMP:[^ ]+]] = load [8 x <3 x float>]* getelementptr inbounds (%struct.v3f8* @global_v3f8, i32 0, i32 0), align 1
+// CHECK: call [8 x <3 x float>] @func_v3f8([8 x <3 x float>] %[[TMP]])
+struct v3f8 global_v3f8;
+void call_v3f8(void) { global_v3f8 = func_v3f8(global_v3f8); }
+
+// CHECK-LABEL: @call_v3f9
+// CHECK: call void @func_v3f9(%struct.v3f9* sret %{{[^ ]+}}, %struct.v3f9* byval align 16 @global_v3f9)
+struct v3f9 global_v3f9;
+void call_v3f9(void) { global_v3f9 = func_v3f9(global_v3f9); }
+
+// CHECK-LABEL: @call_v3fab
+// CHECK: %[[TMP:[^ ]+]] = load [2 x <3 x float>]* bitcast (%struct.v3fab* @global_v3fab to [2 x <3 x float>]*)
+// CHECK: call [2 x <3 x float>] @func_v3fab([2 x <3 x float>] %[[TMP]])
+struct v3fab global_v3fab;
+void call_v3fab(void) { global_v3fab = func_v3fab(global_v3fab); }
+
+// CHECK-LABEL: @call_v3fabc
+// CHECK: %[[TMP:[^ ]+]] = load [3 x <3 x float>]* bitcast (%struct.v3fabc* @global_v3fabc to [3 x <3 x float>]*)
+// CHECK: call [3 x <3 x float>] @func_v3fabc([3 x <3 x float>] %[[TMP]])
+struct v3fabc global_v3fabc;
+void call_v3fabc(void) { global_v3fabc = func_v3fabc(global_v3fabc); }
+
+
+// Test returning small aggregates.
+
+struct s1 { char c[1]; };
+struct s2 { char c[2]; };
+struct s3 { char c[3]; };
+struct s4 { char c[4]; };
+struct s5 { char c[5]; };
+struct s6 { char c[6]; };
+struct s7 { char c[7]; };
+struct s8 { char c[8]; };
+struct s9 { char c[9]; };
+struct s16 { char c[16]; };
+struct s17 { char c[17]; };
+
+// CHECK: define i8 @ret_s1()
+struct s1 ret_s1() {
+  return (struct s1) { 17 };
+}
+
+// CHECK: define i16 @ret_s2()
+struct s2 ret_s2() {
+  return (struct s2) { 17, 18 };
+}
+
+// CHECK: define i24 @ret_s3()
+struct s3 ret_s3() {
+  return (struct s3) { 17, 18, 19 };
+}
+
+// CHECK: define i32 @ret_s4()
+struct s4 ret_s4() {
+  return (struct s4) { 17, 18, 19, 20 };
+}
+
+// CHECK: define i40 @ret_s5()
+struct s5 ret_s5() {
+  return (struct s5) { 17, 18, 19, 20, 21 };
+}
+
+// CHECK: define i48 @ret_s6()
+struct s6 ret_s6() {
+  return (struct s6) { 17, 18, 19, 20, 21, 22 };
+}
+
+// CHECK: define i56 @ret_s7()
+struct s7 ret_s7() {
+  return (struct s7) { 17, 18, 19, 20, 21, 22, 23 };
+}
+
+// CHECK: define i64 @ret_s8()
+struct s8 ret_s8() {
+  return (struct s8) { 17, 18, 19, 20, 21, 22, 23, 24 };
+}
+
+// CHECK: define { i64, i64 } @ret_s9()
+struct s9 ret_s9() {
+  return (struct s9) { 17, 18, 19, 20, 21, 22, 23, 24, 25 };
+}
+
+// CHECK: define { i64, i64 } @ret_s16()
+struct s16 ret_s16() {
+  return (struct s16) { 17, 18, 19, 20, 21, 22, 23, 24,
+                        25, 26, 27, 28, 29, 30, 31, 32 };
+}
+
+// CHECK: define void @ret_s17(%struct.s17*
+struct s17 ret_s17() {
+  return (struct s17) { 17, 18, 19, 20, 21, 22, 23, 24,
+                        25, 26, 27, 28, 29, 30, 31, 32, 33 };
+}
+
diff --git a/test/CodeGen/ppc64le-varargs-complex.c b/test/CodeGen/ppc64le-varargs-complex.c
new file mode 100644
index 0000000..b89f462
--- /dev/null
+++ b/test/CodeGen/ppc64le-varargs-complex.c
@@ -0,0 +1,69 @@
+// REQUIRES: powerpc-registered-target
+// RUN: %clang_cc1 -triple powerpc64le-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
+
+#include <stdarg.h>
+
+void testva (int n, ...)
+{
+  va_list ap;
+
+  _Complex int i   = va_arg(ap, _Complex int);
+  // CHECK: %[[VAR40:[A-Za-z0-9.]+]] = load i8** %[[VAR100:[A-Za-z0-9.]+]]
+  // CHECK-NEXT: %[[VAR41:[A-Za-z0-9.]+]] = getelementptr i8* %[[VAR40]], i64 16
+  // CHECK-NEXT: store i8* %[[VAR41]], i8** %[[VAR100]]
+  // CHECK-NEXT: %[[VAR1:[A-Za-z0-9.]+]] = ptrtoint i8* %[[VAR40]] to i64
+  // CHECK-NEXT: %[[VAR3:[A-Za-z0-9.]+]] = add i64 %[[VAR1]], 8
+  // CHECK-NEXT: %[[VAR4:[A-Za-z0-9.]+]] = inttoptr i64 %[[VAR1]] to i32*
+  // CHECK-NEXT: %[[VAR5:[A-Za-z0-9.]+]] = inttoptr i64 %[[VAR3]] to i32*
+  // CHECK-NEXT: %[[VAR6:[A-Za-z0-9.]+]] = load i32* %[[VAR4]]
+  // CHECK-NEXT: %[[VAR7:[A-Za-z0-9.]+]] = load i32* %[[VAR5]]
+  // CHECK-NEXT: %[[VAR8:[A-Za-z0-9.]+]] = getelementptr inbounds { i32, i32 }* %[[VAR0:[A-Za-z0-9.]+]], i32 0, i32 0
+  // CHECK-NEXT: %[[VAR9:[A-Za-z0-9.]+]] = getelementptr inbounds { i32, i32 }* %[[VAR0]], i32 0, i32 1
+  // CHECK-NEXT: store i32 %[[VAR6]], i32* %[[VAR8]]
+  // CHECK-NEXT: store i32 %[[VAR7]], i32* %[[VAR9]]
+
+  _Complex short s = va_arg(ap, _Complex short);
+  // CHECK: %[[VAR50:[A-Za-z0-9.]+]] = load i8** %[[VAR100:[A-Za-z0-9.]+]]
+  // CHECK-NEXT: %[[VAR51:[A-Za-z0-9.]+]] = getelementptr i8* %[[VAR50]], i64 16
+  // CHECK-NEXT: store i8* %[[VAR51]], i8** %[[VAR100]]
+  // CHECK: %[[VAR11:[A-Za-z0-9.]+]] = ptrtoint i8* %{{[A-Za-z0-9.]+}} to i64
+  // CHECK-NEXT: %[[VAR13:[A-Za-z0-9.]+]] = add i64 %[[VAR11]], 8
+  // CHECK-NEXT: %[[VAR14:[A-Za-z0-9.]+]] = inttoptr i64 %[[VAR11]] to i16*
+  // CHECK-NEXT: %[[VAR15:[A-Za-z0-9.]+]] = inttoptr i64 %[[VAR13]] to i16*
+  // CHECK-NEXT: %[[VAR16:[A-Za-z0-9.]+]] = load i16* %[[VAR14]]
+  // CHECK-NEXT: %[[VAR17:[A-Za-z0-9.]+]] = load i16* %[[VAR15]]
+  // CHECK-NEXT: %[[VAR18:[A-Za-z0-9.]+]] = getelementptr inbounds { i16, i16 }* %[[VAR10:[A-Za-z0-9.]+]], i32 0, i32 0
+  // CHECK-NEXT: %[[VAR19:[A-Za-z0-9.]+]] = getelementptr inbounds { i16, i16 }* %[[VAR10]], i32 0, i32 1
+  // CHECK-NEXT: store i16 %[[VAR16]], i16* %[[VAR18]]
+  // CHECK-NEXT: store i16 %[[VAR17]], i16* %[[VAR19]]
+
+  _Complex char c  = va_arg(ap, _Complex char);
+  // CHECK: %[[VAR60:[A-Za-z0-9.]+]] = load i8** %[[VAR100:[A-Za-z0-9.]+]]
+  // CHECK-NEXT: %[[VAR61:[A-Za-z0-9.]+]] = getelementptr i8* %[[VAR60]], i64 16
+  // CHECK-NEXT: store i8* %[[VAR61]], i8** %[[VAR100]]
+  // CHECK: %[[VAR21:[A-Za-z0-9.]+]] = ptrtoint i8* %{{[A-Za-z0-9.]+}} to i64
+  // CHECK-NEXT: %[[VAR23:[A-Za-z0-9.]+]] = add i64 %[[VAR21]], 8
+  // CHECK-NEXT: %[[VAR24:[A-Za-z0-9.]+]] = inttoptr i64 %[[VAR21]] to i8*
+  // CHECK-NEXT: %[[VAR25:[A-Za-z0-9.]+]] = inttoptr i64 %[[VAR23]] to i8*
+  // CHECK-NEXT: %[[VAR26:[A-Za-z0-9.]+]] = load i8* %[[VAR24]]
+  // CHECK-NEXT: %[[VAR27:[A-Za-z0-9.]+]] = load i8* %[[VAR25]]
+  // CHECK-NEXT: %[[VAR28:[A-Za-z0-9.]+]] = getelementptr inbounds { i8, i8 }* %[[VAR20:[A-Za-z0-9.]+]], i32 0, i32 0
+  // CHECK-NEXT: %[[VAR29:[A-Za-z0-9.]+]] = getelementptr inbounds { i8, i8 }* %[[VAR20]], i32 0, i32 1
+  // CHECK-NEXT: store i8 %[[VAR26]], i8* %[[VAR28]]
+  // CHECK-NEXT: store i8 %[[VAR27]], i8* %[[VAR29]]
+
+  _Complex float f = va_arg(ap, _Complex float);
+  // CHECK: %[[VAR70:[A-Za-z0-9.]+]] = load i8** %[[VAR100:[A-Za-z0-9.]+]]
+  // CHECK-NEXT: %[[VAR71:[A-Za-z0-9.]+]] = getelementptr i8* %[[VAR70]], i64 16
+  // CHECK-NEXT: store i8* %[[VAR71]], i8** %[[VAR100]]
+  // CHECK: %[[VAR31:[A-Za-z0-9.]+]] = ptrtoint i8* %{{[A-Za-z0-9.]+}} to i64
+  // CHECK-NEXT: %[[VAR33:[A-Za-z0-9.]+]] = add i64 %[[VAR31]], 8
+  // CHECK-NEXT: %[[VAR34:[A-Za-z0-9.]+]] = inttoptr i64 %[[VAR31]] to float*
+  // CHECK-NEXT: %[[VAR35:[A-Za-z0-9.]+]] = inttoptr i64 %[[VAR33]] to float*
+  // CHECK-NEXT: %[[VAR36:[A-Za-z0-9.]+]] = load float* %[[VAR34]]
+  // CHECK-NEXT: %[[VAR37:[A-Za-z0-9.]+]] = load float* %[[VAR35]]
+  // CHECK-NEXT: %[[VAR38:[A-Za-z0-9.]+]] = getelementptr inbounds { float, float }* %[[VAR30:[A-Za-z0-9.]+]], i32 0, i32 0
+  // CHECK-NEXT: %[[VAR39:[A-Za-z0-9.]+]] = getelementptr inbounds { float, float }* %[[VAR30]], i32 0, i32 1
+  // CHECK-NEXT: store float %[[VAR36]], float* %[[VAR38]]
+  // CHECK-NEXT: store float %[[VAR37]], float* %[[VAR39]]
+}
diff --git a/test/CodeGen/pr18235.c b/test/CodeGen/pr18235.c
new file mode 100644
index 0000000..d3f12ee
--- /dev/null
+++ b/test/CodeGen/pr18235.c
@@ -0,0 +1,3 @@
+// RUN: not %clang_cc1 -triple le32-unknown-nacl %s -S -o - 2>&1 | FileCheck %s
+
+// CHECK: error: unable to create target: 'No available targets are compatible with this triple, see -version for the available targets.'
diff --git a/test/CodeGen/pr19841.cpp b/test/CodeGen/pr19841.cpp
new file mode 100644
index 0000000..8fef683
--- /dev/null
+++ b/test/CodeGen/pr19841.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -emit-llvm %s -o -  | FileCheck %s
+
+namespace Common {
+enum RenderMode {
+  kRenderEGA,
+  kRenderCGA
+};
+class C;
+class A {
+  A();
+  C *_vm;
+  unsigned char _highlightColorTableVGA[];
+  static const unsigned char b[];
+};
+// CHECK: [[Common_A_b:@[^ ]+]] = constant [1 x i8] zeroinitializer
+class B {
+public:
+  Common::RenderMode _configRenderMode;
+};
+class C : public B {};
+A::A() {
+  0 == Common::kRenderCGA || _vm->_configRenderMode == Common::kRenderEGA
+      ? b
+      : _highlightColorTableVGA;
+// Make sure the PHI value is casted correctly to the PHI type
+// CHECK: %{{.*}} = phi [0 x i8]* [ bitcast ([1 x i8]* [[Common_A_b]] to [0 x i8]*), %{{.*}} ], [ %{{.*}}, %{{.*}} ]
+}
+const unsigned char A::b[] = { 0 };
+}
diff --git a/test/CodeGen/pragma-comment.c b/test/CodeGen/pragma-comment.c
index 30bf7b7..73cc548 100644
--- a/test/CodeGen/pragma-comment.c
+++ b/test/CodeGen/pragma-comment.c
@@ -9,8 +9,8 @@
 #define BAR "2"
 #pragma comment(linker," /bar=" BAR)
 
-// CHECK: !llvm.module.flags = !{!0}
-// CHECK: !0 = metadata !{i32 6, metadata !"Linker Options", metadata ![[link_opts:[0-9]+]]}
+// CHECK: !llvm.module.flags = !{{{.*}}}
+// CHECK: !{{[0-9]+}} = metadata !{i32 6, metadata !"Linker Options", metadata ![[link_opts:[0-9]+]]}
 // CHECK: ![[link_opts]] = metadata !{metadata ![[msvcrt:[0-9]+]], metadata ![[kernel32:[0-9]+]], metadata ![[USER32:[0-9]+]], metadata ![[bar:[0-9]+]]}
 // CHECK: ![[msvcrt]] = metadata !{metadata !"/DEFAULTLIB:msvcrt.lib"}
 // CHECK: ![[kernel32]] = metadata !{metadata !"/DEFAULTLIB:kernel32.lib"}
diff --git a/test/CodeGen/pragma-detect_mismatch.c b/test/CodeGen/pragma-detect_mismatch.c
index 86cc6d8..b223a61 100644
--- a/test/CodeGen/pragma-detect_mismatch.c
+++ b/test/CodeGen/pragma-detect_mismatch.c
@@ -5,8 +5,8 @@
 #define BAR "2"

 #pragma detect_mismatch("test2", BAR)

 

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

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

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

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

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

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

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

diff --git a/test/CodeGen/pragma-loop.cpp b/test/CodeGen/pragma-loop.cpp
new file mode 100644
index 0000000..bdcd304
--- /dev/null
+++ b/test/CodeGen/pragma-loop.cpp
@@ -0,0 +1,129 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+// Verify while loop is recognized after sequence of pragma clang loop directives.
+void while_test(int *List, int Length) {
+  // CHECK: define {{.*}} @_Z10while_test
+  int i = 0;
+
+#pragma clang loop vectorize(enable)
+#pragma clang loop interleave_count(4)
+#pragma clang loop vectorize_width(4)
+#pragma clang loop unroll(enable)
+  while (i < Length) {
+    // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_1:.*]]
+    List[i] = i * 2;
+    i++;
+  }
+}
+
+// Verify do loop is recognized after multi-option pragma clang loop directive.
+void do_test(int *List, int Length) {
+  int i = 0;
+
+#pragma clang loop vectorize_width(8) interleave_count(4) unroll(disable)
+  do {
+    // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_2:.*]]
+    List[i] = i * 2;
+    i++;
+  } while (i < Length);
+}
+
+// Verify for loop is recognized after sequence of pragma clang loop directives.
+void for_test(int *List, int Length) {
+#pragma clang loop interleave(enable)
+#pragma clang loop interleave_count(4)
+#pragma clang loop unroll_count(8)
+  for (int i = 0; i < Length; i++) {
+    // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_3:.*]]
+    List[i] = i * 2;
+  }
+}
+
+// Verify c++11 for range loop is recognized after
+// sequence of pragma clang loop directives.
+void for_range_test() {
+  double List[100];
+
+#pragma clang loop vectorize_width(2) interleave_count(2)
+  for (int i : List) {
+    // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_4:.*]]
+    List[i] = i;
+  }
+}
+
+// Verify disable pragma clang loop directive generates correct metadata
+void disable_test(int *List, int Length) {
+#pragma clang loop vectorize(disable) unroll(disable)
+  for (int i = 0; i < Length; i++) {
+    // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_5:.*]]
+    List[i] = i * 2;
+  }
+}
+
+#define VECWIDTH 2
+#define INTCOUNT 2
+#define UNROLLCOUNT 8
+
+// Verify defines are correctly resolved in pragma clang loop directive
+void for_define_test(int *List, int Length, int Value) {
+#pragma clang loop vectorize_width(VECWIDTH) interleave_count(INTCOUNT)
+#pragma clang loop unroll_count(UNROLLCOUNT)
+  for (int i = 0; i < Length; i++) {
+    // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_6:.*]]
+    List[i] = i * Value;
+  }
+}
+
+// Verify metadata is generated when template is used.
+template <typename A>
+void for_template_test(A *List, int Length, A Value) {
+
+#pragma clang loop vectorize_width(8) interleave_count(8) unroll_count(8)
+  for (int i = 0; i < Length; i++) {
+    // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_7:.*]]
+    List[i] = i * Value;
+  }
+}
+
+// Verify define is resolved correctly when template is used.
+template <typename A>
+void for_template_define_test(A *List, int Length, A Value) {
+#pragma clang loop vectorize_width(VECWIDTH) interleave_count(INTCOUNT)
+#pragma clang loop unroll_count(UNROLLCOUNT)
+  for (int i = 0; i < Length; i++) {
+    // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_8:.*]]
+    List[i] = i * Value;
+  }
+}
+
+#undef VECWIDTH
+#undef INTCOUNT
+#undef UNROLLCOUNT
+
+// Use templates defined above. Test verifies metadata is generated correctly.
+void template_test(double *List, int Length) {
+  double Value = 10;
+
+  for_template_test<double>(List, Length, Value);
+  for_template_define_test<double>(List, Length, Value);
+}
+
+// CHECK: ![[LOOP_1]] = metadata !{metadata ![[LOOP_1]], metadata ![[UNROLLENABLE_1:.*]], metadata ![[WIDTH_4:.*]], metadata ![[INTERLEAVE_4:.*]], metadata ![[INTENABLE_1:.*]]}
+// CHECK: ![[UNROLLENABLE_1]] = metadata !{metadata !"llvm.loop.unroll.enable", i1 true}
+// CHECK: ![[WIDTH_4]] = metadata !{metadata !"llvm.loop.vectorize.width", i32 4}
+// CHECK: ![[INTERLEAVE_4]] = metadata !{metadata !"llvm.loop.interleave.count", i32 4}
+// CHECK: ![[INTENABLE_1]] = metadata !{metadata !"llvm.loop.vectorize.enable", i1 true}
+// CHECK: ![[LOOP_2]] = metadata !{metadata ![[LOOP_2:.*]], metadata ![[UNROLLENABLE_0:.*]], metadata ![[INTERLEAVE_4:.*]], metadata ![[WIDTH_8:.*]]}
+// CHECK: ![[UNROLLENABLE_0]] = metadata !{metadata !"llvm.loop.unroll.enable", i1 false}
+// CHECK: ![[WIDTH_8]] = metadata !{metadata !"llvm.loop.vectorize.width", i32 8}
+// CHECK: ![[LOOP_3]] = metadata !{metadata ![[LOOP_3]], metadata ![[UNROLL_8:.*]], metadata ![[INTERLEAVE_4:.*]], metadata ![[ENABLE_1:.*]]}
+// CHECK: ![[UNROLL_8]] = metadata !{metadata !"llvm.loop.unroll.count", i32 8}
+// CHECK: ![[LOOP_4]] = metadata !{metadata ![[LOOP_4]], metadata ![[INTERLEAVE_2:.*]], metadata ![[WIDTH_2:.*]]}
+// CHECK: ![[INTERLEAVE_2]] = metadata !{metadata !"llvm.loop.interleave.count", i32 2}
+// CHECK: ![[WIDTH_2]] = metadata !{metadata !"llvm.loop.vectorize.width", i32 2}
+// CHECK: ![[LOOP_5]] = metadata !{metadata ![[LOOP_5]], metadata ![[UNROLLENABLE_0:.*]], metadata ![[WIDTH_1:.*]]}
+// CHECK: ![[WIDTH_1]] = metadata !{metadata !"llvm.loop.vectorize.width", i32 1}
+// CHECK: ![[LOOP_6]] = metadata !{metadata ![[LOOP_6]], metadata ![[UNROLL_8:.*]], metadata ![[INTERLEAVE_2:.*]], metadata ![[WIDTH_2:.*]]}
+// CHECK: ![[LOOP_7]] = metadata !{metadata ![[LOOP_7]], metadata ![[UNROLL_8:.*]], metadata ![[INTERLEAVE_8:.*]], metadata ![[WIDTH_8:.*]]}
+// CHECK: ![[INTERLEAVE_8]] = metadata !{metadata !"llvm.loop.interleave.count", i32 8}
+// CHECK: ![[LOOP_8]] = metadata !{metadata ![[LOOP_8]], metadata ![[UNROLL_8:.*]], metadata ![[INTERLEAVE_2:.*]], metadata ![[WIDTH_2:.*]]}
diff --git a/test/CodeGen/pragma-pack-1.c b/test/CodeGen/pragma-pack-1.c
index 2a71c8f..773318c 100644
--- a/test/CodeGen/pragma-pack-1.c
+++ b/test/CodeGen/pragma-pack-1.c
@@ -53,12 +53,12 @@
   int e;
 } s4;
 
-// CHECK: [[struct_ref:%[a-zA-Z0-9_.]+]] = type <{ [[struct_ref]]* }>
+// CHECK: [[struct_ref:%[a-zA-Z0-9_.]+]] = type { [[struct_ref]]* }
 // CHECK: [[struct_S:%[a-zA-Z0-9_.]+]] = type { [3 x i8], [[struct_T:%[a-zA-Z0-9_.]+]], [[struct_T2:%[a-zA-Z0-9_.]+]] }
 // CHECK: [[struct_T]] = type <{ i8, i32 }>
 // CHECK: [[struct_T2]] = type { i8, i32 }
 
-// CHECK: %struct.S3 = type <{ [3 x i8], i8, %struct.T3, [2 x i8], %struct.T32 }>
+// CHECK: %struct.S3 = type { [3 x i8], i8, %struct.T3, %struct.T32 }
 // CHECK: %struct.T3 = type <{ i8, i8, i32 }>
 // CHECK: %struct.T32 = type { i8, i32 }
 // CHECK: %struct.S4 = type { [3 x i8], %struct.T4, i32 }
diff --git a/test/CodeGen/pragma-pack-2.c b/test/CodeGen/pragma-pack-2.c
index 1ca3bdf..8a77280 100644
--- a/test/CodeGen/pragma-pack-2.c
+++ b/test/CodeGen/pragma-pack-2.c
@@ -4,7 +4,7 @@
 
 // RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -emit-llvm -o - | FileCheck -check-prefix CHECK-X64 %s
 // CHECK-X64: %struct.s0 = type <{ i64, i64, i32, [12 x i32] }>
-// CHECK-X64: %struct.s1 = type <{ [15 x i32], %struct.s0 }>
+// CHECK-X64: %struct.s1 = type { [15 x i32], %struct.s0 }
 
 // rdar://problem/7095436
 #pragma pack(4)
@@ -20,4 +20,3 @@
   int a[15];
   struct s0 b;
 } b;
-
diff --git a/test/CodeGen/pragma-unroll.cpp b/test/CodeGen/pragma-unroll.cpp
new file mode 100644
index 0000000..b321e74
--- /dev/null
+++ b/test/CodeGen/pragma-unroll.cpp
@@ -0,0 +1,99 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+// Verify while loop is recognized after unroll pragma.
+void while_test(int *List, int Length) {
+  // CHECK: define {{.*}} @_Z10while_test
+  int i = 0;
+
+#pragma unroll
+  while (i < Length) {
+    // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_1:.*]]
+    List[i] = i * 2;
+    i++;
+  }
+}
+
+// Verify do loop is recognized after multi-option pragma clang loop directive.
+void do_test(int *List, int Length) {
+  int i = 0;
+
+#pragma unroll 16
+  do {
+    // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_2:.*]]
+    List[i] = i * 2;
+    i++;
+  } while (i < Length);
+}
+
+// Verify for loop is recognized after unroll pragma.
+void for_test(int *List, int Length) {
+#pragma unroll 8
+  for (int i = 0; i < Length; i++) {
+    // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_3:.*]]
+    List[i] = i * 2;
+  }
+}
+
+// Verify c++11 for range loop is recognized after unroll pragma.
+void for_range_test() {
+  double List[100];
+
+#pragma unroll(4)
+  for (int i : List) {
+    // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_4:.*]]
+    List[i] = i;
+  }
+}
+
+#define UNROLLCOUNT 8
+
+// Verify defines are correctly resolved in unroll pragmas.
+void for_define_test(int *List, int Length, int Value) {
+#pragma unroll(UNROLLCOUNT)
+  for (int i = 0; i < Length; i++) {
+    // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_5:.*]]
+    List[i] = i * Value;
+  }
+}
+
+// Verify metadata is generated when template is used.
+template <typename A>
+void for_template_test(A *List, int Length, A Value) {
+#pragma unroll 8
+  for (int i = 0; i < Length; i++) {
+    // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_6:.*]]
+    List[i] = i * Value;
+  }
+}
+
+// Verify define is resolved correctly when template is used.
+template <typename A>
+void for_template_define_test(A *List, int Length, A Value) {
+#pragma unroll(UNROLLCOUNT)
+  for (int i = 0; i < Length; i++) {
+    // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_7:.*]]
+    List[i] = i * Value;
+  }
+}
+
+#undef UNROLLCOUNT
+
+// Use templates defined above. Test verifies metadata is generated correctly.
+void template_test(double *List, int Length) {
+  double Value = 10;
+
+  for_template_test<double>(List, Length, Value);
+  for_template_define_test<double>(List, Length, Value);
+}
+
+// CHECK: ![[LOOP_1]] = metadata !{metadata ![[LOOP_1]], metadata ![[UNROLLENABLE_1:.*]]}
+// CHECK: ![[UNROLLENABLE_1]] = metadata !{metadata !"llvm.loop.unroll.enable", i1 true}
+// CHECK: ![[LOOP_2]] = metadata !{metadata ![[LOOP_2:.*]], metadata ![[UNROLL_16:.*]]}
+// CHECK: ![[UNROLL_16]] = metadata !{metadata !"llvm.loop.unroll.count", i32 16}
+// CHECK: ![[LOOP_3]] = metadata !{metadata ![[LOOP_3]], metadata ![[UNROLL_8:.*]]}
+// CHECK: ![[UNROLL_8]] = metadata !{metadata !"llvm.loop.unroll.count", i32 8}
+// CHECK: ![[LOOP_4]] = metadata !{metadata ![[LOOP_4]], metadata ![[UNROLL_4:.*]]}
+// CHECK: ![[UNROLL_4]] = metadata !{metadata !"llvm.loop.unroll.count", i32 4}
+// CHECK: ![[LOOP_5]] = metadata !{metadata ![[LOOP_5]], metadata ![[UNROLL_8:.*]]}
+// CHECK: ![[LOOP_6]] = metadata !{metadata ![[LOOP_6]], metadata ![[UNROLL_8:.*]]}
+// CHECK: ![[LOOP_7]] = metadata !{metadata ![[LOOP_7]], metadata ![[UNROLL_8:.*]]}
diff --git a/test/CodeGen/predefined-expr.c b/test/CodeGen/predefined-expr.c
index 3471dcd..6c94152 100644
--- a/test/CodeGen/predefined-expr.c
+++ b/test/CodeGen/predefined-expr.c
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -fms-extensions %s -emit-llvm -o - | FileCheck %s
 
 // CHECK: @__func__.plainFunction = private unnamed_addr constant [14 x i8] c"plainFunction\00"
 // CHECK: @__PRETTY_FUNCTION__.plainFunction = private unnamed_addr constant [21 x i8] c"void plainFunction()\00"
diff --git a/test/CodeGen/r5.c b/test/CodeGen/r5.c
deleted file mode 100644
index 30a0c0d..0000000
--- a/test/CodeGen/r5.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: %clang -target armv7-none-linux-gnueabi -mcpu=cortex-r5 -emit-llvm -S %s  -o /dev/null
-
-int main() {
-  return 0;
-}
diff --git a/test/CodeGen/sanitize-init-order.cpp b/test/CodeGen/sanitize-init-order.cpp
index 3e94620..8c662db 100644
--- a/test/CodeGen/sanitize-init-order.cpp
+++ b/test/CodeGen/sanitize-init-order.cpp
@@ -1,4 +1,11 @@
-// RUN: %clang_cc1 -fsanitize=address,init-order -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fsanitize=address -emit-llvm -o - %s | FileCheck %s
+
+// Test blacklist functionality.
+// RUN: echo "global-init-src:%s" > %t-file.blacklist
+// RUN: echo "global-init-type:struct.PODWithCtorAndDtor" > %t-type.blacklist
+// RUN: %clang_cc1 -fsanitize=address -fsanitize-blacklist=%t-file.blacklist -emit-llvm -o - %s | FileCheck %s --check-prefix=BLACKLIST
+// RUN: %clang_cc1 -fsanitize=address -fsanitize-blacklist=%t-type.blacklist -emit-llvm -o - %s | FileCheck %s --check-prefix=BLACKLIST
+// REQUIRES: shell
 
 struct PODStruct {
   int x;
@@ -20,5 +27,12 @@
 
 // Check that ASan init-order checking ignores structs with trivial default
 // constructor.
-// CHECK: !llvm.asan.dynamically_initialized_globals = !{[[GLOB:![0-9]+]]}
-// CHECK: [[GLOB]] = metadata !{%struct.PODWithCtorAndDtor
+// CHECK: !llvm.asan.globals = !{![[GLOB_1:[0-9]+]], ![[GLOB_2:[0-9]+]], ![[GLOB_3:[0-9]]]}
+// CHECK: ![[GLOB_1]] = metadata !{%struct.PODStruct* {{.*}}, i1 false, i1 false}
+// CHECK: ![[GLOB_2]] = metadata !{%struct.PODWithDtor* {{.*}}, i1 false, i1 false}
+// CHECK: ![[GLOB_3]] = metadata !{%struct.PODWithCtorAndDtor* {{.*}}, i1 true, i1 false}
+
+// BLACKLIST: !llvm.asan.globals = !{![[GLOB_1:[0-9]+]], ![[GLOB_2:[0-9]+]], ![[GLOB_3:[0-9]]]}
+// BLACKLIST: ![[GLOB_1]] = metadata !{%struct.PODStruct* {{.*}}, i1 false, i1 false}
+// BLACKLIST: ![[GLOB_2]] = metadata !{%struct.PODWithDtor* {{.*}}, i1 false, i1 false}
+// BLACKLIST: ![[GLOB_3]] = metadata !{%struct.PODWithCtorAndDtor* {{.*}}, i1 false, i1 false}
diff --git a/test/CodeGen/sanitize-use-after-scope.c b/test/CodeGen/sanitize-use-after-scope.c
deleted file mode 100644
index 8f92038..0000000
--- a/test/CodeGen/sanitize-use-after-scope.c
+++ /dev/null
@@ -1,22 +0,0 @@
-// RUN: %clang_cc1 -S -emit-llvm -o - -fsanitize=address,use-after-scope %s \
-// RUN:     | FileCheck %s -check-prefix=USE-AFTER-SCOPE
-// RUN: %clang_cc1 -S -emit-llvm -o - -fsanitize=address %s \
-// RUN:     | FileCheck %s -check-prefix=ADDRESS-ONLY
-
-extern int bar(char *A, int n);
-
-// ADDRESS-ONLY-NOT: @llvm.lifetime.start
-int foo (int n) {
-  if (n) {
-    // USE-AFTER-SCOPE: @llvm.lifetime.start(i64 10, i8* {{.*}})
-    char A[10];
-    return bar(A, 1);
-    // USE-AFTER-SCOPE: @llvm.lifetime.end(i64 10, i8* {{.*}})
-  } else {
-    // USE-AFTER-SCOPE: @llvm.lifetime.start(i64 20, i8* {{.*}})
-    char A[20];
-    return bar(A, 2);
-    // USE-AFTER-SCOPE: @llvm.lifetime.end(i64 20, i8* {{.*}})
-  }
-}
-
diff --git a/test/CodeGen/sections.c b/test/CodeGen/sections.c
index 7994acf..8d93fed 100644
--- a/test/CodeGen/sections.c
+++ b/test/CodeGen/sections.c
@@ -1,28 +1,51 @@
-// REQUIRES: x86-registered-target
+// RUN: %clang_cc1 -emit-llvm -fms-extensions -xc++ -o - < %s | FileCheck %s
 
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -S -o - < %s | FileCheck %s --check-prefix=PLAIN
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -S -ffunction-sections -fno-function-sections -o - < %s | FileCheck %s --check-prefix=PLAIN
+#ifdef __cplusplus
+extern "C" {
+#endif
+#pragma const_seg(".my_const")
+#pragma bss_seg(".my_bss")
+int D = 1;
+#pragma data_seg(".data")
+int a = 1;
+#pragma data_seg(push, label, ".data2")
+extern const int b;
+const int b = 1;
+const char* s = "my string!";
+#pragma data_seg(push, ".my_seg")
+int c = 1;
+#pragma data_seg(pop, label)
+int d = 1;
+int e;
+#pragma bss_seg(".c")
+int f;
+void g(void){}
+#pragma code_seg(".my_code")
+void h(void){}
+#pragma bss_seg()
+int i;
+#pragma bss_seg(".bss1")
+#pragma bss_seg(push, test, ".bss2")
+#pragma bss_seg()
+#pragma bss_seg()
+int TEST1;
+#pragma bss_seg(pop)
+int TEST2;
+#ifdef __cplusplus
+}
+#endif
 
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -S -ffunction-sections -o - < %s | FileCheck %s --check-prefix=FUNC_SECT
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -S -fno-function-sections -ffunction-sections -o - < %s | FileCheck %s --check-prefix=FUNC_SECT
-
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -S -fdata-sections -o - < %s | FileCheck %s --check-prefix=DATA_SECT
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -S -fno-data-sections -fdata-sections -o - < %s | FileCheck %s --check-prefix=DATA_SECT
-
-const int hello = 123;
-void world() {}
-
-// PLAIN-NOT: section
-// PLAIN: world:
-// PLAIN: section .rodata,
-// PLAIN: hello:
-
-// FUNC_SECT: section .text.world,
-// FUNC_SECT: world:
-// FUNC_SECT: section .rodata,
-// FUNC_SECT: hello:
-
-// DATA_SECT-NOT: section
-// DATA_SECT: world:
-// DATA_SECT: .section .rodata.hello,
-// DATA_SECT: hello:
+//CHECK: @D = global i32 1
+//CHECK: @a = global i32 1, section ".data"
+//CHECK: @b = constant i32 1, section ".my_const"
+//CHECK: @[[MYSTR:.*]] = {{.*}} unnamed_addr constant [11 x i8] c"my string!\00"
+//CHECK: @s = global i8* getelementptr inbounds ([11 x i8]* @[[MYSTR]], i32 0, i32 0), section ".data2"
+//CHECK: @c = global i32 1, section ".my_seg"
+//CHECK: @d = global i32 1, section ".data"
+//CHECK: @e = global i32 0, section ".my_bss"
+//CHECK: @f = global i32 0, section ".c"
+//CHECK: @i = global i32 0
+//CHECK: @TEST1 = global i32 0
+//CHECK: @TEST2 = global i32 0, section ".bss1"
+//CHECK: define void @g()
+//CHECK: define void @h() {{.*}} section ".my_code"
diff --git a/test/CodeGen/sparc-target-data.c b/test/CodeGen/sparc-target-data.c
deleted file mode 100644
index bb32a21..0000000
--- a/test/CodeGen/sparc-target-data.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: %clang -target sparc-sun-solaris   -o - -emit-llvm -S %s | FileCheck %s -check-prefix=V8
-// RUN: %clang -target sparcv9-sun-solaris -o - -emit-llvm -S %s | FileCheck %s -check-prefix=V9
-
-// V8: E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32-S64
-// V9: E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32:64-S128
diff --git a/test/CodeGen/sparcv9-abi.c b/test/CodeGen/sparcv9-abi.c
index 4ba4be8..d4fff81 100644
--- a/test/CodeGen/sparcv9-abi.c
+++ b/test/CodeGen/sparcv9-abi.c
@@ -18,6 +18,9 @@
 // CHECK-LABEL: define signext i8 @f_int_4(i8 signext %x)
 char f_int_4(char x) { return x; }
 
+// CHECK-LABEL: define fp128 @f_ld(fp128 %x)
+long double f_ld(long double x) { return x; }
+
 // Small structs are passed in registers.
 struct small {
   int *a, *b;
diff --git a/test/CodeGen/sparcv9-dwarf.c b/test/CodeGen/sparcv9-dwarf.c
new file mode 100644
index 0000000..11ac28c
--- /dev/null
+++ b/test/CodeGen/sparcv9-dwarf.c
@@ -0,0 +1,99 @@
+// RUN: %clang_cc1 -triple sparcv9-unknown-unknown -emit-llvm %s -o - | FileCheck %s
+static unsigned char dwarf_reg_size_table[102+1];
+
+int test() {
+  __builtin_init_dwarf_reg_size_table(dwarf_reg_size_table);
+
+  return __builtin_dwarf_sp_column();
+}
+
+// CHECK-LABEL: define signext i32 @test()
+// CHECK:       store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 0)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 1)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 2)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 3)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 4)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 5)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 6)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 7)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 8)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 9)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 10)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 11)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 12)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 13)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 14)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 15)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 16)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 17)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 18)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 19)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 20)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 21)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 22)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 23)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 24)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 25)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 26)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 27)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 28)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 29)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 30)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 31)
+// CHECK-NEXT:  store i8 4, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 32)
+// CHECK-NEXT:  store i8 4, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 33)
+// CHECK-NEXT:  store i8 4, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 34)
+// CHECK-NEXT:  store i8 4, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 35)
+// CHECK-NEXT:  store i8 4, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 36)
+// CHECK-NEXT:  store i8 4, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 37)
+// CHECK-NEXT:  store i8 4, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 38)
+// CHECK-NEXT:  store i8 4, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 39)
+// CHECK-NEXT:  store i8 4, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 40)
+// CHECK-NEXT:  store i8 4, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 41)
+// CHECK-NEXT:  store i8 4, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 42)
+// CHECK-NEXT:  store i8 4, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 43)
+// CHECK-NEXT:  store i8 4, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 44)
+// CHECK-NEXT:  store i8 4, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 45)
+// CHECK-NEXT:  store i8 4, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 46)
+// CHECK-NEXT:  store i8 4, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 47)
+// CHECK-NEXT:  store i8 4, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 48)
+// CHECK-NEXT:  store i8 4, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 49)
+// CHECK-NEXT:  store i8 4, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 50)
+// CHECK-NEXT:  store i8 4, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 51)
+// CHECK-NEXT:  store i8 4, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 52)
+// CHECK-NEXT:  store i8 4, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 53)
+// CHECK-NEXT:  store i8 4, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 54)
+// CHECK-NEXT:  store i8 4, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 55)
+// CHECK-NEXT:  store i8 4, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 56)
+// CHECK-NEXT:  store i8 4, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 57)
+// CHECK-NEXT:  store i8 4, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 58)
+// CHECK-NEXT:  store i8 4, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 59)
+// CHECK-NEXT:  store i8 4, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 60)
+// CHECK-NEXT:  store i8 4, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 61)
+// CHECK-NEXT:  store i8 4, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 62)
+// CHECK-NEXT:  store i8 4, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 63)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 64)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 65)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 66)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 67)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 68)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 69)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 70)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 71)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 72)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 73)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 74)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 75)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 76)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 77)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 78)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 79)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 80)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 81)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 82)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 83)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 84)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 85)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 86)
+// CHECK-NEXT:  store i8 8, i8* getelementptr inbounds ([103 x i8]* @dwarf_reg_size_table, i32 0, i32 87)
+// CHECK-NEXT:  ret i32 14
diff --git a/test/CodeGen/split-stacks.c b/test/CodeGen/split-stacks.c
new file mode 100644
index 0000000..bf4cf0f
--- /dev/null
+++ b/test/CodeGen/split-stacks.c
@@ -0,0 +1,26 @@
+// RUN: %clang -target x86_64-linux-gnu -fsplit-stack -S %s -emit-llvm -o - | FileCheck -check-prefix=CHECK-SEGSTK %s
+// RUN: %clang -target x86_64-linux-gnu -S %s -emit-llvm -o - | FileCheck -check-prefix=CHECK-NOSEGSTK %s
+
+int foo() {
+  return 0;
+}
+
+__attribute__((no_split_stack))
+int nosplit() {
+  return 0;
+}
+
+int main() {
+  return foo();
+}
+
+// CHECK-SEGSTK: define i32 @foo() [[SS:#[0-9]+]] {
+// CHECK-SEGSTK: define i32 @nosplit() [[NSS:#[0-9]+]] {
+// CHECK-SEGSTK: define i32 @main() [[SS]] {
+// CHECK-SEGSTK-NOT: [[NSS]] = { {{.*}} "split-stack" {{.*}} }
+// CHECK-SEGSTK: [[SS]] = { {{.*}} "split-stack" {{.*}} }
+// CHECK-SEGSTK-NOT: [[NSS]] = { {{.*}} "split-stack" {{.*}} }
+
+// CHECK-NOSEGSTK: define i32 @foo() #0 {
+// CHECK-NOSEGSTK: define i32 @main() #0 {
+// CHECK-NOSEGSTK-NOT: #0 = { {{.*}} "split-stack" {{.*}} }
diff --git a/test/CodeGen/sret.c b/test/CodeGen/sret.c
index 828bf9b..5f0d074 100644
--- a/test/CodeGen/sret.c
+++ b/test/CodeGen/sret.c
@@ -4,6 +4,8 @@
  long a;
  long b;
  long c;
+ long d;
+ long e;
 };
  
 struct abc foo1(void);
diff --git a/test/CodeGen/sret2.c b/test/CodeGen/sret2.c
index 3757462..d103d87 100644
--- a/test/CodeGen/sret2.c
+++ b/test/CodeGen/sret2.c
@@ -4,6 +4,8 @@
  long a;
  long b;
  long c;
+ long d;
+ long e;
 };
  
 struct abc foo2(){}
diff --git a/test/CodeGen/sse-builtins-dbg.c b/test/CodeGen/sse-builtins-dbg.c
new file mode 100644
index 0000000..8190744
--- /dev/null
+++ b/test/CodeGen/sse-builtins-dbg.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -ffreestanding -triple x86_64-apple-macosx10.8.0 -target-feature +sse4.1 -g -emit-llvm %s -o - | FileCheck %s
+
+// Test that intrinsic calls inlined from _mm_* wrappers have debug metadata.
+
+#include <xmmintrin.h>
+
+__m128 test_rsqrt_ss(__m128 x) {
+  // CHECK: define {{.*}} @test_rsqrt_ss
+  // CHECK: call <4 x float> @llvm.x86.sse.rsqrt.ss({{.*}}, !dbg !{{.*}}
+  // CHECK: ret <4 x float>
+  return _mm_rsqrt_ss(x);
+}
diff --git a/test/CodeGen/sse-builtins.c b/test/CodeGen/sse-builtins.c
index 1f5cb8e..238454b 100644
--- a/test/CodeGen/sse-builtins.c
+++ b/test/CodeGen/sse-builtins.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -ffreestanding -triple x86_64-apple-macosx10.8.0 -target-feature +sse4.1 -g -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -ffreestanding -triple x86_64-apple-macosx10.8.0 -target-feature +sse4.1 -emit-llvm %s -o - | FileCheck %s
 
 #include <xmmintrin.h>
 #include <emmintrin.h>
@@ -64,7 +64,7 @@
 
 void test_store_ss(__m128 x, void* y) {
   // CHECK-LABEL: define void @test_store_ss
-  // CHECK: store {{.*}} float* {{.*}}, align 1,
+  // CHECK: store {{.*}} float* {{.*}}, align 1{{$}}
   _mm_store_ss(y, x);
 }
 
@@ -237,3 +237,21 @@
   // CHECK: insertelement <4 x i32> %{{.*}}, i32 %{{.*}}, i32 0
    _mm_insert_epi32(__a, b, 4);
 }
+
+__m128d test_blend_pd(__m128d V1, __m128d V2) {
+  // CHECK-LABEL: @test_blend_pd
+  // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x i32> <i32 2, i32 1>
+  return _mm_blend_pd(V1, V2, 1);
+}
+
+__m128 test_blend_ps(__m128 V1, __m128 V2) {
+  // CHECK-LABEL: @test_blend_ps
+  // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x i32> <i32 4, i32 1, i32 6, i32 3>
+  return _mm_blend_ps(V1, V2, 5);
+}
+
+__m128i test_blend_epi16(__m128i V1, __m128i V2) {
+  // CHECK-LABEL: @test_blend_epi16
+  // CHECK: shufflevector <8 x i16> %{{.*}}, <8 x i16> %{{.*}}, <8 x i32> <i32 0, i32 9, i32 2, i32 11, i32 4, i32 13, i32 6, i32 7>
+  return _mm_blend_epi16(V1, V2, 42);
+}
diff --git a/test/CodeGen/stack-protector.c b/test/CodeGen/stack-protector.c
index e47e5b3..2fb9b2c 100644
--- a/test/CodeGen/stack-protector.c
+++ b/test/CodeGen/stack-protector.c
@@ -2,7 +2,9 @@
 // NOSSP: define void @test1(i8* %msg) #0 {
 // RUN: %clang_cc1 -emit-llvm -o - %s -stack-protector 1 | FileCheck -check-prefix=WITHSSP %s
 // WITHSSP: define void @test1(i8* %msg) #0 {
-// RUN: %clang_cc1 -emit-llvm -o - %s -stack-protector 2 | FileCheck -check-prefix=SSPREQ %s
+// RUN: %clang_cc1 -emit-llvm -o - %s -stack-protector 2 | FileCheck -check-prefix=SSPSTRONG %s
+// SSPSTRONG: define void @test1(i8* %msg) #0 {
+// RUN: %clang_cc1 -emit-llvm -o - %s -stack-protector 3 | FileCheck -check-prefix=SSPREQ %s
 // SSPREQ: define void @test1(i8* %msg) #0 {
 
 typedef __SIZE_TYPE__ size_t;
@@ -21,4 +23,6 @@
 
 // WITHSSP: attributes #{{.*}} = { nounwind ssp{{.*}} }
 
+// SSPSTRONG: attributes #{{.*}} = { nounwind sspstrong{{.*}} }
+
 // SSPREQ: attributes #{{.*}} = { nounwind sspreq{{.*}} }
diff --git a/test/CodeGen/string-literal-short-wstring.c b/test/CodeGen/string-literal-short-wstring.c
index 88e4a1e..89aa6f7 100644
--- a/test/CodeGen/string-literal-short-wstring.c
+++ b/test/CodeGen/string-literal-short-wstring.c
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -x c++ -emit-llvm -fshort-wchar %s -o - | FileCheck %s
+// RUN: %clang_cc1 -x c++ -triple %itanium_abi_triple -emit-llvm -fshort-wchar %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=ITANIUM
+// RUN: %clang_cc1 -x c++ -triple %ms_abi_triple -emit-llvm -fshort-wchar %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=MSABI
 // Runs in c++ mode so that wchar_t is available.
 
 int main() {
@@ -6,11 +7,13 @@
   // CHECK: private unnamed_addr constant [10 x i8] c"\E1\84\A0\C8\A0\F4\82\80\B0\00", align 1
   char b[10] = "\u1120\u0220\U00102030";
 
-  // CHECK: private unnamed_addr constant [3 x i16] [i16 65, i16 66, i16 0]
+  // ITANIUM: private unnamed_addr constant [3 x i16] [i16 65, i16 66, i16 0]
+  // MSABI: linkonce_odr unnamed_addr constant [3 x i16] [i16 65, i16 66, i16 0]
   const wchar_t *foo = L"AB";
 
   // This should convert to utf16.
-  // CHECK: private unnamed_addr constant [5 x i16] [i16 4384, i16 544, i16 -9272, i16 -9168, i16 0]
+  // ITANIUM: private unnamed_addr constant [5 x i16] [i16 4384, i16 544, i16 -9272, i16 -9168, i16 0]
+  // MSABI: linkonce_odr unnamed_addr constant [5 x i16] [i16 4384, i16 544, i16 -9272, i16 -9168, i16 0]
   const wchar_t *bar = L"\u1120\u0220\U00102030";
 
 
diff --git a/test/CodeGen/struct-x86-darwin.c b/test/CodeGen/struct-x86-darwin.c
index afdcb8a..5191441 100644
--- a/test/CodeGen/struct-x86-darwin.c
+++ b/test/CodeGen/struct-x86-darwin.c
@@ -1,13 +1,13 @@
-// RUN: %clang_cc1 < %s -emit-llvm > %t1 -triple=i686-apple-darwin9
-// RUN: grep "STest1 = type { i32, \[4 x i16\], double }" %t1
-// RUN: grep "STest2 = type { i16, i16, i32, i32 }" %t1
-// RUN: grep "STest3 = type { i8, i16, i32 }" %t1
-// RUN: grep "STestB1 = type { i8, i8 }" %t1
-// RUN: grep "STestB2 = type { i8, i8, i8 }" %t1
-// RUN: grep "STestB3 = type { i8, i8 }" %t1
-// RUN: grep "STestB4 = type { i8, i8, i8, i8 }" %t1
-// RUN: grep "STestB5 = type { i8, i8, \[2 x i8\], i8, i8 }" %t1
-// RUN: grep "STestB6 = type { i8, i8, \[2 x i8\] }" %t1
+// RUN: %clang_cc1 %s -emit-llvm -triple=i686-apple-darwin9 -o - | FileCheck %s
+// CHECK: STest1 = type { i32, [4 x i16], double }
+// CHECK: STest2 = type { i16, i16, i32, i32 }
+// CHECK: STest3 = type { i8, i16, i32 }
+// CHECK: STestB1 = type { i8, i8 }
+// CHECK: STestB2 = type { i8, i8, i8 }
+// CHECK: STestB3 = type { i8, i8 }
+// CHECK: STestB4 = type { i8, i8, i8, i8 }
+// CHECK: STestB5 = type { i8, i16, i8 }
+// CHECK: STestB6 = type { i8, i8, i16 }
 // Test struct layout for x86-darwin target
 
 struct STest1 {int x; short y[4]; double z; } st1;
diff --git a/test/CodeGen/systemz-inline-asm.c b/test/CodeGen/systemz-inline-asm.c
index eb0f912..c937233 100644
--- a/test/CodeGen/systemz-inline-asm.c
+++ b/test/CodeGen/systemz-inline-asm.c
@@ -123,7 +123,7 @@
 long double test_f128(long double f, long double g) {
   asm("axbr %0, %2" : "=f" (f) : "0" (f), "f" (g));
   return f;
-// CHECK: define void @test_f128(fp128* noalias nocapture sret [[DEST:%.*]], fp128* byval nocapture readonly, fp128* byval nocapture readonly)
+// CHECK: define void @test_f128(fp128* noalias nocapture sret [[DEST:%.*]], fp128* nocapture readonly, fp128* nocapture readonly)
 // CHECK: %f = load fp128* %0
 // CHECK: %g = load fp128* %1
 // CHECK: [[RESULT:%.*]] = tail call fp128 asm "axbr $0, $2", "=f,0,f"(fp128 %f, fp128 %g)
diff --git a/test/CodeGen/target-data.c b/test/CodeGen/target-data.c
index fc8f758..21ea625 100644
--- a/test/CodeGen/target-data.c
+++ b/test/CodeGen/target-data.c
@@ -1,6 +1,167 @@
-// RUN: %clang_cc1 -triple i686-unknown-unknown -emit-llvm -o %t %s
-// RUN: grep 'target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128"' %t
-// RUN: %clang_cc1 -triple i686-apple-darwin9 -emit-llvm -o %t %s
-// RUN: grep 'target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32-S128"' %t
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o %t %s
-// RUN: grep 'target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"' %t
+// RUN: %clang_cc1 -triple i686-unknown-unknown -emit-llvm -o - %s | \
+// RUN:     FileCheck --check-prefix=I686-UNKNOWN %s
+// I686-UNKNOWN: target datalayout = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128"
+
+// RUN: %clang_cc1 -triple i686-apple-darwin9 -emit-llvm -o - %s | \
+// RUN:     FileCheck --check-prefix=I686-DARWIN %s
+// I686-DARWIN: target datalayout = "e-m:o-p:32:32-f64:32:64-f80:128-n8:16:32-S128"
+
+// RUN: %clang_cc1 -triple i686-unknown-win32 -emit-llvm -o - %s | \
+// RUN:     FileCheck --check-prefix=I686-WIN32 %s
+// I686-WIN32: target datalayout = "e-m:w-p:32:32-i64:64-f80:32-n8:16:32-S32"
+
+// RUN: %clang_cc1 -triple i686-unknown-cygwin -emit-llvm -o - %s | \
+// RUN:     FileCheck --check-prefix=I686-CYGWIN %s
+// I686-CYGWIN: target datalayout = "e-m:w-p:32:32-i64:64-f80:32-n8:16:32-S32"
+
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | \
+// RUN:     FileCheck --check-prefix=X86_64 %s
+// X86_64: target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+// RUN: %clang_cc1 -triple xcore-unknown-unknown -emit-llvm -o - %s | \
+// RUN:     FileCheck --check-prefix=XCORE %s
+// XCORE: target datalayout = "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:32-f64:32-a:0:32-n32"
+
+// RUN: %clang_cc1 -triple sparc-sun-solaris -emit-llvm -o - %s | \
+// RUN:     FileCheck %s --check-prefix=SPARC-V8
+// SPARC-V8: target datalayout = "E-m:e-p:32:32-i64:64-f128:64-n32-S64"
+
+// RUN: %clang_cc1 -triple sparcv9-sun-solaris -emit-llvm -o - %s | \
+// RUN: FileCheck %s --check-prefix=SPARC-V9
+// SPARC-V9: target datalayout = "E-m:e-i64:64-n32:64-S128"
+
+// RUN: %clang_cc1 -triple mipsel-linux-gnu -o - -emit-llvm %s |     \
+// RUN: FileCheck %s -check-prefix=MIPS-32EL
+// MIPS-32EL: target datalayout = "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64"
+
+// RUN: %clang_cc1 -triple mips-linux-gnu -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=MIPS-32EB
+// MIPS-32EB: target datalayout = "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64"
+
+// RUN: %clang_cc1 -triple mips64el-linux-gnu -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=MIPS-64EL
+// MIPS-64EL: target datalayout = "e-m:m-i8:8:32-i16:16:32-i64:64-n32:64-S128"
+
+// RUN: %clang_cc1 -triple mips64el-linux-gnu -o - -emit-llvm -target-abi n32 \
+// RUN: %s | FileCheck %s -check-prefix=MIPS-64EL-N32
+// MIPS-64EL-N32: target datalayout = "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32:64-S128"
+
+// RUN: %clang_cc1 -triple mips64-linux-gnu -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=MIPS-64EB
+// MIPS-64EB: target datalayout = "E-m:m-i8:8:32-i16:16:32-i64:64-n32:64-S128"
+
+// RUN: %clang_cc1 -triple mips64-linux-gnu -o - -emit-llvm %s -target-abi n32 \
+// RUN: | FileCheck %s -check-prefix=MIPS-64EB-N32
+// MIPS-64EB-N32: target datalayout = "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32:64-S128"
+
+// RUN: %clang_cc1 -triple powerpc64-lv2 -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=PS3
+// PS3: target datalayout = "E-m:e-p:32:32-i64:64-n32:64"
+
+// RUN: %clang_cc1 -triple i686-nacl -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=I686-NACL
+// I686-NACL: target datalayout = "e-m:e-p:32:32-i64:64-f80:32-n8:16:32-S128"
+
+// RUN: %clang_cc1 -triple x86_64-nacl -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=X86_64-NACL
+// X86_64-NACL: target datalayout = "e-m:e-p:32:32-i64:64-f80:128-n8:16:32:64-S128"
+
+// RUN: %clang_cc1 -triple arm-nacl-gnueabi -o - -emit-llvm %s \
+// RUN:   -target-abi aapcs-linux | FileCheck %s -check-prefix=ARM-NACL
+// ARM-NACL: target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S128"
+
+// RUN: %clang_cc1 -triple mipsel-nacl -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=MIPS-NACL
+// MIPS-NACL: target datalayout = "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64"
+
+// RUN: %clang_cc1 -triple le32-nacl -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=LE32-NACL
+// LE32-NACL: target datalayout = "e-p:32:32-i64:64"
+
+// RUN: %clang_cc1 -triple powerpc-unknown -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=PPC
+// PPC: target datalayout = "E-m:e-p:32:32-i64:64-n32"
+
+// RUN: %clang_cc1 -triple powerpc64-freebsd -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=PPC64-FREEBSD
+// PPC64-FREEBSD: target datalayout = "E-m:e-i64:64-n32:64"
+
+// RUN: %clang_cc1 -triple powerpc64-linux -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=PPC64-LINUX
+// PPC64-LINUX: target datalayout = "E-m:e-i64:64-n32:64"
+
+// RUN: %clang_cc1 -triple powerpc64le-linux -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=PPC64LE-LINUX
+// PPC64LE-LINUX: target datalayout = "e-m:e-i64:64-n32:64"
+
+// RUN: %clang_cc1 -triple powerpc-darwin -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=PPC32-DARWIN
+// PPC32-DARWIN: target datalayout = "E-m:o-p:32:32-f64:32:64-n32"
+
+// RUN: %clang_cc1 -triple powerpc64-darwin -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=PPC64-DARWIN
+// PPC64-DARWIN: target datalayout = "E-m:o-i64:64-n32:64"
+
+// RUN: %clang_cc1 -triple nvptx-unknown -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=NVPTX
+// NVPTX: target datalayout = "e-p:32:32-i64:64-v16:16-v32:32-n16:32:64"
+
+// RUN: %clang_cc1 -triple nvptx64-unknown -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=NVPTX64
+// NVPTX64: target datalayout = "e-i64:64-v16:16-v32:32-n16:32:64"
+
+// RUN: %clang_cc1 -triple r600-unknown -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=R600
+// R600: target datalayout = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64"
+
+// RUN: %clang_cc1 -triple r600-unknown -target-cpu cayman -o - -emit-llvm %s \
+// RUN: | FileCheck %s -check-prefix=R600D
+// R600D: target datalayout = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64"
+
+// RUN: %clang_cc1 -triple r600-unknown -target-cpu hawaii -o - -emit-llvm %s \
+// RUN: | FileCheck %s -check-prefix=R600SI
+// R600SI: target datalayout = "e-p:32:32-p1:64:64-p2:64:64-p3:32:32-p4:64:64-p5:32:32-p24:64:64-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64"
+
+// RUN: %clang_cc1 -triple arm64-unknown -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=AARCH64
+// AARCH64: target datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"
+
+// RUN: %clang_cc1 -triple thumb-unknown-gnueabi -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=THUMB
+// THUMB: target datalayout = "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:64-v128:64:128-a:0:32-n32-S64"
+
+// RUN: %clang_cc1 -triple arm-unknown-gnueabi -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=ARM
+// ARM: target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+// RUN: %clang_cc1 -triple thumb-unknown -o - -emit-llvm -target-abi apcs-gnu \
+// RUN: %s | FileCheck %s -check-prefix=THUMB-GNU
+// THUMB-GNU: target datalayout = "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
+
+// RUN: %clang_cc1 -triple arm-unknown -o - -emit-llvm -target-abi apcs-gnu \
+// RUN: %s | FileCheck %s -check-prefix=ARM-GNU
+// ARM-GNU: target datalayout = "e-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
+
+// RUN: %clang_cc1 -triple hexagon-unknown -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=HEXAGON
+// HEXAGON: target datalayout = "e-m:e-p:32:32-i1:32-i64:64-a:0-n32"
+
+// RUN: %clang_cc1 -triple s390x-unknown -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=SYSTEMZ
+// SYSTEMZ: target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64"
+
+// RUN: %clang_cc1 -triple msp430-unknown -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=MSP430
+// MSP430: target datalayout = "e-m:e-p:16:16-i32:16:32-n8:16"
+
+// RUN: %clang_cc1 -triple tce-unknown -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=TCE
+// TCE: target datalayout = "E-p:32:32-i8:8:32-i16:16:32-i64:32-f64:32-v64:32-v128:32-a:0:32-n32"
+
+// RUN: %clang_cc1 -triple spir-unknown -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=SPIR
+// SPIR: target datalayout = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
+
+// RUN: %clang_cc1 -triple spir64-unknown -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=SPIR64
+// SPIR64: target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
diff --git a/test/CodeGen/tbaa-for-vptr.cpp b/test/CodeGen/tbaa-for-vptr.cpp
index 7ba058b..ded574e 100644
--- a/test/CodeGen/tbaa-for-vptr.cpp
+++ b/test/CodeGen/tbaa-for-vptr.cpp
@@ -1,12 +1,12 @@
-// RUN: %clang_cc1 -emit-llvm -o - -fsanitize=thread %s | FileCheck %s
-// RUN: %clang_cc1 -emit-llvm -o - -O1 %s | FileCheck %s
-// RUN: %clang_cc1 -emit-llvm -o - -O1  -relaxed-aliasing -fsanitize=thread %s | FileCheck %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - -fsanitize=thread %s | FileCheck %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - -O1 %s | FileCheck %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - -O1  -relaxed-aliasing -fsanitize=thread %s | FileCheck %s
 //
-// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s --check-prefix=NOTBAA
-// RUN: %clang_cc1 -emit-llvm -o - -O2  -relaxed-aliasing %s | FileCheck %s --check-prefix=NOTBAA
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s --check-prefix=NOTBAA
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - -O2  -relaxed-aliasing %s | FileCheck %s --check-prefix=NOTBAA
 //
 // Check that we generate TBAA for vtable pointer loads and stores.
-// When -fthread-sanitizer is used TBAA should be generated at all opt levels
+// When -fsanitize=thread is used TBAA should be generated at all opt levels
 // even if -relaxed-aliasing is present.
 struct A {
   virtual int foo() const ;
@@ -17,12 +17,19 @@
   new A;
 }
 
-void CallFoo(A *a) {
+void CallFoo(A *a, int (A::*fp)() const) {
   a->foo();
+  (a->*fp)();
 }
 
+// CHECK-LABEL: @_Z7CallFoo
 // CHECK: %{{.*}} = load {{.*}} !tbaa ![[NUM:[0-9]+]]
+// CHECK: br i1
+// CHECK: load {{.*}}, !tbaa ![[NUM]]
+//
+// CHECK-LABEL: @_ZN1AC2Ev
 // CHECK: store {{.*}} !tbaa ![[NUM]]
+//
 // CHECK: [[NUM]] = metadata !{metadata [[TYPE:!.*]], metadata [[TYPE]], i64 0}
 // CHECK: [[TYPE]] = metadata !{metadata !"vtable pointer", metadata !{{.*}}
 // NOTBAA-NOT: = metadata !{metadata !"Simple C/C++ TBAA"}
diff --git a/test/CodeGen/tbaa-ms-abi.cpp b/test/CodeGen/tbaa-ms-abi.cpp
new file mode 100644
index 0000000..2a9e47e
--- /dev/null
+++ b/test/CodeGen/tbaa-ms-abi.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -triple i686-pc-win32 -disable-llvm-optzns -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.
+
+struct StructA {
+  int a;
+};
+
+struct StructB : virtual StructA {
+  StructB();
+};
+
+StructB::StructB() {
+  a = 42;
+// CHECK: store i32 42, i32* {{.*}}, !tbaa [[TAG_A_i32:!.*]]
+}
+
+// CHECK: [[TYPE_INT:!.*]] = metadata !{metadata !"int", metadata [[TYPE_CHAR:!.*]], i64 0}
+// CHECK: [[TYPE_CHAR]] = metadata !{metadata !"omnipotent char", metadata
+// CHECK: [[TAG_A_i32]] = metadata !{metadata [[TYPE_A:!.*]], metadata [[TYPE_INT]], i64 0}
+// CHECK: [[TYPE_A]] = metadata !{metadata !"?AUStructA@@", metadata [[TYPE_INT]], i64 0}
diff --git a/test/CodeGen/tbaa-struct.cpp b/test/CodeGen/tbaa-struct.cpp
index f8bd124..71d3ed1 100644
--- a/test/CodeGen/tbaa-struct.cpp
+++ b/test/CodeGen/tbaa-struct.cpp
@@ -12,8 +12,7 @@
   *a = *b;
 }
 
-// CHECK: target datalayout = "{{.*}}p:[[P:64|32]]
-// CHECK: call void @llvm.memcpy.p0i8.p0i8.i[[P]](i8* %{{.*}}, i8* %{{.*}}, i[[P]] 16, i32 4, i1 false), !tbaa.struct [[TS:!.*]]
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %{{.*}}, i8* %{{.*}}, i64 16, i32 4, i1 false), !tbaa.struct [[TS:!.*]]
 
 struct B {
   char c1;
@@ -25,7 +24,7 @@
   *a = *b;
 }
 
-// CHECK: call void @llvm.memcpy.p0i8.p0i8.i[[P]](i8* %{{.*}}, i8* %{{.*}}, i[[P]] 24, i32 4, i1 false), !tbaa.struct [[TS2:!.*]]
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %{{.*}}, i8* %{{.*}}, i64 24, i32 4, i1 false), !tbaa.struct [[TS2:!.*]]
 
 typedef _Complex int T2;
 typedef _Complex char T5;
@@ -37,7 +36,7 @@
   *a = *b;
 }
 
-// CHECK: call void @llvm.memcpy.p0i8.p0i8.i[[P]](i8* %{{.*}}, i8* %{{.*}}, i[[P]] 12, i32 4, i1 false), !tbaa.struct [[TS3:!.*]]
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %{{.*}}, i8* %{{.*}}, i64 12, i32 4, i1 false), !tbaa.struct [[TS3:!.*]]
 
 // Make sure that zero-length bitfield works.
 #define ATTR __attribute__ ((ms_struct))
@@ -50,7 +49,7 @@
 void copy4(struct five *a, struct five *b) {
   *a = *b;
 }
-// CHECK: call void @llvm.memcpy.p0i8.p0i8.i[[P]](i8* %{{.*}}, i8* %{{.*}}, i[[P]] 3, i32 1, i1 false), !tbaa.struct [[TS4:!.*]]
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %{{.*}}, i8* %{{.*}}, i64 3, i32 1, i1 false), !tbaa.struct [[TS4:!.*]]
 
 struct six {
   char a;
@@ -61,7 +60,7 @@
 void copy5(struct six *a, struct six *b) {
   *a = *b;
 }
-// CHECK: call void @llvm.memcpy.p0i8.p0i8.i[[P]](i8* %{{.*}}, i8* %{{.*}}, i[[P]] 6, i32 1, i1 false), !tbaa.struct [[TS5:!.*]]
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %{{.*}}, i8* %{{.*}}, i64 6, i32 1, i1 false), !tbaa.struct [[TS5:!.*]]
 
 // CHECK: [[TS]] = metadata !{i64 0, i64 2, metadata !{{.*}}, i64 4, i64 4, metadata !{{.*}}, i64 8, i64 1, metadata !{{.*}}, i64 12, i64 4, metadata !{{.*}}}
 // CHECK: [[CHAR:!.*]] = metadata !{metadata !"omnipotent char", metadata !{{.*}}}
diff --git a/test/CodeGen/ubsan-type-blacklist.cpp b/test/CodeGen/ubsan-type-blacklist.cpp
new file mode 100644
index 0000000..7dc6fe1
--- /dev/null
+++ b/test/CodeGen/ubsan-type-blacklist.cpp
@@ -0,0 +1,25 @@
+// Verify ubsan vptr does not check down-casts on blacklisted types.
+// RUN: echo "type:_ZTI3Foo" > %t-type.blacklist
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsanitize=vptr -emit-llvm %s -o - | FileCheck %s --check-prefix=DEFAULT
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsanitize=vptr -fsanitize-blacklist=%t-type.blacklist -emit-llvm %s -o - | FileCheck %s --check-prefix=TYPE
+
+// REQUIRES: shell
+
+class Bar {
+public:
+  virtual ~Bar() {}
+};
+class Foo : public Bar {};
+
+Bar bar;
+
+// DEFAULT: @_Z7checkmev
+// TYPE: @_Z7checkmev
+void checkme() {
+// DEFAULT: call void @__ubsan_handle_dynamic_type_cache_miss({{.*}} (%class.Bar* @bar to
+// TYPE-NOT: @__ubsan_handle_dynamic_type_cache_miss
+  Foo* foo = static_cast<Foo*>(&bar); // down-casting
+// DEFAULT: ret void
+// TYPE: ret void
+  return;
+}
diff --git a/test/CodeGen/union.c b/test/CodeGen/union.c
index 5c89e2d..7302182 100644
--- a/test/CodeGen/union.c
+++ b/test/CodeGen/union.c
@@ -44,3 +44,16 @@
 T0 t0;
 
 union { int large_bitfield: 31; char c } u2;
+
+struct dt_t_s {
+  union {
+    long long u : 56;
+  } __attribute__((packed));
+};
+struct {
+  struct {
+    struct {
+      struct dt_t_s t;
+    };
+  };
+} a;
diff --git a/test/CodeGen/utf16-cfstrings.c b/test/CodeGen/utf16-cfstrings.c
index d4f214b..dbe9bda 100644
--- a/test/CodeGen/utf16-cfstrings.c
+++ b/test/CodeGen/utf16-cfstrings.c
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm %s -o - | FileCheck %s
 // <rdar://problem/10655949>
 
-// CHECK: @.str = internal unnamed_addr constant [9 x i16] [i16 252, i16 98, i16 101, i16 114, i16 104, i16 117, i16 110, i16 100, i16 0], align 2
+// CHECK: @.str = private unnamed_addr constant [9 x i16] [i16 252, i16 98, i16 101, i16 114, i16 104, i16 117, i16 110, i16 100, i16 0], section "__TEXT,__ustring", align 2
 
 #define CFSTR __builtin___CFStringMakeConstantString
 
diff --git a/test/CodeGen/varargs.c b/test/CodeGen/varargs.c
index b6973d8..3e2cce0 100644
--- a/test/CodeGen/varargs.c
+++ b/test/CodeGen/varargs.c
@@ -1,5 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
-
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -o - %s | FileCheck %s
 
 // PR6433 - Don't crash on va_arg(typedef).
 typedef double gdouble;
@@ -15,3 +14,10 @@
   // CHECK-NOT: llvm.trap
   vararg(0, focus_changed_cb);
 }
+
+void vla(int n, ...)
+{
+  __builtin_va_list ap;
+  void *p;
+  p = __builtin_va_arg(ap, typeof (int (*)[++n])); // CHECK: add nsw i32 {{.*}}, 1
+}
diff --git a/test/CodeGen/variadic-gpfp-x86.c b/test/CodeGen/variadic-gpfp-x86.c
new file mode 100644
index 0000000..735c4be
--- /dev/null
+++ b/test/CodeGen/variadic-gpfp-x86.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o - | FileCheck %s
+
+struct Bar {
+ float f1;
+ float f2;
+ unsigned u;
+};
+
+struct Bar foo(__builtin_va_list ap) {
+  return __builtin_va_arg(ap, struct Bar);
+// CHECK: [[FPOP:%.*]] = getelementptr inbounds %struct.__va_list_tag* {{.*}}, i32 0, i32 1
+// CHECK: [[FPO:%.*]] = load i32* [[FPOP]]
+// CHECK: [[FPVEC:%.*]] = getelementptr i8* {{.*}}, i32 [[FPO]]
+// CHECK: bitcast i8* [[FPVEC]] to <2 x float>*
+}
diff --git a/test/CodeGen/vla.c b/test/CodeGen/vla.c
index 1757ef7..e6cdd5d 100644
--- a/test/CodeGen/vla.c
+++ b/test/CodeGen/vla.c
@@ -195,3 +195,12 @@
   // CHECK-LABEL: define void @test7(
   // CHECK: call i32 @b(i8* null)
 }
+
+// Make sure we emit dereferenceable or nonnull when the static keyword is
+// provided.
+void test8(int a[static 3]) { }
+// CHECK: define void @test8(i32* dereferenceable(12) %a)
+
+void test9(int n, int a[static n]) { }
+// CHECK: define void @test9(i32 %n, i32* nonnull %a)
+
diff --git a/test/CodeGen/volatile-complex.c b/test/CodeGen/volatile-complex.c
index 71e5db6..fd5e52b 100644
--- a/test/CodeGen/volatile-complex.c
+++ b/test/CodeGen/volatile-complex.c
@@ -5,16 +5,14 @@
 //
 // This test assumes that floats are 32-bit aligned and doubles are
 // 64-bit aligned, and uses x86-64 as a target that should have this
-// datalayout.
-
-// CHECK: target datalayout = "{{.*}}f32:32:32-f64:64:64{{.*}}"
+// property.
 
 volatile _Complex float cf;
 volatile _Complex double cd;
 volatile _Complex float cf32 __attribute__((aligned(32)));
 volatile _Complex double cd32 __attribute__((aligned(32)));
 
-// CHECK-LABEL-LABEL: define void @test_cf()
+// CHECK-LABEL: define void @test_cf()
 void test_cf() {
   // CHECK:      load volatile float* getelementptr inbounds ({ float, float }* @cf, i32 0, i32 0), align 4
   // CHECK-NEXT: load volatile float* getelementptr inbounds ({ float, float }* @cf, i32 0, i32 1), align 4
@@ -27,7 +25,7 @@
   // CHECK-NEXT: ret void
 }
 
-// CHECK-LABEL-LABEL: define void @test_cd()
+// CHECK-LABEL: define void @test_cd()
 void test_cd() {
   // CHECK:      load volatile double* getelementptr inbounds ({ double, double }* @cd, i32 0, i32 0), align 8
   // CHECK-NEXT: load volatile double* getelementptr inbounds ({ double, double }* @cd, i32 0, i32 1), align 8
@@ -40,7 +38,7 @@
   // CHECK-NEXT: ret void
 }
 
-// CHECK-LABEL-LABEL: define void @test_cf32()
+// CHECK-LABEL: define void @test_cf32()
 void test_cf32() {
   // CHECK:      load volatile float* getelementptr inbounds ({ float, float }* @cf32, i32 0, i32 0), align 32
   // CHECK-NEXT: load volatile float* getelementptr inbounds ({ float, float }* @cf32, i32 0, i32 1), align 4
@@ -53,7 +51,7 @@
   // CHECK-NEXT: ret void
 }
 
-// CHECK-LABEL-LABEL: define void @test_cd32()
+// CHECK-LABEL: define void @test_cd32()
 void test_cd32() {
   // CHECK:      load volatile double* getelementptr inbounds ({ double, double }* @cd32, i32 0, i32 0), align 32
   // CHECK-NEXT: load volatile double* getelementptr inbounds ({ double, double }* @cd32, i32 0, i32 1), align 8
diff --git a/test/CodeGen/volatile.c b/test/CodeGen/volatile.c
index 0dcdc15..3e891aa 100644
--- a/test/CodeGen/volatile.c
+++ b/test/CodeGen/volatile.c
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -emit-llvm < %s | FileCheck %s
+// RUN: %clang_cc1 -triple=%itanium_abi_triple -emit-llvm < %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-IT
+// RUN: %clang_cc1 -triple=%ms_abi_triple -emit-llvm < %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-MS
 
 int S;
 volatile int vS;
@@ -83,10 +84,12 @@
 // CHECK: load volatile i32* getelementptr {{.*}} @vF3
 // CHECK: store i32 {{.*}}, i32* [[I]]
   i=BF.x;
-// CHECK: load i8* getelementptr {{.*}} @BF
+// CHECK-IT: load i8* getelementptr {{.*}} @BF
+// CHECK-MS: load i32* getelementptr {{.*}} @BF
 // CHECK: store i32 {{.*}}, i32* [[I]]
   i=vBF.x;
-// CHECK: load volatile i8* getelementptr {{.*}} @vBF
+// CHECK-IT: load volatile i8* getelementptr {{.*}} @vBF
+// CHECK-MS: load volatile i32* getelementptr {{.*}} @vBF
 // CHECK: store i32 {{.*}}, i32* [[I]]
   i=V[3];
 // CHECK: load <4 x i32>* @V
@@ -154,12 +157,16 @@
 // CHECK: store volatile i32 {{.*}}, i32* getelementptr {{.*}} @vF3
   BF.x=i;
 // CHECK: load i32* [[I]]
-// CHECK: load i8* getelementptr {{.*}} @BF
-// CHECK: store i8 {{.*}}, i8* getelementptr {{.*}} @BF
+// CHECK-IT: load i8* getelementptr {{.*}} @BF
+// CHECK-MS: load i32* getelementptr {{.*}} @BF
+// CHECK-IT: store i8 {{.*}}, i8* getelementptr {{.*}} @BF
+// CHECK-MS: store i32 {{.*}}, i32* getelementptr {{.*}} @BF
   vBF.x=i;
 // CHECK: load i32* [[I]]
-// CHECK: load volatile i8* getelementptr {{.*}} @vBF
-// CHECK: store volatile i8 {{.*}}, i8* getelementptr {{.*}} @vBF
+// CHECK-IT: load volatile i8* getelementptr {{.*}} @vBF
+// CHECK-MS: load volatile i32* getelementptr {{.*}} @vBF
+// CHECK-IT: store volatile i8 {{.*}}, i8* getelementptr {{.*}} @vBF
+// CHECK-MS: store volatile i32 {{.*}}, i32* getelementptr {{.*}} @vBF
   V[3]=i;
 // CHECK: load i32* [[I]]
 // CHECK: load <4 x i32>* @V
diff --git a/test/CodeGen/wchar-const.c b/test/CodeGen/wchar-const.c
index 2e9af53..34da249 100644
--- a/test/CodeGen/wchar-const.c
+++ b/test/CodeGen/wchar-const.c
@@ -15,7 +15,7 @@
 
 
 // CHECK-DAR: private unnamed_addr constant [18 x i32] [i32 84,
-// CHECK-WIN: private unnamed_addr constant [18 x i16] [i16 84,
+// CHECK-WIN: linkonce_odr unnamed_addr constant [18 x i16] [i16 84,
 extern void foo(const wchar_t* p);
 int main (int argc, const char * argv[])
 {
diff --git a/test/CodeGen/windows-itanium.c b/test/CodeGen/windows-itanium.c
new file mode 100644
index 0000000..7f0e7b1
--- /dev/null
+++ b/test/CodeGen/windows-itanium.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -triple i686-windows-itanium -emit-llvm %s -o - \
+// RUN:    | FileCheck %s -check-prefix CHECK-C -check-prefix CHECK
+
+// RUN: %clang_cc1 -triple i686-windows-itanium -emit-llvm -x c++ %s -o - \
+// RUN:    | FileCheck %s -check-prefix CHECK-CXX -check-prefix CHECK
+
+int function() {
+  return 32;
+}
+
+// CHECK-C: define i32 @function() {{.*}} {
+// CHECK-CXX: define i32 @_Z8functionv() {{.*}} {
+// CHECK:   ret i32 32
+// CHECK: }
+
diff --git a/test/CodeGen/windows-on-arm-dllimport-dllexport.c b/test/CodeGen/windows-on-arm-dllimport-dllexport.c
new file mode 100644
index 0000000..897d06a
--- /dev/null
+++ b/test/CodeGen/windows-on-arm-dllimport-dllexport.c
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -Werror -triple thumbv7-windows-itanium -mfloat-abi hard -emit-llvm %s -o - | FileCheck %s
+
+__declspec(dllexport) int export_int;
+
+__declspec(dllimport) int import_int;
+
+__declspec(dllexport) void export_declared_function();
+
+__declspec(dllexport) void export_implemented_function() {
+}
+
+__declspec(dllimport) void import_function(int);
+
+void call_imported_function() {
+  export_declared_function();
+  return import_function(import_int);
+}
+
+// CHECK: @import_int = external dllimport global i32
+// CHECK: @export_int = common dllexport global i32 0, align 4
+
+// CHECK: define dllexport arm_aapcs_vfpcc void @export_implemented_function()
+
+// CHECK: declare dllimport arm_aapcs_vfpcc void @import_function(i32)
+
diff --git a/test/CodeGen/x86-64-inline-asm.c b/test/CodeGen/x86-64-inline-asm.c
new file mode 100644
index 0000000..bb46eda
--- /dev/null
+++ b/test/CodeGen/x86-64-inline-asm.c
@@ -0,0 +1,17 @@
+// REQUIRES: x86-registered-target
+// RUN: %clang_cc1 -triple x86_64 %s -S -o /dev/null -DWARN -verify
+// RUN: %clang_cc1 -triple x86_64 %s -S -o /dev/null -Werror -verify
+void f() {
+  asm("movaps %xmm3, (%esi, 2)");
+// expected-note@1 {{instantiated into assembly here}}
+#ifdef WARN
+// expected-warning@-3 {{scale factor without index register is ignored}}
+#else
+// expected-error@-5 {{scale factor without index register is ignored}}
+#endif
+}
+
+static unsigned var[1] = {};
+void g(void) { asm volatile("movd %%xmm0, %0"
+                            :
+                            : "m"(var)); }
diff --git a/test/CodeGen/x86_64-atomic-128.c b/test/CodeGen/x86_64-atomic-128.c
new file mode 100644
index 0000000..2069e45
--- /dev/null
+++ b/test/CodeGen/x86_64-atomic-128.c
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -target-cpu core2 %s -S -emit-llvm -o - | FileCheck %s
+
+// All atomics up to 16 bytes should be emitted inline on x86_64. The
+// backend can reform __sync_whatever calls if necessary (e.g. the CPU
+// doesn't have cmpxchg16b).
+
+__int128 test_sync_call(__int128 *addr, __int128 val) {
+  // CHECK-LABEL: @test_sync_call
+  // CHECK: atomicrmw add i128
+  return __sync_fetch_and_add(addr, val);
+}
+
+__int128 test_c11_call(_Atomic __int128 *addr, __int128 val) {
+  // CHECK-LABEL: @test_c11_call
+  // CHECK: atomicrmw sub
+  return __c11_atomic_fetch_sub(addr, val, 0);
+}
+
+__int128 test_atomic_call(__int128 *addr, __int128 val) {
+  // CHECK-LABEL: @test_atomic_call
+  // CHECK: atomicrmw or
+  return __atomic_fetch_or(addr, val, 0);
+}
+
+__int128 test_expression(_Atomic __int128 *addr) {
+  // CHECK-LABEL: @test_expression
+  // CHECK: atomicrmw and
+  *addr &= 1;
+}
diff --git a/test/CodeGen/xcore-abi.c b/test/CodeGen/xcore-abi.c
index 10881de..6dbc44b 100644
--- a/test/CodeGen/xcore-abi.c
+++ b/test/CodeGen/xcore-abi.c
@@ -1,3 +1,4 @@
+// REQUIRES: xcore-registered-target
 // RUN: %clang_cc1 -triple xcore -verify %s
 _Static_assert(sizeof(long long) == 8, "sizeof long long is wrong");
 _Static_assert(_Alignof(long long) == 4, "alignof long long is wrong");
@@ -7,11 +8,15 @@
 
 // RUN: %clang_cc1 -triple xcore-unknown-unknown -fno-signed-char -fno-common -emit-llvm -o - %s | FileCheck %s
 
-// CHECK: target datalayout = "e-p:32:32:32-a0:0:32-n32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f16:16:32-f32:32:32-f64:32:32"
 // CHECK: target triple = "xcore-unknown-unknown"
 
+// CHECK: @cgx = external constant i32, section ".cp.rodata"
+extern const int cgx;
+int fcgx() { return cgx;}
 // CHECK: @g1 = global i32 0, align 4
 int g1;
+// CHECK: @cg1 = constant i32 0, section ".cp.rodata", align 4
+const int cg1;
 
 #include <stdarg.h>
 struct x { int a[5]; };
@@ -66,7 +71,7 @@
   // CHECK:[[V2:%[a-z0-9]+]] = bitcast i64* [[V]] to i8*
   // CHECK: call void @f(i8* [[V2]])
 
-  struct x v5 = va_arg (ap, struct x);  // typical agregate type
+  struct x v5 = va_arg (ap, struct x);  // typical aggregate type
   f(&v5);
   // CHECK: [[I:%[a-z0-9]+]] = load i8** [[AP]]
   // CHECK: [[I2:%[a-z0-9]+]] = bitcast i8* [[I]] to %struct.x**
@@ -79,7 +84,7 @@
   // CHECK: [[V2:%[a-z0-9]+]] = bitcast %struct.x* [[V]] to i8*
   // CHECK: call void @f(i8* [[V2]])
 
-  int* v6 = va_arg (ap, int[4]);  // an unusual agregate type
+  int* v6 = va_arg (ap, int[4]);  // an unusual aggregate type
   f(v6);
   // CHECK: [[I:%[a-z0-9]+]] = load i8** [[AP]]
   // CHECK: [[I2:%[a-z0-9]+]] = bitcast i8* [[I]] to [4 x i32]**
@@ -113,10 +118,18 @@
   // CHECK: call i32 @llvm.xcore.getps(i32 {{%[a-z0-9]+}})
   // CHECK: call i32 @llvm.xcore.bitrev(i32 {{%[a-z0-9]+}})
   // CHECK: call void @llvm.xcore.setps(i32 {{%[a-z0-9]+}}, i32 {{%[a-z0-9]+}})
-  int i = __builtin_getid();
-  unsigned int ui = __builtin_getps(i);
+  volatile int i = __builtin_getid();
+  volatile unsigned int ui = __builtin_getps(i);
   ui = __builtin_bitrev(ui);
   __builtin_setps(i,ui);
+
+  // CHECK: store volatile i32 0, i32* {{%[a-z0-9]+}}, align 4
+  // CHECK: store volatile i32 1, i32* {{%[a-z0-9]+}}, align 4
+  // CHECK: store volatile i32 -1, i32* {{%[a-z0-9]+}}, align 4
+  volatile int res;
+  res = __builtin_eh_return_data_regno(0);
+  res = __builtin_eh_return_data_regno(1);
+  res = __builtin_eh_return_data_regno(2);
 }
 
 // CHECK-LABEL: define zeroext i8 @testchar()
diff --git a/test/CodeGen/xcore-abi.cpp b/test/CodeGen/xcore-abi.cpp
new file mode 100644
index 0000000..fbf31ff
--- /dev/null
+++ b/test/CodeGen/xcore-abi.cpp
@@ -0,0 +1,27 @@
+// REQUIRES: xcore-registered-target
+
+// RUN: %clang_cc1 -triple xcore-unknown-unknown -fno-signed-char -fno-common -emit-llvm -o - -x c++ %s | FileCheck %s
+
+// CHECK: target triple = "xcore-unknown-unknown"
+
+
+// C++ constants are not placed into the ".cp.rodata" section.
+// CHECK: @cgx = external constant i32
+extern const int cgx;
+int fcgx() { return cgx;}
+// CHECK: @g1 = global i32 0, align 4
+int g1;
+// CHECK: @cg1 = constant i32 0, align 4
+extern const int cg1 = 0;
+
+// Regression test for a bug in lib/CodeGen/CodeGenModule.cpp which called
+// getLanguageLinkage() via a null 'VarDecl*'. This was an XCore specific
+// conditional call to GV->setSection(".cp.rodata").
+class C {
+public:
+  ~C(){};
+};
+C c;
+
+// CHECK: "no-frame-pointer-elim"="false"
+// CHECK-NOT: "no-frame-pointer-elim-non-leaf"
diff --git a/test/CodeGen/xcore-stringtype.c b/test/CodeGen/xcore-stringtype.c
new file mode 100644
index 0000000..25589d5
--- /dev/null
+++ b/test/CodeGen/xcore-stringtype.c
@@ -0,0 +1,179 @@
+// REQUIRES: xcore-registered-target
+// RUN: %clang_cc1 -triple xcore-unknown-unknown -fno-signed-char -fno-common -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: target triple = "xcore-unknown-unknown"
+
+// In the tests below, some types are not supported by the ABI (_Complex,
+// variable length arrays) and will thus emit no meta data.
+// The 33 tests that do emit typestrings are gathered into '!xcore.typestrings'
+// Please see 'Tools Development Guide' section 2.16.2 for format details:
+// <https://www.xmos.com/download/public/Tools-Development-Guide%28X9114A%29.pdf>
+
+// CHECK: !xcore.typestrings = !{!1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11,
+// CHECK: !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25,
+// CHECK: !26, !27, !28, !29, !30, !31, !32, !33, !34, !35, !36, !37, !38}
+
+
+// test BuiltinType
+// CHECK: !1 = metadata !{void (i1, i8, i8, i8, i16, i16, i16, i32, i32, i32,
+// CHECK:      i32, i32, i32, i64, i64, i64, float, double, double)*
+// CHECK:      @builtinType, metadata !"f{0}(b,uc,uc,sc,ss,us,ss,si,ui,si,sl,
+// CHECK:      ul,sl,sll,ull,sll,ft,d,ld)"}
+void builtinType(_Bool B, char C, unsigned char UC, signed char SC, short S,
+                 unsigned short US, signed short SS, int I, unsigned int UI,
+                 signed int SI, long L, unsigned long UL, signed long SL,
+                 long long LL, unsigned long long ULL, signed long long SLL,
+                 float F, double D, long double LD) {}
+double _Complex Complex; // not supported
+
+
+// test FunctionType & Qualifiers
+// CHECK: !2 = metadata !{void ()* @gI, metadata !"f{0}()"}
+// CHECK: !3 = metadata !{void (...)* @eI, metadata !"f{0}()"}
+// CHECK: !4 = metadata !{void ()* @gV, metadata !"f{0}(0)"}
+// CHECK: !5 = metadata !{void ()* @eV, metadata !"f{0}(0)"}
+// CHECK: !6 = metadata !{void (i32, ...)* @gVA, metadata !"f{0}(si,va)"}
+// CHECK: !7 = metadata !{void (i32, ...)* @eVA, metadata !"f{0}(si,va)"}
+// CHECK: !8 = metadata !{i32* (i32*)* @gQ, metadata !"f{crv:p(cv:si)}(p(cv:si))"}
+// CHECK: !9 = metadata !{i32* (i32*)* @eQ, metadata !"f{crv:p(cv:si)}(p(cv:si))"}
+extern void eI();
+void gI() {eI();};
+extern void eV(void);
+void gV(void) {eV();}
+extern void eVA(int, ...);
+void gVA(int i, ...) {eVA(i);}
+extern const volatile int* volatile restrict const
+    eQ(const volatile int * volatile restrict const);
+const volatile int* volatile restrict const
+    gQ(const volatile int * volatile restrict const i) {return eQ(i);}
+
+
+// test PointerType
+// CHECK: !10 = metadata !{i32* (i32*, i32* (i32*)*)*
+// CHECK:       @pointerType, metadata !"f{p(si)}(p(si),p(f{p(si)}(p(si))))"}
+// CHECK: !11 = metadata !{i32** @EP, metadata !"p(si)"}
+// CHECK: !12 = metadata !{i32** @GP, metadata !"p(si)"}
+extern int* EP;
+int* GP;
+int* pointerType(int *I, int * (*FP)(int *)) {
+  return I? EP : GP;
+}
+
+// test ArrayType
+// CHECK: !13 = metadata !{[2 x i32]* (i32*, i32*, [2 x i32]*, [2 x i32]*, i32*)*
+// CHECK:       @arrayType, metadata !"f{p(a(2:si))}(p(si),p(cv:si),p(a(2:si)),
+// CHECK:       p(a(2:si)),p(si))"}
+// CHECK: !14 = metadata !{[0 x i32]* @EA1, metadata !"a(*:cv:si)"}
+// CHECK: !15 = metadata !{[2 x i32]* @EA2, metadata !"a(2:si)"}
+// CHECK: !16 = metadata !{[0 x [2 x i32]]* @EA3, metadata !"a(*:a(2:si))"}
+// CHECK: !17 = metadata !{[3 x [2 x i32]]* @EA4, metadata !"a(3:a(2:si))"}
+// CHECK: !18 = metadata !{[2 x i32]* @GA1, metadata !"a(2:cv:si)"}
+// CHECK: !19 = metadata !{void ([2 x i32]*)* @arrayTypeVariable1,
+// CHECK:       metadata !"f{0}(p(a(2:si)))"}
+// CHECK: !20 = metadata !{void (void ([2 x i32]*)*)* @arrayTypeVariable2,
+// CHECK:       metadata !"f{0}(p(f{0}(p(a(2:si)))))"}
+// CHECK: !21 = metadata !{[3 x [2 x i32]]* @GA2, metadata !"a(3:a(2:si))"}
+extern int GA2[3][2];
+extern const volatile int EA1[];
+extern int EA2[2];
+extern int EA3[][2];
+extern int EA4[3][2];
+const volatile int GA1[2];
+extern void arrayTypeVariable1(int[*][2]);
+extern void arrayTypeVariable2( void(*fp)(int[*][2]) );
+extern void arrayTypeVariable3(int[3][*]);                // not supported
+extern void arrayTypeVariable4( void(*fp)(int[3][*]) );   // not supported
+typedef int RetType[2];
+RetType* arrayType(int A1[], int const volatile A2[2], int A3[][2],
+                   int A4[3][2], int A5[const volatile restrict static 2]) {
+  if (A1) EA2[0] = EA1[0];
+  if (A2) return &EA2;
+  if (A3) return EA3;
+  if (A4) return EA4;
+  if (A5) EA2[0] = GA1[0];
+  arrayTypeVariable1(EA4);
+  arrayTypeVariable2(arrayTypeVariable1);
+  arrayTypeVariable3(EA4);
+  arrayTypeVariable4(arrayTypeVariable3);
+  return GA2;
+}
+
+
+// test StructureType
+// CHECK: !22 = metadata !{void (%struct.S1*)* @structureType1, metadata
+// CHECK:       !"f{0}(s(S1){m(ps2){p(s(S2){m(ps3){p(s(S3){m(s1){s(S1){}}})}})}})"}
+// CHECK: !23 = metadata !{void (%struct.S2*)* @structureType2, metadata
+// CHECK:       !"f{0}(s(S2){m(ps3){p(s(S3){m(s1){s(S1){m(ps2){p(s(S2){})}}}})}})"}
+// CHECK: !24 = metadata !{void (%struct.S3*)* @structureType3, metadata
+// CHECK:       !"f{0}(s(S3){m(s1){s(S1){m(ps2){p(s(S2){m(ps3){p(s(S3){})}})}}}})"}
+// CHECK: !25 = metadata !{void (%struct.S4*)* @structureType4, metadata
+// CHECK:       !"f{0}(s(S4){m(s1){s(S1){m(ps2){p(s(S2){m(ps3){p(s(S3){m(s1){s(S1){}}})}})}}}})"}
+// CHECK: !26 = metadata !{%struct.anon* @StructAnon, metadata !"s(){m(A){si}}"}
+// CHECK: !27 = metadata !{i32 (%struct.SB*)* @structureTypeB, metadata
+// CHECK:       !"f{si}(s(SB){m(){b(4:si)},m(){b(2:si)},m(N4){b(4:si)},
+// CHECK:       m(N2){b(2:si)},m(){b(4:ui)},m(){b(4:si)},m(){b(4:c:si)},
+// CHECK:       m(){b(4:c:si)},m(){b(4:cv:si)}})"}
+struct S2;
+struct S1{struct S2 *ps2;};
+struct S3;
+struct S2{struct S3 *ps3;};
+struct S3{struct S1 s1;};
+struct S4{struct S1 s1;};
+void structureType1(struct S1 s1){}
+void structureType2(struct S2 s2){}
+void structureType3(struct S3 s3){}
+void structureType4(struct S4 s4){}
+struct {int A;} StructAnon = {1};
+struct SB{int:4; int:2; int N4:4; int N2:2; unsigned int:4; signed int:4;
+          const int:4; int const :4; volatile const int:4;};
+int structureTypeB(struct SB sb){return StructAnon.A;}
+
+
+// test UnionType
+// CHECK: !28 = metadata !{void (%union.U1*)* @unionType1, metadata
+// CHECK:       !"f{0}(u(U1){m(pu2){p(u(U2){m(pu3){p(u(U3){m(u1){u(U1){}}})}})}})"}
+// CHECK: !29 = metadata !{void (%union.U2*)* @unionType2, metadata
+// CHECK:       !"f{0}(u(U2){m(pu3){p(u(U3){m(u1){u(U1){m(pu2){p(u(U2){})}}}})}})"}
+// CHECK: !30 = metadata !{void (%union.U3*)* @unionType3, metadata
+// CHECK:       !"f{0}(u(U3){m(u1){u(U1){m(pu2){p(u(U2){m(pu3){p(u(U3){})}})}}}})"}
+// CHECK: !31 = metadata !{void (%union.U4*)* @unionType4, metadata
+// CHECK:       !"f{0}(u(U4){m(u1){u(U1){m(pu2){p(u(U2){m(pu3){p(u(U3){m(u1){u(U1){}}})}})}}}})"}
+// CHECK: !32 = metadata !{%union.anon* @UnionAnon, metadata !"u(){m(A){si}}"}
+// CHECK: !33 = metadata !{i32 (%union.UB*)* @unionTypeB, metadata
+// CHECK:       !"f{si}(u(UB){m(N2){b(2:si)},m(N4){b(4:si)},m(){b(2:si)},
+// CHECK:       m(){b(4:c:si)},m(){b(4:c:si)},m(){b(4:cv:si)},m(){b(4:si)},
+// CHECK:       m(){b(4:si)},m(){b(4:ui)}})"}
+union U2;
+union U1{union U2 *pu2;};
+union U3;
+union U2{union U3 *pu3;};
+union U3{union U1 u1;};
+union U4{union U1 u1;};
+void unionType1(union U1 u1) {}
+void unionType2(union U2 u2) {}
+void unionType3(union U3 u3) {}
+void unionType4(union U4 u4) {}
+union UB{int:4; int:2; int N4:4; int N2:2; unsigned int:4; signed int:4;
+         const int:4; int const :4; volatile const int:4;};
+union {int A;} UnionAnon = {1};
+int unionTypeB(union UB ub) {return UnionAnon.A;}
+
+
+// test EnumType
+// CHECK: !34 = metadata !{i32* @EnumAnon, metadata !"e(){m(EA){3}}"}
+// CHECK: !35 = metadata !{i32 (i32)* @enumType, metadata
+// CHECK:       !"f{si}(e(E){m(A){7},m(B){6},m(C){5},m(D){0}})"}
+enum E {D, C=5, B, A};
+enum {EA=3} EnumAnon = EA;
+int enumType(enum E e) {return EnumAnon;}
+
+
+// CHECK: !36 = metadata !{i32 ()* @testReDecl, metadata !"f{si}()"}
+// CHECK: !37 = metadata !{[10 x i32]* @After, metadata !"a(10:si)"}
+// CHECK: !38 = metadata !{[10 x i32]* @Before, metadata !"a(10:si)"}
+extern int After[];
+extern int Before[10];
+int testReDecl() {return After[0] + Before[0];}
+int After[10];
+int Before[];
+
diff --git a/test/CodeGenCUDA/Inputs/cuda.h b/test/CodeGenCUDA/Inputs/cuda.h
new file mode 100644
index 0000000..a9a4595
--- /dev/null
+++ b/test/CodeGenCUDA/Inputs/cuda.h
@@ -0,0 +1,20 @@
+/* Minimal declarations for CUDA support.  Testing purposes only. */
+
+#include <stddef.h>
+
+#define __constant__ __attribute__((constant))
+#define __device__ __attribute__((device))
+#define __global__ __attribute__((global))
+#define __host__ __attribute__((host))
+#define __shared__ __attribute__((shared))
+#define __launch_bounds__(...) __attribute__((launch_bounds(__VA_ARGS__)))
+
+struct dim3 {
+  unsigned x, y, z;
+  __host__ __device__ dim3(unsigned x, unsigned y = 1, unsigned z = 1) : x(x), y(y), z(z) {}
+};
+
+typedef struct cudaStream *cudaStream_t;
+
+int cudaConfigureCall(dim3 gridSize, dim3 blockSize, size_t sharedSize = 0,
+                      cudaStream_t stream = 0);
diff --git a/test/CodeGenCUDA/address-spaces.cu b/test/CodeGenCUDA/address-spaces.cu
index 0434452..b808206 100644
--- a/test/CodeGenCUDA/address-spaces.cu
+++ b/test/CodeGenCUDA/address-spaces.cu
@@ -1,6 +1,9 @@
 // RUN: %clang_cc1 -emit-llvm %s -o - -fcuda-is-device -triple nvptx-unknown-unknown | FileCheck %s
 
-#include "../SemaCUDA/cuda.h"
+// Verifies Clang emits correct address spaces and addrspacecast instructions
+// for CUDA code.
+
+#include "Inputs/cuda.h"
 
 // CHECK: @i = addrspace(1) global
 __device__ int i;
@@ -11,6 +14,18 @@
 // CHECK: @k = addrspace(3) global
 __shared__ int k;
 
+struct MyStruct {
+  int data1;
+  int data2;
+};
+
+// CHECK: @_ZZ5func0vE1a = internal addrspace(3) global %struct.MyStruct zeroinitializer
+// CHECK: @_ZZ5func1vE1a = internal addrspace(3) global float 0.000000e+00
+// CHECK: @_ZZ5func2vE1a = internal addrspace(3) global [256 x float] zeroinitializer
+// CHECK: @_ZZ5func3vE1a = internal addrspace(3) global float 0.000000e+00
+// CHECK: @_ZZ5func4vE1a = internal addrspace(3) global float 0.000000e+00
+// CHECK: @b = addrspace(3) global float 0.000000e+00
+
 __device__ void foo() {
   // CHECK: load i32* addrspacecast (i32 addrspace(1)* @i to i32*)
   i++;
@@ -22,15 +37,66 @@
   k++;
 
   static int li;
-  // CHECK: load i32 addrspace(1)* @_ZZ3foovE2li
+  // CHECK: load i32* addrspacecast (i32 addrspace(1)* @_ZZ3foovE2li to i32*)
   li++;
 
   __constant__ int lj;
-  // CHECK: load i32 addrspace(4)* @_ZZ3foovE2lj
+  // CHECK: load i32* addrspacecast (i32 addrspace(4)* @_ZZ3foovE2lj to i32*)
   lj++;
 
   __shared__ int lk;
-  // CHECK: load i32 addrspace(3)* @_ZZ3foovE2lk
+  // CHECK: load i32* addrspacecast (i32 addrspace(3)* @_ZZ3foovE2lk to i32*)
   lk++;
 }
 
+__device__ void func0() {
+  __shared__ MyStruct a;
+  MyStruct *ap = &a; // composite type
+  ap->data1 = 1;
+  ap->data2 = 2;
+}
+// CHECK: define void @_Z5func0v()
+// CHECK: store %struct.MyStruct* addrspacecast (%struct.MyStruct addrspace(3)* @_ZZ5func0vE1a to %struct.MyStruct*), %struct.MyStruct** %ap
+
+__device__ void callee(float *ap) {
+  *ap = 1.0f;
+}
+
+__device__ void func1() {
+  __shared__ float a;
+  callee(&a); // implicit cast from parameters
+}
+// CHECK: define void @_Z5func1v()
+// CHECK: call void @_Z6calleePf(float* addrspacecast (float addrspace(3)* @_ZZ5func1vE1a to float*))
+
+__device__ void func2() {
+  __shared__ float a[256];
+  float *ap = &a[128]; // implicit cast from a decayed array
+  *ap = 1.0f;
+}
+// CHECK: define void @_Z5func2v()
+// CHECK: store float* getelementptr inbounds ([256 x float]* addrspacecast ([256 x float] addrspace(3)* @_ZZ5func2vE1a to [256 x float]*), i32 0, i32 128), float** %ap
+
+__device__ void func3() {
+  __shared__ float a;
+  float *ap = reinterpret_cast<float *>(&a); // explicit cast
+  *ap = 1.0f;
+}
+// CHECK: define void @_Z5func3v()
+// CHECK: store float* addrspacecast (float addrspace(3)* @_ZZ5func3vE1a to float*), float** %ap
+
+__device__ void func4() {
+  __shared__ float a;
+  float *ap = (float *)&a; // explicit c-style cast
+  *ap = 1.0f;
+}
+// CHECK: define void @_Z5func4v()
+// CHECK: store float* addrspacecast (float addrspace(3)* @_ZZ5func4vE1a to float*), float** %ap
+
+__shared__ float b;
+
+__device__ float *func5() {
+  return &b; // implicit cast from a return value
+}
+// CHECK: define float* @_Z5func5v()
+// CHECK: ret float* addrspacecast (float addrspace(3)* @b to float*)
diff --git a/test/CodeGenCUDA/device-stub.cu b/test/CodeGenCUDA/device-stub.cu
index af73ea9..ed94d10 100644
--- a/test/CodeGenCUDA/device-stub.cu
+++ b/test/CodeGenCUDA/device-stub.cu
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
 
-#include "../SemaCUDA/cuda.h"
+#include "Inputs/cuda.h"
 
 // Test that we build the correct number of calls to cudaSetupArgument followed
 // by a call to cudaLaunch.
diff --git a/test/CodeGenCUDA/filter-decl.cu b/test/CodeGenCUDA/filter-decl.cu
index b758632..faaeb69 100644
--- a/test/CodeGenCUDA/filter-decl.cu
+++ b/test/CodeGenCUDA/filter-decl.cu
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-HOST %s
-// RUN: %clang_cc1 -emit-llvm %s -o - -fcuda-is-device | FileCheck -check-prefix=CHECK-DEVICE %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-HOST %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm %s -o - -fcuda-is-device | FileCheck -check-prefix=CHECK-DEVICE %s
 
-#include "../SemaCUDA/cuda.h"
+#include "Inputs/cuda.h"
 
 // CHECK-HOST-NOT: constantdata = global
 // CHECK-DEVICE: constantdata = global
diff --git a/test/CodeGenCUDA/kernel-call.cu b/test/CodeGenCUDA/kernel-call.cu
index f134624..9b849db 100644
--- a/test/CodeGenCUDA/kernel-call.cu
+++ b/test/CodeGenCUDA/kernel-call.cu
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
 
-#include "../SemaCUDA/cuda.h"
+#include "Inputs/cuda.h"
 
 __global__ void g1(int x) {}
 
diff --git a/test/CodeGenCUDA/launch-bounds.cu b/test/CodeGenCUDA/launch-bounds.cu
new file mode 100644
index 0000000..ed4c2bf
--- /dev/null
+++ b/test/CodeGenCUDA/launch-bounds.cu
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 %s -triple nvptx-unknown-unknown -fcuda-is-device -emit-llvm -o - | FileCheck %s
+
+#include "Inputs/cuda.h"
+
+#define MAX_THREADS_PER_BLOCK 256
+#define MIN_BLOCKS_PER_MP     2
+
+// Test both max threads per block and Min cta per sm.
+extern "C" {
+__global__ void
+__launch_bounds__( MAX_THREADS_PER_BLOCK, MIN_BLOCKS_PER_MP )
+Kernel1()
+{
+}
+}
+
+// CHECK: !{{[0-9]+}} = metadata !{void ()* @Kernel1, metadata !"maxntidx", i32 256}
+// CHECK: !{{[0-9]+}} = metadata !{void ()* @Kernel1, metadata !"minctasm", i32 2}
+
+// Test only max threads per block. Min cta per sm defaults to 0, and
+// CodeGen doesn't output a zero value for minctasm.
+extern "C" {
+__global__ void
+__launch_bounds__( MAX_THREADS_PER_BLOCK )
+Kernel2()
+{
+}
+}
+
+// CHECK: !{{[0-9]+}} = metadata !{void ()* @Kernel2, metadata !"maxntidx", i32 256}
diff --git a/test/CodeGenCUDA/ptx-kernels.cu b/test/CodeGenCUDA/ptx-kernels.cu
index 211692f..11b92b5 100644
--- a/test/CodeGenCUDA/ptx-kernels.cu
+++ b/test/CodeGenCUDA/ptx-kernels.cu
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 %s -triple nvptx-unknown-unknown -fcuda-is-device -emit-llvm -o - | FileCheck %s
 
-#include "../SemaCUDA/cuda.h"
+#include "Inputs/cuda.h"
 
 // CHECK-LABEL: define void @device_function
 extern "C"
diff --git a/test/CodeGenCXX/2003-11-27-MultipleInheritanceThunk.cpp b/test/CodeGenCXX/2003-11-27-MultipleInheritanceThunk.cpp
index 3e53397..a70f6e0 100644
--- a/test/CodeGenCXX/2003-11-27-MultipleInheritanceThunk.cpp
+++ b/test/CodeGenCXX/2003-11-27-MultipleInheritanceThunk.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -emit-llvm %s -o -
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm %s -o -
+// RUN: %clang_cc1 -triple %ms_abi_triple -fno-rtti -emit-llvm %s -o -
 
 
 struct CallSite {
diff --git a/test/CodeGenCXX/2004-03-08-ReinterpretCastCopy.cpp b/test/CodeGenCXX/2004-03-08-ReinterpretCastCopy.cpp
index a6e2e30..a4411fc 100644
--- a/test/CodeGenCXX/2004-03-08-ReinterpretCastCopy.cpp
+++ b/test/CodeGenCXX/2004-03-08-ReinterpretCastCopy.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -emit-llvm %s -o -
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm %s -o -
+// RUN: %clang_cc1 -triple %ms_abi_triple -fno-rtti -emit-llvm %s -o -
 
 struct A {
   virtual void Method() = 0;
diff --git a/test/CodeGenCXX/2004-03-09-UnmangledBuiltinMethods.cpp b/test/CodeGenCXX/2004-03-09-UnmangledBuiltinMethods.cpp
index 5d8c8b0..03c4ed6 100644
--- a/test/CodeGenCXX/2004-03-09-UnmangledBuiltinMethods.cpp
+++ b/test/CodeGenCXX/2004-03-09-UnmangledBuiltinMethods.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -o - %s | FileCheck %s
 
 // CHECK: _ZN11AccessFlags6strlenEv
 struct AccessFlags {
diff --git a/test/CodeGenCXX/2006-09-12-OpaqueStructCrash.cpp b/test/CodeGenCXX/2006-09-12-OpaqueStructCrash.cpp
index bd270dd..c5a2d5a 100644
--- a/test/CodeGenCXX/2006-09-12-OpaqueStructCrash.cpp
+++ b/test/CodeGenCXX/2006-09-12-OpaqueStructCrash.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -emit-llvm -o - %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s
+// RUN: %clang_cc1 -triple %ms_abi_triple -fno-rtti -emit-llvm -o - %s
 
 struct A {
    virtual ~A();
diff --git a/test/CodeGenCXX/2010-05-11-alwaysinlineinstantiation.cpp b/test/CodeGenCXX/2010-05-11-alwaysinlineinstantiation.cpp
index fe0740b..bf00c0f 100644
--- a/test/CodeGenCXX/2010-05-11-alwaysinlineinstantiation.cpp
+++ b/test/CodeGenCXX/2010-05-11-alwaysinlineinstantiation.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple %s -o - | FileCheck %s
 
 // CHECK-NOT: ZN12basic_stringIcEC1Ev
 // CHECK: ZN12basic_stringIcED1Ev
diff --git a/test/CodeGenCXX/Inputs/debug-info-class-limited.cpp b/test/CodeGenCXX/Inputs/debug-info-class-limited.cpp
new file mode 100644
index 0000000..31a0261
--- /dev/null
+++ b/test/CodeGenCXX/Inputs/debug-info-class-limited.cpp
@@ -0,0 +1,49 @@
+
+// CHECK-DAG: [ DW_TAG_structure_type ] [PR16214] [line [[@LINE+1]], {{.*}} [def]
+struct PR16214 {
+  int i;
+};
+
+typedef PR16214 bar;
+
+bar *a;
+bar b;
+
+namespace PR14467 {
+// CHECK-DAG: [ DW_TAG_structure_type ] [foo] [line [[@LINE+1]], {{.*}} [def]
+struct foo {
+};
+
+foo *bar(foo *a) {
+  foo *b = new foo(*a);
+  return b;
+}
+}
+
+namespace test1 {
+// CHECK-DAG: [ DW_TAG_structure_type ] [foo] [line [[@LINE+1]], {{.*}} [def]
+struct foo {
+};
+
+extern int bar(foo *a);
+int baz(foo *a) {
+  return bar(a);
+}
+}
+
+namespace test2 {
+// FIXME: if we were a bit fancier, we could realize that the 'foo' type is only
+// required because of the 'bar' type which is not required at all (or might
+// only be required to be declared)
+// CHECK-DAG: [ DW_TAG_structure_type ] [foo] [line [[@LINE+1]], {{.*}} [def]
+struct foo {
+};
+
+struct bar {
+  foo f;
+};
+
+void func() {
+  foo *f;
+}
+}
diff --git a/test/CodeGenCXX/PR19955.cpp b/test/CodeGenCXX/PR19955.cpp
new file mode 100644
index 0000000..9e10155
--- /dev/null
+++ b/test/CodeGenCXX/PR19955.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple i686-windows-msvc -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s | FileCheck %s --check-prefix X64
+
+extern int __declspec(dllimport) var;
+extern void __declspec(dllimport) fun();
+
+extern int *varp;
+int *varp = &var;
+// CHECK-DAG: @"\01?varp@@3PAHA" = global i32* null
+// X64-DAG: @"\01?varp@@3PEAHEA" = global i32* null
+
+extern void (*funp)();
+void (*funp)() = &fun;
+// CHECK-DAG: @"\01?funp@@3P6AXXZA" = global void ()* null
+// X64-DAG: @"\01?funp@@3P6AXXZEA" = global void ()* null
+
+// CHECK-LABEL: @"\01??__Evarp@@YAXXZ"
+// CHECK-DAG: store i32* @"\01?var@@3HA", i32** @"\01?varp@@3PAHA"
+
+// X64-LABEL: @"\01??__Evarp@@YAXXZ"
+// X64-DAG: store i32* @"\01?var@@3HA", i32** @"\01?varp@@3PEAHEA"
+
+// CHECK-LABEL: @"\01??__Efunp@@YAXXZ"()
+// CHECK-DAG: store void ()* @"\01?fun@@YAXXZ", void ()** @"\01?funp@@3P6AXXZA"
+
+// X64-LABEL: @"\01??__Efunp@@YAXXZ"()
+// X64-DAG: store void ()* @"\01?fun@@YAXXZ", void ()** @"\01?funp@@3P6AXXZEA"
diff --git a/test/CodeGenCXX/PR20038.cpp b/test/CodeGenCXX/PR20038.cpp
new file mode 100644
index 0000000..c24685d
--- /dev/null
+++ b/test/CodeGenCXX/PR20038.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -g -emit-llvm  %s -o - | FileCheck %s
+
+struct C {
+  ~C();
+};
+extern bool b;
+// CHECK: call {{.*}}, !dbg [[DTOR_CALL1_LOC:![0-9]*]]
+// CHECK: call {{.*}}, !dbg [[DTOR_CALL2_LOC:![0-9]*]]
+// CHECK: [[FUN1:.*]] = {{.*}}; [ DW_TAG_subprogram ] {{.*}} [def] [fun1]
+// CHECK: [[FUN2:.*]] = {{.*}}; [ DW_TAG_subprogram ] {{.*}} [def] [fun2]
+// CHECK: [[DTOR_CALL1_LOC]] = metadata !{i32 [[@LINE+2]], i32 0, metadata [[FUN1_BLOCK:.*]], null}
+// CHECK: [[FUN1_BLOCK]] = metadata !{{{[^,]*}}, {{[^,]*}}, metadata [[FUN1]],
+void fun1() { b && (C(), 1); }
+// CHECK: [[DTOR_CALL2_LOC]] = metadata !{i32 [[@LINE+2]], i32 0, metadata [[FUN2_BLOCK1:.*]], null}
+// CHECK: [[FUN2_BLOCK1]] = metadata !{{{[^,]*}}, {{[^,]*}}, metadata [[FUN2]],
+bool fun2() { return (C(), b) && 0; }
diff --git a/test/CodeGenCXX/PR5050-constructor-conversion.cpp b/test/CodeGenCXX/PR5050-constructor-conversion.cpp
index a1b05eb..ce6cc0e 100644
--- a/test/CodeGenCXX/PR5050-constructor-conversion.cpp
+++ b/test/CodeGenCXX/PR5050-constructor-conversion.cpp
@@ -1,8 +1,7 @@
-// REQUIRES: x86-registered-target,x86-64-registered-target
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s
-// RUN: FileCheck -check-prefix CHECK-LP64 --input-file=%t-64.s %s
-// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s
-// RUN: FileCheck -check-prefix CHECK-LP32 --input-file=%t-32.s %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -emit-llvm %s -o - | \
+// RUN: FileCheck %s
 
 struct A { A(const A&, int i1 = 1); };
 
@@ -12,8 +11,4 @@
   return b;
 }
 
-// CHECK-LP64: callq    __ZN1AC1ERKS_i
-
-// CHECK-LP32: calll     L__ZN1AC1ERKS_i
-
-
+// CHECK: call void @_ZN1AC1ERKS_i
diff --git a/test/CodeGenCXX/PR5093-static-member-function.cpp b/test/CodeGenCXX/PR5093-static-member-function.cpp
index ceab852..d61a87a 100644
--- a/test/CodeGenCXX/PR5093-static-member-function.cpp
+++ b/test/CodeGenCXX/PR5093-static-member-function.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o - | FileCheck %s
 struct a {
   static void f();
 };
diff --git a/test/CodeGenCXX/PR5863-unreachable-block.cpp b/test/CodeGenCXX/PR5863-unreachable-block.cpp
index 3f32d75..50d1731 100644
--- a/test/CodeGenCXX/PR5863-unreachable-block.cpp
+++ b/test/CodeGenCXX/PR5863-unreachable-block.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -emit-llvm-only %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -emit-llvm-only %s
 
 // PR5863
 class E { };
diff --git a/test/CodeGenCXX/aarch64-arguments.cpp b/test/CodeGenCXX/aarch64-arguments.cpp
index f56ad0b..013051c 100644
--- a/test/CodeGenCXX/aarch64-arguments.cpp
+++ b/test/CodeGenCXX/aarch64-arguments.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple aarch64-none-linux -emit-llvm -w -o - %s | FileCheck -check-prefix=PCS %s
+// RUN: %clang_cc1 -triple arm64-none-linux -emit-llvm -w -o - %s | FileCheck -check-prefix=PCS %s
 
 // PCS: define void @{{.*}}(i8 %a
 struct s0 {};
diff --git a/test/CodeGenCXX/aarch64-cxxabi.cpp b/test/CodeGenCXX/aarch64-cxxabi.cpp
index 04d9493..6c08ff2 100644
--- a/test/CodeGenCXX/aarch64-cxxabi.cpp
+++ b/test/CodeGenCXX/aarch64-cxxabi.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -emit-llvm -w -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-none-linux-gnu -emit-llvm -w -o - %s | FileCheck %s
 
 // Check differences between the generic Itanium ABI, the AArch32 version and
 // the AArch64 version.
@@ -40,8 +40,8 @@
 
 void guard_variables(int a) {
   static Guarded mine(a);
-// CHECK: [[GUARDBIT:%[0-9]+]] = and i64 {{%[0-9]+}}, 1
-// CHECK: icmp eq i64 [[GUARDBIT]], 0
+// CHECK: [[GUARDBIT:%[0-9]+]] = and i8 {{%[0-9]+}}, 1
+// CHECK: icmp eq i8 [[GUARDBIT]], 0
 
   // As guards are 64-bit, these helpers should take 64-bit pointers.
 // CHECK: call i32 @__cxa_guard_acquire(i64*
diff --git a/test/CodeGenCXX/aarch64-mangle-neon-vectors.cpp b/test/CodeGenCXX/aarch64-mangle-neon-vectors.cpp
index 2514704..3b4a309 100644
--- a/test/CodeGenCXX/aarch64-mangle-neon-vectors.cpp
+++ b/test/CodeGenCXX/aarch64-mangle-neon-vectors.cpp
@@ -1,12 +1,11 @@
-// REQUIRES: aarch64-registered-target
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +neon %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon %s -emit-llvm -o - | FileCheck %s
 
 typedef unsigned char uint8_t;
 typedef unsigned short uint16_t;
 typedef signed char int8_t;
 typedef signed short int16_t;
-typedef signed long long int64_t;
-typedef unsigned long long uint64_t;
+typedef signed long int64_t;
+typedef unsigned long uint64_t;
 typedef unsigned char poly8_t;
 typedef unsigned short poly16_t;
 typedef __fp16 float16_t;
diff --git a/test/CodeGenCXX/aarch64-neon.cpp b/test/CodeGenCXX/aarch64-neon.cpp
index 5d2a00b..d6f6b0e 100644
--- a/test/CodeGenCXX/aarch64-neon.cpp
+++ b/test/CodeGenCXX/aarch64-neon.cpp
@@ -1,13 +1,13 @@
 // REQUIRES: aarch64-registered-target
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +neon \
+// RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \
 // RUN:   -ffp-contract=fast -S -O3 -o - %s | FileCheck %s
 
-// Test whether arm_neon.h can be used in .cpp file.
+// Test whether arm_neon.h works as expected in C++.
 
 #include "arm_neon.h"
 
 poly64x1_t test_vld1_p64(poly64_t const * ptr) {
   // CHECK: test_vld1_p64
   return vld1_p64(ptr);
-  // CHECK:  ld1 {{{v[0-9]+}}.1d}, [{{x[0-9]+|sp}}]
+  // CHECK:  {{ld1 { v[0-9]+.1d }|ldr d[0-9]+}}, [{{x[0-9]+|sp}}]
 }
diff --git a/test/CodeGenCXX/abstract-class-ctors-dtors.cpp b/test/CodeGenCXX/abstract-class-ctors-dtors.cpp
index 793bbde..f369224 100644
--- a/test/CodeGenCXX/abstract-class-ctors-dtors.cpp
+++ b/test/CodeGenCXX/abstract-class-ctors-dtors.cpp
@@ -7,10 +7,10 @@
   ~A();
 };
 
-// CHECK-NOT-LABEL: define void @_ZN1AC1Ev
+// CHECK-NOT: define void @_ZN1AC1Ev
 // CHECK-LABEL: define void @_ZN1AC2Ev
-// CHECK-LABEL: define void @_ZN1AD1Ev
 // CHECK-LABEL: define void @_ZN1AD2Ev
+// CHECK-LABEL: define void @_ZN1AD1Ev
 A::A() { }
 
 A::~A() { }
diff --git a/test/CodeGenCXX/address-of-fntemplate.cpp b/test/CodeGenCXX/address-of-fntemplate.cpp
index 7179452..4ff597a 100644
--- a/test/CodeGenCXX/address-of-fntemplate.cpp
+++ b/test/CodeGenCXX/address-of-fntemplate.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o - | FileCheck %s
 template <typename T> void f(T) {}
 template <typename T> void f() { }
 
diff --git a/test/CodeGenCXX/address-space-ref.cpp b/test/CodeGenCXX/address-space-ref.cpp
new file mode 100644
index 0000000..de6bddc
--- /dev/null
+++ b/test/CodeGenCXX/address-space-ref.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+// For a reference to a complete type, output the dereferenceable attribute (in
+// any address space).
+
+typedef int a __attribute__((address_space(1)));
+
+a & foo(a &x, a & y) {
+  return x;
+}
+
+// CHECK: define dereferenceable(4) i32 addrspace(1)* @_Z3fooRU3AS1iS0_(i32 addrspace(1)* dereferenceable(4) %x, i32 addrspace(1)* dereferenceable(4) %y)
+
+// For a reference to an incomplete type in an alternate address space, output
+// neither dereferenceable nor nonnull.
+
+class bc;
+typedef bc b __attribute__((address_space(1)));
+
+b & bar(b &x, b & y) {
+  return x;
+}
+
+// CHECK: define %class.bc addrspace(1)* @_Z3barRU3AS12bcS1_(%class.bc addrspace(1)* %x, %class.bc addrspace(1)* %y)
+
+// For a reference to an incomplete type in addrspace(0), output nonnull.
+
+bc & bar2(bc &x, bc & y) {
+  return x;
+}
+
+// CHECK: define nonnull %class.bc* @_Z4bar2R2bcS0_(%class.bc* nonnull %x, %class.bc* nonnull %y)
+
+
diff --git a/test/CodeGenCXX/apple-kext.cpp b/test/CodeGenCXX/apple-kext.cpp
index 03506a8..0d7ccfb 100644
--- a/test/CodeGenCXX/apple-kext.cpp
+++ b/test/CodeGenCXX/apple-kext.cpp
@@ -1,8 +1,8 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fno-use-cxa-atexit -fapple-kext -emit-llvm -o - %s | FileCheck %s
 
 // CHECK: @_ZN5test01aE = global [[A:%.*]] zeroinitializer
-// CHECK: @llvm.global_ctors = appending global {{.*}} { i32 65535, void ()* [[CTOR0:@.*]] }
-// CHECK: @llvm.global_dtors = appending global {{.*}} { i32 65535, void ()* [[DTOR0:@.*]] }
+// CHECK: @llvm.global_ctors = appending global {{.*}} { i32 65535, void ()* [[CTOR0:@.*]], i8* null }
+// CHECK: @llvm.global_dtors = appending global {{.*}} { i32 65535, void ()* [[DTOR0:@.*]], i8* null }
 
 // rdar://11241230
 namespace test0 {
diff --git a/test/CodeGenCXX/arm.cpp b/test/CodeGenCXX/arm.cpp
index 2fb9c49..b6629f4 100644
--- a/test/CodeGenCXX/arm.cpp
+++ b/test/CodeGenCXX/arm.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -triple=thumbv7-apple-ios3.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 -o - -fexceptions | FileCheck %s
 
 // CHECK: @_ZZN5test74testEvE1x = internal global i32 0, align 4
 // CHECK: @_ZGVZN5test74testEvE1x = internal global i32 0
@@ -28,6 +28,7 @@
 // CHECK:      call [[BAR:%.*]]* @_ZN3barC1Ev(
 // CHECK-NEXT: call i32 @atexit(void ()* @__dtor_baz)
 
+// CHECK-NOT: @_GLOBAL__D_a()
 // CHECK-LABEL: define internal void @__dtor_baz()
 // CHECK: call [[BAR]]* @_ZN3barD1Ev([[BAR]]* @baz)
 
@@ -292,9 +293,9 @@
 
   // CHECK-LABEL: define void @_ZN5test74testEv()
   void test() {
-    // CHECK:      [[T0:%.*]] = load i32* @_ZGVZN5test74testEvE1x
-    // CHECK-NEXT: [[T1:%.*]] = and i32 [[T0]], 1
-    // CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
+    // CHECK:      [[T0:%.*]] = load atomic i8* bitcast (i32* @_ZGVZN5test74testEvE1x to i8*) acquire, align 1
+    // CHECK-NEXT: [[T1:%.*]] = and i8 [[T0]], 1
+    // CHECK-NEXT: [[T2:%.*]] = icmp eq i8 [[T1]], 0
     // CHECK-NEXT: br i1 [[T2]]
     //   -> fallthrough, end
     // CHECK:      [[T3:%.*]] = call i32 @__cxa_guard_acquire(i32* @_ZGVZN5test74testEvE1x)
@@ -327,9 +328,9 @@
 
   // CHECK-LABEL: define void @_ZN5test84testEv()
   void test() {
-    // CHECK:      [[T0:%.*]] = load i32* @_ZGVZN5test84testEvE1x
-    // CHECK-NEXT: [[T1:%.*]] = and i32 [[T0]], 1
-    // CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0
+    // CHECK:      [[T0:%.*]] = load atomic i8* bitcast (i32* @_ZGVZN5test84testEvE1x to i8*) acquire, align 1
+    // CHECK-NEXT: [[T1:%.*]] = and i8 [[T0]], 1
+    // CHECK-NEXT: [[T2:%.*]] = icmp eq i8 [[T1]], 0
     // CHECK-NEXT: br i1 [[T2]]
     //   -> fallthrough, end
     // CHECK:      [[T3:%.*]] = call i32 @__cxa_guard_acquire(i32* @_ZGVZN5test84testEvE1x)
@@ -416,6 +417,3 @@
   // CHECK-LABEL: define linkonce_odr void @_ZTv0_n12_N5test21CD0Ev(
   // CHECK:   call void @_ZN5test21CD0Ev(
   // CHECK:   ret void
-
-// CH_ECK: @_GLOBAL__D_a()
-// CH_ECK: call %class.bar* @_ZN3barD1Ev(%class.bar* @baz)
diff --git a/test/CodeGenCXX/arm64-constructor-return.cpp b/test/CodeGenCXX/arm64-constructor-return.cpp
new file mode 100644
index 0000000..0d5b3b3
--- /dev/null
+++ b/test/CodeGenCXX/arm64-constructor-return.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 %s -triple=arm64-apple-ios7.0.0 -emit-llvm -o - | FileCheck %s
+// rdar://12162905
+
+struct S {
+  S();
+  int iField;
+};
+
+S::S() {
+  iField = 1;
+};
+
+// CHECK: %struct.S* @_ZN1SC2Ev(%struct.S* returned %this)
+
+// CHECK: %struct.S* @_ZN1SC1Ev(%struct.S* returned %this)
+// CHECK: [[THISADDR:%[a-zA-z0-9.]+]] = alloca %struct.S*
+// CHECK: store %struct.S* %this, %struct.S** [[THISADDR]]
+// CHECK: [[THIS1:%.*]] = load %struct.S** [[THISADDR]]
+// CHECK: ret %struct.S* [[THIS1]]
diff --git a/test/CodeGenCXX/arm64-darwinpcs.cpp b/test/CodeGenCXX/arm64-darwinpcs.cpp
new file mode 100644
index 0000000..0a0ec3a
--- /dev/null
+++ b/test/CodeGenCXX/arm64-darwinpcs.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -triple arm64-linux-gnu -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-linux-gnu -emit-llvm -o - %s -target-abi darwinpcs | FileCheck %s --check-prefix=CHECK-DARWIN
+
+void test_extensions(bool a, char b, short c) {}
+// CHECK: define void @_Z15test_extensionsbcs(i1 %a, i8 %b, i16 %c)
+// CHECK-DARWIN: define void @_Z15test_extensionsbcs(i1 zeroext %a, i8 signext %b, i16 signext %c)
+
+struct Empty {};
+void test_empty(Empty e) {}
+// CHECK: define void @_Z10test_empty5Empty(i8
+// CHECK-DARWIN: define void @_Z10test_empty5Empty()
+
+struct HFA {
+  float a[3];
+};
diff --git a/test/CodeGenCXX/arm64-empty-struct.cpp b/test/CodeGenCXX/arm64-empty-struct.cpp
new file mode 100644
index 0000000..6fa4e95
--- /dev/null
+++ b/test/CodeGenCXX/arm64-empty-struct.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple arm64-apple-ios -target-abi darwinpcs -emit-llvm -o - %s | FileCheck %s
+struct Empty {};
+
+Empty emptyvar;
+
+int take_args(int a, ...) {
+  __builtin_va_list l;
+  __builtin_va_start(l, a);
+// CHECK: call void @llvm.va_start
+
+  emptyvar = __builtin_va_arg(l, Empty);
+// CHECK: load i8**
+// CHECK-NOT: getelementptr
+// CHECK: [[EMPTY_PTR:%[a-zA-Z0-9._]+]] = bitcast i8* {{%[a-zA-Z0-9._]+}} to %struct.Empty*
+
+  // It's conceivable that EMPTY_PTR may not actually be a valid pointer
+  // (e.g. it's at the very bottom of the stack and the next page is
+  // invalid). This doesn't matter provided it's never loaded (there's no
+  // well-defined way to tell), but it becomes a problem if we do try to use it.
+// CHECK-NOT: load %struct.Empty* [[EMPTY_PTR]]
+
+  int i = __builtin_va_arg(l, int);
+// CHECK: va_arg i8** {{%[a-zA-Z0-9._]+}}, i32
+
+  __builtin_va_end(l);
+  return i;
+}
diff --git a/test/CodeGenCXX/arm64.cpp b/test/CodeGenCXX/arm64.cpp
new file mode 100644
index 0000000..d0d4f4f
--- /dev/null
+++ b/test/CodeGenCXX/arm64.cpp
@@ -0,0 +1,88 @@
+// RUN: %clang_cc1 %s -triple=arm64-apple-ios -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=arm64-apple-ios -emit-llvm -o - | FileCheck -check-prefix=CHECK-GLOBALS %s
+
+// __cxa_guard_acquire argument is 64-bit
+// rdar://11540122
+struct A {
+  A();
+};
+
+void f() {
+  // CHECK: call i32 @__cxa_guard_acquire(i64*
+  static A a;
+}
+
+// ARM64 uses the C++11 definition of POD.
+// rdar://12650514
+namespace test1 {
+  // This class is POD in C++11 and cannot have objects allocated in
+  // its tail-padding.
+  struct ABase {};
+  struct A : ABase {
+    int x;
+    char c;
+  };
+
+  struct B : A {
+    char d;
+  };
+
+  int test() {
+    return sizeof(B);
+  }
+  // CHECK: define i32 @_ZN5test14testEv()
+  // CHECK: ret i32 12
+}
+
+namespace std {
+  class type_info;
+}
+
+// ARM64 uses string comparisons for what would otherwise be
+// default-visibility weak RTTI.  rdar://12650568
+namespace test2 {
+  struct A {
+    virtual void foo();
+  };
+  void A::foo() {}
+  // Tested below because these globals get kindof oddly rearranged.
+
+  struct __attribute__((visibility("hidden"))) B {};
+  const std::type_info &b0 = typeid(B);
+  // CHECK-GLOBALS: @_ZTSN5test21BE = linkonce_odr hidden constant
+  // CHECK-GLOBALS: @_ZTIN5test21BE = linkonce_odr hidden constant { {{.*}}, i8* getelementptr inbounds ([11 x i8]* @_ZTSN5test21BE, i32 0, i32 0) }
+
+  const std::type_info &b1 = typeid(B*);
+  // CHECK-GLOBALS: @_ZTSPN5test21BE = linkonce_odr hidden constant
+  // CHECK-GLOBALS: @_ZTIPN5test21BE = linkonce_odr hidden constant { {{.*}}, i8* getelementptr inbounds ([12 x i8]* @_ZTSPN5test21BE, i32 0, i32 0), i32 0, i8* bitcast
+
+  struct C {};
+  const std::type_info &c0 = typeid(C);
+  // CHECK-GLOBALS: @_ZTSN5test21CE = linkonce_odr hidden constant
+  // CHECK-GLOBALS: @_ZTIN5test21CE = linkonce_odr hidden constant { {{.*}}, i8* inttoptr (i64 add (i64 ptrtoint ([11 x i8]* @_ZTSN5test21CE to i64), i64 -9223372036854775808) to i8*) }
+
+  const std::type_info &c1 = typeid(C*);
+  // CHECK-GLOBALS: @_ZTSPN5test21CE = linkonce_odr hidden constant
+  // CHECK-GLOBALS: @_ZTIPN5test21CE = linkonce_odr hidden constant { {{.*}}, i8* inttoptr (i64 add (i64 ptrtoint ([12 x i8]* @_ZTSPN5test21CE to i64), i64 -9223372036854775808) to i8*), i32 0, i8* bitcast
+
+  // This class is explicitly-instantiated, but that instantiation
+  // doesn't guarantee to emit RTTI, so we can still demote the visibility.
+  template <class T> class D {};
+  template class D<int>;
+  const std::type_info &d0 = typeid(D<int>);
+  // CHECK-GLOBALS: @_ZTSN5test21DIiEE = linkonce_odr hidden constant
+  // CHECK-GLOBALS: @_ZTIN5test21DIiEE = linkonce_odr hidden constant { {{.*}}, i8* inttoptr (i64 add (i64 ptrtoint ([14 x i8]* @_ZTSN5test21DIiEE to i64), i64 -9223372036854775808) to i8*) }
+
+  // This class is explicitly-instantiated and *does* guarantee to
+  // emit RTTI, so we're stuck with having to use default visibility.
+  template <class T> class E {
+    virtual void foo() {}
+  };
+  template class E<int>;
+  // CHECK-GLOBALS: @_ZTSN5test21EIiEE = weak_odr constant [14 x i8]
+  // CHECK-GLOBALS: @_ZTIN5test21EIiEE = weak_odr constant { {{.*}}, i8* inttoptr (i64 add (i64 ptrtoint ([14 x i8]* @_ZTSN5test21EIiEE to i64), i64 -9223372036854775808) to i8*) }
+
+  // CHECK-GLOBALS: @_ZTSN5test21AE = constant [11 x i8]
+  // CHECK-GLOBALS: @_ZTIN5test21AE = constant { {{.*}}, i8* getelementptr inbounds ([11 x i8]* @_ZTSN5test21AE, i32 0, i32 0) }
+
+}
diff --git a/test/CodeGenCXX/array-construction.cpp b/test/CodeGenCXX/array-construction.cpp
index 645ad1d..53b81f2 100644
--- a/test/CodeGenCXX/array-construction.cpp
+++ b/test/CodeGenCXX/array-construction.cpp
@@ -1,8 +1,7 @@
-// REQUIRES: x86-registered-target,x86-64-registered-target
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s
-// RUN: FileCheck -check-prefix CHECK-LP64 --input-file=%t-64.s %s
-// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s
-// RUN: FileCheck -check-prefix CHECK-LP32 --input-file=%t-32.s %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -emit-llvm %s -o - | \
+// RUN: FileCheck %s
 
 extern "C" int printf(...);
 
@@ -31,7 +30,4 @@
               h, i, j, array[h][i][j].i, array[h][i][j].f);
 }
 
-// CHECK-LP64: callq    __ZN4xptoC1Ev
-
-// CHECK-LP32: calll     L__ZN4xptoC1Ev
-
+// CHECK: call void @_ZN4xptoC1Ev
diff --git a/test/CodeGenCXX/array-operator-delete-call.cpp b/test/CodeGenCXX/array-operator-delete-call.cpp
index 8d6f50f..890b142 100644
--- a/test/CodeGenCXX/array-operator-delete-call.cpp
+++ b/test/CodeGenCXX/array-operator-delete-call.cpp
@@ -1,8 +1,7 @@
-// REQUIRES: x86-registered-target,x86-64-registered-target
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s
-// RUN: FileCheck -check-prefix CHECK-LP64 --input-file=%t-64.s %s
-// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s
-// RUN: FileCheck -check-prefix CHECK-LP32 --input-file=%t-32.s %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -emit-llvm %s -o - | \
+// RUN: FileCheck %s
 
 extern "C" int printf(...);
 
@@ -58,7 +57,5 @@
 }
 COST c2;
 
-// CHECK-LP64: callq    __ZdaPv
-
-// CHECK-LP32: calll     L__ZdaPv
+// CHECK: call void @_ZdaPv
 
diff --git a/test/CodeGenCXX/atomicinit.cpp b/test/CodeGenCXX/atomicinit.cpp
index ee2e9e4..f453194 100644
--- a/test/CodeGenCXX/atomicinit.cpp
+++ b/test/CodeGenCXX/atomicinit.cpp
@@ -1,4 +1,10 @@
-// RUN: %clang_cc1 %s -emit-llvm -O1 -o - -triple=i686-apple-darwin9 | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -O1 -o - -triple=i686-apple-darwin9 -std=c++11 | FileCheck %s
+
+// CHECK-DAG: @_ZN7PR180978constant1aE = global {{.*}} { i16 1, i8 6, i8 undef }, align 4
+// CHECK-DAG: @_ZN7PR180978constant1bE = global {{.*}} { i16 2, i8 6, i8 undef }, align 4
+// CHECK-DAG: @_ZN7PR180978constant1cE = global {{.*}} { i16 3, i8 6, i8 undef }, align 4
+// CHECK-DAG: @_ZN7PR180978constant1yE = global {{.*}} { {{.*}} { i16 4, i8 6, i8 undef }, i32 5 }, align 4
+
 struct A {
   _Atomic(int) i;
   A(int j);
@@ -46,3 +52,51 @@
 // CHECK-NEXT: ret void
 AtomicBoolMember::AtomicBoolMember(bool b) : ab(b) { }
 
+namespace PR18097 {
+  namespace dynamic {
+    struct X {
+      X(int);
+      short n;
+      char c;
+    };
+
+    // CHECK-LABEL: define {{.*}} @__cxx_global_var_init
+    // CHECK: call void @_ZN7PR180977dynamic1XC1Ei({{.*}}* @_ZN7PR180977dynamic1aE, i32 1)
+    _Atomic(X) a = X(1);
+
+    // CHECK-LABEL: define {{.*}} @__cxx_global_var_init
+    // CHECK: call void @_ZN7PR180977dynamic1XC1Ei({{.*}}* @_ZN7PR180977dynamic1bE, i32 2)
+    _Atomic(X) b(X(2));
+
+    // CHECK-LABEL: define {{.*}} @__cxx_global_var_init
+    // CHECK: call void @_ZN7PR180977dynamic1XC1Ei({{.*}}* @_ZN7PR180977dynamic1cE, i32 3)
+    _Atomic(X) c{X(3)};
+
+    struct Y {
+      _Atomic(X) a;
+      _Atomic(int) b;
+    };
+    // CHECK-LABEL: define {{.*}} @__cxx_global_var_init
+    // CHECK: call void @_ZN7PR180977dynamic1XC1Ei({{.*}}* getelementptr inbounds ({{.*}}* @_ZN7PR180977dynamic1yE, i32 0, i32 0), i32 4)
+    // CHECK: store i32 5, i32* getelementptr inbounds ({{.*}}* @_ZN7PR180977dynamic1yE, i32 0, i32 1)
+    Y y = { X(4), 5 };
+  }
+
+  // CHECKs at top of file.
+  namespace constant {
+    struct X {
+      constexpr X(int n) : n(n) {}
+      short n;
+      char c = 6;
+    };
+    _Atomic(X) a = X(1);
+    _Atomic(X) b(X(2));
+    _Atomic(X) c{X(3)};
+
+    struct Y {
+      _Atomic(X) a;
+      _Atomic(int) b;
+    };
+    Y y = { X(4), 5 };
+  }
+}
diff --git a/test/CodeGenCXX/attr-cleanup.cpp b/test/CodeGenCXX/attr-cleanup.cpp
index ff15b03..18a7798 100644
--- a/test/CodeGenCXX/attr-cleanup.cpp
+++ b/test/CodeGenCXX/attr-cleanup.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -o - %s | FileCheck %s
 
 namespace N {
   void free(void *i) {}
diff --git a/test/CodeGenCXX/attr-used.cpp b/test/CodeGenCXX/attr-used.cpp
index 2c82184..8617346 100644
--- a/test/CodeGenCXX/attr-used.cpp
+++ b/test/CodeGenCXX/attr-used.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -o - %s | FileCheck %s
 
 // <rdar://problem/8684363>: clang++ not respecting __attribute__((used)) on destructors
 struct X0 {
@@ -7,3 +7,21 @@
   // CHECK: define linkonce_odr {{.*}} @_ZN2X0D1Ev
   __attribute__((used)) ~X0() {}
 };
+
+// PR19743: not emitting __attribute__((used)) inline methods in nested classes.
+struct X1 {
+  struct Nested {
+    // CHECK: define linkonce_odr {{.*}} @_ZN2X16Nested1fEv
+    void __attribute__((used)) f() {}
+  };
+};
+
+struct X2 {
+  // We must delay emission of bar() until foo() has had its body parsed,
+  // otherwise foo() would not be emitted.
+  void __attribute__((used)) bar() { foo(); }
+  void foo() { }
+
+  // CHECK: define linkonce_odr {{.*}} @_ZN2X23barEv
+  // CHECK: define linkonce_odr {{.*}} @_ZN2X23fooEv
+};
diff --git a/test/CodeGenCXX/bitfield-layout.cpp b/test/CodeGenCXX/bitfield-layout.cpp
index 646300a..46f4111 100644
--- a/test/CodeGenCXX/bitfield-layout.cpp
+++ b/test/CodeGenCXX/bitfield-layout.cpp
@@ -12,7 +12,7 @@
   int : 6;
 } t2;
 
-// CHECK-LP64: %union.Test3 = type { [2 x i8] }
+// CHECK-LP64: %union.Test3 = type { i16 }
 union Test3 {
   int : 9;
 } t3;
diff --git a/test/CodeGenCXX/bitfield.cpp b/test/CodeGenCXX/bitfield.cpp
index 2c454b0..fafeffe 100644
--- a/test/CodeGenCXX/bitfield.cpp
+++ b/test/CodeGenCXX/bitfield.cpp
@@ -298,7 +298,7 @@
 #endif
   unsigned read(Base* s) {
     // FIXME: We should widen this load as long as the function isn't being
-    // instrumented by thread-sanitizer.
+    // instrumented by ThreadSanitizer.
     //
     // CHECK-X86-64-LABEL: define i32 @_ZN2N44read
     // CHECK-X86-64:   %[[gep:.*]] = getelementptr inbounds {{.*}}* %{{.*}}, i32 0, i32 1
@@ -378,8 +378,8 @@
   // Zero-length bitfields partition the memory locations of bitfields for the
   // purposes of the memory model. That means stores must not span zero-length
   // bitfields and loads may only span them when we are not instrumenting with
-  // thread sanitizer.
-  // FIXME: We currently don't widen loads even without thread sanitizer, even
+  // ThreadSanitizer.
+  // FIXME: We currently don't widen loads even without ThreadSanitizer, even
   // though we could.
   struct S {
     unsigned b1 : 24;
@@ -426,3 +426,55 @@
     s->b2 = x;
   }
 }
+
+namespace N7 {
+  // Similar to N4 except that this adds a virtual base to the picture. (PR18430)
+  // Do NOT widen loads and stores to bitfields into padding at the end of
+  // a class which might end up with members inside of it when inside a derived
+  // class.
+  struct B1 {
+    virtual void f();
+    unsigned b1 : 24;
+  };
+  struct B2 : virtual B1 {
+    virtual ~B2();
+    unsigned b : 24;
+  };
+  // Imagine some other translation unit introduces:
+#if 0
+  struct Derived : public B2 {
+    char c;
+  };
+#endif
+  unsigned read(B2* s) {
+    // FIXME: We should widen this load as long as the function isn't being
+    // instrumented by ThreadSanitizer.
+    //
+    // CHECK-X86-64-LABEL: define i32 @_ZN2N74read
+    // CHECK-X86-64:   %[[gep:.*]] = getelementptr inbounds {{.*}}* %{{.*}}, i32 0, i32 1
+    // CHECK-X86-64:   %[[ptr:.*]] = bitcast [3 x i8]* %[[gep]] to i24*
+    // CHECK-X86-64:   %[[val:.*]] = load i24* %[[ptr]]
+    // CHECK-X86-64:   %[[ext:.*]] = zext i24 %[[val]] to i32
+    // CHECK-X86-64:                 ret i32 %[[ext]]
+    // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N74read
+    // CHECK-PPC64:   %[[gep:.*]] = getelementptr inbounds {{.*}}* %{{.*}}, i32 0, i32 1
+    // CHECK-PPC64:   %[[ptr:.*]] = bitcast [3 x i8]* %[[gep]] to i24*
+    // CHECK-PPC64:   %[[val:.*]] = load i24* %[[ptr]]
+    // CHECK-PPC64:   %[[ext:.*]] = zext i24 %[[val]] to i32
+    // CHECK-PPC64:                 ret i32 %[[ext]]
+    return s->b;
+  }
+  void write(B2* s, unsigned x) {
+    // CHECK-X86-64-LABEL: define void @_ZN2N75write
+    // CHECK-X86-64:   %[[gep:.*]] = getelementptr inbounds {{.*}}* %{{.*}}, i32 0, i32 1
+    // CHECK-X86-64:   %[[ptr:.*]] = bitcast [3 x i8]* %[[gep]] to i24*
+    // CHECK-X86-64:   %[[new:.*]] = trunc i32 %{{.*}} to i24
+    // CHECK-X86-64:                 store i24 %[[new]], i24* %[[ptr]]
+    // CHECK-PPC64-LABEL: define void @_ZN2N75write
+    // CHECK-PPC64:   %[[gep:.*]] = getelementptr inbounds {{.*}}* %{{.*}}, i32 0, i32 1
+    // CHECK-PPC64:   %[[ptr:.*]] = bitcast [3 x i8]* %[[gep]] to i24*
+    // CHECK-PPC64:   %[[new:.*]] = trunc i32 %{{.*}} to i24
+    // CHECK-PPC64:                 store i24 %[[new]], i24* %[[ptr]]
+    s->b = x;
+  }
+}
diff --git a/test/CodeGenCXX/block-byref-cxx-objc.cpp b/test/CodeGenCXX/block-byref-cxx-objc.cpp
index 616fd67..5c35ad7 100644
--- a/test/CodeGenCXX/block-byref-cxx-objc.cpp
+++ b/test/CodeGenCXX/block-byref-cxx-objc.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - -fblocks | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o - -fblocks | FileCheck %s
 // rdar://8594790
 
 struct A {
diff --git a/test/CodeGenCXX/block-in-ctor-dtor.cpp b/test/CodeGenCXX/block-in-ctor-dtor.cpp
index bd37d44..0dc0ab0 100644
--- a/test/CodeGenCXX/block-in-ctor-dtor.cpp
+++ b/test/CodeGenCXX/block-in-ctor-dtor.cpp
@@ -40,9 +40,9 @@
 // CHECK-LABEL: define internal void @___ZN4ZoneC2Ev_block_invoke_
 // CHECK-LABEL: define internal void @___ZN4ZoneD2Ev_block_invoke
 // CHECK-LABEL: define internal void @___ZN4ZoneD2Ev_block_invoke_
-// CHECK-LABEL: define internal void @___ZN1XC1Ev_block_invoke
-// CHECK-LABEL: define internal void @___ZN1XC1Ev_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/block.cpp b/test/CodeGenCXX/block.cpp
index 619d8b0..aa35668 100644
--- a/test/CodeGenCXX/block.cpp
+++ b/test/CodeGenCXX/block.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - -fblocks 
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -emit-llvm -o - -fblocks 
+// RUN: %clang_cc1 %s -triple %ms_abi_triple -fno-rtti -emit-llvm -o - -fblocks 
 // Just test that this doesn't crash the compiler...
 
 void func(void*);
diff --git a/test/CodeGenCXX/blocks-cxx11.cpp b/test/CodeGenCXX/blocks-cxx11.cpp
index 9ff5826..10d1c65 100644
--- a/test/CodeGenCXX/blocks-cxx11.cpp
+++ b/test/CodeGenCXX/blocks-cxx11.cpp
@@ -106,7 +106,7 @@
   // CHECK:      [[TO_DESTROY:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
   // CHECK:      [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
   // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[LAMBDA_T]]* [[THIS]], i32 0, i32 0
-  // CHECK-NEXT: call void @_ZN20test_block_in_lambda1AC1ERKS0_({{.*}}* [[T0]], {{.*}}* [[T1]])
+  // CHECK-NEXT: call void @_ZN20test_block_in_lambda1AC1ERKS0_({{.*}}* [[T0]], {{.*}}* dereferenceable({{[0-9]+}}) [[T1]])
   // CHECK-NEXT: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to void ()*
   // CHECK-NEXT: call void @_ZN20test_block_in_lambda9takeBlockEU13block_pointerFvvE(void ()* [[T0]])
   // CHECK-NEXT: call void @_ZN20test_block_in_lambda1AD1Ev({{.*}}* [[TO_DESTROY]])
diff --git a/test/CodeGenCXX/blocks.cpp b/test/CodeGenCXX/blocks.cpp
index 8a6fdac..6b11083 100644
--- a/test/CodeGenCXX/blocks.cpp
+++ b/test/CodeGenCXX/blocks.cpp
@@ -164,7 +164,7 @@
 
   // CHECK-NOT:  br
   // CHECK:      [[CAPTURE:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
-  // CHECK-NEXT: call void @_ZN5test51AC1ERKS0_([[A]]* [[CAPTURE]], [[A]]* [[X]])
+  // CHECK-NEXT: call void @_ZN5test51AC1ERKS0_([[A]]* [[CAPTURE]], [[A]]* dereferenceable({{[0-9]+}}) [[X]])
   // CHECK-NEXT: store i1 true, i1* [[CLEANUP_ACTIVE]]
   // CHECK-NEXT: bitcast [[BLOCK_T]]* [[BLOCK]] to void ()*
   // CHECK-NEXT: br label
diff --git a/test/CodeGenCXX/c-linkage.cpp b/test/CodeGenCXX/c-linkage.cpp
index 1607623..2f8729e 100644
--- a/test/CodeGenCXX/c-linkage.cpp
+++ b/test/CodeGenCXX/c-linkage.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -o - %s | FileCheck %s
 // pr6644
 
 extern "C" {
@@ -10,7 +10,7 @@
   }
 }
 
-// CHECK-LABEL: define void @_ZN1N1X1fEv
+// CHECK-LABEL: define {{.*}}void @_ZN1N1X1fEv
 
 extern "C" {
   static void test2_f() {
diff --git a/test/CodeGenCXX/call-arg-zero-temp.cpp b/test/CodeGenCXX/call-arg-zero-temp.cpp
index 14238f2..beef2fd 100644
--- a/test/CodeGenCXX/call-arg-zero-temp.cpp
+++ b/test/CodeGenCXX/call-arg-zero-temp.cpp
@@ -1,4 +1,4 @@
-// REQUIRES: x86-registered-target,x86-64-registered-target
+// REQUIRES: x86-registered-target
 // RUN: %clang_cc1 -triple x86_64-apple-darwin -S %s -o %t-64.s
 // RUN: FileCheck -check-prefix CHECK-LP64 --input-file=%t-64.s %s
 // RUN: %clang_cc1 -triple i386-apple-darwin -S %s -o %t-32.s
diff --git a/test/CodeGenCXX/captured-statements.cpp b/test/CodeGenCXX/captured-statements.cpp
index 2843c2b6..fb35446 100644
--- a/test/CodeGenCXX/captured-statements.cpp
+++ b/test/CodeGenCXX/captured-statements.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o %t
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -emit-llvm %s -o %t
 // RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-1
 // RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-2
 // RUN: FileCheck %s -input-file=%t -check-prefix=CHECK-3
diff --git a/test/CodeGenCXX/cast-conversion.cpp b/test/CodeGenCXX/cast-conversion.cpp
index 5565f65..ce8f820 100644
--- a/test/CodeGenCXX/cast-conversion.cpp
+++ b/test/CodeGenCXX/cast-conversion.cpp
@@ -1,8 +1,7 @@
-// REQUIRES: x86-registered-target,x86-64-registered-target
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s
-// RUN: FileCheck -check-prefix CHECK-LP64 --input-file=%t-64.s %s
-// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s
-// RUN: FileCheck -check-prefix CHECK-LP32 --input-file=%t-32.s %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -emit-llvm %s -o - |   \
+// RUN: FileCheck %s
 
 struct A {
   A(int);
@@ -18,16 +17,9 @@
   static_cast<B>(10);
 }
 
-// CHECK-LP64: callq    __ZN1AC1Ei
-// CHECK-LP64: callq    __ZN1BC1E1A
-// CHECK-LP64: callq    __ZN1AC1Ei
-// CHECK-LP64: callq    __ZN1BC1E1A
-// CHECK-LP64: callq    __ZN1AC1Ei
-// CHECK-LP64: callq    __ZN1BC1E1A
-
-// CHECK-LP32: calll     L__ZN1AC1Ei
-// CHECK-LP32: calll     L__ZN1BC1E1A
-// CHECK-LP32: calll     L__ZN1AC1Ei
-// CHECK-LP32: calll     L__ZN1BC1E1A
-// CHECK-LP32: calll     L__ZN1AC1Ei
-// CHECK-LP32: calll     L__ZN1BC1E1A
+// CHECK: call void @_ZN1AC1Ei
+// CHECK: call void @_ZN1BC1E1A
+// CHECK: call void @_ZN1AC1Ei
+// CHECK: call void @_ZN1BC1E1A
+// CHECK: call void @_ZN1AC1Ei
+// CHECK: call void @_ZN1BC1E1A
diff --git a/test/CodeGenCXX/catch-undef-behavior.cpp b/test/CodeGenCXX/catch-undef-behavior.cpp
index 338da57..333855d 100644
--- a/test/CodeGenCXX/catch-undef-behavior.cpp
+++ b/test/CodeGenCXX/catch-undef-behavior.cpp
@@ -1,4 +1,6 @@
 // RUN: %clang_cc1 -std=c++11 -fsanitize=signed-integer-overflow,integer-divide-by-zero,float-divide-by-zero,shift,unreachable,return,vla-bound,alignment,null,vptr,object-size,float-cast-overflow,bool,enum,array-bounds,function -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -fsanitize=vptr,address -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK-ASAN
+// RUN: %clang_cc1 -std=c++11 -fsanitize=vptr -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=DOWNCAST-NULL
 
 struct S {
   double d;
@@ -6,9 +8,15 @@
   virtual int f();
 };
 
+// Check that type descriptor global is not modified by ASan.
+// CHECK-ASAN: [[TYPE_DESCR:@[0-9]+]] = private unnamed_addr constant { i16, i16, [4 x i8] } { i16 -1, i16 0, [4 x i8] c"'S'\00" }
+
+// Check that type mismatch handler is not modified by ASan.
+// CHECK-ASAN: private unnamed_addr global { { [{{.*}} x i8]*, i32, i32 }, { i16, i16, [4 x i8] }*, i8*, i8 } { {{.*}}, { i16, i16, [4 x i8] }* [[TYPE_DESCR]], {{.*}} }
+
 struct T : S {};
 
-// CHECK: @_Z17reference_binding
+// CHECK-LABEL: @_Z17reference_binding
 void reference_binding(int *p, S *q) {
   // C++ core issue 453: If an lvalue to which a reference is directly bound
   // designates neither an existing object or function of an appropriate type,
@@ -30,7 +38,8 @@
   S &r2 = *q;
 }
 
-// CHECK: @_Z13member_access
+// CHECK-LABEL: @_Z13member_access
+// CHECK-ASAN-LABEL: @_Z13member_access
 void member_access(S *p) {
   // (1a) Check 'p' is appropriately sized and aligned for member access.
 
@@ -117,7 +126,7 @@
   k = p->f();
 }
 
-// CHECK: @_Z12lsh_overflow
+// CHECK-LABEL: @_Z12lsh_overflow
 int lsh_overflow(int a, int b) {
   // CHECK: %[[INBOUNDS:.*]] = icmp ule i32 %[[RHS:.*]], 31
   // CHECK-NEXT: br i1 %[[INBOUNDS]]
@@ -142,13 +151,13 @@
   return a << b;
 }
 
-// CHECK: @_Z9no_return
+// CHECK-LABEL: @_Z9no_return
 int no_return() {
   // CHECK:      call void @__ubsan_handle_missing_return(i8* bitcast ({{.*}}* @{{.*}} to i8*)) [[NR_NUW:#[0-9]+]]
   // CHECK-NEXT: unreachable
 }
 
-// CHECK: @_Z9sour_bool
+// CHECK-LABEL: @_Z9sour_bool
 bool sour_bool(bool *p) {
   // CHECK: %[[OK:.*]] = icmp ule i8 {{.*}}, 1
   // CHECK: br i1 %[[OK]]
@@ -160,7 +169,7 @@
 enum E2 { e2a = -1, e2b = 64 } e2;
 enum E3 { e3a = (1u << 31) - 1 } e3;
 
-// CHECK: @_Z14bad_enum_value
+// CHECK-LABEL: @_Z14bad_enum_value
 int bad_enum_value() {
   // CHECK: %[[E1:.*]] = icmp ule i32 {{.*}}, 127
   // CHECK: br i1 %[[E1]]
@@ -181,11 +190,16 @@
   return a + b + c;
 }
 
-// CHECK: @_Z20bad_downcast_pointer
+// CHECK-LABEL: @_Z20bad_downcast_pointer
+// DOWNCAST-NULL-LABEL: @_Z20bad_downcast_pointer
 void bad_downcast_pointer(S *p) {
   // CHECK: %[[NONNULL:.*]] = icmp ne {{.*}}, null
   // CHECK: br i1 %[[NONNULL]],
 
+  // A null poiner access is guarded without -fsanitize=null.
+  // DOWNCAST-NULL: %[[NONNULL:.*]] = icmp ne {{.*}}, null
+  // DOWNCAST-NULL: br i1 %[[NONNULL]],
+
   // CHECK: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64.p0i8(
   // CHECK: %[[E1:.*]] = icmp uge i64 %[[SIZE]], 24
   // CHECK: %[[MISALIGN:.*]] = and i64 %{{.*}}, 7
@@ -203,7 +217,7 @@
   (void) static_cast<T*>(p);
 }
 
-// CHECK: @_Z22bad_downcast_reference
+// CHECK-LABEL: @_Z22bad_downcast_reference
 void bad_downcast_reference(S &p) {
   // CHECK: %[[E1:.*]] = icmp ne {{.*}}, null
   // CHECK-NOT: br i1
@@ -225,7 +239,7 @@
   (void) static_cast<T&>(p);
 }
 
-// CHECK: @_Z11array_index
+// CHECK-LABEL: @_Z11array_index
 int array_index(const int (&a)[4], int n) {
   // CHECK: %[[K1_OK:.*]] = icmp ult i64 %{{.*}}, 4
   // CHECK: br i1 %[[K1_OK]]
@@ -250,7 +264,7 @@
   return k1 + *r1 + k2;
 }
 
-// CHECK: @_Z17multi_array_index
+// CHECK-LABEL: @_Z17multi_array_index
 int multi_array_index(int n, int m) {
   int arr[4][6];
 
@@ -264,7 +278,7 @@
   return arr[n][m];
 }
 
-// CHECK: @_Z11array_arith
+// CHECK-LABEL: @_Z11array_arith
 int array_arith(const int (&a)[4], int n) {
   // CHECK: %[[K1_OK:.*]] = icmp ule i64 %{{.*}}, 4
   // CHECK: br i1 %[[K1_OK]]
@@ -283,7 +297,7 @@
   int a1[5];
   int a2[1];
 };
-// CHECK: @_Z18struct_array_index
+// CHECK-LABEL: @_Z18struct_array_index
 int struct_array_index(ArrayMembers *p, int n) {
   // CHECK: %[[IDX_OK:.*]] = icmp ult i64 %{{.*}}, 5
   // CHECK: br i1 %[[IDX_OK]]
@@ -291,21 +305,21 @@
   return p->a1[n];
 }
 
-// CHECK: @_Z16flex_array_index
+// CHECK-LABEL: @_Z16flex_array_index
 int flex_array_index(ArrayMembers *p, int n) {
   // CHECK-NOT: call void @__ubsan_handle_out_of_bounds(
   return p->a2[n];
 }
 
 extern int incomplete[];
-// CHECK: @_Z22incomplete_array_index
+// CHECK-LABEL: @_Z22incomplete_array_index
 int incomplete_array_index(int n) {
   // CHECK-NOT: call void @__ubsan_handle_out_of_bounds(
   return incomplete[n];
 }
 
 typedef __attribute__((ext_vector_type(4))) int V4I;
-// CHECK: @_Z12vector_index
+// CHECK-LABEL: @_Z12vector_index
 int vector_index(V4I v, int n) {
   // CHECK: %[[IDX_OK:.*]] = icmp ult i64 %{{.*}}, 4
   // CHECK: br i1 %[[IDX_OK]]
@@ -313,7 +327,7 @@
   return v[n];
 }
 
-// CHECK: @_Z12string_index
+// CHECK-LABEL: @_Z12string_index
 char string_index(int n) {
   // CHECK: %[[IDX_OK:.*]] = icmp ult i64 %{{.*}}, 6
   // CHECK: br i1 %[[IDX_OK]]
@@ -357,7 +371,7 @@
   // CHECK-NEXT: br i1 [[AND]]
 }
 
-// CHECK-LABEL: define void @_Z18downcast_referenceR1B(%class.B* %b)
+// CHECK-LABEL: define void @_Z18downcast_referenceR1B(%class.B* dereferenceable({{[0-9]+}}) %b)
 void downcast_reference(B &b) {
   (void) static_cast<C&>(b);
   // Alignment check from EmitTypeCheck(TCK_DowncastReference, ...)
diff --git a/test/CodeGenCXX/class-layout.cpp b/test/CodeGenCXX/class-layout.cpp
index 21e1a2b..d7d84a8 100644
--- a/test/CodeGenCXX/class-layout.cpp
+++ b/test/CodeGenCXX/class-layout.cpp
@@ -39,7 +39,7 @@
     char a;
   };
 
-  // CHECK: %"struct.Test5::B" = type { [9 x i8], i8, i8, [5 x i8] }
+  // CHECK: %"struct.Test5::B" = type {  %"struct.Test5::A.base", i8, i8, [5 x i8] }
   struct B : A {
     char b : 1;
     char c;
@@ -91,3 +91,12 @@
   B* b;
   #pragma pack ()
 }
+
+// Shouldn't crash.
+namespace Test8 {
+  struct A {};
+  struct D { int a; };
+  struct B : virtual D, A { };
+  struct C : B, A { void f() {} };
+  C c;
+}
diff --git a/test/CodeGenCXX/conditional-gnu-ext.cpp b/test/CodeGenCXX/conditional-gnu-ext.cpp
index 44ebf98..3a61a63 100644
--- a/test/CodeGenCXX/conditional-gnu-ext.cpp
+++ b/test/CodeGenCXX/conditional-gnu-ext.cpp
@@ -83,7 +83,7 @@
     // CHECK-NEXT: [[T0:%.*]] = load [[B]]** [[X]]
     // CHECK-NEXT: [[BOOL:%.*]] = call zeroext i1 @_ZN5test31BcvbEv([[B]]* [[T0]])
     // CHECK-NEXT: br i1 [[BOOL]]
-    // CHECK:      call void @_ZN5test31BC1ERKS0_([[B]]* [[RESULT:%.*]], [[B]]* [[T0]])
+    // CHECK:      call void @_ZN5test31BC1ERKS0_([[B]]* [[RESULT:%.*]], [[B]]* dereferenceable({{[0-9]+}}) [[T0]])
     // CHECK-NEXT: br label
     // CHECK:      call void @_ZN5test31BC1Ev([[B]]* [[RESULT]])
     // CHECK-NEXT: br label
@@ -97,7 +97,7 @@
     // CHECK-NEXT: call  void @_ZN5test312test1_helperEv([[B]]* sret [[TEMP]])
     // CHECK-NEXT: [[BOOL:%.*]] = call zeroext i1 @_ZN5test31BcvbEv([[B]]* [[TEMP]])
     // CHECK-NEXT: br i1 [[BOOL]]
-    // CHECK:      call void @_ZN5test31BC1ERKS0_([[B]]* [[RESULT:%.*]], [[B]]* [[TEMP]])
+    // CHECK:      call void @_ZN5test31BC1ERKS0_([[B]]* [[RESULT:%.*]], [[B]]* dereferenceable({{[0-9]+}}) [[TEMP]])
     // CHECK-NEXT: br label
     // CHECK:      call void @_ZN5test31BC1Ev([[B]]* [[RESULT]])
     // CHECK-NEXT: br label
diff --git a/test/CodeGenCXX/const-base-cast.cpp b/test/CodeGenCXX/const-base-cast.cpp
index 320c790..dd980d5 100644
--- a/test/CodeGenCXX/const-base-cast.cpp
+++ b/test/CodeGenCXX/const-base-cast.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
 
 // Check that the following construct, which is similar to one which occurs
 // in Firefox, is folded correctly.
diff --git a/test/CodeGenCXX/const-global-linkage.cpp b/test/CodeGenCXX/const-global-linkage.cpp
index df78fdd..e1e9321 100644
--- a/test/CodeGenCXX/const-global-linkage.cpp
+++ b/test/CodeGenCXX/const-global-linkage.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
 
 const int x = 10;
 const int y = 20;
diff --git a/test/CodeGenCXX/const-init-cxx11.cpp b/test/CodeGenCXX/const-init-cxx11.cpp
index d21e911..f671e0a 100644
--- a/test/CodeGenCXX/const-init-cxx11.cpp
+++ b/test/CodeGenCXX/const-init-cxx11.cpp
@@ -382,17 +382,22 @@
 namespace UnemittedTemporaryDecl {
   constexpr int &&ref = 0;
   extern constexpr int &ref2 = ref;
-  // CHECK: @_ZGRN22UnemittedTemporaryDecl3refE = private global i32 0
+  // CHECK: @_ZGRN22UnemittedTemporaryDecl3refE_ = private global i32 0
 
   // FIXME: This declaration should not be emitted -- it isn't odr-used.
   // CHECK: @_ZN22UnemittedTemporaryDecl3refE
 
-  // CHECK: @_ZN22UnemittedTemporaryDecl4ref2E = constant i32* @_ZGRN22UnemittedTemporaryDecl3refE
+  // CHECK: @_ZN22UnemittedTemporaryDecl4ref2E = constant i32* @_ZGRN22UnemittedTemporaryDecl3refE_
 }
 
 // CHECK: @_ZZN12LocalVarInit3aggEvE1a = internal constant {{.*}} i32 101
 // CHECK: @_ZZN12LocalVarInit4ctorEvE1a = internal constant {{.*}} i32 102
 // CHECK: @_ZZN12LocalVarInit8mutable_EvE1a = private unnamed_addr constant {{.*}} i32 103
+// CHECK: @_ZGRN33ClassTemplateWithStaticDataMember1SIvE1aE_ = linkonce_odr constant i32 5
+// CHECK: @_ZN33ClassTemplateWithStaticDataMember3useE = constant i32* @_ZGRN33ClassTemplateWithStaticDataMember1SIvE1aE_
+// CHECK: @_ZGRN39ClassTemplateWithHiddenStaticDataMember1SIvE1aE_ = linkonce_odr hidden constant i32 5
+// CHECK: @_ZN39ClassTemplateWithHiddenStaticDataMember3useE = constant i32* @_ZGRN39ClassTemplateWithHiddenStaticDataMember1SIvE1aE_
+// CHECK: @_ZGRZN20InlineStaticConstRef3funEvE1i_ = linkonce_odr constant i32 10
 
 // Constant initialization tests go before this point,
 // dynamic initialization tests go after.
@@ -527,10 +532,10 @@
     // CHECK: call void @_ZN13InitFromConst7consumeIdEEvT_(double 4.300000e+00)
     consume(d);
 
-    // CHECK: call void @_ZN13InitFromConst7consumeIRKNS_1SEEEvT_(%"struct.InitFromConst::S"* @_ZN13InitFromConstL1sE)
+    // CHECK: call void @_ZN13InitFromConst7consumeIRKNS_1SEEEvT_(%"struct.InitFromConst::S"* dereferenceable({{[0-9]+}}) @_ZN13InitFromConstL1sE)
     consume<const S&>(s);
 
-    // CHECK: call void @_ZN13InitFromConst7consumeIRKNS_1SEEEvT_(%"struct.InitFromConst::S"* @_ZN13InitFromConstL1sE)
+    // CHECK: call void @_ZN13InitFromConst7consumeIRKNS_1SEEEvT_(%"struct.InitFromConst::S"* dereferenceable({{[0-9]+}}) @_ZN13InitFromConstL1sE)
     consume<const S&>(r);
 
     // CHECK: call void @_ZN13InitFromConst7consumeIPKNS_1SEEEvT_(%"struct.InitFromConst::S"* @_ZN13InitFromConstL1sE)
@@ -552,3 +557,32 @@
   // CHECK: call {{.*}} @_ZN4Null4nullEv(
   int S::*q = null();
 }
+
+namespace InlineStaticConstRef {
+  inline const int &fun() {
+    static const int &i = 10;
+    return i;
+    // CHECK: ret i32* @_ZGRZN20InlineStaticConstRef3funEvE1i_
+  }
+  const int &use = fun();
+}
+
+namespace ClassTemplateWithStaticDataMember {
+  template <typename T>
+  struct S {
+    static const int &a;
+  };
+  template <typename T>
+  const int &S<T>::a = 5;
+  const int &use = S<void>::a;
+}
+
+namespace ClassTemplateWithHiddenStaticDataMember {
+  template <typename T>
+  struct S {
+    __attribute__((visibility("hidden"))) static const int &a;
+  };
+  template <typename T>
+  const int &S<T>::a = 5;
+  const int &use = S<void>::a;
+}
diff --git a/test/CodeGenCXX/const-init-cxx1y.cpp b/test/CodeGenCXX/const-init-cxx1y.cpp
index 978c428..9348b43 100644
--- a/test/CodeGenCXX/const-init-cxx1y.cpp
+++ b/test/CodeGenCXX/const-init-cxx1y.cpp
@@ -1,4 +1,5 @@
-// RUN: not %clang_cc1 -verify -triple x86_64-apple-darwin -emit-llvm -o - %s -std=c++1y | FileCheck %s
+// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin -emit-llvm -o - %s -std=c++1y | FileCheck %s
+// expected-no-diagnostics
 
 struct A {
   constexpr A() : n(1) {}
@@ -22,26 +23,64 @@
   struct A { int &&temporary; int x; };
   constexpr int f(int &r) { r *= 9; return r - 12; }
   A a = { 6, f(a.temporary) };
-  // CHECK: @_ZGRN21ModifyStaticTemporary1aE = private global i32 54
-  // CHECK: @_ZN21ModifyStaticTemporary1aE = global {{.*}} i32* @_ZGRN21ModifyStaticTemporary1aE, i32 42
+  // CHECK: @_ZGRN21ModifyStaticTemporary1aE_ = private global i32 54
+  // CHECK: @_ZN21ModifyStaticTemporary1aE = global {{.*}} i32* @_ZGRN21ModifyStaticTemporary1aE_, i32 42
 
   A b = { 7, ++b.temporary };
-  // CHECK: @_ZGRN21ModifyStaticTemporary1bE = private global i32 8
-  // CHECK: @_ZN21ModifyStaticTemporary1bE = global {{.*}} i32* @_ZGRN21ModifyStaticTemporary1bE, i32 8
+  // CHECK: @_ZGRN21ModifyStaticTemporary1bE_ = private global i32 8
+  // CHECK: @_ZN21ModifyStaticTemporary1bE = global {{.*}} i32* @_ZGRN21ModifyStaticTemporary1bE_, i32 8
 
   // Can't emit all of 'c' as a constant here, so emit the initial value of
   // 'c.temporary', not the value as modified by the partial evaluation within
   // the initialization of 'c.x'.
   A c = { 10, (++c.temporary, b.x) };
-  // CHECK: @_ZGRN21ModifyStaticTemporary1cE = private global i32 10
+  // CHECK: @_ZGRN21ModifyStaticTemporary1cE_ = private global i32 10
   // CHECK: @_ZN21ModifyStaticTemporary1cE = global {{.*}} zeroinitializer
 }
 
+// CHECK: @_ZGRN28VariableTemplateWithConstRef1iIvEE_ = linkonce_odr constant i32 5, align 4
+// CHECK: @_ZN28VariableTemplateWithConstRef3useE = constant i32* @_ZGRN28VariableTemplateWithConstRef1iIvEE_
+namespace VariableTemplateWithConstRef {
+  template <typename T>
+  const int &i = 5;
+  const int &use = i<void>;
+}
+
+// CHECK: @_ZGRN34HiddenVariableTemplateWithConstRef1iIvEE_ = linkonce_odr hidden constant i32 5, align 4
+// CHECK: @_ZN34HiddenVariableTemplateWithConstRef3useE = constant i32* @_ZGRN34HiddenVariableTemplateWithConstRef1iIvEE_
+namespace HiddenVariableTemplateWithConstRef {
+  template <typename T>
+  __attribute__((visibility("hidden"))) const int &i = 5;
+  const int &use = i<void>;
+}
+
+// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE1_ = linkonce_odr constant i32 1
+// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE0_ = linkonce_odr global {{.*}} { i32* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE1_ }
+// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE3_ = linkonce_odr constant i32 2
+// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE2_ = linkonce_odr global {{.*}} { i32* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE3_ }
+// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE5_ = linkonce_odr constant i32 3
+// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE4_ = linkonce_odr global {{.*}} { i32* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE5_ }
+// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE7_ = linkonce_odr constant i32 4
+// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE6_ = linkonce_odr global {{.*}} { i32* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE7_ }
+// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE_ = linkonce_odr global %"struct.VariableTemplateWithPack::S" { {{.*}}* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE0_, {{.*}}* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE2_, {{.*}}* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE4_, {{.*}}* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE6_ }
+// CHECK: @_ZN24VariableTemplateWithPack1pE = global {{.*}} @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE_
+namespace VariableTemplateWithPack {
+  struct A {
+    const int &r;
+  };
+  struct S {
+    A &&a, &&b, &&c, &&d;
+  };
+  template <int... N>
+  S &&s = {A{N}...};
+  S *p = &s<1, 2, 3, 4>;
+}
+
 // CHECK: __cxa_atexit({{.*}} @_ZN1BD1Ev {{.*}} @b
 
 // CHECK: define
-// CHECK-NOT: @_ZGRN21ModifyStaticTemporary1cE
-// CHECK: store {{.*}} @_ZGRN21ModifyStaticTemporary1cE, {{.*}} @_ZN21ModifyStaticTemporary1cE
+// CHECK-NOT: @_ZGRN21ModifyStaticTemporary1cE_
+// CHECK: store {{.*}} @_ZGRN21ModifyStaticTemporary1cE_, {{.*}} @_ZN21ModifyStaticTemporary1cE
 // CHECK: add
 // CHECK: store
 // CHECK: load {{.*}} @_ZN21ModifyStaticTemporary1bE
diff --git a/test/CodeGenCXX/constructor-attr.cpp b/test/CodeGenCXX/constructor-attr.cpp
index 4f6d635..468ce36 100644
--- a/test/CodeGenCXX/constructor-attr.cpp
+++ b/test/CodeGenCXX/constructor-attr.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
 
 // CHECK: @llvm.global_ctors
 
diff --git a/test/CodeGenCXX/constructor-conversion.cpp b/test/CodeGenCXX/constructor-conversion.cpp
index ebb414d..bace54f 100644
--- a/test/CodeGenCXX/constructor-conversion.cpp
+++ b/test/CodeGenCXX/constructor-conversion.cpp
@@ -1,8 +1,7 @@
-// REQUIRES: x86-registered-target,x86-64-registered-target
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s
-// RUN: FileCheck -check-prefix CHECK-LP64 --input-file=%t-64.s %s
-// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s
-// RUN: FileCheck -check-prefix CHECK-LP32 --input-file=%t-32.s %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -emit-llvm %s -o - | \
+// RUN: FileCheck %s
 
 extern "C" int printf(...);
 
@@ -46,10 +45,6 @@
   g(3);           // g(X(3))
 }
 
-// CHECK-LP64: callq    __ZN1XC1Ei
-// CHECK-LP64: callq    __ZN1XC1EPKci
-// CHECK-LP64: callq    __ZN1XC1Ev
-
-// CHECK-LP32: calll     L__ZN1XC1Ei
-// CHECK-LP32: calll     L__ZN1XC1EPKci
-// CHECK-LP32: calll     L__ZN1XC1Ev
+// CHECK: call void @_ZN1XC1Ei
+// CHECK: call void @_ZN1XC1EPKci
+// CHECK: call void @_ZN1XC1Ev
diff --git a/test/CodeGenCXX/constructor-default-arg.cpp b/test/CodeGenCXX/constructor-default-arg.cpp
index c2cf44c..98a5864 100644
--- a/test/CodeGenCXX/constructor-default-arg.cpp
+++ b/test/CodeGenCXX/constructor-default-arg.cpp
@@ -1,8 +1,7 @@
-// REQUIRES: x86-registered-target,x86-64-registered-target
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s
-// RUN: FileCheck -check-prefix CHECK-LP64 --input-file=%t-64.s %s
-// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s
-// RUN: FileCheck -check-prefix CHECK-LP32 --input-file=%t-32.s %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -emit-llvm %s -o - | \
+// RUN: FileCheck %s
 
 extern "C" int printf(...);
 
@@ -31,10 +30,6 @@
   X d(a, 5, 6);
 }
 
-// CHECK-LP64: callq __ZN1XC1ERKS_iii
-// CHECK-LP64: callq __ZN1XC1ERKS_iii
-// CHECK-LP64: callq __ZN1XC1ERKS_iii
-
-// CHECK-LP32: calll L__ZN1XC1ERKS_iii
-// CHECK-LP32: calll L__ZN1XC1ERKS_iii
-// CHECK-LP32: calll L__ZN1XC1ERKS_iii
+// CHECK: call void @_ZN1XC1ERKS_iii
+// CHECK: call void @_ZN1XC1ERKS_iii
+// CHECK: call void @_ZN1XC1ERKS_iii
diff --git a/test/CodeGenCXX/constructor-destructor-return-this.cpp b/test/CodeGenCXX/constructor-destructor-return-this.cpp
index ea2ea45..ce6ddd2 100644
--- a/test/CodeGenCXX/constructor-destructor-return-this.cpp
+++ b/test/CodeGenCXX/constructor-destructor-return-this.cpp
@@ -1,6 +1,7 @@
 //RUN: %clang_cc1 %s -emit-llvm -o - -triple=i686-unknown-linux | FileCheck --check-prefix=CHECKGEN %s
-//RUN: %clang_cc1 %s -emit-llvm -o - -triple=thumbv7-apple-ios3.0 -target-abi apcs-gnu | FileCheck --check-prefix=CHECKARM %s
-//RUN: %clang_cc1 %s -emit-llvm -o - -triple=i386-pc-win32 -cxx-abi microsoft -fno-rtti | FileCheck --check-prefix=CHECKMS %s
+//RUN: %clang_cc1 %s -emit-llvm -o - -triple=thumbv7-apple-ios6.0 -target-abi apcs-gnu | FileCheck --check-prefix=CHECKARM %s
+//RUN: %clang_cc1 %s -emit-llvm -o - -triple=thumbv7-apple-ios5.0 -target-abi apcs-gnu | FileCheck --check-prefix=CHECKIOS5 %s
+//RUN: %clang_cc1 %s -emit-llvm -o - -triple=i386-pc-win32 -fno-rtti | FileCheck --check-prefix=CHECKMS %s
 // FIXME: these tests crash on the bots when run with -triple=x86_64-pc-win32
 
 // Make sure we attach the 'returned' attribute to the 'this' parameter of
@@ -27,15 +28,20 @@
 B::B(int *i) : i_(i) { }
 B::~B() { }
 
-// CHECKGEN-LABEL: define void @_ZN1BC1EPi(%class.B* %this, i32* %i)
 // CHECKGEN-LABEL: define void @_ZN1BC2EPi(%class.B* %this, i32* %i)
-// CHECKGEN-LABEL: define void @_ZN1BD1Ev(%class.B* %this)
+// CHECKGEN-LABEL: define void @_ZN1BC1EPi(%class.B* %this, i32* %i)
 // CHECKGEN-LABEL: define void @_ZN1BD2Ev(%class.B* %this)
+// CHECKGEN-LABEL: define void @_ZN1BD1Ev(%class.B* %this)
 
-// CHECKARM-LABEL: define %class.B* @_ZN1BC1EPi(%class.B* returned %this, i32* %i)
 // CHECKARM-LABEL: define %class.B* @_ZN1BC2EPi(%class.B* returned %this, i32* %i)
-// CHECKARM-LABEL: define %class.B* @_ZN1BD1Ev(%class.B* returned %this)
+// CHECKARM-LABEL: define %class.B* @_ZN1BC1EPi(%class.B* returned %this, i32* %i)
 // CHECKARM-LABEL: define %class.B* @_ZN1BD2Ev(%class.B* returned %this)
+// CHECKARM-LABEL: define %class.B* @_ZN1BD1Ev(%class.B* returned %this)
+
+// CHECKIOS5-LABEL: define %class.B* @_ZN1BC2EPi(%class.B* %this, i32* %i)
+// CHECKIOS5-LABEL: define %class.B* @_ZN1BC1EPi(%class.B* %this, i32* %i)
+// CHECKIOS5-LABEL: define %class.B* @_ZN1BD2Ev(%class.B* %this)
+// CHECKIOS5-LABEL: define %class.B* @_ZN1BD1Ev(%class.B* %this)
 
 // CHECKMS-LABEL: define x86_thiscallcc %class.B* @"\01??0B@@QAE@PAH@Z"(%class.B* returned %this, i32* %i)
 // CHECKMS-LABEL: define x86_thiscallcc void @"\01??1B@@QAE@XZ"(%class.B* %this)
@@ -51,17 +57,23 @@
 C::C(int *i, char *c) : B(i), c_(c) { }
 C::~C() { }
 
-// CHECKGEN-LABEL: define void @_ZN1CC1EPiPc(%class.C* %this, i32* %i, i8* %c)
 // CHECKGEN-LABEL: define void @_ZN1CC2EPiPc(%class.C* %this, i32* %i, i8* %c)
-// CHECKGEN-LABEL: define void @_ZN1CD0Ev(%class.C* %this)
-// CHECKGEN-LABEL: define void @_ZN1CD1Ev(%class.C* %this)
+// CHECKGEN-LABEL: define void @_ZN1CC1EPiPc(%class.C* %this, i32* %i, i8* %c)
 // CHECKGEN-LABEL: define void @_ZN1CD2Ev(%class.C* %this)
+// CHECKGEN-LABEL: define void @_ZN1CD1Ev(%class.C* %this)
+// CHECKGEN-LABEL: define void @_ZN1CD0Ev(%class.C* %this)
 
-// CHECKARM-LABEL: define %class.C* @_ZN1CC1EPiPc(%class.C* returned %this, i32* %i, i8* %c)
 // CHECKARM-LABEL: define %class.C* @_ZN1CC2EPiPc(%class.C* returned %this, i32* %i, i8* %c)
-// CHECKARM-LABEL: define void @_ZN1CD0Ev(%class.C* %this)
-// CHECKARM-LABEL: define %class.C* @_ZN1CD1Ev(%class.C* returned %this)
+// CHECKARM-LABEL: define %class.C* @_ZN1CC1EPiPc(%class.C* returned %this, i32* %i, i8* %c)
 // CHECKARM-LABEL: define %class.C* @_ZN1CD2Ev(%class.C* returned %this)
+// CHECKARM-LABEL: define %class.C* @_ZN1CD1Ev(%class.C* returned %this)
+// CHECKARM-LABEL: define void @_ZN1CD0Ev(%class.C* %this)
+
+// CHECKIOS5-LABEL: define %class.C* @_ZN1CC2EPiPc(%class.C* %this, i32* %i, i8* %c)
+// CHECKIOS5-LABEL: define %class.C* @_ZN1CC1EPiPc(%class.C* %this, i32* %i, i8* %c)
+// CHECKIOS5-LABEL: define %class.C* @_ZN1CD2Ev(%class.C* %this)
+// CHECKIOS5-LABEL: define %class.C* @_ZN1CD1Ev(%class.C* %this)
+// CHECKIOS5-LABEL: define void @_ZN1CD0Ev(%class.C* %this)
 
 // CHECKMS-LABEL: define x86_thiscallcc %class.C* @"\01??0C@@QAE@PAHPAD@Z"(%class.C* returned %this, i32* %i, i8* %c)
 // CHECKMS-LABEL: define x86_thiscallcc void @"\01??1C@@UAE@XZ"(%class.C* %this)
@@ -75,15 +87,20 @@
 D::D() { }
 D::~D() { }
 
-// CHECKGEN-LABEL: define void @_ZN1DC1Ev(%class.D* %this)
 // CHECKGEN-LABEL: define void @_ZN1DC2Ev(%class.D* %this, i8** %vtt)
-// CHECKGEN-LABEL: define void @_ZN1DD1Ev(%class.D* %this)
+// CHECKGEN-LABEL: define void @_ZN1DC1Ev(%class.D* %this)
 // CHECKGEN-LABEL: define void @_ZN1DD2Ev(%class.D* %this, i8** %vtt)
+// CHECKGEN-LABEL: define void @_ZN1DD1Ev(%class.D* %this)
 
-// CHECKARM-LABEL: define %class.D* @_ZN1DC1Ev(%class.D* returned %this)
 // CHECKARM-LABEL: define %class.D* @_ZN1DC2Ev(%class.D* returned %this, i8** %vtt)
-// CHECKARM-LABEL: define %class.D* @_ZN1DD1Ev(%class.D* returned %this)
+// CHECKARM-LABEL: define %class.D* @_ZN1DC1Ev(%class.D* returned %this)
 // CHECKARM-LABEL: define %class.D* @_ZN1DD2Ev(%class.D* returned %this, i8** %vtt)
+// CHECKARM-LABEL: define %class.D* @_ZN1DD1Ev(%class.D* returned %this)
+
+// CHECKIOS5-LABEL: define %class.D* @_ZN1DC2Ev(%class.D* %this, i8** %vtt)
+// CHECKIOS5-LABEL: define %class.D* @_ZN1DC1Ev(%class.D* %this)
+// CHECKIOS5-LABEL: define %class.D* @_ZN1DD2Ev(%class.D* %this, i8** %vtt)
+// CHECKIOS5-LABEL: define %class.D* @_ZN1DD1Ev(%class.D* %this)
 
 // CHECKMS-LABEL: define x86_thiscallcc %class.D* @"\01??0D@@QAE@XZ"(%class.D* returned %this, i32 %is_most_derived)
 // CHECKMS-LABEL: define x86_thiscallcc void @"\01??1D@@QAE@XZ"(%class.D* %this)
diff --git a/test/CodeGenCXX/constructor-direct-call.cpp b/test/CodeGenCXX/constructor-direct-call.cpp
index 75e6f21..9567d09 100644
--- a/test/CodeGenCXX/constructor-direct-call.cpp
+++ b/test/CodeGenCXX/constructor-direct-call.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i686-pc-win32 -fms-extensions -Wmicrosoft %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple i686-pc-mingw32 -fms-extensions -Wmicrosoft %s -emit-llvm -o - | FileCheck %s
 
 class Test1 {
 public:
@@ -22,10 +22,10 @@
 
 void f2() {
   // CHECK:  %var = alloca %class.Test2, align 4
-  // CHECK-NEXT:  call void @_ZN5Test2C1Ev(%class.Test2* %var)
+  // CHECK-NEXT:  call x86_thiscallcc void @_ZN5Test2C1Ev(%class.Test2* %var)
   Test2 var;
 
-  // CHECK-NEXT:  call void @_ZN5Test2C1Ev(%class.Test2* %var)
+  // CHECK-NEXT:  call x86_thiscallcc void @_ZN5Test2C1Ev(%class.Test2* %var)
   var.Test2::Test2();
 
   // CHECK:  call void @llvm.memcpy.p0i8.p0i8.i32(i8* %{{.*}}, i8* %{{.*}}, i32 8, i32 4, i1 false)
@@ -45,16 +45,15 @@
 };
 
 void f3() {
-  // CHECK: call void @_ZN5Test3C1Ev(%class.Test3* %var)
+  // CHECK: call x86_thiscallcc void @_ZN5Test3C1Ev(%class.Test3* %var)
   Test3 var;
 
-  // CHECK-NEXT: call void @_ZN5Test3C1Ev(%class.Test3* %var2)
+  // CHECK-NEXT: call x86_thiscallcc void @_ZN5Test3C1Ev(%class.Test3* %var2)
   Test3 var2;
 
-  // CHECK-NEXT: call void @_ZN5Test3C1Ev(%class.Test3* %var)
+  // CHECK-NEXT: call x86_thiscallcc void @_ZN5Test3C1Ev(%class.Test3* %var)
   var.Test3::Test3();
 
-  // CHECK-NEXT: call void @_ZN5Test3C1ERKS_(%class.Test3* %var, %class.Test3* %var2)
+  // CHECK-NEXT: call x86_thiscallcc void @_ZN5Test3C1ERKS_(%class.Test3* %var, %class.Test3* dereferenceable({{[0-9]+}}) %var2)
   var.Test3::Test3(var2);
 }
-
diff --git a/test/CodeGenCXX/constructor-for-array-members.cpp b/test/CodeGenCXX/constructor-for-array-members.cpp
index 7842d9c..8ea7eac 100644
--- a/test/CodeGenCXX/constructor-for-array-members.cpp
+++ b/test/CodeGenCXX/constructor-for-array-members.cpp
@@ -1,8 +1,7 @@
-// REQUIRES: x86-registered-target,x86-64-registered-target
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s
-// RUN: FileCheck -check-prefix CHECK-LP64 --input-file=%t-64.s %s
-// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s
-// RUN: FileCheck -check-prefix CHECK-LP32 --input-file=%t-32.s %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -emit-llvm %s -o - | \
+// RUN: FileCheck %s
 
 extern "C" int printf(...);
 
@@ -39,6 +38,4 @@
   m1.pr();
 }
 
-// CHECK-LP64: callq __ZN1SC1Ev
-
-// CHECK-LP32: calll L__ZN1SC1Ev
+// CHECK: call void @_ZN1SC1Ev
diff --git a/test/CodeGenCXX/constructor-init-reference.cpp b/test/CodeGenCXX/constructor-init-reference.cpp
index 5e75159..61f426d 100644
--- a/test/CodeGenCXX/constructor-init-reference.cpp
+++ b/test/CodeGenCXX/constructor-init-reference.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -o - %s | grep "store i32\* @x, i32\*\*"
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
 
 int x;
 struct A {
@@ -6,4 +6,4 @@
   A() : y(x) {}
 };
 A z;
-
+// CHECK: store i32* @x, i32**
diff --git a/test/CodeGenCXX/constructor-init.cpp b/test/CodeGenCXX/constructor-init.cpp
index 477a439..a8f483e 100644
--- a/test/CodeGenCXX/constructor-init.cpp
+++ b/test/CodeGenCXX/constructor-init.cpp
@@ -163,7 +163,7 @@
 
 // Make sure that the instantiated constructor initializes start and
 // end properly.
-// CHECK-LABEL: define linkonce_odr void @_ZN1XIiEC2ERKS0_(%struct.X* %this, %struct.X* %other) unnamed_addr
+// CHECK-LABEL: define linkonce_odr void @_ZN1XIiEC2ERKS0_(%struct.X* %this, %struct.X* dereferenceable({{[0-9]+}}) %other) unnamed_addr
 // CHECK: {{store.*null}}
 // CHECK: {{store.*null}}
 // CHECK: ret
diff --git a/test/CodeGenCXX/constructor-template.cpp b/test/CodeGenCXX/constructor-template.cpp
index 0d38d10..675e3cf 100644
--- a/test/CodeGenCXX/constructor-template.cpp
+++ b/test/CodeGenCXX/constructor-template.cpp
@@ -1,4 +1,4 @@
-// REQUIRES: x86-registered-target,x86-64-registered-target
+// REQUIRES: x86-registered-target
 // RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s
 // RUN: FileCheck -check-prefix CHECK-LP64 --input-file=%t-64.s %s
 // RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s
diff --git a/test/CodeGenCXX/constructors.cpp b/test/CodeGenCXX/constructors.cpp
index f730b9e..b99c5a1 100644
--- a/test/CodeGenCXX/constructors.cpp
+++ b/test/CodeGenCXX/constructors.cpp
@@ -21,20 +21,19 @@
 A::A(struct Undeclared &ref) : mem(0) {}
 
 // Check that delegation works.
-// CHECK-LABEL: define void @_ZN1AC1ER10Undeclared(%struct.A* %this, %struct.Undeclared* %ref) unnamed_addr
-// CHECK: call void @_ZN1AC2ER10Undeclared(
-
-// CHECK-LABEL: define void @_ZN1AC2ER10Undeclared(%struct.A* %this, %struct.Undeclared* %ref) unnamed_addr
+// CHECK-LABEL: define void @_ZN1AC2ER10Undeclared(%struct.A* %this, %struct.Undeclared* nonnull %ref) unnamed_addr
 // CHECK: call void @_ZN6MemberC1Ei(
 
-A::A(ValueClass v) : mem(v.y - v.x) {}
+// CHECK-LABEL: define void @_ZN1AC1ER10Undeclared(%struct.A* %this, %struct.Undeclared* nonnull %ref) unnamed_addr
+// CHECK: call void @_ZN1AC2ER10Undeclared(
 
-// CHECK-LABEL: define void @_ZN1AC1E10ValueClass(%struct.A* %this, i64 %v.coerce) unnamed_addr
-// CHECK: call void @_ZN1AC2E10ValueClass(
+A::A(ValueClass v) : mem(v.y - v.x) {}
 
 // CHECK-LABEL: define void @_ZN1AC2E10ValueClass(%struct.A* %this, i64 %v.coerce) unnamed_addr
 // CHECK: call void @_ZN6MemberC1Ei(
 
+// CHECK-LABEL: define void @_ZN1AC1E10ValueClass(%struct.A* %this, i64 %v.coerce) unnamed_addr
+// CHECK: call void @_ZN1AC2E10ValueClass(
 
 /* Test that things work for inheritance. */
 struct B : A {
@@ -44,13 +43,12 @@
 
 B::B(struct Undeclared &ref) : A(ref), mem(1) {}
 
-// CHECK-LABEL: define void @_ZN1BC1ER10Undeclared(%struct.B* %this, %struct.Undeclared* %ref) unnamed_addr
-// CHECK: call void @_ZN1BC2ER10Undeclared(
-
-// CHECK-LABEL: define void @_ZN1BC2ER10Undeclared(%struct.B* %this, %struct.Undeclared* %ref) unnamed_addr
+// CHECK-LABEL: define void @_ZN1BC2ER10Undeclared(%struct.B* %this, %struct.Undeclared* nonnull %ref) unnamed_addr
 // CHECK: call void @_ZN1AC2ER10Undeclared(
 // CHECK: call void @_ZN6MemberC1Ei(
 
+// CHECK-LABEL: define void @_ZN1BC1ER10Undeclared(%struct.B* %this, %struct.Undeclared* nonnull %ref) unnamed_addr
+// CHECK: call void @_ZN1BC2ER10Undeclared(
 
 
 /* Test that the delegation optimization is disabled for classes with
@@ -64,15 +62,14 @@
 };
 C::C(int x) : A(ValueClass(x, x+1)), mem(x * x) {}
 
+// CHECK-LABEL: define void @_ZN1CC2Ei(%struct.C* %this, i8** %vtt, i32 %x) unnamed_addr
+// CHECK: call void @_ZN6MemberC1Ei(
+
 // CHECK-LABEL: define void @_ZN1CC1Ei(%struct.C* %this, i32 %x) unnamed_addr
 // CHECK: call void @_ZN10ValueClassC1Eii(
 // CHECK: call void @_ZN1AC2E10ValueClass(
 // CHECK: call void @_ZN6MemberC1Ei(
 
-// CHECK-LABEL: define void @_ZN1CC2Ei(%struct.C* %this, i8** %vtt, i32 %x) unnamed_addr
-// CHECK: call void @_ZN6MemberC1Ei(
-
-
 
 /* Test that the delegation optimization is disabled for varargs
    constructors. */
@@ -83,16 +80,15 @@
 
 D::D(int x, ...) : A(ValueClass(x, x+1)), mem(x*x) {}
 
-// CHECK-LABEL: define void @_ZN1DC1Eiz(%struct.D* %this, i32 %x, ...) unnamed_addr
-// CHECK: call void @_ZN10ValueClassC1Eii(
-// CHECK: call void @_ZN1AC2E10ValueClass(
-// CHECK: call void @_ZN6MemberC1Ei(
-
 // CHECK-LABEL: define void @_ZN1DC2Eiz(%struct.D* %this, i32 %x, ...) unnamed_addr
 // CHECK: call void @_ZN10ValueClassC1Eii(
 // CHECK: call void @_ZN1AC2E10ValueClass(
 // CHECK: call void @_ZN6MemberC1Ei(
 
+// CHECK-LABEL: define void @_ZN1DC1Eiz(%struct.D* %this, i32 %x, ...) unnamed_addr
+// CHECK: call void @_ZN10ValueClassC1Eii(
+// CHECK: call void @_ZN1AC2E10ValueClass(
+// CHECK: call void @_ZN6MemberC1Ei(
 
 // PR6622:  this shouldn't crash
 namespace test0 {
diff --git a/test/CodeGenCXX/convert-to-fptr.cpp b/test/CodeGenCXX/convert-to-fptr.cpp
index e497acf..c3be962 100644
--- a/test/CodeGenCXX/convert-to-fptr.cpp
+++ b/test/CodeGenCXX/convert-to-fptr.cpp
@@ -1,8 +1,7 @@
-// REQUIRES: x86-registered-target,x86-64-registered-target
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s
-// RUN: FileCheck -check-prefix CHECK-LP64 --input-file=%t-64.s %s
-// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s
-// RUN: FileCheck -check-prefix CHECK-LP32 --input-file=%t-32.s %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -emit-llvm %s -o - | \
+// RUN: FileCheck %s
 
 extern "C" int printf(...);
 
@@ -39,9 +38,5 @@
  return 0;
 }
 
-// CHECK-LP64: callq __ZN1AcvPFiiEEv
-// CHECK-LP64: callq __ZN1BcvRFiiEEv
-
-// CHECK-LP32: calll L__ZN1AcvPFiiEEv
-// CHECK-LP32: calll L__ZN1BcvRFiiEEv
-
+// CHECK: call i32 (i32)* (%struct.A*)* @_ZN1AcvPFiiEEv
+// CHECK: call i32 (i32)* (%struct.B*)* @_ZN1BcvRFiiEEv
diff --git a/test/CodeGenCXX/copy-assign-synthesis-1.cpp b/test/CodeGenCXX/copy-assign-synthesis-1.cpp
index 2ffc7bc..5813d9c 100644
--- a/test/CodeGenCXX/copy-assign-synthesis-1.cpp
+++ b/test/CodeGenCXX/copy-assign-synthesis-1.cpp
@@ -1,4 +1,3 @@
-// REQUIRES: x86-registered-target,x86-64-registered-target
 // RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm %s -o - | \
 // RUN: FileCheck %s
 // RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -emit-llvm %s -o - | \
@@ -93,5 +92,4 @@
   dstY.pr();
 }
 
-// CHECK: define linkonce_odr %struct.X* @_ZN1XaSERKS_
-
+// CHECK: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.X* @_ZN1XaSERKS_
diff --git a/test/CodeGenCXX/copy-assign-synthesis-2.cpp b/test/CodeGenCXX/copy-assign-synthesis-2.cpp
index 18e92f9..0bc7d3d 100644
--- a/test/CodeGenCXX/copy-assign-synthesis-2.cpp
+++ b/test/CodeGenCXX/copy-assign-synthesis-2.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
 struct A {};
 A& (A::*x)(const A&) = &A::operator=;
-// CHECK-LABEL: define linkonce_odr %struct.A* @_ZN1AaSERKS_
+// CHECK-LABEL: define linkonce_odr {{.*}}%struct.A* @_ZN1AaSERKS_
diff --git a/test/CodeGenCXX/copy-constructor-elim-2.cpp b/test/CodeGenCXX/copy-constructor-elim-2.cpp
index 727af1b..c263b7e 100644
--- a/test/CodeGenCXX/copy-constructor-elim-2.cpp
+++ b/test/CodeGenCXX/copy-constructor-elim-2.cpp
@@ -21,7 +21,7 @@
     Derived(const Other &O);
   };
 
-  // CHECK: define {{.*}} @_ZN13no_elide_base7DerivedC1ERKNS_5OtherE(%"struct.no_elide_base::Derived"* returned %this, %"struct.no_elide_base::Other"* %O) unnamed_addr
+  // CHECK: define {{.*}} @_ZN13no_elide_base7DerivedC1ERKNS_5OtherE(%"struct.no_elide_base::Derived"* returned %this, %"struct.no_elide_base::Other"* dereferenceable({{[0-9]+}}) %O) unnamed_addr
   Derived::Derived(const Other &O) 
     // CHECK: call {{.*}} @_ZNK13no_elide_base5OthercvNS_4BaseEEv
     // CHECK: call {{.*}} @_ZN13no_elide_base4BaseC2ERKS0_
@@ -74,4 +74,3 @@
     return a.value;
   }
 }
-
diff --git a/test/CodeGenCXX/copy-constructor-elim.cpp b/test/CodeGenCXX/copy-constructor-elim.cpp
index ad3a87b..8e9bee9 100644
--- a/test/CodeGenCXX/copy-constructor-elim.cpp
+++ b/test/CodeGenCXX/copy-constructor-elim.cpp
@@ -1,6 +1,9 @@
-// RUN: %clang_cc1 -emit-llvm -o %t %s
-// RUN: not grep "_ZN1CC1ERK1C" %t
-// RUN: not grep "_ZN1SC1ERK1S" %t
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK
+// RUN: %clang_cc1 -triple %ms_abi_triple -emit-llvm -o - %s | FileCheck %s -check-prefix MS
+// CHECK-NOT: _ZN1CC1ERK1C
+// CHECK-NOT: _ZN1SC1ERK1S
+// MS-NOT: ?0C@@QAE@ABV0
+// MS-NOT: ?0S@@QAE@ABV0
 
 extern "C" int printf(...);
 
diff --git a/test/CodeGenCXX/copy-constructor-synthesis-2.cpp b/test/CodeGenCXX/copy-constructor-synthesis-2.cpp
index 03c6633..4bb0fee 100644
--- a/test/CodeGenCXX/copy-constructor-synthesis-2.cpp
+++ b/test/CodeGenCXX/copy-constructor-synthesis-2.cpp
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
 
 struct A { virtual void a(); };
 A x(A& y) { return y; }
 
-// CHECK: define linkonce_odr {{.*}} @_ZN1AC1ERKS_(%struct.A* {{.*}}%this, %struct.A*) unnamed_addr
+// CHECK: define linkonce_odr {{.*}} @_ZN1AC1ERKS_(%struct.A* {{.*}}%this, %struct.A* dereferenceable({{[0-9]+}})) unnamed_addr
 // CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1A, i64 0, i64 2)
diff --git a/test/CodeGenCXX/copy-constructor-synthesis.cpp b/test/CodeGenCXX/copy-constructor-synthesis.cpp
index c8b265c..47f8e13 100644
--- a/test/CodeGenCXX/copy-constructor-synthesis.cpp
+++ b/test/CodeGenCXX/copy-constructor-synthesis.cpp
@@ -21,7 +21,7 @@
 };
 
 
-// CHECK-LABEL: define linkonce_odr void @_ZN1XC1ERKS_(%struct.X* %this, %struct.X*) unnamed_addr
+// CHECK-LABEL: define linkonce_odr void @_ZN1XC1ERKS_(%struct.X* %this, %struct.X* dereferenceable({{[0-9]+}})) unnamed_addr
 struct X  : M, N, P { // ...
   X() : f1(1.0), d1(2.0), i1(3), name("HELLO"), bf1(0xff), bf2(0xabcd),
         au_i1(1234), au1_4("MASKED") {}
@@ -136,15 +136,13 @@
   B b2 = b1;
 }
 
-// CHECK:    define linkonce_odr [[A:%.*]]* @_ZN12rdar138169401AaSERKS0_(
+// CHECK:    define linkonce_odr dereferenceable({{[0-9]+}}) [[A:%.*]]* @_ZN12rdar138169401AaSERKS0_(
 // CHECK:      [[THIS:%.*]] = load [[A]]**
 // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]]* [[THIS]], i32 0, i32 1
-// CHECK-NEXT: [[T1:%.*]] = bitcast [2 x i8]* [[T0]] to i16*
 // CHECK-NEXT: [[OTHER:%.*]] = load [[A]]**
 // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[A]]* [[OTHER]], i32 0, i32 1
-// CHECK-NEXT: [[T3:%.*]] = bitcast [2 x i8]* [[T2]] to i16*
-// CHECK-NEXT: [[T4:%.*]] = bitcast i16* [[T1]] to i8*
-// CHECK-NEXT: [[T5:%.*]] = bitcast i16* [[T3]] to i8*
+// CHECK-NEXT: [[T4:%.*]] = bitcast i16* [[T0]] to i8*
+// CHECK-NEXT: [[T5:%.*]] = bitcast i16* [[T2]] to i8*
 // CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[T4]], i8* [[T5]], i64 8, i32 8, i1 false)
 // CHECK-NEXT: ret [[A]]* [[THIS]]
 
@@ -153,16 +151,14 @@
 // CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[THIS]] to i8***
 // CHECK-NEXT: store i8** getelementptr inbounds ([4 x i8*]* @_ZTVN12rdar138169401AE, i64 0, i64 2), i8*** [[T0]]
 // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]]* [[THIS]], i32 0, i32 1
-// CHECK-NEXT: [[T1:%.*]] = bitcast [2 x i8]* [[T0]] to i16*
 // CHECK-NEXT: [[OTHER:%.*]] = load [[A]]**
 // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[A]]* [[OTHER]], i32 0, i32 1
-// CHECK-NEXT: [[T3:%.*]] = bitcast [2 x i8]* [[T2]] to i16*
-// CHECK-NEXT: [[T4:%.*]] = bitcast i16* [[T1]] to i8*
-// CHECK-NEXT: [[T5:%.*]] = bitcast i16* [[T3]] to i8*
+// CHECK-NEXT: [[T4:%.*]] = bitcast i16* [[T0]] to i8*
+// CHECK-NEXT: [[T5:%.*]] = bitcast i16* [[T2]] to i8*
 // CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[T4]], i8* [[T5]], i64 8, i32 8, i1 false)
 // CHECK-NEXT: ret void
 
-// CHECK-LABEL: define linkonce_odr void @_ZN6PR66281BC2ERKS0_(%"struct.PR6628::B"* %this, %"struct.PR6628::B"*) unnamed_addr
+// CHECK-LABEL: define linkonce_odr void @_ZN6PR66281BC2ERKS0_(%"struct.PR6628::B"* %this, %"struct.PR6628::B"* dereferenceable({{[0-9]+}})) unnamed_addr
 // CHECK: call void @_ZN6PR66281TC1Ev
 // CHECK: call void @_ZN6PR66281TC1Ev
 // CHECK: call void @_ZN6PR66281AC2ERKS0_RKNS_1TES5_
diff --git a/test/CodeGenCXX/coverage.cpp b/test/CodeGenCXX/coverage.cpp
index 1f1611b..88f7409 100644
--- a/test/CodeGenCXX/coverage.cpp
+++ b/test/CodeGenCXX/coverage.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - -test-coverage -femit-coverage-notes | FileCheck %s
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -emit-llvm -o - -test-coverage -femit-coverage-notes | FileCheck %s
 
 extern "C" void test_name1() {}
 void test_name2() {}
diff --git a/test/CodeGenCXX/ctor-dtor-alias.cpp b/test/CodeGenCXX/ctor-dtor-alias.cpp
index 6efd0bf..d869a2b 100644
--- a/test/CodeGenCXX/ctor-dtor-alias.cpp
+++ b/test/CodeGenCXX/ctor-dtor-alias.cpp
@@ -1,5 +1,8 @@
-// RUN: %clang_cc1 %s -triple x86_64-linux -emit-llvm -o - -mconstructor-aliases -O1 -disable-llvm-optzns | FileCheck %s
-// RUN: %clang_cc1 %s -triple x86_64-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 | FileCheck %s
+// RUN: %clang_cc1 %s -triple i686-linux -emit-llvm -o - -mconstructor-aliases | FileCheck --check-prefix=NOOPT %s
+
+// RUN: %clang_cc1 -triple x86_64--netbsd -emit-llvm \
+// RUN: -mconstructor-aliases -O2 %s -o - | FileCheck --check-prefix=CHECK-RAUW %s
 
 namespace test1 {
 // test that we don't produce an alias when the destructor is weak_odr. The
@@ -58,7 +61,7 @@
   // test that we don't do this optimization at -O0 so that the debugger can
   // see both destructors.
   // NOOPT-DAG: call i32 @__cxa_atexit{{.*}}@_ZN5test41BD2Ev
-  // NOOOPT-DAG: define linkonce_odr void @_ZN5test41BD2Ev
+  // NOOPT-DAG: define linkonce_odr void @_ZN5test41BD2Ev
   struct A {
     virtual ~A() {}
   };
@@ -129,3 +132,48 @@
   struct zed : public bar {};
   zed foo;
 }
+
+namespace test9 {
+struct foo {
+  __attribute__((stdcall)) ~foo() {
+  }
+};
+
+struct bar : public foo {};
+
+void zed() {
+  // Test that we produce a call to bar's destructor. We used to call foo's, but
+  // it has a different calling conversion.
+  // CHECK-DAG: call void @_ZN5test93barD2Ev
+  bar ptr;
+}
+}
+
+// CHECK-RAUW: @_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 {
+public:
+  A(int);
+  virtual ~A();
+};
+
+template <class>
+class B : A {
+public:
+  B()
+      : A(0) {
+  }
+  __attribute__((always_inline)) ~B() {
+  }
+};
+
+extern template class B<char>;
+
+class C : B<char> {
+};
+
+void
+fn1() {
+  new C;
+}
diff --git a/test/CodeGenCXX/cxx0x-defaulted-templates.cpp b/test/CodeGenCXX/cxx0x-defaulted-templates.cpp
index f4d5ccc..6f4c533 100644
--- a/test/CodeGenCXX/cxx0x-defaulted-templates.cpp
+++ b/test/CodeGenCXX/cxx0x-defaulted-templates.cpp
@@ -1,16 +1,16 @@
-// RUN: %clang_cc1 -std=c++11 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
 
 template <typename T>
 struct X {
   X();
 };
 
-// CHECK: define {{.*}} @_ZN1XIbEC1Ev
 // CHECK: define {{.*}} @_ZN1XIbEC2Ev
+// CHECK: define {{.*}} @_ZN1XIbEC1Ev
 template <> X<bool>::X() = default;
 
-// CHECK: define weak_odr {{.*}} @_ZN1XIiEC1Ev
 // CHECK: define weak_odr {{.*}} @_ZN1XIiEC2Ev
+// CHECK: define weak_odr {{.*}} @_ZN1XIiEC1Ev
 template <typename T> X<T>::X() = default;
 template X<int>::X();
 
diff --git a/test/CodeGenCXX/cxx0x-delegating-ctors.cpp b/test/CodeGenCXX/cxx0x-delegating-ctors.cpp
index c48e61f..dcc0556 100644
--- a/test/CodeGenCXX/cxx0x-delegating-ctors.cpp
+++ b/test/CodeGenCXX/cxx0x-delegating-ctors.cpp
@@ -26,28 +26,30 @@
 delegator::delegator(bool)
 {}
 
-// CHECK: define {{.*}} @_ZN9delegatorC1Ec
-// CHECK: {{.*}} @_ZN9delegatorC1Eb
-// CHECK: void @__cxa_throw
-// CHECK: void @__clang_call_terminate
-// CHECK: {{.*}} @_ZN9delegatorD1Ev
-// CHECK: define {{.*}} @_ZN9delegatorC2Ec
+// CHECK-LABEL: define {{.*}} @_ZN9delegatorC2Ec
 // CHECK: {{.*}} @_ZN9delegatorC2Eb
 // CHECK: void @__cxa_throw
 // CHECK: void @__clang_call_terminate
 // CHECK: {{.*}} @_ZN9delegatorD2Ev
+
+// CHECK-LABEL: define {{.*}} @_ZN9delegatorC1Ec
+// CHECK: {{.*}} @_ZN9delegatorC1Eb
+// CHECK: void @__cxa_throw
+// CHECK: void @__clang_call_terminate
+// CHECK: {{.*}} @_ZN9delegatorD1Ev
 delegator::delegator(char)
   : delegator(true) {
   throw 0;
 }
 
-// CHECK: define {{.*}} @_ZN9delegatorC1Ei
-// CHECK: {{.*}} @_ZN9delegatorC1Ev
+// CHECK-LABEL: define {{.*}} @_ZN9delegatorC2Ei
+// CHECK: {{.*}} @_ZN9delegatorC2Ev
 // CHECK-NOT: void @_ZSt9terminatev
 // CHECK: ret
 // CHECK-NOT: void @_ZSt9terminatev
-// CHECK: define {{.*}} @_ZN9delegatorC2Ei
-// CHECK: {{.*}} @_ZN9delegatorC2Ev
+
+// CHECK-LABEL: define {{.*}} @_ZN9delegatorC1Ei
+// CHECK: {{.*}} @_ZN9delegatorC1Ev
 // CHECK-NOT: void @_ZSt9terminatev
 // CHECK: ret
 // CHECK-NOT: void @_ZSt9terminatev
diff --git a/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-pr12086.cpp b/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-pr12086.cpp
index 091d7b7..91e913e 100644
--- a/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-pr12086.cpp
+++ b/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-pr12086.cpp
@@ -55,78 +55,78 @@
   {1, a}, {3, b}, {5, c}
 };
 
-// CHECK-STATIC-BL: @_ZGR6nested = private constant [2 x i32] [i32 1, i32 2], align 4
-// CHECK-STATIC-BL: @_ZGR6nested1 = private constant [2 x i32] [i32 3, i32 4], align 4
-// CHECK-STATIC-BL: @_ZGR6nested2 = private constant [2 x i32] [i32 5, i32 6], align 4
-// CHECK-STATIC-BL: @_ZGR6nested3 = private constant [3 x {{.*}}] [
-// CHECK-STATIC-BL:   {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested, i32 0, i32 0), i64 2 },
-// CHECK-STATIC-BL:   {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i32 0, i32 0), i64 2 },
-// CHECK-STATIC-BL:   {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i32 0, i32 0), i64 2 }
+// CHECK-STATIC-BL: @_ZGR6nested0_ = private constant [2 x i32] [i32 1, i32 2], align 4
+// CHECK-STATIC-BL: @_ZGR6nested1_ = private constant [2 x i32] [i32 3, i32 4], align 4
+// CHECK-STATIC-BL: @_ZGR6nested2_ = private constant [2 x i32] [i32 5, i32 6], align 4
+// CHECK-STATIC-BL: @_ZGR6nested_ = private constant [3 x {{.*}}] [
+// CHECK-STATIC-BL:   {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested0_, i32 0, i32 0), i64 2 },
+// CHECK-STATIC-BL:   {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1_, i32 0, i32 0), i64 2 },
+// CHECK-STATIC-BL:   {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2_, i32 0, i32 0), i64 2 }
 // CHECK-STATIC-BL: ], align 8
-// CHECK-STATIC-BL: @nested = global {{.*}} { {{.*}} getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested3, i32 0, i32 0), i64 3 }, align 8
+// CHECK-STATIC-BL: @nested = global {{.*}} { {{.*}} getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested_, i32 0, i32 0), i64 3 }, align 8
 
 // CHECK-DYNAMIC-BL: @nested = global
-// CHECK-DYNAMIC-BL: @_ZGR6nested = private global [3 x
-// CHECK-DYNAMIC-BL: @_ZGR6nested1 = private global [2 x i32] zeroinitializer
-// CHECK-DYNAMIC-BL: @_ZGR6nested2 = private global [2 x i32] zeroinitializer
-// CHECK-DYNAMIC-BL: @_ZGR6nested3 = private global [2 x i32] zeroinitializer
-// CHECK-DYNAMIC-BL: store i32 1, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 0)
-// CHECK-DYNAMIC-BL: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 1)
-// CHECK-DYNAMIC-BL: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 0),
-// CHECK-DYMAMIC-BL:       i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 0, i32 0), align 8
-// CHECK-DYNAMIC-BL: store i64 2, i64* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 0, i32 1), align 8
-// CHECK-DYNAMIC-BL: store i32 3, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 0)
-// CHECK-DYNAMIC-BL: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 1)
-// CHECK-DYNAMIC-BL: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 0),
-// CHECK-DYNAMIC-BL:       i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 1, i32 0), align 8
-// CHECK-DYNAMIC-BL: store i64 2, i64* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 1, i32 1), align 8
-// CHECK-DYNAMIC-BL: store i32 5, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested3, i64 0, i64 0)
-// CHECK-DYNAMIC-BL: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested3, i64 0, i64 1)
-// CHECK-DYNAMIC-BL: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested3, i64 0, i64 0),
-// CHECK-DYNAMIC-BL:       i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 2, i32 0), align 8
-// CHECK-DYNAMIC-BL: store i64 2, i64* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 2, i32 1), align 8
-// CHECK-DYNAMIC-BL: store {{.*}}* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 0),
+// CHECK-DYNAMIC-BL: @_ZGR6nested_ = private global [3 x
+// CHECK-DYNAMIC-BL: @_ZGR6nested0_ = private global [2 x i32] zeroinitializer
+// CHECK-DYNAMIC-BL: @_ZGR6nested1_ = private global [2 x i32] zeroinitializer
+// CHECK-DYNAMIC-BL: @_ZGR6nested2_ = private global [2 x i32] zeroinitializer
+// CHECK-DYNAMIC-BL: store i32 1, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested0_, i64 0, i64 0)
+// CHECK-DYNAMIC-BL: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested0_, i64 0, i64 1)
+// CHECK-DYNAMIC-BL: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested0_, i64 0, i64 0),
+// CHECK-DYNAMIC-BL:       i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 0, i32 0), align 8
+// CHECK-DYNAMIC-BL: store i64 2, i64* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 0, i32 1), align 8
+// CHECK-DYNAMIC-BL: store i32 3, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1_, i64 0, i64 0)
+// CHECK-DYNAMIC-BL: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1_, i64 0, i64 1)
+// CHECK-DYNAMIC-BL: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1_, i64 0, i64 0),
+// CHECK-DYNAMIC-BL:       i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 1, i32 0), align 8
+// CHECK-DYNAMIC-BL: store i64 2, i64* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 1, i32 1), align 8
+// CHECK-DYNAMIC-BL: store i32 5, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2_, i64 0, i64 0)
+// CHECK-DYNAMIC-BL: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2_, i64 0, i64 1)
+// CHECK-DYNAMIC-BL: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2_, i64 0, i64 0),
+// CHECK-DYNAMIC-BL:       i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 2, i32 0), align 8
+// CHECK-DYNAMIC-BL: store i64 2, i64* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 2, i32 1), align 8
+// CHECK-DYNAMIC-BL: store {{.*}}* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 0),
 // CHECK-DYNAMIC-BL:       {{.*}}** getelementptr inbounds ({{.*}}* @nested, i32 0, i32 0), align 8
 // CHECK-DYNAMIC-BL: store i64 3, i64* getelementptr inbounds ({{.*}}* @nested, i32 0, i32 1), align 8
 
-// CHECK-STATIC-BE: @_ZGR6nested = private constant [2 x i32] [i32 1, i32 2], align 4
-// CHECK-STATIC-BE: @_ZGR6nested1 = private constant [2 x i32] [i32 3, i32 4], align 4
-// CHECK-STATIC-BE: @_ZGR6nested2 = private constant [2 x i32] [i32 5, i32 6], align 4
-// CHECK-STATIC-BE: @_ZGR6nested3 = private constant [3 x {{.*}}] [
-// CHECK-STATIC-BE:   {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested, i32 0, i32 0),
-// CHECK-STATIC-BE:            i32* bitcast (i8* getelementptr (i8* bitcast ([2 x i32]* @_ZGR6nested to i8*), i64 8) to i32*) }
-// CHECK-STATIC-BE:   {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i32 0, i32 0),
-// CHECK-STATIC-BE:            i32* bitcast (i8* getelementptr (i8* bitcast ([2 x i32]* @_ZGR6nested1 to i8*), i64 8) to i32*) }
-// CHECK-STATIC-BE:   {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i32 0, i32 0),
-// CHECK-STATIC-BE:            i32* bitcast (i8* getelementptr (i8* bitcast ([2 x i32]* @_ZGR6nested2 to i8*), i64 8) to i32*) }
+// CHECK-STATIC-BE: @_ZGR6nested0_ = private constant [2 x i32] [i32 1, i32 2], align 4
+// CHECK-STATIC-BE: @_ZGR6nested1_ = private constant [2 x i32] [i32 3, i32 4], align 4
+// CHECK-STATIC-BE: @_ZGR6nested2_ = private constant [2 x i32] [i32 5, i32 6], align 4
+// CHECK-STATIC-BE: @_ZGR6nested_ = private constant [3 x {{.*}}] [
+// CHECK-STATIC-BE:   {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested0_, i32 0, i32 0),
+// CHECK-STATIC-BE:            i32* bitcast (i8* getelementptr (i8* bitcast ([2 x i32]* @_ZGR6nested0_ to i8*), i64 8) to i32*) }
+// CHECK-STATIC-BE:   {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1_, i32 0, i32 0),
+// CHECK-STATIC-BE:            i32* bitcast (i8* getelementptr (i8* bitcast ([2 x i32]* @_ZGR6nested1_ to i8*), i64 8) to i32*) }
+// CHECK-STATIC-BE:   {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2_, i32 0, i32 0),
+// CHECK-STATIC-BE:            i32* bitcast (i8* getelementptr (i8* bitcast ([2 x i32]* @_ZGR6nested2_ to i8*), i64 8) to i32*) }
 // CHECK-STATIC-BE: ], align 8
-// CHECK-STATIC-BE: @nested = global {{.*}} { {{.*}} getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested3, i32 0, i32 0),
-// CHECK-STATIC-BE:                           {{.*}} bitcast ({{.*}}* getelementptr (i8* bitcast ([3 x {{.*}}]* @_ZGR6nested3 to i8*), i64 48) to {{.*}}*) }
+// CHECK-STATIC-BE: @nested = global {{.*}} { {{.*}} getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested_, i32 0, i32 0),
+// CHECK-STATIC-BE:                           {{.*}} bitcast ({{.*}}* getelementptr (i8* bitcast ([3 x {{.*}}]* @_ZGR6nested_ to i8*), i64 48) to {{.*}}*) }
 
 // CHECK-DYNAMIC-BE: @nested = global
-// CHECK-DYNAMIC-BE: @_ZGR6nested = private global [3 x
-// CHECK-DYNAMIC-BE: @_ZGR6nested1 = private global [2 x i32] zeroinitializer
-// CHECK-DYNAMIC-BE: @_ZGR6nested2 = private global [2 x i32] zeroinitializer
-// CHECK-DYNAMIC-BE: @_ZGR6nested3 = private global [2 x i32] zeroinitializer
-// CHECK-DYNAMIC-BE: store i32 1, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 0)
-// CHECK-DYNAMIC-BE: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 1)
-// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 0, i64 0),
-// CHECK-DYMAMIC-BE:       i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 0, i32 0), align 8
-// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1, i64 1, i64 0),
-// CHECK-DYMAMIC-BE:       i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 0, i32 1), align 8
-// CHECK-DYNAMIC-BE: store i32 3, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 0)
-// CHECK-DYNAMIC-BE: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 1)
-// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 0, i64 0),
-// CHECK-DYNAMIC-BE:       i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 1, i32 0), align 8
-// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2, i64 1, i64 0),
-// CHECK-DYNAMIC-BE:       i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 1, i32 1), align 8
-// CHECK-DYNAMIC-BE: store i32 5, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested3, i64 0, i64 0)
-// CHECK-DYNAMIC-BE: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested3, i64 0, i64 1)
-// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested3, i64 0, i64 0),
-// CHECK-DYNAMIC-BE:       i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 2, i32 0), align 8
-// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested3, i64 1, i64 0),
-// CHECK-DYNAMIC-BE:       i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 2, i32 1), align 8
-// CHECK-DYNAMIC-BE: store {{.*}}* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 0, i64 0),
+// CHECK-DYNAMIC-BE: @_ZGR6nested_ = private global [3 x
+// CHECK-DYNAMIC-BE: @_ZGR6nested0_ = private global [2 x i32] zeroinitializer
+// CHECK-DYNAMIC-BE: @_ZGR6nested1_ = private global [2 x i32] zeroinitializer
+// CHECK-DYNAMIC-BE: @_ZGR6nested2_ = private global [2 x i32] zeroinitializer
+// CHECK-DYNAMIC-BE: store i32 1, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested0_, i64 0, i64 0)
+// CHECK-DYNAMIC-BE: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested0_, i64 0, i64 1)
+// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested0_, i64 0, i64 0),
+// CHECK-DYNAMIC-BE:       i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 0, i32 0), align 8
+// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested0_, i64 1, i64 0),
+// CHECK-DYNAMIC-BE:       i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 0, i32 1), align 8
+// CHECK-DYNAMIC-BE: store i32 3, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1_, i64 0, i64 0)
+// CHECK-DYNAMIC-BE: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1_, i64 0, i64 1)
+// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1_, i64 0, i64 0),
+// CHECK-DYNAMIC-BE:       i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 1, i32 0), align 8
+// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1_, i64 1, i64 0),
+// CHECK-DYNAMIC-BE:       i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 1, i32 1), align 8
+// CHECK-DYNAMIC-BE: store i32 5, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2_, i64 0, i64 0)
+// CHECK-DYNAMIC-BE: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2_, i64 0, i64 1)
+// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2_, i64 0, i64 0),
+// CHECK-DYNAMIC-BE:       i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 2, i32 0), align 8
+// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2_, i64 1, i64 0),
+// CHECK-DYNAMIC-BE:       i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 2, i32 1), align 8
+// CHECK-DYNAMIC-BE: store {{.*}}* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 0),
 // CHECK-DYNAMIC-BE:       {{.*}}** getelementptr inbounds ({{.*}}* @nested, i32 0, i32 0), align 8
-// CHECK-DYNAMIC-BE: store {{.*}}* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested, i64 1, i64 0),
+// CHECK-DYNAMIC-BE: store {{.*}}* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested_, i64 1, i64 0),
 // CHECK-DYNAMIC-BE:       {{.*}}** getelementptr inbounds ({{.*}}* @nested, i32 0, i32 1), align 8
diff --git a/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp b/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp
index 8e0d161..5a48346 100644
--- a/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp
+++ b/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp
@@ -32,8 +32,8 @@
   };
 }
 
-// CHECK: @_ZGR15globalInitList1 = private constant [3 x i32] [i32 1, i32 2, i32 3]
-// CHECK: @globalInitList1 = global {{[^ ]+}} { i32* getelementptr inbounds ([3 x i32]* @_ZGR15globalInitList1, {{[^)]*}}), i32*
+// CHECK: @_ZGR15globalInitList1_ = private constant [3 x i32] [i32 1, i32 2, i32 3]
+// CHECK: @globalInitList1 = global {{[^ ]+}} { i32* getelementptr inbounds ([3 x i32]* @_ZGR15globalInitList1_, {{[^)]*}}), i32*
 std::initializer_list<int> globalInitList1 = {1, 2, 3};
 
 void fn1(int i) {
diff --git a/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp b/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
index 164cbce..4d30344 100644
--- a/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
+++ b/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -S -triple x86_64-none-linux-gnu -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-none-linux-gnu -emit-llvm -o - %s | FileCheck %s
 
 namespace std {
   typedef decltype(sizeof(int)) size_t;
@@ -47,8 +47,8 @@
   ~wantslist1();
 };
 
-// CHECK: @_ZGR15globalInitList1 = private constant [3 x i32] [i32 1, i32 2, i32 3]
-// CHECK: @globalInitList1 = global %{{[^ ]+}} { i32* getelementptr inbounds ([3 x i32]* @_ZGR15globalInitList1, i32 0, i32 0), i{{32|64}} 3 }
+// CHECK: @_ZGR15globalInitList1_ = private constant [3 x i32] [i32 1, i32 2, i32 3]
+// CHECK: @globalInitList1 = global %{{[^ ]+}} { i32* getelementptr inbounds ([3 x i32]* @_ZGR15globalInitList1_, i32 0, i32 0), i{{32|64}} 3 }
 std::initializer_list<int> globalInitList1 = {1, 2, 3};
 
 namespace thread_local_global_array {
@@ -57,12 +57,12 @@
   // objects aren't really a problem).
   //
   // CHECK: @_ZN25thread_local_global_array1xE = thread_local global
-  // CHECK: @_ZGRN25thread_local_global_array1xE = private thread_local constant [4 x i32] [i32 1, i32 2, i32 3, i32 4]
+  // CHECK: @_ZGRN25thread_local_global_array1xE_ = private thread_local constant [4 x i32] [i32 1, i32 2, i32 3, i32 4]
   std::initializer_list<int> thread_local x = { 1, 2, 3, 4 };
 }
 
 // CHECK: @globalInitList2 = global %{{[^ ]+}} zeroinitializer
-// CHECK: @_ZGR15globalInitList2 = private global [2 x %[[WITHARG:[^ ]*]]] zeroinitializer
+// CHECK: @_ZGR15globalInitList2_ = private global [2 x %[[WITHARG:[^ ]*]]] zeroinitializer
 
 // CHECK: @_ZN15partly_constant1kE = global i32 0, align 4
 // CHECK: @_ZN15partly_constant2ilE = global {{.*}} null, align 8
@@ -77,16 +77,16 @@
 
 // thread_local initializer:
 // CHECK-LABEL: define internal void
-// CHECK: store i32* getelementptr inbounds ([4 x i32]* @_ZGRN25thread_local_global_array1xE, i64 0, i64 0),
+// CHECK: store i32* getelementptr inbounds ([4 x i32]* @_ZGRN25thread_local_global_array1xE_, i64 0, i64 0),
 // CHECK:       i32** getelementptr inbounds ({{.*}}* @_ZN25thread_local_global_array1xE, i32 0, i32 0), align 8
 // CHECK: store i64 4, i64* getelementptr inbounds ({{.*}}* @_ZN25thread_local_global_array1xE, i32 0, i32 1), align 8
 
 
 // CHECK-LABEL: define internal void
-// CHECK: call void @_ZN8witharg1C1ERK10destroyme1(%[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]]* @_ZGR15globalInitList2, i{{32|64}} 0, i{{32|64}} 0
-// CHECK: call void @_ZN8witharg1C1ERK10destroyme1(%[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]]* @_ZGR15globalInitList2, i{{32|64}} 0, i{{32|64}} 1
+// CHECK: call void @_ZN8witharg1C1ERK10destroyme1(%[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]]* @_ZGR15globalInitList2_, i{{32|64}} 0, i{{32|64}} 0
+// CHECK: call void @_ZN8witharg1C1ERK10destroyme1(%[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]]* @_ZGR15globalInitList2_, i{{32|64}} 0, i{{32|64}} 1
 // CHECK: __cxa_atexit
-// CHECK: store %[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]]* @_ZGR15globalInitList2, i64 0, i64 0),
+// CHECK: store %[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]]* @_ZGR15globalInitList2_, i64 0, i64 0),
 // CHECK:       %[[WITHARG]]** getelementptr inbounds (%{{.*}}* @globalInitList2, i32 0, i32 0), align 8
 // CHECK: store i64 2, i64* getelementptr inbounds (%{{.*}}* @globalInitList2, i32 0, i32 1), align 8
 // CHECK: call void @_ZN10destroyme1D1Ev
@@ -384,7 +384,7 @@
   // CHECK-NOT: @[[PARTLY_CONSTANT_THIRD]],
   // CHECK: store i32* getelementptr inbounds ({{.*}}* @[[PARTLY_CONSTANT_THIRD]], i64 0, i64 0),
   // CHECK:       i32** getelementptr inbounds ({{.*}}* @[[PARTLY_CONSTANT_INNER]], i64 0, i64 2, i32 0)
-  // CHECK: store i64 4, i64* getelementptr inbounds ({{.*}}* @_ZGRN15partly_constant2ilE4, i64 0, i64 2, i32 1)
+  // CHECK: store i64 4, i64* getelementptr inbounds ({{.*}}* @_ZGRN15partly_constant2ilE4_, i64 0, i64 2, i32 1)
   // CHECK-NOT: @[[PARTLY_CONSTANT_THIRD]],
   //
   // Outer init list.
@@ -431,3 +431,37 @@
     // CHECK: }
   }
 }
+
+namespace DR1070 {
+  struct A {
+    A(std::initializer_list<int>);
+  };
+  struct B {
+    int i;
+    A a;
+  };
+  B b = {1};
+  struct C {
+    std::initializer_list<int> a;
+    B b;
+    std::initializer_list<double> c;
+  };
+  C c = {};
+}
+
+namespace ArrayOfInitList {
+  struct S {
+    S(std::initializer_list<int>);
+  };
+  S x[1] = {};
+}
+
+namespace PR20445 {
+  struct vector { vector(std::initializer_list<int>); };
+  struct MyClass { explicit MyClass(const vector &v); };
+  template<int x> void f() { new MyClass({42, 43}); }
+  template void f<0>();
+  // CHECK-LABEL: define {{.*}} @_ZN7PR204451fILi0EEEvv(
+  // CHECK: call void @_ZN7PR204456vectorC1ESt16initializer_listIiE(
+  // CHECK: call void @_ZN7PR204457MyClassC1ERKNS_6vectorE(
+}
diff --git a/test/CodeGenCXX/cxx11-exception-spec.cpp b/test/CodeGenCXX/cxx11-exception-spec.cpp
index 96ea1d7..3b1516b 100644
--- a/test/CodeGenCXX/cxx11-exception-spec.cpp
+++ b/test/CodeGenCXX/cxx11-exception-spec.cpp
@@ -1,4 +1,5 @@
-// RUN: not %clang_cc1 -std=c++11 -emit-llvm %s -o - -verify -fexceptions -fcxx-exceptions -triple x86_64-linux-gnu | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -verify -fexceptions -fcxx-exceptions -triple x86_64-linux-gnu | FileCheck %s
+// expected-no-diagnostics
 
 void h();
 
diff --git a/test/CodeGenCXX/cxx11-initializer-aggregate.cpp b/test/CodeGenCXX/cxx11-initializer-aggregate.cpp
index acc7782..789970b 100644
--- a/test/CodeGenCXX/cxx11-initializer-aggregate.cpp
+++ b/test/CodeGenCXX/cxx11-initializer-aggregate.cpp
@@ -20,6 +20,25 @@
   // CHECK: %[[INITLIST2:.*]] = alloca %struct.B, align 8
   // CHECK: %[[R:.*]] = getelementptr inbounds %struct.B* %[[INITLIST2:.*]], i32 0, i32 0
   // CHECK: store i32* %{{.*}}, i32** %[[R]], align 8
-  // CHECK: call i32* @_ZN1B1fEv(%struct.B* %[[INITLIST2:.*]])
+  // CHECK: call dereferenceable({{[0-9]+}}) i32* @_ZN1B1fEv(%struct.B* %[[INITLIST2:.*]])
   return B{v}.f();
 }
+
+// CHECK: define {{.*}}@__cxx_global_var_init(
+//
+// CHECK: call {{.*}}@_ZN14NonTrivialInit1AC1Ev(
+// CHECK: getelementptr inbounds {{.*}}, i64 1
+// CHECK: br i1
+//
+// CHECK: getelementptr inbounds {{.*}}, i64 1
+// CHECK: icmp eq {{.*}}, i64 30
+// CHECK: br i1
+//
+// CHECK: call i32 @__cxa_atexit(
+namespace NonTrivialInit {
+  struct A { A(); A(const A&) = delete; ~A(); };
+  struct B { A a[20]; };
+  // NB, this must be large enough to be worth memsetting for this test to be
+  // meaningful.
+  B b[30] = {};
+}
diff --git a/test/CodeGenCXX/cxx11-initializer-array-new.cpp b/test/CodeGenCXX/cxx11-initializer-array-new.cpp
new file mode 100644
index 0000000..2393939
--- /dev/null
+++ b/test/CodeGenCXX/cxx11-initializer-array-new.cpp
@@ -0,0 +1,160 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 %s -emit-llvm -o - | FileCheck %s
+
+// PR10878
+
+struct S { S(); S(int); ~S(); int n; };
+
+void *p = new S[2][3]{ { 1, 2, 3 }, { 4, 5, 6 } };
+
+// CHECK-LABEL: define
+// CHECK: %[[ALLOC:.*]] = call noalias i8* @_Znam(i64 32)
+// CHECK: %[[COOKIE:.*]] = bitcast i8* %[[ALLOC]] to i64*
+// CHECK: store i64 6, i64* %[[COOKIE]]
+// CHECK: %[[START_AS_i8:.*]] = getelementptr inbounds i8* %[[ALLOC]], i64 8
+// CHECK: %[[START_AS_S:.*]] = bitcast i8* %[[START_AS_i8]] to %[[S:.*]]*
+//
+// Explicit initializers:
+//
+// { 1, 2, 3 }
+//
+// CHECK: %[[S_0:.*]] = bitcast %[[S]]* %[[START_AS_S]] to [3 x %[[S]]]*
+//
+// CHECK: %[[S_0_0:.*]] = getelementptr inbounds [3 x %[[S]]]* %[[S_0]], i64 0, i64 0
+// CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_0_0]], i32 1)
+// CHECK: %[[S_0_1:.*]] = getelementptr inbounds %[[S]]* %[[S_0_0]], i64 1
+// CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_0_1]], i32 2)
+// CHECK: %[[S_0_2:.*]] = getelementptr inbounds %[[S]]* %[[S_0_1]], i64 1
+// CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_0_2]], i32 3)
+//
+// { 4, 5, 6 }
+//
+// CHECK: %[[S_1:.*]] = getelementptr inbounds [3 x %[[S]]]* %[[S_0]], i32 1
+//
+// CHECK: %[[S_1_0:.*]] = getelementptr inbounds [3 x %[[S]]]* %[[S_1]], i64 0, i64 0
+// CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_1_0]], i32 4)
+// CHECK: %[[S_1_1:.*]] = getelementptr inbounds %[[S]]* %[[S_1_0]], i64 1
+// CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_1_1]], i32 5)
+// CHECK: %[[S_1_2:.*]] = getelementptr inbounds %[[S]]* %[[S_1_1]], i64 1
+// CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_1_2]], i32 6)
+//
+// CHECK-NOT: br i1
+// CHECK-NOT: call
+// CHECK: }
+
+int n;
+void *q = new S[n][3]{ { 1, 2, 3 }, { 4, 5, 6 } };
+
+// CHECK-LABEL: define
+//
+// CHECK: load i32* @n
+// CHECK: call {{.*}} @llvm.umul.with.overflow.i64(i64 %[[N:.*]], i64 12)
+// CHECK: %[[ELTS:.*]] = mul i64 %[[N]], 3
+// CHECK: call {{.*}} @llvm.uadd.with.overflow.i64(i64 %{{.*}}, i64 8)
+// CHECK: %[[ALLOC:.*]] = call noalias i8* @_Znam(i64 %{{.*}})
+//
+// CHECK: %[[COOKIE:.*]] = bitcast i8* %[[ALLOC]] to i64*
+// CHECK: store i64 %[[ELTS]], i64* %[[COOKIE]]
+// CHECK: %[[START_AS_i8:.*]] = getelementptr inbounds i8* %[[ALLOC]], i64 8
+// CHECK: %[[START_AS_S:.*]] = bitcast i8* %[[START_AS_i8]] to %[[S]]*
+//
+// Explicit initializers:
+//
+// { 1, 2, 3 }
+//
+// CHECK: %[[S_0:.*]] = bitcast %[[S]]* %[[START_AS_S]] to [3 x %[[S]]]*
+//
+// CHECK: %[[S_0_0:.*]] = getelementptr inbounds [3 x %[[S]]]* %[[S_0]], i64 0, i64 0
+// CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_0_0]], i32 1)
+// CHECK: %[[S_0_1:.*]] = getelementptr inbounds %[[S]]* %[[S_0_0]], i64 1
+// CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_0_1]], i32 2)
+// CHECK: %[[S_0_2:.*]] = getelementptr inbounds %[[S]]* %[[S_0_1]], i64 1
+// CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_0_2]], i32 3)
+//
+// { 4, 5, 6 }
+//
+// CHECK: %[[S_1:.*]] = getelementptr inbounds [3 x %[[S]]]* %[[S_0]], i32 1
+//
+// CHECK: %[[S_1_0:.*]] = getelementptr inbounds [3 x %[[S]]]* %[[S_1]], i64 0, i64 0
+// CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_1_0]], i32 4)
+// CHECK: %[[S_1_1:.*]] = getelementptr inbounds %[[S]]* %[[S_1_0]], i64 1
+// CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_1_1]], i32 5)
+// CHECK: %[[S_1_2:.*]] = getelementptr inbounds %[[S]]* %[[S_1_1]], i64 1
+// CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_1_2]], i32 6)
+//
+// And the rest.
+//
+// CHECK: %[[S_2:.*]] = getelementptr inbounds [3 x %[[S]]]* %[[S_1]], i32 1
+// CHECK: %[[S_2_AS_S:.*]] = bitcast [3 x %[[S]]]* %[[S_2]] to %[[S]]*
+//
+// CHECK: %[[REST:.*]] = sub i64 %[[ELTS]], 6
+// CHECK: icmp eq i64 %[[REST]], 0
+// CHECK: br i1
+//
+// CHECK: %[[END:.*]] = getelementptr inbounds %[[S]]* %[[S_2_AS_S]], i64 %[[REST]]
+// CHECK: br label
+//
+// CHECK: %[[CUR:.*]] = phi %[[S]]* [ %[[S_2_AS_S]], {{.*}} ], [ %[[NEXT:.*]], {{.*}} ]
+// CHECK: call void @_ZN1SC1Ev(%[[S]]* %[[CUR]])
+// CHECK: %[[NEXT]] = getelementptr inbounds %[[S]]* %[[CUR]], i64 1
+// CHECK: icmp eq %[[S]]* %[[NEXT]], %[[END]]
+// CHECK: br i1
+//
+// CHECK: }
+
+struct T { int a; };
+void *r = new T[n][3]{ { 1, 2, 3 }, { 4, 5, 6 } };
+
+// CHECK-LABEL: define
+//
+// CHECK: load i32* @n
+// CHECK: call {{.*}} @llvm.umul.with.overflow.i64(i64 %[[N:.*]], i64 12)
+// CHECK: %[[ELTS:.*]] = mul i64 %[[N]], 3
+//
+// No cookie.
+// CHECK-NOT: @llvm.uadd.with.overflow
+//
+// CHECK: %[[ALLOC:.*]] = call noalias i8* @_Znam(i64 %{{.*}})
+//
+// CHECK: %[[START_AS_T:.*]] = bitcast i8* %[[ALLOC]] to %[[T:.*]]*
+//
+// Explicit initializers:
+//
+// { 1, 2, 3 }
+//
+// CHECK: %[[T_0:.*]] = bitcast %[[T]]* %[[START_AS_T]] to [3 x %[[T]]]*
+//
+// CHECK: %[[T_0_0:.*]] = getelementptr inbounds [3 x %[[T]]]* %[[T_0]], i64 0, i64 0
+// CHECK: %[[T_0_0_0:.*]] = getelementptr inbounds %[[T]]* %[[T_0_0]], i32 0, i32 0
+// CHECK: store i32 1, i32* %[[T_0_0_0]]
+// CHECK: %[[T_0_1:.*]] = getelementptr inbounds %[[T]]* %[[T_0_0]], i64 1
+// CHECK: %[[T_0_1_0:.*]] = getelementptr inbounds %[[T]]* %[[T_0_1]], i32 0, i32 0
+// CHECK: store i32 2, i32* %[[T_0_1_0]]
+// CHECK: %[[T_0_2:.*]] = getelementptr inbounds %[[T]]* %[[T_0_1]], i64 1
+// CHECK: %[[T_0_2_0:.*]] = getelementptr inbounds %[[T]]* %[[T_0_2]], i32 0, i32 0
+// CHECK: store i32 3, i32* %[[T_0_2_0]]
+//
+// { 4, 5, 6 }
+//
+// CHECK: %[[T_1:.*]] = getelementptr inbounds [3 x %[[T]]]* %[[T_0]], i32 1
+//
+// CHECK: %[[T_1_0:.*]] = getelementptr inbounds [3 x %[[T]]]* %[[T_1]], i64 0, i64 0
+// CHECK: %[[T_1_0_0:.*]] = getelementptr inbounds %[[T]]* %[[T_1_0]], i32 0, i32 0
+// CHECK: store i32 4, i32* %[[T_1_0_0]]
+// CHECK: %[[T_1_1:.*]] = getelementptr inbounds %[[T]]* %[[T_1_0]], i64 1
+// CHECK: %[[T_1_1_0:.*]] = getelementptr inbounds %[[T]]* %[[T_1_1]], i32 0, i32 0
+// CHECK: store i32 5, i32* %[[T_1_1_0]]
+// CHECK: %[[T_1_2:.*]] = getelementptr inbounds %[[T]]* %[[T_1_1]], i64 1
+// CHECK: %[[T_1_2_0:.*]] = getelementptr inbounds %[[T]]* %[[T_1_2]], i32 0, i32 0
+// CHECK: store i32 6, i32* %[[T_1_2_0]]
+//
+// And the rest gets memset to 0.
+//
+// CHECK: %[[T_2:.*]] = getelementptr inbounds [3 x %[[T]]]* %[[T_1]], i32 1
+// CHECK: %[[T_2_AS_T:.*]] = bitcast [3 x %[[T]]]* %[[T_2]] to %[[T]]*
+//
+// CHECK: %[[SIZE:.*]] = sub i64 %{{.*}}, 24
+// CHECK: %[[REST:.*]] = bitcast %[[T]]* %[[T_2_AS_T]] to i8*
+// CHECK: call void @llvm.memset.p0i8.i64(i8* %[[REST]], i8 0, i64 %[[SIZE]], i32 4, i1 false)
+//
+// CHECK: }
+
diff --git a/test/CodeGenCXX/cxx11-noreturn.cpp b/test/CodeGenCXX/cxx11-noreturn.cpp
index 31c651d..b876bb9 100644
--- a/test/CodeGenCXX/cxx11-noreturn.cpp
+++ b/test/CodeGenCXX/cxx11-noreturn.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -std=c++11 %s -o - | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -std=c++11 %s -o - | FileCheck %s
 
 int g();
 
diff --git a/test/CodeGenCXX/cxx11-thread-local-reference.cpp b/test/CodeGenCXX/cxx11-thread-local-reference.cpp
index 7759d41..4143164 100644
--- a/test/CodeGenCXX/cxx11-thread-local-reference.cpp
+++ b/test/CodeGenCXX/cxx11-thread-local-reference.cpp
@@ -10,10 +10,10 @@
 int &g() { return r; }
 
 // CHECK: define {{.*}} @[[R_INIT:.*]]()
-// CHECK: call i32* @_Z1fv()
+// CHECK: call dereferenceable({{[0-9]+}}) i32* @_Z1fv()
 // CHECK: store i32* %{{.*}}, i32** @r, align 8
 
-// CHECK-LABEL: define i32* @_Z1gv()
+// CHECK-LABEL: define dereferenceable({{[0-9]+}}) i32* @_Z1gv()
 // CHECK: call i32* @_ZTW1r()
 // CHECK: ret i32* %{{.*}}
 
diff --git a/test/CodeGenCXX/cxx11-thread-local.cpp b/test/CodeGenCXX/cxx11-thread-local.cpp
index 509562d..a3690b3 100644
--- a/test/CodeGenCXX/cxx11-thread-local.cpp
+++ b/test/CodeGenCXX/cxx11-thread-local.cpp
@@ -21,7 +21,7 @@
 // CHECK: @e = global i32 0
 int e = V<int>::m;
 
-// CHECK: @_ZN1VIiE1mE = weak_odr thread_local global i32 0
+// CHECK: @_ZN1VIiE1mE = linkonce_odr thread_local global i32 0
 
 // CHECK: @_ZZ1fvE1n = internal thread_local global i32 0
 
@@ -35,9 +35,9 @@
 
 // CHECK: @_ZZ8tls_dtorvE1u = internal thread_local global
 // CHECK: @_ZGVZ8tls_dtorvE1u = internal thread_local global i8 0
-// CHECK: @_ZGRZ8tls_dtorvE1u = private thread_local global
+// CHECK: @_ZGRZ8tls_dtorvE1u_ = internal thread_local global
 
-// CHECK: @_ZGVN1VIiE1mE = weak_odr thread_local global i64 0
+// CHECK: @_ZGVN1VIiE1mE = linkonce_odr thread_local global i64 0
 
 // CHECK: @__tls_guard = internal thread_local global i8 0
 
@@ -46,7 +46,7 @@
 // CHECK: @_ZTH1a = alias void ()* @__tls_init
 // CHECK: @_ZTHL1d = alias internal void ()* @__tls_init
 // CHECK: @_ZTHN1U1mE = alias void ()* @__tls_init
-// CHECK: @_ZTHN1VIiE1mE = alias weak_odr void ()* @__tls_init
+// CHECK: @_ZTHN1VIiE1mE = alias linkonce_odr void ()* @__tls_init
 
 
 // Individual variable initialization functions:
@@ -120,8 +120,8 @@
   static thread_local T t;
 
   // CHECK: load i8* @_ZGVZ8tls_dtorvE1u
-  // CHECK: call void @_ZN1SC1Ev(%struct.S* @_ZGRZ8tls_dtorvE1u)
-  // CHECK: call i32 @__cxa_thread_atexit({{.*}}@_ZN1SD1Ev {{.*}} @_ZGRZ8tls_dtorvE1u{{.*}} @__dso_handle
+  // CHECK: call void @_ZN1SC1Ev(%struct.S* @_ZGRZ8tls_dtorvE1u_)
+  // CHECK: call i32 @__cxa_thread_atexit({{.*}}@_ZN1SD1Ev {{.*}} @_ZGRZ8tls_dtorvE1u_{{.*}} @__dso_handle
   // CHECK: store i8 1, i8* @_ZGVZ8tls_dtorvE1u
   static thread_local const S &u = S();
 }
@@ -135,6 +135,24 @@
   return l();
 }
 
+struct PR19254 {
+  static thread_local int n;
+  int f();
+};
+// CHECK: define {{.*}} @_ZN7PR192541fEv(
+int PR19254::f() {
+  // CHECK: call void @_ZTHN7PR192541nE(
+  return this->n;
+}
+
+namespace {
+thread_local int anon_i{1};
+}
+void set_anon_i() {
+  anon_i = 2;
+}
+// CHECK-LABEL: define internal i32* @_ZTWN12_GLOBAL__N_16anon_iE()
+
 // CHECK: define {{.*}} @[[V_M_INIT:.*]]()
 // CHECK: load i8* bitcast (i64* @_ZGVN1VIiE1mE to i8*)
 // CHECK: %[[V_M_INITIALIZED:.*]] = icmp eq i8 %{{.*}}, 0
@@ -171,7 +189,7 @@
 // CHECK: declare extern_weak void @_ZTH1b()
 
 
-// CHECK-LABEL: define internal hidden i32* @_ZTWL1d()
+// CHECK-LABEL: define internal i32* @_ZTWL1d()
 // CHECK: call void @_ZTHL1d()
 // CHECK: ret i32* @_ZL1d
 
diff --git a/test/CodeGenCXX/cxx11-unrestricted-union.cpp b/test/CodeGenCXX/cxx11-unrestricted-union.cpp
index 0397775..2f22ad2 100644
--- a/test/CodeGenCXX/cxx11-unrestricted-union.cpp
+++ b/test/CodeGenCXX/cxx11-unrestricted-union.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++11 -emit-llvm %s -o - | FileCheck %s
 
 struct A {
   A(); A(const A&); A(A&&); A &operator=(const A&); A &operator=(A&&); ~A();
diff --git a/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp b/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp
index ae49a04..8bdf863 100644
--- a/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp
+++ b/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp
@@ -46,7 +46,7 @@
 // CHECK: store i8 %{{.*}}, i8* getelementptr inbounds ({{.*}} @a, i32 0, i32 2)
 // CHECK: call i32 @_ZN1A1fEv({{.*}} @a)
 // CHECK: store i32 %{{.*}}, i32* getelementptr inbounds ({{.*}}* @a, i32 0, i32 3)
-// CHECK: call void @{{.*}}C1Ev({{.*}} getelementptr inbounds (%struct.A* @a, i32 0, i32 4))
+// CHECK: store double 1.000000e+00, double* getelementptr inbounds ({{.*}} @a, i32 0, i32 4, i32 0)
 
 // No dynamic initialization of 'b':
 
diff --git a/test/CodeGenCXX/cxx1y-sized-deallocation.cpp b/test/CodeGenCXX/cxx1y-sized-deallocation.cpp
index 642e1e0..7fd3ece 100644
--- a/test/CodeGenCXX/cxx1y-sized-deallocation.cpp
+++ b/test/CodeGenCXX/cxx1y-sized-deallocation.cpp
@@ -30,6 +30,8 @@
 void del() {
   ::delete get<T*>();
   ::delete[] get<T*>();
+  delete get<T*>();
+  delete[] get<T*>();
 }
 
 template void del<A>();
@@ -44,6 +46,9 @@
 // CHECK-LABEL: define weak_odr void @_Z3delIiEvv()
 // CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 4)
 // CHECK: call void @_ZdaPv(i8* %{{[^ ]*}})
+//
+// CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 4)
+// CHECK: call void @_ZdaPv(i8* %{{[^ ]*}})
 
 // CHECK-LABEL: define linkonce void @_ZdlPvm(i8*
 // CHECK: call void @_ZdlPv(i8* %0)
@@ -51,12 +56,20 @@
 // CHECK-LABEL: define weak_odr void @_Z3delI1BEvv()
 // CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 4)
 // CHECK: call void @_ZdaPv(i8* %{{[^ ]*}})
+//
+// CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 4)
+// CHECK: call void @_ZdaPv(i8* %{{[^ ]*}})
 
 // CHECK-LABEL: define weak_odr void @_Z3delI1CEvv()
 // CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 1)
 // CHECK: mul i64 1, %{{[^ ]*}}
 // CHECK: add i64 %{{[^ ]*}}, 8
 // CHECK: call void @_ZdaPvm(i8* %{{[^ ]*}}, i64 %{{[^ ]*}})
+//
+// CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 1)
+// CHECK: mul i64 1, %{{[^ ]*}}
+// CHECK: add i64 %{{[^ ]*}}, 8
+// CHECK: call void @_ZdaPvm(i8* %{{[^ ]*}}, i64 %{{[^ ]*}})
 
 // CHECK-LABEL: define linkonce void @_ZdaPvm(i8*
 // CHECK: call void @_ZdaPv(i8* %0)
@@ -66,25 +79,32 @@
 // CHECK: mul i64 8, %{{[^ ]*}}
 // CHECK: add i64 %{{[^ ]*}}, 8
 // CHECK: call void @_ZdaPvm(i8* %{{[^ ]*}}, i64 %{{[^ ]*}})
+//
+// CHECK-NOT: Zdl
+// CHECK: call void %{{.*}}
+// CHECK-NOT: Zdl
+// CHECK: mul i64 8, %{{[^ ]*}}
+// CHECK: add i64 %{{[^ ]*}}, 8
+// CHECK: call void @_ZdaPvm(i8* %{{[^ ]*}}, i64 %{{[^ ]*}})
 
 // CHECK-LABEL: define weak_odr void @_Z3delI1EEvv()
 // CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 1)
 // CHECK: call void @_ZdaPv(i8* %{{[^ ]*}})
+//
+// CHECK: call void @_ZN1EdlEPv(i8* %{{[^ ]*}})
+// CHECK: call void @_ZN1EdaEPv(i8* %{{[^ ]*}})
 
 // CHECK-LABEL: define weak_odr void @_Z3delI1FEvv()
 // CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 1)
 // CHECK: mul i64 1, %{{[^ ]*}}
 // CHECK: add i64 %{{[^ ]*}}, 8
 // CHECK: call void @_ZdaPvm(i8* %{{[^ ]*}}, i64 %{{[^ ]*}})
+//
+// CHECK: call void @_ZN1FdlEPvm(i8* %{{[^ ]*}}, i64 1)
+// CHECK: mul i64 1, %{{[^ ]*}}
+// CHECK: add i64 %{{[^ ]*}}, 8
+// CHECK: call void @_ZN1FdaEPvm(i8* %{{[^ ]*}}, i64 %{{[^ ]*}})
 
-// CHECK-LABEL: define void @_Z10member_delv()
-// CHECK-NOT: Zdl
-// CHECK: call void %{{[^ ]*}}(%{{[^ ]*}}* %
-// CHECK-NOT: Zdl
-// CHECK: }
-void member_del() {
-  delete get<D*>();
-}
 
 // CHECK-LABEL: define linkonce_odr void @_ZN1DD0Ev(%{{[^ ]*}}* %this)
 // CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 8)
diff --git a/test/CodeGenCXX/cxx1y-variable-template.cpp b/test/CodeGenCXX/cxx1y-variable-template.cpp
index d1e7060..cd73817 100644
--- a/test/CodeGenCXX/cxx1y-variable-template.cpp
+++ b/test/CodeGenCXX/cxx1y-variable-template.cpp
@@ -18,7 +18,7 @@
 template<typename T> template<typename U> template<typename V> int Outer<T>::Inner<U>::arr[sizeof(T) + sizeof(U) + sizeof(V)] = { init_arr() };
 int *p = Outer<char[100]>::Inner<char[20]>::arr<char[3]>;
 
-// CHECK: @_ZN5OuterIA100_cE5InnerIA20_cE3arrIA3_cEE = weak_odr global [123 x i32] zeroinitializer
-// CHECK: @_ZGVN5OuterIA100_cE5InnerIA20_cE3arrIA3_cEE = weak_odr global
+// CHECK: @_ZN5OuterIA100_cE5InnerIA20_cE3arrIA3_cEE = linkonce_odr global [123 x i32] zeroinitializer
+// CHECK: @_ZGVN5OuterIA100_cE5InnerIA20_cE3arrIA3_cEE = linkonce_odr global
 
 // CHECK: call {{.*}}@_Z8init_arrv
diff --git a/test/CodeGenCXX/debug-info-alias.cpp b/test/CodeGenCXX/debug-info-alias.cpp
new file mode 100644
index 0000000..fb18ac5
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-alias.cpp
@@ -0,0 +1,37 @@
+// RUN: %clang -g -std=c++11 -S -emit-llvm %s -o - | FileCheck %s
+
+template<typename T>
+struct foo {
+};
+namespace x {
+// splitting these over multiple lines to make sure the right token is used for
+// the location
+template<typename T>
+using
+# 42
+bar
+= foo<T*>;
+}
+
+// CHECK: metadata [[BINT:![0-9]*]], i32 0, i32 1, {{.*}} ; [ DW_TAG_variable ] [bi]
+// CHECK: [[BINT]] = {{.*}} ; [ DW_TAG_typedef ] [bar<int>] [line 42
+x::bar<int> bi;
+// CHECK: metadata [[BFLOAT:![0-9]*]], i32 0, i32 1, {{.*}} ; [ DW_TAG_variable ] [bf]
+// CHECK: [[BFLOAT]] = {{.*}} ; [ DW_TAG_typedef ] [bar<float>] [line 42
+x::bar<float> bf;
+
+using
+// CHECK: metadata [[NARF:![0-9]*]], i32 0, i32 1, {{.*}} ; [ DW_TAG_variable ] [n]
+# 142
+narf // CHECK: [[NARF]] = {{.*}} ; [ DW_TAG_typedef ] [narf] [line 142
+= int;
+narf n;
+
+template <typename T>
+using tv = void;
+// CHECK: null} ; [ DW_TAG_typedef ] [tv<int>] {{.*}} [from ]
+tv<int> *tvp;
+
+using v = void;
+// CHECK: null} ; [ DW_TAG_typedef ] [v] {{.*}} [from ]
+v *vp;
diff --git a/test/CodeGenCXX/debug-info-anon-union-vars.cpp b/test/CodeGenCXX/debug-info-anon-union-vars.cpp
new file mode 100644
index 0000000..396b7e9
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-anon-union-vars.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -emit-llvm -gdwarf-4 -triple x86_64-linux-gnu %s -o - | FileCheck %s
+
+// Make sure that we emit a global variable for each of the members of the
+// anonymous union.
+
+static union {
+  int c;
+  int d;
+  union {
+    int a;
+  };
+  struct {
+    int b;
+  };
+};
+
+int test_it() {
+  c = 1;
+  d = 2;
+  a = 4;
+  return (c == 1);
+}
+
+// CHECK: [[FILE:.*]] = {{.*}}[ DW_TAG_file_type ] [{{.*}}debug-info-anon-union-vars.cpp]
+// CHECK: [[FILE]]{{.*}}[ DW_TAG_variable ] [c] [line 6] [local] [def]
+// CHECK: [[FILE]]{{.*}}[ DW_TAG_variable ] [d] [line 6] [local] [def]
+// CHECK: [[FILE]]{{.*}}[ DW_TAG_variable ] [a] [line 6] [local] [def]
+// CHECK: [[FILE]]{{.*}}[ DW_TAG_variable ] [b] [line 6] [local] [def]
diff --git a/test/CodeGenCXX/debug-info-byval.cpp b/test/CodeGenCXX/debug-info-byval.cpp
index e6317fc..5b0850b 100644
--- a/test/CodeGenCXX/debug-info-byval.cpp
+++ b/test/CodeGenCXX/debug-info-byval.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang -g -S %s -o - | FileCheck %s
+// FIXME: Check IR rather than asm, then triple is not needed.
+// RUN: %clang -Xclang -triple=%itanium_abi_triple -g -S %s -o - | FileCheck %s
 // Test to check presence of debug info for byval parameter.
 // Radar 8350436.
 class DAG {
diff --git a/test/CodeGenCXX/debug-info-char16.cpp b/test/CodeGenCXX/debug-info-char16.cpp
index 06a05b3..e6e2f15 100644
--- a/test/CodeGenCXX/debug-info-char16.cpp
+++ b/test/CodeGenCXX/debug-info-char16.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -std=c++11 -g %s -o -| FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -std=c++11 -g %s -o -| FileCheck %s
 
 // 16 is DW_ATE_UTF (0x10) encoding attribute.
 char16_t char_a = u'h';
diff --git a/test/CodeGenCXX/debug-info-class-limited-plugin.test b/test/CodeGenCXX/debug-info-class-limited-plugin.test
new file mode 100644
index 0000000..61d258d
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-class-limited-plugin.test
@@ -0,0 +1,2 @@
+RUN: %clang_cc1 -emit-llvm -fno-standalone-debug -g -o - -load %llvmshlibdir/PrintFunctionNames%pluginext -add-plugin print-function-names %S/Inputs/debug-info-class-limited.cpp 2>&1 | FileCheck %S/Inputs/debug-info-class-limited.cpp
+REQUIRES: plugins, examples
diff --git a/test/CodeGenCXX/debug-info-class-limited.cpp b/test/CodeGenCXX/debug-info-class-limited.cpp
deleted file mode 100644
index a4b9f46..0000000
--- a/test/CodeGenCXX/debug-info-class-limited.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-// RUN: %clang -emit-llvm -g -S %s -o - | FileCheck %s
-
-namespace PR16214_1 {
-// CHECK-DAG: [ DW_TAG_structure_type ] [foo] [line [[@LINE+1]], {{.*}} [def]
-struct foo {
-  int i;
-};
-
-typedef foo bar;
-
-bar *a;
-bar b;
-}
-
-namespace PR14467 {
-// CHECK-DAG: [ DW_TAG_structure_type ] [foo] [line [[@LINE+1]], {{.*}} [def]
-struct foo {
-};
-
-foo *bar(foo *a) {
-  foo *b = new foo(*a);
-  return b;
-}
-}
-
-namespace test1 {
-// CHECK-DAG: [ DW_TAG_structure_type ] [foo] [line [[@LINE+1]], {{.*}} [decl]
-struct foo {
-};
-
-extern int bar(foo *a);
-int baz(foo *a) {
-  return bar(a);
-}
-}
-
-namespace test2 {
-// FIXME: if we were a bit fancier, we could realize that the 'foo' type is only
-// required because of the 'bar' type which is not required at all (or might
-// only be required to be declared)
-// CHECK-DAG: [ DW_TAG_structure_type ] [foo] [line [[@LINE+1]], {{.*}} [def]
-struct foo {
-};
-
-struct bar {
-  foo f;
-};
-
-void func() {
-  foo *f;
-}
-}
diff --git a/test/CodeGenCXX/debug-info-class-limited.test b/test/CodeGenCXX/debug-info-class-limited.test
new file mode 100644
index 0000000..0b10728
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-class-limited.test
@@ -0,0 +1 @@
+RUN: %clang_cc1 -emit-llvm -fno-standalone-debug -g %S/Inputs/debug-info-class-limited.cpp -o - | FileCheck %S/Inputs/debug-info-class-limited.cpp
diff --git a/test/CodeGenCXX/debug-info-class-nolimit.cpp b/test/CodeGenCXX/debug-info-class-nolimit.cpp
index ce72bd3..7a6ee4d 100644
--- a/test/CodeGenCXX/debug-info-class-nolimit.cpp
+++ b/test/CodeGenCXX/debug-info-class-nolimit.cpp
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -triple x86_64-unk-unk -fno-limit-debug-info -o - -emit-llvm -g %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unk-unk -fstandalone-debug -o - -emit-llvm -g %s | FileCheck %s
+// On Darwin, this should be the default:
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -o - -emit-llvm -g %s | FileCheck %s
 
 namespace rdar14101097_1 { // see also PR16214
 // Check that we emit debug info for the definition of a struct if the
diff --git a/test/CodeGenCXX/debug-info-class.cpp b/test/CodeGenCXX/debug-info-class.cpp
index e1402c9..34add04 100644
--- a/test/CodeGenCXX/debug-info-class.cpp
+++ b/test/CodeGenCXX/debug-info-class.cpp
@@ -102,13 +102,9 @@
 // CHECK: [[C_S]] = {{.*}} ; [ DW_TAG_member ] [s] {{.*}} [static] [from int]
 // CHECK: [[C_DTOR]] = {{.*}} ; [ DW_TAG_subprogram ] {{.*}} [~C]
 
-// CHECK: metadata [[D_MEM:![0-9]*]], i32 0, null, null, metadata !"_ZTS1D"} ; [ DW_TAG_structure_type ] [D] {{.*}} [decl]
-// CHECK: [[D_MEM]] = metadata !{metadata [[D_FUNC:![0-9]*]]}
-// CHECK: [[D_FUNC]] = {{.*}} ; [ DW_TAG_subprogram ] {{.*}} [func]
+// CHECK: null, i32 0, null, null, metadata !"_ZTS1D"} ; [ DW_TAG_structure_type ] [D] {{.*}} [decl]
 // CHECK: null, i32 0, null, null, metadata !"_ZTS1E"} ; [ DW_TAG_structure_type ] [E] {{.*}} [decl]
-// CHECK: [[F:![0-9]*]] = {{.*}} metadata [[F_MEM:![0-9]*]], i32 0, null, null, metadata !"_ZTS1F"} ; [ DW_TAG_structure_type ] [F] {{.*}} [decl]
-// CHECK: [[F_MEM]] = metadata !{metadata [[F_I:![0-9]*]]}
-// CHECK: [[F_I]] = {{.*}} ; [ DW_TAG_member ] [i]
+// CHECK: [[F:![0-9]*]] = {{.*}} null, i32 0, null, null, metadata !"_ZTS1F"} ; [ DW_TAG_structure_type ] [F] {{.*}} [decl]
 
 // CHECK: null, i32 0, null, null, metadata !"_ZTS1G"} ; [ DW_TAG_structure_type ] [G] {{.*}} [decl]
 // CHECK: metadata [[G_INNER_MEM:![0-9]*]], i32 0, null, null, metadata !"_ZTSN1G5innerE"} ; [ DW_TAG_structure_type ] [inner] [line 50, {{.*}} [def]
@@ -118,8 +114,13 @@
 // CHECK: ; [ DW_TAG_structure_type ] [A]
 // CHECK: HdrSize
 // CHECK: ; [ DW_TAG_structure_type ] [I] {{.*}} [def]
+//
+// CHECK: metadata !"_ZTS1D", {{.*}}, metadata [[D_FUNC_DECL:![0-9]*]], metadata {{![0-9]*}}, i32 {{[0-9]*}}} ; [ DW_TAG_subprogram ] {{.*}} [def] [func]
+// CHECK: [[D_FUNC_DECL]] = {{.*}}, metadata !"_ZTS1D", {{.*}}, i32 0, null, i32 {{[0-9]*}}} ; [ DW_TAG_subprogram ] {{.*}} [func]
 
-// CHECK: [[F_I_DEF:![0-9]*]] = {{.*}}, metadata [[F_I]]} ; [ DW_TAG_variable ] [i]
+// CHECK: [[F_I_DEF:![0-9]*]] = {{.*}}, metadata [[F_I:![0-9]*]]} ; [ DW_TAG_variable ] [i]
+
+// CHECK: [[F_I]] = {{.*}}, metadata !"_ZTS1F", {{.*}} ; [ DW_TAG_member ] [i]
 
 // CHECK: ![[EXCEPTLOC]] = metadata !{i32 84,
 // CHECK: ![[RETLOC]] = metadata !{i32 83,
diff --git a/test/CodeGenCXX/debug-info-ctor2.cpp b/test/CodeGenCXX/debug-info-ctor2.cpp
index 19bd64b..3bc931e 100644
--- a/test/CodeGenCXX/debug-info-ctor2.cpp
+++ b/test/CodeGenCXX/debug-info-ctor2.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang -fverbose-asm -g -S %s -o - | grep AT_explicit
+// FIXME: Check IR rather than asm, then triple is not needed.
+// RUN: %clang -Xclang -triple=%itanium_abi_triple -fverbose-asm -g -S %s -o - | grep AT_explicit
 
 
 class MyClass
diff --git a/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp b/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp
index 04fe7a0..1b9a055 100644
--- a/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp
+++ b/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -g -triple x86_64-apple-darwin -fno-limit-debug-info %s -o - | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -g -triple x86_64-apple-darwin -fstandalone-debug %s -o - | FileCheck %s
 
 class Test
 {
diff --git a/test/CodeGenCXX/debug-info-enum-class.cpp b/test/CodeGenCXX/debug-info-enum-class.cpp
index 0f4b09a..f0b97cc 100644
--- a/test/CodeGenCXX/debug-info-enum-class.cpp
+++ b/test/CodeGenCXX/debug-info-enum-class.cpp
@@ -12,7 +12,6 @@
 // CHECK: ; [ DW_TAG_enumeration_type ] [A] [line 3, size 32, align 32, offset 0] [def] [from int]
 // CHECK: ; [ DW_TAG_enumeration_type ] [B] [line 4, size 64, align 64, offset 0] [def] [from long unsigned int]
 // CHECK: ; [ DW_TAG_enumeration_type ] [C] [line 5, size 32, align 32, offset 0] [def] [from ]
-// CHECK: ; [ DW_TAG_enumeration_type ] [D] [line 6, size 16, align 16, offset 0] [decl] [from ]
 
 namespace PR14029 {
   // Make sure this doesn't crash/assert.
@@ -27,3 +26,54 @@
   };
   Test<int> t;
 }
+
+namespace test2 {
+// FIXME: this should just be a declaration under -fno-standalone-debug
+// CHECK: metadata !{i32 {{[^,]*}}, {{[^,]*}}, metadata [[TEST2:![0-9]*]], {{.*}}, metadata [[TEST_ENUMS:![0-9]*]], {{[^,]*}}, null, null, metadata !"_ZTSN5test21EE"} ; [ DW_TAG_enumeration_type ] [E]
+// CHECK: [[TEST2]] = {{.*}} ; [ DW_TAG_namespace ] [test2]
+// CHECK: [[TEST_ENUMS]] = metadata !{metadata [[TEST_E:![0-9]*]]}
+// CHECK: [[TEST_E]] = {{.*}}, metadata !"e", i64 0} ; [ DW_TAG_enumerator ] [e :: 0]
+enum E : int;
+void func(E *) {
+}
+enum E : int { e };
+}
+
+namespace test3 {
+// FIXME: this should just be a declaration under -fno-standalone-debug
+// CHECK: metadata !{i32 {{[^,]*}}, {{[^,]*}}, metadata [[TEST3:![0-9]*]], {{.*}}, metadata [[TEST_ENUMS]], {{[^,]*}}, null, null, metadata !"_ZTSN5test31EE"} ; [ DW_TAG_enumeration_type ] [E]
+// CHECK: [[TEST3]] = {{.*}} ; [ DW_TAG_namespace ] [test3]
+enum E : int { e };
+void func(E *) {
+}
+}
+
+namespace test4 {
+// CHECK: metadata !{i32 {{[^,]*}}, {{[^,]*}}, metadata [[TEST4:![0-9]*]], {{.*}}, metadata [[TEST_ENUMS]], {{[^,]*}}, null, null, metadata !"_ZTSN5test41EE"} ; [ DW_TAG_enumeration_type ] [E]
+// CHECK: [[TEST4]] = {{.*}} ; [ DW_TAG_namespace ] [test4]
+enum E : int;
+void f1(E *) {
+}
+enum E : int { e };
+void f2(E) {
+}
+}
+
+// CHECK: ; [ DW_TAG_enumeration_type ] [D] [line 6, size 16, align 16, offset 0] [decl] [from ]
+
+namespace test5 {
+// CHECK: metadata !{i32 {{[^,]*}}, {{[^,]*}}, metadata [[TEST5:![0-9]*]], {{.*}}, null, {{[^,]*}}, null, null, metadata !"_ZTSN5test51EE"} ; [ DW_TAG_enumeration_type ] [E]
+// CHECK: [[TEST5]] = {{.*}} ; [ DW_TAG_namespace ] [test5]
+enum E : int;
+void f1(E *) {
+}
+}
+
+namespace test6 {
+// Ensure typedef'd enums aren't manifest by debug info generation.
+// This could cause "typedef changes linkage of anonymous type, but linkage was
+// already computed" errors.
+// CHECK-NOT: test7
+typedef enum {
+} E;
+}
diff --git a/test/CodeGenCXX/debug-info-enum.cpp b/test/CodeGenCXX/debug-info-enum.cpp
index f0e2608..810c3ee 100644
--- a/test/CodeGenCXX/debug-info-enum.cpp
+++ b/test/CodeGenCXX/debug-info-enum.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -g %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -g %s -o - | FileCheck %s
 
 // CHECK: [[ENUMS:![0-9]*]], {{[^,]*}}, {{[^,]*}}, {{[^,]*}}, {{[^,]*}}, {{[^,]*}}} ; [ DW_TAG_compile_unit ]
 // CHECK: [[ENUMS]] = metadata !{metadata [[E1:![0-9]*]], metadata [[E2:![0-9]*]], metadata [[E3:![0-9]*]]}
@@ -34,3 +34,12 @@
   e x;
 }
 }
+
+namespace test4 {
+// Don't try to build debug info for a dependent enum.
+// CHECK-NOT: test4
+template <typename T>
+struct S {
+  enum e { E = T::v };
+};
+}
diff --git a/test/CodeGenCXX/debug-info-function-context.cpp b/test/CodeGenCXX/debug-info-function-context.cpp
index 4ca1c8d..e65d328 100644
--- a/test/CodeGenCXX/debug-info-function-context.cpp
+++ b/test/CodeGenCXX/debug-info-function-context.cpp
@@ -29,8 +29,8 @@
 
 // CHECK: metadata !"_ZTS1C", metadata !"static_member_function"{{.*}}  [ DW_TAG_subprogram ] [line 13] [def] [static_member_function]
 
-// CHECK: metadata !22, metadata !"global_function"{{.*}}  [ DW_TAG_subprogram ] [line 17] [def] [global_function]
-// CHECK: !22 = {{.*}} [ DW_TAG_file_type ]
+// CHECK: metadata [[FILE:![0-9]*]], metadata !"global_function"{{.*}}  [ DW_TAG_subprogram ] [line 17] [def] [global_function]
+// CHECK: [[FILE]] = {{.*}} [ DW_TAG_file_type ]
 
-// CHECK: metadata !24, metadata !"global_namespace_function"{{.*}} [ DW_TAG_subprogram ] [line 20] [def] [global_namespace_function]
-// CHECK: !24 = {{.*}} [ DW_TAG_namespace ] [ns] [line 19]
+// CHECK: metadata [[NS:![0-9]*]], metadata !"global_namespace_function"{{.*}} [ DW_TAG_subprogram ] [line 20] [def] [global_namespace_function]
+// CHECK: [[NS]] = {{.*}} [ DW_TAG_namespace ] [ns] [line 19]
diff --git a/test/CodeGenCXX/debug-info-gline-tables-only.cpp b/test/CodeGenCXX/debug-info-gline-tables-only.cpp
index 7ecdeb2..b766c73 100644
--- a/test/CodeGenCXX/debug-info-gline-tables-only.cpp
+++ b/test/CodeGenCXX/debug-info-gline-tables-only.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -gline-tables-only -S -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -fno-rtti -gline-tables-only -S -emit-llvm -o - | FileCheck %s
 // Checks that clang with "-gline-tables-only" doesn't emit debug info
 // for variables and types.
 
diff --git a/test/CodeGenCXX/debug-info-global-ctor-dtor.cpp b/test/CodeGenCXX/debug-info-global-ctor-dtor.cpp
index afa7707..28b1fab 100644
--- a/test/CodeGenCXX/debug-info-global-ctor-dtor.cpp
+++ b/test/CodeGenCXX/debug-info-global-ctor-dtor.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 %s -g -fno-use-cxa-atexit -S -emit-llvm -o - \
+// RUN: %clang_cc1 %s -g -triple %itanium_abi_triple -fno-use-cxa-atexit -S -emit-llvm -o - \
 // RUN:     | FileCheck %s --check-prefix=CHECK-NOKEXT
-// RUN: %clang_cc1 %s -g -fno-use-cxa-atexit -fapple-kext -S -emit-llvm -o - \
+// RUN: %clang_cc1 %s -g -triple %itanium_abi_triple -fno-use-cxa-atexit -fapple-kext -S -emit-llvm -o - \
 // RUN:     | FileCheck %s --check-prefix=CHECK-KEXT
 
 class A {
diff --git a/test/CodeGenCXX/debug-info-global.cpp b/test/CodeGenCXX/debug-info-global.cpp
new file mode 100644
index 0000000..8dc30c8
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-global.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple x86_64-none-linux-gnu -emit-llvm -g %s -o - | FileCheck %s
+
+// Multiple references to the same constant should result in only one entry in
+// the globals list.
+
+namespace ns {
+const int cnst = 42;
+}
+int f1() {
+  return ns::cnst + ns::cnst;
+}
+
+// CHECK: metadata [[GLOBALS:![0-9]*]], metadata {{![0-9]*}}, metadata !"{{.*}}", i32 {{[0-9]*}}} ; [ DW_TAG_compile_unit ]
+
+// CHECK: [[GLOBALS]] = metadata !{metadata [[CNST:![0-9]*]]}
+
+// CHECK: [[CNST]] = {{.*}}, metadata [[NS:![0-9]*]], metadata !"cnst", {{.*}}; [ DW_TAG_variable ] [cnst]
+// CHECK: [[NS]] = {{.*}}; [ DW_TAG_namespace ] [ns]
+
diff --git a/test/CodeGenCXX/debug-info-indirect-field-decl.cpp b/test/CodeGenCXX/debug-info-indirect-field-decl.cpp
new file mode 100644
index 0000000..131ceba
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-indirect-field-decl.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -emit-llvm -g -triple x86_64-apple-darwin %s -o - | FileCheck %s
+//
+// Test that indirect field decls are handled gracefully.
+// rdar://problem/16348575
+//
+template <class T, int T::*ptr> class Foo {  };
+
+struct Bar {
+  int i1;
+  // CHECK: [ DW_TAG_member ] [line [[@LINE+1]], size 32, align 32, offset 32] [from _ZTSN3BarUt_E]
+  union {
+    // CHECK: [ DW_TAG_member ] [i2] [line [[@LINE+1]], size 32, align 32, offset 0] [from int]
+    int i2;
+  };
+};
+
+Foo<Bar, &Bar::i2> the_foo;
diff --git a/test/CodeGenCXX/debug-info-limited.cpp b/test/CodeGenCXX/debug-info-limited.cpp
index 54a2424..294d1f6 100644
--- a/test/CodeGenCXX/debug-info-limited.cpp
+++ b/test/CodeGenCXX/debug-info-limited.cpp
@@ -11,8 +11,7 @@
   return a;
 }
 
-// Verify that we're not emitting a full definition of B in limit debug mode.
-// CHECK: ; [ DW_TAG_class_type ] [B] {{.*}} [decl]
+// CHECK: ; [ DW_TAG_class_type ] [B] {{.*}} [def]
 
 class B {
 public:
diff --git a/test/CodeGenCXX/debug-info-line-if.cpp b/test/CodeGenCXX/debug-info-line-if.cpp
new file mode 100644
index 0000000..e14090f
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-line-if.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -g -std=c++11 -S -emit-llvm %s -o - | FileCheck %s
+// PR19864
+int main() {
+    int v[] = {13, 21, 8, 3, 34, 1, 5, 2};
+    int a = 0, b = 0;
+    for (int x : v)
+      if (x >= 3)
+        ++b;     // CHECK: add nsw{{.*}}, 1
+      else if (x >= 0)
+        ++a;    // CHECK: add nsw{{.*}}, 1
+    // The continuation block if the if statement should not share the
+    // location of the ++a statement. Having it point to the end of
+    // the condition is not ideal either, but it's less missleading.
+
+    // CHECK: br label
+    // CHECK: br label
+    // CHECK: br label {{.*}}, !dbg ![[DBG:.*]]
+    // CHECK: ![[DBG]] = metadata !{i32 [[@LINE-11]], i32 0, metadata !{{.*}}, null}
+
+}
diff --git a/test/CodeGenCXX/debug-info-member.cpp b/test/CodeGenCXX/debug-info-member.cpp
index 8c2e3eb..7ba97b5 100644
--- a/test/CodeGenCXX/debug-info-member.cpp
+++ b/test/CodeGenCXX/debug-info-member.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang -fverbose-asm -g -S %s -o - | grep DW_ACCESS_public
+// FIXME: Check IR rather than asm, then triple is not needed.
+// RUN: %clang -Xclang -triple=%itanium_abi_triple -fverbose-asm -g -S %s -o - | grep DW_ACCESS_public
 class A {
 public:
   int x;
diff --git a/test/CodeGenCXX/debug-info-method-spec.cpp b/test/CodeGenCXX/debug-info-method-spec.cpp
index 2068c5c..c00da00 100644
--- a/test/CodeGenCXX/debug-info-method-spec.cpp
+++ b/test/CodeGenCXX/debug-info-method-spec.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang -fverbose-asm -g -S %s -o - | grep DW_AT_specification
+// FIXME: Check IR rather than asm, then triple is not needed.
+// RUN: %clang -Xclang -triple=%itanium_abi_triple -fverbose-asm -g -S %s -o - | grep DW_AT_specification
 // Radar 9254491
 class A {
 public:
diff --git a/test/CodeGenCXX/debug-info-method.cpp b/test/CodeGenCXX/debug-info-method.cpp
index 50b3f66..49b8dc4 100644
--- a/test/CodeGenCXX/debug-info-method.cpp
+++ b/test/CodeGenCXX/debug-info-method.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -std=c++11 -g %s -o - | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -std=c++11 -g %s -o - | FileCheck %s
 // CHECK: metadata !"_ZTS1A"} ; [ DW_TAG_class_type ] [A]
 // CHECK: metadata !"_ZN1A3fooEiS_3$_0", {{.*}} [protected]
 // CHECK: ![[THISTYPE:[0-9]+]] = {{.*}} ; [ DW_TAG_pointer_type ] {{.*}} [artificial] [from _ZTS1A]
diff --git a/test/CodeGenCXX/debug-info-method2.cpp b/test/CodeGenCXX/debug-info-method2.cpp
index a927c49..a365312 100644
--- a/test/CodeGenCXX/debug-info-method2.cpp
+++ b/test/CodeGenCXX/debug-info-method2.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -flimit-debug-info -x c++ -g -S -emit-llvm < %s | FileCheck %s
+// RUN: %clang_cc1 -fno-standalone-debug -x c++ -g -S -emit-llvm < %s | FileCheck %s
 // rdar://10336845
 // Preserve type qualifiers in -flimit-debug-info mode.
 
diff --git a/test/CodeGenCXX/debug-info-namespace.cpp b/test/CodeGenCXX/debug-info-namespace.cpp
index a2d7ede..a1284d2 100644
--- a/test/CodeGenCXX/debug-info-namespace.cpp
+++ b/test/CodeGenCXX/debug-info-namespace.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang -g -S -emit-llvm %s -o - | FileCheck %s
-// RUN: %clang -g -gline-tables-only -S -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-GMLT %s
-// RUN: %clang -g -fno-limit-debug-info -S -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-NOLIMIT %s
+// RUN: %clang_cc1 -g -fno-standalone-debug -S -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -g -gline-tables-only    -S -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-GMLT %s
+// RUN: %clang_cc1 -g -fstandalone-debug    -S -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-NOLIMIT %s
 
 namespace A {
 #line 1 "foo.cpp"
@@ -36,42 +36,48 @@
   return i + X::B::i + Y::B::i;
 }
 
+namespace A {
+using B::i;
+}
+
 // This should work even if 'i' and 'func' were declarations & not definitions,
 // but it doesn't yet.
 
-// CHECK: [[CU:![0-9]*]] = {{.*}}[[MODULES:![0-9]*]], metadata !""} ; [ DW_TAG_compile_unit ]
-// CHECK: [[FILE:![0-9]*]] {{.*}}debug-info-namespace.cpp"
+// CHECK: [[CU:![0-9]*]] = {{.*}}[[MODULES:![0-9]*]], metadata !"", i32 1} ; [ DW_TAG_compile_unit ]
 // CHECK: [[FOO:![0-9]*]] {{.*}} ; [ DW_TAG_structure_type ] [foo] [line 5, size 0, align 0, offset 0] [decl] [from ]
 // CHECK: [[FOOCPP:![0-9]*]] = metadata !{metadata !"foo.cpp", {{.*}}
 // CHECK: [[NS:![0-9]*]] = {{.*}}, metadata [[FILE2:![0-9]*]], metadata [[CTXT:![0-9]*]], {{.*}} ; [ DW_TAG_namespace ] [B] [line 1]
-// CHECK: [[CTXT]] = {{.*}}, metadata [[FILE]], null, {{.*}} ; [ DW_TAG_namespace ] [A] [line 5]
+// CHECK: [[CTXT]] = {{.*}}, metadata [[FILE:![0-9]*]], null, {{.*}} ; [ DW_TAG_namespace ] [A] [line 5]
+// CHECK: [[FILE]] {{.*}}debug-info-namespace.cpp"
 // CHECK: [[BAR:![0-9]*]] {{.*}} ; [ DW_TAG_structure_type ] [bar] [line 6, {{.*}}] [decl] [from ]
 // CHECK: [[F1:![0-9]*]] {{.*}} ; [ DW_TAG_subprogram ] [line 4] [def] [f1]
 // CHECK: [[FUNC:![0-9]*]] {{.*}} ; [ DW_TAG_subprogram ] {{.*}} [def] [func]
 // CHECK: [[FILE2]]} ; [ DW_TAG_file_type ] [{{.*}}foo.cpp]
 // CHECK: [[I:![0-9]*]] = {{.*}}, metadata [[NS]], metadata !"i", {{.*}} ; [ DW_TAG_variable ] [i]
-// CHECK: [[MODULES]] = metadata !{metadata [[M1:![0-9]*]], metadata [[M2:![0-9]*]], metadata [[M3:![0-9]*]], metadata [[M4:![0-9]*]], metadata [[M5:![0-9]*]], metadata [[M6:![0-9]*]], metadata [[M7:![0-9]*]], metadata [[M8:![0-9]*]], metadata [[M9:![0-9]*]], metadata [[M10:![0-9]*]], metadata [[M11:![0-9]*]], metadata [[M12:![0-9]*]]}
+// CHECK: [[MODULES]] = metadata !{metadata [[M1:![0-9]*]], metadata [[M2:![0-9]*]], metadata [[M3:![0-9]*]], metadata [[M4:![0-9]*]], metadata [[M5:![0-9]*]], metadata [[M6:![0-9]*]], metadata [[M7:![0-9]*]], metadata [[M8:![0-9]*]], metadata [[M9:![0-9]*]], metadata [[M10:![0-9]*]], metadata [[M11:![0-9]*]], metadata [[M12:![0-9]*]], metadata [[M13:![0-9]*]]}
 // CHECK: [[M1]] = metadata !{i32 {{[0-9]*}}, metadata [[CTXT]], metadata [[NS]], i32 11} ; [ DW_TAG_imported_module ]
 // CHECK: [[M2]] = metadata !{i32 {{[0-9]*}}, metadata [[CU]], metadata [[CTXT]], i32 {{[0-9]*}}} ; [ DW_TAG_imported_module ]
-// CHECK: [[M3]] = metadata !{i32 {{[0-9]*}}, metadata [[CU]], metadata [[CTXT]], i32 15, metadata !"E"} ; [ DW_TAG_imported_module ]
+// CHECK: [[M3]] = metadata !{i32 {{[0-9]*}}, metadata [[CU]], metadata [[CTXT]], i32 15, metadata !"E"} ; [ DW_TAG_imported_declaration ]
 // CHECK: [[M4]] = metadata !{i32 {{[0-9]*}}, metadata [[LEX2:![0-9]*]], metadata [[NS]], i32 19} ; [ DW_TAG_imported_module ]
 // CHECK: [[LEX2]] = metadata !{i32 {{[0-9]*}}, metadata [[FILE2]], metadata [[LEX1:![0-9]+]], i32 {{[0-9]*}}, i32 0, i32 {{.*}}} ; [ DW_TAG_lexical_block ]
 // CHECK: [[LEX1]] = metadata !{i32 {{[0-9]*}}, metadata [[FILE2]], metadata [[FUNC]], i32 {{[0-9]*}}, i32 0, i32 {{.*}}} ; [ DW_TAG_lexical_block ]
 // CHECK: [[M5]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]], metadata [[CTXT]], i32 {{[0-9]*}}} ; [ DW_TAG_imported_module ]
-// CHECK: [[M6]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]], metadata [[FOO:![0-9]*]], i32 23} ; [ DW_TAG_imported_declaration ]
-// CHECK: [[M7]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]], metadata [[BAR:![0-9]*]], i32 {{[0-9]*}}} ; [ DW_TAG_imported_declaration ]
+// CHECK: [[M6]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]], metadata [[FOO:!"_ZTSN1A1B3fooE"]], i32 23} ; [ DW_TAG_imported_declaration ]
+// CHECK: [[M7]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]], metadata [[BAR:!"_ZTSN1A1B3barE"]], i32 {{[0-9]*}}} ; [ DW_TAG_imported_declaration ]
 // CHECK: [[M8]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]], metadata [[F1]], i32 {{[0-9]*}}} ; [ DW_TAG_imported_declaration ]
 // CHECK: [[M9]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]], metadata [[I]], i32 {{[0-9]*}}} ; [ DW_TAG_imported_declaration ]
 // CHECK: [[M10]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]], metadata [[BAZ:![0-9]*]], i32 {{[0-9]*}}} ; [ DW_TAG_imported_declaration ]
 // CHECK: [[BAZ]] = metadata !{i32 {{[0-9]*}}, metadata [[FOOCPP]], metadata [[NS]], {{.*}}, metadata !"_ZTSN1A1B3barE"} ; [ DW_TAG_typedef ] [baz] {{.*}} [from _ZTSN1A1B3barE]
-// CHECK: [[M11]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]], metadata [[CTXT]], i32 {{[0-9]*}}, metadata !"X"} ; [ DW_TAG_imported_module ]
-// CHECK: [[M12]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]], metadata [[M11]], i32 {{[0-9]*}}, metadata !"Y"} ; [ DW_TAG_imported_module ]
+// CHECK: [[M11]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]], metadata [[CTXT]], i32 {{[0-9]*}}, metadata !"X"} ; [ DW_TAG_imported_declaration ]
+// CHECK: [[M12]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]], metadata [[M11]], i32 {{[0-9]*}}, metadata !"Y"} ; [ DW_TAG_imported_declaration ]
+// CHECK: [[M13]] = metadata !{i32 {{[0-9]*}}, metadata [[CTXT]], metadata [[I]], i32 {{[0-9]*}}} ; [ DW_TAG_imported_declaration ]
 
-// CHECK-GMLT: [[CU:![0-9]*]] = {{.*}}[[MODULES:![0-9]*]], metadata !""} ; [ DW_TAG_compile_unit ]
-// CHECK-GMLT: [[MODULES]] = metadata !{i32 0}
+// CHECK-GMLT: [[CU:![0-9]*]] = {{.*}}[[MODULES:![0-9]*]], metadata !"", i32 2} ; [ DW_TAG_compile_unit ]
+// CHECK-GMLT: [[MODULES]] = metadata !{}
 
 // CHECK-NOLIMIT: ; [ DW_TAG_structure_type ] [bar] [line 6, {{.*}}] [def] [from ]
 
 // FIXME: It is confused on win32 to generate file entry when dosish filename is given.
 // REQUIRES: shell
 // REQUIRES: shell-preserves-root
+// REQUIRES: dw2
diff --git a/test/CodeGenCXX/debug-info-pubtypes.cpp b/test/CodeGenCXX/debug-info-pubtypes.cpp
deleted file mode 100644
index 6393cdd..0000000
--- a/test/CodeGenCXX/debug-info-pubtypes.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-// REQUIRES: x86-64-registered-target
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10  -g -fno-limit-debug-info -S -mllvm -generate-dwarf-pub-sections=Enable %s -o - | FileCheck %s
-
-// FIXME: This testcase shouldn't rely on assembly emission.
-//CHECK: Lpubtypes_begin[[SECNUM:[0-9]:]]
-//CHECK:         .asciz   "G"
-//CHECK-NEXT:    .long   0
-//CHECK-NEXT: Lpubtypes_end[[SECNUM]]
-
-class G {
-public:
-  void foo();
-};
-
-void G::foo() {
-}
diff --git a/test/CodeGenCXX/debug-info-qualifiers.cpp b/test/CodeGenCXX/debug-info-qualifiers.cpp
new file mode 100644
index 0000000..c6b935f
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-qualifiers.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -std=c++11 -emit-llvm -g -triple x86_64-apple-darwin %s -o - | FileCheck %s
+// Test (r)value and CVR qualifiers on C++11 non-static member functions.
+class A {
+public:
+  // CHECK: i32 [[@LINE+2]], metadata ![[PLSR:[0-9]+]], {{.*}}[ DW_TAG_subprogram ] [line [[@LINE+2]]] [reference] [l]
+  // CHECK: ![[PLSR]] ={{.*}}[ DW_TAG_subroutine_type ]{{.*}}[reference]
+  void l() const &;
+  // CHECK: ![[ARGS:[0-9]+]] = metadata !{null, metadata ![[THIS:[0-9]+]]}
+  // CHECK: ![[THIS]] = {{.*}} metadata ![[CONST_A:.*]]} ; [ DW_TAG_pointer_type ]
+  // CHECK: ![[CONST_A]] = {{.*}} [ DW_TAG_const_type ]
+  // CHECK: i32 [[@LINE+2]], metadata ![[PRSR:[0-9]+]], {{.*}}[ DW_TAG_subprogram ] [line [[@LINE+2]]] [rvalue reference] [r]
+  // CHECK: ![[PRSR]] ={{.*}}metadata ![[ARGS]], i32 0, null, null, null}{{.*}}[ DW_TAG_subroutine_type ]{{.*}}[rvalue reference]
+  void r() const &&;
+};
+
+void g() {
+  A a;
+  // The type of pl is "void (A::*)() const &".
+  // CHECK: metadata ![[PL:[0-9]+]], i32 0, i32 0} ; [ DW_TAG_auto_variable ] [pl] [line [[@LINE+2]]]
+  // CHECK: metadata ![[PLSR]], metadata !"{{.*}}"} ; [ DW_TAG_ptr_to_member_type ]
+  auto pl = &A::l;
+
+  // CHECK: metadata ![[PR:[0-9]+]], i32 0, i32 0} ; [ DW_TAG_auto_variable ] [pr] [line [[@LINE+2]]]
+  // CHECK: metadata ![[PRSR]], metadata !"{{.*}}"} ; [ DW_TAG_ptr_to_member_type ]
+  auto pr = &A::r;
+}
diff --git a/test/CodeGenCXX/debug-info-same-line.cpp b/test/CodeGenCXX/debug-info-same-line.cpp
index 519e9ee..965a538 100644
--- a/test/CodeGenCXX/debug-info-same-line.cpp
+++ b/test/CodeGenCXX/debug-info-same-line.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -g -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -g -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
 
 // Make sure that clang outputs distinct debug info for a function
 // that is inlined twice on the same line. Otherwise it would appear
@@ -6,118 +6,59 @@
 
 #define INLINE inline __attribute__((always_inline))
 
-INLINE int
-product (int x, int y)
-{
-    int result = x * y;
-    return result;
+int i;
+
+INLINE void sum(int a, int b) {
+  i = a + b;
 }
 
-INLINE int
-sum (int a, int b)
-{
-    int result = a + b;
-    return result;
+void noinline(int x, int y) {
+  i = x + y;
 }
 
-int
-strange_max (int m, int n)
-{
-    if (m > n)
-        return m;
-    else if (n > m)
-        return n;
-    else
-        return 0;
+#define CALLS sum(9, 10), sum(11, 12)
+
+inline void inlsum(int t, int u) {
+  i = t + u;
 }
 
-int
-foo (int i, int j)
-{
-    if (strange_max (i, j) == i)
-        return product (i, j);
-    else if (strange_max  (i, j) == j)
-        return sum (i, j);
-    else
-        return product (sum (i, i), sum (j, j));
+int main() {
+  sum(1, 2), sum(3, 4);
+  noinline(5, 6), noinline(7, 8);
+  CALLS;
+  inlsum(13, 14), inlsum(15, 16);
 }
 
-int
-main(int argc, char const *argv[])
-{
+// CHECK-LABEL: @main
+// CHECK: = add {{.*}} !dbg [[FIRST_INLINE:![0-9]*]]
+// CHECK: = add {{.*}} !dbg [[SECOND_INLINE:![0-9]*]]
 
-    int array[3];
-    int n;
+// Check that we don't give column information (and thus end up with distinct
+// line entries) for two non-inlined calls on the same line.
+// CHECK: call {{.*}}noinline{{.*}}({{i32[ ]?[a-z]*}} 5, {{i32[ ]?[a-z]*}} 6), !dbg [[NOINLINE:![0-9]*]]
+// CHECK: call {{.*}}noinline{{.*}}({{i32[ ]?[a-z]*}} 7, {{i32[ ]?[a-z]*}} 8), !dbg [[NOINLINE]]
 
-    array[0] = foo (1238, 78392);
-    array[1] = foo (379265, 23674);
-    array[2] = foo (872934, 234);
+// FIXME: These should be separate locations but because the two calls have the
+// same line /and/ column, they get coalesced into a single inlined call by
+// accident. We need discriminators or some other changes to LLVM to cope with
+// this. (this is, unfortunately, an LLVM test disguised as a Clang test - since
+// inlining is forced to happen here). It's possible this could be fixed in
+// Clang, but I doubt it'll be the right place for the fix.
+// CHECK: = add {{.*}} !dbg [[FIRST_MACRO_INLINE:![0-9]*]]
+// CHECK: = add {{.*}} !dbg [[FIRST_MACRO_INLINE]]
 
-    n = strange_max(array[0], strange_max(array[1], array[2]));
+// Even if the functions are marked inline but do not get inlined, they
+// shouldn't use column information, and thus should be at the same debug
+// location.
+// CHECK: call {{.*}}inlsum{{.*}}({{i32[ ]?[a-z]*}} 13, {{i32[ ]?[a-z]*}} 14), !dbg [[INL_FIRST:![0-9]*]]
+// CHECK: call {{.*}}inlsum{{.*}}({{i32[ ]?[a-z]*}} 15, {{i32[ ]?[a-z]*}} 16), !dbg [[INL_SECOND:![0-9]*]]
 
-    return n & 0xf;
-}
+// [[FIRST_INLINE]] =
+// [[SECOND_INLINE]] =
 
-// CHECK: define {{.*}} @_Z3fooii
-// i
-// CHECK: call void @llvm.dbg.declare
-// j
-// CHECK: call void @llvm.dbg.declare
-// x
-// CHECK: call void @llvm.dbg.declare
-// y
-// CHECK: call void @llvm.dbg.declare
-// result
-// CHECK: call void @llvm.dbg.declare
-
-// CHECK: call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[A_MD:[0-9]+]]), !dbg ![[A_DI:[0-9]+]]
-// CHECK: call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[B_MD:[0-9]+]]), !dbg ![[B_DI:[0-9]+]]
-// result
-// CHECK: call void @llvm.dbg.declare
-
-// We want to see a distinct !dbg node.
-// CHECK-NOT: call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[A_MD]]), !dbg ![[A_DI]]
-// CHECK:     call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[A_MD]]), !dbg !{{.*}}
-// CHECK-NOT: call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[B_MD]]), !dbg ![[B_DI]]
-// CHECK:     call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[B_MD]]), !dbg !{{.*}}
-// result
-// CHECK: call void @llvm.dbg.declare
-
-// We want to see a distinct !dbg node.
-// CHECK-NOT: call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[A_MD]]), !dbg ![[A_DI]]
-// CHECK:     call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[A_MD]]), !dbg !{{.*}}
-// CHECK-NOT: call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[B_MD]]), !dbg ![[B_DI]]
-// CHECK:     call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[B_MD]]), !dbg !{{.*}}
-// result
-// CHECK: call void @llvm.dbg.declare
-
-// Again: we want to see a distinct !dbg node.
-// CHECK:     call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[X_MD:[0-9]+]]), !dbg ![[X_DI:[0-9]+]]
-// CHECK:     call void @llvm.dbg.declare(metadata !{i32* %{{.*}}}, metadata ![[Y_MD:[0-9]+]]), !dbg ![[Y_DI:[0-9]+]]
-// result
-// CHECK: call void @llvm.dbg.declare
-
-
-// CHECK: define {{.*}} @main
-// CHECK: call {{.*}} @_Z3fooii
-// CHECK: call {{.*}} @_Z3fooii
-// CHECK: call {{.*}} @_Z3fooii
-// CHECK: store
-// CHECK: getelementptr
-// We want to see the same !dbg node for non-inlined functions. 
-// Needed for GDB compatibility.
-// CHECK: load {{.*}} !dbg ![[DBG:.*]]
-// CHECK: load {{.*}} !dbg ![[DBG]]
-// CHECK: load {{.*}} !dbg ![[DBG]]
-// CHECK: call {{.*}} @_Z11strange_maxii(i32 {{.*}}, i32 {{.*}}), !dbg ![[DBG]]
-// CHECK: call {{.*}} @_Z11strange_maxii(i32 {{.*}}, i32 {{.*}}), !dbg ![[DBG]]
-
-
-// Verify that product() has its own inlined_at location at column 15.
-// CHECK-DAG: ![[A_MD]] = metadata{{.*}}[ DW_TAG_arg_variable ] [a]
-// CHECK-DAG: ![[B_MD]] = metadata{{.*}}[ DW_TAG_arg_variable ] [b]
-// CHECK-DAG: ![[X_MD]] = metadata{{.*}}[ DW_TAG_arg_variable ] [x]
-// CHECK-DAG: ![[Y_MD]] = metadata{{.*}}[ DW_TAG_arg_variable ] [y]
-// CHECK-DAG: ![[X_DI]] = metadata !{i32 {{[0-9]+}}, i32 {{[0-9]+}}, metadata !{{[0-9]+}}, metadata ![[PRODUCT:[0-9]+]]}
-// CHECK-DAG: [[PRODUCT]] = metadata !{i32 {{.*}}, i32 16, metadata !{{.*}}, null}
-// CHECK-DAG: ![[Y_DI]] = metadata !{i32 {{[0-9]+}}, i32 {{[0-9]+}}, metadata !{{[0-9]+}}, metadata ![[PRODUCT]]}
+// FIXME: These should be the same location since the functions appear on the
+// same line and were not inlined - they needlessly have column information
+// intended to disambiguate inlined calls, which is going to confuse GDB as it
+// doesn't cope well with column information.
+// [[INL_FIRST]] =
+// [[INL_SECOND]] =
diff --git a/test/CodeGenCXX/debug-info-scope.cpp b/test/CodeGenCXX/debug-info-scope.cpp
index 557ee31..0447dc0 100644
--- a/test/CodeGenCXX/debug-info-scope.cpp
+++ b/test/CodeGenCXX/debug-info-scope.cpp
@@ -17,12 +17,12 @@
 
 int main2() {
 // CHECK: [ DW_TAG_auto_variable ] [ptr] [line [[@LINE+2]]]
-// CHECK metadata !{i32 {{.*}}, metadata !{{.*}}, i32 [[@LINE+1]], {{.*}}} ; [ DW_TAG_lexical_block ]
+// CHECK: metadata !{i32 {{.*}}, metadata !{{.*}}, i32 [[@LINE+1]], {{.*}}} ; [ DW_TAG_lexical_block ]
   if (char *ptr = return_char(1)) {
     printf ("%s", ptr);
   }
 // CHECK: [ DW_TAG_auto_variable ] [ptr] [line [[@LINE+2]]]
-// CHECK metadata !{i32 {{.*}}, metadata !{{.*}}, i32 [[@LINE+1]], {{.*}}} ; [ DW_TAG_lexical_block ]
+// CHECK: metadata !{i32 {{.*}}, metadata !{{.*}}, i32 [[@LINE+1]], {{.*}}} ; [ DW_TAG_lexical_block ]
   if (char *ptr = return_char(2)) {
     printf ("%s", ptr);
   }
diff --git a/test/CodeGenCXX/debug-info-template-explicit-specialization.cpp b/test/CodeGenCXX/debug-info-template-explicit-specialization.cpp
new file mode 100644
index 0000000..506c0d5
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-template-explicit-specialization.cpp
@@ -0,0 +1,93 @@
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -g %s -o - -fno-standalone-debug | FileCheck %s
+
+// Run again with -gline-tables-only and verify we don't crash.  We won't output
+// type info at all.
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -g %s -o - -gline-tables-only | FileCheck %s -check-prefix LINES-ONLY
+
+// LINES-ONLY-NOT: DW_TAG_structure_type
+
+template <typename T>
+struct a {
+};
+extern template class a<int>;
+// CHECK-NOT: ; [ DW_TAG_structure_type ] [a<int>]
+
+template <typename T>
+struct b {
+};
+extern template class b<int>;
+b<int> bi;
+// CHECK: ; [ DW_TAG_structure_type ] [b<int>] {{.*}} [def]
+
+template <typename T>
+struct c {
+  void f() {}
+};
+extern template class c<int>;
+c<int> ci;
+// CHECK: ; [ DW_TAG_structure_type ] [c<int>] {{.*}} [decl]
+
+template <typename T>
+struct d {
+  void f();
+};
+extern template class d<int>;
+d<int> di;
+// CHECK: ; [ DW_TAG_structure_type ] [d<int>] {{.*}} [def]
+
+template <typename T>
+struct e {
+  void f();
+};
+template <typename T>
+void e<T>::f() {
+}
+extern template class e<int>;
+e<int> ei;
+// There's no guarantee that the out of line definition will appear before the
+// explicit template instantiation definition, so conservatively emit the type
+// definition here.
+// CHECK: ; [ DW_TAG_structure_type ] [e<int>] {{.*}} [def]
+
+template <typename T>
+struct f {
+  void g();
+};
+extern template class f<int>;
+template <typename T>
+void f<T>::g() {
+}
+f<int> fi;
+// CHECK: ; [ DW_TAG_structure_type ] [f<int>] {{.*}} [def]
+
+template <typename T>
+struct g {
+  void f();
+};
+template <>
+void g<int>::f();
+extern template class g<int>;
+g<int> gi;
+// CHECK: ; [ DW_TAG_structure_type ] [g<int>] {{.*}} [def]
+
+template <typename T>
+struct h {
+};
+template class h<int>;
+// CHECK: ; [ DW_TAG_structure_type ] [h<int>] {{.*}} [def]
+
+template <typename T>
+struct i {
+  void f() {}
+};
+template<> void i<int>::f();
+extern template class i<int>;
+i<int> ii;
+// CHECK: ; [ DW_TAG_structure_type ] [i<int>] {{.*}} [def]
+
+template <typename T1, typename T2 = T1>
+struct j {
+};
+extern template class j<int>;
+j<int> jj;
+// CHECK: ; [ DW_TAG_structure_type ] [j<int, int>]
diff --git a/test/CodeGenCXX/debug-info-template-fwd.cpp b/test/CodeGenCXX/debug-info-template-fwd.cpp
new file mode 100644
index 0000000..b2b7073
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-template-fwd.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin -g -emit-llvm -o - | FileCheck %s
+// This test is for a crash when emitting debug info for not-yet-completed
+// types.
+// Test that we don't actually emit a forward decl for the offending class:
+// CHECK:  [ DW_TAG_structure_type ] [Derived<int>] {{.*}} [def]
+// rdar://problem/15931354
+template <class A> class Derived;
+
+template <class A> class Base {
+  static Derived<A> *create();
+};
+
+template <class A> struct Derived : Base<A> {
+};
+
+Base<int> *f;
+
+// During the instantiation of Derived<int>, Base<int> becomes required to be
+// complete - since the declaration has already been emitted (due to 'f',
+// above), we immediately try to build debug info for Base<int> which then
+// requires the (incomplete definition) of Derived<int> which is problematic.
+//
+// (if 'f' is not present, the point at which Base<int> becomes required to be
+// complete during the instantiation of Derived<int> is a no-op because
+// Base<int> was never emitted so we ignore it and carry on until we
+// wire up the base class of Derived<int> in the debug info later on)
+Derived<int> d;
diff --git a/test/CodeGenCXX/debug-info-template-limit.cpp b/test/CodeGenCXX/debug-info-template-limit.cpp
index c3e241e..e1f23ad 100644
--- a/test/CodeGenCXX/debug-info-template-limit.cpp
+++ b/test/CodeGenCXX/debug-info-template-limit.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang -flimit-debug-info -emit-llvm -g -S %s -o - | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -fno-standalone-debug -triple %itanium_abi_triple -g %s -o - | FileCheck %s
 
 // Check that this pointer type is TC<int>
 // CHECK: ![[LINE:[0-9]+]] = {{.*}}"TC<int>", {{.*}} metadata !"_ZTS2TCIiE"} ; [ DW_TAG_class_type ]
diff --git a/test/CodeGenCXX/debug-info-template-member.cpp b/test/CodeGenCXX/debug-info-template-member.cpp
index 9ac1bef..c9a3d9b 100644
--- a/test/CodeGenCXX/debug-info-template-member.cpp
+++ b/test/CodeGenCXX/debug-info-template-member.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -g -triple x86_64-apple-darwin %s -o - | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -g -fno-standalone-debug -triple x86_64-apple-darwin %s -o - | FileCheck %s
 
 struct MyClass {
   template <int i> int add(int j) {
@@ -21,7 +21,7 @@
 // CHECK: [[FOO_FUNC]] = {{.*}}, metadata !"_ZN3foo4funcEN5outerIS_E5innerE", i32 {{[0-9]*}}, metadata [[FOO_FUNC_TYPE:![0-9]*]], {{.*}} ; [ DW_TAG_subprogram ] {{.*}} [func]
 // CHECK: [[FOO_FUNC_TYPE]] = {{.*}}, metadata [[FOO_FUNC_PARAMS:![0-9]*]], i32 0, null, null, null} ; [ DW_TAG_subroutine_type ]
 // CHECK: [[FOO_FUNC_PARAMS]] = metadata !{null, metadata !{{[0-9]*}}, metadata [[OUTER_FOO_INNER:![0-9]*]]}
-// CHECK: [[OUTER_FOO_INNER]] = {{.*}} ; [ DW_TAG_structure_type ] [inner]
+// CHECK: [[OUTER_FOO_INNER]] = {{.*}}, null, metadata !"[[OUTER_FOO_INNER_ID:.*]]"} ; [ DW_TAG_structure_type ] [inner]
 
 // CHECK: metadata [[VIRT_MEM:![0-9]*]], i32 0, metadata !"_ZTS4virtI4elemE", metadata [[VIRT_TEMP_PARAM:![0-9]*]], metadata !"_ZTS4virtI4elemE"} ; [ DW_TAG_structure_type ] [virt<elem>] {{.*}} [def]
 // CHECK: [[VIRT_TEMP_PARAM]] = metadata !{metadata [[VIRT_T:![0-9]*]]}
@@ -59,7 +59,7 @@
 
 outer<foo>::inner x;
 
-// CHECK: metadata [[OUTER_FOO_INNER]], i32 {{[0-9]*}}, i32 {{[0-9]*}}, %"struct.outer<foo>::inner"* @x, {{.*}} ; [ DW_TAG_variable ] [x]
+// CHECK: metadata !"[[OUTER_FOO_INNER_ID]]", i32 {{[0-9]*}}, i32 {{[0-9]*}}, %"struct.outer<foo>::inner"* @x, {{.*}} ; [ DW_TAG_variable ] [x]
 
 template <typename T>
 struct virt {
diff --git a/test/CodeGenCXX/debug-info-template-partial-specialization.cpp b/test/CodeGenCXX/debug-info-template-partial-specialization.cpp
new file mode 100644
index 0000000..cce84af
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-template-partial-specialization.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -g %s -o - -fstandalone-debug | FileCheck %s
+namespace __pointer_type_imp
+{
+  template <class _Tp, class _Dp, bool > struct __pointer_type1 {};
+
+  // CHECK: metadata ![[PARAMS:[0-9]+]], metadata !"_ZTSN18__pointer_type_imp15__pointer_type1I1C14default_deleteIS1_ELb0EEE"} ; [ DW_TAG_structure_type ] [__pointer_type1<C, default_delete<C>, false>] [line [[@LINE+1]], size 8, align 8, offset 0] [def] [from ]
+  template <class _Tp, class _Dp> struct __pointer_type1<_Tp, _Dp, false>
+  {
+    typedef _Tp* type;
+  };
+}
+template <class _Tp, class _Dp>
+struct __pointer_type2
+{
+  // Test that the bool template type parameter is emitted.
+  //
+  // CHECK: ![[PARAMS]] = metadata !{metadata !{{.*}}, metadata !{{.*}}, metadata ![[FALSE:[0-9]+]]}
+  // CHECK: ![[FALSE]] = {{.*}} i8 0, {{.*}}} ; [ DW_TAG_template_value_parameter ]
+  typedef typename __pointer_type_imp::__pointer_type1<_Tp, _Dp, false>::type type;
+};
+template <class _Tp> struct default_delete {};
+template <class _Tp, class _Dp = default_delete<_Tp> > class unique_ptr
+{
+  typedef typename __pointer_type2<_Tp, _Dp>::type pointer;
+  unique_ptr(pointer __p, _Dp __d) {}
+};
+class C {
+  unique_ptr<C> Ptr;
+};
+void foo(C &c) {
+}
diff --git a/test/CodeGenCXX/debug-info-template.cpp b/test/CodeGenCXX/debug-info-template.cpp
index f58973b..d071830 100644
--- a/test/CodeGenCXX/debug-info-template.cpp
+++ b/test/CodeGenCXX/debug-info-template.cpp
@@ -1,7 +1,7 @@
 // RUN: %clang -S -emit-llvm -target x86_64-unknown_unknown -g %s -o - -std=c++11 | FileCheck %s
 
 // CHECK: {{.*}}, i1 false, metadata !"", i32 0, metadata !{{[0-9]]*}}, metadata [[RETAIN:![0-9]*]], {{.*}} ; [ DW_TAG_compile_unit ]
-// CHECK: [[EMPTY:![0-9]*]] = metadata !{i32 0}
+// CHECK: [[EMPTY:![0-9]*]] = metadata !{}
 // CHECK: [[RETAIN]] = metadata !{metadata !{{[0-9]]*}}, metadata [[FOO:![0-9]*]],
 
 
@@ -50,8 +50,8 @@
 //
 
 
-// CHECK: [[TCNESTED:![0-9]*]] = metadata !{i32 {{[0-9]*}}, metadata !{{[0-9]*}}, metadata !"_ZTS2TCIjLj2EXadL_Z3glbEEXadL_ZN3foo1eEEEXadL_ZNS0_1fEvEEXadL_Z4funcvEE9tmpl_implJLi1ELi2ELi3EEE", {{.*}} ; [ DW_TAG_structure_type ] [nested]
-// CHECK: [[TCNT:![0-9]*]] = {{.*}}, metadata [[TCNARGS:![0-9]*]], metadata !"{{.*}}"} ; [ DW_TAG_structure_type ] [TC<int, -3, nullptr, nullptr, nullptr, nullptr, tmpl_impl>]
+// CHECK: metadata !{i32 {{[0-9]*}}, metadata !{{[0-9]*}}, metadata !"_ZTS2TCIjLj2EXadL_Z3glbEEXadL_ZN3foo1eEEEXadL_ZNS0_1fEvEEXadL_Z4funcvEE9tmpl_implJLi1ELi2ELi3EEE", {{.*}}, metadata !"[[TCNESTED:.*]]"} ; [ DW_TAG_structure_type ] [nested]
+// CHECK: metadata [[TCNARGS:![0-9]*]], metadata !"[[TCNT:.*]]"} ; [ DW_TAG_structure_type ] [TC<int, -3, nullptr, nullptr, nullptr, nullptr, tmpl_impl>]
 // CHECK: [[TCNARGS]] = metadata !{metadata [[TCNARG1:![0-9]*]], metadata [[TCNARG2:![0-9]*]], metadata [[TCNARG3:![0-9]*]], metadata [[TCNARG4:![0-9]*]], metadata [[TCNARG5:![0-9]*]], metadata [[TCNARG6:![0-9]*]], metadata [[TCARG7:![0-9]*]], metadata [[TCNARG8:![0-9]*]]}
 // CHECK: [[TCNARG1]] = {{.*}}metadata !"T", metadata [[INT]], {{.*}} ; [ DW_TAG_template_type_parameter ]
 // CHECK: [[TCNARG2]] = {{.*}}metadata !"", metadata [[INT]], i32 -3, {{.*}} ; [ DW_TAG_template_value_parameter ]
@@ -77,9 +77,9 @@
 // CHECK: [[PTOARG1]] = {{.*}}metadata !"", metadata [[CONST_PADDINGATEND_PTR:![0-9]*]], { i32, i8, [3 x i8] }* @PaddedObj, {{.*}} ; [ DW_TAG_template_value_parameter ]
 // CHECK: [[CONST_PADDINGATEND_PTR]] = {{.*}} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from _ZTS12PaddingAtEnd]
 
-// CHECK: metadata [[TCNESTED]], i32 0, i32 1, %"struct.TC<unsigned int, 2, &glb, &foo::e, &foo::f, &func, tmpl_impl, 1, 2, 3>::nested"* @tci, null} ; [ DW_TAG_variable ] [tci]
+// CHECK: metadata !"[[TCNESTED]]", i32 0, i32 1, %"struct.TC<unsigned int, 2, &glb, &foo::e, &foo::f, &func, tmpl_impl, 1, 2, 3>::nested"* @tci, null} ; [ DW_TAG_variable ] [tci]
 
-// CHECK: metadata [[TCNT:![0-9]*]], i32 0, i32 1, %struct.TC* @tcn, null} ; [ DW_TAG_variable ] [tcn]
+// CHECK: metadata !"[[TCNT]]", i32 0, i32 1, %struct.TC* @tcn, null} ; [ DW_TAG_variable ] [tcn]
 struct foo {
   char pad[8]; // make the member pointer to 'e' a bit more interesting (nonzero)
   int e;
diff --git a/test/CodeGenCXX/debug-info-thunk.cpp b/test/CodeGenCXX/debug-info-thunk.cpp
index 2a50895..1d6f1a7 100644
--- a/test/CodeGenCXX/debug-info-thunk.cpp
+++ b/test/CodeGenCXX/debug-info-thunk.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -g -S -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -g -S -emit-llvm -o - | FileCheck %s
 
 struct A {
   virtual void f();
diff --git a/test/CodeGenCXX/debug-info-use-after-free.cpp b/test/CodeGenCXX/debug-info-use-after-free.cpp
index 852e148..0f28a90 100644
--- a/test/CodeGenCXX/debug-info-use-after-free.cpp
+++ b/test/CodeGenCXX/debug-info-use-after-free.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -g -emit-llvm-only %s
+// RUN: %clang_cc1 -g -triple %itanium_abi_triple -emit-llvm-only %s
 // Check that we don't crash.
 // PR12305, PR12315
 
diff --git a/test/CodeGenCXX/debug-info-uuid.cpp b/test/CodeGenCXX/debug-info-uuid.cpp
index a57e2f0..6137400 100644
--- a/test/CodeGenCXX/debug-info-uuid.cpp
+++ b/test/CodeGenCXX/debug-info-uuid.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -fms-extensions -triple=x86_64-pc-win32 -cxx-abi microsoft -g %s -o - -std=c++11 | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -fms-extensions -triple=x86_64-pc-win32 -g %s -o - -std=c++11 | FileCheck %s
 // RUN: not %clang_cc1 -emit-llvm -fms-extensions -triple=x86_64-unknown-unknown -g %s -o - -std=c++11 2>&1 | FileCheck %s --check-prefix=CHECK-ITANIUM
 
 // CHECK: metadata [[TGIARGS:![0-9]*]], null} ; [ DW_TAG_structure_type ] [tmpl_guid<&__uuidof(uuid)>]
diff --git a/test/CodeGenCXX/debug-info-varargs.cpp b/test/CodeGenCXX/debug-info-varargs.cpp
new file mode 100644
index 0000000..cc92477
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-varargs.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -g %s -o - | FileCheck %s
+
+struct A
+{
+  // CHECK-DAG: ", i32 [[@LINE+1]], metadata ![[ATY:[0-9]+]]{{.*}}[ DW_TAG_subprogram ]{{.*}}[a]
+  void a(int c, ...) {}
+  // CHECK: ![[ATY]] ={{.*}} metadata ![[AARGS:[0-9]+]], i32 0, null, null, null} ; [ DW_TAG_subroutine_type ]
+  // CHECK: ![[AARGS]] = {{.*}} metadata ![[UNSPEC:[0-9]+]]}
+  // CHECK: ![[UNSPEC]] = {{.*}} [ DW_TAG_unspecified_parameters ]
+};
+
+  // CHECK: ", i32 [[@LINE+1]], metadata ![[BTY:[0-9]+]]{{.*}}[ DW_TAG_subprogram ]{{.*}}[b]
+void b(int c, ...) {
+  // CHECK: ![[BTY]] ={{.*}} metadata ![[BARGS:[0-9]+]], i32 0, null, null, null} ; [ DW_TAG_subroutine_type ]
+  // CHECK: ![[BARGS]] = {{.*}} metadata ![[UNSPEC:[0-9]+]]}
+
+  A a;
+
+  // CHECK: metadata ![[PST:[0-9]+]], i32 0, i32 0} ; [ DW_TAG_auto_variable ] [fptr] [line [[@LINE+1]]]
+  void (*fptr)(int, ...) = b;
+  // CHECK: ![[PST]] ={{.*}} metadata ![[BTY]]} ; [ DW_TAG_pointer_type ]
+}
diff --git a/test/CodeGenCXX/debug-info-vtable-optzn.cpp b/test/CodeGenCXX/debug-info-vtable-optzn.cpp
new file mode 100644
index 0000000..c693f79
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-vtable-optzn.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -emit-llvm -g -triple x86_64-apple-darwin %s -o - | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -g -triple amd64-unknown-freebsd %s -o - | FileCheck %s
+//
+// This tests that the "emit debug info for a C++ class only in the
+// module that has its vtable" optimization is disabled by default on
+// Darwin and FreeBSD.
+//
+// CHECK: [ DW_TAG_member ] [lost]
+class A
+{
+  virtual bool f() = 0;
+  int lost;
+};
+
+class B : public A
+{
+  B *g();
+};
+
+B *B::g() {
+  return this;
+}
diff --git a/test/CodeGenCXX/debug-info.cpp b/test/CodeGenCXX/debug-info.cpp
index 93a4fe3..7c89dfc 100644
--- a/test/CodeGenCXX/debug-info.cpp
+++ b/test/CodeGenCXX/debug-info.cpp
@@ -51,11 +51,6 @@
   }
 }
 
-void foo() {
-  const wchar_t c = L'x';
-  wchar_t d = c;
-}
-
 namespace b5249287 {
 template <typename T> class A {
   struct B;
@@ -77,7 +72,7 @@
   return f; // reference 'f' for now because otherwise we hit another bug
 }
 
-// CHECK: [[FOO:![0-9]*]] = metadata !{i32 {{[0-9]*}}, metadata !{{[0-9]*}}, metadata [[PR14763:![0-9]*]], {{.*}} ; [ DW_TAG_structure_type ] [foo]
+// CHECK: metadata !{i32 {{[0-9]*}}, metadata !{{[0-9]*}}, metadata [[PR14763:![0-9]*]], {{.*}}, metadata !"[[FOO:.*]]"} ; [ DW_TAG_structure_type ] [foo]
 // CHECK: [[PR14763]] = {{.*}} ; [ DW_TAG_namespace ] [pr14763]
 // CHECK: [[INCTYPE:![0-9]*]] = {{.*}} ; [ DW_TAG_structure_type ] [incomplete]{{.*}} [decl]
 // CHECK: metadata [[A_MEM:![0-9]*]], i32 0, null, null, metadata !"_ZTSN7pr162141aE"} ; [ DW_TAG_structure_type ] [a]
@@ -88,6 +83,13 @@
 // CHECK: [[FUNC:![0-9]*]] = {{.*}} metadata !"_ZN7pr147634funcENS_3fooE", i32 {{[0-9]*}}, metadata [[FUNC_TYPE:![0-9]*]], {{.*}} ; [ DW_TAG_subprogram ] {{.*}} [def] [func]
 }
 
+void foo() {
+  const wchar_t c = L'x';
+  wchar_t d = c;
+}
+
+// CHECK-NOT: ; [ DW_TAG_variable ] [c]
+
 namespace pr9608 { // also pr9600
 struct incomplete;
 incomplete (*x)[3];
@@ -96,8 +98,10 @@
 // CHECK: [[INCARRAY]] = {{.*}}metadata !"_ZTSN6pr960810incompleteE", metadata {{![0-9]*}}, i32 0, null, null, null} ; [ DW_TAG_array_type ] [line 0, size 0, align 0, offset 0] [from _ZTSN6pr960810incompleteE]
 }
 
-// For some reason the argument for PR14763 ended up all the way down here
-// CHECK: = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]], {{.*}}, metadata [[FOO]], i32 8192, i32 0} ; [ DW_TAG_arg_variable ] [f]
+// For some reason function arguments ended up down here
+// CHECK: = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]], {{.*}}, metadata !"[[FOO]]", i32 8192, i32 0} ; [ DW_TAG_arg_variable ] [f]
+
+// CHECK: ; [ DW_TAG_auto_variable ] [c]
 
 namespace pr16214 {
 struct a {
diff --git a/test/CodeGenCXX/decl-ref-init.cpp b/test/CodeGenCXX/decl-ref-init.cpp
index 1a82ee2..117d277 100644
--- a/test/CodeGenCXX/decl-ref-init.cpp
+++ b/test/CodeGenCXX/decl-ref-init.cpp
@@ -1,8 +1,7 @@
-// REQUIRES: x86-registered-target,x86-64-registered-target
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -S %s -o %t-64.s
-// RUN: FileCheck -check-prefix CHECK-LP64 --input-file=%t-64.s %s
-// RUN: %clang_cc1 -triple i386-apple-darwin -S %s -o %t-32.s
-// RUN: FileCheck -check-prefix CHECK-LP32 --input-file=%t-32.s %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -emit-llvm %s -o - | \
+// RUN: FileCheck %s
 
 struct A {};
 
@@ -24,8 +23,5 @@
 	const A& rca2 = d();
 }
 
-// CHECK-LP64: callq    __ZN1BcvR1AEv
-// CHECK-LP64: callq    __ZN1BcvR1AEv
-
-// CHECK-LP32: calll     L__ZN1BcvR1AEv
-// CHECK-LP32: calll     L__ZN1BcvR1AEv
+// CHECK: call dereferenceable({{[0-9]+}}) %struct.A* @_ZN1BcvR1AEv
+// CHECK: call dereferenceable({{[0-9]+}}) %struct.A* @_ZN1BcvR1AEv
diff --git a/test/CodeGenCXX/default-arg-temps.cpp b/test/CodeGenCXX/default-arg-temps.cpp
index 4375600..6a7f43a 100644
--- a/test/CodeGenCXX/default-arg-temps.cpp
+++ b/test/CodeGenCXX/default-arg-temps.cpp
@@ -16,12 +16,12 @@
 // CHECK-LABEL: define void @_Z1gv()
 void g() {
   // CHECK:      call void @_ZN1TC1Ev([[T:%.*]]* [[AGG1:%.*]])
-  // CHECK-NEXT: call void @_Z1fRK1T([[T]]* [[AGG1]])
+  // CHECK-NEXT: call void @_Z1fRK1T([[T]]* dereferenceable({{[0-9]+}}) [[AGG1]])
   // CHECK-NEXT: call void @_ZN1TD1Ev([[T]]* [[AGG1]])
   f();
 
   // CHECK-NEXT: call void @_ZN1TC1Ev([[T:%.*]]* [[AGG2:%.*]])
-  // CHECK-NEXT: call void @_Z1fRK1T([[T]]* [[AGG2]])
+  // CHECK-NEXT: call void @_Z1fRK1T([[T]]* dereferenceable({{[0-9]+}}) [[AGG2]])
   // CHECK-NEXT: call void @_ZN1TD1Ev([[T]]* [[AGG2]])
   f();
 
diff --git a/test/CodeGenCXX/default-arguments.cpp b/test/CodeGenCXX/default-arguments.cpp
index 83cae3a..d364835 100644
--- a/test/CodeGenCXX/default-arguments.cpp
+++ b/test/CodeGenCXX/default-arguments.cpp
@@ -42,15 +42,15 @@
  C();
 };
 
-// CHECK-LABEL: define void @_ZN1CC1Ev(%struct.C* %this) unnamed_addr
-// CHECK: call void @_ZN1CC2Ev(
-
 // CHECK-LABEL: define void @_ZN1CC2Ev(%struct.C* %this) unnamed_addr
 // CHECK: call void @_ZN2A1C1Ev(
 // CHECK: call void @_ZN2A2C1Ev(
 // CHECK: call void @_ZN1BC1ERK2A1RK2A2(
 // CHECK: call void @_ZN2A2D1Ev
 // CHECK: call void @_ZN2A1D1Ev
+
+// CHECK-LABEL: define void @_ZN1CC1Ev(%struct.C* %this) unnamed_addr
+// CHECK: call void @_ZN1CC2Ev(
 C::C() { }
 
 // CHECK-LABEL: define void @_Z2f3v()
diff --git a/test/CodeGenCXX/default-constructor-default-argument.cpp b/test/CodeGenCXX/default-constructor-default-argument.cpp
index 374a967..17ecc35 100644
--- a/test/CodeGenCXX/default-constructor-default-argument.cpp
+++ b/test/CodeGenCXX/default-constructor-default-argument.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s
 
 // Check that call to constructor for struct A is generated correctly.
 struct A { A(int x = 2); };
diff --git a/test/CodeGenCXX/default-constructor-for-members.cpp b/test/CodeGenCXX/default-constructor-for-members.cpp
index 6065b49..5eb8cd1 100644
--- a/test/CodeGenCXX/default-constructor-for-members.cpp
+++ b/test/CodeGenCXX/default-constructor-for-members.cpp
@@ -1,8 +1,7 @@
-// REQUIRES: x86-registered-target,x86-64-registered-target
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -S %s -o %t-64.s
-// RUN: FileCheck -check-prefix CHECK-LP64 --input-file=%t-64.s %s
-// RUN: %clang_cc1 -triple i386-apple-darwin -S %s -o %t-32.s
-// RUN: FileCheck -check-prefix CHECK-LP32 --input-file=%t-32.s %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -emit-llvm %s -o - | \
+// RUN: FileCheck %s
 
 extern "C" int printf(...);
 
@@ -19,6 +18,4 @@
   M m1;
 }
 
-// CHECK-LP64: callq __ZN1SC1Ev
-
-// CHECK-LP32: calll L__ZN1SC1Ev
+// CHECK: call void @_ZN1SC1Ev
diff --git a/test/CodeGenCXX/default-constructor-template-member.cpp b/test/CodeGenCXX/default-constructor-template-member.cpp
index 2156964..93df818 100644
--- a/test/CodeGenCXX/default-constructor-template-member.cpp
+++ b/test/CodeGenCXX/default-constructor-template-member.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
 
 template <class T> struct A { A(); };
 struct B { A<int> x; };
diff --git a/test/CodeGenCXX/default-destructor-nested.cpp b/test/CodeGenCXX/default-destructor-nested.cpp
index 565a727..77b06d6 100644
--- a/test/CodeGenCXX/default-destructor-nested.cpp
+++ b/test/CodeGenCXX/default-destructor-nested.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -emit-llvm-only
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -emit-llvm-only
 // PR6294
 
 class A {
diff --git a/test/CodeGenCXX/deferred-global-init.cpp b/test/CodeGenCXX/deferred-global-init.cpp
index deb458f..f64f507 100644
--- a/test/CodeGenCXX/deferred-global-init.cpp
+++ b/test/CodeGenCXX/deferred-global-init.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s
 // PR5967
 
 extern void* foo;
@@ -11,6 +11,6 @@
 // CHECK: load i8** @foo
 // CHECK: ret void
 
-// CHECK-LABEL: define internal void @_GLOBAL__I_a
+// CHECK-LABEL: define internal void @_GLOBAL__sub_I_deferred_global_init.cpp
 // CHECK: call void @__cxx_global_var_init()
 // CHECK: ret void
diff --git a/test/CodeGenCXX/delayed-template-parsing.cpp b/test/CodeGenCXX/delayed-template-parsing.cpp
index fa177d4..c5f4486 100644
--- a/test/CodeGenCXX/delayed-template-parsing.cpp
+++ b/test/CodeGenCXX/delayed-template-parsing.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -cxx-abi microsoft -fms-extensions -fdelayed-template-parsing -triple=i386-pc-win32 | FileCheck %s
-// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -cxx-abi microsoft -fms-extensions -fdelayed-template-parsing -triple=x86_64-pc-win32 | FileCheck -check-prefix X64 %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -fms-extensions -fdelayed-template-parsing -triple=i386-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -fms-extensions -fdelayed-template-parsing -triple=x86_64-pc-win32 | FileCheck -check-prefix X64 %s
 
 namespace ClassScopeSpecialization {
   struct Type {
diff --git a/test/CodeGenCXX/delete-two-arg.cpp b/test/CodeGenCXX/delete-two-arg.cpp
index f8e6bff..be3cf1a 100644
--- a/test/CodeGenCXX/delete-two-arg.cpp
+++ b/test/CodeGenCXX/delete-two-arg.cpp
@@ -1,4 +1,5 @@
-// RUN: not %clang_cc1 -triple i686-pc-linux-gnu %s -o - -emit-llvm -verify | FileCheck %s
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu %s -o - -emit-llvm -verify | FileCheck %s
+// expected-no-diagnostics
 
 typedef __typeof(sizeof(int)) size_t;
 
diff --git a/test/CodeGenCXX/dependent-type-member-pointer.cpp b/test/CodeGenCXX/dependent-type-member-pointer.cpp
index 99b8ecd..595eca5 100644
--- a/test/CodeGenCXX/dependent-type-member-pointer.cpp
+++ b/test/CodeGenCXX/dependent-type-member-pointer.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -emit-llvm-only -verify %s
+// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -emit-llvm-only -verify %s
 // expected-no-diagnostics
 // PR7736
 
diff --git a/test/CodeGenCXX/derived-to-base-conv.cpp b/test/CodeGenCXX/derived-to-base-conv.cpp
index 675c50c..f4ef0e5 100644
--- a/test/CodeGenCXX/derived-to-base-conv.cpp
+++ b/test/CodeGenCXX/derived-to-base-conv.cpp
@@ -33,9 +33,9 @@
   test0_helper(x);
   // CHECK-LABEL:    define void @_Z5test01X(
   // CHECK:      [[TMP:%.*]] = alloca [[A:%.*]], align
-  // CHECK-NEXT: [[T0:%.*]] = call [[B:%.*]]* @_ZN1XcvR1BEv(
+  // CHECK-NEXT: [[T0:%.*]] = call dereferenceable({{[0-9]+}}) [[B:%.*]]* @_ZN1XcvR1BEv(
   // CHECK-NEXT: [[T1:%.*]] = bitcast [[B]]* [[T0]] to [[A]]*
-  // CHECK-NEXT: call void @_ZN1AC1ERKS_([[A]]* [[TMP]], [[A]]* [[T1]])
+  // CHECK-NEXT: call void @_ZN1AC1ERKS_([[A]]* [[TMP]], [[A]]* dereferenceable({{[0-9]+}}) [[T1]])
   // CHECK-NEXT: call void @_Z12test0_helper1A([[A]]* [[TMP]])
   // CHECK-NEXT: call void @_ZN1AD1Ev([[A]]* [[TMP]])
   // CHECK-NEXT: ret void
diff --git a/test/CodeGenCXX/derived-to-virtual-base-class-calls-final.cpp b/test/CodeGenCXX/derived-to-virtual-base-class-calls-final.cpp
index f2ecfc1..d859283 100644
--- a/test/CodeGenCXX/derived-to-virtual-base-class-calls-final.cpp
+++ b/test/CodeGenCXX/derived-to-virtual-base-class-calls-final.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s
 
 struct A { int i; };
 struct B { char j; };
@@ -9,7 +9,7 @@
   virtual void f();
 };
 
-// CHECK-LABEL: define %struct.B* @_Z1fR1D
+// CHECK-LABEL: define dereferenceable({{[0-9]+}}) %struct.B* @_Z1fR1D
 B &f(D &d) {
   // CHECK-NOT: load i8**
   return d;
diff --git a/test/CodeGenCXX/destructor-exception-spec.cpp b/test/CodeGenCXX/destructor-exception-spec.cpp
index e111ba0..50c17ef 100644
--- a/test/CodeGenCXX/destructor-exception-spec.cpp
+++ b/test/CodeGenCXX/destructor-exception-spec.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -emit-llvm-only %s -std=c++11
-// RUN: %clang_cc1 -emit-llvm-only -fno-use-cxa-atexit %s -std=c++11
-// RUN: %clang_cc1 -cxx-abi microsoft -fno-rtti -emit-llvm-only %s -std=c++11
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm-only %s -std=c++11
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm-only -fno-use-cxa-atexit %s -std=c++11
+// RUN: %clang_cc1 -triple %ms_abi_triple -fno-rtti -emit-llvm-only %s -std=c++11
 
 // PR13479: don't crash with -fno-exceptions.
 namespace {
diff --git a/test/CodeGenCXX/destructors.cpp b/test/CodeGenCXX/destructors.cpp
index 799cca2..5c43048 100644
--- a/test/CodeGenCXX/destructors.cpp
+++ b/test/CodeGenCXX/destructors.cpp
@@ -6,6 +6,13 @@
 // CHECK-DAG: @_ZN5test11OD2Ev = alias {{.*}} @_ZN5test11AD2Ev
 // CHECK-DAG: @_ZN5test11SD2Ev = alias bitcast {{.*}} @_ZN5test11AD2Ev
 
+// WIN32-DAG: @_ZN5test01AD1Ev = alias {{.*}} @_ZN5test01AD2Ev
+// WIN32-DAG: @_ZN5test11MD2Ev = alias {{.*}} @_ZN5test11AD2Ev
+// WIN32-DAG: @_ZN5test11ND2Ev = alias {{.*}} @_ZN5test11AD2Ev
+// WIN32-DAG: @_ZN5test11OD2Ev = alias {{.*}} @_ZN5test11AD2Ev
+// WIN32-DAG: @_ZN5test11SD2Ev = alias bitcast {{.*}} @_ZN5test11AD2Ev
+
+
 struct A {
   int a;
   
@@ -102,6 +109,12 @@
   B::~B() try { } catch (int i) {}
   // It will suppress the delegation optimization here, though.
 
+// CHECK-LABEL: define void @_ZN5test01BD2Ev(%"struct.test0::B"* %this, i8** %vtt) unnamed_addr
+// CHECK: invoke void @_ZN5test06MemberD1Ev
+// CHECK:   unwind label [[MEM_UNWIND:%[a-zA-Z0-9.]+]]
+// CHECK: invoke void @_ZN5test04BaseD2Ev
+// CHECK:   unwind label [[BASE_UNWIND:%[a-zA-Z0-9.]+]]
+
 // CHECK-LABEL: define void @_ZN5test01BD1Ev(%"struct.test0::B"* %this) unnamed_addr
 // CHECK: invoke void @_ZN5test06MemberD1Ev
 // CHECK:   unwind label [[MEM_UNWIND:%[a-zA-Z0-9.]+]]
@@ -109,12 +122,6 @@
 // CHECK:   unwind label [[BASE_UNWIND:%[a-zA-Z0-9.]+]]
 // CHECK: invoke void @_ZN5test05VBaseD2Ev
 // CHECK:   unwind label [[VBASE_UNWIND:%[a-zA-Z0-9.]+]]
-
-// CHECK-LABEL: define void @_ZN5test01BD2Ev(%"struct.test0::B"* %this, i8** %vtt) unnamed_addr
-// CHECK: invoke void @_ZN5test06MemberD1Ev
-// CHECK:   unwind label [[MEM_UNWIND:%[a-zA-Z0-9.]+]]
-// CHECK: invoke void @_ZN5test04BaseD2Ev
-// CHECK:   unwind label [[BASE_UNWIND:%[a-zA-Z0-9.]+]]
 }
 
 // Test base-class aliasing.
@@ -272,14 +279,6 @@
   // FIXME: way too much EH cleanup code follows
 
   C::~C() { opaque(); }
-  // CHECK-LABEL: define void @_ZN5test61CD1Ev(%"struct.test6::C"* %this) unnamed_addr
-  // CHECK:   invoke void @_ZN5test61CD2Ev
-  // CHECK:   invoke void @_ZN5test61BILj3EED2Ev
-  // CHECK:   call void @_ZN5test61BILj2EED2Ev
-  // CHECK:   ret void
-  // CHECK:   invoke void @_ZN5test61BILj3EED2Ev
-  // CHECK:   invoke void @_ZN5test61BILj2EED2Ev
-
   // CHECK-LABEL: define void @_ZN5test61CD2Ev(%"struct.test6::C"* %this, i8** %vtt) unnamed_addr
   // CHECK:   invoke void @_ZN5test66opaqueEv
   // CHECK:   invoke void @_ZN5test61AD1Ev
@@ -293,6 +292,14 @@
   // CHECK:   invoke void @_ZN5test61AD1Ev
   // CHECK:   invoke void @_ZN5test61BILj1EED2Ev
   // CHECK:   invoke void @_ZN5test61BILj0EED2Ev
+
+  // CHECK-LABEL: define void @_ZN5test61CD1Ev(%"struct.test6::C"* %this) unnamed_addr
+  // CHECK:   invoke void @_ZN5test61CD2Ev
+  // CHECK:   invoke void @_ZN5test61BILj3EED2Ev
+  // CHECK:   call void @_ZN5test61BILj2EED2Ev
+  // CHECK:   ret void
+  // CHECK:   invoke void @_ZN5test61BILj3EED2Ev
+  // CHECK:   invoke void @_ZN5test61BILj2EED2Ev
 }
 
 // PR 9197
@@ -374,7 +381,7 @@
 
 // Checks from test3:
 
-  // CHECK-LABEL: define internal void @_ZN5test312_GLOBAL__N_11DD0Ev(%"struct.test3::<anonymous namespace>::D"* %this) unnamed_addr
+  // CHECK-LABEL: define internal void @_ZN5test312_GLOBAL__N_11DD0Ev(%"struct.test3::(anonymous namespace)::D"* %this) unnamed_addr
   // CHECK: invoke void {{.*}} @_ZN5test312_GLOBAL__N_11CD2Ev
   // CHECK: call void @_ZdlPv({{.*}}) [[NUW:#[0-9]+]]
   // CHECK: ret void
@@ -398,7 +405,7 @@
   // CHECK: call void @_ZN5test312_GLOBAL__N_11CD2Ev(
   // CHECK: ret void
 
-  // CHECK-LABEL: define internal void @_ZN5test312_GLOBAL__N_11CD2Ev(%"struct.test3::<anonymous namespace>::C"* %this) unnamed_addr
+  // CHECK-LABEL: define internal void @_ZN5test312_GLOBAL__N_11CD2Ev(%"struct.test3::(anonymous namespace)::C"* %this) unnamed_addr
   // CHECK: invoke void @_ZN5test31BD2Ev(
   // CHECK: call void @_ZN5test31AD2Ev(
   // CHECK: ret void
@@ -406,7 +413,7 @@
   // CHECK: declare void @_ZN5test31BD2Ev(
   // CHECK: declare void @_ZN5test31AD2Ev(
 
-  // CHECK-LABEL: define internal void @_ZN5test312_GLOBAL__N_11CD0Ev(%"struct.test3::<anonymous namespace>::C"* %this) unnamed_addr
+  // CHECK-LABEL: define internal void @_ZN5test312_GLOBAL__N_11CD0Ev(%"struct.test3::(anonymous namespace)::C"* %this) unnamed_addr
   // CHECK: invoke void @_ZN5test312_GLOBAL__N_11CD2Ev(
   // CHECK: call void @_ZdlPv({{.*}}) [[NUW]]
   // CHECK: ret void
diff --git a/test/CodeGenCXX/dllexport-members.cpp b/test/CodeGenCXX/dllexport-members.cpp
new file mode 100644
index 0000000..d913c09
--- /dev/null
+++ b/test/CodeGenCXX/dllexport-members.cpp
@@ -0,0 +1,647 @@
+// RUN: %clang_cc1 -triple i686-windows-msvc -fms-compatibility   -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=MSC --check-prefix=M32 %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -fms-compatibility -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=MSC --check-prefix=M64 %s
+// RUN: %clang_cc1 -triple i686-windows-gnu                       -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=GNU --check-prefix=G32 %s
+// RUN: %clang_cc1 -triple x86_64-windows-gnu                     -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=GNU --check-prefix=G64 %s
+
+// Helper structs to make templates more expressive.
+struct ImplicitInst_Exported {};
+struct ExplicitDecl_Exported {};
+struct ExplicitInst_Exported {};
+struct ExplicitSpec_Exported {};
+struct ExplicitSpec_Def_Exported {};
+struct ExplicitSpec_InlineDef_Exported {};
+struct ExplicitSpec_NotExported {};
+
+extern "C" void* malloc(__SIZE_TYPE__ size);
+extern "C" void free(void* p);
+
+
+//===----------------------------------------------------------------------===//
+// Class members
+//===----------------------------------------------------------------------===//
+
+// Export individual members of a class.
+struct ExportMembers {
+  struct Nested;
+
+  // M32-DAG: define          dllexport x86_thiscallcc void @"\01?normalDef@ExportMembers@@QAEXXZ"(%struct.ExportMembers* %this)
+  // M64-DAG: define          dllexport                void @"\01?normalDef@ExportMembers@@QEAAXXZ"(%struct.ExportMembers* %this)
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?normalInclass@ExportMembers@@QAEXXZ"(%struct.ExportMembers* %this)
+  // M64-DAG: define weak_odr dllexport                void @"\01?normalInclass@ExportMembers@@QEAAXXZ"(%struct.ExportMembers* %this)
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?normalInlineDef@ExportMembers@@QAEXXZ"(%struct.ExportMembers* %this)
+  // M64-DAG: define weak_odr dllexport                void @"\01?normalInlineDef@ExportMembers@@QEAAXXZ"(%struct.ExportMembers* %this)
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?normalInlineDecl@ExportMembers@@QAEXXZ"(%struct.ExportMembers* %this)
+  // M64-DAG: define weak_odr dllexport                void @"\01?normalInlineDecl@ExportMembers@@QEAAXXZ"(%struct.ExportMembers* %this)
+  // G32-DAG: define          dllexport x86_thiscallcc void @_ZN13ExportMembers9normalDefEv(%struct.ExportMembers* %this)
+  // G64-DAG: define          dllexport                void @_ZN13ExportMembers9normalDefEv(%struct.ExportMembers* %this)
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN13ExportMembers13normalInclassEv(%struct.ExportMembers* %this)
+  // G64-DAG: define weak_odr dllexport                void @_ZN13ExportMembers13normalInclassEv(%struct.ExportMembers* %this)
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN13ExportMembers15normalInlineDefEv(%struct.ExportMembers* %this)
+  // G64-DAG: define weak_odr dllexport                void @_ZN13ExportMembers15normalInlineDefEv(%struct.ExportMembers* %this)
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN13ExportMembers16normalInlineDeclEv(%struct.ExportMembers* %this)
+  // G64-DAG: define weak_odr dllexport                void @_ZN13ExportMembers16normalInlineDeclEv(%struct.ExportMembers* %this)
+  // M32-DAG: define linkonce_odr       x86_thiscallcc void @"\01?referencedNonExportedInClass@ExportMembers@@QAEXXZ"
+  __declspec(dllexport)                void normalDef();
+  __declspec(dllexport)                void normalInclass() { referencedNonExportedInClass(); }
+  __declspec(dllexport)                void normalInlineDef();
+  __declspec(dllexport)         inline void normalInlineDecl();
+                                       void referencedNonExportedInClass() {}
+
+  // M32-DAG: define          dllexport x86_thiscallcc void @"\01?virtualDef@ExportMembers@@UAEXXZ"(%struct.ExportMembers* %this)
+  // M64-DAG: define          dllexport                void @"\01?virtualDef@ExportMembers@@UEAAXXZ"(%struct.ExportMembers* %this)
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?virtualInclass@ExportMembers@@UAEXXZ"(%struct.ExportMembers* %this)
+  // M64-DAG: define weak_odr dllexport                void @"\01?virtualInclass@ExportMembers@@UEAAXXZ"(%struct.ExportMembers* %this)
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?virtualInlineDef@ExportMembers@@UAEXXZ"(%struct.ExportMembers* %this)
+  // M64-DAG: define weak_odr dllexport                void @"\01?virtualInlineDef@ExportMembers@@UEAAXXZ"(%struct.ExportMembers* %this)
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?virtualInlineDecl@ExportMembers@@UAEXXZ"(%struct.ExportMembers* %this)
+  // M64-DAG: define weak_odr dllexport                void @"\01?virtualInlineDecl@ExportMembers@@UEAAXXZ"(%struct.ExportMembers* %this)
+  // G32-DAG: define          dllexport x86_thiscallcc void @_ZN13ExportMembers10virtualDefEv(%struct.ExportMembers* %this)
+  // G64-DAG: define          dllexport                void @_ZN13ExportMembers10virtualDefEv(%struct.ExportMembers* %this)
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN13ExportMembers14virtualInclassEv(%struct.ExportMembers* %this)
+  // G64-DAG: define weak_odr dllexport                void @_ZN13ExportMembers14virtualInclassEv(%struct.ExportMembers* %this)
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN13ExportMembers16virtualInlineDefEv(%struct.ExportMembers* %this)
+  // G64-DAG: define weak_odr dllexport                void @_ZN13ExportMembers16virtualInlineDefEv(%struct.ExportMembers* %this)
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN13ExportMembers17virtualInlineDeclEv(%struct.ExportMembers* %this)
+  // G64-DAG: define weak_odr dllexport                void @_ZN13ExportMembers17virtualInlineDeclEv(%struct.ExportMembers* %this)
+  __declspec(dllexport) virtual        void virtualDef();
+  __declspec(dllexport) virtual        void virtualInclass() {}
+  __declspec(dllexport) virtual        void virtualInlineDef();
+  __declspec(dllexport) virtual inline void virtualInlineDecl();
+
+  // MSC-DAG: define          dllexport                void @"\01?staticDef@ExportMembers@@SAXXZ"()
+  // MSC-DAG: define weak_odr dllexport                void @"\01?staticInclass@ExportMembers@@SAXXZ"()
+  // MSC-DAG: define weak_odr dllexport                void @"\01?staticInlineDef@ExportMembers@@SAXXZ"()
+  // MSC-DAG: define weak_odr dllexport                void @"\01?staticInlineDecl@ExportMembers@@SAXXZ"()
+  // GNU-DAG: define          dllexport                void @_ZN13ExportMembers9staticDefEv()
+  // GNU-DAG: define weak_odr dllexport                void @_ZN13ExportMembers13staticInclassEv()
+  // GNU-DAG: define weak_odr dllexport                void @_ZN13ExportMembers15staticInlineDefEv()
+  // GNU-DAG: define weak_odr dllexport                void @_ZN13ExportMembers16staticInlineDeclEv()
+  __declspec(dllexport) static         void staticDef();
+  __declspec(dllexport) static         void staticInclass() {}
+  __declspec(dllexport) static         void staticInlineDef();
+  __declspec(dllexport) static  inline void staticInlineDecl();
+
+  // M32-DAG: define          dllexport x86_thiscallcc void @"\01?protectedDef@ExportMembers@@IAEXXZ"(%struct.ExportMembers* %this)
+  // M64-DAG: define          dllexport                void @"\01?protectedDef@ExportMembers@@IEAAXXZ"(%struct.ExportMembers* %this)
+  // G32-DAG: define          dllexport x86_thiscallcc void @_ZN13ExportMembers12protectedDefEv(%struct.ExportMembers* %this)
+  // G64-DAG: define          dllexport                void @_ZN13ExportMembers12protectedDefEv(%struct.ExportMembers* %this)
+  // MSC-DAG: define          dllexport                void @"\01?protectedStaticDef@ExportMembers@@KAXXZ"()
+  // GNU-DAG: define          dllexport                void @_ZN13ExportMembers18protectedStaticDefEv()
+protected:
+  __declspec(dllexport)                void protectedDef();
+  __declspec(dllexport) static         void protectedStaticDef();
+
+  // M32-DAG: define          dllexport x86_thiscallcc void @"\01?privateDef@ExportMembers@@AAEXXZ"(%struct.ExportMembers* %this)
+  // M64-DAG: define          dllexport                void @"\01?privateDef@ExportMembers@@AEAAXXZ"(%struct.ExportMembers* %this)
+  // G32-DAG: define          dllexport x86_thiscallcc void @_ZN13ExportMembers10privateDefEv(%struct.ExportMembers* %this)
+  // G64-DAG: define          dllexport                void @_ZN13ExportMembers10privateDefEv(%struct.ExportMembers* %this)
+  // MSC-DAG: define          dllexport                void @"\01?privateStaticDef@ExportMembers@@CAXXZ"()
+  // GNU-DAG: define          dllexport                void @_ZN13ExportMembers16privateStaticDefEv()
+private:
+  __declspec(dllexport)                void privateDef();
+  __declspec(dllexport) static         void privateStaticDef();
+
+  // M32-DAG: define                    x86_thiscallcc void @"\01?ignored@ExportMembers@@QAEXXZ"(%struct.ExportMembers* %this)
+  // M64-DAG: define                                   void @"\01?ignored@ExportMembers@@QEAAXXZ"(%struct.ExportMembers* %this)
+  // G32-DAG: define                    x86_thiscallcc void @_ZN13ExportMembers7ignoredEv(%struct.ExportMembers* %this)
+  // G64-DAG: define                                   void @_ZN13ExportMembers7ignoredEv(%struct.ExportMembers* %this)
+public:
+  void ignored();
+
+  // MSC-DAG: @"\01?StaticField@ExportMembers@@2HA"               = dllexport global i32 1, align 4
+  // MSC-DAG: @"\01?StaticConstField@ExportMembers@@2HB"          = dllexport constant i32 1, align 4
+  // MSC-DAG: @"\01?StaticConstFieldEqualInit@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, align 4
+  // MSC-DAG: @"\01?StaticConstFieldBraceInit@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, align 4
+  // MSC-DAG: @"\01?ConstexprField@ExportMembers@@2HB"            = weak_odr dllexport constant i32 1, align 4
+  // GNU-DAG: @_ZN13ExportMembers11StaticFieldE                   = dllexport global i32 1, align 4
+  // GNU-DAG: @_ZN13ExportMembers16StaticConstFieldE              = dllexport constant i32 1, align 4
+  // GNU-DAG: @_ZN13ExportMembers25StaticConstFieldEqualInitE     = dllexport constant i32 1, align 4
+  // GNU-DAG: @_ZN13ExportMembers25StaticConstFieldBraceInitE     = dllexport constant i32 1, align 4
+  // GNU-DAG: @_ZN13ExportMembers14ConstexprFieldE                = dllexport constant i32 1, align 4
+  __declspec(dllexport) static         int  StaticField;
+  __declspec(dllexport) static  const  int  StaticConstField;
+  __declspec(dllexport) static  const  int  StaticConstFieldEqualInit = 1;
+  __declspec(dllexport) static  const  int  StaticConstFieldBraceInit{1};
+  __declspec(dllexport) constexpr static int ConstexprField = 1;
+};
+
+       void ExportMembers::normalDef() {}
+inline void ExportMembers::normalInlineDef() {}
+       void ExportMembers::normalInlineDecl() {}
+       void ExportMembers::virtualDef() {}
+inline void ExportMembers::virtualInlineDef() {}
+       void ExportMembers::virtualInlineDecl() {}
+       void ExportMembers::staticDef() {}
+inline void ExportMembers::staticInlineDef() {}
+       void ExportMembers::staticInlineDecl() {}
+       void ExportMembers::ignored() {}
+       void ExportMembers::protectedDef() {}
+       void ExportMembers::protectedStaticDef() {}
+       void ExportMembers::privateDef() {}
+       void ExportMembers::privateStaticDef() {}
+
+       int  ExportMembers::StaticField = 1;
+const  int  ExportMembers::StaticConstField = 1;
+const  int  ExportMembers::StaticConstFieldEqualInit;
+const  int  ExportMembers::StaticConstFieldBraceInit;
+constexpr int ExportMembers::ConstexprField;
+
+
+// Export individual members of a nested class.
+struct ExportMembers::Nested {
+  // M32-DAG: define          dllexport x86_thiscallcc void @"\01?normalDef@Nested@ExportMembers@@QAEXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // M64-DAG: define          dllexport                void @"\01?normalDef@Nested@ExportMembers@@QEAAXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?normalInclass@Nested@ExportMembers@@QAEXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // M64-DAG: define weak_odr dllexport                void @"\01?normalInclass@Nested@ExportMembers@@QEAAXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?normalInlineDef@Nested@ExportMembers@@QAEXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // M64-DAG: define weak_odr dllexport                void @"\01?normalInlineDef@Nested@ExportMembers@@QEAAXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?normalInlineDecl@Nested@ExportMembers@@QAEXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // M64-DAG: define weak_odr dllexport                void @"\01?normalInlineDecl@Nested@ExportMembers@@QEAAXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // G32-DAG: define          dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested9normalDefEv(%"struct.ExportMembers::Nested"* %this)
+  // G64-DAG: define          dllexport                void @_ZN13ExportMembers6Nested9normalDefEv(%"struct.ExportMembers::Nested"* %this)
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested13normalInclassEv(%"struct.ExportMembers::Nested"* %this)
+  // G64-DAG: define weak_odr dllexport                void @_ZN13ExportMembers6Nested13normalInclassEv(%"struct.ExportMembers::Nested"* %this)
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested15normalInlineDefEv(%"struct.ExportMembers::Nested"* %this)
+  // G64-DAG: define weak_odr dllexport                void @_ZN13ExportMembers6Nested15normalInlineDefEv(%"struct.ExportMembers::Nested"* %this)
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested16normalInlineDeclEv(%"struct.ExportMembers::Nested"* %this)
+  // G64-DAG: define weak_odr dllexport                void @_ZN13ExportMembers6Nested16normalInlineDeclEv(%"struct.ExportMembers::Nested"* %this)
+  __declspec(dllexport)                void normalDef();
+  __declspec(dllexport)                void normalInclass() {}
+  __declspec(dllexport)                void normalInlineDef();
+  __declspec(dllexport)         inline void normalInlineDecl();
+
+  // M32-DAG: define          dllexport x86_thiscallcc void @"\01?virtualDef@Nested@ExportMembers@@UAEXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // M64-DAG: define          dllexport                void @"\01?virtualDef@Nested@ExportMembers@@UEAAXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?virtualInclass@Nested@ExportMembers@@UAEXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // M64-DAG: define weak_odr dllexport                void @"\01?virtualInclass@Nested@ExportMembers@@UEAAXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?virtualInlineDef@Nested@ExportMembers@@UAEXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // M64-DAG: define weak_odr dllexport                void @"\01?virtualInlineDef@Nested@ExportMembers@@UEAAXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?virtualInlineDecl@Nested@ExportMembers@@UAEXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // M64-DAG: define weak_odr dllexport                void @"\01?virtualInlineDecl@Nested@ExportMembers@@UEAAXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // G32-DAG: define          dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested10virtualDefEv(%"struct.ExportMembers::Nested"* %this)
+  // G64-DAG: define          dllexport                void @_ZN13ExportMembers6Nested10virtualDefEv(%"struct.ExportMembers::Nested"* %this)
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested14virtualInclassEv(%"struct.ExportMembers::Nested"* %this)
+  // G64-DAG: define weak_odr dllexport                void @_ZN13ExportMembers6Nested14virtualInclassEv(%"struct.ExportMembers::Nested"* %this)
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested16virtualInlineDefEv(%"struct.ExportMembers::Nested"* %this)
+  // G64-DAG: define weak_odr dllexport                void @_ZN13ExportMembers6Nested16virtualInlineDefEv(%"struct.ExportMembers::Nested"* %this)
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested17virtualInlineDeclEv(%"struct.ExportMembers::Nested"* %this)
+  // G64-DAG: define weak_odr dllexport                void @_ZN13ExportMembers6Nested17virtualInlineDeclEv(%"struct.ExportMembers::Nested"* %this)
+  __declspec(dllexport) virtual        void virtualDef();
+  __declspec(dllexport) virtual        void virtualInclass() {}
+  __declspec(dllexport) virtual        void virtualInlineDef();
+  __declspec(dllexport) virtual inline void virtualInlineDecl();
+
+  // MSC-DAG: define          dllexport                void @"\01?staticDef@Nested@ExportMembers@@SAXXZ"()
+  // MSC-DAG: define weak_odr dllexport                void @"\01?staticInclass@Nested@ExportMembers@@SAXXZ"()
+  // MSC-DAG: define weak_odr dllexport                void @"\01?staticInlineDef@Nested@ExportMembers@@SAXXZ"()
+  // MSC-DAG: define weak_odr dllexport                void @"\01?staticInlineDecl@Nested@ExportMembers@@SAXXZ"()
+  // GNU-DAG: define          dllexport                void @_ZN13ExportMembers6Nested9staticDefEv()
+  // GNU-DAG: define weak_odr dllexport                void @_ZN13ExportMembers6Nested13staticInclassEv()
+  // GNU-DAG: define weak_odr dllexport                void @_ZN13ExportMembers6Nested15staticInlineDefEv()
+  // GNU-DAG: define weak_odr dllexport                void @_ZN13ExportMembers6Nested16staticInlineDeclEv()
+  __declspec(dllexport) static         void staticDef();
+  __declspec(dllexport) static         void staticInclass() {}
+  __declspec(dllexport) static         void staticInlineDef();
+  __declspec(dllexport) static  inline void staticInlineDecl();
+
+  // M32-DAG: define          dllexport x86_thiscallcc void @"\01?protectedDef@Nested@ExportMembers@@IAEXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // M64-DAG: define          dllexport                void @"\01?protectedDef@Nested@ExportMembers@@IEAAXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // G32-DAG: define          dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested12protectedDefEv(%"struct.ExportMembers::Nested"* %this)
+  // G64-DAG: define          dllexport                void @_ZN13ExportMembers6Nested12protectedDefEv(%"struct.ExportMembers::Nested"* %this)
+  // MSC-DAG: define          dllexport                void @"\01?protectedStaticDef@Nested@ExportMembers@@KAXXZ"()
+  // GNU-DAG: define          dllexport                void @_ZN13ExportMembers6Nested18protectedStaticDefEv()
+protected:
+  __declspec(dllexport)                void protectedDef();
+  __declspec(dllexport) static         void protectedStaticDef();
+
+  // M32-DAG: define          dllexport x86_thiscallcc void @"\01?privateDef@Nested@ExportMembers@@AAEXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // M64-DAG: define          dllexport                void @"\01?privateDef@Nested@ExportMembers@@AEAAXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // G32-DAG: define          dllexport x86_thiscallcc void @_ZN13ExportMembers6Nested10privateDefEv(%"struct.ExportMembers::Nested"* %this)
+  // G64-DAG: define          dllexport                void @_ZN13ExportMembers6Nested10privateDefEv(%"struct.ExportMembers::Nested"* %this)
+  // MSC-DAG: define          dllexport                void @"\01?privateStaticDef@Nested@ExportMembers@@CAXXZ"()
+  // GNU-DAG: define          dllexport                void @_ZN13ExportMembers6Nested16privateStaticDefEv()
+private:
+  __declspec(dllexport)                void privateDef();
+  __declspec(dllexport) static         void privateStaticDef();
+
+  // M32-DAG: define                    x86_thiscallcc void @"\01?ignored@Nested@ExportMembers@@QAEXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // M64-DAG: define                                   void @"\01?ignored@Nested@ExportMembers@@QEAAXXZ"(%"struct.ExportMembers::Nested"* %this)
+  // G32-DAG: define                    x86_thiscallcc void @_ZN13ExportMembers6Nested7ignoredEv(%"struct.ExportMembers::Nested"* %this)
+  // G64-DAG: define                                   void @_ZN13ExportMembers6Nested7ignoredEv(%"struct.ExportMembers::Nested"* %this)
+public:
+  void ignored();
+
+  // MSC-DAG: @"\01?StaticField@Nested@ExportMembers@@2HA"               = dllexport global i32 1, align 4
+  // MSC-DAG: @"\01?StaticConstField@Nested@ExportMembers@@2HB"          = dllexport constant i32 1, align 4
+  // MSC-DAG: @"\01?StaticConstFieldEqualInit@Nested@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, align 4
+  // MSC-DAG: @"\01?StaticConstFieldBraceInit@Nested@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, align 4
+  // MSC-DAG: @"\01?ConstexprField@Nested@ExportMembers@@2HB"            = weak_odr dllexport constant i32 1, align 4
+  // GNU-DAG: @_ZN13ExportMembers6Nested11StaticFieldE                   = dllexport global i32 1, align 4
+  // GNU-DAG: @_ZN13ExportMembers6Nested16StaticConstFieldE              = dllexport constant i32 1, align 4
+  // GNU-DAG: @_ZN13ExportMembers6Nested25StaticConstFieldEqualInitE     = dllexport constant i32 1, align 4
+  // GNU-DAG: @_ZN13ExportMembers6Nested25StaticConstFieldBraceInitE     = dllexport constant i32 1, align 4
+  // GNU-DAG: @_ZN13ExportMembers6Nested14ConstexprFieldE                = dllexport constant i32 1, align 4
+  __declspec(dllexport) static         int  StaticField;
+  __declspec(dllexport) static  const  int  StaticConstField;
+  __declspec(dllexport) static  const  int  StaticConstFieldEqualInit = 1;
+  __declspec(dllexport) static  const  int  StaticConstFieldBraceInit{1};
+  __declspec(dllexport) constexpr static int ConstexprField = 1;
+};
+
+       void ExportMembers::Nested::normalDef() {}
+inline void ExportMembers::Nested::normalInlineDef() {}
+       void ExportMembers::Nested::normalInlineDecl() {}
+       void ExportMembers::Nested::virtualDef() {}
+inline void ExportMembers::Nested::virtualInlineDef() {}
+       void ExportMembers::Nested::virtualInlineDecl() {}
+       void ExportMembers::Nested::staticDef() {}
+inline void ExportMembers::Nested::staticInlineDef() {}
+       void ExportMembers::Nested::staticInlineDecl() {}
+       void ExportMembers::Nested::ignored() {}
+       void ExportMembers::Nested::protectedDef() {}
+       void ExportMembers::Nested::protectedStaticDef() {}
+       void ExportMembers::Nested::privateDef() {}
+       void ExportMembers::Nested::privateStaticDef() {}
+
+       int  ExportMembers::Nested::StaticField = 1;
+const  int  ExportMembers::Nested::StaticConstField = 1;
+const  int  ExportMembers::Nested::StaticConstFieldEqualInit;
+const  int  ExportMembers::Nested::StaticConstFieldBraceInit;
+constexpr int ExportMembers::Nested::ConstexprField;
+
+
+// Export special member functions.
+struct ExportSpecials {
+  // M32-DAG: define dllexport x86_thiscallcc %struct.ExportSpecials* @"\01??0ExportSpecials@@QAE@XZ"(%struct.ExportSpecials* returned %this)
+  // M64-DAG: define dllexport                %struct.ExportSpecials* @"\01??0ExportSpecials@@QEAA@XZ"(%struct.ExportSpecials* returned %this)
+  // G32-DAG: define dllexport x86_thiscallcc void @_ZN14ExportSpecialsC1Ev(%struct.ExportSpecials* %this)
+  // G64-DAG: define dllexport                void @_ZN14ExportSpecialsC1Ev(%struct.ExportSpecials* %this)
+  // G32-DAG: define dllexport x86_thiscallcc void @_ZN14ExportSpecialsC2Ev(%struct.ExportSpecials* %this)
+  // G64-DAG: define dllexport                void @_ZN14ExportSpecialsC2Ev(%struct.ExportSpecials* %this)
+  __declspec(dllexport) ExportSpecials();
+
+  // M32-DAG: define dllexport x86_thiscallcc void @"\01??1ExportSpecials@@QAE@XZ"(%struct.ExportSpecials* %this)
+  // M64-DAG: define dllexport                void @"\01??1ExportSpecials@@QEAA@XZ"(%struct.ExportSpecials* %this)
+  // G32-DAG: define dllexport x86_thiscallcc void @_ZN14ExportSpecialsD1Ev(%struct.ExportSpecials* %this)
+  // G64-DAG: define dllexport                void @_ZN14ExportSpecialsD1Ev(%struct.ExportSpecials* %this)
+  // G32-DAG: define dllexport x86_thiscallcc void @_ZN14ExportSpecialsD2Ev(%struct.ExportSpecials* %this)
+  // G64-DAG: define dllexport                void @_ZN14ExportSpecialsD2Ev(%struct.ExportSpecials* %this)
+  __declspec(dllexport) ~ExportSpecials();
+
+  // M32-DAG: define dllexport x86_thiscallcc %struct.ExportSpecials* @"\01??0ExportSpecials@@QAE@ABU0@@Z"(%struct.ExportSpecials* returned %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+  // M64-DAG: define dllexport                %struct.ExportSpecials* @"\01??0ExportSpecials@@QEAA@AEBU0@@Z"(%struct.ExportSpecials* returned %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+  // G32-DAG: define dllexport x86_thiscallcc void @_ZN14ExportSpecialsC1ERKS_(%struct.ExportSpecials* %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+  // G64-DAG: define dllexport                void @_ZN14ExportSpecialsC1ERKS_(%struct.ExportSpecials* %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+  // G32-DAG: define dllexport x86_thiscallcc void @_ZN14ExportSpecialsC2ERKS_(%struct.ExportSpecials* %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+  // G64-DAG: define dllexport                void @_ZN14ExportSpecialsC2ERKS_(%struct.ExportSpecials* %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+  __declspec(dllexport) ExportSpecials(const ExportSpecials&);
+
+  // M32-DAG: define dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ExportSpecials* @"\01??4ExportSpecials@@QAEAAU0@ABU0@@Z"(%struct.ExportSpecials* %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+  // M64-DAG: define dllexport                dereferenceable({{[0-9]+}}) %struct.ExportSpecials* @"\01??4ExportSpecials@@QEAAAEAU0@AEBU0@@Z"(%struct.ExportSpecials* %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+  // G32-DAG: define dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ExportSpecials* @_ZN14ExportSpecialsaSERKS_(%struct.ExportSpecials* %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+  // G64-DAG: define dllexport                dereferenceable({{[0-9]+}}) %struct.ExportSpecials* @_ZN14ExportSpecialsaSERKS_(%struct.ExportSpecials* %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+  __declspec(dllexport) ExportSpecials& operator=(const ExportSpecials&);
+
+  // M32-DAG: define dllexport x86_thiscallcc %struct.ExportSpecials* @"\01??0ExportSpecials@@QAE@$$QAU0@@Z"(%struct.ExportSpecials* returned %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+  // M64-DAG: define dllexport                %struct.ExportSpecials* @"\01??0ExportSpecials@@QEAA@$$QEAU0@@Z"(%struct.ExportSpecials* returned %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+  // G32-DAG: define dllexport x86_thiscallcc void @_ZN14ExportSpecialsC1EOS_(%struct.ExportSpecials* %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+  // G64-DAG: define dllexport                void @_ZN14ExportSpecialsC1EOS_(%struct.ExportSpecials* %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+  // G32-DAG: define dllexport x86_thiscallcc void @_ZN14ExportSpecialsC2EOS_(%struct.ExportSpecials* %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+  // G64-DAG: define dllexport                void @_ZN14ExportSpecialsC2EOS_(%struct.ExportSpecials* %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+  __declspec(dllexport) ExportSpecials(ExportSpecials&&);
+
+  // M32-DAG: define dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ExportSpecials* @"\01??4ExportSpecials@@QAEAAU0@$$QAU0@@Z"(%struct.ExportSpecials* %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+  // M64-DAG: define dllexport                dereferenceable({{[0-9]+}}) %struct.ExportSpecials* @"\01??4ExportSpecials@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ExportSpecials* %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+  // G32-DAG: define dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ExportSpecials* @_ZN14ExportSpecialsaSEOS_(%struct.ExportSpecials* %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+  // G64-DAG: define dllexport                dereferenceable({{[0-9]+}}) %struct.ExportSpecials* @_ZN14ExportSpecialsaSEOS_(%struct.ExportSpecials* %this, %struct.ExportSpecials* dereferenceable({{[0-9]+}}))
+  __declspec(dllexport) ExportSpecials& operator=(ExportSpecials&&);
+};
+ExportSpecials::ExportSpecials() {}
+ExportSpecials::~ExportSpecials() {}
+ExportSpecials::ExportSpecials(const ExportSpecials&) {}
+ExportSpecials& ExportSpecials::operator=(const ExportSpecials&) { return *this; }
+ExportSpecials::ExportSpecials(ExportSpecials&&) {}
+ExportSpecials& ExportSpecials::operator=(ExportSpecials&&) { return *this; }
+
+
+// Export class with inline special member functions.
+struct ExportInlineSpecials {
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportInlineSpecials* @"\01??0ExportInlineSpecials@@QAE@XZ"(%struct.ExportInlineSpecials* returned %this)
+  // M64-DAG: define weak_odr dllexport                %struct.ExportInlineSpecials* @"\01??0ExportInlineSpecials@@QEAA@XZ"(
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN20ExportInlineSpecialsC1Ev(
+  // G64-DAG: define weak_odr dllexport                void @_ZN20ExportInlineSpecialsC1Ev(
+  __declspec(dllexport) ExportInlineSpecials() {}
+
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??1ExportInlineSpecials@@QAE@XZ"(
+  // M64-DAG: define weak_odr dllexport                void @"\01??1ExportInlineSpecials@@QEAA@XZ"(
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN20ExportInlineSpecialsD1Ev(
+  // G64-DAG: define weak_odr dllexport                void @_ZN20ExportInlineSpecialsD1Ev(
+  __declspec(dllexport) ~ExportInlineSpecials() {}
+
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportInlineSpecials* @"\01??0ExportInlineSpecials@@QAE@ABU0@@Z"(
+  // M64-DAG: define weak_odr dllexport                %struct.ExportInlineSpecials* @"\01??0ExportInlineSpecials@@QEAA@AEBU0@@Z"(
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN20ExportInlineSpecialsC1ERKS_(
+  // G64-DAG: define weak_odr dllexport                void @_ZN20ExportInlineSpecialsC1ERKS_(
+  __declspec(dllexport) inline ExportInlineSpecials(const ExportInlineSpecials&);
+
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ExportInlineSpecials* @"\01??4ExportInlineSpecials@@QAEAAU0@ABU0@@Z"(
+  // M64-DAG: define weak_odr dllexport                dereferenceable({{[0-9]+}}) %struct.ExportInlineSpecials* @"\01??4ExportInlineSpecials@@QEAAAEAU0@AEBU0@@Z"(
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ExportInlineSpecials* @_ZN20ExportInlineSpecialsaSERKS_(
+  // G64-DAG: define weak_odr dllexport                dereferenceable({{[0-9]+}}) %struct.ExportInlineSpecials* @_ZN20ExportInlineSpecialsaSERKS_(
+  __declspec(dllexport) ExportInlineSpecials& operator=(const ExportInlineSpecials&);
+
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportInlineSpecials* @"\01??0ExportInlineSpecials@@QAE@$$QAU0@@Z"(
+  // M64-DAG: define weak_odr dllexport                %struct.ExportInlineSpecials* @"\01??0ExportInlineSpecials@@QEAA@$$QEAU0@@Z"(
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN20ExportInlineSpecialsC1EOS_(
+  // G64-DAG: define weak_odr dllexport                void @_ZN20ExportInlineSpecialsC1EOS_(
+  __declspec(dllexport) ExportInlineSpecials(ExportInlineSpecials&&) {}
+
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ExportInlineSpecials* @"\01??4ExportInlineSpecials@@QAEAAU0@$$QAU0@@Z"(
+  // M64-DAG: define weak_odr dllexport                dereferenceable({{[0-9]+}}) %struct.ExportInlineSpecials* @"\01??4ExportInlineSpecials@@QEAAAEAU0@$$QEAU0@@Z"(
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ExportInlineSpecials* @_ZN20ExportInlineSpecialsaSEOS_(
+  // G64-DAG: define weak_odr dllexport                dereferenceable({{[0-9]+}}) %struct.ExportInlineSpecials* @_ZN20ExportInlineSpecialsaSEOS_(
+  __declspec(dllexport) ExportInlineSpecials& operator=(ExportInlineSpecials&&) { return *this; }
+};
+ExportInlineSpecials::ExportInlineSpecials(const ExportInlineSpecials&) {}
+inline ExportInlineSpecials& ExportInlineSpecials::operator=(const ExportInlineSpecials&) { return *this; }
+
+
+// Export defaulted member function definitions.
+struct ExportDefaultedDefs {
+  __declspec(dllexport) ExportDefaultedDefs();
+  __declspec(dllexport) ~ExportDefaultedDefs();
+  __declspec(dllexport) inline ExportDefaultedDefs(const ExportDefaultedDefs&);
+  __declspec(dllexport) ExportDefaultedDefs& operator=(const ExportDefaultedDefs&);
+  __declspec(dllexport) ExportDefaultedDefs(ExportDefaultedDefs&&);
+  __declspec(dllexport) ExportDefaultedDefs& operator=(ExportDefaultedDefs&&);
+};
+
+// M32-DAG: define dllexport x86_thiscallcc %struct.ExportDefaultedDefs* @"\01??0ExportDefaultedDefs@@QAE@XZ"(%struct.ExportDefaultedDefs* returned %this)
+// M64-DAG: define dllexport                %struct.ExportDefaultedDefs* @"\01??0ExportDefaultedDefs@@QEAA@XZ"(%struct.ExportDefaultedDefs* returned %this)
+// G32-DAG: define dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsC1Ev(%struct.ExportDefaultedDefs* %this)
+// G64-DAG: define dllexport                void @_ZN19ExportDefaultedDefsC1Ev(%struct.ExportDefaultedDefs* %this)
+// G32-DAG: define dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsC2Ev(%struct.ExportDefaultedDefs* %this)
+// G64-DAG: define dllexport                void @_ZN19ExportDefaultedDefsC2Ev(%struct.ExportDefaultedDefs* %this)
+__declspec(dllexport) ExportDefaultedDefs::ExportDefaultedDefs() = default;
+
+// M32-DAG: define dllexport x86_thiscallcc void @"\01??1ExportDefaultedDefs@@QAE@XZ"(%struct.ExportDefaultedDefs* %this)
+// M64-DAG: define dllexport                void @"\01??1ExportDefaultedDefs@@QEAA@XZ"(%struct.ExportDefaultedDefs* %this)
+// G32-DAG: define dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsD1Ev(%struct.ExportDefaultedDefs* %this)
+// G64-DAG: define dllexport                void @_ZN19ExportDefaultedDefsD1Ev(%struct.ExportDefaultedDefs* %this)
+// G32-DAG: define dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsD2Ev(%struct.ExportDefaultedDefs* %this)
+// G64-DAG: define dllexport                void @_ZN19ExportDefaultedDefsD2Ev(%struct.ExportDefaultedDefs* %this)
+ExportDefaultedDefs::~ExportDefaultedDefs() = default;
+
+// M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExportDefaultedDefs* @"\01??0ExportDefaultedDefs@@QAE@ABU0@@Z"(%struct.ExportDefaultedDefs* returned %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// M64-DAG: define weak_odr dllexport                %struct.ExportDefaultedDefs* @"\01??0ExportDefaultedDefs@@QEAA@AEBU0@@Z"(%struct.ExportDefaultedDefs* returned %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsC1ERKS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G64-DAG: define weak_odr dllexport                void @_ZN19ExportDefaultedDefsC1ERKS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsC2ERKS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G64-DAG: define weak_odr dllexport                void @_ZN19ExportDefaultedDefsC2ERKS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+__declspec(dllexport) ExportDefaultedDefs::ExportDefaultedDefs(const ExportDefaultedDefs&) = default;
+
+// M32-DAG: define weak_odr dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ExportDefaultedDefs* @"\01??4ExportDefaultedDefs@@QAEAAU0@ABU0@@Z"(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// M64-DAG: define weak_odr dllexport                dereferenceable({{[0-9]+}}) %struct.ExportDefaultedDefs* @"\01??4ExportDefaultedDefs@@QEAAAEAU0@AEBU0@@Z"(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G32-DAG: define weak_odr dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ExportDefaultedDefs* @_ZN19ExportDefaultedDefsaSERKS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G64-DAG: define weak_odr dllexport                dereferenceable({{[0-9]+}}) %struct.ExportDefaultedDefs* @_ZN19ExportDefaultedDefsaSERKS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+inline ExportDefaultedDefs& ExportDefaultedDefs::operator=(const ExportDefaultedDefs&) = default;
+
+// M32-DAG: define dllexport x86_thiscallcc %struct.ExportDefaultedDefs* @"\01??0ExportDefaultedDefs@@QAE@$$QAU0@@Z"(%struct.ExportDefaultedDefs* returned %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// M64-DAG: define dllexport                %struct.ExportDefaultedDefs* @"\01??0ExportDefaultedDefs@@QEAA@$$QEAU0@@Z"(%struct.ExportDefaultedDefs* returned %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G32-DAG: define dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsC1EOS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G64-DAG: define dllexport                void @_ZN19ExportDefaultedDefsC1EOS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G32-DAG: define dllexport x86_thiscallcc void @_ZN19ExportDefaultedDefsC2EOS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G64-DAG: define dllexport                void @_ZN19ExportDefaultedDefsC2EOS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+__declspec(dllexport) ExportDefaultedDefs::ExportDefaultedDefs(ExportDefaultedDefs&&) = default;
+
+// M32-DAG: define dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ExportDefaultedDefs* @"\01??4ExportDefaultedDefs@@QAEAAU0@$$QAU0@@Z"(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// M64-DAG: define dllexport                dereferenceable({{[0-9]+}}) %struct.ExportDefaultedDefs* @"\01??4ExportDefaultedDefs@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G32-DAG: define dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ExportDefaultedDefs* @_ZN19ExportDefaultedDefsaSEOS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G64-DAG: define dllexport                dereferenceable({{[0-9]+}}) %struct.ExportDefaultedDefs* @_ZN19ExportDefaultedDefsaSEOS_(%struct.ExportDefaultedDefs* %this, %struct.ExportDefaultedDefs* dereferenceable({{[0-9]+}}))
+ExportDefaultedDefs& ExportDefaultedDefs::operator=(ExportDefaultedDefs&&) = default;
+
+
+// Export allocation functions.
+struct ExportAlloc {
+  __declspec(dllexport) void* operator new(__SIZE_TYPE__);
+  __declspec(dllexport) void* operator new[](__SIZE_TYPE__);
+  __declspec(dllexport) void operator delete(void*);
+  __declspec(dllexport) void operator delete[](void*);
+};
+
+// M32-DAG: define dllexport i8* @"\01??2ExportAlloc@@SAPAXI@Z"(i32 %n)
+// M64-DAG: define dllexport i8* @"\01??2ExportAlloc@@SAPEAX_K@Z"(i64 %n)
+// G32-DAG: define dllexport i8* @_ZN11ExportAllocnwEj(i32 %n)
+// G64-DAG: define dllexport i8* @_ZN11ExportAllocnwEy(i64 %n)
+void* ExportAlloc::operator new(__SIZE_TYPE__ n) { return malloc(n); }
+
+// M32-DAG: define dllexport i8* @"\01??_UExportAlloc@@SAPAXI@Z"(i32 %n)
+// M64-DAG: define dllexport i8* @"\01??_UExportAlloc@@SAPEAX_K@Z"(i64 %n)
+// G32-DAG: define dllexport i8* @_ZN11ExportAllocnaEj(i32 %n)
+// G64-DAG: define dllexport i8* @_ZN11ExportAllocnaEy(i64 %n)
+void* ExportAlloc::operator new[](__SIZE_TYPE__ n) { return malloc(n); }
+
+// M32-DAG: define dllexport void @"\01??3ExportAlloc@@SAXPAX@Z"(i8* %p)
+// M64-DAG: define dllexport void @"\01??3ExportAlloc@@SAXPEAX@Z"(i8* %p)
+// G32-DAG: define dllexport void @_ZN11ExportAllocdlEPv(i8* %p)
+// G64-DAG: define dllexport void @_ZN11ExportAllocdlEPv(i8* %p)
+void ExportAlloc::operator delete(void* p) { free(p); }
+
+// M32-DAG: define dllexport void @"\01??_VExportAlloc@@SAXPAX@Z"(i8* %p)
+// M64-DAG: define dllexport void @"\01??_VExportAlloc@@SAXPEAX@Z"(i8* %p)
+// G32-DAG: define dllexport void @_ZN11ExportAllocdaEPv(i8* %p)
+// G64-DAG: define dllexport void @_ZN11ExportAllocdaEPv(i8* %p)
+void ExportAlloc::operator delete[](void* p) { free(p); }
+
+
+//===----------------------------------------------------------------------===//
+// Class member templates
+//===----------------------------------------------------------------------===//
+
+struct MemFunTmpl {
+  template<typename T>                              void normalDef() {}
+  template<typename T> __declspec(dllexport)        void exportedNormal() {}
+  template<typename T>                       static void staticDef() {}
+  template<typename T> __declspec(dllexport) static void exportedStatic() {}
+};
+
+// Export implicit instantiation of an exported member function template.
+void useMemFunTmpl() {
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??$exportedNormal@UImplicitInst_Exported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this)
+  // M64-DAG: define weak_odr dllexport                void @"\01??$exportedNormal@UImplicitInst_Exported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this)
+  // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN10MemFunTmpl14exportedNormalI21ImplicitInst_ExportedEEvv(%struct.MemFunTmpl* %this)
+  // G64-DAG: define weak_odr dllexport                void @_ZN10MemFunTmpl14exportedNormalI21ImplicitInst_ExportedEEvv(%struct.MemFunTmpl* %this)
+  MemFunTmpl().exportedNormal<ImplicitInst_Exported>();
+
+  // MSC-DAG: define weak_odr dllexport                void @"\01??$exportedStatic@UImplicitInst_Exported@@@MemFunTmpl@@SAXXZ"()
+  // GNU-DAG: define weak_odr dllexport                void @_ZN10MemFunTmpl14exportedStaticI21ImplicitInst_ExportedEEvv()
+  MemFunTmpl().exportedStatic<ImplicitInst_Exported>();
+}
+
+
+// Export explicit instantiation declaration of an exported member function
+// template.
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??$exportedNormal@UExplicitDecl_Exported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this)
+// M64-DAG: define weak_odr dllexport                void @"\01??$exportedNormal@UExplicitDecl_Exported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this)
+// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN10MemFunTmpl14exportedNormalI21ExplicitDecl_ExportedEEvv(%struct.MemFunTmpl* %this)
+// G64-DAG: define weak_odr dllexport                void @_ZN10MemFunTmpl14exportedNormalI21ExplicitDecl_ExportedEEvv(%struct.MemFunTmpl* %this)
+extern template void MemFunTmpl::exportedNormal<ExplicitDecl_Exported>();
+       template void MemFunTmpl::exportedNormal<ExplicitDecl_Exported>();
+
+// MSC-DAG: define weak_odr dllexport                void @"\01??$exportedStatic@UExplicitDecl_Exported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: define weak_odr dllexport                void @_ZN10MemFunTmpl14exportedStaticI21ExplicitDecl_ExportedEEvv()
+extern template void MemFunTmpl::exportedStatic<ExplicitDecl_Exported>();
+       template void MemFunTmpl::exportedStatic<ExplicitDecl_Exported>();
+
+
+// Export explicit instantiation definition of an exported member function
+// template.
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??$exportedNormal@UExplicitInst_Exported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this)
+// M64-DAG: define weak_odr dllexport                void @"\01??$exportedNormal@UExplicitInst_Exported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this)
+// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN10MemFunTmpl14exportedNormalI21ExplicitInst_ExportedEEvv(%struct.MemFunTmpl* %this)
+// G64-DAG: define weak_odr dllexport                void @_ZN10MemFunTmpl14exportedNormalI21ExplicitInst_ExportedEEvv(%struct.MemFunTmpl* %this)
+template void MemFunTmpl::exportedNormal<ExplicitInst_Exported>();
+
+// MSC-DAG: define weak_odr dllexport                void @"\01??$exportedStatic@UExplicitInst_Exported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: define weak_odr dllexport                void @_ZN10MemFunTmpl14exportedStaticI21ExplicitInst_ExportedEEvv()
+template void MemFunTmpl::exportedStatic<ExplicitInst_Exported>();
+
+
+// Export specialization of an exported member function template.
+// M32-DAG: define          dllexport x86_thiscallcc void @"\01??$exportedNormal@UExplicitSpec_Def_Exported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this)
+// M64-DAG: define          dllexport                void @"\01??$exportedNormal@UExplicitSpec_Def_Exported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this)
+// G32-DAG: define          dllexport x86_thiscallcc void @_ZN10MemFunTmpl14exportedNormalI25ExplicitSpec_Def_ExportedEEvv(%struct.MemFunTmpl* %this)
+// G64-DAG: define          dllexport                void @_ZN10MemFunTmpl14exportedNormalI25ExplicitSpec_Def_ExportedEEvv(%struct.MemFunTmpl* %this)
+template<> __declspec(dllexport) void MemFunTmpl::exportedNormal<ExplicitSpec_Def_Exported>() {}
+
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??$exportedNormal@UExplicitSpec_InlineDef_Exported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this)
+// M64-DAG: define weak_odr dllexport                void @"\01??$exportedNormal@UExplicitSpec_InlineDef_Exported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this)
+// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN10MemFunTmpl14exportedNormalI31ExplicitSpec_InlineDef_ExportedEEvv(%struct.MemFunTmpl* %this)
+// G64-DAG: define weak_odr dllexport                void @_ZN10MemFunTmpl14exportedNormalI31ExplicitSpec_InlineDef_ExportedEEvv(%struct.MemFunTmpl* %this)
+template<> __declspec(dllexport) inline void MemFunTmpl::exportedNormal<ExplicitSpec_InlineDef_Exported>() {}
+
+// MSC-DAG: define          dllexport                void @"\01??$exportedStatic@UExplicitSpec_Def_Exported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: define          dllexport                void @_ZN10MemFunTmpl14exportedStaticI25ExplicitSpec_Def_ExportedEEvv()
+template<> __declspec(dllexport) void MemFunTmpl::exportedStatic<ExplicitSpec_Def_Exported>() {}
+
+// MSC-DAG: define weak_odr dllexport                void @"\01??$exportedStatic@UExplicitSpec_InlineDef_Exported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: define weak_odr dllexport                void @_ZN10MemFunTmpl14exportedStaticI31ExplicitSpec_InlineDef_ExportedEEvv()
+template<> __declspec(dllexport) inline void MemFunTmpl::exportedStatic<ExplicitSpec_InlineDef_Exported>() {}
+
+
+// Not exporting specialization of an exported member function template without
+// explicit dllexport.
+// M32-DAG: define                    x86_thiscallcc void @"\01??$exportedNormal@UExplicitSpec_NotExported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this)
+// M64-DAG: define                                   void @"\01??$exportedNormal@UExplicitSpec_NotExported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this)
+// G32-DAG: define                    x86_thiscallcc void @_ZN10MemFunTmpl14exportedNormalI24ExplicitSpec_NotExportedEEvv(%struct.MemFunTmpl* %this)
+// G64-DAG: define                                   void @_ZN10MemFunTmpl14exportedNormalI24ExplicitSpec_NotExportedEEvv(%struct.MemFunTmpl* %this)
+template<> void MemFunTmpl::exportedNormal<ExplicitSpec_NotExported>() {}
+
+// M32-DAG: define                                   void @"\01??$exportedStatic@UExplicitSpec_NotExported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: define                                   void @_ZN10MemFunTmpl14exportedStaticI24ExplicitSpec_NotExportedEEvv()
+template<> void MemFunTmpl::exportedStatic<ExplicitSpec_NotExported>() {}
+
+
+// Export explicit instantiation declaration of a non-exported member function
+// template.
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??$normalDef@UExplicitDecl_Exported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this)
+// M64-DAG: define weak_odr dllexport                void @"\01??$normalDef@UExplicitDecl_Exported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this)
+// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN10MemFunTmpl9normalDefI21ExplicitDecl_ExportedEEvv(%struct.MemFunTmpl* %this)
+// G64-DAG: define weak_odr dllexport                void @_ZN10MemFunTmpl9normalDefI21ExplicitDecl_ExportedEEvv(%struct.MemFunTmpl* %this)
+extern template __declspec(dllexport) void MemFunTmpl::normalDef<ExplicitDecl_Exported>();
+       template __declspec(dllexport) void MemFunTmpl::normalDef<ExplicitDecl_Exported>();
+
+// M32-DAG: define weak_odr dllexport                void @"\01??$staticDef@UExplicitDecl_Exported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: define weak_odr dllexport                void @_ZN10MemFunTmpl9staticDefI21ExplicitDecl_ExportedEEvv()
+extern template __declspec(dllexport) void MemFunTmpl::staticDef<ExplicitDecl_Exported>();
+       template __declspec(dllexport) void MemFunTmpl::staticDef<ExplicitDecl_Exported>();
+
+
+// Export explicit instantiation definition of a non-exported member function
+// template.
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??$normalDef@UExplicitInst_Exported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this)
+// M64-DAG: define weak_odr dllexport                void @"\01??$normalDef@UExplicitInst_Exported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this)
+// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN10MemFunTmpl9normalDefI21ExplicitInst_ExportedEEvv(%struct.MemFunTmpl* %this)
+// G64-DAG: define weak_odr dllexport                void @_ZN10MemFunTmpl9normalDefI21ExplicitInst_ExportedEEvv(%struct.MemFunTmpl* %this)
+template __declspec(dllexport) void MemFunTmpl::normalDef<ExplicitInst_Exported>();
+
+// MSC-DAG: define weak_odr dllexport                void @"\01??$staticDef@UExplicitInst_Exported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: define weak_odr dllexport                void @_ZN10MemFunTmpl9staticDefI21ExplicitInst_ExportedEEvv()
+template __declspec(dllexport) void MemFunTmpl::staticDef<ExplicitInst_Exported>();
+
+
+// Export specialization of a non-exported member function template.
+// M32-DAG: define          dllexport x86_thiscallcc void @"\01??$normalDef@UExplicitSpec_Def_Exported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this)
+// M64-DAG: define          dllexport                void @"\01??$normalDef@UExplicitSpec_Def_Exported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this)
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??$normalDef@UExplicitSpec_InlineDef_Exported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this)
+// M64-DAG: define weak_odr dllexport                void @"\01??$normalDef@UExplicitSpec_InlineDef_Exported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this)
+// G32-DAG: define          dllexport x86_thiscallcc void @_ZN10MemFunTmpl9normalDefI25ExplicitSpec_Def_ExportedEEvv(%struct.MemFunTmpl* %this)
+// G64-DAG: define          dllexport                void @_ZN10MemFunTmpl9normalDefI25ExplicitSpec_Def_ExportedEEvv(%struct.MemFunTmpl* %this)
+// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN10MemFunTmpl9normalDefI31ExplicitSpec_InlineDef_ExportedEEvv(%struct.MemFunTmpl* %this)
+// G64-DAG: define weak_odr dllexport                void @_ZN10MemFunTmpl9normalDefI31ExplicitSpec_InlineDef_ExportedEEvv(%struct.MemFunTmpl* %this)
+template<> __declspec(dllexport) void MemFunTmpl::normalDef<ExplicitSpec_Def_Exported>() {}
+template<> __declspec(dllexport) inline void MemFunTmpl::normalDef<ExplicitSpec_InlineDef_Exported>() {}
+
+// MSC-DAG: define          dllexport                void @"\01??$staticDef@UExplicitSpec_Def_Exported@@@MemFunTmpl@@SAXXZ"()
+// MSC-DAG: define weak_odr dllexport                void @"\01??$staticDef@UExplicitSpec_InlineDef_Exported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: define          dllexport                void @_ZN10MemFunTmpl9staticDefI25ExplicitSpec_Def_ExportedEEvv()
+// GNU-DAG: define weak_odr dllexport                void @_ZN10MemFunTmpl9staticDefI31ExplicitSpec_InlineDef_ExportedEEvv()
+template<> __declspec(dllexport) void MemFunTmpl::staticDef<ExplicitSpec_Def_Exported>() {}
+template<> __declspec(dllexport) inline void MemFunTmpl::staticDef<ExplicitSpec_InlineDef_Exported>() {}
+
+
+
+struct MemVarTmpl {
+  template<typename T>                       static const int StaticVar = 1;
+  template<typename T> __declspec(dllexport) static const int ExportedStaticVar = 1;
+};
+template<typename T> const int MemVarTmpl::StaticVar;
+template<typename T> const int MemVarTmpl::ExportedStaticVar;
+
+// Export implicit instantiation of an exported member variable template.
+// MSC-DAG: @"\01??$ExportedStaticVar@UImplicitInst_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, align 4
+// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI21ImplicitInst_ExportedEE       = weak_odr dllexport constant i32 1, align 4
+int useMemVarTmpl() { return MemVarTmpl::ExportedStaticVar<ImplicitInst_Exported>; }
+
+// Export explicit instantiation declaration of an exported member variable
+// template.
+// MSC-DAG: @"\01??$ExportedStaticVar@UExplicitDecl_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, align 4
+// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI21ExplicitDecl_ExportedEE       = weak_odr dllexport constant i32 1, align 4
+extern template const int MemVarTmpl::ExportedStaticVar<ExplicitDecl_Exported>;
+       template const int MemVarTmpl::ExportedStaticVar<ExplicitDecl_Exported>;
+
+// Export explicit instantiation definition of an exported member variable
+// template.
+// MSC-DAG: @"\01??$ExportedStaticVar@UExplicitInst_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, align 4
+// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI21ExplicitInst_ExportedEE       = weak_odr dllexport constant i32 1, align 4
+template const int MemVarTmpl::ExportedStaticVar<ExplicitInst_Exported>;
+
+// Export specialization of an exported member variable template.
+// MSC-DAG: @"\01??$ExportedStaticVar@UExplicitSpec_Def_Exported@@@MemVarTmpl@@2HB" = dllexport constant i32 1, align 4
+// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI25ExplicitSpec_Def_ExportedEE       = dllexport constant i32 1, align 4
+template<> __declspec(dllexport) const int MemVarTmpl::ExportedStaticVar<ExplicitSpec_Def_Exported> = 1;
+
+// Not exporting specialization of an exported member variable template without
+// explicit dllexport.
+// MSC-DAG: @"\01??$ExportedStaticVar@UExplicitSpec_NotExported@@@MemVarTmpl@@2HB" = constant i32 1, align 4
+// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI24ExplicitSpec_NotExportedEE       = constant i32 1, align 4
+template<> const int MemVarTmpl::ExportedStaticVar<ExplicitSpec_NotExported> = 1;
+
+
+// Export explicit instantiation declaration of a non-exported member variable
+// template.
+// MSC-DAG: @"\01??$StaticVar@UExplicitDecl_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, align 4
+// GNU-DAG: @_ZN10MemVarTmpl9StaticVarI21ExplicitDecl_ExportedEE        = weak_odr dllexport constant i32 1, align 4
+extern template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitDecl_Exported>;
+       template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitDecl_Exported>;
+
+// Export explicit instantiation definition of a non-exported member variable
+// template.
+// MSC-DAG: @"\01??$StaticVar@UExplicitInst_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, align 4
+// GNU-DAG: @_ZN10MemVarTmpl9StaticVarI21ExplicitInst_ExportedEE        = weak_odr dllexport constant i32 1, align 4
+template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitInst_Exported>;
+
+// Export specialization of a non-exported member variable template.
+// MSC-DAG: @"\01??$StaticVar@UExplicitSpec_Def_Exported@@@MemVarTmpl@@2HB" = dllexport constant i32 1, align 4
+// GNU-DAG: @_ZN10MemVarTmpl9StaticVarI25ExplicitSpec_Def_ExportedEE        = dllexport constant i32 1, align 4
+template<> __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitSpec_Def_Exported> = 1;
diff --git a/test/CodeGenCXX/dllexport.cpp b/test/CodeGenCXX/dllexport.cpp
new file mode 100644
index 0000000..5097abf
--- /dev/null
+++ b/test/CodeGenCXX/dllexport.cpp
@@ -0,0 +1,686 @@
+// RUN: %clang_cc1 -triple i686-windows-msvc   -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=MSC --check-prefix=M32 %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=MSC --check-prefix=M64 %s
+// RUN: %clang_cc1 -triple i686-windows-gnu    -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=GNU --check-prefix=G32 %s
+// RUN: %clang_cc1 -triple x86_64-windows-gnu  -emit-llvm -std=c++1y -O0 -o - %s | FileCheck --check-prefix=GNU --check-prefix=G64 %s
+
+// RUN: %clang_cc1 -triple i686-pc-win32 -O1 -mconstructor-aliases -std=c++1y -emit-llvm -o - %s | FileCheck %s --check-prefix=MSC --check-prefix=M32
+
+// Helper structs to make templates more expressive.
+struct ImplicitInst_Exported {};
+struct ExplicitDecl_Exported {};
+struct ExplicitInst_Exported {};
+struct ExplicitSpec_Exported {};
+struct ExplicitSpec_Def_Exported {};
+struct ExplicitSpec_InlineDef_Exported {};
+struct ExplicitSpec_NotExported {};
+struct External { int v; };
+
+#define JOIN2(x, y) x##y
+#define JOIN(x, y) JOIN2(x, y)
+#define UNIQ(name) JOIN(name, __LINE__)
+#define USEVAR(var) int UNIQ(use)() { return var; }
+#define USE(func) void UNIQ(use)() { func(); }
+#define USEMEMFUNC(class, func) void (class::*UNIQ(use)())() { return &class::func; }
+#define INSTVAR(var) template int var;
+#define INST(func) template void func();
+
+// The vftable for struct W is comdat largest because we have RTTI.
+// M32-DAG: $"\01??_7W@@6B@" = comdat largest
+
+
+//===----------------------------------------------------------------------===//
+// Globals
+//===----------------------------------------------------------------------===//
+
+// Declarations are not exported.
+// MSC-NOT: @"\01?ExternGlobalDecl@@3HA"
+// GNU-NOT: @ExternGlobalDecl
+__declspec(dllexport) extern int ExternGlobalDecl;
+
+// dllexport implies a definition.
+// MSC-DAG: @"\01?GlobalDef@@3HA" = dllexport global i32 0, align 4
+// GNU-DAG: @GlobalDef            = dllexport global i32 0, align 4
+__declspec(dllexport) int GlobalDef;
+
+// Export definition.
+// MSC-DAG: @"\01?GlobalInit1@@3HA" = dllexport global i32 1, align 4
+// GNU-DAG: @GlobalInit1            = dllexport global i32 1, align 4
+__declspec(dllexport) int GlobalInit1 = 1;
+
+// MSC-DAG: @"\01?GlobalInit2@@3HA" = dllexport global i32 1, align 4
+// GNU-DAG: @GlobalInit2            = dllexport global i32 1, align 4
+int __declspec(dllexport) GlobalInit2 = 1;
+
+// Declare, then export definition.
+// MSC-DAG: @"\01?GlobalDeclInit@@3HA" = dllexport global i32 1, align 4
+// GNU-DAG: @GlobalDeclInit            = dllexport global i32 1, align 4
+__declspec(dllexport) extern int GlobalDeclInit;
+int GlobalDeclInit = 1;
+
+// Redeclarations
+// MSC-DAG: @"\01?GlobalRedecl1@@3HA" = dllexport global i32 0, align 4
+// GNU-DAG: @GlobalRedecl1            = dllexport global i32 0, align 4
+__declspec(dllexport) extern int GlobalRedecl1;
+__declspec(dllexport)        int GlobalRedecl1;
+
+// MSC-DAG: @"\01?GlobalRedecl2@@3HA" = dllexport global i32 0, align 4
+// GNU-DAG: @GlobalRedecl2            = dllexport global i32 0, align 4
+__declspec(dllexport) extern int GlobalRedecl2;
+                             int GlobalRedecl2;
+
+// MSC-DAG: @"\01?ExternalGlobal@ns@@3HA" = dllexport global i32 0, align 4
+// GNU-DAG: @_ZN2ns14ExternalGlobalE      = dllexport global i32 0, align 4
+namespace ns { __declspec(dllexport) int ExternalGlobal; }
+
+// MSC-DAG: @"\01?ExternalAutoTypeGlobal@@3UExternal@@A" = dllexport global %struct.External zeroinitializer, align 4
+// GNU-DAG: @ExternalAutoTypeGlobal                      = dllexport global %struct.External zeroinitializer, align 4
+__declspec(dllexport) auto ExternalAutoTypeGlobal = External();
+
+int f();
+// MSC-DAG: @"\01?x@?0??nonInlineStaticLocalsFunc@@YAHXZ@4HA" = internal {{(unnamed_addr )*}}global i32 0
+// MSC-DAG: @"\01?$S1@?0??nonInlineStaticLocalsFunc@@YAHXZ@4IA" = internal {{(unnamed_addr )*}}global i32 0
+int __declspec(dllexport) nonInlineStaticLocalsFunc() {
+  static int x = f();
+  return x++;
+};
+
+// MSC-DAG: @"\01?x@?1??inlineStaticLocalsFunc@@YAHXZ@4HA" = weak_odr dllexport global i32 0
+// MSC-DAG: @"\01??_B?1??inlineStaticLocalsFunc@@YAHXZ@51" = weak_odr dllexport global i32 0
+// Note: MinGW doesn't seem to export the static local here.
+inline int __declspec(dllexport) inlineStaticLocalsFunc() {
+  static int x = f();
+  return x++;
+}
+
+
+
+//===----------------------------------------------------------------------===//
+// Variable templates
+//===----------------------------------------------------------------------===//
+
+// Declarations are not exported.
+
+// dllexport implies a definition.
+// MSC-NOT: @"\01??$VarTmplDef@UExplicitInst_Exported@@@@3HA"
+// GNU-NOT: @_Z10VarTmplDefI21ExplicitInst_ExportedE
+template<typename T> __declspec(dllexport) int VarTmplDef;
+INSTVAR(VarTmplDef<ExplicitInst_Exported>)
+
+// MSC-DAG: @"\01??$VarTmplImplicitDef@UImplicitInst_Exported@@@@3HA" = external dllexport global
+// GNU-DAG: @_Z18VarTmplImplicitDefI21ImplicitInst_ExportedE          = external dllexport global
+template<typename T> __declspec(dllexport) int VarTmplImplicitDef;
+USEVAR(VarTmplImplicitDef<ImplicitInst_Exported>)
+
+// Export definition.
+// MSC-DAG: @"\01??$VarTmplInit1@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
+// GNU-DAG: @_Z12VarTmplInit1I21ExplicitInst_ExportedE          = weak_odr dllexport global i32 1, align 4
+template<typename T> __declspec(dllexport) int VarTmplInit1 = 1;
+INSTVAR(VarTmplInit1<ExplicitInst_Exported>)
+
+// MSC-DAG: @"\01??$VarTmplInit2@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
+// GNU-DAG: @_Z12VarTmplInit2I21ExplicitInst_ExportedE          = weak_odr dllexport global i32 1, align 4
+template<typename T> int __declspec(dllexport) VarTmplInit2 = 1;
+INSTVAR(VarTmplInit2<ExplicitInst_Exported>)
+
+// Declare, then export definition.
+// MSC-DAG: @"\01??$VarTmplDeclInit@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
+// GNU-DAG: @_Z15VarTmplDeclInitI21ExplicitInst_ExportedE          = weak_odr dllexport global i32 1, align 4
+template<typename T> __declspec(dllexport) extern int VarTmplDeclInit;
+template<typename T>                              int VarTmplDeclInit = 1;
+INSTVAR(VarTmplDeclInit<ExplicitInst_Exported>)
+
+// Redeclarations
+// MSC-DAG: @"\01??$VarTmplRedecl1@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
+// GNU-DAG: @_Z14VarTmplRedecl1I21ExplicitInst_ExportedE          = weak_odr dllexport global i32 1, align 4
+template<typename T> __declspec(dllexport) extern int VarTmplRedecl1;
+template<typename T> __declspec(dllexport)        int VarTmplRedecl1 = 1;
+INSTVAR(VarTmplRedecl1<ExplicitInst_Exported>)
+
+// MSC-DAG: @"\01??$VarTmplRedecl2@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
+// GNU-DAG: @_Z14VarTmplRedecl2I21ExplicitInst_ExportedE          = weak_odr dllexport global i32 1, align 4
+template<typename T> __declspec(dllexport) extern int VarTmplRedecl2;
+template<typename T>                              int VarTmplRedecl2 = 1;
+INSTVAR(VarTmplRedecl2<ExplicitInst_Exported>)
+
+// MSC-DAG: @"\01??$ExternalVarTmpl@UExplicitInst_Exported@@@ns@@3HA" = weak_odr dllexport global i32 1, align 4
+// GNU-DAG: @_ZN2ns15ExternalVarTmplI21ExplicitInst_ExportedEE        = weak_odr dllexport global i32 1, align 4
+namespace ns { template<typename T> __declspec(dllexport) int ExternalVarTmpl = 1; }
+INSTVAR(ns::ExternalVarTmpl<ExplicitInst_Exported>)
+
+// MSC-DAG: @"\01??$ExternalAutoTypeVarTmpl@UExplicitInst_Exported@@@@3UExternal@@A" = weak_odr dllexport global %struct.External zeroinitializer, align 4
+// GNU-DAG: @_Z23ExternalAutoTypeVarTmplI21ExplicitInst_ExportedE                    = weak_odr dllexport global %struct.External zeroinitializer, align 4
+template<typename T> __declspec(dllexport) auto ExternalAutoTypeVarTmpl = External();
+template External ExternalAutoTypeVarTmpl<ExplicitInst_Exported>;
+
+
+template<typename T> int VarTmpl = 1;
+template<typename T> __declspec(dllexport) int ExportedVarTmpl = 1;
+
+// Export implicit instantiation of an exported variable template.
+// MSC-DAG: @"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
+// GNU-DAG: @_Z15ExportedVarTmplI21ImplicitInst_ExportedE          = weak_odr dllexport global i32 1, align 4
+USEVAR(ExportedVarTmpl<ImplicitInst_Exported>)
+
+// Export explicit instantiation declaration of an exported variable template.
+// MSC-DAG: @"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
+// GNU-DAG: @_Z15ExportedVarTmplI21ExplicitDecl_ExportedE          = weak_odr dllexport global i32 1, align 4
+extern template int ExportedVarTmpl<ExplicitDecl_Exported>;
+       template int ExportedVarTmpl<ExplicitDecl_Exported>;
+
+// Export explicit instantiation definition of an exported variable template.
+// MSC-DAG: @"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
+// GNU-DAG: @_Z15ExportedVarTmplI21ExplicitInst_ExportedE          = weak_odr dllexport global i32 1, align 4
+template __declspec(dllexport) int ExportedVarTmpl<ExplicitInst_Exported>;
+
+// Export specialization of an exported variable template.
+// MSC-DAG: @"\01??$ExportedVarTmpl@UExplicitSpec_Exported@@@@3HA" = dllexport global i32 0, align 4
+// GNU-DAG: @_Z15ExportedVarTmplI21ExplicitSpec_ExportedE          = dllexport global i32 0, align 4
+template<> __declspec(dllexport) int ExportedVarTmpl<ExplicitSpec_Exported>;
+
+// MSC-DAG: @"\01??$ExportedVarTmpl@UExplicitSpec_Def_Exported@@@@3HA" = dllexport global i32 1, align 4
+// GNU-DAG: @_Z15ExportedVarTmplI25ExplicitSpec_Def_ExportedE          = dllexport global i32 1, align 4
+template<> __declspec(dllexport) int ExportedVarTmpl<ExplicitSpec_Def_Exported> = 1;
+
+// Not exporting specialization of an exported variable template without
+// explicit dllexport.
+// MSC-DAG: @"\01??$ExportedVarTmpl@UExplicitSpec_NotExported@@@@3HA" = global i32 0, align 4
+// GNU-DAG: @_Z15ExportedVarTmplI24ExplicitSpec_NotExportedE          = global i32 0, align 4
+template<> int ExportedVarTmpl<ExplicitSpec_NotExported>;
+
+
+// Export explicit instantiation declaration of a non-exported variable template.
+// MSC-DAG: @"\01??$VarTmpl@UExplicitDecl_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
+// GNU-DAG: @_Z7VarTmplI21ExplicitDecl_ExportedE           = weak_odr dllexport global i32 1, align 4
+extern template __declspec(dllexport) int VarTmpl<ExplicitDecl_Exported>;
+       template __declspec(dllexport) int VarTmpl<ExplicitDecl_Exported>;
+
+// Export explicit instantiation definition of a non-exported variable template.
+// MSC-DAG: @"\01??$VarTmpl@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4
+// GNU-DAG: @_Z7VarTmplI21ExplicitInst_ExportedE           = weak_odr dllexport global i32 1, align 4
+template __declspec(dllexport) int VarTmpl<ExplicitInst_Exported>;
+
+// Export specialization of a non-exported variable template.
+// MSC-DAG: @"\01??$VarTmpl@UExplicitSpec_Exported@@@@3HA" = dllexport global i32 0, align 4
+// GNU-DAG: @_Z7VarTmplI21ExplicitSpec_ExportedE           = dllexport global i32 0, align 4
+template<> __declspec(dllexport) int VarTmpl<ExplicitSpec_Exported>;
+
+// MSC-DAG: @"\01??$VarTmpl@UExplicitSpec_Def_Exported@@@@3HA" = dllexport global i32 1, align 4
+// GNU-DAG: @_Z7VarTmplI25ExplicitSpec_Def_ExportedE           = dllexport global i32 1, align 4
+template<> __declspec(dllexport) int VarTmpl<ExplicitSpec_Def_Exported> = 1;
+
+
+
+//===----------------------------------------------------------------------===//
+// Functions
+//===----------------------------------------------------------------------===//
+
+// Declarations are not exported.
+
+// Export function definition.
+// MSC-DAG: define dllexport void @"\01?def@@YAXXZ"()
+// GNU-DAG: define dllexport void @_Z3defv()
+__declspec(dllexport) void def() {}
+
+// extern "C"
+// MSC-DAG: define dllexport void @externC()
+// GNU-DAG: define dllexport void @externC()
+extern "C" __declspec(dllexport) void externC() {}
+
+// Export inline function.
+// MSC-DAG: define weak_odr dllexport void @"\01?inlineFunc@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z10inlineFuncv()
+__declspec(dllexport) inline void inlineFunc() {}
+
+// MSC-DAG: define weak_odr dllexport void @"\01?inlineDecl@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z10inlineDeclv()
+__declspec(dllexport) inline void inlineDecl();
+                             void inlineDecl() {}
+
+// MSC-DAG: define weak_odr dllexport void @"\01?inlineDef@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z9inlineDefv()
+__declspec(dllexport) void inlineDef();
+               inline void inlineDef() {}
+
+// Redeclarations
+// MSC-DAG: define dllexport void @"\01?redecl1@@YAXXZ"()
+// GNU-DAG: define dllexport void @_Z7redecl1v()
+__declspec(dllexport) void redecl1();
+__declspec(dllexport) void redecl1() {}
+
+// MSC-DAG: define dllexport void @"\01?redecl2@@YAXXZ"()
+// GNU-DAG: define dllexport void @_Z7redecl2v()
+__declspec(dllexport) void redecl2();
+                      void redecl2() {}
+
+// Friend functions
+// MSC-DAG: define dllexport void @"\01?friend1@@YAXXZ"()
+// GNU-DAG: define dllexport void @_Z7friend1v()
+// MSC-DAG: define dllexport void @"\01?friend2@@YAXXZ"()
+// GNU-DAG: define dllexport void @_Z7friend2v()
+struct FuncFriend {
+  friend __declspec(dllexport) void friend1();
+  friend __declspec(dllexport) void friend2();
+};
+__declspec(dllexport) void friend1() {}
+                      void friend2() {}
+
+// Implicit declarations can be redeclared with dllexport.
+// MSC-DAG: define dllexport noalias i8* @"\01??2@{{YAPAXI|YAPEAX_K}}@Z"(
+// GNU-DAG: define dllexport noalias i8* @_Znw{{[yj]}}(
+void* alloc(__SIZE_TYPE__ n);
+__declspec(dllexport) void* operator new(__SIZE_TYPE__ n) { return alloc(n); }
+
+// MSC-DAG: define dllexport void @"\01?externalFunc@ns@@YAXXZ"()
+// GNU-DAG: define dllexport void @_ZN2ns12externalFuncEv()
+namespace ns { __declspec(dllexport) void externalFunc() {} }
+
+
+
+//===----------------------------------------------------------------------===//
+// Function templates
+//===----------------------------------------------------------------------===//
+
+// Export function template definition.
+// MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplDef@UExplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z11funcTmplDefI21ExplicitInst_ExportedEvv()
+template<typename T> __declspec(dllexport) void funcTmplDef() {}
+INST(funcTmplDef<ExplicitInst_Exported>)
+
+// Export inline function template.
+// MSC-DAG: define weak_odr dllexport void @"\01??$inlineFuncTmpl1@UExplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z15inlineFuncTmpl1I21ExplicitInst_ExportedEvv()
+template<typename T> __declspec(dllexport) inline void inlineFuncTmpl1() {}
+INST(inlineFuncTmpl1<ExplicitInst_Exported>)
+
+// MSC-DAG: define weak_odr dllexport void @"\01??$inlineFuncTmpl2@UExplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z15inlineFuncTmpl2I21ExplicitInst_ExportedEvv()
+template<typename T> inline void __attribute__((dllexport)) inlineFuncTmpl2() {}
+INST(inlineFuncTmpl2<ExplicitInst_Exported>)
+
+// MSC-DAG: define weak_odr dllexport void @"\01??$inlineFuncTmplDecl@UExplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z18inlineFuncTmplDeclI21ExplicitInst_ExportedEvv()
+template<typename T> __declspec(dllexport) inline void inlineFuncTmplDecl();
+template<typename T>                              void inlineFuncTmplDecl() {}
+INST(inlineFuncTmplDecl<ExplicitInst_Exported>)
+
+// MSC-DAG: define weak_odr dllexport void @"\01??$inlineFuncTmplDef@UExplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z17inlineFuncTmplDefI21ExplicitInst_ExportedEvv()
+template<typename T> __declspec(dllexport) void inlineFuncTmplDef();
+template<typename T>                inline void inlineFuncTmplDef() {}
+INST(inlineFuncTmplDef<ExplicitInst_Exported>)
+
+
+// Redeclarations
+// MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplRedecl1@UExplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z15funcTmplRedecl1I21ExplicitInst_ExportedEvv()
+template<typename T> __declspec(dllexport) void funcTmplRedecl1();
+template<typename T> __declspec(dllexport) void funcTmplRedecl1() {}
+INST(funcTmplRedecl1<ExplicitInst_Exported>)
+
+// MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplRedecl2@UExplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z15funcTmplRedecl2I21ExplicitInst_ExportedEvv()
+template<typename T> __declspec(dllexport) void funcTmplRedecl2();
+template<typename T>                       void funcTmplRedecl2() {}
+INST(funcTmplRedecl2<ExplicitInst_Exported>)
+
+// MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplRedecl3@UExplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z15funcTmplRedecl3I21ExplicitInst_ExportedEvv()
+template<typename T> __declspec(dllexport) void funcTmplRedecl3();
+template<typename T>                       void funcTmplRedecl3() {}
+INST(funcTmplRedecl3<ExplicitInst_Exported>)
+
+
+// Function template friends
+// MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplFriend1@UExplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z15funcTmplFriend1I21ExplicitInst_ExportedEvv()
+// MSC-DAG: define weak_odr dllexport void @"\01??$funcTmplFriend2@UExplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z15funcTmplFriend2I21ExplicitInst_ExportedEvv()
+struct FuncTmplFriend {
+  template<typename T> friend __declspec(dllexport) void funcTmplFriend1();
+  template<typename T> friend __declspec(dllexport) void funcTmplFriend2();
+};
+template<typename T> __declspec(dllexport) void funcTmplFriend1() {}
+template<typename T>                       void funcTmplFriend2() {}
+INST(funcTmplFriend1<ExplicitInst_Exported>)
+INST(funcTmplFriend2<ExplicitInst_Exported>)
+
+// MSC-DAG: define weak_odr dllexport void @"\01??$externalFuncTmpl@UExplicitInst_Exported@@@ns@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_ZN2ns16externalFuncTmplI21ExplicitInst_ExportedEEvv()
+namespace ns { template<typename T> __declspec(dllexport) void externalFuncTmpl() {} }
+INST(ns::externalFuncTmpl<ExplicitInst_Exported>)
+
+
+template<typename T> void funcTmpl() {}
+template<typename T> __declspec(dllexport) void exportedFuncTmpl() {}
+
+// Export implicit instantiation of an exported function template.
+// MSC-DAG: define weak_odr dllexport void @"\01??$exportedFuncTmpl@UImplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z16exportedFuncTmplI21ImplicitInst_ExportedEvv()
+USE(exportedFuncTmpl<ImplicitInst_Exported>)
+
+// Export explicit instantiation declaration of an exported function template.
+// MSC-DAG: define weak_odr dllexport void @"\01??$exportedFuncTmpl@UExplicitDecl_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z16exportedFuncTmplI21ExplicitDecl_ExportedEvv()
+extern template void exportedFuncTmpl<ExplicitDecl_Exported>();
+       template void exportedFuncTmpl<ExplicitDecl_Exported>();
+
+// Export explicit instantiation definition of an exported function template.
+// MSC-DAG: define weak_odr dllexport void @"\01??$exportedFuncTmpl@UExplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z16exportedFuncTmplI21ExplicitInst_ExportedEvv()
+template void exportedFuncTmpl<ExplicitInst_Exported>();
+
+// Export specialization of an exported function template.
+// MSC-DAG: define dllexport void @"\01??$exportedFuncTmpl@UExplicitSpec_Def_Exported@@@@YAXXZ"()
+// GNU-DAG: define dllexport void @_Z16exportedFuncTmplI25ExplicitSpec_Def_ExportedEvv()
+template<> __declspec(dllexport) void exportedFuncTmpl<ExplicitSpec_Def_Exported>() {}
+
+// MSC-DAG: define weak_odr dllexport void @"\01??$exportedFuncTmpl@UExplicitSpec_InlineDef_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z16exportedFuncTmplI31ExplicitSpec_InlineDef_ExportedEvv()
+template<> __declspec(dllexport) inline void exportedFuncTmpl<ExplicitSpec_InlineDef_Exported>() {}
+
+// Not exporting specialization of an exported function template without
+// explicit dllexport.
+// MSC-DAG: define void @"\01??$exportedFuncTmpl@UExplicitSpec_NotExported@@@@YAXXZ"()
+// GNU-DAG: define void @_Z16exportedFuncTmplI24ExplicitSpec_NotExportedEvv()
+template<> void exportedFuncTmpl<ExplicitSpec_NotExported>() {}
+
+
+// Export explicit instantiation declaration of a non-exported function template.
+// MSC-DAG: define weak_odr dllexport void @"\01??$funcTmpl@UExplicitDecl_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z8funcTmplI21ExplicitDecl_ExportedEvv()
+extern template __declspec(dllexport) void funcTmpl<ExplicitDecl_Exported>();
+       template __declspec(dllexport) void funcTmpl<ExplicitDecl_Exported>();
+
+// Export explicit instantiation definition of a non-exported function template.
+// MSC-DAG: define weak_odr dllexport void @"\01??$funcTmpl@UExplicitInst_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z8funcTmplI21ExplicitInst_ExportedEvv()
+template __declspec(dllexport) void funcTmpl<ExplicitInst_Exported>();
+
+// Export specialization of a non-exported function template.
+// MSC-DAG: define dllexport void @"\01??$funcTmpl@UExplicitSpec_Def_Exported@@@@YAXXZ"()
+// GNU-DAG: define dllexport void @_Z8funcTmplI25ExplicitSpec_Def_ExportedEvv()
+template<> __declspec(dllexport) void funcTmpl<ExplicitSpec_Def_Exported>() {}
+
+// MSC-DAG: define weak_odr dllexport void @"\01??$funcTmpl@UExplicitSpec_InlineDef_Exported@@@@YAXXZ"()
+// GNU-DAG: define weak_odr dllexport void @_Z8funcTmplI31ExplicitSpec_InlineDef_ExportedEvv()
+template<> __declspec(dllexport) inline void funcTmpl<ExplicitSpec_InlineDef_Exported>() {}
+
+
+
+//===----------------------------------------------------------------------===//
+// Precedence
+//===----------------------------------------------------------------------===//
+
+// dllexport takes precedence over the dllimport if both are specified.
+// MSC-DAG: @"\01?PrecedenceGlobal1A@@3HA" = dllexport global i32 0, align 4
+// MSC-DAG: @"\01?PrecedenceGlobal1B@@3HA" = dllexport global i32 0, align 4
+// GNU-DAG: @PrecedenceGlobal1A            = dllexport global i32 0, align 4
+// GNU-DAG: @PrecedenceGlobal1B            = dllexport global i32 0, align 4
+__attribute__((dllimport, dllexport))       int PrecedenceGlobal1A; // dllimport ignored
+__declspec(dllimport) __declspec(dllexport) int PrecedenceGlobal1B; // dllimport ignored
+
+// MSC-DAG: @"\01?PrecedenceGlobal2A@@3HA" = dllexport global i32 0, align 4
+// MSC-DAG: @"\01?PrecedenceGlobal2B@@3HA" = dllexport global i32 0, align 4
+// GNU-DAG: @PrecedenceGlobal2A            = dllexport global i32 0, align 4
+// GNU-DAG: @PrecedenceGlobal2B            = dllexport global i32 0, align 4
+__attribute__((dllexport, dllimport))       int PrecedenceGlobal2A; // dllimport ignored
+__declspec(dllexport) __declspec(dllimport) int PrecedenceGlobal2B; // dllimport ignored
+
+// MSC-DAG: @"\01?PrecedenceGlobalRedecl1@@3HA" = dllexport global i32 0, align 4
+// GNU-DAG: @PrecedenceGlobalRedecl1            = dllexport global i32 0, align 4
+__declspec(dllexport) extern int PrecedenceGlobalRedecl1;
+__declspec(dllimport)        int PrecedenceGlobalRedecl1 = 0;
+
+// MSC-DAG: @"\01?PrecedenceGlobalRedecl2@@3HA" = dllexport global i32 0, align 4
+// GNU-DAG: @PrecedenceGlobalRedecl2            = dllexport global i32 0, align 4
+__declspec(dllimport) extern int PrecedenceGlobalRedecl2;
+__declspec(dllexport)        int PrecedenceGlobalRedecl2;
+
+// MSC-DAG: @"\01?PrecedenceGlobalMixed1@@3HA" = dllexport global i32 0, align 4
+// GNU-DAG: @PrecedenceGlobalMixed1            = dllexport global i32 0, align 4
+__attribute__((dllexport)) extern int PrecedenceGlobalMixed1;
+__declspec(dllimport)             int PrecedenceGlobalMixed1 = 0;
+
+// MSC-DAG: @"\01?PrecedenceGlobalMixed2@@3HA" = dllexport global i32 0, align 4
+// GNU-DAG: @PrecedenceGlobalMixed2            = dllexport global i32 0, align 4
+__attribute__((dllimport)) extern int PrecedenceGlobalMixed2;
+__declspec(dllexport)             int PrecedenceGlobalMixed2;
+
+// MSC-DAG: define dllexport void @"\01?precedence1A@@YAXXZ"
+// MSC-DAG: define dllexport void @"\01?precedence1B@@YAXXZ"
+// GNU-DAG: define dllexport void @_Z12precedence1Av()
+// GNU-DAG: define dllexport void @_Z12precedence1Bv()
+void __attribute__((dllimport, dllexport))       precedence1A() {}
+void __declspec(dllimport) __declspec(dllexport) precedence1B() {}
+
+// MSC-DAG: define dllexport void @"\01?precedence2A@@YAXXZ"
+// MSC-DAG: define dllexport void @"\01?precedence2B@@YAXXZ"
+// GNU-DAG: define dllexport void @_Z12precedence2Av()
+// GNU-DAG: define dllexport void @_Z12precedence2Bv()
+void __attribute__((dllexport, dllimport))       precedence2A() {}
+void __declspec(dllexport) __declspec(dllimport) precedence2B() {}
+
+// MSC-DAG: define dllexport void @"\01?precedenceRedecl1@@YAXXZ"
+// GNU-DAG: define dllexport void @_Z17precedenceRedecl1v()
+void __declspec(dllimport) precedenceRedecl1();
+void __declspec(dllexport) precedenceRedecl1() {}
+
+// MSC-DAG: define dllexport void @"\01?precedenceRedecl2@@YAXXZ"
+// GNU-DAG: define dllexport void @_Z17precedenceRedecl2v()
+void __declspec(dllexport) precedenceRedecl2();
+void __declspec(dllimport) precedenceRedecl2() {}
+
+
+
+//===----------------------------------------------------------------------===//
+// Classes
+//===----------------------------------------------------------------------===//
+
+struct S {
+  void __declspec(dllexport) a() {}
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?a@S@@QAEXXZ"
+
+  struct T {
+    void __declspec(dllexport) a() {}
+    // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?a@T@S@@QAEXXZ"
+  };
+};
+
+
+struct __declspec(dllexport) T {
+  // Copy assignment operator:
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.T* @"\01??4T@@QAEAAU0@ABU0@@Z"
+
+  // Explicitly defaulted copy constructur:
+  T(const T&) = default;
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.T* @"\01??0T@@QAE@ABU0@@Z"
+
+  void a() {}
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?a@T@@QAEXXZ"
+
+  static int b;
+  // M32-DAG: @"\01?b@T@@2HA" = external dllexport global i32
+
+  static int c;
+  // M32-DAG: @"\01?c@T@@2HA" = dllexport global i32 0, align 4
+};
+
+USEVAR(T::b)
+int T::c;
+
+template <typename T> struct __declspec(dllexport) U { void foo() {} };
+// The U<int> specialization below must cause the following to be emitted:
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?foo@?$U@H@@QAEXXZ"
+// M32-DAG: define weak_odr dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.U* @"\01??4?$U@H@@QAEAAU0@ABU0@@Z"
+struct __declspec(dllexport) V : public U<int> { };
+
+
+struct __declspec(dllexport) W { virtual void foo() {} };
+// Default ctor:
+// M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.W* @"\01??0W@@QAE@XZ"
+// Copy ctor:
+// M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.W* @"\01??0W@@QAE@ABU0@@Z"
+// vftable:
+// M32-DAG: [[W_VTABLE:@.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4W@@6B@" to i8*), i8* bitcast (void (%struct.W*)* @"\01?foo@W@@UAEXXZ" to i8*)], comdat $"\01??_7W@@6B@"
+// M32-DAG: @"\01??_7W@@6B@" = dllexport unnamed_addr alias getelementptr inbounds ([2 x i8*]* [[W_VTABLE]], i32 0, i32 1)
+// G32-DAG: @_ZTV1W = weak_odr dllexport unnamed_addr constant [3 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI1W to i8*), i8* bitcast (void (%struct.W*)* @_ZN1W3fooEv to i8*)]
+
+struct __declspec(dllexport) X : public virtual W {};
+// vbtable:
+// M32-DAG: @"\01??_8X@@7B@" = weak_odr dllexport unnamed_addr constant [2 x i32] [i32 0, i32 4]
+
+struct __declspec(dllexport) Y {
+  // Move assignment operator:
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.Y* @"\01??4Y@@QAEAAU0@$$QAU0@@Z"
+
+  int x;
+};
+
+struct __declspec(dllexport) Z { virtual ~Z() {} };
+// The scalar deleting dtor does not get exported:
+// M32-DAG: define linkonce_odr x86_thiscallcc void @"\01??_GZ@@UAEPAXI@Z"
+
+
+// The user-defined dtor does get exported:
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??1Z@@UAE@XZ"
+
+namespace DontUseDtorAlias {
+  struct __declspec(dllexport) A { ~A(); };
+  struct __declspec(dllexport) B : A { ~B(); };
+  A::~A() { }
+  B::~B() { }
+  // Emit a real definition of B's constructor; don't alias it to A's.
+  // M32-DAG: define dllexport x86_thiscallcc void @"\01??1B@DontUseDtorAlias@@QAE@XZ"
+}
+
+struct __declspec(dllexport) DefaultedCtorsDtors {
+  DefaultedCtorsDtors() = default;
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.DefaultedCtorsDtors* @"\01??0DefaultedCtorsDtors@@QAE@XZ"
+  ~DefaultedCtorsDtors() = default;
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??1DefaultedCtorsDtors@@QAE@XZ"
+};
+
+namespace ReferencedInlineMethodInNestedClass {
+  struct __declspec(dllexport) S {
+    void foo() {
+      t->bar();
+    }
+    struct T {
+      void bar() {}
+    };
+    T *t;
+  };
+  // M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?foo@S@ReferencedInlineMethodInNestedClass@@QAEXXZ"
+  // M32-DAG: define linkonce_odr x86_thiscallcc void @"\01?bar@T@S@ReferencedInlineMethodInNestedClass@@QAEXXZ"
+}
+
+// MS ignores DLL attributes on partial specializations.
+template <typename T> struct PartiallySpecializedClassTemplate {};
+template <typename T> struct __declspec(dllexport) PartiallySpecializedClassTemplate<T*> { void f() {} };
+USEMEMFUNC(PartiallySpecializedClassTemplate<void*>, f);
+// M32-DAG: define linkonce_odr x86_thiscallcc void @"\01?f@?$PartiallySpecializedClassTemplate@PAX@@QAEXXZ"
+// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN33PartiallySpecializedClassTemplateIPvE1fEv
+
+template <typename T> struct ExplicitlySpecializedClassTemplate {};
+template <> struct __declspec(dllexport) ExplicitlySpecializedClassTemplate<void*> { void f() {} };
+USEMEMFUNC(ExplicitlySpecializedClassTemplate<void*>, f);
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?f@?$ExplicitlySpecializedClassTemplate@PAX@@QAEXXZ"
+// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN34ExplicitlySpecializedClassTemplateIPvE1fEv
+
+//===----------------------------------------------------------------------===//
+// Classes with template base classes
+//===----------------------------------------------------------------------===//
+
+template <typename T> struct ClassTemplate { void func() {} };
+template <typename T> struct __declspec(dllexport) ExportedClassTemplate { void func() {} };
+template <typename T> struct __declspec(dllimport) ImportedClassTemplate { void func() {} };
+
+template <typename T> struct ExplicitlySpecializedTemplate { void func() {} };
+template <> struct ExplicitlySpecializedTemplate<int> { void func() {} };
+template <typename T> struct ExplicitlyExportSpecializedTemplate { void func() {} };
+template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func() {} };
+template <typename T> struct ExplicitlyImportSpecializedTemplate { void func() {} };
+template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func() {} };
+
+template <typename T> struct ExplicitlyInstantiatedTemplate { void func() {} };
+template struct ExplicitlyInstantiatedTemplate<int>;
+template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func() {} };
+template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>;
+template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func() {} };
+template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate<int>;
+
+
+// MS: ClassTemplate<int> gets exported.
+struct __declspec(dllexport) DerivedFromTemplate : public ClassTemplate<int> {};
+USEMEMFUNC(ClassTemplate<int>, func)
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ClassTemplate@H@@QAEXXZ"
+// G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN13ClassTemplateIiE4funcEv
+
+// ExportedTemplate is explicitly exported.
+struct __declspec(dllexport) DerivedFromExportedTemplate : public ExportedClassTemplate<int> {};
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ExportedClassTemplate@H@@QAEXXZ"
+// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN21ExportedClassTemplateIiE4funcEv
+
+// ImportedClassTemplate is explicitly imported.
+struct __declspec(dllexport) DerivedFromImportedTemplate : public ImportedClassTemplate<int> {};
+USEMEMFUNC(ImportedClassTemplate<int>, func)
+// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$ImportedClassTemplate@H@@QAEXXZ"
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN21ImportedClassTemplateIiE4funcEv
+
+// Base class already instantiated without dll attribute.
+struct DerivedFromTemplateD : public ClassTemplate<double> {};
+struct __declspec(dllexport) DerivedFromTemplateD2 : public ClassTemplate<double> {};
+USEMEMFUNC(ClassTemplate<double>, func)
+// M32-DAG: define linkonce_odr x86_thiscallcc void @"\01?func@?$ClassTemplate@N@@QAEXXZ"
+// G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN13ClassTemplateIdE4funcEv
+
+// MS: Base class already instantiated with different dll attribute.
+struct __declspec(dllimport) DerivedFromTemplateB : public ClassTemplate<bool> {};
+struct __declspec(dllexport) DerivedFromTemplateB2 : public ClassTemplate<bool> {};
+USEMEMFUNC(ClassTemplate<bool>, func)
+// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$ClassTemplate@_N@@QAEXXZ"
+// G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN13ClassTemplateIbE4funcEv
+
+// Base class already specialized without dll attribute.
+struct __declspec(dllexport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate<int> {};
+USEMEMFUNC(ExplicitlySpecializedTemplate<int>, func)
+// M32-DAG: define linkonce_odr x86_thiscallcc void @"\01?func@?$ExplicitlySpecializedTemplate@H@@QAEXXZ"
+// G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN29ExplicitlySpecializedTemplateIiE4funcEv
+
+// Base class alredy specialized with export attribute.
+struct __declspec(dllexport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {};
+USEMEMFUNC(ExplicitlyExportSpecializedTemplate<int>, func)
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ExplicitlyExportSpecializedTemplate@H@@QAEXXZ"
+// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN35ExplicitlyExportSpecializedTemplateIiE4funcEv
+
+// Base class already specialized with import attribute.
+struct __declspec(dllexport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {};
+USEMEMFUNC(ExplicitlyImportSpecializedTemplate<int>, func)
+// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$ExplicitlyImportSpecializedTemplate@H@@QAEXXZ"
+// G32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @_ZN35ExplicitlyImportSpecializedTemplateIiE4funcEv
+
+// Base class already instantiated without dll attribute.
+struct __declspec(dllexport) DerivedFromExplicitlyInstantiatedTemplate : public ExplicitlyInstantiatedTemplate<int> {};
+USEMEMFUNC(ExplicitlyInstantiatedTemplate<int>, func)
+// M32-DAG: define weak_odr x86_thiscallcc void @"\01?func@?$ExplicitlyInstantiatedTemplate@H@@QAEXXZ"
+// G32-DAG: define weak_odr x86_thiscallcc void @_ZN30ExplicitlyInstantiatedTemplateIiE4funcEv
+
+// Base class already instantiated with export attribute.
+struct __declspec(dllexport) DerivedFromExplicitlyExportInstantiatedTemplate : public ExplicitlyExportInstantiatedTemplate<int> {};
+USEMEMFUNC(ExplicitlyExportInstantiatedTemplate<int>, func)
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ExplicitlyExportInstantiatedTemplate@H@@QAEXXZ"
+// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN36ExplicitlyExportInstantiatedTemplateIiE4funcEv
+
+// Base class already instantiated with import attribute.
+struct __declspec(dllexport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate<int> {};
+USEMEMFUNC(ExplicitlyImportInstantiatedTemplate<int>, func)
+// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$ExplicitlyImportInstantiatedTemplate@H@@QAEXXZ"
+// G32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @_ZN36ExplicitlyImportInstantiatedTemplateIiE4funcEv
+
+// MS: A dll attribute propagates through multiple levels of instantiation.
+template <typename T> struct TopClass { void func() {} };
+template <typename T> struct MiddleClass : public TopClass<T> { };
+struct __declspec(dllexport) BottomClass : public MiddleClass<int> { };
+USEMEMFUNC(TopClass<int>, func)
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$TopClass@H@@QAEXXZ"
+// G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN8TopClassIiE4funcEv
diff --git a/test/CodeGenCXX/dllimport-members.cpp b/test/CodeGenCXX/dllimport-members.cpp
new file mode 100644
index 0000000..6656b92
--- /dev/null
+++ b/test/CodeGenCXX/dllimport-members.cpp
@@ -0,0 +1,875 @@
+// RUN: %clang_cc1 -triple i686-windows-msvc -fms-compatibility   -emit-llvm -std=c++1y -O0 -o - %s -DMSABI | FileCheck --check-prefix=MSC --check-prefix=M32 %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -fms-compatibility -emit-llvm -std=c++1y -O0 -o - %s -DMSABI | FileCheck --check-prefix=MSC --check-prefix=M64 %s
+// RUN: %clang_cc1 -triple i686-windows-gnu                       -emit-llvm -std=c++1y -O0 -o - %s         | FileCheck --check-prefix=GNU --check-prefix=G32 %s
+// RUN: %clang_cc1 -triple x86_64-windows-gnu                     -emit-llvm -std=c++1y -O0 -o - %s         | FileCheck --check-prefix=GNU --check-prefix=G64 %s
+// RUN: %clang_cc1 -triple i686-windows-msvc -fms-compatibility   -emit-llvm -std=c++1y -O1 -o - %s -DMSABI | FileCheck --check-prefix=MO1 %s
+// RUN: %clang_cc1 -triple i686-windows-gnu                       -emit-llvm -std=c++1y -O1 -o - %s         | FileCheck --check-prefix=GO1 %s
+
+// Helper structs to make templates more expressive.
+struct ImplicitInst_Imported {};
+struct ExplicitDecl_Imported {};
+struct ExplicitInst_Imported {};
+struct ExplicitSpec_Imported {};
+struct ExplicitSpec_Def_Imported {};
+struct ExplicitSpec_InlineDef_Imported {};
+struct ExplicitSpec_NotImported {};
+
+#define JOIN2(x, y) x##y
+#define JOIN(x, y) JOIN2(x, y)
+#define UNIQ(name) JOIN(name, __LINE__)
+#define USE(func) void UNIQ(use)() { func(); }
+#define USEMV(cls, var) int UNIQ(use)() { return ref(cls::var); }
+#define USEMF(cls, fun) template<> void useMemFun<__LINE__, cls>() { cls().fun(); }
+#define USESPECIALS(cls) void UNIQ(use)() { useSpecials<cls>(); }
+
+template<typename T>
+T ref(T const& v) { return v; }
+
+template<int Line, typename T>
+void useMemFun();
+
+template<typename T>
+void useSpecials() {
+  T v; // Default constructor
+
+  T c1(static_cast<const T&>(v)); // Copy constructor
+  T c2 = static_cast<const T&>(v); // Copy constructor
+  T c3;
+  c3 = static_cast<const T&>(v); // Copy assignment
+
+  T m1(static_cast<T&&>(v)); // Move constructor
+  T m2 = static_cast<T&&>(v); // Move constructor
+  T m3;
+  m3 = static_cast<T&&>(v); // Move assignment
+}
+
+// Used to force non-trivial special members.
+struct ForceNonTrivial {
+  ForceNonTrivial();
+  ~ForceNonTrivial();
+  ForceNonTrivial(const ForceNonTrivial&);
+  ForceNonTrivial& operator=(const ForceNonTrivial&);
+  ForceNonTrivial(ForceNonTrivial&&);
+  ForceNonTrivial& operator=(ForceNonTrivial&&);
+};
+
+
+
+//===----------------------------------------------------------------------===//
+// Class members
+//===----------------------------------------------------------------------===//
+
+// Import individual members of a class.
+struct ImportMembers {
+  struct Nested;
+
+  // M32-DAG: define            x86_thiscallcc void @"\01?normalDef@ImportMembers@@QAEXXZ"(%struct.ImportMembers* %this)
+  // M64-DAG: define                           void @"\01?normalDef@ImportMembers@@QEAAXXZ"(%struct.ImportMembers* %this)
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?normalDecl@ImportMembers@@QAEXXZ"(%struct.ImportMembers*)
+  // M64-DAG: declare dllimport                void @"\01?normalDecl@ImportMembers@@QEAAXXZ"(%struct.ImportMembers*)
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?normalInclass@ImportMembers@@QAEXXZ"(%struct.ImportMembers*)
+  // M64-DAG: declare dllimport                void @"\01?normalInclass@ImportMembers@@QEAAXXZ"(%struct.ImportMembers*)
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?normalInlineDef@ImportMembers@@QAEXXZ"(%struct.ImportMembers*)
+  // M64-DAG: declare dllimport                void @"\01?normalInlineDef@ImportMembers@@QEAAXXZ"(%struct.ImportMembers*)
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?normalInlineDecl@ImportMembers@@QAEXXZ"(%struct.ImportMembers*)
+  // M64-DAG: declare dllimport                void @"\01?normalInlineDecl@ImportMembers@@QEAAXXZ"(%struct.ImportMembers*)
+  // G32-DAG: define            x86_thiscallcc void @_ZN13ImportMembers9normalDefEv(%struct.ImportMembers* %this)
+  // G64-DAG: define                           void @_ZN13ImportMembers9normalDefEv(%struct.ImportMembers* %this)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers10normalDeclEv(%struct.ImportMembers*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers10normalDeclEv(%struct.ImportMembers*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers13normalInclassEv(%struct.ImportMembers*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers13normalInclassEv(%struct.ImportMembers*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers15normalInlineDefEv(%struct.ImportMembers*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers15normalInlineDefEv(%struct.ImportMembers*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers16normalInlineDeclEv(%struct.ImportMembers*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers16normalInlineDeclEv(%struct.ImportMembers*)
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?normalInclass@ImportMembers@@QAEXXZ"(
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?normalInlineDef@ImportMembers@@QAEXXZ"(
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?normalInlineDecl@ImportMembers@@QAEXXZ"(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN13ImportMembers13normalInclassEv(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN13ImportMembers15normalInlineDefEv(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN13ImportMembers16normalInlineDeclEv(
+  __declspec(dllimport)                void normalDef(); // dllimport ignored
+  __declspec(dllimport)                void normalDecl();
+  __declspec(dllimport)                void normalInclass() {}
+  __declspec(dllimport)                void normalInlineDef();
+  __declspec(dllimport)         inline void normalInlineDecl();
+
+  // M32-DAG: define            x86_thiscallcc void @"\01?virtualDef@ImportMembers@@UAEXXZ"(%struct.ImportMembers* %this)
+  // M64-DAG: define                           void @"\01?virtualDef@ImportMembers@@UEAAXXZ"(%struct.ImportMembers* %this)
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?virtualDecl@ImportMembers@@UAEXXZ"(%struct.ImportMembers*)
+  // M64-DAG: declare dllimport                void @"\01?virtualDecl@ImportMembers@@UEAAXXZ"(%struct.ImportMembers*)
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?virtualInclass@ImportMembers@@UAEXXZ"(%struct.ImportMembers*)
+  // M64-DAG: declare dllimport                void @"\01?virtualInclass@ImportMembers@@UEAAXXZ"(%struct.ImportMembers*)
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?virtualInlineDef@ImportMembers@@UAEXXZ"(%struct.ImportMembers*)
+  // M64-DAG: declare dllimport                void @"\01?virtualInlineDef@ImportMembers@@UEAAXXZ"(%struct.ImportMembers*)
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?virtualInlineDecl@ImportMembers@@UAEXXZ"(%struct.ImportMembers*)
+  // M64-DAG: declare dllimport                void @"\01?virtualInlineDecl@ImportMembers@@UEAAXXZ"(%struct.ImportMembers*)
+  // G32-DAG: define            x86_thiscallcc void @_ZN13ImportMembers10virtualDefEv(%struct.ImportMembers* %this)
+  // G64-DAG: define                           void @_ZN13ImportMembers10virtualDefEv(%struct.ImportMembers* %this)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers11virtualDeclEv(%struct.ImportMembers*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers11virtualDeclEv(%struct.ImportMembers*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers14virtualInclassEv(%struct.ImportMembers*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers14virtualInclassEv(%struct.ImportMembers*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers16virtualInlineDefEv(%struct.ImportMembers*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers16virtualInlineDefEv(%struct.ImportMembers*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers17virtualInlineDeclEv(%struct.ImportMembers*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers17virtualInlineDeclEv(%struct.ImportMembers*)
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?virtualInclass@ImportMembers@@UAEXXZ"(
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?virtualInlineDef@ImportMembers@@UAEXXZ"(
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?virtualInlineDecl@ImportMembers@@UAEXXZ"(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN13ImportMembers14virtualInclassEv(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN13ImportMembers16virtualInlineDefEv(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN13ImportMembers17virtualInlineDeclEv(
+  __declspec(dllimport) virtual        void virtualDef(); // dllimport ignored
+  __declspec(dllimport) virtual        void virtualDecl();
+  __declspec(dllimport) virtual        void virtualInclass() {}
+  __declspec(dllimport) virtual        void virtualInlineDef();
+  __declspec(dllimport) virtual inline void virtualInlineDecl();
+
+  // MSC-DAG: define                           void @"\01?staticDef@ImportMembers@@SAXXZ"()
+  // MSC-DAG: declare dllimport                void @"\01?staticDecl@ImportMembers@@SAXXZ"()
+  // MSC-DAG: declare dllimport                void @"\01?staticInclass@ImportMembers@@SAXXZ"()
+  // MSC-DAG: declare dllimport                void @"\01?staticInlineDef@ImportMembers@@SAXXZ"()
+  // MSC-DAG: declare dllimport                void @"\01?staticInlineDecl@ImportMembers@@SAXXZ"()
+  // GNU-DAG: define                           void @_ZN13ImportMembers9staticDefEv()
+  // GNU-DAG: declare dllimport                void @_ZN13ImportMembers10staticDeclEv()
+  // GNU-DAG: declare dllimport                void @_ZN13ImportMembers13staticInclassEv()
+  // GNU-DAG: declare dllimport                void @_ZN13ImportMembers15staticInlineDefEv()
+  // GNU-DAG: declare dllimport                void @_ZN13ImportMembers16staticInlineDeclEv()
+  // MO1-DAG: define available_externally dllimport void @"\01?staticInclass@ImportMembers@@SAXXZ"()
+  // MO1-DAG: define available_externally dllimport void @"\01?staticInlineDef@ImportMembers@@SAXXZ"()
+  // MO1-DAG: define available_externally dllimport void @"\01?staticInlineDecl@ImportMembers@@SAXXZ"()
+  // GO1-DAG: define available_externally dllimport void @_ZN13ImportMembers13staticInclassEv()
+  // GO1-DAG: define available_externally dllimport void @_ZN13ImportMembers15staticInlineDefEv()
+  // GO1-DAG: define available_externally dllimport void @_ZN13ImportMembers16staticInlineDeclEv()
+  __declspec(dllimport) static         void staticDef(); // dllimport ignored
+  __declspec(dllimport) static         void staticDecl();
+  __declspec(dllimport) static         void staticInclass() {}
+  __declspec(dllimport) static         void staticInlineDef();
+  __declspec(dllimport) static  inline void staticInlineDecl();
+
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?protectedNormalDecl@ImportMembers@@IAEXXZ"(%struct.ImportMembers*)
+  // M64-DAG: declare dllimport                void @"\01?protectedNormalDecl@ImportMembers@@IEAAXXZ"(%struct.ImportMembers*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers19protectedNormalDeclEv(%struct.ImportMembers*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers19protectedNormalDeclEv(%struct.ImportMembers*)
+  // MSC-DAG: declare dllimport                void @"\01?protectedStaticDecl@ImportMembers@@KAXXZ"()
+  // GNU-DAG: declare dllimport                void @_ZN13ImportMembers19protectedStaticDeclEv()
+protected:
+  __declspec(dllimport)                void protectedNormalDecl();
+  __declspec(dllimport) static         void protectedStaticDecl();
+
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?privateNormalDecl@ImportMembers@@AAEXXZ"(%struct.ImportMembers*)
+  // M64-DAG: declare dllimport                void @"\01?privateNormalDecl@ImportMembers@@AEAAXXZ"(%struct.ImportMembers*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers17privateNormalDeclEv(%struct.ImportMembers*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers17privateNormalDeclEv(%struct.ImportMembers*)
+  // MSC-DAG: declare dllimport                void @"\01?privateStaticDecl@ImportMembers@@CAXXZ"()
+  // GNU-DAG: declare dllimport                void @_ZN13ImportMembers17privateStaticDeclEv()
+private:
+  __declspec(dllimport)                void privateNormalDecl();
+  __declspec(dllimport) static         void privateStaticDecl();
+
+  // M32-DAG: declare           x86_thiscallcc void @"\01?ignored@ImportMembers@@QAEXXZ"(%struct.ImportMembers*)
+  // M64-DAG: declare                          void @"\01?ignored@ImportMembers@@QEAAXXZ"(%struct.ImportMembers*)
+  // G32-DAG: declare           x86_thiscallcc void @_ZN13ImportMembers7ignoredEv(%struct.ImportMembers*)
+  // G64-DAG: declare                          void @_ZN13ImportMembers7ignoredEv(%struct.ImportMembers*)
+public:
+  void ignored();
+
+  // MSC-DAG: @"\01?StaticField@ImportMembers@@2HA"               = external dllimport global i32
+  // MSC-DAG: @"\01?StaticConstField@ImportMembers@@2HB"          = external dllimport constant i32
+  // MSC-DAG: @"\01?StaticConstFieldEqualInit@ImportMembers@@2HB" = available_externally dllimport constant i32 1, align 4
+  // MSC-DAG: @"\01?StaticConstFieldBraceInit@ImportMembers@@2HB" = available_externally dllimport constant i32 1, align 4
+  // MSC-DAG: @"\01?ConstexprField@ImportMembers@@2HB"            = available_externally dllimport constant i32 1, align 4
+  // GNU-DAG: @_ZN13ImportMembers11StaticFieldE                   = external dllimport global i32
+  // GNU-DAG: @_ZN13ImportMembers16StaticConstFieldE              = external dllimport constant i32
+  // GNU-DAG: @_ZN13ImportMembers25StaticConstFieldEqualInitE     = external dllimport constant i32
+  // GNU-DAG: @_ZN13ImportMembers25StaticConstFieldBraceInitE     = external dllimport constant i32
+  // GNU-DAG: @_ZN13ImportMembers14ConstexprFieldE                = external dllimport constant i32
+  __declspec(dllimport) static         int  StaticField;
+  __declspec(dllimport) static  const  int  StaticConstField;
+  __declspec(dllimport) static  const  int  StaticConstFieldEqualInit = 1;
+  __declspec(dllimport) static  const  int  StaticConstFieldBraceInit{1};
+  __declspec(dllimport) constexpr static int ConstexprField = 1;
+
+  template<int Line, typename T> friend void useMemFun();
+};
+
+       void ImportMembers::normalDef() {} // dllimport ignored
+inline void ImportMembers::normalInlineDef() {}
+       void ImportMembers::normalInlineDecl() {}
+       void ImportMembers::virtualDef() {} // dllimport ignored
+inline void ImportMembers::virtualInlineDef() {}
+       void ImportMembers::virtualInlineDecl() {}
+       void ImportMembers::staticDef() {} // dllimport ignored
+inline void ImportMembers::staticInlineDef() {}
+       void ImportMembers::staticInlineDecl() {}
+
+USEMF(ImportMembers, normalDef)
+USEMF(ImportMembers, normalDecl)
+USEMF(ImportMembers, normalInclass)
+USEMF(ImportMembers, normalInlineDef)
+USEMF(ImportMembers, normalInlineDecl)
+USEMF(ImportMembers, virtualDef)
+USEMF(ImportMembers, virtualDecl)
+USEMF(ImportMembers, virtualInclass)
+USEMF(ImportMembers, virtualInlineDef)
+USEMF(ImportMembers, virtualInlineDecl)
+USEMF(ImportMembers, staticDef)
+USEMF(ImportMembers, staticDecl)
+USEMF(ImportMembers, staticInclass)
+USEMF(ImportMembers, staticInlineDef)
+USEMF(ImportMembers, staticInlineDecl)
+USEMF(ImportMembers, protectedNormalDecl)
+USEMF(ImportMembers, protectedStaticDecl)
+USEMF(ImportMembers, privateNormalDecl)
+USEMF(ImportMembers, privateStaticDecl)
+USEMF(ImportMembers, ignored)
+
+USEMV(ImportMembers, StaticField)
+USEMV(ImportMembers, StaticConstField)
+USEMV(ImportMembers, StaticConstFieldEqualInit)
+USEMV(ImportMembers, StaticConstFieldBraceInit)
+USEMV(ImportMembers, ConstexprField)
+
+
+// Import individual members of a nested class.
+struct ImportMembers::Nested {
+  // M32-DAG: define            x86_thiscallcc void @"\01?normalDef@Nested@ImportMembers@@QAEXXZ"(%"struct.ImportMembers::Nested"* %this)
+  // M64-DAG: define                           void @"\01?normalDef@Nested@ImportMembers@@QEAAXXZ"(%"struct.ImportMembers::Nested"* %this)
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?normalDecl@Nested@ImportMembers@@QAEXXZ"(%"struct.ImportMembers::Nested"*)
+  // M64-DAG: declare dllimport                void @"\01?normalDecl@Nested@ImportMembers@@QEAAXXZ"(%"struct.ImportMembers::Nested"*)
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?normalInclass@Nested@ImportMembers@@QAEXXZ"(%"struct.ImportMembers::Nested"*)
+  // M64-DAG: declare dllimport                void @"\01?normalInclass@Nested@ImportMembers@@QEAAXXZ"(%"struct.ImportMembers::Nested"*)
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?normalInlineDef@Nested@ImportMembers@@QAEXXZ"(%"struct.ImportMembers::Nested"*)
+  // M64-DAG: declare dllimport                void @"\01?normalInlineDef@Nested@ImportMembers@@QEAAXXZ"(%"struct.ImportMembers::Nested"*)
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?normalInlineDecl@Nested@ImportMembers@@QAEXXZ"(%"struct.ImportMembers::Nested"*)
+  // M64-DAG: declare dllimport                void @"\01?normalInlineDecl@Nested@ImportMembers@@QEAAXXZ"(%"struct.ImportMembers::Nested"*)
+  // G32-DAG: define            x86_thiscallcc void @_ZN13ImportMembers6Nested9normalDefEv(%"struct.ImportMembers::Nested"* %this)
+  // G64-DAG: define                           void @_ZN13ImportMembers6Nested9normalDefEv(%"struct.ImportMembers::Nested"* %this)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested10normalDeclEv(%"struct.ImportMembers::Nested"*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers6Nested10normalDeclEv(%"struct.ImportMembers::Nested"*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested13normalInclassEv(%"struct.ImportMembers::Nested"*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers6Nested13normalInclassEv(%"struct.ImportMembers::Nested"*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested15normalInlineDefEv(%"struct.ImportMembers::Nested"*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers6Nested15normalInlineDefEv(%"struct.ImportMembers::Nested"*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested16normalInlineDeclEv(%"struct.ImportMembers::Nested"*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers6Nested16normalInlineDeclEv(%"struct.ImportMembers::Nested"*)
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?normalInclass@Nested@ImportMembers@@QAEXXZ"(
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?normalInlineDef@Nested@ImportMembers@@QAEXXZ"(
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?normalInlineDecl@Nested@ImportMembers@@QAEXXZ"(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested13normalInclassEv(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested15normalInlineDefEv(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested16normalInlineDeclEv(
+  __declspec(dllimport)                void normalDef(); // dllimport ignored
+  __declspec(dllimport)                void normalDecl();
+  __declspec(dllimport)                void normalInclass() {}
+  __declspec(dllimport)                void normalInlineDef();
+  __declspec(dllimport)         inline void normalInlineDecl();
+
+  // M32-DAG: define            x86_thiscallcc void @"\01?virtualDef@Nested@ImportMembers@@UAEXXZ"(%"struct.ImportMembers::Nested"* %this)
+  // M64-DAG: define                           void @"\01?virtualDef@Nested@ImportMembers@@UEAAXXZ"(%"struct.ImportMembers::Nested"* %this)
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?virtualDecl@Nested@ImportMembers@@UAEXXZ"(%"struct.ImportMembers::Nested"*)
+  // M64-DAG: declare dllimport                void @"\01?virtualDecl@Nested@ImportMembers@@UEAAXXZ"(%"struct.ImportMembers::Nested"*)
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?virtualInclass@Nested@ImportMembers@@UAEXXZ"(%"struct.ImportMembers::Nested"*)
+  // M64-DAG: declare dllimport                void @"\01?virtualInclass@Nested@ImportMembers@@UEAAXXZ"(%"struct.ImportMembers::Nested"*)
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?virtualInlineDef@Nested@ImportMembers@@UAEXXZ"(%"struct.ImportMembers::Nested"*)
+  // M64-DAG: declare dllimport                void @"\01?virtualInlineDef@Nested@ImportMembers@@UEAAXXZ"(%"struct.ImportMembers::Nested"*)
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?virtualInlineDecl@Nested@ImportMembers@@UAEXXZ"(%"struct.ImportMembers::Nested"*)
+  // M64-DAG: declare dllimport                void @"\01?virtualInlineDecl@Nested@ImportMembers@@UEAAXXZ"(%"struct.ImportMembers::Nested"*)
+  // G32-DAG: define            x86_thiscallcc void @_ZN13ImportMembers6Nested10virtualDefEv(%"struct.ImportMembers::Nested"* %this)
+  // G64-DAG: define                           void @_ZN13ImportMembers6Nested10virtualDefEv(%"struct.ImportMembers::Nested"* %this)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested11virtualDeclEv(%"struct.ImportMembers::Nested"*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers6Nested11virtualDeclEv(%"struct.ImportMembers::Nested"*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested14virtualInclassEv(%"struct.ImportMembers::Nested"*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers6Nested14virtualInclassEv(%"struct.ImportMembers::Nested"*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested16virtualInlineDefEv(%"struct.ImportMembers::Nested"*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers6Nested16virtualInlineDefEv(%"struct.ImportMembers::Nested"*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested17virtualInlineDeclEv(%"struct.ImportMembers::Nested"*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers6Nested17virtualInlineDeclEv(%"struct.ImportMembers::Nested"*)
+
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?virtualInclass@Nested@ImportMembers@@UAEXXZ"(
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?virtualInlineDef@Nested@ImportMembers@@UAEXXZ"(
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?virtualInlineDecl@Nested@ImportMembers@@UAEXXZ"(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested14virtualInclassEv(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested16virtualInlineDefEv(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested17virtualInlineDeclEv(
+  __declspec(dllimport) virtual        void virtualDef(); // dllimport ignored
+  __declspec(dllimport) virtual        void virtualDecl();
+  __declspec(dllimport) virtual        void virtualInclass() {}
+  __declspec(dllimport) virtual        void virtualInlineDef();
+  __declspec(dllimport) virtual inline void virtualInlineDecl();
+
+  // MSC-DAG: define                           void @"\01?staticDef@Nested@ImportMembers@@SAXXZ"()
+  // MSC-DAG: declare dllimport                void @"\01?staticDecl@Nested@ImportMembers@@SAXXZ"()
+  // MSC-DAG: declare dllimport                void @"\01?staticInclass@Nested@ImportMembers@@SAXXZ"()
+  // MSC-DAG: declare dllimport                void @"\01?staticInlineDef@Nested@ImportMembers@@SAXXZ"()
+  // MSC-DAG: declare dllimport                void @"\01?staticInlineDecl@Nested@ImportMembers@@SAXXZ"()
+  // GNU-DAG: define                           void @_ZN13ImportMembers6Nested9staticDefEv()
+  // GNU-DAG: declare dllimport                void @_ZN13ImportMembers6Nested10staticDeclEv()
+  // GNU-DAG: declare dllimport                void @_ZN13ImportMembers6Nested13staticInclassEv()
+  // GNU-DAG: declare dllimport                void @_ZN13ImportMembers6Nested15staticInlineDefEv()
+  // GNU-DAG: declare dllimport                void @_ZN13ImportMembers6Nested16staticInlineDeclEv()
+  // MO1-DAG: define available_externally dllimport void @"\01?staticInclass@Nested@ImportMembers@@SAXXZ"()
+  // MO1-DAG: define available_externally dllimport void @"\01?staticInlineDef@Nested@ImportMembers@@SAXXZ"()
+  // MO1-DAG: define available_externally dllimport void @"\01?staticInlineDecl@Nested@ImportMembers@@SAXXZ"()
+  // GO1-DAG: define available_externally dllimport void @_ZN13ImportMembers6Nested13staticInclassEv()
+  // GO1-DAG: define available_externally dllimport void @_ZN13ImportMembers6Nested15staticInlineDefEv()
+  // GO1-DAG: define available_externally dllimport void @_ZN13ImportMembers6Nested16staticInlineDeclEv()
+  __declspec(dllimport) static         void staticDef(); // dllimport ignored
+  __declspec(dllimport) static         void staticDecl();
+  __declspec(dllimport) static         void staticInclass() {}
+  __declspec(dllimport) static         void staticInlineDef();
+  __declspec(dllimport) static  inline void staticInlineDecl();
+
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?protectedNormalDecl@Nested@ImportMembers@@IAEXXZ"(%"struct.ImportMembers::Nested"*)
+  // M64-DAG: declare dllimport                void @"\01?protectedNormalDecl@Nested@ImportMembers@@IEAAXXZ"(%"struct.ImportMembers::Nested"*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested19protectedNormalDeclEv(%"struct.ImportMembers::Nested"*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers6Nested19protectedNormalDeclEv(%"struct.ImportMembers::Nested"*)
+  // MSC-DAG: declare dllimport                void @"\01?protectedStaticDecl@Nested@ImportMembers@@KAXXZ"()
+  // GNU-DAG: declare dllimport                void @_ZN13ImportMembers6Nested19protectedStaticDeclEv()
+protected:
+  __declspec(dllimport)                void protectedNormalDecl();
+  __declspec(dllimport) static         void protectedStaticDecl();
+
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01?privateNormalDecl@Nested@ImportMembers@@AAEXXZ"(%"struct.ImportMembers::Nested"*)
+  // M64-DAG: declare dllimport                void @"\01?privateNormalDecl@Nested@ImportMembers@@AEAAXXZ"(%"struct.ImportMembers::Nested"*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN13ImportMembers6Nested17privateNormalDeclEv(%"struct.ImportMembers::Nested"*)
+  // G64-DAG: declare dllimport                void @_ZN13ImportMembers6Nested17privateNormalDeclEv(%"struct.ImportMembers::Nested"*)
+  // MSC-DAG: declare dllimport                void @"\01?privateStaticDecl@Nested@ImportMembers@@CAXXZ"()
+  // GNU-DAG: declare dllimport                void @_ZN13ImportMembers6Nested17privateStaticDeclEv()
+private:
+  __declspec(dllimport)                void privateNormalDecl();
+  __declspec(dllimport) static         void privateStaticDecl();
+
+  // M32-DAG: declare           x86_thiscallcc void @"\01?ignored@Nested@ImportMembers@@QAEXXZ"(%"struct.ImportMembers::Nested"*)
+  // M64-DAG: declare                          void @"\01?ignored@Nested@ImportMembers@@QEAAXXZ"(%"struct.ImportMembers::Nested"*)
+  // G32-DAG: declare           x86_thiscallcc void @_ZN13ImportMembers6Nested7ignoredEv(%"struct.ImportMembers::Nested"*)
+  // G64-DAG: declare                          void @_ZN13ImportMembers6Nested7ignoredEv(%"struct.ImportMembers::Nested"*)
+public:
+  void ignored();
+
+  // MSC-DAG: @"\01?StaticField@Nested@ImportMembers@@2HA"               = external dllimport global i32
+  // MSC-DAG: @"\01?StaticConstField@Nested@ImportMembers@@2HB"          = external dllimport constant i32
+  // MSC-DAG: @"\01?StaticConstFieldEqualInit@Nested@ImportMembers@@2HB" = available_externally dllimport constant i32 1, align 4
+  // MSC-DAG: @"\01?StaticConstFieldBraceInit@Nested@ImportMembers@@2HB" = available_externally dllimport constant i32 1, align 4
+  // MSC-DAG: @"\01?ConstexprField@Nested@ImportMembers@@2HB"            = available_externally dllimport constant i32 1, align 4
+  // GNU-DAG: @_ZN13ImportMembers6Nested11StaticFieldE                   = external dllimport global i32
+  // GNU-DAG: @_ZN13ImportMembers6Nested16StaticConstFieldE              = external dllimport constant i32
+  // GNU-DAG: @_ZN13ImportMembers6Nested25StaticConstFieldEqualInitE     = external dllimport constant i32
+  // GNU-DAG: @_ZN13ImportMembers6Nested25StaticConstFieldBraceInitE     = external dllimport constant i32
+  // GNU-DAG: @_ZN13ImportMembers6Nested14ConstexprFieldE                = external dllimport constant i32
+  __declspec(dllimport) static         int  StaticField;
+  __declspec(dllimport) static  const  int  StaticConstField;
+  __declspec(dllimport) static  const  int  StaticConstFieldEqualInit = 1;
+  __declspec(dllimport) static  const  int  StaticConstFieldBraceInit{1};
+  __declspec(dllimport) constexpr static int ConstexprField = 1;
+
+  template<int Line, typename T> friend void useMemFun();
+};
+
+       void ImportMembers::Nested::normalDef() {} // dllimport ignored
+inline void ImportMembers::Nested::normalInlineDef() {}
+       void ImportMembers::Nested::normalInlineDecl() {}
+       void ImportMembers::Nested::virtualDef() {} // dllimport ignored
+inline void ImportMembers::Nested::virtualInlineDef() {}
+       void ImportMembers::Nested::virtualInlineDecl() {}
+       void ImportMembers::Nested::staticDef() {} // dllimport ignored
+inline void ImportMembers::Nested::staticInlineDef() {}
+       void ImportMembers::Nested::staticInlineDecl() {}
+
+USEMF(ImportMembers::Nested, normalDef)
+USEMF(ImportMembers::Nested, normalDecl)
+USEMF(ImportMembers::Nested, normalInclass)
+USEMF(ImportMembers::Nested, normalInlineDef)
+USEMF(ImportMembers::Nested, normalInlineDecl)
+USEMF(ImportMembers::Nested, virtualDef)
+USEMF(ImportMembers::Nested, virtualDecl)
+USEMF(ImportMembers::Nested, virtualInclass)
+USEMF(ImportMembers::Nested, virtualInlineDef)
+USEMF(ImportMembers::Nested, virtualInlineDecl)
+USEMF(ImportMembers::Nested, staticDef)
+USEMF(ImportMembers::Nested, staticDecl)
+USEMF(ImportMembers::Nested, staticInclass)
+USEMF(ImportMembers::Nested, staticInlineDef)
+USEMF(ImportMembers::Nested, staticInlineDecl)
+USEMF(ImportMembers::Nested, protectedNormalDecl)
+USEMF(ImportMembers::Nested, protectedStaticDecl)
+USEMF(ImportMembers::Nested, privateNormalDecl)
+USEMF(ImportMembers::Nested, privateStaticDecl)
+USEMF(ImportMembers::Nested, ignored)
+
+USEMV(ImportMembers::Nested, StaticField)
+USEMV(ImportMembers::Nested, StaticConstField)
+USEMV(ImportMembers::Nested, StaticConstFieldEqualInit)
+USEMV(ImportMembers::Nested, StaticConstFieldBraceInit)
+USEMV(ImportMembers::Nested, ConstexprField)
+
+
+// Import special member functions.
+struct ImportSpecials {
+  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportSpecials* @"\01??0ImportSpecials@@QAE@XZ"(%struct.ImportSpecials* returned)
+  // M64-DAG: declare dllimport                %struct.ImportSpecials* @"\01??0ImportSpecials@@QEAA@XZ"(%struct.ImportSpecials* returned)
+  // G32-DAG: declare dllimport x86_thiscallcc void                    @_ZN14ImportSpecialsC1Ev(%struct.ImportSpecials*)
+  // G64-DAG: declare dllimport                void                    @_ZN14ImportSpecialsC1Ev(%struct.ImportSpecials*)
+  __declspec(dllimport) ImportSpecials();
+
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01??1ImportSpecials@@QAE@XZ"(%struct.ImportSpecials*)
+  // M64-DAG: declare dllimport                void @"\01??1ImportSpecials@@QEAA@XZ"(%struct.ImportSpecials*)
+  // G32-DAG: declare dllimport x86_thiscallcc void                    @_ZN14ImportSpecialsD1Ev(%struct.ImportSpecials*)
+  // G64-DAG: declare dllimport                void                    @_ZN14ImportSpecialsD1Ev(%struct.ImportSpecials*)
+  __declspec(dllimport) ~ImportSpecials();
+
+  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportSpecials* @"\01??0ImportSpecials@@QAE@ABU0@@Z"(%struct.ImportSpecials* returned, %struct.ImportSpecials* dereferenceable({{[0-9]+}}))
+  // M64-DAG: declare dllimport                %struct.ImportSpecials* @"\01??0ImportSpecials@@QEAA@AEBU0@@Z"(%struct.ImportSpecials* returned, %struct.ImportSpecials* dereferenceable({{[0-9]+}}))
+  // G32-DAG: declare dllimport x86_thiscallcc void                    @_ZN14ImportSpecialsC1ERKS_(%struct.ImportSpecials*, %struct.ImportSpecials* dereferenceable({{[0-9]+}}))
+  // G64-DAG: declare dllimport                void                    @_ZN14ImportSpecialsC1ERKS_(%struct.ImportSpecials*, %struct.ImportSpecials* dereferenceable({{[0-9]+}}))
+  __declspec(dllimport) ImportSpecials(const ImportSpecials&);
+
+  // M32-DAG: declare dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportSpecials* @"\01??4ImportSpecials@@QAEAAU0@ABU0@@Z"(%struct.ImportSpecials*, %struct.ImportSpecials* dereferenceable({{[0-9]+}}))
+  // M64-DAG: declare dllimport                dereferenceable({{[0-9]+}}) %struct.ImportSpecials* @"\01??4ImportSpecials@@QEAAAEAU0@AEBU0@@Z"(%struct.ImportSpecials*, %struct.ImportSpecials* dereferenceable({{[0-9]+}}))
+  // G32-DAG: declare dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportSpecials* @_ZN14ImportSpecialsaSERKS_(%struct.ImportSpecials*, %struct.ImportSpecials* dereferenceable({{[0-9]+}}))
+  // G64-DAG: declare dllimport                dereferenceable({{[0-9]+}}) %struct.ImportSpecials* @_ZN14ImportSpecialsaSERKS_(%struct.ImportSpecials*, %struct.ImportSpecials* dereferenceable({{[0-9]+}}))
+  __declspec(dllimport) ImportSpecials& operator=(const ImportSpecials&);
+
+  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportSpecials* @"\01??0ImportSpecials@@QAE@$$QAU0@@Z"(%struct.ImportSpecials* returned, %struct.ImportSpecials* dereferenceable({{[0-9]+}}))
+  // M64-DAG: declare dllimport                %struct.ImportSpecials* @"\01??0ImportSpecials@@QEAA@$$QEAU0@@Z"(%struct.ImportSpecials* returned, %struct.ImportSpecials* dereferenceable({{[0-9]+}}))
+  // G32-DAG: declare dllimport x86_thiscallcc void                    @_ZN14ImportSpecialsC1EOS_(%struct.ImportSpecials*, %struct.ImportSpecials* dereferenceable({{[0-9]+}}))
+  // G64-DAG: declare dllimport                void                    @_ZN14ImportSpecialsC1EOS_(%struct.ImportSpecials*, %struct.ImportSpecials* dereferenceable({{[0-9]+}}))
+  __declspec(dllimport) ImportSpecials(ImportSpecials&&);
+
+  // M32-DAG: declare dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportSpecials* @"\01??4ImportSpecials@@QAEAAU0@$$QAU0@@Z"(%struct.ImportSpecials*, %struct.ImportSpecials* dereferenceable({{[0-9]+}}))
+  // M64-DAG: declare dllimport                dereferenceable({{[0-9]+}}) %struct.ImportSpecials* @"\01??4ImportSpecials@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ImportSpecials*, %struct.ImportSpecials* dereferenceable({{[0-9]+}}))
+  // G32-DAG: declare dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportSpecials* @_ZN14ImportSpecialsaSEOS_(%struct.ImportSpecials*, %struct.ImportSpecials* dereferenceable({{[0-9]+}}))
+  // G64-DAG: declare dllimport                dereferenceable({{[0-9]+}}) %struct.ImportSpecials* @_ZN14ImportSpecialsaSEOS_(%struct.ImportSpecials*, %struct.ImportSpecials* dereferenceable({{[0-9]+}}))
+  __declspec(dllimport) ImportSpecials& operator=(ImportSpecials&&);
+};
+USESPECIALS(ImportSpecials)
+
+
+// Export inline special member functions.
+struct ImportInlineSpecials {
+  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"\01??0ImportInlineSpecials@@QAE@XZ"(%struct.ImportInlineSpecials* returned)
+  // M64-DAG: declare dllimport                %struct.ImportInlineSpecials* @"\01??0ImportInlineSpecials@@QEAA@XZ"(%struct.ImportInlineSpecials* returned)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN20ImportInlineSpecialsC1Ev(%struct.ImportInlineSpecials*)
+  // G64-DAG: declare dllimport                void @_ZN20ImportInlineSpecialsC1Ev(%struct.ImportInlineSpecials*)
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"\01??0ImportInlineSpecials@@QAE@XZ"(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN20ImportInlineSpecialsC1Ev(
+  __declspec(dllimport) ImportInlineSpecials() {}
+
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01??1ImportInlineSpecials@@QAE@XZ"(%struct.ImportInlineSpecials*)
+  // M64-DAG: declare dllimport                void @"\01??1ImportInlineSpecials@@QEAA@XZ"(%struct.ImportInlineSpecials*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN20ImportInlineSpecialsD1Ev(%struct.ImportInlineSpecials*)
+  // G64-DAG: declare dllimport                void @_ZN20ImportInlineSpecialsD1Ev(%struct.ImportInlineSpecials*)
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01??1ImportInlineSpecials@@QAE@XZ"(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN20ImportInlineSpecialsD1Ev(
+  __declspec(dllimport) ~ImportInlineSpecials() {}
+
+  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"\01??0ImportInlineSpecials@@QAE@ABU0@@Z"(%struct.ImportInlineSpecials* returned, %struct.ImportInlineSpecials* dereferenceable({{[0-9]+}}))
+  // M64-DAG: declare dllimport                %struct.ImportInlineSpecials* @"\01??0ImportInlineSpecials@@QEAA@AEBU0@@Z"(%struct.ImportInlineSpecials* returned, %struct.ImportInlineSpecials* dereferenceable({{[0-9]+}}))
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN20ImportInlineSpecialsC1ERKS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials* dereferenceable({{[0-9]+}}))
+  // G64-DAG: declare dllimport                void @_ZN20ImportInlineSpecialsC1ERKS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials* dereferenceable({{[0-9]+}}))
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"\01??0ImportInlineSpecials@@QAE@ABU0@@Z"(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN20ImportInlineSpecialsC1ERKS_(
+  __declspec(dllimport) inline ImportInlineSpecials(const ImportInlineSpecials&);
+
+  // M32-DAG: declare dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportInlineSpecials* @"\01??4ImportInlineSpecials@@QAEAAU0@ABU0@@Z"(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials* dereferenceable({{[0-9]+}}))
+  // M64-DAG: declare dllimport                dereferenceable({{[0-9]+}}) %struct.ImportInlineSpecials* @"\01??4ImportInlineSpecials@@QEAAAEAU0@AEBU0@@Z"(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials* dereferenceable({{[0-9]+}}))
+  // G32-DAG: declare dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportInlineSpecials* @_ZN20ImportInlineSpecialsaSERKS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials* dereferenceable({{[0-9]+}}))
+  // G64-DAG: declare dllimport                dereferenceable({{[0-9]+}}) %struct.ImportInlineSpecials* @_ZN20ImportInlineSpecialsaSERKS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials* dereferenceable({{[0-9]+}}))
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportInlineSpecials* @"\01??4ImportInlineSpecials@@QAEAAU0@ABU0@@Z"(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportInlineSpecials* @_ZN20ImportInlineSpecialsaSERKS_(
+  __declspec(dllimport) ImportInlineSpecials& operator=(const ImportInlineSpecials&);
+
+  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"\01??0ImportInlineSpecials@@QAE@$$QAU0@@Z"(%struct.ImportInlineSpecials* returned, %struct.ImportInlineSpecials* dereferenceable({{[0-9]+}}))
+  // M64-DAG: declare dllimport                %struct.ImportInlineSpecials* @"\01??0ImportInlineSpecials@@QEAA@$$QEAU0@@Z"(%struct.ImportInlineSpecials* returned, %struct.ImportInlineSpecials* dereferenceable({{[0-9]+}}))
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN20ImportInlineSpecialsC1EOS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials* dereferenceable({{[0-9]+}}))
+  // G64-DAG: declare dllimport                void @_ZN20ImportInlineSpecialsC1EOS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials* dereferenceable({{[0-9]+}}))
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportInlineSpecials* @"\01??0ImportInlineSpecials@@QAE@$$QAU0@@Z"(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN20ImportInlineSpecialsC1EOS_(
+  __declspec(dllimport) ImportInlineSpecials(ImportInlineSpecials&&) {}
+
+  // M32-DAG: declare dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportInlineSpecials* @"\01??4ImportInlineSpecials@@QAEAAU0@$$QAU0@@Z"(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials* dereferenceable({{[0-9]+}}))
+  // M64-DAG: declare dllimport                dereferenceable({{[0-9]+}}) %struct.ImportInlineSpecials* @"\01??4ImportInlineSpecials@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials* dereferenceable({{[0-9]+}}))
+  // G32-DAG: declare dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportInlineSpecials* @_ZN20ImportInlineSpecialsaSEOS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials* dereferenceable({{[0-9]+}}))
+  // G64-DAG: declare dllimport                dereferenceable({{[0-9]+}}) %struct.ImportInlineSpecials* @_ZN20ImportInlineSpecialsaSEOS_(%struct.ImportInlineSpecials*, %struct.ImportInlineSpecials* dereferenceable({{[0-9]+}}))
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportInlineSpecials* @"\01??4ImportInlineSpecials@@QAEAAU0@$$QAU0@@Z"(
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportInlineSpecials* @_ZN20ImportInlineSpecialsaSEOS_(
+  __declspec(dllimport) ImportInlineSpecials& operator=(ImportInlineSpecials&&) { return *this; }
+};
+ImportInlineSpecials::ImportInlineSpecials(const ImportInlineSpecials&) {}
+inline ImportInlineSpecials& ImportInlineSpecials::operator=(const ImportInlineSpecials&) { return *this; }
+USESPECIALS(ImportInlineSpecials)
+
+
+// Import defaulted member functions.
+struct ImportDefaulted {
+  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QAE@XZ"(%struct.ImportDefaulted* returned)
+  // M64-DAG: declare dllimport                %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QEAA@XZ"(%struct.ImportDefaulted* returned)
+  // G32-DAG: declare dllimport x86_thiscallcc void                     @_ZN15ImportDefaultedC1Ev(%struct.ImportDefaulted*)
+  // G64-DAG: declare dllimport                void                     @_ZN15ImportDefaultedC1Ev(%struct.ImportDefaulted*)
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QAE@XZ"(%struct.ImportDefaulted* returned %this)
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN15ImportDefaultedC1Ev(%struct.ImportDefaulted* %this)
+  __declspec(dllimport) ImportDefaulted() = default;
+
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01??1ImportDefaulted@@QAE@XZ"(%struct.ImportDefaulted*)
+  // M64-DAG: declare dllimport                void @"\01??1ImportDefaulted@@QEAA@XZ"(%struct.ImportDefaulted*)
+  // G32-DAG: declare dllimport x86_thiscallcc void @_ZN15ImportDefaultedD1Ev(%struct.ImportDefaulted*)
+  // G64-DAG: declare dllimport                void @_ZN15ImportDefaultedD1Ev(%struct.ImportDefaulted*)
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01??1ImportDefaulted@@QAE@XZ"(%struct.ImportDefaulted* %this)
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN15ImportDefaultedD1Ev(%struct.ImportDefaulted* %this)
+  __declspec(dllimport) ~ImportDefaulted() = default;
+
+  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QAE@ABU0@@Z"(%struct.ImportDefaulted* returned, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+  // M64-DAG: declare dllimport                %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QEAA@AEBU0@@Z"(%struct.ImportDefaulted* returned, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+  // G32-DAG: declare dllimport x86_thiscallcc void                     @_ZN15ImportDefaultedC1ERKS_(%struct.ImportDefaulted*, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+  // G64-DAG: declare dllimport                void                     @_ZN15ImportDefaultedC1ERKS_(%struct.ImportDefaulted*, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QAE@ABU0@@Z"(%struct.ImportDefaulted* returned %this, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN15ImportDefaultedC1ERKS_(%struct.ImportDefaulted* %this, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+  __declspec(dllimport) ImportDefaulted(const ImportDefaulted&) = default;
+
+  // M32-DAG: declare dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportDefaulted* @"\01??4ImportDefaulted@@QAEAAU0@ABU0@@Z"(%struct.ImportDefaulted*, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+  // M64-DAG: declare dllimport                dereferenceable({{[0-9]+}}) %struct.ImportDefaulted* @"\01??4ImportDefaulted@@QEAAAEAU0@AEBU0@@Z"(%struct.ImportDefaulted*, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+  // G32-DAG: declare dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportDefaulted* @_ZN15ImportDefaultedaSERKS_(%struct.ImportDefaulted*, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+  // G64-DAG: declare dllimport                dereferenceable({{[0-9]+}}) %struct.ImportDefaulted* @_ZN15ImportDefaultedaSERKS_(%struct.ImportDefaulted*, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportDefaulted* @"\01??4ImportDefaulted@@QAEAAU0@ABU0@@Z"(%struct.ImportDefaulted* %this, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportDefaulted* @_ZN15ImportDefaultedaSERKS_(%struct.ImportDefaulted* %this, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+  __declspec(dllimport) ImportDefaulted& operator=(const ImportDefaulted&) = default;
+
+  // M32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QAE@$$QAU0@@Z"(%struct.ImportDefaulted* returned, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+  // M64-DAG: declare dllimport                %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QEAA@$$QEAU0@@Z"(%struct.ImportDefaulted* returned, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+  // G32-DAG: declare dllimport x86_thiscallcc void                     @_ZN15ImportDefaultedC1EOS_(%struct.ImportDefaulted*, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+  // G64-DAG: declare dllimport                void                     @_ZN15ImportDefaultedC1EOS_(%struct.ImportDefaulted*, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc %struct.ImportDefaulted* @"\01??0ImportDefaulted@@QAE@$$QAU0@@Z"(%struct.ImportDefaulted* returned %this, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN15ImportDefaultedC1EOS_(%struct.ImportDefaulted* %this, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+  __declspec(dllimport) ImportDefaulted(ImportDefaulted&&) = default;
+
+  // M32-DAG: declare dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportDefaulted* @"\01??4ImportDefaulted@@QAEAAU0@$$QAU0@@Z"(%struct.ImportDefaulted*, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+  // M64-DAG: declare dllimport                dereferenceable({{[0-9]+}}) %struct.ImportDefaulted* @"\01??4ImportDefaulted@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ImportDefaulted*, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+  // G32-DAG: declare dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportDefaulted* @_ZN15ImportDefaultedaSEOS_(%struct.ImportDefaulted*, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+  // G64-DAG: declare dllimport                dereferenceable({{[0-9]+}}) %struct.ImportDefaulted* @_ZN15ImportDefaultedaSEOS_(%struct.ImportDefaulted*, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportDefaulted* @"\01??4ImportDefaulted@@QAEAAU0@$$QAU0@@Z"(%struct.ImportDefaulted* %this, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+  // GO1-DAG: define available_externally dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportDefaulted* @_ZN15ImportDefaultedaSEOS_(%struct.ImportDefaulted* %this, %struct.ImportDefaulted* dereferenceable({{[0-9]+}}))
+  __declspec(dllimport) ImportDefaulted& operator=(ImportDefaulted&&) = default;
+
+  ForceNonTrivial v; // ensure special members are non-trivial
+};
+USESPECIALS(ImportDefaulted)
+
+
+// Import defaulted member function definitions.
+struct ImportDefaultedDefs {
+  __declspec(dllimport) inline ImportDefaultedDefs();
+  __declspec(dllimport) inline ~ImportDefaultedDefs();
+
+  __declspec(dllimport) ImportDefaultedDefs(const ImportDefaultedDefs&);
+  __declspec(dllimport) ImportDefaultedDefs& operator=(const ImportDefaultedDefs&);
+
+  __declspec(dllimport) ImportDefaultedDefs(ImportDefaultedDefs&&);
+  __declspec(dllimport) ImportDefaultedDefs& operator=(ImportDefaultedDefs&&);
+};
+
+// M32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaultedDefs* @"\01??0ImportDefaultedDefs@@QAE@XZ"(%struct.ImportDefaultedDefs* returned)
+// M64-DAG: declare dllimport                %struct.ImportDefaultedDefs* @"\01??0ImportDefaultedDefs@@QEAA@XZ"(%struct.ImportDefaultedDefs* returned)
+// G32-DAG: declare dllimport x86_thiscallcc void                         @_ZN19ImportDefaultedDefsC1Ev(%struct.ImportDefaultedDefs*)
+// G64-DAG: declare dllimport                void                         @_ZN19ImportDefaultedDefsC1Ev(%struct.ImportDefaultedDefs*)
+__declspec(dllimport) ImportDefaultedDefs::ImportDefaultedDefs() = default;
+
+// M32-DAG: declare dllimport x86_thiscallcc void @"\01??1ImportDefaultedDefs@@QAE@XZ"(%struct.ImportDefaultedDefs*)
+// M64-DAG: declare dllimport                void @"\01??1ImportDefaultedDefs@@QEAA@XZ"(%struct.ImportDefaultedDefs*)
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN19ImportDefaultedDefsD1Ev(%struct.ImportDefaultedDefs*)
+// G64-DAG: declare dllimport                void @_ZN19ImportDefaultedDefsD1Ev(%struct.ImportDefaultedDefs*)
+__declspec(dllimport) ImportDefaultedDefs::~ImportDefaultedDefs() = default;
+
+// M32-DAG: declare dllimport x86_thiscallcc %struct.ImportDefaultedDefs* @"\01??0ImportDefaultedDefs@@QAE@ABU0@@Z"(%struct.ImportDefaultedDefs* returned, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// M64-DAG: declare dllimport                %struct.ImportDefaultedDefs* @"\01??0ImportDefaultedDefs@@QEAA@AEBU0@@Z"(%struct.ImportDefaultedDefs* returned, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN19ImportDefaultedDefsC1ERKS_(%struct.ImportDefaultedDefs*, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G64-DAG: declare dllimport                void @_ZN19ImportDefaultedDefsC1ERKS_(%struct.ImportDefaultedDefs*, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+inline ImportDefaultedDefs::ImportDefaultedDefs(const ImportDefaultedDefs&) = default;
+
+// M32-DAG: declare dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportDefaultedDefs* @"\01??4ImportDefaultedDefs@@QAEAAU0@ABU0@@Z"(%struct.ImportDefaultedDefs*, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// M64-DAG: declare dllimport                dereferenceable({{[0-9]+}}) %struct.ImportDefaultedDefs* @"\01??4ImportDefaultedDefs@@QEAAAEAU0@AEBU0@@Z"(%struct.ImportDefaultedDefs*, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G32-DAG: declare dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportDefaultedDefs* @_ZN19ImportDefaultedDefsaSERKS_(%struct.ImportDefaultedDefs*, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G64-DAG: declare dllimport                dereferenceable({{[0-9]+}}) %struct.ImportDefaultedDefs* @_ZN19ImportDefaultedDefsaSERKS_(%struct.ImportDefaultedDefs*, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+inline ImportDefaultedDefs& ImportDefaultedDefs::operator=(const ImportDefaultedDefs&) = default;
+
+// M32-DAG: define x86_thiscallcc %struct.ImportDefaultedDefs* @"\01??0ImportDefaultedDefs@@QAE@$$QAU0@@Z"(%struct.ImportDefaultedDefs* returned %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// M64-DAG: define                %struct.ImportDefaultedDefs* @"\01??0ImportDefaultedDefs@@QEAA@$$QEAU0@@Z"(%struct.ImportDefaultedDefs* returned %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G32-DAG: define x86_thiscallcc void @_ZN19ImportDefaultedDefsC1EOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G64-DAG: define                void @_ZN19ImportDefaultedDefsC1EOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G32-DAG: define x86_thiscallcc void @_ZN19ImportDefaultedDefsC2EOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G64-DAG: define                void @_ZN19ImportDefaultedDefsC2EOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+ImportDefaultedDefs::ImportDefaultedDefs(ImportDefaultedDefs&&) = default; // dllimport ignored
+
+// M32-DAG: define x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportDefaultedDefs* @"\01??4ImportDefaultedDefs@@QAEAAU0@$$QAU0@@Z"(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// M64-DAG: define                dereferenceable({{[0-9]+}}) %struct.ImportDefaultedDefs* @"\01??4ImportDefaultedDefs@@QEAAAEAU0@$$QEAU0@@Z"(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G32-DAG: define x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.ImportDefaultedDefs* @_ZN19ImportDefaultedDefsaSEOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+// G64-DAG: define                dereferenceable({{[0-9]+}}) %struct.ImportDefaultedDefs* @_ZN19ImportDefaultedDefsaSEOS_(%struct.ImportDefaultedDefs* %this, %struct.ImportDefaultedDefs* dereferenceable({{[0-9]+}}))
+ImportDefaultedDefs& ImportDefaultedDefs::operator=(ImportDefaultedDefs&&) = default; // dllimport ignored
+
+USESPECIALS(ImportDefaultedDefs)
+
+
+// Import allocation functions.
+struct ImportAlloc {
+  __declspec(dllimport) void* operator new(__SIZE_TYPE__);
+  __declspec(dllimport) void* operator new[](__SIZE_TYPE__);
+  __declspec(dllimport) void operator delete(void*);
+  __declspec(dllimport) void operator delete[](void*);
+};
+
+// M32-DAG: declare dllimport i8* @"\01??2ImportAlloc@@SAPAXI@Z"(i32)
+// M64-DAG: declare dllimport i8* @"\01??2ImportAlloc@@SAPEAX_K@Z"(i64)
+// G32-DAG: declare dllimport i8* @_ZN11ImportAllocnwEj(i32)
+// G64-DAG: declare dllimport i8* @_ZN11ImportAllocnwEy(i64)
+void UNIQ(use)() { new ImportAlloc(); }
+
+// M32-DAG: declare dllimport i8* @"\01??_UImportAlloc@@SAPAXI@Z"(i32)
+// M64-DAG: declare dllimport i8* @"\01??_UImportAlloc@@SAPEAX_K@Z"(i64)
+// G32-DAG: declare dllimport i8* @_ZN11ImportAllocnaEj(i32)
+// G64-DAG: declare dllimport i8* @_ZN11ImportAllocnaEy(i64)
+void UNIQ(use)() { new ImportAlloc[1]; }
+
+// M32-DAG: declare dllimport void @"\01??3ImportAlloc@@SAXPAX@Z"(i8*)
+// M64-DAG: declare dllimport void @"\01??3ImportAlloc@@SAXPEAX@Z"(i8*)
+// G32-DAG: declare dllimport void @_ZN11ImportAllocdlEPv(i8*)
+// G64-DAG: declare dllimport void @_ZN11ImportAllocdlEPv(i8*)
+void UNIQ(use)(ImportAlloc* ptr) { delete ptr; }
+
+// M32-DAG: declare dllimport void @"\01??_VImportAlloc@@SAXPAX@Z"(i8*)
+// M64-DAG: declare dllimport void @"\01??_VImportAlloc@@SAXPEAX@Z"(i8*)
+// G32-DAG: declare dllimport void @_ZN11ImportAllocdaEPv(i8*)
+// G64-DAG: declare dllimport void @_ZN11ImportAllocdaEPv(i8*)
+void UNIQ(use)(ImportAlloc* ptr) { delete[] ptr; }
+
+
+//===----------------------------------------------------------------------===//
+// Class member templates
+//===----------------------------------------------------------------------===//
+
+struct MemFunTmpl {
+  template<typename T>                              void normalDef() {}
+  template<typename T> __declspec(dllimport)        void importedNormal() {}
+  template<typename T>                       static void staticDef() {}
+  template<typename T> __declspec(dllimport) static void importedStatic() {}
+};
+
+// Import implicit instantiation of an imported member function template.
+// M32-DAG: declare dllimport x86_thiscallcc void @"\01??$importedNormal@UImplicitInst_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
+// M64-DAG: declare dllimport                void @"\01??$importedNormal@UImplicitInst_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*)
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN10MemFunTmpl14importedNormalI21ImplicitInst_ImportedEEvv(%struct.MemFunTmpl*)
+// G64-DAG: declare dllimport                void @_ZN10MemFunTmpl14importedNormalI21ImplicitInst_ImportedEEvv(%struct.MemFunTmpl*)
+USEMF(MemFunTmpl, importedNormal<ImplicitInst_Imported>)
+
+// MSC-DAG: declare dllimport                void @"\01??$importedStatic@UImplicitInst_Imported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: declare dllimport                void @_ZN10MemFunTmpl14importedStaticI21ImplicitInst_ImportedEEvv()
+USE(MemFunTmpl::importedStatic<ImplicitInst_Imported>)
+
+
+// Import explicit instantiation declaration of an imported member function
+// template.
+// M32-DAG: declare dllimport x86_thiscallcc void @"\01??$importedNormal@UExplicitDecl_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
+// M64-DAG: declare dllimport                void @"\01??$importedNormal@UExplicitDecl_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*)
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN10MemFunTmpl14importedNormalI21ExplicitDecl_ImportedEEvv(%struct.MemFunTmpl*)
+// G64-DAG: declare dllimport                void @_ZN10MemFunTmpl14importedNormalI21ExplicitDecl_ImportedEEvv(%struct.MemFunTmpl*)
+extern template void MemFunTmpl::importedNormal<ExplicitDecl_Imported>();
+USEMF(MemFunTmpl, importedNormal<ExplicitDecl_Imported>)
+
+// MSC-DAG: declare dllimport                void @"\01??$importedStatic@UExplicitDecl_Imported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: declare dllimport                void @_ZN10MemFunTmpl14importedStaticI21ExplicitDecl_ImportedEEvv()
+extern template void MemFunTmpl::importedStatic<ExplicitDecl_Imported>();
+USE(MemFunTmpl::importedStatic<ExplicitDecl_Imported>)
+
+
+// Import explicit instantiation definition of an imported member function
+// template.
+// M32-DAG: declare dllimport x86_thiscallcc void @"\01??$importedNormal@UExplicitInst_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
+// M64-DAG: declare dllimport                void @"\01??$importedNormal@UExplicitInst_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*)
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN10MemFunTmpl14importedNormalI21ExplicitInst_ImportedEEvv(%struct.MemFunTmpl*)
+// G64-DAG: declare dllimport                void @_ZN10MemFunTmpl14importedNormalI21ExplicitInst_ImportedEEvv(%struct.MemFunTmpl*)
+template void MemFunTmpl::importedNormal<ExplicitInst_Imported>();
+USEMF(MemFunTmpl, importedNormal<ExplicitInst_Imported>)
+
+// MSC-DAG: declare dllimport                void @"\01??$importedStatic@UExplicitInst_Imported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: declare dllimport                void @_ZN10MemFunTmpl14importedStaticI21ExplicitInst_ImportedEEvv()
+template void MemFunTmpl::importedStatic<ExplicitInst_Imported>();
+USE(MemFunTmpl::importedStatic<ExplicitInst_Imported>)
+
+
+// Import specialization of an imported member function template.
+// M32-DAG: declare dllimport x86_thiscallcc void @"\01??$importedNormal@UExplicitSpec_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
+// M64-DAG: declare dllimport                void @"\01??$importedNormal@UExplicitSpec_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*)
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN10MemFunTmpl14importedNormalI21ExplicitSpec_ImportedEEvv(%struct.MemFunTmpl*)
+// G64-DAG: declare dllimport                void @_ZN10MemFunTmpl14importedNormalI21ExplicitSpec_ImportedEEvv(%struct.MemFunTmpl*)
+template<> __declspec(dllimport) void MemFunTmpl::importedNormal<ExplicitSpec_Imported>();
+USEMF(MemFunTmpl, importedNormal<ExplicitSpec_Imported>)
+
+// M32-DAG-FIXME: declare dllimport x86_thiscallcc void @"\01??$importedNormal@UExplicitSpec_Def_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
+// M64-DAG-FIXME: declare dllimport                void @"\01??$importedNormal@UExplicitSpec_Def_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*)
+#ifdef MSABI
+//template<> __declspec(dllimport) void MemFunTmpl::importedNormal<ExplicitSpec_Def_Imported>() {}
+//USEMF(MemFunTmpl, importedNormal<ExplicitSpec_Def_Imported>)
+#endif
+
+// M32-DAG: declare dllimport x86_thiscallcc void @"\01??$importedNormal@UExplicitSpec_InlineDef_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
+// M64-DAG: declare dllimport                void @"\01??$importedNormal@UExplicitSpec_InlineDef_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*)
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN10MemFunTmpl14importedNormalI31ExplicitSpec_InlineDef_ImportedEEvv(%struct.MemFunTmpl*)
+// G64-DAG: declare dllimport                void @_ZN10MemFunTmpl14importedNormalI31ExplicitSpec_InlineDef_ImportedEEvv(%struct.MemFunTmpl*)
+template<> __declspec(dllimport) inline void MemFunTmpl::importedNormal<ExplicitSpec_InlineDef_Imported>() {}
+USEMF(MemFunTmpl, importedNormal<ExplicitSpec_InlineDef_Imported>)
+
+
+// MSC-DAG: declare dllimport                void @"\01??$importedStatic@UExplicitSpec_Imported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: declare dllimport                void @_ZN10MemFunTmpl14importedStaticI21ExplicitSpec_ImportedEEvv()
+template<> __declspec(dllimport) void MemFunTmpl::importedStatic<ExplicitSpec_Imported>();
+USE(MemFunTmpl::importedStatic<ExplicitSpec_Imported>)
+
+// MSC-DAG-FIXME: declare dllimport                void @"\01??$importedStatic@UExplicitSpec_Def_Imported@@@MemFunTmpl@@SAXXZ"()
+#ifdef MSABI
+//template<> __declspec(dllimport) void MemFunTmpl::importedStatic<ExplicitSpec_Def_Imported>() {}
+//USE(MemFunTmpl::importedStatic<ExplicitSpec_Def_Imported>)
+#endif
+
+// MSC-DAG: declare dllimport                void @"\01??$importedStatic@UExplicitSpec_InlineDef_Imported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: declare dllimport                void @_ZN10MemFunTmpl14importedStaticI31ExplicitSpec_InlineDef_ImportedEEvv()
+template<> __declspec(dllimport) inline void MemFunTmpl::importedStatic<ExplicitSpec_InlineDef_Imported>() {}
+USE(MemFunTmpl::importedStatic<ExplicitSpec_InlineDef_Imported>)
+
+
+// Not importing specialization of an imported member function template without
+// explicit dllimport.
+// M32-DAG: define x86_thiscallcc void @"\01??$importedNormal@UExplicitSpec_NotImported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl* %this)
+// M64-DAG: define                void @"\01??$importedNormal@UExplicitSpec_NotImported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl* %this)
+// G32-DAG: define x86_thiscallcc void @_ZN10MemFunTmpl14importedNormalI24ExplicitSpec_NotImportedEEvv(%struct.MemFunTmpl* %this)
+// G64-DAG: define                void @_ZN10MemFunTmpl14importedNormalI24ExplicitSpec_NotImportedEEvv(%struct.MemFunTmpl* %this)
+template<> void MemFunTmpl::importedNormal<ExplicitSpec_NotImported>() {}
+USEMF(MemFunTmpl, importedNormal<ExplicitSpec_NotImported>)
+
+// MSC-DAG: define                void @"\01??$importedStatic@UExplicitSpec_NotImported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: define                void @_ZN10MemFunTmpl14importedStaticI24ExplicitSpec_NotImportedEEvv()
+template<> void MemFunTmpl::importedStatic<ExplicitSpec_NotImported>() {}
+USE(MemFunTmpl::importedStatic<ExplicitSpec_NotImported>)
+
+
+// Import explicit instantiation declaration of a non-imported member function
+// template.
+// M32-DAG: declare dllimport x86_thiscallcc void @"\01??$normalDef@UExplicitDecl_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
+// M64-DAG: declare dllimport                void @"\01??$normalDef@UExplicitDecl_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*)
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN10MemFunTmpl9normalDefI21ExplicitDecl_ImportedEEvv(%struct.MemFunTmpl*)
+// G64-DAG: declare dllimport                void @_ZN10MemFunTmpl9normalDefI21ExplicitDecl_ImportedEEvv(%struct.MemFunTmpl*)
+extern template __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitDecl_Imported>();
+USEMF(MemFunTmpl, normalDef<ExplicitDecl_Imported>)
+
+// MSC-DAG: declare dllimport                void @"\01??$staticDef@UExplicitDecl_Imported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: declare dllimport                void @_ZN10MemFunTmpl9staticDefI21ExplicitDecl_ImportedEEvv()
+extern template __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitDecl_Imported>();
+USE(MemFunTmpl::staticDef<ExplicitDecl_Imported>)
+
+
+// Import explicit instantiation definition of a non-imported member function
+// template.
+// M32-DAG: declare dllimport x86_thiscallcc void @"\01??$normalDef@UExplicitInst_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
+// M64-DAG: declare dllimport                void @"\01??$normalDef@UExplicitInst_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*)
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN10MemFunTmpl9normalDefI21ExplicitInst_ImportedEEvv(%struct.MemFunTmpl*)
+// G64-DAG: declare dllimport                void @_ZN10MemFunTmpl9normalDefI21ExplicitInst_ImportedEEvv(%struct.MemFunTmpl*)
+template __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitInst_Imported>();
+USEMF(MemFunTmpl, normalDef<ExplicitInst_Imported>)
+
+// MSC-DAG: declare dllimport                void @"\01??$staticDef@UExplicitInst_Imported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: declare dllimport                void @_ZN10MemFunTmpl9staticDefI21ExplicitInst_ImportedEEvv()
+template __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitInst_Imported>();
+USE(MemFunTmpl::staticDef<ExplicitInst_Imported>)
+
+
+// Import specialization of a non-imported member function template.
+// M32-DAG: declare dllimport x86_thiscallcc void @"\01??$normalDef@UExplicitSpec_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
+// M64-DAG: declare dllimport                void @"\01??$normalDef@UExplicitSpec_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*)
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN10MemFunTmpl9normalDefI21ExplicitSpec_ImportedEEvv(%struct.MemFunTmpl*)
+// G64-DAG: declare dllimport                void @_ZN10MemFunTmpl9normalDefI21ExplicitSpec_ImportedEEvv(%struct.MemFunTmpl*)
+template<> __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitSpec_Imported>();
+USEMF(MemFunTmpl, normalDef<ExplicitSpec_Imported>)
+
+// M32-DAG-FIXME: declare dllimport x86_thiscallcc void @"\01??$normalDef@UExplicitSpec_Def_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
+// M64-DAG-FIXME: declare dllimport                void @"\01??$normalDef@UExplicitSpec_Def_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*)
+#ifdef MSABI
+//template<> __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitSpec_Def_Imported>() {}
+//USEMF(MemFunTmpl, normalDef<ExplicitSpec_Def_Imported>)
+#endif
+
+// M32-DAG: declare dllimport x86_thiscallcc void @"\01??$normalDef@UExplicitSpec_InlineDef_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
+// M64-DAG: declare dllimport                void @"\01??$normalDef@UExplicitSpec_InlineDef_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*)
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN10MemFunTmpl9normalDefI31ExplicitSpec_InlineDef_ImportedEEvv(%struct.MemFunTmpl*)
+// G64-DAG: declare dllimport                void @_ZN10MemFunTmpl9normalDefI31ExplicitSpec_InlineDef_ImportedEEvv(%struct.MemFunTmpl*)
+template<> __declspec(dllimport) inline void MemFunTmpl::normalDef<ExplicitSpec_InlineDef_Imported>() {}
+USEMF(MemFunTmpl, normalDef<ExplicitSpec_InlineDef_Imported>)
+
+
+// MSC-DAG: declare dllimport void @"\01??$staticDef@UExplicitSpec_Imported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: declare dllimport void @_ZN10MemFunTmpl9staticDefI21ExplicitSpec_ImportedEEvv()
+template<> __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitSpec_Imported>();
+USE(MemFunTmpl::staticDef<ExplicitSpec_Imported>)
+
+// MSC-DAG-FIXME: declare dllimport void @"\01??$staticDef@UExplicitSpec_Def_Imported@@@MemFunTmpl@@SAXXZ"()
+#ifdef MSABI
+//template<> __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitSpec_Def_Imported>() {}
+//USE(MemFunTmpl::staticDef<ExplicitSpec_Def_Imported>)
+#endif
+
+// MSC-DAG: declare dllimport void @"\01??$staticDef@UExplicitSpec_InlineDef_Imported@@@MemFunTmpl@@SAXXZ"()
+// GNU-DAG: declare dllimport void @_ZN10MemFunTmpl9staticDefI31ExplicitSpec_InlineDef_ImportedEEvv()
+template<> __declspec(dllimport) inline void MemFunTmpl::staticDef<ExplicitSpec_InlineDef_Imported>() {}
+USE(MemFunTmpl::staticDef<ExplicitSpec_InlineDef_Imported>)
+
+
+
+struct MemVarTmpl {
+  template<typename T>                       static const int StaticVar = 1;
+  template<typename T> __declspec(dllimport) static const int ImportedStaticVar = 1;
+};
+
+// Import implicit instantiation of an imported member variable template.
+// MSC-DAG: @"\01??$ImportedStaticVar@UImplicitInst_Imported@@@MemVarTmpl@@2HB" = available_externally dllimport constant i32 1, align 4
+// GNU-DAG: @_ZN10MemVarTmpl17ImportedStaticVarI21ImplicitInst_ImportedEE       = external dllimport constant i32
+USEMV(MemVarTmpl, ImportedStaticVar<ImplicitInst_Imported>)
+
+// Import explicit instantiation declaration of an imported member variable
+// template.
+// MSC-DAG: @"\01??$ImportedStaticVar@UExplicitDecl_Imported@@@MemVarTmpl@@2HB" = external dllimport constant i32
+// GNU-DAG: @_ZN10MemVarTmpl17ImportedStaticVarI21ExplicitDecl_ImportedEE       = external dllimport constant i32
+extern template const int MemVarTmpl::ImportedStaticVar<ExplicitDecl_Imported>;
+USEMV(MemVarTmpl, ImportedStaticVar<ExplicitDecl_Imported>)
+
+// An explicit instantiation definition of an imported member variable template
+// cannot be imported because the template must be defined which is illegal. The
+// in-class initializer does not count.
+
+// Import specialization of an imported member variable template.
+// MSC-DAG: @"\01??$ImportedStaticVar@UExplicitSpec_Imported@@@MemVarTmpl@@2HB" = external dllimport constant i32
+// GNU-DAG: @_ZN10MemVarTmpl17ImportedStaticVarI21ExplicitSpec_ImportedEE       = external dllimport constant i32
+template<> __declspec(dllimport) const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_Imported>;
+USEMV(MemVarTmpl, ImportedStaticVar<ExplicitSpec_Imported>)
+
+// Not importing specialization of a member variable template without explicit
+// dllimport.
+// MSC-DAG: @"\01??$ImportedStaticVar@UExplicitSpec_NotImported@@@MemVarTmpl@@2HB" = external constant i32
+// GNU-DAG: @_ZN10MemVarTmpl17ImportedStaticVarI24ExplicitSpec_NotImportedEE       = external constant i32
+template<> const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_NotImported>;
+USEMV(MemVarTmpl, ImportedStaticVar<ExplicitSpec_NotImported>)
+
+
+// Import explicit instantiation declaration of a non-imported member variable
+// template.
+// MSC-DAG: @"\01??$StaticVar@UExplicitDecl_Imported@@@MemVarTmpl@@2HB" = external dllimport constant i32
+// GNU-DAG: @_ZN10MemVarTmpl9StaticVarI21ExplicitDecl_ImportedEE        = external dllimport constant i32
+extern template __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitDecl_Imported>;
+USEMV(MemVarTmpl, StaticVar<ExplicitDecl_Imported>)
+
+// An explicit instantiation definition of a non-imported member variable template
+// cannot be imported because the template must be defined which is illegal. The
+// in-class initializer does not count.
+
+// Import specialization of a non-imported member variable template.
+// MSC-DAG: @"\01??$StaticVar@UExplicitSpec_Imported@@@MemVarTmpl@@2HB" = external dllimport constant i32
+// GNU-DAG: @_ZN10MemVarTmpl9StaticVarI21ExplicitSpec_ImportedEE        = external dllimport constant i32
+template<> __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitSpec_Imported>;
+USEMV(MemVarTmpl, StaticVar<ExplicitSpec_Imported>)
diff --git a/test/CodeGenCXX/dllimport-rtti.cpp b/test/CodeGenCXX/dllimport-rtti.cpp
new file mode 100644
index 0000000..7ed7dad
--- /dev/null
+++ b/test/CodeGenCXX/dllimport-rtti.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c++1y -O1 -disable-llvm-optzns -o - %s | FileCheck %s
+
+struct __declspec(dllimport) S {
+  virtual void f();
+} s;
+// CHECK-DAG: @"\01??_7S@@6B@" = available_externally dllimport
+// CHECK-DAG: @"\01??_R0?AUS@@@8" = linkonce_odr
+// CHECK-DAG: @"\01??_R1A@?0A@EA@S@@8" = linkonce_odr
+// CHECK-DAG: @"\01??_R2S@@8" = linkonce_odr
+// CHECK-DAG: @"\01??_R3S@@8" = linkonce_odr
+
+struct U : S {
+} u;
diff --git a/test/CodeGenCXX/dllimport.cpp b/test/CodeGenCXX/dllimport.cpp
new file mode 100644
index 0000000..59f8f63
--- /dev/null
+++ b/test/CodeGenCXX/dllimport.cpp
@@ -0,0 +1,771 @@
+// RUN: %clang_cc1 -triple i686-windows-msvc   -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s -DMSABI | FileCheck --check-prefix=MSC --check-prefix=M32 %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s -DMSABI | FileCheck --check-prefix=MSC --check-prefix=M64 %s
+// RUN: %clang_cc1 -triple i686-windows-gnu    -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s         | FileCheck --check-prefix=GNU --check-prefix=G32 %s
+// RUN: %clang_cc1 -triple x86_64-windows-gnu  -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s         | FileCheck --check-prefix=GNU --check-prefix=G64 %s
+// RUN: %clang_cc1 -triple i686-windows-msvc   -fno-rtti -emit-llvm -std=c++1y -O1 -o - %s -DMSABI | FileCheck --check-prefix=MO1 %s
+// RUN: %clang_cc1 -triple i686-windows-gnu    -fno-rtti -emit-llvm -std=c++1y -O1 -o - %s         | FileCheck --check-prefix=GO1 %s
+
+// CHECK-NOT doesn't play nice with CHECK-DAG, so use separate run lines.
+// RUN: %clang_cc1 -triple i686-windows-msvc   -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s -DMSABI | FileCheck --check-prefix=MSC2 %s
+// RUN: %clang_cc1 -triple i686-windows-gnu    -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s         | FileCheck --check-prefix=GNU2 %s
+
+// Helper structs to make templates more expressive.
+struct ImplicitInst_Imported {};
+struct ImplicitInst_NotImported {};
+struct ExplicitDecl_Imported {};
+struct ExplicitInst_Imported {};
+struct ExplicitSpec_Imported {};
+struct ExplicitSpec_Def_Imported {};
+struct ExplicitSpec_InlineDef_Imported {};
+struct ExplicitSpec_NotImported {};
+
+#define JOIN2(x, y) x##y
+#define JOIN(x, y) JOIN2(x, y)
+#define UNIQ(name) JOIN(name, __LINE__)
+#define USEVARTYPE(type, var) type UNIQ(use)() { return var; }
+#define USEVAR(var) USEVARTYPE(int, var)
+#define USE(func) void UNIQ(use)() { func(); }
+#define USEMEMFUNC(class, func) void (class::*UNIQ(use)())() { return &class::func; }
+#define USECLASS(class) void UNIQ(USE)() { class x; }
+#define USECOPYASSIGN(class) class& (class::*UNIQ(use)())(class&) { return &class::operator=; }
+#define USEMOVEASSIGN(class) class& (class::*UNIQ(use)())(class&&) { return &class::operator=; }
+
+//===----------------------------------------------------------------------===//
+// Globals
+//===----------------------------------------------------------------------===//
+
+// Import declaration.
+// MSC-DAG: @"\01?ExternGlobalDecl@@3HA" = external dllimport global i32
+// GNU-DAG: @ExternGlobalDecl            = external dllimport global i32
+__declspec(dllimport) extern int ExternGlobalDecl;
+USEVAR(ExternGlobalDecl)
+
+// dllimport implies a declaration.
+// MSC-DAG: @"\01?GlobalDecl@@3HA" = external dllimport global i32
+// GNU-DAG: @GlobalDecl            = external dllimport global i32
+__declspec(dllimport) int GlobalDecl;
+USEVAR(GlobalDecl)
+
+// Redeclarations
+// MSC-DAG: @"\01?GlobalRedecl1@@3HA" = external dllimport global i32
+// GNU-DAG: @GlobalRedecl1            = external dllimport global i32
+__declspec(dllimport) extern int GlobalRedecl1;
+__declspec(dllimport) extern int GlobalRedecl1;
+USEVAR(GlobalRedecl1)
+
+// MSC-DAG: @"\01?GlobalRedecl2a@@3HA" = external dllimport global i32
+// GNU-DAG: @GlobalRedecl2a            = external dllimport global i32
+__declspec(dllimport) int GlobalRedecl2a;
+__declspec(dllimport) int GlobalRedecl2a;
+USEVAR(GlobalRedecl2a)
+
+// M32-DAG: @"\01?GlobalRedecl2b@@3PAHA"   = external dllimport global i32*
+// M64-DAG: @"\01?GlobalRedecl2b@@3PEAHEA" = external dllimport global i32*
+// GNU-DAG: @GlobalRedecl2b                = external dllimport global i32*
+int *__attribute__((dllimport)) GlobalRedecl2b;
+int *__attribute__((dllimport)) GlobalRedecl2b;
+USEVARTYPE(int*, GlobalRedecl2b)
+
+// MSC-DAG: @"\01?GlobalRedecl2c@@3HA" = external dllimport global i32
+// GNU-DAG: @GlobalRedecl2c            = external dllimport global i32
+int GlobalRedecl2c __attribute__((dllimport));
+int GlobalRedecl2c __attribute__((dllimport));
+USEVAR(GlobalRedecl2c)
+
+// NB: MSC issues a warning and makes GlobalRedecl3 dllexport. We follow GCC
+// and drop the dllimport with a warning.
+// MSC-DAG: @"\01?GlobalRedecl3@@3HA" = external global i32
+// GNU-DAG: @GlobalRedecl3            = external global i32
+__declspec(dllimport) extern int GlobalRedecl3;
+                      extern int GlobalRedecl3; // dllimport ignored
+USEVAR(GlobalRedecl3)
+
+// MSC-DAG: @"\01?ExternalGlobal@ns@@3HA" = external dllimport global i32
+// GNU-DAG: @_ZN2ns14ExternalGlobalE      = external dllimport global i32
+namespace ns { __declspec(dllimport) int ExternalGlobal; }
+USEVAR(ns::ExternalGlobal)
+
+int f();
+// MO1-DAG: @"\01?x@?1??inlineStaticLocalsFunc@@YAHXZ@4HA" = available_externally dllimport global i32 0
+// MO1-DAG: @"\01??_B?1??inlineStaticLocalsFunc@@YAHXZ@51" = available_externally dllimport global i32 0
+inline int __declspec(dllimport) inlineStaticLocalsFunc() {
+  static int x = f();
+  return x++;
+};
+USE(inlineStaticLocalsFunc);
+
+// The address of a dllimport global cannot be used in constant initialization.
+// M32-DAG: @"\01?arr@?0??initializationFunc@@YAPAHXZ@4QBQAHB" = internal global [1 x i32*] zeroinitializer
+// GNU-DAG: @_ZZ18initializationFuncvE3arr = internal global [1 x i32*] zeroinitializer
+int *initializationFunc() {
+  static int *const arr[] = {&ExternGlobalDecl};
+  return arr[0];
+}
+USE(initializationFunc);
+
+
+//===----------------------------------------------------------------------===//
+// Variable templates
+//===----------------------------------------------------------------------===//
+
+// Import declaration.
+// MSC-DAG: @"\01??$ExternVarTmplDecl@UImplicitInst_Imported@@@@3HA" = external dllimport global i32
+// GNU-DAG: @_Z17ExternVarTmplDeclI21ImplicitInst_ImportedE          = external dllimport global i32
+template<typename T> __declspec(dllimport) extern int ExternVarTmplDecl;
+USEVAR(ExternVarTmplDecl<ImplicitInst_Imported>)
+
+// dllimport implies a declaration.
+// MSC-DAG: @"\01??$VarTmplDecl@UImplicitInst_Imported@@@@3HA" = external dllimport global i32
+// GNU-DAG: @_Z11VarTmplDeclI21ImplicitInst_ImportedE          = external dllimport global i32
+template<typename T> __declspec(dllimport) int VarTmplDecl;
+USEVAR(VarTmplDecl<ImplicitInst_Imported>)
+
+// Redeclarations
+// MSC-DAG: @"\01??$VarTmplRedecl1@UImplicitInst_Imported@@@@3HA" = external dllimport global i32
+// GNU-DAG: @_Z14VarTmplRedecl1I21ImplicitInst_ImportedE          = external dllimport global i32
+template<typename T> __declspec(dllimport) extern int VarTmplRedecl1;
+template<typename T> __declspec(dllimport) extern int VarTmplRedecl1;
+USEVAR(VarTmplRedecl1<ImplicitInst_Imported>)
+
+// MSC-DAG: @"\01??$VarTmplRedecl2@UImplicitInst_Imported@@@@3HA" = external dllimport global i32
+// GNU-DAG: @_Z14VarTmplRedecl2I21ImplicitInst_ImportedE          = external dllimport global i32
+template<typename T> __declspec(dllimport) int VarTmplRedecl2;
+template<typename T> __declspec(dllimport) int VarTmplRedecl2;
+USEVAR(VarTmplRedecl2<ImplicitInst_Imported>)
+
+// MSC-DAG: @"\01??$VarTmplRedecl3@UImplicitInst_Imported@@@@3HA" = external global i32
+// GNU-DAG: @_Z14VarTmplRedecl3I21ImplicitInst_ImportedE          = external global i32
+template<typename T> __declspec(dllimport) extern int VarTmplRedecl3;
+template<typename T>                       extern int VarTmplRedecl3; // dllimport ignored
+USEVAR(VarTmplRedecl3<ImplicitInst_Imported>)
+
+
+// MSC-DAG: @"\01??$ExternalVarTmpl@UImplicitInst_Imported@@@ns@@3HA" = external dllimport global i32
+// GNU-DAG: @_ZN2ns15ExternalVarTmplI21ImplicitInst_ImportedEE        = external dllimport global i32
+namespace ns { template<typename T> __declspec(dllimport) int ExternalVarTmpl; }
+USEVAR(ns::ExternalVarTmpl<ImplicitInst_Imported>)
+
+
+template<typename T> int VarTmpl;
+template<typename T> __declspec(dllimport) int ImportedVarTmpl;
+
+// Import implicit instantiation of an imported variable template.
+// MSC-DAG: @"\01??$ImportedVarTmpl@UImplicitInst_Imported@@@@3HA" = external dllimport global i32
+// GNU-DAG: @_Z15ImportedVarTmplI21ImplicitInst_ImportedE          = external dllimport global i32
+USEVAR(ImportedVarTmpl<ImplicitInst_Imported>)
+
+// Import explicit instantiation declaration of an imported variable template.
+// MSC-DAG: @"\01??$ImportedVarTmpl@UExplicitDecl_Imported@@@@3HA" = external dllimport global i32
+// GNU-DAG: @_Z15ImportedVarTmplI21ExplicitDecl_ImportedE          = external dllimport global i32
+extern template int ImportedVarTmpl<ExplicitDecl_Imported>;
+USEVAR(ImportedVarTmpl<ExplicitDecl_Imported>)
+
+// An explicit instantiation definition of an imported variable template cannot
+// be imported because the template must be defined which is illegal.
+
+// Import specialization of an imported variable template.
+// MSC-DAG: @"\01??$ImportedVarTmpl@UExplicitSpec_Imported@@@@3HA" = external dllimport global i32
+// GNU-DAG: @_Z15ImportedVarTmplI21ExplicitSpec_ImportedE          = external dllimport global i32
+template<> __declspec(dllimport) int ImportedVarTmpl<ExplicitSpec_Imported>;
+USEVAR(ImportedVarTmpl<ExplicitSpec_Imported>)
+
+// Not importing specialization of an imported variable template without
+// explicit dllimport.
+// MSC-DAG: @"\01??$ImportedVarTmpl@UExplicitSpec_NotImported@@@@3HA" = global i32 0, align 4
+// GNU-DAG: @_Z15ImportedVarTmplI24ExplicitSpec_NotImportedE          = global i32 0, align 4
+template<> int ImportedVarTmpl<ExplicitSpec_NotImported>;
+USEVAR(ImportedVarTmpl<ExplicitSpec_NotImported>)
+
+// Import explicit instantiation declaration of a non-imported variable template.
+// MSC-DAG: @"\01??$VarTmpl@UExplicitDecl_Imported@@@@3HA" = external dllimport global i32
+// GNU-DAG: @_Z7VarTmplI21ExplicitDecl_ImportedE           = external dllimport global i32
+extern template __declspec(dllimport) int VarTmpl<ExplicitDecl_Imported>;
+USEVAR(VarTmpl<ExplicitDecl_Imported>)
+
+// Import explicit instantiation definition of a non-imported variable template.
+// MSC-DAG: @"\01??$VarTmpl@UExplicitInst_Imported@@@@3HA" = external dllimport global i32
+// GNU-DAG: @_Z7VarTmplI21ExplicitInst_ImportedE           = external dllimport global i32
+template __declspec(dllimport) int VarTmpl<ExplicitInst_Imported>;
+USEVAR(VarTmpl<ExplicitInst_Imported>)
+
+// Import specialization of a non-imported variable template.
+// MSC-DAG: @"\01??$VarTmpl@UExplicitSpec_Imported@@@@3HA" = external dllimport global i32
+// GNU-DAG: @_Z7VarTmplI21ExplicitSpec_ImportedE           = external dllimport global i32
+template<> __declspec(dllimport) int VarTmpl<ExplicitSpec_Imported>;
+USEVAR(VarTmpl<ExplicitSpec_Imported>)
+
+
+
+//===----------------------------------------------------------------------===//
+// Functions
+//===----------------------------------------------------------------------===//
+
+// Import function declaration.
+// MSC-DAG: declare dllimport void @"\01?decl@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z4declv()
+__declspec(dllimport) void decl();
+USE(decl)
+
+// extern "C"
+// MSC-DAG: declare dllimport void @externC()
+// GNU-DAG: declare dllimport void @externC()
+extern "C" __declspec(dllimport) void externC();
+USE(externC)
+
+// Import inline function.
+// MSC-DAG: declare dllimport void @"\01?inlineFunc@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z10inlineFuncv()
+// MO1-DAG: define available_externally dllimport void @"\01?inlineFunc@@YAXXZ"()
+// GO1-DAG: define available_externally dllimport void @_Z10inlineFuncv()
+__declspec(dllimport) inline void inlineFunc() {}
+USE(inlineFunc)
+
+// MSC-DAG: declare dllimport void @"\01?inlineDecl@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z10inlineDeclv()
+// MO1-DAG: define available_externally dllimport void @"\01?inlineDecl@@YAXXZ"()
+// GO1-DAG: define available_externally dllimport void @_Z10inlineDeclv()
+__declspec(dllimport) inline void inlineDecl();
+                             void inlineDecl() {}
+USE(inlineDecl)
+
+// MSC-DAG: declare dllimport void @"\01?inlineDef@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z9inlineDefv()
+// MO1-DAG: define available_externally dllimport void @"\01?inlineDef@@YAXXZ"()
+// GO1-DAG: define available_externally dllimport void @_Z9inlineDefv()
+__declspec(dllimport) void inlineDef();
+               inline void inlineDef() {}
+USE(inlineDef)
+
+// inline attributes
+// MSC-DAG: declare dllimport void @"\01?noinline@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z8noinlinev()
+__declspec(dllimport) __attribute__((noinline)) inline void noinline() {}
+USE(noinline)
+
+// MSC2-NOT: @"\01?alwaysInline@@YAXXZ"()
+// GNU2-NOT: @_Z12alwaysInlinev()
+__declspec(dllimport) __attribute__((always_inline)) inline void alwaysInline() {}
+USE(alwaysInline)
+
+// Redeclarations
+// MSC-DAG: declare dllimport void @"\01?redecl1@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z7redecl1v()
+__declspec(dllimport) void redecl1();
+__declspec(dllimport) void redecl1();
+USE(redecl1)
+
+// NB: MSC issues a warning and makes redecl2/redecl3 dllexport. We follow GCC
+// and drop the dllimport with a warning.
+// MSC-DAG: declare void @"\01?redecl2@@YAXXZ"()
+// GNU-DAG: declare void @_Z7redecl2v()
+__declspec(dllimport) void redecl2();
+                      void redecl2();
+USE(redecl2)
+
+// MSC-DAG: define void @"\01?redecl3@@YAXXZ"()
+// GNU-DAG: define void @_Z7redecl3v()
+__declspec(dllimport) void redecl3();
+                      void redecl3() {} // dllimport ignored
+USE(redecl3)
+
+
+// Friend functions
+// MSC-DAG: declare dllimport void @"\01?friend1@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z7friend1v()
+// MSC-DAG: declare           void @"\01?friend2@@YAXXZ"()
+// GNU-DAG: declare           void @_Z7friend2v()
+// MSC-DAG: define            void @"\01?friend3@@YAXXZ"()
+// GNU-DAG: define            void @_Z7friend3v()
+struct FuncFriend {
+  friend __declspec(dllimport) void friend1();
+  friend __declspec(dllimport) void friend2();
+  friend __declspec(dllimport) void friend3();
+};
+__declspec(dllimport) void friend1();
+                      void friend2(); // dllimport ignored
+                      void friend3() {} // dllimport ignored
+USE(friend1)
+USE(friend2)
+USE(friend3)
+
+// Implicit declarations can be redeclared with dllimport.
+// MSC-DAG: declare dllimport noalias i8* @"\01??2@{{YAPAXI|YAPEAX_K}}@Z"(
+// GNU-DAG: declare dllimport noalias i8* @_Znw{{[yj]}}(
+__declspec(dllimport) void* operator new(__SIZE_TYPE__ n);
+void UNIQ(use)() { ::operator new(42); }
+
+// MSC-DAG: declare dllimport void @"\01?externalFunc@ns@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_ZN2ns12externalFuncEv()
+namespace ns { __declspec(dllimport) void externalFunc(); }
+USE(ns::externalFunc)
+
+
+
+//===----------------------------------------------------------------------===//
+// Function templates
+//===----------------------------------------------------------------------===//
+
+// Import function template declaration.
+// MSC-DAG: declare dllimport void @"\01??$funcTmplDecl@UImplicitInst_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z12funcTmplDeclI21ImplicitInst_ImportedEvv()
+template<typename T> __declspec(dllimport) void funcTmplDecl();
+USE(funcTmplDecl<ImplicitInst_Imported>)
+
+// Function template definitions cannot be imported.
+
+// Import inline function template.
+// MSC-DAG: declare dllimport void @"\01??$inlineFuncTmpl1@UImplicitInst_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z15inlineFuncTmpl1I21ImplicitInst_ImportedEvv()
+// MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl1@UImplicitInst_Imported@@@@YAXXZ"()
+// GO1-DAG: define available_externally dllimport void @_Z15inlineFuncTmpl1I21ImplicitInst_ImportedEvv()
+template<typename T> __declspec(dllimport) inline void inlineFuncTmpl1() {}
+USE(inlineFuncTmpl1<ImplicitInst_Imported>)
+
+// MSC-DAG: declare dllimport void @"\01??$inlineFuncTmpl2@UImplicitInst_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z15inlineFuncTmpl2I21ImplicitInst_ImportedEvv()
+// MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl2@UImplicitInst_Imported@@@@YAXXZ"()
+// GO1-DAG: define available_externally dllimport void @_Z15inlineFuncTmpl2I21ImplicitInst_ImportedEvv()
+template<typename T> inline void __attribute__((dllimport)) inlineFuncTmpl2() {}
+USE(inlineFuncTmpl2<ImplicitInst_Imported>)
+
+// MSC-DAG: declare dllimport void @"\01??$inlineFuncTmplDecl@UImplicitInst_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z18inlineFuncTmplDeclI21ImplicitInst_ImportedEvv()
+// MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmplDecl@UImplicitInst_Imported@@@@YAXXZ"()
+// GO1-DAG: define available_externally dllimport 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"()
+// GNU-DAG: declare dllimport void @_Z17inlineFuncTmplDefI21ImplicitInst_ImportedEvv()
+// MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmplDef@UImplicitInst_Imported@@@@YAXXZ"()
+// GO1-DAG: define available_externally dllimport void @_Z17inlineFuncTmplDefI21ImplicitInst_ImportedEvv()
+template<typename T> __declspec(dllimport) void inlineFuncTmplDef();
+template<typename T>                inline void inlineFuncTmplDef() {}
+USE(inlineFuncTmplDef<ImplicitInst_Imported>)
+
+
+// Redeclarations
+// MSC-DAG: declare dllimport void @"\01??$funcTmplRedecl1@UImplicitInst_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z15funcTmplRedecl1I21ImplicitInst_ImportedEvv()
+template<typename T> __declspec(dllimport) void funcTmplRedecl1();
+template<typename T> __declspec(dllimport) void funcTmplRedecl1();
+USE(funcTmplRedecl1<ImplicitInst_Imported>)
+
+// MSC-DAG: declare void @"\01??$funcTmplRedecl2@UImplicitInst_NotImported@@@@YAXXZ"()
+// GNU-DAG: declare void @_Z15funcTmplRedecl2I24ImplicitInst_NotImportedEvv()
+template<typename T> __declspec(dllimport) void funcTmplRedecl2();
+template<typename T>                       void funcTmplRedecl2(); // dllimport ignored
+USE(funcTmplRedecl2<ImplicitInst_NotImported>)
+
+// MSC-DAG: define linkonce_odr void @"\01??$funcTmplRedecl3@UImplicitInst_NotImported@@@@YAXXZ"()
+// GNU-DAG: define linkonce_odr void @_Z15funcTmplRedecl3I24ImplicitInst_NotImportedEvv()
+template<typename T> __declspec(dllimport) void funcTmplRedecl3();
+template<typename T>                       void funcTmplRedecl3() {} // dllimport ignored
+USE(funcTmplRedecl3<ImplicitInst_NotImported>)
+
+
+// Function template friends
+// MSC-DAG: declare dllimport   void @"\01??$funcTmplFriend1@UImplicitInst_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport   void @_Z15funcTmplFriend1I21ImplicitInst_ImportedEvv()
+// MSC-DAG: declare             void @"\01??$funcTmplFriend2@UImplicitInst_NotImported@@@@YAXXZ"()
+// 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"()
+// GNU-DAG: declare dllimport   void @_Z15funcTmplFriend4I21ImplicitInst_ImportedEvv()
+struct FuncTmplFriend {
+  template<typename T> friend __declspec(dllimport) void funcTmplFriend1();
+  template<typename T> friend __declspec(dllimport) void funcTmplFriend2();
+  template<typename T> friend __declspec(dllimport) void funcTmplFriend3();
+  template<typename T> friend __declspec(dllimport) inline void funcTmplFriend4();
+};
+template<typename T> __declspec(dllimport) void funcTmplFriend1();
+template<typename T>                       void funcTmplFriend2(); // dllimport ignored
+template<typename T>                       void funcTmplFriend3() {} // dllimport ignored
+template<typename T>                       inline void funcTmplFriend4() {}
+USE(funcTmplFriend1<ImplicitInst_Imported>)
+USE(funcTmplFriend2<ImplicitInst_NotImported>)
+USE(funcTmplFriend3<ImplicitInst_NotImported>)
+USE(funcTmplFriend4<ImplicitInst_Imported>)
+
+// MSC-DAG: declare dllimport void @"\01??$externalFuncTmpl@UImplicitInst_Imported@@@ns@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_ZN2ns16externalFuncTmplI21ImplicitInst_ImportedEEvv()
+namespace ns { template<typename T> __declspec(dllimport) void externalFuncTmpl(); }
+USE(ns::externalFuncTmpl<ImplicitInst_Imported>)
+
+
+template<typename T> void funcTmpl() {}
+template<typename T> inline void inlineFuncTmpl() {}
+template<typename T> __declspec(dllimport) void importedFuncTmplDecl();
+template<typename T> __declspec(dllimport) inline void importedFuncTmpl() {}
+
+// Import implicit instantiation of an imported function template.
+// MSC-DAG: declare dllimport void @"\01??$importedFuncTmplDecl@UImplicitInst_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z20importedFuncTmplDeclI21ImplicitInst_ImportedEvv()
+USE(importedFuncTmplDecl<ImplicitInst_Imported>)
+
+// MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UImplicitInst_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z16importedFuncTmplI21ImplicitInst_ImportedEvv()
+// MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmpl@UImplicitInst_Imported@@@@YAXXZ"()
+// GO1-DAG: define available_externally dllimport void @_Z16importedFuncTmplI21ImplicitInst_ImportedEvv()
+USE(importedFuncTmpl<ImplicitInst_Imported>)
+
+// Import explicit instantiation declaration of an imported function template.
+// MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z16importedFuncTmplI21ExplicitDecl_ImportedEvv()
+// MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"()
+// GO1-DAG: define available_externally dllimport void @_Z16importedFuncTmplI21ExplicitDecl_ImportedEvv()
+extern template void importedFuncTmpl<ExplicitDecl_Imported>();
+USE(importedFuncTmpl<ExplicitDecl_Imported>)
+
+// Import explicit instantiation definition of an imported function template.
+// MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z16importedFuncTmplI21ExplicitInst_ImportedEvv()
+// MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()
+// GO1-DAG: define available_externally dllimport void @_Z16importedFuncTmplI21ExplicitInst_ImportedEvv()
+template void importedFuncTmpl<ExplicitInst_Imported>();
+USE(importedFuncTmpl<ExplicitInst_Imported>)
+
+
+// Import specialization of an imported function template.
+// MSC-DAG: declare dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z20importedFuncTmplDeclI21ExplicitSpec_ImportedEvv()
+template<> __declspec(dllimport) void importedFuncTmplDecl<ExplicitSpec_Imported>();
+USE(importedFuncTmplDecl<ExplicitSpec_Imported>)
+
+// MSC-DAG-FIXME: declare dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
+// MO1-DAG-FIXME: define available_externally dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
+#ifdef MSABI
+//template<> __declspec(dllimport) void importedFuncTmplDecl<ExplicitSpec_Def_Imported>() {}
+//USE(importedFuncTmplDecl<ExplicitSpec_Def_Imported>)
+#endif
+
+// MSC-DAG: declare dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z20importedFuncTmplDeclI31ExplicitSpec_InlineDef_ImportedEvv()
+// MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
+// GO1-DAG: define available_externally dllimport void @_Z20importedFuncTmplDeclI31ExplicitSpec_InlineDef_ImportedEvv()
+template<> __declspec(dllimport) inline void importedFuncTmplDecl<ExplicitSpec_InlineDef_Imported>() {}
+USE(importedFuncTmplDecl<ExplicitSpec_InlineDef_Imported>)
+
+
+// MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z16importedFuncTmplI21ExplicitSpec_ImportedEvv()
+template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Imported>();
+USE(importedFuncTmpl<ExplicitSpec_Imported>)
+
+// MSC-DAG-FIXME: declare dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
+// MO1-DAG-FIXME: define available_externally dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
+#ifdef MSABI
+//template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Def_Imported>() {}
+//USE(importedFuncTmpl<ExplicitSpec_Def_Imported>)
+#endif
+
+// MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z16importedFuncTmplI31ExplicitSpec_InlineDef_ImportedEvv()
+// MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
+// GO1-DAG: define available_externally dllimport void @_Z16importedFuncTmplI31ExplicitSpec_InlineDef_ImportedEvv()
+template<> __declspec(dllimport) inline void importedFuncTmpl<ExplicitSpec_InlineDef_Imported>() {}
+USE(importedFuncTmpl<ExplicitSpec_InlineDef_Imported>)
+
+
+// Not importing specialization of an imported function template without
+// explicit dllimport.
+// MSC-DAG: define void @"\01??$importedFuncTmpl@UExplicitSpec_NotImported@@@@YAXXZ"()
+// GNU-DAG: define void @_Z16importedFuncTmplI24ExplicitSpec_NotImportedEvv()
+template<> void importedFuncTmpl<ExplicitSpec_NotImported>() {}
+USE(importedFuncTmpl<ExplicitSpec_NotImported>)
+
+
+// Import explicit instantiation declaration of a non-imported function template.
+// MSC-DAG: declare dllimport void @"\01??$funcTmpl@UExplicitDecl_Imported@@@@YAXXZ"()
+// MSC-DAG: declare dllimport void @"\01??$inlineFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z8funcTmplI21ExplicitDecl_ImportedEvv()
+// GNU-DAG: declare dllimport void @_Z14inlineFuncTmplI21ExplicitDecl_ImportedEvv()
+// MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl@UExplicitDecl_Imported@@@@YAXXZ"()
+// GO1-DAG: define available_externally dllimport void @_Z14inlineFuncTmplI21ExplicitDecl_ImportedEvv()
+extern template __declspec(dllimport) void funcTmpl<ExplicitDecl_Imported>();
+extern template __declspec(dllimport) void inlineFuncTmpl<ExplicitDecl_Imported>();
+USE(funcTmpl<ExplicitDecl_Imported>)
+USE(inlineFuncTmpl<ExplicitDecl_Imported>)
+
+
+// Import explicit instantiation definition of a non-imported function template.
+// MSC-DAG: declare dllimport void @"\01??$funcTmpl@UExplicitInst_Imported@@@@YAXXZ"()
+// MSC-DAG: declare dllimport void @"\01??$inlineFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z8funcTmplI21ExplicitInst_ImportedEvv()
+// GNU-DAG: declare dllimport void @_Z14inlineFuncTmplI21ExplicitInst_ImportedEvv()
+// MO1-DAG: define available_externally dllimport void @"\01??$funcTmpl@UExplicitInst_Imported@@@@YAXXZ"()
+// MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()
+// GO1-DAG: define available_externally dllimport void @_Z8funcTmplI21ExplicitInst_ImportedEvv()
+// GO1-DAG: define available_externally dllimport void @_Z14inlineFuncTmplI21ExplicitInst_ImportedEvv()
+template __declspec(dllimport) void funcTmpl<ExplicitInst_Imported>();
+template __declspec(dllimport) void inlineFuncTmpl<ExplicitInst_Imported>();
+USE(funcTmpl<ExplicitInst_Imported>)
+USE(inlineFuncTmpl<ExplicitInst_Imported>)
+
+
+// Import specialization of a non-imported function template.
+// MSC-DAG: declare dllimport void @"\01??$funcTmpl@UExplicitSpec_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z8funcTmplI21ExplicitSpec_ImportedEvv()
+template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Imported>();
+USE(funcTmpl<ExplicitSpec_Imported>)
+
+// MSC-DAG-FIXME: declare dllimport void @"\01??$funcTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
+// MO1-DAG-FIXME: define available_externally dllimport void @"\01??$funcTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
+#ifdef MSABI
+//template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Def_Imported>() {}
+//USE(funcTmpl<ExplicitSpec_Def_Imported>)
+#endif
+
+// MSC-DAG: declare dllimport void @"\01??$funcTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
+// GNU-DAG: declare dllimport void @_Z8funcTmplI31ExplicitSpec_InlineDef_ImportedEvv()
+// MO1-DAG: define available_externally dllimport void @"\01??$funcTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
+// GO1-DAG: define available_externally dllimport void @_Z8funcTmplI31ExplicitSpec_InlineDef_ImportedEvv()
+template<> __declspec(dllimport) inline void funcTmpl<ExplicitSpec_InlineDef_Imported>() {}
+USE(funcTmpl<ExplicitSpec_InlineDef_Imported>)
+
+
+
+//===----------------------------------------------------------------------===//
+// Classes
+//===----------------------------------------------------------------------===//
+
+struct __declspec(dllimport) T {
+  void a() {}
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?a@T@@QAEXXZ"
+
+  static int b;
+  // MO1-DAG: @"\01?b@T@@2HA" = external dllimport global i32
+
+  T& operator=(T&) = default;
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.T* @"\01??4T@@QAEAAU0@AAU0@@Z"
+
+  T& operator=(T&&) = default;
+  // Note: Don't mark inline move operators dllimport because current MSVC versions don't export them.
+  // MO1-DAG: define linkonce_odr x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.T* @"\01??4T@@QAEAAU0@$$QAU0@@Z"
+};
+USEMEMFUNC(T, a)
+USEVAR(T::b)
+USECOPYASSIGN(T)
+USEMOVEASSIGN(T)
+
+template <typename T> struct __declspec(dllimport) U { void foo() {} };
+// MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?foo@?$U@H@@QAEXXZ"
+struct __declspec(dllimport) V : public U<int> { };
+USEMEMFUNC(V, foo)
+
+struct __declspec(dllimport) W { virtual void foo() {} };
+USECLASS(W)
+// vftable:
+// MO1-DAG: @"\01??_7W@@6B@" = available_externally dllimport unnamed_addr constant [1 x i8*] [i8* bitcast (void (%struct.W*)* @"\01?foo@W@@UAEXXZ" to i8*)]
+// GO1-DAG: @_ZTV1W = available_externally dllimport unnamed_addr constant [3 x i8*] [i8* null, i8* null, i8* bitcast (void (%struct.W*)* @_ZN1W3fooEv to i8*)]
+
+struct __declspec(dllimport) KeyFuncClass {
+  constexpr KeyFuncClass() {}
+  virtual void foo();
+};
+constexpr KeyFuncClass keyFuncClassVar;
+// G32-DAG: @_ZTV12KeyFuncClass = external dllimport unnamed_addr constant [3 x i8*]
+
+struct __declspec(dllimport) X : public virtual W {};
+USECLASS(X)
+// vbtable:
+// MO1-DAG: @"\01??_8X@@7B@" = available_externally dllimport unnamed_addr constant [2 x i32] [i32 0, i32 4]
+
+struct __declspec(dllimport) Y {
+  int x;
+};
+
+struct __declspec(dllimport) Z { virtual ~Z() {} };
+USECLASS(Z)
+// User-defined dtor:
+// MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01??1Z@@UAE@XZ"
+
+namespace DontUseDtorAlias {
+  struct __declspec(dllimport) A { ~A(); };
+  struct __declspec(dllimport) B : A { ~B(); };
+  inline A::~A() { }
+  inline B::~B() { }
+  // Emit a real definition of B's constructor; don't alias it to A's.
+  // MO1-DAG: available_externally dllimport x86_thiscallcc void @"\01??1B@DontUseDtorAlias@@QAE@XZ"
+  USECLASS(B)
+}
+
+namespace Vtordisp {
+  // Don't dllimport the vtordisp.
+  // MO1-DAG: define linkonce_odr x86_thiscallcc void @"\01?f@?$C@D@Vtordisp@@$4PPPPPPPM@A@AEXXZ"
+
+  class Base {
+    virtual void f() {}
+  };
+  template <typename T>
+  class __declspec(dllimport) C : virtual public Base {
+  public:
+    C() {}
+    virtual void f() {}
+  };
+  template class C<char>;
+}
+
+namespace ClassTemplateStaticDef {
+  // Regular template static field:
+  template <typename T> struct __declspec(dllimport) S {
+    static int x;
+  };
+  template <typename T> int S<T>::x;
+  // MSC-DAG: @"\01?x@?$S@H@ClassTemplateStaticDef@@2HA" = available_externally dllimport global i32 0
+  int f() { return S<int>::x; }
+
+  // Partial class template specialization static field:
+  template <typename A> struct T;
+  template <typename A> struct __declspec(dllimport) T<A*> {
+    static int x;
+  };
+  template <typename A> int T<A*>::x;
+  // GNU-DAG: @_ZN22ClassTemplateStaticDef1TIPvE1xE = available_externally dllimport global i32 0
+  int g() { return T<void*>::x; }
+}
+
+namespace PR19933 {
+// Don't dynamically initialize dllimport vars.
+// MSC2-NOT: @llvm.global_ctors
+// GNU2-NOT: @llvm.global_ctors
+
+  struct NonPOD { NonPOD(); };
+  template <typename T> struct A { static NonPOD x; };
+  template <typename T> NonPOD A<T>::x;
+  template struct __declspec(dllimport) A<int>;
+  // MSC-DAG: @"\01?x@?$A@H@PR19933@@2UNonPOD@2@A" = available_externally dllimport global %"struct.PR19933::NonPOD" zeroinitializer
+
+  int f();
+  template <typename T> struct B { static int x; };
+  template <typename T> int B<T>::x = f();
+  template struct __declspec(dllimport) B<int>;
+  // MSC-DAG: @"\01?x@?$B@H@PR19933@@2HA" = available_externally dllimport global i32 0
+
+  constexpr int g() { return 42; }
+  template <typename T> struct C { static int x; };
+  template <typename T> int C<T>::x = g();
+  template struct __declspec(dllimport) C<int>;
+  // MSC-DAG: @"\01?x@?$C@H@PR19933@@2HA" = available_externally dllimport global i32 42
+
+  template <int I> struct D { static int x, y; };
+  template <int I> int D<I>::x = I + 1;
+  template <int I> int D<I>::y = I + f();
+  template struct __declspec(dllimport) D<42>;
+  // MSC-DAG: @"\01?x@?$D@$0CK@@PR19933@@2HA" = available_externally dllimport global i32 43
+  // MSC-DAG: @"\01?y@?$D@$0CK@@PR19933@@2HA" = available_externally dllimport global i32 0
+}
+
+// MS ignores DLL attributes on partial specializations.
+template <typename T> struct PartiallySpecializedClassTemplate {};
+template <typename T> struct __declspec(dllimport) PartiallySpecializedClassTemplate<T*> { void f() {} };
+USEMEMFUNC(PartiallySpecializedClassTemplate<void*>, f);
+// M32-DAG: define linkonce_odr x86_thiscallcc void @"\01?f@?$PartiallySpecializedClassTemplate@PAX@@QAEXXZ"
+// G32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @_ZN33PartiallySpecializedClassTemplateIPvE1fEv
+
+template <typename T> struct ExplicitlySpecializedClassTemplate {};
+template <> struct __declspec(dllimport) ExplicitlySpecializedClassTemplate<void*> { void f() {} };
+USEMEMFUNC(ExplicitlySpecializedClassTemplate<void*>, f);
+// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?f@?$ExplicitlySpecializedClassTemplate@PAX@@QAEXXZ"
+// G32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @_ZN34ExplicitlySpecializedClassTemplateIPvE1fEv
+
+//===----------------------------------------------------------------------===//
+// Classes with template base classes
+//===----------------------------------------------------------------------===//
+
+template <typename T> struct ClassTemplate { void func() {} };
+template <typename T> struct __declspec(dllexport) ExportedClassTemplate { void func() {} };
+template <typename T> struct __declspec(dllimport) ImportedClassTemplate { void func() {} };
+
+template <typename T> struct ExplicitlySpecializedTemplate { void func() {} };
+template <> struct ExplicitlySpecializedTemplate<int> { void func() {} };
+template <typename T> struct ExplicitlyExportSpecializedTemplate { void func() {} };
+template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func() {} };
+template <typename T> struct ExplicitlyImportSpecializedTemplate { void func() {} };
+template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func() {} };
+
+template <typename T> struct ExplicitlyInstantiatedTemplate { void func() {} };
+template struct ExplicitlyInstantiatedTemplate<int>;
+template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func() {} };
+template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>;
+template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func() {} };
+template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate<int>;
+
+
+// MS: ClassTemplate<int> gets imported.
+struct __declspec(dllimport) DerivedFromTemplate : public ClassTemplate<int> {};
+USEMEMFUNC(ClassTemplate<int>, func)
+// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$ClassTemplate@H@@QAEXXZ"
+// G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN13ClassTemplateIiE4funcEv
+
+// ImportedTemplate is explicitly imported.
+struct __declspec(dllimport) DerivedFromImportedTemplate : public ImportedClassTemplate<int> {};
+USEMEMFUNC(ImportedClassTemplate<int>, func)
+// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$ImportedClassTemplate@H@@QAEXXZ"
+// G32-DAG: declare dllimport x86_thiscallcc void @_ZN21ImportedClassTemplateIiE4funcEv
+
+// ExportedTemplate is explicitly exported.
+struct __declspec(dllimport) DerivedFromExportedTemplate : public ExportedClassTemplate<int> {};
+USEMEMFUNC(ExportedClassTemplate<int>, func)
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ExportedClassTemplate@H@@QAEXXZ"
+// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN21ExportedClassTemplateIiE4funcEv
+
+// Base class already instantiated without attribute.
+struct DerivedFromTemplateD : public ClassTemplate<double> {};
+struct __declspec(dllimport) DerivedFromTemplateD2 : public ClassTemplate<double> {};
+USEMEMFUNC(ClassTemplate<double>, func)
+// M32-DAG: define linkonce_odr x86_thiscallcc void @"\01?func@?$ClassTemplate@N@@QAEXXZ"
+// G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN13ClassTemplateIdE4funcEv
+
+// MS: Base class already instantiated with dfferent attribute.
+struct __declspec(dllexport) DerivedFromTemplateB : public ClassTemplate<bool> {};
+struct __declspec(dllimport) DerivedFromTemplateB2 : public ClassTemplate<bool> {};
+USEMEMFUNC(ClassTemplate<bool>, func)
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ClassTemplate@_N@@QAEXXZ"
+// G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN13ClassTemplateIbE4funcEv
+
+// Base class already specialized without dll attribute.
+struct __declspec(dllimport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate<int> {};
+USEMEMFUNC(ExplicitlySpecializedTemplate<int>, func)
+// M32-DAG: define linkonce_odr x86_thiscallcc void @"\01?func@?$ExplicitlySpecializedTemplate@H@@QAEXXZ"
+// G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN29ExplicitlySpecializedTemplateIiE4funcEv
+
+// Base class alredy specialized with export attribute.
+struct __declspec(dllimport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {};
+USEMEMFUNC(ExplicitlyExportSpecializedTemplate<int>, func)
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ExplicitlyExportSpecializedTemplate@H@@QAEXXZ"
+// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN35ExplicitlyExportSpecializedTemplateIiE4funcEv
+
+// Base class already specialized with import attribute.
+struct __declspec(dllimport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {};
+USEMEMFUNC(ExplicitlyImportSpecializedTemplate<int>, func)
+// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$ExplicitlyImportSpecializedTemplate@H@@QAEXXZ"
+// G32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @_ZN35ExplicitlyImportSpecializedTemplateIiE4funcEv
+
+// Base class already instantiated without dll attribute.
+struct __declspec(dllimport) DerivedFromExplicitlyInstantiatedTemplate : public ExplicitlyInstantiatedTemplate<int> {};
+USEMEMFUNC(ExplicitlyInstantiatedTemplate<int>, func)
+// M32-DAG: define weak_odr x86_thiscallcc void @"\01?func@?$ExplicitlyInstantiatedTemplate@H@@QAEXXZ"
+// G32-DAG: define weak_odr x86_thiscallcc void @_ZN30ExplicitlyInstantiatedTemplateIiE4funcEv
+
+// Base class already instantiated with export attribute.
+struct __declspec(dllimport) DerivedFromExplicitlyExportInstantiatedTemplate : public ExplicitlyExportInstantiatedTemplate<int> {};
+USEMEMFUNC(ExplicitlyExportInstantiatedTemplate<int>, func)
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ExplicitlyExportInstantiatedTemplate@H@@QAEXXZ"
+// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN36ExplicitlyExportInstantiatedTemplateIiE4funcEv
+
+// Base class already instantiated with import attribute.
+struct __declspec(dllimport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate<int> {};
+USEMEMFUNC(ExplicitlyImportInstantiatedTemplate<int>, func)
+// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$ExplicitlyImportInstantiatedTemplate@H@@QAEXXZ"
+// G32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @_ZN36ExplicitlyImportInstantiatedTemplateIiE4funcEv
+
+// MS: A dll attribute propagates through multiple levels of instantiation.
+template <typename T> struct TopClass { void func() {} };
+template <typename T> struct MiddleClass : public TopClass<T> { };
+struct __declspec(dllimport) BottomClass : public MiddleClass<int> { };
+USEMEMFUNC(TopClass<int>, func)
+// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?func@?$TopClass@H@@QAEXXZ"
+// G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN8TopClassIiE4funcEv
diff --git a/test/CodeGenCXX/duplicate-mangled-name.cpp b/test/CodeGenCXX/duplicate-mangled-name.cpp
new file mode 100644
index 0000000..65bfa22
--- /dev/null
+++ b/test/CodeGenCXX/duplicate-mangled-name.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm-only %s -verify
+
+// rdar://15522601
+class MyClass {
+ static void meth();
+};
+void MyClass::meth() { }
+extern "C" {
+  void _ZN7MyClass4methEv() { } // expected-error {{definition with same mangled name as another definition}}
+}
diff --git a/test/CodeGenCXX/dynamic_cast-no-rtti.cpp b/test/CodeGenCXX/dynamic_cast-no-rtti.cpp
index 0e26de5..cde03a3 100644
--- a/test/CodeGenCXX/dynamic_cast-no-rtti.cpp
+++ b/test/CodeGenCXX/dynamic_cast-no-rtti.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -verify -fno-rtti -o - | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm %s -verify -fno-rtti -triple %itanium_abi_triple -o - | FileCheck %s
 // expected-no-diagnostics
 
 struct A {
diff --git a/test/CodeGenCXX/eh.cpp b/test/CodeGenCXX/eh.cpp
index 2a61e61..cb07697 100644
--- a/test/CodeGenCXX/eh.cpp
+++ b/test/CodeGenCXX/eh.cpp
@@ -34,7 +34,7 @@
 // CHECK-NEXT:  [[SELECTORVAR:%.*]] = alloca i32
 // CHECK-NEXT:  [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 16)
 // CHECK-NEXT:  [[EXN:%.*]] = bitcast i8* [[EXNOBJ]] to [[DSTAR:%[^*]*\*]]
-// CHECK-NEXT:  invoke void @_ZN7test2_DC1ERKS_([[DSTAR]] [[EXN]], [[DSTAR]] @d2)
+// CHECK-NEXT:  invoke void @_ZN7test2_DC1ERKS_([[DSTAR]] [[EXN]], [[DSTAR]] dereferenceable({{[0-9]+}}) @d2)
 // CHECK-NEXT:     to label %[[CONT:.*]] unwind label %{{.*}}
 //      :     [[CONT]]:   (can't check this in Release-Asserts builds)
 // CHECK:       call void @__cxa_throw(i8* [[EXNOBJ]], i8* bitcast ({{.*}}* @_ZTI7test2_D to i8*), i8* null) [[NR]]
@@ -184,9 +184,6 @@
 
   struct A { A(); };
 
-  // CHECK-LABEL:      define void @_ZN5test91AC1Ev(%"struct.test9::A"* %this) unnamed_addr
-  // CHECK:      call void @_ZN5test91AC2Ev
-  // CHECK-NEXT: ret void
 
   // CHECK-LABEL: define void @_ZN5test91AC2Ev(%"struct.test9::A"* %this) unnamed_addr
   A::A() try {
@@ -199,6 +196,10 @@
   // CHECK:      call i8* @__cxa_begin_catch
   // CHECK:      invoke void @_ZN5test96opaqueEv()
   // CHECK:      invoke void @__cxa_rethrow()
+
+  // CHECK-LABEL:      define void @_ZN5test91AC1Ev(%"struct.test9::A"* %this) unnamed_addr
+  // CHECK:      call void @_ZN5test91AC2Ev
+  // CHECK-NEXT: ret void
     opaque();
   }
 }
@@ -427,7 +428,7 @@
     // CHECK-NEXT: [[T0:%.*]] = bitcast i8* [[EXN]] to [[B:%.*]]*
     // CHECK-NEXT: invoke void @_ZN6test161AC1Ev([[A]]* [[TEMP]])
     // CHECK:      store i1 true, i1* [[TEMP_ACTIVE]]
-    // CHECK-NEXT: invoke void @_ZN6test161BC1ERKNS_1AE([[B]]* [[T0]], [[A]]* [[TEMP]])
+    // CHECK-NEXT: invoke void @_ZN6test161BC1ERKNS_1AE([[B]]* [[T0]], [[A]]* dereferenceable({{[0-9]+}}) [[TEMP]])
     // CHECK:      store i1 false, i1* [[EXN_ACTIVE]]
     // CHECK-NEXT: invoke void @__cxa_throw(i8* [[EXN]],
 
diff --git a/test/CodeGenCXX/elide-call-reference.cpp b/test/CodeGenCXX/elide-call-reference.cpp
index 55d30e2..0ce856f 100644
--- a/test/CodeGenCXX/elide-call-reference.cpp
+++ b/test/CodeGenCXX/elide-call-reference.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o - | FileCheck %s
 // PR5695
 
 struct A { A(const A&); ~A(); };
diff --git a/test/CodeGenCXX/empty-nontrivially-copyable.cpp b/test/CodeGenCXX/empty-nontrivially-copyable.cpp
index 9ee3281..a0977a7 100644
--- a/test/CodeGenCXX/empty-nontrivially-copyable.cpp
+++ b/test/CodeGenCXX/empty-nontrivially-copyable.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -triple armv7-apple-ios -x c++ -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-apple-ios -x c++ -emit-llvm -o - %s | FileCheck %s
 
 // According to the Itanium ABI (3.1.1), types with non-trivial copy
 // constructors passed by value should be passed indirectly, with the caller
@@ -18,7 +19,7 @@
 }
 
 void caller(Empty &e) {
-// CHECK: @_Z6callerR5Empty(%struct.Empty* %e)
+// CHECK: @_Z6callerR5Empty(%struct.Empty* dereferenceable({{[0-9]+}}) %e)
 // CHECK: call {{.*}} @_ZN5EmptyC1ERKS_(%struct.Empty* [[NEWTMP:%.*]], %struct.Empty*
 // CHECK: call {{.*}} @_Z3foo5Empty(%struct.Empty* [[NEWTMP]])
   foo(e);
diff --git a/test/CodeGenCXX/enable_if.cpp b/test/CodeGenCXX/enable_if.cpp
new file mode 100644
index 0000000..00c55c7
--- /dev/null
+++ b/test/CodeGenCXX/enable_if.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-pc-linux-gnu| FileCheck %s
+// Test itanium mangling for attribute enable_if
+
+// CHECK: _Z5test1Ua9enable_ifIXeqfL0p_Li1EEEi
+void test1(int i) __attribute__((enable_if(i == 1, ""))) {}
+
+void ext();
+// CHECK: _Z5test2Ua9enable_ifIXneadL_Z3extvELi0EEEi
+void test2(int i) __attribute__((enable_if(&ext != 0, ""))) {}
+
+// CHECK: _Z5test3Ua9enable_ifIXeqfL0p_Li1EEXeqfL0p0_Li2EEEii
+void test3(int i, int j) __attribute__((enable_if(i == 1, ""), enable_if(j == 2, ""))) {}
+
+// CHECK: _ZN5test4IdE1fEUa9enable_ifIXeqfL0p_Li1EEXeqfL0p0_Li2EEEi
+template <typename T>
+class test4 {
+  virtual void f(int i, int j) __attribute__((enable_if(i == 1, ""))) __attribute__((enable_if(j == 2, "")));
+};
+
+template class test4<double>;
diff --git a/test/CodeGenCXX/exceptions-no-rtti.cpp b/test/CodeGenCXX/exceptions-no-rtti.cpp
index 902d6ac..e1ef4f1 100644
--- a/test/CodeGenCXX/exceptions-no-rtti.cpp
+++ b/test/CodeGenCXX/exceptions-no-rtti.cpp
@@ -1,10 +1,10 @@
 // RUN: %clang_cc1 -fno-rtti -fcxx-exceptions -fexceptions %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
 
-// CHECK: @_ZTIN5test11AE = linkonce_odr unnamed_addr constant
-// CHECK: @_ZTIN5test11BE = linkonce_odr unnamed_addr constant
-// CHECK: @_ZTIN5test11CE = linkonce_odr unnamed_addr constant
-// CHECK: @_ZTIN5test11DE = linkonce_odr unnamed_addr constant
-// CHECK: @_ZTIPN5test11DE = linkonce_odr unnamed_addr constant {{.*}} @_ZTIN5test11DE
+// CHECK: @_ZTIN5test11AE = linkonce_odr constant
+// CHECK: @_ZTIN5test11BE = linkonce_odr constant
+// CHECK: @_ZTIN5test11CE = linkonce_odr constant
+// CHECK: @_ZTIN5test11DE = linkonce_odr constant
+// CHECK: @_ZTIPN5test11DE = linkonce_odr constant {{.*}} @_ZTIN5test11DE
 
 // PR6974: this shouldn't crash
 namespace test0 {
diff --git a/test/CodeGenCXX/exceptions.cpp b/test/CodeGenCXX/exceptions.cpp
index d37e610..5016e9a 100644
--- a/test/CodeGenCXX/exceptions.cpp
+++ b/test/CodeGenCXX/exceptions.cpp
@@ -279,7 +279,7 @@
   // CHECK-NEXT: [[ADJ:%.*]] = call i8* @__cxa_get_exception_ptr(i8* [[EXN]])
   // CHECK-NEXT: [[SRC:%.*]] = bitcast i8* [[ADJ]] to [[A_T]]*
   // CHECK-NEXT: invoke void @_ZN5test51TC1Ev([[T_T]]* [[T]])
-  // CHECK:      invoke void @_ZN5test51AC1ERKS0_RKNS_1TE([[A_T]]* [[A]], [[A_T]]* [[SRC]], [[T_T]]* [[T]])
+  // CHECK:      invoke void @_ZN5test51AC1ERKS0_RKNS_1TE([[A_T]]* [[A]], [[A_T]]* 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]])
diff --git a/test/CodeGenCXX/explicit-instantiation.cpp b/test/CodeGenCXX/explicit-instantiation.cpp
index 6a4fd82..5bd0678 100644
--- a/test/CodeGenCXX/explicit-instantiation.cpp
+++ b/test/CodeGenCXX/explicit-instantiation.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -emit-llvm -triple i686-pc-linux-gnu -o - %s | FileCheck %s
+// 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
 
 // This check logically is attached to 'template int S<int>::i;' below.
 // CHECK: @_ZN1SIiE1iE = weak_odr global i32
@@ -16,6 +17,79 @@
 // CHECK-LABEL: define weak_odr i32 @_ZNK4plusIillEclERKiRKl
 template struct plus<int, long, long>;
 
+namespace EarlyInstantiation {
+  // Check that we emit definitions if we instantiate a function definition before
+  // it gets explicitly instantiatied.
+  template<typename T> struct S {
+    constexpr int constexpr_function() { return 0; }
+    auto deduced_return_type() { return 0; }
+  };
+
+  // From an implicit instantiation.
+  constexpr int a = S<char>().constexpr_function();
+  int b = S<char>().deduced_return_type();
+
+  // From an explicit instantiation declaration.
+  extern template struct S<int>;
+  constexpr int c = S<int>().constexpr_function();
+  int d = S<int>().deduced_return_type();
+
+  // CHECK: define weak_odr i32 @_ZN18EarlyInstantiation1SIcE18constexpr_functionEv(
+  // CHECK: define weak_odr i32 @_ZN18EarlyInstantiation1SIcE19deduced_return_typeEv(
+  // CHECK: define weak_odr i32 @_ZN18EarlyInstantiation1SIiE18constexpr_functionEv(
+  // CHECK: define weak_odr i32 @_ZN18EarlyInstantiation1SIiE19deduced_return_typeEv(
+  template struct S<char>;
+  template struct S<int>;
+
+  template<typename T> constexpr int constexpr_function() { return 0; }
+  template<typename T> auto deduced_return_type() { return 0; }
+
+  // From an implicit instantiation.
+  constexpr int e = constexpr_function<char>();
+  int f = deduced_return_type<char>();
+
+  // From an explicit instantiation declaration.
+  extern template int constexpr_function<int>();
+  extern template auto deduced_return_type<int>();
+  constexpr int g = constexpr_function<int>();
+  int h = deduced_return_type<int>();
+
+  // The FIXMEs below are for PR19551.
+  // CHECK: define weak_odr i32 @_ZN18EarlyInstantiation18constexpr_functionIcEEiv(
+  // FIXME: define weak_odr i32 @_ZN18EarlyInstantiation19deduced_return_typeIcEEiv(
+  // CHECK: define weak_odr i32 @_ZN18EarlyInstantiation18constexpr_functionIiEEiv(
+  // FIXME: define weak_odr i32 @_ZN18EarlyInstantiation19deduced_return_typeIiEEiv(
+  template int constexpr_function<char>();
+  // FIXME template auto deduced_return_type<char>();
+  template int constexpr_function<int>();
+  // FIXME template auto deduced_return_type<int>();
+}
+
+namespace LateInstantiation {
+  // Check that we downgrade the linkage to available_externally if we see an
+  // explicit instantiation declaration after the function template is
+  // instantiated.
+  template<typename T> struct S { constexpr int f() { return 0; } };
+  template<typename T> constexpr int f() { return 0; }
+
+  // Trigger eager instantiation of the function definitions.
+  int a, b = S<char>().f() + f<char>() + a;
+  int c, d = S<int>().f() + f<int>() + a;
+
+  // Don't allow some of those definitions to be emitted.
+  extern template struct S<int>;
+  extern template int f<int>();
+
+  // Check that we declare, define, or provide an available-externally
+  // definition as appropriate.
+  // CHECK: define linkonce_odr i32 @_ZN17LateInstantiation1SIcE1fEv(
+  // CHECK: define linkonce_odr i32 @_ZN17LateInstantiation1fIcEEiv(
+  // CHECK-NO-OPT: declare i32 @_ZN17LateInstantiation1SIiE1fEv(
+  // CHECK-NO-OPT: declare i32 @_ZN17LateInstantiation1fIiEEiv(
+  // CHECK-OPT: define available_externally i32 @_ZN17LateInstantiation1SIiE1fEv(
+  // CHECK-OPT: define available_externally i32 @_ZN17LateInstantiation1fIiEEiv(
+}
+
 // Check that we emit definitions from explicit instantiations even when they
 // occur prior to the definition itself.
 template <typename T> struct S {
diff --git a/test/CodeGenCXX/extern-c.cpp b/test/CodeGenCXX/extern-c.cpp
index 5899b93..fefb216 100644
--- a/test/CodeGenCXX/extern-c.cpp
+++ b/test/CodeGenCXX/extern-c.cpp
@@ -1,18 +1,21 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
 namespace foo {
 
-// CHECK-NOT: @a = global i32
+// CHECK-NOT: @a = global
 extern "C" int a;
 
-// CHECK-NOT: @_ZN3foo1bE = global i32
+// CHECK-NOT: @_ZN3foo1bE = global
 extern int b;
 
-// CHECK: @_ZN3foo1cE = global i32
+// CHECK: @_ZN3foo1cE = global
 int c = 5;
 
 // CHECK-NOT: @_ZN3foo1dE
 extern "C" struct d;
 
+// CHECK-NOT: should_not_appear
+extern "C++" int should_not_appear;
+
 }
 
 namespace test1 {
@@ -63,3 +66,10 @@
   // CHECK-NOT: @unused
   // CHECK-NOT: @duplicate_internal
 }
+
+namespace PR19411 {
+  struct A { void f(); };
+  extern "C" void A::f() { void g(); g(); }
+  // CHECK-LABEL: @_ZN7PR194111A1fEv(
+  // CHECK: call void @g()
+}
diff --git a/test/CodeGenCXX/fastcall.cpp b/test/CodeGenCXX/fastcall.cpp
index 0326ce5..0820324 100644
--- a/test/CodeGenCXX/fastcall.cpp
+++ b/test/CodeGenCXX/fastcall.cpp
@@ -3,7 +3,7 @@
 void __attribute__((fastcall)) foo1(int &y);
 void bar1(int &y) {
   // CHECK-LABEL: define void @_Z4bar1Ri
-  // CHECK: call x86_fastcallcc void @_Z4foo1Ri(i32* inreg %
+  // CHECK: call x86_fastcallcc void @_Z4foo1Ri(i32* inreg dereferenceable({{[0-9]+}}) %
   foo1(y);
 }
 
diff --git a/test/CodeGenCXX/field-access-debug-info.cpp b/test/CodeGenCXX/field-access-debug-info.cpp
index fd899ed..aed4ee5 100644
--- a/test/CodeGenCXX/field-access-debug-info.cpp
+++ b/test/CodeGenCXX/field-access-debug-info.cpp
@@ -1,8 +1,7 @@
-// RUN: %clang_cc1 -g -S -masm-verbose -o - %s | FileCheck %s
+// RUN: %clang -g -S -emit-llvm %s -o - | FileCheck %s
 
-// CHECK: abbrev_begin:
-// CHECK: DW_AT_accessibility
-// CHECK-NEXT: DW_FORM_data1
+// CHECK: [ DW_TAG_member ] [p] [{{[^]]*}}] [from int]
+// CHECK: [ DW_TAG_member ] [pr] [{{[^]]*}}] [private] [from int]
 
 class A {
 public:
diff --git a/test/CodeGenCXX/flatten.cpp b/test/CodeGenCXX/flatten.cpp
new file mode 100644
index 0000000..9e0f67f
--- /dev/null
+++ b/test/CodeGenCXX/flatten.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -triple=x86_64-linux-gnu -std=c++11 %s -emit-llvm -o - | FileCheck %s
+
+void f(void) {}
+
+[[gnu::flatten]]
+// CHECK: define void @_Z1gv()
+void g(void) {
+  // CHECK-NOT: call {{.*}} @_Z1fv
+  f();
+}
diff --git a/test/CodeGenCXX/funcsig.cpp b/test/CodeGenCXX/funcsig.cpp
new file mode 100644
index 0000000..684a796
--- /dev/null
+++ b/test/CodeGenCXX/funcsig.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -std=c++11 -triple i686-pc-win32 %s -fms-extensions -fno-rtti -emit-llvm -o - | FileCheck %s
+
+// Similar to predefined-expr.cpp, but not as exhaustive, since it's basically
+// equivalent to __PRETTY_FUNCTION__.
+
+extern "C" int printf(const char *, ...);
+
+void freeFunc(int *, char) {
+  printf("__FUNCSIG__ %s\n\n", __FUNCSIG__);
+}
+// CHECK: private unnamed_addr constant [{{.*}} x i8] c"void __cdecl freeFunc(int *, char)\00"
+
+struct TopLevelClass {
+  void topLevelMethod(int *, char);
+};
+void TopLevelClass::topLevelMethod(int *, char) {
+  printf("__FUNCSIG__ %s\n\n", __FUNCSIG__);
+}
+// CHECK: private unnamed_addr constant [{{.*}} x i8] c"void __thiscall TopLevelClass::topLevelMethod(int *, char)\00"
+
+namespace NS {
+struct NamespacedClass {
+  void namespacedMethod(int *, char);
+};
+void NamespacedClass::namespacedMethod(int *, char) {
+  printf("__FUNCSIG__ %s\n\n", __FUNCSIG__);
+}
+// CHECK: private unnamed_addr constant [{{.*}} x i8] c"void __thiscall NS::NamespacedClass::namespacedMethod(int *, char)\00"
+}
diff --git a/test/CodeGenCXX/function-template-explicit-specialization.cpp b/test/CodeGenCXX/function-template-explicit-specialization.cpp
index 5d26dcd..8ff0655 100644
--- a/test/CodeGenCXX/function-template-explicit-specialization.cpp
+++ b/test/CodeGenCXX/function-template-explicit-specialization.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple %s -o - | FileCheck %s
 
 template<typename T> void a(T);
 template<> void a(int) {}
diff --git a/test/CodeGenCXX/function-template-specialization.cpp b/test/CodeGenCXX/function-template-specialization.cpp
index 4a79fb1..eb099df 100644
--- a/test/CodeGenCXX/function-template-specialization.cpp
+++ b/test/CodeGenCXX/function-template-specialization.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple %s -o - | FileCheck %s
 template<typename T, typename U>
 T* next(T* ptr, const U& diff);
 
diff --git a/test/CodeGenCXX/global-array-destruction.cpp b/test/CodeGenCXX/global-array-destruction.cpp
index 6ebc139..0397851 100644
--- a/test/CodeGenCXX/global-array-destruction.cpp
+++ b/test/CodeGenCXX/global-array-destruction.cpp
@@ -56,7 +56,7 @@
 U &&u = U{ {{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 ({{.*}}* getelementptr inbounds ([2 x [3 x {{.*}}]]* @_ZGR1u, i32 0, i32 0, i32 0), i64 6)
+// CHECK: getelementptr inbounds ({{.*}}* getelementptr inbounds ([2 x [3 x {{.*}}]]* @_ZGR1u_, i32 0, i32 0, i32 0), i64 6)
 // CHECK: call void @_ZN1TD1Ev
-// CHECK: icmp eq {{.*}} @_ZGR1u
+// CHECK: icmp eq {{.*}} @_ZGR1u_
 // CHECK: br i1 {{.*}}
diff --git a/test/CodeGenCXX/global-init.cpp b/test/CodeGenCXX/global-init.cpp
index 69631c2..9c5b03a 100644
--- a/test/CodeGenCXX/global-init.cpp
+++ b/test/CodeGenCXX/global-init.cpp
@@ -12,7 +12,7 @@
 
 struct D { ~D(); };
 
-// CHECK: @__dso_handle = external unnamed_addr global i8
+// CHECK: @__dso_handle = external global i8
 // CHECK: @c = global %struct.C zeroinitializer, align 8
 
 // It's okay if we ever implement the IR-generation optimization to remove this.
@@ -195,11 +195,11 @@
 // CHECK-NEXT:   sub
 // CHECK-NEXT:   store i32 {{.*}}, i32* @_ZN5test1L1yE
 
-// CHECK: define internal void @_GLOBAL__I_a() section "__TEXT,__StaticInit,regular,pure_instructions" {
+// CHECK: define internal void @_GLOBAL__sub_I_global_init.cpp() section "__TEXT,__StaticInit,regular,pure_instructions" {
 // CHECK:   call void [[TEST1_Y_INIT]]
 // CHECK:   call void [[TEST1_Z_INIT]]
 
 // rdar://problem/8090834: this should be nounwind
-// CHECK-NOEXC: define internal void @_GLOBAL__I_a() [[NUW:#[0-9]+]] section "__TEXT,__StaticInit,regular,pure_instructions" {
+// 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 }
diff --git a/test/CodeGenCXX/global-llvm-constant.cpp b/test/CodeGenCXX/global-llvm-constant.cpp
index 2bd43b9..55933ee 100644
--- a/test/CodeGenCXX/global-llvm-constant.cpp
+++ b/test/CodeGenCXX/global-llvm-constant.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -o - %s | FileCheck %s
 
 struct A {
   A() { x = 10; }
diff --git a/test/CodeGenCXX/globalinit-loc.cpp b/test/CodeGenCXX/globalinit-loc.cpp
new file mode 100644
index 0000000..eb39aec
--- /dev/null
+++ b/test/CodeGenCXX/globalinit-loc.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -emit-llvm -g %s -o - | FileCheck %s
+// rdar://problem/14985269.
+//
+// Verify that the global init helper function does not get associated
+// with any source location.
+//
+// CHECK: define internal void @_GLOBAL__sub_I_globalinit_loc.cpp
+// CHECK: !dbg ![[DBG:.*]]
+// CHECK: "_GLOBAL__sub_I_globalinit_loc.cpp", i32 0, {{.*}}, i32 0} ; [ DW_TAG_subprogram ] [line 0] [local] [def]
+// CHECK: ![[DBG]] = metadata !{i32 0, i32 0,
+# 99 "someheader.h"
+class A {
+public:
+  A();
+  int foo() { return 0; }
+};
+# 5 "main.cpp"
+A a;
+
+int f() {
+  return a.foo();
+}
+
diff --git a/test/CodeGenCXX/goto.cpp b/test/CodeGenCXX/goto.cpp
index 904f95f..c1a0eec 100644
--- a/test/CodeGenCXX/goto.cpp
+++ b/test/CodeGenCXX/goto.cpp
@@ -22,7 +22,7 @@
     // CHECK:      store i1 true, i1* [[CLEANUPACTIVE]]
     // CHECK:      [[NEWCAST:%.*]] = bitcast i8* [[NEW]] to [[V]]*
     // CHECK-NEXT: invoke void @_ZN5test01AC1Ev([[A]]* [[TMP]])
-    // CHECK:      invoke void @_ZN5test01VC1ERKNS_1AE([[V]]* [[NEWCAST]], [[A]]* [[TMP]])
+    // CHECK:      invoke void @_ZN5test01VC1ERKNS_1AE([[V]]* [[NEWCAST]], [[A]]* dereferenceable({{[0-9]+}}) [[TMP]])
     // CHECK:      store i1 false, i1* [[CLEANUPACTIVE]]
     // CHECK-NEXT: invoke void @_ZN5test01AD1Ev([[A]]* [[TMP]])
     A y;
diff --git a/test/CodeGenCXX/implicit-copy-assign-operator.cpp b/test/CodeGenCXX/implicit-copy-assign-operator.cpp
index 2674021..fded035 100644
--- a/test/CodeGenCXX/implicit-copy-assign-operator.cpp
+++ b/test/CodeGenCXX/implicit-copy-assign-operator.cpp
@@ -40,7 +40,7 @@
   d1 = d2;
 }
 
-// CHECK-LABEL: define linkonce_odr %struct.D* @_ZN1DaSERS_
+// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.D* @_ZN1DaSERS_
 // CHECK: {{call.*_ZN1AaSERS_}}
 // CHECK: {{call.*_ZN1BaSERS_}}
 // CHECK: {{call.*_ZN1CaSERKS_}}
@@ -53,4 +53,3 @@
 // CHECK: call void @_ZN11CopyByValueC1ERKS_
 // CHECK: {{call.*_ZN11CopyByValueaSES_}}
 // CHECK: ret
-
diff --git a/test/CodeGenCXX/implicit-copy-constructor.cpp b/test/CodeGenCXX/implicit-copy-constructor.cpp
index bb04318..d022413 100644
--- a/test/CodeGenCXX/implicit-copy-constructor.cpp
+++ b/test/CodeGenCXX/implicit-copy-constructor.cpp
@@ -40,7 +40,7 @@
   D d2(d);
 }
 
-// CHECK-LABEL: define linkonce_odr void @_ZN1DC1ERS_(%struct.D* %this, %struct.D*) unnamed_addr
+// CHECK-LABEL: define linkonce_odr void @_ZN1DC1ERS_(%struct.D* %this, %struct.D* dereferenceable({{[0-9]+}})) unnamed_addr
 // CHECK: call void @_ZN1AC1Ev
 // CHECK: call void @_ZN1CC2ERS_1A
 // CHECK: call void @_ZN1AD1Ev
diff --git a/test/CodeGenCXX/implicit-instantiation-1.cpp b/test/CodeGenCXX/implicit-instantiation-1.cpp
index bf6a141..c3c49c3 100644
--- a/test/CodeGenCXX/implicit-instantiation-1.cpp
+++ b/test/CodeGenCXX/implicit-instantiation-1.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -o %t
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple %s -o %t
 
 template<typename T>
 struct X {
diff --git a/test/CodeGenCXX/inheriting-constructor.cpp b/test/CodeGenCXX/inheriting-constructor.cpp
index c99a20c..9394137 100644
--- a/test/CodeGenCXX/inheriting-constructor.cpp
+++ b/test/CodeGenCXX/inheriting-constructor.cpp
@@ -11,9 +11,9 @@
 struct D : C { using C::C; };
 D d(123);
 
-// CHECK-LABEL: define void @_ZN1BD0Ev
-// CHECK-LABEL: define void @_ZN1BD1Ev
 // CHECK-LABEL: define void @_ZN1BD2Ev
+// CHECK-LABEL: define void @_ZN1BD1Ev
+// CHECK-LABEL: define void @_ZN1BD0Ev
 
 // CHECK-LABEL: define linkonce_odr void @_ZN1BC1Ei(
 // CHECK: call void @_ZN1BC2Ei(
diff --git a/test/CodeGenCXX/init-priority-attr.cpp b/test/CodeGenCXX/init-priority-attr.cpp
index ef9343c..ff155d0 100644
--- a/test/CodeGenCXX/init-priority-attr.cpp
+++ b/test/CodeGenCXX/init-priority-attr.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
-// PR
+// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -O2 -emit-llvm -o - | FileCheck %s
+// PR11480
 
 void foo(int);
 
@@ -27,18 +27,24 @@
 
 A C::a = A();
 
-// CHECK: @llvm.global_ctors = appending global [3 x { i32, void ()* }] [{ i32, void ()* } { i32 200, void ()* @_GLOBAL__I_000200 }, { i32, void ()* } { i32 300, void ()* @_GLOBAL__I_000300 }, { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_a }]
+// CHECK: @llvm.global_ctors = appending global [3 x { i32, void ()*, i8* }]
+// CHECK: [{ i32, void ()*, i8* } { i32 200, void ()* @_GLOBAL__I_000200, i8* null },
+// CHECK:  { i32, void ()*, i8* } { i32 300, void ()* @_GLOBAL__I_000300, i8* null },
+// CHECK:  { i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_init_priority_attr.cpp, i8* null }]
 
 // CHECK: _GLOBAL__I_000200()
-// CHECK_NEXT: _Z3fooi(i32 3)
+// CHECK: _Z3fooi(i32 3)
+// CHECK-NEXT: ret void
 
 // CHECK: _GLOBAL__I_000300()
-// CHECK_NEXT: _Z3fooi(i32 2)
-// CHECK_NEXT: _Z3fooi(i32 1)
+// CHECK: _Z3fooi(i32 2)
+// CHECK-NEXT: _Z3fooi(i32 1)
+// CHECK-NEXT: ret void
 
-// CHECK: _GLOBAL__I_a()
-// CHECK_NEXT: _Z3fooi(i32 1)
-// CHECK_NEXT: _Z3fooi(i32 4)
+// CHECK: _GLOBAL__sub_I_init_priority_attr.cpp()
+// CHECK: _Z3fooi(i32 1)
+// CHECK-NEXT: _Z3fooi(i32 4)
+// CHECK-NEXT: ret void
 
 C c;
 A1 a1 __attribute__((init_priority (300)));
diff --git a/test/CodeGenCXX/inline-functions.cpp b/test/CodeGenCXX/inline-functions.cpp
index 9f8e536..622cfa9 100644
--- a/test/CodeGenCXX/inline-functions.cpp
+++ b/test/CodeGenCXX/inline-functions.cpp
@@ -1,11 +1,12 @@
-// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s --check-prefix=CHECK --check-prefix=NORMAL
+// RUN: %clang_cc1 %s -std=c++11 -fms-compatibility -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s --check-prefix=CHECK --check-prefix=MSVCCOMPAT
 // CHECK: ; ModuleID 
 
 struct A {
     inline void f();
 };
 
-// CHECK-NOT-LABEL: define void @_ZN1A1fEv
+// CHECK-NOT: define void @_ZN1A1fEv
 void A::f() { }
 
 template<typename> struct B { };
@@ -67,3 +68,56 @@
   }
   // CHECK-LABEL: define linkonce_odr void @_ZN5test21fERKNS_1AE
 }
+
+// MSVCCOMPAT-LABEL: define weak_odr void @_Z17ExternAndInlineFnv
+// NORMAL-NOT: _Z17ExternAndInlineFnv
+extern inline void ExternAndInlineFn() {}
+
+// MSVCCOMPAT-LABEL: define weak_odr void @_Z18InlineThenExternFnv
+// NORMAL-NOT: _Z18InlineThenExternFnv
+inline void InlineThenExternFn() {}
+extern void InlineThenExternFn();
+
+// CHECK-LABEL: define void @_Z18ExternThenInlineFnv
+extern void ExternThenInlineFn() {}
+
+// MSVCCOMPAT-LABEL: define weak_odr void @_Z25ExternThenInlineThenDefFnv
+// NORMAL-NOT: _Z25ExternThenInlineThenDefFnv
+extern void ExternThenInlineThenDefFn();
+inline void ExternThenInlineThenDefFn();
+void ExternThenInlineThenDefFn() {}
+
+// MSVCCOMPAT-LABEL: define weak_odr void @_Z25InlineThenExternThenDefFnv
+// NORMAL-NOT: _Z25InlineThenExternThenDefFnv
+inline void InlineThenExternThenDefFn();
+extern void InlineThenExternThenDefFn();
+void InlineThenExternThenDefFn() {}
+
+// MSVCCOMPAT-LABEL: define weak_odr i32 @_Z20ExternAndConstexprFnv
+// NORMAL-NOT: _Z17ExternAndConstexprFnv
+extern constexpr int ExternAndConstexprFn() { return 0; }
+
+// CHECK-NOT: _Z11ConstexprFnv
+constexpr int ConstexprFn() { return 0; }
+
+template <typename T>
+extern inline void ExternInlineOnPrimaryTemplate(T);
+
+// CHECK-LABEL: define void @_Z29ExternInlineOnPrimaryTemplateIiEvT_
+template <>
+void ExternInlineOnPrimaryTemplate(int) {}
+
+template <typename T>
+extern inline void ExternInlineOnPrimaryTemplateAndSpecialization(T);
+
+// MSVCCOMPAT-LABEL: define weak_odr void @_Z46ExternInlineOnPrimaryTemplateAndSpecializationIiEvT_
+// NORMAL-NOT: _Z46ExternInlineOnPrimaryTemplateAndSpecializationIiEvT_
+template <>
+extern inline void ExternInlineOnPrimaryTemplateAndSpecialization(int) {}
+
+struct TypeWithInlineMethods {
+  // CHECK-NOT: _ZN21TypeWithInlineMethods9StaticFunEv
+  static void StaticFun() {}
+  // CHECK-NOT: _ZN21TypeWithInlineMethods12NonStaticFunEv
+  void NonStaticFun() { StaticFun(); }
+};
diff --git a/test/CodeGenCXX/instrument-functions.cpp b/test/CodeGenCXX/instrument-functions.cpp
index 253e096..587b638 100644
--- a/test/CodeGenCXX/instrument-functions.cpp
+++ b/test/CodeGenCXX/instrument-functions.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -S -emit-llvm -o - %s -finstrument-functions | FileCheck %s
+// RUN: %clang_cc1 -S -emit-llvm -triple %itanium_abi_triple -o - %s -finstrument-functions | FileCheck %s
 
 // CHECK: @_Z5test1i
 int test1(int x) {
diff --git a/test/CodeGenCXX/int64_uint64.cpp b/test/CodeGenCXX/int64_uint64.cpp
new file mode 100644
index 0000000..aad6ea0
--- /dev/null
+++ b/test/CodeGenCXX/int64_uint64.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple arm-linux-guneabi \
+// RUN:   -target-cpu cortex-a8 \
+// RUN:   -emit-llvm -w -O1 -o - %s | FileCheck --check-prefix=CHECK-ARM %s
+
+// RUN: %clang_cc1 -triple arm64-linux-gnueabi \
+// RUN:   -target-feature +neon \
+// RUN:   -emit-llvm -w -O1 -o - %s | FileCheck --check-prefix=CHECK-AARCH64 %s
+
+// Test if int64_t and uint64_t can be correctly mangled.
+
+#include "arm_neon.h"
+// CHECK-ARM: f1x(
+// CHECK-AARCH64: f1l(
+void f1(int64_t a) {}
+// CHECK-ARM: f2y(
+// CHECK-AARCH64: f2m(
+void f2(uint64_t a) {}
+// CHECK-ARM: f3Px(
+// CHECK-AARCH64: f3Pl(
+void f3(int64_t *ptr) {}
+// CHECK-ARM: f4Py(
+// CHECK-AARCH64: f4Pm(
+void f4(uint64_t *ptr) {}
diff --git a/test/CodeGenCXX/internal-linkage.cpp b/test/CodeGenCXX/internal-linkage.cpp
index 56cb810..77b1670 100644
--- a/test/CodeGenCXX/internal-linkage.cpp
+++ b/test/CodeGenCXX/internal-linkage.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -o - %s | FileCheck %s
 
 struct Global { Global(); };
 template<typename T> struct X { X() {} };
diff --git a/test/CodeGenCXX/linetable-cleanup.cpp b/test/CodeGenCXX/linetable-cleanup.cpp
index 96b8572..ce7f2c6 100644
--- a/test/CodeGenCXX/linetable-cleanup.cpp
+++ b/test/CodeGenCXX/linetable-cleanup.cpp
@@ -46,12 +46,14 @@
 void baz()
 {
   if (!foo())
-    // CHECK: {{.*}} = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null}
+    // CHECK: ![[SCOPE1:.*]] = metadata !{{{.*}}, i32 [[@LINE-1]], {{.*}}} ; [ DW_TAG_lexical_block ]
+    // CHECK: {{.*}} = metadata !{i32 [[@LINE+1]], i32 0, metadata ![[SCOPE1]], null}
     return;
 
   if (foo()) {
     // no cleanup
-    // CHECK: {{.*}} = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null}
+    // CHECK: {{.*}} = metadata !{i32 [[@LINE+2]], i32 0, metadata ![[SCOPE2:.*]], null}
+    // CHECK: ![[SCOPE2]] = metadata !{{{.*}}, i32 [[@LINE-3]], {{.*}}} ; [ DW_TAG_lexical_block ]
     return;
   }
   // CHECK: ![[RETBAZ]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null}
diff --git a/test/CodeGenCXX/linetable-eh.cpp b/test/CodeGenCXX/linetable-eh.cpp
new file mode 100644
index 0000000..14a5067
--- /dev/null
+++ b/test/CodeGenCXX/linetable-eh.cpp
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -emit-llvm -g -triple x86_64-apple-macosx10.9.0 -munwind-tables -std=c++11 -fcxx-exceptions -fexceptions %s -o - | FileCheck %s
+
+// Test that emitting a landing pad does not affect the line table
+// entries for the code that triggered it.
+
+// CHECK: call void @llvm.dbg.declare
+// CHECK: call void @llvm.dbg.declare(metadata !{{{.*}}}, metadata ![[CURRENT_ADDR:.*]]), !dbg ![[DBG1:.*]]
+// CHECK: unwind label %{{.*}}, !dbg ![[DBG1]]
+// CHECK: store i64 %{{.*}}, i64* %current_address, align 8, !dbg ![[DBG4:.*]]
+// CHECK-NEXT: call void @llvm.dbg.declare(metadata !{{{.*}}}, metadata ![[FOUND_IT:.*]]), !dbg ![[DBG2:.*]]
+// CHECK: = landingpad
+// CHECK-NEXT: cleanup, !dbg ![[DBG3:.*]]
+// CHECK-DAG: ![[CURRENT_ADDR]] = {{.*}} [current_address]
+// CHECK-DAG: ![[FOUND_IT]] = {{.*}} [found_it]
+// CHECK-DAG: ![[DBG1]] = metadata !{i32 256,
+// CHECK-DAG: ![[DBG2]] = metadata !{i32 257,
+// CHECK-DAG: ![[DBG3]] = metadata !{i32 268,
+// CHECK-DAG: ![[DBG4]] = metadata !{i32 256,
+typedef unsigned long long uint64_t;
+template<class _Tp> class shared_ptr {
+public:
+  typedef _Tp element_type;
+  element_type* __ptr_;
+  ~shared_ptr();
+  element_type* operator->() const noexcept {return __ptr_;}
+};
+class Context {
+public:
+    uint64_t GetIt();
+};
+class Foo
+{
+    bool bar();
+    virtual shared_ptr<Context> GetContext () = 0;
+};
+# 253 "Foo.cpp" 3
+bool
+Foo::bar ()
+{
+  uint64_t current_address = GetContext()->GetIt();
+  bool found_it = false;
+# 267 "Foo.cpp" 3
+  return found_it;
+}
diff --git a/test/CodeGenCXX/linetable-fnbegin.cpp b/test/CodeGenCXX/linetable-fnbegin.cpp
new file mode 100644
index 0000000..ce46306
--- /dev/null
+++ b/test/CodeGenCXX/linetable-fnbegin.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -emit-llvm -g %s -o - | FileCheck %s
+// Test that the line table info for Foo<T>::bar() is pointing to the
+// right header file.
+// CHECK: define{{.*}}bar
+// CHECK-NOT: define
+// CHECK: ret {{.*}}, !dbg [[DBG:.*]]
+// CHECK: [[HPP:.*]] = metadata !{metadata !"./template.hpp",
+// CHECK: [[SP:.*]] = metadata !{i32 786478, metadata [[HPP]],{{.*}}[ DW_TAG_subprogram ] [line 22] [def] [bar]
+// We shouldn't need a lexical block for this function.
+// CHECK: [[DBG]] = metadata !{i32 23, i32 0, metadata [[SP]], null}
+
+
+# 1 "./template.h" 1
+template <typename T>
+class Foo {
+public:
+  int bar();
+};
+# 21 "./template.hpp"
+template <typename T>
+int Foo<T>::bar() {
+  return 23;
+}
+int main (int argc, const char * argv[])
+{
+  Foo<int> f;
+  return f.bar();
+}
diff --git a/test/CodeGenCXX/linkage.cpp b/test/CodeGenCXX/linkage.cpp
index 19f1b20..60e53c6 100644
--- a/test/CodeGenCXX/linkage.cpp
+++ b/test/CodeGenCXX/linkage.cpp
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -std=c++11 -O1 -disable-llvm-optzns %s -o - | FileCheck %s
 
 namespace test1 {
-  // CHECK-DAG-LABEL: define linkonce_odr void @_ZN5test11fIZNS_1gEvE1SEEvT_(
+  // CHECK-DAG: define linkonce_odr void @_ZN5test11fIZNS_1gEvE1SEEvT_(
   template <typename T> void f(T) {}
   inline void *g() {
     struct S {
@@ -12,7 +12,7 @@
 }
 
 namespace test2 {
-  // CHECK-DAG-LABEL: define internal void @_ZN5test21fIZNS_L1gEvE1SEEvT_(
+  // CHECK-DAG: define internal void @_ZN5test21fIZNS_L1gEvE1SEEvT_(
   template <typename T> void f(T) {}
   static inline void *g() {
     struct S {
@@ -23,7 +23,7 @@
 }
 
 namespace test3 {
-  // CHECK-DAG-LABEL: define internal void @_ZN5test31fIZNS_1gEvE1SEEvT_(
+  // CHECK-DAG: define internal void @_ZN5test31fIZNS_1gEvE1SEEvT_(
   template <typename T> void f(T) {}
   void *g() {
     struct S {
@@ -34,7 +34,7 @@
 }
 
 namespace test4 {
-  // CHECK-DAG-LABEL: define linkonce_odr void @_ZN5test41fIZNS_1gILi1EEEPvvE1SEEvT_(
+  // CHECK-DAG: define linkonce_odr void @_ZN5test41fIZNS_1gILi1EEEPvvE1SEEvT_(
   template <typename T> void f(T) {}
   template <int N> inline void *g() {
     struct S {
@@ -46,7 +46,7 @@
 }
 
 namespace test5 {
-  // CHECK-DAG-LABEL: define linkonce_odr void @_ZN5test51fIZNS_1gILi1EEEPvvE1SEEvT_(
+  // CHECK-DAG: define linkonce_odr void @_ZN5test51fIZNS_1gILi1EEEPvvE1SEEvT_(
   template <typename T> void f(T) {}
   template <int N> inline void *g() {
     struct S {
@@ -58,7 +58,7 @@
 }
 
 namespace test6 {
-  // CHECK-DAG-LABEL: define linkonce_odr void @_ZN5test61fIZZNS_1gEvEN1S1hEvE1TEEvv(
+  // CHECK-DAG: define linkonce_odr void @_ZN5test61fIZZNS_1gEvEN1S1hEvE1TEEvv(
   template <typename T> void f() {}
 
   inline void *g() {
@@ -76,7 +76,7 @@
 }
 
 namespace test7 {
-  // CHECK-DAG-LABEL: define internal void @_ZN5test71fIZZNS_1gEvEN1S1hEvE1TEEvv(
+  // CHECK-DAG: define internal void @_ZN5test71fIZZNS_1gEvEN1S1hEvE1TEEvv(
   template <typename T> void f() {}
 
   void *g() {
@@ -94,7 +94,7 @@
 }
 
 namespace test8 {
-  // CHECK-DAG-LABEL: define linkonce_odr void @_ZN5test81fIZNS_1gEvE1SEEvT_(
+  // CHECK-DAG: define linkonce_odr void @_ZN5test81fIZNS_1gEvE1SEEvT_(
   template <typename T> void f(T) {}
   inline void *g() {
     enum S {
@@ -105,7 +105,7 @@
 }
 
 namespace test9 {
-  // CHECK-DAG-LABEL: define linkonce_odr void @_ZN5test91fIPZNS_1gEvE1SEEvT_(
+  // CHECK-DAG: define linkonce_odr void @_ZN5test91fIPZNS_1gEvE1SEEvT_(
   template <typename T> void f(T) {}
   inline void *g() {
     struct S {
@@ -116,7 +116,7 @@
 }
 
 namespace test10 {
-  // CHECK-DAG-LABEL: define linkonce_odr void @_ZN6test101fIPFZNS_1gEvE1SvEEEvT_(
+  // CHECK-DAG: define linkonce_odr void @_ZN6test101fIPFZNS_1gEvE1SvEEEvT_(
   template <typename T> void f(T) {}
   inline void *g() {
     struct S {
@@ -128,7 +128,7 @@
 }
 
 namespace test11 {
-  // CHECK-DAG-LABEL: define internal void @_ZN6test111fIPFZNS_1gEvE1SPNS_12_GLOBAL__N_11IEEEEvT_(
+  // CHECK-DAG: define internal void @_ZN6test111fIPFZNS_1gEvE1SPNS_12_GLOBAL__N_11IEEEEvT_(
   namespace {
     struct I {
     };
@@ -145,7 +145,7 @@
 }
 
 namespace test12 {
-  // CHECK-DAG-LABEL: define linkonce_odr void @_ZN6test123fooIZNS_3barIZNS_3zedEvE2S2EEPvvE2S1EEvv
+  // CHECK-DAG: define linkonce_odr void @_ZN6test123fooIZNS_3barIZNS_3zedEvE2S2EEPvvE2S1EEvv
   template <typename T> void foo() {}
   template <typename T> inline void *bar() {
     enum S1 {
@@ -161,7 +161,7 @@
 }
 
 namespace test13 {
-  // CHECK-DAG-LABEL: define linkonce_odr void @_ZZN6test133fooEvEN1S3barEv(
+  // CHECK-DAG: define linkonce_odr void @_ZZN6test133fooEvEN1S3barEv(
   inline void *foo() {
     struct S {
       static void bar() {}
@@ -172,7 +172,7 @@
 }
 
 namespace test14 {
-  // CHECK-DAG-LABEL: define linkonce_odr void @_ZN6test143fooIZNS_1fEvE1SE3barILPS1_0EEEvv(
+  // CHECK-DAG: define linkonce_odr void @_ZN6test143fooIZNS_1fEvE1SE3barILPS1_0EEEvv(
   template <typename T> struct foo {
     template <T *P> static void bar() {}
     static void *g() { return (void *)bar<nullptr>; }
@@ -186,7 +186,7 @@
 }
 
 namespace test15 {
-  // CHECK-DAG-LABEL: define linkonce_odr void @_ZN6test153zedIZNS_3fooIiEEPvvE3barEEvv(
+  // CHECK-DAG: define linkonce_odr void @_ZN6test153zedIZNS_3fooIiEEPvvE3barEEvv(
   template <class T> void zed() {}
   template <class T> void *foo() {
     class bar {
@@ -197,7 +197,7 @@
 }
 
 namespace test16 {
-  // CHECK-DAG-LABEL: define linkonce_odr void @_ZN6test163zedIZNS_3fooIiE3barEvE1SEEvv(
+  // CHECK-DAG: define linkonce_odr void @_ZN6test163zedIZNS_3fooIiE3barEvE1SEEvv(
   template <class T> void zed() {}
   template <class T> struct foo {
     static void *bar();
@@ -212,7 +212,7 @@
 
 namespace test17 {
   // CHECK-DAG: @_ZZN6test173fooILi42EEEPivE3bar = linkonce_odr
-  // CHECK-DAG-LABEL: define weak_odr i32* @_ZN6test173fooILi42EEEPiv(
+  // CHECK-DAG: define weak_odr i32* @_ZN6test173fooILi42EEEPiv(
   template<int I>
   int *foo() {
     static int bar;
@@ -220,3 +220,11 @@
   }
   template int *foo<42>();
 }
+
+// PR18408
+namespace test18 {
+  template<template<typename> class> struct A {};
+  struct B { template<typename> struct C; };
+  void f(A<B::C>) {}
+  // CHECK-DAG: define void @_ZN6test181fENS_1AINS_1B1CEEE(
+}
diff --git a/test/CodeGenCXX/mangle-abi-examples.cpp b/test/CodeGenCXX/mangle-abi-examples.cpp
index 7124078..6fb82cf 100644
--- a/test/CodeGenCXX/mangle-abi-examples.cpp
+++ b/test/CodeGenCXX/mangle-abi-examples.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o - | FileCheck %s
 
 // CHECK: @_ZTVZ3foovEN1C1DE =
 // CHECK: @_ZTVZN1A3fooEiE1B =
diff --git a/test/CodeGenCXX/mangle-address-space.cpp b/test/CodeGenCXX/mangle-address-space.cpp
index 4a4a1f3..a0b3c1a 100644
--- a/test/CodeGenCXX/mangle-address-space.cpp
+++ b/test/CodeGenCXX/mangle-address-space.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -o - %s | FileCheck %s
 
 // CHECK-LABEL: define void @_Z2f0Pc
 void f0(char *p) { }
diff --git a/test/CodeGenCXX/mangle-alias-template.cpp b/test/CodeGenCXX/mangle-alias-template.cpp
index b6719c5..1dbb3eb 100644
--- a/test/CodeGenCXX/mangle-alias-template.cpp
+++ b/test/CodeGenCXX/mangle-alias-template.cpp
@@ -11,10 +11,6 @@
 
 template<template<typename> class F> void h(F<int>);
 
-template<typename,typename,typename> struct S {};
-template<typename T, typename U> using U = S<T, int, U>;
-template<typename...Ts> void h(U<Ts...>, Ts...);
-
 // CHECK-LABEL: define void @_Z1zv(
 void z() {
   vector<int> VI;
@@ -42,7 +38,4 @@
   Vec<Vec<int>> VVI;
   g(VVI);
   // CHECK: call void @_Z1gI6vectorIS0_Ii5allocIiEES1_IS3_EEEvT_(
-
-  // CHECK: call void @_Z1hIJidEEv1UIDpT_ES2_
-  h({}, 0, 0.0);
 }
diff --git a/test/CodeGenCXX/mangle-lambdas.cpp b/test/CodeGenCXX/mangle-lambdas.cpp
index 659b437..e8d3f19 100644
--- a/test/CodeGenCXX/mangle-lambdas.cpp
+++ b/test/CodeGenCXX/mangle-lambdas.cpp
@@ -192,7 +192,7 @@
   };
   void B::h() { f(); }
 }
-// CHECK-LABEL: define linkonce_odr %"struct.PR12123::A"* @_ZZN7PR121231B1fERKSt9type_infoEd_NKUlvE_clEv
+// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %"struct.PR12123::A"* @_ZZN7PR121231B1fERKSt9type_infoEd_NKUlvE_clEv
 
 namespace PR12808 {
   template <typename> struct B {
diff --git a/test/CodeGenCXX/mangle-local-class-names.cpp b/test/CodeGenCXX/mangle-local-class-names.cpp
index 8b950fc..848e460 100644
--- a/test/CodeGenCXX/mangle-local-class-names.cpp
+++ b/test/CodeGenCXX/mangle-local-class-names.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o - | FileCheck %s
 
 // CHECK:  @_ZZ4FUNCvEN4SSSSC1ERKf
 // CHECK: @_ZZ4FUNCvEN4SSSSC2E_0RKf
diff --git a/test/CodeGenCXX/mangle-local-class-vtables.cpp b/test/CodeGenCXX/mangle-local-class-vtables.cpp
index d9d3afe..078d735 100644
--- a/test/CodeGenCXX/mangle-local-class-vtables.cpp
+++ b/test/CodeGenCXX/mangle-local-class-vtables.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o - | FileCheck %s
 
 // CHECK: @_ZTVZN1J1KEvE1C = {{.*}} @_ZTIZN1J1KEvE1C {{.*}} @_ZZN1J1KEvENK1C1FEv 
 // CHECK: @_ZTIZN1J1KEvE1C = {{.*}} @_ZTSZN1J1KEvE1C
diff --git a/test/CodeGenCXX/mangle-local-classes-nested.cpp b/test/CodeGenCXX/mangle-local-classes-nested.cpp
index fafa5d4..cee541f 100644
--- a/test/CodeGenCXX/mangle-local-classes-nested.cpp
+++ b/test/CodeGenCXX/mangle-local-classes-nested.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o - | FileCheck %s
 
 // CHECK: @_ZTVZZ1HvEN1S1IEvE1S = 
 
diff --git a/test/CodeGenCXX/mangle-ms-abi-examples.cpp b/test/CodeGenCXX/mangle-ms-abi-examples.cpp
index d6726ca..5dc9d2e 100644
--- a/test/CodeGenCXX/mangle-ms-abi-examples.cpp
+++ b/test/CodeGenCXX/mangle-ms-abi-examples.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fms-extensions -fno-rtti -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -fms-extensions -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
 
 // CHECK: @"\01??_7D@C@?1??foo@@YAXXZ@6B@" =
 // CHECK: @"\01??_7B@?1??foo@A@@QAEXH@Z@6B@" =
@@ -11,7 +11,7 @@
     B();
   }
 };
-void foo () {
+inline void foo () {
   struct C {
     struct D { virtual ~D() {} };
     void bar () {
@@ -25,4 +25,6 @@
   C::D();
   C().bar();
 }
-
+void call () {
+  foo();
+}
diff --git a/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp b/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp
index 50a2383..fae2e1a 100644
--- a/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp
+++ b/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s
-// RUN: %clang_cc1 -emit-llvm %s -o - -cxx-abi microsoft -triple=x86_64-pc-win32 | FileCheck -check-prefix=X64 %s
+// 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 -check-prefix=X64 %s
 
 void foo(const unsigned int) {}
 // CHECK: "\01?foo@@YAXI@Z"
@@ -37,6 +37,22 @@
 // CHECK: "\01?foo_sad@@YAXSAD@Z"
 // X64: "\01?foo_sad@@YAXSEAD@Z"
 
+void foo_piad(char * __restrict x) {}
+// CHECK: "\01?foo_piad@@YAXPIAD@Z"
+// X64: "\01?foo_piad@@YAXPEIAD@Z"
+
+void foo_qiad(char * const __restrict x) {}
+// CHECK: "\01?foo_qiad@@YAXQIAD@Z"
+// X64: "\01?foo_qiad@@YAXQEIAD@Z"
+
+void foo_riad(char * volatile __restrict x) {}
+// CHECK: "\01?foo_riad@@YAXRIAD@Z"
+// X64: "\01?foo_riad@@YAXREIAD@Z"
+
+void foo_siad(char * const volatile __restrict x) {}
+// CHECK: "\01?foo_siad@@YAXSIAD@Z"
+// X64: "\01?foo_siad@@YAXSEIAD@Z"
+
 void foo_papad(char ** x) {}
 // CHECK: "\01?foo_papad@@YAXPAPAD@Z"
 // X64: "\01?foo_papad@@YAXPEAPEAD@Z"
@@ -238,3 +254,7 @@
 void mangle_yes_backref3(ptr_to_fun_type *const, void (**const)(void)) {}
 // CHECK: "\01?mangle_yes_backref3@@YAXQAP6AXXZ0@Z"
 // X64:   "\01?mangle_yes_backref3@@YAXQEAP6AXXZ0@Z"
+
+void mangle_yes_backref4(int *const __restrict, int *const __restrict) {}
+// CHECK: "\01?mangle_yes_backref4@@YAXQIAH0@Z"
+// X64:   "\01?mangle_yes_backref4@@YAXQEIAH0@Z"
diff --git a/test/CodeGenCXX/mangle-ms-back-references-pr13207.cpp b/test/CodeGenCXX/mangle-ms-back-references-pr13207.cpp
index e10cc8e..5d4b672 100644
--- a/test/CodeGenCXX/mangle-ms-back-references-pr13207.cpp
+++ b/test/CodeGenCXX/mangle-ms-back-references-pr13207.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
 
 template<class X, class Y, class Z>
 class A {};
diff --git a/test/CodeGenCXX/mangle-ms-back-references.cpp b/test/CodeGenCXX/mangle-ms-back-references.cpp
index 4f17326..25a058a 100644
--- a/test/CodeGenCXX/mangle-ms-back-references.cpp
+++ b/test/CodeGenCXX/mangle-ms-back-references.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fms-extensions -fblocks -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -fms-extensions -fblocks -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
 
 void f1(const char* a, const char* b) {}
 // CHECK: "\01?f1@@YAXPBD0@Z"
diff --git a/test/CodeGenCXX/mangle-ms-cxx11.cpp b/test/CodeGenCXX/mangle-ms-cxx11.cpp
index 6947a53..373d2b7 100644
--- a/test/CodeGenCXX/mangle-ms-cxx11.cpp
+++ b/test/CodeGenCXX/mangle-ms-cxx11.cpp
@@ -1,4 +1,7 @@
-// RUN: %clang_cc1 -std=c++11 -fms-extensions -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -fms-extensions -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
+
+// CHECK: "\01?DeducedType@@3HA"
+auto DeducedType = 30;
 
 // CHECK: "\01?LRef@@YAXAAH@Z"
 void LRef(int& a) { }
@@ -9,3 +12,130 @@
 // CHECK: "\01?Null@@YAX$$T@Z"
 namespace std { typedef decltype(__nullptr) nullptr_t; }
 void Null(std::nullptr_t) {}
+
+namespace EnumMangling {
+  extern enum Enum01 { } Enum;
+  extern enum Enum02 : bool { } BoolEnum;
+  extern enum Enum03 : char { } CharEnum;
+  extern enum Enum04 : signed char { } SCharEnum;
+  extern enum Enum05 : unsigned char { } UCharEnum;
+  extern enum Enum06 : short { } SShortEnum;
+  extern enum Enum07 : unsigned short { } UShortEnum;
+  extern enum Enum08 : int { } SIntEnum;
+  extern enum Enum09 : unsigned int { } UIntEnum;
+  extern enum Enum10 : long { } SLongEnum;
+  extern enum Enum11 : unsigned long { } ULongEnum;
+  extern enum Enum12 : long long { } SLongLongEnum;
+  extern enum Enum13 : unsigned long long { } ULongLongEnum;
+// CHECK-DAG: @"\01?Enum@EnumMangling@@3W4Enum01@1@A"
+// CHECK-DAG: @"\01?BoolEnum@EnumMangling@@3W4Enum02@1@A
+// CHECK-DAG: @"\01?CharEnum@EnumMangling@@3W4Enum03@1@A
+// CHECK-DAG: @"\01?SCharEnum@EnumMangling@@3W4Enum04@1@A
+// CHECK-DAG: @"\01?UCharEnum@EnumMangling@@3W4Enum05@1@A
+// CHECK-DAG: @"\01?SShortEnum@EnumMangling@@3W4Enum06@1@A"
+// CHECK-DAG: @"\01?UShortEnum@EnumMangling@@3W4Enum07@1@A"
+// CHECK-DAG: @"\01?SIntEnum@EnumMangling@@3W4Enum08@1@A"
+// CHECK-DAG: @"\01?UIntEnum@EnumMangling@@3W4Enum09@1@A"
+// CHECK-DAG: @"\01?SLongEnum@EnumMangling@@3W4Enum10@1@A"
+// CHECK-DAG: @"\01?ULongEnum@EnumMangling@@3W4Enum11@1@A"
+// CHECK-DAG: @"\01?SLongLongEnum@EnumMangling@@3W4Enum12@1@A"
+// CHECK-DAG: @"\01?ULongLongEnum@EnumMangling@@3W4Enum13@1@A"
+  decltype(Enum) *UseEnum() { return &Enum; }
+  decltype(BoolEnum) *UseBoolEnum() { return &BoolEnum; }
+  decltype(CharEnum) *UseCharEnum() { return &CharEnum; }
+  decltype(SCharEnum) *UseSCharEnum() { return &SCharEnum; }
+  decltype(UCharEnum) *UseUCharEnum() { return &UCharEnum; }
+  decltype(SShortEnum) *UseSShortEnum() { return &SShortEnum; }
+  decltype(UShortEnum) *UseUShortEnum() { return &UShortEnum; }
+  decltype(SIntEnum) *UseSIntEnum() { return &SIntEnum; }
+  decltype(UIntEnum) *UseUIntEnum() { return &UIntEnum; }
+  decltype(SLongEnum) *UseSLongEnum() { return &SLongEnum; }
+  decltype(ULongEnum) *UseULongEnum() { return &ULongEnum; }
+  decltype(SLongLongEnum) *UseSLongLongEnum() { return &SLongLongEnum; }
+  decltype(ULongLongEnum) *UseULongLongEnum() { return &ULongLongEnum; }
+  extern enum class EnumClass01 { } EnumClass;
+  extern enum class EnumClass02 : bool { } BoolEnumClass;
+  extern enum class EnumClass03 : char { } CharEnumClass;
+  extern enum class EnumClass04 : signed char { } SCharEnumClass;
+  extern enum class EnumClass05 : unsigned char { } UCharEnumClass;
+  extern enum class EnumClass06 : short { } SShortEnumClass;
+  extern enum class EnumClass07 : unsigned short { } UShortEnumClass;
+  extern enum class EnumClass08 : int { } SIntEnumClass;
+  extern enum class EnumClass09 : unsigned int { } UIntEnumClass;
+  extern enum class EnumClass10 : long { } SLongEnumClass;
+  extern enum class EnumClass11 : unsigned long { } ULongEnumClass;
+  extern enum class EnumClass12 : long long { } SLongLongEnumClass;
+  extern enum class EnumClass13 : unsigned long long { } ULongLongEnumClass;
+// CHECK-DAG: @"\01?EnumClass@EnumMangling@@3W4EnumClass01@1@A"
+// CHECK-DAG: @"\01?BoolEnumClass@EnumMangling@@3W4EnumClass02@1@A
+// CHECK-DAG: @"\01?CharEnumClass@EnumMangling@@3W4EnumClass03@1@A
+// CHECK-DAG: @"\01?SCharEnumClass@EnumMangling@@3W4EnumClass04@1@A
+// CHECK-DAG: @"\01?UCharEnumClass@EnumMangling@@3W4EnumClass05@1@A
+// CHECK-DAG: @"\01?SShortEnumClass@EnumMangling@@3W4EnumClass06@1@A"
+// CHECK-DAG: @"\01?UShortEnumClass@EnumMangling@@3W4EnumClass07@1@A"
+// CHECK-DAG: @"\01?SIntEnumClass@EnumMangling@@3W4EnumClass08@1@A"
+// CHECK-DAG: @"\01?UIntEnumClass@EnumMangling@@3W4EnumClass09@1@A"
+// CHECK-DAG: @"\01?SLongEnumClass@EnumMangling@@3W4EnumClass10@1@A"
+// CHECK-DAG: @"\01?ULongEnumClass@EnumMangling@@3W4EnumClass11@1@A"
+// CHECK-DAG: @"\01?SLongLongEnumClass@EnumMangling@@3W4EnumClass12@1@A"
+// CHECK-DAG: @"\01?ULongLongEnumClass@EnumMangling@@3W4EnumClass13@1@A"
+  decltype(EnumClass) *UseEnumClass() { return &EnumClass; }
+  decltype(BoolEnumClass) *UseBoolEnumClass() { return &BoolEnumClass; }
+  decltype(CharEnumClass) *UseCharEnumClass() { return &CharEnumClass; }
+  decltype(SCharEnumClass) *UseSCharEnumClass() { return &SCharEnumClass; }
+  decltype(UCharEnumClass) *UseUCharEnumClass() { return &UCharEnumClass; }
+  decltype(SShortEnumClass) *UseSShortEnumClass() { return &SShortEnumClass; }
+  decltype(UShortEnumClass) *UseUShortEnumClass() { return &UShortEnumClass; }
+  decltype(SIntEnumClass) *UseSIntEnumClass() { return &SIntEnumClass; }
+  decltype(UIntEnumClass) *UseUIntEnumClass() { return &UIntEnumClass; }
+  decltype(SLongEnumClass) *UseSLongEnumClass() { return &SLongEnumClass; }
+  decltype(ULongEnumClass) *UseULongEnumClass() { return &ULongEnumClass; }
+  decltype(SLongLongEnumClass) *UseSLongLongEnumClass() { return &SLongLongEnumClass; }
+  decltype(ULongLongEnumClass) *UseULongLongEnumClass() { return &ULongLongEnumClass; }
+}
+
+namespace PR18022 {
+
+struct { } a;
+decltype(a) fun(decltype(a) x, decltype(a)) { return x; }
+// CHECK-DAG: ?fun@PR18022@@YA?AU<unnamed-type-a>@1@U21@0@Z
+
+}
+
+inline int define_lambda() {
+  static auto lambda = [] { static int local; ++local; return local; };
+// First, we have the static local variable of type "<lambda_1>" inside of
+// "define_lambda".
+// CHECK-DAG: ?lambda@?1??define_lambda@@YAHXZ@4V<lambda_1>@@A
+// Next, we have the "operator()" for "<lambda_1>" which is inside of
+// "define_lambda".
+// CHECK-DAG: ??R<lambda_1>@?define_lambda@@YAHXZ@QBEHXZ
+// Finally, we have the local which is inside of "<lambda_1>" which is inside of
+// "define_lambda". Hooray.
+// CHECK-DAG: ?local@?2???R<lambda_1>@?define_lambda@@YAHXZ@QBEHXZ@4HA
+  return lambda();
+}
+
+int call_lambda() {
+  return define_lambda();
+}
+
+namespace PR19361 {
+struct A {
+  void foo() __restrict &;
+  void foo() __restrict &&;
+};
+void A::foo() __restrict & {}
+// CHECK-DAG: @"\01?foo@A@PR19361@@QIGAEXXZ"
+void A::foo() __restrict && {}
+// CHECK-DAG: @"\01?foo@A@PR19361@@QIHAEXXZ"
+}
+
+int operator"" _deg(long double) { return 0; }
+// CHECK-DAG: @"\01??__K_deg@@YAHO@Z"
+
+template <char...>
+void templ_fun_with_pack() {}
+
+template void templ_fun_with_pack<>();
+// CHECK-DAG: @"\01??$templ_fun_with_pack@$S@@YAXXZ"
diff --git a/test/CodeGenCXX/mangle-ms-cxx14.cpp b/test/CodeGenCXX/mangle-ms-cxx14.cpp
new file mode 100644
index 0000000..0399561
--- /dev/null
+++ b/test/CodeGenCXX/mangle-ms-cxx14.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -std=c++1y -fms-extensions -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
+
+template <typename> int x = 0;
+
+// CHECK: "\01??$x@X@@3HA"
+template <> int x<void>;
+// CHECK: "\01??$x@H@@3HA"
+template <> int x<int>;
+
+// CHECK: "\01?FunctionWithLocalType@@YA?A?<auto>@@XZ"
+auto FunctionWithLocalType() {
+  struct LocalType {};
+  return LocalType{};
+}
+
+// CHECK: "\01?ValueFromFunctionWithLocalType@@3ULocalType@?0??FunctionWithLocalType@@YA?A?<auto>@@XZ@A"
+auto ValueFromFunctionWithLocalType = FunctionWithLocalType();
+
+// CHECK: "\01??R<lambda_0>@@QBE?A?<auto>@@XZ"
+auto LambdaWithLocalType = [] {
+  struct LocalType {};
+  return LocalType{};
+};
+
+// CHECK: "\01?ValueFromLambdaWithLocalType@@3ULocalType@?0???R<lambda_0>@@QBE?A?<auto>@@XZ@A"
+auto ValueFromLambdaWithLocalType = LambdaWithLocalType();
+
+template <typename T>
+auto TemplateFuncionWithLocalLambda(T) {
+  auto LocalLambdaWithLocalType = []() {
+    struct LocalType {};
+    return LocalType{};
+  };
+  return LocalLambdaWithLocalType();
+}
+
+// CHECK: "\01?ValueFromTemplateFuncionWithLocalLambda@@3ULocalType@?2???R<lambda_1>@??$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z@QBA?A?3@XZ@A"
+// CHECK: "\01??$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z"
+// CHECK: "\01??R<lambda_1>@??$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z@QBA?A?1@XZ"
+auto ValueFromTemplateFuncionWithLocalLambda = TemplateFuncionWithLocalLambda(0);
diff --git a/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp b/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp
index 87e04c6..37bbf09 100644
--- a/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp
+++ b/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
 
 void a1() {}
 // CHECK: "\01?a1@@YAXXZ"
@@ -164,6 +164,12 @@
 int S::* const f9() { return 0; }
 // CHECK: "\01?f9@@YAQQS@@HXZ"
 
+int S::* __restrict f10() { return 0; }
+// CHECK: "\01?f10@@YAPIQS@@HXZ"
+
+int S::* const __restrict f11() { return 0; }
+// CHECK: "\01?f11@@YAQIQS@@HXZ"
+
 typedef int (*function_pointer)(int);
 
 function_pointer g1() { return 0; }
diff --git a/test/CodeGenCXX/mangle-ms-string-literals.cpp b/test/CodeGenCXX/mangle-ms-string-literals.cpp
new file mode 100644
index 0000000..a77a04f
--- /dev/null
+++ b/test/CodeGenCXX/mangle-ms-string-literals.cpp
@@ -0,0 +1,721 @@
+// RUN: %clang_cc1 -x c++ -std=c++11 -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -x c++ -std=c++11 -emit-llvm %s -o - -triple=x86_64-pc-win32 | FileCheck %s
+
+const char *l255 = "\xff";
+const char *l254 = "\xfe";
+const char *l253 = "\xfd";
+const char *l252 = "\xfc";
+const char *l251 = "\xfb";
+const char *l250 = "\xfa";
+const char *l249 = "\xf9";
+const char *l248 = "\xf8";
+const char *l247 = "\xf7";
+const char *l246 = "\xf6";
+const char *l245 = "\xf5";
+const char *l244 = "\xf4";
+const char *l243 = "\xf3";
+const char *l242 = "\xf2";
+const char *l241 = "\xf1";
+const char *l240 = "\xf0";
+const char *l239 = "\xef";
+const char *l238 = "\xee";
+const char *l237 = "\xed";
+const char *l236 = "\xec";
+const char *l235 = "\xeb";
+const char *l234 = "\xea";
+const char *l233 = "\xe9";
+const char *l232 = "\xe8";
+const char *l231 = "\xe7";
+const char *l230 = "\xe6";
+const char *l229 = "\xe5";
+const char *l228 = "\xe4";
+const char *l227 = "\xe3";
+const char *l226 = "\xe2";
+const char *l225 = "\xe1";
+const char *l224 = "\xe0";
+const char *l223 = "\xdf";
+const char *l222 = "\xde";
+const char *l221 = "\xdd";
+const char *l220 = "\xdc";
+const char *l219 = "\xdb";
+const char *l218 = "\xda";
+const char *l217 = "\xd9";
+const char *l216 = "\xd8";
+const char *l215 = "\xd7";
+const char *l214 = "\xd6";
+const char *l213 = "\xd5";
+const char *l212 = "\xd4";
+const char *l211 = "\xd3";
+const char *l210 = "\xd2";
+const char *l209 = "\xd1";
+const char *l208 = "\xd0";
+const char *l207 = "\xcf";
+const char *l206 = "\xce";
+const char *l205 = "\xcd";
+const char *l204 = "\xcc";
+const char *l203 = "\xcb";
+const char *l202 = "\xca";
+const char *l201 = "\xc9";
+const char *l200 = "\xc8";
+const char *l199 = "\xc7";
+const char *l198 = "\xc6";
+const char *l197 = "\xc5";
+const char *l196 = "\xc4";
+const char *l195 = "\xc3";
+const char *l194 = "\xc2";
+const char *l193 = "\xc1";
+const char *l192 = "\xc0";
+const char *l191 = "\xbf";
+const char *l190 = "\xbe";
+const char *l189 = "\xbd";
+const char *l188 = "\xbc";
+const char *l187 = "\xbb";
+const char *l186 = "\xba";
+const char *l185 = "\xb9";
+const char *l184 = "\xb8";
+const char *l183 = "\xb7";
+const char *l182 = "\xb6";
+const char *l181 = "\xb5";
+const char *l180 = "\xb4";
+const char *l179 = "\xb3";
+const char *l178 = "\xb2";
+const char *l177 = "\xb1";
+const char *l176 = "\xb0";
+const char *l175 = "\xaf";
+const char *l174 = "\xae";
+const char *l173 = "\xad";
+const char *l172 = "\xac";
+const char *l171 = "\xab";
+const char *l170 = "\xaa";
+const char *l169 = "\xa9";
+const char *l168 = "\xa8";
+const char *l167 = "\xa7";
+const char *l166 = "\xa6";
+const char *l165 = "\xa5";
+const char *l164 = "\xa4";
+const char *l163 = "\xa3";
+const char *l162 = "\xa2";
+const char *l161 = "\xa1";
+const char *l160 = "\xa0";
+const char *l159 = "\x9f";
+const char *l158 = "\x9e";
+const char *l157 = "\x9d";
+const char *l156 = "\x9c";
+const char *l155 = "\x9b";
+const char *l154 = "\x9a";
+const char *l153 = "\x99";
+const char *l152 = "\x98";
+const char *l151 = "\x97";
+const char *l150 = "\x96";
+const char *l149 = "\x95";
+const char *l148 = "\x94";
+const char *l147 = "\x93";
+const char *l146 = "\x92";
+const char *l145 = "\x91";
+const char *l144 = "\x90";
+const char *l143 = "\x8f";
+const char *l142 = "\x8e";
+const char *l141 = "\x8d";
+const char *l140 = "\x8c";
+const char *l139 = "\x8b";
+const char *l138 = "\x8a";
+const char *l137 = "\x89";
+const char *l136 = "\x88";
+const char *l135 = "\x87";
+const char *l134 = "\x86";
+const char *l133 = "\x85";
+const char *l132 = "\x84";
+const char *l131 = "\x83";
+const char *l130 = "\x82";
+const char *l129 = "\x81";
+const char *l128 = "\x80";
+const char *l127 = "\x7f";
+const char *l126 = "\x7e";
+const char *l125 = "\x7d";
+const char *l124 = "\x7c";
+const char *l123 = "\x7b";
+const char *l122 = "\x7a";
+const char *l121 = "\x79";
+const char *l120 = "\x78";
+const char *l119 = "\x77";
+const char *l118 = "\x76";
+const char *l117 = "\x75";
+const char *l116 = "\x74";
+const char *l115 = "\x73";
+const char *l114 = "\x72";
+const char *l113 = "\x71";
+const char *l112 = "\x70";
+const char *l111 = "\x6f";
+const char *l110 = "\x6e";
+const char *l109 = "\x6d";
+const char *l108 = "\x6c";
+const char *l107 = "\x6b";
+const char *l106 = "\x6a";
+const char *l105 = "\x69";
+const char *l104 = "\x68";
+const char *l103 = "\x67";
+const char *l102 = "\x66";
+const char *l101 = "\x65";
+const char *l100 = "\x64";
+const char *l99 = "\x63";
+const char *l98 = "\x62";
+const char *l97 = "\x61";
+const char *l96 = "\x60";
+const char *l95 = "\x5f";
+const char *l94 = "\x5e";
+const char *l93 = "\x5d";
+const char *l92 = "\x5c";
+const char *l91 = "\x5b";
+const char *l90 = "\x5a";
+const char *l89 = "\x59";
+const char *l88 = "\x58";
+const char *l87 = "\x57";
+const char *l86 = "\x56";
+const char *l85 = "\x55";
+const char *l84 = "\x54";
+const char *l83 = "\x53";
+const char *l82 = "\x52";
+const char *l81 = "\x51";
+const char *l80 = "\x50";
+const char *l79 = "\x4f";
+const char *l78 = "\x4e";
+const char *l77 = "\x4d";
+const char *l76 = "\x4c";
+const char *l75 = "\x4b";
+const char *l74 = "\x4a";
+const char *l73 = "\x49";
+const char *l72 = "\x48";
+const char *l71 = "\x47";
+const char *l70 = "\x46";
+const char *l69 = "\x45";
+const char *l68 = "\x44";
+const char *l67 = "\x43";
+const char *l66 = "\x42";
+const char *l65 = "\x41";
+const char *l64 = "\x40";
+const char *l63 = "\x3f";
+const char *l62 = "\x3e";
+const char *l61 = "\x3d";
+const char *l60 = "\x3c";
+const char *l59 = "\x3b";
+const char *l58 = "\x3a";
+const char *l57 = "\x39";
+const char *l56 = "\x38";
+const char *l55 = "\x37";
+const char *l54 = "\x36";
+const char *l53 = "\x35";
+const char *l52 = "\x34";
+const char *l51 = "\x33";
+const char *l50 = "\x32";
+const char *l49 = "\x31";
+const char *l48 = "\x30";
+const char *l47 = "\x2f";
+const char *l46 = "\x2e";
+const char *l45 = "\x2d";
+const char *l44 = "\x2c";
+const char *l43 = "\x2b";
+const char *l42 = "\x2a";
+const char *l41 = "\x29";
+const char *l40 = "\x28";
+const char *l39 = "\x27";
+const char *l38 = "\x26";
+const char *l37 = "\x25";
+const char *l36 = "\x24";
+const char *l35 = "\x23";
+const char *l34 = "\x22";
+const char *l33 = "\x21";
+const char *l32 = "\x20";
+const char *l31 = "\x1f";
+const char *l30 = "\x1e";
+const char *l29 = "\x1d";
+const char *l28 = "\x1c";
+const char *l27 = "\x1b";
+const char *l26 = "\x1a";
+const char *l25 = "\x19";
+const char *l24 = "\x18";
+const char *l23 = "\x17";
+const char *l22 = "\x16";
+const char *l21 = "\x15";
+const char *l20 = "\x14";
+const char *l19 = "\x13";
+const char *l18 = "\x12";
+const char *l17 = "\x11";
+const char *l16 = "\x10";
+const char *l15 = "\xf";
+const char *l14 = "\xe";
+const char *l13 = "\xd";
+const char *l12 = "\xc";
+const char *l11 = "\xb";
+const char *l10 = "\xa";
+const char *l9 = "\x9";
+const char *l8 = "\x8";
+const char *l7 = "\x7";
+const char *l6 = "\x6";
+const char *l5 = "\x5";
+const char *l4 = "\x4";
+const char *l3 = "\x3";
+const char *l2 = "\x2";
+const char *l1 = "\x1";
+const char *l0 = "\x0";
+
+// CHECK: @"\01??_C@_01CNACBAHC@?$PP?$AA@"
+// CHECK: @"\01??_C@_01DEBJCBDD@?$PO?$AA@"
+// CHECK: @"\01??_C@_01BPDEHCPA@?$PN?$AA@"
+// CHECK: @"\01??_C@_01GCPEDLB@?$PM?$AA@"
+// CHECK: @"\01??_C@_01EJGONFHG@?$PL?$AA@"
+// CHECK: @"\01??_C@_01FAHFOEDH@?z?$AA@"
+// CHECK: @"\01??_C@_01HLFILHPE@?y?$AA@"
+// CHECK: @"\01??_C@_01GCEDIGLF@?x?$AA@"
+// CHECK: @"\01??_C@_01OFNLJKHK@?w?$AA@"
+// CHECK: @"\01??_C@_01PMMAKLDL@?v?$AA@"
+// CHECK: @"\01??_C@_01NHONPIPI@?u?$AA@"
+// CHECK: @"\01??_C@_01MOPGMJLJ@?t?$AA@"
+// CHECK: @"\01??_C@_01IBLHFPHO@?s?$AA@"
+// CHECK: @"\01??_C@_01JIKMGODP@?r?$AA@"
+// CHECK: @"\01??_C@_01LDIBDNPM@?q?$AA@"
+// CHECK: @"\01??_C@_01KKJKAMLN@?p?$AA@"
+// CHECK: @"\01??_C@_01GHMAACCD@?o?$AA@"
+// CHECK: @"\01??_C@_01HONLDDGC@?n?$AA@"
+// CHECK: @"\01??_C@_01FFPGGAKB@?m?$AA@"
+// CHECK: @"\01??_C@_01EMONFBOA@?l?$AA@"
+// CHECK: @"\01??_C@_01DKMMHCH@?k?$AA@"
+// CHECK: @"\01??_C@_01BKLHPGGG@?j?$AA@"
+// CHECK: @"\01??_C@_01DBJKKFKF@?i?$AA@"
+// CHECK: @"\01??_C@_01CIIBJEOE@?h?$AA@"
+// CHECK: @"\01??_C@_01KPBJIICL@?g?$AA@"
+// CHECK: @"\01??_C@_01LGACLJGK@?f?$AA@"
+// CHECK: @"\01??_C@_01JNCPOKKJ@?e?$AA@"
+// CHECK: @"\01??_C@_01IEDENLOI@?d?$AA@"
+// CHECK: @"\01??_C@_01MLHFENCP@?c?$AA@"
+// CHECK: @"\01??_C@_01NCGOHMGO@?b?$AA@"
+// CHECK: @"\01??_C@_01PJEDCPKN@?a?$AA@"
+// CHECK: @"\01??_C@_01OAFIBOOM@?$OA?$AA@"
+// CHECK: @"\01??_C@_01LIIGDENA@?$NP?$AA@"
+// CHECK: @"\01??_C@_01KBJNAFJB@?$NO?$AA@"
+// CHECK: @"\01??_C@_01IKLAFGFC@?$NN?$AA@"
+// CHECK: @"\01??_C@_01JDKLGHBD@?$NM?$AA@"
+// CHECK: @"\01??_C@_01NMOKPBNE@?$NL?$AA@"
+// CHECK: @"\01??_C@_01MFPBMAJF@?Z?$AA@"
+// CHECK: @"\01??_C@_01OONMJDFG@?Y?$AA@"
+// CHECK: @"\01??_C@_01PHMHKCBH@?X?$AA@"
+// CHECK: @"\01??_C@_01HAFPLONI@?W?$AA@"
+// CHECK: @"\01??_C@_01GJEEIPJJ@?V?$AA@"
+// CHECK: @"\01??_C@_01ECGJNMFK@?U?$AA@"
+// CHECK: @"\01??_C@_01FLHCONBL@?T?$AA@"
+// CHECK: @"\01??_C@_01BEDDHLNM@?S?$AA@"
+// CHECK: @"\01??_C@_01NCIEKJN@?R?$AA@"
+// CHECK: @"\01??_C@_01CGAFBJFO@?Q?$AA@"
+// CHECK: @"\01??_C@_01DPBOCIBP@?P?$AA@"
+// CHECK: @"\01??_C@_01PCEECGIB@?O?$AA@"
+// CHECK: @"\01??_C@_01OLFPBHMA@?N?$AA@"
+// CHECK: @"\01??_C@_01MAHCEEAD@?M?$AA@"
+// CHECK: @"\01??_C@_01NJGJHFEC@?L?$AA@"
+// CHECK: @"\01??_C@_01JGCIODIF@?K?$AA@"
+// CHECK: @"\01??_C@_01IPDDNCME@?J?$AA@"
+// CHECK: @"\01??_C@_01KEBOIBAH@?I?$AA@"
+// CHECK: @"\01??_C@_01LNAFLAEG@?H?$AA@"
+// CHECK: @"\01??_C@_01DKJNKMIJ@?G?$AA@"
+// CHECK: @"\01??_C@_01CDIGJNMI@?F?$AA@"
+// CHECK: @"\01??_C@_01IKLMOAL@?E?$AA@"
+// CHECK: @"\01??_C@_01BBLAPPEK@?D?$AA@"
+// CHECK: @"\01??_C@_01FOPBGJIN@?C?$AA@"
+// CHECK: @"\01??_C@_01EHOKFIMM@?B?$AA@"
+// CHECK: @"\01??_C@_01GMMHALAP@?A?$AA@"
+// CHECK: @"\01??_C@_01HFNMDKEO@?$MA?$AA@"
+// CHECK: @"\01??_C@_01NNHLFPHH@?$LP?$AA@"
+// CHECK: @"\01??_C@_01MEGAGODG@?$LO?$AA@"
+// CHECK: @"\01??_C@_01OPENDNPF@?$LN?$AA@"
+// CHECK: @"\01??_C@_01PGFGAMLE@?$LM?$AA@"
+// CHECK: @"\01??_C@_01LJBHJKHD@?$LL?$AA@"
+// CHECK: @"\01??_C@_01KAAMKLDC@?$LK?$AA@"
+// CHECK: @"\01??_C@_01ILCBPIPB@?$LJ?$AA@"
+// CHECK: @"\01??_C@_01JCDKMJLA@?$LI?$AA@"
+// CHECK: @"\01??_C@_01BFKCNFHP@?$LH?$AA@"
+// CHECK: @"\01??_C@_01MLJOEDO@?$LG?$AA@"
+// CHECK: @"\01??_C@_01CHJELHPN@?$LF?$AA@"
+// CHECK: @"\01??_C@_01DOIPIGLM@?$LE?$AA@"
+// CHECK: @"\01??_C@_01HBMOBAHL@?$LD?$AA@"
+// CHECK: @"\01??_C@_01GINFCBDK@?$LC?$AA@"
+// CHECK: @"\01??_C@_01EDPIHCPJ@?$LB?$AA@"
+// CHECK: @"\01??_C@_01FKODEDLI@?$LA?$AA@"
+// CHECK: @"\01??_C@_01JHLJENCG@?$KP?$AA@"
+// CHECK: @"\01??_C@_01IOKCHMGH@?$KO?$AA@"
+// CHECK: @"\01??_C@_01KFIPCPKE@?$KN?$AA@"
+// CHECK: @"\01??_C@_01LMJEBOOF@?$KM?$AA@"
+// CHECK: @"\01??_C@_01PDNFIICC@?$KL?$AA@"
+// CHECK: @"\01??_C@_01OKMOLJGD@?$KK?$AA@"
+// CHECK: @"\01??_C@_01MBODOKKA@?$KJ?$AA@"
+// CHECK: @"\01??_C@_01NIPINLOB@?$KI?$AA@"
+// CHECK: @"\01??_C@_01FPGAMHCO@?$KH?$AA@"
+// CHECK: @"\01??_C@_01EGHLPGGP@?$KG?$AA@"
+// CHECK: @"\01??_C@_01GNFGKFKM@?$KF?$AA@"
+// CHECK: @"\01??_C@_01HEENJEON@?$KE?$AA@"
+// CHECK: @"\01??_C@_01DLAMACCK@?$KD?$AA@"
+// CHECK: @"\01??_C@_01CCBHDDGL@?$KC?$AA@"
+// CHECK: @"\01??_C@_01JDKGAKI@?$KB?$AA@"
+// CHECK: @"\01??_C@_01BACBFBOJ@?$KA?$AA@"
+// CHECK: @"\01??_C@_01EIPPHLNF@?$JP?$AA@"
+// CHECK: @"\01??_C@_01FBOEEKJE@?$JO?$AA@"
+// CHECK: @"\01??_C@_01HKMJBJFH@?$JN?$AA@"
+// CHECK: @"\01??_C@_01GDNCCIBG@?$JM?$AA@"
+// CHECK: @"\01??_C@_01CMJDLONB@?$JL?$AA@"
+// CHECK: @"\01??_C@_01DFIIIPJA@?$JK?$AA@"
+// CHECK: @"\01??_C@_01BOKFNMFD@?$JJ?$AA@"
+// CHECK: @"\01??_C@_01HLOONBC@?$JI?$AA@"
+// CHECK: @"\01??_C@_01IACGPBNN@?$JH?$AA@"
+// CHECK: @"\01??_C@_01JJDNMAJM@?$JG?$AA@"
+// CHECK: @"\01??_C@_01LCBAJDFP@?$JF?$AA@"
+// CHECK: @"\01??_C@_01KLALKCBO@?$JE?$AA@"
+// CHECK: @"\01??_C@_01OEEKDENJ@?$JD?$AA@"
+// CHECK: @"\01??_C@_01PNFBAFJI@?$JC?$AA@"
+// CHECK: @"\01??_C@_01NGHMFGFL@?$JB?$AA@"
+// CHECK: @"\01??_C@_01MPGHGHBK@?$JA?$AA@"
+// CHECK: @"\01??_C@_01CDNGJIE@?$IP?$AA@"
+// CHECK: @"\01??_C@_01BLCGFIMF@?$IO?$AA@"
+// CHECK: @"\01??_C@_01DAALALAG@?$IN?$AA@"
+// CHECK: @"\01??_C@_01CJBADKEH@?$IM?$AA@"
+// CHECK: @"\01??_C@_01GGFBKMIA@?$IL?$AA@"
+// CHECK: @"\01??_C@_01HPEKJNMB@?$IK?$AA@"
+// CHECK: @"\01??_C@_01FEGHMOAC@?$IJ?$AA@"
+// CHECK: @"\01??_C@_01ENHMPPED@?$II?$AA@"
+// CHECK: @"\01??_C@_01MKOEODIM@?$IH?$AA@"
+// CHECK: @"\01??_C@_01NDPPNCMN@?$IG?$AA@"
+// CHECK: @"\01??_C@_01PINCIBAO@?$IF?$AA@"
+// CHECK: @"\01??_C@_01OBMJLAEP@?$IE?$AA@"
+// CHECK: @"\01??_C@_01KOIICGII@?$ID?$AA@"
+// CHECK: @"\01??_C@_01LHJDBHMJ@?$IC?$AA@"
+// CHECK: @"\01??_C@_01JMLOEEAK@?$IB?$AA@"
+// CHECK: @"\01??_C@_01IFKFHFEL@?$IA?$AA@"
+// CHECK: @"\01??_C@_01BGIBIIDJ@?$HP?$AA@"
+// CHECK: @"\01??_C@_01PJKLJHI@?$HO?$AA@"
+// CHECK: @"\01??_C@_01CELHOKLL@?$HN?$AA@"
+// CHECK: @"\01??_C@_01DNKMNLPK@?$HM?$AA@"
+// CHECK: @"\01??_C@_01HCONENDN@?$HL?$AA@"
+// CHECK: @"\01??_C@_01GLPGHMHM@z?$AA@"
+// CHECK: @"\01??_C@_01EANLCPLP@y?$AA@"
+// CHECK: @"\01??_C@_01FJMABOPO@x?$AA@"
+// CHECK: @"\01??_C@_01NOFIACDB@w?$AA@"
+// CHECK: @"\01??_C@_01MHEDDDHA@v?$AA@"
+// CHECK: @"\01??_C@_01OMGOGALD@u?$AA@"
+// CHECK: @"\01??_C@_01PFHFFBPC@t?$AA@"
+// CHECK: @"\01??_C@_01LKDEMHDF@s?$AA@"
+// CHECK: @"\01??_C@_01KDCPPGHE@r?$AA@"
+// CHECK: @"\01??_C@_01IIACKFLH@q?$AA@"
+// CHECK: @"\01??_C@_01JBBJJEPG@p?$AA@"
+// CHECK: @"\01??_C@_01FMEDJKGI@o?$AA@"
+// CHECK: @"\01??_C@_01EFFIKLCJ@n?$AA@"
+// CHECK: @"\01??_C@_01GOHFPIOK@m?$AA@"
+// CHECK: @"\01??_C@_01HHGOMJKL@l?$AA@"
+// CHECK: @"\01??_C@_01DICPFPGM@k?$AA@"
+// CHECK: @"\01??_C@_01CBDEGOCN@j?$AA@"
+// CHECK: @"\01??_C@_01KBJDNOO@i?$AA@"
+// CHECK: @"\01??_C@_01BDACAMKP@h?$AA@"
+// CHECK: @"\01??_C@_01JEJKBAGA@g?$AA@"
+// CHECK: @"\01??_C@_01INIBCBCB@f?$AA@"
+// CHECK: @"\01??_C@_01KGKMHCOC@e?$AA@"
+// CHECK: @"\01??_C@_01LPLHEDKD@d?$AA@"
+// CHECK: @"\01??_C@_01PAPGNFGE@c?$AA@"
+// CHECK: @"\01??_C@_01OJONOECF@b?$AA@"
+// CHECK: @"\01??_C@_01MCMALHOG@a?$AA@"
+// CHECK: @"\01??_C@_01NLNLIGKH@?$GA?$AA@"
+// CHECK: @"\01??_C@_01IDAFKMJL@_?$AA@"
+// CHECK: @"\01??_C@_01JKBOJNNK@?$FO?$AA@"
+// CHECK: @"\01??_C@_01LBDDMOBJ@?$FN?$AA@"
+// CHECK: @"\01??_C@_01KICIPPFI@?2?$AA@"
+// CHECK: @"\01??_C@_01OHGJGJJP@?$FL?$AA@"
+// CHECK: @"\01??_C@_01POHCFINO@Z?$AA@"
+// CHECK: @"\01??_C@_01NFFPALBN@Y?$AA@"
+// CHECK: @"\01??_C@_01MMEEDKFM@X?$AA@"
+// CHECK: @"\01??_C@_01ELNMCGJD@W?$AA@"
+// CHECK: @"\01??_C@_01FCMHBHNC@V?$AA@"
+// CHECK: @"\01??_C@_01HJOKEEBB@U?$AA@"
+// CHECK: @"\01??_C@_01GAPBHFFA@T?$AA@"
+// CHECK: @"\01??_C@_01CPLAODJH@S?$AA@"
+// CHECK: @"\01??_C@_01DGKLNCNG@R?$AA@"
+// CHECK: @"\01??_C@_01BNIGIBBF@Q?$AA@"
+// CHECK: @"\01??_C@_01EJNLAFE@P?$AA@"
+// CHECK: @"\01??_C@_01MJMHLOMK@O?$AA@"
+// CHECK: @"\01??_C@_01NANMIPIL@N?$AA@"
+// CHECK: @"\01??_C@_01PLPBNMEI@M?$AA@"
+// CHECK: @"\01??_C@_01OCOKONAJ@L?$AA@"
+// CHECK: @"\01??_C@_01KNKLHLMO@K?$AA@"
+// CHECK: @"\01??_C@_01LELAEKIP@J?$AA@"
+// CHECK: @"\01??_C@_01JPJNBJEM@I?$AA@"
+// CHECK: @"\01??_C@_01IGIGCIAN@H?$AA@"
+// CHECK: @"\01??_C@_01BBODEMC@G?$AA@"
+// CHECK: @"\01??_C@_01BIAFAFID@F?$AA@"
+// CHECK: @"\01??_C@_01DDCIFGEA@E?$AA@"
+// CHECK: @"\01??_C@_01CKDDGHAB@D?$AA@"
+// CHECK: @"\01??_C@_01GFHCPBMG@C?$AA@"
+// CHECK: @"\01??_C@_01HMGJMAIH@B?$AA@"
+// CHECK: @"\01??_C@_01FHEEJDEE@A?$AA@"
+// CHECK: @"\01??_C@_01EOFPKCAF@?$EA?$AA@"
+// CHECK: @"\01??_C@_01OGPIMHDM@?$DP?$AA@"
+// CHECK: @"\01??_C@_01PPODPGHN@?$DO?$AA@"
+// CHECK: @"\01??_C@_01NEMOKFLO@?$DN?$AA@"
+// CHECK: @"\01??_C@_01MNNFJEPP@?$DM?$AA@"
+// CHECK: @"\01??_C@_01ICJEACDI@?$DL?$AA@"
+// CHECK: @"\01??_C@_01JLIPDDHJ@?3?$AA@"
+// CHECK: @"\01??_C@_01LAKCGALK@9?$AA@"
+// CHECK: @"\01??_C@_01KJLJFBPL@8?$AA@"
+// CHECK: @"\01??_C@_01COCBENDE@7?$AA@"
+// CHECK: @"\01??_C@_01DHDKHMHF@6?$AA@"
+// CHECK: @"\01??_C@_01BMBHCPLG@5?$AA@"
+// CHECK: @"\01??_C@_01FAMBOPH@4?$AA@"
+// CHECK: @"\01??_C@_01EKENIIDA@3?$AA@"
+// CHECK: @"\01??_C@_01FDFGLJHB@2?$AA@"
+// CHECK: @"\01??_C@_01HIHLOKLC@1?$AA@"
+// CHECK: @"\01??_C@_01GBGANLPD@0?$AA@"
+// CHECK: @"\01??_C@_01KMDKNFGN@?1?$AA@"
+// CHECK: @"\01??_C@_01LFCBOECM@?4?$AA@"
+// CHECK: @"\01??_C@_01JOAMLHOP@?9?$AA@"
+// CHECK: @"\01??_C@_01IHBHIGKO@?0?$AA@"
+// CHECK: @"\01??_C@_01MIFGBAGJ@?$CL?$AA@"
+// CHECK: @"\01??_C@_01NBENCBCI@?$CK?$AA@"
+// CHECK: @"\01??_C@_01PKGAHCOL@?$CJ?$AA@"
+// CHECK: @"\01??_C@_01ODHLEDKK@?$CI?$AA@"
+// CHECK: @"\01??_C@_01GEODFPGF@?8?$AA@"
+// CHECK: @"\01??_C@_01HNPIGOCE@?$CG?$AA@"
+// CHECK: @"\01??_C@_01FGNFDNOH@?$CF?$AA@"
+// CHECK: @"\01??_C@_01EPMOAMKG@$?$AA@"
+// CHECK: @"\01??_C@_01IPJKGB@?$CD?$AA@"
+// CHECK: @"\01??_C@_01BJJEKLCA@?$CC?$AA@"
+// CHECK: @"\01??_C@_01DCLJPIOD@?$CB?$AA@"
+// CHECK: @"\01??_C@_01CLKCMJKC@?5?$AA@"
+// CHECK: @"\01??_C@_01HDHMODJO@?$BP?$AA@"
+// CHECK: @"\01??_C@_01GKGHNCNP@?$BO?$AA@"
+// CHECK: @"\01??_C@_01EBEKIBBM@?$BN?$AA@"
+// CHECK: @"\01??_C@_01FIFBLAFN@?$BM?$AA@"
+// CHECK: @"\01??_C@_01BHBACGJK@?$BL?$AA@"
+// CHECK: @"\01??_C@_01OALBHNL@?$BK?$AA@"
+// CHECK: @"\01??_C@_01CFCGEEBI@?$BJ?$AA@"
+// CHECK: @"\01??_C@_01DMDNHFFJ@?$BI?$AA@"
+// CHECK: @"\01??_C@_01LLKFGJJG@?$BH?$AA@"
+// CHECK: @"\01??_C@_01KCLOFINH@?$BG?$AA@"
+// CHECK: @"\01??_C@_01IJJDALBE@?$BF?$AA@"
+// CHECK: @"\01??_C@_01JAIIDKFF@?$BE?$AA@"
+// CHECK: @"\01??_C@_01NPMJKMJC@?$BD?$AA@"
+// CHECK: @"\01??_C@_01MGNCJNND@?$BC?$AA@"
+// CHECK: @"\01??_C@_01ONPPMOBA@?$BB?$AA@"
+// CHECK: @"\01??_C@_01PEOEPPFB@?$BA?$AA@"
+// CHECK: @"\01??_C@_01DJLOPBMP@?$AP?$AA@"
+// CHECK: @"\01??_C@_01CAKFMAIO@?$AO?$AA@"
+// CHECK: @"\01??_C@_01LIIJDEN@?$AN?$AA@"
+// CHECK: @"\01??_C@_01BCJDKCAM@?$AM?$AA@"
+// CHECK: @"\01??_C@_01FNNCDEML@?$AL?$AA@"
+// CHECK: @"\01??_C@_01EEMJAFIK@?6?$AA@"
+// CHECK: @"\01??_C@_01GPOEFGEJ@?7?$AA@"
+// CHECK: @"\01??_C@_01HGPPGHAI@?$AI?$AA@"
+// CHECK: @"\01??_C@_01PBGHHLMH@?$AH?$AA@"
+// CHECK: @"\01??_C@_01OIHMEKIG@?$AG?$AA@"
+// CHECK: @"\01??_C@_01MDFBBJEF@?$AF?$AA@"
+// CHECK: @"\01??_C@_01NKEKCIAE@?$AE?$AA@"
+// CHECK: @"\01??_C@_01JFALLOMD@?$AD?$AA@"
+// CHECK: @"\01??_C@_01IMBAIPIC@?$AC?$AA@"
+// CHECK: @"\01??_C@_01KHDNNMEB@?$AB?$AA@"
+// CHECK: @"\01??_C@_01LOCGONAA@?$AA?$AA@"
+
+const wchar_t *wl9 = L"\t";
+const wchar_t *wl10 = L"\n";
+const wchar_t *wl11 = L"\v";
+const wchar_t *wl32 = L" ";
+const wchar_t *wl33 = L"!";
+const wchar_t *wl34 = L"\"";
+const wchar_t *wl35 = L"#";
+const wchar_t *wl36 = L"$";
+const wchar_t *wl37 = L"%";
+const wchar_t *wl38 = L"&";
+const wchar_t *wl39 = L"'";
+const wchar_t *wl40 = L"(";
+const wchar_t *wl41 = L")";
+const wchar_t *wl42 = L"*";
+const wchar_t *wl43 = L"+";
+const wchar_t *wl44 = L",";
+const wchar_t *wl45 = L"-";
+const wchar_t *wl46 = L".";
+const wchar_t *wl47 = L"/";
+const wchar_t *wl48 = L"0";
+const wchar_t *wl49 = L"1";
+const wchar_t *wl50 = L"2";
+const wchar_t *wl51 = L"3";
+const wchar_t *wl52 = L"4";
+const wchar_t *wl53 = L"5";
+const wchar_t *wl54 = L"6";
+const wchar_t *wl55 = L"7";
+const wchar_t *wl56 = L"8";
+const wchar_t *wl57 = L"9";
+const wchar_t *wl58 = L":";
+const wchar_t *wl59 = L";";
+const wchar_t *wl60 = L"<";
+const wchar_t *wl61 = L"=";
+const wchar_t *wl62 = L">";
+const wchar_t *wl63 = L"?";
+const wchar_t *wl64 = L"@";
+const wchar_t *wl65 = L"A";
+const wchar_t *wl66 = L"B";
+const wchar_t *wl67 = L"C";
+const wchar_t *wl68 = L"D";
+const wchar_t *wl69 = L"E";
+const wchar_t *wl70 = L"F";
+const wchar_t *wl71 = L"G";
+const wchar_t *wl72 = L"H";
+const wchar_t *wl73 = L"I";
+const wchar_t *wl74 = L"J";
+const wchar_t *wl75 = L"K";
+const wchar_t *wl76 = L"L";
+const wchar_t *wl77 = L"M";
+const wchar_t *wl78 = L"N";
+const wchar_t *wl79 = L"O";
+const wchar_t *wl80 = L"P";
+const wchar_t *wl81 = L"Q";
+const wchar_t *wl82 = L"R";
+const wchar_t *wl83 = L"S";
+const wchar_t *wl84 = L"T";
+const wchar_t *wl85 = L"U";
+const wchar_t *wl86 = L"V";
+const wchar_t *wl87 = L"W";
+const wchar_t *wl88 = L"X";
+const wchar_t *wl89 = L"Y";
+const wchar_t *wl90 = L"Z";
+const wchar_t *wl91 = L"[";
+const wchar_t *wl92 = L"\\";
+const wchar_t *wl93 = L"]";
+const wchar_t *wl94 = L"^";
+const wchar_t *wl95 = L"_";
+const wchar_t *wl96 = L"`";
+const wchar_t *wl97 = L"a";
+const wchar_t *wl98 = L"b";
+const wchar_t *wl99 = L"c";
+const wchar_t *wl100 = L"d";
+const wchar_t *wl101 = L"e";
+const wchar_t *wl102 = L"f";
+const wchar_t *wl103 = L"g";
+const wchar_t *wl104 = L"h";
+const wchar_t *wl105 = L"i";
+const wchar_t *wl106 = L"j";
+const wchar_t *wl107 = L"k";
+const wchar_t *wl108 = L"l";
+const wchar_t *wl109 = L"m";
+const wchar_t *wl110 = L"n";
+const wchar_t *wl111 = L"o";
+const wchar_t *wl112 = L"p";
+const wchar_t *wl113 = L"q";
+const wchar_t *wl114 = L"r";
+const wchar_t *wl115 = L"s";
+const wchar_t *wl116 = L"t";
+const wchar_t *wl117 = L"u";
+const wchar_t *wl118 = L"v";
+const wchar_t *wl119 = L"w";
+const wchar_t *wl120 = L"x";
+const wchar_t *wl121 = L"y";
+const wchar_t *wl122 = L"z";
+const wchar_t *wl123 = L"{";
+const wchar_t *wl124 = L"|";
+const wchar_t *wl125 = L"}";
+const wchar_t *wl126 = L"~";
+
+// CHECK: @"\01??_C@_13KDLDGPGJ@?$AA?7?$AA?$AA@"
+// CHECK: @"\01??_C@_13LBAGMAIH@?$AA?6?$AA?$AA@"
+// CHECK: @"\01??_C@_13JLKKHOC@?$AA?$AL?$AA?$AA@"
+// CHECK: @"\01??_C@_13HOIJIPNN@?$AA?5?$AA?$AA@"
+// CHECK: @"\01??_C@_13MGDFOILI@?$AA?$CB?$AA?$AA@"
+// CHECK: @"\01??_C@_13NEIAEHFG@?$AA?$CC?$AA?$AA@"
+// CHECK: @"\01??_C@_13GMDMCADD@?$AA?$CD?$AA?$AA@"
+// CHECK: @"\01??_C@_13PBOLBIIK@?$AA$?$AA?$AA@"
+// CHECK: @"\01??_C@_13EJFHHPOP@?$AA?$CF?$AA?$AA@"
+// CHECK: @"\01??_C@_13FLOCNAAB@?$AA?$CG?$AA?$AA@"
+// CHECK: @"\01??_C@_13ODFOLHGE@?$AA?8?$AA?$AA@"
+// CHECK: @"\01??_C@_13LLDNKHDC@?$AA?$CI?$AA?$AA@"
+// CHECK: @"\01??_C@_13DIBMAFH@?$AA?$CJ?$AA?$AA@"
+// CHECK: @"\01??_C@_13BBDEGPLJ@?$AA?$CK?$AA?$AA@"
+// CHECK: @"\01??_C@_13KJIIAINM@?$AA?$CL?$AA?$AA@"
+// CHECK: @"\01??_C@_13DEFPDAGF@?$AA?0?$AA?$AA@"
+// CHECK: @"\01??_C@_13IMODFHAA@?$AA?9?$AA?$AA@"
+// CHECK: @"\01??_C@_13JOFGPIOO@?$AA?4?$AA?$AA@"
+// CHECK: @"\01??_C@_13CGOKJPIL@?$AA?1?$AA?$AA@"
+// CHECK: @"\01??_C@_13COJANIEC@?$AA0?$AA?$AA@"
+// CHECK: @"\01??_C@_13JGCMLPCH@?$AA1?$AA?$AA@"
+// CHECK: @"\01??_C@_13IEJJBAMJ@?$AA2?$AA?$AA@"
+// CHECK: @"\01??_C@_13DMCFHHKM@?$AA3?$AA?$AA@"
+// CHECK: @"\01??_C@_13KBPCEPBF@?$AA4?$AA?$AA@"
+// CHECK: @"\01??_C@_13BJEOCIHA@?$AA5?$AA?$AA@"
+// CHECK: @"\01??_C@_13LPLIHJO@?$AA6?$AA?$AA@"
+// CHECK: @"\01??_C@_13LDEHOAPL@?$AA7?$AA?$AA@"
+// CHECK: @"\01??_C@_13OLCEPAKN@?$AA8?$AA?$AA@"
+// CHECK: @"\01??_C@_13FDJIJHMI@?$AA9?$AA?$AA@"
+// CHECK: @"\01??_C@_13EBCNDICG@?$AA?3?$AA?$AA@"
+// CHECK: @"\01??_C@_13PJJBFPED@?$AA?$DL?$AA?$AA@"
+// CHECK: @"\01??_C@_13GEEGGHPK@?$AA?$DM?$AA?$AA@"
+// CHECK: @"\01??_C@_13NMPKAAJP@?$AA?$DN?$AA?$AA@"
+// CHECK: @"\01??_C@_13MOEPKPHB@?$AA?$DO?$AA?$AA@"
+// CHECK: @"\01??_C@_13HGPDMIBE@?$AA?$DP?$AA?$AA@"
+// CHECK: @"\01??_C@_13EFKPHINO@?$AA?$EA?$AA?$AA@"
+// CHECK: @"\01??_C@_13PNBDBPLL@?$AAA?$AA?$AA@"
+// CHECK: @"\01??_C@_13OPKGLAFF@?$AAB?$AA?$AA@"
+// CHECK: @"\01??_C@_13FHBKNHDA@?$AAC?$AA?$AA@"
+// CHECK: @"\01??_C@_13MKMNOPIJ@?$AAD?$AA?$AA@"
+// CHECK: @"\01??_C@_13HCHBIIOM@?$AAE?$AA?$AA@"
+// CHECK: @"\01??_C@_13GAMECHAC@?$AAF?$AA?$AA@"
+// CHECK: @"\01??_C@_13NIHIEAGH@?$AAG?$AA?$AA@"
+// CHECK: @"\01??_C@_13IABLFADB@?$AAH?$AA?$AA@"
+// CHECK: @"\01??_C@_13DIKHDHFE@?$AAI?$AA?$AA@"
+// CHECK: @"\01??_C@_13CKBCJILK@?$AAJ?$AA?$AA@"
+// CHECK: @"\01??_C@_13JCKOPPNP@?$AAK?$AA?$AA@"
+// CHECK: @"\01??_C@_13PHJMHGG@?$AAL?$AA?$AA@"
+// CHECK: @"\01??_C@_13LHMFKAAD@?$AAM?$AA?$AA@"
+// CHECK: @"\01??_C@_13KFHAAPON@?$AAN?$AA?$AA@"
+// CHECK: @"\01??_C@_13BNMMGIII@?$AAO?$AA?$AA@"
+// CHECK: @"\01??_C@_13BFLGCPEB@?$AAP?$AA?$AA@"
+// CHECK: @"\01??_C@_13KNAKEICE@?$AAQ?$AA?$AA@"
+// CHECK: @"\01??_C@_13LPLPOHMK@?$AAR?$AA?$AA@"
+// CHECK: @"\01??_C@_13HADIAKP@?$AAS?$AA?$AA@"
+// CHECK: @"\01??_C@_13JKNELIBG@?$AAT?$AA?$AA@"
+// CHECK: @"\01??_C@_13CCGINPHD@?$AAU?$AA?$AA@"
+// CHECK: @"\01??_C@_13DANNHAJN@?$AAV?$AA?$AA@"
+// CHECK: @"\01??_C@_13IIGBBHPI@?$AAW?$AA?$AA@"
+// CHECK: @"\01??_C@_13NAACAHKO@?$AAX?$AA?$AA@"
+// CHECK: @"\01??_C@_13GILOGAML@?$AAY?$AA?$AA@"
+// CHECK: @"\01??_C@_13HKALMPCF@?$AAZ?$AA?$AA@"
+// CHECK: @"\01??_C@_13MCLHKIEA@?$AA?$FL?$AA?$AA@"
+// CHECK: @"\01??_C@_13FPGAJAPJ@?$AA?2?$AA?$AA@"
+// CHECK: @"\01??_C@_13OHNMPHJM@?$AA?$FN?$AA?$AA@"
+// CHECK: @"\01??_C@_13PFGJFIHC@?$AA?$FO?$AA?$AA@"
+// CHECK: @"\01??_C@_13ENNFDPBH@?$AA_?$AA?$AA@"
+// CHECK: @"\01??_C@_13OFJNNHOA@?$AA?$GA?$AA?$AA@"
+// CHECK: @"\01??_C@_13FNCBLAIF@?$AAa?$AA?$AA@"
+// CHECK: @"\01??_C@_13EPJEBPGL@?$AAb?$AA?$AA@"
+// CHECK: @"\01??_C@_13PHCIHIAO@?$AAc?$AA?$AA@"
+// CHECK: @"\01??_C@_13GKPPEALH@?$AAd?$AA?$AA@"
+// CHECK: @"\01??_C@_13NCEDCHNC@?$AAe?$AA?$AA@"
+// CHECK: @"\01??_C@_13MAPGIIDM@?$AAf?$AA?$AA@"
+// CHECK: @"\01??_C@_13HIEKOPFJ@?$AAg?$AA?$AA@"
+// CHECK: @"\01??_C@_13CACJPPAP@?$AAh?$AA?$AA@"
+// CHECK: @"\01??_C@_13JIJFJIGK@?$AAi?$AA?$AA@"
+// CHECK: @"\01??_C@_13IKCADHIE@?$AAj?$AA?$AA@"
+// CHECK: @"\01??_C@_13DCJMFAOB@?$AAk?$AA?$AA@"
+// CHECK: @"\01??_C@_13KPELGIFI@?$AAl?$AA?$AA@"
+// CHECK: @"\01??_C@_13BHPHAPDN@?$AAm?$AA?$AA@"
+// CHECK: @"\01??_C@_13FECKAND@?$AAn?$AA?$AA@"
+// CHECK: @"\01??_C@_13LNPOMHLG@?$AAo?$AA?$AA@"
+// CHECK: @"\01??_C@_13LFIEIAHP@?$AAp?$AA?$AA@"
+// CHECK: @"\01??_C@_13NDIOHBK@?$AAq?$AA?$AA@"
+// CHECK: @"\01??_C@_13BPINEIPE@?$AAr?$AA?$AA@"
+// CHECK: @"\01??_C@_13KHDBCPJB@?$AAs?$AA?$AA@"
+// CHECK: @"\01??_C@_13DKOGBHCI@?$AAt?$AA?$AA@"
+// CHECK: @"\01??_C@_13ICFKHAEN@?$AAu?$AA?$AA@"
+// CHECK: @"\01??_C@_13JAOPNPKD@?$AAv?$AA?$AA@"
+// CHECK: @"\01??_C@_13CIFDLIMG@?$AAw?$AA?$AA@"
+// CHECK: @"\01??_C@_13HADAKIJA@?$AAx?$AA?$AA@"
+// CHECK: @"\01??_C@_13MIIMMPPF@?$AAy?$AA?$AA@"
+// CHECK: @"\01??_C@_13NKDJGABL@?$AAz?$AA?$AA@"
+// CHECK: @"\01??_C@_13GCIFAHHO@?$AA?$HL?$AA?$AA@"
+// CHECK: @"\01??_C@_13PPFCDPMH@?$AA?$HM?$AA?$AA@"
+// CHECK: @"\01??_C@_13EHOOFIKC@?$AA?$HN?$AA?$AA@"
+// CHECK: @"\01??_C@_13FFFLPHEM@?$AA?$HO?$AA?$AA@"
+
+const char *LongASCIIString = "012345678901234567890123456789ABCDEF";
+// CHECK: @"\01??_C@_0CF@LABBIIMO@012345678901234567890123456789AB@"
+const wchar_t *LongWideString = L"012345678901234567890123456789ABCDEF";
+// CHECK: @"\01??_C@_1EK@KFPEBLPK@?$AA0?$AA1?$AA2?$AA3?$AA4?$AA5?$AA6?$AA7?$AA8?$AA9?$AA0?$AA1?$AA2?$AA3?$AA4?$AA5?$AA6?$AA7?$AA8?$AA9?$AA0?$AA1?$AA2?$AA3?$AA4?$AA5?$AA6?$AA7?$AA8?$AA9?$AAA?$AAB@"
+const wchar_t *UnicodeLiteral = L"\ud7ff";
+// CHECK: @"\01??_C@_13IIHIAFKH@?W?$PP?$AA?$AA@"
diff --git a/test/CodeGenCXX/mangle-ms-template-callback.cpp b/test/CodeGenCXX/mangle-ms-template-callback.cpp
index 6878148..1a8f82f 100644
--- a/test/CodeGenCXX/mangle-ms-template-callback.cpp
+++ b/test/CodeGenCXX/mangle-ms-template-callback.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
 
 template<typename Signature>
 class C;
@@ -70,3 +70,20 @@
 // CHECK: "\01??$bar@P_EAHH@Z@@YAXP_EAHH@Z@Z"
 // FYI blocks are not present in MSVS, so we're free to choose the spec.
 }
+
+template <void (*Fn)()> void WrapFnPtr() { Fn(); }
+template <void (&Fn)()> void WrapFnRef() { Fn(); }
+struct Thing {
+  static void VoidStaticMethod();
+};
+void VoidFn();
+void CallWrapper() {
+  WrapFnPtr<VoidFn>();
+  WrapFnRef<VoidFn>();
+  WrapFnPtr<Thing::VoidStaticMethod>();
+  WrapFnRef<Thing::VoidStaticMethod>();
+}
+// CHECK: call {{.*}} @"\01??$WrapFnPtr@$1?VoidFn@@YAXXZ@@YAXXZ"
+// CHECK: call {{.*}} @"\01??$WrapFnRef@$1?VoidFn@@YAXXZ@@YAXXZ"
+// CHECK: call {{.*}} @"\01??$WrapFnPtr@$1?VoidStaticMethod@Thing@@SAXXZ@@YAXXZ"
+// CHECK: call {{.*}} @"\01??$WrapFnRef@$1?VoidStaticMethod@Thing@@SAXXZ@@YAXXZ"
diff --git a/test/CodeGenCXX/mangle-ms-templates-memptrs-2.cpp b/test/CodeGenCXX/mangle-ms-templates-memptrs-2.cpp
new file mode 100644
index 0000000..e2cbe15
--- /dev/null
+++ b/test/CodeGenCXX/mangle-ms-templates-memptrs-2.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -Wno-microsoft -fms-extensions -fno-rtti -std=c++11 -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
+
+template <typename T, int (T::*)() = nullptr>
+struct J {};
+
+struct __single_inheritance M;
+J<M> m;
+// CHECK-DAG: @"\01?m@@3U?$J@UM@@$0A@@@A"
+
+struct __multiple_inheritance N;
+J<N> n;
+// CHECK-DAG: @"\01?n@@3U?$J@UN@@$HA@@@A"
+
+struct __virtual_inheritance O;
+J<O> o;
+// CHECK-DAG: @"\01?o@@3U?$J@UO@@$IA@A@@@A"
+
+struct P;
+J<P> p;
+// CHECK-DAG: @"\01?p@@3U?$J@UP@@$JA@A@?0@@A"
+
+#pragma pointers_to_members(full_generality, virtual_inheritance)
+
+struct S {
+  int a, b;
+  void f();
+  virtual void g();
+};
+
+struct GeneralBase {
+  virtual void h();
+};
+struct MostGeneral : S, virtual GeneralBase {
+  virtual void h();
+};
+template <void (MostGeneral::*MP)()>
+struct ClassTemplate {
+  ClassTemplate() {}
+};
+
+template struct ClassTemplate<&MostGeneral::h>;
+
+// Test that we mangle in the vbptr offset, which is 12 here.
+//
+// CHECK: define weak_odr x86_thiscallcc %struct.ClassTemplate* @"\01??0?$ClassTemplate@$J??_9MostGeneral@@$BA@AEA@M@3@@QAE@XZ"
diff --git a/test/CodeGenCXX/mangle-ms-templates-memptrs.cpp b/test/CodeGenCXX/mangle-ms-templates-memptrs.cpp
new file mode 100644
index 0000000..803cac3
--- /dev/null
+++ b/test/CodeGenCXX/mangle-ms-templates-memptrs.cpp
@@ -0,0 +1,143 @@
+// RUN: %clang_cc1 -Wno-microsoft -fno-rtti -std=c++11 -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
+
+struct U;
+static_assert(sizeof(void (U::*)()) == 2 * sizeof(void*) + 2 * sizeof(int), "");
+
+struct A { int a; };
+struct B { int b; };
+struct I { union { struct { int a, b; }; }; };
+
+struct S             { int a, b; void f(); virtual void g(); };
+struct M : A, B      { int a, b; void f(); virtual void g(); };
+struct V : virtual A { int a, b; void f(); virtual void g(); };
+struct U             { int a, b; void f(); virtual void g(); };
+
+struct C        { virtual void f(); };
+struct D        { virtual void g(); };
+struct O : C, D { virtual void g(); }; // override of non-primary
+
+// Test data member pointers.
+template <typename T, int T::*F>
+int ReadField(T &o) {
+  return F ? o.*F : 0;
+}
+
+// Redeclare some of the classes so that the implicit attribute goes on the most
+// recent redeclaration rather than the definition.
+struct V;
+
+void ReadFields() {
+  A a;
+  I i;
+  S s;
+  M m;
+  V v;
+  U u;
+  ReadField<S, &S::a>(s);
+  ReadField<M, &M::a>(m);
+  ReadField<V, &V::a>(v);
+  ReadField<U, &U::a>(u);
+  ReadField<S, &S::b>(s);
+  ReadField<M, &M::b>(m);
+  ReadField<V, &V::b>(v);
+  ReadField<U, &U::b>(u);
+  ReadField<S, nullptr>(s);
+  ReadField<M, nullptr>(m);
+  ReadField<V, nullptr>(v);
+  ReadField<U, nullptr>(u);
+
+  // Non-polymorphic null data memptr vs first field memptr.
+  ReadField<A, &A::a>(a);
+  ReadField<A, nullptr>(a);
+
+  // Indirect fields injected from anonymous unions and structs
+  ReadField<I, &I::a>(i);
+  ReadField<I, &I::b>(i);
+}
+
+// CHECK-LABEL: define {{.*}}ReadFields
+// CHECK: call {{.*}} @"\01??$ReadField@US@@$03@@YAHAAUS@@@Z"
+// CHECK: call {{.*}} @"\01??$ReadField@UM@@$0M@@@YAHAAUM@@@Z"
+// CHECK: call {{.*}} @"\01??$ReadField@UV@@$F7A@@@YAHAAUV@@@Z"
+// CHECK: call {{.*}} @"\01??$ReadField@UU@@$G3A@A@@@YAHAAUU@@@Z"
+// CHECK: call {{.*}} @"\01??$ReadField@US@@$07@@YAHAAUS@@@Z"
+// CHECK: call {{.*}} @"\01??$ReadField@UM@@$0BA@@@YAHAAUM@@@Z"
+// CHECK: call {{.*}} @"\01??$ReadField@UV@@$FM@A@@@YAHAAUV@@@Z"
+// CHECK: call {{.*}} @"\01??$ReadField@UU@@$G7A@A@@@YAHAAUU@@@Z"
+
+// MSVC mangles null member pointers in function templates wrong, but it gets
+// them right in class templates.
+// CHECK: call {{.*}} @"\01??$ReadField@US@@$0A@@@YAHAAUS@@@Z"
+// CHECK: call {{.*}} @"\01??$ReadField@UM@@$0A@@@YAHAAUM@@@Z"
+// CHECK: call {{.*}} @"\01??$ReadField@UV@@$FA@?0@@YAHAAUV@@@Z"
+// CHECK: call {{.*}} @"\01??$ReadField@UU@@$GA@A@?0@@YAHAAUU@@@Z"
+
+// Non-polymorphic null data memptr vs first field memptr.  MSVC mangles these
+// the same.
+// CHECK: call {{.*}} @"\01??$ReadField@UA@@$0A@@@YAHAAUA@@@Z"
+// CHECK: call {{.*}} @"\01??$ReadField@UA@@$0?0@@YAHAAUA@@@Z"
+
+// Indirect fields are handled as-if they were simply members of their enclosing
+// record.
+// CHECK: call {{.*}} @"\01??$ReadField@UI@@$0A@@@YAHAAUI@@@Z"
+// CHECK: call {{.*}} @"\01??$ReadField@UI@@$03@@YAHAAUI@@@Z"
+
+// Test member function pointers.
+template <typename T, void (T::*MFP)()>
+void CallMethod(T &o) {
+  (o.*MFP)();
+}
+
+void CallMethods() {
+  S s;
+  M m;
+  V v;
+  U u;
+  O o;
+
+  // Non-virtual methods.
+  CallMethod<S, &S::f>(s);
+  CallMethod<M, &M::f>(m);
+  CallMethod<V, &V::f>(v);
+  CallMethod<U, &U::f>(u);
+
+  // Virtual methods requiring thunk mangling.
+  CallMethod<S, &S::g>(s);
+  CallMethod<M, &M::g>(m);
+  CallMethod<V, &V::g>(v);
+  CallMethod<U, &U::g>(u);
+
+  // A member pointer for a non-primary vbase will have a non-zero this
+  // adjustment.
+  CallMethod<O, &O::g>(o);
+
+  // Null member pointers.
+  CallMethod<S, nullptr>(s);
+  CallMethod<M, nullptr>(m);
+  CallMethod<V, nullptr>(v);
+  CallMethod<U, nullptr>(u);
+}
+
+// CHECK-LABEL: define {{.*}}CallMethods
+// CHECK: call {{.*}} @"\01??$CallMethod@US@@$1?f@1@QAEXXZ@@YAXAAUS@@@Z"
+// CHECK: call {{.*}} @"\01??$CallMethod@UM@@$H?f@1@QAEXXZA@@@YAXAAUM@@@Z"
+// CHECK: call {{.*}} @"\01??$CallMethod@UV@@$I?f@1@QAEXXZA@A@@@YAXAAUV@@@Z"
+// CHECK: call {{.*}} @"\01??$CallMethod@UU@@$J?f@1@QAEXXZA@A@A@@@YAXAAUU@@@Z"
+
+// PR17034: MSVC reuses the same thunk for every virtual g method because they
+// are all at vftable offset zero.  They then mangle the name of the first thunk
+// created into the name of the template instantiation, which is definitely a
+// bug.  We don't follow them here.  Instead of ?_91@ backref below, they would
+// get ?_9S@@ in every instantiation after the first.
+
+// CHECK: call {{.*}} @"\01??$CallMethod@US@@$1??_91@$BA@AE@@YAXAAUS@@@Z"
+// CHECK: call {{.*}} @"\01??$CallMethod@UM@@$H??_91@$BA@AEA@@@YAXAAUM@@@Z"
+// CHECK: call {{.*}} @"\01??$CallMethod@UV@@$I??_91@$BA@AEA@A@@@YAXAAUV@@@Z"
+// CHECK: call {{.*}} @"\01??$CallMethod@UU@@$J??_91@$BA@AEA@A@A@@@YAXAAUU@@@Z"
+
+// CHECK: call {{.*}} @"\01??$CallMethod@UO@@$H??_91@$BA@AE3@@YAXAAUO@@@Z"
+
+// CHECK: call {{.*}} @"\01??$CallMethod@US@@$0A@@@YAXAAUS@@@Z"
+// CHECK: call {{.*}} @"\01??$CallMethod@UM@@$0A@@@YAXAAUM@@@Z"
+// CHECK: call {{.*}} @"\01??$CallMethod@UV@@$0A@@@YAXAAUV@@@Z"
+// CHECK: call {{.*}} @"\01??$CallMethod@UU@@$0A@@@YAXAAUU@@@Z"
diff --git a/test/CodeGenCXX/mangle-ms-templates.cpp b/test/CodeGenCXX/mangle-ms-templates.cpp
index 713f8e9..31fda20 100644
--- a/test/CodeGenCXX/mangle-ms-templates.cpp
+++ b/test/CodeGenCXX/mangle-ms-templates.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -cxx-abi microsoft -fms-extensions -fdelayed-template-parsing -triple=i386-pc-win32 | FileCheck %s
-// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -cxx-abi microsoft -fms-extensions -fdelayed-template-parsing -triple=x86_64-pc-win32 | FileCheck -check-prefix X64 %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -fms-extensions -fdelayed-template-parsing -triple=i386-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -fms-extensions -fdelayed-template-parsing -triple=x86_64-pc-win32 | FileCheck -check-prefix X64 %s
 
 template<typename T>
 class Class {
@@ -24,6 +24,18 @@
   IntTemplate() {}
 };
 
+template<long long param>
+class LongLongTemplate {
+ public:
+  LongLongTemplate() {}
+};
+
+template<unsigned long long param>
+class UnsignedLongLongTemplate {
+ public:
+  UnsignedLongLongTemplate() {}
+};
+
 template<>
 class BoolTemplate<true> {
  public:
@@ -108,6 +120,32 @@
   IntTemplate<65535> ffff;
 // CHECK: call {{.*}} @"\01??0?$IntTemplate@$0PPPP@@@QAE@XZ"
 // X64: call {{.*}} @"\01??0?$IntTemplate@$0PPPP@@@QEAA@XZ"
+
+  IntTemplate<-1>  neg_1;
+// CHECK: call {{.*}} @"\01??0?$IntTemplate@$0?0@@QAE@XZ"
+// X64: call {{.*}} @"\01??0?$IntTemplate@$0?0@@QEAA@XZ"
+  IntTemplate<-9>  neg_9;
+// CHECK: call {{.*}} @"\01??0?$IntTemplate@$0?8@@QAE@XZ"
+// X64: call {{.*}} @"\01??0?$IntTemplate@$0?8@@QEAA@XZ"
+  IntTemplate<-10> neg_10;
+// CHECK: call {{.*}} @"\01??0?$IntTemplate@$0?9@@QAE@XZ"
+// X64: call {{.*}} @"\01??0?$IntTemplate@$0?9@@QEAA@XZ"
+  IntTemplate<-11> neg_11;
+// CHECK: call {{.*}} @"\01??0?$IntTemplate@$0?L@@@QAE@XZ"
+// X64: call {{.*}} @"\01??0?$IntTemplate@$0?L@@@QEAA@XZ"
+
+  LongLongTemplate<-9223372036854775807LL-1LL> int64_min;
+// CHECK: call {{.*}} @"\01??0?$LongLongTemplate@$0?IAAAAAAAAAAAAAAA@@@QAE@XZ"
+// X64: call {{.*}} @"\01??0?$LongLongTemplate@$0?IAAAAAAAAAAAAAAA@@@QEAA@XZ"
+  LongLongTemplate<9223372036854775807LL>      int64_max;
+// CHECK: call {{.*}} @"\01??0?$LongLongTemplate@$0HPPPPPPPPPPPPPPP@@@QAE@XZ"
+// X64: call {{.*}} @"\01??0?$LongLongTemplate@$0HPPPPPPPPPPPPPPP@@@QEAA@XZ"
+  UnsignedLongLongTemplate<18446744073709551615ULL> uint64_max;
+// CHECK: call {{.*}} @"\01??0?$UnsignedLongLongTemplate@$0?0@@QAE@XZ"
+// X64: call {{.*}} @"\01??0?$UnsignedLongLongTemplate@$0?0@@QEAA@XZ"
+  UnsignedLongLongTemplate<(unsigned long long)-1>  uint64_neg_1;
+// CHECK: call {{.*}} @"\01??0?$UnsignedLongLongTemplate@$0?0@@QAE@XZ"
+// X64: call {{.*}} @"\01??0?$UnsignedLongLongTemplate@$0?0@@QEAA@XZ"
 }
 
 namespace space {
@@ -224,3 +262,17 @@
   FunctionDefinedWithInjectedName(TypeWithFriendDefinition<int>());
 }
 // CHECK: @"\01?FunctionDefinedWithInjectedName@@YAXU?$TypeWithFriendDefinition@H@@@Z"
+
+// We need to be able to feed GUIDs through a couple rounds of template
+// substitution.
+template <const _GUID *G>
+struct UUIDType3 {
+  void foo() {}
+};
+template <const _GUID *G>
+struct UUIDType4 : UUIDType3<G> {
+  void bar() { UUIDType4::foo(); }
+};
+template struct UUIDType4<&__uuidof(uuid)>;
+// CHECK: "\01?bar@?$UUIDType4@$1?_GUID_12345678_1234_1234_1234_1234567890ab@@3U__s_GUID@@B@@QAEXXZ"
+// CHECK: "\01?foo@?$UUIDType3@$1?_GUID_12345678_1234_1234_1234_1234567890ab@@3U__s_GUID@@B@@QAEXXZ"
diff --git a/test/CodeGenCXX/mangle-ms-vector-types.cpp b/test/CodeGenCXX/mangle-ms-vector-types.cpp
index 64cb725..aca4929 100644
--- a/test/CodeGenCXX/mangle-ms-vector-types.cpp
+++ b/test/CodeGenCXX/mangle-ms-vector-types.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fms-extensions -ffreestanding -target-feature +avx -emit-llvm %s -o - -cxx-abi microsoft -triple=i686-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -fms-extensions -ffreestanding -target-feature +avx -emit-llvm %s -o - -triple=i686-pc-win32 | FileCheck %s
 
 #include <xmmintrin.h>
 #include <emmintrin.h>
diff --git a/test/CodeGenCXX/mangle-ms.cpp b/test/CodeGenCXX/mangle-ms.cpp
index 42d574f..3285c98 100644
--- a/test/CodeGenCXX/mangle-ms.cpp
+++ b/test/CodeGenCXX/mangle-ms.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s
-// RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -cxx-abi microsoft -triple=x86_64-pc-win32 | FileCheck -check-prefix X64 %s
+// RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -triple=i386-pc-win32 -std=c++98 | FileCheck %s
+// RUN: %clang_cc1 -fblocks -emit-llvm %s -o - -triple=x86_64-pc-win32 -std=c++98| FileCheck -check-prefix X64 %s
 
 int a;
 // CHECK-DAG: @"\01?a@@3HA"
@@ -95,10 +95,18 @@
 // CHECK-DAG: @"\01?h1@@3QAHA"
 extern const int * const h2 = &a;
 // CHECK-DAG: @"\01?h2@@3QBHB"
+extern int * const __restrict h3 = &a;
+// CHECK-DAG: @"\01?h3@@3QIAHIA"
+// X64-DAG: @"\01?h3@@3QEIAHEIA"
 
 int i[10][20];
 // CHECK-DAG: @"\01?i@@3PAY0BE@HA"
 
+typedef int (*FunT)(int, int);
+FunT FunArr[10][20];
+// CHECK-DAG: @"\01?FunArr@@3PAY0BE@P6AHHH@ZA"
+// X64-DAG: @"\01?FunArr@@3PAY0BE@P6AHHH@ZA"
+
 int (__stdcall *j)(signed char, unsigned char);
 // CHECK-DAG: @"\01?j@@3P6GHCE@ZA"
 
@@ -356,3 +364,4 @@
 // CHECK-DAG: ??_UTypedefNewDelete@@SAPAXI@Z
 // CHECK-DAG: ??3TypedefNewDelete@@SAXPAX@Z
 // CHECK-DAG: ??_VTypedefNewDelete@@SAXPAX@Z
+
diff --git a/test/CodeGenCXX/mangle-neon-vectors.cpp b/test/CodeGenCXX/mangle-neon-vectors.cpp
index 249ec2e..6faf622 100644
--- a/test/CodeGenCXX/mangle-neon-vectors.cpp
+++ b/test/CodeGenCXX/mangle-neon-vectors.cpp
@@ -1,10 +1,18 @@
-// RUN: %clang_cc1 -triple arm-none-linux-gnueabi -target-feature +neon %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple armv7-apple-ios -target-feature +neon  %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-apple-ios -target-feature +neon %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-linux-gnu -target-feature +neon %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-AARCH64
 
 typedef float float32_t;
+typedef double float64_t;
 typedef __fp16 float16_t;
+#if defined(__aarch64__)
+typedef unsigned char poly8_t;
+typedef unsigned short poly16_t;
+#else
 typedef signed char poly8_t;
 typedef short poly16_t;
-typedef unsigned long long uint64_t;
+#endif
+typedef unsigned __INT64_TYPE__ uint64_t;
 
 typedef __attribute__((neon_vector_type(2))) int int32x2_t;
 typedef __attribute__((neon_vector_type(4))) int int32x4_t;
@@ -14,26 +22,53 @@
 typedef __attribute__((neon_vector_type(4))) float32_t float32x4_t;
 typedef __attribute__((neon_vector_type(4))) float16_t float16x4_t;
 typedef __attribute__((neon_vector_type(8))) float16_t float16x8_t;
-typedef __attribute__((neon_polyvector_type(16))) poly8_t poly8x16_t;
-typedef __attribute__((neon_polyvector_type(8))) poly16_t poly16x8_t;
+#ifdef __aarch64__
+typedef __attribute__((neon_vector_type(2))) float64_t float64x2_t;
+#endif
+typedef __attribute__((neon_polyvector_type(16))) poly8_t  poly8x16_t;
+typedef __attribute__((neon_polyvector_type(8)))  poly16_t poly16x8_t;
 
 // CHECK: 16__simd64_int32_t
+// CHECK-AARCH64: 11__Int32x2_t
 void f1(int32x2_t v) { }
+
 // CHECK: 17__simd128_int32_t
+// CHECK-AARCH64: 11__Int32x4_t
 void f2(int32x4_t v) { }
+
 // CHECK: 17__simd64_uint64_t
+// CHECK-AARCH64: 12__Uint64x1_t
 void f3(uint64x1_t v) { }
+
 // CHECK: 18__simd128_uint64_t
+// CHECK-AARCH64: 12__Uint64x2_t
 void f4(uint64x2_t v) { }
+
 // CHECK: 18__simd64_float32_t
+// CHECK-AARCH64: 13__Float32x2_t
 void f5(float32x2_t v) { }
+
 // CHECK: 19__simd128_float32_t
+// CHECK-AARCH64: 13__Float32x4_t
 void f6(float32x4_t v) { }
+
 // CHECK: 18__simd64_float16_t
+// CHECK-AARCH64: 13__Float16x4_t
 void f7(float16x4_t v) {}
+
 // CHECK: 19__simd128_float16_t
+// CHECK-AARCH64: 13__Float16x8_t
 void f8(float16x8_t v) {}
+
 // CHECK: 17__simd128_poly8_t
+// CHECK-AARCH64: 12__Poly8x16_t
 void f9(poly8x16_t v) {}
+
 // CHECK: 18__simd128_poly16_t
+// CHECK-AARCH64: 12__Poly16x8_t
 void f10(poly16x8_t v) {}
+
+#ifdef __aarch64__
+// CHECK-AARCH64: 13__Float64x2_t
+void f11(float64x2_t v) { }
+#endif
diff --git a/test/CodeGenCXX/mangle-nullptr-arg.cpp b/test/CodeGenCXX/mangle-nullptr-arg.cpp
index b55ea6d..66ed7e5 100644
--- a/test/CodeGenCXX/mangle-nullptr-arg.cpp
+++ b/test/CodeGenCXX/mangle-nullptr-arg.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
 
 template<int *ip> struct IP {};
 
diff --git a/test/CodeGenCXX/mangle-std-externc.cpp b/test/CodeGenCXX/mangle-std-externc.cpp
index a478dee..f0c7d69 100644
--- a/test/CodeGenCXX/mangle-std-externc.cpp
+++ b/test/CodeGenCXX/mangle-std-externc.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 %s -DNS=std -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-STD
-// RUN: %clang_cc1 %s -DNS=n -emit-llvm -o - | FileCheck %s --check-prefix=CHECK-N
+// RUN: %clang_cc1 %s -DNS=std -emit-llvm -triple %itanium_abi_triple -o - | FileCheck %s --check-prefix=CHECK-STD
+// RUN: %clang_cc1 %s -DNS=n -emit-llvm -triple %itanium_abi_triple -o - | FileCheck %s --check-prefix=CHECK-N
 
 // _ZNSt1DISt1CE1iE = std::D<std::C>::i
 // CHECK-STD: @_ZNSt1DISt1CE1iE = 
diff --git a/test/CodeGenCXX/mangle-subst-std.cpp b/test/CodeGenCXX/mangle-subst-std.cpp
index 6277c7a..678956e 100644
--- a/test/CodeGenCXX/mangle-subst-std.cpp
+++ b/test/CodeGenCXX/mangle-subst-std.cpp
@@ -15,8 +15,8 @@
 namespace std {
   struct A { A(); };
   
-  // CHECK-LABEL: define void @_ZNSt1AC1Ev(%"struct.std::A"* %this) unnamed_addr
   // CHECK-LABEL: define void @_ZNSt1AC2Ev(%"struct.std::A"* %this) unnamed_addr
+  // CHECK-LABEL: define void @_ZNSt1AC1Ev(%"struct.std::A"* %this) unnamed_addr
   A::A() { }
 };
 
diff --git a/test/CodeGenCXX/mangle-template.cpp b/test/CodeGenCXX/mangle-template.cpp
index 3b7f302..998096a 100644
--- a/test/CodeGenCXX/mangle-template.cpp
+++ b/test/CodeGenCXX/mangle-template.cpp
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -verify -Wno-return-type -Wno-main -std=c++11 -emit-llvm -triple %itanium_abi_triple -o - %s | FileCheck %s
+// expected-no-diagnostics
+
 namespace test1 {
 int x;
 template <int& D> class T { };
@@ -145,7 +147,7 @@
   }
 }
 
-// Report from Jason Merrill on cxx-abi-dev, 2012.01.04.
+// Report from cxx-abi-dev, 2012.01.04.
 namespace test11 {
   int cmp(char a, char b);
   template <typename T, int (*cmp)(T, T)> struct A {};
@@ -156,7 +158,7 @@
 
 namespace test12 {
   // Make sure we can mangle non-type template args with internal linkage.
-  static int f();
+  static int f() {}
   const int n = 10;
   template<typename T, T v> void test() {}
   void use() {
@@ -182,3 +184,25 @@
   template short returnShort<-32768>();
   // CHECK: @_ZN6test1311returnShortILsn32768EEEsv()
 }
+
+namespace test14 {
+  template <typename> inline int inl(bool b) {
+    if (b) {
+      static struct {
+        int field;
+      } a;
+      // CHECK: @_ZZN6test143inlIvEEibE1a
+
+      return a.field;
+    } else {
+      static struct {
+        int field;
+      } a;
+      // CHECK: @_ZZN6test143inlIvEEibE1a_0
+
+      return a.field;
+    }
+  }
+
+  int call(bool b) { return inl<void>(b); }
+}
diff --git a/test/CodeGenCXX/mangle-windows.cpp b/test/CodeGenCXX/mangle-windows.cpp
index c087616..8564447 100644
--- a/test/CodeGenCXX/mangle-windows.cpp
+++ b/test/CodeGenCXX/mangle-windows.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -cxx-abi microsoft \
-// RUN:     -triple=i386-pc-win32 | FileCheck --check-prefix=WIN %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 | \
+// RUN:     FileCheck --check-prefix=WIN %s
 //
 // RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-mingw32 | \
 // RUN:     FileCheck --check-prefix=ITANIUM %s
diff --git a/test/CodeGenCXX/mangle.cpp b/test/CodeGenCXX/mangle.cpp
index d836f36..9bdac7f 100644
--- a/test/CodeGenCXX/mangle.cpp
+++ b/test/CodeGenCXX/mangle.cpp
@@ -216,9 +216,9 @@
 };
 
 // PR5139
-// CHECK: @_ZN2S7C1Ev
 // CHECK: @_ZN2S7C2Ev
 // CHECK: @_ZN2S7Ut_C1Ev
+// CHECK: @_ZN2S7C1Ev
 S7::S7() {}
 
 // PR5063
@@ -280,13 +280,13 @@
   void *v;
 };
 
-// CHECK-LABEL: define %struct.Ops* @_ZN3OpsplERKS_
+// CHECK-LABEL: define dereferenceable({{[0-9]+}}) %struct.Ops* @_ZN3OpsplERKS_
 Ops& Ops::operator+(const Ops&) { return *this; }
-// CHECK-LABEL: define %struct.Ops* @_ZN3OpsmiERKS_
+// CHECK-LABEL: define dereferenceable({{[0-9]+}}) %struct.Ops* @_ZN3OpsmiERKS_
 Ops& Ops::operator-(const Ops&) { return *this; }
-// CHECK-LABEL: define %struct.Ops* @_ZN3OpsanERKS_
+// CHECK-LABEL: define dereferenceable({{[0-9]+}}) %struct.Ops* @_ZN3OpsanERKS_
 Ops& Ops::operator&(const Ops&) { return *this; }
-// CHECK-LABEL: define %struct.Ops* @_ZN3OpsmlERKS_
+// CHECK-LABEL: define dereferenceable({{[0-9]+}}) %struct.Ops* @_ZN3OpsmlERKS_
 Ops& Ops::operator*(const Ops&) { return *this; }
 
 // PR5861
@@ -899,7 +899,7 @@
 }
 
 namespace test40 {
-  // CHECK: i32* @_ZZN6test401fEvE1a_0
+  // CHECK: i32* {{.*}} @_ZZN6test401fEvE1a_0
   void h(int&);
   inline void f() {
     if (0) {
@@ -951,3 +951,43 @@
   }
   // CHECK-LABEL: define linkonce_odr void @_ZN6test443foo3barEv(%"struct.test44::foo"* %this)
 }
+
+namespace test45 {
+  struct S {
+    enum e {};
+  };
+  template <typename T>
+  void f(enum T::e *) {}
+  template void f<S>(S::e *);
+  // CHECK-LABEL: define weak_odr void @_ZN6test451fINS_1SEEEvPTeNT_1eE(i32*)
+}
+
+namespace test46 {
+  struct S {
+    struct s {};
+  };
+  template <typename T>
+  void f(struct T::s *) {}
+  template void f<S>(S::s *);
+  // CHECK-LABEL: define weak_odr void @_ZN6test461fINS_1SEEEvPTsNT_1sE(%"struct.test46::S::s"*)
+}
+
+namespace test47 {
+  struct S {
+    class c {};
+  };
+  template <typename T>
+  void f(class T::c *) {}
+  template void f<S>(S::c *);
+  // CHECK-LABEL: define weak_odr void @_ZN6test471fINS_1SEEEvPTsNT_1cE(%"class.test47::S::c"*)
+}
+
+namespace test48 {
+  struct S {
+    union u {};
+  };
+  template <typename T>
+  void f(union T::u *) {}
+  template void f<S>(S::u *);
+  // CHECK-LABEL: define weak_odr void @_ZN6test481fINS_1SEEEvPTuNT_1uE(%"union.test48::S::u"*)
+}
diff --git a/test/CodeGenCXX/member-alignment.cpp b/test/CodeGenCXX/member-alignment.cpp
index 78026d4..43ed5e2 100644
--- a/test/CodeGenCXX/member-alignment.cpp
+++ b/test/CodeGenCXX/member-alignment.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple %s -o - | FileCheck %s
 
 // rdar://7268289
 
diff --git a/test/CodeGenCXX/member-function-pointer-calls.cpp b/test/CodeGenCXX/member-function-pointer-calls.cpp
index 99162eb..67417ef 100644
--- a/test/CodeGenCXX/member-function-pointer-calls.cpp
+++ b/test/CodeGenCXX/member-function-pointer-calls.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -O3 -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple=x86_64-windows-gnu -emit-llvm -o - | FileCheck %s -check-prefix MINGW64
 struct A {
   virtual int vf1() { return 1; }
   virtual int vf2() { return 2; }
@@ -10,6 +11,8 @@
 
 // CHECK-LABEL: define i32 @_Z2g1v()
 // CHECK: ret i32 1
+// MINGW64-LABEL: define i32 @_Z2g1v()
+// MINGW64: call i32 @_Z1fP1AMS_FivE(%struct.A* %{{.*}}, { i64, i64 }* %{{.*}})
 int g1() {
   A a;
   return f(&a, &A::vf1);
@@ -17,6 +20,8 @@
 
 // CHECK-LABEL: define i32 @_Z2g2v()
 // CHECK: ret i32 2
+// MINGW64-LABEL: define i32 @_Z2g2v()
+// MINGW64: call i32 @_Z1fP1AMS_FivE(%struct.A* %{{.*}}, { i64, i64 }* %{{.*}})
 int g2() {
   A a;
   return f(&a, &A::vf2);
diff --git a/test/CodeGenCXX/member-init-anon-union.cpp b/test/CodeGenCXX/member-init-anon-union.cpp
index bfe1667..b488fa7 100644
--- a/test/CodeGenCXX/member-init-anon-union.cpp
+++ b/test/CodeGenCXX/member-init-anon-union.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -std=c++11 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -std=c++11 -triple x86_64-linux-gnu -emit-llvm -o - | FileCheck %s
 
 // PR10531.
 
@@ -21,12 +21,42 @@
     int a;
     int b = 81;
   };
-  // CHECK: define {{.*}}_Z1gv
+  // CHECK-LABEL: define {{.*}}_Z1gv
   // CHECK-NOT: }
   // CHECK: call {{.*}}@"[[CONSTRUCT_LOCAL:.*]]C1Ev"
   return b;
 }
 
+struct A {
+  A();
+};
+union B {
+  int k;
+  struct {
+    A x;
+    int y = 123;
+  };
+  B() {}
+  B(int n) : k(n) {}
+};
+
+B b1;
+B b2(0);
+
+
+// CHECK-LABEL: define {{.*}} @_ZN1BC2Ei(
+// CHECK-NOT: call void @_ZN1AC1Ev(
+// CHECK-NOT: store i32 123,
+// CHECK: store i32 %
+// CHECK-NOT: call void @_ZN1AC1Ev(
+// CHECK-NOT: store i32 123,
+// CHECK: }
+
+// CHECK-LABEL: define {{.*}} @_ZN1BC2Ev(
+// CHECK: call void @_ZN1AC1Ev(
+// CHECK: store i32 123,
+// CHECK: }
+
 
 // CHECK: define {{.*}}@"[[CONSTRUCT_LOCAL]]C2Ev"
 // CHECK-NOT: }
diff --git a/test/CodeGenCXX/member-templates.cpp b/test/CodeGenCXX/member-templates.cpp
index c72dd6e..93d36ff 100644
--- a/test/CodeGenCXX/member-templates.cpp
+++ b/test/CodeGenCXX/member-templates.cpp
@@ -15,8 +15,8 @@
 
 template<typename T> B::B(T) {}
 
-// CHECK-LABEL: define weak_odr void @_ZN1BC1IiEET_(%struct.B* %this, i32) unnamed_addr
 // CHECK-LABEL: define weak_odr void @_ZN1BC2IiEET_(%struct.B* %this, i32) unnamed_addr
+// CHECK-LABEL: define weak_odr void @_ZN1BC1IiEET_(%struct.B* %this, i32) unnamed_addr
 template B::B(int);
 
 template<typename T>
diff --git a/test/CodeGenCXX/microsoft-abi-alignment-fail.cpp b/test/CodeGenCXX/microsoft-abi-alignment-fail.cpp
index 7407efe..c8477f4 100644
--- a/test/CodeGenCXX/microsoft-abi-alignment-fail.cpp
+++ b/test/CodeGenCXX/microsoft-abi-alignment-fail.cpp
@@ -1,10 +1,10 @@
-// RUN: %clang_cc1 -fno-rtti -emit-llvm -cxx-abi microsoft -triple=i686-pc-win32 -o - %s  2>/dev/null | FileCheck %s
-// RUN: %clang_cc1 -fno-rtti -emit-llvm -cxx-abi microsoft -triple=x86_64-pc-win32 -o - %s  2>/dev/null | FileCheck %s -check-prefix CHECK-X64
+// RUN: %clang_cc1 -fno-rtti -emit-llvm -triple=i686-pc-win32 -o - %s  2>/dev/null | FileCheck %s
+// RUN: %clang_cc1 -fno-rtti -emit-llvm -triple=x86_64-pc-win32 -o - %s  2>/dev/null | FileCheck %s -check-prefix CHECK-X64
 
 struct B { char a; };
 struct A : virtual B {} a;
 
 // The <> indicate that the pointer is packed, which is required to support
 // microsoft layout in 32 bit mode, but not 64 bit mode.
-// CHECK: %struct.A = type <{ i32*, %struct.B }>

-// CHECK-X64: %struct.A = type { i32*, %struct.B }

+// CHECK: %struct.A = type <{ i32*, %struct.B }>
+// CHECK-X64: %struct.A = type { i32*, %struct.B }
diff --git a/test/CodeGenCXX/microsoft-abi-arg-order.cpp b/test/CodeGenCXX/microsoft-abi-arg-order.cpp
new file mode 100644
index 0000000..b47508b
--- /dev/null
+++ b/test/CodeGenCXX/microsoft-abi-arg-order.cpp
@@ -0,0 +1,74 @@
+// RUN: %clang_cc1 -mconstructor-aliases -std=c++11 -fexceptions -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s -check-prefix=X86
+// RUN: %clang_cc1 -mconstructor-aliases -std=c++11 -fexceptions -emit-llvm %s -o - -triple=x86_64-pc-win32 | FileCheck %s -check-prefix=X64
+
+struct A {
+  A(int a);
+  A(const A &o);
+  ~A();
+  int a;
+};
+
+void foo(A a, A b, A c) {
+}
+
+// Order of destruction should be left to right.
+//
+// X86-LABEL: define void @"\01?foo@@YAXUA@@00@Z"
+// X86:          ([[argmem_ty:<{ %struct.A, %struct.A, %struct.A }>]]* inalloca)
+// X86: %[[a:[^ ]*]] = getelementptr inbounds [[argmem_ty]]* %0, i32 0, i32 0
+// X86: %[[b:[^ ]*]] = getelementptr inbounds [[argmem_ty]]* %0, i32 0, i32 1
+// X86: %[[c:[^ ]*]] = getelementptr inbounds [[argmem_ty]]* %0, i32 0, i32 2
+// X86: call x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %[[a]])
+// X86: call x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %[[b]])
+// X86: call x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %[[c]])
+// X86: ret void
+
+// X64-LABEL: define void @"\01?foo@@YAXUA@@00@Z"
+// X64:         (%struct.A* %[[a:[^,]*]], %struct.A* %[[b:[^,]*]], %struct.A* %[[c:[^)]*]])
+// X64: call void @"\01??1A@@QEAA@XZ"(%struct.A* %[[a]])
+// X64: call void @"\01??1A@@QEAA@XZ"(%struct.A* %[[b]])
+// X64: call void @"\01??1A@@QEAA@XZ"(%struct.A* %[[c]])
+// X64: ret void
+
+
+void call_foo() {
+  foo(A(1), A(2), A(3));
+}
+
+// Order of evaluation should be right to left, and we should clean up the right
+// things as we unwind.
+//
+// X86-LABEL: define void @"\01?call_foo@@YAXXZ"()
+// X86: call i8* @llvm.stacksave()
+// X86: %[[argmem:[^ ]*]] = alloca inalloca [[argmem_ty]]
+// X86: %[[arg3:[^ ]*]] = getelementptr inbounds [[argmem_ty]]* %[[argmem]], i32 0, i32 2
+// X86: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@H@Z"(%struct.A* %[[arg3]], i32 3)
+// X86: %[[arg2:[^ ]*]] = getelementptr inbounds [[argmem_ty]]* %[[argmem]], i32 0, i32 1
+// X86: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@H@Z"(%struct.A* %[[arg2]], i32 2)
+// X86: %[[arg1:[^ ]*]] = getelementptr inbounds [[argmem_ty]]* %[[argmem]], i32 0, i32 0
+// X86: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@H@Z"(%struct.A* %[[arg1]], i32 1)
+// X86: invoke void @"\01?foo@@YAXUA@@00@Z"([[argmem_ty]]* inalloca %[[argmem]])
+// X86: call void @llvm.stackrestore
+// X86: ret void
+//
+//   lpad2:
+// X86: call x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %[[arg2]])
+// X86: br label
+//
+//   ehcleanup:
+// X86: call x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %[[arg3]])
+
+// X64-LABEL: define void @"\01?call_foo@@YAXXZ"()
+// X64: call %struct.A* @"\01??0A@@QEAA@H@Z"(%struct.A* %[[arg3:[^,]*]], i32 3)
+// X64: invoke %struct.A* @"\01??0A@@QEAA@H@Z"(%struct.A* %[[arg2:[^,]*]], i32 2)
+// X64: invoke %struct.A* @"\01??0A@@QEAA@H@Z"(%struct.A* %[[arg1:[^,]*]], i32 1)
+// X64: call void @"\01?foo@@YAXUA@@00@Z"
+// X64:       (%struct.A* %[[arg1]], %struct.A* %[[arg2]], %struct.A* %[[arg3]])
+// X64: ret void
+//
+//   lpad2:
+// X64: call void @"\01??1A@@QEAA@XZ"(%struct.A* %[[arg2]])
+// X64: br label
+//
+//   ehcleanup:
+// X64: call void @"\01??1A@@QEAA@XZ"(%struct.A* %[[arg3]])
diff --git a/test/CodeGenCXX/microsoft-abi-array-cookies.cpp b/test/CodeGenCXX/microsoft-abi-array-cookies.cpp
index 1ba1f6a..8da4fcf 100644
--- a/test/CodeGenCXX/microsoft-abi-array-cookies.cpp
+++ b/test/CodeGenCXX/microsoft-abi-array-cookies.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
 
 struct ClassWithoutDtor {
   char x;
diff --git a/test/CodeGenCXX/microsoft-abi-byval-sret.cpp b/test/CodeGenCXX/microsoft-abi-byval-sret.cpp
new file mode 100644
index 0000000..985b1ce
--- /dev/null
+++ b/test/CodeGenCXX/microsoft-abi-byval-sret.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i686-pc-win32 -mconstructor-aliases -fno-rtti | FileCheck %s
+
+struct A {
+  A() : a(42) {}
+  A(const A &o) : a(o.a) {}
+  ~A() {}
+  int a;
+  A foo(A o);
+};
+
+A A::foo(A x) {
+  A y(*this);
+  y.a += x.a;
+  return y;
+}
+
+// CHECK-LABEL: define x86_thiscallcc %struct.A* @"\01?foo@A@@QAE?AU1@U1@@Z"
+// CHECK:       (%struct.A* %this, <{ %struct.A*, %struct.A }>* inalloca)
+// CHECK:   getelementptr inbounds <{ %struct.A*, %struct.A }>* %{{.*}}, i32 0, i32 0
+// CHECK:   load %struct.A**
+// CHECK:   ret %struct.A*
+
+int main() {
+  A x;
+  A y = x.foo(x);
+}
+
+// CHECK: call x86_thiscallcc %struct.A* @"\01?foo@A@@QAE?AU1@U1@@Z"
+// CHECK:       (%struct.A* %{{[^,]*}}, <{ %struct.A*, %struct.A }>* inalloca %{{[^,]*}})
diff --git a/test/CodeGenCXX/microsoft-abi-byval-vararg.cpp b/test/CodeGenCXX/microsoft-abi-byval-vararg.cpp
new file mode 100644
index 0000000..6a0a860
--- /dev/null
+++ b/test/CodeGenCXX/microsoft-abi-byval-vararg.cpp
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -Wno-non-pod-varargs -emit-llvm %s -o - -triple=i686-pc-win32 -mconstructor-aliases -fno-rtti | FileCheck %s
+
+#include <stdarg.h>
+
+struct A {
+  A(int a) : a(a) {}
+  A(const A &o) : a(o.a) {}
+  ~A() {}
+  int a;
+};
+
+int foo(A a, ...) {
+  va_list ap;
+  va_start(ap, a);
+  int sum = 0;
+  for (int i = 0; i < a.a; ++i)
+    sum += va_arg(ap, int);
+  va_end(ap);
+  return sum;
+}
+
+// CHECK-LABEL: define i32 @"\01?foo@@YAHUA@@ZZ"(<{ %struct.A }>* inalloca, ...)
+
+int main() {
+  return foo(A(3), 1, 2, 3);
+}
+// CHECK-LABEL: define i32 @main()
+// CHECK: %[[argmem:[^ ]*]] = alloca inalloca <{ %struct.A, i32, i32, i32 }>
+// CHECK: call i32 {{.*bitcast.*}}@"\01?foo@@YAHUA@@ZZ"{{.*}}(<{ %struct.A, i32, i32, i32 }>* inalloca %[[argmem]])
+
+void varargs_zero(...);
+void varargs_one(int, ...);
+void varargs_two(int, int, ...);
+void varargs_three(int, int, int, ...);
+void call_var_args() {
+  A x(3);
+  varargs_zero(x);
+  varargs_one(1, x);
+  varargs_two(1, 2, x);
+  varargs_three(1, 2, 3, x);
+}
+
+// CHECK-LABEL: define void @"\01?call_var_args@@YAXXZ"()
+// CHECK: call void {{.*bitcast.*varargs_zero.*}}(<{ %struct.A }>* inalloca %{{.*}})
+// CHECK: call void {{.*bitcast.*varargs_one.*}}(<{ i32, %struct.A }>* inalloca %{{.*}})
+// CHECK: call void {{.*bitcast.*varargs_two.*}}(<{ i32, i32, %struct.A }>* inalloca %{{.*}})
+// CHECK: call void {{.*bitcast.*varargs_three.*}}(<{ i32, i32, i32, %struct.A }>* inalloca %{{.*}})
+
+// CHECK-LABEL: declare void @"\01?varargs_zero@@YAXZZ"(...)
+// CHECK-LABEL: declare void @"\01?varargs_one@@YAXHZZ"(i32, ...)
+// CHECK-LABEL: declare void @"\01?varargs_two@@YAXHHZZ"(i32, i32, ...)
+// CHECK-LABEL: declare void @"\01?varargs_three@@YAXHHHZZ"(i32, i32, i32, ...)
diff --git a/test/CodeGenCXX/microsoft-abi-cdecl-method-sret.cpp b/test/CodeGenCXX/microsoft-abi-cdecl-method-sret.cpp
new file mode 100644
index 0000000..da58c46
--- /dev/null
+++ b/test/CodeGenCXX/microsoft-abi-cdecl-method-sret.cpp
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -triple i386-pc-win32 -emit-llvm %s -o - | FileCheck %s
+
+// PR15768
+
+// A trivial 12 byte struct is returned indirectly.
+struct S {
+  S();
+  int a, b, c;
+};
+
+struct C {
+  S variadic_sret(const char *f, ...);
+  S __cdecl cdecl_sret();
+  S __cdecl byval_and_sret(S a);
+  int c;
+};
+
+S C::variadic_sret(const char *f, ...) { return S(); }
+S C::cdecl_sret() { return S(); }
+S C::byval_and_sret(S a) { return S(); }
+
+// CHECK: define void @"\01?variadic_sret@C@@QAA?AUS@@PBDZZ"(%struct.C* %this, %struct.S* noalias sret %agg.result, i8* %f, ...)
+// CHECK: define void @"\01?cdecl_sret@C@@QAA?AUS@@XZ"(%struct.C* %this, %struct.S* noalias sret %agg.result)
+// CHECK: define void @"\01?byval_and_sret@C@@QAA?AUS@@U2@@Z"(%struct.C* %this, %struct.S* noalias sret %agg.result, %struct.S* byval align 4 %a)
+
+int main() {
+  C c;
+  c.variadic_sret("asdf");
+  c.cdecl_sret();
+  c.byval_and_sret(S());
+}
+// CHECK-LABEL: define i32 @main()
+// CHECK: call void {{.*}} @"\01?variadic_sret@C@@QAA?AUS@@PBDZZ"
+// CHECK: call void @"\01?cdecl_sret@C@@QAA?AUS@@XZ"
+// CHECK: call void @"\01?byval_and_sret@C@@QAA?AUS@@U2@@Z"
+
+// __fastcall has similar issues.
+struct A {
+  S __fastcall f(int x);
+};
+S A::f(int x) {
+  return S();
+}
+// CHECK-LABEL: define x86_fastcallcc void @"\01?f@A@@QAI?AUS@@H@Z"(%struct.A* inreg %this, %struct.S* inreg noalias sret %agg.result, i32 %x)
diff --git a/test/CodeGenCXX/microsoft-abi-constexpr-vs-inheritance.cpp b/test/CodeGenCXX/microsoft-abi-constexpr-vs-inheritance.cpp
index 92db9a7..319f39c 100644
--- a/test/CodeGenCXX/microsoft-abi-constexpr-vs-inheritance.cpp
+++ b/test/CodeGenCXX/microsoft-abi-constexpr-vs-inheritance.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -fno-rtti -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
 
 struct A {
   constexpr A(int x) : x(x) {}
diff --git a/test/CodeGenCXX/microsoft-abi-default-cc.cpp b/test/CodeGenCXX/microsoft-abi-default-cc.cpp
index d7fba99..e3ca392 100644
--- a/test/CodeGenCXX/microsoft-abi-default-cc.cpp
+++ b/test/CodeGenCXX/microsoft-abi-default-cc.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck -check-prefix GCABI %s
-// RUN: %clang_cc1 -emit-llvm %s -o - -DMS_ABI -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck -check-prefix MSABI %s
+// RUN: %clang_cc1 -triple i386-pc-linux -emit-llvm %s -o - | FileCheck -check-prefix GCABI %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -DMS_ABI -triple=i386-pc-win32 | FileCheck -check-prefix MSABI %s
 
 #ifdef MS_ABI
 # define METHOD_CC __thiscall
diff --git a/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp b/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp
new file mode 100644
index 0000000..225407b
--- /dev/null
+++ b/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp
@@ -0,0 +1,130 @@
+// RUN: %clang_cc1 -emit-llvm -O1 -o - -triple=i386-pc-win32 %s | FileCheck %s
+
+struct S { char a; };
+struct V { virtual void f(); };
+struct A : virtual V {};
+struct B : S, virtual V {};
+struct T {};
+
+T* test0() { return dynamic_cast<T*>((B*)0); }
+// CHECK-LABEL: define noalias %struct.T* @"\01?test0@@YAPAUT@@XZ"()
+// CHECK:   ret %struct.T* null
+
+T* test1(V* x) { return &dynamic_cast<T&>(*x); }
+// CHECK-LABEL: define %struct.T* @"\01?test1@@YAPAUT@@PAUV@@@Z"(%struct.V* %x)
+// CHECK:        [[CAST:%.*]] = bitcast %struct.V* %x to i8*
+// CHECK-NEXT:   [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[CAST]], i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUV@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUT@@@8" to i8*), i32 1)
+// CHECK-NEXT:   [[RET:%.*]] = bitcast i8* [[CALL]] to %struct.T*
+// CHECK-NEXT:   ret %struct.T* [[RET]]
+
+T* test2(A* x) { return &dynamic_cast<T&>(*x); }
+// CHECK-LABEL: define %struct.T* @"\01?test2@@YAPAUT@@PAUA@@@Z"(%struct.A* %x)
+// CHECK:        [[CAST:%.*]] = bitcast %struct.A* %x to i8*
+// CHECK-NEXT:   [[BITCAST:%.*]] = bitcast %struct.A* %x to i8**
+// CHECK-NEXT:   [[VBTBL:%.*]] = load i8** [[BITCAST]], align 4
+// CHECK-NEXT:   [[VBOFFP:%.*]] = getelementptr inbounds i8* [[VBTBL]], i32 4
+// CHECK-NEXT:   [[VBOFFPCAST:%.*]] = bitcast i8* [[VBOFFP]] to i32*
+// CHECK-NEXT:   [[VBOFFS:%.*]] = load i32* [[VBOFFPCAST]], align 4
+// CHECK-NEXT:   [[ADJ:%.*]] = getelementptr inbounds i8* [[CAST]], i32 [[VBOFFS]]
+// CHECK-NEXT:   [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[VBOFFS]], i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUA@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUT@@@8" to i8*), i32 1)
+// CHECK-NEXT:   [[RET:%.*]] = bitcast i8* [[CALL]] to %struct.T*
+// CHECK-NEXT:   ret %struct.T* [[RET]]
+
+T* test3(B* x) { return &dynamic_cast<T&>(*x); }
+// CHECK-LABEL: define %struct.T* @"\01?test3@@YAPAUT@@PAUB@@@Z"(%struct.B* %x)
+// CHECK:        [[VOIDP:%.*]] = getelementptr inbounds %struct.B* %x, i32 0, i32 0, i32 0
+// CHECK-NEXT:   [[VBPTR:%.*]] = getelementptr inbounds i8* [[VOIDP]], i32 4
+// CHECK-NEXT:   [[BITCAST:%.*]] = bitcast i8* [[VBPTR:%.*]] to i8**
+// CHECK-NEXT:   [[VBTBL:%.*]] = load i8** [[BITCAST]], align 4
+// CHECK-NEXT:   [[VBOFFP:%.*]] = getelementptr inbounds i8* [[VBTBL]], i32 4
+// CHECK-NEXT:   [[VBOFFPCAST:%.*]] = bitcast i8* [[VBOFFP]] to i32*
+// CHECK-NEXT:   [[VBOFFS:%.*]] = load i32* [[VBOFFPCAST]], align 4
+// CHECK-NEXT:   [[DELTA:%.*]] = add nsw i32 [[VBOFFS]], 4
+// CHECK-NEXT:   [[ADJ:%.*]] = getelementptr inbounds i8* [[VOIDP]], i32 [[DELTA]]
+// CHECK-NEXT:   [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[DELTA]], i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUB@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUT@@@8" to i8*), i32 1)
+// CHECK-NEXT:   [[RET:%.*]] = bitcast i8* [[CALL]] to %struct.T*
+// CHECK-NEXT:   ret %struct.T* [[RET]]
+
+T* test4(V* x) { return dynamic_cast<T*>(x); }
+// CHECK-LABEL: define %struct.T* @"\01?test4@@YAPAUT@@PAUV@@@Z"(%struct.V* %x)
+// CHECK:        [[CAST:%.*]] = bitcast %struct.V* %x to i8*
+// CHECK-NEXT:   [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[CAST]], i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUV@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUT@@@8" to i8*), i32 0)
+// CHECK-NEXT:   [[RET:%.*]] = bitcast i8* [[CALL]] to %struct.T*
+// CHECK-NEXT:   ret %struct.T* [[RET]]
+
+T* test5(A* x) { return dynamic_cast<T*>(x); }
+// CHECK-LABEL: define %struct.T* @"\01?test5@@YAPAUT@@PAUA@@@Z"(%struct.A* %x)
+// CHECK:        [[CHECK:%.*]] = icmp eq %struct.A* %x, null
+// CHECK-NEXT:   br i1 [[CHECK]]
+// CHECK:        [[VOIDP:%.*]] = bitcast %struct.A* %x to i8*
+// CHECK-NEXT:   [[BITCAST:%.*]] = bitcast %struct.A* %x to i8**
+// CHECK-NEXT:   [[VBTBL:%.*]] = load i8** [[BITCAST]], align 4
+// CHECK-NEXT:   [[VBOFFP:%.*]] = getelementptr inbounds i8* [[VBTBL]], i32 4
+// CHECK-NEXT:   [[VBOFFPCAST:%.*]] = bitcast i8* [[VBOFFP]] to i32*
+// CHECK-NEXT:   [[VBOFFS:%.*]] = load i32* [[VBOFFPCAST:%.*]], align 4
+// CHECK-NEXT:   [[ADJ:%.*]] = getelementptr inbounds i8* [[VOIDP]], i32 [[VBOFFS]]
+// CHECK-NEXT:   [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[VBOFFS]], i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUA@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUT@@@8" to i8*), i32 0)
+// CHECK-NEXT:   [[RES:%.*]] = bitcast i8* [[CALL]] to %struct.T*
+// CHECK-NEXT:   br label
+// CHECK:        [[RET:%.*]] = phi %struct.T*
+// CHECK-NEXT:   ret %struct.T* [[RET]]
+
+T* test6(B* x) { return dynamic_cast<T*>(x); }
+// CHECK-LABEL: define %struct.T* @"\01?test6@@YAPAUT@@PAUB@@@Z"(%struct.B* %x)
+// CHECK:        [[CHECK:%.*]] = icmp eq %struct.B* %x, null
+// CHECK-NEXT:   br i1 [[CHECK]]
+// CHECK:        [[CAST:%.*]] = getelementptr inbounds %struct.B* %x, i32 0, i32 0, i32 0
+// CHECK-NEXT:   [[VBPTR:%.*]] = getelementptr inbounds i8* [[CAST]], i32 4
+// CHECK-NEXT:   [[BITCAST:%.*]] = bitcast i8* [[VBPTR]] to i8**
+// CHECK-NEXT:   [[VBTBL:%.*]] = load i8** [[BITCAST]], align 4
+// CHECK-NEXT:   [[VBOFFP:%.*]] = getelementptr inbounds i8* [[VBTBL]], i32 4
+// CHECK-NEXT:   [[VBOFFPCAST:%.*]] = bitcast i8* [[VBOFFP]] to i32*
+// CHECK-NEXT:   [[VBOFFS:%.*]] = load i32* [[VBOFFPCAST:%.*]], align 4
+// CHECK-NEXT:   [[DELTA:%.*]] = add nsw i32 [[VBOFFS]], 4
+// CHECK-NEXT:   [[ADJ:%.*]] = getelementptr inbounds i8* [[CAST]], i32 [[DELTA]]
+// CHECK-NEXT:   [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[DELTA]], i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUB@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUT@@@8" to i8*), i32 0)
+// CHECK-NEXT:   [[RES:%.*]] = bitcast i8* [[CALL]] to %struct.T*
+// CHECK-NEXT:   br label
+// CHECK:        [[RET:%.*]] = phi %struct.T*
+// CHECK-NEXT:   ret %struct.T* [[RET]]
+
+void* test7(V* x) { return dynamic_cast<void*>(x); }
+// CHECK-LABEL: define i8* @"\01?test7@@YAPAXPAUV@@@Z"(%struct.V* %x)
+// CHECK:        [[CAST:%.*]] = bitcast %struct.V* %x to i8*
+// CHECK-NEXT:   [[RET:%.*]] = tail call i8* @__RTCastToVoid(i8* [[CAST]])
+// CHECK-NEXT:   ret i8* [[RET]]
+
+void* test8(A* x) { return dynamic_cast<void*>(x); }
+// CHECK-LABEL: define i8* @"\01?test8@@YAPAXPAUA@@@Z"(%struct.A* %x)
+// CHECK:        [[CHECK:%.*]] = icmp eq %struct.A* %x, null
+// CHECK-NEXT:   br i1 [[CHECK]]
+// CHECK:        [[VOIDP:%.*]] = bitcast %struct.A* %x to i8*
+// CHECK-NEXT:   [[BITCAST:%.*]] = bitcast %struct.A* %x to i8**
+// CHECK-NEXT:   [[VBTBL:%.*]] = load i8** [[BITCAST]], align 4
+// CHECK-NEXT:   [[VBOFFP:%.*]] = getelementptr inbounds i8* [[VBTBL]], i32 4
+// CHECK-NEXT:   [[VBOFFPCAST:%.*]] = bitcast i8* [[VBOFFP]] to i32*
+// CHECK-NEXT:   [[VBOFFS:%.*]] = load i32* [[VBOFFPCAST:%.*]], align 4
+// CHECK-NEXT:   [[ADJ:%.*]] = getelementptr inbounds i8* [[VOIDP]], i32 [[VBOFFS]]
+// CHECK-NEXT:   [[RES:%.*]] = tail call i8* @__RTCastToVoid(i8* [[ADJ]])
+// CHECK-NEXT:   br label
+// CHECK:        [[RET:%.*]] = phi i8*
+// CHECK-NEXT:   ret i8* [[RET]]
+
+void* test9(B* x) { return dynamic_cast<void*>(x); }
+// CHECK-LABEL: define i8* @"\01?test9@@YAPAXPAUB@@@Z"(%struct.B* %x)
+// CHECK:        [[CHECK:%.*]] = icmp eq %struct.B* %x, null
+// CHECK-NEXT:   br i1 [[CHECK]]
+// CHECK:        [[CAST:%.*]] = getelementptr inbounds %struct.B* %x, i32 0, i32 0, i32 0
+// CHECK-NEXT:   [[VBPTR:%.*]] = getelementptr inbounds i8* [[CAST]], i32 4
+// CHECK-NEXT:   [[BITCAST:%.*]] = bitcast i8* [[VBPTR]] to i8**
+// CHECK-NEXT:   [[VBTBL:%.*]] = load i8** [[BITCAST]], align 4
+// CHECK-NEXT:   [[VBOFFP:%.*]] = getelementptr inbounds i8* [[VBTBL]], i32 4
+// CHECK-NEXT:   [[VBOFFPCAST:%.*]] = bitcast i8* [[VBOFFP]] to i32*
+// CHECK-NEXT:   [[VBOFFS:%.*]] = load i32* [[VBOFFPCAST:%.*]], align 4
+// CHECK-NEXT:   [[DELTA:%.*]] = add nsw i32 [[VBOFFS]], 4
+// CHECK-NEXT:   [[ADJ:%.*]] = getelementptr inbounds i8* [[CAST]], i32 [[DELTA]]
+// CHECK-NEXT:   [[CALL:%.*]] = tail call i8* @__RTCastToVoid(i8* [[ADJ]])
+// CHECK-NEXT:   br label
+// CHECK:        [[RET:%.*]] = phi i8*
+// CHECK-NEXT:   ret i8* [[RET]]
+
diff --git a/test/CodeGenCXX/microsoft-abi-exceptions.cpp b/test/CodeGenCXX/microsoft-abi-exceptions.cpp
index 7757ea0..60a3514 100644
--- a/test/CodeGenCXX/microsoft-abi-exceptions.cpp
+++ b/test/CodeGenCXX/microsoft-abi-exceptions.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 -mconstructor-aliases -cxx-abi microsoft -fexceptions -fno-rtti | FileCheck -check-prefix WIN32 %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 -mconstructor-aliases -fexceptions -fno-rtti | FileCheck -check-prefix WIN32 %s
 
 struct A {
   A();
@@ -14,17 +14,21 @@
 }
 
 // With exceptions, we need to clean up at least one of these temporaries.
-// WIN32: define void @"\01?HasEHCleanup@@YAXXZ"() {{.*}} {
-//    First one doesn't have any cleanups, no need for invoke.
-// WIN32:   call void @"\01?getA@@YA?AUA@@XZ"(%struct.A* sret %{{.*}})
+// WIN32-LABEL: define void @"\01?HasEHCleanup@@YAXXZ"() {{.*}} {
+// WIN32:   %[[base:.*]] = call i8* @llvm.stacksave()
+//    If this call throws, we have to restore the stack.
+// WIN32:   invoke void @"\01?getA@@YA?AUA@@XZ"(%struct.A* sret %{{.*}})
 //    If this call throws, we have to cleanup the first temporary.
 // WIN32:   invoke void @"\01?getA@@YA?AUA@@XZ"(%struct.A* sret %{{.*}})
-//    If this call throws, we already popped our cleanups
-// WIN32:   call i32 @"\01?TakesTwo@@YAHUA@@0@Z"
+//    If this call throws, we have to cleanup the stacksave.
+// WIN32:   invoke i32 @"\01?TakesTwo@@YAHUA@@0@Z"
+// WIN32:   call void @llvm.stackrestore(i8* %[[base]])
 // WIN32:   ret void
 //
 //    There should be one dtor call for unwinding from the second getA.
 // WIN32:   invoke x86_thiscallcc void @"\01??1A@@QAE@XZ"
+// WIN32-NOT: @"\01??1A@@QAE@XZ"
+// WIN32:   call void @llvm.stackrestore
 // WIN32: }
 
 void TakeRef(const A &a);
@@ -32,20 +36,28 @@
   return TakesTwo((TakeRef(A()), A()), (TakeRef(A()), A()));
 }
 
-// WIN32: define i32 @"\01?HasDeactivatedCleanups@@YAHXZ"() {{.*}} {
+// WIN32-LABEL: define i32 @"\01?HasDeactivatedCleanups@@YAHXZ"() {{.*}} {
 // WIN32:   %[[isactive:.*]] = alloca i1
-// WIN32:   call x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"
+// WIN32:   call i8* @llvm.stacksave()
+// WIN32:   %[[argmem:.*]] = alloca inalloca [[argmem_ty:<{ %struct.A, %struct.A }>]]
+// WIN32:   %[[arg1:.*]] = getelementptr inbounds [[argmem_ty]]* %[[argmem]], i32 0, i32 1
+// WIN32:   invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"
 // WIN32:   invoke void @"\01?TakeRef@@YAXABUA@@@Z"
-// WIN32:   invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"(%struct.A* %[[arg1:.*]])
+//
+// WIN32:   invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"(%struct.A* %[[arg1]])
 // WIN32:   store i1 true, i1* %[[isactive]]
+//
+// WIN32:   %[[arg0:.*]] = getelementptr inbounds [[argmem_ty]]* %[[argmem]], i32 0, i32 0
 // WIN32:   invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"
 // WIN32:   invoke void @"\01?TakeRef@@YAXABUA@@@Z"
 // WIN32:   invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"
 // WIN32:   store i1 false, i1* %[[isactive]]
-// WIN32:   invoke i32 @"\01?TakesTwo@@YAHUA@@0@Z"
+//
+// WIN32:   invoke i32 @"\01?TakesTwo@@YAHUA@@0@Z"([[argmem_ty]]* inalloca %[[argmem]])
+// WIN32:   call void @llvm.stackrestore
 //        Destroy the two const ref temporaries.
 // WIN32:   invoke x86_thiscallcc void @"\01??1A@@QAE@XZ"
-// WIN32:   call x86_thiscallcc void @"\01??1A@@QAE@XZ"
+// WIN32:   invoke x86_thiscallcc void @"\01??1A@@QAE@XZ"
 // WIN32:   ret i32
 //
 //        Conditionally destroy arg1.
@@ -60,20 +72,22 @@
   return (cond ? TakesTwo(A(), A()) : CouldThrow());
 }
 
-// WIN32: define i32 @"\01?HasConditionalCleanup@@YAH_N@Z"(i1 zeroext %{{.*}}) {{.*}} {
+// WIN32-LABEL: define i32 @"\01?HasConditionalCleanup@@YAH_N@Z"(i1 zeroext %{{.*}}) {{.*}} {
 // WIN32:   store i1 false
 // WIN32:   br i1
-//        No cleanups, so we call and then activate a cleanup if it succeeds.
-// WIN32:   call x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"(%struct.A* %[[arg1:.*]])
-// WIN32:   store i1 true
-//        Now we have a cleanup for the first aggregate, so we invoke.
+// WIN32:   call i8* @llvm.stacksave()
 // WIN32:   invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"(%struct.A* %{{.*}})
-//        Now we have no cleanups because TakeTwo will destruct both args.
-// WIN32:   call i32 @"\01?TakesTwo@@YAHUA@@0@Z"
-//        Still no cleanups, so call.
+// WIN32:   store i1 true
+// WIN32:   invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"(%struct.A* %{{.*}})
+// WIN32:   invoke i32 @"\01?TakesTwo@@YAHUA@@0@Z"
+// WIN32:   call void @llvm.stackrestore
+//
 // WIN32:   call i32 @"\01?CouldThrow@@YAHXZ"()
-//        Somewhere in the landing pad for our single invoke, call the dtor.
-// WIN32:   invoke x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %[[arg1]])
+//
+//        Only one dtor in the invoke for arg1
+// WIN32:   invoke x86_thiscallcc void @"\01??1A@@QAE@XZ"({{.*}})
+// WIN32-NOT: invoke x86_thiscallcc void @"\01??1A@@QAE@XZ"
+// WIN32:   call void @llvm.stackrestore
 // WIN32: }
 
 // Now test both.
@@ -81,8 +95,7 @@
   return (cond ? TakesTwo((TakeRef(A()), A()), (TakeRef(A()), A())) : CouldThrow());
 }
 
-// WIN32: define i32 @"\01?HasConditionalDeactivatedCleanups@@YAH_N@Z"{{.*}} {
-// WIN32:   %[[arg1:.*]] = alloca %struct.A, align 4
+// WIN32-LABEL: define i32 @"\01?HasConditionalDeactivatedCleanups@@YAH_N@Z"{{.*}} {
 // WIN32:   alloca i1
 // WIN32:   %[[arg1_cond:.*]] = alloca i1
 //        Start all four cleanups as deactivated.
@@ -92,10 +105,10 @@
 // WIN32:   store i1 false
 // WIN32:   br i1
 //        True condition.
-// WIN32:   call x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"
+// WIN32:   invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"
 // WIN32:   store i1 true
 // WIN32:   invoke void @"\01?TakeRef@@YAXABUA@@@Z"
-// WIN32:   invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"(%struct.A* %[[arg1]])
+// WIN32:   invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"
 // WIN32:   store i1 true, i1* %[[arg1_cond]]
 // WIN32:   invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"
 // WIN32:   store i1 true
@@ -108,13 +121,13 @@
 // WIN32:   invoke i32 @"\01?CouldThrow@@YAHXZ"()
 //        Two normal cleanups for TakeRef args.
 // WIN32:   invoke x86_thiscallcc void @"\01??1A@@QAE@XZ"
-// WIN32:   call x86_thiscallcc void @"\01??1A@@QAE@XZ"
+// WIN32:   invoke x86_thiscallcc void @"\01??1A@@QAE@XZ"
 // WIN32:   ret i32
 //
 //        Somewhere in the landing pad soup, we conditionally destroy arg1.
 // WIN32:   %[[isactive:.*]] = load i1* %[[arg1_cond]]
 // WIN32:   br i1 %[[isactive]]
-// WIN32:   invoke x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %[[arg1]])
+// WIN32:   invoke x86_thiscallcc void @"\01??1A@@QAE@XZ"
 // WIN32: }
 
 namespace crash_on_partial_destroy {
diff --git a/test/CodeGenCXX/microsoft-abi-member-pointers.cpp b/test/CodeGenCXX/microsoft-abi-member-pointers.cpp
index c0dcd3c..18e8c82 100644
--- a/test/CodeGenCXX/microsoft-abi-member-pointers.cpp
+++ b/test/CodeGenCXX/microsoft-abi-member-pointers.cpp
@@ -1,7 +1,11 @@
-// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -fms-extensions | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -fno-rtti -emit-llvm %s -o - -triple=x86_64-pc-win32 -fms-extensions | FileCheck %s -check-prefix=X64
+// RUN: %clang_cc1 -std=c++11 -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -DINCOMPLETE_VIRTUAL -fms-extensions -verify
+// RUN: %clang_cc1 -std=c++11 -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -DINCOMPLETE_VIRTUAL -DMEMFUN -fms-extensions -verify
 // FIXME: Test x86_64 member pointers when codegen no longer asserts on records
 // with virtual bases.
 
+#ifndef INCOMPLETE_VIRTUAL
 struct B1 {
   void foo();
   int b;
@@ -56,20 +60,20 @@
 // CHECK: @"\01?p_d_memptr@@3PQPolymorphic@@HQ1@" = global i32 0, align 4
 // CHECK: @"\01?m_d_memptr@@3PQMultiple@@HQ1@" = global i32 -1, align 4
 // CHECK: @"\01?v_d_memptr@@3PQVirtual@@HQ1@" = global { i32, i32 }
-// CHECK:   { i32 0, i32 -1 }, align 4
+// CHECK:   { i32 0, i32 -1 }, align 8
 // CHECK: @"\01?n_d_memptr@@3PQNonZeroVBPtr@@HQ1@" = global { i32, i32 }
-// CHECK:   { i32 0, i32 -1 }, align 4
+// CHECK:   { i32 0, i32 -1 }, align 8
 // CHECK: @"\01?u_d_memptr@@3PQUnspecified@@HQ1@" = global { i32, i32, i32 }
-// CHECK:   { i32 0, i32 0, i32 -1 }, align 4
+// CHECK:   { i32 0, i32 0, i32 -1 }, align 8
 // CHECK: @"\01?us_d_memptr@@3PQUnspecSingle@@HQ1@" = global { i32, i32, i32 }
-// CHECK:   { i32 0, i32 0, i32 -1 }, align 4
+// CHECK:   { i32 0, i32 0, i32 -1 }, align 8
 
 void (Single  ::*s_f_memptr)();
 void (Multiple::*m_f_memptr)();
 void (Virtual ::*v_f_memptr)();
 // CHECK: @"\01?s_f_memptr@@3P8Single@@AEXXZQ1@" = global i8* null, align 4
-// CHECK: @"\01?m_f_memptr@@3P8Multiple@@AEXXZQ1@" = global { i8*, i32 } zeroinitializer, align 4
-// CHECK: @"\01?v_f_memptr@@3P8Virtual@@AEXXZQ1@" = global { i8*, i32, i32 } zeroinitializer, align 4
+// CHECK: @"\01?m_f_memptr@@3P8Multiple@@AEXXZQ1@" = global { i8*, i32 } zeroinitializer, align 8
+// CHECK: @"\01?v_f_memptr@@3P8Virtual@@AEXXZQ1@" = global { i8*, i32, i32 } zeroinitializer, align 8
 
 // We can define Unspecified after locking in the inheritance model.
 struct Unspecified : Multiple, Virtual {
@@ -91,13 +95,13 @@
 // CHECK: @"\01?s_f_mp@Const@@3P8Single@@AEXXZQ2@" =
 // CHECK:   global i8* bitcast ({{.*}} @"\01?foo@Single@@QAEXXZ" to i8*), align 4
 // CHECK: @"\01?m_f_mp@Const@@3P8Multiple@@AEXXZQ2@" =
-// CHECK:   global { i8*, i32 } { i8* bitcast ({{.*}} @"\01?foo@B2@@QAEXXZ" to i8*), i32 4 }, align 4
+// CHECK:   global { i8*, i32 } { i8* bitcast ({{.*}} @"\01?foo@B2@@QAEXXZ" to i8*), i32 4 }, align 8
 // CHECK: @"\01?v_f_mp@Const@@3P8Virtual@@AEXXZQ2@" =
-// CHECK:   global { i8*, i32, i32 } { i8* bitcast ({{.*}} @"\01?foo@Virtual@@QAEXXZ" to i8*), i32 0, i32 0 }, align 4
+// CHECK:   global { i8*, i32, i32 } { i8* bitcast ({{.*}} @"\01?foo@Virtual@@QAEXXZ" to i8*), i32 0, i32 0 }, align 8
 // CHECK: @"\01?u_f_mp@Const@@3P8Unspecified@@AEXXZQ2@" =
-// CHECK:   global { i8*, i32, i32, i32 } { i8* bitcast ({{.*}} @"\01?foo@Unspecified@@QAEXXZ" to i8*), i32 0, i32 12, i32 0 }, align 4
+// CHECK:   global { i8*, i32, i32, i32 } { i8* bitcast ({{.*}} @"\01?foo@Unspecified@@QAEXXZ" to i8*), i32 0, i32 12, i32 0 }, align 8
 // CHECK: @"\01?us_f_mp@Const@@3P8UnspecSingle@@AEXXZQ2@" =
-// CHECK:   global { i8*, i32, i32, i32 } { i8* bitcast ({{.*}} @"\01?foo@UnspecSingle@@QAEXXZ" to i8*), i32 0, i32 0, i32 0 }, align 4
+// CHECK:   global { i8*, i32, i32, i32 } { i8* bitcast ({{.*}} @"\01?foo@UnspecSingle@@QAEXXZ" to i8*), i32 0, i32 0, i32 0 }, align 8
 }
 
 namespace CastParam {
@@ -119,11 +123,11 @@
 // Try a reinterpret_cast followed by a memptr conversion.
 void (C::*ptr2)(void *) = (void (C::*)(void *)) (void (A::*)(void *)) &A::foo;
 // CHECK: @"\01?ptr2@CastParam@@3P8C@1@AEXPAX@ZQ21@" =
-// CHECK:   global { i8*, i32 } { i8* bitcast (void ({{.*}})* @"\01?foo@A@CastParam@@QAEXPAU12@@Z" to i8*), i32 4 }, align 4
+// CHECK:   global { i8*, i32 } { i8* bitcast (void ({{.*}})* @"\01?foo@A@CastParam@@QAEXPAU12@@Z" to i8*), i32 4 }, align 8
 
 void (C::*ptr3)(void *) = (void (C::*)(void *)) (void (A::*)(void *)) (void (A::*)(A *)) 0;
 // CHECK: @"\01?ptr3@CastParam@@3P8C@1@AEXPAX@ZQ21@" =
-// CHECK:   global { i8*, i32 } zeroinitializer, align 4
+// CHECK:   global { i8*, i32 } zeroinitializer, align 8
 
 struct D : C {
   virtual void isPolymorphic();
@@ -156,23 +160,23 @@
   void (UnspecWithVBPtr::*u2_f_memptr)() = &UnspecWithVBPtr::foo;
 // CHECK: define void @"\01?EmitNonVirtualMemberPointers@@YAXXZ"() {{.*}} {
 // CHECK:   alloca i8*, align 4
-// CHECK:   alloca { i8*, i32 }, align 4
-// CHECK:   alloca { i8*, i32, i32 }, align 4
-// CHECK:   alloca { i8*, i32, i32, i32 }, align 4
+// CHECK:   alloca { i8*, i32 }, align 8
+// CHECK:   alloca { i8*, i32, i32 }, align 8
+// CHECK:   alloca { i8*, i32, i32, i32 }, align 8
 // CHECK:   store i8* bitcast (void (%{{.*}}*)* @"\01?foo@Single@@QAEXXZ" to i8*), i8** %{{.*}}, align 4
 // CHECK:   store { i8*, i32 }
 // CHECK:     { i8* bitcast (void (%{{.*}}*)* @"\01?foo@Multiple@@QAEXXZ" to i8*), i32 0 },
-// CHECK:     { i8*, i32 }* %{{.*}}, align 4
+// CHECK:     { i8*, i32 }* %{{.*}}, align 8
 // CHECK:   store { i8*, i32, i32 }
 // CHECK:     { i8* bitcast (void (%{{.*}}*)* @"\01?foo@Virtual@@QAEXXZ" to i8*), i32 0, i32 0 },
-// CHECK:     { i8*, i32, i32 }* %{{.*}}, align 4
+// CHECK:     { i8*, i32, i32 }* %{{.*}}, align 8
 // CHECK:   store { i8*, i32, i32, i32 }
 // CHECK:     { i8* bitcast (void (%{{.*}}*)* @"\01?foo@Unspecified@@QAEXXZ" to i8*), i32 0, i32 12, i32 0 },
-// CHECK:     { i8*, i32, i32, i32 }* %{{.*}}, align 4
+// CHECK:     { i8*, i32, i32, i32 }* %{{.*}}, align 8
 // CHECK:   store { i8*, i32, i32, i32 }
 // CHECK:     { i8* bitcast (void (%{{.*}}*)* @"\01?foo@UnspecWithVBPtr@@QAEXXZ" to i8*),
 // CHECK:       i32 0, i32 4, i32 0 },
-// CHECK:     { i8*, i32, i32, i32 }* %{{.*}}, align 4
+// CHECK:     { i8*, i32, i32, i32 }* %{{.*}}, align 8
 // CHECK:   ret void
 // CHECK: }
 }
@@ -219,27 +223,31 @@
 bool nullTestDataUnspecified(int Unspecified::*mp) {
   return mp;
 // CHECK: define zeroext i1 @"\01?nullTestDataUnspecified@@YA_NPQUnspecified@@H@Z"{{.*}} {
-// CHECK:   %{{.*}} = load { i32, i32, i32 }* %{{.*}}, align 4
-// CHECK:   store { i32, i32, i32 } {{.*}} align 4
-// CHECK:   %[[mp:.*]] = load { i32, i32, i32 }* %{{.*}}, align 4
+// CHECK:   %{{.*}} = load { i32, i32, i32 }* %{{.*}}, align 8
+// CHECK:   store { i32, i32, i32 } {{.*}} align 8
+// CHECK:   %[[mp:.*]] = load { i32, i32, i32 }* %{{.*}}, align 8
 // CHECK:   %[[mp0:.*]] = extractvalue { i32, i32, i32 } %[[mp]], 0
 // CHECK:   %[[cmp0:.*]] = icmp ne i32 %[[mp0]], 0
 // CHECK:   %[[mp1:.*]] = extractvalue { i32, i32, i32 } %[[mp]], 1
 // CHECK:   %[[cmp1:.*]] = icmp ne i32 %[[mp1]], 0
-// CHECK:   %[[and0:.*]] = and i1 %[[cmp0]], %[[cmp1]]
+// CHECK:   %[[and0:.*]] = or i1 %[[cmp0]], %[[cmp1]]
 // CHECK:   %[[mp2:.*]] = extractvalue { i32, i32, i32 } %[[mp]], 2
 // CHECK:   %[[cmp2:.*]] = icmp ne i32 %[[mp2]], -1
-// CHECK:   %[[and1:.*]] = and i1 %[[and0]], %[[cmp2]]
+// CHECK:   %[[and1:.*]] = or i1 %[[and0]], %[[cmp2]]
 // CHECK:   ret i1 %[[and1]]
 // CHECK: }
+
+// Pass this large type indirectly.
+// X64-LABEL: define zeroext i1 @"\01?nullTestDataUnspecified@@
+// X64:             ({ i32, i32, i32 }*)
 }
 
 bool nullTestFunctionUnspecified(void (Unspecified::*mp)()) {
   return mp;
 // CHECK: define zeroext i1 @"\01?nullTestFunctionUnspecified@@YA_NP8Unspecified@@AEXXZ@Z"{{.*}} {
-// CHECK:   %{{.*}} = load { i8*, i32, i32, i32 }* %{{.*}}, align 4
-// CHECK:   store { i8*, i32, i32, i32 } {{.*}} align 4
-// CHECK:   %[[mp:.*]] = load { i8*, i32, i32, i32 }* %{{.*}}, align 4
+// CHECK:   %{{.*}} = load { i8*, i32, i32, i32 }* %{{.*}}, align 8
+// CHECK:   store { i8*, i32, i32, i32 } {{.*}} align 8
+// CHECK:   %[[mp:.*]] = load { i8*, i32, i32, i32 }* %{{.*}}, align 8
 // CHECK:   %[[mp0:.*]] = extractvalue { i8*, i32, i32, i32 } %[[mp]], 0
 // CHECK:   %[[cmp0:.*]] = icmp ne i8* %[[mp0]], null
 // CHECK:   ret i1 %[[cmp0]]
@@ -252,7 +260,7 @@
 // data pointer.
 // CHECK: define i32 @"\01?loadDataMemberPointerVirtual@@YAHPAUVirtual@@PQ1@H@Z"{{.*}} {
 // CHECK:   %[[o:.*]] = load %{{.*}}** %{{.*}}, align 4
-// CHECK:   %[[memptr:.*]] = load { i32, i32 }* %{{.*}}, align 4
+// CHECK:   %[[memptr:.*]] = load { i32, i32 }* %{{.*}}, align 8
 // CHECK:   %[[memptr0:.*]] = extractvalue { i32, i32 } %[[memptr:.*]], 0
 // CHECK:   %[[memptr1:.*]] = extractvalue { i32, i32 } %[[memptr:.*]], 1
 // CHECK:   %[[v6:.*]] = bitcast %{{.*}}* %[[o]] to i8*
@@ -268,6 +276,11 @@
 // CHECK:   %[[v12:.*]] = load i32* %[[v11]]
 // CHECK:   ret i32 %[[v12]]
 // CHECK: }
+
+// A two-field data memptr on x64 gets coerced to i64 and is passed in a
+// register or memory.
+// X64-LABEL: define i32 @"\01?loadDataMemberPointerVirtual@@YAHPEAUVirtual@@PEQ1@H@Z"
+// X64:             (%struct.Virtual* %o, i64 %memptr.coerce)
 }
 
 int loadDataMemberPointerUnspecified(Unspecified *o, int Unspecified::*memptr) {
@@ -276,7 +289,7 @@
 // data pointer.
 // CHECK: define i32 @"\01?loadDataMemberPointerUnspecified@@YAHPAUUnspecified@@PQ1@H@Z"{{.*}} {
 // CHECK:   %[[o:.*]] = load %{{.*}}** %{{.*}}, align 4
-// CHECK:   %[[memptr:.*]] = load { i32, i32, i32 }* %{{.*}}, align 4
+// CHECK:   %[[memptr:.*]] = load { i32, i32, i32 }* %{{.*}}, align 8
 // CHECK:   %[[memptr0:.*]] = extractvalue { i32, i32, i32 } %[[memptr:.*]], 0
 // CHECK:   %[[memptr1:.*]] = extractvalue { i32, i32, i32 } %[[memptr:.*]], 1
 // CHECK:   %[[memptr2:.*]] = extractvalue { i32, i32, i32 } %[[memptr:.*]], 2
@@ -309,6 +322,11 @@
 // CHECK:   call x86_thiscallcc void %{{.*}}(%{{.*}} %{{.*}})
 // CHECK:   ret void
 // CHECK: }
+
+// X64-LABEL: define void @"\01?callMemberPointerSingle@@
+// X64:           (%struct.Single* %o, i8* %memptr)
+// X64:   bitcast i8* %{{[^ ]*}} to void (%struct.Single*)*
+// X64:   ret void
 }
 
 void callMemberPointerMultiple(Multiple *o, void (Multiple::*memptr)()) {
@@ -355,6 +373,9 @@
 // CHECK-NOT: icmp
 // CHECK:   ret i1 %[[r]]
 // CHECK: }
+
+// X64-LABEL: define zeroext i1 @"\01?compareSingleFunctionMemptr@@
+// X64:             (i8* %{{[^,]*}}, i8* %{{[^)]*}})
 }
 
 bool compareNeqSingleFunctionMemptr(void (Single::*l)(), void (Single::*r)()) {
@@ -390,6 +411,9 @@
 // CHECK:   %{{.*}} = and i1 %[[bits_or_null]], %[[cmp0]]
 // CHECK:   ret i1 %{{.*}}
 // CHECK: }
+
+// X64-LABEL: define zeroext i1 @"\01?unspecFuncMemptrEq@@
+// X64:             ({ i8*, i32, i32, i32 }*, { i8*, i32, i32, i32 }*)
 }
 
 bool unspecFuncMemptrNeq(void (Unspecified::*l)(), void (Unspecified::*r)()) {
@@ -432,6 +456,9 @@
 // CHECK:   and i1
 // CHECK:   ret i1
 // CHECK: }
+
+// X64-LABEL: define zeroext i1 @"\01?unspecDataMemptrEq@@
+// X64:             ({ i32, i32, i32 }*, { i32, i32, i32 }*)
 }
 
 void (Multiple::*convertB2FuncToMultiple(void (B2::*mp)()))() {
@@ -462,7 +489,7 @@
 //
 // CHECK: define i32 @"\01?convertMultipleFuncToB2@@YAP8B2@@AEXXZP8Multiple@@AEXXZ@Z"{{.*}} {
 // CHECK:   store
-// CHECK:   %[[src:.*]] = load { i8*, i32 }* %{{.*}}, align 4
+// CHECK:   %[[src:.*]] = load { i8*, i32 }* %{{.*}}, align 8
 // CHECK:   extractvalue { i8*, i32 } %[[src]], 0
 // CHECK:   icmp ne i8* %{{.*}}, null
 // CHECK:   br i1 %{{.*}}, label %{{.*}}, label %{{.*}}
@@ -487,7 +514,7 @@
   return mp;
 // CHECK: define void @"\01?convertCToD@Test1@@YAP8D@1@AEXXZP8C@1@AEXXZ@Z"{{.*}} {
 // CHECK:   store
-// CHECK:   load { i8*, i32, i32 }* %{{.*}}, align 4
+// CHECK:   load { i8*, i32, i32 }* %{{.*}}, align 8
 // CHECK:   extractvalue { i8*, i32, i32 } %{{.*}}, 0
 // CHECK:   icmp ne i8* %{{.*}}, null
 // CHECK:   br i1 %{{.*}}, label %{{.*}}, label %{{.*}}
@@ -537,3 +564,92 @@
 }
 
 }
+
+namespace Test3 {
+// Make sure we cast 'this' to i8* before using GEP.
+
+struct A {
+  int a;
+  int b;
+};
+
+int *load_data(A *a, int A::*mp) {
+  return &(a->*mp);
+// CHECK-LABEL: define i32* @"\01?load_data@Test3@@YAPAHPAUA@1@PQ21@H@Z"{{.*}}  {
+// CHECK:    %[[a:.*]] = load %"struct.Test3::A"** %{{.*}}, align 4
+// CHECK:    %[[mp:.*]] = load i32* %{{.*}}, align 4
+// CHECK:    %[[a_i8:.*]] = bitcast %"struct.Test3::A"* %[[a]] to i8*
+// CHECK:    getelementptr inbounds i8* %[[a_i8]], i32 %[[mp]]
+// CHECK: }
+}
+
+}
+
+namespace Test4 {
+
+struct A        { virtual void f(); };
+struct B        { virtual void g(); };
+struct C : A, B { virtual void g(); };
+
+void (C::*getmp())() {
+  return &C::g;
+}
+// CHECK-LABEL: define i64 @"\01?getmp@Test4@@YAP8C@1@AEXXZXZ"()
+// CHECK: store { i8*, i32 } { i8* bitcast (void (i8*)* @"\01??_9C@Test4@@$BA@AE" to i8*), i32 4 }, { i8*, i32 }* %{{.*}}
+//
+
+// CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_9C@Test4@@$BA@AE"(i8*)
+// CHECK-NOT:  getelementptr
+// CHECK:  load void (i8*)*** %{{.*}}
+// CHECK:  getelementptr inbounds void (i8*)** %{{.*}}, i64 0
+// CHECK-NOT:  getelementptr
+// CHECK:  call x86_thiscallcc void %
+
+}
+
+namespace pr20007 {
+struct A {
+  void f();
+  void f(int);
+};
+struct B : public A {};
+void test() { void (B::*a)() = &B::f; }
+// CHECK-LABEL: define void @"\01?test@pr20007@@YAXXZ"
+// CHECK: store i8* bitcast (void (%"struct.pr20007::A"*)* @"\01?f@A@pr20007@@QAEXXZ" to i8*)
+}
+
+namespace pr20007_kw {
+struct A {
+  void f();
+  void f(int);
+};
+struct __single_inheritance B;
+struct B : public A {};
+void test() { void (B::*a)() = &B::f; }
+// CHECK-LABEL: define void @"\01?test@pr20007_kw@@YAXXZ"
+// CHECK: store i8* bitcast (void (%"struct.pr20007_kw::A"*)* @"\01?f@A@pr20007_kw@@QAEXXZ" to i8*)
+}
+
+namespace pr19987 {
+template <typename T>
+struct S {
+  int T::*x;
+};
+
+struct U : S<U> {};
+
+static_assert(sizeof(S<U>::x) == 12, "");
+}
+
+#else
+struct __virtual_inheritance A;
+#ifdef MEMFUN
+int foo(A *a, int (A::*mp)()) {
+    return (a->*mp)(); // expected-error{{requires a complete class type}}
+}
+#else
+int foo(A *a, int A::*mp) {
+    return a->*mp; // expected-error{{requires a complete class type}}
+}
+#endif
+#endif
diff --git a/test/CodeGenCXX/microsoft-abi-methods.cpp b/test/CodeGenCXX/microsoft-abi-methods.cpp
index c996ba5..579e549 100644
--- a/test/CodeGenCXX/microsoft-abi-methods.cpp
+++ b/test/CodeGenCXX/microsoft-abi-methods.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
 
 class C {
  public:
diff --git a/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp b/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp
index 802f0ca..b1c1482 100644
--- a/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp
+++ b/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -mconstructor-aliases -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -mconstructor-aliases -triple=i386-pc-win32 | FileCheck %s
 
 struct Left {
   virtual void left();
diff --git a/test/CodeGenCXX/microsoft-abi-non-virtual-base-ordering.cpp b/test/CodeGenCXX/microsoft-abi-non-virtual-base-ordering.cpp
new file mode 100755
index 0000000..0c82ac3
--- /dev/null
+++ b/test/CodeGenCXX/microsoft-abi-non-virtual-base-ordering.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fno-rtti -emit-llvm -triple=i686-pc-win32 -o - %s  2>/dev/null | FileCheck %s
+// RUN: %clang_cc1 -fno-rtti -emit-llvm -triple=x86_64-pc-win32 -o - %s  2>/dev/null | FileCheck %s
+
+struct C0 { int a; };
+struct C1 { int a; virtual void C1M() {} };
+struct C2 { int a; virtual void C2M() {} };
+struct C3 : C0, C1, C2 {} a;
+
+// Check to see that both C1 and C2 get laid out before C0 does.
+// CHECK: %struct.C3 = type { %struct.C1, %struct.C2, %struct.C0 }
diff --git a/test/CodeGenCXX/microsoft-abi-nontrivial-covariant-thunk.cpp b/test/CodeGenCXX/microsoft-abi-nontrivial-covariant-thunk.cpp
new file mode 100644
index 0000000..d305dd8
--- /dev/null
+++ b/test/CodeGenCXX/microsoft-abi-nontrivial-covariant-thunk.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 %s -fno-rtti -emit-llvm-only -o - -triple=i386-pc-win32 -verify
+
+// A is not trivially copyable and must be passed indirectly or with inalloca.
+struct A {
+  A();
+  A(const A &o);
+  virtual ~A();
+  int a;
+};
+
+struct B {
+  B();
+  int b;
+  virtual B *clone(A);
+};
+
+// Converting from C* to B* requires a this adjustment.
+struct C : A, B {
+  C();
+  int c;
+  virtual C *clone(A); // expected-error {{cannot compile this non-trivial argument copy for thunk yet}}
+};
+B::B() {}  // force emission
+C::C() {}  // force emission
diff --git a/test/CodeGenCXX/microsoft-abi-rtti.cpp b/test/CodeGenCXX/microsoft-abi-rtti.cpp
new file mode 100644
index 0000000..062f597
--- /dev/null
+++ b/test/CodeGenCXX/microsoft-abi-rtti.cpp
@@ -0,0 +1,267 @@
+// RUN: %clang_cc1 -emit-llvm -o - -triple=i386-pc-win32 2>/dev/null %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -o - -triple=x86_64-pc-win32 2>/dev/null %s | FileCheck --check-prefix=X64 %s
+
+struct N {};
+struct M : private N {};
+struct X { virtual void f() {} };
+class Z { virtual void f() {} };
+class V : public X { virtual void f() {} };
+class W : M, virtual V { public: virtual void f() {} };
+class Y : Z, W, virtual V { public: virtual void g() {} } y;
+
+struct A {};
+struct B : A {};
+struct C : B { virtual void f() {} } c;
+
+struct X1 { virtual void f() {} };
+struct V1 : X1 {};
+struct W1 : virtual V1 {};
+struct Y1 : W1, virtual V1 {} y1;
+
+struct A1 { virtual void f() {} };
+struct B1 : virtual A1 { virtual void f() {} B1() {} } b1;
+
+struct Z2 { virtual void f() {} };
+struct Y2 { virtual void f() {} };
+struct A2 : Z2, Y2 {};
+struct B2 : virtual A2 { B2() {} virtual void f() {} } b2;
+
+// CHECK: @"\01??_R4B2@@6BZ2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 8, i32 4, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUB2@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3B2@@8" }
+// CHECK: @"\01??_R0?AUB2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUB2@@\00" }
+// CHECK: @"\01??_R3B2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 4, %rtti.BaseClassDescriptor** getelementptr inbounds ([5 x %rtti.BaseClassDescriptor*]* @"\01??_R2B2@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2B2@@8" = linkonce_odr constant [5 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@B2@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@A2@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3EA@Z2@@8", %rtti.BaseClassDescriptor* @"\01??_R13A@3EA@Y2@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R1A@?0A@EA@B2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUB2@@@8" to i8*), i32 3, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3B2@@8" }
+// CHECK: @"\01??_R1A@A@3FA@A2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUA2@@@8" to i8*), i32 2, i32 0, i32 0, i32 4, i32 80, %rtti.ClassHierarchyDescriptor* @"\01??_R3A2@@8" }
+// CHECK: @"\01??_R0?AUA2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUA2@@\00" }
+// CHECK: @"\01??_R3A2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 1, i32 3, %rtti.BaseClassDescriptor** getelementptr inbounds ([4 x %rtti.BaseClassDescriptor*]* @"\01??_R2A2@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2A2@@8" = linkonce_odr constant [4 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@A2@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Z2@@8", %rtti.BaseClassDescriptor* @"\01??_R13?0A@EA@Y2@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R1A@?0A@EA@A2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUA2@@@8" to i8*), i32 2, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3A2@@8" }
+// CHECK: @"\01??_R1A@?0A@EA@Z2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUZ2@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3Z2@@8" }
+// CHECK: @"\01??_R0?AUZ2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUZ2@@\00" }
+// CHECK: @"\01??_R3Z2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*]* @"\01??_R2Z2@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2Z2@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Z2@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R13?0A@EA@Y2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUY2@@@8" to i8*), i32 0, i32 4, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3Y2@@8" }
+// CHECK: @"\01??_R0?AUY2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUY2@@\00" }
+// CHECK: @"\01??_R3Y2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*]* @"\01??_R2Y2@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2Y2@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Y2@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R1A@?0A@EA@Y2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUY2@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3Y2@@8" }
+// CHECK: @"\01??_R1A@A@3EA@Z2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUZ2@@@8" to i8*), i32 0, i32 0, i32 0, i32 4, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3Z2@@8" }
+// CHECK: @"\01??_R13A@3EA@Y2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUY2@@@8" to i8*), i32 0, i32 4, i32 0, i32 4, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3Y2@@8" }
+// CHECK: @"\01??_R4B2@@6BY2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 12, i32 8, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUB2@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3B2@@8" }
+// CHECK: @"\01??_R4A2@@6BZ2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUA2@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3A2@@8" }
+// CHECK: @"\01??_R4A2@@6BY2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 4, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUA2@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3A2@@8" }
+// CHECK: @"\01??_R4Y2@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUY2@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3Y2@@8" }
+// CHECK: @"\01??_R4Z2@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUZ2@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3Z2@@8" }
+// CHECK: @"\01??_R4B1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 8, i32 4, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUB1@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3B1@@8" }
+// CHECK: @"\01??_R0?AUB1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUB1@@\00" }
+// CHECK: @"\01??_R3B1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, %rtti.BaseClassDescriptor** getelementptr inbounds ([3 x %rtti.BaseClassDescriptor*]* @"\01??_R2B1@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2B1@@8" = linkonce_odr constant [3 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@B1@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@A1@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R1A@?0A@EA@B1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUB1@@@8" to i8*), i32 1, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3B1@@8" }
+// CHECK: @"\01??_R1A@A@3FA@A1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUA1@@@8" to i8*), i32 0, i32 0, i32 0, i32 4, i32 80, %rtti.ClassHierarchyDescriptor* @"\01??_R3A1@@8" }
+// CHECK: @"\01??_R0?AUA1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUA1@@\00" }
+// CHECK: @"\01??_R3A1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*]* @"\01??_R2A1@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2A1@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@A1@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R1A@?0A@EA@A1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUA1@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3A1@@8" }
+// CHECK: @"\01??_R4A1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUA1@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3A1@@8" }
+// CHECK: @"\01??_R4Y1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 4, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUY1@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3Y1@@8" }
+// CHECK: @"\01??_R0?AUY1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUY1@@\00" }
+// CHECK: @"\01??_R3Y1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 6, %rtti.BaseClassDescriptor** getelementptr inbounds ([7 x %rtti.BaseClassDescriptor*]* @"\01??_R2Y1@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2Y1@@8" = linkonce_odr constant [7 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Y1@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@W1@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@V1@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3EA@X1@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@V1@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3EA@X1@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R1A@?0A@EA@Y1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUY1@@@8" to i8*), i32 5, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3Y1@@8" }
+// CHECK: @"\01??_R1A@?0A@EA@W1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUW1@@@8" to i8*), i32 2, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3W1@@8" }
+// CHECK: @"\01??_R0?AUW1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUW1@@\00" }
+// CHECK: @"\01??_R3W1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 3, %rtti.BaseClassDescriptor** getelementptr inbounds ([4 x %rtti.BaseClassDescriptor*]* @"\01??_R2W1@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2W1@@8" = linkonce_odr constant [4 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@W1@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@V1@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3EA@X1@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R1A@A@3FA@V1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUV1@@@8" to i8*), i32 1, i32 0, i32 0, i32 4, i32 80, %rtti.ClassHierarchyDescriptor* @"\01??_R3V1@@8" }
+// CHECK: @"\01??_R0?AUV1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUV1@@\00" }
+// CHECK: @"\01??_R3V1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, %rtti.BaseClassDescriptor** getelementptr inbounds ([3 x %rtti.BaseClassDescriptor*]* @"\01??_R2V1@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2V1@@8" = linkonce_odr constant [3 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@V1@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@X1@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R1A@?0A@EA@V1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUV1@@@8" to i8*), i32 1, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3V1@@8" }
+// CHECK: @"\01??_R1A@?0A@EA@X1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUX1@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3X1@@8" }
+// CHECK: @"\01??_R0?AUX1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUX1@@\00" }
+// CHECK: @"\01??_R3X1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*]* @"\01??_R2X1@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2X1@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@X1@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R1A@A@3EA@X1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUX1@@@8" to i8*), i32 0, i32 0, i32 0, i32 4, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3X1@@8" }
+// CHECK: @"\01??_R4W1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 4, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUW1@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3W1@@8" }
+// CHECK: @"\01??_R4V1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUV1@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3V1@@8" }
+// CHECK: @"\01??_R4X1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUX1@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3X1@@8" }
+// CHECK: @"\01??_R4C@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUC@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3C@@8" }
+// CHECK: @"\01??_R0?AUC@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUC@@\00" }
+// CHECK: @"\01??_R3C@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 3, %rtti.BaseClassDescriptor** getelementptr inbounds ([4 x %rtti.BaseClassDescriptor*]* @"\01??_R2C@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2C@@8" = linkonce_odr constant [4 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@C@@8", %rtti.BaseClassDescriptor* @"\01??_R13?0A@EA@B@@8", %rtti.BaseClassDescriptor* @"\01??_R13?0A@EA@A@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R1A@?0A@EA@C@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUC@@@8" to i8*), i32 2, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3C@@8" }
+// CHECK: @"\01??_R13?0A@EA@B@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUB@@@8" to i8*), i32 1, i32 4, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3B@@8" }
+// CHECK: @"\01??_R0?AUB@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUB@@\00" }
+// CHECK: @"\01??_R3B@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, %rtti.BaseClassDescriptor** getelementptr inbounds ([3 x %rtti.BaseClassDescriptor*]* @"\01??_R2B@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2B@@8" = linkonce_odr constant [3 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@B@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@A@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R1A@?0A@EA@B@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUB@@@8" to i8*), i32 1, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3B@@8" }
+// CHECK: @"\01??_R1A@?0A@EA@A@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUA@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3A@@8" }
+// CHECK: @"\01??_R0?AUA@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUA@@\00" }
+// CHECK: @"\01??_R3A@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*]* @"\01??_R2A@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2A@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@A@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R13?0A@EA@A@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUA@@@8" to i8*), i32 0, i32 4, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3A@@8" }
+// CHECK: @"\01??_R4Y@@6BZ@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVY@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3Y@@8" }
+// CHECK: @"\01??_R0?AVY@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AVY@@\00" }
+// CHECK: @"\01??_R3Y@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 9, %rtti.BaseClassDescriptor** getelementptr inbounds ([10 x %rtti.BaseClassDescriptor*]* @"\01??_R2Y@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2Y@@8" = linkonce_odr constant [10 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Y@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EN@Z@@8", %rtti.BaseClassDescriptor* @"\01??_R13?0A@EN@W@@8", %rtti.BaseClassDescriptor* @"\01??_R17?0A@EN@M@@8", %rtti.BaseClassDescriptor* @"\01??_R17?0A@EN@N@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@33FN@V@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@33EJ@X@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@33FN@V@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@33EJ@X@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R1A@?0A@EA@Y@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVY@@@8" to i8*), i32 8, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3Y@@8" }
+// CHECK: @"\01??_R1A@?0A@EN@Z@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVZ@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 77, %rtti.ClassHierarchyDescriptor* @"\01??_R3Z@@8" }
+// CHECK: @"\01??_R0?AVZ@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AVZ@@\00" }
+// CHECK: @"\01??_R3Z@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*]* @"\01??_R2Z@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2Z@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Z@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R1A@?0A@EA@Z@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVZ@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3Z@@8" }
+// CHECK: @"\01??_R13?0A@EN@W@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVW@@@8" to i8*), i32 4, i32 4, i32 -1, i32 0, i32 77, %rtti.ClassHierarchyDescriptor* @"\01??_R3W@@8" }
+// CHECK: @"\01??_R0?AVW@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AVW@@\00" }
+// CHECK: @"\01??_R3W@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 5, %rtti.BaseClassDescriptor** getelementptr inbounds ([6 x %rtti.BaseClassDescriptor*]* @"\01??_R2W@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2W@@8" = linkonce_odr constant [6 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@W@@8", %rtti.BaseClassDescriptor* @"\01??_R13?0A@EN@M@@8", %rtti.BaseClassDescriptor* @"\01??_R13?0A@EN@N@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3FN@V@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3EJ@X@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R1A@?0A@EA@W@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVW@@@8" to i8*), i32 4, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3W@@8" }
+// CHECK: @"\01??_R13?0A@EN@M@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUM@@@8" to i8*), i32 1, i32 4, i32 -1, i32 0, i32 77, %rtti.ClassHierarchyDescriptor* @"\01??_R3M@@8" }
+// CHECK: @"\01??_R0?AUM@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUM@@\00" }
+// CHECK: @"\01??_R3M@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, %rtti.BaseClassDescriptor** getelementptr inbounds ([3 x %rtti.BaseClassDescriptor*]* @"\01??_R2M@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2M@@8" = linkonce_odr constant [3 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@M@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EN@N@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R1A@?0A@EA@M@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUM@@@8" to i8*), i32 1, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3M@@8" }
+// CHECK: @"\01??_R1A@?0A@EN@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUN@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 77, %rtti.ClassHierarchyDescriptor* @"\01??_R3N@@8" }
+// CHECK: @"\01??_R0?AUN@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUN@@\00" }
+// CHECK: @"\01??_R3N@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*]* @"\01??_R2N@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2N@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@N@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R1A@?0A@EA@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUN@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3N@@8" }
+// CHECK: @"\01??_R13?0A@EN@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUN@@@8" to i8*), i32 0, i32 4, i32 -1, i32 0, i32 77, %rtti.ClassHierarchyDescriptor* @"\01??_R3N@@8" }
+// CHECK: @"\01??_R1A@A@3FN@V@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVV@@@8" to i8*), i32 1, i32 0, i32 0, i32 4, i32 93, %rtti.ClassHierarchyDescriptor* @"\01??_R3V@@8" }
+// CHECK: @"\01??_R0?AVV@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AVV@@\00" }
+// CHECK: @"\01??_R3V@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, %rtti.BaseClassDescriptor** getelementptr inbounds ([3 x %rtti.BaseClassDescriptor*]* @"\01??_R2V@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2V@@8" = linkonce_odr constant [3 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@V@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@X@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R1A@?0A@EA@V@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVV@@@8" to i8*), i32 1, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3V@@8" }
+// CHECK: @"\01??_R1A@?0A@EA@X@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUX@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3X@@8" }
+// CHECK: @"\01??_R0?AUX@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUX@@\00" }
+// CHECK: @"\01??_R3X@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*]* @"\01??_R2X@@8", i32 0, i32 0) }
+// CHECK: @"\01??_R2X@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@X@@8", %rtti.BaseClassDescriptor* null]
+// CHECK: @"\01??_R1A@A@3EJ@X@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUX@@@8" to i8*), i32 0, i32 0, i32 0, i32 4, i32 73, %rtti.ClassHierarchyDescriptor* @"\01??_R3X@@8" }
+// CHECK: @"\01??_R17?0A@EN@M@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUM@@@8" to i8*), i32 1, i32 8, i32 -1, i32 0, i32 77, %rtti.ClassHierarchyDescriptor* @"\01??_R3M@@8" }
+// CHECK: @"\01??_R17?0A@EN@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUN@@@8" to i8*), i32 0, i32 8, i32 -1, i32 0, i32 77, %rtti.ClassHierarchyDescriptor* @"\01??_R3N@@8" }
+// CHECK: @"\01??_R1A@33FN@V@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVV@@@8" to i8*), i32 1, i32 0, i32 4, i32 4, i32 93, %rtti.ClassHierarchyDescriptor* @"\01??_R3V@@8" }
+// CHECK: @"\01??_R1A@33EJ@X@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUX@@@8" to i8*), i32 0, i32 0, i32 4, i32 4, i32 73, %rtti.ClassHierarchyDescriptor* @"\01??_R3X@@8" }
+// CHECK: @"\01??_R4Y@@6BW@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 8, i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVY@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3Y@@8" }
+// CHECK: @"\01??_R4W@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 4, i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVW@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3W@@8" }
+// CHECK: @"\01??_R4Z@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVZ@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3Z@@8" }
+// CHECK: @"\01??_R4V@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVV@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3V@@8" }
+// CHECK: @"\01??_R4X@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUX@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3X@@8" }
+
+// X64: @"\01??_R4B2@@6BZ2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 16, i32 4, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUB2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3B2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4B2@@6BZ2@@@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AUB2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUB2@@\00" }
+// X64: @"\01??_R3B2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 4, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([5 x i32]* @"\01??_R2B2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2B2@@8" = linkonce_odr constant [5 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@B2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@A2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3EA@Z2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R17A@3EA@Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R1A@?0A@EA@B2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUB2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 3, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3B2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R1A@A@3FA@A2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUA2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 2, i32 0, i32 0, i32 4, i32 80, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AUA2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUA2@@\00" }
+// X64: @"\01??_R3A2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 1, i32 3, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([4 x i32]* @"\01??_R2A2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2A2@@8" = linkonce_odr constant [4 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@A2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Z2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R17?0A@EA@Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R1A@?0A@EA@A2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUA2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 2, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R1A@?0A@EA@Z2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUZ2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Z2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AUZ2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUZ2@@\00" }
+// X64: @"\01??_R3Z2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"\01??_R2Z2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2Z2@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Z2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R17?0A@EA@Y2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUY2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 8, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AUY2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUY2@@\00" }
+// X64: @"\01??_R3Y2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"\01??_R2Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2Y2@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R1A@?0A@EA@Y2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUY2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R1A@A@3EA@Z2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUZ2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 0, i32 4, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Z2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R17A@3EA@Y2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUY2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 8, i32 0, i32 4, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R4B2@@6BY2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 24, i32 12, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUB2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3B2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4B2@@6BY2@@@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R4A2@@6BZ2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUA2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4A2@@6BZ2@@@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R4A2@@6BY2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 8, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUA2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4A2@@6BY2@@@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R4Y2@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUY2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4Y2@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R4Z2@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUZ2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Z2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4Z2@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R4B1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 16, i32 4, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUB1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3B1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4B1@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AUB1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUB1@@\00" }
+// X64: @"\01??_R3B1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([3 x i32]* @"\01??_R2B1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2B1@@8" = linkonce_odr constant [3 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@B1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@A1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R1A@?0A@EA@B1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUB1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3B1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R1A@A@3FA@A1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUA1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 0, i32 4, i32 80, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AUA1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUA1@@\00" }
+// X64: @"\01??_R3A1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"\01??_R2A1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2A1@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@A1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R1A@?0A@EA@A1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUA1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R4A1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUA1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4A1@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R4Y1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 8, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUY1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Y1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4Y1@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AUY1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUY1@@\00" }
+// X64: @"\01??_R3Y1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 6, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([7 x i32]* @"\01??_R2Y1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2Y1@@8" = linkonce_odr constant [7 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Y1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@W1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3EA@X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3EA@X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R1A@?0A@EA@Y1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUY1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 5, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Y1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R1A@?0A@EA@W1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUW1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 2, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3W1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AUW1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUW1@@\00" }
+// X64: @"\01??_R3W1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 3, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([4 x i32]* @"\01??_R2W1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2W1@@8" = linkonce_odr constant [4 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@W1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3EA@X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R1A@A@3FA@V1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUV1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 0, i32 4, i32 80, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AUV1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUV1@@\00" }
+// X64: @"\01??_R3V1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([3 x i32]* @"\01??_R2V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2V1@@8" = linkonce_odr constant [3 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R1A@?0A@EA@V1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUV1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R1A@?0A@EA@X1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUX1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AUX1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUX1@@\00" }
+// X64: @"\01??_R3X1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"\01??_R2X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2X1@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R1A@A@3EA@X1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUX1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 0, i32 4, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R4W1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 8, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUW1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3W1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4W1@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R4V1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUV1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4V1@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R4X1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUX1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4X1@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R4C@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUC@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3C@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4C@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AUC@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUC@@\00" }
+// X64: @"\01??_R3C@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 3, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([4 x i32]* @"\01??_R2C@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2C@@8" = linkonce_odr constant [4 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@C@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R17?0A@EA@B@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R17?0A@EA@A@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R1A@?0A@EA@C@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUC@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 2, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3C@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R17?0A@EA@B@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUB@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 8, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3B@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AUB@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUB@@\00" }
+// X64: @"\01??_R3B@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([3 x i32]* @"\01??_R2B@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2B@@8" = linkonce_odr constant [3 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@B@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@A@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R1A@?0A@EA@B@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUB@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3B@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R1A@?0A@EA@A@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUA@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AUA@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUA@@\00" }
+// X64: @"\01??_R3A@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"\01??_R2A@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2A@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@A@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R17?0A@EA@A@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUA@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 8, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R4Y@@6BZ@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVY@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Y@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4Y@@6BZ@@@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AVY@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AVY@@\00" }
+// X64: @"\01??_R3Y@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 9, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([10 x i32]* @"\01??_R2Y@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2Y@@8" = linkonce_odr constant [10 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Y@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EN@Z@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R17?0A@EN@W@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1BA@?0A@EN@M@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1BA@?0A@EN@N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@73FN@V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@73EJ@X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@73FN@V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@73EJ@X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R1A@?0A@EA@Y@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVY@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 8, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Y@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R1A@?0A@EN@Z@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVZ@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 77, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Z@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AVZ@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AVZ@@\00" }
+// X64: @"\01??_R3Z@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"\01??_R2Z@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2Z@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Z@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R1A@?0A@EA@Z@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVZ@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Z@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R17?0A@EN@W@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVW@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 4, i32 8, i32 -1, i32 0, i32 77, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3W@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AVW@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AVW@@\00" }
+// X64: @"\01??_R3W@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 5, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([6 x i32]* @"\01??_R2W@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2W@@8" = linkonce_odr constant [6 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@W@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R17?0A@EN@M@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R17?0A@EN@N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3FN@V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3EJ@X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R1A@?0A@EA@W@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVW@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 4, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3W@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R17?0A@EN@M@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUM@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 8, i32 -1, i32 0, i32 77, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3M@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AUM@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUM@@\00" }
+// X64: @"\01??_R3M@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([3 x i32]* @"\01??_R2M@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2M@@8" = linkonce_odr constant [3 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@M@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EN@N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R1A@?0A@EA@M@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUM@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3M@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R1A@?0A@EN@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUN@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 77, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AUN@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUN@@\00" }
+// X64: @"\01??_R3N@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"\01??_R2N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2N@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R1A@?0A@EA@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUN@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R17?0A@EN@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUN@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 8, i32 -1, i32 0, i32 77, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R1A@A@3FN@V@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVV@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 0, i32 4, i32 93, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AVV@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AVV@@\00" }
+// X64: @"\01??_R3V@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([3 x i32]* @"\01??_R2V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2V@@8" = linkonce_odr constant [3 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R1A@?0A@EA@V@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVV@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R1A@?0A@EA@X@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUX@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R0?AUX@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUX@@\00" }
+// X64: @"\01??_R3X@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"\01??_R2X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R2X@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0]
+// X64: @"\01??_R1A@A@3EJ@X@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUX@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 0, i32 4, i32 73, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R1BA@?0A@EN@M@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUM@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 16, i32 -1, i32 0, i32 77, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3M@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R1BA@?0A@EN@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUN@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 16, i32 -1, i32 0, i32 77, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R1A@73FN@V@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVV@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 8, i32 4, i32 93, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R1A@73EJ@X@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUX@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 8, i32 4, i32 73, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R4Y@@6BW@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 16, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVY@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Y@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4Y@@6BW@@@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R4W@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 8, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVW@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3W@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4W@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R4Z@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVZ@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Z@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4Z@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R4V@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVV@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4V@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
+// X64: @"\01??_R4X@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUX@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4X@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }
diff --git a/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp b/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
index d0750e6..96c23c6 100644
--- a/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
+++ b/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-linux | FileCheck -check-prefix LINUX %s
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 -mconstructor-aliases -cxx-abi microsoft -fno-rtti | FileCheck -check-prefix WIN32 %s
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-pc-win32 -mconstructor-aliases -cxx-abi microsoft -fno-rtti | FileCheck -check-prefix WIN64 %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 -mconstructor-aliases -fno-rtti | FileCheck -check-prefix WIN32 %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-pc-win32 -mconstructor-aliases -fno-rtti | FileCheck -check-prefix WIN64 %s
 
 struct Empty {};
 
@@ -47,6 +47,20 @@
   int a, b, c, d, e, f;
 };
 
+struct BigWithDtor {
+  BigWithDtor();
+  ~BigWithDtor();
+  int a, b, c, d, e, f;
+};
+
+// 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)
+void take_bools_and_chars(char a, char b, SmallWithDtor c, char d, bool e, int f, bool g);
+void call_bools_and_chars() {
+  take_bools_and_chars('A', 'B', SmallWithDtor(), 'D', true, 13, false);
+}
+
 // Returning structs that fit into a register.
 Small small_return() { return Small(); }
 // LINUX-LABEL: define void @_Z12small_returnv(%struct.Small* noalias sret %agg.result)
@@ -103,18 +117,46 @@
 
 // Test that dtors are invoked in the callee.
 void small_arg_with_dtor(SmallWithDtor s) {}
-// WIN32: define void @"\01?small_arg_with_dtor@@YAXUSmallWithDtor@@@Z"(%struct.SmallWithDtor* byval align 4 %s) {{.*}} {
-// WIN32:   call x86_thiscallcc void @"\01??1SmallWithDtor@@QAE@XZ"(%struct.SmallWithDtor* %s)
+// WIN32: define void @"\01?small_arg_with_dtor@@YAXUSmallWithDtor@@@Z"(<{ %struct.SmallWithDtor }>* inalloca) {{.*}} {
+// WIN32:   call x86_thiscallcc void @"\01??1SmallWithDtor@@QAE@XZ"
 // WIN32: }
-// WIN64: define void @"\01?small_arg_with_dtor@@YAXUSmallWithDtor@@@Z"(%struct.SmallWithDtor* byval %s) {{.*}} {
-// WIN64:   call void @"\01??1SmallWithDtor@@QEAA@XZ"(%struct.SmallWithDtor* %s)
+// WIN64: define void @"\01?small_arg_with_dtor@@YAXUSmallWithDtor@@@Z"(i32 %s.coerce) {{.*}} {
+// WIN64:   call void @"\01??1SmallWithDtor@@QEAA@XZ"
 // WIN64: }
 
+void call_small_arg_with_dtor() {
+  small_arg_with_dtor(SmallWithDtor());
+}
+// The temporary is copied, so it's destroyed in the caller as well as the
+// callee.
+// WIN64-LABEL: define void @"\01?call_small_arg_with_dtor@@YAXXZ"()
+// WIN64:   call %struct.SmallWithDtor* @"\01??0SmallWithDtor@@QEAA@XZ"
+// WIN64:   call void @"\01?small_arg_with_dtor@@YAXUSmallWithDtor@@@Z"(i32 %{{.*}})
+// WIN64:   call void @"\01??1SmallWithDtor@@QEAA@XZ"
+// WIN64:   ret void
+
 // Test that references aren't destroyed in the callee.
 void ref_small_arg_with_dtor(const SmallWithDtor &s) { }
-// WIN32: define void @"\01?ref_small_arg_with_dtor@@YAXABUSmallWithDtor@@@Z"(%struct.SmallWithDtor* %s) {{.*}} {
+// WIN32: define void @"\01?ref_small_arg_with_dtor@@YAXABUSmallWithDtor@@@Z"(%struct.SmallWithDtor* dereferenceable({{[0-9]+}}) %s) {{.*}} {
 // WIN32-NOT:   call x86_thiscallcc void @"\01??1SmallWithDtor@@QAE@XZ"
 // WIN32: }
+// WIN64-LABEL: define void @"\01?ref_small_arg_with_dtor@@YAXAEBUSmallWithDtor@@@Z"(%struct.SmallWithDtor* dereferenceable({{[0-9]+}}) %s)
+
+void big_arg_with_dtor(BigWithDtor s) {}
+// WIN64-LABEL: define void @"\01?big_arg_with_dtor@@YAXUBigWithDtor@@@Z"(%struct.BigWithDtor* %s)
+// WIN64:   call void @"\01??1BigWithDtor@@QEAA@XZ"
+// WIN64: }
+
+void call_big_arg_with_dtor() {
+  big_arg_with_dtor(BigWithDtor());
+}
+// We can elide the copy of the temporary in the caller, because this object is
+// larger than 8 bytes and is passed indirectly.
+// WIN64-LABEL: define void @"\01?call_big_arg_with_dtor@@YAXXZ"()
+// WIN64:   call %struct.BigWithDtor* @"\01??0BigWithDtor@@QEAA@XZ"
+// WIN64:   call void @"\01?big_arg_with_dtor@@YAXUBigWithDtor@@@Z"(%struct.BigWithDtor* %{{.*}})
+// WIN64-NOT: call void @"\01??1BigWithDtor@@QEAA@XZ"
+// WIN64:   ret void
 
 // Test that temporaries passed by reference are destroyed in the caller.
 void temporary_ref_with_dtor() {
@@ -141,60 +183,65 @@
 
 void small_arg_with_vftable(SmallWithVftable s) {}
 // LINUX-LABEL: define void @_Z22small_arg_with_vftable16SmallWithVftable(%struct.SmallWithVftable* %s)
-// WIN32: define void @"\01?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(%struct.SmallWithVftable* byval align 4 %s)
-// WIN64: define void @"\01?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(%struct.SmallWithVftable* byval %s)
+// WIN32: define void @"\01?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(<{ %struct.SmallWithVftable }>* inalloca)
+// WIN64: define void @"\01?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(%struct.SmallWithVftable* %s)
 
 void medium_arg_with_copy_ctor(MediumWithCopyCtor s) {}
 // LINUX-LABEL: define void @_Z25medium_arg_with_copy_ctor18MediumWithCopyCtor(%struct.MediumWithCopyCtor* %s)
-// WIN32: define void @"\01?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(%struct.MediumWithCopyCtor* byval align 4 %s)
-// WIN64: define void @"\01?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(%struct.MediumWithCopyCtor* byval %s)
+// WIN32: define void @"\01?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(<{ %struct.MediumWithCopyCtor }>* inalloca)
+// WIN64: define void @"\01?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(%struct.MediumWithCopyCtor* %s)
 
 void big_arg(Big s) {}
 // LINUX-LABEL: define void @_Z7big_arg3Big(%struct.Big* byval align 4 %s)
 // WIN32: define void @"\01?big_arg@@YAXUBig@@@Z"(%struct.Big* byval align 4 %s)
 // WIN64: define void @"\01?big_arg@@YAXUBig@@@Z"(%struct.Big* %s)
 
-// FIXME: Add WIN64 tests. Currently, even the method manglings are wrong (sic!).
 class Class {
  public:
   Small thiscall_method_small() { return Small(); }
   // LINUX: define {{.*}} void @_ZN5Class21thiscall_method_smallEv(%struct.Small* noalias sret %agg.result, %class.Class* %this)
-  // WIN32: define {{.*}} x86_thiscallcc void @"\01?thiscall_method_small@Class@@QAE?AUSmall@@XZ"(%struct.Small* noalias sret %agg.result, %class.Class* %this)
+  // WIN32: define {{.*}} x86_thiscallcc void @"\01?thiscall_method_small@Class@@QAE?AUSmall@@XZ"(%class.Class* %this, %struct.Small* noalias sret %agg.result)
+  // WIN64: define linkonce_odr void @"\01?thiscall_method_small@Class@@QEAA?AUSmall@@XZ"(%class.Class* %this, %struct.Small* noalias sret %agg.result)
 
   SmallWithCtor thiscall_method_small_with_ctor() { return SmallWithCtor(); }
   // LINUX: define {{.*}} void @_ZN5Class31thiscall_method_small_with_ctorEv(%struct.SmallWithCtor* noalias sret %agg.result, %class.Class* %this)
-  // WIN32: define {{.*}} x86_thiscallcc void @"\01?thiscall_method_small_with_ctor@Class@@QAE?AUSmallWithCtor@@XZ"(%struct.SmallWithCtor* noalias sret %agg.result, %class.Class* %this)
+  // WIN32: define {{.*}} x86_thiscallcc void @"\01?thiscall_method_small_with_ctor@Class@@QAE?AUSmallWithCtor@@XZ"(%class.Class* %this, %struct.SmallWithCtor* noalias sret %agg.result)
+  // WIN64: define linkonce_odr void @"\01?thiscall_method_small_with_ctor@Class@@QEAA?AUSmallWithCtor@@XZ"(%class.Class* %this, %struct.SmallWithCtor* noalias sret %agg.result)
 
   Small __cdecl cdecl_method_small() { return Small(); }
   // LINUX: define {{.*}} void @_ZN5Class18cdecl_method_smallEv(%struct.Small* noalias sret %agg.result, %class.Class* %this)
-  // FIXME: Interesting, cdecl returns structures differently for instance
-  // methods and global functions. This is not supported by Clang yet...
-  // FIXME: Replace WIN32-NOT with WIN32 when this is fixed.
-  // WIN32-NOT: define {{.*}} void @"\01?cdecl_method_small@Class@@QAA?AUSmall@@XZ"(%struct.Small* noalias sret %agg.result, %class.Class* %this)
+  // WIN32: define {{.*}} void @"\01?cdecl_method_small@Class@@QAA?AUSmall@@XZ"(%class.Class* %this, %struct.Small* noalias sret %agg.result)
+  // WIN64: define linkonce_odr void @"\01?cdecl_method_small@Class@@QEAA?AUSmall@@XZ"(%class.Class* %this, %struct.Small* noalias sret %agg.result)
 
   Big __cdecl cdecl_method_big() { return Big(); }
   // LINUX: define {{.*}} void @_ZN5Class16cdecl_method_bigEv(%struct.Big* noalias sret %agg.result, %class.Class* %this)
-  // WIN32: define {{.*}} void @"\01?cdecl_method_big@Class@@QAA?AUBig@@XZ"(%struct.Big* noalias sret %agg.result, %class.Class* %this)
+  // WIN32: define {{.*}} void @"\01?cdecl_method_big@Class@@QAA?AUBig@@XZ"(%class.Class* %this, %struct.Big* noalias sret %agg.result)
+  // WIN64: define linkonce_odr void @"\01?cdecl_method_big@Class@@QEAA?AUBig@@XZ"(%class.Class* %this, %struct.Big* noalias sret %agg.result)
 
   void thiscall_method_arg(Empty s) {}
   // LINUX: define {{.*}} void @_ZN5Class19thiscall_method_argE5Empty(%class.Class* %this)
   // WIN32: define {{.*}} void @"\01?thiscall_method_arg@Class@@QAEXUEmpty@@@Z"(%class.Class* %this, %struct.Empty* byval align 4 %s)
+  // WIN64: define linkonce_odr void @"\01?thiscall_method_arg@Class@@QEAAXUEmpty@@@Z"(%class.Class* %this, i8 %s.coerce)
 
   void thiscall_method_arg(EmptyWithCtor s) {}
   // LINUX: define {{.*}} void @_ZN5Class19thiscall_method_argE13EmptyWithCtor(%class.Class* %this)
   // WIN32: define {{.*}} void @"\01?thiscall_method_arg@Class@@QAEXUEmptyWithCtor@@@Z"(%class.Class* %this, %struct.EmptyWithCtor* byval align 4 %s)
+  // WIN64: define linkonce_odr void @"\01?thiscall_method_arg@Class@@QEAAXUEmptyWithCtor@@@Z"(%class.Class* %this, i8 %s.coerce)
 
   void thiscall_method_arg(Small s) {}
   // LINUX: define {{.*}} void @_ZN5Class19thiscall_method_argE5Small(%class.Class* %this, %struct.Small* byval align 4 %s)
   // WIN32: define {{.*}} void @"\01?thiscall_method_arg@Class@@QAEXUSmall@@@Z"(%class.Class* %this, %struct.Small* byval align 4 %s)
+  // WIN64: define linkonce_odr void @"\01?thiscall_method_arg@Class@@QEAAXUSmall@@@Z"(%class.Class* %this, i32 %s.coerce)
 
   void thiscall_method_arg(SmallWithCtor s) {}
   // LINUX: define {{.*}} void @_ZN5Class19thiscall_method_argE13SmallWithCtor(%class.Class* %this, %struct.SmallWithCtor* byval align 4 %s)
   // WIN32: define {{.*}} void @"\01?thiscall_method_arg@Class@@QAEXUSmallWithCtor@@@Z"(%class.Class* %this, %struct.SmallWithCtor* byval align 4 %s)
+  // WIN64: define linkonce_odr void @"\01?thiscall_method_arg@Class@@QEAAXUSmallWithCtor@@@Z"(%class.Class* %this, i32 %s.coerce)
 
   void thiscall_method_arg(Big s) {}
   // LINUX: define {{.*}} void @_ZN5Class19thiscall_method_argE3Big(%class.Class* %this, %struct.Big* byval align 4 %s)
   // WIN32: define {{.*}} void @"\01?thiscall_method_arg@Class@@QAEXUBig@@@Z"(%class.Class* %this, %struct.Big* byval align 4 %s)
+  // WIN64: define linkonce_odr void @"\01?thiscall_method_arg@Class@@QEAAXUBig@@@Z"(%class.Class* %this, %struct.Big* %s)
 };
 
 void use_class() {
@@ -218,8 +265,8 @@
 };
 void g(X) {
 }
-// WIN32: define void @"\01?g@@YAXUX@@@Z"(%struct.X* byval align 4) {{.*}} {
-// WIN32:   call x86_thiscallcc void @"\01??1X@@QAE@XZ"(%struct.X* %0)
+// WIN32: define void @"\01?g@@YAXUX@@@Z"(<{ %struct.X, [3 x i8] }>* inalloca) {{.*}} {
+// WIN32:   call x86_thiscallcc void @"\01??1X@@QAE@XZ"(%struct.X* {{.*}})
 // WIN32: }
 void f() {
   g(X());
@@ -227,3 +274,72 @@
 // WIN32: define void @"\01?f@@YAXXZ"() {{.*}} {
 // WIN32-NOT: call {{.*}} @"\01??1X@@QAE@XZ"
 // WIN32: }
+
+
+namespace test2 {
+// We used to crash on this due to the mixture of POD byval and non-trivial
+// byval.
+
+struct NonTrivial {
+  NonTrivial();
+  NonTrivial(const NonTrivial &o);
+  ~NonTrivial();
+  int a;
+};
+struct POD { int b; };
+
+int foo(NonTrivial a, POD b);
+void bar() {
+  POD b;
+  b.b = 13;
+  int c = foo(NonTrivial(), b);
+}
+// WIN32-LABEL: define void @"\01?bar@test2@@YAXXZ"() {{.*}} {
+// WIN32:   %[[argmem:[^ ]*]] = alloca inalloca [[argmem_ty:<{ %"struct.test2::NonTrivial", %"struct.test2::POD" }>]]
+// WIN32:   getelementptr inbounds [[argmem_ty]]* %[[argmem]], i32 0, i32 1
+// WIN32:   call void @llvm.memcpy
+// WIN32:   getelementptr inbounds [[argmem_ty]]* %[[argmem]], i32 0, i32 0
+// WIN32:   call x86_thiscallcc %"struct.test2::NonTrivial"* @"\01??0NonTrivial@test2@@QAE@XZ"
+// WIN32:   call i32 @"\01?foo@test2@@YAHUNonTrivial@1@UPOD@1@@Z"([[argmem_ty]]* inalloca %argmem)
+// WIN32:   ret void
+// WIN32: }
+
+}
+
+namespace test3 {
+
+// Check that we padded the inalloca struct to a multiple of 4.
+struct NonTrivial {
+  NonTrivial();
+  NonTrivial(const NonTrivial &o);
+  ~NonTrivial();
+  int a;
+};
+void foo(NonTrivial a, bool b) { }
+// WIN32-LABEL: define void @"\01?foo@test3@@YAXUNonTrivial@1@_N@Z"(<{ %"struct.test3::NonTrivial", i8, [3 x i8] }>* inalloca)
+
+}
+
+// We would crash here because the later definition of ForwardDeclare1 results
+// in a different IR type for the value we want to store.  However, the alloca's
+// type will use the argument type selected by fn1.
+struct ForwardDeclare1;
+
+typedef void (*FnPtr1)(ForwardDeclare1);
+void fn1(FnPtr1 a, SmallWithDtor b) { }
+
+struct ForwardDeclare1 {};
+
+void fn2(FnPtr1 a, SmallWithDtor b) { fn1(a, b); };
+// WIN32-LABEL: define void @"\01?fn2@@YAXP6AXUForwardDeclare1@@@ZUSmallWithDtor@@@Z"
+// WIN32:   %[[a:[^ ]*]] = getelementptr inbounds [[argmem_ty:<{ {}\*, %struct.SmallWithDtor }>]]* %{{.*}}, i32 0, i32 0
+// WIN32:   %[[a1:[^ ]*]] = bitcast {}** %[[a]] to void [[dst_ty:\(%struct.ForwardDeclare1\*\)\*]]*
+// WIN32:   %[[argmem:[^ ]*]] = alloca inalloca [[argmem_ty]]
+// WIN32:   %[[gep1:[^ ]*]] = getelementptr inbounds [[argmem_ty]]* %[[argmem]], i32 0, i32 1
+// WIN32:   %[[bc1:[^ ]*]] = bitcast %struct.SmallWithDtor* %[[gep1]] to i8*
+// WIN32:   call void @llvm.memcpy.p0i8.p0i8.i32(i8* %[[bc1]], i8* {{.*}}, i32 4, i32 4, i1 false)
+// WIN32:   %[[a2:[^ ]*]] = load void [[dst_ty]]* %[[a1]], align 4
+// WIN32:   %[[gep2:[^ ]*]] = getelementptr inbounds [[argmem_ty]]* %[[argmem]], i32 0, i32 0
+// WIN32:   %[[addr:[^ ]*]] = bitcast {}** %[[gep2]] to void [[dst_ty]]*
+// WIN32:   store void [[dst_ty]] %[[a2]], void [[dst_ty]]* %[[addr]], align 4
+// WIN32:   call void @"\01?fn1@@YAXP6AXUForwardDeclare1@@@ZUSmallWithDtor@@@Z"([[argmem_ty]]* inalloca %[[argmem]])
diff --git a/test/CodeGenCXX/microsoft-abi-static-initializers.cpp b/test/CodeGenCXX/microsoft-abi-static-initializers.cpp
index c0b9722..5f74c54 100644
--- a/test/CodeGenCXX/microsoft-abi-static-initializers.cpp
+++ b/test/CodeGenCXX/microsoft-abi-static-initializers.cpp
@@ -1,8 +1,9 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -mconstructor-aliases -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -fms-extensions -emit-llvm %s -o - -mconstructor-aliases -triple=i386-pc-win32 | FileCheck %s
 
-// CHECK: @llvm.global_ctors = appending global [2 x { i32, void ()* }]
-// CHECK: [{ i32, void ()* } { i32 65535, void ()* @"\01??__Efoo@?$B@H@@YAXXZ" },
-// CHECK:  { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_a }]
+// CHECK: @llvm.global_ctors = appending global [2 x { i32, void ()*, i8* }]
+// CHECK: [{ i32, void ()*, i8* } { i32 65535, void ()* @"\01??__Efoo@?$B@H@@2VA@@A@YAXXZ",
+// CHECK:       i8* bitcast (%class.A* @"\01?foo@?$B@H@@2VA@@A" to i8*) },
+// CHECK:  { i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_microsoft_abi_static_initializers.cpp, i8* null }]
 
 struct S {
   S();
@@ -11,21 +12,34 @@
 
 S s;
 
-// CHECK: define internal void @"\01??__Es@@YAXXZ"() [[NUW:#[0-9]+]]
-// CHECK: %{{[.0-9A-Z_a-z]+}} = call x86_thiscallcc %struct.S* @"\01??0S@@QAE@XZ"
+// CHECK: define internal void @"\01??__Es@@YAXXZ"()
+// CHECK: call x86_thiscallcc %struct.S* @"\01??0S@@QAE@XZ"
 // CHECK: call i32 @atexit(void ()* @"\01??__Fs@@YAXXZ")
 // CHECK: ret void
 
-// CHECK: define internal void @"\01??__Fs@@YAXXZ"() [[NUW]] {
+// CHECK: define internal void @"\01??__Fs@@YAXXZ"()
 // CHECK: call x86_thiscallcc void @"\01??1S@@QAE@XZ"
 // CHECK: ret void
 
+// These globals should use distinct guard variables, and not different bits of
+// the same global.
+__declspec(selectany) S selectany1;
+__declspec(selectany) S selectany2;
+// CHECK: define linkonce_odr void @"\01??__Eselectany1@@YAXXZ"()
+// CHECK-NOT: @"\01??_Bselectany1
+// CHECK: call x86_thiscallcc %struct.S* @"\01??0S@@QAE@XZ"
+// CHECK: ret void
+// CHECK: define linkonce_odr void @"\01??__Eselectany2@@YAXXZ"()
+// CHECK-NOT: @"\01??_Bselectany2
+// CHECK: call x86_thiscallcc %struct.S* @"\01??0S@@QAE@XZ"
+// CHECK: ret void
+
 void StaticLocal() {
   static S TheS;
 }
 // CHECK-LABEL: define void @"\01?StaticLocal@@YAXXZ"()
-// CHECK: load i32* @"\01?$S1@?1??StaticLocal@@YAXXZ@4IA"
-// CHECK: store i32 {{.*}}, i32* @"\01?$S1@?1??StaticLocal@@YAXXZ@4IA"
+// CHECK: load i32* @"\01?$S1@?0??StaticLocal@@YAXXZ@4IA"
+// CHECK: store i32 {{.*}}, i32* @"\01?$S1@?0??StaticLocal@@YAXXZ@4IA"
 // CHECK: ret
 
 void MultipleStatics() {
@@ -66,7 +80,7 @@
   static S S35;
 }
 // CHECK-LABEL: define void @"\01?MultipleStatics@@YAXXZ"()
-// CHECK: load i32* @"\01?$S1@?1??MultipleStatics@@YAXXZ@4IA"
+// CHECK: load i32* @"\01?$S1@?0??MultipleStatics@@YAXXZ@4IA"
 // CHECK: and i32 {{.*}}, 1
 // CHECK: and i32 {{.*}}, 2
 // CHECK: and i32 {{.*}}, 4
@@ -74,7 +88,7 @@
 // CHECK: and i32 {{.*}}, 16
 //   ...
 // CHECK: and i32 {{.*}}, -2147483648
-// CHECK: load i32* @"\01?$S1@?1??MultipleStatics@@YAXXZ@4IA1"
+// CHECK: load i32* @"\01?$S1@?0??MultipleStatics@@YAXXZ@4IA1"
 // CHECK: and i32 {{.*}}, 1
 // CHECK: and i32 {{.*}}, 2
 // CHECK: and i32 {{.*}}, 4
@@ -85,6 +99,7 @@
  public:
   A() {}
   ~A() {}
+  int a;
 };
 
 template<typename T>
@@ -104,7 +119,7 @@
   return s;
 }
 
-// CHECK-LABEL: define linkonce_odr %struct.S* @"\01?UnreachableStatic@@YAAAUS@@XZ"()
+// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.S* @"\01?UnreachableStatic@@YAAAUS@@XZ"()
 // CHECK: and i32 {{.*}}, 2
 // CHECK: or i32 {{.*}}, 2
 // CHECK: ret
@@ -114,7 +129,7 @@
   return TheS;
 }
 
-// CHECK-LABEL: define linkonce_odr %struct.S* @"\01?getS@@YAAAUS@@XZ"
+// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.S* @"\01?getS@@YAAAUS@@XZ"
 // CHECK: load i32* @"\01??_B?1??getS@@YAAAUS@@XZ@51"
 // CHECK: and i32 {{.*}}, 1
 // CHECK: icmp ne i32 {{.*}}, 0
@@ -128,27 +143,95 @@
 //   init.end:
 // CHECK: ret %struct.S* @"\01?TheS@?1??getS@@YAAAUS@@XZ@4U2@A"
 
+inline int enum_in_function() {
+  // CHECK-LABEL: define linkonce_odr i32 @"\01?enum_in_function@@YAHXZ"()
+  static enum e { foo, bar, baz } x;
+  // CHECK: @"\01?x@?1??enum_in_function@@YAHXZ@4W4e@?1??1@YAHXZ@A"
+  static int y;
+  // CHECK: @"\01?y@?1??enum_in_function@@YAHXZ@4HA"
+  return x + y;
+};
+
+struct T {
+  enum e { foo, bar, baz };
+  int enum_in_struct() {
+    // CHECK-LABEL: define linkonce_odr x86_thiscallcc i32 @"\01?enum_in_struct@T@@QAEHXZ"
+    static int x;
+    // CHECK: @"\01?x@?1??enum_in_struct@T@@QAEHXZ@4HA"
+    return x++;
+  }
+};
+
+inline int switch_test(int x) {
+  // CHECK-LABEL: define linkonce_odr i32 @"\01?switch_test@@YAHH@Z"(i32 %x)
+  switch (x) {
+    static int a;
+    // CHECK: @"\01?a@?3??switch_test@@YAHH@Z@4HA"
+    case 0:
+      a++;
+      return 1;
+    case 1:
+      static int b;
+      // CHECK: @"\01?b@?3??switch_test@@YAHH@Z@4HA"
+      return b++;
+    case 2: {
+      static int c;
+      // CHECK: @"\01?c@?4??switch_test@@YAHH@Z@4HA"
+      return b + c++;
+    }
+  };
+}
+
+int f();
+inline void switch_test2() {
+  // CHECK-LABEL: define linkonce_odr void @"\01?switch_test2@@YAXXZ"()
+  // CHECK: @"\01?x@?2??switch_test2@@YAXXZ@4HA"
+  switch (1) default: static int x = f();
+}
+
+namespace DynamicDLLImportInitVSMangling {
+  // Failing to pop the ExprEvalContexts when instantiating a dllimport var with
+  // dynamic initializer would cause subsequent static local numberings to be
+  // incorrect.
+  struct NonPOD { NonPOD(); };
+  template <typename T> struct A { static NonPOD x; };
+  template <typename T> NonPOD A<T>::x;
+  template struct __declspec(dllimport) A<int>;
+
+  inline int switch_test3() {
+    // CHECK-LABEL: define linkonce_odr i32 @"\01?switch_test3@DynamicDLLImportInitVSMangling@@YAHXZ"
+    static int local;
+    // CHECK: @"\01?local@?1??switch_test3@DynamicDLLImportInitVSMangling@@YAHXZ@4HA"
+    return local++;
+  }
+}
+
 void force_usage() {
   UnreachableStatic();
   getS();
   (void)B<int>::foo;  // (void) - force usage
+  enum_in_function();
+  (void)&T::enum_in_struct;
+  switch_test(1);
+  switch_test2();
+  DynamicDLLImportInitVSMangling::switch_test3();
 }
 
-// CHECK: define internal void @"\01??__Efoo@?$B@H@@YAXXZ"() [[NUW]]
-// CHECK: %{{[.0-9A-Z_a-z]+}} = call x86_thiscallcc %class.A* @"\01??0A@@QAE@XZ"
-// CHECK: call i32 @atexit(void ()* @"\01??__Ffoo@?$B@H@@YAXXZ")
+// CHECK: define linkonce_odr void @"\01??__Efoo@?$B@H@@2VA@@A@YAXXZ"()
+// CHECK-NOT: and
+// CHECK-NOT: ?_Bfoo@
+// CHECK: call x86_thiscallcc %class.A* @"\01??0A@@QAE@XZ"
+// CHECK: call i32 @atexit(void ()* @"\01??__Ffoo@?$B@H@@2VA@@A@YAXXZ")
 // CHECK: ret void
 
 // CHECK: define linkonce_odr x86_thiscallcc %class.A* @"\01??0A@@QAE@XZ"
 
 // CHECK: define linkonce_odr x86_thiscallcc void @"\01??1A@@QAE@XZ"
 
-// CHECK: define internal void @"\01??__Ffoo@?$B@H@@YAXXZ"
+// CHECK: define internal void @"\01??__Ffoo@?$B@H@@2VA@@A@YAXXZ"
 // CHECK: call x86_thiscallcc void @"\01??1A@@QAE@XZ"{{.*}}foo
 // CHECK: ret void
 
-// CHECK: define internal void @_GLOBAL__I_a() [[NUW]] {
+// CHECK: define internal void @_GLOBAL__sub_I_microsoft_abi_static_initializers.cpp()
 // CHECK: call void @"\01??__Es@@YAXXZ"()
 // CHECK: ret void
-
-// CHECK: attributes [[NUW]] = { nounwind }
diff --git a/test/CodeGenCXX/microsoft-abi-structors-alias.cpp b/test/CodeGenCXX/microsoft-abi-structors-alias.cpp
index d54520f..f977556 100644
--- a/test/CodeGenCXX/microsoft-abi-structors-alias.cpp
+++ b/test/CodeGenCXX/microsoft-abi-structors-alias.cpp
@@ -1,9 +1,26 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 -fno-rtti -mconstructor-aliases | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 -fno-rtti -mconstructor-aliases -O1 -disable-llvm-optzns | FileCheck %s
 
 namespace test1 {
 template <typename T> class A {
   ~A() {}
 };
 template class A<char>;
-// CHECK: define weak_odr x86_thiscallcc void @"\01??1?$A@D@test1@@AAE@XZ"
+// CHECK-DAG: define weak_odr x86_thiscallcc void @"\01??1?$A@D@test1@@AAE@XZ"
+}
+
+namespace test2 {
+struct A {
+  virtual ~A();
+};
+struct B : A {
+  B();
+  virtual ~B();
+};
+
+A::~A() {}
+B::~B() {}
+void foo() {
+  B b;
+}
+// CHECK-DAG: @"\01??1B@test2@@UAE@XZ" = alias bitcast (void (%"struct.test2::A"*)* @"\01??1A@test2@@UAE@XZ" to void (%"struct.test2::B"*)*)
 }
diff --git a/test/CodeGenCXX/microsoft-abi-structors.cpp b/test/CodeGenCXX/microsoft-abi-structors.cpp
index c2f1395..7d3992b 100644
--- a/test/CodeGenCXX/microsoft-abi-structors.cpp
+++ b/test/CodeGenCXX/microsoft-abi-structors.cpp
@@ -1,10 +1,12 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -mconstructor-aliases -cxx-abi microsoft -triple=i386-pc-win32 -fno-rtti > %t
+// RUN: %clang_cc1 -emit-llvm -fno-rtti %s -std=c++11 -o - -mconstructor-aliases -triple=i386-pc-win32 -fno-rtti > %t
 // RUN: FileCheck %s < %t
 // vftables are emitted very late, so do another pass to try to keep the checks
 // in source order.
 // RUN: FileCheck --check-prefix DTORS %s < %t
+// RUN: FileCheck --check-prefix DTORS2 %s < %t
+// RUN: FileCheck --check-prefix DTORS3 %s < %t
 //
-// RUN: %clang_cc1 -emit-llvm %s -o - -mconstructor-aliases -cxx-abi microsoft -triple=x86_64-pc-win32 -fno-rtti | FileCheck --check-prefix DTORS-X64 %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -mconstructor-aliases -triple=x86_64-pc-win32 -fno-rtti | FileCheck --check-prefix DTORS-X64 %s
 
 namespace basic {
 
@@ -121,6 +123,79 @@
 
 } // end namespace basic
 
+namespace dtor_in_second_nvbase {
+
+struct A {
+  virtual void f();  // A needs vftable to be primary.
+};
+struct B {
+  virtual ~B();
+};
+struct C : A, B {
+  virtual ~C();
+};
+
+C::~C() {
+// CHECK-LABEL: define x86_thiscallcc void @"\01??1C@dtor_in_second_nvbase@@UAE@XZ"
+// CHECK:       (%"struct.dtor_in_second_nvbase::C"* %this)
+//      No this adjustment!
+// CHECK-NOT: getelementptr
+// CHECK:   load %"struct.dtor_in_second_nvbase::C"** %{{.*}}
+//      Now we this-adjust before calling ~B.
+// CHECK:   bitcast %"struct.dtor_in_second_nvbase::C"* %{{.*}} to i8*
+// CHECK:   getelementptr inbounds i8* %{{.*}}, i64 4
+// CHECK:   bitcast i8* %{{.*}} to %"struct.dtor_in_second_nvbase::B"*
+// CHECK:   call x86_thiscallcc void @"\01??1B@dtor_in_second_nvbase@@UAE@XZ"
+// CHECK:       (%"struct.dtor_in_second_nvbase::B"* %{{.*}})
+// CHECK:   ret void
+}
+
+void foo() {
+  C c;
+}
+// DTORS2-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_EC@dtor_in_second_nvbase@@W3AEPAXI@Z"
+// DTORS2:       (%"struct.dtor_in_second_nvbase::C"* %this, i32 %should_call_delete)
+//      Do an adjustment from B* to C*.
+// DTORS2:   getelementptr i8* %{{.*}}, i32 -4
+// DTORS2:   bitcast i8* %{{.*}} to %"struct.dtor_in_second_nvbase::C"*
+// DTORS2:   call x86_thiscallcc void @"\01??_GC@dtor_in_second_nvbase@@UAEPAXI@Z"
+// DTORS2:   ret void
+
+}
+
+namespace test2 {
+// Just like dtor_in_second_nvbase, except put that in a vbase of a diamond.
+
+// C's dtor is in the non-primary base.
+struct A { virtual void f(); };
+struct B { virtual ~B(); };
+struct C : A, B { virtual ~C(); int c; };
+
+// Diamond hierarchy, with C as the shared vbase.
+struct D : virtual C { int d; };
+struct E : virtual C { int e; };
+struct F : D, E { ~F(); int f; };
+
+F::~F() {
+// CHECK-LABEL: define x86_thiscallcc void @"\01??1F@test2@@UAE@XZ"(%"struct.test2::F"*)
+//      Do an adjustment from C vbase subobject to F as though F was the
+//      complete type.
+// CHECK:   getelementptr inbounds i8* %{{.*}}, i32 -20
+// CHECK:   bitcast i8* %{{.*}} to %"struct.test2::F"*
+// CHECK:   store %"struct.test2::F"*
+}
+
+void foo() {
+  F f;
+}
+// DTORS3-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_DF@test2@@UAE@XZ"
+//      Do an adjustment from C* to F*.
+// DTORS3:   getelementptr i8* %{{.*}}, i32 20
+// DTORS3:   bitcast i8* %{{.*}} to %"struct.test2::F"*
+// DTORS3:   call x86_thiscallcc void @"\01??1F@test2@@UAE@XZ"
+// DTORS3:   ret void
+
+}
 
 namespace constructors {
 
@@ -299,3 +374,69 @@
 }
 
 }
+
+namespace test1 {
+struct A { };
+struct B : virtual A {
+  B(int *a);
+  B(const char *a, ...);
+  __cdecl B(short *a);
+};
+B::B(int *a) {}
+B::B(const char *a, ...) {}
+B::B(short *a) {}
+// CHECK: define x86_thiscallcc %"struct.test1::B"* @"\01??0B@test1@@QAE@PAH@Z"
+// CHECK:               (%"struct.test1::B"* returned %this, i32* %a, i32 %is_most_derived)
+// CHECK: define %"struct.test1::B"* @"\01??0B@test1@@QAA@PBDZZ"
+// CHECK:               (%"struct.test1::B"* returned %this, i32 %is_most_derived, i8* %a, ...)
+
+// FIXME: This should be x86_thiscallcc.  MSVC ignores explicit CCs on structors.
+// CHECK: define %"struct.test1::B"* @"\01??0B@test1@@QAA@PAF@Z"
+// CHECK:               (%"struct.test1::B"* returned %this, i16* %a, i32 %is_most_derived)
+
+void construct_b() {
+  int a;
+  B b1(&a);
+  B b2("%d %d", 1, 2);
+}
+// CHECK-LABEL: define void @"\01?construct_b@test1@@YAXXZ"()
+// CHECK: call x86_thiscallcc %"struct.test1::B"* @"\01??0B@test1@@QAE@PAH@Z"
+// CHECK:               (%"struct.test1::B"* {{.*}}, i32* {{.*}}, i32 1)
+// CHECK: call %"struct.test1::B"* (%"struct.test1::B"*, i32, i8*, ...)* @"\01??0B@test1@@QAA@PBDZZ"
+// CHECK:               (%"struct.test1::B"* {{.*}}, i32 1, i8* {{.*}}, i32 1, i32 2)
+}
+
+namespace implicit_copy_vtable {
+// This was a crash that only reproduced in ABIs without key functions.
+struct ImplicitCopy {
+  // implicit copy ctor
+  virtual ~ImplicitCopy();
+};
+void CreateCopy(ImplicitCopy *a) {
+  new ImplicitCopy(*a);
+}
+// CHECK: store {{.*}} @"\01??_7ImplicitCopy@implicit_copy_vtable@@6B@"
+
+struct MoveOnly {
+  MoveOnly(MoveOnly &&o) = default;
+  virtual ~MoveOnly();
+};
+MoveOnly &&f();
+void g() { new MoveOnly(f()); }
+// CHECK: store {{.*}} @"\01??_7MoveOnly@implicit_copy_vtable@@6B@"
+}
+
+// Dtor thunks for classes in anonymous namespaces should be internal, not
+// linkonce_odr.
+namespace {
+struct A {
+  virtual ~A() { }
+};
+}
+void *getA() {
+  return (void*)new A();
+}
+// CHECK: define internal x86_thiscallcc void @"\01??_GA@?A@@UAEPAXI@Z"
+// CHECK:               (%"struct.(anonymous namespace)::A"* %this, i32 %should_call_delete)
+// CHECK: define internal x86_thiscallcc void @"\01??1A@?A@@UAE@XZ"
+// CHECK:               (%"struct.(anonymous namespace)::A"* %this)
diff --git a/test/CodeGenCXX/microsoft-abi-thunks.cpp b/test/CodeGenCXX/microsoft-abi-thunks.cpp
index f1bc385..c755b30 100644
--- a/test/CodeGenCXX/microsoft-abi-thunks.cpp
+++ b/test/CodeGenCXX/microsoft-abi-thunks.cpp
@@ -1,8 +1,8 @@
-// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 >%t 2>&1
+// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 >%t 2>&1
 // RUN: FileCheck --check-prefix=MANGLING %s < %t
 // RUN: FileCheck --check-prefix=XMANGLING %s < %t
 // RUN: FileCheck --check-prefix=CODEGEN %s < %t
-// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -cxx-abi microsoft -triple=x86_64-pc-win32 2>&1 | FileCheck --check-prefix=MANGLING-X64 %s
+// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -triple=x86_64-pc-win32 2>&1 | FileCheck --check-prefix=MANGLING-X64 %s
 
 void foo(void *);
 
@@ -61,13 +61,13 @@
 
 C::C() {}  // Emits vftable and forces thunk generation.
 
-// CODEGEN-LABEL: define weak x86_thiscallcc void @"\01??_EC@@W3AEPAXI@Z"(%struct.C* %this, i32 %should_call_delete)
+// CODEGEN-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_EC@@W3AEPAXI@Z"(%struct.C* %this, i32 %should_call_delete)
 // CODEGEN:   getelementptr i8* {{.*}}, i32 -4
 // FIXME: should actually call _EC, not _GC.
 // CODEGEN:   call x86_thiscallcc void @"\01??_GC@@UAEPAXI@Z"
 // CODEGEN: ret
 
-// CODEGEN-LABEL: define weak x86_thiscallcc void @"\01?public_f@C@@W3AEXXZ"(%struct.C*
+// CODEGEN-LABEL: define linkonce_odr x86_thiscallcc void @"\01?public_f@C@@W3AEXXZ"(%struct.C*
 // CODEGEN:   getelementptr i8* {{.*}}, i32 -4
 // CODEGEN:   call x86_thiscallcc void @"\01?public_f@C@@UAEXXZ"(%struct.C*
 // CODEGEN: ret
@@ -91,7 +91,7 @@
 
 E::E() {}  // Emits vftable and forces thunk generation.
 
-// CODEGEN-LABEL: define weak x86_thiscallcc %struct.C* @"\01?goo@E@@QAEPAUB@@XZ"
+// CODEGEN-LABEL: define weak_odr x86_thiscallcc %struct.C* @"\01?goo@E@@QAEPAUB@@XZ"
 // CODEGEN:   call x86_thiscallcc %struct.C* @"\01?goo@E@@UAEPAUC@@XZ"
 // CODEGEN:   getelementptr inbounds i8* {{.*}}, i32 4
 // CODEGEN: ret
@@ -124,7 +124,7 @@
 
 I::I() {}  // Emits vftable and forces thunk generation.
 
-// CODEGEN-LABEL: define weak x86_thiscallcc %struct.{{[BF]}}* @"\01?goo@I@@QAEPAUB@@XZ"
+// CODEGEN-LABEL: define weak_odr x86_thiscallcc %struct.{{[BF]}}* @"\01?goo@I@@QAEPAUB@@XZ"
 // CODEGEN: %[[ORIG_RET:.*]] = call x86_thiscallcc %struct.F* @"\01?goo@I@@UAEPAUF@@XZ"
 // CODEGEN: %[[ORIG_RET_i8:.*]] = bitcast %struct.F* %[[ORIG_RET]] to i8*
 // CODEGEN: %[[VBPTR_i8:.*]] = getelementptr inbounds i8* %[[ORIG_RET_i8]], i32 4
@@ -152,3 +152,14 @@
 };
 C c;
 }
+
+namespace {
+struct E : D {
+  E();
+  virtual C* goo();
+};
+E::E() {}
+E e;
+// Class with internal linkage has internal linkage thunks.
+// CODEGEN: define internal x86_thiscallcc %struct.C* @"\01?goo@E@?A@@QAEPAUB@@XZ"
+}
diff --git a/test/CodeGenCXX/microsoft-abi-try-throw.cpp b/test/CodeGenCXX/microsoft-abi-try-throw.cpp
new file mode 100644
index 0000000..95c2cbd
--- /dev/null
+++ b/test/CodeGenCXX/microsoft-abi-try-throw.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -emit-llvm-only %s -triple=i386-pc-win32 -mconstructor-aliases -fcxx-exceptions -fexceptions -fno-rtti -verify -DTRY
+// RUN: %clang_cc1 -emit-llvm-only %s -triple=i386-pc-win32 -mconstructor-aliases -fcxx-exceptions -fexceptions -fno-rtti -verify -DTHROW
+
+void external();
+
+inline void not_emitted() {
+  throw int(13); // no error
+}
+
+int main() {
+  int rv = 0;
+#ifdef TRY
+  try { // expected-error {{cannot compile this try statement yet}}
+    external();
+  } catch (int) {
+    rv = 1;
+  }
+#endif
+#ifdef THROW
+  throw int(42); // expected-error {{cannot compile this throw expression yet}}
+#endif
+  return rv;
+}
diff --git a/test/CodeGenCXX/microsoft-abi-typeid.cpp b/test/CodeGenCXX/microsoft-abi-typeid.cpp
new file mode 100644
index 0000000..4ee004d
--- /dev/null
+++ b/test/CodeGenCXX/microsoft-abi-typeid.cpp
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -emit-llvm -O1 -o - -triple=i386-pc-win32 %s | FileCheck %s
+
+struct type_info;
+namespace std { using ::type_info; }
+
+struct V { virtual void f(); };
+struct A : virtual V { A(); };
+
+extern A a;
+extern V v;
+extern int b;
+A* fn();
+
+const std::type_info* test0_typeid() { return &typeid(int); }
+// CHECK-LABEL: define %struct.type_info* @"\01?test0_typeid@@YAPBUtype_info@@XZ"()
+// CHECK:   ret %struct.type_info* bitcast (%rtti.TypeDescriptor2* @"\01??_R0H@8" to %struct.type_info*)
+
+const std::type_info* test1_typeid() { return &typeid(A); }
+// CHECK-LABEL: define %struct.type_info* @"\01?test1_typeid@@YAPBUtype_info@@XZ"()
+// CHECK:   ret %struct.type_info* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUA@@@8" to %struct.type_info*)
+
+const std::type_info* test2_typeid() { return &typeid(&a); }
+// CHECK-LABEL: define %struct.type_info* @"\01?test2_typeid@@YAPBUtype_info@@XZ"()
+// CHECK:   ret %struct.type_info* bitcast (%rtti.TypeDescriptor7* @"\01??_R0PAUA@@@8" to %struct.type_info*)
+
+const std::type_info* test3_typeid() { return &typeid(*fn()); }
+// CHECK-LABEL: define %struct.type_info* @"\01?test3_typeid@@YAPBUtype_info@@XZ"()
+// CHECK:        [[CALL:%.*]] = tail call %struct.A* @"\01?fn@@YAPAUA@@XZ"()
+// CHECK-NEXT:   [[CMP:%.*]] = icmp eq %struct.A* [[CALL]], null
+// CHECK-NEXT:   br i1 [[CMP]]
+// CHECK:        tail call i8* @__RTtypeid(i8* null)
+// CHECK-NEXT:   unreachable
+// CHECK:        [[THIS:%.*]] = bitcast %struct.A* [[CALL]] to i8*
+// CHECK-NEXT:   [[VBTBLP:%.*]] = bitcast %struct.A* [[CALL]] to i8**
+// CHECK-NEXT:   [[VBTBL:%.*]] = load i8** [[VBTBLP]], align 4
+// CHECK-NEXT:   [[VBSLOT:%.*]] = getelementptr inbounds i8* [[VBTBL]], i32 4
+// CHECK-NEXT:   [[VBITCST:%.*]] = bitcast i8* [[VBSLOT]] to i32*
+// CHECK-NEXT:   [[VBASE_OFFS:%.*]] = load i32* [[VBITCST]], align 4
+// CHECK-NEXT:   [[ADJ:%.*]] = getelementptr inbounds i8* [[THIS]], i32 [[VBASE_OFFS]]
+// CHECK-NEXT:   [[RT:%.*]] = tail call i8* @__RTtypeid(i8* [[ADJ]])
+// CHECK-NEXT:   [[RET:%.*]] = bitcast i8* [[RT]] to %struct.type_info*
+// CHECK-NEXT:   ret %struct.type_info* [[RET]]
+
+const std::type_info* test4_typeid() { return &typeid(b); }
+// CHECK: define %struct.type_info* @"\01?test4_typeid@@YAPBUtype_info@@XZ"()
+// CHECK:   ret %struct.type_info* bitcast (%rtti.TypeDescriptor2* @"\01??_R0H@8" to %struct.type_info*)
+
+const std::type_info* test5_typeid() { return &typeid(v); }
+// CHECK: define %struct.type_info* @"\01?test5_typeid@@YAPBUtype_info@@XZ"()
+// CHECK:        [[RT:%.*]] = tail call i8* @__RTtypeid(i8* bitcast (%struct.V* @"\01?v@@3UV@@A" to i8*))
+// CHECK-NEXT:   [[RET:%.*]] = bitcast i8* [[RT]] to %struct.type_info*
+// CHECK-NEXT:   ret %struct.type_info* [[RET]]
diff --git a/test/CodeGenCXX/microsoft-abi-vbtables.cpp b/test/CodeGenCXX/microsoft-abi-vbtables.cpp
index 6de556b..8b86d6b 100644
--- a/test/CodeGenCXX/microsoft-abi-vbtables.cpp
+++ b/test/CodeGenCXX/microsoft-abi-vbtables.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -fno-rtti -cxx-abi microsoft -triple=i386-pc-win32 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -o - | FileCheck %s
 
 // See microsoft-abi-structors.cpp for constructor codegen tests.
 
@@ -477,3 +477,54 @@
 // CHECK-DAG: @"\01??_8F@Test26@@7BD@1@@" = linkonce_odr unnamed_addr constant [4 x i32] [i32 0, i32 16, i32 12, i32 20]
 // CHECK-DAG: @"\01??_8F@Test26@@7BE@1@@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 -4, i32 28]
 }
+
+namespace Test27 {
+// PR17748
+struct A {};
+struct B : virtual A {};
+struct C : virtual B {};
+struct D : C, B {};
+struct E : D {};
+struct F : C, E {};
+struct G : F, D, C, B {};
+G x;
+
+// CHECK-DAG: @"\01??_8G@Test27@@7BB@1@@" =
+// CHECK-DAG: @"\01??_8G@Test27@@7BB@1@F@1@@" =
+// CHECK-DAG: @"\01??_8G@Test27@@7BC@1@@" =
+// CHECK-DAG: @"\01??_8G@Test27@@7BC@1@D@1@@" =
+// CHECK-DAG: @"\01??_8G@Test27@@7BC@1@E@1@@" =
+// CHECK-DAG: @"\01??_8G@Test27@@7BC@1@F@1@@" =
+// CHECK-DAG: @"\01??_8G@Test27@@7BD@1@@" =
+// CHECK-DAG: @"\01??_8G@Test27@@7BF@1@@" =
+}
+
+namespace Test28 {
+// PR17748
+struct A {};
+struct B : virtual A {};
+struct C : virtual B {};
+struct D : C, B {};
+struct E : C, D {};
+struct F : virtual E, virtual D, virtual C {};
+F x;
+
+// CHECK-DAG: @"\01??_8F@Test28@@7B01@@" =
+// CHECK-DAG: @"\01??_8F@Test28@@7BB@1@@" =
+// CHECK-DAG: @"\01??_8F@Test28@@7BC@1@@" =
+// CHECK-DAG: @"\01??_8F@Test28@@7BC@1@D@1@@" =
+// CHECK-DAG: @"\01??_8F@Test28@@7BC@1@D@1@E@1@@" =
+// CHECK-DAG: @"\01??_8F@Test28@@7BC@1@E@1@@" =
+// CHECK-DAG: @"\01??_8F@Test28@@7BD@1@@" =
+// CHECK-DAG: @"\01??_8F@Test28@@7BE@1@@" =
+}
+
+namespace Test29 {
+struct A {};
+struct B : virtual A {};
+struct C : virtual B {};
+struct D : C {};
+D d;
+
+// CHECK-DAG: @"\01??_8D@Test29@@7BB@1@@" = linkonce_odr unnamed_addr constant [2 x i32] zeroinitializer
+}
diff --git a/test/CodeGenCXX/microsoft-abi-vftables.cpp b/test/CodeGenCXX/microsoft-abi-vftables.cpp
new file mode 100644
index 0000000..825aba0
--- /dev/null
+++ b/test/CodeGenCXX/microsoft-abi-vftables.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -o - -O1 -disable-llvm-optzns | FileCheck %s -check-prefix=NO-RTTI
+// RUN: %clang_cc1 %s -triple=i386-pc-win32 -emit-llvm -o - -O1 -disable-llvm-optzns | FileCheck %s -check-prefix=RTTI
+
+// RTTI-DAG: $"\01??_7S@@6B@" = comdat largest
+// RTTI-DAG: $"\01??_7V@@6B@" = comdat largest
+// RTTI-DAG: $"\01??_7W@?A@@6B@" = comdat largest
+
+struct S {
+  virtual ~S();
+} s;
+
+// RTTI-DAG: [[VTABLE_S:@.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast ({{.*}} @"\01??_R4S@@6B@" to i8*), i8* bitcast ({{.*}} @"\01??_GS@@UAEPAXI@Z" to i8*)], comdat $"\01??_7S@@6B@"
+// RTTI-DAG: @"\01??_7S@@6B@" = unnamed_addr alias getelementptr inbounds ([2 x i8*]* [[VTABLE_S]], i32 0, i32 1)
+
+// NO-RTTI-DAG: @"\01??_7S@@6B@" = linkonce_odr unnamed_addr constant [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GS@@UAEPAXI@Z" to i8*)]
+
+struct __declspec(dllimport) U {
+  virtual ~U();
+} u;
+
+// RTTI-DAG: @"\01??_7U@@6B@" = available_externally dllimport unnamed_addr constant [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GU@@UAEPAXI@Z" to i8*)]
+
+// NO-RTTI-DAG: @"\01??_7U@@6B@" = available_externally dllimport unnamed_addr constant [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GU@@UAEPAXI@Z" to i8*)]
+
+struct __declspec(dllexport) V {
+  virtual ~V();
+} v;
+
+// RTTI-DAG: [[VTABLE_V:@.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast ({{.*}} @"\01??_R4V@@6B@" to i8*), i8* bitcast ({{.*}} @"\01??_GV@@UAEPAXI@Z" to i8*)], comdat $"\01??_7V@@6B@"
+// RTTI-DAG: @"\01??_7V@@6B@" = dllexport unnamed_addr alias getelementptr inbounds ([2 x i8*]* [[VTABLE_V]], i32 0, i32 1)
+
+// NO-RTTI-DAG: @"\01??_7V@@6B@" = weak_odr dllexport unnamed_addr constant [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GV@@UAEPAXI@Z" to i8*)]
+
+namespace {
+struct W {
+  virtual ~W();
+} w;
+}
+// RTTI-DAG: [[VTABLE_W:@.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast ({{.*}} @"\01??_R4W@?A@@6B@" to i8*), i8* bitcast ({{.*}} @"\01??_GW@?A@@UAEPAXI@Z" to i8*)], comdat $"\01??_7W@?A@@6B@"
+// RTTI-DAG: @"\01??_7W@?A@@6B@" = unnamed_addr alias internal getelementptr inbounds ([2 x i8*]* @1, i32 0, i32 1)
+
+// NO-RTTI-DAG: @"\01??_7W@?A@@6B@" = internal unnamed_addr constant [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GW@?A@@UAEPAXI@Z" to i8*)]
diff --git a/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp b/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp
index 8e23ade..a6fcdea 100644
--- a/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp
+++ b/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 %s -fno-rtti -cxx-abi microsoft -triple=i386-pc-win32 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -o - | FileCheck %s
 
 // For now, just make sure x86_64 doesn't crash.
-// RUN: %clang_cc1 %s -fno-rtti -cxx-abi microsoft -triple=x86_64-pc-win32 -emit-llvm -o %t
+// RUN: %clang_cc1 %s -fno-rtti -triple=x86_64-pc-win32 -emit-llvm -o %t
 
 struct A {
   virtual void f();
@@ -23,7 +23,7 @@
 
 D::D() {}  // Forces vftable emission.
 
-// CHECK-LABEL: define weak x86_thiscallcc void @"\01?f@D@@$4PPPPPPPM@A@AEXXZ"
+// CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01?f@D@@$4PPPPPPPM@A@AEXXZ"
 // CHECK: %[[ECX:.*]] = load %struct.D** %{{.*}}
 // CHECK: %[[ECX_i8:.*]] = bitcast %struct.D* %[[ECX]] to i8*
 // CHECK: %[[VTORDISP_PTR_i8:.*]] = getelementptr i8* %[[ECX_i8]], i32 -4
@@ -34,7 +34,7 @@
 // CHECK: call x86_thiscallcc void @"\01?f@D@@UAEXXZ"(i8* %[[ADJUSTED_i8]])
 // CHECK: ret void
 
-// CHECK-LABEL: define weak x86_thiscallcc void @"\01?f@D@@$4PPPPPPPI@3AEXXZ"
+// CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01?f@D@@$4PPPPPPPI@3AEXXZ"
 // CHECK: %[[ECX:.*]] = load %struct.D** %{{.*}}
 // CHECK: %[[ECX_i8:.*]] = bitcast %struct.D* %[[ECX]] to i8*
 // CHECK: %[[VTORDISP_PTR_i8:.*]] = getelementptr i8* %[[ECX_i8]], i32 -8
@@ -63,7 +63,7 @@
 
 G::G() {}  // Forces vftable emission.
 
-// CHECK-LABEL: define weak x86_thiscallcc void @"\01?f@E@@$R4BA@M@PPPPPPPM@7AEXXZ"(i8*)
+// CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01?f@E@@$R4BA@M@PPPPPPPM@7AEXXZ"(i8*)
 // CHECK: %[[ECX:.*]] = load %struct.E** %{{.*}}
 // CHECK: %[[ECX_i8:.*]] = bitcast %struct.E* %[[ECX]] to i8*
 // CHECK: %[[VTORDISP_PTR_i8:.*]] = getelementptr i8* %[[ECX_i8]], i32 -4
diff --git a/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp b/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
index 7c223ca..2f0fffee 100644
--- a/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
+++ b/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp
@@ -1,9 +1,9 @@
-// RUN: %clang_cc1 %s -fno-rtti -cxx-abi microsoft -triple=i386-pc-win32 -emit-llvm -o %t
+// RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -o %t
 // RUN: FileCheck %s < %t
 // RUN: FileCheck --check-prefix=CHECK2 %s < %t
 
 // For now, just make sure x86_64 doesn't crash.
-// RUN: %clang_cc1 %s -fno-rtti -cxx-abi microsoft -triple=x86_64-pc-win32 -emit-llvm -o %t
+// RUN: %clang_cc1 %s -fno-rtti -triple=x86_64-pc-win32 -emit-llvm -o %t
 
 struct VBase {
   virtual ~VBase();
@@ -312,3 +312,151 @@
 }
 
 }
+
+namespace test2 {
+struct A { A(); };
+struct B : virtual A { B() {} };
+struct C : B, A { C() {} };
+
+// PR18435: Order mattered here.  We were generating code for the delegating
+// call to B() from C().
+void callC() { C x; }
+
+// CHECK-LABEL: define linkonce_odr x86_thiscallcc %"struct.test2::C"* @"\01??0C@test2@@QAE@XZ"
+// CHECK:           (%"struct.test2::C"* returned %this, i32 %is_most_derived)
+// CHECK: br i1
+//   Virtual bases
+// CHECK: call x86_thiscallcc %"struct.test2::A"* @"\01??0A@test2@@QAE@XZ"(%"struct.test2::A"* %{{.*}})
+// CHECK: br label
+//   Non-virtual bases
+// CHECK: call x86_thiscallcc %"struct.test2::B"* @"\01??0B@test2@@QAE@XZ"(%"struct.test2::B"* %{{.*}}, i32 0)
+// CHECK: call x86_thiscallcc %"struct.test2::A"* @"\01??0A@test2@@QAE@XZ"(%"struct.test2::A"* %{{.*}})
+// CHECK: ret
+
+// CHECK2-LABEL: define linkonce_odr x86_thiscallcc %"struct.test2::B"* @"\01??0B@test2@@QAE@XZ"
+// CHECK2:           (%"struct.test2::B"* returned %this, i32 %is_most_derived)
+// CHECK2: call x86_thiscallcc %"struct.test2::A"* @"\01??0A@test2@@QAE@XZ"(%"struct.test2::A"* %{{.*}})
+// CHECK2: ret
+
+}
+
+namespace test3 {
+// PR19104: A non-virtual call of a virtual method doesn't use vftable thunks,
+// so requires only static adjustment which is different to the one used
+// for virtual calls.
+struct A {
+  virtual void foo();
+};
+
+struct B : virtual A {
+  virtual void bar();
+};
+
+struct C : virtual A {
+  virtual void foo();
+};
+
+struct D : B, C {
+  virtual void bar();
+  int field;  // Laid out between C and A subobjects in D.
+};
+
+void D::bar() {
+  // CHECK-LABEL: define x86_thiscallcc void @"\01?bar@D@test3@@UAEXXZ"(%"struct.test3::D"* %this)
+
+  C::foo();
+  // Shouldn't need any vbtable lookups.  All we have to do is adjust to C*,
+  // then compensate for the adjustment performed in the C::foo() prologue.
+  // CHECK-NOT: load i8**
+  // CHECK: %[[OBJ_i8:.*]] = bitcast %"struct.test3::D"* %{{.*}} to i8*
+  // CHECK: %[[C_i8:.*]] = getelementptr inbounds i8* %[[OBJ_i8]], i32 8
+  // CHECK: %[[C:.*]] = bitcast i8* %[[C_i8]] to %"struct.test3::C"*
+  // CHECK: %[[C_i8:.*]] = bitcast %"struct.test3::C"* %[[C]] to i8*
+  // CHECK: %[[ARG:.*]] = getelementptr i8* %[[C_i8]], i32 4
+  // CHECK: call x86_thiscallcc void @"\01?foo@C@test3@@UAEXXZ"(i8* %[[ARG]])
+  // CHECK: ret
+}
+}
+
+namespace test4{
+// PR19172: We used to merge method vftable locations wrong.
+
+struct A {
+  virtual ~A() {}
+};
+
+struct B {
+  virtual ~B() {}
+};
+
+struct C : virtual A, B {
+  virtual ~C();
+};
+
+void foo(void*);
+
+C::~C() {
+  // CHECK-LABEL: define x86_thiscallcc void @"\01??1C@test4@@UAE@XZ"(%"struct.test4::C"* %this)
+
+  // In this case "this" points to the most derived class, so no GEPs needed.
+  // CHECK-NOT: getelementptr
+  // CHECK-NOT: bitcast
+  // CHECK: %[[VFPTR_i8:.*]] = bitcast %"struct.test4::C"* %{{.*}} to [1 x i8*]**
+  // CHECK: store [1 x i8*]* @"\01??_7C@test4@@6BB@1@@", [1 x i8*]** %[[VFPTR_i8]]
+
+  foo(this);
+  // CHECK: ret
+}
+
+void destroy(C *obj) {
+  // CHECK-LABEL: define void @"\01?destroy@test4@@YAXPAUC@1@@Z"(%"struct.test4::C"* %obj)
+
+  delete obj;
+  // CHECK: %[[VPTR:.*]] = bitcast %"struct.test4::C"* %[[OBJ:.*]] to void (%"struct.test4::C"*, i32)***
+  // CHECK: %[[VFTABLE:.*]] = load void (%"struct.test4::C"*, i32)*** %[[VPTR]]
+  // CHECK: %[[VFTENTRY:.*]] = getelementptr inbounds void (%"struct.test4::C"*, i32)** %[[VFTABLE]], i64 0
+  // CHECK: %[[VFUN:.*]] = load void (%"struct.test4::C"*, i32)** %[[VFTENTRY]]
+  // CHECK: call x86_thiscallcc void %[[VFUN]](%"struct.test4::C"* %[[OBJ]], i32 1)
+  // CHECK: ret
+}
+
+struct D {
+  virtual void d();
+};
+
+// The first non-virtual base doesn't have a vdtor,
+// but "this adjustment" is not needed.
+struct E : D, B, virtual A {
+  virtual ~E();
+};
+
+E::~E() {
+  // CHECK-LABEL: define x86_thiscallcc void @"\01??1E@test4@@UAE@XZ"(%"struct.test4::E"* %this)
+
+  // In this case "this" points to the most derived class, so no GEPs needed.
+  // CHECK-NOT: getelementptr
+  // CHECK-NOT: bitcast
+  // CHECK: %[[VFPTR_i8:.*]] = bitcast %"struct.test4::E"* %{{.*}} to [1 x i8*]**
+  // CHECK: store [1 x i8*]* @"\01??_7E@test4@@6BD@1@@", [1 x i8*]** %[[VFPTR_i8]]
+  foo(this);
+}
+
+void destroy(E *obj) {
+  // CHECK-LABEL: define void @"\01?destroy@test4@@YAXPAUE@1@@Z"(%"struct.test4::E"* %obj)
+
+  // CHECK-NOT: getelementptr
+  // CHECK: %[[OBJ_i8:.*]] = bitcast %"struct.test4::E"* %[[OBJ:.*]] to i8*
+  // CHECK: %[[B_i8:.*]] = getelementptr inbounds i8* %[[OBJ_i8]], i32 4
+  // CHECK: %[[VPTR:.*]] = bitcast i8* %[[B_i8]] to void (%"struct.test4::E"*, i32)***
+  // CHECK: %[[VFTABLE:.*]] = load void (%"struct.test4::E"*, i32)*** %[[VPTR]]
+  // CHECK: %[[VFTENTRY:.*]] = getelementptr inbounds void (%"struct.test4::E"*, i32)** %[[VFTABLE]], i64 0
+  // CHECK: %[[VFUN:.*]] = load void (%"struct.test4::E"*, i32)** %[[VFTENTRY]]
+  // CHECK: %[[OBJ_i8:.*]] = bitcast %"struct.test4::E"* %[[OBJ]] to i8*
+  // CHECK: %[[B_i8:.*]] = getelementptr inbounds i8* %[[OBJ_i8]], i32 4
+  // FIXME: in fact, the call should take i8* and the bitcast is redundant.
+  // CHECK: %[[B_as_E:.*]] = bitcast i8* %[[B_i8]] to %"struct.test4::E"*
+  // CHECK: call x86_thiscallcc void %[[VFUN]](%"struct.test4::E"* %[[B_as_E]], i32 1)
+  delete obj;
+}
+
+}
diff --git a/test/CodeGenCXX/microsoft-abi-virtual-member-pointers.cpp b/test/CodeGenCXX/microsoft-abi-virtual-member-pointers.cpp
index 51a04c8..974953c 100644
--- a/test/CodeGenCXX/microsoft-abi-virtual-member-pointers.cpp
+++ b/test/CodeGenCXX/microsoft-abi-virtual-member-pointers.cpp
@@ -1,14 +1,23 @@
-// RUN: %clang_cc1 -fno-rtti -emit-llvm -cxx-abi microsoft -triple=i386-pc-win32 %s -o - | FileCheck %s --check-prefix=CHECK32
-// RUN: %clang_cc1 -fno-rtti -emit-llvm -cxx-abi microsoft -triple=x86_64-pc-win32 %s -o - | FileCheck %s --check-prefix=CHECK64
+// RUN: %clang_cc1 -fno-rtti -emit-llvm -triple=i386-pc-win32 %s -o - | FileCheck %s --check-prefix=CHECK32
+// RUN: %clang_cc1 -fno-rtti -emit-llvm -triple=x86_64-pc-win32 %s -o - | FileCheck %s --check-prefix=CHECK64
 
 struct S {
   int x, y, z;
 };
 
+// U is not trivially copyable, and requires inalloca to pass by value.
+struct U {
+  int u;
+  U();
+  ~U();
+  U(const U &);
+};
+
 struct C {
   virtual void foo();
   virtual int bar(int, double);
   virtual S baz(int);
+  virtual S qux(U);
 };
 
 namespace {
@@ -31,18 +40,22 @@
   void (D::*ptr4)();
   ptr4 = &D::foo;
 
+  S (C::*ptr5)(U);
+  ptr5 = &C::qux;
+
+
 // CHECK32-LABEL: define void @"\01?f@@YAXXZ"()
 // CHECK32: store i8* bitcast (void (%struct.C*)* @"\01??_9C@@$BA@AE" to i8*), i8** %ptr
 // CHECK32: store i8* bitcast (i32 (%struct.C*, i32, double)* @"\01??_9C@@$B3AE" to i8*), i8** %ptr2
-// CHECK32: store i8* bitcast (void (%struct.S*, %struct.C*, i32)* @"\01??_9C@@$B7AE" to i8*), i8** %ptr3
-// CHECK32: store i8* bitcast (void (%"struct.<anonymous namespace>::D"*)* @"\01??_9D@?A@@$BA@AE" to i8*), i8** %ptr4
+// CHECK32: store i8* bitcast (void (%struct.C*, %struct.S*, i32)* @"\01??_9C@@$B7AE" to i8*), i8** %ptr3
+// CHECK32: store i8* bitcast (void (%"struct.(anonymous namespace)::D"*)* @"\01??_9D@?A@@$BA@AE" to i8*), i8** %ptr4
 // CHECK32: }
 //
 // CHECK64-LABEL: define void @"\01?f@@YAXXZ"()
 // CHECK64: store i8* bitcast (void (%struct.C*)* @"\01??_9C@@$BA@AA" to i8*), i8** %ptr
 // CHECK64: store i8* bitcast (i32 (%struct.C*, i32, double)* @"\01??_9C@@$B7AA" to i8*), i8** %ptr2
-// CHECK64: store i8* bitcast (void (%struct.S*, %struct.C*, i32)* @"\01??_9C@@$BBA@AA" to i8*), i8** %ptr3
-// CHECK64: store i8* bitcast (void (%"struct.<anonymous namespace>::D"*)* @"\01??_9D@?A@@$BA@AA" to i8*), i8** %ptr
+// CHECK64: store i8* bitcast (void (%struct.C*, %struct.S*, i32)* @"\01??_9C@@$BBA@AA" to i8*), i8** %ptr3
+// CHECK64: store i8* bitcast (void (%"struct.(anonymous namespace)::D"*)* @"\01??_9D@?A@@$BA@AA" to i8*), i8** %ptr
 // CHECK64: }
 }
 
@@ -51,14 +64,14 @@
 // CHECK32-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_9C@@$BA@AE"(%struct.C* %this) unnamed_addr
 // CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*)** %{{.*}}, i64 0
 // CHECK32: [[CALLEE:%.*]] = load void (%struct.C*)** [[VPTR]]
-// CHECK32: call x86_thiscallcc void [[CALLEE]](%struct.C* %{{.*}})
+// CHECK32: musttail call x86_thiscallcc void [[CALLEE]](%struct.C* %{{.*}})
 // CHECK32: ret void
 // CHECK32: }
 //
 // CHECK64-LABEL: define linkonce_odr void @"\01??_9C@@$BA@AA"(%struct.C* %this) unnamed_addr
 // CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*)** %{{.*}}, i64 0
 // CHECK64: [[CALLEE:%.*]] = load void (%struct.C*)** [[VPTR]]
-// CHECK64: call void [[CALLEE]](%struct.C* %{{.*}})
+// CHECK64: musttail call void [[CALLEE]](%struct.C* %{{.*}})
 // CHECK64: ret void
 // CHECK64: }
 
@@ -66,43 +79,58 @@
 // CHECK32-LABEL: define linkonce_odr x86_thiscallcc i32 @"\01??_9C@@$B3AE"(%struct.C* %this, i32, double) unnamed_addr
 // CHECK32: [[VPTR:%.*]] = getelementptr inbounds i32 (%struct.C*, i32, double)** %{{.*}}, i64 1
 // CHECK32: [[CALLEE:%.*]] = load i32 (%struct.C*, i32, double)** [[VPTR]]
-// CHECK32: [[CALL:%.*]] = call x86_thiscallcc i32 [[CALLEE]](%struct.C* %{{.*}}, i32 %{{.*}}, double %{{.*}})
+// CHECK32: [[CALL:%.*]] = musttail call x86_thiscallcc i32 [[CALLEE]](%struct.C* %{{.*}}, i32 %{{.*}}, double %{{.*}})
 // CHECK32: ret i32 [[CALL]]
 // CHECK32: }
 //
 // CHECK64-LABEL: define linkonce_odr i32 @"\01??_9C@@$B7AA"(%struct.C* %this, i32, double) unnamed_addr
 // CHECK64: [[VPTR:%.*]] = getelementptr inbounds i32 (%struct.C*, i32, double)** %{{.*}}, i64 1
 // CHECK64: [[CALLEE:%.*]] = load i32 (%struct.C*, i32, double)** [[VPTR]]
-// CHECK64: [[CALL:%.*]] = call i32 [[CALLEE]](%struct.C* %{{.*}}, i32 %{{.*}}, double %{{.*}})
+// CHECK64: [[CALL:%.*]] = musttail call i32 [[CALLEE]](%struct.C* %{{.*}}, i32 %{{.*}}, double %{{.*}})
 // CHECK64: ret i32 [[CALL]]
 // CHECK64: }
 
 // Thunk for calling the 3rd virtual function in C, taking an int parameter, returning a struct.
-// CHECK32-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_9C@@$B7AE"(%struct.S* noalias sret %agg.result, %struct.C* %this, i32) unnamed_addr
-// CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%struct.S*, %struct.C*, i32)** %{{.*}}, i64 2
-// CHECK32: [[CALLEE:%.*]] = load void (%struct.S*, %struct.C*, i32)** [[VPTR]]
-// CHECK32: call x86_thiscallcc void [[CALLEE]](%struct.S* sret %agg.result, %struct.C* %{{.*}}, i32 %{{.*}})
+// CHECK32-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_9C@@$B7AE"(%struct.C* %this, %struct.S* noalias sret %agg.result, i32) unnamed_addr
+// CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, %struct.S*, i32)** %{{.*}}, i64 2
+// CHECK32: [[CALLEE:%.*]] = load void (%struct.C*, %struct.S*, i32)** [[VPTR]]
+// CHECK32: musttail call x86_thiscallcc void [[CALLEE]](%struct.C* %{{.*}}, %struct.S* sret %agg.result, i32 %{{.*}})
 // CHECK32: ret void
 // CHECK32: }
 //
-// CHECK64-LABEL: define linkonce_odr void @"\01??_9C@@$BBA@AA"(%struct.S* noalias sret %agg.result, %struct.C* %this, i32) unnamed_addr
-// CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%struct.S*, %struct.C*, i32)** %{{.*}}, i64 2
-// CHECK64: [[CALLEE:%.*]] = load void (%struct.S*, %struct.C*, i32)** [[VPTR]]
-// CHECK64: call void [[CALLEE]](%struct.S* sret %agg.result, %struct.C* %{{.*}}, i32 %{{.*}})
+// CHECK64-LABEL: define linkonce_odr void @"\01??_9C@@$BBA@AA"(%struct.C* %this, %struct.S* noalias sret %agg.result, i32) unnamed_addr
+// CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, %struct.S*, i32)** %{{.*}}, i64 2
+// CHECK64: [[CALLEE:%.*]] = load void (%struct.C*, %struct.S*, i32)** [[VPTR]]
+// CHECK64: musttail call void [[CALLEE]](%struct.C* %{{.*}}, %struct.S* sret %agg.result, i32 %{{.*}})
 // CHECK64: ret void
 // CHECK64: }
 
 // Thunk for calling the virtual function in internal class D.
-// CHECK32-LABEL: define internal x86_thiscallcc void @"\01??_9D@?A@@$BA@AE"(%"struct.<anonymous namespace>::D"* %this) unnamed_addr
-// CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%"struct.<anonymous namespace>::D"*)** %{{.*}}, i64 0
-// CHECK32: [[CALLEE:%.*]] = load void (%"struct.<anonymous namespace>::D"*)** [[VPTR]]
-// CHECK32: call x86_thiscallcc void [[CALLEE]](%"struct.<anonymous namespace>::D"* %{{.*}})
+// CHECK32-LABEL: define internal x86_thiscallcc void @"\01??_9D@?A@@$BA@AE"(%"struct.(anonymous namespace)::D"* %this) unnamed_addr
+// CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%"struct.(anonymous namespace)::D"*)** %{{.*}}, i64 0
+// CHECK32: [[CALLEE:%.*]] = load void (%"struct.(anonymous namespace)::D"*)** [[VPTR]]
+// CHECK32: musttail call x86_thiscallcc void [[CALLEE]](%"struct.(anonymous namespace)::D"* %{{.*}})
 // CHECK32: ret void
 // CHECK32: }
 //
-// CHECK64-LABEL: define internal void @"\01??_9D@?A@@$BA@AA"(%"struct.<anonymous namespace>::D"* %this) unnamed_addr
-// CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%"struct.<anonymous namespace>::D"*)** %{{.*}}, i64 0
-// CHECK64: [[CALLEE:%.*]] = load void (%"struct.<anonymous namespace>::D"*)** [[VPTR]]
-// CHECK64: call void [[CALLEE]](%"struct.<anonymous namespace>::D"* %{{.*}})
+// CHECK64-LABEL: define internal void @"\01??_9D@?A@@$BA@AA"(%"struct.(anonymous namespace)::D"* %this) unnamed_addr
+// CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%"struct.(anonymous namespace)::D"*)** %{{.*}}, i64 0
+// CHECK64: [[CALLEE:%.*]] = load void (%"struct.(anonymous namespace)::D"*)** [[VPTR]]
+// CHECK64: musttail call void [[CALLEE]](%"struct.(anonymous namespace)::D"* %{{.*}})
+// CHECK64: ret void
+// CHECK64: }
+
+// Thunk for calling the fourth virtual function in C, taking a struct parameter and returning a struct.
+// CHECK32-LABEL: define linkonce_odr x86_thiscallcc %struct.S* @"\01??_9C@@$BM@AE"(%struct.C* %this, <{ %struct.S*, %struct.U }>* inalloca) unnamed_addr
+// CHECK32: [[VPTR:%.*]] = getelementptr inbounds %struct.S* (%struct.C*, <{ %struct.S*, %struct.U }>*)** %{{.*}}, i64 3
+// CHECK32: [[CALLEE:%.*]] = load %struct.S* (%struct.C*, <{ %struct.S*, %struct.U }>*)** [[VPTR]]
+// CHECK32: [[CALL:%.*]] = musttail call x86_thiscallcc %struct.S* [[CALLEE]](%struct.C* %this, <{ %struct.S*, %struct.U }>* inalloca %{{.*}})
+// CHECK32: ret %struct.S* [[CALL]]
+// CHECK32: }
+//
+// CHECK64-LABEL: define linkonce_odr void @"\01??_9C@@$BBI@AA"(%struct.C* %this, %struct.S* noalias sret %agg.result, %struct.U*) unnamed_addr
+// CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, %struct.S*, %struct.U*)** %{{.*}}, i64 3
+// CHECK64: [[CALLEE:%.*]] = load void (%struct.C*, %struct.S*, %struct.U*)** [[VPTR]]
+// CHECK64: musttail call void [[CALLEE]](%struct.C* %this, %struct.S* sret %agg.result, %struct.U* %{{.*}})
 // CHECK64: ret void
 // CHECK64: }
diff --git a/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-no-thunks.cpp b/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-no-thunks.cpp
new file mode 100644
index 0000000..86314cf
--- /dev/null
+++ b/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-no-thunks.cpp
@@ -0,0 +1,302 @@
+// RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -o %t.ll -fdump-vtable-layouts >%t
+// RUN: FileCheck %s < %t
+// RUN: FileCheck --check-prefix=MANGLING %s < %t.ll
+
+namespace test1 {
+struct A {
+  virtual void f();
+};
+
+struct B {
+  virtual void g();
+  // Add an extra virtual method so it's easier to check for the absence of thunks.
+  virtual void h();
+};
+
+struct X : A, B {
+  // CHECK-LABEL: VFTable for 'test1::A' in 'test1::X' (1 entry)
+  // CHECK-NEXT:   0 | void test1::X::f()
+
+  // CHECK-LABEL: VFTable for 'test1::B' in 'test1::X' (2 entries)
+  // CHECK-NEXT:   0 | void test1::B::g()
+  // CHECK-NEXT:   1 | void test1::B::h()
+
+  // CHECK-LABEL: VFTable indices for 'test1::X' (1 entry)
+  // CHECK-NEXT:   0 | void test1::X::f()
+
+  // MANGLING-DAG: @"\01??_7X@test1@@6BA@1@@"
+  // MANGLING-DAG: @"\01??_7X@test1@@6BB@1@@"
+
+  // Overrides only the left child's method (A::f), needs no thunks.
+  virtual void f();
+} x;
+
+void build_vftable(X *obj) { obj->f(); }
+}
+
+namespace test2 {
+struct A {
+  virtual void f();
+};
+
+struct B {
+  virtual void g();
+  virtual void h();
+};
+
+struct X : A, B {
+  // CHECK-LABEL: VFTable for 'test2::A' in 'test2::X' (1 entry)
+  // CHECK-NEXT:   0 | void test2::A::f()
+
+  // CHECK-LABEL: VFTable for 'test2::B' in 'test2::X' (2 entries)
+  // CHECK-NEXT:   0 | void test2::X::g()
+  // CHECK-NEXT:   1 | void test2::B::h()
+
+  // CHECK-LABEL: VFTable indices for 'test2::X' (1 entry).
+  // CHECK-NEXT:   via vfptr at offset 4
+  // CHECK-NEXT:   0 | void test2::X::g()
+
+  // Overrides only the right child's method (B::g), needs this adjustment but
+  // not thunks.
+  virtual void g();
+};
+
+void build_vftable(X *obj) { obj->g(); }
+}
+
+namespace test3 {
+struct A {
+  virtual void f();
+};
+
+struct B {
+  virtual void g();
+  virtual void h();
+};
+
+struct X : A, B {
+  // CHECK-LABEL: VFTable for 'test3::A' in 'test3::X' (2 entries)
+  // CHECK-NEXT:   0 | void test3::A::f()
+  // CHECK-NEXT:   1 | void test3::X::i()
+
+  // CHECK-LABEL: VFTable for 'test3::B' in 'test3::X' (2 entries)
+  // CHECK-NEXT:   0 | void test3::B::g()
+  // CHECK-NEXT:   1 | void test3::B::h()
+
+  // CHECK-LABEL: VFTable indices for 'test3::X' (1 entry).
+  // CHECK-NEXT:   1 | void test3::X::i()
+
+  // Only adds a new method.
+  virtual void i();
+};
+
+void build_vftable(X *obj) { obj->i(); }
+}
+
+namespace test4 {
+struct A {
+  virtual void f();
+};
+
+struct Empty { };  // Doesn't have a vftable!
+
+// Only the right base has a vftable, so it's laid out before the left one!
+struct X : Empty, A {
+  // CHECK-LABEL: VFTable for 'test4::A' in 'test4::X' (1 entry)
+  // CHECK-NEXT:   0 | void test4::X::f()
+
+  // CHECK-LABEL: VFTable indices for 'test4::X' (1 entry).
+  // CHECK-NEXT:   0 | void test4::X::f()
+
+  // MANGLING-DAG: @"\01??_7X@test4@@6B@"
+
+  virtual void f();
+} x;
+
+void build_vftable(X *obj) { obj->f(); }
+}
+
+namespace test5 {
+struct A {
+  virtual void f();
+};
+
+struct B {
+  virtual void g();
+  virtual void h();
+};
+
+struct C : A, B {
+  virtual void f();
+};
+
+struct X : C {
+  // CHECK-LABEL: VFTable for 'test5::A' in 'test5::C' in 'test5::X' (1 entry).
+  // CHECK-NEXT:   0 | void test5::X::f()
+
+  // CHECK-LABEL: VFTable for 'test5::B' in 'test5::C' in 'test5::X' (2 entries).
+  // CHECK-NEXT:   0 | void test5::B::g()
+  // CHECK-NEXT:   1 | void test5::B::h()
+
+  // CHECK-LABEL: VFTable indices for 'test5::X' (1 entry).
+  // CHECK-NEXT:   0 | void test5::X::f()
+
+  // MANGLING-DAG: @"\01??_7X@test5@@6BA@1@@"
+  // MANGLING-DAG: @"\01??_7X@test5@@6BB@1@@"
+
+  // Overrides both C::f and A::f.
+  virtual void f();
+} x;
+
+void build_vftable(X *obj) { obj->f(); }
+}
+
+namespace test6 {
+struct A {
+  virtual void f();
+};
+
+struct B {
+  virtual void g();
+  virtual void h();
+};
+
+struct C : A, B {
+  virtual void g();
+};
+
+struct X : C {
+  // CHECK-LABEL: VFTable for 'test6::A' in 'test6::C' in 'test6::X' (1 entry).
+  // CHECK-NEXT:   0 | void test6::A::f()
+
+  // CHECK-LABEL: VFTable for 'test6::B' in 'test6::C' in 'test6::X' (2 entries).
+  // CHECK-NEXT:   0 | void test6::X::g()
+  // CHECK-NEXT:   1 | void test6::B::h()
+
+  // CHECK-LABEL: VFTable indices for 'test6::X' (1 entry).
+  // CHECK-NEXT:   via vfptr at offset 4
+  // CHECK-NEXT:   0 | void test6::X::g()
+
+  // Overrides both C::g and B::g.
+  virtual void g();
+};
+
+void build_vftable(X *obj) { obj->g(); }
+}
+
+namespace test7 {
+struct A {
+  virtual void f();
+};
+
+struct B {
+  virtual void g();
+  virtual void h();
+};
+
+struct C : A, B {
+  // Only adds a new method.
+  virtual void i();
+};
+
+struct X : C {
+  // CHECK-LABEL: VFTable for 'test7::A' in 'test7::C' in 'test7::X' (2 entries).
+  // CHECK-NEXT:   0 | void test7::A::f()
+  // CHECK-NEXT:   1 | void test7::C::i()
+
+  // CHECK-LABEL: VFTable for 'test7::B' in 'test7::C' in 'test7::X' (2 entries).
+  // CHECK-NEXT:   0 | void test7::X::g()
+  // CHECK-NEXT:   1 | void test7::B::h()
+
+  // CHECK-LABEL: VFTable indices for 'test7::X' (1 entry).
+  // CHECK-NEXT:   via vfptr at offset 4
+  // CHECK-NEXT:   0 | void test7::X::g()
+
+  // Overrides grandparent's B::g.
+  virtual void g();
+};
+
+void build_vftable(X *obj) { obj->g(); }
+}
+
+namespace test8 {
+struct A {
+  virtual void f();
+};
+
+struct B : A {
+  virtual void g();
+};
+
+// There are two 'A' subobjects in this class.
+struct X : A, B {
+  // CHECK-LABEL: VFTable for 'test8::A' in 'test8::X' (2 entries).
+  // CHECK-NEXT:   0 | void test8::A::f()
+  // CHECK-NEXT:   1 | void test8::X::h()
+
+  // CHECK-LABEL: VFTable for 'test8::A' in 'test8::B' in 'test8::X' (2 entries).
+  // CHECK-NEXT:   0 | void test8::A::f()
+  // CHECK-NEXT:   1 | void test8::B::g()
+
+  // CHECK-LABEL: VFTable indices for 'test8::X' (1 entry).
+  // CHECK-NEXT:   1 | void test8::X::h()
+
+  // MANGLING-DAG: @"\01??_7X@test8@@6BA@1@@"
+  // MANGLING-DAG: @"\01??_7X@test8@@6BB@1@@"
+
+  virtual void h();
+} x;
+
+void build_vftable(X *obj) { obj->h(); }
+}
+
+namespace test9 {
+struct A {
+  virtual void f();
+};
+
+struct B {
+  virtual void g();
+  virtual void h();
+};
+
+struct C : A, B {
+  // Overrides only the left child's method (A::f).
+  virtual void f();
+};
+
+struct D : A, B {
+  // Overrides only the right child's method (B::g).
+  virtual void g();
+};
+
+// 2-level structure with repeating subobject types, but no thunks needed.
+struct X : C, D {
+  // CHECK-LABEL: VFTable for 'test9::A' in 'test9::C' in 'test9::X' (2 entries)
+  // CHECK-NEXT:   0 | void test9::C::f()
+  // CHECK-NEXT:   1 | void test9::X::z()
+
+  // CHECK-LABEL: VFTable for 'test9::B' in 'test9::C' in 'test9::X' (2 entries)
+  // CHECK-NEXT:   0 | void test9::B::g()
+  // CHECK-NEXT:   1 | void test9::B::h()
+
+  // CHECK-LABEL: VFTable for 'test9::A' in 'test9::D' in 'test9::X' (1 entry)
+  // CHECK-NEXT:   0 | void test9::A::f()
+
+  // CHECK-LABEL: VFTable for 'test9::B' in 'test9::D' in 'test9::X' (2 entries)
+  // CHECK-NEXT:   0 | void test9::D::g()
+  // CHECK-NEXT:   1 | void test9::B::h()
+
+  // CHECK-LABEL: VFTable indices for 'test9::X' (1 entry).
+  // CHECK-NEXT:   1 | void test9::X::z()
+
+  // MANGLING-DAG: @"\01??_7X@test9@@6BA@1@C@1@@"
+  // MANGLING-DAG: @"\01??_7X@test9@@6BA@1@D@1@@"
+  // MANGLING-DAG: @"\01??_7X@test9@@6BB@1@C@1@@"
+  // MANGLING-DAG: @"\01??_7X@test9@@6BB@1@D@1@@"
+
+  virtual void z();
+} x;
+
+void build_vftable(test9::X *obj) { obj->z(); }
+}
diff --git a/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-pure-virtual.cpp b/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-pure-virtual.cpp
new file mode 100644
index 0000000..76182a2
--- /dev/null
+++ b/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-pure-virtual.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -o %t.ll -fdump-vtable-layouts >%t
+// RUN: FileCheck %s < %t
+// RUN: FileCheck --check-prefix=MANGLING %s < %t.ll
+
+struct A {
+  virtual void f();
+};
+
+struct B {
+  virtual void g() = 0;
+  virtual void h();
+};
+
+struct C : A, B {
+  // CHECK-LABEL: VFTable for 'A' in 'C' (1 entry)
+  // CHECK-NEXT:   0 | void A::f()
+
+  // CHECK-LABEL: VFTable for 'B' in 'C' (2 entries)
+  // CHECK-NEXT:   0 | void C::g()
+  // CHECK-NEXT:   1 | void B::h()
+
+  // CHECK-LABEL: VFTable indices for 'C' (1 entry).
+  // CHECK-NEXT:   via vfptr at offset 4
+  // CHECK-NEXT:   0 | void C::g()
+
+  // MANGLING-DAG: @"\01??_7C@@6BA@@@"
+  // MANGLING-DAG: @"\01??_7C@@6BB@@@"
+
+  // Overrides only the right child's method (B::g),
+  // needs this adjustment but not thunks.
+  virtual void g();
+};
+
+C c;
+void build_vftable(C *obj) { obj->g(); }
diff --git a/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-return-adjustment.cpp b/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-return-adjustment.cpp
new file mode 100644
index 0000000..2d0bf63
--- /dev/null
+++ b/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-return-adjustment.cpp
@@ -0,0 +1,297 @@
+// RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -o %t.ll -fdump-vtable-layouts >%t
+// RUN: FileCheck %s < %t
+// RUN: FileCheck --check-prefix=MANGLING %s < %t.ll
+
+namespace test1 {
+struct A {
+  virtual void g();
+  // Add an extra virtual method so it's easier to check for the absence of thunks.
+  virtual void h();
+};
+
+struct B {
+  virtual void g();
+};
+
+// Overrides a method of two bases at the same time, thus needing thunks.
+struct C : A, B {
+  virtual void g();
+};
+
+struct D {
+  virtual B* foo();
+  virtual void z();
+};
+
+struct X : D {
+  // CHECK-LABEL: VFTable for 'test1::D' in 'test1::X' (3 entries).
+  // CHECK-NEXT:   0 | test1::C *test1::X::foo()
+  // CHECK-NEXT:       [return adjustment (to type 'struct test1::B *'): 4 non-virtual]
+  // CHECK-NEXT:   1 | void test1::D::z()
+  // CHECK-NEXT:   2 | test1::C *test1::X::foo()
+
+  // CHECK-LABEL: Thunks for 'test1::C *test1::X::foo()' (1 entry).
+  // CHECK-NEXT:   0 | [return adjustment (to type 'struct test1::B *'): 4 non-virtual]
+
+  // CHECK-LABEL: VFTable indices for 'test1::X' (1 entry).
+  // CHECK-NEXT:   2 | test1::C *test1::X::foo()
+
+  // MANGLING-DAG: @"\01??_7X@test1@@6B@"
+
+  virtual C* foo();
+} x;
+
+void build_vftable(X *obj) { obj->foo(); }
+}
+
+namespace test2 {
+struct A {
+  virtual void g();
+  virtual void h();
+};
+
+struct B {
+  virtual void g();
+};
+
+struct C : A, B {
+  virtual void g();
+};
+
+struct D {
+  virtual B* foo();
+  virtual void z();
+};
+
+struct E : D {
+  virtual C* foo();
+};
+
+struct F : C { };
+
+struct X : E {
+  virtual F* foo();
+  // CHECK-LABEL: VFTable for 'test2::D' in 'test2::E' in 'test2::X' (4 entries).
+  // CHECK-NEXT:   0 | test2::F *test2::X::foo()
+  // CHECK-NEXT:       [return adjustment (to type 'struct test2::B *'): 4 non-virtual]
+  // CHECK-NEXT:   1 | void test2::D::z()
+  // CHECK-NEXT:   2 | test2::F *test2::X::foo()
+  // CHECK-NEXT:       [return adjustment (to type 'struct test2::C *'): 0 non-virtual]
+  // CHECK-NEXT:   3 | test2::F *test2::X::foo()
+
+  // CHECK-LABEL: Thunks for 'test2::F *test2::X::foo()' (2 entries).
+  // CHECK-NEXT:   0 | [return adjustment (to type 'struct test2::C *'): 0 non-virtual]
+  // CHECK-NEXT:   1 | [return adjustment (to type 'struct test2::B *'): 4 non-virtual]
+
+  // CHECK-LABEL: VFTable indices for 'test2::X' (1 entry).
+  // CHECK-NEXT:   3 | test2::F *test2::X::foo()
+};
+
+void build_vftable(X *obj) { obj->foo(); }
+}
+
+namespace test3 {
+struct A {
+  virtual void g();
+  virtual void h();
+};
+
+struct B {
+  virtual void g();
+};
+
+struct C : A, B {
+  virtual void g();
+};
+
+struct D {
+  virtual B* foo();
+  virtual void z();
+};
+
+struct E : D {
+  virtual C* foo();
+};
+
+struct F : A, C { };
+
+struct X : E {
+  // CHECK-LABEL: VFTable for 'test3::D' in 'test3::E' in 'test3::X' (4 entries).
+  // CHECK-NEXT:   0 | test3::F *test3::X::foo()
+  // CHECK-NEXT:       [return adjustment (to type 'struct test3::B *'): 8 non-virtual]
+  // CHECK-NEXT:   1 | void test3::D::z()
+  // CHECK-NEXT:   2 | test3::F *test3::X::foo()
+  // CHECK-NEXT:       [return adjustment (to type 'struct test3::C *'): 4 non-virtual]
+  // CHECK-NEXT:   3 | test3::F *test3::X::foo()
+
+  // CHECK-LABEL: Thunks for 'test3::F *test3::X::foo()' (2 entries).
+  // CHECK-NEXT:   0 | [return adjustment (to type 'struct test3::C *'): 4 non-virtual]
+  // CHECK-NEXT:   1 | [return adjustment (to type 'struct test3::B *'): 8 non-virtual]
+
+  // CHECK-LABEL: VFTable indices for 'test3::X' (1 entry).
+  // CHECK-NEXT:   3 | test3::F *test3::X::foo()
+
+  virtual F* foo();
+};
+
+void build_vftable(X *obj) { obj->foo(); }
+}
+
+namespace test4 {
+struct A {
+  virtual void g();
+  virtual void h();
+};
+
+struct B {
+  virtual void g();
+};
+
+struct C : A, B {
+  virtual void g();
+};
+
+struct D {
+  virtual B* foo();
+  virtual void z();
+};
+
+struct E : D {
+  virtual C* foo();
+};
+
+struct F : A, C { };
+
+struct X : D, E {
+  // CHECK-LABEL: VFTable for 'test4::D' in 'test4::X' (3 entries).
+  // CHECK-NEXT:   0 | test4::F *test4::X::foo()
+  // CHECK-NEXT:       [return adjustment (to type 'struct test4::B *'): 8 non-virtual]
+  // CHECK-NEXT:   1 | void test4::D::z()
+  // CHECK-NEXT:   2 | test4::F *test4::X::foo()
+
+  // CHECK-LABEL: Thunks for 'test4::F *test4::X::foo()' (1 entry).
+  // CHECK-NEXT:   0 | [return adjustment (to type 'struct test4::B *'): 8 non-virtual]
+
+  // CHECK-LABEL: VFTable for 'test4::D' in 'test4::E' in 'test4::X' (4 entries).
+  // CHECK-NEXT:   0 | test4::F *test4::X::foo()
+  // CHECK-NEXT:       [return adjustment (to type 'struct test4::B *'): 8 non-virtual]
+  // CHECK-NEXT:       [this adjustment: -4 non-virtual]
+  // CHECK-NEXT:   1 | void test4::D::z()
+  // CHECK-NEXT:   2 | test4::F *test4::X::foo()
+  // CHECK-NEXT:       [return adjustment (to type 'struct test4::C *'): 4 non-virtual]
+  // CHECK-NEXT:       [this adjustment: -4 non-virtual]
+  // CHECK-NEXT:   3 | test4::F *test4::X::foo()
+  // CHECK-NEXT:       [return adjustment (to type 'struct test4::F *'): 0 non-virtual]
+  // CHECK-NEXT:       [this adjustment: -4 non-virtual]
+
+  // CHECK-LABEL: Thunks for 'test4::F *test4::X::foo()' (3 entries).
+  // CHECK-NEXT:   0 | [return adjustment (to type 'struct test4::F *'): 0 non-virtual]
+  // CHECK-NEXT:       [this adjustment: -4 non-virtual]
+  // CHECK-NEXT:   1 | [return adjustment (to type 'struct test4::C *'): 4 non-virtual]
+  // CHECK-NEXT:       [this adjustment: -4 non-virtual]
+  // CHECK-NEXT:   2 | [return adjustment (to type 'struct test4::B *'): 8 non-virtual]
+  // CHECK-NEXT:       [this adjustment: -4 non-virtual]
+
+  // CHECK-LABEL: VFTable indices for 'test4::X' (1 entry).
+  // CHECK-NEXT:   2 | test4::F *test4::X::foo()
+
+  virtual F* foo();
+};
+
+void build_vftable(X *obj) { obj->foo(); }
+}
+
+namespace test5 {
+struct A {
+  virtual void g();
+  virtual void h();
+};
+
+struct B {
+  virtual void g();
+};
+
+struct C : A, B {
+  virtual void g();
+};
+
+struct D {
+  virtual B* foo();
+  virtual void z();
+};
+
+struct X : A, D {
+  // CHECK-LABEL: VFTable for 'test5::A' in 'test5::X' (2 entries).
+  // CHECK-NEXT:   0 | void test5::A::g()
+  // CHECK-NEXT:   1 | void test5::A::h()
+
+  // CHECK-LABEL: VFTable for 'test5::D' in 'test5::X' (3 entries).
+  // CHECK-NEXT:   0 | test5::C *test5::X::foo()
+  // CHECK-NEXT:       [return adjustment (to type 'struct test5::B *'): 4 non-virtual]
+  // CHECK-NEXT:   1 | void test5::D::z()
+  // CHECK-NEXT:   2 | test5::C *test5::X::foo()
+
+  // CHECK-LABEL: Thunks for 'test5::C *test5::X::foo()' (1 entry).
+  // CHECK-NEXT:   0 | [return adjustment (to type 'struct test5::B *'): 4 non-virtual]
+
+  // CHECK-LABEL: VFTable indices for 'test5::X' (1 entry).
+  // CHECK-NEXT:   via vfptr at offset 4
+  // CHECK-NEXT:   2 | test5::C *test5::X::foo()
+
+  virtual C* foo();
+};
+
+void build_vftable(X *obj) { obj->foo(); }
+}
+
+namespace test6 {
+struct A {
+  virtual void g();
+  virtual void h();
+};
+
+struct B {
+  virtual void g();
+};
+
+struct C : A, B {
+  virtual void g();
+};
+
+struct D {
+  virtual B* foo();
+  virtual void z();
+};
+
+struct E : A, D {
+  virtual C* foo();
+};
+
+struct F : A, C { };
+
+struct X : E {
+  // CHECK-LABEL: VFTable for 'test6::A' in 'test6::E' in 'test6::X' (2 entries).
+  // CHECK-NEXT:   0 | void test6::A::g()
+  // CHECK-NEXT:   1 | void test6::A::h()
+
+  // CHECK-LABEL: VFTable for 'test6::D' in 'test6::E' in 'test6::X' (4 entries).
+  // CHECK-NEXT:   0 | test6::F *test6::X::foo()
+  // CHECK-NEXT:       [return adjustment (to type 'struct test6::B *'): 8 non-virtual]
+  // CHECK-NEXT:   1 | void test6::D::z()
+  // CHECK-NEXT:   2 | test6::F *test6::X::foo()
+  // CHECK-NEXT:       [return adjustment (to type 'struct test6::C *'): 4 non-virtual]
+  // CHECK-NEXT:   3 | test6::F *test6::X::foo()
+
+  // CHECK-LABEL: Thunks for 'test6::F *test6::X::foo()' (2 entries).
+  // CHECK-NEXT:   0 | [return adjustment (to type 'struct test6::C *'): 4 non-virtual]
+  // CHECK-NEXT:   1 | [return adjustment (to type 'struct test6::B *'): 8 non-virtual]
+
+  // CHECK-LABEL: VFTable indices for 'test6::X' (1 entry).
+  // CHECK-NEXT:   -- accessible via vfptr at offset 4 --
+  // CHECK-NEXT:   3 | test6::F *test6::X::foo()
+
+  virtual F* foo();
+};
+
+void build_vftable(X *obj) { obj->foo(); }
+}
diff --git a/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp b/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp
new file mode 100644
index 0000000..957980a
--- /dev/null
+++ b/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp
@@ -0,0 +1,140 @@
+// RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -o %t.ll -fdump-vtable-layouts >%t
+// RUN: FileCheck %s < %t
+// RUN: FileCheck --check-prefix=MANGLING %s < %t.ll
+
+namespace test1 {
+struct A {
+  virtual void g();
+  // Add an extra virtual method so it's easier to check for the absence of thunks.
+  virtual void h();
+};
+
+struct B {
+  virtual void g();  // Collides with A::g if both are bases of some class.
+};
+
+// Overrides methods of two bases at the same time, thus needing thunks.
+struct X : A, B {
+  // CHECK-LABEL: VFTable for 'test1::A' in 'test1::X' (2 entries).
+  // CHECK-NEXT:   0 | void test1::X::g()
+  // CHECK-NEXT:   1 | void test1::A::h()
+
+  // CHECK-LABEL: VFTable for 'test1::B' in 'test1::X' (1 entry).
+  // CHECK-NEXT:   0 | void test1::X::g()
+  // CHECK-NEXT:       [this adjustment: -4 non-virtual]
+
+  // CHECK-LABEL: Thunks for 'void test1::X::g()' (1 entry).
+  // CHECK-NEXT:   0 | [this adjustment: -4 non-virtual]
+
+  // CHECK-LABEL: VFTable indices for 'test1::X' (1 entry).
+  // CHECK-NEXT:   0 | void test1::X::g()
+
+  // MANGLING-DAG: @"\01??_7X@test1@@6BA@1@@"
+  // MANGLING-DAG: @"\01??_7X@test1@@6BB@1@@"
+
+  virtual void g();
+} x;
+
+void build_vftable(X *obj) { obj->g(); }
+}
+
+namespace test2 {
+struct A {
+  virtual void f();
+};
+
+struct B {
+  virtual void g();
+  virtual void h();
+};
+
+struct C {
+  virtual void g();
+};
+
+struct X : A, B, C {
+  // CHECK-LABEL: VFTable for 'test2::A' in 'test2::X' (1 entry).
+  // CHECK-NEXT:   0 | void test2::A::f()
+
+  // CHECK-LABEL: VFTable for 'test2::B' in 'test2::X' (2 entries).
+  // CHECK-NEXT:   0 | void test2::X::g()
+  // CHECK-NEXT:   1 | void test2::B::h()
+
+  // CHECK-LABEL: VFTable for 'test2::C' in 'test2::X' (1 entry).
+  // CHECK-NEXT:   0 | void test2::X::g()
+  // CHECK-NEXT:       [this adjustment: -4 non-virtual]
+
+  // CHECK-LABEL: Thunks for 'void test2::X::g()' (1 entry).
+  // CHECK-NEXT:   0 | [this adjustment: -4 non-virtual]
+
+  // CHECK-LABEL: VFTable indices for 'test2::X' (1 entry).
+  // CHECK-NEXT:   via vfptr at offset 4
+  // CHECK-NEXT:   0 | void test2::X::g()
+
+  // MANGLING-DAG: @"\01??_7X@test2@@6BA@1@@"
+  // MANGLING-DAG: @"\01??_7X@test2@@6BB@1@@"
+  // MANGLING-DAG: @"\01??_7X@test2@@6BC@1@@"
+
+  virtual void g();
+} x;
+
+void build_vftable(X *obj) { obj->g(); }
+}
+
+namespace test3 {
+struct A {
+  virtual void f();
+};
+
+struct B {
+  virtual void g();
+  virtual void h();
+};
+
+struct C: A, B {
+  // Overrides only the left child's method (A::f), needs no thunks.
+  virtual void f();
+};
+
+struct D: A, B {
+  // Overrides only the right child's method (B::g),
+  // needs this adjustment but not thunks.
+  virtual void g();
+};
+
+// Overrides methods of two bases at the same time, thus needing thunks.
+struct X: C, D {
+  // CHECK-LABEL: VFTable for 'test3::A' in 'test3::C' in 'test3::X' (1 entry).
+  // CHECK-NEXT:   0 | void test3::X::f()
+
+  // CHECK-LABEL: VFTable for 'test3::B' in 'test3::C' in 'test3::X' (2 entries).
+  // CHECK-NEXT:   0 | void test3::X::g()
+  // CHECK-NEXT:   1 | void test3::B::h()
+
+  // CHECK-LABEL: VFTable for 'test3::A' in 'test3::D' in 'test3::X' (1 entry).
+  // CHECK-NEXT:   0 | void test3::X::f()
+  // CHECK-NEXT:       [this adjustment: -8 non-virtual]
+
+  // CHECK-LABEL: Thunks for 'void test3::X::f()' (1 entry).
+  // CHECK-NEXT:   0 | [this adjustment: -8 non-virtual]
+
+  // CHECK-LABEL: VFTable for 'test3::B' in 'test3::D' in 'test3::X' (2 entries).
+  // CHECK-NEXT:   0 | void test3::X::g()
+  // CHECK-NEXT:       [this adjustment: -8 non-virtual]
+  // CHECK-NEXT:   1 | void test3::B::h()
+
+  // CHECK-LABEL: Thunks for 'void test3::X::g()' (1 entry).
+  // CHECK-NEXT:   0 | [this adjustment: -8 non-virtual]
+
+  // CHECK-LABEL: VFTable indices for 'test3::X' (2 entries).
+  // CHECK-NEXT:   via vfptr at offset 0
+  // CHECK-NEXT:   0 | void test3::X::f()
+  // CHECK-NEXT:   via vfptr at offset 4
+  // CHECK-NEXT:   0 | void test3::X::g()
+
+  virtual void f();
+  virtual void g();
+} x;
+
+void build_vftable(X *obj) { obj->g(); }
+}
diff --git a/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-vdtors.cpp b/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-vdtors.cpp
new file mode 100644
index 0000000..a407766
--- /dev/null
+++ b/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-vdtors.cpp
@@ -0,0 +1,94 @@
+// RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -o %t.ll -fdump-vtable-layouts >%t
+// RUN: FileCheck %s < %t
+
+struct A {
+  virtual ~A();
+  virtual void z1();
+};
+
+struct B {
+  virtual ~B();
+};
+
+struct C : A, B {
+  // CHECK-LABEL: VFTable for 'A' in 'C' (2 entries).
+  // CHECK-NEXT:   0 | C::~C() [scalar deleting]
+  // CHECK-NEXT:   1 | void A::z1()
+
+  // CHECK-LABEL: VFTable for 'B' in 'C' (1 entry).
+  // CHECK-NEXT:   0 | C::~C() [scalar deleting]
+  // CHECK-NEXT:       [this adjustment: -4 non-virtual]
+
+  // CHECK-LABEL: Thunks for 'C::~C()' (1 entry).
+  // CHECK-NEXT:   0 | [this adjustment: -4 non-virtual]
+
+  // CHECK-LABEL: VFTable indices for 'C' (1 entry).
+  // CHECK-NEXT:   0 | C::~C() [scalar deleting]
+  virtual ~C();
+};
+
+void build_vftable(C *obj) { delete obj; }
+
+struct D {
+  // No virtual destructor here!
+  virtual void z4();
+};
+
+struct E : D, B {
+  // Implicit virtual dtor here!
+
+  // CHECK-LABEL: VFTable for 'D' in 'E' (1 entry).
+  // CHECK-NEXT:   0 | void D::z4()
+
+  // CHECK-LABEL: VFTable for 'B' in 'E' (1 entry).
+  // CHECK-NEXT:   0 | E::~E() [scalar deleting]
+  // CHECK-NEXT:       [this adjustment: -4 non-virtual]
+
+  // CHECK-LABEL: Thunks for 'E::~E()' (1 entry).
+  // CHECK-NEXT:   0 | [this adjustment: -4 non-virtual]
+
+  // CHECK-LABEL: VFTable indices for 'E' (1 entry).
+  // CHECK-NEXT:   -- accessible via vfptr at offset 4 --
+  // CHECK-NEXT:   0 | E::~E() [scalar deleting]
+};
+
+void build_vftable(E *obj) { delete obj; }
+
+struct F : D, B {
+  // Implicit virtual dtor here!
+
+  // CHECK-LABEL: VFTable for 'D' in 'F' (1 entry).
+  // CHECK-NEXT:   0 | void D::z4()
+
+  // CHECK-LABEL: VFTable for 'B' in 'F' (1 entry).
+  // CHECK-NEXT:   0 | F::~F() [scalar deleting]
+  // CHECK-NEXT:       [this adjustment: -4 non-virtual]
+
+  // CHECK-LABEL: Thunks for 'F::~F()' (1 entry).
+  // CHECK-NEXT:   0 | [this adjustment: -4 non-virtual]
+
+  // CHECK-LABEL: VFTable indices for 'F' (1 entry).
+  // CHECK-NEXT:   -- accessible via vfptr at offset 4 --
+  // CHECK-NEXT:   0 | F::~F() [scalar deleting]
+};
+
+void build_vftable(F *obj) { delete obj; }
+
+struct G : F {
+  // CHECK-LABEL: VFTable for 'D' in 'F' in 'G' (1 entry).
+  // CHECK-NEXT:   0 | void D::z4()
+
+  // CHECK-LABEL: VFTable for 'B' in 'F' in 'G' (1 entry).
+  // CHECK-NEXT:   0 | G::~G() [scalar deleting]
+  // CHECK-NEXT:       [this adjustment: -4 non-virtual]
+
+  // CHECK-LABEL: Thunks for 'G::~G()' (1 entry).
+  // CHECK-NEXT:   0 | [this adjustment: -4 non-virtual]
+
+  // CHECK-LABEL: VFTable indices for 'G' (1 entry).
+  // CHECK-NEXT:   -- accessible via vfptr at offset 4 --
+  // CHECK-NEXT:   0 | G::~G() [scalar deleting]
+  virtual ~G();
+};
+
+void build_vftable(G *obj) { delete obj; }
diff --git a/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance.cpp b/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance.cpp
deleted file mode 100644
index d93dee1..0000000
--- a/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance.cpp
+++ /dev/null
@@ -1,579 +0,0 @@
-// RUN: %clang_cc1 %s -fno-rtti -cxx-abi microsoft -triple=i386-pc-win32 -emit-llvm -o %t.ll -fdump-vtable-layouts >%t
-
-// RUN: FileCheck --check-prefix=NO-THUNKS-Test1 %s < %t
-// RUN: FileCheck --check-prefix=NO-THUNKS-Test2 %s < %t
-// RUN: FileCheck --check-prefix=NO-THUNKS-Test3 %s < %t
-// RUN: FileCheck --check-prefix=NO-THUNKS-Test4 %s < %t
-// RUN: FileCheck --check-prefix=NO-THUNKS-Test5 %s < %t
-// RUN: FileCheck --check-prefix=NO-THUNKS-Test6 %s < %t
-// RUN: FileCheck --check-prefix=NO-THUNKS-Test7 %s < %t
-// RUN: FileCheck --check-prefix=NO-THUNKS-Test8 %s < %t
-// RUN: FileCheck --check-prefix=NO-THUNKS-Test9 %s < %t
-// RUN: FileCheck --check-prefix=PURE-VIRTUAL-Test1 %s < %t
-// RUN: FileCheck --check-prefix=THIS-THUNKS-Test1 %s < %t
-// RUN: FileCheck --check-prefix=THIS-THUNKS-Test2 %s < %t
-// RUN: FileCheck --check-prefix=THIS-THUNKS-Test3 %s < %t
-// RUN: FileCheck --check-prefix=VDTOR-THUNKS-Test3 %s < %t
-// RUN: FileCheck --check-prefix=VDTOR-THUNKS-Test5 %s < %t
-// RUN: FileCheck --check-prefix=VDTOR-THUNKS-Test6 %s < %t
-// RUN: FileCheck --check-prefix=VDTOR-THUNKS-Test7 %s < %t
-// RUN: FileCheck --check-prefix=RET-THUNKS-Test1 %s < %t
-// RUN: FileCheck --check-prefix=RET-THUNKS-Test2 %s < %t
-// RUN: FileCheck --check-prefix=RET-THUNKS-Test3 %s < %t
-// RUN: FileCheck --check-prefix=RET-THUNKS-Test4 %s < %t
-// RUN: FileCheck --check-prefix=RET-THUNKS-Test5 %s < %t
-// RUN: FileCheck --check-prefix=RET-THUNKS-Test6 %s < %t
-
-// RUN: FileCheck --check-prefix=MANGLING %s < %t.ll
-
-struct Empty {
-  // Doesn't have a vftable!
-};
-
-struct A {
-  virtual void f();
-};
-
-struct B {
-  virtual void g();
-  // Add an extra virtual method so it's easier to check for the absence of thunks.
-  virtual void h();
-};
-
-struct C {
-  virtual void g();  // Might "collide" with B::g if both are bases of some class.
-};
-
-
-namespace no_thunks {
-
-struct Test1: A, B {
-  // NO-THUNKS-Test1: VFTable for 'A' in 'no_thunks::Test1' (1 entries)
-  // NO-THUNKS-Test1-NEXT: 0 | void no_thunks::Test1::f()
-
-  // NO-THUNKS-Test1: VFTable for 'B' in 'no_thunks::Test1' (2 entries)
-  // NO-THUNKS-Test1-NEXT: 0 | void B::g()
-  // NO-THUNKS-Test1-NEXT: 1 | void B::h()
-
-  // NO-THUNKS-Test1: VFTable indices for 'no_thunks::Test1' (1 entries)
-  // NO-THUNKS-Test1-NEXT: 0 | void no_thunks::Test1::f()
-
-  // MANGLING-DAG: @"\01??_7Test1@no_thunks@@6BA@@@"
-  // MANGLING-DAG: @"\01??_7Test1@no_thunks@@6BB@@@"
-
-  // Overrides only the left child's method (A::f), needs no thunks.
-  virtual void f();
-};
-
-Test1 t1;
-
-struct Test2: A, B {
-  // NO-THUNKS-Test2: VFTable for 'A' in 'no_thunks::Test2' (1 entries)
-  // NO-THUNKS-Test2-NEXT: 0 | void A::f()
-
-  // NO-THUNKS-Test2: VFTable for 'B' in 'no_thunks::Test2' (2 entries)
-  // NO-THUNKS-Test2-NEXT: 0 | void no_thunks::Test2::g()
-  // NO-THUNKS-Test2-NEXT: 1 | void B::h()
-
-  // NO-THUNKS-Test2: VFTable indices for 'no_thunks::Test2' (1 entries).
-  // NO-THUNKS-Test2-NEXT: via vfptr at offset 4
-  // NO-THUNKS-Test2-NEXT: 0 | void no_thunks::Test2::g()
-
-  // Overrides only the right child's method (B::g), needs this adjustment but
-  // not thunks.
-  virtual void g();
-};
-
-Test2 t2;
-
-struct Test3: A, B {
-  // NO-THUNKS-Test3: VFTable for 'A' in 'no_thunks::Test3' (2 entries)
-  // NO-THUNKS-Test3-NEXT: 0 | void A::f()
-  // NO-THUNKS-Test3-NEXT: 1 | void no_thunks::Test3::i()
-
-  // NO-THUNKS-Test3: VFTable for 'B' in 'no_thunks::Test3' (2 entries)
-  // NO-THUNKS-Test3-NEXT: 0 | void B::g()
-  // NO-THUNKS-Test3-NEXT: 1 | void B::h()
-
-  // NO-THUNKS-Test3: VFTable indices for 'no_thunks::Test3' (1 entries).
-  // NO-THUNKS-Test3-NEXT: 1 | void no_thunks::Test3::i()
-
-  // Only adds a new method.
-  virtual void i();
-};
-
-Test3 t3;
-
-// Only the right base has a vftable, so it's laid out before the left one!
-struct Test4 : Empty, A {
-  // NO-THUNKS-Test4: VFTable for 'A' in 'no_thunks::Test4' (1 entries)
-  // NO-THUNKS-Test4-NEXT: 0 | void no_thunks::Test4::f()
-
-  // NO-THUNKS-Test4: VFTable indices for 'no_thunks::Test4' (1 entries).
-  // NO-THUNKS-Test4-NEXT: 0 | void no_thunks::Test4::f()
-
-  // MANGLING-DAG: @"\01??_7Test4@no_thunks@@6B@"
-
-  virtual void f();
-};
-
-Test4 t4;
-
-// 2-level structure with repeating subobject types, but no thunks needed.
-struct Test5: Test1, Test2 {
-  // NO-THUNKS-Test5: VFTable for 'A' in 'no_thunks::Test1' in 'no_thunks::Test5' (2 entries)
-  // NO-THUNKS-Test5-NEXT: 0 | void no_thunks::Test1::f()
-  // NO-THUNKS-Test5-NEXT: 1 | void no_thunks::Test5::z()
-
-  // NO-THUNKS-Test5: VFTable for 'B' in 'no_thunks::Test1' in 'no_thunks::Test5' (2 entries)
-  // NO-THUNKS-Test5-NEXT: 0 | void B::g()
-  // NO-THUNKS-Test5-NEXT: 1 | void B::h()
-
-  // NO-THUNKS-Test5: VFTable for 'A' in 'no_thunks::Test2' in 'no_thunks::Test5' (1 entries)
-  // NO-THUNKS-Test5-NEXT: 0 | void A::f()
-
-  // NO-THUNKS-Test5: VFTable for 'B' in 'no_thunks::Test2' in 'no_thunks::Test5' (2 entries)
-  // NO-THUNKS-Test5-NEXT: 0 | void no_thunks::Test2::g()
-  // NO-THUNKS-Test5-NEXT: 1 | void B::h()
-
-  // NO-THUNKS-Test5: VFTable indices for 'no_thunks::Test5' (1 entries).
-  // NO-THUNKS-Test5-NEXT: 1 | void no_thunks::Test5::z()
-
-  // MANGLING-DAG: @"\01??_7Test5@no_thunks@@6BA@@Test1@1@@"
-  // MANGLING-DAG: @"\01??_7Test5@no_thunks@@6BA@@Test2@1@@"
-  // MANGLING-DAG: @"\01??_7Test5@no_thunks@@6BB@@Test1@1@@"
-  // MANGLING-DAG: @"\01??_7Test5@no_thunks@@6BB@@Test2@1@@"
-
-  virtual void z();
-};
-
-Test5 t5;
-
-struct Test6: Test1 {
-  // NO-THUNKS-Test6: VFTable for 'A' in 'no_thunks::Test1' in 'no_thunks::Test6' (1 entries).
-  // NO-THUNKS-Test6-NEXT: 0 | void no_thunks::Test6::f()
-
-  // NO-THUNKS-Test6: VFTable for 'B' in 'no_thunks::Test1' in 'no_thunks::Test6' (2 entries).
-  // NO-THUNKS-Test6-NEXT: 0 | void B::g()
-  // NO-THUNKS-Test6-NEXT: 1 | void B::h()
-
-  // NO-THUNKS-Test6: VFTable indices for 'no_thunks::Test6' (1 entries).
-  // NO-THUNKS-Test6-NEXT: 0 | void no_thunks::Test6::f()
-
-  // MANGLING-DAG: @"\01??_7Test6@no_thunks@@6BA@@@"
-  // MANGLING-DAG: @"\01??_7Test6@no_thunks@@6BB@@@"
-
-  // Overrides both no_thunks::Test1::f and A::f.
-  virtual void f();
-};
-
-Test6 t6;
-
-struct Test7: Test2 {
-  // NO-THUNKS-Test7: VFTable for 'A' in 'no_thunks::Test2' in 'no_thunks::Test7' (1 entries).
-  // NO-THUNKS-Test7-NEXT: 0 | void A::f()
-
-  // NO-THUNKS-Test7: VFTable for 'B' in 'no_thunks::Test2' in 'no_thunks::Test7' (2 entries).
-  // NO-THUNKS-Test7-NEXT: 0 | void no_thunks::Test7::g()
-  // NO-THUNKS-Test7-NEXT: 1 | void B::h()
-
-  // NO-THUNKS-Test7: VFTable indices for 'no_thunks::Test7' (1 entries).
-  // NO-THUNKS-Test7-NEXT: via vfptr at offset 4
-  // NO-THUNKS-Test7-NEXT: 0 | void no_thunks::Test7::g()
-
-  // Overrides both no_thunks::Test2::g and B::g.
-  virtual void g();
-};
-
-Test7 t7;
-
-struct Test8: Test3 {
-  // NO-THUNKS-Test8: VFTable for 'A' in 'no_thunks::Test3' in 'no_thunks::Test8' (2 entries).
-  // NO-THUNKS-Test8-NEXT: 0 | void A::f()
-  // NO-THUNKS-Test8-NEXT: 1 | void no_thunks::Test3::i()
-
-  // NO-THUNKS-Test8: VFTable for 'B' in 'no_thunks::Test3' in 'no_thunks::Test8' (2 entries).
-  // NO-THUNKS-Test8-NEXT: 0 | void no_thunks::Test8::g()
-  // NO-THUNKS-Test8-NEXT: 1 | void B::h()
-
-  // NO-THUNKS-Test8: VFTable indices for 'no_thunks::Test8' (1 entries).
-  // NO-THUNKS-Test8-NEXT: via vfptr at offset 4
-  // NO-THUNKS-Test8-NEXT: 0 | void no_thunks::Test8::g()
-
-  // Overrides grandparent's B::g.
-  virtual void g();
-};
-
-Test8 t8;
-
-struct D : A {
-  virtual void g();
-};
-
-// Repeating subobject.
-struct Test9: A, D {
-  // NO-THUNKS-Test9: VFTable for 'A' in 'no_thunks::Test9' (2 entries).
-  // NO-THUNKS-Test9-NEXT: 0 | void A::f()
-  // NO-THUNKS-Test9-NEXT: 1 | void no_thunks::Test9::h()
-
-  // NO-THUNKS-Test9: VFTable for 'A' in 'no_thunks::D' in 'no_thunks::Test9' (2 entries).
-  // NO-THUNKS-Test9-NEXT: 0 | void A::f()
-  // NO-THUNKS-Test9-NEXT: 1 | void no_thunks::D::g()
-
-  // NO-THUNKS-Test9: VFTable indices for 'no_thunks::Test9' (1 entries).
-  // NO-THUNKS-Test9-NEXT: 1 | void no_thunks::Test9::h()
-
-  // MANGLING-DAG: @"\01??_7Test9@no_thunks@@6BA@@@"
-  // MANGLING-DAG: @"\01??_7Test9@no_thunks@@6BD@1@@"
-
-  virtual void h();
-};
-
-Test9 t9;
-}
-
-namespace pure_virtual {
-struct D {
-  virtual void g() = 0;
-  virtual void h();
-};
-
-
-struct Test1: A, D {
-  // PURE-VIRTUAL-Test1: VFTable for 'A' in 'pure_virtual::Test1' (1 entries)
-  // PURE-VIRTUAL-Test1-NEXT: 0 | void A::f()
-
-  // PURE-VIRTUAL-Test1: VFTable for 'pure_virtual::D' in 'pure_virtual::Test1' (2 entries)
-  // PURE-VIRTUAL-Test1-NEXT: 0 | void pure_virtual::Test1::g()
-  // PURE-VIRTUAL-Test1-NEXT: 1 | void pure_virtual::D::h()
-
-  // PURE-VIRTUAL-Test1: VFTable indices for 'pure_virtual::Test1' (1 entries).
-  // PURE-VIRTUAL-Test1-NEXT: via vfptr at offset 4
-  // PURE-VIRTUAL-Test1-NEXT: 0 | void pure_virtual::Test1::g()
-
-  // MANGLING-DAG: @"\01??_7Test1@pure_virtual@@6BA@@@"
-  // MANGLING-DAG: @"\01??_7Test1@pure_virtual@@6BD@1@@"
-
-  // Overrides only the right child's method (pure_virtual::D::g), needs this adjustment but
-  // not thunks.
-  virtual void g();
-};
-
-Test1 t1;
-}
-
-namespace this_adjustment {
-
-// Overrides methods of two bases at the same time, thus needing thunks.
-struct Test1 : B, C {
-  // THIS-THUNKS-Test1: VFTable for 'B' in 'this_adjustment::Test1' (2 entries).
-  // THIS-THUNKS-Test1-NEXT: 0 | void this_adjustment::Test1::g()
-  // THIS-THUNKS-Test1-NEXT: 1 | void B::h()
-
-  // THIS-THUNKS-Test1: VFTable for 'C' in 'this_adjustment::Test1' (1 entries).
-  // THIS-THUNKS-Test1-NEXT: 0 | void this_adjustment::Test1::g()
-  // THIS-THUNKS-Test1-NEXT:     [this adjustment: -4 non-virtual]
-
-  // THIS-THUNKS-Test1: Thunks for 'void this_adjustment::Test1::g()' (1 entry).
-  // THIS-THUNKS-Test1-NEXT: 0 | [this adjustment: -4 non-virtual]
-
-  // THIS-THUNKS-Test1: VFTable indices for 'this_adjustment::Test1' (1 entries).
-  // THIS-THUNKS-Test1-NEXT: 0 | void this_adjustment::Test1::g()
-
-  // MANGLING-DAG: @"\01??_7Test1@this_adjustment@@6BB@@@"
-  // MANGLING-DAG: @"\01??_7Test1@this_adjustment@@6BC@@@"
-
-  virtual void g();
-};
-
-Test1 t1;
-
-struct Test2 : A, B, C {
-  // THIS-THUNKS-Test2: VFTable for 'A' in 'this_adjustment::Test2' (1 entries).
-  // THIS-THUNKS-Test2-NEXT: 0 | void A::f()
-
-  // THIS-THUNKS-Test2: VFTable for 'B' in 'this_adjustment::Test2' (2 entries).
-  // THIS-THUNKS-Test2-NEXT: 0 | void this_adjustment::Test2::g()
-  // THIS-THUNKS-Test2-NEXT: 1 | void B::h()
-
-  // THIS-THUNKS-Test2: VFTable for 'C' in 'this_adjustment::Test2' (1 entries).
-  // THIS-THUNKS-Test2-NEXT: 0 | void this_adjustment::Test2::g()
-  // THIS-THUNKS-Test2-NEXT:     [this adjustment: -4 non-virtual]
-
-  // THIS-THUNKS-Test2: Thunks for 'void this_adjustment::Test2::g()' (1 entry).
-  // THIS-THUNKS-Test2-NEXT: 0 | [this adjustment: -4 non-virtual]
-
-  // THIS-THUNKS-Test2: VFTable indices for 'this_adjustment::Test2' (1 entries).
-  // THIS-THUNKS-Test2-NEXT: via vfptr at offset 4
-  // THIS-THUNKS-Test2-NEXT: 0 | void this_adjustment::Test2::g()
-
-  // MANGLING-DAG: @"\01??_7Test2@this_adjustment@@6BA@@@"
-  // MANGLING-DAG: @"\01??_7Test2@this_adjustment@@6BB@@@"
-  // MANGLING-DAG: @"\01??_7Test2@this_adjustment@@6BC@@@"
-
-  virtual void g();
-};
-
-Test2 t2;
-
-// Overrides methods of two bases at the same time, thus needing thunks.
-struct Test3: no_thunks::Test1, no_thunks::Test2 {
-  // THIS-THUNKS-Test3: VFTable for 'A' in 'no_thunks::Test1' in 'this_adjustment::Test3' (1 entries).
-  // THIS-THUNKS-Test3-NEXT: 0 | void this_adjustment::Test3::f()
-
-  // THIS-THUNKS-Test3: VFTable for 'B' in 'no_thunks::Test1' in 'this_adjustment::Test3' (2 entries).
-  // THIS-THUNKS-Test3-NEXT: 0 | void this_adjustment::Test3::g()
-  // THIS-THUNKS-Test3-NEXT: 1 | void B::h()
-
-  // THIS-THUNKS-Test3: VFTable for 'A' in 'no_thunks::Test2' in 'this_adjustment::Test3' (1 entries).
-  // THIS-THUNKS-Test3-NEXT: 0 | void this_adjustment::Test3::f()
-  // THIS-THUNKS-Test3-NEXT:     [this adjustment: -8 non-virtual]
-
-  // THIS-THUNKS-Test3: Thunks for 'void this_adjustment::Test3::f()' (1 entry).
-  // THIS-THUNKS-Test3-NEXT: 0 | [this adjustment: -8 non-virtual]
-
-  // THIS-THUNKS-Test3: VFTable for 'B' in 'no_thunks::Test2' in 'this_adjustment::Test3' (2 entries).
-  // THIS-THUNKS-Test3-NEXT: 0 | void this_adjustment::Test3::g()
-  // THIS-THUNKS-Test3-NEXT:     [this adjustment: -8 non-virtual]
-  // THIS-THUNKS-Test3-NEXT: 1 | void B::h()
-
-  // THIS-THUNKS-Test3: Thunks for 'void this_adjustment::Test3::g()' (1 entry).
-  // THIS-THUNKS-Test3-NEXT: 0 | [this adjustment: -8 non-virtual]
-
-  // THIS-THUNKS-Test3: VFTable indices for 'this_adjustment::Test3' (2 entries).
-  // THIS-THUNKS-Test3-NEXT: via vfptr at offset 0
-  // THIS-THUNKS-Test3-NEXT: 0 | void this_adjustment::Test3::f()
-  // THIS-THUNKS-Test3-NEXT: via vfptr at offset 4
-  // THIS-THUNKS-Test3-NEXT: 0 | void this_adjustment::Test3::g()
-
-  virtual void f();
-  virtual void g();
-};
-
-Test3 t3;
-}
-
-namespace vdtor {
-struct Test1 {
-  virtual ~Test1();
-  virtual void z1();
-};
-
-struct Test2 {
-  virtual ~Test2();
-};
-
-struct Test3 : Test1, Test2 {
-  // VDTOR-THUNKS-Test3: VFTable for 'vdtor::Test1' in 'vdtor::Test3' (2 entries).
-  // VDTOR-THUNKS-Test3-NEXT: 0 | vdtor::Test3::~Test3() [scalar deleting]
-  // VDTOR-THUNKS-Test3-NEXT: 1 | void vdtor::Test1::z1()
-
-  // VDTOR-THUNKS-Test3: VFTable for 'vdtor::Test2' in 'vdtor::Test3' (1 entries).
-  // VDTOR-THUNKS-Test3-NEXT: 0 | vdtor::Test3::~Test3() [scalar deleting]
-  // VDTOR-THUNKS-Test3-NEXT:     [this adjustment: -4 non-virtual]
-
-  // VDTOR-THUNKS-Test3: Thunks for 'vdtor::Test3::~Test3()' (1 entry).
-  // VDTOR-THUNKS-Test3-NEXT: 0 | [this adjustment: -4 non-virtual]
-
-  // VDTOR-THUNKS-Test3: VFTable indices for 'vdtor::Test3' (1 entries).
-  // VDTOR-THUNKS-Test3-NEXT: 0 | vdtor::Test3::~Test3() [scalar deleting]
-  virtual ~Test3();
-};
-
-Test3 t3;
-
-struct Test4 {
-  // No virtual destructor here!
-  virtual void z4();
-};
-
-struct Test5 : Test4, Test2 {
-  // Implicit virtual dtor here!
-
-  // VDTOR-THUNKS-Test5: VFTable for 'vdtor::Test4' in 'vdtor::Test5' (1 entries).
-  // VDTOR-THUNKS-Test5-NEXT: 0 | void vdtor::Test4::z4()
-
-  // VDTOR-THUNKS-Test5: VFTable for 'vdtor::Test2' in 'vdtor::Test5' (1 entries).
-  // VDTOR-THUNKS-Test5-NEXT: 0 | vdtor::Test5::~Test5() [scalar deleting]
-  // VDTOR-THUNKS-Test5-NEXT:     [this adjustment: -4 non-virtual]
-
-  // VDTOR-THUNKS-Test5: Thunks for 'vdtor::Test5::~Test5()' (1 entry).
-  // VDTOR-THUNKS-Test5-NEXT: 0 | [this adjustment: -4 non-virtual]
-
-  // VDTOR-THUNKS-Test5: VFTable indices for 'vdtor::Test5' (1 entries).
-  // VDTOR-THUNKS-Test5-NEXT: -- accessible via vfptr at offset 4 --
-  // VDTOR-THUNKS-Test5-NEXT: 0 | vdtor::Test5::~Test5() [scalar deleting]
-};
-
-Test5 t5;
-
-struct Test6 : Test4, Test2 {
-  // Implicit virtual dtor here!
-
-  // VDTOR-THUNKS-Test6: VFTable for 'vdtor::Test4' in 'vdtor::Test6' (1 entries).
-  // VDTOR-THUNKS-Test6-NEXT: 0 | void vdtor::Test4::z4()
-
-  // VDTOR-THUNKS-Test6: VFTable for 'vdtor::Test2' in 'vdtor::Test6' (1 entries).
-  // VDTOR-THUNKS-Test6-NEXT: 0 | vdtor::Test6::~Test6() [scalar deleting]
-  // VDTOR-THUNKS-Test6-NEXT:     [this adjustment: -4 non-virtual]
-
-  // VDTOR-THUNKS-Test6: Thunks for 'vdtor::Test6::~Test6()' (1 entry).
-  // VDTOR-THUNKS-Test6-NEXT: 0 | [this adjustment: -4 non-virtual]
-
-  // VDTOR-THUNKS-Test6: VFTable indices for 'vdtor::Test6' (1 entries).
-  // VDTOR-THUNKS-Test6-NEXT: -- accessible via vfptr at offset 4 --
-  // VDTOR-THUNKS-Test6-NEXT: 0 | vdtor::Test6::~Test6() [scalar deleting]
-};
-
-Test6 t6;
-
-struct Test7 : Test5 {
-  // VDTOR-THUNKS-Test7: VFTable for 'vdtor::Test4' in 'vdtor::Test5' in 'vdtor::Test7' (1 entries).
-  // VDTOR-THUNKS-Test7-NEXT: 0 | void vdtor::Test4::z4()
-
-  // VDTOR-THUNKS-Test7: VFTable for 'vdtor::Test2' in 'vdtor::Test5' in 'vdtor::Test7' (1 entries).
-  // VDTOR-THUNKS-Test7-NEXT: 0 | vdtor::Test7::~Test7() [scalar deleting]
-  // VDTOR-THUNKS-Test7-NEXT:     [this adjustment: -4 non-virtual]
-
-  // VDTOR-THUNKS-Test7: Thunks for 'vdtor::Test7::~Test7()' (1 entry).
-  // VDTOR-THUNKS-Test7-NEXT: 0 | [this adjustment: -4 non-virtual]
-
-  // VDTOR-THUNKS-Test7: VFTable indices for 'vdtor::Test7' (1 entries).
-  // VDTOR-THUNKS-Test7-NEXT: -- accessible via vfptr at offset 4 --
-  // VDTOR-THUNKS-Test7-NEXT: 0 | vdtor::Test7::~Test7() [scalar deleting]
-  virtual ~Test7();
-};
-
-Test7 t7;
-
-}
-
-namespace return_adjustment {
-
-struct Ret1 {
-  virtual C* foo();
-  virtual void z();
-};
-
-struct Test1 : Ret1 {
-  // RET-THUNKS-Test1: VFTable for 'return_adjustment::Ret1' in 'return_adjustment::Test1' (3 entries).
-  // RET-THUNKS-Test1-NEXT: 0 | this_adjustment::Test1 *return_adjustment::Test1::foo()
-  // RET-THUNKS-Test1-NEXT:     [return adjustment: 4 non-virtual]
-  // RET-THUNKS-Test1-NEXT: 1 | void return_adjustment::Ret1::z()
-  // RET-THUNKS-Test1-NEXT: 2 | this_adjustment::Test1 *return_adjustment::Test1::foo()
-
-  // RET-THUNKS-Test1: VFTable indices for 'return_adjustment::Test1' (1 entries).
-  // RET-THUNKS-Test1-NEXT: 2 | this_adjustment::Test1 *return_adjustment::Test1::foo()
-
-  // MANGLING-DAG: @"\01??_7Test1@return_adjustment@@6B@"
-
-  virtual this_adjustment::Test1* foo();
-};
-
-Test1 t1;
-
-struct Ret2 : B, this_adjustment::Test1 { };
-
-struct Test2 : Test1 {
-  // RET-THUNKS-Test2: VFTable for 'return_adjustment::Ret1' in 'return_adjustment::Test1' in 'return_adjustment::Test2' (4 entries).
-  // RET-THUNKS-Test2-NEXT: 0 | return_adjustment::Ret2 *return_adjustment::Test2::foo()
-  // RET-THUNKS-Test2-NEXT:     [return adjustment: 8 non-virtual]
-  // RET-THUNKS-Test2-NEXT: 1 | void return_adjustment::Ret1::z()
-  // RET-THUNKS-Test2-NEXT: 2 | return_adjustment::Ret2 *return_adjustment::Test2::foo()
-  // RET-THUNKS-Test2-NEXT:     [return adjustment: 4 non-virtual]
-  // RET-THUNKS-Test2-NEXT: 3 | return_adjustment::Ret2 *return_adjustment::Test2::foo()
-
-  // RET-THUNKS-Test2: VFTable indices for 'return_adjustment::Test2' (1 entries).
-  // RET-THUNKS-Test2-NEXT: 3 | return_adjustment::Ret2 *return_adjustment::Test2::foo()
-
-  virtual Ret2* foo();
-};
-
-Test2 t2;
-
-struct Test3: B, Ret1 {
-  // RET-THUNKS-Test3: VFTable for 'B' in 'return_adjustment::Test3' (2 entries).
-  // RET-THUNKS-Test3-NEXT: 0 | void B::g()
-  // RET-THUNKS-Test3-NEXT: 1 | void B::h()
-
-  // RET-THUNKS-Test3: VFTable for 'return_adjustment::Ret1' in 'return_adjustment::Test3' (3 entries).
-  // RET-THUNKS-Test3-NEXT: 0 | this_adjustment::Test1 *return_adjustment::Test3::foo()
-  // RET-THUNKS-Test3-NEXT:     [return adjustment: 4 non-virtual]
-  // RET-THUNKS-Test3-NEXT: 1 | void return_adjustment::Ret1::z()
-  // RET-THUNKS-Test3-NEXT: 2 | this_adjustment::Test1 *return_adjustment::Test3::foo()
-
-  // RET-THUNKS-Test3: VFTable indices for 'return_adjustment::Test3' (1 entries).
-  // RET-THUNKS-Test3-NEXT: via vfptr at offset 4
-  // RET-THUNKS-Test3-NEXT: 2 | this_adjustment::Test1 *return_adjustment::Test3::foo()
-
-  virtual this_adjustment::Test1* foo();
-};
-
-Test3 t3;
-
-struct Test4 : Test3 {
-  // RET-THUNKS-Test4: VFTable for 'B' in 'return_adjustment::Test3' in 'return_adjustment::Test4' (2 entries).
-  // RET-THUNKS-Test4-NEXT: 0 | void B::g()
-  // RET-THUNKS-Test4-NEXT: 1 | void B::h()
-
-  // RET-THUNKS-Test4: VFTable for 'return_adjustment::Ret1' in 'return_adjustment::Test3' in 'return_adjustment::Test4' (4 entries).
-  // RET-THUNKS-Test4-NEXT: 0 | return_adjustment::Ret2 *return_adjustment::Test4::foo()
-  // RET-THUNKS-Test4-NEXT:     [return adjustment: 8 non-virtual]
-  // RET-THUNKS-Test4-NEXT: 1 | void return_adjustment::Ret1::z()
-  // RET-THUNKS-Test4-NEXT: 2 | return_adjustment::Ret2 *return_adjustment::Test4::foo()
-  // RET-THUNKS-Test4-NEXT:     [return adjustment: 4 non-virtual]
-  // RET-THUNKS-Test4-NEXT: 3 | return_adjustment::Ret2 *return_adjustment::Test4::foo()
-
-  // RET-THUNKS-Test4: VFTable indices for 'return_adjustment::Test4' (1 entries).
-  // RET-THUNKS-Test4-NEXT: -- accessible via vfptr at offset 4 --
-  // RET-THUNKS-Test4-NEXT:   3 | return_adjustment::Ret2 *return_adjustment::Test4::foo()
-
-  virtual Ret2* foo();
-};
-
-Test4 t4;
-
-struct Test5 : Ret1, Test1 {
-  // RET-THUNKS-Test5: VFTable for 'return_adjustment::Ret1' in 'return_adjustment::Test5' (3 entries).
-  // RET-THUNKS-Test5-NEXT: 0 | return_adjustment::Ret2 *return_adjustment::Test5::foo()
-  // RET-THUNKS-Test5-NEXT:     [return adjustment: 8 non-virtual]
-  // RET-THUNKS-Test5-NEXT: 1 | void return_adjustment::Ret1::z()
-  // RET-THUNKS-Test5-NEXT: 2 | return_adjustment::Ret2 *return_adjustment::Test5::foo()
-
-  // RET-THUNKS-Test5: VFTable for 'return_adjustment::Ret1' in  'return_adjustment::Test1' in 'return_adjustment::Test5' (4 entries).
-  // RET-THUNKS-Test5-NEXT: 0 | return_adjustment::Ret2 *return_adjustment::Test5::foo()
-  // RET-THUNKS-Test5-NEXT:     [return adjustment: 8 non-virtual]
-  // RET-THUNKS-Test5-NEXT:     [this adjustment: -4 non-virtual]
-  // RET-THUNKS-Test5-NEXT: 1 | void return_adjustment::Ret1::z()
-  // RET-THUNKS-Test5-NEXT: 2 | return_adjustment::Ret2 *return_adjustment::Test5::foo()
-  // RET-THUNKS-Test5-NEXT:     [return adjustment: 4 non-virtual]
-  // RET-THUNKS-Test5-NEXT:     [this adjustment: -4 non-virtual]
-  // RET-THUNKS-Test5-NEXT: 3 | return_adjustment::Ret2 *return_adjustment::Test5::foo()
-  // RET-THUNKS-Test5-NEXT:     [this adjustment: -4 non-virtual]
-
-  // RET-THUNKS-Test5: VFTable indices for 'return_adjustment::Test5' (1 entries).
-  // RET-THUNKS-Test5-NEXT: 2 | return_adjustment::Ret2 *return_adjustment::Test5::foo()
-
-  virtual Ret2* foo();
-};
-
-Test5 t5;
-
-struct Ret3 : this_adjustment::Test1 { };
-
-struct Test6 : Test1 {
-  virtual Ret3* foo();
-  // RET-THUNKS-Test6: VFTable for 'return_adjustment::Ret1' in 'return_adjustment::Test1' in 'return_adjustment::Test6' (4 entries).
-  // RET-THUNKS-Test6-NEXT: 0 | return_adjustment::Ret3 *return_adjustment::Test6::foo()
-  // RET-THUNKS-Test6-NEXT:     [return adjustment: 4 non-virtual]
-  // RET-THUNKS-Test6-NEXT: 1 | void return_adjustment::Ret1::z()
-  // RET-THUNKS-Test6-NEXT: 2 | return_adjustment::Ret3 *return_adjustment::Test6::foo()
-  // RET-THUNKS-Test6-NEXT: 3 | return_adjustment::Ret3 *return_adjustment::Test6::foo()
-
-  // RET-THUNKS-Test6: VFTable indices for 'return_adjustment::Test6' (1 entries).
-  // RET-THUNKS-Test6-NEXT: 3 | return_adjustment::Ret3 *return_adjustment::Test6::foo()
-};
-
-Test6 t6;
-
-}
diff --git a/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp b/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp
new file mode 100644
index 0000000..a4a2110
--- /dev/null
+++ b/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp
@@ -0,0 +1,106 @@
+// RUN: %clang_cc1 -fno-rtti %s -emit-llvm -o %t -triple=i386-pc-win32 -fdump-vtable-layouts 2>&1 | FileCheck --check-prefix=VFTABLES %s
+// RUN: FileCheck --check-prefix=GLOBALS %s < %t
+// RUN: FileCheck --check-prefix=CODEGEN %s < %t
+
+namespace test1 {
+
+// Some covariant types.
+struct A { int a; };
+struct B { int b; };
+struct C : A, B { int c; };
+struct D : C { int d; };
+struct E : D { int e; };
+
+// One base class and two overrides, all with covariant return types.
+struct H     { virtual B *foo(); };
+struct I : H { virtual C *foo(); };
+struct J : I { virtual D *foo(); J(); };
+struct K : J { virtual E *foo(); K(); };
+
+J::J() {}
+
+// VFTABLES-LABEL: VFTable for 'test1::H' in 'test1::I' in 'test1::J' (3 entries).
+// VFTABLES-NEXT:   0 | test1::D *test1::J::foo()
+// VFTABLES-NEXT:       [return adjustment (to type 'struct test1::B *'): 4 non-virtual]
+// VFTABLES-NEXT:   1 | test1::D *test1::J::foo()
+// 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: @"\01?foo@J@test1@@QAEPAUB@2@XZ"
+// GLOBALS: @"\01?foo@J@test1@@QAEPAUC@2@XZ"
+// GLOBALS: @"\01?foo@J@test1@@UAEPAUD@2@XZ"
+
+K::K() {}
+
+// VFTABLES-LABEL: VFTable for 'test1::H' in 'test1::I' in 'test1::J' in 'test1::K' (4 entries).
+// VFTABLES-NEXT:   0 | test1::E *test1::K::foo()
+// VFTABLES-NEXT:       [return adjustment (to type 'struct test1::B *'): 4 non-virtual]
+// VFTABLES-NEXT:   1 | test1::E *test1::K::foo()
+// VFTABLES-NEXT:       [return adjustment (to type 'struct test1::C *'): 0 non-virtual]
+// VFTABLES-NEXT:   2 | test1::E *test1::K::foo()
+// VFTABLES-NEXT:       [return adjustment (to type 'struct test1::D *'): 0 non-virtual]
+// VFTABLES-NEXT:   3 | test1::E *test1::K::foo()
+
+// 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: @"\01?foo@K@test1@@QAEPAUB@2@XZ"
+// GLOBALS: @"\01?foo@K@test1@@QAEPAUC@2@XZ"
+// GLOBALS: @"\01?foo@K@test1@@QAEPAUD@2@XZ"
+// GLOBALS: @"\01?foo@K@test1@@UAEPAUE@2@XZ"
+
+//  This thunk has a return adjustment.
+// CODEGEN-LABEL: define {{.*}} @"\01?foo@K@test1@@QAEPAUB@2@XZ"
+// CODEGEN: call {{.*}} @"\01?foo@K@test1@@UAEPAUE@2@XZ"
+// CODEGEN: icmp {{.*}}, null
+// CODEGEN: getelementptr
+// CODEGEN: ret
+
+//  These two don't.
+// CODEGEN-LABEL: define {{.*}} @"\01?foo@K@test1@@QAEPAUC@2@XZ"
+// CODEGEN: call {{.*}} @"\01?foo@K@test1@@UAEPAUE@2@XZ"
+// CODEGEN-NEXT: ret
+
+// CODEGEN-LABEL: define {{.*}} @"\01?foo@K@test1@@QAEPAUD@2@XZ"
+// CODEGEN: call {{.*}} @"\01?foo@K@test1@@UAEPAUE@2@XZ"
+// CODEGEN-NEXT: ret
+
+}
+
+namespace test2 {
+
+// Covariant types.  D* is not trivially convertible to C*.
+struct A { int a; };
+struct B { int b; };
+struct C : B { int c; };
+struct D : A, C { int d; };
+struct E : D { int e; };
+
+// J's foo will require an adjusting thunk, and K will require a trivial thunk.
+struct H     { virtual B *foo(); };
+struct I : H { virtual C *foo(); };
+struct J : I { virtual D *foo(); J(); };
+struct K : J { virtual E *foo(); K(); };
+
+J::J() {}
+
+// VFTABLES-LABEL: VFTable for 'test2::H' in 'test2::I' in 'test2::J' (2 entries).
+// VFTABLES-NEXT:    0 | test2::D *test2::J::foo()
+// 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*]
+
+K::K() {}
+
+// VFTABLES-LABEL: VFTable for 'test2::H' in 'test2::I' in 'test2::J' in 'test2::K' (3 entries).
+// VFTABLES-NEXT:    0 | test2::E *test2::K::foo()
+// VFTABLES-NEXT:         [return adjustment (to type 'struct test2::B *'): 4 non-virtual]
+// VFTABLES-NEXT:    1 | test2::E *test2::K::foo()
+// 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*]
+
+}
diff --git a/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp b/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp
index 6fe12b0..d453f5c 100644
--- a/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp
+++ b/test/CodeGenCXX/microsoft-abi-vtables-single-inheritance.cpp
@@ -1,29 +1,17 @@
-// RUN: %clang_cc1 %s -fno-rtti -cxx-abi microsoft -triple=i386-pc-win32 -emit-llvm -fdump-vtable-layouts -o %t.ll > %t
+// RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -fdump-vtable-layouts -o %t.ll > %t
 // RUN: FileCheck --check-prefix=EMITS-VFTABLE %s < %t.ll
 // RUN: FileCheck --check-prefix=NO-VFTABLE %s < %t.ll
-// RUN: FileCheck --check-prefix=CHECK-A %s < %t
-// RUN: FileCheck --check-prefix=CHECK-B %s < %t
-// RUN: FileCheck --check-prefix=CHECK-C %s < %t
-// RUN: FileCheck --check-prefix=CHECK-D %s < %t
-// RUN: FileCheck --check-prefix=CHECK-E %s < %t
-// RUN: FileCheck --check-prefix=CHECK-F %s < %t
-// RUN: FileCheck --check-prefix=CHECK-G %s < %t
-// RUN: FileCheck --check-prefix=CHECK-I %s < %t
-// RUN: FileCheck --check-prefix=CHECK-J %s < %t
-// RUN: FileCheck --check-prefix=CHECK-K %s < %t
-// RUN: FileCheck --check-prefix=CHECK-L %s < %t
-// RUN: FileCheck --check-prefix=CHECK-M %s < %t
-// RUN: FileCheck --check-prefix=CHECK-N %s < %t
+// RUN: FileCheck %s < %t
 
 struct A {
-  // CHECK-A: VFTable for 'A' (3 entries)
-  // CHECK-A-NEXT: 0 | void A::f()
-  // CHECK-A-NEXT: 1 | void A::g()
-  // CHECK-A-NEXT: 2 | void A::h()
-  // CHECK-A: VFTable indices for 'A' (3 entries)
-  // CHECK-A-NEXT: 0 | void A::f()
-  // CHECK-A-NEXT: 1 | void A::g()
-  // CHECK-A-NEXT: 2 | void A::h()
+  // CHECK-LABEL: VFTable for 'A' (3 entries)
+  // CHECK-NEXT: 0 | void A::f()
+  // CHECK-NEXT: 1 | void A::g()
+  // CHECK-NEXT: 2 | void A::h()
+  // CHECK-LABEL: VFTable indices for 'A' (3 entries)
+  // CHECK-NEXT: 0 | void A::f()
+  // CHECK-NEXT: 1 | void A::g()
+  // CHECK-NEXT: 2 | void A::h()
 
   virtual void f();
   virtual void g();
@@ -32,18 +20,19 @@
 };
 A a;
 // EMITS-VFTABLE-DAG: @"\01??_7A@@6B@" = linkonce_odr unnamed_addr constant [3 x i8*]
+void use(A *obj) { obj->f(); }
 
 struct B : A {
-  // CHECK-B: VFTable for 'A' in 'B' (5 entries)
-  // CHECK-B-NEXT: 0 | void B::f()
-  // CHECK-B-NEXT: 1 | void A::g()
-  // CHECK-B-NEXT: 2 | void A::h()
-  // CHECK-B-NEXT: 3 | void B::i()
-  // CHECK-B-NEXT: 4 | void B::j()
-  // CHECK-B: VFTable indices for 'B' (3 entries)
-  // CHECK-B-NEXT: 0 | void B::f()
-  // CHECK-B-NEXT: 3 | void B::i()
-  // CHECK-B-NEXT: 4 | void B::j()
+  // CHECK-LABEL: VFTable for 'A' in 'B' (5 entries)
+  // CHECK-NEXT: 0 | void B::f()
+  // CHECK-NEXT: 1 | void A::g()
+  // CHECK-NEXT: 2 | void A::h()
+  // CHECK-NEXT: 3 | void B::i()
+  // CHECK-NEXT: 4 | void B::j()
+  // CHECK-LABEL: VFTable indices for 'B' (3 entries)
+  // CHECK-NEXT: 0 | void B::f()
+  // CHECK-NEXT: 3 | void B::i()
+  // CHECK-NEXT: 4 | void B::j()
 
   virtual void f();  // overrides A::f()
   virtual void i();
@@ -51,45 +40,48 @@
 };
 B b;
 // EMITS-VFTABLE-DAG: @"\01??_7B@@6B@" = linkonce_odr unnamed_addr constant [5 x i8*]
+void use(B *obj) { obj->f(); }
 
 struct C {
-  // CHECK-C: VFTable for 'C' (2 entries)
-  // CHECK-C-NEXT: 0 | C::~C() [scalar deleting]
-  // CHECK-C-NEXT: 1 | void C::f()
-  // CHECK-C: VFTable indices for 'C' (2 entries).
-  // CHECK-C-NEXT: 0 | C::~C() [scalar deleting]
-  // CHECK-C-NEXT: 1 | void C::f()
+  // CHECK-LABEL: VFTable for 'C' (2 entries)
+  // CHECK-NEXT: 0 | C::~C() [scalar deleting]
+  // CHECK-NEXT: 1 | void C::f()
+  // CHECK-LABEL: VFTable indices for 'C' (2 entries).
+  // CHECK-NEXT: 0 | C::~C() [scalar deleting]
+  // CHECK-NEXT: 1 | void C::f()
 
   virtual ~C();
   virtual void f();
 };
 void C::f() {}
 // NO-VFTABLE-NOT: @"\01??_7C@@6B@"
+void use(C *obj) { obj->f(); }
 
 struct D {
-  // CHECK-D: VFTable for 'D' (2 entries)
-  // CHECK-D-NEXT: 0 | void D::f()
-  // CHECK-D-NEXT: 1 | D::~D() [scalar deleting]
-  // CHECK-D: VFTable indices for 'D' (2 entries)
-  // CHECK-D-NEXT: 0 | void D::f()
-  // CHECK-D-NEXT: 1 | D::~D() [scalar deleting]
+  // CHECK-LABEL: VFTable for 'D' (2 entries)
+  // CHECK-NEXT: 0 | void D::f()
+  // CHECK-NEXT: 1 | D::~D() [scalar deleting]
+  // CHECK-LABEL: VFTable indices for 'D' (2 entries)
+  // CHECK-NEXT: 0 | void D::f()
+  // CHECK-NEXT: 1 | D::~D() [scalar deleting]
 
   virtual void f();
   virtual ~D();
 };
 D d;
 // EMITS-VFTABLE-DAG: @"\01??_7D@@6B@" = linkonce_odr unnamed_addr constant [2 x i8*]
+void use(D *obj) { obj->f(); }
 
 struct E : A {
-  // CHECK-E: VFTable for 'A' in 'E' (5 entries)
-  // CHECK-E-NEXT: 0 | void A::f()
-  // CHECK-E-NEXT: 1 | void A::g()
-  // CHECK-E-NEXT: 2 | void A::h()
-  // CHECK-E-NEXT: 3 | E::~E() [scalar deleting]
-  // CHECK-E-NEXT: 4 | void E::i()
-  // CHECK-E: VFTable indices for 'E' (2 entries).
-  // CHECK-E-NEXT: 3 | E::~E() [scalar deleting]
-  // CHECK-E-NEXT: 4 | void E::i()
+  // CHECK-LABEL: VFTable for 'A' in 'E' (5 entries)
+  // CHECK-NEXT: 0 | void A::f()
+  // CHECK-NEXT: 1 | void A::g()
+  // CHECK-NEXT: 2 | void A::h()
+  // CHECK-NEXT: 3 | E::~E() [scalar deleting]
+  // CHECK-NEXT: 4 | void E::i()
+  // CHECK-LABEL: VFTable indices for 'E' (2 entries).
+  // CHECK-NEXT: 3 | E::~E() [scalar deleting]
+  // CHECK-NEXT: 4 | void E::i()
 
   // ~E would be the key method, but it isn't used, and MS ABI has no key
   // methods.
@@ -98,36 +90,38 @@
 };
 void E::i() {}
 // NO-VFTABLE-NOT: @"\01??_7E@@6B@"
+void use(E *obj) { obj->i(); }
 
 struct F : A {
-  // CHECK-F: VFTable for 'A' in 'F' (5 entries)
-  // CHECK-F-NEXT: 0 | void A::f()
-  // CHECK-F-NEXT: 1 | void A::g()
-  // CHECK-F-NEXT: 2 | void A::h()
-  // CHECK-F-NEXT: 3 | void F::i()
-  // CHECK-F-NEXT: 4 | F::~F() [scalar deleting]
-  // CHECK-F: VFTable indices for 'F' (2 entries).
-  // CHECK-F-NEXT: 3 | void F::i()
-  // CHECK-F-NEXT: 4 | F::~F() [scalar deleting]
+  // CHECK-LABEL: VFTable for 'A' in 'F' (5 entries)
+  // CHECK-NEXT: 0 | void A::f()
+  // CHECK-NEXT: 1 | void A::g()
+  // CHECK-NEXT: 2 | void A::h()
+  // CHECK-NEXT: 3 | void F::i()
+  // CHECK-NEXT: 4 | F::~F() [scalar deleting]
+  // CHECK-LABEL: VFTable indices for 'F' (2 entries).
+  // CHECK-NEXT: 3 | void F::i()
+  // CHECK-NEXT: 4 | F::~F() [scalar deleting]
 
   virtual void i();
   virtual ~F();
 };
 F f;
 // EMITS-VFTABLE-DAG: @"\01??_7F@@6B@" = linkonce_odr unnamed_addr constant [5 x i8*]
+void use(F *obj) { obj->i(); }
 
 struct G : E {
-  // CHECK-G: VFTable for 'A' in 'E' in 'G' (6 entries)
-  // CHECK-G-NEXT: 0 | void G::f()
-  // CHECK-G-NEXT: 1 | void A::g()
-  // CHECK-G-NEXT: 2 | void A::h()
-  // CHECK-G-NEXT: 3 | G::~G() [scalar deleting]
-  // CHECK-G-NEXT: 4 | void E::i()
-  // CHECK-G-NEXT: 5 | void G::j()
-  // CHECK-G: VFTable indices for 'G' (3 entries).
-  // CHECK-G-NEXT: 0 | void G::f()
-  // CHECK-G-NEXT: 3 | G::~G() [scalar deleting]
-  // CHECK-G-NEXT: 5 | void G::j()
+  // CHECK-LABEL: VFTable for 'A' in 'E' in 'G' (6 entries)
+  // CHECK-NEXT: 0 | void G::f()
+  // CHECK-NEXT: 1 | void A::g()
+  // CHECK-NEXT: 2 | void A::h()
+  // CHECK-NEXT: 3 | G::~G() [scalar deleting]
+  // CHECK-NEXT: 4 | void E::i()
+  // CHECK-NEXT: 5 | void G::j()
+  // CHECK-LABEL: VFTable indices for 'G' (3 entries).
+  // CHECK-NEXT: 0 | void G::f()
+  // CHECK-NEXT: 3 | G::~G() [scalar deleting]
+  // CHECK-NEXT: 5 | void G::j()
 
   virtual void f();  // overrides A::f()
   virtual ~G();
@@ -135,6 +129,7 @@
 };
 void G::j() {}
 // NO-VFTABLE-NOT: @"\01??_7G@@6B@"
+void use(G *obj) { obj->j(); }
 
 // Test that the usual Itanium-style key method does not emit a vtable.
 struct H {
@@ -146,23 +141,24 @@
 struct Empty { };
 
 struct I : Empty {
-  // CHECK-I: VFTable for 'I' (2 entries)
-  // CHECK-I-NEXT: 0 | void I::f()
-  // CHECK-I-NEXT: 1 | void I::g()
+  // CHECK-LABEL: VFTable for 'I' (2 entries)
+  // CHECK-NEXT: 0 | void I::f()
+  // CHECK-NEXT: 1 | void I::g()
   virtual void f();
   virtual void g();
 };
 
 I i;
+void use(I *obj) { obj->f(); }
 
 struct J {
-  // CHECK-J: VFTable for 'J' (6 entries)
-  // CHECK-J-NEXT: 0 | void J::foo(long)
-  // CHECK-J-NEXT: 1 | void J::foo(int)
-  // CHECK-J-NEXT: 2 | void J::foo(short)
-  // CHECK-J-NEXT: 3 | void J::bar(long)
-  // CHECK-J-NEXT: 4 | void J::bar(int)
-  // CHECK-J-NEXT: 5 | void J::bar(short)
+  // CHECK-LABEL: VFTable for 'J' (6 entries)
+  // CHECK-NEXT: 0 | void J::foo(long)
+  // CHECK-NEXT: 1 | void J::foo(int)
+  // CHECK-NEXT: 2 | void J::foo(short)
+  // CHECK-NEXT: 3 | void J::bar(long)
+  // CHECK-NEXT: 4 | void J::bar(int)
+  // CHECK-NEXT: 5 | void J::bar(short)
   virtual void foo(short);
   virtual void bar(short);
   virtual void foo(int);
@@ -172,36 +168,38 @@
 };
 
 J j;
+void use(J *obj) { obj->foo(42); }
 
 struct K : J {
-  // CHECK-K: VFTable for 'J' in 'K' (9 entries)
-  // CHECK-K-NEXT: 0 | void J::foo(long)
-  // CHECK-K-NEXT: 1 | void J::foo(int)
-  // CHECK-K-NEXT: 2 | void J::foo(short)
-  // CHECK-K-NEXT: 3 | void J::bar(long)
-  // CHECK-K-NEXT: 4 | void J::bar(int)
-  // CHECK-K-NEXT: 5 | void J::bar(short)
-  // CHECK-K-NEXT: 6 | void K::bar(double)
-  // CHECK-K-NEXT: 7 | void K::bar(float)
-  // CHECK-K-NEXT: 8 | void K::foo(float)
+  // CHECK-LABEL: VFTable for 'J' in 'K' (9 entries)
+  // CHECK-NEXT: 0 | void J::foo(long)
+  // CHECK-NEXT: 1 | void J::foo(int)
+  // CHECK-NEXT: 2 | void J::foo(short)
+  // CHECK-NEXT: 3 | void J::bar(long)
+  // CHECK-NEXT: 4 | void J::bar(int)
+  // CHECK-NEXT: 5 | void J::bar(short)
+  // CHECK-NEXT: 6 | void K::bar(double)
+  // CHECK-NEXT: 7 | void K::bar(float)
+  // CHECK-NEXT: 8 | void K::foo(float)
   virtual void bar(float);
   virtual void foo(float);
   virtual void bar(double);
 };
 
 K k;
+void use(K *obj) { obj->foo(42.0f); }
 
 struct L : J {
-  // CHECK-L: VFTable for 'J' in 'L' (9 entries)
-  // CHECK-L-NEXT: 0 | void J::foo(long)
-  // CHECK-L-NEXT: 1 | void L::foo(int)
-  // CHECK-L-NEXT: 2 | void J::foo(short)
-  // CHECK-L-NEXT: 3 | void J::bar(long)
-  // CHECK-L-NEXT: 4 | void J::bar(int)
-  // CHECK-L-NEXT: 5 | void J::bar(short)
-  // CHECK-L-NEXT: 6 | void L::foo(float)
-  // CHECK-L-NEXT: 7 | void L::bar(double)
-  // CHECK-L-NEXT: 8 | void L::bar(float)
+  // CHECK-LABEL: VFTable for 'J' in 'L' (9 entries)
+  // CHECK-NEXT: 0 | void J::foo(long)
+  // CHECK-NEXT: 1 | void L::foo(int)
+  // CHECK-NEXT: 2 | void J::foo(short)
+  // CHECK-NEXT: 3 | void J::bar(long)
+  // CHECK-NEXT: 4 | void J::bar(int)
+  // CHECK-NEXT: 5 | void J::bar(short)
+  // CHECK-NEXT: 6 | void L::foo(float)
+  // CHECK-NEXT: 7 | void L::bar(double)
+  // CHECK-NEXT: 8 | void L::bar(float)
 
   // This case is interesting. Since the J::foo(int) override is the first method in
   // the class, foo(float) precedes the bar(double) and bar(float) in the vftable.
@@ -212,20 +210,21 @@
 };
 
 L l;
+void use(L *obj) { obj->foo(42.0f); }
 
 struct M : J {
-  // CHECK-M: VFTable for 'J' in 'M' (11 entries)
-  // CHECK-M-NEXT:  0 | void J::foo(long)
-  // CHECK-M-NEXT:  1 | void M::foo(int)
-  // CHECK-M-NEXT:  2 | void J::foo(short)
-  // CHECK-M-NEXT:  3 | void J::bar(long)
-  // CHECK-M-NEXT:  4 | void J::bar(int)
-  // CHECK-M-NEXT:  5 | void J::bar(short)
-  // CHECK-M-NEXT:  6 | void M::foo(float)
-  // CHECK-M-NEXT:  7 | void M::spam(long)
-  // CHECK-M-NEXT:  8 | void M::spam(int)
-  // CHECK-M-NEXT:  9 | void M::bar(double)
-  // CHECK-M-NEXT: 10 | void M::bar(float)
+  // CHECK-LABEL: VFTable for 'J' in 'M' (11 entries)
+  // CHECK-NEXT:  0 | void J::foo(long)
+  // CHECK-NEXT:  1 | void M::foo(int)
+  // CHECK-NEXT:  2 | void J::foo(short)
+  // CHECK-NEXT:  3 | void J::bar(long)
+  // CHECK-NEXT:  4 | void J::bar(int)
+  // CHECK-NEXT:  5 | void J::bar(short)
+  // CHECK-NEXT:  6 | void M::foo(float)
+  // CHECK-NEXT:  7 | void M::spam(long)
+  // CHECK-NEXT:  8 | void M::spam(int)
+  // CHECK-NEXT:  9 | void M::bar(double)
+  // CHECK-NEXT: 10 | void M::bar(float)
 
   virtual void foo(int);
   virtual void spam(int);
@@ -236,13 +235,14 @@
 };
 
 M m;
+void use(M *obj) { obj->foo(42.0f); }
 
 struct N {
-  // CHECK-N: VFTable for 'N' (4 entries)
-  // CHECK-N-NEXT: 0 | void N::operator+(int)
-  // CHECK-N-NEXT: 1 | void N::operator+(short)
-  // CHECK-N-NEXT: 2 | void N::operator*(int)
-  // CHECK-N-NEXT: 3 | void N::operator*(short)
+  // CHECK-LABEL: VFTable for 'N' (4 entries)
+  // CHECK-NEXT: 0 | void N::operator+(int)
+  // CHECK-NEXT: 1 | void N::operator+(short)
+  // CHECK-NEXT: 2 | void N::operator*(int)
+  // CHECK-NEXT: 3 | void N::operator*(short)
   virtual void operator+(short);
   virtual void operator*(short);
   virtual void operator+(int);
@@ -250,3 +250,42 @@
 };
 
 N n;
+void use(N *obj) { obj->operator+(42); }
+
+struct O { virtual A *f(); };
+struct P : O { virtual B *f(); };
+P p;
+void use(O *obj) { obj->f(); }
+void use(P *obj) { obj->f(); }
+// CHECK-LABEL: VFTable for 'O' (1 entry)
+// CHECK-NEXT: 0 | A *O::f()
+
+// CHECK-LABEL: VFTable for 'O' in 'P' (1 entry)
+// CHECK-NEXT: 0 | B *P::f()
+
+struct Q {
+  // CHECK-LABEL: VFTable for 'Q' (2 entries)
+  // CHECK-NEXT: 0 | void Q::foo(int)
+  // CHECK-NEXT: 1 | void Q::bar(int)
+  void foo(short);
+  void bar(short);
+  virtual void bar(int);
+  virtual void foo(int);
+};
+
+Q q;
+void use(Q *obj) { obj->foo(42); }
+
+// Inherited non-virtual overloads don't participate in the ordering.
+struct R : Q {
+  // CHECK-LABEL: VFTable for 'Q' in 'R' (4 entries)
+  // CHECK-NEXT: 0 | void Q::foo(int)
+  // CHECK-NEXT: 1 | void Q::bar(int)
+  // CHECK-NEXT: 2 | void R::bar(long)
+  // CHECK-NEXT: 3 | void R::foo(long)
+  virtual void bar(long);
+  virtual void foo(long);
+};
+
+R r;
+void use(R *obj) { obj->foo(42l); }
diff --git a/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance-vtordisps.cpp b/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance-vtordisps.cpp
index 3fef0e4..f63808a 100644
--- a/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance-vtordisps.cpp
+++ b/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance-vtordisps.cpp
@@ -1,19 +1,9 @@
-// RUN: %clang_cc1 -fno-rtti -emit-llvm -fdump-vtable-layouts %s -o %t.ll -cxx-abi microsoft -triple=i386-pc-win32 >%t
-// RUN: FileCheck --check-prefix=VTABLE-SIMPLE-A %s < %t
-// RUN: FileCheck --check-prefix=VTABLE-SIMPLE-B %s < %t
-// RUN: FileCheck --check-prefix=VTABLE-SIMPLE-C %s < %t
-// RUN: FileCheck --check-prefix=VTABLE-EXTENDED-A %s < %t
-// RUN: FileCheck --check-prefix=VTABLE-EXTENDED-B %s < %t
-// RUN: FileCheck --check-prefix=VTABLE-EXTENDED-C %s < %t
-// RUN: FileCheck --check-prefix=VTABLE-EXTENDED-E %s < %t
-// RUN: FileCheck --check-prefix=VTABLE-EXTENDED-F %s < %t
-// RUN: FileCheck --check-prefix=VTABLE-EXTENDED-G %s < %t
-// RUN: FileCheck --check-prefix=VTABLE-EXTENDED-H %s < %t
-// RUN: FileCheck --check-prefix=VTABLE-PR17738-A %s < %t
+// RUN: %clang_cc1 -fno-rtti -emit-llvm -fdump-vtable-layouts %s -o %t.ll -triple=i386-pc-win32 > %t
+// RUN: FileCheck %s < %t
 // RUN: FileCheck --check-prefix=MANGLING %s < %t.ll
 
 // For now, just make sure x86_64 doesn't crash.
-// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -fdump-vtable-layouts %s -cxx-abi microsoft -triple=x86_64-pc-win32 >/dev/null
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -fdump-vtable-layouts %s -triple=x86_64-pc-win32 > /dev/null
 
 struct V1 {
   virtual void f();
@@ -64,11 +54,17 @@
 //   jmp Method@Class
 
 struct A : virtual V1 {
-  // VTABLE-SIMPLE-A: VFTable for 'V1' in 'simple::A' (2 entries).
-  // VTABLE-SIMPLE-A-NEXT: 0 | void simple::A::f()
-  // VTABLE-SIMPLE-A-NEXT:     [this adjustment: vtordisp at -4, 0 non-virtual]
-  // VTABLE-SIMPLE-A-NEXT: 1 | simple::A::~A() [scalar deleting]
-  // VTABLE-SIMPLE-A-NEXT:     [this adjustment: vtordisp at -4, 0 non-virtual]
+  // CHECK-LABEL: VFTable for 'V1' in 'simple::A' (2 entries).
+  // CHECK-NEXT: 0 | void simple::A::f()
+  // CHECK-NEXT:     [this adjustment: vtordisp at -4, 0 non-virtual]
+  // CHECK-NEXT: 1 | simple::A::~A() [scalar deleting]
+  // CHECK-NEXT:     [this adjustment: vtordisp at -4, 0 non-virtual]
+
+  // CHECK-LABEL: Thunks for 'simple::A::~A()' (1 entry).
+  // CHECK-NEXT: 0 | [this adjustment: vtordisp at -4, 0 non-virtual]
+
+  // CHECK-LABEL: Thunks for 'void simple::A::f()' (1 entry).
+  // CHECK-NEXT: 0 | [this adjustment: vtordisp at -4, 0 non-virtual]
 
   virtual void f();
   // MANGLING-DAG: @"\01?f@A@simple@@$4PPPPPPPM@A@AEXXZ"
@@ -78,18 +74,28 @@
 };
 
 A a;
+void use(A *obj) { obj->f(); }
 
 struct B : virtual V3 {
-  // VTABLE-SIMPLE-B: VFTable for 'Z' in 'V3' in 'simple::B' (2 entries).
-  // VTABLE-SIMPLE-B-NEXT: 0 | void Z::g()
-  // VTABLE-SIMPLE-B-NEXT: 1 | simple::B::~B() [scalar deleting]
-  // VTABLE-SIMPLE-B-NEXT:     [this adjustment: vtordisp at -4, 0 non-virtual]
+  // CHECK-LABEL: VFTable for 'Z' in 'V3' in 'simple::B' (2 entries).
+  // CHECK-NEXT: 0 | void Z::g()
+  // CHECK-NEXT: 1 | simple::B::~B() [scalar deleting]
+  // CHECK-NEXT:     [this adjustment: vtordisp at -4, 0 non-virtual]
 
-  // VTABLE-SIMPLE-B: VFTable for 'V2' in 'V3' in 'simple::B' (2 entries).
-  // VTABLE-SIMPLE-B-NEXT: 0 | void simple::B::f()
-  // VTABLE-SIMPLE-B-NEXT:     [this adjustment: vtordisp at -12, 0 non-virtual]
-  // VTABLE-SIMPLE-B-NEXT: 1 | simple::B::~B() [scalar deleting]
-  // VTABLE-SIMPLE-B-NEXT:     [this adjustment: vtordisp at -12, -8 non-virtual]
+  // CHECK-LABEL: Thunks for 'simple::B::~B()' (1 entry).
+  // CHECK-NEXT: 0 | [this adjustment: vtordisp at -4, 0 non-virtual]
+
+  // CHECK-LABEL: VFTable for 'V2' in 'V3' in 'simple::B' (2 entries).
+  // CHECK-NEXT: 0 | void simple::B::f()
+  // CHECK-NEXT:     [this adjustment: vtordisp at -12, 0 non-virtual]
+  // CHECK-NEXT: 1 | simple::B::~B() [scalar deleting]
+  // CHECK-NEXT:     [this adjustment: vtordisp at -12, -8 non-virtual]
+
+  // CHECK-LABEL: Thunks for 'simple::B::~B()' (1 entry).
+  // CHECK-NEXT: 0 | [this adjustment: vtordisp at -12, -8 non-virtual]
+
+  // CHECK-LABEL: Thunks for 'void simple::B::f()' (1 entry).
+  // CHECK-NEXT: 0 | [this adjustment: vtordisp at -12, 0 non-virtual]
 
   // FIXME: The vtordisp thunk should only get emitted for a constructor
   // if "this" leaves scope.
@@ -104,24 +110,40 @@
 };
 
 B b;
+void use(B *obj) { obj->f(); }
 
 struct C : virtual V4 {
-  // VTABLE-SIMPLE-C: VFTable for 'Z' in 'V4' in 'simple::C' (2 entries).
-  // VTABLE-SIMPLE-C-NEXT: 0 | void Z::g()
-  // VTABLE-SIMPLE-C-NEXT: 1 | simple::C::~C() [scalar deleting]
-  // VTABLE-SIMPLE-C-NEXT:     [this adjustment: vtordisp at -4, 0 non-virtual]
+  // CHECK-LABEL: VFTable for 'Z' in 'V4' in 'simple::C' (2 entries).
+  // CHECK-NEXT: 0 | void Z::g()
+  // CHECK-NEXT: 1 | simple::C::~C() [scalar deleting]
+  // CHECK-NEXT:     [this adjustment: vtordisp at -4, 0 non-virtual]
 
-  // VTABLE-SIMPLE-C: VFTable for 'V1' in 'V4' in 'simple::C' (2 entries).
-  // VTABLE-SIMPLE-C-NEXT: 0 | void simple::C::f()
-  // VTABLE-SIMPLE-C-NEXT:     [this adjustment: vtordisp at -12, 0 non-virtual]
-  // VTABLE-SIMPLE-C-NEXT: 1 | simple::C::~C() [scalar deleting]
-  // VTABLE-SIMPLE-C-NEXT:     [this adjustment: vtordisp at -12, -8 non-virtual]
+  // CHECK-LABEL: Thunks for 'simple::C::~C()' (1 entry).
+  // CHECK-NEXT: 0 | [this adjustment: vtordisp at -4, 0 non-virtual]
 
-  // VTABLE-SIMPLE-C: VFTable for 'V2' in 'V4' in 'simple::C' (2 entries).
-  // VTABLE-SIMPLE-C-NEXT: 0 | void simple::C::f()
-  // VTABLE-SIMPLE-C-NEXT:     [this adjustment: vtordisp at -16, -4 non-virtual]
-  // VTABLE-SIMPLE-C-NEXT: 1 | simple::C::~C() [scalar deleting]
-  // VTABLE-SIMPLE-C-NEXT:     [this adjustment: vtordisp at -16, -12 non-virtual]
+  // CHECK-LABEL: VFTable for 'V1' in 'V4' in 'simple::C' (2 entries).
+  // CHECK-NEXT: 0 | void simple::C::f()
+  // CHECK-NEXT:     [this adjustment: vtordisp at -12, 0 non-virtual]
+  // CHECK-NEXT: 1 | simple::C::~C() [scalar deleting]
+  // CHECK-NEXT:     [this adjustment: vtordisp at -12, -8 non-virtual]
+
+  // CHECK-LABEL: Thunks for 'simple::C::~C()' (1 entry).
+  // CHECK-NEXT: 0 | [this adjustment: vtordisp at -12, -8 non-virtual]
+
+  // CHECK-LABEL: Thunks for 'void simple::C::f()' (1 entry).
+  // CHECK-NEXT: 0 | [this adjustment: vtordisp at -12, 0 non-virtual]
+
+  // CHECK-LABEL: VFTable for 'V2' in 'V4' in 'simple::C' (2 entries).
+  // CHECK-NEXT: 0 | void simple::C::f()
+  // CHECK-NEXT:     [this adjustment: vtordisp at -16, -4 non-virtual]
+  // CHECK-NEXT: 1 | simple::C::~C() [scalar deleting]
+  // CHECK-NEXT:     [this adjustment: vtordisp at -16, -12 non-virtual]
+
+  // CHECK-LABEL: Thunks for 'simple::C::~C()' (1 entry).
+  // CHECK-NEXT: 0 | [this adjustment: vtordisp at -16, -12 non-virtual]
+
+  // CHECK-LABEL: Thunks for 'void simple::C::f()' (1 entry).
+  // CHECK-NEXT: 0 | [this adjustment: vtordisp at -16, -4 non-virtual]
 
   int x;
   virtual void f();
@@ -134,6 +156,68 @@
 };
 
 C c;
+void use(C *obj) { obj->f(); }
+
+class D : B {
+  // CHECK-LABEL: VFTable for 'V2' in 'V3' in 'simple::B' in 'simple::D' (2 entries).
+  // CHECK-NEXT: 0 | void simple::B::f()
+  // CHECK-NEXT:     [this adjustment: vtordisp at -12, -4 non-virtual]
+  // CHECK-NEXT: 1 | simple::D::~D() [scalar deleting]
+  // CHECK-NEXT:     [this adjustment: vtordisp at -12, -8 non-virtual]
+  D();
+  int z;
+
+  // MANGLING-DAG: @"\01?f@B@simple@@$4PPPPPPPE@3AEXXZ"
+};
+
+D::D() {}
+
+struct E : V3 {
+  virtual void f();
+};
+
+struct F : virtual E {
+  // CHECK-LABEL: VFTable for 'Z' in 'V3' in 'simple::E' in 'simple::F' (2 entries).
+  // CHECK-NEXT:   0 | void simple::F::g()
+  // CHECK-NEXT:       [this adjustment: vtordisp at -4, 0 non-virtual]
+  // CHECK-NEXT:   1 | simple::F::~F() [scalar deleting]
+  // CHECK-NEXT:       [this adjustment: vtordisp at -4, 0 non-virtual]
+
+  // CHECK-LABEL: VFTable for 'V2' in 'V3' in 'simple::E' in 'simple::F' (2 entries).
+  // CHECK-NEXT:   0 | void simple::E::f()
+  // CHECK-NEXT:   1 | simple::F::~F() [scalar deleting]
+  // CHECK-NEXT:       [this adjustment: vtordisp at -12, -8 non-virtual]
+
+  F();
+  virtual void g();  // Force a vtordisp.
+  int f;
+
+  // MANGLING-DAG: @"\01?g@F@simple@@$4PPPPPPPM@A@AEXXZ"{{.*}}??_EF@simple@@$4PPPPPPPM@A@AEPAXI@Z
+  // MANGLING-DAG: ?f@E@simple@@UAEXXZ{{.*}}??_EF@simple@@$4PPPPPPPE@7AEPAXI@Z
+};
+
+F::F() {}
+
+struct G : F {
+  // CHECK-LABEL: VFTable for 'Z' in 'V3' in 'simple::E' in 'simple::F' in 'simple::G' (2 entries).
+  // CHECK-NEXT:   0 | void simple::F::g()
+  // CHECK-NEXT:       [this adjustment: vtordisp at -4, -4 non-virtual]
+  // CHECK-NEXT:   1 | simple::G::~G() [scalar deleting]
+  // CHECK-NEXT:       [this adjustment: vtordisp at -4, 0 non-virtual]
+
+  // CHECK-LABEL: VFTable for 'V2' in 'V3' in 'simple::E' in 'simple::F' in 'simple::G' (2 entries).
+  // CHECK-NEXT:   0 | void simple::E::f()
+  // CHECK-NEXT:   1 | simple::G::~G() [scalar deleting]
+  // CHECK-NEXT:       [this adjustment: vtordisp at -12, -8 non-virtual]
+
+  G();
+  int g;
+
+  // MANGLING-DAG: @"\01?g@F@simple@@$4PPPPPPPM@3AEXXZ"{{.*}}@"\01??_EG@simple@@$4PPPPPPPM@A@AEPAXI@Z"
+  // MANGLING-DAG: @"\01?f@E@simple@@UAEXXZ"{{.*}}@"\01??_EG@simple@@$4PPPPPPPE@7AEPAXI@Z"
+};
+
+G::G() {}
 }
 
 namespace extended {
@@ -152,12 +236,16 @@
 //   jmp Method@Class
 
 struct A : virtual simple::A {
-  // VTABLE-EXTENDED-A: VFTable for 'V1' in 'simple::A' in 'extended::A' (2 entries).
-  // VTABLE-EXTENDED-A-NEXT: 0 | void simple::A::f()
-  // VTABLE-EXTENDED-A-NEXT:     [this adjustment: vtordisp at -4, vbptr at 8 to the left,
-  // VTABLE-EXTENDED-A-NEXT:      vboffset at 8 in the vbtable, 8 non-virtual]
-  // VTABLE-EXTENDED-A-NEXT: 1 | extended::A::~A() [scalar deleting]
-  // VTABLE-EXTENDED-A-NEXT:     [this adjustment: vtordisp at -4, 0 non-virtual]
+  // CHECK-LABEL: VFTable for 'V1' in 'simple::A' in 'extended::A' (2 entries).
+  // CHECK-NEXT: 0 | void simple::A::f()
+  // CHECK-NEXT:     [this adjustment: vtordisp at -4, vbptr at 8 to the left,
+  // CHECK-NEXT:      vboffset at 8 in the vbtable, 8 non-virtual]
+  // CHECK-NEXT: 1 | extended::A::~A() [scalar deleting]
+  // CHECK-NEXT:     [this adjustment: vtordisp at -4, 0 non-virtual]
+
+  // CHECK-LABEL: Thunks for 'void simple::A::f()' (1 entry).
+  // CHECK-NEXT: 0 | [this adjustment: vtordisp at -4, vbptr at 8 to the left,
+  // CHECK-NEXT:      vboffset at 8 in the vbtable, 8 non-virtual]
 
   // `vtordispex{8,8,4294967292,8}'
   // MANGLING-DAG: @"\01?f@A@simple@@$R477PPPPPPPM@7AEXXZ"
@@ -168,28 +256,38 @@
 };
 
 A a;
+void use(A *obj) { delete obj; }
 
 struct B : virtual simple::A {
   // This class has an implicit dtor.  Vdtors don't require vtordispex thunks
   // as the most derived class always has an implicit dtor,
   // which is a final overrider.
 
-  // VTABLE-EXTENDED-B: VFTable for 'V1' in 'simple::A' in 'extended::B' (2 entries).
+  // CHECK-LABEL: VFTable for 'V1' in 'simple::A' in 'extended::B' (2 entries).
   //  ...
-  // VTABLE-EXTENDED-B: 1 | extended::B::~B() [scalar deleting]
-  // VTABLE-EXTENDED-B-NEXT: [this adjustment: vtordisp at -4, 0 non-virtual]
+  // CHECK: 1 | extended::B::~B() [scalar deleting]
+  // CHECK-NEXT: [this adjustment: vtordisp at -4, 0 non-virtual]
+
+  // CHECK-LABEL: Thunks for 'void simple::A::f()' (1 entry).
+  // CHECK-NEXT: 0 | [this adjustment: vtordisp at -4, vbptr at 8 to the left,
+  // CHECK-NEXT:      vboffset at 8 in the vbtable, 8 non-virtual]
 
   // vtordisp{4294967292,0}
   // MANGLING-DAG: @"\01??_EB@extended@@$4PPPPPPPM@A@AEPAXI@Z"
 };
 
 B b;
+void use(B *obj) { delete obj; }
 
 struct C : virtual simple::A {
-  // VTABLE-EXTENDED-C: VFTable for 'V1' in 'simple::A' in 'extended::C' (2 entries).
-  // VTABLE-EXTENDED-C-NEXT: 0 | void simple::A::f()
-  // VTABLE-EXTENDED-C-NEXT:     [this adjustment: vtordisp at -4, vbptr at 12 to the left,
-  // VTABLE-EXTENDED-C-NEXT:      vboffset at 8 in the vbtable, 8 non-virtual]
+  // CHECK-LABEL: VFTable for 'V1' in 'simple::A' in 'extended::C' (2 entries).
+  // CHECK-NEXT: 0 | void simple::A::f()
+  // CHECK-NEXT:     [this adjustment: vtordisp at -4, vbptr at 12 to the left,
+  // CHECK-NEXT:      vboffset at 8 in the vbtable, 8 non-virtual]
+
+  // CHECK-LABEL: Thunks for 'void simple::A::f()' (1 entry).
+  // CHECK-NEXT: 0 | [this adjustment: vtordisp at -4, vbptr at 12 to the left,
+  // CHECK-NEXT:      vboffset at 8 in the vbtable, 8 non-virtual]
 
   // `vtordispex{12,8,4294967292,8}'
   // MANGLING-DAG: @"\01?f@A@simple@@$R4M@7PPPPPPPM@7AEXXZ"
@@ -199,6 +297,7 @@
 };
 
 C c;
+void use(C *obj) { delete obj; }
 
 struct D : virtual V2 {
   virtual void f();
@@ -207,10 +306,14 @@
 };
 
 struct E : virtual D {
-  // VTABLE-EXTENDED-E: VFTable for 'V2' in 'extended::D' in 'extended::E' (2 entries).
-  // VTABLE-EXTENDED-E-NEXT: 0 | void extended::D::f()
-  // VTABLE-EXTENDED-E-NEXT:     [this adjustment: vtordisp at -4, vbptr at 8 to the left,
-  // VTABLE-EXTENDED-E-NEXT:      vboffset at 8 in the vbtable, 12 non-virtual]
+  // CHECK-LABEL: VFTable for 'V2' in 'extended::D' in 'extended::E' (2 entries).
+  // CHECK-NEXT: 0 | void extended::D::f()
+  // CHECK-NEXT:     [this adjustment: vtordisp at -4, vbptr at 8 to the left,
+  // CHECK-NEXT:      vboffset at 8 in the vbtable, 12 non-virtual]
+
+  // CHECK-LABEL: Thunks for 'void extended::D::f()' (1 entry).
+  // CHECK-NEXT: 0 | [this adjustment: vtordisp at -4, vbptr at 8 to the left,
+  // CHECK-NEXT:      vboffset at 8 in the vbtable, 12 non-virtual]
 
   // `vtordispex{8,8,4294967292,12}'
   // MANGLING-DAG: @"\01?f@D@extended@@$R477PPPPPPPM@M@AEXXZ"
@@ -220,12 +323,17 @@
 };
 
 E e;
+void use(E *obj) { delete obj; } 
 
 struct F : virtual Z, virtual D {
-  // VTABLE-EXTENDED-F: VFTable for 'V2' in 'extended::D' in 'extended::F' (2 entries).
-  // VTABLE-EXTENDED-F-NEXT: 0 | void extended::D::f()
-  // VTABLE-EXTENDED-F-NEXT:     [this adjustment: vtordisp at -4, vbptr at 20 to the left,
-  // VTABLE-EXTENDED-F-NEXT:      vboffset at 12 in the vbtable, 12 non-virtual]
+  // CHECK-LABEL: VFTable for 'V2' in 'extended::D' in 'extended::F' (2 entries).
+  // CHECK-NEXT: 0 | void extended::D::f()
+  // CHECK-NEXT:     [this adjustment: vtordisp at -4, vbptr at 20 to the left,
+  // CHECK-NEXT:      vboffset at 12 in the vbtable, 12 non-virtual]
+
+  // CHECK-LABEL: Thunks for 'void extended::D::f()' (1 entry).
+  // CHECK-NEXT: 0 | [this adjustment: vtordisp at -4, vbptr at 20 to the left,
+  // CHECK-NEXT:      vboffset at 12 in the vbtable, 12 non-virtual]
 
   // `vtordispex{20,12,4294967292,12}'
   // MANGLING-DAG: @"\01?f@D@extended@@$R4BE@M@PPPPPPPM@M@AEXXZ"
@@ -235,17 +343,22 @@
 };
 
 F f;
+void use(F *obj) { delete obj; }
 
 struct G : virtual simple::A {
-  // VTABLE-EXTENDED-G: VFTable for 'extended::G' (1 entries).
-  // VTABLE-EXTENDED-G-NEXT: 0 | void extended::G::g()
+  // CHECK-LABEL: VFTable for 'extended::G' (1 entry).
+  // CHECK-NEXT: 0 | void extended::G::g()
 
-  // VTABLE-EXTENDED-G: VFTable for 'V1' in 'simple::A' in 'extended::G' (2 entries).
-  // VTABLE-EXTENDED-G-NEXT: 0 | void simple::A::f()
-  // VTABLE-EXTENDED-G-NEXT:     [this adjustment: vtordisp at -4, vbptr at 8 to the left,
-  // VTABLE-EXTENDED-G-NEXT:      vboffset at 8 in the vbtable, 8 non-virtual]
-  // VTABLE-EXTENDED-G-NEXT: 1 | extended::G::~G() [scalar deleting]
-  // VTABLE-EXTENDED-G-NEXT:     [this adjustment: vtordisp at -4, 0 non-virtual]
+  // CHECK-LABEL: VFTable for 'V1' in 'simple::A' in 'extended::G' (2 entries).
+  // CHECK-NEXT: 0 | void simple::A::f()
+  // CHECK-NEXT:     [this adjustment: vtordisp at -4, vbptr at 8 to the left,
+  // CHECK-NEXT:      vboffset at 8 in the vbtable, 8 non-virtual]
+  // CHECK-NEXT: 1 | extended::G::~G() [scalar deleting]
+  // CHECK-NEXT:     [this adjustment: vtordisp at -4, 0 non-virtual]
+
+  // CHECK-LABEL: Thunks for 'void simple::A::f()' (1 entry).
+  // CHECK-NEXT: 0 | [this adjustment: vtordisp at -4, vbptr at 8 to the left,
+  // CHECK-NEXT:      vboffset at 8 in the vbtable, 8 non-virtual]
 
   // Emits a G's own vfptr, thus moving the vbptr in the layout.
   virtual void g();
@@ -256,22 +369,28 @@
 };
 
 G g;
+void use(G *obj) { obj->g(); }
 
 struct H : Z, A {
-  // VTABLE-EXTENDED-H: VFTable for 'Z' in 'extended::H' (2 entries).
-  // VTABLE-EXTENDED-H-NEXT: 0 | void Z::g()
-  // VTABLE-EXTENDED-H-NEXT: 1 | extended::H::~H() [scalar deleting]
+  // CHECK-LABEL: VFTable for 'Z' in 'extended::H' (2 entries).
+  // CHECK-NEXT: 0 | void Z::g()
+  // CHECK-NEXT: 1 | extended::H::~H() [scalar deleting]
 
-  // VTABLE-EXTENDED-H: VFTable for 'V1' in 'simple::A' in 'extended::A' in 'extended::H' (2 entries).
-  // VTABLE-EXTENDED-H-NEXT: 0 | void simple::A::f()
-  // VTABLE-EXTENDED-H-NEXT:     [this adjustment: vtordisp at -4, vbptr at 8 to the left,
-  // VTABLE-EXTENDED-H-NEXT:      vboffset at 8 in the vbtable, 8 non-virtual]
+  // CHECK-LABEL: VFTable for 'V1' in 'simple::A' in 'extended::A' in 'extended::H' (2 entries).
+  // CHECK-NEXT: 0 | void simple::A::f()
+  // CHECK-NEXT:     [this adjustment: vtordisp at -4, vbptr at 8 to the left,
+  // CHECK-NEXT:      vboffset at 8 in the vbtable, 8 non-virtual]
+
+  // CHECK-LABEL: Thunks for 'void simple::A::f()' (1 entry).
+  // CHECK-NEXT: 0 | [this adjustment: vtordisp at -4, vbptr at 8 to the left,
+  // CHECK-NEXT:      vboffset at 8 in the vbtable, 8 non-virtual]
 
   // MANGLING-DAG: @"\01?f@A@simple@@$R477PPPPPPPM@7AEXXZ"
   // MANGLING-DAG: @"\01??_EH@extended@@$4PPPPPPPM@BA@AEPAXI@Z"
 };
 
 H h;
+void use(H *obj) { delete obj; }
 }
 
 namespace pr17738 {
@@ -279,10 +398,14 @@
 // Just do the right thing.
 
 struct A : virtual simple::B {
-  // VTABLE-PR17738-A: VFTable for 'V2' in 'V3' in 'simple::B' in 'pr17738::A' (2 entries).
-  // VTABLE-PR17738-A-NEXT: 0 | void simple::B::f()
-  // VTABLE-PR17738-A-NEXT:     [this adjustment: vtordisp at -12, vbptr at 20 to the left,
-  // VTABLE-PR17738-A-NEXT:      vboffset at 8 in the vbtable, 16 non-virtual]
+  // CHECK-LABEL: VFTable for 'V2' in 'V3' in 'simple::B' in 'pr17738::A' (2 entries).
+  // CHECK-NEXT: 0 | void simple::B::f()
+  // CHECK-NEXT:     [this adjustment: vtordisp at -12, vbptr at 20 to the left,
+  // CHECK-NEXT:      vboffset at 8 in the vbtable, 16 non-virtual]
+
+  // CHECK-LABEL: Thunks for 'void simple::B::f()' (1 entry).
+  // CHECK-NEXT: 0 | [this adjustment: vtordisp at -12, vbptr at 20 to the left,
+  // CHECK-NEXT:      vboffset at 8 in the vbtable, 16 non-virtual]
 
   // MANGLING-DAG: @"\01?f@B@simple@@$R4BE@7PPPPPPPE@BA@AEXXZ"
   int a;
@@ -290,6 +413,41 @@
 };
 
 A a;
+void use(A *obj) { delete obj; }
+}
+
+namespace pr19408 {
+// In this test, the vptr used to vcall D::f() is located in the A vbase.
+// The offset of A in different in C and D, so the D vtordisp thunk should
+// adjust "this" so C::f gets the right value.
+struct A {
+  A();
+  virtual void f();
+  int a;
+};
+
+struct B : virtual A {
+  B();
+  int b;
+};
+
+struct C : B {
+  C();
+  virtual void f();
+  int c;
+};
+
+struct D : C {
+  // CHECK-LABEL: VFTable for 'pr19408::A' in 'pr19408::B' in 'pr19408::C' in 'pr19408::D' (1 entry).
+  // CHECK-NEXT:   0 | void pr19408::C::f()
+  // CHECK-NEXT:       [this adjustment: vtordisp at -4, -4 non-virtual]
+
+  // MANGLING-DAG: @"\01?f@C@pr19408@@$4PPPPPPPM@3AEXXZ"
+  D();
+  int d;
+};
+
+D::D() {}
 }
 
 namespace access {
@@ -322,3 +480,90 @@
 
 C c;
 }
+
+namespace pr19505 {
+struct A {
+  virtual void f();
+  virtual void z();
+};
+
+struct B : A {
+  virtual void f();
+};
+
+struct C : A, B {
+  virtual void g();
+};
+
+struct X : B, virtual C {
+  X() {}
+  virtual void g();
+
+  // CHECK-LABEL: VFTable for 'pr19505::A' in 'pr19505::B' in 'pr19505::C' in 'pr19505::X' (2 entries).
+  // CHECK-NEXT:   0 | void pr19505::B::f()
+  // CHECK-NEXT:   1 | void pr19505::A::z()
+
+  // MANGLING-DAG: @"\01??_7X@pr19505@@6BB@1@@" = {{.*}}@"\01?f@B@pr19505@@UAEXXZ"
+} x;
+
+void build_vftable(X *obj) { obj->g(); }
+}
+
+namespace pr19506 {
+struct A {
+  virtual void f();
+  virtual void g();
+};
+
+struct B : A {
+  virtual void f();
+};
+
+struct C : B {};
+
+struct X : C, virtual B {
+  virtual void g();
+  X() {}
+
+  // CHECK-LABEL: VFTable for 'pr19506::A' in 'pr19506::B' in 'pr19506::X' (2 entries).
+  // CHECK-NEXT:   0 | void pr19506::B::f()
+  // CHECK-NEXT:   1 | void pr19506::X::g()
+  // CHECK-NEXT:       [this adjustment: vtordisp at -4, -12 non-virtual]
+
+  // MANGLING-DAG: @"\01??_7X@pr19506@@6BB@1@@" = {{.*}}@"\01?f@B@pr19506@@UAEXXZ"
+} x;
+
+void build_vftable(X *obj) { obj->g(); }
+}
+
+namespace pr19519 {
+// VS2013 CL miscompiles this, just make sure we don't regress.
+
+struct A {
+  virtual void f();
+  virtual void g();
+};
+
+struct B : virtual A {
+  virtual void f();
+  B();
+};
+
+struct C : virtual A {
+  virtual void g();
+};
+
+struct X : B, C {
+  X();
+
+  // CHECK-LABEL: VFTable for 'pr19519::A' in 'pr19519::B' in 'pr19519::X' (2 entries).
+  // CHECK-NEXT:   0 | void pr19519::B::f()
+  // CHECK-NEXT:       [this adjustment: vtordisp at -4, -4 non-virtual]
+  // CHECK-NEXT:   1 | void pr19519::C::g()
+  // CHECK-NEXT:       [this adjustment: vtordisp at -4, -4 non-virtual]
+
+  // MANGLING-DAG: @"\01??_7X@pr19519@@6B@" = {{.*}}@"\01?g@C@pr19519@@$4PPPPPPPM@3AEXXZ"
+};
+
+X::X() {}
+}
diff --git a/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp b/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp
index b58a0b1..4ce4e9c 100644
--- a/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp
+++ b/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp
@@ -1,29 +1,5 @@
-// RUN: %clang_cc1 -fno-rtti -emit-llvm -o %t.ll -fdump-vtable-layouts %s -cxx-abi microsoft -triple=i386-pc-win32 >%t
-
-// RUN: FileCheck --check-prefix=VTABLE-C %s < %t
-// RUN: FileCheck --check-prefix=VTABLE-D %s < %t
-// RUN: FileCheck --check-prefix=TEST1 %s < %t
-// RUN: FileCheck --check-prefix=TEST2 %s < %t
-// RUN: FileCheck --check-prefix=TEST3 %s < %t
-// RUN: FileCheck --check-prefix=TEST4 %s < %t
-// RUN: FileCheck --check-prefix=TEST5 %s < %t
-// RUN: FileCheck --check-prefix=TEST6 %s < %t
-// RUN: FileCheck --check-prefix=TEST7 %s < %t
-// RUN: FileCheck --check-prefix=TEST8-X %s < %t
-// RUN: FileCheck --check-prefix=TEST8-Z %s < %t
-// RUN: FileCheck --check-prefix=TEST9-Y %s < %t
-// RUN: FileCheck --check-prefix=TEST9-Z %s < %t
-// RUN: FileCheck --check-prefix=TEST9-W %s < %t
-// RUN: FileCheck --check-prefix=TEST9-T %s < %t
-// RUN: FileCheck --check-prefix=TEST10 %s < %t
-// RUN: FileCheck --check-prefix=VDTORS-Y %s < %t
-// RUN: FileCheck --check-prefix=VDTORS-U %s < %t
-// RUN: FileCheck --check-prefix=VDTORS-V %s < %t
-// RUN: FileCheck --check-prefix=VDTORS-P %s < %t
-// RUN: FileCheck --check-prefix=RET-W %s < %t
-// RUN: FileCheck --check-prefix=RET-T %s < %t
-// RUN: FileCheck --check-prefix=RET-V %s < %t
-
+// RUN: %clang_cc1 -fno-rtti -emit-llvm -o %t.ll -fdump-vtable-layouts %s -triple=i386-pc-win32 >%t
+// RUN: FileCheck %s < %t
 // RUN: FileCheck --check-prefix=MANGLING %s < %t.ll
 
 struct Empty { };
@@ -38,34 +14,35 @@
 };
 
 struct C: virtual A {
-  // VTABLE-C: VFTable for 'A' in 'C' (2 entries)
-  // VTABLE-C-NEXT: 0 | void C::f()
-  // VTABLE-C-NEXT: 1 | void A::z()
+  // CHECK-LABEL: VFTable for 'A' in 'C' (2 entries)
+  // CHECK-NEXT: 0 | void C::f()
+  // CHECK-NEXT: 1 | void A::z()
 
-  // VTABLE-C: VFTable indices for 'C' (1 entries)
-  // VTABLE-C-NEXT: vbtable index 1, vfptr at offset 0
-  // VTABLE-C-NEXT: 0 | void C::f()
+  // CHECK-LABEL: VFTable indices for 'C' (1 entry)
+  // CHECK-NEXT: vbtable index 1, vfptr at offset 0
+  // CHECK-NEXT: 0 | void C::f()
 
   // MANGLING-DAG: @"\01??_7C@@6B@"
 
-  virtual void f();
+  virtual void f() {}
 };
 
 C c;
+void use(C *obj) { obj->f(); }
 
 struct D: virtual A {
-  // VTABLE-D: VFTable for 'D' (1 entries).
-  // VTABLE-D-NEXT: 0 | void D::h()
+  // CHECK-LABEL: VFTable for 'D' (1 entry).
+  // CHECK-NEXT: 0 | void D::h()
 
-  // VTABLE-D: VFTable for 'A' in 'D' (2 entries).
-  // VTABLE-D-NEXT: 0 | void D::f()
-  // VTABLE-D-NEXT: 1 | void A::z()
+  // CHECK-LABEL: VFTable for 'A' in 'D' (2 entries).
+  // CHECK-NEXT: 0 | void D::f()
+  // CHECK-NEXT: 1 | void A::z()
 
-  // VTABLE-D: VFTable indices for 'D' (2 entries).
-  // VTABLE-D-NEXT: via vfptr at offset 0
-  // VTABLE-D-NEXT: 0 | void D::h()
-  // VTABLE-D-NEXT: via vbtable index 1, vfptr at offset 0
-  // VTABLE-D-NEXT: 0 | void D::f()
+  // CHECK-LABEL: VFTable indices for 'D' (2 entries).
+  // CHECK-NEXT: via vfptr at offset 0
+  // CHECK-NEXT: 0 | void D::h()
+  // CHECK-NEXT: via vbtable index 1, vfptr at offset 0
+  // CHECK-NEXT: 0 | void D::f()
 
   // MANGLING-DAG: @"\01??_7D@@6B0@@"
   // MANGLING-DAG: @"\01??_7D@@6BA@@@"
@@ -74,8 +51,8 @@
   virtual void h();
 };
 
-void D::h() {}
 D d;
+void use(D *obj) { obj->h(); }
 
 namespace Test1 {
 
@@ -86,33 +63,34 @@
 // MANGLING-DAG: @"\01??_7Y@Test1@@6B@"
 
 struct Z : virtual Y {
-  // TEST1: VFTable for 'A' in 'Test1::Y' in 'Test1::Z' (2 entries).
-  // TEST1-NEXT: 0 | void A::f()
-  // TEST1-NEXT: 1 | void A::z()
+  Z();
+  // CHECK-LABEL: VFTable for 'A' in 'Test1::Y' in 'Test1::Z' (2 entries).
+  // CHECK-NEXT: 0 | void A::f()
+  // CHECK-NEXT: 1 | void A::z()
 
-  // TEST1-NOT: VFTable indices for 'Test1::Z'
+  // CHECK-NOT: VFTable indices for 'Test1::Z'
 
   // MANGLING-DAG: @"\01??_7Z@Test1@@6B@"
 };
 
-Z z;
+Z::Z() {}
 }
 
 namespace Test2 {
 
 struct X: virtual A, virtual B {
-  // TEST2: VFTable for 'Test2::X' (1 entries).
-  // TEST2-NEXT: 0 | void Test2::X::h()
+  // CHECK-LABEL: VFTable for 'Test2::X' (1 entry).
+  // CHECK-NEXT: 0 | void Test2::X::h()
 
-  // TEST2: VFTable for 'A' in 'Test2::X' (2 entries).
-  // TEST2-NEXT: 0 | void A::f()
-  // TEST2-NEXT: 1 | void A::z()
+  // CHECK-LABEL: VFTable for 'A' in 'Test2::X' (2 entries).
+  // CHECK-NEXT: 0 | void A::f()
+  // CHECK-NEXT: 1 | void A::z()
 
-  // TEST2: VFTable for 'B' in 'Test2::X' (1 entries).
-  // TEST2-NEXT: 0 | void B::g()
+  // CHECK-LABEL: VFTable for 'B' in 'Test2::X' (1 entry).
+  // CHECK-NEXT: 0 | void B::g()
 
-  // TEST2: VFTable indices for 'Test2::X' (1 entries).
-  // TEST2-NEXT: 0 | void Test2::X::h()
+  // CHECK-LABEL: VFTable indices for 'Test2::X' (1 entry).
+  // CHECK-NEXT: 0 | void Test2::X::h()
 
   // MANGLING-DAG: @"\01??_7X@Test2@@6B01@@"
   // MANGLING-DAG: @"\01??_7X@Test2@@6BA@@@"
@@ -122,6 +100,7 @@
 };
 
 X x;
+void use(X *obj) { obj->h(); }
 }
 
 namespace Test3 {
@@ -131,40 +110,45 @@
 };
 
 struct Y: virtual X {
-  // TEST3: VFTable for 'A' in 'Test3::X' in 'Test3::Y' (2 entries).
-  // TEST3-NEXT: 0 | void A::f()
-  // TEST3-NEXT: 1 | void A::z()
+  Y();
+  // CHECK-LABEL: VFTable for 'A' in 'Test3::X' in 'Test3::Y' (2 entries).
+  // CHECK-NEXT: 0 | void A::f()
+  // CHECK-NEXT: 1 | void A::z()
 
-  // TEST3-NOT: VFTable indices for 'Test3::Y'
+  // CHECK-NOT: VFTable indices for 'Test3::Y'
 
   // MANGLING-DAG: @"\01??_7Y@Test3@@6B@"
 };
 
-Y y;
+Y::Y() {}
 }
 
 namespace Test4 {
 
 struct X: virtual C {
+  X();
   // This one's interesting. C::f expects (A*) to be passed as 'this' and does
   // ECX-=4 to cast to (C*). In X, C and A vbases are reordered, so the thunk
   // should pass a pointer to the end of X in order
   // for ECX-=4 to point at the C part.
 
-  // TEST4: VFTable for 'A' in 'C' in 'Test4::X' (2 entries).
-  // TEST4-NEXT: 0 | void C::f()
-  // TEST4-NEXT:     [this adjustment: 8 non-virtual]
-  // TEST4-NEXT: 1 | void A::z()
+  // CHECK-LABEL: VFTable for 'A' in 'C' in 'Test4::X' (2 entries).
+  // CHECK-NEXT: 0 | void C::f()
+  // CHECK-NEXT:     [this adjustment: 8 non-virtual]
+  // CHECK-NEXT: 1 | void A::z()
 
-  // TEST4-NOT: VFTable indices for 'Test4::X'
+  // CHECK-LABEL: Thunks for 'void C::f()' (1 entry).
+  // CHECK-NEXT: 0 | [this adjustment: 8 non-virtual]
+
+  // CHECK-NOT: VFTable indices for 'Test4::X'
 
   // MANGLING-DAG: @"\01??_7X@Test4@@6B@"
 
   // Also check the mangling of the thunk.
-  // MANGLING-DAG: define weak x86_thiscallcc void @"\01?f@C@@WPPPPPPPI@AEXXZ"
+  // MANGLING-DAG: define linkonce_odr x86_thiscallcc void @"\01?f@C@@WPPPPPPPI@AEXXZ"
 };
 
-X x;
+X::X() {}
 }
 
 namespace Test5 {
@@ -176,16 +160,16 @@
 };
 
 struct Y : virtual X {
-  // TEST5: VFTable for 'Test5::Y' (1 entries).
-  // TEST5-NEXT: 0 | void Test5::Y::h()
+  // CHECK-LABEL: VFTable for 'Test5::Y' (1 entry).
+  // CHECK-NEXT: 0 | void Test5::Y::h()
 
-  // TEST5: VFTable for 'A' in 'Test5::X' in 'Test5::Y' (3 entries).
-  // TEST5-NEXT: 0 | void A::f()
-  // TEST5-NEXT: 1 | void A::z()
-  // TEST5-NEXT: 2 | void Test5::X::g()
+  // CHECK-LABEL: VFTable for 'A' in 'Test5::X' in 'Test5::Y' (3 entries).
+  // CHECK-NEXT: 0 | void A::f()
+  // CHECK-NEXT: 1 | void A::z()
+  // CHECK-NEXT: 2 | void Test5::X::g()
 
-  // TEST5: VFTable indices for 'Test5::Y' (1 entries).
-  // TEST5-NEXT: 0 | void Test5::Y::h()
+  // CHECK-LABEL: VFTable indices for 'Test5::Y' (1 entry).
+  // CHECK-NEXT: 0 | void Test5::Y::h()
 
   // MANGLING-DAG: @"\01??_7Y@Test5@@6B01@@"
   // MANGLING-DAG: @"\01??_7Y@Test5@@6BX@1@@"
@@ -194,21 +178,23 @@
 };
 
 Y y;
+void use(Y *obj) { obj->h(); }
 }
 
 namespace Test6 {
 
 struct X : A, virtual Empty {
-  // TEST6: VFTable for 'A' in 'Test6::X' (2 entries).
-  // TEST6-NEXT: 0 | void A::f()
-  // TEST6-NEXT: 1 | void A::z()
+  X();
+  // CHECK-LABEL: VFTable for 'A' in 'Test6::X' (2 entries).
+  // CHECK-NEXT: 0 | void A::f()
+  // CHECK-NEXT: 1 | void A::z()
 
-  // TEST6-NOT: VFTable indices for 'Test6::X'
+  // CHECK-NOT: VFTable indices for 'Test6::X'
 
   // MANGLING-DAG: @"\01??_7X@Test6@@6B@"
 };
 
-X x;
+X::X() {}
 }
 
 namespace Test7 {
@@ -218,36 +204,37 @@
 };
 
 struct Y : virtual X {
-  // TEST7: VFTable for 'A' in 'C' in 'Test7::X' in 'Test7::Y' (2 entries).
-  // TEST7-NEXT: 0 | void C::f()
-  // TEST7-NEXT:     [this adjustment: 8 non-virtual]
-  // TEST7-NEXT: 1 | void A::z()
+  Y();
+  // CHECK-LABEL: VFTable for 'A' in 'C' in 'Test7::X' in 'Test7::Y' (2 entries).
+  // CHECK-NEXT: 0 | void C::f()
+  // CHECK-NEXT:     [this adjustment: 8 non-virtual]
+  // CHECK-NEXT: 1 | void A::z()
 
-  // TEST7: Thunks for 'void C::f()' (1 entry).
-  // TEST7-NEXT: 0 | [this adjustment: 8 non-virtual]
+  // CHECK-LABEL: Thunks for 'void C::f()' (1 entry).
+  // CHECK-NEXT: 0 | [this adjustment: 8 non-virtual]
 
-  // TEST7-NOT: VFTable indices for 'Test7::Y'
+  // CHECK-NOT: VFTable indices for 'Test7::Y'
 
   // MANGLING-DAG: @"\01??_7Y@Test7@@6B@"
 };
 
-Y y;
+Y::Y() {}
 }
 
 namespace Test8 {
 
 // This is a typical diamond inheritance with a shared 'A' vbase.
 struct X : D, C {
-  // TEST8-X: VFTable for 'D' in 'Test8::X' (1 entries).
-  // TEST8-X-NEXT: 0 | void D::h()
+  // CHECK-LABEL: VFTable for 'D' in 'Test8::X' (1 entry).
+  // CHECK-NEXT: 0 | void D::h()
 
-  // TEST8-X: VFTable for 'A' in 'D' in 'Test8::X' (2 entries).
-  // TEST8-X-NEXT: 0 | void Test8::X::f()
-  // TEST8-X-NEXT: 1 | void A::z()
+  // CHECK-LABEL: VFTable for 'A' in 'D' in 'Test8::X' (2 entries).
+  // CHECK-NEXT: 0 | void Test8::X::f()
+  // CHECK-NEXT: 1 | void A::z()
 
-  // TEST8-X: VFTable indices for 'Test8::X' (1 entries).
-  // TEST8-X-NEXT: via vbtable index 1, vfptr at offset 0
-  // TEST8-X-NEXT: 0 | void Test8::X::f()
+  // CHECK-LABEL: VFTable indices for 'Test8::X' (1 entry).
+  // CHECK-NEXT: via vbtable index 1, vfptr at offset 0
+  // CHECK-NEXT: 0 | void Test8::X::f()
 
   // MANGLING-DAG: @"\01??_7X@Test8@@6BA@@@"
   // MANGLING-DAG: @"\01??_7X@Test8@@6BD@@@"
@@ -256,21 +243,45 @@
 };
 
 X x;
+void use(X *obj) { obj->f(); }
 
 // Another diamond inheritance which led to AST crashes.
 struct Y : virtual A {};
 
-class Z : Y, C {
-  // TEST8-Z: VFTable for 'A' in 'Test8::Y' in 'Test8::Z' (2 entries).
-  // TEST8-Z-NEXT: 0 | void Test8::Z::f()
-  // TEST8-Z-NEXT: 1 | void A::z()
+struct Z : Y, C {
+  // CHECK-LABEL: VFTable for 'A' in 'Test8::Y' in 'Test8::Z' (2 entries).
+  // CHECK-NEXT: 0 | void Test8::Z::f()
+  // CHECK-NEXT: 1 | void A::z()
 
-  // TEST8-Z: VFTable indices for 'Test8::Z' (1 entries).
-  // TEST8-Z-NEXT: via vbtable index 1, vfptr at offset 0
-  // TEST8-Z-NEXT: 0 | void Test8::Z::f()
+  // CHECK-LABEL: VFTable indices for 'Test8::Z' (1 entry).
+  // CHECK-NEXT: via vbtable index 1, vfptr at offset 0
+  // CHECK-NEXT: 0 | void Test8::Z::f()
   virtual void f();
 };
 Z z;
+void use(Z *obj) { obj->f(); }
+
+// Another diamond inheritance which we miscompiled (PR18967).
+struct W : virtual A {
+  virtual void bar();
+};
+
+struct T : W, C {
+  // CHECK-LABEL: VFTable for 'Test8::W' in 'Test8::T' (1 entry)
+  // CHECK-NEXT: 0 | void Test8::T::bar()
+
+  // CHECK-LABEL: VFTable for 'A' in 'Test8::W' in 'Test8::T' (2 entries)
+  // CHECK-NEXT: 0 | void C::f()
+  // CHECK-NEXT:     [this adjustment: -4 non-virtual]
+  // CHECK-NEXT: 1 | void A::z()
+
+  // CHECK-LABEL: Thunks for 'void C::f()' (1 entry).
+  // CHECK-NEXT: 0 | [this adjustment: -4 non-virtual]
+  virtual void bar();
+  int field;
+};
+T t;
+void use(T *obj) { obj->bar(); }
 }
 
 namespace Test9 {
@@ -278,15 +289,15 @@
 struct X : A { };
 
 struct Y : virtual X {
-  // TEST9-Y: VFTable for 'Test9::Y' (1 entries).
-  // TEST9-Y-NEXT: 0 | void Test9::Y::h()
+  // CHECK-LABEL: VFTable for 'Test9::Y' (1 entry).
+  // CHECK-NEXT: 0 | void Test9::Y::h()
 
-  // TEST9-Y: VFTable for 'A' in 'Test9::X' in 'Test9::Y' (2 entries).
-  // TEST9-Y-NEXT: 0 | void A::f()
-  // TEST9-Y-NEXT: 1 | void A::z()
+  // CHECK-LABEL: VFTable for 'A' in 'Test9::X' in 'Test9::Y' (2 entries).
+  // CHECK-NEXT: 0 | void A::f()
+  // CHECK-NEXT: 1 | void A::z()
 
-  // TEST9-Y: VFTable indices for 'Test9::Y' (1 entries).
-  // TEST9-Y-NEXT: 0 | void Test9::Y::h()
+  // CHECK-LABEL: VFTable indices for 'Test9::Y' (1 entry).
+  // CHECK-NEXT: 0 | void Test9::Y::h()
 
   // MANGLING-DAG: @"\01??_7Y@Test9@@6B01@@"
   // MANGLING-DAG: @"\01??_7Y@Test9@@6BX@1@@"
@@ -295,115 +306,110 @@
 };
 
 Y y;
+void use(Y *obj) { obj->h(); }
 
 struct Z : Y, virtual B {
-  // TEST9-Z: VFTable for 'Test9::Y' in 'Test9::Z' (1 entries).
-  // TEST9-Z-NEXT: 0 | void Test9::Y::h()
+  Z();
+  // CHECK-LABEL: VFTable for 'Test9::Y' in 'Test9::Z' (1 entry).
+  // CHECK-NEXT: 0 | void Test9::Y::h()
 
-  // TEST9-Z: VFTable for 'A' in 'Test9::X' in 'Test9::Y' in 'Test9::Z' (2 entries).
-  // TEST9-Z-NEXT: 0 | void A::f()
-  // TEST9-Z-NEXT: 1 | void A::z()
+  // CHECK-LABEL: VFTable for 'A' in 'Test9::X' in 'Test9::Y' in 'Test9::Z' (2 entries).
+  // CHECK-NEXT: 0 | void A::f()
+  // CHECK-NEXT: 1 | void A::z()
 
-  // TEST9-Z: VFTable for 'B' in 'Test9::Z' (1 entries).
-  // TEST9-Z-NEXT: 0 | void B::g()
+  // CHECK-LABEL: VFTable for 'B' in 'Test9::Z' (1 entry).
+  // CHECK-NEXT: 0 | void B::g()
 
-  // TEST9-Z-NOT: VFTable indices for 'Test9::Z'
+  // CHECK-NOT: VFTable indices for 'Test9::Z'
 
   // MANGLING-DAG: @"\01??_7Z@Test9@@6BX@1@@"
   // MANGLING-DAG: @"\01??_7Z@Test9@@6BY@1@@"
 
-  // FIXME this one is wrong:
-  // INCORRECT MANGLING-DAG: @"\01??_7Z@Test9@@6BB@@@"
-  // MANGLING-DAG-SHOULD-BE: @"\01??_7Z@Test9@@6B@"
+  // MANGLING-DAG: @"\01??_7Z@Test9@@6B@"
 };
 
-Z z;
+Z::Z() {}
 
 struct W : Z, D, virtual A, virtual B {
-  // TEST9-W: VFTable for 'Test9::Y' in 'Test9::Z' in 'Test9::W' (1 entries).
-  // TEST9-W-NEXT: 0 | void Test9::Y::h()
+  W();
+  // CHECK-LABEL: VFTable for 'Test9::Y' in 'Test9::Z' in 'Test9::W' (1 entry).
+  // CHECK-NEXT: 0 | void Test9::Y::h()
 
-  // TEST9-W: VFTable for 'A' in 'Test9::X' in 'Test9::Y' in 'Test9::Z' in 'Test9::W' (2 entries).
-  // TEST9-W-NEXT: 0 | void A::f()
-  // TEST9-W-NEXT: 1 | void A::z()
+  // CHECK-LABEL: VFTable for 'A' in 'Test9::X' in 'Test9::Y' in 'Test9::Z' in 'Test9::W' (2 entries).
+  // CHECK-NEXT: 0 | void A::f()
+  // CHECK-NEXT: 1 | void A::z()
 
-  // TEST9-W: VFTable for 'B' in 'Test9::Z' in 'Test9::W' (1 entries).
-  // TEST9-W-NEXT: 0 | void B::g()
+  // CHECK-LABEL: VFTable for 'B' in 'Test9::Z' in 'Test9::W' (1 entry).
+  // CHECK-NEXT: 0 | void B::g()
 
-  // TEST9-W: VFTable for 'D' in 'Test9::W' (1 entries).
-  // TEST9-W-NEXT: 0 | void D::h()
+  // CHECK-LABEL: VFTable for 'D' in 'Test9::W' (1 entry).
+  // CHECK-NEXT: 0 | void D::h()
 
-  // TEST9-W: VFTable for 'A' in 'D' in 'Test9::W' (2 entries).
-  // TEST9-W-NEXT: 0 | void D::f()
-  // TEST9-W-NEXT:     [this adjustment: -8 non-virtual]
-  // TEST9-W-NEXT: 1 | void A::z()
+  // CHECK-LABEL: VFTable for 'A' in 'D' in 'Test9::W' (2 entries).
+  // CHECK-NEXT: 0 | void D::f()
+  // CHECK-NEXT:     [this adjustment: -8 non-virtual]
+  // CHECK-NEXT: 1 | void A::z()
 
-  // TEST9-W: Thunks for 'void D::f()' (1 entry).
-  // TEST9-W-NEXT: 0 | [this adjustment: -8 non-virtual]
+  // CHECK-LABEL: Thunks for 'void D::f()' (1 entry).
+  // CHECK-NEXT: 0 | [this adjustment: -8 non-virtual]
 
-  // TEST9-W-NOT: VFTable indices for 'Test9::W'
+  // CHECK-NOT: VFTable indices for 'Test9::W'
 
   // MANGLING-DAG: @"\01??_7W@Test9@@6BA@@@"
   // MANGLING-DAG: @"\01??_7W@Test9@@6BD@@@"
   // MANGLING-DAG: @"\01??_7W@Test9@@6BX@1@@"
 
-  // FIXME: these two are wrong:
-  // INCORRECT MANGLING-DAG: @"\01??_7W@Test9@@6BB@@@"
-  // MANGLING-DAG-SHOULD-BE: @"\01??_7W@Test9@@6B@"
-  // INCORRECT MANGLING-DAG: @"\01??_7W@Test9@@6BY@1@Z@1@@"
-  // MANGLING-DAG-SHOULD-BE: @"\01??_7W@Test9@@6BY@1@@"
+  // MANGLING-DAG: @"\01??_7W@Test9@@6B@"
+  // MANGLING-DAG: @"\01??_7W@Test9@@6BY@1@@"
 };
 
-W w;
+W::W() {}
 
 struct T : Z, D, virtual A, virtual B {
-  // TEST9-T: VFTable for 'Test9::Y' in 'Test9::Z' in 'Test9::T' (1 entries).
-  // TEST9-T-NEXT: 0 | void Test9::T::h()
+  // CHECK-LABEL: VFTable for 'Test9::Y' in 'Test9::Z' in 'Test9::T' (1 entry).
+  // CHECK-NEXT: 0 | void Test9::T::h()
 
-  // TEST9-T: VFTable for 'A' in 'Test9::X' in 'Test9::Y' in 'Test9::Z' in 'Test9::T' (2 entries).
-  // TEST9-T-NEXT: 0 | void Test9::T::f()
-  // TEST9-T-NEXT: 1 | void Test9::T::z()
+  // CHECK-LABEL: VFTable for 'A' in 'Test9::X' in 'Test9::Y' in 'Test9::Z' in 'Test9::T' (2 entries).
+  // CHECK-NEXT: 0 | void Test9::T::f()
+  // CHECK-NEXT: 1 | void Test9::T::z()
 
-  // TEST9-T: VFTable for 'B' in 'Test9::Z' in 'Test9::T' (1 entries).
-  // TEST9-T-NEXT: 0 | void Test9::T::g()
+  // CHECK-LABEL: VFTable for 'B' in 'Test9::Z' in 'Test9::T' (1 entry).
+  // CHECK-NEXT: 0 | void Test9::T::g()
 
-  // TEST9-T: VFTable for 'D' in 'Test9::T' (1 entries).
-  // TEST9-T-NEXT: 0 | void Test9::T::h()
-  // TEST9-T-NEXT:     [this adjustment: -8 non-virtual]
+  // CHECK-LABEL: VFTable for 'D' in 'Test9::T' (1 entry).
+  // CHECK-NEXT: 0 | void Test9::T::h()
+  // CHECK-NEXT:     [this adjustment: -8 non-virtual]
 
-  // TEST9-T: Thunks for 'void Test9::T::h()' (1 entry).
-  // TEST9-T-NEXT: 0 | [this adjustment: -8 non-virtual]
+  // CHECK-LABEL: Thunks for 'void Test9::T::h()' (1 entry).
+  // CHECK-NEXT: 0 | [this adjustment: -8 non-virtual]
 
-  // TEST9-T: VFTable for 'A' in 'D' in 'Test9::T' (2 entries).
-  // TEST9-T-NEXT: 0 | void Test9::T::f()
-  // TEST9-T-NEXT:     [this adjustment: -8 non-virtual]
-  // TEST9-T-NEXT: 1 | void Test9::T::z()
-  // TEST9-T-NEXT:     [this adjustment: -8 non-virtual]
+  // CHECK-LABEL: VFTable for 'A' in 'D' in 'Test9::T' (2 entries).
+  // CHECK-NEXT: 0 | void Test9::T::f()
+  // CHECK-NEXT:     [this adjustment: -8 non-virtual]
+  // CHECK-NEXT: 1 | void Test9::T::z()
+  // CHECK-NEXT:     [this adjustment: -8 non-virtual]
 
-  // TEST9-T: Thunks for 'void Test9::T::f()' (1 entry).
-  // TEST9-T-NEXT: 0 | [this adjustment: -8 non-virtual]
+  // CHECK-LABEL: Thunks for 'void Test9::T::f()' (1 entry).
+  // CHECK-NEXT: 0 | [this adjustment: -8 non-virtual]
 
-  // TEST9-T: Thunks for 'void Test9::T::z()' (1 entry).
-  // TEST9-T-NEXT: 0 | [this adjustment: -8 non-virtual]
+  // CHECK-LABEL: Thunks for 'void Test9::T::z()' (1 entry).
+  // CHECK-NEXT: 0 | [this adjustment: -8 non-virtual]
 
-  // TEST9-T: VFTable indices for 'Test9::T' (4 entries).
-  // TEST9-T-NEXT: via vfptr at offset 0
-  // TEST9-T-NEXT: 0 | void Test9::T::h()
-  // TEST9-T-NEXT: via vbtable index 1, vfptr at offset 0
-  // TEST9-T-NEXT: 0 | void Test9::T::f()
-  // TEST9-T-NEXT: 1 | void Test9::T::z()
-  // TEST9-T-NEXT: via vbtable index 2, vfptr at offset 0
-  // TEST9-T-NEXT: 0 | void Test9::T::g()
+  // CHECK-LABEL: VFTable indices for 'Test9::T' (4 entries).
+  // CHECK-NEXT: via vfptr at offset 0
+  // CHECK-NEXT: 0 | void Test9::T::h()
+  // CHECK-NEXT: via vbtable index 1, vfptr at offset 0
+  // CHECK-NEXT: 0 | void Test9::T::f()
+  // CHECK-NEXT: 1 | void Test9::T::z()
+  // CHECK-NEXT: via vbtable index 2, vfptr at offset 0
+  // CHECK-NEXT: 0 | void Test9::T::g()
 
   // MANGLING-DAG: @"\01??_7T@Test9@@6BA@@@"
   // MANGLING-DAG: @"\01??_7T@Test9@@6BD@@@"
   // MANGLING-DAG: @"\01??_7T@Test9@@6BX@1@@"
 
-  // FIXME: these two are wrong:
-  // INCORRECT MANGLING-DAG: @"\01??_7T@Test9@@6BB@@@"
-  // MANGLING-DAG-SHOULD-BE: @"\01??_7T@Test9@@6B@"
-  // INCORRECT MANGLING-DAG: @"\01??_7T@Test9@@6BY@1@Z@1@@"
-  // MANGLING-DAG-SHOULD-BE: @"\01??_7T@Test9@@6BY@1@@"
+  // MANGLING-DAG: @"\01??_7T@Test9@@6B@"
+  // MANGLING-DAG: @"\01??_7T@Test9@@6BY@1@@"
 
   virtual void f();
   virtual void g();
@@ -412,22 +418,70 @@
 };
 
 T t;
+void use(T *obj) { obj->f(); }
 }
 
 namespace Test10 {
 struct X : virtual C, virtual A {
-  // TEST10: VFTable for 'A' in 'C' in 'Test10::X' (2 entries).
-  // TEST10-NEXT: 0 | void Test10::X::f()
-  // TEST10-NEXT: 1 | void A::z()
+  // CHECK-LABEL: VFTable for 'A' in 'C' in 'Test10::X' (2 entries).
+  // CHECK-NEXT: 0 | void Test10::X::f()
+  // CHECK-NEXT: 1 | void A::z()
 
-  // TEST10: VFTable indices for 'Test10::X' (1 entries).
-  // TEST10-NEXT: via vbtable index 1, vfptr at offset 0
-  // TEST10-NEXT: 0 | void Test10::X::f()
+  // CHECK-LABEL: VFTable indices for 'Test10::X' (1 entry).
+  // CHECK-NEXT: via vbtable index 1, vfptr at offset 0
+  // CHECK-NEXT: 0 | void Test10::X::f()
   virtual void f();
 };
 
 void X::f() {}
 X x;
+void use(X *obj) { obj->f(); }
+}
+
+namespace Test11 {
+struct X : virtual A {};
+struct Y { virtual void g(); };
+
+struct Z : virtual X, Y {
+  // MANGLING-DAG: @"\01??_7Z@Test11@@6BY@1@@"
+  // MANGLING-DAG: @"\01??_7Z@Test11@@6BX@1@@"
+};
+
+Z z;
+
+struct W : virtual X, A {};
+
+// Used to crash, PR17748.
+W w;
+}
+
+namespace Test12 {
+struct X : B, A { };
+
+struct Y : X {
+  virtual void f();  // Overrides A::f.
+};
+
+struct Z : virtual Y {
+  // CHECK-LABEL: VFTable for 'A' in 'Test12::X' in 'Test12::Y' in 'Test12::Z' (2 entries).
+  // CHECK-NEXT:   0 | void Test12::Y::f()
+  // CHECK-NEXT:   1 | void A::z()
+
+  int z;
+  // MANGLING-DAG: @"\01??_7Z@Test12@@6BA@@@" = {{.*}}@"\01?f@Y@Test12@@UAEXXZ"
+};
+
+struct W : Z {
+  // CHECK-LABEL: VFTable for 'A' in 'Test12::X' in 'Test12::Y' in 'Test12::Z' in 'Test12::W' (2 entries).
+  // CHECK-NEXT:   0 | void Test12::Y::f()
+  // CHECK-NEXT:   1 | void A::z()
+  W();
+
+  int w;
+  // MANGLING-DAG: @"\01??_7W@Test12@@6BA@@@" = {{.*}}@"\01?f@Y@Test12@@UAEXXZ"
+};
+
+W::W() {}
 }
 
 namespace vdtors {
@@ -437,15 +491,16 @@
 };
 
 struct Y : virtual X {
-  // VDTORS-Y: VFTable for 'vdtors::X' in 'vdtors::Y' (2 entries).
-  // VDTORS-Y-NEXT: 0 | vdtors::Y::~Y() [scalar deleting]
-  // VDTORS-Y-NEXT: 1 | void vdtors::X::zzz()
+  // CHECK-LABEL: VFTable for 'vdtors::X' in 'vdtors::Y' (2 entries).
+  // CHECK-NEXT: 0 | vdtors::Y::~Y() [scalar deleting]
+  // CHECK-NEXT: 1 | void vdtors::X::zzz()
 
-  // VDTORS-Y-NOT: Thunks for 'vdtors::Y::~Y()'
+  // CHECK-NOT: Thunks for 'vdtors::Y::~Y()'
   virtual ~Y();
 };
 
 Y y;
+void use(Y *obj) { delete obj; }
 
 struct Z {
   virtual void z();
@@ -456,59 +511,86 @@
 };
 
 struct U : virtual W {
-  // VDTORS-U: VFTable for 'vdtors::Z' in 'vdtors::W' in 'vdtors::U' (1 entries).
-  // VDTORS-U-NEXT: 0 | void vdtors::Z::z()
+  // CHECK-LABEL: VFTable for 'vdtors::Z' in 'vdtors::W' in 'vdtors::U' (1 entry).
+  // CHECK-NEXT: 0 | void vdtors::Z::z()
 
-  // VDTORS-U: VFTable for 'vdtors::X' in 'vdtors::W' in 'vdtors::U' (2 entries).
-  // VDTORS-U-NEXT: 0 | vdtors::U::~U() [scalar deleting]
-  // VDTORS-U-NEXT:     [this adjustment: -4 non-virtual]
-  // VDTORS-U-NEXT: 1 | void vdtors::X::zzz()
+  // CHECK-LABEL: VFTable for 'vdtors::X' in 'vdtors::W' in 'vdtors::U' (2 entries).
+  // CHECK-NEXT: 0 | vdtors::U::~U() [scalar deleting]
+  // CHECK-NEXT:     [this adjustment: -4 non-virtual]
+  // CHECK-NEXT: 1 | void vdtors::X::zzz()
 
-  // VDTORS-U: Thunks for 'vdtors::W::~W()' (1 entry).
-  // VDTORS-U-NEXT: 0 | [this adjustment: -4 non-virtual]
+  // CHECK-LABEL: Thunks for 'vdtors::U::~U()' (1 entry).
+  // CHECK-NEXT: 0 | [this adjustment: -4 non-virtual]
 
-  // VDTORS-U: VFTable indices for 'vdtors::U' (1 entries).
-  // VDTORS-U-NEXT: -- accessible via vbtable index 1, vfptr at offset 4 --
-  // VDTORS-U-NEXT: 0 | vdtors::U::~U() [scalar deleting]
+  // CHECK-LABEL: VFTable indices for 'vdtors::U' (1 entry).
+  // CHECK-NEXT: -- accessible via vbtable index 1, vfptr at offset 4 --
+  // CHECK-NEXT: 0 | vdtors::U::~U() [scalar deleting]
   virtual ~U();
 };
 
 U u;
+void use(U *obj) { delete obj; }
 
 struct V : virtual W {
-  // VDTORS-V: VFTable for 'vdtors::Z' in 'vdtors::W' in 'vdtors::V' (1 entries).
-  // VDTORS-V-NEXT: 0 | void vdtors::Z::z()
+  // CHECK-LABEL: VFTable for 'vdtors::Z' in 'vdtors::W' in 'vdtors::V' (1 entry).
+  // CHECK-NEXT: 0 | void vdtors::Z::z()
 
-  // VDTORS-V: VFTable for 'vdtors::X' in 'vdtors::W' in 'vdtors::V' (2 entries).
-  // VDTORS-V-NEXT: 0 | vdtors::V::~V() [scalar deleting]
-  // VDTORS-V-NEXT:     [this adjustment: -4 non-virtual]
-  // VDTORS-V-NEXT: 1 | void vdtors::X::zzz()
+  // CHECK-LABEL: VFTable for 'vdtors::X' in 'vdtors::W' in 'vdtors::V' (2 entries).
+  // CHECK-NEXT: 0 | vdtors::V::~V() [scalar deleting]
+  // CHECK-NEXT:     [this adjustment: -4 non-virtual]
+  // CHECK-NEXT: 1 | void vdtors::X::zzz()
 
-  // VDTORS-V: Thunks for 'vdtors::W::~W()' (1 entry).
-  // VDTORS-V-NEXT: 0 | [this adjustment: -4 non-virtual]
+  // CHECK-LABEL: Thunks for 'vdtors::V::~V()' (1 entry).
+  // CHECK-NEXT: 0 | [this adjustment: -4 non-virtual]
 
-  // VDTORS-V: VFTable indices for 'vdtors::V' (1 entries).
-  // VDTORS-V-NEXT: -- accessible via vbtable index 1, vfptr at offset 4 --
-  // VDTORS-V-NEXT: 0 | vdtors::V::~V() [scalar deleting]
+  // CHECK-LABEL: VFTable indices for 'vdtors::V' (1 entry).
+  // CHECK-NEXT: -- accessible via vbtable index 1, vfptr at offset 4 --
+  // CHECK-NEXT: 0 | vdtors::V::~V() [scalar deleting]
 };
 
 V v;
+void use(V *obj) { delete obj; }
 
 struct T : virtual X {
   virtual ~T();
 };
 
 struct P : T, Y {
-  // VDTORS-P: VFTable for 'vdtors::X' in 'vdtors::T' in 'vdtors::P' (2 entries).
-  // VDTORS-P-NEXT: 0 | vdtors::P::~P() [scalar deleting]
-  // VDTORS-P-NEXT: 1 | void vdtors::X::zzz()
+  // CHECK-LABEL: VFTable for 'vdtors::X' in 'vdtors::T' in 'vdtors::P' (2 entries).
+  // CHECK-NEXT: 0 | vdtors::P::~P() [scalar deleting]
+  // CHECK-NEXT: 1 | void vdtors::X::zzz()
 
-  // VDTORS-P-NOT: Thunks for 'vdtors::P::~P()'
+  // CHECK-NOT: Thunks for 'vdtors::P::~P()'
   virtual ~P();
 };
 
 P p;
+void use(P *obj) { delete obj; }
 
+struct Q {
+  virtual ~Q();
+};
+
+// PR19172: Yet another diamond we miscompiled.
+struct R : virtual Q, X {
+  // CHECK-LABEL: VFTable for 'vdtors::Q' in 'vdtors::R' (1 entry).
+  // CHECK-NEXT: 0 | vdtors::R::~R() [scalar deleting]
+  // CHECK-NEXT:     [this adjustment: -8 non-virtual]
+
+  // CHECK-LABEL: Thunks for 'vdtors::R::~R()' (1 entry).
+  // CHECK-NEXT: 0 | [this adjustment: -8 non-virtual]
+
+  // CHECK-LABEL: VFTable for 'vdtors::X' in 'vdtors::R' (2 entries).
+  // CHECK-NEXT: 0 | vdtors::R::~R() [scalar deleting]
+  // CHECK-NEXT: 1 | void vdtors::X::zzz()
+
+  // CHECK-LABEL: VFTable indices for 'vdtors::R' (1 entry).
+  // CHECK-NEXT: 0 | vdtors::R::~R() [scalar deleting]
+  virtual ~R();
+};
+
+R r;
+void use(R *obj) { delete obj; }
 }
 
 namespace return_adjustment {
@@ -526,50 +608,159 @@
 };
 
 struct W : Z {
-  // RET-W: VFTable for 'return_adjustment::Z' in 'return_adjustment::W' (2 entries).
-  // RET-W-NEXT: 0 | return_adjustment::X *return_adjustment::W::foo()
-  // RET-W-NEXT:     [return adjustment: vbase #1, 0 non-virtual]
-  // RET-W-NEXT: 1 | return_adjustment::X *return_adjustment::W::foo()
+  // CHECK-LABEL: VFTable for 'return_adjustment::Z' in 'return_adjustment::W' (2 entries).
+  // CHECK-NEXT: 0 | return_adjustment::X *return_adjustment::W::foo()
+  // CHECK-NEXT:     [return adjustment (to type 'struct A *'): vbase #1, 0 non-virtual]
+  // CHECK-NEXT: 1 | return_adjustment::X *return_adjustment::W::foo()
 
-  // RET-W: VFTable indices for 'return_adjustment::W' (1 entries).
-  // RET-W-NEXT: 1 | return_adjustment::X *return_adjustment::W::foo()
+  // CHECK-LABEL: Thunks for 'return_adjustment::X *return_adjustment::W::foo()' (1 entry).
+  // CHECK-NEXT: 0 | [return adjustment (to type 'struct A *'): vbase #1, 0 non-virtual]
+
+  // CHECK-LABEL: VFTable indices for 'return_adjustment::W' (1 entry).
+  // CHECK-NEXT: 1 | return_adjustment::X *return_adjustment::W::foo()
 
   virtual X* foo();
 };
 
-W y;
+W w;
+void use(W *obj) { obj->foo(); }
 
 struct T : W {
-  // RET-T: VFTable for 'return_adjustment::Z' in 'return_adjustment::W' in 'return_adjustment::T' (3 entries).
-  // RET-T-NEXT: 0 | return_adjustment::Y *return_adjustment::T::foo()
-  // RET-T-NEXT:     [return adjustment: vbase #1, 0 non-virtual]
-  // RET-T-NEXT: 1 | return_adjustment::Y *return_adjustment::T::foo()
-  // RET-T-NEXT:     [return adjustment: vbase #2, 0 non-virtual]
-  // RET-T-NEXT: 2 | return_adjustment::Y *return_adjustment::T::foo()
+  // CHECK-LABEL: VFTable for 'return_adjustment::Z' in 'return_adjustment::W' in 'return_adjustment::T' (3 entries).
+  // CHECK-NEXT: 0 | return_adjustment::Y *return_adjustment::T::foo()
+  // CHECK-NEXT:     [return adjustment (to type 'struct A *'): vbase #1, 0 non-virtual]
+  // CHECK-NEXT: 1 | return_adjustment::Y *return_adjustment::T::foo()
+  // CHECK-NEXT:     [return adjustment (to type 'struct return_adjustment::X *'): vbase #2, 0 non-virtual]
+  // CHECK-NEXT: 2 | return_adjustment::Y *return_adjustment::T::foo()
 
-  // RET-T: VFTable indices for 'return_adjustment::T' (1 entries).
-  // RET-T-NEXT: 2 | return_adjustment::Y *return_adjustment::T::foo()
+  // CHECK-LABEL: Thunks for 'return_adjustment::Y *return_adjustment::T::foo()' (2 entries).
+  // CHECK-NEXT: 0 | [return adjustment (to type 'struct A *'): vbase #1, 0 non-virtual]
+  // CHECK-NEXT: 1 | [return adjustment (to type 'struct return_adjustment::X *'): vbase #2, 0 non-virtual]
+
+  // CHECK-LABEL: VFTable indices for 'return_adjustment::T' (1 entry).
+  // CHECK-NEXT: 2 | return_adjustment::Y *return_adjustment::T::foo()
 
   virtual Y* foo();
 };
 
 T t;
+void use(T *obj) { obj->foo(); }
 
 struct U : virtual A {
   virtual void g();  // adds a vfptr
 };
 
 struct V : Z {
-  // RET-V: VFTable for 'return_adjustment::Z' in 'return_adjustment::V' (2 entries).
-  // RET-V-NEXT: 0 | return_adjustment::U *return_adjustment::V::foo()
-  // RET-V-NEXT:     [return adjustment: vbptr at offset 4, vbase #1, 0 non-virtual]
-  // RET-V-NEXT: 1 | return_adjustment::U *return_adjustment::V::foo()
+  // CHECK-LABEL: VFTable for 'return_adjustment::Z' in 'return_adjustment::V' (2 entries).
+  // CHECK-NEXT: 0 | return_adjustment::U *return_adjustment::V::foo()
+  // CHECK-NEXT:     [return adjustment (to type 'struct A *'): vbptr at offset 4, vbase #1, 0 non-virtual]
+  // CHECK-NEXT: 1 | return_adjustment::U *return_adjustment::V::foo()
 
-  // RET-V: VFTable indices for 'return_adjustment::V' (1 entries).
-  // RET-V-NEXT: 1 | return_adjustment::U *return_adjustment::V::foo()
+  // CHECK-LABEL: Thunks for 'return_adjustment::U *return_adjustment::V::foo()' (1 entry).
+  // CHECK-NEXT: 0 | [return adjustment (to type 'struct A *'): vbptr at offset 4, vbase #1, 0 non-virtual]
+
+  // CHECK-LABEL: VFTable indices for 'return_adjustment::V' (1 entry).
+  // CHECK-NEXT: 1 | return_adjustment::U *return_adjustment::V::foo()
 
   virtual U* foo();
 };
 
 V v;
+void use(V *obj) { obj->foo(); }
+}
+
+namespace pr17748 {
+struct A {
+  virtual void f() {}
+};
+
+struct B : virtual A {
+  B() {}
+};
+
+struct C : virtual B, A {
+  C() {}
+};
+C c;
+
+// MANGLING-DAG: @"\01??_7A@pr17748@@6B@"
+// MANGLING-DAG: @"\01??_7B@pr17748@@6B@"
+// MANGLING-DAG: @"\01??_7C@pr17748@@6BA@1@@"
+// MANGLING-DAG: @"\01??_7C@pr17748@@6BB@1@@"
+}
+
+namespace pr19066 {
+struct X : virtual B {};
+
+struct Y : virtual X, B {
+  Y();
+  // CHECK-LABEL: VFTable for 'B' in 'pr19066::X' in 'pr19066::Y' (1 entry).
+  // CHECK-NEXT:  0 | void B::g()
+
+  // CHECK-LABEL: VFTable for 'B' in 'pr19066::Y' (1 entry).
+  // CHECK-NEXT:  0 | void B::g()
+};
+
+Y::Y() {}
+}
+
+namespace pr19240 {
+struct A {
+  virtual void c();
+};
+
+struct B : virtual A {
+  virtual void c();
+};
+
+struct C { };
+
+struct D : virtual A, virtual C, B {};
+
+D obj;
+
+// Each MDC only has one vftable.
+
+// MANGLING-DAG: @"\01??_7D@pr19240@@6B@"
+// MANGLING-DAG: @"\01??_7A@pr19240@@6B@"
+// MANGLING-DAG: @"\01??_7B@pr19240@@6B@"
+
+}
+
+namespace pr19408 {
+// This test is a non-vtordisp version of the reproducer for PR19408.
+struct X : virtual A {
+  int x;
+};
+
+struct Y : X {
+  virtual void f();
+  int y;
+};
+
+struct Z : Y {
+  // CHECK-LABEL: VFTable for 'A' in 'pr19408::X' in 'pr19408::Y' in 'pr19408::Z' (2 entries).
+  // CHECK-NEXT:   0 | void pr19408::Y::f()
+  // CHECK-NEXT:       [this adjustment: -4 non-virtual]
+  // CHECK-NEXT:   1 | void A::z()
+
+  Z();
+  int z;
+  // MANGLING-DAG: @"\01??_7Z@pr19408@@6B@" = {{.*}}@"\01?f@Y@pr19408@@W3AEXXZ"
+};
+
+Z::Z() {}
+
+struct W : B, Y {
+  // CHECK-LABEL: VFTable for 'A' in 'pr19408::X' in 'pr19408::Y' in 'pr19408::W' (2 entries).
+  // CHECK-NEXT:   0 | void pr19408::Y::f()
+  // CHECK-NEXT:       [this adjustment: -4 non-virtual]
+  // CHECK-NEXT:   1 | void A::z()
+
+  W();
+  int w;
+  // MANGLING-DAG: @"\01??_7W@pr19408@@6BY@1@@" = {{.*}}@"\01?f@Y@pr19408@@W3AEXXZ"
+};
+
+W::W() {}
 }
diff --git a/test/CodeGenCXX/microsoft-compatibility.cpp b/test/CodeGenCXX/microsoft-compatibility.cpp
new file mode 100644
index 0000000..297184a
--- /dev/null
+++ b/test/CodeGenCXX/microsoft-compatibility.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 %s -triple i686-pc-win32 -std=c++11 -fms-compatibility -emit-llvm -o - | FileCheck %s
+
+template<class T>
+void destroy(T *p) {
+  p->~T();
+}
+
+extern "C" void f() {
+  int a;
+  destroy((void*)&a);
+}
+
+// CHECK-LABEL: define void @f()
+// CHECK: call void @"\01??$destroy@X@@YAXPAX@Z"
+// CHECK: ret void
+
+// CHECK-LABEL: define linkonce_odr void @"\01??$destroy@X@@YAXPAX@Z"(i8* %p)
+//    The pseudo-dtor expr should not generate calls to anything.
+// CHECK-NOT: call
+// CHECK-NOT: invoke
+// CHECK: ret void
diff --git a/test/CodeGenCXX/microsoft-interface.cpp b/test/CodeGenCXX/microsoft-interface.cpp
index 419075a..c030d1d 100644
--- a/test/CodeGenCXX/microsoft-interface.cpp
+++ b/test/CodeGenCXX/microsoft-interface.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -fms-extensions -Wno-microsoft -triple=i386-pc-win32 -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -fms-extensions -Wno-microsoft -triple=i386-pc-windows-gnu -emit-llvm %s -o - | FileCheck %s
 
 __interface I {
   int test() {
@@ -20,24 +20,21 @@
 // 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-LABEL: define i32 @_Z2fnv()
-// CHECK:   call void @_ZN1SC1Ev(%struct.S* %s)
-// CHECK:   %{{[.0-9A-Z_a-z]+}} = call i32 @_ZN1S4testEv(%struct.S* %s)
+// CHECK:   call x86_thiscallcc void @_ZN1SC1Ev(%struct.S* %s)
+// CHECK:   %{{[.0-9A-Z_a-z]+}} = call x86_thiscallcc i32 @_ZN1S4testEv(%struct.S* %s)
 
-// CHECK-LABEL: define linkonce_odr void @_ZN1SC1Ev(%struct.S* %this)
-// CHECK:   call void @_ZN1SC2Ev(%struct.S* %{{[.0-9A-Z_a-z]+}})
+// CHECK-LABEL: define linkonce_odr x86_thiscallcc void @_ZN1SC1Ev(%struct.S* %this)
+// CHECK:   call x86_thiscallcc void @_ZN1SC2Ev(%struct.S* %{{[.0-9A-Z_a-z]+}})
 
-// CHECK-LABEL: define linkonce_odr i32 @_ZN1S4testEv(%struct.S* %this)
-// CHECK:   %{{[.0-9A-Z_a-z]+}} = call i32 @_ZN1I4testEv(%__interface.I* %{{[.0-9A-Z_a-z]+}})
+// CHECK-LABEL: define linkonce_odr x86_thiscallcc i32 @_ZN1S4testEv(%struct.S* %this)
+// CHECK:   %{{[.0-9A-Z_a-z]+}} = call x86_thiscallcc i32 @_ZN1I4testEv(%__interface.I* %{{[.0-9A-Z_a-z]+}})
 
-// CHECK-LABEL: define linkonce_odr i32 @_ZN1I4testEv(%__interface.I* %this)
+// CHECK-LABEL: define linkonce_odr x86_thiscallcc i32 @_ZN1I4testEv(%__interface.I* %this)
 // CHECK:   ret i32 1
 
-// CHECK-LABEL: define linkonce_odr void @_ZN1SC2Ev(%struct.S* %this)
-// CHECK:   call void @_ZN1IC2Ev(%__interface.I* %{{[.0-9A-Z_a-z]+}})
+// 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 i8** getelementptr inbounds ([3 x i8*]* @_ZTV1S, i64 0, i64 2), i8*** %{{[.0-9A-Z_a-z]+}}
 
-// CHECK-LABEL: define linkonce_odr void @_ZN1IC2Ev(%__interface.I* %this)
+// CHECK-LABEL: define linkonce_odr x86_thiscallcc void @_ZN1IC2Ev(%__interface.I* %this)
 // CHECK:   store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1I, i64 0, i64 2), i8*** %{{[.0-9A-Z_a-z]+}}
-
-// CHECK-NOT-LABEL: define linkonce_odr %__interface.I* @_ZN1IaSERKS_(%__interface.I* %this, %__interface.I*)
-// CHECK-NOT-LABEL: define linkonce_odr %__interface.I* @_ZN1IaSEOS_(%__interface.I* %this, %__interface.I*)
diff --git a/test/CodeGenCXX/microsoft-new.cpp b/test/CodeGenCXX/microsoft-new.cpp
index 48e93d4..7857e47 100644
--- a/test/CodeGenCXX/microsoft-new.cpp
+++ b/test/CodeGenCXX/microsoft-new.cpp
@@ -1,39 +1,39 @@
-// RUN: %clang_cc1 -triple i686-pc-win32 -fms-compatibility %s -emit-llvm -o - | FileCheck %s

-

-#include <stddef.h>

-

-struct arbitrary_t {} arbitrary;

-void *operator new(size_t size, arbitrary_t);

-

-struct arbitrary2_t {} arbitrary2;

-void *operator new[](size_t size, arbitrary2_t);

-

-namespace PR13164 {

-  void f() {

-	// MSVC will fall back on the non-array operator new.

-    void *a;

-    int *p = new(arbitrary) int[4];

-    // CHECK: call i8* @_Znwj11arbitrary_t(i32 16, %struct.arbitrary_t*

-  }

-

-  struct S {

-    void *operator new[](size_t size, arbitrary_t);

-  };

-

-  void g() {

-    S *s = new(arbitrary) S[2];

-    // CHECK: call i8* @_ZN7PR131641SnaEj11arbitrary_t(i32 2, %struct.arbitrary_t*

-    S *s1 = new(arbitrary) S;

-    // CHECK: call i8* @_Znwj11arbitrary_t(i32 1, %struct.arbitrary_t*

-  }

-

-  struct T {

-    void *operator new(size_t size, arbitrary2_t);

-  };

-

-  void h() {

-    // This should still call the global operator new[].

-    T *t = new(arbitrary2) T[2];

-    // CHECK: call i8* @_Znaj12arbitrary2_t(i32 2, %struct.arbitrary2_t*

-  }

-}

+// RUN: %clang_cc1 -triple i686-pc-win32 -fms-compatibility %s -emit-llvm -o - | FileCheck %s
+
+#include <stddef.h>
+
+struct arbitrary_t {} arbitrary;
+void *operator new(size_t size, arbitrary_t);
+
+struct arbitrary2_t {} arbitrary2;
+void *operator new[](size_t size, arbitrary2_t);
+
+namespace PR13164 {
+  void f() {
+	// MSVC will fall back on the non-array operator new.
+    void *a;
+    int *p = new(arbitrary) int[4];
+    // CHECK: call i8* @"\01??2@YAPAXIUarbitrary_t@@@Z"(i32 16, %struct.arbitrary_t*
+  }
+
+  struct S {
+    void *operator new[](size_t size, arbitrary_t);
+  };
+
+  void g() {
+    S *s = new(arbitrary) S[2];
+    // CHECK: call i8* @"\01??_US@PR13164@@SAPAXIUarbitrary_t@@@Z"(i32 2, %struct.arbitrary_t*
+    S *s1 = new(arbitrary) S;
+    // CHECK: call i8* @"\01??2@YAPAXIUarbitrary_t@@@Z"(i32 1, %struct.arbitrary_t*
+  }
+
+  struct T {
+    void *operator new(size_t size, arbitrary2_t);
+  };
+
+  void h() {
+    // This should still call the global operator new[].
+    T *t = new(arbitrary2) T[2];
+    // CHECK: call i8* @"\01??_U@YAPAXIUarbitrary2_t@@@Z"(i32 2, %struct.arbitrary2_t*
+  }
+}
diff --git a/test/CodeGenCXX/microsoft-no-rtti-data.cpp b/test/CodeGenCXX/microsoft-no-rtti-data.cpp
new file mode 100644
index 0000000..d4002c2
--- /dev/null
+++ b/test/CodeGenCXX/microsoft-no-rtti-data.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 %s -fno-rtti-data -triple=i386-pc-win32 -o - -emit-llvm | FileCheck %s
+
+// vftable shouldn't have RTTI data in it.
+// CHECK: @"\01??_7S@@6B@" = linkonce_odr unnamed_addr constant [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GS@@UAEPAXI@Z" to i8*)]
+
+struct type_info;
+namespace std { using ::type_info; }
+
+struct S {
+  virtual ~S();
+} s;
+
+struct U : S {
+  virtual ~U();
+};
+
+extern S *getS();
+
+const std::type_info &ti = typeid(*getS());
+const U &u = dynamic_cast<U &>(*getS());
+// CHECK: call i8* @__RTDynamicCast(i8* %{{.+}}, i32 0, i8* bitcast ({{.*}} @"\01??_R0?AUS@@@8" to i8*), i8* bitcast ({{.*}} @"\01??_R0?AUU@@@8" to i8*), i32 1)
diff --git a/test/CodeGenCXX/microsoft-templ-uuidof.cpp b/test/CodeGenCXX/microsoft-templ-uuidof.cpp
new file mode 100644
index 0000000..0ee3908
--- /dev/null
+++ b/test/CodeGenCXX/microsoft-templ-uuidof.cpp
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -DDEFINE_GUID -triple=i386-pc-win32 -fms-extensions | FileCheck %s --check-prefix=CHECK
+
+struct _GUID;
+
+template <typename>
+struct X {
+};
+
+struct __declspec(uuid("{AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA}")) A {};
+
+struct B {};
+
+template <>
+struct __declspec(uuid("{BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBB}")) X<B> {};
+
+struct __declspec(uuid("{CCCCCCCC-CCCC-CCCC-CCCC-CCCCCCCCCCCC}")) C {};
+
+const _GUID &xa = __uuidof(X<A>);
+// CHECK-DAG:  @"\01?xa@@3ABU_GUID@@B" = {{.*}} @_GUID_aaaaaaaa_aaaa_aaaa_aaaa_aaaaaaaaaaaa
+
+const _GUID &xb = __uuidof(X<B>);
+// CHECK-DAG:  @"\01?xb@@3ABU_GUID@@B" = {{.*}} @_GUID_bbbbbbbb_bbbb_bbbb_bbbb_bbbbbbbbbbbb
+const _GUID &xc = __uuidof(X<C>);
+// CHECK-DAG:  @"\01?xc@@3ABU_GUID@@B" = {{.*}} @_GUID_cccccccc_cccc_cccc_cccc_cccccccccccc
+
+template <>
+struct __declspec(uuid("{DDDDDDDD-DDDD-DDDD-DDDD-DDDDDDDDDDDD}")) X<C> {};
+
+template <typename>
+struct __declspec(uuid("{EEEEEEEE-EEEE-EEEE-EEEE-EEEEEEEEEEEE}")) Y {
+};
+
+const _GUID &xd = __uuidof(X<C>);
+// CHECK-DAG:  @"\01?xd@@3ABU_GUID@@B" = {{.*}} @_GUID_dddddddd_dddd_dddd_dddd_dddddddddddd
+
+const _GUID &yd = __uuidof(Y<X<C> >);
+// CHECK-DAG:  @"\01?yd@@3ABU_GUID@@B" = {{.*}} @_GUID_dddddddd_dddd_dddd_dddd_dddddddddddd
diff --git a/test/CodeGenCXX/microsoft-uuidof.cpp b/test/CodeGenCXX/microsoft-uuidof.cpp
index ab3d9b6..d57ca83 100644
--- a/test/CodeGenCXX/microsoft-uuidof.cpp
+++ b/test/CodeGenCXX/microsoft-uuidof.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -DDEFINE_GUID -triple=i386-pc-win32 -fms-extensions | FileCheck %s --check-prefix=CHECK-DEFINE-GUID
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 -fms-extensions | FileCheck %s
-// RUN: %clang_cc1 -emit-llvm %s -o - -DDEFINE_GUID -DWRONG_GUID -triple=i386-pc-win32 -fms-extensions | FileCheck %s --check-prefix=CHECK-DEFINE-WRONG-GUID
+// RUN: %clang_cc1 -emit-llvm %s -o - -DDEFINE_GUID -triple=i386-pc-linux -fms-extensions | FileCheck %s --check-prefix=CHECK-DEFINE-GUID
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-linux -fms-extensions | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -DDEFINE_GUID -DWRONG_GUID -triple=i386-pc-linux -fms-extensions | FileCheck %s --check-prefix=CHECK-DEFINE-WRONG-GUID
 
 #ifdef DEFINE_GUID
 struct _GUID {
diff --git a/test/CodeGenCXX/mingw-new-abi.cpp b/test/CodeGenCXX/mingw-new-abi.cpp
new file mode 100644
index 0000000..2b05253
--- /dev/null
+++ b/test/CodeGenCXX/mingw-new-abi.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -emit-llvm -triple i386-pc-mingw32 %s -o - | FileCheck --check-prefix=MINGW %s
+// RUN: %clang_cc1 -emit-llvm -triple i386-pc-cygwin %s -o - | FileCheck --check-prefix=CYGWIN %s
+
+namespace test1 {
+  struct foo {
+    //  MINGW: declare x86_thiscallcc void @_ZN5test13foo1fEv
+    //  CYGWIN: declare void @_ZN5test13foo1fEv
+    void f();
+  };
+  void g(foo *x) {
+    x->f();
+  }
+}
diff --git a/test/CodeGenCXX/mips-size_t-ptrdiff_t.cpp b/test/CodeGenCXX/mips-size_t-ptrdiff_t.cpp
new file mode 100644
index 0000000..92e704a
--- /dev/null
+++ b/test/CodeGenCXX/mips-size_t-ptrdiff_t.cpp
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -x c++ -emit-llvm -triple=mips-unknown-linux-gnu < %s | FileCheck --check-prefix=O32 %s
+// RUN: %clang_cc1 -x c++ -emit-llvm -triple=mips64-unknown-linux-gnu -target-abi n32 < %s | FileCheck --check-prefix=N32 %s
+// RUN: %clang_cc1 -x c++ -emit-llvm -triple=mips64-unknown-linux-gnu -target-abi n64 < %s | FileCheck --check-prefix=N64 %s
+
+// Test that the size_t is correct for the ABI. It's not sufficient to be the
+// correct size, it must be the same type for correct name mangling.
+
+long *alloc_long() {
+  long *rv = new long; // size_t is implicit in the new operator
+  return rv;
+}
+// O32-LABEL: define i32* @_Z10alloc_longv()
+// O32: call noalias i8* @_Znwj(i32 4)
+
+// N32-LABEL: define i32* @_Z10alloc_longv()
+// N32: call noalias i8* @_Znwj(i32 4)
+
+// N64-LABEL: define i64* @_Z10alloc_longv()
+// N64: call noalias i8* @_Znwm(i64 8)
+
+long *alloc_long_array() {
+  long *rv = new long[2];
+  return rv;
+}
+
+// O32-LABEL: define i32* @_Z16alloc_long_arrayv()
+// O32: call noalias i8* @_Znaj(i32 8)
+
+// N32-LABEL: define i32* @_Z16alloc_long_arrayv()
+// N32: call noalias i8* @_Znaj(i32 8)
+
+// N64-LABEL: define i64* @_Z16alloc_long_arrayv()
+// N64: call noalias i8* @_Znam(i64 16)
+
+#include <stddef.h>
+
+void size_t_arg(size_t a) {
+}
+
+// O32-LABEL: _Z10size_t_argj
+// N32-LABEL: _Z10size_t_argj
+// N64-LABEL: _Z10size_t_argm
+
+void ptrdiff_t_arg(ptrdiff_t a) {
+}
+
+// O32-LABEL: _Z13ptrdiff_t_argi
+// N32-LABEL: _Z13ptrdiff_t_argi
+// N64-LABEL: _Z13ptrdiff_t_argl
diff --git a/test/CodeGenCXX/ms-integer-static-data-members-exported.cpp b/test/CodeGenCXX/ms-integer-static-data-members-exported.cpp
new file mode 100644
index 0000000..3f868f3
--- /dev/null
+++ b/test/CodeGenCXX/ms-integer-static-data-members-exported.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -emit-llvm -triple=i386-pc-win32 -fms-compatibility %s -o - | FileCheck %s
+
+enum Enum { zero, one, two };
+
+struct __declspec(dllexport) S {
+  // In MS compatibility mode, this counts as a definition.
+  // Since it is exported, it must be emitted even if it's unreferenced.
+  static const short x = 42;
+
+  // This works for enums too.
+  static const Enum y = two;
+
+  struct NonExported {
+    // dllexport is not inherited by this nested class.
+    // Since z is not referenced, it should not be emitted.
+    static const int z = 42;
+  };
+};
+
+// CHECK: @"\01?x@S@@2FB" = weak_odr dllexport constant i16 42, align 2
+// CHECK: @"\01?y@S@@2W4Enum@@B" = weak_odr dllexport constant i32 2, align 4
+// CHECK-NOT: NonExported
diff --git a/test/CodeGenCXX/ms-integer-static-data-members.cpp b/test/CodeGenCXX/ms-integer-static-data-members.cpp
new file mode 100644
index 0000000..b02b679
--- /dev/null
+++ b/test/CodeGenCXX/ms-integer-static-data-members.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -emit-llvm -triple=i386-pc-win32 -fms-compatibility %s -o - | FileCheck %s
+// RUN: %clang_cc1 -DINLINE_INIT -emit-llvm -triple=i386-pc-win32 -fms-compatibility %s -o - | FileCheck %s --check-prefix=CHECK-INLINE
+// RUN: %clang_cc1 -DREAL_DEFINITION -emit-llvm -triple=i386-pc-win32 -fms-compatibility %s -o - | FileCheck %s --check-prefix=CHECK-OUTOFLINE
+// RUN: %clang_cc1 -DINLINE_INIT -DREAL_DEFINITION -emit-llvm -triple=i386-pc-win32 -fms-compatibility %s -o - | FileCheck %s --check-prefix=CHECK-INLINE
+
+struct S {
+  // For MS ABI, we emit a linkonce_odr definition here, even though it's really just a declaration.
+#ifdef INLINE_INIT
+  static const int x = 5;
+#else
+  static const int x;
+#endif
+};
+
+const int *f() {
+  return &S::x;
+};
+
+#ifdef REAL_DEFINITION
+#ifdef INLINE_INIT
+const int S::x;
+#else
+const int S::x = 5;
+#endif
+#endif
+
+
+// Inline initialization.
+// CHECK-INLINE: @"\01?x@S@@2HB" = linkonce_odr constant i32 5, align 4
+
+// Out-of-line initialization.
+// CHECK-OUTOFLINE: @"\01?x@S@@2HB" = constant i32 5, align 4
+
+// No initialization.
+// CHECK: @"\01?x@S@@2HB" = external constant i32
diff --git a/test/CodeGenCXX/ms_wide_predefined_expr.cpp b/test/CodeGenCXX/ms_wide_predefined_expr.cpp
index 5f0bcde..3949d39 100644
--- a/test/CodeGenCXX/ms_wide_predefined_expr.cpp
+++ b/test/CodeGenCXX/ms_wide_predefined_expr.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 %s -fms-extensions -triple i686-pc-win32 -emit-llvm -o - | FileCheck %s
 
-// CHECK: @L__FUNCTION__._Z4funcv = private constant [5 x i16] [i16 102, i16 117, i16 110, i16 99, i16 0], align 2
+// CHECK: @"\01??_C@_19DPFBEKIN@?$AAf?$AAu?$AAn?$AAc?$AA?$AA@" = linkonce_odr unnamed_addr constant [5 x i16] [i16 102, i16 117, i16 110, i16 99, i16 0], align 2
 
 void wprint(const wchar_t*);
 
diff --git a/test/CodeGenCXX/new-array-init.cpp b/test/CodeGenCXX/new-array-init.cpp
index 0e925c0a..65123ea 100644
--- a/test/CodeGenCXX/new-array-init.cpp
+++ b/test/CodeGenCXX/new-array-init.cpp
@@ -6,8 +6,8 @@
   // CHECK: store i32 1
   // CHECK: store i32 2
   // CHECK: store i32 3
-  // CHECK: icmp eq i32*
-  // CHECK-NEXT: br i1
+  // CHECK: sub {{.*}}, 12
+  // CHECK: call void @llvm.memset
   new int[n] { 1, 2, 3 };
 }
 
@@ -31,3 +31,18 @@
   new int[4] { 1, 2, 3 };
   // CHECK: ret void
 }
+
+// CHECK-LABEL: define void @_Z22check_array_value_initv
+void check_array_value_init() {
+  struct S;
+  new (int S::*[3][4][5]) ();
+
+  // CHECK: call noalias i8* @_Zna{{.}}(i{{32 240|64 480}})
+  // CHECK: getelementptr inbounds i{{32|64}}* {{.*}}, i{{32|64}} 60
+
+  // CHECK: phi
+  // CHECK: store i{{32|64}} -1,
+  // CHECK: getelementptr inbounds i{{32|64}}* {{.*}}, i{{32|64}} 1
+  // CHECK: icmp eq
+  // CHECK: br i1
+}
diff --git a/test/CodeGenCXX/new.cpp b/test/CodeGenCXX/new.cpp
index 91da77a..862161b 100644
--- a/test/CodeGenCXX/new.cpp
+++ b/test/CodeGenCXX/new.cpp
@@ -2,6 +2,9 @@
 
 typedef __typeof__(sizeof(0)) size_t;
 
+// Declare an 'operator new' template to tickle a bug in __builtin_operator_new.
+template<typename T> void *operator new(size_t, int (*)(T));
+
 // Ensure that this declaration doesn't cause operator new to lose its
 // 'noalias' attribute.
 void *operator new[](size_t);
@@ -33,7 +36,6 @@
 void operator delete(void *, const std::nothrow_t &) throw();
 void operator delete[](void *, const std::nothrow_t &) throw();
 
-
 void t2(int* a) {
   int* b = new (a) int;
 }
@@ -285,7 +287,7 @@
 namespace N3664 {
   struct S { S() throw(int); };
 
-  // CHECK-LABEL-LABEL: define void @_ZN5N36641fEv
+  // CHECK-LABEL: define void @_ZN5N36641fEv
   void f() {
     // CHECK: call noalias i8* @_Znwm(i64 4) [[ATTR_BUILTIN_NEW:#[^ ]*]]
     int *p = new int;
@@ -307,7 +309,7 @@
   // FIXME: Can we mark this noalias?
   // CHECK: declare i8* @_ZnamRKSt9nothrow_t(i64, {{.*}}) [[ATTR_NOBUILTIN_NOUNWIND]]
 
-  // CHECK-LABEL-LABEL: define void @_ZN5N36641gEv
+  // CHECK-LABEL: define void @_ZN5N36641gEv
   void g() {
     // It's OK for there to be attributes here, so long as we don't have a
     // 'builtin' attribute.
@@ -326,6 +328,15 @@
   }
 }
 
+namespace builtins {
+  // CHECK-LABEL: define void @_ZN8builtins1fEv
+  void f() {
+    // CHECK: call noalias i8* @_Znwm(i64 4) [[ATTR_BUILTIN_NEW]]
+    // CHECK: call void @_ZdlPv({{.*}}) [[ATTR_BUILTIN_DELETE]]
+    __builtin_operator_delete(__builtin_operator_new(4));
+  }
+}
+
 // CHECK-DAG: attributes [[ATTR_NOBUILTIN]] = {{[{].*}} nobuiltin {{.*[}]}}
 // CHECK-DAG: attributes [[ATTR_NOBUILTIN_NOUNWIND]] = {{[{].*}} nobuiltin nounwind {{.*[}]}}
 
diff --git a/test/CodeGenCXX/no-elide-constructors.cpp b/test/CodeGenCXX/no-elide-constructors.cpp
new file mode 100644
index 0000000..ecb350f
--- /dev/null
+++ b/test/CodeGenCXX/no-elide-constructors.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -std=c++98 -triple i386-unknown-unknown -fno-elide-constructors -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-CXX98
+// RUN: %clang_cc1 -std=c++11 -triple i386-unknown-unknown -fno-elide-constructors -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-CXX11
+// RUN: %clang_cc1 -std=c++98 -triple i386-unknown-unknown -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-CXX98-ELIDE
+// RUN: %clang_cc1 -std=c++11 -triple i386-unknown-unknown -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-CXX11-ELIDE
+
+// Reduced from PR12208
+class X {
+public:
+  X();
+  X(const X&);
+#if __cplusplus >= 201103L
+  X(X&&);
+#endif
+  ~X();
+};
+
+// CHECK-LABEL: define void @_Z4Testv(
+X Test()
+{
+  X x;
+
+  // Check that the copy constructor for X is called with result variable as
+  // sret argument.
+  // CHECK-CXX98: call void @_ZN1XC1ERKS_(
+  // CHECK-CXX11: call void @_ZN1XC1EOS_(
+  // CHECK-CXX98-ELIDE-NOT: call void @_ZN1XC1ERKS_(
+  // CHECK-CXX11-ELIDE-NOT: call void @_ZN1XC1EOS_(
+
+  // Make sure that the destructor for X is called.
+  // FIXME: This call is present even in the -ELIDE runs, but is guarded by a
+  // branch that is never taken in those cases. We could generate better IR
+  // here.
+  // CHECK: call void @_ZN1XD1Ev(
+  return x;
+}
diff --git a/test/CodeGenCXX/noinline-template.cpp b/test/CodeGenCXX/noinline-template.cpp
index 51a84f7..3dd4366 100644
--- a/test/CodeGenCXX/noinline-template.cpp
+++ b/test/CodeGenCXX/noinline-template.cpp
@@ -1,9 +1,9 @@
-// RUN: %clang_cc1 %s  -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o - | FileCheck %s
 
 // This was a problem in Sema, but only shows up as noinline missing
 // in CodeGen.
 
-// CHECK: define linkonce_odr void @_ZN6VectorIiE13growStorageByEv(%struct.Vector* %this) [[NI:#[0-9]+]]
+// CHECK: define linkonce_odr {{.*}}void @_ZN6VectorIiE13growStorageByEv(%struct.Vector* %this) [[NI:#[0-9]+]]
 
 template <class Ty> struct Vector  {
   void growStorageBy();
diff --git a/test/CodeGenCXX/nrvo.cpp b/test/CodeGenCXX/nrvo.cpp
index b83dd72..aad287d 100644
--- a/test/CodeGenCXX/nrvo.cpp
+++ b/test/CodeGenCXX/nrvo.cpp
@@ -9,6 +9,14 @@
   ~X();
 };
 
+template<typename T> struct Y {
+  Y();
+  static Y f() {
+    Y y;
+    return y;
+  }
+};
+
 // CHECK-LABEL: define void @_Z5test0v
 // CHECK-EH-LABEL: define void @_Z5test0v
 X test0() {
@@ -108,12 +116,17 @@
 
 }
 
+// CHECK-LABEL: define void @_Z5test3b
 X test3(bool B) {
-  // FIXME: We don't manage to apply NRVO here, although we could.
-  {
+  // CHECK: tail call {{.*}} @_ZN1XC1Ev
+  // CHECK-NOT: call {{.*}} @_ZN1XC1ERKS_
+  // CHECK: call {{.*}} @_ZN1XC1Ev
+  // CHECK: call {{.*}} @_ZN1XC1ERKS_
+  if (B) {
     X y;
     return y;
   }
+  // FIXME: we should NRVO this variable too.
   X x;
   return x;
 }
@@ -156,9 +169,40 @@
   return a;
   // CHECK:      [[A:%.*]] = alloca [[X:%.*]], align 8
   // CHECK-NEXT: call {{.*}} @_ZN1XC1Ev([[X]]* [[A]])
-  // CHECK-NEXT: call {{.*}} @_ZN1XC1ERKS_([[X]]* {{%.*}}, [[X]]* [[A]])
+  // CHECK-NEXT: call {{.*}} @_ZN1XC1ERKS_([[X]]* {{%.*}}, [[X]]* dereferenceable({{[0-9]+}}) [[A]])
   // CHECK-NEXT: call {{.*}} @_ZN1XD1Ev([[X]]* [[A]])
   // CHECK-NEXT: ret void
 }
 
+// CHECK-LABEL: define void @_Z5test7b
+X test7(bool b) {
+  // CHECK: tail call {{.*}} @_ZN1XC1Ev
+  // CHECK-NEXT: ret
+  if (b) {
+    X x;
+    return x;
+  }
+  return X();
+}
+
+// CHECK-LABEL: define void @_Z5test8b
+X test8(bool b) {
+  // CHECK: tail call {{.*}} @_ZN1XC1Ev
+  // CHECK-NEXT: ret
+  if (b) {
+    X x;
+    return x;
+  } else {
+    X y;
+    return y;
+  }
+}
+
+Y<int> test9() {
+  Y<int>::f();
+}
+
+// CHECK-LABEL: define linkonce_odr void @_ZN1YIiE1fEv
+// CHECK: tail call {{.*}} @_ZN1YIiEC1Ev
+
 // CHECK-EH: attributes [[NR_NUW]] = { noreturn nounwind }
diff --git a/test/CodeGenCXX/pod-member-memcpys.cpp b/test/CodeGenCXX/pod-member-memcpys.cpp
index 5c79568..31d774c 100644
--- a/test/CodeGenCXX/pod-member-memcpys.cpp
+++ b/test/CodeGenCXX/pod-member-memcpys.cpp
@@ -108,59 +108,59 @@
 CALL_AO(PackedMembers)
 
 // Basic copy-assignment:
-// CHECK-LABEL: define linkonce_odr %struct.Basic* @_ZN5BasicaSERKS_(%struct.Basic* %this, %struct.Basic*)
+// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.Basic* @_ZN5BasicaSERKS_(%struct.Basic* %this, %struct.Basic* dereferenceable({{[0-9]+}}))
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
-// CHECK: call %struct.NonPOD* @_ZN6NonPODaSERKS_
+// CHECK: call dereferenceable({{[0-9]+}}) %struct.NonPOD* @_ZN6NonPODaSERKS_
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
 // CHECK: ret %struct.Basic*
 
 // PODMember copy-assignment:
-// CHECK-LABEL: define linkonce_odr %struct.PODMember* @_ZN9PODMemberaSERKS_(%struct.PODMember* %this, %struct.PODMember*)
+// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.PODMember* @_ZN9PODMemberaSERKS_(%struct.PODMember* %this, %struct.PODMember* dereferenceable({{[0-9]+}}))
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}})
-// CHECK: call %struct.NonPOD* @_ZN6NonPODaSERKS_
+// CHECK: call dereferenceable({{[0-9]+}}) %struct.NonPOD* @_ZN6NonPODaSERKS_
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
 // CHECK: ret %struct.PODMember*
 
 // PODLikeMember copy-assignment:
-// CHECK-LABEL: define linkonce_odr %struct.PODLikeMember* @_ZN13PODLikeMemberaSERKS_(%struct.PODLikeMember* %this, %struct.PODLikeMember*)
+// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.PODLikeMember* @_ZN13PODLikeMemberaSERKS_(%struct.PODLikeMember* %this, %struct.PODLikeMember* dereferenceable({{[0-9]+}}))
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}})
-// CHECK: call %struct.NonPOD* @_ZN6NonPODaSERKS_
+// CHECK: call dereferenceable({{[0-9]+}}) %struct.NonPOD* @_ZN6NonPODaSERKS_
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
 // CHECK: ret %struct.PODLikeMember*
 
 // ArrayMember copy-assignment:
-// CHECK-LABEL: define linkonce_odr %struct.ArrayMember* @_ZN11ArrayMemberaSERKS_(%struct.ArrayMember* %this, %struct.ArrayMember*)
+// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.ArrayMember* @_ZN11ArrayMemberaSERKS_(%struct.ArrayMember* %this, %struct.ArrayMember* dereferenceable({{[0-9]+}}))
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 64, i32 4{{.*}})
-// CHECK: call %struct.NonPOD* @_ZN6NonPODaSERKS_
+// CHECK: call dereferenceable({{[0-9]+}}) %struct.NonPOD* @_ZN6NonPODaSERKS_
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 64, i32 4{{.*}})
 // CHECK: ret %struct.ArrayMember*
 
 // VolatileMember copy-assignment:
-// CHECK-LABEL: define linkonce_odr %struct.VolatileMember* @_ZN14VolatileMemberaSERKS_(%struct.VolatileMember* %this, %struct.VolatileMember*)
+// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.VolatileMember* @_ZN14VolatileMemberaSERKS_(%struct.VolatileMember* %this, %struct.VolatileMember* dereferenceable({{[0-9]+}}))
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
 // CHECK: load volatile i32* {{.*}}, align 4
 // CHECK: store volatile i32 {{.*}}, align 4
-// CHECK: call %struct.NonPOD* @_ZN6NonPODaSERKS_
+// CHECK: call dereferenceable({{[0-9]+}}) %struct.NonPOD* @_ZN6NonPODaSERKS_
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
 // CHECK: ret %struct.VolatileMember*
 
 // BitfieldMember copy-assignment:
-// CHECK-LABEL: define linkonce_odr %struct.BitfieldMember* @_ZN14BitfieldMemberaSERKS_(%struct.BitfieldMember* %this, %struct.BitfieldMember*)
+// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.BitfieldMember* @_ZN14BitfieldMemberaSERKS_(%struct.BitfieldMember* %this, %struct.BitfieldMember* dereferenceable({{[0-9]+}}))
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
-// CHECK: call %struct.NonPOD* @_ZN6NonPODaSERKS_
+// CHECK: call dereferenceable({{[0-9]+}}) %struct.NonPOD* @_ZN6NonPODaSERKS_
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 3, i32 1{{.*}})
 // CHECK: ret %struct.BitfieldMember*
 
 // InnerClass copy-assignment:
-// CHECK-LABEL: define linkonce_odr %struct.InnerClassMember* @_ZN16InnerClassMemberaSERKS_(%struct.InnerClassMember* %this, %struct.InnerClassMember*)
+// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.InnerClassMember* @_ZN16InnerClassMemberaSERKS_(%struct.InnerClassMember* %this, %struct.InnerClassMember* dereferenceable({{[0-9]+}}))
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}})
-// CHECK: call %struct.NonPOD* @_ZN6NonPODaSERKS_
+// CHECK: call dereferenceable({{[0-9]+}}) %struct.NonPOD* @_ZN6NonPODaSERKS_
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
 // CHECK: ret %struct.InnerClassMember*
 
 // PackedMembers copy-assignment:
-// CHECK-LABEL: define linkonce_odr %struct.PackedMembers* @_ZN13PackedMembersaSERKS_(%struct.PackedMembers* %this, %struct.PackedMembers*)
-// CHECK: call %struct.NonPOD* @_ZN6NonPODaSERKS_
+// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.PackedMembers* @_ZN13PackedMembersaSERKS_(%struct.PackedMembers* %this, %struct.PackedMembers* dereferenceable({{[0-9]+}}))
+// CHECK: call dereferenceable({{[0-9]+}}) %struct.NonPOD* @_ZN6NonPODaSERKS_
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 1{{.*}})
 // CHECK: ret %struct.PackedMembers*
 
@@ -184,21 +184,21 @@
 CALL_CC(Basic)
 
 // Basic copy-constructor:
-// CHECK-LABEL: define linkonce_odr void @_ZN5BasicC2ERKS_(%struct.Basic* %this, %struct.Basic*)
+// CHECK-LABEL: define linkonce_odr void @_ZN5BasicC2ERKS_(%struct.Basic* %this, %struct.Basic* dereferenceable({{[0-9]+}}))
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
 // CHECK: call void @_ZN6NonPODC1ERKS_
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
 // CHECK: ret void
 
 // PODMember copy-constructor:
-// CHECK-LABEL: define linkonce_odr void @_ZN9PODMemberC2ERKS_(%struct.PODMember* %this, %struct.PODMember*)
+// CHECK-LABEL: define linkonce_odr void @_ZN9PODMemberC2ERKS_(%struct.PODMember* %this, %struct.PODMember* dereferenceable({{[0-9]+}}))
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}})
 // CHECK: call void @_ZN6NonPODC1ERKS_
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
 // CHECK: ret void
 
 // PODLikeMember copy-constructor:
-// CHECK-LABEL: define linkonce_odr void @_ZN13PODLikeMemberC2ERKS_(%struct.PODLikeMember* %this, %struct.PODLikeMember*)
+// CHECK-LABEL: define linkonce_odr void @_ZN13PODLikeMemberC2ERKS_(%struct.PODLikeMember* %this, %struct.PODLikeMember* dereferenceable({{[0-9]+}}))
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}})
 // CHECK: invoke void @_ZN6NonPODC1ERKS_
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
@@ -207,14 +207,14 @@
 // CHECK: invoke void @_ZN7PODLikeD1Ev
 
 // ArrayMember copy-constructor:
-// CHECK-LABEL: define linkonce_odr void @_ZN11ArrayMemberC2ERKS_(%struct.ArrayMember* %this, %struct.ArrayMember*)
+// CHECK-LABEL: define linkonce_odr void @_ZN11ArrayMemberC2ERKS_(%struct.ArrayMember* %this, %struct.ArrayMember* dereferenceable({{[0-9]+}}))
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 64, i32 4{{.*}})
 // CHECK: call void @_ZN6NonPODC1ERKS_
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 64, i32 4{{.*}})
 // CHECK: ret void
 
 // VolatileMember copy-constructor:
-// CHECK-LABEL: define linkonce_odr void @_ZN14VolatileMemberC2ERKS_(%struct.VolatileMember* %this, %struct.VolatileMember*)
+// CHECK-LABEL: define linkonce_odr void @_ZN14VolatileMemberC2ERKS_(%struct.VolatileMember* %this, %struct.VolatileMember* dereferenceable({{[0-9]+}}))
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
 // CHECK: load volatile i32* {{.*}}, align 4
 // CHECK: store volatile i32 {{.*}}, align 4
@@ -223,34 +223,34 @@
 // CHECK: ret void
 
 // BitfieldMember copy-constructor:
-// CHECK-LABEL: define linkonce_odr void @_ZN14BitfieldMemberC2ERKS_(%struct.BitfieldMember* %this, %struct.BitfieldMember*)
+// CHECK-LABEL: define linkonce_odr void @_ZN14BitfieldMemberC2ERKS_(%struct.BitfieldMember* %this, %struct.BitfieldMember* dereferenceable({{[0-9]+}}))
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
 // CHECK: call void @_ZN6NonPODC1ERKS_
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 3, i32 1{{.*}})
 // CHECK: ret void
 
 // InnerClass copy-constructor:
-// CHECK-LABEL: define linkonce_odr void @_ZN16InnerClassMemberC2ERKS_(%struct.InnerClassMember* %this, %struct.InnerClassMember*)
+// CHECK-LABEL: define linkonce_odr void @_ZN16InnerClassMemberC2ERKS_(%struct.InnerClassMember* %this, %struct.InnerClassMember* dereferenceable({{[0-9]+}}))
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}})
 // CHECK: call void @_ZN6NonPODC1ERKS_
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}})
 // CHECK: ret void
 
 // ReferenceMember copy-constructor:
-// CHECK-LABEL: define linkonce_odr void @_ZN15ReferenceMemberC2ERKS_(%struct.ReferenceMember* %this, %struct.ReferenceMember*)
+// CHECK-LABEL: define linkonce_odr void @_ZN15ReferenceMemberC2ERKS_(%struct.ReferenceMember* %this, %struct.ReferenceMember* dereferenceable({{[0-9]+}}))
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 8{{.*}})
 // CHECK: call void @_ZN6NonPODC1ERKS_
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 8{{.*}})
 // CHECK: ret void
 
 // BitfieldMember2 copy-constructor:
-// CHECK-2-LABEL: define linkonce_odr void @_ZN15BitfieldMember2C2ERKS_(%struct.BitfieldMember2* %this, %struct.BitfieldMember2*)
+// CHECK-2-LABEL: define linkonce_odr void @_ZN15BitfieldMember2C2ERKS_(%struct.BitfieldMember2* %this, %struct.BitfieldMember2* dereferenceable({{[0-9]+}}))
 // CHECK-2: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4, i1 false)
 // CHECK-2: call void @_ZN6NonPODC1ERKS_
 // CHECK-2: ret void
 
 // PackedMembers copy-assignment:
-// CHECK-LABEL: define linkonce_odr void @_ZN13PackedMembersC2ERKS_(%struct.PackedMembers* %this, %struct.PackedMembers*)
+// CHECK-LABEL: define linkonce_odr void @_ZN13PackedMembersC2ERKS_(%struct.PackedMembers* %this, %struct.PackedMembers* dereferenceable({{[0-9]+}}))
 // CHECK: call void @_ZN6NonPODC1ERKS_
 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 1{{.*}})
 // CHECK: ret void
diff --git a/test/CodeGenCXX/pointers-to-data-members.cpp b/test/CodeGenCXX/pointers-to-data-members.cpp
index f0199c8..745cf18 100644
--- a/test/CodeGenCXX/pointers-to-data-members.cpp
+++ b/test/CodeGenCXX/pointers-to-data-members.cpp
@@ -202,7 +202,7 @@
     bool member;
   };
 
-  // CHECK-LABEL: define i8* @_ZN15BoolPtrToMember1fERNS_1XEMS0_b
+  // CHECK-LABEL: define dereferenceable({{[0-9]+}}) i8* @_ZN15BoolPtrToMember1fERNS_1XEMS0_b
   bool &f(X &x, bool X::*member) {
     // CHECK: {{bitcast.* to i8\*}}
     // CHECK-NEXT: getelementptr inbounds i8*
diff --git a/test/CodeGenCXX/poly-unsigned.cpp b/test/CodeGenCXX/poly-unsigned.cpp
new file mode 100644
index 0000000..e2ab430
--- /dev/null
+++ b/test/CodeGenCXX/poly-unsigned.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple arm64-apple-ios -target-feature +neon -ffreestanding -S -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-UNSIGNED-POLY %s
+// RUN: %clang_cc1 -triple arm64-linux-gnu -target-feature +neon -ffreestanding -S -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-UNSIGNED-POLY %s
+// RUN: %clang_cc1 -triple armv7-apple-ios -ffreestanding -target-cpu cortex-a8 -S -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-SIGNED-POLY %s
+
+#include <arm_neon.h>
+
+// Polynomial types really should be universally unsigned, otherwise casting
+// (say) poly8_t "x^7" to poly16_t would change it to "x^15 + x^14 + ... +
+// x^7". Unfortunately 32-bit ARM ended up in a slightly delicate ABI situation
+// so for now it got that wrong.
+
+poly16_t test_poly8(poly8_t pIn) {
+// CHECK-UNSIGNED-POLY: @_Z10test_poly8h
+// CHECK-UNSIGNED-POLY: zext i8 {{.*}} to i16
+
+// CHECK-SIGNED-POLY: @_Z10test_poly8a
+// CHECK-SIGNED-POLY: sext i8 {{.*}} to i16
+
+  return pIn;
+}
diff --git a/test/CodeGenCXX/pr11797.cpp b/test/CodeGenCXX/pr11797.cpp
index 1098372..2a31090 100644
--- a/test/CodeGenCXX/pr11797.cpp
+++ b/test/CodeGenCXX/pr11797.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -fvisibility hidden -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -fvisibility hidden -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s
 
 namespace std __attribute__ ((__visibility__ ("default"))) {}
 #pragma GCC visibility push(default)
diff --git a/test/CodeGenCXX/pr12104.cpp b/test/CodeGenCXX/pr12104.cpp
index a62f04b..560ffbe 100644
--- a/test/CodeGenCXX/pr12104.cpp
+++ b/test/CodeGenCXX/pr12104.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -include %S/pr12104.h %s -emit-llvm -o - | FileCheck %s
-// RUN: %clang_cc1 -x c++ -emit-pch -o %t %S/pr12104.h
-// RUN: %clang_cc1 -include-pch %t %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -include %S/pr12104.h %s -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -x c++ -triple %itanium_abi_triple -emit-pch -o %t %S/pr12104.h
+// RUN: %clang_cc1 -include-pch %t %s -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s
 
 template struct Patch<1>;
 
diff --git a/test/CodeGenCXX/pr13396.cpp b/test/CodeGenCXX/pr13396.cpp
index 3d582c5..e41dd39 100644
--- a/test/CodeGenCXX/pr13396.cpp
+++ b/test/CodeGenCXX/pr13396.cpp
@@ -7,13 +7,13 @@
 };
 
 foo::foo() {
-  // CHECK-LABEL: define void @_ZN3fooC1Ev(%struct.foo* inreg %this)
   // CHECK-LABEL: define void @_ZN3fooC2Ev(%struct.foo* inreg %this)
+  // CHECK-LABEL: define void @_ZN3fooC1Ev(%struct.foo* inreg %this)
 }
 
 foo::~foo() {
-  // CHECK-LABEL: define void @_ZN3fooD1Ev(%struct.foo* inreg %this)
   // CHECK-LABEL: define void @_ZN3fooD2Ev(%struct.foo* inreg %this)
+  // CHECK-LABEL: define void @_ZN3fooD1Ev(%struct.foo* inreg %this)
 }
 
 void dummy() {
diff --git a/test/CodeGenCXX/pr18661.cpp b/test/CodeGenCXX/pr18661.cpp
new file mode 100644
index 0000000..2358678
--- /dev/null
+++ b/test/CodeGenCXX/pr18661.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -fcxx-exceptions -fms-extensions -emit-llvm -o - | FileCheck %s
+
+extern "C" {
+  void f();
+
+  // In MS mode we don't validate the exception specification.
+  void f() throw() {
+  }
+}
+
+// PR18661: Clang would fail to emit function definition with mismatching
+// exception specification, even though it was just treated as a warning.
+
+// CHECK: define void @f()
diff --git a/test/CodeGenCXX/pr18962.cpp b/test/CodeGenCXX/pr18962.cpp
new file mode 100644
index 0000000..ab537b4
--- /dev/null
+++ b/test/CodeGenCXX/pr18962.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -triple i686-linux-gnu %s -emit-llvm -o - | FileCheck %s
+
+class A {
+  // append has to have the same prototype as fn1 to tickle the bug.
+  void (*append)(A *);
+};
+
+class B {};
+class D;
+
+// C has to be non-C++98 POD with available tail padding, making the LLVM base
+// type differ from the complete LLVM type.
+class C {
+  // This member creates a circular LLVM type reference to %class.D.
+  D *m_group;
+  B changeListeners;
+};
+class D : C {};
+
+void fn1(A *p1) {
+}
+
+void
+fn2(C *) {
+}
+
+// We end up using an opaque type for 'append' to avoid circular references.
+// CHECK: %class.A = type { {}* }
+// CHECK: %class.C = type { %class.D*, %class.B }
+// CHECK: %class.D = type { %class.C.base, [3 x i8] }
+// CHECK: %class.C.base = type <{ %class.D*, %class.B }>
+// CHECK: %class.B = type { i8 }
diff --git a/test/CodeGenCXX/pr9965.cpp b/test/CodeGenCXX/pr9965.cpp
index c2d54e1..46fd609 100644
--- a/test/CodeGenCXX/pr9965.cpp
+++ b/test/CodeGenCXX/pr9965.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
 struct A { A(); };
 template<typename T>
 struct X : A // default constructor is not trivial
diff --git a/test/CodeGenCXX/pragma-init_seg.cpp b/test/CodeGenCXX/pragma-init_seg.cpp
new file mode 100644
index 0000000..3f9ff21
--- /dev/null
+++ b/test/CodeGenCXX/pragma-init_seg.cpp
@@ -0,0 +1,72 @@
+// RUN: %clang_cc1 %s -triple=i686-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s
+
+int f();
+
+// CHECK: $"\01?x@selectany_init@@3HA" = comdat any
+// CHECK: $"\01?x@?$A@H@explicit_template_instantiation@@2HB" = comdat any
+// CHECK: $"\01?x@?$A@H@implicit_template_instantiation@@2HB" = comdat any
+
+namespace simple_init {
+#pragma init_seg(compiler)
+int x = f();
+// CHECK: @"\01?x@simple_init@@3HA" = global i32 0, align 4
+// CHECK: @__cxx_init_fn_ptr = private constant void ()* @"\01??__Ex@simple_init@@YAXXZ", section ".CRT$XCC"
+
+#pragma init_seg(lib)
+int y = f();
+// CHECK: @"\01?y@simple_init@@3HA" = global i32 0, align 4
+// CHECK: @__cxx_init_fn_ptr1 = private constant void ()* @"\01??__Ey@simple_init@@YAXXZ", section ".CRT$XCL"
+
+#pragma init_seg(user)
+int z = f();
+// CHECK: @"\01?z@simple_init@@3HA" = global i32 0, align 4
+// No function pointer!  This one goes on @llvm.global_ctors.
+}
+
+#pragma init_seg(".asdf")
+
+namespace internal_init {
+namespace {
+int x = f();
+// CHECK: @"\01?x@?A@internal_init@@3HA" = internal global i32 0, align 4
+// CHECK: @__cxx_init_fn_ptr2 = private constant void ()* @"\01??__Ex@?A@internal_init@@YAXXZ", section ".asdf"
+}
+}
+
+namespace selectany_init {
+int __declspec(selectany) x = f();
+// CHECK: @"\01?x@selectany_init@@3HA" = weak_odr global i32 0, comdat $"\01?x@selectany_init@@3HA", align 4
+// CHECK: @__cxx_init_fn_ptr3 = private constant void ()* @"\01??__Ex@selectany_init@@YAXXZ", section ".asdf", comdat $"\01?x@selectany_init@@3HA"
+}
+
+namespace explicit_template_instantiation {
+template <typename T> struct A { static const int x; };
+template <typename T> const int A<T>::x = f();
+template struct A<int>;
+// CHECK: @"\01?x@?$A@H@explicit_template_instantiation@@2HB" = weak_odr global i32 0, comdat $"\01?x@?$A@H@explicit_template_instantiation@@2HB", align 4
+// CHECK: @__cxx_init_fn_ptr4 = private constant void ()* @"\01??__Ex@?$A@H@explicit_template_instantiation@@2HB@YAXXZ", section ".asdf", comdat $"\01?x@?$A@H@explicit_template_instantiation@@2HB"
+}
+
+namespace implicit_template_instantiation {
+template <typename T> struct A { static const int x; };
+template <typename T> const int A<T>::x = f();
+int g() { return A<int>::x; }
+// CHECK: @"\01?x@?$A@H@implicit_template_instantiation@@2HB" = linkonce_odr global i32 0, comdat $"\01?x@?$A@H@implicit_template_instantiation@@2HB", align 4
+// CHECK: @__cxx_init_fn_ptr5 = private constant void ()* @"\01??__Ex@?$A@H@implicit_template_instantiation@@2HB@YAXXZ", section ".asdf", comdat $"\01?x@?$A@H@implicit_template_instantiation@@2HB"
+}
+
+// ... and here's where we emitted user level ctors.
+// CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }]
+// CHECK: [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_pragma_init_seg.cpp, i8* null }]
+
+// We have to mark everything used so we can survive globalopt, even through
+// LTO.  There's no way LLVM could really understand if data in the .asdf
+// section is really used or dead.
+//
+// CHECK: @llvm.used = appending global [6 x i8*]
+// CHECK: [i8* bitcast (void ()** @__cxx_init_fn_ptr to i8*),
+// CHECK: i8* bitcast (void ()** @__cxx_init_fn_ptr1 to i8*),
+// CHECK: i8* bitcast (void ()** @__cxx_init_fn_ptr2 to i8*),
+// CHECK: i8* bitcast (void ()** @__cxx_init_fn_ptr3 to i8*),
+// CHECK: i8* bitcast (void ()** @__cxx_init_fn_ptr4 to i8*),
+// CHECK: i8* bitcast (void ()** @__cxx_init_fn_ptr5 to i8*)], section "llvm.metadata"
diff --git a/test/CodeGenCXX/pragma-pack-3.cpp b/test/CodeGenCXX/pragma-pack-3.cpp
new file mode 100644
index 0000000..49509a5
--- /dev/null
+++ b/test/CodeGenCXX/pragma-pack-3.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 %s -triple=i686-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+struct Base {
+  char a;
+};
+
+struct Derived_1 : virtual Base
+{
+  char b;
+};
+
+#pragma pack(1)
+struct Derived_2 : Derived_1 {
+  // CHECK: %struct.Derived_2 = type { %struct.Derived_1.base, %struct.Base }
+  // CHECK: %struct.Derived_1.base = type <{ i32 (...)**, i8 }>
+};
+
+Derived_2 x;
diff --git a/test/CodeGenCXX/pragma-weak.cpp b/test/CodeGenCXX/pragma-weak.cpp
index c033079..e2d4648 100644
--- a/test/CodeGenCXX/pragma-weak.cpp
+++ b/test/CodeGenCXX/pragma-weak.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
 
 #pragma weak zex
 int zex;
@@ -10,7 +10,7 @@
 #pragma weak foo
 struct S {  void foo(); };
 void S::foo() {}
-// CHECK-LABEL: define void @_ZN1S3fooEv(
+// CHECK-LABEL: define {{.*}}void @_ZN1S3fooEv(
 
 #pragma weak zed
 namespace bar {  void zed() {} }
diff --git a/test/CodeGenCXX/predefined-expr.cpp b/test/CodeGenCXX/predefined-expr.cpp
index 9062ee0..f901467 100644
--- a/test/CodeGenCXX/predefined-expr.cpp
+++ b/test/CodeGenCXX/predefined-expr.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 %s -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s
 
 // CHECK: private unnamed_addr constant [15 x i8] c"externFunction\00"
 // CHECK: private unnamed_addr constant [26 x i8] c"void NS::externFunction()\00"
@@ -10,7 +10,7 @@
 // CHECK: private unnamed_addr constant [122 x i8] c"static void ClassWithTemplateTemplateParam<char, NS::ClassTemplate>::staticMember() [T = char, Param = NS::ClassTemplate]\00"
 // CHECK: private unnamed_addr constant [106 x i8] c"void OuterClass<int *>::MiddleClass::InnerClass<float>::memberFunction(T, U) const [T = int *, U = float]\00"
 // CHECK: private unnamed_addr constant [51 x i8] c"void functionTemplateWithCapturedStmt(T) [T = int]\00"
-// CHECK: private unnamed_addr constant [76 x i8] c"auto functionTemplateWithLambda(int)::<anonymous class>::operator()() const\00"
+// CHECK: private unnamed_addr constant [76 x i8] c"auto functionTemplateWithLambda(int)::(anonymous class)::operator()() const\00"
 // CHECK: private unnamed_addr constant [65 x i8] c"void functionTemplateWithUnnamedTemplateParameter(T) [T = float]\00"
 
 // CHECK: private unnamed_addr constant [60 x i8] c"void functionTemplateExplicitSpecialization(T) [T = double]\00"
@@ -28,13 +28,13 @@
 // CHECK: private unnamed_addr constant [46 x i8] c"void NS::Base::functionTemplate1(T) [T = int]\00"
 
 // CHECK: private unnamed_addr constant [23 x i8] c"anonymousUnionFunction\00"
-// CHECK: private unnamed_addr constant [83 x i8] c"void NS::ContainerForAnonymousRecords::<anonymous union>::anonymousUnionFunction()\00"
+// CHECK: private unnamed_addr constant [83 x i8] c"void NS::ContainerForAnonymousRecords::(anonymous union)::anonymousUnionFunction()\00"
 
 // CHECK: private unnamed_addr constant [24 x i8] c"anonymousStructFunction\00"
-// CHECK: private unnamed_addr constant [85 x i8] c"void NS::ContainerForAnonymousRecords::<anonymous struct>::anonymousStructFunction()\00"
+// CHECK: private unnamed_addr constant [85 x i8] c"void NS::ContainerForAnonymousRecords::(anonymous struct)::anonymousStructFunction()\00"
 
 // CHECK: private unnamed_addr constant [23 x i8] c"anonymousClassFunction\00"
-// CHECK: private unnamed_addr constant [83 x i8] c"void NS::ContainerForAnonymousRecords::<anonymous class>::anonymousClassFunction()\00"
+// CHECK: private unnamed_addr constant [83 x i8] c"void NS::ContainerForAnonymousRecords::(anonymous class)::anonymousClassFunction()\00"
 
 // CHECK: private unnamed_addr constant [12 x i8] c"~Destructor\00"
 // CHECK: private unnamed_addr constant [30 x i8] c"NS::Destructor::~Destructor()\00"
@@ -93,7 +93,7 @@
 // CHECK: private unnamed_addr constant [59 x i8] c"void ClassInTopLevelNamespace::topLevelNamespaceFunction()\00"
 
 // CHECK: private unnamed_addr constant [27 x i8] c"anonymousNamespaceFunction\00"
-// CHECK: private unnamed_addr constant [84 x i8] c"void <anonymous namespace>::ClassInAnonymousNamespace::anonymousNamespaceFunction()\00"
+// CHECK: private unnamed_addr constant [84 x i8] c"void (anonymous namespace)::ClassInAnonymousNamespace::anonymousNamespaceFunction()\00"
 
 // CHECK: private unnamed_addr constant [19 x i8] c"localClassFunction\00"
 // CHECK: private unnamed_addr constant [59 x i8] c"void NS::localClass(int)::LocalClass::localClassFunction()\00"
diff --git a/test/CodeGenCXX/ptr-to-member-function.cpp b/test/CodeGenCXX/ptr-to-member-function.cpp
index 914a90a..e02b209 100644
--- a/test/CodeGenCXX/ptr-to-member-function.cpp
+++ b/test/CodeGenCXX/ptr-to-member-function.cpp
@@ -1,8 +1,7 @@
-// REQUIRES: x86-registered-target,x86-64-registered-target
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s
-// RUN: FileCheck -check-prefix CHECK-LP64 --input-file=%t-64.s %s
-// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s
-// RUN: FileCheck -check-prefix CHECK-LP32 --input-file=%t-32.s %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm %s -o - | \
+// RUN: FileCheck -check-prefix CHECK-LP64 %s
+// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -emit-llvm %s -o - | \
+// RUN: FileCheck -check-prefix CHECK-LP32 %s
 // 13.3.3.2 Ranking implicit conversion sequences
 
 extern "C" int printf(...);
@@ -64,8 +63,8 @@
   	B1 c = B1(2);
 }
 
-// CHECK-LP64: callq	__ZN1XcvM1BFvvEEv
-// CHECK-LP64: callq	__Z1gM1CFvvE
+// CHECK-LP64: call { i64, i64 } @_ZN1XcvM1BFvvEEv
+// CHECK-LP64: call void @_Z1gM1CFvvE
 
-// CHECK-LP32: calll	L__ZN1XcvM1BFvvEEv
-// CHECK-LP32: calll	__Z1gM1CFvvE
+// CHECK-LP32: call i64 @_ZN1XcvM1BFvvEEv
+// CHECK-LP32: call void @_Z1gM1CFvvE
diff --git a/test/CodeGenCXX/reference-cast.cpp b/test/CodeGenCXX/reference-cast.cpp
index 60ea393..c4be5b7 100644
--- a/test/CodeGenCXX/reference-cast.cpp
+++ b/test/CodeGenCXX/reference-cast.cpp
@@ -3,7 +3,7 @@
 // PR6024
 extern int i;
 
-// CHECK: define i32* @_Z16lvalue_noop_castv() [[NUW:#[0-9]+]]
+// CHECK: define dereferenceable({{[0-9]+}}) i32* @_Z16lvalue_noop_castv() [[NUW:#[0-9]+]]
 const int &lvalue_noop_cast() {
   if (i == 0)
     // CHECK: store i32 17, i32*
@@ -15,7 +15,7 @@
   return 17;
 }
 
-// CHECK-LABEL: define i16* @_Z20lvalue_integral_castv() 
+// CHECK-LABEL: define dereferenceable({{[0-9]+}}) i16* @_Z20lvalue_integral_castv() 
 const short &lvalue_integral_cast() {
   if (i == 0)
     // CHECK: store i16 17, i16*
@@ -27,7 +27,7 @@
   return 17;
 }
 
-// CHECK-LABEL: define i16* @_Z29lvalue_floating_integral_castv()
+// CHECK-LABEL: define dereferenceable({{[0-9]+}}) i16* @_Z29lvalue_floating_integral_castv()
 const short &lvalue_floating_integral_cast() {
   if (i == 0)
     // CHECK: store i16 17, i16*
@@ -39,7 +39,7 @@
   return 17.5;
 }
 
-// CHECK-LABEL: define float* @_Z29lvalue_integral_floating_castv()
+// CHECK-LABEL: define dereferenceable({{[0-9]+}}) float* @_Z29lvalue_integral_floating_castv()
 const float &lvalue_integral_floating_cast() {
   if (i == 0)
     // CHECK: store float 1.700000e+{{0*}}1, float*
@@ -51,7 +51,7 @@
   return 17;
 }
 
-// CHECK-LABEL: define float* @_Z20lvalue_floating_castv()
+// CHECK-LABEL: define dereferenceable({{[0-9]+}}) float* @_Z20lvalue_floating_castv()
 const float &lvalue_floating_cast() {
   if (i == 0)
     // CHECK: store float 1.700000e+{{0*}}1, float*
@@ -65,7 +65,7 @@
 
 int get_int();
 
-// CHECK-LABEL: define i8* @_Z24lvalue_integer_bool_castv()
+// CHECK-LABEL: define dereferenceable({{[0-9]+}}) i8* @_Z24lvalue_integer_bool_castv()
 const bool &lvalue_integer_bool_cast() {
   if (i == 0)
     // CHECK: call i32 @_Z7get_intv()
@@ -82,7 +82,7 @@
 
 float get_float();
 
-// CHECK-LABEL: define i8* @_Z25lvalue_floating_bool_castv()
+// CHECK-LABEL: define dereferenceable({{[0-9]+}}) i8* @_Z25lvalue_floating_bool_castv()
 const bool &lvalue_floating_bool_cast() {
   if (i == 0)
     // CHECK: call float @_Z9get_floatv()
@@ -107,7 +107,7 @@
 pm get_pointer_to_member_data();
 pmf get_pointer_to_member_function();
 
-// CHECK-LABEL: define i8* @_Z26lvalue_ptrmem_to_bool_castv()
+// CHECK-LABEL: define dereferenceable({{[0-9]+}}) i8* @_Z26lvalue_ptrmem_to_bool_castv()
 const bool &lvalue_ptrmem_to_bool_cast() {
   if (i == 0)
     // CHECK: call i64 @_Z26get_pointer_to_member_datav()
@@ -125,7 +125,7 @@
   return get_pointer_to_member_data();
 }
 
-// CHECK-LABEL: define i8* @_Z27lvalue_ptrmem_to_bool_cast2v
+// CHECK-LABEL: define dereferenceable({{[0-9]+}}) i8* @_Z27lvalue_ptrmem_to_bool_cast2v
 const bool &lvalue_ptrmem_to_bool_cast2() {
   if (i == 0)
     // CHECK: {{call.*_Z30get_pointer_to_member_functionv}}
diff --git a/test/CodeGenCXX/reference-field.cpp b/test/CodeGenCXX/reference-field.cpp
index 0312029..54e914d 100644
--- a/test/CodeGenCXX/reference-field.cpp
+++ b/test/CodeGenCXX/reference-field.cpp
@@ -1,6 +1,8 @@
-// RUN: %clang_cc1 -emit-llvm -o - %s -O2 | grep "@_Z1bv"
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -o - %s -O2 | FileCheck %s
 
 // Make sure the call to b() doesn't get optimized out.
 extern struct x {char& x,y;}y;
 int b();      
 int a() { if (!&y.x) b(); }
+
+// CHECK: @_Z1bv
diff --git a/test/CodeGenCXX/reference-init.cpp b/test/CodeGenCXX/reference-init.cpp
index d47b1f3..3a3eaee 100644
--- a/test/CodeGenCXX/reference-init.cpp
+++ b/test/CodeGenCXX/reference-init.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm-only -verify %s
+// RUN: %clang_cc1 -emit-llvm-only -triple %itanium_abi_triple -verify %s
 // expected-no-diagnostics
 
 struct XPTParamDescriptor {};
diff --git a/test/CodeGenCXX/references.cpp b/test/CodeGenCXX/references.cpp
index ec7a3d5..454c306 100644
--- a/test/CodeGenCXX/references.cpp
+++ b/test/CodeGenCXX/references.cpp
@@ -241,7 +241,7 @@
 };
 
 // CHECK-LABEL: define internal void @__cxx_global_var_init
-// CHECK: call void @_ZN2N31AC1Ei(%"struct.N3::A"* @_ZGRN2N35sA123E, i32 123)
+// CHECK: call void @_ZN2N31AC1Ei(%"struct.N3::A"* @_ZGRN2N35sA123E_, i32 123)
 // CHECK: call i32 @__cxa_atexit
 // CHECK: ret void
 const A &sA123 = A(123);
@@ -256,7 +256,7 @@
 
 void f() {
   // CHECK-LABEL: define void @_ZN2N41fEv
-  // CHECK: call void @_ZN2N41AC1Ev(%"struct.N4::A"* @_ZGRZN2N41fEvE2ar)
+  // CHECK: call void @_ZN2N41AC1Ev(%"struct.N4::A"* @_ZGRZN2N41fEvE2ar_)
   // CHECK: call i32 @__cxa_atexit
   // CHECK: ret void
   static const A& ar = A();
diff --git a/test/CodeGenCXX/return.cpp b/test/CodeGenCXX/return.cpp
index 1975055..5c1cfda 100644
--- a/test/CodeGenCXX/return.cpp
+++ b/test/CodeGenCXX/return.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
-// RUN: %clang_cc1 -emit-llvm -O -o - %s | FileCheck %s --check-prefix=CHECK-OPT
+// 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
 
 // CHECK:     @_Z9no_return
 // CHECK-OPT: @_Z9no_return
diff --git a/test/CodeGenCXX/rtti-fundamental.cpp b/test/CodeGenCXX/rtti-fundamental.cpp
index 2495e96..e70c3aa 100644
--- a/test/CodeGenCXX/rtti-fundamental.cpp
+++ b/test/CodeGenCXX/rtti-fundamental.cpp
@@ -15,102 +15,107 @@
 }
 
 // void
-// CHECK: @_ZTIv = unnamed_addr constant
-// CHECK: @_ZTIPv = unnamed_addr constant
-// CHECK: @_ZTIPKv = unnamed_addr constant
+// CHECK: @_ZTIv = constant
+// CHECK: @_ZTIPv = constant
+// CHECK: @_ZTIPKv = constant
 
 // std::nullptr_t
-// CHECK: @_ZTIDn = unnamed_addr constant
-// CHECK: @_ZTIPDn = unnamed_addr constant
-// CHECK: @_ZTIPKDn = unnamed_addr constant
+// CHECK: @_ZTIDn = constant
+// CHECK: @_ZTIPDn = constant
+// CHECK: @_ZTIPKDn = constant
 
 // bool
-// CHECK: @_ZTIb = unnamed_addr constant
-// CHECK: @_ZTIPb = unnamed_addr constant
-// CHECK: @_ZTIPKb = unnamed_addr constant
+// CHECK: @_ZTIb = constant
+// CHECK: @_ZTIPb = constant
+// CHECK: @_ZTIPKb = constant
 
 // wchar_t
-// CHECK: @_ZTIw = unnamed_addr constant
-// CHECK: @_ZTIPw = unnamed_addr constant
-// CHECK: @_ZTIPKw = unnamed_addr constant
+// CHECK: @_ZTIw = constant
+// CHECK: @_ZTIPw = constant
+// CHECK: @_ZTIPKw = constant
 
 // char
-// CHECK: @_ZTIc = unnamed_addr constant
-// CHECK: @_ZTIPc = unnamed_addr constant
-// CHECK: @_ZTIPKc = unnamed_addr constant
+// CHECK: @_ZTIc = constant
+// CHECK: @_ZTIPc = constant
+// CHECK: @_ZTIPKc = constant
 
 // unsigned char
-// CHECK: @_ZTIh = unnamed_addr constant
-// CHECK: @_ZTIPh = unnamed_addr constant
-// CHECK: @_ZTIPKh = unnamed_addr constant
+// CHECK: @_ZTIh = constant
+// CHECK: @_ZTIPh = constant
+// CHECK: @_ZTIPKh = constant
 
 // signed char
-// CHECK: @_ZTIa = unnamed_addr constant
-// CHECK: @_ZTIPa = unnamed_addr constant
-// CHECK: @_ZTIPKa = unnamed_addr constant
+// CHECK: @_ZTIa = constant
+// CHECK: @_ZTIPa = constant
+// CHECK: @_ZTIPKa = constant
 
 // short
-// CHECK: @_ZTIs = unnamed_addr constant
-// CHECK: @_ZTIPs = unnamed_addr constant
-// CHECK: @_ZTIPKs = unnamed_addr constant
+// CHECK: @_ZTIs = constant
+// CHECK: @_ZTIPs = constant
+// CHECK: @_ZTIPKs = constant
 
 // unsigned short
-// CHECK: @_ZTIt = unnamed_addr constant
-// CHECK: @_ZTIPt = unnamed_addr constant
-// CHECK: @_ZTIPKt = unnamed_addr constant
+// CHECK: @_ZTIt = constant
+// CHECK: @_ZTIPt = constant
+// CHECK: @_ZTIPKt = constant
 
 // int
-// CHECK: @_ZTIi = unnamed_addr constant
-// CHECK: @_ZTIPi = unnamed_addr constant
-// CHECK: @_ZTIPKi = unnamed_addr constant
+// CHECK: @_ZTIi = constant
+// CHECK: @_ZTIPi = constant
+// CHECK: @_ZTIPKi = constant
 
 // unsigned int
-// CHECK: @_ZTIj = unnamed_addr constant
-// CHECK: @_ZTIPj = unnamed_addr constant
-// CHECK: @_ZTIPKj = unnamed_addr constant
+// CHECK: @_ZTIj = constant
+// CHECK: @_ZTIPj = constant
+// CHECK: @_ZTIPKj = constant
 
 // long
-// CHECK: @_ZTIl = unnamed_addr constant
-// CHECK: @_ZTIPl = unnamed_addr constant
-// CHECK: @_ZTIPKl = unnamed_addr constant
+// CHECK: @_ZTIl = constant
+// CHECK: @_ZTIPl = constant
+// CHECK: @_ZTIPKl = constant
 
 // unsigned long
-// CHECK: @_ZTIm = unnamed_addr constant
-// CHECK: @_ZTIPm = unnamed_addr constant
-// CHECK: @_ZTIPKm = unnamed_addr constant
+// CHECK: @_ZTIm = constant
+// CHECK: @_ZTIPm = constant
+// CHECK: @_ZTIPKm = constant
 
 // long long
-// CHECK: @_ZTIx = unnamed_addr constant
-// CHECK: @_ZTIPx = unnamed_addr constant
-// CHECK: @_ZTIPKx = unnamed_addr constant
+// CHECK: @_ZTIx = constant
+// CHECK: @_ZTIPx = constant
+// CHECK: @_ZTIPKx = constant
 
 // unsigned long long
-// CHECK: @_ZTIy = unnamed_addr constant
-// CHECK: @_ZTIPy = unnamed_addr constant
-// CHECK: @_ZTIPKy = unnamed_addr constant
+// CHECK: @_ZTIy = constant
+// CHECK: @_ZTIPy = constant
+// CHECK: @_ZTIPKy = constant
+
+// half
+// CHECK: @_ZTIDh = constant
+// CHECK: @_ZTIPDh = constant
+// CHECK: @_ZTIPKDh = constant
 
 // float
-// CHECK: @_ZTIf = unnamed_addr constant
-// CHECK: @_ZTIPf = unnamed_addr constant
-// CHECK: @_ZTIPKf = unnamed_addr constant
+// CHECK: @_ZTIf = constant
+// CHECK: @_ZTIPf = constant
+// CHECK: @_ZTIPKf = constant
 
 // double
-// CHECK: @_ZTId = unnamed_addr constant
-// CHECK: @_ZTIPd = unnamed_addr constant
-// CHECK: @_ZTIPKd = unnamed_addr constant
+// CHECK: @_ZTId = constant
+// CHECK: @_ZTIPd = constant
+// CHECK: @_ZTIPKd = constant
 
 // long double
-// CHECK: @_ZTIe = unnamed_addr constant
-// CHECK: @_ZTIPe = unnamed_addr constant
-// CHECK: @_ZTIPKe = unnamed_addr constant
+// CHECK: @_ZTIe = constant
+// CHECK: @_ZTIPe = constant
+// CHECK: @_ZTIPKe = constant
 
 // char16_t
-// CHECK: @_ZTIDs = unnamed_addr constant
-// CHECK: @_ZTIPDs = unnamed_addr constant
-// CHECK: @_ZTIPKDs = unnamed_addr constant
+// CHECK: @_ZTIDs = constant
+// CHECK: @_ZTIPDs = constant
+// CHECK: @_ZTIPKDs = constant
 
 // char32_t
-// CHECK: @_ZTIDi = unnamed_addr constant
-// CHECK: @_ZTIPDi = unnamed_addr constant
-// CHECK: @_ZTIPKDi = unnamed_addr constant
+// CHECK: @_ZTIDi = constant
+// CHECK: @_ZTIPDi = constant
+// CHECK: @_ZTIPKDi = constant
 
diff --git a/test/CodeGenCXX/rtti-linkage.cpp b/test/CodeGenCXX/rtti-linkage.cpp
index 42fe435..3b06d42 100644
--- a/test/CodeGenCXX/rtti-linkage.cpp
+++ b/test/CodeGenCXX/rtti-linkage.cpp
@@ -1,56 +1,75 @@
-// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -fhidden-weak-vtables -emit-llvm -o - | FileCheck %s
-// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -fvisibility hidden -fhidden-weak-vtables -emit-llvm -o - | FileCheck -check-prefix=CHECK-WITH-HIDDEN %s
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-BOTH
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -fvisibility hidden -emit-llvm -o - | FileCheck -check-prefix=CHECK-WITH-HIDDEN -check-prefix=CHECK-BOTH %s
 
 #include <typeinfo>
 
+// CHECK-BOTH: _ZTSP1C = internal constant
+// CHECK-BOTH: _ZTS1C = internal constant
+// CHECK-BOTH: _ZTI1C = internal constant
+// CHECK-BOTH: _ZTIP1C = internal constant
+// CHECK-BOTH: _ZTSPP1C = internal constant
+// CHECK-BOTH: _ZTIPP1C = internal constant
+// CHECK-BOTH: _ZTSM1Ci = internal constant
+// CHECK-BOTH: _ZTIM1Ci = internal constant
+// CHECK-BOTH: _ZTSPM1Ci = internal constant
+// CHECK-BOTH: _ZTIPM1Ci = internal constant
+// CHECK-BOTH: _ZTSM1CS_ = internal constant
+// CHECK-BOTH: _ZTIM1CS_ = internal constant
+// CHECK-BOTH: _ZTSM1CPS_ = internal constant
+// CHECK-BOTH: _ZTIM1CPS_ = internal constant
+// CHECK-BOTH: _ZTSM1A1C = internal constant
+// CHECK: _ZTS1A = linkonce_odr constant
+// CHECK-WITH-HIDDEN: _ZTS1A = linkonce_odr hidden constant
+// CHECK: _ZTI1A = linkonce_odr constant
+// CHECK-WITH-HIDDEN: _ZTI1A = linkonce_odr hidden constant
+// CHECK-BOTH: _ZTIM1A1C = internal constant
+// CHECK-BOTH: _ZTSM1AP1C = internal constant
+// CHECK-BOTH: _ZTIM1AP1C = internal constant
+
 // CHECK-WITH-HIDDEN: _ZTSFN12_GLOBAL__N_11DEvE = internal constant
 // CHECK-WITH-HIDDEN: @_ZTSPK2T4 = linkonce_odr hidden constant 
 // CHECK-WITH-HIDDEN: @_ZTS2T4 = linkonce_odr hidden constant 
-// CHECK-WITH-HIDDEN: @_ZTI2T4 = linkonce_odr hidden unnamed_addr constant 
-// CHECK-WITH-HIDDEN: @_ZTIPK2T4 = linkonce_odr hidden unnamed_addr constant 
+// CHECK-WITH-HIDDEN: @_ZTI2T4 = linkonce_odr hidden constant 
+// CHECK-WITH-HIDDEN: @_ZTIPK2T4 = linkonce_odr hidden constant 
+// CHECK-WITH-HIDDEN: @_ZTSZ2t5vE1A = internal constant
+// CHECK-WITH-HIDDEN: @_ZTIZ2t5vE1A = internal constant
+// CHECK-WITH-HIDDEN: @_ZTSPZ2t7vE1A = linkonce_odr hidden constant
+// CHECK-WITH-HIDDEN: @_ZTSZ2t7vE1A = linkonce_odr hidden constant
+// CHECK-WITH-HIDDEN: @_ZTIZ2t7vE1A = linkonce_odr hidden constant
+// CHECK-WITH-HIDDEN: @_ZTIPZ2t7vE1A = linkonce_odr hidden constant
+// CHECK-WITH-HIDDEN: @_ZTSZ2t6vE1A = linkonce_odr hidden constant
+// CHECK-WITH-HIDDEN: @_ZTIZ2t6vE1A = linkonce_odr hidden constant
 
-// CHECK: _ZTSP1C = internal constant
-// CHECK: _ZTS1C = internal constant
-// CHECK: _ZTI1C = internal unnamed_addr constant
-// CHECK: _ZTIP1C = internal unnamed_addr constant
-// CHECK: _ZTSPP1C = internal constant
-// CHECK: _ZTIPP1C = internal unnamed_addr constant
-// CHECK: _ZTSM1Ci = internal constant
-// CHECK: _ZTIM1Ci = internal unnamed_addr constant
-// CHECK: _ZTSPM1Ci = internal constant
-// CHECK: _ZTIPM1Ci = internal unnamed_addr constant
-// CHECK: _ZTSM1CS_ = internal constant
-// CHECK: _ZTIM1CS_ = internal unnamed_addr constant
-// CHECK: _ZTSM1CPS_ = internal constant
-// CHECK: _ZTIM1CPS_ = internal unnamed_addr constant
-// CHECK: _ZTSM1A1C = internal constant
-// CHECK: _ZTS1A = linkonce_odr constant
-// CHECK: _ZTI1A = linkonce_odr hidden unnamed_addr constant
-// CHECK: _ZTIM1A1C = internal unnamed_addr constant
-// CHECK: _ZTSM1AP1C = internal constant
-// CHECK: _ZTIM1AP1C = internal unnamed_addr constant
 // CHECK: _ZTSN12_GLOBAL__N_11DE = internal constant
-// CHECK: _ZTIN12_GLOBAL__N_11DE = internal unnamed_addr constant
+// CHECK: _ZTIN12_GLOBAL__N_11DE = internal constant
 // CHECK: _ZTSPN12_GLOBAL__N_11DE = internal constant
-// CHECK: _ZTIPN12_GLOBAL__N_11DE = internal unnamed_addr constant
+// CHECK: _ZTIPN12_GLOBAL__N_11DE = internal constant
 // CHECK: _ZTSFN12_GLOBAL__N_11DEvE = internal constant
-// CHECK: _ZTIFN12_GLOBAL__N_11DEvE = internal unnamed_addr constant
+// CHECK: _ZTIFN12_GLOBAL__N_11DEvE = internal constant
 // CHECK: _ZTSFvN12_GLOBAL__N_11DEE = internal constant
-// CHECK: _ZTIFvN12_GLOBAL__N_11DEE = internal unnamed_addr constant
+// CHECK: _ZTIFvN12_GLOBAL__N_11DEE = internal constant
 // CHECK: _ZTSPFvvE = linkonce_odr constant
 // CHECK: _ZTSFvvE = linkonce_odr constant
-// CHECK: _ZTIFvvE = linkonce_odr hidden unnamed_addr constant
-// CHECK: _ZTIPFvvE = linkonce_odr hidden unnamed_addr constant
+// CHECK: _ZTIFvvE = linkonce_odr constant
+// CHECK: _ZTIPFvvE = linkonce_odr constant
 // CHECK: _ZTSN12_GLOBAL__N_11EE = internal constant
-// CHECK: _ZTIN12_GLOBAL__N_11EE = internal unnamed_addr constant
+// CHECK: _ZTIN12_GLOBAL__N_11EE = internal constant
 // CHECK: _ZTSA10_i = linkonce_odr constant
-// CHECK: _ZTIA10_i = linkonce_odr hidden unnamed_addr constant
-// CHECK: _ZTI1TILj0EE = linkonce_odr unnamed_addr constant
-// CHECK: _ZTI1TILj1EE = weak_odr unnamed_addr constant
+// CHECK: _ZTIA10_i = linkonce_odr constant
+// CHECK: _ZTI1TILj0EE = linkonce_odr constant
+// CHECK: _ZTI1TILj1EE = weak_odr constant
 // CHECK: _ZTI1TILj2EE = external constant
+// CHECK: _ZTSZ2t5vE1A = internal constant
+// CHECK: _ZTIZ2t5vE1A = internal constant
 // CHECK: _ZTS1B = constant
-// CHECK: _ZTI1B = unnamed_addr constant
+// CHECK: _ZTI1B = constant
 // CHECK: _ZTS1F = linkonce_odr constant
+// CHECK: _ZTSPZ2t7vE1A = linkonce_odr constant
+// CHECK: _ZTSZ2t7vE1A = linkonce_odr constant
+// CHECK: _ZTIZ2t7vE1A = linkonce_odr constant
+// CHECK: _ZTIPZ2t7vE1A = linkonce_odr constant
+// CHECK: _ZTSZ2t6vE1A = linkonce_odr constant
+// CHECK: _ZTIZ2t6vE1A = linkonce_odr constant
 
 // CHECK: _ZTIN12_GLOBAL__N_11DE to
 
@@ -138,3 +157,25 @@
 void t4(const T4 *ptr) {
   const void *value = &typeid(ptr);
 }
+
+// rdar://16265084
+void t5() {
+  struct A {};
+  const void *value = &typeid(A);
+}
+
+inline void t6() {
+  struct A {};
+  const void *value = &typeid(A);
+}
+void t6_helper() {
+  t6();
+}
+
+inline void t7() {
+  struct A {};
+  const void *value = &typeid(A*);
+}
+void t7_helper() {
+  t7();
+}
diff --git a/test/CodeGenCXX/rtti-visibility.cpp b/test/CodeGenCXX/rtti-visibility.cpp
index 40cee06..5945be5 100644
--- a/test/CodeGenCXX/rtti-visibility.cpp
+++ b/test/CodeGenCXX/rtti-visibility.cpp
@@ -1,17 +1,15 @@
 // 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 -fhidden-weak-vtables -emit-llvm -o %t.hidden
 // RUN: FileCheck --check-prefix=CHECK-TEST1 %s < %t
 // RUN: FileCheck --check-prefix=CHECK-TEST2 %s < %t
-// RUN: FileCheck --check-prefix=CHECK-TEST2-HIDDEN %s < %t.hidden
 
 #include <typeinfo>
 
 namespace Test1 {
   // A is explicitly marked hidden, so all RTTI data should also be marked hidden.
   // CHECK-TEST1: @_ZTSN5Test11AE = linkonce_odr hidden constant
-  // CHECK-TEST1: @_ZTIN5Test11AE = linkonce_odr hidden unnamed_addr constant
+  // CHECK-TEST1: @_ZTIN5Test11AE = linkonce_odr hidden constant
   // CHECK-TEST1: @_ZTSPN5Test11AE = linkonce_odr hidden constant
-  // CHECK-TEST1: @_ZTIPN5Test11AE = linkonce_odr hidden unnamed_addr constant
+  // CHECK-TEST1: @_ZTIPN5Test11AE = linkonce_odr hidden constant
   struct __attribute__((visibility("hidden"))) A { };
 
   void f() {
@@ -23,12 +21,8 @@
 namespace Test2 {
   // A is weak, so its linkage should be linkoce_odr, but not marked hidden.
   // CHECK-TEST2: @_ZTSN5Test21AE = linkonce_odr constant
-  // CHECK-TEST2: @_ZTIN5Test21AE = linkonce_odr unnamed_addr constant
+  // CHECK-TEST2: @_ZTIN5Test21AE = linkonce_odr constant
   struct A { };
-
-  // With -fhidden-weak-vtables, the typeinfo for A is marked hidden, but not its name.
-  // CHECK-TEST2-HIDDEN: _ZTSN5Test21AE = linkonce_odr constant
-  // CHECK-TEST2-HIDDEN: @_ZTIN5Test21AE = linkonce_odr hidden unnamed_addr constant
   void f() {
     (void)typeid(A);
   }
diff --git a/test/CodeGenCXX/runtimecc.cpp b/test/CodeGenCXX/runtimecc.cpp
index 646c61e..2044883 100644
--- a/test/CodeGenCXX/runtimecc.cpp
+++ b/test/CodeGenCXX/runtimecc.cpp
@@ -45,7 +45,7 @@
 
 // CHECK: declare arm_aapcscc void @__cxa_throw(i8*, i8*, i8*)
 
-// CHECK-LABEL: define internal arm_aapcscc void @_GLOBAL__I_a()
+// CHECK-LABEL: define internal arm_aapcscc void @_GLOBAL__sub_I_runtimecc.cpp()
 // CHECK:   call arm_aapcscc void @__cxx_global_var_init()
 
 
diff --git a/test/CodeGenCXX/rvalue-references.cpp b/test/CodeGenCXX/rvalue-references.cpp
index 2e0fa82..66705bf 100644
--- a/test/CodeGenCXX/rvalue-references.cpp
+++ b/test/CodeGenCXX/rvalue-references.cpp
@@ -7,8 +7,8 @@
 
 B &getB();
 
-// CHECK-LABEL: define %struct.A* @_Z4getAv()
-// CHECK: call %struct.B* @_Z4getBv()
+// CHECK-LABEL: define dereferenceable({{[0-9]+}}) %struct.A* @_Z4getAv()
+// CHECK: call dereferenceable({{[0-9]+}}) %struct.B* @_Z4getBv()
 // CHECK-NEXT: bitcast %struct.B*
 // CHECK-NEXT: getelementptr inbounds i8*
 // CHECK-NEXT: bitcast i8* {{.*}} to %struct.A*
@@ -19,17 +19,17 @@
 int &&getIntXValue();
 int getIntPRValue();
 
-// CHECK-LABEL: define i32* @_Z2f0v()
-// CHECK: call i32* @_Z12getIntLValuev()
+// CHECK-LABEL: define dereferenceable({{[0-9]+}}) i32* @_Z2f0v()
+// CHECK: call dereferenceable({{[0-9]+}}) i32* @_Z12getIntLValuev()
 // CHECK-NEXT: ret i32*
 int &&f0() { return static_cast<int&&>(getIntLValue()); }
 
-// CHECK-LABEL: define i32* @_Z2f1v()
-// CHECK: call i32* @_Z12getIntXValuev()
+// CHECK-LABEL: define dereferenceable({{[0-9]+}}) i32* @_Z2f1v()
+// CHECK: call dereferenceable({{[0-9]+}}) i32* @_Z12getIntXValuev()
 // CHECK-NEXT: ret i32*
 int &&f1() { return static_cast<int&&>(getIntXValue()); }
 
-// CHECK-LABEL: define i32* @_Z2f2v
+// CHECK-LABEL: define dereferenceable({{[0-9]+}}) i32* @_Z2f2v
 // CHECK: call i32 @_Z13getIntPRValuev()
 // CHECK-NEXT: store i32 {{.*}}, i32*
 // CHECK-NEXT: ret i32*
@@ -95,7 +95,7 @@
   };
 
   // CHECK-LABEL:    define void @_ZN5test11BC2Ei(
-  // CHECK:      [[T0:%.*]] = call i32* @_ZN5test14moveERi(
+  // CHECK:      [[T0:%.*]] = call dereferenceable({{[0-9]+}}) i32* @_ZN5test14moveERi(
   // CHECK-NEXT: [[T1:%.*]] = load i32* [[T0]]
   // CHECK-NEXT: call void @_ZN5test11AC1Ei({{.*}}, i32 [[T1]])
   // CHECK-NEXT: ret void
diff --git a/test/CodeGenCXX/scoped-enums.cpp b/test/CodeGenCXX/scoped-enums.cpp
index 159172d..218013a 100644
--- a/test/CodeGenCXX/scoped-enums.cpp
+++ b/test/CodeGenCXX/scoped-enums.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
 
 // PR9923
 enum class Color { red, blue, green };
diff --git a/test/CodeGenCXX/sparcv9-abi.cpp b/test/CodeGenCXX/sparcv9-abi.cpp
new file mode 100644
index 0000000..128d648
--- /dev/null
+++ b/test/CodeGenCXX/sparcv9-abi.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple sparcv9-unknown-unknown -emit-llvm %s -o - | FileCheck %s
+
+struct pod {
+  int a, b;
+};
+
+void f0();
+void f1(struct pod);
+
+struct notpod {
+  int a, b;
+  ~notpod() { f0(); }
+};
+
+void f2(struct notpod);
+
+// CHECK-LABEL: caller
+// CHECK: call void @_Z2f13pod(i64
+// CHECK: call void @_Z2f26notpod(%struct.notpod*
+void caller()
+{
+  pod p1;
+  notpod p2;
+  f1(p1);
+  f2(p2);
+}
diff --git a/test/CodeGenCXX/specialized-static-data-mem-init.cpp b/test/CodeGenCXX/specialized-static-data-mem-init.cpp
index c2a2ddb..6879962 100644
--- a/test/CodeGenCXX/specialized-static-data-mem-init.cpp
+++ b/test/CodeGenCXX/specialized-static-data-mem-init.cpp
@@ -1,9 +1,9 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o - | FileCheck %s
 // rdar: // 8562966
 // pr8409
 
-// CHECK: @_ZN1CIiE11needs_guardE = weak_odr global
-// CHECK: @_ZGVN1CIiE11needs_guardE = weak_odr global
+// CHECK: @_ZN1CIiE11needs_guardE = linkonce_odr global
+// CHECK: @_ZGVN1CIiE11needs_guardE = linkonce_odr global
 
 struct K
 {
diff --git a/test/CodeGenCXX/split-stacks.cpp b/test/CodeGenCXX/split-stacks.cpp
new file mode 100644
index 0000000..3e12034
--- /dev/null
+++ b/test/CodeGenCXX/split-stacks.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang -target x86_64-linux-gnu -fsplit-stack -S -std=c++11 %s -emit-llvm -o - | FileCheck -check-prefix=CHECK-SEGSTK %s
+// RUN: %clang -target x86_64-linux-gnu -S -std=c++11 %s -emit-llvm -o - | FileCheck -check-prefix=CHECK-NOSEGSTK %s
+
+int foo() {
+  return 0;
+}
+
+template <typename T>
+[[gnu::no_split_stack]]
+int tnosplit() {
+  return 0;
+}
+
+[[gnu::no_split_stack]]
+int nosplit() {
+  return tnosplit<int>();
+}
+
+// CHECK-SEGSTK: define i32 @_Z3foov() [[SS:#[0-9]+]] {
+// CHECK-SEGSTK: define i32 @_Z7nosplitv() [[NSS1:#[0-9]+]] {
+// CHECK-SEGSTK: define linkonce_odr i32 @_Z8tnosplitIiEiv() [[NSS2:#[0-9]+]] {
+// CHECK-SEGSTK-NOT: [[NSS1]] = { {{.*}} "split-stack" {{.*}} }
+// CHECK-SEGSTK-NOT: [[NSS2]] = { {{.*}} "split-stack" {{.*}} }
+// CHECK-SEGSTK: [[SS]] = { {{.*}} "split-stack" {{.*}} }
+// CHECK-SEGSTK-NOT: [[NSS1]] = { {{.*}} "split-stack" {{.*}} }
+// CHECK-SEGSTK-NOT: [[NSS2]] = { {{.*}} "split-stack" {{.*}} }
+
+// CHECK-NOSEGSTK: define i32 @_Z3foov() [[NSS0:#[0-9]+]] {
+// CHECK-NOSEGSTK: define i32 @_Z7nosplitv() [[NSS1:#[0-9]+]] {
+// CHECK-NOSEGSTK: define linkonce_odr i32 @_Z8tnosplitIiEiv() [[NSS2:#[0-9]+]] {
+// CHECK-NOSEGSTK-NOT: [[NSS1]] = { {{.*}} "split-stack" {{.*}} }
+// CHECK-NOSEGSTK-NOT: [[NSS2]] = { {{.*}} "split-stack" {{.*}} }
+// CHECK-NOSEGSTK-NOT: [[NSS3]] = { {{.*}} "split-stack" {{.*}} }
diff --git a/test/CodeGenCXX/static-init-3.cpp b/test/CodeGenCXX/static-init-3.cpp
index dc28d5a..083e001 100644
--- a/test/CodeGenCXX/static-init-3.cpp
+++ b/test/CodeGenCXX/static-init-3.cpp
@@ -16,8 +16,8 @@
     }
 };
 
-// CHECK: @_ZN2X1I2X2I1BEE8instanceE = weak_odr global %struct.X2* null, align 8
-// CHECJ: @_ZN2X1I2X2I1AEE8instanceE = weak_odr global %struct.X2* null, align 8
+// CHECK: @_ZN2X1I2X2I1BEE8instanceE = linkonce_odr global %struct.X2* null, align 8
+// CHECJ: @_ZN2X1I2X2I1AEE8instanceE = linkonce_odr global %struct.X2* null, align 8
 template<class T> T & X1<T>::instance = X1<T>::get();
 
 class A { };
diff --git a/test/CodeGenCXX/static-init.cpp b/test/CodeGenCXX/static-init.cpp
index f522775..d23ead4 100644
--- a/test/CodeGenCXX/static-init.cpp
+++ b/test/CodeGenCXX/static-init.cpp
@@ -103,14 +103,14 @@
   B::B() {
     static int x = foo();
   }
-  // CHECK-LABEL: define void @_ZN5test21BC1Ev
+  // CHECK-LABEL: define void @_ZN5test21BC2Ev
   // CHECK:   load atomic i8* bitcast (i64* @_ZGVZN5test21BC1EvE1x to i8*) acquire,
   // CHECK:   call i32 @__cxa_guard_acquire(i64* @_ZGVZN5test21BC1EvE1x)
   // CHECK:   [[T0:%.*]] = call i32 @_ZN5test23fooEv()
   // CHECK:   store i32 [[T0]], i32* @_ZZN5test21BC1EvE1x,
   // CHECK:   call void @__cxa_guard_release(i64* @_ZGVZN5test21BC1EvE1x)
 
-  // CHECK-LABEL: define void @_ZN5test21BC2Ev
+  // CHECK-LABEL: define void @_ZN5test21BC1Ev
   // CHECK:   load atomic i8* bitcast (i64* @_ZGVZN5test21BC1EvE1x to i8*) acquire,
   // CHECK:   call i32 @__cxa_guard_acquire(i64* @_ZGVZN5test21BC1EvE1x)
   // CHECK:   [[T0:%.*]] = call i32 @_ZN5test23fooEv()
@@ -122,15 +122,15 @@
   B::~B() {
     static int y = foo();
   }
-  // CHECK-LABEL: define void @_ZN5test21BD1Ev(
-  // CHECK:   call void @_ZN5test21BD2Ev(
-
   // CHECK-LABEL: define void @_ZN5test21BD2Ev(
   // CHECK:   load atomic i8* bitcast (i64* @_ZGVZN5test21BD1EvE1y to i8*) acquire,
   // CHECK:   call i32 @__cxa_guard_acquire(i64* @_ZGVZN5test21BD1EvE1y)
   // CHECK:   [[T0:%.*]] = call i32 @_ZN5test23fooEv()
   // CHECK:   store i32 [[T0]], i32* @_ZZN5test21BD1EvE1y,
   // CHECK:   call void @__cxa_guard_release(i64* @_ZGVZN5test21BD1EvE1y)
+
+  // CHECK-LABEL: define void @_ZN5test21BD1Ev(
+  // CHECK:   call void @_ZN5test21BD2Ev(
 }
 
 // This shouldn't error out.
@@ -149,6 +149,6 @@
     union U { char x; int i; };
     static U u = { 'a' };
   }
-  // CHECK-LABEL: define void @_ZN5test31BC1Ev(
   // CHECK-LABEL: define void @_ZN5test31BC2Ev(
+  // CHECK-LABEL: define void @_ZN5test31BC1Ev(
 }
diff --git a/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp b/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp
index 50772bf..98c09b8 100644
--- a/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp
+++ b/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp
@@ -12,21 +12,21 @@
 // CHECK: @_ZN1AIbE1aE = global i32 10
 template<> int A<bool>::a = 10;
 
-// CHECK: @llvm.global_ctors = appending global [7 x { i32, void ()* }]
-// CHECK: [{ i32, void ()* } { i32 65535, void ()* @[[unordered1:[^ ]*]] },
-// CHECK:  { i32, void ()* } { i32 65535, void ()* @[[unordered2:[^ ]*]] },
-// CHECK:  { i32, void ()* } { i32 65535, void ()* @[[unordered3:[^ ]*]] },
-// CHECK:  { i32, void ()* } { i32 65535, void ()* @[[unordered4:[^ ]*]] },
-// CHECK:  { i32, void ()* } { i32 65535, void ()* @[[unordered5:[^ ]*]] },
-// CHECK:  { i32, void ()* } { i32 65535, void ()* @[[unordered6:[^ ]*]] },
-// CHECK:  { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_a }]
+// CHECK: @llvm.global_ctors = appending global [7 x { i32, void ()*, i8* }]
+// CHECK: [{ i32, void ()*, i8* } { i32 65535, void ()* @[[unordered1:[^,]*]], i8* bitcast (i32* @_ZN1AIsE1aE to i8*) },
+// CHECK:  { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered2:[^,]*]], i8* bitcast (i16* @_Z1xIsE to i8*) },
+// CHECK:  { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered3:[^,]*]], i8* bitcast (i32* @_ZN2ns1aIiE1iE to i8*) },
+// CHECK:  { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered4:[^,]*]], i8* bitcast (i32* @_ZN2ns1b1iIiEE to i8*) },
+// CHECK:  { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered5:[^,]*]], i8* bitcast (i32* @_ZN1AIvE1aE to i8*) },
+// CHECK:  { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered6:[^,]*]], i8* @_Z1xIcE },
+// CHECK:  { i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_static_member_variable_explicit_specialization.cpp, i8* null }]
 
 template int A<short>::a;  // Unordered
 int b = foo();
 int c = foo();
 int d = A<void>::a; // Unordered
 
-// An explicit specialization is ordered, and goes in __GLOBAL_I_a.
+// An explicit specialization is ordered, and goes in __GLOBAL_sub_I_static_member_variable_explicit_specialization.cpp.
 template<> struct A<int> { static int a; };
 int A<int>::a = foo();
 
@@ -82,7 +82,7 @@
 // CHECK: store {{.*}} @_Z1xIcE
 // CHECK: ret
 
-// CHECK: define internal void @_GLOBAL__I_a()
+// CHECK: define internal void @_GLOBAL__sub_I_static_member_variable_explicit_specialization.cpp()
 //   We call unique stubs for every ordered dynamic initializer in the TU.
 // CHECK: call
 // CHECK: call
diff --git a/test/CodeGenCXX/stmtexpr.cpp b/test/CodeGenCXX/stmtexpr.cpp
index 5d4d6bc..7bf19bb 100644
--- a/test/CodeGenCXX/stmtexpr.cpp
+++ b/test/CodeGenCXX/stmtexpr.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -Wno-unused-value -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -Wno-unused-value -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
 // rdar: //8540501
 extern "C" int printf(...);
 extern "C" void abort();
diff --git a/test/CodeGenCXX/template-dependent-bind-temporary.cpp b/test/CodeGenCXX/template-dependent-bind-temporary.cpp
index ca980c3..47d8279 100644
--- a/test/CodeGenCXX/template-dependent-bind-temporary.cpp
+++ b/test/CodeGenCXX/template-dependent-bind-temporary.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o - | FileCheck %s
 // rdar: //8620524
 // PR7851
 struct string {
diff --git a/test/CodeGenCXX/template-inner-struct-visibility-hidden.cpp b/test/CodeGenCXX/template-inner-struct-visibility-hidden.cpp
index de86f10..137792b 100644
--- a/test/CodeGenCXX/template-inner-struct-visibility-hidden.cpp
+++ b/test/CodeGenCXX/template-inner-struct-visibility-hidden.cpp
@@ -1,9 +1,9 @@
-// RUN: %clang_cc1 -fvisibility hidden -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fvisibility hidden -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
 
 // Verify that symbols are hidden.
 // CHECK: @_ZN1CIiE5Inner6Inner26StaticE = weak_odr hidden global
-// CHECK-LABEL: define weak_odr hidden void @_ZN1CIiE5Inner1fEv
-// CHECK-LABEL: define weak_odr hidden void @_ZN1CIiE5Inner6Inner21gEv
+// CHECK-LABEL: define weak_odr hidden {{.*}}void @_ZN1CIiE5Inner1fEv
+// CHECK-LABEL: define weak_odr hidden {{.*}}void @_ZN1CIiE5Inner6Inner21gEv
 
 template<typename T>
 struct C {
diff --git a/test/CodeGenCXX/template-instantiation.cpp b/test/CodeGenCXX/template-instantiation.cpp
index 80283a1..90b8099 100644
--- a/test/CodeGenCXX/template-instantiation.cpp
+++ b/test/CodeGenCXX/template-instantiation.cpp
@@ -5,10 +5,14 @@
 //
 // CHECK-NOT: @_ZTVN5test118stdio_sync_filebufIwEE = constant
 // CHECK-NOT: _ZTVN5test315basic_fstreamXXIcEE
-// CHECK: @_ZTVN5test018stdio_sync_filebufIwEE = unnamed_addr constant
+// CHECK-NOT: @_ZTVN5test018stdio_sync_filebufIA1_iEE
+// CHECK-NOT: @_ZTVN5test018stdio_sync_filebufIA2_iEE
+// CHECK:     @_ZTVN5test018stdio_sync_filebufIA3_iEE = weak_odr unnamed_addr constant
 
-// CHECK: @_ZN7PR100011SIiE3arrE = weak_odr global [3 x i32]
-// CHECK-NOT: @_ZN7PR100011SIiE3arr2E = weak_odr global [3 x i32]A
+// CHECK: @_ZN7PR100011SIiE3arrE = linkonce_odr global [3 x i32]
+// CHECK-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
@@ -39,11 +43,21 @@
     virtual void      xsgetn();
   };
 
-  // This specialization should cause the vtable to be emitted, even with
-  // the following extern template declaration.
-  template<> void stdio_sync_filebuf<wchar_t>::xsgetn()  {
+  // This specialization is not a key function, so doesn't cause the vtable to
+  // be instantiated unless we're instantiating a class definition anyway.
+  template<> void stdio_sync_filebuf<int[1]>::xsgetn()  {
   }
-  extern template class stdio_sync_filebuf<wchar_t>;
+  template<> void stdio_sync_filebuf<int[2]>::xsgetn()  {
+  }
+  template<> void stdio_sync_filebuf<int[3]>::xsgetn()  {
+  }
+  template<> void stdio_sync_filebuf<int[4]>::xsgetn()  {
+  }
+  extern template class stdio_sync_filebuf<int[2]>;
+
+  // These two both cause vtables to be emitted.
+  template class stdio_sync_filebuf<int[3]>;
+  stdio_sync_filebuf<int[4]> implicit_instantiation;
 }
 
 namespace test1 {
diff --git a/test/CodeGenCXX/temporaries.cpp b/test/CodeGenCXX/temporaries.cpp
index e8a7a1f..7f5c7af 100644
--- a/test/CodeGenCXX/temporaries.cpp
+++ b/test/CodeGenCXX/temporaries.cpp
@@ -3,8 +3,8 @@
 namespace PR16263 {
   const unsigned int n = 1234;
   extern const int &r = (const int&)n;
-  // CHECK: @_ZGRN7PR162631rE = private constant i32 1234,
-  // CHECK: @_ZN7PR162631rE = constant i32* @_ZGRN7PR162631rE,
+  // CHECK: @_ZGRN7PR162631rE_ = private constant i32 1234,
+  // CHECK: @_ZN7PR162631rE = constant i32* @_ZGRN7PR162631rE_,
 
   extern const int &s = reinterpret_cast<const int&>(n);
   // CHECK: @_ZN7PR16263L1nE = internal constant i32 1234, align 4
@@ -14,17 +14,32 @@
   struct B { int n; };
   struct C : A, B {};
   extern const A &&a = (A&&)(A&&)(C&&)(C{});
-  // CHECK: @_ZGRN7PR162631aE = private global {{.*}} zeroinitializer,
-  // CHECK: @_ZN7PR162631aE = constant {{.*}} bitcast ({{.*}}* @_ZGRN7PR162631aE to
+  // CHECK: @_ZGRN7PR162631aE_ = private global {{.*}} zeroinitializer,
+  // CHECK: @_ZN7PR162631aE = constant {{.*}} bitcast ({{.*}}* @_ZGRN7PR162631aE_ to
 
   extern const int &&t = ((B&&)C{}).n;
-  // CHECK: @_ZGRN7PR162631tE = private global {{.*}} zeroinitializer,
-  // CHECK: @_ZN7PR162631tE = constant i32* {{.*}}* @_ZGRN7PR162631tE {{.*}} 4
+  // CHECK: @_ZGRN7PR162631tE_ = private global {{.*}} zeroinitializer,
+  // CHECK: @_ZN7PR162631tE = constant i32* {{.*}}* @_ZGRN7PR162631tE_ {{.*}} 4
 
   struct D { double d; C c; };
   extern const int &&u = (123, static_cast<B&&>(0, ((D&&)D{}).*&D::c).n);
-  // CHECK: @_ZGRN7PR162631uE = private global {{.*}} zeroinitializer
-  // CHECK: @_ZN7PR162631uE = constant i32* {{.*}} @_ZGRN7PR162631uE {{.*}} 12
+  // CHECK: @_ZGRN7PR162631uE_ = private global {{.*}} zeroinitializer
+  // CHECK: @_ZN7PR162631uE = constant i32* {{.*}} @_ZGRN7PR162631uE_ {{.*}} 12
+}
+
+namespace PR20227 {
+  struct A { ~A(); };
+  struct B { virtual ~B(); };
+  struct C : B {};
+
+  A &&a = dynamic_cast<A&&>(A{});
+  // CHECK: @_ZGRN7PR202271aE_ = private global
+
+  B &&b = dynamic_cast<C&&>(dynamic_cast<B&&>(C{}));
+  // CHECK: @_ZGRN7PR202271bE_ = private global
+
+  B &&c = static_cast<C&&>(static_cast<B&&>(C{}));
+  // CHECK: @_ZGRN7PR202271cE_ = private global
 }
 
 struct A {
@@ -310,7 +325,7 @@
 void g() {
   // CHECK: call void @_ZN3T121AC1Ev
   // CHECK-NEXT: call i32 @_ZN3T121A1fEv(
-  // CHECK-NEXT: call i32* @_ZN3T121fEi(
+  // CHECK-NEXT: call dereferenceable({{[0-9]+}}) i32* @_ZN3T121fEi(
   // CHECK-NEXT: call void @_ZN3T121AD1Ev(
   int& i = f(A().f());
 }
@@ -325,7 +340,7 @@
   struct D;
   D& zed(B);
   void foobar() {
-    // CHECK: call %"struct.PR6648::D"* @_ZN6PR66483zedENS_1BE
+    // CHECK: call nonnull %"struct.PR6648::D"* @_ZN6PR66483zedENS_1BE
     zed(foo);
   }
 }
@@ -412,10 +427,10 @@
     // CHECK-NEXT: [[J:%.*]] = alloca [[A]], align 8
 
     // CHECK:      call void @_ZN7Elision1AC1Ev([[A]]* [[I]])
-    // CHECK:      call void @_ZN7Elision1AC1ERKS0_([[A]]* [[I]], [[A]]* [[X:%.*]])
+    // CHECK:      call void @_ZN7Elision1AC1ERKS0_([[A]]* [[I]], [[A]]* dereferenceable({{[0-9]+}}) [[X:%.*]])
     A i = (c ? A() : x);
 
-    // CHECK:      call void @_ZN7Elision1AC1ERKS0_([[A]]* [[J]], [[A]]* [[X]])
+    // CHECK:      call void @_ZN7Elision1AC1ERKS0_([[A]]* [[J]], [[A]]* dereferenceable({{[0-9]+}}) [[X]])
     // CHECK:      call void @_ZN7Elision1AC1Ev([[A]]* [[J]])
     A j = (c ? x : A());
 
@@ -435,10 +450,10 @@
   A test3(int v, A x) {
     if (v < 5)
     // CHECK:      call void @_ZN7Elision1AC1Ev([[A]]* [[RET:%.*]])
-    // CHECK:      call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET]], [[A]]* [[X:%.*]])
+    // CHECK:      call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET]], [[A]]* dereferenceable({{[0-9]+}}) [[X:%.*]])
       return (v < 0 ? A() : x);
     else
-    // CHECK:      call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET]], [[A]]* [[X]])
+    // CHECK:      call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET]], [[A]]* dereferenceable({{[0-9]+}}) [[X]])
     // CHECK:      call void @_ZN7Elision1AC1Ev([[A]]* [[RET]])
       return (v > 10 ? x : A());
 
@@ -456,7 +471,7 @@
     // CHECK-NEXT: [[XS0:%.*]] = getelementptr inbounds [2 x [[A]]]* [[XS]], i64 0, i64 0
     // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[XS0]])
     // CHECK-NEXT: [[XS1:%.*]] = getelementptr inbounds [[A]]* [[XS0]], i64 1
-    // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[XS1]], [[A]]* [[X]])
+    // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[XS1]], [[A]]* dereferenceable({{[0-9]+}}) [[X]])
     A xs[] = { A(), x };
 
     // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [2 x [[A]]]* [[XS]], i32 0, i32 0
@@ -483,7 +498,7 @@
 
     // CHECK:      call void @_ZN7Elision1BC1Ev([[B]]* [[BT0]])
     // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]]* [[BT0]], i32 0, i32 0
-    // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[AT0]], [[A]]* [[AM]])
+    // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[AT0]], [[A]]* dereferenceable({{[0-9]+}}) [[AM]])
     // CHECK-NEXT: call void @_ZN7Elision5takeAENS_1AE([[A]]* [[AT0]])
     // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[AT0]])
     // CHECK-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT0]])
@@ -491,13 +506,13 @@
 
     // CHECK-NEXT: call void @_ZN7Elision1BC1Ev([[B]]* [[BT1]])
     // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]]* [[BT1]], i32 0, i32 0
-    // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[X]], [[A]]* [[AM]])
+    // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[X]], [[A]]* dereferenceable({{[0-9]+}}) [[AM]])
     // CHECK-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT1]])
     A x = B().a;
 
     // CHECK-NEXT: call void @_ZN7Elision1BC1Ev([[B]]* [[BT2]])
     // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]]* [[BT2]], i32 0, i32 0
-    // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET:%.*]], [[A]]* [[AM]])
+    // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET:%.*]], [[A]]* dereferenceable({{[0-9]+}}) [[AM]])
     // CHECK-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT2]])
     return B().a;
 
@@ -596,23 +611,23 @@
 
   void f(), g();
 
-  // CHECK: call void @_ZN15BindToSubobject1AC1Ev({{.*}} @_ZGRN15BindToSubobject1aE)
-  // CHECK: call i32 @__cxa_atexit({{.*}} bitcast ({{.*}} @_ZN15BindToSubobject1AD1Ev to void (i8*)*), i8* bitcast ({{.*}} @_ZGRN15BindToSubobject1aE to i8*), i8* @__dso_handle)
-  // CHECK: store i32* getelementptr inbounds ({{.*}} @_ZGRN15BindToSubobject1aE, i32 0, i32 0), i32** @_ZN15BindToSubobject1aE, align 8
+  // CHECK: call void @_ZN15BindToSubobject1AC1Ev({{.*}} @_ZGRN15BindToSubobject1aE_)
+  // CHECK: call i32 @__cxa_atexit({{.*}} bitcast ({{.*}} @_ZN15BindToSubobject1AD1Ev to void (i8*)*), i8* bitcast ({{.*}} @_ZGRN15BindToSubobject1aE_ to i8*), i8* @__dso_handle)
+  // CHECK: store i32* getelementptr inbounds ({{.*}} @_ZGRN15BindToSubobject1aE_, i32 0, i32 0), i32** @_ZN15BindToSubobject1aE, align 8
   int &&a = A().a;
 
   // CHECK: call void @_ZN15BindToSubobject1fEv()
-  // CHECK: call void @_ZN15BindToSubobject1AC1Ev({{.*}} @_ZGRN15BindToSubobject1bE)
-  // CHECK: call i32 @__cxa_atexit({{.*}} bitcast ({{.*}} @_ZN15BindToSubobject1AD1Ev to void (i8*)*), i8* bitcast ({{.*}} @_ZGRN15BindToSubobject1bE to i8*), i8* @__dso_handle)
-  // CHECK: store i32* getelementptr inbounds ({{.*}} @_ZGRN15BindToSubobject1bE, i32 0, i32 0), i32** @_ZN15BindToSubobject1bE, align 8
+  // CHECK: call void @_ZN15BindToSubobject1AC1Ev({{.*}} @_ZGRN15BindToSubobject1bE_)
+  // CHECK: call i32 @__cxa_atexit({{.*}} bitcast ({{.*}} @_ZN15BindToSubobject1AD1Ev to void (i8*)*), i8* bitcast ({{.*}} @_ZGRN15BindToSubobject1bE_ to i8*), i8* @__dso_handle)
+  // CHECK: store i32* getelementptr inbounds ({{.*}} @_ZGRN15BindToSubobject1bE_, i32 0, i32 0), i32** @_ZN15BindToSubobject1bE, align 8
   int &&b = (f(), A().a);
 
   int A::*h();
 
   // CHECK: call void @_ZN15BindToSubobject1fEv()
   // CHECK: call void @_ZN15BindToSubobject1gEv()
-  // CHECK: call void @_ZN15BindToSubobject1AC1Ev({{.*}} @_ZGRN15BindToSubobject1cE)
-  // CHECK: call i32 @__cxa_atexit({{.*}} bitcast ({{.*}} @_ZN15BindToSubobject1AD1Ev to void (i8*)*), i8* bitcast ({{.*}} @_ZGRN15BindToSubobject1cE to i8*), i8* @__dso_handle)
+  // CHECK: call void @_ZN15BindToSubobject1AC1Ev({{.*}} @_ZGRN15BindToSubobject1cE_)
+  // CHECK: call i32 @__cxa_atexit({{.*}} bitcast ({{.*}} @_ZN15BindToSubobject1AD1Ev to void (i8*)*), i8* bitcast ({{.*}} @_ZGRN15BindToSubobject1cE_ to i8*), i8* @__dso_handle)
   // CHECK: call {{.*}} @_ZN15BindToSubobject1hE
   // CHECK: getelementptr
   // CHECK: store i32* {{.*}}, i32** @_ZN15BindToSubobject1cE, align 8
@@ -623,8 +638,8 @@
     A a;
   };
 
-  // CHECK: call void @_ZN15BindToSubobject1BC1Ev({{.*}} @_ZGRN15BindToSubobject1dE)
-  // CHECK: call i32 @__cxa_atexit({{.*}} bitcast ({{.*}} @_ZN15BindToSubobject1BD1Ev to void (i8*)*), i8* bitcast ({{.*}} @_ZGRN15BindToSubobject1dE to i8*), i8* @__dso_handle)
+  // CHECK: call void @_ZN15BindToSubobject1BC1Ev({{.*}} @_ZGRN15BindToSubobject1dE_)
+  // CHECK: call i32 @__cxa_atexit({{.*}} bitcast ({{.*}} @_ZN15BindToSubobject1BD1Ev to void (i8*)*), i8* bitcast ({{.*}} @_ZGRN15BindToSubobject1dE_ to i8*), i8* @__dso_handle)
   // CHECK: call {{.*}} @_ZN15BindToSubobject1hE
   // CHECK: getelementptr {{.*}} getelementptr
   // CHECK: store i32* {{.*}}, i32** @_ZN15BindToSubobject1dE, align 8
@@ -637,9 +652,9 @@
   // Do not lifetime extend the S() temporary here.
   // CHECK: alloca
   // CHECK: call {{.*}}memset
-  // CHECK: store i32 {{.*}}, i32* @_ZGRN8Bitfield1rE
+  // CHECK: store i32 {{.*}}, i32* @_ZGRN8Bitfield1rE_
   // CHECK: call void @_ZN8Bitfield1SD1
-  // CHECK: store i32* @_ZGRN8Bitfield1rE, i32** @_ZN8Bitfield1rE, align 8
+  // CHECK: store i32* @_ZGRN8Bitfield1rE_, i32** @_ZN8Bitfield1rE, align 8
   int &&r = S().a;
 }
 
@@ -652,14 +667,14 @@
   };
   // CHECK: alloca
   // CHECK: extractelement
-  // CHECK: store i32 {{.*}}, i32* @_ZGRN6Vector1rE
-  // CHECK: store i32* @_ZGRN6Vector1rE, i32** @_ZN6Vector1rE,
+  // CHECK: store i32 {{.*}}, i32* @_ZGRN6Vector1rE_
+  // CHECK: store i32* @_ZGRN6Vector1rE_, i32** @_ZN6Vector1rE,
   int &&r = S().v[1];
 
   // CHECK: alloca
   // CHECK: extractelement
-  // CHECK: store i32 {{.*}}, i32* @_ZGRN6Vector1sE
-  // CHECK: store i32* @_ZGRN6Vector1sE, i32** @_ZN6Vector1sE,
+  // CHECK: store i32 {{.*}}, i32* @_ZGRN6Vector1sE_
+  // CHECK: store i32* @_ZGRN6Vector1sE_, i32** @_ZN6Vector1sE,
   int &&s = S().w[1];
   // FIXME PR16204: The following code leads to an assertion in Sema.
   //int &&s = S().w.y;
@@ -761,8 +776,8 @@
   struct S { S(int); };
   struct U { S &&s; };
   U v { { 0 } };
-  // CHECK: call void @_ZN7PR141301SC1Ei({{.*}} @_ZGRN7PR141301vE, i32 0)
-  // CHECK: store {{.*}} @_ZGRN7PR141301vE, {{.*}} @_ZN7PR141301vE
+  // CHECK: call void @_ZN7PR141301SC1Ei({{.*}} @_ZGRN7PR141301vE_, i32 0)
+  // CHECK: store {{.*}} @_ZGRN7PR141301vE_, {{.*}} @_ZN7PR141301vE
 }
 
 namespace Ctor {
diff --git a/test/CodeGenCXX/throw-expression-dtor.cpp b/test/CodeGenCXX/throw-expression-dtor.cpp
index cb4a6c6..b883b85 100644
--- a/test/CodeGenCXX/throw-expression-dtor.cpp
+++ b/test/CodeGenCXX/throw-expression-dtor.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -emit-llvm-only -verify -fcxx-exceptions -fexceptions
+// RUN: %clang_cc1 %s -emit-llvm-only -verify -triple %itanium_abi_triple -fcxx-exceptions -fexceptions
 // expected-no-diagnostics
 // PR7281
 
diff --git a/test/CodeGenCXX/throw-expressions.cpp b/test/CodeGenCXX/throw-expressions.cpp
index d9bf8fd..4dd5322 100644
--- a/test/CodeGenCXX/throw-expressions.cpp
+++ b/test/CodeGenCXX/throw-expressions.cpp
@@ -67,3 +67,48 @@
 //
 // end:
 // CHECK: ret i32
+
+namespace DR1560 {
+  struct A {
+    ~A();
+  };
+  extern bool b;
+  A get();
+  // CHECK-LABEL: @_ZN6DR15601bE
+  const A &r = b ? get() : throw 0;
+  // CHECK-NOT: call {{.*}}@_ZN6DR15601AD1Ev
+  // CHECK: call {{.*}} @__cxa_atexit({{.*}} @_ZN6DR15601AD1Ev {{.*}} @_ZGRN6DR15601rE
+  // CHECK-NOT: call {{.*}}@_ZN6DR15601AD1Ev
+}
+
+// CHECK-LABEL: define void @_Z5test7b(
+void test7(bool cond) {
+  // CHECK: br i1
+  //
+  // x.true:
+  // CHECK: call void @__cxa_throw(
+  // CHECK-NEXT: unreachable
+  //
+  // x.false:
+  // CHECK: br label
+  //
+  // end:
+  // CHECK: ret void
+  cond ? throw test7 : val;
+}
+
+// CHECK-LABEL: define dereferenceable(4) i32* @_Z5test8b(
+int &test8(bool cond) {
+  // CHECK: br i1
+  //
+  // x.true:
+  // CHECK: br label
+  //
+  // x.false:
+  // CHECK: call void @__cxa_throw(
+  // CHECK-NEXT: unreachable
+  //
+  // end:
+  // CHECK: ret i32* @val
+  return cond ? val : ((throw "foo"));
+}
diff --git a/test/CodeGenCXX/thunk-use-after-free.cpp b/test/CodeGenCXX/thunk-use-after-free.cpp
index d70e902..14f2356 100644
--- a/test/CodeGenCXX/thunk-use-after-free.cpp
+++ b/test/CodeGenCXX/thunk-use-after-free.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm-only -O1 %s
+// RUN: %clang_cc1 -emit-llvm-only -triple %itanium_abi_triple -O1 %s
 // This used to crash under asan and valgrind.
 // PR12284
 
diff --git a/test/CodeGenCXX/thunks.cpp b/test/CodeGenCXX/thunks.cpp
index f5a85ef..89e4db3 100644
--- a/test/CodeGenCXX/thunks.cpp
+++ b/test/CodeGenCXX/thunks.cpp
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -munwind-tables -emit-llvm -o - | FileCheck %s
-// RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -munwind-tables -fhidden-weak-vtables -emit-llvm -o - | FileCheck -check-prefix=CHECK-HIDDEN %s
+// RUN: %clang_cc1 %s -triple=x86_64-pc-linux-gnu -munwind-tables -emit-llvm -o - -O1 -disable-llvm-optzns | FileCheck %s
 
 namespace Test1 {
 
@@ -250,9 +250,7 @@
   struct B { virtual void foo(); };
   struct C : A, B { void foo() {} };
 
-  // CHECK-HIDDEN-LABEL: define linkonce_odr void @_ZN6Test101C3fooEv
-  // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZThn8_N6Test101C3fooEv
-
+  // Test later.
   void test() {
     C c;
   }
@@ -342,8 +340,33 @@
   // CHECK: define void @_ZThn8_N6Test141C1fEv({{.*}}) unnamed_addr [[NUW:#[0-9]+]]
 }
 
+// Varargs non-covariant thunk test.
+// PR18098
+namespace Test15 {
+  struct A {
+    virtual ~A();
+  };
+  struct B {
+    virtual void f(int x, ...);
+  };
+  struct C : A, B {
+    virtual void c();
+    virtual void f(int x, ...);
+  };
+  void C::c() {}
+
+  // C::c
+  // CHECK: declare void @_ZN6Test151C1fEiz
+  // non-virtual thunk to C::f
+  // CHECK: declare void @_ZThn8_N6Test151C1fEiz
+}
+
 /**** The following has to go at the end of the file ****/
 
+// This is from Test10:
+// CHECK-LABEL: define linkonce_odr void @_ZN6Test101C3fooEv
+// CHECK-LABEL: define linkonce_odr void @_ZThn8_N6Test101C3fooEv
+
 // This is from Test5:
 // CHECK-LABEL: define linkonce_odr void @_ZTv0_n24_N5Test51B1fEv
 // CHECK-LABEL: define internal void @_ZThn8_N6Test4B12_GLOBAL__N_11C1fEv(
diff --git a/test/CodeGenCXX/tls-init-funcs.cpp b/test/CodeGenCXX/tls-init-funcs.cpp
index 17299dc..d47329c 100644
--- a/test/CodeGenCXX/tls-init-funcs.cpp
+++ b/test/CodeGenCXX/tls-init-funcs.cpp
@@ -1,10 +1,34 @@
-// RUN: %clang_cc1 -triple x86_64-apple-macosx10.8 -std=c++11 -S -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.8 -std=c++1y -S -emit-llvm %s -o - | FileCheck %s
 
 // CHECK: @a = internal thread_local global
+// CHECK: @_Z2vtIiE = internal thread_local global i32 5
+// CHECK: @_ZZ3inlvE3loc = linkonce_odr thread_local global i32 0
 // CHECK: @_tlv_atexit({{.*}}@_ZN1AD1Ev
+// CHECK: call i32* @_ZTW3ext()
+// CHECK: declare i32* @_ZTW3ext()
+// CHECK: define weak i32* @_ZTW2vtIiE()
+// CHECK: define weak i32* @_ZTW2vtIvE()
+// CHECK: define {{.*}} @_ZTW1a
 
 struct A {
   ~A();
 };
 
 thread_local A a;
+
+extern thread_local int ext;
+int &get_ext() { return ext; }
+
+template <typename T>
+thread_local int vt = 5;
+
+int get_vt() { return vt<int>; }
+
+inline int &inl() {
+  thread_local int loc;
+  return loc;
+}
+int &use_inl() { return inl(); }
+
+template int vt<void>;
+int &get_vt_void() { return vt<void>; }
diff --git a/test/CodeGenCXX/trivial-constructor-init.cpp b/test/CodeGenCXX/trivial-constructor-init.cpp
index 65ed45e..9130e4e 100644
--- a/test/CodeGenCXX/trivial-constructor-init.cpp
+++ b/test/CodeGenCXX/trivial-constructor-init.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -std=c++11 | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -std=c++11 -triple %itanium_abi_triple | FileCheck %s
 
 extern "C" int printf(...);
 
diff --git a/test/CodeGenCXX/type-traits.cpp b/test/CodeGenCXX/type-traits.cpp
new file mode 100644
index 0000000..93cc6b5
--- /dev/null
+++ b/test/CodeGenCXX/type-traits.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -emit-llvm-only -verify %s
+// expected-no-diagnostics
+
+bool a() { return __is_pod(int); }
+
+bool b() { return __is_trivially_constructible(int, int, int); }
diff --git a/test/CodeGenCXX/type_visibility.cpp b/test/CodeGenCXX/type_visibility.cpp
index 11e5091..a7b7198 100644
--- a/test/CodeGenCXX/type_visibility.cpp
+++ b/test/CodeGenCXX/type_visibility.cpp
@@ -29,11 +29,11 @@
   // FUNS-LABEL:        define weak_odr void @_ZN5temp01BINS_1AEE3fooEv(
   // VARS:        @_ZTVN5temp01BINS_1AEEE = weak_odr unnamed_addr constant
   // VARS:        @_ZTSN5temp01BINS_1AEEE = weak_odr constant
-  // VARS:        @_ZTIN5temp01BINS_1AEEE = weak_odr unnamed_addr constant
+  // VARS:        @_ZTIN5temp01BINS_1AEEE = weak_odr constant
   // FUNS-HIDDEN-LABEL: define weak_odr hidden void @_ZN5temp01BINS_1AEE3fooEv(
   // VARS-HIDDEN: @_ZTVN5temp01BINS_1AEEE = weak_odr hidden unnamed_addr constant
   // VARS-HIDDEN: @_ZTSN5temp01BINS_1AEEE = weak_odr hidden constant
-  // VARS-HIDDEN: @_ZTIN5temp01BINS_1AEEE = weak_odr hidden unnamed_addr constant
+  // VARS-HIDDEN: @_ZTIN5temp01BINS_1AEEE = weak_odr hidden constant
 }
 
 namespace temp1 {
@@ -46,11 +46,11 @@
   // FUNS-LABEL:        define weak_odr void @_ZN5temp11BINS_1AEE3fooEv(
   // VARS:        @_ZTVN5temp11BINS_1AEEE = weak_odr unnamed_addr constant
   // VARS:        @_ZTSN5temp11BINS_1AEEE = weak_odr constant
-  // VARS:        @_ZTIN5temp11BINS_1AEEE = weak_odr unnamed_addr constant
+  // VARS:        @_ZTIN5temp11BINS_1AEEE = weak_odr constant
   // FUNS-HIDDEN-LABEL: define weak_odr hidden void @_ZN5temp11BINS_1AEE3fooEv(
   // VARS-HIDDEN: @_ZTVN5temp11BINS_1AEEE = weak_odr unnamed_addr constant
   // VARS-HIDDEN: @_ZTSN5temp11BINS_1AEEE = weak_odr constant
-  // VARS-HIDDEN: @_ZTIN5temp11BINS_1AEEE = weak_odr unnamed_addr constant
+  // VARS-HIDDEN: @_ZTIN5temp11BINS_1AEEE = weak_odr constant
 }
 
 namespace temp2 {
@@ -63,11 +63,11 @@
   // FUNS-LABEL:        define weak_odr void @_ZN5temp21BINS_1AEE3fooEv(
   // VARS:        @_ZTVN5temp21BINS_1AEEE = weak_odr unnamed_addr constant
   // VARS:        @_ZTSN5temp21BINS_1AEEE = weak_odr constant
-  // VARS:        @_ZTIN5temp21BINS_1AEEE = weak_odr unnamed_addr constant
+  // VARS:        @_ZTIN5temp21BINS_1AEEE = weak_odr constant
   // FUNS-HIDDEN-LABEL: define weak_odr hidden void @_ZN5temp21BINS_1AEE3fooEv(
   // VARS-HIDDEN: @_ZTVN5temp21BINS_1AEEE = weak_odr hidden unnamed_addr constant
   // VARS-HIDDEN: @_ZTSN5temp21BINS_1AEEE = weak_odr hidden constant
-  // VARS-HIDDEN: @_ZTIN5temp21BINS_1AEEE = weak_odr hidden unnamed_addr constant
+  // VARS-HIDDEN: @_ZTIN5temp21BINS_1AEEE = weak_odr hidden constant
 }
 
 namespace temp3 {
@@ -80,11 +80,11 @@
   // FUNS-LABEL:        define weak_odr hidden void @_ZN5temp31BINS_1AEE3fooEv(
   // VARS:        @_ZTVN5temp31BINS_1AEEE = weak_odr hidden unnamed_addr constant
   // VARS:        @_ZTSN5temp31BINS_1AEEE = weak_odr hidden constant
-  // VARS:        @_ZTIN5temp31BINS_1AEEE = weak_odr hidden unnamed_addr constant
+  // VARS:        @_ZTIN5temp31BINS_1AEEE = weak_odr hidden constant
   // FUNS-HIDDEN-LABEL: define weak_odr hidden void @_ZN5temp31BINS_1AEE3fooEv(
   // VARS-HIDDEN: @_ZTVN5temp31BINS_1AEEE = weak_odr hidden unnamed_addr constant
   // VARS-HIDDEN: @_ZTSN5temp31BINS_1AEEE = weak_odr hidden constant
-  // VARS-HIDDEN: @_ZTIN5temp31BINS_1AEEE = weak_odr hidden unnamed_addr constant
+  // VARS-HIDDEN: @_ZTIN5temp31BINS_1AEEE = weak_odr hidden constant
 }
 
 namespace temp4 {
@@ -97,11 +97,11 @@
   // FUNS-LABEL:        define weak_odr void @_ZN5temp41BINS_1AEE3fooEv(
   // VARS:        @_ZTVN5temp41BINS_1AEEE = weak_odr hidden unnamed_addr constant
   // VARS:        @_ZTSN5temp41BINS_1AEEE = weak_odr hidden constant
-  // VARS:        @_ZTIN5temp41BINS_1AEEE = weak_odr hidden unnamed_addr constant
+  // VARS:        @_ZTIN5temp41BINS_1AEEE = weak_odr hidden constant
   // FUNS-HIDDEN-LABEL: define weak_odr hidden void @_ZN5temp41BINS_1AEE3fooEv(
   // VARS-HIDDEN: @_ZTVN5temp41BINS_1AEEE = weak_odr hidden unnamed_addr constant
   // VARS-HIDDEN: @_ZTSN5temp41BINS_1AEEE = weak_odr hidden constant
-  // VARS-HIDDEN: @_ZTIN5temp41BINS_1AEEE = weak_odr hidden unnamed_addr constant
+  // VARS-HIDDEN: @_ZTIN5temp41BINS_1AEEE = weak_odr hidden constant
 }
 
 namespace type0 {
@@ -113,11 +113,11 @@
   // FUNS-LABEL:        define void @_ZN5type01A3fooEv(
   // VARS:        @_ZTVN5type01AE = unnamed_addr constant
   // VARS:        @_ZTSN5type01AE = constant
-  // VARS:        @_ZTIN5type01AE = unnamed_addr constant
+  // VARS:        @_ZTIN5type01AE = constant
   // FUNS-HIDDEN-LABEL: define hidden void @_ZN5type01A3fooEv(
   // VARS-HIDDEN: @_ZTVN5type01AE = unnamed_addr constant
   // VARS-HIDDEN: @_ZTSN5type01AE = constant
-  // VARS-HIDDEN: @_ZTIN5type01AE = unnamed_addr constant
+  // VARS-HIDDEN: @_ZTIN5type01AE = constant
 }
 
 namespace type1 {
@@ -129,11 +129,11 @@
   // FUNS-LABEL:        define hidden void @_ZN5type11A3fooEv(
   // VARS:        @_ZTVN5type11AE = unnamed_addr constant
   // VARS:        @_ZTSN5type11AE = constant
-  // VARS:        @_ZTIN5type11AE = unnamed_addr constant
+  // VARS:        @_ZTIN5type11AE = constant
   // FUNS-HIDDEN-LABEL: define hidden void @_ZN5type11A3fooEv(
   // VARS-HIDDEN: @_ZTVN5type11AE = unnamed_addr constant
   // VARS-HIDDEN: @_ZTSN5type11AE = constant
-  // VARS-HIDDEN: @_ZTIN5type11AE = unnamed_addr constant
+  // VARS-HIDDEN: @_ZTIN5type11AE = constant
 }
 
 namespace type2 {
@@ -145,11 +145,11 @@
   // FUNS-LABEL:        define void @_ZN5type21A3fooEv(
   // VARS:        @_ZTVN5type21AE = hidden unnamed_addr constant
   // VARS:        @_ZTSN5type21AE = hidden constant
-  // VARS:        @_ZTIN5type21AE = hidden unnamed_addr constant
+  // VARS:        @_ZTIN5type21AE = hidden constant
   // FUNS-HIDDEN-LABEL: define hidden void @_ZN5type21A3fooEv(
   // VARS-HIDDEN: @_ZTVN5type21AE = hidden unnamed_addr constant
   // VARS-HIDDEN: @_ZTSN5type21AE = hidden constant
-  // VARS-HIDDEN: @_ZTIN5type21AE = hidden unnamed_addr constant
+  // VARS-HIDDEN: @_ZTIN5type21AE = hidden constant
 }
 
 namespace type3 {
@@ -161,10 +161,10 @@
   // FUNS-LABEL:        define void @_ZN5type31A3fooEv(
   // VARS:        @_ZTVN5type31AE = hidden unnamed_addr constant
   // VARS:        @_ZTSN5type31AE = hidden constant
-  // VARS:        @_ZTIN5type31AE = hidden unnamed_addr constant
+  // VARS:        @_ZTIN5type31AE = hidden constant
   // FUNS-HIDDEN-LABEL: define void @_ZN5type31A3fooEv(
   // VARS-HIDDEN: @_ZTVN5type31AE = hidden unnamed_addr constant
   // VARS-HIDDEN: @_ZTSN5type31AE = hidden constant
-  // VARS-HIDDEN: @_ZTIN5type31AE = hidden unnamed_addr constant
+  // VARS-HIDDEN: @_ZTIN5type31AE = hidden constant
 }
 
diff --git a/test/CodeGenCXX/typeid-should-throw.cpp b/test/CodeGenCXX/typeid-should-throw.cpp
new file mode 100644
index 0000000..1d8fc85
--- /dev/null
+++ b/test/CodeGenCXX/typeid-should-throw.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -Wno-unused-value -emit-llvm -o - -std=c++11 | FileCheck %s
+namespace std {
+struct type_info;
+}
+
+struct A {
+  virtual ~A();
+  operator bool();
+};
+struct B : A {};
+
+void f1(A *x) { typeid(false, *x); }
+// CHECK-LABEL: define void @_Z2f1P1A
+// CHECK:       icmp eq {{.*}}, null
+// CHECK-NEXT:  br i1
+
+void f2(bool b, A *x, A *y) { typeid(b ? *x : *y); }
+// CHECK-LABEL: define void @_Z2f2bP1AS0_
+// CHECK:       icmp eq {{.*}}, null
+// CHECK-NEXT:  br i1
+
+void f3(bool b, A *x, A &y) { typeid(b ? *x : y); }
+// CHECK-LABEL: define void @_Z2f3bP1ARS_
+// CHECK:       icmp eq {{.*}}, null
+// CHECK-NEXT:  br i1
+
+void f4(bool b, A &x, A *y) { typeid(b ? x : *y); }
+// CHECK-LABEL: define void @_Z2f4bR1APS_
+// CHECK:       icmp eq {{.*}}, null
+// CHECK-NEXT:  br i1
+
+void f5(volatile A *x) { typeid(*x); }
+// CHECK-LABEL: define void @_Z2f5PV1A
+// CHECK:       icmp eq {{.*}}, null
+// CHECK-NEXT:  br i1
+
+void f6(A *x) { typeid((B &)*(B *)x); }
+// CHECK-LABEL: define void @_Z2f6P1A
+// CHECK:       icmp eq {{.*}}, null
+// CHECK-NEXT:  br i1
+
+void f7(A *x) { typeid((*x)); }
+// CHECK-LABEL: define void @_Z2f7P1A
+// CHECK:       icmp eq {{.*}}, null
+// CHECK-NEXT:  br i1
+
+void f8(A *x) { typeid(x[0]); }
+// CHECK-LABEL: define void @_Z2f8P1A
+// CHECK:       icmp eq {{.*}}, null
+// CHECK-NEXT:  br i1
+
+void f9(A *x) { typeid(0[x]); }
+// CHECK-LABEL: define void @_Z2f9P1A
+// CHECK:       icmp eq {{.*}}, null
+// CHECK-NEXT:  br i1
+
+void f10(A *x, A *y) { typeid(*y ?: *x); }
+// CHECK-LABEL: define void @_Z3f10P1AS0_
+// CHECK:       icmp eq {{.*}}, null
+// CHECK-NEXT:  br i1
+
+void f11(A *x, A &y) { typeid(*x ?: y); }
+// CHECK-LABEL: define void @_Z3f11P1ARS_
+// CHECK:       icmp eq {{.*}}, null
+// CHECK-NEXT:  br i1
+
+void f12(A &x, A *y) { typeid(x ?: *y); }
+// CHECK-LABEL: define void @_Z3f12R1APS_
+// CHECK:       icmp eq {{.*}}, null
+// CHECK-NEXT:  br i1
+
+void f13(A &x, A &y) { typeid(x ?: y); }
+// CHECK-LABEL: define void @_Z3f13R1AS0_
+// CHECK-NOT:   icmp eq {{.*}}, null
+
+void f14(A *x) { typeid((const A &)(A)*x); }
+// CHECK-LABEL: define void @_Z3f14P1A
+// CHECK-NOT:   icmp eq {{.*}}, null
+
+void f15(A *x) { typeid((A &&)*(A *)nullptr); }
+// CHECK-LABEL: define void @_Z3f15P1A
+// CHECK-NOT:   icmp eq {{.*}}, null
diff --git a/test/CodeGenCXX/unary-type-trait.cpp b/test/CodeGenCXX/unary-type-trait.cpp
deleted file mode 100644
index 3c6f9c0..0000000
--- a/test/CodeGenCXX/unary-type-trait.cpp
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: %clang_cc1 -emit-llvm-only -verify %s
-// expected-no-diagnostics
-
-bool a() { return __is_pod(int); }
diff --git a/test/CodeGenCXX/uncopyable-args.cpp b/test/CodeGenCXX/uncopyable-args.cpp
new file mode 100644
index 0000000..77996f6
--- /dev/null
+++ b/test/CodeGenCXX/uncopyable-args.cpp
@@ -0,0 +1,206 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-msvc -emit-llvm -o - %s | FileCheck %s -check-prefix=WIN64
+
+namespace trivial {
+// Trivial structs should be passed directly.
+struct A {
+  void *p;
+};
+void foo(A);
+void bar() {
+  foo({});
+}
+// CHECK-LABEL: define void @_ZN7trivial3barEv()
+// CHECK: alloca %"struct.trivial::A"
+// CHECK: load i8**
+// CHECK: call void @_ZN7trivial3fooENS_1AE(i8* %{{.*}})
+// CHECK-LABEL: declare void @_ZN7trivial3fooENS_1AE(i8*)
+
+// WIN64-LABEL: declare void @"\01?foo@trivial@@YAXUA@1@@Z"(i64)
+}
+
+namespace default_ctor {
+struct A {
+  A();
+  void *p;
+};
+void foo(A);
+void bar() {
+  // Core issue 1590.  We can pass this type in registers, even though C++
+  // normally doesn't permit copies when using braced initialization.
+  foo({});
+}
+// CHECK-LABEL: define void @_ZN12default_ctor3barEv()
+// CHECK: alloca %"struct.default_ctor::A"
+// CHECK: call void @_Z{{.*}}C1Ev(
+// CHECK: load i8**
+// CHECK: call void @_ZN12default_ctor3fooENS_1AE(i8* %{{.*}})
+// CHECK-LABEL: declare void @_ZN12default_ctor3fooENS_1AE(i8*)
+
+// WIN64-LABEL: declare void @"\01?foo@default_ctor@@YAXUA@1@@Z"(i64)
+}
+
+namespace move_ctor {
+// The presence of a move constructor implicitly deletes the trivial copy ctor
+// and means that we have to pass this struct by address.
+struct A {
+  A();
+  A(A &&o);
+  void *p;
+};
+void foo(A);
+void bar() {
+  foo({});
+}
+// FIXME: The copy ctor is implicitly deleted.
+// CHECK-DISABLED-LABEL: define void @_ZN9move_ctor3barEv()
+// CHECK-DISABLED: call void @_Z{{.*}}C1Ev(
+// CHECK-DISABLED-NOT: call
+// CHECK-DISABLED: call void @_ZN9move_ctor3fooENS_1AE(%"struct.move_ctor::A"* %{{.*}})
+// CHECK-DISABLED-LABEL: declare void @_ZN9move_ctor3fooENS_1AE(%"struct.move_ctor::A"*)
+
+// WIN64-LABEL: declare void @"\01?foo@move_ctor@@YAXUA@1@@Z"(%"struct.move_ctor::A"*)
+}
+
+namespace all_deleted {
+struct A {
+  A();
+  A(const A &o) = delete;
+  A(A &&o) = delete;
+  void *p;
+};
+void foo(A);
+void bar() {
+  foo({});
+}
+// FIXME: The copy ctor is deleted.
+// CHECK-DISABLED-LABEL: define void @_ZN11all_deleted3barEv()
+// CHECK-DISABLED: call void @_Z{{.*}}C1Ev(
+// CHECK-DISABLED-NOT call
+// CHECK-DISABLED: call void @_ZN11all_deleted3fooENS_1AE(%"struct.all_deleted::A"* %{{.*}})
+// CHECK-DISABLED-LABEL: declare void @_ZN11all_deleted3fooENS_1AE(%"struct.all_deleted::A"*)
+
+// WIN64-LABEL: declare void @"\01?foo@all_deleted@@YAXUA@1@@Z"(%"struct.all_deleted::A"*)
+}
+
+namespace implicitly_deleted {
+struct A {
+  A();
+  A &operator=(A &&o);
+  void *p;
+};
+void foo(A);
+void bar() {
+  foo({});
+}
+// FIXME: The copy and move ctors are implicitly deleted.
+// CHECK-DISABLED-LABEL: define void @_ZN18implicitly_deleted3barEv()
+// CHECK-DISABLED: call void @_Z{{.*}}C1Ev(
+// CHECK-DISABLED-NOT call
+// CHECK-DISABLED: call void @_ZN18implicitly_deleted3fooENS_1AE(%"struct.implicitly_deleted::A"* %{{.*}})
+// CHECK-DISABLED-LABEL: declare void @_ZN18implicitly_deleted3fooENS_1AE(%"struct.implicitly_deleted::A"*)
+
+// WIN64-LABEL: declare void @"\01?foo@implicitly_deleted@@YAXUA@1@@Z"(%"struct.implicitly_deleted::A"*)
+}
+
+namespace one_deleted {
+struct A {
+  A();
+  A(A &&o) = delete;
+  void *p;
+};
+void foo(A);
+void bar() {
+  foo({});
+}
+// FIXME: The copy constructor is implicitly deleted.
+// CHECK-DISABLED-LABEL: define void @_ZN11one_deleted3barEv()
+// CHECK-DISABLED: call void @_Z{{.*}}C1Ev(
+// CHECK-DISABLED-NOT call
+// CHECK-DISABLED: call void @_ZN11one_deleted3fooENS_1AE(%"struct.one_deleted::A"* %{{.*}})
+// CHECK-DISABLED-LABEL: declare void @_ZN11one_deleted3fooENS_1AE(%"struct.one_deleted::A"*)
+
+// WIN64-LABEL: declare void @"\01?foo@one_deleted@@YAXUA@1@@Z"(%"struct.one_deleted::A"*)
+}
+
+namespace copy_defaulted {
+struct A {
+  A();
+  A(const A &o) = default;
+  A(A &&o) = delete;
+  void *p;
+};
+void foo(A);
+void bar() {
+  foo({});
+}
+// CHECK-LABEL: define void @_ZN14copy_defaulted3barEv()
+// CHECK: call void @_Z{{.*}}C1Ev(
+// CHECK: load i8**
+// CHECK: call void @_ZN14copy_defaulted3fooENS_1AE(i8* %{{.*}})
+// CHECK-LABEL: declare void @_ZN14copy_defaulted3fooENS_1AE(i8*)
+
+// WIN64-LABEL: declare void @"\01?foo@copy_defaulted@@YAXUA@1@@Z"(i64)
+}
+
+namespace move_defaulted {
+struct A {
+  A();
+  A(const A &o) = delete;
+  A(A &&o) = default;
+  void *p;
+};
+void foo(A);
+void bar() {
+  foo({});
+}
+// CHECK-LABEL: define void @_ZN14move_defaulted3barEv()
+// CHECK: call void @_Z{{.*}}C1Ev(
+// CHECK: load i8**
+// CHECK: call void @_ZN14move_defaulted3fooENS_1AE(i8* %{{.*}})
+// CHECK-LABEL: declare void @_ZN14move_defaulted3fooENS_1AE(i8*)
+
+// WIN64-LABEL: declare void @"\01?foo@move_defaulted@@YAXUA@1@@Z"(%"struct.move_defaulted::A"*)
+}
+
+namespace trivial_defaulted {
+struct A {
+  A();
+  A(const A &o) = default;
+  void *p;
+};
+void foo(A);
+void bar() {
+  foo({});
+}
+// CHECK-LABEL: define void @_ZN17trivial_defaulted3barEv()
+// CHECK: call void @_Z{{.*}}C1Ev(
+// CHECK: load i8**
+// CHECK: call void @_ZN17trivial_defaulted3fooENS_1AE(i8* %{{.*}})
+// CHECK-LABEL: declare void @_ZN17trivial_defaulted3fooENS_1AE(i8*)
+
+// WIN64-LABEL: declare void @"\01?foo@trivial_defaulted@@YAXUA@1@@Z"(i64)
+}
+
+namespace two_copy_ctors {
+struct A {
+  A();
+  A(const A &) = default;
+  A(const A &, int = 0);
+  void *p;
+};
+struct B : A {};
+
+void foo(B);
+void bar() {
+  foo({});
+}
+// FIXME: This class has a non-trivial copy ctor and a trivial copy ctor.  It's
+// not clear whether we should pass by address or in registers.
+// CHECK-DISABLED-LABEL: define void @_ZN14two_copy_ctors3barEv()
+// CHECK-DISABLED: call void @_Z{{.*}}C1Ev(
+// CHECK-DISABLED: call void @_ZN14two_copy_ctors3fooENS_1BE(%"struct.two_copy_ctors::B"* %{{.*}})
+// CHECK-DISABLED-LABEL: declare void @_ZN14two_copy_ctors3fooENS_1BE(%"struct.two_copy_ctors::B"*)
+
+// WIN64-LABEL: declare void @"\01?foo@two_copy_ctors@@YAXUB@1@@Z"(%"struct.two_copy_ctors::B"*)
+}
diff --git a/test/CodeGenCXX/value-init.cpp b/test/CodeGenCXX/value-init.cpp
index fad459b..423d973 100644
--- a/test/CodeGenCXX/value-init.cpp
+++ b/test/CodeGenCXX/value-init.cpp
@@ -262,6 +262,59 @@
 void r170806_a(bool b = bool());
 void r170806_b() { r170806_a(); }
 
+namespace PR20256 {
+  struct data { int i; };
+
+  template<typename T = int>
+  data g() {
+    data d; // not value-init
+    return d;
+  }
+  template data g();
+  // CHECK-LABEL: define {{.*}} @_ZN7PR202561gIiEENS_4dataEv(
+  // CHECK-NOT: store
+  // CHECK-NOT: memset
+  // CHECK: }
+
+  template<typename ...T>
+  data h(T ...t) {
+    data d(t...); // value-init
+    return d;
+  }
+  template data h();
+  // CHECK-LABEL: define {{.*}} @_ZN7PR202561hIJEEENS_4dataEDpT_(
+  // CHECK: call void @llvm.memset
+  // CHECK: }
+
+
+  template<typename T = int>
+  data j() {
+    data d = {}; // value-init
+    return d;
+  }
+  template data j();
+  // CHECK-LABEL: define {{.*}} @_ZN7PR202561jIiEENS_4dataEv(
+  // CHECK: call void @llvm.memset
+  // CHECK: }
+
+  data f() {
+    data d; // not value-init
+    return d;
+  }
+  // CHECK-LABEL: define {{.*}} @_ZN7PR202561fEv(
+  // CHECK-NOT: store
+  // CHECK-NOT: memset
+  // CHECK: }
+
+  data i() {
+    data d = {}; // value-init
+    return d;
+  }
+  // CHECK-LABEL: define {{.*}} @_ZN7PR202561iEv(
+  // CHECK: call void @llvm.memset
+  // CHECK: }
+}
+
 // 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/vararg-non-pod.cpp b/test/CodeGenCXX/vararg-non-pod.cpp
index 9497179..613b28c 100644
--- a/test/CodeGenCXX/vararg-non-pod.cpp
+++ b/test/CodeGenCXX/vararg-non-pod.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -Wno-error=non-pod-varargs -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -Wno-error=non-pod-varargs -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
 
 struct X {
   X();
diff --git a/test/CodeGenCXX/virt-dtor-gen.cpp b/test/CodeGenCXX/virt-dtor-gen.cpp
index 78a0b81..ba83689 100644
--- a/test/CodeGenCXX/virt-dtor-gen.cpp
+++ b/test/CodeGenCXX/virt-dtor-gen.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -o - -emit-llvm %s | FileCheck %s
+// RUN: %clang_cc1 -o - -triple %itanium_abi_triple -emit-llvm %s | FileCheck %s
 // PR5483
 
 // Make sure we generate all three forms of the destructor when it is virtual.
@@ -7,4 +7,4 @@
 };
 Foo::~Foo() {}
 
-// CHECK-LABEL: define void @_ZN3FooD0Ev(%class.Foo* %this) unnamed_addr
+// CHECK-LABEL: define {{.*}}void @_ZN3FooD0Ev(%class.Foo* %this) unnamed_addr
diff --git a/test/CodeGenCXX/virt-dtor-key.cpp b/test/CodeGenCXX/virt-dtor-key.cpp
index a8fa371..40c5a53 100644
--- a/test/CodeGenCXX/virt-dtor-key.cpp
+++ b/test/CodeGenCXX/virt-dtor-key.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
-// CHECK: @_ZTI3foo = unnamed_addr constant
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
+// CHECK: @_ZTI3foo = constant
 class foo {
    foo();
    virtual ~foo();
diff --git a/test/CodeGenCXX/virt-template-vtable.cpp b/test/CodeGenCXX/virt-template-vtable.cpp
index a6067d6..a71db48 100644
--- a/test/CodeGenCXX/virt-template-vtable.cpp
+++ b/test/CodeGenCXX/virt-template-vtable.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s
 
 template<class T> class A {
 public:
diff --git a/test/CodeGenCXX/virtual-base-cast.cpp b/test/CodeGenCXX/virtual-base-cast.cpp
index 40e68f6..6a4894b 100644
--- a/test/CodeGenCXX/virtual-base-cast.cpp
+++ b/test/CodeGenCXX/virtual-base-cast.cpp
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -emit-llvm %s -o - -triple i686-pc-linux-gnu | FileCheck %s
-// RUN: %clang_cc1 -cxx-abi microsoft -emit-llvm %s -o - -triple i686-pc-win32 | FileCheck -check-prefix MSVC %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple i686-pc-win32 | FileCheck -check-prefix MSVC %s
 
 struct A { int a; virtual int aa(); };
 struct B { int b; virtual int bb(); };
diff --git a/test/CodeGenCXX/virtual-base-ctor.cpp b/test/CodeGenCXX/virtual-base-ctor.cpp
index 2d81ebd..8c28965 100644
--- a/test/CodeGenCXX/virtual-base-ctor.cpp
+++ b/test/CodeGenCXX/virtual-base-ctor.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - -O2 | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o - -O2 | FileCheck %s
 
 struct B;
 extern B x;
diff --git a/test/CodeGenCXX/virtual-base-destructor-call.cpp b/test/CodeGenCXX/virtual-base-destructor-call.cpp
index 5014eaf..3d79071 100644
--- a/test/CodeGenCXX/virtual-base-destructor-call.cpp
+++ b/test/CodeGenCXX/virtual-base-destructor-call.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s
 
 struct basic_ios{~basic_ios(); };
 
diff --git a/test/CodeGenCXX/virtual-bases.cpp b/test/CodeGenCXX/virtual-bases.cpp
index 2878e95..e9c568c 100644
--- a/test/CodeGenCXX/virtual-bases.cpp
+++ b/test/CodeGenCXX/virtual-bases.cpp
@@ -12,16 +12,16 @@
   B();
 };
 
-// CHECK-LABEL: define void @_ZN1BC1Ev(%struct.B* %this) unnamed_addr
 // CHECK-LABEL: define void @_ZN1BC2Ev(%struct.B* %this, i8** %vtt) unnamed_addr
+// CHECK-LABEL: define void @_ZN1BC1Ev(%struct.B* %this) unnamed_addr
 B::B() { }
 
 struct C : virtual A {
   C(bool);
 };
 
-// CHECK-LABEL: define void @_ZN1CC1Eb(%struct.C* %this, i1 zeroext) unnamed_addr
 // CHECK-LABEL: define void @_ZN1CC2Eb(%struct.C* %this, i8** %vtt, i1 zeroext) unnamed_addr
+// CHECK-LABEL: define void @_ZN1CC1Eb(%struct.C* %this, i1 zeroext) unnamed_addr
 C::C(bool) { }
 
 // PR6251
diff --git a/test/CodeGenCXX/virtual-destructor-calls.cpp b/test/CodeGenCXX/virtual-destructor-calls.cpp
index ae3704f..3e7fa82 100644
--- a/test/CodeGenCXX/virtual-destructor-calls.cpp
+++ b/test/CodeGenCXX/virtual-destructor-calls.cpp
@@ -20,16 +20,16 @@
 // CHECK: @_ZN1CD1Ev = alias {{.*}} @_ZN1CD2Ev
 // CHECK: @_ZN1CD2Ev = alias bitcast {{.*}} @_ZN1BD2Ev
 
-// Deleting dtor: defers to the complete dtor.
-// CHECK-LABEL: define void @_ZN1BD0Ev(%struct.B* %this) unnamed_addr
-// CHECK: call void @_ZN1BD1Ev
-// CHECK: call void @_ZdlPv
-
 // Base dtor: actually calls A's base dtor.
 // CHECK-LABEL: define void @_ZN1BD2Ev(%struct.B* %this) unnamed_addr
 // CHECK: call void @_ZN6MemberD1Ev
 // CHECK: call void @_ZN1AD2Ev
 
+// Deleting dtor: defers to the complete dtor.
+// CHECK-LABEL: define void @_ZN1BD0Ev(%struct.B* %this) unnamed_addr
+// CHECK: call void @_ZN1BD1Ev
+// CHECK: call void @_ZdlPv
+
 B::~B() { }
 
 struct C : B {
diff --git a/test/CodeGenCXX/virtual-destructor-synthesis.cpp b/test/CodeGenCXX/virtual-destructor-synthesis.cpp
index 90f66a8..80d1b1e 100644
--- a/test/CodeGenCXX/virtual-destructor-synthesis.cpp
+++ b/test/CodeGenCXX/virtual-destructor-synthesis.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s
 
 struct box {
   virtual ~box();
diff --git a/test/CodeGenCXX/virtual-function-calls.cpp b/test/CodeGenCXX/virtual-function-calls.cpp
index e1b380f..0a6fc6b 100644
--- a/test/CodeGenCXX/virtual-function-calls.cpp
+++ b/test/CodeGenCXX/virtual-function-calls.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -std=c++11 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -std=c++11 -emit-llvm -o - | FileCheck %s
 
 // PR5021
 namespace PR5021 {
@@ -8,7 +8,7 @@
 };
 
 void f(A *a) {
-  // CHECK: call void %
+  // CHECK: call {{.*}}void %
   a->f('c');
 }
 
@@ -45,7 +45,7 @@
   // CHECK: @_ZN15VirtualNoreturn1f
   void f(A *p) {
     p->f();
-    // CHECK: call void %{{[^#]*$}}
+    // CHECK: call {{.*}}void %{{[^#]*$}}
     // CHECK-NOT: unreachable
   }
 }
diff --git a/test/CodeGenCXX/virtual-implicit-copy-assignment.cpp b/test/CodeGenCXX/virtual-implicit-copy-assignment.cpp
index 70bc6fc..0310465 100644
--- a/test/CodeGenCXX/virtual-implicit-copy-assignment.cpp
+++ b/test/CodeGenCXX/virtual-implicit-copy-assignment.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
 
 struct D;
 struct B {
diff --git a/test/CodeGenCXX/virtual-implicit-move-assignment.cpp b/test/CodeGenCXX/virtual-implicit-move-assignment.cpp
index d8ac1ed..7c28fb1 100644
--- a/test/CodeGenCXX/virtual-implicit-move-assignment.cpp
+++ b/test/CodeGenCXX/virtual-implicit-move-assignment.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -std=c++11 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -std=c++11 -o - %s | FileCheck %s
 
 struct D;
 struct B {
diff --git a/test/CodeGenCXX/virtual-inherited-destructor.cpp b/test/CodeGenCXX/virtual-inherited-destructor.cpp
index 509d40a..3ca7b6d 100644
--- a/test/CodeGenCXX/virtual-inherited-destructor.cpp
+++ b/test/CodeGenCXX/virtual-inherited-destructor.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -emit-llvm-only
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -emit-llvm-only
 
 struct A { virtual ~A(); };
 struct B : A {
diff --git a/test/CodeGenCXX/virtual-pseudo-destructor-call.cpp b/test/CodeGenCXX/virtual-pseudo-destructor-call.cpp
index 0d3574e..b14a34d 100644
--- a/test/CodeGenCXX/virtual-pseudo-destructor-call.cpp
+++ b/test/CodeGenCXX/virtual-pseudo-destructor-call.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s
 
 struct A {
   virtual ~A();
diff --git a/test/CodeGenCXX/visibility-hidden-extern-templates.cpp b/test/CodeGenCXX/visibility-hidden-extern-templates.cpp
index 549e674..95e8e08 100644
--- a/test/CodeGenCXX/visibility-hidden-extern-templates.cpp
+++ b/test/CodeGenCXX/visibility-hidden-extern-templates.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -O1 -emit-llvm -o - -fvisibility hidden %s | FileCheck %s
+// RUN: %clang_cc1 -O1 -triple %itanium_abi_triple -emit-llvm -o - -fvisibility hidden %s | FileCheck %s
 
 template<typename T>
 struct X {
@@ -14,13 +14,13 @@
 
 // <rdar://problem/8109763>
 void test_X(X<int> xi, X<char> xc) {
-  // CHECK-LABEL: define weak_odr hidden void @_ZN1XIiE1fEv
+  // CHECK-LABEL: define weak_odr hidden {{.*}}void @_ZN1XIiE1fEv
   xi.f();
-  // CHECK-LABEL: define weak_odr hidden void @_ZN1XIiE1gEv
+  // CHECK-LABEL: define weak_odr hidden {{.*}}void @_ZN1XIiE1gEv
   xi.g();
-  // CHECK: declare void @_ZN1XIcE1fEv
+  // CHECK: declare {{.*}}void @_ZN1XIcE1fEv
   xc.f();
-  // CHECK-LABEL: define available_externally void @_ZN1XIcE1gEv
+  // CHECK-LABEL: define available_externally {{.*}}void @_ZN1XIcE1gEv
   xc.g();
 }
 
diff --git a/test/CodeGenCXX/visibility-ms-compat.cpp b/test/CodeGenCXX/visibility-ms-compat.cpp
index 25446cd..963b2a4 100644
--- a/test/CodeGenCXX/visibility-ms-compat.cpp
+++ b/test/CodeGenCXX/visibility-ms-compat.cpp
@@ -27,7 +27,7 @@
 
   const std::type_info &ti = typeid(A);
   // CHECK-GLOBAL: @_ZTSN5test01AE = linkonce_odr constant
-  // CHECK-GLOBAL: @_ZTIN5test01AE = linkonce_odr unnamed_addr constant
+  // CHECK-GLOBAL: @_ZTIN5test01AE = linkonce_odr constant
   // CHECK-GLOBAL: @_ZN5test02tiE = hidden constant
 }
 
@@ -43,7 +43,7 @@
 
   const std::type_info &ti = typeid(A);
   // CHECK-GLOBAL: @_ZTSN5test11AE = linkonce_odr hidden constant
-  // CHECK-GLOBAL: @_ZTIN5test11AE = linkonce_odr hidden unnamed_addr constant
+  // CHECK-GLOBAL: @_ZTIN5test11AE = linkonce_odr hidden constant
   // CHECK-GLOBAL: @_ZN5test12tiE = hidden constant
 }
 
@@ -59,7 +59,7 @@
 
   const std::type_info &ti = typeid(A);
   // CHECK-GLOBAL: @_ZTSN5test21AE = linkonce_odr constant
-  // CHECK-GLOBAL: @_ZTIN5test21AE = linkonce_odr unnamed_addr constant
+  // CHECK-GLOBAL: @_ZTIN5test21AE = linkonce_odr constant
   // CHECK-GLOBAL: @_ZN5test22tiE = hidden constant
 }
 
@@ -76,7 +76,7 @@
 
   const std::type_info &ti = typeid(B<A>);
   // CHECK-GLOBAL: @_ZTSN5test31BINS_1AEEE = linkonce_odr constant
-  // CHECK-GLOBAL: @_ZTIN5test31BINS_1AEEE = linkonce_odr unnamed_addr constant
+  // CHECK-GLOBAL: @_ZTIN5test31BINS_1AEEE = linkonce_odr constant
 }
 
 namespace test4 {
@@ -92,7 +92,7 @@
 
   const std::type_info &ti = typeid(B<A>);
   // CHECK-GLOBAL: @_ZTSN5test41BINS_1AEEE = linkonce_odr constant
-  // CHECK-GLOBAL: @_ZTIN5test41BINS_1AEEE = linkonce_odr unnamed_addr constant
+  // CHECK-GLOBAL: @_ZTIN5test41BINS_1AEEE = linkonce_odr constant
 }
 
 namespace test5 {
@@ -108,5 +108,5 @@
 
   const std::type_info &ti = typeid(B<A>);
   // CHECK-GLOBAL: @_ZTSN5test51BINS_1AEEE = linkonce_odr hidden constant
-  // CHECK-GLOBAL: @_ZTIN5test51BINS_1AEEE = linkonce_odr hidden unnamed_addr constant
+  // CHECK-GLOBAL: @_ZTIN5test51BINS_1AEEE = linkonce_odr hidden constant
 }
diff --git a/test/CodeGenCXX/visibility.cpp b/test/CodeGenCXX/visibility.cpp
index 6049bf8..1c4d5bb 100644
--- a/test/CodeGenCXX/visibility.cpp
+++ b/test/CodeGenCXX/visibility.cpp
@@ -1295,3 +1295,17 @@
   }
   // Check lines at top of file.
 }
+
+namespace test69 {
+  // PR18174
+  namespace foo {
+    void f();
+  }
+  namespace foo {
+    void f() {};
+  }
+  namespace foo __attribute__((visibility("hidden"))) {
+  }
+  // CHECK-LABEL: define void @_ZN6test693foo1fEv
+  // CHECK-HIDDEN-LABEL: define hidden void @_ZN6test693foo1fEv
+}
diff --git a/test/CodeGenCXX/vla.cpp b/test/CodeGenCXX/vla.cpp
index b22f21c..a6616d3 100644
--- a/test/CodeGenCXX/vla.cpp
+++ b/test/CodeGenCXX/vla.cpp
@@ -9,7 +9,7 @@
 int f() {
   // Make sure that the reference here is enough to trigger the instantiation of
   // the static data member.
-  // CHECK: @_ZN1SIiE1nE = weak_odr global i32 5
+  // CHECK: @_ZN1SIiE1nE = linkonce_odr global i32 5
   int a[S<int>::n];
   return sizeof a;
 }
diff --git a/test/CodeGenCXX/volatile-1.cpp b/test/CodeGenCXX/volatile-1.cpp
index 71ff1ed..2038936 100644
--- a/test/CodeGenCXX/volatile-1.cpp
+++ b/test/CodeGenCXX/volatile-1.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -Wno-unused-value -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -Wno-unused-value -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
 
 // CHECK: @i = global [[INT:i[0-9]+]] 0
 volatile int i, j, k;
@@ -248,11 +248,11 @@
   // gcc.
 
   // Not a use.  gcc forgets to do the assignment.
-  // CHECK-NEXT: call
+  // CHECK-NEXT: call {{.*}}void
   ((a=a),a);
 
   // Not a use.  gcc gets this wrong, it doesn't emit the copy!  
-  // CHECK-NEXT: call
+  // CHECK-NEXT: call {{.*}}void
   (void)(a=a);
 
   // Not a use.  gcc got this wrong in 4.2 and omitted the side effects
diff --git a/test/CodeGenCXX/volatile.cpp b/test/CodeGenCXX/volatile.cpp
index 38c8829..f6ae0c5 100644
--- a/test/CodeGenCXX/volatile.cpp
+++ b/test/CodeGenCXX/volatile.cpp
@@ -15,7 +15,7 @@
   void test(A t) {
     // CHECK:      [[ARR:%.*]] = load [[A:%.*]]** @_ZN5test05arrayE, align 8
     // CHECK-NEXT: [[IDX:%.*]] = getelementptr inbounds [[A]]* [[ARR]], i64 0
-    // CHECK-NEXT: [[TMP:%.*]] = call [[A]]* @_ZNV5test01AaSERVKS0_([[A]]* [[IDX]], [[A]]* [[T:%.*]])
+    // CHECK-NEXT: [[TMP:%.*]] = call dereferenceable({{[0-9]+}}) [[A]]* @_ZNV5test01AaSERVKS0_([[A]]* [[IDX]], [[A]]* dereferenceable({{[0-9]+}}) [[T:%.*]])
     // CHECK-NEXT: ret void
     array[0] = t;
   }
diff --git a/test/CodeGenCXX/vtable-available-externally.cpp b/test/CodeGenCXX/vtable-available-externally.cpp
index 282bd2a..e07d484 100644
--- a/test/CodeGenCXX/vtable-available-externally.cpp
+++ b/test/CodeGenCXX/vtable-available-externally.cpp
@@ -35,7 +35,7 @@
 // updated correctly.
 
 // CHECK-TEST2: @_ZTSN5Test21AE = constant
-// CHECK-TEST2: @_ZTIN5Test21AE = unnamed_addr constant
+// CHECK-TEST2: @_ZTIN5Test21AE = constant
 // CHECK-TEST2: @_ZTVN5Test21AE = unnamed_addr constant
 namespace Test2 {
   struct A {
diff --git a/test/CodeGenCXX/vtable-cast-crash.cpp b/test/CodeGenCXX/vtable-cast-crash.cpp
index cc419fd..58f9e0b 100644
--- a/test/CodeGenCXX/vtable-cast-crash.cpp
+++ b/test/CodeGenCXX/vtable-cast-crash.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm-only %s
+// RUN: %clang_cc1 -emit-llvm-only -triple %itanium_abi_triple %s
 struct A
 {
 A();    
diff --git a/test/CodeGenCXX/vtable-key-function-arm.cpp b/test/CodeGenCXX/vtable-key-function-arm.cpp
index 08efe8a..6f1265b 100644
--- a/test/CodeGenCXX/vtable-key-function-arm.cpp
+++ b/test/CodeGenCXX/vtable-key-function-arm.cpp
@@ -4,7 +4,7 @@
 // The 'a' variants ask for the v-table first.
 // The 'b' variants ask for the v-table second.
 // The 'c' variants ask for the v-table third.
-// We do a separate CHECK-LATE pass because the RTTI defintion gets
+// We do a separate CHECK-LATE pass because the RTTI definition gets
 // changed after the fact, which causes reordering of the globals.
 
 // These are not separated into namespaces because the way that Sema
@@ -91,7 +91,7 @@
 Test2a::Test2a() { use(typeid(Test2a)); }
 // CHECK:      @_ZTV6Test2a = unnamed_addr constant
 // CHECK-LATE: @_ZTS6Test2a = constant
-// CHECK-LATE: @_ZTI6Test2a = unnamed_addr constant
+// CHECK-LATE: @_ZTI6Test2a = constant
 
 // 'bar' becomes the key function when 'foo' is defined inline.
 void Test2a::bar() {}
@@ -112,7 +112,7 @@
 Test2b::Test2b() { use(typeid(Test2b)); }
 // CHECK:      @_ZTV6Test2b = unnamed_addr constant
 // CHECK-LATE: @_ZTS6Test2b = constant
-// CHECK-LATE: @_ZTI6Test2b = unnamed_addr constant
+// CHECK-LATE: @_ZTI6Test2b = constant
 
 inline void Test2b::foo() {}
 
@@ -132,7 +132,7 @@
 Test2c::Test2c() { use(typeid(Test2c)); }
 // CHECK: @_ZTV6Test2c = unnamed_addr constant
 // CHECK: @_ZTS6Test2c = constant
-// CHECK: @_ZTI6Test2c = unnamed_addr constant
+// CHECK: @_ZTI6Test2c = constant
 
 /*** Test3a ******************************************************************/
 
@@ -146,7 +146,7 @@
 Test3a::Test3a() { use(typeid(Test3a)); }
 // CHECK:      @_ZTV6Test3a = linkonce_odr unnamed_addr constant
 // CHECK-LATE: @_ZTS6Test3a = linkonce_odr constant
-// CHECK-LATE: @_ZTI6Test3a = linkonce_odr unnamed_addr constant
+// CHECK-LATE: @_ZTI6Test3a = linkonce_odr constant
 
 // There ceases to be a key function after these declarations.
 inline void Test3a::bar() {}
@@ -167,7 +167,7 @@
 Test3b::Test3b() { use(typeid(Test3b)); }
 // CHECK:      @_ZTV6Test3b = linkonce_odr unnamed_addr constant
 // CHECK-LATE: @_ZTS6Test3b = linkonce_odr constant
-// CHECK-LATE: @_ZTI6Test3b = linkonce_odr unnamed_addr constant
+// CHECK-LATE: @_ZTI6Test3b = linkonce_odr constant
 
 inline void Test3b::foo() {}
 
@@ -187,7 +187,7 @@
 Test3c::Test3c() { use(typeid(Test3c)); }
 // CHECK: @_ZTV6Test3c = linkonce_odr unnamed_addr constant
 // CHECK: @_ZTS6Test3c = linkonce_odr constant
-// CHECK: @_ZTI6Test3c = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTI6Test3c = linkonce_odr constant
 
 /*** Test4a ******************************************************************/
 
@@ -201,7 +201,7 @@
 template <> Test4a<int>::Test4a() { use(typeid(Test4a)); }
 // CHECK: @_ZTV6Test4aIiE = linkonce_odr unnamed_addr constant
 // CHECK: @_ZTS6Test4aIiE = linkonce_odr constant
-// CHECK: @_ZTI6Test4aIiE = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTI6Test4aIiE = linkonce_odr constant
 
 // There ceases to be a key function after these declarations.
 template <> inline void Test4a<int>::bar() {}
@@ -222,7 +222,7 @@
 template <> Test4b<int>::Test4b() { use(typeid(Test4b)); }
 // CHECK: @_ZTV6Test4bIiE = linkonce_odr unnamed_addr constant
 // CHECK: @_ZTS6Test4bIiE = linkonce_odr constant
-// CHECK: @_ZTI6Test4bIiE = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTI6Test4bIiE = linkonce_odr constant
 
 template <> inline void Test4b<int>::foo() {}
 
@@ -242,7 +242,7 @@
 template <> Test4c<int>::Test4c() { use(typeid(Test4c)); }
 // CHECK: @_ZTV6Test4cIiE = linkonce_odr unnamed_addr constant
 // CHECK: @_ZTS6Test4cIiE = linkonce_odr constant
-// CHECK: @_ZTI6Test4cIiE = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTI6Test4cIiE = linkonce_odr constant
 
 /*** Test5a ******************************************************************/
 
@@ -259,7 +259,7 @@
 template <> Test5a<int>::Test5a() { use(typeid(Test5a)); }
 // CHECK: @_ZTV6Test5aIiE = linkonce_odr unnamed_addr constant
 // CHECK: @_ZTS6Test5aIiE = linkonce_odr constant
-// CHECK: @_ZTI6Test5aIiE = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTI6Test5aIiE = linkonce_odr constant
 
 // There ceases to be a key function after these declarations.
 template <> inline void Test5a<int>::bar() {}
@@ -281,7 +281,7 @@
 template <> Test5b<int>::Test5b() { use(typeid(Test5b)); }
 // CHECK: @_ZTV6Test5bIiE = linkonce_odr unnamed_addr constant
 // CHECK: @_ZTS6Test5bIiE = linkonce_odr constant
-// CHECK: @_ZTI6Test5bIiE = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTI6Test5bIiE = linkonce_odr constant
 
 template <> inline void Test5a<int>::foo();
 template <> inline void Test5b<int>::foo() {}
@@ -304,4 +304,4 @@
 template <> Test5c<int>::Test5c() { use(typeid(Test5c)); }
 // CHECK: @_ZTV6Test5cIiE = linkonce_odr unnamed_addr constant
 // CHECK: @_ZTS6Test5cIiE = linkonce_odr constant
-// CHECK: @_ZTI6Test5cIiE = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTI6Test5cIiE = linkonce_odr constant
diff --git a/test/CodeGenCXX/vtable-key-function-ios.cpp b/test/CodeGenCXX/vtable-key-function-ios.cpp
index bcd3e88..bf2e1f9 100644
--- a/test/CodeGenCXX/vtable-key-function-ios.cpp
+++ b/test/CodeGenCXX/vtable-key-function-ios.cpp
@@ -4,7 +4,7 @@
 // The 'a' variants ask for the v-table first.
 // The 'b' variants ask for the v-table second.
 // The 'c' variants ask for the v-table third.
-// We do a separate CHECK-LATE pass because the RTTI defintion gets
+// We do a separate CHECK-LATE pass because the RTTI definition gets
 // changed after the fact, which causes reordering of the globals.
 
 // These are not separated into namespaces because the way that Sema
@@ -59,7 +59,7 @@
 Test1a::Test1a() { use(typeid(Test1a)); }
 // CHECK:      @_ZTV6Test1a = linkonce_odr unnamed_addr constant 
 // CHECK-LATE: @_ZTS6Test1a = linkonce_odr constant
-// CHECK-LATE: @_ZTI6Test1a = linkonce_odr unnamed_addr constant
+// CHECK-LATE: @_ZTI6Test1a = linkonce_odr constant
 
 // This defines the key function.
 inline void Test1a::foo() {}
@@ -79,7 +79,7 @@
 Test1b::Test1b() { use(typeid(Test1b)); }
 // CHECK: @_ZTV6Test1b = linkonce_odr unnamed_addr constant 
 // CHECK: @_ZTS6Test1b = linkonce_odr constant
-// CHECK: @_ZTI6Test1b = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTI6Test1b = linkonce_odr constant
 
 /*** Test2a ******************************************************************/
 
@@ -93,7 +93,7 @@
 Test2a::Test2a() { use(typeid(Test2a)); }
 // CHECK:      @_ZTV6Test2a = linkonce_odr unnamed_addr constant
 // CHECK-LATE: @_ZTS6Test2a = linkonce_odr constant
-// CHECK-LATE: @_ZTI6Test2a = linkonce_odr unnamed_addr constant
+// CHECK-LATE: @_ZTI6Test2a = linkonce_odr constant
 
 void Test2a::bar() {}
 inline void Test2a::foo() {}
@@ -112,7 +112,7 @@
 Test2b::Test2b() { use(typeid(Test2b)); }
 // CHECK:      @_ZTV6Test2b = linkonce_odr unnamed_addr constant
 // CHECK-LATE: @_ZTS6Test2b = linkonce_odr constant
-// CHECK-LATE: @_ZTI6Test2b = linkonce_odr unnamed_addr constant
+// CHECK-LATE: @_ZTI6Test2b = linkonce_odr constant
 
 inline void Test2b::foo() {}
 
@@ -131,7 +131,7 @@
 Test2c::Test2c() { use(typeid(Test2c)); }
 // CHECK: @_ZTV6Test2c = linkonce_odr unnamed_addr constant
 // CHECK: @_ZTS6Test2c = linkonce_odr constant
-// CHECK: @_ZTI6Test2c = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTI6Test2c = linkonce_odr constant
 
 /*** Test3a ******************************************************************/
 
@@ -145,7 +145,7 @@
 Test3a::Test3a() { use(typeid(Test3a)); }
 // CHECK:      @_ZTV6Test3a = linkonce_odr unnamed_addr constant
 // CHECK-LATE: @_ZTS6Test3a = linkonce_odr constant
-// CHECK-LATE: @_ZTI6Test3a = linkonce_odr unnamed_addr constant
+// CHECK-LATE: @_ZTI6Test3a = linkonce_odr constant
 
 // This defines the key function.
 inline void Test3a::bar() {}
@@ -165,7 +165,7 @@
 Test3b::Test3b() { use(typeid(Test3b)); }
 // CHECK:      @_ZTV6Test3b = linkonce_odr unnamed_addr constant
 // CHECK-LATE: @_ZTS6Test3b = linkonce_odr constant
-// CHECK-LATE: @_ZTI6Test3b = linkonce_odr unnamed_addr constant
+// CHECK-LATE: @_ZTI6Test3b = linkonce_odr constant
 
 // This defines the key function.
 inline void Test3b::foo() {}
@@ -186,4 +186,4 @@
 Test3c::Test3c() { use(typeid(Test3c)); }
 // CHECK: @_ZTV6Test3c = linkonce_odr unnamed_addr constant
 // CHECK: @_ZTS6Test3c = linkonce_odr constant
-// CHECK: @_ZTI6Test3c = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTI6Test3c = linkonce_odr constant
diff --git a/test/CodeGenCXX/vtable-layout-abi-examples.cpp b/test/CodeGenCXX/vtable-layout-abi-examples.cpp
index 8f084a9..b8ac6f5 100644
--- a/test/CodeGenCXX/vtable-layout-abi-examples.cpp
+++ b/test/CodeGenCXX/vtable-layout-abi-examples.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm-only -fdump-vtable-layouts > %t 2>&1
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm-only -fdump-vtable-layouts > %t 2>/dev/null
 // RUN: FileCheck --check-prefix=CHECK-1 %s < %t
 // RUN: FileCheck --check-prefix=CHECK-2 %s < %t
 // RUN: FileCheck --check-prefix=CHECK-3 %s < %t
diff --git a/test/CodeGenCXX/vtable-linkage.cpp b/test/CodeGenCXX/vtable-linkage.cpp
index c17e333..9c08b30 100644
--- a/test/CodeGenCXX/vtable-linkage.cpp
+++ b/test/CodeGenCXX/vtable-linkage.cpp
@@ -1,8 +1,6 @@
 // RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o %t
-// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fhidden-weak-vtables -emit-llvm -o %t.hidden
 // RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -disable-llvm-optzns -O3 -emit-llvm -o %t.opt
 // RUN: FileCheck --check-prefix=CHECK %s < %t
-// RUN: FileCheck --check-prefix=CHECK-HIDDEN %s < %t.hidden
 // RUN: FileCheck --check-prefix=CHECK-OPT %s < %t.opt
 
 namespace {
@@ -93,57 +91,47 @@
 // and hidden visibility (rdar://problem/7523229).
 // CHECK-DAG: @_ZTV1C = linkonce_odr unnamed_addr constant
 // CHECK-DAG: @_ZTS1C = linkonce_odr constant
-// CHECK-DAG: @_ZTI1C = linkonce_odr unnamed_addr constant
+// CHECK-DAG: @_ZTI1C = linkonce_odr constant
 // CHECK-DAG: @_ZTT1C = linkonce_odr unnamed_addr constant
-// CHECK-HIDDEN-DAG: @_ZTV1C = linkonce_odr hidden unnamed_addr constant
-// CHECK-HIDDEN-DAG: @_ZTS1C = linkonce_odr constant
-// CHECK-HIDDEN-DAG: @_ZTI1C = linkonce_odr hidden unnamed_addr constant
-// CHECK-HIDDEN-DAG: @_ZTT1C = linkonce_odr hidden unnamed_addr constant
 
 // D has a key function that is defined in this translation unit so its vtable is
 // defined in the translation unit.
 // CHECK-DAG: @_ZTV1D = unnamed_addr constant
 // CHECK-DAG: @_ZTS1D = constant
-// CHECK-DAG: @_ZTI1D = unnamed_addr constant
+// CHECK-DAG: @_ZTI1D = constant
 
 // E<char> is an explicit specialization with a key function defined
 // in this translation unit, so its vtable should have external
 // linkage.
 // CHECK-DAG: @_ZTV1EIcE = unnamed_addr constant
 // CHECK-DAG: @_ZTS1EIcE = constant
-// CHECK-DAG: @_ZTI1EIcE = unnamed_addr constant
+// CHECK-DAG: @_ZTI1EIcE = constant
 
 // E<short> is an explicit template instantiation with a key function
 // defined in this translation unit, so its vtable should have
 // weak_odr linkage.
 // CHECK-DAG: @_ZTV1EIsE = weak_odr unnamed_addr constant
 // CHECK-DAG: @_ZTS1EIsE = weak_odr constant
-// CHECK-DAG: @_ZTI1EIsE = weak_odr unnamed_addr constant
-// CHECK-HIDDEN-DAG: @_ZTV1EIsE = weak_odr unnamed_addr constant
-// CHECK-HIDDEN-DAG: @_ZTS1EIsE = weak_odr constant
-// CHECK-HIDDEN-DAG: @_ZTI1EIsE = weak_odr unnamed_addr constant
+// CHECK-DAG: @_ZTI1EIsE = weak_odr constant
 
 // F<short> is an explicit template instantiation without a key
 // function, so its vtable should have weak_odr linkage
 // CHECK-DAG: @_ZTV1FIsE = weak_odr unnamed_addr constant
 // CHECK-DAG: @_ZTS1FIsE = weak_odr constant
-// CHECK-DAG: @_ZTI1FIsE = weak_odr unnamed_addr constant
-// CHECK-HIDDEN-DAG: @_ZTV1FIsE = weak_odr unnamed_addr constant
-// CHECK-HIDDEN-DAG: @_ZTS1FIsE = weak_odr constant
-// CHECK-HIDDEN-DAG: @_ZTI1FIsE = weak_odr unnamed_addr constant
+// CHECK-DAG: @_ZTI1FIsE = weak_odr constant
 
 // E<long> is an implicit template instantiation with a key function
 // defined in this translation unit, so its vtable should have
 // linkonce_odr linkage.
 // CHECK-DAG: @_ZTV1EIlE = linkonce_odr unnamed_addr constant
 // CHECK-DAG: @_ZTS1EIlE = linkonce_odr constant
-// CHECK-DAG: @_ZTI1EIlE = linkonce_odr unnamed_addr constant
+// CHECK-DAG: @_ZTI1EIlE = linkonce_odr constant
 
 // F<long> is an implicit template instantiation with no key function,
 // so its vtable should have linkonce_odr linkage.
 // CHECK-DAG: @_ZTV1FIlE = linkonce_odr unnamed_addr constant
 // CHECK-DAG: @_ZTS1FIlE = linkonce_odr constant
-// CHECK-DAG: @_ZTI1FIlE = linkonce_odr unnamed_addr constant
+// CHECK-DAG: @_ZTI1FIlE = linkonce_odr constant
 
 // F<int> is an explicit template instantiation declaration without a
 // key function, so its vtable should have external linkage.
@@ -160,19 +148,19 @@
 // internal linkage.
 // CHECK-DAG: @"_ZTV3$_0" = internal unnamed_addr constant
 // CHECK-DAG: @"_ZTS3$_0" = internal constant
-// CHECK-DAG: @"_ZTI3$_0" = internal unnamed_addr constant
+// CHECK-DAG: @"_ZTI3$_0" = internal constant
 
 // The A vtable should have internal linkage since it is inside an anonymous 
 // namespace.
 // CHECK-DAG: @_ZTVN12_GLOBAL__N_11AE = internal unnamed_addr constant
 // CHECK-DAG: @_ZTSN12_GLOBAL__N_11AE = internal constant
-// CHECK-DAG: @_ZTIN12_GLOBAL__N_11AE = internal unnamed_addr constant
+// CHECK-DAG: @_ZTIN12_GLOBAL__N_11AE = internal constant
 
 // F<char> is an explicit specialization without a key function, so
 // its vtable should have linkonce_odr linkage.
 // CHECK-DAG: @_ZTV1FIcE = linkonce_odr unnamed_addr constant
 // CHECK-DAG: @_ZTS1FIcE = linkonce_odr constant
-// CHECK-DAG: @_ZTI1FIcE = linkonce_odr unnamed_addr constant
+// CHECK-DAG: @_ZTI1FIcE = linkonce_odr constant
 
 // CHECK-DAG: @_ZTV1GIiE = linkonce_odr unnamed_addr constant
 template <typename T>
diff --git a/test/CodeGenCXX/weak-extern-typeinfo.cpp b/test/CodeGenCXX/weak-extern-typeinfo.cpp
index 3c3406e..38f6a3e 100644
--- a/test/CodeGenCXX/weak-extern-typeinfo.cpp
+++ b/test/CodeGenCXX/weak-extern-typeinfo.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o - | FileCheck %s
 // rdar://10246395
 
 #define WEAK __attribute__ ((weak)) 
@@ -32,16 +32,16 @@
 void V2::foo() { }
 
 // CHECK: @_ZTS1A = weak_odr constant
-// CHECK: @_ZTI1A = weak_odr unnamed_addr constant
+// CHECK: @_ZTI1A = weak_odr constant
 // CHECK: @_ZTS1B = weak_odr constant
-// CHECK: @_ZTI1B = weak_odr unnamed_addr constant
+// CHECK: @_ZTI1B = weak_odr constant
 // CHECK: @_ZTS1C = weak_odr constant
 // CHECK: @_ZTS2T1 = linkonce_odr constant
-// CHECK: @_ZTI2T1 = linkonce_odr unnamed_addr constant
+// CHECK: @_ZTI2T1 = linkonce_odr constant
 // CHECK: @_ZTS1T = linkonce_odr constant
-// CHECK: @_ZTI1T = linkonce_odr unnamed_addr constant
-// CHECK: @_ZTI1C = weak_odr unnamed_addr constant
+// CHECK: @_ZTI1T = linkonce_odr constant
+// CHECK: @_ZTI1C = weak_odr constant
 // CHECK: @_ZTS2V1 = weak_odr constant
-// CHECK: @_ZTI2V1 = weak_odr unnamed_addr constant
+// CHECK: @_ZTI2V1 = weak_odr constant
 // CHECK: @_ZTS2V2 = weak_odr constant
-// CHECK: @_ZTI2V2 = weak_odr unnamed_addr constant
+// CHECK: @_ZTI2V2 = weak_odr constant
diff --git a/test/CodeGenCXX/weak-external.cpp b/test/CodeGenCXX/weak-external.cpp
index dad54f6..a2c53a5 100644
--- a/test/CodeGenCXX/weak-external.cpp
+++ b/test/CodeGenCXX/weak-external.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang -fexceptions %s -S -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -triple %itanium_abi_triple %s -S -emit-llvm -o - | FileCheck %s
 // PR4262
 
 // CHECK-NOT: _ZNSs12_S_constructIPKcEEPcT_S3_RKSaIcESt20forward_iterator_tag
diff --git a/test/CodeGenCXX/windows-itanium-exceptions.cpp b/test/CodeGenCXX/windows-itanium-exceptions.cpp
new file mode 100644
index 0000000..e2c4190
--- /dev/null
+++ b/test/CodeGenCXX/windows-itanium-exceptions.cpp
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -emit-llvm -triple thumbv7-windows-itanium -fexceptions -fcxx-exceptions %s -o - | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -triple i686-windows-itanium -fexceptions -fcxx-exceptions %s -o - | FileCheck %s
+// REQUIRES: asserts
+
+void except() {
+  throw 32;
+}
+
+void attempt() {
+  try { except(); } catch (...) { }
+}
+
+// CHECK: @_ZTIi = external constant i8*
+
+// CHECK: define {{.*}}void @_Z6exceptv() {{.*}} {
+// CHECK:   %exception = call {{.*}}i8* @__cxa_allocate_exception(i32 4)
+// CHECK:   %0 = bitcast i8* %exception to i32*
+// CHECK:   store i32 32, i32* %0
+// CHECK:   call {{.*}}void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null)
+// CHECK:   unreachable
+// CHECK: }
+
+// CHECK: define {{.*}}void @_Z7attemptv() {{.*}} {
+// CHECK:   %exn.slot = alloca i8*
+// CHECK:   %ehselector.slot = alloca i32
+// CHECK:   invoke {{.*}}void @_Z6exceptv()
+// CHECK:     to label %invoke.cont unwind label %lpad
+// CHECK: invoke.cont:
+// CHECK:    br label %try.cont
+// CHECK: lpad:
+// CHECK:    %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+// CHECK:      catch i8* null
+// CHECK:    %1 = extractvalue { i8*, i32 } %0, 0
+// CHECK:    store i8* %1, i8** %exn.slot
+// CHECK:    %2 = extractvalue { i8*, i32 } %0, 1
+// CHECK:    store i32 %2, i32* %ehselector.slot
+// CHECK:    br label %catch
+// CHECK: catch:
+// CHECK:    %exn = load i8** %exn.slot
+// CHECK:    %3 = call {{.*}}i8* @__cxa_begin_catch(i8* %{{2|exn}})
+// CHECK:    call {{.*}}void @__cxa_end_catch()
+// CHECK:    br label %try.cont
+// CHECK: try.cont:
+// CHECK:    ret void
+// CHECK: }
+
+
diff --git a/test/CodeGenCXX/x86_64-arguments-nacl-x32.cpp b/test/CodeGenCXX/x86_64-arguments-nacl-x32.cpp
new file mode 100644
index 0000000..bd8009b
--- /dev/null
+++ b/test/CodeGenCXX/x86_64-arguments-nacl-x32.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-nacl -emit-llvm -o - %s | FileCheck %s
+// TODO(jvoung): Enable this after 3.5 or 3.6 merge. Clang x32 doesn't
+// consider x32 has having 32-bit pointers in LLVM 3.4.
+// XUN: %clang_cc1 -triple=x86_64-unknown-linux-gnux32 -emit-llvm -o - %s | FileCheck %s
+
+struct test_struct {};
+typedef int test_struct::* test_struct_mdp;
+typedef int (test_struct::*test_struct_mfp)();
+
+// CHECK-LABEL: define i32 @{{.*}}f_mdp{{.*}}(i32 %a)
+test_struct_mdp f_mdp(test_struct_mdp a) { return a; }
+
+// CHECK-LABEL: define {{.*}} @{{.*}}f_mfp{{.*}}(i64 %a.coerce)
+test_struct_mfp f_mfp(test_struct_mfp a) { return a; }
+
+// A struct with <= 12 bytes before a member data pointer should still
+// be allowed in registers, since the member data pointer is only 4 bytes.
+// CHECK-LABEL: define void @{{.*}}f_struct_with_mdp{{.*}}(i64 %a.coerce0, i64 %a.coerce1)
+struct struct_with_mdp { char *a; char *b; char *c; test_struct_mdp d; };
+void f_struct_with_mdp(struct_with_mdp a) { (void)a; }
+
+struct struct_with_mdp_too_much {
+  char *a; char *b; char *c; char *d; test_struct_mdp e;
+};
+// CHECK-LABEL: define void @{{.*}}f_struct_with_mdp_too_much{{.*}}({{.*}} byval {{.*}} %a)
+void f_struct_with_mdp_too_much(struct_with_mdp_too_much a) {
+  (void)a;
+}
+
+// A struct with <= 8 bytes before a member function pointer should still
+// be allowed in registers, since the member function pointer is only 8 bytes.
+// CHECK-LABEL: define void @{{.*}}f_struct_with_mfp_0{{.*}}(i64 %a.coerce0, i32 %a.coerce1)
+struct struct_with_mfp_0 { char *a; test_struct_mfp b; };
+void f_struct_with_mfp_0(struct_with_mfp_0 a) { (void)a; }
+
+// CHECK-LABEL: define void @{{.*}}f_struct_with_mfp_1{{.*}}(i64 %a.coerce0, i64 %a.coerce1)
+struct struct_with_mfp_1 { char *a; char *b; test_struct_mfp c; };
+void f_struct_with_mfp_1(struct_with_mfp_1 a) { (void)a; }
+
+// CHECK-LABEL: define void @{{.*}}f_struct_with_mfp_too_much{{.*}}({{.*}} byval {{.*}} %a, i32 %x)
+struct struct_with_mfp_too_much {
+  char *a; char *b; char *c; test_struct_mfp d;
+};
+void f_struct_with_mfp_too_much(struct_with_mfp_too_much a, int x) {
+  (void)a;
+}
diff --git a/test/CodeGenCXX/x86_64-arguments.cpp b/test/CodeGenCXX/x86_64-arguments.cpp
index 2172e08..815ef61 100644
--- a/test/CodeGenCXX/x86_64-arguments.cpp
+++ b/test/CodeGenCXX/x86_64-arguments.cpp
@@ -32,6 +32,21 @@
 s4_mdp f4_0(s4_mdp a) { return a; }
 s4_mfp f4_1(s4_mfp a) { return a; }
 
+// A struct with <= one eightbyte before a member data pointer should still
+// be allowed in registers.
+// CHECK-LABEL: define void @{{.*}}f_struct_with_mdp{{.*}}(i8* %a.coerce0, i64 %a.coerce1)
+struct struct_with_mdp { char *a; s4_mdp b; };
+void f_struct_with_mdp(struct_with_mdp a) { (void)a; }
+
+// A struct with anything before a member function will be too big and
+// goes in memory.
+// CHECK-LABEL: define void @{{.*}}f_struct_with_mfp_0{{.*}}(%struct{{.*}} byval align 8 %a)
+struct struct_with_mfp_0 { char a; s4_mfp b; };
+void f_struct_with_mfp_0(struct_with_mfp_0 a) { (void)a; }
+
+// CHECK-LABEL: define void @{{.*}}f_struct_with_mfp_1{{.*}}(%struct{{.*}} byval align 8 %a)
+struct struct_with_mfp_1 { void *a; s4_mfp b; };
+void f_struct_with_mfp_1(struct_with_mfp_1 a) { (void)a; }
 
 namespace PR7523 {
 struct StringRef {
diff --git a/test/CodeGenObjC/2009-08-05-utf16.m b/test/CodeGenObjC/2009-08-05-utf16.m
index 06458e7..18ac1db 100644
--- a/test/CodeGenObjC/2009-08-05-utf16.m
+++ b/test/CodeGenObjC/2009-08-05-utf16.m
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -emit-llvm -w -x objective-c %s -o - | FileCheck %s
 // rdar://7095855 rdar://7115749
 
-// CHECK: internal unnamed_addr constant [6 x i16] [i16 105, i16 80, i16 111, i16 100, i16 8482, i16 0], align 2
+// CHECK: private unnamed_addr constant [6 x i16] [i16 105, i16 80, i16 111, i16 100, i16 8482, i16 0], section "__TEXT,__ustring", align 2
 void *P = @"iPod™";
diff --git a/test/CodeGenObjC/2010-02-01-utf16-with-null.m b/test/CodeGenObjC/2010-02-01-utf16-with-null.m
index 1863984..37fb9cd 100644
--- a/test/CodeGenObjC/2010-02-01-utf16-with-null.m
+++ b/test/CodeGenObjC/2010-02-01-utf16-with-null.m
@@ -1,5 +1,7 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple i686-apple-darwin -emit-llvm %s -o - | FileCheck %s
 // rdar://7589850
 
-// CHECK-NOT: __ustring
+// CHECK: @.str = private unnamed_addr constant [9 x i16] [i16 103, i16 111, i16 111, i16 100, i16 0, i16 98, i16 121, i16 101, i16 0], section "__TEXT,__ustring", align 2
+// CHECK: @_unnamed_cfstring_ = private constant %struct.NSConstantString { i32* getelementptr inbounds ([0 x i32]* @__CFConstantStringClassReference, i32 0, i32 0), i32 2000, i8* bitcast ([9 x i16]* @.str to i8*), i32 8 }, section "__DATA,__cfstring"
+// CHECK: @P = global i8* bitcast (%struct.NSConstantString* @_unnamed_cfstring_ to i8*), align 4
 void *P = @"good\0bye";
diff --git a/test/CodeGenObjC/arc-arm.m b/test/CodeGenObjC/arc-arm.m
index 3989f56..8d5f0d5 100644
--- a/test/CodeGenObjC/arc-arm.m
+++ b/test/CodeGenObjC/arc-arm.m
@@ -1,19 +1,22 @@
 // RUN: %clang_cc1 -triple armv7-apple-darwin10 -emit-llvm -fblocks -fobjc-arc -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-apple-ios -emit-llvm -fblocks -fobjc-arc -o - %s | FileCheck %s
+
+// <rdar://12438598>: use an autorelease marker on ARM64.
 
 id test0(void) {
   extern id test0_helper(void);
-  // CHECK:      [[T0:%.*]] = call arm_aapcscc i8* @test0_helper()
+  // CHECK:      [[T0:%.*]] = call [[CC:(arm_aapcscc )?]]i8* @test0_helper()
   // CHECK-NEXT: ret i8* [[T0]]
   return test0_helper();
 }
 
 void test1(void) {
   extern id test1_helper(void);
-  // CHECK:      [[T0:%.*]] = call arm_aapcscc i8* @test1_helper()
-  // CHECK-NEXT: call void asm sideeffect "mov\09r7, r7
-  // CHECK-NEXT: [[T1:%.*]] = call arm_aapcscc i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]])
+  // CHECK:      [[T0:%.*]] = call [[CC]]i8* @test1_helper()
+  // CHECK-NEXT: call void asm sideeffect "mov
+  // CHECK-NEXT: [[T1:%.*]] = call [[CC]]i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]])
   // CHECK-NEXT: store i8* [[T1]],
-  // CHECK-NEXT: call arm_aapcscc void @objc_storeStrong(
+  // CHECK-NEXT: call [[CC]]void @objc_storeStrong(
   // CHECK-NEXT: ret void
   id x = test1_helper();
 }
@@ -22,14 +25,14 @@
 @class A;
 A *test2(void) {
   extern A *test2_helper(void);
-  // CHECK:      [[T0:%.*]] = call arm_aapcscc [[A:%.*]]* @test2_helper()
+  // CHECK:      [[T0:%.*]] = call [[CC]][[A:%.*]]* @test2_helper()
   // CHECK-NEXT: ret [[A]]* [[T0]]
   return test2_helper();
 }
 
 id test3(void) {
   extern A *test3_helper(void);
-  // CHECK:      [[T0:%.*]] = call arm_aapcscc [[A:%.*]]* @test3_helper()
+  // CHECK:      [[T0:%.*]] = call [[CC]][[A:%.*]]* @test3_helper()
   // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
   // CHECK-NEXT: ret i8* [[T1]]
   return test3_helper();
diff --git a/test/CodeGenObjC/arc-foreach.m b/test/CodeGenObjC/arc-foreach.m
index 4456181..ec767d3 100644
--- a/test/CodeGenObjC/arc-foreach.m
+++ b/test/CodeGenObjC/arc-foreach.m
@@ -172,4 +172,4 @@
   // CHECK-LP64-NEXT: br label [[L]]
 }
 
-// CHECK: attributes [[NUW]] = { nounwind }
+// CHECK-LP64: attributes [[NUW]] = { nounwind }
diff --git a/test/CodeGenObjC/arc-ivar-layout.m b/test/CodeGenObjC/arc-ivar-layout.m
index 62428f5..06e387c 100644
--- a/test/CodeGenObjC/arc-ivar-layout.m
+++ b/test/CodeGenObjC/arc-ivar-layout.m
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -fobjc-arc -fobjc-runtime-has-weak -triple x86_64-apple-darwin -S %s -o %t-64.s
 // RUN: FileCheck -check-prefix CHECK-LP64 --input-file=%t-64.s %s
-// REQUIRES: x86-64-registered-target
+// REQUIRES: x86-registered-target
 // rdar://8991729
 
 @interface NSObject {
@@ -54,3 +54,12 @@
 @implementation UnsafePerson @end
 // CHECK-LP64: L_OBJC_CLASS_NAME_20:
 // CHECK-LP64-NEXT: .asciz      "!"
+
+// rdar://16136439
+@interface rdar16136439
+    @property (nonatomic, readonly, weak) id first;
+@end
+
+@implementation rdar16136439 @end
+// CHECK-LP64: L_OBJC_PROP_NAME_ATTR_29:
+// CHECK-LP64-NEXT: .asciz  "T@,R,W,N,V_first"
diff --git a/test/CodeGenObjC/arc-linetable-autorelease.m b/test/CodeGenObjC/arc-linetable-autorelease.m
index be05ec2..fa10915 100644
--- a/test/CodeGenObjC/arc-linetable-autorelease.m
+++ b/test/CodeGenObjC/arc-linetable-autorelease.m
@@ -29,12 +29,11 @@
   CGFloat pattern[2];
   // CHECK: define {{.*}}_createBezierPathWithWidth
   // CHECK: load {{.*}} %path, align {{.*}}, !dbg ![[RET:[0-9]+]]
-  // CHECK: call void @objc_storeStrong{{.*}} !dbg ![[ARC1:[0-9]+]]
-  // CHECK: call {{.*}} @objc_autoreleaseReturnValue{{.*}} !dbg ![[ARC2:[0-9]+]]
-  // CHECK: ret {{.*}} !dbg ![[ARC2]]
+  // CHECK: call void @objc_storeStrong{{.*}} !dbg ![[ARC:[0-9]+]]
+  // CHECK: call {{.*}} @objc_autoreleaseReturnValue{{.*}} !dbg ![[ARC]]
+  // CHECK: ret {{.*}} !dbg ![[ARC]]
   // CHECK: ![[RET]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null}
   return path;
-  // CHECK: ![[ARC1]] = metadata !{i32 [[@LINE+2]], i32 0, metadata !{{.*}}, null}
-  // CHECK: ![[ARC2]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null}
+  // CHECK: ![[ARC]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null}
 }
 @end
diff --git a/test/CodeGenObjC/arc-linetable.m b/test/CodeGenObjC/arc-linetable.m
index eac91f1..2d56ab3 100644
--- a/test/CodeGenObjC/arc-linetable.m
+++ b/test/CodeGenObjC/arc-linetable.m
@@ -32,6 +32,13 @@
 // CHECK: @objc_msgSend{{.*}} !dbg ![[MSG7:[0-9]+]]
 // CHECK: ret {{.*}} !dbg ![[RET7:[0-9]+]]
 
+// CHECK: define {{.*}}testCleanupVoid
+// CHECK: icmp ne {{.*}}!dbg ![[SKIP1:[0-9]+]]
+// CHECK: store i32 0, i32* {{.*}}, !dbg ![[RET8:[0-9]+]]
+// CHECK: @objc_storeStrong{{.*}}, !dbg ![[ARC8:[0-9]+]]
+// CHECK: ret {{.*}} !dbg ![[RET8]]
+
+typedef signed char BOOL;
 
 @interface NSObject
 + (id)alloc;
@@ -47,8 +54,10 @@
 
 @implementation AppDelegate : NSObject
 
+// CHECK: ![[TESTNOSIDEEFFECT:.*]] = {{.*}}[ DW_TAG_subprogram ] [line [[@LINE+1]]] [local] [def] [-[AppDelegate testNoSideEffect:]]
 - (int)testNoSideEffect:(NSString *)foo {
-  // CHECK: ![[ARC1]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null}
+  int x = 1;
+  // CHECK: ![[ARC1]] = metadata !{i32 [[@LINE+1]], i32 0, metadata ![[TESTNOSIDEEFFECT]], null}
   return 1; // Return expression
   // CHECK: ![[RET1]] = metadata !{i32 [[@LINE+1]], i32 0, metadata !{{.*}}, null}
 }           // Cleanup + Ret
@@ -91,6 +100,22 @@
   return 1;
 }
 
+- (void)testCleanupVoid:(BOOL)skip withDelegate: (AppDelegate *) delegate {
+  static BOOL skip_all;
+  // CHECK: ![[SKIP1]] = metadata !{i32 [[@LINE+1]], i32 0,
+  if (!skip_all) {
+    if (!skip) {
+      return;
+    }
+    NSString *s = @"bar";
+    if (!skip) {
+      [delegate testVoid :s];
+    }
+  }
+  // CHECK: ![[RET8]] = metadata !{i32 [[@LINE+2]], i32 0,
+  // CHECK: ![[ARC8]] = metadata !{i32 [[@LINE+1]], i32 0,
+}
+
 
 @end
 
diff --git a/test/CodeGenObjC/arc-property.m b/test/CodeGenObjC/arc-property.m
index c3c7e2b..8398a1b 100644
--- a/test/CodeGenObjC/arc-property.m
+++ b/test/CodeGenObjC/arc-property.m
@@ -67,7 +67,7 @@
 
 // CHECK:    define internal i8* @"\01-[Test2 theClass]"(
 // CHECK:      [[OFFSET:%.*]] = load i64* @"OBJC_IVAR_$_Test2._theClass"
-// CHECK-NEXT: [[T0:%.*]] = call i8* @objc_getProperty(i8* {{.*}}, i8* {{.*}}, i64 [[OFFSET]], i1 zeroext true)
+// CHECK-NEXT: [[T0:%.*]] = tail call i8* @objc_getProperty(i8* {{.*}}, i8* {{.*}}, i64 [[OFFSET]], i1 zeroext true)
 // CHECK-NEXT: ret i8* [[T0]]
 
 // CHECK:    define internal void @"\01-[Test2 setTheClass:]"(
diff --git a/test/CodeGenObjC/arc.m b/test/CodeGenObjC/arc.m
index 00cdb6f..8fc68ca 100644
--- a/test/CodeGenObjC/arc.m
+++ b/test/CodeGenObjC/arc.m
@@ -180,7 +180,7 @@
   // CHECK-NEXT: [[ALLOC:%.*]] = bitcast
   // CHECK-NEXT: [[INIT:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i32)*)(i8* [[ALLOC]],
 
-  // Initialization of return value, occuring within full-expression.
+  // Initialization of return value, occurring within full-expression.
   // Retain/release elided.
   // CHECK-NEXT: bitcast
   // CHECK-NEXT: [[INIT:%.*]] = bitcast
@@ -581,11 +581,11 @@
 // rdar://problem/12492434
 //   Note that we set the flag saying that we need destruction *and*
 //   the flag saying that we don't also need construction.
-// CHECK-GLOBALS: @"\01l_OBJC_CLASS_RO_$_Test23" = internal global [[RO_T:%.*]] { i32 390,
+// CHECK-GLOBALS: @"\01l_OBJC_CLASS_RO_$_Test23" = private global [[RO_T:%.*]] { i32 390,
 @interface Test23 { id x; } @end
 @implementation Test23 @end
 
-// CHECK-GLOBALS: @"\01l_OBJC_CLASS_RO_$_Test24" = internal global [[RO_T:%.*]] { i32 130,
+// CHECK-GLOBALS: @"\01l_OBJC_CLASS_RO_$_Test24" = private global [[RO_T:%.*]] { i32 130,
 @interface Test24 {} @end
 @implementation Test24 @end
 
@@ -1004,7 +1004,7 @@
 @synthesize x;
 @end
 // CHECK:    define internal i8* @"\01-[Test45 x]"(
-// CHECK:      [[CALL:%.*]] = call i8* @objc_getProperty(
+// CHECK:      [[CALL:%.*]] = tail call i8* @objc_getProperty(
 // CHECK-NEXT: ret i8* [[CALL]]
 
 // rdar://problem/9315552
@@ -1352,7 +1352,7 @@
 @implementation Person
 @synthesize address;
 @end
-// CHECK: call i8* @objc_getProperty
+// CHECK: tail call i8* @objc_getProperty
 // CHECK: call void @objc_setProperty 
 
 // Verify that we successfully parse and preserve this attribute in
diff --git a/test/CodeGenObjC/arm64-int32-ivar.m b/test/CodeGenObjC/arm64-int32-ivar.m
new file mode 100644
index 0000000..8f8c34a
--- /dev/null
+++ b/test/CodeGenObjC/arm64-int32-ivar.m
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple arm64-apple-ios -emit-llvm  -o - %s | FileCheck %s
+// rdar://12617764
+
+// CHECK: @"OBJC_IVAR_$_I.IVAR2" = global i32 8
+// CHECK: @"OBJC_IVAR_$_I.IVAR1" = global i32 0
+@interface I
+{
+	id IVAR1;
+	id IVAR2;
+}
+@end
+
+@implementation I
+// CHECK: [[IVAR:%.*]] = load i32* @"OBJC_IVAR_$_I.IVAR2"
+// CHECK: [[CONV:%.*]] = sext i32 [[IVAR]] to i64
+- (id) METH { return IVAR2; }
+@end
diff --git a/test/CodeGenObjC/attr-callconv.m b/test/CodeGenObjC/attr-callconv.m
new file mode 100644
index 0000000..b0a41f7
--- /dev/null
+++ b/test/CodeGenObjC/attr-callconv.m
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+
+@interface Test
+- (void)test;
+@end
+
+@implementation Test
+- (void)test __attribute__((stdcall)) {}
+    // CHECK: define{{.*}}x86_stdcallcc{{.*}}Test test
+    
+- (void)test2 __attribute__((ms_abi)) {}
+    // CHECK: define{{.*}}x86_64_win64cc{{.*}}Test test2
+@end
diff --git a/test/CodeGenObjC/block-var-layout.m b/test/CodeGenObjC/block-var-layout.m
index 0ad44da..171df7b 100644
--- a/test/CodeGenObjC/block-var-layout.m
+++ b/test/CodeGenObjC/block-var-layout.m
@@ -164,3 +164,11 @@
   };
  wrapperBlock();
 }
+
+// rdar://16111839
+typedef union { char ch[8];  } SS;
+typedef struct { SS s[4]; } CS;
+void test_union_in_layout() {
+  CS cs;
+  ^{ cs; };
+}
diff --git a/test/CodeGenObjC/blocks.m b/test/CodeGenObjC/blocks.m
index 5245679..6ae3e9f 100644
--- a/test/CodeGenObjC/blocks.m
+++ b/test/CodeGenObjC/blocks.m
@@ -65,7 +65,7 @@
   // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds [[WEAK_T]]* [[WEAKX]], i32 0, i32 3
   // CHECK-NEXT: store i32 28, i32* [[T3]]
 
-  // Copy and dipose helpers.
+  // Copy and dispose helpers.
   // CHECK-NEXT: [[T4:%.*]] = getelementptr inbounds [[WEAK_T]]* [[WEAKX]], i32 0, i32 4
   // CHECK-NEXT: store i8* bitcast (void (i8*, i8*)* @__Block_byref_object_copy_{{.*}} to i8*), i8** [[T4]]
   // CHECK-NEXT: [[T5:%.*]] = getelementptr inbounds [[WEAK_T]]* [[WEAKX]], i32 0, i32 5
diff --git a/test/CodeGenObjC/boxing.m b/test/CodeGenObjC/boxing.m
index 87ff0e7..efd2b16 100644
--- a/test/CodeGenObjC/boxing.m
+++ b/test/CodeGenObjC/boxing.m
@@ -53,18 +53,18 @@
 + (id)stringWithUTF8String:(const char *)nullTerminatedCString;
 @end
 
-// CHECK: [[WithIntMeth:@".*"]] = internal global [15 x i8] c"numberWithInt:\00"
-// CHECK: [[WithIntSEL:@".*"]] = internal externally_initialized global i8* getelementptr inbounds ([15 x i8]* [[WithIntMeth]]
-// CHECK: [[WithCharMeth:@".*"]] = internal global [16 x i8] c"numberWithChar:\00"
-// CHECK: [[WithCharSEL:@".*"]] = internal externally_initialized global i8* getelementptr inbounds ([16 x i8]* [[WithCharMeth]]
-// CHECK: [[WithBoolMeth:@".*"]] = internal global [16 x i8] c"numberWithBool:\00"
-// CHECK: [[WithBoolSEL:@".*"]] = internal externally_initialized global i8* getelementptr inbounds ([16 x i8]* [[WithBoolMeth]]
-// CHECK: [[WithIntegerMeth:@".*"]] = internal global [19 x i8] c"numberWithInteger:\00"
-// CHECK: [[WithIntegerSEL:@".*"]] = internal externally_initialized global i8* getelementptr inbounds ([19 x i8]* [[WithIntegerMeth]]
-// CHECK: [[WithUnsignedIntegerMeth:@".*"]] = internal global [27 x i8] c"numberWithUnsignedInteger:\00"
-// CHECK: [[WithUnsignedIntegerSEL:@".*"]] = internal externally_initialized global i8* getelementptr inbounds ([27 x i8]* [[WithUnsignedIntegerMeth]]
-// CHECK: [[stringWithUTF8StringMeth:@".*"]] = internal global [22 x i8] c"stringWithUTF8String:\00"
-// CHECK: [[stringWithUTF8StringSEL:@".*"]] = internal externally_initialized global i8* getelementptr inbounds ([22 x i8]* [[stringWithUTF8StringMeth]]
+// CHECK: [[WithIntMeth:@".*"]] = private global [15 x i8] c"numberWithInt:\00"
+// CHECK: [[WithIntSEL:@".*"]] = private externally_initialized global i8* getelementptr inbounds ([15 x i8]* [[WithIntMeth]]
+// CHECK: [[WithCharMeth:@".*"]] = private global [16 x i8] c"numberWithChar:\00"
+// CHECK: [[WithCharSEL:@".*"]] = private externally_initialized global i8* getelementptr inbounds ([16 x i8]* [[WithCharMeth]]
+// CHECK: [[WithBoolMeth:@".*"]] = private global [16 x i8] c"numberWithBool:\00"
+// CHECK: [[WithBoolSEL:@".*"]] = private externally_initialized global i8* getelementptr inbounds ([16 x i8]* [[WithBoolMeth]]
+// CHECK: [[WithIntegerMeth:@".*"]] = private global [19 x i8] c"numberWithInteger:\00"
+// CHECK: [[WithIntegerSEL:@".*"]] = private externally_initialized global i8* getelementptr inbounds ([19 x i8]* [[WithIntegerMeth]]
+// CHECK: [[WithUnsignedIntegerMeth:@".*"]] = private global [27 x i8] c"numberWithUnsignedInteger:\00"
+// CHECK: [[WithUnsignedIntegerSEL:@".*"]] = private externally_initialized global i8* getelementptr inbounds ([27 x i8]* [[WithUnsignedIntegerMeth]]
+// CHECK: [[stringWithUTF8StringMeth:@".*"]] = private global [22 x i8] c"stringWithUTF8String:\00"
+// CHECK: [[stringWithUTF8StringSEL:@".*"]] = private externally_initialized global i8* getelementptr inbounds ([22 x i8]* [[stringWithUTF8StringMeth]]
 
 int main() {
   // CHECK: load i8** [[WithIntSEL]]
diff --git a/test/CodeGenObjC/complex-property.m b/test/CodeGenObjC/complex-property.m
index d65d72f..bed0ca6 100644
--- a/test/CodeGenObjC/complex-property.m
+++ b/test/CodeGenObjC/complex-property.m
@@ -13,8 +13,8 @@
   a.y += a1;
 }
 
-// CHECK-LP64: internal global [13 x i8] c"COMPLEX_PROP
-// CHECK-LP64: internal global [17 x i8] c"setCOMPLEX_PROP
+// CHECK-LP64: private global [13 x i8] c"COMPLEX_PROP
+// CHECK-LP64: private global [17 x i8] c"setCOMPLEX_PROP
 
 // rdar: // 7351147
 @interface B
diff --git a/test/CodeGenObjC/constant-strings.m b/test/CodeGenObjC/constant-strings.m
index cad634a..0a65496 100644
--- a/test/CodeGenObjC/constant-strings.m
+++ b/test/CodeGenObjC/constant-strings.m
@@ -3,7 +3,7 @@
 
 // Check that we set alignment 1 on the string.
 //
-// CHECK-NEXT: @.str = {{.*}}constant [13 x i8] c"Hello World!\00", align 1
+// CHECK-NEXT: @.str = {{.*}}constant [13 x i8] c"Hello World!\00", section "__TEXT,__cstring,cstring_literals", align 1
 
 // RUN: %clang_cc1 -fobjc-runtime=gcc -emit-llvm -o %t %s
 // RUN: FileCheck --check-prefix=CHECK-GNU < %t %s
diff --git a/test/CodeGenObjC/debug-info-block-helper.m b/test/CodeGenObjC/debug-info-block-helper.m
index 49c8c5d..1403327 100644
--- a/test/CodeGenObjC/debug-info-block-helper.m
+++ b/test/CodeGenObjC/debug-info-block-helper.m
@@ -1,4 +1,4 @@
-// REQUIRES: x86-64-registered-target
+// REQUIRES: x86-registered-target
 // RUN: %clang_cc1 -emit-llvm -fblocks -g -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 %s -o - | FileCheck %s
 extern void foo(void(^)(void));
 
diff --git a/test/CodeGenObjC/debug-info-block-line.m b/test/CodeGenObjC/debug-info-block-line.m
index 1965e1d..9ba22bc 100644
--- a/test/CodeGenObjC/debug-info-block-line.m
+++ b/test/CodeGenObjC/debug-info-block-line.m
@@ -1,4 +1,4 @@
-// REQUIRES: x86-64-registered-target
+// REQUIRES: x86-registered-target
 // RUN: %clang_cc1 -emit-llvm -fblocks -fobjc-arc -g -triple x86_64-apple-darwin10 %s -o - | FileCheck %s
 
 // rdar://11562117
diff --git a/test/CodeGenObjC/debug-info-blocks.m b/test/CodeGenObjC/debug-info-blocks.m
index 63068a9..d025ca8 100644
--- a/test/CodeGenObjC/debug-info-blocks.m
+++ b/test/CodeGenObjC/debug-info-blocks.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -fblocks -g  -triple x86_64-apple-darwin10 -fobjc-dispatch-method=mixed  %s -o - | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -fblocks -g  -triple x86_64-apple-darwin10 -fobjc-dispatch-method=mixed -x objective-c < %s -o - | FileCheck %s
 
 // rdar://problem/9279956
 // Test that we generate the proper debug location for a captured self.
diff --git a/test/CodeGenObjC/debug-info-class-extension.m b/test/CodeGenObjC/debug-info-class-extension.m
index e1573f0..0d1b720 100644
--- a/test/CodeGenObjC/debug-info-class-extension.m
+++ b/test/CodeGenObjC/debug-info-class-extension.m
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -masm-verbose -S -g %s -o - | FileCheck %s
+// FIXME: Check IR rather than asm, then triple is not needed.
+// RUN: %clang_cc1 -triple %itanium_abi_triple -masm-verbose -S -g %s -o - | FileCheck %s
 
 // CHECK: AT_APPLE_objc_complete_type
 
diff --git a/test/CodeGenObjC/debug-info-class-extension2.m b/test/CodeGenObjC/debug-info-class-extension2.m
index bae12dc..383390c 100644
--- a/test/CodeGenObjC/debug-info-class-extension2.m
+++ b/test/CodeGenObjC/debug-info-class-extension2.m
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1  -masm-verbose -S -g %s -o - | FileCheck %s
+// FIXME: Check IR rather than asm, then triple is not needed.
+// RUN: %clang_cc1 -triple %itanium_abi_triple -masm-verbose -S -g %s -o - | FileCheck %s
 // CHECK: AT_APPLE_objc_complete_type
 
 @interface Foo {} @end
diff --git a/test/CodeGenObjC/debug-info-crash-2.m b/test/CodeGenObjC/debug-info-crash-2.m
index 7d05f53..9e80580 100644
--- a/test/CodeGenObjC/debug-info-crash-2.m
+++ b/test/CodeGenObjC/debug-info-crash-2.m
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin11 -g -S %s -o -
-// REQUIRES: x86-64-registered-target
+// REQUIRES: x86-registered-target
 
 @class Bar;
 @interface Foo
diff --git a/test/CodeGenObjC/debug-info-getter-name.m b/test/CodeGenObjC/debug-info-getter-name.m
index 3939f35..70d9936 100644
--- a/test/CodeGenObjC/debug-info-getter-name.m
+++ b/test/CodeGenObjC/debug-info-getter-name.m
@@ -1,4 +1,4 @@
-// REQUIRES: x86-64-registered-target
+// REQUIRES: x86-registered-target
 // RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin10 -fexceptions -fobjc-exceptions -g %s -o - | FileCheck %s
 
 // CHECK: {{.*}}, metadata !"-[InstanceVariablesEverywhereButTheInterface someString]", {{.*}}} ; [ DW_TAG_subprogram ]
diff --git a/test/CodeGenObjC/debug-info-ivars-indirect.m b/test/CodeGenObjC/debug-info-ivars-indirect.m
index 1548ddd..f9593d2 100644
--- a/test/CodeGenObjC/debug-info-ivars-indirect.m
+++ b/test/CodeGenObjC/debug-info-ivars-indirect.m
@@ -3,6 +3,14 @@
 // Make sure we generate debug symbols for an indirectly referenced
 // extension to an interface.
 
+// This happens to be the order the members are emitted in... I'm assuming it's
+// not meaningful/important, so if something causes the order to change, feel
+// free to update the test to reflect the new order.
+// CHECK: ; [ DW_TAG_member ] [a]
+// CHECK: ; [ DW_TAG_member ] [d]
+// CHECK: ; [ DW_TAG_member ] [c]
+// CHECK: ; [ DW_TAG_member ] [b]
+
 @interface I
 {
     @public int a;
@@ -29,4 +37,23 @@
     int _b = s->i->b;
 }
 
-// CHECK: {{.*}} [ DW_TAG_member ] [b] [line 24, size 32, align 32, offset 0] [from int]
+
+I *source();
+
+@interface I()
+{
+    @public int c;
+}
+@end
+
+void use() {
+    int _c = source()->c;
+}
+
+@interface I()
+{
+    @public int d;
+}
+@end
+
+I *x();
diff --git a/test/CodeGenObjC/debug-info-lifetime-crash.m b/test/CodeGenObjC/debug-info-lifetime-crash.m
index 9038201..81c7fbc 100644
--- a/test/CodeGenObjC/debug-info-lifetime-crash.m
+++ b/test/CodeGenObjC/debug-info-lifetime-crash.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -cc1 -triple arm-apple-ios -emit-llvm -g -fblocks -fobjc-runtime=ios-7.0.0 -fobjc-arc %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple arm-apple-ios -emit-llvm -g -fblocks -fobjc-runtime=ios-7.0.0 -fobjc-arc %s -o - | FileCheck %s
 // rdar://problem/14990656
 @protocol NSObject
 - (id)copy;
diff --git a/test/CodeGenObjC/debug-info-property.m b/test/CodeGenObjC/debug-info-property.m
index dd105a5..6e2dcda 100644
--- a/test/CodeGenObjC/debug-info-property.m
+++ b/test/CodeGenObjC/debug-info-property.m
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -masm-verbose -S -g %s -o - | FileCheck %s
+// FIXME: Check IR rather than asm, then triple is not needed.
+// RUN: %clang_cc1 -triple %itanium_abi_triple -masm-verbose -S -g %s -o - | FileCheck %s
 
 // CHECK: AT_APPLE_property_name
 // CHECK: AT_APPLE_property_attribute
diff --git a/test/CodeGenObjC/debug-info-property2.m b/test/CodeGenObjC/debug-info-property2.m
index 4cd76c1..41140dc 100644
--- a/test/CodeGenObjC/debug-info-property2.m
+++ b/test/CodeGenObjC/debug-info-property2.m
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -masm-verbose -S -g %s -o - | FileCheck %s
+// FIXME: Check IR rather than asm, then triple is not needed.
+// RUN: %clang_cc1 -triple %itanium_abi_triple -masm-verbose -S -g %s -o - | FileCheck %s
 
 // CHECK: AT_APPLE_property_name
 @interface C {
diff --git a/test/CodeGenObjC/debug-info-property4.m b/test/CodeGenObjC/debug-info-property4.m
index 71863a6..2057d4d 100644
--- a/test/CodeGenObjC/debug-info-property4.m
+++ b/test/CodeGenObjC/debug-info-property4.m
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -masm-verbose -S -g %s -o - | FileCheck %s
+// FIXME: Check IR rather than asm, then triple is not needed.
+// RUN: %clang_cc1 -triple %itanium_abi_triple -masm-verbose -S -g %s -o - | FileCheck %s
 
 // CHECK: AT_APPLE_property_name
 // CHECK-NOT: AT_APPLE_property_getter
diff --git a/test/CodeGenObjC/debug-info-property5.m b/test/CodeGenObjC/debug-info-property5.m
index 272aa5d..126d0a2 100644
--- a/test/CodeGenObjC/debug-info-property5.m
+++ b/test/CodeGenObjC/debug-info-property5.m
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -masm-verbose -S -g %s -o - | FileCheck %s
+// FIXME: Check IR rather than asm, then triple is not needed.
+// RUN: %clang_cc1 -triple %itanium_abi_triple -masm-verbose -S -g %s -o - | FileCheck %s
 
 // CHECK: AT_APPLE_property_name
 // CHECK: AT_APPLE_property_getter
diff --git a/test/CodeGenObjC/debug-info-pubtypes.m b/test/CodeGenObjC/debug-info-pubtypes.m
index 8b7dfad..845b946 100644
--- a/test/CodeGenObjC/debug-info-pubtypes.m
+++ b/test/CodeGenObjC/debug-info-pubtypes.m
@@ -1,4 +1,4 @@
-// REQUIRES: x86-64-registered-target
+// REQUIRES: x86-registered-target
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -g -emit-llvm %s -o - | FileCheck %s
 
 // CHECK: {{.*}} [ DW_TAG_structure_type ] [H] [line 6,
diff --git a/test/CodeGenObjC/debug-info-self.m b/test/CodeGenObjC/debug-info-self.m
index 8cbc029..7a484d8 100644
--- a/test/CodeGenObjC/debug-info-self.m
+++ b/test/CodeGenObjC/debug-info-self.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -g %s -o - | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -g %s -o - | FileCheck %s
 // self and _cmd are marked as DW_AT_artificial. 
 // myarg is not marked as DW_AT_artificial.
 
diff --git a/test/CodeGenObjC/debug-property-synth.m b/test/CodeGenObjC/debug-property-synth.m
index 954620a..68fb956 100644
--- a/test/CodeGenObjC/debug-property-synth.m
+++ b/test/CodeGenObjC/debug-property-synth.m
@@ -1,8 +1,27 @@
-// RUN: %clang_cc1 -masm-verbose -S -g %s -o - | FileCheck %s
-// Radar 9468526
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -g %s -o - | FileCheck %s
+// rdar://problem/9468526
+//
+// Setting a breakpoint on a property should create breakpoints in
+// synthesized getters/setters.
+//
 @interface I {
   int _p1;
 }
+// Test that the linetable entries for the synthesized getter and
+// setter are correct.
+//
+// CHECK: define {{.*}}[I p1]
+// CHECK-NOT: ret
+// CHECK: load {{.*}}, !dbg ![[DBG1:[0-9]+]]
+//
+// CHECK: define {{.*}}[I setP1:]
+// CHECK-NOT: ret
+// CHECK: load {{.*}}, !dbg ![[DBG2:[0-9]+]]
+//
+// CHECK: [ DW_TAG_subprogram ] [line [[@LINE+4]]] [local] [def] [-[I p1]]
+// CHECK: [ DW_TAG_subprogram ] [line [[@LINE+3]]] [local] [def] [-[I setP1:]]
+// CHECK: ![[DBG1]] = metadata !{i32 [[@LINE+2]],
+// CHECK: ![[DBG2]] = metadata !{i32 [[@LINE+1]],
 @property int p1;
 @end
 
@@ -13,8 +32,5 @@
 int main() {
   I *myi;
   myi.p1 = 2;
-  return 0;
+  return myi.p1;
 }
-
-// FIXME: Make this test ir files.
-// CHECK:       .loc    2 6 0
diff --git a/test/CodeGenObjC/encode-cstyle-method.m b/test/CodeGenObjC/encode-cstyle-method.m
index 309089b..d0a9921 100644
--- a/test/CodeGenObjC/encode-cstyle-method.m
+++ b/test/CodeGenObjC/encode-cstyle-method.m
@@ -8,4 +8,4 @@
 @implementation Foo
 - (id)test:(id )one, id two {return two; } @end
 
-// CHECK-LP64: internal global [11 x i8] c"@24@0:8@16
+// CHECK-LP64: private global [11 x i8] c"@24@0:8@16
diff --git a/test/CodeGenObjC/encode-test-6.m b/test/CodeGenObjC/encode-test-6.m
index b7b3799..4e9c422 100644
--- a/test/CodeGenObjC/encode-test-6.m
+++ b/test/CodeGenObjC/encode-test-6.m
@@ -14,8 +14,8 @@
 -(void)foo:(Z)a: (char*)b : (Z)c : (double) d {}
 @end
 
-// CHECK: internal global [14 x i8] c"v16@0:8{?=}16
-// CHECK: internal global [26 x i8] c"v32@0:8{?=}16*16{?=}24d24
+// CHECK: private global [14 x i8] c"v16@0:8{?=}16
+// CHECK: private global [26 x i8] c"v32@0:8{?=}16*16{?=}24d24
 
 
 // rdar://13190095
@@ -34,7 +34,7 @@
 @synthesize property = _property;
 @end
 
-// CHECK: internal global [24 x i8] c"^{BABugExample=@}16
+// CHECK: private global [24 x i8] c"^{BABugExample=@}16
 
 // rdar://14408244
 @class SCNCamera;
@@ -52,4 +52,15 @@
     C3DCameraStorage _storage;
 }
 @end
-// CHECK: internal global [39 x i8] c"{?=\22presentationInstance\22^{SCNCamera}}\00"
+// CHECK: private global [39 x i8] c"{?=\22presentationInstance\22^{SCNCamera}}\00"
+
+// rdar://16655340
+int i;
+typeof(@encode(typeof(i))) e = @encode(typeof(i));
+const char * Test()
+{
+    return e;
+}
+// CHECK: @e = global [2 x i8] c"i\00", align 1
+// CHECK: define i8* @Test()
+// CHECK: ret i8* getelementptr inbounds ([2 x i8]* @e, i32 0, i32 0)
diff --git a/test/CodeGenObjC/encode-test.m b/test/CodeGenObjC/encode-test.m
index d6e7b6d..6f2423b 100644
--- a/test/CodeGenObjC/encode-test.m
+++ b/test/CodeGenObjC/encode-test.m
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -triple i686-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o %t %s
 // RUN: FileCheck < %t %s
 //
-// CHECK: @"\01L_OBJC_METH_VAR_TYPE_34" = internal global [16 x i8] c"v12@0:4[3[4@]]8\00"
+// CHECK: @"\01L_OBJC_METH_VAR_TYPE_34" = private global [16 x i8] c"v12@0:4[3[4@]]8\00"
 
 @class Int1;
 
@@ -169,3 +169,11 @@
 // PR14628
 // CHECK: @g12 = constant [3 x i8] c"Ai\00"
 const char g12[] = @encode(_Atomic(int));
+
+// rdar://15824769
+id test_id = 0;
+Class test_class = 0;
+const char g13[] = @encode(__typeof__(*test_class));
+const char g14[] = @encode(__typeof__(*test_id));
+// CHECK: constant [14 x i8] c"{objc_class=}\00"
+// CHECK: constant [15 x i8] c"{objc_object=}\00"
diff --git a/test/CodeGenObjC/exceptions-asm-attribute.m b/test/CodeGenObjC/exceptions-asm-attribute.m
new file mode 100644
index 0000000..eb36990
--- /dev/null
+++ b/test/CodeGenObjC/exceptions-asm-attribute.m
@@ -0,0 +1,86 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fexceptions -fobjc-exceptions -o %t %s
+// RUN: FileCheck -check-prefix=CHECK-X86_64 < %t %s
+// RUN: FileCheck -check-prefix=CHECK-EHTYPE < %t %s
+// rdar://16462586
+
+// We need exactly 3 of these.
+// CHECK-EHTYPE: @"OBJC_EHTYPE_$_MySecretNamespace.EH3"
+// CHECK-EHTYPE: @"OBJC_EHTYPE_$_MySecretNamespace.EH3"
+// CHECK-EHTYPE: @"OBJC_EHTYPE_$_MySecretNamespace.EH3"
+// CHECK-EHTYPE-NOT: @"OBJC_EHTYPE_$_MySecretNamespace.EH3"
+
+// CHECK-X86_64: @"OBJC_CLASS_$_MySecretNamespace.A" = global {{.*}}, section "__DATA, __objc_data", align 8
+// CHECK-X86_64: @"OBJC_METACLASS_$_MySecretNamespace.A" = global {{.*}}, section "__DATA, __objc_data", align 8
+// CHECK-X86_64: @"\01L_OBJC_CLASS_NAME_" = {{.*}}, section "__TEXT,__objc_classname,cstring_literals", align 1
+// CHECK-X86_64: @"OBJC_EHTYPE_$_MySecretNamespace.EH1" = weak global {{.*}}, section "__DATA,__datacoal_nt,coalesced", align 8
+// CHECK-X86_64: @"OBJC_EHTYPE_$_MySecretNamespace.EH2" = external global
+// CHECK-X86_64: @"OBJC_EHTYPE_$_MySecretNamespace.EH3" = global {{.*}}, section "__DATA,__objc_const", align 8
+// CHECK-X86_64: @"\01L_OBJC_LABEL_CLASS_$" = private global {{.*}}, section "__DATA, __objc_classlist, regular, no_dead_strip", align 8
+// CHECK-X86_64: define internal void @"\01-[A im0]"
+// CHECK-X86_64: define internal void @"\01-[A(Cat) im1]"
+
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-exceptions -fvisibility hidden -emit-llvm -o %t %s
+// RUN: FileCheck -check-prefix=CHECK-X86_64-HIDDEN < %t %s
+
+// CHECK-X86_64-HIDDEN: @"OBJC_CLASS_$_MySecretNamespace.A" = hidden global {{.*}}, section "__DATA, __objc_data", align 8
+// CHECK-X86_64-HIDDEN: @"OBJC_METACLASS_$_MySecretNamespace.A" = hidden global {{.*}}, section "__DATA, __objc_data", align 8
+// CHECK-X86_64-HIDDEN: @"OBJC_EHTYPE_$_MySecretNamespace.EH1" = weak hidden global {{.*}}, section "__DATA,__datacoal_nt,coalesced"
+// CHECK-X86_64-HIDDEN: @"OBJC_EHTYPE_$_MySecretNamespace.EH2" = external global
+// CHECK-X86_64-HIDDEN: @"OBJC_EHTYPE_$_MySecretNamespace.EH3" = hidden global {{.*}}, section "__DATA,__objc_const", align 8
+// CHECK-X86_64-HIDDEN: define internal void @"\01-[A im0]"
+// CHECK-X86_64-HIDDEN: define internal void @"\01-[A(Cat) im1]"
+
+// RUN: %clang_cc1 -triple armv6-apple-darwin10 -target-abi apcs-gnu -fobjc-exceptions -emit-llvm -o %t %s
+// RUN: FileCheck -check-prefix=CHECK-ARMV6 < %t %s
+
+// CHECK-ARMV6: @"OBJC_CLASS_$_MySecretNamespace.A" = global {{.*}}, section "__DATA, __objc_data", align 4
+// CHECK-ARMV6: @"OBJC_METACLASS_$_MySecretNamespace.A" = global {{.*}}, section "__DATA, __objc_data", align 4
+// CHECK-ARMV6: @"\01L_OBJC_CLASS_NAME_" = {{.*}}, section "__TEXT,__objc_classname,cstring_literals", align 1
+// CHECK-ARMV6: @"OBJC_EHTYPE_$_MySecretNamespace.EH1" = weak global {{.*}}, section "__DATA,__datacoal_nt,coalesced", align 4
+// CHECK-ARMV6: @"OBJC_EHTYPE_$_MySecretNamespace.EH2" = external global
+// CHECK-ARMV6: @"OBJC_EHTYPE_$_MySecretNamespace.EH3" = global {{.*}}, section "__DATA,__objc_const", align 4
+// CHECK-ARMV6: @"\01L_OBJC_LABEL_CLASS_$" = private global {{.*}}, section "__DATA, __objc_classlist, regular, no_dead_strip", align 4
+// CHECK-ARMV6: define internal void @"\01-[A im0]"
+// CHECK-ARMV6: define internal void @"\01-[A(Cat) im1]"
+
+__attribute__((objc_runtime_name("MySecretNamespace.A")))
+@interface A
+@end
+
+@implementation A
+-(void) im0 {
+}
+@end
+
+@implementation A (Cat)
+-(void) im1 {
+}
+@end
+
+__attribute__((objc_runtime_name("MySecretNamespace.EH1")))
+@interface EH1
+@end
+
+__attribute__((objc_runtime_name("MySecretNamespace.EH2")))
+__attribute__((__objc_exception__))
+@interface EH2
+@end
+
+__attribute__((objc_runtime_name("MySecretNamespace.EH3")))
+__attribute__((__objc_exception__))
+@interface EH3
+@end
+
+void f1();
+
+void f0(id x) {
+  @try {
+    f1();
+  } @catch (EH1 *x) {
+  } @catch (EH2 *x) {
+  } @catch (EH3 *x) {
+  }
+}
+
+@implementation EH3
+@end
diff --git a/test/CodeGenObjC/externally-initialized-selectors.m b/test/CodeGenObjC/externally-initialized-selectors.m
index 87a7c04..0b7c24e 100644
--- a/test/CodeGenObjC/externally-initialized-selectors.m
+++ b/test/CodeGenObjC/externally-initialized-selectors.m
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -cc1 -fobjc-runtime=macosx-fragile-10.5 -o - -emit-llvm %s | FileCheck %s
-// RUN: %clang_cc1 -cc1 -o - -emit-llvm %s | FileCheck %s
+// RUN: %clang_cc1 -fobjc-runtime=macosx-fragile-10.5 -o - -emit-llvm %s | FileCheck %s
+// RUN: %clang_cc1 -o - -emit-llvm %s | FileCheck %s
 
-// CHECK: @"\01L_OBJC_SELECTOR_REFERENCES_" = internal externally_initialized global
+// CHECK: @"\01L_OBJC_SELECTOR_REFERENCES_" = private externally_initialized global
 
 void test(id x) {
   [x doSomething];
diff --git a/test/CodeGenObjC/forward-protocol-metadata-symbols.m b/test/CodeGenObjC/forward-protocol-metadata-symbols.m
new file mode 100644
index 0000000..2b687d1
--- /dev/null
+++ b/test/CodeGenObjC/forward-protocol-metadata-symbols.m
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -emit-llvm -x objective-c %s -o - | FileCheck %s
+// rdar://16203115
+
+@interface NSObject @end
+
+@protocol P0;
+
+@interface A : NSObject <P0>
++(Class) getClass;
+@end
+
+@implementation A
++(Class) getClass { return self; }
+@end
+
+int main() {
+  Protocol *P0 = @protocol(P0);
+  return 0;
+}
+
+// CHECK: @"\01l_OBJC_PROTOCOL_$_P0" = weak hidden global
+// CHECK: @"\01l_OBJC_CLASS_PROTOCOLS_$_A" = private global
+// CHECK: @"\01l_OBJC_LABEL_PROTOCOL_$_P0" = weak hidden global
+// CHECK: @"\01l_OBJC_PROTOCOL_REFERENCE_$_P0" = weak hidden global
+
+// CHECK: llvm.compiler.used = appending global [10 x i8*] {{[^"]*}}"\01L_OBJC_CLASS_NAME_"{{[^"]*}}"\01L_OBJC_METH_VAR_NAME_"{{[^"]*}}"\01L_OBJC_METH_VAR_TYPE_"{{[^"]*}}"\01l_OBJC_$_CLASS_METHODS_A"{{[^"]*}}"\01l_OBJC_CLASS_PROTOCOLS_$_A"{{[^"]*}}"\01L_OBJC_CLASS_NAME_1"{{[^"]*}}"\01l_OBJC_PROTOCOL_$_P0"{{[^"]*}}"\01l_OBJC_LABEL_PROTOCOL_$_P0"{{[^"]*}}"\01l_OBJC_PROTOCOL_REFERENCE_$_P0"{{[^"]*}}"\01L_OBJC_LABEL_CLASS_$"{{[^"]*}} section "llvm.metadata"
diff --git a/test/CodeGenObjC/getter-property-mismatch.m b/test/CodeGenObjC/getter-property-mismatch.m
index 21ed6ee..fe415d5 100644
--- a/test/CodeGenObjC/getter-property-mismatch.m
+++ b/test/CodeGenObjC/getter-property-mismatch.m
@@ -13,7 +13,7 @@
 @synthesize filenamesToServerLocation=_filenamesToServerLocation;
 @end
 
-// CHECK:  [[CALL:%.*]] = call i8* @objc_getProperty
+// CHECK:  [[CALL:%.*]] = tail call i8* @objc_getProperty
 // CHECK:  [[ONE:%.*]] = bitcast i8* [[CALL:%.*]] to [[T1:%.*]]*
 // CHECK:  [[TWO:%.*]] = bitcast [[T1]]* [[ONE]] to [[T2:%.*]]*
 // CHECK:  ret [[T2]]* [[TWO]]
diff --git a/test/CodeGenObjC/image-info.m b/test/CodeGenObjC/image-info.m
index 030bcae..49f5d90 100644
--- a/test/CodeGenObjC/image-info.m
+++ b/test/CodeGenObjC/image-info.m
@@ -4,14 +4,14 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o %t %s
 // RUN: FileCheck --check-prefix CHECK-NONFRAGILE < %t %s
 
-// CHECK-FRAGILE:      !llvm.module.flags = !{!0, !1, !2, !3}
-// CHECK-FRAGILE:      !0 = metadata !{i32 1, metadata !"Objective-C Version", i32 1}
-// CHECK-FRAGILE-NEXT: !1 = metadata !{i32 1, metadata !"Objective-C Image Info Version", i32 0}
-// CHECK-FRAGILE-NEXT: !2 = metadata !{i32 1, metadata !"Objective-C Image Info Section", metadata !"__OBJC, __image_info,regular"}
-// CHECK-FRAGILE-NEXT: !3 = metadata !{i32 4, metadata !"Objective-C Garbage Collection", i32 0}
+// CHECK-FRAGILE:      !llvm.module.flags = !{{{.*}}}
+// CHECK-FRAGILE:      !{{[0-9]+}} = metadata !{i32 1, metadata !"Objective-C Version", i32 1}
+// CHECK-FRAGILE-NEXT: !{{[0-9]+}} = metadata !{i32 1, metadata !"Objective-C Image Info Version", i32 0}
+// CHECK-FRAGILE-NEXT: !{{[0-9]+}} = metadata !{i32 1, metadata !"Objective-C Image Info Section", metadata !"__OBJC, __image_info,regular"}
+// CHECK-FRAGILE-NEXT: !{{[0-9]+}} = metadata !{i32 4, metadata !"Objective-C Garbage Collection", i32 0}
 
-// CHECK-NONFRAGILE:      !llvm.module.flags = !{!0, !1, !2, !3}
-// CHECK-NONFRAGILE:      !0 = metadata !{i32 1, metadata !"Objective-C Version", i32 2}
-// CHECK-NONFRAGILE-NEXT: !1 = metadata !{i32 1, metadata !"Objective-C Image Info Version", i32 0}
-// CHECK-NONFRAGILE-NEXT: !2 = metadata !{i32 1, metadata !"Objective-C Image Info Section", metadata !"__DATA, __objc_imageinfo, regular, no_dead_strip"}
-// CHECK-NONFRAGILE-NEXT: !3 = metadata !{i32 4, metadata !"Objective-C Garbage Collection", i32 0}
+// CHECK-NONFRAGILE:      !llvm.module.flags = !{{{.*}}}
+// CHECK-NONFRAGILE:      !{{[0-9]+}} = metadata !{i32 1, metadata !"Objective-C Version", i32 2}
+// CHECK-NONFRAGILE-NEXT: !{{[0-9]+}} = metadata !{i32 1, metadata !"Objective-C Image Info Version", i32 0}
+// CHECK-NONFRAGILE-NEXT: !{{[0-9]+}} = metadata !{i32 1, metadata !"Objective-C Image Info Section", metadata !"__DATA, __objc_imageinfo, regular, no_dead_strip"}
+// CHECK-NONFRAGILE-NEXT: !{{[0-9]+}} = metadata !{i32 4, metadata !"Objective-C Garbage Collection", i32 0}
diff --git a/test/CodeGenObjC/instance-method-metadata.m b/test/CodeGenObjC/instance-method-metadata.m
index 0d8c0e0..59be440 100644
--- a/test/CodeGenObjC/instance-method-metadata.m
+++ b/test/CodeGenObjC/instance-method-metadata.m
@@ -1,4 +1,4 @@
-// REQUIRES: x86-64-registered-target
+// REQUIRES: x86-registered-target
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -S -o %t %s 
 // RUN: FileCheck < %t %s
 
diff --git a/test/CodeGenObjC/interface-layout-64.m b/test/CodeGenObjC/interface-layout-64.m
index 4b41cf8..450300d 100644
--- a/test/CodeGenObjC/interface-layout-64.m
+++ b/test/CodeGenObjC/interface-layout-64.m
@@ -2,24 +2,24 @@
 
 // CHECK: @"OBJC_IVAR_$_I3._iv2" = global i64 8, section "__DATA, __objc_ivar", align 8
 // CHECK: @"OBJC_IVAR_$_I3._iv3" = global i64 12, section "__DATA, __objc_ivar", align 8
-// CHECK: _OBJC_CLASS_RO_$_I3" = internal global {{.*}} { i32 0, i32 8, i32 13
+// CHECK: _OBJC_CLASS_RO_$_I3" = private global {{.*}} { i32 0, i32 8, i32 13
 // CHECK: @"OBJC_IVAR_$_I4._iv4" = global i64 13, section "__DATA, __objc_ivar", align 8
-// CHECK: _OBJC_CLASS_RO_$_I4" = internal global {{.*}} { i32 0, i32 13, i32 14, {{.*}}
+// CHECK: _OBJC_CLASS_RO_$_I4" = private global {{.*}} { i32 0, i32 13, i32 14, {{.*}}
 // CHECK: @"OBJC_IVAR_$_I5._iv6_synth" = hidden global i64 16, section "__DATA, __objc_ivar", align 8
 // CHECK: @"OBJC_IVAR_$_I5._iv7_synth" = hidden global i64 20, section "__DATA, __objc_ivar", align 8
 // CHECK: @"OBJC_IVAR_$_I5._iv5" = global i64 14, section "__DATA, __objc_ivar", align 8
-// CHECK: _OBJC_CLASS_RO_$_I5" = internal global {{.*}} { i32 0, i32 14, i32 24, {{.*}}
+// CHECK: _OBJC_CLASS_RO_$_I5" = private global {{.*}} { i32 0, i32 14, i32 24, {{.*}}
 // CHECK: @"OBJC_IVAR_$_I6.iv0" = global i64 0, section "__DATA, __objc_ivar", align 8
-// CHECK: _OBJC_CLASS_RO_$_I6" = internal global {{.*}} { i32 2, i32 0, i32 1, {{.*}}
+// CHECK: _OBJC_CLASS_RO_$_I6" = private global {{.*}} { i32 2, i32 0, i32 1, {{.*}}
 // CHECK: @"OBJC_IVAR_$_I8.b" = global i64 8, section "__DATA, __objc_ivar", align 8
-// CHECK: _OBJC_CLASS_RO_$_I8" = internal global {{.*}} { i32 0, i32 8, i32 16, {{.*}}
+// CHECK: _OBJC_CLASS_RO_$_I8" = private global {{.*}} { i32 0, i32 8, i32 16, {{.*}}
 // CHECK: @"OBJC_IVAR_$_I9.iv0" = global i64 0, section "__DATA, __objc_ivar", align 8
-// CHECK: _OBJC_CLASS_RO_$_I9" = internal global {{.*}} { i32 2, i32 0, i32 4, {{.*}}
+// CHECK: _OBJC_CLASS_RO_$_I9" = private global {{.*}} { i32 2, i32 0, i32 4, {{.*}}
 // CHECK: @"OBJC_IVAR_$_I10.iv1" = global i64 4, section "__DATA, __objc_ivar", align 8
-// CHECK: _OBJC_CLASS_RO_$_I10" = internal global {{.*}} { i32 0, i32 4, i32 5, {{.*}}
-// CHECK: _OBJC_CLASS_RO_$_I11" = internal global {{.*}} { i32 0, i32 5, i32 5, {{.*}}
+// CHECK: _OBJC_CLASS_RO_$_I10" = private global {{.*}} { i32 0, i32 4, i32 5, {{.*}}
+// CHECK: _OBJC_CLASS_RO_$_I11" = private global {{.*}} { i32 0, i32 5, i32 5, {{.*}}
 // CHECK: @"OBJC_IVAR_$_I12.iv2" = global i64 8, section "__DATA, __objc_ivar", align 8
-// CHECK: _OBJC_CLASS_RO_$_I12" = internal global {{.*}} { i32 0, i32 8, i32 12, {{.*}}
+// CHECK: _OBJC_CLASS_RO_$_I12" = private global {{.*}} { i32 0, i32 8, i32 12, {{.*}}
 
 /*
   Compare to:
diff --git a/test/CodeGenObjC/ivar-base-as-invariant-load.m b/test/CodeGenObjC/ivar-base-as-invariant-load.m
index 19dc658..061fea3 100644
--- a/test/CodeGenObjC/ivar-base-as-invariant-load.m
+++ b/test/CodeGenObjC/ivar-base-as-invariant-load.m
@@ -23,7 +23,7 @@
 
 @end
 
-// CHECK: [[T1:%.*]] = load i64* @"OBJC_IVAR_$_A._flags", !invariant.load !5
-// CHECK: [[T2:%.*]] = load i64* @"OBJC_IVAR_$_A._flags", !invariant.load !5
-// CHECK: [[T3:%.*]] = load i64* @"OBJC_IVAR_$_A._flags", !invariant.load !5
-
+// CHECK: [[T1:%.*]] = load i64* @"OBJC_IVAR_$_A._flags", !invariant.load ![[MD_NUM:[0-9]+]]
+// CHECK: [[T2:%.*]] = load i64* @"OBJC_IVAR_$_A._flags", !invariant.load ![[MD_NUM]]
+// CHECK: [[T3:%.*]] = load i64* @"OBJC_IVAR_$_A._flags", !invariant.load ![[MD_NUM]]
+//
diff --git a/test/CodeGenObjC/ivar-layout-64.m b/test/CodeGenObjC/ivar-layout-64.m
index 91a8375..068d109 100644
--- a/test/CodeGenObjC/ivar-layout-64.m
+++ b/test/CodeGenObjC/ivar-layout-64.m
@@ -33,9 +33,9 @@
 @property int p3;
 @end
 
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global {{.*}} c"C\00"
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global {{.*}} c"\11p\00"
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global {{.*}} c"!`\00"
+// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = private global {{.*}} c"C\00"
+// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = private global {{.*}} c"\11p\00"
+// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = private global {{.*}} c"!`\00"
 
 
 @implementation C
@@ -48,9 +48,9 @@
 @property (assign) __weak id p2;
 @end
 
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global {{.*}} c"A\00"
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global {{.*}} c"\11q\10\00"
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global {{.*}} c"!q\00"
+// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = private global {{.*}} c"A\00"
+// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = private global {{.*}} c"\11q\10\00"
+// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = private global {{.*}} c"!q\00"
 
 @implementation A
 @synthesize p0 = _p0;
@@ -62,9 +62,9 @@
 @property int p3;
 @end
 
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global {{.*}} c"D\00"
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global {{.*}} c"\11p\00"
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global {{.*}} c"!`\00"
+// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = private global {{.*}} c"D\00"
+// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = private global {{.*}} c"\11p\00"
+// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = private global {{.*}} c"!`\00"
 
 @implementation D
 @synthesize p3 = _p3;
@@ -89,8 +89,8 @@
 }
 @end
 
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global {{.*}} c"NSFileLocationComponent\00"
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global {{.*}} c"\01\14\00"
+// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = private global {{.*}} c"NSFileLocationComponent\00"
+// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = private global {{.*}} c"\01\14\00"
 
 @implementation NSFileLocationComponent @end
 
@@ -108,7 +108,7 @@
 }
 @end
 
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global {{.*}} c"Foo\00"
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global {{.*}} c"\02\10\00"
+// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = private global {{.*}} c"Foo\00"
+// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = private global {{.*}} c"\02\10\00"
 
 @implementation Foo @end
diff --git a/test/CodeGenObjC/ivar-layout-array0-struct.m b/test/CodeGenObjC/ivar-layout-array0-struct.m
index 4737303..8e27710 100644
--- a/test/CodeGenObjC/ivar-layout-array0-struct.m
+++ b/test/CodeGenObjC/ivar-layout-array0-struct.m
@@ -1,4 +1,4 @@
-// REQUIRES: x86-64-registered-target
+// REQUIRES: x86-registered-target
 // RUN: %clang_cc1 -fobjc-gc -triple x86_64-apple-darwin -fobjc-runtime=macosx-fragile-10.5 -S %s -o %t-64.s
 // RUN: FileCheck -check-prefix CHECK-LP64 --input-file=%t-64.s %s
 
diff --git a/test/CodeGenObjC/ivar-layout-no-optimize.m b/test/CodeGenObjC/ivar-layout-no-optimize.m
index 17b5195..554038f 100644
--- a/test/CodeGenObjC/ivar-layout-no-optimize.m
+++ b/test/CodeGenObjC/ivar-layout-no-optimize.m
@@ -1,4 +1,4 @@
-// REQUIRES: x86-64-registered-target
+// REQUIRES: x86-registered-target
 // RUN: %clang_cc1 -fobjc-gc -triple x86_64-apple-darwin -fobjc-runtime=macosx-fragile-10.5 -S %s -o %t-64.s
 // RUN: FileCheck -check-prefix CHECK-LP64 --input-file=%t-64.s %s
 // RUN: %clang_cc1 -x objective-c++ -fobjc-gc -triple x86_64-apple-darwin -fobjc-runtime=macosx-fragile-10.5 -S %s -o %t-64.s
diff --git a/test/CodeGenObjC/metadata-symbols-32.m b/test/CodeGenObjC/metadata-symbols-32.m
index fda909c..61279e1 100644
--- a/test/CodeGenObjC/metadata-symbols-32.m
+++ b/test/CodeGenObjC/metadata-symbols-32.m
@@ -2,31 +2,33 @@
 
 // CHECK: .lazy_reference .objc_class_name_J0
 
-// CHECK: @"\01L_OBJC_METH_VAR_NAME_{{[0-9]*}}" = internal global {{.*}}section "__TEXT,__cstring,cstring_literals", align 1
-// CHECK: @"\01L_OBJC_METH_VAR_TYPE_{{[0-9]*}}" = internal global {{.*}}section "__TEXT,__cstring,cstring_literals", align 1
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{[0-9]*}}" = internal global {{.*}}section "__TEXT,__cstring,cstring_literals", align 1
-// CHECK: @"\01L_OBJC_PROTOCOL_INSTANCE_METHODS_P" = internal global {{.*}}section "__OBJC,__cat_inst_meth,regular,no_dead_strip", align 4
-// CHECK: @"\01L_OBJC_PROTOCOL_CLASS_METHODS_P" = internal global {{.*}}section "__OBJC,__cat_cls_meth,regular,no_dead_strip", align 4
-// CHECK: @"\01L_OBJC_PROTOCOL_P" = internal global {{.*}}section "__OBJC,__protocol,regular,no_dead_strip", align 4
-// CHECK: @"\01L_OBJC_CLASS_PROTOCOLS_A" = internal global {{.*}}section "__OBJC,__cat_cls_meth,regular,no_dead_strip", align 4
-// CHECK: @"\01L_OBJC_CLASS_METHODS_A" = internal global {{.*}}section "__OBJC,__cls_meth,regular,no_dead_strip", align 4
-// CHECK: @"\01L_OBJC_METACLASS_A" = internal global {{.*}}section "__OBJC,__meta_class,regular,no_dead_strip", align 4
-// CHECK: @"\01L_OBJC_INSTANCE_VARIABLES_A" = internal global {{.*}}section "__OBJC,__instance_vars,regular,no_dead_strip", align 4
-// CHECK: @"\01L_OBJC_INSTANCE_METHODS_A" = internal global {{.*}}section "__OBJC,__inst_meth,regular,no_dead_strip", align 4
-// CHECK: @"\01L_OBJC_PROP_NAME_ATTR_{{[0-9]*}}" = internal global {{.*}}section "__TEXT,__cstring,cstring_literals", align 1
-// CHECK: @"\01l_OBJC_$_PROP_LIST_A" = internal global {{.*}}section "__OBJC,__property,regular,no_dead_strip", align 4
-// CHECK: @"\01L_OBJC_CLASSEXT_A" = internal global {{.*}}section "__OBJC,__class_ext,regular,no_dead_strip", align 4
-// CHECK: @"\01L_OBJC_CLASS_A" = internal global {{.*}}section "__OBJC,__class,regular,no_dead_strip", align 4
-// CHECK: @"\01L_OBJC_CATEGORY_INSTANCE_METHODS_A_Cat" = internal global {{.*}}section "__OBJC,__cat_inst_meth,regular,no_dead_strip", align 4
-// CHECK: @"\01L_OBJC_CATEGORY_CLASS_METHODS_A_Cat" = internal global {{.*}}section "__OBJC,__cat_cls_meth,regular,no_dead_strip", align 4
-// CHECK: @"\01L_OBJC_CATEGORY_A_Cat" = internal global {{.*}}section "__OBJC,__category,regular,no_dead_strip", align 4
-// CHECK: @"\01L_OBJC_CLASS_REFERENCES_{{[0-9]*}}" = internal global {{.*}}section "__OBJC,__cls_refs,literal_pointers,no_dead_strip", align 4
-// CHECK: @"\01L_OBJC_SELECTOR_REFERENCES_{{[0-9]*}}" = internal externally_initialized global {{.*}}section "__OBJC,__message_refs,literal_pointers,no_dead_strip", align 4
-// CHECK: @"\01L_OBJC_SYMBOLS" = internal global {{.*}}section "__OBJC,__symbols,regular,no_dead_strip", align 4
-// CHECK: @"\01L_OBJC_MODULES" = internal global {{.*}}section "__OBJC,__module_info,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_METH_VAR_NAME_{{[0-9]*}}" = private global {{.*}}section "__TEXT,__cstring,cstring_literals", align 1
+// CHECK: @"\01L_OBJC_METH_VAR_TYPE_{{[0-9]*}}" = private global {{.*}}section "__TEXT,__cstring,cstring_literals", align 1
+// CHECK: @"\01l_OBJC_PROTOCOLEXT_P" = private global
+// CHECK-NOT: section
+// CHECK: @"\01L_OBJC_CLASS_NAME_{{[0-9]*}}" = private global {{.*}}section "__TEXT,__cstring,cstring_literals", align 1
+// CHECK: @"\01L_OBJC_PROTOCOL_INSTANCE_METHODS_P" = private global {{.*}}section "__OBJC,__cat_inst_meth,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_PROTOCOL_CLASS_METHODS_P" = private global {{.*}}section "__OBJC,__cat_cls_meth,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_PROTOCOL_P" = private global {{.*}}section "__OBJC,__protocol,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_CLASS_PROTOCOLS_A" = private global {{.*}}section "__OBJC,__cat_cls_meth,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_CLASS_METHODS_A" = private global {{.*}}section "__OBJC,__cls_meth,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_METACLASS_A" = private global {{.*}}section "__OBJC,__meta_class,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_INSTANCE_VARIABLES_A" = private global {{.*}}section "__OBJC,__instance_vars,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_INSTANCE_METHODS_A" = private global {{.*}}section "__OBJC,__inst_meth,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_PROP_NAME_ATTR_{{[0-9]*}}" = private global {{.*}}section "__TEXT,__cstring,cstring_literals", align 1
+// CHECK: @"\01l_OBJC_$_PROP_LIST_A" = private global {{.*}}section "__OBJC,__property,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_CLASSEXT_A" = private global {{.*}}section "__OBJC,__class_ext,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_CLASS_A" = private global {{.*}}section "__OBJC,__class,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_CATEGORY_INSTANCE_METHODS_A_Cat" = private global {{.*}}section "__OBJC,__cat_inst_meth,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_CATEGORY_CLASS_METHODS_A_Cat" = private global {{.*}}section "__OBJC,__cat_cls_meth,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_CATEGORY_A_Cat" = private global {{.*}}section "__OBJC,__category,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_CLASS_REFERENCES_{{[0-9]*}}" = private global {{.*}}section "__OBJC,__cls_refs,literal_pointers,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_SELECTOR_REFERENCES_{{[0-9]*}}" = private externally_initialized global {{.*}}section "__OBJC,__message_refs,literal_pointers,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_SYMBOLS" = private global {{.*}}section "__OBJC,__symbols,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_MODULES" = private global {{.*}}section "__OBJC,__module_info,regular,no_dead_strip", align 4
 
 // Clang's Obj-C 32-bit doesn't emit ivars for the root class.
-// CHECKX: @"\01L_OBJC_CLASS_VARIABLES_A" = internal global {{.*}}section "__OBJC,__class_vars,regular,no_dead_strip", align 4
+// CHECKX: @"\01L_OBJC_CLASS_VARIABLES_A" = private global {{.*}}section "__OBJC,__class_vars,regular,no_dead_strip", align 4
 
 
 /*
diff --git a/test/CodeGenObjC/metadata-symbols-64.m b/test/CodeGenObjC/metadata-symbols-64.m
index a89fec5..7b96093 100644
--- a/test/CodeGenObjC/metadata-symbols-64.m
+++ b/test/CodeGenObjC/metadata-symbols-64.m
@@ -5,32 +5,32 @@
 // CHECK: @_objc_empty_vtable = external global
 // CHECK: @"OBJC_CLASS_$_A" = global
 // CHECK: @"OBJC_METACLASS_$_A" = global {{.*}} section "__DATA, __objc_data", align 8
-// CHECK: @"\01L_OBJC_CLASS_NAME_{{[0-9]*}}" = internal global {{.*}} section "__TEXT,__objc_classname,cstring_literals", align 1
-// CHECK: @"\01L_OBJC_METH_VAR_NAME_{{[0-9]*}}" = internal global {{.*}} section "__TEXT,__objc_methname,cstring_literals", align 1
-// CHECK: @"\01L_OBJC_METH_VAR_TYPE_{{[0-9]*}}" = internal global {{.*}} section "__TEXT,__objc_methtype,cstring_literals", align 1
-// CHECK: @"\01l_OBJC_$_CLASS_METHODS_A" = internal global {{.*}} section "__DATA, __objc_const", align 8
-// CHECK: @"\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_P" = internal global {{.*}} section "__DATA, __objc_const", align 8
-// CHECK: @"\01l_OBJC_$_PROTOCOL_CLASS_METHODS_P" = internal global {{.*}} section "__DATA, __objc_const", align 8
+// CHECK: @"\01L_OBJC_CLASS_NAME_{{[0-9]*}}" = private global {{.*}} section "__TEXT,__objc_classname,cstring_literals", align 1
+// CHECK: @"\01L_OBJC_METH_VAR_NAME_{{[0-9]*}}" = private global {{.*}} section "__TEXT,__objc_methname,cstring_literals", align 1
+// CHECK: @"\01L_OBJC_METH_VAR_TYPE_{{[0-9]*}}" = private global {{.*}} section "__TEXT,__objc_methtype,cstring_literals", align 1
+// CHECK: @"\01l_OBJC_$_CLASS_METHODS_A" = private global {{.*}} section "__DATA, __objc_const", align 8
+// CHECK: @"\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_P" = private global {{.*}} section "__DATA, __objc_const", align 8
+// CHECK: @"\01l_OBJC_$_PROTOCOL_CLASS_METHODS_P" = private global {{.*}} section "__DATA, __objc_const", align 8
 // CHECK: @"\01l_OBJC_PROTOCOL_$_P" = weak hidden global {{.*}} section "__DATA,__datacoal_nt,coalesced", align 8
 // CHECK: @"\01l_OBJC_LABEL_PROTOCOL_$_P" = weak hidden global {{.*}} section "__DATA, __objc_protolist, coalesced, no_dead_strip", align 8
-// CHECK: @"\01l_OBJC_CLASS_PROTOCOLS_$_A" = internal global {{.*}} section "__DATA, __objc_const", align 8
-// CHECK: @"\01l_OBJC_METACLASS_RO_$_A" = internal global {{.*}} section "__DATA, __objc_const", align 8
-// CHECK: @"\01l_OBJC_$_INSTANCE_METHODS_A" = internal global {{.*}} section "__DATA, __objc_const", align 8
-// CHECK: @"\01l_OBJC_$_INSTANCE_VARIABLES_A" = internal global {{.*}} section "__DATA, __objc_const", align 8
-// CHECK: @"\01L_OBJC_PROP_NAME_ATTR_{{[0-9]*}}" = internal global {{.*}} section "__TEXT,__cstring,cstring_literals", align 1
-// CHECK: @"\01l_OBJC_$_PROP_LIST_A" = internal global {{.*}} section "__DATA, __objc_const", align 8
-// CHECK: @"\01l_OBJC_CLASS_RO_$_A" = internal global {{.*}} section "__DATA, __objc_const", align 8
-// CHECK: @"\01l_OBJC_$_CATEGORY_INSTANCE_METHODS_A_$_Cat" = internal global {{.*}} section "__DATA, __objc_const", align 8
-// CHECK: @"\01l_OBJC_$_CATEGORY_CLASS_METHODS_A_$_Cat" = internal global {{.*}} section "__DATA, __objc_const", align 8
-// CHECK: @"\01l_OBJC_$_CATEGORY_A_$_Cat" = internal global {{.*}} section "__DATA, __objc_const", align 8
-// CHECK: @"\01L_OBJC_CLASSLIST_SUP_REFS_$_{{[0-9]*}}" = internal global {{.*}} section "__DATA, __objc_superrefs, regular, no_dead_strip", align 8
-// CHECK: @"\01L_OBJC_SELECTOR_REFERENCES_" = internal externally_initialized global {{.*}} section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
-// CHECK: @"\01L_OBJC_CLASSLIST_SUP_REFS_$_{{[0-9]*}}" = internal global {{.*}} section "__DATA, __objc_superrefs, regular, no_dead_strip", align 8
+// CHECK: @"\01l_OBJC_CLASS_PROTOCOLS_$_A" = private global {{.*}} section "__DATA, __objc_const", align 8
+// CHECK: @"\01l_OBJC_METACLASS_RO_$_A" = private global {{.*}} section "__DATA, __objc_const", align 8
+// CHECK: @"\01l_OBJC_$_INSTANCE_METHODS_A" = private global {{.*}} section "__DATA, __objc_const", align 8
+// CHECK: @"\01l_OBJC_$_INSTANCE_VARIABLES_A" = private global {{.*}} section "__DATA, __objc_const", align 8
+// CHECK: @"\01L_OBJC_PROP_NAME_ATTR_{{[0-9]*}}" = private global {{.*}} section "__TEXT,__cstring,cstring_literals", align 1
+// CHECK: @"\01l_OBJC_$_PROP_LIST_A" = private global {{.*}} section "__DATA, __objc_const", align 8
+// CHECK: @"\01l_OBJC_CLASS_RO_$_A" = private global {{.*}} section "__DATA, __objc_const", align 8
+// CHECK: @"\01l_OBJC_$_CATEGORY_INSTANCE_METHODS_A_$_Cat" = private global {{.*}} section "__DATA, __objc_const", align 8
+// CHECK: @"\01l_OBJC_$_CATEGORY_CLASS_METHODS_A_$_Cat" = private global {{.*}} section "__DATA, __objc_const", align 8
+// CHECK: @"\01l_OBJC_$_CATEGORY_A_$_Cat" = private global {{.*}} section "__DATA, __objc_const", align 8
+// CHECK: @"\01L_OBJC_CLASSLIST_SUP_REFS_$_{{[0-9]*}}" = private global {{.*}} section "__DATA, __objc_superrefs, regular, no_dead_strip", align 8
+// CHECK: @"\01L_OBJC_SELECTOR_REFERENCES_" = private externally_initialized global {{.*}} section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip"
+// CHECK: @"\01L_OBJC_CLASSLIST_SUP_REFS_$_{{[0-9]*}}" = private global {{.*}} section "__DATA, __objc_superrefs, regular, no_dead_strip", align 8
 // CHECK: @"OBJC_CLASS_$_B" = external global
-// CHECK: @"\01L_OBJC_CLASSLIST_REFERENCES_$_{{[0-9]*}}" = internal global {{.*}} section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8
+// CHECK: @"\01L_OBJC_CLASSLIST_REFERENCES_$_{{[0-9]*}}" = private global {{.*}} section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8
 // CHECK: @"\01l_objc_msgSend_fixup_alloc" = weak hidden global {{.*}} section "__DATA, __objc_msgrefs, coalesced", align 16
-// CHECK: @"\01L_OBJC_LABEL_CLASS_$" = internal global {{.*}} section "__DATA, __objc_classlist, regular, no_dead_strip", align 8
-// CHECK: @"\01L_OBJC_LABEL_CATEGORY_$" = internal global {{.*}} section "__DATA, __objc_catlist, regular, no_dead_strip", align 8
+// CHECK: @"\01L_OBJC_LABEL_CLASS_$" = private global {{.*}} section "__DATA, __objc_classlist, regular, no_dead_strip", align 8
+// CHECK: @"\01L_OBJC_LABEL_CATEGORY_$" = private global {{.*}} section "__DATA, __objc_catlist, regular, no_dead_strip", align 8
 // CHECK: @objc_msgSend_fpret(
 // CHECK: @objc_msgSend_fixup(
 
diff --git a/test/CodeGenObjC/metadata_symbols.m b/test/CodeGenObjC/metadata_symbols.m
index eedcf16..2b61c5d 100644
--- a/test/CodeGenObjC/metadata_symbols.m
+++ b/test/CodeGenObjC/metadata_symbols.m
@@ -14,7 +14,7 @@
 // CHECK-X86_64: @"OBJC_EHTYPE_$_EH1" = weak global {{.*}}, section "__DATA,__datacoal_nt,coalesced", align 8
 // CHECK-X86_64: @"OBJC_EHTYPE_$_EH2" = external global
 // CHECK-X86_64: @"OBJC_EHTYPE_$_EH3" = global {{.*}}, section "__DATA,__objc_const", align 8
-// CHECK-X86_64: @"\01L_OBJC_LABEL_CLASS_$" = internal global {{.*}}, section "__DATA, __objc_classlist, regular, no_dead_strip", align 8
+// CHECK-X86_64: @"\01L_OBJC_LABEL_CLASS_$" = private global {{.*}}, section "__DATA, __objc_classlist, regular, no_dead_strip", align 8
 // CHECK-X86_64: define internal void @"\01-[A im0]"
 // CHECK-X86_64: define internal void @"\01-[A(Cat) im1]"
 
@@ -38,7 +38,7 @@
 // CHECK-ARMV6: @"OBJC_EHTYPE_$_EH1" = weak global {{.*}}, section "__DATA,__datacoal_nt,coalesced", align 4
 // CHECK-ARMV6: @"OBJC_EHTYPE_$_EH2" = external global
 // CHECK-ARMV6: @"OBJC_EHTYPE_$_EH3" = global {{.*}}, section "__DATA,__objc_const", align 4
-// CHECK-ARMV6: @"\01L_OBJC_LABEL_CLASS_$" = internal global {{.*}}, section "__DATA, __objc_classlist, regular, no_dead_strip", align 4
+// CHECK-ARMV6: @"\01L_OBJC_LABEL_CLASS_$" = private global {{.*}}, section "__DATA, __objc_classlist, regular, no_dead_strip", align 4
 // CHECK-ARMV6: define internal void @"\01-[A im0]"
 // CHECK-ARMV6: define internal void @"\01-[A(Cat) im1]"
 
diff --git a/test/CodeGenObjC/no-vararg-messaging.m b/test/CodeGenObjC/no-vararg-messaging.m
index 3f9d934..0095209 100644
--- a/test/CodeGenObjC/no-vararg-messaging.m
+++ b/test/CodeGenObjC/no-vararg-messaging.m
@@ -1,4 +1,4 @@
-// REQUIRES: x86-64-registered-target
+// REQUIRES: x86-registered-target
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10  -S -o - %s | FileCheck %s
 // rdar://9048030
 
diff --git a/test/CodeGenObjC/non-lazy-classes.m b/test/CodeGenObjC/non-lazy-classes.m
index d95cb78..760ddad 100644
--- a/test/CodeGenObjC/non-lazy-classes.m
+++ b/test/CodeGenObjC/non-lazy-classes.m
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o %t %s
-// RUN: grep '@".01L_OBJC_LABEL_NONLAZY_CLASS_$" = internal global \[1 x .*\] .*@"OBJC_CLASS_$_A".*, section "__DATA, __objc_nlclslist, regular, no_dead_strip", align 8' %t
-// RUN: grep '@".01L_OBJC_LABEL_NONLAZY_CATEGORY_$" = internal global \[1 x .*\] .*@".01l_OBJC_$_CATEGORY_A_$_Cat".*, section "__DATA, __objc_nlcatlist, regular, no_dead_strip", align 8' %t
+// RUN: grep '@".01L_OBJC_LABEL_NONLAZY_CLASS_$" = private global \[1 x .*\] .*@"OBJC_CLASS_$_A".*, section "__DATA, __objc_nlclslist, regular, no_dead_strip", align 8' %t
+// RUN: grep '@".01L_OBJC_LABEL_NONLAZY_CATEGORY_$" = private global \[1 x .*\] .*@".01l_OBJC_$_CATEGORY_A_$_Cat".*, section "__DATA, __objc_nlcatlist, regular, no_dead_strip", align 8' %t
 
 @interface A @end
 @implementation A
diff --git a/test/CodeGenObjC/objc-align.m b/test/CodeGenObjC/objc-align.m
index 1a96f34..2b2133e 100644
--- a/test/CodeGenObjC/objc-align.m
+++ b/test/CodeGenObjC/objc-align.m
@@ -1,14 +1,14 @@
 // 32-bit
 
 // RUN: %clang_cc1 -triple i386-apple-darwin9 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - %s | FileCheck %s
-// CHECK: @"\01L_OBJC_METACLASS_A" = internal global {{.*}}, section "__OBJC,__meta_class,regular,no_dead_strip", align 4
-// CHECK: @"\01L_OBJC_CLASS_A" = internal global {{.*}}, section "__OBJC,__class,regular,no_dead_strip", align 4
-// CHECK: @"\01L_OBJC_CATEGORY_A_Cat" = internal global {{.*}}, section "__OBJC,__category,regular,no_dead_strip", align 4
-// CHECK: @"\01L_OBJC_PROTOCOL_P" = internal global {{.*}}, section "__OBJC,__protocol,regular,no_dead_strip", align 4
-// CHECK: @"\01L_OBJC_CLASS_PROTOCOLS_C" = internal global {{.*}}, section "__OBJC,__cat_cls_meth,regular,no_dead_strip", align 4
-// CHECK: @"\01L_OBJC_METACLASS_C" = internal global {{.*}}, section "__OBJC,__meta_class,regular,no_dead_strip", align 4
-// CHECK: @"\01L_OBJC_CLASS_C" = internal global {{.*}}, section "__OBJC,__class,regular,no_dead_strip", align 4
-// CHECK: @"\01L_OBJC_MODULES" = internal global {{.*}}, section "__OBJC,__module_info,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_METACLASS_A" = private global {{.*}}, section "__OBJC,__meta_class,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_CLASS_A" = private global {{.*}}, section "__OBJC,__class,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_CATEGORY_A_Cat" = private global {{.*}}, section "__OBJC,__category,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_PROTOCOL_P" = private global {{.*}}, section "__OBJC,__protocol,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_CLASS_PROTOCOLS_C" = private global {{.*}}, section "__OBJC,__cat_cls_meth,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_METACLASS_C" = private global {{.*}}, section "__OBJC,__meta_class,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_CLASS_C" = private global {{.*}}, section "__OBJC,__class,regular,no_dead_strip", align 4
+// CHECK: @"\01L_OBJC_MODULES" = private global {{.*}}, section "__OBJC,__module_info,regular,no_dead_strip", align 4
 
 // 64-bit
 
@@ -17,16 +17,16 @@
 // RUNX: grep '@"OBJC_CLASS_$_C" = global' %t &&
 // RUNX: grep '@"OBJC_METACLASS_$_A" = global' %t &&
 // RUNX: grep '@"OBJC_METACLASS_$_C" = global' %t &&
-// RUNX: grep '@"\\01L_OBJC_CLASSLIST_REFERENCES_$_0" = internal global .*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8' %t &&
-// RUNX: grep '@"\\01L_OBJC_LABEL_CATEGORY_$" = internal global .*, section "__DATA, __objc_catlist, regular, no_dead_strip", align 8' %t &&
-// RUNX: grep '@"\\01L_OBJC_LABEL_CLASS_$" = internal global .*, section "__DATA, __objc_classlist, regular, no_dead_strip", align 8' %t &&
-// RUNX: grep '@"\\01l_OBJC_$_CATEGORY_A_$_Cat" = internal global .*, section "__DATA, __objc_const", align 8' %t &&
-// RUNX: grep '@"\\01l_OBJC_CLASS_PROTOCOLS_$_C" = internal global .*, section "__DATA, __objc_const", align 8' %t &&
-// RUNX: grep '@"\\01l_OBJC_CLASS_RO_$_A" = internal global .*, section "__DATA, __objc_const", align 8' %t &&
-// RUNX: grep '@"\\01l_OBJC_CLASS_RO_$_C" = internal global .*, section "__DATA, __objc_const", align 8' %t &&
+// RUNX: grep '@"\\01L_OBJC_CLASSLIST_REFERENCES_$_0" = private global .*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8' %t &&
+// RUNX: grep '@"\\01L_OBJC_LABEL_CATEGORY_$" = private global .*, section "__DATA, __objc_catlist, regular, no_dead_strip", align 8' %t &&
+// RUNX: grep '@"\\01L_OBJC_LABEL_CLASS_$" = private global .*, section "__DATA, __objc_classlist, regular, no_dead_strip", align 8' %t &&
+// RUNX: grep '@"\\01l_OBJC_$_CATEGORY_A_$_Cat" = private global .*, section "__DATA, __objc_const", align 8' %t &&
+// RUNX: grep '@"\\01l_OBJC_CLASS_PROTOCOLS_$_C" = private global .*, section "__DATA, __objc_const", align 8' %t &&
+// RUNX: grep '@"\\01l_OBJC_CLASS_RO_$_A" = private global .*, section "__DATA, __objc_const", align 8' %t &&
+// RUNX: grep '@"\\01l_OBJC_CLASS_RO_$_C" = private global .*, section "__DATA, __objc_const", align 8' %t &&
 // RUNX: grep '@"\\01l_OBJC_LABEL_PROTOCOL_$_P" = weak hidden global .*, section "__DATA, __objc_protolist, coalesced, no_dead_strip", align 8' %t &&
-// RUNX: grep '@"\\01l_OBJC_METACLASS_RO_$_A" = internal global .*, section "__DATA, __objc_const", align 8' %t &&
-// RUNX: grep '@"\\01l_OBJC_METACLASS_RO_$_C" = internal global .*, section "__DATA, __objc_const", align 8' %t &&
+// RUNX: grep '@"\\01l_OBJC_METACLASS_RO_$_A" = private global .*, section "__DATA, __objc_const", align 8' %t &&
+// RUNX: grep '@"\\01l_OBJC_METACLASS_RO_$_C" = private global .*, section "__DATA, __objc_const", align 8' %t &&
 // RUNX: grep '@"\\01l_OBJC_PROTOCOL_$_P" = weak hidden global .*, section "__DATA,__datacoal_nt,coalesced", align 8' %t &&
 
 
diff --git a/test/CodeGenObjC/objc-asm-attribute-neg-test.m b/test/CodeGenObjC/objc-asm-attribute-neg-test.m
new file mode 100644
index 0000000..e9bef4c
--- /dev/null
+++ b/test/CodeGenObjC/objc-asm-attribute-neg-test.m
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1  -fsyntax-only -verify -Wno-objc-root-class %s
+// rdar://16462586
+
+__attribute__((objc_runtime_name("MySecretNamespace.Protocol")))
+@protocol Protocol
+@end
+
+__attribute__((objc_runtime_name("MySecretNamespace.Message")))
+@interface Message <Protocol> { 
+__attribute__((objc_runtime_name("MySecretNamespace.Message"))) // expected-error {{'objc_runtime_name' attribute only applies to interface or protocol declarations}}
+  id MyIVAR;
+}
+__attribute__((objc_runtime_name("MySecretNamespace.Message")))
+@property int MyProperty; // expected-error {{prefix attribute must be followed by an interface or protocol}}}}
+
+- (int) getMyProperty __attribute__((objc_runtime_name("MySecretNamespace.Message"))); // expected-error {{'objc_runtime_name' attribute only applies to interface or protocol declarations}}
+
+- (void) setMyProperty : (int) arg __attribute__((objc_runtime_name("MySecretNamespace.Message"))); // expected-error {{'objc_runtime_name' attribute only applies to interface or protocol declarations}}
+
+@end
+
+__attribute__((objc_runtime_name("MySecretNamespace.ForwardClass")))
+@class ForwardClass; // expected-error {{prefix attribute must be followed by an interface or protocol}}
+
+__attribute__((objc_runtime_name("MySecretNamespace.ForwardProtocol")))
+@protocol ForwardProtocol;
+
+__attribute__((objc_runtime_name("MySecretNamespace.Message")))
+@implementation Message // expected-error {{prefix attribute must be followed by an interface or protocol}}
+__attribute__((objc_runtime_name("MySecretNamespace.Message")))
+- (id) MyMethod {
+  return MyIVAR;
+}
+@end
diff --git a/test/CodeGenObjC/objc-asm-attribute-test.m b/test/CodeGenObjC/objc-asm-attribute-test.m
new file mode 100644
index 0000000..12903b52
--- /dev/null
+++ b/test/CodeGenObjC/objc-asm-attribute-test.m
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin %s -o - | FileCheck %s
+// rdar://16462586
+
+__attribute__((objc_runtime_name("MySecretNamespace.Protocol")))
+@protocol Protocol
+- (void) MethodP;
++ (void) ClsMethodP;
+@end
+
+__attribute__((objc_runtime_name("MySecretNamespace.Protocol2")))
+@protocol Protocol2
+- (void) MethodP2;
++ (void) ClsMethodP2;
+@end
+
+__attribute__((objc_runtime_name("MySecretNamespace.Message")))
+@interface Message <Protocol, Protocol2> {
+  id MyIVAR;
+}
+@end
+
+@implementation Message
+- (id) MyMethod {
+  return MyIVAR;
+}
+
++ (id) MyClsMethod {
+  return 0;
+}
+
+- (void) MethodP{}
+- (void) MethodP2{}
+
++ (void) ClsMethodP {}
++ (void) ClsMethodP2 {}
+@end
+
+// rdar://16877359
+__attribute__((objc_runtime_name("foo")))
+@interface SLREarth
+- (instancetype)init;
++ (instancetype)alloc;
+@end
+
+id Test16877359() {
+    return [SLREarth alloc];
+}
+
+// CHECK: @"OBJC_IVAR_$_MySecretNamespace.Message.MyIVAR" = global i64
+// CHECK: @"OBJC_CLASS_$_MySecretNamespace.Message" = global %struct._class_t
+// CHECK: @"OBJC_METACLASS_$_MySecretNamespace.Message" = global %struct._class_t
+// CHECK: @"OBJC_CLASS_$_foo" = external global %struct._class_t
+// CHECK: define internal i8* @"\01-[Message MyMethod]"
+// CHECK: [[IVAR:%.*]] = load i64* @"OBJC_IVAR_$_MySecretNamespace.Message.MyIVAR"
diff --git a/test/CodeGenObjC/objc-read-weak-byref.m b/test/CodeGenObjC/objc-read-weak-byref.m
index 35b4de1..228f477 100644
--- a/test/CodeGenObjC/objc-read-weak-byref.m
+++ b/test/CodeGenObjC/objc-read-weak-byref.m
@@ -1,8 +1,7 @@
-// REQUIRES: x86-registered-target,x86-64-registered-target
-// RUN: %clang_cc1 -fblocks -fobjc-gc -triple x86_64-apple-darwin -fobjc-runtime=macosx-fragile-10.5 -S %s -o %t-64.s
-// RUN: FileCheck -check-prefix CHECK-LP64 --input-file=%t-64.s %s
-// RUN: %clang_cc1 -fblocks -fobjc-gc -triple i386-apple-darwin -fobjc-runtime=macosx-fragile-10.5 -S %s -o %t-32.s
-// RUN: FileCheck -check-prefix CHECK-LP32 --input-file=%t-32.s %s
+// RUN: %clang_cc1 -fblocks -fobjc-gc -triple x86_64-apple-darwin -fobjc-runtime=macosx-fragile-10.5 -emit-llvm %s -o - | \
+// RUN: FileCheck %s
+// RUN: %clang_cc1 -fblocks -fobjc-gc -triple i386-apple-darwin -fobjc-runtime=macosx-fragile-10.5 -emit-llvm %s -o - | \
+// RUN: FileCheck %s
 
 @interface NSObject 
 - copy;
@@ -19,8 +18,5 @@
     return 0;
 }
 
-// CHECK-LP64: callq    _objc_read_weak
-// CHECK-LP64: callq    _objc_read_weak
-
-// CHECK-LP32: calll     L_objc_read_weak
-// CHECK-LP32: calll     L_objc_read_weak
+// CHECK: call i8* @objc_read_weak
+// CHECK: call i8* @objc_read_weak
diff --git a/test/CodeGenObjC/objc2-weak-block-call.m b/test/CodeGenObjC/objc2-weak-block-call.m
index 7c68817..e13cc7d 100644
--- a/test/CodeGenObjC/objc2-weak-block-call.m
+++ b/test/CodeGenObjC/objc2-weak-block-call.m
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -fblocks -fobjc-gc -triple x86_64-apple-darwin -fobjc-runtime=macosx-fragile-10.5 -emit-llvm %s -o - | FileCheck -check-prefix CHECK-LP64 %s
-// RUN: %clang_cc1 -fblocks -fobjc-gc -triple i386-apple-darwin -fobjc-runtime=macosx-fragile-10.5 -emit-llvm %s -o - | FileCheck -check-prefix CHECK-LP64 %s
+// RUN: %clang_cc1 -fblocks -fobjc-gc -triple i386-apple-darwin -fobjc-runtime=macosx-fragile-10.5 -emit-llvm %s -o - | FileCheck -check-prefix CHECK-LP32 %s
 
 @interface MyView
 - (void)MyView_sharedInit;
diff --git a/test/CodeGenObjC/objc2-weak-import-attribute.m b/test/CodeGenObjC/objc2-weak-import-attribute.m
index 201e24b..6ee5746 100644
--- a/test/CodeGenObjC/objc2-weak-import-attribute.m
+++ b/test/CodeGenObjC/objc2-weak-import-attribute.m
@@ -45,4 +45,4 @@
 
 @implementation Root @end
 
-// CHECK-NOT-X86-64: OBJC_METACLASS_$_Root" = extern_weak global
+// CHECK-X86-64-NOT: OBJC_METACLASS_$_Root" = extern_weak global
diff --git a/test/CodeGenObjC/optimize-ivar-offset-load.m b/test/CodeGenObjC/optimize-ivar-offset-load.m
new file mode 100644
index 0000000..d34ac13
--- /dev/null
+++ b/test/CodeGenObjC/optimize-ivar-offset-load.m
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10  -Os -emit-llvm %s -o -  | FileCheck %s
+// rdar://16095748
+
+@interface NSObject 
+@end
+
+@interface SampleClass : NSObject {
+    @public
+    int _value;
+}
++ (SampleClass*) new;
+@end
+
+@interface AppDelegate  : NSObject
+@end
+
+extern void foo(int);
+
+@implementation AppDelegate
+- (void)application
+{
+    // Create set of objects in loop
+    for(int i = 0; i < 2; i++) {
+        SampleClass *sample = [SampleClass new];
+        foo (sample->_value);
+    }
+}
+@end
+// CHECK: [[IVAR:%.*]]  = load i64* @"OBJC_IVAR_$_SampleClass._value", align 8
+// CHECK: [[THREE:%.*]] = bitcast [[ONE:%.*]]* [[CALL:%.*]] to i8*
+// CHECK: [[ADDPTR:%.*]] = getelementptr inbounds i8* [[THREE]], i64 [[IVAR]]
+// CHECK: [[FOUR:%.*]] = bitcast i8* [[ADDPTR]] to i32*
+// CHECK: [[FIVE:%.*]] = load i32* [[FOUR]], align 4
+// CHECK:   tail call void @foo(i32 [[FIVE]])
+
+@implementation SampleClass
++ (SampleClass*) new { return 0; }
+- (void) SampleClassApplication
+{
+    // Create set of objects in loop
+    for(int i = 0; i < 2; i++) {
+        SampleClass *sample = [SampleClass new];
+        foo (sample->_value);
+    }
+}
+@end
+// CHECK: [[ZERO:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8, !invariant.load
+// CHECK: [[IVAR:%.*]] = load i64* @"OBJC_IVAR_$_SampleClass._value", align 8, !invariant.load
+
+@interface Sample : SampleClass @end
+
+@implementation Sample
+- (void) SampleApplication
+{
+    // Create set of objects in loop
+    for(int i = 0; i < 2; i++) {
+        SampleClass *sample = [SampleClass new];
+        foo (sample->_value);
+    }
+}
+@end
+// CHECK: [[ZERO:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8, !invariant.load 
+// CHECK: [[IVAR:%.*]] = load i64* @"OBJC_IVAR_$_SampleClass._value", align 8, !invariant.load
+
diff --git a/test/CodeGenObjC/overloadable.m b/test/CodeGenObjC/overloadable.m
index 4fd1429..0d55cd3 100644
--- a/test/CodeGenObjC/overloadable.m
+++ b/test/CodeGenObjC/overloadable.m
@@ -1,10 +1,12 @@
 // rdar://6657613
-// RUN: %clang_cc1 -emit-llvm %s -o %t
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
 
 @class C;
 
-// RUN: grep _Z1fP11objc_object %t | count 1
+// CHECK: _Z1fP11objc_object
+// CHECK-NOT: _Z1fP11objc_object
 void __attribute__((overloadable)) f(id c) { }
 
-// RUN: grep _Z1fP1C %t | count 1
+// CHECK: _Z1fP1C
+// CHECK-NOT: _Z1fP1C
 void __attribute__((overloadable)) f(C *c) { }
diff --git a/test/CodeGenObjC/property-array-type.m b/test/CodeGenObjC/property-array-type.m
new file mode 100644
index 0000000..6600fd0
--- /dev/null
+++ b/test/CodeGenObjC/property-array-type.m
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10  -emit-llvm -o - %s | FileCheck %s
+// rdar://15610943
+
+struct _GLKMatrix4
+{
+    float m[16];
+};
+typedef struct _GLKMatrix4 GLKMatrix4;
+
+@interface NSObject @end
+
+@interface MyProgram
+- (void)setTransform:(float[16])transform;
+@end
+
+@interface ViewController
+@property (nonatomic, assign) GLKMatrix4 transform;
+@end
+
+@implementation ViewController
+- (void)viewDidLoad {
+  MyProgram *program;
+  program.transform = self.transform.m;
+}
+@end
+
+// CHECK: [[M:%.*]] = getelementptr inbounds %struct._GLKMatrix4* [[TMP:%.*]], i32 0, i32 0
+// CHECK: [[ARRAYDECAY:%.*]] = getelementptr inbounds [16 x float]* [[M]], i32 0, i32 0
+// CHECK: [[SIX:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES
+// CHECK:  call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, float*)*)(i8* [[SEVEN:%.*]], i8* [[SIX]], float* [[ARRAYDECAY]])
diff --git a/test/CodeGenObjC/property-category-impl.m b/test/CodeGenObjC/property-category-impl.m
index 734f9a3..765f1ad 100644
--- a/test/CodeGenObjC/property-category-impl.m
+++ b/test/CodeGenObjC/property-category-impl.m
@@ -15,6 +15,6 @@
 @end
 
 
-// CHECK: l_OBJC_$_PROP_LIST_Foo_$_Category" = internal global
-// CHECK: l_OBJC_$_CATEGORY_Foo_$_Category" = internal global
+// CHECK: l_OBJC_$_PROP_LIST_Foo_$_Category" = private global
+// CHECK: l_OBJC_$_CATEGORY_Foo_$_Category" = private global
 // CHECK: l_OBJC_$_PROP_LIST_Foo_$_Category
diff --git a/test/CodeGenObjC/property-dbg.m b/test/CodeGenObjC/property-dbg.m
index 42ab611..e0cac98 100644
--- a/test/CodeGenObjC/property-dbg.m
+++ b/test/CodeGenObjC/property-dbg.m
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -S -g -masm-verbose -x objective-c < %s | grep DW_AT_name
+// FIXME: Check IR rather than asm, then triple is not needed.
+// RUN: %clang_cc1 -triple %itanium_abi_triple -S -g -masm-verbose -x objective-c < %s | grep DW_AT_name
 @interface Foo {
   int i;
 }
diff --git a/test/CodeGenObjC/property-list-in-class.m b/test/CodeGenObjC/property-list-in-class.m
index e801485..2f92ca7 100644
--- a/test/CodeGenObjC/property-list-in-class.m
+++ b/test/CodeGenObjC/property-list-in-class.m
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s
-// CHECK: l_OBJC_$_PROP_LIST_C2" = internal global { i32, i32, [3 x %struct._prop_t] } { i32 16, i32 3
+// CHECK: l_OBJC_$_PROP_LIST_C2" = private global { i32, i32, [3 x %struct._prop_t] } { i32 16, i32 3
 
 @protocol P 
 @property int i;
diff --git a/test/CodeGenObjC/property-section-attribute.m b/test/CodeGenObjC/property-section-attribute.m
new file mode 100644
index 0000000..5ba064c
--- /dev/null
+++ b/test/CodeGenObjC/property-section-attribute.m
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+// rdar://15450637.
+
+@interface NSObject @end
+
+@interface Foo : NSObject
+@property int p __attribute__((section("__TEXT,foo")));
+@end
+
+@implementation Foo @end
+
+// CHECK: define internal i32 @"\01-[Foo p]"({{.*}} section "__TEXT,foo" {
+// CHECK: define internal void @"\01-[Foo setP:]"({{.*}} section "__TEXT,foo" {
diff --git a/test/CodeGenObjC/protocol-in-extended-class.m b/test/CodeGenObjC/protocol-in-extended-class.m
index a5fb80e..49b2901 100644
--- a/test/CodeGenObjC/protocol-in-extended-class.m
+++ b/test/CodeGenObjC/protocol-in-extended-class.m
@@ -1,4 +1,4 @@
-// REQUIRES: x86-registered-target,x86-64-registered-target
+// REQUIRES: x86-registered-target
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -S %s -o %t-64.s
 // RUN: FileCheck -check-prefix CHECK-LP64 --input-file=%t-64.s %s
 // RUN: %clang_cc1 -triple i386-apple-darwin -fobjc-runtime=macosx-fragile-10.5 -S %s -o %t-32.s
diff --git a/test/CodeGenObjC/reorder-synthesized-ivars.m b/test/CodeGenObjC/reorder-synthesized-ivars.m
index 0f8cf6a..8faafff 100644
--- a/test/CodeGenObjC/reorder-synthesized-ivars.m
+++ b/test/CodeGenObjC/reorder-synthesized-ivars.m
@@ -38,21 +38,21 @@
 }
 @end
 
-// CHECK: @"{{.*}}" = internal global [10 x i8] c"_boolean1
-// CHECK-NEXT: @"{{.*}}" = internal global [10 x i8] c"_boolean2
-// CHECK-NEXT: @"{{.*}}" = internal global [10 x i8] c"_boolean3
-// CHECK-NEXT: @"{{.*}}" = internal global [10 x i8] c"_boolean4
-// CHECK-NEXT: @"{{.*}}" = internal global [10 x i8] c"_boolean5
-// CHECK-NEXT: @"{{.*}}" = internal global [10 x i8] c"_boolean6
-// CHECK-NEXT: @"{{.*}}" = internal global [10 x i8] c"_boolean7
-// CHECK-NEXT: @"{{.*}}" = internal global [10 x i8] c"_boolean8
-// CHECK-NEXT: @"{{.*}}" = internal global [10 x i8] c"_boolean9
-// CHECK-NEXT: @"{{.*}}" = internal global [9 x i8] c"_object1
-// CHECK-NEXT: @"{{.*}}" = internal global [9 x i8] c"_object2
-// CHECK-NEXT: @"{{.*}}" = internal global [9 x i8] c"_object3
-// CHECK-NEXT: @"{{.*}}" = internal global [9 x i8] c"_object4
-// CHECK-NEXT: @"{{.*}}" = internal global [9 x i8] c"_object5
-// CHECK-NEXT: @"{{.*}}" = internal global [9 x i8] c"_object6
-// CHECK-NEXT: @"{{.*}}" = internal global [9 x i8] c"_object7
-// CHECK-NEXT: @"{{.*}}" = internal global [9 x i8] c"_object8
-// CHECK-NEXT: @"{{.*}}" = internal global [9 x i8] c"_object9
+// CHECK: @"{{.*}}" = private global [10 x i8] c"_boolean1
+// CHECK-NEXT: @"{{.*}}" = private global [10 x i8] c"_boolean2
+// CHECK-NEXT: @"{{.*}}" = private global [10 x i8] c"_boolean3
+// CHECK-NEXT: @"{{.*}}" = private global [10 x i8] c"_boolean4
+// CHECK-NEXT: @"{{.*}}" = private global [10 x i8] c"_boolean5
+// CHECK-NEXT: @"{{.*}}" = private global [10 x i8] c"_boolean6
+// CHECK-NEXT: @"{{.*}}" = private global [10 x i8] c"_boolean7
+// CHECK-NEXT: @"{{.*}}" = private global [10 x i8] c"_boolean8
+// CHECK-NEXT: @"{{.*}}" = private global [10 x i8] c"_boolean9
+// CHECK-NEXT: @"{{.*}}" = private global [9 x i8] c"_object1
+// CHECK-NEXT: @"{{.*}}" = private global [9 x i8] c"_object2
+// CHECK-NEXT: @"{{.*}}" = private global [9 x i8] c"_object3
+// CHECK-NEXT: @"{{.*}}" = private global [9 x i8] c"_object4
+// CHECK-NEXT: @"{{.*}}" = private global [9 x i8] c"_object5
+// CHECK-NEXT: @"{{.*}}" = private global [9 x i8] c"_object6
+// CHECK-NEXT: @"{{.*}}" = private global [9 x i8] c"_object7
+// CHECK-NEXT: @"{{.*}}" = private global [9 x i8] c"_object8
+// CHECK-NEXT: @"{{.*}}" = private global [9 x i8] c"_object9
diff --git a/test/CodeGenObjC/return-objc-object.mm b/test/CodeGenObjC/return-objc-object.mm
index 95cce23..d756c4b 100644
--- a/test/CodeGenObjC/return-objc-object.mm
+++ b/test/CodeGenObjC/return-objc-object.mm
@@ -15,5 +15,5 @@
   f();
   f1();
 }
-// CHECK: call %0* @_Z1fv()
-// CHECK: call %0* @_Z2f1v()  
+// CHECK: call dereferenceable({{[0-9]+}}) %0* @_Z1fv()
+// CHECK: call dereferenceable({{[0-9]+}}) %0* @_Z2f1v()  
diff --git a/test/CodeGenObjC/stret-1.m b/test/CodeGenObjC/stret-1.m
new file mode 100644
index 0000000..f45d121
--- /dev/null
+++ b/test/CodeGenObjC/stret-1.m
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fblocks -triple arm64-apple-darwin %s -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-ARM64
+// rdar://12416433
+
+struct stret { int x[100]; };
+struct stret zero;
+struct stret one = {{1}};
+
+@interface Test  @end
+
+@implementation Test
++(struct stret) method { return one; }
+@end
+
+int main(int argc, const char **argv)
+{
+    struct stret st2 = one;
+    if (argc) st2 = [(id)(argc&~255) method];
+}
+
+// CHECK-ARM64: call void @llvm.memset.p0i8.i64(i8* [[T0:%.*]], i8 0, i64 400, i32 4, i1 false)
diff --git a/test/CodeGenObjC/stret.m b/test/CodeGenObjC/stret.m
new file mode 100644
index 0000000..beb6f30
--- /dev/null
+++ b/test/CodeGenObjC/stret.m
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin9 %s -emit-llvm -o - | FileCheck %s -check-prefix=X86
+// RUN: %clang_cc1 -fblocks -triple arm-apple-darwin %s -emit-llvm -o - | FileCheck %s -check-prefix=ARM
+// RUN: %clang_cc1 -fblocks -triple arm64-apple-darwin %s -emit-llvm -o - | FileCheck %s -check-prefix=ARM64
+
+// <rdar://problem/9757015>: Don't use 'stret' variants on ARM64.
+
+// X86: @main
+// X86: @objc_msgSend_stret
+
+// ARM: @main
+// ARM: @objc_msgSend_stret
+
+// ARM64:     @main
+// ARM64-NOT: @objc_msgSend_stret
+
+struct st { int i[1000]; };
+@interface Test
++(struct st)method;
+@end
+int main() {
+  [Test method];
+}
diff --git a/test/CodeGenObjC/try.m b/test/CodeGenObjC/try.m
index 56b8e64..4168cb2 100644
--- a/test/CodeGenObjC/try.m
+++ b/test/CodeGenObjC/try.m
@@ -1,4 +1,4 @@
-// REQUIRES: x86-registered-target,x86-64-registered-target
+// REQUIRES: x86-registered-target
 // RUN: %clang_cc1 %s -fobjc-exceptions -S -o - -triple=i686-apple-darwin9
 // RUN: %clang_cc1 %s -fobjc-exceptions -S -o - -triple=x86_64-apple-darwin9
 
diff --git a/test/CodeGenObjC/weak-metaclass-visibility.m b/test/CodeGenObjC/weak-metaclass-visibility.m
new file mode 100644
index 0000000..d174bdb
--- /dev/null
+++ b/test/CodeGenObjC/weak-metaclass-visibility.m
@@ -0,0 +1,60 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple armv7-apple-darwin10 -emit-llvm  -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-apple-ios -emit-llvm -o - %s | FileCheck %s
+// rdar://16206443
+
+@interface NSObject 
+- (void) finalize;
++ (void) class;
+@end
+
+__attribute__((availability(macosx,introduced=9876.5)))
+@interface MyClass : NSObject
++ (void)someClassMethod;
+- (void)someInstanceMethod;
+@end
+
+@implementation MyClass
++ (void)someClassMethod {
+}
+
+- (void)someInstanceMethod {
+    [MyClass someClassMethod];
+    [super finalize];
+}
+@end
+
+void kit()
+{
+    MyClass *wrapper = [MyClass alloc];
+}
+
+// CHECK: @"OBJC_CLASS_$_MyClass" = global %struct._class_t
+// CHECK: @"OBJC_METACLASS_$_NSObject" = external global %struct._class_t
+// CHECK: @"OBJC_METACLASS_$_MyClass" = global %struct._class_t
+// CHECK: @"OBJC_CLASS_$_NSObject" = external global %struct._class_t
+
+// rdar://16529125
+__attribute__((weak_import))
+@interface NSURLQueryItem : NSObject
+@end
+
+@implementation NSURLQueryItem (hax)
++(void)classmethod { [super class]; }
+@end
+
+// CHECK: @"OBJC_METACLASS_$_NSURLQueryItem" = extern_weak global
+// CHECK: @"OBJC_CLASS_$_NSURLQueryItem" = extern_weak global
+
+// rdar://17633301
+__attribute__((visibility("default"))) __attribute__((availability(ios,introduced=9876.5)))
+@interface AVScheduledAudioParameters @end
+
+@interface XXXX : AVScheduledAudioParameters
+@end
+
+@implementation AVScheduledAudioParameters @end
+@implementation XXXX @end
+
+// CHECK: @"OBJC_CLASS_$_AVScheduledAudioParameters" = global %struct._class_t
+// CHECK: @"OBJC_METACLASS_$_AVScheduledAudioParameters" = global %struct._class_t 
diff --git a/test/CodeGenObjCXX/arc-blocks.mm b/test/CodeGenObjCXX/arc-blocks.mm
index ebb9d21..2695b4d 100644
--- a/test/CodeGenObjCXX/arc-blocks.mm
+++ b/test/CodeGenObjCXX/arc-blocks.mm
@@ -2,7 +2,7 @@
 
 // CHECK: [[A:.*]] = type { i64, [10 x i8*] }
 
-// CHECK: [[LAYOUT0:@.*]] = internal global [3 x i8] c" 9\00"
+// CHECK: [[LAYOUT0:@.*]] = private global [3 x i8] c" 9\00"
 
 // rdar://13045269
 // If a __block variable requires extended layout information *and*
@@ -38,7 +38,7 @@
   // CHECK-NEXT: load
   // CHECK-NEXT: [[T2:%.*]] = bitcast i8* {{.*}} to [[BYREF_A]]*
   // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds [[BYREF_A]]* [[T2]], i32 0, i32 7
-  // CHECK-NEXT: call void @_ZN5test01AC1ERKS0_([[A]]* [[T1]], [[A]]* [[T3]])
+  // CHECK-NEXT: call void @_ZN5test01AC1ERKS0_([[A]]* [[T1]], [[A]]* dereferenceable({{[0-9]+}}) [[T3]])
   // CHECK-NEXT: ret void
 
   // CHECK:    define internal void [[DISPOSE_HELPER]](
diff --git a/test/CodeGenObjCXX/arc-cxx11-member-init.mm b/test/CodeGenObjCXX/arc-cxx11-member-init.mm
new file mode 100644
index 0000000..213e7a1
--- /dev/null
+++ b/test/CodeGenObjCXX/arc-cxx11-member-init.mm
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1  -triple x86_64-apple-darwin10 -fobjc-arc -std=c++11 -emit-llvm -o - %s | FileCheck %s
+// rdar://16299964
+  
+@interface NSObject
++ (id)new;
+@end
+
+@interface NSMutableDictionary : NSObject
+@end
+  
+class XClipboardDataSet
+{ 
+  NSMutableDictionary* mClipData = [NSMutableDictionary new];
+};
+  
+@interface AppDelegate @end
+
+@implementation AppDelegate
+- (void)applicationDidFinishLaunching
+{ 
+ XClipboardDataSet clip; 
+}
+@end
+
+// CHECK: [[mClipData:%.*]] = getelementptr inbounds %class.XClipboardDataSet* 
+// CHECK: [[ZERO:%.*]] = load %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_"
+// CHECK: [[ONE:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_"
+// CHECK: [[TWO:%.*]] = bitcast %struct._class_t* [[ZERO]] to i8*
+// CHECK: [[CALL:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* [[TWO]], i8* [[ONE]])
+// CHECK: [[THREE:%.*]] = bitcast i8* [[CALL]] to [[T:%.*]]*
+// CHECK: store [[T]]* [[THREE]], [[T]]** [[mClipData]], align 8
+
diff --git a/test/CodeGenObjCXX/arc-globals.mm b/test/CodeGenObjCXX/arc-globals.mm
index 84ea180..8ba3fb8 100644
--- a/test/CodeGenObjCXX/arc-globals.mm
+++ b/test/CodeGenObjCXX/arc-globals.mm
@@ -19,7 +19,7 @@
 // CHECK-NEXT: ret void
 id global_obj2 = getObject();
 
-// CHECK-LABEL: define internal void @_GLOBAL__I_a
+// CHECK-LABEL: define internal void @_GLOBAL__sub_I_arc_globals.mm
 // CHECK: call i8* @objc_autoreleasePoolPush()
 // CHECK-NEXT: call void @__cxx_global_var_init
 // CHECK-NEXT: call void @__cxx_global_var_init1
diff --git a/test/CodeGenObjCXX/arc-mangle.mm b/test/CodeGenObjCXX/arc-mangle.mm
index 10c4f68..b921a7f 100644
--- a/test/CodeGenObjCXX/arc-mangle.mm
+++ b/test/CodeGenObjCXX/arc-mangle.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fobjc-arc -fobjc-runtime-has-weak -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fobjc-arc -fobjc-runtime-has-weak -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
 
 // CHECK-LABEL: define void @_Z1fPU8__strongP11objc_object(i8**)
 void f(__strong id *) {}
diff --git a/test/CodeGenObjCXX/arc-move.mm b/test/CodeGenObjCXX/arc-move.mm
index 0a8286d..d7b9f55 100644
--- a/test/CodeGenObjCXX/arc-move.mm
+++ b/test/CodeGenObjCXX/arc-move.mm
@@ -33,7 +33,7 @@
 
 // CHECK-LABEL: define void @_Z12library_moveRU8__strongP11objc_objectS2_
 void library_move(__strong id &x, __strong id &y) {
-  // CHECK: call i8** @_Z4moveIRU8__strongP11objc_objectEON16remove_referenceIT_E4typeEOS5_
+  // CHECK: call dereferenceable({{[0-9]+}}) i8** @_Z4moveIRU8__strongP11objc_objectEON16remove_referenceIT_E4typeEOS5_
   // CHECK: load i8**
   // CHECK: store i8* null, i8**
   // CHECK: load i8***
@@ -46,7 +46,7 @@
 
 // CHECK-LABEL: define void @_Z12library_moveRU8__strongP11objc_object
 void library_move(__strong id &y) {
-  // CHECK: [[Y:%[a-zA-Z0-9]+]] = call i8** @_Z4moveIRU8__strongP11objc_objectEON16remove_referenceIT_E4typeEOS5_
+  // CHECK: [[Y:%[a-zA-Z0-9]+]] = call dereferenceable({{[0-9]+}}) i8** @_Z4moveIRU8__strongP11objc_objectEON16remove_referenceIT_E4typeEOS5_
   // Load the object
   // CHECK-NEXT: [[OBJ:%[a-zA-Z0-9]+]] = load i8** [[Y]]
   // Null out y
@@ -65,7 +65,7 @@
 // CHECK-LABEL: define void @_Z10const_moveRKU8__strongP11objc_object(
 void const_move(const __strong id &x) {
   // CHECK:      [[Y:%.*]] = alloca i8*,
-  // CHECK:      [[X:%.*]] = call i8** @_Z4moveIRKU8__strongP11objc_objectEON16remove_referenceIT_E4typeEOS5_(
+  // CHECK:      [[X:%.*]] = call dereferenceable({{[0-9]+}}) i8** @_Z4moveIRKU8__strongP11objc_objectEON16remove_referenceIT_E4typeEOS5_(
   // CHECK-NEXT: [[T0:%.*]] = load i8** [[X]]
   // CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[T0]])
   // CHECK-NEXT: store i8* [[T1]], i8** [[Y]]
diff --git a/test/CodeGenObjCXX/arc-special-member-functions.mm b/test/CodeGenObjCXX/arc-special-member-functions.mm
index 49077ff..8b002d5 100644
--- a/test/CodeGenObjCXX/arc-special-member-functions.mm
+++ b/test/CodeGenObjCXX/arc-special-member-functions.mm
@@ -91,7 +91,7 @@
 }
 
 // Implicitly-generated copy assignment operator for ObjCBlockMember
-// CHECK:    define linkonce_odr {{%.*}}* @_ZN15ObjCBlockMemberaSERKS_(
+// CHECK:    define linkonce_odr dereferenceable({{[0-9]+}}) {{%.*}}* @_ZN15ObjCBlockMemberaSERKS_(
 // CHECK:      [[T0:%.*]] = getelementptr inbounds [[T:%.*]]* {{%.*}}, i32 0, i32 0
 // CHECK-NEXT: [[T1:%.*]] = load i32 (i32)** [[T0]], align 8
 // CHECK-NEXT: [[T2:%.*]] = bitcast i32 (i32)* [[T1]] to i8*
diff --git a/test/CodeGenObjCXX/encode.mm b/test/CodeGenObjCXX/encode.mm
index 075d790..e0171ef 100644
--- a/test/CodeGenObjCXX/encode.mm
+++ b/test/CodeGenObjCXX/encode.mm
@@ -213,7 +213,7 @@
   dynamic_class dynamic_class_ivar;
 }
 @end
-// CHECK: internal global [41 x i8] c"{dynamic_class=\22_vptr$dynamic_class\22^^?}\00"
+// CHECK: private global [41 x i8] c"{dynamic_class=\22_vptr$dynamic_class\22^^?}\00"
 
 namespace PR17142 {
   struct A { virtual ~A(); };
diff --git a/test/CodeGenObjCXX/externally-initialized-selectors.mm b/test/CodeGenObjCXX/externally-initialized-selectors.mm
index 87a7c04..0b7c24e 100644
--- a/test/CodeGenObjCXX/externally-initialized-selectors.mm
+++ b/test/CodeGenObjCXX/externally-initialized-selectors.mm
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -cc1 -fobjc-runtime=macosx-fragile-10.5 -o - -emit-llvm %s | FileCheck %s
-// RUN: %clang_cc1 -cc1 -o - -emit-llvm %s | FileCheck %s
+// RUN: %clang_cc1 -fobjc-runtime=macosx-fragile-10.5 -o - -emit-llvm %s | FileCheck %s
+// RUN: %clang_cc1 -o - -emit-llvm %s | FileCheck %s
 
-// CHECK: @"\01L_OBJC_SELECTOR_REFERENCES_" = internal externally_initialized global
+// CHECK: @"\01L_OBJC_SELECTOR_REFERENCES_" = private externally_initialized global
 
 void test(id x) {
   [x doSomething];
diff --git a/test/CodeGenObjCXX/implicit-copy-assign-operator.mm b/test/CodeGenObjCXX/implicit-copy-assign-operator.mm
index 88837c1..01d8112 100644
--- a/test/CodeGenObjCXX/implicit-copy-assign-operator.mm
+++ b/test/CodeGenObjCXX/implicit-copy-assign-operator.mm
@@ -43,7 +43,7 @@
   d1 = d2;
 }
 
-// CHECK-OBJ-LABEL: define linkonce_odr %struct.D* @_ZN1DaSERS_
+// CHECK-OBJ-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.D* @_ZN1DaSERS_
 // CHECK-OBJ: {{call.*_ZN1AaSERS_}}
 // CHECK-OBJ: {{call.*_ZN1BaSERS_}}
 // CHECK-OBJ: {{call.*_ZN1CaSERKS_}}
diff --git a/test/CodeGenObjCXX/implicit-copy-constructor.mm b/test/CodeGenObjCXX/implicit-copy-constructor.mm
index 6dbd39e..6c56616 100644
--- a/test/CodeGenObjCXX/implicit-copy-constructor.mm
+++ b/test/CodeGenObjCXX/implicit-copy-constructor.mm
@@ -41,7 +41,7 @@
   D d2(d);
 }
 
-// CHECK-LABEL: define linkonce_odr void @_ZN1DC1ERS_(%struct.D* %this, %struct.D*) unnamed_addr
+// CHECK-LABEL: define linkonce_odr void @_ZN1DC1ERS_(%struct.D* %this, %struct.D* dereferenceable({{[0-9]+}})) unnamed_addr
 // CHECK: call void @_ZN1AC1Ev
 // CHECK: call void @_ZN1CC2ERS_1A
 // CHECK: call void @_ZN1AD1Ev
diff --git a/test/CodeGenObjCXX/lambda-expressions.mm b/test/CodeGenObjCXX/lambda-expressions.mm
index 2468eb1..435f805 100644
--- a/test/CodeGenObjCXX/lambda-expressions.mm
+++ b/test/CodeGenObjCXX/lambda-expressions.mm
@@ -4,8 +4,8 @@
 typedef int (^fp)();
 fp f() { auto x = []{ return 3; }; return x; }
 
-// MRC: @"\01L_OBJC_METH_VAR_NAME{{.*}}" = internal global [5 x i8] c"copy\00"
-// MRC: @"\01L_OBJC_METH_VAR_NAME{{.*}}" = internal global [12 x i8] c"autorelease\00"
+// MRC: @"\01L_OBJC_METH_VAR_NAME{{.*}}" = private global [5 x i8] c"copy\00"
+// MRC: @"\01L_OBJC_METH_VAR_NAME{{.*}}" = private global [12 x i8] c"autorelease\00"
 // MRC-LABEL: define i32 ()* @_Z1fv(
 // MRC-LABEL: define internal i32 ()* @"_ZZ1fvENK3$_0cvU13block_pointerFivEEv"
 // MRC: store i8* bitcast (i8** @_NSConcreteStackBlock to i8*)
diff --git a/test/CodeGenObjCXX/lvalue-reference-getter.mm b/test/CodeGenObjCXX/lvalue-reference-getter.mm
index 83d3b93..5205a7c 100644
--- a/test/CodeGenObjCXX/lvalue-reference-getter.mm
+++ b/test/CodeGenObjCXX/lvalue-reference-getter.mm
@@ -24,5 +24,5 @@
 // CHECK: [[SELF:%.*]] = alloca [[T6:%.*]]*, align
 // CHECK: [[T0:%.*]] = load {{.*}}* [[SELF]], align
 // CHECK: [[T1:%.*]] = load {{.*}}* @"\01L_OBJC_SELECTOR_REFERENCES_"
-// CHECK: [[C:%.*]] = call %struct.SetSection* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
-// CHECK: call i32* @_ZN10SetSection2atEi(%struct.SetSection* [[C]]
+// CHECK: [[C:%.*]] = call dereferenceable({{[0-9]+}}) %struct.SetSection* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
+// CHECK: call dereferenceable({{[0-9]+}}) i32* @_ZN10SetSection2atEi(%struct.SetSection* [[C]]
diff --git a/test/CodeGenObjCXX/message-reference.mm b/test/CodeGenObjCXX/message-reference.mm
index 0d1bbc7..6b341f8 100644
--- a/test/CodeGenObjCXX/message-reference.mm
+++ b/test/CodeGenObjCXX/message-reference.mm
@@ -15,6 +15,6 @@
 }
 @end
 
-// CHECK: [[T:%.*]] = call i32* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
+// CHECK: [[T:%.*]] = call dereferenceable({{[0-9]+}}) i32* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
 // CHECK: [[U:%.*]] = load i32* [[T]]
 // CHECK  [[V:%.*]] = icmp eq i32 [[U]], 0
diff --git a/test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm b/test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm
new file mode 100644
index 0000000..0b01b27
--- /dev/null
+++ b/test/CodeGenObjCXX/microsoft-abi-arc-param-order.mm
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -mconstructor-aliases -fobjc-arc -triple i686-pc-win32 -emit-llvm -o - %s | FileCheck %s
+
+struct A {
+  A();
+  A(const A &);
+  ~A();
+  int a;
+};
+
+// Verify that we destruct things from left to right in the MS C++ ABI: a, b, c, d.
+//
+// CHECK-LABEL: define void @"\01?test_arc_order@@YAXUA@@PAAAPAUobjc_object@@01@Z"
+// CHECK:                       (<{ %struct.A, i8*, %struct.A, i8* }>* inalloca)
+void test_arc_order(A a, id __attribute__((ns_consumed)) b , A c, id __attribute__((ns_consumed)) d) {
+  // CHECK: call x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %{{.*}})
+  // CHECK: call void @objc_storeStrong(i8** %{{.*}}, i8* null)
+  // CHECK: call x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %{{.*}})
+  // CHECK: call void @objc_storeStrong(i8** %{{.*}}, i8* null)
+  // CHECK: ret void
+}
diff --git a/test/CodeGenObjCXX/property-dot-reference.mm b/test/CodeGenObjCXX/property-dot-reference.mm
index be6742a..8f3b29d 100644
--- a/test/CodeGenObjCXX/property-dot-reference.mm
+++ b/test/CodeGenObjCXX/property-dot-reference.mm
@@ -11,7 +11,7 @@
 
 @implementation TNodeIconAndNameCell     
 - (const TFENode&) node {
-// CHECK: call %struct.TFENode* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
+// CHECK: call dereferenceable({{[0-9]+}}) %struct.TFENode* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
 // CHECK-NEXT: call void @_ZNK7TFENode6GetURLEv(%struct.TFENode* %{{.*}})
 	self.node.GetURL();
 }	// expected-warning {{control reaches end of non-void function}}
@@ -27,12 +27,12 @@
 - (const X&) target;
 @end
 void f1(A *a) {
-// CHECK: [[PRP:%.*]] = call %struct.X* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
-// CHECK-NEXT:call void @_Z2f0RK1X(%struct.X* [[PRP]])
+// CHECK: [[PRP:%.*]] = call dereferenceable({{[0-9]+}}) %struct.X* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
+// CHECK-NEXT:call void @_Z2f0RK1X(%struct.X* dereferenceable({{[0-9]+}}) [[PRP]])
   f0(a.target);
 
-// CHECK: [[MSG:%.*]] = call %struct.X* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
-// CHECK-NEXT:call void @_Z2f0RK1X(%struct.X* [[MSG]])
+// CHECK: [[MSG:%.*]] = call dereferenceable({{[0-9]+}}) %struct.X* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
+// CHECK-NEXT:call void @_Z2f0RK1X(%struct.X* dereferenceable({{[0-9]+}}) [[MSG]])
   f0([a target]);
 }
 
diff --git a/test/CodeGenObjCXX/property-lvalue-capture.mm b/test/CodeGenObjCXX/property-lvalue-capture.mm
new file mode 100644
index 0000000..690ffa9
--- /dev/null
+++ b/test/CodeGenObjCXX/property-lvalue-capture.mm
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+// rdar://15118128
+
+template <typename T> struct Quad2 {
+  Quad2() {}
+};
+
+typedef Quad2<double> Quad2d;
+
+@interface Root @end
+
+@interface PAGeometryFrame
+- (const Quad2d &)quad;
+- (void)setQuad:(const Quad2d &)quad;
+@end
+
+@interface PA2DScaleTransform  : Root
+@end
+
+@implementation PA2DScaleTransform
+- (void)transformFrame:(PAGeometryFrame *)frame {
+ PAGeometryFrame *result;
+ result.quad  = frame.quad;
+}
+@end
+
+// CHECK:   [[TWO:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", !invariant.load ![[MD_NUM:[0-9]+]]
+// CHECK:   [[THREE:%.*]] = bitcast [[ONET:%.*]]* [[ONE:%.*]] to i8*
+// CHECK:   [[CALL:%.*]] = call nonnull %struct.Quad2* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to %struct.Quad2* (i8*, i8*)*)(i8* [[THREE]], i8* [[TWO]])
+// CHECK:   [[FOUR:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_2", !invariant.load ![[MD_NUM]]
+// CHECK:   [[FIVE:%.*]] = bitcast [[ONET]]* [[ZERO:%.*]] to i8*
+// CHECK:   call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, %struct.Quad2*)*)(i8* [[FIVE]], i8* [[FOUR]], %struct.Quad2* nonnull [[CALL]])
+
+
+struct A {
+ void *ptr;
+ A();
+ A(const A &);
+ ~A();
+};
+
+@interface C
+- (void) setProp: (const A&) value;
+@end
+void test(C *c, const A &a) {
+ const A &result = c.prop = a;
+}
+
+// CHECK:   [[ONE1:%.*]] = load %struct.A** [[AADDR:%.*]], align 8
+// CHECK:   [[TWO1:%.*]] = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_5", !invariant.load ![[MD_NUM]]
+// CHECK:   [[THREE1:%.*]] = bitcast [[TWOT:%.*]]* [[ZERO1:%.*]] to i8*
+// CHECK:   call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, %struct.A*)*)(i8* [[THREE1]], i8* [[TWO1]], %struct.A* dereferenceable({{[0-9]+}}) [[ONE1]])
+// CHECK:   store %struct.A* [[ONE1]], %struct.A** [[RESULT:%.*]], align 8
diff --git a/test/CodeGenObjCXX/property-object-reference-2.mm b/test/CodeGenObjCXX/property-object-reference-2.mm
index 542967c..20949f7 100644
--- a/test/CodeGenObjCXX/property-object-reference-2.mm
+++ b/test/CodeGenObjCXX/property-object-reference-2.mm
@@ -33,7 +33,7 @@
 // CHECK: [[TWO:%.*]] = load %struct.TCPPObject** [[ADDR:%.*]], align 8
 // CHECK: [[THREE:%.*]] = load %struct.TCPPObject** [[ADDR1:%.*]], align 8
 // CHECK: [[CALL:%.*]] = call i32 @_Z7DEFAULTv()
-// CHECK:  call void @_ZN10TCPPObjectC1ERKS_i(%struct.TCPPObject* [[TWO]], %struct.TCPPObject* [[THREE]], i32 [[CALL]])
+// CHECK:  call void @_ZN10TCPPObjectC1ERKS_i(%struct.TCPPObject* [[TWO]], %struct.TCPPObject* dereferenceable({{[0-9]+}}) [[THREE]], i32 [[CALL]])
 // CHECK:  ret void
 
 // CHECK: define internal void @"\01-[MyDocument MyProperty]"(
@@ -46,7 +46,7 @@
 // CHECK-LABEL: define internal void @__assign_helper_atomic_property_(
 // CHECK: [[TWO:%.*]] = load %struct.TCPPObject** [[ADDR:%.*]], align 8
 // CHECK: [[THREE:%.*]] = load %struct.TCPPObject** [[ADDR1:%.*]], align 8
-// CHECK: [[CALL:%.*]] = call %struct.TCPPObject* @_ZN10TCPPObjectaSERKS_(%struct.TCPPObject* [[TWO]], %struct.TCPPObject* [[THREE]])
+// CHECK: [[CALL:%.*]] = call dereferenceable({{[0-9]+}}) %struct.TCPPObject* @_ZN10TCPPObjectaSERKS_(%struct.TCPPObject* [[TWO]], %struct.TCPPObject* dereferenceable({{[0-9]+}}) [[THREE]])
 // CHECK:  ret void
 
 // CHECK: define internal void @"\01-[MyDocument setMyProperty:]"(
diff --git a/test/CodeGenObjCXX/property-objects.mm b/test/CodeGenObjCXX/property-objects.mm
index 88e992c..c79c280 100644
--- a/test/CodeGenObjCXX/property-objects.mm
+++ b/test/CodeGenObjCXX/property-objects.mm
@@ -32,7 +32,7 @@
 @synthesize frame;
 
 // CHECK: define internal void @"\01-[I setPosition:]"
-// CHECK: call %class.S* @_ZN1SaSERKS_
+// CHECK: call dereferenceable({{[0-9]+}}) %class.S* @_ZN1SaSERKS_
 // CHECK-NEXT: ret void
 
 - (void)setFrame:(CGRect)frameRect {}
@@ -55,7 +55,7 @@
 @end
 
 // CHECK-LABEL: define i32 @main
-// CHECK: call void @_ZN1SC1ERKS_(%class.S* [[AGGTMP:%[a-zA-Z0-9\.]+]], %class.S* {{%[a-zA-Z0-9\.]+}})
+// CHECK: call void @_ZN1SC1ERKS_(%class.S* [[AGGTMP:%[a-zA-Z0-9\.]+]], %class.S* dereferenceable({{[0-9]+}}) {{%[a-zA-Z0-9\.]+}})
 // CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, %class.S*)*)(i8* {{%[a-zA-Z0-9\.]+}}, i8* {{%[a-zA-Z0-9\.]+}}, %class.S* [[AGGTMP]])
 // CHECK-NEXT: ret i32 0
 int main() {
@@ -68,7 +68,7 @@
 // rdar://8379892
 // CHECK-LABEL: define void @_Z1fP1A
 // CHECK: call void @_ZN1XC1Ev(%struct.X* [[LVTEMP:%[a-zA-Z0-9\.]+]])
-// CHECK: call void @_ZN1XC1ERKS_(%struct.X* [[AGGTMP:%[a-zA-Z0-9\.]+]], %struct.X* [[LVTEMP]])
+// CHECK: call void @_ZN1XC1ERKS_(%struct.X* [[AGGTMP:%[a-zA-Z0-9\.]+]], %struct.X* dereferenceable({{[0-9]+}}) [[LVTEMP]])
 // CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, %struct.X*)*)({{.*}} %struct.X* [[AGGTMP]])
 struct X {
   X();
diff --git a/test/CodeGenObjCXX/property-reference.mm b/test/CodeGenObjCXX/property-reference.mm
index a4af900..e426900 100644
--- a/test/CodeGenObjCXX/property-reference.mm
+++ b/test/CodeGenObjCXX/property-reference.mm
@@ -26,7 +26,7 @@
   const MyStruct& currentMyStruct = myClass.foo;   
 }
 
-// CHECK: [[C:%.*]] = call %struct.MyStruct* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
+// CHECK: [[C:%.*]] = call dereferenceable({{[0-9]+}}) %struct.MyStruct* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
 // CHECK:   store %struct.MyStruct* [[C]], %struct.MyStruct** [[D:%.*]]
 
 namespace test1 {
@@ -40,7 +40,7 @@
 @implementation Test1
 @synthesize prop1 = ivar;
 @end
-// CHECK:    define internal [[A:%.*]]* @"\01-[Test1 prop1]"(
+// CHECK:    define internal dereferenceable({{[0-9]+}}) [[A:%.*]]* @"\01-[Test1 prop1]"(
 // CHECK:      [[SELF:%.*]] = alloca [[TEST1:%.*]]*, align 8
 // CHECK:      [[T0:%.*]] = load [[TEST1]]** [[SELF]]
 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
@@ -49,7 +49,7 @@
 // CHECK-NEXT: ret [[A]]* [[T3]]
 
 // CHECK:    define internal void @"\01-[Test1 setProp1:]"(
-// CHECK:      call [[A]]* @_ZN5test11AaSERKS0_(
+// CHECK:      call dereferenceable({{[0-9]+}}) [[A]]* @_ZN5test11AaSERKS0_(
 // CHECK-NEXT: ret void
 
 // rdar://problem/10497174
diff --git a/test/CodeGenObjCXX/rtti.mm b/test/CodeGenObjCXX/rtti.mm
index e458f09..326760f 100644
--- a/test/CodeGenObjCXX/rtti.mm
+++ b/test/CodeGenObjCXX/rtti.mm
@@ -4,19 +4,19 @@
 
 namespace std { class type_info; }
 
-// CHECK: @_ZTI1A = linkonce_odr unnamed_addr constant {{.*}}@_ZTVN10__cxxabiv117__class_type_infoE{{.*}}@_ZTS1A
+// CHECK: @_ZTI1A = linkonce_odr constant {{.*}}@_ZTVN10__cxxabiv117__class_type_infoE{{.*}}@_ZTS1A
 @interface A
 @end
 
-// CHECK: @_ZTI1B = linkonce_odr unnamed_addr constant {{.*}}@_ZTVN10__cxxabiv120__si_class_type_infoE{{.*}}@_ZTS1B{{.*}}@_ZTI1A
+// CHECK: @_ZTI1B = linkonce_odr constant {{.*}}@_ZTVN10__cxxabiv120__si_class_type_infoE{{.*}}@_ZTS1B{{.*}}@_ZTI1A
 @interface B : A
 @end
 
-// CHECK: @_ZTIP1B = linkonce_odr unnamed_addr constant {{.*}}@_ZTVN10__cxxabiv119__pointer_type_infoE{{.*}}@_ZTSP1B{{.*}}), i32 0, {{.*}}@_ZTI1B
-// CHECK: @_ZTI11objc_object = linkonce_odr unnamed_addr constant {{.*}}@_ZTVN10__cxxabiv117__class_type_infoE{{.*}}@_ZTS11objc_object
-// CHECK: @_ZTIP11objc_object = linkonce_odr unnamed_addr constant {{.*}}@_ZTVN10__cxxabiv119__pointer_type_infoE{{.*}}@_ZTSP11objc_object{{.*}}@_ZTI11objc_object
-// CHECK: @_ZTI10objc_class = linkonce_odr unnamed_addr constant {{.*}}@_ZTVN10__cxxabiv117__class_type_infoE{{.*}}@_ZTS10objc_class
-// CHECK: @_ZTIP10objc_class = linkonce_odr unnamed_addr constant {{.*}}@_ZTVN10__cxxabiv119__pointer_type_infoE{{.*}}@_ZTSP10objc_class{{.*}}@_ZTI10objc_class
+// CHECK: @_ZTIP1B = linkonce_odr constant {{.*}}@_ZTVN10__cxxabiv119__pointer_type_infoE{{.*}}@_ZTSP1B{{.*}}), i32 0, {{.*}}@_ZTI1B
+// CHECK: @_ZTI11objc_object = linkonce_odr constant {{.*}}@_ZTVN10__cxxabiv117__class_type_infoE{{.*}}@_ZTS11objc_object
+// CHECK: @_ZTIP11objc_object = linkonce_odr constant {{.*}}@_ZTVN10__cxxabiv119__pointer_type_infoE{{.*}}@_ZTSP11objc_object{{.*}}@_ZTI11objc_object
+// CHECK: @_ZTI10objc_class = linkonce_odr constant {{.*}}@_ZTVN10__cxxabiv117__class_type_infoE{{.*}}@_ZTS10objc_class
+// CHECK: @_ZTIP10objc_class = linkonce_odr constant {{.*}}@_ZTVN10__cxxabiv119__pointer_type_infoE{{.*}}@_ZTSP10objc_class{{.*}}@_ZTI10objc_class
 
 @protocol P;
 
diff --git a/test/CodeGenOpenCL/address-space-constant-initializers.cl b/test/CodeGenOpenCL/address-space-constant-initializers.cl
new file mode 100644
index 0000000..ae8cedc
--- /dev/null
+++ b/test/CodeGenOpenCL/address-space-constant-initializers.cl
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 %s -ffake-address-space-map -emit-llvm -o - | FileCheck %s
+
+typedef struct {
+    int i;
+    float f; // At non-zero offset.
+} ArrayStruct;
+
+__constant ArrayStruct constant_array_struct = { 0, 0.0f };
+
+typedef struct {
+    __constant float* constant_float_ptr;
+} ConstantArrayPointerStruct;
+
+// CHECK: %struct.ConstantArrayPointerStruct = type { float addrspace(3)* }
+// CHECK: addrspace(3) global %struct.ConstantArrayPointerStruct { float addrspace(3)* bitcast (i8 addrspace(3)* getelementptr (i8 addrspace(3)* bitcast (%struct.ArrayStruct addrspace(3)* @constant_array_struct to i8 addrspace(3)*), i64 4) to float addrspace(3)*) }
+// 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 3c7a518..edb53fc 100644
--- a/test/CodeGenOpenCL/address-spaces-mangling.cl
+++ b/test/CodeGenOpenCL/address-spaces-mangling.cl
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 %s -ffake-address-space-map -faddress-space-map-mangling=yes -emit-llvm -o - | FileCheck -check-prefix=ASMANG %s
-// RUN: %clang_cc1 %s -ffake-address-space-map -faddress-space-map-mangling=no -emit-llvm -o - | FileCheck -check-prefix=NOASMANG %s
+// RUN: %clang_cc1 %s -ffake-address-space-map -faddress-space-map-mangling=yes -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefix=ASMANG %s
+// RUN: %clang_cc1 %s -ffake-address-space-map -faddress-space-map-mangling=no -triple %itanium_abi_triple -emit-llvm -o - | FileCheck -check-prefix=NOASMANG %s
 
 // We can't name this f as private is equivalent to default
 // no specifier given address space so we get multiple definition
diff --git a/test/CodeGenOpenCL/builtins-r600.cl b/test/CodeGenOpenCL/builtins-r600.cl
new file mode 100644
index 0000000..cebeba1
--- /dev/null
+++ b/test/CodeGenOpenCL/builtins-r600.cl
@@ -0,0 +1,114 @@
+// REQUIRES: r600-registered-target
+// RUN: %clang_cc1 -triple r600-unknown-unknown -S -emit-llvm -o - %s | FileCheck %s
+
+#pragma OPENCL EXTENSION cl_khr_fp64 : enable
+
+// CHECK-LABEL: @test_div_scale_f64
+// CHECK: call { double, i1 } @llvm.AMDGPU.div.scale.f64(double %a, double %b, i1 true)
+// CHECK-DAG: [[FLAG:%.+]] = extractvalue { double, i1 } %{{.+}}, 1
+// CHECK-DAG: [[VAL:%.+]] = extractvalue { double, i1 } %{{.+}}, 0
+// CHECK: [[FLAGEXT:%.+]] = zext i1 [[FLAG]] to i32
+// CHECK: store i32 [[FLAGEXT]]
+void test_div_scale_f64(global double* out, global int* flagout, double a, double b)
+{
+  bool flag;
+  *out = __builtin_amdgpu_div_scale(a, b, true, &flag);
+  *flagout = flag;
+}
+
+// CHECK-LABEL: @test_div_scale_f32
+// CHECK: call { float, i1 } @llvm.AMDGPU.div.scale.f32(float %a, float %b, i1 true)
+// CHECK-DAG: [[FLAG:%.+]] = extractvalue { float, i1 } %{{.+}}, 1
+// CHECK-DAG: [[VAL:%.+]] = extractvalue { float, i1 } %{{.+}}, 0
+// CHECK: [[FLAGEXT:%.+]] = zext i1 [[FLAG]] to i32
+// CHECK: store i32 [[FLAGEXT]]
+void test_div_scale_f32(global float* out, global int* flagout, float a, float b)
+{
+  bool flag;
+  *out = __builtin_amdgpu_div_scalef(a, b, true, &flag);
+  *flagout = flag;
+}
+
+// CHECK-LABEL: @test_div_fmas_f32
+// CHECK: call float @llvm.AMDGPU.div.fmas.f32
+void test_div_fmas_f32(global float* out, float a, float b, float c)
+{
+  *out = __builtin_amdgpu_div_fmasf(a, b, c);
+}
+
+// CHECK-LABEL: @test_div_fmas_f64
+// CHECK: call double @llvm.AMDGPU.div.fmas.f64
+void test_div_fmas_f64(global double* out, double a, double b, double c)
+{
+  *out = __builtin_amdgpu_div_fmas(a, b, c);
+}
+
+// CHECK-LABEL: @test_div_fixup_f32
+// CHECK: call float @llvm.AMDGPU.div.fixup.f32
+void test_div_fixup_f32(global float* out, float a, float b, float c)
+{
+  *out = __builtin_amdgpu_div_fixupf(a, b, c);
+}
+
+// CHECK-LABEL: @test_div_fixup_f64
+// CHECK: call double @llvm.AMDGPU.div.fixup.f64
+void test_div_fixup_f64(global double* out, double a, double b, double c)
+{
+  *out = __builtin_amdgpu_div_fixup(a, b, c);
+}
+
+// CHECK-LABEL: @test_trig_preop_f32
+// CHECK: call float @llvm.AMDGPU.trig.preop.f32
+void test_trig_preop_f32(global float* out, float a, int b)
+{
+  *out = __builtin_amdgpu_trig_preopf(a, b);
+}
+
+// CHECK-LABEL: @test_trig_preop_f64
+// CHECK: call double @llvm.AMDGPU.trig.preop.f64
+void test_trig_preop_f64(global double* out, double a, int b)
+{
+  *out = __builtin_amdgpu_trig_preop(a, b);
+}
+
+// CHECK-LABEL: @test_rcp_f32
+// CHECK: call float @llvm.AMDGPU.rcp.f32
+void test_rcp_f32(global float* out, float a)
+{
+  *out = __builtin_amdgpu_rcpf(a);
+}
+
+// CHECK-LABEL: @test_rcp_f64
+// CHECK: call double @llvm.AMDGPU.rcp.f64
+void test_rcp_f64(global double* out, double a)
+{
+  *out = __builtin_amdgpu_rcp(a);
+}
+
+// CHECK-LABEL: @test_rsq_f32
+// CHECK: call float @llvm.AMDGPU.rsq.f32
+void test_rsq_f32(global float* out, float a)
+{
+  *out = __builtin_amdgpu_rsqf(a);
+}
+
+// CHECK-LABEL: @test_rsq_f64
+// CHECK: call double @llvm.AMDGPU.rsq.f64
+void test_rsq_f64(global double* out, double a)
+{
+  *out = __builtin_amdgpu_rsq(a);
+}
+
+// CHECK-LABEL: @test_rsq_clamped_f32
+// CHECK: call float @llvm.AMDGPU.rsq.clamped.f32
+void test_rsq_clamped_f32(global float* out, float a)
+{
+  *out = __builtin_amdgpu_rsq_clampedf(a);
+}
+
+// CHECK-LABEL: @test_rsq_clamped_f64
+// CHECK: call double @llvm.AMDGPU.rsq.clamped.f64
+void test_rsq_clamped_f64(global double* out, double a)
+{
+  *out = __builtin_amdgpu_rsq_clamped(a);
+}
diff --git a/test/CodeGenOpenCL/kernel-arg-info.cl b/test/CodeGenOpenCL/kernel-arg-info.cl
index c7e2049..9832604 100644
--- a/test/CodeGenOpenCL/kernel-arg-info.cl
+++ b/test/CodeGenOpenCL/kernel-arg-info.cl
@@ -13,8 +13,16 @@
 
 kernel void foo2(read_only image1d_t img1, image2d_t img2, write_only image2d_array_t img3) {
 }
-// CHECK: metadata !{metadata !"kernel_arg_addr_space", i32 0, i32 0, i32 0}
+// CHECK: metadata !{metadata !"kernel_arg_addr_space", i32 1, i32 1, i32 1}
 // CHECK: metadata !{metadata !"kernel_arg_access_qual", metadata !"read_only", metadata !"read_only", metadata !"write_only"}
 // CHECK: metadata !{metadata !"kernel_arg_type", metadata !"image1d_t", metadata !"image2d_t", metadata !"image2d_array_t"}
 // CHECK: metadata !{metadata !"kernel_arg_type_qual", metadata !"", metadata !"", metadata !""}
 // CHECK: metadata !{metadata !"kernel_arg_name", metadata !"img1", metadata !"img2", metadata !"img3"}
+
+kernel void foo3(__global half * X) {
+}
+// CHECK: metadata !{metadata !"kernel_arg_addr_space", i32 1}
+// CHECK: metadata !{metadata !"kernel_arg_access_qual", metadata !"none"}
+// CHECK: metadata !{metadata !"kernel_arg_type", metadata !"half*"}
+// CHECK: metadata !{metadata !"kernel_arg_type_qual", metadata !""}
+// CHECK: metadata !{metadata !"kernel_arg_name", metadata !"X"}
diff --git a/test/CodeGenOpenCL/local.cl b/test/CodeGenOpenCL/local.cl
index b5c67d9..895c8fa 100644
--- a/test/CodeGenOpenCL/local.cl
+++ b/test/CodeGenOpenCL/local.cl
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 %s -ffake-address-space-map -faddress-space-map-mangling=no -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -ffake-address-space-map -faddress-space-map-mangling=no -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s
 
 __kernel void foo(void) {
-  // CHECK: @foo.i = internal addrspace(2)
+  // CHECK: @foo.i = internal unnamed_addr addrspace(2)
   __local int i;
   ++i;
 }
diff --git a/test/CodeGenOpenCL/str_literals.cl b/test/CodeGenOpenCL/str_literals.cl
index 78a9305..43c90f8 100644
--- a/test/CodeGenOpenCL/str_literals.cl
+++ b/test/CodeGenOpenCL/str_literals.cl
@@ -3,7 +3,7 @@
 __constant char * __constant x = "hello world";
 __constant char * __constant y = "hello world";
 
-// CHECK: addrspace(3) unnamed_addr constant
+// CHECK: unnamed_addr addrspace(3) constant
 // CHECK-NOT: addrspace(3) unnamed_addr constant
 // CHECK: @x = addrspace(3) global i8 addrspace(3)*
 // CHECK: @y = addrspace(3) global i8 addrspace(3)*
diff --git a/test/CodeGenOpenCL/vector_odd.cl b/test/CodeGenOpenCL/vector_odd.cl
new file mode 100644
index 0000000..c44328b
--- /dev/null
+++ b/test/CodeGenOpenCL/vector_odd.cl
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 %s -O0 -emit-llvm -o - | FileCheck %s
+
+typedef unsigned char __attribute__((ext_vector_type(3))) uchar3;
+
+//CHECK: {{%.*}} = shufflevector <3 x i8> {{%.*}}, <3 x i8> <i8 1, i8 1, i8 undef>, <3 x i32> <i32 0, i32 3, i32 2>
+
+kernel void test_odd_vector1 (uchar3 lhs)
+{
+  lhs.odd = 1;
+}
+
+//CHECK: {{%.*}} = shufflevector <3 x i8> {{%.*}}, <3 x i8> <i8 2, i8 2, i8 undef>, <3 x i32> <i32 0, i32 1, i32 3>
+
+kernel void test_odd_vector2 (uchar3 lhs)
+{
+  lhs.hi = 2;
+}
diff --git a/test/Coverage/c-language-features.inc b/test/Coverage/c-language-features.inc
index 0ff1237..3566879 100644
--- a/test/Coverage/c-language-features.inc
+++ b/test/Coverage/c-language-features.inc
@@ -196,3 +196,15 @@
   } f0;
   int f1;
 };
+
+// Unnamed structures.
+struct s12 {
+  struct {
+    unsigned char aa;
+    unsigned char bb;
+  };
+};
+
+void f11() {
+  struct s12 var = { .aa = 33 };
+}
diff --git a/test/Coverage/html-diagnostics.c b/test/Coverage/html-diagnostics.c
index 410ee2a..c7489f8 100644
--- a/test/Coverage/html-diagnostics.c
+++ b/test/Coverage/html-diagnostics.c
@@ -2,6 +2,8 @@
 // RUN: %clang_cc1 -analyze -analyzer-output=html -analyzer-checker=core -o %t %s
 // RUN: cat %t/*.html | FileCheck %s
 
+// REQUIRES: staticanalyzer
+
 // Because of the glob (*.html)
 // REQUIRES: shell
 
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/basic_android_tree/aarch64-linux-android/bin/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/basic_android_tree/aarch64-linux-android/bin/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/basic_android_tree/aarch64-linux-android/include/c++/4.8/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/basic_android_tree/aarch64-linux-android/include/c++/4.8/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/basic_android_tree/aarch64-linux-android/lib/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/basic_android_tree/aarch64-linux-android/lib/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/basic_android_tree/arm-linux-androideabi/bin/ld
old mode 100644
new mode 100755
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/basic_android_tree/arm-linux-androideabi/bin/ld
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/basic_android_tree/arm-linux-androideabi/bin/ld.bfd
old mode 100644
new mode 100755
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/basic_android_tree/arm-linux-androideabi/bin/ld.bfd
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/basic_android_tree/arm-linux-androideabi/bin/ld.gold
old mode 100644
new mode 100755
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/basic_android_tree/arm-linux-androideabi/bin/ld.gold
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/basic_android_tree/bin/arm-linux-androideabi-ld
old mode 100644
new mode 100755
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/basic_android_tree/bin/arm-linux-androideabi-ld
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/basic_android_tree/bin/arm-linux-androideabi-ld.bfd
old mode 100644
new mode 100755
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/basic_android_tree/bin/arm-linux-androideabi-ld.bfd
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/basic_android_tree/bin/arm-linux-androideabi-ld.gold
old mode 100644
new mode 100755
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/basic_android_tree/bin/arm-linux-androideabi-ld.gold
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/basic_android_tree/lib/gcc/aarch64-linux-android/4.8/crtbegin.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/basic_android_tree/lib/gcc/aarch64-linux-android/4.8/crtbegin.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/basic_android_tree/lib/gcc/aarch64-linux-android/4.8/crtbeginS.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/basic_android_tree/lib/gcc/aarch64-linux-android/4.8/crtbeginS.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/basic_android_tree/lib/gcc/aarch64-linux-android/4.8/crtbeginT.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/basic_android_tree/lib/gcc/aarch64-linux-android/4.8/crtbeginT.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/basic_android_tree/lib/gcc/aarch64-linux-android/4.8/crtend.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/basic_android_tree/lib/gcc/aarch64-linux-android/4.8/crtend.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/basic_android_tree/lib/gcc/aarch64-linux-android/4.8/crtendS.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/basic_android_tree/lib/gcc/aarch64-linux-android/4.8/crtendS.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/basic_freebsd_tree/usr/bin/ld.bfd
old mode 100644
new mode 100755
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/basic_freebsd_tree/usr/bin/ld.bfd
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/basic_freebsd_tree/usr/bin/ld.gold
old mode 100644
new mode 100755
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/basic_freebsd_tree/usr/bin/ld.gold
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/basic_linux_libcxx_tree/usr/bin/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/basic_linux_libcxx_tree/usr/bin/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/basic_linux_libcxx_tree/usr/include/c++/v1/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/basic_linux_libcxx_tree/usr/include/c++/v1/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/basic_linux_libcxx_tree/usr/lib/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/basic_linux_libcxx_tree/usr/lib/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/basic_netbsd_tree/usr/lib/64/crti.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/basic_netbsd_tree/usr/lib/64/crti.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/basic_netbsd_tree/usr/lib/eabi/crti.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/basic_netbsd_tree/usr/lib/eabi/crti.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/basic_netbsd_tree/usr/lib/i386/crti.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/basic_netbsd_tree/usr/lib/i386/crti.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/basic_netbsd_tree/usr/lib/o32/crti.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/basic_netbsd_tree/usr/lib/o32/crti.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/basic_netbsd_tree/usr/lib/oabi/crti.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/basic_netbsd_tree/usr/lib/oabi/crti.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/basic_netbsd_tree/usr/lib/sparc/crti.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/basic_netbsd_tree/usr/lib/sparc/crti.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/cl-libs/cl-test.lib
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/cl-libs/cl-test.lib
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/debian_6_mips64_tree/lib/mips64-linux-gnuabi64/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/debian_6_mips64_tree/lib/mips64-linux-gnuabi64/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/debian_6_mips64_tree/lib/mips64el-linux-gnuabi64/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/debian_6_mips64_tree/lib/mips64el-linux-gnuabi64/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/debian_6_mips64_tree/usr/include/c++/4.9/backward/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/debian_6_mips64_tree/usr/include/c++/4.9/backward/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/debian_6_mips64_tree/usr/include/c++/4.9/mips64-linux-gnuabi64/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/debian_6_mips64_tree/usr/include/c++/4.9/mips64-linux-gnuabi64/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/debian_6_mips64_tree/usr/include/c++/4.9/mips64el-linux-gnuabi64/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/debian_6_mips64_tree/usr/include/c++/4.9/mips64el-linux-gnuabi64/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/debian_6_mips64_tree/usr/include/mips64-linux-gnuabi64/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/debian_6_mips64_tree/usr/include/mips64-linux-gnuabi64/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/debian_6_mips64_tree/usr/include/mips64el-linux-gnuabi64/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/debian_6_mips64_tree/usr/include/mips64el-linux-gnuabi64/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/gcc/mips64-linux-gnuabi64/4.9/crtbegin.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/debian_6_mips64_tree/usr/lib/gcc/mips64-linux-gnuabi64/4.9/crtbegin.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/gcc/mips64-linux-gnuabi64/4.9/crtend.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/debian_6_mips64_tree/usr/lib/gcc/mips64-linux-gnuabi64/4.9/crtend.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/gcc/mips64el-linux-gnuabi64/4.9/crtbegin.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/debian_6_mips64_tree/usr/lib/gcc/mips64el-linux-gnuabi64/4.9/crtbegin.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/gcc/mips64el-linux-gnuabi64/4.9/crtend.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/debian_6_mips64_tree/usr/lib/gcc/mips64el-linux-gnuabi64/4.9/crtend.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/mips64-linux-gnuabi64/crt1.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/debian_6_mips64_tree/usr/lib/mips64-linux-gnuabi64/crt1.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/mips64-linux-gnuabi64/crti.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/debian_6_mips64_tree/usr/lib/mips64-linux-gnuabi64/crti.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/mips64-linux-gnuabi64/crtn.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/debian_6_mips64_tree/usr/lib/mips64-linux-gnuabi64/crtn.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/mips64el-linux-gnuabi64/crt1.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/debian_6_mips64_tree/usr/lib/mips64el-linux-gnuabi64/crt1.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/mips64el-linux-gnuabi64/crti.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/debian_6_mips64_tree/usr/lib/mips64el-linux-gnuabi64/crti.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/debian_6_mips64_tree/usr/lib/mips64el-linux-gnuabi64/crtn.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/debian_6_mips64_tree/usr/lib/mips64el-linux-gnuabi64/crtn.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/debian_reduced_mips_tree/lib/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/debian_reduced_mips_tree/lib/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/debian_reduced_mips_tree/lib/mips-linux-gnu/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/debian_reduced_mips_tree/lib/mips-linux-gnu/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/debian_reduced_mips_tree/lib/mipsel-linux-gnu/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/debian_reduced_mips_tree/lib/mipsel-linux-gnu/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/debian_reduced_mips_tree/usr/include/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/debian_reduced_mips_tree/usr/include/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/debian_reduced_mips_tree/usr/include/c++/4.7/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/debian_reduced_mips_tree/usr/include/c++/4.7/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/debian_reduced_mips_tree/usr/include/c++/4.7/backward/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/debian_reduced_mips_tree/usr/include/c++/4.7/backward/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/debian_reduced_mips_tree/usr/include/c++/4.7/mips-linux-gnu/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/debian_reduced_mips_tree/usr/include/c++/4.7/mips-linux-gnu/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/debian_reduced_mips_tree/usr/include/c++/4.7/mipsel-linux-gnu/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/debian_reduced_mips_tree/usr/include/c++/4.7/mipsel-linux-gnu/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/debian_reduced_mips_tree/usr/include/mips-linux-gnu/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/debian_reduced_mips_tree/usr/include/mips-linux-gnu/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/debian_reduced_mips_tree/usr/include/mipsel-linux-gnu/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/debian_reduced_mips_tree/usr/include/mipsel-linux-gnu/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/debian_reduced_mips_tree/usr/lib/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/debian_reduced_mips_tree/usr/lib/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/debian_reduced_mips_tree/usr/lib/gcc/mips-linux-gnu/4.7/crtbegin.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/debian_reduced_mips_tree/usr/lib/gcc/mips-linux-gnu/4.7/crtbegin.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/debian_reduced_mips_tree/usr/lib/gcc/mipsel-linux-gnu/4.7/crtbegin.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/debian_reduced_mips_tree/usr/lib/gcc/mipsel-linux-gnu/4.7/crtbegin.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/debian_reduced_mips_tree/usr/lib/mips-linux-gnu/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/debian_reduced_mips_tree/usr/lib/mips-linux-gnu/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/debian_reduced_mips_tree/usr/lib/mipsel-linux-gnu/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/debian_reduced_mips_tree/usr/lib/mipsel-linux-gnu/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/fedora_21_tree/usr/lib/gcc/aarch64-redhat-linux/4.9.0/crtbegin.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/fedora_21_tree/usr/lib/gcc/aarch64-redhat-linux/4.9.0/crtbegin.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/fedora_21_tree/usr/lib/gcc/aarch64-redhat-linux/4.9.0/crtend.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/fedora_21_tree/usr/lib/gcc/aarch64-redhat-linux/4.9.0/crtend.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/fedora_21_tree/usr/lib64/crt1.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/fedora_21_tree/usr/lib64/crt1.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/fedora_21_tree/usr/lib64/crti.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/fedora_21_tree/usr/lib64/crti.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/fedora_21_tree/usr/lib64/crtn.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/fedora_21_tree/usr/lib64/crtn.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/file.ll
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/file.ll
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/gentoo_linux_gcc_4.6.2_tree/usr/include/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/gentoo_linux_gcc_4.6.2_tree/usr/include/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/gentoo_linux_gcc_4.6.4_tree/usr/include/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/gentoo_linux_gcc_4.6.4_tree/usr/include/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/nan2008/el/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/include-fixed/nan2008/el/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/nan2008/crtbegin.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/nan2008/crtbegin.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/nan2008/crtend.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/nan2008/crtend.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/nan2008/el/crtbegin.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/nan2008/el/crtbegin.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/nan2008/el/crtend.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_cs_tree/lib/gcc/mips-linux-gnu/4.6.3/nan2008/el/crtend.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/nan2008/el/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/lib/nan2008/el/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/nan2008/el/lib/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/nan2008/el/lib/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/nan2008/el/usr/lib/crt1.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/nan2008/el/usr/lib/crt1.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/nan2008/el/usr/lib/crti.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/nan2008/el/usr/lib/crti.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/nan2008/el/usr/lib/crtn.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/nan2008/el/usr/lib/crtn.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/nan2008/lib/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/nan2008/lib/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/nan2008/usr/lib/crt1.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/nan2008/usr/lib/crt1.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/nan2008/usr/lib/crti.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/nan2008/usr/lib/crti.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/nan2008/usr/lib/crtn.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_cs_tree/mips-linux-gnu/libc/nan2008/usr/lib/crtn.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/bin/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/bin/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/crtbegin.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/crtbegin.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/crtend.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/crtend.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/el/crtbegin.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/el/crtbegin.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/el/crtend.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/el/crtend.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/include-fixed/el/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/include-fixed/el/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/include-fixed/mips64r6/64/el/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/include-fixed/mips64r6/64/el/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/include-fixed/mips64r6/el/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/include-fixed/mips64r6/el/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/include/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/include/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/64/crtbegin.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/64/crtbegin.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/64/crtend.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/64/crtend.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/64/el/crtbegin.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/64/el/crtbegin.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/64/el/crtend.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/64/el/crtend.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/crtbegin.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/crtbegin.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/crtend.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/crtend.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/el/crtbegin.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/el/crtbegin.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/el/crtend.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/lib/gcc/mips-img-linux-gnu/4.9.0/mips64r6/el/crtend.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/mips-img-linux-gnu/bin/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/mips-img-linux-gnu/bin/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/mips-img-linux-gnu/include/c++/4.9.0/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/mips-img-linux-gnu/include/c++/4.9.0/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/mips-img-linux-gnu/lib/el/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/mips-img-linux-gnu/lib/el/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/mips-img-linux-gnu/lib/mips64r6/64/el/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/mips-img-linux-gnu/lib/mips64r6/64/el/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/mips-img-linux-gnu/lib/mips64r6/el/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/mips-img-linux-gnu/lib/mips64r6/el/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/sysroot/el/usr/bin/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/sysroot/el/usr/bin/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/sysroot/el/usr/lib/crt1.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/sysroot/el/usr/lib/crt1.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/sysroot/el/usr/lib/crti.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/sysroot/el/usr/lib/crti.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/sysroot/el/usr/lib/crtn.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/sysroot/el/usr/lib/crtn.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/sysroot/el/usr/sbin/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/sysroot/el/usr/sbin/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/el/usr/bin/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/el/usr/bin/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/el/usr/lib/crt1.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/el/usr/lib/crt1.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/el/usr/lib/crti.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/el/usr/lib/crti.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/el/usr/lib/crtn.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/el/usr/lib/crtn.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/el/usr/sbin/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/el/usr/sbin/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/usr/bin/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/usr/bin/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/usr/lib/crt1.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/usr/lib/crt1.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/usr/lib/crti.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/usr/lib/crti.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/usr/lib/crtn.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/usr/lib/crtn.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/usr/sbin/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/64/usr/sbin/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/el/usr/bin/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/el/usr/bin/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/el/usr/lib/crt1.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/el/usr/lib/crt1.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/el/usr/lib/crti.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/el/usr/lib/crti.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/el/usr/lib/crtn.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/el/usr/lib/crtn.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/el/usr/sbin/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/el/usr/sbin/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/usr/bin/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/usr/bin/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/usr/lib/crt1.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/usr/lib/crt1.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/usr/lib/crti.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/usr/lib/crti.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/usr/lib/crtn.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/usr/lib/crtn.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/usr/sbin/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/sysroot/mips64r6/usr/sbin/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/sysroot/usr/bin/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/sysroot/usr/bin/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/sysroot/usr/include/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/sysroot/usr/include/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/sysroot/usr/lib/crt1.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/sysroot/usr/lib/crt1.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/sysroot/usr/lib/crti.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/sysroot/usr/lib/crti.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/sysroot/usr/lib/crtn.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/sysroot/usr/lib/crtn.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/mips_img_tree/sysroot/usr/sbin/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/mips_img_tree/sysroot/usr/sbin/.keep
diff --git a/test/Driver/Inputs/module/module.modulemap b/test/Driver/Inputs/module/module.modulemap
new file mode 100644
index 0000000..4fddd4b
--- /dev/null
+++ b/test/Driver/Inputs/module/module.modulemap
@@ -0,0 +1,4 @@
+module simple {
+  header "simple.h"
+  export *
+}
diff --git a/test/Driver/Inputs/module/simple.h b/test/Driver/Inputs/module/simple.h
new file mode 100644
index 0000000..afd674e
--- /dev/null
+++ b/test/Driver/Inputs/module/simple.h
@@ -0,0 +1 @@
+#define MODULE_MACRO 10
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/multilib_64bit_linux_tree/libx32/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/multilib_64bit_linux_tree/libx32/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0/x32/crtbegin.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/multilib_64bit_linux_tree/usr/lib/gcc/x86_64-unknown-linux/4.6.0/x32/crtbegin.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/multilib_64bit_linux_tree/usr/libx32/gcc/x86_64-unknown-gnu/4.6.0/32/crtbegin.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/multilib_64bit_linux_tree/usr/libx32/gcc/x86_64-unknown-gnu/4.6.0/32/crtbegin.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/multilib_64bit_linux_tree/usr/libx32/gcc/x86_64-unknown-gnu/4.6.0/crtbegin.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/multilib_64bit_linux_tree/usr/libx32/gcc/x86_64-unknown-gnu/4.6.0/crtbegin.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/multilib_64bit_linux_tree/usr/libx32/gcc/x86_64-unknown-gnu/4.6.0/x32/crtbegin.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/multilib_64bit_linux_tree/usr/libx32/gcc/x86_64-unknown-gnu/4.6.0/x32/crtbegin.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/multilib_64bit_linux_tree/usr/x86_64-unknown-linux/libx32/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/multilib_64bit_linux_tree/usr/x86_64-unknown-linux/libx32/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/resource_dir/lib/macho_embedded/libclang_rt.hard_pic.a
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/resource_dir/lib/macho_embedded/libclang_rt.hard_pic.a
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/resource_dir/lib/macho_embedded/libclang_rt.hard_static.a
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/resource_dir/lib/macho_embedded/libclang_rt.hard_static.a
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/resource_dir/lib/macho_embedded/libclang_rt.soft_pic.a
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/resource_dir/lib/macho_embedded/libclang_rt.soft_pic.a
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/resource_dir/lib/macho_embedded/libclang_rt.soft_static.a
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/resource_dir/lib/macho_embedded/libclang_rt.soft_static.a
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/lib/powerpc64le-linux-gnu/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/ubuntu_14.04_multiarch_tree/lib/powerpc64le-linux-gnu/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/lib/x86_64-linux-gnu/.keep
old mode 100644
new mode 100755
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/ubuntu_14.04_multiarch_tree/lib/x86_64-linux-gnu/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/libx32/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/ubuntu_14.04_multiarch_tree/libx32/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/include/c++/4.8/backward/.keep
old mode 100644
new mode 100755
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/include/c++/4.8/backward/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/include/powerpc64le-linux-gnu/c++/4.8/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/include/powerpc64le-linux-gnu/c++/4.8/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/include/x86_64-linux-gnu/c++/4.8/32/.keep
old mode 100644
new mode 100755
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/include/x86_64-linux-gnu/c++/4.8/32/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/include/x86_64-linux-gnu/c++/4.8/x32/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/include/x86_64-linux-gnu/c++/4.8/x32/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/powerpc64le-linux-gnu/4.8/crtbegin.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/powerpc64le-linux-gnu/4.8/crtbegin.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/powerpc64le-linux-gnu/4.8/crtend.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/powerpc64le-linux-gnu/4.8/crtend.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/powerpc64le-linux-gnu/4.9/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/powerpc64le-linux-gnu/4.9/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.8/32/crtbegin.o
old mode 100644
new mode 100755
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.8/32/crtbegin.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.8/crtbegin.o
old mode 100644
new mode 100755
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.8/crtbegin.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.8/x32/crtbegin.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.8/x32/crtbegin.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.8/x32/crtend.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.8/x32/crtend.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.9/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/gcc/x86_64-linux-gnu/4.9/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/powerpc64le-linux-gnu/crt1.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/powerpc64le-linux-gnu/crt1.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/powerpc64le-linux-gnu/crti.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/powerpc64le-linux-gnu/crti.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/powerpc64le-linux-gnu/crtn.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/powerpc64le-linux-gnu/crtn.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/x86_64-linux-gnu/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/lib/x86_64-linux-gnu/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/libx32/crt1.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/libx32/crt1.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/libx32/crti.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/libx32/crti.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/libx32/crtn.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/ubuntu_14.04_multiarch_tree/usr/libx32/crtn.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/lib/i386-linux-gnu/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/lib/i386-linux-gnu/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/lib/x86_64-linux-gnu/.keep
old mode 100644
new mode 100755
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/lib/x86_64-linux-gnu/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/include/c++/4.8/backward/.keep
old mode 100644
new mode 100755
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/include/c++/4.8/backward/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/include/i386-linux-gnu/c++/4.8/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/include/i386-linux-gnu/c++/4.8/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/include/x86_64-linux-gnu/c++/4.8/32/.keep
old mode 100644
new mode 100755
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/include/x86_64-linux-gnu/c++/4.8/32/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/lib/gcc/i686-linux-gnu/4.8/crtbegin.o
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/lib/gcc/i686-linux-gnu/4.8/crtbegin.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/lib/gcc/x86_64-linux-gnu/4.8/32/crtbegin.o
old mode 100644
new mode 100755
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/lib/gcc/x86_64-linux-gnu/4.8/32/crtbegin.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/lib/gcc/x86_64-linux-gnu/4.8/crtbegin.o
old mode 100644
new mode 100755
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/lib/gcc/x86_64-linux-gnu/4.8/crtbegin.o
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/lib/i386-linux-gnu/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/lib/i386-linux-gnu/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/lib/x86_64-linux-gnu/.keep
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/ubuntu_14.04_multiarch_tree2/usr/lib/x86_64-linux-gnu/.keep
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/wildcard1.c
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/wildcard1.c
diff --git a/include/clang/Driver/CC1Options.h b/test/Driver/Inputs/wildcard2.c
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Driver/Inputs/wildcard2.c
diff --git a/test/Driver/Xlinker-args.c b/test/Driver/Xlinker-args.c
index 4285af7..87b238b 100644
--- a/test/Driver/Xlinker-args.c
+++ b/test/Driver/Xlinker-args.c
@@ -3,17 +3,17 @@
 
 // RUN: %clang -target i386-apple-darwin9 -### \
 // RUN:   -Xlinker one -Xlinker --no-demangle \
-// RUN:   -Wl,two,--no-demangle,three -Xlinker four %s 2> %t
+// RUN:   -Wl,two,--no-demangle,three -Xlinker four -z five %s 2> %t
 // RUN: FileCheck -check-prefix=DARWIN < %t %s
 //
 // RUN: %clang -target x86_64-pc-linux-gnu -### \
 // RUN:   -Xlinker one -Xlinker --no-demangle \
-// RUN:   -Wl,two,--no-demangle,three -Xlinker four %s 2> %t
+// RUN:   -Wl,two,--no-demangle,three -Xlinker four -z five %s 2> %t
 // RUN: FileCheck -check-prefix=LINUX < %t %s
 //
 // DARWIN-NOT: --no-demangle
-// DARWIN: "one" "two" "three" "four"
-// LINUX: "--no-demangle" "one" "two" "three" "four"
+// DARWIN: "one" "two" "three" "four" "-z" "five"
+// LINUX: "--no-demangle" "one" "two" "three" "four" "-z" "five"
 
 // Check that we forward '-Xlinker' and '-Wl,' on Windows.
 // RUN: %clang -target i686-pc-win32 -### \
diff --git a/test/Driver/aarch64-cpus.c b/test/Driver/aarch64-cpus.c
index 799ce10..68ad326 100644
--- a/test/Driver/aarch64-cpus.c
+++ b/test/Driver/aarch64-cpus.c
@@ -1,10 +1,91 @@
 // Check target CPUs are correctly passed.
 
 // RUN: %clang -target aarch64 -### -c %s 2>&1 | FileCheck -check-prefix=GENERIC %s
+// RUN: %clang -target aarch64 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=GENERIC %s
+// RUN: %clang -target aarch64_be -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=GENERIC %s
 // GENERIC: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic"
 
+// RUN: %clang -target arm64 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-GENERIC %s
+// RUN: %clang -target arm64 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-GENERIC %s
+// RUN: %clang -target arm64_be -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-GENERIC %s
+// ARM64-GENERIC: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "generic"
+
+// RUN: %clang -target arm64-apple-darwin -arch arm64 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-DARWIN %s
+// ARM64-DARWIN: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "cyclone"
+
 // RUN: %clang -target aarch64 -mcpu=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=CA53 %s
+// RUN: %clang -target aarch64 -mlittle-endian -mcpu=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=CA53 %s
+// RUN: %clang -target aarch64_be -mlittle-endian -mcpu=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=CA53 %s
+// RUN: %clang -target aarch64 -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=CA53 %s
+// RUN: %clang -target aarch64_be -mlittle-endian -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=CA53 %s
 // CA53: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "cortex-a53"
 
+// RUN: %clang -target arm64 -mcpu=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA53 %s
+// RUN: %clang -target arm64 -mlittle-endian -mcpu=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA53 %s
+// RUN: %clang -target arm64_be -mlittle-endian -mcpu=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA53 %s
+// RUN: %clang -target arm64 -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA53 %s
+// RUN: %clang -target arm64 -mlittle-endian -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA53 %s
+// RUN: %clang -target arm64_be -mlittle-endian -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA53 %s
+// ARM64-CA53: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "cortex-a53"
+
 // RUN: %clang -target aarch64 -mcpu=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=CA57 %s
+// RUN: %clang -target aarch64 -mlittle-endian -mcpu=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=CA57 %s
+// RUN: %clang -target aarch64_be -mlittle-endian -mcpu=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=CA57 %s
+// RUN: %clang -target aarch64 -mtune=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=CA57 %s
+// RUN: %clang -target aarch64 -mlittle-endian -mtune=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=CA57 %s
+// RUN: %clang -target aarch64_be -mlittle-endian -mtune=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=CA57 %s
 // CA57: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "cortex-a57"
+
+// RUN: %clang -target arm64 -mcpu=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA57 %s
+// RUN: %clang -target arm64 -mlittle-endian -mcpu=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA57 %s
+// RUN: %clang -target arm64_be -mlittle-endian -mcpu=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA57 %s
+// RUN: %clang -target arm64 -mtune=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA57 %s
+// RUN: %clang -target arm64 -mlittle-endian -mtune=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA57 %s
+// RUN: %clang -target arm64_be -mlittle-endian -mtune=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA57 %s
+// ARM64-CA57: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "cortex-a57"
+
+// 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
+// RUN: %clang -target aarch64_be -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=GENERIC-BE %s
+// GENERIC-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "generic"
+
+// RUN: %clang -target arm64_be -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-GENERIC-BE %s
+// RUN: %clang -target arm64 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-GENERIC-BE %s
+// RUN: %clang -target arm64_be -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-GENERIC-BE %s
+// ARM64-GENERIC-BE: "-cc1"{{.*}} "-triple" "arm64_be{{.*}}" "-target-cpu" "generic"
+
+// RUN: %clang -target aarch64_be -mcpu=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=CA53-BE %s
+// RUN: %clang -target aarch64 -mbig-endian -mcpu=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=CA53-BE %s
+// RUN: %clang -target aarch64_be -mbig-endian -mcpu=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=CA53-BE %s
+// RUN: %clang -target aarch64_be -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=CA53-BE %s
+// RUN: %clang -target aarch64 -mbig-endian -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=CA53-BE %s
+// RUN: %clang -target aarch64_be -mbig-endian -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=CA53-BE %s
+// CA53-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "cortex-a53"
+
+// RUN: %clang -target arm64_be -mcpu=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA53-BE %s
+// RUN: %clang -target arm64 -mbig-endian -mcpu=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA53-BE %s
+// RUN: %clang -target arm64_be -mbig-endian -mcpu=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA53-BE %s
+// RUN: %clang -target arm64_be -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA53-BE %s
+// RUN: %clang -target arm64 -mbig-endian -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA53-BE %s
+// RUN: %clang -target arm64_be -mbig-endian -mtune=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA53-BE %s
+// ARM64-CA53-BE: "-cc1"{{.*}} "-triple" "arm64_be{{.*}}" "-target-cpu" "cortex-a53"
+
+// RUN: %clang -target aarch64_be -mcpu=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=CA57-BE %s
+// RUN: %clang -target aarch64 -mbig-endian -mcpu=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=CA57-BE %s
+// RUN: %clang -target aarch64_be -mbig-endian -mcpu=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=CA57-BE %s
+// RUN: %clang -target aarch64_be -mtune=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=CA57-BE %s
+// RUN: %clang -target aarch64 -mbig-endian -mtune=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=CA57-BE %s
+// RUN: %clang -target aarch64_be -mbig-endian -mtune=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=CA57-BE %s
+// CA57-BE: "-cc1"{{.*}} "-triple" "aarch64_be{{.*}}" "-target-cpu" "cortex-a57"
+
+// RUN: %clang -target arm64_be -mcpu=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA57-BE %s
+// RUN: %clang -target arm64 -mbig-endian -mcpu=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA57-BE %s
+// RUN: %clang -target arm64_be -mbig-endian -mcpu=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA57-BE %s
+// RUN: %clang -target arm64_be -mtune=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA57-BE %s
+// RUN: %clang -target arm64 -mbig-endian -mtune=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA57-BE %s
+// RUN: %clang -target arm64_be -mbig-endian -mtune=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-CA57-BE %s
+// ARM64-CA57-BE: "-cc1"{{.*}} "-triple" "arm64_be{{.*}}" "-target-cpu" "cortex-a57"
+
+// 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
+// MCPU-MTUNE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "cortex-a53"
diff --git a/test/Driver/aarch64-features.c b/test/Driver/aarch64-features.c
index 2acb715..7c3f875 100644
--- a/test/Driver/aarch64-features.c
+++ b/test/Driver/aarch64-features.c
@@ -1,4 +1,5 @@
 // RUN: %clang -target aarch64-none-linux-gnu -### %s -fsyntax-only 2>&1 | FileCheck %s
+// RUN: %clang -target arm64-none-linux-gnu -### %s -fsyntax-only 2>&1 | FileCheck %s
 
 // The AArch64 PCS states that chars should be unsigned.
 // CHECK: fno-signed-char
diff --git a/test/Driver/aarch64-mfpu.c b/test/Driver/aarch64-mfpu.c
deleted file mode 100644
index 234401b..0000000
--- a/test/Driver/aarch64-mfpu.c
+++ /dev/null
@@ -1,26 +0,0 @@
-// Test that different values of -mfpu pick correct AArch64 FPU target-feature(s).
-
-// RUN: %clang -target aarch64-linux-eabi -mfpu=neon %s -### -o %t.o 2>&1 \
-// RUN:   | FileCheck --check-prefix=CHECK-NEON %s
-// CHECK-NEON: "-target-feature" "+neon"
-
-// RUN: %clang -target aarch64-linux-eabi -mfpu=fp-armv8 %s -### -o %t.o 2>&1 \
-// RUN:   | FileCheck --check-prefix=CHECK-FP-ARMV8 %s
-// CHECK-FP-ARMV8: "-target-feature" "+fp-armv8"
-
-// RUN: %clang -target aarch64-linux-eabi -mfpu=neon-fp-armv8 %s -### 2>&1 \
-// RUN:   | FileCheck --check-prefix=CHECK-NEON-FP-ARMV8 %s
-// CHECK-NEON-FP-ARMV8: "-target-feature" "+fp-armv8"
-// CHECK-NEON-FP-ARMV8: "-target-feature" "+neon"
-
-// RUN: %clang -target aarch64-linux-eabi -mfpu=crypto-neon-fp-armv8 %s -### 2>&1 \
-// RUN:   | FileCheck --check-prefix=CHECK-CRYPTO-NEON-FP-ARMV8 %s
-// CHECK-CRYPTO-NEON-FP-ARMV8: "-target-feature" "+fp-armv8"
-// CHECK-CRYPTO-NEON-FP-ARMV8: "-target-feature" "+neon"
-// CHECK-CRYPTO-NEON-FP-ARMV8: "-target-feature" "+crypto"
-
-// RUN: %clang -target aarch64-linux-eabi -mfpu=none %s -### 2>&1 \
-// RUN:   | FileCheck --check-prefix=CHECK-NO-FP %s
-// CHECK-NO-FP: "-target-feature" "-fp-armv8"
-// CHECK-NO-FP: "-target-feature" "-crypto"
-// CHECK-NO-FP: "-target-feature" "-neon"
diff --git a/test/Driver/aarch64-mgeneral_regs_only.c b/test/Driver/aarch64-mgeneral_regs_only.c
new file mode 100644
index 0000000..43172c7
--- /dev/null
+++ b/test/Driver/aarch64-mgeneral_regs_only.c
@@ -0,0 +1,9 @@
+// Test the -mgeneral-regs-only option
+
+// RUN: %clang -target aarch64-linux-eabi -mgeneral-regs-only %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-NO-FP %s
+// RUN: %clang -target arm64-linux-eabi -mgeneral-regs-only %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-NO-FP %s
+// CHECK-NO-FP: "-target-feature" "-fp-armv8"
+// CHECK-NO-FP: "-target-feature" "-crypto"
+// CHECK-NO-FP: "-target-feature" "-neon"
diff --git a/test/Driver/altivec-asm.S b/test/Driver/altivec-asm.S
index 4143d52..3f78b58 100644
--- a/test/Driver/altivec-asm.S
+++ b/test/Driver/altivec-asm.S
@@ -1,3 +1,4 @@
 // RUN: %clang -target powerpc64-linux-gnu -maltivec -S %s -o - | FileCheck %s
+// RUN: %clang -target powerpc64le-linux-gnu -maltivec -S %s -o - | FileCheck %s
 // Verify that assembling an empty file does not auto-include altivec.h.
 // CHECK-NOT: static vector
diff --git a/test/Driver/android-standalone.cpp b/test/Driver/android-standalone.cpp
index dc41ed7..2bdaedd 100644
--- a/test/Driver/android-standalone.cpp
+++ b/test/Driver/android-standalone.cpp
@@ -17,6 +17,36 @@
 // CHECK: "-L{{.*}}/sysroot/usr/lib"
 //
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     -target aarch64-linux-android \
+// RUN:     -B%S/Inputs/basic_android_tree \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:   | FileCheck --check-prefix=CHECK-AARCH64 %s
+// CHECK-AARCH64: {{.*}}clang{{.*}}" "-cc1"
+// CHECK-AARCH64: "-internal-isystem" "{{.*}}/aarch64-linux-android/include/c++/4.8"
+// CHECK-AARCH64: "-internal-isystem" "{{.*}}/aarch64-linux-android/include/c++/4.8/aarch64-linux-android"
+// CHECK-AARCH64: "-internal-externc-isystem" "{{.*}}/sysroot/include"
+// CHECK-AARCH64: "-internal-externc-isystem" "{{.*}}/sysroot/usr/include"
+// CHECK-AARCH64: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-AARCH64: "-L{{.*}}/lib/gcc/aarch64-linux-android/4.8"
+// CHECK-AARCH64: "-L{{.*}}/lib/gcc/aarch64-linux-android/4.8/../../../../aarch64-linux-android/lib"
+// CHECK-AARCH64: "-L{{.*}}/sysroot/usr/lib"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     -target arm64-linux-android \
+// RUN:     -B%S/Inputs/basic_android_tree \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:   | FileCheck --check-prefix=CHECK-ARM64 %s
+// CHECK-ARM64: {{.*}}clang{{.*}}" "-cc1"
+// CHECK-ARM64: "-internal-isystem" "{{.*}}/aarch64-linux-android/include/c++/4.8"
+// CHECK-ARM64: "-internal-isystem" "{{.*}}/aarch64-linux-android/include/c++/4.8/aarch64-linux-android"
+// CHECK-ARM64: "-internal-externc-isystem" "{{.*}}/sysroot/include"
+// CHECK-ARM64: "-internal-externc-isystem" "{{.*}}/sysroot/usr/include"
+// CHECK-ARM64: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-ARM64: "-L{{.*}}/lib/gcc/aarch64-linux-android/4.8"
+// CHECK-ARM64: "-L{{.*}}/lib/gcc/aarch64-linux-android/4.8/../../../../aarch64-linux-android/lib"
+// CHECK-ARM64: "-L{{.*}}/sysroot/usr/lib"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     -target mipsel-linux-android \
 // RUN:     -mips32 \
 // RUN:     -B%S/Inputs/basic_android_tree \
diff --git a/test/Driver/arm-alignment.c b/test/Driver/arm-alignment.c
index e3ab276..98046d7 100644
--- a/test/Driver/arm-alignment.c
+++ b/test/Driver/arm-alignment.c
@@ -1,25 +1,48 @@
 // RUN: %clang -target arm-none-gnueabi -munaligned-access -### %s 2> %t
-// RUN: FileCheck --check-prefix=CHECK-UNALIGNED < %t %s
+// RUN: FileCheck --check-prefix=CHECK-UNALIGNED-ARM < %t %s
 
 // RUN: %clang -target arm-none-gnueabi -mstrict-align -munaligned-access -### %s 2> %t
-// RUN: FileCheck --check-prefix=CHECK-UNALIGNED < %t %s
+// RUN: FileCheck --check-prefix=CHECK-UNALIGNED-ARM < %t %s
 
 // RUN: %clang -target arm-none-gnueabi -mno-unaligned-access -munaligned-access -### %s 2> %t
-// RUN: FileCheck --check-prefix=CHECK-UNALIGNED < %t %s
+// RUN: FileCheck --check-prefix=CHECK-UNALIGNED-ARM < %t %s
 
-// CHECK-UNALIGNED: "-backend-option" "-arm-no-strict-align"
+// RUN: %clang -target aarch64-none-gnueabi -munaligned-access -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-UNALIGNED-AARCH64 < %t %s
+
+// RUN: %clang -target aarch64-none-gnueabi -mstrict-align -munaligned-access -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-UNALIGNED-AARCH64 < %t %s
+
+// RUN: %clang -target aarch64-none-gnueabi -mno-unaligned-access -munaligned-access -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-UNALIGNED-AARCH64 < %t %s
+
+// CHECK-UNALIGNED-ARM: "-backend-option" "-arm-no-strict-align"
+// CHECK-UNALIGNED-AARCH64: "-backend-option" "-aarch64-no-strict-align"
 
 
 // RUN: %clang -target arm-none-gnueabi -mno-unaligned-access -### %s 2> %t
-// RUN: FileCheck --check-prefix=CHECK-ALIGNED < %t %s
+// RUN: FileCheck --check-prefix=CHECK-ALIGNED-ARM < %t %s
 
 // RUN: %clang -target arm-none-gnueabi -mstrict-align -### %s 2> %t
-// RUN: FileCheck --check-prefix=CHECK-ALIGNED < %t %s
+// RUN: FileCheck --check-prefix=CHECK-ALIGNED-ARM < %t %s
 
 // RUN: %clang -target arm-none-gnueabi -munaligned-access -mno-unaligned-access -### %s 2> %t
-// RUN: FileCheck --check-prefix=CHECK-ALIGNED < %t %s
+// RUN: FileCheck --check-prefix=CHECK-ALIGNED-ARM < %t %s
 
 // RUN: %clang -target arm-none-gnueabi -munaligned-access -mstrict-align -### %s 2> %t
-// RUN: FileCheck --check-prefix=CHECK-ALIGNED < %t %s
+// RUN: FileCheck --check-prefix=CHECK-ALIGNED-ARM < %t %s
 
-// CHECK-ALIGNED: "-backend-option" "-arm-strict-align"
+// RUN: %clang -target aarch64-none-gnueabi -mno-unaligned-access -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-ALIGNED-AARCH64 < %t %s
+
+// RUN: %clang -target aarch64-none-gnueabi -mstrict-align -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-ALIGNED-AARCH64 < %t %s
+
+// RUN: %clang -target aarch64-none-gnueabi -munaligned-access -mno-unaligned-access -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-ALIGNED-AARCH64 < %t %s
+
+// RUN: %clang -target aarch64-none-gnueabi -munaligned-access -mstrict-align -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-ALIGNED-AARCH64 < %t %s
+
+// CHECK-ALIGNED-ARM: "-backend-option" "-arm-strict-align"
+// CHECK-ALIGNED-AARCH64: "-backend-option" "-aarch64-strict-align"
diff --git a/test/Driver/arm-arch-darwin.c b/test/Driver/arm-arch-darwin.c
new file mode 100644
index 0000000..5508961
--- /dev/null
+++ b/test/Driver/arm-arch-darwin.c
@@ -0,0 +1,6 @@
+// On Darwin, arch should override CPU for triple purposes
+// RUN: %clang -target armv7m-apple-darwin -arch armv7m -mcpu=cortex-m4 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V7M-DARWIN %s
+// CHECK-V7M-DARWIN: "-cc1"{{.*}} "-triple" "thumbv7m-{{.*}} "-target-cpu" "cortex-m4"
+// RUN: %clang -target armv7m -arch armv7m -mcpu=cortex-m4 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V7M-OVERRIDDEN %s
+// CHECK-V7M-OVERRIDDEN: "-cc1"{{.*}} "-triple" "thumbv7em-{{.*}} "-target-cpu" "cortex-m4"
+
diff --git a/test/Driver/arm-cortex-cpus.c b/test/Driver/arm-cortex-cpus.c
index bd833cb..224ba57 100644
--- a/test/Driver/arm-cortex-cpus.c
+++ b/test/Driver/arm-cortex-cpus.c
@@ -1,23 +1,167 @@
-// ================== Check default Cortex CPU on each major architecture
-// RUN: %clang -target armv6m-apple-darwin -arch armv6m -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V6M %s
+// ================== Check default CPU on each major architecture
+// RUN: %clang -target armv4t -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V4T %s
+// RUN: %clang -target arm -march=armv4t -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V4T %s
+// CHECK-V4T: "-cc1"{{.*}} "-triple" "armv4t-{{.*}} "-target-cpu" "arm7tdmi"
+
+// RUN: %clang -target armv4t -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V4T-THUMB %s
+// RUN: %clang -target arm -mthumb -march=armv4t -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V4T-THUMB %s
+// CHECK-V4T-THUMB: "-cc1"{{.*}} "-triple" "thumbv4t-{{.*}} "-target-cpu" "arm7tdmi"
+
+// RUN: %clang -target armv5 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V5 %s
+// RUN: %clang -target arm -march=armv5 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V5 %s
+// RUN: %clang -target armv5t -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V5 %s
+// RUN: %clang -target arm -march=armv5t -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V5 %s
+// CHECK-V5: "-cc1"{{.*}} "-triple" "armv5-{{.*}} "-target-cpu" "arm10tdmi"
+
+// RUN: %clang -target armv5 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V5-THUMB %s
+// RUN: %clang -target armv -march=armv5 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V5-THUMB %s
+// RUN: %clang -target armv5t -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V5-THUMB %s
+// RUN: %clang -target arm -march=armv5 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V5-THUMB %s
+// CHECK-V5-THUMB: "-cc1"{{.*}} "-triple" "thumbv5-{{.*}} "-target-cpu" "arm10tdmi"
+
+// RUN: %clang -target armv5e -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V5E %s
+// RUN: %clang -target arm -march=armv5e -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V5E %s
+// CHECK-V5E: "-cc1"{{.*}} "-triple" "armv5e-{{.*}} "-target-cpu" "arm1022e"
+
+// RUN: %clang -target armv5e -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V5E-THUMB %s
+// RUN: %clang -target arm -march=armv5e -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V5E-THUMB %s
+// CHECK-V5E-THUMB: "-cc1"{{.*}} "-triple" "thumbv5e-{{.*}} "-target-cpu" "arm1022e"
+
+// FIXME %clang -target armv5tej -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V5TEJ %s
+// RUN: %clang -target arm -march=armv5tej -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V5TEJ %s
+// CHECK-V5TEJ: "-cc1"{{.*}} "-triple" "armv5e-{{.*}} "-target-cpu" "arm926ej-s"
+
+// FIXME %clang -target armv5tej -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V5TEJ-THUMB %s
+// RUN: %clang -target arm -march=armv5tej -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V5TEJ-THUMB %s
+// CHECK-V5TEJ-THUMB: "-cc1"{{.*}} "-triple" "thumbv5e-{{.*}} "-target-cpu" "arm926ej-s"
+
+// RUN: %clang -target armv6 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V6 %s
+// RUN: %clang -target arm -march=armv6 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V6 %s
+// CHECK-V6: "-cc1"{{.*}} "-triple" "armv6-{{.*}} "-target-cpu" "arm1136jf-s"
+
+// RUN: %clang -target armv6 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V6-THUMB %s
+// RUN: %clang -target arm -march=armv6 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V6-THUMB %s
+// CHECK-V6-THUMB: "-cc1"{{.*}} "-triple" "thumbv6-{{.*}} "-target-cpu" "arm1136jf-s"
+
+// FIXME %clang -target armv6j -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V6J %s
+// RUN: %clang -target arm -march=armv6j -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V6J %s
+// CHECK-V6J: "-cc1"{{.*}} "-triple" "armv6-{{.*}} "-target-cpu" "arm1136j-s"
+
+// FIXME %clang -target armv6j -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V6J-THUMB %s
+// RUN: %clang -target arm -march=armv6j -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V6J-THUMB %s
+// CHECK-V6J-THUMB: "-cc1"{{.*}} "-triple" "thumbv6-{{.*}} "-target-cpu" "arm1136j-s"
+
+// FIXME %clang -target armv6z -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V6Z %s
+// FIXME %clang -target arm -march=armv6z -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V6Z %s
+// CHECK-V6Z: "-cc1"{{.*}} "-triple" "armv6-{{.*}} "-target-cpu" "arm1176jzf-s"
+
+// FIXME %clang -target armv6z -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V6Z-THUMB %s
+// FIXME %clang -target arm arch=armv6z -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V6Z-THUMB %s
+// CHECK-V6Z-THUMB: "-cc1"{{.*}} "-triple" "thumbv6-{{.*}} "-target-cpu" "arm1176jzfs"
+
+// RUN: %clang -target armv6t2 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V6T2 %s
+// RUN: %clang -target arm -march=armv6t2 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V6T2 %s
+// CHECK-V6T2: "-cc1"{{.*}} "-triple" "armv6t2-{{.*}} "-target-cpu" "arm1156t2-s"
+
+// RUN: %clang -target armv6t2 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V6T2-THUMB %s
+// RUN: %clang -target arm -march=armv6t2 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V6T2-THUMB %s
+// CHECK-V6T2-THUMB: "-cc1"{{.*}} "-triple" "thumbv6t2-{{.*}} "-target-cpu" "arm1156t2-s"
+
+// RUN: %clang -target armv6m -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V6M %s
+// RUN: %clang -target arm -march=armv6m -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V6M %s
 // CHECK-V6M: "-cc1"{{.*}} "-triple" "thumbv6m-{{.*}} "-target-cpu" "cortex-m0"
 
-// RUN: %clang -target armv7m-apple-darwin -arch armv7m -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V7M %s
+// RUN: %clang -target armv6m -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V6M-BIG %s
+// RUN: %clang -target arm -march=armv6m -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V6M-BIG %s
+// CHECK-V6M-BIG: "-cc1"{{.*}} "-triple" "thumbebv6m-{{.*}} "-target-cpu" "cortex-m0"
+
+// RUN: %clang -target armv7m -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V7M %s
+// RUN: %clang -target arm -march=armv7-m -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V7M %s
 // CHECK-V7M: "-cc1"{{.*}} "-triple" "thumbv7m-{{.*}} "-target-cpu" "cortex-m3"
 
-// RUN: %clang -target armv7em-apple-darwin -arch armv7em -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V7EM %s
+// RUN: %clang -target armv7em -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V7EM %s
+// RUN: %clang -target arm -march=armv7e-m -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V7EM %s
 // CHECK-V7EM: "-cc1"{{.*}} "-triple" "thumbv7em-{{.*}} "-target-cpu" "cortex-m4"
 
+// RUN: %clang -target armv7em -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V7EM-BIG %s
+// RUN: %clang -target arm -march=armv7e-m -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V7EM-BIG %s
+// CHECK-V7EM-BIG: "-cc1"{{.*}} "-triple" "thumbebv7em-{{.*}} "-target-cpu" "cortex-m4"
+
+// RUN: %clang -target armv6m-apple-darwin -arch armv6m -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V6M-DARWIN %s
+// CHECK-V6M-DARWIN: "-cc1"{{.*}} "-triple" "thumbv6m-{{.*}} "-target-cpu" "cortex-m0"
+
+// RUN: %clang -target armv7m-apple-darwin -arch armv7m -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V7M-DARWIN %s
+// CHECK-V7M-DARWIN: "-cc1"{{.*}} "-triple" "thumbv7m-{{.*}} "-target-cpu" "cortex-m3"
+
+// RUN: %clang -target armv7em-apple-darwin -arch armv7em -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V7EM-DARWIN %s
+// CHECK-V7EM-DARWIN: "-cc1"{{.*}} "-triple" "thumbv7em-{{.*}} "-target-cpu" "cortex-m4"
+
 // RUN: %clang -target armv7a-linux-gnueabi -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V7A %s
+// RUN: %clang -target arm-linux-gnueabi -march=armv7-a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V7A %s
 // CHECK-V7A: "-cc1"{{.*}} "-triple" "armv7-{{.*}} "-target-cpu" "cortex-a8"
 
+// RUN: %clang -target armv7a-linux-gnueabi -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V7A-THUMB %s
+// RUN: %clang -target arm-linux-gnueabi -march=armv7-a -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V7A-THUMB %s
+// CHECK-V7A-THUMB: "-cc1"{{.*}} "-triple" "thumbv7-{{.*}} "-target-cpu" "cortex-a8"
+
 // RUN: %clang -target armv7r-linux-gnueabi -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V7R %s
+// RUN: %clang -target arm-linux-gnueabi -march=armv7-r -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V7R %s
 // CHECK-V7R: "-cc1"{{.*}} "-triple" "armv7r-{{.*}} "-target-cpu" "cortex-r4"
 
-// RUN: %clang -target armv8  -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8A %s
+// RUN: %clang -target armv7r-linux-gnueabi -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V7R-THUMB %s
+// RUN: %clang -target arm-linux-gnueabi -march=armv7-r -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V7R-THUMB %s
+// CHECK-V7R-THUMB: "-cc1"{{.*}} "-triple" "thumbv7r-{{.*}} "-target-cpu" "cortex-r4"
+
+// RUN: %clang -target armv8 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8A %s
+// RUN: %clang -target arm -march=armv8 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8A %s
 // RUN: %clang -target armv8a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8A %s
+// RUN: %clang -target arm -march=armv8a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8A %s
+// RUN: %clang -target arm -march=armv8-a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8A %s
+// RUN: %clang -target armv8 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8A %s
+// RUN: %clang -target arm -march=armv8 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8A %s
+// RUN: %clang -target armv8a -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8A %s
+// RUN: %clang -target arm -march=armv8a -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8A %s
+// RUN: %clang -target arm -mlittle-endian -march=armv8-a -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8A %s
 // CHECK-V8A: "-cc1"{{.*}} "-triple" "armv8-{{.*}}" "-target-cpu" "cortex-a53"
 
+// RUN: %clang -target armebv8 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V8A %s
+// RUN: %clang -target armeb -march=armebv8 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V8A %s
+// RUN: %clang -target armebv8a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V8A %s
+// RUN: %clang -target armeb -march=armebv8a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V8A %s
+// RUN: %clang -target armeb -march=armebv8-a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V8A %s
+// RUN: %clang -target armv8 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V8A %s
+// RUN: %clang -target arm -march=armebv8 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V8A %s
+// RUN: %clang -target armv8a -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V8A %s
+// RUN: %clang -target arm -march=armebv8a -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V8A %s
+// RUN: %clang -target arm -march=armebv8-a -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V8A %s
+// CHECK-BE-V8A: "-cc1"{{.*}} "-triple" "armebv8-{{.*}}" "-target-cpu" "cortex-a53"
+
+// RUN: %clang -target armv8 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8A-THUMB %s
+// RUN: %clang -target arm -march=armv8 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8A-THUMB %s
+// RUN: %clang -target armv8a -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8A-THUMB %s
+// RUN: %clang -target arm -march=armv8a -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8A-THUMB %s
+// RUN: %clang -target armv8 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8A-THUMB %s
+// RUN: %clang -target arm -march=armv8 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8A-THUMB %s
+// RUN: %clang -target armv8a -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8A-THUMB %s
+// RUN: %clang -target arm -march=armv8a -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-V8A-THUMB %s
+// CHECK-V8A-THUMB: "-cc1"{{.*}} "-triple" "thumbv8-{{.*}}" "-target-cpu" "cortex-a53"
+
+// RUN: %clang -target armebv8 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V8A-THUMB %s
+// RUN: %clang -target armeb -march=armebv8 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V8A-THUMB %s
+// RUN: %clang -target armebv8a -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V8A-THUMB %s
+// RUN: %clang -target armeb -march=armebv8a -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V8A-THUMB %s
+// RUN: %clang -target armv8 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V8A-THUMB %s
+// RUN: %clang -target arm -march=armebv8 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V8A-THUMB %s
+// RUN: %clang -target armv8a -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V8A-THUMB %s
+// RUN: %clang -target arm -march=armebv8a -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-V8A-THUMB %s
+// CHECK-BE-V8A-THUMB: "-cc1"{{.*}} "-triple" "thumbebv8-{{.*}}" "-target-cpu" "cortex-a53"
+
+// ================== Check default CPU on bogus architecture
+// RUN: %clang -target arm -march=armbogusv6 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BOGUS %s
+// CHECK-BOGUS: "-cc1"{{.*}} "-triple" "armv4t-{{.*}} "-target-cpu" "arm7tdmi"
+// RUN: %clang -target arm---eabihf -march=armbogusv7 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BOGUS-HF %s
+// CHECK-BOGUS-HF: "-cc1"{{.*}} "-triple" "armv6-{{.*}} "-target-cpu" "arm1176jzf-s"
+
 // ================== Check default Architecture on each Cortex CPU
 // RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-a5 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7A %s
 // RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-a7 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7A %s
@@ -25,21 +169,119 @@
 // RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-a9 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7A %s
 // RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-a12 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7A %s
 // RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-a15 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7A %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-a5 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7A %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-a7 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7A %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-a8 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7A %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-a9 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7A %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-a12 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7A %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-a15 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7A %s
 // CHECK-CPUV7A: "-cc1"{{.*}} "-triple" "armv7-{{.*}}
 
+// RUN: %clang -target armeb-linux-gnueabi -mcpu=cortex-a5 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7A %s
+// RUN: %clang -target armeb-linux-gnueabi -mcpu=cortex-a7 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7A %s
+// RUN: %clang -target armeb-linux-gnueabi -mcpu=cortex-a8 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7A %s
+// RUN: %clang -target armeb-linux-gnueabi -mcpu=cortex-a9 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7A %s
+// RUN: %clang -target armeb-linux-gnueabi -mcpu=cortex-a12 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7A %s
+// RUN: %clang -target armeb-linux-gnueabi -mcpu=cortex-a15 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7A %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-a5 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7A %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-a7 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7A %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-a8 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7A %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-a9 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7A %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-a12 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7A %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-a15 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7A %s
+// CHECK-BE-CPUV7A: "-cc1"{{.*}} "-triple" "armebv7-{{.*}}
+
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-a5 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7A-THUMB %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-a7 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7A-THUMB %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-a8 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7A-THUMB %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-a9 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7A-THUMB %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-a12 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7A-THUMB %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-a15 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7A-THUMB %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-a5 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7A-THUMB %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-a7 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7A-THUMB %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-a8 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7A-THUMB %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-a9 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7A-THUMB %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-a12 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7A-THUMB %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-a15 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7A-THUMB %s
+// CHECK-CPUV7A-THUMB: "-cc1"{{.*}} "-triple" "thumbv7-{{.*}}
+
+// RUN: %clang -target armeb-linux-gnueabi -mcpu=cortex-a5 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7A-THUMB %s
+// RUN: %clang -target armeb-linux-gnueabi -mcpu=cortex-a7 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7A-THUMB %s
+// RUN: %clang -target armeb-linux-gnueabi -mcpu=cortex-a8 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7A-THUMB %s
+// RUN: %clang -target armeb-linux-gnueabi -mcpu=cortex-a9 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7A-THUMB %s
+// RUN: %clang -target armeb-linux-gnueabi -mcpu=cortex-a12 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7A-THUMB %s
+// RUN: %clang -target armeb-linux-gnueabi -mcpu=cortex-a15 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7A-THUMB %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-a5 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7A-THUMB %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-a7 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7A-THUMB %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-a8 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7A-THUMB %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-a9 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7A-THUMB %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-a12 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7A-THUMB %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-a15 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7A-THUMB %s
+// CHECK-BE-CPUV7A-THUMB: "-cc1"{{.*}} "-triple" "thumbebv7-{{.*}}
+
 // RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-m0 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV6M %s
 // CHECK-CPUV6M: "-cc1"{{.*}} "-triple" "thumbv6m-{{.*}}
 
 // RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-m3 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7M %s
-// CHECK-CPUV7M: "-cc1"{{.*}} "-triple" "armv7m-{{.*}}
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-m3 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7M %s
+// CHECK-CPUV7M: "-cc1"{{.*}} "-triple" "thumbv7m-{{.*}}
+
+// RUN: %clang -target armeb-linux-gnueabi -mcpu=cortex-m3 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7M %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-m3 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7M %s
+// CHECK-BE-CPUV7M: "-cc1"{{.*}} "-triple" "thumbebv7m-{{.*}}
 
 // RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-m4 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7EM %s
-// CHECK-CPUV7EM: "-cc1"{{.*}} "-triple" "armv7em-{{.*}}
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-m4 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7EM %s
+// CHECK-CPUV7EM: "-cc1"{{.*}} "-triple" "thumbv7em-{{.*}}
+
+// RUN: %clang -target armeb-linux-gnueabi -mcpu=cortex-m4 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7EM %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-m4 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7EM %s
+// CHECK-BE-CPUV7EM: "-cc1"{{.*}} "-triple" "thumbebv7em-{{.*}}
 
 // RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r4 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7R %s
 // RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r5 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7R %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r4 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7R %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r5 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7R %s
 // CHECK-CPUV7R: "-cc1"{{.*}} "-triple" "armv7r-{{.*}}
 
+// RUN: %clang -target armeb-linux-gnueabi -mcpu=cortex-r4 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7R %s
+// RUN: %clang -target armeb-linux-gnueabi -mcpu=cortex-r5 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7R %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r4 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7R %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r5 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7R %s
+// CHECK-BE-CPUV7R: "-cc1"{{.*}} "-triple" "armebv7r-{{.*}}
+
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r4 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7R-THUMB %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r5 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7R-THUMB %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r4 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7R-THUMB %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r5 -mlittle-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7R-THUMB %s
+// CHECK-CPUV7R-THUMB: "-cc1"{{.*}} "-triple" "thumbv7r-{{.*}}
+
+// RUN: %clang -target armeb-linux-gnueabi -mcpu=cortex-r4 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7R-THUMB %s
+// RUN: %clang -target armeb-linux-gnueabi -mcpu=cortex-r5 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7R-THUMB %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r4 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7R-THUMB %s
+// RUN: %clang -target arm-linux-gnueabi -mcpu=cortex-r5 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV7R-THUMB %s
+// CHECK-BE-CPUV7R-THUMB: "-cc1"{{.*}} "-triple" "thumbebv7r-{{.*}}
+
 // RUN: %clang -target arm -mcpu=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A %s
 // RUN: %clang -target arm -mcpu=cortex-a57 -### -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
+// RUN: %clang -target arm -mcpu=cortex-a57 -mlittle-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A %s
 // CHECK-CPUV8A: "-cc1"{{.*}} "-triple" "armv8-{{.*}}
+
+// RUN: %clang -target armeb -mcpu=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A %s
+// RUN: %clang -target armeb -mcpu=cortex-a57 -### -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
+// RUN: %clang -target arm -mcpu=cortex-a57 -mbig-endian -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A %s
+// CHECK-BE-CPUV8A: "-cc1"{{.*}} "-triple" "armebv8-{{.*}}
+
+// RUN: %clang -target arm -mcpu=cortex-a53 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV8A-THUMB %s
+// RUN: %clang -target arm -mcpu=cortex-a57 -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
+// RUN: %clang -target arm -mcpu=cortex-a57 -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-a53 -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A-THUMB %s
+// RUN: %clang -target armeb -mcpu=cortex-a57 -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
+// RUN: %clang -target arm -mcpu=cortex-a57 -mbig-endian -mthumb -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BE-CPUV8A-THUMB %s
+// CHECK-BE-CPUV8A-THUMB: "-cc1"{{.*}} "-triple" "thumbebv8-{{.*}}
diff --git a/test/Driver/arm-hwdiv.c b/test/Driver/arm-hwdiv.c
index b3617ce..0b75948 100644
--- a/test/Driver/arm-hwdiv.c
+++ b/test/Driver/arm-hwdiv.c
@@ -37,3 +37,8 @@
 // CHECK-ALT: "-target-feature" "+hwdiv-arm"
 // CHECK-ALT: "-target-feature" "-hwdiv"
 
+// RUN: %clang -### -target arm %s --mhwdiv=arm -o %t.o 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-ALT-EQ %s
+// CHECK-ALT-EQ: "-target-feature" "+hwdiv-arm"
+// CHECK-ALT-EQ: "-target-feature" "-hwdiv"
+
diff --git a/test/Driver/arm-long-calls.c b/test/Driver/arm-long-calls.c
new file mode 100644
index 0000000..62294a0
--- /dev/null
+++ b/test/Driver/arm-long-calls.c
@@ -0,0 +1,15 @@
+// RUN: %clang -target armv7-eabi -### %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-DEFAULT
+
+// RUN: %clang -target armv7-eabi -### -mlong-calls %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-LONG-CALLS
+
+// RUN: %clang -target armv7-eabi -### -mlong-calls -mno-long-calls %s 2>&1 \
+// RUN:    | FileCheck %s -check-prefix CHECK-NO-LONG-CALLS
+
+// CHECK-DEFAULT-NOT: "-backend-option" "-arm-long-calls"
+
+// CHECK-LONG-CALLS: "-backend-option" "-arm-long-calls"
+
+// CHECK-NO-LONG-CALLS-NOT: "-backend-option" "-arm-long-calls"
+
diff --git a/test/Driver/arm-mfpu.c b/test/Driver/arm-mfpu.c
index 765b298..89c2035 100644
--- a/test/Driver/arm-mfpu.c
+++ b/test/Driver/arm-mfpu.c
@@ -39,6 +39,30 @@
 // CHECK-VFP3: "-target-feature" "+vfp3"
 // CHECK-VFP3: "-target-feature" "-neon"
 
+// RUN: %clang -target arm-linux-eabi -mfpu=vfp4 %s -### -o %t.o 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-VFP4 %s
+// RUN: %clang -target arm-linux-eabi -mfpu=vfpv4 %s -### -o %t.o 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-VFP4 %s
+// CHECK-VFP4: "-target-feature" "+vfp4"
+// CHECK-VFP4: "-target-feature" "-neon"
+
+// RUN: %clang -target arm-linux-eabi -mfpu=vfp4-d16 %s -### -o %t.o 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-VFP4-D16 %s
+// RUN: %clang -target arm-linux-eabi -mfpu=vfpv4-d16 %s -### -o %t.o 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-VFP4-D16 %s
+// CHECK-VFP4-D16: "-target-feature" "+vfp4"
+// CHECK-VFP4-D16: "-target-feature" "+d16"
+// CHECK-VFP4-D16: "-target-feature" "-neon"
+
+// RUN: %clang -target arm-linux-eabi -mfpu=fp4-sp-d16 %s -### -o %t.o 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-FP4-SP-D16 %s
+// RUN: %clang -target arm-linux-eabi -mfpu=fpv4-sp-d16 %s -### -o %t.o 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-FP4-SP-D16 %s
+// CHECK-FP4-SP-D16: "-target-feature" "+vfp4"
+// CHECK-FP4-SP-D16: "-target-feature" "+d16"
+// CHECK-FP4-SP-D16: "-target-feature" "+fp-only-sp"
+// CHECK-FP4-SP-D16: "-target-feature" "-neon"
+
 // RUN: %clang -target arm-linux-eabi -mfpu=neon %s -### -o %t.o 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-NEON %s
 // CHECK-NEON: "-target-feature" "+neon"
@@ -47,11 +71,16 @@
 // RUN:   | FileCheck --check-prefix=CHECK-SOFT-FLOAT %s
 // CHECK-SOFT-FLOAT: "-target-feature" "-neon"
 
+// RUN: %clang -target armv8 %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-ARMV8-DEFAULT-SOFT-FP %s
+// CHECK-ARMV8-DEFAULT-SOFT-FP: "-target-feature" "-neon"
+// CHECK-ARMV8-DEFAULT-SOFT-FP: "-target-feature" "-crypto"
+
 // RUN: %clang -target armv8 -mfpu=fp-armv8 %s -### 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-ARMV8-SOFT-FLOAT %s
 // CHECK-ARMV8-SOFT-FLOAT: "-target-feature" "+fp-armv8"
-// CHECK-ARMV8-SOFT-FLOAT: "-target-feature" "-crypto"
 // CHECK-ARMV8-SOFT-FLOAT: "-target-feature" "-neon"
+// CHECK-ARMV8-SOFT-FLOAT: "-target-feature" "-crypto"
 
 // RUN: %clang -target armv8-linux-gnueabihf -mfpu=fp-armv8 %s -### 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-FP-ARMV8 %s
@@ -84,3 +113,7 @@
 // RUN: %clang -target arm-linux-gnueabihf %s -### 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-HF %s
 // CHECK-HF: "-target-cpu" "arm1136jf-s"
+
+// RUN: %clang -target armv7-apple-darwin -x assembler %s -### -c 2>&1 \
+// RUN:   | FileCheck --check-prefix=ASM %s
+// ASM-NOT: -target-feature
diff --git a/test/Driver/arm64-as.s b/test/Driver/arm64-as.s
new file mode 100644
index 0000000..061e5b2
--- /dev/null
+++ b/test/Driver/arm64-as.s
@@ -0,0 +1,5 @@
+// Make sure the arm64 default on cyclone when compiling for apple.
+// RUN: %clang -target arm64-apple-ios -arch arm64 -### -c %s 2>&1 | FileCheck -check-prefix=TARGET %s
+//
+// TARGET: "-cc1as"
+// TARGET: "-target-cpu" "cyclone"
diff --git a/test/Driver/arm64-darwinpcs.c b/test/Driver/arm64-darwinpcs.c
new file mode 100644
index 0000000..8d28552
--- /dev/null
+++ b/test/Driver/arm64-darwinpcs.c
@@ -0,0 +1,3 @@
+// RUN: %clang -target arm64-apple-ios7.0 -### %s 2>&1 | FileCheck %s
+
+// CHECK: "-target-abi" "darwinpcs"
diff --git a/test/Driver/asan.c b/test/Driver/asan.c
index c9b3796..f199e90 100644
--- a/test/Driver/asan.c
+++ b/test/Driver/asan.c
@@ -1,9 +1,8 @@
-// RUN: %clang     -target i386-unknown-unknown -faddress-sanitizer %s -S -emit-llvm -o - | FileCheck %s
-// RUN: %clang -O1 -target i386-unknown-unknown -faddress-sanitizer %s -S -emit-llvm -o - | FileCheck %s
-// RUN: %clang -O2 -target i386-unknown-unknown -faddress-sanitizer %s -S -emit-llvm -o - | FileCheck %s
-// RUN: %clang -O3 -target i386-unknown-unknown -faddress-sanitizer %s -S -emit-llvm -o - | FileCheck %s
-// RUN: %clang     -target i386-unknown-unknown -fsanitize=address  %s -S -emit-llvm -o - | FileCheck %s
-// Verify that -faddress-sanitizer invokes asan instrumentation.
+// RUN: %clang     -target i386-unknown-unknown -fsanitize=address %s -S -emit-llvm -o - | FileCheck %s
+// RUN: %clang -O1 -target i386-unknown-unknown -fsanitize=address %s -S -emit-llvm -o - | FileCheck %s
+// RUN: %clang -O2 -target i386-unknown-unknown -fsanitize=address %s -S -emit-llvm -o - | FileCheck %s
+// RUN: %clang -O3 -target i386-unknown-unknown -fsanitize=address %s -S -emit-llvm -o - | FileCheck %s
+// Verify that -fsanitize=address invokes asan instrumentation.
 
 int foo(int *a) { return *a; }
 // CHECK: __asan_init
diff --git a/test/Driver/at_file_missing.c b/test/Driver/at_file_missing.c
new file mode 100644
index 0000000..0189a8b
--- /dev/null
+++ b/test/Driver/at_file_missing.c
@@ -0,0 +1,7 @@
+// Make sure that arguments that begin with @ are left as is in the argument
+// stream, and also that @file arguments continue to be processed.
+
+// RUN: echo "%s -D FOO" > %t.args
+// RUN: %clang -rpath @executable_path/../lib @%t.args -### 2>&1 | FileCheck %s
+// CHECK: "-D" "FOO"
+// CHECK: "-rpath" "@executable_path/../lib"
diff --git a/test/Driver/bindings.c b/test/Driver/bindings.c
index d25fc8f..dd8ad14 100644
--- a/test/Driver/bindings.c
+++ b/test/Driver/bindings.c
@@ -1,7 +1,7 @@
 // Basic binding.
-// RUN: %clang -target i386-unknown-unknown -ccc-print-bindings %s 2>&1 | FileCheck %s --check-prefix=CHECK01
+// RUN: %clang -target i386-unknown-unknown -ccc-print-bindings -no-integrated-as %s 2>&1 | FileCheck %s --check-prefix=CHECK01
 // CHECK01: "clang", inputs: ["{{.*}}bindings.c"], output: "{{.*}}.s"
-// CHECK01: "gcc::Assemble", inputs: ["{{.*}}.s"], output: "{{.*}}.o"
+// CHECK01: "GNU::Assemble", inputs: ["{{.*}}.s"], output: "{{.*}}.o"
 // CHECK01: "gcc::Link", inputs: ["{{.*}}.o"], output: "a.out"
 
 // Clang control options
diff --git a/test/Driver/bitrig.c b/test/Driver/bitrig.c
index 876a9cd..934cb02 100644
--- a/test/Driver/bitrig.c
+++ b/test/Driver/bitrig.c
@@ -4,14 +4,14 @@
 // CHECK-LD-C: ld{{.*}}" {{.*}} "-lc" "-lclang_rt.amd64"
 
 // RUN: %clangxx -no-canonical-prefixes -target amd64-pc-bitrig %s -### 2>&1 \
-// RUN:   | FileCheck --check-prefix=CHECK-LD-CXX %s
-// CHECK-LD-CXX: clang{{.*}}" "-cc1" "-triple" "amd64-pc-bitrig" 
-// CHECK-LD-CXX: ld{{.*}}" {{.*}} "-lstdc++" "-lm" "-lc" "-lclang_rt.amd64"
-
-// RUN: %clangxx -stdlib=libc++ -no-canonical-prefixes -target amd64-pc-bitrig %s -### 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-LD-CXX-STDLIB %s
 // CHECK-LD-CXX-STDLIB: clang{{.*}}" "-cc1" "-triple" "amd64-pc-bitrig"
-// CHECK-LD-CXX-STDLIB: ld{{.*}}" {{.*}} "-lc++" "-lcxxrt" "-lgcc" "-lm" "-lc" "-lclang_rt.amd64"
+// CHECK-LD-CXX-STDLIB: ld{{.*}}" {{.*}} "-lc++" "-lc++abi" "-lpthread" "-lm" "-lc" "-lclang_rt.amd64"
+
+// RUN: %clangxx -stdlib=libstdc++ -no-canonical-prefixes -target amd64-pc-bitrig %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-LD-CXX %s
+// CHECK-LD-CXX: clang{{.*}}" "-cc1" "-triple" "amd64-pc-bitrig"
+// CHECK-LD-CXX: ld{{.*}}" {{.*}} "-lstdc++" "-lm" "-lc" "-lclang_rt.amd64"
 
 // RUN: %clang -no-canonical-prefixes -target amd64-pc-bitrig -pthread %s -### 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-PTHREAD %s
diff --git a/test/Driver/bounds-checking.c b/test/Driver/bounds-checking.c
deleted file mode 100644
index fdd20ca..0000000
--- a/test/Driver/bounds-checking.c
+++ /dev/null
@@ -1,11 +0,0 @@
-// RUN: %clang -fsanitize=bounds -### -fsyntax-only %s 2> %t
-// RUN: FileCheck -check-prefix=CHECK < %t %s
-// CHECK: "-fsanitize=array-bounds,local-bounds"
-
-// RUN: %clang -fbounds-checking -### -fsyntax-only %s 2> %t
-// RUN: FileCheck -check-prefix=CHECK-OLD < %t %s
-// CHECK-OLD: "-fsanitize=local-bounds"
-
-// RUN: %clang -fbounds-checking=3 -### -fsyntax-only %s 2> %t
-// RUN: FileCheck -check-prefix=CHECK-OLD2 < %t %s
-// CHECK-OLD2: "-fsanitize=local-bounds"
diff --git a/test/Driver/cfi.c b/test/Driver/cfi.c
deleted file mode 100644
index c33d190..0000000
--- a/test/Driver/cfi.c
+++ /dev/null
@@ -1,9 +0,0 @@
-// RUN: %clang -target i386-apple-darwin10 \
-// RUN:    -no-integrated-as -### %s 2>&1 | \
-// RUN:  FileCheck --check-prefix=CHECK-DARWIN %s
-
-// RUN: %clang -target i386-pc-linux-gnu  -static -### %s 2>&1 | \
-// RUN: FileCheck --check-prefix=CHECK-LINUX %s
-
-// CHECK-DARWIN: -fno-dwarf2-cfi-asm
-// CHECK-LINUX-NOT: -fno-dwarf2-cfi-asm
diff --git a/test/Driver/cl-eh.cpp b/test/Driver/cl-eh.cpp
new file mode 100644
index 0000000..8a3450a
--- /dev/null
+++ b/test/Driver/cl-eh.cpp
@@ -0,0 +1,24 @@
+// Don't attempt slash switches on msys bash.
+// REQUIRES: shell-preserves-root
+
+// Note: %s must be preceded by --, otherwise it may be interpreted as a
+// command-line option, e.g. on Mac where %s is commonly under /Users.
+
+// RUN: %clang_cl /c /EHsc -### -- %s 2>&1 | FileCheck -check-prefix=EHsc %s
+// EHsc: "-fexceptions"
+
+// RUN: %clang_cl /c /EHs-c- -### -- %s 2>&1 | FileCheck -check-prefix=EHs_c_ %s
+// EHs_c_-NOT: "-fexceptions"
+
+// RUN: %clang_cl /c /EHs- /EHc- -### -- %s 2>&1 | FileCheck -check-prefix=EHs_EHc_ %s
+// EHs_EHc_-NOT: "-fexceptions"
+
+// RUN: %clang_cl /c /EHs- /EHs -### -- %s 2>&1 | FileCheck -check-prefix=EHs_EHs %s
+// EHs_EHs: "-fexceptions"
+
+// RUN: %clang_cl /c /EHs- /EHsa -### -- %s 2>&1 | FileCheck -check-prefix=EHs_EHa %s
+// EHs_EHa: "-fexceptions"
+
+// RUN: %clang_cl /c /EHinvalid -### -- %s 2>&1 | FileCheck -check-prefix=EHinvalid %s
+// EHinvalid: error: invalid value 'invalid' in '/EH'
+// EHinvalid-NOT: error:
diff --git a/test/Driver/cl-fallback.c b/test/Driver/cl-fallback.c
index 2433072..bbc9ad8 100644
--- a/test/Driver/cl-fallback.c
+++ b/test/Driver/cl-fallback.c
@@ -4,8 +4,10 @@
 // Note: %s must be preceded by --, otherwise it may be interpreted as a
 // command-line option, e.g. on Mac where %s is commonly under /Users.
 
-// RUN: %clang_cl /fallback /Dfoo=bar /Ubaz /Ifoo /O0 /Ox /GR /GR- /LD /LDd \
-// RUN:     /MD /MDd /MTd /MT /FImyheader.h -### -- %s 2>&1 | FileCheck %s
+// RUN: %clang_cl /fallback /Dfoo=bar /Ubaz /Ifoo /O0 /Ox /GR /GR- /Gy /Gy- \
+// RUN:   /Gw /Gw- /LD /LDd /EHs /EHs- /MD /MDd /MTd /MT /FImyheader.h /Zi \
+// RUN:   -### -- %s 2>&1 \
+// RUN:   | FileCheck %s
 // CHECK: "-fdiagnostics-format" "msvc-fallback"
 // CHECK: ||
 // CHECK: cl.exe
@@ -17,13 +19,22 @@
 // CHECK: "-I" "foo"
 // CHECK: "/Ox"
 // CHECK: "/GR-"
+// CHECK: "/Gy-"
+// CHECK: "/Gw-"
+// CHECK: "/Z7"
 // CHECK: "/FImyheader.h"
 // CHECK: "/LD"
 // CHECK: "/LDd"
+// CHECK: "/EHs"
+// CHECK: "/EHs-"
 // CHECK: "/MT"
 // CHECK: "/Tc" "{{.*cl-fallback.c}}"
 // CHECK: "/Fo{{.*cl-fallback.*.obj}}"
 
+// RUN: %clang_cl /fallback /GR- -### -- %s 2>&1 | FileCheck -check-prefix=GR %s
+// GR: cl.exe
+// GR: "/GR-"
+
 // RUN: %clang_cl /fallback /Od -### -- %s 2>&1 | FileCheck -check-prefix=O0 %s
 // O0: cl.exe
 // O0: "/Od"
@@ -39,3 +50,28 @@
 // RUN: %clang_cl /fallback /Ox -### -- %s 2>&1 | FileCheck -check-prefix=Ox %s
 // Ox: cl.exe
 // Ox: "/Ox"
+
+// Only fall back when actually compiling, not for e.g. /P (preprocess).
+// RUN: %clang_cl /fallback /P -### -- %s 2>&1 | FileCheck -check-prefix=P %s
+// P-NOT: ||
+// P-NOT: "cl.exe"
+
+// RUN: not %clang_cl /fallback /c -- %s 2>&1 | \
+// RUN:     FileCheck -check-prefix=ErrWarn %s
+// ErrWarn: warning: falling back to {{.*}}cl.exe
+
+// RUN: %clang_cl /fallback /c /GR /GR- -### -- %s 2>&1 | \
+// RUN:     FileCheck -check-prefix=NO_RTTI %s
+// NO_RTTI: "-cc1"
+// NO_RTTI: ||
+// NO_RTTI: cl.exe
+// NO_RTTI: "/GR-"
+
+// Don't fall back on non-C or C++ files.
+// RUN: %clang_cl /fallback -### -- %S/Inputs/file.ll 2>&1 | FileCheck -check-prefix=LL %s
+// LL: file.ll
+// LL-NOT: ||
+// LL-NOT: "cl.exe"
+
+
+#error "This fails to compile."
diff --git a/test/Driver/cl-inputs.c b/test/Driver/cl-inputs.c
index d6ee520..029aead 100644
--- a/test/Driver/cl-inputs.c
+++ b/test/Driver/cl-inputs.c
@@ -33,3 +33,20 @@
 // WARN: warning: overriding '/TC' option with '/TP'
 // WARN: note: The last /TC or /TP option takes precedence over earlier instances
 // WARN-NOT: note
+
+// RUN: not %clang_cl - 2>&1 | FileCheck -check-prefix=STDIN %s
+// STDIN: error: use /Tc or /Tp
+
+// RUN: %clang_cl -### /Tc - 2>&1 | FileCheck -check-prefix=STDINTc %s
+// STDINTc: "-x" "c"
+
+// RUN: env LIB=%S/Inputs/cl-libs %clang_cl -### -- %s cl-test.lib 2>&1 | FileCheck -check-prefix=LIBINPUT %s
+// LIBINPUT: link.exe"
+// LIBINPUT: "cl-test.lib"
+
+// RUN: env LIB=%S/Inputs/cl-libs %clang_cl -### -- %s cl-test2.lib 2>&1 | FileCheck -check-prefix=LIBINPUT2 %s
+// LIBINPUT2: error: no such file or directory: 'cl-test2.lib'
+// LIBINPUT2: link.exe"
+// LIBINPUT2-NOT: "cl-test2.lib"
+
+void f();
diff --git a/test/Driver/cl-link.c b/test/Driver/cl-link.c
index 24e0702..f471746 100644
--- a/test/Driver/cl-link.c
+++ b/test/Driver/cl-link.c
@@ -16,6 +16,7 @@
 // ASAN: "-debug"
 // ASAN: "-incremental:no"
 // ASAN: "{{.*}}clang_rt.asan-i386.lib"
+// ASAN: "{{.*}}clang_rt.asan_cxx-i386.lib"
 // ASAN: "{{.*}}cl-link{{.*}}.obj"
 
 // RUN: %clang_cl /LD -### /Tc%s 2>&1 | FileCheck --check-prefix=DLL %s
@@ -31,3 +32,7 @@
 // ASAN-DLL: "-incremental:no"
 // ASAN-DLL: "{{.*}}clang_rt.asan_dll_thunk-i386.lib"
 // ASAN-DLL: "{{.*}}cl-link{{.*}}.obj"
+
+// RUN: %clang_cl /Zi /Tc%s -### 2>&1 | FileCheck --check-prefix=DEBUG %s
+// DEBUG: link.exe
+// DEBUG: "-debug"
diff --git a/test/Driver/cl-options.c b/test/Driver/cl-options.c
index 01032bb..26cd7e9 100644
--- a/test/Driver/cl-options.c
+++ b/test/Driver/cl-options.c
@@ -7,19 +7,47 @@
 
 // Alias options:
 
-// RUN: %clang_cl /c -### -- %s 2>&1 | FileCheck -check-prefix=C %s
-// C: -c
+// RUN: %clang_cl /c -### -- %s 2>&1 | FileCheck -check-prefix=c %s
+// c: -c
+
+// RUN: %clang_cl /C -### -- %s 2>&1 | FileCheck -check-prefix=C %s
+// C: error: invalid argument '-C' only allowed with '/E, /P or /EP'
+
+// RUN: %clang_cl /C /P -### -- %s 2>&1 | FileCheck -check-prefix=C_P %s
+// C_P: "-E"
+// C_P: "-C"
 
 // RUN: %clang_cl /Dfoo=bar -### -- %s 2>&1 | FileCheck -check-prefix=D %s
 // RUN: %clang_cl /D foo=bar -### -- %s 2>&1 | FileCheck -check-prefix=D %s
 // D: "-D" "foo=bar"
 
+// RUN: %clang_cl /E -### -- %s 2>&1 | FileCheck -check-prefix=E %s
+// E: "-E"
+// E: "-o" "-"
+
+// RUN: %clang_cl /EP -### -- %s 2>&1 | FileCheck -check-prefix=EP %s
+// EP: "-E"
+// EP: "-P"
+// EP: "-o" "-"
+
 // RTTI is on by default; just check that we don't error.
 // RUN: %clang_cl /Zs /GR -- %s 2>&1
 
 // RUN: %clang_cl /GR- -### -- %s 2>&1 | FileCheck -check-prefix=GR_ %s
 // GR_: -fno-rtti
 
+// RUN: %clang_cl /Gy -### -- %s 2>&1 | FileCheck -check-prefix=Gy %s
+// Gy: -ffunction-sections
+
+// RUN: %clang_cl /Gy /Gy- -### -- %s 2>&1 | FileCheck -check-prefix=Gy_ %s
+// Gy_-NOT: -ffunction-sections
+
+// RUN: %clang_cl /Gw -### -- %s 2>&1 | FileCheck -check-prefix=Gw %s
+// Gw: -fdata-sections
+
+// RUN: %clang_cl /Gw /Gw- -### -- %s 2>&1 | FileCheck -check-prefix=Gw_ %s
+// Gw_-NOT: -fdata-sections
+
 // RUN: %clang_cl /Imyincludedir -### -- %s 2>&1 | FileCheck -check-prefix=SLASH_I %s
 // RUN: %clang_cl /I myincludedir -### -- %s 2>&1 | FileCheck -check-prefix=SLASH_I %s
 // SLASH_I: "-I" "myincludedir"
@@ -56,16 +84,38 @@
 // RUN: %clang_cl /Oy- -### -- %s 2>&1 | FileCheck -check-prefix=Oy_ %s
 // Oy_: -mdisable-fp-elim
 
-// RUN: %clang_cl /P -### -- %s 2>&1 | FileCheck -check-prefix=P %s
-// P: -E
-
 // RUN: %clang_cl /showIncludes -### -- %s 2>&1 | FileCheck -check-prefix=showIncludes %s
 // showIncludes: --show-includes
 
+// RUN: %clang_cl /E /showIncludes -### -- %s 2>&1 | FileCheck -check-prefix=showIncludes_E %s
+// RUN: %clang_cl /EP /showIncludes -### -- %s 2>&1 | FileCheck -check-prefix=showIncludes_E %s
+// showIncludes_E: warning: argument unused during compilation: '--show-includes'
+
 // RUN: %clang_cl /Umymacro -### -- %s 2>&1 | FileCheck -check-prefix=U %s
 // RUN: %clang_cl /U mymacro -### -- %s 2>&1 | FileCheck -check-prefix=U %s
 // U: "-U" "mymacro"
 
+// RUN: %clang_cl /vd2 -### -- %s 2>&1 | FileCheck -check-prefix=VD2 %s
+// VD2: -vtordisp-mode=2
+
+// RUN: %clang_cl /vmg -### -- %s 2>&1 | FileCheck -check-prefix=VMG %s
+// VMG: "-fms-memptr-rep=virtual"
+
+// RUN: %clang_cl /vmg /vms -### -- %s 2>&1 | FileCheck -check-prefix=VMS %s
+// VMS: "-fms-memptr-rep=single"
+
+// RUN: %clang_cl /vmg /vmm -### -- %s 2>&1 | FileCheck -check-prefix=VMM %s
+// VMM: "-fms-memptr-rep=multiple"
+
+// RUN: %clang_cl /vmg /vmv -### -- %s 2>&1 | FileCheck -check-prefix=VMV %s
+// VMV: "-fms-memptr-rep=virtual"
+
+// RUN: %clang_cl /vmg /vmb -### -- %s 2>&1 | FileCheck -check-prefix=VMB %s
+// VMB: '/vmg' not allowed with '/vmb'
+
+// RUN: %clang_cl /vmg /vmm /vms -### -- %s 2>&1 | FileCheck -check-prefix=VMX %s
+// VMX: '/vms' not allowed with '/vmm'
+
 // RUN: %clang_cl /W0 -### -- %s 2>&1 | FileCheck -check-prefix=W0 %s
 // W0: -w
 
@@ -99,10 +149,22 @@
 // WJoined: "-cc1"
 // WJoined: "-Wunused-pragmas"
 
+// We recognize -f[no-]strict-aliasing.
+// RUN: %clang_cl -c -### -- %s 2>&1 | FileCheck -check-prefix=DEFAULTSTRICT %s
+// DEFAULTSTRICT: "-relaxed-aliasing"
+// RUN: %clang_cl -c -fstrict-aliasing -### -- %s 2>&1 | FileCheck -check-prefix=STRICT %s
+// STRICT-NOT: "-relaxed-aliasing"
+// RUN: %clang_cl -c -fno-strict-aliasing -### -- %s 2>&1 | FileCheck -check-prefix=NOSTRICT %s
+// NOSTRICT: "-relaxed-aliasing"
+
+// For some warning ids, we can map from MSVC warning to Clang warning.
+// RUN: %clang_cl -wd4005 -### -- %s 2>&1 | FileCheck -check-prefix=wd4005 %s
+// wd4005: "-cc1"
+// wd4005: "-Wno-macro-redefined"
 
 // Ignored options. Check that we don't get "unused during compilation" errors.
-// (/Zs is for syntax-only, /WX is for -Werror)
-// RUN: %clang_cl /Zs /WX \
+// (/Zs is for syntax-only)
+// RUN: %clang_cl /Zs \
 // RUN:    /analyze- \
 // RUN:    /errorReport:foo \
 // RUN:    /FS \
@@ -120,7 +182,10 @@
 // RUN:    /wd1234 \
 // RUN:    /Zc:forScope \
 // RUN:    /Zc:wchar_t \
-// RUN:    -- %s
+// RUN:    /Zc:inline \
+// RUN:    /Zc:rvalueCast \
+// RUN:    -### -- %s 2>&1 | FileCheck -check-prefix=IGNORED %s
+// IGNORED-NOT: argument unused during compilation
 
 // Ignored options and compile-only options are ignored for link jobs.
 // RUN: touch %t.obj
@@ -131,18 +196,16 @@
 
 // Support ignoring warnings about unused arguments.
 // RUN: %clang_cl /Abracadabra -Qunused-arguments -### -- %s 2>&1 | FileCheck -check-prefix=UNUSED %s
-// UNUSED-NOT: warning
+// UNUSED-NOT: argument unused during compilation
 
 // Unsupported but parsed options. Check that we don't error on them.
 // (/Zs is for syntax-only)
 // RUN: %clang_cl /Zs \
 // RUN:     /AIfoo \
-// RUN:     /arch:sse2 \
 // RUN:     /clr:pure \
 // RUN:     /docname \
-// RUN:     /E \
+// RUN:     /d2Zi+ \
 // RUN:     /EHsc \
-// RUN:     /EP \
 // RUN:     /F \
 // RUN:     /FA \
 // RUN:     /FAc \
@@ -176,8 +239,6 @@
 // RUN:     /Gs1000 \
 // RUN:     /GT \
 // RUN:     /GX \
-// RUN:     /Gy \
-// RUN:     /Gy- \
 // RUN:     /Gz \
 // RUN:     /GZ \
 // RUN:     /H \
@@ -196,11 +257,6 @@
 // RUN:     /Qvec-report:2 \
 // RUN:     /u \
 // RUN:     /V \
-// RUN:     /vd2 \
-// RUN:     /vmb \
-// RUN:     /vmm \
-// RUN:     /vms \
-// RUN:     /vmv \
 // RUN:     /volatile \
 // RUN:     /wfoo \
 // RUN:     /WL \
@@ -223,6 +279,7 @@
 // RUN:     /ZI \
 // RUN:     /Zl \
 // RUN:     /Zp \
+// RUN:     /Zp1 \
 // RUN:     /ZW:nostdlib \
 // RUN:     -- %s 2>&1
 
@@ -231,8 +288,25 @@
 // Xclang: "-cc1"
 // Xclang: "hellocc1"
 
-// We support -m32 and -m64.
-// RUN: %clang_cl /Zs /WX -m32 -m64 -- %s
+// RTTI is on by default. /GR- controls -fno-rtti-data.
+// RUN: %clang_cl /c /GR- -### -- %s 2>&1 | FileCheck -check-prefix=NoRTTI %s
+// NoRTTI: "-fno-rtti-data"
+// NoRTTI-NOT: "-fno-rtti"
+// RUN: %clang_cl /c /GR -### -- %s 2>&1 | FileCheck -check-prefix=RTTI %s
+// RTTI-NOT: "-fno-rtti-data"
+// RTTI-NOT: "-fno-rtti"
+
+// Accept "core" clang options.
+// (/Zs is for syntax-only)
+// RUN: %clang_cl \
+// RUN:     --driver-mode=cl \
+// RUN:     -ferror-limit=10 \
+// RUN:     -fmsc-version=1800 \
+// RUN:     -fno-strict-aliasing \
+// RUN:     -fstrict-aliasing \
+// RUN:     -mllvm -disable-llvm-optzns \
+// RUN:     -Wunused-variables \
+// RUN:     /Zs -- %s 2>&1
 
 
 void f() { }
diff --git a/test/Driver/cl-outputs.c b/test/Driver/cl-outputs.c
index 2ceaa85..46502f6 100644
--- a/test/Driver/cl-outputs.c
+++ b/test/Driver/cl-outputs.c
@@ -105,3 +105,15 @@
 // FaDIRNAMEEXT:  "-o" "foo.dir{{[/\\]+}}a.ext"
 // RUN: %clang_cl /Faa.asm -### -- %s %s 2>&1 | FileCheck -check-prefix=FaMULTIPLESOURCE %s
 // FaMULTIPLESOURCE: error: cannot specify '/Faa.asm' when compiling multiple source files
+
+// RUN: %clang_cl /P -### -- %s 2>&1 | FileCheck -check-prefix=P %s
+// P: "-E"
+// P: "-o" "cl-outputs.i"
+
+// RUN: %clang_cl /P /Fifoo -### -- %s 2>&1 | FileCheck -check-prefix=Fi1 %s
+// Fi1: "-E"
+// Fi1: "-o" "foo.i"
+
+// RUN: %clang_cl /P /Fifoo.x -### -- %s 2>&1 | FileCheck -check-prefix=Fi2 %s
+// Fi2: "-E"
+// Fi2: "-o" "foo.x"
diff --git a/test/Driver/cl-x86-flags.c b/test/Driver/cl-x86-flags.c
new file mode 100644
index 0000000..62083db
--- /dev/null
+++ b/test/Driver/cl-x86-flags.c
@@ -0,0 +1,83 @@
+// Don't attempt slash switches on msys bash.
+// REQUIRES: shell-preserves-root
+// REQUIRES: x86-registered-target
+
+// We support -m32 and -m64.  We support all x86 CPU feature flags in gcc's -m
+// flag space.
+// RUN: %clang_cl /Zs /WX -m32 -m64 -msse3 -msse4.1 -mavx -mno-avx \
+// RUN:     --target=i386-pc-win32 -### -- 2>&1 %s | FileCheck -check-prefix=MFLAGS %s
+// MFLAGS-NOT: argument unused during compilation
+
+// -arch:IA32 is no-op.
+// RUN: %clang_cl -m32 -arch:IA32 -### -- 2>&1 %s | FileCheck -check-prefix=IA32 %s
+// IA32-NOT: argument unused during compilation
+// IA32-NOT: -target-feature
+
+// RUN: %clang_cl -m32 -arch:ia32 -### -- 2>&1 %s | FileCheck -check-prefix=ia32 %s
+// ia32: argument unused during compilation
+// ia32-NOT: -target-feature
+
+// RUN: %clang_cl -m64 -arch:IA32 -### -- 2>&1 %s | FileCheck -check-prefix=IA3264 %s
+// IA3264: argument unused during compilation
+// IA3264-NOT: -target-feature
+
+// RUN: %clang_cl -m32 -arch:SSE -### -- 2>&1 %s | FileCheck -check-prefix=SSE %s
+// SSE: -target-feature
+// SSE: +sse
+// SSE-NOT: argument unused during compilation
+
+// RUN: %clang_cl -m32 -arch:sse -### -- 2>&1 %s | FileCheck -check-prefix=sse %s
+// sse: argument unused during compilation
+// sse-NOT: -target-feature
+
+// RUN: %clang_cl -m32 -arch:SSE2 -### -- 2>&1 %s | FileCheck -check-prefix=SSE2 %s
+// SSE2: -target-feature
+// SSE2: +sse2
+// SSE2-NOT: argument unused during compilation
+
+// RUN: %clang_cl -m32 -arch:sse2 -### -- 2>&1 %s | FileCheck -check-prefix=sse %s
+// sse2: argument unused during compilation
+// sse2-NOT: -target-feature
+
+// RUN: %clang_cl -m64 -arch:SSE -### -- 2>&1 %s | FileCheck -check-prefix=SSE64 %s
+// SSE64: argument unused during compilation
+// SSE64-NOT: -target-feature
+
+// RUN: %clang_cl -m64 -arch:SSE2 -### -- 2>&1 %s | FileCheck -check-prefix=SSE264 %s
+// SSE264: argument unused during compilation
+// SSE264-NOT: -target-feature
+
+// RUN: %clang_cl -m32 -arch:AVX -### -- 2>&1 %s | FileCheck -check-prefix=AVX %s
+// AVX: -target-feature
+// AVX: +avx
+
+// RUN: %clang_cl -m32 -arch:avx -### -- 2>&1 %s | FileCheck -check-prefix=avx %s
+// avx: argument unused during compilation
+// avx-NOT: -target-feature
+
+// RUN: %clang_cl -m32 -arch:AVX2 -### -- 2>&1 %s | FileCheck -check-prefix=AVX2 %s
+// AVX2: -target-feature
+// AVX2: +avx2
+
+// RUN: %clang_cl -m32 -arch:avx2 -### -- 2>&1 %s | FileCheck -check-prefix=avx2 %s
+// avx2: argument unused during compilation
+// avx2-NOT: -target-feature
+
+// RUN: %clang_cl -m64 -arch:AVX -### -- 2>&1 %s | FileCheck -check-prefix=AVX64 %s
+// AVX64: -target-feature
+// AVX64: +avx
+
+// RUN: %clang_cl -m64 -arch:avx -### -- 2>&1 %s | FileCheck -check-prefix=avx64 %s
+// avx64: argument unused during compilation
+// avx64-NOT: -target-feature
+
+// RUN: %clang_cl -m64 -arch:AVX2 -### -- 2>&1 %s | FileCheck -check-prefix=AVX264 %s
+// AVX264: -target-feature
+// AVX264: +avx2
+
+// RUN: %clang_cl -m64 -arch:avx2 -### -- 2>&1 %s | FileCheck -check-prefix=avx264 %s
+// avx264: argument unused during compilation
+// avx264-NOT: -target-feature
+
+void f() {
+}
diff --git a/test/Driver/cl.c b/test/Driver/cl.c
index 4fd4064..855cdc8 100644
--- a/test/Driver/cl.c
+++ b/test/Driver/cl.c
@@ -31,5 +31,4 @@
 // CL-NOT: -fapple-kext
 
 // RUN: %clang_cl /c -### -- %s 2>&1 | FileCheck -check-prefix=COMPILE %s
-// COMPILE: "-cxx-abi" "microsoft"
 // COMPILE: "-fdiagnostics-format" "msvc"
diff --git a/test/Driver/clang-g-opts.c b/test/Driver/clang-g-opts.c
index 9ca1fd3..a9566b7 100644
--- a/test/Driver/clang-g-opts.c
+++ b/test/Driver/clang-g-opts.c
@@ -2,15 +2,23 @@
 // RUN: %clang -### -S %s -g -target x86_64-linux-gnu 2>&1 \
 // RUN:             | FileCheck --check-prefix=CHECK-WITH-G %s
 // RUN: %clang -### -S %s -g -target x86_64-apple-darwin 2>&1 \
-// RUN:             | FileCheck --check-prefix=CHECK-WITH-G-DARWIN %s
+// RUN:             | FileCheck --check-prefix=CHECK-WITH-G-DWARF2 %s
+// RUN: %clang -### -S %s -g -target i686-pc-openbsd 2>&1 \
+// RUN:             | FileCheck --check-prefix=CHECK-WITH-G-DWARF2 %s
+// RUN: %clang -### -S %s -g -target x86_64-pc-freebsd10.0 2>&1 \
+// RUN:             | FileCheck --check-prefix=CHECK-WITH-G-DWARF2 %s
 // RUN: %clang -### -S %s -g0    2>&1 | FileCheck --check-prefix=CHECK-WITHOUT-G %s
 // RUN: %clang -### -S %s -g -g0 2>&1 | FileCheck --check-prefix=CHECK-WITHOUT-G %s
 // RUN: %clang -### -S %s -g0 -g -target x86_64-linux-gnu 2>&1 \
 // RUN:             | FileCheck --check-prefix=CHECK-WITH-G %s
 // RUN: %clang -### -S %s -g0 -g -target x86_64-apple-darwin 2>&1 \
-// RUN:             | FileCheck --check-prefix=CHECK-WITH-G-DARWIN %s
+// RUN:             | FileCheck --check-prefix=CHECK-WITH-G-DWARF2 %s
+// RUN: %clang -### -S %s -g0 -g -target i686-pc-openbsd 2>&1 \
+// RUN:             | FileCheck --check-prefix=CHECK-WITH-G-DWARF2 %s
+// RUN: %clang -### -S %s -g0 -g -target x86_64-pc-freebsd10.0 2>&1 \
+// RUN:             | FileCheck --check-prefix=CHECK-WITH-G-DWARF2 %s
 
 // CHECK-WITHOUT-G-NOT: "-g"
 // CHECK-WITH-G: "-g"
-// CHECK-WITH-G-DARWIN: "-gdwarf-2"
+// CHECK-WITH-G-DWARF2: "-gdwarf-2"
 
diff --git a/test/Driver/clang-translation.c b/test/Driver/clang-translation.c
index 0930384..9db23a0 100644
--- a/test/Driver/clang-translation.c
+++ b/test/Driver/clang-translation.c
@@ -71,6 +71,12 @@
 // PPCPWR7: "-target-cpu" "pwr7"
 
 // RUN: %clang -target powerpc64-unknown-linux-gnu \
+// RUN: -### -S %s -mcpu=power8 2>&1 | FileCheck -check-prefix=PPCPWR8 %s
+// PPCPWR8: clang
+// PPCPWR8: "-cc1"
+// PPCPWR8: "-target-cpu" "pwr8"
+
+// RUN: %clang -target powerpc64-unknown-linux-gnu \
 // RUN: -### -S %s -mcpu=a2q 2>&1 | FileCheck -check-prefix=PPCA2Q %s
 // PPCA2Q: clang
 // PPCA2Q: "-cc1"
@@ -203,11 +209,62 @@
 // AMD64-MINGW: clang
 // AMD64-MINGW: "-cc1"
 // AMD64-MINGW: "-triple"
-// AMD64-MINGW: "amd64--mingw32"
+// AMD64-MINGW: "amd64--windows-gnu"
 // AMD64-MINGW: "-munwind-tables"
 
-// RUN: %clang -target i386-linux-android -### -S %s 2>&1 \
+// RUN: %clang -target i686-linux-android -### -S %s 2>&1 \
 // RUN:        --sysroot=%S/Inputs/basic_android_tree/sysroot \
 // RUN:   | FileCheck --check-prefix=ANDROID-X86 %s
 // ANDROID-X86: clang
-// ANDROID-X86: "-target-cpu" "core2"
+// ANDROID-X86: "-target-cpu" "i686"
+// ANDROID-X86: "-target-feature" "+ssse3"
+
+// RUN: %clang -target x86_64-linux-android -### -S %s 2>&1 \
+// RUN:        --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:   | FileCheck --check-prefix=ANDROID-X86_64 %s
+// ANDROID-X86_64: clang
+// ANDROID-X86_64: "-target-cpu" "x86-64"
+// ANDROID-X86_64: "-target-feature" "+sse4.2"
+// ANDROID-X86_64: "-target-feature" "+popcnt"
+
+// RUN: %clang -target mips-linux-gnu -### -S %s 2>&1 | \
+// RUN: FileCheck -check-prefix=MIPS %s
+// MIPS: clang
+// MIPS: "-cc1"
+// MIPS: "-target-cpu" "mips32r2"
+// MIPS: "-mfloat-abi" "hard"
+
+// RUN: %clang -target mipsel-linux-gnu -### -S %s 2>&1 | \
+// RUN: FileCheck -check-prefix=MIPSEL %s
+// MIPSEL: clang
+// MIPSEL: "-cc1"
+// MIPSEL: "-target-cpu" "mips32r2"
+// MIPSEL: "-mfloat-abi" "hard"
+
+// RUN: %clang -target mipsel-linux-android -### -S %s 2>&1 | \
+// RUN: FileCheck -check-prefix=MIPSEL-ANDROID %s
+// MIPSEL-ANDROID: clang
+// MIPSEL-ANDROID: "-cc1"
+// MIPSEL-ANDROID: "-target-cpu" "mips32r2"
+// MIPSEL-ANDROID: "-mfloat-abi" "hard"
+
+// RUN: %clang -target mips64-linux-gnu -### -S %s 2>&1 | \
+// RUN: FileCheck -check-prefix=MIPS64 %s
+// MIPS64: clang
+// MIPS64: "-cc1"
+// MIPS64: "-target-cpu" "mips64r2"
+// MIPS64: "-mfloat-abi" "hard"
+
+// RUN: %clang -target mips64el-linux-gnu -### -S %s 2>&1 | \
+// RUN: FileCheck -check-prefix=MIPS64EL %s
+// MIPS64EL: clang
+// MIPS64EL: "-cc1"
+// MIPS64EL: "-target-cpu" "mips64r2"
+// MIPS64EL: "-mfloat-abi" "hard"
+
+// RUN: %clang -target mips64el-linux-android -### -S %s 2>&1 | \
+// RUN: FileCheck -check-prefix=MIPS64EL-ANDROID %s
+// MIPS64EL-ANDROID: clang
+// MIPS64EL-ANDROID: "-cc1"
+// MIPS64EL-ANDROID: "-target-cpu" "mips64r2"
+// MIPS64EL-ANDROID: "-mfloat-abi" "hard"
diff --git a/test/Driver/clang_f_opts.c b/test/Driver/clang_f_opts.c
index 8bf53e5..796da76 100644
--- a/test/Driver/clang_f_opts.c
+++ b/test/Driver/clang_f_opts.c
@@ -1,3 +1,5 @@
+// REQUIRES: clang-driver
+
 // RUN: %clang -### -S -fasm -fblocks -fbuiltin -fno-math-errno -fcommon -fpascal-strings -fno-blocks -fno-builtin -fmath-errno -fno-common -fno-pascal-strings -fblocks -fbuiltin -fmath-errno -fcommon -fpascal-strings -fsplit-stack %s 2>&1 | FileCheck -check-prefix=CHECK-OPTIONS1 %s
 // RUN: %clang -### -S -fasm -fblocks -fbuiltin -fno-math-errno -fcommon -fpascal-strings -fno-asm -fno-blocks -fno-builtin -fmath-errno -fno-common -fno-pascal-strings -fno-show-source-location -fshort-enums -fshort-wchar %s 2>&1 | FileCheck -check-prefix=CHECK-OPTIONS2 %s
 
@@ -6,8 +8,8 @@
 // CHECK-OPTIONS1: -fblocks
 // CHECK-OPTIONS1: -fpascal-strings
 
-// CHECK_OPTIONS2: -fno-gnu-keywords
 // CHECK-OPTIONS2: -fmath-errno
+// CHECK-OPTIONS2: -fno-gnu-keywords
 // CHECK-OPTIONS2: -fno-builtin
 // CHECK-OPTIONS2: -fshort-enums
 // CHECK-OPTIONS2: -fshort-wchar
@@ -15,11 +17,11 @@
 // CHECK-OPTIONS2: -fno-show-source-location
 
 // RUN: %clang -### -S -Wwrite-strings %s 2>&1 | FileCheck -check-prefix=WRITE-STRINGS1 %s
-// RUN: %clang -### -S -Weverything %s 2>&1 | FileCheck -check-prefix=WRITE-STRINGS1 %s
 // WRITE-STRINGS1: -fconst-strings
 // RUN: %clang -### -S -Wwrite-strings -Wno-write-strings %s 2>&1 | FileCheck -check-prefix=WRITE-STRINGS2 %s
-// RUN: %clang -### -S -Wwrite-strings -w %s 2>&1 | FileCheck -check-prefix=WRITE-STRINGS2 %s
 // WRITE-STRINGS2-NOT: -fconst-strings
+// RUN: %clang -### -S -Wwrite-strings -w %s 2>&1 | FileCheck -check-prefix=WRITE-STRINGS3 %s
+// WRITE-STRINGS3-NOT: -fconst-strings
 
 // RUN: %clang -### -x c++ -c %s 2>&1 | FileCheck -check-prefix=DEPRECATED-ON-CHECK %s
 // RUN: %clang -### -x c++ -c -Wdeprecated %s 2>&1 | FileCheck -check-prefix=DEPRECATED-ON-CHECK %s
@@ -54,6 +56,9 @@
 // RUN: %clang -### -S -fprofile-sample-use=%S/Inputs/file.prof %s 2>&1 | FileCheck -check-prefix=CHECK-SAMPLE-PROFILE %s
 // CHECK-SAMPLE-PROFILE: "-fprofile-sample-use={{.*}}/file.prof"
 
+// RUN: %clang -### -S -fauto-profile=%S/Inputs/file.prof %s 2>&1 | FileCheck -check-prefix=CHECK-AUTO-PROFILE %s
+// CHECK-AUTO-PROFILE: "-fprofile-sample-use={{.*}}/file.prof"
+
 // RUN: %clang -### -S -fvectorize %s 2>&1 | FileCheck -check-prefix=CHECK-VECTORIZE %s
 // RUN: %clang -### -S -fno-vectorize -fvectorize %s 2>&1 | FileCheck -check-prefix=CHECK-VECTORIZE %s
 // RUN: %clang -### -S -fno-vectorize %s 2>&1 | FileCheck -check-prefix=CHECK-NO-VECTORIZE %s
@@ -84,6 +89,17 @@
 // RUN: %clang -### -S -fno-tree-slp-vectorize -fslp-vectorize %s 2>&1 | FileCheck -check-prefix=CHECK-SLP-VECTORIZE %s
 // RUN: %clang -### -S -fno-tree-slp-vectorize %s 2>&1 | FileCheck -check-prefix=CHECK-NO-SLP-VECTORIZE %s
 // RUN: %clang -### -S -ftree-slp-vectorize -fno-slp-vectorize %s 2>&1 | FileCheck -check-prefix=CHECK-NO-SLP-VECTORIZE %s
+// RUN: %clang -### -S -O %s 2>&1 | FileCheck -check-prefix=CHECK-SLP-VECTORIZE %s
+// RUN: %clang -### -S -O2 %s 2>&1 | FileCheck -check-prefix=CHECK-SLP-VECTORIZE %s
+// RUN: %clang -### -S -Os %s 2>&1 | FileCheck -check-prefix=CHECK-SLP-VECTORIZE %s
+// RUN: %clang -### -S -Oz %s 2>&1 | FileCheck -check-prefix=CHECK-SLP-VECTORIZE %s
+// RUN: %clang -### -S -O3 %s 2>&1 | FileCheck -check-prefix=CHECK-SLP-VECTORIZE %s
+// RUN: %clang -### -S -fno-slp-vectorize -O3 %s 2>&1 | FileCheck -check-prefix=CHECK-SLP-VECTORIZE %s
+// RUN: %clang -### -S -O1 -fslp-vectorize %s 2>&1 | FileCheck -check-prefix=CHECK-SLP-VECTORIZE %s
+// RUN: %clang -### -S -Ofast %s 2>&1 | FileCheck -check-prefix=CHECK-SLP-VECTORIZE %s
+// RUN: %clang -### -S %s 2>&1 | FileCheck -check-prefix=CHECK-NO-SLP-VECTORIZE %s
+// RUN: %clang -### -S -O0 %s 2>&1 | FileCheck -check-prefix=CHECK-NO-SLP-VECTORIZE %s
+// RUN: %clang -### -S -O1 %s 2>&1 | FileCheck -check-prefix=CHECK-NO-SLP-VECTORIZE %s
 // CHECK-SLP-VECTORIZE: "-vectorize-slp"
 // CHECK-NO-SLP-VECTORIZE-NOT: "-vectorize-slp"
 
@@ -111,7 +127,10 @@
 // CHECK-MAX-O: -O3
 
 // RUN: %clang -S -O20 -o /dev/null %s 2>&1 | FileCheck -check-prefix=CHECK-INVALID-O %s
-// CHECK-INVALID-O: warning: optimization level '-O20' is unsupported; using '-O3' instead
+// CHECK-INVALID-O: warning: optimization level '-O20' is not supported; using '-O3' instead
+
+// RUN: %clang -### -S -finput-charset=iso-8859-1 -o /dev/null %s 2>&1 | FileCheck -check-prefix=CHECK-INVALID-CHARSET %s
+// CHECK-INVALID-CHARSET: error: invalid value 'iso-8859-1' in '-finput-charset=iso-8859-1'
 
 // Test that we don't error on these.
 // RUN: %clang -### -S -Werror                                                \
@@ -124,9 +143,11 @@
 // RUN:     -fgcse -fno-gcse                                                  \
 // RUN:     -fident -fno-ident                                                \
 // RUN:     -fimplicit-templates -fno-implicit-templates                      \
+// RUN:     -finput-charset=UTF-8                                             \
 // RUN:     -fivopts -fno-ivopts                                              \
 // RUN:     -fnon-call-exceptions -fno-non-call-exceptions                    \
 // RUN:     -fpermissive -fno-permissive                                      \
+// RUN:     -fdefer-pop -fno-defer-pop                                        \
 // RUN:     -fprefetch-loop-arrays -fno-prefetch-loop-arrays                  \
 // RUN:     -fprofile-correction -fno-profile-correction                      \
 // RUN:     -fprofile-dir=bar                                                 \
@@ -143,5 +164,79 @@
 // RUN:     -fno-unsigned-char                                                \
 // RUN:     -fno-signed-char                                                  \
 // RUN:     -fstrength-reduce -fno-strength-reduce                            \
+// RUN:     -finline-limit=1000                                               \
+// RUN:     -finline-limit                                                    \
 // RUN:     %s 2>&1 | FileCheck --check-prefix=IGNORE %s
 // IGNORE-NOT: error: unknown argument
+
+// Test that the warning is displayed on these.
+// RUN: %clang -###                                                           \
+// RUN: -finline-limit=1000                                                   \
+// RUN: -finline-limit                                                        \
+// RUN: -fexpensive-optimizations                                             \
+// RUN: -fno-expensive-optimizations                                          \
+// RUN: -fno-defer-pop                                                        \
+// RUN: -finline-functions                                                    \
+// RUN: -fno-keep-inline-functions                                            \
+// RUN: -freorder-blocks                                                      \
+// RUN: -fprofile-dir=/rand/dir                                               \
+// RUN: -fprofile-use                                                         \
+// RUN: -fprofile-use=/rand/dir                                               \
+// RUN: -falign-functions                                                     \
+// RUN: -falign-functions=1                                                   \
+// RUN: -ffloat-store                                                         \
+// RUN: -fgcse                                                                \
+// RUN: -fivopts                                                              \
+// RUN: -fprefetch-loop-arrays                                                \
+// RUN: -fprofile-correction                                                  \
+// RUN: -fprofile-values                                                      \
+// RUN: -frounding-math                                                       \
+// RUN: -fschedule-insns                                                      \
+// RUN: -fsignaling-nans                                                      \
+// RUN: -fstrength-reduce                                                     \
+// RUN: -ftracer                                                              \
+// RUN: -funroll-all-loops                                                    \
+// RUN: -funswitch-loops                                                      \
+// RUN: %s 2>&1 | FileCheck --check-prefix=CHECK-WARNING %s
+// CHECK-WARNING-DAG: optimization flag '-finline-limit=1000' is not supported
+// CHECK-WARNING-DAG: optimization flag '-finline-limit' is not supported
+// CHECK-WARNING-DAG: optimization flag '-fexpensive-optimizations' is not supported
+// CHECK-WARNING-DAG: optimization flag '-fno-expensive-optimizations' is not supported
+// CHECK-WARNING-DAG: optimization flag '-fno-defer-pop' is not supported
+// CHECK-WARNING-DAG: optimization flag '-finline-functions' is not supported
+// CHECK-WARNING-DAG: optimization flag '-fno-keep-inline-functions' is not supported
+// CHECK-WARNING-DAG: optimization flag '-freorder-blocks' is not supported
+// CHECK-WARNING-DAG: optimization flag '-fprofile-dir=/rand/dir' is not supported
+// CHECK-WARNING-DAG: optimization flag '-fprofile-use' is not supported
+// CHECK-WARNING-DAG: optimization flag '-fprofile-use=/rand/dir' is not supported
+// CHECK-WARNING-DAG: optimization flag '-falign-functions' is not supported
+// CHECK-WARNING-DAG: optimization flag '-falign-functions=1' is not supported
+// CHECK-WARNING-DAG: optimization flag '-ffloat-store' is not supported
+// CHECK-WARNING-DAG: optimization flag '-fgcse' is not supported
+// CHECK-WARNING-DAG: optimization flag '-fivopts' is not supported
+// CHECK-WARNING-DAG: optimization flag '-fprefetch-loop-arrays' is not supported
+// CHECK-WARNING-DAG: optimization flag '-fprofile-correction' is not supported
+// CHECK-WARNING-DAG: optimization flag '-fprofile-values' is not supported
+// CHECK-WARNING-DAG: optimization flag '-frounding-math' is not supported
+// CHECK-WARNING-DAG: optimization flag '-fschedule-insns' is not supported
+// CHECK-WARNING-DAG: optimization flag '-fsignaling-nans' is not supported
+// CHECK-WARNING-DAG: optimization flag '-fstrength-reduce' is not supported
+// CHECK-WARNING-DAG: optimization flag '-ftracer' is not supported
+// CHECK-WARNING-DAG: optimization flag '-funroll-all-loops' is not supported
+// CHECK-WARNING-DAG: optimization flag '-funswitch-loops' is not supported
+
+// Test that we mute the warning on these
+// RUN: %clang -### -finline-limit=1000 -Wno-invalid-command-line-argument              \
+// RUN:     %s 2>&1 | FileCheck --check-prefix=CHECK-NO-WARNING1 %s
+// RUN: %clang -### -finline-limit -Wno-invalid-command-line-argument                   \
+// RUN:     %s 2>&1 | FileCheck --check-prefix=CHECK-NO-WARNING2 %s
+// CHECK-NO-WARNING1-NOT: optimization flag '-finline-limit=1000' is not supported
+// CHECK-NO-WARNING2-NOT: optimization flag '-finline-limit' is not supported
+
+
+// RUN: %clang -### -fshort-wchar -fno-short-wchar %s 2>&1 | FileCheck -check-prefix=CHECK-WCHAR1 %s
+// RUN: %clang -### -fno-short-wchar -fshort-wchar %s 2>&1 | FileCheck -check-prefix=CHECK-WCHAR2 %s
+// CHECK-WCHAR1: -fno-short-wchar
+// CHECK-WCHAR1-NOT: -fshort-wchar
+// CHECK-WCHAR2: -fshort-wchar
+// CHECK-WCHAR2-NOT: -fno-short-wchar
diff --git a/test/Driver/code-model.c b/test/Driver/code-model.c
new file mode 100644
index 0000000..001ca60
--- /dev/null
+++ b/test/Driver/code-model.c
@@ -0,0 +1,13 @@
+// RUN: %clang -### -c -mcmodel=small %s 2>&1 | FileCheck -check-prefix CHECK-SMALL %s
+// RUN: %clang -### -S -mcmodel=kernel %s 2>&1 | FileCheck -check-prefix CHECK-KERNEL %s
+// RUN: %clang -### -c -mcmodel=medium %s 2>&1 | FileCheck -check-prefix CHECK-MEDIUM %s
+// RUN: %clang -### -S -mcmodel=large %s 2>&1 | FileCheck -check-prefix CHECK-LARGE %s
+// RUN: not %clang -c -mcmodel=lager %s 2>&1 | FileCheck -check-prefix CHECK-INVALID %s
+
+// CHECK-SMALL: "-mcode-model" "small"
+// CHECK-KERNEL: "-mcode-model" "kernel"
+// CHECK-MEDIUM: "-mcode-model" "medium"
+// CHECK-LARGE: "-mcode-model" "large"
+
+// CHECK-INVALID: error: invalid value 'lager' in '-mcode-model lager'
+
diff --git a/test/Driver/compress.c b/test/Driver/compress.c
new file mode 100644
index 0000000..6cdc6b7
--- /dev/null
+++ b/test/Driver/compress.c
@@ -0,0 +1,8 @@
+// RUN: %clang -### -c -integrated-as -Wa,-compress-debug-sections %s 2>&1 | FileCheck --check-prefix=COMPRESS_DEBUG %s
+// RUN: %clang -### -c -integrated-as -Wa,--compress-debug-sections %s 2>&1 | FileCheck --check-prefix=COMPRESS_DEBUG %s
+// REQUIRES: zlib
+
+// COMPRESS_DEBUG: "-compress-debug-sections"
+
+// RUN: %clang -### -c -integrated-as -Wa,--compress-debug-sections -Wa,--nocompress-debug-sections %s 2>&1 | FileCheck --check-prefix=NOCOMPRESS_DEBUG %s
+// NOCOMPRESS_DEBUG-NOT: "-compress-debug-sections"
diff --git a/test/Driver/constructors.c b/test/Driver/constructors.c
index 9ea91d9..a8b0942 100644
--- a/test/Driver/constructors.c
+++ b/test/Driver/constructors.c
@@ -46,3 +46,21 @@
 // RUN:     -target i386-unknown-linux-android \
 // RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
 // RUN:   | FileCheck --check-prefix=CHECK-INIT-ARRAY %s
+//
+// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1       \
+// RUN:     -target aarch64-none-linux-gnu \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-INIT-ARRAY %s
+//
+// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1       \
+// RUN:     -target aarch64-none-none-eabi \
+// RUN:   | FileCheck --check-prefix=CHECK-INIT-ARRAY %s
+
+// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1       \
+// RUN:     -target arm64-none-linux-gnu \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-INIT-ARRAY %s
+//
+// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1       \
+// RUN:     -target arm64-none-none-eabi \
+// RUN:   | FileCheck --check-prefix=CHECK-INIT-ARRAY %s
diff --git a/test/Driver/coverage-ld.c b/test/Driver/coverage-ld.c
index cbb7dd4..0e39249 100644
--- a/test/Driver/coverage-ld.c
+++ b/test/Driver/coverage-ld.c
@@ -17,3 +17,12 @@
 //
 // CHECK-LINUX-X86-64: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
 // 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:     -resource-dir=%S/Inputs/resource_dir \
+// RUN:     --sysroot=%S/Inputs/basic_freebsd64_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-FREEBSD-X86-64 %s
+//
+// CHECK-FREEBSD-X86-64: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-FREEBSD-X86-64: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}freebsd{{/|\\\\}}libclang_rt.profile-x86_64.a"
diff --git a/test/Driver/crash-report-modules.m b/test/Driver/crash-report-modules.m
new file mode 100644
index 0000000..d1c7832
--- /dev/null
+++ b/test/Driver/crash-report-modules.m
@@ -0,0 +1,32 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+
+// RUN: not env FORCE_CLANG_DIAGNOSTICS_CRASH= TMPDIR=%t TEMP=%t TMP=%t \
+// RUN: %clang -fsyntax-only %s -I %S/Inputs/module                     \
+// RUN: -fmodules -fmodules-cache-path=/tmp/ -DFOO=BAR 2>&1 | FileCheck %s
+
+// RUN: FileCheck --check-prefix=CHECKSRC %s -input-file %t/crash-report-*.m
+// RUN: FileCheck --check-prefix=CHECKSH %s -input-file %t/crash-report-*.sh
+// REQUIRES: crash-recovery
+
+// because of the glob (*.m, *.sh)
+// REQUIRES: shell
+
+// FIXME: This XFAIL is cargo-culted from crash-report.c. Do we need it?
+// XFAIL: mingw32
+
+@import simple;
+const int x = MODULE_MACRO;
+
+// CHECK: Preprocessed source(s) and associated run script(s) are located at:
+// CHECK-NEXT: note: diagnostic msg: {{.*}}.m
+// CHECK-NEXT: note: diagnostic msg: {{.*}}.cache
+
+// CHECKSRC: @import simple;
+// CHECKSRC: const int x = 10;
+
+// CHECKSH: -cc1
+// CHECKSH: -D "FOO=BAR"
+// CHECKSH-NOT: -fmodules-cache-path=/tmp/
+// CHECKSH: crash-report-modules-{{[^ ]*}}.m
+// CHECKSH: -ivfsoverlay crash-report-modules-{{[^ ]*}}.cache/vfs/vfs.yaml
diff --git a/test/Driver/crash-report.c b/test/Driver/crash-report.c
index 95c57f2..da1ff95 100644
--- a/test/Driver/crash-report.c
+++ b/test/Driver/crash-report.c
@@ -13,7 +13,7 @@
 // because of the glob (*.c, *.sh)
 // REQUIRES: shell
 
-// RUN: not env FORCE_CLANG_DIAGNOSTICS_CRASH=1 %clang -fsyntax-only -x c /dev/null 2>&1 | FileCheck %s
+// RUN: not env FORCE_CLANG_DIAGNOSTICS_CRASH=1 %clang -fsyntax-only -x c /dev/null -lstdc++ 2>&1 | FileCheck %s
 
 // FIXME: Investigating. "fatal error: file 'nul' modified since it was first processed"
 // XFAIL: mingw32
@@ -36,3 +36,4 @@
 // CHECKSH-NOT: -internal-isystem /tmp/
 // CHECKSH-NOT: -internal-externc-isystem /tmp/
 // CHECKSH-NOT: -dwarf-debug-flags
+// CHECKSH: crash-report-{{[^ ]*}}.c
diff --git a/test/Driver/cross-linux.c b/test/Driver/cross-linux.c
index 3013d80..ade8d8f 100644
--- a/test/Driver/cross-linux.c
+++ b/test/Driver/cross-linux.c
@@ -16,6 +16,14 @@
 //
 // RUN: %clang -### -o %t %s 2>&1 -no-integrated-as \
 // RUN:   --gcc-toolchain=%S/Inputs/basic_cross_linux_tree/usr \
+// RUN:   --target=x86_64-unknown-linux-gnux32 \
+// RUN:   | FileCheck --check-prefix=CHECK-X32 %s
+// CHECK-X32: "-cc1" "-triple" "x86_64-unknown-linux-gnux32"
+// CHECK-X32: "{{.*}}/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.0/../../../../x86_64-unknown-linux-gnu/bin{{/|\\}}as" "--x32"
+// CHECK-X32: "{{.*}}/Inputs/basic_cross_linux_tree/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.0/../../../../x86_64-unknown-linux-gnu/bin{{/|\\}}ld" {{.*}} "-m" "elf32_x86_64"
+//
+// RUN: %clang -### -o %t %s 2>&1 -no-integrated-as \
+// RUN:   --gcc-toolchain=%S/Inputs/basic_cross_linux_tree/usr \
 // RUN:   --target=x86_64-unknown-linux-gnu -m32 \
 // RUN:   | FileCheck --check-prefix=CHECK-I386 %s
 //
diff --git a/test/Driver/darwin-as.c b/test/Driver/darwin-as.c
index 58c850e..e35391e 100644
--- a/test/Driver/darwin-as.c
+++ b/test/Driver/darwin-as.c
@@ -1,16 +1,22 @@
 // RUN: %clang -target i386-apple-darwin10 -### -x assembler -c %s \
 // RUN:   -no-integrated-as -static -dynamic 2>%t
+// RUN: FileCheck -check-prefix=CHECK-STATIC_AND_DYNAMIC-32-DARWIN10 --input-file %t %s
+//
+// CHECK-STATIC_AND_DYNAMIC-32-DARWIN10: as{{(.exe)?}}" "-arch" "i386" "-force_cpusubtype_ALL" "-static" "-o"
+
+// RUN: %clang -target i386-apple-darwin11 -### -x assembler -c %s \
+// RUN:   -no-integrated-as -static -dynamic 2>%t
 // RUN: FileCheck -check-prefix=CHECK-STATIC_AND_DYNAMIC-32 --input-file %t %s
 //
 // CHECK-STATIC_AND_DYNAMIC-32: as{{(.exe)?}}" "-Q" "-arch" "i386" "-force_cpusubtype_ALL" "-static" "-o"
 
-// RUN: %clang -target x86_64-apple-darwin10 -### -x assembler -c %s \
+// RUN: %clang -target x86_64-apple-darwin11 -### -x assembler -c %s \
 // RUN:   -no-integrated-as -static 2>%t
 // RUN: FileCheck -check-prefix=CHECK-STATIC-64 --input-file %t %s
 //
 // CHECK-STATIC-64: as{{(.exe)?}}" "-Q" "-arch" "x86_64" "-force_cpusubtype_ALL" "-o"
 
-// RUN: %clang -target x86_64-apple-darwin10 -### \
+// RUN: %clang -target x86_64-apple-darwin11 -### \
 // RUN:   -arch armv6 -no-integrated-as -x assembler -c %s 2>%t
 // RUN: FileCheck -check-prefix=CHECK-ARMV6 --input-file %t %s
 //
diff --git a/test/Driver/darwin-asan-nofortify.c b/test/Driver/darwin-asan-nofortify.c
index 7f325e0..58b5be9 100644
--- a/test/Driver/darwin-asan-nofortify.c
+++ b/test/Driver/darwin-asan-nofortify.c
@@ -1,6 +1,5 @@
 // Make sure AddressSanitizer disables _FORTIFY_SOURCE on Darwin.
 
-// RUN: %clang -faddress-sanitizer %s -E -dM -target x86_64-darwin - | FileCheck %s
-// RUN: %clang -fsanitize=address  %s -E -dM -target x86_64-darwin - | FileCheck %s
+// RUN: %clang -fsanitize=address  %s -E -dM -target x86_64-darwin | FileCheck %s
 
 // CHECK: #define _FORTIFY_SOURCE 0
diff --git a/test/Driver/darwin-dsymutil.c b/test/Driver/darwin-dsymutil.c
index b8c3083..59084a2 100644
--- a/test/Driver/darwin-dsymutil.c
+++ b/test/Driver/darwin-dsymutil.c
@@ -43,3 +43,6 @@
 // RUN: FileCheck -check-prefix=CHECK-LOCATION < %t %s
 
 // CHECK-LOCATION: "x86_64-apple-darwin10" - "darwin::Dsymutil", inputs: ["bar/foo"], output: "bar/foo.dSYM"
+
+// Check that we don't crash when translating arguments for dsymutil.
+// RUN: %clang -m32 -arch x86_64 -g %s -###
diff --git a/test/Driver/darwin-eabi.c b/test/Driver/darwin-eabi.c
deleted file mode 100644
index 1288fa4..0000000
--- a/test/Driver/darwin-eabi.c
+++ /dev/null
@@ -1,12 +0,0 @@
-// RUN: %clang -arch armv7 -target thumbv7-apple-darwin-eabi -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-AAPCS
-// RUN: %clang -arch armv7s -target thumbv7-apple-ios -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-APCS
-// RUN: %clang -arch armv7s -target thumbv7-apple-darwin -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-APCS
-// RUN: %clang -arch armv6m -target thumbv7-apple-darwin -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-DARWIN-EABI
-// RUN: %clang -arch armv7m -target thumbv7-apple-darwin -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-DARWIN-EABI
-// RUN: %clang -arch armv7em -target thumbv7-apple-darwin -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-DARWIN-EABI
-
-// CHECK-DARWIN-EABI: "-triple" "{{thumbv[67]e?m}}-apple-darwin-eabi"
-// CHECK-IOS: "-triple" "thumbv7" "thumbv7-apple-ios
-
-// CHECK-AAPCS: "-target-abi" "aapcs"
-// CHECK-APCS: "-target-abi" "apcs-gnu"
diff --git a/test/Driver/darwin-embedded.c b/test/Driver/darwin-embedded.c
new file mode 100644
index 0000000..66b7bd9
--- /dev/null
+++ b/test/Driver/darwin-embedded.c
@@ -0,0 +1,60 @@
+// RUN: %clang -target x86_64-apple-darwin -arch armv6m -resource-dir=%S/Inputs/resource_dir %s -### 2> %t
+// RUN: %clang -target x86_64-apple-darwin -arch armv7em -resource-dir=%S/Inputs/resource_dir %s -### 2>> %t
+// RUN: %clang -target x86_64-apple-darwin -arch armv7em -mhard-float -resource-dir=%S/Inputs/resource_dir %s -### 2>> %t
+
+// RUN: %clang -target x86_64-apple-darwin -arch armv7m -fPIC -resource-dir=%S/Inputs/resource_dir %s -### 2>> %t
+// RUN: %clang -target x86_64-apple-darwin -arch armv7em -fPIC -mfloat-abi=hard -resource-dir=%S/Inputs/resource_dir %s -### 2>> %t
+// RUN: %clang -target x86_64-apple-darwin -arch armv7em -fPIC -mfloat-abi=softfp -resource-dir=%S/Inputs/resource_dir %s -### 2>> %t
+// RUN: %clang -target x86_64-apple-none-macho -arch armv7 -mhard-float -resource-dir=%S/Inputs/resource_dir %s -### 2>> %t
+// RUN: %clang -target x86_64-apple-none-macho -arch armv7 -msoft-float -fPIC -resource-dir=%S/Inputs/resource_dir %s -### 2>> %t
+
+
+// RUN: FileCheck %s < %t
+
+// ARMv6m has no float
+// CHECK-LABEL: Target:
+// CHECK-NOT: warning: unknown platform
+// CHECK: "-mfloat-abi" "soft"
+// CHECK: libclang_rt.soft_static.a
+
+// ARMv7em does, but defaults to soft
+// CHECK-LABEL: Target:
+// CHECK-NOT: warning: unknown platform
+// CHECK: "-mfloat-abi" "soft"
+// CHECK: libclang_rt.soft_static.a
+
+// Which can be overridden
+// CHECK-LABEL: Target:
+// CHECK-NOT: warning: unknown platform
+// CHECK: "-mfloat-abi" "hard"
+// CHECK: libclang_rt.hard_static.a
+
+// ARMv7m has no float either
+// CHECK-LABEL: Target:
+// CHECK-NOT: warning: unknown platform
+// CHECK: "-mfloat-abi" "soft"
+// CHECK: libclang_rt.soft_pic.a
+
+// But it can be enabled on ARMv7em
+// CHECK-LABEL: Target:
+// CHECK-NOT: warning: unknown platform
+// CHECK: "-mfloat-abi" "hard"
+// CHECK: libclang_rt.hard_pic.a
+
+// "softfp" must link against a soft-float library since that's what the
+// callers we're compiling will expect.
+// CHECK-LABEL: Target:
+// CHECK-NOT: warning: unknown platform
+// CHECK: "-mfloat-abi" "soft"
+// CHECK: libclang_rt.soft_pic.a
+
+// -arch "armv7" (== embedded v7a) can be used in a couple of variants:
+// CHECK-LABEL: Target:
+// CHECK-NOT: warning: unknown platform
+// CHECK: "-mfloat-abi" "hard"
+// CHECK: libclang_rt.hard_static.a
+
+// CHECK-LABEL: Target:
+// CHECK-NOT: warning: unknown platform
+// CHECK: "-mfloat-abi" "soft"
+// CHECK: libclang_rt.soft_pic.a
diff --git a/test/Driver/darwin-ld.c b/test/Driver/darwin-ld.c
index d6c5170..2da0d30 100644
--- a/test/Driver/darwin-ld.c
+++ b/test/Driver/darwin-ld.c
@@ -45,6 +45,22 @@
 // LINK_IPHONE_3_1-NOT: -lbundle1.o
 // LINK_IPHONE_3_1: -lSystem
 
+// RUN: %clang -target i386-apple-darwin9 -### -arch i386 -mios-simulator-version-min=3.0 %t.o 2> %t.log
+// RUN: %clang -target i386-apple-darwin9 -### -arch i386 -mios-simulator-version-min=3.0 -dynamiclib %t.o 2>> %t.log
+// RUN: %clang -target i386-apple-darwin9 -### -arch i386 -mios-simulator-version-min=3.0 -bundle %t.o 2>> %t.log
+// RUN: FileCheck -check-prefix=LINK_IOSSIM_3_0 %s < %t.log
+
+// LINK_IOSSIM_3_0: {{ld(.exe)?"}}
+// LINK_IOSSIM_3_0-NOT: -lcrt1.o
+// LINK_IOSSIM_3_0: -lSystem
+// LINK_IOSSIM_3_0: {{ld(.exe)?"}}
+// LINK_IOSSIM_3_0: -dylib
+// LINK_IOSSIM_3_0-NOT: -ldylib1.o
+// LINK_IOSSIM_3_0: -lSystem
+// LINK_IOSSIM_3_0: {{ld(.exe)?"}}
+// LINK_IOSSIM_3_0-NOT: -lbundle1.o
+// LINK_IOSSIM_3_0: -lSystem
+
 // RUN: %clang -target i386-apple-darwin9 -### -fpie %t.o 2> %t.log
 // RUN: FileCheck -check-prefix=LINK_EXPLICIT_PIE %s < %t.log
 //
@@ -126,11 +142,24 @@
 // RUN: FileCheck -check-prefix=LINK_NO_IOS_CRT1 %s < %t.log
 // LINK_NO_IOS_CRT1-NOT: crt
 
+// RUN: %clang -target arm64-apple-ios5.0 -miphoneos-version-min=5.0 -### %t.o 2> %t.log
+// RUN: FileCheck -check-prefix=LINK_NO_IOS_ARM64_CRT1 %s < %t.log
+// LINK_NO_IOS_ARM64_CRT1-NOT: crt
+
 // RUN: %clang -target i386-apple-darwin12 -pg -### %t.o 2> %t.log
 // RUN: FileCheck -check-prefix=LINK_PG %s < %t.log
 // LINK_PG: -lgcrt1.o
 // LINK_PG: -no_new_main
 
+// Check that clang links with libgcc_s.1 for iOS 4 and earlier, but not arm64.
+// RUN: %clang -target armv7-apple-ios4.0 -miphoneos-version-min=4.0 -### %t.o 2> %t.log
+// RUN: FileCheck -check-prefix=LINK_IOS_LIBGCC_S %s < %t.log
+// LINK_IOS_LIBGCC_S: lgcc_s.1
+
+// RUN: %clang -target arm64-apple-ios4.0 -miphoneos-version-min=4.0 -### %t.o 2> %t.log
+// RUN: FileCheck -check-prefix=LINK_NO_IOS_ARM64_LIBGCC_S %s < %t.log
+// LINK_NO_IOS_ARM64_LIBGCC_S-NOT: lgcc_s.1
+
 // RUN: %clang -target x86_64-apple-darwin12 -rdynamic -### %t.o \
 // RUN:   -mlinker-version=100 2> %t.log
 // RUN: FileCheck -check-prefix=LINK_NO_EXPORT_DYNAMIC %s < %t.log
@@ -143,4 +172,25 @@
 // LINK_EXPORT_DYNAMIC: {{ld(.exe)?"}}
 // LINK_EXPORT_DYNAMIC: "-export_dynamic"
 
+// RUN: %clang -target x86_64h-apple-darwin -### %t.o 2> %t.log
+// RUN: FileCheck -check-prefix=LINK_X86_64H_ARCH %s < %t.log
+//
+// LINK_X86_64H_ARCH: {{ld(.exe)?"}}
+// LINK_X86_64H_ARCH: "x86_64h"
 
+// RUN: %clang -target x86_64-apple-darwin -arch x86_64 -arch x86_64h -### %t.o 2> %t.log
+// RUN: FileCheck -check-prefix=LINK_X86_64H_MULTIARCH %s < %t.log
+//
+// LINK_X86_64H_MULTIARCH: {{ld(.exe)?"}}
+// LINK_X86_64H_MULTIARCH: "x86_64"
+//
+// LINK_X86_64H_MULTIARCH: {{ld(.exe)?"}}
+// LINK_X86_64H_MULTIARCH: "x86_64h"
+
+// Check that clang passes -iphoneos_version_min to the linker when building
+// for the iOS simulator but when -mios-simulator-version-min is not
+// explicitly specified (<rdar://problem/15959009>).
+// RUN: env IPHONEOS_DEPLOYMENT_TARGET=7.0 \
+// RUN:   %clang -target i386-apple-darwin -### %t.o 2> %t.log
+// RUN: FileCheck -check-prefix=LINK_IPHONEOS_VERSION_MIN %s < %t.log
+// LINK_IPHONEOS_VERSION_MIN: -iphoneos_version_min
diff --git a/test/Driver/darwin-objc-defaults.m b/test/Driver/darwin-objc-defaults.m
index 1742deb..1b3f7a8 100644
--- a/test/Driver/darwin-objc-defaults.m
+++ b/test/Driver/darwin-objc-defaults.m
@@ -32,11 +32,20 @@
 // x86_64
 
 // RUN: %clang -target x86_64-apple-darwin10 -S -### %s \
+// RUN:   -arch x86_64 -mmacosx-version-min=10.4 2> %t
+// RUN: FileCheck --check-prefix CHECK-CHECK-X86_64_OSX10_4 < %t %s
+
+// CHECK-CHECK-X86_64_OSX10_4: "-cc1"
+// CHECK-CHECK-X86_64_OSX10_4: -fobjc-dispatch-method=non-legacy
+
+// RUN: %clang -target x86_64-apple-darwin10 -S -### %s \
 // RUN:   -arch x86_64 -mmacosx-version-min=10.5 2> %t
 // RUN: FileCheck --check-prefix CHECK-CHECK-X86_64_OSX10_5 < %t %s
 
+
 // CHECK-CHECK-X86_64_OSX10_5: "-cc1"
 // CHECK-CHECK-X86_64_OSX10_5: -fobjc-runtime=macosx-10.5
+// CHECK-CHECK-X86_64_OSX10_5: -fobjc-dispatch-method=non-legacy
 // CHECK-CHECK-X86_64_OSX10_5: darwin-objc-defaults
 
 // RUN: %clang -target x86_64-apple-darwin10 -S -### %s \
diff --git a/test/Driver/darwin-objc-options.m b/test/Driver/darwin-objc-options.m
index a90a12d..3e21fb3 100644
--- a/test/Driver/darwin-objc-options.m
+++ b/test/Driver/darwin-objc-options.m
@@ -30,3 +30,6 @@
 // CHECK-CHECK-I386_IOS: -fexceptions
 // CHECK-CHECK-I386_IOS-NOT: -fobjc-dispatch-method
 // CHECK-CHECK-I386_IOS: darwin-objc-options
+
+// Don't crash with an unexpected target triple.
+// RUN: %clang -target i386-apple-ios7 -S -### %s
diff --git a/test/Driver/darwin-verify-debug.c b/test/Driver/darwin-verify-debug.c
index c419cef..4878c74 100644
--- a/test/Driver/darwin-verify-debug.c
+++ b/test/Driver/darwin-verify-debug.c
@@ -2,15 +2,15 @@
 //
 // REQUIRES: asserts
 // RUN: %clang -target x86_64-apple-darwin10 -ccc-print-phases \
-// RUN:   -verify -arch i386 -arch x86_64 %s -g 2> %t
+// RUN:   --verify-debug-info -arch i386 -arch x86_64 %s -g 2> %t
 // RUN: FileCheck -check-prefix=CHECK-MULTIARCH-ACTIONS < %t %s
 //
 // CHECK-MULTIARCH-ACTIONS: 0: input, "{{.*}}darwin-verify-debug.c", c
 // CHECK-MULTIARCH-ACTIONS: 8: dsymutil, {7}, dSYM
-// CHECK-MULTIARCH-ACTIONS: 9: verify, {8}, none
+// CHECK-MULTIARCH-ACTIONS: 9: verify-debug-info, {8}, none
 //
 // RUN: %clang -target x86_64-apple-darwin10 -ccc-print-bindings \
-// RUN:   -verify -arch i386 -arch x86_64 %s -g 2> %t
+// RUN:   --verify-debug-info -arch i386 -arch x86_64 %s -g 2> %t
 // RUN: FileCheck -check-prefix=CHECK-MULTIARCH-BINDINGS < %t %s
 //
 // CHECK-MULTIARCH-BINDINGS: # "x86_64-apple-darwin10" - "darwin::Dsymutil", inputs: ["a.out"], output: "a.out.dSYM"
@@ -19,7 +19,7 @@
 // Check output name derivation.
 //
 // RUN: %clang -target x86_64-apple-darwin10 -ccc-print-bindings \
-// RUN:   -verify -o foo %s -g 2> %t
+// RUN:   --verify-debug-info -o foo %s -g 2> %t
 // RUN: FileCheck -check-prefix=CHECK-OUTPUT-NAME < %t %s
 //
 // CHECK-OUTPUT-NAME: "x86_64-apple-darwin10" - "darwin::Link", inputs: [{{.*}}], output: "foo"
@@ -30,5 +30,5 @@
 //
 // RUN: touch %t.o
 // RUN: %clang -target x86_64-apple-darwin10 -ccc-print-bindings \
-// RUN:   -verify -o foo %t.o -g 2> %t
+// RUN:   --verify-debug-info -o foo %t.o -g 2> %t
 // RUN: not grep "Verify" %t
diff --git a/test/Driver/debug-options.c b/test/Driver/debug-options.c
index 1f890b2..a8fadb3 100644
--- a/test/Driver/debug-options.c
+++ b/test/Driver/debug-options.c
@@ -33,28 +33,52 @@
 // RUN: %clang -### -c -g -g0 %s 2>&1 | FileCheck -check-prefix=G_NO %s
 // RUN: %clang -### -c -ggdb0 %s 2>&1 | FileCheck -check-prefix=G_NO %s
 //
+// RUN: %clang -### -c -gmlt %s 2>&1 \
+// RUN:             | FileCheck -check-prefix=GLTO_ONLY %s
 // RUN: %clang -### -c -gline-tables-only %s 2>&1 \
 // RUN:             | FileCheck -check-prefix=GLTO_ONLY %s
+// RUN: %clang -### -c -gline-tables-only %s -target x86_64-apple-darwin 2>&1 \
+// RUN:             | FileCheck -check-prefix=GLTO_ONLY_DWARF2 %s
+// RUN: %clang -### -c -gline-tables-only %s -target i686-pc-openbsd 2>&1 \
+// RUN:             | FileCheck -check-prefix=GLTO_ONLY_DWARF2 %s
+// RUN: %clang -### -c -gline-tables-only %s -target x86_64-pc-freebsd10.0 2>&1 \
+// RUN:             | FileCheck -check-prefix=GLTO_ONLY_DWARF2 %s
 // RUN: %clang -### -c -gline-tables-only -g %s -target x86_64-linux-gnu 2>&1 \
 // RUN:             | FileCheck -check-prefix=G_ONLY %s
 // RUN: %clang -### -c -gline-tables-only -g %s -target x86_64-apple-darwin 2>&1 \
-// RUN:             | FileCheck -check-prefix=G_ONLY_DARWIN %s
+// RUN:             | FileCheck -check-prefix=G_ONLY_DWARF2 %s
+// RUN: %clang -### -c -gline-tables-only -g %s -target i686-pc-openbsd 2>&1 \
+// RUN:             | FileCheck -check-prefix=G_ONLY_DWARF2 %s
+// RUN: %clang -### -c -gline-tables-only -g %s -target x86_64-pc-freebsd10.0 2>&1 \
+// RUN:             | FileCheck -check-prefix=G_ONLY_DWARF2 %s
 // RUN: %clang -### -c -gline-tables-only -g0 %s 2>&1 \
 // RUN:             | FileCheck -check-prefix=GLTO_NO %s
 //
 // RUN: %clang -### -c -grecord-gcc-switches -gno-record-gcc-switches \
-// RUN:        -gstrict-dwarf -gno-strict-dwarf -fdebug-types-section \
-// RUN:        -fno-debug-types-section %s 2>&1                       \
+// RUN:        -gstrict-dwarf -gno-strict-dwarf %s 2>&1 \
 // RUN:        | FileCheck -check-prefix=GIGNORE %s
 //
 // RUN: %clang -### -c -ggnu-pubnames %s 2>&1 | FileCheck -check-prefix=GOPT %s
 //
+// RUN: %clang -### -c -gdwarf-aranges %s 2>&1 | FileCheck -check-prefix=GARANGE %s
+//
+// RUN: %clang -### -fdebug-types-section %s 2>&1 \
+// RUN:        | FileCheck -check-prefix=FDTS %s
+//
+// RUN: %clang -### -fdebug-types-section -fno-debug-types-section %s 2>&1 \
+// RUN:        | FileCheck -check-prefix=NOFDTS %s
+//
+// RUN: %clang -### -g -gno-column-info %s 2>&1 \
+// RUN:        | FileCheck -check-prefix=NOCI %s
+//
+// RUN: %clang -### -g %s 2>&1 | FileCheck -check-prefix=CI %s
+//
 // G: "-cc1"
 // G: "-g"
 //
 // G_DARWIN: "-cc1"
 // G_DARWIN: "-gdwarf-2"
-// 
+//
 // G_D2: "-cc1"
 // G_D2: "-gdwarf-2"
 //
@@ -66,15 +90,21 @@
 // GLTO_ONLY: "-gline-tables-only"
 // GLTO_ONLY-NOT: "-g"
 //
+// GLTO_ONLY_DWARF2: "-cc1"
+// GLTO_ONLY_DWARF2-NOT: "-g"
+// GLTO_ONLY_DWARF2: "-gline-tables-only"
+// GLTO_ONLY_DWARF2: "-gdwarf-2"
+// GLTO_ONLY_DWARF2-NOT: "-g"
+//
 // G_ONLY: "-cc1"
 // G_ONLY-NOT: "-gline-tables-only"
 // G_ONLY: "-g"
 // G_ONLY-NOT: "-gline-tables-only"
 //
-// G_ONLY_DARWIN: "-cc1"
-// G_ONLY_DARWIN-NOT: "-gline-tables-only"
-// G_ONLY_DARWIN: "-gdwarf-2"
-// G_ONLY_DARWIN-NOT: "-gline-tables-only"
+// G_ONLY_DWARF2: "-cc1"
+// G_ONLY_DWARF2-NOT: "-gline-tables-only"
+// G_ONLY_DWARF2: "-gdwarf-2"
+// G_ONLY_DWARF2-NOT: "-gline-tables-only"
 //
 // GLTO_NO: "-cc1"
 // GLTO_NO-NOT: "-gline-tables-only"
@@ -82,3 +112,13 @@
 // GIGNORE-NOT: "argument unused during compilation"
 //
 // GOPT: -generate-gnu-dwarf-pub-sections
+//
+// GARANGE: -generate-arange-section
+//
+// FDTS: "-backend-option" "-generate-type-units"
+//
+// NOFDTS-NOT: "-backend-option" "-generate-type-units"
+//
+// CI: "-dwarf-column-info"
+//
+// NOCI-NOT: "-dwarf-column-info"
diff --git a/test/Driver/dwarf2-cfi-asm.c b/test/Driver/dwarf2-cfi-asm.c
deleted file mode 100644
index a5c4878..0000000
--- a/test/Driver/dwarf2-cfi-asm.c
+++ /dev/null
@@ -1,35 +0,0 @@
-// RUN: %clang -target x86_64-apple-darwin -### -S -integrated-as %s -o %t.s 2>&1 | FileCheck -check-prefix=CHECK-DARWIN-MC-DEFAULT %s
-// RUN: %clang -target x86_64-apple-darwin -### -S -integrated-as -fdwarf2-cfi-asm %s -o %t.s 2>&1 | FileCheck -check-prefix=CHECK-DARWIN-MC-CFI %s
-// RUN: %clang -target x86_64-apple-darwin -### -S -integrated-as -fno-dwarf2-cfi-asm %s -o %t.s 2>&1 | FileCheck -check-prefix=CHECK-DARWIN-MC-NOCFI %s
-
-// RUN: %clang -target x86_64-apple-darwin -### -S -no-integrated-as %s -o %t.s 2>&1 | FileCheck -check-prefix=CHECK-DARWIN-AS-DEFAULT %s
-// RUN: %clang -target x86_64-apple-darwin -### -S -no-integrated-as -fdwarf2-cfi-asm %s -o %t.s 2>&1 | FileCheck -check-prefix=CHECK-DARWIN-AS-CFI %s
-// RUN: %clang -target x86_64-apple-darwin -### -S -no-integrated-as -fno-dwarf2-cfi-asm %s -o %t.s 2>&1 | FileCheck -check-prefix=CHECK-DARWIN-AS-NOCFI %s
-
-
-// RUN: %clang -target x86_64-pc-linux -### -S -integrated-as %s -o %t.s 2>&1 | FileCheck -check-prefix=CHECK-LINUX-MC-DEFAULT %s
-// RUN: %clang -target x86_64-pc-linux -### -S -integrated-as -fdwarf2-cfi-asm %s -o %t.s 2>&1 | FileCheck -check-prefix=CHECK-LINUX-MC-CFI %s
-// RUN: %clang -target x86_64-pc-linux -### -S -integrated-as -fno-dwarf2-cfi-asm %s -o %t.s 2>&1 | FileCheck -check-prefix=CHECK-LINUX-MC-NOCFI %s
-
-// RUN: %clang -target x86_64-pc-linux -### -S -no-integrated-as %s -o %t.s 2>&1 | FileCheck -check-prefix=CHECK-LINUX-AS-DEFAULT %s
-// RUN: %clang -target x86_64-pc-linux -### -S -no-integrated-as -fdwarf2-cfi-asm %s -o %t.s 2>&1 | FileCheck -check-prefix=CHECK-LINUX-AS-CFI %s
-// RUN: %clang -target x86_64-pc-linux -### -S -no-integrated-as -fno-dwarf2-cfi-asm %s -o %t.s 2>&1 | FileCheck -check-prefix=CHECK-LINUX-AS-NOCFI %s
-
-
-
-// CHECK-DARWIN-MC-DEFAULT-NOT: -fno-dwarf2-cfi-asm
-// CHECK-DARWIN-MC-CFI-NOT: -fno-dwarf2-cfi-asm
-// CHECK-DARWIN-MC-NOCFI: -fno-dwarf2-cfi-asm
-
-// CHECK-DARWIN-AS-DEFAULT: -fno-dwarf2-cfi-asm
-// CHECK-DARWIN-AS-CFI-NOT: -fno-dwarf2-cfi-asm
-// CHECK-DARWIN-AS-NOCFI: -fno-dwarf2-cfi-asm
-
-
-// CHECK-LINUX-MC-DEFAULT-NOT: -fno-dwarf2-cfi-asmx
-// CHECK-LINUX-MC-CFI-NOT: -fno-dwarf2-cfi-asm
-// CHECK-LINUX-MC-NOCFI: -fno-dwarf2-cfi-asm
-
-// CHECK-LINUX-AS-DEFAULT-NOT: -fno-dwarf2-cfi-asm
-// CHECK-LINUX-AS-CFI-NOT: -fno-dwarf2-cfi-asm
-// CHECK-LINUX-AS-NOCFI: -fno-dwarf2-cfi-asm
diff --git a/test/Driver/dyld-prefix.c b/test/Driver/dyld-prefix.c
index 317d644..5336a11 100644
--- a/test/Driver/dyld-prefix.c
+++ b/test/Driver/dyld-prefix.c
@@ -7,3 +7,6 @@
 
 // RUN: %clang -target x86_64-unknown-linux --dyld-prefix /foo -### %t.o 2>&1 | FileCheck --check-prefix=CHECK-64 %s
 // CHECK-64: "-dynamic-linker" "/foo/lib64/ld-linux-x86-64.so.2"
+
+// RUN: %clang -target x86_64-unknown-linux-gnux32 --dyld-prefix /foo -### %t.o 2>&1 | FileCheck --check-prefix=CHECK-X32 %s
+// CHECK-X32: "-dynamic-linker" "/foo/libx32/ld-linux-x32.so.2"
diff --git a/test/Driver/fast-math.c b/test/Driver/fast-math.c
index eba25c8..690d7a1 100644
--- a/test/Driver/fast-math.c
+++ b/test/Driver/fast-math.c
@@ -9,6 +9,9 @@
 //
 // RUN: %clang -### -fno-honor-infinities -c %s 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-NO-INFS %s
+// infinites [sic] is a supported alternative spelling of infinities.
+// RUN: %clang -### -fno-honor-infinites -c %s 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-NO-INFS %s
 // CHECK-NO-INFS: "-cc1"
 // CHECK-NO-INFS: "-menable-no-infs"
 //
diff --git a/test/Driver/freebsd-mips-as.c b/test/Driver/freebsd-mips-as.c
index 508deba..da2d120 100644
--- a/test/Driver/freebsd-mips-as.c
+++ b/test/Driver/freebsd-mips-as.c
@@ -3,67 +3,67 @@
 // RUN: %clang -target mips-unknown-freebsd -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS32-EB-AS %s
-// MIPS32-EB-AS: as{{(.exe)?}}" "-march" "mips32" "-mabi" "32" "-EB"
+// MIPS32-EB-AS: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-EB"
 // MIPS32-EB-AS-NOT: "-KPIC"
 //
 // RUN: %clang -target mips-unknown-freebsd -### \
 // RUN:   -no-integrated-as -fPIC -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS32-EB-PIC %s
-// MIPS32-EB-PIC: as{{(.exe)?}}" "-march" "mips32" "-mabi" "32" "-EB"
+// MIPS32-EB-PIC: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-EB"
 // MIPS32-EB-PIC: "-KPIC"
 //
 // RUN: %clang -target mips-unknown-freebsd -### \
 // RUN:   -no-integrated-as -fpic -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS32-EB-PIC-SMALL %s
-// MIPS32-EB-PIC-SMALL: as{{(.exe)?}}" "-march" "mips32" "-mabi" "32" "-EB"
+// MIPS32-EB-PIC-SMALL: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-EB"
 // MIPS32-EB-PIC-SMALL: "-KPIC"
 //
 // RUN: %clang -target mips-unknown-freebsd -### \
 // RUN:   -no-integrated-as -fPIE -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS32-EB-PIE %s
-// MIPS32-EB-PIE: as{{(.exe)?}}" "-march" "mips32" "-mabi" "32" "-EB"
+// MIPS32-EB-PIE: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-EB"
 // MIPS32-EB-PIE: "-KPIC"
 //
 // RUN: %clang -target mips-unknown-freebsd -### \
 // RUN:   -no-integrated-as -fpie -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS32-EB-PIE-SMALL %s
-// MIPS32-EB-PIE-SMALL: as{{(.exe)?}}" "-march" "mips32" "-mabi" "32" "-EB"
+// MIPS32-EB-PIE-SMALL: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-EB"
 // MIPS32-EB-PIE-SMALL: "-KPIC"
 //
 // RUN: %clang -target mipsel-unknown-freebsd -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS32-DEF-EL-AS %s
-// MIPS32-DEF-EL-AS: as{{(.exe)?}}" "-march" "mips32" "-mabi" "32" "-EL"
+// MIPS32-DEF-EL-AS: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-EL"
 //
 // RUN: %clang -target mips64-unknown-freebsd -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS64-EB-AS %s
-// MIPS64-EB-AS: as{{(.exe)?}}" "-march" "mips64" "-mabi" "64" "-EB"
+// MIPS64-EB-AS: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64" "-EB"
 //
 // RUN: %clang -target mips64el-unknown-freebsd -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS64-DEF-EL-AS %s
-// MIPS64-DEF-EL-AS: as{{(.exe)?}}" "-march" "mips64" "-mabi" "64" "-EL"
+// MIPS64-DEF-EL-AS: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64" "-EL"
 //
 // RUN: %clang -target mips-unknown-freebsd -mabi=eabi -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-EABI %s
-// MIPS-EABI: as{{(.exe)?}}" "-march" "mips32" "-mabi" "eabi" "-EB"
+// MIPS-EABI: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "eabi" "-EB"
 //
 // RUN: %clang -target mips64-unknown-freebsd -mabi=n32 -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-N32 %s
-// MIPS-N32: as{{(.exe)?}}" "-march" "mips64" "-mabi" "n32" "-EB"
+// MIPS-N32: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "n32" "-EB"
 //
 // RUN: %clang -target mipsel-unknown-freebsd -mabi=32 -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS32-EL-AS %s
-// MIPS32-EL-AS: as{{(.exe)?}}" "-march" "mips32" "-mabi" "32" "-EL"
+// MIPS32-EL-AS: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-EL"
 //
 // RUN: %clang -target mips64el-unknown-freebsd -mabi=64 -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS64-EL-AS %s
-// MIPS64-EL-AS: as{{(.exe)?}}" "-march" "mips64" "-mabi" "64" "-EL"
+// MIPS64-EL-AS: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64" "-EL"
 //
 // RUN: %clang -target mips-linux-freebsd -march=mips32r2 -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
@@ -80,12 +80,12 @@
 // RUN:   | FileCheck -check-prefix=MIPS-ALIAS-32R2 %s
 // MIPS-ALIAS-32R2: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-EB"
 //
-// RUN: %clang -target mips-unknown-freebsd -mips64 -### \
+// RUN: %clang -target mips64-unknown-freebsd -mips64 -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-ALIAS-64 %s
 // MIPS-ALIAS-64: as{{(.exe)?}}" "-march" "mips64" "-mabi" "64" "-EB"
 //
-// RUN: %clang -target mips-unknown-freebsd -mips64r2 -### \
+// RUN: %clang -target mips64-unknown-freebsd -mips64r2 -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-ALIAS-64R2 %s
 // MIPS-ALIAS-64R2: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64" "-EB"
diff --git a/test/Driver/freebsd.c b/test/Driver/freebsd.c
index d1d9ea8..f0275d0 100644
--- a/test/Driver/freebsd.c
+++ b/test/Driver/freebsd.c
@@ -1,9 +1,8 @@
-// REQUIRES: ppc32-registered-target,ppc64-registered-target,mips-registered-target
 // RUN: %clang -no-canonical-prefixes \
 // RUN:   -target powerpc-pc-freebsd8 %s    \
 // RUN:   --sysroot=%S/Inputs/basic_freebsd_tree -### 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-PPC %s
-// CHECK-PPC: clang{{.*}}" "-cc1" "-triple" "powerpc-pc-freebsd8"
+// CHECK-PPC: "-cc1" "-triple" "powerpc-pc-freebsd8"
 // CHECK-PPC: ld{{.*}}" "--sysroot=[[SYSROOT:[^"]+]]"
 // CHECK-PPC: "--eh-frame-hdr" "-dynamic-linker" "{{.*}}ld-elf{{.*}}" "-o" "a.out" "{{.*}}crt1.o" "{{.*}}crti.o" "{{.*}}crtbegin.o" "-L[[SYSROOT]]/usr/lib" "{{.*}}.o" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "-lc" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "{{.*}}crtend.o" "{{.*}}crtn.o"
 //
@@ -11,7 +10,7 @@
 // RUN:   -target powerpc64-pc-freebsd8 %s                              \
 // RUN:   --sysroot=%S/Inputs/basic_freebsd64_tree -### 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-PPC64 %s
-// CHECK-PPC64: clang{{.*}}" "-cc1" "-triple" "powerpc64-pc-freebsd8"
+// CHECK-PPC64: "-cc1" "-triple" "powerpc64-pc-freebsd8"
 // CHECK-PPC64: ld{{.*}}" "--sysroot=[[SYSROOT:[^"]+]]"
 // CHECK-PPC64: "--eh-frame-hdr" "-dynamic-linker" "{{.*}}ld-elf{{.*}}" "-o" "a.out" "{{.*}}crt1.o" "{{.*}}crti.o" "{{.*}}crtbegin.o" "-L[[SYSROOT]]/usr/lib" "{{.*}}.o" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "-lc" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "{{.*}}crtend.o" "{{.*}}crtn.o"
 //
@@ -21,7 +20,7 @@
 // RUN: %clang -no-canonical-prefixes -target x86_64-pc-freebsd8 -m32 %s \
 // RUN:   --sysroot=%S/Inputs/multiarch_freebsd64_tree -### 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-LIB32 %s
-// CHECK-LIB32: clang{{.*}}" "-cc1" "-triple" "i386-pc-freebsd8"
+// CHECK-LIB32: "-cc1" "-triple" "i386-pc-freebsd8"
 // CHECK-LIB32: ld{{.*}}" {{.*}} "-m" "elf_i386_fbsd"
 //
 // RUN: %clang -target x86_64-pc-freebsd8 -m32 %s 2>&1 \
@@ -59,13 +58,13 @@
 // CHECK-MIPSEL: "{{[^" ]*}}ld{{[^" ]*}}"
 // CHECK-MIPSEL: "-dynamic-linker" "{{.*}}/libexec/ld-elf.so.1"
 // CHECK-MIPSEL-NOT: "--hash-style={{gnu|both}}"
-// RUN: %clang %s -### -o %t.o 2>&1 \
+// RUN: %clang %s -### 2>&1 \
 // RUN:     -target mips64-unknown-freebsd10.0 \
 // RUN:   | FileCheck --check-prefix=CHECK-MIPS64 %s
 // CHECK-MIPS64: "{{[^" ]*}}ld{{[^" ]*}}"
 // CHECK-MIPS64: "-dynamic-linker" "{{.*}}/libexec/ld-elf.so.1"
 // CHECK-MIPS64-NOT: "--hash-style={{gnu|both}}"
-// RUN: %clang %s -### -o %t.o 2>&1 \
+// RUN: %clang %s -### 2>&1 \
 // RUN:     -target mips64el-unknown-freebsd10.0 \
 // RUN:   | FileCheck --check-prefix=CHECK-MIPS64EL %s
 // CHECK-MIPS64EL: "{{[^" ]*}}ld{{[^" ]*}}"
@@ -97,17 +96,35 @@
 // CHECK-NORMAL: crt1.o
 // CHECK-NORMAL: crtbegin.o
 
-// RUN: %clang %s -### -o %t.o -target arm-unknown-freebsd10.0 2>&1 \
+// RUN: %clang %s -### -target arm-unknown-freebsd10.0 -no-integrated-as 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-ARM %s
-// CHECK-ARM: clang{{.*}}" "-cc1"{{.*}}" "-fsjlj-exceptions"
+// CHECK-ARM: "-cc1"{{.*}}" "-fsjlj-exceptions"
 // CHECK-ARM: as{{.*}}" "-mfpu=softvfp"{{.*}}"-matpcs"
+// CHECK-ARM-EABI-NOT: as{{.*}}" "-mfpu=vfp"
 
-// RUN: %clang %s -### -o %t.o -target arm-gnueabi-freebsd10.0 2>&1 \
+// RUN: %clang %s -### -target arm-gnueabi-freebsd10.0 -no-integrated-as 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-ARM-EABI %s
-// CHECK-ARM-EABI-NOT: clang{{.*}}" "-cc1"{{.*}}" "-fsjlj-exceptions"
+// CHECK-ARM-EABI-NOT: "-cc1"{{.*}}" "-fsjlj-exceptions"
 // CHECK-ARM-EABI: as{{.*}}" "-mfpu=softvfp" "-meabi=5"
+// CHECK-ARM-EABI-NOT: as{{.*}}" "-mfpu=vfp"
 // CHECK-ARM-EABI-NOT: as{{.*}}" "-matpcs"
 
-// RUN: %clang -target x86_64-pc-freebsd8 %s -### -flto -o %t.o 2>&1 \
+// RUN: %clang %s -### -target arm-gnueabihf-freebsd10.0 -no-integrated-as 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-ARM-EABIHF %s
+// CHECK-ARM-EABIHF-NOT: "-cc1"{{.*}}" "-fsjlj-exceptions"
+// CHECK-ARM-EABIHF: as{{.*}}" "-mfpu=vfp" "-meabi=5"
+// CHECK-ARM-EABIHF-NOT: as{{.*}}" "-mfpu=softvfp"
+// CHECK-ARM-EABIHF-NOT: as{{.*}}" "-matpcs"
+
+// RUN: %clang -target x86_64-pc-freebsd8 %s -### -flto 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-LTO %s
 // CHECK-LTO: ld{{.*}}" "-plugin{{.*}}LLVMgold.so
+
+// RUN: %clang -target sparc-unknown-freebsd8 %s -### -fpic 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-SPARC-PIE %s
+// CHECK-SPARC-PIE: as{{.*}}" "-KPIC
+
+// RUN: %clang -mcpu=ultrasparc -target sparc64-unknown-freebsd8 %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-SPARC-CPU %s
+// CHECK-SPARC-CPU: cc1{{.*}}" "-target-cpu" "ultrasparc"
+// CHECK-SPARC-CPU: as{{.*}}" "-Av9a
diff --git a/test/Driver/fsanitize.c b/test/Driver/fsanitize.c
index 2d07923..57ea5a2 100644
--- a/test/Driver/fsanitize.c
+++ b/test/Driver/fsanitize.c
@@ -1,4 +1,3 @@
-// RUN: %clang -target x86_64-linux-gnu -fcatch-undefined-behavior %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-TRAP
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-TRAP
 // RUN: %clang -target x86_64-linux-gnu -fsanitize-undefined-trap-on-error -fsanitize=undefined-trap %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-TRAP
 // CHECK-UNDEFINED-TRAP: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|shift|unreachable|return|vla-bound|alignment|null|object-size|float-cast-overflow|array-bounds|enum|bool),?){14}"}}
@@ -13,27 +12,12 @@
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=integer %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-INTEGER
 // CHECK-INTEGER: "-fsanitize={{((signed-integer-overflow|unsigned-integer-overflow|integer-divide-by-zero|shift),?){4}"}}
 
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=thread,undefined -fno-thread-sanitizer -fno-sanitize=float-cast-overflow,vptr,bool,enum %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-PARTIAL-UNDEFINED
+// RUN: %clang -fsanitize=bounds -### -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix=CHECK-BOUNDS
+// CHECK-BOUNDS: "-fsanitize={{((array-bounds|local-bounds),?){2}"}}
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=thread,undefined -fno-sanitize=thread -fno-sanitize=float-cast-overflow,vptr,bool,enum %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-PARTIAL-UNDEFINED
 // CHECK-PARTIAL-UNDEFINED: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|function|shift|unreachable|return|vla-bound|alignment|null|object-size|array-bounds),?){12}"}}
 
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=address-full %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-FULL
-// CHECK-ASAN-FULL: "-fsanitize={{((address|init-order|use-after-return|use-after-scope),?){4}"}}
-
-// RUN: %clang -target x86_64-linux-gnu -fno-sanitize=init-order,use-after-return -fsanitize=address %s -### 2>&1 |  FileCheck %s --check-prefix=CHECK-ASAN-IMPLIED-INIT-ORDER-UAR
-// CHECK-ASAN-IMPLIED-INIT-ORDER-UAR: "-fsanitize={{((address|init-order|use-after-return),?){3}"}}
-
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fno-sanitize=init-order %s -### 2>&1 |  FileCheck %s --check-prefix=CHECK-ASAN-NO-IMPLIED-INIT-ORDER
-// CHECK-ASAN-NO-IMPLIED-INIT-ORDER-NOT: init-order
-
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fno-sanitize=use-after-return %s -### 2>&1 |  FileCheck %s --check-prefix=CHECK-ASAN-NO-IMPLIED-UAR
-// CHECK-ASAN-NO-IMPLIED-UAR-NOT: use-after-return
-
-// RUN: %clang -target x86_64-linux-gnu -fcatch-undefined-behavior -fno-sanitize-undefined-trap-on-error %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-NO-TRAP-ERROR
-// CHECK-UNDEFINED-NO-TRAP-ERROR: '-fcatch-undefined-behavior' not allowed with '-fno-sanitize-undefined-trap-on-error'
-
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=vptr -fcatch-undefined-behavior %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-VPTR-UNDEF-ERROR
-// CHECK-VPTR-UNDEF-ERROR: '-fsanitize=vptr' not allowed with '-fcatch-undefined-behavior'
-
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined -fsanitize-undefined-trap-on-error %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-TRAP-ON-ERROR-UNDEF
 // CHECK-UNDEFINED-TRAP-ON-ERROR-UNDEF: '-fsanitize=undefined' not allowed with '-fsanitize-undefined-trap-on-error'
 
@@ -62,50 +46,43 @@
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=leak,memory -pie -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SANL-SANM
 // CHECK-SANL-SANM: '-fsanitize=leak' not allowed with '-fsanitize=memory'
 
-// RUN: %clang -target x86_64-linux-gnu -faddress-sanitizer -fthread-sanitizer -fno-rtti %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-TSAN
-// CHECK-ASAN-TSAN: '-faddress-sanitizer' not allowed with '-fthread-sanitizer'
-
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=init-order %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ONLY-EXTRA-ASAN
-// CHECK-ONLY-EXTRA-ASAN: '-fsanitize=init-order' is ignored in absence of '-fsanitize=address'
-
-// RUN: %clang -target x86_64-linux-gnu -Wno-unused-sanitize-argument -fsanitize=init-order %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-WNO-UNUSED-SANITIZE-ARGUMENT
-// CHECK-WNO-UNUSED-SANITIZE-ARGUMENT-NOT: '-fsanitize=init-order' is ignored in absence of '-fsanitize=address'
-
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=address,init-order -fno-sanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NOWARN-ONLY-EXTRA-ASAN
-// CHECK-NOWARN-ONLY-EXTRA-ASAN-NOT: is ignored in absence of '-fsanitize=address'
-
 // RUN: %clang -target x86_64-linux-gnu -fsanitize-memory-track-origins -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ONLY-TRACK-ORIGINS
 // CHECK-ONLY-TRACK-ORIGINS: warning: argument unused during compilation: '-fsanitize-memory-track-origins'
 
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-EXTRA-TRACK-ORIGINS
 // CHECK-NO-EXTRA-TRACK-ORIGINS-NOT: "-fsanitize-memory-track-origins"
 
-// RUN: %clang -target x86_64-linux-gnu -fsanitize-address-zero-base-shadow -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ONLY-ASAN-ZERO-BASE-SHADOW
-// CHECK-ONLY-ASAN-ZERO-BASE-SHADOW: warning: argument unused during compilation: '-fsanitize-address-zero-base-shadow'
-
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize=alignment -fsanitize=vptr -fno-sanitize=vptr %s -### 2>&1
 // OK
 
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -pie %s -### 2>&1
 // OK
 
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fsanitize-memory-track-origins -pie %s -### 2>&1
-// OK
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fsanitize-memory-track-origins -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TRACK-ORIGINS-1
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fsanitize-memory-track-origins=1 -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TRACK-ORIGINS-1
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fsanitize-memory-track-origins=2 -fsanitize-memory-track-origins -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TRACK-ORIGINS-1
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fno-sanitize-memory-track-origins -fsanitize-memory-track-origins -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TRACK-ORIGINS-1
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fsanitize-memory-track-origins=0 -fsanitize-memory-track-origins -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TRACK-ORIGINS-1
+
+// CHECK-TRACK-ORIGINS-1: -fsanitize-memory-track-origins=1
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fno-sanitize-memory-track-origins -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-TRACK-ORIGINS
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fsanitize-memory-track-origins=0 -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-TRACK-ORIGINS
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fsanitize-memory-track-origins -fno-sanitize-memory-track-origins -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-TRACK-ORIGINS
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fsanitize-memory-track-origins -fsanitize-memory-track-origins=0 -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-TRACK-ORIGINS
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fsanitize-memory-track-origins=2 -fno-sanitize-memory-track-origins -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-TRACK-ORIGINS
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fsanitize-memory-track-origins=2 -fsanitize-memory-track-origins=0 -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-TRACK-ORIGINS
+// CHECK-NO-TRACK-ORIGINS-NOT: sanitize-memory-track-origins
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fsanitize-memory-track-origins=2 -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TRACK-ORIGINS-2
+// CHECK-TRACK-ORIGINS-2: -fsanitize-memory-track-origins=2
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory -fsanitize-memory-track-origins=3 -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TRACK-ORIGINS-3
+// CHECK-TRACK-ORIGINS-3: error: invalid value '3' in '-fsanitize-memory-track-origins=3'
 
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=vptr -fno-sanitize=vptr -fsanitize=undefined,address %s -### 2>&1
 // OK
 
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-address-zero-base-shadow -pie %s -### 2>&1
-// OK
-
-// RUN: %clang -target x86_64-linux-gnu -fcatch-undefined-behavior -fthread-sanitizer -fno-thread-sanitizer -faddress-sanitizer -fno-address-sanitizer -fbounds-checking -### %s 2>&1 | FileCheck %s --check-prefix=CHECK-DEPRECATED
-// CHECK-DEPRECATED: argument '-fbounds-checking' is deprecated, use '-fsanitize=local-bounds' instead
-// CHECK-DEPRECATED: argument '-fno-address-sanitizer' is deprecated, use '-fno-sanitize=address' instead
-// CHECK-DEPRECATED: argument '-faddress-sanitizer' is deprecated, use '-fsanitize=address' instead
-// CHECK-DEPRECATED: argument '-fno-thread-sanitizer' is deprecated, use '-fno-sanitize=thread' instead
-// CHECK-DEPRECATED: argument '-fthread-sanitizer' is deprecated, use '-fsanitize=thread' instead
-// CHECK-DEPRECATED: argument '-fcatch-undefined-behavior' is deprecated, use '-fsanitize=undefined-trap -fsanitize-undefined-trap-on-error' instead
-
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-NO-PIE
 // CHECK-TSAN-NO-PIE: "-mrelocation-model" "pic" "-pic-level" "2" "-pie-level" "2"
 // CHECK-TSAN-NO-PIE: "-pie"
@@ -114,26 +91,12 @@
 // CHECK-MSAN-NO-PIE: "-mrelocation-model" "pic" "-pic-level" "2" "-pie-level" "2"
 // CHECK-MSAN-NO-PIE: "-pie"
 
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-address-zero-base-shadow %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-ZERO-BASE-SHADOW-NO-PIE
-// CHECK-ASAN-ZERO-BASE-SHADOW-NO-PIE: "-mrelocation-model" "pic" "-pic-level" "2" "-pie-level" "2"
-// CHECK-ASAN-ZERO-BASE-SHADOW-NO-PIE: "-pie"
-
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-address-zero-base-shadow -fno-sanitize-address-zero-base-shadow %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-ZERO-BASE-SHADOW-CANCEL
-// CHECK-ASAN-ZERO-BASE-SHADOW-CANCEL-NOT: "-mrelocation-model" "pic" "-pic-level" "2" "-pie-level" "2"
-// CHECK-ASAN-ZERO-BASE-SHADOW-CANCEL-NOT: "-pie"
-
 // RUN: %clang -target arm-linux-androideabi -fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ANDROID-ASAN-NO-PIE
 // CHECK-ANDROID-ASAN-NO-PIE: "-mrelocation-model" "pic" "-pic-level" "2" "-pie-level" "2"
 // CHECK-ANDROID-ASAN-NO-PIE: "-pie"
 
 // RUN: %clang -target arm-linux-androideabi %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ANDROID-NO-ASAN
-// CHECK-ANDROID-NO-ASAN: "-mrelocation-model" "static"
-
-// RUN: %clang -target arm-linux-androideabi -fsanitize=address -fsanitize-address-zero-base-shadow %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ANDROID-ASAN-ZERO-BASE
-// CHECK-ANDROID-ASAN-ZERO-BASE-NOT: argument unused during compilation
-
-// RUN: %clang -target arm-linux-androideabi -fsanitize=address -fno-sanitize-address-zero-base-shadow %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ANDROID-ASAN-NO-ZERO-BASE
-// CHECK-ANDROID-ASAN-NO-ZERO-BASE: '-fno-sanitize-address-zero-base-shadow' not allowed with '-fsanitize=address'
+// CHECK-ANDROID-NO-ASAN: "-mrelocation-model" "pic"
 
 // RUN: %clang -target x86_64-linux-gnu %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-RECOVER
 // RUN: %clang -target x86_64-linux-gnu %s -fsanitize-recover -### 2>&1 | FileCheck %s --check-prefix=CHECK-RECOVER
diff --git a/test/Driver/function-sections.c b/test/Driver/function-sections.c
new file mode 100644
index 0000000..fe6d303
--- /dev/null
+++ b/test/Driver/function-sections.c
@@ -0,0 +1,62 @@
+// Test handling of -f(no-)function-sections and -f(no-)data-sections
+//
+// CHECK-FS: -ffunction-sections
+// CHECK-NOFS-NOT: -ffunction-sections
+// CHECK-DS: -fdata-sections
+// CHECK-NODS-NOT: -fdata-sections
+
+// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1       \
+// RUN:     -target i386-unknown-linux \
+// RUN:   | FileCheck --check-prefix=CHECK-NOFS --check-prefix=CHECK-NODS %s
+
+// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1       \
+// RUN:     -target i386-unknown-linux \
+// RUN:     -ffunction-sections \
+// RUN:   | FileCheck --check-prefix=CHECK-FS %s
+
+// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1       \
+// RUN:     -target i386-unknown-linux \
+// RUN:     -fno-function-sections \
+// RUN:   | FileCheck --check-prefix=CHECK-NOFS %s
+
+// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1       \
+// RUN:     -target i386-unknown-linux \
+// RUN:     -ffunction-sections -fno-function-sections \
+// RUN:   | FileCheck --check-prefix=CHECK-NOFS %s
+
+// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1       \
+// RUN:     -target i386-unknown-linux \
+// RUN:     -fno-function-sections -ffunction-sections \
+// RUN:   | FileCheck --check-prefix=CHECK-FS %s
+
+// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1       \
+// RUN:     -target i386-unknown-linux \
+// RUN:     -ffunction-sections -fno-function-sections -ffunction-sections \
+// RUN:   | FileCheck --check-prefix=CHECK-FS %s
+
+
+// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1       \
+// RUN:     -target i386-unknown-linux \
+// RUN:     -fdata-sections \
+// RUN:   | FileCheck --check-prefix=CHECK-DS %s
+
+// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1       \
+// RUN:     -target i386-unknown-linux \
+// RUN:     -fno-data-sections \
+// RUN:   | FileCheck --check-prefix=CHECK-NODS %s
+
+// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1       \
+// RUN:     -target i386-unknown-linux \
+// RUN:     -fdata-sections -fno-data-sections \
+// RUN:   | FileCheck --check-prefix=CHECK-NODS %s
+
+// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1       \
+// RUN:     -target i386-unknown-linux \
+// RUN:     -fno-data-sections -fdata-sections \
+// RUN:   | FileCheck --check-prefix=CHECK-DS %s
+
+// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1       \
+// RUN:     -target i386-unknown-linux \
+// RUN:     -fdata-sections -fno-data-sections -fdata-sections \
+// RUN:   | FileCheck --check-prefix=CHECK-DS %s
+
diff --git a/test/Driver/fuse-ld.c b/test/Driver/fuse-ld.c
new file mode 100644
index 0000000..bd25b8d
--- /dev/null
+++ b/test/Driver/fuse-ld.c
@@ -0,0 +1,63 @@
+// RUN: %clang %s -### \
+// RUN:     -target x86_64-unknown-freebsd 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-FREEBSD-LD
+// CHECK-FREEBSD-LD: ld
+
+// RUN: %clang %s -### -fuse-ld=bfd \
+// RUN:     --sysroot=%S/Inputs/basic_freebsd_tree \
+// RUN:     -target x86_64-unknown-freebsd \
+// RUN:     -B%S/Inputs/basic_freebsd_tree/usr/bin 2>&1 \
+// RUN:   | FileCheck %s -check-prefix=CHECK-FREEBSD-BFD
+// CHECK-FREEBSD-BFD: Inputs/basic_freebsd_tree/usr/bin{{/|\\+}}ld.bfd
+
+// RUN: %clang %s -### -fuse-ld=gold \
+// RUN:     --sysroot=%S/Inputs/basic_freebsd_tree \
+// RUN:     -target x86_64-unknown-freebsd \
+// RUN:     -B%S/Inputs/basic_freebsd_tree/usr/bin 2>&1 \
+// RUN:   | FileCheck %s -check-prefix=CHECK-FREEBSD-GOLD
+// CHECK-FREEBSD-GOLD: Inputs/basic_freebsd_tree/usr/bin{{/|\\+}}ld.gold
+
+// RUN: %clang %s -### -fuse-ld=plib \
+// RUN:     --sysroot=%S/Inputs/basic_freebsd_tree \
+// RUN:     -target x86_64-unknown-freebsd \
+// RUN:     -B%S/Inputs/basic_freebsd_tree/usr/bin 2>&1 \
+// RUN:   | FileCheck %s -check-prefix=CHECK-FREEBSD-PLIB
+// CHECK-FREEBSD-PLIB: error: invalid linker name
+
+
+
+// RUN: %clang %s -### \
+// RUN:     -target arm-linux-androideabi \
+// RUN:     -B%S/Inputs/basic_android_tree/bin 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-ANDROID-ARM-LD
+// CHECK-ANDROID-ARM-LD: Inputs/basic_android_tree/bin{{/|\\+}}arm-linux-androideabi-ld
+
+// RUN: %clang %s -### -fuse-ld=bfd \
+// RUN:     -target arm-linux-androideabi \
+// RUN:     -B%S/Inputs/basic_android_tree/bin 2>&1 \
+// RUN:   | FileCheck %s -check-prefix=CHECK-ANDROID-ARM-BFD
+// CHECK-ANDROID-ARM-BFD: Inputs/basic_android_tree/bin{{/|\\+}}arm-linux-androideabi-ld.bfd
+
+// RUN: %clang %s -### -fuse-ld=gold \
+// RUN:     -target arm-linux-androideabi \
+// RUN:     -B%S/Inputs/basic_android_tree/bin 2>&1 \
+// RUN:   | FileCheck %s -check-prefix=CHECK-ANDROID-ARM-GOLD
+// CHECK-ANDROID-ARM-GOLD: Inputs/basic_android_tree/bin{{/|\\+}}arm-linux-androideabi-ld.gold
+
+// RUN: %clang %s -### \
+// RUN:     -target arm-linux-androideabi \
+// RUN:     -gcc-toolchain %S/Inputs/basic_android_tree 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-ANDROID-ARM-LD-TC
+// CHECK-ANDROID-ARM-LD-TC: Inputs/basic_android_tree/lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin{{/|\\+}}ld
+
+// RUN: %clang %s -### -fuse-ld=bfd \
+// RUN:     -target arm-linux-androideabi \
+// RUN:     -gcc-toolchain %S/Inputs/basic_android_tree 2>&1 \
+// RUN:   | FileCheck %s -check-prefix=CHECK-ANDROID-ARM-BFD-TC
+// CHECK-ANDROID-ARM-BFD-TC: Inputs/basic_android_tree/lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin{{/|\\+}}ld.bfd
+
+// RUN: %clang %s -### -fuse-ld=gold \
+// RUN:     -target arm-linux-androideabi \
+// RUN:     -gcc-toolchain %S/Inputs/basic_android_tree 2>&1 \
+// RUN:   | FileCheck %s -check-prefix=CHECK-ANDROID-ARM-GOLD-TC
+// CHECK-ANDROID-ARM-GOLD-TC: Inputs/basic_android_tree/lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin{{/|\\+}}ld.gold
diff --git a/test/Driver/gcc_forward.c b/test/Driver/gcc_forward.c
index b9933d7..3bc4131 100644
--- a/test/Driver/gcc_forward.c
+++ b/test/Driver/gcc_forward.c
@@ -13,19 +13,8 @@
 // CHECK: "-Wall" "-Wdocumentation"
 // CHECK: "-o" "{{[^"]+}}.s"
 //
-// gcc-as
-// CHECK: gcc{{[^"]*}}"
-// CHECK-NOT: "-mlinker-version=10"
-// CHECK-NOT: "-Xclang"
-// CHECK-NOT: "foo-bar"
-// CHECK-NOT: "-Wall"
-// CHECK-NOT: "-Wdocumentation"
-// CHECK: -march
-// CHECK-NOT: "-mlinker-version=10"
-// CHECK-NOT: "-Xclang"
-// CHECK-NOT: "foo-bar"
-// CHECK-NOT: "-Wall"
-// CHECK-NOT: "-Wdocumentation"
+// gnu-as
+// CHECK: as{{[^"]*}}"
 // CHECK: "-o" "{{[^"]+}}.o"
 //
 // gcc-ld
diff --git a/test/Driver/gold-lto.c b/test/Driver/gold-lto.c
index c2e8bdf..18a293b 100644
--- a/test/Driver/gold-lto.c
+++ b/test/Driver/gold-lto.c
@@ -19,3 +19,8 @@
 // CHECK-ARM-V7A: "-plugin" "{{.*}}/LLVMgold.so"
 // CHECK-ARM-V7A: "-plugin-opt=mcpu=cortex-a8"
 // CHECK-ARM-V7A: "-plugin-opt=foo"
+//
+// RUN: %clang -target i686-linux-android -### %t.o -flto 2>&1 \
+// RUN:     | FileCheck %s --check-prefix=CHECK-X86-ANDROID
+// CHECK-X86-ANDROID: "-pie"
+// CHECK-X86-ANDROID: "-plugin" "{{.*}}/LLVMgold.so"
diff --git a/test/Driver/hexagon-toolchain-elf.c b/test/Driver/hexagon-toolchain-elf.c
index f60c61c..87c33c7 100644
--- a/test/Driver/hexagon-toolchain-elf.c
+++ b/test/Driver/hexagon-toolchain-elf.c
@@ -1,5 +1,3 @@
-// REQUIRES: hexagon-registered-target
-
 // -----------------------------------------------------------------------------
 // Test standard include paths
 // -----------------------------------------------------------------------------
@@ -135,7 +133,7 @@
 // RUN:   -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK011 %s
-// CHECK011: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK011: "-cc1"
 // CHECK011-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK011-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK011-NOT: "-static"
@@ -159,7 +157,7 @@
 // RUN:   -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK012 %s
-// CHECK012: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK012: "-cc1"
 // CHECK012-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK012-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK012-NOT: "-static"
@@ -185,7 +183,7 @@
 // RUN:   -Lone -L two -L three \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK013 %s
-// CHECK013: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK013: "-cc1"
 // CHECK013-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK013-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK013: "{{.*}}/hexagon/lib/v4/crt0_standalone.o"
@@ -209,7 +207,7 @@
 // RUN:   -static \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK014 %s
-// CHECK014: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK014: "-cc1"
 // CHECK014-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK014-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK014: "-static"
@@ -230,7 +228,7 @@
 // RUN:   -shared \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK015 %s
-// CHECK015: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK015: "-cc1"
 // CHECK015-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK015-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK015: "-shared" "-call_shared"
@@ -260,7 +258,7 @@
 // RUN:   -static \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK016 %s
-// CHECK016: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK016: "-cc1"
 // CHECK016-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK016-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK016: "-shared" "-call_shared" "-static"
@@ -292,7 +290,7 @@
 // RUN:   -nostdlib \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK017 %s
-// CHECK017: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK017: "-cc1"
 // CHECK017-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK017-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK017-NOT: crt0_standalone.o
@@ -318,7 +316,7 @@
 // RUN:   -nostartfiles \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK018 %s
-// CHECK018: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK018: "-cc1"
 // CHECK018-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK018-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK018-NOT: crt0_standalone.o
@@ -344,7 +342,7 @@
 // RUN:   -nodefaultlibs \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK019 %s
-// CHECK019: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK019: "-cc1"
 // CHECK019-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK019-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK019: "{{.*}}/hexagon/lib/v4/crt0_standalone.o"
@@ -373,7 +371,7 @@
 // RUN:   -moslib=first -moslib=second \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK020 %s
-// CHECK020: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK020: "-cc1"
 // CHECK020-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK020-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK020-NOT: "-static"
@@ -398,7 +396,7 @@
 // RUN:   -moslib=first -moslib=second -moslib=standalone\
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK021 %s
-// CHECK021: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK021: "-cc1"
 // CHECK021-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK021-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK021-NOT: "-static"
@@ -430,7 +428,7 @@
 // RUN:   -uFoo -undefined Bar \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK022 %s
-// CHECK022: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK022: "-cc1"
 // CHECK022-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK022-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK022: "{{.*}}/hexagon/lib/v4/crt0_standalone.o"
@@ -457,7 +455,7 @@
 // RUN:   -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK023 %s
-// CHECK023:      "{{.*}}clang{{.*}}" "-cc1"
+// CHECK023:      "-cc1"
 // CHECK023:        "-mrelocation-model" "static"
 // CHECK023-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"
 // CHECK023-NOT:    "-G{{[0-9]+}}"
@@ -480,7 +478,7 @@
 // RUN:   -msmall-data-threshold=8 \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK024 %s
-// CHECK024:      "{{.*}}clang{{.*}}" "-cc1"
+// CHECK024:      "-cc1"
 // CHECK024-NOT:    "-mrelocation-model" "static"
 // CHECK024:        "-pic-level" "{{[12]}}"
 // CHECK024:        "-mllvm" "-hexagon-small-data-threshold=0"
@@ -504,7 +502,7 @@
 // RUN:   -msmall-data-threshold=8 \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK025 %s
-// CHECK025:      "{{.*}}clang{{.*}}" "-cc1"
+// CHECK025:      "-cc1"
 // CHECK025:        "-mrelocation-model" "static"
 // CHECK025:        "-mllvm" "-hexagon-small-data-threshold=8"
 // CHECK025-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"
@@ -520,7 +518,7 @@
 // RUN:   -pie \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK026 %s
-// CHECK026:      "{{.*}}clang{{.*}}" "-cc1"
+// CHECK026:      "-cc1"
 // CHECK026-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"
 // CHECK026-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK026:        "-pie"
@@ -530,7 +528,7 @@
 // RUN:   -pie -shared \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK027 %s
-// CHECK027:      "{{.*}}clang{{.*}}" "-cc1"
+// CHECK027:      "-cc1"
 // CHECK027-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"
 // CHECK027-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK027-NOT:    "-pie"
@@ -542,7 +540,7 @@
 // RUN:   -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK028 %s
-// CHECK028:      "{{.*}}clang{{.*}}" "-cc1"
+// CHECK028:      "-cc1"
 // CHECK028:        "-mqdsp6-compat"
 // CHECK028:        "-Wreturn-type"
 // CHECK028-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"
@@ -558,7 +556,7 @@
 // RUN:   -Xassembler --keep-locals \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK029 %s
-// CHECK029:      "{{.*}}clang{{.*}}" "-cc1"
+// CHECK029:      "-cc1"
 // CHECK029-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"
 // CHECK029:      "--noexecstack" "--trap" "--keep-locals"
 // CHECK029-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
diff --git a/test/Driver/hexagon-toolchain.c b/test/Driver/hexagon-toolchain.c
index f3d7e25..88440f8 100644
--- a/test/Driver/hexagon-toolchain.c
+++ b/test/Driver/hexagon-toolchain.c
@@ -1,5 +1,3 @@
-// REQUIRES: hexagon-registered-target
-
 // -----------------------------------------------------------------------------
 // Test standard include paths
 // -----------------------------------------------------------------------------
@@ -135,7 +133,7 @@
 // RUN:   -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK011 %s
-// CHECK011: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK011: "-cc1"
 // CHECK011-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK011-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK011-NOT: "-static"
@@ -159,7 +157,7 @@
 // RUN:   -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK012 %s
-// CHECK012: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK012: "-cc1"
 // CHECK012-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK012-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK012-NOT: "-static"
@@ -185,7 +183,7 @@
 // RUN:   -Lone -L two -L three \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK013 %s
-// CHECK013: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK013: "-cc1"
 // CHECK013-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK013-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK013: "{{.*}}/hexagon/lib/v4/crt0_standalone.o"
@@ -209,7 +207,7 @@
 // RUN:   -static \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK014 %s
-// CHECK014: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK014: "-cc1"
 // CHECK014-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK014-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK014: "-static"
@@ -230,7 +228,7 @@
 // RUN:   -shared \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK015 %s
-// CHECK015: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK015: "-cc1"
 // CHECK015-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK015-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK015: "-shared" "-call_shared"
@@ -260,7 +258,7 @@
 // RUN:   -static \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK016 %s
-// CHECK016: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK016: "-cc1"
 // CHECK016-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK016-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK016: "-shared" "-call_shared" "-static"
@@ -292,7 +290,7 @@
 // RUN:   -nostdlib \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK017 %s
-// CHECK017: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK017: "-cc1"
 // CHECK017-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK017-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK017-NOT: crt0_standalone.o
@@ -318,7 +316,7 @@
 // RUN:   -nostartfiles \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK018 %s
-// CHECK018: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK018: "-cc1"
 // CHECK018-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK018-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK018-NOT: crt0_standalone.o
@@ -344,7 +342,7 @@
 // RUN:   -nodefaultlibs \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK019 %s
-// CHECK019: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK019: "-cc1"
 // CHECK019-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK019-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK019: "{{.*}}/hexagon/lib/v4/crt0_standalone.o"
@@ -373,7 +371,7 @@
 // RUN:   -moslib=first -moslib=second \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK020 %s
-// CHECK020: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK020: "-cc1"
 // CHECK020-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK020-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK020-NOT: "-static"
@@ -398,7 +396,7 @@
 // RUN:   -moslib=first -moslib=second -moslib=standalone\
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK021 %s
-// CHECK021: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK021: "-cc1"
 // CHECK021-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK021-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK021-NOT: "-static"
@@ -430,7 +428,7 @@
 // RUN:   -uFoo -undefined Bar \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK022 %s
-// CHECK022: "{{.*}}clang{{.*}}" "-cc1"
+// CHECK022: "-cc1"
 // CHECK022-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"{{.*}}
 // CHECK022-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK022: "{{.*}}/hexagon/lib/v4/crt0_standalone.o"
@@ -457,7 +455,7 @@
 // RUN:   -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK023 %s
-// CHECK023:      "{{.*}}clang{{.*}}" "-cc1"
+// CHECK023:      "-cc1"
 // CHECK023:        "-mrelocation-model" "static"
 // CHECK023-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"
 // CHECK023-NOT:    "-G{{[0-9]+}}"
@@ -480,7 +478,7 @@
 // RUN:   -msmall-data-threshold=8 \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK024 %s
-// CHECK024:      "{{.*}}clang{{.*}}" "-cc1"
+// CHECK024:      "-cc1"
 // CHECK024-NOT:    "-mrelocation-model" "static"
 // CHECK024:        "-pic-level" "{{[12]}}"
 // CHECK024:        "-mllvm" "-hexagon-small-data-threshold=0"
@@ -504,7 +502,7 @@
 // RUN:   -msmall-data-threshold=8 \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK025 %s
-// CHECK025:      "{{.*}}clang{{.*}}" "-cc1"
+// CHECK025:      "-cc1"
 // CHECK025:        "-mrelocation-model" "static"
 // CHECK025:        "-mllvm" "-hexagon-small-data-threshold=8"
 // CHECK025-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"
@@ -520,7 +518,7 @@
 // RUN:   -pie \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK026 %s
-// CHECK026:      "{{.*}}clang{{.*}}" "-cc1"
+// CHECK026:      "-cc1"
 // CHECK026-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"
 // CHECK026-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK026:        "-pie"
@@ -530,7 +528,7 @@
 // RUN:   -pie -shared \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK027 %s
-// CHECK027:      "{{.*}}clang{{.*}}" "-cc1"
+// CHECK027:      "-cc1"
 // CHECK027-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"
 // CHECK027-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
 // CHECK027-NOT:    "-pie"
@@ -542,7 +540,7 @@
 // RUN:   -ccc-install-dir %S/Inputs/hexagon_tree/qc/bin \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK028 %s
-// CHECK028:      "{{.*}}clang{{.*}}" "-cc1"
+// CHECK028:      "-cc1"
 // CHECK028:        "-mqdsp6-compat"
 // CHECK028:        "-Wreturn-type"
 // CHECK028-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"
@@ -558,7 +556,7 @@
 // RUN:   -Xassembler --keep-locals \
 // RUN:   %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK029 %s
-// CHECK029:      "{{.*}}clang{{.*}}" "-cc1"
+// CHECK029:      "-cc1"
 // CHECK029-NEXT: "{{.*}}/bin{{/|\\}}hexagon-as"
 // CHECK029:      "--noexecstack" "--trap" "--keep-locals"
 // CHECK029-NEXT: "{{.*}}/bin{{/|\\}}hexagon-ld"
diff --git a/test/Driver/ident_md.c b/test/Driver/ident_md.c
index d7da317..7b2b2f6 100644
--- a/test/Driver/ident_md.c
+++ b/test/Driver/ident_md.c
@@ -1,6 +1,6 @@
 // RUN: %clang %s -emit-llvm -S -o - | FileCheck %s
 // Verify that clang version appears in the llvm.ident metadata.
 
-// CHECK: !llvm.ident = !{!0}
-// CHECK: !0 = metadata !{metadata !{{.*}}
+// CHECK: !llvm.ident = !{{{.*}}}
+// CHECK: !{{[0-9]+}} = metadata !{metadata !{{.*}}
 
diff --git a/test/Driver/implicit-function-as-error.c b/test/Driver/implicit-function-as-error.c
new file mode 100644
index 0000000..5949e20
--- /dev/null
+++ b/test/Driver/implicit-function-as-error.c
@@ -0,0 +1,9 @@
+// RUN: %clang -target x86_64-apple-darwin -mios-simulator-version-min=7 -fsyntax-only %s -Xclang -verify
+// RUN: %clang -target x86_64-apple-darwin -arch arm64 -target x86_64-apple-darwin -mios-version-min=7 -fsyntax-only %s -Xclang -verify
+
+// For 64-bit iOS, automatically promote -Wimplicit-function-declaration
+// to an error.
+
+void radar_10894044() {
+  radar_10894044_not_declared(); // expected-error {{implicit declaration of function 'radar_10894044_not_declared' is invalid in C99}}
+}
diff --git a/test/Driver/instrprof-ld.c b/test/Driver/instrprof-ld.c
new file mode 100644
index 0000000..f70ae47
--- /dev/null
+++ b/test/Driver/instrprof-ld.c
@@ -0,0 +1,58 @@
+// 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:     -resource-dir=%S/Inputs/resource_dir \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-LINUX-I386 %s
+//
+// CHECK-LINUX-I386: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// 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:     -resource-dir=%S/Inputs/resource_dir \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-LINUX-X86-64 %s
+//
+// CHECK-LINUX-X86-64: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// 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 -fprofile-instr-generate \
+// RUN:     -resource-dir=%S/Inputs/resource_dir \
+// RUN:     --sysroot=%S/Inputs/basic_freebsd64_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-FREEBSD-X86-64 %s
+//
+// CHECK-FREEBSD-X86-64: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// 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:     -shared \
+// RUN:     -target i386-unknown-linux -fprofile-instr-generate \
+// RUN:     -resource-dir=%S/Inputs/resource_dir \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-LINUX-I386-SHARED %s
+//
+// CHECK-LINUX-I386-SHARED: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-LINUX-I386-SHARED: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}linux{{/|\\\\}}libclang_rt.profile-pic-i386.a" {{.*}} "-lc"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     -shared \
+// RUN:     -target x86_64-unknown-linux -fprofile-instr-generate \
+// RUN:     -resource-dir=%S/Inputs/resource_dir \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-LINUX-X86-64-SHARED %s
+//
+// CHECK-LINUX-X86-64-SHARED: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-LINUX-X86-64-SHARED: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}linux{{/|\\\\}}libclang_rt.profile-pic-x86_64.a" {{.*}} "-lc"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     -shared \
+// RUN:     -target x86_64-unknown-freebsd -fprofile-instr-generate \
+// RUN:     -resource-dir=%S/Inputs/resource_dir \
+// RUN:     --sysroot=%S/Inputs/basic_freebsd64_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-FREEBSD-X86-64-SHARED %s
+//
+// CHECK-FREEBSD-X86-64-SHARED: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-FREEBSD-X86-64-SHARED: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}freebsd{{/|\\\\}}libclang_rt.profile-pic-x86_64.a"
diff --git a/test/Driver/integrated-as.c b/test/Driver/integrated-as.c
index e73174e..c65973c 100644
--- a/test/Driver/integrated-as.c
+++ b/test/Driver/integrated-as.c
@@ -2,3 +2,14 @@
 
 // CHECK: cc1as
 // CHECK: -mrelax-all
+
+// RUN: %clang -### -fintegrated-as -c -save-temps %s 2>&1 | FileCheck %s -check-prefix FIAS
+
+// FIAS: cc1as
+
+// RUN: %clang -### -fno-integrated-as -S %s 2>&1 \
+// RUN:     | FileCheck %s -check-prefix NOFIAS
+
+// NOFIAS-NOT: cc1as
+// NOFIAS: -cc1
+// NOFIAS: -no-integrated-as
diff --git a/test/Driver/integrated-as.s b/test/Driver/integrated-as.s
index 0843cf9..9a7d2c5 100644
--- a/test/Driver/integrated-as.s
+++ b/test/Driver/integrated-as.s
@@ -5,29 +5,41 @@
 // RUN: %clang -### -c -integrated-as -Wa,-L %s 2>&1 | FileCheck --check-prefix=OPT_L %s
 // OPT_L: msave-temp-labels
 
-// RUN: not %clang -c -integrated-as -Wa,--compress-debug-sections %s 2>&1 | FileCheck --check-prefix=INVALID %s
-// INVALID: error: unsupported argument '--compress-debug-sections' to option 'Wa,'
-
 // RUN: %clang -### -target x86_64-linux-gnu -c -integrated-as %s -fsanitize=address 2>&1 %s | FileCheck --check-prefix=SANITIZE %s
 // SANITIZE: argument unused during compilation: '-fsanitize=address'
 
 // 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 %s | FileCheck --check-prefix=WA_INCLUDE1 %s
+// RUN: %clang -### -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 %s | FileCheck --check-prefix=WA_INCLUDE2 %s
+// RUN: %clang -### -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 %s | FileCheck --check-prefix=WA_INCLUDE3 %s
+// RUN: %clang -### -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 %s | FileCheck --check-prefix=XA_INCLUDE1 %s
+// RUN: %clang -### -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 %s | FileCheck --check-prefix=XA_INCLUDE2 %s
+// RUN: %clang -### -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-2 2>&1 | FileCheck --check-prefix=DWARF2 %s
+// DWARF2: "-g" "-gdwarf-2"
+
+// RUN: %clang -### -c -integrated-as %s -gdwarf-3 2>&1 | FileCheck --check-prefix=DWARF3 %s
+// DWARF3: "-g" "-gdwarf-3"
+
+// RUN: %clang -### -c -integrated-as %s -gdwarf-4 2>&1 | FileCheck --check-prefix=DWARF4 %s
+// DWARF4: "-g" "-gdwarf-4"
+
+// RUN: %clang -### -c -integrated-as %s -Xassembler -gdwarf-2 2>&1 | FileCheck --check-prefix=DWARF2XASSEMBLER %s
+// DWARF2XASSEMBLER: "-gdwarf-2"
+
+// RUN: %clang -### -c -integrated-as %s -Wa,-gdwarf-2 2>&1 | FileCheck --check-prefix=DWARF2WA %s
+// DWARF2WA: "-gdwarf-2"
diff --git a/test/Driver/krait-cpu.c b/test/Driver/krait-cpu.c
new file mode 100644
index 0000000..ee324b6
--- /dev/null
+++ b/test/Driver/krait-cpu.c
@@ -0,0 +1,3 @@
+// ================== Check default Architecture on krait CPU
+// RUN: %clang -target arm-linux-gnueabi -mcpu=krait -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV7A %s
+// CHECK-CPUV7A: "-cc1"{{.*}} "-triple" "armv7-{{.*}}
diff --git a/test/Driver/linker-opts.c b/test/Driver/linker-opts.c
index 7668a75..24866a6 100644
--- a/test/Driver/linker-opts.c
+++ b/test/Driver/linker-opts.c
@@ -4,3 +4,8 @@
 // GCC driver is used as linker on cygming. It should be aware of LIBRARY_PATH.
 // XFAIL: win32
 // REQUIRES: clang-driver
+// REQUIRES: native
+
+// Make sure that LIBRARY_PATH works for both i386 and x86_64 on Darwin.
+// RUN: env LIBRARY_PATH=%T/test1 %clang -target x86_64-apple-darwin %s -### 2>&1 | FileCheck %s
+// RUN: env LIBRARY_PATH=%T/test1 %clang -target i386-apple-darwin  %s -### 2>&1 | FileCheck %s
diff --git a/test/Driver/linux-as.c b/test/Driver/linux-as.c
index a449b7b..05c7fa7 100644
--- a/test/Driver/linux-as.c
+++ b/test/Driver/linux-as.c
@@ -60,6 +60,32 @@
 // RUN:   | FileCheck -check-prefix=CHECK-PPC-NO-MCPU %s
 // CHECK-PPC-NO-MCPU-NOT: as{{.*}} "-mcpu=invalid-cpu"
 //
+// RUN: %clang -target sparc64-linux -mcpu=invalid-cpu -### \
+// RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-SPARCV9 %s
+// CHECK-SPARCV9: as
+// CHECK-SPARCV9: -64
+// CHECK-SPARCV9: -Av9a
+// CHECK-SPARCV9-NOT: -KPIC
+// CHECK-SPARCV9: -o
+//
+// RUN: %clang -target sparc64-linux -mcpu=invalid-cpu -### \
+// RUN:   -no-integrated-as -fpic -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-SPARCV9PIC %s
+// CHECK-SPARCV9PIC: as
+// CHECK-SPARCV9PIC: -64
+// CHECK-SPARCV9PIC: -Av9a
+// CHECK-SPARCV9PIC: -KPIC
+// CHECK-SPARCV9PIC: -o
+//
+// RUN: %clang -target sparc-linux -mcpu=invalid-cpu -### \
+// RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-SPARCV8 %s
+// CHECK-SPARCV8: as
+// CHECK-SPARCV8: -32
+// CHECK-SPARCV8: -Av8plusa
+// CHECK-SPARCV8: -o
+//
 // RUN: %clang -target s390x-linux -### -no-integrated-as -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK-Z-DEFAULT-ARCH %s
 // CHECK-Z-DEFAULT-ARCH: as{{.*}} "-march=z10"
diff --git a/test/Driver/linux-header-search.cpp b/test/Driver/linux-header-search.cpp
index 8955ed7..309ece2 100644
--- a/test/Driver/linux-header-search.cpp
+++ b/test/Driver/linux-header-search.cpp
@@ -1,6 +1,29 @@
 // General tests that the header search paths detected by the driver and passed
 // to CC1 are sane.
 //
+// Test a simulated installation of libc++ on Linux, both through sysroot and
+// the installation path of Clang.
+// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \
+// RUN:     -target x86_64-unknown-linux-gnu \
+// RUN:     -stdlib=libc++ \
+// RUN:     -ccc-install-dir %S/Inputs/basic_linux_tree/usr/bin \
+// RUN:     --sysroot=%S/Inputs/basic_linux_libcxx_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BASIC-LIBCXX-SYSROOT %s
+// CHECK-BASIC-LIBCXX-SYSROOT: "{{[^"]*}}clang{{[^"]*}}" "-cc1"
+// CHECK-BASIC-LIBCXX-SYSROOT: "-isysroot" "[[SYSROOT:[^"]+]]"
+// CHECK-BASIC-LIBCXX-SYSROOT: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1"
+// CHECK-BASIC-LIBCXX-SYSROOT: "-internal-isystem" "[[SYSROOT]]/usr/local/include"
+// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \
+// RUN:     -target x86_64-unknown-linux-gnu \
+// RUN:     -stdlib=libc++ \
+// RUN:     -ccc-install-dir %S/Inputs/basic_linux_libcxx_tree/usr/bin \
+// RUN:     --sysroot=%S/Inputs/basic_linux_libcxx_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BASIC-LIBCXX-INSTALL %s
+// CHECK-BASIC-LIBCXX-INSTALL: "{{[^"]*}}clang{{[^"]*}}" "-cc1"
+// CHECK-BASIC-LIBCXX-INSTALL: "-isysroot" "[[SYSROOT:[^"]+]]"
+// CHECK-BASIC-LIBCXX-INSTALL: "-internal-isystem" "[[SYSROOT]]/usr/bin/../include/c++/v1"
+// CHECK-BASIC-LIBCXX-INSTALL: "-internal-isystem" "[[SYSROOT]]/usr/local/include"
+//
 // Test a very broken version of multiarch that shipped in Ubuntu 11.04.
 // RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \
 // RUN:     -target i386-unknown-linux \
@@ -12,7 +35,7 @@
 // CHECK-UBUNTU-11-04: "-internal-isystem" "[[SYSROOT]]/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5/../../../../../include/c++/4.5/i686-linux-gnu"
 // CHECK-UBUNTU-11-04: "-internal-isystem" "[[SYSROOT]]/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/4.5/../../../../../include/c++/4.5/backward"
 // CHECK-UBUNTU-11-04: "-internal-isystem" "[[SYSROOT]]/usr/local/include"
-// CHECK-UBUNTU-11-04: "-internal-isystem" "{{.*}}{{/|\\\\}}lib{{(64|32)?}}{{/|\\\\}}clang{{/|\\\\}}{{[0-9]\.[0-9]}}{{/|\\\\}}include"
+// CHECK-UBUNTU-11-04: "-internal-isystem" "{{.*}}{{/|\\\\}}lib{{(64|32)?}}{{/|\\\\}}clang{{/|\\\\}}{{[0-9]\.[0-9]\.[0-9]}}{{/|\\\\}}include"
 // CHECK-UBUNTU-11-04: "-internal-externc-isystem" "[[SYSROOT]]/include"
 // CHECK-UBUNTU-11-04: "-internal-externc-isystem" "[[SYSROOT]]/usr/include"
 //
@@ -23,25 +46,40 @@
 // CHECK-UBUNTU-13-04: "{{[^"]*}}clang{{[^"]*}}" "-cc1"
 // CHECK-UBUNTU-13-04: "-isysroot" "[[SYSROOT:[^"]+]]"
 // CHECK-UBUNTU-13-04: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7"
-// CHECK-UBUNTU-13-04: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/backward"
 // CHECK-UBUNTU-13-04: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/x86_64-linux-gnu/c++/4.7"
+// CHECK-UBUNTU-13-04: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/backward"
 // CHECK-UBUNTU-13-04: "-internal-isystem" "[[SYSROOT]]/usr/local/include"
-// CHECK-UBUNTU-13-04: "-internal-isystem" "{{.*}}{{/|\\\\}}lib{{(64|32)?}}{{/|\\\\}}clang{{/|\\\\}}{{[0-9]\.[0-9]}}{{/|\\\\}}include"
+// CHECK-UBUNTU-13-04: "-internal-isystem" "{{.*}}{{/|\\\\}}lib{{(64|32)?}}{{/|\\\\}}clang{{/|\\\\}}{{[0-9]\.[0-9]\.[0-9]}}{{/|\\\\}}include"
 // CHECK-UBUNTU-13-04: "-internal-externc-isystem" "[[SYSROOT]]/usr/include/x86_64-linux-gnu"
 // CHECK-UBUNTU-13-04: "-internal-externc-isystem" "[[SYSROOT]]/include"
 // CHECK-UBUNTU-13-04: "-internal-externc-isystem" "[[SYSROOT]]/usr/include"
 //
 // RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \
+// RUN:     -target x86_64-unknown-linux-gnux32 \
+// RUN:     --sysroot=%S/Inputs/ubuntu_14.04_multiarch_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-UBUNTU-14-04 %s
+// CHECK-UBUNTU-14-04: "{{[^"]*}}clang{{[^"]*}}" "-cc1"
+// CHECK-UBUNTU-14-04: "-isysroot" "[[SYSROOT:[^"]+]]"
+// CHECK-UBUNTU-14-04: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8"
+// CHECK-UBUNTU-14-04: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/x86_64-linux-gnu/c++/4.8/x32"
+// CHECK-UBUNTU-14-04: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/backward"
+// CHECK-UBUNTU-14-04: "-internal-isystem" "[[SYSROOT]]/usr/local/include"
+// CHECK-UBUNTU-14-04: "-internal-isystem" "{{.*}}{{/|\\\\}}lib{{(64|x32)?}}{{/|\\\\}}clang{{/|\\\\}}{{[0-9]\.[0-9]\.[0-9]}}{{/|\\\\}}include"
+// CHECK-UBUNTU-14-04: "-internal-externc-isystem" "[[SYSROOT]]/usr/include/x86_64-linux-gnu"
+// CHECK-UBUNTU-14-04: "-internal-externc-isystem" "[[SYSROOT]]/include"
+// CHECK-UBUNTU-14-04: "-internal-externc-isystem" "[[SYSROOT]]/usr/include"
+///
+// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \
 // RUN:     -target arm-linux-gnueabihf \
 // RUN:     --sysroot=%S/Inputs/ubuntu_13.04_multiarch_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-UBUNTU-13-04-CROSS %s
 // CHECK-UBUNTU-13-04-CROSS: "{{[^"]*}}clang{{[^"]*}}" "-cc1"
 // CHECK-UBUNTU-13-04-CROSS: "-isysroot" "[[SYSROOT:[^"]+]]"
 // CHECK-UBUNTU-13-04-CROSS: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc-cross/arm-linux-gnueabihf/4.7/../../../../include/c++/4.7"
-// CHECK-UBUNTU-13-04-CROSS: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc-cross/arm-linux-gnueabihf/4.7/../../../../include/c++/4.7/backward"
 // CHECK-UBUNTU-13-04-CROSS: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc-cross/arm-linux-gnueabihf/4.7/../../../../include/arm-linux-gnueabihf/c++/4.7"
+// CHECK-UBUNTU-13-04-CROSS: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc-cross/arm-linux-gnueabihf/4.7/../../../../include/c++/4.7/backward"
 // CHECK-UBUNTU-13-04-CROSS: "-internal-isystem" "[[SYSROOT]]/usr/local/include"
-// CHECK-UBUNTU-13-04-CROSS: "-internal-isystem" "{{.*}}{{/|\\\\}}lib{{(64|32)?}}{{/|\\\\}}clang{{/|\\\\}}{{[0-9]\.[0-9]}}{{/|\\\\}}include"
+// CHECK-UBUNTU-13-04-CROSS: "-internal-isystem" "{{.*}}{{/|\\\\}}lib{{(64|32)?}}{{/|\\\\}}clang{{/|\\\\}}{{[0-9]\.[0-9]\.[0-9]}}{{/|\\\\}}include"
 // CHECK-UBUNTU-13-04-CROSS: "-internal-externc-isystem" "[[SYSROOT]]/include"
 // CHECK-UBUNTU-13-04-CROSS: "-internal-externc-isystem" "[[SYSROOT]]/usr/include"
 //
@@ -54,9 +92,50 @@
 // CHECK-UBUNTU-13-04-M32: "-triple" "i386-unknown-linux-gnu"
 // CHECK-UBUNTU-13-04-M32: "-isysroot" "[[SYSROOT:[^"]+]]"
 // CHECK-UBUNTU-13-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7"
-// CHECK-UBUNTU-13-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/x86_64-linux-gnu/32"
-// CHECK-UBUNTU-13-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/backward"
 // CHECK-UBUNTU-13-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/x86_64-linux-gnu/c++/4.7/32"
+// CHECK-UBUNTU-13-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/backward"
+//
+// Test Ubuntu/Debian's Ubuntu 14.04 config variant, with -m32
+// and an empty 4.9 directory.
+// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \
+// RUN:     -target x86_64-unknown-linux-gnu -m32 \
+// RUN:     --sysroot=%S/Inputs/ubuntu_14.04_multiarch_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-UBUNTU-14-04-M32 %s
+// CHECK-UBUNTU-14-04-M32: "{{[^"]*}}clang{{[^"]*}}" "-cc1"
+// CHECK-UBUNTU-14-04-M32: "-triple" "i386-unknown-linux-gnu"
+// CHECK-UBUNTU-14-04-M32: "-isysroot" "[[SYSROOT:[^"]+]]"
+// CHECK-UBUNTU-14-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8"
+// CHECK-UBUNTU-14-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/x86_64-linux-gnu/c++/4.8/32"
+// CHECK-UBUNTU-14-04-M32: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/backward"
+//
+// Test Ubuntu/Debian's Ubuntu 14.04 with -m32 and an i686 cross compiler
+// installed rather than relying on multilib. Also happens to look like an
+// actual i686 Ubuntu system.
+// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \
+// RUN:     -target x86_64-unknown-linux-gnu -m32 \
+// RUN:     --sysroot=%S/Inputs/ubuntu_14.04_multiarch_tree2 \
+// RUN:   | FileCheck --check-prefix=CHECK-UBUNTU-14-04-I686 %s
+// CHECK-UBUNTU-14-04-I686: "{{[^"]*}}clang{{[^"]*}}" "-cc1"
+// CHECK-UBUNTU-14-04-I686: "-triple" "i386-unknown-linux-gnu"
+// CHECK-UBUNTU-14-04-I686: "-isysroot" "[[SYSROOT:[^"]+]]"
+// CHECK-UBUNTU-14-04-I686: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/i686-linux-gnu/4.8/../../../../include/c++/4.8"
+// CHECK-UBUNTU-14-04-I686: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/i686-linux-gnu/4.8/../../../../include/i386-linux-gnu/c++/4.8"
+// CHECK-UBUNTU-14-04-I686: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/i686-linux-gnu/4.8/../../../../include/c++/4.8/backward"
+//
+// Test Ubuntu/Debian's Ubuntu 14.04 for powerpc64le
+// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \
+// RUN:     -target powerpc64le-unknown-linux-gnu -m32 \
+// RUN:     --sysroot=%S/Inputs/ubuntu_14.04_multiarch_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-UBUNTU-14-04-PPC64LE %s
+// CHECK-UBUNTU-14-04-PPC64LE: "{{[^"]*}}clang{{[^"]*}}" "-cc1"
+// CHECK-UBUNTU-14-04-PPC64LE: "-triple" "powerpc64le-unknown-linux-gnu"
+// CHECK-UBUNTU-14-04-PPC64LE: "-isysroot" "[[SYSROOT:[^"]+]]"
+// CHECK-UBUNTU-14-04-PPC64LE: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/powerpc64le-linux-gnu/4.8/../../../../include/c++/4.8"
+// CHECK-UBUNTU-14-04-PPC64LE: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/powerpc64le-linux-gnu/4.8/../../../../include/powerpc64le-linux-gnu/c++/4.8"
+// CHECK-UBUNTU-14-04-PPC64LE: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/powerpc64le-linux-gnu/4.8/../../../../include/c++/4.8/backward"
+// CHECK-UBUNTU-14-04-PPC64LE: "-internal-externc-isystem" "[[SYSROOT]]/usr/include/powerpc64le-linux-gnu"
+// CHECK-UBUNTU-14-04-PPC64LE: "-internal-externc-isystem" "[[SYSROOT]]/include"
+// CHECK-UBUNTU-14-04-PPC64LE: "-internal-externc-isystem" "[[SYSROOT]]/usr/include"
 //
 // Thoroughly exercise the Debian multiarch environment.
 // RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \
@@ -69,7 +148,7 @@
 // CHECK-DEBIAN-X86: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/i686-linux-gnu/4.5/../../../../include/c++/4.5/i686-linux-gnu"
 // CHECK-DEBIAN-X86: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/i686-linux-gnu/4.5/../../../../include/c++/4.5/backward"
 // CHECK-DEBIAN-X86: "-internal-isystem" "[[SYSROOT]]/usr/local/include"
-// CHECK-DEBIAN-X86: "-internal-isystem" "{{.*}}{{/|\\\\}}lib{{(64|32)?}}{{/|\\\\}}clang{{/|\\\\}}{{[0-9]\.[0-9]}}{{/|\\\\}}include"
+// CHECK-DEBIAN-X86: "-internal-isystem" "{{.*}}{{/|\\\\}}lib{{(64|32)?}}{{/|\\\\}}clang{{/|\\\\}}{{[0-9]\.[0-9]\.[0-9]}}{{/|\\\\}}include"
 // CHECK-DEBIAN-X86: "-internal-externc-isystem" "[[SYSROOT]]/usr/include/i386-linux-gnu"
 // CHECK-DEBIAN-X86: "-internal-externc-isystem" "[[SYSROOT]]/include"
 // CHECK-DEBIAN-X86: "-internal-externc-isystem" "[[SYSROOT]]/usr/include"
@@ -83,7 +162,7 @@
 // CHECK-DEBIAN-X86-64: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.5/../../../../include/c++/4.5/x86_64-linux-gnu"
 // CHECK-DEBIAN-X86-64: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.5/../../../../include/c++/4.5/backward"
 // CHECK-DEBIAN-X86-64: "-internal-isystem" "[[SYSROOT]]/usr/local/include"
-// CHECK-DEBIAN-X86-64: "-internal-isystem" "{{.*}}{{/|\\\\}}lib{{(64|32)?}}{{/|\\\\}}clang{{/|\\\\}}{{[0-9]\.[0-9]}}{{/|\\\\}}include"
+// CHECK-DEBIAN-X86-64: "-internal-isystem" "{{.*}}{{/|\\\\}}lib{{(64|32)?}}{{/|\\\\}}clang{{/|\\\\}}{{[0-9]\.[0-9]\.[0-9]}}{{/|\\\\}}include"
 // CHECK-DEBIAN-X86-64: "-internal-externc-isystem" "[[SYSROOT]]/usr/include/x86_64-linux-gnu"
 // CHECK-DEBIAN-X86-64: "-internal-externc-isystem" "[[SYSROOT]]/include"
 // CHECK-DEBIAN-X86-64: "-internal-externc-isystem" "[[SYSROOT]]/usr/include"
@@ -97,7 +176,7 @@
 // CHECK-DEBIAN-PPC: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/powerpc-linux-gnu/4.5/../../../../include/c++/4.5/powerpc-linux-gnu"
 // CHECK-DEBIAN-PPC: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/powerpc-linux-gnu/4.5/../../../../include/c++/4.5/backward"
 // CHECK-DEBIAN-PPC: "-internal-isystem" "[[SYSROOT]]/usr/local/include"
-// CHECK-DEBIAN-PPC: "-internal-isystem" "{{.*}}{{/|\\\\}}lib{{(64|32)?}}{{/|\\\\}}clang{{/|\\\\}}{{[0-9]\.[0-9]}}{{/|\\\\}}include"
+// CHECK-DEBIAN-PPC: "-internal-isystem" "{{.*}}{{/|\\\\}}lib{{(64|32)?}}{{/|\\\\}}clang{{/|\\\\}}{{[0-9]\.[0-9]\.[0-9]}}{{/|\\\\}}include"
 // CHECK-DEBIAN-PPC: "-internal-externc-isystem" "[[SYSROOT]]/usr/include/powerpc-linux-gnu"
 // CHECK-DEBIAN-PPC: "-internal-externc-isystem" "[[SYSROOT]]/include"
 // CHECK-DEBIAN-PPC: "-internal-externc-isystem" "[[SYSROOT]]/usr/include"
@@ -111,7 +190,7 @@
 // CHECK-DEBIAN-PPC64: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/powerpc64-linux-gnu/4.5/../../../../include/c++/4.5/powerpc64-linux-gnu"
 // CHECK-DEBIAN-PPC64: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/powerpc64-linux-gnu/4.5/../../../../include/c++/4.5/backward"
 // CHECK-DEBIAN-PPC64: "-internal-isystem" "[[SYSROOT]]/usr/local/include"
-// CHECK-DEBIAN-PPC64: "-internal-isystem" "{{.*}}{{/|\\\\}}lib{{(64|32)?}}{{/|\\\\}}clang{{/|\\\\}}{{[0-9]\.[0-9]}}{{/|\\\\}}include"
+// CHECK-DEBIAN-PPC64: "-internal-isystem" "{{.*}}{{/|\\\\}}lib{{(64|32)?}}{{/|\\\\}}clang{{/|\\\\}}{{[0-9]\.[0-9]\.[0-9]}}{{/|\\\\}}include"
 // CHECK-DEBIAN-PPC64: "-internal-externc-isystem" "[[SYSROOT]]/usr/include/powerpc64-linux-gnu"
 // CHECK-DEBIAN-PPC64: "-internal-externc-isystem" "[[SYSROOT]]/include"
 // CHECK-DEBIAN-PPC64: "-internal-externc-isystem" "[[SYSROOT]]/usr/include"
@@ -128,7 +207,7 @@
 // CHECK-GENTOO-4-6-2: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.6.2/include/g++-v4/x86_64-pc-linux-gnu"
 // CHECK-GENTOO-4-6-2: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.6.2/include/g++-v4/backward"
 // CHECK-GENTOO-4-6-2: "-internal-isystem" "[[SYSROOT]]/usr/local/include"
-// CHECK-GENTOO-4-6-2: "-internal-isystem" "{{.*}}{{/|\\\\}}lib{{(64|32)?}}{{/|\\\\}}clang{{/|\\\\}}{{[0-9]\.[0-9]}}{{/|\\\\}}include"
+// CHECK-GENTOO-4-6-2: "-internal-isystem" "{{.*}}{{/|\\\\}}lib{{(64|32)?}}{{/|\\\\}}clang{{/|\\\\}}{{[0-9]\.[0-9]\.[0-9]}}{{/|\\\\}}include"
 // CHECK-GENTOO-4-6-2: "-internal-externc-isystem" "[[SYSROOT]]/include"
 // CHECK-GENTOO-4-6-2: "-internal-externc-isystem" "[[SYSROOT]]/usr/include"
 // RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \
@@ -141,6 +220,38 @@
 // CHECK-GENTOO-4-6-4: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.6.4/include/g++-v4.6/x86_64-pc-linux-gnu"
 // CHECK-GENTOO-4-6-4: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/x86_64-pc-linux-gnu/4.6.4/include/g++-v4.6/backward"
 // CHECK-GENTOO-4-6-4: "-internal-isystem" "[[SYSROOT]]/usr/local/include"
-// CHECK-GENTOO-4-6-4: "-internal-isystem" "{{.*}}{{/|\\\\}}lib{{(64|32)?}}{{/|\\\\}}clang{{/|\\\\}}{{[0-9]\.[0-9]}}{{/|\\\\}}include"
+// CHECK-GENTOO-4-6-4: "-internal-isystem" "{{.*}}{{/|\\\\}}lib{{(64|32)?}}{{/|\\\\}}clang{{/|\\\\}}{{[0-9]\.[0-9]\.[0-9]}}{{/|\\\\}}include"
 // CHECK-GENTOO-4-6-4: "-internal-externc-isystem" "[[SYSROOT]]/include"
 // CHECK-GENTOO-4-6-4: "-internal-externc-isystem" "[[SYSROOT]]/usr/include"
+//
+// Check header search on Debian 6 / MIPS64
+// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \
+// RUN:     -target mips64-unknown-linux-gnuabi64 \
+// RUN:     --sysroot=%S/Inputs/debian_6_mips64_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-MIPS64-GNUABI %s
+// CHECK-MIPS64-GNUABI: "{{[^"]*}}clang{{[^"]*}}" "-cc1"
+// CHECK-MIPS64-GNUABI: "-isysroot" "[[SYSROOT:[^"]+]]"
+// CHECK-MIPS64-GNUABI: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/mips64-linux-gnuabi64/4.9/../../../../include/c++/4.9"
+// CHECK-MIPS64-GNUABI: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/mips64-linux-gnuabi64/4.9/../../../../include/c++/4.9/mips64-linux-gnuabi64"
+// CHECK-MIPS64-GNUABI: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/mips64-linux-gnuabi64/4.9/../../../../include/c++/4.9/backward"
+// CHECK-MIPS64-GNUABI: "-internal-isystem" "[[SYSROOT]]/usr/local/include"
+// CHECK-MIPS64-GNUABI: "-internal-isystem" "{{.*}}{{/|\\\\}}lib{{(64|32)?}}{{/|\\\\}}clang{{/|\\\\}}{{[0-9]\.[0-9]\.[0-9]}}{{/|\\\\}}include"
+// CHECK-MIPS64-GNUABI: "-internal-externc-isystem" "[[SYSROOT]]/usr/include/mips64-linux-gnuabi64"
+// CHECK-MIPS64-GNUABI: "-internal-externc-isystem" "[[SYSROOT]]/include"
+// CHECK-MIPS64-GNUABI: "-internal-externc-isystem" "[[SYSROOT]]/usr/include"
+//
+// Check header search on Debian 6 / MIPS64
+// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \
+// RUN:     -target mips64el-unknown-linux-gnuabi64 \
+// RUN:     --sysroot=%S/Inputs/debian_6_mips64_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-MIPS64EL-GNUABI %s
+// CHECK-MIPS64EL-GNUABI: "{{[^"]*}}clang{{[^"]*}}" "-cc1"
+// CHECK-MIPS64EL-GNUABI: "-isysroot" "[[SYSROOT:[^"]+]]"
+// CHECK-MIPS64EL-GNUABI: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/mips64el-linux-gnuabi64/4.9/../../../../include/c++/4.9"
+// CHECK-MIPS64EL-GNUABI: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/mips64el-linux-gnuabi64/4.9/../../../../include/c++/4.9/mips64el-linux-gnuabi64"
+// CHECK-MIPS64EL-GNUABI: "-internal-isystem" "[[SYSROOT]]/usr/lib/gcc/mips64el-linux-gnuabi64/4.9/../../../../include/c++/4.9/backward"
+// CHECK-MIPS64EL-GNUABI: "-internal-isystem" "[[SYSROOT]]/usr/local/include"
+// CHECK-MIPS64EL-GNUABI: "-internal-isystem" "{{.*}}{{/|\\\\}}lib{{(64|32)?}}{{/|\\\\}}clang{{/|\\\\}}{{[0-9]\.[0-9]\.[0-9]}}{{/|\\\\}}include"
+// CHECK-MIPS64EL-GNUABI: "-internal-externc-isystem" "[[SYSROOT]]/usr/include/mips64el-linux-gnuabi64"
+// CHECK-MIPS64EL-GNUABI: "-internal-externc-isystem" "[[SYSROOT]]/include"
+// CHECK-MIPS64EL-GNUABI: "-internal-externc-isystem" "[[SYSROOT]]/usr/include"
diff --git a/test/Driver/linux-ld.c b/test/Driver/linux-ld.c
index 755fa04..6a47d08 100644
--- a/test/Driver/linux-ld.c
+++ b/test/Driver/linux-ld.c
@@ -34,6 +34,59 @@
 // CHECK-LD-64: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
 //
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=x86_64-unknown-linux-gnux32 \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-LD-X32 %s
+// CHECK-LD-X32-NOT: warning:
+// CHECK-LD-X32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-LD-X32: "--eh-frame-hdr"
+// CHECK-LD-X32: "-m" "elf32_x86_64"
+// CHECK-LD-X32: "-dynamic-linker"
+// CHECK-LD-X32: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
+// CHECK-LD-X32: "-lc"
+// CHECK-LD-X32: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=x86_64-unknown-linux \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:     --rtlib=compiler-rt \
+// RUN:   | FileCheck --check-prefix=CHECK-LD-RT %s
+// CHECK-LD-RT-NOT: warning:
+// CHECK-LD-RT: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-LD-RT: "--eh-frame-hdr"
+// CHECK-LD-RT: "-m" "elf_x86_64"
+// CHECK-LD-RT: "-dynamic-linker"
+// CHECK-LD-RT: "{{.*}}/usr/lib/gcc/x86_64-unknown-linux/4.6.0{{/|\\\\}}crtbegin.o"
+// CHECK-LD-RT: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0"
+// CHECK-LD-RT: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../x86_64-unknown-linux/lib"
+// CHECK-LD-RT: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../.."
+// CHECK-LD-RT: "-L[[SYSROOT]]/lib"
+// CHECK-LD-RT: "-L[[SYSROOT]]/usr/lib"
+// CHECK-LD-RT: libclang_rt.builtins-x86_64.a" "-lgcc_s"
+// CHECK-LD-RT: "-lc"
+// CHECK-LD-RT: libclang_rt.builtins-x86_64.a" "-lgcc_s"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=x86_64-unknown-linux \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:     --rtlib=libgcc \
+// RUN:   | FileCheck --check-prefix=CHECK-LD-GCC %s
+// CHECK-LD-GCC-NOT: warning:
+// CHECK-LD-GCC: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-LD-GCC: "--eh-frame-hdr"
+// CHECK-LD-GCC: "-m" "elf_x86_64"
+// CHECK-LD-GCC: "-dynamic-linker"
+// CHECK-LD-GCC: "{{.*}}/usr/lib/gcc/x86_64-unknown-linux/4.6.0{{/|\\\\}}crtbegin.o"
+// CHECK-LD-GCC: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0"
+// CHECK-LD-GCC: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../x86_64-unknown-linux/lib"
+// CHECK-LD-GCC: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../.."
+// CHECK-LD-GCC: "-L[[SYSROOT]]/lib"
+// CHECK-LD-GCC: "-L[[SYSROOT]]/usr/lib"
+// CHECK-LD-GCC "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
+// CHECK-LD-GCC: "-lc"
+// CHECK-LD-GCC: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=x86_64-unknown-linux \
 // RUN:     -static-libgcc \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
@@ -146,6 +199,57 @@
 // CHECK-64-TO-32: "-L[[SYSROOT]]/usr/lib"
 //
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=x86_64-unknown-linux-gnux32 \
+// RUN:     --sysroot=%S/Inputs/multilib_64bit_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-X32 %s
+// CHECK-X32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-X32: "{{.*}}/usr/lib/gcc/x86_64-unknown-linux/4.6.0/x32{{/|\\\\}}crtbegin.o"
+// CHECK-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/x32"
+// CHECK-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../x86_64-unknown-linux/lib/../libx32"
+// CHECK-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../libx32"
+// CHECK-X32: "-L[[SYSROOT]]/lib/../libx32"
+// CHECK-X32: "-L[[SYSROOT]]/usr/lib/../libx32"
+// CHECK-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0"
+// CHECK-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../x86_64-unknown-linux/lib"
+// CHECK-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../.."
+// CHECK-X32: "-L[[SYSROOT]]/lib"
+// CHECK-X32: "-L[[SYSROOT]]/usr/lib"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=x86_64-unknown-linux -mx32 \
+// RUN:     --sysroot=%S/Inputs/multilib_64bit_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-64-TO-X32 %s
+// CHECK-64-TO-X32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-64-TO-X32: "{{.*}}/usr/lib/gcc/x86_64-unknown-linux/4.6.0/x32{{/|\\\\}}crtbegin.o"
+// CHECK-64-TO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/x32"
+// CHECK-64-TO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../x86_64-unknown-linux/lib/../libx32"
+// CHECK-64-TO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../libx32"
+// CHECK-64-TO-X32: "-L[[SYSROOT]]/lib/../libx32"
+// CHECK-64-TO-X32: "-L[[SYSROOT]]/usr/lib/../libx32"
+// CHECK-64-TO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0"
+// CHECK-64-TO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../x86_64-unknown-linux/lib"
+// CHECK-64-TO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../.."
+// CHECK-64-TO-X32: "-L[[SYSROOT]]/lib"
+// CHECK-64-TO-X32: "-L[[SYSROOT]]/usr/lib"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=i386-unknown-linux -mx32 \
+// RUN:     --sysroot=%S/Inputs/multilib_64bit_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-32-TO-X32 %s
+// CHECK-32-TO-X32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-32-TO-X32: "{{.*}}/usr/lib/gcc/x86_64-unknown-linux/4.6.0/x32{{/|\\\\}}crtbegin.o"
+// CHECK-32-TO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/x32"
+// CHECK-32-TO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../x86_64-unknown-linux/lib/../libx32"
+// CHECK-32-TO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../libx32"
+// CHECK-32-TO-X32: "-L[[SYSROOT]]/lib/../libx32"
+// CHECK-32-TO-X32: "-L[[SYSROOT]]/usr/lib/../libx32"
+// CHECK-32-TO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0"
+// CHECK-32-TO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../../../x86_64-unknown-linux/lib"
+// CHECK-32-TO-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-unknown-linux/4.6.0/../../.."
+// CHECK-32-TO-X32: "-L[[SYSROOT]]/lib"
+// CHECK-32-TO-X32: "-L[[SYSROOT]]/usr/lib"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=x86_64-unknown-linux -m32 \
 // RUN:     --gcc-toolchain=%S/Inputs/multilib_64bit_linux_tree/usr \
 // RUN:     --sysroot=%S/Inputs/multilib_32bit_linux_tree \
@@ -214,6 +318,32 @@
 // CHECK-GCC-VERSION4: "{{.*}}/Inputs/gcc_version_parsing4/bin/../lib/gcc/i386-unknown-linux/4.7.99{{/|\\\\}}crtbegin.o"
 // CHECK-GCC-VERSION4: "-L{{.*}}/Inputs/gcc_version_parsing4/bin/../lib/gcc/i386-unknown-linux/4.7.99"
 //
+// Test a simulated installation of libc++ on Linux, both through sysroot and
+// the installation path of Clang.
+// RUN: %clangxx -no-canonical-prefixes -x c++ %s -### -o %t.o 2>&1 \
+// RUN:     -target x86_64-unknown-linux-gnu \
+// RUN:     -stdlib=libc++ \
+// RUN:     -ccc-install-dir %S/Inputs/basic_linux_tree/usr/bin \
+// RUN:     --sysroot=%S/Inputs/basic_linux_libcxx_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BASIC-LIBCXX-SYSROOT %s
+// CHECK-BASIC-LIBCXX-SYSROOT: "{{[^"]*}}clang{{[^"]*}}" "-cc1"
+// CHECK-BASIC-LIBCXX-SYSROOT: "-isysroot" "[[SYSROOT:[^"]+]]"
+// CHECK-BASIC-LIBCXX-SYSROOT: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1"
+// CHECK-BASIC-LIBCXX-SYSROOT: "-internal-isystem" "[[SYSROOT]]/usr/local/include"
+// CHECK-BASIC-LIBCXX-SYSROOT: "--sysroot=[[SYSROOT]]"
+// RUN: %clang -no-canonical-prefixes -x c++ %s -### -o %t.o 2>&1 \
+// RUN:     -target x86_64-unknown-linux-gnu \
+// RUN:     -stdlib=libc++ \
+// RUN:     -ccc-install-dir %S/Inputs/basic_linux_libcxx_tree/usr/bin \
+// RUN:     --sysroot=%S/Inputs/basic_linux_libcxx_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BASIC-LIBCXX-INSTALL %s
+// CHECK-BASIC-LIBCXX-INSTALL: "{{[^"]*}}clang{{[^"]*}}" "-cc1"
+// CHECK-BASIC-LIBCXX-INSTALL: "-isysroot" "[[SYSROOT:[^"]+]]"
+// CHECK-BASIC-LIBCXX-INSTALL: "-internal-isystem" "[[SYSROOT]]/usr/bin/../include/c++/v1"
+// CHECK-BASIC-LIBCXX-INSTALL: "-internal-isystem" "[[SYSROOT]]/usr/local/include"
+// CHECK-BASIC-LIBCXX-INSTALL: "--sysroot=[[SYSROOT]]"
+// CHECK-BASIC-LIBCXX-INSTALL: "-L[[SYSROOT]]/usr/bin/../lib"
+//
 // Test a very broken version of multiarch that shipped in Ubuntu 11.04.
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=i386-unknown-linux \
@@ -281,6 +411,43 @@
 // CHECK-X86-64-UBUNTU-13-10-ARM: "{{.*}}/usr/lib/gcc-cross/arm-linux-gnueabi/4.7{{/|\\\\}}crtend.o"
 // CHECK-X86-64-UBUNTU-13-10-ARM: "{{.*}}/usr/lib/gcc-cross/arm-linux-gnueabi/4.7/../../../../arm-linux-gnueabi/lib/../lib{{/|\\\\}}crtn.o"
 //
+// Check Ubuntu 14.04 on powerpc64le.
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=powerpc64le-unknown-linux-gnu \
+// RUN:     --sysroot=%S/Inputs/ubuntu_14.04_multiarch_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-UBUNTU-14-04-PPC64LE %s
+// CHECK-UBUNTU-14-04-PPC64LE: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-UBUNTU-14-04-PPC64LE: "{{.*}}/usr/lib/gcc/powerpc64le-linux-gnu/4.8/../../../powerpc64le-linux-gnu{{/|\\\\}}crt1.o"
+// CHECK-UBUNTU-14-04-PPC64LE: "{{.*}}/usr/lib/gcc/powerpc64le-linux-gnu/4.8/../../../powerpc64le-linux-gnu{{/|\\\\}}crti.o"
+// CHECK-UBUNTU-14-04-PPC64LE: "{{.*}}/usr/lib/gcc/powerpc64le-linux-gnu/4.8{{/|\\\\}}crtbegin.o"
+// CHECK-UBUNTU-14-04-PPC64LE: "-L[[SYSROOT]]/usr/lib/gcc/powerpc64le-linux-gnu/4.8"
+// CHECK-UBUNTU-14-04-PPC64LE: "-L[[SYSROOT]]/usr/lib/gcc/powerpc64le-linux-gnu/4.8/../../../powerpc64le-linux-gnu"
+// CHECK-UBUNTU-14-04-PPC64LE: "-L[[SYSROOT]]/lib/powerpc64le-linux-gnu"
+// CHECK-UBUNTU-14-04-PPC64LE: "-L[[SYSROOT]]/usr/lib/powerpc64le-linux-gnu"
+// CHECK-UBUNTU-14-04-PPC64LE: "-L[[SYSROOT]]/usr/lib/gcc/powerpc64le-linux-gnu/4.8/../../.."
+// CHECK-UBUNTU-14-04-PPC64LE: "{{.*}}/usr/lib/gcc/powerpc64le-linux-gnu/4.8{{/|\\\\}}crtend.o"
+// CHECK-UBUNTU-14-04-PPC64LE: "{{.*}}/usr/lib/gcc/powerpc64le-linux-gnu/4.8/../../../powerpc64le-linux-gnu{{/|\\\\}}crtn.o"
+//
+// Check Ubuntu 14.04 on x32.
+// "/usr/lib/gcc/x86_64-linux-gnu/4.8/x32/crtend.o" "/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../libx32/crtn.o"
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=x86_64-unknown-linux-gnux32 \
+// RUN:     --sysroot=%S/Inputs/ubuntu_14.04_multiarch_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-UBUNTU-14-04-X32 %s
+// CHECK-UBUNTU-14-04-X32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-UBUNTU-14-04-X32: "{{.*}}/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../libx32{{/|\\\\}}crt1.o"
+// CHECK-UBUNTU-14-04-X32: "{{.*}}/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../libx32{{/|\\\\}}crti.o"
+// CHECK-UBUNTU-14-04-X32: "{{.*}}/usr/lib/gcc/x86_64-linux-gnu/4.8/x32{{/|\\\\}}crtbegin.o"
+// CHECK-UBUNTU-14-04-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/x32"
+// CHECK-UBUNTU-14-04-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../libx32"
+// CHECK-UBUNTU-14-04-X32: "-L[[SYSROOT]]/lib/../libx32"
+// CHECK-UBUNTU-14-04-X32: "-L[[SYSROOT]]/usr/lib/../libx32"
+// CHECK-UBUNTU-14-04-X32: "-L[[SYSROOT]]/usr/lib/x86_64-linux-gnu/../../libx32"
+// CHECK-UBUNTU-14-04-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8"
+// CHECK-UBUNTU-14-04-X32: "-L[[SYSROOT]]/usr/lib/gcc/x86_64-linux-gnu/4.8/../../.."
+// CHECK-UBUNTU-14-04-X32: "{{.*}}/usr/lib/gcc/x86_64-linux-gnu/4.8/x32{{/|\\\\}}crtend.o"
+// CHECK-UBUNTU-14-04-X32: "{{.*}}/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../libx32{{/|\\\\}}crtn.o"
+//
 // Check fedora 18 on arm.
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=armv7-unknown-linux-gnueabihf \
@@ -295,6 +462,24 @@
 // CHECK-FEDORA-18-ARM-HF: "{{.*}}/usr/lib/gcc/armv7hl-redhat-linux-gnueabi/4.7.2{{/|\\\\}}crtend.o"
 // CHECK-FEDORA-18-ARM-HF: "{{.*}}/usr/lib/gcc/armv7hl-redhat-linux-gnueabi/4.7.2/../../../../lib{{/|\\\\}}crtn.o"
 //
+// Check Fedora 21 on AArch64.
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=arm64-unknown-linux-gnu \
+// RUN:     --sysroot=%S/Inputs/fedora_21_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-FEDORA-21-AARCH64 %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=aarch64-unknown-linux-gnu \
+// RUN:     --sysroot=%S/Inputs/fedora_21_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-FEDORA-21-AARCH64 %s
+// CHECK-FEDORA-21-AARCH64: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-FEDORA-21-AARCH64: "{{.*}}/usr/lib/gcc/aarch64-redhat-linux/4.9.0/../../../../lib64{{/|\\\\}}crt1.o"
+// CHECK-FEDORA-21-AARCH64: "{{.*}}/usr/lib/gcc/aarch64-redhat-linux/4.9.0/../../../../lib64{{/|\\\\}}crti.o"
+// CHECK-FEDORA-21-AARCH64: "{{.*}}/usr/lib/gcc/aarch64-redhat-linux/4.9.0{{/|\\\\}}crtbegin.o"
+// CHECK-FEDORA-21-AARCH64: "-L[[SYSROOT]]/usr/lib/gcc/aarch64-redhat-linux/4.9.0"
+// CHECK-FEDORA-21-AARCH64: "-L[[SYSROOT]]/usr/lib/gcc/aarch64-redhat-linux/4.9.0/../../../../lib64"
+// CHECK-FEDORA-21-AARCH64: "{{.*}}/usr/lib/gcc/aarch64-redhat-linux/4.9.0{{/|\\\\}}crtend.o"
+// CHECK-FEDORA-21-AARCH64: "{{.*}}/usr/lib/gcc/aarch64-redhat-linux/4.9.0/../../../../lib64{{/|\\\\}}crtn.o"
+//
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=arm-unknown-linux-gnueabi \
 // RUN:     --sysroot=%S/Inputs/ubuntu_12.04_LTS_multiarch_tree \
@@ -338,6 +523,13 @@
 // CHECK-ARM-HF: "-m" "armelf_linux_eabi"
 // CHECK-ARM-HF: "-dynamic-linker" "{{.*}}/lib/ld-linux-armhf.so.3"
 //
+// RUN: %clang %s -### -o %t.o 2>&1 \
+// RUN:     --target=powerpc64le-linux-gnu \
+// RUN:   | FileCheck --check-prefix=CHECK-PPC64LE %s
+// CHECK-PPC64LE: "{{.*}}ld{{(.exe)?}}"
+// CHECK-PPC64LE: "-m" "elf64lppc"
+// CHECK-PPC64LE: "-dynamic-linker" "{{.*}}/lib64/ld64.so.2"
+//
 // Check that we do not pass --hash-style=gnu and --hash-style=both to linker
 // and provide correct path to the dynamic linker and emulation mode when build
 // for MIPS platforms.
@@ -348,6 +540,7 @@
 // CHECK-MIPS: "-m" "elf32btsmip"
 // CHECK-MIPS: "-dynamic-linker" "{{.*}}/lib/ld.so.1"
 // CHECK-MIPS-NOT: "--hash-style={{gnu|both}}"
+//
 // RUN: %clang %s -### -o %t.o 2>&1 \
 // RUN:     --target=mipsel-linux-gnu \
 // RUN:   | FileCheck --check-prefix=CHECK-MIPSEL %s
@@ -355,6 +548,21 @@
 // CHECK-MIPSEL: "-m" "elf32ltsmip"
 // CHECK-MIPSEL: "-dynamic-linker" "{{.*}}/lib/ld.so.1"
 // CHECK-MIPSEL-NOT: "--hash-style={{gnu|both}}"
+//
+// RUN: %clang %s -### -o %t.o 2>&1 --target=mipsel-linux-gnu -mnan=2008 \
+// RUN:   | FileCheck --check-prefix=CHECK-MIPSEL-NAN2008 %s
+// CHECK-MIPSEL-NAN2008: "{{.*}}ld{{(.exe)?}}"
+// CHECK-MIPSEL-NAN2008: "-m" "elf32ltsmip"
+// CHECK-MIPSEL-NAN2008: "-dynamic-linker" "{{.*}}/lib/ld-linux-mipsn8.so.1"
+// CHECK-MIPSEL-NAN2008-NOT: "--hash-style={{gnu|both}}"
+//
+// RUN: %clang %s -### -o %t.o 2>&1 --target=mipsel-linux-gnu -mcpu=mips32r6 \
+// RUN:   | FileCheck --check-prefix=CHECK-MIPS32R6EL %s
+// CHECK-MIPS32R6EL: "{{.*}}ld{{(.exe)?}}"
+// CHECK-MIPS32R6EL: "-m" "elf32ltsmip"
+// CHECK-MIPS32R6EL: "-dynamic-linker" "{{.*}}/lib/ld-linux-mipsn8.so.1"
+// CHECK-MIPS32R6EL-NOT: "--hash-style={{gnu|both}}"
+//
 // RUN: %clang %s -### -o %t.o 2>&1 \
 // RUN:     --target=mips64-linux-gnu \
 // RUN:   | FileCheck --check-prefix=CHECK-MIPS64 %s
@@ -362,6 +570,7 @@
 // CHECK-MIPS64: "-m" "elf64btsmip"
 // CHECK-MIPS64: "-dynamic-linker" "{{.*}}/lib64/ld.so.1"
 // CHECK-MIPS64-NOT: "--hash-style={{gnu|both}}"
+//
 // RUN: %clang %s -### -o %t.o 2>&1 \
 // RUN:     --target=mips64el-linux-gnu \
 // RUN:   | FileCheck --check-prefix=CHECK-MIPS64EL %s
@@ -369,6 +578,21 @@
 // CHECK-MIPS64EL: "-m" "elf64ltsmip"
 // CHECK-MIPS64EL: "-dynamic-linker" "{{.*}}/lib64/ld.so.1"
 // CHECK-MIPS64EL-NOT: "--hash-style={{gnu|both}}"
+//
+// RUN: %clang %s -### -o %t.o 2>&1 --target=mips64el-linux-gnu -mnan=2008 \
+// RUN:   | FileCheck --check-prefix=CHECK-MIPS64EL-NAN2008 %s
+// CHECK-MIPS64EL-NAN2008: "{{.*}}ld{{(.exe)?}}"
+// CHECK-MIPS64EL-NAN2008: "-m" "elf64ltsmip"
+// CHECK-MIPS64EL-NAN2008: "-dynamic-linker" "{{.*}}/lib64/ld-linux-mipsn8.so.1"
+// CHECK-MIPS64EL-NAN2008-NOT: "--hash-style={{gnu|both}}"
+//
+// RUN: %clang %s -### -o %t.o 2>&1 --target=mips64el-linux-gnu -mcpu=mips64r6 \
+// RUN:   | FileCheck --check-prefix=CHECK-MIPS64R6EL %s
+// CHECK-MIPS64R6EL: "{{.*}}ld{{(.exe)?}}"
+// CHECK-MIPS64R6EL: "-m" "elf64ltsmip"
+// CHECK-MIPS64R6EL: "-dynamic-linker" "{{.*}}/lib64/ld-linux-mipsn8.so.1"
+// CHECK-MIPS64R6EL-NOT: "--hash-style={{gnu|both}}"
+//
 // RUN: %clang %s -### -o %t.o 2>&1 \
 // RUN:     --target=mips64-linux-gnu -mabi=n32 \
 // RUN:   | FileCheck --check-prefix=CHECK-MIPS64-N32 %s
@@ -376,6 +600,7 @@
 // CHECK-MIPS64-N32: "-m" "elf32btsmipn32"
 // CHECK-MIPS64-N32: "-dynamic-linker" "{{.*}}/lib32/ld.so.1"
 // CHECK-MIPS64-N32-NOT: "--hash-style={{gnu|both}}"
+//
 // RUN: %clang %s -### -o %t.o 2>&1 \
 // RUN:     --target=mips64el-linux-gnu -mabi=n32 \
 // RUN:   | FileCheck --check-prefix=CHECK-MIPS64EL-N32 %s
@@ -384,6 +609,27 @@
 // CHECK-MIPS64EL-N32: "-dynamic-linker" "{{.*}}/lib32/ld.so.1"
 // CHECK-MIPS64EL-N32-NOT: "--hash-style={{gnu|both}}"
 //
+// RUN: %clang %s -### -o %t.o 2>&1 --target=mips64el-linux-gnu -mabi=n32 \
+// RUN:   -mnan=2008 | FileCheck --check-prefix=CHECK-MIPS64EL-N32-NAN2008 %s
+// CHECK-MIPS64EL-N32-NAN2008: "{{.*}}ld{{(.exe)?}}"
+// CHECK-MIPS64EL-N32-NAN2008: "-m" "elf32ltsmipn32"
+// CHECK-MIPS64EL-N32-NAN2008: "-dynamic-linker" "{{.*}}/lib32/ld-linux-mipsn8.so.1"
+// CHECK-MIPS64EL-N32-NAN2008-NOT: "--hash-style={{gnu|both}}"
+//
+// RUN: %clang %s -### -o %t.o 2>&1 \
+// RUN:     --target=sparc-linux-gnu \
+// RUN:   | FileCheck --check-prefix=CHECK-SPARCV8 %s
+// CHECK-SPARCV8: "{{.*}}ld{{(.exe)?}}"
+// CHECK-SPARCV8: "-m" "elf32_sparc"
+// CHECK-SPARCV8: "-dynamic-linker" "/lib/ld-linux.so.2"
+//
+// RUN: %clang %s -### -o %t.o 2>&1 \
+// RUN:     --target=sparcv9-linux-gnu \
+// RUN:   | FileCheck --check-prefix=CHECK-SPARCV9 %s
+// CHECK-SPARCV9: "{{.*}}ld{{(.exe)?}}"
+// CHECK-SPARCV9: "-m" "elf64_sparc"
+// CHECK-SPARCV9: "-dynamic-linker" "/lib64/ld-linux.so.2"
+//
 // Thoroughly exercise the Debian multiarch environment.
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=i686-linux-gnu \
@@ -512,11 +758,27 @@
 // RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
 // RUN:   | FileCheck --check-prefix=CHECK-ANDROID %s
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=aarch64-linux-android \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=arm64-linux-android \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mipsel-linux-android \
 // RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
 // RUN:   | FileCheck --check-prefix=CHECK-ANDROID %s
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     --target=i386-linux-android \
+// RUN:     --target=mips64el-linux-android \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=i686-linux-android \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=x86_64-linux-android \
 // RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
 // RUN:   | FileCheck --check-prefix=CHECK-ANDROID %s
 // CHECK-ANDROID: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
@@ -538,17 +800,37 @@
 // RUN:     -shared \
 // RUN:   | FileCheck --check-prefix=CHECK-ANDROID-SO %s
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=aarch64-linux-android \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:     -shared \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-SO %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=arm64-linux-android \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:     -shared \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-SO %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mipsel-linux-android \
 // RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
 // RUN:     -shared \
 // RUN:   | FileCheck --check-prefix=CHECK-ANDROID-SO %s
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     --target=i386-linux-android \
+// RUN:     --target=mips64el-linux-android \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:     -shared \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-SO %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=i686-linux-android \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:     -shared \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-SO %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=x86_64-linux-android \
 // RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
 // RUN:     -shared \
 // RUN:   | FileCheck --check-prefix=CHECK-ANDROID-SO %s
 // CHECK-ANDROID-SO: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
-// CHECK-ANDROID-SO: "-Bsymbolic"
+// CHECK-ANDROID-SO-NOT: "-Bsymbolic"
 // CHECK-ANDROID-SO: "{{.*}}{{/|\\\\}}crtbegin_so.o"
 // CHECK-ANDROID-SO: "-L[[SYSROOT]]/usr/lib"
 // CHECK-ANDROID-SO-NOT: "gcc_s"
@@ -567,12 +849,32 @@
 // RUN:     -static \
 // RUN:   | FileCheck --check-prefix=CHECK-ANDROID-STATIC %s
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=aarch64-linux-android \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:     -static \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-STATIC %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=arm64-linux-android \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:     -static \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-STATIC %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mipsel-linux-android \
 // RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
 // RUN:     -static \
 // RUN:   | FileCheck --check-prefix=CHECK-ANDROID-STATIC %s
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     --target=i386-linux-android \
+// RUN:     --target=mips64el-linux-android \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:     -static \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-STATIC %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=i686-linux-android \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:     -static \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-STATIC %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=x86-linux-android \
 // RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
 // RUN:     -static \
 // RUN:   | FileCheck --check-prefix=CHECK-ANDROID-STATIC %s
@@ -595,12 +897,32 @@
 // RUN:     -pie \
 // RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PIE %s
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=aarch64-linux-android \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot  \
+// RUN:     -pie \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PIE %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=arm64-linux-android \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot  \
+// RUN:     -pie \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PIE %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mipsel-linux-android \
 // RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
 // RUN:     -pie \
 // RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PIE %s
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     --target=i386-linux-android \
+// RUN:     --target=mips64el-linux-android \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:     -pie \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PIE %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=i686-linux-android \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:     -pie \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PIE %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=x86_64-linux-android \
 // RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
 // RUN:     -pie \
 // RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PIE %s
@@ -611,6 +933,121 @@
 // CHECK-ANDROID-PIE: "-lgcc"
 // CHECK-ANDROID-PIE-NOT: "gcc_s"
 // CHECK-ANDROID-PIE: "{{.*}}{{/|\\\\}}crtend_android.o"
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=arm-linux-androideabi \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-32 %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=arm-linux-android \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-32 %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mipsel-linux-android \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-32 %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=aarch64-linux-android \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-64 %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=arm64-linux-android \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-64 %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64el-linux-android \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-64 %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=i686-linux-android \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-32 %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=x86_64-linux-android \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-64 %s
+// CHECK-ANDROID-32: "-dynamic-linker" "/system/bin/linker"
+// CHECK-ANDROID-64: "-dynamic-linker" "/system/bin/linker64"
+//
+// Test that -pthread does not add -lpthread on Android.
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=arm-linux-androideabi -pthread \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=arm-linux-android -pthread \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=aarch64-linux-android -pthread \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=arm64-linux-android -pthread \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mipsel-linux-android -pthread \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64el-linux-android -pthread \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=i686-linux-android -pthread \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=x86_64-linux-android -pthread \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=arm-linux-androideabi -pthread \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:     -shared \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=arm-linux-android -pthread \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:     -shared \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=aarch64-linux-android -pthread \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:     -shared \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=arm64-linux-android -pthread \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:     -shared \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mipsel-linux-android -pthread \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:     -shared \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64el-linux-android -pthread \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:     -shared \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=i686-linux-android -pthread \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:     -shared \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=x86_64-linux-android -pthread \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:     -shared \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD %s
+// CHECK-ANDROID-PTHREAD-NOT: -lpthread
+//
+// RUN: %clang -no-canonical-prefixes %t.o -### -o %t 2>&1 \
+// RUN:     --target=arm-linux-androideabi -pthread \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-PTHREAD-LINK %s
+// CHECK-ANDROID-PTHREAD-LINK-NOT: argument unused during compilation: '-pthread'
 //
 // Check linker invocation on Debian 6 MIPS 32/64-bit.
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
@@ -661,6 +1098,44 @@
 // CHECK-DEBIAN-ML-MIPS64EL-N32: "-L[[SYSROOT]]/lib"
 // CHECK-DEBIAN-ML-MIPS64EL-N32: "-L[[SYSROOT]]/usr/lib"
 //
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64-linux-gnuabi64 -mabi=n64 \
+// RUN:     --sysroot=%S/Inputs/debian_6_mips64_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-DEBIAN-ML-MIPS64-GNUABI %s
+// CHECK-DEBIAN-ML-MIPS64-GNUABI: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-DEBIAN-ML-MIPS64-GNUABI: "{{.*}}/usr/lib/gcc/mips64-linux-gnuabi64/4.9/../../../mips64-linux-gnuabi64{{/|\\\\}}crt1.o"
+// CHECK-DEBIAN-ML-MIPS64-GNUABI: "{{.*}}/usr/lib/gcc/mips64-linux-gnuabi64/4.9/../../../mips64-linux-gnuabi64{{/|\\\\}}crti.o"
+// CHECK-DEBIAN-ML-MIPS64-GNUABI: "{{.*}}/usr/lib/gcc/mips64-linux-gnuabi64/4.9{{/|\\\\}}crtbegin.o"
+// CHECK-DEBIAN-ML-MIPS64-GNUABI: "-L[[SYSROOT]]/usr/lib/gcc/mips64-linux-gnuabi64/4.9"
+// CHECK-DEBIAN-ML-MIPS64-GNUABI: "-L[[SYSROOT]]/usr/lib/gcc/mips64-linux-gnuabi64/4.9/../../../mips64-linux-gnuabi64"
+// CHECK-DEBIAN-ML-MIPS64-GNUABI: "-L[[SYSROOT]]/lib/mips64-linux-gnuabi64"
+// CHECK-DEBIAN-ML-MIPS64-GNUABI: "-L[[SYSROOT]]/usr/lib/mips64-linux-gnuabi64"
+// CHECK-DEBIAN-ML-MIPS64-GNUABI: "-L[[SYSROOT]]/usr/lib/gcc/mips64-linux-gnuabi64/4.9"
+// CHECK-DEBIAN-ML-MIPS64-GNUABI: "-L[[SYSROOT]]/usr/lib/gcc/mips64-linux-gnuabi64/4.9/../../.."
+// CHECK-DEBIAN-ML-MIPS64-GNUABI: "-L[[SYSROOT]]/lib"
+// CHECK-DEBIAN-ML-MIPS64-GNUABI: "-L[[SYSROOT]]/usr/lib"
+// CHECK-DEBIAN-ML-MIPS64-GNUABI: "{{.*}}/usr/lib/gcc/mips64-linux-gnuabi64/4.9{{/|\\\\}}crtend.o"
+// CHECK-DEBIAN-ML-MIPS64-GNUABI: "{{.*}}/usr/lib/gcc/mips64-linux-gnuabi64/4.9/../../../mips64-linux-gnuabi64{{/|\\\\}}crtn.o"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64el-linux-gnuabi64 -mabi=n64 \
+// RUN:     --sysroot=%S/Inputs/debian_6_mips64_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-DEBIAN-ML-MIPS64EL-GNUABI %s
+// CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "{{.*}}/usr/lib/gcc/mips64el-linux-gnuabi64/4.9/../../../mips64el-linux-gnuabi64{{/|\\\\}}crt1.o"
+// CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "{{.*}}/usr/lib/gcc/mips64el-linux-gnuabi64/4.9/../../../mips64el-linux-gnuabi64{{/|\\\\}}crti.o"
+// CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "{{.*}}/usr/lib/gcc/mips64el-linux-gnuabi64/4.9{{/|\\\\}}crtbegin.o"
+// CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "-L[[SYSROOT]]/usr/lib/gcc/mips64el-linux-gnuabi64/4.9"
+// CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "-L[[SYSROOT]]/usr/lib/gcc/mips64el-linux-gnuabi64/4.9/../../../mips64el-linux-gnuabi64"
+// CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "-L[[SYSROOT]]/lib/mips64el-linux-gnuabi64"
+// CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "-L[[SYSROOT]]/usr/lib/mips64el-linux-gnuabi64"
+// CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "-L[[SYSROOT]]/usr/lib/gcc/mips64el-linux-gnuabi64/4.9"
+// CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "-L[[SYSROOT]]/usr/lib/gcc/mips64el-linux-gnuabi64/4.9/../../.."
+// CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "-L[[SYSROOT]]/lib"
+// CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "-L[[SYSROOT]]/usr/lib"
+// CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "{{.*}}/usr/lib/gcc/mips64el-linux-gnuabi64/4.9{{/|\\\\}}crtend.o"
+// CHECK-DEBIAN-ML-MIPS64EL-GNUABI: "{{.*}}/usr/lib/gcc/mips64el-linux-gnuabi64/4.9/../../../mips64el-linux-gnuabi64{{/|\\\\}}crtn.o"
+//
 // Test linker invocation for Freescale SDK (OpenEmbedded).
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=powerpc-fsl-linux \
@@ -681,7 +1156,7 @@
 // CHECK-FSL-PPC64: "{{.*}}{{/|\\\\}}crtbegin.o"
 // CHECK-FSL-PPC64: "-L[[SYSROOT]]/usr/lib64/powerpc64-fsl-linux/4.6.2/../.."
 //
-// Check that crtfastmath.o is linked with -ffast-math.
+// Check that crtfastmath.o is linked with -ffast-math and with -Ofast.
 // RUN: %clang --target=x86_64-unknown-linux -### %s \
 // RUN:        --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-NOCRTFASTMATH %s
@@ -691,9 +1166,30 @@
 // RUN: %clang --target=x86_64-unknown-linux -### %s -funsafe-math-optimizations\
 // RUN:        --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-CRTFASTMATH %s
+// RUN: %clang --target=x86_64-unknown-linux -### %s -Ofast\
+// RUN:        --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-CRTFASTMATH %s
+// RUN: %clang --target=x86_64-unknown-linux -### %s -Ofast -O3\
+// RUN:        --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-NOCRTFASTMATH %s
+// RUN: %clang --target=x86_64-unknown-linux -### %s -O3 -Ofast\
+// RUN:        --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-CRTFASTMATH %s
 // RUN: %clang --target=x86_64-unknown-linux -### %s -ffast-math -fno-fast-math \
 // RUN:        --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-NOCRTFASTMATH %s
+// RUN: %clang --target=x86_64-unknown-linux -### %s -Ofast -fno-fast-math \
+// RUN:        --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-CRTFASTMATH %s
+// RUN: %clang --target=x86_64-unknown-linux -### %s -Ofast -fno-unsafe-math-optimizations \
+// RUN:        --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-CRTFASTMATH %s
+// RUN: %clang --target=x86_64-unknown-linux -### %s -fno-fast-math -Ofast  \
+// RUN:        --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-CRTFASTMATH %s
+// RUN: %clang --target=x86_64-unknown-linux -### %s -fno-unsafe-math-optimizations -Ofast \
+// RUN:        --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-CRTFASTMATH %s
 // We don't have crtfastmath.o in the i386 tree, use it to check that file
 // detection works.
 // RUN: %clang --target=i386-unknown-linux -### %s -ffast-math \
@@ -707,3 +1203,9 @@
 // RUN:        --sysroot=%S/Inputs/basic_linux_tree 2>& 1 \
 // RUN:   | FileCheck --check-prefix=CHECK-PG %s
 // CHECK-PG: gcrt1.o
+
+// GCC forwards -u to the linker.
+// RUN: %clang -u asdf --target=x86_64-unknown-linux -### %s \
+// RUN:        --sysroot=%S/Inputs/basic_linux_tree 2>& 1 \
+// RUN:   | FileCheck --check-prefix=CHECK-u %s
+// CHECK-u: "-u" "asdf"
diff --git a/test/Driver/macho-embedded.c b/test/Driver/macho-embedded.c
new file mode 100644
index 0000000..cde157d
--- /dev/null
+++ b/test/Driver/macho-embedded.c
@@ -0,0 +1,15 @@
+// RUN: %clang -arch armv7 -target thumbv7-apple-darwin-eabi -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-AAPCS
+// RUN: %clang -target x86_64-apple-macosx10.9 -arch armv7m -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-AAPCS
+// RUN: %clang -arch armv7s -target thumbv7-apple-ios -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-APCS
+// RUN: %clang -arch armv7s -target thumbv7-apple-darwin -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-APCS
+// RUN: %clang -arch armv6m -target thumbv7-apple-darwin -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-MACHO-EMBEDDED
+// RUN: %clang -arch armv7m -target thumbv7-apple-darwin -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-MACHO-EMBEDDED
+// RUN: %clang -arch armv7em -target thumbv7-apple-darwin -### -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-MACHO-EMBEDDED
+
+// CHECK-IOS: "-triple" "thumbv7" "thumbv7-apple-ios
+
+// CHECK-AAPCS: "-target-abi" "aapcs"
+// CHECK-APCS: "-target-abi" "apcs-gnu"
+
+// CHECK-MACHO-EMBEDDED: "-triple" "{{thumbv[67]e?m}}-apple-unknown-macho"
+// CHECK-MACHO-EMBEDDED: "-mrelocation-model" "pic"
diff --git a/test/Driver/masm.c b/test/Driver/masm.c
new file mode 100644
index 0000000..17c6393
--- /dev/null
+++ b/test/Driver/masm.c
@@ -0,0 +1,12 @@
+// RUN: %clang -target i386-unknown-linux -masm=intel -S %s -### 2>&1 | FileCheck --check-prefix=CHECK-INTEL %s
+// RUN: %clang -target i386-unknown-linux -masm=att -S %s -### 2>&1 | FileCheck --check-prefix=CHECK-ATT %s
+// RUN: %clang -target i386-unknown-linux -S -masm=somerequired %s -### 2>&1 | FileCheck --check-prefix=CHECK-SOMEREQUIRED %s
+// RUN: %clang -target arm-unknown-eabi -S -masm=intel %s -### 2>&1 | FileCheck --check-prefix=CHECK-ARM %s
+
+int f() {
+// CHECK-INTEL: -x86-asm-syntax=intel
+// CHECK-ATT: -x86-asm-syntax=att
+// CHECK-SOMEREQUIRED: error: unsupported argument 'somerequired' to option 'masm='
+// CHECK-ARM: warning: argument unused during compilation: '-masm=intel'
+  return 0;
+}
diff --git a/test/Driver/mips-abi.c b/test/Driver/mips-abi.c
index fd2b46f..f756324 100644
--- a/test/Driver/mips-abi.c
+++ b/test/Driver/mips-abi.c
@@ -1,36 +1,133 @@
 // Check passing Mips ABI options to the backend.
 //
+// RUN: %clang -target mips-linux-gnu -### -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-DEF %s
+// MIPS-DEF: "-target-cpu" "mips32r2"
+// MIPS-DEF: "-target-abi" "o32"
+//
+// RUN: %clang -target mips64-linux-gnu -### -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS64-DEF %s
+// MIPS64-DEF: "-target-cpu" "mips64r2"
+// MIPS64-DEF: "-target-abi" "n64"
+//
 // RUN: %clang -target mips-linux-gnu -### -c %s \
 // RUN:        -mabi=32 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-ABI-32 %s
+// MIPS-ABI-32: "-target-cpu" "mips32r2"
 // MIPS-ABI-32: "-target-abi" "o32"
 //
 // RUN: %clang -target mips-linux-gnu -### -c %s \
 // RUN:        -mabi=o32 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-ABI-O32 %s
+// MIPS-ABI-O32: "-target-cpu" "mips32r2"
 // MIPS-ABI-O32: "-target-abi" "o32"
 //
 // RUN: %clang -target mips-linux-gnu -### -c %s \
 // RUN:        -mabi=n32 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-ABI-N32 %s
+// MIPS-ABI-N32: "-target-cpu" "mips64r2"
 // MIPS-ABI-N32: "-target-abi" "n32"
 //
 // RUN: %clang -target mips64-linux-gnu -### -c %s \
 // RUN:        -mabi=64 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-ABI-64 %s
+// MIPS-ABI-64: "-target-cpu" "mips64r2"
 // MIPS-ABI-64: "-target-abi" "n64"
 //
 // RUN: %clang -target mips64-linux-gnu -### -c %s \
 // RUN:        -mabi=n64 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-ABI-N64 %s
+// MIPS-ABI-N64: "-target-cpu" "mips64r2"
 // MIPS-ABI-N64: "-target-abi" "n64"
 //
-// RUN: %clang -target mips64-linux-gnu -### -c %s \
+// RUN: not %clang -target mips64-linux-gnu -c %s \
 // RUN:        -mabi=o64 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-ABI-O64 %s
-// MIPS-ABI-O64: "-target-abi" "o64"
+// MIPS-ABI-O64: error: unknown target ABI 'o64'
 //
 // RUN: %clang -target mips-linux-gnu -### -c %s \
 // RUN:        -mabi=eabi 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-ABI-EABI %s
+// MIPS-ABI-EABI: "-target-cpu" "mips32r2"
 // MIPS-ABI-EABI: "-target-abi" "eabi"
+//
+// RUN: not %clang -target mips-linux-gnu -c %s \
+// RUN:        -mabi=unknown 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ABI-UNKNOWN %s
+// MIPS-ABI-UNKNOWN: error: unknown target ABI 'unknown'
+//
+// RUN: %clang -target mips-linux-gnu -### -c %s \
+// RUN:        -march=mips1 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ARCH-1 %s
+// MIPS-ARCH-1: "-target-cpu" "mips1"
+// MIPS-ARCH-1: "-target-abi" "o32"
+//
+// RUN: %clang -target mips-linux-gnu -### -c %s \
+// RUN:        -march=mips2 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ARCH-2 %s
+// MIPS-ARCH-2: "-target-cpu" "mips2"
+// MIPS-ARCH-2: "-target-abi" "o32"
+//
+// RUN: %clang -target mips-linux-gnu -### -c %s \
+// RUN:        -march=mips3 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ARCH-3 %s
+// MIPS-ARCH-3: "-target-cpu" "mips3"
+// MIPS-ARCH-3: "-target-abi" "o32"
+//
+// RUN: %clang -target mips-linux-gnu -### -c %s \
+// RUN:        -march=mips4 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ARCH-4 %s
+// MIPS-ARCH-4: "-target-cpu" "mips4"
+// MIPS-ARCH-4: "-target-abi" "o32"
+//
+// RUN: %clang -target mips-linux-gnu -### -c %s \
+// RUN:        -march=mips5 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ARCH-5 %s
+// MIPS-ARCH-5: "-target-cpu" "mips5"
+// MIPS-ARCH-5: "-target-abi" "o32"
+//
+// RUN: %clang -target mips-linux-gnu -### -c %s \
+// RUN:        -march=mips32 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ARCH-32 %s
+// MIPS-ARCH-32: "-target-cpu" "mips32"
+// MIPS-ARCH-32: "-target-abi" "o32"
+//
+// RUN: %clang -target mips-linux-gnu -### -c %s \
+// RUN:        -march=mips32r2 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ARCH-32R2 %s
+// MIPS-ARCH-32R2: "-target-cpu" "mips32r2"
+// MIPS-ARCH-32R2: "-target-abi" "o32"
+//
+// RUN: %clang -target mips-linux-gnu -### -c %s \
+// RUN:        -march=mips64 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ARCH-3264 %s
+// MIPS-ARCH-3264: "-target-cpu" "mips64"
+// MIPS-ARCH-3264: "-target-abi" "o32"
+//
+// RUN: %clang -target mips64-linux-gnu -### -c %s \
+// RUN:        -march=mips64 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ARCH-64 %s
+// MIPS-ARCH-64: "-target-cpu" "mips64"
+// MIPS-ARCH-64: "-target-abi" "n64"
+//
+// RUN: %clang -target mips64-linux-gnu -### -c %s \
+// RUN:        -march=mips64r2 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ARCH-64R2 %s
+// MIPS-ARCH-64R2: "-target-cpu" "mips64r2"
+// MIPS-ARCH-64R2: "-target-abi" "n64"
+//
+// RUN: %clang -target mips64-linux-gnu -### -c %s \
+// RUN:        -march=octeon 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ARCH-OCTEON %s
+// MIPS-ARCH-OCTEON: "-target-cpu" "octeon"
+// MIPS-ARCH-OCTEON: "-target-abi" "n64"
+//
+// RUN: not %clang -target mips64-linux-gnu -c %s \
+// RUN:        -march=mips32 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ARCH-6432 %s
+// MIPS-ARCH-6432: error: unknown target CPU 'mips32'
+//
+// RUN: not %clang -target mips-linux-gnu -c %s \
+// RUN:        -march=unknown 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ARCH-UNKNOWN %s
+// MIPS-ARCH-UNKNOWN: error: unknown target CPU 'unknown'
diff --git a/test/Driver/mips-as.c b/test/Driver/mips-as.c
index b861943..ecbe7d6 100644
--- a/test/Driver/mips-as.c
+++ b/test/Driver/mips-as.c
@@ -2,127 +2,262 @@
 //
 // RUN: %clang -target mips-linux-gnu -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
-// RUN:   | FileCheck -check-prefix=MIPS32-EB-AS %s
-// MIPS32-EB-AS: as{{(.exe)?}}" "-march" "mips32" "-mabi" "32" "-EB"
-// MIPS32-EB-AS-NOT: "-KPIC"
+// RUN:   | FileCheck -check-prefix=MIPS32R2-EB-AS %s
+// RUN: %clang -target mipsel-linux-gnu -### \
+// RUN:   -no-integrated-as -c -EB %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS32R2-EB-AS %s
+// MIPS32R2-EB-AS: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-mno-shared" "-call_nonpic" "-EB"
+// MIPS32R2-EB-AS-NOT: "{{[ A-Za-z\\\/]*}}as{{(.exe)?}}{{.*}}"-KPIC"
 //
 // RUN: %clang -target mips-linux-gnu -### \
 // RUN:   -no-integrated-as -fPIC -c %s 2>&1 \
-// RUN:   | FileCheck -check-prefix=MIPS32-EB-PIC %s
-// MIPS32-EB-PIC: as{{(.exe)?}}" "-march" "mips32" "-mabi" "32" "-EB"
-// MIPS32-EB-PIC: "-KPIC"
+// RUN:   | FileCheck -check-prefix=MIPS32R2-EB-PIC %s
+// MIPS32R2-EB-PIC: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-call_nonpic" "-EB"
+// MIPS32R2-EB-PIC: "-KPIC"
 //
 // RUN: %clang -target mipsel-linux-gnu -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
-// RUN:   | FileCheck -check-prefix=MIPS32-DEF-EL-AS %s
-// MIPS32-DEF-EL-AS: as{{(.exe)?}}" "-march" "mips32" "-mabi" "32" "-EL"
+// RUN:   | FileCheck -check-prefix=MIPS32R2-DEF-EL-AS %s
+// 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:   | FileCheck -check-prefix=MIPS64-EB-AS %s
-// MIPS64-EB-AS: as{{(.exe)?}}" "-march" "mips64" "-mabi" "64" "-EB"
+// RUN:   | FileCheck -check-prefix=MIPS64R2-EB-AS %s
+// MIPS64R2-EB-AS: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64" "-mno-shared" "-KPIC" "-EB"
 //
 // RUN: %clang -target mips64el-linux-gnu -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
-// RUN:   | FileCheck -check-prefix=MIPS64-DEF-EL-AS %s
-// MIPS64-DEF-EL-AS: as{{(.exe)?}}" "-march" "mips64" "-mabi" "64" "-EL"
+// RUN:   | FileCheck -check-prefix=MIPS64R2-DEF-EL-AS %s
+// MIPS64R2-DEF-EL-AS: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64"  "-mno-shared" "-KPIC" "-EL"
 //
 // RUN: %clang -target mips-linux-gnu -mabi=eabi -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-EABI %s
-// MIPS-EABI: as{{(.exe)?}}" "-march" "mips32" "-mabi" "eabi" "-EB"
+// MIPS-EABI: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "eabi" "-mno-shared" "-call_nonpic" "-EB"
 //
 // RUN: %clang -target mips64-linux-gnu -mabi=n32 -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-N32 %s
-// MIPS-N32: as{{(.exe)?}}" "-march" "mips64" "-mabi" "n32" "-EB"
+// MIPS-N32: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "n32" "-mno-shared" "-call_nonpic" "-EB"
 //
 // RUN: %clang -target mipsel-linux-gnu -mabi=32 -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
-// RUN:   | FileCheck -check-prefix=MIPS32-EL-AS %s
-// MIPS32-EL-AS: as{{(.exe)?}}" "-march" "mips32" "-mabi" "32" "-EL"
+// RUN:   | FileCheck -check-prefix=MIPS32R2-EL-AS %s
+// RUN: %clang -target mips-linux-gnu -mabi=32 -### \
+// RUN:   -no-integrated-as -c %s -EL 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS32R2-EL-AS %s
+// MIPS32R2-EL-AS: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-mno-shared" "-call_nonpic" "-EL"
 //
 // RUN: %clang -target mips64el-linux-gnu -mabi=64 -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
-// RUN:   | FileCheck -check-prefix=MIPS64-EL-AS %s
-// MIPS64-EL-AS: as{{(.exe)?}}" "-march" "mips64" "-mabi" "64" "-EL"
+// RUN:   | FileCheck -check-prefix=MIPS64R2-EL-AS %s
+// MIPS64R2-EL-AS: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64"  "-mno-shared" "-KPIC" "-EL"
 //
 // RUN: %clang -target mips-linux-gnu -march=mips32r2 -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-32R2 %s
-// MIPS-32R2: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-EB"
+// MIPS-32R2: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-mno-shared" "-call_nonpic" "-EB"
+//
+// RUN: %clang -target mips64-linux-gnu -march=octeon -### \
+// RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-OCTEON %s
+// MIPS-OCTEON: as{{(.exe)?}}" "-march" "octeon" "-mabi" "64"  "-mno-shared" "-KPIC" "-EB"
+//
+// RUN: %clang -target mips-linux-gnu -mips1 -### \
+// RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ALIAS-1 %s
+// MIPS-ALIAS-1: as{{(.exe)?}}" "-march" "mips1" "-mabi" "32" "-mno-shared" "-call_nonpic" "-EB"
+//
+// RUN: %clang -target mips-linux-gnu -mips2 -### \
+// RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ALIAS-2 %s
+// MIPS-ALIAS-2: as{{(.exe)?}}" "-march" "mips2" "-mabi" "32" "-mno-shared" "-call_nonpic" "-EB"
+//
+// RUN: %clang -target mips-linux-gnu -mips3 -### \
+// RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ALIAS-3 %s
+// MIPS-ALIAS-3: as{{(.exe)?}}" "-march" "mips3" "-mabi" "32" "-mno-shared" "-call_nonpic" "-EB"
+//
+// RUN: %clang -target mips-linux-gnu -mips4 -### \
+// RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ALIAS-4 %s
+// MIPS-ALIAS-4: as{{(.exe)?}}" "-march" "mips4" "-mabi" "32" "-mno-shared" "-call_nonpic" "-EB"
+//
+// RUN: %clang -target mips-linux-gnu -mips5 -### \
+// RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ALIAS-5 %s
+// MIPS-ALIAS-5: as{{(.exe)?}}" "-march" "mips5" "-mabi" "32" "-mno-shared" "-call_nonpic" "-EB"
 //
 // RUN: %clang -target mips-linux-gnu -mips32 -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-ALIAS-32 %s
-// MIPS-ALIAS-32: as{{(.exe)?}}" "-march" "mips32" "-mabi" "32" "-EB"
+// MIPS-ALIAS-32: as{{(.exe)?}}" "-march" "mips32" "-mabi" "32" "-mno-shared" "-call_nonpic" "-EB"
 //
 // RUN: %clang -target mips-linux-gnu -mips32r2 -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-ALIAS-32R2 %s
-// MIPS-ALIAS-32R2: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-EB"
+// MIPS-ALIAS-32R2: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-mno-shared" "-call_nonpic" "-EB"
 //
-// RUN: %clang -target mips-linux-gnu -mips64 -### \
+// RUN: %clang -target mips-linux-gnu -mips32r6 -### \
+// RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ALIAS-32R6 %s
+// MIPS-ALIAS-32R6: as{{(.exe)?}}" "-march" "mips32r6" "-mabi" "32" "-mno-shared" "-call_nonpic" "-EB"
+//
+// RUN: %clang -target mips64-linux-gnu -mips64 -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-ALIAS-64 %s
-// MIPS-ALIAS-64: as{{(.exe)?}}" "-march" "mips64" "-mabi" "64" "-EB"
+// MIPS-ALIAS-64: as{{(.exe)?}}" "-march" "mips64" "-mabi" "64"  "-mno-shared" "-KPIC" "-EB"
 //
-// RUN: %clang -target mips-linux-gnu -mips64r2 -### \
+// RUN: %clang -target mips64-linux-gnu -mips64r2 -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-ALIAS-64R2 %s
-// MIPS-ALIAS-64R2: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64" "-EB"
+// MIPS-ALIAS-64R2: as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64"  "-mno-shared" "-KPIC" "-EB"
+//
+// RUN: %clang -target mips64-linux-gnu -mips64r6 -### \
+// RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-ALIAS-64R6 %s
+// MIPS-ALIAS-64R6: as{{(.exe)?}}" "-march" "mips64r6" "-mabi" "64"  "-mno-shared" "-KPIC" "-EB"
 //
 // RUN: %clang -target mips-linux-gnu -mno-mips16 -mips16 -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-16 %s
-// MIPS-16: as{{(.exe)?}}" "-march" "mips32" "-mabi" "32" "-EB" "-mips16"
+// MIPS-16: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-mno-shared" "-call_nonpic" "-EB" "-mips16"
 //
 // RUN: %clang -target mips-linux-gnu -mips16 -mno-mips16 -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-N16 %s
 // MIPS-N16: as{{(.exe)?}}"
-// MIPS-N16-NOT: "-mips16"
+// MIPS-N16: -no-mips16
 //
 // RUN: %clang -target mips-linux-gnu -mno-micromips -mmicromips -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-MICRO %s
-// MIPS-MICRO: as{{(.exe)?}}" "-march" "mips32" "-mabi" "32" "-EB" "-mmicromips"
+// MIPS-MICRO: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-mno-shared" "-call_nonpic" "-EB" "-mmicromips"
 //
 // RUN: %clang -target mips-linux-gnu -mmicromips -mno-micromips -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-NMICRO %s
 // MIPS-NMICRO: as{{(.exe)?}}"
-// MIPS-NMICRO-NOT: "-mmicromips"
+// MIPS-NMICRO-NOT: {{[A-Za-z\\\/]*}}as{{(.exe)?}}{{.*}}"-mmicromips"
 //
 // RUN: %clang -target mips-linux-gnu -mno-dsp -mdsp -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-DSP %s
-// MIPS-DSP: as{{(.exe)?}}" "-march" "mips32" "-mabi" "32" "-EB" "-mdsp"
+// MIPS-DSP: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-mno-shared" "-call_nonpic" "-EB" "-mdsp"
 //
 // RUN: %clang -target mips-linux-gnu -mdsp -mno-dsp -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-NDSP %s
 // MIPS-NDSP: as{{(.exe)?}}"
-// MIPS-NDSP-NOT: "-mdsp"
+// MIPS-NDSP-NOT: "{{[ A-Za-z\\\/]*}}as{{(.exe)?}}{{.*}}"-mdsp"
 //
 // RUN: %clang -target mips-linux-gnu -mno-dspr2 -mdspr2 -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-DSPR2 %s
-// MIPS-DSPR2: as{{(.exe)?}}" "-march" "mips32" "-mabi" "32" "-EB" "-mdspr2"
+// MIPS-DSPR2: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-mno-shared" "-call_nonpic" "-EB" "-mdspr2"
 //
 // RUN: %clang -target mips-linux-gnu -mdspr2 -mno-dspr2 -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-NDSPR2 %s
 // MIPS-NDSPR2: as{{(.exe)?}}"
-// MIPS-NDSPR2-NOT: "-mdspr2"
+// MIPS-NDSPR2-NOT: "{{[ A-Za-z\\\/]*}}as{{(.exe)?}}{{.*}}"-mdspr2"
 //
 // RUN: %clang -target mips-linux-gnu -mnan=legacy -mnan=2008 -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-NAN2008 %s
-// MIPS-NAN2008: as{{(.exe)?}}" "-march" "mips32" "-mabi" "32" "-EB" "-mnan=2008"
+// MIPS-NAN2008: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-mno-shared" "-call_nonpic" "-EB" "-mnan=2008"
 //
 // RUN: %clang -target mips-linux-gnu -mnan=2008 -mnan=legacy -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=MIPS-NAN-LEGACY %s
 // MIPS-NAN-LEGACY: as{{(.exe)?}}"
-// MIPS-NAN_LEGACY-NOT: "-mnan={{.*}}"
+// MIPS-NAN-LEGACY-NOT: "{{[ A-Za-z\\\/]*}}as{{(.exe)?}}{{.*}}"-mnan={{.*}}"
+//
+// RUN: %clang -target mips-linux-gnu -mfp64 -mfpxx -mfp32 -### \
+// RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-MFP32 %s
+// MIPS-MFP32: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-mno-shared" "-call_nonpic" "-EB" "-mfp32"
+//
+// RUN: %clang -target mips-linux-gnu -mfp32 -mfp64 -mfpxx -### \
+// RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-MFPXX %s
+// MIPS-MFPXX: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-mno-shared" "-call_nonpic" "-EB" "-mfpxx"
+//
+// RUN: %clang -target mips-linux-gnu -mfpxx -mfp32 -mfp64 -### \
+// RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-MFP64 %s
+// MIPS-MFP64: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-mno-shared" "-call_nonpic" "-EB" "-mfp64"
+//
+// RUN: %clang -target mips-linux-gnu -mno-msa -mmsa -### \
+// RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-MSA %s
+// MIPS-MSA: as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32" "-mno-shared" "-call_nonpic" "-EB" "-mmsa"
+//
+// RUN: %clang -target mips-linux-gnu -mmsa -mno-msa -### \
+// RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=MIPS-NMSA %s
+// MIPS-NMSA: as{{(.exe)?}}"
+// MIPS-NMSA-NOT: "{{[ A-Za-z\\\/]*}}as{{(.exe)?}}{{.*}}"-mmsa"
+//
+// We've already tested MIPS32r2 and MIPS64r2 thoroughly. Do minimal tests on
+// the remaining CPU's since it was possible to pass on a -mabi with no value
+// when the CPU name is absent from a StringSwitch in getMipsCPUAndABI()
+// RUN: %clang -target mips-linux-gnu -### -no-integrated-as -c %s -mcpu=mips1 \
+// RUN:   2>&1 | FileCheck -check-prefix=MIPS1-EB-AS %s
+// MIPS1-EB-AS: as{{(.exe)?}}" "-march" "mips1" "-mabi" "32" "-mno-shared" "-call_nonpic" "-EB"
+// MIPS1-EB-AS-NOT: "{{[ A-Za-z\\\/]*}}as{{(.exe)?}}{{.*}}"-KPIC"
+//
+// RUN: %clang -target mips-linux-gnu -### -no-integrated-as -c %s -mcpu=mips2 \
+// RUN:   2>&1 | FileCheck -check-prefix=MIPS2-EB-AS %s
+// MIPS2-EB-AS: as{{(.exe)?}}" "-march" "mips2" "-mabi" "32" "-mno-shared" "-call_nonpic" "-EB"
+// MIPS2-EB-AS-NOT: "{{[ A-Za-z\\\/]*}}as{{(.exe)?}}{{.*}}"-KPIC"
+//
+// RUN: %clang -target mips64-linux-gnu -### -no-integrated-as -c %s -mcpu=mips3 \
+// RUN:   2>&1 | FileCheck -check-prefix=MIPS3-EB-AS %s
+// MIPS3-EB-AS: as{{(.exe)?}}" "-march" "mips3" "-mabi" "64"  "-mno-shared" "-KPIC" "-EB"
+//
+// 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"
+//
+// 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"
+//
+// RUN: %clang -target mips-linux-gnu -### -no-integrated-as -c %s -mcpu=mips32 \
+// RUN:   2>&1 | FileCheck -check-prefix=MIPS32-EB-AS %s
+// MIPS32-EB-AS: as{{(.exe)?}}" "-march" "mips32" "-mabi" "32" "-mno-shared" "-call_nonpic" "-EB"
+// MIPS32-EB-AS-NOT: "{{[ A-Za-z\\\/]*}}as{{(.exe)?}}{{.*}}"-KPIC"
+//
+// RUN: %clang -target mips-linux-gnu -### -no-integrated-as -c %s -mcpu=mips32r6 \
+// RUN:   2>&1 | FileCheck -check-prefix=MIPS32R6-EB-AS %s
+// MIPS32R6-EB-AS: as{{(.exe)?}}" "-march" "mips32r6" "-mabi" "32" "-mno-shared" "-call_nonpic" "-EB"
+// MIPS32R6-EB-AS-NOT: "{{[ A-Za-z\\\/]*}}as{{(.exe)?}}{{.*}}"-KPIC"
+//
+// RUN: %clang -target mips64-linux-gnu -### -no-integrated-as -c %s -mcpu=mips64 \
+// RUN:   2>&1 | FileCheck -check-prefix=MIPS64-EB-AS %s
+// MIPS64-EB-AS: as{{(.exe)?}}" "-march" "mips64" "-mabi" "64"  "-mno-shared" "-KPIC" "-EB"
+//
+// 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"
+//
+// 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
+// HARDFLOAT: as{{(.exe)?}}"
+// HARDFLOAT: -mhard-float
+//
+// RUN: %clang -target mips-linux-gnu -### -no-integrated-as -mhard-float -msoft-float -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=SOFTFLOAT --implicit-check-not=-mhard-float %s
+// SOFTFLOAT: as{{(.exe)?}}"
+// SOFTFLOAT: -msoft-float
+//
+// RUN: %clang -target mips-linux-gnu -### -no-integrated-as -mno-odd-spreg -modd-spreg -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=ODDSPREG --implicit-check-not=-mno-odd-spreg %s
+// ODDSPREG: as{{(.exe)?}}"
+// ODDSPREG: -modd-spreg
+//
+// RUN: %clang -target mips-linux-gnu -### -no-integrated-as -modd-spreg -mno-odd-spreg -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=NOODDSPREG --implicit-check-not=-modd-spreg %s
+// NOODDSPREG: as{{(.exe)?}}"
+// NOODDSPREG: -mno-odd-spreg
diff --git a/test/Driver/mips-cs-header-search.cpp b/test/Driver/mips-cs-header-search.cpp
deleted file mode 100644
index 5538031..0000000
--- a/test/Driver/mips-cs-header-search.cpp
+++ /dev/null
@@ -1,257 +0,0 @@
-// Check frontend invocations on Mentor Graphics MIPS toolchain.
-//
-// = Big-endian, hard float
-// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \
-// RUN:     --target=mips-linux-gnu \
-// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-BE-HF-32 %s
-// CHECK-BE-HF-32: "-internal-isystem"
-// CHECK-BE-HF-32: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
-// CHECK-BE-HF-32: "-internal-isystem"
-// CHECK-BE-HF-32: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu"
-// CHECK-BE-HF-32: "-internal-isystem"
-// CHECK-BE-HF-32: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
-// CHECK-BE-HF-32: "-internal-externc-isystem"
-// CHECK-BE-HF-32: "[[TC]]/include"
-// CHECK-BE-HF-32: "-internal-externc-isystem"
-// CHECK-BE-HF-32: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
-//
-// = Big-endian, hard float, mips16
-// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \
-// RUN:     --target=mips-linux-gnu -mips16 \
-// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-BE-HF-16 %s
-// CHECK-BE-HF-16: "-internal-isystem"
-// CHECK-BE-HF-16: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
-// CHECK-BE-HF-16: "-internal-isystem"
-// CHECK-BE-HF-16: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/mips16"
-// CHECK-BE-HF-16: "-internal-isystem"
-// CHECK-BE-HF-16: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
-// CHECK-BE-HF-16: "-internal-externc-isystem"
-// CHECK-BE-HF-16: "[[TC]]/include"
-// CHECK-BE-HF-16: "-internal-externc-isystem"
-// CHECK-BE-HF-16: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
-//
-// = Big-endian, hard float, micromips
-// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \
-// RUN:     --target=mips-linux-gnu -mmicromips \
-// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-BE-HF-MICRO %s
-// CHECK-BE-HF-MICRO: "-internal-isystem"
-// CHECK-BE-HF-MICRO: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
-// CHECK-BE-HF-MICRO: "-internal-isystem"
-// CHECK-BE-HF-MICRO: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/micromips"
-// CHECK-BE-HF-MICRO: "-internal-isystem"
-// CHECK-BE-HF-MICRO: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
-// CHECK-BE-HF-MICRO: "-internal-externc-isystem"
-// CHECK-BE-HF-MICRO: "[[TC]]/include"
-// CHECK-BE-HF-MICRO: "-internal-externc-isystem"
-// CHECK-BE-HF-MICRO: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
-//
-// = Big-endian, soft float
-// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \
-// RUN:     --target=mips-linux-gnu -msoft-float \
-// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-BE-SF-32 %s
-// CHECK-BE-SF-32: "-internal-isystem"
-// CHECK-BE-SF-32: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
-// CHECK-BE-SF-32: "-internal-isystem"
-// CHECK-BE-SF-32: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/soft-float"
-// CHECK-BE-SF-32: "-internal-isystem"
-// CHECK-BE-SF-32: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
-// CHECK-BE-SF-32: "-internal-externc-isystem"
-// CHECK-BE-SF-32: "[[TC]]/include"
-// CHECK-BE-SF-32: "-internal-externc-isystem"
-// CHECK-BE-SF-32: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
-//
-// = Big-endian, soft float, mips16
-// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \
-// RUN:     --target=mips-linux-gnu -msoft-float -mips16 \
-// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-BE-SF-16 %s
-// CHECK-BE-SF-16: "-internal-isystem"
-// CHECK-BE-SF-16: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
-// CHECK-BE-SF-16: "-internal-isystem"
-// CHECK-BE-SF-16: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/mips16/soft-float"
-// CHECK-BE-SF-16: "-internal-isystem"
-// CHECK-BE-SF-16: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
-// CHECK-BE-SF-16: "-internal-externc-isystem"
-// CHECK-BE-SF-16: "[[TC]]/include"
-// CHECK-BE-SF-16: "-internal-externc-isystem"
-// CHECK-BE-SF-16: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
-//
-// = Big-endian, soft float, micromips
-// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \
-// RUN:     --target=mips-linux-gnu -msoft-float -mmicromips \
-// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-BE-SF-MICRO %s
-// CHECK-BE-SF-MICRO: "-internal-isystem"
-// CHECK-BE-SF-MICRO: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
-// CHECK-BE-SF-MICRO: "-internal-isystem"
-// CHECK-BE-SF-MICRO: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/micromips/soft-float"
-// CHECK-BE-SF-MICRO: "-internal-isystem"
-// CHECK-BE-SF-MICRO: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
-// CHECK-BE-SF-MICRO: "-internal-externc-isystem"
-// CHECK-BE-SF-MICRO: "[[TC]]/include"
-// CHECK-BE-SF-MICRO: "-internal-externc-isystem"
-// CHECK-BE-SF-MICRO: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
-//
-// = Big-endian, hard float, 64-bit
-// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \
-// RUN:     --target=mips64-linux-gnu \
-// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-BE-HF-64 %s
-// CHECK-BE-HF-64: "-internal-isystem"
-// CHECK-BE-HF-64: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
-// CHECK-BE-HF-64: "-internal-isystem"
-// CHECK-BE-HF-64: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/64"
-// CHECK-BE-HF-64: "-internal-isystem"
-// CHECK-BE-HF-64: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
-// CHECK-BE-HF-64: "-internal-externc-isystem"
-// CHECK-BE-HF-64: "[[TC]]/include"
-// CHECK-BE-HF-64: "-internal-externc-isystem"
-// CHECK-BE-HF-64: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
-//
-// = Big-endian, soft float, 64-bit
-// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \
-// RUN:     --target=mips64-linux-gnu -msoft-float \
-// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-BE-SF-64 %s
-// CHECK-BE-SF-64: "-internal-isystem"
-// CHECK-BE-SF-64: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
-// CHECK-BE-SF-64: "-internal-isystem"
-// CHECK-BE-SF-64: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/soft-float/64"
-// CHECK-BE-SF-64: "-internal-isystem"
-// CHECK-BE-SF-64: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
-// CHECK-BE-SF-64: "-internal-externc-isystem"
-// CHECK-BE-SF-64: "[[TC]]/include"
-// CHECK-BE-SF-64: "-internal-externc-isystem"
-// CHECK-BE-SF-64: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
-//
-// = Little-endian, hard float
-// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \
-// RUN:     --target=mipsel-linux-gnu -mhard-float \
-// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-EL-HF-32 %s
-// CHECK-EL-HF-32: "-internal-isystem"
-// CHECK-EL-HF-32: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
-// CHECK-EL-HF-32: "-internal-isystem"
-// CHECK-EL-HF-32: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/el"
-// CHECK-EL-HF-32: "-internal-isystem"
-// CHECK-EL-HF-32: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
-// CHECK-EL-HF-32: "-internal-externc-isystem"
-// CHECK-EL-HF-32: "[[TC]]/include"
-// CHECK-EL-HF-32: "-internal-externc-isystem"
-// CHECK-EL-HF-32: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
-//
-// = Little-endian, hard float, mips16
-// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \
-// RUN:     --target=mipsel-linux-gnu -mips16 \
-// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-EL-HF-16 %s
-// CHECK-EL-HF-16: "-internal-isystem"
-// CHECK-EL-HF-16: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
-// CHECK-EL-HF-16: "-internal-isystem"
-// CHECK-EL-HF-16: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/mips16/el"
-// CHECK-EL-HF-16: "-internal-isystem"
-// CHECK-EL-HF-16: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
-// CHECK-EL-HF-16: "-internal-externc-isystem"
-// CHECK-EL-HF-16: "[[TC]]/include"
-// CHECK-EL-HF-16: "-internal-externc-isystem"
-// CHECK-EL-HF-16: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
-//
-// = Little-endian, hard float, micromips
-// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \
-// RUN:     --target=mipsel-linux-gnu -mmicromips \
-// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-EL-HF-MICRO %s
-// CHECK-EL-HF-MICRO: "-internal-isystem"
-// CHECK-EL-HF-MICRO: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
-// CHECK-EL-HF-MICRO: "-internal-isystem"
-// CHECK-EL-HF-MICRO: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/micromips/el"
-// CHECK-EL-HF-MICRO: "-internal-isystem"
-// CHECK-EL-HF-MICRO: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
-// CHECK-EL-HF-MICRO: "-internal-externc-isystem"
-// CHECK-EL-HF-MICRO: "[[TC]]/include"
-// CHECK-EL-HF-MICRO: "-internal-externc-isystem"
-// CHECK-EL-HF-MICRO: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
-//
-// = Little-endian, soft float
-// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \
-// RUN:     --target=mipsel-linux-gnu -mfloat-abi=soft \
-// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-EL-SF-32 %s
-// CHECK-EL-SF-32: "-internal-isystem"
-// CHECK-EL-SF-32: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
-// CHECK-EL-SF-32: "-internal-isystem"
-// CHECK-EL-SF-32: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/soft-float/el"
-// CHECK-EL-SF-32: "-internal-isystem"
-// CHECK-EL-SF-32: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
-// CHECK-EL-SF-32: "-internal-externc-isystem"
-// CHECK-EL-SF-32: "[[TC]]/include"
-// CHECK-EL-SF-32: "-internal-externc-isystem"
-// CHECK-EL-SF-32: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
-//
-// = Little-endian, soft float, mips16
-// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \
-// RUN:     --target=mipsel-linux-gnu -mips16 -msoft-float \
-// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-EL-SF-16 %s
-// CHECK-EL-SF-16: "-internal-isystem"
-// CHECK-EL-SF-16: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
-// CHECK-EL-SF-16: "-internal-isystem"
-// CHECK-EL-SF-16: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/mips16/soft-float/el"
-// CHECK-EL-SF-16: "-internal-isystem"
-// CHECK-EL-SF-16: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
-// CHECK-EL-SF-16: "-internal-externc-isystem"
-// CHECK-EL-SF-16: "[[TC]]/include"
-// CHECK-EL-SF-16: "-internal-externc-isystem"
-// CHECK-EL-SF-16: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
-//
-// = Little-endian, soft float, micromips
-// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \
-// RUN:     --target=mipsel-linux-gnu -mmicromips -msoft-float \
-// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-EL-SF-MICRO %s
-// CHECK-EL-SF-MICRO: "-internal-isystem"
-// CHECK-EL-SF-MICRO: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
-// CHECK-EL-SF-MICRO: "-internal-isystem"
-// CHECK-EL-SF-MICRO: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/micromips/soft-float/el"
-// CHECK-EL-SF-MICRO: "-internal-isystem"
-// CHECK-EL-SF-MICRO: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
-// CHECK-EL-SF-MICRO: "-internal-externc-isystem"
-// CHECK-EL-SF-MICRO: "[[TC]]/include"
-// CHECK-EL-SF-MICRO: "-internal-externc-isystem"
-// CHECK-EL-SF-MICRO: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
-//
-// = Little-endian, hard float, 64-bit
-// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \
-// RUN:     --target=mips64el-linux-gnu \
-// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-EL-HF-64 %s
-// CHECK-EL-HF-64: "-internal-isystem"
-// CHECK-EL-HF-64: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
-// CHECK-EL-HF-64: "-internal-isystem"
-// CHECK-EL-HF-64: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/el/64"
-// CHECK-EL-HF-64: "-internal-isystem"
-// CHECK-EL-HF-64: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
-// CHECK-EL-HF-64: "-internal-externc-isystem"
-// CHECK-EL-HF-64: "[[TC]]/include"
-// CHECK-EL-HF-64: "-internal-externc-isystem"
-// CHECK-EL-HF-64: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
-//
-// = Little-endian, soft float, 64-bit
-// RUN: %clang -no-canonical-prefixes %s -### -c -o %t.o 2>&1 \
-// RUN:     --target=mips64el-linux-gnu -msoft-float \
-// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-EL-SF-64 %s
-// CHECK-EL-SF-64: "-internal-isystem"
-// CHECK-EL-SF-64: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
-// CHECK-EL-SF-64: "-internal-isystem"
-// CHECK-EL-SF-64: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/soft-float/el/64"
-// CHECK-EL-SF-64: "-internal-isystem"
-// CHECK-EL-SF-64: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
-// CHECK-EL-SF-64: "-internal-externc-isystem"
-// CHECK-EL-SF-64: "[[TC]]/include"
-// CHECK-EL-SF-64: "-internal-externc-isystem"
-// CHECK-EL-SF-64: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
diff --git a/test/Driver/mips-cs-ld.c b/test/Driver/mips-cs-ld.c
deleted file mode 100644
index cdbd5c8..0000000
--- a/test/Driver/mips-cs-ld.c
+++ /dev/null
@@ -1,288 +0,0 @@
-// Check ld invocations on Mentor Graphics MIPS toolchain.
-//
-// = Big-endian, hard float
-// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     --target=mips-linux-gnu \
-// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-BE-HF-32 %s
-// CHECK-BE-HF-32: "{{.*}}ld{{(.exe)?}}"
-// CHECK-BE-HF-32: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc"
-// CHECK-BE-HF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/usr/lib/../lib{{/|\\\\}}crt1.o"
-// CHECK-BE-HF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/usr/lib/../lib{{/|\\\\}}crti.o"
-// CHECK-BE-HF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3{{/|\\\\}}crtbegin.o"
-// CHECK-BE-HF-32: "-L[[TC]]"
-// CHECK-BE-HF-32: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib"
-// CHECK-BE-HF-32: "-L[[TC]]/../../../../mips-linux-gnu/libc/lib"
-// CHECK-BE-HF-32: "-L[[TC]]/../../../../mips-linux-gnu/libc/usr/lib"
-// CHECK-BE-HF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3{{/|\\\\}}crtend.o"
-// CHECK-BE-HF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/usr/lib/../lib{{/|\\\\}}crtn.o"
-//
-// = Big-endian, hard float, mips16
-// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     --target=mips-linux-gnu -mips16 \
-// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-BE-HF-16 %s
-// CHECK-BE-HF-16: "{{.*}}ld{{(.exe)?}}"
-// CHECK-BE-HF-16: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/mips16"
-// CHECK-BE-HF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/mips16/usr/lib/../lib{{/|\\\\}}crt1.o"
-// CHECK-BE-HF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/mips16/usr/lib/../lib{{/|\\\\}}crti.o"
-// CHECK-BE-HF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/mips16{{/|\\\\}}crtbegin.o"
-// CHECK-BE-HF-16: "-L[[TC]]/mips16"
-// CHECK-BE-HF-16: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/mips16"
-// CHECK-BE-HF-16-NOT: "-L[[TC]]"
-// CHECK-BE-HF-16: "-L[[TC]]/../../../../mips-linux-gnu/libc/mips16/lib/../lib"
-// CHECK-BE-HF-16: "-L[[TC]]/../../../../mips-linux-gnu/libc/mips16/usr/lib/../lib"
-// CHECK-BE-HF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/mips16{{/|\\\\}}crtend.o"
-// CHECK-BE-HF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/mips16/usr/lib/../lib{{/|\\\\}}crtn.o"
-//
-// = Big-endian, hard float, mmicromips
-// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     --target=mips-linux-gnu -mmicromips \
-// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-BE-HF-MICRO %s
-// CHECK-BE-HF-MICRO: "{{.*}}ld{{(.exe)?}}"
-// CHECK-BE-HF-MICRO: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/micromips"
-// CHECK-BE-HF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/micromips/usr/lib/../lib{{/|\\\\}}crt1.o"
-// CHECK-BE-HF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/micromips/usr/lib/../lib{{/|\\\\}}crti.o"
-// CHECK-BE-HF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/micromips{{/|\\\\}}crtbegin.o"
-// CHECK-BE-HF-MICRO: "-L[[TC]]/micromips"
-// CHECK-BE-HF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/micromips"
-// CHECK-BE-HF-MICRO-NOT: "-L[[TC]]"
-// CHECK-BE-HF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/libc/micromips/lib/../lib"
-// CHECK-BE-HF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/libc/micromips/usr/lib/../lib"
-// CHECK-BE-HF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/micromips{{/|\\\\}}crtend.o"
-// CHECK-BE-HF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/micromips/usr/lib/../lib{{/|\\\\}}crtn.o"
-//
-// = Big-endian, soft float
-// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     --target=mips-linux-gnu -msoft-float \
-// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-BE-SF-32 %s
-// CHECK-BE-SF-32: "{{.*}}ld{{(.exe)?}}"
-// CHECK-BE-SF-32: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/soft-float"
-// CHECK-BE-SF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/soft-float/usr/lib/../lib{{/|\\\\}}crt1.o"
-// CHECK-BE-SF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/soft-float/usr/lib/../lib{{/|\\\\}}crti.o"
-// CHECK-BE-SF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/soft-float{{/|\\\\}}crtbegin.o"
-// CHECK-BE-SF-32: "-L[[TC]]/soft-float"
-// CHECK-BE-SF-32: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/soft-float"
-// CHECK-BE-SF-32-NOT: "-L[[TC]]"
-// CHECK-BE-SF-32: "-L[[TC]]/../../../../mips-linux-gnu/libc/soft-float/lib/../lib"
-// CHECK-BE-SF-32: "-L[[TC]]/../../../../mips-linux-gnu/libc/soft-float/usr/lib/../lib"
-// CHECK-BE-SF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/soft-float{{/|\\\\}}crtend.o"
-// CHECK-BE-SF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/soft-float/usr/lib/../lib{{/|\\\\}}crtn.o"
-//
-// = Big-endian, soft float, mips16
-// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     --target=mips-linux-gnu -msoft-float -mips16 \
-// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-BE-SF-16 %s
-// CHECK-BE-SF-16: "{{.*}}ld{{(.exe)?}}"
-// CHECK-BE-SF-16: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/mips16/soft-float"
-// CHECK-BE-SF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/mips16/soft-float/usr/lib/../lib{{/|\\\\}}crt1.o"
-// CHECK-BE-SF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/mips16/soft-float/usr/lib/../lib{{/|\\\\}}crti.o"
-// CHECK-BE-SF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float{{/|\\\\}}crtbegin.o"
-// CHECK-BE-SF-16: "-L[[TC]]/mips16/soft-float"
-// CHECK-BE-SF-16: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/mips16/soft-float"
-// CHECK-BE-SF-16-NOT: "-L[[TC]]"
-// CHECK-BE-SF-16: "-L[[TC]]/../../../../mips-linux-gnu/libc/mips16/soft-float/lib/../lib"
-// CHECK-BE-SF-16: "-L[[TC]]/../../../../mips-linux-gnu/libc/mips16/soft-float/usr/lib/../lib"
-// CHECK-BE-SF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float{{/|\\\\}}crtend.o"
-// CHECK-BE-SF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/mips16/soft-float/usr/lib/../lib{{/|\\\\}}crtn.o"
-//
-// = Big-endian, soft float, micromips
-// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     --target=mips-linux-gnu -msoft-float -mmicromips \
-// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-BE-SF-MICRO %s
-// CHECK-BE-SF-MICRO: "{{.*}}ld{{(.exe)?}}"
-// CHECK-BE-SF-MICRO: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/micromips/soft-float"
-// CHECK-BE-SF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/micromips/soft-float/usr/lib/../lib{{/|\\\\}}crt1.o"
-// CHECK-BE-SF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/micromips/soft-float/usr/lib/../lib{{/|\\\\}}crti.o"
-// CHECK-BE-SF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float{{/|\\\\}}crtbegin.o"
-// CHECK-BE-SF-MICRO: "-L[[TC]]/micromips/soft-float"
-// CHECK-BE-SF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/micromips/soft-float"
-// CHECK-BE-SF-MICRO-NOT: "-L[[TC]]"
-// CHECK-BE-SF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/libc/micromips/soft-float/lib/../lib"
-// CHECK-BE-SF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/libc/micromips/soft-float/usr/lib/../lib"
-// CHECK-BE-SF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float{{/|\\\\}}crtend.o"
-// CHECK-BE-SF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/micromips/soft-float/usr/lib/../lib{{/|\\\\}}crtn.o"
-//
-// = Big-endian, hard float, 64-bit
-// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     --target=mips64-linux-gnu \
-// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-BE-HF-64 %s
-// CHECK-BE-HF-64: "{{.*}}ld{{(.exe)?}}"
-// CHECK-BE-HF-64: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc"
-// CHECK-BE-HF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/usr/lib/../lib64{{/|\\\\}}crt1.o"
-// CHECK-BE-HF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/usr/lib/../lib64{{/|\\\\}}crti.o"
-// CHECK-BE-HF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/64{{/|\\\\}}crtbegin.o"
-// CHECK-BE-HF-64: "-L[[TC]]/64"
-// CHECK-BE-HF-64: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib64"
-// CHECK-BE-HF-64: "-L[[TC]]/../../../../mips-linux-gnu/libc/lib/../lib64"
-// CHECK-BE-HF-64: "-L[[TC]]/../../../../mips-linux-gnu/libc/usr/lib/../lib64"
-// CHECK-BE-HF-64-NOT: "-L[[TC]]"
-// CHECK-BE-HF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/64{{/|\\\\}}crtend.o"
-// CHECK-BE-HF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/usr/lib/../lib64{{/|\\\\}}crtn.o"
-//
-// = Big-endian, soft float, 64-bit
-// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     --target=mips64-linux-gnu -msoft-float \
-// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-BE-SF-64 %s
-// CHECK-BE-SF-64: "{{.*}}ld{{(.exe)?}}"
-// CHECK-BE-SF-64: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/soft-float"
-// CHECK-BE-SF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/soft-float/usr/lib/../lib64{{/|\\\\}}crt1.o"
-// CHECK-BE-SF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/soft-float/usr/lib/../lib64{{/|\\\\}}crti.o"
-// CHECK-BE-SF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/soft-float/64{{/|\\\\}}crtbegin.o"
-// CHECK-BE-SF-64: "-L[[TC]]/soft-float/64"
-// CHECK-BE-SF-64: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib64/soft-float"
-// CHECK-BE-SF-64: "-L[[TC]]/../../../../mips-linux-gnu/libc/soft-float/lib/../lib64"
-// CHECK-BE-SF-64: "-L[[TC]]/../../../../mips-linux-gnu/libc/soft-float/usr/lib/../lib64"
-// CHECK-BE-SF-64-NOT: "-L[[TC]]"
-// CHECK-BE-SF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/soft-float/64{{/|\\\\}}crtend.o"
-// CHECK-BE-SF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/soft-float/usr/lib/../lib64{{/|\\\\}}crtn.o"
-//
-// = Little-endian, hard float
-// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     --target=mipsel-linux-gnu -mhard-float \
-// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-EL-HF-32 %s
-// CHECK-EL-HF-32: "{{.*}}ld{{(.exe)?}}"
-// CHECK-EL-HF-32: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/el"
-// CHECK-EL-HF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/el/usr/lib/../lib{{/|\\\\}}crt1.o"
-// CHECK-EL-HF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/el/usr/lib/../lib{{/|\\\\}}crti.o"
-// CHECK-EL-HF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/el{{/|\\\\}}crtbegin.o"
-// CHECK-EL-HF-32: "-L[[TC]]/el"
-// CHECK-EL-HF-32: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/el"
-// CHECK-EL-HF-32-NOT: "-L[[TC]]"
-// CHECK-EL-HF-32: "-L[[TC]]/../../../../mips-linux-gnu/libc/el/lib/../lib"
-// CHECK-EL-HF-32: "-L[[TC]]/../../../../mips-linux-gnu/libc/el/usr/lib/../lib"
-// CHECK-EL-HF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/el{{/|\\\\}}crtend.o"
-// CHECK-EL-HF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/el/usr/lib/../lib{{/|\\\\}}crtn.o"
-//
-// = Little-endian, hard float, mips16
-// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     --target=mipsel-linux-gnu -mips16 \
-// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-EL-HF-16 %s
-// CHECK-EL-HF-16: "{{.*}}ld{{(.exe)?}}"
-// CHECK-EL-HF-16: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/mips16/el"
-// CHECK-EL-HF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/mips16/el/usr/lib/../lib{{/|\\\\}}crt1.o"
-// CHECK-EL-HF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/mips16/el/usr/lib/../lib{{/|\\\\}}crti.o"
-// CHECK-EL-HF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/mips16/el{{/|\\\\}}crtbegin.o"
-// CHECK-EL-HF-16: "-L[[TC]]/mips16/el"
-// CHECK-EL-HF-16: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/mips16/el"
-// CHECK-EL-HF-16-NOT: "-L[[TC]]"
-// CHECK-EL-HF-16: "-L[[TC]]/../../../../mips-linux-gnu/libc/mips16/el/lib/../lib"
-// CHECK-EL-HF-16: "-L[[TC]]/../../../../mips-linux-gnu/libc/mips16/el/usr/lib/../lib"
-// CHECK-EL-HF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/mips16/el{{/|\\\\}}crtend.o"
-// CHECK-EL-HF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/mips16/el/usr/lib/../lib{{/|\\\\}}crtn.o"
-//
-// = Little-endian, hard float, micromips
-// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     --target=mipsel-linux-gnu -mmicromips \
-// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-EL-HF-MICRO %s
-// CHECK-EL-HF-MICRO: "{{.*}}ld{{(.exe)?}}"
-// CHECK-EL-HF-MICRO: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/micromips/el"
-// CHECK-EL-HF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/micromips/el/usr/lib/../lib{{/|\\\\}}crt1.o"
-// CHECK-EL-HF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/micromips/el/usr/lib/../lib{{/|\\\\}}crti.o"
-// CHECK-EL-HF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/micromips/el{{/|\\\\}}crtbegin.o"
-// CHECK-EL-HF-MICRO: "-L[[TC]]/micromips/el"
-// CHECK-EL-HF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/micromips/el"
-// CHECK-EL-HF-MICRO-NOT: "-L[[TC]]"
-// CHECK-EL-HF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/libc/micromips/el/lib/../lib"
-// CHECK-EL-HF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/libc/micromips/el/usr/lib/../lib"
-// CHECK-EL-HF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/micromips/el{{/|\\\\}}crtend.o"
-// CHECK-EL-HF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/micromips/el/usr/lib/../lib{{/|\\\\}}crtn.o"
-//
-// = Little-endian, soft float
-// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     --target=mipsel-linux-gnu -mfloat-abi=soft \
-// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-EL-SF-32 %s
-// CHECK-EL-SF-32: "{{.*}}ld{{(.exe)?}}"
-// CHECK-EL-SF-32: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/soft-float/el"
-// CHECK-EL-SF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/soft-float/el/usr/lib/../lib{{/|\\\\}}crt1.o"
-// CHECK-EL-SF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/soft-float/el/usr/lib/../lib{{/|\\\\}}crti.o"
-// CHECK-EL-SF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el{{/|\\\\}}crtbegin.o"
-// CHECK-EL-SF-32: "-L[[TC]]/soft-float/el"
-// CHECK-EL-SF-32: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/soft-float/el"
-// CHECK-EL-SF-32-NOT: "-L[[TC]]"
-// CHECK-EL-SF-32: "-L[[TC]]/../../../../mips-linux-gnu/libc/soft-float/el/lib/../lib"
-// CHECK-EL-SF-32: "-L[[TC]]/../../../../mips-linux-gnu/libc/soft-float/el/usr/lib/../lib"
-// CHECK-EL-SF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el{{/|\\\\}}crtend.o"
-// CHECK-EL-SF-32: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/soft-float/el/usr/lib/../lib{{/|\\\\}}crtn.o"
-//
-// = Little-endian, soft float, mips16
-// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     --target=mipsel-linux-gnu -mips16 -msoft-float \
-// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-EL-SF-16 %s
-// CHECK-EL-SF-16: "{{.*}}ld{{(.exe)?}}"
-// CHECK-EL-SF-16: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/mips16/soft-float/el"
-// CHECK-EL-SF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/mips16/soft-float/el/usr/lib/../lib{{/|\\\\}}crt1.o"
-// CHECK-EL-SF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/mips16/soft-float/el/usr/lib/../lib{{/|\\\\}}crti.o"
-// CHECK-EL-SF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/el{{/|\\\\}}crtbegin.o"
-// CHECK-EL-SF-16: "-L[[TC]]/mips16/soft-float/el"
-// CHECK-EL-SF-16: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/mips16/soft-float/el"
-// CHECK-EL-SF-16-NOT: "-L[[TC]]"
-// CHECK-EL-SF-16: "-L[[TC]]/../../../../mips-linux-gnu/libc/mips16/soft-float/el/lib/../lib"
-// CHECK-EL-SF-16: "-L[[TC]]/../../../../mips-linux-gnu/libc/mips16/soft-float/el/usr/lib/../lib"
-// CHECK-EL-SF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/mips16/soft-float/el{{/|\\\\}}crtend.o"
-// CHECK-EL-SF-16: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/mips16/soft-float/el/usr/lib/../lib{{/|\\\\}}crtn.o"
-//
-// = Little-endian, soft float, micromips
-// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     --target=mipsel-linux-gnu -mmicromips -msoft-float \
-// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-EL-SF-MICRO %s
-// CHECK-EL-SF-MICRO: "{{.*}}ld{{(.exe)?}}"
-// CHECK-EL-SF-MICRO: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/micromips/soft-float/el"
-// CHECK-EL-SF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/micromips/soft-float/el/usr/lib/../lib{{/|\\\\}}crt1.o"
-// CHECK-EL-SF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/micromips/soft-float/el/usr/lib/../lib{{/|\\\\}}crti.o"
-// CHECK-EL-SF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/el{{/|\\\\}}crtbegin.o"
-// CHECK-EL-SF-MICRO: "-L[[TC]]/micromips/soft-float/el"
-// CHECK-EL-SF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/micromips/soft-float/el"
-// CHECK-EL-SF-MICRO-NOT: "-L[[TC]]"
-// CHECK-EL-SF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/libc/micromips/soft-float/el/lib/../lib"
-// CHECK-EL-SF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/libc/micromips/soft-float/el/usr/lib/../lib"
-// CHECK-EL-SF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/micromips/soft-float/el{{/|\\\\}}crtend.o"
-// CHECK-EL-SF-MICRO: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/micromips/soft-float/el/usr/lib/../lib{{/|\\\\}}crtn.o"
-//
-// = Little-endian, hard float, 64-bit
-// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     --target=mips64el-linux-gnu \
-// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-EL-HF-64 %s
-// CHECK-EL-HF-64: "{{.*}}ld{{(.exe)?}}"
-// CHECK-EL-HF-64: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/el"
-// CHECK-EL-HF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/el/usr/lib/../lib64{{/|\\\\}}crt1.o"
-// CHECK-EL-HF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/el/usr/lib/../lib64{{/|\\\\}}crti.o"
-// CHECK-EL-HF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/el/64{{/|\\\\}}crtbegin.o"
-// CHECK-EL-HF-64: "-L[[TC]]/el/64"
-// CHECK-EL-HF-64: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib64/el"
-// CHECK-EL-HF-64: "-L[[TC]]/../../../../mips-linux-gnu/libc/el/lib/../lib64"
-// CHECK-EL-HF-64: "-L[[TC]]/../../../../mips-linux-gnu/libc/el/usr/lib/../lib64"
-// CHECK-EL-HF-64-NOT: "-L[[TC]]"
-// CHECK-EL-HF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/el/64{{/|\\\\}}crtend.o"
-// CHECK-EL-HF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/el/usr/lib/../lib64{{/|\\\\}}crtn.o"
-//
-// = Little-endian, soft float, 64-bit
-// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
-// RUN:     --target=mips64el-linux-gnu -msoft-float \
-// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
-// RUN:   | FileCheck --check-prefix=CHECK-EL-SF-64 %s
-// CHECK-EL-SF-64: "{{.*}}ld{{(.exe)?}}"
-// CHECK-EL-SF-64: "--sysroot=[[TC:[^"]+]]/../../../../mips-linux-gnu/libc/soft-float/el"
-// CHECK-EL-SF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/soft-float/el/usr/lib/../lib64{{/|\\\\}}crt1.o"
-// CHECK-EL-SF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/soft-float/el/usr/lib/../lib64{{/|\\\\}}crti.o"
-// CHECK-EL-SF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/64{{/|\\\\}}crtbegin.o"
-// CHECK-EL-SF-64: "-L[[TC]]/soft-float/el/64"
-// CHECK-EL-SF-64: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib64/soft-float/el"
-// CHECK-EL-SF-64: "-L[[TC]]/../../../../mips-linux-gnu/libc/soft-float/el/lib/../lib64"
-// CHECK-EL-SF-64: "-L[[TC]]/../../../../mips-linux-gnu/libc/soft-float/el/usr/lib/../lib64"
-// CHECK-EL-SF-64-NOT: "-L[[TC]]"
-// CHECK-EL-SF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/soft-float/el/64{{/|\\\\}}crtend.o"
-// CHECK-EL-SF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/../../../../mips-linux-gnu/libc/soft-float/el/usr/lib/../lib64{{/|\\\\}}crtn.o"
diff --git a/test/Driver/mips-cs.cpp b/test/Driver/mips-cs.cpp
new file mode 100644
index 0000000..275d615
--- /dev/null
+++ b/test/Driver/mips-cs.cpp
@@ -0,0 +1,504 @@
+// Check frontend and linker invocations on Mentor Graphics MIPS toolchain.
+//
+// = Big-endian, hard float
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips-linux-gnu \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BE-HF-32 %s
+// CHECK-BE-HF-32: "-internal-isystem"
+// CHECK-BE-HF-32: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
+// CHECK-BE-HF-32: "-internal-isystem"
+// CHECK-BE-HF-32: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu"
+// CHECK-BE-HF-32: "-internal-isystem"
+// CHECK-BE-HF-32: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
+// CHECK-BE-HF-32: "-internal-externc-isystem"
+// CHECK-BE-HF-32: "[[TC]]/include"
+// CHECK-BE-HF-32: "-internal-externc-isystem"
+// CHECK-BE-HF-32: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
+// CHECK-BE-HF-32: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-HF-32: "--sysroot=[[TC]]/../../../../mips-linux-gnu/libc"
+// CHECK-BE-HF-32: "[[TC]]/../../../../mips-linux-gnu/libc/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-BE-HF-32: "[[TC]]/../../../../mips-linux-gnu/libc/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-BE-HF-32: "[[TC]]{{/|\\\\}}crtbegin.o"
+// CHECK-BE-HF-32: "-L[[TC]]"
+// CHECK-BE-HF-32: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib"
+// CHECK-BE-HF-32: "-L[[TC]]/../../../../mips-linux-gnu/libc/lib"
+// CHECK-BE-HF-32: "-L[[TC]]/../../../../mips-linux-gnu/libc/usr/lib"
+// CHECK-BE-HF-32: "[[TC]]{{/|\\\\}}crtend.o"
+// CHECK-BE-HF-32: "[[TC]]/../../../../mips-linux-gnu/libc/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
+// = Big-endian, hard float, mips16
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips-linux-gnu -mips16 \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BE-HF-16 %s
+// CHECK-BE-HF-16: "-internal-isystem"
+// CHECK-BE-HF-16: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
+// CHECK-BE-HF-16: "-internal-isystem"
+// CHECK-BE-HF-16: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/mips16"
+// CHECK-BE-HF-16: "-internal-isystem"
+// CHECK-BE-HF-16: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
+// CHECK-BE-HF-16: "-internal-externc-isystem"
+// CHECK-BE-HF-16: "[[TC]]/include"
+// CHECK-BE-HF-16: "-internal-externc-isystem"
+// CHECK-BE-HF-16: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
+// CHECK-BE-HF-16: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-HF-16: "--sysroot=[[TC]]/../../../../mips-linux-gnu/libc/mips16"
+// CHECK-BE-HF-16: "[[TC]]/../../../../mips-linux-gnu/libc/mips16/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-BE-HF-16: "[[TC]]/../../../../mips-linux-gnu/libc/mips16/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-BE-HF-16: "[[TC]]/mips16{{/|\\\\}}crtbegin.o"
+// CHECK-BE-HF-16: "-L[[TC]]/mips16"
+// CHECK-BE-HF-16: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/mips16"
+// CHECK-BE-HF-16-NOT: "-L[[TC]]"
+// CHECK-BE-HF-16: "-L[[TC]]/../../../../mips-linux-gnu/libc/mips16/lib/../lib"
+// CHECK-BE-HF-16: "-L[[TC]]/../../../../mips-linux-gnu/libc/mips16/usr/lib/../lib"
+// CHECK-BE-HF-16: "[[TC]]/mips16{{/|\\\\}}crtend.o"
+// CHECK-BE-HF-16: "[[TC]]/../../../../mips-linux-gnu/libc/mips16/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
+// = Big-endian, hard float, mmicromips
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips-linux-gnu -mmicromips \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BE-HF-MICRO %s
+// CHECK-BE-HF-MICRO: "-internal-isystem"
+// CHECK-BE-HF-MICRO: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
+// CHECK-BE-HF-MICRO: "-internal-isystem"
+// CHECK-BE-HF-MICRO: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/micromips"
+// CHECK-BE-HF-MICRO: "-internal-isystem"
+// CHECK-BE-HF-MICRO: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
+// CHECK-BE-HF-MICRO: "-internal-externc-isystem"
+// CHECK-BE-HF-MICRO: "[[TC]]/include"
+// CHECK-BE-HF-MICRO: "-internal-externc-isystem"
+// CHECK-BE-HF-MICRO: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
+// CHECK-BE-HF-MICRO: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-HF-MICRO: "--sysroot=[[TC]]/../../../../mips-linux-gnu/libc/micromips"
+// CHECK-BE-HF-MICRO: "[[TC]]/../../../../mips-linux-gnu/libc/micromips/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-BE-HF-MICRO: "[[TC]]/../../../../mips-linux-gnu/libc/micromips/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-BE-HF-MICRO: "[[TC]]/micromips{{/|\\\\}}crtbegin.o"
+// CHECK-BE-HF-MICRO: "-L[[TC]]/micromips"
+// CHECK-BE-HF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/micromips"
+// CHECK-BE-HF-MICRO-NOT: "-L[[TC]]"
+// CHECK-BE-HF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/libc/micromips/lib/../lib"
+// CHECK-BE-HF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/libc/micromips/usr/lib/../lib"
+// CHECK-BE-HF-MICRO: "[[TC]]/micromips{{/|\\\\}}crtend.o"
+// CHECK-BE-HF-MICRO: "[[TC]]/../../../../mips-linux-gnu/libc/micromips/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
+// = Big-endian, hard float, nan2008
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips-linux-gnu -mnan=2008 \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BE-HF-NAN %s
+// CHECK-BE-HF-NAN: "-internal-isystem"
+// CHECK-BE-HF-NAN: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
+// CHECK-BE-HF-NAN: "-internal-isystem"
+// CHECK-BE-HF-NAN: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/nan2008"
+// CHECK-BE-HF-NAN: "-internal-isystem"
+// CHECK-BE-HF-NAN: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
+// CHECK-BE-HF-NAN: "-internal-externc-isystem"
+// CHECK-BE-HF-NAN: "[[TC]]/include"
+// CHECK-BE-HF-NAN: "-internal-externc-isystem"
+// CHECK-BE-HF-NAN: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
+// CHECK-BE-HF-NAN: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-HF-NAN: "--sysroot=[[TC]]/../../../../mips-linux-gnu/libc/nan2008"
+// CHECK-BE-HF-NAN: "[[TC]]/../../../../mips-linux-gnu/libc/nan2008/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-BE-HF-NAN: "[[TC]]/../../../../mips-linux-gnu/libc/nan2008/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-BE-HF-NAN: "[[TC]]/nan2008{{/|\\\\}}crtbegin.o"
+// CHECK-BE-HF-NAN: "-L[[TC]]/nan2008"
+// CHECK-BE-HF-NAN: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/nan2008"
+// CHECK-BE-HF-NAN-NOT: "-L[[TC]]"
+// CHECK-BE-HF-NAN: "-L[[TC]]/../../../../mips-linux-gnu/libc/nan2008/lib/../lib"
+// CHECK-BE-HF-NAN: "-L[[TC]]/../../../../mips-linux-gnu/libc/nan2008/usr/lib/../lib"
+// CHECK-BE-HF-NAN: "[[TC]]/nan2008{{/|\\\\}}crtend.o"
+// CHECK-BE-HF-NAN: "[[TC]]/../../../../mips-linux-gnu/libc/nan2008/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
+// = Big-endian, soft float
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips-linux-gnu -msoft-float \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BE-SF-32 %s
+// CHECK-BE-SF-32: "-internal-isystem"
+// CHECK-BE-SF-32: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
+// CHECK-BE-SF-32: "-internal-isystem"
+// CHECK-BE-SF-32: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/soft-float"
+// CHECK-BE-SF-32: "-internal-isystem"
+// CHECK-BE-SF-32: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
+// CHECK-BE-SF-32: "-internal-externc-isystem"
+// CHECK-BE-SF-32: "[[TC]]/include"
+// CHECK-BE-SF-32: "-internal-externc-isystem"
+// CHECK-BE-SF-32: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
+// CHECK-BE-SF-32: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-SF-32: "--sysroot=[[TC]]/../../../../mips-linux-gnu/libc/soft-float"
+// CHECK-BE-SF-32: "[[TC]]/../../../../mips-linux-gnu/libc/soft-float/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-BE-SF-32: "[[TC]]/../../../../mips-linux-gnu/libc/soft-float/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-BE-SF-32: "[[TC]]/soft-float{{/|\\\\}}crtbegin.o"
+// CHECK-BE-SF-32: "-L[[TC]]/soft-float"
+// CHECK-BE-SF-32: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/soft-float"
+// CHECK-BE-SF-32-NOT: "-L[[TC]]"
+// CHECK-BE-SF-32: "-L[[TC]]/../../../../mips-linux-gnu/libc/soft-float/lib/../lib"
+// CHECK-BE-SF-32: "-L[[TC]]/../../../../mips-linux-gnu/libc/soft-float/usr/lib/../lib"
+// CHECK-BE-SF-32: "[[TC]]/soft-float{{/|\\\\}}crtend.o"
+// CHECK-BE-SF-32: "[[TC]]/../../../../mips-linux-gnu/libc/soft-float/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
+// = Big-endian, soft float, mips16
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips-linux-gnu -msoft-float -mips16 \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BE-SF-16 %s
+// CHECK-BE-SF-16: "-internal-isystem"
+// CHECK-BE-SF-16: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
+// CHECK-BE-SF-16: "-internal-isystem"
+// CHECK-BE-SF-16: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/mips16/soft-float"
+// CHECK-BE-SF-16: "-internal-isystem"
+// CHECK-BE-SF-16: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
+// CHECK-BE-SF-16: "-internal-externc-isystem"
+// CHECK-BE-SF-16: "[[TC]]/include"
+// CHECK-BE-SF-16: "-internal-externc-isystem"
+// CHECK-BE-SF-16: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
+// CHECK-BE-SF-16: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-SF-16: "--sysroot=[[TC]]/../../../../mips-linux-gnu/libc/mips16/soft-float"
+// CHECK-BE-SF-16: "[[TC]]/../../../../mips-linux-gnu/libc/mips16/soft-float/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-BE-SF-16: "[[TC]]/../../../../mips-linux-gnu/libc/mips16/soft-float/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-BE-SF-16: "[[TC]]/mips16/soft-float{{/|\\\\}}crtbegin.o"
+// CHECK-BE-SF-16: "-L[[TC]]/mips16/soft-float"
+// CHECK-BE-SF-16: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/mips16/soft-float"
+// CHECK-BE-SF-16-NOT: "-L[[TC]]"
+// CHECK-BE-SF-16: "-L[[TC]]/../../../../mips-linux-gnu/libc/mips16/soft-float/lib/../lib"
+// CHECK-BE-SF-16: "-L[[TC]]/../../../../mips-linux-gnu/libc/mips16/soft-float/usr/lib/../lib"
+// CHECK-BE-SF-16: "[[TC]]/mips16/soft-float{{/|\\\\}}crtend.o"
+// CHECK-BE-SF-16: "[[TC]]/../../../../mips-linux-gnu/libc/mips16/soft-float/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
+// = Big-endian, soft float, micromips
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips-linux-gnu -msoft-float -mmicromips \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BE-SF-MICRO %s
+// CHECK-BE-SF-MICRO: "-internal-isystem"
+// CHECK-BE-SF-MICRO: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
+// CHECK-BE-SF-MICRO: "-internal-isystem"
+// CHECK-BE-SF-MICRO: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/micromips/soft-float"
+// CHECK-BE-SF-MICRO: "-internal-isystem"
+// CHECK-BE-SF-MICRO: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
+// CHECK-BE-SF-MICRO: "-internal-externc-isystem"
+// CHECK-BE-SF-MICRO: "[[TC]]/include"
+// CHECK-BE-SF-MICRO: "-internal-externc-isystem"
+// CHECK-BE-SF-MICRO: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
+// CHECK-BE-SF-MICRO: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-SF-MICRO: "--sysroot=[[TC]]/../../../../mips-linux-gnu/libc/micromips/soft-float"
+// CHECK-BE-SF-MICRO: "[[TC]]/../../../../mips-linux-gnu/libc/micromips/soft-float/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-BE-SF-MICRO: "[[TC]]/../../../../mips-linux-gnu/libc/micromips/soft-float/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-BE-SF-MICRO: "[[TC]]/micromips/soft-float{{/|\\\\}}crtbegin.o"
+// CHECK-BE-SF-MICRO: "-L[[TC]]/micromips/soft-float"
+// CHECK-BE-SF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/micromips/soft-float"
+// CHECK-BE-SF-MICRO-NOT: "-L[[TC]]"
+// CHECK-BE-SF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/libc/micromips/soft-float/lib/../lib"
+// CHECK-BE-SF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/libc/micromips/soft-float/usr/lib/../lib"
+// CHECK-BE-SF-MICRO: "[[TC]]/micromips/soft-float{{/|\\\\}}crtend.o"
+// CHECK-BE-SF-MICRO: "[[TC]]/../../../../mips-linux-gnu/libc/micromips/soft-float/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
+// = Big-endian, hard float, 64-bit
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64-linux-gnu \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BE-HF-64 %s
+// CHECK-BE-HF-64: "-internal-isystem"
+// CHECK-BE-HF-64: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
+// CHECK-BE-HF-64: "-internal-isystem"
+// CHECK-BE-HF-64: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/64"
+// CHECK-BE-HF-64: "-internal-isystem"
+// CHECK-BE-HF-64: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
+// CHECK-BE-HF-64: "-internal-externc-isystem"
+// CHECK-BE-HF-64: "[[TC]]/include"
+// CHECK-BE-HF-64: "-internal-externc-isystem"
+// CHECK-BE-HF-64: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
+// CHECK-BE-HF-64: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-HF-64: "--sysroot=[[TC]]/../../../../mips-linux-gnu/libc"
+// CHECK-BE-HF-64: "[[TC]]/../../../../mips-linux-gnu/libc/usr/lib/../lib64{{/|\\\\}}crt1.o"
+// CHECK-BE-HF-64: "[[TC]]/../../../../mips-linux-gnu/libc/usr/lib/../lib64{{/|\\\\}}crti.o"
+// CHECK-BE-HF-64: "[[TC]]/64{{/|\\\\}}crtbegin.o"
+// CHECK-BE-HF-64: "-L[[TC]]/64"
+// CHECK-BE-HF-64: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib64"
+// CHECK-BE-HF-64: "-L[[TC]]/../../../../mips-linux-gnu/libc/lib/../lib64"
+// CHECK-BE-HF-64: "-L[[TC]]/../../../../mips-linux-gnu/libc/usr/lib/../lib64"
+// CHECK-BE-HF-64-NOT: "-L[[TC]]"
+// CHECK-BE-HF-64: "{{.*}}/lib/gcc/mips-linux-gnu/4.6.3/64{{/|\\\\}}crtend.o"
+// CHECK-BE-HF-64: "[[TC]]/../../../../mips-linux-gnu/libc/usr/lib/../lib64{{/|\\\\}}crtn.o"
+//
+// = Big-endian, soft float, 64-bit
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64-linux-gnu -msoft-float \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BE-SF-64 %s
+// CHECK-BE-SF-64: "-internal-isystem"
+// CHECK-BE-SF-64: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
+// CHECK-BE-SF-64: "-internal-isystem"
+// CHECK-BE-SF-64: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/soft-float/64"
+// CHECK-BE-SF-64: "-internal-isystem"
+// CHECK-BE-SF-64: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
+// CHECK-BE-SF-64: "-internal-externc-isystem"
+// CHECK-BE-SF-64: "[[TC]]/include"
+// CHECK-BE-SF-64: "-internal-externc-isystem"
+// CHECK-BE-SF-64: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
+// CHECK-BE-SF-64: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-SF-64: "--sysroot=[[TC]]/../../../../mips-linux-gnu/libc/soft-float"
+// CHECK-BE-SF-64: "[[TC]]/../../../../mips-linux-gnu/libc/soft-float/usr/lib/../lib64{{/|\\\\}}crt1.o"
+// CHECK-BE-SF-64: "[[TC]]/../../../../mips-linux-gnu/libc/soft-float/usr/lib/../lib64{{/|\\\\}}crti.o"
+// CHECK-BE-SF-64: "[[TC]]/soft-float/64{{/|\\\\}}crtbegin.o"
+// CHECK-BE-SF-64: "-L[[TC]]/soft-float/64"
+// CHECK-BE-SF-64: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib64/soft-float"
+// CHECK-BE-SF-64: "-L[[TC]]/../../../../mips-linux-gnu/libc/soft-float/lib/../lib64"
+// CHECK-BE-SF-64: "-L[[TC]]/../../../../mips-linux-gnu/libc/soft-float/usr/lib/../lib64"
+// CHECK-BE-SF-64-NOT: "-L[[TC]]"
+// CHECK-BE-SF-64: "[[TC]]/soft-float/64{{/|\\\\}}crtend.o"
+// CHECK-BE-SF-64: "[[TC]]/../../../../mips-linux-gnu/libc/soft-float/usr/lib/../lib64{{/|\\\\}}crtn.o"
+//
+// = Little-endian, hard float
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mipsel-linux-gnu -mhard-float \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-EL-HF-32 %s
+// CHECK-EL-HF-32: "-internal-isystem"
+// CHECK-EL-HF-32: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
+// CHECK-EL-HF-32: "-internal-isystem"
+// CHECK-EL-HF-32: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/el"
+// CHECK-EL-HF-32: "-internal-isystem"
+// CHECK-EL-HF-32: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
+// CHECK-EL-HF-32: "-internal-externc-isystem"
+// CHECK-EL-HF-32: "[[TC]]/include"
+// CHECK-EL-HF-32: "-internal-externc-isystem"
+// CHECK-EL-HF-32: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
+// CHECK-EL-HF-32: "{{.*}}ld{{(.exe)?}}"
+// CHECK-EL-HF-32: "--sysroot=[[TC]]/../../../../mips-linux-gnu/libc/el"
+// CHECK-EL-HF-32: "[[TC]]/../../../../mips-linux-gnu/libc/el/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-EL-HF-32: "[[TC]]/../../../../mips-linux-gnu/libc/el/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-EL-HF-32: "[[TC]]/el{{/|\\\\}}crtbegin.o"
+// CHECK-EL-HF-32: "-L[[TC]]/el"
+// CHECK-EL-HF-32: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/el"
+// CHECK-EL-HF-32-NOT: "-L[[TC]]"
+// CHECK-EL-HF-32: "-L[[TC]]/../../../../mips-linux-gnu/libc/el/lib/../lib"
+// CHECK-EL-HF-32: "-L[[TC]]/../../../../mips-linux-gnu/libc/el/usr/lib/../lib"
+// CHECK-EL-HF-32: "[[TC]]/el{{/|\\\\}}crtend.o"
+// CHECK-EL-HF-32: "[[TC]]/../../../../mips-linux-gnu/libc/el/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
+// = Little-endian, hard float, mips16
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mipsel-linux-gnu -mips16 \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-EL-HF-16 %s
+// CHECK-EL-HF-16: "-internal-isystem"
+// CHECK-EL-HF-16: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
+// CHECK-EL-HF-16: "-internal-isystem"
+// CHECK-EL-HF-16: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/mips16/el"
+// CHECK-EL-HF-16: "-internal-isystem"
+// CHECK-EL-HF-16: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
+// CHECK-EL-HF-16: "-internal-externc-isystem"
+// CHECK-EL-HF-16: "[[TC]]/include"
+// CHECK-EL-HF-16: "-internal-externc-isystem"
+// CHECK-EL-HF-16: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
+// CHECK-EL-HF-16: "{{.*}}ld{{(.exe)?}}"
+// CHECK-EL-HF-16: "--sysroot=[[TC]]/../../../../mips-linux-gnu/libc/mips16/el"
+// CHECK-EL-HF-16: "[[TC]]/../../../../mips-linux-gnu/libc/mips16/el/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-EL-HF-16: "[[TC]]/../../../../mips-linux-gnu/libc/mips16/el/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-EL-HF-16: "[[TC]]/mips16/el{{/|\\\\}}crtbegin.o"
+// CHECK-EL-HF-16: "-L[[TC]]/mips16/el"
+// CHECK-EL-HF-16: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/mips16/el"
+// CHECK-EL-HF-16-NOT: "-L[[TC]]"
+// CHECK-EL-HF-16: "-L[[TC]]/../../../../mips-linux-gnu/libc/mips16/el/lib/../lib"
+// CHECK-EL-HF-16: "-L[[TC]]/../../../../mips-linux-gnu/libc/mips16/el/usr/lib/../lib"
+// CHECK-EL-HF-16: "[[TC]]/mips16/el{{/|\\\\}}crtend.o"
+// CHECK-EL-HF-16: "[[TC]]/../../../../mips-linux-gnu/libc/mips16/el/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
+// = Little-endian, hard float, micromips
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mipsel-linux-gnu -mmicromips \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-EL-HF-MICRO %s
+// CHECK-EL-HF-MICRO: "-internal-isystem"
+// CHECK-EL-HF-MICRO: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
+// CHECK-EL-HF-MICRO: "-internal-isystem"
+// CHECK-EL-HF-MICRO: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/micromips/el"
+// CHECK-EL-HF-MICRO: "-internal-isystem"
+// CHECK-EL-HF-MICRO: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
+// CHECK-EL-HF-MICRO: "-internal-externc-isystem"
+// CHECK-EL-HF-MICRO: "[[TC]]/include"
+// CHECK-EL-HF-MICRO: "-internal-externc-isystem"
+// CHECK-EL-HF-MICRO: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
+// CHECK-EL-HF-MICRO: "{{.*}}ld{{(.exe)?}}"
+// CHECK-EL-HF-MICRO: "--sysroot=[[TC]]/../../../../mips-linux-gnu/libc/micromips/el"
+// CHECK-EL-HF-MICRO: "[[TC]]/../../../../mips-linux-gnu/libc/micromips/el/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-EL-HF-MICRO: "[[TC]]/../../../../mips-linux-gnu/libc/micromips/el/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-EL-HF-MICRO: "[[TC]]/micromips/el{{/|\\\\}}crtbegin.o"
+// CHECK-EL-HF-MICRO: "-L[[TC]]/micromips/el"
+// CHECK-EL-HF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/micromips/el"
+// CHECK-EL-HF-MICRO-NOT: "-L[[TC]]"
+// CHECK-EL-HF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/libc/micromips/el/lib/../lib"
+// CHECK-EL-HF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/libc/micromips/el/usr/lib/../lib"
+// CHECK-EL-HF-MICRO: "[[TC]]/micromips/el{{/|\\\\}}crtend.o"
+// CHECK-EL-HF-MICRO: "[[TC]]/../../../../mips-linux-gnu/libc/micromips/el/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
+// = Little-endian, hard float, nan2008
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mipsel-linux-gnu -mnan=2008 \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-EL-HF-NAN %s
+// CHECK-EL-HF-NAN: "-internal-isystem"
+// CHECK-EL-HF-NAN: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
+// CHECK-EL-HF-NAN: "-internal-isystem"
+// CHECK-EL-HF-NAN: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/nan2008/el"
+// CHECK-EL-HF-NAN: "-internal-isystem"
+// CHECK-EL-HF-NAN: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
+// CHECK-EL-HF-NAN: "-internal-externc-isystem"
+// CHECK-EL-HF-NAN: "[[TC]]/include"
+// CHECK-EL-HF-NAN: "-internal-externc-isystem"
+// CHECK-EL-HF-NAN: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
+// CHECK-EL-HF-NAN: "{{.*}}ld{{(.exe)?}}"
+// CHECK-EL-HF-NAN: "--sysroot=[[TC]]/../../../../mips-linux-gnu/libc/nan2008/el"
+// CHECK-EL-HF-NAN: "[[TC]]/../../../../mips-linux-gnu/libc/nan2008/el/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-EL-HF-NAN: "[[TC]]/../../../../mips-linux-gnu/libc/nan2008/el/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-EL-HF-NAN: "[[TC]]/nan2008/el{{/|\\\\}}crtbegin.o"
+// CHECK-EL-HF-NAN: "-L[[TC]]/nan2008/el"
+// CHECK-EL-HF-NAN: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/nan2008/el"
+// CHECK-EL-HF-NAN-NOT: "-L[[TC]]"
+// CHECK-EL-HF-NAN: "-L[[TC]]/../../../../mips-linux-gnu/libc/nan2008/el/lib/../lib"
+// CHECK-EL-HF-NAN: "-L[[TC]]/../../../../mips-linux-gnu/libc/nan2008/el/usr/lib/../lib"
+// CHECK-EL-HF-NAN: "[[TC]]/nan2008/el{{/|\\\\}}crtend.o"
+// CHECK-EL-HF-NAN: "[[TC]]/../../../../mips-linux-gnu/libc/nan2008/el/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
+// = Little-endian, soft float
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mipsel-linux-gnu -mfloat-abi=soft \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-EL-SF-32 %s
+// CHECK-EL-SF-32: "-internal-isystem"
+// CHECK-EL-SF-32: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
+// CHECK-EL-SF-32: "-internal-isystem"
+// CHECK-EL-SF-32: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/soft-float/el"
+// CHECK-EL-SF-32: "-internal-isystem"
+// CHECK-EL-SF-32: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
+// CHECK-EL-SF-32: "-internal-externc-isystem"
+// CHECK-EL-SF-32: "[[TC]]/include"
+// CHECK-EL-SF-32: "-internal-externc-isystem"
+// CHECK-EL-SF-32: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
+// CHECK-EL-SF-32: "{{.*}}ld{{(.exe)?}}"
+// CHECK-EL-SF-32: "--sysroot=[[TC]]/../../../../mips-linux-gnu/libc/soft-float/el"
+// CHECK-EL-SF-32: "[[TC]]/../../../../mips-linux-gnu/libc/soft-float/el/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-EL-SF-32: "[[TC]]/../../../../mips-linux-gnu/libc/soft-float/el/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-EL-SF-32: "[[TC]]/soft-float/el{{/|\\\\}}crtbegin.o"
+// CHECK-EL-SF-32: "-L[[TC]]/soft-float/el"
+// CHECK-EL-SF-32: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/soft-float/el"
+// CHECK-EL-SF-32-NOT: "-L[[TC]]"
+// CHECK-EL-SF-32: "-L[[TC]]/../../../../mips-linux-gnu/libc/soft-float/el/lib/../lib"
+// CHECK-EL-SF-32: "-L[[TC]]/../../../../mips-linux-gnu/libc/soft-float/el/usr/lib/../lib"
+// CHECK-EL-SF-32: "[[TC]]/soft-float/el{{/|\\\\}}crtend.o"
+// CHECK-EL-SF-32: "[[TC]]/../../../../mips-linux-gnu/libc/soft-float/el/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
+// = Little-endian, soft float, mips16
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mipsel-linux-gnu -mips16 -msoft-float \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-EL-SF-16 %s
+// CHECK-EL-SF-16: "-internal-isystem"
+// CHECK-EL-SF-16: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
+// CHECK-EL-SF-16: "-internal-isystem"
+// CHECK-EL-SF-16: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/mips16/soft-float/el"
+// CHECK-EL-SF-16: "-internal-isystem"
+// CHECK-EL-SF-16: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
+// CHECK-EL-SF-16: "-internal-externc-isystem"
+// CHECK-EL-SF-16: "[[TC]]/include"
+// CHECK-EL-SF-16: "-internal-externc-isystem"
+// CHECK-EL-SF-16: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
+// CHECK-EL-SF-16: "{{.*}}ld{{(.exe)?}}"
+// CHECK-EL-SF-16: "--sysroot=[[TC]]/../../../../mips-linux-gnu/libc/mips16/soft-float/el"
+// CHECK-EL-SF-16: "[[TC]]/../../../../mips-linux-gnu/libc/mips16/soft-float/el/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-EL-SF-16: "[[TC]]/../../../../mips-linux-gnu/libc/mips16/soft-float/el/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-EL-SF-16: "[[TC]]/mips16/soft-float/el{{/|\\\\}}crtbegin.o"
+// CHECK-EL-SF-16: "-L[[TC]]/mips16/soft-float/el"
+// CHECK-EL-SF-16: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/mips16/soft-float/el"
+// CHECK-EL-SF-16-NOT: "-L[[TC]]"
+// CHECK-EL-SF-16: "-L[[TC]]/../../../../mips-linux-gnu/libc/mips16/soft-float/el/lib/../lib"
+// CHECK-EL-SF-16: "-L[[TC]]/../../../../mips-linux-gnu/libc/mips16/soft-float/el/usr/lib/../lib"
+// CHECK-EL-SF-16: "[[TC]]/mips16/soft-float/el{{/|\\\\}}crtend.o"
+// CHECK-EL-SF-16: "[[TC]]/../../../../mips-linux-gnu/libc/mips16/soft-float/el/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
+// = Little-endian, soft float, micromips
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mipsel-linux-gnu -mmicromips -msoft-float \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-EL-SF-MICRO %s
+// CHECK-EL-SF-MICRO: "-internal-isystem"
+// CHECK-EL-SF-MICRO: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
+// CHECK-EL-SF-MICRO: "-internal-isystem"
+// CHECK-EL-SF-MICRO: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/micromips/soft-float/el"
+// CHECK-EL-SF-MICRO: "-internal-isystem"
+// CHECK-EL-SF-MICRO: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
+// CHECK-EL-SF-MICRO: "-internal-externc-isystem"
+// CHECK-EL-SF-MICRO: "[[TC]]/include"
+// CHECK-EL-SF-MICRO: "-internal-externc-isystem"
+// CHECK-EL-SF-MICRO: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
+// CHECK-EL-SF-MICRO: "{{.*}}ld{{(.exe)?}}"
+// CHECK-EL-SF-MICRO: "--sysroot=[[TC]]/../../../../mips-linux-gnu/libc/micromips/soft-float/el"
+// CHECK-EL-SF-MICRO: "[[TC]]/../../../../mips-linux-gnu/libc/micromips/soft-float/el/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-EL-SF-MICRO: "[[TC]]/../../../../mips-linux-gnu/libc/micromips/soft-float/el/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-EL-SF-MICRO: "[[TC]]/micromips/soft-float/el{{/|\\\\}}crtbegin.o"
+// CHECK-EL-SF-MICRO: "-L[[TC]]/micromips/soft-float/el"
+// CHECK-EL-SF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib/micromips/soft-float/el"
+// CHECK-EL-SF-MICRO-NOT: "-L[[TC]]"
+// CHECK-EL-SF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/libc/micromips/soft-float/el/lib/../lib"
+// CHECK-EL-SF-MICRO: "-L[[TC]]/../../../../mips-linux-gnu/libc/micromips/soft-float/el/usr/lib/../lib"
+// CHECK-EL-SF-MICRO: "[[TC]]/micromips/soft-float/el{{/|\\\\}}crtend.o"
+// CHECK-EL-SF-MICRO: "[[TC]]/../../../../mips-linux-gnu/libc/micromips/soft-float/el/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
+// = Little-endian, hard float, 64-bit
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64el-linux-gnu \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-EL-HF-64 %s
+// CHECK-EL-HF-64: "-internal-isystem"
+// CHECK-EL-HF-64: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
+// CHECK-EL-HF-64: "-internal-isystem"
+// CHECK-EL-HF-64: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/el/64"
+// CHECK-EL-HF-64: "-internal-isystem"
+// CHECK-EL-HF-64: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
+// CHECK-EL-HF-64: "-internal-externc-isystem"
+// CHECK-EL-HF-64: "[[TC]]/include"
+// CHECK-EL-HF-64: "-internal-externc-isystem"
+// CHECK-EL-HF-64: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
+// CHECK-EL-HF-64: "{{.*}}ld{{(.exe)?}}"
+// CHECK-EL-HF-64: "--sysroot=[[TC]]/../../../../mips-linux-gnu/libc/el"
+// CHECK-EL-HF-64: "[[TC]]/../../../../mips-linux-gnu/libc/el/usr/lib/../lib64{{/|\\\\}}crt1.o"
+// CHECK-EL-HF-64: "[[TC]]/../../../../mips-linux-gnu/libc/el/usr/lib/../lib64{{/|\\\\}}crti.o"
+// CHECK-EL-HF-64: "[[TC]]/el/64{{/|\\\\}}crtbegin.o"
+// CHECK-EL-HF-64: "-L[[TC]]/el/64"
+// CHECK-EL-HF-64: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib64/el"
+// CHECK-EL-HF-64: "-L[[TC]]/../../../../mips-linux-gnu/libc/el/lib/../lib64"
+// CHECK-EL-HF-64: "-L[[TC]]/../../../../mips-linux-gnu/libc/el/usr/lib/../lib64"
+// CHECK-EL-HF-64-NOT: "-L[[TC]]"
+// CHECK-EL-HF-64: "[[TC]]/el/64{{/|\\\\}}crtend.o"
+// CHECK-EL-HF-64: "[[TC]]/../../../../mips-linux-gnu/libc/el/usr/lib/../lib64{{/|\\\\}}crtn.o"
+//
+// = Little-endian, soft float, 64-bit
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64el-linux-gnu -msoft-float \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_cs_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-EL-SF-64 %s
+// CHECK-EL-SF-64: "-internal-isystem"
+// CHECK-EL-SF-64: "[[TC:[^"]+/lib/gcc/mips-linux-gnu/4.6.3]]/../../../../mips-linux-gnu/include/c++/4.6.3"
+// CHECK-EL-SF-64: "-internal-isystem"
+// CHECK-EL-SF-64: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/mips-linux-gnu/soft-float/el/64"
+// CHECK-EL-SF-64: "-internal-isystem"
+// CHECK-EL-SF-64: "[[TC]]/../../../../mips-linux-gnu/include/c++/4.6.3/backward"
+// CHECK-EL-SF-64: "-internal-externc-isystem"
+// CHECK-EL-SF-64: "[[TC]]/include"
+// CHECK-EL-SF-64: "-internal-externc-isystem"
+// CHECK-EL-SF-64: "[[TC]]/../../../../mips-linux-gnu/libc/usr/include"
+// CHECK-EL-SF-64: "{{.*}}ld{{(.exe)?}}"
+// CHECK-EL-SF-64: "--sysroot=[[TC]]/../../../../mips-linux-gnu/libc/soft-float/el"
+// CHECK-EL-SF-64: "[[TC]]/../../../../mips-linux-gnu/libc/soft-float/el/usr/lib/../lib64{{/|\\\\}}crt1.o"
+// CHECK-EL-SF-64: "[[TC]]/../../../../mips-linux-gnu/libc/soft-float/el/usr/lib/../lib64{{/|\\\\}}crti.o"
+// CHECK-EL-SF-64: "[[TC]]/soft-float/el/64{{/|\\\\}}crtbegin.o"
+// CHECK-EL-SF-64: "-L[[TC]]/soft-float/el/64"
+// CHECK-EL-SF-64: "-L[[TC]]/../../../../mips-linux-gnu/lib/../lib64/soft-float/el"
+// CHECK-EL-SF-64: "-L[[TC]]/../../../../mips-linux-gnu/libc/soft-float/el/lib/../lib64"
+// CHECK-EL-SF-64: "-L[[TC]]/../../../../mips-linux-gnu/libc/soft-float/el/usr/lib/../lib64"
+// CHECK-EL-SF-64-NOT: "-L[[TC]]"
+// CHECK-EL-SF-64: "[[TC]]/soft-float/el/64{{/|\\\\}}crtend.o"
+// CHECK-EL-SF-64: "[[TC]]/../../../../mips-linux-gnu/libc/soft-float/el/usr/lib/../lib64{{/|\\\\}}crtn.o"
diff --git a/test/Driver/mips-eleb.c b/test/Driver/mips-eleb.c
index 6ea49be..aaa80e0 100644
--- a/test/Driver/mips-eleb.c
+++ b/test/Driver/mips-eleb.c
@@ -4,26 +4,30 @@
 // RUN:        -EL -no-integrated-as %s 2>&1 \
 // RUN:        | FileCheck -check-prefix=MIPS32-EL %s
 // MIPS32-EL: "{{.*}}clang{{.*}}" "-cc1" "-triple" "mipsel-unknown-linux-gnu"
-// MIPS32-EL: "{{.*}}as{{(.exe)?}}" "-march" "mips32" "-mabi" "32" "-EL"
+// MIPS32-EL: "{{.*}}as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32"
+// MIPS32-EL: "-EL"
 // MIPS32-EL: "{{.*}}ld{{(.exe)?}}" {{.*}} "-m" "elf32ltsmip"
 //
 // RUN: %clang -no-canonical-prefixes -target mips64-unknown-linux-gnu -### \
 // RUN:        -EL -no-integrated-as %s 2>&1 \
 // RUN:        | FileCheck -check-prefix=MIPS64-EL %s
 // MIPS64-EL: "{{.*}}clang{{.*}}" "-cc1" "-triple" "mips64el-unknown-linux-gnu"
-// MIPS64-EL: "{{.*}}as{{(.exe)?}}" "-march" "mips64" "-mabi" "64" "-EL"
+// MIPS64-EL: "{{.*}}as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64"
+// MIPS64-EL: "-EL"
 // MIPS64-EL: "{{.*}}ld{{(.exe)?}}" {{.*}} "-m" "elf64ltsmip"
 //
 // RUN: %clang -no-canonical-prefixes -target mipsel-unknown-linux-gnu -### \
 // RUN:        -EB -no-integrated-as %s 2>&1 \
 // RUN:        | FileCheck -check-prefix=MIPS32-EB %s
 // MIPS32-EB: "{{.*}}clang{{.*}}" "-cc1" "-triple" "mips-unknown-linux-gnu"
-// MIPS32-EB: "{{.*}}as{{(.exe)?}}" "-march" "mips32" "-mabi" "32" "-EB"
+// MIPS32-EB: "{{.*}}as{{(.exe)?}}" "-march" "mips32r2" "-mabi" "32"
+// MIPS32-EB: "-EB"
 // MIPS32-EB: "{{.*}}ld{{(.exe)?}}" {{.*}} "-m" "elf32btsmip"
 //
 // RUN: %clang -no-canonical-prefixes -target mips64el-unknown-linux-gnu -### \
 // RUN:        -EB -no-integrated-as %s 2>&1 \
 // RUN:        | FileCheck -check-prefix=MIPS64-EB %s
 // MIPS64-EB: "{{.*}}clang{{.*}}" "-cc1" "-triple" "mips64-unknown-linux-gnu"
-// MIPS64-EB: "{{.*}}as{{(.exe)?}}" "-march" "mips64" "-mabi" "64" "-EB"
+// MIPS64-EB: "{{.*}}as{{(.exe)?}}" "-march" "mips64r2" "-mabi" "64"
+// MIPS64-EB: "-EB"
 // MIPS64-EB: "{{.*}}ld{{(.exe)?}}" {{.*}} "-m" "elf64btsmip"
diff --git a/test/Driver/mips-features.c b/test/Driver/mips-features.c
index d663e66..03cc0fd 100644
--- a/test/Driver/mips-features.c
+++ b/test/Driver/mips-features.c
@@ -60,6 +60,28 @@
 // RUN:   | FileCheck --check-prefix=CHECK-NOMMSA %s
 // CHECK-NOMMSA: "-target-feature" "-msa"
 //
+// -modd-spreg
+// RUN: %clang -target mips-linux-gnu -### -c %s -mno-odd-spreg -modd-spreg 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-MODDSPREG %s
+// CHECK-MODDSPREG: "-target-feature" "-nooddspreg"
+//
+// -mno-odd-spreg
+// RUN: %clang -target mips-linux-gnu -### -c %s -modd-spreg -mno-odd-spreg 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-NOMODDSPREG %s
+// CHECK-NOMODDSPREG: "-target-feature" "+nooddspreg"
+//
+// -mfpxx
+// RUN: %clang -target mips-linux-gnu -### -c %s -mfpxx 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-MFPXX %s
+// CHECK-MFPXX: "-target-feature" "+fpxx"
+// CHECK-MFPXX: "-target-feature" "+nooddspreg"
+//
+// -mfpxx -modd-spreg
+// RUN: %clang -target mips-linux-gnu -### -c %s -mfpxx -modd-spreg 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-MFPXX-ODDSPREG %s
+// CHECK-MFPXX-ODDSPREG: "-target-feature" "+fpxx"
+// CHECK-MFPXX-ODDSPREG: "-target-feature" "-nooddspreg"
+//
 // -mfp64
 // RUN: %clang -target mips-linux-gnu -### -c %s \
 // RUN:     -mfp32 -mfp64 2>&1 \
@@ -72,6 +94,18 @@
 // RUN:   | FileCheck --check-prefix=CHECK-NOMFP64 %s
 // CHECK-NOMFP64: "-target-feature" "-fp64"
 //
+// -mnan=2008
+// RUN: %clang -target mips-linux-gnu -### -c %s \
+// RUN:     -mnan=legacy -mnan=2008 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-NAN2008 %s
+// CHECK-NAN2008: "-target-feature" "+nan2008"
+//
+// -mnan=legacy
+// RUN: %clang -target mips-linux-gnu -### -c %s \
+// RUN:     -mnan=2008 -mnan=legacy 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-NANLEGACY %s
+// CHECK-NANLEGACY: "-target-feature" "-nan2008"
+//
 // -mxgot
 // RUN: %clang -target mips-linux-gnu -### -c %s \
 // RUN:     -mno-xgot -mxgot 2>&1 \
diff --git a/test/Driver/mips-float.c b/test/Driver/mips-float.c
index ad2106a..1621075 100644
--- a/test/Driver/mips-float.c
+++ b/test/Driver/mips-float.c
@@ -60,23 +60,22 @@
 // RUN: %clang -c %s -### -o %t.o 2>&1 \
 // RUN:     -target mips-linux-gnu -mips16 \
 // RUN:   | FileCheck --check-prefix=CHECK-DEF-MIPS16 %s
-// CHECK-DEF-MIPS16: "-mfloat-abi" "soft"
-// CHECK-DEF-MIPS16: "-mllvm" "-mips16-hard-float"
+// CHECK-DEF-MIPS16: "-target-feature" "+mips16"
+// CHECK-DEF-MIPS16: "-mfloat-abi" "hard"
 //
 // -mhard-float -mips16
 // RUN: %clang -c %s -### -o %t.o 2>&1 \
 // RUN:     -target mips-linux-gnu -mhard-float -mips16 \
 // RUN:   | FileCheck --check-prefix=CHECK-HARD-MIPS16 %s
-// CHECK-HARD-MIPS16: "-target-feature" "+soft-float"
-// CHECK-HARD-MIPS16: "-msoft-float"
-// CHECK-HARD-MIPS16: "-mfloat-abi" "soft"
-// CHECK-HARD-MIPS16: "-mllvm" "-mips16-hard-float"
+// CHECK-HARD-MIPS16: "-target-feature" "+mips16"
+// CHECK-HARD-MIPS16: "-mfloat-abi" "hard"
 //
 // -msoft-float -mips16
 // RUN: %clang -c %s -### -o %t.o 2>&1 \
 // RUN:     -target mips-linux-gnu -msoft-float -mips16 \
 // RUN:   | FileCheck --check-prefix=CHECK-SOFT-MIPS16 %s
 // CHECK-SOFT-MIPS16: "-target-feature" "+soft-float"
+// CHECK-SOFT-MIPS16: "-target-feature" "+mips16"
 // CHECK-SOFT-MIPS16: "-msoft-float"
 // CHECK-SOFT-MIPS16: "-mfloat-abi" "soft"
 //
@@ -84,15 +83,14 @@
 // RUN: %clang -c %s -### -o %t.o 2>&1 \
 // RUN:     -target mips-linux-gnu -mfloat-abi=hard -mips16 \
 // RUN:   | FileCheck --check-prefix=CHECK-ABI-HARD-MIPS16 %s
-// CHECK-ABI-HARD-MIPS16: "-target-feature" "+soft-float"
-// CHECK-ABI-HARD-MIPS16: "-msoft-float"
-// CHECK-ABI-HARD-MIPS16: "-mfloat-abi" "soft"
-// CHECK-ABI-HARD-MIPS16: "-mllvm" "-mips16-hard-float"
+// CHECK-ABI-HARD-MIPS16: "-target-feature" "+mips16"
+// CHECK-ABI-HARD-MIPS16: "-mfloat-abi" "hard"
 //
 // -mfloat-abi=soft -mips16
 // RUN: %clang -c %s -### -o %t.o 2>&1 \
 // RUN:     -target mips-linux-gnu -mfloat-abi=soft -mips16 \
 // RUN:   | FileCheck --check-prefix=CHECK-ABI-SOFT-MIPS16 %s
 // CHECK-ABI-SOFT-MIPS16: "-target-feature" "+soft-float"
+// CHECK-ABI-SOFT-MIPS16: "-target-feature" "+mips16"
 // CHECK-ABI-SOFT-MIPS16: "-msoft-float"
 // CHECK-ABI-SOFT-MIPS16: "-mfloat-abi" "soft"
diff --git a/test/Driver/mips-fsf.cpp b/test/Driver/mips-fsf.cpp
index f084370..4520aec 100644
--- a/test/Driver/mips-fsf.cpp
+++ b/test/Driver/mips-fsf.cpp
@@ -16,16 +16,42 @@
 // CHECK-BE-HF-32: "-internal-externc-isystem"
 // CHECK-BE-HF-32: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-BE-HF-32: "{{.*}}ld{{(.exe)?}}"
-// CHECK-BE-HF-32: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips32"
+// CHECK-BE-HF-32: "--sysroot=[[TC]]/../../../../sysroot/mips32"
 // CHECK-BE-HF-32: "[[TC]]/../../../../sysroot/mips32/usr/lib/../lib{{/|\\\\}}crt1.o"
 // CHECK-BE-HF-32: "[[TC]]/../../../../sysroot/mips32/usr/lib/../lib{{/|\\\\}}crti.o"
 // CHECK-BE-HF-32: "[[TC]]/mips32{{/|\\\\}}crtbegin.o"
-// CHECK-BE-HF-32: "-L[[SR]]/mips32"
-// CHECK-BE-HF-32: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/../lib/mips32"
-// CHECK-BE-HF-32: "-L[[SR]]/../../../../sysroot/mips32/usr/lib/../lib"
+// CHECK-BE-HF-32: "-L[[TC]]/mips32"
+// CHECK-BE-HF-32: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/mips32"
+// CHECK-BE-HF-32: "-L[[TC]]/../../../../sysroot/mips32/usr/lib/../lib"
 // CHECK-BE-HF-32: "[[TC]]/mips32{{/|\\\\}}crtend.o"
 // CHECK-BE-HF-32: "[[TC]]/../../../../sysroot/mips32/usr/lib/../lib{{/|\\\\}}crtn.o"
 //
+// = Big-endian, mips32, hard float, fp64
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips-linux-gnu -mips32 -mfp64 -mhard-float \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BE-HF64-32 %s
+// CHECK-BE-HF64-32: "-internal-isystem"
+// CHECK-BE-HF64-32: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-BE-HF64-32: "-internal-isystem"
+// CHECK-BE-HF64-32: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/mips32"
+// CHECK-BE-HF64-32: "-internal-isystem"
+// CHECK-BE-HF64-32: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-BE-HF64-32: "-internal-externc-isystem"
+// CHECK-BE-HF64-32: "[[TC]]/include"
+// CHECK-BE-HF64-32: "-internal-externc-isystem"
+// CHECK-BE-HF64-32: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-BE-HF64-32: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-HF64-32: "--sysroot=[[TC]]/../../../../sysroot/mips32"
+// CHECK-BE-HF64-32: "[[TC]]/../../../../sysroot/mips32/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-BE-HF64-32: "[[TC]]/../../../../sysroot/mips32/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-BE-HF64-32: "[[TC]]/mips32{{/|\\\\}}crtbegin.o"
+// CHECK-BE-HF64-32: "-L[[TC]]/mips32"
+// CHECK-BE-HF64-32: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/mips32"
+// CHECK-BE-HF64-32: "-L[[TC]]/../../../../sysroot/mips32/usr/lib/../lib"
+// CHECK-BE-HF64-32: "[[TC]]/mips32{{/|\\\\}}crtend.o"
+// CHECK-BE-HF64-32: "[[TC]]/../../../../sysroot/mips32/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
 // = Big-endian, mips32, soft float
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mips-linux-gnu -mips32 -msoft-float \
@@ -42,13 +68,13 @@
 // CHECK-BE-SF-32: "-internal-externc-isystem"
 // CHECK-BE-SF-32: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-BE-SF-32: "{{.*}}ld{{(.exe)?}}"
-// CHECK-BE-SF-32: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips32/sof"
+// CHECK-BE-SF-32: "--sysroot=[[TC]]/../../../../sysroot/mips32/sof"
 // CHECK-BE-SF-32: "[[TC]]/../../../../sysroot/mips32/sof/usr/lib/../lib{{/|\\\\}}crt1.o"
 // CHECK-BE-SF-32: "[[TC]]/../../../../sysroot/mips32/sof/usr/lib/../lib{{/|\\\\}}crti.o"
 // CHECK-BE-SF-32: "[[TC]]/mips32/sof{{/|\\\\}}crtbegin.o"
-// CHECK-BE-SF-32: "-L[[SR]]/mips32/sof"
-// CHECK-BE-SF-32: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/../lib/mips32/sof"
-// CHECK-BE-SF-32: "-L[[SR]]/../../../../sysroot/mips32/sof/usr/lib/../lib"
+// CHECK-BE-SF-32: "-L[[TC]]/mips32/sof"
+// CHECK-BE-SF-32: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/mips32/sof"
+// CHECK-BE-SF-32: "-L[[TC]]/../../../../sysroot/mips32/sof/usr/lib/../lib"
 // CHECK-BE-SF-32: "[[TC]]/mips32/sof{{/|\\\\}}crtend.o"
 // CHECK-BE-SF-32: "[[TC]]/../../../../sysroot/mips32/sof/usr/lib/../lib{{/|\\\\}}crtn.o"
 //
@@ -68,16 +94,42 @@
 // CHECK-BE-HF-16: "-internal-externc-isystem"
 // CHECK-BE-HF-16: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-BE-HF-16: "{{.*}}ld{{(.exe)?}}"
-// CHECK-BE-HF-16: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips32/mips16"
+// CHECK-BE-HF-16: "--sysroot=[[TC]]/../../../../sysroot/mips32/mips16"
 // CHECK-BE-HF-16: "[[TC]]/../../../../sysroot/mips32/mips16/usr/lib/../lib{{/|\\\\}}crt1.o"
 // CHECK-BE-HF-16: "[[TC]]/../../../../sysroot/mips32/mips16/usr/lib/../lib{{/|\\\\}}crti.o"
 // CHECK-BE-HF-16: "[[TC]]/mips32/mips16{{/|\\\\}}crtbegin.o"
-// CHECK-BE-HF-16: "-L[[SR]]/mips32/mips16"
-// CHECK-BE-HF-16: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/../lib/mips32/mips16"
-// CHECK-BE-HF-16: "-L[[SR]]/../../../../sysroot/mips32/mips16/usr/lib/../lib"
+// CHECK-BE-HF-16: "-L[[TC]]/mips32/mips16"
+// CHECK-BE-HF-16: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/mips32/mips16"
+// CHECK-BE-HF-16: "-L[[TC]]/../../../../sysroot/mips32/mips16/usr/lib/../lib"
 // CHECK-BE-HF-16: "[[TC]]/mips32/mips16{{/|\\\\}}crtend.o"
 // CHECK-BE-HF-16: "[[TC]]/../../../../sysroot/mips32/mips16/usr/lib/../lib{{/|\\\\}}crtn.o"
 //
+// = Big-endian, mips16 / mips32, hard float, fp64
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips-linux-gnu -mips32 -mips16 -mfp64 -mhard-float \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BE-HF64-16 %s
+// CHECK-BE-HF64-16: "-internal-isystem"
+// CHECK-BE-HF64-16: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-BE-HF64-16: "-internal-isystem"
+// CHECK-BE-HF64-16: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/mips32/mips16"
+// CHECK-BE-HF64-16: "-internal-isystem"
+// CHECK-BE-HF64-16: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-BE-HF64-16: "-internal-externc-isystem"
+// CHECK-BE-HF64-16: "[[TC]]/include"
+// CHECK-BE-HF64-16: "-internal-externc-isystem"
+// CHECK-BE-HF64-16: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-BE-HF64-16: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-HF64-16: "--sysroot=[[TC]]/../../../../sysroot/mips32/mips16"
+// CHECK-BE-HF64-16: "[[TC]]/../../../../sysroot/mips32/mips16/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-BE-HF64-16: "[[TC]]/../../../../sysroot/mips32/mips16/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-BE-HF64-16: "[[TC]]/mips32/mips16{{/|\\\\}}crtbegin.o"
+// CHECK-BE-HF64-16: "-L[[TC]]/mips32/mips16"
+// CHECK-BE-HF64-16: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/mips32/mips16"
+// CHECK-BE-HF64-16: "-L[[TC]]/../../../../sysroot/mips32/mips16/usr/lib/../lib"
+// CHECK-BE-HF64-16: "[[TC]]/mips32/mips16{{/|\\\\}}crtend.o"
+// CHECK-BE-HF64-16: "[[TC]]/../../../../sysroot/mips32/mips16/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
 // = Big-endian, mips16 / mips32, soft float
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mips-linux-gnu -mips32 -mips16 -msoft-float \
@@ -94,13 +146,13 @@
 // CHECK-BE-SF-16: "-internal-externc-isystem"
 // CHECK-BE-SF-16: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-BE-SF-16: "{{.*}}ld{{(.exe)?}}"
-// CHECK-BE-SF-16: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips32/mips16/sof"
+// CHECK-BE-SF-16: "--sysroot=[[TC]]/../../../../sysroot/mips32/mips16/sof"
 // CHECK-BE-SF-16: "[[TC]]/../../../../sysroot/mips32/mips16/sof/usr/lib/../lib{{/|\\\\}}crt1.o"
 // CHECK-BE-SF-16: "[[TC]]/../../../../sysroot/mips32/mips16/sof/usr/lib/../lib{{/|\\\\}}crti.o"
 // CHECK-BE-SF-16: "[[TC]]/mips32/mips16/sof{{/|\\\\}}crtbegin.o"
-// CHECK-BE-SF-16: "-L[[SR]]/mips32/mips16/sof"
-// CHECK-BE-SF-16: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/../lib/mips32/mips16/sof"
-// CHECK-BE-SF-16: "-L[[SR]]/../../../../sysroot/mips32/mips16/sof/usr/lib/../lib"
+// CHECK-BE-SF-16: "-L[[TC]]/mips32/mips16/sof"
+// CHECK-BE-SF-16: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/mips32/mips16/sof"
+// CHECK-BE-SF-16: "-L[[TC]]/../../../../sysroot/mips32/mips16/sof/usr/lib/../lib"
 // CHECK-BE-SF-16: "[[TC]]/mips32/mips16/sof{{/|\\\\}}crtend.o"
 // CHECK-BE-SF-16: "[[TC]]/../../../../sysroot/mips32/mips16/sof/usr/lib/../lib{{/|\\\\}}crtn.o"
 //
@@ -120,16 +172,42 @@
 // CHECK-BE-NAN-16: "-internal-externc-isystem"
 // CHECK-BE-NAN-16: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-BE-NAN-16: "{{.*}}ld{{(.exe)?}}"
-// CHECK-BE-NAN-16: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips32/mips16/nan2008"
+// CHECK-BE-NAN-16: "--sysroot=[[TC]]/../../../../sysroot/mips32/mips16/nan2008"
 // CHECK-BE-NAN-16: "[[TC]]/../../../../sysroot/mips32/mips16/nan2008/usr/lib/../lib{{/|\\\\}}crt1.o"
 // CHECK-BE-NAN-16: "[[TC]]/../../../../sysroot/mips32/mips16/nan2008/usr/lib/../lib{{/|\\\\}}crti.o"
 // CHECK-BE-NAN-16: "[[TC]]/mips32/mips16/nan2008{{/|\\\\}}crtbegin.o"
-// CHECK-BE-NAN-16: "-L[[SR]]/mips32/mips16/nan2008"
-// CHECK-BE-NAN-16: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/../lib/mips32/mips16/nan2008"
-// CHECK-BE-NAN-16: "-L[[SR]]/../../../../sysroot/mips32/mips16/nan2008/usr/lib/../lib"
+// CHECK-BE-NAN-16: "-L[[TC]]/mips32/mips16/nan2008"
+// CHECK-BE-NAN-16: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/mips32/mips16/nan2008"
+// CHECK-BE-NAN-16: "-L[[TC]]/../../../../sysroot/mips32/mips16/nan2008/usr/lib/../lib"
 // CHECK-BE-NAN-16: "[[TC]]/mips32/mips16/nan2008{{/|\\\\}}crtend.o"
 // CHECK-BE-NAN-16: "[[TC]]/../../../../sysroot/mips32/mips16/nan2008/usr/lib/../lib{{/|\\\\}}crtn.o"
 //
+// = Big-endian, mips32 / mips16, fp64, nan2008
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips-linux-gnu -mips32 -mips16 -mfp64 -mnan=2008 \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BE-NAN64-16 %s
+// CHECK-BE-NAN64-16: "-internal-isystem"
+// CHECK-BE-NAN64-16: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-BE-NAN64-16: "-internal-isystem"
+// CHECK-BE-NAN64-16: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/mips32/mips16/nan2008"
+// CHECK-BE-NAN64-16: "-internal-isystem"
+// CHECK-BE-NAN64-16: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-BE-NAN64-16: "-internal-externc-isystem"
+// CHECK-BE-NAN64-16: "[[TC]]/include"
+// CHECK-BE-NAN64-16: "-internal-externc-isystem"
+// CHECK-BE-NAN64-16: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-BE-NAN64-16: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-NAN64-16: "--sysroot=[[TC]]/../../../../sysroot/mips32/mips16/nan2008"
+// CHECK-BE-NAN64-16: "[[TC]]/../../../../sysroot/mips32/mips16/nan2008/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-BE-NAN64-16: "[[TC]]/../../../../sysroot/mips32/mips16/nan2008/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-BE-NAN64-16: "[[TC]]/mips32/mips16/nan2008{{/|\\\\}}crtbegin.o"
+// CHECK-BE-NAN64-16: "-L[[TC]]/mips32/mips16/nan2008"
+// CHECK-BE-NAN64-16: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/mips32/mips16/nan2008"
+// CHECK-BE-NAN64-16: "-L[[TC]]/../../../../sysroot/mips32/mips16/nan2008/usr/lib/../lib"
+// CHECK-BE-NAN64-16: "[[TC]]/mips32/mips16/nan2008{{/|\\\\}}crtend.o"
+// CHECK-BE-NAN64-16: "[[TC]]/../../../../sysroot/mips32/mips16/nan2008/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
 // = Big-endian, mips32, nan2008
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mips-linux-gnu -mips32 -mnan=2008 \
@@ -146,16 +224,42 @@
 // CHECK-BE-NAN-32: "-internal-externc-isystem"
 // CHECK-BE-NAN-32: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-BE-NAN-32: "{{.*}}ld{{(.exe)?}}"
-// CHECK-BE-NAN-32: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips32/nan2008"
+// CHECK-BE-NAN-32: "--sysroot=[[TC]]/../../../../sysroot/mips32/nan2008"
 // CHECK-BE-NAN-32: "[[TC]]/../../../../sysroot/mips32/nan2008/usr/lib/../lib{{/|\\\\}}crt1.o"
 // CHECK-BE-NAN-32: "[[TC]]/../../../../sysroot/mips32/nan2008/usr/lib/../lib{{/|\\\\}}crti.o"
 // CHECK-BE-NAN-32: "[[TC]]/mips32/nan2008{{/|\\\\}}crtbegin.o"
-// CHECK-BE-NAN-32: "-L[[SR]]/mips32/nan2008"
-// CHECK-BE-NAN-32: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/../lib/mips32/nan2008"
-// CHECK-BE-NAN-32: "-L[[SR]]/../../../../sysroot/mips32/nan2008/usr/lib/../lib"
+// CHECK-BE-NAN-32: "-L[[TC]]/mips32/nan2008"
+// CHECK-BE-NAN-32: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/mips32/nan2008"
+// CHECK-BE-NAN-32: "-L[[TC]]/../../../../sysroot/mips32/nan2008/usr/lib/../lib"
 // CHECK-BE-NAN-32: "[[TC]]/mips32/nan2008{{/|\\\\}}crtend.o"
 // CHECK-BE-NAN-32: "[[TC]]/../../../../sysroot/mips32/nan2008/usr/lib/../lib{{/|\\\\}}crtn.o"
 //
+// = Big-endian, mips32, fp64, nan2008
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips-linux-gnu -mips32 -mfp64 -mnan=2008 \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BE-NAN64-32 %s
+// CHECK-BE-NAN64-32: "-internal-isystem"
+// CHECK-BE-NAN64-32: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-BE-NAN64-32: "-internal-isystem"
+// CHECK-BE-NAN64-32: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/mips32/nan2008"
+// CHECK-BE-NAN64-32: "-internal-isystem"
+// CHECK-BE-NAN64-32: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-BE-NAN64-32: "-internal-externc-isystem"
+// CHECK-BE-NAN64-32: "[[TC]]/include"
+// CHECK-BE-NAN64-32: "-internal-externc-isystem"
+// CHECK-BE-NAN64-32: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-BE-NAN64-32: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-NAN64-32: "--sysroot=[[TC]]/../../../../sysroot/mips32/nan2008"
+// CHECK-BE-NAN64-32: "[[TC]]/../../../../sysroot/mips32/nan2008/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-BE-NAN64-32: "[[TC]]/../../../../sysroot/mips32/nan2008/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-BE-NAN64-32: "[[TC]]/mips32/nan2008{{/|\\\\}}crtbegin.o"
+// CHECK-BE-NAN64-32: "-L[[TC]]/mips32/nan2008"
+// CHECK-BE-NAN64-32: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/mips32/nan2008"
+// CHECK-BE-NAN64-32: "-L[[TC]]/../../../../sysroot/mips32/nan2008/usr/lib/../lib"
+// CHECK-BE-NAN64-32: "[[TC]]/mips32/nan2008{{/|\\\\}}crtend.o"
+// CHECK-BE-NAN64-32: "[[TC]]/../../../../sysroot/mips32/nan2008/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
 // = Big-endian, mips32r2, hard float
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mips-linux-gnu -mips32r2 -mhard-float \
@@ -172,16 +276,42 @@
 // CHECK-BE-HF-32R2: "-internal-externc-isystem"
 // CHECK-BE-HF-32R2: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-BE-HF-32R2: "{{.*}}ld{{(.exe)?}}"
-// CHECK-BE-HF-32R2: "--sysroot=[[SR:[^"]+]]/../../../../sysroot"
+// CHECK-BE-HF-32R2: "--sysroot=[[TC]]/../../../../sysroot"
 // CHECK-BE-HF-32R2: "[[TC]]/../../../../sysroot/usr/lib/../lib{{/|\\\\}}crt1.o"
 // CHECK-BE-HF-32R2: "[[TC]]/../../../../sysroot/usr/lib/../lib{{/|\\\\}}crti.o"
 // CHECK-BE-HF-32R2: "[[TC]]{{/|\\\\}}crtbegin.o"
-// CHECK-BE-HF-32R2: "-L[[SR]]"
-// CHECK-BE-HF-32R2: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/../lib"
-// CHECK-BE-HF-32R2: "-L[[SR]]/../../../../sysroot/usr/lib/../lib"
+// CHECK-BE-HF-32R2: "-L[[TC]]"
+// CHECK-BE-HF-32R2: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib"
+// CHECK-BE-HF-32R2: "-L[[TC]]/../../../../sysroot/usr/lib/../lib"
 // CHECK-BE-HF-32R2: "[[TC]]{{/|\\\\}}crtend.o"
 // CHECK-BE-HF-32R2: "[[TC]]/../../../../sysroot/usr/lib/../lib{{/|\\\\}}crtn.o"
 //
+// = Big-endian, mips32r2, fp64, hard float
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips-linux-gnu -mips32r2 -mfp64 -mhard-float \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BE-HF64-32R2 %s
+// CHECK-BE-HF64-32R2: "-internal-isystem"
+// CHECK-BE-HF64-32R2: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-BE-HF64-32R2: "-internal-isystem"
+// CHECK-BE-HF64-32R2: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu"
+// CHECK-BE-HF64-32R2: "-internal-isystem"
+// CHECK-BE-HF64-32R2: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-BE-HF64-32R2: "-internal-externc-isystem"
+// CHECK-BE-HF64-32R2: "[[TC]]/include"
+// CHECK-BE-HF64-32R2: "-internal-externc-isystem"
+// CHECK-BE-HF64-32R2: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-BE-HF64-32R2: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-HF64-32R2: "--sysroot=[[TC]]/../../../../sysroot"
+// CHECK-BE-HF64-32R2: "[[TC]]/../../../../sysroot/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-BE-HF64-32R2: "[[TC]]/../../../../sysroot/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-BE-HF64-32R2: "[[TC]]{{/|\\\\}}crtbegin.o"
+// CHECK-BE-HF64-32R2: "-L[[TC]]"
+// CHECK-BE-HF64-32R2: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib"
+// CHECK-BE-HF64-32R2: "-L[[TC]]/../../../../sysroot/usr/lib/../lib"
+// CHECK-BE-HF64-32R2: "[[TC]]{{/|\\\\}}crtend.o"
+// CHECK-BE-HF64-32R2: "[[TC]]/../../../../sysroot/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
 // = Big-endian, mips32r2, soft float
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mips-linux-gnu -mips32r2 -msoft-float \
@@ -198,13 +328,13 @@
 // CHECK-BE-SF-32R2: "-internal-externc-isystem"
 // CHECK-BE-SF-32R2: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-BE-SF-32R2: "{{.*}}ld{{(.exe)?}}"
-// CHECK-BE-SF-32R2: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/sof"
+// CHECK-BE-SF-32R2: "--sysroot=[[TC]]/../../../../sysroot/sof"
 // CHECK-BE-SF-32R2: "[[TC]]/../../../../sysroot/sof/usr/lib/../lib{{/|\\\\}}crt1.o"
 // CHECK-BE-SF-32R2: "[[TC]]/../../../../sysroot/sof/usr/lib/../lib{{/|\\\\}}crti.o"
 // CHECK-BE-SF-32R2: "[[TC]]/sof{{/|\\\\}}crtbegin.o"
-// CHECK-BE-SF-32R2: "-L[[SR]]/sof"
-// CHECK-BE-SF-32R2: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/../lib/sof"
-// CHECK-BE-SF-32R2: "-L[[SR]]/../../../../sysroot/sof/usr/lib/../lib"
+// CHECK-BE-SF-32R2: "-L[[TC]]/sof"
+// CHECK-BE-SF-32R2: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/sof"
+// CHECK-BE-SF-32R2: "-L[[TC]]/../../../../sysroot/sof/usr/lib/../lib"
 // CHECK-BE-SF-32R2: "[[TC]]/sof{{/|\\\\}}crtend.o"
 // CHECK-BE-SF-32R2: "[[TC]]/../../../../sysroot/sof/usr/lib/../lib{{/|\\\\}}crtn.o"
 //
@@ -224,16 +354,42 @@
 // CHECK-BE-HF-16R2: "-internal-externc-isystem"
 // CHECK-BE-HF-16R2: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-BE-HF-16R2: "{{.*}}ld{{(.exe)?}}"
-// CHECK-BE-HF-16R2: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips16"
+// CHECK-BE-HF-16R2: "--sysroot=[[TC]]/../../../../sysroot/mips16"
 // CHECK-BE-HF-16R2: "[[TC]]/../../../../sysroot/mips16/usr/lib/../lib{{/|\\\\}}crt1.o"
 // CHECK-BE-HF-16R2: "[[TC]]/../../../../sysroot/mips16/usr/lib/../lib{{/|\\\\}}crti.o"
 // CHECK-BE-HF-16R2: "[[TC]]/mips16{{/|\\\\}}crtbegin.o"
-// CHECK-BE-HF-16R2: "-L[[SR]]/mips16"
-// CHECK-BE-HF-16R2: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/../lib/mips16"
-// CHECK-BE-HF-16R2: "-L[[SR]]/../../../../sysroot/mips16/usr/lib/../lib"
+// CHECK-BE-HF-16R2: "-L[[TC]]/mips16"
+// CHECK-BE-HF-16R2: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/mips16"
+// CHECK-BE-HF-16R2: "-L[[TC]]/../../../../sysroot/mips16/usr/lib/../lib"
 // CHECK-BE-HF-16R2: "[[TC]]/mips16{{/|\\\\}}crtend.o"
 // CHECK-BE-HF-16R2: "[[TC]]/../../../../sysroot/mips16/usr/lib/../lib{{/|\\\\}}crtn.o"
 //
+// = Big-endian, mips32r2 / mips16, fp64, hard float
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips-linux-gnu -mips32r2 -mips16 -mfp64 -mhard-float \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BE-HF64-16R2 %s
+// CHECK-BE-HF64-16R2: "-internal-isystem"
+// CHECK-BE-HF64-16R2: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-BE-HF64-16R2: "-internal-isystem"
+// CHECK-BE-HF64-16R2: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/mips16"
+// CHECK-BE-HF64-16R2: "-internal-isystem"
+// CHECK-BE-HF64-16R2: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-BE-HF64-16R2: "-internal-externc-isystem"
+// CHECK-BE-HF64-16R2: "[[TC]]/include"
+// CHECK-BE-HF64-16R2: "-internal-externc-isystem"
+// CHECK-BE-HF64-16R2: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-BE-HF64-16R2: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-HF64-16R2: "--sysroot=[[TC]]/../../../../sysroot/mips16"
+// CHECK-BE-HF64-16R2: "[[TC]]/../../../../sysroot/mips16/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-BE-HF64-16R2: "[[TC]]/../../../../sysroot/mips16/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-BE-HF64-16R2: "[[TC]]/mips16{{/|\\\\}}crtbegin.o"
+// CHECK-BE-HF64-16R2: "-L[[TC]]/mips16"
+// CHECK-BE-HF64-16R2: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/mips16"
+// CHECK-BE-HF64-16R2: "-L[[TC]]/../../../../sysroot/mips16/usr/lib/../lib"
+// CHECK-BE-HF64-16R2: "[[TC]]/mips16{{/|\\\\}}crtend.o"
+// CHECK-BE-HF64-16R2: "[[TC]]/../../../../sysroot/mips16/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
 // = Big-endian, mips32r2 / mips16, soft float
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mips-linux-gnu -mips32r2 -mips16 -msoft-float \
@@ -250,13 +406,13 @@
 // CHECK-BE-SF-16R2: "-internal-externc-isystem"
 // CHECK-BE-SF-16R2: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-BE-SF-16R2: "{{.*}}ld{{(.exe)?}}"
-// CHECK-BE-SF-16R2: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips16/sof"
+// CHECK-BE-SF-16R2: "--sysroot=[[TC]]/../../../../sysroot/mips16/sof"
 // CHECK-BE-SF-16R2: "[[TC]]/../../../../sysroot/mips16/sof/usr/lib/../lib{{/|\\\\}}crt1.o"
 // CHECK-BE-SF-16R2: "[[TC]]/../../../../sysroot/mips16/sof/usr/lib/../lib{{/|\\\\}}crti.o"
 // CHECK-BE-SF-16R2: "[[TC]]/mips16/sof{{/|\\\\}}crtbegin.o"
-// CHECK-BE-SF-16R2: "-L[[SR]]/mips16/sof"
-// CHECK-BE-SF-16R2: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/../lib/mips16/sof"
-// CHECK-BE-SF-16R2: "-L[[SR]]/../../../../sysroot/mips16/sof/usr/lib/../lib"
+// CHECK-BE-SF-16R2: "-L[[TC]]/mips16/sof"
+// CHECK-BE-SF-16R2: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/mips16/sof"
+// CHECK-BE-SF-16R2: "-L[[TC]]/../../../../sysroot/mips16/sof/usr/lib/../lib"
 // CHECK-BE-SF-16R2: "[[TC]]/mips16/sof{{/|\\\\}}crtend.o"
 // CHECK-BE-SF-16R2: "[[TC]]/../../../../sysroot/mips16/sof/usr/lib/../lib{{/|\\\\}}crtn.o"
 //
@@ -276,16 +432,42 @@
 // CHECK-BE-NAN-16R2: "-internal-externc-isystem"
 // CHECK-BE-NAN-16R2: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-BE-NAN-16R2: "{{.*}}ld{{(.exe)?}}"
-// CHECK-BE-NAN-16R2: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips16/nan2008"
+// CHECK-BE-NAN-16R2: "--sysroot=[[TC]]/../../../../sysroot/mips16/nan2008"
 // CHECK-BE-NAN-16R2: "[[TC]]/../../../../sysroot/mips16/nan2008/usr/lib/../lib{{/|\\\\}}crt1.o"
 // CHECK-BE-NAN-16R2: "[[TC]]/../../../../sysroot/mips16/nan2008/usr/lib/../lib{{/|\\\\}}crti.o"
 // CHECK-BE-NAN-16R2: "[[TC]]/mips16/nan2008{{/|\\\\}}crtbegin.o"
-// CHECK-BE-NAN-16R2: "-L[[SR]]/mips16/nan2008"
-// CHECK-BE-NAN-16R2: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/../lib/mips16/nan2008"
-// CHECK-BE-NAN-16R2: "-L[[SR]]/../../../../sysroot/mips16/nan2008/usr/lib/../lib"
+// CHECK-BE-NAN-16R2: "-L[[TC]]/mips16/nan2008"
+// CHECK-BE-NAN-16R2: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/mips16/nan2008"
+// CHECK-BE-NAN-16R2: "-L[[TC]]/../../../../sysroot/mips16/nan2008/usr/lib/../lib"
 // CHECK-BE-NAN-16R2: "[[TC]]/mips16/nan2008{{/|\\\\}}crtend.o"
 // CHECK-BE-NAN-16R2: "[[TC]]/../../../../sysroot/mips16/nan2008/usr/lib/../lib{{/|\\\\}}crtn.o"
 //
+// = Big-endian, mips32r2 / mips16, fp64, nan2008
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips-linux-gnu -mips32r2 -mips16 -mfp64 -mnan=2008 \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BE-NAN64-16R2 %s
+// CHECK-BE-NAN64-16R2: "-internal-isystem"
+// CHECK-BE-NAN64-16R2: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-BE-NAN64-16R2: "-internal-isystem"
+// CHECK-BE-NAN64-16R2: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/mips16/nan2008"
+// CHECK-BE-NAN64-16R2: "-internal-isystem"
+// CHECK-BE-NAN64-16R2: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-BE-NAN64-16R2: "-internal-externc-isystem"
+// CHECK-BE-NAN64-16R2: "[[TC]]/include"
+// CHECK-BE-NAN64-16R2: "-internal-externc-isystem"
+// CHECK-BE-NAN64-16R2: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-BE-NAN64-16R2: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-NAN64-16R2: "--sysroot=[[TC]]/../../../../sysroot/mips16/nan2008"
+// CHECK-BE-NAN64-16R2: "[[TC]]/../../../../sysroot/mips16/nan2008/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-BE-NAN64-16R2: "[[TC]]/../../../../sysroot/mips16/nan2008/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-BE-NAN64-16R2: "[[TC]]/mips16/nan2008{{/|\\\\}}crtbegin.o"
+// CHECK-BE-NAN64-16R2: "-L[[TC]]/mips16/nan2008"
+// CHECK-BE-NAN64-16R2: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/mips16/nan2008"
+// CHECK-BE-NAN64-16R2: "-L[[TC]]/../../../../sysroot/mips16/nan2008/usr/lib/../lib"
+// CHECK-BE-NAN64-16R2: "[[TC]]/mips16/nan2008{{/|\\\\}}crtend.o"
+// CHECK-BE-NAN64-16R2: "[[TC]]/../../../../sysroot/mips16/nan2008/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
 // = Big-endian, mips32r2, nan2008
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mips-linux-gnu -mips32r2 -mnan=2008 \
@@ -302,16 +484,68 @@
 // CHECK-BE-NAN-32R2: "-internal-externc-isystem"
 // CHECK-BE-NAN-32R2: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-BE-NAN-32R2: "{{.*}}ld{{(.exe)?}}"
-// CHECK-BE-NAN-32R2: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/nan2008"
+// CHECK-BE-NAN-32R2: "--sysroot=[[TC]]/../../../../sysroot/nan2008"
 // CHECK-BE-NAN-32R2: "[[TC]]/../../../../sysroot/nan2008/usr/lib/../lib{{/|\\\\}}crt1.o"
 // CHECK-BE-NAN-32R2: "[[TC]]/../../../../sysroot/nan2008/usr/lib/../lib{{/|\\\\}}crti.o"
 // CHECK-BE-NAN-32R2: "[[TC]]/nan2008{{/|\\\\}}crtbegin.o"
-// CHECK-BE-NAN-32R2: "-L[[SR]]/nan2008"
-// CHECK-BE-NAN-32R2: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/../lib/nan2008"
-// CHECK-BE-NAN-32R2: "-L[[SR]]/../../../../sysroot/nan2008/usr/lib/../lib"
+// CHECK-BE-NAN-32R2: "-L[[TC]]/nan2008"
+// CHECK-BE-NAN-32R2: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/nan2008"
+// CHECK-BE-NAN-32R2: "-L[[TC]]/../../../../sysroot/nan2008/usr/lib/../lib"
 // CHECK-BE-NAN-32R2: "[[TC]]/nan2008{{/|\\\\}}crtend.o"
 // CHECK-BE-NAN-32R2: "[[TC]]/../../../../sysroot/nan2008/usr/lib/../lib{{/|\\\\}}crtn.o"
 //
+// = Big-endian, mips32r2, fp64, nan2008
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips-linux-gnu -mips32r2 -mfp64 -mnan=2008 \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BE-NAN64-32R2 %s
+// CHECK-BE-NAN64-32R2: "-internal-isystem"
+// CHECK-BE-NAN64-32R2: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-BE-NAN64-32R2: "-internal-isystem"
+// CHECK-BE-NAN64-32R2: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/nan2008"
+// CHECK-BE-NAN64-32R2: "-internal-isystem"
+// CHECK-BE-NAN64-32R2: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-BE-NAN64-32R2: "-internal-externc-isystem"
+// CHECK-BE-NAN64-32R2: "[[TC]]/include"
+// CHECK-BE-NAN64-32R2: "-internal-externc-isystem"
+// CHECK-BE-NAN64-32R2: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-BE-NAN64-32R2: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-NAN64-32R2: "--sysroot=[[TC]]/../../../../sysroot/nan2008"
+// CHECK-BE-NAN64-32R2: "[[TC]]/../../../../sysroot/nan2008/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-BE-NAN64-32R2: "[[TC]]/../../../../sysroot/nan2008/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-BE-NAN64-32R2: "[[TC]]/nan2008{{/|\\\\}}crtbegin.o"
+// CHECK-BE-NAN64-32R2: "-L[[TC]]/nan2008"
+// CHECK-BE-NAN64-32R2: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/nan2008"
+// CHECK-BE-NAN64-32R2: "-L[[TC]]/../../../../sysroot/nan2008/usr/lib/../lib"
+// CHECK-BE-NAN64-32R2: "[[TC]]/nan2008{{/|\\\\}}crtend.o"
+// CHECK-BE-NAN64-32R2: "[[TC]]/../../../../sysroot/nan2008/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
+// = Big-endian, default (mips32r2), fp64, nan2008
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips-linux-gnu -mfp64 -mnan=2008 \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BE-NAN64-32R2-DEF %s
+// CHECK-BE-NAN64-32R2-DEF: "-internal-isystem"
+// CHECK-BE-NAN64-32R2-DEF: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-BE-NAN64-32R2-DEF: "-internal-isystem"
+// CHECK-BE-NAN64-32R2-DEF: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/nan2008"
+// CHECK-BE-NAN64-32R2-DEF: "-internal-isystem"
+// CHECK-BE-NAN64-32R2-DEF: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-BE-NAN64-32R2-DEF: "-internal-externc-isystem"
+// CHECK-BE-NAN64-32R2-DEF: "[[TC]]/include"
+// CHECK-BE-NAN64-32R2-DEF: "-internal-externc-isystem"
+// CHECK-BE-NAN64-32R2-DEF: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-BE-NAN64-32R2-DEF: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-NAN64-32R2-DEF: "--sysroot=[[TC]]/../../../../sysroot/nan2008"
+// CHECK-BE-NAN64-32R2-DEF: "[[TC]]/../../../../sysroot/nan2008/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-BE-NAN64-32R2-DEF: "[[TC]]/../../../../sysroot/nan2008/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-BE-NAN64-32R2-DEF: "[[TC]]/nan2008{{/|\\\\}}crtbegin.o"
+// CHECK-BE-NAN64-32R2-DEF: "-L[[TC]]/nan2008"
+// CHECK-BE-NAN64-32R2-DEF: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/nan2008"
+// CHECK-BE-NAN64-32R2-DEF: "-L[[TC]]/../../../../sysroot/nan2008/usr/lib/../lib"
+// CHECK-BE-NAN64-32R2-DEF: "[[TC]]/nan2008{{/|\\\\}}crtend.o"
+// CHECK-BE-NAN64-32R2-DEF: "[[TC]]/../../../../sysroot/nan2008/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
 // = Big-endian, micromips, hard float
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mips-linux-gnu -mmicromips -mhard-float \
@@ -328,16 +562,42 @@
 // CHECK-BE-HF-MM: "-internal-externc-isystem"
 // CHECK-BE-HF-MM: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-BE-HF-MM: "{{.*}}ld{{(.exe)?}}"
-// CHECK-BE-HF-MM: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/micromips"
+// CHECK-BE-HF-MM: "--sysroot=[[TC]]/../../../../sysroot/micromips"
 // CHECK-BE-HF-MM: "[[TC]]/../../../../sysroot/micromips/usr/lib/../lib{{/|\\\\}}crt1.o"
 // CHECK-BE-HF-MM: "[[TC]]/../../../../sysroot/micromips/usr/lib/../lib{{/|\\\\}}crti.o"
 // CHECK-BE-HF-MM: "[[TC]]/micromips{{/|\\\\}}crtbegin.o"
-// CHECK-BE-HF-MM: "-L[[SR]]/micromips"
-// CHECK-BE-HF-MM: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/../lib/micromips"
-// CHECK-BE-HF-MM: "-L[[SR]]/../../../../sysroot/micromips/usr/lib/../lib"
+// CHECK-BE-HF-MM: "-L[[TC]]/micromips"
+// CHECK-BE-HF-MM: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/micromips"
+// CHECK-BE-HF-MM: "-L[[TC]]/../../../../sysroot/micromips/usr/lib/../lib"
 // CHECK-BE-HF-MM: "[[TC]]/micromips{{/|\\\\}}crtend.o"
 // CHECK-BE-HF-MM: "[[TC]]/../../../../sysroot/micromips/usr/lib/../lib{{/|\\\\}}crtn.o"
 //
+// = Big-endian, micromips, fp64, hard float
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips-linux-gnu -mmicromips -mfp64 -mhard-float \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BE-HF64-MM %s
+// CHECK-BE-HF64-MM: "-internal-isystem"
+// CHECK-BE-HF64-MM: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-BE-HF64-MM: "-internal-isystem"
+// CHECK-BE-HF64-MM: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/micromips"
+// CHECK-BE-HF64-MM: "-internal-isystem"
+// CHECK-BE-HF64-MM: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-BE-HF64-MM: "-internal-externc-isystem"
+// CHECK-BE-HF64-MM: "[[TC]]/include"
+// CHECK-BE-HF64-MM: "-internal-externc-isystem"
+// CHECK-BE-HF64-MM: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-BE-HF64-MM: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-HF64-MM: "--sysroot=[[TC]]/../../../../sysroot/micromips"
+// CHECK-BE-HF64-MM: "[[TC]]/../../../../sysroot/micromips/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-BE-HF64-MM: "[[TC]]/../../../../sysroot/micromips/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-BE-HF64-MM: "[[TC]]/micromips{{/|\\\\}}crtbegin.o"
+// CHECK-BE-HF64-MM: "-L[[TC]]/micromips"
+// CHECK-BE-HF64-MM: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/micromips"
+// CHECK-BE-HF64-MM: "-L[[TC]]/../../../../sysroot/micromips/usr/lib/../lib"
+// CHECK-BE-HF64-MM: "[[TC]]/micromips{{/|\\\\}}crtend.o"
+// CHECK-BE-HF64-MM: "[[TC]]/../../../../sysroot/micromips/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
 // = Big-endian, micromips, soft float
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mips-linux-gnu -mmicromips -msoft-float \
@@ -354,13 +614,13 @@
 // CHECK-BE-SF-MM: "-internal-externc-isystem"
 // CHECK-BE-SF-MM: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-BE-SF-MM: "{{.*}}ld{{(.exe)?}}"
-// CHECK-BE-SF-MM: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/micromips/sof"
+// CHECK-BE-SF-MM: "--sysroot=[[TC]]/../../../../sysroot/micromips/sof"
 // CHECK-BE-SF-MM: "[[TC]]/../../../../sysroot/micromips/sof/usr/lib/../lib{{/|\\\\}}crt1.o"
 // CHECK-BE-SF-MM: "[[TC]]/../../../../sysroot/micromips/sof/usr/lib/../lib{{/|\\\\}}crti.o"
 // CHECK-BE-SF-MM: "[[TC]]/micromips/sof{{/|\\\\}}crtbegin.o"
-// CHECK-BE-SF-MM: "-L[[SR]]/micromips/sof"
-// CHECK-BE-SF-MM: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/../lib/micromips/sof"
-// CHECK-BE-SF-MM: "-L[[SR]]/../../../../sysroot/micromips/sof/usr/lib/../lib"
+// CHECK-BE-SF-MM: "-L[[TC]]/micromips/sof"
+// CHECK-BE-SF-MM: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/micromips/sof"
+// CHECK-BE-SF-MM: "-L[[TC]]/../../../../sysroot/micromips/sof/usr/lib/../lib"
 // CHECK-BE-SF-MM: "[[TC]]/micromips/sof{{/|\\\\}}crtend.o"
 // CHECK-BE-SF-MM: "[[TC]]/../../../../sysroot/micromips/sof/usr/lib/../lib{{/|\\\\}}crtn.o"
 //
@@ -380,16 +640,42 @@
 // CHECK-BE-NAN-MM: "-internal-externc-isystem"
 // CHECK-BE-NAN-MM: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-BE-NAN-MM: "{{.*}}ld{{(.exe)?}}"
-// CHECK-BE-NAN-MM: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/micromips/nan2008"
+// CHECK-BE-NAN-MM: "--sysroot=[[TC]]/../../../../sysroot/micromips/nan2008"
 // CHECK-BE-NAN-MM: "[[TC]]/../../../../sysroot/micromips/nan2008/usr/lib/../lib{{/|\\\\}}crt1.o"
 // CHECK-BE-NAN-MM: "[[TC]]/../../../../sysroot/micromips/nan2008/usr/lib/../lib{{/|\\\\}}crti.o"
 // CHECK-BE-NAN-MM: "[[TC]]/micromips/nan2008{{/|\\\\}}crtbegin.o"
-// CHECK-BE-NAN-MM: "-L[[SR]]/micromips/nan2008"
-// CHECK-BE-NAN-MM: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/../lib/micromips/nan2008"
-// CHECK-BE-NAN-MM: "-L[[SR]]/../../../../sysroot/micromips/nan2008/usr/lib/../lib"
+// CHECK-BE-NAN-MM: "-L[[TC]]/micromips/nan2008"
+// CHECK-BE-NAN-MM: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/micromips/nan2008"
+// CHECK-BE-NAN-MM: "-L[[TC]]/../../../../sysroot/micromips/nan2008/usr/lib/../lib"
 // CHECK-BE-NAN-MM: "[[TC]]/micromips/nan2008{{/|\\\\}}crtend.o"
 // CHECK-BE-NAN-MM: "[[TC]]/../../../../sysroot/micromips/nan2008/usr/lib/../lib{{/|\\\\}}crtn.o"
 //
+// = Big-endian, micromips, fp64, nan2008
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips-linux-gnu -mmicromips -mfp64 -mnan=2008 \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BE-NAN64-MM %s
+// CHECK-BE-NAN64-MM: "-internal-isystem"
+// CHECK-BE-NAN64-MM: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-BE-NAN64-MM: "-internal-isystem"
+// CHECK-BE-NAN64-MM: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/micromips/nan2008"
+// CHECK-BE-NAN64-MM: "-internal-isystem"
+// CHECK-BE-NAN64-MM: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-BE-NAN64-MM: "-internal-externc-isystem"
+// CHECK-BE-NAN64-MM: "[[TC]]/include"
+// CHECK-BE-NAN64-MM: "-internal-externc-isystem"
+// CHECK-BE-NAN64-MM: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-BE-NAN64-MM: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-NAN64-MM: "--sysroot=[[TC]]/../../../../sysroot/micromips/nan2008"
+// CHECK-BE-NAN64-MM: "[[TC]]/../../../../sysroot/micromips/nan2008/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-BE-NAN64-MM: "[[TC]]/../../../../sysroot/micromips/nan2008/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-BE-NAN64-MM: "[[TC]]/micromips/nan2008{{/|\\\\}}crtbegin.o"
+// CHECK-BE-NAN64-MM: "-L[[TC]]/micromips/nan2008"
+// CHECK-BE-NAN64-MM: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/micromips/nan2008"
+// CHECK-BE-NAN64-MM: "-L[[TC]]/../../../../sysroot/micromips/nan2008/usr/lib/../lib"
+// CHECK-BE-NAN64-MM: "[[TC]]/micromips/nan2008{{/|\\\\}}crtend.o"
+// CHECK-BE-NAN64-MM: "[[TC]]/../../../../sysroot/micromips/nan2008/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
 // = Big-endian, mips64, ABI n32, hard float
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mips64-linux-gnu -mips64 -mabi=n32 -mhard-float \
@@ -406,16 +692,42 @@
 // CHECK-BE-HF-64-N32: "-internal-externc-isystem"
 // CHECK-BE-HF-64-N32: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-BE-HF-64-N32: "{{.*}}ld{{(.exe)?}}"
-// CHECK-BE-HF-64-N32: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips64"
+// CHECK-BE-HF-64-N32: "--sysroot=[[TC]]/../../../../sysroot/mips64"
 // CHECK-BE-HF-64-N32: "[[TC]]/../../../../sysroot/mips64/usr/lib{{/|\\\\}}crt1.o"
 // CHECK-BE-HF-64-N32: "[[TC]]/../../../../sysroot/mips64/usr/lib{{/|\\\\}}crti.o"
 // CHECK-BE-HF-64-N32: "[[TC]]/mips64{{/|\\\\}}crtbegin.o"
-// CHECK-BE-HF-64-N32: "-L[[SR]]/mips64"
-// CHECK-BE-HF-64-N32: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/mips64"
-// CHECK-BE-HF-64-N32: "-L[[SR]]/../../../../sysroot/mips64/usr/lib"
+// CHECK-BE-HF-64-N32: "-L[[TC]]/mips64"
+// CHECK-BE-HF-64-N32: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64"
+// CHECK-BE-HF-64-N32: "-L[[TC]]/../../../../sysroot/mips64/usr/lib"
 // CHECK-BE-HF-64-N32: "[[TC]]/mips64{{/|\\\\}}crtend.o"
 // CHECK-BE-HF-64-N32: "[[TC]]/../../../../sysroot/mips64/usr/lib{{/|\\\\}}crtn.o"
 //
+// = Big-endian, mips64, ABI n32, fp64, hard float
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64-linux-gnu -mips64 -mabi=n32 -mfp64 -mhard-float \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BE-HF64-64-N32 %s
+// CHECK-BE-HF64-64-N32: "-internal-isystem"
+// CHECK-BE-HF64-64-N32: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-BE-HF64-64-N32: "-internal-isystem"
+// CHECK-BE-HF64-64-N32: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/mips64"
+// CHECK-BE-HF64-64-N32: "-internal-isystem"
+// CHECK-BE-HF64-64-N32: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-BE-HF64-64-N32: "-internal-externc-isystem"
+// CHECK-BE-HF64-64-N32: "[[TC]]/include"
+// CHECK-BE-HF64-64-N32: "-internal-externc-isystem"
+// CHECK-BE-HF64-64-N32: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-BE-HF64-64-N32: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-HF64-64-N32: "--sysroot=[[TC]]/../../../../sysroot/mips64"
+// CHECK-BE-HF64-64-N32: "[[TC]]/../../../../sysroot/mips64/usr/lib{{/|\\\\}}crt1.o"
+// CHECK-BE-HF64-64-N32: "[[TC]]/../../../../sysroot/mips64/usr/lib{{/|\\\\}}crti.o"
+// CHECK-BE-HF64-64-N32: "[[TC]]/mips64{{/|\\\\}}crtbegin.o"
+// CHECK-BE-HF64-64-N32: "-L[[TC]]/mips64"
+// CHECK-BE-HF64-64-N32: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64"
+// CHECK-BE-HF64-64-N32: "-L[[TC]]/../../../../sysroot/mips64/usr/lib"
+// CHECK-BE-HF64-64-N32: "[[TC]]/mips64{{/|\\\\}}crtend.o"
+// CHECK-BE-HF64-64-N32: "[[TC]]/../../../../sysroot/mips64/usr/lib{{/|\\\\}}crtn.o"
+//
 // = Big-endian, mips64, ABI n32, soft float
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mips64-linux-gnu -mips64 -mabi=n32 -msoft-float \
@@ -432,13 +744,13 @@
 // CHECK-BE-SF-64-N32: "-internal-externc-isystem"
 // CHECK-BE-SF-64-N32: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-BE-SF-64-N32: "{{.*}}ld{{(.exe)?}}"
-// CHECK-BE-SF-64-N32: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips64/sof"
+// CHECK-BE-SF-64-N32: "--sysroot=[[TC]]/../../../../sysroot/mips64/sof"
 // CHECK-BE-SF-64-N32: "[[TC]]/../../../../sysroot/mips64/sof/usr/lib{{/|\\\\}}crt1.o"
 // CHECK-BE-SF-64-N32: "[[TC]]/../../../../sysroot/mips64/sof/usr/lib{{/|\\\\}}crti.o"
 // CHECK-BE-SF-64-N32: "[[TC]]/mips64/sof{{/|\\\\}}crtbegin.o"
-// CHECK-BE-SF-64-N32: "-L[[SR]]/mips64/sof"
-// CHECK-BE-SF-64-N32: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/mips64/sof"
-// CHECK-BE-SF-64-N32: "-L[[SR]]/../../../../sysroot/mips64/sof/usr/lib"
+// CHECK-BE-SF-64-N32: "-L[[TC]]/mips64/sof"
+// CHECK-BE-SF-64-N32: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64/sof"
+// CHECK-BE-SF-64-N32: "-L[[TC]]/../../../../sysroot/mips64/sof/usr/lib"
 // CHECK-BE-SF-64-N32: "[[TC]]/mips64/sof{{/|\\\\}}crtend.o"
 // CHECK-BE-SF-64-N32: "[[TC]]/../../../../sysroot/mips64/sof/usr/lib{{/|\\\\}}crtn.o"
 //
@@ -458,16 +770,42 @@
 // CHECK-BE-NAN-64-N32: "-internal-externc-isystem"
 // CHECK-BE-NAN-64-N32: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-BE-NAN-64-N32: "{{.*}}ld{{(.exe)?}}"
-// CHECK-BE-NAN-64-N32: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips64/nan2008"
+// CHECK-BE-NAN-64-N32: "--sysroot=[[TC]]/../../../../sysroot/mips64/nan2008"
 // CHECK-BE-NAN-64-N32: "[[TC]]/../../../../sysroot/mips64/nan2008/usr/lib{{/|\\\\}}crt1.o"
 // CHECK-BE-NAN-64-N32: "[[TC]]/../../../../sysroot/mips64/nan2008/usr/lib{{/|\\\\}}crti.o"
 // CHECK-BE-NAN-64-N32: "[[TC]]/mips64/nan2008{{/|\\\\}}crtbegin.o"
-// CHECK-BE-NAN-64-N32: "-L[[SR]]/mips64/nan2008"
-// CHECK-BE-NAN-64-N32: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/mips64/nan2008"
-// CHECK-BE-NAN-64-N32: "-L[[SR]]/../../../../sysroot/mips64/nan2008/usr/lib"
+// CHECK-BE-NAN-64-N32: "-L[[TC]]/mips64/nan2008"
+// CHECK-BE-NAN-64-N32: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64/nan2008"
+// CHECK-BE-NAN-64-N32: "-L[[TC]]/../../../../sysroot/mips64/nan2008/usr/lib"
 // CHECK-BE-NAN-64-N32: "[[TC]]/mips64/nan2008{{/|\\\\}}crtend.o"
 // CHECK-BE-NAN-64-N32: "[[TC]]/../../../../sysroot/mips64/nan2008/usr/lib{{/|\\\\}}crtn.o"
 //
+// = Big-endian, mips64, ABI n32, fp64, nan2008
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64-linux-gnu -mips64 -mabi=n32 -mfp64 -mnan=2008 \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BE-NAN64-64-N32 %s
+// CHECK-BE-NAN64-64-N32: "-internal-isystem"
+// CHECK-BE-NAN64-64-N32: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-BE-NAN64-64-N32: "-internal-isystem"
+// CHECK-BE-NAN64-64-N32: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/mips64/nan2008"
+// CHECK-BE-NAN64-64-N32: "-internal-isystem"
+// CHECK-BE-NAN64-64-N32: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-BE-NAN64-64-N32: "-internal-externc-isystem"
+// CHECK-BE-NAN64-64-N32: "[[TC]]/include"
+// CHECK-BE-NAN64-64-N32: "-internal-externc-isystem"
+// CHECK-BE-NAN64-64-N32: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-BE-NAN64-64-N32: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-NAN64-64-N32: "--sysroot=[[TC]]/../../../../sysroot/mips64/nan2008"
+// CHECK-BE-NAN64-64-N32: "[[TC]]/../../../../sysroot/mips64/nan2008/usr/lib{{/|\\\\}}crt1.o"
+// CHECK-BE-NAN64-64-N32: "[[TC]]/../../../../sysroot/mips64/nan2008/usr/lib{{/|\\\\}}crti.o"
+// CHECK-BE-NAN64-64-N32: "[[TC]]/mips64/nan2008{{/|\\\\}}crtbegin.o"
+// CHECK-BE-NAN64-64-N32: "-L[[TC]]/mips64/nan2008"
+// CHECK-BE-NAN64-64-N32: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64/nan2008"
+// CHECK-BE-NAN64-64-N32: "-L[[TC]]/../../../../sysroot/mips64/nan2008/usr/lib"
+// CHECK-BE-NAN64-64-N32: "[[TC]]/mips64/nan2008{{/|\\\\}}crtend.o"
+// CHECK-BE-NAN64-64-N32: "[[TC]]/../../../../sysroot/mips64/nan2008/usr/lib{{/|\\\\}}crtn.o"
+//
 // = Big-endian, mips64, ABI 64, hard float
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mips64-linux-gnu -mips64 -mabi=64 -mhard-float \
@@ -484,16 +822,42 @@
 // CHECK-BE-HF-64-64: "-internal-externc-isystem"
 // CHECK-BE-HF-64-64: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-BE-HF-64-64: "{{.*}}ld{{(.exe)?}}"
-// CHECK-BE-HF-64-64: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips64/64"
+// CHECK-BE-HF-64-64: "--sysroot=[[TC]]/../../../../sysroot/mips64/64"
 // CHECK-BE-HF-64-64: "[[TC]]/../../../../sysroot/mips64/64/usr/lib{{/|\\\\}}crt1.o"
 // CHECK-BE-HF-64-64: "[[TC]]/../../../../sysroot/mips64/64/usr/lib{{/|\\\\}}crti.o"
 // CHECK-BE-HF-64-64: "[[TC]]/mips64/64{{/|\\\\}}crtbegin.o"
-// CHECK-BE-HF-64-64: "-L[[SR]]/mips64/64"
-// CHECK-BE-HF-64-64: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/mips64/64"
-// CHECK-BE-HF-64-64: "-L[[SR]]/../../../../sysroot/mips64/64/usr/lib"
+// CHECK-BE-HF-64-64: "-L[[TC]]/mips64/64"
+// CHECK-BE-HF-64-64: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64/64"
+// CHECK-BE-HF-64-64: "-L[[TC]]/../../../../sysroot/mips64/64/usr/lib"
 // CHECK-BE-HF-64-64: "[[TC]]/mips64/64{{/|\\\\}}crtend.o"
 // CHECK-BE-HF-64-64: "[[TC]]/../../../../sysroot/mips64/64/usr/lib{{/|\\\\}}crtn.o"
 //
+// = Big-endian, mips64, ABI 64, fp64, hard float
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64-linux-gnu -mips64 -mabi=64 -mfp64 -mhard-float \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BE-HF64-64-64 %s
+// CHECK-BE-HF64-64-64: "-internal-isystem"
+// CHECK-BE-HF64-64-64: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-BE-HF64-64-64: "-internal-isystem"
+// CHECK-BE-HF64-64-64: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/mips64/64"
+// CHECK-BE-HF64-64-64: "-internal-isystem"
+// CHECK-BE-HF64-64-64: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-BE-HF64-64-64: "-internal-externc-isystem"
+// CHECK-BE-HF64-64-64: "[[TC]]/include"
+// CHECK-BE-HF64-64-64: "-internal-externc-isystem"
+// CHECK-BE-HF64-64-64: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-BE-HF64-64-64: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-HF64-64-64: "--sysroot=[[TC]]/../../../../sysroot/mips64/64"
+// CHECK-BE-HF64-64-64: "[[TC]]/../../../../sysroot/mips64/64/usr/lib{{/|\\\\}}crt1.o"
+// CHECK-BE-HF64-64-64: "[[TC]]/../../../../sysroot/mips64/64/usr/lib{{/|\\\\}}crti.o"
+// CHECK-BE-HF64-64-64: "[[TC]]/mips64/64{{/|\\\\}}crtbegin.o"
+// CHECK-BE-HF64-64-64: "-L[[TC]]/mips64/64"
+// CHECK-BE-HF64-64-64: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64/64"
+// CHECK-BE-HF64-64-64: "-L[[TC]]/../../../../sysroot/mips64/64/usr/lib"
+// CHECK-BE-HF64-64-64: "[[TC]]/mips64/64{{/|\\\\}}crtend.o"
+// CHECK-BE-HF64-64-64: "[[TC]]/../../../../sysroot/mips64/64/usr/lib{{/|\\\\}}crtn.o"
+//
 // = Big-endian, mips64, ABI 64, soft float
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mips64-linux-gnu -mips64 -mabi=64 -msoft-float \
@@ -510,13 +874,13 @@
 // CHECK-BE-SF-64-64: "-internal-externc-isystem"
 // CHECK-BE-SF-64-64: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-BE-SF-64-64: "{{.*}}ld{{(.exe)?}}"
-// CHECK-BE-SF-64-64: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips64/64/sof"
+// CHECK-BE-SF-64-64: "--sysroot=[[TC]]/../../../../sysroot/mips64/64/sof"
 // CHECK-BE-SF-64-64: "[[TC]]/../../../../sysroot/mips64/64/sof/usr/lib{{/|\\\\}}crt1.o"
 // CHECK-BE-SF-64-64: "[[TC]]/../../../../sysroot/mips64/64/sof/usr/lib{{/|\\\\}}crti.o"
 // CHECK-BE-SF-64-64: "[[TC]]/mips64/64/sof{{/|\\\\}}crtbegin.o"
-// CHECK-BE-SF-64-64: "-L[[SR]]/mips64/64/sof"
-// CHECK-BE-SF-64-64: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/mips64/64/sof"
-// CHECK-BE-SF-64-64: "-L[[SR]]/../../../../sysroot/mips64/64/sof/usr/lib"
+// CHECK-BE-SF-64-64: "-L[[TC]]/mips64/64/sof"
+// CHECK-BE-SF-64-64: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64/64/sof"
+// CHECK-BE-SF-64-64: "-L[[TC]]/../../../../sysroot/mips64/64/sof/usr/lib"
 // CHECK-BE-SF-64-64: "[[TC]]/mips64/64/sof{{/|\\\\}}crtend.o"
 // CHECK-BE-SF-64-64: "[[TC]]/../../../../sysroot/mips64/64/sof/usr/lib{{/|\\\\}}crtn.o"
 //
@@ -536,16 +900,42 @@
 // CHECK-BE-NAN-64-64: "-internal-externc-isystem"
 // CHECK-BE-NAN-64-64: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-BE-NAN-64-64: "{{.*}}ld{{(.exe)?}}"
-// CHECK-BE-NAN-64-64: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips64/64/nan2008"
+// CHECK-BE-NAN-64-64: "--sysroot=[[TC]]/../../../../sysroot/mips64/64/nan2008"
 // CHECK-BE-NAN-64-64: "[[TC]]/../../../../sysroot/mips64/64/nan2008/usr/lib{{/|\\\\}}crt1.o"
 // CHECK-BE-NAN-64-64: "[[TC]]/../../../../sysroot/mips64/64/nan2008/usr/lib{{/|\\\\}}crti.o"
 // CHECK-BE-NAN-64-64: "[[TC]]/mips64/64/nan2008{{/|\\\\}}crtbegin.o"
-// CHECK-BE-NAN-64-64: "-L[[SR]]/mips64/64/nan2008"
-// CHECK-BE-NAN-64-64: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/mips64/64/nan2008"
-// CHECK-BE-NAN-64-64: "-L[[SR]]/../../../../sysroot/mips64/64/nan2008/usr/lib"
+// CHECK-BE-NAN-64-64: "-L[[TC]]/mips64/64/nan2008"
+// CHECK-BE-NAN-64-64: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64/64/nan2008"
+// CHECK-BE-NAN-64-64: "-L[[TC]]/../../../../sysroot/mips64/64/nan2008/usr/lib"
 // CHECK-BE-NAN-64-64: "[[TC]]/mips64/64/nan2008{{/|\\\\}}crtend.o"
 // CHECK-BE-NAN-64-64: "[[TC]]/../../../../sysroot/mips64/64/nan2008/usr/lib{{/|\\\\}}crtn.o"
 //
+// = Big-endian, mips64, ABI 64, fp64, nan2008
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64-linux-gnu -mips64 -mabi=64 -mfp64 -mnan=2008 \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BE-NAN64-64-64 %s
+// CHECK-BE-NAN64-64-64: "-internal-isystem"
+// CHECK-BE-NAN64-64-64: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-BE-NAN64-64-64: "-internal-isystem"
+// CHECK-BE-NAN64-64-64: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/mips64/64/nan2008"
+// CHECK-BE-NAN64-64-64: "-internal-isystem"
+// CHECK-BE-NAN64-64-64: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-BE-NAN64-64-64: "-internal-externc-isystem"
+// CHECK-BE-NAN64-64-64: "[[TC]]/include"
+// CHECK-BE-NAN64-64-64: "-internal-externc-isystem"
+// CHECK-BE-NAN64-64-64: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-BE-NAN64-64-64: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-NAN64-64-64: "--sysroot=[[TC]]/../../../../sysroot/mips64/64/nan2008"
+// CHECK-BE-NAN64-64-64: "[[TC]]/../../../../sysroot/mips64/64/nan2008/usr/lib{{/|\\\\}}crt1.o"
+// CHECK-BE-NAN64-64-64: "[[TC]]/../../../../sysroot/mips64/64/nan2008/usr/lib{{/|\\\\}}crti.o"
+// CHECK-BE-NAN64-64-64: "[[TC]]/mips64/64/nan2008{{/|\\\\}}crtbegin.o"
+// CHECK-BE-NAN64-64-64: "-L[[TC]]/mips64/64/nan2008"
+// CHECK-BE-NAN64-64-64: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64/64/nan2008"
+// CHECK-BE-NAN64-64-64: "-L[[TC]]/../../../../sysroot/mips64/64/nan2008/usr/lib"
+// CHECK-BE-NAN64-64-64: "[[TC]]/mips64/64/nan2008{{/|\\\\}}crtend.o"
+// CHECK-BE-NAN64-64-64: "[[TC]]/../../../../sysroot/mips64/64/nan2008/usr/lib{{/|\\\\}}crtn.o"
+//
 // = Big-endian, mips64r2, ABI n32, hard float
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mips64-linux-gnu -mips64r2 -mabi=n32 -mhard-float \
@@ -562,16 +952,42 @@
 // CHECK-BE-HF-64R2-N32: "-internal-externc-isystem"
 // CHECK-BE-HF-64R2-N32: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-BE-HF-64R2-N32: "{{.*}}ld{{(.exe)?}}"
-// CHECK-BE-HF-64R2-N32: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips64r2"
+// CHECK-BE-HF-64R2-N32: "--sysroot=[[TC]]/../../../../sysroot/mips64r2"
 // CHECK-BE-HF-64R2-N32: "[[TC]]/../../../../sysroot/mips64r2/usr/lib{{/|\\\\}}crt1.o"
 // CHECK-BE-HF-64R2-N32: "[[TC]]/../../../../sysroot/mips64r2/usr/lib{{/|\\\\}}crti.o"
 // CHECK-BE-HF-64R2-N32: "[[TC]]/mips64r2{{/|\\\\}}crtbegin.o"
-// CHECK-BE-HF-64R2-N32: "-L[[SR]]/mips64r2"
-// CHECK-BE-HF-64R2-N32: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/mips64r2"
-// CHECK-BE-HF-64R2-N32: "-L[[SR]]/../../../../sysroot/mips64r2/usr/lib"
+// CHECK-BE-HF-64R2-N32: "-L[[TC]]/mips64r2"
+// CHECK-BE-HF-64R2-N32: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64r2"
+// CHECK-BE-HF-64R2-N32: "-L[[TC]]/../../../../sysroot/mips64r2/usr/lib"
 // CHECK-BE-HF-64R2-N32: "[[TC]]/mips64r2{{/|\\\\}}crtend.o"
 // CHECK-BE-HF-64R2-N32: "[[TC]]/../../../../sysroot/mips64r2/usr/lib{{/|\\\\}}crtn.o"
 //
+// = Big-endian, mips64r2, ABI n32, fp64, hard float
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64-linux-gnu -mips64r2 -mabi=n32 -mfp64 -mhard-float \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BE-HF64-64R2-N32 %s
+// CHECK-BE-HF64-64R2-N32: "-internal-isystem"
+// CHECK-BE-HF64-64R2-N32: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-BE-HF64-64R2-N32: "-internal-isystem"
+// CHECK-BE-HF64-64R2-N32: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/mips64r2"
+// CHECK-BE-HF64-64R2-N32: "-internal-isystem"
+// CHECK-BE-HF64-64R2-N32: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-BE-HF64-64R2-N32: "-internal-externc-isystem"
+// CHECK-BE-HF64-64R2-N32: "[[TC]]/include"
+// CHECK-BE-HF64-64R2-N32: "-internal-externc-isystem"
+// CHECK-BE-HF64-64R2-N32: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-BE-HF64-64R2-N32: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-HF64-64R2-N32: "--sysroot=[[TC]]/../../../../sysroot/mips64r2"
+// CHECK-BE-HF64-64R2-N32: "[[TC]]/../../../../sysroot/mips64r2/usr/lib{{/|\\\\}}crt1.o"
+// CHECK-BE-HF64-64R2-N32: "[[TC]]/../../../../sysroot/mips64r2/usr/lib{{/|\\\\}}crti.o"
+// CHECK-BE-HF64-64R2-N32: "[[TC]]/mips64r2{{/|\\\\}}crtbegin.o"
+// CHECK-BE-HF64-64R2-N32: "-L[[TC]]/mips64r2"
+// CHECK-BE-HF64-64R2-N32: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64r2"
+// CHECK-BE-HF64-64R2-N32: "-L[[TC]]/../../../../sysroot/mips64r2/usr/lib"
+// CHECK-BE-HF64-64R2-N32: "[[TC]]/mips64r2{{/|\\\\}}crtend.o"
+// CHECK-BE-HF64-64R2-N32: "[[TC]]/../../../../sysroot/mips64r2/usr/lib{{/|\\\\}}crtn.o"
+//
 // = Big-endian, mips64r2, ABI n32, soft float
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mips64-linux-gnu -mips64r2 -mabi=n32 -msoft-float \
@@ -588,13 +1004,13 @@
 // CHECK-BE-SF-64R2-N32: "-internal-externc-isystem"
 // CHECK-BE-SF-64R2-N32: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-BE-SF-64R2-N32: "{{.*}}ld{{(.exe)?}}"
-// CHECK-BE-SF-64R2-N32: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips64r2/sof"
+// CHECK-BE-SF-64R2-N32: "--sysroot=[[TC]]/../../../../sysroot/mips64r2/sof"
 // CHECK-BE-SF-64R2-N32: "[[TC]]/../../../../sysroot/mips64r2/sof/usr/lib{{/|\\\\}}crt1.o"
 // CHECK-BE-SF-64R2-N32: "[[TC]]/../../../../sysroot/mips64r2/sof/usr/lib{{/|\\\\}}crti.o"
 // CHECK-BE-SF-64R2-N32: "[[TC]]/mips64r2/sof{{/|\\\\}}crtbegin.o"
-// CHECK-BE-SF-64R2-N32: "-L[[SR]]/mips64r2/sof"
-// CHECK-BE-SF-64R2-N32: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/mips64r2/sof"
-// CHECK-BE-SF-64R2-N32: "-L[[SR]]/../../../../sysroot/mips64r2/sof/usr/lib"
+// CHECK-BE-SF-64R2-N32: "-L[[TC]]/mips64r2/sof"
+// CHECK-BE-SF-64R2-N32: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64r2/sof"
+// CHECK-BE-SF-64R2-N32: "-L[[TC]]/../../../../sysroot/mips64r2/sof/usr/lib"
 // CHECK-BE-SF-64R2-N32: "[[TC]]/mips64r2/sof{{/|\\\\}}crtend.o"
 // CHECK-BE-SF-64R2-N32: "[[TC]]/../../../../sysroot/mips64r2/sof/usr/lib{{/|\\\\}}crtn.o"
 //
@@ -614,16 +1030,42 @@
 // CHECK-BE-NAN-64R2-N32: "-internal-externc-isystem"
 // CHECK-BE-NAN-64R2-N32: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-BE-NAN-64R2-N32: "{{.*}}ld{{(.exe)?}}"
-// CHECK-BE-NAN-64R2-N32: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips64r2/nan2008"
+// CHECK-BE-NAN-64R2-N32: "--sysroot=[[TC]]/../../../../sysroot/mips64r2/nan2008"
 // CHECK-BE-NAN-64R2-N32: "[[TC]]/../../../../sysroot/mips64r2/nan2008/usr/lib{{/|\\\\}}crt1.o"
 // CHECK-BE-NAN-64R2-N32: "[[TC]]/../../../../sysroot/mips64r2/nan2008/usr/lib{{/|\\\\}}crti.o"
 // CHECK-BE-NAN-64R2-N32: "[[TC]]/mips64r2/nan2008{{/|\\\\}}crtbegin.o"
-// CHECK-BE-NAN-64R2-N32: "-L[[SR]]/mips64r2/nan2008"
-// CHECK-BE-NAN-64R2-N32: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/mips64r2/nan2008"
-// CHECK-BE-NAN-64R2-N32: "-L[[SR]]/../../../../sysroot/mips64r2/nan2008/usr/lib"
+// CHECK-BE-NAN-64R2-N32: "-L[[TC]]/mips64r2/nan2008"
+// CHECK-BE-NAN-64R2-N32: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64r2/nan2008"
+// CHECK-BE-NAN-64R2-N32: "-L[[TC]]/../../../../sysroot/mips64r2/nan2008/usr/lib"
 // CHECK-BE-NAN-64R2-N32: "[[TC]]/mips64r2/nan2008{{/|\\\\}}crtend.o"
 // CHECK-BE-NAN-64R2-N32: "[[TC]]/../../../../sysroot/mips64r2/nan2008/usr/lib{{/|\\\\}}crtn.o"
 //
+// = Big-endian, mips64r2, ABI n32, fp64, nan2008
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64-linux-gnu -mips64r2 -mabi=n32 -mfp64 -mnan=2008 \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BE-NAN64-64R2-N32 %s
+// CHECK-BE-NAN64-64R2-N32: "-internal-isystem"
+// CHECK-BE-NAN64-64R2-N32: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-BE-NAN64-64R2-N32: "-internal-isystem"
+// CHECK-BE-NAN64-64R2-N32: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/mips64r2/nan2008"
+// CHECK-BE-NAN64-64R2-N32: "-internal-isystem"
+// CHECK-BE-NAN64-64R2-N32: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-BE-NAN64-64R2-N32: "-internal-externc-isystem"
+// CHECK-BE-NAN64-64R2-N32: "[[TC]]/include"
+// CHECK-BE-NAN64-64R2-N32: "-internal-externc-isystem"
+// CHECK-BE-NAN64-64R2-N32: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-BE-NAN64-64R2-N32: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-NAN64-64R2-N32: "--sysroot=[[TC]]/../../../../sysroot/mips64r2/nan2008"
+// CHECK-BE-NAN64-64R2-N32: "[[TC]]/../../../../sysroot/mips64r2/nan2008/usr/lib{{/|\\\\}}crt1.o"
+// CHECK-BE-NAN64-64R2-N32: "[[TC]]/../../../../sysroot/mips64r2/nan2008/usr/lib{{/|\\\\}}crti.o"
+// CHECK-BE-NAN64-64R2-N32: "[[TC]]/mips64r2/nan2008{{/|\\\\}}crtbegin.o"
+// CHECK-BE-NAN64-64R2-N32: "-L[[TC]]/mips64r2/nan2008"
+// CHECK-BE-NAN64-64R2-N32: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64r2/nan2008"
+// CHECK-BE-NAN64-64R2-N32: "-L[[TC]]/../../../../sysroot/mips64r2/nan2008/usr/lib"
+// CHECK-BE-NAN64-64R2-N32: "[[TC]]/mips64r2/nan2008{{/|\\\\}}crtend.o"
+// CHECK-BE-NAN64-64R2-N32: "[[TC]]/../../../../sysroot/mips64r2/nan2008/usr/lib{{/|\\\\}}crtn.o"
+//
 // = Big-endian, mips64r2, ABI 64, hard float
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mips64-linux-gnu -mips64r2 -mabi=64 -mhard-float \
@@ -640,16 +1082,42 @@
 // CHECK-BE-HF-64R2-64: "-internal-externc-isystem"
 // CHECK-BE-HF-64R2-64: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-BE-HF-64R2-64: "{{.*}}ld{{(.exe)?}}"
-// CHECK-BE-HF-64R2-64: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips64r2/64"
+// CHECK-BE-HF-64R2-64: "--sysroot=[[TC]]/../../../../sysroot/mips64r2/64"
 // CHECK-BE-HF-64R2-64: "[[TC]]/../../../../sysroot/mips64r2/64/usr/lib{{/|\\\\}}crt1.o"
 // CHECK-BE-HF-64R2-64: "[[TC]]/../../../../sysroot/mips64r2/64/usr/lib{{/|\\\\}}crti.o"
 // CHECK-BE-HF-64R2-64: "[[TC]]/mips64r2/64{{/|\\\\}}crtbegin.o"
-// CHECK-BE-HF-64R2-64: "-L[[SR]]/mips64r2/64"
-// CHECK-BE-HF-64R2-64: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/mips64r2/64"
-// CHECK-BE-HF-64R2-64: "-L[[SR]]/../../../../sysroot/mips64r2/64/usr/lib"
+// CHECK-BE-HF-64R2-64: "-L[[TC]]/mips64r2/64"
+// CHECK-BE-HF-64R2-64: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64r2/64"
+// CHECK-BE-HF-64R2-64: "-L[[TC]]/../../../../sysroot/mips64r2/64/usr/lib"
 // CHECK-BE-HF-64R2-64: "[[TC]]/mips64r2/64{{/|\\\\}}crtend.o"
 // CHECK-BE-HF-64R2-64: "[[TC]]/../../../../sysroot/mips64r2/64/usr/lib{{/|\\\\}}crtn.o"
 //
+// = Big-endian, mips64r2, ABI 64, fp64, hard float
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64-linux-gnu -mips64r2 -mabi=64 -mfp64 -mhard-float \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BE-HF64-64R2-64 %s
+// CHECK-BE-HF64-64R2-64: "-internal-isystem"
+// CHECK-BE-HF64-64R2-64: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-BE-HF64-64R2-64: "-internal-isystem"
+// CHECK-BE-HF64-64R2-64: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/mips64r2/64"
+// CHECK-BE-HF64-64R2-64: "-internal-isystem"
+// CHECK-BE-HF64-64R2-64: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-BE-HF64-64R2-64: "-internal-externc-isystem"
+// CHECK-BE-HF64-64R2-64: "[[TC]]/include"
+// CHECK-BE-HF64-64R2-64: "-internal-externc-isystem"
+// CHECK-BE-HF64-64R2-64: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-BE-HF64-64R2-64: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-HF64-64R2-64: "--sysroot=[[TC]]/../../../../sysroot/mips64r2/64"
+// CHECK-BE-HF64-64R2-64: "[[TC]]/../../../../sysroot/mips64r2/64/usr/lib{{/|\\\\}}crt1.o"
+// CHECK-BE-HF64-64R2-64: "[[TC]]/../../../../sysroot/mips64r2/64/usr/lib{{/|\\\\}}crti.o"
+// CHECK-BE-HF64-64R2-64: "[[TC]]/mips64r2/64{{/|\\\\}}crtbegin.o"
+// CHECK-BE-HF64-64R2-64: "-L[[TC]]/mips64r2/64"
+// CHECK-BE-HF64-64R2-64: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64r2/64"
+// CHECK-BE-HF64-64R2-64: "-L[[TC]]/../../../../sysroot/mips64r2/64/usr/lib"
+// CHECK-BE-HF64-64R2-64: "[[TC]]/mips64r2/64{{/|\\\\}}crtend.o"
+// CHECK-BE-HF64-64R2-64: "[[TC]]/../../../../sysroot/mips64r2/64/usr/lib{{/|\\\\}}crtn.o"
+//
 // = Big-endian, mips64r2, ABI 64, soft float
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mips64-linux-gnu -mips64r2 -mabi=64 -msoft-float \
@@ -666,13 +1134,13 @@
 // CHECK-BE-SF-64R2-64: "-internal-externc-isystem"
 // CHECK-BE-SF-64R2-64: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-BE-SF-64R2-64: "{{.*}}ld{{(.exe)?}}"
-// CHECK-BE-SF-64R2-64: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips64r2/64/sof"
+// CHECK-BE-SF-64R2-64: "--sysroot=[[TC]]/../../../../sysroot/mips64r2/64/sof"
 // CHECK-BE-SF-64R2-64: "[[TC]]/../../../../sysroot/mips64r2/64/sof/usr/lib{{/|\\\\}}crt1.o"
 // CHECK-BE-SF-64R2-64: "[[TC]]/../../../../sysroot/mips64r2/64/sof/usr/lib{{/|\\\\}}crti.o"
 // CHECK-BE-SF-64R2-64: "[[TC]]/mips64r2/64/sof{{/|\\\\}}crtbegin.o"
-// CHECK-BE-SF-64R2-64: "-L[[SR]]/mips64r2/64/sof"
-// CHECK-BE-SF-64R2-64: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/mips64r2/64/sof"
-// CHECK-BE-SF-64R2-64: "-L[[SR]]/../../../../sysroot/mips64r2/64/sof/usr/lib"
+// CHECK-BE-SF-64R2-64: "-L[[TC]]/mips64r2/64/sof"
+// CHECK-BE-SF-64R2-64: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64r2/64/sof"
+// CHECK-BE-SF-64R2-64: "-L[[TC]]/../../../../sysroot/mips64r2/64/sof/usr/lib"
 // CHECK-BE-SF-64R2-64: "[[TC]]/mips64r2/64/sof{{/|\\\\}}crtend.o"
 // CHECK-BE-SF-64R2-64: "[[TC]]/../../../../sysroot/mips64r2/64/sof/usr/lib{{/|\\\\}}crtn.o"
 //
@@ -692,16 +1160,68 @@
 // CHECK-BE-NAN-64R2-64: "-internal-externc-isystem"
 // CHECK-BE-NAN-64R2-64: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-BE-NAN-64R2-64: "{{.*}}ld{{(.exe)?}}"
-// CHECK-BE-NAN-64R2-64: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips64r2/64/nan2008"
+// CHECK-BE-NAN-64R2-64: "--sysroot=[[TC]]/../../../../sysroot/mips64r2/64/nan2008"
 // CHECK-BE-NAN-64R2-64: "[[TC]]/../../../../sysroot/mips64r2/64/nan2008/usr/lib{{/|\\\\}}crt1.o"
 // CHECK-BE-NAN-64R2-64: "[[TC]]/../../../../sysroot/mips64r2/64/nan2008/usr/lib{{/|\\\\}}crti.o"
 // CHECK-BE-NAN-64R2-64: "[[TC]]/mips64r2/64/nan2008{{/|\\\\}}crtbegin.o"
-// CHECK-BE-NAN-64R2-64: "-L[[SR]]/mips64r2/64/nan2008"
-// CHECK-BE-NAN-64R2-64: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/mips64r2/64/nan2008"
-// CHECK-BE-NAN-64R2-64: "-L[[SR]]/../../../../sysroot/mips64r2/64/nan2008/usr/lib"
+// CHECK-BE-NAN-64R2-64: "-L[[TC]]/mips64r2/64/nan2008"
+// CHECK-BE-NAN-64R2-64: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64r2/64/nan2008"
+// CHECK-BE-NAN-64R2-64: "-L[[TC]]/../../../../sysroot/mips64r2/64/nan2008/usr/lib"
 // CHECK-BE-NAN-64R2-64: "[[TC]]/mips64r2/64/nan2008{{/|\\\\}}crtend.o"
 // CHECK-BE-NAN-64R2-64: "[[TC]]/../../../../sysroot/mips64r2/64/nan2008/usr/lib{{/|\\\\}}crtn.o"
 //
+// = Big-endian, mips64r2, ABI 64, fp64, nan2008
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64-linux-gnu -mips64r2 -mabi=64 -mfp64 -mnan=2008 \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BE-NAN64-64R2-64 %s
+// CHECK-BE-NAN64-64R2-64: "-internal-isystem"
+// CHECK-BE-NAN64-64R2-64: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-BE-NAN64-64R2-64: "-internal-isystem"
+// CHECK-BE-NAN64-64R2-64: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/mips64r2/64/nan2008"
+// CHECK-BE-NAN64-64R2-64: "-internal-isystem"
+// CHECK-BE-NAN64-64R2-64: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-BE-NAN64-64R2-64: "-internal-externc-isystem"
+// CHECK-BE-NAN64-64R2-64: "[[TC]]/include"
+// CHECK-BE-NAN64-64R2-64: "-internal-externc-isystem"
+// CHECK-BE-NAN64-64R2-64: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-BE-NAN64-64R2-64: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-NAN64-64R2-64: "--sysroot=[[TC]]/../../../../sysroot/mips64r2/64/nan2008"
+// CHECK-BE-NAN64-64R2-64: "[[TC]]/../../../../sysroot/mips64r2/64/nan2008/usr/lib{{/|\\\\}}crt1.o"
+// CHECK-BE-NAN64-64R2-64: "[[TC]]/../../../../sysroot/mips64r2/64/nan2008/usr/lib{{/|\\\\}}crti.o"
+// CHECK-BE-NAN64-64R2-64: "[[TC]]/mips64r2/64/nan2008{{/|\\\\}}crtbegin.o"
+// CHECK-BE-NAN64-64R2-64: "-L[[TC]]/mips64r2/64/nan2008"
+// CHECK-BE-NAN64-64R2-64: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64r2/64/nan2008"
+// CHECK-BE-NAN64-64R2-64: "-L[[TC]]/../../../../sysroot/mips64r2/64/nan2008/usr/lib"
+// CHECK-BE-NAN64-64R2-64: "[[TC]]/mips64r2/64/nan2008{{/|\\\\}}crtend.o"
+// CHECK-BE-NAN64-64R2-64: "[[TC]]/../../../../sysroot/mips64r2/64/nan2008/usr/lib{{/|\\\\}}crtn.o"
+//
+// = Big-endian, default (mips64r2), ABI 64, fp64, nan2008
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64-linux-gnu -mabi=64 -mfp64 -mnan=2008 \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BE-NAN64-64R2-64-DEF %s
+// CHECK-BE-NAN64-64R2-64-DEF: "-internal-isystem"
+// CHECK-BE-NAN64-64R2-64-DEF: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-BE-NAN64-64R2-64-DEF: "-internal-isystem"
+// CHECK-BE-NAN64-64R2-64-DEF: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/mips64r2/64/nan2008"
+// CHECK-BE-NAN64-64R2-64-DEF: "-internal-isystem"
+// CHECK-BE-NAN64-64R2-64-DEF: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-BE-NAN64-64R2-64-DEF: "-internal-externc-isystem"
+// CHECK-BE-NAN64-64R2-64-DEF: "[[TC]]/include"
+// CHECK-BE-NAN64-64R2-64-DEF: "-internal-externc-isystem"
+// CHECK-BE-NAN64-64R2-64-DEF: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-BE-NAN64-64R2-64-DEF: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-NAN64-64R2-64-DEF: "--sysroot=[[TC]]/../../../../sysroot/mips64r2/64/nan2008"
+// CHECK-BE-NAN64-64R2-64-DEF: "[[TC]]/../../../../sysroot/mips64r2/64/nan2008/usr/lib{{/|\\\\}}crt1.o"
+// CHECK-BE-NAN64-64R2-64-DEF: "[[TC]]/../../../../sysroot/mips64r2/64/nan2008/usr/lib{{/|\\\\}}crti.o"
+// CHECK-BE-NAN64-64R2-64-DEF: "[[TC]]/mips64r2/64/nan2008{{/|\\\\}}crtbegin.o"
+// CHECK-BE-NAN64-64R2-64-DEF: "-L[[TC]]/mips64r2/64/nan2008"
+// CHECK-BE-NAN64-64R2-64-DEF: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64r2/64/nan2008"
+// CHECK-BE-NAN64-64R2-64-DEF: "-L[[TC]]/../../../../sysroot/mips64r2/64/nan2008/usr/lib"
+// CHECK-BE-NAN64-64R2-64-DEF: "[[TC]]/mips64r2/64/nan2008{{/|\\\\}}crtend.o"
+// CHECK-BE-NAN64-64R2-64-DEF: "[[TC]]/../../../../sysroot/mips64r2/64/nan2008/usr/lib{{/|\\\\}}crtn.o"
+//
 // = Little-endian, mips32, hard float
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mipsel-linux-gnu -mips32 -mhard-float \
@@ -718,16 +1238,42 @@
 // CHECK-EL-HF-32: "-internal-externc-isystem"
 // CHECK-EL-HF-32: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-EL-HF-32: "{{.*}}ld{{(.exe)?}}"
-// CHECK-EL-HF-32: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips32/el"
+// CHECK-EL-HF-32: "--sysroot=[[TC]]/../../../../sysroot/mips32/el"
 // CHECK-EL-HF-32: "[[TC]]/../../../../sysroot/mips32/el/usr/lib/../lib{{/|\\\\}}crt1.o"
 // CHECK-EL-HF-32: "[[TC]]/../../../../sysroot/mips32/el/usr/lib/../lib{{/|\\\\}}crti.o"
 // CHECK-EL-HF-32: "[[TC]]/mips32/el{{/|\\\\}}crtbegin.o"
-// CHECK-EL-HF-32: "-L[[SR]]/mips32/el"
-// CHECK-EL-HF-32: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/../lib/mips32/el"
-// CHECK-EL-HF-32: "-L[[SR]]/../../../../sysroot/mips32/el/usr/lib/../lib"
+// CHECK-EL-HF-32: "-L[[TC]]/mips32/el"
+// CHECK-EL-HF-32: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/mips32/el"
+// CHECK-EL-HF-32: "-L[[TC]]/../../../../sysroot/mips32/el/usr/lib/../lib"
 // CHECK-EL-HF-32: "[[TC]]/mips32/el{{/|\\\\}}crtend.o"
 // CHECK-EL-HF-32: "[[TC]]/../../../../sysroot/mips32/el/usr/lib/../lib{{/|\\\\}}crtn.o"
 //
+// = Little-endian, mips32, fp64, hard float
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mipsel-linux-gnu -mips32 -mfp64 -mhard-float \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-EL-HF64-32 %s
+// CHECK-EL-HF64-32: "-internal-isystem"
+// CHECK-EL-HF64-32: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-EL-HF64-32: "-internal-isystem"
+// CHECK-EL-HF64-32: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/mips32/el"
+// CHECK-EL-HF64-32: "-internal-isystem"
+// CHECK-EL-HF64-32: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-EL-HF64-32: "-internal-externc-isystem"
+// CHECK-EL-HF64-32: "[[TC]]/include"
+// CHECK-EL-HF64-32: "-internal-externc-isystem"
+// CHECK-EL-HF64-32: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-EL-HF64-32: "{{.*}}ld{{(.exe)?}}"
+// CHECK-EL-HF64-32: "--sysroot=[[TC]]/../../../../sysroot/mips32/el"
+// CHECK-EL-HF64-32: "[[TC]]/../../../../sysroot/mips32/el/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-EL-HF64-32: "[[TC]]/../../../../sysroot/mips32/el/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-EL-HF64-32: "[[TC]]/mips32/el{{/|\\\\}}crtbegin.o"
+// CHECK-EL-HF64-32: "-L[[TC]]/mips32/el"
+// CHECK-EL-HF64-32: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/mips32/el"
+// CHECK-EL-HF64-32: "-L[[TC]]/../../../../sysroot/mips32/el/usr/lib/../lib"
+// CHECK-EL-HF64-32: "[[TC]]/mips32/el{{/|\\\\}}crtend.o"
+// CHECK-EL-HF64-32: "[[TC]]/../../../../sysroot/mips32/el/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
 // = Little-endian, mips32, soft float
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mipsel-linux-gnu -mips32 -msoft-float \
@@ -744,13 +1290,13 @@
 // CHECK-EL-SF-32: "-internal-externc-isystem"
 // CHECK-EL-SF-32: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-EL-SF-32: "{{.*}}ld{{(.exe)?}}"
-// CHECK-EL-SF-32: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips32/el/sof"
+// CHECK-EL-SF-32: "--sysroot=[[TC]]/../../../../sysroot/mips32/el/sof"
 // CHECK-EL-SF-32: "[[TC]]/../../../../sysroot/mips32/el/sof/usr/lib/../lib{{/|\\\\}}crt1.o"
 // CHECK-EL-SF-32: "[[TC]]/../../../../sysroot/mips32/el/sof/usr/lib/../lib{{/|\\\\}}crti.o"
 // CHECK-EL-SF-32: "[[TC]]/mips32/el/sof{{/|\\\\}}crtbegin.o"
-// CHECK-EL-SF-32: "-L[[SR]]/mips32/el/sof"
-// CHECK-EL-SF-32: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/../lib/mips32/el/sof"
-// CHECK-EL-SF-32: "-L[[SR]]/../../../../sysroot/mips32/el/sof/usr/lib/../lib"
+// CHECK-EL-SF-32: "-L[[TC]]/mips32/el/sof"
+// CHECK-EL-SF-32: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/mips32/el/sof"
+// CHECK-EL-SF-32: "-L[[TC]]/../../../../sysroot/mips32/el/sof/usr/lib/../lib"
 // CHECK-EL-SF-32: "[[TC]]/mips32/el/sof{{/|\\\\}}crtend.o"
 // CHECK-EL-SF-32: "[[TC]]/../../../../sysroot/mips32/el/sof/usr/lib/../lib{{/|\\\\}}crtn.o"
 //
@@ -770,16 +1316,42 @@
 // CHECK-EL-HF-16: "-internal-externc-isystem"
 // CHECK-EL-HF-16: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-EL-HF-16: "{{.*}}ld{{(.exe)?}}"
-// CHECK-EL-HF-16: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips32/mips16/el"
+// CHECK-EL-HF-16: "--sysroot=[[TC]]/../../../../sysroot/mips32/mips16/el"
 // CHECK-EL-HF-16: "[[TC]]/../../../../sysroot/mips32/mips16/el/usr/lib/../lib{{/|\\\\}}crt1.o"
 // CHECK-EL-HF-16: "[[TC]]/../../../../sysroot/mips32/mips16/el/usr/lib/../lib{{/|\\\\}}crti.o"
 // CHECK-EL-HF-16: "[[TC]]/mips32/mips16/el{{/|\\\\}}crtbegin.o"
-// CHECK-EL-HF-16: "-L[[SR]]/mips32/mips16/el"
-// CHECK-EL-HF-16: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/../lib/mips32/mips16/el"
-// CHECK-EL-HF-16: "-L[[SR]]/../../../../sysroot/mips32/mips16/el/usr/lib/../lib"
+// CHECK-EL-HF-16: "-L[[TC]]/mips32/mips16/el"
+// CHECK-EL-HF-16: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/mips32/mips16/el"
+// CHECK-EL-HF-16: "-L[[TC]]/../../../../sysroot/mips32/mips16/el/usr/lib/../lib"
 // CHECK-EL-HF-16: "[[TC]]/mips32/mips16/el{{/|\\\\}}crtend.o"
 // CHECK-EL-HF-16: "[[TC]]/../../../../sysroot/mips32/mips16/el/usr/lib/../lib{{/|\\\\}}crtn.o"
 //
+// = Little-endian, mips32 / mips16, fp64, hard float
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mipsel-linux-gnu -mips32 -mips16 -mfp64 -mhard-float \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-EL-HF64-16 %s
+// CHECK-EL-HF64-16: "-internal-isystem"
+// CHECK-EL-HF64-16: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-EL-HF64-16: "-internal-isystem"
+// CHECK-EL-HF64-16: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/mips32/mips16/el"
+// CHECK-EL-HF64-16: "-internal-isystem"
+// CHECK-EL-HF64-16: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-EL-HF64-16: "-internal-externc-isystem"
+// CHECK-EL-HF64-16: "[[TC]]/include"
+// CHECK-EL-HF64-16: "-internal-externc-isystem"
+// CHECK-EL-HF64-16: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-EL-HF64-16: "{{.*}}ld{{(.exe)?}}"
+// CHECK-EL-HF64-16: "--sysroot=[[TC]]/../../../../sysroot/mips32/mips16/el"
+// CHECK-EL-HF64-16: "[[TC]]/../../../../sysroot/mips32/mips16/el/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-EL-HF64-16: "[[TC]]/../../../../sysroot/mips32/mips16/el/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-EL-HF64-16: "[[TC]]/mips32/mips16/el{{/|\\\\}}crtbegin.o"
+// CHECK-EL-HF64-16: "-L[[TC]]/mips32/mips16/el"
+// CHECK-EL-HF64-16: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/mips32/mips16/el"
+// CHECK-EL-HF64-16: "-L[[TC]]/../../../../sysroot/mips32/mips16/el/usr/lib/../lib"
+// CHECK-EL-HF64-16: "[[TC]]/mips32/mips16/el{{/|\\\\}}crtend.o"
+// CHECK-EL-HF64-16: "[[TC]]/../../../../sysroot/mips32/mips16/el/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
 // = Little-endian, mips32 / mips16, soft float
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mipsel-linux-gnu -mips32 -mips16 -msoft-float \
@@ -796,13 +1368,13 @@
 // CHECK-EL-SF-16: "-internal-externc-isystem"
 // CHECK-EL-SF-16: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-EL-SF-16: "{{.*}}ld{{(.exe)?}}"
-// CHECK-EL-SF-16: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips32/mips16/el/sof"
+// CHECK-EL-SF-16: "--sysroot=[[TC]]/../../../../sysroot/mips32/mips16/el/sof"
 // CHECK-EL-SF-16: "[[TC]]/../../../../sysroot/mips32/mips16/el/sof/usr/lib/../lib{{/|\\\\}}crt1.o"
 // CHECK-EL-SF-16: "[[TC]]/../../../../sysroot/mips32/mips16/el/sof/usr/lib/../lib{{/|\\\\}}crti.o"
 // CHECK-EL-SF-16: "[[TC]]/mips32/mips16/el/sof{{/|\\\\}}crtbegin.o"
-// CHECK-EL-SF-16: "-L[[SR]]/mips32/mips16/el/sof"
-// CHECK-EL-SF-16: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/../lib/mips32/mips16/el/sof"
-// CHECK-EL-SF-16: "-L[[SR]]/../../../../sysroot/mips32/mips16/el/sof/usr/lib/../lib"
+// CHECK-EL-SF-16: "-L[[TC]]/mips32/mips16/el/sof"
+// CHECK-EL-SF-16: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/mips32/mips16/el/sof"
+// CHECK-EL-SF-16: "-L[[TC]]/../../../../sysroot/mips32/mips16/el/sof/usr/lib/../lib"
 // CHECK-EL-SF-16: "[[TC]]/mips32/mips16/el/sof{{/|\\\\}}crtend.o"
 // CHECK-EL-SF-16: "[[TC]]/../../../../sysroot/mips32/mips16/el/sof/usr/lib/../lib{{/|\\\\}}crtn.o"
 //
@@ -822,16 +1394,42 @@
 // CHECK-EL-NAN-16: "-internal-externc-isystem"
 // CHECK-EL-NAN-16: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-EL-NAN-16: "{{.*}}ld{{(.exe)?}}"
-// CHECK-EL-NAN-16: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips32/mips16/el/nan2008"
+// CHECK-EL-NAN-16: "--sysroot=[[TC]]/../../../../sysroot/mips32/mips16/el/nan2008"
 // CHECK-EL-NAN-16: "[[TC]]/../../../../sysroot/mips32/mips16/el/nan2008/usr/lib/../lib{{/|\\\\}}crt1.o"
 // CHECK-EL-NAN-16: "[[TC]]/../../../../sysroot/mips32/mips16/el/nan2008/usr/lib/../lib{{/|\\\\}}crti.o"
 // CHECK-EL-NAN-16: "[[TC]]/mips32/mips16/el/nan2008{{/|\\\\}}crtbegin.o"
-// CHECK-EL-NAN-16: "-L[[SR]]/mips32/mips16/el/nan2008"
-// CHECK-EL-NAN-16: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/../lib/mips32/mips16/el/nan2008"
-// CHECK-EL-NAN-16: "-L[[SR]]/../../../../sysroot/mips32/mips16/el/nan2008/usr/lib/../lib"
+// CHECK-EL-NAN-16: "-L[[TC]]/mips32/mips16/el/nan2008"
+// CHECK-EL-NAN-16: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/mips32/mips16/el/nan2008"
+// CHECK-EL-NAN-16: "-L[[TC]]/../../../../sysroot/mips32/mips16/el/nan2008/usr/lib/../lib"
 // CHECK-EL-NAN-16: "[[TC]]/mips32/mips16/el/nan2008{{/|\\\\}}crtend.o"
 // CHECK-EL-NAN-16: "[[TC]]/../../../../sysroot/mips32/mips16/el/nan2008/usr/lib/../lib{{/|\\\\}}crtn.o"
 //
+// = Little-endian, mips32 / mips16, fp64, nan2008
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mipsel-linux-gnu -mips32 -mips16 -mfp64 -mnan=2008 \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-EL-NAN64-16 %s
+// CHECK-EL-NAN64-16: "-internal-isystem"
+// CHECK-EL-NAN64-16: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-EL-NAN64-16: "-internal-isystem"
+// CHECK-EL-NAN64-16: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/mips32/mips16/el/nan2008"
+// CHECK-EL-NAN64-16: "-internal-isystem"
+// CHECK-EL-NAN64-16: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-EL-NAN64-16: "-internal-externc-isystem"
+// CHECK-EL-NAN64-16: "[[TC]]/include"
+// CHECK-EL-NAN64-16: "-internal-externc-isystem"
+// CHECK-EL-NAN64-16: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-EL-NAN64-16: "{{.*}}ld{{(.exe)?}}"
+// CHECK-EL-NAN64-16: "--sysroot=[[TC]]/../../../../sysroot/mips32/mips16/el/nan2008"
+// CHECK-EL-NAN64-16: "[[TC]]/../../../../sysroot/mips32/mips16/el/nan2008/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-EL-NAN64-16: "[[TC]]/../../../../sysroot/mips32/mips16/el/nan2008/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-EL-NAN64-16: "[[TC]]/mips32/mips16/el/nan2008{{/|\\\\}}crtbegin.o"
+// CHECK-EL-NAN64-16: "-L[[TC]]/mips32/mips16/el/nan2008"
+// CHECK-EL-NAN64-16: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/mips32/mips16/el/nan2008"
+// CHECK-EL-NAN64-16: "-L[[TC]]/../../../../sysroot/mips32/mips16/el/nan2008/usr/lib/../lib"
+// CHECK-EL-NAN64-16: "[[TC]]/mips32/mips16/el/nan2008{{/|\\\\}}crtend.o"
+// CHECK-EL-NAN64-16: "[[TC]]/../../../../sysroot/mips32/mips16/el/nan2008/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
 // = Little-endian, mips32, nan2008
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mipsel-linux-gnu -mips32 -mnan=2008 \
@@ -848,16 +1446,42 @@
 // CHECK-EL-NAN-32: "-internal-externc-isystem"
 // CHECK-EL-NAN-32: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-EL-NAN-32: "{{.*}}ld{{(.exe)?}}"
-// CHECK-EL-NAN-32: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips32/el/nan2008"
+// CHECK-EL-NAN-32: "--sysroot=[[TC]]/../../../../sysroot/mips32/el/nan2008"
 // CHECK-EL-NAN-32: "[[TC]]/../../../../sysroot/mips32/el/nan2008/usr/lib/../lib{{/|\\\\}}crt1.o"
 // CHECK-EL-NAN-32: "[[TC]]/../../../../sysroot/mips32/el/nan2008/usr/lib/../lib{{/|\\\\}}crti.o"
 // CHECK-EL-NAN-32: "[[TC]]/mips32/el/nan2008{{/|\\\\}}crtbegin.o"
-// CHECK-EL-NAN-32: "-L[[SR]]/mips32/el/nan2008"
-// CHECK-EL-NAN-32: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/../lib/mips32/el/nan2008"
-// CHECK-EL-NAN-32: "-L[[SR]]/../../../../sysroot/mips32/el/nan2008/usr/lib/../lib"
+// CHECK-EL-NAN-32: "-L[[TC]]/mips32/el/nan2008"
+// CHECK-EL-NAN-32: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/mips32/el/nan2008"
+// CHECK-EL-NAN-32: "-L[[TC]]/../../../../sysroot/mips32/el/nan2008/usr/lib/../lib"
 // CHECK-EL-NAN-32: "[[TC]]/mips32/el/nan2008{{/|\\\\}}crtend.o"
 // CHECK-EL-NAN-32: "[[TC]]/../../../../sysroot/mips32/el/nan2008/usr/lib/../lib{{/|\\\\}}crtn.o"
 //
+// = Little-endian, mips32, fp64, nan2008
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mipsel-linux-gnu -mips32 -mfp64 -mnan=2008 \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-EL-NAN64-32 %s
+// CHECK-EL-NAN64-32: "-internal-isystem"
+// CHECK-EL-NAN64-32: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-EL-NAN64-32: "-internal-isystem"
+// CHECK-EL-NAN64-32: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/mips32/el/nan2008"
+// CHECK-EL-NAN64-32: "-internal-isystem"
+// CHECK-EL-NAN64-32: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-EL-NAN64-32: "-internal-externc-isystem"
+// CHECK-EL-NAN64-32: "[[TC]]/include"
+// CHECK-EL-NAN64-32: "-internal-externc-isystem"
+// CHECK-EL-NAN64-32: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-EL-NAN64-32: "{{.*}}ld{{(.exe)?}}"
+// CHECK-EL-NAN64-32: "--sysroot=[[TC]]/../../../../sysroot/mips32/el/nan2008"
+// CHECK-EL-NAN64-32: "[[TC]]/../../../../sysroot/mips32/el/nan2008/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-EL-NAN64-32: "[[TC]]/../../../../sysroot/mips32/el/nan2008/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-EL-NAN64-32: "[[TC]]/mips32/el/nan2008{{/|\\\\}}crtbegin.o"
+// CHECK-EL-NAN64-32: "-L[[TC]]/mips32/el/nan2008"
+// CHECK-EL-NAN64-32: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/mips32/el/nan2008"
+// CHECK-EL-NAN64-32: "-L[[TC]]/../../../../sysroot/mips32/el/nan2008/usr/lib/../lib"
+// CHECK-EL-NAN64-32: "[[TC]]/mips32/el/nan2008{{/|\\\\}}crtend.o"
+// CHECK-EL-NAN64-32: "[[TC]]/../../../../sysroot/mips32/el/nan2008/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
 // = Little-endian, mips32r2, hard float
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mipsel-linux-gnu -mips32r2 -mhard-float \
@@ -874,16 +1498,42 @@
 // CHECK-EL-HF-32R2: "-internal-externc-isystem"
 // CHECK-EL-HF-32R2: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-EL-HF-32R2: "{{.*}}ld{{(.exe)?}}"
-// CHECK-EL-HF-32R2: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/el"
+// CHECK-EL-HF-32R2: "--sysroot=[[TC]]/../../../../sysroot/el"
 // CHECK-EL-HF-32R2: "[[TC]]/../../../../sysroot/el/usr/lib/../lib{{/|\\\\}}crt1.o"
 // CHECK-EL-HF-32R2: "[[TC]]/../../../../sysroot/el/usr/lib/../lib{{/|\\\\}}crti.o"
 // CHECK-EL-HF-32R2: "[[TC]]/el{{/|\\\\}}crtbegin.o"
-// CHECK-EL-HF-32R2: "-L[[SR]]/el"
-// CHECK-EL-HF-32R2: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/../lib/el"
-// CHECK-EL-HF-32R2: "-L[[SR]]/../../../../sysroot/el/usr/lib/../lib"
+// CHECK-EL-HF-32R2: "-L[[TC]]/el"
+// CHECK-EL-HF-32R2: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/el"
+// CHECK-EL-HF-32R2: "-L[[TC]]/../../../../sysroot/el/usr/lib/../lib"
 // CHECK-EL-HF-32R2: "[[TC]]/el{{/|\\\\}}crtend.o"
 // CHECK-EL-HF-32R2: "[[TC]]/../../../../sysroot/el/usr/lib/../lib{{/|\\\\}}crtn.o"
 //
+// = Little-endian, mips32r2, fp64, hard float
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mipsel-linux-gnu -mips32r2 -mfp64 -mhard-float \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-EL-HF64-32R2 %s
+// CHECK-EL-HF64-32R2: "-internal-isystem"
+// CHECK-EL-HF64-32R2: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-EL-HF64-32R2: "-internal-isystem"
+// CHECK-EL-HF64-32R2: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/el"
+// CHECK-EL-HF64-32R2: "-internal-isystem"
+// CHECK-EL-HF64-32R2: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-EL-HF64-32R2: "-internal-externc-isystem"
+// CHECK-EL-HF64-32R2: "[[TC]]/include"
+// CHECK-EL-HF64-32R2: "-internal-externc-isystem"
+// CHECK-EL-HF64-32R2: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-EL-HF64-32R2: "{{.*}}ld{{(.exe)?}}"
+// CHECK-EL-HF64-32R2: "--sysroot=[[TC]]/../../../../sysroot/el"
+// CHECK-EL-HF64-32R2: "[[TC]]/../../../../sysroot/el/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-EL-HF64-32R2: "[[TC]]/../../../../sysroot/el/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-EL-HF64-32R2: "[[TC]]/el{{/|\\\\}}crtbegin.o"
+// CHECK-EL-HF64-32R2: "-L[[TC]]/el"
+// CHECK-EL-HF64-32R2: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/el"
+// CHECK-EL-HF64-32R2: "-L[[TC]]/../../../../sysroot/el/usr/lib/../lib"
+// CHECK-EL-HF64-32R2: "[[TC]]/el{{/|\\\\}}crtend.o"
+// CHECK-EL-HF64-32R2: "[[TC]]/../../../../sysroot/el/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
 // = Little-endian, mips32r2, soft float
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mipsel-linux-gnu -mips32r2 -msoft-float \
@@ -900,13 +1550,13 @@
 // CHECK-EL-SF-32R2: "-internal-externc-isystem"
 // CHECK-EL-SF-32R2: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-EL-SF-32R2: "{{.*}}ld{{(.exe)?}}"
-// CHECK-EL-SF-32R2: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/el/sof"
+// CHECK-EL-SF-32R2: "--sysroot=[[TC]]/../../../../sysroot/el/sof"
 // CHECK-EL-SF-32R2: "[[TC]]/../../../../sysroot/el/sof/usr/lib/../lib{{/|\\\\}}crt1.o"
 // CHECK-EL-SF-32R2: "[[TC]]/../../../../sysroot/el/sof/usr/lib/../lib{{/|\\\\}}crti.o"
 // CHECK-EL-SF-32R2: "[[TC]]/el/sof{{/|\\\\}}crtbegin.o"
-// CHECK-EL-SF-32R2: "-L[[SR]]/el/sof"
-// CHECK-EL-SF-32R2: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/../lib/el/sof"
-// CHECK-EL-SF-32R2: "-L[[SR]]/../../../../sysroot/el/sof/usr/lib/../lib"
+// CHECK-EL-SF-32R2: "-L[[TC]]/el/sof"
+// CHECK-EL-SF-32R2: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/el/sof"
+// CHECK-EL-SF-32R2: "-L[[TC]]/../../../../sysroot/el/sof/usr/lib/../lib"
 // CHECK-EL-SF-32R2: "[[TC]]/el/sof{{/|\\\\}}crtend.o"
 // CHECK-EL-SF-32R2: "[[TC]]/../../../../sysroot/el/sof/usr/lib/../lib{{/|\\\\}}crtn.o"
 //
@@ -926,16 +1576,42 @@
 // CHECK-EL-HF-16R2: "-internal-externc-isystem"
 // CHECK-EL-HF-16R2: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-EL-HF-16R2: "{{.*}}ld{{(.exe)?}}"
-// CHECK-EL-HF-16R2: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips16/el"
+// CHECK-EL-HF-16R2: "--sysroot=[[TC]]/../../../../sysroot/mips16/el"
 // CHECK-EL-HF-16R2: "[[TC]]/../../../../sysroot/mips16/el/usr/lib/../lib{{/|\\\\}}crt1.o"
 // CHECK-EL-HF-16R2: "[[TC]]/../../../../sysroot/mips16/el/usr/lib/../lib{{/|\\\\}}crti.o"
 // CHECK-EL-HF-16R2: "[[TC]]/mips16/el{{/|\\\\}}crtbegin.o"
-// CHECK-EL-HF-16R2: "-L[[SR]]/mips16/el"
-// CHECK-EL-HF-16R2: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/../lib/mips16/el"
-// CHECK-EL-HF-16R2: "-L[[SR]]/../../../../sysroot/mips16/el/usr/lib/../lib"
+// CHECK-EL-HF-16R2: "-L[[TC]]/mips16/el"
+// CHECK-EL-HF-16R2: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/mips16/el"
+// CHECK-EL-HF-16R2: "-L[[TC]]/../../../../sysroot/mips16/el/usr/lib/../lib"
 // CHECK-EL-HF-16R2: "[[TC]]/mips16/el{{/|\\\\}}crtend.o"
 // CHECK-EL-HF-16R2: "[[TC]]/../../../../sysroot/mips16/el/usr/lib/../lib{{/|\\\\}}crtn.o"
 //
+// = Little-endian, mips32r2 / mips16, fp64, hard float
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mipsel-linux-gnu -mips32r2 -mips16 -mfp64 -mhard-float \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-EL-HF64-16R2 %s
+// CHECK-EL-HF64-16R2: "-internal-isystem"
+// CHECK-EL-HF64-16R2: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-EL-HF64-16R2: "-internal-isystem"
+// CHECK-EL-HF64-16R2: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/mips16/el"
+// CHECK-EL-HF64-16R2: "-internal-isystem"
+// CHECK-EL-HF64-16R2: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-EL-HF64-16R2: "-internal-externc-isystem"
+// CHECK-EL-HF64-16R2: "[[TC]]/include"
+// CHECK-EL-HF64-16R2: "-internal-externc-isystem"
+// CHECK-EL-HF64-16R2: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-EL-HF64-16R2: "{{.*}}ld{{(.exe)?}}"
+// CHECK-EL-HF64-16R2: "--sysroot=[[TC]]/../../../../sysroot/mips16/el"
+// CHECK-EL-HF64-16R2: "[[TC]]/../../../../sysroot/mips16/el/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-EL-HF64-16R2: "[[TC]]/../../../../sysroot/mips16/el/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-EL-HF64-16R2: "[[TC]]/mips16/el{{/|\\\\}}crtbegin.o"
+// CHECK-EL-HF64-16R2: "-L[[TC]]/mips16/el"
+// CHECK-EL-HF64-16R2: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/mips16/el"
+// CHECK-EL-HF64-16R2: "-L[[TC]]/../../../../sysroot/mips16/el/usr/lib/../lib"
+// CHECK-EL-HF64-16R2: "[[TC]]/mips16/el{{/|\\\\}}crtend.o"
+// CHECK-EL-HF64-16R2: "[[TC]]/../../../../sysroot/mips16/el/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
 // = Little-endian, mips32r2 / mips16, soft float
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mipsel-linux-gnu -mips32r2 -mips16 -msoft-float \
@@ -952,13 +1628,13 @@
 // CHECK-EL-SF-16R2: "-internal-externc-isystem"
 // CHECK-EL-SF-16R2: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-EL-SF-16R2: "{{.*}}ld{{(.exe)?}}"
-// CHECK-EL-SF-16R2: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips16/el/sof"
+// CHECK-EL-SF-16R2: "--sysroot=[[TC]]/../../../../sysroot/mips16/el/sof"
 // CHECK-EL-SF-16R2: "[[TC]]/../../../../sysroot/mips16/el/sof/usr/lib/../lib{{/|\\\\}}crt1.o"
 // CHECK-EL-SF-16R2: "[[TC]]/../../../../sysroot/mips16/el/sof/usr/lib/../lib{{/|\\\\}}crti.o"
 // CHECK-EL-SF-16R2: "[[TC]]/mips16/el/sof{{/|\\\\}}crtbegin.o"
-// CHECK-EL-SF-16R2: "-L[[SR]]/mips16/el/sof"
-// CHECK-EL-SF-16R2: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/../lib/mips16/el/sof"
-// CHECK-EL-SF-16R2: "-L[[SR]]/../../../../sysroot/mips16/el/sof/usr/lib/../lib"
+// CHECK-EL-SF-16R2: "-L[[TC]]/mips16/el/sof"
+// CHECK-EL-SF-16R2: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/mips16/el/sof"
+// CHECK-EL-SF-16R2: "-L[[TC]]/../../../../sysroot/mips16/el/sof/usr/lib/../lib"
 // CHECK-EL-SF-16R2: "[[TC]]/mips16/el/sof{{/|\\\\}}crtend.o"
 // CHECK-EL-SF-16R2: "[[TC]]/../../../../sysroot/mips16/el/sof/usr/lib/../lib{{/|\\\\}}crtn.o"
 //
@@ -978,16 +1654,42 @@
 // CHECK-EL-NAN-16R2: "-internal-externc-isystem"
 // CHECK-EL-NAN-16R2: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-EL-NAN-16R2: "{{.*}}ld{{(.exe)?}}"
-// CHECK-EL-NAN-16R2: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips16/el/nan2008"
+// CHECK-EL-NAN-16R2: "--sysroot=[[TC]]/../../../../sysroot/mips16/el/nan2008"
 // CHECK-EL-NAN-16R2: "[[TC]]/../../../../sysroot/mips16/el/nan2008/usr/lib/../lib{{/|\\\\}}crt1.o"
 // CHECK-EL-NAN-16R2: "[[TC]]/../../../../sysroot/mips16/el/nan2008/usr/lib/../lib{{/|\\\\}}crti.o"
 // CHECK-EL-NAN-16R2: "[[TC]]/mips16/el/nan2008{{/|\\\\}}crtbegin.o"
-// CHECK-EL-NAN-16R2: "-L[[SR]]/mips16/el/nan2008"
-// CHECK-EL-NAN-16R2: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/../lib/mips16/el/nan2008"
-// CHECK-EL-NAN-16R2: "-L[[SR]]/../../../../sysroot/mips16/el/nan2008/usr/lib/../lib"
+// CHECK-EL-NAN-16R2: "-L[[TC]]/mips16/el/nan2008"
+// CHECK-EL-NAN-16R2: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/mips16/el/nan2008"
+// CHECK-EL-NAN-16R2: "-L[[TC]]/../../../../sysroot/mips16/el/nan2008/usr/lib/../lib"
 // CHECK-EL-NAN-16R2: "[[TC]]/mips16/el/nan2008{{/|\\\\}}crtend.o"
 // CHECK-EL-NAN-16R2: "[[TC]]/../../../../sysroot/mips16/el/nan2008/usr/lib/../lib{{/|\\\\}}crtn.o"
 //
+// = Little-endian, mips32r2 / mips16, fp64, nan2008
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mipsel-linux-gnu -mips32r2 -mips16 -mfp64 -mnan=2008 \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-EL-NAN64-16R2 %s
+// CHECK-EL-NAN64-16R2: "-internal-isystem"
+// CHECK-EL-NAN64-16R2: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-EL-NAN64-16R2: "-internal-isystem"
+// CHECK-EL-NAN64-16R2: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/mips16/el/nan2008"
+// CHECK-EL-NAN64-16R2: "-internal-isystem"
+// CHECK-EL-NAN64-16R2: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-EL-NAN64-16R2: "-internal-externc-isystem"
+// CHECK-EL-NAN64-16R2: "[[TC]]/include"
+// CHECK-EL-NAN64-16R2: "-internal-externc-isystem"
+// CHECK-EL-NAN64-16R2: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-EL-NAN64-16R2: "{{.*}}ld{{(.exe)?}}"
+// CHECK-EL-NAN64-16R2: "--sysroot=[[TC]]/../../../../sysroot/mips16/el/nan2008"
+// CHECK-EL-NAN64-16R2: "[[TC]]/../../../../sysroot/mips16/el/nan2008/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-EL-NAN64-16R2: "[[TC]]/../../../../sysroot/mips16/el/nan2008/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-EL-NAN64-16R2: "[[TC]]/mips16/el/nan2008{{/|\\\\}}crtbegin.o"
+// CHECK-EL-NAN64-16R2: "-L[[TC]]/mips16/el/nan2008"
+// CHECK-EL-NAN64-16R2: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/mips16/el/nan2008"
+// CHECK-EL-NAN64-16R2: "-L[[TC]]/../../../../sysroot/mips16/el/nan2008/usr/lib/../lib"
+// CHECK-EL-NAN64-16R2: "[[TC]]/mips16/el/nan2008{{/|\\\\}}crtend.o"
+// CHECK-EL-NAN64-16R2: "[[TC]]/../../../../sysroot/mips16/el/nan2008/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
 // = Little-endian, mips32r2, nan2008
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mipsel-linux-gnu -mips32r2 -mnan=2008 \
@@ -1004,16 +1706,68 @@
 // CHECK-EL-NAN-32R2: "-internal-externc-isystem"
 // CHECK-EL-NAN-32R2: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-EL-NAN-32R2: "{{.*}}ld{{(.exe)?}}"
-// CHECK-EL-NAN-32R2: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/el/nan2008"
+// CHECK-EL-NAN-32R2: "--sysroot=[[TC]]/../../../../sysroot/el/nan2008"
 // CHECK-EL-NAN-32R2: "[[TC]]/../../../../sysroot/el/nan2008/usr/lib/../lib{{/|\\\\}}crt1.o"
 // CHECK-EL-NAN-32R2: "[[TC]]/../../../../sysroot/el/nan2008/usr/lib/../lib{{/|\\\\}}crti.o"
 // CHECK-EL-NAN-32R2: "[[TC]]/el/nan2008{{/|\\\\}}crtbegin.o"
-// CHECK-EL-NAN-32R2: "-L[[SR]]/el/nan2008"
-// CHECK-EL-NAN-32R2: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/../lib/el/nan2008"
-// CHECK-EL-NAN-32R2: "-L[[SR]]/../../../../sysroot/el/nan2008/usr/lib/../lib"
+// CHECK-EL-NAN-32R2: "-L[[TC]]/el/nan2008"
+// CHECK-EL-NAN-32R2: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/el/nan2008"
+// CHECK-EL-NAN-32R2: "-L[[TC]]/../../../../sysroot/el/nan2008/usr/lib/../lib"
 // CHECK-EL-NAN-32R2: "[[TC]]/el/nan2008{{/|\\\\}}crtend.o"
 // CHECK-EL-NAN-32R2: "[[TC]]/../../../../sysroot/el/nan2008/usr/lib/../lib{{/|\\\\}}crtn.o"
 //
+// = Little-endian, mips32r2, fp64, nan2008
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mipsel-linux-gnu -mips32r2 -mfp64 -mnan=2008 \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-EL-NAN64-32R2 %s
+// CHECK-EL-NAN64-32R2: "-internal-isystem"
+// CHECK-EL-NAN64-32R2: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-EL-NAN64-32R2: "-internal-isystem"
+// CHECK-EL-NAN64-32R2: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/el/nan2008"
+// CHECK-EL-NAN64-32R2: "-internal-isystem"
+// CHECK-EL-NAN64-32R2: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-EL-NAN64-32R2: "-internal-externc-isystem"
+// CHECK-EL-NAN64-32R2: "[[TC]]/include"
+// CHECK-EL-NAN64-32R2: "-internal-externc-isystem"
+// CHECK-EL-NAN64-32R2: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-EL-NAN64-32R2: "{{.*}}ld{{(.exe)?}}"
+// CHECK-EL-NAN64-32R2: "--sysroot=[[TC]]/../../../../sysroot/el/nan2008"
+// CHECK-EL-NAN64-32R2: "[[TC]]/../../../../sysroot/el/nan2008/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-EL-NAN64-32R2: "[[TC]]/../../../../sysroot/el/nan2008/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-EL-NAN64-32R2: "[[TC]]/el/nan2008{{/|\\\\}}crtbegin.o"
+// CHECK-EL-NAN64-32R2: "-L[[TC]]/el/nan2008"
+// CHECK-EL-NAN64-32R2: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/el/nan2008"
+// CHECK-EL-NAN64-32R2: "-L[[TC]]/../../../../sysroot/el/nan2008/usr/lib/../lib"
+// CHECK-EL-NAN64-32R2: "[[TC]]/el/nan2008{{/|\\\\}}crtend.o"
+// CHECK-EL-NAN64-32R2: "[[TC]]/../../../../sysroot/el/nan2008/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
+// = Little-endian, default (mips32r2), fp64, nan2008
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mipsel-linux-gnu -mfp64 -mnan=2008 \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-EL-NAN64-32R2-DEF %s
+// CHECK-EL-NAN64-32R2-DEF: "-internal-isystem"
+// CHECK-EL-NAN64-32R2-DEF: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-EL-NAN64-32R2-DEF: "-internal-isystem"
+// CHECK-EL-NAN64-32R2-DEF: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/el/nan2008"
+// CHECK-EL-NAN64-32R2-DEF: "-internal-isystem"
+// CHECK-EL-NAN64-32R2-DEF: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-EL-NAN64-32R2-DEF: "-internal-externc-isystem"
+// CHECK-EL-NAN64-32R2-DEF: "[[TC]]/include"
+// CHECK-EL-NAN64-32R2-DEF: "-internal-externc-isystem"
+// CHECK-EL-NAN64-32R2-DEF: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-EL-NAN64-32R2-DEF: "{{.*}}ld{{(.exe)?}}"
+// CHECK-EL-NAN64-32R2-DEF: "--sysroot=[[TC]]/../../../../sysroot/el/nan2008"
+// CHECK-EL-NAN64-32R2-DEF: "[[TC]]/../../../../sysroot/el/nan2008/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-EL-NAN64-32R2-DEF: "[[TC]]/../../../../sysroot/el/nan2008/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-EL-NAN64-32R2-DEF: "[[TC]]/el/nan2008{{/|\\\\}}crtbegin.o"
+// CHECK-EL-NAN64-32R2-DEF: "-L[[TC]]/el/nan2008"
+// CHECK-EL-NAN64-32R2-DEF: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/el/nan2008"
+// CHECK-EL-NAN64-32R2-DEF: "-L[[TC]]/../../../../sysroot/el/nan2008/usr/lib/../lib"
+// CHECK-EL-NAN64-32R2-DEF: "[[TC]]/el/nan2008{{/|\\\\}}crtend.o"
+// CHECK-EL-NAN64-32R2-DEF: "[[TC]]/../../../../sysroot/el/nan2008/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
 // = Little-endian, micromips, hard float
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mipsel-linux-gnu -mmicromips -mhard-float \
@@ -1030,16 +1784,42 @@
 // CHECK-EL-HF-MM: "-internal-externc-isystem"
 // CHECK-EL-HF-MM: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-EL-HF-MM: "{{.*}}ld{{(.exe)?}}"
-// CHECK-EL-HF-MM: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/micromips/el"
+// CHECK-EL-HF-MM: "--sysroot=[[TC]]/../../../../sysroot/micromips/el"
 // CHECK-EL-HF-MM: "[[TC]]/../../../../sysroot/micromips/el/usr/lib/../lib{{/|\\\\}}crt1.o"
 // CHECK-EL-HF-MM: "[[TC]]/../../../../sysroot/micromips/el/usr/lib/../lib{{/|\\\\}}crti.o"
 // CHECK-EL-HF-MM: "[[TC]]/micromips/el{{/|\\\\}}crtbegin.o"
-// CHECK-EL-HF-MM: "-L[[SR]]/micromips/el"
-// CHECK-EL-HF-MM: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/../lib/micromips/el"
-// CHECK-EL-HF-MM: "-L[[SR]]/../../../../sysroot/micromips/el/usr/lib/../lib"
+// CHECK-EL-HF-MM: "-L[[TC]]/micromips/el"
+// CHECK-EL-HF-MM: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/micromips/el"
+// CHECK-EL-HF-MM: "-L[[TC]]/../../../../sysroot/micromips/el/usr/lib/../lib"
 // CHECK-EL-HF-MM: "[[TC]]/micromips/el{{/|\\\\}}crtend.o"
 // CHECK-EL-HF-MM: "[[TC]]/../../../../sysroot/micromips/el/usr/lib/../lib{{/|\\\\}}crtn.o"
 //
+// = Little-endian, micromips, fp64, hard float
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mipsel-linux-gnu -mmicromips -mfp64 -mhard-float \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-EL-HF64-MM %s
+// CHECK-EL-HF64-MM: "-internal-isystem"
+// CHECK-EL-HF64-MM: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-EL-HF64-MM: "-internal-isystem"
+// CHECK-EL-HF64-MM: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/micromips/el"
+// CHECK-EL-HF64-MM: "-internal-isystem"
+// CHECK-EL-HF64-MM: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-EL-HF64-MM: "-internal-externc-isystem"
+// CHECK-EL-HF64-MM: "[[TC]]/include"
+// CHECK-EL-HF64-MM: "-internal-externc-isystem"
+// CHECK-EL-HF64-MM: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-EL-HF64-MM: "{{.*}}ld{{(.exe)?}}"
+// CHECK-EL-HF64-MM: "--sysroot=[[TC]]/../../../../sysroot/micromips/el"
+// CHECK-EL-HF64-MM: "[[TC]]/../../../../sysroot/micromips/el/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-EL-HF64-MM: "[[TC]]/../../../../sysroot/micromips/el/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-EL-HF64-MM: "[[TC]]/micromips/el{{/|\\\\}}crtbegin.o"
+// CHECK-EL-HF64-MM: "-L[[TC]]/micromips/el"
+// CHECK-EL-HF64-MM: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/micromips/el"
+// CHECK-EL-HF64-MM: "-L[[TC]]/../../../../sysroot/micromips/el/usr/lib/../lib"
+// CHECK-EL-HF64-MM: "[[TC]]/micromips/el{{/|\\\\}}crtend.o"
+// CHECK-EL-HF64-MM: "[[TC]]/../../../../sysroot/micromips/el/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
 // = Little-endian, micromips, soft float
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mipsel-linux-gnu -mmicromips -msoft-float \
@@ -1056,13 +1836,13 @@
 // CHECK-EL-SF-MM: "-internal-externc-isystem"
 // CHECK-EL-SF-MM: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-EL-SF-MM: "{{.*}}ld{{(.exe)?}}"
-// CHECK-EL-SF-MM: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/micromips/el/sof"
+// CHECK-EL-SF-MM: "--sysroot=[[TC]]/../../../../sysroot/micromips/el/sof"
 // CHECK-EL-SF-MM: "[[TC]]/../../../../sysroot/micromips/el/sof/usr/lib/../lib{{/|\\\\}}crt1.o"
 // CHECK-EL-SF-MM: "[[TC]]/../../../../sysroot/micromips/el/sof/usr/lib/../lib{{/|\\\\}}crti.o"
 // CHECK-EL-SF-MM: "[[TC]]/micromips/el/sof{{/|\\\\}}crtbegin.o"
-// CHECK-EL-SF-MM: "-L[[SR]]/micromips/el/sof"
-// CHECK-EL-SF-MM: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/../lib/micromips/el/sof"
-// CHECK-EL-SF-MM: "-L[[SR]]/../../../../sysroot/micromips/el/sof/usr/lib/../lib"
+// CHECK-EL-SF-MM: "-L[[TC]]/micromips/el/sof"
+// CHECK-EL-SF-MM: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/micromips/el/sof"
+// CHECK-EL-SF-MM: "-L[[TC]]/../../../../sysroot/micromips/el/sof/usr/lib/../lib"
 // CHECK-EL-SF-MM: "[[TC]]/micromips/el/sof{{/|\\\\}}crtend.o"
 // CHECK-EL-SF-MM: "[[TC]]/../../../../sysroot/micromips/el/sof/usr/lib/../lib{{/|\\\\}}crtn.o"
 //
@@ -1082,16 +1862,42 @@
 // CHECK-EL-NAN-MM: "-internal-externc-isystem"
 // CHECK-EL-NAN-MM: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-EL-NAN-MM: "{{.*}}ld{{(.exe)?}}"
-// CHECK-EL-NAN-MM: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/micromips/el/nan2008"
+// CHECK-EL-NAN-MM: "--sysroot=[[TC]]/../../../../sysroot/micromips/el/nan2008"
 // CHECK-EL-NAN-MM: "[[TC]]/../../../../sysroot/micromips/el/nan2008/usr/lib/../lib{{/|\\\\}}crt1.o"
 // CHECK-EL-NAN-MM: "[[TC]]/../../../../sysroot/micromips/el/nan2008/usr/lib/../lib{{/|\\\\}}crti.o"
 // CHECK-EL-NAN-MM: "[[TC]]/micromips/el/nan2008{{/|\\\\}}crtbegin.o"
-// CHECK-EL-NAN-MM: "-L[[SR]]/micromips/el/nan2008"
-// CHECK-EL-NAN-MM: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/../lib/micromips/el/nan2008"
-// CHECK-EL-NAN-MM: "-L[[SR]]/../../../../sysroot/micromips/el/nan2008/usr/lib/../lib"
+// CHECK-EL-NAN-MM: "-L[[TC]]/micromips/el/nan2008"
+// CHECK-EL-NAN-MM: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/micromips/el/nan2008"
+// CHECK-EL-NAN-MM: "-L[[TC]]/../../../../sysroot/micromips/el/nan2008/usr/lib/../lib"
 // CHECK-EL-NAN-MM: "[[TC]]/micromips/el/nan2008{{/|\\\\}}crtend.o"
 // CHECK-EL-NAN-MM: "[[TC]]/../../../../sysroot/micromips/el/nan2008/usr/lib/../lib{{/|\\\\}}crtn.o"
 //
+// = Little-endian, micromips, fp64, nan2008
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mipsel-linux-gnu -mmicromips -mfp64 -mnan=2008 \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-EL-NAN64-MM %s
+// CHECK-EL-NAN64-MM: "-internal-isystem"
+// CHECK-EL-NAN64-MM: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-EL-NAN64-MM: "-internal-isystem"
+// CHECK-EL-NAN64-MM: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/micromips/el/nan2008"
+// CHECK-EL-NAN64-MM: "-internal-isystem"
+// CHECK-EL-NAN64-MM: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-EL-NAN64-MM: "-internal-externc-isystem"
+// CHECK-EL-NAN64-MM: "[[TC]]/include"
+// CHECK-EL-NAN64-MM: "-internal-externc-isystem"
+// CHECK-EL-NAN64-MM: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-EL-NAN64-MM: "{{.*}}ld{{(.exe)?}}"
+// CHECK-EL-NAN64-MM: "--sysroot=[[TC]]/../../../../sysroot/micromips/el/nan2008"
+// CHECK-EL-NAN64-MM: "[[TC]]/../../../../sysroot/micromips/el/nan2008/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-EL-NAN64-MM: "[[TC]]/../../../../sysroot/micromips/el/nan2008/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-EL-NAN64-MM: "[[TC]]/micromips/el/nan2008{{/|\\\\}}crtbegin.o"
+// CHECK-EL-NAN64-MM: "-L[[TC]]/micromips/el/nan2008"
+// CHECK-EL-NAN64-MM: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/../lib/micromips/el/nan2008"
+// CHECK-EL-NAN64-MM: "-L[[TC]]/../../../../sysroot/micromips/el/nan2008/usr/lib/../lib"
+// CHECK-EL-NAN64-MM: "[[TC]]/micromips/el/nan2008{{/|\\\\}}crtend.o"
+// CHECK-EL-NAN64-MM: "[[TC]]/../../../../sysroot/micromips/el/nan2008/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
 // = Little-endian, mips64, ABI n32, hard float
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mips64el-linux-gnu -mips64 -mabi=n32 -mhard-float \
@@ -1108,16 +1914,42 @@
 // CHECK-EL-HF-64-N32: "-internal-externc-isystem"
 // CHECK-EL-HF-64-N32: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-EL-HF-64-N32: "{{.*}}ld{{(.exe)?}}"
-// CHECK-EL-HF-64-N32: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips64/el"
+// CHECK-EL-HF-64-N32: "--sysroot=[[TC]]/../../../../sysroot/mips64/el"
 // CHECK-EL-HF-64-N32: "[[TC]]/../../../../sysroot/mips64/el/usr/lib{{/|\\\\}}crt1.o"
 // CHECK-EL-HF-64-N32: "[[TC]]/../../../../sysroot/mips64/el/usr/lib{{/|\\\\}}crti.o"
 // CHECK-EL-HF-64-N32: "[[TC]]/mips64/el{{/|\\\\}}crtbegin.o"
-// CHECK-EL-HF-64-N32: "-L[[SR]]/mips64/el"
-// CHECK-EL-HF-64-N32: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/mips64/el"
-// CHECK-EL-HF-64-N32: "-L[[SR]]/../../../../sysroot/mips64/el/usr/lib"
+// CHECK-EL-HF-64-N32: "-L[[TC]]/mips64/el"
+// CHECK-EL-HF-64-N32: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64/el"
+// CHECK-EL-HF-64-N32: "-L[[TC]]/../../../../sysroot/mips64/el/usr/lib"
 // CHECK-EL-HF-64-N32: "[[TC]]/mips64/el{{/|\\\\}}crtend.o"
 // CHECK-EL-HF-64-N32: "[[TC]]/../../../../sysroot/mips64/el/usr/lib{{/|\\\\}}crtn.o"
 //
+// = Little-endian, mips64, ABI n32, fp64, hard float
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64el-linux-gnu -mips64 -mabi=n32 -mfp64 -mhard-float \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-EL-HF64-64-N32 %s
+// CHECK-EL-HF64-64-N32: "-internal-isystem"
+// CHECK-EL-HF64-64-N32: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-EL-HF64-64-N32: "-internal-isystem"
+// CHECK-EL-HF64-64-N32: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/mips64/el"
+// CHECK-EL-HF64-64-N32: "-internal-isystem"
+// CHECK-EL-HF64-64-N32: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-EL-HF64-64-N32: "-internal-externc-isystem"
+// CHECK-EL-HF64-64-N32: "[[TC]]/include"
+// CHECK-EL-HF64-64-N32: "-internal-externc-isystem"
+// CHECK-EL-HF64-64-N32: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-EL-HF64-64-N32: "{{.*}}ld{{(.exe)?}}"
+// CHECK-EL-HF64-64-N32: "--sysroot=[[TC]]/../../../../sysroot/mips64/el"
+// CHECK-EL-HF64-64-N32: "[[TC]]/../../../../sysroot/mips64/el/usr/lib{{/|\\\\}}crt1.o"
+// CHECK-EL-HF64-64-N32: "[[TC]]/../../../../sysroot/mips64/el/usr/lib{{/|\\\\}}crti.o"
+// CHECK-EL-HF64-64-N32: "[[TC]]/mips64/el{{/|\\\\}}crtbegin.o"
+// CHECK-EL-HF64-64-N32: "-L[[TC]]/mips64/el"
+// CHECK-EL-HF64-64-N32: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64/el"
+// CHECK-EL-HF64-64-N32: "-L[[TC]]/../../../../sysroot/mips64/el/usr/lib"
+// CHECK-EL-HF64-64-N32: "[[TC]]/mips64/el{{/|\\\\}}crtend.o"
+// CHECK-EL-HF64-64-N32: "[[TC]]/../../../../sysroot/mips64/el/usr/lib{{/|\\\\}}crtn.o"
+//
 // = Little-endian, mips64, ABI n32, soft float
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mips64el-linux-gnu -mips64 -mabi=n32 -msoft-float \
@@ -1134,13 +1966,13 @@
 // CHECK-EL-SF-64-N32: "-internal-externc-isystem"
 // CHECK-EL-SF-64-N32: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-EL-SF-64-N32: "{{.*}}ld{{(.exe)?}}"
-// CHECK-EL-SF-64-N32: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips64/el/sof"
+// CHECK-EL-SF-64-N32: "--sysroot=[[TC]]/../../../../sysroot/mips64/el/sof"
 // CHECK-EL-SF-64-N32: "[[TC]]/../../../../sysroot/mips64/el/sof/usr/lib{{/|\\\\}}crt1.o"
 // CHECK-EL-SF-64-N32: "[[TC]]/../../../../sysroot/mips64/el/sof/usr/lib{{/|\\\\}}crti.o"
 // CHECK-EL-SF-64-N32: "[[TC]]/mips64/el/sof{{/|\\\\}}crtbegin.o"
-// CHECK-EL-SF-64-N32: "-L[[SR]]/mips64/el/sof"
-// CHECK-EL-SF-64-N32: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/mips64/el/sof"
-// CHECK-EL-SF-64-N32: "-L[[SR]]/../../../../sysroot/mips64/el/sof/usr/lib"
+// CHECK-EL-SF-64-N32: "-L[[TC]]/mips64/el/sof"
+// CHECK-EL-SF-64-N32: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64/el/sof"
+// CHECK-EL-SF-64-N32: "-L[[TC]]/../../../../sysroot/mips64/el/sof/usr/lib"
 // CHECK-EL-SF-64-N32: "[[TC]]/mips64/el/sof{{/|\\\\}}crtend.o"
 // CHECK-EL-SF-64-N32: "[[TC]]/../../../../sysroot/mips64/el/sof/usr/lib{{/|\\\\}}crtn.o"
 //
@@ -1160,16 +1992,42 @@
 // CHECK-EL-NAN-64-N32: "-internal-externc-isystem"
 // CHECK-EL-NAN-64-N32: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-EL-NAN-64-N32: "{{.*}}ld{{(.exe)?}}"
-// CHECK-EL-NAN-64-N32: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips64/el/nan2008"
+// CHECK-EL-NAN-64-N32: "--sysroot=[[TC]]/../../../../sysroot/mips64/el/nan2008"
 // CHECK-EL-NAN-64-N32: "[[TC]]/../../../../sysroot/mips64/el/nan2008/usr/lib{{/|\\\\}}crt1.o"
 // CHECK-EL-NAN-64-N32: "[[TC]]/../../../../sysroot/mips64/el/nan2008/usr/lib{{/|\\\\}}crti.o"
 // CHECK-EL-NAN-64-N32: "[[TC]]/mips64/el/nan2008{{/|\\\\}}crtbegin.o"
-// CHECK-EL-NAN-64-N32: "-L[[SR]]/mips64/el/nan2008"
-// CHECK-EL-NAN-64-N32: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/mips64/el/nan2008"
-// CHECK-EL-NAN-64-N32: "-L[[SR]]/../../../../sysroot/mips64/el/nan2008/usr/lib"
+// CHECK-EL-NAN-64-N32: "-L[[TC]]/mips64/el/nan2008"
+// CHECK-EL-NAN-64-N32: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64/el/nan2008"
+// CHECK-EL-NAN-64-N32: "-L[[TC]]/../../../../sysroot/mips64/el/nan2008/usr/lib"
 // CHECK-EL-NAN-64-N32: "[[TC]]/mips64/el/nan2008{{/|\\\\}}crtend.o"
 // CHECK-EL-NAN-64-N32: "[[TC]]/../../../../sysroot/mips64/el/nan2008/usr/lib{{/|\\\\}}crtn.o"
 //
+// = Little-endian, mips64, ABI n32, fp64, nan2008
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64el-linux-gnu -mips64 -mabi=n32 -mfp64 -mnan=2008 \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-EL-NAN64-64-N32 %s
+// CHECK-EL-NAN64-64-N32: "-internal-isystem"
+// CHECK-EL-NAN64-64-N32: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-EL-NAN64-64-N32: "-internal-isystem"
+// CHECK-EL-NAN64-64-N32: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/mips64/el/nan2008"
+// CHECK-EL-NAN64-64-N32: "-internal-isystem"
+// CHECK-EL-NAN64-64-N32: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-EL-NAN64-64-N32: "-internal-externc-isystem"
+// CHECK-EL-NAN64-64-N32: "[[TC]]/include"
+// CHECK-EL-NAN64-64-N32: "-internal-externc-isystem"
+// CHECK-EL-NAN64-64-N32: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-EL-NAN64-64-N32: "{{.*}}ld{{(.exe)?}}"
+// CHECK-EL-NAN64-64-N32: "--sysroot=[[TC]]/../../../../sysroot/mips64/el/nan2008"
+// CHECK-EL-NAN64-64-N32: "[[TC]]/../../../../sysroot/mips64/el/nan2008/usr/lib{{/|\\\\}}crt1.o"
+// CHECK-EL-NAN64-64-N32: "[[TC]]/../../../../sysroot/mips64/el/nan2008/usr/lib{{/|\\\\}}crti.o"
+// CHECK-EL-NAN64-64-N32: "[[TC]]/mips64/el/nan2008{{/|\\\\}}crtbegin.o"
+// CHECK-EL-NAN64-64-N32: "-L[[TC]]/mips64/el/nan2008"
+// CHECK-EL-NAN64-64-N32: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64/el/nan2008"
+// CHECK-EL-NAN64-64-N32: "-L[[TC]]/../../../../sysroot/mips64/el/nan2008/usr/lib"
+// CHECK-EL-NAN64-64-N32: "[[TC]]/mips64/el/nan2008{{/|\\\\}}crtend.o"
+// CHECK-EL-NAN64-64-N32: "[[TC]]/../../../../sysroot/mips64/el/nan2008/usr/lib{{/|\\\\}}crtn.o"
+//
 // = Little-endian, mips64, ABI 64, hard float
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mips64el-linux-gnu -mips64 -mabi=64 -mhard-float \
@@ -1186,16 +2044,42 @@
 // CHECK-EL-HF-64-64: "-internal-externc-isystem"
 // CHECK-EL-HF-64-64: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-EL-HF-64-64: "{{.*}}ld{{(.exe)?}}"
-// CHECK-EL-HF-64-64: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips64/64/el"
+// CHECK-EL-HF-64-64: "--sysroot=[[TC]]/../../../../sysroot/mips64/64/el"
 // CHECK-EL-HF-64-64: "[[TC]]/../../../../sysroot/mips64/64/el/usr/lib{{/|\\\\}}crt1.o"
 // CHECK-EL-HF-64-64: "[[TC]]/../../../../sysroot/mips64/64/el/usr/lib{{/|\\\\}}crti.o"
 // CHECK-EL-HF-64-64: "[[TC]]/mips64/64/el{{/|\\\\}}crtbegin.o"
-// CHECK-EL-HF-64-64: "-L[[SR]]/mips64/64/el"
-// CHECK-EL-HF-64-64: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/mips64/64/el"
-// CHECK-EL-HF-64-64: "-L[[SR]]/../../../../sysroot/mips64/64/el/usr/lib"
+// CHECK-EL-HF-64-64: "-L[[TC]]/mips64/64/el"
+// CHECK-EL-HF-64-64: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64/64/el"
+// CHECK-EL-HF-64-64: "-L[[TC]]/../../../../sysroot/mips64/64/el/usr/lib"
 // CHECK-EL-HF-64-64: "[[TC]]/mips64/64/el{{/|\\\\}}crtend.o"
 // CHECK-EL-HF-64-64: "[[TC]]/../../../../sysroot/mips64/64/el/usr/lib{{/|\\\\}}crtn.o"
 //
+// = Little-endian, mips64, ABI 64, fp64, hard float
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64el-linux-gnu -mips64 -mabi=64 -mfp64 -mhard-float \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-EL-HF64-64-64 %s
+// CHECK-EL-HF64-64-64: "-internal-isystem"
+// CHECK-EL-HF64-64-64: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-EL-HF64-64-64: "-internal-isystem"
+// CHECK-EL-HF64-64-64: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/mips64/64/el"
+// CHECK-EL-HF64-64-64: "-internal-isystem"
+// CHECK-EL-HF64-64-64: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-EL-HF64-64-64: "-internal-externc-isystem"
+// CHECK-EL-HF64-64-64: "[[TC]]/include"
+// CHECK-EL-HF64-64-64: "-internal-externc-isystem"
+// CHECK-EL-HF64-64-64: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-EL-HF64-64-64: "{{.*}}ld{{(.exe)?}}"
+// CHECK-EL-HF64-64-64: "--sysroot=[[TC]]/../../../../sysroot/mips64/64/el"
+// CHECK-EL-HF64-64-64: "[[TC]]/../../../../sysroot/mips64/64/el/usr/lib{{/|\\\\}}crt1.o"
+// CHECK-EL-HF64-64-64: "[[TC]]/../../../../sysroot/mips64/64/el/usr/lib{{/|\\\\}}crti.o"
+// CHECK-EL-HF64-64-64: "[[TC]]/mips64/64/el{{/|\\\\}}crtbegin.o"
+// CHECK-EL-HF64-64-64: "-L[[TC]]/mips64/64/el"
+// CHECK-EL-HF64-64-64: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64/64/el"
+// CHECK-EL-HF64-64-64: "-L[[TC]]/../../../../sysroot/mips64/64/el/usr/lib"
+// CHECK-EL-HF64-64-64: "[[TC]]/mips64/64/el{{/|\\\\}}crtend.o"
+// CHECK-EL-HF64-64-64: "[[TC]]/../../../../sysroot/mips64/64/el/usr/lib{{/|\\\\}}crtn.o"
+//
 // = Little-endian, mips64, ABI 64, soft float
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mips64el-linux-gnu -mips64 -mabi=64 -msoft-float \
@@ -1212,13 +2096,13 @@
 // CHECK-EL-SF-64-64: "-internal-externc-isystem"
 // CHECK-EL-SF-64-64: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-EL-SF-64-64: "{{.*}}ld{{(.exe)?}}"
-// CHECK-EL-SF-64-64: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips64/64/el/sof"
+// CHECK-EL-SF-64-64: "--sysroot=[[TC]]/../../../../sysroot/mips64/64/el/sof"
 // CHECK-EL-SF-64-64: "[[TC]]/../../../../sysroot/mips64/64/el/sof/usr/lib{{/|\\\\}}crt1.o"
 // CHECK-EL-SF-64-64: "[[TC]]/../../../../sysroot/mips64/64/el/sof/usr/lib{{/|\\\\}}crti.o"
 // CHECK-EL-SF-64-64: "[[TC]]/mips64/64/el/sof{{/|\\\\}}crtbegin.o"
-// CHECK-EL-SF-64-64: "-L[[SR]]/mips64/64/el/sof"
-// CHECK-EL-SF-64-64: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/mips64/64/el/sof"
-// CHECK-EL-SF-64-64: "-L[[SR]]/../../../../sysroot/mips64/64/el/sof/usr/lib"
+// CHECK-EL-SF-64-64: "-L[[TC]]/mips64/64/el/sof"
+// CHECK-EL-SF-64-64: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64/64/el/sof"
+// CHECK-EL-SF-64-64: "-L[[TC]]/../../../../sysroot/mips64/64/el/sof/usr/lib"
 // CHECK-EL-SF-64-64: "[[TC]]/mips64/64/el/sof{{/|\\\\}}crtend.o"
 // CHECK-EL-SF-64-64: "[[TC]]/../../../../sysroot/mips64/64/el/sof/usr/lib{{/|\\\\}}crtn.o"
 //
@@ -1238,16 +2122,42 @@
 // CHECK-EL-NAN-64-64: "-internal-externc-isystem"
 // CHECK-EL-NAN-64-64: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-EL-NAN-64-64: "{{.*}}ld{{(.exe)?}}"
-// CHECK-EL-NAN-64-64: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips64/64/el/nan2008"
+// CHECK-EL-NAN-64-64: "--sysroot=[[TC]]/../../../../sysroot/mips64/64/el/nan2008"
 // CHECK-EL-NAN-64-64: "[[TC]]/../../../../sysroot/mips64/64/el/nan2008/usr/lib{{/|\\\\}}crt1.o"
 // CHECK-EL-NAN-64-64: "[[TC]]/../../../../sysroot/mips64/64/el/nan2008/usr/lib{{/|\\\\}}crti.o"
 // CHECK-EL-NAN-64-64: "[[TC]]/mips64/64/el/nan2008{{/|\\\\}}crtbegin.o"
-// CHECK-EL-NAN-64-64: "-L[[SR]]/mips64/64/el/nan2008"
-// CHECK-EL-NAN-64-64: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/mips64/64/el/nan2008"
-// CHECK-EL-NAN-64-64: "-L[[SR]]/../../../../sysroot/mips64/64/el/nan2008/usr/lib"
+// CHECK-EL-NAN-64-64: "-L[[TC]]/mips64/64/el/nan2008"
+// CHECK-EL-NAN-64-64: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64/64/el/nan2008"
+// CHECK-EL-NAN-64-64: "-L[[TC]]/../../../../sysroot/mips64/64/el/nan2008/usr/lib"
 // CHECK-EL-NAN-64-64: "[[TC]]/mips64/64/el/nan2008{{/|\\\\}}crtend.o"
 // CHECK-EL-NAN-64-64: "[[TC]]/../../../../sysroot/mips64/64/el/nan2008/usr/lib{{/|\\\\}}crtn.o"
 //
+// = Little-endian, mips64, ABI 64, fp64, nan2008
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64el-linux-gnu -mips64 -mabi=64 -mfp64 -mnan=2008 \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-EL-NAN64-64-64 %s
+// CHECK-EL-NAN64-64-64: "-internal-isystem"
+// CHECK-EL-NAN64-64-64: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-EL-NAN64-64-64: "-internal-isystem"
+// CHECK-EL-NAN64-64-64: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/mips64/64/el/nan2008"
+// CHECK-EL-NAN64-64-64: "-internal-isystem"
+// CHECK-EL-NAN64-64-64: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-EL-NAN64-64-64: "-internal-externc-isystem"
+// CHECK-EL-NAN64-64-64: "[[TC]]/include"
+// CHECK-EL-NAN64-64-64: "-internal-externc-isystem"
+// CHECK-EL-NAN64-64-64: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-EL-NAN64-64-64: "{{.*}}ld{{(.exe)?}}"
+// CHECK-EL-NAN64-64-64: "--sysroot=[[TC]]/../../../../sysroot/mips64/64/el/nan2008"
+// CHECK-EL-NAN64-64-64: "[[TC]]/../../../../sysroot/mips64/64/el/nan2008/usr/lib{{/|\\\\}}crt1.o"
+// CHECK-EL-NAN64-64-64: "[[TC]]/../../../../sysroot/mips64/64/el/nan2008/usr/lib{{/|\\\\}}crti.o"
+// CHECK-EL-NAN64-64-64: "[[TC]]/mips64/64/el/nan2008{{/|\\\\}}crtbegin.o"
+// CHECK-EL-NAN64-64-64: "-L[[TC]]/mips64/64/el/nan2008"
+// CHECK-EL-NAN64-64-64: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64/64/el/nan2008"
+// CHECK-EL-NAN64-64-64: "-L[[TC]]/../../../../sysroot/mips64/64/el/nan2008/usr/lib"
+// CHECK-EL-NAN64-64-64: "[[TC]]/mips64/64/el/nan2008{{/|\\\\}}crtend.o"
+// CHECK-EL-NAN64-64-64: "[[TC]]/../../../../sysroot/mips64/64/el/nan2008/usr/lib{{/|\\\\}}crtn.o"
+//
 // = Little-endian, mips64r2, ABI n32, hard float
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mips64el-linux-gnu -mips64r2 -mabi=n32 -mhard-float \
@@ -1264,16 +2174,42 @@
 // CHECK-EL-HF-64R2-N32: "-internal-externc-isystem"
 // CHECK-EL-HF-64R2-N32: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-EL-HF-64R2-N32: "{{.*}}ld{{(.exe)?}}"
-// CHECK-EL-HF-64R2-N32: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips64r2/el"
+// CHECK-EL-HF-64R2-N32: "--sysroot=[[TC]]/../../../../sysroot/mips64r2/el"
 // CHECK-EL-HF-64R2-N32: "[[TC]]/../../../../sysroot/mips64r2/el/usr/lib{{/|\\\\}}crt1.o"
 // CHECK-EL-HF-64R2-N32: "[[TC]]/../../../../sysroot/mips64r2/el/usr/lib{{/|\\\\}}crti.o"
 // CHECK-EL-HF-64R2-N32: "[[TC]]/mips64r2/el{{/|\\\\}}crtbegin.o"
-// CHECK-EL-HF-64R2-N32: "-L[[SR]]/mips64r2/el"
-// CHECK-EL-HF-64R2-N32: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/mips64r2/el"
-// CHECK-EL-HF-64R2-N32: "-L[[SR]]/../../../../sysroot/mips64r2/el/usr/lib"
+// CHECK-EL-HF-64R2-N32: "-L[[TC]]/mips64r2/el"
+// CHECK-EL-HF-64R2-N32: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64r2/el"
+// CHECK-EL-HF-64R2-N32: "-L[[TC]]/../../../../sysroot/mips64r2/el/usr/lib"
 // CHECK-EL-HF-64R2-N32: "[[TC]]/mips64r2/el{{/|\\\\}}crtend.o"
 // CHECK-EL-HF-64R2-N32: "[[TC]]/../../../../sysroot/mips64r2/el/usr/lib{{/|\\\\}}crtn.o"
 //
+// = Little-endian, mips64r2, ABI n32, fp64, hard float
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64el-linux-gnu -mips64r2 -mabi=n32 -mfp64 -mhard-float \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-EL-HF64-64R2-N32 %s
+// CHECK-EL-HF64-64R2-N32: "-internal-isystem"
+// CHECK-EL-HF64-64R2-N32: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-EL-HF64-64R2-N32: "-internal-isystem"
+// CHECK-EL-HF64-64R2-N32: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/mips64r2/el"
+// CHECK-EL-HF64-64R2-N32: "-internal-isystem"
+// CHECK-EL-HF64-64R2-N32: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-EL-HF64-64R2-N32: "-internal-externc-isystem"
+// CHECK-EL-HF64-64R2-N32: "[[TC]]/include"
+// CHECK-EL-HF64-64R2-N32: "-internal-externc-isystem"
+// CHECK-EL-HF64-64R2-N32: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-EL-HF64-64R2-N32: "{{.*}}ld{{(.exe)?}}"
+// CHECK-EL-HF64-64R2-N32: "--sysroot=[[TC]]/../../../../sysroot/mips64r2/el"
+// CHECK-EL-HF64-64R2-N32: "[[TC]]/../../../../sysroot/mips64r2/el/usr/lib{{/|\\\\}}crt1.o"
+// CHECK-EL-HF64-64R2-N32: "[[TC]]/../../../../sysroot/mips64r2/el/usr/lib{{/|\\\\}}crti.o"
+// CHECK-EL-HF64-64R2-N32: "[[TC]]/mips64r2/el{{/|\\\\}}crtbegin.o"
+// CHECK-EL-HF64-64R2-N32: "-L[[TC]]/mips64r2/el"
+// CHECK-EL-HF64-64R2-N32: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64r2/el"
+// CHECK-EL-HF64-64R2-N32: "-L[[TC]]/../../../../sysroot/mips64r2/el/usr/lib"
+// CHECK-EL-HF64-64R2-N32: "[[TC]]/mips64r2/el{{/|\\\\}}crtend.o"
+// CHECK-EL-HF64-64R2-N32: "[[TC]]/../../../../sysroot/mips64r2/el/usr/lib{{/|\\\\}}crtn.o"
+//
 // = Little-endian, mips64r2, ABI n32, soft float
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mips64el-linux-gnu -mips64r2 -mabi=n32 -msoft-float \
@@ -1290,13 +2226,13 @@
 // CHECK-EL-SF-64R2-N32: "-internal-externc-isystem"
 // CHECK-EL-SF-64R2-N32: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-EL-SF-64R2-N32: "{{.*}}ld{{(.exe)?}}"
-// CHECK-EL-SF-64R2-N32: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips64r2/el/sof"
+// CHECK-EL-SF-64R2-N32: "--sysroot=[[TC]]/../../../../sysroot/mips64r2/el/sof"
 // CHECK-EL-SF-64R2-N32: "[[TC]]/../../../../sysroot/mips64r2/el/sof/usr/lib{{/|\\\\}}crt1.o"
 // CHECK-EL-SF-64R2-N32: "[[TC]]/../../../../sysroot/mips64r2/el/sof/usr/lib{{/|\\\\}}crti.o"
 // CHECK-EL-SF-64R2-N32: "[[TC]]/mips64r2/el/sof{{/|\\\\}}crtbegin.o"
-// CHECK-EL-SF-64R2-N32: "-L[[SR]]/mips64r2/el/sof"
-// CHECK-EL-SF-64R2-N32: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/mips64r2/el/sof"
-// CHECK-EL-SF-64R2-N32: "-L[[SR]]/../../../../sysroot/mips64r2/el/sof/usr/lib"
+// CHECK-EL-SF-64R2-N32: "-L[[TC]]/mips64r2/el/sof"
+// CHECK-EL-SF-64R2-N32: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64r2/el/sof"
+// CHECK-EL-SF-64R2-N32: "-L[[TC]]/../../../../sysroot/mips64r2/el/sof/usr/lib"
 // CHECK-EL-SF-64R2-N32: "[[TC]]/mips64r2/el/sof{{/|\\\\}}crtend.o"
 // CHECK-EL-SF-64R2-N32: "[[TC]]/../../../../sysroot/mips64r2/el/sof/usr/lib{{/|\\\\}}crtn.o"
 //
@@ -1316,16 +2252,42 @@
 // CHECK-EL-NAN-64R2-N32: "-internal-externc-isystem"
 // CHECK-EL-NAN-64R2-N32: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-EL-NAN-64R2-N32: "{{.*}}ld{{(.exe)?}}"
-// CHECK-EL-NAN-64R2-N32: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips64r2/el/nan2008"
+// CHECK-EL-NAN-64R2-N32: "--sysroot=[[TC]]/../../../../sysroot/mips64r2/el/nan2008"
 // CHECK-EL-NAN-64R2-N32: "[[TC]]/../../../../sysroot/mips64r2/el/nan2008/usr/lib{{/|\\\\}}crt1.o"
 // CHECK-EL-NAN-64R2-N32: "[[TC]]/../../../../sysroot/mips64r2/el/nan2008/usr/lib{{/|\\\\}}crti.o"
 // CHECK-EL-NAN-64R2-N32: "[[TC]]/mips64r2/el/nan2008{{/|\\\\}}crtbegin.o"
-// CHECK-EL-NAN-64R2-N32: "-L[[SR]]/mips64r2/el/nan2008"
-// CHECK-EL-NAN-64R2-N32: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/mips64r2/el/nan2008"
-// CHECK-EL-NAN-64R2-N32: "-L[[SR]]/../../../../sysroot/mips64r2/el/nan2008/usr/lib"
+// CHECK-EL-NAN-64R2-N32: "-L[[TC]]/mips64r2/el/nan2008"
+// CHECK-EL-NAN-64R2-N32: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64r2/el/nan2008"
+// CHECK-EL-NAN-64R2-N32: "-L[[TC]]/../../../../sysroot/mips64r2/el/nan2008/usr/lib"
 // CHECK-EL-NAN-64R2-N32: "[[TC]]/mips64r2/el/nan2008{{/|\\\\}}crtend.o"
 // CHECK-EL-NAN-64R2-N32: "[[TC]]/../../../../sysroot/mips64r2/el/nan2008/usr/lib{{/|\\\\}}crtn.o"
 //
+// = Little-endian, mips64r2, ABI n32, fp64, nan2008
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64el-linux-gnu -mips64r2 -mabi=n32 -mfp64 -mnan=2008 \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-EL-NAN64-64R2-N32 %s
+// CHECK-EL-NAN64-64R2-N32: "-internal-isystem"
+// CHECK-EL-NAN64-64R2-N32: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-EL-NAN64-64R2-N32: "-internal-isystem"
+// CHECK-EL-NAN64-64R2-N32: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/mips64r2/el/nan2008"
+// CHECK-EL-NAN64-64R2-N32: "-internal-isystem"
+// CHECK-EL-NAN64-64R2-N32: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-EL-NAN64-64R2-N32: "-internal-externc-isystem"
+// CHECK-EL-NAN64-64R2-N32: "[[TC]]/include"
+// CHECK-EL-NAN64-64R2-N32: "-internal-externc-isystem"
+// CHECK-EL-NAN64-64R2-N32: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-EL-NAN64-64R2-N32: "{{.*}}ld{{(.exe)?}}"
+// CHECK-EL-NAN64-64R2-N32: "--sysroot=[[TC]]/../../../../sysroot/mips64r2/el/nan2008"
+// CHECK-EL-NAN64-64R2-N32: "[[TC]]/../../../../sysroot/mips64r2/el/nan2008/usr/lib{{/|\\\\}}crt1.o"
+// CHECK-EL-NAN64-64R2-N32: "[[TC]]/../../../../sysroot/mips64r2/el/nan2008/usr/lib{{/|\\\\}}crti.o"
+// CHECK-EL-NAN64-64R2-N32: "[[TC]]/mips64r2/el/nan2008{{/|\\\\}}crtbegin.o"
+// CHECK-EL-NAN64-64R2-N32: "-L[[TC]]/mips64r2/el/nan2008"
+// CHECK-EL-NAN64-64R2-N32: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64r2/el/nan2008"
+// CHECK-EL-NAN64-64R2-N32: "-L[[TC]]/../../../../sysroot/mips64r2/el/nan2008/usr/lib"
+// CHECK-EL-NAN64-64R2-N32: "[[TC]]/mips64r2/el/nan2008{{/|\\\\}}crtend.o"
+// CHECK-EL-NAN64-64R2-N32: "[[TC]]/../../../../sysroot/mips64r2/el/nan2008/usr/lib{{/|\\\\}}crtn.o"
+//
 // = Little-endian, mips64r2, ABI 64, hard float
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mips64el-linux-gnu -mips64r2 -mabi=64 -mhard-float \
@@ -1342,16 +2304,42 @@
 // CHECK-EL-HF-64R2-64: "-internal-externc-isystem"
 // CHECK-EL-HF-64R2-64: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-EL-HF-64R2-64: "{{.*}}ld{{(.exe)?}}"
-// CHECK-EL-HF-64R2-64: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips64r2/64/el"
+// CHECK-EL-HF-64R2-64: "--sysroot=[[TC]]/../../../../sysroot/mips64r2/64/el"
 // CHECK-EL-HF-64R2-64: "[[TC]]/../../../../sysroot/mips64r2/64/el/usr/lib{{/|\\\\}}crt1.o"
 // CHECK-EL-HF-64R2-64: "[[TC]]/../../../../sysroot/mips64r2/64/el/usr/lib{{/|\\\\}}crti.o"
 // CHECK-EL-HF-64R2-64: "[[TC]]/mips64r2/64/el{{/|\\\\}}crtbegin.o"
-// CHECK-EL-HF-64R2-64: "-L[[SR]]/mips64r2/64/el"
-// CHECK-EL-HF-64R2-64: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/mips64r2/64/el"
-// CHECK-EL-HF-64R2-64: "-L[[SR]]/../../../../sysroot/mips64r2/64/el/usr/lib"
+// CHECK-EL-HF-64R2-64: "-L[[TC]]/mips64r2/64/el"
+// CHECK-EL-HF-64R2-64: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64r2/64/el"
+// CHECK-EL-HF-64R2-64: "-L[[TC]]/../../../../sysroot/mips64r2/64/el/usr/lib"
 // CHECK-EL-HF-64R2-64: "[[TC]]/mips64r2/64/el{{/|\\\\}}crtend.o"
 // CHECK-EL-HF-64R2-64: "[[TC]]/../../../../sysroot/mips64r2/64/el/usr/lib{{/|\\\\}}crtn.o"
 //
+// = Little-endian, mips64r2, ABI 64, fp64, hard float
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64el-linux-gnu -mips64r2 -mabi=64 -mfp64 -mhard-float \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-EL-HF64-64R2-64 %s
+// CHECK-EL-HF64-64R2-64: "-internal-isystem"
+// CHECK-EL-HF64-64R2-64: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-EL-HF64-64R2-64: "-internal-isystem"
+// CHECK-EL-HF64-64R2-64: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/mips64r2/64/el"
+// CHECK-EL-HF64-64R2-64: "-internal-isystem"
+// CHECK-EL-HF64-64R2-64: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-EL-HF64-64R2-64: "-internal-externc-isystem"
+// CHECK-EL-HF64-64R2-64: "[[TC]]/include"
+// CHECK-EL-HF64-64R2-64: "-internal-externc-isystem"
+// CHECK-EL-HF64-64R2-64: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-EL-HF64-64R2-64: "{{.*}}ld{{(.exe)?}}"
+// CHECK-EL-HF64-64R2-64: "--sysroot=[[TC]]/../../../../sysroot/mips64r2/64/el"
+// CHECK-EL-HF64-64R2-64: "[[TC]]/../../../../sysroot/mips64r2/64/el/usr/lib{{/|\\\\}}crt1.o"
+// CHECK-EL-HF64-64R2-64: "[[TC]]/../../../../sysroot/mips64r2/64/el/usr/lib{{/|\\\\}}crti.o"
+// CHECK-EL-HF64-64R2-64: "[[TC]]/mips64r2/64/el{{/|\\\\}}crtbegin.o"
+// CHECK-EL-HF64-64R2-64: "-L[[TC]]/mips64r2/64/el"
+// CHECK-EL-HF64-64R2-64: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64r2/64/el"
+// CHECK-EL-HF64-64R2-64: "-L[[TC]]/../../../../sysroot/mips64r2/64/el/usr/lib"
+// CHECK-EL-HF64-64R2-64: "[[TC]]/mips64r2/64/el{{/|\\\\}}crtend.o"
+// CHECK-EL-HF64-64R2-64: "[[TC]]/../../../../sysroot/mips64r2/64/el/usr/lib{{/|\\\\}}crtn.o"
+//
 // = Little-endian, mips64r2, ABI 64, soft float
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     --target=mips64el-linux-gnu -mips64r2 -mabi=64 -msoft-float \
@@ -1368,13 +2356,13 @@
 // CHECK-EL-SF-64R2-64: "-internal-externc-isystem"
 // CHECK-EL-SF-64R2-64: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-EL-SF-64R2-64: "{{.*}}ld{{(.exe)?}}"
-// CHECK-EL-SF-64R2-64: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips64r2/64/el/sof"
+// CHECK-EL-SF-64R2-64: "--sysroot=[[TC]]/../../../../sysroot/mips64r2/64/el/sof"
 // CHECK-EL-SF-64R2-64: "[[TC]]/../../../../sysroot/mips64r2/64/el/sof/usr/lib{{/|\\\\}}crt1.o"
 // CHECK-EL-SF-64R2-64: "[[TC]]/../../../../sysroot/mips64r2/64/el/sof/usr/lib{{/|\\\\}}crti.o"
 // CHECK-EL-SF-64R2-64: "[[TC]]/mips64r2/64/el/sof{{/|\\\\}}crtbegin.o"
-// CHECK-EL-SF-64R2-64: "-L[[SR]]/mips64r2/64/el/sof"
-// CHECK-EL-SF-64R2-64: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/mips64r2/64/el/sof"
-// CHECK-EL-SF-64R2-64: "-L[[SR]]/../../../../sysroot/mips64r2/64/el/sof/usr/lib"
+// CHECK-EL-SF-64R2-64: "-L[[TC]]/mips64r2/64/el/sof"
+// CHECK-EL-SF-64R2-64: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64r2/64/el/sof"
+// CHECK-EL-SF-64R2-64: "-L[[TC]]/../../../../sysroot/mips64r2/64/el/sof/usr/lib"
 // CHECK-EL-SF-64R2-64: "[[TC]]/mips64r2/64/el/sof{{/|\\\\}}crtend.o"
 // CHECK-EL-SF-64R2-64: "[[TC]]/../../../../sysroot/mips64r2/64/el/sof/usr/lib{{/|\\\\}}crtn.o"
 //
@@ -1394,12 +2382,64 @@
 // CHECK-EL-NAN-64R2-64: "-internal-externc-isystem"
 // CHECK-EL-NAN-64R2-64: "[[TC]]/../../../../sysroot/usr/include"
 // CHECK-EL-NAN-64R2-64: "{{.*}}ld{{(.exe)?}}"
-// CHECK-EL-NAN-64R2-64: "--sysroot=[[SR:[^"]+]]/../../../../sysroot/mips64r2/64/el/nan2008"
+// CHECK-EL-NAN-64R2-64: "--sysroot=[[TC]]/../../../../sysroot/mips64r2/64/el/nan2008"
 // CHECK-EL-NAN-64R2-64: "[[TC]]/../../../../sysroot/mips64r2/64/el/nan2008/usr/lib{{/|\\\\}}crt1.o"
 // CHECK-EL-NAN-64R2-64: "[[TC]]/../../../../sysroot/mips64r2/64/el/nan2008/usr/lib{{/|\\\\}}crti.o"
 // CHECK-EL-NAN-64R2-64: "[[TC]]/mips64r2/64/el/nan2008{{/|\\\\}}crtbegin.o"
-// CHECK-EL-NAN-64R2-64: "-L[[SR]]/mips64r2/64/el/nan2008"
-// CHECK-EL-NAN-64R2-64: "-L[[SR]]/../../../../mips-mti-linux-gnu/lib/mips64r2/64/el/nan2008"
-// CHECK-EL-NAN-64R2-64: "-L[[SR]]/../../../../sysroot/mips64r2/64/el/nan2008/usr/lib"
+// CHECK-EL-NAN-64R2-64: "-L[[TC]]/mips64r2/64/el/nan2008"
+// CHECK-EL-NAN-64R2-64: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64r2/64/el/nan2008"
+// CHECK-EL-NAN-64R2-64: "-L[[TC]]/../../../../sysroot/mips64r2/64/el/nan2008/usr/lib"
 // CHECK-EL-NAN-64R2-64: "[[TC]]/mips64r2/64/el/nan2008{{/|\\\\}}crtend.o"
 // CHECK-EL-NAN-64R2-64: "[[TC]]/../../../../sysroot/mips64r2/64/el/nan2008/usr/lib{{/|\\\\}}crtn.o"
+//
+// = Little-endian, mips64r2, ABI 64, fp64, nan2008
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64el-linux-gnu -mips64r2 -mabi=64 -mfp64 -mnan=2008 \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-EL-NAN64-64R2-64 %s
+// CHECK-EL-NAN64-64R2-64: "-internal-isystem"
+// CHECK-EL-NAN64-64R2-64: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-EL-NAN64-64R2-64: "-internal-isystem"
+// CHECK-EL-NAN64-64R2-64: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/mips64r2/64/el/nan2008"
+// CHECK-EL-NAN64-64R2-64: "-internal-isystem"
+// CHECK-EL-NAN64-64R2-64: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-EL-NAN64-64R2-64: "-internal-externc-isystem"
+// CHECK-EL-NAN64-64R2-64: "[[TC]]/include"
+// CHECK-EL-NAN64-64R2-64: "-internal-externc-isystem"
+// CHECK-EL-NAN64-64R2-64: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-EL-NAN64-64R2-64: "{{.*}}ld{{(.exe)?}}"
+// CHECK-EL-NAN64-64R2-64: "--sysroot=[[TC]]/../../../../sysroot/mips64r2/64/el/nan2008"
+// CHECK-EL-NAN64-64R2-64: "[[TC]]/../../../../sysroot/mips64r2/64/el/nan2008/usr/lib{{/|\\\\}}crt1.o"
+// CHECK-EL-NAN64-64R2-64: "[[TC]]/../../../../sysroot/mips64r2/64/el/nan2008/usr/lib{{/|\\\\}}crti.o"
+// CHECK-EL-NAN64-64R2-64: "[[TC]]/mips64r2/64/el/nan2008{{/|\\\\}}crtbegin.o"
+// CHECK-EL-NAN64-64R2-64: "-L[[TC]]/mips64r2/64/el/nan2008"
+// CHECK-EL-NAN64-64R2-64: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64r2/64/el/nan2008"
+// CHECK-EL-NAN64-64R2-64: "-L[[TC]]/../../../../sysroot/mips64r2/64/el/nan2008/usr/lib"
+// CHECK-EL-NAN64-64R2-64: "[[TC]]/mips64r2/64/el/nan2008{{/|\\\\}}crtend.o"
+// CHECK-EL-NAN64-64R2-64: "[[TC]]/../../../../sysroot/mips64r2/64/el/nan2008/usr/lib{{/|\\\\}}crtn.o"
+//
+// = Little-endian, default (mips64r2), ABI 64, fp64, nan2008
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64el-linux-gnu -mabi=64 -mfp64 -mnan=2008 \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_fsf_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-EL-NAN64-64R2-64-DEF %s
+// CHECK-EL-NAN64-64R2-64-DEF: "-internal-isystem"
+// CHECK-EL-NAN64-64R2-64-DEF: "[[TC:[^"]+/lib/gcc/mips-mti-linux-gnu/4.9.0]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0"
+// CHECK-EL-NAN64-64R2-64-DEF: "-internal-isystem"
+// CHECK-EL-NAN64-64R2-64-DEF: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/mips-mti-linux-gnu/mips64r2/64/el/nan2008"
+// CHECK-EL-NAN64-64R2-64-DEF: "-internal-isystem"
+// CHECK-EL-NAN64-64R2-64-DEF: "[[TC]]/../../../../mips-mti-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-EL-NAN64-64R2-64-DEF: "-internal-externc-isystem"
+// CHECK-EL-NAN64-64R2-64-DEF: "[[TC]]/include"
+// CHECK-EL-NAN64-64R2-64-DEF: "-internal-externc-isystem"
+// CHECK-EL-NAN64-64R2-64-DEF: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-EL-NAN64-64R2-64-DEF: "{{.*}}ld{{(.exe)?}}"
+// CHECK-EL-NAN64-64R2-64-DEF: "--sysroot=[[TC]]/../../../../sysroot/mips64r2/64/el/nan2008"
+// CHECK-EL-NAN64-64R2-64-DEF: "[[TC]]/../../../../sysroot/mips64r2/64/el/nan2008/usr/lib{{/|\\\\}}crt1.o"
+// CHECK-EL-NAN64-64R2-64-DEF: "[[TC]]/../../../../sysroot/mips64r2/64/el/nan2008/usr/lib{{/|\\\\}}crti.o"
+// CHECK-EL-NAN64-64R2-64-DEF: "[[TC]]/mips64r2/64/el/nan2008{{/|\\\\}}crtbegin.o"
+// CHECK-EL-NAN64-64R2-64-DEF: "-L[[TC]]/mips64r2/64/el/nan2008"
+// CHECK-EL-NAN64-64R2-64-DEF: "-L[[TC]]/../../../../mips-mti-linux-gnu/lib/mips64r2/64/el/nan2008"
+// CHECK-EL-NAN64-64R2-64-DEF: "-L[[TC]]/../../../../sysroot/mips64r2/64/el/nan2008/usr/lib"
+// CHECK-EL-NAN64-64R2-64-DEF: "[[TC]]/mips64r2/64/el/nan2008{{/|\\\\}}crtend.o"
+// CHECK-EL-NAN64-64R2-64-DEF: "[[TC]]/../../../../sysroot/mips64r2/64/el/nan2008/usr/lib{{/|\\\\}}crtn.o"
diff --git a/test/Driver/mips-img.cpp b/test/Driver/mips-img.cpp
new file mode 100644
index 0000000..389e0f7
--- /dev/null
+++ b/test/Driver/mips-img.cpp
@@ -0,0 +1,163 @@
+// Check frontend and linker invocations on the IMG MIPS toolchain.
+//
+// = Big-endian, mips32r6
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips-img-linux-gnu -mips32r6 \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_img_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BE-32R6 %s
+// CHECK-BE-32R6: "-internal-isystem"
+// CHECK-BE-32R6: "[[TC:[^"]+/lib/gcc/mips-img-linux-gnu/4.9.0]]/../../../../mips-img-linux-gnu/include/c++/4.9.0"
+// CHECK-BE-32R6: "-internal-isystem"
+// CHECK-BE-32R6: "[[TC]]/../../../../mips-img-linux-gnu/include/c++/4.9.0/mips-img-linux-gnu"
+// CHECK-BE-32R6: "-internal-isystem"
+// CHECK-BE-32R6: "[[TC]]/../../../../mips-img-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-BE-32R6: "-internal-externc-isystem"
+// CHECK-BE-32R6: "[[TC]]/include"
+// CHECK-BE-32R6: "-internal-externc-isystem"
+// CHECK-BE-32R6: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-BE-32R6: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-32R6: "--sysroot=[[TC]]/../../../../sysroot"
+// CHECK-BE-32R6: "-dynamic-linker" "/lib/ld-linux-mipsn8.so.1"
+// CHECK-BE-32R6: "[[TC]]/../../../../sysroot/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-BE-32R6: "[[TC]]/../../../../sysroot/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-BE-32R6: "[[TC]]{{/|\\\\}}crtbegin.o"
+// CHECK-BE-32R6: "-L[[TC]]"
+// CHECK-BE-32R6: "-L[[TC]]/../../../../mips-img-linux-gnu/lib/../lib"
+// CHECK-BE-32R6: "-L[[TC]]/../../../../sysroot/usr/lib/../lib"
+// CHECK-BE-32R6: "[[TC]]{{/|\\\\}}crtend.o"
+// CHECK-BE-32R6: "[[TC]]/../../../../sysroot/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
+// = Little-endian, mips32r6
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips-img-linux-gnu -mips32r6 -EL \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_img_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-LE-32R6 %s
+// CHECK-LE-32R6: "-internal-isystem"
+// CHECK-LE-32R6: "[[TC:[^"]+/lib/gcc/mips-img-linux-gnu/4.9.0]]/../../../../mips-img-linux-gnu/include/c++/4.9.0"
+// CHECK-LE-32R6: "-internal-isystem"
+// CHECK-LE-32R6: "[[TC]]/../../../../mips-img-linux-gnu/include/c++/4.9.0/mips-img-linux-gnu/el"
+// CHECK-LE-32R6: "-internal-isystem"
+// CHECK-LE-32R6: "[[TC]]/../../../../mips-img-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-LE-32R6: "-internal-externc-isystem"
+// CHECK-LE-32R6: "[[TC]]/include"
+// CHECK-LE-32R6: "-internal-externc-isystem"
+// CHECK-LE-32R6: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-LE-32R6: "{{.*}}ld{{(.exe)?}}"
+// CHECK-LE-32R6: "--sysroot=[[TC]]/../../../../sysroot/el"
+// CHECK-LE-32R6: "-dynamic-linker" "/lib/ld-linux-mipsn8.so.1"
+// CHECK-LE-32R6: "[[TC]]/../../../../sysroot/el/usr/lib/../lib{{/|\\\\}}crt1.o"
+// CHECK-LE-32R6: "[[TC]]/../../../../sysroot/el/usr/lib/../lib{{/|\\\\}}crti.o"
+// CHECK-LE-32R6: "[[TC]]/el{{/|\\\\}}crtbegin.o"
+// CHECK-LE-32R6: "-L[[TC]]/el"
+// CHECK-LE-32R6: "-L[[TC]]/../../../../mips-img-linux-gnu/lib/../lib/el"
+// CHECK-LE-32R6: "-L[[TC]]/../../../../sysroot/el/usr/lib/../lib"
+// CHECK-LE-32R6: "[[TC]]/el{{/|\\\\}}crtend.o"
+// CHECK-LE-32R6: "[[TC]]/../../../../sysroot/el/usr/lib/../lib{{/|\\\\}}crtn.o"
+//
+// = Big-endian, mips64r6, N32
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64-img-linux-gnu -mips64r6 -mabi=n32 \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_img_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BE-64R6-N32 %s
+// CHECK-BE-64R6-N32: "-internal-isystem"
+// CHECK-BE-64R6-N32: "[[TC:[^"]+/lib/gcc/mips-img-linux-gnu/4.9.0]]/../../../../mips-img-linux-gnu/include/c++/4.9.0"
+// CHECK-BE-64R6-N32: "-internal-isystem"
+// CHECK-BE-64R6-N32: "[[TC]]/../../../../mips-img-linux-gnu/include/c++/4.9.0/mips-img-linux-gnu/mips64r6"
+// CHECK-BE-64R6-N32: "-internal-isystem"
+// CHECK-BE-64R6-N32: "[[TC]]/../../../../mips-img-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-BE-64R6-N32: "-internal-externc-isystem"
+// CHECK-BE-64R6-N32: "[[TC]]/include"
+// CHECK-BE-64R6-N32: "-internal-externc-isystem"
+// CHECK-BE-64R6-N32: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-BE-64R6-N32: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-64R6-N32: "--sysroot=[[TC]]/../../../../sysroot/mips64r6"
+// CHECK-BE-64R6-N32: "-dynamic-linker" "/lib32/ld-linux-mipsn8.so.1"
+// CHECK-BE-64R6-N32: "[[TC]]/../../../../sysroot/mips64r6/usr/lib{{/|\\\\}}crt1.o"
+// CHECK-BE-64R6-N32: "[[TC]]/../../../../sysroot/mips64r6/usr/lib{{/|\\\\}}crti.o"
+// CHECK-BE-64R6-N32: "[[TC]]/mips64r6{{/|\\\\}}crtbegin.o"
+// CHECK-BE-64R6-N32: "-L[[TC]]/mips64r6"
+// CHECK-BE-64R6-N32: "-L[[TC]]/../../../../mips-img-linux-gnu/lib/mips64r6"
+// CHECK-BE-64R6-N32: "-L[[TC]]/../../../../sysroot/mips64r6/usr/lib"
+// CHECK-BE-64R6-N32: "[[TC]]/mips64r6{{/|\\\\}}crtend.o"
+// CHECK-BE-64R6-N32: "[[TC]]/../../../../sysroot/mips64r6/usr/lib{{/|\\\\}}crtn.o"
+//
+// = Little-endian, mips64r6, N32
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64-img-linux-gnu -mips64r6 -EL -mabi=n32 \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_img_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-LE-64R6-N32 %s
+// CHECK-LE-64R6-N32: "-internal-isystem"
+// CHECK-LE-64R6-N32: "[[TC:[^"]+/lib/gcc/mips-img-linux-gnu/4.9.0]]/../../../../mips-img-linux-gnu/include/c++/4.9.0"
+// CHECK-LE-64R6-N32: "-internal-isystem"
+// CHECK-LE-64R6-N32: "[[TC]]/../../../../mips-img-linux-gnu/include/c++/4.9.0/mips-img-linux-gnu/mips64r6/el"
+// CHECK-LE-64R6-N32: "-internal-isystem"
+// CHECK-LE-64R6-N32: "[[TC]]/../../../../mips-img-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-LE-64R6-N32: "-internal-externc-isystem"
+// CHECK-LE-64R6-N32: "[[TC]]/include"
+// CHECK-LE-64R6-N32: "-internal-externc-isystem"
+// CHECK-LE-64R6-N32: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-LE-64R6-N32: "{{.*}}ld{{(.exe)?}}"
+// CHECK-LE-64R6-N32: "--sysroot=[[TC]]/../../../../sysroot/mips64r6/el"
+// CHECK-LE-64R6-N32: "-dynamic-linker" "/lib32/ld-linux-mipsn8.so.1"
+// CHECK-LE-64R6-N32: "[[TC]]/../../../../sysroot/mips64r6/el/usr/lib{{/|\\\\}}crt1.o"
+// CHECK-LE-64R6-N32: "[[TC]]/../../../../sysroot/mips64r6/el/usr/lib{{/|\\\\}}crti.o"
+// CHECK-LE-64R6-N32: "[[TC]]/mips64r6/el{{/|\\\\}}crtbegin.o"
+// CHECK-LE-64R6-N32: "-L[[TC]]/mips64r6/el"
+// CHECK-LE-64R6-N32: "-L[[TC]]/../../../../mips-img-linux-gnu/lib/mips64r6/el"
+// CHECK-LE-64R6-N32: "-L[[TC]]/../../../../sysroot/mips64r6/el/usr/lib"
+// CHECK-LE-64R6-N32: "[[TC]]/mips64r6/el{{/|\\\\}}crtend.o"
+// CHECK-LE-64R6-N32: "[[TC]]/../../../../sysroot/mips64r6/el/usr/lib{{/|\\\\}}crtn.o"
+//
+// = Big-endian, mips64r6, N64
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64-img-linux-gnu -mips64r6 -mabi=64 \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_img_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-BE-64R6-N64 %s
+// CHECK-BE-64R6-N64: "-internal-isystem"
+// CHECK-BE-64R6-N64: "[[TC:[^"]+/lib/gcc/mips-img-linux-gnu/4.9.0]]/../../../../mips-img-linux-gnu/include/c++/4.9.0"
+// CHECK-BE-64R6-N64: "-internal-isystem"
+// CHECK-BE-64R6-N64: "[[TC]]/../../../../mips-img-linux-gnu/include/c++/4.9.0/mips-img-linux-gnu/mips64r6/64"
+// CHECK-BE-64R6-N64: "-internal-isystem"
+// CHECK-BE-64R6-N64: "[[TC]]/../../../../mips-img-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-BE-64R6-N64: "-internal-externc-isystem"
+// CHECK-BE-64R6-N64: "[[TC]]/include"
+// CHECK-BE-64R6-N64: "-internal-externc-isystem"
+// CHECK-BE-64R6-N64: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-BE-64R6-N64: "{{.*}}ld{{(.exe)?}}"
+// CHECK-BE-64R6-N64: "--sysroot=[[TC]]/../../../../sysroot/mips64r6/64"
+// CHECK-BE-64R6-N64: "-dynamic-linker" "/lib64/ld-linux-mipsn8.so.1"
+// CHECK-BE-64R6-N64: "[[TC]]/../../../../sysroot/mips64r6/64/usr/lib{{/|\\\\}}crt1.o"
+// CHECK-BE-64R6-N64: "[[TC]]/../../../../sysroot/mips64r6/64/usr/lib{{/|\\\\}}crti.o"
+// CHECK-BE-64R6-N64: "[[TC]]/mips64r6/64{{/|\\\\}}crtbegin.o"
+// CHECK-BE-64R6-N64: "-L[[TC]]/mips64r6/64"
+// CHECK-BE-64R6-N64: "-L[[TC]]/../../../../mips-img-linux-gnu/lib/mips64r6/64"
+// CHECK-BE-64R6-N64: "-L[[TC]]/../../../../sysroot/mips64r6/64/usr/lib"
+// CHECK-BE-64R6-N64: "[[TC]]/mips64r6/64{{/|\\\\}}crtend.o"
+// CHECK-BE-64R6-N64: "[[TC]]/../../../../sysroot/mips64r6/64/usr/lib{{/|\\\\}}crtn.o"
+//
+// = Little-endian, mips64r6, N64
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips64-img-linux-gnu -mips64r6 -EL -mabi=64 \
+// RUN:     --gcc-toolchain=%S/Inputs/mips_img_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-LE-64R6-N64 %s
+// CHECK-LE-64R6-N64: "-internal-isystem"
+// CHECK-LE-64R6-N64: "[[TC:[^"]+/lib/gcc/mips-img-linux-gnu/4.9.0]]/../../../../mips-img-linux-gnu/include/c++/4.9.0"
+// CHECK-LE-64R6-N64: "-internal-isystem"
+// CHECK-LE-64R6-N64: "[[TC]]/../../../../mips-img-linux-gnu/include/c++/4.9.0/mips-img-linux-gnu/mips64r6/64/el"
+// CHECK-LE-64R6-N64: "-internal-isystem"
+// CHECK-LE-64R6-N64: "[[TC]]/../../../../mips-img-linux-gnu/include/c++/4.9.0/backward"
+// CHECK-LE-64R6-N64: "-internal-externc-isystem"
+// CHECK-LE-64R6-N64: "[[TC]]/include"
+// CHECK-LE-64R6-N64: "-internal-externc-isystem"
+// CHECK-LE-64R6-N64: "[[TC]]/../../../../sysroot/usr/include"
+// CHECK-LE-64R6-N64: "{{.*}}ld{{(.exe)?}}"
+// CHECK-LE-64R6-N64: "--sysroot=[[TC]]/../../../../sysroot/mips64r6/64/el"
+// CHECK-LE-64R6-N64: "-dynamic-linker" "/lib64/ld-linux-mipsn8.so.1"
+// CHECK-LE-64R6-N64: "[[TC]]/../../../../sysroot/mips64r6/64/el/usr/lib{{/|\\\\}}crt1.o"
+// CHECK-LE-64R6-N64: "[[TC]]/../../../../sysroot/mips64r6/64/el/usr/lib{{/|\\\\}}crti.o"
+// CHECK-LE-64R6-N64: "[[TC]]/mips64r6/64/el{{/|\\\\}}crtbegin.o"
+// CHECK-LE-64R6-N64: "-L[[TC]]/mips64r6/64/el"
+// CHECK-LE-64R6-N64: "-L[[TC]]/../../../../mips-img-linux-gnu/lib/mips64r6/64/el"
+// CHECK-LE-64R6-N64: "-L[[TC]]/../../../../sysroot/mips64r6/64/el/usr/lib"
+// CHECK-LE-64R6-N64: "[[TC]]/mips64r6/64/el{{/|\\\\}}crtend.o"
+// CHECK-LE-64R6-N64: "[[TC]]/../../../../sysroot/mips64r6/64/el/usr/lib{{/|\\\\}}crtn.o"
diff --git a/test/Driver/mips-integrated-as.s b/test/Driver/mips-integrated-as.s
new file mode 100644
index 0000000..c3b1db3
--- /dev/null
+++ b/test/Driver/mips-integrated-as.s
@@ -0,0 +1,207 @@
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s 2>&1 | \
+// RUN:   FileCheck -check-prefix=ABI-O32 %s
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s -mabi=32 2>&1 | \
+// RUN:   FileCheck -check-prefix=ABI-O32 %s
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s -mabi=o32 2>&1 | \
+// RUN:   FileCheck -check-prefix=ABI-O32 %s
+// ABI-O32: -cc1as
+// ABI-O32: "-target-feature" "-n64"
+// ABI-O32: "-target-feature" "+o32"
+
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s -mabi=eabi 2>&1 | \
+// RUN:   FileCheck -check-prefix=ABI-EABI32 %s
+// ABI-EABI32: -cc1as
+// ABI-EABI32: "-target-feature" "-o32"
+// ABI-EABI32: "-target-feature" "-n64"
+// ABI-EABI32: "-target-feature" "+eabi"
+
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s -mips64 -mabi=n32 2>&1 | \
+// RUN:   FileCheck -check-prefix=ABI-N32 %s
+// RUN: %clang -target mips64-linux-gnu -### -fintegrated-as -c %s -mabi=n32 2>&1 | \
+// RUN:   FileCheck -check-prefix=ABI-N32 %s
+// ABI-N32: -cc1as
+// ABI-N32: "-target-feature" "-o32"
+// ABI-N32: "-target-feature" "-n64"
+// ABI-N32: "-target-feature" "+n32"
+
+// FIXME: We should also test '-target mips-linux-gnu -mips64' defaults to the
+//        default 64-bit ABI (N64 but GCC uses N32). It currently selects O32
+//        because of the triple.
+// RUN: %clang -target mips64-linux-gnu -### -fintegrated-as -c %s -mips64 2>&1 | \
+// RUN:   FileCheck -check-prefix=ABI-N64 %s
+//
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s -mips64 -mabi=64 2>&1 | \
+// RUN:   FileCheck -check-prefix=ABI-N64 %s
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s -mips64 -mabi=n64 2>&1 | \
+// RUN:   FileCheck -check-prefix=ABI-N64 %s
+// RUN: %clang -target mips64-linux-gnu -### -fintegrated-as -c %s -mips64 -mabi=64 2>&1 | \
+// RUN:   FileCheck -check-prefix=ABI-N64 %s
+// RUN: %clang -target mips64-linux-gnu -### -fintegrated-as -c %s -mips64 -mabi=n64 2>&1 | \
+// RUN:   FileCheck -check-prefix=ABI-N64 %s
+// ABI-N64: -cc1as
+// ABI-N64: "-target-feature" "-o32"
+// ABI-N64: "-target-feature" "+n64"
+
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s -msoft-float 2>&1 | \
+// RUN:   FileCheck -check-prefix=SOFTFLOAT %s
+// SOFTFLOAT: -cc1as
+// SOFTFLOAT: "-target-feature" "+soft-float"
+
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s 2>&1 | \
+// RUN:   FileCheck -check-prefix=HARDFLOAT %s
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s -mhard-float 2>&1 | \
+// RUN:   FileCheck -check-prefix=HARDFLOAT %s
+// HARDFLOAT: -cc1as
+// HARDFLOAT-NOT: "-target-feature" "+soft-float"
+
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s 2>&1 | \
+// RUN:   FileCheck -check-prefix=NAN-DEFAULT %s
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s -mips32r6 2>&1 | \
+// RUN:   FileCheck -check-prefix=NAN-DEFAULT %s
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s -mips64r6 2>&1 | \
+// RUN:   FileCheck -check-prefix=NAN-DEFAULT %s
+// NAN-DEFAULT: -cc1as
+// NAN-DEFAULT-NOT: "-target-feature" "{{[-+]}}nan2008"
+
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s -mnan=legacy 2>&1 | \
+// RUN:   FileCheck -check-prefix=NAN-LEGACY %s
+// NAN-LEGACY: -cc1as
+// NAN-LEGACY: "-target-feature" "-nan2008"
+
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s -mnan=2008 2>&1 | \
+// RUN:   FileCheck -check-prefix=NAN-2008 %s
+// NAN-2008: -cc1as
+// NAN-2008: "-target-feature" "+nan2008"
+
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s 2>&1 | \
+// RUN:   FileCheck -check-prefix=DEFAULT-FLOAT %s
+// DEFAULT-FLOAT: -cc1as
+// DEFAULT-FLOAT-NOT: "-target-feature" "{{[+-]}}single-float"
+
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s -msingle-float 2>&1 | \
+// RUN:   FileCheck -check-prefix=SINGLE-FLOAT %s
+// SINGLE-FLOAT: -cc1as
+// SINGLE-FLOAT: "-target-feature" "+single-float"
+
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s -mdouble-float 2>&1 | \
+// RUN:   FileCheck -check-prefix=DOUBLE-FLOAT %s
+// DOUBLE-FLOAT: -cc1as
+// DOUBLE-FLOAT: "-target-feature" "-single-float"
+
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s 2>&1 | \
+// RUN:   FileCheck -check-prefix=MIPS16-DEFAULT %s
+// MIPS16-DEFAULT: -cc1as
+// MIPS16-DEFAULT-NOT: "-target-feature" "{{[+-]}}mips16"
+
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s -mips16 2>&1 | \
+// RUN:   FileCheck -check-prefix=MIPS16-ON %s
+// MIPS16-ON: -cc1as
+// MIPS16-ON: "-target-feature" "+mips16"
+
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s -mno-mips16 2>&1 | \
+// RUN:   FileCheck -check-prefix=MIPS16-OFF %s
+// MIPS16-OFF: -cc1as
+// MIPS16-OFF: "-target-feature" "-mips16"
+
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s 2>&1 | \
+// RUN:   FileCheck -check-prefix=MICROMIPS-DEFAULT %s
+// MICROMIPS-DEFAULT: -cc1as
+// MICROMIPS-DEFAULT-NOT: "-target-feature" "{{[+-]}}micromips"
+
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s -mmicromips 2>&1 | \
+// RUN:   FileCheck -check-prefix=MICROMIPS-ON %s
+// MICROMIPS-ON: -cc1as
+// MICROMIPS-ON: "-target-feature" "+micromips"
+
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s -mno-micromips 2>&1 | \
+// RUN:   FileCheck -check-prefix=MICROMIPS-OFF %s
+// MICROMIPS-OFF: -cc1as
+// MICROMIPS-OFF: "-target-feature" "-micromips"
+
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s 2>&1 | \
+// RUN:   FileCheck -check-prefix=DSP-DEFAULT %s
+// DSP-DEFAULT: -cc1as
+// DSP-DEFAULT-NOT: "-target-feature" "{{[+-]}}dsp"
+
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s -mdsp 2>&1 | \
+// RUN:   FileCheck -check-prefix=DSP-ON %s
+// DSP-ON: -cc1as
+// DSP-ON: "-target-feature" "+dsp"
+
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s -mno-dsp 2>&1 | \
+// RUN:   FileCheck -check-prefix=DSP-OFF %s
+// DSP-OFF: -cc1as
+// DSP-OFF: "-target-feature" "-dsp"
+
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s 2>&1 | \
+// RUN:   FileCheck -check-prefix=DSPR2-DEFAULT %s
+// DSPR2-DEFAULT: -cc1as
+// DSPR2-DEFAULT-NOT: "-target-feature" "{{[+-]}}dspr2"
+
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s -mdspr2 2>&1 | \
+// RUN:   FileCheck -check-prefix=DSPR2-ON %s
+// DSPR2-ON: -cc1as
+// DSPR2-ON: "-target-feature" "+dspr2"
+
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s -mno-dspr2 2>&1 | \
+// RUN:   FileCheck -check-prefix=DSPR2-OFF %s
+// DSPR2-OFF: -cc1as
+// DSPR2-OFF: "-target-feature" "-dspr2"
+
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s 2>&1 | \
+// RUN:   FileCheck -check-prefix=MSA-DEFAULT %s
+// MSA-DEFAULT: -cc1as
+// MSA-DEFAULT-NOT: "-target-feature" "{{[+-]}}msa"
+
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s -mmsa 2>&1 | \
+// RUN:   FileCheck -check-prefix=MSA-ON %s
+// MSA-ON: -cc1as
+// MSA-ON: "-target-feature" "+msa"
+
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s -mno-msa 2>&1 | \
+// RUN:   FileCheck -check-prefix=MSA-OFF %s
+// MSA-OFF: -cc1as
+// MSA-OFF: "-target-feature" "-msa"
+
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s 2>&1 | \
+// RUN:   FileCheck -check-prefix=FPXX-DEFAULT %s
+// FPXX-DEFAULT: -cc1as
+// FPXX-DEFAULT-NOT: "-target-feature" "+fpxx"
+// FPXX-DEFAULT-NOT: "-target-feature" "+nooddspreg"
+
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s -mfp32 2>&1 | \
+// RUN:   FileCheck -check-prefix=FP32 %s
+// FP32: -cc1as
+// FP32: "-target-feature" "-fp64"
+
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s -mfpxx 2>&1 | \
+// RUN:   FileCheck -check-prefix=FPXX %s
+// FPXX: -cc1as
+// FPXX: "-target-feature" "+fpxx"
+// FPXX: "-target-feature" "+nooddspreg"
+
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s -mfp64 2>&1 | \
+// RUN:   FileCheck -check-prefix=FP64 %s
+// FP64: -cc1as
+// FP64: "-target-feature" "+fp64"
+
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s 2>&1 | \
+// RUN:   FileCheck -check-prefix=ODDSPREG-DEFAULT %s
+// ODDSPREG-DEFAULT: -cc1as
+// ODDSPREG-DEFAULT-NOT: "-target-feature" "{{[+-]}}nooddspreg"
+
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s -modd-spreg 2>&1 | \
+// RUN:   FileCheck -check-prefix=ODDSPREG-ON %s
+// ODDSPREG-ON: -cc1as
+// ODDSPREG-ON: "-target-feature" "-nooddspreg"
+
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s -mno-odd-spreg 2>&1 | \
+// RUN:   FileCheck -check-prefix=ODDSPREG-OFF %s
+// ODDSPREG-OFF: -cc1as
+// ODDSPREG-OFF: "-target-feature" "+nooddspreg"
+
+// RUN: %clang -target mips-linux-gnu -### -fintegrated-as -c %s -mfpxx -modd-spreg 2>&1 | \
+// RUN:   FileCheck -check-prefix=FPXX-ODDSPREG %s
+// FPXX-ODDSPREG: -cc1as
+// FPXX-ODDSPREG: "-target-feature" "+fpxx"
+// FPXX-ODDSPREG: "-target-feature" "-nooddspreg"
diff --git a/test/Driver/mips-reduced-toolchain.cpp b/test/Driver/mips-reduced-toolchain.cpp
new file mode 100644
index 0000000..fe7ed8a
--- /dev/null
+++ b/test/Driver/mips-reduced-toolchain.cpp
@@ -0,0 +1,28 @@
+// Check frontend and linker invocations on reduced Debian MIPS toolchain.
+// This toolchain icludes O32 ABI only.
+
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mips-linux-gnu \
+// RUN:     --sysroot=%S/Inputs/debian_reduced_mips_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-DEBIAN-MIPS %s
+// CHECK-DEBIAN-MIPS: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-DEBIAN-MIPS: "{{.*}}/usr/lib/gcc/mips-linux-gnu/4.7{{/|\\\\}}crtbegin.o"
+// CHECK-DEBIAN-MIPS: "-L[[SYSROOT]]/usr/lib/gcc/mips-linux-gnu/4.7"
+// CHECK-DEBIAN-MIPS: "-L[[SYSROOT]]/usr/lib/gcc/mips-linux-gnu/4.7/../../../mips-linux-gnu"
+// CHECK-DEBIAN-MIPS: "-L[[SYSROOT]]/usr/lib/mips-linux-gnu"
+// CHECK-DEBIAN-MIPS: "-L[[SYSROOT]]/usr/lib/gcc/mips-linux-gnu/4.7/../../.."
+// CHECK-DEBIAN-MIPS: "-L[[SYSROOT]]/lib"
+// CHECK-DEBIAN-MIPS: "-L[[SYSROOT]]/usr/lib"
+
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     --target=mipsel-linux-gnu \
+// RUN:     --sysroot=%S/Inputs/debian_reduced_mips_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-DEBIAN-MIPSEL %s
+// CHECK-DEBIAN-MIPSEL: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-DEBIAN-MIPSEL: "{{.*}}/usr/lib/gcc/mipsel-linux-gnu/4.7{{/|\\\\}}crtbegin.o"
+// CHECK-DEBIAN-MIPSEL: "-L[[SYSROOT]]/usr/lib/gcc/mipsel-linux-gnu/4.7"
+// CHECK-DEBIAN-MIPSEL: "-L[[SYSROOT]]/usr/lib/gcc/mipsel-linux-gnu/4.7/../../../mipsel-linux-gnu"
+// CHECK-DEBIAN-MIPSEL: "-L[[SYSROOT]]/usr/lib/mipsel-linux-gnu"
+// CHECK-DEBIAN-MIPSEL: "-L[[SYSROOT]]/usr/lib/gcc/mipsel-linux-gnu/4.7/../../.."
+// CHECK-DEBIAN-MIPSEL: "-L[[SYSROOT]]/lib"
+// CHECK-DEBIAN-MIPSEL: "-L[[SYSROOT]]/usr/lib"
diff --git a/test/Driver/mno-global-merge.c b/test/Driver/mno-global-merge.c
index ec9f69e..a17848f 100644
--- a/test/Driver/mno-global-merge.c
+++ b/test/Driver/mno-global-merge.c
@@ -2,11 +2,19 @@
 // RUN:   -mno-global-merge -### -fsyntax-only %s 2> %t
 // RUN: FileCheck --check-prefix=CHECK-NGM < %t %s
 
+// RUN: %clang -target arm64-apple-ios7 \
+// RUN:   -mno-global-merge -### -fsyntax-only %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-NGM < %t %s
+
 // CHECK-NGM: "-mno-global-merge"
 
 // RUN: %clang -target armv7-apple-darwin10 \
 // RUN:   -mglobal-merge -### -fsyntax-only %s 2> %t
 // RUN: FileCheck --check-prefix=CHECK-GM < %t %s
 
+// RUN: %clang -target arm64-apple-ios7 \
+// RUN:   -mglobal-merge -### -fsyntax-only %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK-GM < %t %s
+
 // CHECK-GM-NOT: "-mglobal-merge"
 
diff --git a/test/Driver/modules.m b/test/Driver/modules.m
index b93054d..d8e20e4 100644
--- a/test/Driver/modules.m
+++ b/test/Driver/modules.m
@@ -4,3 +4,18 @@
 // RUN: %clang -fmodules -fno-modules -fmodules -### %s 2>&1 | FileCheck -check-prefix=CHECK-HAS-MODULES %s
 // CHECK-HAS-MODULES: -fmodules
 
+// RUN: %clang -fbuild-session-timestamp=123 -### %s 2>&1 | FileCheck -check-prefix=TIMESTAMP_ONLY %s
+// TIMESTAMP_ONLY: -fbuild-session-timestamp=123
+
+// RUN: %clang -fbuild-session-timestamp=123 -fmodules-validate-once-per-build-session -### %s 2>&1 | FileCheck -check-prefix=MODULES_VALIDATE_ONCE %s
+// MODULES_VALIDATE_ONCE: -fbuild-session-timestamp=123
+// MODULES_VALIDATE_ONCE: -fmodules-validate-once-per-build-session
+
+// RUN: %clang -fmodules-validate-once-per-build-session -### %s 2>&1 | FileCheck -check-prefix=MODULES_VALIDATE_ONCE_ERR %s
+// MODULES_VALIDATE_ONCE_ERR: option '-fmodules-validate-once-per-build-session' requires '-fbuild-session-timestamp=<seconds since Epoch>'
+
+// RUN: %clang -### %s 2>&1 | FileCheck -check-prefix=MODULES_VALIDATE_SYSTEM_HEADERS_DEFAULT %s
+// MODULES_VALIDATE_SYSTEM_HEADERS_DEFAULT-NOT: -fmodules-validate-system-headers
+
+// RUN: %clang -fmodules-validate-system-headers -### %s 2>&1 | FileCheck -check-prefix=MODULES_VALIDATE_SYSTEM_HEADERS %s
+// MODULES_VALIDATE_SYSTEM_HEADERS: -fmodules-validate-system-headers
diff --git a/test/Driver/msc-version.c b/test/Driver/msc-version.c
new file mode 100644
index 0000000..1a88419
--- /dev/null
+++ b/test/Driver/msc-version.c
@@ -0,0 +1,68 @@
+//
+// Verify defaults
+//
+
+// RUN: %clang -target i686-windows -fms-compatibility -dM -E - </dev/null -o - | FileCheck %s -check-prefix CHECK-NO-MSC-VERSION
+
+// CHECK-NO-MSC-VERSION: _MSC_BUILD 1
+// CHECK-NO-MSC-VERSION: _MSC_FULL_VER 170000000
+// CHECK-NO-MSC-VERSION: _MSC_VER 1700
+
+
+//
+// Verify -fms-compatibility-version parsing
+//
+
+// RUN: %clang -target i686-windows -fms-compatibility -fms-compatibility-version=14 -dM -E - </dev/null -o - | FileCheck %s -check-prefix CHECK-MSC-VERSION-MAJOR
+
+// CHECK-MSC-VERSION-MAJOR: _MSC_BUILD 1
+// CHECK-MSC-VERSION-MAJOR: _MSC_FULL_VER 140000000
+// CHECK-MSC-VERSION-MAJOR: _MSC_VER 1400
+
+// RUN: %clang -target i686-windows -fms-compatibility -fms-compatibility-version=15.00 -dM -E - </dev/null -o - | FileCheck %s -check-prefix CHECK-MSC-VERSION-MAJOR-MINOR
+
+// CHECK-MSC-VERSION-MAJOR-MINOR: _MSC_BUILD 1
+// CHECK-MSC-VERSION-MAJOR-MINOR: _MSC_FULL_VER 150000000
+// CHECK-MSC-VERSION-MAJOR-MINOR: _MSC_VER 1500
+
+// RUN: %clang -target i686-windows -fms-compatibility -fms-compatibility-version=15.00.20706 -dM -E - </dev/null -o - | FileCheck %s -check-prefix CHECK-MSC-VERSION-MAJOR-MINOR-BUILD
+
+// CHECK-MSC-VERSION-MAJOR-MINOR-BUILD: _MSC_BUILD 1
+// CHECK-MSC-VERSION-MAJOR-MINOR-BUILD: _MSC_FULL_VER 150020706
+// CHECK-MSC-VERSION-MAJOR-MINOR-BUILD: _MSC_VER 1500
+
+// RUN: %clang -target i686-windows -fms-compatibility -fms-compatibility-version=15.00.20706.01 -dM -E - </dev/null -o - | FileCheck %s -check-prefix CHECK-MSC-VERSION-MAJOR-MINOR-BUILD-PATCH
+
+// CHECK-MSC-VERSION-MAJOR-MINOR-BUILD-PATCH: _MSC_BUILD 1
+// CHECK-MSC-VERSION-MAJOR-MINOR-BUILD-PATCH: _MSC_FULL_VER 150020706
+// CHECK-MSC-VERSION-MAJOR-MINOR-BUILD-PATCH: _MSC_VER 1500
+
+
+//
+// Verify -fmsc-version and -fms-compatibility-version diagnostic
+//
+
+// RUN: not %clang -target i686-windows -fms-compatibility -fmsc-version=1700 -fms-compatibility-version=17.00.50727.1 -E - </dev/null 2>&1 | FileCheck %s -check-prefix CHECK-BASIC-EXTENDED-DIAGNOSTIC
+
+// CHECK-BASIC-EXTENDED-DIAGNOSTIC: invalid argument '-fmsc-version={{.*}}' not allowed with '-fms-compatibility-version={{.*}}'
+
+
+//
+// Verify -fmsc-version to -fms-compatibility-version conversion
+//
+
+// RUN: %clang -### -target i686-windows -fms-compatibility -fmsc-version=17 -E - </dev/null -o /dev/null 2>&1 | FileCheck %s -check-prefix CHECK-MSC-17
+
+// CHECK-MSC-17-NOT: "-fmsc-version=1700"
+// CHECK-MSC-17: "-fms-compatibility-version=17.0"
+
+// RUN: %clang -### -target i686-windows -fms-compatibility -fmsc-version=1600 -E - </dev/null -o /dev/null 2>&1 | FileCheck %s -check-prefix CHECK-MSC-16
+
+// CHECK-MSC-16-NOT: "-fmsc-version=1600"
+// CHECK-MSC-16: "-fms-compatibility-version=16.0"
+
+// RUN: %clang -### -target i686-windows -fms-compatibility -fmsc-version=150020706 -E - </dev/null -o /dev/null 2>&1 | FileCheck %s -check-prefix CHECK-MSC-15
+
+// CHECK-MSC-15-NOT: "-fmsc-version=150020706"
+// CHECK-MSC-15: "-fms-compatibility-version=15.0.20706"
+
diff --git a/test/Driver/nacl-direct.c b/test/Driver/nacl-direct.c
new file mode 100644
index 0000000..ddb2ae4
--- /dev/null
+++ b/test/Driver/nacl-direct.c
@@ -0,0 +1,41 @@
+// Test clang changes for NaCl Support including:
+//    include paths, library paths, emulation, default static
+//
+// RUN: %clang -### -o %t.o %s 2>&1 \
+// RUN:     -target armv7a-unknown-nacl-gnueabihf \
+// RUN:   | FileCheck --check-prefix=CHECK-ARM %s
+// CHECK-ARM: {{.*}}clang{{.*}}" "-cc1"
+// CHECK-ARM: "-target-cpu" "cortex-a8"
+// CHECK-ARM: "-resource-dir" "{{.*}}/lib/clang/[[VER:[0-9.]+]]"
+// CHECK-ARM: "-internal-isystem" "{{.*}}/../lib/clang/[[VER]]/include"
+// CHECK-ARM: "-internal-isystem" "{{.*}}/../arm-nacl/include"
+// CHECK-ARM: "-m" "armelf_nacl"
+// CHECK-ARM: "-static"
+// CHECK-ARM: "-L{{.*}}/../arm-nacl/lib"
+// CHECK-ARM: "-L{{.*}}/../lib/clang/[[VER]]/lib/arm-nacl"
+//
+// RUN: %clang -### -o %t.o %s 2>&1 \
+// RUN:     -target i686-unknown-nacl \
+// RUN:   | FileCheck --check-prefix=CHECK-I686 %s
+// CHECK-I686: {{.*}}clang{{.*}}" "-cc1"
+// CHECK-I686: "-target-cpu" "pentium4"
+// CHECK-I686: "-resource-dir" "{{.*}}/lib/clang/[[VER:[0-9.]+]]"
+// CHECK-I686: "-internal-isystem" "{{.*}}/../lib/clang/[[VER]]/include"
+// CHECK-I686: "-internal-isystem" "{{.*}}/../x86_64-nacl/include"
+// CHECK-I686: "-m" "elf_i386_nacl"
+// CHECK-I686: "-static"
+// CHECK-I686: "-L{{.*}}/../x86_64-nacl/lib32"
+// CHECK-I686: "-L{{.*}}/../lib/clang/[[VER]]/lib/i686-nacl"
+//
+// RUN: %clang -### -o %t.o %s 2>&1 \
+// RUN:     -target x86_64-unknown-nacl \
+// RUN:   | FileCheck --check-prefix=CHECK-x86_64 %s
+// CHECK-x86_64: {{.*}}clang{{.*}}" "-cc1"
+// CHECK-x86_64: "-target-cpu" "x86-64"
+// CHECK-x86_64: "-resource-dir" "{{.*}}/lib/clang/[[VER:[0-9.]+]]"
+// CHECK-x86_64: "-internal-isystem" "{{.*}}/../lib/clang/[[VER]]/include"
+// CHECK-x86_64: "-internal-isystem" "{{.*}}/../x86_64-nacl/include"
+// CHECK-x86_64: "-m" "elf_x86_64_nacl"
+// CHECK-x86_64: "-static"
+// CHECK-x86_64: "-L{{.*}}/../x86_64-nacl/lib"
+// CHECK-x86_64: "-L{{.*}}/../lib/clang/[[VER]]/lib/x86_64-nacl"
diff --git a/test/Driver/netbsd.c b/test/Driver/netbsd.c
index 09c2bd3..0e3ebf3 100644
--- a/test/Driver/netbsd.c
+++ b/test/Driver/netbsd.c
@@ -7,6 +7,42 @@
 // RUN: %clang -no-canonical-prefixes -target x86_64--netbsd6.0.0 \
 // RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
 // RUN: | FileCheck -check-prefix=X86_64-6 %s
+// RUN: %clang -no-canonical-prefixes -target aarch64--netbsd \
+// RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=AARCH64 %s
+// 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 arm64--netbsd \
+// RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=ARM64 %s
+// RUN: %clang -no-canonical-prefixes -target arm64--netbsd7.0.0 \
+// RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=ARM64-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
+// RUN: %clang -no-canonical-prefixes -target arm--netbsd \
+// RUN: -no-integrated-as --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=ARM-APCS %s
+// RUN: %clang -no-canonical-prefixes -target thumb--netbsd-eabi \
+// RUN: -no-integrated-as --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=THUMB %s
+// RUN: %clang -no-canonical-prefixes -target arm--netbsd7.0.0-eabi \
+// RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=ARM-7 %s
+// RUN: %clang -no-canonical-prefixes -target arm--netbsd6.0.0-eabi \
+// RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=ARM-6 %s
+// RUN: %clang -no-canonical-prefixes -target arm--netbsd-eabihf \
+// RUN: -no-integrated-as --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=ARM-HF %s
+// RUN: %clang -no-canonical-prefixes -target sparc--netbsd \
+// RUN: -no-integrated-as --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=SPARC %s
+// RUN: %clang -no-canonical-prefixes -target sparc64--netbsd \
+// RUN: -no-integrated-as --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=SPARC64 %s
 
 // RUN: %clang -no-canonical-prefixes -target x86_64--netbsd -static \
 // RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
@@ -17,6 +53,33 @@
 // RUN: %clang -no-canonical-prefixes -target x86_64--netbsd6.0.0 -static \
 // RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
 // RUN: | FileCheck -check-prefix=S-X86_64-6 %s
+// RUN: %clang -no-canonical-prefixes -target aarch64--netbsd -static \
+// RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=S-AARCH64 %s
+// 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 arm64--netbsd -static \
+// RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=S-ARM64 %s
+// RUN: %clang -no-canonical-prefixes -target arm64--netbsd7.0.0 -static \
+// RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=S-ARM64-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
+// RUN: %clang -no-canonical-prefixes -target arm--netbsd7.0.0-eabi -static \
+// RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=S-ARM-7 %s
+// RUN: %clang -no-canonical-prefixes -target arm--netbsd6.0.0-eabi -static \
+// RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=S-ARM-6 %s
+// RUN: %clang -no-canonical-prefixes -target sparc--netbsd -static \
+// RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=S-SPARC %s
+// RUN: %clang -no-canonical-prefixes -target sparc64--netbsd -static \
+// RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=S-SPARC64 %s
 
 // X86_64: clang{{.*}}" "-cc1" "-triple" "x86_64--netbsd"
 // X86_64: ld{{.*}}" "--eh-frame-hdr" "-dynamic-linker" "/libexec/ld.elf_so"
@@ -34,24 +97,184 @@
 // X86_64-6: ld{{.*}}" "--eh-frame-hdr" "-dynamic-linker" "/libexec/ld.elf_so"
 // X86_64-6: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}crti.o"
 // X86_64-6: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc"
-// X86_64-6: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
 // X86_64-6: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
 
+// AARCH64: clang{{.*}}" "-cc1" "-triple" "aarch64--netbsd"
+// AARCH64: ld{{.*}}" "--eh-frame-hdr" "-dynamic-linker" "/libexec/ld.elf_so"
+// AARCH64: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}crti.o"
+// AARCH64: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc"
+// AARCH64: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
+// AARCH64: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
+// AARCH64-7: clang{{.*}}" "-cc1" "-triple" "aarch64--netbsd7.0.0"
+// AARCH64-7: ld{{.*}}" "--eh-frame-hdr" "-dynamic-linker" "/libexec/ld.elf_so"
+// AARCH64-7: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}crti.o"
+// AARCH64-7:  "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc"
+// AARCH64-7: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
+// AARCH64-7: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
+// ARM64: clang{{.*}}" "-cc1" "-triple" "arm64--netbsd"
+// ARM64: ld{{.*}}" "--eh-frame-hdr" "-dynamic-linker" "/libexec/ld.elf_so"
+// ARM64: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}crti.o"
+// ARM64: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc"
+// ARM64: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
+// ARM64: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
+// ARM64-7: clang{{.*}}" "-cc1" "-triple" "arm64--netbsd7.0.0"
+// ARM64-7: ld{{.*}}" "--eh-frame-hdr" "-dynamic-linker" "/libexec/ld.elf_so"
+// ARM64-7: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}crti.o"
+// ARM64-7:  "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc"
+// ARM64-7: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
+// ARM64-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"
+// ARM: "-m" "armelf_nbsd_eabi"
+// ARM: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o"
+// ARM: "{{.*}}/usr/lib{{/|\\\\}}eabi{{/|\\\\}}crti.o"
+// ARM: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc"
+// ARM: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
+// ARM-APCS: clang{{.*}}" "-cc1" "-triple" "armv4--netbsd"
+// ARM-APCS: as{{.*}}" "-mcpu=strongarm" "-o"
+// ARM-APCS: ld{{.*}}" "--eh-frame-hdr" "-dynamic-linker" "/libexec/ld.elf_so"
+// ARM-APCS: "-m" "armelf_nbsd"
+// ARM-APCS: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o"
+// ARM-APCS: "{{.*}}/usr/lib{{/|\\\\}}oabi{{/|\\\\}}crti.o"
+// ARM-APCS: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc"
+// ARM-APCS: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
+// THUMB: clang{{.*}}" "-cc1" "-triple" "armv5e--netbsd-eabi"
+// THUMB: as{{.*}}" "-mcpu=arm926ej-s" "-o"
+// THUMB: ld{{.*}}" "--eh-frame-hdr" "-dynamic-linker" "/libexec/ld.elf_so"
+// THUMB: "-m" "armelf_nbsd_eabi"
+// THUMB: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o"
+// THUMB: "{{.*}}/usr/lib{{/|\\\\}}eabi{{/|\\\\}}crti.o"
+// THUMB: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc"
+// THUMB: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
+// ARM-7: clang{{.*}}" "-cc1" "-triple" "armv5e--netbsd7.0.0-eabi"
+// ARM-7: ld{{.*}}" "--eh-frame-hdr" "-dynamic-linker" "/libexec/ld.elf_so"
+// ARM-7: "-m" "armelf_nbsd_eabi"
+// ARM-7: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o"
+// ARM-7: "{{.*}}/usr/lib{{/|\\\\}}eabi{{/|\\\\}}crti.o"
+// ARM-7:  "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc"
+// ARM-7: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
+// ARM-6: clang{{.*}}" "-cc1" "-triple" "armv5e--netbsd6.0.0-eabi"
+// ARM-6: ld{{.*}}" "--eh-frame-hdr" "-dynamic-linker" "/libexec/ld.elf_so"
+// ARM-6: "-m" "armelf_nbsd_eabi"
+// ARM-6: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o"
+// ARM-6: "{{.*}}/usr/lib{{/|\\\\}}eabi{{/|\\\\}}crti.o"
+// ARM-6: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc"
+// ARM-6: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
+// ARM-HF: clang{{.*}}" "-cc1" "-triple" "armv5e--netbsd-eabihf"
+// ARM-HF: ld{{.*}}" "-m" "armelf_nbsd_eabihf"
+
+// SPARC: clang{{.*}}" "-cc1" "-triple" "sparc--netbsd"
+// SPARC: as{{.*}}" "-32" "-o"
+// SPARC: ld{{.*}}" "--eh-frame-hdr" "-dynamic-linker" "/libexec/ld.elf_so"
+// SPARC: "-m" "elf32_sparc"
+// SPARC: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o"
+// SPARC: "{{.*}}/usr/lib{{/|\\\\}}sparc{{/|\\\\}}crti.o"
+// SPARC: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc"
+// SPARC: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
+// SPARC64: clang{{.*}}" "-cc1" "-triple" "sparc64--netbsd"
+// SPARC64: as{{.*}}" "-64" "-Av9" "-o"
+// SPARC64: ld{{.*}}" "--eh-frame-hdr" "-dynamic-linker" "/libexec/ld.elf_so"
+// SPARC64: "-m" "elf64_sparc"
+// SPARC64: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}crti.o"
+// SPARC64: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc"
+// SPARC64: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
 // S-X86_64: clang{{.*}}" "-cc1" "-triple" "x86_64--netbsd"
-// S-X86_64: ld{{.*}}" "-Bstatic"
+// S-X86_64: ld{{.*}}" "--eh-frame-hdr" "-Bstatic"
 // S-X86_64: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}crti.o"
 // S-X86_64: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc"
 // S-X86_64: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
 
 // S-X86_64-7: clang{{.*}}" "-cc1" "-triple" "x86_64--netbsd7.0.0"
-// S-X86_64-7: ld{{.*}}" "-Bstatic"
+// S-X86_64-7: ld{{.*}}" "--eh-frame-hdr" "-Bstatic"
 // S-X86_64-7: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}crti.o"
 // S-X86_64-7: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc"
 // S-X86_64-7: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
 
 // S-X86_64-6: clang{{.*}}" "-cc1" "-triple" "x86_64--netbsd6.0.0"
-// S-X86_64-6: ld{{.*}}" "-Bstatic"
+// S-X86_64-6: ld{{.*}}" "--eh-frame-hdr" "-Bstatic"
 // S-X86_64-6: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}crti.o"
 // S-X86_64-6: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc"
 // S-X86_64-6: "-lgcc_eh" "-lc" "-lgcc"
 // S-X86_64-6: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
+// S-AARCH64: clang{{.*}}" "-cc1" "-triple" "aarch64--netbsd"
+// S-AARCH64: ld{{.*}}" "--eh-frame-hdr" "-Bstatic"
+// S-AARCH64: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}crti.o"
+// S-AARCH64: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc"
+// S-AARCH64: "-lgcc_eh" "-lc" "-lgcc"
+// S-AARCH64: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
+// S-AARCH64-7: clang{{.*}}" "-cc1" "-triple" "aarch64--netbsd7.0.0"
+// S-AARCH64-7: ld{{.*}}" "--eh-frame-hdr" "-Bstatic"
+// S-AARCH64-7: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}crti.o"
+// S-AARCH64-7: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc"
+// S-AARCH64-7: "-lgcc_eh" "-lc" "-lgcc"
+// S-AARCH64-7: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
+// S-ARM64: clang{{.*}}" "-cc1" "-triple" "arm64--netbsd"
+// S-ARM64: ld{{.*}}" "--eh-frame-hdr" "-Bstatic"
+// S-ARM64: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}crti.o"
+// S-ARM64: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc"
+// S-ARM64: "-lgcc_eh" "-lc" "-lgcc"
+// S-ARM64: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
+// S-ARM64-7: clang{{.*}}" "-cc1" "-triple" "arm64--netbsd7.0.0"
+// S-ARM64-7: ld{{.*}}" "--eh-frame-hdr" "-Bstatic"
+// S-ARM64-7: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}crti.o"
+// S-ARM64-7: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc"
+// S-ARM64-7: "-lgcc_eh" "-lc" "-lgcc"
+// S-ARM64-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"
+// S-ARM: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o"
+// S-ARM: "{{.*}}/usr/lib{{/|\\\\}}eabi{{/|\\\\}}crti.o"
+// S-ARM: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc"
+// S-ARM: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
+// S-ARM-7: clang{{.*}}" "-cc1" "-triple" "armv5e--netbsd7.0.0-eabi"
+// S-ARM-7: ld{{.*}}" "--eh-frame-hdr" "-Bstatic"
+// S-ARM-7: "-m" "armelf_nbsd_eabi"
+// S-ARM-7: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o"
+// S-ARM-7: "{{.*}}/usr/lib{{/|\\\\}}eabi{{/|\\\\}}crti.o"
+// S-ARM-7: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc"
+// S-ARM-7: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
+// S-ARM-6: clang{{.*}}" "-cc1" "-triple" "armv5e--netbsd6.0.0-eabi"
+// S-ARM-6: ld{{.*}}" "--eh-frame-hdr" "-Bstatic"
+// S-ARM-6: "-m" "armelf_nbsd_eabi"
+// S-ARM-6: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o"
+// S-ARM-6: "{{.*}}/usr/lib{{/|\\\\}}eabi{{/|\\\\}}crti.o"
+// S-ARM-6: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc"
+// S-ARM-6: "-lgcc_eh" "-lc" "-lgcc"
+// S-ARM-6: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
+// S-SPARC: clang{{.*}}" "-cc1" "-triple" "sparc--netbsd"
+// S-SPARC: ld{{.*}}" "--eh-frame-hdr" "-Bstatic"
+// S-SPARC: "-m" "elf32_sparc"
+// S-SPARC: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o"
+// S-SPARC: "{{.*}}/usr/lib{{/|\\\\}}sparc{{/|\\\\}}crti.o"
+// S-SPARC: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc"
+// S-SPARC: "-lgcc_eh" "-lc" "-lgcc"
+// S-SPARC: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
+// S-SPARC64: clang{{.*}}" "-cc1" "-triple" "sparc64--netbsd"
+// S-SPARC64: ld{{.*}}" "--eh-frame-hdr" "-Bstatic"
+// S-SPARC64: "-m" "elf64_sparc"
+// S-SPARC64: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}crti.o"
+// S-SPARC64: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc"
+// S-SPARC64: "-lgcc_eh" "-lc" "-lgcc"
+// S-SPARC64: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
diff --git a/test/Driver/netbsd.cpp b/test/Driver/netbsd.cpp
index 1c338d3..43b9fde 100644
--- a/test/Driver/netbsd.cpp
+++ b/test/Driver/netbsd.cpp
@@ -7,6 +7,30 @@
 // RUN: %clangxx -no-canonical-prefixes -target x86_64--netbsd6.0.0 \
 // RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
 // RUN: | FileCheck -check-prefix=X86_64-6 %s
+// RUN: %clangxx -no-canonical-prefixes -target arm--netbsd6.0.0-eabi \
+// RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=ARM %s
+// RUN: %clangxx -no-canonical-prefixes -target arm--netbsd7.0.0-eabi \
+// RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=ARM-7 %s
+// RUN: %clangxx -no-canonical-prefixes -target aarch64--netbsd \
+// RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=AARCH64 %s
+// RUN: %clangxx -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: %clangxx -no-canonical-prefixes -target arm64--netbsd \
+// RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=ARM64 %s
+// RUN: %clangxx -no-canonical-prefixes -target arm64--netbsd7.0.0 \
+// RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=ARM64-7 %s
+// RUN: %clangxx -no-canonical-prefixes -target sparc--netbsd \
+// RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=SPARC %s
+// RUN: %clangxx -no-canonical-prefixes -target sparc64--netbsd \
+// RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=SPARC64 %s
 
 // RUN: %clangxx -no-canonical-prefixes -target x86_64--netbsd -static \
 // RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
@@ -17,6 +41,30 @@
 // RUN: %clangxx -no-canonical-prefixes -target x86_64--netbsd6.0.0 -static \
 // RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
 // RUN: | FileCheck -check-prefix=S-X86_64-6 %s
+// RUN: %clangxx -no-canonical-prefixes -target arm--netbsd6.0.0-eabi -static \
+// RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=S-ARM %s
+// RUN: %clangxx -no-canonical-prefixes -target arm--netbsd7.0.0-eabi -static \
+// RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=S-ARM-7 %s
+// RUN: %clangxx -no-canonical-prefixes -target aarch64--netbsd -static \
+// RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=S-AARCH64 %s
+// RUN: %clangxx -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: %clangxx -no-canonical-prefixes -target arm64--netbsd -static \
+// RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=S-ARM64 %s
+// RUN: %clangxx -no-canonical-prefixes -target arm64--netbsd7.0.0 -static \
+// RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=S-ARM64-7 %s
+// RUN: %clangxx -no-canonical-prefixes -target sparc--netbsd -static \
+// RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=S-SPARC %s
+// RUN: %clangxx -no-canonical-prefixes -target sparc64--netbsd -static \
+// RUN: --sysroot=%S/Inputs/basic_netbsd_tree %s -### 2>&1 \
+// RUN: | FileCheck -check-prefix=S-SPARC64 %s
 
 // X86_64: clang{{.*}}" "-cc1" "-triple" "x86_64--netbsd"
 // X86_64: ld{{.*}}" "--eh-frame-hdr" "-dynamic-linker" "/libexec/ld.elf_so"
@@ -37,21 +85,133 @@
 // X86_64-6: "-lm" "-lc" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
 // X86_64-6: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
 
+// ARM: clang{{.*}}" "-cc1" "-triple" "armv5e--netbsd6.0.0-eabi"
+// ARM: ld{{.*}}" "--eh-frame-hdr" "-dynamic-linker" "/libexec/ld.elf_so"
+// ARM: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}eabi{{/|\\\\}}crti.o"
+// ARM: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lstdc++"
+// ARM: "-lm" "-lc" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
+// ARM: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
+// ARM-7: clang{{.*}}" "-cc1" "-triple" "armv5e--netbsd7.0.0-eabi"
+// ARM-7: ld{{.*}}" "--eh-frame-hdr" "-dynamic-linker" "/libexec/ld.elf_so"
+// ARM-7: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}eabi{{/|\\\\}}crti.o"
+// ARM-7: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc++" "-lm" "-lc"
+// ARM-7: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
+// AARCH64: clang{{.*}}" "-cc1" "-triple" "aarch64--netbsd"
+// AARCH64: ld{{.*}}" "--eh-frame-hdr" "-dynamic-linker" "/libexec/ld.elf_so"
+// AARCH64: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}crti.o"
+// AARCH64: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lstdc++"
+// AARCH64: "-lm" "-lc" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
+// AARCH64: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
+// AARCH64-7: clang{{.*}}" "-cc1" "-triple" "aarch64--netbsd7.0.0"
+// AARCH64-7: ld{{.*}}" "--eh-frame-hdr" "-dynamic-linker" "/libexec/ld.elf_so"
+// AARCH64-7: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}crti.o"
+// AARCH64-7: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lstdc++"
+// AARCH64-7: "-lm" "-lc" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
+// AARCH64-7: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
+// ARM64: clang{{.*}}" "-cc1" "-triple" "arm64--netbsd"
+// ARM64: ld{{.*}}" "--eh-frame-hdr" "-dynamic-linker" "/libexec/ld.elf_so"
+// ARM64: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}crti.o"
+// ARM64: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lstdc++"
+// ARM64: "-lm" "-lc" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
+// ARM64: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
+// ARM64-7: clang{{.*}}" "-cc1" "-triple" "arm64--netbsd7.0.0"
+// ARM64-7: ld{{.*}}" "--eh-frame-hdr" "-dynamic-linker" "/libexec/ld.elf_so"
+// ARM64-7: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}crti.o"
+// ARM64-7: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lstdc++"
+// ARM64-7: "-lm" "-lc" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
+// ARM64-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"
+// SPARC: "{{.*}}/usr/lib{{/|\\\\}}sparc{{/|\\\\}}crti.o"
+// SPARC: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lstdc++"
+// SPARC: "-lm" "-lc" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
+// SPARC: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
+// SPARC64: clang{{.*}}" "-cc1" "-triple" "sparc64--netbsd"
+// SPARC64: ld{{.*}}" "--eh-frame-hdr" "-dynamic-linker" "/libexec/ld.elf_so"
+// SPARC64: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}crti.o"
+// SPARC64: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lstdc++"
+// SPARC64: "-lm" "-lc" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
+// SPARC64: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
 // S-X86_64: clang{{.*}}" "-cc1" "-triple" "x86_64--netbsd"
-// S-X86_64: ld{{.*}}" "-Bstatic"
+// S-X86_64: ld{{.*}}" "--eh-frame-hdr" "-Bstatic"
 // S-X86_64: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}crti.o"
 // S-X86_64: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc++"
 // S-X86_64: "-lm" "-lc" "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
 
 // S-X86_64-7: clang{{.*}}" "-cc1" "-triple" "x86_64--netbsd7.0.0"
-// S-X86_64-7: ld{{.*}}" "-Bstatic"
+// S-X86_64-7: ld{{.*}}" "--eh-frame-hdr" "-Bstatic"
 // S-X86_64-7: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}crti.o"
 // S-X86_64-7: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc++"
 // S-X86_64-7: "-lm" "-lc" "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
 
 // S-X86_64-6: clang{{.*}}" "-cc1" "-triple" "x86_64--netbsd6.0.0"
-// S-X86_64-6: ld{{.*}}" "-Bstatic"
+// S-X86_64-6: ld{{.*}}" "--eh-frame-hdr" "-Bstatic"
 // S-X86_64-6: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}crti.o"
 // S-X86_64-6: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lstdc++"
 // S-X86_64-6: "-lm" "-lc" "-lgcc_eh" "-lc" "-lgcc"
 // S-X86_64-6: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
+// S-ARM: clang{{.*}}" "-cc1" "-triple" "armv5e--netbsd6.0.0-eabi"
+// S-ARM: ld{{.*}}" "--eh-frame-hdr" "-Bstatic"
+// S-ARM: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}eabi{{/|\\\\}}crti.o"
+// S-ARM: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lstdc++"
+// S-ARM: "-lm" "-lc" "-lgcc_eh" "-lc" "-lgcc"
+// S-ARM: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
+// S-ARM-7: clang{{.*}}" "-cc1" "-triple" "armv5e--netbsd7.0.0-eabi"
+// S-ARM-7: ld{{.*}}" "--eh-frame-hdr" "-Bstatic"
+// S-ARM-7: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}eabi{{/|\\\\}}crti.o"
+// S-ARM-7: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lc++" "-lm" "-lc"
+// S-ARM-7: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
+// S-AARCH64: clang{{.*}}" "-cc1" "-triple" "aarch64--netbsd"
+// S-AARCH64: ld{{.*}}" "--eh-frame-hdr" "-Bstatic"
+// S-AARCH64: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}crti.o"
+// S-AARCH64: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lstdc++"
+// S-AARCH64: "-lm" "-lc" "-lgcc_eh" "-lc" "-lgcc"
+// S-AARCH64: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
+// S-AARCH64-7: clang{{.*}}" "-cc1" "-triple" "aarch64--netbsd7.0.0"
+// S-AARCH64-7: ld{{.*}}" "--eh-frame-hdr" "-Bstatic"
+// S-AARCH64-7: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}crti.o"
+// S-AARCH64-7: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lstdc++"
+// S-AARCH64-7: "-lm" "-lc" "-lgcc_eh" "-lc" "-lgcc"
+// S-AARCH64-7: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
+// S-ARM64: clang{{.*}}" "-cc1" "-triple" "arm64--netbsd"
+// S-ARM64: ld{{.*}}" "--eh-frame-hdr" "-Bstatic"
+// S-ARM64: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}crti.o"
+// S-ARM64: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lstdc++"
+// S-ARM64: "-lm" "-lc" "-lgcc_eh" "-lc" "-lgcc"
+// S-ARM64: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
+// S-ARM64-7: clang{{.*}}" "-cc1" "-triple" "arm64--netbsd7.0.0"
+// S-ARM64-7: ld{{.*}}" "--eh-frame-hdr" "-Bstatic"
+// S-ARM64-7: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}crti.o"
+// S-ARM64-7: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lstdc++"
+// S-ARM64-7: "-lm" "-lc" "-lgcc_eh" "-lc" "-lgcc"
+// S-ARM64-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"
+// S-SPARC: "{{.*}}/usr/lib{{/|\\\\}}sparc{{/|\\\\}}crti.o"
+// S-SPARC: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lstdc++"
+// S-SPARC: "-lm" "-lc" "-lgcc_eh" "-lc" "-lgcc"
+// S-SPARC: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
+
+// S-SPARC64: clang{{.*}}" "-cc1" "-triple" "sparc64--netbsd"
+// S-SPARC64: ld{{.*}}" "--eh-frame-hdr" "-Bstatic"
+// S-SPARC64: "-o" "a.out" "{{.*}}/usr/lib{{/|\\\\}}crt0.o" "{{.*}}/usr/lib{{/|\\\\}}crti.o"
+// S-SPARC64: "{{.*}}/usr/lib{{/|\\\\}}crtbegin.o" "{{.*}}.o" "-lstdc++"
+// S-SPARC64: "-lm" "-lc" "-lgcc_eh" "-lc" "-lgcc"
+// S-SPARC64: "{{.*}}/usr/lib{{/|\\\\}}crtend.o" "{{.*}}/usr/lib{{/|\\\\}}crtn.o"
diff --git a/test/Driver/no-integrated-as-win.c b/test/Driver/no-integrated-as-win.c
index 1ab2480..8f590a0 100644
--- a/test/Driver/no-integrated-as-win.c
+++ b/test/Driver/no-integrated-as-win.c
@@ -1,5 +1,5 @@
 // RUN: %clang -target x86_64-pc-win32 -### -no-integrated-as %s -c 2>&1 | FileCheck %s
-// CHECK: there is no external assembler we can use on windows
+// CHECK: there is no external assembler that can be used on this platform
 
 // But there is for mingw.  The source file should only be mentioned once for
 // the compile step.
diff --git a/test/Driver/no-integrated-as.c b/test/Driver/no-integrated-as.c
new file mode 100644
index 0000000..812ab1e
--- /dev/null
+++ b/test/Driver/no-integrated-as.c
@@ -0,0 +1,19 @@
+// RUN: %clang -target i386 -### -no-integrated-as -c %s 2>&1 \
+// RUN:     | FileCheck %s -check-prefix NOIAS
+
+// NOIAS: -no-integrated-as
+
+// RUN: %clang -target i386 -### -integrated-as -c %s 2>&1 \
+// RUN:     | FileCheck %s -check-prefix IAS
+
+// IAS-NOT: -no-integrated-as
+
+// RUN: %clang -target i386 -### -c %s 2>&1 | FileCheck %s -check-prefix DEFAULT
+
+// DEFAULT-NOT: -no-integrated-as
+
+// RUN: %clang -target msp430 -### -c %s 2>&1 \
+// RUN:     | FileCheck %s -check-prefix NO-IAS-DEFAULT
+
+// NO-IAS-DEFAULT: -no-integrated-as
+
diff --git a/test/Driver/nostdincxx.cpp b/test/Driver/nostdincxx.cpp
index 1e1d85f..126828d 100644
--- a/test/Driver/nostdincxx.cpp
+++ b/test/Driver/nostdincxx.cpp
@@ -1,4 +1,6 @@
 // RUN: not %clangxx -nostdinc++ %s 2>&1 | FileCheck %s
-// XFAIL: win32
 // CHECK: file not found
 #include <vector> 
+
+// MSVC has C++ headers in same directory as C headers.
+// REQUIRES: non-ms-sdk
diff --git a/test/Driver/nozlibcompress.c b/test/Driver/nozlibcompress.c
new file mode 100644
index 0000000..4eac066
--- /dev/null
+++ b/test/Driver/nozlibcompress.c
@@ -0,0 +1,6 @@
+// RUN: %clang -c %s -Wa,--compress-debug-sections 2>&1 | FileCheck %s
+// RUN: %clang -c %s -Wa,--compress-debug-sections -Wa,--nocompress-debug-sections 2>&1 | FileCheck --check-prefix=NOWARN %s
+// REQUIRES: nozlib
+
+// CHECK: warning: cannot compress debug sections (zlib not installed)
+// NOWARN-NOT: warning: cannot compress debug sections (zlib not installed)
diff --git a/test/Driver/openbsd.c b/test/Driver/openbsd.c
index 4fd5b6a..d263f48 100644
--- a/test/Driver/openbsd.c
+++ b/test/Driver/openbsd.c
@@ -17,6 +17,10 @@
 // RUN:   | FileCheck --check-prefix=CHECK-LD-T %s
 // RUN: %clang -no-canonical-prefixes -target i686-pc-openbsd -Z %s -### 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-LD-Z %s
+// RUN: %clang -no-canonical-prefixes -target mips64-unknown-openbsd %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-MIPS64-LD %s
+// RUN: %clang -no-canonical-prefixes -target mips64el-unknown-openbsd %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-MIPS64EL-LD %s
 // CHECK-LD-R: clang{{.*}}" "-cc1" "-triple" "i686-pc-openbsd"
 // CHECK-LD-R: ld{{.*}}" "-e" "__start" "--eh-frame-hdr" "-Bdynamic" "-dynamic-linker" "{{.*}}ld.so" "-o" "a.out" "{{.*}}crt0.o" "{{.*}}crtbegin.o" "-L{{.*}}" "-r" "{{.*}}.o" "-lgcc" "-lc" "-lgcc" "{{.*}}crtend.o"
 // CHECK-LD-S: clang{{.*}}" "-cc1" "-triple" "i686-pc-openbsd"
@@ -25,3 +29,42 @@
 // CHECK-LD-T: ld{{.*}}" "-e" "__start" "--eh-frame-hdr" "-Bdynamic" "-dynamic-linker" "{{.*}}ld.so" "-o" "a.out" "{{.*}}crt0.o" "{{.*}}crtbegin.o" "-L{{.*}}" "-t" "{{.*}}.o" "-lgcc" "-lc" "-lgcc" "{{.*}}crtend.o"
 // CHECK-LD-Z: clang{{.*}}" "-cc1" "-triple" "i686-pc-openbsd"
 // CHECK-LD-Z: ld{{.*}}" "-e" "__start" "--eh-frame-hdr" "-Bdynamic" "-dynamic-linker" "{{.*}}ld.so" "-o" "a.out" "{{.*}}crt0.o" "{{.*}}crtbegin.o" "-L{{.*}}" "-Z" "{{.*}}.o" "-lgcc" "-lc" "-lgcc" "{{.*}}crtend.o"
+// CHECK-MIPS64-LD: clang{{.*}}" "-cc1" "-triple" "mips64-unknown-openbsd"
+// CHECK-MIPS64-LD: ld{{.*}}" "-EB" "-e" "__start" "--eh-frame-hdr" "-Bdynamic" "-dynamic-linker" "{{.*}}ld.so" "-o" "a.out" "{{.*}}crt0.o" "{{.*}}crtbegin.o" "-L{{.*}}" "{{.*}}.o" "-lgcc" "-lc" "-lgcc" "{{.*}}crtend.o"
+// CHECK-MIPS64EL-LD: clang{{.*}}" "-cc1" "-triple" "mips64el-unknown-openbsd"
+// CHECK-MIPS64EL-LD: ld{{.*}}" "-EL" "-e" "__start" "--eh-frame-hdr" "-Bdynamic" "-dynamic-linker" "{{.*}}ld.so" "-o" "a.out" "{{.*}}crt0.o" "{{.*}}crtbegin.o" "-L{{.*}}" "{{.*}}.o" "-lgcc" "-lc" "-lgcc" "{{.*}}crtend.o"
+
+// Check passing options to the assembler for various OpenBSD targets
+// RUN: %clang -target amd64-pc-openbsd -m32 -### -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-AMD64-M32 %s
+// RUN: %clang -target powerpc-unknown-openbsd -### -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-POWERPC %s
+// RUN: %clang -target sparc-unknown-openbsd -### -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-SPARC %s
+// RUN: %clang -target sparc64-unknown-openbsd -### -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-SPARC64 %s
+// RUN: %clang -target mips64-unknown-openbsd -### -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-MIPS64 %s
+// RUN: %clang -target mips64-unknown-openbsd -fPIC -### -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-MIPS64-PIC %s
+// RUN: %clang -target mips64el-unknown-openbsd -### -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-MIPS64EL %s
+// RUN: %clang -target mips64el-unknown-openbsd -fPIC -### -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-MIPS64EL-PIC %s
+// CHECK-AMD64-M32: as{{.*}}" "--32"
+// CHECK-POWERPC: as{{.*}}" "-mppc" "-many"
+// CHECK-SPARC: as{{.*}}" "-32"
+// CHECK-SPARC64: as{{.*}}" "-64" "-Av9a"
+// CHECK-MIPS64: as{{.*}}" "-mabi" "64" "-EB"
+// CHECK-MIPS64-PIC: as{{.*}}" "-mabi" "64" "-EB" "-KPIC"
+// CHECK-MIPS64EL: as{{.*}}" "-mabi" "64" "-EL"
+// CHECK-MIPS64EL-PIC: as{{.*}}" "-mabi" "64" "-EL" "-KPIC"
+
+// Check that the integrated assembler is enabled for PowerPC and SPARC
+// RUN: %clang -target powerpc-unknown-openbsd -### -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-IAS %s
+// RUN: %clang -target sparc-unknown-openbsd -### -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-IAS %s
+// RUN: %clang -target sparc64-unknown-openbsd -### -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-IAS %s
+// CHECK-IAS-NOT: "-no-integrated-as"
diff --git a/test/Driver/pch-deps.c b/test/Driver/pch-deps.c
new file mode 100644
index 0000000..3048636
--- /dev/null
+++ b/test/Driver/pch-deps.c
@@ -0,0 +1,10 @@
+// RUN: %clang -x c-header %s -o %t.pch -MMD -MT dependencies -MF %t.d -### 2> %t
+// RUN: FileCheck %s -input-file=%t
+// CHECK: -emit-pch
+// CHECK: -dependency-file
+// CHECK: -module-file-deps
+
+// RUN: %clang -c %s -o %t -MMD -MT dependencies -MF %t.d -### 2> %t
+// RUN: FileCheck %s -check-prefix=CHECK-NOPCH -input-file=%t
+// CHECK-NOPCH: -dependency-file
+// CHECK-NOPCH-NOT: -module-file-deps
diff --git a/test/Driver/pic.c b/test/Driver/pic.c
index 30e1005..3629cc4 100644
--- a/test/Driver/pic.c
+++ b/test/Driver/pic.c
@@ -138,7 +138,7 @@
 // RUN:   | FileCheck %s --check-prefix=CHECK-NO-PIE
 //
 // Darwin is a beautiful and unique snowflake when it comes to these flags.
-// When targetting a 32-bit darwin system, the -fno-* flag variants work and
+// When targeting a 32-bit darwin system, the -fno-* flag variants work and
 // disable PIC, but any other flag enables PIC (*not* PIE) even if the flag
 // specifies PIE. On 64-bit targets, there is simply nothing you can do, there
 // is no PIE, there is only PIC when it comes to compilation.
@@ -201,7 +201,17 @@
 // RUN:   | FileCheck %s --check-prefix=CHECK-NO-PIC
 //
 // On OpenBSD, PIE is enabled by default, but can be disabled.
+// RUN: %clang -c %s -target amd64-pc-openbsd -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-PIE1
 // RUN: %clang -c %s -target i386-pc-openbsd -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-PIE1
+// RUN: %clang -c %s -target mips64-unknown-openbsd -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-PIE1
+// RUN: %clang -c %s -target mips64el-unknown-openbsd -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-PIE1
+// RUN: %clang -c %s -target powerpc-unknown-openbsd -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-PIE2
+// RUN: %clang -c %s -target sparc64-unknown-openbsd -### 2>&1 \
 // RUN:   | FileCheck %s --check-prefix=CHECK-PIE2
 // RUN: %clang -c %s -target i386-pc-openbsd -fno-pie -### 2>&1 \
 // RUN:   | FileCheck %s --check-prefix=CHECK-NO-PIC
@@ -209,3 +219,15 @@
 // On OpenBSD, -nopie needs to be passed through to the linker.
 // RUN: %clang %s -target i386-pc-openbsd -nopie -### 2>&1 \
 // RUN:   | FileCheck %s --check-prefix=CHECK-NOPIE-LD
+//
+// On Android PIC is enabled by default
+// RUN: %clang -c %s -target i686-linux-android -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-PIC2
+// RUN: %clang -c %s -target arm-linux-androideabi -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-PIC1
+// RUN: %clang -c %s -target mipsel-linux-android -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-PIC1
+// RUN: %clang -c %s -target aarch64-linux-android -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-PIC1
+// RUN: %clang -c %s -target arm64-linux-android -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-PIC1
diff --git a/test/Driver/ppc-features.cpp b/test/Driver/ppc-features.cpp
index 6959c62..fa9a7ec 100644
--- a/test/Driver/ppc-features.cpp
+++ b/test/Driver/ppc-features.cpp
@@ -59,9 +59,12 @@
 // RUN: %clang -target powerpc64-unknown-linux-gnu %s -fno-altivec -mcpu=pwr7 -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-14 %s
 // CHECK-14: "-target-feature" "-altivec"
 
-// RUN: %clang -target powerpc64-unknown-linux-gnu %s -fno-altivec -mcpu=ppc64 -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-15 %s
+// RUN: %clang -target powerpc64-unknown-linux-gnu %s -fno-altivec -mcpu=pwr8 -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-15 %s
 // CHECK-15: "-target-feature" "-altivec"
 
+// RUN: %clang -target powerpc64-unknown-linux-gnu %s -fno-altivec -mcpu=ppc64 -### -o %t.o 2>&1 | FileCheck --check-prefix=CHECK-16 %s
+// CHECK-16: "-target-feature" "-altivec"
+
 // RUN: %clang -target powerpc64-unknown-linux-gnu %s -mno-qpx -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK-NOQPX %s
 // CHECK-NOQPX: "-target-feature" "-qpx"
 
@@ -92,3 +95,27 @@
 // RUN: %clang -target powerpc64-unknown-linux-gnu %s -mno-vsx -mvsx -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK-VSX %s
 // CHECK-VSX: "-target-feature" "+vsx"
 
+// RUN: %clang -target powerpc64-unknown-linux-gnu %s -mno-crbits -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK-NOCRBITS %s
+// CHECK-NOCRBITS: "-target-feature" "-crbits"
+
+// RUN: %clang -target powerpc64-unknown-linux-gnu %s -mno-crbits -mcrbits -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK-CRBITS %s
+// CHECK-CRBITS: "-target-feature" "+crbits"
+
+// Assembler features
+// RUN: %clang -target powerpc64-unknown-linux-gnu %s -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK_BE_AS_ARGS %s
+// CHECK_BE_AS_ARGS: "-mppc64"
+// CHECK_BE_AS_ARGS: "-many"
+
+// RUN: %clang -target powerpc64le-unknown-linux-gnu %s -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK_LE_AS_ARGS %s
+// CHECK_LE_AS_ARGS: "-mppc64"
+// CHECK_LE_AS_ARGS: "-many"
+// CHECK_LE_AS_ARGS: "-mlittle-endian"
+
+// linker features
+// RUN: %clang -target powerpc64-unknown-linux-gnu %s -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK_BE_LD_ARGS %s
+// CHECK_BE_LD_ARGS: "elf64ppc"
+
+// RUN: %clang -target powerpc64le-unknown-linux-gnu %s -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK_LE_LD_ARGS %s
+// CHECK_LE_LD_ARGS: "elf64lppc"
+
+
diff --git a/test/Driver/preprocess-multiple.c b/test/Driver/preprocess-multiple.c
new file mode 100644
index 0000000..9f87d3d
--- /dev/null
+++ b/test/Driver/preprocess-multiple.c
@@ -0,0 +1,6 @@
+// RUN: %clang -E %s %s | FileCheck %s
+// Test that the driver can preprocess multiple files.
+
+X
+// CHECK: X
+// CHECK: X
diff --git a/test/Driver/qa_override.c b/test/Driver/qa_override.c
index e5d9c95..d2754c8 100644
--- a/test/Driver/qa_override.c
+++ b/test/Driver/qa_override.c
@@ -1,12 +1,12 @@
-// RUN: env QA_OVERRIDE_GCC3_OPTIONS="#+-Os +-Oz +-O +-O3 +-Oignore +a +b +c xb Xa Omagic ^-###  " %clang -target x86_64-apple-darwin %s -O2 b -O3 2>&1 | FileCheck %s
-// RUN: env QA_OVERRIDE_GCC3_OPTIONS="x-Werror +-msse" %clang -target x86_64-apple-darwin -Werror %s -c -### 2>&1 | FileCheck %s -check-prefix=RM-WERROR
+// RUN: env CCC_OVERRIDE_OPTIONS="#+-Os +-Oz +-O +-O3 +-Oignore +a +b +c xb Xa Omagic ^-###  " %clang -target x86_64-apple-darwin %s -O2 b -O3 2>&1 | FileCheck %s
+// RUN: env CCC_OVERRIDE_OPTIONS="x-Werror +-msse" %clang -target x86_64-apple-darwin -Werror %s -c -### 2>&1 | FileCheck %s -check-prefix=RM-WERROR
 
 // CHECK: "-cc1"
 // CHECK-NOT: "-Oignore"
 // CHECK: "-Omagic"
 // CHECK-NOT: "-Oignore"
 
-// RM-WERROR: ### QA_OVERRIDE_GCC3_OPTIONS: x-Werror +-msse
+// RM-WERROR: ### CCC_OVERRIDE_OPTIONS: x-Werror +-msse
 // RM-WERROR-NEXT: ### Deleting argument -Werror
 // RM-WERROR-NEXT: ### Adding argument -msse at end
 // RM-WERROR-NOT: "-Werror"
diff --git a/test/Driver/r600-mcpu.cl b/test/Driver/r600-mcpu.cl
index 7238ff4..47c0185 100644
--- a/test/Driver/r600-mcpu.cl
+++ b/test/Driver/r600-mcpu.cl
@@ -34,6 +34,7 @@
 // RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=kabini %s -o - 2>&1 | FileCheck --check-prefix=KABINI-CHECK %s
 // RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=kaveri %s -o - 2>&1 | FileCheck --check-prefix=KAVERI-CHECK %s
 // RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=hawaii %s -o - 2>&1 | FileCheck --check-prefix=HAWAII-CHECK %s
+// RUN: %clang -### -target r600 -x cl -S -emit-llvm -mcpu=mullins %s -o - 2>&1 | FileCheck --check-prefix=MULLINS-CHECK %s
 
 // R600-CHECK:  "-target-cpu" "r600"
 // RS880-CHECK: "-target-cpu" "rs880"
@@ -58,3 +59,4 @@
 // KABINI-CHECK: "-target-cpu" "kabini"
 // KAVERI-CHECK: "-target-cpu" "kaveri"
 // HAWAII-CHECK: "-target-cpu" "hawaii"
+// MULLINS-CHECK: "-target-cpu" "mullins"
diff --git a/test/Driver/sanitize_unwind_tables.c b/test/Driver/sanitize_unwind_tables.c
new file mode 100644
index 0000000..8b78899
--- /dev/null
+++ b/test/Driver/sanitize_unwind_tables.c
@@ -0,0 +1,11 @@
+// Sanitizers need to unwind stack at any code location.
+// Test that unwind tables are enabled in supported configurations.
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=address %s -### 2>&1 |  FileCheck %s
+// RUN: %clang -target i686-linux-gnu -fsanitize=address %s -### 2>&1 |  FileCheck %s
+// RUN: %clang -target arm-linux-androideabi -fsanitize=address %s -### 2>&1 |  FileCheck %s
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=memory %s -### 2>&1 |  FileCheck %s
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=thread %s -### 2>&1 |  FileCheck %s
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=dataflow %s -### 2>&1 |  FileCheck %s
+
+// CHECK: -munwind-tables
diff --git a/test/Driver/sanitizer-ld.c b/test/Driver/sanitizer-ld.c
index 691b44b..786262c 100644
--- a/test/Driver/sanitizer-ld.c
+++ b/test/Driver/sanitizer-ld.c
@@ -15,6 +15,65 @@
 // CHECK-ASAN-LINUX-NOT: "-export-dynamic"
 // CHECK-ASAN-LINUX: "--dynamic-list={{.*}}libclang_rt.asan-i386.a.syms"
 
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     -target i386-unknown-linux -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
+//
+// CHECK-SHARED-ASAN-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-SHARED-ASAN-LINUX-NOT: "-lc"
+// CHECK-SHARED-ASAN-LINUX-NOT: libclang_rt.asan-i386.a"
+// CHECK-SHARED-ASAN-LINUX: "-whole-archive" "{{.*}}libclang_rt.asan-preinit-i386.a" "-no-whole-archive"
+// CHECK-SHARED-ASAN-LINUX: libclang_rt.asan-i386.so"
+// CHECK-SHARED-ASAN-LINUX-NOT: "-lpthread"
+// CHECK-SHARED-ASAN-LINUX-NOT: "-lrt"
+// CHECK-SHARED-ASAN-LINUX-NOT: "-ldl"
+// CHECK-SHARED-ASAN-LINUX-NOT: "-export-dynamic"
+// 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:     -resource-dir=%S/Inputs/resource_dir \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-DSO-SHARED-ASAN-LINUX %s
+//
+// CHECK-DSO-SHARED-ASAN-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-DSO-SHARED-ASAN-LINUX-NOT: "-lc"
+// CHECK-DSO-SHARED-ASAN-LINUX-NOT: libclang_rt.asan-i386.a"
+// CHECK-DSO-SHARED-ASAN-LINUX-NOT: "libclang_rt.asan-preinit-i386.a"
+// CHECK-DSO-SHARED-ASAN-LINUX: libclang_rt.asan-i386.so"
+// CHECK-DSO-SHARED-ASAN-LINUX-NOT: "-lpthread"
+// CHECK-DSO-SHARED-ASAN-LINUX-NOT: "-lrt"
+// CHECK-DSO-SHARED-ASAN-LINUX-NOT: "-ldl"
+// CHECK-DSO-SHARED-ASAN-LINUX-NOT: "-export-dynamic"
+// 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:     -resource-dir=%S/Inputs/resource_dir \
+// RUN:     --sysroot=%S/Inputs/basic_freebsd_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-ASAN-FREEBSD %s
+//
+// CHECK-ASAN-FREEBSD: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-ASAN-FREEBSD-NOT: "-lc"
+// CHECK-ASAN-FREEBSD-NOT: libclang_rt.asan_cxx
+// CHECK-ASAN-FREEBSD: freebsd{{/|\\+}}libclang_rt.asan-i386.a"
+// CHECK-ASAN-FREEBSD-NOT: libclang_rt.asan_cxx
+// CHECK-ASAN-FREEBSD: "-lpthread"
+// CHECK-ASAN-FREEBSD: "-lrt"
+// CHECK-ASAN-FREEBSD: "-export-dynamic"
+// CHECK-ASAN-FREEBSD-NOT: "--dynamic-list"
+
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     -target i386-unknown-freebsd -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
+//
+// CHECK-ASAN-FREEBSD-LDL: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-ASAN-FREEBSD-LDL-NOT: "-ldl"
+
 // RUN: %clangxx -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     -target i386-unknown-linux -fsanitize=address \
 // RUN:     -resource-dir=%S/Inputs/empty_resource_dir \
@@ -23,6 +82,7 @@
 //
 // CHECK-ASAN-LINUX-CXX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
 // CHECK-ASAN-LINUX-CXX-NOT: "-lc"
+// CHECK-ASAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.asan_cxx-i386.a" "-no-whole-archive"
 // CHECK-ASAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.asan-i386.a" "-no-whole-archive"
 // CHECK-ASAN-LINUX-CXX: "-lpthread"
 // CHECK-ASAN-LINUX-CXX: "-lrt"
@@ -42,6 +102,24 @@
 // 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:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:   | FileCheck --check-prefix=CHECK-ASAN-ARM %s
+//
+// CHECK-ASAN-ARM: "{{(.*[^.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-ASAN-ARM-NOT: "-lc"
+// 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:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:   | FileCheck --check-prefix=CHECK-ASAN-ARMv7 %s
+//
+// CHECK-ASAN-ARMv7: "{{(.*[^.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-ASAN-ARMv7-NOT: "-lc"
+// 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:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
 // RUN:   | FileCheck --check-prefix=CHECK-ASAN-ANDROID %s
@@ -50,6 +128,16 @@
 // CHECK-ASAN-ANDROID-NOT: "-lc"
 // CHECK-ASAN-ANDROID: libclang_rt.asan-arm-android.so"
 // CHECK-ASAN-ANDROID-NOT: "-lpthread"
+// CHECK-ASAN-ANDROID: "-pie"
+// CHECK-ASAN-ANDROID-NOT: "-lpthread"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     -target arm-linux-androideabi -fsanitize=address \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:     -shared-libasan \
+// RUN:   | FileCheck --check-prefix=CHECK-ASAN-ANDROID-SHARED-LIBASAN %s
+//
+// CHECK-ASAN-ANDROID-SHARED-LIBASAN-NOT: argument unused during compilation: '-shared-libasan'
 //
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     -target arm-linux-androideabi -fsanitize=address \
@@ -109,6 +197,7 @@
 
 // RUN: %clangxx -fsanitize=undefined %s -### -o %t.o 2>&1 \
 // RUN:     -target i386-unknown-linux \
+// RUN:     -resource-dir=%S/Inputs/resource_dir \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-UBSAN-LINUX-CXX %s
 // CHECK-UBSAN-LINUX-CXX: "{{.*}}ld{{(.exe)?}}"
@@ -116,8 +205,10 @@
 // CHECK-UBSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.san-i386.a" "-no-whole-archive"
 // CHECK-UBSAN-LINUX-CXX-NOT: libclang_rt.asan
 // CHECK-UBSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.ubsan-i386.a" "-no-whole-archive"
+// CHECK-UBSAN-LINUX-CXX: "--dynamic-list={{.*}}libclang_rt.ubsan-i386.a.syms"
 // CHECK-UBSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.ubsan_cxx-i386.a" "-no-whole-archive"
 // CHECK-UBSAN-LINUX-CXX: "-lpthread"
+// CHECK-UBSAN-LINUX-CXX: "--dynamic-list={{.*}}libclang_rt.ubsan_cxx-i386.a.syms"
 // CHECK-UBSAN-LINUX-CXX: "-lstdc++"
 
 // RUN: %clang -fsanitize=address,undefined %s -### -o %t.o 2>&1 \
@@ -148,11 +239,16 @@
 
 // RUN: %clang -fsanitize=undefined %s -### -o %t.o 2>&1 \
 // RUN:     -target i386-unknown-linux \
+// RUN:     -resource-dir=%S/Inputs/resource_dir \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:     -shared \
 // RUN:   | FileCheck --check-prefix=CHECK-UBSAN-LINUX-SHARED %s
 // CHECK-UBSAN-LINUX-SHARED: "{{.*}}ld{{(.exe)?}}"
-// CHECK-UBSAN-LINUX-SHARED: libclang_rt.ubsan-i386.a"
+// CHECK-UBSAN-LINUX-SHARED-NOT: --export-dynamic
+// CHECK-UBSAN-LINUX-SHARED-NOT: --dynamic-list
+// CHECK-UBSAN-LINUX-SHARED-NOT: libclang_rt.ubsan-i386.a"
+// CHECK-UBSAN-LINUX-SHARED-NOT: --export-dynamic
+// CHECK-UBSAN-LINUX-SHARED-NOT: --dynamic-list
 
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     -target x86_64-unknown-linux -fsanitize=leak \
diff --git a/test/Driver/sparc-float.c b/test/Driver/sparc-float.c
new file mode 100644
index 0000000..15050d2
--- /dev/null
+++ b/test/Driver/sparc-float.c
@@ -0,0 +1,38 @@
+// Check handling -mhard-float / -msoft-float options
+// when build for SPARC platforms.
+//
+// Default sparc
+// RUN: %clang -c %s -### -o %t.o 2>&1 \
+// RUN:     -target sparc-linux-gnu \
+// RUN:   | FileCheck --check-prefix=CHECK-DEF %s
+// CHECK-DEF: "-msoft-float"
+//
+// -mhard-float
+// RUN: %clang -c %s -### -o %t.o 2>&1 \
+// RUN:     -target sparc-linux-gnu -mhard-float \
+// RUN:   | FileCheck --check-prefix=CHECK-HARD %s
+// CHECK-HARD: "-mhard-float"
+//
+// -msoft-float
+// RUN: %clang -c %s -### -o %t.o 2>&1 \
+// RUN:     -target sparc-linux-gnu -msoft-float \
+// RUN:   | FileCheck --check-prefix=CHECK-SOFT %s
+// CHECK-SOFT: "-msoft-float"
+//
+// Default sparc64
+// RUN: %clang -c %s -### -o %t.o 2>&1 \
+// RUN:     -target sparc64-linux-gnu \
+// RUN:   | FileCheck --check-prefix=CHECK-DEF-SPARC64 %s
+// CHECK-DEF-SPARC64: "-msoft-float"
+//
+// -mhard-float
+// RUN: %clang -c %s -### -o %t.o 2>&1 \
+// RUN:     -target sparc64-linux-gnu -mhard-float \
+// RUN:   | FileCheck --check-prefix=CHECK-HARD-SPARC64 %s
+// CHECK-HARD-SPARC64: "-mhard-float"
+//
+// -msoft-float
+// RUN: %clang -c %s -### -o %t.o 2>&1 \
+// RUN:     -target sparc64-linux-gnu -msoft-float \
+// RUN:   | FileCheck --check-prefix=CHECK-SOFT-SPARC64 %s
+// CHECK-SOFT-SPARC64: "-msoft-float"
diff --git a/test/Driver/stack-protector.c b/test/Driver/stack-protector.c
index 2eb0f53..7fecd1b 100644
--- a/test/Driver/stack-protector.c
+++ b/test/Driver/stack-protector.c
@@ -1,17 +1,25 @@
 // RUN: %clang -fno-stack-protector -### %s 2>&1 | FileCheck %s -check-prefix=NOSSP
-// NOSSP-NOT: "-stack-protector" "1"
+// NOSSP-NOT: "-stack-protector"
 // NOSSP-NOT: "-stack-protector-buffer-size" 
 
-// RUN: %clang -fstack-protector -### %s 2>&1 | FileCheck %s -check-prefix=SSP
+// RUN: %clang -target i386-unknown-linux -fstack-protector -### %s 2>&1 | FileCheck %s -check-prefix=SSP
 // SSP: "-stack-protector" "1"
 // SSP-NOT: "-stack-protector-buffer-size" 
 
-// RUN: %clang -fstack-protector --param ssp-buffer-size=16 -### %s 2>&1 | FileCheck %s -check-prefix=SSP-BUF
+// RUN: %clang -target i386-unknown-linux -fstack-protector --param ssp-buffer-size=16 -### %s 2>&1 | FileCheck %s -check-prefix=SSP-BUF
 // SSP-BUF: "-stack-protector" "1"
 // SSP-BUF: "-stack-protector-buffer-size" "16" 
 
 // RUN: %clang -target i386-pc-openbsd -### %s 2>&1 | FileCheck %s -check-prefix=OPENBSD
-// OPENBSD: "-stack-protector" "1"
+// OPENBSD: "-stack-protector" "2"
 
-// RUN: %clang -target i386-pc-openbsd -fno-stack-protector -### %s 2>&1 | FileCheck %s -check-prefix=OPENBSD_OFF
-// OPENBSD_OFF-NOT: "-stack-protector"
+// RUN: %clang -target i386-pc-openbsd -fstack-protector -### %s 2>&1 | FileCheck %s -check-prefix=OPENBSD_SPS
+// OPENBSD_SPS: "-stack-protector" "2"
+
+// RUN: %clang -fstack-protector-strong -### %s 2>&1 | FileCheck %s -check-prefix=SSP-STRONG
+// SSP-STRONG: "-stack-protector" "2"
+// SSP-STRONG-NOT: "-stack-protector-buffer-size" 
+
+// RUN: %clang -fstack-protector-all -### %s 2>&1 | FileCheck %s -check-prefix=SSP-ALL
+// SSP-ALL: "-stack-protector" "3"
+// SSP-ALL-NOT: "-stack-protector-buffer-size" 
diff --git a/test/Driver/std.cpp b/test/Driver/std.cpp
index e98fd2c..aceda01 100644
--- a/test/Driver/std.cpp
+++ b/test/Driver/std.cpp
@@ -7,6 +7,8 @@
 // RUN: not %clang -std=gnu++11 %s -fsyntax-only 2>&1 | FileCheck -check-prefix=GNUXX11 %s
 // RUN: not %clang -std=c++1y %s -fsyntax-only 2>&1 | FileCheck -check-prefix=CXX1Y %s
 // RUN: not %clang -std=gnu++1y %s -fsyntax-only 2>&1 | FileCheck -check-prefix=GNUXX1Y %s
+// RUN: not %clang -std=c++1z %s -fsyntax-only 2>&1 | FileCheck -check-prefix=CXX1Z %s
+// RUN: not %clang -std=gnu++1z %s -fsyntax-only 2>&1 | FileCheck -check-prefix=GNUXX1Z %s
 
 void f(int n) {
   typeof(n)();
@@ -30,3 +32,9 @@
 
 // GNUXX1Y-NOT: undeclared identifier 'typeof'
 // GNUXX1Y-NOT: undeclared identifier 'decltype'
+
+// CXX1Z: undeclared identifier 'typeof'
+// CXX1Z-NOT: undeclared identifier 'decltype'
+
+// GNUXX1Z-NOT: undeclared identifier 'typeof'
+// GNUXX1Z-NOT: undeclared identifier 'decltype'
diff --git a/test/Driver/target-triple-deployment.c b/test/Driver/target-triple-deployment.c
index 8e4824a..4f5de59 100644
--- a/test/Driver/target-triple-deployment.c
+++ b/test/Driver/target-triple-deployment.c
@@ -7,6 +7,8 @@
 // RUN: %clang -target armv7-apple-ios0.0 -### %t.o 2>> %t.log
 // RUN: %clang -target armv7-apple-ios1.2.3 -### %t.o 2>> %t.log
 // RUN: %clang -target armv7-apple-ios5.0 -### %t.o 2>> %t.log
+// RUN: %clang -target armv7-apple-ios7.0 -### %t.o 2>> %t.log
+// RUN: %clang -target arm64-apple-ios -### %t.o 2>> %t.log
 //
 // RUN: FileCheck %s < %t.log
 
@@ -21,13 +23,19 @@
 // CHECK: 10.7.0
 // CHECK: {{ld(.exe)?"}}
 // CHECK: -iphoneos_version_min
-// CHECK: 3.0.0
+// CHECK: 5.0.0
 // CHECK: {{ld(.exe)?"}}
 // CHECK: -iphoneos_version_min
-// CHECK: 3.0.0
+// CHECK: 5.0.0
 // CHECK: {{ld(.exe)?"}}
 // CHECK: -iphoneos_version_min
 // CHECK: 1.2.3
 // CHECK: {{ld(.exe)?"}}
 // CHECK: -iphoneos_version_min
 // CHECK: 5.0.0
+// CHECK: {{ld(.exe)?"}}
+// CHECK: -iphoneos_version_min
+// CHECK: 7.0.0
+// CHECK: {{ld(.exe)?"}}
+// CHECK: -iphoneos_version_min
+// CHECK: 7.0.0
diff --git a/test/Driver/target.c b/test/Driver/target.c
index b400f99..a46ba16 100644
--- a/test/Driver/target.c
+++ b/test/Driver/target.c
@@ -4,12 +4,6 @@
 // Ensure we get a crazy triple here as we asked for one.
 // CHECK: Target: unknown-unknown-unknown
 //
-// Also, ensure we don't blindly hand our target selection logic down to GCC.
-// CHECK: "{{.*gcc(\.[Ee][Xx][Ee])?}}"
-// CHECK-NOT: "-target"
-// CHECK-NOT: "unknown-unknown-unknown"
-// CHECK: "-x" "assembler"
-//
 // Also check that the legacy spelling works.
 // RUN: %clang -no-canonical-prefixes -target unknown-unknown-unknown -c %s \
 // RUN:   -o %t.o -### 2>&1 | FileCheck %s
diff --git a/test/Driver/unknown-gcc-arch.c b/test/Driver/unknown-gcc-arch.c
index dcd17d4..6317e13 100644
--- a/test/Driver/unknown-gcc-arch.c
+++ b/test/Driver/unknown-gcc-arch.c
@@ -1,32 +1,40 @@
-// RUN: %clang -target x86_64-unknown-unknown -c -x assembler %s -### 2>&1 \
-// RUN:   | FileCheck -check-prefix=X86_64 %s
-// X86_64: {{.*gcc.*-m64}}
+// RUN: %clang -target x86_64-unknown-unknown -no-integrated-as -c \
+// RUN: -x assembler %s -### 2>&1 | FileCheck -check-prefix=X86_64 %s
+// X86_64: {{.*as.*--64}}
 
-// RUN: %clang -target x86_64-unknown-unknown -c -x assembler %s -### -m32 2>&1 \
-// RUN:   | FileCheck -check-prefix=X86_64-M32 %s
-// X86_64-M32: {{.*gcc.*-m32}}
+// RUN: %clang -target x86_64-unknown-unknown -c -x assembler %s -### -m32 \
+// RUN: -no-integrated-as 2>&1 | FileCheck -check-prefix=X86_64-M32 %s
+// X86_64-M32: {{.*as.*--32}}
 
-// RUN: %clang -target i386-unknown-unknown -c -x assembler %s -### 2>&1 \
-// RUN:   | FileCheck -check-prefix=I386 %s
-// I386: {{.*gcc.*-m32}}
+// RUN: %clang -target i386-unknown-unknown -c -x assembler %s -### \
+// RUN: -no-integrated-as 2>&1| FileCheck -check-prefix=I386 %s
+// I386: {{.*as.*--32}}
 
-// RUN: %clang -target i386-unknown-unknown -c -x assembler %s -### -m64 2>&1 \
-// RUN:   | FileCheck -check-prefix=I386-M64 %s
-// I386-M64: {{.*gcc.*-m64}}
+// RUN: %clang -target i386-unknown-unknown -c -x assembler %s -### -m64 \
+// RUN: -no-integrated-as 2>&1 | FileCheck -check-prefix=I386-M64 %s
+// I386-M64: {{.*as.*--64}}
 
 
 // RUN: %clang -target powerpc64-unknown-unknown -c -x assembler %s -### 2>&1 \
 // RUN:   | FileCheck -check-prefix=PPC64 %s
-// PPC64: {{.*gcc.*-m64}}
+// PPC64: {{.*as.*-a64}}
 
 // RUN: %clang -target powerpc64-unknown-unknown -c -x assembler %s -### -m32 2>&1 \
 // RUN:   | FileCheck -check-prefix=PPC64-M32 %s
-// PPC64-M32: {{.*gcc.*-m32}}
+// PPC64-M32: {{.*as.*-a32}}
 
 // RUN: %clang -target powerpc-unknown-unknown -c -x assembler %s -### 2>&1 \
 // RUN:   | FileCheck -check-prefix=PPC %s
-// PPC: {{.*gcc.*-m32}}
+// PPC: {{.*as.*-a32}}
 
 // RUN: %clang -target powerpc-unknown-unknown -c -x assembler %s -### -m64 2>&1 \
 // RUN:   | FileCheck -check-prefix=PPC-M64 %s
-// PPC-M64: {{.*gcc.*-m64}}
+// PPC-M64: {{.*as.*-a64}}
+
+// RUN: %clang -target sparc64-unknown-unknown -no-integrated-as -c -x assembler %s -### -m32 2>&1 \
+// RUN:   | FileCheck -check-prefix=SPARCV8 %s
+// SPARCV8: {{.*as.*-32}}
+
+// RUN: %clang -target sparc-unknown-unknown -no-integrated-as -c -x assembler %s -### -m64 2>&1 \
+// RUN:   | FileCheck -check-prefix=SPARCV9 %s
+// SPARCV9: {{.*as.*-64}}
diff --git a/test/Driver/verify_pch.m b/test/Driver/verify_pch.m
new file mode 100644
index 0000000..c6eca42
--- /dev/null
+++ b/test/Driver/verify_pch.m
@@ -0,0 +1,12 @@
+// RUN: touch %t.pch
+// RUN: %clang -### -verify-pch %t.pch 2> %t.log.1
+// RUN: FileCheck %s < %t.log.1
+// CHECK: -verify-pch
+
+// Also ensure that the language setting is not affected by the .pch extension
+// CHECK-NOT: "-x" "precompiled-header"
+
+// RUN: %clang -### -verify-pch -x objective-c %t.pch 2> %t.log.2
+// RUN: FileCheck -check-prefix=CHECK2 %s < %t.log.2
+// CHECK2: "-x" "objective-c"
+// CHECK2-NOT: "-x" "precompiled-header"
diff --git a/test/Driver/vfsoverlay.c b/test/Driver/vfsoverlay.c
new file mode 100644
index 0000000..6ae4945
--- /dev/null
+++ b/test/Driver/vfsoverlay.c
@@ -0,0 +1,5 @@
+// RUN: %clang -ivfsoverlay foo.h -### %s 2>&1 | FileCheck %s
+// CHECK: "-ivfsoverlay" "foo.h"
+
+// RUN: not %clang -ivfsoverlay foo.h %s 2>&1 | FileCheck -check-prefix=CHECK-MISSING %s
+// CHECK-MISSING: virtual filesystem overlay file 'foo.h' not found
diff --git a/test/Driver/via-file-asm.c b/test/Driver/via-file-asm.c
new file mode 100644
index 0000000..3fa5b54
--- /dev/null
+++ b/test/Driver/via-file-asm.c
@@ -0,0 +1,10 @@
+// Should save and read back the assembly from a file
+// RUN: %clang -target arm-none-linux-gnueabi -integrated-as -via-file-asm %s -### 2>&1 | FileCheck %s
+// CHECK: "-cc1"
+// CHECK: "-o" "[[TMP:[^"]*]]"
+// CHECK: -cc1as
+// CHECK: [[TMP]]
+
+// Should not force using the integrated assembler
+// RUN: %clang -target arm-none-linux-gnueabi -no-integrated-as -via-file-asm %s -### 2>&1 | FileCheck --check-prefix=NO_IAS %s
+// NO_IAS-NOT: "-cc1as"
diff --git a/test/Driver/visibility.cpp b/test/Driver/visibility.cpp
index cdbef97..5b137c8 100644
--- a/test/Driver/visibility.cpp
+++ b/test/Driver/visibility.cpp
@@ -1,26 +1,26 @@
 // RUN: %clang -### -S -fvisibility=hidden -fvisibility=default %s 2> %t.log
 // RUN: FileCheck -check-prefix=CHECK-1 %s < %t.log
-// CHECK-NOT: "-ftype-visibility"
+// CHECK-1-NOT: "-ftype-visibility"
 // CHECK-1: "-fvisibility" "default"
-// CHECK-NOT: "-ftype-visibility"
+// CHECK-1-NOT: "-ftype-visibility"
 
 // RUN: %clang -### -S -fvisibility=default -fvisibility=hidden %s 2> %t.log
 // RUN: FileCheck -check-prefix=CHECK-2 %s < %t.log
-// CHECK-NOT: "-ftype-visibility"
+// CHECK-2-NOT: "-ftype-visibility"
 // CHECK-2: "-fvisibility" "hidden"
-// CHECK-NOT: "-ftype-visibility"
+// CHECK-2-NOT: "-ftype-visibility"
 
 // RUN: %clang -### -S -fvisibility-ms-compat -fvisibility=hidden %s 2> %t.log
 // RUN: FileCheck -check-prefix=CHECK-3 %s < %t.log
-// CHECK-NOT: "-ftype-visibility"
+// CHECK-3-NOT: "-ftype-visibility"
 // CHECK-3: "-fvisibility" "hidden"
-// CHECK-NOT: "-ftype-visibility"
+// CHECK-3-NOT: "-ftype-visibility"
 
 // RUN: %clang -### -S -fvisibility-ms-compat -fvisibility=default %s 2> %t.log
 // RUN: FileCheck -check-prefix=CHECK-4 %s < %t.log
-// CHECK-NOT: "-ftype-visibility"
+// CHECK-4-NOT: "-ftype-visibility"
 // CHECK-4: "-fvisibility" "default"
-// CHECK-NOT: "-ftype-visibility"
+// CHECK-4-NOT: "-ftype-visibility"
 
 // RUN: %clang -### -S -fvisibility=hidden -fvisibility-ms-compat %s 2> %t.log
 // RUN: FileCheck -check-prefix=CHECK-5 %s < %t.log
diff --git a/test/Driver/windows-arm-minimal-arch.c b/test/Driver/windows-arm-minimal-arch.c
new file mode 100644
index 0000000..cf55b8f
--- /dev/null
+++ b/test/Driver/windows-arm-minimal-arch.c
@@ -0,0 +1,5 @@
+// RUN: not %clang -target thumbv5-windows -mcpu=arm10tdmi %s -o /dev/null 2>&1 \
+// RUN:   | FileCheck %s
+
+// CHECK: error: the target architecture 'thumbv5' is not supported by the target 'thumbv5--windows-msvc'
+
diff --git a/test/Driver/windows-wildcard-expansion.c b/test/Driver/windows-wildcard-expansion.c
new file mode 100644
index 0000000..3977dc3
--- /dev/null
+++ b/test/Driver/windows-wildcard-expansion.c
@@ -0,0 +1,7 @@
+// Clang does wildcard expansion on Windows. On other OSs, it's done by the shell.
+// REQUIRES: system-windows
+
+// RUN: %clang -c -### %S/Inputs/wildcard*.c 2>&1 | FileCheck %s
+// RUN: %clang -c -### %S/Inputs/wildcard?.c 2>&1 | FileCheck %s
+// CHECK: wildcard1.c
+// CHECK: wildcard2.c
diff --git a/test/Driver/woa-restrict-it.c b/test/Driver/woa-restrict-it.c
new file mode 100644
index 0000000..c046991
--- /dev/null
+++ b/test/Driver/woa-restrict-it.c
@@ -0,0 +1,4 @@
+// RUN: %clang -target armv7-windows -### %s 2>&1 | FileCheck %s
+
+// CHECK: "-backend-option" "-arm-restrict-it"
+
diff --git a/test/Driver/x86_m16.c b/test/Driver/x86_m16.c
new file mode 100644
index 0000000..be15ff5
--- /dev/null
+++ b/test/Driver/x86_m16.c
@@ -0,0 +1,4 @@
+// RUN: %clang -target i386 -m16 -### -c %s 2>&1 | FileCheck %s
+
+// CHECK: Target: i386-{{.*}}-{{.*}}-code16
+
diff --git a/test/Driver/xcore-opts.c b/test/Driver/xcore-opts.c
index 10d8da1..161756d 100644
--- a/test/Driver/xcore-opts.c
+++ b/test/Driver/xcore-opts.c
@@ -1,13 +1,34 @@
-// RUN: %clang -target xcore %s -g -Wl,L1Arg,L2Arg -Wa,A1Arg,A2Arg -### -o %t.o 2>&1 | FileCheck %s
+// RUN: %clang -target xcore %s -g -Wl,L1Arg,L2Arg -Wa,A1Arg,A2Arg -fverbose-asm -v -### -o %t.o 2>&1 | FileCheck %s
+// RUN: %clang -target xcore -x c++ %s -g -Wl,L1Arg,L2Arg -Wa,A1Arg,A2Arg -fverbose-asm -v -### -o %t.o 2>&1 | FileCheck %s
+// RUN: %clang -target xcore -x c++ %s -fexceptions -### -o %t.o 2>&1 | FileCheck -check-prefix CHECK-EXCEP %s
+// RUN: %clang -target xcore %s -g0 -### -o %t.o 2>&1 | FileCheck -check-prefix CHECK-G0 %s
 
 // CHECK: "-nostdsysteminc"
 // CHECK: "-momit-leaf-frame-pointer"
 // CHECK-NOT: "-mdisable-fp-elim"
 // CHECK: "-fno-signed-char"
 // CHECK: "-fno-use-cxa-atexit"
+// CHECK-NOT: "-fcxx-exceptions"
+// CHECK-NOT: "-fexceptions"
 // CHECK: "-fno-common"
-// CHECH: xcc" "-o"
-// CHECK: "-c" "-g" "A1Arg" "A2Arg"
 // CHECK: xcc" "-o"
+// CHECK-EXCEP-NOT: "-fexceptions"
+// CHECK: "-c" "-v" "-g" "-fverbose-asm" "A1Arg" "A2Arg"
+// CHECK: xcc" "-o"
+// CHECK-EXCEP-NOT: "-fexceptions"
+// CHECK: "-v"
 // CHECK: "L1Arg" "L2Arg"
 
+// CHECK-EXCEP: "-fno-use-cxa-atexit"
+// CHECK-EXCEP: "-fcxx-exceptions"
+// CHECK-EXCEP: "-fexceptions"
+// CHECK-EXCEP: "-fno-common"
+// CHECK-EXCEP: xcc" "-o"
+// CHECK-EXCEP-NOT: "-fexceptions"
+// CHECK-EXCEP: xcc" "-o"
+// CHECK-EXCEP: "-fexceptions"
+
+// CHECK-G0: xcc"
+// CHECK-G0-NOT: "-g"
+// CHECK-G0: xcc"
+
diff --git a/test/FixIt/fixit-cxx0x.cpp b/test/FixIt/fixit-cxx0x.cpp
index bfd8c3d..49a05ff 100644
--- a/test/FixIt/fixit-cxx0x.cpp
+++ b/test/FixIt/fixit-cxx0x.cpp
@@ -125,7 +125,8 @@
   struct foo {
     constexpr int i; // expected-error {{non-static data member cannot be constexpr; did you intend to make it const?}}
     constexpr int j = 7; // expected-error {{non-static data member cannot be constexpr; did you intend to make it static?}}
-    foo() : i(3) {
+    constexpr const int k; // expected-error {{non-static data member cannot be constexpr; did you intend to make it const?}}
+    foo() : i(3), k(4) {
     }
     static int get_j() {
       return j;
@@ -137,3 +138,23 @@
   register int n; // expected-warning {{'register' storage class specifier is deprecated}}
   return n;
 }
+
+namespace MisplacedParameterPack {
+  template <typename Args...> // expected-error {{'...' must immediately precede declared identifier}}
+  void misplacedEllipsisInTypeParameter(Args...);
+
+  template <typename... Args...> // expected-error {{'...' must immediately precede declared identifier}}
+  void redundantEllipsisInTypeParameter(Args...);
+
+  template <template <typename> class Args...> // expected-error {{'...' must immediately precede declared identifier}}
+  void misplacedEllipsisInTemplateTypeParameter(Args<int>...);
+
+  template <template <typename> class... Args...> // expected-error {{'...' must immediately precede declared identifier}}
+  void redundantEllipsisInTemplateTypeParameter(Args<int>...);
+
+  template <int N...> // expected-error {{'...' must immediately precede declared identifier}}
+  void misplacedEllipsisInNonTypeTemplateParameter();
+
+  template <int... N...> // expected-error {{'...' must immediately precede declared identifier}}
+  void redundantEllipsisInNonTypeTemplateParameter();
+}
diff --git a/test/FixIt/fixit-include.h b/test/FixIt/fixit-include.h
index 6a22d2e..358609b 100644
--- a/test/FixIt/fixit-include.h
+++ b/test/FixIt/fixit-include.h
@@ -1 +1 @@
-// This file is purposefully left empty

+// This file is purposefully left empty
diff --git a/test/FixIt/fixit-multiple-selector-warnings.m b/test/FixIt/fixit-multiple-selector-warnings.m
new file mode 100644
index 0000000..391728d
--- /dev/null
+++ b/test/FixIt/fixit-multiple-selector-warnings.m
@@ -0,0 +1,26 @@
+/* RUN: cp %s %t
+   RUN: %clang_cc1 -x objective-c -Wselector-type-mismatch -fixit %t
+   RUN: %clang_cc1 -x objective-c -Wselector-type-mismatch -Werror %t
+*/
+// rdar://16458579
+
+@interface I
+- (id) compare: (char) arg1;
+- length;
+@end
+
+@interface J
+- (id) compare: (id) arg1;
+@end
+
+SEL func()
+{
+        (void)@selector( compare: );
+        (void)@selector (compare:);
+        (void)@selector( compare:);
+        (void)@selector(compare: );
+        (void)@selector ( compare: );
+	return @selector(compare:);
+}
+
+
diff --git a/test/FixIt/fixit-objc-arc.m b/test/FixIt/fixit-objc-arc.m
new file mode 100644
index 0000000..dcee815
--- /dev/null
+++ b/test/FixIt/fixit-objc-arc.m
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -pedantic -verify %s
+// RUN: cp %s %t
+// RUN: not %clang_cc1 -pedantic -fobjc-arc -fixit -x objective-c %t
+// RUN: %clang_cc1 -pedantic -fobjc-arc -Werror -x objective-c %t
+// rdar://14106083
+
+@class A;
+@class NSString;
+
+@interface Test
+- (void)test:(NSString *)string;
+
+@property (copy) NSString *property;
+@end
+
+void g(NSString *a);
+void h(id a);
+
+void f(Test *t) {
+  NSString *a = "Foo"; // expected-error {{string literal must be prefixed by '@'}}
+  g("Foo"); // expected-error {{string literal must be prefixed by '@'}}
+  [t test:"Foo"]; // expected-error {{string literal must be prefixed by '@'}}
+  t.property = "Foo"; // expected-error {{string literal must be prefixed by '@'}}
+}
diff --git a/test/FixIt/fixit-objc-bridge-related-attr.m b/test/FixIt/fixit-objc-bridge-related-attr.m
new file mode 100644
index 0000000..4a81ecd
--- /dev/null
+++ b/test/FixIt/fixit-objc-bridge-related-attr.m
@@ -0,0 +1,35 @@
+// Objective-C recovery
+// RUN: not %clang_cc1  -triple x86_64-apple-darwin10  -fdiagnostics-parseable-fixits -x objective-c %s 2>&1  | FileCheck %s
+// RUN: not %clang_cc1  -triple x86_64-apple-darwin10  -fobjc-arc -fdiagnostics-parseable-fixits -x objective-c %s 2>&1  | FileCheck %s
+// RUN: not %clang_cc1  -triple x86_64-apple-darwin10  -fdiagnostics-parseable-fixits -x objective-c++ %s 2>&1  | FileCheck %s
+// rdar://15499111
+
+typedef struct __attribute__((objc_bridge_related(NSColor,colorWithCGColor:,CGColor))) CGColor *CGColorRef;
+
+@interface NSColor
++ (NSColor *)colorWithCGColor:(CGColorRef)cgColor;
+- (CGColorRef)CGColor;
+@end
+
+@interface NSTextField
+- (void)setBackgroundColor:(NSColor *)color;
+- (NSColor *)backgroundColor;
+@end
+
+NSColor * Test1(NSTextField *textField, CGColorRef newColor) {
+ textField.backgroundColor = newColor;
+ return newColor;
+}
+
+CGColorRef Test2(NSTextField *textField, CGColorRef newColor) {
+ newColor = textField.backgroundColor; // [textField.backgroundColor CGColor]
+ return textField.backgroundColor;
+}
+// CHECK: {20:30-20:30}:"[NSColor colorWithCGColor:"
+// CHECK: {20:38-20:38}:"]"
+// CHECK: {21:9-21:9}:"[NSColor colorWithCGColor:"
+// CHECK: {21:17-21:17}:"]"
+// CHECK: {25:13-25:13}:"["
+// CHECK: {25:38-25:38}:" CGColor]"
+// CHECK: {26:9-26:9}:"["
+// CHECK: {26:34-26:34}:" CGColor]"
diff --git a/test/FixIt/fixit-objc-bridge-related-property.m b/test/FixIt/fixit-objc-bridge-related-property.m
new file mode 100644
index 0000000..5b13645
--- /dev/null
+++ b/test/FixIt/fixit-objc-bridge-related-property.m
@@ -0,0 +1,23 @@
+// RUN: not %clang_cc1  -triple x86_64-apple-darwin10  -fdiagnostics-parseable-fixits -x objective-c %s 2>&1  | FileCheck %s
+// RUN: not %clang_cc1  -triple x86_64-apple-darwin10  -fobjc-arc -fdiagnostics-parseable-fixits -x objective-c %s 2>&1  | FileCheck %s
+// RUN: not %clang_cc1  -triple x86_64-apple-darwin10  -fdiagnostics-parseable-fixits -x objective-c++ %s 2>&1  | FileCheck %s
+// rdar://15517899
+
+typedef struct __attribute__((objc_bridge_related(NSColor,colorWithCGColor:,CGColor))) CGColor *CGColorRef;
+
+@interface NSColor
++ (NSColor *)colorWithCGColor:(CGColorRef)cgColor;
+@property CGColorRef CGColor;
+@end
+
+@interface NSTextField
+- (void)setBackgroundColor:(NSColor *)color;
+- (NSColor *)backgroundColor;
+@end
+
+CGColorRef Test(NSTextField *textField, CGColorRef newColor) {
+ newColor = textField.backgroundColor;
+ return textField.backgroundColor;
+}
+// CHECK:{19:38-19:38}:".CGColor"
+// CHECK:{20:34-20:34}:".CGColor"
diff --git a/test/FixIt/fixit-objc-bridge-related.m b/test/FixIt/fixit-objc-bridge-related.m
new file mode 100644
index 0000000..36ccbca
--- /dev/null
+++ b/test/FixIt/fixit-objc-bridge-related.m
@@ -0,0 +1,43 @@
+// RUN: not %clang_cc1 -triple x86_64-apple-darwin10  -fdiagnostics-parseable-fixits -x objective-c -fobjc-arc %s 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -triple x86_64-apple-darwin10  -fdiagnostics-parseable-fixits -x objective-c++ -fobjc-arc %s 2>&1 | FileCheck %s
+// rdar://15932435
+
+typedef struct __attribute__((objc_bridge_related(UIColor,colorWithCGColor:,CGColor))) CGColor *CGColorRef;
+
+@interface UIColor 
++ (UIColor *)colorWithCGColor:(CGColorRef)cgColor;
+- (CGColorRef)CGColor;
+@end
+
+@interface UIButton
+@property(nonatomic,retain) UIColor *tintColor;
+@end
+
+void test(UIButton *myButton) {
+  CGColorRef cgColor = (CGColorRef)myButton.tintColor;
+  cgColor = myButton.tintColor;
+
+  cgColor = (CGColorRef)[myButton.tintColor CGColor];
+
+  cgColor = (CGColorRef)[myButton tintColor];
+}
+
+// CHECK: {17:36-17:36}:"["
+// CHECK: {17:54-17:54}:" CGColor]"
+
+// CHECK :{18:13-18:13}:"["
+// CHECK: {18:31-18:31}:" CGColor]"
+
+// CHECK :{22:25-22:25}:"["
+// CHECK :{22:45-22:45}:" CGColor]"
+
+@interface ImplicitPropertyTest
+- (UIColor *)tintColor;
+@end
+
+void test1(ImplicitPropertyTest *myImplicitPropertyTest) {
+  CGColorRef cgColor = (CGColorRef)[myImplicitPropertyTest tintColor];
+}
+
+// CHECK :{39:36-39:36}:"["
+// CHECK :{39:70-39:70}:" CGColor]"
diff --git a/test/FixIt/fixit-objc.m b/test/FixIt/fixit-objc.m
index 7c4776a..f41f75f 100644
--- a/test/FixIt/fixit-objc.m
+++ b/test/FixIt/fixit-objc.m
@@ -18,22 +18,22 @@
 @class NSString;
 
 @interface Test
-- (void)test:(NSString *)string; // expected-note{{passing argument to parameter 'string' here}}
+- (void)test:(NSString *)string;
 
 @property (copy) NSString *property;
 @end
 
-void g(NSString *a); // expected-note{{passing argument to parameter 'a' here}}
-void h(id a); // expected-note 2{{passing argument to parameter 'a' here}}
+void g(NSString *a);
+void h(id a);
 
 void f(Test *t) {
-  NSString *a = "Foo"; // expected-warning {{string literal must be prefixed by '@'}}
-  id b = "Foo"; // expected-warning {{incompatible pointer types initializing 'id' with an expression of type 'char [4]'}}
-  g("Foo"); // expected-warning {{string literal must be prefixed by '@'}}
-  h("Foo"); // expected-warning{{incompatible pointer types passing 'char [4]' to parameter of type 'id'}}
-  h(("Foo")); // expected-warning{{incompatible pointer types passing 'char [4]' to parameter of type 'id'}}
-  [t test:"Foo"]; // expected-warning {{string literal must be prefixed by '@'}}
-  t.property = "Foo"; // expected-warning {{string literal must be prefixed by '@'}}
+  NSString *a = "Foo"; // expected-error {{string literal must be prefixed by '@'}}
+  id b = "Foo"; // expected-error {{string literal must be prefixed by '@'}}
+  g("Foo"); // expected-error {{string literal must be prefixed by '@'}}
+  h("Foo"); // expected-error {{string literal must be prefixed by '@'}}
+  h(("Foo")); // expected-error {{string literal must be prefixed by '@'}}
+  [t test:"Foo"]; // expected-error {{string literal must be prefixed by '@'}}
+  t.property = "Foo"; // expected-error {{string literal must be prefixed by '@'}}
 
   // <rdar://problem/6896493>
   [t test:@"Foo"]]; // expected-error{{extraneous ']' before ';'}}
diff --git a/test/FixIt/fixit-unicode-with-utf8-output.c b/test/FixIt/fixit-unicode-with-utf8-output.c
index aff8542..a1a7bb7 100644
--- a/test/FixIt/fixit-unicode-with-utf8-output.c
+++ b/test/FixIt/fixit-unicode-with-utf8-output.c
@@ -2,6 +2,7 @@
 // systems capable of outputting Unicode characters to the standard output in
 // the UTF-8 encoding.
 // RUN: not %clang_cc1 -fsyntax-only %S/fixit-unicode.c 2>&1 | FileCheck -strict-whitespace %s
+// REQUIRES: utf8-capable-terminal
 
 // CHECK: warning: format specifies type 'int' but the argument has type 'long'
 // CHECK: {{^  printf\("∆: %d", 1L\);}}
diff --git a/test/FixIt/fixit.cpp b/test/FixIt/fixit.cpp
index 52bbb38..f264938 100644
--- a/test/FixIt/fixit.cpp
+++ b/test/FixIt/fixit.cpp
@@ -19,7 +19,7 @@
 
 static void C1::g() { } // expected-error{{'static' can only be specified inside the class definition}}
 
-template<int Value> struct CT { }; // expected-note{{previous use is here}}
+template<int Value> struct CT { template<typename> struct Inner; }; // expected-note{{previous use is here}}
 
 CT<10 >> 2> ct; // expected-warning{{require parentheses}}
 
@@ -32,6 +32,8 @@
 
 template<> union CT<1> { }; // expected-error{{tag type}}
 
+struct CT<2>::Inner<int> { }; // expected-error 2{{'template<>'}}
+
 // Access declarations
 class A {
 protected:
@@ -202,7 +204,7 @@
 }
 
 template<template<typename> Foo, // expected-error {{template template parameter requires 'class' after the parameter list}}
-         template<typename> typename Bar, // expected-error {{template template parameter requires 'class' after the parameter list}}
+         template<typename> typename Bar, // expected-warning {{template template parameter using 'typename' is a C++1z extension}}
          template<typename> struct Baz> // expected-error {{template template parameter requires 'class' after the parameter list}}
 void func();
 
diff --git a/test/FixIt/format-darwin.m b/test/FixIt/format-darwin.m
index f5205643..170bb09 100644
--- a/test/FixIt/format-darwin.m
+++ b/test/FixIt/format-darwin.m
@@ -1,11 +1,8 @@
 // RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -fblocks -Wformat-non-iso -verify %s
 // RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fsyntax-only -fblocks -Wformat-non-iso -verify %s
 
-// RUN: %clang_cc1 -triple i386-apple-darwin9 -fdiagnostics-parseable-fixits -fblocks -Wformat-non-iso %s 2>&1 | FileCheck %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fdiagnostics-parseable-fixits -fblocks -Wformat-non-iso %s 2>&1 | FileCheck %s
-
-// RUN: %clang_cc1 -triple i386-apple-darwin9 -fdiagnostics-parseable-fixits -fblocks -Wformat-non-iso %s 2>&1 | FileCheck -check-prefix=CHECK-32 %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fdiagnostics-parseable-fixits -fblocks -Wformat-non-iso %s 2>&1 | FileCheck -check-prefix=CHECK-64 %s
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -fdiagnostics-parseable-fixits -fblocks -Wformat-non-iso %s 2>&1 | FileCheck -check-prefix=CHECK -check-prefix=CHECK-32 %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fdiagnostics-parseable-fixits -fblocks -Wformat-non-iso %s 2>&1 | FileCheck -check-prefix=CHECK -check-prefix=CHECK-64 %s
 
 int printf(const char * restrict, ...);
 
@@ -25,10 +22,16 @@
 
 typedef SInt32 OSStatus;
 
+typedef enum NSIntegerEnum : NSInteger {
+  EnumValueA,
+  EnumValueB
+} NSIntegerEnum;
+
 NSInteger getNSInteger();
 NSUInteger getNSUInteger();
 SInt32 getSInt32();
 UInt32 getUInt32();
+NSIntegerEnum getNSIntegerEnum();
 
 void testCorrectionInAllCases() {
   printf("%s", getNSInteger()); // expected-warning{{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
@@ -47,6 +50,11 @@
 
   // CHECK: fix-it:"{{.*}}":{[[@LINE-11]]:11-[[@LINE-11]]:13}:"%u"
   // CHECK: fix-it:"{{.*}}":{[[@LINE-12]]:16-[[@LINE-12]]:16}:"(unsigned int)"
+
+  printf("%s", getNSIntegerEnum()); // expected-warning{{enum values with underlying type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
+
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:11-[[@LINE-2]]:13}:"%ld"
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:16-[[@LINE-3]]:16}:"(long)"
 }
 
 @interface Foo {
@@ -107,6 +115,11 @@
 
   // CHECK-64: fix-it:"{{.*}}":{[[@LINE-11]]:11-[[@LINE-11]]:14}:"%u"
   // CHECK-64: fix-it:"{{.*}}":{[[@LINE-12]]:17-[[@LINE-12]]:17}:"(unsigned int)"
+
+  printf("%d", getNSIntegerEnum()); // expected-warning{{enum values with underlying type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
+
+  // CHECK-64: fix-it:"{{.*}}":{[[@LINE-2]]:11-[[@LINE-2]]:13}:"%ld"
+  // CHECK-64: fix-it:"{{.*}}":{[[@LINE-3]]:16-[[@LINE-3]]:16}:"(long)"
 }
 
 void testPreserveHex() {
@@ -135,6 +148,7 @@
   printf("%lu", getNSUInteger()); // no-warning
   printf("%d", getSInt32()); // no-warning
   printf("%u", getUInt32()); // no-warning
+  printf("%ld", getNSIntegerEnum()); // no-warning
 }
 
 #else
@@ -149,6 +163,10 @@
   // CHECK-32: fix-it:"{{.*}}":{[[@LINE-5]]:17-[[@LINE-5]]:17}:"(unsigned long)"
   // CHECK-32: fix-it:"{{.*}}":{[[@LINE-5]]:16-[[@LINE-5]]:16}:"(int)"
   // CHECK-32: fix-it:"{{.*}}":{[[@LINE-5]]:16-[[@LINE-5]]:16}:"(unsigned int)"
+
+  printf("%ld", getNSIntegerEnum()); // expected-warning{{enum values with underlying type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
+
+  // CHECK-32: fix-it:"{{.*}}":{[[@LINE-2]]:17-[[@LINE-2]]:17}:"(long)"
 }
 
 void testPreserveHex() {
@@ -164,6 +182,7 @@
   printf("%u", getNSUInteger()); // no-warning
   printf("%ld", getSInt32()); // no-warning
   printf("%lu", getUInt32()); // no-warning
+  printf("%d", getNSIntegerEnum()); // no-warning
 }
 
 void testSignedness(NSInteger i, NSUInteger u) {
@@ -194,6 +213,11 @@
 
   // CHECK: fix-it:"{{.*}}":{[[@LINE-11]]:11-[[@LINE-11]]:13}:"%u"
   // CHECK: fix-it:"{{.*}}":{[[@LINE-12]]:16-[[@LINE-12]]:24}:"(unsigned int)"
+
+  printf("%s", (NSIntegerEnum)0); // expected-warning{{enum values with underlying type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
+
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:11-[[@LINE-2]]:13}:"%ld"
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:16-[[@LINE-3]]:31}:"(long)"
 }
 
 void testCapitals() {
diff --git a/test/FixIt/format.m b/test/FixIt/format.m
index 5e46360..d07ee36 100644
--- a/test/FixIt/format.m
+++ b/test/FixIt/format.m
@@ -82,14 +82,14 @@
 
 typedef enum : int { NSUTF8StringEncoding = 8 } NSStringEncoding;
 void test_fixed_enum_correction(NSStringEncoding x) {
-  NSLog(@"%@", x); // expected-warning{{format specifies type 'id' but the argument has type 'NSStringEncoding'}}
+  NSLog(@"%@", x); // expected-warning{{format specifies type 'id' but the argument has underlying type 'int'}}
   // CHECK: fix-it:"{{.*}}":{85:11-85:13}:"%d"
 }
 
 typedef __SIZE_TYPE__ size_t;
 enum SomeSize : size_t { IntegerSize = sizeof(int) };
 void test_named_fixed_enum_correction(enum SomeSize x) {
-  NSLog(@"%@", x); // expected-warning{{format specifies type 'id' but the argument has type 'enum SomeSize'}}
+  NSLog(@"%@", x); // expected-warning{{format specifies type 'id' but the argument has underlying type 'size_t' (aka}}
   // CHECK: fix-it:"{{.*}}":{92:11-92:13}:"%zu"
 }
 
@@ -228,3 +228,29 @@
 
   // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:11-[[@LINE-2]]:14}:"%+ld"
 }
+
+void testEnum() {
+  typedef enum {
+    ImplicitA = 1,
+    ImplicitB = 2
+  } Implicit;
+
+  typedef enum {
+    ImplicitLLA = 0,
+    ImplicitLLB = ~0ULL
+  } ImplicitLongLong;
+
+  typedef enum : short {
+    ExplicitA = 0,
+    ExplicitB
+  } ExplicitShort;
+
+  printf("%f", (Implicit)0); // expected-warning{{format specifies type 'double' but the argument has underlying type}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%{{[du]}}"
+
+  printf("%f", (ImplicitLongLong)0); // expected-warning{{format specifies type 'double' but the argument has underlying type}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%{{l*[du]}}"
+
+  printf("%f", (ExplicitShort)0); // expected-warning{{format specifies type 'double' but the argument has underlying type 'short'}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%hd"
+}
diff --git a/test/FixIt/lit.local.cfg b/test/FixIt/lit.local.cfg
deleted file mode 100644
index 5bbc711..0000000
--- a/test/FixIt/lit.local.cfg
+++ /dev/null
@@ -1,2 +0,0 @@
-if config.root.clang_rewriter == 0:
-    config.unsupported = True
diff --git a/test/FixIt/no-diagnostics-fixit-info.c b/test/FixIt/no-diagnostics-fixit-info.c
new file mode 100644
index 0000000..9696a2e
--- /dev/null
+++ b/test/FixIt/no-diagnostics-fixit-info.c
@@ -0,0 +1,16 @@
+// RUN: not %clang_cc1 %s 2>&1 | FileCheck -check-prefix=WITH-FIXIT %s
+// RUN: not %clang_cc1 -fno-diagnostics-fixit-info %s 2>&1 | FileCheck -check-prefix=WITHOUT-FIXIT %s
+
+struct Foo {
+  int x;
+}
+// WITH-FIXIT: error: expected ';' after struct
+// WITH-FIXIT-NEXT: }
+// WITH-FIXIT-NEXT:  ^
+// WITH-FIXIT-NEXT:  ;
+
+// WITHOUT-FIXIT: error: expected ';' after struct
+// WITHOUT-FIXIT-NEXT: }
+// WITHOUT-FIXIT-NEXT: ^
+// WITHOUT-FIXIT-NOT: ;
+
diff --git a/test/FixIt/typo-location-bugs.cpp b/test/FixIt/typo-location-bugs.cpp
index 9c34a91..e44664d 100644
--- a/test/FixIt/typo-location-bugs.cpp
+++ b/test/FixIt/typo-location-bugs.cpp
@@ -19,3 +19,18 @@
   pb->f(); // expected-error{{too few arguments to function call, expected 1, have 0; did you mean 'A::f'?}}
 }
 }
+
+namespace PR18608 {
+struct A {
+virtual void f() const;
+virtual void f(int x) const;  // expected-note{{'A::f' declared here}}
+};
+
+struct B : public A {
+virtual void f() const;
+};
+
+void test(B b) {
+  b.f(1);  // expected-error{{too many arguments to function call, expected 0, have 1; did you mean 'A::f'?}}
+}
+}
diff --git a/test/Format/disable-format.cpp b/test/Format/disable-format.cpp
new file mode 100644
index 0000000..59484b3
--- /dev/null
+++ b/test/Format/disable-format.cpp
@@ -0,0 +1,6 @@
+// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
+// RUN: clang-format -style=none -i %t.cpp
+// RUN: FileCheck -strict-whitespace -input-file=%t.cpp %s
+
+// CHECK: int   i;
+int   i;
diff --git a/test/Format/language-detection.cpp b/test/Format/language-detection.cpp
new file mode 100644
index 0000000..bec444d
--- /dev/null
+++ b/test/Format/language-detection.cpp
@@ -0,0 +1,7 @@
+// RUN: grep -Ev "// *[A-Z0-9_]+:" %s > %t.js
+// RUN: grep -Ev "// *[A-Z0-9_]+:" %s > %t.cpp
+// RUN: clang-format -style=llvm %t.js | FileCheck -strict-whitespace -check-prefix=CHECK1 %s
+// RUN: clang-format -style=llvm %t.cpp | FileCheck -strict-whitespace -check-prefix=CHECK2 %s
+// CHECK1: {{^a >>>= b;$}}
+// CHECK2: {{^a >> >= b;$}}
+a >>>= b;
diff --git a/test/Format/style-on-command-line.cpp b/test/Format/style-on-command-line.cpp
index 22131a1..007022e 100644
--- a/test/Format/style-on-command-line.cpp
+++ b/test/Format/style-on-command-line.cpp
@@ -1,29 +1,34 @@
 // RUN: grep -Ev "// *[A-Z0-9_]+:" %s > %t.cpp
 // RUN: clang-format -style="{BasedOnStyle: Google, IndentWidth: 8}" %t.cpp | FileCheck -strict-whitespace -check-prefix=CHECK1 %s
 // RUN: clang-format -style="{BasedOnStyle: LLVM, IndentWidth: 7}" %t.cpp | FileCheck -strict-whitespace -check-prefix=CHECK2 %s
-// RUN: clang-format -style="{BasedOnStyle: invalid, IndentWidth: 7}" %t.cpp 2>&1 | FileCheck -strict-whitespace -check-prefix=CHECK3 %s
-// RUN: clang-format -style="{lsjd}" %t.cpp 2>&1 | FileCheck -strict-whitespace -check-prefix=CHECK4 %s
+// RUN: clang-format -style="{BasedOnStyle: invalid, IndentWidth: 7}" -fallback-style=LLVM %t.cpp 2>&1 | FileCheck -strict-whitespace -check-prefix=CHECK3 %s
+// RUN: clang-format -style="{lsjd}" %t.cpp -fallback-style=LLVM 2>&1 | FileCheck -strict-whitespace -check-prefix=CHECK4 %s
 // RUN: [ ! -e %T/.clang-format ] || rm %T/.clang-format
 // RUN: printf "BasedOnStyle: google\nIndentWidth: 5\n" > %T/.clang-format
 // RUN: clang-format -style=file %t.cpp 2>&1 | FileCheck -strict-whitespace -check-prefix=CHECK5 %s
 // RUN: printf "\n" > %T/.clang-format
-// RUN: clang-format -style=file %t.cpp 2>&1 | FileCheck -strict-whitespace -check-prefix=CHECK6 %s
+// RUN: clang-format -style=file -fallback-style=webkit %t.cpp 2>&1 | FileCheck -strict-whitespace -check-prefix=CHECK6 %s
 // RUN: [ ! -e %T/.clang-format ] || rm %T/.clang-format
 // RUN: [ ! -e %T/_clang-format ] || rm %T/_clang-format
 // RUN: printf "BasedOnStyle: google\nIndentWidth: 6\n" > %T/_clang-format
 // RUN: clang-format -style=file %t.cpp 2>&1 | FileCheck -strict-whitespace -check-prefix=CHECK7 %s
+// RUN: clang-format -style="{BasedOnStyle: LLVM, PointerBindsToType: true}" %t.cpp | FileCheck -strict-whitespace -check-prefix=CHECK8 %s
+// RUN: clang-format -style="{BasedOnStyle: WebKit, PointerBindsToType: false}" %t.cpp | FileCheck -strict-whitespace -check-prefix=CHECK9 %s
 void f() {
 // CHECK1: {{^        int\* i;$}}
 // CHECK2: {{^       int \*i;$}}
 // CHECK3: Unknown value for BasedOnStyle: invalid
-// CHECK3: Error parsing -style: Invalid argument, using LLVM style
+// CHECK3: Error parsing -style: {{I|i}}nvalid argument, using LLVM style
 // CHECK3: {{^  int \*i;$}}
-// CHECK4: Error parsing -style: Invalid argument, using LLVM style
+// CHECK4: Error parsing -style: {{I|i}}nvalid argument, using LLVM style
 // CHECK4: {{^  int \*i;$}}
 // CHECK5: {{^     int\* i;$}}
-// CHECK6: {{^Error reading .*\.clang-format: Invalid argument}}
-// XCHECK6X: {{^  int \*i;$}}
+// CHECK6: {{^Error reading .*\.clang-format: (I|i)nvalid argument}}
+// CHECK6: {{^Can't find usable .clang-format, using webkit style$}}
+// CHECK6: {{^    int\* i;$}}
 // CHECK7: {{^      int\* i;$}}
+// CHECK8: {{^  int\* i;$}}
+// CHECK9: {{^    int \*i;$}}
 int*i;
 int j;
 }
diff --git a/test/Frontend/Inputs/rewrite-includes-bom.h b/test/Frontend/Inputs/rewrite-includes-bom.h
new file mode 100644
index 0000000..7ba011f
--- /dev/null
+++ b/test/Frontend/Inputs/rewrite-includes-bom.h
@@ -0,0 +1 @@
+// This file starts with UTF-8 BOM marker.
diff --git a/test/Frontend/Inputs/rewrite-includes-messages.h b/test/Frontend/Inputs/rewrite-includes-messages.h
new file mode 100644
index 0000000..e5f0eb2
--- /dev/null
+++ b/test/Frontend/Inputs/rewrite-includes-messages.h
@@ -0,0 +1,4 @@
+void f()
+{
+    int unused_variable;
+}
diff --git a/test/Frontend/backend-diagnostic.c b/test/Frontend/backend-diagnostic.c
new file mode 100644
index 0000000..1fe4fdb
--- /dev/null
+++ b/test/Frontend/backend-diagnostic.c
@@ -0,0 +1,31 @@
+// REQUIRES: x86-registered-target
+// Play around with backend reporting:
+// _REGULAR_: Regular behavior, no warning switch enabled.
+// _PROMOTE_: Promote warning to error.
+// _IGNORE_: Drop backend warning.
+//
+// RUN: not %clang_cc1 %s -mllvm -warn-stack-size=0 -no-integrated-as -S -o - -triple=i386-apple-darwin 2> %t.err
+// RUN: FileCheck < %t.err %s --check-prefix=REGULAR --check-prefix=ASM
+// RUN: not %clang_cc1 %s -mllvm -warn-stack-size=0 -no-integrated-as -S -o - -triple=i386-apple-darwin -Werror=frame-larger-than= 2> %t.err
+// RUN: FileCheck < %t.err %s --check-prefix=PROMOTE --check-prefix=ASM
+// RUN: not %clang_cc1 %s -mllvm -warn-stack-size=0 -no-integrated-as -S -o - -triple=i386-apple-darwin -Wno-frame-larger-than= 2> %t.err
+// RUN: FileCheck < %t.err %s --check-prefix=IGNORE --check-prefix=ASM
+//
+// RUN: %clang_cc1 %s -S -o - -triple=i386-apple-darwin -verify -no-integrated-as
+
+extern void doIt(char *);
+
+// REGULAR: warning: stack frame size of {{[0-9]+}} bytes in function 'stackSizeWarning'
+// PROMOTE: error: stack frame size of {{[0-9]+}} bytes in function 'stackSizeWarning'
+// IGNORE-NOT: stack frame size of {{[0-9]+}} bytes in function 'stackSizeWarning'
+void stackSizeWarning() {
+  char buffer[80];
+  doIt(buffer);
+}
+
+// ASM: inline assembly requires more registers than available
+void inlineAsmError(int x0, int x1, int x2, int x3, int x4,
+                    int x5, int x6, int x7, int x8, int x9) {
+  __asm__("hello world": : "r" (x0),"r" (x1),"r" (x2),"r" (x3), // expected-error + {{inline assembly requires more registers than available}}
+          "r" (x4),"r" (x5),"r" (x6),"r" (x7),"r" (x8),"r" (x9));
+}
diff --git a/test/Frontend/darwin-eabi.c b/test/Frontend/darwin-eabi.c
index dc0504b..27471e6 100644
--- a/test/Frontend/darwin-eabi.c
+++ b/test/Frontend/darwin-eabi.c
@@ -1,6 +1,7 @@
-// RUN: %clang -target x86_64-apple-darwin -arch armv6m -dM -E %s | FileCheck %s
-// RUN: %clang -target x86_64-apple-darwin -arch armv7m -dM -E %s | FileCheck %s
-// RUN: %clang -target x86_64-apple-darwin -arch armv7em -dM -E %s | FileCheck %s
+// RUN: %clang -arch armv6m -dM -E %s | FileCheck %s
+// RUN: %clang -arch armv7m -dM -E %s | FileCheck %s
+// RUN: %clang -arch armv7em -dM -E %s | FileCheck %s
+// RUN: %clang_cc1 -triple thumbv7m-apple-unknown-macho -dM -E %s | FileCheck %s
 
 // CHECK-NOT: __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__
 // CHECK-NOT: __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
diff --git a/test/Frontend/darwin-version.c b/test/Frontend/darwin-version.c
index 7234ab4..2e0804b 100644
--- a/test/Frontend/darwin-version.c
+++ b/test/Frontend/darwin-version.c
@@ -23,3 +23,5 @@
 // RUN: grep '__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__' %t | grep '1050' | count 1
 // RUN: %clang -target i686-apple-darwin9 -mmacosx-version-min=10.6 -dM -E -o %t %s
 // RUN: grep '__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__' %t | grep '1060' | count 1
+// RUN: %clang -target x86_64-apple-macosx -mmacosx-version-min=10.10 -dM -E -o %t %s
+// RUN: grep '__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__' %t | grep '101000' | count 1
diff --git a/test/Frontend/disable-output.c b/test/Frontend/disable-output.c
new file mode 100644
index 0000000..786ac77
--- /dev/null
+++ b/test/Frontend/disable-output.c
@@ -0,0 +1,7 @@
+// REQUIRES: x86-registered-target
+// RUN: %clang_cc1 %s -emit-llvm-only -triple=i386-apple-darwin -o %t
+// RUN: not rm %t
+// RUN: %clang_cc1 %s -emit-codegen-only -triple=i386-apple-darwin -o %t
+// RUN: not rm %t
+
+// Test that output is not generated when emission is disabled.
diff --git a/test/Frontend/exceptions.c b/test/Frontend/exceptions.c
new file mode 100644
index 0000000..4bbaaa3
--- /dev/null
+++ b/test/Frontend/exceptions.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fms-compatibility -fexceptions -fcxx-exceptions -verify %s
+// expected-no-diagnostics
+
+#if defined(__EXCEPTIONS)
+#error __EXCEPTIONS should not be defined.
+#endif
diff --git a/test/Frontend/invalid-o-level.c b/test/Frontend/invalid-o-level.c
index b9e01fc..73be9b1 100644
--- a/test/Frontend/invalid-o-level.c
+++ b/test/Frontend/invalid-o-level.c
@@ -1,4 +1,4 @@
 // RUN: %clang_cc1 %s -O900 -o /dev/null 2> %t.log
 // RUN: FileCheck %s -input-file=%t.log
 
-// CHECK: warning: optimization level '-O900' is unsupported; using '-O3' instead
+// CHECK: warning: optimization level '-O900' is not supported; using '-O3' instead
diff --git a/test/Frontend/ir-support-codegen.ll b/test/Frontend/ir-support-codegen.ll
index e5e5b62..3dc3c0a 100644
--- a/test/Frontend/ir-support-codegen.ll
+++ b/test/Frontend/ir-support-codegen.ll
@@ -1,9 +1,15 @@
-; REQUIRES: x86-64-registered-target
-; RUN: %clang_cc1 -S -o - %s | FileCheck %s
+; REQUIRES: x86-registered-target
+; RUN: %clang_cc1 -triple x86_64-apple-darwin10 -S -o - %s | FileCheck %s
+
+; RUN: %clang_cc1 -triple x86_64-pc-linux -S -o %t %s 2>&1 | \
+; RUN: FileCheck --check-prefix=WARN %s
+; WARN: warning: overriding the module target triple with x86_64-pc-linux
+; RUN: FileCheck --check-prefix=LINUX %s < %t
 
 target triple = "x86_64-apple-darwin10"
 
 ; CHECK: .globl _f0
+; LINUX: .globl f0
 define i32 @f0() nounwind ssp {
        ret i32 0
 }
diff --git a/test/Frontend/ir-support.c b/test/Frontend/ir-support.c
new file mode 100644
index 0000000..f69161e
--- /dev/null
+++ b/test/Frontend/ir-support.c
@@ -0,0 +1,19 @@
+// Test that we can consume LLVM IR/bitcode in the frontend and produce
+// equivalent output to a standard compilation.
+
+// We strip differing '.file' directives before comparing.
+
+// Reference output:
+// RUN: %clang_cc1 -S -o - %s | grep -v '\.file' > %t.s
+
+// LLVM bitcode:
+// RUN: %clang_cc1 -emit-llvm-bc -o %t.bc %s
+// RUN: %clang_cc1 -S -o - %t.bc | grep -v '\.file' > %t.bc.s
+// RUN: diff %t.s %t.bc.s
+
+// LLVM IR source code:
+// RUN: %clang_cc1 -emit-llvm -o %t.ll %s
+// RUN: %clang_cc1 -S -o - %t.ll | grep -v '\.file' > %t.ll.s
+// RUN: diff %t.s %t.ll.s
+
+int f() { return 0; }
diff --git a/test/Frontend/lit.local.cfg b/test/Frontend/lit.local.cfg
index 4c13598..c11fb6d 100644
--- a/test/Frontend/lit.local.cfg
+++ b/test/Frontend/lit.local.cfg
@@ -1 +1 @@
-config.suffixes = ['.c', '.cpp', '.m', '.mm', '.ll', '.bc']
+config.suffixes = ['.c', '.cpp', '.m', '.mm', '.ll']
diff --git a/test/Frontend/optimization-remark-line-directive.c b/test/Frontend/optimization-remark-line-directive.c
new file mode 100644
index 0000000..f4c0011
--- /dev/null
+++ b/test/Frontend/optimization-remark-line-directive.c
@@ -0,0 +1,12 @@
+// This file tests -Rpass diagnostics together with #line
+// directives. We cannot map #line directives back to
+// a SourceLocation.
+
+// RUN: %clang_cc1 %s -Rpass=inline -gline-tables-only -dwarf-column-info -emit-llvm-only -verify
+
+int foo(int x, int y) __attribute__((always_inline));
+int foo(int x, int y) { return x + y; }
+
+// expected-remark@+2 {{foo inlined into bar}} expected-note@+2 {{could not determine the original source location for /bad/path/to/original.c:1230:25}}
+#line 1230 "/bad/path/to/original.c"
+int bar(int j) { return foo(j, j - 2); }
diff --git a/test/Frontend/optimization-remark.c b/test/Frontend/optimization-remark.c
new file mode 100644
index 0000000..6ada003
--- /dev/null
+++ b/test/Frontend/optimization-remark.c
@@ -0,0 +1,51 @@
+// This file tests the -Rpass family of flags (-Rpass, -Rpass-missed
+// and -Rpass-analysis) with the inliner. The test is designed to
+// always trigger the inliner, so it should be independent of the
+// optimization level.
+
+// RUN: %clang_cc1 %s -Rpass=inline -Rpass-analysis=inline -Rpass-missed=inline -O0 -emit-llvm-only -verify
+// RUN: %clang_cc1 %s -Rpass=inline -Rpass-analysis=inline -Rpass-missed=inline -O0 -emit-llvm-only -gline-tables-only -verify
+// RUN: %clang_cc1 %s -Rpass=inline -emit-llvm -o - 2>/dev/null | FileCheck %s
+//
+// Check that we can override -Rpass= with -Rno-pass.
+// RUN: %clang_cc1 %s -Rpass=inline -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK-REMARKS
+// RUN: %clang_cc1 %s -Rpass=inline -Rno-pass -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK-NO-REMARKS
+// RUN: %clang_cc1 %s -Rpass=inline -Rno-everything -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK-NO-REMARKS
+// RUN: %clang_cc1 %s -Rpass=inline -Rno-everything -Reverything -emit-llvm -o - 2>&1 | FileCheck %s --check-prefix=CHECK-REMARKS
+//
+// FIXME: -Reverything should imply -Rpass=.*.
+// RUN: %clang_cc1 %s -Reverything -emit-llvm -o - 2>/dev/null | FileCheck %s --check-prefix=CHECK-NO-REMARKS
+//
+// FIXME: -Rpass should either imply -Rpass=.* or should be rejected.
+// RUN: %clang_cc1 %s -Rpass -emit-llvm -o - 2>/dev/null | FileCheck %s --check-prefix=CHECK-NO-REMARKS
+
+// CHECK-REMARKS: remark:
+// CHECK-NO-REMARKS-NOT: remark:
+
+// -Rpass should produce source location annotations, exclusively (just
+// like -gmlt).
+// CHECK: , !dbg !
+// CHECK-NOT: DW_TAG_base_type
+
+// But llvm.dbg.cu should be missing (to prevent writing debug info to
+// the final output).
+// CHECK-NOT: !llvm.dbg.cu = !{
+
+int foo(int x, int y) __attribute__((always_inline));
+int foo(int x, int y) { return x + y; }
+
+float foz(int x, int y) __attribute__((noinline));
+float foz(int x, int y) { return x * y; }
+
+// The negative diagnostics are emitted twice because the inliner runs
+// twice.
+//
+int bar(int j) {
+// expected-remark@+6 {{foz should never be inlined (cost=never)}}
+// expected-remark@+5 {{foz will not be inlined into bar}}
+// expected-remark@+4 {{foz should never be inlined}}
+// expected-remark@+3 {{foz will not be inlined into bar}}
+// expected-remark@+2 {{foo should always be inlined}}
+// expected-remark@+1 {{foo inlined into bar}}
+  return foo(j, j - 2) * foz(j - 2, j);
+}
diff --git a/test/Frontend/plugins.c b/test/Frontend/plugins.c
new file mode 100644
index 0000000..8117f72
--- /dev/null
+++ b/test/Frontend/plugins.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -load %llvmshlibdir/PrintFunctionNames%pluginext -plugin print-fns %s 2>&1 | FileCheck %s
+// REQUIRES: plugins, examples
+
+// CHECK: top-level-decl: "x"
+void x();
diff --git a/test/Frontend/print-header-includes.c b/test/Frontend/print-header-includes.c
index aa3e397..e248c76 100644
--- a/test/Frontend/print-header-includes.c
+++ b/test/Frontend/print-header-includes.c
@@ -1,12 +1,12 @@
-// RUN: %clang_cc1 -include Inputs/test3.h -E -H -o %t.out %s 2> %t.err
-// RUN: FileCheck < %t.err %s
+// RUN: %clang_cc1 -include Inputs/test3.h -E -H -o %t.out %s 2> %t.stderr
+// RUN: FileCheck < %t.stderr %s
 
 // CHECK-NOT: test3.h
 // CHECK: . {{.*test.h}}
 // CHECK: .. {{.*test2.h}}
 
-// RUN: %clang_cc1 -include Inputs/test3.h -E --show-includes -o %t.out %s 2> %t.err
-// RUN: FileCheck --check-prefix=MS < %t.err %s
+// RUN: %clang_cc1 -include Inputs/test3.h -E --show-includes -o %t.out %s > %t.stdout
+// RUN: FileCheck --check-prefix=MS < %t.stdout %s
 // MS-NOT: test3.h
 // MS: Note: including file: {{.*test.h}}
 // MS: Note: including file:  {{.*test2.h}}
diff --git a/test/Frontend/rewrite-includes-bom.c b/test/Frontend/rewrite-includes-bom.c
new file mode 100644
index 0000000..caa431a
--- /dev/null
+++ b/test/Frontend/rewrite-includes-bom.c
@@ -0,0 +1,8 @@
+// RUN: grep -q $'^\xEF\xBB\xBF' %S/Inputs/rewrite-includes-bom.h
+// RUN: %clang_cc1 -E -frewrite-includes -I %S/Inputs %s -o %t.c
+// RUN: ! grep -q $'\xEF\xBB\xBF' %t.c
+// RUN: %clang_cc1 -fsyntax-only -verify %t.c
+// expected-no-diagnostics
+// REQUIRES: shell
+
+#include "rewrite-includes-bom.h"
diff --git a/test/Frontend/rewrite-includes-cli-include.c b/test/Frontend/rewrite-includes-cli-include.c
new file mode 100644
index 0000000..ba96039
--- /dev/null
+++ b/test/Frontend/rewrite-includes-cli-include.c
@@ -0,0 +1,9 @@
+// RUN: not %clang_cc1 -verify -E -frewrite-includes -include %S/Inputs/rewrite-includes2.h %s -o - | FileCheck -strict-whitespace %s
+main_file_line
+// CHECK: {{^}}# 1 "<built-in>"{{$}}
+// CHECK-NEXT: {{^}}# 1 "{{.*[/\\]Inputs(/|\\\\)}}rewrite-includes2.h" 1{{$}}
+// CHECK-NEXT: {{^}}included_line2{{$}}
+// CHECK-NEXT: {{^}}# 1 "<built-in>" 2{{$}}
+// CHECK-NEXT: {{^}}# 1 "{{.*}}rewrite-includes-cli-include.c"{{$}}
+// CHECK-NEXT: FileCheck
+// CHECK-NEXT: {{^}}main_file_line{{$}}
diff --git a/test/Frontend/rewrite-includes-eof.c b/test/Frontend/rewrite-includes-eof.c
new file mode 100644
index 0000000..af7fd89
--- /dev/null
+++ b/test/Frontend/rewrite-includes-eof.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -E -frewrite-includes -I %S/Inputs %s
+// expected-no-diagnostics
+// Note: there's no newline at the end of this C file.
+#include "rewrite-includes-bom.h"
\ No newline at end of file
diff --git a/test/Frontend/rewrite-includes-messages.c b/test/Frontend/rewrite-includes-messages.c
new file mode 100644
index 0000000..f93fe72
--- /dev/null
+++ b/test/Frontend/rewrite-includes-messages.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -E -frewrite-includes %s -I%S/Inputs/ | %clang_cc1 -Wall -fsyntax-only -Wunused-macros -x c - 2>&1 > %t.1
+// RUN: %clang_cc1 -I%S/Inputs/ -Wall -Wunused-macros -fsyntax-only %s 2>&1 > %t.2
+// RUN: diff %t.1 %t.2 -u
+// expected-no-diagnostics
+
+#include "rewrite-includes-messages.h"
+#define UNUSED_MACRO
diff --git a/test/Frontend/rewrite-includes-missing.c b/test/Frontend/rewrite-includes-missing.c
index da4e209..25a59a0 100644
--- a/test/Frontend/rewrite-includes-missing.c
+++ b/test/Frontend/rewrite-includes-missing.c
@@ -4,4 +4,5 @@
 // CHECK: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}}
 // CHECK-NEXT: {{^}}#include "foobar.h"
 // CHECK-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}# 3 "{{.*}}rewrite-includes-missing.c"{{$}}
 // CHECK-NEXT: {{^}}# 4 "{{.*}}rewrite-includes-missing.c"{{$}}
diff --git a/test/Frontend/rewrite-includes-modules.c b/test/Frontend/rewrite-includes-modules.c
index 783a967..58d7809 100644
--- a/test/Frontend/rewrite-includes-modules.c
+++ b/test/Frontend/rewrite-includes-modules.c
@@ -10,11 +10,13 @@
 // CHECK-NEXT: #if 0 /* expanded by -frewrite-includes */{{$}}
 // CHECK-NEXT: #include <Module/Module.h>{{$}}
 // CHECK-NEXT: #endif /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: # 5 "{{.*[/\\]}}rewrite-includes-modules.c"{{$}}
 // CHECK-NEXT: @import Module; /* clang -frewrite-includes: implicit import */{{$}}
 // CHECK-NEXT: # 6 "{{.*[/\\]}}rewrite-includes-modules.c"{{$}}
 // CHECK-NEXT: int foo();{{$}}
 // CHECK-NEXT: #if 0 /* expanded by -frewrite-includes */{{$}}
 // CHECK-NEXT: #include <Module/Module.h>{{$}}
 // CHECK-NEXT: #endif /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: # 7 "{{.*[/\\]}}rewrite-includes-modules.c"{{$}}
 // CHECK-NEXT: @import Module; /* clang -frewrite-includes: implicit import */{{$}}
 // CHECK-NEXT: # 8 "{{.*[/\\]}}rewrite-includes-modules.c"{{$}}
diff --git a/test/Frontend/rewrite-includes.c b/test/Frontend/rewrite-includes.c
index 2158dd0..bed87ef 100644
--- a/test/Frontend/rewrite-includes.c
+++ b/test/Frontend/rewrite-includes.c
@@ -21,12 +21,14 @@
 #include "rewrite-includes7.h"
 #include "rewrite-includes8.h"
 // ENDCOMPARE
+// CHECK: {{^}}# 1 "{{.*}}rewrite-includes.c"{{$}}
 // CHECK: {{^}}// STARTCOMPARE{{$}}
 // CHECK-NEXT: {{^}}#define A(a,b) a ## b{{$}}
 // CHECK-NEXT: {{^}}A(1,2){{$}}
 // CHECK-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}}
 // CHECK-NEXT: {{^}}#include "rewrite-includes1.h"{{$}}
 // CHECK-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}# 6 "{{.*}}rewrite-includes.c"{{$}}
 // CHECK-NEXT: {{^}}# 1 "{{.*[/\\]Inputs(/|\\\\)}}rewrite-includes1.h" 1{{$}}
 // CHECK-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}}
 // CHECK-NEXT: {{^}}#pragma clang system_header{{$}}
@@ -36,6 +38,7 @@
 // CHECK-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}}
 // CHECK-NEXT: {{^}}#include "rewrite-includes2.h"{{$}}
 // CHECK-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}# 3 "{{.*[/\\]Inputs(/|\\\\)}}rewrite-includes1.h" 3{{$}}
 // CHECK-NEXT: {{^}}# 1 "{{.*[/\\]Inputs(/|\\\\)}}rewrite-includes2.h" 1 3{{$}}
 // CHECK-NEXT: {{^}}included_line2{{$}}
 // CHECK-NEXT: {{^}}# 4 "{{.*[/\\]Inputs(/|\\\\)}}rewrite-includes1.h" 2 3{{$}}
@@ -45,6 +48,7 @@
 // CHECK-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}}
 // CHECK-NEXT: {{^}}#include HEADER{{$}}
 // CHECK-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}# 9 "{{.*}}rewrite-includes.c"{{$}}
 // CHECK-NEXT: {{^}}# 1 "{{.*[/\\]Inputs(/|\\\\)}}rewrite-includes3.h" 1{{$}}
 // CHECK-NEXT: {{^}}included_line3{{$}}
 // CHECK-NEXT: {{^}}# 10 "{{.*}}rewrite-includes.c" 2{{$}}
@@ -53,6 +57,7 @@
 // CHECK-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}}
 // CHECK-NEXT: {{^}}#include "rewrite-includes4.h"{{$}}
 // CHECK-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}# 11 "{{.*}}rewrite-includes.c"{{$}}
 // CHECK-NEXT: {{^}}# 12 "{{.*}}rewrite-includes.c"{{$}}
 // CHECK-NEXT: {{^}}#endif{{$}}
 // CHECK-NEXT: {{^}}# 13 "{{.*}}rewrite-includes.c"{{$}}
@@ -61,12 +66,14 @@
 // CHECK-NEXT: {{^}}#/**/include /**/ "rewrite-includes5.h" /**/ {{\\}}{{$}}
 // CHECK-NEXT: {{^}} {{$}}
 // CHECK-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}# 15 "{{.*}}rewrite-includes.c"{{$}}
 // CHECK-NEXT: {{^}}# 1 "{{.*[/\\]Inputs(/|\\\\)}}rewrite-includes5.h" 1{{$}}
 // CHECK-NEXT: {{^}}included_line5{{$}}
 // CHECK-NEXT: {{^}}# 16 "{{.*}}rewrite-includes.c" 2{{$}}
 // CHECK-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}}
 // CHECK-NEXT: {{^}}#include "rewrite-includes6.h" // comment{{$}}
 // CHECK-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}# 16 "{{.*}}rewrite-includes.c"{{$}}
 // CHECK-NEXT: {{^}}# 1 "{{.*[/\\]Inputs(/|\\\\)}}rewrite-includes6.h" 1{{$}}
 // CHECK-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}}
 // CHECK-NEXT: {{^}}#pragma once{{$}}
@@ -79,10 +86,12 @@
 // CHECK-NEXT: {{^}}#include "rewrite-includes6.h" /* comment{{$}}
 // CHECK-NEXT: {{^}}                                  continues */{{$}}
 // CHECK-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}# 19 "{{.*}}rewrite-includes.c"{{$}}
 // CHECK-NEXT: {{^}}# 20 "{{.*}}rewrite-includes.c"{{$}}
 // CHECK-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}}
 // CHECK-NEXT: {{^}}#include "rewrite-includes7.h"{{$}}
 // CHECK-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}# 20 "{{.*}}rewrite-includes.c"{{$}}
 // CHECK-NEXT: {{^}}# 1 "{{.*[/\\]Inputs(/|\\\\)}}rewrite-includes7.h" 1{{$}}
 // CHECK-NEXT: {{^}}#ifndef REWRITE_INCLUDES_7{{$}}
 // CHECK-NEXT: {{^}}#define REWRITE_INCLUDES_7{{$}}
@@ -93,10 +102,12 @@
 // CHECK-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}}
 // CHECK-NEXT: {{^}}#include "rewrite-includes7.h"{{$}}
 // CHECK-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}# 21 "{{.*}}rewrite-includes.c"{{$}}
 // CHECK-NEXT: {{^}}# 22 "{{.*}}rewrite-includes.c"{{$}}
 // CHECK-NEXT: {{^}}#if 0 /* expanded by -frewrite-includes */{{$}}
 // CHECK-NEXT: {{^}}#include "rewrite-includes8.h"{{$}}
 // CHECK-NEXT: {{^}}#endif /* expanded by -frewrite-includes */{{$}}
+// CHECK-NEXT: {{^}}# 22 "{{.*}}rewrite-includes.c"{{$}}
 // CHECK-NEXT: {{^}}# 1 "{{.*[/\\]Inputs(/|\\\\)}}rewrite-includes8.h" 1{{$}}
 // CHECK-NEXT: {{^}}#if (1)/*__has_include_next(<rewrite-includes8.h>)*/{{$}}
 // CHECK-NEXT: {{^}}#elif (0)/*__has_include(<rewrite-includes8.hfail>)*/{{$}}
diff --git a/test/Frontend/rewrite-macros.c b/test/Frontend/rewrite-macros.c
index eab6657..759afb0 100644
--- a/test/Frontend/rewrite-macros.c
+++ b/test/Frontend/rewrite-macros.c
@@ -17,5 +17,3 @@
 
 // CHECK: {{^}}//#pragma mark mark{{$}}
 #pragma mark mark
-
-
diff --git a/test/Frontend/stdlang.c b/test/Frontend/stdlang.c
new file mode 100644
index 0000000..71997f1
--- /dev/null
+++ b/test/Frontend/stdlang.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -x cuda -std=c++11 -DCUDA %s
+// RUN: %clang_cc1 -x cl -std=c99 -DOPENCL %s
+// expected-no-diagnostics
+
+#if defined(CUDA)
+  __attribute__((device)) void f_device();
+#elif defined(OPENCL)
+  kernel void func(void);
+#endif
diff --git a/test/Frontend/system-header-prefix.c b/test/Frontend/system-header-prefix.c
index 31194d9..55b954f 100644
--- a/test/Frontend/system-header-prefix.c
+++ b/test/Frontend/system-header-prefix.c
@@ -1,11 +1,12 @@
-// RUN: %clang_cc1 -isystem-prefix libs/ -ino-system-prefix libs/mylib/ -I%S/Inputs/SystemHeaderPrefix -Wundef -E %s 2>&1 | FileCheck %s
+// RUN: %clang --system-header-prefix=libs/ --no-system-header-prefix=libs/mylib/ -I%S/Inputs/SystemHeaderPrefix -Wundef -E %s 2>&1 | FileCheck %s
+// RUN: %clang --system-header-prefix libs/ --no-system-header-prefix libs/mylib/ -I%S/Inputs/SystemHeaderPrefix -Wundef -E %s 2>&1 | FileCheck %s
 
 #include "src/all.h"
 
 // CHECK-NOT: BOOST
-// CHECK: libs/mylib/warn.h:1:5: warning: 'MYLIB' is not defined, evaluates to 0
+// CHECK: libs{{/|\\}}mylib{{/|\\}}warn.h:1:5: warning: 'MYLIB' is not defined, evaluates to 0
 // CHECK-NOT: BOOST
-// CHECK: libs/mylib/warn.h:1:5: warning: 'MYLIB' is not defined, evaluates to 0
+// CHECK: libs{{/|\\}}mylib{{/|\\}}warn.h:1:5: warning: 'MYLIB' is not defined, evaluates to 0
 // CHECK-NOT: BOOST
-// CHECK: src/warn.h:1:5: warning: 'SRC' is not defined, evaluates to 0
+// CHECK: src{{/|\\}}warn.h:1:5: warning: 'SRC' is not defined, evaluates to 0
 // CHECK-NOT: BOOST
diff --git a/test/Frontend/verify.c b/test/Frontend/verify.c
index 4bd0c90..e2e7894 100644
--- a/test/Frontend/verify.c
+++ b/test/Frontend/verify.c
@@ -134,9 +134,18 @@
 // expected-warning@verify-directive.h: {{ }}
 // expected-error@-1 {{missing or invalid line number}}
 
+// expected-warning@verify-directive.h:0 {{ }}
+// expected-error@-1 {{missing or invalid line number}}
+
+// expected-warning@verify-directive.h:0*{{ }}
+// expected-error@-1 {{missing or invalid line number}}
+
+// expected-warning@verify-directive.h:*0{{ }}
+// syntactically ok -- means match in any line for 0 occurrences.
+
 // expected-warning@verify-directive.h:1 {{diagnostic}}
 
 //      CHECK8: error: 'warning' diagnostics expected but not seen:
-// CHECK8-NEXT:   File {{.*}}verify-directive.h Line 1 (directive at {{.*}}verify.c:137): diagnostic
+// CHECK8-NEXT:   File {{.*}}verify-directive.h Line 1 (directive at {{.*}}verify.c:146): diagnostic
 // CHECK8-NEXT: 1 error generated.
 #endif
diff --git a/test/Frontend/verify2.c b/test/Frontend/verify2.c
index 73eda4d..075a2ab 100644
--- a/test/Frontend/verify2.c
+++ b/test/Frontend/verify2.c
@@ -14,7 +14,26 @@
 
 //      CHECK: error: no expected directives found: consider use of 'expected-no-diagnostics'
 // CHECK-NEXT: error: 'error' diagnostics seen but not expected:
-// CHECK-NEXT:   Line 1: header
+// CHECK-NEXT:   Line 5: header
 // CHECK-NEXT:   Line 10: source
 // CHECK-NEXT: 3 errors generated.
 #endif
+
+#ifdef CHECK2
+// RUN: not %clang_cc1 -DCHECK2 -verify %s 2>&1 | FileCheck -check-prefix=CHECK2 %s
+
+// The following checks that -verify can match "any line" in an included file.
+// The location of the diagnostic need therefore only match in the file, not to
+// a specific line number.  This is useful where -verify is used as a testing
+// tool for 3rd-party libraries where headers may change and the specific line
+// number of a diagnostic in a header is not important.
+
+// expected-error@verify2.h:* {{header}}
+// expected-error@verify2.h:* {{unknown}}
+
+//      CHECK2: error: 'error' diagnostics expected but not seen:
+// CHECK2-NEXT:   File {{.*}}verify2.h Line * (directive at {{.*}}verify2.c:32): unknown
+// CHECK2-NEXT: error: 'error' diagnostics seen but not expected:
+// CHECK2-NEXT:   File {{.*}}verify2.c Line 10: source
+// CHECK2-NEXT: 2 errors generated.
+#endif
diff --git a/test/Frontend/verify2.h b/test/Frontend/verify2.h
index 8acbf6e..a426722 100644
--- a/test/Frontend/verify2.h
+++ b/test/Frontend/verify2.h
@@ -1,5 +1,5 @@
-#error header
-
 #if 0
 // expected-error {{should be ignored}}
 #endif
+
+#error header
diff --git a/test/Frontend/warning-options.cpp b/test/Frontend/warning-options.cpp
index 85bea62..3c3396b 100644
--- a/test/Frontend/warning-options.cpp
+++ b/test/Frontend/warning-options.cpp
@@ -1,5 +1,7 @@
 // RUN: %clang_cc1 -Wmonkey -Wno-monkey -Wno-unused-command-line-arguments \
-// RUN:        -Wno-unused-command-line-argument %s 2>&1 | FileCheck %s
+// RUN:        -Wno-unused-command-line-argument -Wmodule-build -Rmodule-built %s 2>&1 | FileCheck %s
 // CHECK: unknown warning option '-Wmonkey'
 // CHECK: unknown warning option '-Wno-monkey'
 // CHECK: unknown warning option '-Wno-unused-command-line-arguments'; did you mean '-Wno-unused-command-line-argument'?
+// CHECK: unknown warning option '-Wmodule-build'; did you mean '-Wmodule-conflict'?
+// CHECK: unknown remark option '-Rmodule-built'; did you mean '-Rmodule-build'?
diff --git a/test/Frontend/windows-nul.c b/test/Frontend/windows-nul.c
new file mode 100644
index 0000000..9f1fc04
--- /dev/null
+++ b/test/Frontend/windows-nul.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 nul
+
+// REQUIRES: system-windows
+
+// Verify that cc1 doesn't crash with an assertion failure
+// in MemoryBuffer.cpp due to an invalid file size reported
+// when the Windows 'nul' device is passed in input.
+
diff --git a/test/Headers/Inputs/include/setjmp.h b/test/Headers/Inputs/include/setjmp.h
new file mode 100644
index 0000000..3d5e903
--- /dev/null
+++ b/test/Headers/Inputs/include/setjmp.h
@@ -0,0 +1,8 @@
+#ifndef SETJMP_H
+#define SETJMP_H
+
+typedef struct {
+  int x[42];
+} jmp_buf;
+
+#endif
diff --git a/test/Headers/altivec-header.c b/test/Headers/altivec-header.c
index b01cc97..3d85957 100644
--- a/test/Headers/altivec-header.c
+++ b/test/Headers/altivec-header.c
@@ -1,4 +1,4 @@
-// REQUIRES: ppc64-registered-target
+// REQUIRES: powerpc-registered-target
 // RUN: %clang_cc1 -triple powerpc64-unknown-unknown -faltivec -ffreestanding -S -o - %s | FileCheck %s
 // RUN: %clang_cc1 -triple powerpc64-unknown-unknown -faltivec -ffreestanding -fno-lax-vector-conversions -S -o - %s | FileCheck %s
 // RUN: %clang_cc1 -triple powerpc64-unknown-unknown -faltivec -ffreestanding -x c++ -S -o - %s | FileCheck %s
@@ -8,5 +8,8 @@
 // Verify that simply including <altivec.h> does not generate any code
 // (i.e. all inline routines in the header are marked "static")
 
-// CHECK-NOT: .text
-
+// CHECK: .text
+// CHECK-NEXT: .file
+// CHECK-NEXT: {{^$}}
+// CHECK-NEXT: .ident{{.*$}}
+// CHECK-NOT: .
diff --git a/test/Headers/arm-acle-header.c b/test/Headers/arm-acle-header.c
new file mode 100644
index 0000000..d9d2e04
--- /dev/null
+++ b/test/Headers/arm-acle-header.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple armv7-eabi -target-cpu cortex-a15 -fsyntax-only -ffreestanding %s
+// RUN: %clang_cc1 -triple aarch64-eabi -target-cpu cortex-a53 -fsyntax-only -ffreestanding %s
+// RUN: %clang_cc1 -triple thumbv7-windows -target-cpu cortex-a53 -fsyntax-only -ffreestanding %s
+// RUN: %clang_cc1 -x c++ -triple armv7-eabi -target-cpu cortex-a15 -fsyntax-only -ffreestanding %s
+// RUN: %clang_cc1 -x c++ -triple aarch64-eabi -target-cpu cortex-a57 -fsyntax-only -ffreestanding %s
+// RUN: %clang_cc1 -x c++ -triple thumbv7-windows -target-cpu cortex-a15 -fsyntax-only -ffreestanding %s
+// expected-no-diagnostics
+
+#include <arm_acle.h>
diff --git a/test/Headers/c11.c b/test/Headers/c11.c
index 11bec19..b7b1501 100644
--- a/test/Headers/c11.c
+++ b/test/Headers/c11.c
@@ -1,6 +1,8 @@
+// RUN: rm -rf %t
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c11 %s
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c11 -fmodules %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c11 -fmodules -fmodules-cache-path=%t %s
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c11 -ffreestanding %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c11 -triple i686-pc-win32 -fms-compatibility-version=17.00 %s
 
 noreturn int f(); // expected-error 1+{{}}
 
@@ -22,6 +24,14 @@
 #define __STDC_WANT_LIB_EXT1__ 1
 #include <stddef.h>
 rsize_t x = 0;
+_Static_assert(sizeof(max_align_t) >= sizeof(long long), "");
+_Static_assert(alignof(max_align_t) >= alignof(long long), "");
+_Static_assert(sizeof(max_align_t) >= sizeof(long double), "");
+_Static_assert(alignof(max_align_t) >= alignof(long double), "");
+
+#ifdef _MSC_VER
+_Static_assert(sizeof(max_align_t) == sizeof(double), "");
+#endif
 
 // If we are freestanding, then also check RSIZE_MAX (in a hosted implementation
 // we will use the host stdint.h, which may not yet have C11 support).
diff --git a/test/Headers/cxx11.cpp b/test/Headers/cxx11.cpp
index 1a4b640..5b0ec0b 100644
--- a/test/Headers/cxx11.cpp
+++ b/test/Headers/cxx11.cpp
@@ -1,6 +1,8 @@
 // RUN: %clang_cc1 -ffreestanding -fsyntax-only -std=c++11 %s
 // RUN: %clang_cc1 -ffreestanding -fsyntax-only -std=c++11 -fmodules %s
 
+// This test fails on systems with older OS X 10.9 SDK headers, see PR18322.
+
 #include <stdalign.h>
 
 #if defined alignas
diff --git a/test/Headers/ms-intrin.cpp b/test/Headers/ms-intrin.cpp
index 1bf134e..68f436c 100644
--- a/test/Headers/ms-intrin.cpp
+++ b/test/Headers/ms-intrin.cpp
@@ -1,6 +1,17 @@
 // RUN: %clang_cc1 -triple i386-pc-win32 -target-cpu pentium4 \
-// RUN:     -fms-extensions -fms-compatibility -fmsc-version=1700 \
-// RUN:     -ffreestanding -verify %s
+// RUN:     -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 \
+// RUN:     -ffreestanding -fsyntax-only -Werror \
+// RUN:     -isystem %S/Inputs/include %s
+
+// RUN: %clang_cc1 -triple x86_64-pc-win32  \
+// RUN:     -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 \
+// RUN:     -ffreestanding -fsyntax-only -Werror \
+// RUN:     -isystem %S/Inputs/include %s
+
+// RUN: %clang_cc1 -triple thumbv7--windows \
+// RUN:     -fms-compatibility -fms-compatibility-version=17.00 \
+// RUN:     -ffreestanding -fsyntax-only -Werror \
+// RUN:     -isystem %S/Inputs/include %s
 
 // Intrin.h needs size_t, but -ffreestanding prevents us from getting it from
 // stddef.h.  Work around it with this typedef.
@@ -11,14 +22,3 @@
 // Use some C++ to make sure we closed the extern "C" brackets.
 template <typename T>
 void foo(T V) {}
-
-void bar() {
-  _ReadWriteBarrier();  // expected-warning {{is deprecated: use other intrinsics or C++11 atomics instead}}
-  _ReadBarrier();       // expected-warning {{is deprecated: use other intrinsics or C++11 atomics instead}}
-  _WriteBarrier();      // expected-warning {{is deprecated: use other intrinsics or C++11 atomics instead}}
-  // FIXME: It'd be handy if we didn't have to hardcode the line number in
-  // intrin.h.
-  // expected-note@Intrin.h:754 {{declared here}}
-  // expected-note@Intrin.h:759 {{declared here}}
-  // expected-note@Intrin.h:764 {{declared here}}
-}
diff --git a/test/Headers/ms-null-ms-header-vs-stddef.cpp b/test/Headers/ms-null-ms-header-vs-stddef.cpp
index 237ed51..e391089 100644
--- a/test/Headers/ms-null-ms-header-vs-stddef.cpp
+++ b/test/Headers/ms-null-ms-header-vs-stddef.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -triple i686-pc-win32 -fms-compatibility -fmsc-version=1700 %s
+// RUN: %clang_cc1 -fsyntax-only -triple i686-pc-win32 -fms-compatibility -fms-compatibility-version=17.00 %s
 // RUN: %clang_cc1 -fsyntax-only -triple i386-mingw32 %s
 
 // Something in MSVC's headers (pulled in e.g. by <crtdefs.h>) defines __null
diff --git a/test/Headers/stddefneeds.cpp b/test/Headers/stddefneeds.cpp
new file mode 100644
index 0000000..0763bbd
--- /dev/null
+++ b/test/Headers/stddefneeds.cpp
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-macosx10.9.0 -verify -Wsentinel -std=c++11 %s
+
+ptrdiff_t p0; // expected-error{{unknown}}
+size_t s0; // expected-error{{unknown}}
+void* v0 = NULL; // expected-error{{undeclared}}
+wint_t w0; // expected-error{{unknown}}
+max_align_t m0; // expected-error{{unknown}}
+
+#define __need_ptrdiff_t
+#include <stddef.h>
+
+ptrdiff_t p1;
+size_t s1; // expected-error{{unknown}}
+void* v1 = NULL; // expected-error{{undeclared}}
+wint_t w1; // expected-error{{unknown}}
+max_align_t m1; // expected-error{{unknown}}
+
+#define __need_size_t
+#include <stddef.h>
+
+ptrdiff_t p2;
+size_t s2;
+void* v2 = NULL; // expected-error{{undeclared}}
+wint_t w2; // expected-error{{unknown}}
+max_align_t m2; // expected-error{{unknown}}
+
+#define __need_NULL
+#include <stddef.h>
+
+ptrdiff_t p3;
+size_t s3;
+void* v3 = NULL;
+wint_t w3; // expected-error{{unknown}}
+max_align_t m3; // expected-error{{unknown}}
+
+// Shouldn't bring in wint_t by default:
+#include <stddef.h>
+
+ptrdiff_t p4;
+size_t s4;
+void* v4 = NULL;
+wint_t w4; // expected-error{{unknown}}
+max_align_t m4;
+
+#define __need_wint_t
+#include <stddef.h>
+
+ptrdiff_t p5;
+size_t s5;
+void* v5 = NULL;
+wint_t w5;
+max_align_t m5;
+
+
+// linux/stddef.h does something like this for cpp files:
+#undef NULL
+#define NULL 0
+
+// glibc (and other) headers then define __need_NULL and rely on stddef.h
+// to redefine NULL to the correct value again.
+#define __need_NULL
+#include <stddef.h>
+
+// gtk headers then use __attribute__((sentinel)), which doesn't work if NULL
+// is 0.
+void f(const char* c, ...) __attribute__((sentinel));
+void g() {
+  f("", NULL);  // Shouldn't warn.
+}
diff --git a/test/Headers/xmmintrin.c b/test/Headers/xmmintrin.c
new file mode 100644
index 0000000..c426f34
--- /dev/null
+++ b/test/Headers/xmmintrin.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 %s -ffreestanding -triple x86_64-apple-macosx10.9.0 -emit-llvm -o - | FileCheck %s
+
+#include <xmmintrin.h>
+
+// Make sure the last step of _mm_cvtps_pi16 converts <4 x i32> to <4 x i16> by
+// checking that clang emits PACKSSDW instead of PACKSSWB.
+
+// CHECK: define i64 @test_mm_cvtps_pi16
+// CHECK: call x86_mmx @llvm.x86.mmx.packssdw
+
+__m64 test_mm_cvtps_pi16(__m128 a) {
+  return _mm_cvtps_pi16(a);
+}
diff --git a/test/Index/Inputs/CommentXML/valid-function-02.xml b/test/Index/Inputs/CommentXML/valid-function-02.xml
index 989d6a7..6a8c242 100644
--- a/test/Index/Inputs/CommentXML/valid-function-02.xml
+++ b/test/Index/Inputs/CommentXML/valid-function-02.xml
@@ -1,5 +1,14 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Function>
 <Name>aaa</Name>
-<Abstract><Para>Aaa <bold>bbb</bold> <monospaced>ccc</monospaced> <emphasized>ddd</emphasized>.</Para></Abstract>
+<Abstract>
+  <Para>Aaa
+    <bold>bbb</bold>
+    <monospaced>ccc</monospaced>
+    <emphasized>ddd</emphasized>
+    <rawHTML>&lt;eee&gt;</rawHTML>
+    <rawHTML isMalformed="0">&lt;fff&gt;</rawHTML>
+    <rawHTML isMalformed="1">&lt;ggg&gt;</rawHTML>.
+  </Para>
+</Abstract>
 </Function>
diff --git a/test/Index/Inputs/Frameworks/DocCommentsA.framework/Headers/DocCommentsA.h b/test/Index/Inputs/Frameworks/DocCommentsA.framework/Headers/DocCommentsA.h
new file mode 100644
index 0000000..d548f81
--- /dev/null
+++ b/test/Index/Inputs/Frameworks/DocCommentsA.framework/Headers/DocCommentsA.h
@@ -0,0 +1,8 @@
+/// Comment for 'functionFromDocCommentsA1'.
+void functionFromDocCommentsA1(void);
+
+#import <DocCommentsC/DocCommentsC.h>
+
+/// Comment for 'functionFromDocCommentsA2'.
+void functionFromDocCommentsA2(void);
+
diff --git a/test/Index/Inputs/Frameworks/DocCommentsB.framework/Headers/DocCommentsB.h b/test/Index/Inputs/Frameworks/DocCommentsB.framework/Headers/DocCommentsB.h
new file mode 100644
index 0000000..af279e3
--- /dev/null
+++ b/test/Index/Inputs/Frameworks/DocCommentsB.framework/Headers/DocCommentsB.h
@@ -0,0 +1,7 @@
+/// Comment for 'functionFromDocCommentsB1'.
+void functionFromDocCommentsB1(void);
+
+#import <DocCommentsC/DocCommentsC.h>
+
+/// Comment for 'functionFromDocCommentsB2'.
+void functionFromDocCommentsB2(void);
diff --git a/test/Index/Inputs/Frameworks/DocCommentsC.framework/Headers/DocCommentsC.h b/test/Index/Inputs/Frameworks/DocCommentsC.framework/Headers/DocCommentsC.h
new file mode 100644
index 0000000..db696a3
--- /dev/null
+++ b/test/Index/Inputs/Frameworks/DocCommentsC.framework/Headers/DocCommentsC.h
@@ -0,0 +1,2 @@
+/// Comment for 'functionFromDocCommentsC'.
+void functionFromDocCommentsC(void);
diff --git a/test/Index/Inputs/base_module_needs_vfs.h b/test/Index/Inputs/base_module_needs_vfs.h
new file mode 100644
index 0000000..9a7a244
--- /dev/null
+++ b/test/Index/Inputs/base_module_needs_vfs.h
@@ -0,0 +1 @@
+void base_module_needs_vfs(void);
diff --git a/test/Index/Inputs/crash-recovery-code-complete-remap.c b/test/Index/Inputs/crash-recovery-code-complete-remap.c
index 50a8658..0cc2e89 100644
--- a/test/Index/Inputs/crash-recovery-code-complete-remap.c
+++ b/test/Index/Inputs/crash-recovery-code-complete-remap.c
@@ -1,11 +1,9 @@
 // RUN: echo env CINDEXTEST_EDITING=1 \
 // RUN:   not c-index-test -test-load-source-reparse 1 local \
-// RUN:   -remap-file="%s;%S/Inputs/crash-recovery-code-complete-remap.c" \
+// RUN:   -remap-file="%s,%S/Inputs/crash-recovery-code-complete-remap.c" \
 // RUN:   %s 2> %t.err
 // RUN: FileCheck < %t.err -check-prefix=CHECK-CODE-COMPLETE-CRASH %s
 // CHECK-CODE-COMPLETE-CRASH: Unable to reparse translation unit
-//
-// XFAIL: win32
 
 #warning parsing original file
 
diff --git a/test/Index/Inputs/module.map b/test/Index/Inputs/module.map
new file mode 100644
index 0000000..8f24840
--- /dev/null
+++ b/test/Index/Inputs/module.map
@@ -0,0 +1,6 @@
+// See vfsoverlay.yaml
+module ModuleNeedsVFS {
+  header "ModuleNeedsVFS.h"
+  export *
+}
+framework module * { }
diff --git a/test/Index/Inputs/module_needs_vfs.h b/test/Index/Inputs/module_needs_vfs.h
new file mode 100644
index 0000000..d79cc3f
--- /dev/null
+++ b/test/Index/Inputs/module_needs_vfs.h
@@ -0,0 +1,4 @@
+@import BaseModuleNeedsVFS;
+inline void module_needs_vfs(void) {
+  base_module_needs_vfs();
+}
diff --git a/test/Index/Inputs/retain-comments-from-system-headers-module.map b/test/Index/Inputs/retain-comments-from-system-headers-module.map
new file mode 100644
index 0000000..0b77f3c
--- /dev/null
+++ b/test/Index/Inputs/retain-comments-from-system-headers-module.map
@@ -0,0 +1,4 @@
+module retain_comments_from_system_headers {
+  header "retain-comments-from-system-headers.h"
+  export *
+}
diff --git a/test/Index/Inputs/usrs-system.h b/test/Index/Inputs/usrs-system.h
new file mode 100644
index 0000000..dee4d83
--- /dev/null
+++ b/test/Index/Inputs/usrs-system.h
@@ -0,0 +1 @@
+#define MACRO_FROM_SYSTEM_HEADER_1 meow
diff --git a/test/Index/Inputs/vfsoverlay.yaml b/test/Index/Inputs/vfsoverlay.yaml
new file mode 100644
index 0000000..95b00be
--- /dev/null
+++ b/test/Index/Inputs/vfsoverlay.yaml
@@ -0,0 +1,18 @@
+{
+  'version': 0,
+  'roots': [
+    { 'name': 'OUT_DIR', 'type': 'directory',
+      'contents': [
+        { 'name': 'module.map', 'type': 'file',
+          'external-contents': 'INPUT_DIR/module.map'
+        },
+        { 'name': 'ModuleNeedsVFS.h', 'type': 'file',
+          'external-contents': 'INPUT_DIR/module_needs_vfs.h'
+        },
+        { 'name': 'BaseModuleNeedsVFS.framework/Headers/BaseModuleNeedsVFS.h', 'type': 'file',
+          'external-contents': 'INPUT_DIR/base_module_needs_vfs.h'
+        },
+      ]
+    }
+  ]
+}
diff --git a/test/Index/annotate-comments-objc.m b/test/Index/annotate-comments-objc.m
index e778d6c..a8eaa0b 100644
--- a/test/Index/annotate-comments-objc.m
+++ b/test/Index/annotate-comments-objc.m
@@ -3,6 +3,12 @@
 #ifndef HEADER
 #define HEADER
 
+/// Comment for 'functionBeforeImports'.
+void functionBeforeImports(void);
+
+#import <DocCommentsA/DocCommentsA.h>
+#import <DocCommentsB/DocCommentsB.h>
+
 @class NSString;
 
 //===---
@@ -21,25 +27,54 @@
 
 /// method1_isdoxy1 IS_DOXYGEN_SINGLE
 - (void)method1_isdoxy1;
-- (void)method1_isdoxy2; /*!< method1_isdoxy2 IS_DOXYGEN_SINGLE */
-- (void)method1_isdoxy3; /*!< method1_isdoxy3 IS_DOXYGEN_SINGLE */
+- (void)method1_isdoxy2; ///< method1_isdoxy2 IS_DOXYGEN_SINGLE
+- (void)method1_isdoxy3; /**< method1_isdoxy3 IS_DOXYGEN_SINGLE */
 - (void)method1_isdoxy4; /*!< method1_isdoxy4 IS_DOXYGEN_SINGLE */
 @end
 
+//===---
+// rdar://14348912
+// Check that we attach comments to enums declared using the NS_ENUM macro.
+//===---
+
+#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
+
+/// An_NS_ENUM_isdoxy1 IS_DOXYGEN_SINGLE
+typedef NS_ENUM(int, An_NS_ENUM_isdoxy1) { Red, Green, Blue };
+
+// In the implementation of attaching comments to enums declared using the
+// NS_ENUM macro, it is tempting to use the fact that enum decl is embedded in
+// the typedef.  Make sure that the heuristic is strong enough that it does not
+// attach unrelated comments in the following cases where tag decls are
+// embedded in declarators.
+
+#define DECLARE_FUNCTION() \
+    void functionFromMacro() { \
+      typedef struct Struct_notdoxy Struct_notdoxy; \
+    }
+
+/// IS_DOXYGEN_NOT_ATTACHED
+DECLARE_FUNCTION()
+
+/// typedef_isdoxy1 IS_DOXYGEN_SINGLE
+typedef struct Struct_notdoxy *typedef_isdoxy1;
 
 #endif
 
 // RUN: rm -rf %t
 // RUN: mkdir %t
+// RUN: mkdir %t/module-cache
 
 // Check that we serialize comment source locations properly.
-// RUN: %clang_cc1 -emit-pch -o %t/out.pch %s
-// RUN: %clang_cc1 -include-pch %t/out.pch -fsyntax-only %s
+// RUN: %clang_cc1 -emit-pch -o %t/out.pch -F %S/Inputs/Frameworks %s
+// RUN: %clang_cc1 -include-pch %t/out.pch -F %S/Inputs/Frameworks -fsyntax-only %s
 
-// RUN: c-index-test -test-load-source all -comments-xml-schema=%S/../../bindings/xml/comment-xml-schema.rng %s > %t/out.c-index-direct
-// RUN: c-index-test -test-load-tu %t/out.pch all > %t/out.c-index-pch
+// RUN: c-index-test -test-load-source all -comments-xml-schema=%S/../../bindings/xml/comment-xml-schema.rng %s -F %S/Inputs/Frameworks > %t/out.c-index-direct
+// RUN: c-index-test -test-load-source all -comments-xml-schema=%S/../../bindings/xml/comment-xml-schema.rng %s -F %S/Inputs/Frameworks -fmodules -fmodules-cache-path=%t/module-cache > %t/out.c-index-modules
+// RUN: c-index-test -test-load-tu %t/out.pch all -F %S/Inputs/Frameworks > %t/out.c-index-pch
 
 // RUN: FileCheck %s -check-prefix=WRONG < %t/out.c-index-direct
+// RUN: FileCheck %s -check-prefix=WRONG < %t/out.c-index-modules
 // RUN: FileCheck %s -check-prefix=WRONG < %t/out.c-index-pch
 
 // Declarations without Doxygen comments should not pick up some Doxygen comments.
@@ -60,6 +95,7 @@
 // WRONG-NOT: CommentXMLInvalid
 
 // RUN: FileCheck %s < %t/out.c-index-direct
+// RUN: FileCheck %s < %t/out.c-index-modules
 // RUN: FileCheck %s < %t/out.c-index-pch
 
 // These CHECK lines are not located near the code on purpose.  This test
@@ -67,12 +103,22 @@
 // Adding a non-documentation comment with CHECK line between every two
 // documentation comments will only test a single code path.
 //
-// CHECK: annotate-comments-objc.m:17:50: ObjCPropertyDecl=property1_isdoxy1:{{.*}} property1_isdoxy1 IS_DOXYGEN_SINGLE
-// CHECK: annotate-comments-objc.m:18:50: ObjCPropertyDecl=property1_isdoxy2:{{.*}} property1_isdoxy2 IS_DOXYGEN_SINGLE
-// CHECK: annotate-comments-objc.m:19:50: ObjCPropertyDecl=property1_isdoxy3:{{.*}} property1_isdoxy3 IS_DOXYGEN_SINGLE
-// CHECK: annotate-comments-objc.m:20:50: ObjCPropertyDecl=property1_isdoxy4:{{.*}} property1_isdoxy4 IS_DOXYGEN_SINGLE
-// CHECK: annotate-comments-objc.m:23:9: ObjCInstanceMethodDecl=method1_isdoxy1:{{.*}} method1_isdoxy1 IS_DOXYGEN_SINGLE
-// CHECK: annotate-comments-objc.m:24:9: ObjCInstanceMethodDecl=method1_isdoxy2:{{.*}} method1_isdoxy2 IS_DOXYGEN_SINGLE
-// CHECK: annotate-comments-objc.m:25:9: ObjCInstanceMethodDecl=method1_isdoxy3:{{.*}} method1_isdoxy3 IS_DOXYGEN_SINGLE
-// CHECK: annotate-comments-objc.m:26:9: ObjCInstanceMethodDecl=method1_isdoxy4:{{.*}} method1_isdoxy4 IS_DOXYGEN_SINGLE
+// CHECK-DAG: annotate-comments-objc.m:7:6: FunctionDecl=functionBeforeImports:{{.*}} BriefComment=[Comment for 'functionBeforeImports'.]
+// CHECK-DAG: DocCommentsA.h:2:6: FunctionDecl=functionFromDocCommentsA1:{{.*}} BriefComment=[Comment for 'functionFromDocCommentsA1'.]
+// CHECK-DAG: DocCommentsA.h:7:6: FunctionDecl=functionFromDocCommentsA2:{{.*}} BriefComment=[Comment for 'functionFromDocCommentsA2'.]
+// CHECK-DAG: DocCommentsB.h:2:6: FunctionDecl=functionFromDocCommentsB1:{{.*}} BriefComment=[Comment for 'functionFromDocCommentsB1'.]
+// CHECK-DAG: DocCommentsB.h:7:6: FunctionDecl=functionFromDocCommentsB2:{{.*}} BriefComment=[Comment for 'functionFromDocCommentsB2'.]
+// CHECK-DAG: DocCommentsC.h:2:6: FunctionDecl=functionFromDocCommentsC:{{.*}} BriefComment=[Comment for 'functionFromDocCommentsC'.]
+// CHECK: annotate-comments-objc.m:23:50: ObjCPropertyDecl=property1_isdoxy1:{{.*}} property1_isdoxy1 IS_DOXYGEN_SINGLE
+// CHECK: annotate-comments-objc.m:24:50: ObjCPropertyDecl=property1_isdoxy2:{{.*}} property1_isdoxy2 IS_DOXYGEN_SINGLE
+// CHECK: annotate-comments-objc.m:25:50: ObjCPropertyDecl=property1_isdoxy3:{{.*}} property1_isdoxy3 IS_DOXYGEN_SINGLE
+// CHECK: annotate-comments-objc.m:26:50: ObjCPropertyDecl=property1_isdoxy4:{{.*}} property1_isdoxy4 IS_DOXYGEN_SINGLE
+// CHECK: annotate-comments-objc.m:29:9: ObjCInstanceMethodDecl=method1_isdoxy1:{{.*}} method1_isdoxy1 IS_DOXYGEN_SINGLE
+// CHECK: annotate-comments-objc.m:30:9: ObjCInstanceMethodDecl=method1_isdoxy2:{{.*}} method1_isdoxy2 IS_DOXYGEN_SINGLE
+// CHECK: annotate-comments-objc.m:31:9: ObjCInstanceMethodDecl=method1_isdoxy3:{{.*}} method1_isdoxy3 IS_DOXYGEN_SINGLE
+// CHECK: annotate-comments-objc.m:32:9: ObjCInstanceMethodDecl=method1_isdoxy4:{{.*}} method1_isdoxy4 IS_DOXYGEN_SINGLE
+// CHECK: annotate-comments-objc.m:43:22: EnumDecl=An_NS_ENUM_isdoxy1:{{.*}} An_NS_ENUM_isdoxy1 IS_DOXYGEN_SINGLE
+// CHECK: annotate-comments-objc.m:43:22: TypedefDecl=An_NS_ENUM_isdoxy1:{{.*}} An_NS_ENUM_isdoxy1 IS_DOXYGEN_SINGLE
+// CHECK: annotate-comments-objc.m:43:22: EnumDecl=An_NS_ENUM_isdoxy1:{{.*}} An_NS_ENUM_isdoxy1 IS_DOXYGEN_SINGLE
+// CHECK: annotate-comments-objc.m:60:32: TypedefDecl=typedef_isdoxy1:{{.*}} typedef_isdoxy1 IS_DOXYGEN_SINGLE
 
diff --git a/test/Index/annotate-comments-typedef.m b/test/Index/annotate-comments-typedef.m
index b23e535..751cfaa 100644
--- a/test/Index/annotate-comments-typedef.m
+++ b/test/Index/annotate-comments-typedef.m
@@ -45,5 +45,5 @@
 /** About Foo1T */
 typedef struct Foo1 Foo1T;
 // FIXME: we don't attach this comment to 'struct Foo1'
-// CHECK: TypedefDecl=Foo1T:[[@LINE-2]]:21 (Definition) {{.*}} FullCommentAsHTML=[<p class="para-brief"> About Foo1T </p>] FullCommentAsXML=[<Typedef file="{{[^"]+}}annotate-comments-typedef.m" line="[[@LINE-2]]" column="21"><Name>Foo1T</Name><USR>c:annotate-comments-typedef.m@{{[0-9]+}}@T@Foo1T</USR><Declaration>typedef struct Foo1 Foo1T</Declaration><Abstract><Para> About Foo1T </Para></Abstract></Typedef>]
+// CHECK: TypedefDecl=Foo1T:[[@LINE-2]]:21 (Definition) {{.*}} FullCommentAsHTML=[<p class="para-brief"> About Foo1T </p>] FullCommentAsXML=[<Typedef file="{{[^"]+}}annotate-comments-typedef.m" line="[[@LINE-2]]" column="21"><Name>Foo1T</Name><USR>c:annotate-comments-typedef.m@T@Foo1T</USR><Declaration>typedef struct Foo1 Foo1T</Declaration><Abstract><Para> About Foo1T </Para></Abstract></Typedef>]
 
diff --git a/test/Index/annotate-deep-statements.cpp b/test/Index/annotate-deep-statements.cpp
index 79f2d39..c0a55f2 100644
--- a/test/Index/annotate-deep-statements.cpp
+++ b/test/Index/annotate-deep-statements.cpp
@@ -4,13 +4,13 @@
 // Check that we don't get stack overflow trying to annotate an extremely deep AST.
 
 // AddressSanitizer increases stack usage.
-// XFAIL: asan
+// REQUIRES: not_asan
 
 struct S {
   S &operator()();
 };
 
-// CHECK: Identifier: "foo" [11:6 - 11:9] FunctionDecl=foo:11:6 (Definition)
+// CHECK: Identifier: "foo" {{\[}}[[@LINE+1]]:6 - [[@LINE+1]]:9] FunctionDecl=foo:[[@LINE+1]]:6 (Definition)
 void foo() {
   S s;
   s()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()
diff --git a/test/Index/annotate-module.m b/test/Index/annotate-module.m
index 55e21d2..456a192 100644
--- a/test/Index/annotate-module.m
+++ b/test/Index/annotate-module.m
@@ -44,6 +44,6 @@
 // RUN: c-index-test -cursor-at=%s:3:11 %s -fmodules-cache-path=%t.cache -fmodules -F %S/../Modules/Inputs \
 // RUN:     | FileCheck %s -check-prefix=CHECK-CURSOR
 
-// CHECK-CURSOR:      3:1 ModuleImport=DependsOnModule:3:1 (Definition) Extent=[3:1 - 3:24] Spelling=DependsOnModule ([3:9 - 3:24]) ModuleName=DependsOnModule ({{.*}}DependsOnModule.pcm) Headers(2):
+// CHECK-CURSOR:      3:1 ModuleImport=DependsOnModule:3:1 (Definition) Extent=[3:1 - 3:24] Spelling=DependsOnModule ([3:9 - 3:24]) ModuleName=DependsOnModule ({{.*}}DependsOnModule-{{[^.]*}}.pcm) system=0 Headers(2):
 // CHECK-CURSOR-NEXT: {{.*}}other.h
 // CHECK-CURSOR-NEXT: {{.*}}DependsOnModule.h
diff --git a/test/Index/annotate-tokens-cxx0x.cpp b/test/Index/annotate-tokens-cxx0x.cpp
index 4e6d156..8992aff 100644
--- a/test/Index/annotate-tokens-cxx0x.cpp
+++ b/test/Index/annotate-tokens-cxx0x.cpp
@@ -83,14 +83,14 @@
 // CHECK-WITH-OVERRIDE: Identifier: "foo" [19:15 - 19:18] CXXMethod=foo:19:15 (virtual)
 // CHECK-WITH-OVERRIDE: Punctuation: "(" [19:18 - 19:19] CXXMethod=foo:19:15 (virtual)
 // CHECK-WITH-OVERRIDE: Identifier: "Int" [19:19 - 19:22] TypeRef=Int:16:13
-// CHECK-WITH-OVERRIDE: Punctuation: ")" [19:22 - 19:23] ParmDecl=:19:22 (Definition)
+// CHECK-WITH-OVERRIDE: Punctuation: ")" [19:22 - 19:23] CXXMethod=foo:19:15 (virtual)
 // CHECK-WITH-OVERRIDE: Punctuation: ";" [19:23 - 19:24] ClassDecl=B:18:7 (Definition)
 // CHECK-WITH-OVERRIDE: Keyword: "virtual" [23:3 - 23:10] CXXMethod=foo:23:16 (virtual) [Overrides @19:15]
 // CHECK-WITH-OVERRIDE: Keyword: "void" [23:11 - 23:15] CXXMethod=foo:23:16 (virtual) [Overrides @19:15]
 // CHECK-WITH-OVERRIDE: Identifier: "foo" [23:16 - 23:19] CXXMethod=foo:23:16 (virtual) [Overrides @19:15]
 // CHECK-WITH-OVERRIDE: Punctuation: "(" [23:19 - 23:20] CXXMethod=foo:23:16 (virtual) [Overrides @19:15]
 // CHECK-WITH-OVERRIDE: Identifier: "Int" [23:20 - 23:23] TypeRef=Int:16:13
-// CHECK-WITH-OVERRIDE: Punctuation: ")" [23:23 - 23:24] ParmDecl=:23:23 (Definition)
+// CHECK-WITH-OVERRIDE: Punctuation: ")" [23:23 - 23:24] CXXMethod=foo:23:16 (virtual) [Overrides @19:15]
 // CHECK-WITH-OVERRIDE: Keyword: "override" [23:25 - 23:33] attribute(override)=
 // CHECK-WITH-OVERRIDE: Punctuation: ";" [23:33 - 23:34] ClassDecl=S:22:7 (Definition)
 
diff --git a/test/Index/annotate-tokens.cpp b/test/Index/annotate-tokens.cpp
index 1672654..460ab51 100644
--- a/test/Index/annotate-tokens.cpp
+++ b/test/Index/annotate-tokens.cpp
@@ -28,7 +28,16 @@
 template <bool (*tfn)(X*)>
 void TS<tfn>::foo() {}
 
-// RUN: c-index-test -test-annotate-tokens=%s:1:1:30:1 %s -fno-delayed-template-parsing | FileCheck %s
+void test4() {
+  if (int p = 0)
+    return;
+}
+
+class C {
+  ~C();
+};
+
+// RUN: c-index-test -test-annotate-tokens=%s:1:1:38:1 %s -fno-delayed-template-parsing | FileCheck %s
 // CHECK: Keyword: "struct" [1:1 - 1:7] StructDecl=bonk:1:8 (Definition)
 // CHECK: Identifier: "bonk" [1:8 - 1:12] StructDecl=bonk:1:8 (Definition)
 // CHECK: Punctuation: "{" [1:13 - 1:14] StructDecl=bonk:1:8 (Definition)
@@ -66,8 +75,8 @@
 // CHECK: Keyword: "operator" [9:5 - 9:13] CXXMethod=operator++:9:5
 // CHECK: Punctuation: "++" [9:13 - 9:15] CXXMethod=operator++:9:5
 // CHECK: Punctuation: "(" [9:15 - 9:16] CXXMethod=operator++:9:5
-// CHECK: Keyword: "int" [9:16 - 9:19] ParmDecl=:9:19 (Definition)
-// CHECK: Punctuation: ")" [9:19 - 9:20] ParmDecl=:9:19 (Definition)
+// CHECK: Keyword: "int" [9:16 - 9:19] ParmDecl=:9:19 (Definition
+// CHECK: Punctuation: ")" [9:19 - 9:20] CXXMethod=operator++:9:5
 // CHECK: Punctuation: ";" [9:20 - 9:21] StructDecl=X:7:8 (Definition)
 // CHECK: Punctuation: "}" [10:1 - 10:2] StructDecl=X:7:8 (Definition)
 // CHECK: Punctuation: ";" [10:2 - 10:3]
@@ -138,7 +147,7 @@
 // CHECK: Punctuation: "(" [23:22 - 23:23] NonTypeTemplateParameter=tfn:23:18 (Definition)
 // CHECK: Identifier: "X" [23:23 - 23:24] TypeRef=struct X:7:8
 // CHECK: Punctuation: "*" [23:24 - 23:25] ParmDecl=:23:25 (Definition)
-// CHECK: Punctuation: ")" [23:25 - 23:26] ParmDecl=:23:25 (Definition)
+// CHECK: Punctuation: ")" [23:25 - 23:26] NonTypeTemplateParameter=tfn:23:18 (Definition)
 // CHECK: Punctuation: ">" [23:26 - 23:27] ClassTemplate=TS:24:8 (Definition)
 // CHECK: Keyword: "struct" [24:1 - 24:7] ClassTemplate=TS:24:8 (Definition)
 // CHECK: Identifier: "TS" [24:8 - 24:10] ClassTemplate=TS:24:8 (Definition)
@@ -160,7 +169,7 @@
 // CHECK: Punctuation: "(" [28:22 - 28:23] NonTypeTemplateParameter=tfn:28:18 (Definition)
 // CHECK: Identifier: "X" [28:23 - 28:24] TypeRef=struct X:7:8
 // CHECK: Punctuation: "*" [28:24 - 28:25] ParmDecl=:28:25 (Definition)
-// CHECK: Punctuation: ")" [28:25 - 28:26] ParmDecl=:28:25 (Definition)
+// CHECK: Punctuation: ")" [28:25 - 28:26] NonTypeTemplateParameter=tfn:28:18 (Definition)
 // CHECK: Punctuation: ">" [28:26 - 28:27] CXXMethod=foo:29:15 (Definition)
 // CHECK: Keyword: "void" [29:1 - 29:5] CXXMethod=foo:29:15 (Definition)
 // CHECK: Identifier: "TS" [29:6 - 29:8] TemplateRef=TS:24:8
@@ -173,3 +182,12 @@
 // CHECK: Punctuation: ")" [29:19 - 29:20] CXXMethod=foo:29:15 (Definition)
 // CHECK: Punctuation: "{" [29:21 - 29:22] CompoundStmt=
 // CHECK: Punctuation: "}" [29:22 - 29:23] CompoundStmt=
+// CHECK: Punctuation: "~" [37:3 - 37:4] CXXDestructor=~C:37:3
+// CHECK: Identifier: "C" [37:4 - 37:5] CXXDestructor=~C:37:3
+
+// RUN: env LIBCLANG_DISABLE_CRASH_RECOVERY=1 c-index-test -test-annotate-tokens=%s:32:1:32:13 %s | FileCheck %s -check-prefix=CHECK2
+// CHECK2: Keyword: "if" [32:3 - 32:5] IfStmt=
+// CHECK2: Punctuation: "(" [32:6 - 32:7] IfStmt=
+// CHECK2: Keyword: "int" [32:7 - 32:10] VarDecl=p:32:11 (Definition)
+// CHECK2: Identifier: "p" [32:11 - 32:12] VarDecl=p:32:11 (Definition)
+// CHECK2: Punctuation: "=" [32:13 - 32:14] VarDecl=p:32:11 (Definition)
diff --git a/test/Index/attributes-cuda.cu b/test/Index/attributes-cuda.cu
new file mode 100644
index 0000000..953ef3d
--- /dev/null
+++ b/test/Index/attributes-cuda.cu
@@ -0,0 +1,15 @@
+// RUN: c-index-test -test-load-source all -x cuda %s | FileCheck %s
+
+__attribute__((device)) void f_device();
+__attribute__((global)) void f_global();
+__attribute__((constant)) int* g_constant;
+__attribute__((host)) void f_host();
+
+// CHECK:       attributes-cuda.cu:3:30: FunctionDecl=f_device:3:30
+// CHECK-NEXT:  attributes-cuda.cu:3:16: attribute(device)
+// CHECK:       attributes-cuda.cu:4:30: FunctionDecl=f_global:4:30
+// CHECK-NEXT:  attributes-cuda.cu:4:16: attribute(global)
+// CHECK:       attributes-cuda.cu:5:32: VarDecl=g_constant:5:32 (Definition)
+// CHECK-NEXT:  attributes-cuda.cu:5:16: attribute(constant)
+// CHECK:       attributes-cuda.cu:6:28: FunctionDecl=f_host:6:28
+// CHECK-NEXT:  attributes-cuda.cu:6:16: attribute(host)
diff --git a/test/Index/attributes.c b/test/Index/attributes.c
index 3e60e6c..95d9c75 100644
--- a/test/Index/attributes.c
+++ b/test/Index/attributes.c
@@ -4,7 +4,17 @@
   char a;
 };
 
+void pure_fn() __attribute__((pure));
+void const_fn() __attribute__((const));
+void noduplicate_fn() __attribute__((noduplicate));
+
 // CHECK: attributes.c:3:32: StructDecl=Test2:3:32 (Definition) Extent=[3:1 - 5:2]
 // CHECK: attributes.c:3:23: attribute(packed)=packed Extent=[3:23 - 3:29]
 // CHECK: attributes.c:4:8: FieldDecl=a:4:8 (Definition) Extent=[4:3 - 4:9] [access=public]
 
+// CHECK: attributes.c:7:6: FunctionDecl=pure_fn:7:6 Extent=[7:1 - 7:37]
+// CHECK: attributes.c:7:31: attribute(pure)= Extent=[7:31 - 7:35]
+// CHECK: attributes.c:8:6: FunctionDecl=const_fn:8:6 Extent=[8:1 - 8:39]
+// CHECK: attributes.c:8:32: attribute(const)= Extent=[8:32 - 8:37]
+// CHECK: attributes.c:9:6: FunctionDecl=noduplicate_fn:9:6 Extent=[9:1 - 9:51]
+// CHECK: attributes.c:9:38: attribute(noduplicate)= Extent=[9:38 - 9:49]
diff --git a/test/Index/comment-cplus-decls.cpp b/test/Index/comment-cplus-decls.cpp
index de1c2c5..002482e 100644
--- a/test/Index/comment-cplus-decls.cpp
+++ b/test/Index/comment-cplus-decls.cpp
@@ -42,7 +42,7 @@
 // CHECK: <Declaration>class Test {}</Declaration>
 // CHECK: <Declaration>Test() : reserved(new Test::data())</Declaration>
 // CHECK: <Declaration>unsigned int getID() const</Declaration>
-// CHECK: <Declaration>void ~Test()</Declaration>
+// CHECK: <Declaration>~Test()</Declaration>
 // CHECK: <Declaration>Test::data *reserved</Declaration>
 
 
diff --git a/test/Index/comment-cplus-template-decls.cpp b/test/Index/comment-cplus-template-decls.cpp
index 039f092..7ef09bd 100644
--- a/test/Index/comment-cplus-template-decls.cpp
+++ b/test/Index/comment-cplus-template-decls.cpp
@@ -27,7 +27,7 @@
 };
 // CHECK: <Declaration>template &lt;typename T&gt; struct A {}</Declaration>
 // CHECK: <Declaration>A&lt;T&gt;()</Declaration>
-// CHECK: <Declaration>void ~A&lt;T&gt;()</Declaration>
+// CHECK: <Declaration>~A&lt;T&gt;()</Declaration>
 
 /**
  * \Brief Eee
@@ -67,3 +67,18 @@
 template<template<template<typename CCC> class DDD, class BBB> class AAA>
 void func_template_2();
 // FIXME: There is not Declaration field in the generated output.
+
+namespace rdar16128173 {
+// CHECK: <Declaration>template &lt;class PtrTy&gt; class OpaquePtr {}</Declaration>
+
+/// \brief Wrapper for void* pointer.
+/// \tparam PtrTy Either a pointer type like 'T*' or a type that behaves like
+///               a pointer.
+template <class PtrTy>
+class OpaquePtr {};
+
+// CHECK: <Declaration>typedef OpaquePtr&lt;int&gt; DeclGroupPtrTy</Declaration>
+typedef OpaquePtr<int> DeclGroupPtrTy;
+
+DeclGroupPtrTy blah;
+}
diff --git a/test/Index/comment-to-html-xml-conversion.cpp b/test/Index/comment-to-html-xml-conversion.cpp
index 8c0ed21..95e11c3 100644
--- a/test/Index/comment-to-html-xml-conversion.cpp
+++ b/test/Index/comment-to-html-xml-conversion.cpp
@@ -25,19 +25,23 @@
 #ifndef HEADER
 #define HEADER
 
-/// Aaa.
-void comment_to_html_conversion_1();
+//===---
+// Tests for \brief and its aliases.
+//===---
 
-// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=comment_to_html_conversion_1:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>comment_to_html_conversion_1</Name><USR>c:@F@comment_to_html_conversion_1#</USR><Declaration>void comment_to_html_conversion_1()</Declaration><Abstract><Para> Aaa.</Para></Abstract></Function>]
+/// Aaa.
+void test_cmd_brief_like_1();
+
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=test_cmd_brief_like_1:{{.*}} BriefComment=[Aaa.] FullCommentAsHTML=[<p class="para-brief"> Aaa.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>test_cmd_brief_like_1</Name><USR>c:@F@test_cmd_brief_like_1#</USR><Declaration>void test_cmd_brief_like_1()</Declaration><Abstract><Para> Aaa.</Para></Abstract></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph
 // CHECK-NEXT:         (CXComment_Text Text=[ Aaa.])))]
 
 /// \brief Aaa.
-void comment_to_html_conversion_2();
+void test_cmd_brief_like_2();
 
-// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=comment_to_html_conversion_2:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>comment_to_html_conversion_2</Name><USR>c:@F@comment_to_html_conversion_2#</USR><Declaration>void comment_to_html_conversion_2()</Declaration><Abstract><Para> Aaa.</Para></Abstract></Function>]
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=test_cmd_brief_like_2:{{.*}} BriefComment=[Aaa.] FullCommentAsHTML=[<p class="para-brief"> Aaa.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>test_cmd_brief_like_2</Name><USR>c:@F@test_cmd_brief_like_2#</USR><Declaration>void test_cmd_brief_like_2()</Declaration><Abstract><Para> Aaa.</Para></Abstract></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph IsWhitespace
@@ -47,9 +51,9 @@
 // CHECK-NEXT:           (CXComment_Text Text=[ Aaa.]))))]
 
 /// \short Aaa.
-void comment_to_html_conversion_3();
+void test_cmd_brief_like_3();
 
-// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=comment_to_html_conversion_3:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>comment_to_html_conversion_3</Name><USR>c:@F@comment_to_html_conversion_3#</USR><Declaration>void comment_to_html_conversion_3()</Declaration><Abstract><Para> Aaa.</Para></Abstract></Function>]
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=test_cmd_brief_like_3:{{.*}} BriefComment=[Aaa.] FullCommentAsHTML=[<p class="para-brief"> Aaa.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>test_cmd_brief_like_3</Name><USR>c:@F@test_cmd_brief_like_3#</USR><Declaration>void test_cmd_brief_like_3()</Declaration><Abstract><Para> Aaa.</Para></Abstract></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph IsWhitespace
@@ -61,9 +65,9 @@
 /// Aaa.
 ///
 /// \brief Bbb.
-void comment_to_html_conversion_4();
+void test_cmd_brief_like_4();
 
-// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=comment_to_html_conversion_4:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Bbb.</p><p> Aaa.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>comment_to_html_conversion_4</Name><USR>c:@F@comment_to_html_conversion_4#</USR><Declaration>void comment_to_html_conversion_4()</Declaration><Abstract><Para> Bbb.</Para></Abstract><Discussion><Para> Aaa.</Para></Discussion></Function>]
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=test_cmd_brief_like_4:{{.*}} BriefComment=[Bbb.] FullCommentAsHTML=[<p class="para-brief"> Bbb.</p><p> Aaa.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>test_cmd_brief_like_4</Name><USR>c:@F@test_cmd_brief_like_4#</USR><Declaration>void test_cmd_brief_like_4()</Declaration><Abstract><Para> Bbb.</Para></Abstract><Discussion><Para> Aaa.</Para></Discussion></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph
@@ -79,9 +83,9 @@
 /// \brief Bbb.
 ///
 /// Ccc.
-void comment_to_html_conversion_5();
+void test_cmd_brief_like_5();
 
-// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=comment_to_html_conversion_5:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Bbb.</p><p> Aaa.</p><p> Ccc.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>comment_to_html_conversion_5</Name><USR>c:@F@comment_to_html_conversion_5#</USR><Declaration>void comment_to_html_conversion_5()</Declaration><Abstract><Para> Bbb.</Para></Abstract><Discussion><Para> Aaa.</Para><Para> Ccc.</Para></Discussion></Function>]
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=test_cmd_brief_like_5:{{.*}} BriefComment=[Bbb.] FullCommentAsHTML=[<p class="para-brief"> Bbb.</p><p> Aaa.</p><p> Ccc.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>test_cmd_brief_like_5</Name><USR>c:@F@test_cmd_brief_like_5#</USR><Declaration>void test_cmd_brief_like_5()</Declaration><Abstract><Para> Bbb.</Para></Abstract><Discussion><Para> Aaa.</Para><Para> Ccc.</Para></Discussion></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph
@@ -96,9 +100,9 @@
 
 /// \brief Aaa.
 /// \brief Bbb.
-void comment_to_html_conversion_6();
+void test_cmd_brief_like_6();
 
-// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=comment_to_html_conversion_6:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa. </p><p class="para-brief"> Bbb.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>comment_to_html_conversion_6</Name><USR>c:@F@comment_to_html_conversion_6#</USR><Declaration>void comment_to_html_conversion_6()</Declaration><Abstract><Para> Aaa. </Para></Abstract><Discussion><Para> Bbb.</Para></Discussion></Function>]
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=test_cmd_brief_like_6:{{.*}} BriefComment=[Bbb.] FullCommentAsHTML=[<p class="para-brief"> Aaa. </p><p class="para-brief"> Bbb.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>test_cmd_brief_like_6</Name><USR>c:@F@test_cmd_brief_like_6#</USR><Declaration>void test_cmd_brief_like_6()</Declaration><Abstract><Para> Aaa. </Para></Abstract><Discussion><Para> Bbb.</Para></Discussion></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph IsWhitespace
@@ -111,12 +115,32 @@
 // CHECK-NEXT:         (CXComment_Paragraph
 // CHECK-NEXT:           (CXComment_Text Text=[ Bbb.]))))]
 
+/// \abstract Aaa.
+///
+/// Bbb.
+void test_cmd_brief_like_7();
+
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=test_cmd_brief_like_7:{{.*}} BriefComment=[Aaa.] FullCommentAsHTML=[<p class="para-brief"> Aaa.</p><p> Bbb.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>test_cmd_brief_like_7</Name><USR>c:@F@test_cmd_brief_like_7#</USR><Declaration>void test_cmd_brief_like_7()</Declaration><Abstract><Para> Aaa.</Para></Abstract><Discussion><Para> Bbb.</Para></Discussion></Function>]
+// CHECK-NEXT:  CommentAST=[
+// CHECK-NEXT:    (CXComment_FullComment
+// CHECK-NEXT:       (CXComment_Paragraph IsWhitespace
+// CHECK-NEXT:         (CXComment_Text Text=[ ] IsWhitespace))
+// CHECK-NEXT:       (CXComment_BlockCommand CommandName=[abstract]
+// CHECK-NEXT:         (CXComment_Paragraph
+// CHECK-NEXT:           (CXComment_Text Text=[ Aaa.])))
+// CHECK-NEXT:       (CXComment_Paragraph
+// CHECK-NEXT:         (CXComment_Text Text=[ Bbb.])))]
+
+//===---
+// Tests for \returns and its aliases.
+//===---
+
 /// Aaa.
 ///
 /// \return Bbb.
-void comment_to_html_conversion_7();
+void test_cmd_returns_like_1();
 
-// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=comment_to_html_conversion_7:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p><div class="result-discussion"><p class="para-returns"><span class="word-returns">Returns</span>  Bbb.</p></div>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>comment_to_html_conversion_7</Name><USR>c:@F@comment_to_html_conversion_7#</USR><Declaration>void comment_to_html_conversion_7()</Declaration><Abstract><Para> Aaa.</Para></Abstract><ResultDiscussion><Para> Bbb.</Para></ResultDiscussion></Function>]
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=test_cmd_returns_like_1:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p><div class="result-discussion"><p class="para-returns"><span class="word-returns">Returns</span>  Bbb.</p></div>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>test_cmd_returns_like_1</Name><USR>c:@F@test_cmd_returns_like_1#</USR><Declaration>void test_cmd_returns_like_1()</Declaration><Abstract><Para> Aaa.</Para></Abstract><ResultDiscussion><Para> Bbb.</Para></ResultDiscussion></Function>]
 
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
@@ -131,9 +155,9 @@
 /// Aaa.
 ///
 /// \returns Bbb.
-void comment_to_html_conversion_8();
+void test_cmd_returns_like_2();
 
-// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=comment_to_html_conversion_8:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p><div class="result-discussion"><p class="para-returns"><span class="word-returns">Returns</span>  Bbb.</p></div>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>comment_to_html_conversion_8</Name><USR>c:@F@comment_to_html_conversion_8#</USR><Declaration>void comment_to_html_conversion_8()</Declaration><Abstract><Para> Aaa.</Para></Abstract><ResultDiscussion><Para> Bbb.</Para></ResultDiscussion></Function>]
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=test_cmd_returns_like_2:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p><div class="result-discussion"><p class="para-returns"><span class="word-returns">Returns</span>  Bbb.</p></div>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>test_cmd_returns_like_2</Name><USR>c:@F@test_cmd_returns_like_2#</USR><Declaration>void test_cmd_returns_like_2()</Declaration><Abstract><Para> Aaa.</Para></Abstract><ResultDiscussion><Para> Bbb.</Para></ResultDiscussion></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph
@@ -147,9 +171,9 @@
 /// Aaa.
 ///
 /// \result Bbb.
-void comment_to_html_conversion_9();
+void test_cmd_returns_like_3();
 
-// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=comment_to_html_conversion_9:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p><div class="result-discussion"><p class="para-returns"><span class="word-returns">Returns</span>  Bbb.</p></div>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>comment_to_html_conversion_9</Name><USR>c:@F@comment_to_html_conversion_9#</USR><Declaration>void comment_to_html_conversion_9()</Declaration><Abstract><Para> Aaa.</Para></Abstract><ResultDiscussion><Para> Bbb.</Para></ResultDiscussion></Function>]
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=test_cmd_returns_like_3:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p><div class="result-discussion"><p class="para-returns"><span class="word-returns">Returns</span>  Bbb.</p></div>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>test_cmd_returns_like_3</Name><USR>c:@F@test_cmd_returns_like_3#</USR><Declaration>void test_cmd_returns_like_3()</Declaration><Abstract><Para> Aaa.</Para></Abstract><ResultDiscussion><Para> Bbb.</Para></ResultDiscussion></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph
@@ -162,9 +186,9 @@
 
 /// \returns Aaa.
 /// \returns Bbb.
-void comment_to_html_conversion_10();
+void test_cmd_returns_like_4();
 
-// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=comment_to_html_conversion_10:{{.*}} FullCommentAsHTML=[<div class="result-discussion"><p class="para-returns"><span class="word-returns">Returns</span>  Aaa. </p><p class="para-returns"><span class="word-returns">Returns</span>  Bbb.</p></div>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>comment_to_html_conversion_10</Name><USR>c:@F@comment_to_html_conversion_10#</USR><Declaration>void comment_to_html_conversion_10()</Declaration><ResultDiscussion><Para> Aaa. </Para><Para> Bbb.</Para></ResultDiscussion></Function>]
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=test_cmd_returns_like_4:{{.*}} FullCommentAsHTML=[<div class="result-discussion"><p class="para-returns"><span class="word-returns">Returns</span>  Aaa. </p><p class="para-returns"><span class="word-returns">Returns</span>  Bbb.</p></div>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>test_cmd_returns_like_4</Name><USR>c:@F@test_cmd_returns_like_4#</USR><Declaration>void test_cmd_returns_like_4()</Declaration><ResultDiscussion><Para> Aaa. </Para><Para> Bbb.</Para></ResultDiscussion></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph IsWhitespace
@@ -182,9 +206,9 @@
 /// Bbb.
 ///
 /// \returns Ccc.
-void comment_to_html_conversion_11();
+void test_cmd_returns_like_5();
 
-// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=comment_to_html_conversion_11:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p><p> Bbb.</p><div class="result-discussion"><p class="para-returns"><span class="word-returns">Returns</span>  Ccc.</p></div>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>comment_to_html_conversion_11</Name><USR>c:@F@comment_to_html_conversion_11#</USR><Declaration>void comment_to_html_conversion_11()</Declaration><Abstract><Para> Aaa.</Para></Abstract><ResultDiscussion><Para> Ccc.</Para></ResultDiscussion><Discussion><Para> Bbb.</Para></Discussion></Function>]
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=test_cmd_returns_like_5:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p><p> Bbb.</p><div class="result-discussion"><p class="para-returns"><span class="word-returns">Returns</span>  Ccc.</p></div>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>test_cmd_returns_like_5</Name><USR>c:@F@test_cmd_returns_like_5#</USR><Declaration>void test_cmd_returns_like_5()</Declaration><Abstract><Para> Aaa.</Para></Abstract><ResultDiscussion><Para> Ccc.</Para></ResultDiscussion><Discussion><Para> Bbb.</Para></Discussion></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph
@@ -197,10 +221,14 @@
 // CHECK-NEXT:         (CXComment_Paragraph
 // CHECK-NEXT:           (CXComment_Text Text=[ Ccc.]))))]
 
-/// \param
-void comment_to_html_conversion_12(int x1);
+//===---
+// Tests for \param.
+//===---
 
-// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=comment_to_html_conversion_12:{{.*}} FullCommentAsHTML=[] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>comment_to_html_conversion_12</Name><USR>c:@F@comment_to_html_conversion_12#I#</USR><Declaration>void comment_to_html_conversion_12(int x1)</Declaration></Function>]
+/// \param
+void test_cmd_param_1(int x1);
+
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=test_cmd_param_1:{{.*}} FullCommentAsHTML=[] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>test_cmd_param_1</Name><USR>c:@F@test_cmd_param_1#I#</USR><Declaration>void test_cmd_param_1(int x1)</Declaration></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph IsWhitespace
@@ -209,9 +237,9 @@
 // CHECK-NEXT:         (CXComment_Paragraph IsWhitespace)))]
 
 /// \param x1 Aaa.
-void comment_to_html_conversion_13(int x1);
+void test_cmd_param_2(int x1);
 
-// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=comment_to_html_conversion_13:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-0">x1</dt><dd class="param-descr-index-0"> Aaa.</dd></dl>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>comment_to_html_conversion_13</Name><USR>c:@F@comment_to_html_conversion_13#I#</USR><Declaration>void comment_to_html_conversion_13(int x1)</Declaration><Parameters><Parameter><Name>x1</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Aaa.</Para></Discussion></Parameter></Parameters></Function>]
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=test_cmd_param_2:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-0">x1</dt><dd class="param-descr-index-0"> Aaa.</dd></dl>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>test_cmd_param_2</Name><USR>c:@F@test_cmd_param_2#I#</USR><Declaration>void test_cmd_param_2(int x1)</Declaration><Parameters><Parameter><Name>x1</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Aaa.</Para></Discussion></Parameter></Parameters></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph IsWhitespace
@@ -221,9 +249,9 @@
 // CHECK-NEXT:           (CXComment_Text Text=[ Aaa.]))))]
 
 /// \param zzz Aaa.
-void comment_to_html_conversion_14(int x1);
+void test_cmd_param_3(int x1);
 
-// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=comment_to_html_conversion_14:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-invalid">zzz</dt><dd class="param-descr-index-invalid"> Aaa.</dd></dl>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>comment_to_html_conversion_14</Name><USR>c:@F@comment_to_html_conversion_14#I#</USR><Declaration>void comment_to_html_conversion_14(int x1)</Declaration><Parameters><Parameter><Name>zzz</Name><Direction isExplicit="0">in</Direction><Discussion><Para> Aaa.</Para></Discussion></Parameter></Parameters></Function>]
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=test_cmd_param_3:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-invalid">zzz</dt><dd class="param-descr-index-invalid"> Aaa.</dd></dl>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>test_cmd_param_3</Name><USR>c:@F@test_cmd_param_3#I#</USR><Declaration>void test_cmd_param_3(int x1)</Declaration><Parameters><Parameter><Name>zzz</Name><Direction isExplicit="0">in</Direction><Discussion><Para> Aaa.</Para></Discussion></Parameter></Parameters></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph IsWhitespace
@@ -234,9 +262,9 @@
 
 /// \param x2 Bbb.
 /// \param x1 Aaa.
-void comment_to_html_conversion_15(int x1, int x2);
+void test_cmd_param_4(int x1, int x2);
 
-// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=comment_to_html_conversion_15:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-0">x1</dt><dd class="param-descr-index-0"> Aaa.</dd><dt class="param-name-index-1">x2</dt><dd class="param-descr-index-1"> Bbb. </dd></dl>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>comment_to_html_conversion_15</Name><USR>c:@F@comment_to_html_conversion_15#I#I#</USR><Declaration>void comment_to_html_conversion_15(int x1, int x2)</Declaration><Parameters><Parameter><Name>x1</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Aaa.</Para></Discussion></Parameter><Parameter><Name>x2</Name><Index>1</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Bbb. </Para></Discussion></Parameter></Parameters></Function>]
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=test_cmd_param_4:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-0">x1</dt><dd class="param-descr-index-0"> Aaa.</dd><dt class="param-name-index-1">x2</dt><dd class="param-descr-index-1"> Bbb. </dd></dl>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>test_cmd_param_4</Name><USR>c:@F@test_cmd_param_4#I#I#</USR><Declaration>void test_cmd_param_4(int x1, int x2)</Declaration><Parameters><Parameter><Name>x1</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Aaa.</Para></Discussion></Parameter><Parameter><Name>x2</Name><Index>1</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Bbb. </Para></Discussion></Parameter></Parameters></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph IsWhitespace
@@ -252,9 +280,9 @@
 /// \param x2 Bbb.
 /// \param zzz Aaa.
 /// \param x1 Aaa.
-void comment_to_html_conversion_16(int x1, int x2);
+void test_cmd_param_5(int x1, int x2);
 
-// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=comment_to_html_conversion_16:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-0">x1</dt><dd class="param-descr-index-0"> Aaa.</dd><dt class="param-name-index-1">x2</dt><dd class="param-descr-index-1"> Bbb. </dd><dt class="param-name-index-invalid">zzz</dt><dd class="param-descr-index-invalid"> Aaa. </dd></dl>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>comment_to_html_conversion_16</Name><USR>c:@F@comment_to_html_conversion_16#I#I#</USR><Declaration>void comment_to_html_conversion_16(int x1, int x2)</Declaration><Parameters><Parameter><Name>x1</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Aaa.</Para></Discussion></Parameter><Parameter><Name>x2</Name><Index>1</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Bbb. </Para></Discussion></Parameter><Parameter><Name>zzz</Name><Direction isExplicit="0">in</Direction><Discussion><Para> Aaa. </Para></Discussion></Parameter></Parameters></Function>]
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=test_cmd_param_5:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-0">x1</dt><dd class="param-descr-index-0"> Aaa.</dd><dt class="param-name-index-1">x2</dt><dd class="param-descr-index-1"> Bbb. </dd><dt class="param-name-index-invalid">zzz</dt><dd class="param-descr-index-invalid"> Aaa. </dd></dl>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>test_cmd_param_5</Name><USR>c:@F@test_cmd_param_5#I#I#</USR><Declaration>void test_cmd_param_5(int x1, int x2)</Declaration><Parameters><Parameter><Name>x1</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Aaa.</Para></Discussion></Parameter><Parameter><Name>x2</Name><Index>1</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Bbb. </Para></Discussion></Parameter><Parameter><Name>zzz</Name><Direction isExplicit="0">in</Direction><Discussion><Para> Aaa. </Para></Discussion></Parameter></Parameters></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph IsWhitespace
@@ -273,9 +301,9 @@
 
 /// \param x1 Aaa.
 /// \param ... Bbb.
-void comment_to_html_conversion_17(int x1, ...);
+void test_cmd_param_6(int x1, ...);
 
-// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=comment_to_html_conversion_17:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-0">x1</dt><dd class="param-descr-index-0"> Aaa. </dd><dt class="param-name-index-vararg">...</dt><dd class="param-descr-index-vararg"> Bbb.</dd></dl>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>comment_to_html_conversion_17</Name><USR>c:@F@comment_to_html_conversion_17#I.#</USR><Declaration>void comment_to_html_conversion_17(int x1, ...)</Declaration><Parameters><Parameter><Name>x1</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Aaa. </Para></Discussion></Parameter><Parameter><Name>...</Name><IsVarArg /><Direction isExplicit="0">in</Direction><Discussion><Para> Bbb.</Para></Discussion></Parameter></Parameters></Function>]
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=test_cmd_param_6:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-0">x1</dt><dd class="param-descr-index-0"> Aaa. </dd><dt class="param-name-index-vararg">...</dt><dd class="param-descr-index-vararg"> Bbb.</dd></dl>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>test_cmd_param_6</Name><USR>c:@F@test_cmd_param_6#I.#</USR><Declaration>void test_cmd_param_6(int x1, ...)</Declaration><Parameters><Parameter><Name>x1</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Aaa. </Para></Discussion></Parameter><Parameter><Name>...</Name><IsVarArg /><Direction isExplicit="0">in</Direction><Discussion><Para> Bbb.</Para></Discussion></Parameter></Parameters></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph IsWhitespace
@@ -286,14 +314,18 @@
 // CHECK-NEXT:           (CXComment_Text Text=[ ] IsWhitespace)))
 // CHECK-NEXT:       (CXComment_ParamCommand in implicitly ParamName=[...] ParamIndex=4294967295
 // CHECK-NEXT:         (CXComment_Paragraph
-// CHECK-NEXT:           (CXComment_Text Text=[ Bbb.]))))] Extent=[276:1 - 276:48]
+// CHECK-NEXT:           (CXComment_Text Text=[ Bbb.]))))]
+
+//===---
+// Tests for \tparam.
+//===---
 
 /// \tparam
 /// \param aaa Blah blah
 template<typename T>
-void comment_to_html_conversion_18(T aaa);
+void test_cmd_tparam_1(T aaa);
 
-// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionTemplate=comment_to_html_conversion_18:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-0">aaa</dt><dd class="param-descr-index-0"> Blah blah</dd></dl>] FullCommentAsXML=[<Function templateKind="template" file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>comment_to_html_conversion_18</Name><USR>c:@FT@&gt;1#Tcomment_to_html_conversion_18#t0.0#</USR><Declaration>template &lt;typename T&gt; void comment_to_html_conversion_18(T aaa)</Declaration><Parameters><Parameter><Name>aaa</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Blah blah</Para></Discussion></Parameter></Parameters></Function>]
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionTemplate=test_cmd_tparam_1:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-0">aaa</dt><dd class="param-descr-index-0"> Blah blah</dd></dl>] FullCommentAsXML=[<Function templateKind="template" file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>test_cmd_tparam_1</Name><USR>c:@FT@&gt;1#Ttest_cmd_tparam_1#t0.0#</USR><Declaration>template &lt;typename T&gt; void test_cmd_tparam_1(T aaa)</Declaration><Parameters><Parameter><Name>aaa</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Blah blah</Para></Discussion></Parameter></Parameters></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph IsWhitespace
@@ -308,9 +340,9 @@
 /// \tparam T
 /// \param aaa Blah blah
 template<typename T>
-void comment_to_html_conversion_19(T aaa);
+void test_cmd_tparam_2(T aaa);
 
-// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionTemplate=comment_to_html_conversion_19:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-0">aaa</dt><dd class="param-descr-index-0"> Blah blah</dd></dl>] FullCommentAsXML=[<Function templateKind="template" file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>comment_to_html_conversion_19</Name><USR>c:@FT@&gt;1#Tcomment_to_html_conversion_19#t0.0#</USR><Declaration>template &lt;typename T&gt; void comment_to_html_conversion_19(T aaa)</Declaration><Parameters><Parameter><Name>aaa</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Blah blah</Para></Discussion></Parameter></Parameters></Function>]
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionTemplate=test_cmd_tparam_2:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-0">aaa</dt><dd class="param-descr-index-0"> Blah blah</dd></dl>] FullCommentAsXML=[<Function templateKind="template" file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>test_cmd_tparam_2</Name><USR>c:@FT@&gt;1#Ttest_cmd_tparam_2#t0.0#</USR><Declaration>template &lt;typename T&gt; void test_cmd_tparam_2(T aaa)</Declaration><Parameters><Parameter><Name>aaa</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Blah blah</Para></Discussion></Parameter></Parameters></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph IsWhitespace
@@ -325,9 +357,9 @@
 /// \tparam T2 Bbb
 /// \tparam T1 Aaa
 template<typename T1, typename T2>
-void comment_to_html_conversion_20(T1 aaa, T2 bbb);
+void test_cmd_tparam_3(T1 aaa, T2 bbb);
 
-// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionTemplate=comment_to_html_conversion_20:{{.*}} FullCommentAsHTML=[<dl><dt class="tparam-name-index-0">T1</dt><dd class="tparam-descr-index-0"> Aaa</dd><dt class="tparam-name-index-1">T2</dt><dd class="tparam-descr-index-1"> Bbb </dd></dl>] FullCommentAsXML=[<Function templateKind="template" file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>comment_to_html_conversion_20</Name><USR>c:@FT@&gt;2#T#Tcomment_to_html_conversion_20#t0.0#t0.1#</USR><Declaration>template &lt;typename T1, typename T2&gt;\nvoid comment_to_html_conversion_20(T1 aaa, T2 bbb)</Declaration><TemplateParameters><Parameter><Name>T1</Name><Index>0</Index><Discussion><Para> Aaa</Para></Discussion></Parameter><Parameter><Name>T2</Name><Index>1</Index><Discussion><Para> Bbb </Para></Discussion></Parameter></TemplateParameters></Function>]
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionTemplate=test_cmd_tparam_3:{{.*}} FullCommentAsHTML=[<dl><dt class="tparam-name-index-0">T1</dt><dd class="tparam-descr-index-0"> Aaa</dd><dt class="tparam-name-index-1">T2</dt><dd class="tparam-descr-index-1"> Bbb </dd></dl>] FullCommentAsXML=[<Function templateKind="template" file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>test_cmd_tparam_3</Name><USR>c:@FT@&gt;2#T#Ttest_cmd_tparam_3#t0.0#t0.1#</USR><Declaration>template &lt;typename T1, typename T2&gt; void test_cmd_tparam_3(T1 aaa, T2 bbb)</Declaration><TemplateParameters><Parameter><Name>T1</Name><Index>0</Index><Discussion><Para> Aaa</Para></Discussion></Parameter><Parameter><Name>T2</Name><Index>1</Index><Discussion><Para> Bbb </Para></Discussion></Parameter></TemplateParameters></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph IsWhitespace
@@ -345,9 +377,9 @@
 /// \tparam V Ccc
 /// \tparam T1 Aaa
 template<typename T1, typename T2, int V>
-void comment_to_html_conversion_21(T1 aaa, T2 bbb);
+void test_cmd_tparam_4(T1 aaa, T2 bbb);
 
-// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionTemplate=comment_to_html_conversion_21:{{.*}} FullCommentAsHTML=[<dl><dt class="tparam-name-index-0">T1</dt><dd class="tparam-descr-index-0"> Aaa</dd><dt class="tparam-name-index-1">T2</dt><dd class="tparam-descr-index-1"> Bbb </dd><dt class="tparam-name-index-2">V</dt><dd class="tparam-descr-index-2"> Ccc </dd><dt class="tparam-name-index-invalid">U</dt><dd class="tparam-descr-index-invalid"> Zzz </dd></dl>] FullCommentAsXML=[<Function templateKind="template" file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>comment_to_html_conversion_21</Name><USR>c:@FT@&gt;3#T#T#NIcomment_to_html_conversion_21#t0.0#t0.1#</USR><Declaration>template &lt;typename T1, typename T2, int V&gt;\nvoid comment_to_html_conversion_21(T1 aaa, T2 bbb)</Declaration><TemplateParameters><Parameter><Name>T1</Name><Index>0</Index><Discussion><Para> Aaa</Para></Discussion></Parameter><Parameter><Name>T2</Name><Index>1</Index><Discussion><Para> Bbb </Para></Discussion></Parameter><Parameter><Name>V</Name><Index>2</Index><Discussion><Para> Ccc </Para></Discussion></Parameter><Parameter><Name>U</Name><Discussion><Para> Zzz </Para></Discussion></Parameter></TemplateParameters></Function>]
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionTemplate=test_cmd_tparam_4:{{.*}} FullCommentAsHTML=[<dl><dt class="tparam-name-index-0">T1</dt><dd class="tparam-descr-index-0"> Aaa</dd><dt class="tparam-name-index-1">T2</dt><dd class="tparam-descr-index-1"> Bbb </dd><dt class="tparam-name-index-2">V</dt><dd class="tparam-descr-index-2"> Ccc </dd><dt class="tparam-name-index-invalid">U</dt><dd class="tparam-descr-index-invalid"> Zzz </dd></dl>] FullCommentAsXML=[<Function templateKind="template" file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>test_cmd_tparam_4</Name><USR>c:@FT@&gt;3#T#T#NItest_cmd_tparam_4#t0.0#t0.1#</USR><Declaration>template &lt;typename T1, typename T2, int V&gt;\nvoid test_cmd_tparam_4(T1 aaa, T2 bbb)</Declaration><TemplateParameters><Parameter><Name>T1</Name><Index>0</Index><Discussion><Para> Aaa</Para></Discussion></Parameter><Parameter><Name>T2</Name><Index>1</Index><Discussion><Para> Bbb </Para></Discussion></Parameter><Parameter><Name>V</Name><Index>2</Index><Discussion><Para> Ccc </Para></Discussion></Parameter><Parameter><Name>U</Name><Discussion><Para> Zzz </Para></Discussion></Parameter></TemplateParameters></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph IsWhitespace
@@ -373,9 +405,9 @@
 /// \tparam T Aaa
 /// \tparam TT Bbb
 template<template<template<typename T> class TT, class C> class TTT>
-void comment_to_html_conversion_22();
+void test_cmd_tparam_5();
 
-// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionTemplate=comment_to_html_conversion_22:{{.*}} FullCommentAsHTML=[<dl><dt class="tparam-name-index-0">TTT</dt><dd class="tparam-descr-index-0"> Ddd </dd><dt class="tparam-name-index-other">C</dt><dd class="tparam-descr-index-other"> Ccc </dd><dt class="tparam-name-index-other">T</dt><dd class="tparam-descr-index-other"> Aaa </dd><dt class="tparam-name-index-other">TT</dt><dd class="tparam-descr-index-other"> Bbb</dd></dl>] FullCommentAsXML=[<Function templateKind="template" file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>comment_to_html_conversion_22</Name><USR>c:@FT@&gt;1#t&gt;2#t&gt;1#T#Tcomment_to_html_conversion_22#</USR><Declaration>template &lt;template &lt;template &lt;typename T&gt; class TT, class C&gt; class TTT&gt;\nvoid comment_to_html_conversion_22()</Declaration><TemplateParameters><Parameter><Name>TTT</Name><Index>0</Index><Discussion><Para> Ddd </Para></Discussion></Parameter><Parameter><Name>C</Name><Discussion><Para> Ccc </Para></Discussion></Parameter><Parameter><Name>T</Name><Discussion><Para> Aaa </Para></Discussion></Parameter><Parameter><Name>TT</Name><Discussion><Para> Bbb</Para></Discussion></Parameter></TemplateParameters></Function>]
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionTemplate=test_cmd_tparam_5:{{.*}} FullCommentAsHTML=[<dl><dt class="tparam-name-index-0">TTT</dt><dd class="tparam-descr-index-0"> Ddd </dd><dt class="tparam-name-index-other">C</dt><dd class="tparam-descr-index-other"> Ccc </dd><dt class="tparam-name-index-other">T</dt><dd class="tparam-descr-index-other"> Aaa </dd><dt class="tparam-name-index-other">TT</dt><dd class="tparam-descr-index-other"> Bbb</dd></dl>] FullCommentAsXML=[<Function templateKind="template" file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>test_cmd_tparam_5</Name><USR>c:@FT@&gt;1#t&gt;2#t&gt;1#T#Ttest_cmd_tparam_5#</USR><Declaration>template &lt;template &lt;template &lt;typename T&gt; class TT, class C&gt; class TTT&gt;\nvoid test_cmd_tparam_5()</Declaration><TemplateParameters><Parameter><Name>TTT</Name><Index>0</Index><Discussion><Para> Ddd </Para></Discussion></Parameter><Parameter><Name>C</Name><Discussion><Para> Ccc </Para></Discussion></Parameter><Parameter><Name>T</Name><Discussion><Para> Aaa </Para></Discussion></Parameter><Parameter><Name>TT</Name><Discussion><Para> Bbb</Para></Discussion></Parameter></TemplateParameters></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph IsWhitespace
@@ -396,6 +428,10 @@
 // CHECK-NEXT:         (CXComment_Paragraph
 // CHECK-NEXT:           (CXComment_Text Text=[ Bbb]))))]
 
+//===---
+// Tests for interaction between commands.
+//===---
+
 /// \brief Aaa.
 ///
 /// Bbb.
@@ -403,9 +439,9 @@
 /// \param x2 Ddd.
 /// \param x1 Ccc.
 /// \returns Eee.
-void comment_to_html_conversion_23(int x1, int x2);
+void test_full_comment_1(int x1, int x2);
 
-// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=comment_to_html_conversion_23:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p><p> Bbb.</p><dl><dt class="param-name-index-0">x1</dt><dd class="param-descr-index-0"> Ccc. </dd><dt class="param-name-index-1">x2</dt><dd class="param-descr-index-1"> Ddd. </dd></dl><div class="result-discussion"><p class="para-returns"><span class="word-returns">Returns</span>  Eee.</p></div>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>comment_to_html_conversion_23</Name><USR>c:@F@comment_to_html_conversion_23#I#I#</USR><Declaration>void comment_to_html_conversion_23(int x1, int x2)</Declaration><Abstract><Para> Aaa.</Para></Abstract><Parameters><Parameter><Name>x1</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Ccc. </Para></Discussion></Parameter><Parameter><Name>x2</Name><Index>1</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Ddd. </Para></Discussion></Parameter></Parameters><ResultDiscussion><Para> Eee.</Para></ResultDiscussion><Discussion><Para> Bbb.</Para></Discussion></Function>]
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=test_full_comment_1:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p><p> Bbb.</p><dl><dt class="param-name-index-0">x1</dt><dd class="param-descr-index-0"> Ccc. </dd><dt class="param-name-index-1">x2</dt><dd class="param-descr-index-1"> Ddd. </dd></dl><div class="result-discussion"><p class="para-returns"><span class="word-returns">Returns</span>  Eee.</p></div>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>test_full_comment_1</Name><USR>c:@F@test_full_comment_1#I#I#</USR><Declaration>void test_full_comment_1(int x1, int x2)</Declaration><Abstract><Para> Aaa.</Para></Abstract><Parameters><Parameter><Name>x1</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Ccc. </Para></Discussion></Parameter><Parameter><Name>x2</Name><Index>1</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Ddd. </Para></Discussion></Parameter></Parameters><ResultDiscussion><Para> Eee.</Para></ResultDiscussion><Discussion><Para> Bbb.</Para></Discussion></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph IsWhitespace
@@ -429,6 +465,10 @@
 // CHECK-NEXT:         (CXComment_Paragraph
 // CHECK-NEXT:           (CXComment_Text Text=[ Eee.]))))]
 
+//===---
+// Misc tests.
+//===---
+
 /// <br><a href="http://example.com/">Aaa</a>
 void comment_to_html_conversion_24();
 
@@ -653,12 +693,12 @@
 /// &copy; the copyright symbol
 /// &trade; the trade mark symbol
 /// &reg; the registered trade mark symbol
-/// &nbsp; a non breakable space.
+/// &nbsp; a non-breakable space.
 /// &Delta; Greek letter Delta Δ.
 /// &Gamma; Greek letter Gamma Γ.
 void comment_to_html_conversion_35();
 
-// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=comment_to_html_conversion_35:{{.*}} FullCommentAsHTML=[<p class="para-brief"> © the copyright symbol ™ the trade mark symbol ® the registered trade mark symbol   a non breakable space. Δ Greek letter Delta Δ. Γ Greek letter Gamma Γ.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>comment_to_html_conversion_35</Name><USR>c:@F@comment_to_html_conversion_35#</USR><Declaration>void comment_to_html_conversion_35()</Declaration><Abstract><Para> © the copyright symbol ™ the trade mark symbol ® the registered trade mark symbol   a non breakable space. Δ Greek letter Delta Δ. Γ Greek letter Gamma Γ.</Para></Abstract></Function>]
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=comment_to_html_conversion_35:{{.*}} FullCommentAsHTML=[<p class="para-brief"> © the copyright symbol ™ the trade mark symbol ® the registered trade mark symbol   a non-breakable space. Δ Greek letter Delta Δ. Γ Greek letter Gamma Γ.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>comment_to_html_conversion_35</Name><USR>c:@F@comment_to_html_conversion_35#</USR><Declaration>void comment_to_html_conversion_35()</Declaration><Abstract><Para> © the copyright symbol ™ the trade mark symbol ® the registered trade mark symbol   a non-breakable space. Δ Greek letter Delta Δ. Γ Greek letter Gamma Γ.</Para></Abstract></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph
@@ -673,7 +713,7 @@
 // CHECK-NEXT:         (CXComment_Text Text=[ the registered trade mark symbol] HasTrailingNewline)
 // CHECK-NEXT:         (CXComment_Text Text=[ ] IsWhitespace)
 // CHECK-NEXT:         (CXComment_Text Text=[ ])
-// CHECK-NEXT:         (CXComment_Text Text=[ a non breakable space.] HasTrailingNewline)
+// CHECK-NEXT:         (CXComment_Text Text=[ a non-breakable space.] HasTrailingNewline)
 // CHECK-NEXT:         (CXComment_Text Text=[ ] IsWhitespace)
 // CHECK-NEXT:         (CXComment_Text Text=[Δ])
 // CHECK-NEXT:         (CXComment_Text Text=[ Greek letter Delta Δ.] HasTrailingNewline)
@@ -681,6 +721,18 @@
 // CHECK-NEXT:         (CXComment_Text Text=[Γ])
 // CHECK-NEXT:         (CXComment_Text Text=[ Greek letter Gamma Γ.])))]
 
+/// <h1 id="]]>">Aaa</h1>
+void comment_to_html_conversion_36();
+
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:6: FunctionDecl=comment_to_html_conversion_36:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <h1 id="]]>">Aaa</h1></p>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="6"><Name>comment_to_html_conversion_36</Name><USR>c:@F@comment_to_html_conversion_36#</USR><Declaration>void comment_to_html_conversion_36()</Declaration><Abstract><Para> <rawHTML><![CDATA[<h1 id="]]]]><![CDATA[>">]]></rawHTML>Aaa<rawHTML>&lt;/h1&gt;</rawHTML></Para></Abstract></Function>]
+// CHECK-NEXT:  CommentAST=[
+// CHECK-NEXT:    (CXComment_FullComment
+// CHECK-NEXT:       (CXComment_Paragraph
+// CHECK-NEXT:         (CXComment_Text Text=[ ] IsWhitespace)
+// CHECK-NEXT:         (CXComment_HTMLStartTag Name=[h1] Attrs: id=]]>)
+// CHECK-NEXT:         (CXComment_Text Text=[Aaa])
+// CHECK-NEXT:         (CXComment_HTMLEndTag Name=[h1])))]
+
 
 /// Aaa.
 class comment_to_xml_conversion_01 {
@@ -694,7 +746,7 @@
   /// Aaa.
   ~comment_to_xml_conversion_01();
 
-// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:3: CXXDestructor=~comment_to_xml_conversion_01:{{.*}} FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="3"><Name>~comment_to_xml_conversion_01</Name><USR>c:@C@comment_to_xml_conversion_01@F@~comment_to_xml_conversion_01#</USR><Declaration>void ~comment_to_xml_conversion_01()</Declaration><Abstract><Para> Aaa.</Para></Abstract></Function>]
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:3: CXXDestructor=~comment_to_xml_conversion_01:{{.*}} FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="3"><Name>~comment_to_xml_conversion_01</Name><USR>c:@C@comment_to_xml_conversion_01@F@~comment_to_xml_conversion_01#</USR><Declaration>~comment_to_xml_conversion_01()</Declaration><Abstract><Para> Aaa.</Para></Abstract></Function>]
 
   /// \param aaa Blah blah.
   int comment_to_xml_conversion_02(int aaa);
@@ -724,7 +776,7 @@
   /// Aaa.
   operator bool();
 
-// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:3: CXXConversion=operator _Bool:{{.*}} FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="3"><Name>operator _Bool</Name><USR>c:@C@comment_to_xml_conversion_01@F@operator _Bool#</USR><Declaration>bool operator _Bool()</Declaration><Abstract><Para> Aaa.</Para></Abstract></Function>]
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-2]]:3: CXXConversion=operator bool:{{.*}} FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-2]]" column="3"><Name>operator bool</Name><USR>c:@C@comment_to_xml_conversion_01@F@operator bool#</USR><Declaration>operator bool()</Declaration><Abstract><Para> Aaa.</Para></Abstract></Function>]
 
   /// Aaa.
   typedef int comment_to_xml_conversion_06;
@@ -813,6 +865,34 @@
 // CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-1]]:3: EnumConstantDecl=comment_to_xml_conversion_18:{{.*}} FullCommentAsXML=[<Variable file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-1]]" column="3"><Name>comment_to_xml_conversion_18</Name><USR>c:@E@comment_to_xml_conversion_17@comment_to_xml_conversion_18</USR><Declaration>comment_to_xml_conversion_18</Declaration><Abstract><Para> Aaa.</Para></Abstract></Variable>]
 };
 
+/// <a href="http://example.org/">
+void comment_to_xml_conversion_unsafe_html_01();
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-1]]:6: FunctionDecl=comment_to_xml_conversion_unsafe_html_01:{{.*}} FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-1]]" column="6"><Name>comment_to_xml_conversion_unsafe_html_01</Name><USR>c:@F@comment_to_xml_conversion_unsafe_html_01#</USR><Declaration>void comment_to_xml_conversion_unsafe_html_01()</Declaration><Abstract><Para> <rawHTML isMalformed="1"><![CDATA[<a href="http://example.org/">]]></rawHTML></Para></Abstract></Function>]
+
+/// <a href="http://example.org/"><em>Aaa</em>
+void comment_to_xml_conversion_unsafe_html_02();
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-1]]:6: FunctionDecl=comment_to_xml_conversion_unsafe_html_02:{{.*}} FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-1]]" column="6"><Name>comment_to_xml_conversion_unsafe_html_02</Name><USR>c:@F@comment_to_xml_conversion_unsafe_html_02#</USR><Declaration>void comment_to_xml_conversion_unsafe_html_02()</Declaration><Abstract><Para> <rawHTML isMalformed="1"><![CDATA[<a href="http://example.org/">]]></rawHTML><rawHTML><![CDATA[<em>]]></rawHTML>Aaa<rawHTML>&lt;/em&gt;</rawHTML></Para></Abstract></Function>]
+
+/// <em>Aaa
+void comment_to_xml_conversion_unsafe_html_03();
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-1]]:6: FunctionDecl=comment_to_xml_conversion_unsafe_html_03:{{.*}} FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-1]]" column="6"><Name>comment_to_xml_conversion_unsafe_html_03</Name><USR>c:@F@comment_to_xml_conversion_unsafe_html_03#</USR><Declaration>void comment_to_xml_conversion_unsafe_html_03()</Declaration><Abstract><Para> <rawHTML isMalformed="1"><![CDATA[<em>]]></rawHTML>Aaa</Para></Abstract></Function>]
+
+/// <em>Aaa</b></em>
+void comment_to_xml_conversion_unsafe_html_04();
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-1]]:6: FunctionDecl=comment_to_xml_conversion_unsafe_html_04:{{.*}} FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-1]]" column="6"><Name>comment_to_xml_conversion_unsafe_html_04</Name><USR>c:@F@comment_to_xml_conversion_unsafe_html_04#</USR><Declaration>void comment_to_xml_conversion_unsafe_html_04()</Declaration><Abstract><Para> <rawHTML><![CDATA[<em>]]></rawHTML>Aaa<rawHTML isMalformed="1">&lt;/b&gt;</rawHTML><rawHTML>&lt;/em&gt;</rawHTML></Para></Abstract></Function>]
+
+/// <em>Aaa</em></b>
+void comment_to_xml_conversion_unsafe_html_05();
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-1]]:6: FunctionDecl=comment_to_xml_conversion_unsafe_html_05:{{.*}} FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-1]]" column="6"><Name>comment_to_xml_conversion_unsafe_html_05</Name><USR>c:@F@comment_to_xml_conversion_unsafe_html_05#</USR><Declaration>void comment_to_xml_conversion_unsafe_html_05()</Declaration><Abstract><Para> <rawHTML><![CDATA[<em>]]></rawHTML>Aaa<rawHTML>&lt;/em&gt;</rawHTML><rawHTML isMalformed="1">&lt;/b&gt;</rawHTML></Para></Abstract></Function>]
+
+/// </table>
+void comment_to_xml_conversion_unsafe_html_06();
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-1]]:6: FunctionDecl=comment_to_xml_conversion_unsafe_html_06:{{.*}} FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-1]]" column="6"><Name>comment_to_xml_conversion_unsafe_html_06</Name><USR>c:@F@comment_to_xml_conversion_unsafe_html_06#</USR><Declaration>void comment_to_xml_conversion_unsafe_html_06()</Declaration><Abstract><Para> <rawHTML isMalformed="1">&lt;/table&gt;</rawHTML></Para></Abstract></Function>]
+
+/// <div onclick="alert('meow');">Aaa</div>
+void comment_to_xml_conversion_unsafe_html_07();
+// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-1]]:6: FunctionDecl=comment_to_xml_conversion_unsafe_html_07:{{.*}} FullCommentAsXML=[<Function file="{{[^"]+}}comment-to-html-xml-conversion.cpp" line="[[@LINE-1]]" column="6"><Name>comment_to_xml_conversion_unsafe_html_07</Name><USR>c:@F@comment_to_xml_conversion_unsafe_html_07#</USR><Declaration>void comment_to_xml_conversion_unsafe_html_07()</Declaration><Abstract><Para> <rawHTML><![CDATA[<div onclick="alert('meow');">]]></rawHTML>Aaa<rawHTML>&lt;/div&gt;</rawHTML></Para></Abstract></Function>]
+
 //===---
 // Check that we attach comments from the base class to derived classes if they don't have a comment.
 // rdar://13647476
@@ -975,17 +1055,5 @@
 // CHECK-NEXT:         (CXComment_Paragraph
 // CHECK-NEXT:           (CXComment_Text Text=[ Ccc.]))))]
 
-
-// rdar://14348912
-#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
-
-/**! Documentation comment */
-typedef NS_ENUM(int, Color) { Red, Green, Blue };
-// CHECK: comment-to-html-xml-conversion.cpp:[[@LINE-1]]:22: TypedefDecl=Color:[[@LINE-1]]:22
-// CHECK-NEXT:  CommentAST=[
-// CHECK-NEXT:    (CXComment_FullComment
-// CHECK-NEXT:       (CXComment_Paragraph
-// CHECK-NEXT:         (CXComment_Text Text=[! Documentation comment ])))] 
-
 #endif
 
diff --git a/test/Index/comment-xml-schema.c b/test/Index/comment-xml-schema.c
index 2bbdfcf..37cb47c 100644
--- a/test/Index/comment-xml-schema.c
+++ b/test/Index/comment-xml-schema.c
@@ -11,6 +11,7 @@
 // RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-function-07.xml
 // RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-function-08.xml
 // RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-function-09.xml
+// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-function-10.xml
 //
 // RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-availability-attr-01.xml
 // RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-availability-attr-02.xml
diff --git a/test/Index/complete-macros.c b/test/Index/complete-macros.c
index 6d27b44..c81c8ca 100644
--- a/test/Index/complete-macros.c
+++ b/test/Index/complete-macros.c
@@ -1,5 +1,5 @@
-// Note: the run lines follow their respective tests, since line/column
-// matter in this test.
+#include "complete-macros.h"
+// Note: the run lines follow their respective tests, since line/column matter in this test.
 #define FOO(Arg1,Arg2) foobar
 #define nil 0
 #undef FOO
@@ -25,20 +25,23 @@
   
 }
 
-// RUN: c-index-test -code-completion-at=%s:7:1 %s | FileCheck -check-prefix=CHECK-CC0 %s
+// RUN: c-index-test -code-completion-at=%s:7:1 %s -I%S | FileCheck -check-prefix=CHECK-CC0 %s
 // CHECK-CC0-NOT: FOO
-// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:7:1 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:7:1 %s -I%S | FileCheck -check-prefix=CHECK-CC1 %s
 // CHECK-CC1: macro definition:{TypedText FOO}{LeftParen (}{Placeholder Arg1}{Comma , }{Placeholder Arg2}{RightParen )}
-// RUN: c-index-test -code-completion-at=%s:13:13 %s | FileCheck -check-prefix=CHECK-CC2 %s
-// RUN: c-index-test -code-completion-at=%s:14:8 %s | FileCheck -check-prefix=CHECK-CC2 %s
-// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:14:8 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// RUN: c-index-test -code-completion-at=%s:13:13 %s -I%S | FileCheck -check-prefix=CHECK-CC2 %s
+// RUN: c-index-test -code-completion-at=%s:14:8 %s -I%S | FileCheck -check-prefix=CHECK-CC2 %s
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:14:8 %s -I%S | FileCheck -check-prefix=CHECK-CC2 %s
 // CHECK-CC2: macro definition:{TypedText nil} (32)
-// RUN: c-index-test -code-completion-at=%s:15:5 %s | FileCheck -check-prefix=CHECK-CC3 %s
-// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:15:5 %s | FileCheck -check-prefix=CHECK-CC3 %s
+// RUN: c-index-test -code-completion-at=%s:15:5 %s -I%S | FileCheck -check-prefix=CHECK-CC3 %s
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:15:5 %s -I%S | FileCheck -check-prefix=CHECK-CC3 %s
 // CHECK-CC3: macro definition:{TypedText nil} (65)
-// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:25:2 %s | FileCheck -check-prefix=CHECK-VARIADIC %s
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:25:2 %s -I%S | FileCheck -check-prefix=CHECK-VARIADIC %s
 // CHECK-VARIADIC: macro definition:{TypedText variadic1}{LeftParen (}{Placeholder ...}{RightParen )} (70)
 // CHECK-VARIADIC: macro definition:{TypedText variadic2}{LeftParen (}{Placeholder args...}{RightParen )} (70)
 // CHECK-VARIADIC: macro definition:{TypedText variadic3}{LeftParen (}{Placeholder args, ...}{RightParen )} (70)
 // CHECK-VARIADIC: macro definition:{TypedText variadic4}{LeftParen (}{Placeholder first}{Comma , }{Placeholder second}{Comma , }{Placeholder args, ...}{RightParen )} (70)
 // CHECK-VARIADIC: macro definition:{TypedText variadic5}{LeftParen (}{Placeholder first}{Comma , }{Placeholder second}{Comma , }{Placeholder args...}{RightParen )} (70)
+
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:15:5 %s -I%S | FileCheck -check-prefix=CHECK-CC4 %s
+// CHECK-CC4-NOT: COMPLETE_MACROS_H_GUARD
diff --git a/test/Index/complete-macros.h b/test/Index/complete-macros.h
new file mode 100644
index 0000000..70f49e3
--- /dev/null
+++ b/test/Index/complete-macros.h
@@ -0,0 +1,6 @@
+#ifndef COMPLETE_MACROS_H_GUARD
+#define COMPLETE_MACROS_H_GUARD
+
+void in_header(int);
+
+#endif
diff --git a/test/Index/complete-method-decls.m b/test/Index/complete-method-decls.m
index 9e52d93..eceaa83 100644
--- a/test/Index/complete-method-decls.m
+++ b/test/Index/complete-method-decls.m
@@ -72,6 +72,19 @@
 - (oneway void)method:(in id x) {}
 @end
 
+typedef A MyObject;
+typedef A *MyObjectRef;
+
+@interface I1
+-(Class<P1>)meth;
+-(MyObject <P1> *)meth2;
+-(MyObjectRef)meth3;
+@end
+
+@implementation I1
+-
+@end
+
 // RUN: c-index-test -code-completion-at=%s:17:3 %s | FileCheck -check-prefix=CHECK-CC1 %s
 // CHECK-CC1: ObjCInstanceMethodDecl:{LeftParen (}{Text id}{RightParen )}{TypedText abc} (40)
 // CHECK-CC1: ObjCInstanceMethodDecl:{LeftParen (}{Text int}{RightParen )}{TypedText getInt} (40)
@@ -182,3 +195,9 @@
 
 // RUN: c-index-test -code-completion-at=%s:72:2 %s | FileCheck -check-prefix=CHECK-ONEWAY %s
 // CHECK-ONEWAY: ObjCInstanceMethodDecl:{LeftParen (}{Text oneway }{Text void}{RightParen )}{TypedText method}{TypedText :}{LeftParen (}{Text in }{Text id}{RightParen )}{Text x} (40)
+
+// RUN: c-index-test -code-completion-at=%s:85:2 %s | FileCheck -check-prefix=CHECK-CLASSTY %s
+// CHECK-CLASSTY: ObjCInstanceMethodDecl:{LeftParen (}{Text Class<P1>}{RightParen )}{TypedText meth}
+// FIXME: It should be "MyObject <P1> *""
+// CHECK-CLASSTY: ObjCInstanceMethodDecl:{LeftParen (}{Text A<P1> *}{RightParen )}{TypedText meth2}
+// CHECK-CLASSTY: ObjCInstanceMethodDecl:{LeftParen (}{Text MyObjectRef}{RightParen )}{TypedText meth3}
diff --git a/test/Index/complete-property-flags.m b/test/Index/complete-property-flags.m
index 86ee8e2..13ec1e7 100644
--- a/test/Index/complete-property-flags.m
+++ b/test/Index/complete-property-flags.m
@@ -11,12 +11,12 @@
 // CHECK-CC1: {TypedText assign}
 // CHECK-CC1-NEXT: {TypedText atomic}
 // CHECK-CC1-NEXT: {TypedText copy}
-// CHECK-CC1-NEXT: {TypedText getter}{Text  = }{Placeholder method}
+// CHECK-CC1-NEXT: {TypedText getter}{Text =}{Placeholder method}
 // CHECK-CC1-NEXT: {TypedText nonatomic}
 // CHECK-CC1-NEXT: {TypedText readonly}
 // CHECK-CC1-NEXT: {TypedText readwrite}
 // CHECK-CC1-NEXT: {TypedText retain}
-// CHECK-CC1-NEXT: {TypedText setter}{Text  = }{Placeholder method}
+// CHECK-CC1-NEXT: {TypedText setter}{Text =}{Placeholder method}
 // CHECK-CC1-NEXT: {TypedText strong}
 // CHECK-CC1-NEXT: {TypedText unsafe_unretained}
 // CHECK-CC1-NOT: {TypedText weak}
@@ -25,20 +25,20 @@
 // CHECK-CC1-ARC: {TypedText assign}
 // CHECK-CC1-ARC-NEXT: {TypedText atomic}
 // CHECK-CC1-ARC-NEXT: {TypedText copy}
-// CHECK-CC1-ARC-NEXT: {TypedText getter}{Text  = }{Placeholder method}
+// CHECK-CC1-ARC-NEXT: {TypedText getter}{Text =}{Placeholder method}
 // CHECK-CC1-ARC-NEXT: {TypedText nonatomic}
 // CHECK-CC1-ARC-NEXT: {TypedText readonly}
 // CHECK-CC1-ARC-NEXT: {TypedText readwrite}
 // CHECK-CC1-ARC-NEXT: {TypedText retain}
-// CHECK-CC1-ARC-NEXT: {TypedText setter}{Text  = }{Placeholder method}
+// CHECK-CC1-ARC-NEXT: {TypedText setter}{Text =}{Placeholder method}
 // CHECK-CC1-ARC-NEXT: {TypedText strong}
 // CHECK-CC1-ARC-NEXT: {TypedText unsafe_unretained}
 // CHECK-CC1-ARC-NEXT: {TypedText weak}
 
 // RUN: c-index-test -code-completion-at=%s:8:18 %s | FileCheck -check-prefix=CHECK-CC2 %s
-// CHECK-CC2: {TypedText getter}{Text  = }{Placeholder method}
+// CHECK-CC2: {TypedText getter}{Text =}{Placeholder method}
 // CHECK-CC2-NEXT: {TypedText nonatomic}
 // CHECK-CC2-NEXT: {TypedText readonly}
 // CHECK-CC2-NEXT: {TypedText readwrite}
-// CHECK-CC2-NEXT: {TypedText setter}{Text  = }{Placeholder method}
+// CHECK-CC2-NEXT: {TypedText setter}{Text =}{Placeholder method}
 @end
diff --git a/test/Index/complete-recovery.m b/test/Index/complete-recovery.m
index 19de0fb..ec5bf8a 100644
--- a/test/Index/complete-recovery.m
+++ b/test/Index/complete-recovery.m
@@ -23,7 +23,7 @@
 // CHECK-CC1: VarDecl:{ResultType A *}{TypedText a}
 // CHECK-CC1: NotImplemented:{ResultType size_t}{TypedText sizeof}{LeftParen (}{Placeholder expression-or-type}{RightParen )}
 
-// Test case for fix comitted in r145441. 
+// Test case for fix committed in r145441.
 // RUN: env CINDEXTEST_CODE_COMPLETE_PATTERNS=1 c-index-test -code-completion-at=%s:9:20 %s -fms-compatibility | FileCheck -check-prefix=CHECK-CC1 %s
 
 // RUN: env CINDEXTEST_CODE_COMPLETE_PATTERNS=1 c-index-test -code-completion-at=%s:10:24 %s | FileCheck -check-prefix=CHECK-CC2 %s
diff --git a/test/Index/crash-recovery-code-complete.c b/test/Index/crash-recovery-code-complete.c
index c502ce5..b2a1a9b 100644
--- a/test/Index/crash-recovery-code-complete.c
+++ b/test/Index/crash-recovery-code-complete.c
@@ -1,6 +1,6 @@
 // RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_PREAMBLE_FILE=%t-preamble.pch \
 // RUN:   not c-index-test -code-completion-at=%s:20:1 \
-// RUN:   "-remap-file=%s;%S/Inputs/crash-recovery-code-complete-remap.c" \
+// RUN:   "-remap-file=%s,%S/Inputs/crash-recovery-code-complete-remap.c" \
 // RUN:   %s 2> %t.err
 // RUN: FileCheck < %t.err -check-prefix=CHECK-CODE-COMPLETE-CRASH %s
 // RUN: test ! -e %t-preamble.pch
@@ -9,6 +9,6 @@
 // REQUIRES: crash-recovery
 
 // FIXME: Please investigate abnormal path in MemoryBuffer.
-// XFAIL: mingw32,win32
+// REQUIRES: can-remove-opened-file
 
 #warning parsing original file
diff --git a/test/Index/crash-recovery-reparse.c b/test/Index/crash-recovery-reparse.c
index e3f7265..baa6604 100644
--- a/test/Index/crash-recovery-reparse.c
+++ b/test/Index/crash-recovery-reparse.c
@@ -1,6 +1,6 @@
 // RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_PREAMBLE_FILE=%t-preamble.pch \
 // RUN:   not c-index-test -test-load-source-reparse 1 local \
-// RUN:   -remap-file="%s;%S/Inputs/crash-recovery-reparse-remap.c" \
+// RUN:   -remap-file="%s,%S/Inputs/crash-recovery-reparse-remap.c" \
 // RUN:   %s 2> %t.err
 // RUN: FileCheck < %t.err -check-prefix=CHECK-REPARSE-SOURCE-CRASH %s
 // RUN: test ! -e $t-preamble.pch
diff --git a/test/Index/crash-recovery.c b/test/Index/crash-recovery.c
index b7f6e0b..e8e84bc 100644
--- a/test/Index/crash-recovery.c
+++ b/test/Index/crash-recovery.c
@@ -1,6 +1,7 @@
 // RUN: not c-index-test -test-load-source all %s 2> %t.err
 // RUN: FileCheck < %t.err -check-prefix=CHECK-LOAD-SOURCE-CRASH %s
 // CHECK-LOAD-SOURCE-CRASH: Unable to load translation unit
+// RUN: env LIBCLANG_DISABLE_CRASH_RECOVERY=1 not --crash c-index-test -test-load-source all %s
 //
 // REQUIRES: crash-recovery
 
diff --git a/test/Index/cxx11-lambdas.cpp b/test/Index/cxx11-lambdas.cpp
index 93db022..afb540a 100644
--- a/test/Index/cxx11-lambdas.cpp
+++ b/test/Index/cxx11-lambdas.cpp
@@ -26,8 +26,8 @@
 // RUN: env CINDEXTEST_INDEXLOCALSYMBOLS=1 c-index-test -index-file -std=c++11 %s | FileCheck -check-prefix=CHECK-INDEX %s
 // CHECK-INDEX: [indexEntityReference]: kind: variable | name: localA | USR: c:cxx11-lambdas.cpp@100@S@X@F@f#@localA | lang: C | cursor: VariableRef=localA:6:9 | loc: 7:21
 // CHECK-INDEX: [indexEntityReference]: kind: variable | name: localB | USR: c:cxx11-lambdas.cpp@100@S@X@F@f#@localB | lang: C | cursor: VariableRef=localB:6:17 | loc: 7:29
-// CHECK-INDEX: [indexEntityReference]: kind: typedef | name: Integer | USR: c:cxx11-lambdas.cpp@51@T@Integer | lang: C | cursor: TypeRef=Integer:3:13 | loc: 7:52
-// CHECK-INDEX: [indexEntityReference]: kind: typedef | name: Integer | USR: c:cxx11-lambdas.cpp@51@T@Integer | lang: C | cursor: TypeRef=Integer:3:13 | loc: 7:38
+// CHECK-INDEX: [indexEntityReference]: kind: typedef | name: Integer | USR: c:cxx11-lambdas.cpp@T@Integer | lang: C | cursor: TypeRef=Integer:3:13 | loc: 7:52
+// CHECK-INDEX: [indexEntityReference]: kind: typedef | name: Integer | USR: c:cxx11-lambdas.cpp@T@Integer | lang: C | cursor: TypeRef=Integer:3:13 | loc: 7:38
 // CHECK-INDEX: [indexEntityReference]: kind: variable | name: localA | USR: c:cxx11-lambdas.cpp@100@S@X@F@f#@localA | lang: C | cursor: DeclRefExpr=localA:6:9 | loc: 8:14
 // CHECK-INDEX: [indexEntityReference]: kind: variable | name: localB | USR: c:cxx11-lambdas.cpp@100@S@X@F@f#@localB | lang: C | cursor: DeclRefExpr=localB:6:17 | loc: 8:23
 // CHECK-INDEX: [indexEntityReference]: kind: variable | name: x | USR: c:cxx11-lambdas.cpp@157@S@X@F@f#@Ca@F@operator()#I#1@x | lang: C | cursor: DeclRefExpr=x:7:46 | loc: 8:32
diff --git a/test/Index/fix-its.m b/test/Index/fix-its.m
index b307cf4..fabcdb2 100644
--- a/test/Index/fix-its.m
+++ b/test/Index/fix-its.m
@@ -24,5 +24,3 @@
 // CHECK: Number FIX-ITs = 0
 // CHECK: fix-its.m:7:77: note: expanded from macro '_rdar_12584554_B'
 // CHECK: Number FIX-ITs = 0
-// CHECK: fix-its.m:5:172: note: passing argument to parameter 'msgFormat' here
-// CHECK: Number FIX-ITs = 0
diff --git a/test/Index/index-module-with-vfs.m b/test/Index/index-module-with-vfs.m
new file mode 100644
index 0000000..f3ca60c
--- /dev/null
+++ b/test/Index/index-module-with-vfs.m
@@ -0,0 +1,26 @@
+// REQUIRES: shell
+@import ModuleNeedsVFS;
+
+void foo() {
+  module_needs_vfs();
+  base_module_needs_vfs();
+}
+
+// RUN: rm -rf %t.cache
+// RUN: sed -e "s:INPUT_DIR:%S/Inputs:g" -e "s:OUT_DIR:%t:g" %S/Inputs/vfsoverlay.yaml > %t.yaml
+// RUN: c-index-test -index-file %s -fmodules-cache-path=%t.cache -fmodules -F %t -I %t \
+// RUN:              -ivfsoverlay %t.yaml -Xclang -fdisable-module-hash | FileCheck %s
+
+// CHECK: [importedASTFile]: {{.*}}ModuleNeedsVFS.pcm | loc: 2:1 | name: "ModuleNeedsVFS" | isImplicit: 0
+// CHECK: [indexEntityReference]: kind: function | name: module_needs_vfs
+// CHECK: [indexEntityReference]: kind: function | name: base_module_needs_vfs
+
+// RUN: c-index-test -index-tu %t.cache/ModuleNeedsVFS.pcm | FileCheck %s -check-prefix=CHECK-MOD
+
+// CHECK-MOD: [ppIncludedFile]: {{.*}}module_needs_vfs.h 
+// CHECK-MOD: [importedASTFile]: {{.*}}BaseModuleNeedsVFS.pcm
+// CHECK-MOD: [indexEntityReference]: kind: function | name: base_module_needs_vfs
+
+// RUN: c-index-test -index-tu %t.cache/BaseModuleNeedsVFS.pcm | FileCheck %s -check-prefix=CHECK-MOD2
+
+// CHECK-MOD2: [ppIncludedFile]: {{.*}}base_module_needs_vfs.h
diff --git a/test/Index/index-module.m b/test/Index/index-module.m
index d695313..8e01556 100644
--- a/test/Index/index-module.m
+++ b/test/Index/index-module.m
@@ -18,13 +18,13 @@
 // RUN: c-index-test -index-tu %t.cache/DependsOnModule.pcm | FileCheck %s -check-prefix=CHECK-DMOD
 
 // CHECK-DMOD:      [startedTranslationUnit]
-// CHECK-DMOD-NEXT: [ppIncludedFile]: [[DMOD_MODULE_H:.*/Modules/Inputs/DependsOnModule\.framework[/\\]Headers[/\\]DependsOnModule\.h]] | {{.*}} | hash loc: <invalid>
-// CHECK-DMOD-NEXT: [ppIncludedFile]: {{.*}}/Modules/Inputs/Module.framework{{[/\\]}}Headers{{[/\\]}}Module.h | name: "Module/Module.h" | hash loc: {{.*}}/Modules/Inputs/DependsOnModule.framework{{[/\\]}}Headers{{[/\\]}}DependsOnModule.h:1:1 | isImport: 0 | isAngled: 1 | isModule: 1
-// CHECK-DMOD-NEXT: [ppIncludedFile]: [[DMOD_OTHER_H:.*/Modules/Inputs/DependsOnModule\.framework[/\\]Headers[/\\]other\.h]] | {{.*}} | hash loc: <invalid>
-// CHECK-DMOD-NEXT: [ppIncludedFile]: [[DMOD_NOT_CXX_H:.*/Modules/Inputs/DependsOnModule\.framework[/\\]Headers[/\\]not_cxx\.h]] | {{.*}} | hash loc: <invalid>
-// CHECK-DMOD-NEXT: [ppIncludedFile]: [[DMOD_SUB_H:.*/Modules/Inputs/DependsOnModule\.framework[/\\]Frameworks[/\\]SubFramework\.framework[/\\]Headers[/\\]SubFramework\.h]] | {{.*}} | hash loc: <invalid>
-// CHECK-DMOD-NEXT: [ppIncludedFile]: [[DMOD_SUB_OTHER_H:.*/Modules/Inputs/DependsOnModule.framework[/\\]Frameworks/SubFramework\.framework/Headers/Other\.h]] | name: "SubFramework/Other.h" | hash loc: [[DMOD_SUB_H]]:1:1 | isImport: 0 | isAngled: 0
-// CHECK-DMOD-NEXT: [ppIncludedFile]: [[DMOD_PRIVATE_H:.*/Modules/Inputs/DependsOnModule.framework[/\\]PrivateHeaders[/\\]DependsOnModulePrivate.h]] | {{.*}} | hash loc: <invalid>
+// CHECK-DMOD-NEXT: [ppIncludedFile]: [[DMOD_MODULE_H:.*/Modules/Inputs/DependsOnModule\.framework[/\\]Headers[/\\]DependsOnModule\.h]] | {{.*}} | hash loc: <invalid> | {{.*}} | module: DependsOnModule
+// CHECK-DMOD-NEXT: [ppIncludedFile]: {{.*}}/Modules/Inputs/Module.framework{{[/\\]}}Headers{{[/\\]}}Module.h | name: "Module/Module.h" | hash loc: {{.*}}/Modules/Inputs/DependsOnModule.framework{{[/\\]}}Headers{{[/\\]}}DependsOnModule.h:1:1 | isImport: 0 | isAngled: 1 | isModule: 1 | module: Module
+// CHECK-DMOD-NEXT: [ppIncludedFile]: [[DMOD_OTHER_H:.*/Modules/Inputs/DependsOnModule\.framework[/\\]Headers[/\\]other\.h]] | {{.*}} | hash loc: <invalid> | {{.*}} | module: DependsOnModule
+// CHECK-DMOD-NEXT: [ppIncludedFile]: [[DMOD_NOT_CXX_H:.*/Modules/Inputs/DependsOnModule\.framework[/\\]Headers[/\\]not_cxx\.h]] | {{.*}} | hash loc: <invalid> | {{.*}} | module: DependsOnModule.NotCXX
+// CHECK-DMOD-NEXT: [ppIncludedFile]: [[DMOD_SUB_H:.*/Modules/Inputs/DependsOnModule\.framework[/\\]Frameworks[/\\]SubFramework\.framework[/\\]Headers[/\\]SubFramework\.h]] | {{.*}} | hash loc: <invalid> | {{.*}} | module: DependsOnModule.SubFramework
+// CHECK-DMOD-NEXT: [ppIncludedFile]: [[DMOD_SUB_OTHER_H:.*/Modules/Inputs/DependsOnModule.framework[/\\]Frameworks/SubFramework\.framework/Headers/Other\.h]] | name: "SubFramework/Other.h" | hash loc: [[DMOD_SUB_H]]:1:1 | isImport: 0 | isAngled: 0 | isModule: 0 | module: DependsOnModule.SubFramework.Other
+// CHECK-DMOD-NEXT: [ppIncludedFile]: [[DMOD_PRIVATE_H:.*/Modules/Inputs/DependsOnModule.framework[/\\]PrivateHeaders[/\\]DependsOnModulePrivate.h]] | {{.*}} | hash loc: <invalid> | {{.*}} | module: DependsOnModule.Private.DependsOnModule
 // CHECK-DMOD-NEXT: [importedASTFile]: {{.*}}.cache{{[/\\]}}Module.pcm | loc: [[DMOD_MODULE_H]]:1:2 | name: "Module" | isImplicit: 1
 // CHECK-DMOD-NEXT: [indexDeclaration]: kind: variable | name: depends_on_module_other | {{.*}} | loc: [[DMOD_OTHER_H]]:1:5
 // CHECK-DMOD-NEXT: [indexDeclaration]: kind: variable | name: template | {{.*}} | loc: [[DMOD_NOT_CXX_H]]:1:12
diff --git a/test/Index/index-pch-objc.m b/test/Index/index-pch-objc.m
new file mode 100644
index 0000000..b9b741f
--- /dev/null
+++ b/test/Index/index-pch-objc.m
@@ -0,0 +1,10 @@
+// RUN: c-index-test -write-pch %t.pch -target x86_64-apple-darwin10 %s
+// RUN: env LIBCLANG_NOTHREADS=1 c-index-test -index-tu %t.pch | FileCheck %s
+
+@interface SomeClass
+@property (retain) id foo;
+@end
+@implementation SomeClass
+@end
+
+// CHECK: [indexDeclaration]: kind: objc-ivar | name: _foo
diff --git a/test/Index/index-refs.cpp b/test/Index/index-refs.cpp
index 77e2af7..adbf02a 100644
--- a/test/Index/index-refs.cpp
+++ b/test/Index/index-refs.cpp
@@ -102,7 +102,7 @@
 
 // CHECK:      [indexDeclaration]: kind: c++-class-template | name: TS | {{.*}} | loc: 47:8
 // CHECK-NEXT: [indexDeclaration]: kind: struct-template-partial-spec | name: TS | USR: c:@SP>1#T@TS>#t0.0#I | {{.*}} | loc: 50:8
-// CHECK-NEXT: [indexDeclaration]: kind: typedef | name: MyInt | USR: c:index-refs.cpp@593@SP>1#T@TS>#t0.0#I@T@MyInt | {{.*}} | loc: 51:15 | semantic-container: [TS:50:8] | lexical-container: [TS:50:8]
+// CHECK-NEXT: [indexDeclaration]: kind: typedef | name: MyInt | USR: c:index-refs.cpp@SP>1#T@TS>#t0.0#I@T@MyInt | {{.*}} | loc: 51:15 | semantic-container: [TS:50:8] | lexical-container: [TS:50:8]
 /* when indexing implicit instantiations
   [indexDeclaration]: kind: struct-template-spec | name: TS | USR: c:@S@TS>#I | {{.*}} | loc: 50:8
   [indexDeclaration]: kind: typedef | name: MyInt | USR: c:index-refs.cpp@593@S@TS>#I@T@MyInt | {{.*}} | loc: 51:15 | semantic-container: [TS:50:8] | lexical-container: [TS:50:8]
diff --git a/test/Index/index-templates.cpp b/test/Index/index-templates.cpp
index 05068df..5fcb652 100644
--- a/test/Index/index-templates.cpp
+++ b/test/Index/index-templates.cpp
@@ -143,7 +143,7 @@
 // CHECK-LOAD: index-templates.cpp:40:8: ClassTemplate=storage:40:8 (Definition) Extent=[39:1 - 40:19]
 // CHECK-LOAD: index-templates.cpp:39:45: TemplateTemplateParameter=DataStructure:39:45 (Definition) Extent=[39:10 - 39:66]
 // CHECK-LOAD: index-templates.cpp:39:19: TemplateTypeParameter=:39:19 (Definition) Extent=[39:19 - 39:27]
-// CHECK-LOAD: index-templates.cpp:39:37: NonTypeTemplateParameter=:39:37 (Definition) Extent=[39:29 - 39:38]
+// CHECK-LOAD: index-templates.cpp:39:37: NonTypeTemplateParameter=:39:37 (Definition) Extent=[39:29 - 39:37]
 // CHECK-LOAD: index-templates.cpp:39:61: TemplateRef=array:37:8 Extent=[39:61 - 39:66]
 // CHECK-LOAD: index-templates.cpp:42:18: TypedefDecl=Unsigned:42:18 (Definition) Extent=[42:1 - 42:26]
 // CHECK-LOAD: index-templates.cpp:45:8: ClassTemplate=value_c:45:8 Extent=[44:1 - 45:15]
diff --git a/test/Index/load-classes.cpp b/test/Index/load-classes.cpp
index db7b48f..3b66be5 100644
--- a/test/Index/load-classes.cpp
+++ b/test/Index/load-classes.cpp
@@ -7,13 +7,24 @@
   ~X();
 private:
   operator X*();
+
+  void constMemberFunction() const;
+  template<typename T>
+  void constMemberFunctionTemplate() const;
+
+  static void staticMemberFunction();
+  template<typename T>
+  static void staticMemberFunctionTemplate();
+
+  virtual void virtualMemberFunction();
+  virtual void pureVirtualMemberFunction() = 0;
 };
 
 X::X(int value) {
 }
 
 // RUN: c-index-test -test-load-source all %s | FileCheck %s
-// CHECK: load-classes.cpp:3:8: StructDecl=X:3:8 (Definition) Extent=[3:1 - 10:2]
+// CHECK: load-classes.cpp:3:8: StructDecl=X:3:8 (Definition) Extent=[3:1 - 21:2]
 // CHECK: load-classes.cpp:4:3: CXXConstructor=X:4:3 Extent=[4:3 - 4:15] [access=public]
 // FIXME: missing TypeRef in the constructor name
 // CHECK: load-classes.cpp:4:9: ParmDecl=value:4:9 (Definition) Extent=[4:5 - 4:14]
@@ -21,10 +32,21 @@
 // FIXME: missing TypeRef in the constructor name
 // CHECK: load-classes.cpp:5:14: ParmDecl=x:5:14 (Definition) Extent=[5:5 - 5:15]
 // CHECK: load-classes.cpp:5:11: TypeRef=struct X:3:8 Extent=[5:11 - 5:12]
+// CHECK: load-classes.cpp:6:1: CXXAccessSpecifier=:6:1 (Definition) Extent=[6:1 - 6:11] [access=protected]
 // CHECK: load-classes.cpp:7:3: CXXDestructor=~X:7:3 Extent=[7:3 - 7:7] [access=protected]
 // FIXME: missing TypeRef in the destructor name
-// CHECK: load-classes.cpp:9:3: CXXConversion=operator struct X *:9:3 Extent=[9:3 - 9:16] [access=private]
+// CHECK: load-classes.cpp:8:1: CXXAccessSpecifier=:8:1 (Definition) Extent=[8:1 - 8:9] [access=private]
+// CHECK: load-classes.cpp:9:3: CXXConversion=operator X *:9:3 Extent=[9:3 - 9:16] [access=private]
 // CHECK: load-classes.cpp:9:12: TypeRef=struct X:3:8 Extent=[9:12 - 9:13]
-// CHECK: load-classes.cpp:12:4: CXXConstructor=X:12:4 (Definition) Extent=[12:1 - 13:2] [access=public]
-// CHECK: load-classes.cpp:12:1: TypeRef=struct X:3:8 Extent=[12:1 - 12:2]
-// CHECK: load-classes.cpp:12:10: ParmDecl=value:12:10 (Definition) Extent=[12:6 - 12:15]
+// CHECK: load-classes.cpp:11:8: CXXMethod=constMemberFunction:11:8 (const) Extent=[11:3 - 11:35] [access=private]
+// CHECK: load-classes.cpp:13:8: FunctionTemplate=constMemberFunctionTemplate:13:8 (const) Extent=[12:3 - 13:43] [access=private]
+// CHECK: load-classes.cpp:12:21: TemplateTypeParameter=T:12:21 (Definition) Extent=[12:12 - 12:22] [access=public]
+// CHECK: load-classes.cpp:15:15: CXXMethod=staticMemberFunction:15:15 (static) Extent=[15:3 - 15:37] [access=private]
+// CHECK: load-classes.cpp:17:15: FunctionTemplate=staticMemberFunctionTemplate:17:15 (static) Extent=[16:3 - 17:45] [access=private]
+// CHECK: load-classes.cpp:16:21: TemplateTypeParameter=T:16:21 (Definition) Extent=[16:12 - 16:22] [access=public]
+// CHECK: load-classes.cpp:19:16: CXXMethod=virtualMemberFunction:19:16 (virtual) Extent=[19:3 - 19:39] [access=private]
+// CHECK: load-classes.cpp:20:16: CXXMethod=pureVirtualMemberFunction:20:16 (virtual) (pure) Extent=[20:3 - 20:47] [access=private]
+// CHECK: load-classes.cpp:23:4: CXXConstructor=X:23:4 (Definition) Extent=[23:1 - 24:2] [access=public]
+// CHECK: load-classes.cpp:23:1: TypeRef=struct X:3:8 Extent=[23:1 - 23:2]
+// CHECK: load-classes.cpp:23:10: ParmDecl=value:23:10 (Definition) Extent=[23:6 - 23:15]
+// CHECK: load-classes.cpp:23:17: CompoundStmt= Extent=[23:17 - 24:2]
diff --git a/test/Index/load-decls.c b/test/Index/load-decls.c
index e0617c0..8d50134 100644
--- a/test/Index/load-decls.c
+++ b/test/Index/load-decls.c
@@ -6,6 +6,8 @@
   Rouge = Red
 };
 
+void PR17970(void (*)(int), float);
+
 // RUN: c-index-test -test-load-source all %s | FileCheck %s
 // CHECK: load-decls.c:1:6: EnumDecl=Color:1:6 (Definition) Extent=[1:1 - 7:2]
 // CHECK: load-decls.c:2:3: EnumConstantDecl=Red:2:3 (Definition) Extent=[2:3 - 2:6]
@@ -13,3 +15,8 @@
 // CHECK: load-decls.c:4:3: EnumConstantDecl=Blue:4:3 (Definition) Extent=[4:3 - 4:7]
 // CHECK: load-decls.c:6:3: EnumConstantDecl=Rouge:6:3 (Definition) Extent=[6:3 - 6:14]
 // CHECK: load-decls.c:6:11: DeclRefExpr=Red:2:3 Extent=[6:11 - 6:14]
+//
+// CHECK: load-decls.c:9:6: FunctionDecl=PR17970:9:6 Extent=[9:1 - 9:35]
+// CHECK: load-decls.c:9:21: ParmDecl=:9:21 (Definition) Extent=[9:14 - 9:27]
+// CHECK: load-decls.c:9:26: ParmDecl=:9:26 (Definition) Extent=[9:23 - 9:26]
+// CHECK: load-decls.c:9:34: ParmDecl=:9:34 (Definition) Extent=[9:29 - 9:34]
diff --git a/test/Index/load-namespaces.cpp b/test/Index/load-namespaces.cpp
index 49de66a..7d83aca 100644
--- a/test/Index/load-namespaces.cpp
+++ b/test/Index/load-namespaces.cpp
@@ -40,7 +40,7 @@
 // CHECK: load-namespaces.cpp:16:17: NamespaceRef=std0x:14:11 Extent=[16:17 - 16:22]
 // CHECK: load-namespaces.cpp:18:11: Namespace=std:18:11 (Definition) Extent=[18:1 - 20:2]
 // CHECK: load-namespaces.cpp:19:7: FunctionDecl=g:19:7 Extent=[19:3 - 19:13]
-// CHECK: load-namespaces.cpp:19:12: ParmDecl=:19:12 (Definition) Extent=[19:9 - 19:13]
+// CHECK: load-namespaces.cpp:19:12: ParmDecl=:19:12 (Definition) Extent=[19:9 - 19:12]
 // CHECK: load-namespaces.cpp:22:12: UsingDeclaration=g[19:7, 10:8] Extent=[22:1 - 22:13]
 // CHECK: load-namespaces.cpp:22:7: NamespaceRef=std:18:11 Extent=[22:7 - 22:10]
 // CHECK: load-namespaces.cpp:24:11: FunctionDecl=g:24:11 (Definition) Extent=[24:1 - 25:2]
diff --git a/test/Index/local-symbols.m b/test/Index/local-symbols.m
index b4eb262..c7b903a 100644
--- a/test/Index/local-symbols.m
+++ b/test/Index/local-symbols.m
@@ -26,6 +26,12 @@
 @interface R8380046 () <Prot8380046>
 @end
 
+@class NSString;
+
+void test() {
+  NSString *s = @"objc str";
+}
+
 // CHECK: local-symbols.m:6:12: ObjCInterfaceDecl=Foo:6:12 Extent=[6:1 - 10:5]
 // CHECK: local-symbols.m:7:6: ObjCIvarDecl=x:7:6 (Definition) Extent=[7:3 - 7:7]
 // CHECK: local-symbols.m:7:3: TypeRef=id:0:0 Extent=[7:3 - 7:5]
@@ -42,3 +48,4 @@
 // CHECK: local-symbols.m:26:12: ObjCClassRef=R8380046:23:12 Extent=[26:12 - 26:20]
 // CHECK: local-symbols.m:26:25: ObjCProtocolRef=Prot8380046:20:11 Extent=[26:25 - 26:36]
 
+// CHECK: local-symbols.m:32:17: ObjCStringLiteral="objc str" Extent=[32:17 - 32:28]
diff --git a/test/Index/pch-depending-on-deleted-module.c b/test/Index/pch-depending-on-deleted-module.c
new file mode 100644
index 0000000..4e85ff0
--- /dev/null
+++ b/test/Index/pch-depending-on-deleted-module.c
@@ -0,0 +1,14 @@
+#include "a.h"
+
+// RUN: rm -rf %t
+// RUN: mkdir %t
+
+// RUN: %clang_cc1 -x c-header -fmodules -fdisable-module-hash -fmodules-cache-path=%t/modules-cache -emit-pch -I %S/Inputs/Headers -o %t/use_LibA.pch %s
+// RUN: %clang_cc1 -fmodules -fdisable-module-hash -fmodules-cache-path=%t/modules-cache -I %S/Inputs/Headers -verify-pch %t/use_LibA.pch
+// RUN: rm -f %t/modules-cache/LibA.pcm
+// RUN: not %clang_cc1 -fmodules -fdisable-module-hash -fmodules-cache-path=%t/modules-cache -I %S/Inputs/Headers -verify-pch %t/use_LibA.pch 2>&1 | FileCheck -check-prefix=VERIFY %s
+// RUN: not c-index-test -test-load-source all -x c -fmodules -Xclang -fdisable-module-hash -fmodules-cache-path=%t/modules-cache -I %S/Inputs/Headers -include-pch %t/use_LibA.pch %s 2>&1 | FileCheck -check-prefix=INDEX %s
+
+// VERIFY: fatal error: malformed or corrupted AST file: 'Unable to load module
+// INDEX: {{^}}Failure: AST deserialization error occurred{{$}}
+
diff --git a/test/Index/preamble-reparse-cmd-define.c b/test/Index/preamble-reparse-cmd-define.c
index 67ffde1..3fa7683 100644
--- a/test/Index/preamble-reparse-cmd-define.c
+++ b/test/Index/preamble-reparse-cmd-define.c
@@ -1,6 +1,6 @@
 // RUN: c-index-test -write-pch %t.h.pch %s.h
 // RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_REMAP_AFTER_TRIAL=1 c-index-test -test-load-source-reparse 3 local \ 
-// RUN:           "-remap-file=%s;%s.remap" %s -include %t.h -D CMD_MACRO=1 2>&1 | FileCheck %s
+// RUN:           "-remap-file=%s,%s.remap" %s -include %t.h -D CMD_MACRO=1 2>&1 | FileCheck %s
 
 // CHECK-NOT: error:
 
diff --git a/test/Index/preamble-reparse-warn-end-of-file.c b/test/Index/preamble-reparse-warn-end-of-file.c
new file mode 100644
index 0000000..c2ae892
--- /dev/null
+++ b/test/Index/preamble-reparse-warn-end-of-file.c
@@ -0,0 +1,11 @@
+// RUN: mkdir -p %t
+// RUN: touch %t/header.h
+// RUN: env CINDEXTEST_EDITING=1 c-index-test -test-load-source-reparse 2 local %s -I %t 2>&1 > %t.out.txt | FileCheck -check-prefix=STDERR %s
+// RUN: FileCheck -input-file=%t.out.txt %s
+// CHECK: preamble-reparse-warn-end-of-file.c:[[@LINE+6]]:6: FunctionDecl=test:[[@LINE+6]]:6
+// STDERR: preamble-reparse-warn-end-of-file.c:[[@LINE+5]]:14: error: expected '}'
+// STDERR: preamble-reparse-warn-end-of-file.c:[[@LINE+4]]:14: error: expected '}'
+
+#include "header.h"
+
+void test() {
diff --git a/test/Index/preamble-reparse-warn-macro.c b/test/Index/preamble-reparse-warn-macro.c
new file mode 100644
index 0000000..e02fbde
--- /dev/null
+++ b/test/Index/preamble-reparse-warn-macro.c
@@ -0,0 +1,12 @@
+// RUN: mkdir -p %t
+// RUN: touch %t/header.h
+// RUN: env CINDEXTEST_EDITING=1 c-index-test -test-load-source-reparse 2 local %s -I %t 2>&1 > %t.out.txt | FileCheck %s
+// CHECK: preamble-reparse-warn-macro.c:[[@LINE+8]]:9: warning: 'MAC' macro redefined
+// CHECK-NEXT: Number FIX-ITs = 0
+// CHECK-NEXT: preamble-reparse-warn-macro.c:[[@LINE+2]]:9: note: previous definition is here
+
+#define MAC 1
+#include "header.h"
+
+void test();
+#define MAC 2
diff --git a/test/Index/preamble-reparse.c b/test/Index/preamble-reparse.c
index 5bd03b3..a7c8780 100644
--- a/test/Index/preamble-reparse.c
+++ b/test/Index/preamble-reparse.c
@@ -1,2 +1,2 @@
-// RUN: env CINDEXTEST_EDITING=1 c-index-test -test-load-source-reparse 5 local "-remap-file=%S/Inputs/preamble-reparse-1.c;%S/Inputs/preamble-reparse-2.c" %S/Inputs/preamble-reparse-1.c | FileCheck %s
+// RUN: env CINDEXTEST_EDITING=1 c-index-test -test-load-source-reparse 5 local "-remap-file=%S/Inputs/preamble-reparse-1.c,%S/Inputs/preamble-reparse-2.c" %S/Inputs/preamble-reparse-1.c | FileCheck %s
 // CHECK: preamble-reparse-1.c:1:5: VarDecl=x:1:5 Extent=[1:1 - 1:6]
diff --git a/test/Index/preamble.c b/test/Index/preamble.c
index 92a9b84..ae8e1aa 100644
--- a/test/Index/preamble.c
+++ b/test/Index/preamble.c
@@ -2,13 +2,16 @@
 #include "preamble.h"
 #include "preamble-with-error.h"
 
+#define MACRO_UNUSED 1
+#define MACRO_USED 2
+
 int wibble(int);
 
 void f(int x) {
-  
+  x = MACRO_USED
 }
 // RUN: c-index-test -write-pch %t.pch -x c-header %S/Inputs/prefix.h
-// RUN: env CINDEXTEST_EDITING=1 c-index-test -test-load-source-reparse 5 local -I %S/Inputs -include %t %s 2> %t.stderr.txt | FileCheck %s
+// RUN: env CINDEXTEST_EDITING=1 c-index-test -test-load-source-reparse 5 local -I %S/Inputs -include %t %s -Wunused-macros 2> %t.stderr.txt | FileCheck %s
 // RUN: FileCheck -check-prefix CHECK-DIAG %s < %t.stderr.txt
 // CHECK: preamble.h:1:12: FunctionDecl=bar:1:12 (Definition) Extent=[1:1 - 6:2]
 // CHECK: preamble.h:4:3: BinaryOperator= Extent=[4:3 - 4:13]
@@ -16,10 +19,13 @@
 // CHECK: preamble.h:4:9: UnexposedExpr=ptr1:3:10 Extent=[4:9 - 4:13]
 // CHECK: preamble.h:4:9: DeclRefExpr=ptr1:3:10 Extent=[4:9 - 4:13]
 // CHECK: preamble.h:5:10: IntegerLiteral= Extent=[5:10 - 5:11]
-// CHECK: preamble.c:5:5: FunctionDecl=wibble:5:5 Extent=[5:1 - 5:16]
-// CHECK: preamble.c:5:15: ParmDecl=:5:15 (Definition) Extent=[5:12 - 5:16]
+// CHECK: preamble.c:8:5: FunctionDecl=wibble:8:5 Extent=[8:1 - 8:16]
+// CHECK: preamble.c:8:15: ParmDecl=:8:15 (Definition) Extent=[8:12 - 8:15]
 // CHECK-DIAG: preamble.h:4:7:{4:9-4:13}: warning: incompatible pointer types assigning to 'int *' from 'float *'
-// RUN: env CINDEXTEST_EDITING=1 c-index-test -code-completion-at=%s:8:1 -I %S/Inputs -include %t %s 2> %t.stderr.txt | FileCheck -check-prefix CHECK-CC %s
+// FIXME: Should see:
+//     preamble.c:5:9: warning: macro is not used
+// CHECK-DIAG-NOT: preamble.c:6:9: warning: macro is not used
+// RUN: env CINDEXTEST_EDITING=1 c-index-test -code-completion-at=%s:11:1 -I %S/Inputs -include %t %s 2> %t.stderr.txt | FileCheck -check-prefix CHECK-CC %s
 // CHECK-CC: FunctionDecl:{ResultType int}{TypedText bar}{LeftParen (}{Placeholder int i}{RightParen )} (50)
 // CHECK-CC: FunctionDecl:{ResultType void}{TypedText f}{LeftParen (}{Placeholder int x}{RightParen )} (50)
 // CHECK-CC: FunctionDecl:{ResultType int}{TypedText foo}{LeftParen (}{Placeholder int}{RightParen )} (50)
diff --git a/test/Index/print-type-cxx11.cpp b/test/Index/print-type-cxx11.cpp
index 0ad5473..1f7522f 100644
--- a/test/Index/print-type-cxx11.cpp
+++ b/test/Index/print-type-cxx11.cpp
@@ -4,5 +4,5 @@
 };
 
 // RUN: c-index-test -test-print-type -std=c++11 %s | FileCheck %s
-// CHECK: CXXMethod=f:2:8 (Definition) [type=void () &] [typekind=FunctionProto] lvalue-ref-qualifier [resulttype=void] [resulttypekind=Void] [isPOD=0]
-// CHECK: CXXMethod=f:3:8 (Definition) [type=void () &&] [typekind=FunctionProto] rvalue-ref-qualifier [resulttype=void] [resulttypekind=Void] [isPOD=0]
+// CHECK: CXXMethod=f:2:8 (Definition) [type=void () {{.*}}&] [typekind=FunctionProto] lvalue-ref-qualifier [resulttype=void] [resulttypekind=Void] [isPOD=0]
+// CHECK: CXXMethod=f:3:8 (Definition) [type=void () {{.*}}&&] [typekind=FunctionProto] rvalue-ref-qualifier [resulttype=void] [resulttypekind=Void] [isPOD=0]
diff --git a/test/Index/print-type.c b/test/Index/print-type.c
index 6c7095a..35aab71 100644
--- a/test/Index/print-type.c
+++ b/test/Index/print-type.c
@@ -14,27 +14,27 @@
 
 // RUN: c-index-test -test-print-type %s | FileCheck %s
 // CHECK: FunctionDecl=f:3:6 (Definition) [type=int *(int *, char *, FooType, int *, void (*)(int))] [typekind=FunctionProto] [canonicaltype=int *(int *, char *, int, int *, void (*)(int))] [canonicaltypekind=FunctionProto] [resulttype=int *] [resulttypekind=Pointer] [args= [int *] [Pointer] [char *] [Pointer] [FooType] [Typedef] [int [5]] [ConstantArray] [void (*)(int)] [Pointer]] [isPOD=0]
-// CHECK: ParmDecl=p:3:13 (Definition) [type=int *] [typekind=Pointer] [isPOD=1]
-// CHECK: ParmDecl=x:3:22 (Definition) [type=char *] [typekind=Pointer] [isPOD=1]
+// CHECK: ParmDecl=p:3:13 (Definition) [type=int *] [typekind=Pointer] [isPOD=1] [pointeetype=int] [pointeekind=Int]
+// CHECK: ParmDecl=x:3:22 (Definition) [type=char *] [typekind=Pointer] [isPOD=1] [pointeetype=char] [pointeekind=Char_{{[US]}}]
 // CHECK: ParmDecl=z:3:33 (Definition) [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
 // CHECK: TypeRef=FooType:1:13 [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
 // CHECK: ParmDecl=arr:3:40 (Definition) [type=int [5]] [typekind=ConstantArray] [isPOD=1]
 // CHECK: IntegerLiteral= [type=int] [typekind=Int] [isPOD=1]
-// CHECK: ParmDecl=fn:3:55 (Definition) [type=void (*)(int)] [typekind=Pointer] [canonicaltype=void (*)(int)] [canonicaltypekind=Pointer] [isPOD=1]
+// CHECK: ParmDecl=fn:3:55 (Definition) [type=void (*)(int)] [typekind=Pointer] [canonicaltype=void (*)(int)] [canonicaltypekind=Pointer] [isPOD=1] [pointeetype=void (int)] [pointeekind=Unexposed]
 // CHECK: ParmDecl=:3:62 (Definition) [type=int] [typekind=Int] [isPOD=1]
 // CHECK: CompoundStmt= [type=] [typekind=Invalid] [isPOD=0]
 // CHECK: CallExpr=fn:3:55 [type=void] [typekind=Void] [args= [int] [Int]] [isPOD=0]
-// CHECK: DeclRefExpr=fn:3:55 [type=void (*)(int)] [typekind=Pointer] [canonicaltype=void (*)(int)] [canonicaltypekind=Pointer] [isPOD=1]
+// CHECK: DeclRefExpr=fn:3:55 [type=void (*)(int)] [typekind=Pointer] [canonicaltype=void (*)(int)] [canonicaltypekind=Pointer] [isPOD=1] [pointeetype=void (int)] [pointeekind=Unexposed]
 // CHECK: UnaryOperator= [type=int] [typekind=Int] [isPOD=1]
-// CHECK: DeclRefExpr=p:3:13 [type=int *] [typekind=Pointer] [isPOD=1]
+// CHECK: DeclRefExpr=p:3:13 [type=int *] [typekind=Pointer] [isPOD=1] [pointeetype=int] [pointeekind=Int]
 // CHECK: DeclStmt= [type=] [typekind=Invalid] [isPOD=0]
 // CHECK: VarDecl=w:5:17 (Definition) [type=const FooType] [typekind=Typedef] const [canonicaltype=const int] [canonicaltypekind=Int] [isPOD=1]
 // CHECK: TypeRef=FooType:1:13 [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
 // CHECK: DeclRefExpr=z:3:33 [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
 // CHECK: ReturnStmt= [type=] [typekind=Invalid] [isPOD=0]
-// CHECK: BinaryOperator= [type=int *] [typekind=Pointer] [isPOD=1]
-// CHECK: BinaryOperator= [type=int *] [typekind=Pointer] [isPOD=1]
-// CHECK: DeclRefExpr=p:3:13 [type=int *] [typekind=Pointer] [isPOD=1]
+// CHECK: BinaryOperator= [type=int *] [typekind=Pointer] [isPOD=1] [pointeetype=int] [pointeekind=Int]
+// CHECK: BinaryOperator= [type=int *] [typekind=Pointer] [isPOD=1] [pointeetype=int] [pointeekind=Int]
+// CHECK: DeclRefExpr=p:3:13 [type=int *] [typekind=Pointer] [isPOD=1] [pointeetype=int] [pointeekind=Int]
 // CHECK: DeclRefExpr=z:3:33 [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
 // CHECK: ArraySubscriptExpr= [type=int] [typekind=Int] [isPOD=1]
 // CHECK: UnexposedExpr=arr:3:40 [type=int [5]] [typekind=ConstantArray] [isPOD=1]
diff --git a/test/Index/print-type.cpp b/test/Index/print-type.cpp
index 6324d43..af5c556 100644
--- a/test/Index/print-type.cpp
+++ b/test/Index/print-type.cpp
@@ -5,10 +5,16 @@
   T t;
 };
 
+template <typename T, unsigned U, template<typename> class W>
+struct Baz { };
+
+template <typename... T>
+struct Qux { };
+
 namespace inner {
 
 struct Bar {
-  Bar(outer::Foo<bool>* foo) { };
+  Bar(outer::Foo<bool>* foo) { }
 
   typedef int FooType;
   int *p;
@@ -18,6 +24,8 @@
   }
   typedef double OtherType;
   typedef int ArrayType[5];
+  Baz<int, 1, Foo> baz;
+  Qux<int, char*, Foo<int>> qux;
 };
 
 }
@@ -39,43 +47,74 @@
 };
 int Blob::*member_pointer;
 
-// RUN: c-index-test -test-print-type %s | FileCheck %s
+// RUN: c-index-test -test-print-type %s -std=c++11 | FileCheck %s
 // CHECK: Namespace=outer:1:11 (Definition) [type=] [typekind=Invalid] [isPOD=0]
 // CHECK: ClassTemplate=Foo:4:8 (Definition) [type=] [typekind=Invalid] [isPOD=0]
 // CHECK: TemplateTypeParameter=T:3:19 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
 // CHECK: FieldDecl=t:5:5 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
 // CHECK: TypeRef=T:3:19 [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
-// CHECK: Namespace=inner:8:11 (Definition) [type=] [typekind=Invalid] [isPOD=0]
-// CHECK: StructDecl=Bar:10:8 (Definition) [type=outer::inner::Bar] [typekind=Record] [isPOD=0]
-// CHECK: CXXConstructor=Bar:11:3 (Definition) [type=void (outer::Foo<bool> *)] [typekind=FunctionProto] [canonicaltype=void (outer::Foo<bool> *)] [canonicaltypekind=FunctionProto] [resulttype=void] [resulttypekind=Void] [args= [outer::Foo<bool> *] [Pointer]] [isPOD=0]
-// CHECK: ParmDecl=foo:11:25 (Definition) [type=outer::Foo<bool> *] [typekind=Pointer] [canonicaltype=outer::Foo<bool> *] [canonicaltypekind=Pointer] [isPOD=1]
+// CHECK: ClassTemplate=Baz:9:8 (Definition) [type=] [typekind=Invalid] [isPOD=0]
+// CHECK: TemplateTypeParameter=T:8:20 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
+// CHECK: NonTypeTemplateParameter=U:8:32 (Definition) [type=unsigned int] [typekind=UInt] [isPOD=1]
+// CHECK: TemplateTemplateParameter=W:8:60 (Definition) [type=] [typekind=Invalid] [isPOD=0]
+// CHECK: Namespace=inner:14:11 (Definition) [type=] [typekind=Invalid] [isPOD=0]
+// CHECK: StructDecl=Bar:16:8 (Definition) [type=outer::inner::Bar] [typekind=Record] [isPOD=0]
+// CHECK: CXXConstructor=Bar:17:3 (Definition) [type=void (outer::Foo<bool> *){{.*}}] [typekind=FunctionProto] [canonicaltype=void (outer::Foo<bool> *){{.*}}] [canonicaltypekind=FunctionProto] [resulttype=void] [resulttypekind=Void] [args= [outer::Foo<bool> *] [Pointer]] [isPOD=0]
+// CHECK: ParmDecl=foo:17:25 (Definition) [type=outer::Foo<bool> *] [typekind=Pointer] [canonicaltype=outer::Foo<bool> *] [canonicaltypekind=Pointer] [isPOD=1] [pointeetype=outer::Foo<bool>] [pointeekind=Unexposed]
 // 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:13:15 (Definition) [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
-// CHECK: FieldDecl=p:14:8 (Definition) [type=int *] [typekind=Pointer] [isPOD=1]
-// CHECK: CXXMethod=f:15: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:15:15 (Definition) [type=int *] [typekind=Pointer] [isPOD=1]
-// CHECK: ParmDecl=x:15:24 (Definition) [type=char *] [typekind=Pointer] [isPOD=1]
-// CHECK: ParmDecl=z:15:35 (Definition) [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
-// CHECK: TypeRef=FooType:13:15 [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
+// 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: CompoundStmt= [type=] [typekind=Invalid] [isPOD=0]
 // CHECK: DeclStmt= [type=] [typekind=Invalid] [isPOD=0]
-// CHECK: VarDecl=w:16:19 (Definition) [type=const FooType] [typekind=Typedef] const [canonicaltype=const int] [canonicaltypekind=Int] [isPOD=1]
-// CHECK: TypeRef=FooType:13:15 [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
-// CHECK: DeclRefExpr=z:15:35 [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
+// 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: ReturnStmt= [type=] [typekind=Invalid] [isPOD=0]
-// CHECK: BinaryOperator= [type=int *] [typekind=Pointer] [isPOD=1]
-// CHECK: DeclRefExpr=p:15:15 [type=int *] [typekind=Pointer] [isPOD=1]
-// CHECK: DeclRefExpr=z:15:35 [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
-// CHECK: TypedefDecl=OtherType:19:18 (Definition) [type=OtherType] [typekind=Typedef] [canonicaltype=double] [canonicaltypekind=Double] [isPOD=1]
-// CHECK: TypedefDecl=ArrayType:20:15 (Definition) [type=ArrayType] [typekind=Typedef] [canonicaltype=int [5]] [canonicaltypekind=ConstantArray] [isPOD=1]
-// CHECK: FunctionTemplate=tbar:27:3 [type=T (int)] [typekind=FunctionProto] [canonicaltype=type-parameter-0-0 (int)] [canonicaltypekind=FunctionProto] [resulttype=T] [resulttypekind=Unexposed] [isPOD=0]
-// CHECK: TemplateTypeParameter=T:26:20 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
-// CHECK: FunctionTemplate=tbar:30:3 [type=T (int *)] [typekind=FunctionProto] [canonicaltype=type-parameter-0-0 (int *)] [canonicaltypekind=FunctionProto] [resulttype=T] [resulttypekind=Unexposed] [isPOD=0]
-// CHECK: ParmDecl=:30:11 (Definition) [type=int [5]] [typekind=ConstantArray] [isPOD=1]
-// CHECK: FunctionTemplate=tbar:33:3 [type=T (int *)] [typekind=FunctionProto] [canonicaltype=type-parameter-0-0 (int *)] [canonicaltypekind=FunctionProto] [resulttype=T] [resulttypekind=Unexposed] [isPOD=0]
-// CHECK: ParmDecl=:33:11 (Definition) [type=int [size]] [typekind=DependentSizedArray] [isPOD=0]
-// CHECK: ParmDecl=incomplete_array:35:21 (Definition) [type=int []] [typekind=IncompleteArray] [isPOD=1]
-// CHECK: VarDecl=variable_array:35:47 (Definition) [type=int [i]] [typekind=VariableArray] [isPOD=1]
-// CHECK: VarDecl=member_pointer:40:12 (Definition) [type=int Blob::*] [typekind=MemberPointer] [isPOD=1]
+// 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: 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: 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/1=] [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: 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: 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]
+// CHECK: FieldDecl=i:46:7 (Definition) [type=int] [typekind=Int] [isPOD=1]
+// CHECK: VarDecl=member_pointer:48:12 (Definition) [type=int Blob::*] [typekind=MemberPointer] [isPOD=1]
diff --git a/test/Index/print-type.m b/test/Index/print-type.m
index 6f146f8..5a4272b 100644
--- a/test/Index/print-type.m
+++ b/test/Index/print-type.m
@@ -12,4 +12,4 @@
 // CHECK: ParmDecl=z:4:52 (Definition) [type=SEL] [typekind=ObjCSel] [canonicaltype=SEL *] [canonicaltypekind=Pointer] [isPOD=1]
 // CHECK: ObjCInstanceMethodDecl=methodIn:andOut::5:10 (variadic) [Bycopy,] [type=] [typekind=Invalid] [resulttype=id] [resulttypekind=ObjCId] [args= [int] [Int] [short *] [Pointer]] [isPOD=0]
 // CHECK: ParmDecl=i:5:27 (Definition) [In,] [type=int] [typekind=Int] [isPOD=1]
-// CHECK: ParmDecl=j:5:49 (Definition) [Out,] [type=short *] [typekind=Pointer] [isPOD=1]
+// CHECK: ParmDecl=j:5:49 (Definition) [Out,] [type=short *] [typekind=Pointer] [isPOD=1] [pointeetype=short] [pointeekind=Short]
diff --git a/test/Index/recursive-cxx-member-calls.cpp b/test/Index/recursive-cxx-member-calls.cpp
index 2cd8d13..34a5652 100644
--- a/test/Index/recursive-cxx-member-calls.cpp
+++ b/test/Index/recursive-cxx-member-calls.cpp
@@ -185,7 +185,7 @@
     .Default(UnknownAttribute);
 }
 
-// RUN: c-index-test -test-annotate-tokens=%s:1:1:186:1 %s 2>&1 | FileCheck -check-prefix=CHECK-tokens %s
+// RUN: c-index-test -test-annotate-tokens=%s:1:1:186:1 -target x86_64-unknown-unknown %s 2>&1 | FileCheck -check-prefix=CHECK-tokens %s
 // CHECK-tokens: Keyword: "typedef" [1:1 - 1:8]
 // CHECK-tokens: Keyword: "long" [1:9 - 1:13]
 // CHECK-tokens: Keyword: "unsigned" [1:14 - 1:22]
@@ -225,13 +225,13 @@
 // CHECK-tokens: Keyword: "const" [7:14 - 7:19] ParmDecl=:7:26 (Definition)
 // CHECK-tokens: Keyword: "void" [7:20 - 7:24] ParmDecl=:7:26 (Definition)
 // CHECK-tokens: Punctuation: "*" [7:25 - 7:26] ParmDecl=:7:26 (Definition)
-// CHECK-tokens: Punctuation: "," [7:26 - 7:27] ParmDecl=:7:26 (Definition)
+// CHECK-tokens: Punctuation: "," [7:26 - 7:27] FunctionDecl=memcmp:7:7
 // CHECK-tokens: Keyword: "const" [7:28 - 7:33] ParmDecl=:7:40 (Definition)
 // CHECK-tokens: Keyword: "void" [7:34 - 7:38] ParmDecl=:7:40 (Definition)
 // CHECK-tokens: Punctuation: "*" [7:39 - 7:40] ParmDecl=:7:40 (Definition)
-// CHECK-tokens: Punctuation: "," [7:40 - 7:41] ParmDecl=:7:40 (Definition)
+// CHECK-tokens: Punctuation: "," [7:40 - 7:41] FunctionDecl=memcmp:7:7
 // CHECK-tokens: Identifier: "size_t" [7:42 - 7:48] TypeRef=size_t:2:25
-// CHECK-tokens: Punctuation: ")" [7:48 - 7:49] ParmDecl=:7:48 (Definition)
+// CHECK-tokens: Punctuation: ")" [7:48 - 7:49] FunctionDecl=memcmp:7:7
 // CHECK-tokens: Punctuation: ";" [7:49 - 7:50] UnexposedDecl=:6:8 (Definition)
 // CHECK-tokens: Identifier: "size_t" [8:3 - 8:9] TypeRef=size_t:2:25
 // CHECK-tokens: Identifier: "strlen" [8:10 - 8:16] FunctionDecl=strlen:8:10
@@ -239,7 +239,7 @@
 // CHECK-tokens: Keyword: "const" [8:17 - 8:22] ParmDecl=:8:29 (Definition)
 // CHECK-tokens: Keyword: "char" [8:23 - 8:27] ParmDecl=:8:29 (Definition)
 // CHECK-tokens: Punctuation: "*" [8:28 - 8:29] ParmDecl=:8:29 (Definition)
-// CHECK-tokens: Punctuation: ")" [8:29 - 8:30] ParmDecl=:8:29 (Definition)
+// CHECK-tokens: Punctuation: ")" [8:29 - 8:30] FunctionDecl=strlen:8:10
 // CHECK-tokens: Punctuation: ";" [8:30 - 8:31]
 // CHECK-tokens: Punctuation: "}" [9:1 - 9:2]
 // CHECK-tokens: Keyword: "namespace" [10:1 - 10:10]
@@ -1523,7 +1523,7 @@
 // CHECK-tokens: Punctuation: ";" [185:31 - 185:32] CompoundStmt=
 // CHECK-tokens: Punctuation: "}" [186:1 - 186:2] CompoundStmt=
 
-// RUN: c-index-test -test-load-source all %s -std=c++98 2>&1 | FileCheck %s
+// RUN: c-index-test -test-load-source all %s -std=c++98 -target x86_64-unknown-unknown 2>&1 | FileCheck %s
 // CHECK: 1:27: TypedefDecl=__darwin_size_t:1:27 (Definition) Extent=[1:1 - 1:42]
 // CHECK: 2:25: TypedefDecl=size_t:2:25 (Definition) Extent=[2:1 - 2:31]
 // CHECK: 2:9: TypeRef=__darwin_size_t:1:27 Extent=[2:9 - 2:24]
@@ -1534,13 +1534,13 @@
 // CHECK: 4:55: FieldDecl=second:4:55 (Definition) Extent=[4:51 - 4:61]
 // CHECK: 6:8: UnexposedDecl=:6:8 (Definition) Extent=[6:1 - 9:2]
 // CHECK: 7:7: FunctionDecl=memcmp:7:7 Extent=[7:3 - 7:49]
-// CHECK: 7:26: ParmDecl=:7:26 (Definition) Extent=[7:14 - 7:27]
-// CHECK: 7:40: ParmDecl=:7:40 (Definition) Extent=[7:28 - 7:41]
-// CHECK: 7:48: ParmDecl=:7:48 (Definition) Extent=[7:42 - 7:49]
+// CHECK: 7:26: ParmDecl=:7:26 (Definition) Extent=[7:14 - 7:26]
+// CHECK: 7:40: ParmDecl=:7:40 (Definition) Extent=[7:28 - 7:40]
+// CHECK: 7:48: ParmDecl=:7:48 (Definition) Extent=[7:42 - 7:48]
 // CHECK: 7:42: TypeRef=size_t:2:25 Extent=[7:42 - 7:48]
 // CHECK: 8:10: FunctionDecl=strlen:8:10 Extent=[8:3 - 8:30]
 // CHECK: 8:3: TypeRef=size_t:2:25 Extent=[8:3 - 8:9]
-// CHECK: 8:29: ParmDecl=:8:29 (Definition) Extent=[8:17 - 8:30]
+// CHECK: 8:29: ParmDecl=:8:29 (Definition) Extent=[8:17 - 8:29]
 // CHECK: 10:17: Namespace=clang:10:17 (Definition) Extent=[10:1 - 35:2]
 // CHECK: 11:9: ClassDecl=IdentifierInfo:11:9 Extent=[11:3 - 11:23]
 // CHECK: 12:9: ClassDecl=AttributeList:12:9 (Definition) Extent=[12:3 - 34:4]
@@ -1680,17 +1680,17 @@
 // CHECK: 49:60: MemberRef=Length:44:10 Extent=[49:60 - 49:66]
 // 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) Extent=[50:3 - 50:40]
+// 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: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]
-// CHECK: 51:10: CXXMethod=size:51:10 (Definition) Extent=[51:3 - 51:41]
+// CHECK: 51:10: CXXMethod=size:51:10 (Definition) (const) Extent=[51:3 - 51:41] [access=public]
 // CHECK: 51:3: TypeRef=size_t:2:25 Extent=[51:3 - 51:9]
 // CHECK: 51:23: CompoundStmt= Extent=[51:23 - 51:41]
 // CHECK: 51:25: ReturnStmt= Extent=[51:25 - 51:38]
 // CHECK: 51:32: MemberRefExpr=Length:44:10 Extent=[51:32 - 51:38]
-// CHECK: 52:8: CXXMethod=startswith:52:8 (Definition) Extent=[52:3 - 55:4]
+// CHECK: 52:8: CXXMethod=startswith:52:8 (Definition) (const) Extent=[52:3 - 55:4] [access=public]
 // CHECK: 52:29: ParmDecl=Prefix:52:29 (Definition) Extent=[52:19 - 52:35]
 // CHECK: 52:19: TypeRef=class llvm::StringRef:38:7 Extent=[52:19 - 52:28]
 // CHECK: 52:43: CompoundStmt= Extent=[52:43 - 55:4]
@@ -1713,7 +1713,7 @@
 // CHECK: 54:44: MemberRefExpr=Length:44:10 SingleRefName=[54:44 - 54:50] RefName=[54:44 - 54:50] Extent=[54:37 - 54:50]
 // CHECK: 54:37: DeclRefExpr=Prefix:52:29 Extent=[54:37 - 54:43]
 // CHECK: 54:55: IntegerLiteral= Extent=[54:55 - 54:56]
-// CHECK: 56:8: CXXMethod=endswith:56:8 (Definition) Extent=[56:3 - 59:4]
+// CHECK: 56:8: CXXMethod=endswith:56:8 (Definition) (const) Extent=[56:3 - 59:4] [access=public]
 // CHECK: 56:27: ParmDecl=Suffix:56:27 (Definition) Extent=[56:17 - 56:33]
 // CHECK: 56:17: TypeRef=class llvm::StringRef:38:7 Extent=[56:17 - 56:26]
 // CHECK: 56:41: CompoundStmt= Extent=[56:41 - 59:4]
@@ -1740,7 +1740,7 @@
 // CHECK: 58:57: MemberRefExpr=Length:44:10 SingleRefName=[58:57 - 58:63] RefName=[58:57 - 58:63] Extent=[58:50 - 58:63]
 // CHECK: 58:50: DeclRefExpr=Suffix:56:27 Extent=[58:50 - 58:56]
 // CHECK: 58:68: IntegerLiteral= Extent=[58:68 - 58:69]
-// CHECK: 60:13: CXXMethod=substr:60:13 (Definition) Extent=[60:3 - 62:4]
+// CHECK: 60:13: CXXMethod=substr:60:13 (Definition) (const) Extent=[60:3 - 62:4] [access=public]
 // CHECK: 60:3: TypeRef=class llvm::StringRef:38:7 Extent=[60:3 - 60:12]
 // CHECK: 60:27: ParmDecl=Start:60:27 (Definition) Extent=[60:20 - 60:32]
 // CHECK: 60:20: TypeRef=size_t:2:25 Extent=[60:20 - 60:26]
@@ -1769,7 +1769,7 @@
 // CHECK: 66:7: ClassDecl=IdentifierInfo:66:7 (Definition) Extent=[66:1 - 80:2]
 // CHECK: 67:1: CXXAccessSpecifier=:67:1 (Definition) Extent=[67:1 - 67:8]
 // CHECK: 67:8: CXXConstructor=IdentifierInfo:67:8 Extent=[67:8 - 67:24]
-// CHECK: 68:15: CXXMethod=getNameStart:68:15 (Definition) Extent=[68:3 - 71:4]
+// CHECK: 68:15: CXXMethod=getNameStart:68:15 (Definition) (const) Extent=[68:3 - 71:4] [access=public]
 // CHECK: 68:36: CompoundStmt= Extent=[68:36 - 71:4]
 // CHECK: 69:5: DeclStmt= Extent=[69:5 - 69:65]
 // CHECK: 69:54: TypedefDecl=actualtype:69:54 (Definition) Extent=[69:5 - 69:64]
@@ -1781,7 +1781,7 @@
 // CHECK: 70:13: CStyleCastExpr= Extent=[70:13 - 70:38]
 // CHECK: 70:20: TypeRef=actualtype:69:54 Extent=[70:20 - 70:30]
 // CHECK: 70:34: CXXThisExpr= Extent=[70:34 - 70:38]
-// CHECK: 72:12: CXXMethod=getLength:72:12 (Definition) Extent=[72:3 - 76:4]
+// CHECK: 72:12: CXXMethod=getLength:72:12 (Definition) (const) Extent=[72:3 - 76:4] [access=public]
 // CHECK: 72:30: CompoundStmt= Extent=[72:30 - 76:4]
 // CHECK: 73:5: DeclStmt= Extent=[73:5 - 73:65]
 // CHECK: 73:54: TypedefDecl=actualtype:73:54 (Definition) Extent=[73:5 - 73:64]
@@ -1820,7 +1820,7 @@
 // CHECK: 75:55: IntegerLiteral= Extent=[75:55 - 75:56]
 // CHECK: 75:61: UnexposedExpr= Extent=[75:61 - 75:62]
 // CHECK: 75:61: IntegerLiteral= Extent=[75:61 - 75:62]
-// CHECK: 77:19: CXXMethod=getName:77:19 (Definition) Extent=[77:3 - 79:4]
+// CHECK: 77:19: CXXMethod=getName:77:19 (Definition) (const) Extent=[77:3 - 79:4] [access=public]
 // CHECK: 77:35: CompoundStmt= Extent=[77:35 - 79:4]
 // CHECK: 78:5: ReturnStmt= Extent=[78:5 - 78:56]
 // CHECK: 78:12: CallExpr= Extent=[78:12 - 78:56]
@@ -1858,7 +1858,7 @@
 // CHECK: 90:5: ReturnStmt= Extent=[90:5 - 90:17]
 // CHECK: 90:12: UnaryOperator= Extent=[90:12 - 90:17]
 // CHECK: 90:13: CXXThisExpr= Extent=[90:13 - 90:17]
-// CHECK: 92:5: CXXMethod=Default:92:5 (Definition) Extent=[92:3 - 94:4]
+// CHECK: 92:5: CXXMethod=Default:92:5 (Definition) (const) Extent=[92:3 - 94:4] [access=public]
 // CHECK: 92:23: ParmDecl=Value:92:23 (Definition) Extent=[92:13 - 92:28]
 // CHECK: 92:36: CompoundStmt= Extent=[92:36 - 94:4]
 // CHECK: 93:5: ReturnStmt= Extent=[93:5 - 93:17]
@@ -1888,7 +1888,7 @@
 // CHECK: 102:27: UnexposedExpr=StringRef:48:3 Extent=[102:27 - 102:31]
 // CHECK: 102:27: CallExpr=StringRef:48:3 Extent=[102:27 - 102:31]
 // CHECK: 102:27: UnexposedExpr= Extent=[102:27 - 102:31]
-// CHECK: 102:27: StringLiteral= Extent=[102:27 - 102:31]
+// CHECK: 102:27: StringLiteral="__" Extent=[102:27 - 102:31]
 // CHECK: 102:36: CallExpr=endswith:56:8 Extent=[102:36 - 102:59]
 // CHECK: 102:45: MemberRefExpr=endswith:56:8 SingleRefName=[102:45 - 102:53] RefName=[102:45 - 102:53] Extent=[102:36 - 102:53]
 // CHECK: 102:36: UnexposedExpr=AttrName:101:19 Extent=[102:36 - 102:44]
@@ -1898,7 +1898,7 @@
 // CHECK: 102:54: UnexposedExpr=StringRef:48:3 Extent=[102:54 - 102:58]
 // CHECK: 102:54: CallExpr=StringRef:48:3 Extent=[102:54 - 102:58]
 // CHECK: 102:54: UnexposedExpr= Extent=[102:54 - 102:58]
-// CHECK: 102:54: StringLiteral= Extent=[102:54 - 102:58]
+// CHECK: 102:54: StringLiteral="__" Extent=[102:54 - 102:58]
 // CHECK: 103:5: CallExpr=operator=:38:7 Extent=[103:5 - 103:55]
 // CHECK: 103:5: DeclRefExpr=AttrName:101:19 Extent=[103:5 - 103:13]
 // CHECK: 103:14: UnexposedExpr=operator=:38:7
@@ -2085,158 +2085,158 @@
 // CHECK: 105:54: CallExpr=StringRef:38:7 Extent=[105:54 - 105:62]
 // CHECK: 105:54: UnexposedExpr=AttrName:101:19 Extent=[105:54 - 105:62]
 // CHECK: 105:54: DeclRefExpr=AttrName:101:19 Extent=[105:54 - 105:62]
-// CHECK: 106:11: StringLiteral= Extent=[106:11 - 106:17]
+// CHECK: 106:11: StringLiteral="weak" Extent=[106:11 - 106:17]
 // CHECK: 106:19: DeclRefExpr=AT_weak:29:45 Extent=[106:19 - 106:26]
-// CHECK: 107:11: StringLiteral= Extent=[107:11 - 107:20]
+// CHECK: 107:11: StringLiteral="weakref" Extent=[107:11 - 107:20]
 // CHECK: 107:22: DeclRefExpr=AT_weakref:29:54 Extent=[107:22 - 107:32]
-// CHECK: 108:11: StringLiteral= Extent=[108:11 - 108:17]
+// CHECK: 108:11: StringLiteral="pure" Extent=[108:11 - 108:17]
 // CHECK: 108:19: DeclRefExpr=AT_pure:26:49 Extent=[108:19 - 108:26]
-// CHECK: 109:11: StringLiteral= Extent=[109:11 - 109:17]
+// CHECK: 109:11: StringLiteral="mode" Extent=[109:11 - 109:17]
 // CHECK: 109:19: DeclRefExpr=AT_mode:20:44 Extent=[109:19 - 109:26]
-// CHECK: 110:11: StringLiteral= Extent=[110:11 - 110:17]
+// CHECK: 110:11: StringLiteral="used" Extent=[110:11 - 110:17]
 // CHECK: 110:19: DeclRefExpr=AT_used:28:34 Extent=[110:19 - 110:26]
-// CHECK: 111:11: StringLiteral= Extent=[111:11 - 111:18]
+// CHECK: 111:11: StringLiteral="alias" Extent=[111:11 - 111:18]
 // CHECK: 111:20: DeclRefExpr=AT_alias:15:25 Extent=[111:20 - 111:28]
-// CHECK: 112:11: StringLiteral= Extent=[112:11 - 112:18]
+// CHECK: 112:11: StringLiteral="align" Extent=[112:11 - 112:18]
 // CHECK: 112:20: DeclRefExpr=AT_aligned:15:35 Extent=[112:20 - 112:30]
-// CHECK: 113:11: StringLiteral= Extent=[113:11 - 113:18]
+// CHECK: 113:11: StringLiteral="final" Extent=[113:11 - 113:18]
 // CHECK: 113:20: DeclRefExpr=AT_final:19:40 Extent=[113:20 - 113:28]
-// CHECK: 114:11: StringLiteral= Extent=[114:11 - 114:18]
+// CHECK: 114:11: StringLiteral="cdecl" Extent=[114:11 - 114:18]
 // CHECK: 114:20: DeclRefExpr=AT_cdecl:17:30 Extent=[114:20 - 114:28]
-// CHECK: 115:11: StringLiteral= Extent=[115:11 - 115:18]
+// CHECK: 115:11: StringLiteral="const" Extent=[115:11 - 115:18]
 // CHECK: 115:20: DeclRefExpr=AT_const:17:52 Extent=[115:20 - 115:28]
-// CHECK: 116:11: StringLiteral= Extent=[116:11 - 116:20]
+// CHECK: 116:11: StringLiteral="__const" Extent=[116:11 - 116:20]
 // CHECK: 116:22: DeclRefExpr=AT_const:17:52 Extent=[116:22 - 116:30]
-// CHECK: 117:11: StringLiteral= Extent=[117:11 - 117:19]
+// CHECK: 117:11: StringLiteral="blocks" Extent=[117:11 - 117:19]
 // CHECK: 117:21: DeclRefExpr=AT_blocks:16:57 Extent=[117:21 - 117:30]
-// CHECK: 118:11: StringLiteral= Extent=[118:11 - 118:19]
+// CHECK: 118:11: StringLiteral="format" Extent=[118:11 - 118:19]
 // CHECK: 118:21: DeclRefExpr=AT_format:19:50 Extent=[118:21 - 118:30]
-// CHECK: 119:11: StringLiteral= Extent=[119:11 - 119:19]
+// CHECK: 119:11: StringLiteral="hiding" Extent=[119:11 - 119:19]
 // CHECK: 119:21: DeclRefExpr=AT_hiding:20:22 Extent=[119:21 - 119:30]
-// CHECK: 120:11: StringLiteral= Extent=[120:11 - 120:19]
+// CHECK: 120:11: StringLiteral="malloc" Extent=[120:11 - 120:19]
 // CHECK: 120:21: DeclRefExpr=AT_malloc:20:33 Extent=[120:21 - 120:30]
-// CHECK: 121:11: StringLiteral= Extent=[121:11 - 121:19]
+// CHECK: 121:11: StringLiteral="packed" Extent=[121:11 - 121:19]
 // CHECK: 121:21: DeclRefExpr=AT_packed:26:27 Extent=[121:21 - 121:30]
-// CHECK: 122:11: StringLiteral= Extent=[122:11 - 122:19]
+// CHECK: 122:11: StringLiteral="unused" Extent=[122:11 - 122:19]
 // CHECK: 122:21: DeclRefExpr=AT_unused:28:23 Extent=[122:21 - 122:30]
-// CHECK: 123:11: StringLiteral= Extent=[123:11 - 123:20]
+// CHECK: 123:11: StringLiteral="aligned" Extent=[123:11 - 123:20]
 // CHECK: 123:22: DeclRefExpr=AT_aligned:15:35 Extent=[123:22 - 123:32]
-// CHECK: 124:11: StringLiteral= Extent=[124:11 - 124:20]
+// CHECK: 124:11: StringLiteral="cleanup" Extent=[124:11 - 124:20]
 // CHECK: 124:22: DeclRefExpr=AT_cleanup:17:40 Extent=[124:22 - 124:32]
-// CHECK: 125:11: StringLiteral= Extent=[125:11 - 125:18]
+// CHECK: 125:11: StringLiteral="naked" Extent=[125:11 - 125:18]
 // CHECK: 125:20: DeclRefExpr=AT_naked:20:53 Extent=[125:20 - 125:28]
-// CHECK: 126:11: StringLiteral= Extent=[126:11 - 126:20]
+// CHECK: 126:11: StringLiteral="nodebug" Extent=[126:11 - 126:20]
 // CHECK: 126:22: DeclRefExpr=AT_nodebug:20:63 Extent=[126:22 - 126:32]
-// CHECK: 127:11: StringLiteral= Extent=[127:11 - 127:20]
+// CHECK: 127:11: StringLiteral="nonnull" Extent=[127:11 - 127:20]
 // CHECK: 127:22: DeclRefExpr=AT_nonnull:21:47 Extent=[127:22 - 127:32]
-// CHECK: 128:11: StringLiteral= Extent=[128:11 - 128:20]
+// CHECK: 128:11: StringLiteral="nothrow" Extent=[128:11 - 128:20]
 // CHECK: 128:22: DeclRefExpr=AT_nothrow:22:7 Extent=[128:22 - 128:32]
-// CHECK: 129:11: StringLiteral= Extent=[129:11 - 129:20]
+// CHECK: 129:11: StringLiteral="objc_gc" Extent=[129:11 - 129:20]
 // CHECK: 129:22: DeclRefExpr=AT_objc_gc:24:59 Extent=[129:22 - 129:32]
-// CHECK: 130:11: StringLiteral= Extent=[130:11 - 130:20]
+// CHECK: 130:11: StringLiteral="regparm" Extent=[130:11 - 130:20]
 // CHECK: 130:22: DeclRefExpr=AT_regparm:26:58 Extent=[130:22 - 130:32]
-// CHECK: 131:11: StringLiteral= Extent=[131:11 - 131:20]
+// CHECK: 131:11: StringLiteral="section" Extent=[131:11 - 131:20]
 // CHECK: 131:22: DeclRefExpr=AT_section:27:7 Extent=[131:22 - 131:32]
-// CHECK: 132:11: StringLiteral= Extent=[132:11 - 132:20]
+// CHECK: 132:11: StringLiteral="stdcall" Extent=[132:11 - 132:20]
 // CHECK: 132:22: DeclRefExpr=AT_stdcall:27:32 Extent=[132:22 - 132:32]
-// CHECK: 133:11: StringLiteral= Extent=[133:11 - 133:21]
+// CHECK: 133:11: StringLiteral="annotate" Extent=[133:11 - 133:21]
 // CHECK: 133:23: DeclRefExpr=AT_annotate:16:29 Extent=[133:23 - 133:34]
-// CHECK: 134:11: StringLiteral= Extent=[134:11 - 134:21]
+// CHECK: 134:11: StringLiteral="fastcall" Extent=[134:11 - 134:21]
 // CHECK: 134:23: DeclRefExpr=AT_fastcall:19:27 Extent=[134:23 - 134:34]
-// CHECK: 135:11: StringLiteral= Extent=[135:11 - 135:21]
+// CHECK: 135:11: StringLiteral="ibaction" Extent=[135:11 - 135:21]
 // CHECK: 135:23: DeclRefExpr=AT_IBAction:14:7 Extent=[135:23 - 135:34]
-// CHECK: 136:11: StringLiteral= Extent=[136:11 - 136:21]
+// CHECK: 136:11: StringLiteral="iboutlet" Extent=[136:11 - 136:21]
 // CHECK: 136:23: DeclRefExpr=AT_IBOutlet:14:20 Extent=[136:23 - 136:34]
-// CHECK: 137:11: StringLiteral= Extent=[137:11 - 137:31]
+// CHECK: 137:11: StringLiteral="iboutletcollection" Extent=[137:11 - 137:31]
 // CHECK: 137:33: DeclRefExpr=AT_IBOutletCollection:14:33 Extent=[137:33 - 137:54]
-// CHECK: 138:11: StringLiteral= Extent=[138:11 - 138:21]
+// CHECK: 138:11: StringLiteral="noreturn" Extent=[138:11 - 138:21]
 // CHECK: 138:23: DeclRefExpr=AT_noreturn:21:59 Extent=[138:23 - 138:34]
-// CHECK: 139:11: StringLiteral= Extent=[139:11 - 139:21]
+// CHECK: 139:11: StringLiteral="noinline" Extent=[139:11 - 139:21]
 // CHECK: 139:23: DeclRefExpr=AT_noinline:21:7 Extent=[139:23 - 139:34]
-// CHECK: 140:11: StringLiteral= Extent=[140:11 - 140:21]
+// CHECK: 140:11: StringLiteral="override" Extent=[140:11 - 140:21]
 // CHECK: 140:23: DeclRefExpr=AT_override:22:51 Extent=[140:23 - 140:34]
-// CHECK: 141:11: StringLiteral= Extent=[141:11 - 141:21]
+// CHECK: 141:11: StringLiteral="sentinel" Extent=[141:11 - 141:21]
 // CHECK: 141:23: DeclRefExpr=AT_sentinel:27:19 Extent=[141:23 - 141:34]
-// CHECK: 142:11: StringLiteral= Extent=[142:11 - 142:21]
+// CHECK: 142:11: StringLiteral="NSObject" Extent=[142:11 - 142:21]
 // CHECK: 142:23: DeclRefExpr=AT_nsobject:22:19 Extent=[142:23 - 142:34]
-// CHECK: 143:11: StringLiteral= Extent=[143:11 - 143:22]
+// CHECK: 143:11: StringLiteral="dllimport" Extent=[143:11 - 143:22]
 // CHECK: 143:24: DeclRefExpr=AT_dllimport:18:51 Extent=[143:24 - 143:36]
-// CHECK: 144:11: StringLiteral= Extent=[144:11 - 144:22]
+// CHECK: 144:11: StringLiteral="dllexport" Extent=[144:11 - 144:22]
 // CHECK: 144:24: DeclRefExpr=AT_dllexport:18:37 Extent=[144:24 - 144:36]
-// CHECK: 145:11: StringLiteral= Extent=[145:11 - 145:22]
-// CHECK: 146:11: StringLiteral= Extent=[146:11 - 146:23]
+// CHECK: 145:11: StringLiteral="may_alias" Extent=[145:11 - 145:22]
+// CHECK: 146:11: StringLiteral="base_check" Extent=[146:11 - 146:23]
 // CHECK: 146:25: DeclRefExpr=AT_base_check:16:42 Extent=[146:25 - 146:38]
-// CHECK: 147:11: StringLiteral= Extent=[147:11 - 147:23]
+// CHECK: 147:11: StringLiteral="deprecated" Extent=[147:11 - 147:23]
 // CHECK: 147:25: DeclRefExpr=AT_deprecated:18:7 Extent=[147:25 - 147:38]
-// CHECK: 148:11: StringLiteral= Extent=[148:11 - 148:23]
+// CHECK: 148:11: StringLiteral="visibility" Extent=[148:11 - 148:23]
 // CHECK: 148:25: DeclRefExpr=AT_visibility:29:7 Extent=[148:25 - 148:38]
-// CHECK: 149:11: StringLiteral= Extent=[149:11 - 149:23]
+// CHECK: 149:11: StringLiteral="destructor" Extent=[149:11 - 149:23]
 // CHECK: 149:25: DeclRefExpr=AT_destructor:18:22 Extent=[149:25 - 149:38]
-// CHECK: 150:11: StringLiteral= Extent=[150:11 - 150:23]
+// CHECK: 150:11: StringLiteral="format_arg" Extent=[150:11 - 150:23]
 // CHECK: 150:25: DeclRefExpr=AT_format_arg:19:61 Extent=[150:25 - 150:38]
-// CHECK: 151:11: StringLiteral= Extent=[151:11 - 151:23]
+// CHECK: 151:11: StringLiteral="gnu_inline" Extent=[151:11 - 151:23]
 // CHECK: 151:25: DeclRefExpr=AT_gnu_inline:20:7 Extent=[151:25 - 151:38]
-// CHECK: 152:11: StringLiteral= Extent=[152:11 - 152:24]
+// CHECK: 152:11: StringLiteral="weak_import" Extent=[152:11 - 152:24]
 // CHECK: 152:26: DeclRefExpr=AT_weak_import:30:7 Extent=[152:26 - 152:40]
-// CHECK: 153:11: StringLiteral= Extent=[153:11 - 153:22]
+// CHECK: 153:11: StringLiteral="vecreturn" Extent=[153:11 - 153:22]
 // CHECK: 153:24: DeclRefExpr=AT_vecreturn:28:43 Extent=[153:24 - 153:36]
-// CHECK: 154:11: StringLiteral= Extent=[154:11 - 154:24]
+// CHECK: 154:11: StringLiteral="vector_size" Extent=[154:11 - 154:24]
 // CHECK: 154:26: DeclRefExpr=AT_vector_size:28:57 Extent=[154:26 - 154:40]
-// CHECK: 155:11: StringLiteral= Extent=[155:11 - 155:24]
+// CHECK: 155:11: StringLiteral="constructor" Extent=[155:11 - 155:24]
 // CHECK: 155:26: DeclRefExpr=AT_constructor:17:62 Extent=[155:26 - 155:40]
-// CHECK: 156:11: StringLiteral= Extent=[156:11 - 156:24]
+// CHECK: 156:11: StringLiteral="unavailable" Extent=[156:11 - 156:24]
 // CHECK: 156:26: DeclRefExpr=AT_unavailable:28:7 Extent=[156:26 - 156:40]
-// CHECK: 157:11: StringLiteral= Extent=[157:11 - 157:25]
+// CHECK: 157:11: StringLiteral="overloadable" Extent=[157:11 - 157:25]
 // CHECK: 157:27: DeclRefExpr=AT_overloadable:25:7 Extent=[157:27 - 157:42]
-// CHECK: 158:11: StringLiteral= Extent=[158:11 - 158:26]
+// CHECK: 158:11: StringLiteral="address_space" Extent=[158:11 - 158:26]
 // CHECK: 158:28: DeclRefExpr=AT_address_space:15:7 Extent=[158:28 - 158:44]
-// CHECK: 159:11: StringLiteral= Extent=[159:11 - 159:26]
+// CHECK: 159:11: StringLiteral="always_inline" Extent=[159:11 - 159:26]
 // CHECK: 159:28: DeclRefExpr=AT_always_inline:15:47 Extent=[159:28 - 159:44]
-// CHECK: 160:11: StringLiteral= Extent=[160:11 - 160:26]
-// CHECK: 161:11: StringLiteral= Extent=[161:11 - 161:26]
-// CHECK: 162:11: StringLiteral= Extent=[162:11 - 162:27]
+// CHECK: 160:11: StringLiteral="returns_twice" Extent=[160:11 - 160:26]
+// CHECK: 161:11: StringLiteral="vec_type_hint" Extent=[161:11 - 161:26]
+// CHECK: 162:11: StringLiteral="objc_exception" Extent=[162:11 - 162:27]
 // CHECK: 162:29: DeclRefExpr=AT_objc_exception:22:32 Extent=[162:29 - 162:46]
-// CHECK: 163:11: StringLiteral= Extent=[163:11 - 163:28]
+// CHECK: 163:11: StringLiteral="ext_vector_type" Extent=[163:11 - 163:28]
 // CHECK: 163:30: DeclRefExpr=AT_ext_vector_type:19:7 Extent=[163:30 - 163:48]
-// CHECK: 164:11: StringLiteral= Extent=[164:11 - 164:30]
+// CHECK: 164:11: StringLiteral="transparent_union" Extent=[164:11 - 164:30]
 // CHECK: 164:32: DeclRefExpr=AT_transparent_union:27:57 Extent=[164:32 - 164:52]
-// CHECK: 165:11: StringLiteral= Extent=[165:11 - 165:30]
+// CHECK: 165:11: StringLiteral="analyzer_noreturn" Extent=[165:11 - 165:30]
 // CHECK: 165:32: DeclRefExpr=AT_analyzer_noreturn:16:7 Extent=[165:32 - 165:52]
-// CHECK: 166:11: StringLiteral= Extent=[166:11 - 166:31]
+// CHECK: 166:11: StringLiteral="warn_unused_result" Extent=[166:11 - 166:31]
 // CHECK: 166:33: DeclRefExpr=AT_warn_unused_result:29:22 Extent=[166:33 - 166:54]
-// CHECK: 167:11: StringLiteral= Extent=[167:11 - 167:31]
+// CHECK: 167:11: StringLiteral="carries_dependency" Extent=[167:11 - 167:31]
 // CHECK: 167:33: DeclRefExpr=AT_carries_dependency:17:7 Extent=[167:33 - 167:54]
-// CHECK: 168:11: StringLiteral= Extent=[168:11 - 168:36]
+// CHECK: 168:11: StringLiteral="ns_returns_not_retained" Extent=[168:11 - 168:36]
 // CHECK: 168:38: DeclRefExpr=AT_ns_returns_not_retained:24:7 Extent=[168:38 - 168:64]
-// CHECK: 169:11: StringLiteral= Extent=[169:11 - 169:32]
+// CHECK: 169:11: StringLiteral="ns_returns_retained" Extent=[169:11 - 169:32]
 // CHECK: 169:34: DeclRefExpr=AT_ns_returns_retained:24:35 Extent=[169:34 - 169:56]
-// CHECK: 170:11: StringLiteral= Extent=[170:11 - 170:36]
+// CHECK: 170:11: StringLiteral="cf_returns_not_retained" Extent=[170:11 - 170:36]
 // CHECK: 170:38: DeclRefExpr=AT_cf_returns_not_retained:23:7 Extent=[170:38 - 170:64]
-// CHECK: 171:11: StringLiteral= Extent=[171:11 - 171:32]
+// CHECK: 171:11: StringLiteral="cf_returns_retained" Extent=[171:11 - 171:32]
 // CHECK: 171:34: DeclRefExpr=AT_cf_returns_retained:23:35 Extent=[171:34 - 171:56]
-// CHECK: 172:11: StringLiteral= Extent=[172:11 - 172:30]
+// CHECK: 172:11: StringLiteral="ownership_returns" Extent=[172:11 - 172:30]
 // CHECK: 172:32: DeclRefExpr=AT_ownership_returns:25:44 Extent=[172:32 - 172:52]
-// CHECK: 173:11: StringLiteral= Extent=[173:11 - 173:28]
+// CHECK: 173:11: StringLiteral="ownership_holds" Extent=[173:11 - 173:28]
 // CHECK: 173:30: DeclRefExpr=AT_ownership_holds:25:24 Extent=[173:30 - 173:48]
-// CHECK: 174:11: StringLiteral= Extent=[174:11 - 174:28]
+// CHECK: 174:11: StringLiteral="ownership_takes" Extent=[174:11 - 174:28]
 // CHECK: 174:30: DeclRefExpr=AT_ownership_takes:26:7 Extent=[174:30 - 174:48]
-// CHECK: 175:11: StringLiteral= Extent=[175:11 - 175:33]
+// CHECK: 175:11: StringLiteral="reqd_work_group_size" Extent=[175:11 - 175:33]
 // CHECK: 175:35: DeclRefExpr=AT_reqd_wg_size:30:23 Extent=[175:35 - 175:50]
-// CHECK: 176:11: StringLiteral= Extent=[176:11 - 176:26]
+// CHECK: 176:11: StringLiteral="init_priority" Extent=[176:11 - 176:26]
 // CHECK: 176:28: DeclRefExpr=AT_init_priority:30:40 Extent=[176:28 - 176:44]
-// CHECK: 177:11: StringLiteral= Extent=[177:11 - 177:35]
+// CHECK: 177:11: StringLiteral="no_instrument_function" Extent=[177:11 - 177:35]
 // CHECK: 177:37: DeclRefExpr=AT_no_instrument_function:21:20 Extent=[177:37 - 177:62]
-// CHECK: 178:11: StringLiteral= Extent=[178:11 - 178:21]
+// CHECK: 178:11: StringLiteral="thiscall" Extent=[178:11 - 178:21]
 // CHECK: 178:23: DeclRefExpr=AT_thiscall:27:44 Extent=[178:23 - 178:34]
-// CHECK: 179:11: StringLiteral= Extent=[179:11 - 179:19]
+// CHECK: 179:11: StringLiteral="pascal" Extent=[179:11 - 179:19]
 // CHECK: 179:21: DeclRefExpr=AT_pascal:26:38 Extent=[179:21 - 179:30]
-// CHECK: 180:11: StringLiteral= Extent=[180:11 - 180:20]
+// CHECK: 180:11: StringLiteral="__cdecl" Extent=[180:11 - 180:20]
 // CHECK: 180:22: DeclRefExpr=AT_cdecl:17:30 Extent=[180:22 - 180:30]
-// CHECK: 181:11: StringLiteral= Extent=[181:11 - 181:22]
+// CHECK: 181:11: StringLiteral="__stdcall" Extent=[181:11 - 181:22]
 // CHECK: 181:24: DeclRefExpr=AT_stdcall:27:32 Extent=[181:24 - 181:34]
-// CHECK: 182:11: StringLiteral= Extent=[182:11 - 182:23]
+// CHECK: 182:11: StringLiteral="__fastcall" Extent=[182:11 - 182:23]
 // CHECK: 182:25: DeclRefExpr=AT_fastcall:19:27 Extent=[182:25 - 182:36]
-// CHECK: 183:11: StringLiteral= Extent=[183:11 - 183:23]
+// CHECK: 183:11: StringLiteral="__thiscall" Extent=[183:11 - 183:23]
 // CHECK: 183:25: DeclRefExpr=AT_thiscall:27:44 Extent=[183:25 - 183:36]
-// CHECK: 184:11: StringLiteral= Extent=[184:11 - 184:21]
+// CHECK: 184:11: StringLiteral="__pascal" Extent=[184:11 - 184:21]
 // CHECK: 184:23: DeclRefExpr=AT_pascal:26:38 Extent=[184:23 - 184:32]
diff --git a/test/Index/remap-complete.c b/test/Index/remap-complete.c
index 93fb623..ffc467f 100644
--- a/test/Index/remap-complete.c
+++ b/test/Index/remap-complete.c
@@ -1,4 +1,4 @@
-// RUN: c-index-test -code-completion-at=%s:6:2 -remap-file="%s;%S/Inputs/remap-complete-to.c" %s | FileCheck %s
+// RUN: c-index-test -code-completion-at=%s:6:2 -remap-file="%s,%S/Inputs/remap-complete-to.c" %s | FileCheck %s
 
 // CHECK: FunctionDecl:{ResultType int}{TypedText f0}{LeftParen (}
 void f() { }
diff --git a/test/Index/remap-cursor-at.c b/test/Index/remap-cursor-at.c
index c2bed0e..782b6bb 100644
--- a/test/Index/remap-cursor-at.c
+++ b/test/Index/remap-cursor-at.c
@@ -1,4 +1,4 @@
-// RUN: c-index-test -cursor-at=%s:1:15 -cursor-at=%s:2:21 -remap-file="%s;%S/Inputs/remap-load-to.c" %s | FileCheck %s
+// RUN: c-index-test -cursor-at=%s:1:15 -cursor-at=%s:2:21 -remap-file="%s,%S/Inputs/remap-load-to.c" %s | FileCheck %s
 
 // CHECK: ParmDecl=parm1:1:13 (Definition)
 // CHECK: DeclRefExpr=parm2:1:26
diff --git a/test/Index/remap-load.c b/test/Index/remap-load.c
index 2608874..f433fa7 100644
--- a/test/Index/remap-load.c
+++ b/test/Index/remap-load.c
@@ -1,4 +1,4 @@
-// RUN: c-index-test -test-load-source all -remap-file="%s;%S/Inputs/remap-load-to.c" %s | FileCheck -check-prefix=CHECK %s
+// RUN: c-index-test -test-load-source all -remap-file="%s,%S/Inputs/remap-load-to.c" %s | FileCheck -check-prefix=CHECK %s
 
 // CHECK: remap-load.c:1:5: FunctionDecl=foo:1:5 (Definition) Extent=[1:1 - 3:2]
 // CHECK: remap-load.c:1:13: ParmDecl=parm1:1:13 (Definition) Extent=[1:9 - 1:18]
diff --git a/test/Index/reparse-with-remaps/reparse.c b/test/Index/reparse-with-remaps/reparse.c
new file mode 100644
index 0000000..617626b
--- /dev/null
+++ b/test/Index/reparse-with-remaps/reparse.c
@@ -0,0 +1,8 @@
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_BRIEF_COMMENTS=1 LIBCLANG_DISABLE_CRASH_RECOVERY=1 \
+// RUN:   c-index-test -test-load-source-reparse 2 all -remap-file-0="%S/test.h,%S/test.h-0" -remap-file-1="%S/test.h,%S/test.h-1" -- %s
+
+#include "test.h"
+
+void foo() {
+  bar();
+}
diff --git a/test/Index/reparse-with-remaps/test.h b/test/Index/reparse-with-remaps/test.h
new file mode 100644
index 0000000..3e2adb0
--- /dev/null
+++ b/test/Index/reparse-with-remaps/test.h
@@ -0,0 +1,3 @@
+
+/// Comment for bar
+void bar(void);
diff --git a/test/Index/reparse-with-remaps/test.h-0 b/test/Index/reparse-with-remaps/test.h-0
new file mode 100644
index 0000000..0d666a7
--- /dev/null
+++ b/test/Index/reparse-with-remaps/test.h-0
@@ -0,0 +1,6 @@
+void test1(void);
+
+/// Comment for bar
+void bar(void);
+void test3(void);
+
diff --git a/test/Index/reparse-with-remaps/test.h-1 b/test/Index/reparse-with-remaps/test.h-1
new file mode 100644
index 0000000..1eed01e
--- /dev/null
+++ b/test/Index/reparse-with-remaps/test.h-1
@@ -0,0 +1,6 @@
+
+void test1(void);
+void test2(void);
+
+/// Comment for bar
+void bar(void);
diff --git a/test/Index/retain-comments-from-system-headers.c b/test/Index/retain-comments-from-system-headers.c
index 67a0fd0..490699d 100644
--- a/test/Index/retain-comments-from-system-headers.c
+++ b/test/Index/retain-comments-from-system-headers.c
@@ -8,12 +8,16 @@
  */
 int user_function(int a);
 
+// RUN: rm -rf %t/cache
 // RUN: c-index-test -test-load-source all %s -I %S/Inputs | FileCheck %s
 // RUN: c-index-test -test-load-source all %s -fretain-comments-from-system-headers -I %S/Inputs | FileCheck %s -check-prefix=CHECK-RETAIN
 
+// Modules:
+// RUN: c-index-test -test-load-source all %s -I %S/Inputs -fmodules -fmodules-cache-path=%t/cache -fmodule-map-file=%S/Inputs/retain-comments-from-system-headers-module.map | FileCheck %s -check-prefix=CHECK
+// RUN: c-index-test -test-load-source all %s -fretain-comments-from-system-headers -I %S/Inputs -fmodules -fmodules-cache-path=%t/cache -fmodule-map-file=%S/Inputs/retain-comments-from-system-headers-module.map | FileCheck %s -check-prefix=CHECK-RETAIN
+
 // CHECK: retain-comments-from-system-headers.h:7:5: FunctionDecl=system_function:7:5 Extent=[7:1 - 7:27]
 // CHECK: retain-comments-from-system-headers.c:9:5: FunctionDecl=user_function:9:5 RawComment=[/**\n * user_function\n * \param a Aaa.\n */] RawCommentRange=[5:1 - 8:4] BriefComment=[user_function]
 
 // CHECK-RETAIN: retain-comments-from-system-headers.h:7:5: FunctionDecl=system_function:7:5 RawComment=[/**\n * system_function\n * \param a Aaa.\n */] RawCommentRange=[3:1 - 6:4] BriefComment=[system_function]
 // CHECK-RETAIN: retain-comments-from-system-headers.c:9:5: FunctionDecl=user_function:9:5 RawComment=[/**\n * user_function\n * \param a Aaa.\n */] RawCommentRange=[5:1 - 8:4] BriefComment=[user_function]
-
diff --git a/test/Index/skipped-ranges.c b/test/Index/skipped-ranges.c
new file mode 100644
index 0000000..bd16fb3
--- /dev/null
+++ b/test/Index/skipped-ranges.c
@@ -0,0 +1,25 @@
+#define cool
+
+#if defined(cool)
+
+#if defined(really_cool)
+#endif // really_cool
+
+#elif defined(hot)
+// hot
+
+
+#endif // trailing comment
+
+#ifndef cool
+#ifndef uncool
+
+int probably_hot = 1;
+
+#endif // uncool
+#endif // cool
+
+// RUN: env CINDEXTEST_SHOW_SKIPPED_RANGES=1 c-index-test -test-annotate-tokens=%s:1:1:16:1 %s | FileCheck %s
+// CHECK: Skipping: [5:2 - 6:7]
+// CHECK: Skipping: [8:2 - 12:7]
+// CHECK: Skipping: [14:2 - 20:7]
diff --git a/test/Index/usrs.cpp b/test/Index/usrs.cpp
index e350f5c..909ce75 100644
--- a/test/Index/usrs.cpp
+++ b/test/Index/usrs.cpp
@@ -85,7 +85,7 @@
 // CHECK: usrs.cpp c:@N@foo@F@bar#I# Extent=[3:3 - 3:18]
 // CHECK: usrs.cpp c:usrs.cpp@36@N@foo@F@bar#I#@z Extent=[3:12 - 3:17]
 // CHECK: usrs.cpp c:@N@bar Extent=[5:1 - 8:2]
-// CHECK: usrs.cpp c:usrs.cpp@64@N@bar@T@QType Extent=[6:3 - 6:20]
+// CHECK: usrs.cpp c:usrs.cpp@N@bar@T@QType Extent=[6:3 - 6:20]
 // CHECK: usrs.cpp c:@N@bar@F@bar#I# Extent=[7:3 - 7:20]
 // CHECK: usrs.cpp c:usrs.cpp@94@N@bar@F@bar#I#@z Extent=[7:12 - 7:19]
 // CHECK: usrs.cpp c:@C@ClsA Extent=[10:1 - 14:2]
@@ -101,13 +101,13 @@
 // CHECK: usrs.cpp c:@N@foo@C@ClsB@F@ClsB# Extent=[19:5 - 19:27]
 // CHECK: usrs.cpp c:@N@foo@C@ClsB@F@result#1 Extent=[20:5 - 20:23]
 // CHECK: usrs.cpp c:@N@foo@C@ClsB@F@result#1 Extent=[24:1 - 26:2]
-// CHECK: usrs.cpp c:usrs.cpp@360@aN@C@ClsC Extent=[29:3 - 29:35]
-// CHECK: usrs.cpp c:usrs.cpp@396@aN@w Extent=[30:3 - 30:8]
+// CHECK: usrs.cpp c:usrs.cpp@aN@C@ClsC Extent=[29:3 - 29:35]
+// CHECK: usrs.cpp c:usrs.cpp@aN@w Extent=[30:3 - 30:8]
 // CHECK: usrs.cpp c:@z Extent=[33:1 - 33:6]
 // CHECK: usrs.cpp c:@N@foo Extent=[35:1 - 40:2]
 // CHECK: usrs.cpp c:@N@foo@N@taz Extent=[35:17 - 39:2]
 // CHECK: usrs.cpp c:@N@foo@N@taz@x Extent=[36:3 - 36:8]
-// CHECK: usrs.cpp c:usrs.cpp@457@N@foo@N@taz@F@add#I#I# Extent=[37:3 - 37:56]
+// CHECK: usrs.cpp c:usrs.cpp@N@foo@N@taz@F@add#I#I# Extent=[37:3 - 37:56]
 // CHECK: usrs.cpp c:usrs.cpp@479@N@foo@N@taz@F@add#I#I#@a Extent=[37:25 - 37:30]
 // CHECK: usrs.cpp c:usrs.cpp@486@N@foo@N@taz@F@add#I#I#@b Extent=[37:32 - 37:37]
 // CHECK: usrs.cpp c:@N@foo@N@taz@F@sub#I#I# Extent=[38:3 - 38:25]
@@ -137,10 +137,10 @@
 // CHECK-NOT: ClsB
 // CHECK: usrs.cpp c:@NA@foo_alias3
 // CHECK: usrs.cpp c:@aN Extent=[68:1 - 73:2]
-// CHECK: usrs.cpp c:usrs.cpp@1097@aN@C@RDar9371763_Foo Extent=[69:1 - 72:2]
+// CHECK: usrs.cpp c:usrs.cpp@aN@C@RDar9371763_Foo Extent=[69:1 - 72:2]
 // CHECK: usrs.cpp c: Extent=[70:1 - 70:8]
-// CHECK: usrs.cpp c:usrs.cpp@1131@aN@C@RDar9371763_Foo@F@bar# Extent=[71:3 - 71:13]
-// CHECK: usrs.cpp c:usrs.cpp@1131@aN@C@RDar9371763_Foo@F@bar# Extent=[75:1 - 75:31]
+// CHECK: usrs.cpp c:usrs.cpp@aN@C@RDar9371763_Foo@F@bar# Extent=[71:3 - 71:13]
+// CHECK: usrs.cpp c:usrs.cpp@aN@C@RDar9371763_Foo@F@bar# Extent=[75:1 - 75:31]
 // CHECK: usrs.cpp c:@F@rdar9371763# Extent=[77:1 - 80:2]
 // CHECK: usrs.cpp c:usrs.cpp@1204@F@rdar9371763#@foo Extent=[78:3 - 78:22]
 
diff --git a/test/Index/usrs.m b/test/Index/usrs.m
index cc2e0fd..fc3fbc9 100644
--- a/test/Index/usrs.m
+++ b/test/Index/usrs.m
@@ -89,20 +89,37 @@
 -(int)methodWithFn:(void (*)(int *p))fn;
 @end
 
-// RUN: c-index-test -test-load-source-usrs all -target x86_64-apple-macosx10.7 %s | FileCheck %s
-// CHECK: usrs.m c:usrs.m@67@F@my_helper Extent=[3:1 - 3:60]
+#include <usrs-system.h>
+
+#define MACRO1 123
+
+#define MACRO2 123
+#undef MACRO2
+#define MACRO2 789
+
+#define MACRO3(X) 123, X
+#define MACRO3(X) 789, X
+
+// RUN: c-index-test -test-load-source-usrs all -target x86_64-apple-macosx10.7 %s -isystem %S/Inputs | FileCheck %s
+// CHECK: usrs-system.h c:@macro@MACRO_FROM_SYSTEM_HEADER_1 Extent=[1:9 - 1:40]
+// CHECK: usrs.m c:usrs.m@1265@macro@MACRO1 Extent=[94:9 - 94:19]
+// CHECK: usrs.m c:usrs.m@1285@macro@MACRO2 Extent=[96:9 - 96:19]
+// CHECK: usrs.m c:usrs.m@1318@macro@MACRO2 Extent=[98:9 - 98:19]
+// CHECK: usrs.m c:usrs.m@1338@macro@MACRO3 Extent=[100:9 - 100:25]
+// CHECK: usrs.m c:usrs.m@1363@macro@MACRO3 Extent=[101:9 - 101:25]
+// CHECK: usrs.m c:usrs.m@F@my_helper Extent=[3:1 - 3:60]
 // CHECK: usrs.m c:usrs.m@95@F@my_helper@x Extent=[3:29 - 3:34]
 // CHECK: usrs.m c:usrs.m@102@F@my_helper@y Extent=[3:36 - 3:41]
-// CHECK: usrs.m c:usrs.m@128@Ea Extent=[5:1 - 8:2]
-// CHECK: usrs.m c:usrs.m@128@Ea@ABA Extent=[6:3 - 6:6]
-// CHECK: usrs.m c:usrs.m@128@Ea@CADABA Extent=[7:3 - 7:9]
-// CHECK: usrs.m c:usrs.m@155@Ea Extent=[10:1 - 13:2]
-// CHECK: usrs.m c:usrs.m@155@Ea@FOO Extent=[11:3 - 11:6]
-// CHECK: usrs.m c:usrs.m@155@Ea@BAR Extent=[12:3 - 12:6]
+// CHECK: usrs.m c:usrs.m@Ea Extent=[5:1 - 8:2]
+// CHECK: usrs.m c:usrs.m@Ea@ABA Extent=[6:3 - 6:6]
+// CHECK: usrs.m c:usrs.m@Ea@CADABA Extent=[7:3 - 7:9]
+// CHECK: usrs.m c:usrs.m@Ea Extent=[10:1 - 13:2]
+// CHECK: usrs.m c:usrs.m@Ea@FOO Extent=[11:3 - 11:6]
+// CHECK: usrs.m c:usrs.m@Ea@BAR Extent=[12:3 - 12:6]
 // CHECK: usrs.m c:@SA@MyStruct Extent=[15:9 - 18:2]
 // CHECK: usrs.m c:@SA@MyStruct@FI@wa Extent=[16:3 - 16:9]
 // CHECK: usrs.m c:@SA@MyStruct@FI@moo Extent=[17:3 - 17:10]
-// CHECK: usrs.m c:usrs.m@179@T@MyStruct Extent=[15:1 - 18:11]
+// CHECK: usrs.m c:usrs.m@T@MyStruct Extent=[15:1 - 18:11]
 // CHECK: usrs.m c:@E@Pizza Extent=[20:1 - 23:2]
 // CHECK: usrs.m c:@E@Pizza@CHEESE Extent=[21:3 - 21:9]
 // CHECK: usrs.m c:@E@Pizza@MUSHROOMS Extent=[22:3 - 22:12]
@@ -123,7 +140,7 @@
 // CHECK: usrs.m c:usrs.m@470objc(cs)Foo(cm)kingkong@local_var Extent=[41:3 - 41:16]
 // CHECK: usrs.m c:objc(cs)Foo(py)d1 Extent=[44:1 - 44:15]
 // CHECK: usrs.m c:@z Extent=[47:1 - 47:6]
-// CHECK: usrs.m c:usrs.m@529@F@local_func Extent=[49:1 - 49:43]
+// CHECK: usrs.m c:usrs.m@F@local_func Extent=[49:1 - 49:43]
 // CHECK: usrs.m c:usrs.m@551@F@local_func@x Extent=[49:23 - 49:28]
 // CHECK: usrs.m c:objc(cs)CWithExt Extent=[51:1 - 53:5]
 // CHECK: usrs.m c:objc(cs)CWithExt(im)meth1 Extent=[52:1 - 52:14]
@@ -153,7 +170,13 @@
 // CHECK: usrs.m c:objc(cs)CWithExt2(im)pro_ext Extent=[88:23 - 88:30]
 // CHECK: usrs.m c:objc(cs)CWithExt2(im)setPro_ext: Extent=[88:23 - 88:30]
 
-// RUN: c-index-test -test-load-source all %s | FileCheck -check-prefix=CHECK-source %s
+// RUN: c-index-test -test-load-source all %s -isystem %S/Inputs | FileCheck -check-prefix=CHECK-source %s
+// CHECK-source: usrs-system.h:1:9: macro definition=MACRO_FROM_SYSTEM_HEADER_1 Extent=[1:9 - 1:40]
+// CHECK-source: usrs.m:94:9: macro definition=MACRO1 Extent=[94:9 - 94:19]
+// CHECK-source: usrs.m:96:9: macro definition=MACRO2 Extent=[96:9 - 96:19]
+// CHECK-source: usrs.m:98:9: macro definition=MACRO2 Extent=[98:9 - 98:19]
+// CHECK-source: usrs.m:100:9: macro definition=MACRO3 Extent=[100:9 - 100:25]
+// CHECK-source: usrs.m:101:9: macro definition=MACRO3 Extent=[101:9 - 101:25]
 // CHECK-source: usrs.m:3:19: FunctionDecl=my_helper:3:19 (Definition) Extent=[3:1 - 3:60]
 // CHECK-source: usrs.m:3:33: ParmDecl=x:3:33 (Definition) Extent=[3:29 - 3:34]
 // CHECK-source: usrs.m:3:40: ParmDecl=y:3:40 (Definition) Extent=[3:36 - 3:41]
@@ -258,9 +281,9 @@
 // CHECK-source: usrs.m:69:23: UnexposedExpr= Extent=[69:23 - 69:24]
 // CHECK-source: usrs.m:69:23: IntegerLiteral= Extent=[69:23 - 69:24]
 // CHECK-source: usrs.m:72:6: FunctionDecl=aux_1:72:6 Extent=[72:1 - 72:26]
-// CHECK-source: usrs.m:72:15: ParmDecl=:72:15 (Definition) Extent=[72:12 - 72:16]
-// CHECK-source: usrs.m:72:20: ParmDecl=:72:20 (Definition) Extent=[72:17 - 72:21]
-// CHECK-source: usrs.m:72:25: ParmDecl=:72:25 (Definition) Extent=[72:22 - 72:26]
+// CHECK-source: usrs.m:72:15: ParmDecl=:72:15 (Definition) Extent=[72:12 - 72:15]
+// CHECK-source: usrs.m:72:20: ParmDecl=:72:20 (Definition) Extent=[72:17 - 72:20]
+// CHECK-source: usrs.m:72:25: ParmDecl=:72:25 (Definition) Extent=[72:22 - 72:25]
 // CHECK-source: usrs.m:73:5: FunctionDecl=test_multi_declaration:73:5 (Definition) Extent=[73:1 - 77:2]
 // CHECK-source: usrs.m:73:34: CompoundStmt= Extent=[73:34 - 77:2]
 // CHECK-source: usrs.m:74:3: DeclStmt= Extent=[74:3 - 74:33]
diff --git a/test/Sema/carbon.c b/test/Integration/carbon.c
similarity index 100%
rename from test/Sema/carbon.c
rename to test/Integration/carbon.c
diff --git a/test/PCH/cocoa.m b/test/Integration/cocoa-pch.m
similarity index 100%
rename from test/PCH/cocoa.m
rename to test/Integration/cocoa-pch.m
diff --git a/test/Integration/cocoa.m b/test/Integration/cocoa.m
new file mode 100644
index 0000000..d814b3e
--- /dev/null
+++ b/test/Integration/cocoa.m
@@ -0,0 +1,5 @@
+// RUN: %clang -arch x86_64 %s -fsyntax-only -Xclang -print-stats
+#ifdef __APPLE__
+#include <Cocoa/Cocoa.h>
+#endif
+
diff --git a/test/Layout/ms-x86-alias-avoidance-padding.cpp b/test/Layout/ms-x86-alias-avoidance-padding.cpp
new file mode 100644
index 0000000..e51bab3
--- /dev/null
+++ b/test/Layout/ms-x86-alias-avoidance-padding.cpp
@@ -0,0 +1,599 @@
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>/dev/null \
+// RUN:            | FileCheck %s
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>/dev/null \
+// RUN:            | FileCheck %s -check-prefix CHECK-X64
+
+extern "C" int printf(const char *fmt, ...);
+__declspec(align(4096)) char buffer[4096];
+
+struct AT {};
+
+struct V : AT {
+	char c;
+	V() {
+		printf("V   - this: %d\n", (int)((char*)this - buffer));
+	}
+};
+
+struct AT0 {
+	union { struct { int a; AT t; } y; int b; } x;
+	char c;
+	AT0() {
+		printf("AT0 - this: %d\n", (int)((char*)this - buffer));
+	}
+};
+
+struct AT1 : V {
+	int a;
+	AT1() {
+		printf("AT1 - this: %d\n", (int)((char*)this - buffer));
+	}
+};
+
+struct AT2 {
+	AT0 t;
+	char AT2FieldName0;
+	AT2() {
+		printf("AT2 - this: %d\n", (int)((char*)this - buffer));
+		printf("AT2 - Fiel: %d\n", (int)((char*)&AT2FieldName0 - buffer));
+	}
+};
+
+struct AT3 : AT2, AT1 {
+	AT3() {
+		printf("AT3 - this: %d\n", (int)((char*)this - buffer));
+	}
+};
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct AT3
+// CHECK-NEXT:    0 |   struct AT2 (base)
+// CHECK-NEXT:    0 |     struct AT0 t
+// CHECK-NEXT:    0 |       union AT0::(anonymous at {{.*}} x
+// CHECK-NEXT:    0 |         struct AT0::(anonymous at {{.*}} y
+// CHECK-NEXT:    0 |           int a
+// CHECK-NEXT:    4 |           struct AT t (empty)
+// CHECK:         0 |         int b
+// CHECK:         8 |       char c
+// CHECK:        12 |     char AT2FieldName0
+// CHECK-NEXT:   20 |   struct AT1 (base)
+// CHECK-NEXT:   20 |     struct V (base)
+// CHECK-NEXT:   20 |       struct AT (base) (empty)
+// CHECK-NEXT:   20 |       char c
+// CHECK-NEXT:   24 |     int a
+// CHECK-NEXT:      | [sizeof=28, align=4
+// CHECK-NEXT:      |  nvsize=28, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct AT3
+// CHECK-X64-NEXT:    0 |   struct AT2 (base)
+// CHECK-X64-NEXT:    0 |     struct AT0 t
+// CHECK-X64-NEXT:    0 |       union AT0::(anonymous at {{.*}} x
+// CHECK-X64-NEXT:    0 |         struct AT0::(anonymous at {{.*}} y
+// CHECK-X64-NEXT:    0 |           int a
+// CHECK-X64-NEXT:    4 |           struct AT t (empty)
+// CHECK-X64:         0 |         int b
+// CHECK-X64:         8 |       char c
+// CHECK-X64:        12 |     char AT2FieldName0
+// CHECK-X64-NEXT:   20 |   struct AT1 (base)
+// CHECK-X64-NEXT:   20 |     struct V (base)
+// CHECK-X64-NEXT:   20 |       struct AT (base) (empty)
+// CHECK-X64-NEXT:   20 |       char c
+// CHECK-X64-NEXT:   24 |     int a
+// CHECK-X64-NEXT:      | [sizeof=28, align=4
+// CHECK-X64-NEXT:      |  nvsize=28, nvalign=4]
+
+struct BT0 {
+	BT0() {
+		printf("BT0 - this: %d\n", (int)((char*)this - buffer));
+	}
+};
+
+struct BT2 : BT0 {
+	char BT2FieldName0;
+	BT2() {
+		printf("BT2 - this: %d\n", (int)((char*)this - buffer));
+		printf("BT2 - Fiel: %d\n", (int)((char*)&BT2FieldName0 - buffer));
+	}
+};
+
+struct BT3 : BT0, BT2 {
+	BT3() {
+		printf("BT3 - this: %d\n", (int)((char*)this - buffer));
+	}
+};
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct BT3
+// CHECK-NEXT:    0 |   struct BT0 (base) (empty)
+// CHECK-NEXT:    1 |   struct BT2 (base)
+// CHECK-NEXT:    1 |     struct BT0 (base) (empty)
+// CHECK-NEXT:    1 |     char BT2FieldName0
+// CHECK-NEXT:      | [sizeof=2, align=1
+// CHECK-NEXT:      |  nvsize=2, nvalign=1]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct BT3
+// CHECK-X64-NEXT:    0 |   struct BT0 (base) (empty)
+// CHECK-X64-NEXT:    1 |   struct BT2 (base)
+// CHECK-X64-NEXT:    1 |     struct BT0 (base) (empty)
+// CHECK-X64-NEXT:    1 |     char BT2FieldName0
+// CHECK-X64-NEXT:      | [sizeof=2, align=1
+// CHECK-X64-NEXT:      |  nvsize=2, nvalign=1]
+
+struct T0 : AT {
+	T0() {
+		printf("T0 (this) : %d\n", (int)((char*)this - buffer));
+	}
+};
+
+struct T1 : T0 {
+	char a;
+	T1() {
+		printf("T1 (this) : %d\n", (int)((char*)this - buffer));
+		printf("T1 (fiel) : %d\n", (int)((char*)&a - buffer));
+	}
+};
+
+struct T2 : AT {
+	char a;
+	T2() {
+		printf("T2 (this) : %d\n", (int)((char*)this - buffer));
+		printf("T2 (fiel) : %d\n", (int)((char*)&a - buffer));
+	}
+};
+
+struct __declspec(align(1)) T3 : virtual T1, virtual T2 {
+	T3() {
+		printf("T3 (this) : %d\n", (int)((char*)this - buffer));
+	}
+};
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct T3
+// CHECK-NEXT:    0 |   (T3 vbtable pointer)
+// CHECK-NEXT:    4 |   struct T1 (virtual base)
+// CHECK-NEXT:    4 |     struct T0 (base) (empty)
+// CHECK-NEXT:    4 |       struct AT (base) (empty)
+// CHECK-NEXT:    4 |     char a
+// CHECK-NEXT:   12 |   struct T2 (virtual base)
+// CHECK-NEXT:   12 |     struct AT (base) (empty)
+// CHECK-NEXT:   12 |     char a
+// CHECK-NEXT:      | [sizeof=16, align=4
+// CHECK-NEXT:      |  nvsize=4, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct T3
+// CHECK-X64-NEXT:    0 |   (T3 vbtable pointer)
+// CHECK-X64-NEXT:    8 |   struct T1 (virtual base)
+// CHECK-X64-NEXT:    8 |     struct T0 (base) (empty)
+// CHECK-X64-NEXT:    8 |       struct AT (base) (empty)
+// CHECK-X64-NEXT:    8 |     char a
+// CHECK-X64-NEXT:   16 |   struct T2 (virtual base)
+// CHECK-X64-NEXT:   16 |     struct AT (base) (empty)
+// CHECK-X64-NEXT:   16 |     char a
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
+
+struct B {};
+struct C { int a; };
+struct D : B, virtual C { B b; };
+struct E : D, B {};
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct E
+// CHECK-NEXT:    0 |   struct D (base)
+// CHECK-NEXT:    4 |     struct B (base) (empty)
+// CHECK-NEXT:    0 |     (D vbtable pointer)
+// CHECK-NEXT:    4 |     struct B b (empty)
+// CHECK:         8 |   struct B (base) (empty)
+// CHECK-NEXT:    8 |   struct C (virtual base)
+// CHECK-NEXT:    8 |     int a
+// CHECK-NEXT:      | [sizeof=12, align=4
+// CHECK-NEXT:      |  nvsize=8, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:   0 | struct E
+// CHECK-X64-NEXT:   0 |   struct D (base)
+// CHECK-X64-NEXT:   8 |     struct B (base) (empty)
+// CHECK-X64-NEXT:   0 |     (D vbtable pointer)
+// CHECK-X64-NEXT:   8 |     struct B b (empty)
+// CHECK-X64:       16 |   struct B (base) (empty)
+// CHECK-X64-NEXT:  16 |   struct C (virtual base)
+// CHECK-X64-NEXT:  16 |     int a
+// CHECK-X64-NEXT:     | [sizeof=24, align=8
+// CHECK-X64-NEXT:     |  nvsize=16, nvalign=8]
+
+struct F : virtual D, virtual B {};
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct F
+// CHECK-NEXT:    0 |   (F vbtable pointer)
+// CHECK-NEXT:    4 |   struct C (virtual base)
+// CHECK-NEXT:    4 |     int a
+// CHECK-NEXT:    8 |   struct D (virtual base)
+// CHECK-NEXT:   12 |     struct B (base) (empty)
+// CHECK-NEXT:    8 |     (D vbtable pointer)
+// CHECK-NEXT:   12 |     struct B b (empty)
+// CHECK:        16 |   struct B (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=16, align=4
+// CHECK-NEXT:      |  nvsize=4, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct F
+// CHECK-X64-NEXT:    0 |   (F vbtable pointer)
+// CHECK-X64-NEXT:    8 |   struct C (virtual base)
+// CHECK-X64-NEXT:    8 |     int a
+// CHECK-X64-NEXT:   16 |   struct D (virtual base)
+// CHECK-X64-NEXT:   24 |     struct B (base) (empty)
+// CHECK-X64-NEXT:   16 |     (D vbtable pointer)
+// CHECK-X64-NEXT:   24 |     struct B b (empty)
+// CHECK-X64:        32 |   struct B (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=32, align=8
+// CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
+
+struct JC0 {
+	JC0() { printf("JC0 : %d\n", (int)((char*)this - buffer)); }
+};
+struct JC1 : JC0 {
+	virtual void f() {}
+	JC1() { printf("JC1 : %d\n", (int)((char*)this - buffer)); }
+};
+struct JC2 : JC1 {
+	JC2() { printf("JC2 : %d\n", (int)((char*)this - buffer)); }
+};
+struct JC4 : JC1, JC2 {
+	JC4() { printf("JC4 : %d\n", (int)((char*)this - buffer)); }
+};
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct JC4
+// CHECK-NEXT:    0 |   struct JC1 (primary base)
+// CHECK-NEXT:    0 |     (JC1 vftable pointer)
+// CHECK-NEXT:    4 |     struct JC0 (base) (empty)
+// CHECK-NEXT:    8 |   struct JC2 (base)
+// CHECK-NEXT:    8 |     struct JC1 (primary base)
+// CHECK-NEXT:    8 |       (JC1 vftable pointer)
+// CHECK-NEXT:   12 |       struct JC0 (base) (empty)
+// CHECK-NEXT:      | [sizeof=12, align=4
+// CHECK-NEXT:      |  nvsize=12, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct JC4
+// CHECK-X64-NEXT:    0 |   struct JC1 (primary base)
+// CHECK-X64-NEXT:    0 |     (JC1 vftable pointer)
+// CHECK-X64-NEXT:    8 |     struct JC0 (base) (empty)
+// CHECK-X64-NEXT:   16 |   struct JC2 (base)
+// CHECK-X64-NEXT:   16 |     struct JC1 (primary base)
+// CHECK-X64-NEXT:   16 |       (JC1 vftable pointer)
+// CHECK-X64-NEXT:   24 |       struct JC0 (base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
+
+struct RA {};
+struct RB { char c; };
+struct RV {};
+struct RW { char c; };
+struct RY { RY() { printf("%Id\n", (char*)this - buffer); } };
+struct RX0 : RB, RA {};
+struct RX1 : RA, RB {};
+struct RX2 : RA { char a; };
+struct RX3 : RA { RB a; };
+struct RX4 { RA a; char b; };
+struct RX5 { RA a; RB b; };
+struct RX6 : virtual RV { RB a; };
+struct RX7 : virtual RW { RA a; };
+struct RX8 : RA, virtual RW {};
+
+struct RZ0 : RX0, RY {};
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct RZ0
+// CHECK-NEXT:    0 |   struct RX0 (base)
+// CHECK-NEXT:    0 |     struct RB (base)
+// CHECK-NEXT:    0 |       char c
+// CHECK-NEXT:    1 |     struct RA (base) (empty)
+// CHECK-NEXT:    2 |   struct RY (base) (empty)
+// CHECK-NEXT:      | [sizeof=2, align=1
+// CHECK-NEXT:      |  nvsize=2, nvalign=1]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct RZ0
+// CHECK-X64-NEXT:    0 |   struct RX0 (base)
+// CHECK-X64-NEXT:    0 |     struct RB (base)
+// CHECK-X64-NEXT:    0 |       char c
+// CHECK-X64-NEXT:    1 |     struct RA (base) (empty)
+// CHECK-X64-NEXT:    2 |   struct RY (base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=2, align=1
+// CHECK-X64-NEXT:      |  nvsize=2, nvalign=1]
+
+struct RZ1 : RX1, RY {};
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct RZ1
+// CHECK-NEXT:    0 |   struct RX1 (base)
+// CHECK-NEXT:    0 |     struct RA (base) (empty)
+// CHECK-NEXT:    0 |     struct RB (base)
+// CHECK-NEXT:    0 |       char c
+// CHECK-NEXT:    1 |   struct RY (base) (empty)
+// CHECK-NEXT:      | [sizeof=1, align=1
+// CHECK-NEXT:      |  nvsize=1, nvalign=1]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct RZ1
+// CHECK-X64-NEXT:    0 |   struct RX1 (base)
+// CHECK-X64-NEXT:    0 |     struct RA (base) (empty)
+// CHECK-X64-NEXT:    0 |     struct RB (base)
+// CHECK-X64-NEXT:    0 |       char c
+// CHECK-X64-NEXT:    1 |   struct RY (base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=1, align=1
+// CHECK-X64-NEXT:      |  nvsize=1, nvalign=1]
+
+struct RZ2 : RX2, RY {};
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct RZ2
+// CHECK-NEXT:    0 |   struct RX2 (base)
+// CHECK-NEXT:    0 |     struct RA (base) (empty)
+// CHECK-NEXT:    0 |     char a
+// CHECK-NEXT:    2 |   struct RY (base) (empty)
+// CHECK-NEXT:      | [sizeof=2, align=1
+// CHECK-NEXT:      |  nvsize=2, nvalign=1]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct RZ2
+// CHECK-X64-NEXT:    0 |   struct RX2 (base)
+// CHECK-X64-NEXT:    0 |     struct RA (base) (empty)
+// CHECK-X64-NEXT:    0 |     char a
+// CHECK-X64-NEXT:    2 |   struct RY (base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=2, align=1
+// CHECK-X64-NEXT:      |  nvsize=2, nvalign=1]
+
+struct RZ3 : RX3, RY {};
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct RZ3
+// CHECK-NEXT:    0 |   struct RX3 (base)
+// CHECK-NEXT:    0 |     struct RA (base) (empty)
+// CHECK-NEXT:    0 |     struct RB a
+// CHECK-NEXT:    0 |       char c
+// CHECK-NEXT:      |     [sizeof=1, align=1
+// CHECK-NEXT:      |      nvsize=1, nvalign=1]
+// CHECK-NEXT:    1 |   struct RY (base) (empty)
+// CHECK-NEXT:      | [sizeof=1, align=1
+// CHECK-NEXT:      |  nvsize=1, nvalign=1]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct RZ3
+// CHECK-X64-NEXT:    0 |   struct RX3 (base)
+// CHECK-X64-NEXT:    0 |     struct RA (base) (empty)
+// CHECK-X64-NEXT:    0 |     struct RB a
+// CHECK-X64-NEXT:    0 |       char c
+// CHECK-X64-NEXT:      |     [sizeof=1, align=1
+// CHECK-X64-NEXT:      |      nvsize=1, nvalign=1]
+// CHECK-X64-NEXT:    1 |   struct RY (base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=1, align=1
+// CHECK-X64-NEXT:      |  nvsize=1, nvalign=1]
+
+struct RZ4 : RX4, RY {};
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct RZ4
+// CHECK-NEXT:    0 |   struct RX4 (base)
+// CHECK-NEXT:    0 |     struct RA a (empty)
+// CHECK-NEXT:      |     [sizeof=1, align=1
+// CHECK-NEXT:      |      nvsize=0, nvalign=1]
+// CHECK-NEXT:    1 |     char b
+// CHECK-NEXT:    3 |   struct RY (base) (empty)
+// CHECK-NEXT:      | [sizeof=3, align=1
+// CHECK-NEXT:      |  nvsize=3, nvalign=1]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct RZ4
+// CHECK-X64-NEXT:    0 |   struct RX4 (base)
+// CHECK-X64-NEXT:    0 |     struct RA a (empty)
+// CHECK-X64-NEXT:      |     [sizeof=1, align=1
+// CHECK-X64-NEXT:      |      nvsize=0, nvalign=1]
+// CHECK-X64-NEXT:    1 |     char b
+// CHECK-X64-NEXT:    3 |   struct RY (base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=3, align=1
+// CHECK-X64-NEXT:      |  nvsize=3, nvalign=1]
+
+struct RZ5 : RX5, RY {};
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct RZ5
+// CHECK-NEXT:    0 |   struct RX5 (base)
+// CHECK-NEXT:    0 |     struct RA a (empty)
+// CHECK-NEXT:      |     [sizeof=1, align=1
+// CHECK-NEXT:      |      nvsize=0, nvalign=1]
+// CHECK-NEXT:    1 |     struct RB b
+// CHECK-NEXT:    1 |       char c
+// CHECK-NEXT:      |     [sizeof=1, align=1
+// CHECK-NEXT:      |      nvsize=1, nvalign=1]
+// CHECK-NEXT:    2 |   struct RY (base) (empty)
+// CHECK-NEXT:      | [sizeof=2, align=1
+// CHECK-NEXT:      |  nvsize=2, nvalign=1]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct RZ5
+// CHECK-X64-NEXT:    0 |   struct RX5 (base)
+// CHECK-X64-NEXT:    0 |     struct RA a (empty)
+// CHECK-X64-NEXT:      |     [sizeof=1, align=1
+// CHECK-X64-NEXT:      |      nvsize=0, nvalign=1]
+// CHECK-X64-NEXT:    1 |     struct RB b
+// CHECK-X64-NEXT:    1 |       char c
+// CHECK-X64-NEXT:      |     [sizeof=1, align=1
+// CHECK-X64-NEXT:      |      nvsize=1, nvalign=1]
+// CHECK-X64-NEXT:    2 |   struct RY (base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=2, align=1
+// CHECK-X64-NEXT:      |  nvsize=2, nvalign=1]
+
+struct RZ6 : RX6, RY {};
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct RZ6
+// CHECK-NEXT:    0 |   struct RX6 (base)
+// CHECK-NEXT:    0 |     (RX6 vbtable pointer)
+// CHECK-NEXT:    4 |     struct RB a
+// CHECK-NEXT:    4 |       char c
+// CHECK-NEXT:      |     [sizeof=1, align=1
+// CHECK-NEXT:      |      nvsize=1, nvalign=1]
+// CHECK-NEXT:    9 |   struct RY (base) (empty)
+// CHECK-NEXT:   12 |   struct RV (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=12, align=4
+// CHECK-NEXT:      |  nvsize=12, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct RZ6
+// CHECK-X64-NEXT:    0 |   struct RX6 (base)
+// CHECK-X64-NEXT:    0 |     (RX6 vbtable pointer)
+// CHECK-X64-NEXT:    8 |     struct RB a
+// CHECK-X64-NEXT:    8 |       char c
+// CHECK-X64-NEXT:      |     [sizeof=1, align=1
+// CHECK-X64-NEXT:      |      nvsize=1, nvalign=1]
+// CHECK-X64-NEXT:   17 |   struct RY (base) (empty)
+// CHECK-X64-NEXT:   24 |   struct RV (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
+
+struct RZ7 : RX7, RY {};
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct RZ7
+// CHECK-NEXT:    0 |   struct RX7 (base)
+// CHECK-NEXT:    0 |     (RX7 vbtable pointer)
+// CHECK-NEXT:    4 |     struct RA a (empty)
+// CHECK-NEXT:      |     [sizeof=1, align=1
+// CHECK-NEXT:      |      nvsize=0, nvalign=1]
+// CHECK-NEXT:    8 |   struct RY (base) (empty)
+// CHECK-NEXT:    8 |   struct RW (virtual base)
+// CHECK-NEXT:    8 |     char c
+// CHECK-NEXT:      | [sizeof=9, align=4
+// CHECK-NEXT:      |  nvsize=8, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct RZ7
+// CHECK-X64-NEXT:    0 |   struct RX7 (base)
+// CHECK-X64-NEXT:    0 |     (RX7 vbtable pointer)
+// CHECK-X64-NEXT:    8 |     struct RA a (empty)
+// CHECK-X64-NEXT:      |     [sizeof=1, align=1
+// CHECK-X64-NEXT:      |      nvsize=0, nvalign=1]
+// CHECK-X64-NEXT:   16 |   struct RY (base) (empty)
+// CHECK-X64-NEXT:   16 |   struct RW (virtual base)
+// CHECK-X64-NEXT:   16 |     char c
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
+
+struct RZ8 : RX8, RY {};
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct RZ8
+// CHECK-NEXT:    0 |   struct RX8 (base)
+// CHECK-NEXT:    4 |     struct RA (base) (empty)
+// CHECK-NEXT:    0 |     (RX8 vbtable pointer)
+// CHECK-NEXT:    4 |   struct RY (base) (empty)
+// CHECK-NEXT:    4 |   struct RW (virtual base)
+// CHECK-NEXT:    4 |     char c
+// CHECK-NEXT:      | [sizeof=5, align=4
+// CHECK-NEXT:      |  nvsize=4, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct RZ8
+// CHECK-X64-NEXT:    0 |   struct RX8 (base)
+// CHECK-X64-NEXT:    8 |     struct RA (base) (empty)
+// CHECK-X64-NEXT:    0 |     (RX8 vbtable pointer)
+// CHECK-X64-NEXT:    8 |   struct RY (base) (empty)
+// CHECK-X64-NEXT:    8 |   struct RW (virtual base)
+// CHECK-X64-NEXT:    8 |     char c
+// CHECK-X64-NEXT:      | [sizeof=16, align=8
+// CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
+
+struct JA {};
+struct JB {};
+struct JC : JA { virtual void f() {} };
+struct JD : virtual JB, virtual JC { virtual void f() {} JD() {} };
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct JD
+// CHECK-NEXT:    0 |   (JD vbtable pointer)
+// CHECK-NEXT:    4 |   struct JB (virtual base) (empty)
+// CHECK-NEXT:    4 |   (vtordisp for vbase JC)
+// CHECK-NEXT:    8 |   struct JC (virtual base)
+// CHECK-NEXT:    8 |     (JC vftable pointer)
+// CHECK-NEXT:   12 |     struct JA (base) (empty)
+// CHECK-NEXT:      | [sizeof=12, align=4
+// CHECK-NEXT:      |  nvsize=4, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct JD
+// CHECK-X64-NEXT:    0 |   (JD vbtable pointer)
+// CHECK-X64-NEXT:    8 |   struct JB (virtual base) (empty)
+// CHECK-X64-NEXT:   12 |   (vtordisp for vbase JC)
+// CHECK-X64-NEXT:   16 |   struct JC (virtual base)
+// CHECK-X64-NEXT:   16 |     (JC vftable pointer)
+// CHECK-X64-NEXT:   24 |     struct JA (base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
+
+int a[
+sizeof(AT3) +
+sizeof(BT3) +
+sizeof(T3) +
+sizeof(E) +
+sizeof(F) +
+sizeof(JC4) +
+sizeof(RZ0) +
+sizeof(RZ1) +
+sizeof(RZ2) +
+sizeof(RZ3) +
+sizeof(RZ4) +
+sizeof(RZ5) +
+sizeof(RZ6) +
+sizeof(RZ7) +
+sizeof(RZ8) +
+sizeof(JD) +
+0];
diff --git a/test/Layout/ms-x86-aligned-tail-padding.cpp b/test/Layout/ms-x86-aligned-tail-padding.cpp
index b9020f3..f919766 100644
--- a/test/Layout/ms-x86-aligned-tail-padding.cpp
+++ b/test/Layout/ms-x86-aligned-tail-padding.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>/dev/null \
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>/dev/null \
 // RUN:            | FileCheck %s
-// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>/dev/null \
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>/dev/null \
 // RUN:            | FileCheck %s -check-prefix CHECK-X64
 
 extern "C" int printf(const char *fmt, ...);
@@ -75,33 +75,41 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct A
-// CHECK:    0 |   struct B1 (base)
-// CHECK:    0 |     int a
-// CHECK:    4 |   struct B0 (base)
-// CHECK:    4 |     int a
-// CHECK:   16 |   struct B2 (base)
-// CHECK:   16 |     int a
-// CHECK:   32 |   (A vbtable pointer)
-// CHECK:   48 |   int a
-// CHECK:   64 |   struct V (virtual base)
-// CHECK:   64 |     char a
-// CHECK:      | [sizeof=80, align=16
-// CHECK:      |  nvsize=64, nvalign=16]
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct A
+// CHECK-NEXT:    0 |   struct B1 (base)
+// CHECK-NEXT:    0 |     int a
+// CHECK-NEXT:    4 |   struct B0 (base)
+// CHECK-NEXT:    4 |     int a
+// CHECK-NEXT:   16 |   struct B2 (base)
+// CHECK-NEXT:   16 |     int a
+// CHECK-NEXT:   32 |   (A vbtable pointer)
+// CHECK-NEXT:   48 |   int a
+// CHECK-NEXT:   64 |   struct V (virtual base)
+// CHECK-NEXT:   64 |     char a
+// CHECK-NEXT:      | [sizeof=80, align=16
+// CHECK-NEXT:      |  nvsize=64, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct A
-// CHECK-X64:    0 |   struct B1 (base)
-// CHECK-X64:    0 |     int a
-// CHECK-X64:    4 |   struct B0 (base)
-// CHECK-X64:    4 |     int a
-// CHECK-X64:   16 |   struct B2 (base)
-// CHECK-X64:   16 |     int a
-// CHECK-X64:   32 |   (A vbtable pointer)
-// CHECK-X64:   40 |   int a
-// CHECK-X64:   48 |   struct V (virtual base)
-// CHECK-X64:   48 |     char a
-// CHECK-X64:      | [sizeof=64, align=16
-// CHECK-X64:      |  nvsize=48, nvalign=16]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct A
+// CHECK-X64-NEXT:    0 |   struct B1 (base)
+// CHECK-X64-NEXT:    0 |     int a
+// CHECK-X64-NEXT:    4 |   struct B0 (base)
+// CHECK-X64-NEXT:    4 |     int a
+// CHECK-X64-NEXT:   16 |   struct B2 (base)
+// CHECK-X64-NEXT:   16 |     int a
+// CHECK-X64-NEXT:   32 |   (A vbtable pointer)
+// CHECK-X64-NEXT:   48 |   int a
+// CHECK-X64-NEXT:   64 |   struct V (virtual base)
+// CHECK-X64-NEXT:   64 |     char a
+// CHECK-X64-NEXT:      | [sizeof=80, align=16
+// CHECK-X64-NEXT:      |  nvsize=64, nvalign=16]
 
 struct B : B2, B0, B1, virtual V {
 	int a;
@@ -109,33 +117,33 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct B
-// CHECK:    0 |   struct B2 (base)
-// CHECK:    0 |     int a
-// CHECK:   16 |   struct B0 (base)
-// CHECK:   16 |     int a
-// CHECK:   32 |   struct B1 (base)
-// CHECK:   32 |     int a
-// CHECK:   36 |   (B vbtable pointer)
-// CHECK:   52 |   int a
-// CHECK:   64 |   struct V (virtual base)
-// CHECK:   64 |     char a
-// CHECK:      | [sizeof=80, align=16
-// CHECK:      |  nvsize=64, nvalign=16]
+// CHECK-NEXT:    0 | struct B
+// CHECK-NEXT:    0 |   struct B2 (base)
+// CHECK-NEXT:    0 |     int a
+// CHECK-NEXT:   16 |   struct B0 (base)
+// CHECK-NEXT:   16 |     int a
+// CHECK-NEXT:   32 |   struct B1 (base)
+// CHECK-NEXT:   32 |     int a
+// CHECK-NEXT:   36 |   (B vbtable pointer)
+// CHECK-NEXT:   52 |   int a
+// CHECK-NEXT:   64 |   struct V (virtual base)
+// CHECK-NEXT:   64 |     char a
+// CHECK-NEXT:      | [sizeof=80, align=16
+// CHECK-NEXT:      |  nvsize=64, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct B
-// CHECK-X64:    0 |   struct B2 (base)
-// CHECK-X64:    0 |     int a
-// CHECK-X64:   16 |   struct B0 (base)
-// CHECK-X64:   16 |     int a
-// CHECK-X64:   32 |   struct B1 (base)
-// CHECK-X64:   32 |     int a
-// CHECK-X64:   40 |   (B vbtable pointer)
-// CHECK-X64:   48 |   int a
-// CHECK-X64:   64 |   struct V (virtual base)
-// CHECK-X64:   64 |     char a
-// CHECK-X64:      | [sizeof=80, align=16
-// CHECK-X64:      |  nvsize=64, nvalign=16]
+// CHECK-X64-NEXT:    0 | struct B
+// CHECK-X64-NEXT:    0 |   struct B2 (base)
+// CHECK-X64-NEXT:    0 |     int a
+// CHECK-X64-NEXT:   16 |   struct B0 (base)
+// CHECK-X64-NEXT:   16 |     int a
+// CHECK-X64-NEXT:   32 |   struct B1 (base)
+// CHECK-X64-NEXT:   32 |     int a
+// CHECK-X64-NEXT:   40 |   (B vbtable pointer)
+// CHECK-X64-NEXT:   52 |   int a
+// CHECK-X64-NEXT:   64 |   struct V (virtual base)
+// CHECK-X64-NEXT:   64 |     char a
+// CHECK-X64-NEXT:      | [sizeof=80, align=16
+// CHECK-X64-NEXT:      |  nvsize=64, nvalign=16]
 
 struct C : B1, B0, virtual V {
 	int a;
@@ -144,31 +152,31 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct C
-// CHECK:    0 |   struct B1 (base)
-// CHECK:    0 |     int a
-// CHECK:    4 |   struct B0 (base)
-// CHECK:    4 |     int a
-// CHECK:    8 |   (C vbtable pointer)
-// CHECK:   24 |   int a
-// CHECK:   32 |   long long a1
-// CHECK:   48 |   struct V (virtual base)
-// CHECK:   48 |     char a
-// CHECK:      | [sizeof=64, align=16
-// CHECK:      |  nvsize=48, nvalign=16]
+// CHECK-NEXT:    0 | struct C
+// CHECK-NEXT:    0 |   struct B1 (base)
+// CHECK-NEXT:    0 |     int a
+// CHECK-NEXT:    4 |   struct B0 (base)
+// CHECK-NEXT:    4 |     int a
+// CHECK-NEXT:    8 |   (C vbtable pointer)
+// CHECK-NEXT:   24 |   int a
+// CHECK-NEXT:   32 |   long long a1
+// CHECK-NEXT:   48 |   struct V (virtual base)
+// CHECK-NEXT:   48 |     char a
+// CHECK-NEXT:      | [sizeof=64, align=16
+// CHECK-NEXT:      |  nvsize=48, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct C
-// CHECK-X64:    0 |   struct B1 (base)
-// CHECK-X64:    0 |     int a
-// CHECK-X64:    4 |   struct B0 (base)
-// CHECK-X64:    4 |     int a
-// CHECK-X64:    8 |   (C vbtable pointer)
-// CHECK-X64:   16 |   int a
-// CHECK-X64:   24 |   long long a1
-// CHECK-X64:   32 |   struct V (virtual base)
-// CHECK-X64:   32 |     char a
-// CHECK-X64:      | [sizeof=48, align=16
-// CHECK-X64:      |  nvsize=32, nvalign=16]
+// CHECK-X64-NEXT:    0 | struct C
+// CHECK-X64-NEXT:    0 |   struct B1 (base)
+// CHECK-X64-NEXT:    0 |     int a
+// CHECK-X64-NEXT:    4 |   struct B0 (base)
+// CHECK-X64-NEXT:    4 |     int a
+// CHECK-X64-NEXT:    8 |   (C vbtable pointer)
+// CHECK-X64-NEXT:   24 |   int a
+// CHECK-X64-NEXT:   32 |   long long a1
+// CHECK-X64-NEXT:   48 |   struct V (virtual base)
+// CHECK-X64-NEXT:   48 |     char a
+// CHECK-X64-NEXT:      | [sizeof=64, align=16
+// CHECK-X64-NEXT:      |  nvsize=48, nvalign=16]
 
 struct D : B2, B0, virtual V {
 	int a;
@@ -176,29 +184,29 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct D
-// CHECK:    0 |   struct B2 (base)
-// CHECK:    0 |     int a
-// CHECK:   16 |   struct B0 (base)
-// CHECK:   16 |     int a
-// CHECK:   20 |   (D vbtable pointer)
-// CHECK:   36 |   int a
-// CHECK:   48 |   struct V (virtual base)
-// CHECK:   48 |     char a
-// CHECK:      | [sizeof=64, align=16
-// CHECK:      |  nvsize=48, nvalign=16]
+// CHECK-NEXT:    0 | struct D
+// CHECK-NEXT:    0 |   struct B2 (base)
+// CHECK-NEXT:    0 |     int a
+// CHECK-NEXT:   16 |   struct B0 (base)
+// CHECK-NEXT:   16 |     int a
+// CHECK-NEXT:   20 |   (D vbtable pointer)
+// CHECK-NEXT:   36 |   int a
+// CHECK-NEXT:   48 |   struct V (virtual base)
+// CHECK-NEXT:   48 |     char a
+// CHECK-NEXT:      | [sizeof=64, align=16
+// CHECK-NEXT:      |  nvsize=48, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct D
-// CHECK-X64:    0 |   struct B2 (base)
-// CHECK-X64:    0 |     int a
-// CHECK-X64:   16 |   struct B0 (base)
-// CHECK-X64:   16 |     int a
-// CHECK-X64:   24 |   (D vbtable pointer)
-// CHECK-X64:   32 |   int a
-// CHECK-X64:   48 |   struct V (virtual base)
-// CHECK-X64:   48 |     char a
-// CHECK-X64:      | [sizeof=64, align=16
-// CHECK-X64:      |  nvsize=48, nvalign=16]
+// CHECK-X64-NEXT:    0 | struct D
+// CHECK-X64-NEXT:    0 |   struct B2 (base)
+// CHECK-X64-NEXT:    0 |     int a
+// CHECK-X64-NEXT:   16 |   struct B0 (base)
+// CHECK-X64-NEXT:   16 |     int a
+// CHECK-X64-NEXT:   24 |   (D vbtable pointer)
+// CHECK-X64-NEXT:   36 |   int a
+// CHECK-X64-NEXT:   48 |   struct V (virtual base)
+// CHECK-X64-NEXT:   48 |     char a
+// CHECK-X64-NEXT:      | [sizeof=64, align=16
+// CHECK-X64-NEXT:      |  nvsize=48, nvalign=16]
 
 struct E : B3, B0, virtual V {
 	int a;
@@ -206,31 +214,33 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct E
-// CHECK:    0 |   struct B3 (base)
-// CHECK:    0 |     long long a1
-// CHECK:    8 |     int a
-// CHECK:   16 |   struct B0 (base)
-// CHECK:   16 |     int a
-// CHECK:   20 |   (E vbtable pointer)
-// CHECK:   36 |   int a
-// CHECK:   48 |   struct V (virtual base)
-// CHECK:   48 |     char a
-// CHECK:      | [sizeof=64, align=16
-// CHECK:      |  nvsize=48, nvalign=16]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct E
+// CHECK-NEXT:    0 |   struct B3 (base)
+// CHECK-NEXT:    0 |     long long a1
+// CHECK-NEXT:    8 |     int a
+// CHECK-NEXT:   16 |   struct B0 (base)
+// CHECK-NEXT:   16 |     int a
+// CHECK-NEXT:   20 |   (E vbtable pointer)
+// CHECK-NEXT:   36 |   int a
+// CHECK-NEXT:   48 |   struct V (virtual base)
+// CHECK-NEXT:   48 |     char a
+// CHECK-NEXT:      | [sizeof=64, align=16
+// CHECK-NEXT:      |  nvsize=48, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct E
-// CHECK-X64:    0 |   struct B3 (base)
-// CHECK-X64:    0 |     long long a1
-// CHECK-X64:    8 |     int a
-// CHECK-X64:   16 |   struct B0 (base)
-// CHECK-X64:   16 |     int a
-// CHECK-X64:   24 |   (E vbtable pointer)
-// CHECK-X64:   32 |   int a
-// CHECK-X64:   48 |   struct V (virtual base)
-// CHECK-X64:   48 |     char a
-// CHECK-X64:      | [sizeof=64, align=16
-// CHECK-X64:      |  nvsize=48, nvalign=16]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct E
+// CHECK-X64-NEXT:    0 |   struct B3 (base)
+// CHECK-X64-NEXT:    0 |     long long a1
+// CHECK-X64-NEXT:    8 |     int a
+// CHECK-X64-NEXT:   16 |   struct B0 (base)
+// CHECK-X64-NEXT:   16 |     int a
+// CHECK-X64-NEXT:   24 |   (E vbtable pointer)
+// CHECK-X64-NEXT:   36 |   int a
+// CHECK-X64-NEXT:   48 |   struct V (virtual base)
+// CHECK-X64-NEXT:   48 |     char a
+// CHECK-X64-NEXT:      | [sizeof=64, align=16
+// CHECK-X64-NEXT:      |  nvsize=48, nvalign=16]
 
 struct F : B0, virtual V1 {
 	__declspec(align(16)) int a;
@@ -239,29 +249,33 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct F
-// CHECK:    0 |   struct B0 (base)
-// CHECK:    0 |     int a
-// CHECK:    4 |   (F vbtable pointer)
-// CHECK:   32 |   int a
-// CHECK:   92 |   (vtordisp for vbase V1)
-// CHECK:   96 |   struct V1 (virtual base)
-// CHECK:   96 |     (V1 vftable pointer)
-// CHECK:  128 |     struct A16 (base) (empty)
-// CHECK:      | [sizeof=128, align=32
-// CHECK:      |  nvsize=48, nvalign=16]
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct F
+// CHECK-NEXT:    0 |   struct B0 (base)
+// CHECK-NEXT:    0 |     int a
+// CHECK-NEXT:    4 |   (F vbtable pointer)
+// CHECK-NEXT:   32 |   int a
+// CHECK-NEXT:   92 |   (vtordisp for vbase V1)
+// CHECK-NEXT:   96 |   struct V1 (virtual base)
+// CHECK-NEXT:   96 |     (V1 vftable pointer)
+// CHECK-NEXT:  128 |     struct A16 (base) (empty)
+// CHECK-NEXT:      | [sizeof=128, align=32
+// CHECK-NEXT:      |  nvsize=48, nvalign=32]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct F
-// CHECK-X64:    0 |   struct B0 (base)
-// CHECK-X64:    0 |     int a
-// CHECK-X64:    8 |   (F vbtable pointer)
-// CHECK-X64:   16 |   int a
-// CHECK-X64:   60 |   (vtordisp for vbase V1)
-// CHECK-X64:   64 |   struct V1 (virtual base)
-// CHECK-X64:   64 |     (V1 vftable pointer)
-// CHECK-X64:   96 |     struct A16 (base) (empty)
-// CHECK-X64:      | [sizeof=96, align=32
-// CHECK-X64:      |  nvsize=32, nvalign=16]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct F
+// CHECK-X64-NEXT:    0 |   struct B0 (base)
+// CHECK-X64-NEXT:    0 |     int a
+// CHECK-X64-NEXT:    8 |   (F vbtable pointer)
+// CHECK-X64-NEXT:   32 |   int a
+// CHECK-X64-NEXT:   92 |   (vtordisp for vbase V1)
+// CHECK-X64-NEXT:   96 |   struct V1 (virtual base)
+// CHECK-X64-NEXT:   96 |     (V1 vftable pointer)
+// CHECK-X64-NEXT:  128 |     struct A16 (base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=128, align=32
+// CHECK-X64-NEXT:      |  nvsize=48, nvalign=32]
 
 struct G : virtual V2, virtual V3 {
 	int a;
@@ -269,27 +283,31 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct G
-// CHECK:    0 |   (G vbtable pointer)
-// CHECK:    4 |   int a
-// CHECK:    8 |   struct V2 (virtual base)
-// CHECK:    8 |     long long a
-// CHECK:   16 |     int a1
-// CHECK:   24 |   struct V3 (virtual base)
-// CHECK:   24 |     int a
-// CHECK:      | [sizeof=28, align=8
-// CHECK:      |  nvsize=8, nvalign=4]
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct G
+// CHECK-NEXT:    0 |   (G vbtable pointer)
+// CHECK-NEXT:    4 |   int a
+// CHECK-NEXT:    8 |   struct V2 (virtual base)
+// CHECK-NEXT:    8 |     long long a
+// CHECK-NEXT:   16 |     int a1
+// CHECK-NEXT:   24 |   struct V3 (virtual base)
+// CHECK-NEXT:   24 |     int a
+// CHECK-NEXT:      | [sizeof=28, align=8
+// CHECK-NEXT:      |  nvsize=8, nvalign=8]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct G
-// CHECK-X64:    0 |   (G vbtable pointer)
-// CHECK-X64:    8 |   int a
-// CHECK-X64:   16 |   struct V2 (virtual base)
-// CHECK-X64:   16 |     long long a
-// CHECK-X64:   24 |     int a1
-// CHECK-X64:   32 |   struct V3 (virtual base)
-// CHECK-X64:   32 |     int a
-// CHECK-X64:      | [sizeof=40, align=8
-// CHECK-X64:      |  nvsize=16, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct G
+// CHECK-X64-NEXT:    0 |   (G vbtable pointer)
+// CHECK-X64-NEXT:    8 |   int a
+// CHECK-X64-NEXT:   16 |   struct V2 (virtual base)
+// CHECK-X64-NEXT:   16 |     long long a
+// CHECK-X64-NEXT:   24 |     int a1
+// CHECK-X64-NEXT:   32 |   struct V3 (virtual base)
+// CHECK-X64-NEXT:   32 |     int a
+// CHECK-X64-NEXT:      | [sizeof=40, align=8
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
 
 struct H {
 	__declspec(align(16)) int a;
@@ -298,17 +316,17 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct H
-// CHECK:    0 |   int a
-// CHECK:    4 |   int b
-// CHECK:      | [sizeof=16, align=16
-// CHECK:      |  nvsize=16, nvalign=16]
+// CHECK-NEXT:    0 | struct H
+// CHECK-NEXT:    0 |   int a
+// CHECK-NEXT:    4 |   int b
+// CHECK-NEXT:      | [sizeof=16, align=16
+// CHECK-NEXT:      |  nvsize=16, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct H
-// CHECK-X64:    0 |   int a
-// CHECK-X64:    4 |   int b
-// CHECK-X64:      | [sizeof=16, align=16
-// CHECK-X64:      |  nvsize=16, nvalign=16]
+// CHECK-X64-NEXT:    0 | struct H
+// CHECK-X64-NEXT:    0 |   int a
+// CHECK-X64-NEXT:    4 |   int b
+// CHECK-X64-NEXT:      | [sizeof=16, align=16
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=16]
 
 struct I {
 	B2 a;
@@ -317,19 +335,19 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct I
-// CHECK:    0 |   struct B2 a
-// CHECK:    0 |     int a
-// CHECK:   16 |   int b
-// CHECK:      | [sizeof=32, align=16
-// CHECK:      |  nvsize=32, nvalign=16]
+// CHECK-NEXT:    0 | struct I
+// CHECK-NEXT:    0 |   struct B2 a
+// CHECK-NEXT:    0 |     int a
+// CHECK:        16 |   int b
+// CHECK-NEXT:      | [sizeof=32, align=16
+// CHECK-NEXT:      |  nvsize=32, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct I
-// CHECK-X64:    0 |   struct B2 a
-// CHECK-X64:    0 |     int a
-// CHECK-X64:   16 |   int b
-// CHECK-X64:      | [sizeof=32, align=16
-// CHECK-X64:      |  nvsize=32, nvalign=16]
+// CHECK-X64-NEXT:    0 | struct I
+// CHECK-X64-NEXT:    0 |   struct B2 a
+// CHECK-X64-NEXT:    0 |     int a
+// CHECK-X64:        16 |   int b
+// CHECK-X64-NEXT:      | [sizeof=32, align=16
+// CHECK-X64-NEXT:      |  nvsize=32, nvalign=16]
 
 struct AX : B0X, virtual B2X, virtual B6X, virtual B3X {
 	int a;
@@ -339,41 +357,49 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct AX
-// CHECK:    0 |   (AX vftable pointer)
-// CHECK:   16 |   struct B0X (base)
-// CHECK:   16 |     int a
-// CHECK:   20 |     int a1
-// CHECK:   24 |   (AX vbtable pointer)
-// CHECK:   40 |   int a
-// CHECK:   48 |   struct B2X (virtual base)
-// CHECK:   48 |     int a
-// CHECK:   52 |   struct B6X (virtual base)
-// CHECK:   52 |     int a
-// CHECK:   76 |   (vtordisp for vbase B3X)
-// CHECK:   80 |   struct B3X (virtual base)
-// CHECK:   80 |     (B3X vftable pointer)
-// CHECK:   84 |     int a
-// CHECK:      | [sizeof=96, align=16
-// CHECK:      |  nvsize=48, nvalign=16]
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct AX
+// CHECK-NEXT:    0 |   (AX vftable pointer)
+// CHECK-NEXT:   16 |   struct B0X (base)
+// CHECK-NEXT:   16 |     int a
+// CHECK-NEXT:   20 |     int a1
+// CHECK-NEXT:   24 |   (AX vbtable pointer)
+// CHECK-NEXT:   40 |   int a
+// CHECK-NEXT:   48 |   struct B2X (virtual base)
+// CHECK-NEXT:   48 |     int a
+// CHECK-NEXT:   52 |   struct B6X (virtual base)
+// CHECK-NEXT:   52 |     int a
+// CHECK-NEXT:   76 |   (vtordisp for vbase B3X)
+// CHECK-NEXT:   80 |   struct B3X (virtual base)
+// CHECK-NEXT:   80 |     (B3X vftable pointer)
+// CHECK-NEXT:   84 |     int a
+// CHECK-NEXT:      | [sizeof=96, align=16
+// CHECK-NEXT:      |  nvsize=48, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct AX
-// CHECK-X64:    0 |   (AX vftable pointer)
-// CHECK-X64:   16 |   struct B0X (base)
-// CHECK-X64:   16 |     int a
-// CHECK-X64:   20 |     int a1
-// CHECK-X64:   24 |   (AX vbtable pointer)
-// CHECK-X64:   32 |   int a
-// CHECK-X64:   48 |   struct B2X (virtual base)
-// CHECK-X64:   48 |     int a
-// CHECK-X64:   52 |   struct B6X (virtual base)
-// CHECK-X64:   52 |     int a
-// CHECK-X64:   76 |   (vtordisp for vbase B3X)
-// CHECK-X64:   80 |   struct B3X (virtual base)
-// CHECK-X64:   80 |     (B3X vftable pointer)
-// CHECK-X64:   88 |     int a
-// CHECK-X64:      | [sizeof=96, align=16
-// CHECK-X64:      |  nvsize=48, nvalign=16]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct AX
+// CHECK-X64-NEXT:    0 |   (AX vftable pointer)
+// CHECK-X64-NEXT:   16 |   struct B0X (base)
+// CHECK-X64-NEXT:   16 |     int a
+// CHECK-X64-NEXT:   20 |     int a1
+// CHECK-X64-NEXT:   24 |   (AX vbtable pointer)
+// CHECK-X64-NEXT:   40 |   int a
+// CHECK-X64-NEXT:   48 |   struct B2X (virtual base)
+// CHECK-X64-NEXT:   48 |     int a
+// CHECK-X64-NEXT:   52 |   struct B6X (virtual base)
+// CHECK-X64-NEXT:   52 |     int a
+// CHECK-X64-NEXT:   76 |   (vtordisp for vbase B3X)
+// CHECK-X64-NEXT:   80 |   struct B3X (virtual base)
+// CHECK-X64-NEXT:   80 |     (B3X vftable pointer)
+// CHECK-X64-NEXT:   88 |     int a
+// CHECK-X64-NEXT:      | [sizeof=96, align=16
+// CHECK-X64-NEXT:      |  nvsize=48, nvalign=16]
 
 struct BX : B4X, virtual B2X, virtual B6X, virtual B3X {
 	int a;
@@ -383,43 +409,47 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct BX
-// CHECK:    0 |   (BX vftable pointer)
-// CHECK:   16 |   struct B4X (base)
-// CHECK:   16 |     struct A16X (base) (empty)
-// CHECK:   16 |     int a
-// CHECK:   20 |     int a1
-// CHECK:   32 |   (BX vbtable pointer)
-// CHECK:   48 |   int a
-// CHECK:   64 |   struct B2X (virtual base)
-// CHECK:   64 |     int a
-// CHECK:   68 |   struct B6X (virtual base)
-// CHECK:   68 |     int a
-// CHECK:   92 |   (vtordisp for vbase B3X)
-// CHECK:   96 |   struct B3X (virtual base)
-// CHECK:   96 |     (B3X vftable pointer)
-// CHECK:  100 |     int a
-// CHECK:      | [sizeof=112, align=16
-// CHECK:      |  nvsize=64, nvalign=16]
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct BX
+// CHECK-NEXT:    0 |   (BX vftable pointer)
+// CHECK-NEXT:   16 |   struct B4X (base)
+// CHECK-NEXT:   16 |     struct A16X (base) (empty)
+// CHECK-NEXT:   16 |     int a
+// CHECK-NEXT:   20 |     int a1
+// CHECK-NEXT:   32 |   (BX vbtable pointer)
+// CHECK-NEXT:   48 |   int a
+// CHECK-NEXT:   64 |   struct B2X (virtual base)
+// CHECK-NEXT:   64 |     int a
+// CHECK-NEXT:   68 |   struct B6X (virtual base)
+// CHECK-NEXT:   68 |     int a
+// CHECK-NEXT:   92 |   (vtordisp for vbase B3X)
+// CHECK-NEXT:   96 |   struct B3X (virtual base)
+// CHECK-NEXT:   96 |     (B3X vftable pointer)
+// CHECK-NEXT:  100 |     int a
+// CHECK-NEXT:      | [sizeof=112, align=16
+// CHECK-NEXT:      |  nvsize=64, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct BX
-// CHECK-X64:    0 |   (BX vftable pointer)
-// CHECK-X64:   16 |   struct B4X (base)
-// CHECK-X64:   16 |     struct A16X (base) (empty)
-// CHECK-X64:   16 |     int a
-// CHECK-X64:   20 |     int a1
-// CHECK-X64:   32 |   (BX vbtable pointer)
-// CHECK-X64:   40 |   int a
-// CHECK-X64:   48 |   struct B2X (virtual base)
-// CHECK-X64:   48 |     int a
-// CHECK-X64:   52 |   struct B6X (virtual base)
-// CHECK-X64:   52 |     int a
-// CHECK-X64:   76 |   (vtordisp for vbase B3X)
-// CHECK-X64:   80 |   struct B3X (virtual base)
-// CHECK-X64:   80 |     (B3X vftable pointer)
-// CHECK-X64:   88 |     int a
-// CHECK-X64:      | [sizeof=96, align=16
-// CHECK-X64:      |  nvsize=48, nvalign=16]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct BX
+// CHECK-X64-NEXT:    0 |   (BX vftable pointer)
+// CHECK-X64-NEXT:   16 |   struct B4X (base)
+// CHECK-X64-NEXT:   16 |     struct A16X (base) (empty)
+// CHECK-X64-NEXT:   16 |     int a
+// CHECK-X64-NEXT:   20 |     int a1
+// CHECK-X64-NEXT:   32 |   (BX vbtable pointer)
+// CHECK-X64-NEXT:   48 |   int a
+// CHECK-X64-NEXT:   64 |   struct B2X (virtual base)
+// CHECK-X64-NEXT:   64 |     int a
+// CHECK-X64-NEXT:   68 |   struct B6X (virtual base)
+// CHECK-X64-NEXT:   68 |     int a
+// CHECK-X64-NEXT:   92 |   (vtordisp for vbase B3X)
+// CHECK-X64-NEXT:   96 |   struct B3X (virtual base)
+// CHECK-X64-NEXT:   96 |     (B3X vftable pointer)
+// CHECK-X64-NEXT:  104 |     int a
+// CHECK-X64-NEXT:      | [sizeof=112, align=16
+// CHECK-X64-NEXT:      |  nvsize=64, nvalign=16]
 
 struct CX : B5X, virtual B2X, virtual B6X, virtual B3X {
 	int a;
@@ -429,43 +459,45 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct CX
-// CHECK:    0 |   (CX vftable pointer)
-// CHECK:   16 |   struct B5X (base)
-// CHECK:   16 |     (B5X vbtable pointer)
-// CHECK:   20 |     int a
-// CHECK:   24 |     int a1
-// CHECK:   28 |   int a
-// CHECK:   32 |   struct A16X (virtual base) (empty)
-// CHECK:   32 |   struct B2X (virtual base)
-// CHECK:   32 |     int a
-// CHECK:   36 |   struct B6X (virtual base)
-// CHECK:   36 |     int a
-// CHECK:   60 |   (vtordisp for vbase B3X)
-// CHECK:   64 |   struct B3X (virtual base)
-// CHECK:   64 |     (B3X vftable pointer)
-// CHECK:   68 |     int a
-// CHECK:      | [sizeof=80, align=16
-// CHECK:      |  nvsize=32, nvalign=16]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct CX
+// CHECK-NEXT:    0 |   (CX vftable pointer)
+// CHECK-NEXT:   16 |   struct B5X (base)
+// CHECK-NEXT:   16 |     (B5X vbtable pointer)
+// CHECK-NEXT:   20 |     int a
+// CHECK-NEXT:   24 |     int a1
+// CHECK-NEXT:   28 |   int a
+// CHECK-NEXT:   32 |   struct A16X (virtual base) (empty)
+// CHECK-NEXT:   32 |   struct B2X (virtual base)
+// CHECK-NEXT:   32 |     int a
+// CHECK-NEXT:   36 |   struct B6X (virtual base)
+// CHECK-NEXT:   36 |     int a
+// CHECK-NEXT:   60 |   (vtordisp for vbase B3X)
+// CHECK-NEXT:   64 |   struct B3X (virtual base)
+// CHECK-NEXT:   64 |     (B3X vftable pointer)
+// CHECK-NEXT:   68 |     int a
+// CHECK-NEXT:      | [sizeof=80, align=16
+// CHECK-NEXT:      |  nvsize=32, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct CX
-// CHECK-X64:    0 |   (CX vftable pointer)
-// CHECK-X64:   16 |   struct B5X (base)
-// CHECK-X64:   16 |     (B5X vbtable pointer)
-// CHECK-X64:   24 |     int a
-// CHECK-X64:   28 |     int a1
-// CHECK-X64:   32 |   int a
-// CHECK-X64:   48 |   struct A16X (virtual base) (empty)
-// CHECK-X64:   48 |   struct B2X (virtual base)
-// CHECK-X64:   48 |     int a
-// CHECK-X64:   52 |   struct B6X (virtual base)
-// CHECK-X64:   52 |     int a
-// CHECK-X64:   76 |   (vtordisp for vbase B3X)
-// CHECK-X64:   80 |   struct B3X (virtual base)
-// CHECK-X64:   80 |     (B3X vftable pointer)
-// CHECK-X64:   88 |     int a
-// CHECK-X64:      | [sizeof=96, align=16
-// CHECK-X64:      |  nvsize=48, nvalign=16]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct CX
+// CHECK-X64-NEXT:    0 |   (CX vftable pointer)
+// CHECK-X64-NEXT:   16 |   struct B5X (base)
+// CHECK-X64-NEXT:   16 |     (B5X vbtable pointer)
+// CHECK-X64-NEXT:   24 |     int a
+// CHECK-X64-NEXT:   28 |     int a1
+// CHECK-X64-NEXT:   32 |   int a
+// CHECK-X64-NEXT:   48 |   struct A16X (virtual base) (empty)
+// CHECK-X64-NEXT:   48 |   struct B2X (virtual base)
+// CHECK-X64-NEXT:   48 |     int a
+// CHECK-X64-NEXT:   52 |   struct B6X (virtual base)
+// CHECK-X64-NEXT:   52 |     int a
+// CHECK-X64-NEXT:   76 |   (vtordisp for vbase B3X)
+// CHECK-X64-NEXT:   80 |   struct B3X (virtual base)
+// CHECK-X64-NEXT:   80 |     (B3X vftable pointer)
+// CHECK-X64-NEXT:   88 |     int a
+// CHECK-X64-NEXT:      | [sizeof=96, align=16
+// CHECK-X64-NEXT:      |  nvsize=48, nvalign=16]
 
 struct __declspec(align(16)) DX {
 	int a;
@@ -474,17 +506,17 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct DX
-// CHECK:    0 |   (DX vftable pointer)
-// CHECK:    4 |   int a
-// CHECK:      | [sizeof=16, align=16
-// CHECK:      |  nvsize=8, nvalign=4]
+// CHECK-NEXT:    0 | struct DX
+// CHECK-NEXT:    0 |   (DX vftable pointer)
+// CHECK-NEXT:    4 |   int a
+// CHECK-NEXT:      | [sizeof=16, align=16
+// CHECK-NEXT:      |  nvsize=8, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct DX
-// CHECK-X64:    0 |   (DX vftable pointer)
-// CHECK-X64:    8 |   int a
-// CHECK-X64:      | [sizeof=16, align=16
-// CHECK-X64:      |  nvsize=16, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct DX
+// CHECK-X64-NEXT:    0 |   (DX vftable pointer)
+// CHECK-X64-NEXT:    8 |   int a
+// CHECK-X64-NEXT:      | [sizeof=16, align=16
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=16]
 
 int a[
 sizeof(A)+
diff --git a/test/Layout/ms-x86-basic-layout.cpp b/test/Layout/ms-x86-basic-layout.cpp
index 86b3553..b6ffeee 100644
--- a/test/Layout/ms-x86-basic-layout.cpp
+++ b/test/Layout/ms-x86-basic-layout.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>/dev/null \
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>/dev/null \
 // RUN:            | FileCheck %s
-// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>/dev/null \
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>/dev/null \
 // RUN:            | FileCheck %s -check-prefix CHECK-X64
 
 extern "C" int printf(const char *fmt, ...);
@@ -38,25 +38,29 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct TestF0
-// CHECK:    0 |   struct A4 (base)
-// CHECK:    0 |     int a
-// CHECK:    4 |   (TestF0 vbtable pointer)
-// CHECK:    8 |   int a
-// CHECK:   12 |   struct B4 (virtual base)
-// CHECK:   12 |     int a
-// CHECK:      | [sizeof=16, align=4
-// CHECK:      |  nvsize=12, nvalign=4]
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct TestF0
+// CHECK-NEXT:    0 |   struct A4 (base)
+// CHECK-NEXT:    0 |     int a
+// CHECK-NEXT:    4 |   (TestF0 vbtable pointer)
+// CHECK-NEXT:    8 |   int a
+// CHECK-NEXT:   12 |   struct B4 (virtual base)
+// CHECK-NEXT:   12 |     int a
+// CHECK-NEXT:      | [sizeof=16, align=4
+// CHECK-NEXT:      |  nvsize=12, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct TestF0
-// CHECK-X64:    0 |   struct A4 (base)
-// CHECK-X64:    0 |     int a
-// CHECK-X64:    8 |   (TestF0 vbtable pointer)
-// CHECK-X64:   16 |   int a
-// CHECK-X64:   24 |   struct B4 (virtual base)
-// CHECK-X64:   24 |     int a
-// CHECK-X64:      | [sizeof=32, align=8
-// CHECK-X64:      |  nvsize=24, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct TestF0
+// CHECK-X64-NEXT:    0 |   struct A4 (base)
+// CHECK-X64-NEXT:    0 |     int a
+// CHECK-X64-NEXT:    8 |   (TestF0 vbtable pointer)
+// CHECK-X64-NEXT:   16 |   int a
+// CHECK-X64-NEXT:   24 |   struct B4 (virtual base)
+// CHECK-X64-NEXT:   24 |     int a
+// CHECK-X64-NEXT:      | [sizeof=32, align=8
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
 
 struct TestF1 : A4, virtual A16 {
 	int a;
@@ -64,25 +68,27 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct TestF1
-// CHECK:    0 |   struct A4 (base)
-// CHECK:    0 |     int a
-// CHECK:    4 |   (TestF1 vbtable pointer)
-// CHECK:    8 |   int a
-// CHECK:   16 |   struct A16 (virtual base)
-// CHECK:   16 |     int a
-// CHECK:      | [sizeof=32, align=16
-// CHECK:      |  nvsize=12, nvalign=4]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct TestF1
+// CHECK-NEXT:    0 |   struct A4 (base)
+// CHECK-NEXT:    0 |     int a
+// CHECK-NEXT:    4 |   (TestF1 vbtable pointer)
+// CHECK-NEXT:    8 |   int a
+// CHECK-NEXT:   16 |   struct A16 (virtual base)
+// CHECK-NEXT:   16 |     int a
+// CHECK-NEXT:      | [sizeof=32, align=16
+// CHECK-NEXT:      |  nvsize=12, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct TestF1
-// CHECK-X64:    0 |   struct A4 (base)
-// CHECK-X64:    0 |     int a
-// CHECK-X64:    8 |   (TestF1 vbtable pointer)
-// CHECK-X64:   16 |   int a
-// CHECK-X64:   32 |   struct A16 (virtual base)
-// CHECK-X64:   32 |     int a
-// CHECK-X64:      | [sizeof=48, align=16
-// CHECK-X64:      |  nvsize=24, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct TestF1
+// CHECK-X64-NEXT:    0 |   struct A4 (base)
+// CHECK-X64-NEXT:    0 |     int a
+// CHECK-X64-NEXT:    8 |   (TestF1 vbtable pointer)
+// CHECK-X64-NEXT:   16 |   int a
+// CHECK-X64-NEXT:   32 |   struct A16 (virtual base)
+// CHECK-X64-NEXT:   32 |     int a
+// CHECK-X64-NEXT:      | [sizeof=48, align=16
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=16]
 
 struct TestF2 : A4, virtual C4 {
 	int a;
@@ -90,27 +96,29 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct TestF2
-// CHECK:    0 |   struct A4 (base)
-// CHECK:    0 |     int a
-// CHECK:    4 |   (TestF2 vbtable pointer)
-// CHECK:    8 |   int a
-// CHECK:   12 |   struct C4 (virtual base)
-// CHECK:   12 |     (C4 vftable pointer)
-// CHECK:   16 |     int a
-// CHECK:      | [sizeof=20, align=4
-// CHECK:      |  nvsize=12, nvalign=4]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct TestF2
+// CHECK-NEXT:    0 |   struct A4 (base)
+// CHECK-NEXT:    0 |     int a
+// CHECK-NEXT:    4 |   (TestF2 vbtable pointer)
+// CHECK-NEXT:    8 |   int a
+// CHECK-NEXT:   12 |   struct C4 (virtual base)
+// CHECK-NEXT:   12 |     (C4 vftable pointer)
+// CHECK-NEXT:   16 |     int a
+// CHECK-NEXT:      | [sizeof=20, align=4
+// CHECK-NEXT:      |  nvsize=12, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct TestF2
-// CHECK-X64:    0 |   struct A4 (base)
-// CHECK-X64:    0 |     int a
-// CHECK-X64:    8 |   (TestF2 vbtable pointer)
-// CHECK-X64:   16 |   int a
-// CHECK-X64:   24 |   struct C4 (virtual base)
-// CHECK-X64:   24 |     (C4 vftable pointer)
-// CHECK-X64:   32 |     int a
-// CHECK-X64:      | [sizeof=40, align=8
-// CHECK-X64:      |  nvsize=24, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct TestF2
+// CHECK-X64-NEXT:    0 |   struct A4 (base)
+// CHECK-X64-NEXT:    0 |     int a
+// CHECK-X64-NEXT:    8 |   (TestF2 vbtable pointer)
+// CHECK-X64-NEXT:   16 |   int a
+// CHECK-X64-NEXT:   24 |   struct C4 (virtual base)
+// CHECK-X64-NEXT:   24 |     (C4 vftable pointer)
+// CHECK-X64-NEXT:   32 |     int a
+// CHECK-X64-NEXT:      | [sizeof=40, align=8
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
 
 struct TestF3 : A4, virtual C16 {
 	int a;
@@ -118,27 +126,29 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct TestF3
-// CHECK:    0 |   struct A4 (base)
-// CHECK:    0 |     int a
-// CHECK:    4 |   (TestF3 vbtable pointer)
-// CHECK:    8 |   int a
-// CHECK:   16 |   struct C16 (virtual base)
-// CHECK:   16 |     (C16 vftable pointer)
-// CHECK:   32 |     int a
-// CHECK:      | [sizeof=48, align=16
-// CHECK:      |  nvsize=12, nvalign=4]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct TestF3
+// CHECK-NEXT:    0 |   struct A4 (base)
+// CHECK-NEXT:    0 |     int a
+// CHECK-NEXT:    4 |   (TestF3 vbtable pointer)
+// CHECK-NEXT:    8 |   int a
+// CHECK-NEXT:   16 |   struct C16 (virtual base)
+// CHECK-NEXT:   16 |     (C16 vftable pointer)
+// CHECK-NEXT:   32 |     int a
+// CHECK-NEXT:      | [sizeof=48, align=16
+// CHECK-NEXT:      |  nvsize=12, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct TestF3
-// CHECK-X64:    0 |   struct A4 (base)
-// CHECK-X64:    0 |     int a
-// CHECK-X64:    8 |   (TestF3 vbtable pointer)
-// CHECK-X64:   16 |   int a
-// CHECK-X64:   32 |   struct C16 (virtual base)
-// CHECK-X64:   32 |     (C16 vftable pointer)
-// CHECK-X64:   48 |     int a
-// CHECK-X64:      | [sizeof=64, align=16
-// CHECK-X64:      |  nvsize=24, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct TestF3
+// CHECK-X64-NEXT:    0 |   struct A4 (base)
+// CHECK-X64-NEXT:    0 |     int a
+// CHECK-X64-NEXT:    8 |   (TestF3 vbtable pointer)
+// CHECK-X64-NEXT:   16 |   int a
+// CHECK-X64-NEXT:   32 |   struct C16 (virtual base)
+// CHECK-X64-NEXT:   32 |     (C16 vftable pointer)
+// CHECK-X64-NEXT:   48 |     int a
+// CHECK-X64-NEXT:      | [sizeof=64, align=16
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=16]
 
 struct TestF4 : TestF3, A4 {
 	int a;
@@ -146,35 +156,35 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct TestF4
-// CHECK:    0 |   struct TestF3 (base)
-// CHECK:    0 |     struct A4 (base)
-// CHECK:    0 |       int a
-// CHECK:    4 |     (TestF3 vbtable pointer)
-// CHECK:    8 |     int a
-// CHECK:   12 |   struct A4 (base)
-// CHECK:   12 |     int a
-// CHECK:   16 |   int a
-// CHECK:   32 |   struct C16 (virtual base)
-// CHECK:   32 |     (C16 vftable pointer)
-// CHECK:   48 |     int a
-// CHECK:      | [sizeof=64, align=16
-// CHECK:      |  nvsize=32, nvalign=16]
+// CHECK-NEXT:    0 | struct TestF4
+// CHECK-NEXT:    0 |   struct TestF3 (base)
+// CHECK-NEXT:    0 |     struct A4 (base)
+// CHECK-NEXT:    0 |       int a
+// CHECK-NEXT:    4 |     (TestF3 vbtable pointer)
+// CHECK-NEXT:    8 |     int a
+// CHECK-NEXT:   12 |   struct A4 (base)
+// CHECK-NEXT:   12 |     int a
+// CHECK-NEXT:   16 |   int a
+// CHECK-NEXT:   32 |   struct C16 (virtual base)
+// CHECK-NEXT:   32 |     (C16 vftable pointer)
+// CHECK-NEXT:   48 |     int a
+// CHECK-NEXT:      | [sizeof=64, align=16
+// CHECK-NEXT:      |  nvsize=32, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct TestF4
-// CHECK-X64:    0 |   struct TestF3 (base)
-// CHECK-X64:    0 |     struct A4 (base)
-// CHECK-X64:    0 |       int a
-// CHECK-X64:    8 |     (TestF3 vbtable pointer)
-// CHECK-X64:   16 |     int a
-// CHECK-X64:   24 |   struct A4 (base)
-// CHECK-X64:   24 |     int a
-// CHECK-X64:   28 |   int a
-// CHECK-X64:   32 |   struct C16 (virtual base)
-// CHECK-X64:   32 |     (C16 vftable pointer)
-// CHECK-X64:   48 |     int a
-// CHECK-X64:      | [sizeof=64, align=16
-// CHECK-X64:      |  nvsize=32, nvalign=16]
+// CHECK-X64-NEXT:    0 | struct TestF4
+// CHECK-X64-NEXT:    0 |   struct TestF3 (base)
+// CHECK-X64-NEXT:    0 |     struct A4 (base)
+// CHECK-X64-NEXT:    0 |       int a
+// CHECK-X64-NEXT:    8 |     (TestF3 vbtable pointer)
+// CHECK-X64-NEXT:   16 |     int a
+// CHECK-X64-NEXT:   24 |   struct A4 (base)
+// CHECK-X64-NEXT:   24 |     int a
+// CHECK-X64-NEXT:   28 |   int a
+// CHECK-X64-NEXT:   32 |   struct C16 (virtual base)
+// CHECK-X64-NEXT:   32 |     (C16 vftable pointer)
+// CHECK-X64-NEXT:   48 |     int a
+// CHECK-X64-NEXT:      | [sizeof=64, align=16
+// CHECK-X64-NEXT:      |  nvsize=32, nvalign=16]
 
 struct TestF5 : TestF3, A4 {
 	int a;
@@ -183,37 +193,37 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct TestF5
-// CHECK:    0 |   (TestF5 vftable pointer)
-// CHECK:   16 |   struct TestF3 (base)
-// CHECK:   16 |     struct A4 (base)
-// CHECK:   16 |       int a
-// CHECK:   20 |     (TestF3 vbtable pointer)
-// CHECK:   24 |     int a
-// CHECK:   28 |   struct A4 (base)
-// CHECK:   28 |     int a
-// CHECK:   32 |   int a
-// CHECK:   48 |   struct C16 (virtual base)
-// CHECK:   48 |     (C16 vftable pointer)
-// CHECK:   64 |     int a
-// CHECK:      | [sizeof=80, align=16
-// CHECK:      |  nvsize=48, nvalign=16]
+// CHECK-NEXT:    0 | struct TestF5
+// CHECK-NEXT:    0 |   (TestF5 vftable pointer)
+// CHECK-NEXT:   16 |   struct TestF3 (base)
+// CHECK-NEXT:   16 |     struct A4 (base)
+// CHECK-NEXT:   16 |       int a
+// CHECK-NEXT:   20 |     (TestF3 vbtable pointer)
+// CHECK-NEXT:   24 |     int a
+// CHECK-NEXT:   28 |   struct A4 (base)
+// CHECK-NEXT:   28 |     int a
+// CHECK-NEXT:   32 |   int a
+// CHECK-NEXT:   48 |   struct C16 (virtual base)
+// CHECK-NEXT:   48 |     (C16 vftable pointer)
+// CHECK-NEXT:   64 |     int a
+// CHECK-NEXT:      | [sizeof=80, align=16
+// CHECK-NEXT:      |  nvsize=48, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct TestF5
-// CHECK-X64:    0 |   (TestF5 vftable pointer)
-// CHECK-X64:   16 |   struct TestF3 (base)
-// CHECK-X64:   16 |     struct A4 (base)
-// CHECK-X64:   16 |       int a
-// CHECK-X64:   24 |     (TestF3 vbtable pointer)
-// CHECK-X64:   32 |     int a
-// CHECK-X64:   40 |   struct A4 (base)
-// CHECK-X64:   40 |     int a
-// CHECK-X64:   44 |   int a
-// CHECK-X64:   48 |   struct C16 (virtual base)
-// CHECK-X64:   48 |     (C16 vftable pointer)
-// CHECK-X64:   64 |     int a
-// CHECK-X64:      | [sizeof=80, align=16
-// CHECK-X64:      |  nvsize=48, nvalign=16]
+// CHECK-X64-NEXT:    0 | struct TestF5
+// CHECK-X64-NEXT:    0 |   (TestF5 vftable pointer)
+// CHECK-X64-NEXT:   16 |   struct TestF3 (base)
+// CHECK-X64-NEXT:   16 |     struct A4 (base)
+// CHECK-X64-NEXT:   16 |       int a
+// CHECK-X64-NEXT:   24 |     (TestF3 vbtable pointer)
+// CHECK-X64-NEXT:   32 |     int a
+// CHECK-X64-NEXT:   40 |   struct A4 (base)
+// CHECK-X64-NEXT:   40 |     int a
+// CHECK-X64-NEXT:   44 |   int a
+// CHECK-X64-NEXT:   48 |   struct C16 (virtual base)
+// CHECK-X64-NEXT:   48 |     (C16 vftable pointer)
+// CHECK-X64-NEXT:   64 |     int a
+// CHECK-X64-NEXT:      | [sizeof=80, align=16
+// CHECK-X64-NEXT:      |  nvsize=48, nvalign=16]
 
 struct TestF6 : TestF3, A4 {
 	int a;
@@ -222,37 +232,37 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct TestF6
-// CHECK:    0 |   struct TestF3 (base)
-// CHECK:    0 |     struct A4 (base)
-// CHECK:    0 |       int a
-// CHECK:    4 |     (TestF3 vbtable pointer)
-// CHECK:    8 |     int a
-// CHECK:   12 |   struct A4 (base)
-// CHECK:   12 |     int a
-// CHECK:   16 |   int a
-// CHECK:   44 |   (vtordisp for vbase C16)
-// CHECK:   48 |   struct C16 (virtual base)
-// CHECK:   48 |     (C16 vftable pointer)
-// CHECK:   64 |     int a
-// CHECK:      | [sizeof=80, align=16
-// CHECK:      |  nvsize=32, nvalign=16]
+// CHECK-NEXT:    0 | struct TestF6
+// CHECK-NEXT:    0 |   struct TestF3 (base)
+// CHECK-NEXT:    0 |     struct A4 (base)
+// CHECK-NEXT:    0 |       int a
+// CHECK-NEXT:    4 |     (TestF3 vbtable pointer)
+// CHECK-NEXT:    8 |     int a
+// CHECK-NEXT:   12 |   struct A4 (base)
+// CHECK-NEXT:   12 |     int a
+// CHECK-NEXT:   16 |   int a
+// CHECK-NEXT:   44 |   (vtordisp for vbase C16)
+// CHECK-NEXT:   48 |   struct C16 (virtual base)
+// CHECK-NEXT:   48 |     (C16 vftable pointer)
+// CHECK-NEXT:   64 |     int a
+// CHECK-NEXT:      | [sizeof=80, align=16
+// CHECK-NEXT:      |  nvsize=32, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct TestF6
-// CHECK-X64:    0 |   struct TestF3 (base)
-// CHECK-X64:    0 |     struct A4 (base)
-// CHECK-X64:    0 |       int a
-// CHECK-X64:    8 |     (TestF3 vbtable pointer)
-// CHECK-X64:   16 |     int a
-// CHECK-X64:   24 |   struct A4 (base)
-// CHECK-X64:   24 |     int a
-// CHECK-X64:   28 |   int a
-// CHECK-X64:   44 |   (vtordisp for vbase C16)
-// CHECK-X64:   48 |   struct C16 (virtual base)
-// CHECK-X64:   48 |     (C16 vftable pointer)
-// CHECK-X64:   64 |     int a
-// CHECK-X64:      | [sizeof=80, align=16
-// CHECK-X64:      |  nvsize=32, nvalign=16]
+// CHECK-X64-NEXT:    0 | struct TestF6
+// CHECK-X64-NEXT:    0 |   struct TestF3 (base)
+// CHECK-X64-NEXT:    0 |     struct A4 (base)
+// CHECK-X64-NEXT:    0 |       int a
+// CHECK-X64-NEXT:    8 |     (TestF3 vbtable pointer)
+// CHECK-X64-NEXT:   16 |     int a
+// CHECK-X64-NEXT:   24 |   struct A4 (base)
+// CHECK-X64-NEXT:   24 |     int a
+// CHECK-X64-NEXT:   28 |   int a
+// CHECK-X64-NEXT:   44 |   (vtordisp for vbase C16)
+// CHECK-X64-NEXT:   48 |   struct C16 (virtual base)
+// CHECK-X64-NEXT:   48 |     (C16 vftable pointer)
+// CHECK-X64-NEXT:   64 |     int a
+// CHECK-X64-NEXT:      | [sizeof=80, align=16
+// CHECK-X64-NEXT:      |  nvsize=32, nvalign=16]
 
 struct TestF7 : A4, virtual C16 {
 	int a;
@@ -261,29 +271,29 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct TestF7
-// CHECK:    0 |   struct A4 (base)
-// CHECK:    0 |     int a
-// CHECK:    4 |   (TestF7 vbtable pointer)
-// CHECK:    8 |   int a
-// CHECK:   28 |   (vtordisp for vbase C16)
-// CHECK:   32 |   struct C16 (virtual base)
-// CHECK:   32 |     (C16 vftable pointer)
-// CHECK:   48 |     int a
-// CHECK:      | [sizeof=64, align=16
-// CHECK:      |  nvsize=12, nvalign=4]
+// CHECK-NEXT:    0 | struct TestF7
+// CHECK-NEXT:    0 |   struct A4 (base)
+// CHECK-NEXT:    0 |     int a
+// CHECK-NEXT:    4 |   (TestF7 vbtable pointer)
+// CHECK-NEXT:    8 |   int a
+// CHECK-NEXT:   28 |   (vtordisp for vbase C16)
+// CHECK-NEXT:   32 |   struct C16 (virtual base)
+// CHECK-NEXT:   32 |     (C16 vftable pointer)
+// CHECK-NEXT:   48 |     int a
+// CHECK-NEXT:      | [sizeof=64, align=16
+// CHECK-NEXT:      |  nvsize=12, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct TestF7
-// CHECK-X64:    0 |   struct A4 (base)
-// CHECK-X64:    0 |     int a
-// CHECK-X64:    8 |   (TestF7 vbtable pointer)
-// CHECK-X64:   16 |   int a
-// CHECK-X64:   44 |   (vtordisp for vbase C16)
-// CHECK-X64:   48 |   struct C16 (virtual base)
-// CHECK-X64:   48 |     (C16 vftable pointer)
-// CHECK-X64:   64 |     int a
-// CHECK-X64:      | [sizeof=80, align=16
-// CHECK-X64:      |  nvsize=24, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct TestF7
+// CHECK-X64-NEXT:    0 |   struct A4 (base)
+// CHECK-X64-NEXT:    0 |     int a
+// CHECK-X64-NEXT:    8 |   (TestF7 vbtable pointer)
+// CHECK-X64-NEXT:   16 |   int a
+// CHECK-X64-NEXT:   44 |   (vtordisp for vbase C16)
+// CHECK-X64-NEXT:   48 |   struct C16 (virtual base)
+// CHECK-X64-NEXT:   48 |     (C16 vftable pointer)
+// CHECK-X64-NEXT:   64 |     int a
+// CHECK-X64-NEXT:      | [sizeof=80, align=16
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=16]
 
 struct TestF8 : TestF7, A4 {
 	int a;
@@ -292,37 +302,37 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct TestF8
-// CHECK:    0 |   struct TestF7 (base)
-// CHECK:    0 |     struct A4 (base)
-// CHECK:    0 |       int a
-// CHECK:    4 |     (TestF7 vbtable pointer)
-// CHECK:    8 |     int a
-// CHECK:   12 |   struct A4 (base)
-// CHECK:   12 |     int a
-// CHECK:   16 |   int a
-// CHECK:   44 |   (vtordisp for vbase C16)
-// CHECK:   48 |   struct C16 (virtual base)
-// CHECK:   48 |     (C16 vftable pointer)
-// CHECK:   64 |     int a
-// CHECK:      | [sizeof=80, align=16
-// CHECK:      |  nvsize=32, nvalign=16]
+// CHECK-NEXT:    0 | struct TestF8
+// CHECK-NEXT:    0 |   struct TestF7 (base)
+// CHECK-NEXT:    0 |     struct A4 (base)
+// CHECK-NEXT:    0 |       int a
+// CHECK-NEXT:    4 |     (TestF7 vbtable pointer)
+// CHECK-NEXT:    8 |     int a
+// CHECK-NEXT:   12 |   struct A4 (base)
+// CHECK-NEXT:   12 |     int a
+// CHECK-NEXT:   16 |   int a
+// CHECK-NEXT:   44 |   (vtordisp for vbase C16)
+// CHECK-NEXT:   48 |   struct C16 (virtual base)
+// CHECK-NEXT:   48 |     (C16 vftable pointer)
+// CHECK-NEXT:   64 |     int a
+// CHECK-NEXT:      | [sizeof=80, align=16
+// CHECK-NEXT:      |  nvsize=32, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct TestF8
-// CHECK-X64:    0 |   struct TestF7 (base)
-// CHECK-X64:    0 |     struct A4 (base)
-// CHECK-X64:    0 |       int a
-// CHECK-X64:    8 |     (TestF7 vbtable pointer)
-// CHECK-X64:   16 |     int a
-// CHECK-X64:   24 |   struct A4 (base)
-// CHECK-X64:   24 |     int a
-// CHECK-X64:   28 |   int a
-// CHECK-X64:   44 |   (vtordisp for vbase C16)
-// CHECK-X64:   48 |   struct C16 (virtual base)
-// CHECK-X64:   48 |     (C16 vftable pointer)
-// CHECK-X64:   64 |     int a
-// CHECK-X64:      | [sizeof=80, align=16
-// CHECK-X64:      |  nvsize=32, nvalign=16]
+// CHECK-X64-NEXT:    0 | struct TestF8
+// CHECK-X64-NEXT:    0 |   struct TestF7 (base)
+// CHECK-X64-NEXT:    0 |     struct A4 (base)
+// CHECK-X64-NEXT:    0 |       int a
+// CHECK-X64-NEXT:    8 |     (TestF7 vbtable pointer)
+// CHECK-X64-NEXT:   16 |     int a
+// CHECK-X64-NEXT:   24 |   struct A4 (base)
+// CHECK-X64-NEXT:   24 |     int a
+// CHECK-X64-NEXT:   28 |   int a
+// CHECK-X64-NEXT:   44 |   (vtordisp for vbase C16)
+// CHECK-X64-NEXT:   48 |   struct C16 (virtual base)
+// CHECK-X64-NEXT:   48 |     (C16 vftable pointer)
+// CHECK-X64-NEXT:   64 |     int a
+// CHECK-X64-NEXT:      | [sizeof=80, align=16
+// CHECK-X64-NEXT:      |  nvsize=32, nvalign=16]
 
 struct TestF9 : A4, virtual C16 {
 	int a;
@@ -331,29 +341,29 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct TestF9
-// CHECK:    0 |   (TestF9 vftable pointer)
-// CHECK:    4 |   struct A4 (base)
-// CHECK:    4 |     int a
-// CHECK:    8 |   (TestF9 vbtable pointer)
-// CHECK:   12 |   int a
-// CHECK:   16 |   struct C16 (virtual base)
-// CHECK:   16 |     (C16 vftable pointer)
-// CHECK:   32 |     int a
-// CHECK:      | [sizeof=48, align=16
-// CHECK:      |  nvsize=16, nvalign=4]
+// CHECK-NEXT:    0 | struct TestF9
+// CHECK-NEXT:    0 |   (TestF9 vftable pointer)
+// CHECK-NEXT:    4 |   struct A4 (base)
+// CHECK-NEXT:    4 |     int a
+// CHECK-NEXT:    8 |   (TestF9 vbtable pointer)
+// CHECK-NEXT:   12 |   int a
+// CHECK-NEXT:   16 |   struct C16 (virtual base)
+// CHECK-NEXT:   16 |     (C16 vftable pointer)
+// CHECK-NEXT:   32 |     int a
+// CHECK-NEXT:      | [sizeof=48, align=16
+// CHECK-NEXT:      |  nvsize=16, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct TestF9
-// CHECK-X64:    0 |   (TestF9 vftable pointer)
-// CHECK-X64:    8 |   struct A4 (base)
-// CHECK-X64:    8 |     int a
-// CHECK-X64:   16 |   (TestF9 vbtable pointer)
-// CHECK-X64:   24 |   int a
-// CHECK-X64:   32 |   struct C16 (virtual base)
-// CHECK-X64:   32 |     (C16 vftable pointer)
-// CHECK-X64:   48 |     int a
-// CHECK-X64:      | [sizeof=64, align=16
-// CHECK-X64:      |  nvsize=32, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct TestF9
+// CHECK-X64-NEXT:    0 |   (TestF9 vftable pointer)
+// CHECK-X64-NEXT:    8 |   struct A4 (base)
+// CHECK-X64-NEXT:    8 |     int a
+// CHECK-X64-NEXT:   16 |   (TestF9 vbtable pointer)
+// CHECK-X64-NEXT:   24 |   int a
+// CHECK-X64-NEXT:   32 |   struct C16 (virtual base)
+// CHECK-X64-NEXT:   32 |     (C16 vftable pointer)
+// CHECK-X64-NEXT:   48 |     int a
+// CHECK-X64-NEXT:      | [sizeof=64, align=16
+// CHECK-X64-NEXT:      |  nvsize=32, nvalign=16]
 
 struct TestFA : TestF9, A4 {
 	int a;
@@ -362,37 +372,37 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct TestFA
-// CHECK:    0 |   struct TestF9 (primary base)
-// CHECK:    0 |     (TestF9 vftable pointer)
-// CHECK:    4 |     struct A4 (base)
-// CHECK:    4 |       int a
-// CHECK:    8 |     (TestF9 vbtable pointer)
-// CHECK:   12 |     int a
-// CHECK:   16 |   struct A4 (base)
-// CHECK:   16 |     int a
-// CHECK:   20 |   int a
-// CHECK:   32 |   struct C16 (virtual base)
-// CHECK:   32 |     (C16 vftable pointer)
-// CHECK:   48 |     int a
-// CHECK:      | [sizeof=64, align=16
-// CHECK:      |  nvsize=32, nvalign=16]
+// CHECK-NEXT:    0 | struct TestFA
+// CHECK-NEXT:    0 |   struct TestF9 (primary base)
+// CHECK-NEXT:    0 |     (TestF9 vftable pointer)
+// CHECK-NEXT:    4 |     struct A4 (base)
+// CHECK-NEXT:    4 |       int a
+// CHECK-NEXT:    8 |     (TestF9 vbtable pointer)
+// CHECK-NEXT:   12 |     int a
+// CHECK-NEXT:   16 |   struct A4 (base)
+// CHECK-NEXT:   16 |     int a
+// CHECK-NEXT:   20 |   int a
+// CHECK-NEXT:   32 |   struct C16 (virtual base)
+// CHECK-NEXT:   32 |     (C16 vftable pointer)
+// CHECK-NEXT:   48 |     int a
+// CHECK-NEXT:      | [sizeof=64, align=16
+// CHECK-NEXT:      |  nvsize=32, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct TestFA
-// CHECK-X64:    0 |   struct TestF9 (primary base)
-// CHECK-X64:    0 |     (TestF9 vftable pointer)
-// CHECK-X64:    8 |     struct A4 (base)
-// CHECK-X64:    8 |       int a
-// CHECK-X64:   16 |     (TestF9 vbtable pointer)
-// CHECK-X64:   24 |     int a
-// CHECK-X64:   32 |   struct A4 (base)
-// CHECK-X64:   32 |     int a
-// CHECK-X64:   36 |   int a
-// CHECK-X64:   48 |   struct C16 (virtual base)
-// CHECK-X64:   48 |     (C16 vftable pointer)
-// CHECK-X64:   64 |     int a
-// CHECK-X64:      | [sizeof=80, align=16
-// CHECK-X64:      |  nvsize=48, nvalign=16]
+// CHECK-X64-NEXT:    0 | struct TestFA
+// CHECK-X64-NEXT:    0 |   struct TestF9 (primary base)
+// CHECK-X64-NEXT:    0 |     (TestF9 vftable pointer)
+// CHECK-X64-NEXT:    8 |     struct A4 (base)
+// CHECK-X64-NEXT:    8 |       int a
+// CHECK-X64-NEXT:   16 |     (TestF9 vbtable pointer)
+// CHECK-X64-NEXT:   24 |     int a
+// CHECK-X64-NEXT:   32 |   struct A4 (base)
+// CHECK-X64-NEXT:   32 |     int a
+// CHECK-X64-NEXT:   36 |   int a
+// CHECK-X64-NEXT:   48 |   struct C16 (virtual base)
+// CHECK-X64-NEXT:   48 |     (C16 vftable pointer)
+// CHECK-X64-NEXT:   64 |     int a
+// CHECK-X64-NEXT:      | [sizeof=80, align=16
+// CHECK-X64-NEXT:      |  nvsize=48, nvalign=16]
 
 struct TestFB : A16, virtual C16 {
 	int a;
@@ -401,29 +411,29 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct TestFB
-// CHECK:    0 |   (TestFB vftable pointer)
-// CHECK:   16 |   struct A16 (base)
-// CHECK:   16 |     int a
-// CHECK:   32 |   (TestFB vbtable pointer)
-// CHECK:   48 |   int a
-// CHECK:   64 |   struct C16 (virtual base)
-// CHECK:   64 |     (C16 vftable pointer)
-// CHECK:   80 |     int a
-// CHECK:      | [sizeof=96, align=16
-// CHECK:      |  nvsize=64, nvalign=16]
+// CHECK-NEXT:    0 | struct TestFB
+// CHECK-NEXT:    0 |   (TestFB vftable pointer)
+// CHECK-NEXT:   16 |   struct A16 (base)
+// CHECK-NEXT:   16 |     int a
+// CHECK-NEXT:   32 |   (TestFB vbtable pointer)
+// CHECK-NEXT:   48 |   int a
+// CHECK-NEXT:   64 |   struct C16 (virtual base)
+// CHECK-NEXT:   64 |     (C16 vftable pointer)
+// CHECK-NEXT:   80 |     int a
+// CHECK-NEXT:      | [sizeof=96, align=16
+// CHECK-NEXT:      |  nvsize=64, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct TestFB
-// CHECK-X64:    0 |   (TestFB vftable pointer)
-// CHECK-X64:   16 |   struct A16 (base)
-// CHECK-X64:   16 |     int a
-// CHECK-X64:   32 |   (TestFB vbtable pointer)
-// CHECK-X64:   40 |   int a
-// CHECK-X64:   48 |   struct C16 (virtual base)
-// CHECK-X64:   48 |     (C16 vftable pointer)
-// CHECK-X64:   64 |     int a
-// CHECK-X64:      | [sizeof=80, align=16
-// CHECK-X64:      |  nvsize=48, nvalign=16]
+// CHECK-X64-NEXT:    0 | struct TestFB
+// CHECK-X64-NEXT:    0 |   (TestFB vftable pointer)
+// CHECK-X64-NEXT:   16 |   struct A16 (base)
+// CHECK-X64-NEXT:   16 |     int a
+// CHECK-X64-NEXT:   32 |   (TestFB vbtable pointer)
+// CHECK-X64-NEXT:   48 |   int a
+// CHECK-X64-NEXT:   64 |   struct C16 (virtual base)
+// CHECK-X64-NEXT:   64 |     (C16 vftable pointer)
+// CHECK-X64-NEXT:   80 |     int a
+// CHECK-X64-NEXT:      | [sizeof=96, align=16
+// CHECK-X64-NEXT:      |  nvsize=64, nvalign=16]
 
 struct TestFC : TestFB, A4 {
 	int a;
@@ -432,37 +442,37 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct TestFC
-// CHECK:    0 |   struct TestFB (primary base)
-// CHECK:    0 |     (TestFB vftable pointer)
-// CHECK:   16 |     struct A16 (base)
-// CHECK:   16 |       int a
-// CHECK:   32 |     (TestFB vbtable pointer)
-// CHECK:   48 |     int a
-// CHECK:   64 |   struct A4 (base)
-// CHECK:   64 |     int a
-// CHECK:   68 |   int a
-// CHECK:   80 |   struct C16 (virtual base)
-// CHECK:   80 |     (C16 vftable pointer)
-// CHECK:   96 |     int a
-// CHECK:      | [sizeof=112, align=16
-// CHECK:      |  nvsize=80, nvalign=16]
+// CHECK-NEXT:    0 | struct TestFC
+// CHECK-NEXT:    0 |   struct TestFB (primary base)
+// CHECK-NEXT:    0 |     (TestFB vftable pointer)
+// CHECK-NEXT:   16 |     struct A16 (base)
+// CHECK-NEXT:   16 |       int a
+// CHECK-NEXT:   32 |     (TestFB vbtable pointer)
+// CHECK-NEXT:   48 |     int a
+// CHECK-NEXT:   64 |   struct A4 (base)
+// CHECK-NEXT:   64 |     int a
+// CHECK-NEXT:   68 |   int a
+// CHECK-NEXT:   80 |   struct C16 (virtual base)
+// CHECK-NEXT:   80 |     (C16 vftable pointer)
+// CHECK-NEXT:   96 |     int a
+// CHECK-NEXT:      | [sizeof=112, align=16
+// CHECK-NEXT:      |  nvsize=80, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct TestFC
-// CHECK-X64:    0 |   struct TestFB (primary base)
-// CHECK-X64:    0 |     (TestFB vftable pointer)
-// CHECK-X64:   16 |     struct A16 (base)
-// CHECK-X64:   16 |       int a
-// CHECK-X64:   32 |     (TestFB vbtable pointer)
-// CHECK-X64:   40 |     int a
-// CHECK-X64:   48 |   struct A4 (base)
-// CHECK-X64:   48 |     int a
-// CHECK-X64:   52 |   int a
-// CHECK-X64:   64 |   struct C16 (virtual base)
-// CHECK-X64:   64 |     (C16 vftable pointer)
-// CHECK-X64:   80 |     int a
-// CHECK-X64:      | [sizeof=96, align=16
-// CHECK-X64:      |  nvsize=64, nvalign=16]
+// CHECK-X64-NEXT:    0 | struct TestFC
+// CHECK-X64-NEXT:    0 |   struct TestFB (primary base)
+// CHECK-X64-NEXT:    0 |     (TestFB vftable pointer)
+// CHECK-X64-NEXT:   16 |     struct A16 (base)
+// CHECK-X64-NEXT:   16 |       int a
+// CHECK-X64-NEXT:   32 |     (TestFB vbtable pointer)
+// CHECK-X64-NEXT:   48 |     int a
+// CHECK-X64-NEXT:   64 |   struct A4 (base)
+// CHECK-X64-NEXT:   64 |     int a
+// CHECK-X64-NEXT:   68 |   int a
+// CHECK-X64-NEXT:   80 |   struct C16 (virtual base)
+// CHECK-X64-NEXT:   80 |     (C16 vftable pointer)
+// CHECK-X64-NEXT:   96 |     int a
+// CHECK-X64-NEXT:      | [sizeof=112, align=16
+// CHECK-X64-NEXT:      |  nvsize=80, nvalign=16]
 
 
 struct A16f {
@@ -486,43 +496,51 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct F0
-// CHECK:    0 |   (F0 vftable pointer)
-// CHECK:   16 |   struct A4 (base)
-// CHECK:   16 |     int a
-// CHECK:   32 |   struct B (base)
-// CHECK:   32 |     struct A4 (base)
-// CHECK:   32 |       int a
-// CHECK:   36 |     struct Y (base)
-// CHECK:   36 |       char y
-// CHECK:   48 |     struct X (base)
-// CHECK:   48 |       (X vbtable pointer)
-// CHECK:   52 |     int a
-// CHECK:   64 |   int a
-// CHECK:   80 |   struct A16f (virtual base)
-// CHECK:   80 |     (A16f vftable pointer)
-// CHECK:   96 |     int a
-// CHECK:      | [sizeof=112, align=16
-// CHECK:      |  nvsize=80, nvalign=16]
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct F0
+// CHECK-NEXT:    0 |   (F0 vftable pointer)
+// CHECK-NEXT:   16 |   struct A4 (base)
+// CHECK-NEXT:   16 |     int a
+// CHECK-NEXT:   32 |   struct B (base)
+// CHECK-NEXT:   32 |     struct A4 (base)
+// CHECK-NEXT:   32 |       int a
+// CHECK-NEXT:   36 |     struct Y (base)
+// CHECK-NEXT:   36 |       char y
+// CHECK-NEXT:   48 |     struct X (base)
+// CHECK-NEXT:   48 |       (X vbtable pointer)
+// CHECK-NEXT:   52 |     int a
+// CHECK-NEXT:   64 |   int a
+// CHECK-NEXT:   80 |   struct A16f (virtual base)
+// CHECK-NEXT:   80 |     (A16f vftable pointer)
+// CHECK-NEXT:   96 |     int a
+// CHECK-NEXT:      | [sizeof=112, align=16
+// CHECK-NEXT:      |  nvsize=80, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct F0
-// CHECK-X64:    0 |   (F0 vftable pointer)
-// CHECK-X64:    8 |   struct A4 (base)
-// CHECK-X64:    8 |     int a
-// CHECK-X64:   16 |   struct B (base)
-// CHECK-X64:   16 |     struct A4 (base)
-// CHECK-X64:   16 |       int a
-// CHECK-X64:   20 |     struct Y (base)
-// CHECK-X64:   20 |       char y
-// CHECK-X64:   32 |     struct X (base)
-// CHECK-X64:   32 |       (X vbtable pointer)
-// CHECK-X64:   40 |     int a
-// CHECK-X64:   48 |   int a
-// CHECK-X64:   64 |   struct A16f (virtual base)
-// CHECK-X64:   64 |     (A16f vftable pointer)
-// CHECK-X64:   80 |     int a
-// CHECK-X64:      | [sizeof=96, align=16
-// CHECK-X64:      |  nvsize=64, nvalign=16]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct F0
+// CHECK-X64-NEXT:    0 |   (F0 vftable pointer)
+// CHECK-X64-NEXT:   16 |   struct A4 (base)
+// CHECK-X64-NEXT:   16 |     int a
+// CHECK-X64-NEXT:   32 |   struct B (base)
+// CHECK-X64-NEXT:   32 |     struct A4 (base)
+// CHECK-X64-NEXT:   32 |       int a
+// CHECK-X64-NEXT:   36 |     struct Y (base)
+// CHECK-X64-NEXT:   36 |       char y
+// CHECK-X64-NEXT:   48 |     struct X (base)
+// CHECK-X64-NEXT:   48 |       (X vbtable pointer)
+// CHECK-X64-NEXT:   56 |     int a
+// CHECK-X64-NEXT:   64 |   int a
+// CHECK-X64-NEXT:   80 |   struct A16f (virtual base)
+// CHECK-X64-NEXT:   80 |     (A16f vftable pointer)
+// CHECK-X64-NEXT:   96 |     int a
+// CHECK-X64-NEXT:      | [sizeof=112, align=16
+// CHECK-X64-NEXT:      |  nvsize=80, nvalign=16]
 
 struct F1 : B, A4 {
 	int a;
@@ -531,43 +549,43 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct F1
-// CHECK:    0 |   (F1 vftable pointer)
-// CHECK:   16 |   struct B (base)
-// CHECK:   16 |     struct A4 (base)
-// CHECK:   16 |       int a
-// CHECK:   20 |     struct Y (base)
-// CHECK:   20 |       char y
-// CHECK:   32 |     struct X (base)
-// CHECK:   32 |       (X vbtable pointer)
-// CHECK:   36 |     int a
-// CHECK:   48 |   struct A4 (base)
-// CHECK:   48 |     int a
-// CHECK:   52 |   int a
-// CHECK:   64 |   struct A16f (virtual base)
-// CHECK:   64 |     (A16f vftable pointer)
-// CHECK:   80 |     int a
-// CHECK:      | [sizeof=96, align=16
-// CHECK:      |  nvsize=64, nvalign=16]
+// CHECK-NEXT:    0 | struct F1
+// CHECK-NEXT:    0 |   (F1 vftable pointer)
+// CHECK-NEXT:   16 |   struct B (base)
+// CHECK-NEXT:   16 |     struct A4 (base)
+// CHECK-NEXT:   16 |       int a
+// CHECK-NEXT:   20 |     struct Y (base)
+// CHECK-NEXT:   20 |       char y
+// CHECK-NEXT:   32 |     struct X (base)
+// CHECK-NEXT:   32 |       (X vbtable pointer)
+// CHECK-NEXT:   36 |     int a
+// CHECK-NEXT:   48 |   struct A4 (base)
+// CHECK-NEXT:   48 |     int a
+// CHECK-NEXT:   52 |   int a
+// CHECK-NEXT:   64 |   struct A16f (virtual base)
+// CHECK-NEXT:   64 |     (A16f vftable pointer)
+// CHECK-NEXT:   80 |     int a
+// CHECK-NEXT:      | [sizeof=96, align=16
+// CHECK-NEXT:      |  nvsize=64, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct F1
-// CHECK-X64:    0 |   (F1 vftable pointer)
-// CHECK-X64:   16 |   struct B (base)
-// CHECK-X64:   16 |     struct A4 (base)
-// CHECK-X64:   16 |       int a
-// CHECK-X64:   20 |     struct Y (base)
-// CHECK-X64:   20 |       char y
-// CHECK-X64:   32 |     struct X (base)
-// CHECK-X64:   32 |       (X vbtable pointer)
-// CHECK-X64:   40 |     int a
-// CHECK-X64:   48 |   struct A4 (base)
-// CHECK-X64:   48 |     int a
-// CHECK-X64:   52 |   int a
-// CHECK-X64:   64 |   struct A16f (virtual base)
-// CHECK-X64:   64 |     (A16f vftable pointer)
-// CHECK-X64:   80 |     int a
-// CHECK-X64:      | [sizeof=96, align=16
-// CHECK-X64:      |  nvsize=64, nvalign=16]
+// CHECK-X64-NEXT:    0 | struct F1
+// CHECK-X64-NEXT:    0 |   (F1 vftable pointer)
+// CHECK-X64-NEXT:   16 |   struct B (base)
+// CHECK-X64-NEXT:   16 |     struct A4 (base)
+// CHECK-X64-NEXT:   16 |       int a
+// CHECK-X64-NEXT:   20 |     struct Y (base)
+// CHECK-X64-NEXT:   20 |       char y
+// CHECK-X64-NEXT:   32 |     struct X (base)
+// CHECK-X64-NEXT:   32 |       (X vbtable pointer)
+// CHECK-X64-NEXT:   40 |     int a
+// CHECK-X64-NEXT:   48 |   struct A4 (base)
+// CHECK-X64-NEXT:   48 |     int a
+// CHECK-X64-NEXT:   52 |   int a
+// CHECK-X64-NEXT:   64 |   struct A16f (virtual base)
+// CHECK-X64-NEXT:   64 |     (A16f vftable pointer)
+// CHECK-X64-NEXT:   80 |     int a
+// CHECK-X64-NEXT:      | [sizeof=96, align=16
+// CHECK-X64-NEXT:      |  nvsize=64, nvalign=16]
 
 struct F2 : A4, virtual A16f {
 	int a;
@@ -576,29 +594,29 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct F2
-// CHECK:    0 |   (F2 vftable pointer)
-// CHECK:    4 |   struct A4 (base)
-// CHECK:    4 |     int a
-// CHECK:    8 |   (F2 vbtable pointer)
-// CHECK:   12 |   int a
-// CHECK:   16 |   struct A16f (virtual base)
-// CHECK:   16 |     (A16f vftable pointer)
-// CHECK:   32 |     int a
-// CHECK:      | [sizeof=48, align=16
-// CHECK:      |  nvsize=16, nvalign=4]
+// CHECK-NEXT:    0 | struct F2
+// CHECK-NEXT:    0 |   (F2 vftable pointer)
+// CHECK-NEXT:    4 |   struct A4 (base)
+// CHECK-NEXT:    4 |     int a
+// CHECK-NEXT:    8 |   (F2 vbtable pointer)
+// CHECK-NEXT:   12 |   int a
+// CHECK-NEXT:   16 |   struct A16f (virtual base)
+// CHECK-NEXT:   16 |     (A16f vftable pointer)
+// CHECK-NEXT:   32 |     int a
+// CHECK-NEXT:      | [sizeof=48, align=16
+// CHECK-NEXT:      |  nvsize=16, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct F2
-// CHECK-X64:    0 |   (F2 vftable pointer)
-// CHECK-X64:    8 |   struct A4 (base)
-// CHECK-X64:    8 |     int a
-// CHECK-X64:   16 |   (F2 vbtable pointer)
-// CHECK-X64:   24 |   int a
-// CHECK-X64:   32 |   struct A16f (virtual base)
-// CHECK-X64:   32 |     (A16f vftable pointer)
-// CHECK-X64:   48 |     int a
-// CHECK-X64:      | [sizeof=64, align=16
-// CHECK-X64:      |  nvsize=32, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct F2
+// CHECK-X64-NEXT:    0 |   (F2 vftable pointer)
+// CHECK-X64-NEXT:    8 |   struct A4 (base)
+// CHECK-X64-NEXT:    8 |     int a
+// CHECK-X64-NEXT:   16 |   (F2 vbtable pointer)
+// CHECK-X64-NEXT:   24 |   int a
+// CHECK-X64-NEXT:   32 |   struct A16f (virtual base)
+// CHECK-X64-NEXT:   32 |     (A16f vftable pointer)
+// CHECK-X64-NEXT:   48 |     int a
+// CHECK-X64-NEXT:      | [sizeof=64, align=16
+// CHECK-X64-NEXT:      |  nvsize=32, nvalign=16]
 
 struct F3 : A4, virtual A16f {
 	__declspec(align(16)) int a;
@@ -607,29 +625,29 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct F3
-// CHECK:    0 |   (F3 vftable pointer)
-// CHECK:   16 |   struct A4 (base)
-// CHECK:   16 |     int a
-// CHECK:   20 |   (F3 vbtable pointer)
-// CHECK:   48 |   int a
-// CHECK:   64 |   struct A16f (virtual base)
-// CHECK:   64 |     (A16f vftable pointer)
-// CHECK:   80 |     int a
-// CHECK:      | [sizeof=96, align=16
-// CHECK:      |  nvsize=64, nvalign=16]
+// CHECK-NEXT:    0 | struct F3
+// CHECK-NEXT:    0 |   (F3 vftable pointer)
+// CHECK-NEXT:   16 |   struct A4 (base)
+// CHECK-NEXT:   16 |     int a
+// CHECK-NEXT:   20 |   (F3 vbtable pointer)
+// CHECK-NEXT:   48 |   int a
+// CHECK-NEXT:   64 |   struct A16f (virtual base)
+// CHECK-NEXT:   64 |     (A16f vftable pointer)
+// CHECK-NEXT:   80 |     int a
+// CHECK-NEXT:      | [sizeof=96, align=16
+// CHECK-NEXT:      |  nvsize=64, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct F3
-// CHECK-X64:    0 |   (F3 vftable pointer)
-// CHECK-X64:    8 |   struct A4 (base)
-// CHECK-X64:    8 |     int a
-// CHECK-X64:   16 |   (F3 vbtable pointer)
-// CHECK-X64:   32 |   int a
-// CHECK-X64:   48 |   struct A16f (virtual base)
-// CHECK-X64:   48 |     (A16f vftable pointer)
-// CHECK-X64:   64 |     int a
-// CHECK-X64:      | [sizeof=80, align=16
-// CHECK-X64:      |  nvsize=48, nvalign=16]
+// CHECK-X64-NEXT:    0 | struct F3
+// CHECK-X64-NEXT:    0 |   (F3 vftable pointer)
+// CHECK-X64-NEXT:   16 |   struct A4 (base)
+// CHECK-X64-NEXT:   16 |     int a
+// CHECK-X64-NEXT:   24 |   (F3 vbtable pointer)
+// CHECK-X64-NEXT:   48 |   int a
+// CHECK-X64-NEXT:   64 |   struct A16f (virtual base)
+// CHECK-X64-NEXT:   64 |     (A16f vftable pointer)
+// CHECK-X64-NEXT:   80 |     int a
+// CHECK-X64-NEXT:      | [sizeof=96, align=16
+// CHECK-X64-NEXT:      |  nvsize=64, nvalign=16]
 
 struct F4 : A4, B {
 	__declspec(align(16)) int a;
@@ -638,43 +656,43 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct F4
-// CHECK:    0 |   (F4 vftable pointer)
-// CHECK:   16 |   struct A4 (base)
-// CHECK:   16 |     int a
-// CHECK:   32 |   struct B (base)
-// CHECK:   32 |     struct A4 (base)
-// CHECK:   32 |       int a
-// CHECK:   36 |     struct Y (base)
-// CHECK:   36 |       char y
-// CHECK:   48 |     struct X (base)
-// CHECK:   48 |       (X vbtable pointer)
-// CHECK:   52 |     int a
-// CHECK:   64 |   int a
-// CHECK:   80 |   struct A16f (virtual base)
-// CHECK:   80 |     (A16f vftable pointer)
-// CHECK:   96 |     int a
-// CHECK:      | [sizeof=112, align=16
-// CHECK:      |  nvsize=80, nvalign=16]
+// CHECK-NEXT:    0 | struct F4
+// CHECK-NEXT:    0 |   (F4 vftable pointer)
+// CHECK-NEXT:   16 |   struct A4 (base)
+// CHECK-NEXT:   16 |     int a
+// CHECK-NEXT:   32 |   struct B (base)
+// CHECK-NEXT:   32 |     struct A4 (base)
+// CHECK-NEXT:   32 |       int a
+// CHECK-NEXT:   36 |     struct Y (base)
+// CHECK-NEXT:   36 |       char y
+// CHECK-NEXT:   48 |     struct X (base)
+// CHECK-NEXT:   48 |       (X vbtable pointer)
+// CHECK-NEXT:   52 |     int a
+// CHECK-NEXT:   64 |   int a
+// CHECK-NEXT:   80 |   struct A16f (virtual base)
+// CHECK-NEXT:   80 |     (A16f vftable pointer)
+// CHECK-NEXT:   96 |     int a
+// CHECK-NEXT:      | [sizeof=112, align=16
+// CHECK-NEXT:      |  nvsize=80, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct F4
-// CHECK-X64:    0 |   (F4 vftable pointer)
-// CHECK-X64:    8 |   struct A4 (base)
-// CHECK-X64:    8 |     int a
-// CHECK-X64:   16 |   struct B (base)
-// CHECK-X64:   16 |     struct A4 (base)
-// CHECK-X64:   16 |       int a
-// CHECK-X64:   20 |     struct Y (base)
-// CHECK-X64:   20 |       char y
-// CHECK-X64:   32 |     struct X (base)
-// CHECK-X64:   32 |       (X vbtable pointer)
-// CHECK-X64:   40 |     int a
-// CHECK-X64:   48 |   int a
-// CHECK-X64:   64 |   struct A16f (virtual base)
-// CHECK-X64:   64 |     (A16f vftable pointer)
-// CHECK-X64:   80 |     int a
-// CHECK-X64:      | [sizeof=96, align=16
-// CHECK-X64:      |  nvsize=64, nvalign=16]
+// CHECK-X64-NEXT:    0 | struct F4
+// CHECK-X64-NEXT:    0 |   (F4 vftable pointer)
+// CHECK-X64-NEXT:   16 |   struct A4 (base)
+// CHECK-X64-NEXT:   16 |     int a
+// CHECK-X64-NEXT:   32 |   struct B (base)
+// CHECK-X64-NEXT:   32 |     struct A4 (base)
+// CHECK-X64-NEXT:   32 |       int a
+// CHECK-X64-NEXT:   36 |     struct Y (base)
+// CHECK-X64-NEXT:   36 |       char y
+// CHECK-X64-NEXT:   48 |     struct X (base)
+// CHECK-X64-NEXT:   48 |       (X vbtable pointer)
+// CHECK-X64-NEXT:   56 |     int a
+// CHECK-X64-NEXT:   64 |   int a
+// CHECK-X64-NEXT:   80 |   struct A16f (virtual base)
+// CHECK-X64-NEXT:   80 |     (A16f vftable pointer)
+// CHECK-X64-NEXT:   96 |     int a
+// CHECK-X64-NEXT:      | [sizeof=112, align=16
+// CHECK-X64-NEXT:      |  nvsize=80, nvalign=16]
 
 struct F5 : A16f, virtual A4 {
 	int a;
@@ -683,27 +701,27 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct F5
-// CHECK:    0 |   struct A16f (primary base)
-// CHECK:    0 |     (A16f vftable pointer)
-// CHECK:   16 |     int a
-// CHECK:   32 |   (F5 vbtable pointer)
-// CHECK:   48 |   int a
-// CHECK:   64 |   struct A4 (virtual base)
-// CHECK:   64 |     int a
-// CHECK:      | [sizeof=80, align=16
-// CHECK:      |  nvsize=64, nvalign=16]
+// CHECK-NEXT:    0 | struct F5
+// CHECK-NEXT:    0 |   struct A16f (primary base)
+// CHECK-NEXT:    0 |     (A16f vftable pointer)
+// CHECK-NEXT:   16 |     int a
+// CHECK-NEXT:   32 |   (F5 vbtable pointer)
+// CHECK-NEXT:   48 |   int a
+// CHECK-NEXT:   64 |   struct A4 (virtual base)
+// CHECK-NEXT:   64 |     int a
+// CHECK-NEXT:      | [sizeof=80, align=16
+// CHECK-NEXT:      |  nvsize=64, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct F5
-// CHECK-X64:    0 |   struct A16f (primary base)
-// CHECK-X64:    0 |     (A16f vftable pointer)
-// CHECK-X64:   16 |     int a
-// CHECK-X64:   32 |   (F5 vbtable pointer)
-// CHECK-X64:   40 |   int a
-// CHECK-X64:   48 |   struct A4 (virtual base)
-// CHECK-X64:   48 |     int a
-// CHECK-X64:      | [sizeof=64, align=16
-// CHECK-X64:      |  nvsize=48, nvalign=16]
+// CHECK-X64-NEXT:    0 | struct F5
+// CHECK-X64-NEXT:    0 |   struct A16f (primary base)
+// CHECK-X64-NEXT:    0 |     (A16f vftable pointer)
+// CHECK-X64-NEXT:   16 |     int a
+// CHECK-X64-NEXT:   32 |   (F5 vbtable pointer)
+// CHECK-X64-NEXT:   48 |   int a
+// CHECK-X64-NEXT:   64 |   struct A4 (virtual base)
+// CHECK-X64-NEXT:   64 |     int a
+// CHECK-X64-NEXT:      | [sizeof=80, align=16
+// CHECK-X64-NEXT:      |  nvsize=64, nvalign=16]
 
 struct F6 : virtual A16f, A4, virtual B {
 	int a;
@@ -712,45 +730,91 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct F6
-// CHECK:    0 |   (F6 vftable pointer)
-// CHECK:    4 |   struct A4 (base)
-// CHECK:    4 |     int a
-// CHECK:    8 |   (F6 vbtable pointer)
-// CHECK:   12 |   int a
-// CHECK:   16 |   struct A16f (virtual base)
-// CHECK:   16 |     (A16f vftable pointer)
-// CHECK:   32 |     int a
-// CHECK:   48 |   struct B (virtual base)
-// CHECK:   48 |     struct A4 (base)
-// CHECK:   48 |       int a
-// CHECK:   52 |     struct Y (base)
-// CHECK:   52 |       char y
-// CHECK:   64 |     struct X (base)
-// CHECK:   64 |       (X vbtable pointer)
-// CHECK:   68 |     int a
-// CHECK:      | [sizeof=80, align=16
-// CHECK:      |  nvsize=16, nvalign=4]
+// CHECK-NEXT:    0 | struct F6
+// CHECK-NEXT:    0 |   (F6 vftable pointer)
+// CHECK-NEXT:    4 |   struct A4 (base)
+// CHECK-NEXT:    4 |     int a
+// CHECK-NEXT:    8 |   (F6 vbtable pointer)
+// CHECK-NEXT:   12 |   int a
+// CHECK-NEXT:   16 |   struct A16f (virtual base)
+// CHECK-NEXT:   16 |     (A16f vftable pointer)
+// CHECK-NEXT:   32 |     int a
+// CHECK-NEXT:   48 |   struct B (virtual base)
+// CHECK-NEXT:   48 |     struct A4 (base)
+// CHECK-NEXT:   48 |       int a
+// CHECK-NEXT:   52 |     struct Y (base)
+// CHECK-NEXT:   52 |       char y
+// CHECK-NEXT:   64 |     struct X (base)
+// CHECK-NEXT:   64 |       (X vbtable pointer)
+// CHECK-NEXT:   68 |     int a
+// CHECK-NEXT:      | [sizeof=80, align=16
+// CHECK-NEXT:      |  nvsize=16, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct F6
-// CHECK-X64:    0 |   (F6 vftable pointer)
-// CHECK-X64:    8 |   struct A4 (base)
-// CHECK-X64:    8 |     int a
-// CHECK-X64:   16 |   (F6 vbtable pointer)
-// CHECK-X64:   24 |   int a
-// CHECK-X64:   32 |   struct A16f (virtual base)
-// CHECK-X64:   32 |     (A16f vftable pointer)
-// CHECK-X64:   48 |     int a
-// CHECK-X64:   64 |   struct B (virtual base)
-// CHECK-X64:   64 |     struct A4 (base)
-// CHECK-X64:   64 |       int a
-// CHECK-X64:   68 |     struct Y (base)
-// CHECK-X64:   68 |       char y
-// CHECK-X64:   80 |     struct X (base)
-// CHECK-X64:   80 |       (X vbtable pointer)
-// CHECK-X64:   88 |     int a
-// CHECK-X64:      | [sizeof=96, align=16
-// CHECK-X64:      |  nvsize=32, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct F6
+// CHECK-X64-NEXT:    0 |   (F6 vftable pointer)
+// CHECK-X64-NEXT:    8 |   struct A4 (base)
+// CHECK-X64-NEXT:    8 |     int a
+// CHECK-X64-NEXT:   16 |   (F6 vbtable pointer)
+// CHECK-X64-NEXT:   24 |   int a
+// CHECK-X64-NEXT:   32 |   struct A16f (virtual base)
+// CHECK-X64-NEXT:   32 |     (A16f vftable pointer)
+// CHECK-X64-NEXT:   48 |     int a
+// CHECK-X64-NEXT:   64 |   struct B (virtual base)
+// CHECK-X64-NEXT:   64 |     struct A4 (base)
+// CHECK-X64-NEXT:   64 |       int a
+// CHECK-X64-NEXT:   68 |     struct Y (base)
+// CHECK-X64-NEXT:   68 |       char y
+// CHECK-X64-NEXT:   80 |     struct X (base)
+// CHECK-X64-NEXT:   80 |       (X vbtable pointer)
+// CHECK-X64-NEXT:   88 |     int a
+// CHECK-X64-NEXT:      | [sizeof=96, align=16
+// CHECK-X64-NEXT:      |  nvsize=32, nvalign=16]
+
+struct ArrayFieldOfRecords {
+  A4 InlineElts[2];
+};
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct ArrayFieldOfRecords
+// CHECK-NEXT:    0 |   struct A4 [2] InlineElts
+// CHECK-NEXT:      | [sizeof=8, align=4
+// CHECK-NEXT:      |  nvsize=8, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct ArrayFieldOfRecords
+// CHECK-X64-NEXT:    0 |   struct A4 [2] InlineElts
+// CHECK-X64-NEXT:      | [sizeof=8, align=4
+// CHECK-X64-NEXT:      |  nvsize=8, nvalign=4]
+
+struct ArrayOfArrayFieldOfRecords {
+  A4 InlineElts[2][2];
+};
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct ArrayOfArrayFieldOfRecords
+// CHECK-NEXT:    0 |   struct A4 [2][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 ArrayOfArrayFieldOfRecords
+// CHECK-X64-NEXT:    0 |   struct A4 [2][2] InlineElts
+// CHECK-X64-NEXT:      | [sizeof=16, align=4
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=4]
+
+struct RecordArrayTypedef {
+  typedef A4 ArrayTy[2];
+  ArrayTy InlineElts[2];
+};
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct RecordArrayTypedef
+// CHECK-NEXT:    0 |   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:      | [sizeof=16, align=4
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=4]
 
 int a[
 sizeof(TestF0)+
@@ -772,4 +836,8 @@
 sizeof(F3)+
 sizeof(F4)+
 sizeof(F5)+
-sizeof(F6)];
+sizeof(F6)+
+sizeof(ArrayFieldOfRecords)+
+sizeof(ArrayOfArrayFieldOfRecords)+
+sizeof(RecordArrayTypedef)+
+0];
diff --git a/test/Layout/ms-x86-bitfields-vbases.cpp b/test/Layout/ms-x86-bitfields-vbases.cpp
index e11ef67..5b54596 100644
--- a/test/Layout/ms-x86-bitfields-vbases.cpp
+++ b/test/Layout/ms-x86-bitfields-vbases.cpp
@@ -1,84 +1,120 @@
-// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>&1 \
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>&1 \
 // RUN:            | FileCheck %s
-// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>/dev/null \
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>/dev/null \
 // RUN:            | FileCheck %s -check-prefix CHECK-X64
 
-struct B0 { };

-

-struct A : virtual B0 { char a : 1; };

+struct B0 { int a; };
+struct B1 { int a; };
 
-// CHECK: *** Dumping AST Record Layout

-// CHECK:    0 | struct A

-// CHECK:    0 |   (A vbtable pointer)

-// CHECK:    4 |   char a

-// CHECK:    9 |   struct B0 (virtual base) (empty)

-// CHECK:      | [sizeof=9, align=4

-// CHECK:      |  nvsize=8, nvalign=4]

-// CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct A

-// CHECK-X64:    0 |   (A vbtable pointer)

-// CHECK-X64:    8 |   char a

-// CHECK-X64:   17 |   struct B0 (virtual base) (empty)

-// CHECK-X64:      | [sizeof=24, align=8

-// CHECK-X64:      |  nvsize=16, nvalign=8]

-
-struct B : virtual B0 { short a : 1; };

+struct A : virtual B0 { char a : 1; };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct B

-// CHECK:    0 |   (B vbtable pointer)

-// CHECK:    4 |   short a

-// CHECK:   10 |   struct B0 (virtual base) (empty)

-// CHECK:      | [sizeof=10, align=4

-// CHECK:      |  nvsize=8, nvalign=4]

+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct A
+// CHECK-NEXT:    0 |   (A vbtable pointer)
+// CHECK-NEXT:    4 |   char a
+// CHECK-NEXT:    8 |   struct B0 (virtual base)
+// CHECK-NEXT:    8 |     int a
+// CHECK-NEXT:      | [sizeof=12, align=4
+// CHECK-NEXT:      |  nvsize=8, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct B

-// CHECK-X64:    0 |   (B vbtable pointer)

-// CHECK-X64:    8 |   short a

-// CHECK-X64:   18 |   struct B0 (virtual base) (empty)

-// CHECK-X64:      | [sizeof=24, align=8

-// CHECK-X64:      |  nvsize=16, nvalign=8]

+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct A
+// CHECK-X64-NEXT:    0 |   (A vbtable pointer)
+// CHECK-X64-NEXT:    8 |   char a
+// CHECK-X64-NEXT:   16 |   struct B0 (virtual base)
+// CHECK-X64-NEXT:   16 |     int a
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
 
-struct C : virtual B0 { char a : 1; char : 0; };

+struct B : virtual B0 { short a : 1; };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct C

-// CHECK:    0 |   (C vbtable pointer)

-// CHECK:    4 |   char a

-// CHECK:    5 |   char

-// CHECK:    8 |   struct B0 (virtual base) (empty)

-// CHECK:      | [sizeof=8, align=4

-// CHECK:      |  nvsize=8, nvalign=4]

+// CHECK-NEXT:    0 | struct B
+// CHECK-NEXT:    0 |   (B vbtable pointer)
+// CHECK-NEXT:    4 |   short a
+// CHECK-NEXT:    8 |   struct B0 (virtual base)
+// CHECK-NEXT:    8 |     int a
+// CHECK-NEXT:      | [sizeof=12, align=4
+// CHECK-NEXT:      |  nvsize=8, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct C

-// CHECK-X64:    0 |   (C vbtable pointer)

-// CHECK-X64:    8 |   char a

-// CHECK-X64:    9 |   char

-// CHECK-X64:   16 |   struct B0 (virtual base) (empty)

-// CHECK-X64:      | [sizeof=16, align=8

-// CHECK-X64:      |  nvsize=16, nvalign=8]

+// CHECK-X64-NEXT:    0 | struct B
+// CHECK-X64-NEXT:    0 |   (B vbtable pointer)
+// CHECK-X64-NEXT:    8 |   short a
+// CHECK-X64-NEXT:   16 |   struct B0 (virtual base)
+// CHECK-X64-NEXT:   16 |     int a
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
 
-struct D : virtual B0 { char a : 1; char b; };

+struct C : virtual B0 { char a : 1; char : 0; };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct D

-// CHECK:    0 |   (D vbtable pointer)

-// CHECK:    4 |   char a

-// CHECK:    5 |   char b

-// CHECK:    8 |   struct B0 (virtual base) (empty)

-// CHECK:      | [sizeof=8, align=4

-// CHECK:      |  nvsize=8, nvalign=4]

+// CHECK-NEXT:    0 | struct C
+// CHECK-NEXT:    0 |   (C vbtable pointer)
+// CHECK-NEXT:    4 |   char a
+// CHECK-NEXT:    5 |   char
+// CHECK-NEXT:    8 |   struct B0 (virtual base)
+// CHECK-NEXT:    8 |     int a
+// CHECK-NEXT:      | [sizeof=12, align=4
+// CHECK-NEXT:      |  nvsize=8, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct D

-// CHECK-X64:    0 |   (D vbtable pointer)

-// CHECK-X64:    8 |   char a

-// CHECK-X64:    9 |   char b

-// CHECK-X64:   16 |   struct B0 (virtual base) (empty)

-// CHECK-X64:      | [sizeof=16, align=8

-// CHECK-X64:      |  nvsize=16, nvalign=8]

+// CHECK-X64-NEXT:    0 | struct C
+// CHECK-X64-NEXT:    0 |   (C vbtable pointer)
+// CHECK-X64-NEXT:    8 |   char a
+// CHECK-X64-NEXT:    9 |   char
+// CHECK-X64-NEXT:   16 |   struct B0 (virtual base)
+// CHECK-X64-NEXT:   16 |     int a
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
+
+struct D : virtual B0 { char a : 1; char b; };
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct D
+// CHECK-NEXT:    0 |   (D vbtable pointer)
+// CHECK-NEXT:    4 |   char a
+// CHECK-NEXT:    5 |   char b
+// CHECK-NEXT:    8 |   struct B0 (virtual base)
+// CHECK-NEXT:    8 |     int a
+// CHECK-NEXT:      | [sizeof=12, align=4
+// CHECK-NEXT:      |  nvsize=8, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct D
+// CHECK-X64-NEXT:    0 |   (D vbtable pointer)
+// CHECK-X64-NEXT:    8 |   char a
+// CHECK-X64-NEXT:    9 |   char b
+// CHECK-X64-NEXT:   16 |   struct B0 (virtual base)
+// CHECK-X64-NEXT:   16 |     int a
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
+
+struct E : virtual B0, virtual B1 { long long : 1; };
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct E
+// CHECK-NEXT:    0 |   (E vbtable pointer)
+// CHECK-NEXT:    8 |   long long
+// CHECK-NEXT:   16 |   struct B0 (virtual base)
+// CHECK-NEXT:   16 |     int a
+// CHECK-NEXT:   20 |   struct B1 (virtual base)
+// CHECK-NEXT:   20 |     int a
+// CHECK-NEXT:      | [sizeof=24, align=8
+// CHECK-NEXT:      |  nvsize=16, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct E
+// CHECK-X64-NEXT:    0 |   (E vbtable pointer)
+// CHECK-X64-NEXT:    8 |   long long
+// CHECK-X64-NEXT:   16 |   struct B0 (virtual base)
+// CHECK-X64-NEXT:   16 |     int a
+// CHECK-X64-NEXT:   20 |   struct B1 (virtual base)
+// CHECK-X64-NEXT:   20 |     int a
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
 
 int a[
 sizeof(A)+
 sizeof(B)+
 sizeof(C)+
-sizeof(D)];
+sizeof(D)+
+sizeof(E)];
diff --git a/test/Layout/ms-x86-empty-base-after-base-with-vbptr.cpp b/test/Layout/ms-x86-empty-base-after-base-with-vbptr.cpp
new file mode 100644
index 0000000..224594e
--- /dev/null
+++ b/test/Layout/ms-x86-empty-base-after-base-with-vbptr.cpp
@@ -0,0 +1,228 @@
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts %s 2>/dev/null \
+// RUN:            | FileCheck %s
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts %s 2>/dev/null \
+// RUN:            | FileCheck %s -check-prefix CHECK-X64
+
+
+struct U { char a; };
+struct V { };
+struct W { };
+struct X : virtual V { char a; };
+struct Y : virtual V { char a; };
+struct Z : Y { };
+
+struct A : X, W  { char a; };
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct A
+// CHECK-NEXT:    0 |   struct X (base)
+// CHECK-NEXT:    0 |     (X vbtable pointer)
+// CHECK-NEXT:    4 |     char a
+// CHECK-NEXT:    9 |   struct W (base) (empty)
+// CHECK-NEXT:    9 |   char a
+// CHECK-NEXT:   12 |   struct V (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=12, align=4
+// CHECK-NEXT:      |  nvsize=12, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct A
+// CHECK-X64-NEXT:    0 |   struct X (base)
+// CHECK-X64-NEXT:    0 |     (X vbtable pointer)
+// CHECK-X64-NEXT:    8 |     char a
+// CHECK-X64-NEXT:   17 |   struct W (base) (empty)
+// CHECK-X64-NEXT:   17 |   char a
+// CHECK-X64-NEXT:   24 |   struct V (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
+
+struct B : X, U, W  { char a; };
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct B
+// CHECK-NEXT:    0 |   struct X (base)
+// CHECK-NEXT:    0 |     (X vbtable pointer)
+// CHECK-NEXT:    4 |     char a
+// CHECK-NEXT:    8 |   struct U (base)
+// CHECK-NEXT:    8 |     char a
+// CHECK-NEXT:    9 |   struct W (base) (empty)
+// CHECK-NEXT:    9 |   char a
+// CHECK-NEXT:   12 |   struct V (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=12, align=4
+// CHECK-NEXT:      |  nvsize=12, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct B
+// CHECK-X64-NEXT:    0 |   struct X (base)
+// CHECK-X64-NEXT:    0 |     (X vbtable pointer)
+// CHECK-X64-NEXT:    8 |     char a
+// CHECK-X64-NEXT:   16 |   struct U (base)
+// CHECK-X64-NEXT:   16 |     char a
+// CHECK-X64-NEXT:   17 |   struct W (base) (empty)
+// CHECK-X64-NEXT:   17 |   char a
+// CHECK-X64-NEXT:   24 |   struct V (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
+
+struct C : X, V, W  { char a; };
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct C
+// CHECK-NEXT:    0 |   struct X (base)
+// CHECK-NEXT:    0 |     (X vbtable pointer)
+// CHECK-NEXT:    4 |     char a
+// CHECK-NEXT:    9 |   struct V (base) (empty)
+// CHECK-NEXT:   10 |   struct W (base) (empty)
+// CHECK-NEXT:   10 |   char a
+// CHECK-NEXT:   12 |   struct V (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=12, align=4
+// CHECK-NEXT:      |  nvsize=12, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct C
+// CHECK-X64-NEXT:    0 |   struct X (base)
+// CHECK-X64-NEXT:    0 |     (X vbtable pointer)
+// CHECK-X64-NEXT:    8 |     char a
+// CHECK-X64-NEXT:   17 |   struct V (base) (empty)
+// CHECK-X64-NEXT:   18 |   struct W (base) (empty)
+// CHECK-X64-NEXT:   18 |   char a
+// CHECK-X64-NEXT:   24 |   struct V (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
+
+struct D : X, U, V, W  { char a; };
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct D
+// CHECK-NEXT:    0 |   struct X (base)
+// CHECK-NEXT:    0 |     (X vbtable pointer)
+// CHECK-NEXT:    4 |     char a
+// CHECK-NEXT:    8 |   struct U (base)
+// CHECK-NEXT:    8 |     char a
+// CHECK-NEXT:    9 |   struct V (base) (empty)
+// CHECK-NEXT:   10 |   struct W (base) (empty)
+// CHECK-NEXT:   10 |   char a
+// CHECK-NEXT:   12 |   struct V (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=12, align=4
+// CHECK-NEXT:      |  nvsize=12, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct D
+// CHECK-X64-NEXT:    0 |   struct X (base)
+// CHECK-X64-NEXT:    0 |     (X vbtable pointer)
+// CHECK-X64-NEXT:    8 |     char a
+// CHECK-X64-NEXT:   16 |   struct U (base)
+// CHECK-X64-NEXT:   16 |     char a
+// CHECK-X64-NEXT:   17 |   struct V (base) (empty)
+// CHECK-X64-NEXT:   18 |   struct W (base) (empty)
+// CHECK-X64-NEXT:   18 |   char a
+// CHECK-X64-NEXT:   24 |   struct V (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
+
+struct E : X, U, Y, V, W  { char a; };
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct E
+// CHECK-NEXT:    0 |   struct X (base)
+// CHECK-NEXT:    0 |     (X vbtable pointer)
+// CHECK-NEXT:    4 |     char a
+// CHECK-NEXT:    8 |   struct U (base)
+// CHECK-NEXT:    8 |     char a
+// CHECK-NEXT:   12 |   struct Y (base)
+// CHECK-NEXT:   12 |     (Y vbtable pointer)
+// CHECK-NEXT:   16 |     char a
+// CHECK-NEXT:   21 |   struct V (base) (empty)
+// CHECK-NEXT:   22 |   struct W (base) (empty)
+// CHECK-NEXT:   22 |   char a
+// CHECK-NEXT:   24 |   struct V (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=24, align=4
+// CHECK-NEXT:      |  nvsize=24, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct E
+// CHECK-X64-NEXT:    0 |   struct X (base)
+// CHECK-X64-NEXT:    0 |     (X vbtable pointer)
+// CHECK-X64-NEXT:    8 |     char a
+// CHECK-X64-NEXT:   16 |   struct U (base)
+// CHECK-X64-NEXT:   16 |     char a
+// CHECK-X64-NEXT:   24 |   struct Y (base)
+// CHECK-X64-NEXT:   24 |     (Y vbtable pointer)
+// CHECK-X64-NEXT:   32 |     char a
+// CHECK-X64-NEXT:   41 |   struct V (base) (empty)
+// CHECK-X64-NEXT:   42 |   struct W (base) (empty)
+// CHECK-X64-NEXT:   42 |   char a
+// CHECK-X64-NEXT:   48 |   struct V (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=48, align=8
+// CHECK-X64-NEXT:      |  nvsize=48, nvalign=8]
+
+struct F : Z, W  { char a; };
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct F
+// CHECK-NEXT:    0 |   struct Z (base)
+// CHECK-NEXT:    0 |     struct Y (base)
+// CHECK-NEXT:    0 |       (Y vbtable pointer)
+// CHECK-NEXT:    4 |       char a
+// CHECK-NEXT:    9 |   struct W (base) (empty)
+// CHECK-NEXT:    9 |   char a
+// CHECK-NEXT:   12 |   struct V (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=12, align=4
+// CHECK-NEXT:      |  nvsize=12, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct F
+// CHECK-X64-NEXT:    0 |   struct Z (base)
+// CHECK-X64-NEXT:    0 |     struct Y (base)
+// CHECK-X64-NEXT:    0 |       (Y vbtable pointer)
+// CHECK-X64-NEXT:    8 |       char a
+// CHECK-X64-NEXT:   17 |   struct W (base) (empty)
+// CHECK-X64-NEXT:   17 |   char a
+// CHECK-X64-NEXT:   24 |   struct V (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
+
+struct G : X, W, Y, V  { char a; };
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct G
+// CHECK-NEXT:    0 |   struct X (base)
+// CHECK-NEXT:    0 |     (X vbtable pointer)
+// CHECK-NEXT:    4 |     char a
+// CHECK-NEXT:    9 |   struct W (base) (empty)
+// CHECK-NEXT:   12 |   struct Y (base)
+// CHECK-NEXT:   12 |     (Y vbtable pointer)
+// CHECK-NEXT:   16 |     char a
+// CHECK-NEXT:   21 |   struct V (base) (empty)
+// CHECK-NEXT:   21 |   char a
+// CHECK-NEXT:   24 |   struct V (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=24, align=4
+// CHECK-NEXT:      |  nvsize=24, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct G
+// CHECK-X64-NEXT:    0 |   struct X (base)
+// CHECK-X64-NEXT:    0 |     (X vbtable pointer)
+// CHECK-X64-NEXT:    8 |     char a
+// CHECK-X64-NEXT:   17 |   struct W (base) (empty)
+// CHECK-X64-NEXT:   24 |   struct Y (base)
+// CHECK-X64-NEXT:   24 |     (Y vbtable pointer)
+// CHECK-X64-NEXT:   32 |     char a
+// CHECK-X64-NEXT:   41 |   struct V (base) (empty)
+// CHECK-X64-NEXT:   41 |   char a
+// CHECK-X64-NEXT:   48 |   struct V (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=48, align=8
+// CHECK-X64-NEXT:      |  nvsize=48, nvalign=8]
+
+int a[
+sizeof(A)+
+sizeof(B)+
+sizeof(C)+
+sizeof(D)+
+sizeof(E)+
+sizeof(F)+
+sizeof(G)];
diff --git a/test/Layout/ms-x86-empty-nonvirtual-bases.cpp b/test/Layout/ms-x86-empty-nonvirtual-bases.cpp
index 01d10c9..6ef1494 100644
--- a/test/Layout/ms-x86-empty-nonvirtual-bases.cpp
+++ b/test/Layout/ms-x86-empty-nonvirtual-bases.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>/dev/null \
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>/dev/null \
 // RUN:            | FileCheck %s
-// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>/dev/null \
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>/dev/null \
 // RUN:            | FileCheck %s
 
 extern "C" int printf(const char *fmt, ...);
@@ -23,11 +23,12 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct A
-// CHECK:    0 |   struct B0 (base) (empty)
-// CHECK:    0 |   int a
-// CHECK:      | [sizeof=8, align=8
-// CHECK:      |  nvsize=8, nvalign=8]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct A
+// CHECK-NEXT:    0 |   struct B0 (base) (empty)
+// CHECK-NEXT:    0 |   int a
+// CHECK-NEXT:      | [sizeof=8, align=8
+// CHECK-NEXT:      |  nvsize=8, nvalign=8]
 
 struct B : B0 {
 	B0 b0;
@@ -36,14 +37,14 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct B
-// CHECK:    0 |   struct B0 (base) (empty)
-// CHECK:    0 |   struct B0 b0 (empty)
-// CHECK:      |   [sizeof=8, align=8
-// CHECK:      |    nvsize=0, nvalign=1]
-// CHECK:    8 |   int a
-// CHECK:      | [sizeof=16, align=8
-// CHECK:      |  nvsize=16, nvalign=8]
+// CHECK-NEXT:    0 | struct B
+// CHECK-NEXT:    0 |   struct B0 (base) (empty)
+// CHECK-NEXT:    0 |   struct B0 b0 (empty)
+// CHECK-NEXT:      |   [sizeof=8, align=8
+// CHECK-NEXT:      |    nvsize=0, nvalign=8]
+// CHECK:         8 |   int a
+// CHECK-NEXT:      | [sizeof=16, align=8
+// CHECK-NEXT:      |  nvsize=16, nvalign=8]
 
 struct C : B0, B1, B2, B3, B4 {
 	int a;
@@ -51,15 +52,19 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct C
-// CHECK:    0 |   struct B0 (base) (empty)
-// CHECK:    8 |   struct B1 (base) (empty)
-// CHECK:   16 |   struct B2 (base) (empty)
-// CHECK:   24 |   struct B3 (base) (empty)
-// CHECK:   32 |   struct B4 (base) (empty)
-// CHECK:   32 |   int a
-// CHECK:      | [sizeof=40, align=8
-// CHECK:      |  nvsize=40, nvalign=8]
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct C
+// CHECK-NEXT:    0 |   struct B0 (base) (empty)
+// CHECK-NEXT:    8 |   struct B1 (base) (empty)
+// CHECK-NEXT:   16 |   struct B2 (base) (empty)
+// CHECK-NEXT:   24 |   struct B3 (base) (empty)
+// CHECK-NEXT:   32 |   struct B4 (base) (empty)
+// CHECK-NEXT:   32 |   int a
+// CHECK-NEXT:      | [sizeof=40, align=8
+// CHECK-NEXT:      |  nvsize=40, nvalign=8]
 
 struct D {
 	B0 b0;
@@ -72,28 +77,31 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct D
-// CHECK:    0 |   struct B0 b0 (empty)
-// CHECK:      |   [sizeof=8, align=8
-// CHECK:      |    nvsize=0, nvalign=1]
-// CHECK:    8 |   struct C0 c0
-// CHECK:    8 |     int a
-// CHECK:      |   [sizeof=4, align=4
-// CHECK:      |    nvsize=4, nvalign=4]
-// CHECK:   12 |   struct C1 c1
-// CHECK:   12 |     int a
-// CHECK:      |   [sizeof=4, align=4
-// CHECK:      |    nvsize=4, nvalign=4]
-// CHECK:   16 |   struct C2 c2
-// CHECK:   16 |     int a
-// CHECK:      |   [sizeof=4, align=4
-// CHECK:      |    nvsize=4, nvalign=4]
-// CHECK:   24 |   struct B1 b1 (empty)
-// CHECK:      |   [sizeof=8, align=8
-// CHECK:      |    nvsize=0, nvalign=1]
-// CHECK:   32 |   int a
-// CHECK:      | [sizeof=40, align=8
-// CHECK:      |  nvsize=40, nvalign=8]
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct D
+// CHECK-NEXT:    0 |   struct B0 b0 (empty)
+// CHECK-NEXT:      |   [sizeof=8, align=8
+// CHECK-NEXT:      |    nvsize=0, nvalign=8]
+// CHECK:         8 |   struct C0 c0
+// CHECK-NEXT:    8 |     int a
+// CHECK-NEXT:      |   [sizeof=4, align=4
+// CHECK-NEXT:      |    nvsize=4, nvalign=4]
+// CHECK:        12 |   struct C1 c1
+// CHECK-NEXT:   12 |     int a
+// CHECK-NEXT:      |   [sizeof=4, align=4
+// CHECK-NEXT:      |    nvsize=4, nvalign=4]
+// CHECK:        16 |   struct C2 c2
+// CHECK-NEXT:   16 |     int a
+// CHECK-NEXT:      |   [sizeof=4, align=4
+// CHECK-NEXT:      |    nvsize=4, nvalign=4]
+// CHECK:        24 |   struct B1 b1 (empty)
+// CHECK-NEXT:      |   [sizeof=8, align=8
+// CHECK-NEXT:      |    nvsize=0, nvalign=8]
+// CHECK:        32 |   int a
+// CHECK-NEXT:      | [sizeof=40, align=8
+// CHECK-NEXT:      |  nvsize=40, nvalign=8]
 
 struct E : B0, C0, C1, C2, B1 {
 	int a;
@@ -101,18 +109,18 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct E
-// CHECK:    0 |   struct B0 (base) (empty)
-// CHECK:    0 |   struct C0 (base)
-// CHECK:    0 |     int a
-// CHECK:    4 |   struct C1 (base)
-// CHECK:    4 |     int a
-// CHECK:    8 |   struct C2 (base)
-// CHECK:    8 |     int a
-// CHECK:   16 |   struct B1 (base) (empty)
-// CHECK:   16 |   int a
-// CHECK:      | [sizeof=24, align=8
-// CHECK:      |  nvsize=24, nvalign=8]
+// CHECK-NEXT:    0 | struct E
+// CHECK-NEXT:    0 |   struct B0 (base) (empty)
+// CHECK-NEXT:    0 |   struct C0 (base)
+// CHECK-NEXT:    0 |     int a
+// CHECK-NEXT:    4 |   struct C1 (base)
+// CHECK-NEXT:    4 |     int a
+// CHECK-NEXT:    8 |   struct C2 (base)
+// CHECK-NEXT:    8 |     int a
+// CHECK-NEXT:   16 |   struct B1 (base) (empty)
+// CHECK-NEXT:   16 |   int a
+// CHECK-NEXT:      | [sizeof=24, align=8
+// CHECK-NEXT:      |  nvsize=24, nvalign=8]
 
 struct F : C0, B0, B1, C1 {
 	int a;
@@ -120,16 +128,16 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct F
-// CHECK:    0 |   struct C0 (base)
-// CHECK:    0 |     int a
-// CHECK:    8 |   struct B0 (base) (empty)
-// CHECK:   16 |   struct B1 (base) (empty)
-// CHECK:   16 |   struct C1 (base)
-// CHECK:   16 |     int a
-// CHECK:   20 |   int a
-// CHECK:      | [sizeof=24, align=8
-// CHECK:      |  nvsize=24, nvalign=8]
+// CHECK-NEXT:    0 | struct F
+// CHECK-NEXT:    0 |   struct C0 (base)
+// CHECK-NEXT:    0 |     int a
+// CHECK-NEXT:    8 |   struct B0 (base) (empty)
+// CHECK-NEXT:   16 |   struct B1 (base) (empty)
+// CHECK-NEXT:   16 |   struct C1 (base)
+// CHECK-NEXT:   16 |     int a
+// CHECK-NEXT:   20 |   int a
+// CHECK-NEXT:      | [sizeof=24, align=8
+// CHECK-NEXT:      |  nvsize=24, nvalign=8]
 
 struct G : B0, B1, B2, B3, B4 {
 	__declspec(align(32)) int a;
@@ -137,15 +145,15 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct G
-// CHECK:    0 |   struct B0 (base) (empty)
-// CHECK:    8 |   struct B1 (base) (empty)
-// CHECK:   16 |   struct B2 (base) (empty)
-// CHECK:   24 |   struct B3 (base) (empty)
-// CHECK:   32 |   struct B4 (base) (empty)
-// CHECK:   32 |   int a
-// CHECK:      | [sizeof=64, align=32
-// CHECK:      |  nvsize=64, nvalign=32]
+// CHECK-NEXT:    0 | struct G
+// CHECK-NEXT:    0 |   struct B0 (base) (empty)
+// CHECK-NEXT:    8 |   struct B1 (base) (empty)
+// CHECK-NEXT:   16 |   struct B2 (base) (empty)
+// CHECK-NEXT:   24 |   struct B3 (base) (empty)
+// CHECK-NEXT:   32 |   struct B4 (base) (empty)
+// CHECK-NEXT:   32 |   int a
+// CHECK-NEXT:      | [sizeof=64, align=32
+// CHECK-NEXT:      |  nvsize=64, nvalign=32]
 
 struct __declspec(align(32)) H : B0, B1, B2, B3, B4 {
 	int a;
@@ -153,15 +161,15 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct H
-// CHECK:    0 |   struct B0 (base) (empty)
-// CHECK:    8 |   struct B1 (base) (empty)
-// CHECK:   16 |   struct B2 (base) (empty)
-// CHECK:   24 |   struct B3 (base) (empty)
-// CHECK:   32 |   struct B4 (base) (empty)
-// CHECK:   32 |   int a
-// CHECK:      | [sizeof=64, align=32
-// CHECK:      |  nvsize=40, nvalign=8]
+// CHECK-NEXT:    0 | struct H
+// CHECK-NEXT:    0 |   struct B0 (base) (empty)
+// CHECK-NEXT:    8 |   struct B1 (base) (empty)
+// CHECK-NEXT:   16 |   struct B2 (base) (empty)
+// CHECK-NEXT:   24 |   struct B3 (base) (empty)
+// CHECK-NEXT:   32 |   struct B4 (base) (empty)
+// CHECK-NEXT:   32 |   int a
+// CHECK-NEXT:      | [sizeof=64, align=32
+// CHECK-NEXT:      |  nvsize=40, nvalign=32]
 
 int a[
 sizeof(A)+
diff --git a/test/Layout/ms-x86-empty-virtual-base.cpp b/test/Layout/ms-x86-empty-virtual-base.cpp
index ef6f081..23e287a 100644
--- a/test/Layout/ms-x86-empty-virtual-base.cpp
+++ b/test/Layout/ms-x86-empty-virtual-base.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>/dev/null \
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>/dev/null \
 // RUN:            | FileCheck %s
-// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>/dev/null \
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>/dev/null \
 // RUN:            | FileCheck %s -check-prefix CHECK-X64
 
 extern "C" int printf(const char *fmt, ...);
@@ -27,19 +27,21 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct A
-// CHECK:    0 |   (A vbtable pointer)
-// CHECK:    4 |   int a
-// CHECK:    8 |   struct B0 (virtual base) (empty)
-// CHECK:      | [sizeof=8, align=8
-// CHECK:      |  nvsize=8, nvalign=4]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct A
+// CHECK-NEXT:    0 |   (A vbtable pointer)
+// CHECK-NEXT:    4 |   int a
+// CHECK-NEXT:    8 |   struct B0 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=8, align=8
+// CHECK-NEXT:      |  nvsize=8, nvalign=8]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct A
-// CHECK-X64:    0 |   (A vbtable pointer)
-// CHECK-X64:    8 |   int a
-// CHECK-X64:   16 |   struct B0 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=16, align=8
-// CHECK-X64:      |  nvsize=16, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct A
+// CHECK-X64-NEXT:    0 |   (A vbtable pointer)
+// CHECK-X64-NEXT:    8 |   int a
+// CHECK-X64-NEXT:   16 |   struct B0 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=16, align=8
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
 
 struct B : virtual B0 {
 	B0 b0;
@@ -48,25 +50,25 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct B
-// CHECK:    0 |   (B vbtable pointer)
-// CHECK:    8 |   struct B0 b0 (empty)
-// CHECK:      |   [sizeof=8, align=8
-// CHECK:      |    nvsize=0, nvalign=1]
-// CHECK:   16 |   int a
-// CHECK:   24 |   struct B0 (virtual base) (empty)
-// CHECK:      | [sizeof=24, align=8
-// CHECK:      |  nvsize=24, nvalign=8]
+// CHECK-NEXT:    0 | struct B
+// CHECK-NEXT:    0 |   (B vbtable pointer)
+// CHECK-NEXT:    8 |   struct B0 b0 (empty)
+// CHECK-NEXT:      |   [sizeof=8, align=8
+// CHECK-NEXT:      |    nvsize=0, nvalign=8]
+// CHECK:        16 |   int a
+// CHECK-NEXT:   24 |   struct B0 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=24, align=8
+// CHECK-NEXT:      |  nvsize=24, nvalign=8]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct B
-// CHECK-X64:    0 |   (B vbtable pointer)
-// CHECK-X64:    8 |   struct B0 b0 (empty)
-// CHECK-X64:      |   [sizeof=8, align=8
-// CHECK-X64:      |    nvsize=0, nvalign=1]
-// CHECK-X64:   16 |   int a
-// CHECK-X64:   24 |   struct B0 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=24, align=8
-// CHECK-X64:      |  nvsize=24, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct B
+// CHECK-X64-NEXT:    0 |   (B vbtable pointer)
+// CHECK-X64-NEXT:    8 |   struct B0 b0 (empty)
+// CHECK-X64-NEXT:      |   [sizeof=8, align=8
+// CHECK-X64-NEXT:      |    nvsize=0, nvalign=8]
+// CHECK-X64:        16 |   int a
+// CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
 
 struct C : virtual B0, virtual B1, virtual B2, virtual B3, virtual B4 {
 	int a;
@@ -74,27 +76,35 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct C
-// CHECK:    0 |   (C vbtable pointer)
-// CHECK:    4 |   int a
-// CHECK:    8 |   struct B0 (virtual base) (empty)
-// CHECK:   16 |   struct B1 (virtual base) (empty)
-// CHECK:   24 |   struct B2 (virtual base) (empty)
-// CHECK:   32 |   struct B3 (virtual base) (empty)
-// CHECK:   40 |   struct B4 (virtual base) (empty)
-// CHECK:      | [sizeof=40, align=8
-// CHECK:      |  nvsize=8, nvalign=4]
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct C
+// CHECK-NEXT:    0 |   (C vbtable pointer)
+// CHECK-NEXT:    4 |   int a
+// CHECK-NEXT:    8 |   struct B0 (virtual base) (empty)
+// CHECK-NEXT:   16 |   struct B1 (virtual base) (empty)
+// CHECK-NEXT:   24 |   struct B2 (virtual base) (empty)
+// CHECK-NEXT:   32 |   struct B3 (virtual base) (empty)
+// CHECK-NEXT:   40 |   struct B4 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=40, align=8
+// CHECK-NEXT:      |  nvsize=8, nvalign=8]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct C
-// CHECK-X64:    0 |   (C vbtable pointer)
-// CHECK-X64:    8 |   int a
-// CHECK-X64:   16 |   struct B0 (virtual base) (empty)
-// CHECK-X64:   24 |   struct B1 (virtual base) (empty)
-// CHECK-X64:   32 |   struct B2 (virtual base) (empty)
-// CHECK-X64:   40 |   struct B3 (virtual base) (empty)
-// CHECK-X64:   48 |   struct B4 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=48, align=8
-// CHECK-X64:      |  nvsize=16, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct C
+// CHECK-X64-NEXT:    0 |   (C vbtable pointer)
+// CHECK-X64-NEXT:    8 |   int a
+// CHECK-X64-NEXT:   16 |   struct B0 (virtual base) (empty)
+// CHECK-X64-NEXT:   24 |   struct B1 (virtual base) (empty)
+// CHECK-X64-NEXT:   32 |   struct B2 (virtual base) (empty)
+// CHECK-X64-NEXT:   40 |   struct B3 (virtual base) (empty)
+// CHECK-X64-NEXT:   48 |   struct B4 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=48, align=8
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
 
 struct D {
 	B0 b0;
@@ -107,31 +117,37 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct D
-// CHECK:    0 |   struct B0 b0 (empty)
-// CHECK:    8 |   struct C0 c0
-// CHECK:    8 |     int a
-// CHECK:   12 |   struct C1 c1
-// CHECK:   12 |     int a
-// CHECK:   16 |   struct C2 c2
-// CHECK:   16 |     int a
-// CHECK:   24 |   struct B1 b1 (empty)
-// CHECK:   32 |   int a
-// CHECK:      | [sizeof=40, align=8
-// CHECK:      |  nvsize=40, nvalign=8]
-// CHECK-64: *** Dumping AST Record Layout
-// CHECK-64:    0 | struct D
-// CHECK-64:    0 |   struct B0 b0 (empty)
-// CHECK-64:    8 |   struct C0 c0
-// CHECK-64:    8 |     int a
-// CHECK-64:   12 |   struct C1 c1
-// CHECK-64:   12 |     int a
-// CHECK-64:   16 |   struct C2 c2
-// CHECK-64:   16 |     int a
-// CHECK-64:   24 |   struct B1 b1 (empty)
-// CHECK-64:   32 |   int a
-// CHECK-64:      | [sizeof=40, align=8
-// CHECK-64:      |  nvsize=40, nvalign=8]
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct D
+// CHECK-NEXT:    0 |   struct B0 b0 (empty)
+// CHECK:         8 |   struct C0 c0
+// CHECK-NEXT:    8 |     int a
+// CHECK:        12 |   struct C1 c1
+// CHECK-NEXT:   12 |     int a
+// CHECK:        16 |   struct C2 c2
+// CHECK-NEXT:   16 |     int a
+// CHECK:        24 |   struct B1 b1 (empty)
+// CHECK:        32 |   int a
+// CHECK-NEXT:      | [sizeof=40, align=8
+// CHECK-NEXT:      |  nvsize=40, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct D
+// CHECK-X64-NEXT:    0 |   struct B0 b0 (empty)
+// CHECK-X64:         8 |   struct C0 c0
+// CHECK-X64-NEXT:    8 |     int a
+// CHECK-X64:        12 |   struct C1 c1
+// CHECK-X64-NEXT:   12 |     int a
+// CHECK-X64:        16 |   struct C2 c2
+// CHECK-X64-NEXT:   16 |     int a
+// CHECK-X64:        24 |   struct B1 b1 (empty)
+// CHECK-X64:        32 |   int a
+// CHECK-X64-NEXT:      | [sizeof=40, align=8
+// CHECK-X64-NEXT:      |  nvsize=40, nvalign=8]
 
 struct E : virtual B0, virtual C0, virtual C1, virtual C2, virtual B1 {
 	int a;
@@ -139,33 +155,33 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct E
-// CHECK:    0 |   (E vbtable pointer)
-// CHECK:    4 |   int a
-// CHECK:    8 |   struct B0 (virtual base) (empty)
-// CHECK:    8 |   struct C0 (virtual base)
-// CHECK:    8 |     int a
-// CHECK:   12 |   struct C1 (virtual base)
-// CHECK:   12 |     int a
-// CHECK:   16 |   struct C2 (virtual base)
-// CHECK:   16 |     int a
-// CHECK:   24 |   struct B1 (virtual base) (empty)
-// CHECK:      | [sizeof=24, align=8
-// CHECK:      |  nvsize=8, nvalign=4]
+// CHECK-NEXT:    0 | struct E
+// CHECK-NEXT:    0 |   (E vbtable pointer)
+// CHECK-NEXT:    4 |   int a
+// CHECK-NEXT:    8 |   struct B0 (virtual base) (empty)
+// CHECK-NEXT:    8 |   struct C0 (virtual base)
+// CHECK-NEXT:    8 |     int a
+// CHECK-NEXT:   12 |   struct C1 (virtual base)
+// CHECK-NEXT:   12 |     int a
+// CHECK-NEXT:   16 |   struct C2 (virtual base)
+// CHECK-NEXT:   16 |     int a
+// CHECK-NEXT:   24 |   struct B1 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=24, align=8
+// CHECK-NEXT:      |  nvsize=8, nvalign=8]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct E
-// CHECK-X64:    0 |   (E vbtable pointer)
-// CHECK-X64:    8 |   int a
-// CHECK-X64:   16 |   struct B0 (virtual base) (empty)
-// CHECK-X64:   16 |   struct C0 (virtual base)
-// CHECK-X64:   16 |     int a
-// CHECK-X64:   20 |   struct C1 (virtual base)
-// CHECK-X64:   20 |     int a
-// CHECK-X64:   24 |   struct C2 (virtual base)
-// CHECK-X64:   24 |     int a
-// CHECK-X64:   32 |   struct B1 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=32, align=8
-// CHECK-X64:      |  nvsize=16, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct E
+// CHECK-X64-NEXT:    0 |   (E vbtable pointer)
+// CHECK-X64-NEXT:    8 |   int a
+// CHECK-X64-NEXT:   16 |   struct B0 (virtual base) (empty)
+// CHECK-X64-NEXT:   16 |   struct C0 (virtual base)
+// CHECK-X64-NEXT:   16 |     int a
+// CHECK-X64-NEXT:   20 |   struct C1 (virtual base)
+// CHECK-X64-NEXT:   20 |     int a
+// CHECK-X64-NEXT:   24 |   struct C2 (virtual base)
+// CHECK-X64-NEXT:   24 |     int a
+// CHECK-X64-NEXT:   32 |   struct B1 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=32, align=8
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
 
 struct F : virtual C0, virtual B0, virtual B1, virtual C1 {
 	int a;
@@ -173,29 +189,29 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct F
-// CHECK:    0 |   (F vbtable pointer)
-// CHECK:    4 |   int a
-// CHECK:    8 |   struct C0 (virtual base)
-// CHECK:    8 |     int a
-// CHECK:   16 |   struct B0 (virtual base) (empty)
-// CHECK:   24 |   struct B1 (virtual base) (empty)
-// CHECK:   24 |   struct C1 (virtual base)
-// CHECK:   24 |     int a
-// CHECK:      | [sizeof=32, align=8
-// CHECK:      |  nvsize=8, nvalign=4]
+// CHECK-NEXT:    0 | struct F
+// CHECK-NEXT:    0 |   (F vbtable pointer)
+// CHECK-NEXT:    4 |   int a
+// CHECK-NEXT:    8 |   struct C0 (virtual base)
+// CHECK-NEXT:    8 |     int a
+// CHECK-NEXT:   16 |   struct B0 (virtual base) (empty)
+// CHECK-NEXT:   24 |   struct B1 (virtual base) (empty)
+// CHECK-NEXT:   24 |   struct C1 (virtual base)
+// CHECK-NEXT:   24 |     int a
+// CHECK-NEXT:      | [sizeof=32, align=8
+// CHECK-NEXT:      |  nvsize=8, nvalign=8]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct F
-// CHECK-X64:    0 |   (F vbtable pointer)
-// CHECK-X64:    8 |   int a
-// CHECK-X64:   16 |   struct C0 (virtual base)
-// CHECK-X64:   16 |     int a
-// CHECK-X64:   24 |   struct B0 (virtual base) (empty)
-// CHECK-X64:   32 |   struct B1 (virtual base) (empty)
-// CHECK-X64:   32 |   struct C1 (virtual base)
-// CHECK-X64:   32 |     int a
-// CHECK-X64:      | [sizeof=40, align=8
-// CHECK-X64:      |  nvsize=16, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct F
+// CHECK-X64-NEXT:    0 |   (F vbtable pointer)
+// CHECK-X64-NEXT:    8 |   int a
+// CHECK-X64-NEXT:   16 |   struct C0 (virtual base)
+// CHECK-X64-NEXT:   16 |     int a
+// CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
+// CHECK-X64-NEXT:   32 |   struct B1 (virtual base) (empty)
+// CHECK-X64-NEXT:   32 |   struct C1 (virtual base)
+// CHECK-X64-NEXT:   32 |     int a
+// CHECK-X64-NEXT:      | [sizeof=40, align=8
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
 
 struct G : virtual C0, virtual B0, virtual B1, D0, virtual C1 {
 	int a;
@@ -204,33 +220,35 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct G
-// CHECK:    0 |   struct D0 (primary base)
-// CHECK:    0 |     (D0 vftable pointer)
-// CHECK:    4 |   (G vbtable pointer)
-// CHECK:   20 |   int a
-// CHECK:   32 |   struct C0 (virtual base)
-// CHECK:   32 |     int a
-// CHECK:   40 |   struct B0 (virtual base) (empty)
-// CHECK:   56 |   struct B1 (virtual base) (empty)
-// CHECK:   56 |   struct C1 (virtual base)
-// CHECK:   56 |     int a
-// CHECK:      | [sizeof=64, align=16
-// CHECK:      |  nvsize=32, nvalign=16]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct G
+// CHECK-NEXT:    0 |   struct D0 (primary base)
+// CHECK-NEXT:    0 |     (D0 vftable pointer)
+// CHECK-NEXT:    4 |   (G vbtable pointer)
+// CHECK-NEXT:   20 |   int a
+// CHECK-NEXT:   32 |   struct C0 (virtual base)
+// CHECK-NEXT:   32 |     int a
+// CHECK-NEXT:   40 |   struct B0 (virtual base) (empty)
+// CHECK-NEXT:   56 |   struct B1 (virtual base) (empty)
+// CHECK-NEXT:   56 |   struct C1 (virtual base)
+// CHECK-NEXT:   56 |     int a
+// CHECK-NEXT:      | [sizeof=64, align=16
+// CHECK-NEXT:      |  nvsize=32, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct G
-// CHECK-X64:    0 |   struct D0 (primary base)
-// CHECK-X64:    0 |     (D0 vftable pointer)
-// CHECK-X64:    8 |   (G vbtable pointer)
-// CHECK-X64:   16 |   int a
-// CHECK-X64:   32 |   struct C0 (virtual base)
-// CHECK-X64:   32 |     int a
-// CHECK-X64:   40 |   struct B0 (virtual base) (empty)
-// CHECK-X64:   56 |   struct B1 (virtual base) (empty)
-// CHECK-X64:   56 |   struct C1 (virtual base)
-// CHECK-X64:   56 |     int a
-// CHECK-X64:      | [sizeof=64, align=16
-// CHECK-X64:      |  nvsize=32, nvalign=16]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct G
+// CHECK-X64-NEXT:    0 |   struct D0 (primary base)
+// CHECK-X64-NEXT:    0 |     (D0 vftable pointer)
+// CHECK-X64-NEXT:    8 |   (G vbtable pointer)
+// CHECK-X64-NEXT:   24 |   int a
+// CHECK-X64-NEXT:   32 |   struct C0 (virtual base)
+// CHECK-X64-NEXT:   32 |     int a
+// CHECK-X64-NEXT:   40 |   struct B0 (virtual base) (empty)
+// CHECK-X64-NEXT:   56 |   struct B1 (virtual base) (empty)
+// CHECK-X64-NEXT:   56 |   struct C1 (virtual base)
+// CHECK-X64-NEXT:   56 |     int a
+// CHECK-X64-NEXT:      | [sizeof=64, align=16
+// CHECK-X64-NEXT:      |  nvsize=32, nvalign=16]
 
 struct H : virtual C0, virtual B0, virtual B1, virtual D0, virtual C1 {
 	int a;
@@ -239,35 +257,35 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct H
-// CHECK:    0 |   (H vbtable pointer)
-// CHECK:    4 |   int a
-// CHECK:    8 |   struct C0 (virtual base)
-// CHECK:    8 |     int a
-// CHECK:   16 |   struct B0 (virtual base) (empty)
-// CHECK:   24 |   struct B1 (virtual base) (empty)
-// CHECK:   44 |   (vtordisp for vbase D0)
-// CHECK:   48 |   struct D0 (virtual base)
-// CHECK:   48 |     (D0 vftable pointer)
-// CHECK:   52 |   struct C1 (virtual base)
-// CHECK:   52 |     int a
-// CHECK:      | [sizeof=64, align=16
-// CHECK:      |  nvsize=8, nvalign=4]
+// CHECK-NEXT:    0 | struct H
+// CHECK-NEXT:    0 |   (H vbtable pointer)
+// CHECK-NEXT:    4 |   int a
+// CHECK-NEXT:    8 |   struct C0 (virtual base)
+// CHECK-NEXT:    8 |     int a
+// CHECK-NEXT:   16 |   struct B0 (virtual base) (empty)
+// CHECK-NEXT:   24 |   struct B1 (virtual base) (empty)
+// CHECK-NEXT:   44 |   (vtordisp for vbase D0)
+// CHECK-NEXT:   48 |   struct D0 (virtual base)
+// CHECK-NEXT:   48 |     (D0 vftable pointer)
+// CHECK-NEXT:   52 |   struct C1 (virtual base)
+// CHECK-NEXT:   52 |     int a
+// CHECK-NEXT:      | [sizeof=64, align=16
+// CHECK-NEXT:      |  nvsize=8, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct H
-// CHECK-X64:    0 |   (H vbtable pointer)
-// CHECK-X64:    8 |   int a
-// CHECK-X64:   16 |   struct C0 (virtual base)
-// CHECK-X64:   16 |     int a
-// CHECK-X64:   24 |   struct B0 (virtual base) (empty)
-// CHECK-X64:   40 |   struct B1 (virtual base) (empty)
-// CHECK-X64:   60 |   (vtordisp for vbase D0)
-// CHECK-X64:   64 |   struct D0 (virtual base)
-// CHECK-X64:   64 |     (D0 vftable pointer)
-// CHECK-X64:   72 |   struct C1 (virtual base)
-// CHECK-X64:   72 |     int a
-// CHECK-X64:      | [sizeof=80, align=16
-// CHECK-X64:      |  nvsize=16, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct H
+// CHECK-X64-NEXT:    0 |   (H vbtable pointer)
+// CHECK-X64-NEXT:    8 |   int a
+// CHECK-X64-NEXT:   16 |   struct C0 (virtual base)
+// CHECK-X64-NEXT:   16 |     int a
+// CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
+// CHECK-X64-NEXT:   40 |   struct B1 (virtual base) (empty)
+// CHECK-X64-NEXT:   60 |   (vtordisp for vbase D0)
+// CHECK-X64-NEXT:   64 |   struct D0 (virtual base)
+// CHECK-X64-NEXT:   64 |     (D0 vftable pointer)
+// CHECK-X64-NEXT:   72 |   struct C1 (virtual base)
+// CHECK-X64-NEXT:   72 |     int a
+// CHECK-X64-NEXT:      | [sizeof=80, align=16
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=16]
 
 struct I : virtual B0, virtual B1, virtual B2, virtual B3, virtual B4 {
 	__declspec(align(32)) int a;
@@ -275,27 +293,27 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct I
-// CHECK:    0 |   (I vbtable pointer)
-// CHECK:   32 |   int a
-// CHECK:   64 |   struct B0 (virtual base) (empty)
-// CHECK:   72 |   struct B1 (virtual base) (empty)
-// CHECK:  104 |   struct B2 (virtual base) (empty)
-// CHECK:  136 |   struct B3 (virtual base) (empty)
-// CHECK:  168 |   struct B4 (virtual base) (empty)
-// CHECK:      | [sizeof=192, align=32
-// CHECK:      |  nvsize=64, nvalign=32]
+// CHECK-NEXT:    0 | struct I
+// CHECK-NEXT:    0 |   (I vbtable pointer)
+// CHECK-NEXT:   32 |   int a
+// CHECK-NEXT:   64 |   struct B0 (virtual base) (empty)
+// CHECK-NEXT:   72 |   struct B1 (virtual base) (empty)
+// CHECK-NEXT:  104 |   struct B2 (virtual base) (empty)
+// CHECK-NEXT:  136 |   struct B3 (virtual base) (empty)
+// CHECK-NEXT:  168 |   struct B4 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=192, align=32
+// CHECK-NEXT:      |  nvsize=64, nvalign=32]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct I
-// CHECK-X64:    0 |   (I vbtable pointer)
-// CHECK-X64:   32 |   int a
-// CHECK-X64:   64 |   struct B0 (virtual base) (empty)
-// CHECK-X64:   72 |   struct B1 (virtual base) (empty)
-// CHECK-X64:  104 |   struct B2 (virtual base) (empty)
-// CHECK-X64:  136 |   struct B3 (virtual base) (empty)
-// CHECK-X64:  168 |   struct B4 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=192, align=32
-// CHECK-X64:      |  nvsize=64, nvalign=32]
+// CHECK-X64-NEXT:    0 | struct I
+// CHECK-X64-NEXT:    0 |   (I vbtable pointer)
+// CHECK-X64-NEXT:   32 |   int a
+// CHECK-X64-NEXT:   64 |   struct B0 (virtual base) (empty)
+// CHECK-X64-NEXT:   72 |   struct B1 (virtual base) (empty)
+// CHECK-X64-NEXT:  104 |   struct B2 (virtual base) (empty)
+// CHECK-X64-NEXT:  136 |   struct B3 (virtual base) (empty)
+// CHECK-X64-NEXT:  168 |   struct B4 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=192, align=32
+// CHECK-X64-NEXT:      |  nvsize=64, nvalign=32]
 
 struct __declspec(align(32)) J : virtual B0, virtual B1, virtual B2, virtual B3, virtual B4 {
 	int a;
@@ -303,27 +321,27 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct J
-// CHECK:    0 |   (J vbtable pointer)
-// CHECK:    4 |   int a
-// CHECK:    8 |   struct B0 (virtual base) (empty)
-// CHECK:   40 |   struct B1 (virtual base) (empty)
-// CHECK:   72 |   struct B2 (virtual base) (empty)
-// CHECK:  104 |   struct B3 (virtual base) (empty)
-// CHECK:  136 |   struct B4 (virtual base) (empty)
-// CHECK:      | [sizeof=160, align=32
-// CHECK:      |  nvsize=8, nvalign=4]
+// CHECK-NEXT:    0 | struct J
+// CHECK-NEXT:    0 |   (J vbtable pointer)
+// CHECK-NEXT:    4 |   int a
+// CHECK-NEXT:    8 |   struct B0 (virtual base) (empty)
+// CHECK-NEXT:   40 |   struct B1 (virtual base) (empty)
+// CHECK-NEXT:   72 |   struct B2 (virtual base) (empty)
+// CHECK-NEXT:  104 |   struct B3 (virtual base) (empty)
+// CHECK-NEXT:  136 |   struct B4 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=160, align=32
+// CHECK-NEXT:      |  nvsize=8, nvalign=32]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct J
-// CHECK-X64:    0 |   (J vbtable pointer)
-// CHECK-X64:    8 |   int a
-// CHECK-X64:   16 |   struct B0 (virtual base) (empty)
-// CHECK-X64:   40 |   struct B1 (virtual base) (empty)
-// CHECK-X64:   72 |   struct B2 (virtual base) (empty)
-// CHECK-X64:  104 |   struct B3 (virtual base) (empty)
-// CHECK-X64:  136 |   struct B4 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=160, align=32
-// CHECK-X64:      |  nvsize=16, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct J
+// CHECK-X64-NEXT:    0 |   (J vbtable pointer)
+// CHECK-X64-NEXT:    8 |   int a
+// CHECK-X64-NEXT:   16 |   struct B0 (virtual base) (empty)
+// CHECK-X64-NEXT:   40 |   struct B1 (virtual base) (empty)
+// CHECK-X64-NEXT:   72 |   struct B2 (virtual base) (empty)
+// CHECK-X64-NEXT:  104 |   struct B3 (virtual base) (empty)
+// CHECK-X64-NEXT:  136 |   struct B4 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=160, align=32
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=32]
 
 struct K : virtual D1, virtual B1, virtual B2, virtual B3, virtual B4 {
 	__declspec(align(32)) int a;
@@ -331,27 +349,29 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct K
-// CHECK:    0 |   (K vbtable pointer)
-// CHECK:   32 |   int a
-// CHECK:   64 |   struct D1 (virtual base) (empty)
-// CHECK:   72 |   struct B1 (virtual base) (empty)
-// CHECK:  104 |   struct B2 (virtual base) (empty)
-// CHECK:  136 |   struct B3 (virtual base) (empty)
-// CHECK:  168 |   struct B4 (virtual base) (empty)
-// CHECK:      | [sizeof=192, align=32
-// CHECK:      |  nvsize=64, nvalign=32]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct K
+// CHECK-NEXT:    0 |   (K vbtable pointer)
+// CHECK-NEXT:   32 |   int a
+// CHECK-NEXT:   64 |   struct D1 (virtual base) (empty)
+// CHECK-NEXT:   72 |   struct B1 (virtual base) (empty)
+// CHECK-NEXT:  104 |   struct B2 (virtual base) (empty)
+// CHECK-NEXT:  136 |   struct B3 (virtual base) (empty)
+// CHECK-NEXT:  168 |   struct B4 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=192, align=32
+// CHECK-NEXT:      |  nvsize=64, nvalign=32]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct K
-// CHECK-X64:    0 |   (K vbtable pointer)
-// CHECK-X64:   32 |   int a
-// CHECK-X64:   64 |   struct D1 (virtual base) (empty)
-// CHECK-X64:   72 |   struct B1 (virtual base) (empty)
-// CHECK-X64:  104 |   struct B2 (virtual base) (empty)
-// CHECK-X64:  136 |   struct B3 (virtual base) (empty)
-// CHECK-X64:  168 |   struct B4 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=192, align=32
-// CHECK-X64:      |  nvsize=64, nvalign=32]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct K
+// CHECK-X64-NEXT:    0 |   (K vbtable pointer)
+// CHECK-X64-NEXT:   32 |   int a
+// CHECK-X64-NEXT:   64 |   struct D1 (virtual base) (empty)
+// CHECK-X64-NEXT:   72 |   struct B1 (virtual base) (empty)
+// CHECK-X64-NEXT:  104 |   struct B2 (virtual base) (empty)
+// CHECK-X64-NEXT:  136 |   struct B3 (virtual base) (empty)
+// CHECK-X64-NEXT:  168 |   struct B4 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=192, align=32
+// CHECK-X64-NEXT:      |  nvsize=64, nvalign=32]
 
 struct L : virtual B1, virtual D1, virtual B2, virtual B3, virtual B4 {
 	__declspec(align(32)) int a;
@@ -359,27 +379,27 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct L
-// CHECK:    0 |   (L vbtable pointer)
-// CHECK:   32 |   int a
-// CHECK:   64 |   struct B1 (virtual base) (empty)
-// CHECK:   68 |   struct D1 (virtual base) (empty)
-// CHECK:  104 |   struct B2 (virtual base) (empty)
-// CHECK:  136 |   struct B3 (virtual base) (empty)
-// CHECK:  168 |   struct B4 (virtual base) (empty)
-// CHECK:      | [sizeof=192, align=32
-// CHECK:      |  nvsize=64, nvalign=32]
+// CHECK-NEXT:    0 | struct L
+// CHECK-NEXT:    0 |   (L vbtable pointer)
+// CHECK-NEXT:   32 |   int a
+// CHECK-NEXT:   64 |   struct B1 (virtual base) (empty)
+// CHECK-NEXT:   68 |   struct D1 (virtual base) (empty)
+// CHECK-NEXT:  104 |   struct B2 (virtual base) (empty)
+// CHECK-NEXT:  136 |   struct B3 (virtual base) (empty)
+// CHECK-NEXT:  168 |   struct B4 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=192, align=32
+// CHECK-NEXT:      |  nvsize=64, nvalign=32]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct L
-// CHECK-X64:    0 |   (L vbtable pointer)
-// CHECK-X64:   32 |   int a
-// CHECK-X64:   64 |   struct B1 (virtual base) (empty)
-// CHECK-X64:   68 |   struct D1 (virtual base) (empty)
-// CHECK-X64:  104 |   struct B2 (virtual base) (empty)
-// CHECK-X64:  136 |   struct B3 (virtual base) (empty)
-// CHECK-X64:  168 |   struct B4 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=192, align=32
-// CHECK-X64:      |  nvsize=64, nvalign=32]
+// CHECK-X64-NEXT:    0 | struct L
+// CHECK-X64-NEXT:    0 |   (L vbtable pointer)
+// CHECK-X64-NEXT:   32 |   int a
+// CHECK-X64-NEXT:   64 |   struct B1 (virtual base) (empty)
+// CHECK-X64-NEXT:   68 |   struct D1 (virtual base) (empty)
+// CHECK-X64-NEXT:  104 |   struct B2 (virtual base) (empty)
+// CHECK-X64-NEXT:  136 |   struct B3 (virtual base) (empty)
+// CHECK-X64-NEXT:  168 |   struct B4 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=192, align=32
+// CHECK-X64-NEXT:      |  nvsize=64, nvalign=32]
 
 struct M : virtual B1, virtual B2, virtual D1, virtual B3, virtual B4 {
 	__declspec(align(32)) int a;
@@ -387,27 +407,27 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct M
-// CHECK:    0 |   (M vbtable pointer)
-// CHECK:   32 |   int a
-// CHECK:   64 |   struct B1 (virtual base) (empty)
-// CHECK:   72 |   struct B2 (virtual base) (empty)
-// CHECK:  100 |   struct D1 (virtual base) (empty)
-// CHECK:  136 |   struct B3 (virtual base) (empty)
-// CHECK:  168 |   struct B4 (virtual base) (empty)
-// CHECK:      | [sizeof=192, align=32
-// CHECK:      |  nvsize=64, nvalign=32]
+// CHECK-NEXT:    0 | struct M
+// CHECK-NEXT:    0 |   (M vbtable pointer)
+// CHECK-NEXT:   32 |   int a
+// CHECK-NEXT:   64 |   struct B1 (virtual base) (empty)
+// CHECK-NEXT:   72 |   struct B2 (virtual base) (empty)
+// CHECK-NEXT:  100 |   struct D1 (virtual base) (empty)
+// CHECK-NEXT:  136 |   struct B3 (virtual base) (empty)
+// CHECK-NEXT:  168 |   struct B4 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=192, align=32
+// CHECK-NEXT:      |  nvsize=64, nvalign=32]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct M
-// CHECK-X64:    0 |   (M vbtable pointer)
-// CHECK-X64:   32 |   int a
-// CHECK-X64:   64 |   struct B1 (virtual base) (empty)
-// CHECK-X64:   72 |   struct B2 (virtual base) (empty)
-// CHECK-X64:  100 |   struct D1 (virtual base) (empty)
-// CHECK-X64:  136 |   struct B3 (virtual base) (empty)
-// CHECK-X64:  168 |   struct B4 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=192, align=32
-// CHECK-X64:      |  nvsize=64, nvalign=32]
+// CHECK-X64-NEXT:    0 | struct M
+// CHECK-X64-NEXT:    0 |   (M vbtable pointer)
+// CHECK-X64-NEXT:   32 |   int a
+// CHECK-X64-NEXT:   64 |   struct B1 (virtual base) (empty)
+// CHECK-X64-NEXT:   72 |   struct B2 (virtual base) (empty)
+// CHECK-X64-NEXT:  100 |   struct D1 (virtual base) (empty)
+// CHECK-X64-NEXT:  136 |   struct B3 (virtual base) (empty)
+// CHECK-X64-NEXT:  168 |   struct B4 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=192, align=32
+// CHECK-X64-NEXT:      |  nvsize=64, nvalign=32]
 
 struct N : virtual C0, virtual B1, virtual D1, virtual B2, virtual B3, virtual B4 {
 	__declspec(align(32)) int a;
@@ -415,31 +435,31 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct N
-// CHECK:    0 |   (N vbtable pointer)
-// CHECK:   32 |   int a
-// CHECK:   64 |   struct C0 (virtual base)
-// CHECK:   64 |     int a
-// CHECK:   72 |   struct B1 (virtual base) (empty)
-// CHECK:  100 |   struct D1 (virtual base) (empty)
-// CHECK:  136 |   struct B2 (virtual base) (empty)
-// CHECK:  168 |   struct B3 (virtual base) (empty)
-// CHECK:  200 |   struct B4 (virtual base) (empty)
-// CHECK:      | [sizeof=224, align=32
-// CHECK:      |  nvsize=64, nvalign=32]
+// CHECK-NEXT:    0 | struct N
+// CHECK-NEXT:    0 |   (N vbtable pointer)
+// CHECK-NEXT:   32 |   int a
+// CHECK-NEXT:   64 |   struct C0 (virtual base)
+// CHECK-NEXT:   64 |     int a
+// CHECK-NEXT:   72 |   struct B1 (virtual base) (empty)
+// CHECK-NEXT:  100 |   struct D1 (virtual base) (empty)
+// CHECK-NEXT:  136 |   struct B2 (virtual base) (empty)
+// CHECK-NEXT:  168 |   struct B3 (virtual base) (empty)
+// CHECK-NEXT:  200 |   struct B4 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=224, align=32
+// CHECK-NEXT:      |  nvsize=64, nvalign=32]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct N
-// CHECK-X64:    0 |   (N vbtable pointer)
-// CHECK-X64:   32 |   int a
-// CHECK-X64:   64 |   struct C0 (virtual base)
-// CHECK-X64:   64 |     int a
-// CHECK-X64:   72 |   struct B1 (virtual base) (empty)
-// CHECK-X64:  100 |   struct D1 (virtual base) (empty)
-// CHECK-X64:  136 |   struct B2 (virtual base) (empty)
-// CHECK-X64:  168 |   struct B3 (virtual base) (empty)
-// CHECK-X64:  200 |   struct B4 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=224, align=32
-// CHECK-X64:      |  nvsize=64, nvalign=32]
+// CHECK-X64-NEXT:    0 | struct N
+// CHECK-X64-NEXT:    0 |   (N vbtable pointer)
+// CHECK-X64-NEXT:   32 |   int a
+// CHECK-X64-NEXT:   64 |   struct C0 (virtual base)
+// CHECK-X64-NEXT:   64 |     int a
+// CHECK-X64-NEXT:   72 |   struct B1 (virtual base) (empty)
+// CHECK-X64-NEXT:  100 |   struct D1 (virtual base) (empty)
+// CHECK-X64-NEXT:  136 |   struct B2 (virtual base) (empty)
+// CHECK-X64-NEXT:  168 |   struct B3 (virtual base) (empty)
+// CHECK-X64-NEXT:  200 |   struct B4 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=224, align=32
+// CHECK-X64-NEXT:      |  nvsize=64, nvalign=32]
 
 struct O : virtual C0, virtual B1, virtual B2, virtual D1, virtual B3, virtual B4 {
 	__declspec(align(32)) int a;
@@ -447,31 +467,31 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct O
-// CHECK:    0 |   (O vbtable pointer)
-// CHECK:   32 |   int a
-// CHECK:   64 |   struct C0 (virtual base)
-// CHECK:   64 |     int a
-// CHECK:   72 |   struct B1 (virtual base) (empty)
-// CHECK:  104 |   struct B2 (virtual base) (empty)
-// CHECK:  132 |   struct D1 (virtual base) (empty)
-// CHECK:  168 |   struct B3 (virtual base) (empty)
-// CHECK:  200 |   struct B4 (virtual base) (empty)
-// CHECK:      | [sizeof=224, align=32
-// CHECK:      |  nvsize=64, nvalign=32]
+// CHECK-NEXT:    0 | struct O
+// CHECK-NEXT:    0 |   (O vbtable pointer)
+// CHECK-NEXT:   32 |   int a
+// CHECK-NEXT:   64 |   struct C0 (virtual base)
+// CHECK-NEXT:   64 |     int a
+// CHECK-NEXT:   72 |   struct B1 (virtual base) (empty)
+// CHECK-NEXT:  104 |   struct B2 (virtual base) (empty)
+// CHECK-NEXT:  132 |   struct D1 (virtual base) (empty)
+// CHECK-NEXT:  168 |   struct B3 (virtual base) (empty)
+// CHECK-NEXT:  200 |   struct B4 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=224, align=32
+// CHECK-NEXT:      |  nvsize=64, nvalign=32]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct O
-// CHECK-X64:    0 |   (O vbtable pointer)
-// CHECK-X64:   32 |   int a
-// CHECK-X64:   64 |   struct C0 (virtual base)
-// CHECK-X64:   64 |     int a
-// CHECK-X64:   72 |   struct B1 (virtual base) (empty)
-// CHECK-X64:  104 |   struct B2 (virtual base) (empty)
-// CHECK-X64:  132 |   struct D1 (virtual base) (empty)
-// CHECK-X64:  168 |   struct B3 (virtual base) (empty)
-// CHECK-X64:  200 |   struct B4 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=224, align=32
-// CHECK-X64:      |  nvsize=64, nvalign=32]
+// CHECK-X64-NEXT:    0 | struct O
+// CHECK-X64-NEXT:    0 |   (O vbtable pointer)
+// CHECK-X64-NEXT:   32 |   int a
+// CHECK-X64-NEXT:   64 |   struct C0 (virtual base)
+// CHECK-X64-NEXT:   64 |     int a
+// CHECK-X64-NEXT:   72 |   struct B1 (virtual base) (empty)
+// CHECK-X64-NEXT:  104 |   struct B2 (virtual base) (empty)
+// CHECK-X64-NEXT:  132 |   struct D1 (virtual base) (empty)
+// CHECK-X64-NEXT:  168 |   struct B3 (virtual base) (empty)
+// CHECK-X64-NEXT:  200 |   struct B4 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=224, align=32
+// CHECK-X64-NEXT:      |  nvsize=64, nvalign=32]
 
 struct P : virtual B1, virtual C0, virtual D1, virtual B2, virtual B3, virtual B4 {
 	__declspec(align(32)) int a;
@@ -479,31 +499,31 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct P
-// CHECK:    0 |   (P vbtable pointer)
-// CHECK:   32 |   int a
-// CHECK:   64 |   struct B1 (virtual base) (empty)
-// CHECK:   64 |   struct C0 (virtual base)
-// CHECK:   64 |     int a
-// CHECK:   68 |   struct D1 (virtual base) (empty)
-// CHECK:  104 |   struct B2 (virtual base) (empty)
-// CHECK:  136 |   struct B3 (virtual base) (empty)
-// CHECK:  168 |   struct B4 (virtual base) (empty)
-// CHECK:      | [sizeof=192, align=32
-// CHECK:      |  nvsize=64, nvalign=32]
+// CHECK-NEXT:    0 | struct P
+// CHECK-NEXT:    0 |   (P vbtable pointer)
+// CHECK-NEXT:   32 |   int a
+// CHECK-NEXT:   64 |   struct B1 (virtual base) (empty)
+// CHECK-NEXT:   64 |   struct C0 (virtual base)
+// CHECK-NEXT:   64 |     int a
+// CHECK-NEXT:   68 |   struct D1 (virtual base) (empty)
+// CHECK-NEXT:  104 |   struct B2 (virtual base) (empty)
+// CHECK-NEXT:  136 |   struct B3 (virtual base) (empty)
+// CHECK-NEXT:  168 |   struct B4 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=192, align=32
+// CHECK-NEXT:      |  nvsize=64, nvalign=32]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct P
-// CHECK-X64:    0 |   (P vbtable pointer)
-// CHECK-X64:   32 |   int a
-// CHECK-X64:   64 |   struct B1 (virtual base) (empty)
-// CHECK-X64:   64 |   struct C0 (virtual base)
-// CHECK-X64:   64 |     int a
-// CHECK-X64:   68 |   struct D1 (virtual base) (empty)
-// CHECK-X64:  104 |   struct B2 (virtual base) (empty)
-// CHECK-X64:  136 |   struct B3 (virtual base) (empty)
-// CHECK-X64:  168 |   struct B4 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=192, align=32
-// CHECK-X64:      |  nvsize=64, nvalign=32]
+// CHECK-X64-NEXT:    0 | struct P
+// CHECK-X64-NEXT:    0 |   (P vbtable pointer)
+// CHECK-X64-NEXT:   32 |   int a
+// CHECK-X64-NEXT:   64 |   struct B1 (virtual base) (empty)
+// CHECK-X64-NEXT:   64 |   struct C0 (virtual base)
+// CHECK-X64-NEXT:   64 |     int a
+// CHECK-X64-NEXT:   68 |   struct D1 (virtual base) (empty)
+// CHECK-X64-NEXT:  104 |   struct B2 (virtual base) (empty)
+// CHECK-X64-NEXT:  136 |   struct B3 (virtual base) (empty)
+// CHECK-X64-NEXT:  168 |   struct B4 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=192, align=32
+// CHECK-X64-NEXT:      |  nvsize=64, nvalign=32]
 
 struct Q : virtual B1, virtual C0, virtual B2, virtual D1, virtual B3, virtual B4 {
 	__declspec(align(32)) int a;
@@ -511,31 +531,31 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct Q
-// CHECK:    0 |   (Q vbtable pointer)
-// CHECK:   32 |   int a
-// CHECK:   64 |   struct B1 (virtual base) (empty)
-// CHECK:   64 |   struct C0 (virtual base)
-// CHECK:   64 |     int a
-// CHECK:   72 |   struct B2 (virtual base) (empty)
-// CHECK:  100 |   struct D1 (virtual base) (empty)
-// CHECK:  136 |   struct B3 (virtual base) (empty)
-// CHECK:  168 |   struct B4 (virtual base) (empty)
-// CHECK:      | [sizeof=192, align=32
-// CHECK:      |  nvsize=64, nvalign=32]
+// CHECK-NEXT:    0 | struct Q
+// CHECK-NEXT:    0 |   (Q vbtable pointer)
+// CHECK-NEXT:   32 |   int a
+// CHECK-NEXT:   64 |   struct B1 (virtual base) (empty)
+// CHECK-NEXT:   64 |   struct C0 (virtual base)
+// CHECK-NEXT:   64 |     int a
+// CHECK-NEXT:   72 |   struct B2 (virtual base) (empty)
+// CHECK-NEXT:  100 |   struct D1 (virtual base) (empty)
+// CHECK-NEXT:  136 |   struct B3 (virtual base) (empty)
+// CHECK-NEXT:  168 |   struct B4 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=192, align=32
+// CHECK-NEXT:      |  nvsize=64, nvalign=32]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct Q
-// CHECK-X64:    0 |   (Q vbtable pointer)
-// CHECK-X64:   32 |   int a
-// CHECK-X64:   64 |   struct B1 (virtual base) (empty)
-// CHECK-X64:   64 |   struct C0 (virtual base)
-// CHECK-X64:   64 |     int a
-// CHECK-X64:   72 |   struct B2 (virtual base) (empty)
-// CHECK-X64:  100 |   struct D1 (virtual base) (empty)
-// CHECK-X64:  136 |   struct B3 (virtual base) (empty)
-// CHECK-X64:  168 |   struct B4 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=192, align=32
-// CHECK-X64:      |  nvsize=64, nvalign=32]
+// CHECK-X64-NEXT:    0 | struct Q
+// CHECK-X64-NEXT:    0 |   (Q vbtable pointer)
+// CHECK-X64-NEXT:   32 |   int a
+// CHECK-X64-NEXT:   64 |   struct B1 (virtual base) (empty)
+// CHECK-X64-NEXT:   64 |   struct C0 (virtual base)
+// CHECK-X64-NEXT:   64 |     int a
+// CHECK-X64-NEXT:   72 |   struct B2 (virtual base) (empty)
+// CHECK-X64-NEXT:  100 |   struct D1 (virtual base) (empty)
+// CHECK-X64-NEXT:  136 |   struct B3 (virtual base) (empty)
+// CHECK-X64-NEXT:  168 |   struct B4 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=192, align=32
+// CHECK-X64-NEXT:      |  nvsize=64, nvalign=32]
 
 struct R : virtual B0, virtual B1, virtual B2, virtual C0, virtual B3, virtual B4 {
 	__declspec(align(32)) int a;
@@ -543,31 +563,31 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct R
-// CHECK:    0 |   (R vbtable pointer)
-// CHECK:   32 |   int a
-// CHECK:   64 |   struct B0 (virtual base) (empty)
-// CHECK:   72 |   struct B1 (virtual base) (empty)
-// CHECK:  104 |   struct B2 (virtual base) (empty)
-// CHECK:  104 |   struct C0 (virtual base)
-// CHECK:  104 |     int a
-// CHECK:  112 |   struct B3 (virtual base) (empty)
-// CHECK:  136 |   struct B4 (virtual base) (empty)
-// CHECK:      | [sizeof=160, align=32
-// CHECK:      |  nvsize=64, nvalign=32]
+// CHECK-NEXT:    0 | struct R
+// CHECK-NEXT:    0 |   (R vbtable pointer)
+// CHECK-NEXT:   32 |   int a
+// CHECK-NEXT:   64 |   struct B0 (virtual base) (empty)
+// CHECK-NEXT:   72 |   struct B1 (virtual base) (empty)
+// CHECK-NEXT:  104 |   struct B2 (virtual base) (empty)
+// CHECK-NEXT:  104 |   struct C0 (virtual base)
+// CHECK-NEXT:  104 |     int a
+// CHECK-NEXT:  112 |   struct B3 (virtual base) (empty)
+// CHECK-NEXT:  136 |   struct B4 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=160, align=32
+// CHECK-NEXT:      |  nvsize=64, nvalign=32]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct R
-// CHECK-X64:    0 |   (R vbtable pointer)
-// CHECK-X64:   32 |   int a
-// CHECK-X64:   64 |   struct B0 (virtual base) (empty)
-// CHECK-X64:   72 |   struct B1 (virtual base) (empty)
-// CHECK-X64:  104 |   struct B2 (virtual base) (empty)
-// CHECK-X64:  104 |   struct C0 (virtual base)
-// CHECK-X64:  104 |     int a
-// CHECK-X64:  112 |   struct B3 (virtual base) (empty)
-// CHECK-X64:  136 |   struct B4 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=160, align=32
-// CHECK-X64:      |  nvsize=64, nvalign=32]
+// CHECK-X64-NEXT:    0 | struct R
+// CHECK-X64-NEXT:    0 |   (R vbtable pointer)
+// CHECK-X64-NEXT:   32 |   int a
+// CHECK-X64-NEXT:   64 |   struct B0 (virtual base) (empty)
+// CHECK-X64-NEXT:   72 |   struct B1 (virtual base) (empty)
+// CHECK-X64-NEXT:  104 |   struct B2 (virtual base) (empty)
+// CHECK-X64-NEXT:  104 |   struct C0 (virtual base)
+// CHECK-X64-NEXT:  104 |     int a
+// CHECK-X64-NEXT:  112 |   struct B3 (virtual base) (empty)
+// CHECK-X64-NEXT:  136 |   struct B4 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=160, align=32
+// CHECK-X64-NEXT:      |  nvsize=64, nvalign=32]
 
 struct S : virtual B0, virtual B1, virtual C0, virtual B2, virtual B3, virtual B4 {
 	__declspec(align(32)) int a;
@@ -575,31 +595,31 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct S
-// CHECK:    0 |   (S vbtable pointer)
-// CHECK:   32 |   int a
-// CHECK:   64 |   struct B0 (virtual base) (empty)
-// CHECK:   72 |   struct B1 (virtual base) (empty)
-// CHECK:   72 |   struct C0 (virtual base)
-// CHECK:   72 |     int a
-// CHECK:   80 |   struct B2 (virtual base) (empty)
-// CHECK:  104 |   struct B3 (virtual base) (empty)
-// CHECK:  136 |   struct B4 (virtual base) (empty)
-// CHECK:      | [sizeof=160, align=32
-// CHECK:      |  nvsize=64, nvalign=32]
+// CHECK-NEXT:    0 | struct S
+// CHECK-NEXT:    0 |   (S vbtable pointer)
+// CHECK-NEXT:   32 |   int a
+// CHECK-NEXT:   64 |   struct B0 (virtual base) (empty)
+// CHECK-NEXT:   72 |   struct B1 (virtual base) (empty)
+// CHECK-NEXT:   72 |   struct C0 (virtual base)
+// CHECK-NEXT:   72 |     int a
+// CHECK-NEXT:   80 |   struct B2 (virtual base) (empty)
+// CHECK-NEXT:  104 |   struct B3 (virtual base) (empty)
+// CHECK-NEXT:  136 |   struct B4 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=160, align=32
+// CHECK-NEXT:      |  nvsize=64, nvalign=32]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct S
-// CHECK-X64:    0 |   (S vbtable pointer)
-// CHECK-X64:   32 |   int a
-// CHECK-X64:   64 |   struct B0 (virtual base) (empty)
-// CHECK-X64:   72 |   struct B1 (virtual base) (empty)
-// CHECK-X64:   72 |   struct C0 (virtual base)
-// CHECK-X64:   72 |     int a
-// CHECK-X64:   80 |   struct B2 (virtual base) (empty)
-// CHECK-X64:  104 |   struct B3 (virtual base) (empty)
-// CHECK-X64:  136 |   struct B4 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=160, align=32
-// CHECK-X64:      |  nvsize=64, nvalign=32]
+// CHECK-X64-NEXT:    0 | struct S
+// CHECK-X64-NEXT:    0 |   (S vbtable pointer)
+// CHECK-X64-NEXT:   32 |   int a
+// CHECK-X64-NEXT:   64 |   struct B0 (virtual base) (empty)
+// CHECK-X64-NEXT:   72 |   struct B1 (virtual base) (empty)
+// CHECK-X64-NEXT:   72 |   struct C0 (virtual base)
+// CHECK-X64-NEXT:   72 |     int a
+// CHECK-X64-NEXT:   80 |   struct B2 (virtual base) (empty)
+// CHECK-X64-NEXT:  104 |   struct B3 (virtual base) (empty)
+// CHECK-X64-NEXT:  136 |   struct B4 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=160, align=32
+// CHECK-X64-NEXT:      |  nvsize=64, nvalign=32]
 
 struct T : virtual B0, virtual B1, virtual C0, virtual D2, virtual B2, virtual B3, virtual B4 {
 	__declspec(align(16)) int a;
@@ -607,35 +627,37 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct T
-// CHECK:    0 |   (T vbtable pointer)
-// CHECK:   16 |   int a
-// CHECK:   32 |   struct B0 (virtual base) (empty)
-// CHECK:   40 |   struct B1 (virtual base) (empty)
-// CHECK:   40 |   struct C0 (virtual base)
-// CHECK:   40 |     int a
-// CHECK:   44 |   struct D2 (virtual base)
-// CHECK:   44 |     int [8] a
-// CHECK:   80 |   struct B2 (virtual base) (empty)
-// CHECK:   88 |   struct B3 (virtual base) (empty)
-// CHECK:  104 |   struct B4 (virtual base) (empty)
-// CHECK:      | [sizeof=112, align=16
-// CHECK:      |  nvsize=32, nvalign=16]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct T
+// CHECK-NEXT:    0 |   (T vbtable pointer)
+// CHECK-NEXT:   16 |   int a
+// CHECK-NEXT:   32 |   struct B0 (virtual base) (empty)
+// CHECK-NEXT:   40 |   struct B1 (virtual base) (empty)
+// CHECK-NEXT:   40 |   struct C0 (virtual base)
+// CHECK-NEXT:   40 |     int a
+// CHECK-NEXT:   44 |   struct D2 (virtual base)
+// CHECK-NEXT:   44 |     int [8] a
+// CHECK-NEXT:   80 |   struct B2 (virtual base) (empty)
+// CHECK-NEXT:   88 |   struct B3 (virtual base) (empty)
+// CHECK-NEXT:  104 |   struct B4 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=112, align=16
+// CHECK-NEXT:      |  nvsize=32, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct T
-// CHECK-X64:    0 |   (T vbtable pointer)
-// CHECK-X64:   16 |   int a
-// CHECK-X64:   32 |   struct B0 (virtual base) (empty)
-// CHECK-X64:   40 |   struct B1 (virtual base) (empty)
-// CHECK-X64:   40 |   struct C0 (virtual base)
-// CHECK-X64:   40 |     int a
-// CHECK-X64:   44 |   struct D2 (virtual base)
-// CHECK-X64:   44 |     int [8] a
-// CHECK-X64:   80 |   struct B2 (virtual base) (empty)
-// CHECK-X64:   88 |   struct B3 (virtual base) (empty)
-// CHECK-X64:  104 |   struct B4 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=112, align=16
-// CHECK-X64:      |  nvsize=32, nvalign=16]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct T
+// CHECK-X64-NEXT:    0 |   (T vbtable pointer)
+// CHECK-X64-NEXT:   16 |   int a
+// CHECK-X64-NEXT:   32 |   struct B0 (virtual base) (empty)
+// CHECK-X64-NEXT:   40 |   struct B1 (virtual base) (empty)
+// CHECK-X64-NEXT:   40 |   struct C0 (virtual base)
+// CHECK-X64-NEXT:   40 |     int a
+// CHECK-X64-NEXT:   44 |   struct D2 (virtual base)
+// CHECK-X64-NEXT:   44 |     int [8] a
+// CHECK-X64-NEXT:   80 |   struct B2 (virtual base) (empty)
+// CHECK-X64-NEXT:   88 |   struct B3 (virtual base) (empty)
+// CHECK-X64-NEXT:  104 |   struct B4 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=112, align=16
+// CHECK-X64-NEXT:      |  nvsize=32, nvalign=16]
 
 struct __declspec(align(32)) U : virtual B0, virtual B1 {
 	int a;
@@ -643,21 +665,21 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct U
-// CHECK:    0 |   (U vbtable pointer)
-// CHECK:    4 |   int a
-// CHECK:    8 |   struct B0 (virtual base) (empty)
-// CHECK:   40 |   struct B1 (virtual base) (empty)
-// CHECK:      | [sizeof=64, align=32
-// CHECK:      |  nvsize=8, nvalign=4]
+// CHECK-NEXT:    0 | struct U
+// CHECK-NEXT:    0 |   (U vbtable pointer)
+// CHECK-NEXT:    4 |   int a
+// CHECK-NEXT:    8 |   struct B0 (virtual base) (empty)
+// CHECK-NEXT:   40 |   struct B1 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=64, align=32
+// CHECK-NEXT:      |  nvsize=8, nvalign=32]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct U
-// CHECK-X64:    0 |   (U vbtable pointer)
-// CHECK-X64:    8 |   int a
-// CHECK-X64:   16 |   struct B0 (virtual base) (empty)
-// CHECK-X64:   40 |   struct B1 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=64, align=32
-// CHECK-X64:      |  nvsize=16, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct U
+// CHECK-X64-NEXT:    0 |   (U vbtable pointer)
+// CHECK-X64-NEXT:    8 |   int a
+// CHECK-X64-NEXT:   16 |   struct B0 (virtual base) (empty)
+// CHECK-X64-NEXT:   40 |   struct B1 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=64, align=32
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=32]
 
 struct __declspec(align(32)) V : virtual D1 {
 	int a;
@@ -665,19 +687,82 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct V
-// CHECK:    0 |   (V vbtable pointer)
-// CHECK:    4 |   int a
-// CHECK:    8 |   struct D1 (virtual base) (empty)
-// CHECK:      | [sizeof=32, align=32
-// CHECK:      |  nvsize=8, nvalign=4]
+// CHECK-NEXT:    0 | struct V
+// CHECK-NEXT:    0 |   (V vbtable pointer)
+// CHECK-NEXT:    4 |   int a
+// CHECK-NEXT:    8 |   struct D1 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=32, align=32
+// CHECK-NEXT:      |  nvsize=8, nvalign=32]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct V
-// CHECK-X64:    0 |   (V vbtable pointer)
-// CHECK-X64:    8 |   int a
-// CHECK-X64:   16 |   struct D1 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=32, align=32
-// CHECK-X64:      |  nvsize=16, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct V
+// CHECK-X64-NEXT:    0 |   (V vbtable pointer)
+// CHECK-X64-NEXT:    8 |   int a
+// CHECK-X64-NEXT:   16 |   struct D1 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=32, align=32
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=32]
+
+struct T0 {};
+struct T1 : T0 { char a; };
+struct T3 : virtual T1, virtual T0 { long long a; };
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct T3
+// CHECK-NEXT:    0 |   (T3 vbtable pointer)
+// CHECK-NEXT:    8 |   long long a
+// CHECK-NEXT:   16 |   struct T1 (virtual base)
+// CHECK-NEXT:   16 |     struct T0 (base) (empty)
+// CHECK-NEXT:   16 |     char a
+// CHECK-NEXT:   24 |   struct T0 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=24, align=8
+// CHECK-NEXT:      |  nvsize=16, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct T3
+// CHECK-X64-NEXT:    0 |   (T3 vbtable pointer)
+// CHECK-X64-NEXT:    8 |   long long a
+// CHECK-X64-NEXT:   16 |   struct T1 (virtual base)
+// CHECK-X64-NEXT:   16 |     struct T0 (base) (empty)
+// CHECK-X64-NEXT:   16 |     char a
+// CHECK-X64-NEXT:   24 |   struct T0 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
+
+struct Q0A {};
+struct Q0B { char Q0BField; };
+struct Q0C : virtual Q0A, virtual Q0B { char Q0CField; };
+struct Q0D : Q0C, Q0A {};
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct Q0D
+// CHECK-NEXT:    0 |   struct Q0C (base)
+// CHECK-NEXT:    0 |     (Q0C vbtable pointer)
+// CHECK-NEXT:    4 |     char Q0CField
+// CHECK-NEXT:    8 |   struct Q0A (base) (empty)
+// CHECK-NEXT:    8 |   struct Q0A (virtual base) (empty)
+// CHECK-NEXT:    8 |   struct Q0B (virtual base)
+// CHECK-NEXT:    8 |     char Q0BField
+// CHECK-NEXT:      | [sizeof=9, align=4
+// CHECK-NEXT:      |  nvsize=8, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct Q0D
+// CHECK-X64-NEXT:    0 |   struct Q0C (base)
+// CHECK-X64-NEXT:    0 |     (Q0C vbtable pointer)
+// CHECK-X64-NEXT:    8 |     char Q0CField
+// CHECK-X64-NEXT:   16 |   struct Q0A (base) (empty)
+// CHECK-X64-NEXT:   16 |   struct Q0A (virtual base) (empty)
+// CHECK-X64-NEXT:   16 |   struct Q0B (virtual base)
+// CHECK-X64-NEXT:   16 |     char Q0BField
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
 
 int a[
 sizeof(A)+
@@ -701,4 +786,6 @@
 sizeof(S)+
 sizeof(T)+
 sizeof(U)+
-sizeof(V)];
\ No newline at end of file
+sizeof(V)+
+sizeof(T3)+
+sizeof(Q0D)];
diff --git a/test/Layout/ms-x86-lazy-empty-nonvirtual-base.cpp b/test/Layout/ms-x86-lazy-empty-nonvirtual-base.cpp
index 7dd3fad..34ae0cf 100644
--- a/test/Layout/ms-x86-lazy-empty-nonvirtual-base.cpp
+++ b/test/Layout/ms-x86-lazy-empty-nonvirtual-base.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>/dev/null \
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>/dev/null \
 // RUN:            | FileCheck %s
-// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>/dev/null \
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>/dev/null \
 // RUN:            | FileCheck %s -check-prefix CHECK-X64
 
 extern "C" int printf(const char *fmt, ...);
@@ -24,687 +24,786 @@
 struct B4X { B4X() { printf("B4 = %p\n", this); } };
 struct B5X { B5X() { printf("B5 = %p\n", this); } };
 struct B6X { B6X() { printf("B6 = %p\n", this); } };
-struct B8X { short a; B8X() : a(0xf00000B8) { printf("B8 = %p\n", this); } };
+struct B8X { short a; B8X() : a(0x000000B8) { printf("B8 = %p\n", this); } };
 
 struct AA : B8, B1, virtual B0 {
 	int a;
-	AA() : a(0xf00000AA) { printf("AA = %p\n", this); }
+	AA() : a(0x000000AA) { printf("AA = %p\n", this); }
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct AA
-// CHECK:    0 |   struct B8 (base)
-// CHECK:    0 |     char [5] c
-// CHECK:   13 |   struct B1 (base) (empty)
-// CHECK:    8 |   (AA vbtable pointer)
-// CHECK:   16 |   int a
-// CHECK:   20 |   struct B0 (virtual base) (empty)
-// CHECK:      | [sizeof=20, align=4
-// CHECK:      |  nvsize=20, nvalign=4]
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct AA
+// CHECK-NEXT:    0 |   struct B8 (base)
+// CHECK-NEXT:    0 |     char [5] c
+// CHECK-NEXT:   13 |   struct B1 (base) (empty)
+// CHECK-NEXT:    8 |   (AA vbtable pointer)
+// CHECK-NEXT:   16 |   int a
+// CHECK-NEXT:   20 |   struct B0 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=20, align=4
+// CHECK-NEXT:      |  nvsize=20, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct AA
-// CHECK-X64:    0 |   struct B8 (base)
-// CHECK-X64:    0 |     char [5] c
-// CHECK-X64:   17 |   struct B1 (base) (empty)
-// CHECK-X64:    8 |   (AA vbtable pointer)
-// CHECK-X64:   20 |   int a
-// CHECK-X64:   24 |   struct B0 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=24, align=8
-// CHECK-X64:      |  nvsize=24, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct AA
+// CHECK-X64-NEXT:    0 |   struct B8 (base)
+// CHECK-X64-NEXT:    0 |     char [5] c
+// CHECK-X64-NEXT:   17 |   struct B1 (base) (empty)
+// CHECK-X64-NEXT:    8 |   (AA vbtable pointer)
+// CHECK-X64-NEXT:   20 |   int a
+// CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
 
 struct AB : B8, B1, virtual B0 {
 	short a;
-	AB() : a(0xf00000AB) { printf("AB = %p\n", this); }
+	AB() : a(0x000000AB) { printf("AB = %p\n", this); }
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct AB
-// CHECK:    0 |   struct B8 (base)
-// CHECK:    0 |     char [5] c
-// CHECK:   13 |   struct B1 (base) (empty)
-// CHECK:    8 |   (AB vbtable pointer)
-// CHECK:   14 |   short a
-// CHECK:   16 |   struct B0 (virtual base) (empty)
-// CHECK:      | [sizeof=16, align=4
-// CHECK:      |  nvsize=16, nvalign=4]
+// CHECK-NEXT:    0 | struct AB
+// CHECK-NEXT:    0 |   struct B8 (base)
+// CHECK-NEXT:    0 |     char [5] c
+// CHECK-NEXT:   13 |   struct B1 (base) (empty)
+// CHECK-NEXT:    8 |   (AB vbtable pointer)
+// CHECK-NEXT:   14 |   short a
+// CHECK-NEXT:   16 |   struct B0 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=16, align=4
+// CHECK-NEXT:      |  nvsize=16, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct AB
-// CHECK-X64:    0 |   struct B8 (base)
-// CHECK-X64:    0 |     char [5] c
-// CHECK-X64:   17 |   struct B1 (base) (empty)
-// CHECK-X64:    8 |   (AB vbtable pointer)
-// CHECK-X64:   18 |   short a
-// CHECK-X64:   24 |   struct B0 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=24, align=8
-// CHECK-X64:      |  nvsize=24, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct AB
+// CHECK-X64-NEXT:    0 |   struct B8 (base)
+// CHECK-X64-NEXT:    0 |     char [5] c
+// CHECK-X64-NEXT:   17 |   struct B1 (base) (empty)
+// CHECK-X64-NEXT:    8 |   (AB vbtable pointer)
+// CHECK-X64-NEXT:   18 |   short a
+// CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
 
 struct AC : B8, B1, virtual B0 {
 	char a;
-	AC() : a(0xf00000AC) { printf("AC = %p\n", this); }
+	AC() : a(0x000000AC) { printf("AC = %p\n", this); }
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct AC
-// CHECK:    0 |   struct B8 (base)
-// CHECK:    0 |     char [5] c
-// CHECK:   12 |   struct B1 (base) (empty)
-// CHECK:    8 |   (AC vbtable pointer)
-// CHECK:   12 |   char a
-// CHECK:   16 |   struct B0 (virtual base) (empty)
-// CHECK:      | [sizeof=16, align=4
-// CHECK:      |  nvsize=16, nvalign=4]
+// CHECK-NEXT:    0 | struct AC
+// CHECK-NEXT:    0 |   struct B8 (base)
+// CHECK-NEXT:    0 |     char [5] c
+// CHECK-NEXT:   12 |   struct B1 (base) (empty)
+// CHECK-NEXT:    8 |   (AC vbtable pointer)
+// CHECK-NEXT:   12 |   char a
+// CHECK-NEXT:   16 |   struct B0 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=16, align=4
+// CHECK-NEXT:      |  nvsize=16, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct AC
-// CHECK-X64:    0 |   struct B8 (base)
-// CHECK-X64:    0 |     char [5] c
-// CHECK-X64:   16 |   struct B1 (base) (empty)
-// CHECK-X64:    8 |   (AC vbtable pointer)
-// CHECK-X64:   16 |   char a
-// CHECK-X64:   24 |   struct B0 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=24, align=8
-// CHECK-X64:      |  nvsize=24, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct AC
+// CHECK-X64-NEXT:    0 |   struct B8 (base)
+// CHECK-X64-NEXT:    0 |     char [5] c
+// CHECK-X64-NEXT:   16 |   struct B1 (base) (empty)
+// CHECK-X64-NEXT:    8 |   (AC vbtable pointer)
+// CHECK-X64-NEXT:   16 |   char a
+// CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
 
 struct AD : B8, B1, virtual B0 {
 	AD() { printf("AD = %p\n", this); }
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct AD
-// CHECK:    0 |   struct B8 (base)
-// CHECK:    0 |     char [5] c
-// CHECK:   12 |   struct B1 (base) (empty)
-// CHECK:    8 |   (AD vbtable pointer)
-// CHECK:   12 |   struct B0 (virtual base) (empty)
-// CHECK:      | [sizeof=12, align=4
-// CHECK:      |  nvsize=12, nvalign=4]
+// CHECK-NEXT:    0 | struct AD
+// CHECK-NEXT:    0 |   struct B8 (base)
+// CHECK-NEXT:    0 |     char [5] c
+// CHECK-NEXT:   12 |   struct B1 (base) (empty)
+// CHECK-NEXT:    8 |   (AD vbtable pointer)
+// CHECK-NEXT:   12 |   struct B0 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=12, align=4
+// CHECK-NEXT:      |  nvsize=12, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct AD
-// CHECK-X64:    0 |   struct B8 (base)
-// CHECK-X64:    0 |     char [5] c
-// CHECK-X64:   16 |   struct B1 (base) (empty)
-// CHECK-X64:    8 |   (AD vbtable pointer)
-// CHECK-X64:   16 |   struct B0 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=16, align=8
-// CHECK-X64:      |  nvsize=16, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct AD
+// CHECK-X64-NEXT:    0 |   struct B8 (base)
+// CHECK-X64-NEXT:    0 |     char [5] c
+// CHECK-X64-NEXT:   16 |   struct B1 (base) (empty)
+// CHECK-X64-NEXT:    8 |   (AD vbtable pointer)
+// CHECK-X64-NEXT:   16 |   struct B0 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=16, align=8
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
 
 struct AA1 : B9, B1, virtual B0 {
 	int a;
-	AA1() : a(0xf0000AA1) { printf("AA1 = %p\n", this); }
+	AA1() : a(0x00000AA1) { printf("AA1 = %p\n", this); }
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct AA1
-// CHECK:    0 |   struct B9 (base)
-// CHECK:    0 |     char [6] c
-// CHECK:   14 |   struct B1 (base) (empty)
-// CHECK:    8 |   (AA1 vbtable pointer)
-// CHECK:   16 |   int a
-// CHECK:   20 |   struct B0 (virtual base) (empty)
-// CHECK:      | [sizeof=20, align=4
-// CHECK:      |  nvsize=20, nvalign=4]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct AA1
+// CHECK-NEXT:    0 |   struct B9 (base)
+// CHECK-NEXT:    0 |     char [6] c
+// CHECK-NEXT:   14 |   struct B1 (base) (empty)
+// CHECK-NEXT:    8 |   (AA1 vbtable pointer)
+// CHECK-NEXT:   16 |   int a
+// CHECK-NEXT:   20 |   struct B0 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=20, align=4
+// CHECK-NEXT:      |  nvsize=20, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct AA1
-// CHECK-X64:    0 |   struct B9 (base)
-// CHECK-X64:    0 |     char [6] c
-// CHECK-X64:   18 |   struct B1 (base) (empty)
-// CHECK-X64:    8 |   (AA1 vbtable pointer)
-// CHECK-X64:   20 |   int a
-// CHECK-X64:   24 |   struct B0 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=24, align=8
-// CHECK-X64:      |  nvsize=24, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct AA1
+// CHECK-X64-NEXT:    0 |   struct B9 (base)
+// CHECK-X64-NEXT:    0 |     char [6] c
+// CHECK-X64-NEXT:   18 |   struct B1 (base) (empty)
+// CHECK-X64-NEXT:    8 |   (AA1 vbtable pointer)
+// CHECK-X64-NEXT:   20 |   int a
+// CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
 
 struct AB1 : B9, B1, virtual B0 {
 	short a;
-	AB1() : a(0xf0000AB1) { printf("AB1 = %p\n", this); }
+	AB1() : a(0x00000AB1) { printf("AB1 = %p\n", this); }
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct AB1
-// CHECK:    0 |   struct B9 (base)
-// CHECK:    0 |     char [6] c
-// CHECK:   12 |   struct B1 (base) (empty)
-// CHECK:    8 |   (AB1 vbtable pointer)
-// CHECK:   12 |   short a
-// CHECK:   16 |   struct B0 (virtual base) (empty)
-// CHECK:      | [sizeof=16, align=4
-// CHECK:      |  nvsize=16, nvalign=4]
+// CHECK-NEXT:    0 | struct AB1
+// CHECK-NEXT:    0 |   struct B9 (base)
+// CHECK-NEXT:    0 |     char [6] c
+// CHECK-NEXT:   12 |   struct B1 (base) (empty)
+// CHECK-NEXT:    8 |   (AB1 vbtable pointer)
+// CHECK-NEXT:   12 |   short a
+// CHECK-NEXT:   16 |   struct B0 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=16, align=4
+// CHECK-NEXT:      |  nvsize=16, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct AB1
-// CHECK-X64:    0 |   struct B9 (base)
-// CHECK-X64:    0 |     char [6] c
-// CHECK-X64:   16 |   struct B1 (base) (empty)
-// CHECK-X64:    8 |   (AB1 vbtable pointer)
-// CHECK-X64:   16 |   short a
-// CHECK-X64:   24 |   struct B0 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=24, align=8
-// CHECK-X64:      |  nvsize=24, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct AB1
+// CHECK-X64-NEXT:    0 |   struct B9 (base)
+// CHECK-X64-NEXT:    0 |     char [6] c
+// CHECK-X64-NEXT:   16 |   struct B1 (base) (empty)
+// CHECK-X64-NEXT:    8 |   (AB1 vbtable pointer)
+// CHECK-X64-NEXT:   16 |   short a
+// CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
 
 struct AC1 : B9, B1, virtual B0 {
 	char a;
-	AC1() : a(0xf0000AC1) { printf("AC1 = %p\n", this); }
+	AC1() : a(0x000000C1) { printf("AC1 = %p\n", this); }
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct AC1
-// CHECK:    0 |   struct B9 (base)
-// CHECK:    0 |     char [6] c
-// CHECK:   12 |   struct B1 (base) (empty)
-// CHECK:    8 |   (AC1 vbtable pointer)
-// CHECK:   12 |   char a
-// CHECK:   16 |   struct B0 (virtual base) (empty)
-// CHECK:      | [sizeof=16, align=4
-// CHECK:      |  nvsize=16, nvalign=4]
+// CHECK-NEXT:    0 | struct AC1
+// CHECK-NEXT:    0 |   struct B9 (base)
+// CHECK-NEXT:    0 |     char [6] c
+// CHECK-NEXT:   12 |   struct B1 (base) (empty)
+// CHECK-NEXT:    8 |   (AC1 vbtable pointer)
+// CHECK-NEXT:   12 |   char a
+// CHECK-NEXT:   16 |   struct B0 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=16, align=4
+// CHECK-NEXT:      |  nvsize=16, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct AC1
-// CHECK-X64:    0 |   struct B9 (base)
-// CHECK-X64:    0 |     char [6] c
-// CHECK-X64:   16 |   struct B1 (base) (empty)
-// CHECK-X64:    8 |   (AC1 vbtable pointer)
-// CHECK-X64:   16 |   char a
-// CHECK-X64:   24 |   struct B0 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=24, align=8
-// CHECK-X64:      |  nvsize=24, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct AC1
+// CHECK-X64-NEXT:    0 |   struct B9 (base)
+// CHECK-X64-NEXT:    0 |     char [6] c
+// CHECK-X64-NEXT:   16 |   struct B1 (base) (empty)
+// CHECK-X64-NEXT:    8 |   (AC1 vbtable pointer)
+// CHECK-X64-NEXT:   16 |   char a
+// CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
 
 struct AD1 : B9, B1, virtual B0 {
 	AD1() { printf("AD1 = %p\n", this); }
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct AD1
-// CHECK:    0 |   struct B9 (base)
-// CHECK:    0 |     char [6] c
-// CHECK:   12 |   struct B1 (base) (empty)
-// CHECK:    8 |   (AD1 vbtable pointer)
-// CHECK:   12 |   struct B0 (virtual base) (empty)
-// CHECK:      | [sizeof=12, align=4
-// CHECK:      |  nvsize=12, nvalign=4]
+// CHECK-NEXT:    0 | struct AD1
+// CHECK-NEXT:    0 |   struct B9 (base)
+// CHECK-NEXT:    0 |     char [6] c
+// CHECK-NEXT:   12 |   struct B1 (base) (empty)
+// CHECK-NEXT:    8 |   (AD1 vbtable pointer)
+// CHECK-NEXT:   12 |   struct B0 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=12, align=4
+// CHECK-NEXT:      |  nvsize=12, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct AD1
-// CHECK-X64:    0 |   struct B9 (base)
-// CHECK-X64:    0 |     char [6] c
-// CHECK-X64:   16 |   struct B1 (base) (empty)
-// CHECK-X64:    8 |   (AD1 vbtable pointer)
-// CHECK-X64:   16 |   struct B0 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=16, align=8
-// CHECK-X64:      |  nvsize=16, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct AD1
+// CHECK-X64-NEXT:    0 |   struct B9 (base)
+// CHECK-X64-NEXT:    0 |     char [6] c
+// CHECK-X64-NEXT:   16 |   struct B1 (base) (empty)
+// CHECK-X64-NEXT:    8 |   (AD1 vbtable pointer)
+// CHECK-X64-NEXT:   16 |   struct B0 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=16, align=8
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
 
 struct AA2 : B10, B1, virtual B0 {
 	int a;
-	AA2() : a(0xf0000AA2) { printf("AA2 = %p\n", this); }
+	AA2() : a(0x00000AA2) { printf("AA2 = %p\n", this); }
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct AA2
-// CHECK:    0 |   struct B10 (base)
-// CHECK:    0 |     char [7] c
-// CHECK:   15 |   struct B1 (base) (empty)
-// CHECK:    8 |   (AA2 vbtable pointer)
-// CHECK:   16 |   int a
-// CHECK:   20 |   struct B0 (virtual base) (empty)
-// CHECK:      | [sizeof=20, align=4
-// CHECK:      |  nvsize=20, nvalign=4]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct AA2
+// CHECK-NEXT:    0 |   struct B10 (base)
+// CHECK-NEXT:    0 |     char [7] c
+// CHECK-NEXT:   15 |   struct B1 (base) (empty)
+// CHECK-NEXT:    8 |   (AA2 vbtable pointer)
+// CHECK-NEXT:   16 |   int a
+// CHECK-NEXT:   20 |   struct B0 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=20, align=4
+// CHECK-NEXT:      |  nvsize=20, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct AA2
-// CHECK-X64:    0 |   struct B10 (base)
-// CHECK-X64:    0 |     char [7] c
-// CHECK-X64:   19 |   struct B1 (base) (empty)
-// CHECK-X64:    8 |   (AA2 vbtable pointer)
-// CHECK-X64:   20 |   int a
-// CHECK-X64:   24 |   struct B0 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=24, align=8
-// CHECK-X64:      |  nvsize=24, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct AA2
+// CHECK-X64-NEXT:    0 |   struct B10 (base)
+// CHECK-X64-NEXT:    0 |     char [7] c
+// CHECK-X64-NEXT:   19 |   struct B1 (base) (empty)
+// CHECK-X64-NEXT:    8 |   (AA2 vbtable pointer)
+// CHECK-X64-NEXT:   20 |   int a
+// CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
 
 struct AB2 : B10, B1, virtual B0 {
 	short a;
-	AB2() : a(0xf0000AB2) { printf("AB2 = %p\n", this); }
+	AB2() : a(0x00000AB2) { printf("AB2 = %p\n", this); }
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct AB2
-// CHECK:    0 |   struct B10 (base)
-// CHECK:    0 |     char [7] c
-// CHECK:   13 |   struct B1 (base) (empty)
-// CHECK:    8 |   (AB2 vbtable pointer)
-// CHECK:   14 |   short a
-// CHECK:   16 |   struct B0 (virtual base) (empty)
-// CHECK:      | [sizeof=16, align=4
-// CHECK:      |  nvsize=16, nvalign=4]
+// CHECK-NEXT:    0 | struct AB2
+// CHECK-NEXT:    0 |   struct B10 (base)
+// CHECK-NEXT:    0 |     char [7] c
+// CHECK-NEXT:   13 |   struct B1 (base) (empty)
+// CHECK-NEXT:    8 |   (AB2 vbtable pointer)
+// CHECK-NEXT:   14 |   short a
+// CHECK-NEXT:   16 |   struct B0 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=16, align=4
+// CHECK-NEXT:      |  nvsize=16, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct AB2
-// CHECK-X64:    0 |   struct B10 (base)
-// CHECK-X64:    0 |     char [7] c
-// CHECK-X64:   17 |   struct B1 (base) (empty)
-// CHECK-X64:    8 |   (AB2 vbtable pointer)
-// CHECK-X64:   18 |   short a
-// CHECK-X64:   24 |   struct B0 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=24, align=8
-// CHECK-X64:      |  nvsize=24, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct AB2
+// CHECK-X64-NEXT:    0 |   struct B10 (base)
+// CHECK-X64-NEXT:    0 |     char [7] c
+// CHECK-X64-NEXT:   17 |   struct B1 (base) (empty)
+// CHECK-X64-NEXT:    8 |   (AB2 vbtable pointer)
+// CHECK-X64-NEXT:   18 |   short a
+// CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
 
 struct AC2 : B10, B1, virtual B0 {
 	char a;
-	AC2() : a(0xf0000AC2) { printf("AC2 = %p\n", this); }
+	AC2() : a(0x000000C2) { printf("AC2 = %p\n", this); }
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct AC2
-// CHECK:    0 |   struct B10 (base)
-// CHECK:    0 |     char [7] c
-// CHECK:   12 |   struct B1 (base) (empty)
-// CHECK:    8 |   (AC2 vbtable pointer)
-// CHECK:   12 |   char a
-// CHECK:   16 |   struct B0 (virtual base) (empty)
-// CHECK:      | [sizeof=16, align=4
-// CHECK:      |  nvsize=16, nvalign=4]
+// CHECK-NEXT:    0 | struct AC2
+// CHECK-NEXT:    0 |   struct B10 (base)
+// CHECK-NEXT:    0 |     char [7] c
+// CHECK-NEXT:   12 |   struct B1 (base) (empty)
+// CHECK-NEXT:    8 |   (AC2 vbtable pointer)
+// CHECK-NEXT:   12 |   char a
+// CHECK-NEXT:   16 |   struct B0 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=16, align=4
+// CHECK-NEXT:      |  nvsize=16, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct AC2
-// CHECK-X64:    0 |   struct B10 (base)
-// CHECK-X64:    0 |     char [7] c
-// CHECK-X64:   16 |   struct B1 (base) (empty)
-// CHECK-X64:    8 |   (AC2 vbtable pointer)
-// CHECK-X64:   16 |   char a
-// CHECK-X64:   24 |   struct B0 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=24, align=8
-// CHECK-X64:      |  nvsize=24, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct AC2
+// CHECK-X64-NEXT:    0 |   struct B10 (base)
+// CHECK-X64-NEXT:    0 |     char [7] c
+// CHECK-X64-NEXT:   16 |   struct B1 (base) (empty)
+// CHECK-X64-NEXT:    8 |   (AC2 vbtable pointer)
+// CHECK-X64-NEXT:   16 |   char a
+// CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
 
 struct AD2 : B10, B1, virtual B0 {
 	AD2() { printf("AD2 = %p\n", this); }
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct AD2
-// CHECK:    0 |   struct B10 (base)
-// CHECK:    0 |     char [7] c
-// CHECK:   12 |   struct B1 (base) (empty)
-// CHECK:    8 |   (AD2 vbtable pointer)
-// CHECK:   12 |   struct B0 (virtual base) (empty)
-// CHECK:      | [sizeof=12, align=4
-// CHECK:      |  nvsize=12, nvalign=4]
+// CHECK-NEXT:    0 | struct AD2
+// CHECK-NEXT:    0 |   struct B10 (base)
+// CHECK-NEXT:    0 |     char [7] c
+// CHECK-NEXT:   12 |   struct B1 (base) (empty)
+// CHECK-NEXT:    8 |   (AD2 vbtable pointer)
+// CHECK-NEXT:   12 |   struct B0 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=12, align=4
+// CHECK-NEXT:      |  nvsize=12, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct AD2
-// CHECK-X64:    0 |   struct B10 (base)
-// CHECK-X64:    0 |     char [7] c
-// CHECK-X64:   16 |   struct B1 (base) (empty)
-// CHECK-X64:    8 |   (AD2 vbtable pointer)
-// CHECK-X64:   16 |   struct B0 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=16, align=8
-// CHECK-X64:      |  nvsize=16, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct AD2
+// CHECK-X64-NEXT:    0 |   struct B10 (base)
+// CHECK-X64-NEXT:    0 |     char [7] c
+// CHECK-X64-NEXT:   16 |   struct B1 (base) (empty)
+// CHECK-X64-NEXT:    8 |   (AD2 vbtable pointer)
+// CHECK-X64-NEXT:   16 |   struct B0 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=16, align=8
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
 
 struct AA3 : B11, B1, virtual B0 {
 	int a;
-	AA3() : a(0xf0000AA3) { printf("AA3 = %p\n", this); }
+	AA3() : a(0x00000AA3) { printf("AA3 = %p\n", this); }
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct AA3
-// CHECK:    0 |   struct B11 (base)
-// CHECK:    0 |     char [8] c
-// CHECK:   12 |   struct B1 (base) (empty)
-// CHECK:    8 |   (AA3 vbtable pointer)
-// CHECK:   12 |   int a
-// CHECK:   16 |   struct B0 (virtual base) (empty)
-// CHECK:      | [sizeof=16, align=4
-// CHECK:      |  nvsize=16, nvalign=4]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct AA3
+// CHECK-NEXT:    0 |   struct B11 (base)
+// CHECK-NEXT:    0 |     char [8] c
+// CHECK-NEXT:   12 |   struct B1 (base) (empty)
+// CHECK-NEXT:    8 |   (AA3 vbtable pointer)
+// CHECK-NEXT:   12 |   int a
+// CHECK-NEXT:   16 |   struct B0 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=16, align=4
+// CHECK-NEXT:      |  nvsize=16, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct AA3
-// CHECK-X64:    0 |   struct B11 (base)
-// CHECK-X64:    0 |     char [8] c
-// CHECK-X64:   16 |   struct B1 (base) (empty)
-// CHECK-X64:    8 |   (AA3 vbtable pointer)
-// CHECK-X64:   16 |   int a
-// CHECK-X64:   24 |   struct B0 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=24, align=8
-// CHECK-X64:      |  nvsize=24, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct AA3
+// CHECK-X64-NEXT:    0 |   struct B11 (base)
+// CHECK-X64-NEXT:    0 |     char [8] c
+// CHECK-X64-NEXT:   16 |   struct B1 (base) (empty)
+// CHECK-X64-NEXT:    8 |   (AA3 vbtable pointer)
+// CHECK-X64-NEXT:   16 |   int a
+// CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
 
 struct AB3 : B11, B1, virtual B0 {
 	short a;
-	AB3() : a(0xf0000AB3) { printf("AB3 = %p\n", this); }
+	AB3() : a(0x00000AB3) { printf("AB3 = %p\n", this); }
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct AB3
-// CHECK:    0 |   struct B11 (base)
-// CHECK:    0 |     char [8] c
-// CHECK:   12 |   struct B1 (base) (empty)
-// CHECK:    8 |   (AB3 vbtable pointer)
-// CHECK:   12 |   short a
-// CHECK:   16 |   struct B0 (virtual base) (empty)
-// CHECK:      | [sizeof=16, align=4
-// CHECK:      |  nvsize=16, nvalign=4]
+// CHECK-NEXT:    0 | struct AB3
+// CHECK-NEXT:    0 |   struct B11 (base)
+// CHECK-NEXT:    0 |     char [8] c
+// CHECK-NEXT:   12 |   struct B1 (base) (empty)
+// CHECK-NEXT:    8 |   (AB3 vbtable pointer)
+// CHECK-NEXT:   12 |   short a
+// CHECK-NEXT:   16 |   struct B0 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=16, align=4
+// CHECK-NEXT:      |  nvsize=16, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct AB3
-// CHECK-X64:    0 |   struct B11 (base)
-// CHECK-X64:    0 |     char [8] c
-// CHECK-X64:   16 |   struct B1 (base) (empty)
-// CHECK-X64:    8 |   (AB3 vbtable pointer)
-// CHECK-X64:   16 |   short a
-// CHECK-X64:   24 |   struct B0 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=24, align=8
-// CHECK-X64:      |  nvsize=24, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct AB3
+// CHECK-X64-NEXT:    0 |   struct B11 (base)
+// CHECK-X64-NEXT:    0 |     char [8] c
+// CHECK-X64-NEXT:   16 |   struct B1 (base) (empty)
+// CHECK-X64-NEXT:    8 |   (AB3 vbtable pointer)
+// CHECK-X64-NEXT:   16 |   short a
+// CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
 
 struct AC3 : B11, B1, virtual B0 {
 	char a;
-	AC3() : a(0xf0000AC3) { printf("AC3 = %p\n", this); }
+	AC3() : a(0x000000C3) { printf("AC3 = %p\n", this); }
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct AC3
-// CHECK:    0 |   struct B11 (base)
-// CHECK:    0 |     char [8] c
-// CHECK:   12 |   struct B1 (base) (empty)
-// CHECK:    8 |   (AC3 vbtable pointer)
-// CHECK:   12 |   char a
-// CHECK:   16 |   struct B0 (virtual base) (empty)
-// CHECK:      | [sizeof=16, align=4
-// CHECK:      |  nvsize=16, nvalign=4]
+// CHECK-NEXT:    0 | struct AC3
+// CHECK-NEXT:    0 |   struct B11 (base)
+// CHECK-NEXT:    0 |     char [8] c
+// CHECK-NEXT:   12 |   struct B1 (base) (empty)
+// CHECK-NEXT:    8 |   (AC3 vbtable pointer)
+// CHECK-NEXT:   12 |   char a
+// CHECK-NEXT:   16 |   struct B0 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=16, align=4
+// CHECK-NEXT:      |  nvsize=16, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct AC3
-// CHECK-X64:    0 |   struct B11 (base)
-// CHECK-X64:    0 |     char [8] c
-// CHECK-X64:   16 |   struct B1 (base) (empty)
-// CHECK-X64:    8 |   (AC3 vbtable pointer)
-// CHECK-X64:   16 |   char a
-// CHECK-X64:   24 |   struct B0 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=24, align=8
-// CHECK-X64:      |  nvsize=24, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct AC3
+// CHECK-X64-NEXT:    0 |   struct B11 (base)
+// CHECK-X64-NEXT:    0 |     char [8] c
+// CHECK-X64-NEXT:   16 |   struct B1 (base) (empty)
+// CHECK-X64-NEXT:    8 |   (AC3 vbtable pointer)
+// CHECK-X64-NEXT:   16 |   char a
+// CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
 
 struct AD3 : B11, B1, virtual B0 {
 	AD3() { printf("AD3 = %p\n", this); }
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct AD3
-// CHECK:    0 |   struct B11 (base)
-// CHECK:    0 |     char [8] c
-// CHECK:   12 |   struct B1 (base) (empty)
-// CHECK:    8 |   (AD3 vbtable pointer)
-// CHECK:   12 |   struct B0 (virtual base) (empty)
-// CHECK:      | [sizeof=12, align=4
-// CHECK:      |  nvsize=12, nvalign=4]
+// CHECK-NEXT:    0 | struct AD3
+// CHECK-NEXT:    0 |   struct B11 (base)
+// CHECK-NEXT:    0 |     char [8] c
+// CHECK-NEXT:   12 |   struct B1 (base) (empty)
+// CHECK-NEXT:    8 |   (AD3 vbtable pointer)
+// CHECK-NEXT:   12 |   struct B0 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=12, align=4
+// CHECK-NEXT:      |  nvsize=12, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct AD3
-// CHECK-X64:    0 |   struct B11 (base)
-// CHECK-X64:    0 |     char [8] c
-// CHECK-X64:   16 |   struct B1 (base) (empty)
-// CHECK-X64:    8 |   (AD3 vbtable pointer)
-// CHECK-X64:   16 |   struct B0 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=16, align=8
-// CHECK-X64:      |  nvsize=16, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct AD3
+// CHECK-X64-NEXT:    0 |   struct B11 (base)
+// CHECK-X64-NEXT:    0 |     char [8] c
+// CHECK-X64-NEXT:   16 |   struct B1 (base) (empty)
+// CHECK-X64-NEXT:    8 |   (AD3 vbtable pointer)
+// CHECK-X64-NEXT:   16 |   struct B0 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=16, align=8
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
 
 struct B : B1, B2, virtual B0 {
 	B() { printf("B = %p\n", this); }
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct B
-// CHECK:    0 |   struct B1 (base) (empty)
-// CHECK:    8 |   struct B2 (base) (empty)
-// CHECK:    4 |   (B vbtable pointer)
-// CHECK:    8 |   struct B0 (virtual base) (empty)
-// CHECK:      | [sizeof=8, align=4
-// CHECK:      |  nvsize=8, nvalign=4]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct B
+// CHECK-NEXT:    0 |   struct B1 (base) (empty)
+// CHECK-NEXT:    8 |   struct B2 (base) (empty)
+// CHECK-NEXT:    4 |   (B vbtable pointer)
+// CHECK-NEXT:    8 |   struct B0 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=8, align=4
+// CHECK-NEXT:      |  nvsize=8, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct B
-// CHECK-X64:    0 |   struct B1 (base) (empty)
-// CHECK-X64:   16 |   struct B2 (base) (empty)
-// CHECK-X64:    8 |   (B vbtable pointer)
-// CHECK-X64:   16 |   struct B0 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=16, align=8
-// CHECK-X64:      |  nvsize=16, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct B
+// CHECK-X64-NEXT:    0 |   struct B1 (base) (empty)
+// CHECK-X64-NEXT:   16 |   struct B2 (base) (empty)
+// CHECK-X64-NEXT:    8 |   (B vbtable pointer)
+// CHECK-X64-NEXT:   16 |   struct B0 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=16, align=8
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
 
 struct C : B1, B2, B3, virtual B0 {
 	char a;
-	C() : a(0xf000000C) { printf("C = %p\n", this); }
+	C() : a(0x0000000C) { printf("C = %p\n", this); }
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct C
-// CHECK:    0 |   struct B1 (base) (empty)
-// CHECK:    1 |   struct B2 (base) (empty)
-// CHECK:    8 |   struct B3 (base) (empty)
-// CHECK:    4 |   (C vbtable pointer)
-// CHECK:    8 |   char a
-// CHECK:   12 |   struct B0 (virtual base) (empty)
-// CHECK:      | [sizeof=12, align=4
-// CHECK:      |  nvsize=12, nvalign=4]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct C
+// CHECK-NEXT:    0 |   struct B1 (base) (empty)
+// CHECK-NEXT:    1 |   struct B2 (base) (empty)
+// CHECK-NEXT:    8 |   struct B3 (base) (empty)
+// CHECK-NEXT:    4 |   (C vbtable pointer)
+// CHECK-NEXT:    8 |   char a
+// CHECK-NEXT:   12 |   struct B0 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=12, align=4
+// CHECK-NEXT:      |  nvsize=12, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct C
-// CHECK-X64:    0 |   struct B1 (base) (empty)
-// CHECK-X64:    1 |   struct B2 (base) (empty)
-// CHECK-X64:   16 |   struct B3 (base) (empty)
-// CHECK-X64:    8 |   (C vbtable pointer)
-// CHECK-X64:   16 |   char a
-// CHECK-X64:   24 |   struct B0 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=24, align=8
-// CHECK-X64:      |  nvsize=24, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct C
+// CHECK-X64-NEXT:    0 |   struct B1 (base) (empty)
+// CHECK-X64-NEXT:    1 |   struct B2 (base) (empty)
+// CHECK-X64-NEXT:   16 |   struct B3 (base) (empty)
+// CHECK-X64-NEXT:    8 |   (C vbtable pointer)
+// CHECK-X64-NEXT:   16 |   char a
+// CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
 
 struct D : B1, B2, B3, B4, B5, virtual B0 {
 	int a;
-	D() : a(0xf000000D) { printf("D = %p\n", this); }
+	D() : a(0x0000000D) { printf("D = %p\n", this); }
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct D
-// CHECK:    0 |   struct B1 (base) (empty)
-// CHECK:    1 |   struct B2 (base) (empty)
-// CHECK:    2 |   struct B3 (base) (empty)
-// CHECK:    3 |   struct B4 (base) (empty)
-// CHECK:    8 |   struct B5 (base) (empty)
-// CHECK:    4 |   (D vbtable pointer)
-// CHECK:    8 |   int a
-// CHECK:   12 |   struct B0 (virtual base) (empty)
-// CHECK:      | [sizeof=12, align=4
-// CHECK:      |  nvsize=12, nvalign=4]
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct D
+// CHECK-NEXT:    0 |   struct B1 (base) (empty)
+// CHECK-NEXT:    1 |   struct B2 (base) (empty)
+// CHECK-NEXT:    2 |   struct B3 (base) (empty)
+// CHECK-NEXT:    3 |   struct B4 (base) (empty)
+// CHECK-NEXT:    8 |   struct B5 (base) (empty)
+// CHECK-NEXT:    4 |   (D vbtable pointer)
+// CHECK-NEXT:    8 |   int a
+// CHECK-NEXT:   12 |   struct B0 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=12, align=4
+// CHECK-NEXT:      |  nvsize=12, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct D
-// CHECK-X64:    0 |   struct B1 (base) (empty)
-// CHECK-X64:    1 |   struct B2 (base) (empty)
-// CHECK-X64:    2 |   struct B3 (base) (empty)
-// CHECK-X64:    3 |   struct B4 (base) (empty)
-// CHECK-X64:   16 |   struct B5 (base) (empty)
-// CHECK-X64:    8 |   (D vbtable pointer)
-// CHECK-X64:   16 |   int a
-// CHECK-X64:   24 |   struct B0 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=24, align=8
-// CHECK-X64:      |  nvsize=24, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct D
+// CHECK-X64-NEXT:    0 |   struct B1 (base) (empty)
+// CHECK-X64-NEXT:    1 |   struct B2 (base) (empty)
+// CHECK-X64-NEXT:    2 |   struct B3 (base) (empty)
+// CHECK-X64-NEXT:    3 |   struct B4 (base) (empty)
+// CHECK-X64-NEXT:   16 |   struct B5 (base) (empty)
+// CHECK-X64-NEXT:    8 |   (D vbtable pointer)
+// CHECK-X64-NEXT:   16 |   int a
+// CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
 
 struct E : B1, B6, B3, B4, B5, virtual B0 {
 	int a;
-	E() : a(0xf000000E) { printf("E = %p\n", this); }
+	E() : a(0x0000000E) { printf("E = %p\n", this); }
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct E
-// CHECK:    0 |   struct B1 (base) (empty)
-// CHECK:    2 |   struct B6 (base) (empty)
-// CHECK:    3 |   struct B3 (base) (empty)
-// CHECK:    4 |   struct B4 (base) (empty)
-// CHECK:   13 |   struct B5 (base) (empty)
-// CHECK:    8 |   (E vbtable pointer)
-// CHECK:   16 |   int a
-// CHECK:   20 |   struct B0 (virtual base) (empty)
-// CHECK:      | [sizeof=20, align=4
-// CHECK:      |  nvsize=20, nvalign=4]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct E
+// CHECK-NEXT:    0 |   struct B1 (base) (empty)
+// CHECK-NEXT:    2 |   struct B6 (base) (empty)
+// CHECK-NEXT:    3 |   struct B3 (base) (empty)
+// CHECK-NEXT:    4 |   struct B4 (base) (empty)
+// CHECK-NEXT:   13 |   struct B5 (base) (empty)
+// CHECK-NEXT:    8 |   (E vbtable pointer)
+// CHECK-NEXT:   16 |   int a
+// CHECK-NEXT:   20 |   struct B0 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=20, align=4
+// CHECK-NEXT:      |  nvsize=20, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct E
-// CHECK-X64:    0 |   struct B1 (base) (empty)
-// CHECK-X64:    2 |   struct B6 (base) (empty)
-// CHECK-X64:    3 |   struct B3 (base) (empty)
-// CHECK-X64:    4 |   struct B4 (base) (empty)
-// CHECK-X64:   17 |   struct B5 (base) (empty)
-// CHECK-X64:    8 |   (E vbtable pointer)
-// CHECK-X64:   20 |   int a
-// CHECK-X64:   24 |   struct B0 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=24, align=8
-// CHECK-X64:      |  nvsize=24, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct E
+// CHECK-X64-NEXT:    0 |   struct B1 (base) (empty)
+// CHECK-X64-NEXT:    2 |   struct B6 (base) (empty)
+// CHECK-X64-NEXT:    3 |   struct B3 (base) (empty)
+// CHECK-X64-NEXT:    4 |   struct B4 (base) (empty)
+// CHECK-X64-NEXT:   17 |   struct B5 (base) (empty)
+// CHECK-X64-NEXT:    8 |   (E vbtable pointer)
+// CHECK-X64-NEXT:   20 |   int a
+// CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
 
 struct F : B1, B6, B4, B8, B5, virtual B0 {
 	int a;
-	F() : a(0xf000000F) { printf("&a = %p\n", &a); printf("F = %p\n", this); }
+	F() : a(0x0000000F) { printf("&a = %p\n", &a); printf("F = %p\n", this); }
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct F
-// CHECK:    0 |   struct B1 (base) (empty)
-// CHECK:    2 |   struct B6 (base) (empty)
-// CHECK:    3 |   struct B4 (base) (empty)
-// CHECK:    3 |   struct B8 (base)
-// CHECK:    3 |     char [5] c
-// CHECK:   12 |   struct B5 (base) (empty)
-// CHECK:    8 |   (F vbtable pointer)
-// CHECK:   12 |   int a
-// CHECK:   16 |   struct B0 (virtual base) (empty)
-// CHECK:      | [sizeof=16, align=4
-// CHECK:      |  nvsize=16, nvalign=4]
+// CHECK-NEXT:    0 | struct F
+// CHECK-NEXT:    0 |   struct B1 (base) (empty)
+// CHECK-NEXT:    2 |   struct B6 (base) (empty)
+// CHECK-NEXT:    3 |   struct B4 (base) (empty)
+// CHECK-NEXT:    3 |   struct B8 (base)
+// CHECK-NEXT:    3 |     char [5] c
+// CHECK-NEXT:   12 |   struct B5 (base) (empty)
+// CHECK-NEXT:    8 |   (F vbtable pointer)
+// CHECK-NEXT:   12 |   int a
+// CHECK-NEXT:   16 |   struct B0 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=16, align=4
+// CHECK-NEXT:      |  nvsize=16, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct F
-// CHECK-X64:    0 |   struct B1 (base) (empty)
-// CHECK-X64:    2 |   struct B6 (base) (empty)
-// CHECK-X64:    3 |   struct B4 (base) (empty)
-// CHECK-X64:    3 |   struct B8 (base)
-// CHECK-X64:    3 |     char [5] c
-// CHECK-X64:   16 |   struct B5 (base) (empty)
-// CHECK-X64:    8 |   (F vbtable pointer)
-// CHECK-X64:   16 |   int a
-// CHECK-X64:   24 |   struct B0 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=24, align=8
-// CHECK-X64:      |  nvsize=24, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct F
+// CHECK-X64-NEXT:    0 |   struct B1 (base) (empty)
+// CHECK-X64-NEXT:    2 |   struct B6 (base) (empty)
+// CHECK-X64-NEXT:    3 |   struct B4 (base) (empty)
+// CHECK-X64-NEXT:    3 |   struct B8 (base)
+// CHECK-X64-NEXT:    3 |     char [5] c
+// CHECK-X64-NEXT:   16 |   struct B5 (base) (empty)
+// CHECK-X64-NEXT:    8 |   (F vbtable pointer)
+// CHECK-X64-NEXT:   16 |   int a
+// CHECK-X64-NEXT:   24 |   struct B0 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
 
 struct G : B8, B1, virtual B0 {
 	int a;
 	__declspec(align(16)) int a1;
-	G() : a(0xf0000010), a1(0xf0000010) { printf("G = %p\n", this); }
+	G() : a(0x00000010), a1(0xf0000010) { printf("G = %p\n", this); }
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct G
-// CHECK:    0 |   struct B8 (base)
-// CHECK:    0 |     char [5] c
-// CHECK:   21 |   struct B1 (base) (empty)
-// CHECK:    8 |   (G vbtable pointer)
-// CHECK:   24 |   int a
-// CHECK:   32 |   int a1
-// CHECK:   48 |   struct B0 (virtual base) (empty)
-// CHECK:      | [sizeof=48, align=16
-// CHECK:      |  nvsize=48, nvalign=16]
+// CHECK-NEXT:    0 | struct G
+// CHECK-NEXT:    0 |   struct B8 (base)
+// CHECK-NEXT:    0 |     char [5] c
+// CHECK-NEXT:   21 |   struct B1 (base) (empty)
+// CHECK-NEXT:    8 |   (G vbtable pointer)
+// CHECK-NEXT:   24 |   int a
+// CHECK-NEXT:   32 |   int a1
+// CHECK-NEXT:   48 |   struct B0 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=48, align=16
+// CHECK-NEXT:      |  nvsize=48, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct G
-// CHECK-X64:    0 |   struct B8 (base)
-// CHECK-X64:    0 |     char [5] c
-// CHECK-X64:   16 |   struct B1 (base) (empty)
-// CHECK-X64:    8 |   (G vbtable pointer)
-// CHECK-X64:   16 |   int a
-// CHECK-X64:   32 |   int a1
-// CHECK-X64:   48 |   struct B0 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=48, align=16
-// CHECK-X64:      |  nvsize=48, nvalign=16]
+// CHECK-X64-NEXT:    0 | struct G
+// CHECK-X64-NEXT:    0 |   struct B8 (base)
+// CHECK-X64-NEXT:    0 |     char [5] c
+// CHECK-X64-NEXT:   21 |   struct B1 (base) (empty)
+// CHECK-X64-NEXT:    8 |   (G vbtable pointer)
+// CHECK-X64-NEXT:   24 |   int a
+// CHECK-X64-NEXT:   32 |   int a1
+// CHECK-X64-NEXT:   48 |   struct B0 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=48, align=16
+// CHECK-X64-NEXT:      |  nvsize=48, nvalign=16]
 
 struct AX : B1X, B2X, B3X, B4X, virtual B0X {
 	int a;
-	AX() : a(0xf000000A) { printf(" A = %p\n", this); }
+	AX() : a(0x0000000A) { printf(" A = %p\n", this); }
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct AX
-// CHECK:    0 |   struct B1X (base) (empty)
-// CHECK:   16 |   struct B2X (base) (empty)
-// CHECK:   18 |   struct B3X (base) (empty)
-// CHECK:   35 |   struct B4X (base) (empty)
-// CHECK:   20 |   (AX vbtable pointer)
-// CHECK:   36 |   int a
-// CHECK:   48 |   struct B0X (virtual base) (empty)
-// CHECK:      | [sizeof=48, align=16
-// CHECK:      |  nvsize=48, nvalign=16]
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct AX
+// CHECK-NEXT:    0 |   struct B1X (base) (empty)
+// CHECK-NEXT:   16 |   struct B2X (base) (empty)
+// CHECK-NEXT:   18 |   struct B3X (base) (empty)
+// CHECK-NEXT:   35 |   struct B4X (base) (empty)
+// CHECK-NEXT:   20 |   (AX vbtable pointer)
+// CHECK-NEXT:   36 |   int a
+// CHECK-NEXT:   48 |   struct B0X (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=48, align=16
+// CHECK-NEXT:      |  nvsize=48, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct AX
-// CHECK-X64:    0 |   struct B1X (base) (empty)
-// CHECK-X64:   16 |   struct B2X (base) (empty)
-// CHECK-X64:   18 |   struct B3X (base) (empty)
-// CHECK-X64:   33 |   struct B4X (base) (empty)
-// CHECK-X64:   24 |   (AX vbtable pointer)
-// CHECK-X64:   36 |   int a
-// CHECK-X64:   48 |   struct B0X (virtual base) (empty)
-// CHECK-X64:      | [sizeof=48, align=16
-// CHECK-X64:      |  nvsize=48, nvalign=16]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct AX
+// CHECK-X64-NEXT:    0 |   struct B1X (base) (empty)
+// CHECK-X64-NEXT:   16 |   struct B2X (base) (empty)
+// CHECK-X64-NEXT:   18 |   struct B3X (base) (empty)
+// CHECK-X64-NEXT:   35 |   struct B4X (base) (empty)
+// CHECK-X64-NEXT:   24 |   (AX vbtable pointer)
+// CHECK-X64-NEXT:   36 |   int a
+// CHECK-X64-NEXT:   48 |   struct B0X (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=48, align=16
+// CHECK-X64-NEXT:      |  nvsize=48, nvalign=16]
 
 struct BX : B2X, B1X, B3X, B4X, virtual B0X {
 	int a;
-	BX() : a(0xf000000B) { printf(" B = %p\n", this); }
+	BX() : a(0x0000000B) { printf(" B = %p\n", this); }
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct BX
-// CHECK:    0 |   struct B2X (base) (empty)
-// CHECK:    1 |   struct B1X (base) (empty)
-// CHECK:    2 |   struct B3X (base) (empty)
-// CHECK:   19 |   struct B4X (base) (empty)
-// CHECK:    4 |   (BX vbtable pointer)
-// CHECK:   20 |   int a
-// CHECK:   32 |   struct B0X (virtual base) (empty)
-// CHECK:      | [sizeof=32, align=16
-// CHECK:      |  nvsize=32, nvalign=16]
+// CHECK-NEXT:    0 | struct BX
+// CHECK-NEXT:    0 |   struct B2X (base) (empty)
+// CHECK-NEXT:    1 |   struct B1X (base) (empty)
+// CHECK-NEXT:    2 |   struct B3X (base) (empty)
+// CHECK-NEXT:   19 |   struct B4X (base) (empty)
+// CHECK-NEXT:    4 |   (BX vbtable pointer)
+// CHECK-NEXT:   20 |   int a
+// CHECK-NEXT:   32 |   struct B0X (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=32, align=16
+// CHECK-NEXT:      |  nvsize=32, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct BX
-// CHECK-X64:    0 |   struct B2X (base) (empty)
-// CHECK-X64:    1 |   struct B1X (base) (empty)
-// CHECK-X64:    2 |   struct B3X (base) (empty)
-// CHECK-X64:   17 |   struct B4X (base) (empty)
-// CHECK-X64:    8 |   (BX vbtable pointer)
-// CHECK-X64:   20 |   int a
-// CHECK-X64:   32 |   struct B0X (virtual base) (empty)
-// CHECK-X64:      | [sizeof=32, align=16
-// CHECK-X64:      |  nvsize=32, nvalign=16]
+// CHECK-X64-NEXT:    0 | struct BX
+// CHECK-X64-NEXT:    0 |   struct B2X (base) (empty)
+// CHECK-X64-NEXT:    1 |   struct B1X (base) (empty)
+// CHECK-X64-NEXT:    2 |   struct B3X (base) (empty)
+// CHECK-X64-NEXT:   19 |   struct B4X (base) (empty)
+// CHECK-X64-NEXT:    8 |   (BX vbtable pointer)
+// CHECK-X64-NEXT:   20 |   int a
+// CHECK-X64-NEXT:   32 |   struct B0X (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=32, align=16
+// CHECK-X64-NEXT:      |  nvsize=32, nvalign=16]
 
 struct CX : B1X, B3X, B2X, virtual B0X {
 	int a;
-	CX() : a(0xf000000C) { printf(" C = %p\n", this); }
+	CX() : a(0x0000000C) { printf(" C = %p\n", this); }
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct CX
-// CHECK:    0 |   struct B1X (base) (empty)
-// CHECK:    2 |   struct B3X (base) (empty)
-// CHECK:   32 |   struct B2X (base) (empty)
-// CHECK:    4 |   (CX vbtable pointer)
-// CHECK:   32 |   int a
-// CHECK:   48 |   struct B0X (virtual base) (empty)
-// CHECK:      | [sizeof=48, align=16
-// CHECK:      |  nvsize=48, nvalign=16]
+// CHECK-NEXT:    0 | struct CX
+// CHECK-NEXT:    0 |   struct B1X (base) (empty)
+// CHECK-NEXT:    2 |   struct B3X (base) (empty)
+// CHECK-NEXT:   32 |   struct B2X (base) (empty)
+// CHECK-NEXT:   16 |   (CX vbtable pointer)
+// CHECK-NEXT:   32 |   int a
+// CHECK-NEXT:   48 |   struct B0X (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=48, align=16
+// CHECK-NEXT:      |  nvsize=48, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct CX
-// CHECK-X64:    0 |   struct B1X (base) (empty)
-// CHECK-X64:    2 |   struct B3X (base) (empty)
-// CHECK-X64:   32 |   struct B2X (base) (empty)
-// CHECK-X64:    8 |   (CX vbtable pointer)
-// CHECK-X64:   32 |   int a
-// CHECK-X64:   48 |   struct B0X (virtual base) (empty)
-// CHECK-X64:      | [sizeof=48, align=16
-// CHECK-X64:      |  nvsize=48, nvalign=16]
+// CHECK-X64-NEXT:    0 | struct CX
+// CHECK-X64-NEXT:    0 |   struct B1X (base) (empty)
+// CHECK-X64-NEXT:    2 |   struct B3X (base) (empty)
+// CHECK-X64-NEXT:   32 |   struct B2X (base) (empty)
+// CHECK-X64-NEXT:   16 |   (CX vbtable pointer)
+// CHECK-X64-NEXT:   32 |   int a
+// CHECK-X64-NEXT:   48 |   struct B0X (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=48, align=16
+// CHECK-X64-NEXT:      |  nvsize=48, nvalign=16]
 
 struct DX : B8X, B1X, virtual B0X {
 	int a;
-	DX() : a(0xf000000D) { printf(" D = %p\n", this); }
+	DX() : a(0x0000000D) { printf(" D = %p\n", this); }
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct DX
-// CHECK:    0 |   struct B8X (base)
-// CHECK:    0 |     short a
-// CHECK:   10 |   struct B1X (base) (empty)
-// CHECK:    4 |   (DX vbtable pointer)
-// CHECK:   12 |   int a
-// CHECK:   16 |   struct B0X (virtual base) (empty)
-// CHECK:      | [sizeof=16, align=4
-// CHECK:      |  nvsize=16, nvalign=4]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct DX
+// CHECK-NEXT:    0 |   struct B8X (base)
+// CHECK-NEXT:    0 |     short a
+// CHECK-NEXT:   10 |   struct B1X (base) (empty)
+// CHECK-NEXT:    4 |   (DX vbtable pointer)
+// CHECK-NEXT:   12 |   int a
+// CHECK-NEXT:   16 |   struct B0X (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=16, align=4
+// CHECK-NEXT:      |  nvsize=16, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct DX
-// CHECK-X64:    0 |   struct B8X (base)
-// CHECK-X64:    0 |     short a
-// CHECK-X64:   18 |   struct B1X (base) (empty)
-// CHECK-X64:    8 |   (DX vbtable pointer)
-// CHECK-X64:   20 |   int a
-// CHECK-X64:   24 |   struct B0X (virtual base) (empty)
-// CHECK-X64:      | [sizeof=24, align=8
-// CHECK-X64:      |  nvsize=24, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct DX
+// CHECK-X64-NEXT:    0 |   struct B8X (base)
+// CHECK-X64-NEXT:    0 |     short a
+// CHECK-X64-NEXT:   18 |   struct B1X (base) (empty)
+// CHECK-X64-NEXT:    8 |   (DX vbtable pointer)
+// CHECK-X64-NEXT:   20 |   int a
+// CHECK-X64-NEXT:   24 |   struct B0X (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
+
+
+struct C0 {};
+struct C1 : public C0 { int C1F0; };
+struct C2 : public C1, public C0 {};
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct C2
+// CHECK-NEXT:    0 |   struct C1 (base)
+// CHECK-NEXT:    0 |     struct C0 (base) (empty)
+// CHECK-NEXT:    0 |     int C1F0
+// CHECK-NEXT:    5 |   struct C0 (base) (empty)
+// CHECK-NEXT:      | [sizeof=8, align=4
+// CHECK-NEXT:      |  nvsize=8, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct C2
+// CHECK-X64-NEXT:    0 |   struct C1 (base)
+// CHECK-X64-NEXT:    0 |     struct C0 (base) (empty)
+// CHECK-X64-NEXT:    0 |     int C1F0
+// CHECK-X64-NEXT:    5 |   struct C0 (base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=8, align=4
+// CHECK-X64-NEXT:      |  nvsize=8, nvalign=4]
+
+struct JA { char a; };
+struct JB {
+  char a;
+  virtual void f() {}
+};
+struct JC { char a; };
+struct JD : JA, JB, virtual JC {};
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct JD
+// CHECK-NEXT:    0 |   struct JB (primary base)
+// CHECK-NEXT:    0 |     (JB vftable pointer)
+// CHECK-NEXT:    4 |     char a
+// CHECK-NEXT:   12 |   struct JA (base)
+// CHECK-NEXT:   12 |     char a
+// CHECK-NEXT:    8 |   (JD vbtable pointer)
+// CHECK-NEXT:   16 |   struct JC (virtual base)
+// CHECK-NEXT:   16 |     char a
+// CHECK-NEXT:      | [sizeof=17, align=4
+// CHECK-NEXT:      |  nvsize=16, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct JD
+// CHECK-X64-NEXT:    0 |   struct JB (primary base)
+// CHECK-X64-NEXT:    0 |     (JB vftable pointer)
+// CHECK-X64-NEXT:    8 |     char a
+// CHECK-X64-NEXT:   24 |   struct JA (base)
+// CHECK-X64-NEXT:   24 |     char a
+// CHECK-X64-NEXT:   16 |   (JD vbtable pointer)
+// CHECK-X64-NEXT:   32 |   struct JC (virtual base)
+// CHECK-X64-NEXT:   32 |     char a
+// CHECK-X64-NEXT:      | [sizeof=40, align=8
+// CHECK-X64-NEXT:      |  nvsize=32, nvalign=8]
 
 int a[
 sizeof(AA)+
@@ -732,4 +831,7 @@
 sizeof(AX)+
 sizeof(BX)+
 sizeof(CX)+
-sizeof(DX)];
+sizeof(DX)+
+sizeof(C2)+
+sizeof(JD)+
+0];
diff --git a/test/Layout/ms-x86-member-pointers.cpp b/test/Layout/ms-x86-member-pointers.cpp
new file mode 100644
index 0000000..89dd211
--- /dev/null
+++ b/test/Layout/ms-x86-member-pointers.cpp
@@ -0,0 +1,80 @@
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fms-extensions -fsyntax-only %s 2>&1 | FileCheck %s
+
+struct __single_inheritance S;
+struct __multiple_inheritance M;
+struct __virtual_inheritance V;
+struct U;
+
+struct SD { char a; int S::*mp; };
+struct MD { char a; int M::*mp; };
+struct VD { char a; int V::*mp; };
+struct UD { char a; int U::*mp; };
+struct SF { char a; int (S::*mp)(); };
+struct MF { char a; int (M::*mp)(); };
+struct VF { char a; int (V::*mp)(); };
+struct UF { char a; int (U::*mp)(); };
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct SD
+// CHECK-NEXT:    0 |   char a
+// CHECK-NEXT:    4 |   int struct S::* mp
+// CHECK-NEXT:      | [sizeof=8, align=4
+// CHECK-NEXT:      |  nvsize=8, nvalign=4]
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct MD
+// CHECK-NEXT:    0 |   char a
+// CHECK-NEXT:    4 |   int struct M::* mp
+// CHECK-NEXT:      | [sizeof=8, align=4
+// CHECK-NEXT:      |  nvsize=8, nvalign=4]
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct VD
+// CHECK-NEXT:    0 |   char a
+// CHECK-NEXT:    8 |   int struct V::* mp
+// CHECK-NEXT:      | [sizeof=16, align=8
+// CHECK-NEXT:      |  nvsize=16, nvalign=8]
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct UD
+// CHECK-NEXT:    0 |   char a
+// CHECK-NEXT:    8 |   int struct U::* mp
+// CHECK-NEXT:      | [sizeof=24, align=8
+// CHECK-NEXT:      |  nvsize=24, nvalign=8]
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct SF
+// CHECK-NEXT:    0 |   char a
+// CHECK-NEXT:    4 |   int (struct S::*)(void) __attribute__((thiscall)) mp
+// CHECK-NEXT:      | [sizeof=8, align=4
+// CHECK-NEXT:      |  nvsize=8, nvalign=4]
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct MF
+// CHECK-NEXT:    0 |   char a
+// CHECK-NEXT:    8 |   int (struct M::*)(void) __attribute__((thiscall)) mp
+// CHECK-NEXT:      | [sizeof=16, align=8
+// CHECK-NEXT:      |  nvsize=16, nvalign=8]
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct VF
+// CHECK-NEXT:    0 |   char a
+// CHECK-NEXT:    8 |   int (struct V::*)(void) __attribute__((thiscall)) mp
+// CHECK-NEXT:      | [sizeof=24, align=8
+// CHECK-NEXT:      |  nvsize=24, nvalign=8]
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct UF
+// CHECK-NEXT:    0 |   char a
+// CHECK-NEXT:    8 |   int (struct U::*)(void) __attribute__((thiscall)) mp
+// CHECK-NEXT:      | [sizeof=24, align=8
+// CHECK-NEXT:      |  nvsize=24, nvalign=8]
+
+char a[sizeof(SD) +
+       sizeof(MD) +
+       sizeof(VD) +
+       sizeof(UD) +
+       sizeof(SF) +
+       sizeof(MF) +
+       sizeof(VF) +
+       sizeof(UF)];
diff --git a/test/Layout/ms-x86-misalignedarray.cpp b/test/Layout/ms-x86-misalignedarray.cpp
index f6887da..de5bcc7 100644
--- a/test/Layout/ms-x86-misalignedarray.cpp
+++ b/test/Layout/ms-x86-misalignedarray.cpp
@@ -1,23 +1,27 @@
-// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>&1 \
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>&1 \
 // RUN:            | FileCheck %s
-// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>/dev/null \
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>/dev/null \
 // RUN:            | FileCheck %s -check-prefix CHECK-X64
 
-struct T0 { char c; };

-struct T2 : virtual T0 { };

-struct T3 { T2 a[1]; char c; };

+struct T0 { char c; };
+struct T2 : virtual T0 { };
+struct T3 { T2 a[1]; char c; };
 
-// CHECK: *** Dumping AST Record Layout

-// CHECK:    0 | struct T3

-// CHECK:    0 |   struct T2 [1] a

-// CHECK:    5 |   char c

-// CHECK:      | [sizeof=8, align=4

-// CHECK:      |  nvsize=8, nvalign=4]

-// CHECK-X64: *** Dumping AST Record Layout

-// CHECK-X64:    0 | struct T3

-// CHECK-X64:    0 |   struct T2 [1] a

-// CHECK-X64:   16 |   char c

-// CHECK-X64:      | [sizeof=24, align=8

-// CHECK-X64:      |  nvsize=24, nvalign=8]

+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct T3
+// CHECK-NEXT:    0 |   struct T2 [1] a
+// CHECK-NEXT:    5 |   char c
+// CHECK-NEXT:      | [sizeof=8, align=4
+// CHECK-NEXT:      |  nvsize=8, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct T3
+// CHECK-X64-NEXT:    0 |   struct T2 [1] a
+// CHECK-X64-NEXT:   16 |   char c
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
 
 int a[sizeof(T3)];
diff --git a/test/Layout/ms-x86-pack-and-align.cpp b/test/Layout/ms-x86-pack-and-align.cpp
new file mode 100644
index 0000000..5e1aae1
--- /dev/null
+++ b/test/Layout/ms-x86-pack-and-align.cpp
@@ -0,0 +1,683 @@
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>&1 \
+// RUN:            | FileCheck %s
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>/dev/null \
+// RUN:            | FileCheck %s -check-prefix CHECK-X64
+
+extern "C" int printf(const char *fmt, ...);
+char buffer[419430400];
+
+struct A {
+	char a;
+	A() {
+		printf("A   = %d\n", (int)((char*)this - buffer));
+		printf("A.a = %d\n", (int)((char*)&a - buffer));
+	}
+};
+
+struct B {
+	__declspec(align(4)) long long a;
+	B() {
+		printf("B   = %d\n", (int)((char*)this - buffer));
+		printf("B.a = %d\n", (int)((char*)&a - buffer));
+	}
+};
+
+#pragma pack(push, 2)
+struct X {
+	B a;
+	char b;
+	int c;
+	X() {
+		printf("X   = %d\n", (int)((char*)this - buffer));
+		printf("X.a = %d\n", (int)((char*)&a - buffer));
+		printf("X.b = %d\n", (int)((char*)&b - buffer));
+		printf("X.c = %d\n", (int)((char*)&c - buffer));
+	}
+};
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct X
+// CHECK-NEXT:    0 |   struct B a
+// CHECK-NEXT:    0 |     long long a
+// CHECK-NEXT:      |   [sizeof=8, align=8
+// CHECK-NEXT:      |    nvsize=8, nvalign=8]
+// CHECK-NEXT:    8 |   char b
+// CHECK-NEXT:   10 |   int c
+// CHECK-NEXT:      | [sizeof=16, align=4
+// CHECK-NEXT:      |  nvsize=14, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct X
+// CHECK-X64-NEXT:    0 |   struct B a
+// CHECK-X64-NEXT:    0 |     long long a
+// CHECK-X64-NEXT:      |   [sizeof=8, align=8
+// CHECK-X64-NEXT:      |    nvsize=8, nvalign=8]
+// CHECK-X64-NEXT:    8 |   char b
+// CHECK-X64-NEXT:   10 |   int c
+// CHECK-X64-NEXT:      | [sizeof=16, align=4
+// CHECK-X64-NEXT:      |  nvsize=14, nvalign=4]
+
+struct Y : A, B {
+	char a;
+	int b;
+	Y() {
+		printf("Y   = %d\n", (int)((char*)this - buffer));
+		printf("Y.a = %d\n", (int)((char*)&a - buffer));
+		printf("Y.b = %d\n", (int)((char*)&b - buffer));
+	}
+};
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct Y
+// CHECK-NEXT:    0 |   struct A (base)
+// CHECK-NEXT:    0 |     char a
+// CHECK-NEXT:    4 |   struct B (base)
+// CHECK-NEXT:    4 |     long long a
+// CHECK-NEXT:   12 |   char a
+// CHECK-NEXT:   14 |   int b
+// CHECK-NEXT:      | [sizeof=20, align=4
+// CHECK-NEXT:      |  nvsize=18, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct Y
+// CHECK-X64-NEXT:    0 |   struct A (base)
+// CHECK-X64-NEXT:    0 |     char a
+// CHECK-X64-NEXT:    4 |   struct B (base)
+// CHECK-X64-NEXT:    4 |     long long a
+// CHECK-X64-NEXT:   12 |   char a
+// CHECK-X64-NEXT:   14 |   int b
+// CHECK-X64-NEXT:      | [sizeof=20, align=4
+// CHECK-X64-NEXT:      |  nvsize=18, nvalign=4]
+
+struct Z : virtual B {
+	char a;
+	int b;
+	Z() {
+		printf("Z   = %d\n", (int)((char*)this - buffer));
+		printf("Z.a = %d\n", (int)((char*)&a - buffer));
+		printf("Z.b = %d\n", (int)((char*)&b - buffer));
+	}
+};
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct Z
+// CHECK-NEXT:    0 |   (Z vbtable pointer)
+// CHECK-NEXT:    4 |   char a
+// CHECK-NEXT:    6 |   int b
+// CHECK-NEXT:   12 |   struct B (virtual base)
+// CHECK-NEXT:   12 |     long long a
+// CHECK-NEXT:      | [sizeof=20, align=4
+// CHECK-NEXT:      |  nvsize=10, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct Z
+// CHECK-X64-NEXT:    0 |   (Z vbtable pointer)
+// CHECK-X64-NEXT:    8 |   char a
+// CHECK-X64-NEXT:   10 |   int b
+// CHECK-X64-NEXT:   16 |   struct B (virtual base)
+// CHECK-X64-NEXT:   16 |     long long a
+// CHECK-X64-NEXT:      | [sizeof=24, align=4
+// CHECK-X64-NEXT:      |  nvsize=14, nvalign=4]
+
+#pragma pack(pop)
+
+struct A1 { long long a; };
+#pragma pack(push, 1)
+struct B1 : virtual A1 { char a; };
+#pragma pack(pop)
+struct C1 : B1 {};
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct C1
+// CHECK-NEXT:    0 |   struct B1 (base)
+// CHECK-NEXT:    0 |     (B1 vbtable pointer)
+// CHECK-NEXT:    4 |     char a
+// CHECK-NEXT:    8 |   struct A1 (virtual base)
+// CHECK-NEXT:    8 |     long long a
+// CHECK-NEXT:      | [sizeof=16, align=8
+// CHECK-NEXT:      |  nvsize=5, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct C1
+// CHECK-X64-NEXT:    0 |   struct B1 (base)
+// CHECK-X64-NEXT:    0 |     (B1 vbtable pointer)
+// CHECK-X64-NEXT:    8 |     char a
+// CHECK-X64-NEXT:   16 |   struct A1 (virtual base)
+// CHECK-X64-NEXT:   16 |     long long a
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=9, nvalign=8]
+
+struct CA0 {
+	CA0() {}
+};
+struct CA1 : virtual CA0 {
+	CA1() {}
+};
+#pragma pack(push, 1)
+struct CA2 : public CA1, public CA0 {
+	virtual void CA2Method() {}
+	CA2() {}
+};
+#pragma pack(pop)
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct CA2
+// CHECK-NEXT:    0 |   (CA2 vftable pointer)
+// CHECK-NEXT:    4 |   struct CA1 (base)
+// CHECK-NEXT:    4 |     (CA1 vbtable pointer)
+// CHECK-NEXT:    9 |   struct CA0 (base) (empty)
+// CHECK-NEXT:    9 |   struct CA0 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=9, align=1
+// CHECK-NEXT:      |  nvsize=9, nvalign=1]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct CA2
+// CHECK-X64-NEXT:    0 |   (CA2 vftable pointer)
+// CHECK-X64-NEXT:    8 |   struct CA1 (base)
+// CHECK-X64-NEXT:    8 |     (CA1 vbtable pointer)
+// CHECK-X64-NEXT:   17 |   struct CA0 (base) (empty)
+// CHECK-X64-NEXT:   17 |   struct CA0 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=17, align=1
+// CHECK-X64-NEXT:      |  nvsize=17, nvalign=1]
+
+#pragma pack(16)
+struct YA {
+	__declspec(align(32)) char : 1;
+};
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct YA (empty)
+// CHECK-NEXT:    0 |   char
+// CHECK-NEXT:      | [sizeof=32, align=32
+// CHECK-NEXT:      |  nvsize=32, nvalign=32]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct YA (empty)
+// CHECK-X64-NEXT:    0 |   char
+// CHECK-X64-NEXT:      | [sizeof=32, align=32
+// CHECK-X64-NEXT:      |  nvsize=32, nvalign=32]
+
+#pragma pack(1)
+struct YB {
+	char a;
+	YA b;
+};
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct YB
+// CHECK-NEXT:    0 |   char a
+// CHECK-NEXT:    1 |   struct YA b (empty)
+// CHECK-NEXT:    1 |     char
+// CHECK-NEXT:      |   [sizeof=32, align=32
+// CHECK-NEXT:      |    nvsize=32, nvalign=32]
+// CHECK-NEXT:      | [sizeof=33, align=1
+// CHECK-NEXT:      |  nvsize=33, nvalign=1]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct YB
+// CHECK-X64-NEXT:    0 |   char a
+// CHECK-X64-NEXT:    1 |   struct YA b (empty)
+// CHECK-X64-NEXT:    1 |     char
+// CHECK-X64-NEXT:      |   [sizeof=32, align=32
+// CHECK-X64-NEXT:      |    nvsize=32, nvalign=32]
+// CHECK-X64-NEXT:      | [sizeof=33, align=1
+// CHECK-X64-NEXT:      |  nvsize=33, nvalign=1]
+
+#pragma pack(8)
+struct YC {
+	__declspec(align(32)) char : 1;
+};
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct YC (empty)
+// CHECK-NEXT:    0 |   char
+// CHECK-NEXT:      | [sizeof=32, align=32
+// CHECK-NEXT:      |  nvsize=32, nvalign=32]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct YC (empty)
+// CHECK-X64-NEXT:    0 |   char
+// CHECK-X64-NEXT:      | [sizeof=8, align=32
+// CHECK-X64-NEXT:      |  nvsize=8, nvalign=32]
+
+#pragma pack(1)
+struct YD {
+	char a;
+	YC b;
+};
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct YD
+// CHECK-NEXT:    0 |   char a
+// CHECK-NEXT:    1 |   struct YC b (empty)
+// CHECK-NEXT:    1 |     char
+// CHECK-NEXT:      |   [sizeof=32, align=32
+// CHECK-NEXT:      |    nvsize=32, nvalign=32]
+// CHECK-NEXT:      | [sizeof=33, align=1
+// CHECK-NEXT:      |  nvsize=33, nvalign=1]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct YD
+// CHECK-X64-NEXT:    0 |   char a
+// CHECK-X64-NEXT:    1 |   struct YC b (empty)
+// CHECK-X64-NEXT:    1 |     char
+// CHECK-X64-NEXT:      |   [sizeof=8, align=32
+// CHECK-X64-NEXT:      |    nvsize=8, nvalign=32]
+// CHECK-X64-NEXT:      | [sizeof=9, align=1
+// CHECK-X64-NEXT:      |  nvsize=9, nvalign=1]
+
+#pragma pack(4)
+struct YE {
+	__declspec(align(32)) char : 1;
+};
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct YE (empty)
+// CHECK-NEXT:    0 |   char
+// CHECK-NEXT:      | [sizeof=4, align=32
+// CHECK-NEXT:      |  nvsize=4, nvalign=32]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct YE (empty)
+// CHECK-X64-NEXT:    0 |   char
+// CHECK-X64-NEXT:      | [sizeof=4, align=32
+// CHECK-X64-NEXT:      |  nvsize=4, nvalign=32]
+
+#pragma pack(1)
+struct YF {
+	char a;
+	YE b;
+};
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct YF
+// CHECK-NEXT:    0 |   char a
+// CHECK-NEXT:    1 |   struct YE b (empty)
+// CHECK-NEXT:    1 |     char
+// CHECK-NEXT:      |   [sizeof=4, align=32
+// CHECK-NEXT:      |    nvsize=4, nvalign=32]
+// CHECK-NEXT:      | [sizeof=5, align=1
+// CHECK-NEXT:      |  nvsize=5, nvalign=1]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct YF
+// CHECK-X64-NEXT:    0 |   char a
+// CHECK-X64-NEXT:    1 |   struct YE b (empty)
+// CHECK-X64-NEXT:    1 |     char
+// CHECK-X64-NEXT:      |   [sizeof=4, align=32
+// CHECK-X64-NEXT:      |    nvsize=4, nvalign=32]
+// CHECK-X64-NEXT:      | [sizeof=5, align=1
+// CHECK-X64-NEXT:      |  nvsize=5, nvalign=1]
+
+#pragma pack(16)
+struct __declspec(align(16)) D0 { char a; };
+#pragma pack(1)
+struct D1 : public D0 { char a; };
+#pragma pack(16)
+struct D2 : D1 { char a; };
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct D2
+// CHECK-NEXT:    0 |   struct D1 (base)
+// CHECK-NEXT:    0 |     struct D0 (base)
+// CHECK-NEXT:    0 |       char a
+// CHECK-NEXT:    1 |     char a
+// CHECK-NEXT:    2 |   char a
+// CHECK-NEXT:      | [sizeof=16, align=16
+// CHECK-NEXT:      |  nvsize=16, nvalign=16]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct D2
+// CHECK-X64-NEXT:    0 |   struct D1 (base)
+// CHECK-X64-NEXT:    0 |     struct D0 (base)
+// CHECK-X64-NEXT:    0 |       char a
+// CHECK-X64-NEXT:    1 |     char a
+// CHECK-X64-NEXT:    2 |   char a
+// CHECK-X64-NEXT:      | [sizeof=16, align=16
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=16]
+
+#pragma pack()
+struct JA { char a; };
+#pragma pack(1)
+struct JB { __declspec(align(4)) char a; };
+#pragma pack()
+struct JC : JB, JA { };
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct JC
+// CHECK-NEXT:    0 |   struct JB (base)
+// CHECK-NEXT:    0 |     char a
+// CHECK-NEXT:    1 |   struct JA (base)
+// CHECK-NEXT:    1 |     char a
+// CHECK-NEXT:      | [sizeof=4, align=4
+// CHECK-NEXT:      |  nvsize=4, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct JC
+// CHECK-X64-NEXT:    0 |   struct JB (base)
+// CHECK-X64-NEXT:    0 |     char a
+// CHECK-X64-NEXT:    1 |   struct JA (base)
+// CHECK-X64-NEXT:    1 |     char a
+// CHECK-X64-NEXT:      | [sizeof=4, align=4
+// CHECK-X64-NEXT:      |  nvsize=4, nvalign=4]
+
+#pragma pack()
+struct KA { char a; };
+#pragma pack(1)
+struct KB : KA { __declspec(align(2)) char a; };
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct KB
+// CHECK-NEXT:    0 |   struct KA (base)
+// CHECK-NEXT:    0 |     char a
+// CHECK-NEXT:    2 |   char a
+// CHECK-NEXT:      | [sizeof=4, align=2
+// CHECK-NEXT:      |  nvsize=3, nvalign=2]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct KB
+// CHECK-X64-NEXT:    0 |   struct KA (base)
+// CHECK-X64-NEXT:    0 |     char a
+// CHECK-X64-NEXT:    2 |   char a
+// CHECK-X64-NEXT:      | [sizeof=4, align=2
+// CHECK-X64-NEXT:      |  nvsize=3, nvalign=2]
+
+#pragma pack(1)
+struct L {
+  virtual void fun() {}
+  __declspec(align(256)) int Field;
+};
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct L
+// CHECK-NEXT:    0 |   (L vftable pointer)
+// CHECK-NEXT:  256 |   int Field
+// CHECK-NEXT:      | [sizeof=512, align=256
+// CHECK-NEXT:      |  nvsize=260, nvalign=256]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct L
+// CHECK-X64-NEXT:    0 |   (L vftable pointer)
+// CHECK-X64-NEXT:  256 |   int Field
+// CHECK-X64-NEXT:      | [sizeof=512, align=256
+// CHECK-X64-NEXT:      |  nvsize=260, nvalign=256]
+
+#pragma pack()
+struct MA {};
+#pragma pack(1)
+struct MB : virtual MA {
+  __declspec(align(256)) int Field;
+};
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct MB
+// CHECK-NEXT:    0 |   (MB vbtable pointer)
+// CHECK-NEXT:  256 |   int Field
+// CHECK-NEXT:  260 |   struct MA (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=512, align=256
+// CHECK-NEXT:      |  nvsize=260, nvalign=256]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct MB
+// CHECK-X64-NEXT:    0 |   (MB vbtable pointer)
+// CHECK-X64-NEXT:  256 |   int Field
+// CHECK-X64-NEXT:  260 |   struct MA (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=512, align=256
+// CHECK-X64-NEXT:      |  nvsize=260, nvalign=256]
+
+struct RA {};
+#pragma pack(1)
+struct __declspec(align(8)) RB0 { 
+	__declspec(align(1024)) int b : 3;
+};
+
+struct __declspec(align(8)) RB1 { 
+	__declspec(align(1024)) int b : 3;
+	virtual void f() {}
+};
+
+struct __declspec(align(8)) RB2 : virtual RA { 
+	__declspec(align(1024)) int b : 3;
+};
+
+struct __declspec(align(8)) RB3 : virtual RA { 
+	__declspec(align(1024)) int b : 3;
+	virtual void f() {}
+};
+
+struct RC {
+	char _;
+	__declspec(align(1024)) int c : 3;
+};
+struct RE {
+	char _;
+	RC c;
+};
+#pragma pack()
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct RB0
+// CHECK-NEXT:    0 |   int b
+// CHECK-NEXT:      | [sizeof=8, align=1024
+// CHECK-NEXT:      |  nvsize=4, nvalign=1024]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct RB1
+// CHECK-NEXT:    0 |   (RB1 vftable pointer)
+// CHECK-NEXT: 1024 |   int b
+// CHECK-NEXT:      | [sizeof=1032, align=1024
+// CHECK-NEXT:      |  nvsize=1028, nvalign=1024]
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct RB2
+// CHECK-NEXT:    0 |   (RB2 vbtable pointer)
+// CHECK-NEXT: 1024 |   int b
+// CHECK-NEXT: 1028 |   struct RA (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=1032, align=1024
+// CHECK-NEXT:      |  nvsize=1028, nvalign=1024]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct RB3
+// CHECK-NEXT:    0 |   (RB3 vftable pointer)
+// CHECK-NEXT: 1024 |   (RB3 vbtable pointer)
+// CHECK-NEXT: 2048 |   int b
+// CHECK-NEXT: 2052 |   struct RA (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=2056, align=1024
+// CHECK-NEXT:      |  nvsize=2052, nvalign=1024]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct RC
+// CHECK-NEXT:    0 |   char _
+// CHECK-NEXT: 1024 |   int c
+// CHECK-NEXT:      | [sizeof=1028, align=1024
+// CHECK-NEXT:      |  nvsize=1028, nvalign=1024]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct RE
+// CHECK-NEXT:    0 |   char _
+// CHECK-NEXT:    1 |   struct RC c
+// CHECK-NEXT:    1 |     char _
+// CHECK-NEXT: 1025 |     int c
+// CHECK-NEXT:      |   [sizeof=1028, align=1024
+// CHECK-NEXT:      |    nvsize=1028, nvalign=1024]
+// CHECK-NEXT:      | [sizeof=1029, align=1
+// CHECK-NEXT:      |  nvsize=1029, nvalign=1]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct RB0
+// CHECK-X64-NEXT:    0 |   int b
+// CHECK-X64-NEXT:      | [sizeof=8, align=1024
+// CHECK-X64-NEXT:      |  nvsize=4, nvalign=1024]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct RB1
+// CHECK-X64-NEXT:    0 |   (RB1 vftable pointer)
+// CHECK-X64-NEXT: 1024 |   int b
+// CHECK-X64-NEXT:      | [sizeof=1032, align=1024
+// CHECK-X64-NEXT:      |  nvsize=1028, nvalign=1024]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct RB2
+// CHECK-X64-NEXT:    0 |   (RB2 vbtable pointer)
+// CHECK-X64-NEXT: 1024 |   int b
+// CHECK-X64-NEXT: 1028 |   struct RA (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=1032, align=1024
+// CHECK-X64-NEXT:      |  nvsize=1028, nvalign=1024]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct RB3
+// CHECK-X64-NEXT:    0 |   (RB3 vftable pointer)
+// CHECK-X64-NEXT: 1024 |   (RB3 vbtable pointer)
+// CHECK-X64-NEXT: 2048 |   int b
+// CHECK-X64-NEXT: 2052 |   struct RA (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=2056, align=1024
+// CHECK-X64-NEXT:      |  nvsize=2052, nvalign=1024]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct RC
+// CHECK-X64-NEXT:    0 |   char _
+// CHECK-X64-NEXT: 1024 |   int c
+// CHECK-X64-NEXT:      | [sizeof=1028, align=1024
+// CHECK-X64-NEXT:      |  nvsize=1028, nvalign=1024]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct RE
+// CHECK-X64-NEXT:    0 |   char _
+// CHECK-X64-NEXT:    1 |   struct RC c
+// CHECK-X64-NEXT:    1 |     char _
+// CHECK-X64-NEXT: 1025 |     int c
+// CHECK-X64-NEXT:      |   [sizeof=1028, align=1024
+// CHECK-X64-NEXT:      |    nvsize=1028, nvalign=1024]
+// CHECK-X64-NEXT:      | [sizeof=1029, align=1
+// CHECK-X64-NEXT:      |  nvsize=1029, nvalign=1]
+
+struct NA {};
+struct NB {};
+#pragma pack(push, 1)
+struct NC : virtual NA, virtual NB {};
+#pragma pack(pop)
+struct ND : NC {};
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct NA (empty)
+// CHECK-NEXT:      | [sizeof=1, align=1
+// CHECK-NEXT:      |  nvsize=0, nvalign=1]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct NB (empty)
+// CHECK-NEXT:      | [sizeof=1, align=1
+// CHECK-NEXT:      |  nvsize=0, nvalign=1]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct NC
+// CHECK-NEXT:    0 |   (NC vbtable pointer)
+// CHECK-NEXT:    4 |   struct NA (virtual base) (empty)
+// CHECK-NEXT:    8 |   struct NB (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=8, align=1
+// CHECK-NEXT:      |  nvsize=4, nvalign=1]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct ND
+// CHECK-NEXT:    0 |   struct NC (base)
+// CHECK-NEXT:    0 |     (NC vbtable pointer)
+// CHECK-NEXT:    4 |   struct NA (virtual base) (empty)
+// CHECK-NEXT:    8 |   struct NB (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=8, align=4
+// CHECK-NEXT:      |  nvsize=4, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct NA (empty)
+// CHECK-X64-NEXT:      | [sizeof=1, align=1
+// CHECK-X64-NEXT:      |  nvsize=0, nvalign=1]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct NB (empty)
+// CHECK-X64-NEXT:      | [sizeof=1, align=1
+// CHECK-X64-NEXT:      |  nvsize=0, nvalign=1]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct NC
+// CHECK-X64-NEXT:    0 |   (NC vbtable pointer)
+// CHECK-X64-NEXT:    8 |   struct NA (virtual base) (empty)
+// CHECK-X64-NEXT:   12 |   struct NB (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=12, align=1
+// CHECK-X64-NEXT:      |  nvsize=8, nvalign=1]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct ND
+// CHECK-X64-NEXT:    0 |   struct NC (base)
+// CHECK-X64-NEXT:    0 |     (NC vbtable pointer)
+// CHECK-X64-NEXT:    8 |   struct NA (virtual base) (empty)
+// CHECK-X64-NEXT:   12 |   struct NB (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=12, align=4
+// CHECK-X64-NEXT:      |  nvsize=8, nvalign=4]
+
+struct OA {};
+struct OB {};
+struct OC : virtual OA, virtual OB {};
+#pragma pack(push, 1)
+struct OD : OC {};
+#pragma pack(pop)
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct OA (empty)
+// CHECK-NEXT:      | [sizeof=1, align=1
+// CHECK-NEXT:      |  nvsize=0, nvalign=1]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct OB (empty)
+// CHECK-NEXT:      | [sizeof=1, align=1
+// CHECK-NEXT:      |  nvsize=0, nvalign=1]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct OC
+// CHECK-NEXT:    0 |   (OC vbtable pointer)
+// CHECK-NEXT:    4 |   struct OA (virtual base) (empty)
+// CHECK-NEXT:    8 |   struct OB (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=8, align=4
+// CHECK-NEXT:      |  nvsize=4, nvalign=4]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct OD
+// CHECK-NEXT:    0 |   struct OC (base)
+// CHECK-NEXT:    0 |     (OC vbtable pointer)
+// CHECK-NEXT:    4 |   struct OA (virtual base) (empty)
+// CHECK-NEXT:    8 |   struct OB (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=8, align=1
+// CHECK-NEXT:      |  nvsize=4, nvalign=1]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct OA (empty)
+// CHECK-X64-NEXT:      | [sizeof=1, align=1
+// CHECK-X64-NEXT:      |  nvsize=0, nvalign=1]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct OB (empty)
+// CHECK-X64-NEXT:      | [sizeof=1, align=1
+// CHECK-X64-NEXT:      |  nvsize=0, nvalign=1]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct OC
+// CHECK-X64-NEXT:    0 |   (OC vbtable pointer)
+// CHECK-X64-NEXT:    8 |   struct OA (virtual base) (empty)
+// CHECK-X64-NEXT:   12 |   struct OB (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=16, align=8
+// CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct OD
+// CHECK-X64-NEXT:    0 |   struct OC (base)
+// CHECK-X64-NEXT:    0 |     (OC vbtable pointer)
+// CHECK-X64-NEXT:    8 |   struct OA (virtual base) (empty)
+// CHECK-X64-NEXT:   12 |   struct OB (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=12, align=1
+// CHECK-X64-NEXT:      |  nvsize=8, nvalign=1]
+
+
+
+int a[
+sizeof(X)+
+sizeof(Y)+
+sizeof(Z)+
+sizeof(C1)+
+sizeof(CA2)+
+sizeof(YA)+
+sizeof(YB)+
+sizeof(YC)+
+sizeof(YD)+
+sizeof(YE)+
+sizeof(YF)+
+sizeof(YF)+
+sizeof(D2)+
+sizeof(JC)+
+sizeof(KB)+
+sizeof(L)+
+sizeof(MB)+
+sizeof(RB0)+
+sizeof(RB1)+
+sizeof(RB2)+
+sizeof(RB3)+
+sizeof(RC)+
+sizeof(RE)+
+sizeof(ND)+
+sizeof(OD)+
+0];
diff --git a/test/Layout/ms-x86-primary-bases.cpp b/test/Layout/ms-x86-primary-bases.cpp
index bc9b801..b5bd041 100644
--- a/test/Layout/ms-x86-primary-bases.cpp
+++ b/test/Layout/ms-x86-primary-bases.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>/dev/null \
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>/dev/null \
 // RUN:            | FileCheck %s
-// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>/dev/null \
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>/dev/null \
 // RUN:            | FileCheck %s -check-prefix CHECK-X64
 
 extern "C" int printf(const char *fmt, ...);
@@ -16,65 +16,67 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct A
-// CHECK:    0 |   (A vbtable pointer)
-// CHECK:    4 |   struct B0 (virtual base)
-// CHECK:    4 |     (B0 vftable pointer)
-// CHECK:    8 |     int a
-// CHECK:      | [sizeof=12, align=4
-// CHECK:      |  nvsize=4, nvalign=4]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct A
+// CHECK-NEXT:    0 |   (A vbtable pointer)
+// CHECK-NEXT:    4 |   struct B0 (virtual base)
+// CHECK-NEXT:    4 |     (B0 vftable pointer)
+// CHECK-NEXT:    8 |     int a
+// CHECK-NEXT:      | [sizeof=12, align=4
+// CHECK-NEXT:      |  nvsize=4, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct A
-// CHECK-X64:    0 |   (A vbtable pointer)
-// CHECK-X64:    8 |   struct B0 (virtual base)
-// CHECK-X64:    8 |     (B0 vftable pointer)
-// CHECK-X64:   16 |     int a
-// CHECK-X64:      | [sizeof=24, align=8
-// CHECK-X64:      |  nvsize=8, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct A
+// CHECK-X64-NEXT:    0 |   (A vbtable pointer)
+// CHECK-X64-NEXT:    8 |   struct B0 (virtual base)
+// CHECK-X64-NEXT:    8 |     (B0 vftable pointer)
+// CHECK-X64-NEXT:   16 |     int a
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
 
 struct B : virtual B0 {
 	virtual void f() { printf("B"); }
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct B
-// CHECK:    0 |   (B vbtable pointer)
-// CHECK:    4 |   struct B0 (virtual base)
-// CHECK:    4 |     (B0 vftable pointer)
-// CHECK:    8 |     int a
-// CHECK:      | [sizeof=12, align=4
-// CHECK:      |  nvsize=4, nvalign=4]
+// CHECK-NEXT:    0 | struct B
+// CHECK-NEXT:    0 |   (B vbtable pointer)
+// CHECK-NEXT:    4 |   struct B0 (virtual base)
+// CHECK-NEXT:    4 |     (B0 vftable pointer)
+// CHECK-NEXT:    8 |     int a
+// CHECK-NEXT:      | [sizeof=12, align=4
+// CHECK-NEXT:      |  nvsize=4, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct B
-// CHECK-X64:    0 |   (B vbtable pointer)
-// CHECK-X64:    8 |   struct B0 (virtual base)
-// CHECK-X64:    8 |     (B0 vftable pointer)
-// CHECK-X64:   16 |     int a
-// CHECK-X64:      | [sizeof=24, align=8
-// CHECK-X64:      |  nvsize=8, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct B
+// CHECK-X64-NEXT:    0 |   (B vbtable pointer)
+// CHECK-X64-NEXT:    8 |   struct B0 (virtual base)
+// CHECK-X64-NEXT:    8 |     (B0 vftable pointer)
+// CHECK-X64-NEXT:   16 |     int a
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
 
 struct C : virtual B0 {
 	virtual void g() { printf("A"); }
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct C
-// CHECK:    0 |   (C vftable pointer)
-// CHECK:    4 |   (C vbtable pointer)
-// CHECK:    8 |   struct B0 (virtual base)
-// CHECK:    8 |     (B0 vftable pointer)
-// CHECK:   12 |     int a
-// CHECK:      | [sizeof=16, align=4
-// CHECK:      |  nvsize=8, nvalign=4]
+// CHECK-NEXT:    0 | struct C
+// CHECK-NEXT:    0 |   (C vftable pointer)
+// CHECK-NEXT:    4 |   (C vbtable pointer)
+// CHECK-NEXT:    8 |   struct B0 (virtual base)
+// CHECK-NEXT:    8 |     (B0 vftable pointer)
+// CHECK-NEXT:   12 |     int a
+// CHECK-NEXT:      | [sizeof=16, align=4
+// CHECK-NEXT:      |  nvsize=8, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct C
-// CHECK-X64:    0 |   (C vftable pointer)
-// CHECK-X64:    8 |   (C vbtable pointer)
-// CHECK-X64:   16 |   struct B0 (virtual base)
-// CHECK-X64:   16 |     (B0 vftable pointer)
-// CHECK-X64:   24 |     int a
-// CHECK-X64:      | [sizeof=32, align=8
-// CHECK-X64:      |  nvsize=16, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct C
+// CHECK-X64-NEXT:    0 |   (C vftable pointer)
+// CHECK-X64-NEXT:    8 |   (C vbtable pointer)
+// CHECK-X64-NEXT:   16 |   struct B0 (virtual base)
+// CHECK-X64-NEXT:   16 |     (B0 vftable pointer)
+// CHECK-X64-NEXT:   24 |     int a
+// CHECK-X64-NEXT:      | [sizeof=32, align=8
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
 
 struct D : virtual B2, virtual B0 {
 	virtual void f() { printf("D"); }
@@ -82,27 +84,29 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct D
-// CHECK:    0 |   (D vftable pointer)
-// CHECK:    4 |   (D vbtable pointer)
-// CHECK:    8 |   struct B2 (virtual base)
-// CHECK:    8 |     int a
-// CHECK:   12 |   struct B0 (virtual base)
-// CHECK:   12 |     (B0 vftable pointer)
-// CHECK:   16 |     int a
-// CHECK:      | [sizeof=20, align=4
-// CHECK:      |  nvsize=8, nvalign=4]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct D
+// CHECK-NEXT:    0 |   (D vftable pointer)
+// CHECK-NEXT:    4 |   (D vbtable pointer)
+// CHECK-NEXT:    8 |   struct B2 (virtual base)
+// CHECK-NEXT:    8 |     int a
+// CHECK-NEXT:   12 |   struct B0 (virtual base)
+// CHECK-NEXT:   12 |     (B0 vftable pointer)
+// CHECK-NEXT:   16 |     int a
+// CHECK-NEXT:      | [sizeof=20, align=4
+// CHECK-NEXT:      |  nvsize=8, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct D
-// CHECK-X64:    0 |   (D vftable pointer)
-// CHECK-X64:    8 |   (D vbtable pointer)
-// CHECK-X64:   16 |   struct B2 (virtual base)
-// CHECK-X64:   16 |     int a
-// CHECK-X64:   24 |   struct B0 (virtual base)
-// CHECK-X64:   24 |     (B0 vftable pointer)
-// CHECK-X64:   32 |     int a
-// CHECK-X64:      | [sizeof=40, align=8
-// CHECK-X64:      |  nvsize=16, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct D
+// CHECK-X64-NEXT:    0 |   (D vftable pointer)
+// CHECK-X64-NEXT:    8 |   (D vbtable pointer)
+// CHECK-X64-NEXT:   16 |   struct B2 (virtual base)
+// CHECK-X64-NEXT:   16 |     int a
+// CHECK-X64-NEXT:   24 |   struct B0 (virtual base)
+// CHECK-X64-NEXT:   24 |     (B0 vftable pointer)
+// CHECK-X64-NEXT:   32 |     int a
+// CHECK-X64-NEXT:      | [sizeof=40, align=8
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
 
 struct E : B0, virtual B1 {
 	virtual void f() { printf("E"); }
@@ -110,197 +114,205 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct E
-// CHECK:    0 |   struct B0 (primary base)
-// CHECK:    0 |     (B0 vftable pointer)
-// CHECK:    4 |     int a
-// CHECK:    8 |   (E vbtable pointer)
-// CHECK:   12 |   struct B1 (virtual base)
-// CHECK:   12 |     (B1 vftable pointer)
-// CHECK:   16 |     int a
-// CHECK:      | [sizeof=20, align=4
-// CHECK:      |  nvsize=12, nvalign=4]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct E
+// CHECK-NEXT:    0 |   struct B0 (primary base)
+// CHECK-NEXT:    0 |     (B0 vftable pointer)
+// CHECK-NEXT:    4 |     int a
+// CHECK-NEXT:    8 |   (E vbtable pointer)
+// CHECK-NEXT:   12 |   struct B1 (virtual base)
+// CHECK-NEXT:   12 |     (B1 vftable pointer)
+// CHECK-NEXT:   16 |     int a
+// CHECK-NEXT:      | [sizeof=20, align=4
+// CHECK-NEXT:      |  nvsize=12, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct E
-// CHECK-X64:    0 |   struct B0 (primary base)
-// CHECK-X64:    0 |     (B0 vftable pointer)
-// CHECK-X64:    8 |     int a
-// CHECK-X64:   16 |   (E vbtable pointer)
-// CHECK-X64:   24 |   struct B1 (virtual base)
-// CHECK-X64:   24 |     (B1 vftable pointer)
-// CHECK-X64:   32 |     int a
-// CHECK-X64:      | [sizeof=40, align=8
-// CHECK-X64:      |  nvsize=24, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct E
+// CHECK-X64-NEXT:    0 |   struct B0 (primary base)
+// CHECK-X64-NEXT:    0 |     (B0 vftable pointer)
+// CHECK-X64-NEXT:    8 |     int a
+// CHECK-X64-NEXT:   16 |   (E vbtable pointer)
+// CHECK-X64-NEXT:   24 |   struct B1 (virtual base)
+// CHECK-X64-NEXT:   24 |     (B1 vftable pointer)
+// CHECK-X64-NEXT:   32 |     int a
+// CHECK-X64-NEXT:      | [sizeof=40, align=8
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
 
 struct F : virtual B0, virtual B1 {
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct F
-// CHECK:    0 |   (F vbtable pointer)
-// CHECK:    4 |   struct B0 (virtual base)
-// CHECK:    4 |     (B0 vftable pointer)
-// CHECK:    8 |     int a
-// CHECK:   12 |   struct B1 (virtual base)
-// CHECK:   12 |     (B1 vftable pointer)
-// CHECK:   16 |     int a
-// CHECK:      | [sizeof=20, align=4
-// CHECK:      |  nvsize=4, nvalign=4]
+// CHECK-NEXT:    0 | struct F
+// CHECK-NEXT:    0 |   (F vbtable pointer)
+// CHECK-NEXT:    4 |   struct B0 (virtual base)
+// CHECK-NEXT:    4 |     (B0 vftable pointer)
+// CHECK-NEXT:    8 |     int a
+// CHECK-NEXT:   12 |   struct B1 (virtual base)
+// CHECK-NEXT:   12 |     (B1 vftable pointer)
+// CHECK-NEXT:   16 |     int a
+// CHECK-NEXT:      | [sizeof=20, align=4
+// CHECK-NEXT:      |  nvsize=4, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct F
-// CHECK-X64:    0 |   (F vbtable pointer)
-// CHECK-X64:    8 |   struct B0 (virtual base)
-// CHECK-X64:    8 |     (B0 vftable pointer)
-// CHECK-X64:   16 |     int a
-// CHECK-X64:   24 |   struct B1 (virtual base)
-// CHECK-X64:   24 |     (B1 vftable pointer)
-// CHECK-X64:   32 |     int a
-// CHECK-X64:      | [sizeof=40, align=8
-// CHECK-X64:      |  nvsize=8, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct F
+// CHECK-X64-NEXT:    0 |   (F vbtable pointer)
+// CHECK-X64-NEXT:    8 |   struct B0 (virtual base)
+// CHECK-X64-NEXT:    8 |     (B0 vftable pointer)
+// CHECK-X64-NEXT:   16 |     int a
+// CHECK-X64-NEXT:   24 |   struct B1 (virtual base)
+// CHECK-X64-NEXT:   24 |     (B1 vftable pointer)
+// CHECK-X64-NEXT:   32 |     int a
+// CHECK-X64-NEXT:      | [sizeof=40, align=8
+// CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
 
 struct AX : B0X, B1X { int a; AX() : a(0xf000000A) {} virtual void f() { printf("A"); } };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct AX
-// CHECK:    8 |   struct B0X (base)
-// CHECK:    8 |     int a
-// CHECK:    0 |   struct B1X (primary base)
-// CHECK:    0 |     (B1X vftable pointer)
-// CHECK:    4 |     int a
-// CHECK:   12 |   int a
-// CHECK:      | [sizeof=16, align=4
-// CHECK:      |  nvsize=16, nvalign=4]
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct AX
+// CHECK-NEXT:    0 |   struct B1X (primary base)
+// CHECK-NEXT:    0 |     (B1X vftable pointer)
+// CHECK-NEXT:    4 |     int a
+// CHECK-NEXT:    8 |   struct B0X (base)
+// CHECK-NEXT:    8 |     int a
+// CHECK-NEXT:   12 |   int a
+// CHECK-NEXT:      | [sizeof=16, align=4
+// CHECK-NEXT:      |  nvsize=16, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct AX
-// CHECK-X64:   16 |   struct B0X (base)
-// CHECK-X64:   16 |     int a
-// CHECK-X64:    0 |   struct B1X (primary base)
-// CHECK-X64:    0 |     (B1X vftable pointer)
-// CHECK-X64:    8 |     int a
-// CHECK-X64:   20 |   int a
-// CHECK-X64:      | [sizeof=24, align=8
-// CHECK-X64:      |  nvsize=24, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct AX
+// CHECK-X64-NEXT:    0 |   struct B1X (primary base)
+// CHECK-X64-NEXT:    0 |     (B1X vftable pointer)
+// CHECK-X64-NEXT:    8 |     int a
+// CHECK-X64-NEXT:   16 |   struct B0X (base)
+// CHECK-X64-NEXT:   16 |     int a
+// CHECK-X64-NEXT:   20 |   int a
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
 
 struct BX : B0X, B1X { int a; BX() : a(0xf000000B) {} virtual void g() { printf("B"); } };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct BX
-// CHECK:    8 |   struct B0X (base)
-// CHECK:    8 |     int a
-// CHECK:    0 |   struct B1X (primary base)
-// CHECK:    0 |     (B1X vftable pointer)
-// CHECK:    4 |     int a
-// CHECK:   12 |   int a
-// CHECK:      | [sizeof=16, align=4
-// CHECK:      |  nvsize=16, nvalign=4]
-// CHECK-x64: *** Dumping AST Record Layout
-// CHECK-x64:    0 | struct BX
-// CHECK-x64:   16 |   struct B0X (base)
-// CHECK-x64:   16 |     int a
-// CHECK-x64:    0 |   struct B1X (primary base)
-// CHECK-x64:    0 |     (B1X vftable pointer)
-// CHECK-x64:    8 |     int a
-// CHECK-x64:   24 |   int a
-// CHECK-x64:      | [sizeof=24, align=8
-// CHECK-x64:      |  nvsize=24, nvalign=8]
+// CHECK-NEXT:    0 | struct BX
+// CHECK-NEXT:    0 |   struct B1X (primary base)
+// CHECK-NEXT:    0 |     (B1X vftable pointer)
+// CHECK-NEXT:    4 |     int a
+// CHECK-NEXT:    8 |   struct B0X (base)
+// CHECK-NEXT:    8 |     int a
+// CHECK-NEXT:   12 |   int a
+// CHECK-NEXT:      | [sizeof=16, align=4
+// CHECK-NEXT:      |  nvsize=16, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct BX
+// CHECK-X64-NEXT:    0 |   struct B1X (primary base)
+// CHECK-X64-NEXT:    0 |     (B1X vftable pointer)
+// CHECK-X64-NEXT:    8 |     int a
+// CHECK-X64-NEXT:   16 |   struct B0X (base)
+// CHECK-X64-NEXT:   16 |     int a
+// CHECK-X64-NEXT:   20 |   int a
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
 
 struct CX : B0X, B2X { int a; CX() : a(0xf000000C) {} virtual void g() { printf("C"); } };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct CX
-// CHECK:    0 |   (CX vftable pointer)
-// CHECK:    4 |   struct B0X (base)
-// CHECK:    4 |     int a
-// CHECK:    8 |   struct B2X (base)
-// CHECK:    8 |     (B2X vbtable pointer)
-// CHECK:   12 |     int a
-// CHECK:   16 |   int a
-// CHECK:   20 |   struct B1X (virtual base)
-// CHECK:   20 |     (B1X vftable pointer)
-// CHECK:   24 |     int a
-// CHECK:      | [sizeof=28, align=4
-// CHECK:      |  nvsize=20, nvalign=4]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct CX
+// CHECK-NEXT:    0 |   (CX vftable pointer)
+// CHECK-NEXT:    4 |   struct B0X (base)
+// CHECK-NEXT:    4 |     int a
+// CHECK-NEXT:    8 |   struct B2X (base)
+// CHECK-NEXT:    8 |     (B2X vbtable pointer)
+// CHECK-NEXT:   12 |     int a
+// CHECK-NEXT:   16 |   int a
+// CHECK-NEXT:   20 |   struct B1X (virtual base)
+// CHECK-NEXT:   20 |     (B1X vftable pointer)
+// CHECK-NEXT:   24 |     int a
+// CHECK-NEXT:      | [sizeof=28, align=4
+// CHECK-NEXT:      |  nvsize=20, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct CX
-// CHECK-X64:    0 |   (CX vftable pointer)
-// CHECK-X64:    8 |   struct B0X (base)
-// CHECK-X64:    8 |     int a
-// CHECK-X64:   16 |   struct B2X (base)
-// CHECK-X64:   16 |     (B2X vbtable pointer)
-// CHECK-X64:   24 |     int a
-// CHECK-X64:   32 |   int a
-// CHECK-X64:   40 |   struct B1X (virtual base)
-// CHECK-X64:   40 |     (B1X vftable pointer)
-// CHECK-X64:   48 |     int a
-// CHECK-X64:      | [sizeof=56, align=8
-// CHECK-X64:      |  nvsize=40, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct CX
+// CHECK-X64-NEXT:    0 |   (CX vftable pointer)
+// CHECK-X64-NEXT:    8 |   struct B0X (base)
+// CHECK-X64-NEXT:    8 |     int a
+// CHECK-X64-NEXT:   16 |   struct B2X (base)
+// CHECK-X64-NEXT:   16 |     (B2X vbtable pointer)
+// CHECK-X64-NEXT:   24 |     int a
+// CHECK-X64-NEXT:   32 |   int a
+// CHECK-X64-NEXT:   40 |   struct B1X (virtual base)
+// CHECK-X64-NEXT:   40 |     (B1X vftable pointer)
+// CHECK-X64-NEXT:   48 |     int a
+// CHECK-X64-NEXT:      | [sizeof=56, align=8
+// CHECK-X64-NEXT:      |  nvsize=40, nvalign=8]
 
 struct DX : virtual B1X { int a; DX() : a(0xf000000D) {} virtual void f() { printf("D"); } };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct DX
-// CHECK:    0 |   (DX vbtable pointer)
-// CHECK:    4 |   int a
-// CHECK:    8 |   (vtordisp for vbase B1X)
-// CHECK:   12 |   struct B1X (virtual base)
-// CHECK:   12 |     (B1X vftable pointer)
-// CHECK:   16 |     int a
-// CHECK:      | [sizeof=20, align=4
-// CHECK:      |  nvsize=8, nvalign=4]
+// CHECK-NEXT:    0 | struct DX
+// CHECK-NEXT:    0 |   (DX vbtable pointer)
+// CHECK-NEXT:    4 |   int a
+// CHECK-NEXT:    8 |   (vtordisp for vbase B1X)
+// CHECK-NEXT:   12 |   struct B1X (virtual base)
+// CHECK-NEXT:   12 |     (B1X vftable pointer)
+// CHECK-NEXT:   16 |     int a
+// CHECK-NEXT:      | [sizeof=20, align=4
+// CHECK-NEXT:      |  nvsize=8, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct DX
-// CHECK-X64:    0 |   (DX vbtable pointer)
-// CHECK-X64:    8 |   int a
-// CHECK-X64:   20 |   (vtordisp for vbase B1X)
-// CHECK-X64:   24 |   struct B1X (virtual base)
-// CHECK-X64:   24 |     (B1X vftable pointer)
-// CHECK-X64:   32 |     int a
-// CHECK-X64:      | [sizeof=40, align=8
-// CHECK-X64:      |  nvsize=16, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct DX
+// CHECK-X64-NEXT:    0 |   (DX vbtable pointer)
+// CHECK-X64-NEXT:    8 |   int a
+// CHECK-X64-NEXT:   20 |   (vtordisp for vbase B1X)
+// CHECK-X64-NEXT:   24 |   struct B1X (virtual base)
+// CHECK-X64-NEXT:   24 |     (B1X vftable pointer)
+// CHECK-X64-NEXT:   32 |     int a
+// CHECK-X64-NEXT:      | [sizeof=40, align=8
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
 
 struct EX : virtual B1X { int a; EX() : a(0xf000000E) {} virtual void g() { printf("E"); } };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct EX
-// CHECK:    0 |   (EX vftable pointer)
-// CHECK:    4 |   (EX vbtable pointer)
-// CHECK:    8 |   int a
-// CHECK:   12 |   struct B1X (virtual base)
-// CHECK:   12 |     (B1X vftable pointer)
-// CHECK:   16 |     int a
-// CHECK:      | [sizeof=20, align=4
-// CHECK:      |  nvsize=12, nvalign=4]
+// CHECK-NEXT:    0 | struct EX
+// CHECK-NEXT:    0 |   (EX vftable pointer)
+// CHECK-NEXT:    4 |   (EX vbtable pointer)
+// CHECK-NEXT:    8 |   int a
+// CHECK-NEXT:   12 |   struct B1X (virtual base)
+// CHECK-NEXT:   12 |     (B1X vftable pointer)
+// CHECK-NEXT:   16 |     int a
+// CHECK-NEXT:      | [sizeof=20, align=4
+// CHECK-NEXT:      |  nvsize=12, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct EX
-// CHECK-X64:    0 |   (EX vftable pointer)
-// CHECK-X64:    8 |   (EX vbtable pointer)
-// CHECK-X64:   16 |   int a
-// CHECK-X64:   24 |   struct B1X (virtual base)
-// CHECK-X64:   24 |     (B1X vftable pointer)
-// CHECK-X64:   32 |     int a
-// CHECK-X64:      | [sizeof=40, align=8
-// CHECK-X64:      |  nvsize=24, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct EX
+// CHECK-X64-NEXT:    0 |   (EX vftable pointer)
+// CHECK-X64-NEXT:    8 |   (EX vbtable pointer)
+// CHECK-X64-NEXT:   16 |   int a
+// CHECK-X64-NEXT:   24 |   struct B1X (virtual base)
+// CHECK-X64-NEXT:   24 |     (B1X vftable pointer)
+// CHECK-X64-NEXT:   32 |     int a
+// CHECK-X64-NEXT:      | [sizeof=40, align=8
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
 
 struct FX : virtual B1X { int a; FX() : a(0xf000000F) {} };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct FX
-// CHECK:    0 |   (FX vbtable pointer)
-// CHECK:    4 |   int a
-// CHECK:    8 |   struct B1X (virtual base)
-// CHECK:    8 |     (B1X vftable pointer)
-// CHECK:   12 |     int a
-// CHECK:      | [sizeof=16, align=4
-// CHECK:      |  nvsize=8, nvalign=4]
+// CHECK-NEXT:    0 | struct FX
+// CHECK-NEXT:    0 |   (FX vbtable pointer)
+// CHECK-NEXT:    4 |   int a
+// CHECK-NEXT:    8 |   struct B1X (virtual base)
+// CHECK-NEXT:    8 |     (B1X vftable pointer)
+// CHECK-NEXT:   12 |     int a
+// CHECK-NEXT:      | [sizeof=16, align=4
+// CHECK-NEXT:      |  nvsize=8, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct FX
-// CHECK-X64:    0 |   (FX vbtable pointer)
-// CHECK-X64:    8 |   int a
-// CHECK-X64:   16 |   struct B1X (virtual base)
-// CHECK-X64:   16 |     (B1X vftable pointer)
-// CHECK-X64:   24 |     int a
-// CHECK-X64:      | [sizeof=32, align=8
-// CHECK-X64:      |  nvsize=16, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct FX
+// CHECK-X64-NEXT:    0 |   (FX vbtable pointer)
+// CHECK-X64-NEXT:    8 |   int a
+// CHECK-X64-NEXT:   16 |   struct B1X (virtual base)
+// CHECK-X64-NEXT:   16 |     (B1X vftable pointer)
+// CHECK-X64-NEXT:   24 |     int a
+// CHECK-X64-NEXT:      | [sizeof=32, align=8
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
 
 int a[
 sizeof(A)+
diff --git a/test/Layout/ms-x86-size-alignment-fail.cpp b/test/Layout/ms-x86-size-alignment-fail.cpp
index f998ee1..7e975b0 100644
--- a/test/Layout/ms-x86-size-alignment-fail.cpp
+++ b/test/Layout/ms-x86-size-alignment-fail.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -cxx-abi microsoft %s 2>/dev/null \
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts %s 2>/dev/null \
 // RUN:            | FileCheck %s
-// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -cxx-abi microsoft %s 2>/dev/null \
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts %s 2>/dev/null \
 // RUN:            | FileCheck %s -check-prefix CHECK-X64
 
 extern "C" int printf(const char *fmt, ...);
@@ -11,108 +11,112 @@
 struct A : virtual B0 {};
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct A
-// CHECK:    0 |   (A vbtable pointer)
-// CHECK:    4 |   struct B0 (virtual base)
-// CHECK:    4 |     char a
-// CHECK:      | [sizeof=5, align=4
-// CHECK:      |  nvsize=4, nvalign=4]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct A
+// CHECK-NEXT:    0 |   (A vbtable pointer)
+// CHECK-NEXT:    4 |   struct B0 (virtual base)
+// CHECK-NEXT:    4 |     char a
+// CHECK-NEXT:      | [sizeof=5, align=4
+// CHECK-NEXT:      |  nvsize=4, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct A
-// CHECK-X64:    0 |   (A vbtable pointer)
-// CHECK-X64:    8 |   struct B0 (virtual base)
-// CHECK-X64:    8 |     char a
-// CHECK-X64:      | [sizeof=16, align=8
-// CHECK-X64:      |  nvsize=8, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct A
+// CHECK-X64-NEXT:    0 |   (A vbtable pointer)
+// CHECK-X64-NEXT:    8 |   struct B0 (virtual base)
+// CHECK-X64-NEXT:    8 |     char a
+// CHECK-X64-NEXT:      | [sizeof=16, align=8
+// CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
 
 struct __declspec(align(1)) B : virtual B0 {};
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct B
-// CHECK:    0 |   (B vbtable pointer)
-// CHECK:    4 |   struct B0 (virtual base)
-// CHECK:    4 |     char a
-// CHECK:      | [sizeof=8, align=4
-// CHECK:      |  nvsize=4, nvalign=4]
+// CHECK-NEXT:    0 | struct B
+// CHECK-NEXT:    0 |   (B vbtable pointer)
+// CHECK-NEXT:    4 |   struct B0 (virtual base)
+// CHECK-NEXT:    4 |     char a
+// CHECK-NEXT:      | [sizeof=8, align=4
+// CHECK-NEXT:      |  nvsize=4, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct B
-// CHECK-X64:    0 |   (B vbtable pointer)
-// CHECK-X64:    8 |   struct B0 (virtual base)
-// CHECK-X64:    8 |     char a
-// CHECK-X64:      | [sizeof=16, align=8
-// CHECK-X64:      |  nvsize=8, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct B
+// CHECK-X64-NEXT:    0 |   (B vbtable pointer)
+// CHECK-X64-NEXT:    8 |   struct B0 (virtual base)
+// CHECK-X64-NEXT:    8 |     char a
+// CHECK-X64-NEXT:      | [sizeof=16, align=8
+// CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
 
 struct C : virtual B0 { int a; C() : a(0xC) {} };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct C
-// CHECK:    0 |   (C vbtable pointer)
-// CHECK:    4 |   int a
-// CHECK:    8 |   struct B0 (virtual base)
-// CHECK:    8 |     char a
-// CHECK:      | [sizeof=9, align=4
-// CHECK:      |  nvsize=8, nvalign=4]
+// CHECK-NEXT:    0 | struct C
+// CHECK-NEXT:    0 |   (C vbtable pointer)
+// CHECK-NEXT:    4 |   int a
+// CHECK-NEXT:    8 |   struct B0 (virtual base)
+// CHECK-NEXT:    8 |     char a
+// CHECK-NEXT:      | [sizeof=9, align=4
+// CHECK-NEXT:      |  nvsize=8, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct C
-// CHECK-X64:    0 |   (C vbtable pointer)
-// CHECK-X64:    8 |   int a
-// CHECK-X64:   16 |   struct B0 (virtual base)
-// CHECK-X64:   16 |     char a
-// CHECK-X64:      | [sizeof=24, align=8
-// CHECK-X64:      |  nvsize=16, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct C
+// CHECK-X64-NEXT:    0 |   (C vbtable pointer)
+// CHECK-X64-NEXT:    8 |   int a
+// CHECK-X64-NEXT:   16 |   struct B0 (virtual base)
+// CHECK-X64-NEXT:   16 |     char a
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
 
 struct D : virtual B0 { __declspec(align(1)) int a; D() : a(0xD) {} };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct D
-// CHECK:    0 |   (D vbtable pointer)
-// CHECK:    4 |   int a
-// CHECK:    8 |   struct B0 (virtual base)
-// CHECK:    8 |     char a
-// CHECK:      | [sizeof=12, align=4
-// CHECK:      |  nvsize=8, nvalign=4]
+// CHECK-NEXT:    0 | struct D
+// CHECK-NEXT:    0 |   (D vbtable pointer)
+// CHECK-NEXT:    4 |   int a
+// CHECK-NEXT:    8 |   struct B0 (virtual base)
+// CHECK-NEXT:    8 |     char a
+// CHECK-NEXT:      | [sizeof=12, align=4
+// CHECK-NEXT:      |  nvsize=8, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct D
-// CHECK-X64:    0 |   (D vbtable pointer)
-// CHECK-X64:    8 |   int a
-// CHECK-X64:   16 |   struct B0 (virtual base)
-// CHECK-X64:   16 |     char a
-// CHECK-X64:      | [sizeof=24, align=8
-// CHECK-X64:      |  nvsize=16, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct D
+// CHECK-X64-NEXT:    0 |   (D vbtable pointer)
+// CHECK-X64-NEXT:    8 |   int a
+// CHECK-X64-NEXT:   16 |   struct B0 (virtual base)
+// CHECK-X64-NEXT:   16 |     char a
+// CHECK-X64-NEXT:      | [sizeof=24, align=8
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
 
 struct E : virtual B0, virtual B1 {};
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct E
-// CHECK:    0 |   (E vbtable pointer)
-// CHECK:    4 |   struct B0 (virtual base)
-// CHECK:    4 |     char a
-// CHECK:    5 |   struct B1 (virtual base) (empty)
-// CHECK:      | [sizeof=8, align=4
-// CHECK:      |  nvsize=4, nvalign=4]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct E
+// CHECK-NEXT:    0 |   (E vbtable pointer)
+// CHECK-NEXT:    4 |   struct B0 (virtual base)
+// CHECK-NEXT:    4 |     char a
+// CHECK-NEXT:    5 |   struct B1 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=8, align=4
+// CHECK-NEXT:      |  nvsize=4, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct E
-// CHECK-X64:    0 |   (E vbtable pointer)
-// CHECK-X64:    8 |   struct B0 (virtual base)
-// CHECK-X64:    8 |     char a
-// CHECK-X64:    9 |   struct B1 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=16, align=8
-// CHECK-X64:      |  nvsize=8, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct E
+// CHECK-X64-NEXT:    0 |   (E vbtable pointer)
+// CHECK-X64-NEXT:    8 |   struct B0 (virtual base)
+// CHECK-X64-NEXT:    8 |     char a
+// CHECK-X64-NEXT:    9 |   struct B1 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=16, align=8
+// CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
 
 struct F { char a; virtual ~F(); };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct F
-// CHECK:    0 |   (F vftable pointer)
-// CHECK:    4 |   char a
-// CHECK:      | [sizeof=8, align=4
-// CHECK:      |  nvsize=8, nvalign=4]
+// CHECK-NEXT:    0 | struct F
+// CHECK-NEXT:    0 |   (F vftable pointer)
+// CHECK-NEXT:    4 |   char a
+// CHECK-NEXT:      | [sizeof=8, align=4
+// CHECK-NEXT:      |  nvsize=8, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct F
-// CHECK-X64:    0 |   (F vftable pointer)
-// CHECK-X64:    8 |   char a
-// CHECK-X64:      | [sizeof=16, align=8
-// CHECK-X64:      |  nvsize=16, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct F
+// CHECK-X64-NEXT:    0 |   (F vftable pointer)
+// CHECK-X64-NEXT:    8 |   char a
+// CHECK-X64-NEXT:      | [sizeof=16, align=8
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
 
 int a[
 sizeof(A)+
diff --git a/test/Layout/ms-x86-vfvb-alignment.cpp b/test/Layout/ms-x86-vfvb-alignment.cpp
index 8eea209..54f74ac 100644
--- a/test/Layout/ms-x86-vfvb-alignment.cpp
+++ b/test/Layout/ms-x86-vfvb-alignment.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>&1 \
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>&1 \
 // RUN:            | FileCheck %s
-// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>/dev/null \
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>/dev/null \
 // RUN:            | FileCheck %s -check-prefix CHECK-X64
 
 extern "C" int printf(const char *fmt, ...);
@@ -16,349 +16,361 @@
 struct A : B0, virtual B1 { __declspec(align(16)) int a; A() : a(0xf000000A) {} virtual void f() { printf("A"); } };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct A
-// CHECK:    0 |   (A vftable pointer)
-// CHECK:   16 |   struct B0 (base)
-// CHECK:   16 |     int a
-// CHECK:   20 |   (A vbtable pointer)
-// CHECK:   48 |   int a
-// CHECK:   64 |   struct B1 (virtual base)
-// CHECK:   64 |     char a
-// CHECK:      | [sizeof=80, align=16
-// CHECK:      |  nvsize=64, nvalign=16]
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct A
+// CHECK-NEXT:    0 |   (A vftable pointer)
+// CHECK-NEXT:   16 |   struct B0 (base)
+// CHECK-NEXT:   16 |     int a
+// CHECK-NEXT:   20 |   (A vbtable pointer)
+// CHECK-NEXT:   48 |   int a
+// CHECK-NEXT:   64 |   struct B1 (virtual base)
+// CHECK-NEXT:   64 |     char a
+// CHECK-NEXT:      | [sizeof=80, align=16
+// CHECK-NEXT:      |  nvsize=64, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct A
-// CHECK-X64:    0 |   (A vftable pointer)
-// CHECK-X64:    8 |   struct B0 (base)
-// CHECK-X64:    8 |     int a
-// CHECK-X64:   16 |   (A vbtable pointer)
-// CHECK-X64:   32 |   int a
-// CHECK-X64:   48 |   struct B1 (virtual base)
-// CHECK-X64:   48 |     char a
-// CHECK-X64:      | [sizeof=64, align=16
-// CHECK-X64:      |  nvsize=48, nvalign=16]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct A
+// CHECK-X64-NEXT:    0 |   (A vftable pointer)
+// CHECK-X64-NEXT:   16 |   struct B0 (base)
+// CHECK-X64-NEXT:   16 |     int a
+// CHECK-X64-NEXT:   24 |   (A vbtable pointer)
+// CHECK-X64-NEXT:   48 |   int a
+// CHECK-X64-NEXT:   64 |   struct B1 (virtual base)
+// CHECK-X64-NEXT:   64 |     char a
+// CHECK-X64-NEXT:      | [sizeof=80, align=16
+// CHECK-X64-NEXT:      |  nvsize=64, nvalign=16]
 
 struct B : A, B2 { int a; B() : a(0xf000000B) {} virtual void f() { printf("B"); } };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct B
-// CHECK:    0 |   struct A (primary base)
-// CHECK:    0 |     (A vftable pointer)
-// CHECK:   16 |     struct B0 (base)
-// CHECK:   16 |       int a
-// CHECK:   20 |     (A vbtable pointer)
-// CHECK:   48 |     int a
-// CHECK:   64 |   struct B2 (base)
-// CHECK:   64 |     (B2 vbtable pointer)
-// CHECK:   68 |     int a
-// CHECK:   72 |   int a
-// CHECK:   80 |   struct B1 (virtual base)
-// CHECK:   80 |     char a
-// CHECK:      | [sizeof=96, align=16
-// CHECK:      |  nvsize=80, nvalign=16]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct B
+// CHECK-NEXT:    0 |   struct A (primary base)
+// CHECK-NEXT:    0 |     (A vftable pointer)
+// CHECK-NEXT:   16 |     struct B0 (base)
+// CHECK-NEXT:   16 |       int a
+// CHECK-NEXT:   20 |     (A vbtable pointer)
+// CHECK-NEXT:   48 |     int a
+// CHECK-NEXT:   64 |   struct B2 (base)
+// CHECK-NEXT:   64 |     (B2 vbtable pointer)
+// CHECK-NEXT:   68 |     int a
+// CHECK-NEXT:   72 |   int a
+// CHECK-NEXT:   80 |   struct B1 (virtual base)
+// CHECK-NEXT:   80 |     char a
+// CHECK-NEXT:      | [sizeof=96, align=16
+// CHECK-NEXT:      |  nvsize=80, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct B
-// CHECK-X64:    0 |   struct A (primary base)
-// CHECK-X64:    0 |     (A vftable pointer)
-// CHECK-X64:    8 |     struct B0 (base)
-// CHECK-X64:    8 |       int a
-// CHECK-X64:   16 |     (A vbtable pointer)
-// CHECK-X64:   32 |     int a
-// CHECK-X64:   48 |   struct B2 (base)
-// CHECK-X64:   48 |     (B2 vbtable pointer)
-// CHECK-X64:   56 |     int a
-// CHECK-X64:   64 |   int a
-// CHECK-X64:   80 |   struct B1 (virtual base)
-// CHECK-X64:   80 |     char a
-// CHECK-X64:      | [sizeof=96, align=16
-// CHECK-X64:      |  nvsize=80, nvalign=16]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct B
+// CHECK-X64-NEXT:    0 |   struct A (primary base)
+// CHECK-X64-NEXT:    0 |     (A vftable pointer)
+// CHECK-X64-NEXT:   16 |     struct B0 (base)
+// CHECK-X64-NEXT:   16 |       int a
+// CHECK-X64-NEXT:   24 |     (A vbtable pointer)
+// CHECK-X64-NEXT:   48 |     int a
+// CHECK-X64-NEXT:   64 |   struct B2 (base)
+// CHECK-X64-NEXT:   64 |     (B2 vbtable pointer)
+// CHECK-X64-NEXT:   72 |     int a
+// CHECK-X64-NEXT:   80 |   int a
+// CHECK-X64-NEXT:   96 |   struct B1 (virtual base)
+// CHECK-X64-NEXT:   96 |     char a
+// CHECK-X64-NEXT:      | [sizeof=112, align=16
+// CHECK-X64-NEXT:      |  nvsize=96, nvalign=16]
 
 struct C : B4 { int a; C() : a(0xf000000C) {} virtual void f() { printf("C"); } };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct C
-// CHECK:    0 |   (C vftable pointer)
-// CHECK:   16 |   struct B4 (base)
-// CHECK:   16 |     (B4 vbtable pointer)
-// CHECK:   20 |     int a
-// CHECK:   24 |   int a
-// CHECK:   32 |   struct B3 (virtual base)
-// CHECK:   32 |     int a
-// CHECK:      | [sizeof=48, align=16
-// CHECK:      |  nvsize=32, nvalign=16]
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct C
+// CHECK-NEXT:    0 |   (C vftable pointer)
+// CHECK-NEXT:   16 |   struct B4 (base)
+// CHECK-NEXT:   16 |     (B4 vbtable pointer)
+// CHECK-NEXT:   20 |     int a
+// CHECK-NEXT:   24 |   int a
+// CHECK-NEXT:   32 |   struct B3 (virtual base)
+// CHECK-NEXT:   32 |     int a
+// CHECK-NEXT:      | [sizeof=48, align=16
+// CHECK-NEXT:      |  nvsize=32, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct C
-// CHECK-X64:    0 |   (C vftable pointer)
-// CHECK-X64:   16 |   struct B4 (base)
-// CHECK-X64:   16 |     (B4 vbtable pointer)
-// CHECK-X64:   24 |     int a
-// CHECK-X64:   32 |   int a
-// CHECK-X64:   48 |   struct B3 (virtual base)
-// CHECK-X64:   48 |     int a
-// CHECK-X64:      | [sizeof=64, align=16
-// CHECK-X64:      |  nvsize=48, nvalign=16]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct C
+// CHECK-X64-NEXT:    0 |   (C vftable pointer)
+// CHECK-X64-NEXT:   16 |   struct B4 (base)
+// CHECK-X64-NEXT:   16 |     (B4 vbtable pointer)
+// CHECK-X64-NEXT:   24 |     int a
+// CHECK-X64-NEXT:   32 |   int a
+// CHECK-X64-NEXT:   48 |   struct B3 (virtual base)
+// CHECK-X64-NEXT:   48 |     int a
+// CHECK-X64-NEXT:      | [sizeof=64, align=16
+// CHECK-X64-NEXT:      |  nvsize=48, nvalign=16]
 
 struct D : C { int a; D() : a(0xf000000D) {} virtual void f() { printf("D"); } };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct D
-// CHECK:    0 |   struct C (primary base)
-// CHECK:    0 |     (C vftable pointer)
-// CHECK:   16 |     struct B4 (base)
-// CHECK:   16 |       (B4 vbtable pointer)
-// CHECK:   20 |       int a
-// CHECK:   24 |     int a
-// CHECK:   32 |   int a
-// CHECK:   48 |   struct B3 (virtual base)
-// CHECK:   48 |     int a
-// CHECK:      | [sizeof=64, align=16
-// CHECK:      |  nvsize=48, nvalign=16]
+// CHECK-NEXT:    0 | struct D
+// CHECK-NEXT:    0 |   struct C (primary base)
+// CHECK-NEXT:    0 |     (C vftable pointer)
+// CHECK-NEXT:   16 |     struct B4 (base)
+// CHECK-NEXT:   16 |       (B4 vbtable pointer)
+// CHECK-NEXT:   20 |       int a
+// CHECK-NEXT:   24 |     int a
+// CHECK-NEXT:   32 |   int a
+// CHECK-NEXT:   48 |   struct B3 (virtual base)
+// CHECK-NEXT:   48 |     int a
+// CHECK-NEXT:      | [sizeof=64, align=16
+// CHECK-NEXT:      |  nvsize=48, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct D
-// CHECK-X64:    0 |   struct C (primary base)
-// CHECK-X64:    0 |     (C vftable pointer)
-// CHECK-X64:   16 |     struct B4 (base)
-// CHECK-X64:   16 |       (B4 vbtable pointer)
-// CHECK-X64:   24 |       int a
-// CHECK-X64:   32 |     int a
-// CHECK-X64:   48 |   int a
-// CHECK-X64:   64 |   struct B3 (virtual base)
-// CHECK-X64:   64 |     int a
-// CHECK-X64:      | [sizeof=80, align=16
-// CHECK-X64:      |  nvsize=64, nvalign=16]
+// CHECK-X64-NEXT:    0 | struct D
+// CHECK-X64-NEXT:    0 |   struct C (primary base)
+// CHECK-X64-NEXT:    0 |     (C vftable pointer)
+// CHECK-X64-NEXT:   16 |     struct B4 (base)
+// CHECK-X64-NEXT:   16 |       (B4 vbtable pointer)
+// CHECK-X64-NEXT:   24 |       int a
+// CHECK-X64-NEXT:   32 |     int a
+// CHECK-X64-NEXT:   48 |   int a
+// CHECK-X64-NEXT:   64 |   struct B3 (virtual base)
+// CHECK-X64-NEXT:   64 |     int a
+// CHECK-X64-NEXT:      | [sizeof=80, align=16
+// CHECK-X64-NEXT:      |  nvsize=64, nvalign=16]
 
 struct E : virtual C { int a; E() : a(0xf000000E) {} virtual void f() { printf("E"); } };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct E
-// CHECK:    0 |   (E vbtable pointer)
-// CHECK:    4 |   int a
-// CHECK:   16 |   struct B3 (virtual base)
-// CHECK:   16 |     int a
-// CHECK:   44 |   (vtordisp for vbase C)
-// CHECK:   48 |   struct C (virtual base)
-// CHECK:   48 |     (C vftable pointer)
-// CHECK:   64 |     struct B4 (base)
-// CHECK:   64 |       (B4 vbtable pointer)
-// CHECK:   68 |       int a
-// CHECK:   72 |     int a
-// CHECK:      | [sizeof=80, align=16
-// CHECK:      |  nvsize=8, nvalign=4]
+// CHECK-NEXT:    0 | struct E
+// CHECK-NEXT:    0 |   (E vbtable pointer)
+// CHECK-NEXT:    4 |   int a
+// CHECK-NEXT:   16 |   struct B3 (virtual base)
+// CHECK-NEXT:   16 |     int a
+// CHECK-NEXT:   44 |   (vtordisp for vbase C)
+// CHECK-NEXT:   48 |   struct C (virtual base)
+// CHECK-NEXT:   48 |     (C vftable pointer)
+// CHECK-NEXT:   64 |     struct B4 (base)
+// CHECK-NEXT:   64 |       (B4 vbtable pointer)
+// CHECK-NEXT:   68 |       int a
+// CHECK-NEXT:   72 |     int a
+// CHECK-NEXT:      | [sizeof=80, align=16
+// CHECK-NEXT:      |  nvsize=8, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct E
-// CHECK-X64:    0 |   (E vbtable pointer)
-// CHECK-X64:    8 |   int a
-// CHECK-X64:   16 |   struct B3 (virtual base)
-// CHECK-X64:   16 |     int a
-// CHECK-X64:   44 |   (vtordisp for vbase C)
-// CHECK-X64:   48 |   struct C (virtual base)
-// CHECK-X64:   48 |     (C vftable pointer)
-// CHECK-X64:   64 |     struct B4 (base)
-// CHECK-X64:   64 |       (B4 vbtable pointer)
-// CHECK-X64:   72 |       int a
-// CHECK-X64:   80 |     int a
-// CHECK-X64:      | [sizeof=96, align=16
-// CHECK-X64:      |  nvsize=16, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct E
+// CHECK-X64-NEXT:    0 |   (E vbtable pointer)
+// CHECK-X64-NEXT:    8 |   int a
+// CHECK-X64-NEXT:   16 |   struct B3 (virtual base)
+// CHECK-X64-NEXT:   16 |     int a
+// CHECK-X64-NEXT:   44 |   (vtordisp for vbase C)
+// CHECK-X64-NEXT:   48 |   struct C (virtual base)
+// CHECK-X64-NEXT:   48 |     (C vftable pointer)
+// CHECK-X64-NEXT:   64 |     struct B4 (base)
+// CHECK-X64-NEXT:   64 |       (B4 vbtable pointer)
+// CHECK-X64-NEXT:   72 |       int a
+// CHECK-X64-NEXT:   80 |     int a
+// CHECK-X64-NEXT:      | [sizeof=96, align=16
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=16]
 
 struct F : B3, virtual B0 { int a; F() : a(0xf000000F) {} virtual void f() { printf("F"); } };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct F
-// CHECK:    0 |   (F vftable pointer)
-// CHECK:   16 |   struct B3 (base)
-// CHECK:   16 |     int a
-// CHECK:   32 |   (F vbtable pointer)
-// CHECK:   48 |   int a
-// CHECK:   64 |   struct B0 (virtual base)
-// CHECK:   64 |     int a
-// CHECK:      | [sizeof=80, align=16
-// CHECK:      |  nvsize=64, nvalign=16]
+// CHECK-NEXT:    0 | struct F
+// CHECK-NEXT:    0 |   (F vftable pointer)
+// CHECK-NEXT:   16 |   struct B3 (base)
+// CHECK-NEXT:   16 |     int a
+// CHECK-NEXT:   32 |   (F vbtable pointer)
+// CHECK-NEXT:   48 |   int a
+// CHECK-NEXT:   64 |   struct B0 (virtual base)
+// CHECK-NEXT:   64 |     int a
+// CHECK-NEXT:      | [sizeof=80, align=16
+// CHECK-NEXT:      |  nvsize=64, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct F
-// CHECK-X64:    0 |   (F vftable pointer)
-// CHECK-X64:   16 |   struct B3 (base)
-// CHECK-X64:   16 |     int a
-// CHECK-X64:   32 |   (F vbtable pointer)
-// CHECK-X64:   40 |   int a
-// CHECK-X64:   48 |   struct B0 (virtual base)
-// CHECK-X64:   48 |     int a
-// CHECK-X64:      | [sizeof=64, align=16
-// CHECK-X64:      |  nvsize=48, nvalign=16]
+// CHECK-X64-NEXT:    0 | struct F
+// CHECK-X64-NEXT:    0 |   (F vftable pointer)
+// CHECK-X64-NEXT:   16 |   struct B3 (base)
+// CHECK-X64-NEXT:   16 |     int a
+// CHECK-X64-NEXT:   32 |   (F vbtable pointer)
+// CHECK-X64-NEXT:   48 |   int a
+// CHECK-X64-NEXT:   64 |   struct B0 (virtual base)
+// CHECK-X64-NEXT:   64 |     int a
+// CHECK-X64-NEXT:      | [sizeof=80, align=16
+// CHECK-X64-NEXT:      |  nvsize=64, nvalign=16]
 
 struct G : B2, B6, virtual B1 { int a; G() : a(0xf0000010) {} };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct G
-// CHECK:    8 |   struct B2 (base)
-// CHECK:    8 |     (B2 vbtable pointer)
-// CHECK:   12 |     int a
-// CHECK:    0 |   struct B6 (primary base)
-// CHECK:    0 |     (B6 vftable pointer)
-// CHECK:    4 |     int a
-// CHECK:   16 |   int a
-// CHECK:   20 |   struct B1 (virtual base)
-// CHECK:   20 |     char a
-// CHECK:      | [sizeof=21, align=4
-// CHECK:      |  nvsize=20, nvalign=4]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct G
+// CHECK-NEXT:    0 |   struct B6 (primary base)
+// CHECK-NEXT:    0 |     (B6 vftable pointer)
+// CHECK-NEXT:    4 |     int a
+// CHECK-NEXT:    8 |   struct B2 (base)
+// CHECK-NEXT:    8 |     (B2 vbtable pointer)
+// CHECK-NEXT:   12 |     int a
+// CHECK-NEXT:   16 |   int a
+// CHECK-NEXT:   20 |   struct B1 (virtual base)
+// CHECK-NEXT:   20 |     char a
+// CHECK-NEXT:      | [sizeof=21, align=4
+// CHECK-NEXT:      |  nvsize=20, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct G
-// CHECK-X64:   16 |   struct B2 (base)
-// CHECK-X64:   16 |     (B2 vbtable pointer)
-// CHECK-X64:   24 |     int a
-// CHECK-X64:    0 |   struct B6 (primary base)
-// CHECK-X64:    0 |     (B6 vftable pointer)
-// CHECK-X64:    8 |     int a
-// CHECK-X64:   32 |   int a
-// CHECK-X64:   40 |   struct B1 (virtual base)
-// CHECK-X64:   40 |     char a
-// CHECK-X64:      | [sizeof=48, align=8
-// CHECK-X64:      |  nvsize=40, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct G
+// CHECK-X64-NEXT:    0 |   struct B6 (primary base)
+// CHECK-X64-NEXT:    0 |     (B6 vftable pointer)
+// CHECK-X64-NEXT:    8 |     int a
+// CHECK-X64-NEXT:   16 |   struct B2 (base)
+// CHECK-X64-NEXT:   16 |     (B2 vbtable pointer)
+// CHECK-X64-NEXT:   24 |     int a
+// CHECK-X64-NEXT:   32 |   int a
+// CHECK-X64-NEXT:   40 |   struct B1 (virtual base)
+// CHECK-X64-NEXT:   40 |     char a
+// CHECK-X64-NEXT:      | [sizeof=48, align=8
+// CHECK-X64-NEXT:      |  nvsize=40, nvalign=8]
 
 struct H : B6, B2, virtual B1 { int a; H() : a(0xf0000011) {} };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct H
-// CHECK:    0 |   struct B6 (primary base)
-// CHECK:    0 |     (B6 vftable pointer)
-// CHECK:    4 |     int a
-// CHECK:    8 |   struct B2 (base)
-// CHECK:    8 |     (B2 vbtable pointer)
-// CHECK:   12 |     int a
-// CHECK:   16 |   int a
-// CHECK:   20 |   struct B1 (virtual base)
-// CHECK:   20 |     char a
-// CHECK:      | [sizeof=21, align=4
-// CHECK:      |  nvsize=20, nvalign=4]
+// CHECK-NEXT:    0 | struct H
+// CHECK-NEXT:    0 |   struct B6 (primary base)
+// CHECK-NEXT:    0 |     (B6 vftable pointer)
+// CHECK-NEXT:    4 |     int a
+// CHECK-NEXT:    8 |   struct B2 (base)
+// CHECK-NEXT:    8 |     (B2 vbtable pointer)
+// CHECK-NEXT:   12 |     int a
+// CHECK-NEXT:   16 |   int a
+// CHECK-NEXT:   20 |   struct B1 (virtual base)
+// CHECK-NEXT:   20 |     char a
+// CHECK-NEXT:      | [sizeof=21, align=4
+// CHECK-NEXT:      |  nvsize=20, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct H
-// CHECK-X64:    0 |   struct B6 (primary base)
-// CHECK-X64:    0 |     (B6 vftable pointer)
-// CHECK-X64:    8 |     int a
-// CHECK-X64:   16 |   struct B2 (base)
-// CHECK-X64:   16 |     (B2 vbtable pointer)
-// CHECK-X64:   24 |     int a
-// CHECK-X64:   32 |   int a
-// CHECK-X64:   40 |   struct B1 (virtual base)
-// CHECK-X64:   40 |     char a
-// CHECK-X64:      | [sizeof=48, align=8
-// CHECK-X64:      |  nvsize=40, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct H
+// CHECK-X64-NEXT:    0 |   struct B6 (primary base)
+// CHECK-X64-NEXT:    0 |     (B6 vftable pointer)
+// CHECK-X64-NEXT:    8 |     int a
+// CHECK-X64-NEXT:   16 |   struct B2 (base)
+// CHECK-X64-NEXT:   16 |     (B2 vbtable pointer)
+// CHECK-X64-NEXT:   24 |     int a
+// CHECK-X64-NEXT:   32 |   int a
+// CHECK-X64-NEXT:   40 |   struct B1 (virtual base)
+// CHECK-X64-NEXT:   40 |     char a
+// CHECK-X64-NEXT:      | [sizeof=48, align=8
+// CHECK-X64-NEXT:      |  nvsize=40, nvalign=8]
 
 struct I : B0, virtual B1 { int a; int a1; __declspec(align(16)) int a2; I() : a(0xf0000011), a1(0xf0000011), a2(0xf0000011) {} };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct I
-// CHECK:    0 |   struct B0 (base)
-// CHECK:    0 |     int a
-// CHECK:    4 |   (I vbtable pointer)
-// CHECK:   20 |   int a
-// CHECK:   24 |   int a1
-// CHECK:   32 |   int a2
-// CHECK:   48 |   struct B1 (virtual base)
-// CHECK:   48 |     char a
-// CHECK:      | [sizeof=64, align=16
-// CHECK:      |  nvsize=48, nvalign=16]
+// CHECK-NEXT:    0 | struct I
+// CHECK-NEXT:    0 |   struct B0 (base)
+// CHECK-NEXT:    0 |     int a
+// CHECK-NEXT:    4 |   (I vbtable pointer)
+// CHECK-NEXT:   20 |   int a
+// CHECK-NEXT:   24 |   int a1
+// CHECK-NEXT:   32 |   int a2
+// CHECK-NEXT:   48 |   struct B1 (virtual base)
+// CHECK-NEXT:   48 |     char a
+// CHECK-NEXT:      | [sizeof=64, align=16
+// CHECK-NEXT:      |  nvsize=48, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct I
-// CHECK-X64:    0 |   struct B0 (base)
-// CHECK-X64:    0 |     int a
-// CHECK-X64:    8 |   (I vbtable pointer)
-// CHECK-X64:   16 |   int a
-// CHECK-X64:   20 |   int a1
-// CHECK-X64:   32 |   int a2
-// CHECK-X64:   48 |   struct B1 (virtual base)
-// CHECK-X64:   48 |     char a
-// CHECK-X64:      | [sizeof=64, align=16
-// CHECK-X64:      |  nvsize=48, nvalign=16]
+// CHECK-X64-NEXT:    0 | struct I
+// CHECK-X64-NEXT:    0 |   struct B0 (base)
+// CHECK-X64-NEXT:    0 |     int a
+// CHECK-X64-NEXT:    8 |   (I vbtable pointer)
+// CHECK-X64-NEXT:   20 |   int a
+// CHECK-X64-NEXT:   24 |   int a1
+// CHECK-X64-NEXT:   32 |   int a2
+// CHECK-X64-NEXT:   48 |   struct B1 (virtual base)
+// CHECK-X64-NEXT:   48 |     char a
+// CHECK-X64-NEXT:      | [sizeof=64, align=16
+// CHECK-X64-NEXT:      |  nvsize=48, nvalign=16]
 
 struct J : B0, B3, virtual B1 { int a; int a1; J() : a(0xf0000012), a1(0xf0000012) {} };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct J
-// CHECK:    0 |   struct B0 (base)
-// CHECK:    0 |     int a
-// CHECK:   16 |   struct B3 (base)
-// CHECK:   16 |     int a
-// CHECK:   32 |   (J vbtable pointer)
-// CHECK:   48 |   int a
-// CHECK:   52 |   int a1
-// CHECK:   64 |   struct B1 (virtual base)
-// CHECK:   64 |     char a
-// CHECK:      | [sizeof=80, align=16
-// CHECK:      |  nvsize=64, nvalign=16]
+// CHECK-NEXT:    0 | struct J
+// CHECK-NEXT:    0 |   struct B0 (base)
+// CHECK-NEXT:    0 |     int a
+// CHECK-NEXT:   16 |   struct B3 (base)
+// CHECK-NEXT:   16 |     int a
+// CHECK-NEXT:   32 |   (J vbtable pointer)
+// CHECK-NEXT:   48 |   int a
+// CHECK-NEXT:   52 |   int a1
+// CHECK-NEXT:   64 |   struct B1 (virtual base)
+// CHECK-NEXT:   64 |     char a
+// CHECK-NEXT:      | [sizeof=80, align=16
+// CHECK-NEXT:      |  nvsize=64, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct J
-// CHECK-X64:    0 |   struct B0 (base)
-// CHECK-X64:    0 |     int a
-// CHECK-X64:   16 |   struct B3 (base)
-// CHECK-X64:   16 |     int a
-// CHECK-X64:   32 |   (J vbtable pointer)
-// CHECK-X64:   40 |   int a
-// CHECK-X64:   44 |   int a1
-// CHECK-X64:   48 |   struct B1 (virtual base)
-// CHECK-X64:   48 |     char a
-// CHECK-X64:      | [sizeof=64, align=16
-// CHECK-X64:      |  nvsize=48, nvalign=16]
+// CHECK-X64-NEXT:    0 | struct J
+// CHECK-X64-NEXT:    0 |   struct B0 (base)
+// CHECK-X64-NEXT:    0 |     int a
+// CHECK-X64-NEXT:   16 |   struct B3 (base)
+// CHECK-X64-NEXT:   16 |     int a
+// CHECK-X64-NEXT:   32 |   (J vbtable pointer)
+// CHECK-X64-NEXT:   48 |   int a
+// CHECK-X64-NEXT:   52 |   int a1
+// CHECK-X64-NEXT:   64 |   struct B1 (virtual base)
+// CHECK-X64-NEXT:   64 |     char a
+// CHECK-X64-NEXT:      | [sizeof=80, align=16
+// CHECK-X64-NEXT:      |  nvsize=64, nvalign=16]
 
 struct K { int a; K() : a(0xf0000013) {} virtual void f() { printf("K"); } };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct K
-// CHECK:    0 |   (K vftable pointer)
-// CHECK:    4 |   int a
-// CHECK:      | [sizeof=8, align=4
-// CHECK:      |  nvsize=8, nvalign=4]
+// CHECK-NEXT:    0 | struct K
+// CHECK-NEXT:    0 |   (K vftable pointer)
+// CHECK-NEXT:    4 |   int a
+// CHECK-NEXT:      | [sizeof=8, align=4
+// CHECK-NEXT:      |  nvsize=8, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct K
-// CHECK-X64:    0 |   (K vftable pointer)
-// CHECK-X64:    8 |   int a
-// CHECK-X64:      | [sizeof=16, align=8
-// CHECK-X64:      |  nvsize=16, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct K
+// CHECK-X64-NEXT:    0 |   (K vftable pointer)
+// CHECK-X64-NEXT:    8 |   int a
+// CHECK-X64-NEXT:      | [sizeof=16, align=8
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
 
 struct L : virtual K { int a; L() : a(0xf0000014) {} virtual void g() { printf("L"); } };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct L
-// CHECK:    0 |   (L vftable pointer)
-// CHECK:    4 |   (L vbtable pointer)
-// CHECK:    8 |   int a
-// CHECK:   12 |   struct K (virtual base)
-// CHECK:   12 |     (K vftable pointer)
-// CHECK:   16 |     int a
-// CHECK:      | [sizeof=20, align=4
-// CHECK:      |  nvsize=12, nvalign=4]
+// CHECK-NEXT:    0 | struct L
+// CHECK-NEXT:    0 |   (L vftable pointer)
+// CHECK-NEXT:    4 |   (L vbtable pointer)
+// CHECK-NEXT:    8 |   int a
+// CHECK-NEXT:   12 |   struct K (virtual base)
+// CHECK-NEXT:   12 |     (K vftable pointer)
+// CHECK-NEXT:   16 |     int a
+// CHECK-NEXT:      | [sizeof=20, align=4
+// CHECK-NEXT:      |  nvsize=12, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct L
-// CHECK-X64:    0 |   (L vftable pointer)
-// CHECK-X64:    8 |   (L vbtable pointer)
-// CHECK-X64:   16 |   int a
-// CHECK-X64:   24 |   struct K (virtual base)
-// CHECK-X64:   24 |     (K vftable pointer)
-// CHECK-X64:   32 |     int a
-// CHECK-X64:      | [sizeof=40, align=8
-// CHECK-X64:      |  nvsize=24, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct L
+// CHECK-X64-NEXT:    0 |   (L vftable pointer)
+// CHECK-X64-NEXT:    8 |   (L vbtable pointer)
+// CHECK-X64-NEXT:   16 |   int a
+// CHECK-X64-NEXT:   24 |   struct K (virtual base)
+// CHECK-X64-NEXT:   24 |     (K vftable pointer)
+// CHECK-X64-NEXT:   32 |     int a
+// CHECK-X64-NEXT:      | [sizeof=40, align=8
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=8]
 
 struct M : virtual K { int a; M() : a(0xf0000015) {} virtual void f() { printf("M"); } };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct M
-// CHECK:    0 |   (M vbtable pointer)
-// CHECK:    4 |   int a
-// CHECK:    8 |   (vtordisp for vbase K)
-// CHECK:   12 |   struct K (virtual base)
-// CHECK:   12 |     (K vftable pointer)
-// CHECK:   16 |     int a
-// CHECK:      | [sizeof=20, align=4
-// CHECK:      |  nvsize=8, nvalign=4]
+// CHECK-NEXT:    0 | struct M
+// CHECK-NEXT:    0 |   (M vbtable pointer)
+// CHECK-NEXT:    4 |   int a
+// CHECK-NEXT:    8 |   (vtordisp for vbase K)
+// CHECK-NEXT:   12 |   struct K (virtual base)
+// CHECK-NEXT:   12 |     (K vftable pointer)
+// CHECK-NEXT:   16 |     int a
+// CHECK-NEXT:      | [sizeof=20, align=4
+// CHECK-NEXT:      |  nvsize=8, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct M
-// CHECK-X64:    0 |   (M vbtable pointer)
-// CHECK-X64:    8 |   int a
-// CHECK-X64:   20 |   (vtordisp for vbase K)
-// CHECK-X64:   24 |   struct K (virtual base)
-// CHECK-X64:   24 |     (K vftable pointer)
-// CHECK-X64:   32 |     int a
-// CHECK-X64:      | [sizeof=40, align=8
-// CHECK-X64:      |  nvsize=16, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct M
+// CHECK-X64-NEXT:    0 |   (M vbtable pointer)
+// CHECK-X64-NEXT:    8 |   int a
+// CHECK-X64-NEXT:   20 |   (vtordisp for vbase K)
+// CHECK-X64-NEXT:   24 |   struct K (virtual base)
+// CHECK-X64-NEXT:   24 |     (K vftable pointer)
+// CHECK-X64-NEXT:   32 |     int a
+// CHECK-X64-NEXT:      | [sizeof=40, align=8
+// CHECK-X64-NEXT:      |  nvsize=16, nvalign=8]
 
 int a[
 sizeof(A)+
diff --git a/test/Layout/ms-x86-vfvb-sharing.cpp b/test/Layout/ms-x86-vfvb-sharing.cpp
index 2b3d08e..91f194f 100644
--- a/test/Layout/ms-x86-vfvb-sharing.cpp
+++ b/test/Layout/ms-x86-vfvb-sharing.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>&1 \
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>&1 \
 // RUN:            | FileCheck %s
-// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>/dev/null \
+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>/dev/null \
 // RUN:            | FileCheck %s -check-prefix CHECK-X64
 
 extern "C" int printf(const char *fmt, ...);
@@ -18,27 +18,31 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct A
-// CHECK:    0 |   (A vftable pointer)
-// CHECK:   16 |   struct B0 (base)
-// CHECK:   16 |     int a
-// CHECK:   20 |   (A vbtable pointer)
-// CHECK:   48 |   int a
-// CHECK:   64 |   struct B1 (virtual base)
-// CHECK:   64 |     int a
-// CHECK:      | [sizeof=80, align=16
-// CHECK:      |  nvsize=64, nvalign=16]
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct A
+// CHECK-NEXT:    0 |   (A vftable pointer)
+// CHECK-NEXT:   16 |   struct B0 (base)
+// CHECK-NEXT:   16 |     int a
+// CHECK-NEXT:   20 |   (A vbtable pointer)
+// CHECK-NEXT:   48 |   int a
+// CHECK-NEXT:   64 |   struct B1 (virtual base)
+// CHECK-NEXT:   64 |     int a
+// CHECK-NEXT:      | [sizeof=80, align=16
+// CHECK-NEXT:      |  nvsize=64, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct A
-// CHECK-X64:    0 |   (A vftable pointer)
-// CHECK-X64:    8 |   struct B0 (base)
-// CHECK-X64:    8 |     int a
-// CHECK-X64:   16 |   (A vbtable pointer)
-// CHECK-X64:   32 |   int a
-// CHECK-X64:   48 |   struct B1 (virtual base)
-// CHECK-X64:   48 |     int a
-// CHECK-X64:      | [sizeof=64, align=16
-// CHECK-X64:      |  nvsize=48, nvalign=16]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct A
+// CHECK-X64-NEXT:    0 |   (A vftable pointer)
+// CHECK-X64-NEXT:   16 |   struct B0 (base)
+// CHECK-X64-NEXT:   16 |     int a
+// CHECK-X64-NEXT:   24 |   (A vbtable pointer)
+// CHECK-X64-NEXT:   48 |   int a
+// CHECK-X64-NEXT:   64 |   struct B1 (virtual base)
+// CHECK-X64-NEXT:   64 |     int a
+// CHECK-X64-NEXT:      | [sizeof=80, align=16
+// CHECK-X64-NEXT:      |  nvsize=64, nvalign=16]
 
 struct B : B2, B0, virtual B1 {
 	__declspec(align(16)) int a;
@@ -47,29 +51,31 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct B
-// CHECK:    0 |   struct B2 (primary base)
-// CHECK:    0 |     (B2 vftable pointer)
-// CHECK:    4 |   struct B0 (base)
-// CHECK:    4 |     int a
-// CHECK:    8 |   (B vbtable pointer)
-// CHECK:   32 |   int a
-// CHECK:   48 |   struct B1 (virtual base)
-// CHECK:   48 |     int a
-// CHECK:      | [sizeof=64, align=16
-// CHECK:      |  nvsize=48, nvalign=16]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct B
+// CHECK-NEXT:    0 |   struct B2 (primary base)
+// CHECK-NEXT:    0 |     (B2 vftable pointer)
+// CHECK-NEXT:    4 |   struct B0 (base)
+// CHECK-NEXT:    4 |     int a
+// CHECK-NEXT:    8 |   (B vbtable pointer)
+// CHECK-NEXT:   32 |   int a
+// CHECK-NEXT:   48 |   struct B1 (virtual base)
+// CHECK-NEXT:   48 |     int a
+// CHECK-NEXT:      | [sizeof=64, align=16
+// CHECK-NEXT:      |  nvsize=48, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct B
-// CHECK-X64:    0 |   struct B2 (primary base)
-// CHECK-X64:    0 |     (B2 vftable pointer)
-// CHECK-X64:    8 |   struct B0 (base)
-// CHECK-X64:    8 |     int a
-// CHECK-X64:   16 |   (B vbtable pointer)
-// CHECK-X64:   32 |   int a
-// CHECK-X64:   48 |   struct B1 (virtual base)
-// CHECK-X64:   48 |     int a
-// CHECK-X64:      | [sizeof=64, align=16
-// CHECK-X64:      |  nvsize=48, nvalign=16]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct B
+// CHECK-X64-NEXT:    0 |   struct B2 (primary base)
+// CHECK-X64-NEXT:    0 |     (B2 vftable pointer)
+// CHECK-X64-NEXT:    8 |   struct B0 (base)
+// CHECK-X64-NEXT:    8 |     int a
+// CHECK-X64-NEXT:   16 |   (B vbtable pointer)
+// CHECK-X64-NEXT:   32 |   int a
+// CHECK-X64-NEXT:   48 |   struct B1 (virtual base)
+// CHECK-X64-NEXT:   48 |     int a
+// CHECK-X64-NEXT:      | [sizeof=64, align=16
+// CHECK-X64-NEXT:      |  nvsize=48, nvalign=16]
 
 struct C : B3, B0, virtual B1 {
 	__declspec(align(16)) int a;
@@ -78,29 +84,31 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct C
-// CHECK:    0 |   (C vftable pointer)
-// CHECK:   16 |   struct B3 (base)
-// CHECK:   16 |     (B3 vbtable pointer)
-// CHECK:   20 |   struct B0 (base)
-// CHECK:   20 |     int a
-// CHECK:   32 |   int a
-// CHECK:   48 |   struct B1 (virtual base)
-// CHECK:   48 |     int a
-// CHECK:      | [sizeof=64, align=16
-// CHECK:      |  nvsize=48, nvalign=16]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct C
+// CHECK-NEXT:    0 |   (C vftable pointer)
+// CHECK-NEXT:   16 |   struct B3 (base)
+// CHECK-NEXT:   16 |     (B3 vbtable pointer)
+// CHECK-NEXT:   20 |   struct B0 (base)
+// CHECK-NEXT:   20 |     int a
+// CHECK-NEXT:   32 |   int a
+// CHECK-NEXT:   48 |   struct B1 (virtual base)
+// CHECK-NEXT:   48 |     int a
+// CHECK-NEXT:      | [sizeof=64, align=16
+// CHECK-NEXT:      |  nvsize=48, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct C
-// CHECK-X64:    0 |   (C vftable pointer)
-// CHECK-X64:    8 |   struct B3 (base)
-// CHECK-X64:    8 |     (B3 vbtable pointer)
-// CHECK-X64:   16 |   struct B0 (base)
-// CHECK-X64:   16 |     int a
-// CHECK-X64:   32 |   int a
-// CHECK-X64:   48 |   struct B1 (virtual base)
-// CHECK-X64:   48 |     int a
-// CHECK-X64:      | [sizeof=64, align=16
-// CHECK-X64:      |  nvsize=48, nvalign=16]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct C
+// CHECK-X64-NEXT:    0 |   (C vftable pointer)
+// CHECK-X64-NEXT:   16 |   struct B3 (base)
+// CHECK-X64-NEXT:   16 |     (B3 vbtable pointer)
+// CHECK-X64-NEXT:   24 |   struct B0 (base)
+// CHECK-X64-NEXT:   24 |     int a
+// CHECK-X64-NEXT:   32 |   int a
+// CHECK-X64-NEXT:   48 |   struct B1 (virtual base)
+// CHECK-X64-NEXT:   48 |     int a
+// CHECK-X64-NEXT:      | [sizeof=64, align=16
+// CHECK-X64-NEXT:      |  nvsize=48, nvalign=16]
 
 struct D : B4, B0, virtual B1 {
 	__declspec(align(16)) int a;
@@ -109,29 +117,31 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct D
-// CHECK:    0 |   struct B4 (primary base)
-// CHECK:    0 |     (B4 vftable pointer)
-// CHECK:    4 |     (B4 vbtable pointer)
-// CHECK:    8 |   struct B0 (base)
-// CHECK:    8 |     int a
-// CHECK:   16 |   int a
-// CHECK:   32 |   struct B1 (virtual base)
-// CHECK:   32 |     int a
-// CHECK:      | [sizeof=48, align=16
-// CHECK:      |  nvsize=32, nvalign=16]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct D
+// CHECK-NEXT:    0 |   struct B4 (primary base)
+// CHECK-NEXT:    0 |     (B4 vftable pointer)
+// CHECK-NEXT:    4 |     (B4 vbtable pointer)
+// CHECK-NEXT:    8 |   struct B0 (base)
+// CHECK-NEXT:    8 |     int a
+// CHECK-NEXT:   16 |   int a
+// CHECK-NEXT:   32 |   struct B1 (virtual base)
+// CHECK-NEXT:   32 |     int a
+// CHECK-NEXT:      | [sizeof=48, align=16
+// CHECK-NEXT:      |  nvsize=32, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct D
-// CHECK-X64:    0 |   struct B4 (primary base)
-// CHECK-X64:    0 |     (B4 vftable pointer)
-// CHECK-X64:    8 |     (B4 vbtable pointer)
-// CHECK-X64:   16 |   struct B0 (base)
-// CHECK-X64:   16 |     int a
-// CHECK-X64:   32 |   int a
-// CHECK-X64:   48 |   struct B1 (virtual base)
-// CHECK-X64:   48 |     int a
-// CHECK-X64:      | [sizeof=64, align=16
-// CHECK-X64:      |  nvsize=48, nvalign=16]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct D
+// CHECK-X64-NEXT:    0 |   struct B4 (primary base)
+// CHECK-X64-NEXT:    0 |     (B4 vftable pointer)
+// CHECK-X64-NEXT:    8 |     (B4 vbtable pointer)
+// CHECK-X64-NEXT:   16 |   struct B0 (base)
+// CHECK-X64-NEXT:   16 |     int a
+// CHECK-X64-NEXT:   32 |   int a
+// CHECK-X64-NEXT:   48 |   struct B1 (virtual base)
+// CHECK-X64-NEXT:   48 |     int a
+// CHECK-X64-NEXT:      | [sizeof=64, align=16
+// CHECK-X64-NEXT:      |  nvsize=48, nvalign=16]
 
 int a[
 sizeof(A)+
diff --git a/test/Layout/ms-x86-vtordisp.cpp b/test/Layout/ms-x86-vtordisp.cpp
index b16f09e..60779fb 100644
--- a/test/Layout/ms-x86-vtordisp.cpp
+++ b/test/Layout/ms-x86-vtordisp.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>&1 \
+// RUN: %clang_cc1 -fno-rtti -fms-extensions -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>&1 \
 // RUN:            | FileCheck %s
-// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only -cxx-abi microsoft %s 2>/dev/null \
+// RUN: %clang_cc1 -fno-rtti -fms-extensions -emit-llvm-only -triple x86_64-pc-win32 -fdump-record-layouts -fsyntax-only %s 2>/dev/null \
 // RUN:            | FileCheck %s -check-prefix CHECK-X64
 
 extern "C" int printf(const char *fmt, ...);
@@ -30,35 +30,39 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct A
-// CHECK:    0 |   (A vftable pointer)
-// CHECK:    4 |   (A vbtable pointer)
-// CHECK:    8 |   int a
-// CHECK:   16 |   (vtordisp for vbase B0)
-// CHECK:   20 |   struct B0 (virtual base)
-// CHECK:   20 |     (B0 vftable pointer)
-// CHECK:   24 |     int a
-// CHECK:   44 |   (vtordisp for vbase B1)
-// CHECK:   48 |   struct B1 (virtual base)
-// CHECK:   48 |     (B1 vftable pointer)
-// CHECK:   52 |     int a
-// CHECK:      | [sizeof=64, align=16
-// CHECK:      |  nvsize=12, nvalign=4]
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct A
+// CHECK-NEXT:    0 |   (A vftable pointer)
+// CHECK-NEXT:    4 |   (A vbtable pointer)
+// CHECK-NEXT:    8 |   int a
+// CHECK-NEXT:   16 |   (vtordisp for vbase B0)
+// CHECK-NEXT:   20 |   struct B0 (virtual base)
+// CHECK-NEXT:   20 |     (B0 vftable pointer)
+// CHECK-NEXT:   24 |     int a
+// CHECK-NEXT:   44 |   (vtordisp for vbase B1)
+// CHECK-NEXT:   48 |   struct B1 (virtual base)
+// CHECK-NEXT:   48 |     (B1 vftable pointer)
+// CHECK-NEXT:   52 |     int a
+// CHECK-NEXT:      | [sizeof=64, align=16
+// CHECK-NEXT:      |  nvsize=12, nvalign=16]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct A
-// CHECK-X64:    0 |   (A vftable pointer)
-// CHECK-X64:    8 |   (A vbtable pointer)
-// CHECK-X64:   16 |   int a
-// CHECK-X64:   36 |   (vtordisp for vbase B0)
-// CHECK-X64:   40 |   struct B0 (virtual base)
-// CHECK-X64:   40 |     (B0 vftable pointer)
-// CHECK-X64:   48 |     int a
-// CHECK-X64:   76 |   (vtordisp for vbase B1)
-// CHECK-X64:   80 |   struct B1 (virtual base)
-// CHECK-X64:   80 |     (B1 vftable pointer)
-// CHECK-X64:   88 |     int a
-// CHECK-X64:      | [sizeof=96, align=16
-// CHECK-X64:      |  nvsize=24, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct A
+// CHECK-X64-NEXT:    0 |   (A vftable pointer)
+// CHECK-X64-NEXT:    8 |   (A vbtable pointer)
+// CHECK-X64-NEXT:   16 |   int a
+// CHECK-X64-NEXT:   36 |   (vtordisp for vbase B0)
+// CHECK-X64-NEXT:   40 |   struct B0 (virtual base)
+// CHECK-X64-NEXT:   40 |     (B0 vftable pointer)
+// CHECK-X64-NEXT:   48 |     int a
+// CHECK-X64-NEXT:   76 |   (vtordisp for vbase B1)
+// CHECK-X64-NEXT:   80 |   struct B1 (virtual base)
+// CHECK-X64-NEXT:   80 |     (B1 vftable pointer)
+// CHECK-X64-NEXT:   88 |     int a
+// CHECK-X64-NEXT:      | [sizeof=96, align=16
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=16]
 
 struct C : virtual B0, virtual B1, VAlign32 {
 	int a;
@@ -68,39 +72,43 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct C
-// CHECK:    0 |   (C vftable pointer)
-// CHECK:   32 |   struct VAlign32 (base)
-// CHECK:   32 |     (VAlign32 vbtable pointer)
-// CHECK:   36 |   int a
-// CHECK:   64 |   (vtordisp for vbase B0)
-// CHECK:   68 |   struct B0 (virtual base)
-// CHECK:   68 |     (B0 vftable pointer)
-// CHECK:   72 |     int a
-// CHECK:  108 |   (vtordisp for vbase B1)
-// CHECK:  112 |   struct B1 (virtual base)
-// CHECK:  112 |     (B1 vftable pointer)
-// CHECK:  116 |     int a
-// CHECK:  128 |   struct Align32 (virtual base) (empty)
-// CHECK:      | [sizeof=128, align=32
-// CHECK:      |  nvsize=64, nvalign=32]
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct C
+// CHECK-NEXT:    0 |   (C vftable pointer)
+// CHECK-NEXT:   32 |   struct VAlign32 (base)
+// CHECK-NEXT:   32 |     (VAlign32 vbtable pointer)
+// CHECK-NEXT:   36 |   int a
+// CHECK-NEXT:   64 |   (vtordisp for vbase B0)
+// CHECK-NEXT:   68 |   struct B0 (virtual base)
+// CHECK-NEXT:   68 |     (B0 vftable pointer)
+// CHECK-NEXT:   72 |     int a
+// CHECK-NEXT:  108 |   (vtordisp for vbase B1)
+// CHECK-NEXT:  112 |   struct B1 (virtual base)
+// CHECK-NEXT:  112 |     (B1 vftable pointer)
+// CHECK-NEXT:  116 |     int a
+// CHECK-NEXT:  128 |   struct Align32 (virtual base) (empty)
+// CHECK-NEXT:      | [sizeof=128, align=32
+// CHECK-NEXT:      |  nvsize=64, nvalign=32]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct C
-// CHECK-X64:    0 |   (C vftable pointer)
-// CHECK-X64:   32 |   struct VAlign32 (base)
-// CHECK-X64:   32 |     (VAlign32 vbtable pointer)
-// CHECK-X64:   40 |   int a
-// CHECK-X64:   68 |   (vtordisp for vbase B0)
-// CHECK-X64:   72 |   struct B0 (virtual base)
-// CHECK-X64:   72 |     (B0 vftable pointer)
-// CHECK-X64:   80 |     int a
-// CHECK-X64:  108 |   (vtordisp for vbase B1)
-// CHECK-X64:  112 |   struct B1 (virtual base)
-// CHECK-X64:  112 |     (B1 vftable pointer)
-// CHECK-X64:  120 |     int a
-// CHECK-X64:  128 |   struct Align32 (virtual base) (empty)
-// CHECK-X64:      | [sizeof=128, align=32
-// CHECK-X64:      |  nvsize=64, nvalign=32]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct C
+// CHECK-X64-NEXT:    0 |   (C vftable pointer)
+// CHECK-X64-NEXT:   32 |   struct VAlign32 (base)
+// CHECK-X64-NEXT:   32 |     (VAlign32 vbtable pointer)
+// CHECK-X64-NEXT:   40 |   int a
+// CHECK-X64-NEXT:   68 |   (vtordisp for vbase B0)
+// CHECK-X64-NEXT:   72 |   struct B0 (virtual base)
+// CHECK-X64-NEXT:   72 |     (B0 vftable pointer)
+// CHECK-X64-NEXT:   80 |     int a
+// CHECK-X64-NEXT:  108 |   (vtordisp for vbase B1)
+// CHECK-X64-NEXT:  112 |   struct B1 (virtual base)
+// CHECK-X64-NEXT:  112 |     (B1 vftable pointer)
+// CHECK-X64-NEXT:  120 |     int a
+// CHECK-X64-NEXT:  128 |   struct Align32 (virtual base) (empty)
+// CHECK-X64-NEXT:      | [sizeof=128, align=32
+// CHECK-X64-NEXT:      |  nvsize=64, nvalign=32]
 
 struct __declspec(align(32)) D : virtual B0, virtual B1  {
 	int a;
@@ -110,35 +118,35 @@
 };
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct D
-// CHECK:    0 |   (D vftable pointer)
-// CHECK:    4 |   (D vbtable pointer)
-// CHECK:    8 |   int a
-// CHECK:   32 |   (vtordisp for vbase B0)
-// CHECK:   36 |   struct B0 (virtual base)
-// CHECK:   36 |     (B0 vftable pointer)
-// CHECK:   40 |     int a
-// CHECK:   76 |   (vtordisp for vbase B1)
-// CHECK:   80 |   struct B1 (virtual base)
-// CHECK:   80 |     (B1 vftable pointer)
-// CHECK:   84 |     int a
-// CHECK:      | [sizeof=96, align=32
-// CHECK:      |  nvsize=12, nvalign=4]
+// CHECK-NEXT:    0 | struct D
+// CHECK-NEXT:    0 |   (D vftable pointer)
+// CHECK-NEXT:    4 |   (D vbtable pointer)
+// CHECK-NEXT:    8 |   int a
+// CHECK-NEXT:   32 |   (vtordisp for vbase B0)
+// CHECK-NEXT:   36 |   struct B0 (virtual base)
+// CHECK-NEXT:   36 |     (B0 vftable pointer)
+// CHECK-NEXT:   40 |     int a
+// CHECK-NEXT:   76 |   (vtordisp for vbase B1)
+// CHECK-NEXT:   80 |   struct B1 (virtual base)
+// CHECK-NEXT:   80 |     (B1 vftable pointer)
+// CHECK-NEXT:   84 |     int a
+// CHECK-NEXT:      | [sizeof=96, align=32
+// CHECK-NEXT:      |  nvsize=12, nvalign=32]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct D
-// CHECK-X64:    0 |   (D vftable pointer)
-// CHECK-X64:    8 |   (D vbtable pointer)
-// CHECK-X64:   16 |   int a
-// CHECK-X64:   36 |   (vtordisp for vbase B0)
-// CHECK-X64:   40 |   struct B0 (virtual base)
-// CHECK-X64:   40 |     (B0 vftable pointer)
-// CHECK-X64:   48 |     int a
-// CHECK-X64:   76 |   (vtordisp for vbase B1)
-// CHECK-X64:   80 |   struct B1 (virtual base)
-// CHECK-X64:   80 |     (B1 vftable pointer)
-// CHECK-X64:   88 |     int a
-// CHECK-X64:      | [sizeof=96, align=32
-// CHECK-X64:      |  nvsize=24, nvalign=8]
+// CHECK-X64-NEXT:    0 | struct D
+// CHECK-X64-NEXT:    0 |   (D vftable pointer)
+// CHECK-X64-NEXT:    8 |   (D vbtable pointer)
+// CHECK-X64-NEXT:   16 |   int a
+// CHECK-X64-NEXT:   36 |   (vtordisp for vbase B0)
+// CHECK-X64-NEXT:   40 |   struct B0 (virtual base)
+// CHECK-X64-NEXT:   40 |     (B0 vftable pointer)
+// CHECK-X64-NEXT:   48 |     int a
+// CHECK-X64-NEXT:   76 |   (vtordisp for vbase B1)
+// CHECK-X64-NEXT:   80 |   struct B1 (virtual base)
+// CHECK-X64-NEXT:   80 |     (B1 vftable pointer)
+// CHECK-X64-NEXT:   88 |     int a
+// CHECK-X64-NEXT:      | [sizeof=96, align=32
+// CHECK-X64-NEXT:      |  nvsize=24, nvalign=32]
 
 struct AT {
 	virtual ~AT(){}
@@ -149,22 +157,275 @@
 CT::~CT(){}
 
 // CHECK: *** Dumping AST Record Layout
-// CHECK:    0 | struct CT
-// CHECK:    0 |   (CT vbtable pointer)
-// CHECK:    4 |   struct AT (virtual base)
-// CHECK:    4 |     (AT vftable pointer)
-// CHECK:      | [sizeof=8, align=4
-// CHECK:      |  nvsize=4, nvalign=4]
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct CT
+// CHECK-NEXT:    0 |   (CT vbtable pointer)
+// CHECK-NEXT:    4 |   struct AT (virtual base)
+// CHECK-NEXT:    4 |     (AT vftable pointer)
+// CHECK-NEXT:      | [sizeof=8, align=4
+// CHECK-NEXT:      |  nvsize=4, nvalign=4]
 // CHECK-X64: *** Dumping AST Record Layout
-// CHECK-X64:    0 | struct CT
-// CHECK-X64:    0 |   (CT vbtable pointer)
-// CHECK-X64:    8 |   struct AT (virtual base)
-// CHECK-X64:    8 |     (AT vftable pointer)
-// CHECK-X64:      | [sizeof=16, align=8
-// CHECK-X64:      |  nvsize=8, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct CT
+// CHECK-X64-NEXT:    0 |   (CT vbtable pointer)
+// CHECK-X64-NEXT:    8 |   struct AT (virtual base)
+// CHECK-X64-NEXT:    8 |     (AT vftable pointer)
+// CHECK-X64-NEXT:      | [sizeof=16, align=8
+// CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
+
+struct XA {
+	XA() { printf("XA"); }
+	long long ll;
+};
+struct XB : XA {
+	XB() { printf("XB"); }
+	virtual void foo() {}
+	int b;
+};
+struct XC : virtual XB {
+	XC() { printf("XC"); }
+	virtual void foo() {}
+};
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct XC
+// CHECK-NEXT:    0 |   (XC vbtable pointer)
+// CHECK-NEXT:    4 |   (vtordisp for vbase XB)
+// CHECK-NEXT:    8 |   struct XB (virtual base)
+// CHECK-NEXT:    8 |     (XB vftable pointer)
+// CHECK-NEXT:   16 |     struct XA (base)
+// CHECK-NEXT:   16 |       long long ll
+// CHECK-NEXT:   24 |     int b
+// CHECK-NEXT:      | [sizeof=32, align=8
+// CHECK-NEXT:      |  nvsize=4, nvalign=8]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct XC
+// CHECK-X64-NEXT:    0 |   (XC vbtable pointer)
+// CHECK-X64-NEXT:   12 |   (vtordisp for vbase XB)
+// CHECK-X64-NEXT:   16 |   struct XB (virtual base)
+// CHECK-X64-NEXT:   16 |     (XB vftable pointer)
+// CHECK-X64-NEXT:   24 |     struct XA (base)
+// CHECK-X64-NEXT:   24 |       long long ll
+// CHECK-X64-NEXT:   32 |     int b
+// CHECK-X64-NEXT:      | [sizeof=40, align=8
+// CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
+
+namespace pragma_test1 {
+// No overrides means no vtordisps by default.
+struct A { virtual ~A(); virtual void foo(); int a; };
+struct B : virtual A { virtual ~B(); virtual void bar(); int b; };
+struct C : virtual B { int c; };
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct pragma_test1::C
+// CHECK-NEXT:    0 |   (C vbtable pointer)
+// CHECK-NEXT:    4 |   int c
+// CHECK-NEXT:    8 |   struct pragma_test1::A (virtual base)
+// CHECK-NEXT:    8 |     (A vftable pointer)
+// CHECK-NEXT:   12 |     int a
+// CHECK-NEXT:   16 |   struct pragma_test1::B (virtual base)
+// CHECK-NEXT:   16 |     (B vftable pointer)
+// CHECK-NEXT:   20 |     (B vbtable pointer)
+// CHECK-NEXT:   24 |     int b
+// CHECK-NEXT:      | [sizeof=28, align=4
+// CHECK-NEXT:      |  nvsize=8, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+}
+
+namespace pragma_test2 {
+struct A { virtual ~A(); virtual void foo(); int a; };
+#pragma vtordisp(push,2)
+struct B : virtual A { virtual ~B(); virtual void bar(); int b; };
+struct C : virtual B { int c; };
+#pragma vtordisp(pop)
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct pragma_test2::C
+// CHECK-NEXT:    0 |   (C vbtable pointer)
+// CHECK-NEXT:    4 |   int c
+// CHECK-NEXT:    8 |   (vtordisp for vbase A)
+// CHECK-NEXT:   12 |   struct pragma_test2::A (virtual base)
+// CHECK-NEXT:   12 |     (A vftable pointer)
+// CHECK-NEXT:   16 |     int a
+//   By adding a virtual method and vftable to B, now we need a vtordisp.
+// CHECK-NEXT:   20 |   (vtordisp for vbase B)
+// CHECK-NEXT:   24 |   struct pragma_test2::B (virtual base)
+// CHECK-NEXT:   24 |     (B vftable pointer)
+// CHECK-NEXT:   28 |     (B vbtable pointer)
+// CHECK-NEXT:   32 |     int b
+// CHECK-NEXT:      | [sizeof=36, align=4
+// CHECK-NEXT:      |  nvsize=8, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+}
+
+namespace pragma_test3 {
+struct A { virtual ~A(); virtual void foo(); int a; };
+#pragma vtordisp(push,2)
+struct B : virtual A { virtual ~B(); virtual void foo(); int b; };
+struct C : virtual B { int c; };
+#pragma vtordisp(pop)
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct pragma_test3::C
+// CHECK-NEXT:    0 |   (C vbtable pointer)
+// CHECK-NEXT:    4 |   int c
+// CHECK-NEXT:    8 |   (vtordisp for vbase A)
+// CHECK-NEXT:   12 |   struct pragma_test3::A (virtual base)
+// CHECK-NEXT:   12 |     (A vftable pointer)
+// CHECK-NEXT:   16 |     int a
+//   No vtordisp before B!  It doesn't have its own vftable.
+// CHECK-NEXT:   20 |   struct pragma_test3::B (virtual base)
+// CHECK-NEXT:   20 |     (B vbtable pointer)
+// CHECK-NEXT:   24 |     int b
+// CHECK-NEXT:      | [sizeof=28, align=4
+// CHECK-NEXT:      |  nvsize=8, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+}
+
+namespace pragma_test4 {
+struct A {
+  A();
+  virtual void foo();
+  int a;
+};
+
+// Make sure the pragma applies to class template decls before they've been
+// instantiated.
+#pragma vtordisp(push,2)
+template <typename T>
+struct B : virtual A {
+  B();
+  virtual ~B();
+  virtual void bar();
+  T b;
+};
+#pragma vtordisp(pop)
+
+struct C : virtual B<int> { int c; };
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct pragma_test4::C
+// CHECK-NEXT:    0 |   (C vbtable pointer)
+// CHECK-NEXT:    4 |   int c
+//   Pragma applies to B, which has vbase A.
+// CHECK-NEXT:    8 |   (vtordisp for vbase A)
+// CHECK-NEXT:   12 |   struct pragma_test4::A (virtual base)
+// CHECK-NEXT:   12 |     (A vftable pointer)
+// CHECK-NEXT:   16 |     int a
+//   Pragma does not apply to C, and B doesn't usually need a vtordisp in C.
+// CHECK-NEXT:   20 |   struct pragma_test4::B<int> (virtual base)
+// CHECK-NEXT:   20 |     (B vftable pointer)
+// CHECK-NEXT:   24 |     (B vbtable pointer)
+// CHECK-NEXT:   28 |     int b
+// CHECK-NEXT:      | [sizeof=32, align=4
+// CHECK-NEXT:      |  nvsize=8, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+}
+
+struct GA {
+	virtual void fun() {}
+};
+struct GB: public GA {};
+struct GC: public virtual GA {
+	virtual void fun() {}
+	GC() {}
+};
+struct GD: public virtual GC, public virtual GB {};
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct GD
+// CHECK-NEXT:    0 |   (GD vbtable pointer)
+// CHECK-NEXT:    4 |   (vtordisp for vbase GA)
+// CHECK-NEXT:    8 |   struct GA (virtual base)
+// CHECK-NEXT:    8 |     (GA vftable pointer)
+// CHECK-NEXT:   12 |   struct GC (virtual base)
+// CHECK-NEXT:   12 |     (GC vbtable pointer)
+// CHECK-NEXT:   16 |   struct GB (virtual base)
+// CHECK-NEXT:   16 |     struct GA (primary base)
+// CHECK-NEXT:   16 |       (GA vftable pointer)
+// CHECK-NEXT:      | [sizeof=20, align=4
+// CHECK-NEXT:      |  nvsize=4, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct GD
+// CHECK-X64-NEXT:    0 |   (GD vbtable pointer)
+// CHECK-X64-NEXT:   12 |   (vtordisp for vbase GA)
+// CHECK-X64-NEXT:   16 |   struct GA (virtual base)
+// CHECK-X64-NEXT:   16 |     (GA vftable pointer)
+// CHECK-X64-NEXT:   24 |   struct GC (virtual base)
+// CHECK-X64-NEXT:   24 |     (GC vbtable pointer)
+// CHECK-X64-NEXT:   32 |   struct GB (virtual base)
+// CHECK-X64-NEXT:   32 |     struct GA (primary base)
+// CHECK-X64-NEXT:   32 |       (GA vftable pointer)
+// CHECK-X64-NEXT:      | [sizeof=40, align=8
+// CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
+
+struct HA {
+  virtual void fun() {}
+};
+#pragma vtordisp(push, 2)
+struct HB : virtual HA {};
+#pragma vtordisp(pop)
+#pragma vtordisp(push, 0)
+struct HC : virtual HB {};
+#pragma vtordisp(pop)
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT:    0 | struct HC
+// CHECK-NEXT:    0 |   (HC vbtable pointer)
+// CHECK-NEXT:    4 |   (vtordisp for vbase HA)
+// CHECK-NEXT:    8 |   struct HA (virtual base)
+// CHECK-NEXT:    8 |     (HA vftable pointer)
+// CHECK-NEXT:   12 |   struct HB (virtual base)
+// CHECK-NEXT:   12 |     (HB vbtable pointer)
+// CHECK-NEXT:      | [sizeof=16, align=4
+// CHECK-NEXT:      |  nvsize=4, nvalign=4]
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64: *** Dumping AST Record Layout
+// CHECK-X64-NEXT:    0 | struct HC
+// CHECK-X64-NEXT:    0 |   (HC vbtable pointer)
+// CHECK-X64-NEXT:   12 |   (vtordisp for vbase HA)
+// CHECK-X64-NEXT:   16 |   struct HA (virtual base)
+// CHECK-X64-NEXT:   16 |     (HA vftable pointer)
+// CHECK-X64-NEXT:   24 |   struct HB (virtual base)
+// CHECK-X64-NEXT:   24 |     (HB vbtable pointer)
+// CHECK-X64-NEXT:      | [sizeof=32, align=8
+// CHECK-X64-NEXT:      |  nvsize=8, nvalign=8]
 
 int a[
 sizeof(A)+
 sizeof(C)+
 sizeof(D)+
-sizeof(CT)];
+sizeof(CT)+
+sizeof(XC)+
+sizeof(pragma_test1::C)+
+sizeof(pragma_test2::C)+
+sizeof(pragma_test3::C)+
+sizeof(pragma_test4::C)+
+sizeof(GD)+
+sizeof(HC)+
+0];
diff --git a/test/Lexer/Inputs/success.h b/test/Lexer/Inputs/success.h
new file mode 100644
index 0000000..5fdf5aa
--- /dev/null
+++ b/test/Lexer/Inputs/success.h
@@ -0,0 +1 @@
+#error success
diff --git a/test/Lexer/bcpl-escaped-newline.c b/test/Lexer/bcpl-escaped-newline.c
index d87ee9b..05d4773 100644
--- a/test/Lexer/bcpl-escaped-newline.c
+++ b/test/Lexer/bcpl-escaped-newline.c
@@ -11,3 +11,4 @@
 // Trailing whitespace!
 //\ 
 #error quux
+// expected-warning@-2 {{backslash and newline separated by space}}
diff --git a/test/Lexer/clang-keywords.cpp b/test/Lexer/clang-keywords.cpp
deleted file mode 100644
index 3a24dce..0000000
--- a/test/Lexer/clang-keywords.cpp
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-// expected-no-diagnostics
-__char16_t c16;
-void f(__char32_t) { }
diff --git a/test/Lexer/cross-windows-on-linux-default.cpp b/test/Lexer/cross-windows-on-linux-default.cpp
new file mode 100644
index 0000000..520b419
--- /dev/null
+++ b/test/Lexer/cross-windows-on-linux-default.cpp
@@ -0,0 +1,6 @@
+// RUN: not %clang_cc1 -fsyntax-only -fms-compatibility -triple i686-win32 %s 2>&1 \
+// RUN:   | FileCheck %s
+
+#include "Inputs\success.h"
+
+// CHECK: error: success
diff --git a/test/Lexer/cross-windows-on-linux.cpp b/test/Lexer/cross-windows-on-linux.cpp
new file mode 100644
index 0000000..810e1d6
--- /dev/null
+++ b/test/Lexer/cross-windows-on-linux.cpp
@@ -0,0 +1,15 @@
+// RUN: not %clang_cc1 -fsyntax-only -triple i686-win32 %s 2>&1 | FileCheck %s
+
+#include "Inputs\success.h"
+
+// CHECK: error: 'Inputs\success.h' file not found
+// CHECK: #include "Inputs\success.h"
+// CHECK:          ^
+
+// expected to fail on windows as the inclusion would succeed and the
+// compilation will fail due to the '#error success'.
+// XFAIL: win32
+
+// This test may or may not fail since 'Inputs\success.h' is passed
+// to Win32 APIs on Windows.
+// REQUIRES: disabled
diff --git a/test/Lexer/cxx-features.cpp b/test/Lexer/cxx-features.cpp
new file mode 100644
index 0000000..1202ecb
--- /dev/null
+++ b/test/Lexer/cxx-features.cpp
@@ -0,0 +1,89 @@
+// RUN: %clang_cc1 -std=c++98 -verify %s
+// RUN: %clang_cc1 -std=c++11 -verify %s
+// RUN: %clang_cc1 -std=c++1y -verify %s
+
+// expected-no-diagnostics
+
+#if __cplusplus < 201103L
+#define check(macro, cxx98, cxx11, cxx1y) cxx98 == 0 ? defined(__cpp_##macro) : __cpp_##macro != cxx98
+#elif __cplusplus < 201304L
+#define check(macro, cxx98, cxx11, cxx1y) cxx11 == 0 ? defined(__cpp_##macro) : __cpp_##macro != cxx11
+#else
+#define check(macro, cxx98, cxx11, cxx1y) cxx1y == 0 ? defined(__cpp_##macro) : __cpp_##macro != cxx1y
+#endif
+
+#if check(binary_literals, 0, 0, 201304)
+#error "wrong value for __cpp_binary_literals"
+#endif
+
+#if check(init_captures, 0, 0, 201304)
+#error "wrong value for __cpp_init_captures"
+#endif
+
+#if check(generic_lambdas, 0, 0, 201304)
+#error "wrong value for __cpp_generic_lambdas"
+#endif
+
+#if check(constexpr, 0, 200704, 201304)
+#error "wrong value for __cpp_constexpr"
+#endif
+
+#if check(decltype_auto, 0, 0, 201304)
+#error "wrong value for __cpp_decltype_auto"
+#endif
+
+#if check(return_type_deduction, 0, 0, 201304)
+#error "wrong value for __cpp_return_type_deduction"
+#endif
+
+#if check(runtime_arrays, 0, 0, 0)
+#error "wrong value for __cpp_runtime_arrays"
+#endif
+
+#if check(aggregate_nsdmi, 0, 0, 201304)
+#error "wrong value for __cpp_aggregate_nsdmi"
+#endif
+
+#if check(variable_templates, 0, 0, 201304)
+#error "wrong value for __cpp_variable_templates"
+#endif
+
+#if check(unicode_characters, 0, 200704, 200704)
+#error "wrong value for __cpp_unicode_characters"
+#endif
+
+#if check(raw_strings, 0, 200710, 200710)
+#error "wrong value for __cpp_raw_strings"
+#endif
+
+#if check(unicode_literals, 0, 200710, 200710)
+#error "wrong value for __cpp_unicode_literals"
+#endif
+
+#if check(user_defined_literals, 0, 200809, 200809)
+#error "wrong value for __cpp_user_defined_literals"
+#endif
+
+#if check(lambdas, 0, 200907, 200907)
+#error "wrong value for __cpp_lambdas"
+#endif
+
+#if check(static_assert, 0, 200410, 200410)
+#error "wrong value for __cpp_static_assert"
+#endif
+
+#if check(decltype, 0, 200707, 200707)
+#error "wrong value for __cpp_decltype"
+#endif
+
+#if check(attributes, 0, 200809, 200809)
+#error "wrong value for __cpp_attributes"
+#endif
+
+#if check(rvalue_references, 0, 200610, 200610)
+#error "wrong value for __cpp_rvalue_references"
+#endif
+
+#if check(variadic_templates, 0, 200704, 200704)
+#error "wrong value for __cpp_variadic_templates"
+#endif
diff --git a/test/Lexer/cxx0x_keyword.cpp b/test/Lexer/cxx0x_keyword.cpp
deleted file mode 100644
index e6841ef..0000000
--- a/test/Lexer/cxx0x_keyword.cpp
+++ /dev/null
@@ -1,2 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s 2>&1
-int static_assert; /* expected-error {{expected unqualified-id}} */
diff --git a/test/Lexer/cxx1y_digit_separators.cpp b/test/Lexer/cxx1y_digit_separators.cpp
index 39ea3e7..c4c6aee 100644
--- a/test/Lexer/cxx1y_digit_separators.cpp
+++ b/test/Lexer/cxx1y_digit_separators.cpp
@@ -18,6 +18,8 @@
   int e = 0'b1010; // expected-error {{digit 'b' in octal constant}}
   int f = 0b'1010; // expected-error {{invalid digit 'b' in octal}}
   int g = 123'ms; // expected-error {{digit separator cannot appear at end of digit sequence}}
+  int h = 0x1e+1; // expected-error {{invalid suffix '+1' on integer constant}}
+  int i = 0x1'e+1; // ok, 'e+' is not recognized after a digit separator
 
   int z = 0'123'_foo; //'; // expected-error {{cannot appear at end of digit seq}}
 }
@@ -32,6 +34,20 @@
   float d = 1.0'e1; // expected-error {{digit separator cannot appear at end of digit sequence}}
   float e = 1e'1; // expected-error {{digit separator cannot appear at start of digit sequence}}
   float f = 1e1'ms; // expected-error {{digit separator cannot appear at end of digit sequence}}
+  float g = 0.'0; // expected-error {{digit separator cannot appear at start of digit sequence}}
+  float h = .'0; // '; // expected-error {{expected expression}}, lexed as . followed by character literal
+  float i = 0x.'0p0; // expected-error {{digit separator cannot appear at start of digit sequence}}
+  float j = 0x'0.0p0; // expected-error {{invalid suffix 'x'0.0p0'}}
+  float k = 0x0'.0p0; // '; // expected-error {{expected ';'}}
+  float l = 0x0.'0p0; // expected-error {{digit separator cannot appear at start of digit sequence}}
+  float m = 0x0.0'p0; // expected-error {{digit separator cannot appear at end of digit sequence}}
+  float n = 0x0.0p'0; // expected-error {{digit separator cannot appear at start of digit sequence}}
+  float o = 0x0.0p0'ms; // expected-error {{digit separator cannot appear at end of digit sequence}}
+  float p = 0'e1; // expected-error {{digit separator cannot appear at end of digit sequence}}
+  float q = 0'0e1;
+  float r = 0.'0e1; // expected-error {{digit separator cannot appear at start of digit sequence}}
+  float s = 0.0'e1; // expected-error {{digit separator cannot appear at end of digit sequence}}
+  float t = 0.0e'1; // expected-error {{digit separator cannot appear at start of digit sequence}}
 }
 
 #line 123'456
@@ -41,3 +57,23 @@
 #define M(x, ...) __VA_ARGS__
 constexpr int x = { M(1'2,3'4) };
 static_assert(x == 34, "");
+
+namespace UCNs {
+  // UCNs can appear before digit separators but not after.
+  int a = 0\u1234'5; // expected-error {{invalid suffix '\u1234'5' on integer constant}}
+  int b = 0'\u12345; // '; // expected-error {{expected ';'}}
+  constexpr int c {M(0\u1234'0,0'1)};
+  constexpr int d {M(00'\u1234,0'1)};
+  static_assert(c == 1, "");
+  static_assert(d == 0, "");
+}
+
+namespace UTF8 {
+  // extended characters can appear before digit separators but not after.
+  int a = 0ሴ'5; // expected-error {{invalid suffix 'ሴ'5' on integer constant}}
+  int b = 0'ሴ5; // '; // expected-error {{expected ';'}}
+  constexpr int c {M(0ሴ'0,0'1)};
+  constexpr int d {M(00'ሴ,0'1)};
+  static_assert(c == 1, "");
+  static_assert(d == 0, "");
+}
diff --git a/test/Lexer/cxx1z-trigraphs.cpp b/test/Lexer/cxx1z-trigraphs.cpp
new file mode 100644
index 0000000..410626f
--- /dev/null
+++ b/test/Lexer/cxx1z-trigraphs.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -std=c++1z %s -verify
+// RUN: %clang_cc1 -std=c++1z %s -trigraphs -fsyntax-only
+
+??= define foo ; // expected-error {{}} expected-warning {{trigraph ignored}}
+
+static_assert("??="[0] == '#', ""); // expected-error {{failed}} expected-warning {{trigraph ignored}}
+
+// ??/
+error here; // expected-error {{}}
diff --git a/test/Lexer/gnu_keywords.c b/test/Lexer/gnu_keywords.c
deleted file mode 100644
index 10a7d31..0000000
--- a/test/Lexer/gnu_keywords.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// RUN: %clang_cc1 -DGNU_KEYWORDS -std=gnu89 -fsyntax-only -verify %s
-// RUN: %clang_cc1 -DGNU_KEYWORDS -std=c99 -fgnu-keywords -fsyntax-only -verify %s
-// RUN: %clang_cc1 -std=c99 -fsyntax-only -verify %s
-// RUN: %clang_cc1 -std=gnu89 -fno-gnu-keywords -fsyntax-only -verify %s
-// expected-no-diagnostics
-
-void f() {
-#ifdef GNU_KEYWORDS
-  asm ("ret" : :);
-#else
-  int asm;
-#endif
-}
diff --git a/test/Lexer/has_feature_cxx0x.cpp b/test/Lexer/has_feature_cxx0x.cpp
index b2fe842..e558f88 100644
--- a/test/Lexer/has_feature_cxx0x.cpp
+++ b/test/Lexer/has_feature_cxx0x.cpp
@@ -396,3 +396,23 @@
 // CHECK-1Y: has_init_captures
 // CHECK-11: no_init_captures
 // CHECK-NO-11: no_init_captures
+
+#if __has_feature(cxx_decltype_auto)
+int has_decltype_auto();
+#else
+int no_decltype_auto();
+#endif
+
+// CHECK-1Y: has_decltype_auto
+// CHECK-11: no_decltype_auto
+// CHECK-NO-11: no_decltype_auto
+
+#if __has_feature(cxx_generic_lambdas)
+int has_generic_lambdas();
+#else
+int no_generic_lambdas();
+#endif
+
+// CHECK-1Y: has_generic_lambdas
+// CHECK-11: no_generic_lambdas
+// CHECK-NO-11: no_generic_lambdas
diff --git a/test/Lexer/has_feature_exceptions.cpp b/test/Lexer/has_feature_exceptions.cpp
index bb5dc0c..242a015 100644
--- a/test/Lexer/has_feature_exceptions.cpp
+++ b/test/Lexer/has_feature_exceptions.cpp
@@ -1,4 +1,10 @@
-// RUN: %clang_cc1 -E -fexceptions %s -o - | FileCheck --check-prefix=CHECK-EXCEPTIONS %s
+// RUN: %clang -E -fexceptions %s -o - | FileCheck --check-prefix=CHECK-EXCEPTIONS %s
+// RUN: %clang -E -fexceptions -fno-cxx-exceptions %s -o - | FileCheck --check-prefix=CHECK-NO-EXCEPTIONS %s
+// RUN: %clang -E -fno-exceptions %s -o - | FileCheck --check-prefix=CHECK-NO-EXCEPTIONS %s
+
+// RUN: %clang_cc1 -E -fcxx-exceptions %s -o - | FileCheck --check-prefix=CHECK-EXCEPTIONS %s
+// RUN: %clang_cc1 -E -fobjc-exceptions %s -o - | FileCheck --check-prefix=CHECK-NO-EXCEPTIONS %s
+// RUN: %clang_cc1 -E -fexceptions %s -o - | FileCheck --check-prefix=CHECK-NO-EXCEPTIONS %s
 // RUN: %clang_cc1 -E %s -o - | FileCheck --check-prefix=CHECK-NO-EXCEPTIONS %s
 
 #if __has_feature(cxx_exceptions)
diff --git a/test/Lexer/has_feature_type_traits.cpp b/test/Lexer/has_feature_type_traits.cpp
index 0c2cfa5..f772d6d 100644
--- a/test/Lexer/has_feature_type_traits.cpp
+++ b/test/Lexer/has_feature_type_traits.cpp
@@ -55,6 +55,11 @@
 #endif
 // CHECK: int is_class();
 
+#if __has_feature(is_constructible)
+int is_constructible();
+#endif
+// CHECK: int is_constructible();
+
 #if __has_feature(is_convertible_to)
 int is_convertible_to();
 #endif
diff --git a/test/Lexer/hexfloat.cpp b/test/Lexer/hexfloat.cpp
index 9bd8f83..bd53d4a 100644
--- a/test/Lexer/hexfloat.cpp
+++ b/test/Lexer/hexfloat.cpp
@@ -12,4 +12,4 @@
 double i = 0p+3; // expected-error{{invalid suffix 'p' on integer constant}}
 #define PREFIX(x) foo ## x
 double foo0p = 1, j = PREFIX(0p+3); // ok
-double k = 0x42_amp+3; // expected-error-re{{invalid suffix '_amp' on integer constant|no matching literal operator for call to 'operator "" _amp'}}
+double k = 0x42_amp+3; // expected-error-re{{{{invalid suffix '_amp' on integer constant|no matching literal operator for call to 'operator "" _amp'}}}}
diff --git a/test/Lexer/keywords_test.c b/test/Lexer/keywords_test.c
new file mode 100644
index 0000000..4eb1700
--- /dev/null
+++ b/test/Lexer/keywords_test.c
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -std=c99 -E %s -o - | FileCheck --check-prefix=CHECK-NONE %s
+
+// RUN: %clang_cc1 -std=gnu89 -E %s -o - \
+// RUN:     | FileCheck --check-prefix=CHECK-GNU-KEYWORDS %s
+// RUN: %clang_cc1 -std=c99 -fgnu-keywords -E %s -o - \
+// RUN:     | FileCheck --check-prefix=CHECK-GNU-KEYWORDS %s
+// RUN: %clang_cc1 -std=gnu89 -fno-gnu-keywords -E %s -o - \
+// RUN:     | FileCheck --check-prefix=CHECK-NONE %s
+
+// RUN: %clang_cc1 -std=c99 -fms-extensions -E %s -o - \
+// RUN:     | FileCheck --check-prefix=CHECK-MS-KEYWORDS %s
+
+void f() {
+// CHECK-NONE: int asm
+// CHECK-GNU-KEYWORDS: asm ("ret" : :)
+#if __is_identifier(asm)
+  int asm;
+#else
+  asm ("ret" : :);
+#endif
+}
+
+// CHECK-NONE: no_ms_wchar
+// CHECK-MS-KEYWORDS: has_ms_wchar
+#if __is_identifier(__wchar_t)
+void no_ms_wchar();
+#else
+void has_ms_wchar();
+#endif
diff --git a/test/Lexer/keywords_test.cpp b/test/Lexer/keywords_test.cpp
new file mode 100644
index 0000000..19a89c3
--- /dev/null
+++ b/test/Lexer/keywords_test.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -std=c++03 -fsyntax-only %s
+// RUN: %clang_cc1 -std=c++11 -DCXX11 -fsyntax-only %s
+
+#define IS_KEYWORD(NAME) _Static_assert(!__is_identifier(NAME), #NAME)
+#define NOT_KEYWORD(NAME) _Static_assert(__is_identifier(NAME), #NAME)
+#define IS_TYPE(NAME) void is_##NAME##_type() { int f(NAME); }
+
+#ifdef CXX11
+#define CXX11_KEYWORD(NAME)  IS_KEYWORD(NAME)
+#define CXX11_TYPE(NAME)     IS_TYPE(NAME)
+#else
+#define CXX11_KEYWORD(NAME)  NOT_KEYWORD(NAME)
+#define CXX11_TYPE(NAME)
+#endif
+
+// C++11 keywords
+CXX11_KEYWORD(nullptr);
+CXX11_KEYWORD(decltype);
+CXX11_KEYWORD(alignof);
+CXX11_KEYWORD(alignas);
+CXX11_KEYWORD(char16_t);
+CXX11_TYPE(char16_t);
+CXX11_KEYWORD(char32_t);
+CXX11_TYPE(char32_t);
+CXX11_KEYWORD(constexpr);
+CXX11_KEYWORD(noexcept);
+CXX11_KEYWORD(static_assert);
+CXX11_KEYWORD(thread_local);
+
+// Clang extension
+IS_KEYWORD(__char16_t);
+IS_TYPE(__char16_t);
+IS_KEYWORD(__char32_t);
+IS_TYPE(__char32_t);
diff --git a/test/Lexer/ms-extensions.c b/test/Lexer/ms-extensions.c
index 377d2d5..ebcf0f4 100644
--- a/test/Lexer/ms-extensions.c
+++ b/test/Lexer/ms-extensions.c
@@ -1,11 +1,15 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions %s
 // RUN: %clang_cc1 -fsyntax-only -verify -fms-compatibility %s
+// RUN: %clang_cc1 -fsyntax-only -verify -triple i386-pc-win32 -fms-compatibility %s
 
 __int8 x1  = 3i8;
 __int16 x2 = 4i16;
 __int32 x3 = 5i32;
 __int64 x5 = 0x42i64;
 __int64 x6 = 0x42I64;
+#ifndef __SIZEOF_INT128__
+// expected-error@+2 {{__int128 is not supported on this target}}
+#endif
 __int64 x4 = 70000000i128;
 
 __int64 y = 0x42i64u;  // expected-error {{invalid suffix}}
@@ -13,6 +17,10 @@
 __int64 z = 9Li64;  // expected-error {{invalid suffix}}
 __int64 q = 10lli64;  // expected-error {{invalid suffix}}
 
+__complex double c1 = 1i;
+__complex double c2 = 1.0i;
+__complex float c3 = 1.0if;
+
 // radar 7562363
 #define ULLONG_MAX 0xffffffffffffffffui64
 #define UINT 0xffffffffui32
diff --git a/test/Lexer/warn-date-time.c b/test/Lexer/warn-date-time.c
new file mode 100644
index 0000000..96fb553
--- /dev/null
+++ b/test/Lexer/warn-date-time.c
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -Wdate-time -Wno-builtin-macro-redefined %s -verify -E
+// RUN: %clang_cc1 -Wdate-time -Wno-builtin-macro-redefined %s -DIS_SYSHEADER -verify -E
+// RUN: not %clang_cc1 -Werror=date-time -Wno-builtin-macro-redefined %s -DIS_SYSHEADER -E 2>&1 | grep 'error: expansion' | count 3
+
+
+#ifdef IS_HEADER
+
+#ifdef IS_SYSHEADER
+#pragma clang system_header
+#endif
+
+__TIME__ // expected-warning {{expansion of date or time macro is not reproducible}}
+__DATE__  // expected-warning {{expansion of date or time macro is not reproducible}}
+__TIMESTAMP__ // expected-warning {{expansion of date or time macro is not reproducible}}
+
+#define __TIME__
+__TIME__
+
+#else
+
+#define IS_HEADER
+#include __FILE__
+#endif
diff --git a/test/Makefile b/test/Makefile
index dbfa521..bd0bd2e 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -44,10 +44,12 @@
 	@$(ECHOPATH) s=@LLVM_LIBS_DIR@=$(LibDir)=g >> lit.tmp
 	@$(ECHOPATH) s=@CLANG_SOURCE_DIR@=$(PROJ_SRC_DIR)/..=g >> lit.tmp
 	@$(ECHOPATH) s=@CLANG_BINARY_DIR@=$(PROJ_OBJ_DIR)/..=g >> lit.tmp
+	@$(ECHOPATH) s=@CLANG_TOOLS_DIR@=$(ToolDir)=g >> lit.tmp
 	@$(ECHOPATH) s=@TARGET_TRIPLE@=$(TARGET_TRIPLE)=g >> lit.tmp
 	@$(ECHOPATH) s=@ENABLE_CLANG_ARCMT@=$(ENABLE_CLANG_ARCMT)=g >> lit.tmp
-	@$(ECHOPATH) s=@ENABLE_CLANG_REWRITER@=$(ENABLE_CLANG_REWRITER)=g >> lit.tmp
 	@$(ECHOPATH) s=@ENABLE_CLANG_STATIC_ANALYZER@=$(ENABLE_CLANG_STATIC_ANALYZER)=g >> lit.tmp
+	@$(ECHOPATH) s=@ENABLE_CLANG_EXAMPLES@=$(ENABLE_CLANG_EXAMPLES)=g >> lit.tmp
+	@$(ECHOPATH) s=@ENABLE_SHARED@=$(ENABLE_SHARED)=g >> lit.tmp
 	@sed -f lit.tmp $(PROJ_SRC_DIR)/lit.site.cfg.in > $@
 	@-rm -f lit.tmp
 
diff --git a/test/Misc/Inputs/serialized-diags-stable.dia b/test/Misc/Inputs/serialized-diags-stable.dia
new file mode 100644
index 0000000..acdaad2
--- /dev/null
+++ b/test/Misc/Inputs/serialized-diags-stable.dia
Binary files differ
diff --git a/test/Misc/ast-dump-arm-attr.c b/test/Misc/ast-dump-arm-attr.c
new file mode 100644
index 0000000..bec3531
--- /dev/null
+++ b/test/Misc/ast-dump-arm-attr.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -triple arm-apple-darwin -ast-dump -ast-dump-filter Test %s | FileCheck --strict-whitespace %s

+

+__attribute__((interrupt)) void Test(void);

+// CHECK: FunctionDecl{{.*}}Test

+// CHECK-NEXT: ARMInterruptAttr

diff --git a/test/Misc/ast-dump-attr.cpp b/test/Misc/ast-dump-attr.cpp
index 729be1f..1aa6adf 100644
--- a/test/Misc/ast-dump-attr.cpp
+++ b/test/Misc/ast-dump-attr.cpp
@@ -29,12 +29,12 @@
 
 int TestAlignedNull __attribute__((aligned));
 // CHECK:      VarDecl{{.*}}TestAlignedNull
-// CHECK-NEXT:   AlignedAttr
+// CHECK-NEXT:   AlignedAttr {{.*}} aligned
 // CHECK-NEXT:     <<<NULL>>>
 
 int TestAlignedExpr __attribute__((aligned(4)));
 // CHECK:      VarDecl{{.*}}TestAlignedExpr
-// CHECK-NEXT:   AlignedAttr
+// CHECK-NEXT:   AlignedAttr {{.*}} aligned
 // CHECK-NEXT:     IntegerLiteral
 
 int TestEnum __attribute__((visibility("default")));
@@ -63,17 +63,17 @@
 void TestIdentifier(void *, int)
 __attribute__((pointer_with_type_tag(ident1,1,2)));
 // CHECK: FunctionDecl{{.*}}TestIdentifier
-// CHECK:   ArgumentWithTypeTagAttr{{.*}} ident1
+// CHECK:   ArgumentWithTypeTagAttr{{.*}} pointer_with_type_tag ident1
 
 void TestBool(void *, int)
 __attribute__((pointer_with_type_tag(bool1,1,2)));
 // CHECK: FunctionDecl{{.*}}TestBool
-// CHECK:   ArgumentWithTypeTagAttr{{.*}} IsPointer
+// CHECK:   ArgumentWithTypeTagAttr{{.*}}pointer_with_type_tag bool1 0 1 IsPointer
 
 void TestUnsigned(void *, int)
 __attribute__((pointer_with_type_tag(unsigned1,1,2)));
 // CHECK: FunctionDecl{{.*}}TestUnsigned
-// CHECK:   ArgumentWithTypeTagAttr{{.*}} 0 1
+// CHECK:   ArgumentWithTypeTagAttr{{.*}} pointer_with_type_tag unsigned1 0 1
 
 void TestInt(void) __attribute__((constructor(123)));
 // CHECK:      FunctionDecl{{.*}}TestInt
@@ -88,14 +88,6 @@
 // CHECK:      VarDecl{{.*}}TestType
 // CHECK-NEXT:   TypeTagForDatatypeAttr{{.*}} int
 
-void *TestVariadicUnsigned1(int) __attribute__((alloc_size(1)));
-// CHECK: FunctionDecl{{.*}}TestVariadicUnsigned1
-// CHECK:   AllocSizeAttr{{.*}} 0
-
-void *TestVariadicUnsigned2(int, int) __attribute__((alloc_size(1,2)));
-// CHECK: FunctionDecl{{.*}}TestVariadicUnsigned2
-// CHECK:   AllocSizeAttr{{.*}} 0 1
-
 void TestLabel() {
 L: __attribute__((unused)) int i;
 // CHECK: LabelStmt{{.*}}'L'
@@ -111,3 +103,35 @@
 // CHECK: LabelStmt {{.*}} 'N'
 // CHECK-NEXT: NullStmt
 }
+
+namespace Test {
+extern "C" int printf(const char *format, ...);
+// CHECK: FunctionDecl{{.*}}printf
+// CHECK-NEXT: ParmVarDecl{{.*}}format{{.*}}'const char *'
+// CHECK-NEXT: FormatAttr{{.*}}Implicit printf 1 2
+
+alignas(8) extern int x;
+extern int x;
+// CHECK: VarDecl{{.*}} x 'int'
+// CHECK: VarDecl{{.*}} x 'int'
+// CHECK-NEXT: AlignedAttr{{.*}} Inherited
+}
+
+int __attribute__((cdecl)) TestOne(void), TestTwo(void);
+// CHECK: FunctionDecl{{.*}}TestOne{{.*}}__attribute__((cdecl))
+// CHECK: FunctionDecl{{.*}}TestTwo{{.*}}__attribute__((cdecl))
+
+void func() {
+  auto Test = []() __attribute__((no_thread_safety_analysis)) {};
+  // CHECK: CXXMethodDecl{{.*}}operator() 'void (void) const'
+  // CHECK: NoThreadSafetyAnalysisAttr
+
+  // Because GNU's noreturn applies to the function type, and this lambda does
+  // not have a capture list, the call operator and the function pointer
+  // conversion should both be noreturn, but the method should not contain a
+  // NoReturnAttr because the attribute applied to the type.
+  auto Test2 = []() __attribute__((noreturn)) { while(1); };
+  // CHECK: CXXMethodDecl{{.*}}operator() 'void (void) __attribute__((noreturn)) const'
+  // CHECK-NOT: NoReturnAttr
+  // CHECK: CXXConversionDecl{{.*}}operator void (*)() __attribute__((noreturn))
+}
diff --git a/test/Misc/ast-dump-color.cpp b/test/Misc/ast-dump-color.cpp
index a41c0bb..b4660b4 100644
--- a/test/Misc/ast-dump-color.cpp
+++ b/test/Misc/ast-dump-color.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-pc-linux -std=c++11 -ast-dump -fcolor-diagnostics %s | FileCheck --strict-whitespace %s
+// RUN: not %clang_cc1 -triple x86_64-pc-linux -std=c++11 -ast-dump -fcolor-diagnostics %s | FileCheck --strict-whitespace %s
 // REQUIRES: ansi-escape-sequences
 
 /// <a>Hello</a>
@@ -25,22 +25,26 @@
 } mu1, mu2;
 int TestExpr __attribute__((guarded_by(mu1)));
 
-//CHECK: {{^}}[[Blue:.\[0;34m]][[RESET:.\[0m]][[GREEN:.\[0;1;32m]]TranslationUnitDecl[[RESET]][[Yellow:.\[0;33m]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]<invalid sloc>[[RESET]]>{{$}}
-//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]TypedefDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]<invalid sloc>[[RESET]]>[[CYAN:.\[0;1;36m]] __int128_t[[RESET]] [[Green:.\[0;32m]]'__int128'[[RESET]]{{$}}
-//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]TypedefDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]<invalid sloc>[[RESET]]>[[CYAN]] __uint128_t[[RESET]] [[Green]]'unsigned __int128'[[RESET]]{{$}}
-//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]TypedefDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]<invalid sloc>[[RESET]]>[[CYAN]] __builtin_va_list[[RESET]] [[Green]]'__va_list_tag [1]'[[RESET]]{{$}}
-//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]VarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]{{.*}}ast-dump-color.cpp:6:1[[RESET]], [[Yellow]]col:5[[RESET]]>[[CYAN]] Test[[RESET]] [[Green]]'int'[[RESET]]{{$}}
+struct Invalid {
+  __attribute__((noinline)) Invalid(error);
+} Invalid;
+
+//CHECK: {{^}}[[Blue:.\[0;34m]][[RESET:.\[0m]][[GREEN:.\[0;1;32m]]TranslationUnitDecl[[RESET]][[Yellow:.\[0;33m]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]<invalid sloc>[[RESET]]> [[Yellow]]<invalid sloc>[[RESET]]{{$}}
+//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]TypedefDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]<invalid sloc>[[RESET]]> [[Yellow]]<invalid sloc>[[RESET]] implicit[[CYAN:.\[0;1;36m]] __int128_t[[RESET]] [[Green:.\[0;32m]]'__int128'[[RESET]]{{$}}
+//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]TypedefDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]<invalid sloc>[[RESET]]> [[Yellow]]<invalid sloc>[[RESET]] implicit[[CYAN]] __uint128_t[[RESET]] [[Green]]'unsigned __int128'[[RESET]]{{$}}
+//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]TypedefDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]<invalid sloc>[[RESET]]> [[Yellow]]<invalid sloc>[[RESET]] implicit[[CYAN]] __builtin_va_list[[RESET]] [[Green]]'__va_list_tag [1]'[[RESET]]{{$}}
+//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]VarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]{{.*}}ast-dump-color.cpp:6:1[[RESET]], [[Yellow]]col:5[[RESET]]> [[Yellow]]col:5[[RESET]][[CYAN]] Test[[RESET]] [[Green]]'int'[[RESET]]
 //CHECK: {{^}}[[Blue]]| |-[[RESET]][[BLUE:.\[0;1;34m]]UnusedAttr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:25[[RESET]]>{{$}}
-//CHECK: {{^}}[[Blue]]| `-[[RESET]][[YELLOW:.\[0;1;33m]]FullComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:4:4[[RESET]], [[Yellow]]line:5:8[[RESET]]>{{$}}
-//CHECK: {{^}}[[Blue]]|   `-[[RESET]][[YELLOW]]ParagraphComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:4:4[[RESET]], [[Yellow]]line:5:8[[RESET]]>{{$}}
-//CHECK: {{^}}[[Blue]]|     |-[[RESET]][[YELLOW]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:4:4[[RESET]]> Text=" "{{$}}
-//CHECK: {{^}}[[Blue]]|     |-[[RESET]][[YELLOW]]HTMLStartTagComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:5[[RESET]], [[Yellow]]col:7[[RESET]]> Name="a"{{$}}
-//CHECK: {{^}}[[Blue]]|     |-[[RESET]][[YELLOW]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]], [[Yellow]]col:12[[RESET]]> Text="Hello"{{$}}
-//CHECK: {{^}}[[Blue]]|     |-[[RESET]][[YELLOW]]HTMLEndTagComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:13[[RESET]], [[Yellow]]col:16[[RESET]]> Name="a"{{$}}
-//CHECK: {{^}}[[Blue]]|     |-[[RESET]][[YELLOW]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:5:4[[RESET]]> Text=" "{{$}}
-//CHECK: {{^}}[[Blue]]|     `-[[RESET]][[YELLOW]]HTMLStartTagComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:5[[RESET]], [[Yellow]]col:8[[RESET]]> Name="br" SelfClosing{{$}}
-//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]FunctionDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:9:1[[RESET]], [[Yellow]]line:16:1[[RESET]]>[[CYAN]] TestAttributedStmt[[RESET]] [[Green]]'void (void)'[[RESET]]{{$}}
-//CHECK: {{^}}[[Blue]]| |-[[RESET]][[MAGENTA:.\[0;1;35m]]CompoundStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:9:27[[RESET]], [[Yellow]]line:16:1[[RESET]]>{{$}}
+//CHECK: {{^}}[[Blue]]| `-[[RESET]][[Blue]]FullComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:4:4[[RESET]], [[Yellow]]line:5:8[[RESET]]>{{$}}
+//CHECK: {{^}}[[Blue]]|   `-[[RESET]][[Blue]]ParagraphComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:4:4[[RESET]], [[Yellow]]line:5:8[[RESET]]>{{$}}
+//CHECK: {{^}}[[Blue]]|     |-[[RESET]][[Blue]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:4:4[[RESET]]> Text=" "{{$}}
+//CHECK: {{^}}[[Blue]]|     |-[[RESET]][[Blue]]HTMLStartTagComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:5[[RESET]], [[Yellow]]col:7[[RESET]]> Name="a"{{$}}
+//CHECK: {{^}}[[Blue]]|     |-[[RESET]][[Blue]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]], [[Yellow]]col:12[[RESET]]> Text="Hello"{{$}}
+//CHECK: {{^}}[[Blue]]|     |-[[RESET]][[Blue]]HTMLEndTagComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:13[[RESET]], [[Yellow]]col:16[[RESET]]> Name="a"{{$}}
+//CHECK: {{^}}[[Blue]]|     |-[[RESET]][[Blue]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:5:4[[RESET]]> Text=" "{{$}}
+//CHECK: {{^}}[[Blue]]|     `-[[RESET]][[Blue]]HTMLStartTagComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:5[[RESET]], [[Yellow]]col:8[[RESET]]> Name="br" SelfClosing{{$}}
+//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]FunctionDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:9:1[[RESET]], [[Yellow]]line:16:1[[RESET]]> [[Yellow]]line:9:6[[RESET]][[CYAN]] TestAttributedStmt[[RESET]] [[Green]]'void (void)'[[RESET]]{{$}}
+//CHECK: {{^}}[[Blue]]| |-[[RESET]][[MAGENTA:.\[0;1;35m]]CompoundStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:27[[RESET]], [[Yellow]]line:16:1[[RESET]]>{{$}}
 //CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]SwitchStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:10:3[[RESET]], [[Yellow]]line:15:3[[RESET]]>{{$}}
 //CHECK: {{^}}[[Blue]]| |   |-[[RESET]][[Blue:.\[0;34m]]<<<NULL>>>[[RESET]]{{$}}
 //CHECK: {{^}}[[Blue]]| |   |-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:10:11[[RESET]]> [[Green]]'int'[[RESET]][[Cyan:.\[0;36m]][[RESET]][[Cyan]][[RESET]][[CYAN]] 1[[RESET]]{{$}}
@@ -55,33 +59,45 @@
 //CHECK: {{^}}[[Blue]]| |       |-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:13:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]][[CYAN]] 2[[RESET]]{{$}}
 //CHECK: {{^}}[[Blue]]| |       |-[[RESET]][[Blue]]<<<NULL>>>[[RESET]]{{$}}
 //CHECK: {{^}}[[Blue]]| |       `-[[RESET]][[MAGENTA]]NullStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:14:5[[RESET]]>{{$}}
-//CHECK: {{^}}[[Blue]]| `-[[RESET]][[YELLOW]]FullComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:8:4[[RESET]], [[Yellow]]col:11[[RESET]]>{{$}}
-//CHECK: {{^}}[[Blue]]|   `-[[RESET]][[YELLOW]]ParagraphComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:4[[RESET]], [[Yellow]]col:11[[RESET]]>{{$}}
-//CHECK: {{^}}[[Blue]]|     `-[[RESET]][[YELLOW]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:4[[RESET]], [[Yellow]]col:11[[RESET]]> Text=" Comment"{{$}}
-//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]CXXRecordDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:18:1[[RESET]], [[Yellow]]line:25:1[[RESET]]> class[[CYAN]] Mutex[[RESET]] definition{{$}}
-//CHECK: {{^}}[[Blue]]| |-[[RESET]][[BLUE]]LockableAttr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:18:22[[RESET]]>{{$}}
-//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXRecordDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:1[[RESET]], [[Yellow]]col:33[[RESET]]> class[[CYAN]] Mutex[[RESET]]{{$}}
-//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]FieldDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:20:3[[RESET]], [[Yellow]]col:7[[RESET]]>[[CYAN]] var1[[RESET]] [[Green]]'int'[[RESET]]{{$}}
-//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[YELLOW]]FullComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:19:6[[RESET]], [[Yellow]]col:16[[RESET]]>{{$}}
-//CHECK: {{^}}[[Blue]]| |   `-[[RESET]][[YELLOW]]ParagraphComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:6[[RESET]], [[Yellow]]col:16[[RESET]]>{{$}}
-//CHECK: {{^}}[[Blue]]| |     `-[[RESET]][[YELLOW]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:6[[RESET]], [[Yellow]]col:16[[RESET]]> Text=" A variable"{{$}}
-//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]FieldDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:24:3[[RESET]], [[Yellow]]col:7[[RESET]]>[[CYAN]] var2[[RESET]] [[Green]]'int'[[RESET]]{{$}}
-//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[YELLOW]]FullComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:21:6[[RESET]], [[Yellow]]line:23:44[[RESET]]>{{$}}
-//CHECK: {{^}}[[Blue]]| |   |-[[RESET]][[YELLOW]]ParagraphComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:21:6[[RESET]], [[Yellow]]col:22[[RESET]]>{{$}}
-//CHECK: {{^}}[[Blue]]| |   | `-[[RESET]][[YELLOW]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:6[[RESET]], [[Yellow]]col:22[[RESET]]> Text=" Another variable"{{$}}
-//CHECK: {{^}}[[Blue]]| |   `-[[RESET]][[YELLOW]]ParagraphComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:23:6[[RESET]], [[Yellow]]col:44[[RESET]]>{{$}}
-//CHECK: {{^}}[[Blue]]| |     `-[[RESET]][[YELLOW]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:6[[RESET]], [[Yellow]]col:44[[RESET]]> Text=" Like the other variable, but different"{{$}}
-//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:18:33[[RESET]]>[[CYAN]] Mutex[[RESET]] [[Green]]'void (void)'[[RESET]] inline{{.*$}}
+//CHECK: {{^}}[[Blue]]| `-[[RESET]][[Blue]]FullComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:8:4[[RESET]], [[Yellow]]col:11[[RESET]]>{{$}}
+//CHECK: {{^}}[[Blue]]|   `-[[RESET]][[Blue]]ParagraphComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:4[[RESET]], [[Yellow]]col:11[[RESET]]>{{$}}
+//CHECK: {{^}}[[Blue]]|     `-[[RESET]][[Blue]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:4[[RESET]], [[Yellow]]col:11[[RESET]]> Text=" Comment"{{$}}
+//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]CXXRecordDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:18:1[[RESET]], [[Yellow]]line:25:1[[RESET]]> [[Yellow]]line:18:33[[RESET]] class[[CYAN]] Mutex[[RESET]] definition{{$}}
+//CHECK: {{^}}[[Blue]]| |-[[RESET]][[BLUE]]CapabilityAttr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:22[[RESET]]> capability "mutex"{{$}}
+//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXRecordDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:1[[RESET]], [[Yellow]]col:33[[RESET]]> [[Yellow]]col:33[[RESET]] implicit class[[CYAN]] Mutex[[RESET]]{{$}}
+//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]FieldDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:20:3[[RESET]], [[Yellow]]col:7[[RESET]]> [[Yellow]]col:7[[RESET]][[CYAN]] var1[[RESET]] [[Green]]'int'[[RESET]]{{$}}
+//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[Blue]]FullComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:19:6[[RESET]], [[Yellow]]col:16[[RESET]]>{{$}}
+//CHECK: {{^}}[[Blue]]| |   `-[[RESET]][[Blue]]ParagraphComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:6[[RESET]], [[Yellow]]col:16[[RESET]]>{{$}}
+//CHECK: {{^}}[[Blue]]| |     `-[[RESET]][[Blue]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:6[[RESET]], [[Yellow]]col:16[[RESET]]> Text=" A variable"{{$}}
+//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]FieldDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:24:3[[RESET]], [[Yellow]]col:7[[RESET]]> [[Yellow]]col:7[[RESET]][[CYAN]] var2[[RESET]] [[Green]]'int'[[RESET]]{{$}}
+//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[Blue]]FullComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:21:6[[RESET]], [[Yellow]]line:23:44[[RESET]]>{{$}}
+//CHECK: {{^}}[[Blue]]| |   |-[[RESET]][[Blue]]ParagraphComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:21:6[[RESET]], [[Yellow]]col:22[[RESET]]>{{$}}
+//CHECK: {{^}}[[Blue]]| |   | `-[[RESET]][[Blue]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:6[[RESET]], [[Yellow]]col:22[[RESET]]> Text=" Another variable"{{$}}
+//CHECK: {{^}}[[Blue]]| |   `-[[RESET]][[Blue]]ParagraphComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:23:6[[RESET]], [[Yellow]]col:44[[RESET]]>{{$}}
+//CHECK: {{^}}[[Blue]]| |     `-[[RESET]][[Blue]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:6[[RESET]], [[Yellow]]col:44[[RESET]]> Text=" Like the other variable, but different"{{$}}
+//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:18:33[[RESET]]> [[Yellow]]col:33[[RESET]] implicit used[[CYAN]] Mutex[[RESET]] [[Green]]'void (void)'[[RESET]] inline{{.*$}}
 //CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]CompoundStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:33[[RESET]]>{{$}}
-//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:33[[RESET]]>[[CYAN]] Mutex[[RESET]] [[Green]]'void (const class Mutex &)'[[RESET]] inline{{ .*$}}
-//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[GREEN]]ParmVarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:33[[RESET]]> [[Green]]'const class Mutex &'[[RESET]]{{$}}
-//CHECK: {{^}}[[Blue]]| `-[[RESET]][[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:33[[RESET]]>[[CYAN]] Mutex[[RESET]] [[Green]]'void (class Mutex &&)'[[RESET]] inline{{ .*$}}
-//CHECK: {{^}}[[Blue]]|   `-[[RESET]][[GREEN]]ParmVarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:33[[RESET]]> [[Green]]'class Mutex &&'[[RESET]]{{$}}
-//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]VarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:1[[RESET]], [[Yellow]]line:25:3[[RESET]]>[[CYAN]] mu1[[RESET]] [[Green]]'class Mutex':'class Mutex'[[RESET]]{{$}}
+//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:33[[RESET]]> [[Yellow]]col:33[[RESET]] implicit[[CYAN]] Mutex[[RESET]] [[Green]]'void (const class Mutex &)'[[RESET]] inline{{ .*$}}
+//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[GREEN]]ParmVarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:33[[RESET]]> [[Yellow]]col:33[[RESET]] [[Green]]'const class Mutex &'[[RESET]]{{$}}
+//CHECK: {{^}}[[Blue]]| `-[[RESET]][[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:33[[RESET]]> [[Yellow]]col:33[[RESET]] implicit[[CYAN]] Mutex[[RESET]] [[Green]]'void (class Mutex &&)'[[RESET]] inline{{ .*$}}
+//CHECK: {{^}}[[Blue]]|   `-[[RESET]][[GREEN]]ParmVarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:33[[RESET]]> [[Yellow]]col:33[[RESET]] [[Green]]'class Mutex &&'[[RESET]]{{$}}
+//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]VarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:1[[RESET]], [[Yellow]]line:25:3[[RESET]]> [[Yellow]]col:3[[RESET]] referenced[[CYAN]] mu1[[RESET]] [[Green]]'class Mutex':'class Mutex'[[RESET]]
 //CHECK: {{^}}[[Blue]]| `-[[RESET]][[MAGENTA]]CXXConstructExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:3[[RESET]]> [[Green]]'class Mutex':'class Mutex'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]] [[Green]]'void (void)'[[RESET]]{{$}}
-//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]VarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:18:1[[RESET]], [[Yellow]]line:25:8[[RESET]]>[[CYAN]] mu2[[RESET]] [[Green]]'class Mutex':'class Mutex'[[RESET]]{{$}}
+//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]VarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:18:1[[RESET]], [[Yellow]]line:25:8[[RESET]]> [[Yellow]]col:8[[RESET]][[CYAN]] mu2[[RESET]] [[Green]]'class Mutex':'class Mutex'[[RESET]]
 //CHECK: {{^}}[[Blue]]| `-[[RESET]][[MAGENTA]]CXXConstructExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]> [[Green]]'class Mutex':'class Mutex'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]] [[Green]]'void (void)'[[RESET]]{{$}}
-//CHECK: {{^}}[[Blue]]`-[[RESET]][[GREEN]]VarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:26:1[[RESET]], [[Yellow]]col:5[[RESET]]>[[CYAN]] TestExpr[[RESET]] [[Green]]'int'[[RESET]]{{$}}
-//CHECK: {{^}}[[Blue]]  `-[[RESET]][[BLUE]]GuardedByAttr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:29[[RESET]]>{{$}}
-//CHECK: {{^}}[[Blue]]    `-[[RESET]][[MAGENTA]]DeclRefExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:40[[RESET]]> [[Green]]'class Mutex':'class Mutex'[[RESET]][[Cyan]] lvalue[[RESET]][[Cyan]][[RESET]] [[GREEN]]Var[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]][[CYAN]] 'mu1'[[RESET]] [[Green]]'class Mutex':'class Mutex'[[RESET]]{{$}}
-
+//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]VarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:26:1[[RESET]], [[Yellow]]col:5[[RESET]]> [[Yellow]]col:5[[RESET]][[CYAN]] TestExpr[[RESET]] [[Green]]'int'[[RESET]]
+//CHECK: {{^}}[[Blue]]| `-[[RESET]][[BLUE]]GuardedByAttr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:29[[RESET]], [[Yellow]]col:43[[RESET]]>{{$}}
+//CHECK: {{^}}[[Blue]]|   `-[[RESET]][[MAGENTA]]DeclRefExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:40[[RESET]]> [[Green]]'class Mutex':'class Mutex'[[RESET]][[Cyan]] lvalue[[RESET]][[Cyan]][[RESET]] [[GREEN]]Var[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]][[CYAN]] 'mu1'[[RESET]] [[Green]]'class Mutex':'class Mutex'[[RESET]]{{$}}
+//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]CXXRecordDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:28:1[[RESET]], [[Yellow]]line:30:1[[RESET]]> [[Yellow]]line:28:8[[RESET]] struct[[CYAN]] Invalid[[RESET]] definition
+//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXRecordDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:1[[RESET]], [[Yellow]]col:8[[RESET]]> [[Yellow]]col:8[[RESET]] implicit struct[[CYAN]] Invalid[[RESET]]
+//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:29:3[[RESET]], [[Yellow]]col:42[[RESET]]> [[Yellow]]col:29[[RESET]] invalid[[CYAN]] Invalid[[RESET]] [[Green]]'void (int)'[[RESET]]
+//CHECK: {{^}}[[Blue]]| | |-[[RESET]][[GREEN]]ParmVarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:37[[RESET]], [[Yellow]]<invalid sloc>[[RESET]]> [[Yellow]]col:42[[RESET]] invalid [[Green]]'int'[[RESET]]
+//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[BLUE]]NoInlineAttr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:18[[RESET]]>
+//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:28:8[[RESET]]> [[Yellow]]col:8[[RESET]] implicit used[[CYAN]] Invalid[[RESET]] [[Green]]'void (void)'[[RESET]] inline noexcept-unevaluated 0x{{[0-9a-fA-F]*}}
+//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]CompoundStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]>
+//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]> [[Yellow]]col:8[[RESET]] implicit[[CYAN]] Invalid[[RESET]] [[Green]]'void (const struct Invalid &)'[[RESET]] inline noexcept-unevaluated 0x{{[0-9a-fA-F]*}}
+//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[GREEN]]ParmVarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]> [[Yellow]]col:8[[RESET]] [[Green]]'const struct Invalid &'[[RESET]]
+//CHECK: {{^}}[[Blue]]| `-[[RESET]][[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]> [[Yellow]]col:8[[RESET]] implicit[[CYAN]] Invalid[[RESET]] [[Green]]'void (struct Invalid &&)'[[RESET]] inline noexcept-unevaluated 0x{{[0-9a-fA-F]*}}
+//CHECK: {{^}}[[Blue]]|   `-[[RESET]][[GREEN]]ParmVarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]> [[Yellow]]col:8[[RESET]] [[Green]]'struct Invalid &&'[[RESET]]
+//CHECK: {{^}}[[Blue]]`-[[RESET]][[GREEN]]VarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:1[[RESET]], [[Yellow]]line:30:3[[RESET]]> [[Yellow]]col:3[[RESET]][[CYAN]] Invalid[[RESET]] [[Green]]'struct Invalid':'struct Invalid'[[RESET]]
+//CHECK: {{^}}[[Blue]]  `-[[RESET]][[MAGENTA]]CXXConstructExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:3[[RESET]]> [[Green]]'struct Invalid':'struct Invalid'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]] [[Green]]'void (void)'[[RESET]]
diff --git a/test/Misc/ast-dump-comment.cpp b/test/Misc/ast-dump-comment.cpp
index 4e84af0..5bd6934 100644
--- a/test/Misc/ast-dump-comment.cpp
+++ b/test/Misc/ast-dump-comment.cpp
@@ -67,3 +67,11 @@
 // CHECK:      VarDecl{{.*}}Test_VerbatimBlockComment
 // CHECK:        VerbatimBlockComment{{.*}} Name="verbatim" CloseName="endverbatim"
 // CHECK-NEXT:     VerbatimBlockLineComment{{.*}} Text=" Aaa"
+
+/// \param ... More arguments
+template<typename T>
+void Test_TemplatedFunctionVariadic(int arg, ...);
+// CHECK:      FunctionTemplateDecl{{.*}}Test_TemplatedFunctionVariadic
+// CHECK:        ParamCommandComment{{.*}} [in] implicitly Param="..."
+// CHECK-NEXT:     ParagraphComment
+// CHECK-NEXT:       TextComment{{.*}} Text=" More arguments"
diff --git a/test/Misc/ast-dump-decl.c b/test/Misc/ast-dump-decl.c
index 94335b8..7d39e6b 100644
--- a/test/Misc/ast-dump-decl.c
+++ b/test/Misc/ast-dump-decl.c
@@ -2,7 +2,7 @@
 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -ast-dump %s | FileCheck -check-prefix CHECK-TU -strict-whitespace %s
 
 int TestLocation;
-// CHECK: VarDecl 0x{{[^ ]*}} <{{.*}}:4:1, col:5> TestLocation
+// CHECK: VarDecl 0x{{[^ ]*}} <{{.*}}:4:1, col:5> col:5 TestLocation
 
 struct TestIndent {
   int x;
@@ -47,7 +47,7 @@
   } e;
 };
 // CHECK:      RecordDecl{{.*}} TestEnumDeclAnon
-// CHECK-NEXT:   EnumDecl{{.*>$}}
+// CHECK-NEXT:   EnumDecl{{.*> .*$}}
 
 enum TestEnumDeclForward;
 // CHECK:      EnumDecl{{.*}} TestEnumDeclForward
diff --git a/test/Misc/ast-dump-decl.cpp b/test/Misc/ast-dump-decl.cpp
index d98bdb5..b41e4ee 100644
--- a/test/Misc/ast-dump-decl.cpp
+++ b/test/Misc/ast-dump-decl.cpp
@@ -133,6 +133,31 @@
 // CHECK:      CXXDestructorDecl{{.*}} ~TestCXXDestructorDecl 'void (void) noexcept'
 // CHECK-NEXT:   CompoundStmt
 
+// Test that the range of a defaulted members is computed correctly.
+// FIXME: This should include the "= default".
+class TestMemberRanges {
+public:
+  TestMemberRanges() = default;
+  TestMemberRanges(const TestMemberRanges &Other) = default;
+  TestMemberRanges(TestMemberRanges &&Other) = default;
+  ~TestMemberRanges() = default;
+  TestMemberRanges &operator=(const TestMemberRanges &Other) = default;
+  TestMemberRanges &operator=(TestMemberRanges &&Other) = default;
+};
+void SomeFunction() {
+  TestMemberRanges A;
+  TestMemberRanges B(A);
+  B = A;
+  A = static_cast<TestMemberRanges &&>(B);
+  TestMemberRanges C(static_cast<TestMemberRanges &&>(A));
+}
+// CHECK:      CXXConstructorDecl{{.*}} <line:{{.*}}:3, col:20>
+// CHECK:      CXXConstructorDecl{{.*}} <line:{{.*}}:3, col:49>
+// CHECK:      CXXConstructorDecl{{.*}} <line:{{.*}}:3, col:44>
+// CHECK:      CXXDestructorDecl{{.*}} <line:{{.*}}:3, col:21>
+// CHECK:      CXXMethodDecl{{.*}} <line:{{.*}}:3, col:60>
+// CHECK:      CXXMethodDecl{{.*}} <line:{{.*}}:3, col:55>
+
 class TestCXXConversionDecl {
   operator int() { return 0; }
 };
@@ -143,7 +168,7 @@
   static_assert(true, "msg");
 }
 // CHECK:      NamespaceDecl{{.*}} TestStaticAssertDecl
-// CHECK-NEXT:   StaticAssertDecl{{.*>$}}
+// CHECK-NEXT:   StaticAssertDecl{{.*> .*$}}
 // CHECK-NEXT:     CXXBoolLiteralExpr
 // CHECK-NEXT:     StringLiteral
 
@@ -273,7 +298,7 @@
   // CHECK-NEXT:   FunctionDecl{{.*}} TestFunctionTemplate 'void (T)'
   // CHECK-NEXT:     ParmVarDecl{{.*}} 'T'
   // CHECK-NEXT:   Function{{.*}} 'TestFunctionTemplate'
-  // CHECK-NEXT-NOT: TemplateArgument
+  // CHECK-NOT:      TemplateArgument
 
   template<typename T1> class TestClassTemplate {
     template<typename T2> friend class TestClassTemplate;
@@ -308,7 +333,8 @@
 // CHECK:      NamespaceDecl{{.*}} TestTemplateTypeParmDecl
 // CHECK-NEXT:   FunctionTemplateDecl
 // CHECK-NEXT:     TemplateTypeParmDecl{{.*}} typename ... T
-// CHECK-NEXT:     TemplateTypeParmDecl{{.*}} class U 'int'
+// CHECK-NEXT:     TemplateTypeParmDecl{{.*}} class U
+// CHECK-NEXT:       TemplateArgument type 'int'
 
 namespace TestNonTypeTemplateParmDecl {
   template<int I = 1, int ... J> void foo();
@@ -316,7 +342,8 @@
 // CHECK:      NamespaceDecl{{.*}} TestNonTypeTemplateParmDecl
 // CHECK-NEXT:   FunctionTemplateDecl
 // CHECK-NEXT:     NonTypeTemplateParmDecl{{.*}} 'int' I
-// CHECK-NEXT:       IntegerLiteral{{.*}} 'int' 1
+// CHECK-NEXT:       TemplateArgument expr
+// CHECK-NEXT:         IntegerLiteral{{.*}} 'int' 1
 // CHECK-NEXT:     NonTypeTemplateParmDecl{{.*}} 'int' ... J
 
 namespace TestTemplateTemplateParmDecl {
@@ -443,7 +470,7 @@
   asm("ret");
 }
 // CHECK:      NamespaceDecl{{.*}} TestFileScopeAsmDecl{{$}}
-// CHECK:        FileScopeAsmDecl{{.*>$}}
+// CHECK:        FileScopeAsmDecl{{.*> .*$}}
 // CHECK-NEXT:     StringLiteral
 
 namespace TestFriendDecl2 {
@@ -452,12 +479,12 @@
     friend void f();
   };
 }
-// CHECK: NamespaceDecl [[TestFriendDecl2:0x.*]] <{{.*}}> TestFriendDecl2
-// CHECK: |-FunctionDecl [[TestFriendDecl2_f:0x.*]] <{{.*}}> f 'void (void)'
+// CHECK: NamespaceDecl [[TestFriendDecl2:0x.*]] <{{.*}}> {{.*}} TestFriendDecl2
+// CHECK: |-FunctionDecl [[TestFriendDecl2_f:0x.*]] <{{.*}}> {{.*}} f 'void (void)'
 // CHECK: `-CXXRecordDecl {{.*}} struct S
 // CHECK:   |-CXXRecordDecl {{.*}} struct S
 // CHECK:   `-FriendDecl
-// CHECK:     `-FunctionDecl {{.*}} parent [[TestFriendDecl2]] prev [[TestFriendDecl2_f]] <{{.*}}> f 'void (void)'
+// CHECK:     `-FunctionDecl {{.*}} parent [[TestFriendDecl2]] prev [[TestFriendDecl2_f]] <{{.*}}> {{.*}} f 'void (void)'
 
 namespace Comment {
   extern int Test;
diff --git a/test/Misc/ast-dump-decl.m b/test/Misc/ast-dump-decl.m
index f8a5e5a..539923b 100644
--- a/test/Misc/ast-dump-decl.m
+++ b/test/Misc/ast-dump-decl.m
@@ -134,3 +134,12 @@
 // CHECK-NEXT:   ...
 // CHECK-NEXT:   capture ParmVar{{.*}} 'x' 'int'
 // CHECK-NEXT:   CompoundStmt
+
+@interface B
++ (int) foo;
+@end
+
+void f() {
+  __typeof__(B.foo) Test;
+}
+// CHECK: VarDecl{{.*}}Test 'typeof (B.foo)':'int'
diff --git a/test/Misc/ast-dump-msp430-attr.c b/test/Misc/ast-dump-msp430-attr.c
new file mode 100644
index 0000000..170e0be
--- /dev/null
+++ b/test/Misc/ast-dump-msp430-attr.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -triple msp430-unknown-unknown -ast-dump -ast-dump-filter Test %s | FileCheck --strict-whitespace %s

+

+__attribute__((interrupt(12))) void Test(void);

+// CHECK: FunctionDecl{{.*}}Test

+// CHECK-NEXT: MSP430InterruptAttr

diff --git a/test/Misc/ast-print-pragmas-xfail.cpp b/test/Misc/ast-print-pragmas-xfail.cpp
new file mode 100644
index 0000000..994e1fd
--- /dev/null
+++ b/test/Misc/ast-print-pragmas-xfail.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 %s -ast-print -o - | FileCheck %s
+
+// FIXME: Test fails because attribute order is reversed by ParsedAttributes.
+// XFAIL: *
+
+void run1(int *List, int Length) {
+  int i = 0;
+// CEHCK: #pragma loop vectorize(4)
+// CHECK-NEXT: #pragma loop interleave(8)
+// CHECK-NEXT: #pragma loop vectorize(enable)
+// CHECK-NEXT: #pragma loop interleave(enable)
+#pragma loop vectorize(4)
+#pragma loop interleave(8)
+#pragma loop vectorize(enable)
+#pragma loop interleave(enable)
+// CHECK-NEXT: while (i < Length)
+  while (i < Length) {
+    List[i] = i;
+    i++;
+  }
+}
diff --git a/test/Misc/ast-print-pragmas.cpp b/test/Misc/ast-print-pragmas.cpp
new file mode 100644
index 0000000..25421fc
--- /dev/null
+++ b/test/Misc/ast-print-pragmas.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -ast-print %s -o - | FileCheck %s
+
+// FIXME: A bug in ParsedAttributes causes the order of the attributes to be
+// reversed. The checks are consequently in the reverse order below.
+
+// CHECK: #pragma clang loop interleave_count(8)
+// CHECK-NEXT: #pragma clang loop vectorize_width(4)
+
+void test(int *List, int Length) {
+  int i = 0;
+#pragma clang loop vectorize_width(4)
+#pragma clang loop interleave_count(8)
+// CHECK-NEXT: while (i < Length)
+  while (i < Length) {
+    List[i] = i * 2;
+    i++;
+  }
+
+// CHECK: #pragma clang loop interleave(disable)
+// CHECK-NEXT: #pragma clang loop vectorize(enable)
+
+#pragma clang loop vectorize(enable)
+#pragma clang loop interleave(disable)
+// CHECK-NEXT: while (i - 1 < Length)
+  while (i - 1 < Length) {
+    List[i] = i * 2;
+    i++;
+  }
+
+// CHECK: #pragma clang loop interleave(enable)
+// CHECK-NEXT: #pragma clang loop vectorize(disable)
+
+#pragma clang loop vectorize(disable)
+#pragma clang loop interleave(enable)
+// CHECK-NEXT: while (i - 2 < Length)
+  while (i - 2 < Length) {
+    List[i] = i * 2;
+    i++;
+  }
+}
diff --git a/test/Misc/backend-optimization-failure.cpp b/test/Misc/backend-optimization-failure.cpp
new file mode 100644
index 0000000..1b79fb3
--- /dev/null
+++ b/test/Misc/backend-optimization-failure.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown %s -O3 -emit-llvm -gline-tables-only -S -verify -o /dev/null
+// REQUIRES: x86-registered-target
+
+// Test verifies optimization failures generated by the backend are handled
+// correctly by clang. LLVM tests verify all of the failure conditions.
+
+void test_switch(int *A, int *B, int Length) {
+#pragma clang loop vectorize(enable) unroll(disable)
+  for (int i = 0; i < Length; i++) {
+    /* expected-warning {{loop not vectorized: failed explicitly specified loop vectorization}} */ switch (A[i]) {
+    case 0:
+      B[i] = 1;
+      break;
+    case 1:
+      B[i] = 2;
+      break;
+    default:
+      B[i] = 3;
+    }
+  }
+}
diff --git a/test/Misc/backend-stack-frame-diagnostics-fallback.cpp b/test/Misc/backend-stack-frame-diagnostics-fallback.cpp
new file mode 100644
index 0000000..8ae8c55
--- /dev/null
+++ b/test/Misc/backend-stack-frame-diagnostics-fallback.cpp
@@ -0,0 +1,18 @@
+// REQUIRES: x86-registered-target
+// RUN: %clang_cc1 %s -mllvm -warn-stack-size=0 -emit-codegen-only -triple=i386-apple-darwin 2>&1 | FileCheck %s
+
+// TODO: Emit rich diagnostics for thunks and move this into the appropriate test file.
+// Until then, test that we fall back and display the LLVM backend diagnostic.
+namespace frameSizeThunkWarning {
+  struct A {
+    virtual void f();
+  };
+
+  struct B : virtual A {
+    virtual void f();
+  };
+
+  // CHECK: warning: stack frame size of {{[0-9]+}} bytes in function 'frameSizeThunkWarning::B::f'
+  // CHECK: warning: stack size limit exceeded ({{[0-9]+}}) in {{[^ ]+}}
+  void B::f() { }
+}
diff --git a/test/Misc/backend-stack-frame-diagnostics.cpp b/test/Misc/backend-stack-frame-diagnostics.cpp
new file mode 100644
index 0000000..1d865e7
--- /dev/null
+++ b/test/Misc/backend-stack-frame-diagnostics.cpp
@@ -0,0 +1,85 @@
+// REQUIRES: x86-registered-target
+// RUN: %clang -target i386-apple-darwin -std=c++11 -fblocks -Wframe-larger-than=70 -Xclang -verify -o /dev/null -c %s
+// RUN: %clang -target i386-apple-darwin -std=c++11 -fblocks -Wframe-larger-than=70 -Xclang -verify -o /dev/null -c %s -DIS_SYSHEADER
+
+// Test that:
+//  * The driver passes the option through to the backend.
+//  * The frontend diagnostic handler 'demangles' and resolves the correct function definition.
+
+// Test that link invocations don't emit an "argument unused during compilation" diagnostic.
+// RUN: touch %t.o
+// RUN: %clang -Werror -Wframe-larger-than=0 %t.o -###  2>&1 | not grep ' error: '
+
+// TODO: Support rich backend diagnostics for Objective-C methods.
+
+// Backend diagnostics aren't suppressed in system headers because such results
+// are significant and actionable.
+#ifdef IS_HEADER
+
+#ifdef IS_SYSHEADER
+#pragma clang system_header
+#endif
+
+extern void doIt(char *);
+
+void frameSizeWarning(int, int) {}
+
+void frameSizeWarning();
+
+void frameSizeWarning() { // expected-warning-re {{stack frame size of {{[0-9]+}} bytes in function 'frameSizeWarning'}}
+  char buffer[80];
+  doIt(buffer);
+}
+
+void frameSizeWarning();
+
+void frameSizeWarning(int) {}
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wframe-larger-than="
+void frameSizeWarningIgnored() {
+  char buffer[80];
+  doIt(buffer);
+}
+#pragma GCC diagnostic pop
+
+#pragma GCC diagnostic push
+#ifndef IS_SYSHEADER
+// expected-warning@+2 {{unknown warning group '-Wframe-larger-than'}}
+#endif
+#pragma GCC diagnostic ignored "-Wframe-larger-than"
+#pragma GCC diagnostic pop
+
+void frameSizeLocalClassWarning() {
+  struct S {
+    S() { // expected-warning-re {{stack frame size of {{[0-9]+}} bytes in function 'frameSizeLocalClassWarning()::S::S'}}
+      char buffer[80];
+      doIt(buffer);
+    }
+  };
+  S();
+}
+
+void frameSizeLambdaWarning() {
+  auto fn =
+      []() { // expected-warning-re {{stack frame size of {{[0-9]+}} bytes in lambda expression}}
+    char buffer[80];
+    doIt(buffer);
+  };
+  fn();
+}
+
+void frameSizeBlocksWarning() {
+  auto fn =
+      ^() { // expected-warning-re {{stack frame size of {{[0-9]+}} bytes in block literal}}
+    char buffer[80];
+    doIt(buffer);
+  };
+  fn();
+}
+
+#else
+
+#define IS_HEADER
+#include __FILE__
+#endif
diff --git a/test/Misc/diag-format.c b/test/Misc/diag-format.c
index 3dc351d..8e30cf7 100644
--- a/test/Misc/diag-format.c
+++ b/test/Misc/diag-format.c
@@ -2,8 +2,14 @@
 // RUN: %clang -fsyntax-only -fdiagnostics-format=clang %s 2>&1 | FileCheck %s -check-prefix=DEFAULT
 // RUN: %clang -fsyntax-only -fdiagnostics-format=clang -target x86_64-pc-win32 %s 2>&1 | FileCheck %s -check-prefix=DEFAULT
 //
+// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fmsc-version=1300  %s 2>&1 | FileCheck %s -check-prefix=MSVC2010
+// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fms-compatibility-version=13.00  %s 2>&1 | FileCheck %s -check-prefix=MSVC2010
 // RUN: %clang -fsyntax-only -fdiagnostics-format=msvc  %s 2>&1 | FileCheck %s -check-prefix=MSVC
+// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fmsc-version=1300 -target x86_64-pc-win32 %s 2>&1 | FileCheck %s -check-prefix=MSVC2010
+// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fms-compatibility-version=13.00 -target x86_64-pc-win32 %s 2>&1 | FileCheck %s -check-prefix=MSVC2010
 // RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -target x86_64-pc-win32 %s 2>&1 | FileCheck %s -check-prefix=MSVC
+// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fmsc-version=1300 -target x86_64-pc-win32 -fshow-column %s 2>&1 | FileCheck %s -check-prefix=MSVC2010
+// RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -fms-compatibility-version=13.00 -target x86_64-pc-win32 -fshow-column %s 2>&1 | FileCheck %s -check-prefix=MSVC2010
 // RUN: %clang -fsyntax-only -fdiagnostics-format=msvc -target x86_64-pc-win32 -fshow-column %s 2>&1 | FileCheck %s -check-prefix=MSVC
 //
 // RUN: %clang -fsyntax-only -fdiagnostics-format=vi    %s 2>&1 | FileCheck %s -check-prefix=VI
@@ -12,6 +18,8 @@
 //
 // RUN: %clang -fsyntax-only -fno-show-column %s 2>&1 | FileCheck %s -check-prefix=NO_COLUMN
 //
+// RUN: not %clang -fsyntax-only -Werror -fdiagnostics-format=msvc-fallback -fmsc-version=1300 %s 2>&1 | FileCheck %s -check-prefix=MSVC2010-FALLBACK
+// RUN: not %clang -fsyntax-only -Werror -fdiagnostics-format=msvc-fallback -fms-compatibility-version=13.00 %s 2>&1 | FileCheck %s -check-prefix=MSVC2010-FALLBACK
 // RUN: not %clang -fsyntax-only -Werror -fdiagnostics-format=msvc-fallback %s 2>&1 | FileCheck %s -check-prefix=MSVC-FALLBACK
 
 
@@ -26,10 +34,12 @@
 
 #ifdef foo
 #endif bad // extension!
-// DEFAULT: {{.*}}:28:8: warning: extra tokens at end of #endif directive [-Wextra-tokens]
-// MSVC: {{.*}}(28,7) : warning: extra tokens at end of #endif directive [-Wextra-tokens]
-// VI: {{.*}} +28:8: warning: extra tokens at end of #endif directive [-Wextra-tokens]
-// MSVC_ORIG: {{.*}}(28) : warning: extra tokens at end of #endif directive [-Wextra-tokens]
-// NO_COLUMN: {{.*}}:28: warning: extra tokens at end of #endif directive [-Wextra-tokens]
-// MSVC-FALLBACK: {{.*}}(28,7) : error(clang): extra tokens at end of #endif directive
+// DEFAULT: {{.*}}:36:8: warning: extra tokens at end of #endif directive [-Wextra-tokens]
+// MSVC2010: {{.*}}(36,7) : warning: extra tokens at end of #endif directive [-Wextra-tokens]
+// MSVC: {{.*}}(36,8) : warning: extra tokens at end of #endif directive [-Wextra-tokens]
+// VI: {{.*}} +36:8: warning: extra tokens at end of #endif directive [-Wextra-tokens]
+// MSVC_ORIG: {{.*}}(36) : warning: extra tokens at end of #endif directive [-Wextra-tokens]
+// NO_COLUMN: {{.*}}:36: warning: extra tokens at end of #endif directive [-Wextra-tokens]
+// MSVC2010-FALLBACK: {{.*}}(36,7) : error(clang): extra tokens at end of #endif directive
+// MSVC-FALLBACK: {{.*}}(36,8) : error(clang): extra tokens at end of #endif directive
 int x;
diff --git a/test/Misc/diag-mapping2.c b/test/Misc/diag-mapping2.c
index c4ade07..672d054 100644
--- a/test/Misc/diag-mapping2.c
+++ b/test/Misc/diag-mapping2.c
@@ -1,22 +1,21 @@
 // This should warn by default.
-// RUN: %clang_cc1 %s 2>&1 | grep "warning:"
+// RUN: %clang_cc1 %s 2>&1 | grep "warning: foo"
 
 // This should not emit anything.
 // RUN: %clang_cc1 %s -w 2>&1 | not grep diagnostic
 // RUN: %clang_cc1 %s -Wno-#warnings 2>&1 | not grep diagnostic
 
 // -Werror can map all warnings to error.
-// RUN: not %clang_cc1 %s -Werror 2>&1 | grep "error:"
+// RUN: not %clang_cc1 %s -Werror 2>&1 | grep "error: foo"
 
 // -Werror can map this one warning to error.
-// RUN: not %clang_cc1 %s -Werror=#warnings 2>&1 | grep "error:"
+// RUN: not %clang_cc1 %s -Werror=#warnings 2>&1 | grep "error: foo"
 
 // -Wno-error= overrides -Werror.  rdar://3158301
-// RUN: %clang_cc1 %s -Werror -Wno-error=#warnings 2>&1 | grep "warning:"
+// RUN: %clang_cc1 %s -Werror -Wno-error=#warnings 2>&1 | grep "warning: foo"
 
 // -Wno-error overrides -Werror.  PR4715
-// RUN: %clang_cc1 %s -Werror -Wno-error 2>&1 | grep "warning:"
+// RUN: %clang_cc1 %s -Werror -Wno-error 2>&1 | grep "warning: foo"
 
 #warning foo
 
-
diff --git a/test/Misc/diag-template-diffing.cpp b/test/Misc/diag-template-diffing.cpp
index 4680707..bdd6d62 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<class std::basic_string>' to 'vector<class versa_string>' for 1st argument 
+// CHECK-ELIDE-NOTREE: candidate function not viable: no known conversion from 'vector<std::basic_string>' to 'vector<versa_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<class std::basic_string>' to 'vector<class versa_string>' for 1st argument
+// CHECK-NOELIDE-NOTREE: candidate function not viable: no known conversion from 'vector<std::basic_string>' to 'vector<versa_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:     [class std::basic_string != class versa_string]>
+// CHECK-ELIDE-TREE:     [std::basic_string != versa_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:     [class std::basic_string != class versa_string]>
+// CHECK-NOELIDE-TREE:     [std::basic_string != versa_string]>
 
 template <int... A>
 class I1{};
@@ -1047,7 +1047,7 @@
     using T2 = M<C<N>>;
     T2 p;
     T1 x = p;
-    // CHECK-ELIDE-NOTREE: no viable conversion from 'M<C<struct DependentInt::N, INT<1>>>' to 'M<C<int, INT<0>>>'
+    // CHECK-ELIDE-NOTREE: no viable conversion from 'M<C<DependentInt::N, INT<1>>>' to 'M<C<int, INT<0>>>'
   }
 }
 
@@ -1064,10 +1064,189 @@
 void foo() {
   vector<Atom *> v;
   AtomVector v2(v);
-  // CHECK-ELIDE-NOTREE: no known conversion from 'vector<class PR17510::Atom *, [...]>' to 'const vector<const class PR17510::Atom *, [...]>'
+  // CHECK-ELIDE-NOTREE: no known conversion from 'vector<PR17510::Atom *, [...]>' to 'const vector<const PR17510::Atom *, [...]>'
 }
 }
 
+namespace PR15677 {
+template <bool>
+struct A{};
+
+template <typename T>
+using B = A<T::value>;
+
+template <typename T>
+using B = A<!T::value>;
+// CHECK-ELIDE-NOTREE: type alias template redefinition with different types ('A<!T::value>' vs 'A<T::value>')
+
+template <int>
+struct C{};
+
+template <typename T>
+using D = C<T::value>;
+
+template <typename T>
+using D = C<T::value + 1>;
+// CHECK-ELIDE-NOTREE: type alias template redefinition with different types ('C<T::value + 1>' vs 'C<T::value>')
+
+template <typename T>
+using E = C<T::value>;
+
+template <typename T>
+using E = C<42>;
+// CHECK-ELIDE-NOTREE: type alias template redefinition with different types ('C<42>' vs 'C<T::value>')
+
+template <typename T>
+using F = C<T::value>;
+
+template <typename T>
+using F = C<21 + 21>;
+// CHECK-ELIDE-NOTREE: type alias template redefinition with different types ('C<21 + 21 aka 42>' vs 'C<T::value>')
+}
+}
+
+namespace AddressOf {
+template <int*>
+struct S {};
+
+template <class T>
+struct Wrapper {};
+
+template <class T>
+Wrapper<T> MakeWrapper();
+int global, global2;
+constexpr int * ptr = nullptr;
+Wrapper<S<ptr>> W = MakeWrapper<S<&global>>();
+// Don't print an extra '&' for 'ptr'
+// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<&global>>' to 'Wrapper<S<ptr>>'
+
+// Handle parens correctly
+Wrapper<S<(&global2)>> W2 = MakeWrapper<S<&global>>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<&global>>' to 'Wrapper<S<&global2>>'
+Wrapper<S<&global2>> W3 = MakeWrapper<S<(&global)>>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<&global>>' to 'Wrapper<S<&global2>>'
+Wrapper<S<(&global2)>> W4 = MakeWrapper<S<(&global)>>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<&global>>' to 'Wrapper<S<&global2>>'
+}
+
+namespace NullPtr {
+template <int*, int*>
+struct S {};
+
+template <class T>
+struct Wrapper {};
+
+template <class T>
+Wrapper<T> MakeWrapper();
+int global, global2;
+constexpr int * ptr = nullptr;
+constexpr int * ptr2 = static_cast<int*>(0);
+
+S<&global> s1 = S<&global, ptr>();
+S<&global, nullptr> s2 = S<&global, ptr>();
+
+S<&global, nullptr> s3 = S<&global, &global>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'S<[...], &global>' to 'S<[...], nullptr>'
+S<&global, ptr> s4 = S<&global, &global>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'S<[...], &global>' to 'S<[...], ptr>
+
+Wrapper<S<&global, nullptr>> W1 = MakeWrapper<S<&global, ptr>>();
+Wrapper<S<&global, static_cast<int*>(0)>> W2 = MakeWrapper<S<&global, ptr>>();
+
+Wrapper<S<&global, nullptr>> W3 = MakeWrapper<S<&global, &global>>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<[...], &global>>' to 'Wrapper<S<[...], nullptr>>'
+Wrapper<S<&global, ptr>> W4 = MakeWrapper<S<&global, &global>>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<[...], &global>>' to 'Wrapper<S<[...], ptr>>'
+
+Wrapper<S<&global2, ptr>> W5 = MakeWrapper<S<&global, nullptr>>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<&global, [...]>>' to 'Wrapper<S<&global2, [...]>>'
+Wrapper<S<&global2, nullptr>> W6 = MakeWrapper<S<&global, nullptr>>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<&global, [...]>>' to 'Wrapper<S<&global2, [...]>>'
+Wrapper<S<&global2, ptr2>> W7 = MakeWrapper<S<&global, nullptr>>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<&global, [...]>>' to 'Wrapper<S<&global2, [...]>>'
+Wrapper<S<&global2, nullptr>> W8 = MakeWrapper<S<&global, ptr2>>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<&global, [...]>>' to 'Wrapper<S<&global2, [...]>>'
+Wrapper<S<&global2, ptr>> W9 = MakeWrapper<S<&global, ptr2>>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<&global, [...]>>' to 'Wrapper<S<&global2, [...]>>'
+Wrapper<S<&global2, ptr2>> W10 = MakeWrapper<S<&global, ptr>>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<&global, [...]>>' to 'Wrapper<S<&global2, [...]>>'
+Wrapper<S<&global2, static_cast<int *>(0)>> W11 =
+    MakeWrapper<S<&global, nullptr>>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<&global, [...]>>' to 'Wrapper<S<&global2, [...]>>'
+Wrapper<S<&global2, nullptr>> W12 =
+    MakeWrapper<S<&global, static_cast<int *>(0)>>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<&global, [...]>>' to 'Wrapper<S<&global2, [...]>>'
+
+Wrapper<S<&global, &global>> W13 = MakeWrapper<S<&global, ptr>>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<[...], nullptr>>' to 'Wrapper<S<[...], &global>>'
+Wrapper<S<&global, ptr>> W14 = MakeWrapper<S<&global, &global>>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'Wrapper<S<[...], &global>>' to 'Wrapper<S<[...], ptr>>'
+}
+
+namespace TemplateTemplateDefault {
+template <class> class A{};
+template <class> class B{};
+template <class> class C{};
+template <template <class> class, template <class> class = A>
+        class T {};
+
+T<A> t1 = T<A, C>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'T<[...], template C>' to 'T<[...], (default) template A>'
+T<A, C> t2 = T<A>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'T<[...], (default) template A>' to 'T<[...], template C>'
+T<A> t3 = T<B>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'T<template B>' to 'T<template A>'
+T<B, C> t4 = T<C, B>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'T<template C, template B>' to 'T<template B, template C>'
+T<A, A> t5 = T<B>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'T<template B, [...]>' to 'T<template A, [...]>'
+T<B> t6 = T<A, A>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'T<template A, [...]>' to 'T<template B, [...]>'
+}
+
+namespace Bool {
+template <class> class A{};
+A<bool> a1 = A<int>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'A<int>' to 'A<bool>'
+A<int> a2 = A<bool>();
+// CHECK-ELIDE-NOTREE: no viable conversion from 'A<bool>' to 'A<int>'
+}
+
+namespace TypeAlias {
+template <int, int = 0> class A {};
+
+template <class T> using a = A<T::num, 0>;
+template <class T> using a = A<T::num>;
+
+template <class T> using A1 = A<T::num>;
+template <class T> using A1 = A<T::num + 0>;
+// CHECK-ELIDE-NOTREE: type alias template redefinition with different types ('A<T::num + 0>' vs 'A<T::num>')
+
+template <class T> using A2 = A<1 + T::num>;
+template <class T> using A2 = A<T::num + 1>;
+// CHECK-ELIDE-NOTREE: type alias template redefinition with different types ('A<T::num + 1>' vs 'A<1 + T::num>')
+
+template <class T> using A3 = A<(T::num)>;
+template <class T> using A3 = A<T::num>;
+// CHECK-ELIDE-NOTREE: error: type alias template redefinition with different types ('A<T::num>' vs 'A<(T::num)>')
+
+          template <class T> using A4 = A<(T::num)>;
+template <class T> using A4 = A<((T::num))>;
+// CHECK-ELIDE-NOTREE: type alias template redefinition with different types ('A<((T::num))>' vs 'A<(T::num)>')
+
+template <class T> using A5 = A<T::num, 1>;
+template <class T> using A5 = A<T::num>;
+// CHECK-ELIDE-NOTREE: type alias template redefinition with different types ('A<[...], (default) 0>' vs 'A<[...], 1>')
+
+template <class T> using A6 = A<T::num + 5, 1>;
+template <class T> using A6 = A<T::num + 5>;
+// CHECK-ELIDE-NOTREE: type alias template redefinition with different types ('A<[...], (default) 0>' vs 'A<[...], 1>')
+
+template <class T> using A7 = A<T::num, 1>;
+template <class T> using A7 = A<(T::num)>;
+// CHECK-ELIDE-NOTREE: type alias template redefinition with different types ('A<(T::num), (default) 0>' vs 'A<T::num, 1>')
+}
+
 // CHECK-ELIDE-NOTREE: {{[0-9]*}} errors generated.
 // CHECK-NOELIDE-NOTREE: {{[0-9]*}} errors generated.
 // CHECK-ELIDE-TREE: {{[0-9]*}} errors generated.
diff --git a/test/Misc/driver-verify.c b/test/Misc/driver-verify.c
new file mode 100644
index 0000000..fa31f82
--- /dev/null
+++ b/test/Misc/driver-verify.c
@@ -0,0 +1,6 @@
+// RUN: not %clang -verify %s 2>&1 | FileCheck %s
+// RUN: %clang -cc1 -verify %s
+// expected-no-diagnostics
+
+// Test that -verify is strictly rejected as unknown by the driver.
+// CHECK: unknown argument: '-verify'
diff --git a/test/Misc/error-limit-multiple-notes.cpp b/test/Misc/error-limit-multiple-notes.cpp
index 71a3909..a0c3967 100644
--- a/test/Misc/error-limit-multiple-notes.cpp
+++ b/test/Misc/error-limit-multiple-notes.cpp
@@ -4,20 +4,22 @@
 void foo(int);
 void foo(double);
 void foo(int, int);
+void foo(int, int, int, int);
 
 int main()
 {
-    foo();
+    foo(1, 2, 3);
 }
 
 // error and note suppressed by error-limit
 struct s1{};
 struct s1{};
 
-// CHECK: 10:5: error: no matching function for call to 'foo'
-// CHECK: 6:6: note: candidate function not viable: requires 2 arguments, but 0 were provided
-// CHECK: 5:6: note: candidate function not viable: requires 1 argument, but 0 were provided
-// CHECK: 4:6: note: candidate function not viable: requires 1 argument, but 0 were provided
+// CHECK: 11:5: error: no matching function for call to 'foo'
+// CHECK: 6:6: note: candidate function not viable: requires 2 arguments, but 3 were provided
+// CHECK: 7:6: note: candidate function not viable: requires 4 arguments, but 3 were provided
+// CHECK: 5:6: note: candidate function not viable: requires 1 argument, but 3 were provided
+// CHECK: 4:6: note: candidate function not viable: requires 1 argument, but 3 were provided
 // CHECK: fatal error: too many errors emitted, stopping now
-// CHECK-NOT: 15:8: error: redefinition of 's1'
-// CHECK-NOT: 14:8: note: previous definition is here
+// CHECK-NOT: 16:8: error: redefinition of 's1'
+// CHECK-NOT: 15:8: note: previous definition is here
diff --git a/test/Misc/interpreter.c b/test/Misc/interpreter.c
new file mode 100644
index 0000000..42e1645
--- /dev/null
+++ b/test/Misc/interpreter.c
@@ -0,0 +1,10 @@
+// RUN: clang-interpreter %s | FileCheck %s
+// REQUIRES: native, examples
+
+int printf(const char *, ...);
+
+int main() {
+  // CHECK: {{Hello world!}}
+  printf("Hello world!\n");
+  return 0;
+}
diff --git a/test/Misc/languageOptsOpenCL.cl b/test/Misc/languageOptsOpenCL.cl
index c81db99..82a8f36 100644
--- a/test/Misc/languageOptsOpenCL.cl
+++ b/test/Misc/languageOptsOpenCL.cl
@@ -3,17 +3,19 @@
 
 // Test the forced language options for OpenCL are set correctly.
 
-__constant int v0[(sizeof(int) == 4) -1];
-__constant int v1[(__alignof(int) == 4) -1];
-__constant int v2[(sizeof(long) == 8) -1];
-__constant int v3[(__alignof(long) == 8) -1];
-__constant int v4[(sizeof(long long) == 16) -1];
-__constant int v5[(__alignof(long long) == 16) -1];
-__constant int v6[(sizeof(float) == 4) -1];
-__constant int v7[(__alignof(float) == 4) -1];
+kernel void test() {
+  int v0[(sizeof(int) == 4) - 1];
+  int v1[(__alignof(int)== 4) - 1];
+  int v2[(sizeof(long) == 8) - 1];
+  int v3[(__alignof(long)== 8) - 1];
+  int v4[(sizeof(long long) == 16) - 1];
+  int v5[(__alignof(long long)== 16) - 1];
+  int v6[(sizeof(float) == 4) - 1];
+  int v7[(__alignof(float)== 4) - 1];
 #pragma OPENCL EXTENSION cl_khr_fp64 : enable
-__constant int v8[(sizeof(double)==8) -1];
-__constant int v9[(__alignof(double)==8) -1];
+  int v8[(sizeof(double) == 8) - 1];
+  int v9[(__alignof(double)== 8) - 1];
 #pragma OPENCL EXTENSION cl_khr_fp16 : enable
-__constant int v10[(sizeof(half) == 2) -1];
-__constant int v11[(__alignof(half) == 2) -1];
+  int v10[(sizeof(half) == 2) - 1];
+  int v11[(__alignof(half) == 2) - 1];
+}
diff --git a/test/Misc/serialized-diags-stable.c b/test/Misc/serialized-diags-stable.c
new file mode 100644
index 0000000..4bd4c99
--- /dev/null
+++ b/test/Misc/serialized-diags-stable.c
@@ -0,0 +1,20 @@
+// RUN: rm -f %t
+// RUN: not %clang -Wall -fsyntax-only %s --serialize-diagnostics %t.dia > /dev/null 2>&1
+// RUN: c-index-test -read-diagnostics %t.dia 2>&1 | FileCheck %s
+
+// RUN: c-index-test -read-diagnostics %S/Inputs/serialized-diags-stable.dia 2>&1 | FileCheck %s
+
+int foo() {
+  // CHECK: serialized-diags-stable.c:[[@LINE+2]]:1: warning: control reaches end of non-void function [-Wreturn-type] [Semantic Issue]
+  // CHECK-NEXT: Number FIXITs = 0
+}
+
+// CHECK: serialized-diags-stable.c:[[@LINE+5]]:13: error: redefinition of 'bar' as different kind of symbol [] [Semantic Issue]
+// CHECK-NEXT: Number FIXITs = 0
+// CHECK-NEXT: +-{{.*}}serialized-diags-stable.c:[[@LINE+2]]:6: note: previous definition is here [] []
+// CHECK-NEXT: Number FIXITs = 0
+void bar() {}
+typedef int bar;
+
+
+// CHECK-LABEL: Number of diagnostics: 2
diff --git a/test/Misc/verify.c b/test/Misc/verify.c
index 85b034e..9fe83e1 100644
--- a/test/Misc/verify.c
+++ b/test/Misc/verify.c
@@ -7,8 +7,8 @@
 struct s s2; // expected-error {{tentative definition has type}}
 
 // regex matching
-struct s r1; // expected-error-re {{tentative definition has type 'struct s' that is never completed}}
-struct s r2; // expected-error-re {{tentative definition has type '.*[[:space:]]*.*' that is never completed}}
-struct s r3; // expected-error-re {{tentative definition has type '(.*)[[:space:]]*(.*)' that is never completed}}
-struct s r4; // expected-error-re {{^tentative}}
-struct s r5; // expected-error-re {{completed$}}
+struct s r1; // expected-error    {{tentative definition has type 'struct s' that is never completed}}
+struct s r2; // expected-error-re {{tentative definition has type '{{.*[[:space:]]*.*}}' that is never completed}}
+struct s r3; // expected-error-re {{tentative definition has type '{{(.*)[[:space:]]*(.*)}}' that is never completed}}
+struct s r4; // expected-error-re {{{{^}}tentative}}
+struct s r5; // expected-error-re {{completed{{$}}}}
diff --git a/test/Misc/warn-sysheader.cpp b/test/Misc/warn-sysheader.cpp
new file mode 100644
index 0000000..dbc3825
--- /dev/null
+++ b/test/Misc/warn-sysheader.cpp
@@ -0,0 +1,33 @@
+// Test that -Wsystem-headers works with default and custom mappings like -Werror.
+// Keep run lines at the bottom for line number stability.
+
+#ifdef IS_SYSHEADER
+#pragma clang system_header
+
+int f() { return (int)0; } // Use the old-style-cast warning as an arbitrary "ordinary" diagnostic for the purpose of testing.
+
+#warning "custom message"
+
+#if defined(A) || defined(B)
+// expected-warning@9 {{"custom message"}}
+#elif defined(C)
+// expected-warning@7 {{use of old-style cast}}
+// expected-warning@9 {{"custom message"}}
+#elif defined(D)
+// expected-error@7 {{use of old-style cast}}
+// expected-error@9 {{"custom message"}}
+#elif defined(E)
+// expected-error@7 {{use of old-style cast}}
+// expected-warning@9 {{"custom message"}}
+#endif
+
+#else
+#define IS_SYSHEADER
+#include __FILE__
+#endif
+
+// RUN: %clang_cc1 -verify -fsyntax-only -DA %s
+// RUN: %clang_cc1 -verify -fsyntax-only -DB -Wold-style-cast %s
+// RUN: %clang_cc1 -verify -fsyntax-only -DC -Wold-style-cast -Wsystem-headers %s
+// RUN: %clang_cc1 -verify -fsyntax-only -DD -Wold-style-cast -Wsystem-headers -Werror %s
+// RUN: %clang_cc1 -verify -fsyntax-only -DE -Wold-style-cast -Wsystem-headers -Werror=old-style-cast %s
diff --git a/test/Misc/warning-flags.c b/test/Misc/warning-flags.c
index e61225a..f58d2bf 100644
--- a/test/Misc/warning-flags.c
+++ b/test/Misc/warning-flags.c
@@ -18,23 +18,25 @@
 
 The list of warnings below should NEVER grow.  It should gradually shrink to 0.
 
-CHECK: Warnings without flags (134):
+CHECK: Warnings without flags (103):
 CHECK-NEXT:   ext_delete_void_ptr_operand
+CHECK-NEXT:   ext_excess_initializers
+CHECK-NEXT:   ext_excess_initializers_in_char_array_initializer
 CHECK-NEXT:   ext_expected_semi_decl_list
 CHECK-NEXT:   ext_explicit_specialization_storage_class
 CHECK-NEXT:   ext_implicit_lib_function_decl
+CHECK-NEXT:   ext_initializer_string_for_char_array_too_long
+CHECK-NEXT:   ext_many_braces_around_scalar_init
 CHECK-NEXT:   ext_missing_declspec
 CHECK-NEXT:   ext_missing_whitespace_after_macro_name
 CHECK-NEXT:   ext_new_paren_array_nonconst
 CHECK-NEXT:   ext_plain_complex
-CHECK-NEXT:   ext_pp_macro_redef
 CHECK-NEXT:   ext_template_arg_extra_parens
 CHECK-NEXT:   ext_typecheck_comparison_of_pointer_integer
 CHECK-NEXT:   ext_typecheck_cond_incompatible_operands
 CHECK-NEXT:   ext_typecheck_cond_incompatible_operands_nonstandard
 CHECK-NEXT:   ext_typecheck_ordered_comparison_of_function_pointers
 CHECK-NEXT:   ext_typecheck_ordered_comparison_of_pointer_integer
-CHECK-NEXT:   ext_unknown_escape
 CHECK-NEXT:   ext_using_undefined_std
 CHECK-NEXT:   pp_include_next_absolute_path
 CHECK-NEXT:   pp_include_next_in_primary
@@ -46,9 +48,9 @@
 CHECK-NEXT:   w_asm_qualifier_ignored
 CHECK-NEXT:   warn_accessor_property_type_mismatch
 CHECK-NEXT:   warn_anon_bitfield_width_exceeds_type_size
+CHECK-NEXT:   warn_arcmt_nsalloc_realloc
 CHECK-NEXT:   warn_asm_label_on_auto_decl
 CHECK-NEXT:   warn_bitfield_width_exceeds_type_size
-CHECK-NEXT:   warn_bool_switch_condition
 CHECK-NEXT:   warn_braces_around_scalar_init
 CHECK-NEXT:   warn_c_kext
 CHECK-NEXT:   warn_call_to_pure_virtual_member_function_from_ctor_dtor
@@ -68,12 +70,8 @@
 CHECK-NEXT:   warn_drv_pch_not_first_include
 CHECK-NEXT:   warn_dup_category_def
 CHECK-NEXT:   warn_duplicate_protocol_def
-CHECK-NEXT:   warn_enum_too_large
 CHECK-NEXT:   warn_enum_value_overflow
-CHECK-NEXT:   warn_enumerator_too_large
 CHECK-NEXT:   warn_exception_caught_by_earlier_handler
-CHECK-NEXT:   warn_excess_initializers
-CHECK-NEXT:   warn_excess_initializers_in_char_array_initializer
 CHECK-NEXT:   warn_expected_qualified_after_typename
 CHECK-NEXT:   warn_extraneous_char_constant
 CHECK-NEXT:   warn_fe_cc_log_diagnostics_failure
@@ -83,55 +81,28 @@
 CHECK-NEXT:   warn_ignoring_ftabstop_value
 CHECK-NEXT:   warn_implements_nscopying
 CHECK-NEXT:   warn_incompatible_qualified_id
-CHECK-NEXT:   warn_initializer_string_for_char_array_too_long
 CHECK-NEXT:   warn_inline_namespace_reopened_noninline
-CHECK-NEXT:   warn_integer_too_large_for_signed
 CHECK-NEXT:   warn_invalid_asm_cast_lvalue
-CHECK-NEXT:   warn_many_braces_around_scalar_init
 CHECK-NEXT:   warn_maynot_respond
 CHECK-NEXT:   warn_method_param_redefinition
-CHECK-NEXT:   warn_mismatched_exception_spec
 CHECK-NEXT:   warn_missing_case_for_condition
 CHECK-NEXT:   warn_missing_dependent_template_keyword
 CHECK-NEXT:   warn_missing_exception_specification
 CHECK-NEXT:   warn_missing_whitespace_after_macro_name
+CHECK-NEXT:   warn_mt_message
 CHECK-NEXT:   warn_multiple_method_decl
 CHECK-NEXT:   warn_no_constructor_for_refconst
-CHECK-NEXT:   warn_nonnull_pointers_only
 CHECK-NEXT:   warn_not_compound_assign
 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_param_default_argument_redefinition
 CHECK-NEXT:   warn_partial_specs_not_deducible
 CHECK-NEXT:   warn_pp_convert_lhs_to_positive
 CHECK-NEXT:   warn_pp_convert_rhs_to_positive
 CHECK-NEXT:   warn_pp_expr_overflow
 CHECK-NEXT:   warn_pp_line_decimal
-CHECK-NEXT:   warn_pragma_align_expected_equal
-CHECK-NEXT:   warn_pragma_align_invalid_option
-CHECK-NEXT:   warn_pragma_debug_unexpected_command
-CHECK-NEXT:   warn_pragma_expected_colon
-CHECK-NEXT:   warn_pragma_expected_enable_disable
-CHECK-NEXT:   warn_pragma_expected_identifier
-CHECK-NEXT:   warn_pragma_expected_lparen
-CHECK-NEXT:   warn_pragma_expected_rparen
-CHECK-NEXT:   warn_pragma_extra_tokens_at_eol
-CHECK-NEXT:   warn_pragma_ms_struct
-CHECK-NEXT:   warn_pragma_options_align_reset_failed
-CHECK-NEXT:   warn_pragma_options_expected_align
-CHECK-NEXT:   warn_pragma_pack_invalid_action
-CHECK-NEXT:   warn_pragma_pack_invalid_alignment
-CHECK-NEXT:   warn_pragma_pack_malformed
-CHECK-NEXT:   warn_pragma_pack_pop_failed
 CHECK-NEXT:   warn_pragma_pack_pop_identifer_and_alignment
 CHECK-NEXT:   warn_pragma_pack_show
-CHECK-NEXT:   warn_pragma_pop_macro_no_push
-CHECK-NEXT:   warn_pragma_unknown_extension
-CHECK-NEXT:   warn_pragma_unused_expected_punc
-CHECK-NEXT:   warn_pragma_unused_expected_var
-CHECK-NEXT:   warn_pragma_unused_expected_var_arg
-CHECK-NEXT:   warn_pragma_unused_undeclared_var
 CHECK-NEXT:   warn_property_attr_mismatch
 CHECK-NEXT:   warn_property_attribute
 CHECK-NEXT:   warn_property_getter_owning_mismatch
@@ -141,12 +112,10 @@
 CHECK-NEXT:   warn_register_objc_catch_parm
 CHECK-NEXT:   warn_related_result_type_compatibility_class
 CHECK-NEXT:   warn_related_result_type_compatibility_protocol
-CHECK-NEXT:   warn_static_non_static
 CHECK-NEXT:   warn_template_export_unsupported
 CHECK-NEXT:   warn_template_spec_extra_headers
 CHECK-NEXT:   warn_tentative_incomplete_array
 CHECK-NEXT:   warn_typecheck_function_qualifiers
-CHECK-NEXT:   warn_unavailable_fwdclass_message
 CHECK-NEXT:   warn_undef_interface
 CHECK-NEXT:   warn_undef_interface_suggest
 CHECK-NEXT:   warn_undef_protocolref
diff --git a/test/Misc/win32-macho.c b/test/Misc/win32-macho.c
new file mode 100644
index 0000000..517bde9
--- /dev/null
+++ b/test/Misc/win32-macho.c
@@ -0,0 +1,2 @@
+// Check that basic use of win32-macho targets works.
+// RUN: %clang -fsyntax-only -target x86_64-pc-win32-macho %s
diff --git a/include/clang/Driver/CC1Options.h b/test/Modules/Inputs/ModuleMapLocations/Both/a.h
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Modules/Inputs/ModuleMapLocations/Both/a.h
diff --git a/test/Modules/Inputs/ModuleMapLocations/Both/b.h b/test/Modules/Inputs/ModuleMapLocations/Both/b.h
new file mode 100644
index 0000000..3abbd39
--- /dev/null
+++ b/test/Modules/Inputs/ModuleMapLocations/Both/b.h
@@ -0,0 +1 @@
+void wont_be_found1(void);
diff --git a/test/Modules/Inputs/ModuleMapLocations/Both/module.map b/test/Modules/Inputs/ModuleMapLocations/Both/module.map
new file mode 100644
index 0000000..bf5aaed
--- /dev/null
+++ b/test/Modules/Inputs/ModuleMapLocations/Both/module.map
@@ -0,0 +1,3 @@
+module both {
+  header "b.h"
+}
diff --git a/test/Modules/Inputs/ModuleMapLocations/Both/module.modulemap b/test/Modules/Inputs/ModuleMapLocations/Both/module.modulemap
new file mode 100644
index 0000000..0bfa096
--- /dev/null
+++ b/test/Modules/Inputs/ModuleMapLocations/Both/module.modulemap
@@ -0,0 +1,3 @@
+module both {
+  header "a.h"
+}
diff --git a/test/Modules/Inputs/ModuleMapLocations/Both_F.framework/Headers/a.h b/test/Modules/Inputs/ModuleMapLocations/Both_F.framework/Headers/a.h
new file mode 100644
index 0000000..9dabfc0
--- /dev/null
+++ b/test/Modules/Inputs/ModuleMapLocations/Both_F.framework/Headers/a.h
@@ -0,0 +1 @@
+void will_be_found2(void);
diff --git a/test/Modules/Inputs/ModuleMapLocations/Both_F.framework/Headers/b.h b/test/Modules/Inputs/ModuleMapLocations/Both_F.framework/Headers/b.h
new file mode 100644
index 0000000..26169fa
--- /dev/null
+++ b/test/Modules/Inputs/ModuleMapLocations/Both_F.framework/Headers/b.h
@@ -0,0 +1 @@
+void wont_be_found2(void);
diff --git a/test/Modules/Inputs/ModuleMapLocations/Both_F.framework/Modules/module.modulemap b/test/Modules/Inputs/ModuleMapLocations/Both_F.framework/Modules/module.modulemap
new file mode 100644
index 0000000..da49ba5
--- /dev/null
+++ b/test/Modules/Inputs/ModuleMapLocations/Both_F.framework/Modules/module.modulemap
@@ -0,0 +1,3 @@
+framework module Both_F {
+  header "a.h"
+}
diff --git a/test/Modules/Inputs/ModuleMapLocations/Both_F.framework/module.map b/test/Modules/Inputs/ModuleMapLocations/Both_F.framework/module.map
new file mode 100644
index 0000000..8fc108d
--- /dev/null
+++ b/test/Modules/Inputs/ModuleMapLocations/Both_F.framework/module.map
@@ -0,0 +1,3 @@
+framework module Both_F {
+  header "b.h"
+}
diff --git a/include/clang/Driver/CC1Options.h b/test/Modules/Inputs/ModuleMapLocations/Inferred.framework/Headers/Inferred.h
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Modules/Inputs/ModuleMapLocations/Inferred.framework/Headers/Inferred.h
diff --git a/test/Modules/Inputs/ModuleMapLocations/Module_ModuleMap/a.h b/test/Modules/Inputs/ModuleMapLocations/Module_ModuleMap/a.h
new file mode 100644
index 0000000..d571c6e
--- /dev/null
+++ b/test/Modules/Inputs/ModuleMapLocations/Module_ModuleMap/a.h
@@ -0,0 +1 @@
+void will_be_found1(void);
diff --git a/test/Modules/Inputs/ModuleMapLocations/Module_ModuleMap/module.modulemap b/test/Modules/Inputs/ModuleMapLocations/Module_ModuleMap/module.modulemap
new file mode 100644
index 0000000..2ac7cc5
--- /dev/null
+++ b/test/Modules/Inputs/ModuleMapLocations/Module_ModuleMap/module.modulemap
@@ -0,0 +1,3 @@
+module module_modulemap {
+  header "a.h"
+}
diff --git a/include/clang/Driver/CC1Options.h b/test/Modules/Inputs/ModuleMapLocations/Module_ModuleMap_F.framework/Headers/a.h
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Modules/Inputs/ModuleMapLocations/Module_ModuleMap_F.framework/Headers/a.h
diff --git a/test/Modules/Inputs/ModuleMapLocations/Module_ModuleMap_F.framework/Modules/module.modulemap b/test/Modules/Inputs/ModuleMapLocations/Module_ModuleMap_F.framework/Modules/module.modulemap
new file mode 100644
index 0000000..400f304
--- /dev/null
+++ b/test/Modules/Inputs/ModuleMapLocations/Module_ModuleMap_F.framework/Modules/module.modulemap
@@ -0,0 +1,3 @@
+framework module Module_ModuleMap_F {
+  header "a.h"
+}
diff --git a/test/Modules/Inputs/ModuleMapLocations/Module_ModuleMap_F.framework/Modules/module.private.modulemap b/test/Modules/Inputs/ModuleMapLocations/Module_ModuleMap_F.framework/Modules/module.private.modulemap
new file mode 100644
index 0000000..25a469d
--- /dev/null
+++ b/test/Modules/Inputs/ModuleMapLocations/Module_ModuleMap_F.framework/Modules/module.private.modulemap
@@ -0,0 +1,3 @@
+explicit framework module Module_ModuleMap_F.Private {
+  header "private.h"
+}
diff --git a/include/clang/Driver/CC1Options.h b/test/Modules/Inputs/ModuleMapLocations/Module_ModuleMap_F.framework/PrivateHeaders/private.h
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Modules/Inputs/ModuleMapLocations/Module_ModuleMap_F.framework/PrivateHeaders/private.h
diff --git a/test/Modules/Inputs/ModuleMapLocations/module.modulemap b/test/Modules/Inputs/ModuleMapLocations/module.modulemap
new file mode 100644
index 0000000..a8f5d1f
--- /dev/null
+++ b/test/Modules/Inputs/ModuleMapLocations/module.modulemap
@@ -0,0 +1,2 @@
+framework module * {
+}
diff --git a/test/Modules/Inputs/autolink-sub3.h b/test/Modules/Inputs/autolink-sub3.h
new file mode 100644
index 0000000..132c729
--- /dev/null
+++ b/test/Modules/Inputs/autolink-sub3.h
@@ -0,0 +1 @@
+int autolink_sub3(void);
diff --git a/test/Modules/Inputs/autolink-sub3.pch b/test/Modules/Inputs/autolink-sub3.pch
new file mode 100644
index 0000000..f63b2d5
--- /dev/null
+++ b/test/Modules/Inputs/autolink-sub3.pch
@@ -0,0 +1 @@
+@import autolink.sub3;
diff --git a/test/Modules/Inputs/c-header-bad.h b/test/Modules/Inputs/c-header-bad.h
new file mode 100644
index 0000000..7f7cd87
--- /dev/null
+++ b/test/Modules/Inputs/c-header-bad.h
@@ -0,0 +1,4 @@
+} // expected-error {{extraneous closing brace ('}')}}
+int not_in_extern_c;
+extern "C" { // expected-note {{to match this '{'}}
+// expected-error {{expected '}'}}
diff --git a/test/Modules/Inputs/c-header.h b/test/Modules/Inputs/c-header.h
new file mode 100644
index 0000000..e12f644
--- /dev/null
+++ b/test/Modules/Inputs/c-header.h
@@ -0,0 +1 @@
+int f(void);
diff --git a/test/Modules/Inputs/cxx-decls-imported.h b/test/Modules/Inputs/cxx-decls-imported.h
index b943686..38cc00d 100644
--- a/test/Modules/Inputs/cxx-decls-imported.h
+++ b/test/Modules/Inputs/cxx-decls-imported.h
@@ -3,3 +3,23 @@
   friend void friend_2(HasFriends);
   void private_thing();
 };
+
+struct HasNontrivialDefaultConstructor {
+  HasNontrivialDefaultConstructor() = default;
+  HasNontrivialDefaultConstructor(int n = 0);
+
+  // Ensure this class is not POD but is still trivially-copyable.
+  // This is necessary to exercise the second static_assert below,
+  // because GCC's spec for __has_trivial_constructor is absurd.
+  int m;
+private:
+  int n;
+};
+
+static_assert(!__is_trivial(HasNontrivialDefaultConstructor), "");
+static_assert(!__has_trivial_constructor(HasNontrivialDefaultConstructor), "");
+
+void *operator new[](__SIZE_TYPE__);
+
+extern int mergeUsedFlag;
+inline int getMergeUsedFlag() { return mergeUsedFlag; }
diff --git a/test/Modules/Inputs/cxx-decls-merged.h b/test/Modules/Inputs/cxx-decls-merged.h
new file mode 100644
index 0000000..ccc3b01
--- /dev/null
+++ b/test/Modules/Inputs/cxx-decls-merged.h
@@ -0,0 +1 @@
+extern int mergeUsedFlag;
diff --git a/test/Modules/Inputs/cxx-header.h b/test/Modules/Inputs/cxx-header.h
new file mode 100644
index 0000000..7ed7775
--- /dev/null
+++ b/test/Modules/Inputs/cxx-header.h
@@ -0,0 +1 @@
+int f();
diff --git a/test/Modules/Inputs/cxx-inline-namespace-b.h b/test/Modules/Inputs/cxx-inline-namespace-b.h
new file mode 100644
index 0000000..242a585
--- /dev/null
+++ b/test/Modules/Inputs/cxx-inline-namespace-b.h
@@ -0,0 +1,5 @@
+@import cxx_inline_namespace;
+
+struct X::Y::Z {
+  void f(struct Elaborated);
+};
diff --git a/test/Modules/Inputs/cxx-inline-namespace.h b/test/Modules/Inputs/cxx-inline-namespace.h
index 2525ad3..4feb850 100644
--- a/test/Modules/Inputs/cxx-inline-namespace.h
+++ b/test/Modules/Inputs/cxx-inline-namespace.h
@@ -9,3 +9,9 @@
     typedef int size_t;
   }
 }
+
+namespace X {
+  inline namespace Y {
+    struct Z;
+  }
+}
diff --git a/test/Modules/Inputs/cxx-irgen-left.h b/test/Modules/Inputs/cxx-irgen-left.h
new file mode 100644
index 0000000..ceb5084
--- /dev/null
+++ b/test/Modules/Inputs/cxx-irgen-left.h
@@ -0,0 +1,11 @@
+#include "cxx-irgen-top.h"
+
+S<int> s;
+
+inline int instantiate_min() {
+  return min(1, 2);
+}
+
+inline int instantiate_CtorInit(CtorInit<int> i = CtorInit<int>()) {
+  return i.a;
+}
diff --git a/test/Modules/Inputs/cxx-irgen-right.h b/test/Modules/Inputs/cxx-irgen-right.h
new file mode 100644
index 0000000..4400c76
--- /dev/null
+++ b/test/Modules/Inputs/cxx-irgen-right.h
@@ -0,0 +1,3 @@
+#include "cxx-irgen-top.h"
+
+inline int h() { return S<int>::f(); }
diff --git a/test/Modules/Inputs/cxx-irgen-top.h b/test/Modules/Inputs/cxx-irgen-top.h
new file mode 100644
index 0000000..8753d8d
--- /dev/null
+++ b/test/Modules/Inputs/cxx-irgen-top.h
@@ -0,0 +1,16 @@
+template<typename T> struct S {
+  __attribute__((always_inline)) static int f() { return 0; }
+  __attribute__((always_inline, visibility("hidden"))) static int g() { return 0; }
+};
+
+extern template struct S<int>;
+
+template<typename T> T min(T a, T b) { return a < b ? a : b; }
+
+extern decltype(min(1, 2)) instantiate_min_decl;
+
+template<typename T> struct CtorInit {
+  static int f() { return 0; }
+  int a;
+  CtorInit() : a(f()) {}
+};
diff --git a/test/Modules/Inputs/cxx-templates-a.h b/test/Modules/Inputs/cxx-templates-a.h
index 0b1614d..c95dc63 100644
--- a/test/Modules/Inputs/cxx-templates-a.h
+++ b/test/Modules/Inputs/cxx-templates-a.h
@@ -48,3 +48,28 @@
 template<> struct MergeSpecializations<char> {
   typedef int explicitly_specialized_in_a;
 };
+
+void InstantiateWithFriend(Std::WithFriend<int> wfi) {}
+
+template<typename T> struct WithPartialSpecialization<T*> {
+  typedef int type;
+  T &f() { static T t; return t; }
+};
+typedef WithPartialSpecializationUse::type WithPartialSpecializationInstantiate;
+
+template<> struct WithExplicitSpecialization<int> {
+  int n;
+  template<typename T> T &inner_template() {
+    return n;
+  }
+};
+
+template<typename T> template<typename U>
+constexpr int Outer<T>::Inner<U>::f() { return 1; }
+static_assert(Outer<int>::Inner<int>::f() == 1, "");
+
+template<typename T> struct MergeTemplateDefinitions {
+  static constexpr int f();
+  static constexpr int g();
+};
+template<typename T> constexpr int MergeTemplateDefinitions<T>::f() { return 1; }
diff --git a/test/Modules/Inputs/cxx-templates-b-impl.h b/test/Modules/Inputs/cxx-templates-b-impl.h
index fdf4a4f..93d0574 100644
--- a/test/Modules/Inputs/cxx-templates-b-impl.h
+++ b/test/Modules/Inputs/cxx-templates-b-impl.h
@@ -3,3 +3,10 @@
   struct Inner {};
   friend void FoundByADL(DefinedInBImpl);
 };
+
+@import cxx_templates_common;
+template struct TemplateInstantiationVisibility<char[1]>;
+extern template struct TemplateInstantiationVisibility<char[2]>;
+template<> struct TemplateInstantiationVisibility<char[3]> {};
+extern TemplateInstantiationVisibility<char[4]>::type
+    TemplateInstantiationVisibility_ImplicitInstantiation;
diff --git a/test/Modules/Inputs/cxx-templates-b.h b/test/Modules/Inputs/cxx-templates-b.h
index 6cd83fa..efd07c6 100644
--- a/test/Modules/Inputs/cxx-templates-b.h
+++ b/test/Modules/Inputs/cxx-templates-b.h
@@ -20,6 +20,10 @@
 template<int> struct MergeTemplates;
 MergeTemplates<0> *merge_templates_b;
 
+template<typename T> template<typename U>
+constexpr int Outer<T>::Inner<U>::g() { return 2; }
+static_assert(Outer<int>::Inner<int>::g() == 2, "");
+
 @import cxx_templates_b_impl;
 
 template<typename T, typename> struct Identity { typedef T type; };
@@ -66,4 +70,5 @@
 
 void TriggerInstantiation() {
   UseDefinedInBImpl<void>();
+  Std::f<int>();
 }
diff --git a/test/Modules/Inputs/cxx-templates-c.h b/test/Modules/Inputs/cxx-templates-c.h
index 4c0fc8a..6daffad 100644
--- a/test/Modules/Inputs/cxx-templates-c.h
+++ b/test/Modules/Inputs/cxx-templates-c.h
@@ -5,3 +5,9 @@
 template<> struct MergeSpecializations<bool> {
   typedef int explicitly_specialized_in_c;
 };
+
+template<typename T> struct MergeTemplateDefinitions {
+  static constexpr int f();
+  static constexpr int g();
+};
+template<typename T> constexpr int MergeTemplateDefinitions<T>::g() { return 2; }
diff --git a/test/Modules/Inputs/cxx-templates-common.h b/test/Modules/Inputs/cxx-templates-common.h
index 40a11e2..682ef93 100644
--- a/test/Modules/Inputs/cxx-templates-common.h
+++ b/test/Modules/Inputs/cxx-templates-common.h
@@ -9,3 +9,30 @@
 template<typename T> struct CommonTemplate {
   enum E { a = 1, b = 2, c = 3 };
 };
+
+namespace Std {
+  template<typename T> struct WithFriend {
+    friend bool operator!=(const WithFriend &A, const WithFriend &B) { return false; }
+  };
+}
+
+namespace Std {
+  template<typename T> void f() {
+    extern T g();
+  }
+}
+
+template<typename T> struct TemplateInstantiationVisibility { typedef int type; };
+
+template<typename T> struct Outer {
+  template<typename U> struct Inner {
+    static constexpr int f();
+    static constexpr int g();
+  };
+};
+
+template<typename T> struct WithPartialSpecialization {};
+typedef WithPartialSpecialization<int*> WithPartialSpecializationUse;
+
+template<typename T> struct WithExplicitSpecialization;
+typedef WithExplicitSpecialization<int> WithExplicitSpecializationUse;
diff --git a/test/Modules/Inputs/declare-use/e.h b/test/Modules/Inputs/declare-use/e.h
index ed8d843..31247f7 100644
--- a/test/Modules/Inputs/declare-use/e.h
+++ b/test/Modules/Inputs/declare-use/e.h
@@ -1,6 +1,7 @@
 #ifndef E_H
 #define E_H
-#include "a.h"
+#define HEADER "a.h"
+#include HEADER
 #include "b.h"
 const int e = a*b;
 #endif
diff --git a/test/Modules/Inputs/declare-use/h.h b/test/Modules/Inputs/declare-use/h.h
index df99a6d..379e501 100644
--- a/test/Modules/Inputs/declare-use/h.h
+++ b/test/Modules/Inputs/declare-use/h.h
@@ -1,7 +1,7 @@
 #ifndef H_H
 #define H_H
 #include "c.h"
-#include "d.h" // expected-error {{use of a module not declared used}}
+#include "d.h" // expected-error {{does not depend on a module exporting}}
 #include "h1.h"
 const int h1 = aux_h*c*7*d;
 #endif
diff --git a/test/Modules/Inputs/declare-use/i.h b/test/Modules/Inputs/declare-use/i.h
new file mode 100644
index 0000000..30e7ded
--- /dev/null
+++ b/test/Modules/Inputs/declare-use/i.h
@@ -0,0 +1 @@
+int aux_i = 13;
diff --git a/test/Modules/Inputs/declare-use/j.h b/test/Modules/Inputs/declare-use/j.h
new file mode 100644
index 0000000..04d46a9
--- /dev/null
+++ b/test/Modules/Inputs/declare-use/j.h
@@ -0,0 +1,14 @@
+#ifndef J_H
+#define J_H
+
+#define STR(x) #x
+#define HDR(x) STR(x.h)
+
+#include ALLOWED_INC
+#include HDR(a)
+
+const int j = a * a + b;
+
+// expected-no-diagnostics
+
+#endif
diff --git a/test/Modules/Inputs/declare-use/module.map b/test/Modules/Inputs/declare-use/module.map
index 774fc37..a176fb3 100644
--- a/test/Modules/Inputs/declare-use/module.map
+++ b/test/Modules/Inputs/declare-use/module.map
@@ -9,21 +9,25 @@
 module XC {
   header "c.h"
   use XA
+  // Intentionally doesn't use XB to show that -fdecl-use isn't transitive.
 }
 
 module XD {
   header "d.h"
   use XA
+  // Intentionally doesn't use XB to show that -fdecl-use isn't transitive.
 }
 
 module XE {
   header "e.h"
+  header "unavailable.h"
   use XA
   use XB
 }
 
 module XF {
   header "f.h"
+  header "unavailable.h"
   use XA
   use XB
 }
@@ -33,11 +37,20 @@
   header "g1.h"
   use XC
   use XE
+  use XJ
 }
 
 module XH {
   header "h.h"
   header "h1.h"
+  header "s.h"
   use XC
   use XE
 }
+
+module XJ {
+  header "j.h"
+}
+
+module XS {
+}
diff --git a/include/clang/Driver/CC1Options.h b/test/Modules/Inputs/declare-use/s.h
similarity index 100%
rename from include/clang/Driver/CC1Options.h
rename to test/Modules/Inputs/declare-use/s.h
diff --git a/test/Modules/Inputs/elsewhere/c-header-indirect.h b/test/Modules/Inputs/elsewhere/c-header-indirect.h
new file mode 100644
index 0000000..083c41f
--- /dev/null
+++ b/test/Modules/Inputs/elsewhere/c-header-indirect.h
@@ -0,0 +1 @@
+#include "c-header.h"
diff --git a/test/Modules/Inputs/elsewhere/module.map b/test/Modules/Inputs/elsewhere/module.map
new file mode 100644
index 0000000..2c56820
--- /dev/null
+++ b/test/Modules/Inputs/elsewhere/module.map
@@ -0,0 +1 @@
+module c_library_indirect { header "c-header-indirect.h" }
diff --git a/test/Modules/Inputs/exclude-header/module.map b/test/Modules/Inputs/exclude-header/module.map
new file mode 100644
index 0000000..2563ef9
--- /dev/null
+++ b/test/Modules/Inputs/exclude-header/module.map
@@ -0,0 +1,3 @@
+module x { umbrella "x" exclude header "x/bad.h" module * {} }
+module y { umbrella "y" module * {} }
+module bad { header "x/bad.h" }
diff --git a/test/Modules/Inputs/exclude-header/x/a.h b/test/Modules/Inputs/exclude-header/x/a.h
new file mode 100644
index 0000000..389d285
--- /dev/null
+++ b/test/Modules/Inputs/exclude-header/x/a.h
@@ -0,0 +1 @@
+typedef int a;
diff --git a/test/Modules/Inputs/exclude-header/x/bad.h b/test/Modules/Inputs/exclude-header/x/bad.h
new file mode 100644
index 0000000..179ef26
--- /dev/null
+++ b/test/Modules/Inputs/exclude-header/x/bad.h
@@ -0,0 +1 @@
+#error bad
diff --git a/test/Modules/Inputs/exclude-header/y/b.h b/test/Modules/Inputs/exclude-header/y/b.h
new file mode 100644
index 0000000..a16836a
--- /dev/null
+++ b/test/Modules/Inputs/exclude-header/y/b.h
@@ -0,0 +1 @@
+typedef int b;
diff --git a/test/Modules/Inputs/include-relative/a.h b/test/Modules/Inputs/include-relative/a.h
new file mode 100644
index 0000000..b95284b
--- /dev/null
+++ b/test/Modules/Inputs/include-relative/a.h
@@ -0,0 +1 @@
+extern int n;
diff --git a/test/Modules/Inputs/include-relative/module.map b/test/Modules/Inputs/include-relative/module.map
new file mode 100644
index 0000000..bb00c84
--- /dev/null
+++ b/test/Modules/Inputs/include-relative/module.map
@@ -0,0 +1 @@
+module a { header "a.h" }
diff --git a/test/Modules/Inputs/macro-hiding/a1.h b/test/Modules/Inputs/macro-hiding/a1.h
new file mode 100644
index 0000000..b17c8ee
--- /dev/null
+++ b/test/Modules/Inputs/macro-hiding/a1.h
@@ -0,0 +1 @@
+#define assert(x)
diff --git a/include/clang/Driver/CC1Options.h b/test/Modules/Inputs/macro-hiding/a2.h
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Modules/Inputs/macro-hiding/a2.h
diff --git a/include/clang/Driver/CC1Options.h b/test/Modules/Inputs/macro-hiding/b1.h
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Modules/Inputs/macro-hiding/b1.h
diff --git a/test/Modules/Inputs/macro-hiding/b2.h b/test/Modules/Inputs/macro-hiding/b2.h
new file mode 100644
index 0000000..8391848
--- /dev/null
+++ b/test/Modules/Inputs/macro-hiding/b2.h
@@ -0,0 +1,2 @@
+#include "a2.h"
+#define assert(x)
diff --git a/test/Modules/Inputs/macro-hiding/c1.h b/test/Modules/Inputs/macro-hiding/c1.h
new file mode 100644
index 0000000..4b78b3c
--- /dev/null
+++ b/test/Modules/Inputs/macro-hiding/c1.h
@@ -0,0 +1,2 @@
+#include "b1.h"
+#define assert(x)
diff --git a/test/Modules/Inputs/macro-hiding/d1.h b/test/Modules/Inputs/macro-hiding/d1.h
new file mode 100644
index 0000000..8391848
--- /dev/null
+++ b/test/Modules/Inputs/macro-hiding/d1.h
@@ -0,0 +1,2 @@
+#include "a2.h"
+#define assert(x)
diff --git a/test/Modules/Inputs/macro-hiding/e1.h b/test/Modules/Inputs/macro-hiding/e1.h
new file mode 100644
index 0000000..bd01708
--- /dev/null
+++ b/test/Modules/Inputs/macro-hiding/e1.h
@@ -0,0 +1 @@
+#include "a1.h"
diff --git a/test/Modules/Inputs/macro-hiding/e2.h b/test/Modules/Inputs/macro-hiding/e2.h
new file mode 100644
index 0000000..f3a49c7
--- /dev/null
+++ b/test/Modules/Inputs/macro-hiding/e2.h
@@ -0,0 +1,2 @@
+#include "a1.h"
+inline void e1() { assert(true); }
diff --git a/test/Modules/Inputs/macro-hiding/module.modulemap b/test/Modules/Inputs/macro-hiding/module.modulemap
new file mode 100644
index 0000000..20632d3
--- /dev/null
+++ b/test/Modules/Inputs/macro-hiding/module.modulemap
@@ -0,0 +1,18 @@
+module a {
+  module a1 { header "a1.h" export * }
+  module a2 { header "a2.h" export * }
+}
+module b {
+  module b1 { header "b1.h" export * }
+  module b2 { header "b2.h" export * }
+}
+module c {
+  module c1 { header "c1.h" export * }
+}
+module d {
+  module d1 { header "d1.h" export * }
+}
+module e {
+  module e1 { header "e1.h" export * }
+  module e2 { header "e2.h" export * }
+}
diff --git a/test/Modules/Inputs/macro-undef-through-pch/A.h b/test/Modules/Inputs/macro-undef-through-pch/A.h
new file mode 100644
index 0000000..6a2cc5c
--- /dev/null
+++ b/test/Modules/Inputs/macro-undef-through-pch/A.h
@@ -0,0 +1,2 @@
+#define AB
+#undef AB
diff --git a/test/Modules/Inputs/macro-undef-through-pch/foo.h b/test/Modules/Inputs/macro-undef-through-pch/foo.h
new file mode 100644
index 0000000..9d0256b
--- /dev/null
+++ b/test/Modules/Inputs/macro-undef-through-pch/foo.h
@@ -0,0 +1 @@
+@import A;
diff --git a/test/Modules/Inputs/macro-undef-through-pch/module.map b/test/Modules/Inputs/macro-undef-through-pch/module.map
new file mode 100644
index 0000000..63f68ca
--- /dev/null
+++ b/test/Modules/Inputs/macro-undef-through-pch/module.map
@@ -0,0 +1,3 @@
+module A {
+  header "A.h"
+}
diff --git a/test/Modules/Inputs/macros_other.h b/test/Modules/Inputs/macros_other.h
index ea686bf..4923a7f 100644
--- a/test/Modules/Inputs/macros_other.h
+++ b/test/Modules/Inputs/macros_other.h
@@ -1 +1,6 @@
-#define OTHER_INTEGER int
+#undef TOP_OTHER_UNDEF1
+#define TOP_OTHER_UNDEF2 42
+#define TOP_OTHER_REDEF1 1
+#define TOP_OTHER_REDEF1 3
+
+#define TOP_OTHER_DEF_RIGHT_UNDEF 4
diff --git a/test/Modules/Inputs/macros_right.h b/test/Modules/Inputs/macros_right.h
index dbbd2c3..a70c350 100644
--- a/test/Modules/Inputs/macros_right.h
+++ b/test/Modules/Inputs/macros_right.h
@@ -17,3 +17,5 @@
 #define TOP_RIGHT_REDEF float
 
 #define FN_ADD(x, y) (x+y)
+
+#undef TOP_OTHER_DEF_RIGHT_UNDEF
diff --git a/test/Modules/Inputs/macros_right_undef.h b/test/Modules/Inputs/macros_right_undef.h
index 49473e3..15a8366 100644
--- a/test/Modules/Inputs/macros_right_undef.h
+++ b/test/Modules/Inputs/macros_right_undef.h
@@ -1 +1,4 @@
 #undef TOP_RIGHT_UNDEF
+
+@import macros_top;
+#undef TOP_OTHER_DEF_RIGHT_UNDEF
diff --git a/test/Modules/Inputs/macros_top.h b/test/Modules/Inputs/macros_top.h
index dd303ff..1093504 100644
--- a/test/Modules/Inputs/macros_top.h
+++ b/test/Modules/Inputs/macros_top.h
@@ -14,3 +14,11 @@
 
 #define TOP_RIGHT_UNDEF int
 
+#define TOP_OTHER_UNDEF1 42
+#undef TOP_OTHER_UNDEF2
+#define TOP_OTHER_REDEF1 1
+#define TOP_OTHER_REDEF2 2
+
+#define TOP_OTHER_DEF_RIGHT_UNDEF void
+
+#define TOP_REDEF_IN_SUBMODULES 0
diff --git a/test/Modules/Inputs/macros_top_b.h b/test/Modules/Inputs/macros_top_b.h
new file mode 100644
index 0000000..cfee17c
--- /dev/null
+++ b/test/Modules/Inputs/macros_top_b.h
@@ -0,0 +1,5 @@
+#include "macros_top.h"
+#undef TOP_REDEF_IN_SUBMODULES
+#define TOP_REDEF_IN_SUBMODULES 1
+#undef TOP_REDEF_IN_SUBMODULES
+#define TOP_REDEF_IN_SUBMODULES 2
diff --git a/test/Modules/Inputs/macros_top_c.h b/test/Modules/Inputs/macros_top_c.h
new file mode 100644
index 0000000..aee8246
--- /dev/null
+++ b/test/Modules/Inputs/macros_top_c.h
@@ -0,0 +1,2 @@
+#include "macros_top_b.h"
+#undef TOP_REDEF_IN_SUBMODULES
diff --git a/test/Modules/Inputs/malformed/a1.h b/test/Modules/Inputs/malformed/a1.h
new file mode 100644
index 0000000..400b916
--- /dev/null
+++ b/test/Modules/Inputs/malformed/a1.h
@@ -0,0 +1 @@
+void f() {
diff --git a/test/Modules/Inputs/malformed/a2.h b/test/Modules/Inputs/malformed/a2.h
new file mode 100644
index 0000000..5c34318
--- /dev/null
+++ b/test/Modules/Inputs/malformed/a2.h
@@ -0,0 +1 @@
+}
diff --git a/test/Modules/Inputs/malformed/b1.h b/test/Modules/Inputs/malformed/b1.h
new file mode 100644
index 0000000..3d98bc1
--- /dev/null
+++ b/test/Modules/Inputs/malformed/b1.h
@@ -0,0 +1,3 @@
+struct S {
+  #include "b2.h"
+};
diff --git a/test/Modules/Inputs/malformed/b2.h b/test/Modules/Inputs/malformed/b2.h
new file mode 100644
index 0000000..7fc5340
--- /dev/null
+++ b/test/Modules/Inputs/malformed/b2.h
@@ -0,0 +1 @@
+void g() {}
diff --git a/test/Modules/Inputs/malformed/module.map b/test/Modules/Inputs/malformed/module.map
new file mode 100644
index 0000000..5277ffa
--- /dev/null
+++ b/test/Modules/Inputs/malformed/module.map
@@ -0,0 +1,8 @@
+module malformed_a {
+  module a1 { header "a1.h" }
+  module a2 { header "a2.h" }
+}
+module malformed_b {
+  module b1 { header "b1.h" }
+  module b2 { header "b2.h" }
+}
diff --git a/test/Modules/Inputs/module.map b/test/Modules/Inputs/module.map
index cf8a298..fea1201 100644
--- a/test/Modules/Inputs/module.map
+++ b/test/Modules/Inputs/module.map
@@ -1,3 +1,6 @@
+module c_library [extern_c] { module inner { header "c-header.h" } }
+module cxx_library { header "cxx-header.h" requires cplusplus }
+module c_library_bad [extern_c] { header "c-header-bad.h" }
 module diamond_top { header "diamond_top.h" }
 module diamond_left { 
   header "diamond_left.h" 
@@ -12,6 +15,9 @@
   export *
 }
 module irgen { header "irgen.h" }
+module cxx_irgen_top { header "cxx-irgen-top.h" }
+module cxx_irgen_left { header "cxx-irgen-left.h" }
+module cxx_irgen_right { header "cxx-irgen-right.h" }
 module lookup_left_objc { header "lookup_left.h" }
 module lookup_right_objc { header "lookup_right.h" }
 module lookup_left_cxx { header "lookup_left.hpp" }
@@ -20,6 +26,8 @@
 module module_private_right { header "module_private_right.h" }
 module macros_top { 
   header "macros_top.h" 
+  explicit module b { header "macros_top_b.h" }
+  explicit module c { header "macros_top_c.h" }
 }
 module macros_left { 
   header "macros_left.h" 
@@ -33,6 +41,7 @@
   }
 }
 module macros { header "macros.h" }
+module macros_other { header "macros_other.h" }
 module category_top { header "category_top.h" }
 module category_left { 
   header "category_left.h" 
@@ -60,6 +69,9 @@
 module redeclarations_right { header "redeclarations_right.h" }
 module redecl_namespaces_left { header "redecl_namespaces_left.h" }
 module redecl_namespaces_right { header "redecl_namespaces_right.h" }
+module redecl_add_after_load_top { header "redecl-add-after-load-top.h" }
+module redecl_add_after_load_decls { header "redecl-add-after-load-decls.h" }
+module redecl_add_after_load { header "redecl-add-after-load.h" }
 module load_failure { header "load_failure.h" }
 
 module decldef {
@@ -166,6 +178,11 @@
     header "autolink-sub2.h"
     link framework "autolink_framework"
   }
+
+  explicit module sub3 {
+    header "autolink-sub3.h"
+    link "autolink_from_pch"
+  }
 }
 
 module weird_objc {
@@ -184,6 +201,10 @@
   header "cxx-inline-namespace.h"
 }
 
+module cxx_inline_namespace_b {
+  header "cxx-inline-namespace-b.h"
+}
+
 module cxx_linkage_cache {
   header "cxx-linkage-cache.h"
 }
@@ -217,6 +238,10 @@
   }
 }
 
+module cxx_decls_merged {
+  header "cxx-decls-merged.h"
+}
+
 module config {
   header "config.h"
   config_macros [exhaustive] WANT_FOO, WANT_BAR
@@ -281,3 +306,9 @@
 module recursive_visibility_c {
   header "recursive_visibility_c.h"
 }
+module recursive1 {
+  header "recursive1.h"
+}
+module recursive2 {
+  header "recursive2.h"
+}
diff --git a/test/Modules/Inputs/modules-with-same-name/DependsOnA/DependsOnA.h b/test/Modules/Inputs/modules-with-same-name/DependsOnA/DependsOnA.h
new file mode 100644
index 0000000..9d0256b
--- /dev/null
+++ b/test/Modules/Inputs/modules-with-same-name/DependsOnA/DependsOnA.h
@@ -0,0 +1 @@
+@import A;
diff --git a/test/Modules/Inputs/modules-with-same-name/DependsOnA/module.modulemap b/test/Modules/Inputs/modules-with-same-name/DependsOnA/module.modulemap
new file mode 100644
index 0000000..b2a027b
--- /dev/null
+++ b/test/Modules/Inputs/modules-with-same-name/DependsOnA/module.modulemap
@@ -0,0 +1,4 @@
+module DependsOnA {
+  header "DependsOnA.h"
+  export *
+}
diff --git a/test/Modules/Inputs/modules-with-same-name/path1/A/a.h b/test/Modules/Inputs/modules-with-same-name/path1/A/a.h
new file mode 100644
index 0000000..0086e2a
--- /dev/null
+++ b/test/Modules/Inputs/modules-with-same-name/path1/A/a.h
@@ -0,0 +1 @@
+#define FROM_PATH 1
diff --git a/test/Modules/Inputs/modules-with-same-name/path1/A/module.modulemap b/test/Modules/Inputs/modules-with-same-name/path1/A/module.modulemap
new file mode 100644
index 0000000..76c3358
--- /dev/null
+++ b/test/Modules/Inputs/modules-with-same-name/path1/A/module.modulemap
@@ -0,0 +1,5 @@
+// path1. This comment keeps this file from being identical to
+// path2/A/module.modulemap.
+module A {
+  header "a.h"
+}
diff --git a/test/Modules/Inputs/modules-with-same-name/path2/A/a.h b/test/Modules/Inputs/modules-with-same-name/path2/A/a.h
new file mode 100644
index 0000000..184c190
--- /dev/null
+++ b/test/Modules/Inputs/modules-with-same-name/path2/A/a.h
@@ -0,0 +1 @@
+#define FROM_PATH 2
diff --git a/test/Modules/Inputs/modules-with-same-name/path2/A/module.modulemap b/test/Modules/Inputs/modules-with-same-name/path2/A/module.modulemap
new file mode 100644
index 0000000..2ff3943
--- /dev/null
+++ b/test/Modules/Inputs/modules-with-same-name/path2/A/module.modulemap
@@ -0,0 +1,5 @@
+// path2. This comment keeps this file from being identical to
+// path1/A/module.modulemap.
+module A {
+  header "a.h"
+}
diff --git a/test/Modules/Inputs/namespaces-left.h b/test/Modules/Inputs/namespaces-left.h
index bd192af..787fe75 100644
--- a/test/Modules/Inputs/namespaces-left.h
+++ b/test/Modules/Inputs/namespaces-left.h
@@ -1,5 +1,18 @@
+namespace RedeclAcrossImport {
+  enum E { e };
+}
+
+namespace AddAndReexportBeforeImport {
+  struct S {};
+  extern struct S t;
+}
+
 @import namespaces_top;
 
+namespace RedeclAcrossImport {
+  E x = e;
+}
+
 float &global(float);
 float &global2(float);
 
diff --git a/test/Modules/Inputs/namespaces-top.h b/test/Modules/Inputs/namespaces-top.h
index 7aa8490..7bf5394 100644
--- a/test/Modules/Inputs/namespaces-top.h
+++ b/test/Modules/Inputs/namespaces-top.h
@@ -17,3 +17,7 @@
   int f(int);
   void (*p)() = &f;
 }
+
+namespace AddAndReexportBeforeImport {
+  int S;
+}
diff --git a/test/Modules/Inputs/recursive1.h b/test/Modules/Inputs/recursive1.h
new file mode 100644
index 0000000..8cb5917
--- /dev/null
+++ b/test/Modules/Inputs/recursive1.h
@@ -0,0 +1 @@
+#include "recursive2.h"
diff --git a/test/Modules/Inputs/recursive2.h b/test/Modules/Inputs/recursive2.h
new file mode 100644
index 0000000..d9480aa
--- /dev/null
+++ b/test/Modules/Inputs/recursive2.h
@@ -0,0 +1 @@
+#include "recursive1.h"
diff --git a/test/Modules/Inputs/redecl-add-after-load-decls.h b/test/Modules/Inputs/redecl-add-after-load-decls.h
new file mode 100644
index 0000000..fbe6b93
--- /dev/null
+++ b/test/Modules/Inputs/redecl-add-after-load-decls.h
@@ -0,0 +1,24 @@
+typedef struct A B;
+extern const int variable;
+extern constexpr int function();
+constexpr int test(bool b) { return b ? variable : function(); }
+
+namespace N {
+  typedef struct A B;
+  extern const int variable;
+  extern constexpr int function();
+}
+typedef N::B NB;
+constexpr int N_test(bool b) { return b ? N::variable : N::function(); }
+
+@import redecl_add_after_load_top;
+typedef C::A CB;
+constexpr int C_test(bool b) { return b ? C::variable : C::function(); }
+
+struct D {
+  struct A; // expected-note {{forward}}
+  static const int variable;
+  static constexpr int function(); // expected-note {{here}}
+};
+typedef D::A DB;
+constexpr int D_test(bool b) { return b ? D::variable : D::function(); } // expected-note {{subexpression}} expected-note {{undefined}}
diff --git a/test/Modules/Inputs/redecl-add-after-load-top.h b/test/Modules/Inputs/redecl-add-after-load-top.h
new file mode 100644
index 0000000..638fb01
--- /dev/null
+++ b/test/Modules/Inputs/redecl-add-after-load-top.h
@@ -0,0 +1,5 @@
+struct C {
+  struct A;
+  static const int variable;
+  static constexpr int function();
+};
diff --git a/test/Modules/Inputs/redecl-add-after-load.h b/test/Modules/Inputs/redecl-add-after-load.h
new file mode 100644
index 0000000..6951a76
--- /dev/null
+++ b/test/Modules/Inputs/redecl-add-after-load.h
@@ -0,0 +1,23 @@
+struct A {};
+extern const int variable = 0;
+extern constexpr int function() { return 0; }
+
+namespace N {
+  struct A {};
+  extern const int variable = 0;
+  extern constexpr int function() { return 0; }
+}
+
+@import redecl_add_after_load_top;
+struct C::A {};
+const int C::variable = 0;
+constexpr int C::function() { return 0; }
+
+struct D {
+  struct A;
+  static const int variable;
+  static constexpr int function();
+};
+struct D::A {};
+const int D::variable = 0;
+constexpr int D::function() { return 0; }
diff --git a/test/Modules/Inputs/require-modular-includes/A.framework/Headers/A.h b/test/Modules/Inputs/require-modular-includes/A.framework/Headers/A.h
new file mode 100644
index 0000000..fad91bd
--- /dev/null
+++ b/test/Modules/Inputs/require-modular-includes/A.framework/Headers/A.h
@@ -0,0 +1 @@
+#include "B/B.h"
diff --git a/test/Modules/Inputs/require-modular-includes/AnotherModule.h b/test/Modules/Inputs/require-modular-includes/AnotherModule.h
new file mode 100644
index 0000000..96913aa
--- /dev/null
+++ b/test/Modules/Inputs/require-modular-includes/AnotherModule.h
@@ -0,0 +1 @@
+// AnotherModule.h
diff --git a/test/Modules/Inputs/require-modular-includes/AnotherModuleExcluded.h b/test/Modules/Inputs/require-modular-includes/AnotherModuleExcluded.h
new file mode 100644
index 0000000..b539dd9
--- /dev/null
+++ b/test/Modules/Inputs/require-modular-includes/AnotherModuleExcluded.h
@@ -0,0 +1 @@
+// AnotherModuleExcluded.h
diff --git a/test/Modules/Inputs/require-modular-includes/B.framework/Headers/B.h b/test/Modules/Inputs/require-modular-includes/B.framework/Headers/B.h
new file mode 100644
index 0000000..77d6ff1
--- /dev/null
+++ b/test/Modules/Inputs/require-modular-includes/B.framework/Headers/B.h
@@ -0,0 +1 @@
+#include "C.h"
diff --git a/test/Modules/Inputs/require-modular-includes/C.h b/test/Modules/Inputs/require-modular-includes/C.h
new file mode 100644
index 0000000..a0121d4
--- /dev/null
+++ b/test/Modules/Inputs/require-modular-includes/C.h
@@ -0,0 +1 @@
+// C.h
diff --git a/test/Modules/Inputs/require-modular-includes/ExcludedFromAnotherModule.framework/Headers/ExcludedFromAnotherModule.h b/test/Modules/Inputs/require-modular-includes/ExcludedFromAnotherModule.framework/Headers/ExcludedFromAnotherModule.h
new file mode 100644
index 0000000..0c0ce7b
--- /dev/null
+++ b/test/Modules/Inputs/require-modular-includes/ExcludedFromAnotherModule.framework/Headers/ExcludedFromAnotherModule.h
@@ -0,0 +1 @@
+#include "AnotherModuleExcluded.h"
diff --git a/test/Modules/Inputs/require-modular-includes/FromAnotherModule.framework/Headers/FromAnotherModule.h b/test/Modules/Inputs/require-modular-includes/FromAnotherModule.framework/Headers/FromAnotherModule.h
new file mode 100644
index 0000000..1fe5c08
--- /dev/null
+++ b/test/Modules/Inputs/require-modular-includes/FromAnotherModule.framework/Headers/FromAnotherModule.h
@@ -0,0 +1 @@
+#include "AnotherModule.h"
diff --git a/test/Modules/Inputs/require-modular-includes/FromImportedModuleFail.framework/Headers/FromImportedModuleFail.h b/test/Modules/Inputs/require-modular-includes/FromImportedModuleFail.framework/Headers/FromImportedModuleFail.h
new file mode 100644
index 0000000..a80bcc6
--- /dev/null
+++ b/test/Modules/Inputs/require-modular-includes/FromImportedModuleFail.framework/Headers/FromImportedModuleFail.h
@@ -0,0 +1,2 @@
+// FromImportedModuleFail.h
+#include "NotInModule.h"
diff --git a/test/Modules/Inputs/require-modular-includes/FromImportedModuleOK.framework/Headers/FromImportedModuleOK.h b/test/Modules/Inputs/require-modular-includes/FromImportedModuleOK.framework/Headers/FromImportedModuleOK.h
new file mode 100644
index 0000000..3b2056c
--- /dev/null
+++ b/test/Modules/Inputs/require-modular-includes/FromImportedModuleOK.framework/Headers/FromImportedModuleOK.h
@@ -0,0 +1 @@
+#include "FromImportedModuleOK2.h"
diff --git a/test/Modules/Inputs/require-modular-includes/FromImportedModuleOK.framework/Headers/FromImportedModuleOK2.h b/test/Modules/Inputs/require-modular-includes/FromImportedModuleOK.framework/Headers/FromImportedModuleOK2.h
new file mode 100644
index 0000000..775fd6e
--- /dev/null
+++ b/test/Modules/Inputs/require-modular-includes/FromImportedModuleOK.framework/Headers/FromImportedModuleOK2.h
@@ -0,0 +1 @@
+// FromImportedModuleOK2.h
diff --git a/test/Modules/Inputs/require-modular-includes/FromImportedModuleOK.framework/Modules/module.modulemap b/test/Modules/Inputs/require-modular-includes/FromImportedModuleOK.framework/Modules/module.modulemap
new file mode 100644
index 0000000..2638111
--- /dev/null
+++ b/test/Modules/Inputs/require-modular-includes/FromImportedModuleOK.framework/Modules/module.modulemap
@@ -0,0 +1,4 @@
+framework module FromImportedModuleOK {
+  header "FromImportedModuleOK.h"
+  header "FromImportedModuleOK2.h"
+}
diff --git a/test/Modules/Inputs/require-modular-includes/FromImportedSubModule.framework/Headers/Header.h b/test/Modules/Inputs/require-modular-includes/FromImportedSubModule.framework/Headers/Header.h
new file mode 100644
index 0000000..613cd9d
--- /dev/null
+++ b/test/Modules/Inputs/require-modular-includes/FromImportedSubModule.framework/Headers/Header.h
@@ -0,0 +1,2 @@
+// Header.h
+#include "NotInModule.h"
diff --git a/test/Modules/Inputs/require-modular-includes/FromImportedSubModule.framework/Modules/module.modulemap b/test/Modules/Inputs/require-modular-includes/FromImportedSubModule.framework/Modules/module.modulemap
new file mode 100644
index 0000000..c07efec
--- /dev/null
+++ b/test/Modules/Inputs/require-modular-includes/FromImportedSubModule.framework/Modules/module.modulemap
@@ -0,0 +1,5 @@
+framework module FromImportedSubModule {
+  module Sub {
+    header "Header.h"
+  }
+}
diff --git a/include/clang/Driver/CC1Options.h b/test/Modules/Inputs/require-modular-includes/FromNonModularSubframework.framework/Frameworks/Subframework.framework/Headers/Subframework.h
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Modules/Inputs/require-modular-includes/FromNonModularSubframework.framework/Frameworks/Subframework.framework/Headers/Subframework.h
diff --git a/test/Modules/Inputs/require-modular-includes/FromNonModularSubframework.framework/Headers/FromNonModularSubframework.h b/test/Modules/Inputs/require-modular-includes/FromNonModularSubframework.framework/Headers/FromNonModularSubframework.h
new file mode 100644
index 0000000..4680be4
--- /dev/null
+++ b/test/Modules/Inputs/require-modular-includes/FromNonModularSubframework.framework/Headers/FromNonModularSubframework.h
@@ -0,0 +1 @@
+#include "Subframework/Subframework.h"
diff --git a/test/Modules/Inputs/require-modular-includes/FromNonModularSubframework.framework/Modules/module.modulemap b/test/Modules/Inputs/require-modular-includes/FromNonModularSubframework.framework/Modules/module.modulemap
new file mode 100644
index 0000000..c308ea4
--- /dev/null
+++ b/test/Modules/Inputs/require-modular-includes/FromNonModularSubframework.framework/Modules/module.modulemap
@@ -0,0 +1,3 @@
+framework module FromNonModularSubframework {
+  header "FromNonModularSubframework.h"
+}
diff --git a/test/Modules/Inputs/require-modular-includes/FromSubframework.framework/Frameworks/Subframework.framework/Headers/Subframework.h b/test/Modules/Inputs/require-modular-includes/FromSubframework.framework/Frameworks/Subframework.framework/Headers/Subframework.h
new file mode 100644
index 0000000..c08fac0
--- /dev/null
+++ b/test/Modules/Inputs/require-modular-includes/FromSubframework.framework/Frameworks/Subframework.framework/Headers/Subframework.h
@@ -0,0 +1 @@
+// Subframework.h
diff --git a/test/Modules/Inputs/require-modular-includes/FromSubframework.framework/Headers/FromSubframework.h b/test/Modules/Inputs/require-modular-includes/FromSubframework.framework/Headers/FromSubframework.h
new file mode 100644
index 0000000..4680be4
--- /dev/null
+++ b/test/Modules/Inputs/require-modular-includes/FromSubframework.framework/Headers/FromSubframework.h
@@ -0,0 +1 @@
+#include "Subframework/Subframework.h"
diff --git a/test/Modules/Inputs/require-modular-includes/FromSubframework.framework/Modules/module.modulemap b/test/Modules/Inputs/require-modular-includes/FromSubframework.framework/Modules/module.modulemap
new file mode 100644
index 0000000..250f05a
--- /dev/null
+++ b/test/Modules/Inputs/require-modular-includes/FromSubframework.framework/Modules/module.modulemap
@@ -0,0 +1,7 @@
+framework module FromSubframework {
+  umbrella header "FromSubframework.h"
+
+  framework module Subframework {
+    umbrella header "Subframework.h"
+  }
+}
diff --git a/test/Modules/Inputs/require-modular-includes/FromUmbrella.framework/Headers/FromUmbrella.h b/test/Modules/Inputs/require-modular-includes/FromUmbrella.framework/Headers/FromUmbrella.h
new file mode 100644
index 0000000..f6f891f
--- /dev/null
+++ b/test/Modules/Inputs/require-modular-includes/FromUmbrella.framework/Headers/FromUmbrella.h
@@ -0,0 +1,2 @@
+#include "umbrella/foo.h"
+#include "umbrella/bar/bar.h"
diff --git a/test/Modules/Inputs/require-modular-includes/IncludeExcluded.framework/Headers/Excluded.h b/test/Modules/Inputs/require-modular-includes/IncludeExcluded.framework/Headers/Excluded.h
new file mode 100644
index 0000000..f330e6c
--- /dev/null
+++ b/test/Modules/Inputs/require-modular-includes/IncludeExcluded.framework/Headers/Excluded.h
@@ -0,0 +1 @@
+// Excluded.h
diff --git a/test/Modules/Inputs/require-modular-includes/IncludeExcluded.framework/Headers/IncludeExcluded.h b/test/Modules/Inputs/require-modular-includes/IncludeExcluded.framework/Headers/IncludeExcluded.h
new file mode 100644
index 0000000..f2ffdc3
--- /dev/null
+++ b/test/Modules/Inputs/require-modular-includes/IncludeExcluded.framework/Headers/IncludeExcluded.h
@@ -0,0 +1 @@
+#include "Excluded.h"
diff --git a/test/Modules/Inputs/require-modular-includes/IncludeExcluded.framework/Modules/module.modulemap b/test/Modules/Inputs/require-modular-includes/IncludeExcluded.framework/Modules/module.modulemap
new file mode 100644
index 0000000..a175353
--- /dev/null
+++ b/test/Modules/Inputs/require-modular-includes/IncludeExcluded.framework/Modules/module.modulemap
@@ -0,0 +1,4 @@
+framework module IncludeExcluded {
+  header "IncludeExcluded.h"
+  exclude header "Excluded.h"
+}
diff --git a/test/Modules/Inputs/require-modular-includes/NotFramework.h b/test/Modules/Inputs/require-modular-includes/NotFramework.h
new file mode 100644
index 0000000..3afd8fc
--- /dev/null
+++ b/test/Modules/Inputs/require-modular-includes/NotFramework.h
@@ -0,0 +1,2 @@
+// NotFramework.h
+#import "NotInModule.h"
diff --git a/test/Modules/Inputs/require-modular-includes/NotInModule.h b/test/Modules/Inputs/require-modular-includes/NotInModule.h
new file mode 100644
index 0000000..c2a626c
--- /dev/null
+++ b/test/Modules/Inputs/require-modular-includes/NotInModule.h
@@ -0,0 +1 @@
+// NotInModule.h
diff --git a/test/Modules/Inputs/require-modular-includes/module.modulemap b/test/Modules/Inputs/require-modular-includes/module.modulemap
new file mode 100644
index 0000000..0ac4d5b
--- /dev/null
+++ b/test/Modules/Inputs/require-modular-includes/module.modulemap
@@ -0,0 +1,12 @@
+module AnotherModule {
+  header "AnotherModule.h"
+  exclude header "AnotherModuleExcluded.h"
+}
+module Umbrella {
+  umbrella "umbrella"
+}
+module NotFramework {
+  header "NotFramework.h"
+}
+
+framework module * { }
diff --git a/test/Modules/Inputs/require-modular-includes/umbrella/bar/bar.h b/test/Modules/Inputs/require-modular-includes/umbrella/bar/bar.h
new file mode 100644
index 0000000..410aba2
--- /dev/null
+++ b/test/Modules/Inputs/require-modular-includes/umbrella/bar/bar.h
@@ -0,0 +1 @@
+// bar.h
diff --git a/test/Modules/Inputs/require-modular-includes/umbrella/foo.h b/test/Modules/Inputs/require-modular-includes/umbrella/foo.h
new file mode 100644
index 0000000..2496648
--- /dev/null
+++ b/test/Modules/Inputs/require-modular-includes/umbrella/foo.h
@@ -0,0 +1 @@
+// foo.h
diff --git a/test/Modules/Inputs/string_names/a.h b/test/Modules/Inputs/string_names/a.h
new file mode 100644
index 0000000..a36dc1b
--- /dev/null
+++ b/test/Modules/Inputs/string_names/a.h
@@ -0,0 +1,4 @@
+#ifndef A_H
+#define A_H
+const int a = 2;
+#endif
diff --git a/test/Modules/Inputs/string_names/b.h b/test/Modules/Inputs/string_names/b.h
new file mode 100644
index 0000000..55daf72
--- /dev/null
+++ b/test/Modules/Inputs/string_names/b.h
@@ -0,0 +1,4 @@
+#ifndef B_H
+#define B_H
+const int b = 3;
+#endif
diff --git a/test/Modules/Inputs/string_names/c.h b/test/Modules/Inputs/string_names/c.h
new file mode 100644
index 0000000..38c278f
--- /dev/null
+++ b/test/Modules/Inputs/string_names/c.h
@@ -0,0 +1,4 @@
+#ifndef C_H
+#define C_H
+const int c = 2;
+#endif
diff --git a/test/Modules/Inputs/string_names/module.map b/test/Modules/Inputs/string_names/module.map
new file mode 100644
index 0000000..4e70eda
--- /dev/null
+++ b/test/Modules/Inputs/string_names/module.map
@@ -0,0 +1,16 @@
+module "my/module-a" {
+  header "a.h"
+  use "my/module-c"
+
+  module "Sub" {
+    header "sub.h"
+  }
+}
+
+module "my/module-b" {
+  header "b.h"
+}
+
+module "my/module-c" {
+  header "c.h"
+}
diff --git a/test/Modules/Inputs/string_names/sub.h b/test/Modules/Inputs/string_names/sub.h
new file mode 100644
index 0000000..64b9112
--- /dev/null
+++ b/test/Modules/Inputs/string_names/sub.h
@@ -0,0 +1,4 @@
+#ifndef SUB_H
+#define SUB_H
+const int sub = 2;
+#endif
diff --git a/test/Modules/Inputs/submodules/import-self-b.h b/test/Modules/Inputs/submodules/import-self-b.h
index f88b56d..9852094 100644
--- a/test/Modules/Inputs/submodules/import-self-b.h
+++ b/test/Modules/Inputs/submodules/import-self-b.h
@@ -1,10 +1,12 @@
+// FIXME: This import has no effect, because the submodule isn't built yet, and
+// we don't map an @import to a #include in this case.
 @import import_self.c;
 #include "import-self-d.h"
 
 // FIXME: This should not work; names from 'a' should not be visible here.
 MyTypeA import_self_test_a;
 
-// FIXME: This should work but does not; names from 'b' are not actually visible here.
+// FIXME: This should work but does not; names from 'c' are not actually visible here.
 //MyTypeC import_self_test_c;
 
 MyTypeD import_self_test_d;
diff --git a/test/Modules/Inputs/submodules/module.map b/test/Modules/Inputs/submodules/module.map
index c91e94f..1c1b76a 100644
--- a/test/Modules/Inputs/submodules/module.map
+++ b/test/Modules/Inputs/submodules/module.map
@@ -10,3 +10,23 @@
   module c { header "import-self-c.h" }
   module d { header "import-self-d.h" }
 }
+
+module missing_headers {
+  module missing { header "missing.h" }
+  module not_missing { header "not_missing.h" }
+}
+
+module missing_unavailable_headers {
+  module missing {
+    requires !objc
+    header "missing.h"
+    module also_missing { header "also_missing.h" }
+  }
+  module not_missing { }
+}
+
+module missing_umbrella_with_inferred_submodules {
+  umbrella header "missing_umbrella.h"
+  module * { export * }
+  export *
+}
diff --git a/test/Modules/Inputs/submodules/not_missing.h b/test/Modules/Inputs/submodules/not_missing.h
new file mode 100644
index 0000000..1f8d048
--- /dev/null
+++ b/test/Modules/Inputs/submodules/not_missing.h
@@ -0,0 +1,2 @@
+void NotMissingFunction() {
+}
diff --git a/test/Modules/Inputs/template-specialization-visibility/a.h b/test/Modules/Inputs/template-specialization-visibility/a.h
new file mode 100644
index 0000000..e8820555
--- /dev/null
+++ b/test/Modules/Inputs/template-specialization-visibility/a.h
@@ -0,0 +1,8 @@
+#ifndef A_H
+#define A_H
+template<typename T> struct S;
+template<typename U> struct T {
+  struct S;
+  enum E : int;
+};
+#endif
diff --git a/test/Modules/Inputs/template-specialization-visibility/b.h b/test/Modules/Inputs/template-specialization-visibility/b.h
new file mode 100644
index 0000000..1a09826
--- /dev/null
+++ b/test/Modules/Inputs/template-specialization-visibility/b.h
@@ -0,0 +1,7 @@
+#ifndef B_H
+#define B_H
+#include "a.h"
+S<int> *s1;
+T<int>::S *s2;
+T<int>::E e1;
+#endif
diff --git a/test/Modules/Inputs/template-specialization-visibility/c.h b/test/Modules/Inputs/template-specialization-visibility/c.h
new file mode 100644
index 0000000..a92fb3b
--- /dev/null
+++ b/test/Modules/Inputs/template-specialization-visibility/c.h
@@ -0,0 +1,6 @@
+#ifndef C_H
+#define C_H
+template<typename T> struct S { int n; };
+template<typename U> struct T<U>::S { int n; };
+template<typename U> enum T<U>::E : int { e };
+#endif
diff --git a/test/Modules/Inputs/template-specialization-visibility/d.h b/test/Modules/Inputs/template-specialization-visibility/d.h
new file mode 100644
index 0000000..3048272
--- /dev/null
+++ b/test/Modules/Inputs/template-specialization-visibility/d.h
@@ -0,0 +1,5 @@
+#ifndef D_H
+#define D_H
+template<typename> struct S;
+template<typename> struct T;
+#endif
diff --git a/test/Modules/Inputs/template-specialization-visibility/e.h b/test/Modules/Inputs/template-specialization-visibility/e.h
new file mode 100644
index 0000000..5d6b142
--- /dev/null
+++ b/test/Modules/Inputs/template-specialization-visibility/e.h
@@ -0,0 +1,6 @@
+#ifndef E_H
+#define E_H
+#include "c.h"
+template struct S<char>;
+template struct T<char>;
+#endif
diff --git a/test/Modules/Inputs/template-specialization-visibility/module.map b/test/Modules/Inputs/template-specialization-visibility/module.map
new file mode 100644
index 0000000..f0e2a0e
--- /dev/null
+++ b/test/Modules/Inputs/template-specialization-visibility/module.map
@@ -0,0 +1,7 @@
+module tsv {
+  module a { header "a.h" }
+  module b { header "b.h" }
+  module c { header "c.h" }
+  module d { header "d.h" }
+  module e { header "e.h" }
+}
diff --git a/test/Modules/Inputs/templates-left.h b/test/Modules/Inputs/templates-left.h
index e76598d..2bd79be 100644
--- a/test/Modules/Inputs/templates-left.h
+++ b/test/Modules/Inputs/templates-left.h
@@ -33,3 +33,30 @@
 void redeclDefinitionEmit(){}
 
 typedef Outer<int>::Inner OuterIntInner_left;
+
+int defineListDoubleLeft() {
+  List<double> ld;
+  ld.push_back(0.0);
+  return ld.size;
+}
+
+template<typename T> struct MergePatternDecl;
+
+extern template struct ExplicitInstantiation<false, false>;
+extern template struct ExplicitInstantiation<false, true>;
+extern template struct ExplicitInstantiation<true, false>;
+extern template struct ExplicitInstantiation<true, true>;
+
+void useExplicitInstantiation() {
+  ExplicitInstantiation<true, false>().f();
+  ExplicitInstantiation<true, true>().f();
+}
+
+template<typename> struct DelayUpdates;
+template<> struct DelayUpdates<int>;
+template<typename T> struct DelayUpdates<T*>;
+template<typename T> void testDelayUpdates(DelayUpdates<T> *p = 0) {}
+
+void outOfLineInlineUseLeftF(void (OutOfLineInline<int>::*)() = &OutOfLineInline<int>::f);
+void outOfLineInlineUseLeftG(void (OutOfLineInline<int>::*)() = &OutOfLineInline<int>::g);
+void outOfLineInlineUseLeftH(void (OutOfLineInline<int>::*)() = &OutOfLineInline<int>::h);
diff --git a/test/Modules/Inputs/templates-right.h b/test/Modules/Inputs/templates-right.h
index 16d0a71..5907cbc 100644
--- a/test/Modules/Inputs/templates-right.h
+++ b/test/Modules/Inputs/templates-right.h
@@ -31,3 +31,15 @@
 void redeclDefinitionEmit(){}
 
 typedef Outer<int>::Inner OuterIntInner_right;
+
+int defineListDoubleRight() {
+  List<double> ld;
+  ld.push_back(0.0);
+  return ld.size;
+}
+
+template<typename T> struct MergePatternDecl;
+
+void outOfLineInlineUseRightF(void (OutOfLineInline<int>::*)() = &OutOfLineInline<int>::f);
+void outOfLineInlineUseRightG(void (OutOfLineInline<int>::*)() = &OutOfLineInline<int>::g);
+void outOfLineInlineUseRightH(void (OutOfLineInline<int>::*)() = &OutOfLineInline<int>::h);
diff --git a/test/Modules/Inputs/templates-top.h b/test/Modules/Inputs/templates-top.h
index 87dcd8b..1216266 100644
--- a/test/Modules/Inputs/templates-top.h
+++ b/test/Modules/Inputs/templates-top.h
@@ -9,6 +9,8 @@
   unsigned size;
 };
 
+extern List<double> *instantiateListDoubleDeclaration;
+
 namespace A {
   class Y {
     template <typename T> friend class WhereAmI;
@@ -23,3 +25,18 @@
 template<typename T> struct Outer {
   struct Inner {};
 };
+
+template<bool, bool> struct ExplicitInstantiation {
+  void f() {}
+};
+
+template<typename> struct DelayUpdates {};
+
+template<typename T> struct OutOfLineInline {
+  void f();
+  void g();
+  void h();
+};
+template<typename T> inline void OutOfLineInline<T>::f() {}
+template<typename T> inline void OutOfLineInline<T>::g() {}
+template<typename T> inline void OutOfLineInline<T>::h() {}
diff --git a/test/Modules/Inputs/undefined-type-fixit/module.map b/test/Modules/Inputs/undefined-type-fixit/module.map
new file mode 100644
index 0000000..f5ce34b
--- /dev/null
+++ b/test/Modules/Inputs/undefined-type-fixit/module.map
@@ -0,0 +1,9 @@
+module public1 {
+  header "public1.h"
+}
+module public2 {
+  header "public2.h"
+  module public2sub {
+    header "public2sub.h"
+  }
+}
diff --git a/test/Modules/Inputs/undefined-type-fixit/public1.h b/test/Modules/Inputs/undefined-type-fixit/public1.h
new file mode 100644
index 0000000..bc98ca9
--- /dev/null
+++ b/test/Modules/Inputs/undefined-type-fixit/public1.h
@@ -0,0 +1,6 @@
+#ifndef PUBLIC1_H
+#define PUBLIC1_H
+
+struct use_this1 { int field; };
+
+#endif
diff --git a/test/Modules/Inputs/undefined-type-fixit/public2.h b/test/Modules/Inputs/undefined-type-fixit/public2.h
new file mode 100644
index 0000000..2aa3e96
--- /dev/null
+++ b/test/Modules/Inputs/undefined-type-fixit/public2.h
@@ -0,0 +1,6 @@
+#ifndef PUBLIC2_H
+#define PUBLIC2_H
+
+struct use_this2 { int field; };
+
+#endif
diff --git a/test/Modules/Inputs/undefined-type-fixit/public2sub.h b/test/Modules/Inputs/undefined-type-fixit/public2sub.h
new file mode 100644
index 0000000..4c8c3cc
--- /dev/null
+++ b/test/Modules/Inputs/undefined-type-fixit/public2sub.h
@@ -0,0 +1,6 @@
+#ifndef PUBLIC2SUB_H
+#define PUBLIC2SUB_H
+
+struct use_this2sub { int field; };
+
+#endif
diff --git a/test/Modules/Inputs/unnecessary-module-map-parsing/a1.h b/test/Modules/Inputs/unnecessary-module-map-parsing/a1.h
new file mode 100644
index 0000000..56757a7
--- /dev/null
+++ b/test/Modules/Inputs/unnecessary-module-map-parsing/a1.h
@@ -0,0 +1 @@
+void f() {}
diff --git a/test/Modules/Inputs/unnecessary-module-map-parsing/module.map b/test/Modules/Inputs/unnecessary-module-map-parsing/module.map
new file mode 100644
index 0000000..6d4ceee
--- /dev/null
+++ b/test/Modules/Inputs/unnecessary-module-map-parsing/module.map
@@ -0,0 +1,3 @@
+module a {
+  eader "unknown.h"
+}
diff --git a/test/Modules/Inputs/update-after-load/a.h b/test/Modules/Inputs/update-after-load/a.h
new file mode 100644
index 0000000..0ebcf3e
--- /dev/null
+++ b/test/Modules/Inputs/update-after-load/a.h
@@ -0,0 +1 @@
+namespace llvm {}
diff --git a/test/Modules/Inputs/update-after-load/b.h b/test/Modules/Inputs/update-after-load/b.h
new file mode 100644
index 0000000..64e9bfd
--- /dev/null
+++ b/test/Modules/Inputs/update-after-load/b.h
@@ -0,0 +1,2 @@
+#include "a.h"
+namespace llvm { void f(); }
diff --git a/test/Modules/Inputs/update-after-load/module.map b/test/Modules/Inputs/update-after-load/module.map
new file mode 100644
index 0000000..21e160e
--- /dev/null
+++ b/test/Modules/Inputs/update-after-load/module.map
@@ -0,0 +1 @@
+module a { header "a.h" } module b { header "b.h" }
diff --git a/include/clang/Driver/CC1Options.h b/test/Modules/Inputs/update-after-load/modules.timestamp
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Modules/Inputs/update-after-load/modules.timestamp
diff --git a/test/Modules/Rmodule-build.m b/test/Modules/Rmodule-build.m
new file mode 100644
index 0000000..b8abc01
--- /dev/null
+++ b/test/Modules/Rmodule-build.m
@@ -0,0 +1,34 @@
+// REQUIRES: shell
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: echo '// A' > %t/A.h
+// RUN: echo '// B' > %t/B.h
+// RUN: echo 'module A { header "A.h" }' > %t/module.modulemap
+// RUN: echo 'module B { header "B.h" }' >> %t/module.modulemap
+
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fsyntax-only %s -verify \
+// RUN:            -I %t -Rmodule-build
+
+@import A; // expected-remark{{building module 'A' as}}
+@import B; // expected-remark{{building module 'B' as}}
+@import A; // no diagnostic
+@import B; // no diagnostic
+
+// RUN: echo ' ' >> %t/B.h
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fsyntax-only %s -I %t \
+// RUN:            -Rmodule-build 2>&1 | FileCheck %s
+
+// RUN: echo ' ' >> %t/B.h
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fsyntax-only %s -I %t \
+// RUN:            -Reverything 2>&1 | FileCheck %s
+
+// RUN: echo ' ' >> %t/B.h
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fsyntax-only %s -I %t \
+// RUN:            2>&1 | count 0
+
+// RUN: echo ' ' >> %t/B.h
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fsyntax-only %s -I %t \
+// RUN:            -Rmodule-build -Rno-everything 2>&1 | count 0
+
+// CHECK-NOT: building module 'A'
+// CHECK: building module 'B'
diff --git a/test/Modules/Werror-Wsystem-headers.m b/test/Modules/Werror-Wsystem-headers.m
new file mode 100644
index 0000000..c4cd1a6
--- /dev/null
+++ b/test/Modules/Werror-Wsystem-headers.m
@@ -0,0 +1,23 @@
+// REQUIRES: shell
+// RUN: rm -rf %t
+// RUN: rm -rf %t-saved
+// RUN: mkdir %t-saved
+
+// Initial module build
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fdisable-module-hash \
+// RUN:     -isysroot %S/Inputs/System -triple x86_64-apple-darwin10 -fsyntax-only %s -verify
+// RUN: cp %t/cstd.pcm %t-saved/cstd.pcm
+
+// Even with -Werror don't rebuild a system module
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fdisable-module-hash \
+// RUN:     -isysroot %S/Inputs/System -triple x86_64-apple-darwin10 -fsyntax-only %s -verify -Werror
+// RUN: diff %t/cstd.pcm %t-saved/cstd.pcm
+
+// Unless -Wsystem-headers is on
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fdisable-module-hash \
+// RUN:     -isysroot %S/Inputs/System -triple x86_64-apple-darwin10 -fsyntax-only %s -verify \
+// RUN:     -Werror=unused -Wsystem-headers
+// RUN: not diff %t/cstd.pcm %t-saved/cstd.pcm
+
+// expected-no-diagnostics
+@import cstd;
diff --git a/test/Modules/Werror.m b/test/Modules/Werror.m
new file mode 100644
index 0000000..94a98a5
--- /dev/null
+++ b/test/Modules/Werror.m
@@ -0,0 +1,75 @@
+// REQUIRES: shell
+// RUN: rm -rf %t
+// RUN: rm -rf %t-saved
+// RUN: mkdir -p %t-saved
+
+// Initial module build (-Werror=header-guard)
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fdisable-module-hash \
+// RUN:     -F %S/Inputs -fsyntax-only %s -verify -Wno-incomplete-umbrella  \
+// RUN:     -Werror=header-guard
+// RUN: cp %t/Module.pcm %t-saved/Module.pcm
+
+// Building with looser -Werror options does not rebuild
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fdisable-module-hash \
+// RUN:     -F %S/Inputs -fsyntax-only %s -verify -Wno-incomplete-umbrella 
+// RUN: diff %t/Module.pcm %t-saved/Module.pcm
+
+// Make the build more restricted (-Werror)
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fdisable-module-hash \
+// RUN:     -F %S/Inputs -fsyntax-only %s -verify -Wno-incomplete-umbrella \
+// RUN:     -Werror -Wno-incomplete-umbrella
+// RUN: not diff %t/Module.pcm %t-saved/Module.pcm
+// RUN: cp %t/Module.pcm %t-saved/Module.pcm
+
+// Ensure -Werror=header-guard is less strict than -Werror
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fdisable-module-hash \
+// RUN:     -F %S/Inputs -fsyntax-only %s -verify -Wno-incomplete-umbrella \
+// RUN:     -Werror=header-guard -Wno-incomplete-umbrella
+// RUN: diff %t/Module.pcm %t-saved/Module.pcm
+
+// But -Werror=unused is not, because some of its diags are DefaultIgnore
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fdisable-module-hash \
+// RUN:     -F %S/Inputs -fsyntax-only %s -verify -Wno-incomplete-umbrella \
+// RUN:     -Werror=unused
+// RUN: not diff %t/Module.pcm %t-saved/Module.pcm
+// RUN: cp %t/Module.pcm %t-saved/Module.pcm
+
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fdisable-module-hash \
+// RUN:     -F %S/Inputs -fsyntax-only %s -verify -Wno-incomplete-umbrella \
+// RUN:     -Werror -Wno-incomplete-umbrella
+
+// FIXME: when rebuilding the module, take the union of the diagnostic options
+// so that we don't need to rebuild here
+// RUN-DISABLED: diff %t/Module.pcm %t-saved/Module.pcm
+
+// -Wno-everything, -Werror
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fdisable-module-hash \
+// RUN:     -F %S/Inputs -fsyntax-only %s -verify -Wno-incomplete-umbrella \
+// RUN:     -Wno-everything -Wall -Werror
+// RUN: cp %t/Module.pcm %t-saved/Module.pcm
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fdisable-module-hash \
+// RUN:     -F %S/Inputs -fsyntax-only %s -verify -Wno-incomplete-umbrella \
+// RUN:     -Wall -Werror
+// RUN: not diff %t/Module.pcm %t-saved/Module.pcm
+
+// -pedantic, -Werror is not compatible with -Wall -Werror
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fdisable-module-hash \
+// RUN:     -F %S/Inputs -fsyntax-only %s -verify -Wno-incomplete-umbrella \
+// RUN:     -Werror -pedantic
+// RUN: not diff %t/Module.pcm %t-saved/Module.pcm
+// RUN: cp %t/Module.pcm %t-saved/Module.pcm
+
+// -pedantic-errors is less strict that -pedantic, -Werror
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fdisable-module-hash \
+// RUN:     -F %S/Inputs -fsyntax-only %s -verify -Wno-incomplete-umbrella \
+// RUN:     -pedantic-errors
+// RUN: diff %t/Module.pcm %t-saved/Module.pcm
+
+// -Wsystem-headers does not affect non-system modules
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fdisable-module-hash \
+// RUN:     -F %S/Inputs -fsyntax-only %s -verify -Wno-incomplete-umbrella \
+// RUN:     -pedantic-errors -Wsystem-headers
+// RUN: diff %t/Module.pcm %t-saved/Module.pcm
+
+// expected-no-diagnostics
+@import Module;
diff --git a/test/Modules/auto-module-import.m b/test/Modules/auto-module-import.m
index d7fb9d1..bf99377 100644
--- a/test/Modules/auto-module-import.m
+++ b/test/Modules/auto-module-import.m
@@ -83,6 +83,6 @@
   return not_in_module;
 }
 
-void includeNotAtTopLevel() {
-  #include <NoUmbrella/A.h> // expected-warning {{treating #include as an import}} expected-error {{expected expression}}
-}
+void includeNotAtTopLevel() { // expected-note {{to match this '{'}}
+  #include <NoUmbrella/A.h> // expected-warning {{treating #include as an import}} expected-error {{expected '}'}}
+} // expected-error {{extraneous closing brace}}
diff --git a/test/Modules/autolink.m b/test/Modules/autolink.m
index 077aac5..47eda3f 100644
--- a/test/Modules/autolink.m
+++ b/test/Modules/autolink.m
@@ -1,6 +1,7 @@
 // RUN: rm -rf %t
-// RUN: %clang_cc1 -emit-llvm -o - -fmodules-cache-path=%t -fmodules -F %S/Inputs -I %S/Inputs %s | FileCheck %s
-// RUN: %clang_cc1 -emit-llvm -fno-autolink -o - -fmodules-cache-path=%t -fmodules -F %S/Inputs -I %S/Inputs %s | FileCheck --check-prefix=CHECK-AUTOLINK-DISABLED %s
+// RUN: %clang_cc1 -emit-pch -fmodules-cache-path=%t -fmodules -o %t.pch -I %S/Inputs -x objective-c-header %S/Inputs/autolink-sub3.pch
+// RUN: %clang_cc1 -emit-llvm -o - -fmodules-cache-path=%t -fmodules -F %S/Inputs -I %S/Inputs -include-pch %t.pch %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -fno-autolink -o - -fmodules-cache-path=%t -fmodules -F %S/Inputs -I %S/Inputs -include-pch %t.pch %s | FileCheck --check-prefix=CHECK-AUTOLINK-DISABLED %s
 
 @import autolink.sub2;
 
@@ -29,11 +30,16 @@
   return no_umbrella_A;
 }
 
+int use_autolink_sub3() {
+  return autolink_sub3();
+}
+
 // NOTE: "autolink_sub" is intentionally not linked.
 
-// CHECK: !llvm.module.flags = !{!0, !1, !2, !3, !4}
-// CHECK: !4 = metadata !{i32 6, metadata !"Linker Options", metadata ![[AUTOLINK_OPTIONS:[0-9]+]]}
-// CHECK: ![[AUTOLINK_OPTIONS]] = metadata !{metadata ![[AUTOLINK_FRAMEWORK:[0-9]+]], metadata ![[AUTOLINK:[0-9]+]], metadata ![[DEPENDSONMODULE:[0-9]+]], metadata ![[MODULE:[0-9]+]], metadata ![[NOUMBRELLA:[0-9]+]]}
+// CHECK: !llvm.module.flags = !{{{.*}}}
+// CHECK: !{{[0-9]+}} = metadata !{i32 6, metadata !"Linker Options", metadata ![[AUTOLINK_OPTIONS:[0-9]+]]}
+// CHECK: ![[AUTOLINK_OPTIONS]] = metadata !{metadata ![[AUTOLINK_PCH:[0-9]+]], metadata ![[AUTOLINK_FRAMEWORK:[0-9]+]], metadata ![[AUTOLINK:[0-9]+]], metadata ![[DEPENDSONMODULE:[0-9]+]], metadata ![[MODULE:[0-9]+]], metadata ![[NOUMBRELLA:[0-9]+]]}
+// CHECK: ![[AUTOLINK_PCH]] = metadata !{metadata !"{{(-l|/DEFAULTLIB:)}}autolink_from_pch{{(\.lib)?}}"}
 // CHECK: ![[AUTOLINK_FRAMEWORK]] = metadata !{metadata !"-framework", metadata !"autolink_framework"}
 // CHECK: ![[AUTOLINK]] = metadata !{metadata !"{{(-l|/DEFAULTLIB:)}}autolink{{(\.lib)?}}"}
 // CHECK: ![[DEPENDSONMODULE]] = metadata !{metadata !"-framework", metadata !"DependsOnModule"}
diff --git a/test/Modules/compiler_builtins_arm.m b/test/Modules/compiler_builtins_arm.m
index d15437c..5da6a12 100644
--- a/test/Modules/compiler_builtins_arm.m
+++ b/test/Modules/compiler_builtins_arm.m
@@ -1,6 +1,5 @@
 // RUN: rm -rf %t
 // RUN: %clang_cc1 -fsyntax-only -triple thumbv7-none-linux-gnueabihf -target-abi aapcs -target-cpu cortex-a8 -mfloat-abi hard -std=c99 -fmodules -fmodules-cache-path=%t -D__need_wint_t %s -verify
 // expected-no-diagnostics
-// REQUIRES: arm-registered-target
 
 @import _Builtin_intrinsics.arm.neon;
diff --git a/test/Modules/config_macros.m b/test/Modules/config_macros.m
index 200744d..b147317 100644
--- a/test/Modules/config_macros.m
+++ b/test/Modules/config_macros.m
@@ -24,5 +24,5 @@
 
 // RUN: rm -rf %t
 // RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -DWANT_FOO=1 -emit-module -fmodule-name=config %S/Inputs/module.map
-// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -DWANT_FOO=1 %s -verify
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs -DWANT_FOO=1 %s -verify
 
diff --git a/test/Modules/cxx-decls.cpp b/test/Modules/cxx-decls.cpp
index ba3281a..5498b47 100644
--- a/test/Modules/cxx-decls.cpp
+++ b/test/Modules/cxx-decls.cpp
@@ -1,8 +1,11 @@
 // RUN: rm -rf %t
 // RUN: %clang_cc1 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs %s -verify -std=c++11
+// RUN: %clang_cc1 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs %s -ast-dump -ast-dump-filter merge -std=c++11 | FileCheck %s
 
 // expected-no-diagnostics
 
+void use_implicit_new() { operator new[](3); }
+
 @import dummy;
 @import cxx_decls.imported;
 
@@ -19,3 +22,15 @@
   friend_1(s);
   friend_2(s);
 }
+
+static_assert(!__is_trivial(HasNontrivialDefaultConstructor), "");
+static_assert(!__has_trivial_constructor(HasNontrivialDefaultConstructor), "");
+
+void use_implicit_new_again() { operator new[](3); }
+
+int importMergeUsedFlag = getMergeUsedFlag();
+
+@import cxx_decls_merged;
+
+// CHECK: VarDecl [[mergeUsedFlag:0x[0-9a-f]*]] {{.*}} in cxx_decls.imported used mergeUsedFlag
+// CHECK: VarDecl {{0x[0-9a-f]*}} prev [[mergeUsedFlag]] {{.*}} in cxx_decls_merged used mergeUsedFlag
diff --git a/test/Modules/cxx-inline-namespace.cpp b/test/Modules/cxx-inline-namespace.cpp
index 5b96790..f67d43b 100644
--- a/test/Modules/cxx-inline-namespace.cpp
+++ b/test/Modules/cxx-inline-namespace.cpp
@@ -2,5 +2,8 @@
 // RUN: %clang_cc1 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs %s -verify -std=c++11
 
 @import cxx_inline_namespace;
+@import cxx_inline_namespace_b;
 
 T x; // expected-error {{unknown type name 'T'}}
+
+X::Elaborated *p;
diff --git a/test/Modules/cxx-irgen.cpp b/test/Modules/cxx-irgen.cpp
new file mode 100644
index 0000000..4c61a3a
--- /dev/null
+++ b/test/Modules/cxx-irgen.cpp
@@ -0,0 +1,22 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -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
+// FIXME: When we have a syntax for modules in C++, use that.
+
+@import cxx_irgen_top;
+
+// CHECK-DAG: call {{[a-z]*[ ]?i32}} @_ZN8CtorInitIiE1fEv(
+CtorInit<int> x;
+
+@import cxx_irgen_left;
+@import cxx_irgen_right;
+
+// CHECK-DAG: define available_externally hidden {{signext i32|i32}} @_ZN1SIiE1gEv({{.*}} #[[ALWAYS_INLINE:.*]] align
+int a = S<int>::g();
+
+// CHECK-DAG: define available_externally {{signext i32|i32}} @_ZN1SIiE1fEv({{.*}} #[[ALWAYS_INLINE]] align
+int b = h();
+
+// CHECK-DAG: define linkonce_odr {{signext i32|i32}} @_Z3minIiET_S0_S0_(i32
+int c = min(1, 2);
+
+// CHECK: attributes #[[ALWAYS_INLINE]] = {{.*}} alwaysinline
diff --git a/test/Modules/cxx-templates.cpp b/test/Modules/cxx-templates.cpp
index 65f41f6..cbe9f35 100644
--- a/test/Modules/cxx-templates.cpp
+++ b/test/Modules/cxx-templates.cpp
@@ -1,7 +1,8 @@
 // RUN: rm -rf %t
-// RUN: not %clang_cc1 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs %s -std=c++11 -ast-dump -ast-dump-lookups | FileCheck %s --check-prefix=CHECK-GLOBAL
-// RUN: not %clang_cc1 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs %s -std=c++11 -ast-dump -ast-dump-lookups -ast-dump-filter N | FileCheck %s --check-prefix=CHECK-NAMESPACE-N
-// RUN: %clang_cc1 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs %s -verify -std=c++11
+// RUN: not %clang_cc1 -x objective-c++ -fmodules -fno-modules-error-recovery -fmodules-cache-path=%t -I %S/Inputs %s -std=c++11 -ast-dump -ast-dump-lookups | FileCheck %s --check-prefix=CHECK-GLOBAL
+// RUN: not %clang_cc1 -x objective-c++ -fmodules -fno-modules-error-recovery -fmodules-cache-path=%t -I %S/Inputs %s -std=c++11 -ast-dump -ast-dump-lookups -ast-dump-filter N | FileCheck %s --check-prefix=CHECK-NAMESPACE-N
+// RUN: not %clang_cc1 -x objective-c++ -fmodules -fno-modules-error-recovery -fmodules-cache-path=%t -I %S/Inputs %s -std=c++11 -ast-dump | FileCheck %s --check-prefix=CHECK-DUMP
+// RUN: %clang_cc1 -x objective-c++ -fmodules -fno-modules-error-recovery -fmodules-cache-path=%t -I %S/Inputs %s -verify -std=c++11
 
 @import cxx_templates_a;
 @import cxx_templates_b;
@@ -28,8 +29,8 @@
   N::f<double>(1.0);
   N::f<int>();
   N::f(); // expected-error {{no matching function}}
-  // expected-note@Inputs/cxx-templates-b.h:6 {{couldn't infer template argument}}
-  // expected-note@Inputs/cxx-templates-b.h:7 {{requires single argument 't'}}
+  // expected-note@Inputs/cxx-templates-a.h:6 {{couldn't infer template argument}}
+  // expected-note@Inputs/cxx-templates-a.h:7 {{requires 1 argument}}
 
   template_param_kinds_1<0>(); // ok, from cxx-templates-a.h
   template_param_kinds_1<int>(); // ok, from cxx-templates-b.h
@@ -70,8 +71,15 @@
   // Trigger the instantiation of a template in 'a' that uses a type defined in
   // 'b_impl'. That type is not visible here, nor in 'a'. This fails; there is
   // no reason why DefinedInBImpl should be visible here.
+  //
+  // We turn off error recovery for modules in this test (so we don't get an
+  // implicit import of cxx_templates_b_impl), and that results in us producing
+  // a big spew of errors here.
+  //
   // expected-error@Inputs/cxx-templates-a.h:19 {{definition of 'DefinedInBImpl' must be imported}}
-  // expected-note@Inputs/cxx-templates-b-impl.h:1 {{definition is here}}
+  // expected-note@Inputs/cxx-templates-b-impl.h:1 +{{definition is here}}
+  // expected-error@Inputs/cxx-templates-a.h:19 +{{}}
+  // expected-error@Inputs/cxx-templates-a.h:20 +{{}}
   PerformDelayedLookup(defined_in_b_impl); // expected-note {{in instantiation of}}
 
   merge_templates_a = merge_templates_b; // ok, same type
@@ -88,8 +96,23 @@
   static_assert(enum_c_from_a == enum_c_from_b, "");
   CommonTemplate<int> cti;
   CommonTemplate<int>::E eee = CommonTemplate<int>::c;
+
+  TemplateInstantiationVisibility<char[1]> tiv1;
+  TemplateInstantiationVisibility<char[2]> tiv2;
+  TemplateInstantiationVisibility<char[3]> tiv3; // expected-error {{must be imported from module 'cxx_templates_b_impl'}}
+  // expected-note@cxx-templates-b-impl.h:10 {{previous definition is here}}
+  TemplateInstantiationVisibility<char[4]> tiv4;
+
+  int &p = WithPartialSpecializationUse().f();
+  int &q = WithExplicitSpecializationUse().inner_template<int>();
 }
 
+static_assert(Outer<int>::Inner<int>::f() == 1, "");
+static_assert(Outer<int>::Inner<int>::g() == 2, "");
+
+static_assert(MergeTemplateDefinitions<int>::f() == 1, "");
+static_assert(MergeTemplateDefinitions<int>::g() == 2, "");
+
 RedeclaredAsFriend<int> raf1;
 RedeclareTemplateAsFriend<double> rtaf;
 RedeclaredAsFriend<double> raf2;
@@ -116,6 +139,15 @@
   c = d;
 }
 
+bool testFriendInClassTemplate(Std::WithFriend<int> wfi) {
+  return wfi != wfi;
+}
+
+namespace Std {
+  void g(); // expected-error {{functions that differ only in their return type cannot be overloaded}}
+  // expected-note@cxx-templates-common.h:21 {{previous}}
+}
+
 // CHECK-GLOBAL:      DeclarationName 'f'
 // CHECK-GLOBAL-NEXT: |-FunctionTemplate {{.*}} 'f'
 // CHECK-GLOBAL-NEXT: `-FunctionTemplate {{.*}} 'f'
@@ -123,3 +155,13 @@
 // CHECK-NAMESPACE-N:      DeclarationName 'f'
 // CHECK-NAMESPACE-N-NEXT: |-FunctionTemplate {{.*}} 'f'
 // CHECK-NAMESPACE-N-NEXT: `-FunctionTemplate {{.*}} 'f'
+
+// CHECK-DUMP:      ClassTemplateDecl {{.*}} <{{.*[/\\]}}cxx-templates-common.h:1:1, {{.*}}>  col:{{.*}} in cxx_templates_common SomeTemplate
+// CHECK-DUMP:        ClassTemplateSpecializationDecl {{.*}} prev [[CHAR2:[^ ]*]] {{.*}} SomeTemplate
+// CHECK-DUMP-NEXT:     TemplateArgument type 'char [2]'
+// CHECK-DUMP:        ClassTemplateSpecializationDecl [[CHAR2]] {{.*}} SomeTemplate definition
+// CHECK-DUMP-NEXT:     TemplateArgument type 'char [2]'
+// CHECK-DUMP:        ClassTemplateSpecializationDecl {{.*}} prev [[CHAR1:[^ ]*]] {{.*}} SomeTemplate
+// CHECK-DUMP-NEXT:     TemplateArgument type 'char [1]'
+// CHECK-DUMP:        ClassTemplateSpecializationDecl [[CHAR1]] {{.*}} SomeTemplate definition
+// CHECK-DUMP-NEXT:     TemplateArgument type 'char [1]'
diff --git a/test/Modules/declare-use.S b/test/Modules/declare-use.S
new file mode 100644
index 0000000..2c5d8af
--- /dev/null
+++ b/test/Modules/declare-use.S
@@ -0,0 +1,5 @@
+// RUN: rm -rf %t
+// RUN: %clang -fmodule-maps -fmodules-cache-path=%t -fmodules-decluse -fmodule-name=XS -I %S/Inputs/declare-use -S %s -Xclang -verify
+// expected-no-diagnostics
+
+#include "s.h"
diff --git a/test/Modules/declare-use1.cpp b/test/Modules/declare-use1.cpp
index 4508017..5fc4336 100644
--- a/test/Modules/declare-use1.cpp
+++ b/test/Modules/declare-use1.cpp
@@ -1,7 +1,8 @@
 // RUN: rm -rf %t
-// RUN: %clang_cc1 -x objective-c++ -fmodules-cache-path=%t -fmodules -fmodules-decluse -fmodule-name=XG -I %S/Inputs/declare-use %s -verify
+// RUN: %clang_cc1 -fmodule-maps -fmodules-cache-path=%t -fmodules-decluse -fmodule-name=XG -I %S/Inputs/declare-use %s -verify
 
 #include "g.h"
 #include "e.h"
-#include "f.h" // expected-error {{use of a module not declared used}}
-const int g2 = g1+e+f;
+#include "f.h" // expected-error {{module XG does not depend on a module exporting 'f.h'}}
+#include "i.h"
+const int g2 = g1 + e + f + aux_i;
diff --git a/test/Modules/declare-use2.cpp b/test/Modules/declare-use2.cpp
index a2ec55e..4535289 100644
--- a/test/Modules/declare-use2.cpp
+++ b/test/Modules/declare-use2.cpp
@@ -1,7 +1,7 @@
 // RUN: rm -rf %t
-// RUN: %clang_cc1 -x objective-c++ -fmodules-cache-path=%t -fmodules -fmodules-decluse -fmodule-name=XH -I %S/Inputs/declare-use %s -verify
+// RUN: %clang_cc1 -fmodule-maps -fmodules-cache-path=%t -fmodules-decluse -fmodule-name=XH -I %S/Inputs/declare-use %s -verify
 
 #include "h.h"
 #include "e.h"
-#include "f.h" // expected-error {{use of a module not declared used}}
+#include "f.h" // expected-error {{module XH does not depend on a module exporting 'f.h'}}
 const int h2 = h1+e+f;
diff --git a/test/Modules/declare-use3.cpp b/test/Modules/declare-use3.cpp
new file mode 100644
index 0000000..8b0bbfa
--- /dev/null
+++ b/test/Modules/declare-use3.cpp
@@ -0,0 +1,4 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -include "g.h" -include "e.h" -include "f.h" -include "i.h" -fmodule-maps -fmodules-cache-path=%t -fmodules-decluse -fmodule-name=XG -I %S/Inputs/declare-use %s -verify
+// expected-error {{module XG does not depend on a module exporting 'f.h'}}
+const int g2 = g1 + e + f + aux_i;
diff --git a/test/Modules/declare-use4.cpp b/test/Modules/declare-use4.cpp
new file mode 100644
index 0000000..1d34646
--- /dev/null
+++ b/test/Modules/declare-use4.cpp
@@ -0,0 +1,10 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodule-maps -fmodules-cache-path=%t -fmodules-decluse -fmodule-name=XG -I %S/Inputs/declare-use %s -verify
+
+#define ALLOWED_INC "b.h"
+
+#include "j.h"
+
+const int g2 = j;
+
+// expected-no-diagnostics
diff --git a/test/Modules/decldef.mm b/test/Modules/decldef.mm
index 3569493..2e2bd8a 100644
--- a/test/Modules/decldef.mm
+++ b/test/Modules/decldef.mm
@@ -1,14 +1,18 @@
 // RUN: rm -rf %t
-// RUN: %clang_cc1 -fmodules -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify -DUSE_EARLY
-// RUN: %clang_cc1 -fmodules -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify
+// RUN: %clang_cc1 -fmodules -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify -DUSE_1 -DUSE_2 -DUSE_3 -DUSE_4
+// RUN: %clang_cc1 -fmodules -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify -DUSE_2 -DUSE_3 -DUSE_4
+// RUN: %clang_cc1 -fmodules -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify -DUSE_3 -DUSE_4
+// RUN: %clang_cc1 -fmodules -fobjc-arc -I %S/Inputs -fmodules-cache-path=%t %s -verify -DUSE_4
 
-// expected-note@Inputs/def.h:5 {{previous}}
+// expected-note@Inputs/def.h:5 0-1{{previous}}
+// expected-note@Inputs/def.h:16 0-1{{previous}}
+// expected-note@Inputs/def-include.h:11 0-1{{previous}}
 
 @class Def;
 Def *def;
-class Def2; // expected-note {{forward decl}}
+class Def2; // expected-note 0-1{{forward decl}}
 Def2 *def2;
-namespace Def3NS { class Def3; } // expected-note {{forward decl}}
+namespace Def3NS { class Def3; } // expected-note 0-1{{forward decl}}
 Def3NS::Def3 *def3;
 
 @interface Unrelated
@@ -16,9 +20,10 @@
 @end
 
 @import decldef;
-#ifdef USE_EARLY
+#ifdef USE_1
 A *a1; // expected-error{{declaration of 'A' must be imported from module 'decldef.Def'}}
 B *b1;
+#define USED
 #endif
 @import decldef.Decl;
 
@@ -26,14 +31,23 @@
 B *b;
 
 void testA(A *a) {
+#ifdef USE_2
   a->ivar = 17;
-#ifndef USE_EARLY
+  #ifndef USED
   // expected-error@-2{{definition of 'A' must be imported from module 'decldef.Def' before it is required}}
+  #define USED
+  #endif
 #endif
 }
 
 void testB() {
-  B b; // Note: redundant error silenced
+#ifdef USE_3
+  B b;
+  #ifndef USED
+  // expected-error@-2{{definition of 'B' must be imported from module 'decldef.Def' before it is required}}
+  #define USED
+  #endif
+#endif
 }
 
 void testDef() {
@@ -41,9 +55,12 @@
 }
 
 void testDef2() {
-  // FIXME: These should both work, since we've (implicitly) imported
-  // decldef.Def here, but they don't, because nothing has triggered the lazy
-  // loading of the definitions of these classes.
-  def2->func(); // expected-error {{incomplete}}
-  def3->func(); // expected-error {{incomplete}}
+#ifdef USE_4
+  def2->func();
+  def3->func();
+  #ifndef USED
+  // expected-error@-3 {{definition of 'Def2' must be imported}}
+  #define USED
+  #endif
+#endif
 }
diff --git a/test/Modules/dependency-dump-dependent-module.m b/test/Modules/dependency-dump-dependent-module.m
new file mode 100644
index 0000000..3b04435
--- /dev/null
+++ b/test/Modules/dependency-dump-dependent-module.m
@@ -0,0 +1,22 @@
+// When a module depends on another, check that we dump the dependency header
+// files for both.
+
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t/cache -module-dependency-dir %t/vfs -F %S/Inputs -I %S/Inputs -verify %s
+// expected-no-diagnostics
+
+// RUN: FileCheck %s -check-prefix=VFS < %t/vfs/vfs.yaml
+// VFS: 'name': "AlsoDependsOnModule.h"
+// VFS: 'name': "SubFramework.h"
+// VFS: 'name': "Treasure.h"
+// VFS: 'name': "Module.h"
+// VFS: 'name': "Sub.h"
+// VFS: 'name': "Sub2.h"
+
+@import AlsoDependsOnModule;
+
+// FIXME: This fails on win32 due to ERROR_FILENAME_EXCED_RANGE
+// if the working directory is too deep.
+// We should make Win32/Path.inc capable of long pathnames with '\\?\'.
+// For now, this is suppressed on win32.
+// REQUIRES: shell
diff --git a/test/Modules/dependency-dump.m b/test/Modules/dependency-dump.m
new file mode 100644
index 0000000..630af49
--- /dev/null
+++ b/test/Modules/dependency-dump.m
@@ -0,0 +1,15 @@
+// Check that we can dump all of the headers a module depends on, and a VFS map
+// for the same.
+
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t/cache -module-dependency-dir %t/vfs -F %S/Inputs -I %S/Inputs -verify %s
+// expected-no-diagnostics
+
+// RUN: FileCheck %s -check-prefix=VFS -input-file %t/vfs/vfs.yaml
+// VFS: 'name': "SubFramework.h"
+// VFS: 'name': "Treasure.h"
+// VFS: 'name': "Module.h"
+// VFS: 'name': "Sub.h"
+// VFS: 'name': "Sub2.h"
+
+@import Module;
diff --git a/test/Modules/dependency-gen-inferred-map.m b/test/Modules/dependency-gen-inferred-map.m
new file mode 100644
index 0000000..11cc872
--- /dev/null
+++ b/test/Modules/dependency-gen-inferred-map.m
@@ -0,0 +1,8 @@
+// Test that the virtual file "__inferred_module.map" doesn't show up as dependency.
+
+// RUN: rm -rf %t-mcp
+// RUN: %clang_cc1 -isysroot %S/Inputs/System -triple x86_64-apple-darwin10 -dependency-file %t.d -MT %s.o -F %S/Inputs -fsyntax-only -fmodules -fmodules-cache-path=%t-mcp %s
+// RUN: FileCheck %s < %t.d
+// CHECK-NOT: __inferred_module
+
+@import Module;
diff --git a/test/Modules/dependency-gen-pch.m b/test/Modules/dependency-gen-pch.m
new file mode 100644
index 0000000..65e22d4
--- /dev/null
+++ b/test/Modules/dependency-gen-pch.m
@@ -0,0 +1,12 @@
+// RUN: rm -rf %t-mcp
+// RUN: mkdir -p %t-mcp
+
+// RUN: %clang_cc1 -isysroot %S/Inputs/System -triple x86_64-apple-darwin10 -module-file-deps -dependency-file %t.d -MT %s.o -I %S/Inputs -fmodules -fdisable-module-hash -fmodules-cache-path=%t-mcp -emit-pch -o %t.pch %s
+// RUN: FileCheck %s < %t.d
+// CHECK: dependency-gen-pch.m.o
+// CHECK-NEXT: dependency-gen-pch.m
+// CHECK-NEXT: diamond_top.pcm
+// CHECK-NEXT: Inputs{{.}}diamond_top.h
+// CHECK-NEXT: Inputs{{.}}module.map
+
+#import "diamond_top.h"
diff --git a/test/Modules/dependency-gen.m b/test/Modules/dependency-gen.m
new file mode 100644
index 0000000..dec8384
--- /dev/null
+++ b/test/Modules/dependency-gen.m
@@ -0,0 +1,22 @@
+// RUN: rm -rf %t-mcp
+// RUN: mkdir -p %t-mcp
+
+// RUN: %clang_cc1 -x objective-c -isysroot %S/Inputs/System -triple x86_64-apple-darwin10 -dependency-file %t.d.1 -MT %s.o -I %S/Inputs -fsyntax-only -fmodules -fmodules-cache-path=%t-mcp %s
+// RUN: FileCheck %s < %t.d.1
+// CHECK: dependency-gen.m
+// CHECK: Inputs{{.}}diamond_top.h
+// CHECK: Inputs{{.}}module.map
+// CHECK-NOT: usr{{.}}include{{.}}module.map
+// CHECK-NOT: stdint.h
+
+
+// RUN: %clang_cc1 -x objective-c -isysroot %S/Inputs/System -triple x86_64-apple-darwin10 -dependency-file %t.d.2 -MT %s.o -I %S/Inputs -sys-header-deps -fsyntax-only -fmodules -fmodules-cache-path=%t-mcp %s
+// RUN: FileCheck %s -check-prefix=CHECK-SYS < %t.d.2
+// CHECK-SYS: dependency-gen.m
+// CHECK-SYS: Inputs{{.}}diamond_top.h
+// CHECK-SYS: Inputs{{.}}module.map
+// CHECK-SYS: usr{{.}}include{{.}}module.map
+// CHECK-SYS: stdint.h
+
+#import "diamond_top.h"
+#import "stdint.h" // inside sysroot
diff --git a/test/Modules/diag-pragma.c b/test/Modules/diag-pragma.c
index 7ec3400..89435c1 100644
--- a/test/Modules/diag-pragma.c
+++ b/test/Modules/diag-pragma.c
@@ -1,6 +1,6 @@
 // RUN: rm -rf %t
 // RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diag_pragma %S/Inputs/module.map
-// RUN: %clang_cc1 -fmodules -x objective-c -verify -fmodules-cache-path=%t %s
+// RUN: %clang_cc1 -fmodules -x objective-c -verify -fmodules-cache-path=%t -I %S/Inputs %s
 // FIXME: When we have a syntax for modules in C, use that.
 
 @import diag_pragma;
diff --git a/test/Modules/diamond-pch.c b/test/Modules/diamond-pch.c
index e7ad02d..f66ad87 100644
--- a/test/Modules/diamond-pch.c
+++ b/test/Modules/diamond-pch.c
@@ -3,8 +3,8 @@
 // RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_left %S/Inputs/module.map
 // RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_right %S/Inputs/module.map
 // RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_bottom %S/Inputs/module.map
-// RUN: %clang_cc1 -fmodules -x objective-c -emit-pch -fmodules-cache-path=%t -o %t.pch %S/Inputs/diamond.h
-// RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -include-pch %t.pch %s -verify
+// RUN: %clang_cc1 -fmodules -x objective-c -emit-pch -fmodules-cache-path=%t -I %S/Inputs -o %t.pch %S/Inputs/diamond.h
+// RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -include-pch %t.pch %s -I %S/Inputs -verify
 // FIXME: When we have a syntax for modules in C, use that.
 
 void test_diamond(int i, float f, double d, char c) {
diff --git a/test/Modules/diamond.c b/test/Modules/diamond.c
index 89d5bc0..8b82408 100644
--- a/test/Modules/diamond.c
+++ b/test/Modules/diamond.c
@@ -3,7 +3,7 @@
 // RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_left %S/Inputs/module.map
 // RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_right %S/Inputs/module.map
 // RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_bottom %S/Inputs/module.map
-// RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t %s -verify
+// RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -I %S/Inputs %s -verify
 // FIXME: When we have a syntax for modules in C, use that.
 
 @import diamond_bottom;
diff --git a/test/Modules/exclude-header.c b/test/Modules/exclude-header.c
new file mode 100644
index 0000000..4134c82
--- /dev/null
+++ b/test/Modules/exclude-header.c
@@ -0,0 +1,11 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -x objective-c -fmodules -fmodules-cache-path=%t -I %S/Inputs/exclude-header %s -verify
+
+@import x;
+
+a var_a;
+b var_b1; // expected-error {{unknown type name 'b'}}
+
+@import y;
+
+b var_b2;
diff --git a/test/Modules/extern_c.cpp b/test/Modules/extern_c.cpp
new file mode 100644
index 0000000..ba466f2
--- /dev/null
+++ b/test/Modules/extern_c.cpp
@@ -0,0 +1,81 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -verify -fmodules-cache-path=%t -I %S/Inputs %s
+// RUN: %clang_cc1 -fmodules -verify -fmodules-cache-path=%t -I %S/Inputs %s -DEXTERN_C
+// RUN: %clang_cc1 -fmodules -verify -fmodules-cache-path=%t -I %S/Inputs %s -DEXTERN_CXX
+// RUN: %clang_cc1 -fmodules -verify -fmodules-cache-path=%t -I %S/Inputs %s -DEXTERN_C -DEXTERN_CXX
+// RUN: %clang_cc1 -fmodules -verify -fmodules-cache-path=%t -I %S/Inputs %s -DEXTERN_C -DNAMESPACE
+// RUN: %clang_cc1 -fmodules -verify -fmodules-cache-path=%t -I %S/Inputs %s -DCXX_HEADER
+// RUN: %clang_cc1 -fmodules -verify -fmodules-cache-path=%t -I %S/Inputs %s -DCXX_HEADER -DEXTERN_C
+// RUN: %clang_cc1 -fmodules -verify -fmodules-cache-path=%t -I %S/Inputs %s -DCXX_HEADER -DEXTERN_CXX
+// RUN: %clang_cc1 -fmodules -verify -fmodules-cache-path=%t -I %S/Inputs %s -DCXX_HEADER -DEXTERN_C -DEXTERN_CXX
+// RUN: %clang_cc1 -fmodules -verify -fmodules-cache-path=%t -I %S/Inputs %s -DCXX_HEADER -DEXTERN_C -DNAMESPACE
+// RUN: %clang_cc1 -fmodules -verify -fmodules-cache-path=%t -I %S/Inputs -x c %s
+// RUN: %clang_cc1 -fmodules -verify -fmodules-cache-path=%t -I %S/Inputs/elsewhere -I %S/Inputs %s -DEXTERN_C -DINDIRECT
+
+#ifdef INDIRECT
+#include "c-header-indirect.h"
+#endif
+
+#ifdef NAMESPACE
+namespace M {
+#endif
+
+#ifdef EXTERN_C
+extern "C" {
+#endif
+
+#ifdef EXTERN_CXX
+extern "C++" {
+#endif
+
+#ifdef CXX_HEADER
+#define HEADER "cxx-header.h"
+#else
+#define HEADER "c-header.h"
+#endif
+
+#include HEADER
+
+#if defined(EXTERN_C) && !defined(EXTERN_CXX) && defined(CXX_HEADER)
+// expected-error@-3 {{import of C++ module 'cxx_library' appears within extern "C" language linkage specification}}
+// expected-note@-17 {{extern "C" language linkage specification begins here}}
+#elif defined(NAMESPACE)
+// expected-error-re@-6 {{import of module '{{c_library.inner|cxx_library}}' appears within namespace 'M'}}
+// expected-note@-24 {{namespace 'M' begins here}}
+#endif
+
+#ifdef EXTERN_CXX
+}
+#endif
+
+#ifdef EXTERN_C
+}
+#endif
+
+#ifdef NAMESPACE
+}
+using namespace M;
+#endif
+
+#ifdef __cplusplus
+namespace N {
+#endif
+  void g() {
+    int k = f();
+  }
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+    int f;
+#if !defined(CXX_HEADER)
+    // expected-error@-2 {{redefinition of 'f' as different kind of symbol}}
+    // expected-note@c-header.h:1 {{previous}}
+#endif
+
+#ifdef __cplusplus
+  }
+}
+#endif
+
+suppress_expected_no_diagnostics_error error_here; // expected-error {{}}
diff --git a/test/Modules/extern_c_bad.cpp b/test/Modules/extern_c_bad.cpp
new file mode 100644
index 0000000..bafdc04
--- /dev/null
+++ b/test/Modules/extern_c_bad.cpp
@@ -0,0 +1,2 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -verify -fmodules -x c++ -emit-module -fmodules-cache-path=%t -fmodule-name=c_library_bad %S/Inputs/module.map
diff --git a/test/Modules/fatal-module-loader-error.m b/test/Modules/fatal-module-loader-error.m
index 6af3b4c..2d8dd24 100644
--- a/test/Modules/fatal-module-loader-error.m
+++ b/test/Modules/fatal-module-loader-error.m
@@ -23,4 +23,4 @@
 // Also check that libclang does not create a PCH with such an error.
 // RUN: not c-index-test -write-pch %t.pch -fmodules -fmodules-cache-path=%t \
 // RUN: %s -Xclang -fdisable-module-hash -F %S/Inputs 2>&1 | FileCheck %s
-// CHECK: Unable to write PCH file
+// CHECK: {{^}}Failure: AST deserialization error occurred{{$}}
diff --git a/test/Modules/fmodules-validate-once-per-build-session.c b/test/Modules/fmodules-validate-once-per-build-session.c
new file mode 100644
index 0000000..346d5a7
--- /dev/null
+++ b/test/Modules/fmodules-validate-once-per-build-session.c
@@ -0,0 +1,45 @@
+#include "foo.h"
+
+// Clear the module cache.
+// RUN: rm -rf %t
+// RUN: mkdir -p %t/Inputs
+// RUN: mkdir -p %t/modules-to-compare
+
+// ===
+// Create a module with system headers.
+// RUN: echo 'void meow(void);' > %t/Inputs/foo.h
+// RUN: echo 'module Foo [system] { header "foo.h" }' > %t/Inputs/module.map
+
+// ===
+// Compile the module.
+// RUN: %clang_cc1 -cc1 -fmodules -fdisable-module-hash -fmodules-cache-path=%t/modules-cache -fsyntax-only -I %t/Inputs -fbuild-session-timestamp=1390000000 -fmodules-validate-once-per-build-session %s
+// RUN: ls -R %t/modules-cache | grep Foo.pcm.timestamp
+// RUN: cp %t/modules-cache/Foo.pcm %t/modules-to-compare/Foo-before.pcm
+
+// ===
+// Use it, and make sure that we did not recompile it.
+// RUN: %clang_cc1 -cc1 -fmodules -fdisable-module-hash -fmodules-cache-path=%t/modules-cache -fsyntax-only -I %t/Inputs -fbuild-session-timestamp=1390000000 -fmodules-validate-once-per-build-session %s
+// RUN: ls -R %t/modules-cache | grep Foo.pcm.timestamp
+// RUN: cp %t/modules-cache/Foo.pcm %t/modules-to-compare/Foo-after.pcm
+
+// RUN: diff %t/modules-to-compare/Foo-before.pcm %t/modules-to-compare/Foo-after.pcm
+
+// ===
+// Change the sources.
+// RUN: echo 'void meow2(void);' > %t/Inputs/foo.h
+
+// ===
+// Use the module, and make sure that we did not recompile it, even though the sources changed.
+// RUN: %clang_cc1 -cc1 -fmodules -fdisable-module-hash -fmodules-cache-path=%t/modules-cache -fsyntax-only -I %t/Inputs -fbuild-session-timestamp=1390000000 -fmodules-validate-once-per-build-session %s
+// RUN: ls -R %t/modules-cache | grep Foo.pcm.timestamp
+// RUN: cp %t/modules-cache/Foo.pcm %t/modules-to-compare/Foo-after.pcm
+
+// RUN: diff %t/modules-to-compare/Foo-before.pcm %t/modules-to-compare/Foo-after.pcm
+
+// ===
+// Recompile the module if the today's date is before 01 January 2030.
+// RUN: %clang_cc1 -cc1 -fmodules -fdisable-module-hash -fmodules-cache-path=%t/modules-cache -fsyntax-only -I %t/Inputs -fbuild-session-timestamp=1893456000 -fmodules-validate-once-per-build-session %s
+// RUN: ls -R %t/modules-cache | grep Foo.pcm.timestamp
+// RUN: cp %t/modules-cache/Foo.pcm %t/modules-to-compare/Foo-after.pcm
+
+// RUN: not diff %t/modules-to-compare/Foo-before.pcm %t/modules-to-compare/Foo-after.pcm
diff --git a/test/Modules/import-self.m b/test/Modules/import-self.m
new file mode 100644
index 0000000..68be565
--- /dev/null
+++ b/test/Modules/import-self.m
@@ -0,0 +1,11 @@
+// RUN: rm -rf %t
+// RUN: not %clang_cc1 -fmodules -fmodules-cache-path=%t \
+// RUN:                -I %S/Inputs/submodules %s 2>&1 | FileCheck %s
+// CHECK: import of module 'import_self.c' appears within same top-level module 'import_self'
+
+// RUN: not %clang_cc1 -fmodules -fmodules-cache-path=%t \
+// RUN:                -I %S/Inputs/submodules -fmodule-name=import_self %s \
+// RUN:     2>&1 |  FileCheck -check-prefix=CHECK-fmodule-name %s
+// CHECK-fmodule-name: import of module 'import_self.b' appears within same top-level module 'import_self'
+
+@import import_self.b;
diff --git a/test/Modules/include-relative.c b/test/Modules/include-relative.c
new file mode 100644
index 0000000..9ca76ee
--- /dev/null
+++ b/test/Modules/include-relative.c
@@ -0,0 +1,12 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: cp -r %S/Inputs/include-relative %t/include-relative
+// RUN: cd %t
+// RUN: %clang_cc1 -fmodules -x c -verify -fmodules-cache-path=%t -I include-relative %s
+// REQUIRES: shell
+
+// expected-no-diagnostics
+
+#include "a.h"
+
+int f() { return n; }
diff --git a/test/Modules/inferred-framework-case.m b/test/Modules/inferred-framework-case.m
new file mode 100644
index 0000000..e511155
--- /dev/null
+++ b/test/Modules/inferred-framework-case.m
@@ -0,0 +1,7 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -F %S/Inputs %s -verify -DA
+// FIXME: PR20299 - getCanonicalName() is not implemented on Windows.
+// REQUIRES: shell
+
+@import MOdule; // expected-error{{module 'MOdule' not found}}
+@import Module;
diff --git a/test/Modules/irgen.c b/test/Modules/irgen.c
index 9a7cf7e..c44afb1 100644
--- a/test/Modules/irgen.c
+++ b/test/Modules/irgen.c
@@ -1,6 +1,6 @@
 // RUN: rm -rf %t
 // RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -emit-module -fmodule-name=irgen -triple x86_64-apple-darwin10 %S/Inputs/module.map
-// RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -I %S/Inputs -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
 // FIXME: When we have a syntax for modules in C, use that.
 
 @import irgen;
diff --git a/test/Modules/linkage-merge.cpp b/test/Modules/linkage-merge.cpp
index 9cc9ae6..664716d 100644
--- a/test/Modules/linkage-merge.cpp
+++ b/test/Modules/linkage-merge.cpp
@@ -7,6 +7,5 @@
 int f(int);
 
 static void g(int);
-// expected-error@-1 {{declaration conflicts with target of using declaration already in scope}}
-// expected-note@Inputs/linkage-merge-foo.h:2 {{target of using declaration}}
-// expected-note@Inputs/linkage-merge-bar.h:3 {{using declaration}}
+// expected-error@-1 {{functions that differ only in their return type cannot be overloaded}}
+// expected-note@Inputs/linkage-merge-foo.h:2 {{previous declaration is here}}
diff --git a/test/Modules/linkage-merge.m b/test/Modules/linkage-merge.m
index e838ca1..12ad32f 100644
--- a/test/Modules/linkage-merge.m
+++ b/test/Modules/linkage-merge.m
@@ -1,6 +1,6 @@
 // RUN: rm -rf %t
 // RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -emit-module -fmodule-name=linkage_merge_left %S/Inputs/module.map
-// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -w %s -verify
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs -w %s -verify
 
 // Test redeclarations of functions where the original declaration is
 // still hidden.
diff --git a/test/Modules/load-after-failure.m b/test/Modules/load-after-failure.m
new file mode 100644
index 0000000..f471fd8
--- /dev/null
+++ b/test/Modules/load-after-failure.m
@@ -0,0 +1,25 @@
+// REQUIRES: shell
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+
+// RUN: echo '@import B;' > %t/A.h
+// RUN: echo '@import C;' > %t/B.h
+// RUN: echo '@import D;' >> %t/B.h
+// RUN: echo '// C.h' > %t/C.h
+// RUN: echo '// D.h' > %t/D.h
+// RUN: echo 'module A { header "A.h" }' > %t/module.modulemap
+// RUN: echo 'module B { header "B.h" }' >> %t/module.modulemap
+// RUN: echo 'module C { header "C.h" }' >> %t/module.modulemap
+// RUN: echo 'module D { header "D.h" }' >> %t/module.modulemap
+
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %t %s -verify
+// RUN: echo " " >> %t/D.h
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %t %s -verify
+// expected-no-diagnostics
+
+
+@import C;
+@import A;
+@import C;
+// When compiling A, C will be be loaded then removed when D fails. Ensure
+// this does not cause problems importing C again later.
diff --git a/test/Modules/load_failure.c b/test/Modules/load_failure.c
index 6c6d812..8b0d202 100644
--- a/test/Modules/load_failure.c
+++ b/test/Modules/load_failure.c
@@ -8,10 +8,10 @@
 
 // RUN: rm -rf %t
 // RUN: %clang_cc1 -fmodules -x objective-c++ -fmodules-cache-path=%t -fdisable-module-hash -emit-module -fmodule-name=load_failure %S/Inputs/module.map
-// RUN: not %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -fdisable-module-hash %s -DNONEXISTENT 2>&1 | FileCheck -check-prefix=CHECK-NONEXISTENT %s
+// RUN: not %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -I %S/Inputs -fdisable-module-hash %s -DNONEXISTENT 2>&1 | FileCheck -check-prefix=CHECK-NONEXISTENT %s
 // CHECK-NONEXISTENT: load_failure.c:2:9: fatal error: module 'load_nonexistent' not found
 
-// RUN: not %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -fdisable-module-hash %s -DFAILURE 2> %t.out
+// RUN: not %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -I %S/Inputs -fdisable-module-hash %s -DFAILURE 2> %t.out
 // RUN: FileCheck -check-prefix=CHECK-FAILURE %s < %t.out
 
 // FIXME: Clean up diagnostic text below and give it a location
diff --git a/test/Modules/lookup.cpp b/test/Modules/lookup.cpp
index efd88f4..bfe0307 100644
--- a/test/Modules/lookup.cpp
+++ b/test/Modules/lookup.cpp
@@ -26,8 +26,8 @@
 // RUN: rm -rf %t
 // RUN: %clang_cc1 -fmodules -x objective-c++ -emit-module -fmodules-cache-path=%t -fmodule-name=lookup_left_cxx %S/Inputs/module.map -verify
 // RUN: %clang_cc1 -fmodules -x objective-c++ -emit-module -fmodules-cache-path=%t -fmodule-name=lookup_right_cxx %S/Inputs/module.map -verify
-// RUN: %clang_cc1 -fmodules -x objective-c++ -fmodules-cache-path=%t %s -verify
-// RUN: %clang_cc1 -fmodules -ast-print -x objective-c++ -fmodules-cache-path=%t %s | FileCheck -check-prefix=CHECK-PRINT %s
+// RUN: %clang_cc1 -fmodules -x objective-c++ -fmodules-cache-path=%t -I %S/Inputs %s -verify
+// RUN: %clang_cc1 -fmodules -ast-print -x objective-c++ -fmodules-cache-path=%t -I %S/Inputs %s | FileCheck -check-prefix=CHECK-PRINT %s
 // FIXME: When we have a syntax for modules in C++, use that.
 
 // CHECK-PRINT: int *f0(int *);
diff --git a/test/Modules/lookup.m b/test/Modules/lookup.m
index 54c7491..187e876 100644
--- a/test/Modules/lookup.m
+++ b/test/Modules/lookup.m
@@ -1,8 +1,8 @@
 // RUN: rm -rf %t
 // RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -emit-module -x objective-c -fmodule-name=lookup_left_objc %S/Inputs/module.map
 // RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -emit-module -x objective-c -fmodule-name=lookup_right_objc %S/Inputs/module.map
-// RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -verify %s
-// RUN: %clang_cc1 -fmodules -ast-print -x objective-c -fmodules-cache-path=%t %s | FileCheck -check-prefix=CHECK-PRINT %s
+// RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -I %S/Inputs -verify %s
+// RUN: %clang_cc1 -fmodules -ast-print -x objective-c -fmodules-cache-path=%t -I %S/Inputs %s | FileCheck -check-prefix=CHECK-PRINT %s
 
 @import lookup_left_objc;
 @import lookup_right_objc;
diff --git a/test/Modules/macro-hiding.cpp b/test/Modules/macro-hiding.cpp
new file mode 100644
index 0000000..b166f4b
--- /dev/null
+++ b/test/Modules/macro-hiding.cpp
@@ -0,0 +1,104 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DD1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DC1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DC1 -DD1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DB2
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DB2 -DD1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DB2 -DC1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DB2 -DC1 -DD1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DB1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DB1 -DD1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DB1 -DC1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DB1 -DC1 -DD1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DB1 -DB2
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DB1 -DB2 -DD1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DB1 -DB2 -DC1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DB1 -DB2 -DC1 -DD1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA2
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA2 -DD1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA2 -DC1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA2 -DC1 -DD1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA2 -DB2
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA2 -DB2 -DD1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA2 -DB2 -DC1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA2 -DB2 -DC1 -DD1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA2 -DB1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA2 -DB1 -DD1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA2 -DB1 -DC1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA2 -DB1 -DC1 -DD1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA2 -DB1 -DB2
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA2 -DB1 -DB2 -DD1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA2 -DB1 -DB2 -DC1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA2 -DB1 -DB2 -DC1 -DD1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA1 -DD1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA1 -DC1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA1 -DC1 -DD1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA1 -DB2
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA1 -DB2 -DD1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA1 -DB2 -DC1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA1 -DB2 -DC1 -DD1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA1 -DB1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA1 -DB1 -DD1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA1 -DB1 -DC1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA1 -DB1 -DC1 -DD1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA1 -DB1 -DB2
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA1 -DB1 -DB2 -DD1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA1 -DB1 -DB2 -DC1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA1 -DB1 -DB2 -DC1 -DD1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA1 -DA2
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA1 -DA2 -DD1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA1 -DA2 -DC1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA1 -DA2 -DC1 -DD1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA1 -DA2 -DB2
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA1 -DA2 -DB2 -DD1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA1 -DA2 -DB2 -DC1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA1 -DA2 -DB2 -DC1 -DD1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA1 -DA2 -DB1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA1 -DA2 -DB1 -DD1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA1 -DA2 -DB1 -DC1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA1 -DA2 -DB1 -DC1 -DD1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA1 -DA2 -DB1 -DB2
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA1 -DA2 -DB1 -DB2 -DD1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA1 -DA2 -DB1 -DB2 -DC1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DA1 -DA2 -DB1 -DB2 -DC1 -DD1
+//
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/macro-hiding %s -DE1
+
+#ifdef A1
+#include "a1.h"
+#endif
+
+#ifdef A2
+#include "a2.h"
+#endif
+
+#ifdef B1
+#include "b1.h"
+#endif
+
+#ifdef B2
+#include "b2.h"
+#endif
+
+#ifdef C1
+#include "c1.h"
+#endif
+
+#ifdef D1
+#include "d1.h"
+#endif
+
+#ifdef E1
+#include "e1.h"
+#endif
+
+#ifdef E2
+#include "e2.h"
+#endif
+
+#if defined(A1) || defined(B2) || defined(C1) || defined(D1) || defined(E1) || defined(E2)
+void h() { assert(true); }
+#else
+void assert() {}
+#endif
diff --git a/test/Modules/macro-reexport/a1.h b/test/Modules/macro-reexport/a1.h
new file mode 100644
index 0000000..3993331
--- /dev/null
+++ b/test/Modules/macro-reexport/a1.h
@@ -0,0 +1 @@
+#define assert(x) a
diff --git a/include/clang/Driver/CC1Options.h b/test/Modules/macro-reexport/a2.h
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Modules/macro-reexport/a2.h
diff --git a/include/clang/Driver/CC1Options.h b/test/Modules/macro-reexport/b1.h
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/Modules/macro-reexport/b1.h
diff --git a/test/Modules/macro-reexport/b2.h b/test/Modules/macro-reexport/b2.h
new file mode 100644
index 0000000..2615045
--- /dev/null
+++ b/test/Modules/macro-reexport/b2.h
@@ -0,0 +1,2 @@
+#include "a2.h"
+#define assert(x) b
diff --git a/test/Modules/macro-reexport/c1.h b/test/Modules/macro-reexport/c1.h
new file mode 100644
index 0000000..d6a20e7
--- /dev/null
+++ b/test/Modules/macro-reexport/c1.h
@@ -0,0 +1,2 @@
+#include "b1.h"
+#define assert(x) c
diff --git a/test/Modules/macro-reexport/d1.h b/test/Modules/macro-reexport/d1.h
new file mode 100644
index 0000000..fbd68d5
--- /dev/null
+++ b/test/Modules/macro-reexport/d1.h
@@ -0,0 +1,2 @@
+#include "c1.h"
+#define assert(x) d
diff --git a/test/Modules/macro-reexport/d2.h b/test/Modules/macro-reexport/d2.h
new file mode 100644
index 0000000..688f2d9
--- /dev/null
+++ b/test/Modules/macro-reexport/d2.h
@@ -0,0 +1 @@
+#include "b2.h"
diff --git a/test/Modules/macro-reexport/macro-reexport.cpp b/test/Modules/macro-reexport/macro-reexport.cpp
new file mode 100644
index 0000000..47b15c2
--- /dev/null
+++ b/test/Modules/macro-reexport/macro-reexport.cpp
@@ -0,0 +1,13 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fsyntax-only -DD2 -I. %s -fmodules-cache-path=%t -verify
+// RUN: %clang_cc1 -fsyntax-only -DD2 -I. -fmodules %s -fmodules-cache-path=%t -verify
+// RUN: %clang_cc1 -fsyntax-only -DC1 -I. %s -fmodules-cache-path=%t -verify
+// RUN: %clang_cc1 -fsyntax-only -DC1 -I. -fmodules %s -fmodules-cache-path=%t -verify
+
+#ifdef D2
+#include "d2.h"
+void f() { return assert(true); } // expected-error {{undeclared identifier 'b'}}
+#else
+#include "c1.h"
+void f() { return assert(true); } // expected-error {{undeclared identifier 'c'}}
+#endif
diff --git a/test/Modules/macro-reexport/module.modulemap b/test/Modules/macro-reexport/module.modulemap
new file mode 100644
index 0000000..21585b6
--- /dev/null
+++ b/test/Modules/macro-reexport/module.modulemap
@@ -0,0 +1,15 @@
+module b {
+  module b2 { header "b2.h" export * }
+  module b1 { header "b1.h" export * }
+}
+module a {
+  module a1 { header "a1.h" export * }
+  module a2 { header "a2.h" export * }
+}
+module c {
+  module c1 { header "c1.h" export * }
+}
+module d {
+  module d1 { header "d1.h" export * }
+  module d2 { header "d2.h" export * }
+}
diff --git a/test/Modules/macro-undef-through-pch.m b/test/Modules/macro-undef-through-pch.m
new file mode 100644
index 0000000..0e5e99f
--- /dev/null
+++ b/test/Modules/macro-undef-through-pch.m
@@ -0,0 +1,10 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -x objective-c-header -fmodules -fmodules-cache-path=%t \
+// RUN:            -I%S/Inputs/macro-undef-through-pch -emit-pch \
+// RUN:            %S/Inputs/macro-undef-through-pch/foo.h -o %t.pch
+// RUN: %clang_cc1 -x objective-c -fmodules -fmodules-cache-path=%t \
+// RUN:            -I%S/Inputs/macro-undef-through-pch -emit-pch \
+// RUN:            -include-pch %t.pch %s
+
+// PR19215
+#undef AB
diff --git a/test/Modules/macros.c b/test/Modules/macros.c
index 541c95b..7a7e570 100644
--- a/test/Modules/macros.c
+++ b/test/Modules/macros.c
@@ -3,18 +3,16 @@
 // RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=macros_left %S/Inputs/module.map
 // RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=macros_right %S/Inputs/module.map
 // RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=macros %S/Inputs/module.map
-// RUN: %clang_cc1 -fmodules -x objective-c -verify -fmodules-cache-path=%t %s
-// RUN: not %clang_cc1 -E -fmodules -x objective-c -fmodules-cache-path=%t %s | FileCheck -check-prefix CHECK-PREPROCESSED %s
+// RUN: %clang_cc1 -fmodules -x objective-c -verify -fmodules-cache-path=%t -I %S/Inputs %s
+// RUN: not %clang_cc1 -E -fmodules -x objective-c -fmodules-cache-path=%t -I %S/Inputs %s | FileCheck -check-prefix CHECK-PREPROCESSED %s
 // FIXME: When we have a syntax for modules in C, use that.
 // These notes come from headers in modules, and are bogus.
 
 // FIXME: expected-note@Inputs/macros_left.h:11{{previous definition is here}}
 // FIXME: expected-note@Inputs/macros_right.h:12{{previous definition is here}}
 // expected-note@Inputs/macros_right.h:12{{expanding this definition of 'LEFT_RIGHT_DIFFERENT'}}
-// expected-note@Inputs/macros_top.h:13{{other definition of 'TOP_RIGHT_REDEF'}}
 // expected-note@Inputs/macros_right.h:13{{expanding this definition of 'LEFT_RIGHT_DIFFERENT2'}}
 // expected-note@Inputs/macros_left.h:14{{other definition of 'LEFT_RIGHT_DIFFERENT'}}
-// expected-note@Inputs/macros_right.h:17{{expanding this definition of 'TOP_RIGHT_REDEF'}}
 
 @import macros;
 
@@ -79,8 +77,8 @@
 #  error TOP should be visible
 #endif
 
-#ifndef TOP_LEFT_UNDEF
-#  error TOP_LEFT_UNDEF should still be defined
+#ifdef TOP_LEFT_UNDEF
+#  error TOP_LEFT_UNDEF should not be defined
 #endif
 
 void test1() {
@@ -112,7 +110,7 @@
   int i;
   float f;
   double d;
-  TOP_RIGHT_REDEF *fp = &f; // expected-warning{{ambiguous expansion of macro 'TOP_RIGHT_REDEF'}}
+  TOP_RIGHT_REDEF *fp = &f; // ok, right's definition overrides top's definition
   
   LEFT_RIGHT_IDENTICAL *ip = &i;
   LEFT_RIGHT_DIFFERENT *ip2 = &i; // expected-warning{{ambiguous expansion of macro 'LEFT_RIGHT_DIFFERENT'}}
@@ -134,6 +132,33 @@
 
 @import macros_right.undef;
 
-#ifndef TOP_RIGHT_UNDEF
-# error TOP_RIGHT_UNDEF should still be defined
+// FIXME: When macros_right.undef is built, macros_top is visible because
+// the state from building macros_right leaks through, so macros_right.undef
+// undefines macros_top's macro.
+#ifdef TOP_RIGHT_UNDEF
+# error TOP_RIGHT_UNDEF should not be defined
 #endif
+
+@import macros_other;
+
+#ifndef TOP_OTHER_UNDEF1
+# error TOP_OTHER_UNDEF1 should still be defined
+#endif
+
+#ifndef TOP_OTHER_UNDEF2
+# error TOP_OTHER_UNDEF2 should still be defined
+#endif
+
+#ifndef TOP_OTHER_REDEF1
+# error TOP_OTHER_REDEF1 should still be defined
+#endif
+int n1 = TOP_OTHER_REDEF1; // expected-warning{{ambiguous expansion of macro 'TOP_OTHER_REDEF1'}}
+// expected-note@macros_top.h:19 {{expanding this definition}}
+// expected-note@macros_other.h:4 {{other definition}}
+
+#ifndef TOP_OTHER_REDEF2
+# error TOP_OTHER_REDEF2 should still be defined
+#endif
+int n2 = TOP_OTHER_REDEF2; // ok
+
+int n3 = TOP_OTHER_DEF_RIGHT_UNDEF; // ok
diff --git a/test/Modules/macros2.c b/test/Modules/macros2.c
new file mode 100644
index 0000000..c4c8059
--- /dev/null
+++ b/test/Modules/macros2.c
@@ -0,0 +1,83 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=macros_top %S/Inputs/module.map
+// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=macros_left %S/Inputs/module.map
+// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=macros_right %S/Inputs/module.map
+// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=macros %S/Inputs/module.map
+// RUN: %clang_cc1 -fmodules -x objective-c -verify -fmodules-cache-path=%t -I %S/Inputs %s
+
+// This test checks some of the same things as macros.c, but imports modules in
+// a different order.
+
+@import macros_other;
+
+int n0 = TOP_OTHER_DEF_RIGHT_UNDEF; // ok
+
+@import macros_top;
+
+TOP_OTHER_DEF_RIGHT_UNDEF *n0b; // expected-warning{{ambiguous expansion of macro 'TOP_OTHER_DEF_RIGHT_UNDEF'}}
+// expected-note@macros_top.h:22 {{expanding this definition of 'TOP_OTHER_DEF_RIGHT_UNDEF'}}
+// expected-note@macros_other.h:6 {{other definition of 'TOP_OTHER_DEF_RIGHT_UNDEF'}}
+
+@import macros_right;
+@import macros_left;
+
+#ifdef TOP_LEFT_UNDEF
+#  error TOP_LEFT_UNDEF should not be defined
+#endif
+
+#ifndef TOP_RIGHT_UNDEF
+#  error TOP_RIGHT_UNDEF should still be defined
+#endif
+
+void test() {
+  float f;
+  TOP_RIGHT_REDEF *fp = &f; // ok, right's definition overrides top's definition
+
+  // Note, left's definition wins here, whereas right's definition wins in
+  // macros.c.
+  int i;
+  LEFT_RIGHT_IDENTICAL *ip = &i;
+  LEFT_RIGHT_DIFFERENT *ip2 = &f; // expected-warning{{ambiguous expansion of macro 'LEFT_RIGHT_DIFFERENT'}}
+  // expected-note@macros_left.h:14 {{expanding this}}
+  // expected-note@macros_right.h:12 {{other}}
+  LEFT_RIGHT_DIFFERENT2 *ip3 = &f; // expected-warning{{ambiguous expansion of macro 'LEFT_RIGHT_DIFFERENT2}}
+  // expected-note@macros_left.h:11 {{expanding this}}
+  // expected-note@macros_right.h:13 {{other}}
+#undef LEFT_RIGHT_DIFFERENT3
+  int LEFT_RIGHT_DIFFERENT3;
+}
+
+@import macros_right.undef;
+
+// FIXME: See macros.c.
+#ifdef TOP_RIGHT_UNDEF
+# error TOP_RIGHT_UNDEF should not be defined
+#endif
+
+#ifndef TOP_OTHER_UNDEF1
+# error TOP_OTHER_UNDEF1 should still be defined
+#endif
+
+#ifndef TOP_OTHER_UNDEF2
+# error TOP_OTHER_UNDEF2 should still be defined
+#endif
+
+#ifndef TOP_OTHER_REDEF1
+# error TOP_OTHER_REDEF1 should still be defined
+#endif
+int n1 = TOP_OTHER_REDEF1; // expected-warning{{ambiguous expansion of macro 'TOP_OTHER_REDEF1'}}
+// expected-note@macros_top.h:19 {{expanding this definition}}
+// expected-note@macros_other.h:4 {{other definition}}
+
+#ifndef TOP_OTHER_REDEF2
+# error TOP_OTHER_REDEF2 should still be defined
+#endif
+int n2 = TOP_OTHER_REDEF2; // ok
+
+int n3 = TOP_OTHER_DEF_RIGHT_UNDEF; // ok
+
+int top_redef_in_submodules = TOP_REDEF_IN_SUBMODULES;
+@import macros_top.c;
+void test2() {
+  int TOP_REDEF_IN_SUBMODULES = top_redef_in_submodules;
+}
diff --git a/test/Modules/malformed.cpp b/test/Modules/malformed.cpp
new file mode 100644
index 0000000..cd7b334
--- /dev/null
+++ b/test/Modules/malformed.cpp
@@ -0,0 +1,23 @@
+// RUN: rm -rf %t
+// RUN: not %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs/malformed -DHEADER="a1.h" %s 2>&1 | FileCheck %s --check-prefix=CHECK-A
+// RUN: not %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs/malformed -DHEADER="b1.h" %s 2>&1 | FileCheck %s --check-prefix=CHECK-B
+
+#define STR2(x) #x
+#define STR(x) STR2(x)
+#include STR(HEADER)
+
+// CHECK-A: While building module 'malformed_a'
+// CHECK-A: a1.h:1:{{.*}} error: expected '}'
+// CHECK-A: a1.h:1:{{.*}} note: to match this '{'
+//
+// CHECK-A: While building module 'malformed_a'
+// CHECK-A: a2.h:1:{{.*}} error: extraneous closing brace
+
+// CHECK-B: While building module 'malformed_b'
+// CHECK-B: b1.h:2:{{.*}} error: expected '}'
+// CHECK-B: b1.h:1:{{.*}} note: to match this '{'
+// CHECK-B: b1.h:3:{{.*}} error: extraneous closing brace ('}')
+//
+// CHECK-B: While building module 'malformed_b'
+// CHECK-B: b2.h:1:{{.*}} error: redefinition of 'g'
+// CHECK-B: b2.h:1:{{.*}} note: previous definition is here
diff --git a/test/Modules/missing-header.m b/test/Modules/missing-header.m
new file mode 100644
index 0000000..c2c1673
--- /dev/null
+++ b/test/Modules/missing-header.m
@@ -0,0 +1,13 @@
+// RUN: rm -rf %t
+// RUN: not %clang_cc1 -x objective-c -fmodules-cache-path=%t -fmodules -I %S/Inputs/submodules %s 2>&1 | FileCheck %s
+
+// FIXME: cannot use -verify, because the error from inside the module build has
+// a different source manager than the verifier.
+
+@import missing_unavailable_headers; // OK
+@import missing_unavailable_headers.not_missing; // OK
+// CHECK-NOT: missing_unavailable_headers
+
+@import missing_headers;
+// CHECK: module.map:15:27: error: header 'missing.h' not found
+// CHECK: could not build module 'missing_headers'
diff --git a/test/Modules/missing-submodule.m b/test/Modules/missing-submodule.m
new file mode 100644
index 0000000..4f3553c
--- /dev/null
+++ b/test/Modules/missing-submodule.m
@@ -0,0 +1,7 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -F %S/Inputs %s -verify
+#include <Module/NotInModule.h> // expected-warning{{missing submodule 'Module.NotInModule'}}
+
+int getNotInModule() {
+  return not_in_module;
+}
diff --git a/test/Modules/module-private.cpp b/test/Modules/module-private.cpp
index 438dcab..9213a0f 100644
--- a/test/Modules/module-private.cpp
+++ b/test/Modules/module-private.cpp
@@ -1,7 +1,7 @@
 // RUN: rm -rf %t
 // RUN: %clang_cc1 -fmodules -x objective-c++ -fmodules-cache-path=%t -fmodule-name=module_private_left -emit-module %S/Inputs/module.map
 // RUN: %clang_cc1 -fmodules -x objective-c++ -fmodules-cache-path=%t -fmodule-name=module_private_right -emit-module %S/Inputs/module.map
-// RUN: %clang_cc1 -fmodules -x objective-c++ -fmodules-cache-path=%t %s -verify
+// RUN: %clang_cc1 -fmodules -x objective-c++ -fmodules-cache-path=%t -I %S/Inputs %s -verify
 // FIXME: When we have a syntax for modules in C++, use that.
 
 @import module_private_left;
diff --git a/test/Modules/module_file_info.m b/test/Modules/module_file_info.m
index 09319d6..2447a74 100644
--- a/test/Modules/module_file_info.m
+++ b/test/Modules/module_file_info.m
@@ -2,11 +2,14 @@
 @import DependsOnModule;
 
 // RUN: rm -rf %t
-// RUN: %clang_cc1 -w -fmodules -fdisable-module-hash -fmodules-cache-path=%t -F %S/Inputs -DBLARG -DWIBBLE=WOBBLE %s
+// RUN: %clang_cc1 -w -Wunused -fmodules -fdisable-module-hash -fmodules-cache-path=%t -F %S/Inputs -DBLARG -DWIBBLE=WOBBLE %s
 // RUN: %clang_cc1 -module-file-info %t/DependsOnModule.pcm | FileCheck %s
 
 // CHECK: Generated by this Clang:
 
+// CHECK: Module name: DependsOnModule
+// CHECK: Module map file: {{.*}}DependsOnModule.framework{{[/\\]}}module.map
+
 // CHECK: Language options:
 // CHECK:   C99: Yes
 // CHECK:   Objective-C 1: Yes
@@ -16,8 +19,11 @@
 // CHECK:     Triple:
 // CHECK:     CPU: 
 // CHECK:     ABI: 
-// CHECK:     C++ ABI: 
-// CHECK:     Linker version: 
+
+// CHECK: Diagnostic options:
+// CHECK:   IgnoreWarnings: Yes
+// CHECK:   Diagnostic flags:
+// CHECK:     -Wunused
 
 // CHECK: Header search options:
 // CHECK:   System root [-isysroot=]: '/'
diff --git a/test/Modules/modulemap-locations.m b/test/Modules/modulemap-locations.m
new file mode 100644
index 0000000..9acdcd6
--- /dev/null
+++ b/test/Modules/modulemap-locations.m
@@ -0,0 +1,18 @@
+// RUN: rm -rf %t 
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs/ModuleMapLocations/Module_ModuleMap -I %S/Inputs/ModuleMapLocations/Both -F %S/Inputs/ModuleMapLocations -x objective-c -fsyntax-only %s -verify
+
+// regular
+@import module_modulemap;
+@import both;
+// framework
+@import Module_ModuleMap_F;
+@import Module_ModuleMap_F.Private;
+@import Both_F;
+@import Inferred;
+
+void test() {
+  will_be_found1();
+  wont_be_found1(); // expected-warning{{implicit declaration of function 'wont_be_found1' is invalid in C99}}
+  will_be_found2();
+  wont_be_found2(); // expected-warning{{implicit declaration of function 'wont_be_found2' is invalid in C99}}
+}
diff --git a/test/Modules/modules-with-same-name.m b/test/Modules/modules-with-same-name.m
new file mode 100644
index 0000000..c90aa5d
--- /dev/null
+++ b/test/Modules/modules-with-same-name.m
@@ -0,0 +1,35 @@
+// REQUIRES: shell
+// RUN: rm -rf %t
+
+// A from path 1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fmodules-ignore-macro=EXPECTED_PATH -fmodules-ignore-macro=DIRECT -fsyntax-only %s -verify -I %S/Inputs/modules-with-same-name/path1/A -DDIRECT -DEXPECTED_PATH=1
+
+// A from path 2
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fmodules-ignore-macro=EXPECTED_PATH -fmodules-ignore-macro=DIRECT -fsyntax-only %s -verify -I %S/Inputs/modules-with-same-name/path2/A -DDIRECT -DEXPECTED_PATH=2
+
+// Confirm that we have two pcm files (one for each 'A').
+// RUN: find %t -name "A-*.pcm" | count 2
+
+// DependsOnA, using A from path 1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fmodules-ignore-macro=EXPECTED_PATH -fmodules-ignore-macro=DIRECT -fsyntax-only %s -verify -I %S/Inputs/modules-with-same-name/DependsOnA -I %S/Inputs/modules-with-same-name/path1/A -DEXPECTED_PATH=1
+
+// Confirm that we have three pcm files (one for each 'A', and one for 'DependsOnA')
+// RUN: find %t -name "*.pcm" | count 3
+
+// DependsOnA, using A from path 2
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fmodules-ignore-macro=EXPECTED_PATH -fmodules-ignore-macro=DIRECT -fsyntax-only %s -verify -I %S/Inputs/modules-with-same-name/DependsOnA -I %S/Inputs/modules-with-same-name/path2/A -DEXPECTED_PATH=2
+
+// Confirm that we still have three pcm files, since DependsOnA will be rebuilt
+// RUN: find %t -name "*.pcm" | count 3
+
+#ifdef DIRECT
+@import A;
+#else
+@import DependsOnA;
+#endif
+
+#if FROM_PATH != EXPECTED_PATH
+#error "Got the wrong module!"
+#endif
+
+// expected-no-diagnostics
diff --git a/test/Modules/namespaces.cpp b/test/Modules/namespaces.cpp
index 8c225e0..a6f4c25 100644
--- a/test/Modules/namespaces.cpp
+++ b/test/Modules/namespaces.cpp
@@ -36,6 +36,9 @@
   double &dr3 = global(1.0);
   double &dr4 = ::global2(1.0);
   double &dr5 = LookupBeforeImport::f(1.0);
+
+  struct AddAndReexportBeforeImport::S s;
+  int k = AddAndReexportBeforeImport::S;
 }
 
 // Test namespaces merged without a common first declaration.
@@ -69,8 +72,8 @@
 // Test merging when using anonymous namespaces, which does not
 // actually perform any merging.
 void testAnonymousNotMerged() {
-  N11::consumeFoo(N11::getFoo()); // expected-error{{cannot initialize a parameter of type 'N11::<anonymous>::Foo *' with an rvalue of type 'N11::<anonymous>::Foo *'}}
-  N12::consumeFoo(N12::getFoo()); // expected-error{{cannot initialize a parameter of type 'N12::<anonymous>::Foo *' with an rvalue of type 'N12::<anonymous>::Foo *'}}  
+  N11::consumeFoo(N11::getFoo()); // expected-error{{cannot initialize a parameter of type 'N11::(anonymous namespace)::Foo *' with an rvalue of type 'N11::(anonymous namespace)::Foo *'}}
+  N12::consumeFoo(N12::getFoo()); // expected-error{{cannot initialize a parameter of type 'N12::(anonymous namespace)::Foo *' with an rvalue of type 'N12::(anonymous namespace)::Foo *'}}
 }
 
 // expected-note@Inputs/namespaces-right.h:60 {{passing argument to parameter here}}
diff --git a/test/Modules/no-stale-modtime.m b/test/Modules/no-stale-modtime.m
new file mode 100644
index 0000000..1bff2b0
--- /dev/null
+++ b/test/Modules/no-stale-modtime.m
@@ -0,0 +1,37 @@
+// Ensure that when rebuilding a module we don't save its old modtime when
+// building modules that depend on it.
+
+// REQUIRES: shell
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// This could be replaced by diamond_*, except we want to modify the top header
+// RUN: echo '@import l; @import r;' > %t/b.h
+// RUN: echo '@import t; // fromt l' > %t/l.h
+// RUN: echo '@import t; // fromt r' > %t/r.h
+// RUN: echo '// top' > %t/t.h
+// RUN: echo 'module b { header "b.h" } module l { header "l.h" }' > %t/module.map
+// RUN: echo 'module r { header "r.h" } module t { header "t.h" }' >> %t/module.map
+
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fdisable-module-hash \
+// RUN:     -I %t -fsyntax-only %s -Rmodule-build 2>&1 \
+// RUN: | FileCheck -check-prefix=REBUILD-ALL %s
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fdisable-module-hash \
+// RUN:     -I %t -fsyntax-only %s -Rmodule-build -verify
+
+// Add an identifier to ensure everything depending on t is out of date
+// RUN: echo 'extern int a;' >> %t/t.h
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fdisable-module-hash \
+// RUN:     -I %t -fsyntax-only %s -Rmodule-build 2>&1 \
+// RUN: | FileCheck -check-prefix=REBUILD-ALL %s
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fdisable-module-hash \
+// RUN:     -I %t -fsyntax-only %s -Rmodule-build -verify
+
+// REBUILD-ALL: building module 'b'
+// REBUILD-ALL: building module 'l'
+// REBUILD-ALL: building module 't'
+// REBUILD-ALL: building module 'r'
+
+// Use -verify when expecting no modules to be rebuilt.
+// expected-no-diagnostics
+
+@import b;
diff --git a/test/Modules/objc-categories.m b/test/Modules/objc-categories.m
index f08b13a..a66ab8d 100644
--- a/test/Modules/objc-categories.m
+++ b/test/Modules/objc-categories.m
@@ -4,7 +4,7 @@
 // RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -x objective-c -fmodule-name=category_right -emit-module %S/Inputs/module.map
 // RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -x objective-c -fmodule-name=category_bottom -emit-module %S/Inputs/module.map
 // RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -x objective-c -fmodule-name=category_other -emit-module %S/Inputs/module.map
-// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t %s -verify
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs %s -verify
 
 @import category_bottom;
 
diff --git a/test/Modules/objc_redef.m b/test/Modules/objc_redef.m
index f911241..28e4766 100644
--- a/test/Modules/objc_redef.m
+++ b/test/Modules/objc_redef.m
@@ -8,6 +8,6 @@
 // RUN: rm -rf %t
 // RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -emit-module -fmodule-name=redeclarations_left %S/Inputs/module.map
 // RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -emit-module -fmodule-name=weird_objc %S/Inputs/module.map
-// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t %s -verify
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs %s -verify
 // expected-no-diagnostics
 
diff --git a/test/Modules/prune.m b/test/Modules/prune.m
index 8af7e6c..7bc771f 100644
--- a/test/Modules/prune.m
+++ b/test/Modules/prune.m
@@ -14,33 +14,33 @@
 // RUN: %clang_cc1 -DIMPORT_DEPENDS_ON_MODULE -fmodules-ignore-macro=DIMPORT_DEPENDS_ON_MODULE -fmodules -F %S/Inputs -fmodules-cache-path=%t %s -verify
 // RUN: %clang_cc1 -DIMPORT_DEPENDS_ON_MODULE -fmodules-ignore-macro=DIMPORT_DEPENDS_ON_MODULE -fmodules -F %S/Inputs -fmodules-cache-path=%t %s -verify
 // RUN: ls %t | grep modules.timestamp
-// RUN: ls -R %t | grep ^Module.pcm
-// RUN: ls -R %t | grep DependsOnModule.pcm
+// RUN: ls -R %t | grep ^Module.*pcm
+// RUN: ls -R %t | grep DependsOnModule.*pcm
 
 // Set the timestamp back more than two days. We should try to prune,
 // but nothing gets pruned because the module files are new enough.
 // RUN: touch -m -a -t 201101010000 %t/modules.timestamp 
 // RUN: %clang_cc1 -fmodules -F %S/Inputs -fmodules-cache-path=%t -fmodules -fmodules-prune-interval=172800 -fmodules-prune-after=345600 %s -verify
 // RUN: ls %t | grep modules.timestamp
-// RUN: ls -R %t | grep ^Module.pcm
-// RUN: ls -R %t | grep DependsOnModule.pcm
+// RUN: ls -R %t | grep ^Module.*pcm
+// RUN: ls -R %t | grep DependsOnModule.*pcm
 
 // Set the DependsOnModule access time back more than four days.
 // This shouldn't prune anything, because the timestamp has been updated, so
 // the pruning mechanism won't fire.
-// RUN: find %t -name DependsOnModule.pcm | xargs touch -a -t 201101010000
+// RUN: find %t -name DependsOnModule*.pcm | xargs touch -a -t 201101010000
 // RUN: %clang_cc1 -fmodules -F %S/Inputs -fmodules-cache-path=%t -fmodules -fmodules-prune-interval=172800 -fmodules-prune-after=345600 %s -verify
 // RUN: ls %t | grep modules.timestamp
-// RUN: ls -R %t | grep ^Module.pcm
-// RUN: ls -R %t | grep DependsOnModule.pcm
+// RUN: ls -R %t | grep ^Module.*pcm
+// RUN: ls -R %t | grep DependsOnModule.*pcm
 
 // Set both timestamp and DependsOnModule.pcm back beyond the cutoff.
 // This should trigger pruning, which will remove DependsOnModule but not Module.
 // RUN: touch -m -a -t 201101010000 %t/modules.timestamp 
-// RUN: find %t -name DependsOnModule.pcm | xargs touch -a -t 201101010000
+// RUN: find %t -name DependsOnModule*.pcm | xargs touch -a -t 201101010000
 // RUN: %clang_cc1 -fmodules -F %S/Inputs -fmodules-cache-path=%t -fmodules -fmodules-prune-interval=172800 -fmodules-prune-after=345600 %s -verify
 // RUN: ls %t | grep modules.timestamp
-// RUN: ls -R %t | grep ^Module.pcm
-// RUN: ls -R %t | not grep DependsOnModule.pcm
+// RUN: ls -R %t | grep ^Module.*pcm
+// RUN: ls -R %t | not grep DependsOnModule.*pcm
 
 // expected-no-diagnostics
diff --git a/test/Modules/recursive.c b/test/Modules/recursive.c
new file mode 100644
index 0000000..5315b10
--- /dev/null
+++ b/test/Modules/recursive.c
@@ -0,0 +1,11 @@
+// RUN: rm -rf %t
+// RUN: not %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -I %S/Inputs %s 2>&1 | FileCheck %s
+#include "recursive1.h"
+
+// RUN: rm -rf %t
+// RUN: not %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -emit-module -fmodule-name=recursive1 %S/Inputs/module.map 2>&1 | FileCheck %s
+
+// CHECK:      While building module 'recursive1'{{( imported from .*[/\]recursive.c:3)?}}:
+// CHECK-NEXT: While building module 'recursive2' imported from {{.*Inputs[/\]}}recursive1.h:1:
+// CHECK-NEXT: In file included from <module-includes>:1:
+// CHECK-NEXT: recursive2.h:1:10: fatal error: cyclic dependency in module 'recursive1': recursive1 -> recursive2 -> recursive1
diff --git a/test/Modules/redecl-add-after-load.cpp b/test/Modules/redecl-add-after-load.cpp
new file mode 100644
index 0000000..68deaf8
--- /dev/null
+++ b/test/Modules/redecl-add-after-load.cpp
@@ -0,0 +1,59 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -x objective-c++ -fmodules -fno-modules-error-recovery -fmodules-cache-path=%t -I %S/Inputs %s -verify -std=c++11
+// RUN: %clang_cc1 -x objective-c++ -fmodules -fno-modules-error-recovery -fmodules-cache-path=%t -I %S/Inputs %s -verify -std=c++11 -DIMPORT_DECLS
+
+#ifdef IMPORT_DECLS
+// expected-no-diagnostics
+@import redecl_add_after_load_decls;
+#else
+typedef struct A B;
+extern const int variable;
+extern constexpr int function();
+constexpr int test(bool b) { return b ? variable : function(); }
+
+namespace N {
+  typedef struct A B;
+  extern const int variable;
+  extern constexpr int function();
+}
+typedef N::B NB;
+constexpr int N_test(bool b) { return b ? N::variable : N::function(); }
+
+@import redecl_add_after_load_top;
+typedef C::A CB;
+constexpr int C_test(bool b) { return b ? C::variable : C::function(); }
+
+struct D {
+  struct A; // expected-note {{forward}}
+  static const int variable;
+  static constexpr int function(); // expected-note {{here}}
+};
+typedef D::A DB;
+constexpr int D_test(bool b) { return b ? D::variable : D::function(); } // expected-note {{subexpression}} expected-note {{undefined}}
+#endif
+
+@import redecl_add_after_load;
+
+B tu_struct_test;
+constexpr int tu_variable_test = test(true);
+constexpr int tu_function_test = test(false);
+
+NB ns_struct_test;
+constexpr int ns_variable_test = N_test(true);
+constexpr int ns_function_test = N_test(false);
+
+CB struct_struct_test;
+constexpr int struct_variable_test = C_test(true);
+constexpr int struct_function_test = C_test(false);
+
+// FIXME: We should accept this, but we're currently too lazy when merging class
+// definitions to determine that the definitions in redecl_add_after_load are
+// definitions of these entities.
+DB merged_struct_struct_test;
+constexpr int merged_struct_variable_test = D_test(true);
+constexpr int merged_struct_function_test = D_test(false);
+#ifndef IMPORT_DECLS
+// expected-error@-4 {{incomplete}}
+// expected-error@-4 {{constant}} expected-note@-4 {{in call to}}
+// expected-error@-4 {{constant}} expected-note@-4 {{in call to}}
+#endif
diff --git a/test/Modules/redecl-namespaces.mm b/test/Modules/redecl-namespaces.mm
index 93102c0..203daa9 100644
--- a/test/Modules/redecl-namespaces.mm
+++ b/test/Modules/redecl-namespaces.mm
@@ -10,4 +10,4 @@
 // RUN: rm -rf %t
 // RUN: %clang_cc1 -fmodules -x objective-c++ -fmodules-cache-path=%t -emit-module -fmodule-name=redecl_namespaces_left %S/Inputs/module.map
 // RUN: %clang_cc1 -fmodules -x objective-c++ -fmodules-cache-path=%t -emit-module -fmodule-name=redecl_namespaces_right %S/Inputs/module.map
-// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -w %s -verify
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs -w %s -verify
diff --git a/test/Modules/redeclarations.m b/test/Modules/redeclarations.m
index f210f37..11aca75 100644
--- a/test/Modules/redeclarations.m
+++ b/test/Modules/redeclarations.m
@@ -7,6 +7,6 @@
 // RUN: rm -rf %t
 // RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -emit-module -fmodule-name=redeclarations_left %S/Inputs/module.map
 // RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -emit-module -fmodule-name=redeclarations_right %S/Inputs/module.map
-// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t %s -verify
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs %s -verify
 // expected-no-diagnostics
 
diff --git a/test/Modules/redecls/main.m b/test/Modules/redecls/main.m
index 9ec02b0..bf3788a 100644
--- a/test/Modules/redecls/main.m
+++ b/test/Modules/redecls/main.m
@@ -1,9 +1,9 @@
 // RUN: rm -rf %t.mcp
 // RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodule-name=a %S/module.map -fmodules-cache-path=%t.mcp
 // RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodule-name=b %S/module.map -fmodules-cache-path=%t.mcp
-// RUN: %clang_cc1 -fmodules %s -emit-pch -o %t1.pch -fmodules-cache-path=%t.mcp
-// RUN: %clang_cc1 -fmodules %s -emit-pch -o %t2.pch -include-pch %t1.pch -fmodules-cache-path=%t.mcp
-// RUN: %clang_cc1 -fmodules %s -fsyntax-only -include-pch %t2.pch -fmodules-cache-path=%t.mcp -verify
+// RUN: %clang_cc1 -fmodules %s -emit-pch -o %t1.pch -fmodules-cache-path=%t.mcp -I %S
+// RUN: %clang_cc1 -fmodules %s -emit-pch -o %t2.pch -include-pch %t1.pch -fmodules-cache-path=%t.mcp -I %S
+// RUN: %clang_cc1 -fmodules %s -fsyntax-only -include-pch %t2.pch -I %S -fmodules-cache-path=%t.mcp -verify
 
 #ifndef HEADER1
 #define HEADER1
diff --git a/test/Modules/renamed.m b/test/Modules/renamed.m
index 4e8f532..ec2616e 100644
--- a/test/Modules/renamed.m
+++ b/test/Modules/renamed.m
@@ -3,6 +3,6 @@
 int f() { return same_api; }
 
 // RUN: rm -rf %t
-// RUN: %clang_cc1 -fmodules -I %S/Inputs -fmodules-cache-path=%t %s -verify
+// RUN: %clang_cc1 -fmodules -I %S/Inputs/oldname -fmodules-cache-path=%t %s -verify
 
 // expected-no-diagnostics
diff --git a/test/Modules/require-modular-includes.m b/test/Modules/require-modular-includes.m
new file mode 100644
index 0000000..835a352
--- /dev/null
+++ b/test/Modules/require-modular-includes.m
@@ -0,0 +1,83 @@
+// RUN: rm -rf %t
+// REQUIRES: shell
+
+// Including a header from the imported module
+// RUN: echo '@import FromImportedModuleOK;' | \
+// RUN:   %clang_cc1 -Wnon-modular-include-in-framework-module -fmodules \
+// RUN:     -fmodules-cache-path=%t -F %S/Inputs/require-modular-includes \
+// RUN:     -Werror -fsyntax-only -x objective-c -
+
+// Including a non-modular header
+// RUN: echo '@import FromImportedModuleFail;' | \
+// RUN:   %clang_cc1 -Wnon-modular-include-in-framework-module -fmodules \
+// RUN:     -fmodules-cache-path=%t -F %S/Inputs/require-modular-includes \
+// RUN:     -I %S/Inputs/require-modular-includes \
+// RUN:     -fsyntax-only -x objective-c - 2>&1 | FileCheck %s
+
+// Including a header from a subframework
+// RUN: echo '@import FromSubframework;' | \
+// RUN:   %clang_cc1 -Wnon-modular-include-in-framework-module -fmodules \
+// RUN:     -fmodules-cache-path=%t -F %S/Inputs/require-modular-includes \
+// RUN:     -Werror -fsyntax-only -x objective-c -
+
+// Including a header from a subframework (fail)
+// RUN: echo '@import FromNonModularSubframework;' | \
+// RUN:   %clang_cc1 -Wnon-modular-include-in-framework-module -fmodules \
+// RUN:     -fmodules-cache-path=%t -F %S/Inputs/require-modular-includes \
+// RUN:     -I %S/Inputs/require-modular-includes \
+// RUN:     -fsyntax-only -x objective-c - 2>&1 | FileCheck %s
+
+// Including a non-modular header from a submodule
+// RUN: echo '@import FromImportedSubModule;' | \
+// RUN:   %clang_cc1 -Wnon-modular-include-in-framework-module -fmodules \
+// RUN:     -fmodules-cache-path=%t -F %S/Inputs/require-modular-includes \
+// RUN:     -I %S/Inputs/require-modular-includes \
+// RUN:     -fsyntax-only -x objective-c - 2>&1 | FileCheck %s
+
+// Including a non-modular header (directly) with -fmodule-name set
+// RUN: echo '#include "NotInModule.h"' | \
+// RUN:   %clang_cc1 -Wnon-modular-include-in-framework-module -fmodules \
+// RUN:     -fmodules-cache-path=%t -I %S/Inputs/require-modular-includes \
+// RUN:     -Werror -fmodule-name=A -fsyntax-only -x objective-c -
+
+// Including an excluded header
+// RUN: echo '@import IncludeExcluded;' | \
+// RUN:   %clang_cc1 -Wnon-modular-include-in-framework-module -fmodules \
+// RUN:     -fmodules-cache-path=%t -F %S/Inputs/require-modular-includes \
+// RUN:     -Werror -fsyntax-only -x objective-c -
+
+// Including a header from another module
+// RUN: echo '@import FromAnotherModule;' | \
+// RUN:   %clang_cc1 -Wnon-modular-include-in-framework-module -fmodules \
+// RUN:     -fmodules-cache-path=%t -F %S/Inputs/require-modular-includes \
+// RUN:     -I %S/Inputs/require-modular-includes \
+// RUN:     -Werror -fsyntax-only -x objective-c -
+
+// Including an excluded header from another module
+// RUN: echo '@import ExcludedFromAnotherModule;' | \
+// RUN:   %clang_cc1 -Wnon-modular-include-in-framework-module -fmodules \
+// RUN:     -fmodules-cache-path=%t -F %S/Inputs/require-modular-includes \
+// RUN:     -I %S/Inputs/require-modular-includes \
+// RUN:     -Werror -fsyntax-only -x objective-c -
+
+// Including a header from an umbrella directory
+// RUN: echo '@import FromUmbrella;' | \
+// RUN:   %clang_cc1 -Wnon-modular-include-in-framework-module -fmodules \
+// RUN:     -fmodules-cache-path=%t -F %S/Inputs/require-modular-includes \
+// RUN:     -I %S/Inputs/require-modular-includes \
+// RUN:     -Werror -fsyntax-only -x objective-c -
+
+// A includes B includes non-modular C
+// RUN: echo '@import A;' | \
+// RUN:   %clang_cc1 -Wnon-modular-include-in-framework-module -fmodules \
+// RUN:     -fmodules-cache-path=%t -F %S/Inputs/require-modular-includes \
+// RUN:     -I %S/Inputs/require-modular-includes \
+// RUN:     -fsyntax-only -x objective-c - 2>&1 | FileCheck %s
+
+// Non-framework module (pass)
+// RUN: echo '@import NotFramework;' | \
+// RUN:   %clang_cc1 -Wnon-modular-include-in-framework-module -fmodules \
+// RUN:     -fmodules-cache-path=%t -I %S/Inputs/require-modular-includes \
+// RUN:     -Werror -fsyntax-only -x objective-c -
+
+// CHECK: include of non-modular header
diff --git a/test/Modules/resolution-change.m b/test/Modules/resolution-change.m
new file mode 100644
index 0000000..011782e
--- /dev/null
+++ b/test/Modules/resolution-change.m
@@ -0,0 +1,27 @@
+// RUN: rm -rf %t
+
+// Build PCH using A from path 1
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs/modules-with-same-name/DependsOnA -I %S/Inputs/modules-with-same-name/path1/A -emit-pch -o %t-A.pch %s
+
+// Use the PCH with the same header search options; should be fine
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs/modules-with-same-name/DependsOnA -I %S/Inputs/modules-with-same-name/path1/A -include-pch %t-A.pch %s -fsyntax-only -Werror
+
+// Different -W options are ok
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs/modules-with-same-name/DependsOnA -I %S/Inputs/modules-with-same-name/path1/A -include-pch %t-A.pch %s -fsyntax-only -Werror -Wauto-import
+
+// Use the PCH with no way to resolve DependsOnA
+// RUN: not %clang_cc1 -fmodules -fmodules-cache-path=%t -include-pch %t-A.pch %s -fsyntax-only 2>&1 | FileCheck -check-prefix=CHECK-NODOA %s
+// CHECK-NODOA: module 'DependsOnA' imported by AST file '{{.*A.pch}}' not found
+
+// Use the PCH with no way to resolve A
+// RUN: not %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs/modules-with-same-name/DependsOnA -include-pch %t-A.pch %s -fsyntax-only 2>&1 | FileCheck -check-prefix=CHECK-NOA %s
+// CHECK-NOA: module 'A' imported by AST file '{{.*DependsOnA.*pcm}}' not found
+
+// Use the PCH and have it resolve the the other A
+// RUN: not %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs/modules-with-same-name/DependsOnA -I %S/Inputs/modules-with-same-name/path2/A -include-pch %t-A.pch %s -fsyntax-only 2>&1 | FileCheck -check-prefix=CHECK-WRONGA %s
+// CHECK-WRONGA: module 'A' imported by AST file '{{.*DependsOnA.*pcm}}' found in a different module map file ({{.*path2.*}}) than when the importing AST file was built ({{.*path1.*}})
+
+#ifndef HEADER
+#define HEADER
+@import DependsOnA;
+#endif
diff --git a/test/Modules/strict-decluse.cpp b/test/Modules/strict-decluse.cpp
new file mode 100644
index 0000000..fa6955a
--- /dev/null
+++ b/test/Modules/strict-decluse.cpp
@@ -0,0 +1,9 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodule-maps -fmodules-cache-path=%t -fmodules-strict-decluse -fmodule-name=XG -I %S/Inputs/declare-use %s -verify
+
+#include "g.h"
+#include "e.h"
+#include "f.h" // expected-error {{module XG does not depend on a module exporting 'f.h'}}
+#include "i.h" // expected-error {{module XG does not depend on a module exporting 'i.h'}}
+
+const int g2 = g1 + e + f + aux_i;
diff --git a/test/Modules/string_names.cpp b/test/Modules/string_names.cpp
new file mode 100644
index 0000000..ed65aa8
--- /dev/null
+++ b/test/Modules/string_names.cpp
@@ -0,0 +1,6 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fmodules-decluse -I %S/Inputs/string_names %s -fmodule-name="my/module-a" -verify
+
+#include "a.h"
+#include "b.h" // expected-error {{does not depend on a module exporting}}
+#include "c.h"
diff --git a/test/Modules/subframework-from-intermediate-path.m b/test/Modules/subframework-from-intermediate-path.m
new file mode 100644
index 0000000..ae0bd64
--- /dev/null
+++ b/test/Modules/subframework-from-intermediate-path.m
@@ -0,0 +1,5 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -F %S/Inputs -F %S/Inputs/DependsOnModule.framework/Frameworks %s -verify
+
+@import DependsOnModule;
+@import SubFramework; // expected-error{{module 'SubFramework' not found}}
diff --git a/test/Modules/submodules.cpp b/test/Modules/submodules.cpp
index 9c62389..c3b2623 100644
--- a/test/Modules/submodules.cpp
+++ b/test/Modules/submodules.cpp
@@ -26,11 +26,3 @@
 @import std.hash_map;
 
 hash_map<int, float> ints_to_floats2;
-
-@import import_self.b;
-extern MyTypeA import_self_test_a; // expected-error {{must be imported from module 'import_self.a'}}
-// expected-note@import-self-a.h:1 {{here}}
-extern MyTypeC import_self_test_c;
-// FIXME: This should be valid; import_self.b re-exports import_self.d.
-extern MyTypeD import_self_test_d; // expected-error {{must be imported from module 'import_self.d'}}
-// expected-note@import-self-d.h:1 {{here}}
diff --git a/test/Modules/system_version.m b/test/Modules/system_version.m
index 85b3263..bc82bf8 100644
--- a/test/Modules/system_version.m
+++ b/test/Modules/system_version.m
@@ -11,21 +11,21 @@
 
 // Run once with no system version file. We should end up with one module.
 // RUN: %clang_cc1 -fmodules-cache-path=%t/cache -fmodules -isysroot %t -I %t/usr/include %s -verify
-// RUN: ls -R %t | grep -c ModA.pcm| grep 1
+// RUN: ls -R %t | grep -c "ModA.*pcm" | grep 1
 
 // Add a system version file and run again. We should now have two
 // module variants.
 // RUN: mkdir -p %t/System/Library/CoreServices
 // RUN: echo "hello" > %t/System/Library/CoreServices/SystemVersion.plist
 // RUN: %clang_cc1 -fmodules-cache-path=%t/cache -fmodules -isysroot %t -I %t/usr/include %s -verify
-// RUN: ls -R %t | grep -c ModA.pcm| grep 2
+// RUN: ls -R %t | grep -c "ModA.*pcm" | grep 2
 
 // Change the system version file and run again. We should now have three
 // module variants.
 // RUN: mkdir -p %t/System/Library/CoreServices
 // RUN: echo "modules" > %t/System/Library/CoreServices/SystemVersion.plist
 // RUN: %clang_cc1 -fmodules-cache-path=%t/cache -fmodules -isysroot %t -I %t/usr/include %s -verify
-// RUN: ls -R %t | grep -c ModA.pcm| grep 3
+// RUN: ls -R %t | grep -c "ModA.*pcm" | grep 3
 
 // expected-no-diagnostics
 @import ModA;
diff --git a/test/Modules/template-specialization-visibility.cpp b/test/Modules/template-specialization-visibility.cpp
new file mode 100644
index 0000000..efcfd93
--- /dev/null
+++ b/test/Modules/template-specialization-visibility.cpp
@@ -0,0 +1,26 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -verify -fmodules-cache-path=%t -I %S/Inputs/template-specialization-visibility -std=c++11 %s
+//
+// expected-no-diagnostics
+
+#include "c.h"
+
+S<int> implicit_inst_class_template;
+int k1 = implicit_inst_class_template.n;
+
+S<char> explicit_inst_class_template;
+int k2 = explicit_inst_class_template.n;
+
+#include "a.h"
+
+T<int>::S implicit_inst_member_class_template;
+int k3 = implicit_inst_member_class_template.n;
+
+T<char>::S explicit_inst_member_class_template;
+int k4 = explicit_inst_member_class_template.n;
+
+T<int>::E implicit_inst_member_enum_template;
+int k5 = decltype(implicit_inst_member_enum_template)::e;
+
+T<char>::E explicit_inst_member_enum_template;
+int k6 = decltype(explicit_inst_member_enum_template)::e;
diff --git a/test/Modules/templates.mm b/test/Modules/templates.mm
index 080f9e7..78348af 100644
--- a/test/Modules/templates.mm
+++ b/test/Modules/templates.mm
@@ -4,6 +4,12 @@
 // expected-no-diagnostics
 
 @import templates_left;
+
+void testInlineRedeclEarly() {
+  // instantiate definition now, we'll add another declaration in _right.
+  OutOfLineInline<int>().h();
+}
+
 @import templates_right;
 
 // CHECK: @list_left = global { %{{.*}}*, i32, [4 x i8] } { %{{.*}}* null, i32 8,
@@ -20,6 +26,9 @@
 
   N::Set<char> set_char;
   set_char.insert('A');
+
+  List<double> list_double;
+  list_double.push_back(0.0);
 }
 
 void testPendingInstantiations() {
@@ -36,6 +45,19 @@
   redeclDefinitionEmit();
 }
 
+void testInlineRedecl() {
+  outOfLineInlineUseLeftF();
+  outOfLineInlineUseRightG();
+
+  outOfLineInlineUseRightF();
+  outOfLineInlineUseLeftG();
+}
+
+// CHECK-NOT: @_ZN21ExplicitInstantiationILb0ELb0EE1fEv(
+// CHECK: declare {{.*}}@_ZN21ExplicitInstantiationILb1ELb0EE1fEv(
+// CHECK: define {{.*}}@_ZN21ExplicitInstantiationILb1ELb1EE1fEv(
+// CHECK-NOT: @_ZN21ExplicitInstantiationILb0ELb0EE1fEv(
+
 // These three are all the same type.
 typedef OuterIntInner_left OuterIntInner;
 typedef OuterIntInner_right OuterIntInner;
@@ -58,12 +80,23 @@
   // CHECK: call {{.*}}memcpy{{.*}}(i8* %{{.*}}, i8* bitcast ({{.*}}* @_ZZ15testMixedStructvE1r to i8*), i64 16,
   ListInt_right r{0, 2};
 
-  // CHECK: call void @_Z10useListIntR4ListIiE(%[[ListInt]]* %[[l]])
+  // CHECK: call void @_Z10useListIntR4ListIiE(%[[ListInt]]* dereferenceable({{[0-9]+}}) %[[l]])
   useListInt(l);
-  // CHECK: call void @_Z10useListIntR4ListIiE(%[[ListInt]]* %[[r]])
+  // CHECK: call void @_Z10useListIntR4ListIiE(%[[ListInt]]* dereferenceable({{[0-9]+}}) %[[r]])
   useListInt(r);
 
   // CHECK: load i32* bitcast (i8* getelementptr inbounds (i8* bitcast ({{.*}}* @list_left to i8*), i64 8) to i32*)
   // CHECK: load i32* bitcast (i8* getelementptr inbounds (i8* bitcast ({{.*}}* @list_right to i8*), i64 8) to i32*)
   return list_left.*size_right + list_right.*size_left;
 }
+
+template<typename T> struct MergePatternDecl {
+  typedef int Type;
+  void f(Type);
+};
+template<typename T> void MergePatternDecl<T>::f(Type type) {}
+// CHECK: define {{.*}}@_ZN21ExplicitInstantiationILb0ELb1EE1fEv(
+template struct ExplicitInstantiation<false, true>;
+template struct ExplicitInstantiation<true, true>;
+
+void testDelayUpdatesImpl() { testDelayUpdates<int>(); }
diff --git a/test/Modules/undefined-type-fixit1.cpp b/test/Modules/undefined-type-fixit1.cpp
new file mode 100644
index 0000000..78ce174
--- /dev/null
+++ b/test/Modules/undefined-type-fixit1.cpp
@@ -0,0 +1,12 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fmodules-search-all -I %S/Inputs/undefined-type-fixit %s -verify
+
+//#include "public1.h"
+#include "public2.h"
+#include "public2sub.h"
+
+use_this1 client_variable1; // expected-error{{declaration of 'use_this1' must be imported from module 'public1' before it is required}}
+use_this2 client_variable2;
+use_this2sub client_variable2sub;
+
+// expected-note@Inputs/undefined-type-fixit/public1.h:4 {{previous declaration is here}}
diff --git a/test/Modules/unnecessary-module-map-parsing.c b/test/Modules/unnecessary-module-map-parsing.c
new file mode 100644
index 0000000..4c83448
--- /dev/null
+++ b/test/Modules/unnecessary-module-map-parsing.c
@@ -0,0 +1,8 @@
+// This checks that we are not parsing module maps if modules are not enabled.
+
+// RUN: not %clang_cc1 -fmodules -I %S/Inputs/unnecessary-module-map-parsing -fsyntax-only %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -I %S/Inputs/unnecessary-module-map-parsing -fsyntax-only %s
+
+// CHECK: error: expected umbrella, header, submodule, or module export
+
+#include "a1.h"
diff --git a/test/Modules/update-after-load.cpp b/test/Modules/update-after-load.cpp
new file mode 100644
index 0000000..f497ea4
--- /dev/null
+++ b/test/Modules/update-after-load.cpp
@@ -0,0 +1,8 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -I %S/Inputs/update-after-load -verify -fmodules-cache-path=%t %s
+
+// expected-no-diagnostics
+#include "a.h"
+namespace llvm {}
+#include "b.h"
+void llvm::f() {}
diff --git a/test/Modules/validate-system-headers.m b/test/Modules/validate-system-headers.m
new file mode 100644
index 0000000..48ea64c
--- /dev/null
+++ b/test/Modules/validate-system-headers.m
@@ -0,0 +1,43 @@
+// RUN: rm -rf %t/ModuleCache
+// RUN: mkdir -p %t/Inputs/usr/include
+// RUN: touch %t/Inputs/usr/include/foo.h
+// RUN: echo 'module Foo [system] { header "foo.h" }' > %t/Inputs/usr/include/module.map
+
+////
+// Build a module using a system header
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -isysroot %t/Inputs -fmodules -fmodules-cache-path=%t/ModuleCache -fdisable-module-hash -x objective-c-header -fsyntax-only %s
+// RUN: cp %t/ModuleCache/Foo.pcm %t/Foo.pcm.saved
+
+////
+// Modify the system header, and confirm that we don't notice without -fmodules-validate-system-headers.
+// The pcm file in the cache should fail to validate.
+// RUN: echo ' ' >> %t/Inputs/usr/include/foo.h
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -isysroot %t/Inputs -fmodules -fmodules-cache-path=%t/ModuleCache -fdisable-module-hash -x objective-c-header -fsyntax-only %s
+// RUN: diff %t/ModuleCache/Foo.pcm %t/Foo.pcm.saved
+
+////
+// Now make sure we rebuild the module when -fmodules-validate-system-headers is set.
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -isysroot %t/Inputs -fmodules -fmodules-validate-system-headers -fmodules-cache-path=%t/ModuleCache -fdisable-module-hash -x objective-c-header -fsyntax-only %s
+// RUN: not diff %t/ModuleCache/Foo.pcm %t/Foo.pcm.saved
+
+
+////
+// This should override -fmodules-validate-once-per-build-session
+// RUN: cp %t/ModuleCache/Foo.pcm %t/Foo.pcm.saved
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -isysroot %t/Inputs -fmodules -fmodules-cache-path=%t/ModuleCache -fdisable-module-hash -x objective-c-header -fsyntax-only %s -fbuild-session-timestamp=1390000000 -fmodules-validate-once-per-build-session
+// RUN: diff %t/ModuleCache/Foo.pcm %t/Foo.pcm.saved
+
+// Modify the system header...
+// RUN: echo ' ' >> %t/Inputs/usr/include/foo.h
+
+// Don't recompile due to -fmodules-validate-once-per-build-session
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -isysroot %t/Inputs -fmodules -fmodules-cache-path=%t/ModuleCache -fdisable-module-hash -x objective-c-header -fsyntax-only %s -fbuild-session-timestamp=1390000000 -fmodules-validate-once-per-build-session
+// RUN: diff %t/ModuleCache/Foo.pcm %t/Foo.pcm.saved
+
+// Now add -fmodules-validate-system-headers and rebuild
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -isysroot %t/Inputs -fmodules -fmodules-validate-system-headers -fmodules-cache-path=%t/ModuleCache -fdisable-module-hash -x objective-c-header -fsyntax-only %s -fbuild-session-timestamp=1390000000 -fmodules-validate-once-per-build-session
+// RUN: not diff %t/ModuleCache/Foo.pcm %t/Foo.pcm.saved
+
+// REQUIRES: shell
+
+@import Foo;
diff --git a/test/OpenMP/barrier_ast_print.cpp b/test/OpenMP/barrier_ast_print.cpp
new file mode 100644
index 0000000..0ce344f
--- /dev/null
+++ b/test/OpenMP/barrier_ast_print.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+void foo() {}
+
+template <class T>
+T tmain(T argc) {
+  static T a;
+#pragma omp barrier
+  return a + argc;
+}
+// CHECK:      static int a;
+// CHECK-NEXT: #pragma omp barrier
+// CHECK:      static char a;
+// CHECK-NEXT: #pragma omp barrier
+// CHECK:      static T a;
+// CHECK-NEXT: #pragma omp barrier
+
+int main(int argc, char **argv) {
+  static int a;
+// CHECK: static int a;
+#pragma omp barrier
+  // CHECK-NEXT: #pragma omp barrier
+  return tmain(argc) + tmain(argv[0][0]) + a;
+}
+
+#endif
diff --git a/test/OpenMP/barrier_messages.cpp b/test/OpenMP/barrier_messages.cpp
new file mode 100644
index 0000000..81ff84e
--- /dev/null
+++ b/test/OpenMP/barrier_messages.cpp
@@ -0,0 +1,110 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 %s
+
+template <class T>
+T tmain(T argc) {
+#pragma omp barrier
+  ;
+#pragma omp barrier untied  // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp barrier'}}
+#pragma omp barrier unknown // expected-warning {{extra tokens at the end of '#pragma omp barrier' are ignored}}
+  if (argc)
+#pragma omp barrier // expected-error {{'#pragma omp barrier' cannot be an immediate substatement}}
+    if (argc) {
+#pragma omp barrier
+    }
+  while (argc)
+#pragma omp barrier // expected-error {{'#pragma omp barrier' cannot be an immediate substatement}}
+    while (argc) {
+#pragma omp barrier
+    }
+  do
+#pragma omp barrier // expected-error {{'#pragma omp barrier' cannot be an immediate substatement}}
+    while (argc)
+      ;
+  do {
+#pragma omp barrier
+  } while (argc);
+  switch (argc)
+#pragma omp barrier // expected-error {{'#pragma omp barrier' cannot be an immediate substatement}}
+    switch (argc)
+    case 1:
+#pragma omp barrier // expected-error {{'#pragma omp barrier' cannot be an immediate substatement}}
+  switch (argc)
+  case 1: {
+#pragma omp barrier
+  }
+  switch (argc) {
+#pragma omp barrier
+  case 1:
+#pragma omp barrier // expected-error {{'#pragma omp barrier' cannot be an immediate substatement}}
+    break;
+  default: {
+#pragma omp barrier
+  } break;
+  }
+  for (;;)
+#pragma omp barrier // expected-error {{'#pragma omp barrier' cannot be an immediate substatement}}
+    for (;;) {
+#pragma omp barrier
+    }
+label:
+#pragma omp barrier // expected-error {{'#pragma omp barrier' cannot be an immediate substatement}}
+label1 : {
+#pragma omp barrier
+}
+
+  return T();
+}
+
+int main(int argc, char **argv) {
+#pragma omp barrier
+  ;
+#pragma omp barrier untied  // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp barrier'}}
+#pragma omp barrier unknown // expected-warning {{extra tokens at the end of '#pragma omp barrier' are ignored}}
+  if (argc)
+#pragma omp barrier // expected-error {{'#pragma omp barrier' cannot be an immediate substatement}}
+    if (argc) {
+#pragma omp barrier
+    }
+  while (argc)
+#pragma omp barrier // expected-error {{'#pragma omp barrier' cannot be an immediate substatement}}
+    while (argc) {
+#pragma omp barrier
+    }
+  do
+#pragma omp barrier // expected-error {{'#pragma omp barrier' cannot be an immediate substatement}}
+    while (argc)
+      ;
+  do {
+#pragma omp barrier
+  } while (argc);
+  switch (argc)
+#pragma omp barrier // expected-error {{'#pragma omp barrier' cannot be an immediate substatement}}
+    switch (argc)
+    case 1:
+#pragma omp barrier // expected-error {{'#pragma omp barrier' cannot be an immediate substatement}}
+  switch (argc)
+  case 1: {
+#pragma omp barrier
+  }
+  switch (argc) {
+#pragma omp barrier
+  case 1:
+#pragma omp barrier // expected-error {{'#pragma omp barrier' cannot be an immediate substatement}}
+    break;
+  default: {
+#pragma omp barrier
+  } break;
+  }
+  for (;;)
+#pragma omp barrier // expected-error {{'#pragma omp barrier' cannot be an immediate substatement}}
+    for (;;) {
+#pragma omp barrier
+    }
+label:
+#pragma omp barrier // expected-error {{'#pragma omp barrier' cannot be an immediate substatement}}
+label1 : {
+#pragma omp barrier
+}
+
+  return tmain(argc);
+}
diff --git a/test/OpenMP/critical_ast_print.cpp b/test/OpenMP/critical_ast_print.cpp
new file mode 100644
index 0000000..98ece88
--- /dev/null
+++ b/test/OpenMP/critical_ast_print.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+void foo() {}
+
+int main (int argc, char **argv) {
+  int b = argc, c, d, e, f, g;
+  static int a;
+// CHECK: static int a;
+#pragma omp critical
+  a=2;
+// CHECK-NEXT: #pragma omp critical
+// CHECK-NEXT: a = 2;
+// CHECK-NEXT: ++a;
+  ++a;
+#pragma omp critical  (the_name)
+  foo();
+// CHECK-NEXT: #pragma omp critical (the_name)
+// CHECK-NEXT: foo();
+// CHECK-NEXT: return 0;
+  return 0;
+}
+
+#endif
diff --git a/test/OpenMP/critical_messages.cpp b/test/OpenMP/critical_messages.cpp
new file mode 100644
index 0000000..08df9e0
--- /dev/null
+++ b/test/OpenMP/critical_messages.cpp
@@ -0,0 +1,72 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+int foo();
+
+int main() {
+  #pragma omp critical
+  ;
+  #pragma omp critical untied // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp critical'}}
+  #pragma omp critical unknown // expected-warning {{extra tokens at the end of '#pragma omp critical' are ignored}}
+  #pragma omp critical ( // expected-error {{expected identifier}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp critical ( + // expected-error {{expected identifier}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp critical (name // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp critical (name1)
+  foo();
+  {
+    #pragma omp critical
+  } // expected-error {{expected statement}}
+  #pragma omp critical (name) // expected-note {{previous 'critical' region starts here}}
+  #pragma omp critical
+  for (int i = 0; i < 10; ++i) {
+    foo();
+    #pragma omp parallel
+    #pragma omp for
+    for (int j = 0; j < 10; j++) {
+      foo();
+      #pragma omp critical(name) // expected-error {{cannot nest 'critical' regions having the same name 'name'}}
+      foo();
+    }
+  }
+  #pragma omp critical (name)
+  #pragma omp critical
+  for (int i = 0; i < 10; ++i) {
+    foo();
+    #pragma omp parallel
+    #pragma omp for
+    for (int j = 0; j < 10; j++) {
+      #pragma omp critical
+      foo();
+    }
+  }
+  #pragma omp critical (name)
+  #pragma omp critical
+  for (int i = 0; i < 10; ++i) {
+    foo();
+    #pragma omp parallel
+    #pragma omp for
+    for (int j = 0; j < 10; j++) {
+      #pragma omp critical (nam)
+      foo();
+    }
+  }
+
+  return 0;
+}
+
+int foo() {
+  L1:
+    foo();
+  #pragma omp critical
+  {
+    foo();
+    goto L1; // expected-error {{use of undeclared label 'L1'}}
+  }
+  goto L2; // expected-error {{use of undeclared label 'L2'}}
+  #pragma omp critical
+  {
+    L2:
+    foo();
+  }
+
+  return 0;
+}
diff --git a/test/OpenMP/flush_ast_print.cpp b/test/OpenMP/flush_ast_print.cpp
new file mode 100644
index 0000000..7eb18f0
--- /dev/null
+++ b/test/OpenMP/flush_ast_print.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+void foo() {}
+
+template <class T>
+T tmain(T argc) {
+  static T a;
+#pragma omp flush
+#pragma omp flush(a)
+  return a + argc;
+}
+// CHECK:      static int a;
+// CHECK-NEXT: #pragma omp flush
+// CHECK-NEXT: #pragma omp flush (a)
+// CHECK:      static char a;
+// CHECK-NEXT: #pragma omp flush
+// CHECK-NEXT: #pragma omp flush (a)
+// CHECK:      static T a;
+// CHECK-NEXT: #pragma omp flush
+// CHECK-NEXT: #pragma omp flush (a)
+
+int main(int argc, char **argv) {
+  static int a;
+// CHECK: static int a;
+#pragma omp flush
+#pragma omp flush(a)
+// CHECK-NEXT: #pragma omp flush
+// CHECK-NEXT: #pragma omp flush (a)
+  return tmain(argc) + tmain(argv[0][0]) + a;
+}
+
+#endif
diff --git a/test/OpenMP/flush_messages.cpp b/test/OpenMP/flush_messages.cpp
new file mode 100644
index 0000000..8c61680
--- /dev/null
+++ b/test/OpenMP/flush_messages.cpp
@@ -0,0 +1,134 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 %s
+
+struct S1 { // expected-note 2 {{declared here}}
+  int a;
+};
+
+template <class T>
+T tmain(T argc) {
+#pragma omp flush
+  ;
+#pragma omp flush untied  // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp flush'}}
+#pragma omp flush unknown // expected-warning {{extra tokens at the end of '#pragma omp flush' are ignored}}
+  if (argc)
+#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
+    if (argc) {
+#pragma omp flush
+    }
+  while (argc)
+#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
+    while (argc) {
+#pragma omp flush
+    }
+  do
+#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
+    while (argc)
+      ;
+  do {
+#pragma omp flush
+  } while (argc);
+  switch (argc)
+#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
+    switch (argc)
+    case 1:
+#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
+  switch (argc)
+  case 1: {
+#pragma omp flush
+  }
+  switch (argc) {
+#pragma omp flush
+  case 1:
+#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
+    break;
+  default: {
+#pragma omp flush
+  } break;
+  }
+  for (;;)
+#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
+    for (;;) {
+#pragma omp flush
+    }
+label:
+#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
+label1 : {
+#pragma omp flush
+}
+
+#pragma omp flush
+#pragma omp flush(                              // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp flush()                             // expected-error {{expected expression}}
+#pragma omp flush(argc                          // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp flush(argc,                         // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp flush(argc)
+#pragma omp flush(S1) // expected-error {{'S1' does not refer to a value}}
+#pragma omp flush(argc) flush(argc) // expected-warning {{extra tokens at the end of '#pragma omp flush' are ignored}}
+#pragma omp parallel flush(argc) // expected-warning {{extra tokens at the end of '#pragma omp parallel' are ignored}}
+  ;
+  return T();
+}
+
+int main(int argc, char **argv) {
+#pragma omp flush
+  ;
+#pragma omp flush untied  // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp flush'}}
+#pragma omp flush unknown // expected-warning {{extra tokens at the end of '#pragma omp flush' are ignored}}
+  if (argc)
+#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
+    if (argc) {
+#pragma omp flush
+    }
+  while (argc)
+#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
+    while (argc) {
+#pragma omp flush
+    }
+  do
+#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
+    while (argc)
+      ;
+  do {
+#pragma omp flush
+  } while (argc);
+  switch (argc)
+#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
+    switch (argc)
+    case 1:
+#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
+  switch (argc)
+  case 1: {
+#pragma omp flush
+  }
+  switch (argc) {
+#pragma omp flush
+  case 1:
+#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
+    break;
+  default: {
+#pragma omp flush
+  } break;
+  }
+  for (;;)
+#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
+    for (;;) {
+#pragma omp flush
+    }
+label:
+#pragma omp flush // expected-error {{'#pragma omp flush' cannot be an immediate substatement}}
+label1 : {
+#pragma omp flush
+}
+
+#pragma omp flush
+#pragma omp flush(                              // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp flush()                             // expected-error {{expected expression}}
+#pragma omp flush(argc                          // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp flush(argc,                         // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp flush(argc)
+#pragma omp flush(S1) // expected-error {{'S1' does not refer to a value}}
+#pragma omp flush(argc) flush(argc) // expected-warning {{extra tokens at the end of '#pragma omp flush' are ignored}}
+#pragma omp parallel flush(argc) // expected-warning {{extra tokens at the end of '#pragma omp parallel' are ignored}}
+  ;
+  return tmain(argc);
+}
diff --git a/test/OpenMP/for_ast_print.cpp b/test/OpenMP/for_ast_print.cpp
new file mode 100644
index 0000000..8802237
--- /dev/null
+++ b/test/OpenMP/for_ast_print.cpp
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+void foo() {}
+
+template <class T, int N>
+T tmain(T argc) {
+  T b = argc, c, d, e, f, g;
+  static T a;
+// CHECK: static T a;
+#pragma omp for schedule(dynamic)
+  // CHECK-NEXT: #pragma omp for schedule(dynamic)
+  for (int i = 0; i < 2; ++i)
+    a = 2;
+// CHECK-NEXT: for (int i = 0; i < 2; ++i)
+// CHECK-NEXT: a = 2;
+#pragma omp parallel
+#pragma omp for private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) schedule(static, N) ordered nowait
+  for (int i = 0; i < 10; ++i)
+    for (int j = 0; j < 10; ++j)
+      for (int j = 0; j < 10; ++j)
+        for (int j = 0; j < 10; ++j)
+          for (int j = 0; j < 10; ++j)
+            foo();
+  // CHECK-NEXT: #pragma omp parallel
+  // CHECK-NEXT: #pragma omp for private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) schedule(static, N) ordered nowait
+  // CHECK-NEXT: for (int i = 0; i < 10; ++i)
+  // CHECK-NEXT: for (int j = 0; j < 10; ++j)
+  // CHECK-NEXT: for (int j = 0; j < 10; ++j)
+  // CHECK-NEXT: for (int j = 0; j < 10; ++j)
+  // CHECK-NEXT: for (int j = 0; j < 10; ++j)
+  // CHECK-NEXT: foo();
+  return T();
+}
+
+int main(int argc, char **argv) {
+  int b = argc, c, d, e, f, g;
+  static int a;
+// CHECK: static int a;
+#pragma omp for schedule(guided, argc)
+  // CHECK-NEXT: #pragma omp for schedule(guided, argc)
+  for (int i = 0; i < 2; ++i)
+    a = 2;
+// CHECK-NEXT: for (int i = 0; i < 2; ++i)
+// CHECK-NEXT: a = 2;
+#pragma omp parallel
+#pragma omp for private(argc, b), firstprivate(argv, c), lastprivate(d, f) collapse(2) schedule(auto) ordered nowait
+  for (int i = 0; i < 10; ++i)
+    for (int j = 0; j < 10; ++j)
+      foo();
+  // CHECK-NEXT: #pragma omp parallel
+  // CHECK-NEXT: #pragma omp for private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) schedule(auto) ordered nowait
+  // CHECK-NEXT: for (int i = 0; i < 10; ++i)
+  // CHECK-NEXT: for (int j = 0; j < 10; ++j)
+  // CHECK-NEXT: foo();
+  return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0]));
+}
+
+#endif
diff --git a/test/OpenMP/for_collapse_messages.cpp b/test/OpenMP/for_collapse_messages.cpp
new file mode 100644
index 0000000..9e14234
--- /dev/null
+++ b/test/OpenMP/for_collapse_messages.cpp
@@ -0,0 +1,83 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, typename S, int N, int ST> // expected-note {{declared here}}
+T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
+  #pragma omp for collapse // expected-error {{expected '(' after 'collapse'}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for collapse ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for collapse () // expected-error {{expected expression}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}}
+  // expected-error@+2 2 {{expression is not an integral constant expression}}
+  // expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}}
+  #pragma omp for collapse (argc 
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  // expected-error@+1 2 {{argument to 'collapse' clause must be a positive integer value}}
+  #pragma omp for collapse (ST // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for collapse (1)) // expected-warning {{extra tokens at the end of '#pragma omp for' are ignored}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp for', but found only 1}}
+  // expected-error@+3 2 {{directive '#pragma omp for' cannot contain more than one 'collapse' clause}}
+  // expected-error@+2 2 {{argument to 'collapse' clause must be a positive integer value}}
+  // expected-error@+1 2 {{expression is not an integral constant expression}}
+  #pragma omp for collapse (foobool(argc)), collapse (true), collapse (-5)
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for collapse (S) // expected-error {{'S' does not refer to a value}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  // expected-error@+1 2 {{expression is not an integral constant expression}}
+  #pragma omp for collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for collapse (1)
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for collapse (N) // expected-error {{argument to 'collapse' clause must be a positive integer value}}
+  for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for collapse (2) // expected-note {{as specified in 'collapse' clause}}
+  foo(); // expected-error {{expected 2 for loops after '#pragma omp for'}}
+  return argc;
+}
+
+int main(int argc, char **argv) {
+  #pragma omp for collapse // expected-error {{expected '(' after 'collapse'}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp for collapse ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp for collapse () // expected-error {{expected expression}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp for collapse (4 // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{as specified in 'collapse' clause}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp for', but found only 1}}
+  #pragma omp for collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp for' are ignored}}  expected-note {{as specified in 'collapse' clause}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp for', but found only 1}}
+  #pragma omp for collapse (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  // expected-error@+3 {{expression is not an integral constant expression}}
+  // expected-error@+2 2 {{directive '#pragma omp for' cannot contain more than one 'collapse' clause}}
+  // expected-error@+1 2 {{argument to 'collapse' clause must be a positive integer value}}
+  #pragma omp for collapse (foobool(argc)), collapse (true), collapse (-5) 
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp for collapse (S1) // expected-error {{'S1' does not refer to a value}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  // expected-error@+1 {{expression is not an integral constant expression}}
+  #pragma omp for collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  // expected-error@+3 {{statement after '#pragma omp for' must be a for loop}}
+  // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
+  #pragma omp for collapse(collapse(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
+  foo();
+  #pragma omp for collapse (2) // expected-note {{as specified in 'collapse' clause}}
+  foo(); // expected-error {{expected 2 for loops after '#pragma omp for'}}
+  // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}}
+  return tmain<int, char, 1, 0>(argc, argv);
+}
+
diff --git a/test/OpenMP/for_firstprivate_messages.cpp b/test/OpenMP/for_firstprivate_messages.cpp
new file mode 100644
index 0000000..f1d21b8
--- /dev/null
+++ b/test/OpenMP/for_firstprivate_messages.cpp
@@ -0,0 +1,293 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+  S2(S2 &s2) : a(s2.a) {}
+  static float S2s;
+  static const float S2sc;
+};
+const float S2::S2sc = 0;
+const S2 b;
+const S2 ba[5];
+class S3 {
+  int a;
+  S3 &operator=(const S3 &s3);
+
+public:
+  S3() : a(0) {}
+  S3(S3 &s3) : a(s3.a) {}
+};
+const S3 c;
+const S3 ca[5];
+extern const int f;
+class S4 { // expected-note 2 {{'S4' declared here}}
+  int a;
+  S4();
+  S4(const S4 &s4);
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note 4 {{'S5' declared here}}
+  int a;
+  S5(const S5 &s5) : a(s5.a) {}
+
+public:
+  S5() : a(0) {}
+  S5(int v) : a(v) {}
+};
+class S6 {
+  int a;
+  S6() : a(0) {}
+
+public:
+  S6(const S6 &s6) : a(s6.a) {}
+  S6(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(int argc, char **argv) {
+  I e(4); // expected-note {{'e' defined here}}
+  C g(5); // expected-note 2 {{'g' defined here}}
+  int i;
+  int &j = i; // expected-note {{'j' defined here}}
+#pragma omp parallel
+#pragma omp for firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for firstprivate() // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for firstprivate(argc)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for firstprivate(a, b) // expected-error {{firstprivate variable with incomplete type 'S1'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for firstprivate(argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for linear(i) // expected-error {{unexpected OpenMP clause 'linear' in directive '#pragma omp for'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;                      // expected-note {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp for' directive into a parallel or another task region?}}
+#pragma omp for firstprivate(i) // expected-error {{private variable cannot be firstprivate}}
+    for (int k = 0; k < argc; ++k) {
+      i = k;
+      v += i;
+    }
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp for firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for firstprivate(i)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for lastprivate(g) firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel private(i) // expected-note {{defined as private}}
+#pragma omp for firstprivate(i) // expected-error {{firstprivate variable must be shared}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel reduction(+ : i) // expected-note {{defined as reduction}}
+#pragma omp for firstprivate(i)       // expected-error {{firstprivate variable must be shared}}
+  for (i = 0; i < argc; ++i)
+    foo();
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;
+  const int da[5] = {0};
+  S4 e(4); // expected-note {{'e' defined here}}
+  S5 g(5); // expected-note 2 {{'g' defined here}}
+  S3 m;
+  S6 n(2);
+  int i;
+  int &j = i; // expected-note {{'j' defined here}}
+#pragma omp parallel
+#pragma omp for firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate() // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(argc)
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(argv[1]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(2 * 2) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(ba) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(ca) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(da) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+  int xa;
+#pragma omp parallel
+#pragma omp for firstprivate(xa) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(S2::S2s) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(S2::S2sc) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for safelen(5) // expected-error {{unexpected OpenMP clause 'safelen' in directive '#pragma omp for'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(m) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for private(xa), firstprivate(xa) // expected-error {{private variable cannot be firstprivate}} expected-note {{defined as private}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(i) // expected-note {{defined as firstprivate}}
+  for (i = 0; i < argc; ++i)    // expected-error {{loop iteration variable in the associated loop of 'omp for' directive may not be firstprivate, predetermined as private}}
+    foo();
+#pragma omp parallel shared(xa)
+#pragma omp for firstprivate(xa) // OK: may be firstprivate
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(g) firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(n) firstprivate(n) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;                      // expected-note {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp for' directive into a parallel or another task region?}}
+#pragma omp for firstprivate(i) // expected-error {{private variable cannot be firstprivate}}
+    for (int k = 0; k < argc; ++k) {
+      i = k;
+      v += i;
+    }
+  }
+#pragma omp parallel private(i) // expected-note {{defined as private}}
+#pragma omp for firstprivate(i) // expected-error {{firstprivate variable must be shared}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel reduction(+ : i) // expected-note {{defined as reduction}}
+#pragma omp for firstprivate(i)       // expected-error {{firstprivate variable must be shared}}
+  for (i = 0; i < argc; ++i)
+    foo();
+
+  return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}}
+}
diff --git a/test/OpenMP/for_lastprivate_messages.cpp b/test/OpenMP/for_lastprivate_messages.cpp
new file mode 100644
index 0000000..a3a1c4b
--- /dev/null
+++ b/test/OpenMP/for_lastprivate_messages.cpp
@@ -0,0 +1,266 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+  S2(S2 &s2) : a(s2.a) {}
+  static float S2s; // expected-note {{static data member is predetermined as shared}}
+  static const float S2sc;
+};
+const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const S2 b;
+const S2 ba[5];
+class S3 { // expected-note 2 {{'S3' declared here}}
+  int a;
+  S3 &operator=(const S3 &s3);
+
+public:
+  S3() : a(0) {}
+  S3(S3 &s3) : a(s3.a) {}
+};
+const S3 c;         // expected-note {{global variable is predetermined as shared}}
+const S3 ca[5];     // expected-note {{global variable is predetermined as shared}}
+extern const int f; // expected-note {{global variable is predetermined as shared}}
+class S4 {          // expected-note 3 {{'S4' declared here}}
+  int a;
+  S4();
+  S4(const S4 &s4);
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note {{'S5' declared here}}
+  int a;
+  S5() : a(0) {}
+
+public:
+  S5(const S5 &s5) : a(s5.a) {}
+  S5(int v) : a(v) {}
+};
+class S6 {
+  int a;
+  S6() : a(0) {}
+
+public:
+  S6(const S6 &s6) : a(s6.a) {}
+  S6(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(int argc, char **argv) {
+  I e(4); // expected-note {{'e' defined here}}
+  I g(5); // expected-note {{'g' defined here}}
+  int i;
+  int &j = i; // expected-note {{'j' defined here}}
+#pragma omp parallel
+#pragma omp for lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for lastprivate() // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for lastprivate(argc)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for lastprivate(a, b) // expected-error {{lastprivate variable with incomplete type 'S1'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for lastprivate(argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for lastprivate(e, g) // expected-error 2 {{lastprivate variable must have an accessible, unambiguous default constructor}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for linear(i) // expected-error {{unexpected OpenMP clause 'linear' in directive '#pragma omp for'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;                     // expected-note {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp for' directive into a parallel or another task region?}}
+#pragma omp for lastprivate(i) // expected-error {{lastprivate variable must be shared}}
+    for (int k = 0; k < argc; ++k) {
+      i = k;
+      v += i;
+    }
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp for lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+#pragma omp for lastprivate(i)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;       // expected-note {{constant variable is predetermined as shared}}
+  const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+  S4 e(4);               // expected-note {{'e' defined here}}
+  S5 g(5);               // expected-note {{'g' defined here}}
+  S3 m;                  // expected-note 2 {{'m' defined here}}
+  S6 n(2);
+  int i;
+  int &j = i; // expected-note {{'j' defined here}}
+#pragma omp parallel
+#pragma omp for lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate() // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(argc)
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(argv[1]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(2 * 2) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(ba)
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+  int xa;
+#pragma omp parallel
+#pragma omp for lastprivate(xa) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for safelen(5) // expected-error {{unexpected OpenMP clause 'safelen' in directive '#pragma omp for'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(e, g) // expected-error 2 {{lastprivate variable must have an accessible, unambiguous default constructor}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(m) // expected-error {{lastprivate variable must have an accessible, unambiguous copy assignment operator}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for private(xa), lastprivate(xa) // expected-error {{private variable cannot be lastprivate}} expected-note {{defined as private}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(i)
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel private(xa) // expected-note {{defined as private}}
+#pragma omp for lastprivate(xa)  // expected-error {{lastprivate variable must be shared}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel reduction(+ : xa) // expected-note {{defined as reduction}}
+#pragma omp for lastprivate(xa)        // expected-error {{lastprivate variable must be shared}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for firstprivate(m) lastprivate(m) // expected-error {{lastprivate variable must have an accessible, unambiguous copy assignment operator}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for lastprivate(n) firstprivate(n) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+  return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}}
+}
diff --git a/test/OpenMP/for_loop_messages.cpp b/test/OpenMP/for_loop_messages.cpp
new file mode 100644
index 0000000..8cc882e
--- /dev/null
+++ b/test/OpenMP/for_loop_messages.cpp
@@ -0,0 +1,694 @@
+// RUN: %clang_cc1 -fsyntax-only -fopenmp=libiomp5 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify %s
+
+class S {
+  int a;
+  S() : a(0) {}
+
+public:
+  S(int v) : a(v) {}
+  S(const S &s) : a(s.a) {}
+};
+
+static int sii;
+#pragma omp threadprivate(sii) // expected-note {{defined as threadprivate or thread local}}
+
+int test_iteration_spaces() {
+  const int N = 100;
+  float a[N], b[N], c[N];
+  int ii, jj, kk;
+  float fii;
+  double dii;
+#pragma omp parallel
+#pragma omp for
+  for (int i = 0; i < 10; i += 1) {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp parallel
+#pragma omp for
+  for (char i = 0; i < 10; i++) {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp parallel
+#pragma omp for
+  for (char i = 0; i < 10; i += '\1') {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp parallel
+#pragma omp for
+  for (long long i = 0; i < 10; i++) {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp parallel
+// expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'double'}}
+#pragma omp for
+  for (long long i = 0; i < 10; i += 1.5) {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp parallel
+#pragma omp for
+  for (long long i = 0; i < 'z'; i += 1u) {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp parallel
+// expected-error@+2 {{variable must be of integer or random access iterator type}}
+#pragma omp for
+  for (float fi = 0; fi < 10.0; fi++) {
+    c[(int)fi] = a[(int)fi] + b[(int)fi];
+  }
+#pragma omp parallel
+// expected-error@+2 {{variable must be of integer or random access iterator type}}
+#pragma omp for
+  for (double fi = 0; fi < 10.0; fi++) {
+    c[(int)fi] = a[(int)fi] + b[(int)fi];
+  }
+#pragma omp parallel
+// expected-error@+2 {{variable must be of integer or random access iterator type}}
+#pragma omp for
+  for (int &ref = ii; ref < 10; ref++) {
+  }
+#pragma omp parallel
+// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
+#pragma omp for
+  for (int i; i < 10; i++)
+    c[i] = a[i];
+
+#pragma omp parallel
+// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
+#pragma omp for
+  for (int i = 0, j = 0; i < 10; ++i)
+    c[i] = a[i];
+
+#pragma omp parallel
+// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
+#pragma omp for
+  for (; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-warning@+3 {{expression result unused}}
+// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
+#pragma omp for
+  for (ii + 1; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
+#pragma omp for
+  for (c[ii] = 0; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// Ok to skip parenthesises.
+#pragma omp for
+  for (((ii)) = 0; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+#pragma omp for
+  for (int i = 0; i; i++)
+    c[i] = a[i];
+
+#pragma omp parallel
+// expected-error@+3 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'i'}}
+#pragma omp for
+  for (int i = 0; jj < kk; ii++)
+    c[i] = a[i];
+
+#pragma omp parallel
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+#pragma omp for
+  for (int i = 0; !!i; i++)
+    c[i] = a[i];
+
+#pragma omp parallel
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+#pragma omp for
+  for (int i = 0; i != 1; i++)
+    c[i] = a[i];
+
+#pragma omp parallel
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+#pragma omp for
+  for (int i = 0;; i++)
+    c[i] = a[i];
+
+#pragma omp parallel
+// Ok.
+#pragma omp for
+  for (int i = 11; i > 10; i--)
+    c[i] = a[i];
+
+#pragma omp parallel
+// Ok.
+#pragma omp for
+  for (int i = 0; i < 10; ++i)
+    c[i] = a[i];
+
+#pragma omp parallel
+// Ok.
+#pragma omp for
+  for (ii = 0; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp for
+  for (ii = 0; ii < 10; ++jj)
+    c[ii] = a[jj];
+
+#pragma omp parallel
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp for
+  for (ii = 0; ii < 10; ++++ii)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// Ok but undefined behavior (in general, cannot check that incr
+// is really loop-invariant).
+#pragma omp for
+  for (ii = 0; ii < 10; ii = ii + ii)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'float'}}
+#pragma omp for
+  for (ii = 0; ii < 10; ii = ii + 1.0f)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// Ok - step was converted to integer type.
+#pragma omp for
+  for (ii = 0; ii < 10; ii = ii + (int)1.1f)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp for
+  for (ii = 0; ii < 10; jj = ii + 2)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-warning@+3 {{relational comparison result unused}}
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp for
+  for (ii = 0; ii<10; jj> kk + 2)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp for
+  for (ii = 0; ii < 10;)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-warning@+3 {{expression result unused}}
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp for
+  for (ii = 0; ii < 10; !ii)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp for
+  for (ii = 0; ii < 10; ii ? ++ii : ++jj)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp for
+  for (ii = 0; ii < 10; ii = ii < 10)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp for
+  for (ii = 0; ii < 10; ii = ii + 0)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp for
+  for (ii = 0; ii < 10; ii = ii + (int)(0.8 - 0.45))
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp for
+  for (ii = 0; (ii) < 10; ii -= 25)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp for
+  for (ii = 0; (ii < 10); ii -= 0)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}}
+#pragma omp for
+  for (ii = 0; ii > 10; (ii += 0))
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp for
+  for (ii = 0; ii < 10; (ii) = (1 - 1) + (ii))
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}}
+#pragma omp for
+  for ((ii = 0); ii > 10; (ii -= 0))
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp for
+  for (ii = 0; (ii < 10); (ii -= 0))
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-note@+2  {{defined as firstprivate}}
+// expected-error@+2 {{loop iteration variable in the associated loop of 'omp for' directive may not be firstprivate, predetermined as private}}
+#pragma omp for firstprivate(ii)
+  for (ii = 0; ii < 10; ii++)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+// expected-error@+3 {{unexpected OpenMP clause 'linear' in directive '#pragma omp for'}}
+// expected-note@+2  {{defined as linear}}
+// expected-error@+2 {{loop iteration variable in the associated loop of 'omp for' directive may not be linear, predetermined as private}}
+#pragma omp for linear(ii)
+  for (ii = 0; ii < 10; ii++)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+#pragma omp for private(ii)
+  for (ii = 0; ii < 10; ii++)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+#pragma omp for lastprivate(ii)
+  for (ii = 0; ii < 10; ii++)
+    c[ii] = a[ii];
+
+#pragma omp parallel
+  {
+// expected-error@+2 {{loop iteration variable in the associated loop of 'omp for' directive may not be threadprivate or thread local, predetermined as private}}
+#pragma omp for
+    for (sii = 0; sii < 10; sii += 1)
+      c[sii] = a[sii];
+  }
+
+#pragma omp parallel
+// expected-error@+2 {{statement after '#pragma omp for' must be a for loop}}
+#pragma omp for
+  for (auto &item : a) {
+    item = item + 1;
+  }
+
+#pragma omp parallel
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'i' to increase on each iteration of OpenMP for loop}}
+#pragma omp for
+  for (unsigned i = 9; i < 10; i--) {
+    c[i] = a[i] + b[i];
+  }
+
+  int(*lb)[4] = nullptr;
+#pragma omp parallel
+#pragma omp for
+  for (int(*p)[4] = lb; p < lb + 8; ++p) {
+  }
+
+#pragma omp parallel
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp for
+  for (int a{0}; a < 10; ++a) {
+  }
+
+  return 0;
+}
+
+// Iterators allowed in openmp for-loops.
+namespace std {
+struct random_access_iterator_tag {};
+template <class Iter>
+struct iterator_traits {
+  typedef typename Iter::difference_type difference_type;
+  typedef typename Iter::iterator_category iterator_category;
+};
+template <class Iter>
+typename iterator_traits<Iter>::difference_type
+distance(Iter first, Iter last) { return first - last; }
+}
+class Iter0 {
+public:
+  Iter0() {}
+  Iter0(const Iter0 &) {}
+  Iter0 operator++() { return *this; }
+  Iter0 operator--() { return *this; }
+  bool operator<(Iter0 a) { return true; }
+};
+int operator-(Iter0 a, Iter0 b) { return 0; }
+class Iter1 {
+public:
+  Iter1(float f = 0.0f, double d = 0.0) {}
+  Iter1(const Iter1 &) {}
+  Iter1 operator++() { return *this; }
+  Iter1 operator--() { return *this; }
+  bool operator<(Iter1 a) { return true; }
+  bool operator>=(Iter1 a) { return false; }
+};
+class GoodIter {
+public:
+  GoodIter() {}
+  GoodIter(const GoodIter &) {}
+  GoodIter(int fst, int snd) {}
+  GoodIter &operator=(const GoodIter &that) { return *this; }
+  GoodIter &operator=(const Iter0 &that) { return *this; }
+  GoodIter &operator+=(int x) { return *this; }
+  explicit GoodIter(void *) {}
+  GoodIter operator++() { return *this; }
+  GoodIter operator--() { return *this; }
+  bool operator!() { return true; }
+  bool operator<(GoodIter a) { return true; }
+  bool operator<=(GoodIter a) { return true; }
+  bool operator>=(GoodIter a) { return false; }
+  typedef int difference_type;
+  typedef std::random_access_iterator_tag iterator_category;
+};
+int operator-(GoodIter a, GoodIter b) { return 0; }
+GoodIter operator-(GoodIter a) { return a; }
+GoodIter operator-(GoodIter a, int v) { return GoodIter(); }
+GoodIter operator+(GoodIter a, int v) { return GoodIter(); }
+GoodIter operator-(int v, GoodIter a) { return GoodIter(); }
+GoodIter operator+(int v, GoodIter a) { return GoodIter(); }
+
+int test_with_random_access_iterator() {
+  GoodIter begin, end;
+  Iter0 begin0, end0;
+#pragma omp parallel
+#pragma omp for
+  for (GoodIter I = begin; I < end; ++I)
+    ++I;
+#pragma omp parallel
+// expected-error@+2 {{variable must be of integer or random access iterator type}}
+#pragma omp for
+  for (GoodIter &I = begin; I < end; ++I)
+    ++I;
+#pragma omp parallel
+#pragma omp for
+  for (GoodIter I = begin; I >= end; --I)
+    ++I;
+#pragma omp parallel
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp for
+  for (GoodIter I(begin); I < end; ++I)
+    ++I;
+#pragma omp parallel
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp for
+  for (GoodIter I(nullptr); I < end; ++I)
+    ++I;
+#pragma omp parallel
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp for
+  for (GoodIter I(0); I < end; ++I)
+    ++I;
+#pragma omp parallel
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp for
+  for (GoodIter I(1, 2); I < end; ++I)
+    ++I;
+#pragma omp parallel
+#pragma omp for
+  for (begin = GoodIter(0); begin < end; ++begin)
+    ++begin;
+#pragma omp parallel
+#pragma omp for
+  for (begin = begin0; begin < end; ++begin)
+    ++begin;
+#pragma omp parallel
+// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
+#pragma omp for
+  for (++begin; begin < end; ++begin)
+    ++begin;
+#pragma omp parallel
+#pragma omp for
+  for (begin = end; begin < end; ++begin)
+    ++begin;
+#pragma omp parallel
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+#pragma omp for
+  for (GoodIter I = begin; I - I; ++I)
+    ++I;
+#pragma omp parallel
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+#pragma omp for
+  for (GoodIter I = begin; begin < end; ++I)
+    ++I;
+#pragma omp parallel
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+#pragma omp for
+  for (GoodIter I = begin; !I; ++I)
+    ++I;
+#pragma omp parallel
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp for
+  for (GoodIter I = begin; I >= end; I = I + 1)
+    ++I;
+#pragma omp parallel
+#pragma omp for
+  for (GoodIter I = begin; I >= end; I = I - 1)
+    ++I;
+#pragma omp parallel
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}}
+#pragma omp for
+  for (GoodIter I = begin; I >= end; I = -I)
+    ++I;
+#pragma omp parallel
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp for
+  for (GoodIter I = begin; I >= end; I = 2 + I)
+    ++I;
+#pragma omp parallel
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}}
+#pragma omp for
+  for (GoodIter I = begin; I >= end; I = 2 - I)
+    ++I;
+#pragma omp parallel
+#pragma omp for
+  for (Iter0 I = begin0; I < end0; ++I)
+    ++I;
+#pragma omp parallel
+// Initializer is constructor without params.
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp for
+  for (Iter0 I; I < end0; ++I)
+    ++I;
+  Iter1 begin1, end1;
+#pragma omp parallel
+#pragma omp for
+  for (Iter1 I = begin1; I < end1; ++I)
+    ++I;
+#pragma omp parallel
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp for
+  for (Iter1 I = begin1; I >= end1; ++I)
+    ++I;
+#pragma omp parallel
+// Initializer is constructor with all default params.
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp for
+  for (Iter1 I; I < end1; ++I) {
+  }
+  return 0;
+}
+
+template <typename IT, int ST>
+class TC {
+public:
+  int dotest_lt(IT begin, IT end) {
+#pragma omp parallel
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}}
+#pragma omp for
+    for (IT I = begin; I < end; I = I + ST) {
+      ++I;
+    }
+#pragma omp parallel
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}}
+#pragma omp for
+    for (IT I = begin; I <= end; I += ST) {
+      ++I;
+    }
+#pragma omp parallel
+#pragma omp for
+    for (IT I = begin; I < end; ++I) {
+      ++I;
+    }
+  }
+
+  static IT step() {
+    return IT(ST);
+  }
+};
+template <typename IT, int ST = 0>
+int dotest_gt(IT begin, IT end) {
+#pragma omp parallel
+// expected-note@+3 2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp for
+  for (IT I = begin; I >= end; I = I + ST) {
+    ++I;
+  }
+#pragma omp parallel
+// expected-note@+3 2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp for
+  for (IT I = begin; I >= end; I += ST) {
+    ++I;
+  }
+
+#pragma omp parallel
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp for
+  for (IT I = begin; I >= end; ++I) {
+    ++I;
+  }
+
+#pragma omp parallel
+#pragma omp for
+  for (IT I = begin; I < end; I += TC<int, ST>::step()) {
+    ++I;
+  }
+}
+
+void test_with_template() {
+  GoodIter begin, end;
+  TC<GoodIter, 100> t1;
+  TC<GoodIter, -100> t2;
+  t1.dotest_lt(begin, end);
+  t2.dotest_lt(begin, end);         // expected-note {{in instantiation of member function 'TC<GoodIter, -100>::dotest_lt' requested here}}
+  dotest_gt(begin, end);            // expected-note {{in instantiation of function template specialization 'dotest_gt<GoodIter, 0>' requested here}}
+  dotest_gt<unsigned, -10>(0, 100); // expected-note {{in instantiation of function template specialization 'dotest_gt<unsigned int, -10>' requested here}}
+}
+
+void test_loop_break() {
+  const int N = 100;
+  float a[N], b[N], c[N];
+#pragma omp parallel
+#pragma omp for
+  for (int i = 0; i < 10; i++) {
+    c[i] = a[i] + b[i];
+    for (int j = 0; j < 10; ++j) {
+      if (a[i] > b[j])
+        break; // OK in nested loop
+    }
+    switch (i) {
+    case 1:
+      b[i]++;
+      break;
+    default:
+      break;
+    }
+    if (c[i] > 10)
+      break; // expected-error {{'break' statement cannot be used in OpenMP for loop}}
+
+    if (c[i] > 11)
+      break; // expected-error {{'break' statement cannot be used in OpenMP for loop}}
+  }
+
+#pragma omp parallel
+#pragma omp for
+  for (int i = 0; i < 10; i++) {
+    for (int j = 0; j < 10; j++) {
+      c[i] = a[i] + b[i];
+      if (c[i] > 10) {
+        if (c[i] < 20) {
+          break; // OK
+        }
+      }
+    }
+  }
+}
+
+void test_loop_eh() {
+  const int N = 100;
+  float a[N], b[N], c[N];
+#pragma omp parallel
+#pragma omp for
+  for (int i = 0; i < 10; i++) {
+    c[i] = a[i] + b[i];
+    try {
+      for (int j = 0; j < 10; ++j) {
+        if (a[i] > b[j])
+          throw a[i];
+      }
+      throw a[i];
+    } catch (float f) {
+      if (f > 0.1)
+        throw a[i];
+      return; // expected-error {{cannot return from OpenMP region}}
+    }
+    switch (i) {
+    case 1:
+      b[i]++;
+      break;
+    default:
+      break;
+    }
+    for (int j = 0; j < 10; j++) {
+      if (c[i] > 10)
+        throw c[i];
+    }
+  }
+  if (c[9] > 10)
+    throw c[9]; // OK
+
+#pragma omp parallel
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+    struct S {
+      void g() { throw 0; }
+    };
+  }
+}
+
+void test_loop_firstprivate_lastprivate() {
+  S s(4);
+#pragma omp parallel
+#pragma omp for lastprivate(s) firstprivate(s)
+  for (int i = 0; i < 16; ++i)
+    ;
+}
+
+void test_ordered() {
+#pragma omp parallel
+#pragma omp for ordered ordered // expected-error {{directive '#pragma omp for' cannot contain more than one 'ordered' clause}}
+  for (int i = 0; i < 16; ++i)
+    ;
+}
+
+void test_nowait() {
+#pragma omp parallel
+#pragma omp for nowait nowait // expected-error {{directive '#pragma omp for' cannot contain more than one 'nowait' clause}}
+  for (int i = 0; i < 16; ++i)
+    ;
+}
diff --git a/test/OpenMP/for_misc_messages.c b/test/OpenMP/for_misc_messages.c
new file mode 100644
index 0000000..854898c
--- /dev/null
+++ b/test/OpenMP/for_misc_messages.c
@@ -0,0 +1,363 @@
+// RUN: %clang_cc1 -fsyntax-only -fopenmp=libiomp5 -verify %s
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp for'}}
+#pragma omp for
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp for'}}
+#pragma omp for foo
+
+void test_no_clause() {
+  int i;
+#pragma omp for
+  for (i = 0; i < 16; ++i)
+    ;
+
+// expected-error@+2 {{statement after '#pragma omp for' must be a for loop}}
+#pragma omp for
+  ++i;
+}
+
+void test_branch_protected_scope() {
+  int i = 0;
+L1:
+  ++i;
+
+  int x[24];
+
+#pragma omp parallel
+#pragma omp for
+  for (i = 0; i < 16; ++i) {
+    if (i == 5)
+      goto L1; // expected-error {{use of undeclared label 'L1'}}
+    else if (i == 6)
+      return; // expected-error {{cannot return from OpenMP region}}
+    else if (i == 7)
+      goto L2;
+    else if (i == 8) {
+    L2:
+      x[i]++;
+    }
+  }
+
+  if (x[0] == 0)
+    goto L2; // expected-error {{use of undeclared label 'L2'}}
+  else if (x[1] == 1)
+    goto L1;
+}
+
+void test_invalid_clause() {
+  int i;
+#pragma omp parallel
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp for' are ignored}}
+#pragma omp for foo bar
+  for (i = 0; i < 16; ++i)
+    ;
+}
+
+void test_non_identifiers() {
+  int i, x;
+
+#pragma omp parallel
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp for' are ignored}}
+#pragma omp for;
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+2 {{unexpected OpenMP clause 'linear' in directive '#pragma omp for'}}
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp for' are ignored}}
+#pragma omp for linear(x);
+  for (i = 0; i < 16; ++i)
+    ;
+
+#pragma omp parallel
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp for' are ignored}}
+#pragma omp for private(x);
+  for (i = 0; i < 16; ++i)
+    ;
+
+#pragma omp parallel
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp for' are ignored}}
+#pragma omp for, private(x);
+  for (i = 0; i < 16; ++i)
+    ;
+}
+
+extern int foo();
+
+void test_collapse() {
+  int i;
+#pragma omp parallel
+// expected-error@+1 {{expected '('}}
+#pragma omp for collapse
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp for collapse(
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 {{expected expression}}
+#pragma omp for collapse()
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp for collapse(,
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 {{expected expression}}  expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp for collapse(, )
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-warning@+2 {{extra tokens at the end of '#pragma omp for' are ignored}}
+// expected-error@+1 {{expected '('}}
+#pragma omp for collapse 4)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp for collapse(4
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp for', but found only 1}}
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp for collapse(4,
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp for', but found only 1}}
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp for collapse(4, )
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp for', but found only 1}}
+#pragma omp parallel
+// expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp for collapse(4)
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp for', but found only 1}}
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp for collapse(4 4)
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp for', but found only 1}}
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp for collapse(4, , 4)
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp for', but found only 1}}
+#pragma omp parallel
+#pragma omp for collapse(4)
+  for (int i1 = 0; i1 < 16; ++i1)
+    for (int i2 = 0; i2 < 16; ++i2)
+      for (int i3 = 0; i3 < 16; ++i3)
+        for (int i4 = 0; i4 < 16; ++i4)
+          foo();
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp for collapse(4, 8)
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp for', but found only 1}}
+#pragma omp parallel
+// expected-error@+1 {{expression is not an integer constant expression}}
+#pragma omp for collapse(2.5)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 {{expression is not an integer constant expression}}
+#pragma omp for collapse(foo())
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}}
+#pragma omp for collapse(-5)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}}
+#pragma omp for collapse(0)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}}
+#pragma omp for collapse(5 - 5)
+  for (i = 0; i < 16; ++i)
+    ;
+}
+
+void test_private() {
+  int i;
+#pragma omp parallel
+// expected-error@+2 {{expected expression}}
+// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp for private(
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp for private(,
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 2 {{expected expression}}
+#pragma omp for private(, )
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 {{expected expression}}
+#pragma omp for private()
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 {{expected expression}}
+#pragma omp for private(int)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 {{expected variable name}}
+#pragma omp for private(0)
+  for (i = 0; i < 16; ++i)
+    ;
+
+  int x, y, z;
+#pragma omp parallel
+#pragma omp for private(x)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+#pragma omp for private(x, y)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+#pragma omp for private(x, y, z)
+  for (i = 0; i < 16; ++i) {
+    x = y * i + z;
+  }
+}
+
+void test_lastprivate() {
+  int i;
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 {{expected expression}}
+#pragma omp for lastprivate(
+  for (i = 0; i < 16; ++i)
+    ;
+
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp for lastprivate(,
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 2 {{expected expression}}
+#pragma omp for lastprivate(, )
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 {{expected expression}}
+#pragma omp for lastprivate()
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 {{expected expression}}
+#pragma omp for lastprivate(int)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 {{expected variable name}}
+#pragma omp for lastprivate(0)
+  for (i = 0; i < 16; ++i)
+    ;
+
+  int x, y, z;
+#pragma omp parallel
+#pragma omp for lastprivate(x)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+#pragma omp for lastprivate(x, y)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+#pragma omp for lastprivate(x, y, z)
+  for (i = 0; i < 16; ++i)
+    ;
+}
+
+void test_firstprivate() {
+  int i;
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 {{expected expression}}
+#pragma omp for firstprivate(
+  for (i = 0; i < 16; ++i)
+    ;
+
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp for firstprivate(,
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 2 {{expected expression}}
+#pragma omp for firstprivate(, )
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 {{expected expression}}
+#pragma omp for firstprivate()
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 {{expected expression}}
+#pragma omp for firstprivate(int)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+// expected-error@+1 {{expected variable name}}
+#pragma omp for firstprivate(0)
+  for (i = 0; i < 16; ++i)
+    ;
+
+  int x, y, z;
+#pragma omp parallel
+#pragma omp for lastprivate(x) firstprivate(x)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+#pragma omp for lastprivate(x, y) firstprivate(x, y)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel
+#pragma omp for lastprivate(x, y, z) firstprivate(x, y, z)
+  for (i = 0; i < 16; ++i)
+    ;
+}
+
+void test_loop_messages() {
+  float a[100], b[100], c[100];
+#pragma omp parallel
+// expected-error@+2 {{variable must be of integer or pointer type}}
+#pragma omp for
+  for (float fi = 0; fi < 10.0; fi++) {
+    c[(int)fi] = a[(int)fi] + b[(int)fi];
+  }
+#pragma omp parallel
+// expected-error@+2 {{variable must be of integer or pointer type}}
+#pragma omp for
+  for (double fi = 0; fi < 10.0; fi++) {
+    c[(int)fi] = a[(int)fi] + b[(int)fi];
+  }
+}
+
diff --git a/test/OpenMP/for_private_messages.cpp b/test/OpenMP/for_private_messages.cpp
new file mode 100644
index 0000000..f7a4979
--- /dev/null
+++ b/test/OpenMP/for_private_messages.cpp
@@ -0,0 +1,173 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+};
+const S2 b;
+const S2 ba[5];
+class S3 {
+  int a;
+
+public:
+  S3() : a(0) {}
+};
+const S3 ca[5];
+class S4 { // expected-note {{'S4' declared here}}
+  int a;
+  S4();
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note {{'S5' declared here}}
+  int a;
+  S5() : a(0) {}
+
+public:
+  S5(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(I argc, C **argv) {
+  I e(4);
+  I g(5);
+  int i;
+  int &j = i;           // expected-note {{'j' defined here}}
+#pragma omp for private // expected-error {{expected '(' after 'private'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private() // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(argc)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(e, g)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for shared(i) // expected-error {{unexpected OpenMP clause 'shared' in directive '#pragma omp for'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;
+#pragma omp for private(i)
+    for (int k = 0; k < argc; ++k) {
+      i = k;
+      v += i;
+    }
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp for private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(i)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  S4 e(4); // expected-note {{'e' defined here}}
+  S5 g(5); // expected-note {{'g' defined here}}
+  int i;
+  int &j = i;           // expected-note {{'j' defined here}}
+#pragma omp for private // expected-error {{expected '(' after 'private'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private() // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(argc)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(e, g) // expected-error 2 {{private variable must have an accessible, unambiguous default constructor}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for shared(i) // expected-error {{unexpected OpenMP clause 'shared' in directive '#pragma omp for'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+  {
+    int i;
+#pragma omp for private(i)
+    for (int k = 0; k < argc; ++k)
+      ++k;
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp for private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp for private(i)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+
+  return 0;
+}
+
diff --git a/test/OpenMP/for_reduction_messages.cpp b/test/OpenMP/for_reduction_messages.cpp
new file mode 100644
index 0000000..62fee52
--- /dev/null
+++ b/test/OpenMP/for_reduction_messages.cpp
@@ -0,0 +1,350 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+  S2 &operator+=(const S2 &arg) { return (*this); }
+
+public:
+  S2() : a(0) {}
+  S2(S2 &s2) : a(s2.a) {}
+  static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
+  static const float S2sc;
+};
+const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+S2 b;                     // expected-note 2 {{'b' defined here}}
+const S2 ba[5];           // expected-note 2 {{'ba' defined here}}
+class S3 {
+  int a;
+
+public:
+  S3() : a(0) {}
+  S3(const S3 &s3) : a(s3.a) {}
+  S3 operator+=(const S3 &arg1) { return arg1; }
+};
+int operator+=(const S3 &arg1, const S3 &arg2) { return 5; }
+S3 c;               // expected-note 2 {{'c' defined here}}
+const S3 ca[5];     // expected-note 2 {{'ca' defined here}}
+extern const int f; // expected-note 4 {{'f' declared here}}
+class S4 {          // expected-note {{'S4' declared here}}
+  int a;
+  S4();
+  S4(const S4 &s4);
+  S4 &operator+=(const S4 &arg) { return (*this); }
+
+public:
+  S4(int v) : a(v) {}
+};
+S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; }
+class S5 {
+  int a;
+  S5() : a(0) {}
+  S5(const S5 &s5) : a(s5.a) {}
+  S5 &operator+=(const S5 &arg);
+
+public:
+  S5(int v) : a(v) {}
+};
+class S6 {
+  int a;
+
+public:
+  S6() : a(6) {}
+  operator int() { return 6; }
+} o; // expected-note 2 {{'o' defined here}}
+
+S3 h, k;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class T>       // expected-note {{declared here}}
+T tmain(T argc) {        // expected-note 2 {{'argc' defined here}}
+  const T d = T();       // expected-note 4 {{'d' defined here}}
+  const T da[5] = {T()}; // expected-note 2 {{'da' defined here}}
+  T qa[5] = {T()};
+  T i;
+  T &j = i;                // expected-note 4 {{'j' defined here}}
+  S3 &p = k;               // expected-note 2 {{'p' defined here}}
+  const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}}
+  T &q = qa[(int)i];       // expected-note 2 {{'q' defined here}}
+  T fl;                    // expected-note {{'fl' defined here}}
+#pragma omp parallel
+#pragma omp for reduction // expected-error {{expected '(' after 'reduction'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp for' are ignored}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(&& : argc)
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(^ : T) // expected-error {{'T' does not refer to a value}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(max : qa[1]) // expected-error 2 {{expected variable name}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel private(k)
+#pragma omp for reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp for reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel private(fl)  // expected-note 2 {{defined as private}}
+#pragma omp for reduction(+ : fl) // expected-error 2 {{reduction variable must be shared}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel reduction(* : fl) // expected-note 2 {{defined as reduction}}
+#pragma omp for reduction(+ : fl)      // expected-error 2 {{reduction variable must be shared}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+
+  return T();
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;       // expected-note 2 {{'d' defined here}}
+  const int da[5] = {0}; // expected-note {{'da' defined here}}
+  int qa[5] = {0};
+  S4 e(4); // expected-note {{'e' defined here}}
+  S5 g(5); // expected-note {{'g' defined here}}
+  int i;
+  int &j = i;           // expected-note 2 {{'j' defined here}}
+  S3 &p = k;            // expected-note 2 {{'p' defined here}}
+  const int &r = da[i]; // expected-note {{'r' defined here}}
+  int &q = qa[i];       // expected-note {{'q' defined here}}
+  float fl;             // expected-note {{'fl' defined here}}
+#pragma omp parallel
+#pragma omp for reduction // expected-error {{expected '(' after 'reduction'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp for' are ignored}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(foo : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(~ : argc) // expected-error {{expected unqualified-id}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(&& : argc)
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(max : argv[1]) // expected-error {{expected variable name}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(& : e, g) // expected-error {{reduction variable must have an accessible, unambiguous default constructor}} expected-error {{variable of type 'S5' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for private(i), reduction(+ : j), reduction(+ : q) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel private(k)
+#pragma omp for reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp for reduction(max : j) // expected-error {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel private(fl)  // expected-note {{defined as private}}
+#pragma omp for reduction(+ : fl) // expected-error {{reduction variable must be shared}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel reduction(* : fl) // expected-note {{defined as reduction}}
+#pragma omp for reduction(+ : fl)      // expected-error {{reduction variable must be shared}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+
+  return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain<int>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<float>' requested here}}
+}
diff --git a/test/OpenMP/for_schedule_messages.cpp b/test/OpenMP/for_schedule_messages.cpp
new file mode 100644
index 0000000..be4ff4f
--- /dev/null
+++ b/test/OpenMP/for_schedule_messages.cpp
@@ -0,0 +1,91 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, typename S, int N, int ST> // expected-note {{declared here}}
+T tmain(T argc, S **argv) {
+  #pragma omp for schedule // expected-error {{expected '(' after 'schedule'}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for schedule (auto // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for schedule (auto,  // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for schedule (runtime, 3)  // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  // expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+  #pragma omp for schedule (guided argc
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  // expected-error@+1 2 {{argument to 'schedule' clause must be a positive integer value}}
+  #pragma omp for schedule (static, ST // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for schedule (dynamic, 1)) // expected-warning {{extra tokens at the end of '#pragma omp for' are ignored}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for schedule (guided, (ST > 0) ? 1 + ST : 2)
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  // expected-error@+2 2 {{directive '#pragma omp for' cannot contain more than one 'schedule' clause}}
+  // expected-error@+1 {{argument to 'schedule' clause must be a positive integer value}}
+  #pragma omp for schedule (static, foobool(argc)), schedule (dynamic, true), schedule (guided, -5)
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for schedule (static, S) // expected-error {{'S' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp for' are ignored}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  // expected-error@+1 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  #pragma omp for schedule (guided, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for schedule (dynamic, 1)
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp for schedule (static, N) // expected-error {{argument to 'schedule' clause must be a positive integer value}}
+  for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  return argc;
+}
+
+int main(int argc, char **argv) {
+  #pragma omp for schedule // expected-error {{expected '(' after 'schedule'}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp for schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp for schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp for schedule (auto // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp for schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp for schedule (auto,  // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp for schedule (runtime, 3)  // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp for schedule (guided, 4 // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp for schedule (static, 2+2)) // expected-warning {{extra tokens at the end of '#pragma omp for' are ignored}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp for schedule (dynamic, foobool(1) > 0 ? 1 : 2)
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  // expected-error@+2 2 {{directive '#pragma omp for' cannot contain more than one 'schedule' clause}}
+  // expected-error@+1 {{argument to 'schedule' clause must be a positive integer value}}
+  #pragma omp for schedule (guided, foobool(argc)), schedule (static, true), schedule (dynamic, -5)
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp for schedule (guided, S1) // expected-error {{'S1' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp for' are ignored}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  // expected-error@+1 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  #pragma omp for schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  // expected-error@+3 {{statement after '#pragma omp for' must be a for loop}}
+  // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
+  #pragma omp for schedule(dynamic, schedule(tmain<int, char, -1, -2>(argc, argv) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+  // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}}
+  return tmain<int, char, 1, 0>(argc, argv);
+}
+
diff --git a/test/OpenMP/linking.c b/test/OpenMP/linking.c
index 31fd57d..979ba1f 100644
--- a/test/OpenMP/linking.c
+++ b/test/OpenMP/linking.c
@@ -1,5 +1,5 @@
 // Test the that the driver produces reasonable linker invocations with
-// -fopenmp.
+// -fopenmp or -fopenmp=libiomp5|libgomp.
 //
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     -fopenmp -target i386-unknown-linux \
@@ -14,3 +14,58 @@
 // CHECK-LD-64: "{{.*}}ld{{(.exe)?}}"
 // CHECK-LD-64: "-lgomp" "-lrt" "-lgcc"
 // CHECK-LD-64: "-lpthread" "-lc"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     -fopenmp=libgomp -target i386-unknown-linux \
+// 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: "-lpthread" "-lc"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     -fopenmp=libgomp -target x86_64-unknown-linux \
+// 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: "-lpthread" "-lc"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     -fopenmp=libiomp5 -target i386-unknown-linux \
+// RUN:   | FileCheck --check-prefix=CHECK-IOMP5-LD-32 %s
+// CHECK-IOMP5-LD-32: "{{.*}}ld{{(.exe)?}}"
+// CHECK-IOMP5-LD-32: "-liomp5" "-lgcc"
+// CHECK-IOMP5-LD-32: "-lpthread" "-lc"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     -fopenmp=libiomp5 -target x86_64-unknown-linux \
+// RUN:   | FileCheck --check-prefix=CHECK-IOMP5-LD-64 %s
+// CHECK-IOMP5-LD-64: "{{.*}}ld{{(.exe)?}}"
+// CHECK-IOMP5-LD-64: "-liomp5" "-lgcc"
+// CHECK-IOMP5-LD-64: "-lpthread" "-lc"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     -fopenmp=lib -target i386-unknown-linux \
+// RUN:   | FileCheck --check-prefix=CHECK-LIB-LD-32 %s
+// CHECK-LIB-LD-32: error: unsupported argument 'lib' to option 'fopenmp='
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     -fopenmp=lib -target x86_64-unknown-linux \
+// RUN:   | FileCheck --check-prefix=CHECK-LIB-LD-64 %s
+// CHECK-LIB-LD-64: error: unsupported argument 'lib' to option 'fopenmp='
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     -fopenmp -fopenmp=libiomp5 -target i386-unknown-linux \
+// RUN:   | FileCheck --check-prefix=CHECK-LD-WARN-32 %s
+// CHECK-LD-WARN-32: warning: argument unused during compilation: '-fopenmp=libiomp5'
+// CHECK-LD-WARN-32: "{{.*}}ld{{(.exe)?}}"
+// CHECK-LD-WARN-32: "-lgomp" "-lrt" "-lgcc"
+// CHECK-LD-WARN-32: "-lpthread" "-lc"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     -fopenmp -fopenmp=libiomp5 -target x86_64-unknown-linux \
+// RUN:   | FileCheck --check-prefix=CHECK-LD-WARN-64 %s
+// CHECK-LD-WARN-64: warning: argument unused during compilation: '-fopenmp=libiomp5'
+// CHECK-LD-WARN-64: "{{.*}}ld{{(.exe)?}}"
+// CHECK-LD-WARN-64: "-lgomp" "-lrt" "-lgcc"
+// CHECK-LD-WARN-64: "-lpthread" "-lc"
+//
diff --git a/test/OpenMP/master_ast_print.cpp b/test/OpenMP/master_ast_print.cpp
new file mode 100644
index 0000000..7ce4c10
--- /dev/null
+++ b/test/OpenMP/master_ast_print.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+void foo() {}
+
+int main (int argc, char **argv) {
+  int b = argc, c, d, e, f, g;
+  static int a;
+// CHECK: static int a;
+#pragma omp parallel
+{
+#pragma omp master
+{
+  a=2;
+}
+}
+// CHECK-NEXT: #pragma omp parallel
+// CHECK-NEXT: {
+// CHECK-NEXT: #pragma omp master
+// CHECK-NEXT: {
+// CHECK-NEXT: a = 2;
+// CHECK-NEXT: }
+// CHECK-NEXT: }
+  return (0);
+}
+
+#endif
diff --git a/test/OpenMP/master_messages.cpp b/test/OpenMP/master_messages.cpp
new file mode 100644
index 0000000..fbe35ac
--- /dev/null
+++ b/test/OpenMP/master_messages.cpp
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+int foo();
+
+int main() {
+  #pragma omp master
+  ;
+  #pragma omp master nowait // expected-error {{unexpected OpenMP clause 'nowait' in directive '#pragma omp master'}}
+  #pragma omp master unknown // expected-warning {{extra tokens at the end of '#pragma omp master' are ignored}}
+  foo();
+  {
+    #pragma omp master
+  } // expected-error {{expected statement}}
+  #pragma omp for
+  for (int i = 0; i < 10; ++i) {
+    foo();
+    #pragma omp master // expected-error {{region cannot be closely nested inside 'for' region}}
+    foo();
+  }
+  #pragma omp sections
+  {
+    foo();
+    #pragma omp master // expected-error {{region cannot be closely nested inside 'sections' region}}
+    foo();
+  }
+  #pragma omp single
+  for (int i = 0; i < 10; ++i) {
+    foo();
+    #pragma omp master // expected-error {{region cannot be closely nested inside 'single' region}}
+    foo();
+  }
+  #pragma omp master
+  for (int i = 0; i < 10; ++i) {
+    foo();
+    #pragma omp master
+    foo();
+  }
+  #pragma omp for ordered
+  for (int i = 0; i < 10; ++i)
+  #pragma omp master // expected-error {{region cannot be closely nested inside 'for' region}}
+  {
+    foo();
+  }
+
+  return 0;
+}
+
+int foo() {
+  L1:
+    foo();
+  #pragma omp master
+  {
+    foo();
+    goto L1; // expected-error {{use of undeclared label 'L1'}}
+  }
+  goto L2; // expected-error {{use of undeclared label 'L2'}}
+  #pragma omp master
+  {
+    L2:
+    foo();
+  }
+
+  return 0;
+}
diff --git a/test/OpenMP/nesting_of_regions.cpp b/test/OpenMP/nesting_of_regions.cpp
new file mode 100644
index 0000000..d8dcec5
--- /dev/null
+++ b/test/OpenMP/nesting_of_regions.cpp
@@ -0,0 +1,2278 @@
+// RUN: %clang_cc1 -fsyntax-only -fopenmp=libiomp5 -verify %s
+
+void bar();
+
+template <class T>
+void foo() {
+// PARALLEL DIRECTIVE
+#pragma omp parallel
+#pragma omp for
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp parallel
+#pragma omp simd
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp parallel
+#pragma omp sections
+  {
+    bar();
+  }
+#pragma omp parallel
+#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a parallel region}}
+  {
+    bar();
+  }
+#pragma omp parallel
+#pragma omp single
+  bar();
+
+#pragma omp parallel
+#pragma omp master
+  {
+    bar();
+  }
+#pragma omp parallel
+#pragma omp critical
+  {
+    bar();
+  }
+#pragma omp parallel
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp parallel
+#pragma omp parallel sections
+  {
+    bar();
+  }
+#pragma omp parallel
+#pragma omp task
+  {
+    bar();
+  }
+#pragma omp parallel
+  {
+#pragma omp taskyield
+    bar();
+  }
+#pragma omp parallel
+  {
+#pragma omp barrier
+    bar();
+  }
+#pragma omp parallel
+  {
+#pragma omp taskwait
+    bar();
+  }
+#pragma omp parallel
+  {
+#pragma omp flush
+    bar();
+  }
+
+// SIMD DIRECTIVE
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp sections // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    {
+      bar();
+    }
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp section // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    {
+      bar();
+    }
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp single // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    {
+      bar();
+    }
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp master // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    {
+      bar();
+    }
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp critical // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    {
+      bar();
+    }
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel sections // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    {
+      bar();
+    }
+  }
+#pragma omp 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 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 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 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 simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp flush // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    bar();
+  }
+
+// FOR DIRECTIVE
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp simd
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a for region}}
+    {
+      bar();
+    }
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp single // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp master // expected-error {{region cannot be closely nested inside 'for' region}}
+    {
+      bar();
+    }
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp critical 
+    {
+      bar();
+    }
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel
+    {
+#pragma omp single // OK
+      {
+        bar();
+      }
+#pragma omp for // OK
+      for (int i = 0; i < 10; ++i)
+        ;
+#pragma omp sections // OK
+      {
+        bar();
+      }
+    }
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel sections
+    {
+      bar();
+    }
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp task
+    {
+      bar();
+    }
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp taskyield
+    bar();
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp barrier // expected-error {{region cannot be closely nested inside 'for' region}}
+    bar();
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp taskwait
+    bar();
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp flush
+    bar();
+  }
+
+// SECTIONS DIRECTIVE
+#pragma omp sections
+  {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp sections
+  {
+#pragma omp simd
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp sections
+  {
+#pragma omp parallel
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp sections
+  {
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp section
+    {
+      bar();
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp parallel
+    {
+#pragma omp single // OK
+      {
+        bar();
+      }
+#pragma omp for // OK
+      for (int i = 0; i < 10; ++i)
+        ;
+#pragma omp sections // OK
+      {
+        bar();
+      }
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp parallel
+    {
+#pragma omp master // OK
+      {
+        bar();
+      }
+#pragma omp for // OK
+      for (int i = 0; i < 10; ++i)
+        ;
+#pragma omp master // OK
+      {
+        bar();
+      }
+    }
+#pragma omp master // expected-error {{region cannot be closely nested inside 'sections' region}}
+    bar();
+  }
+#pragma omp sections
+  {
+#pragma omp parallel
+    {
+#pragma omp critical(A) // OK
+      {
+        bar();
+      }
+#pragma omp for // OK
+      for (int i = 0; i < 10; ++i)
+        ;
+#pragma omp critical // OK
+      {
+        bar();
+      }
+    }
+#pragma omp critical(A) // expected-error {{statement in 'omp sections' directive must be enclosed into a section region}}
+    bar();
+  }
+#pragma omp sections
+  {
+#pragma omp parallel for
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp sections
+  {
+#pragma omp parallel sections
+    {
+      bar();
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp task
+    {
+      bar();
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp taskyield
+  }
+#pragma omp sections
+  {
+#pragma omp barrier // expected-error {{region cannot be closely nested inside 'sections' region}}
+  }
+#pragma omp sections
+  {
+#pragma omp taskwait
+  }
+#pragma omp sections
+  {
+#pragma omp flush
+  }
+
+// SECTION DIRECTIVE
+#pragma omp section // expected-error {{orphaned 'omp section' directives are prohibited, it must be closely nested to a sections region}}
+  {
+    bar();
+  }
+#pragma omp sections
+  {
+#pragma omp section
+    {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+      for (int i = 0; i < 10; ++i)
+        ;
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp section
+    {
+#pragma omp simd
+      for (int i = 0; i < 10; ++i)
+        ;
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp section
+    {
+#pragma omp parallel
+      for (int i = 0; i < 10; ++i)
+        ;
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp section
+    {
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+      {
+        bar();
+      }
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp section
+    {
+#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a section region}}
+      {
+        bar();
+      }
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp section
+    {
+#pragma omp single // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+      bar();
+#pragma omp master // expected-error {{region cannot be closely nested inside 'section' region}}
+      bar();
+#pragma omp critical
+      bar();
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp section
+    {
+#pragma omp parallel
+      {
+#pragma omp single // OK
+        {
+          bar();
+        }
+#pragma omp for // OK
+        for (int i = 0; i < 10; ++i)
+          ;
+#pragma omp sections // OK
+        {
+          bar();
+        }
+      }
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp section
+    {
+#pragma omp parallel for
+      for (int i = 0; i < 10; ++i)
+        ;
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp section
+    {
+#pragma omp parallel sections
+      {
+        bar();
+      }
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp section
+    {
+#pragma omp task
+      {
+        bar();
+      }
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp section
+    {
+#pragma omp taskyield
+      bar();
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp section
+    {
+#pragma omp barrier // expected-error {{region cannot be closely nested inside 'section' region}}
+      bar();
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp section
+    {
+#pragma omp taskwait
+      bar();
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp section
+    {
+#pragma omp flush
+      bar();
+    }
+  }
+
+// SINGLE DIRECTIVE
+#pragma omp single
+  {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp single
+  {
+#pragma omp simd
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp single
+  {
+#pragma omp parallel
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp single
+  {
+#pragma omp single // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp single
+  {
+#pragma omp master // expected-error {{region cannot be closely nested inside 'single' region}}
+    {
+      bar();
+    }
+  }
+#pragma omp single
+  {
+#pragma omp critical
+    {
+      bar();
+    }
+  }
+#pragma omp single
+  {
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp single
+  {
+#pragma omp parallel
+    {
+#pragma omp single // OK
+      {
+        bar();
+      }
+#pragma omp for // OK
+      for (int i = 0; i < 10; ++i)
+        ;
+#pragma omp sections // OK
+      {
+        bar();
+      }
+    }
+  }
+#pragma omp single
+  {
+#pragma omp parallel for
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp single
+  {
+#pragma omp parallel sections
+    {
+      bar();
+    }
+  }
+#pragma omp single
+  {
+#pragma omp task
+    {
+      bar();
+    }
+  }
+#pragma omp single
+  {
+#pragma omp taskyield
+    bar();
+  }
+#pragma omp single
+  {
+#pragma omp barrier // expected-error {{region cannot be closely nested inside 'single' region}}
+    bar();
+  }
+#pragma omp single
+  {
+#pragma omp taskwait
+    bar();
+  }
+#pragma omp single
+  {
+#pragma omp flush
+    bar();
+  }
+
+// MASTER DIRECTIVE
+#pragma omp master
+  {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp master
+  {
+#pragma omp simd
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp master
+  {
+#pragma omp parallel
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp master
+  {
+#pragma omp single // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp master
+  {
+#pragma omp master // OK, though second 'master' is redundant
+    {
+      bar();
+    }
+  }
+#pragma omp master
+  {
+#pragma omp critical
+    {
+      bar();
+    }
+  }
+#pragma omp master
+  {
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp master
+  {
+#pragma omp parallel
+    {
+#pragma omp master // OK
+      {
+        bar();
+      }
+#pragma omp for // OK
+      for (int i = 0; i < 10; ++i)
+        ;
+#pragma omp sections // OK
+      {
+        bar();
+      }
+    }
+  }
+#pragma omp master
+  {
+#pragma omp parallel for
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp master
+  {
+#pragma omp parallel sections
+    {
+      bar();
+    }
+  }
+#pragma omp master
+  {
+#pragma omp task
+    {
+      bar();
+    }
+  }
+#pragma omp master
+  {
+#pragma omp taskyield
+    bar();
+  }
+#pragma omp master
+  {
+#pragma omp barrier // expected-error {{region cannot be closely nested inside 'master' region}}
+    bar();
+  }
+#pragma omp master
+  {
+#pragma omp taskwait
+    bar();
+  }
+#pragma omp master
+  {
+#pragma omp flush
+    bar();
+  }
+
+// CRITICAL DIRECTIVE
+#pragma omp critical
+  {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp critical
+  {
+#pragma omp simd
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp critical
+  {
+#pragma omp parallel
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp critical
+  {
+#pragma omp single // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp critical
+  {
+#pragma omp master // OK, though second 'master' is redundant
+    {
+      bar();
+    }
+  }
+#pragma omp critical
+  {
+#pragma omp critical
+    {
+      bar();
+    }
+  }
+#pragma omp critical
+  {
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp critical
+  {
+#pragma omp parallel
+    {
+#pragma omp master // OK
+      {
+        bar();
+      }
+#pragma omp for // OK
+      for (int i = 0; i < 10; ++i)
+        ;
+#pragma omp sections // OK
+      {
+        bar();
+      }
+    }
+  }
+#pragma omp critical
+  {
+#pragma omp parallel for
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp critical
+  {
+#pragma omp parallel sections
+    {
+      bar();
+    }
+  }
+#pragma omp critical
+  {
+#pragma omp task
+    {
+      bar();
+    }
+  }
+#pragma omp critical
+  {
+#pragma omp taskyield
+    bar();
+  }
+#pragma omp critical
+  {
+#pragma omp barrier // expected-error {{region cannot be closely nested inside 'critical' region}}
+    bar();
+  }
+#pragma omp critical
+  {
+#pragma omp taskwait
+    bar();
+  }
+#pragma omp critical(Tuzik)
+  {
+#pragma omp critical(grelka)
+    bar();
+  }
+#pragma omp critical(Belka)// expected-note {{previous 'critical' region starts here}}
+  {
+#pragma omp critical(Belka) // expected-error {{cannot nest 'critical' regions having the same name 'Belka'}}
+    {
+#pragma omp critical(Tuzik)
+      {
+#pragma omp parallel
+#pragma omp critical(grelka)
+        {
+          bar();
+        }
+      }
+    }
+  }
+
+// PARALLEL FOR DIRECTIVE
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp simd
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a parallel for region}}
+    {
+      bar();
+    }
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp single // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp master // expected-error {{region cannot be closely nested inside 'parallel for' region}}
+    {
+      bar();
+    }
+  }
+
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp critical
+    {
+      bar();
+    }
+  }
+
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel
+    {
+#pragma omp single // OK
+      {
+        bar();
+      }
+#pragma omp for // OK
+      for (int i = 0; i < 10; ++i)
+        ;
+#pragma omp sections // OK
+      {
+        bar();
+      }
+    }
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel sections
+    {
+      bar();
+    }
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp task
+    {
+      bar();
+    }
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp taskyield
+    bar();
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp barrier // expected-error {{region cannot be closely nested inside 'parallel for' region}}
+    bar();
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp taskwait
+    bar();
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp flush
+    bar();
+  }
+
+// PARALLEL SECTIONS DIRECTIVE
+#pragma omp parallel sections
+  {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'parallel sections' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel sections
+  {
+#pragma omp simd
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel sections
+  {
+#pragma omp parallel
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel sections
+  {
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'parallel sections' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp parallel sections
+  {
+#pragma omp section
+    {
+      bar();
+    }
+  }
+#pragma omp parallel sections
+  {
+#pragma omp section
+    {
+#pragma omp single // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+      bar();
+    }
+  }
+#pragma omp parallel sections
+  {
+#pragma omp section
+    {
+#pragma omp master // expected-error {{region cannot be closely nested inside 'section' region}}
+      bar();
+    }
+  }
+#pragma omp parallel sections
+  {
+#pragma omp section
+    {
+#pragma omp critical
+      bar();
+    }
+  }
+#pragma omp parallel sections
+  {
+#pragma omp parallel
+    {
+#pragma omp single // OK
+      {
+        bar();
+      }
+#pragma omp for // OK
+      for (int i = 0; i < 10; ++i)
+        ;
+#pragma omp sections // OK
+      {
+        bar();
+      }
+    }
+  }
+#pragma omp parallel sections
+  {
+#pragma omp parallel for
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel sections
+  {
+#pragma omp parallel sections
+    {
+      bar();
+    }
+  }
+#pragma omp parallel sections
+  {
+#pragma omp task
+    {
+      bar();
+    }
+  }
+#pragma omp parallel sections
+  {
+#pragma omp taskyield
+  }
+#pragma omp parallel sections
+  {
+#pragma omp barrier // expected-error {{region cannot be closely nested inside 'parallel sections' region}}
+  }
+#pragma omp parallel sections
+  {
+#pragma omp taskwait
+  }
+#pragma omp parallel sections
+  {
+#pragma omp flush
+  }
+
+// TASK DIRECTIVE
+#pragma omp task
+#pragma omp for // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp task
+#pragma omp simd
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp task
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+  {
+    bar();
+  }
+#pragma omp task
+#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a task region}}
+  {
+    bar();
+  }
+#pragma omp task
+#pragma omp single // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+  bar();
+#pragma omp task
+#pragma omp master // expected-error {{region cannot be closely nested inside 'task' region}}
+  bar();
+#pragma omp task
+#pragma omp critical
+  bar();
+
+#pragma omp task
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp task
+#pragma omp parallel sections
+  {
+    bar();
+  }
+#pragma omp task
+#pragma omp task
+  {
+    bar();
+  }
+#pragma omp task
+  {
+#pragma omp taskyield
+    bar();
+  }
+#pragma omp task
+  {
+#pragma omp barrier // expected-error {{region cannot be closely nested inside 'task' region}}
+    bar();
+  }
+#pragma omp task
+  {
+#pragma omp taskwait
+    bar();
+  }
+#pragma omp task
+  {
+#pragma omp flush
+    bar();
+  }
+}
+
+void foo() {
+// PARALLEL DIRECTIVE
+#pragma omp parallel
+#pragma omp for
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp parallel
+#pragma omp simd
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp parallel
+#pragma omp sections
+  {
+    bar();
+  }
+#pragma omp parallel
+#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a parallel region}}
+  {
+    bar();
+  }
+#pragma omp parallel
+#pragma omp sections
+  {
+    bar();
+  }
+#pragma omp parallel
+#pragma omp single
+  bar();
+#pragma omp parallel
+#pragma omp master
+  bar();
+#pragma omp parallel
+#pragma omp critical
+  bar();
+#pragma omp parallel
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp parallel
+#pragma omp parallel sections
+  {
+    bar();
+  }
+#pragma omp parallel
+#pragma omp task
+  {
+    bar();
+  }
+#pragma omp parallel
+  {
+#pragma omp taskyield
+    bar();
+  }
+#pragma omp parallel
+  {
+#pragma omp barrier
+    bar();
+  }
+#pragma omp parallel
+  {
+#pragma omp taskwait
+    bar();
+  }
+#pragma omp parallel
+  {
+#pragma omp flush
+    bar();
+  }
+
+// SIMD DIRECTIVE
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp sections // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    {
+      bar();
+    }
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp section // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    {
+      bar();
+    }
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp single // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    bar();
+#pragma omp master // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    bar();
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp single // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    bar();
+#pragma omp critical // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    bar();
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel sections // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    {
+      bar();
+    }
+  }
+#pragma omp 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 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 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 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 simd
+  for (int i = 0; i < 10; ++i) {
+#pragma omp flush // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+    bar();
+  }
+
+// FOR DIRECTIVE
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp simd
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a for region}}
+    {
+      bar();
+    }
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp single // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+    bar();
+#pragma omp master // expected-error {{region cannot be closely nested inside 'for' region}}
+    bar();
+#pragma omp critical
+    bar();
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel
+    {
+#pragma omp single // OK
+      {
+        bar();
+      }
+#pragma omp for // OK
+      for (int i = 0; i < 10; ++i)
+        ;
+#pragma omp sections // OK
+      {
+        bar();
+      }
+    }
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel sections
+    {
+      bar();
+    }
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp task
+    {
+      bar();
+    }
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp taskyield
+    bar();
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp barrier // expected-error {{region cannot be closely nested inside 'for' region}}
+    bar();
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp taskwait
+    bar();
+  }
+#pragma omp for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp flush
+    bar();
+  }
+
+// SECTIONS DIRECTIVE
+#pragma omp sections
+  {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp sections
+  {
+#pragma omp simd
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp sections
+  {
+#pragma omp parallel
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp sections
+  {
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp section
+    {
+      bar();
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp critical
+    bar();
+#pragma omp single // expected-error {{region cannot be closely nested inside 'sections' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+    bar();
+#pragma omp master // expected-error {{region cannot be closely nested inside 'sections' region}}
+    bar();
+  }
+#pragma omp sections
+  {
+#pragma omp parallel
+    {
+#pragma omp single // OK
+      {
+        bar();
+      }
+#pragma omp for // OK
+      for (int i = 0; i < 10; ++i)
+        ;
+#pragma omp sections // OK
+      {
+        bar();
+      }
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp parallel for
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp sections
+  {
+#pragma omp parallel sections
+    {
+      bar();
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp task
+    {
+      bar();
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp taskyield
+  }
+#pragma omp sections
+  {
+#pragma omp barrier // expected-error {{region cannot be closely nested inside 'sections' region}}
+    bar();
+  }
+#pragma omp sections
+  {
+#pragma omp taskwait
+  }
+#pragma omp sections
+  {
+#pragma omp flush
+  }
+
+// SECTION DIRECTIVE
+#pragma omp section // expected-error {{orphaned 'omp section' directives are prohibited, it must be closely nested to a sections region}}
+  {
+    bar();
+  }
+#pragma omp sections
+  {
+#pragma omp section
+    {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+      for (int i = 0; i < 10; ++i)
+        ;
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp section
+    {
+#pragma omp simd
+      for (int i = 0; i < 10; ++i)
+        ;
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp section
+    {
+#pragma omp parallel
+      for (int i = 0; i < 10; ++i)
+        ;
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp section
+    {
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+      {
+        bar();
+      }
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp section
+    {
+#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a section region}}
+      {
+        bar();
+      }
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp section
+    {
+#pragma omp single // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+      bar();
+#pragma omp master // expected-error {{region cannot be closely nested inside 'section' region}}
+      bar();
+#pragma omp critical
+      bar();
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp section
+    {
+#pragma omp parallel
+      {
+#pragma omp single // OK
+        {
+          bar();
+        }
+#pragma omp for // OK
+        for (int i = 0; i < 10; ++i)
+          ;
+#pragma omp sections // OK
+        {
+          bar();
+        }
+      }
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp section
+    {
+#pragma omp parallel for
+      for (int i = 0; i < 10; ++i)
+        ;
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp section
+    {
+#pragma omp parallel sections
+      {
+        bar();
+      }
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp section
+    {
+#pragma omp task
+      {
+        bar();
+      }
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp section
+    {
+#pragma omp taskyield
+      bar();
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp section
+    {
+#pragma omp barrier // expected-error {{region cannot be closely nested inside 'section' region}}
+      bar();
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp section
+    {
+#pragma omp taskwait
+      bar();
+    }
+  }
+#pragma omp sections
+  {
+#pragma omp section
+    {
+#pragma omp flush
+      bar();
+    }
+  }
+
+// SINGLE DIRECTIVE
+#pragma omp single
+  {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp single
+  {
+#pragma omp simd
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp single
+  {
+#pragma omp parallel
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp single
+  {
+#pragma omp single // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+    {
+      bar();
+    }
+#pragma omp master // expected-error {{region cannot be closely nested inside 'single' region}}
+    bar();
+#pragma omp critical
+    bar();
+  }
+#pragma omp single
+  {
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'single' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp single
+  {
+#pragma omp parallel
+    {
+#pragma omp single // OK
+      {
+        bar();
+      }
+#pragma omp for // OK
+      for (int i = 0; i < 10; ++i)
+        ;
+#pragma omp sections // OK
+      {
+        bar();
+      }
+    }
+  }
+#pragma omp single
+  {
+#pragma omp parallel for
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp single
+  {
+#pragma omp parallel sections
+    {
+      bar();
+    }
+  }
+#pragma omp single
+  {
+#pragma omp task
+    {
+      bar();
+    }
+  }
+#pragma omp single
+  {
+#pragma omp taskyield
+    bar();
+  }
+#pragma omp single
+  {
+#pragma omp barrier // expected-error {{region cannot be closely nested inside 'single' region}}
+    bar();
+  }
+#pragma omp single
+  {
+#pragma omp taskwait
+    bar();
+  }
+#pragma omp single
+  {
+#pragma omp flush
+    bar();
+  }
+
+// MASTER DIRECTIVE
+#pragma omp master
+  {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp master
+  {
+#pragma omp simd
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp master
+  {
+#pragma omp parallel
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp master
+  {
+#pragma omp single // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp master
+  {
+#pragma omp master // OK, though second 'master' is redundant
+    {
+      bar();
+    }
+  }
+#pragma omp master
+  {
+#pragma omp critical
+    {
+      bar();
+    }
+  }
+#pragma omp master
+  {
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'master' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp master
+  {
+#pragma omp parallel
+    {
+#pragma omp master // OK
+      {
+        bar();
+      }
+#pragma omp for // OK
+      for (int i = 0; i < 10; ++i)
+        ;
+#pragma omp sections // OK
+      {
+        bar();
+      }
+    }
+  }
+#pragma omp master
+  {
+#pragma omp parallel for
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp master
+  {
+#pragma omp parallel sections
+    {
+      bar();
+    }
+  }
+#pragma omp master
+  {
+#pragma omp task
+    {
+      bar();
+    }
+  }
+#pragma omp master
+  {
+#pragma omp taskyield
+    bar();
+  }
+#pragma omp master
+  {
+#pragma omp barrier // expected-error {{region cannot be closely nested inside 'master' region}}
+    bar();
+  }
+#pragma omp master
+  {
+#pragma omp taskwait
+    bar();
+  }
+#pragma omp master
+  {
+#pragma omp flush
+    bar();
+  }
+
+// CRITICAL DIRECTIVE
+#pragma omp critical
+  {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp critical
+  {
+#pragma omp simd
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp critical
+  {
+#pragma omp parallel
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp critical
+  {
+#pragma omp single // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp critical
+  {
+#pragma omp master // OK, though second 'master' is redundant
+    {
+      bar();
+    }
+  }
+#pragma omp critical
+  {
+#pragma omp critical
+    {
+      bar();
+    }
+  }
+#pragma omp critical
+  {
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'critical' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp critical
+  {
+#pragma omp parallel
+    {
+#pragma omp master // OK
+      {
+        bar();
+      }
+#pragma omp for // OK
+      for (int i = 0; i < 10; ++i)
+        ;
+#pragma omp sections // OK
+      {
+        bar();
+      }
+    }
+  }
+#pragma omp critical
+  {
+#pragma omp parallel for
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp critical
+  {
+#pragma omp parallel sections
+    {
+      bar();
+    }
+  }
+#pragma omp critical
+  {
+#pragma omp task
+    {
+      bar();
+    }
+  }
+#pragma omp critical
+  {
+#pragma omp taskyield
+    bar();
+  }
+#pragma omp critical
+  {
+#pragma omp barrier // expected-error {{region cannot be closely nested inside 'critical' region}}
+    bar();
+  }
+#pragma omp critical
+  {
+#pragma omp taskwait
+    bar();
+  }
+#pragma omp critical(Belka)
+  {
+#pragma omp critical(Strelka)
+    bar();
+  }
+#pragma omp critical(Tuzik)// expected-note {{previous 'critical' region starts here}}
+  {
+#pragma omp critical(grelka) // expected-note {{previous 'critical' region starts here}}
+    {
+#pragma omp critical(Tuzik) // expected-error {{cannot nest 'critical' regions having the same name 'Tuzik'}}
+      {
+#pragma omp parallel
+#pragma omp critical(grelka) // expected-error {{cannot nest 'critical' regions having the same name 'grelka'}}
+        {
+          bar();
+        }
+      }
+    }
+  }
+
+// PARALLEL FOR DIRECTIVE
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp simd
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a parallel for region}}
+    {
+      bar();
+    }
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp single // expected-error {{region cannot be closely nested inside 'parallel for' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+    {
+      bar();
+    }
+#pragma omp master // expected-error {{region cannot be closely nested inside 'parallel for' region}}
+    {
+      bar();
+    }
+#pragma omp critical
+    {
+      bar();
+    }
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel
+    {
+#pragma omp single // OK
+      {
+        bar();
+      }
+#pragma omp master // OK
+      {
+        bar();
+      }
+#pragma omp critical // OK
+      {
+        bar();
+      }
+#pragma omp for // OK
+      for (int i = 0; i < 10; ++i)
+        ;
+#pragma omp sections // OK
+      {
+        bar();
+      }
+    }
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel for
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp parallel sections
+    {
+      bar();
+    }
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp task
+    {
+      bar();
+    }
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp taskyield
+    bar();
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp barrier // expected-error {{region cannot be closely nested inside 'parallel for' region}}
+    bar();
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp taskwait
+    bar();
+  }
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+#pragma omp flush
+    bar();
+  }
+
+// PARALLEL SECTIONS DIRECTIVE
+#pragma omp parallel sections
+  {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'parallel sections' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel sections
+  {
+#pragma omp simd
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel sections
+  {
+#pragma omp parallel
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel sections
+  {
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'parallel sections' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+    {
+      bar();
+    }
+  }
+#pragma omp parallel sections
+  {
+#pragma omp section
+    {
+      bar();
+    }
+  }
+#pragma omp parallel sections
+  {
+#pragma omp section
+    {
+#pragma omp single // expected-error {{region cannot be closely nested inside 'section' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+      bar();
+#pragma omp master // expected-error {{region cannot be closely nested inside 'section' region}}
+      bar();
+#pragma omp critical
+      bar();
+    }
+  }
+#pragma omp parallel sections
+  {
+#pragma omp parallel
+    {
+#pragma omp single // OK
+      {
+        bar();
+      }
+#pragma omp master // OK
+      {
+        bar();
+      }
+#pragma omp critical // OK
+      {
+        bar();
+      }
+#pragma omp for // OK
+      for (int i = 0; i < 10; ++i)
+        ;
+#pragma omp sections // OK
+      {
+        bar();
+      }
+    }
+  }
+#pragma omp parallel sections
+  {
+#pragma omp parallel for
+    for (int i = 0; i < 10; ++i)
+      ;
+  }
+#pragma omp parallel sections
+  {
+#pragma omp parallel sections
+    {
+      bar();
+    }
+  }
+#pragma omp parallel sections
+  {
+#pragma omp task
+    {
+      bar();
+    }
+  }
+#pragma omp parallel sections
+  {
+#pragma omp taskyield
+  }
+#pragma omp parallel sections
+  {
+#pragma omp barrier // expected-error {{region cannot be closely nested inside 'parallel sections' region}}
+  }
+#pragma omp parallel sections
+  {
+#pragma omp taskwait
+  }
+#pragma omp parallel sections
+  {
+#pragma omp flush
+  }
+
+// TASK DIRECTIVE
+#pragma omp task
+#pragma omp for // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp task
+#pragma omp simd
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp task
+#pragma omp sections // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp sections' directive into a parallel region?}}
+  {
+    bar();
+  }
+#pragma omp task
+#pragma omp section // expected-error {{'omp section' directive must be closely nested to a sections region, not a task region}}
+  {
+    bar();
+  }
+#pragma omp task
+#pragma omp single // expected-error {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp single' directive into a parallel region?}}
+  bar();
+#pragma omp task
+#pragma omp master // expected-error {{region cannot be closely nested inside 'task' region}}
+  bar();
+#pragma omp task
+#pragma omp critical
+  bar();
+#pragma omp task
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i)
+    ;
+#pragma omp task
+#pragma omp parallel sections
+  {
+    bar();
+  }
+#pragma omp task
+#pragma omp task
+  {
+    bar();
+  }
+#pragma omp task
+  {
+#pragma omp taskyield
+    bar();
+  }
+#pragma omp task
+  {
+#pragma omp barrier // expected-error {{region cannot be closely nested inside 'task' region}}
+    bar();
+  }
+#pragma omp task
+  {
+#pragma omp taskwait
+    bar();
+  }
+#pragma omp task
+  {
+#pragma omp flush
+    bar();
+  }
+  return foo<int>();
+}
+
diff --git a/test/OpenMP/no_option.c b/test/OpenMP/no_option.c
index 4acc8d0..8a65b03 100644
--- a/test/OpenMP/no_option.c
+++ b/test/OpenMP/no_option.c
@@ -2,5 +2,5 @@
 // expected-no-diagnostics
 
 int a;
-#pragma omp threadprivate(a,b)
+#pragma omp threadprivate(a, b)
 #pragma omp parallel
diff --git a/test/OpenMP/no_option_no_warn.c b/test/OpenMP/no_option_no_warn.c
index c989991..10778c0 100644
--- a/test/OpenMP/no_option_no_warn.c
+++ b/test/OpenMP/no_option_no_warn.c
@@ -2,5 +2,5 @@
 // expected-no-diagnostics
 
 int a;
-#pragma omp threadprivate(a,b)
+#pragma omp threadprivate(a, b)
 #pragma omp parallel
diff --git a/test/OpenMP/openmp_common.c b/test/OpenMP/openmp_common.c
index 3765f4c..3131b30 100644
--- a/test/OpenMP/openmp_common.c
+++ b/test/OpenMP/openmp_common.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -o - %s
 
 #pragma omp // expected-error {{expected an OpenMP directive}}
 #pragma omp unknown_directive // expected-error {{expected an OpenMP directive}}
diff --git a/test/OpenMP/parallel_ast_print.cpp b/test/OpenMP/parallel_ast_print.cpp
index f2fd2f7..0415c0c 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=libiomp5 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
 // expected-no-diagnostics
 
 #ifndef HEADER
@@ -8,53 +8,89 @@
 
 void foo() {}
 
+template <class T>
+struct S {
+  operator T() {return T();}
+  static T TS;
+  #pragma omp threadprivate(TS)
+};
 
-template <typename T>
+// CHECK:      template <class T = int> struct S {
+// CHECK:        static int TS;
+// CHECK-NEXT:   #pragma omp threadprivate(S<int>::TS)
+// CHECK-NEXT: }
+// CHECK:      template <class T = long> struct S {
+// CHECK:        static long TS;
+// CHECK-NEXT:   #pragma omp threadprivate(S<long>::TS)
+// CHECK-NEXT: }
+// CHECK:      template <class T> struct S {
+// CHECK:        static T TS;
+// CHECK-NEXT:   #pragma omp threadprivate(S::TS)
+// CHECK:      };
+
+template <typename T, int C>
 T tmain(T argc, T *argv) {
   T b = argc, c, d, e, f, g;
   static T a;
+  S<T> s;
 #pragma omp parallel
   a=2;
-#pragma omp parallel default(none), private(argc,b) firstprivate(argv) shared (d)
+#pragma omp parallel default(none), private(argc,b) firstprivate(argv) shared (d) if (argc > 0) num_threads(C) copyin(S<T>::TS) proc_bind(master) reduction(+:c) reduction(max:e)
+  foo();
+#pragma omp parallel if (C) num_threads(s) proc_bind(close) reduction(^:e, f) reduction(&& : g)
   foo();
   return 0;
 }
-// CHECK: template <typename T = int> int tmain(int argc, int *argv) {
+
+// CHECK: template <typename T = int, int C = 5> int tmain(int argc, int *argv) {
 // CHECK-NEXT: int b = argc, c, d, e, f, g;
 // CHECK-NEXT: static int a;
+// CHECK-NEXT: S<int> s;
 // CHECK-NEXT: #pragma omp parallel
 // CHECK-NEXT: a = 2;
-// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d)
+// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) num_threads(5) copyin(S<int>::TS) proc_bind(master) reduction(+: c) reduction(max: e)
 // CHECK-NEXT: foo()
-// CHECK: template <typename T = float> float tmain(float argc, float *argv) {
-// CHECK-NEXT: float b = argc, c, d, e, f, g;
-// CHECK-NEXT: static float a;
+// CHECK-NEXT: #pragma omp parallel if(5) num_threads(s) proc_bind(close) reduction(^: e,f) reduction(&&: g)
+// CHECK-NEXT: foo()
+// CHECK: template <typename T = long, int C = 1> long tmain(long argc, long *argv) {
+// CHECK-NEXT: long b = argc, c, d, e, f, g;
+// CHECK-NEXT: static long a;
+// CHECK-NEXT: S<long> s;
 // CHECK-NEXT: #pragma omp parallel
 // CHECK-NEXT: a = 2;
-// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d)
+// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) num_threads(1) copyin(S<long>::TS) proc_bind(master) reduction(+: c) reduction(max: e)
 // CHECK-NEXT: foo()
-// CHECK: template <typename T> T tmain(T argc, T *argv) {
+// CHECK-NEXT: #pragma omp parallel if(1) num_threads(s) proc_bind(close) reduction(^: e,f) reduction(&&: g)
+// CHECK-NEXT: foo()
+// CHECK: template <typename T, int C> T tmain(T argc, T *argv) {
 // CHECK-NEXT: T b = argc, c, d, e, f, g;
 // CHECK-NEXT: static T a;
+// CHECK-NEXT: S<T> s;
 // CHECK-NEXT: #pragma omp parallel
 // CHECK-NEXT: a = 2;
-// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d)
+// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) num_threads(C) copyin(S<T>::TS) proc_bind(master) reduction(+: c) reduction(max: e)
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp parallel if(C) num_threads(s) proc_bind(close) reduction(^: e,f) reduction(&&: g)
 // CHECK-NEXT: foo()
 
+enum Enum { };
+
 int main (int argc, char **argv) {
-  float x;
+  long x;
   int b = argc, c, d, e, f, g;
   static int a;
-// CHECK: static int a;
+  #pragma omp threadprivate(a)
+  Enum ee;
+// CHECK: Enum ee;
 #pragma omp parallel
 // CHECK-NEXT: #pragma omp parallel
   a=2;
 // CHECK-NEXT: a = 2;
-#pragma omp parallel default(none), private(argc,b) firstprivate(argv)
-// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv)
+#pragma omp parallel default(none), private(argc,b) firstprivate(argv) if (argc > 0) num_threads(ee) copyin(a) proc_bind(spread) reduction(| : c, d) reduction(* : e)
+// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) if(argc > 0) num_threads(ee) copyin(a) proc_bind(spread) reduction(|: c,d) reduction(*: e)
   foo();
 // CHECK-NEXT: foo();
-  return tmain(b, &b) + tmain(x, &x);
+  return tmain<int, 5>(b, &b) + tmain<long, 1>(x, &x);
 }
 
 #endif
diff --git a/test/OpenMP/parallel_codegen.cpp b/test/OpenMP/parallel_codegen.cpp
new file mode 100644
index 0000000..d9ff5ac
--- /dev/null
+++ b/test/OpenMP/parallel_codegen.cpp
@@ -0,0 +1,145 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -g -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix=CHECK-DEBUG %s
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// CHECK-DAG: %ident_t = type { i32, i32, i32, i32, i8* }
+// CHECK-DAG: %struct.anon = type { i32* }
+// CHECK-DAG: %struct.anon.0 = type { i8*** }
+// CHECK-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00"
+// CHECK-DAG: [[DEF_LOC_2:@.+]] = private unnamed_addr constant %ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8]* [[STR]], i32 0, i32 0) }
+// CHECK-DEBUG-DAG: %ident_t = type { i32, i32, i32, i32, i8* }
+// CHECK-DEBUG-DAG: %struct.anon = type { i32* }
+// CHECK-DEBUG-DAG: %struct.anon.0 = type { i8*** }
+// CHECK-DEBUG-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00"
+// CHECK-DEBUG-DAG: [[DEF_LOC_2:@.+]] = private unnamed_addr constant %ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8]* [[STR]], i32 0, i32 0) }
+// CHECK-DEBUG-DAG: [[LOC1:@.+]] = private unnamed_addr constant [{{.+}} x i8] c";{{.*}}parallel_codegen.cpp;main;[[@LINE+14]];9;;\00"
+// CHECK-DEBUG-DAG: [[LOC2:@.+]] = private unnamed_addr constant [{{.+}} x i8] c";{{.*}}parallel_codegen.cpp;tmain;[[@LINE+7]];9;;\00"
+
+template <class T>
+void foo(T argc) {}
+
+template <typename T>
+int tmain(T argc) {
+#pragma omp parallel
+  foo(argc);
+  return 0;
+}
+
+int main (int argc, char **argv) {
+#pragma omp parallel
+  foo(argc);
+  return tmain(argv);
+}
+
+// CHECK-LABEL: define {{[a-z]*[ ]?i32}} @main({{i32[ ]?[a-z]*}} %argc, i8** %argv)
+// CHECK:       [[AGG_CAPTURED:%.+]] = alloca %struct.anon
+// CHECK:       [[ARGC_REF:%.+]] = getelementptr inbounds %struct.anon* [[AGG_CAPTURED]], i32 0, i32 0
+// CHECK-NEXT:  store i32* {{%[a-z0-9.]+}}, i32** [[ARGC_REF]]
+// CHECK-NEXT:  [[BITCAST:%.+]] = bitcast %struct.anon* [[AGG_CAPTURED]] to i8*
+// CHECK-NEXT:  call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...)* @__kmpc_fork_call(%ident_t* [[DEF_LOC_2]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.anon*)* @__captured_stmt to void (i32*, i32*, ...)*), i8* [[BITCAST]])
+// CHECK-NEXT:  [[ARGV:%.+]] = load i8*** {{%[a-z0-9.]+}}
+// CHECK-NEXT:  [[RET:%.+]] = call {{[a-z]*[ ]?i32}} [[TMAIN:@.+tmain.+]](i8** [[ARGV]])
+// CHECK-NEXT:  ret i32 [[RET]]
+// CHECK-NEXT:  }
+// CHECK-DEBUG-LABEL: define i32 @main(i32 %argc, i8** %argv)
+// CHECK-DEBUG-DAG:   [[AGG_CAPTURED:%.+]] = alloca %struct.anon
+// CHECK-DEBUG-DAG:   [[LOC_2_ADDR:%.+]] = alloca %ident_t
+// CHECK-DEBUG:       [[KMPC_LOC_VOIDPTR:%.+]] = bitcast %ident_t* [[LOC_2_ADDR]] to i8*
+// CHECK-DEBUG-NEXT:  [[KMPC_DEFAULT_LOC_VOIDPTR:%.+]] = bitcast %ident_t* [[DEF_LOC_2]] to i8*
+// CHECK-DEBUG-NEXT:   call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[KMPC_LOC_VOIDPTR]], i8* [[KMPC_DEFAULT_LOC_VOIDPTR]], i64 ptrtoint (%ident_t* getelementptr (%ident_t* null, i32 1) to i64), i32 8, i1 false)
+// CHECK-DEBUG:       [[ARGC_REF:%.+]] = getelementptr inbounds %struct.anon* [[AGG_CAPTURED]], i32 0, i32 0
+// CHECK-DEBUG-NEXT:  store i32* {{%[a-z0-9.]+}}, i32** [[ARGC_REF]]
+// CHECK-DEBUG-NEXT:  [[KMPC_LOC_PSOURCE_REF:%.+]] = getelementptr inbounds %ident_t* [[LOC_2_ADDR]], i32 0, i32 4
+// CHECK-DEBUG-NEXT:  store i8* getelementptr inbounds ([{{.+}} x i8]* [[LOC1]], i32 0, i32 0), i8** [[KMPC_LOC_PSOURCE_REF]]
+// CHECK-DEBUG-NEXT:  [[BITCAST:%.+]] = bitcast %struct.anon* [[AGG_CAPTURED]] to i8*
+// CHECK-DEBUG-NEXT:  call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...)* @__kmpc_fork_call(%ident_t* [[LOC_2_ADDR]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.anon*)* @__captured_stmt to void (i32*, i32*, ...)*), i8* [[BITCAST]])
+// CHECK-DEBUG-NEXT:  [[ARGV:%.+]] = load i8*** {{%[a-z0-9.]+}}
+// CHECK-DEBUG-NEXT:  [[RET:%.+]] = call i32 [[TMAIN:@.+tmain.+]](i8** [[ARGV]])
+// CHECK-DEBUG-NEXT:  ret i32 [[RET]]
+// CHECK-DEBUG-NEXT:  }
+
+// CHECK-LABEL: define internal void @__captured_stmt(i32* %.global_tid., i32* %.bound_tid., %struct.anon* %__context)
+// CHECK:       [[CONTEXT_ADDR:%.+]] = alloca %struct.anon*
+// CHECK:       store %struct.anon* %__context, %struct.anon** [[CONTEXT_ADDR]]
+// CHECK:       [[CONTEXT_PTR:%.+]] = load %struct.anon** [[CONTEXT_ADDR]]
+// CHECK-NEXT:  [[ARGC_PTR_REF:%.+]] = getelementptr inbounds %struct.anon* [[CONTEXT_PTR]], i32 0, i32 0
+// CHECK-NEXT:  [[ARGC_REF:%.+]] = load i32** [[ARGC_PTR_REF]]
+// CHECK-NEXT:  [[ARGC:%.+]] = load i32* [[ARGC_REF]]
+// CHECK-NEXT:  invoke void [[FOO:@.+foo.+]](i32{{[ ]?[a-z]*}} [[ARGC]])
+// CHECK:       ret void
+// CHECK:       call void @{{.+terminate.*}}(
+// CHECK-NEXT:  unreachable
+// CHECK-NEXT:  }
+// CHECK-DEBUG-LABEL: define internal void @__captured_stmt(i32* %.global_tid., i32* %.bound_tid., %struct.anon* %__context)
+// CHECK-DEBUG:       [[CONTEXT_ADDR:%.+]] = alloca %struct.anon*
+// CHECK-DEBUG:       store %struct.anon* %__context, %struct.anon** [[CONTEXT_ADDR]]
+// CHECK-DEBUG:       [[CONTEXT_PTR:%.+]] = load %struct.anon** [[CONTEXT_ADDR]]
+// CHECK-DEBUG-NEXT:  [[ARGC_PTR_REF:%.+]] = getelementptr inbounds %struct.anon* [[CONTEXT_PTR]], i32 0, i32 0
+// CHECK-DEBUG-NEXT:  [[ARGC_REF:%.+]] = load i32** [[ARGC_PTR_REF]]
+// CHECK-DEBUG-NEXT:  [[ARGC:%.+]] = load i32* [[ARGC_REF]]
+// CHECK-DEBUG-NEXT:  invoke void [[FOO:@.+foo.+]](i32 [[ARGC]])
+// CHECK-DEBUG:       ret void
+// CHECK-DEBUG:       call void @{{.+terminate.*}}(
+// CHECK-DEBUG-NEXT:  unreachable
+// CHECK-DEBUG-NEXT:  }
+
+// CHECK-DAG: define linkonce_odr void [[FOO]]({{i32[ ]?[a-z]*}} %argc)
+// CHECK-DAG: declare void @__kmpc_fork_call(%ident_t*, i32, void (i32*, i32*, ...)*, ...)
+// CHECK-DEBUG-DAG: define linkonce_odr void [[FOO]](i32 %argc)
+// CHECK-DEBUG-DAG: declare void @__kmpc_fork_call(%ident_t*, i32, void (i32*, i32*, ...)*, ...)
+
+// CHECK:       define linkonce_odr {{[a-z]*[ ]?i32}} [[TMAIN]](i8** %argc)
+// CHECK:       [[AGG_CAPTURED:%.+]] = alloca %struct.anon.0
+// CHECK:       [[ARGC_REF:%.+]] = getelementptr inbounds %struct.anon.0* [[AGG_CAPTURED]], i32 0, i32 0
+// CHECK-NEXT:  store i8*** {{%[a-z0-9.]+}}, i8**** [[ARGC_REF]]
+// CHECK-NEXT:  [[BITCAST:%.+]] = bitcast %struct.anon.0* [[AGG_CAPTURED]] to i8*
+// CHECK-NEXT:  call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...)* @__kmpc_fork_call(%ident_t* [[DEF_LOC_2]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.anon.0*)* @__captured_stmt1 to void (i32*, i32*, ...)*), i8* [[BITCAST]])
+// CHECK-NEXT:  ret i32 0
+// CHECK-NEXT:  }
+// CHECK-DEBUG:       define linkonce_odr i32 [[TMAIN]](i8** %argc)
+// CHECK-DEBUG-DAG:   [[AGG_CAPTURED:%.+]] = alloca %struct.anon.0
+// CHECK-DEBUG-DAG:   [[LOC_2_ADDR:%.+]] = alloca %ident_t
+// CHECK-DEBUG:       [[KMPC_LOC_VOIDPTR:%.+]] = bitcast %ident_t* [[LOC_2_ADDR]] to i8*
+// CHECK-DEBUG-NEXT:  [[KMPC_DEFAULT_LOC_VOIDPTR:%.+]] = bitcast %ident_t* [[DEF_LOC_2]] to i8*
+// CHECK-DEBUG-NEXT:   call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[KMPC_LOC_VOIDPTR]], i8* [[KMPC_DEFAULT_LOC_VOIDPTR]], i64 ptrtoint (%ident_t* getelementptr (%ident_t* null, i32 1) to i64), i32 8, i1 false)
+// CHECK-DEBUG:       [[ARGC_REF:%.+]] = getelementptr inbounds %struct.anon.0* [[AGG_CAPTURED]], i32 0, i32 0
+// CHECK-DEBUG-NEXT:  store i8*** {{%[a-z0-9.]+}}, i8**** [[ARGC_REF]]
+// CHECK-DEBUG-NEXT:  [[KMPC_LOC_PSOURCE_REF:%.+]] = getelementptr inbounds %ident_t* [[LOC_2_ADDR]], i32 0, i32 4
+// CHECK-DEBUG-NEXT:  store i8* getelementptr inbounds ([{{.+}} x i8]* [[LOC2]], i32 0, i32 0), i8** [[KMPC_LOC_PSOURCE_REF]]
+// CHECK-DEBUG-NEXT:  [[BITCAST:%.+]] = bitcast %struct.anon.0* [[AGG_CAPTURED]] to i8*
+// CHECK-DEBUG-NEXT:  call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...)* @__kmpc_fork_call(%ident_t* [[LOC_2_ADDR]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, %struct.anon.0*)* @__captured_stmt1 to void (i32*, i32*, ...)*), i8* [[BITCAST]])
+// CHECK-DEBUG-NEXT:  ret i32 0
+// CHECK-DEBUG-NEXT:  }
+
+// CHECK-LABEL: define internal void @__captured_stmt1(i32* %.global_tid., i32* %.bound_tid., %struct.anon.0* %__context)
+// CHECK:       [[CONTEXT_ADDR:%.+]] = alloca %struct.anon.0*
+// CHECK:       store %struct.anon.0* %__context, %struct.anon.0** [[CONTEXT_ADDR]]
+// CHECK:       [[CONTEXT_PTR:%.+]] = load %struct.anon.0** [[CONTEXT_ADDR]]
+// CHECK-NEXT:  [[ARGC_PTR_REF:%.+]] = getelementptr inbounds %struct.anon.0* [[CONTEXT_PTR]], i32 0, i32 0
+// CHECK-NEXT:  [[ARGC_REF:%.+]] = load i8**** [[ARGC_PTR_REF]]
+// CHECK-NEXT:  [[ARGC:%.+]] = load i8*** [[ARGC_REF]]
+// CHECK-NEXT:  invoke void [[FOO1:@.+foo.+]](i8** [[ARGC]])
+// CHECK:       ret void
+// CHECK:       call void @{{.+terminate.*}}(
+// CHECK-NEXT:  unreachable
+// CHECK-NEXT:  }
+// CHECK-DEBUG-LABEL: define internal void @__captured_stmt1(i32* %.global_tid., i32* %.bound_tid., %struct.anon.0* %__context)
+// CHECK-DEBUG:       [[CONTEXT_ADDR:%.+]] = alloca %struct.anon.0*
+// CHECK-DEBUG:       store %struct.anon.0* %__context, %struct.anon.0** [[CONTEXT_ADDR]]
+// CHECK-DEBUG:       [[CONTEXT_PTR:%.+]] = load %struct.anon.0** [[CONTEXT_ADDR]]
+// CHECK-DEBUG-NEXT:  [[ARGC_PTR_REF:%.+]] = getelementptr inbounds %struct.anon.0* [[CONTEXT_PTR]], i32 0, i32 0
+// CHECK-DEBUG-NEXT:  [[ARGC_REF:%.+]] = load i8**** [[ARGC_PTR_REF]]
+// CHECK-DEBUG-NEXT:  [[ARGC:%.+]] = load i8*** [[ARGC_REF]]
+// CHECK-DEBUG-NEXT:  invoke void [[FOO1:@.+foo.+]](i8** [[ARGC]])
+// CHECK-DEBUG:       ret void
+// CHECK-DEBUG:       call void @{{.+terminate.*}}(
+// CHECK-DEBUG-NEXT:  unreachable
+// CHECK-DEBUG-NEXT:  }
+
+// CHECK: define linkonce_odr void [[FOO1]](i8** %argc)
+// CHECK-DEBUG: define linkonce_odr void [[FOO1]](i8** %argc)
+
+#endif
diff --git a/test/OpenMP/parallel_copyin_messages.cpp b/test/OpenMP/parallel_copyin_messages.cpp
new file mode 100644
index 0000000..c1ce363
--- /dev/null
+++ b/test/OpenMP/parallel_copyin_messages.cpp
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+class S2 {
+  mutable int a;
+public:
+  S2():a(0) { }
+  S2 & operator =(S2 &s2) { return *this; }
+};
+class S3 {
+  int a;
+public:
+  S3():a(0) { }
+  S3 &operator =(S3 &s3) { return *this; }
+};
+class S4 { // expected-note {{'S4' declared here}}
+  int a;
+  S4();
+  S4 &operator =(const S4 &s4);
+public:
+  S4(int v):a(v) { }
+};
+class S5 { // expected-note {{'S5' declared here}}
+  int a;
+  S5():a(0) {}
+  S5 &operator =(const S5 &s5) { return *this; }
+public:
+  S5(int v):a(v) { }
+};
+template <class T>
+class ST {
+public:
+  static T s;
+};
+
+
+S2 k;
+S3 h;
+S4 l(3); // expected-note {{'l' defined here}}
+S5 m(4); // expected-note {{'m' defined here}}
+#pragma omp threadprivate(h, k, l, m)
+
+int main(int argc, char **argv) {
+  int i;
+  #pragma omp parallel copyin // expected-error {{expected '(' after 'copyin'}}
+  #pragma omp parallel copyin ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp parallel copyin () // expected-error {{expected expression}}
+  #pragma omp parallel copyin (k // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp parallel copyin (h, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp parallel copyin (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  #pragma omp parallel copyin (l) // expected-error {{copyin variable must have an accessible, unambiguous copy assignment operator}}
+  #pragma omp parallel copyin (S1) // expected-error {{'S1' does not refer to a value}}
+  #pragma omp parallel copyin (argv[1]) // expected-error {{expected variable name}}
+  #pragma omp parallel copyin(i) // expected-error {{copyin variable must be threadprivate}}
+  #pragma omp parallel copyin(m) // expected-error {{copyin variable must have an accessible, unambiguous copy assignment operator}}
+  #pragma omp parallel copyin(ST<int>::s) // expected-error {{copyin variable must be threadprivate}}
+  foo();
+
+  return 0;
+}
diff --git a/test/OpenMP/parallel_default_messages.cpp b/test/OpenMP/parallel_default_messages.cpp
index cbc6a73..6014cdf 100644
--- a/test/OpenMP/parallel_default_messages.cpp
+++ b/test/OpenMP/parallel_default_messages.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -o - %s
 
 void foo();
 
diff --git a/test/OpenMP/parallel_firstprivate_messages.cpp b/test/OpenMP/parallel_firstprivate_messages.cpp
index 780059e..9df45c6 100644
--- a/test/OpenMP/parallel_firstprivate_messages.cpp
+++ b/test/OpenMP/parallel_firstprivate_messages.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 %s
 
 void foo() {
 }
diff --git a/test/OpenMP/parallel_for_ast_print.cpp b/test/OpenMP/parallel_for_ast_print.cpp
new file mode 100644
index 0000000..375664f
--- /dev/null
+++ b/test/OpenMP/parallel_for_ast_print.cpp
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+void foo() {}
+
+template <class T, int N>
+T tmain(T argc) {
+  T b = argc, c, d, e, f, h;
+  static T a;
+// CHECK: static T a;
+  static T g;
+#pragma omp threadprivate(g)
+#pragma omp parallel for schedule(dynamic) default(none) copyin(g)
+  // CHECK: #pragma omp parallel for schedule(dynamic) default(none) copyin(g)
+  for (int i = 0; i < 2; ++i)
+    a = 2;
+// CHECK-NEXT: for (int i = 0; i < 2; ++i)
+// CHECK-NEXT: a = 2;
+#pragma omp parallel for private(argc, b), firstprivate(c, d), lastprivate(d, f) collapse(N) schedule(static, N) ordered if (argc) num_threads(N) default(shared) shared(e) reduction(+ : h)
+  for (int i = 0; i < 10; ++i)
+    for (int j = 0; j < 10; ++j)
+      for (int j = 0; j < 10; ++j)
+        for (int j = 0; j < 10; ++j)
+          for (int j = 0; j < 10; ++j)
+            foo();
+  // CHECK-NEXT: #pragma omp parallel for private(argc,b) firstprivate(c,d) lastprivate(d,f) collapse(N) schedule(static, N) ordered if(argc) num_threads(N) default(shared) shared(e) reduction(+: h)
+  // CHECK-NEXT: for (int i = 0; i < 10; ++i)
+  // CHECK-NEXT: for (int j = 0; j < 10; ++j)
+  // CHECK-NEXT: for (int j = 0; j < 10; ++j)
+  // CHECK-NEXT: for (int j = 0; j < 10; ++j)
+  // CHECK-NEXT: for (int j = 0; j < 10; ++j)
+  // CHECK-NEXT: foo();
+  return T();
+}
+
+int main(int argc, char **argv) {
+  int b = argc, c, d, e, f, h;
+  static int a;
+// CHECK: static int a;
+  static float g;
+#pragma omp threadprivate(g)
+#pragma omp parallel for schedule(guided, argc) default(none) copyin(g)
+  // CHECK: #pragma omp parallel for schedule(guided, argc) default(none) copyin(g)
+  for (int i = 0; i < 2; ++i)
+    a = 2;
+// CHECK-NEXT: for (int i = 0; i < 2; ++i)
+// CHECK-NEXT: a = 2;
+#pragma omp parallel for private(argc, b), firstprivate(argv, c), lastprivate(d, f) collapse(2) schedule(auto) ordered if (argc) num_threads(a) default(shared) shared(e) reduction(+ : h)
+  for (int i = 0; i < 10; ++i)
+    for (int j = 0; j < 10; ++j)
+      foo();
+  // CHECK-NEXT: #pragma omp parallel for private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) schedule(auto) ordered if(argc) num_threads(a) default(shared) shared(e) reduction(+: h)
+  // CHECK-NEXT: for (int i = 0; i < 10; ++i)
+  // CHECK-NEXT: for (int j = 0; j < 10; ++j)
+  // CHECK-NEXT: foo();
+  return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0]));
+}
+
+#endif
diff --git a/test/OpenMP/parallel_for_collapse_messages.cpp b/test/OpenMP/parallel_for_collapse_messages.cpp
new file mode 100644
index 0000000..06dfe0f
--- /dev/null
+++ b/test/OpenMP/parallel_for_collapse_messages.cpp
@@ -0,0 +1,83 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, typename S, int N, int ST> // expected-note {{declared here}}
+T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
+  #pragma omp parallel for collapse // expected-error {{expected '(' after 'collapse'}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for collapse ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for collapse () // expected-error {{expected expression}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}}
+  // expected-error@+2 2 {{expression is not an integral constant expression}}
+  // expected-note@+1 2 {{read of non-const variable 'argc' is not allowed in a constant expression}}
+  #pragma omp parallel for collapse (argc 
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  // expected-error@+1 2 {{argument to 'collapse' clause must be a positive integer value}}
+  #pragma omp parallel for collapse (ST // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for collapse (1)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp parallel for', but found only 1}}
+  // expected-error@+3 2 {{directive '#pragma omp parallel for' cannot contain more than one 'collapse' clause}}
+  // expected-error@+2 2 {{argument to 'collapse' clause must be a positive integer value}}
+  // expected-error@+1 2 {{expression is not an integral constant expression}}
+  #pragma omp parallel for collapse (foobool(argc)), collapse (true), collapse (-5)
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for collapse (S) // expected-error {{'S' does not refer to a value}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  // expected-error@+1 2 {{expression is not an integral constant expression}}
+  #pragma omp parallel for collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for collapse (1)
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for collapse (N) // expected-error {{argument to 'collapse' clause must be a positive integer value}}
+  for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for collapse (2) // expected-note {{as specified in 'collapse' clause}}
+  foo(); // expected-error {{expected 2 for loops after '#pragma omp parallel for'}}
+  return argc;
+}
+
+int main(int argc, char **argv) {
+  #pragma omp parallel for collapse // expected-error {{expected '(' after 'collapse'}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp parallel for collapse ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp parallel for collapse () // expected-error {{expected expression}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp parallel for collapse (4 // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{as specified in 'collapse' clause}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp parallel for', but found only 1}}
+  #pragma omp parallel for collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}  expected-note {{as specified in 'collapse' clause}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp parallel for', but found only 1}}
+  #pragma omp parallel for collapse (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  // expected-error@+3 {{expression is not an integral constant expression}}
+  // expected-error@+2 2 {{directive '#pragma omp parallel for' cannot contain more than one 'collapse' clause}}
+  // expected-error@+1 2 {{argument to 'collapse' clause must be a positive integer value}}
+  #pragma omp parallel for collapse (foobool(argc)), collapse (true), collapse (-5) 
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp parallel for collapse (S1) // expected-error {{'S1' does not refer to a value}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  // expected-error@+1 {{expression is not an integral constant expression}}
+  #pragma omp parallel for collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  // expected-error@+3 {{statement after '#pragma omp parallel for' must be a for loop}}
+  // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
+  #pragma omp parallel for collapse(collapse(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
+  foo();
+  #pragma omp parallel for collapse (2) // expected-note {{as specified in 'collapse' clause}}
+  foo(); // expected-error {{expected 2 for loops after '#pragma omp parallel for'}}
+  // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}}
+  return tmain<int, char, 1, 0>(argc, argv);
+}
+
diff --git a/test/OpenMP/parallel_for_copyin_messages.cpp b/test/OpenMP/parallel_for_copyin_messages.cpp
new file mode 100644
index 0000000..2ebc2de
--- /dev/null
+++ b/test/OpenMP/parallel_for_copyin_messages.cpp
@@ -0,0 +1,93 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+  S2 &operator=(S2 &s2) { return *this; }
+};
+class S3 {
+  int a;
+
+public:
+  S3() : a(0) {}
+  S3 &operator=(S3 &s3) { return *this; }
+};
+class S4 { // expected-note {{'S4' declared here}}
+  int a;
+  S4();
+  S4 &operator=(const S4 &s4);
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note {{'S5' declared here}}
+  int a;
+  S5() : a(0) {}
+  S5 &operator=(const S5 &s5) { return *this; }
+
+public:
+  S5(int v) : a(v) {}
+};
+template <class T>
+class ST {
+public:
+  static T s;
+};
+
+S2 k;
+S3 h;
+S4 l(3); // expected-note {{'l' defined here}}
+S5 m(4); // expected-note {{'m' defined here}}
+#pragma omp threadprivate(h, k, l, m)
+
+int main(int argc, char **argv) {
+  int i;
+#pragma omp parallel for copyin // expected-error {{expected '(' after 'copyin'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for copyin( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for copyin() // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for copyin(k // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for copyin(h, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for copyin(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for copyin(l) // expected-error {{copyin variable must have an accessible, unambiguous copy assignment operator}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for copyin(S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for copyin(argv[1]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for copyin(i) // expected-error {{copyin variable must be threadprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for copyin(m) // expected-error {{copyin variable must have an accessible, unambiguous copy assignment operator}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for copyin(ST < int > ::s) // expected-error {{copyin variable must be threadprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+
+  return 0;
+}
diff --git a/test/OpenMP/parallel_for_default_messages.cpp b/test/OpenMP/parallel_for_default_messages.cpp
new file mode 100644
index 0000000..ed478a8
--- /dev/null
+++ b/test/OpenMP/parallel_for_default_messages.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -o - %s
+
+void foo();
+
+int main(int argc, char **argv) {
+  int i;
+#pragma omp parallel for default // expected-error {{expected '(' after 'default'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for default(none // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
+    foo();
+#pragma omp parallel for default(shared), default(shared) // expected-error {{directive '#pragma omp parallel for' cannot contain more than one 'default' clause}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+
+#pragma omp parallel for default(none)
+  for (i = 0; i < argc; ++i)  // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
+    foo();
+
+#pragma omp parallel default(none)
+#pragma omp parallel for default(shared)
+  for (i = 0; i < argc; ++i)
+    foo();
+
+  return 0;
+}
diff --git a/test/OpenMP/parallel_for_firstprivate_messages.cpp b/test/OpenMP/parallel_for_firstprivate_messages.cpp
new file mode 100644
index 0000000..99dd68f
--- /dev/null
+++ b/test/OpenMP/parallel_for_firstprivate_messages.cpp
@@ -0,0 +1,252 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+  S2(S2 &s2) : a(s2.a) {}
+  static float S2s;
+  static const float S2sc;
+};
+const float S2::S2sc = 0;
+const S2 b;
+const S2 ba[5];
+class S3 {
+  int a;
+  S3 &operator=(const S3 &s3);
+
+public:
+  S3() : a(0) {}
+  S3(S3 &s3) : a(s3.a) {}
+};
+const S3 c;
+const S3 ca[5];
+extern const int f;
+class S4 { // expected-note 2 {{'S4' declared here}}
+  int a;
+  S4();
+  S4(const S4 &s4);
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note 4 {{'S5' declared here}}
+  int a;
+  S5(const S5 &s5) : a(s5.a) {}
+
+public:
+  S5() : a(0) {}
+  S5(int v) : a(v) {}
+};
+class S6 {
+  int a;
+  S6() : a(0) {}
+
+public:
+  S6(const S6 &s6) : a(s6.a) {}
+  S6(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(int argc, char **argv) {
+  I e(4); // expected-note {{'e' defined here}}
+  C g(5); // expected-note 2 {{'g' defined here}}
+  int i;
+  int &j = i; // expected-note {{'j' defined here}}
+#pragma omp parallel for firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for firstprivate() // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for firstprivate(argc)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for firstprivate(a, b) // expected-error {{firstprivate variable with incomplete type 'S1'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for firstprivate(argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for linear(i) // expected-error {{unexpected OpenMP clause 'linear' in directive '#pragma omp parallel for'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;
+#pragma omp parallel for firstprivate(i)
+    for (int k = 0; k < argc; ++k) {
+      i = k;
+      v += i;
+    }
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp parallel for firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for firstprivate(i)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for lastprivate(g) firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel private(i)
+#pragma omp parallel for firstprivate(i) // expected-note {{defined as firstprivate}}
+  for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp parallel for' directive may not be firstprivate, predetermined as private}}
+    foo();
+#pragma omp parallel reduction(+ : i)
+#pragma omp parallel for firstprivate(i) // expected-note {{defined as firstprivate}}
+  for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp parallel for' directive may not be firstprivate, predetermined as private}}
+    foo();
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;
+  const int da[5] = {0};
+  S4 e(4); // expected-note {{'e' defined here}}
+  S5 g(5); // expected-note 2 {{'g' defined here}}
+  S3 m;
+  S6 n(2);
+  int i;
+  int &j = i; // expected-note {{'j' defined here}}
+#pragma omp parallel for firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate() // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(argc)
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(argv[1]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(2 * 2) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(ba) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(ca) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(da) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+  int xa;
+#pragma omp parallel for firstprivate(xa) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(S2::S2s) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(S2::S2sc) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for safelen(5) // expected-error {{unexpected OpenMP clause 'safelen' in directive '#pragma omp parallel for'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(m) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for private(xa), firstprivate(xa) // expected-error {{private variable cannot be firstprivate}} expected-note {{defined as private}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(i) // expected-note {{defined as firstprivate}}
+  for (i = 0; i < argc; ++i)    // expected-error {{loop iteration variable in the associated loop of 'omp parallel for' directive may not be firstprivate, predetermined as private}}
+    foo();
+#pragma omp parallel shared(xa)
+#pragma omp parallel for firstprivate(xa) // OK: may be firstprivate
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(g) firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(n) firstprivate(n) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;
+#pragma omp parallel for firstprivate(i)
+    for (int k = 0; k < argc; ++k) {
+      i = k;
+      v += i;
+    }
+  }
+#pragma omp parallel private(i)
+#pragma omp parallel for firstprivate(i) // expected-note {{defined as firstprivate}}
+  for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp parallel for' directive may not be firstprivate, predetermined as private}}
+    foo();
+#pragma omp parallel reduction(+ : i)
+#pragma omp parallel for firstprivate(i) // expected-note {{defined as firstprivate}}
+  for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp parallel for' directive may not be firstprivate, predetermined as private}}
+    foo();
+
+  return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}}
+}
diff --git a/test/OpenMP/parallel_for_if_messages.cpp b/test/OpenMP/parallel_for_if_messages.cpp
new file mode 100644
index 0000000..295d739
--- /dev/null
+++ b/test/OpenMP/parallel_for_if_messages.cpp
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, class S> // expected-note {{declared here}}
+int tmain(T argc, S **argv) {
+  T i;
+  #pragma omp parallel for if // expected-error {{expected '(' after 'if'}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if () // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if (argc > 0 ? argv[1] : argv[2])
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp parallel for' cannot contain more than one 'if' clause}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if (S) // expected-error {{'S' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if(argc)
+  for (i = 0; i < argc; ++i) foo();
+
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  int i;
+  #pragma omp parallel for if // expected-error {{expected '(' after 'if'}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if () // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if (argc > 0 ? argv[1] : argv[2])
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp parallel for' cannot contain more than one 'if' clause}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if (S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+
+  return tmain(argc, argv);
+}
diff --git a/test/OpenMP/parallel_for_lastprivate_messages.cpp b/test/OpenMP/parallel_for_lastprivate_messages.cpp
new file mode 100644
index 0000000..bd1dd4b
--- /dev/null
+++ b/test/OpenMP/parallel_for_lastprivate_messages.cpp
@@ -0,0 +1,226 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+  S2(S2 &s2) : a(s2.a) {}
+  static float S2s; // expected-note {{static data member is predetermined as shared}}
+  static const float S2sc;
+};
+const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const S2 b;
+const S2 ba[5];
+class S3 { // expected-note 2 {{'S3' declared here}}
+  int a;
+  S3 &operator=(const S3 &s3);
+
+public:
+  S3() : a(0) {}
+  S3(S3 &s3) : a(s3.a) {}
+};
+const S3 c;         // expected-note {{global variable is predetermined as shared}}
+const S3 ca[5];     // expected-note {{global variable is predetermined as shared}}
+extern const int f; // expected-note {{global variable is predetermined as shared}}
+class S4 {          // expected-note 3 {{'S4' declared here}}
+  int a;
+  S4();
+  S4(const S4 &s4);
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note {{'S5' declared here}}
+  int a;
+  S5() : a(0) {}
+
+public:
+  S5(const S5 &s5) : a(s5.a) {}
+  S5(int v) : a(v) {}
+};
+class S6 {
+  int a;
+  S6() : a(0) {}
+
+public:
+  S6(const S6 &s6) : a(s6.a) {}
+  S6(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(int argc, char **argv) {
+  I e(4); // expected-note {{'e' defined here}}
+  I g(5); // expected-note {{'g' defined here}}
+  int i;
+  int &j = i;                        // expected-note {{'j' defined here}}
+#pragma omp parallel for lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for lastprivate() // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for lastprivate(argc)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for lastprivate(a, b) // expected-error {{lastprivate variable with incomplete type 'S1'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for lastprivate(argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for lastprivate(e, g) // expected-error 2 {{lastprivate variable must have an accessible, unambiguous default constructor}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for linear(i) // expected-error {{unexpected OpenMP clause 'linear' in directive '#pragma omp parallel for'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;
+#pragma omp parallel for lastprivate(i)
+    for (int k = 0; k < argc; ++k) {
+      i = k;
+      v += i;
+    }
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp parallel for lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for lastprivate(i)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;       // expected-note {{constant variable is predetermined as shared}}
+  const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+  S4 e(4);               // expected-note {{'e' defined here}}
+  S5 g(5);               // expected-note {{'g' defined here}}
+  S3 m;                  // expected-note 2 {{'m' defined here}}
+  S6 n(2);
+  int i;
+  int &j = i;                        // expected-note {{'j' defined here}}
+#pragma omp parallel for lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate() // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(argc)
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(argv[1]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(2 * 2) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(ba)
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+  int xa;
+#pragma omp parallel for lastprivate(xa) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for safelen(5) // expected-error {{unexpected OpenMP clause 'safelen' in directive '#pragma omp parallel for'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(e, g) // expected-error 2 {{lastprivate variable must have an accessible, unambiguous default constructor}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(m) // expected-error {{lastprivate variable must have an accessible, unambiguous copy assignment operator}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for private(xa), lastprivate(xa) // expected-error {{private variable cannot be lastprivate}} expected-note {{defined as private}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(i)
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel private(xa)
+#pragma omp parallel for lastprivate(xa)
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel reduction(+ : xa)
+#pragma omp parallel for lastprivate(xa)
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for firstprivate(m) lastprivate(m) // expected-error {{lastprivate variable must have an accessible, unambiguous copy assignment operator}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for lastprivate(n) firstprivate(n) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+  return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}}
+}
diff --git a/test/OpenMP/parallel_for_loop_messages.cpp b/test/OpenMP/parallel_for_loop_messages.cpp
new file mode 100644
index 0000000..f029ef4
--- /dev/null
+++ b/test/OpenMP/parallel_for_loop_messages.cpp
@@ -0,0 +1,593 @@
+// RUN: %clang_cc1 -fsyntax-only -fopenmp=libiomp5 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify %s
+
+class S {
+  int a;
+  S() : a(0) {}
+
+public:
+  S(int v) : a(v) {}
+  S(const S &s) : a(s.a) {}
+};
+
+static int sii;
+#pragma omp threadprivate(sii) // expected-note {{defined as threadprivate or thread local}}
+
+int test_iteration_spaces() {
+  const int N = 100;
+  float a[N], b[N], c[N];
+  int ii, jj, kk;
+  float fii;
+  double dii;
+#pragma omp parallel for
+  for (int i = 0; i < 10; i += 1) {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp parallel for
+  for (char i = 0; i < 10; i++) {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp parallel for
+  for (char i = 0; i < 10; i += '\1') {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp parallel for
+  for (long long i = 0; i < 10; i++) {
+    c[i] = a[i] + b[i];
+  }
+// expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'double'}}
+#pragma omp parallel for
+  for (long long i = 0; i < 10; i += 1.5) {
+    c[i] = a[i] + b[i];
+  }
+#pragma omp parallel for
+  for (long long i = 0; i < 'z'; i += 1u) {
+    c[i] = a[i] + b[i];
+  }
+// expected-error@+2 {{variable must be of integer or random access iterator type}}
+#pragma omp parallel for
+  for (float fi = 0; fi < 10.0; fi++) {
+    c[(int)fi] = a[(int)fi] + b[(int)fi];
+  }
+// expected-error@+2 {{variable must be of integer or random access iterator type}}
+#pragma omp parallel for
+  for (double fi = 0; fi < 10.0; fi++) {
+    c[(int)fi] = a[(int)fi] + b[(int)fi];
+  }
+// expected-error@+2 {{variable must be of integer or random access iterator type}}
+#pragma omp parallel for
+  for (int &ref = ii; ref < 10; ref++) {
+  }
+// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
+#pragma omp parallel for
+  for (int i; i < 10; i++)
+    c[i] = a[i];
+
+// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
+#pragma omp parallel for
+  for (int i = 0, j = 0; i < 10; ++i)
+    c[i] = a[i];
+
+// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
+#pragma omp parallel for
+  for (; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+// expected-warning@+3 {{expression result unused}}
+// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
+#pragma omp parallel for
+  for (ii + 1; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
+#pragma omp parallel for
+  for (c[ii] = 0; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+// Ok to skip parenthesises.
+#pragma omp parallel for
+  for (((ii)) = 0; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+#pragma omp parallel for
+  for (int i = 0; i; i++)
+    c[i] = a[i];
+
+// expected-error@+3 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'i'}}
+#pragma omp parallel for
+  for (int i = 0; jj < kk; ii++)
+    c[i] = a[i];
+
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+#pragma omp parallel for
+  for (int i = 0; !!i; i++)
+    c[i] = a[i];
+
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+#pragma omp parallel for
+  for (int i = 0; i != 1; i++)
+    c[i] = a[i];
+
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+#pragma omp parallel for
+  for (int i = 0;; i++)
+    c[i] = a[i];
+
+// Ok.
+#pragma omp parallel for
+  for (int i = 11; i > 10; i--)
+    c[i] = a[i];
+
+// Ok.
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i)
+    c[i] = a[i];
+
+// Ok.
+#pragma omp parallel for
+  for (ii = 0; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp parallel for
+  for (ii = 0; ii < 10; ++jj)
+    c[ii] = a[jj];
+
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp parallel for
+  for (ii = 0; ii < 10; ++++ii)
+    c[ii] = a[ii];
+
+// Ok but undefined behavior (in general, cannot check that incr
+// is really loop-invariant).
+#pragma omp parallel for
+  for (ii = 0; ii < 10; ii = ii + ii)
+    c[ii] = a[ii];
+
+// expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'float'}}
+#pragma omp parallel for
+  for (ii = 0; ii < 10; ii = ii + 1.0f)
+    c[ii] = a[ii];
+
+// Ok - step was converted to integer type.
+#pragma omp parallel for
+  for (ii = 0; ii < 10; ii = ii + (int)1.1f)
+    c[ii] = a[ii];
+
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp parallel for
+  for (ii = 0; ii < 10; jj = ii + 2)
+    c[ii] = a[ii];
+
+// expected-warning@+3 {{relational comparison result unused}}
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp parallel for
+  for (ii = 0; ii<10; jj> kk + 2)
+    c[ii] = a[ii];
+
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp parallel for
+  for (ii = 0; ii < 10;)
+    c[ii] = a[ii];
+
+// expected-warning@+3 {{expression result unused}}
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp parallel for
+  for (ii = 0; ii < 10; !ii)
+    c[ii] = a[ii];
+
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp parallel for
+  for (ii = 0; ii < 10; ii ? ++ii : ++jj)
+    c[ii] = a[ii];
+
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+#pragma omp parallel for
+  for (ii = 0; ii < 10; ii = ii < 10)
+    c[ii] = a[ii];
+
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp parallel for
+  for (ii = 0; ii < 10; ii = ii + 0)
+    c[ii] = a[ii];
+
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp parallel for
+  for (ii = 0; ii < 10; ii = ii + (int)(0.8 - 0.45))
+    c[ii] = a[ii];
+
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp parallel for
+  for (ii = 0; (ii) < 10; ii -= 25)
+    c[ii] = a[ii];
+
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp parallel for
+  for (ii = 0; (ii < 10); ii -= 0)
+    c[ii] = a[ii];
+
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}}
+#pragma omp parallel for
+  for (ii = 0; ii > 10; (ii += 0))
+    c[ii] = a[ii];
+
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp parallel for
+  for (ii = 0; ii < 10; (ii) = (1 - 1) + (ii))
+    c[ii] = a[ii];
+
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}}
+#pragma omp parallel for
+  for ((ii = 0); ii > 10; (ii -= 0))
+    c[ii] = a[ii];
+
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+#pragma omp parallel for
+  for (ii = 0; (ii < 10); (ii -= 0))
+    c[ii] = a[ii];
+
+// expected-note@+2  {{defined as firstprivate}}
+// expected-error@+2 {{loop iteration variable in the associated loop of 'omp parallel for' directive may not be firstprivate, predetermined as private}}
+#pragma omp parallel for firstprivate(ii)
+  for (ii = 0; ii < 10; ii++)
+    c[ii] = a[ii];
+
+// expected-error@+3 {{unexpected OpenMP clause 'linear' in directive '#pragma omp parallel for'}}
+// expected-note@+2  {{defined as linear}}
+// expected-error@+2 {{loop iteration variable in the associated loop of 'omp parallel for' directive may not be linear, predetermined as private}}
+#pragma omp parallel for linear(ii)
+  for (ii = 0; ii < 10; ii++)
+    c[ii] = a[ii];
+
+#pragma omp parallel for private(ii)
+  for (ii = 0; ii < 10; ii++)
+    c[ii] = a[ii];
+
+#pragma omp parallel for lastprivate(ii)
+  for (ii = 0; ii < 10; ii++)
+    c[ii] = a[ii];
+
+  {
+// expected-error@+2 {{loop iteration variable in the associated loop of 'omp parallel for' directive may not be threadprivate or thread local, predetermined as private}}
+#pragma omp parallel for
+    for (sii = 0; sii < 10; sii += 1)
+      c[sii] = a[sii];
+  }
+
+// expected-error@+2 {{statement after '#pragma omp parallel for' must be a for loop}}
+#pragma omp parallel for
+  for (auto &item : a) {
+    item = item + 1;
+  }
+
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'i' to increase on each iteration of OpenMP for loop}}
+#pragma omp parallel for
+  for (unsigned i = 9; i < 10; i--) {
+    c[i] = a[i] + b[i];
+  }
+
+  int(*lb)[4] = nullptr;
+#pragma omp parallel for
+  for (int(*p)[4] = lb; p < lb + 8; ++p) {
+  }
+
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp parallel for
+  for (int a{0}; a < 10; ++a) {
+  }
+
+  return 0;
+}
+
+// Iterators allowed in openmp for-loops.
+namespace std {
+struct random_access_iterator_tag {};
+template <class Iter>
+struct iterator_traits {
+  typedef typename Iter::difference_type difference_type;
+  typedef typename Iter::iterator_category iterator_category;
+};
+template <class Iter>
+typename iterator_traits<Iter>::difference_type
+distance(Iter first, Iter last) { return first - last; }
+}
+class Iter0 {
+public:
+  Iter0() {}
+  Iter0(const Iter0 &) {}
+  Iter0 operator++() { return *this; }
+  Iter0 operator--() { return *this; }
+  bool operator<(Iter0 a) { return true; }
+};
+int operator-(Iter0 a, Iter0 b) { return 0; }
+class Iter1 {
+public:
+  Iter1(float f = 0.0f, double d = 0.0) {}
+  Iter1(const Iter1 &) {}
+  Iter1 operator++() { return *this; }
+  Iter1 operator--() { return *this; }
+  bool operator<(Iter1 a) { return true; }
+  bool operator>=(Iter1 a) { return false; }
+};
+class GoodIter {
+public:
+  GoodIter() {}
+  GoodIter(const GoodIter &) {}
+  GoodIter(int fst, int snd) {}
+  GoodIter &operator=(const GoodIter &that) { return *this; }
+  GoodIter &operator=(const Iter0 &that) { return *this; }
+  GoodIter &operator+=(int x) { return *this; }
+  explicit GoodIter(void *) {}
+  GoodIter operator++() { return *this; }
+  GoodIter operator--() { return *this; }
+  bool operator!() { return true; }
+  bool operator<(GoodIter a) { return true; }
+  bool operator<=(GoodIter a) { return true; }
+  bool operator>=(GoodIter a) { return false; }
+  typedef int difference_type;
+  typedef std::random_access_iterator_tag iterator_category;
+};
+int operator-(GoodIter a, GoodIter b) { return 0; }
+GoodIter operator-(GoodIter a) { return a; }
+GoodIter operator-(GoodIter a, int v) { return GoodIter(); }
+GoodIter operator+(GoodIter a, int v) { return GoodIter(); }
+GoodIter operator-(int v, GoodIter a) { return GoodIter(); }
+GoodIter operator+(int v, GoodIter a) { return GoodIter(); }
+
+int test_with_random_access_iterator() {
+  GoodIter begin, end;
+  Iter0 begin0, end0;
+#pragma omp parallel for
+  for (GoodIter I = begin; I < end; ++I)
+    ++I;
+// expected-error@+2 {{variable must be of integer or random access iterator type}}
+#pragma omp parallel for
+  for (GoodIter &I = begin; I < end; ++I)
+    ++I;
+#pragma omp parallel for
+  for (GoodIter I = begin; I >= end; --I)
+    ++I;
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp parallel for
+  for (GoodIter I(begin); I < end; ++I)
+    ++I;
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp parallel for
+  for (GoodIter I(nullptr); I < end; ++I)
+    ++I;
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp parallel for
+  for (GoodIter I(0); I < end; ++I)
+    ++I;
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp parallel for
+  for (GoodIter I(1, 2); I < end; ++I)
+    ++I;
+#pragma omp parallel for
+  for (begin = GoodIter(0); begin < end; ++begin)
+    ++begin;
+#pragma omp parallel for
+  for (begin = begin0; begin < end; ++begin)
+    ++begin;
+// expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
+#pragma omp parallel for
+  for (++begin; begin < end; ++begin)
+    ++begin;
+#pragma omp parallel for
+  for (begin = end; begin < end; ++begin)
+    ++begin;
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+#pragma omp parallel for
+  for (GoodIter I = begin; I - I; ++I)
+    ++I;
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+#pragma omp parallel for
+  for (GoodIter I = begin; begin < end; ++I)
+    ++I;
+// expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+#pragma omp parallel for
+  for (GoodIter I = begin; !I; ++I)
+    ++I;
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp parallel for
+  for (GoodIter I = begin; I >= end; I = I + 1)
+    ++I;
+#pragma omp parallel for
+  for (GoodIter I = begin; I >= end; I = I - 1)
+    ++I;
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}}
+#pragma omp parallel for
+  for (GoodIter I = begin; I >= end; I = -I)
+    ++I;
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp parallel for
+  for (GoodIter I = begin; I >= end; I = 2 + I)
+    ++I;
+// expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}}
+#pragma omp parallel for
+  for (GoodIter I = begin; I >= end; I = 2 - I)
+    ++I;
+#pragma omp parallel for
+  for (Iter0 I = begin0; I < end0; ++I)
+    ++I;
+// Initializer is constructor without params.
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp parallel for
+  for (Iter0 I; I < end0; ++I)
+    ++I;
+  Iter1 begin1, end1;
+#pragma omp parallel for
+  for (Iter1 I = begin1; I < end1; ++I)
+    ++I;
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp parallel for
+  for (Iter1 I = begin1; I >= end1; ++I)
+    ++I;
+// Initializer is constructor with all default params.
+// expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+#pragma omp parallel for
+  for (Iter1 I; I < end1; ++I) {
+  }
+  return 0;
+}
+
+template <typename IT, int ST>
+class TC {
+public:
+  int dotest_lt(IT begin, IT end) {
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}}
+#pragma omp parallel for
+    for (IT I = begin; I < end; I = I + ST) {
+      ++I;
+    }
+// expected-note@+3 {{loop step is expected to be positive due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}}
+#pragma omp parallel for
+    for (IT I = begin; I <= end; I += ST) {
+      ++I;
+    }
+#pragma omp parallel for
+    for (IT I = begin; I < end; ++I) {
+      ++I;
+    }
+  }
+
+  static IT step() {
+    return IT(ST);
+  }
+};
+template <typename IT, int ST = 0>
+int dotest_gt(IT begin, IT end) {
+// expected-note@+3 2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp parallel for
+  for (IT I = begin; I >= end; I = I + ST) {
+    ++I;
+  }
+// expected-note@+3 2 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp parallel for
+  for (IT I = begin; I >= end; I += ST) {
+    ++I;
+  }
+
+// expected-note@+3 {{loop step is expected to be negative due to this condition}}
+// expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+#pragma omp parallel for
+  for (IT I = begin; I >= end; ++I) {
+    ++I;
+  }
+
+#pragma omp parallel for
+  for (IT I = begin; I < end; I += TC<int, ST>::step()) {
+    ++I;
+  }
+}
+
+void test_with_template() {
+  GoodIter begin, end;
+  TC<GoodIter, 100> t1;
+  TC<GoodIter, -100> t2;
+  t1.dotest_lt(begin, end);
+  t2.dotest_lt(begin, end);         // expected-note {{in instantiation of member function 'TC<GoodIter, -100>::dotest_lt' requested here}}
+  dotest_gt(begin, end);            // expected-note {{in instantiation of function template specialization 'dotest_gt<GoodIter, 0>' requested here}}
+  dotest_gt<unsigned, -10>(0, 100); // expected-note {{in instantiation of function template specialization 'dotest_gt<unsigned int, -10>' requested here}}
+}
+
+void test_loop_break() {
+  const int N = 100;
+  float a[N], b[N], c[N];
+#pragma omp parallel for
+  for (int i = 0; i < 10; i++) {
+    c[i] = a[i] + b[i];
+    for (int j = 0; j < 10; ++j) {
+      if (a[i] > b[j])
+        break; // OK in nested loop
+    }
+    switch (i) {
+    case 1:
+      b[i]++;
+      break;
+    default:
+      break;
+    }
+    if (c[i] > 10)
+      break; // expected-error {{'break' statement cannot be used in OpenMP for loop}}
+
+    if (c[i] > 11)
+      break; // expected-error {{'break' statement cannot be used in OpenMP for loop}}
+  }
+
+#pragma omp parallel for
+  for (int i = 0; i < 10; i++) {
+    for (int j = 0; j < 10; j++) {
+      c[i] = a[i] + b[i];
+      if (c[i] > 10) {
+        if (c[i] < 20) {
+          break; // OK
+        }
+      }
+    }
+  }
+}
+
+void test_loop_eh() {
+  const int N = 100;
+  float a[N], b[N], c[N];
+#pragma omp parallel for
+  for (int i = 0; i < 10; i++) {
+    c[i] = a[i] + b[i];
+    try {
+      for (int j = 0; j < 10; ++j) {
+        if (a[i] > b[j])
+          throw a[i];
+      }
+      throw a[i];
+    } catch (float f) {
+      if (f > 0.1)
+        throw a[i];
+      return; // expected-error {{cannot return from OpenMP region}}
+    }
+    switch (i) {
+    case 1:
+      b[i]++;
+      break;
+    default:
+      break;
+    }
+    for (int j = 0; j < 10; j++) {
+      if (c[i] > 10)
+        throw c[i];
+    }
+  }
+  if (c[9] > 10)
+    throw c[9]; // OK
+
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i) {
+    struct S {
+      void g() { throw 0; }
+    };
+  }
+}
+
+void test_loop_firstprivate_lastprivate() {
+  S s(4);
+#pragma omp parallel for lastprivate(s) firstprivate(s)
+  for (int i = 0; i < 16; ++i)
+    ;
+}
diff --git a/test/OpenMP/parallel_for_messages.cpp b/test/OpenMP/parallel_for_messages.cpp
new file mode 100644
index 0000000..e4ea0d5
--- /dev/null
+++ b/test/OpenMP/parallel_for_messages.cpp
@@ -0,0 +1,86 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -std=c++11 -o - %s
+
+void foo() {
+}
+
+#pragma omp parallel for // expected-error {{unexpected OpenMP directive '#pragma omp parallel for'}}
+
+int main(int argc, char **argv) {
+#pragma omp parallel for { // expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for ( // expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for[ // expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for] // expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for) // expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for } // expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for
+  for (int i = 0; i < argc; ++i)
+    foo();
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+#pragma omp parallel for unknown()
+  for (int i = 0; i < argc; ++i)
+    foo();
+L1:
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for
+  for (int i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for
+  for (int i = 0; i < argc; ++i) {
+    goto L1; // expected-error {{use of undeclared label 'L1'}}
+    argc++;
+  }
+
+  for (int i = 0; i < 10; ++i) {
+    switch (argc) {
+    case (0):
+#pragma omp parallel for
+      for (int i = 0; i < argc; ++i) {
+        foo();
+        break; // expected-error {{'break' statement cannot be used in OpenMP for loop}}
+        continue;
+      }
+    default:
+      break;
+    }
+  }
+#pragma omp parallel for default(none)
+  for (int i = 0; i < 10; ++i)
+    ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
+
+  goto L2; // expected-error {{use of undeclared label 'L2'}}
+#pragma omp parallel for
+  for (int i = 0; i < argc; ++i)
+  L2:
+  foo();
+#pragma omp parallel for
+  for (int i = 0; i < argc; ++i) {
+    return 1; // expected-error {{cannot return from OpenMP region}}
+  }
+
+  [[]] // expected-error {{an attribute list cannot appear here}}
+#pragma omp parallel for
+      for (int n = 0; n < 100; ++n) {
+  }
+
+  return 0;
+}
+
+void test_ordered() {
+#pragma omp parallel for ordered ordered // expected-error {{directive '#pragma omp parallel for' cannot contain more than one 'ordered' clause}}
+  for (int i = 0; i < 16; ++i)
+    ;
+}
+
diff --git a/test/OpenMP/parallel_for_misc_messages.c b/test/OpenMP/parallel_for_misc_messages.c
new file mode 100644
index 0000000..b236a61
--- /dev/null
+++ b/test/OpenMP/parallel_for_misc_messages.c
@@ -0,0 +1,309 @@
+// RUN: %clang_cc1 -fsyntax-only -fopenmp=libiomp5 -verify %s
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp parallel for'}}
+#pragma omp parallel for
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp parallel for'}}
+#pragma omp parallel for foo
+
+void test_no_clause() {
+  int i;
+#pragma omp parallel for
+  for (i = 0; i < 16; ++i)
+    ;
+
+// expected-error@+2 {{statement after '#pragma omp parallel for' must be a for loop}}
+#pragma omp parallel for
+  ++i;
+}
+
+void test_branch_protected_scope() {
+  int i = 0;
+L1:
+  ++i;
+
+  int x[24];
+
+#pragma omp parallel for
+  for (i = 0; i < 16; ++i) {
+    if (i == 5)
+      goto L1; // expected-error {{use of undeclared label 'L1'}}
+    else if (i == 6)
+      return; // expected-error {{cannot return from OpenMP region}}
+    else if (i == 7)
+      goto L2;
+    else if (i == 8) {
+    L2:
+      x[i]++;
+    }
+  }
+
+  if (x[0] == 0)
+    goto L2; // expected-error {{use of undeclared label 'L2'}}
+  else if (x[1] == 1)
+    goto L1;
+}
+
+void test_invalid_clause() {
+  int i;
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+#pragma omp parallel for foo bar
+  for (i = 0; i < 16; ++i)
+    ;
+}
+
+void test_non_identifiers() {
+  int i, x;
+
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+#pragma omp parallel for;
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+2 {{unexpected OpenMP clause 'linear' in directive '#pragma omp parallel for'}}
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+#pragma omp parallel for linear(x);
+  for (i = 0; i < 16; ++i)
+    ;
+
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+#pragma omp parallel for private(x);
+  for (i = 0; i < 16; ++i)
+    ;
+
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+#pragma omp parallel for, private(x);
+  for (i = 0; i < 16; ++i)
+    ;
+}
+
+extern int foo();
+
+void test_collapse() {
+  int i;
+// expected-error@+1 {{expected '('}}
+#pragma omp parallel for collapse
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp parallel for collapse(
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp parallel for collapse()
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp parallel for collapse(,
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}  expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp parallel for collapse(, )
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-warning@+2 {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+// expected-error@+1 {{expected '('}}
+#pragma omp parallel for collapse 4)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp parallel for collapse(4
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp parallel for', but found only 1}}
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp parallel for collapse(4,
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp parallel for', but found only 1}}
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp parallel for collapse(4, )
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp parallel for', but found only 1}}
+// expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp parallel for collapse(4)
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp parallel for', but found only 1}}
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp parallel for collapse(4 4)
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp parallel for', but found only 1}}
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp parallel for collapse(4, , 4)
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp parallel for', but found only 1}}
+#pragma omp parallel for collapse(4)
+  for (int i1 = 0; i1 < 16; ++i1)
+    for (int i2 = 0; i2 < 16; ++i2)
+      for (int i3 = 0; i3 < 16; ++i3)
+        for (int i4 = 0; i4 < 16; ++i4)
+          foo();
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+#pragma omp parallel for collapse(4, 8)
+  for (i = 0; i < 16; ++i)
+    ; // expected-error {{expected 4 for loops after '#pragma omp parallel for', but found only 1}}
+// expected-error@+1 {{expression is not an integer constant expression}}
+#pragma omp parallel for collapse(2.5)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expression is not an integer constant expression}}
+#pragma omp parallel for collapse(foo())
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}}
+#pragma omp parallel for collapse(-5)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}}
+#pragma omp parallel for collapse(0)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}}
+#pragma omp parallel for collapse(5 - 5)
+  for (i = 0; i < 16; ++i)
+    ;
+}
+
+void test_private() {
+  int i;
+// expected-error@+2 {{expected expression}}
+// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp parallel for private(
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp parallel for private(,
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 2 {{expected expression}}
+#pragma omp parallel for private(, )
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp parallel for private()
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp parallel for private(int)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected variable name}}
+#pragma omp parallel for private(0)
+  for (i = 0; i < 16; ++i)
+    ;
+
+  int x, y, z;
+#pragma omp parallel for private(x)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel for private(x, y)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel for private(x, y, z)
+  for (i = 0; i < 16; ++i) {
+    x = y * i + z;
+  }
+}
+
+void test_lastprivate() {
+  int i;
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 {{expected expression}}
+#pragma omp parallel for lastprivate(
+  for (i = 0; i < 16; ++i)
+    ;
+
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp parallel for lastprivate(,
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 2 {{expected expression}}
+#pragma omp parallel for lastprivate(, )
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp parallel for lastprivate()
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp parallel for lastprivate(int)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected variable name}}
+#pragma omp parallel for lastprivate(0)
+  for (i = 0; i < 16; ++i)
+    ;
+
+  int x, y, z;
+#pragma omp parallel for lastprivate(x)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel for lastprivate(x, y)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel for lastprivate(x, y, z)
+  for (i = 0; i < 16; ++i)
+    ;
+}
+
+void test_firstprivate() {
+  int i;
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 {{expected expression}}
+#pragma omp parallel for firstprivate(
+  for (i = 0; i < 16; ++i)
+    ;
+
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp parallel for firstprivate(,
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 2 {{expected expression}}
+#pragma omp parallel for firstprivate(, )
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp parallel for firstprivate()
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected expression}}
+#pragma omp parallel for firstprivate(int)
+  for (i = 0; i < 16; ++i)
+    ;
+// expected-error@+1 {{expected variable name}}
+#pragma omp parallel for firstprivate(0)
+  for (i = 0; i < 16; ++i)
+    ;
+
+  int x, y, z;
+#pragma omp parallel for lastprivate(x) firstprivate(x)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel for lastprivate(x, y) firstprivate(x, y)
+  for (i = 0; i < 16; ++i)
+    ;
+#pragma omp parallel for lastprivate(x, y, z) firstprivate(x, y, z)
+  for (i = 0; i < 16; ++i)
+    ;
+}
+
+void test_loop_messages() {
+  float a[100], b[100], c[100];
+// expected-error@+2 {{variable must be of integer or pointer type}}
+#pragma omp parallel for
+  for (float fi = 0; fi < 10.0; fi++) {
+    c[(int)fi] = a[(int)fi] + b[(int)fi];
+  }
+// expected-error@+2 {{variable must be of integer or pointer type}}
+#pragma omp parallel for
+  for (double fi = 0; fi < 10.0; fi++) {
+    c[(int)fi] = a[(int)fi] + b[(int)fi];
+  }
+}
+
diff --git a/test/OpenMP/parallel_for_num_threads_messages.cpp b/test/OpenMP/parallel_for_num_threads_messages.cpp
new file mode 100644
index 0000000..e192898
--- /dev/null
+++ b/test/OpenMP/parallel_for_num_threads_messages.cpp
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, typename S, int N> // expected-note {{declared here}}
+T tmain(T argc, S **argv) {
+  T i;
+  #pragma omp parallel for num_threads // expected-error {{expected '(' after 'num_threads'}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads () // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads ((argc > 0) ? argv[1] : argv[2]) // expected-error 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp parallel for' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a positive integer value}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads (S) // expected-error {{'S' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads (argc)
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads (N) // expected-error {{argument to 'num_threads' clause must be a positive integer value}}
+  for (i = 0; i < argc; ++i) foo();
+
+  return argc;
+}
+
+int main(int argc, char **argv) {
+  int i;
+  #pragma omp parallel for num_threads // expected-error {{expected '(' after 'num_threads'}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads () // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads (argc > 0 ? argv[1] : argv[2]) // expected-error {{integral }}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp parallel for' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a positive integer value}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads (S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  for (i = 0; i < argc; ++i) foo();
+  #pragma omp parallel for num_threads (num_threads(tmain<int, char, -1>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} expected-note {{in instantiation of function template specialization 'tmain<int, char, -1>' requested here}}
+  for (i = 0; i < argc; ++i) foo();
+
+  return tmain<int, char, 3>(argc, argv); // expected-note {{in instantiation of function template specialization 'tmain<int, char, 3>' requested here}}
+}
diff --git a/test/OpenMP/parallel_for_private_messages.cpp b/test/OpenMP/parallel_for_private_messages.cpp
new file mode 100644
index 0000000..7366fe8
--- /dev/null
+++ b/test/OpenMP/parallel_for_private_messages.cpp
@@ -0,0 +1,173 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+};
+const S2 b;
+const S2 ba[5];
+class S3 {
+  int a;
+
+public:
+  S3() : a(0) {}
+};
+const S3 ca[5];
+class S4 { // expected-note {{'S4' declared here}}
+  int a;
+  S4();
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note {{'S5' declared here}}
+  int a;
+  S5() : a(0) {}
+
+public:
+  S5(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(I argc, C **argv) {
+  I e(4);
+  I g(5);
+  int i;
+  int &j = i;           // expected-note {{'j' defined here}}
+#pragma omp parallel for private // expected-error {{expected '(' after 'private'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private() // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(argc)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(e, g)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for nowait // expected-error {{unexpected OpenMP clause 'nowait' in directive '#pragma omp parallel for'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;
+#pragma omp parallel for private(i)
+    for (int k = 0; k < argc; ++k) {
+      i = k;
+      v += i;
+    }
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp parallel for private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(i)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  S4 e(4); // expected-note {{'e' defined here}}
+  S5 g(5); // expected-note {{'g' defined here}}
+  int i;
+  int &j = i;           // expected-note {{'j' defined here}}
+#pragma omp parallel for private // expected-error {{expected '(' after 'private'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private() // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(argc)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(e, g) // expected-error 2 {{private variable must have an accessible, unambiguous default constructor}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for nowait // expected-error {{unexpected OpenMP clause 'nowait' in directive '#pragma omp parallel for'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+  {
+    int i;
+#pragma omp parallel for private(i)
+    for (int k = 0; k < argc; ++k)
+      ++k;
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp parallel for private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel for private(i)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+
+  return 0;
+}
+
diff --git a/test/OpenMP/parallel_for_proc_bind_messages.cpp b/test/OpenMP/parallel_for_proc_bind_messages.cpp
new file mode 100644
index 0000000..0347caf
--- /dev/null
+++ b/test/OpenMP/parallel_for_proc_bind_messages.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -o - %s
+
+void foo();
+
+int main(int argc, char **argv) {
+  int i;
+#pragma omp parallel for proc_bind // expected-error {{expected '(' after 'proc_bind'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for proc_bind( // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for proc_bind() // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for proc_bind(master // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for proc_bind(close), proc_bind(spread) // expected-error {{directive '#pragma omp parallel for' cannot contain more than one 'proc_bind' clause}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel for proc_bind(x) // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+
+#pragma omp parallel for proc_bind(master)
+  for (i = 0; i < argc; ++i)
+    foo();
+
+#pragma omp parallel proc_bind(close)
+#pragma omp parallel for proc_bind(spread)
+  for (i = 0; i < argc; ++i)
+    foo();
+  return 0;
+}
diff --git a/test/OpenMP/parallel_for_reduction_messages.cpp b/test/OpenMP/parallel_for_reduction_messages.cpp
new file mode 100644
index 0000000..8e482ef
--- /dev/null
+++ b/test/OpenMP/parallel_for_reduction_messages.cpp
@@ -0,0 +1,295 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+  S2 &operator+=(const S2 &arg) { return (*this); }
+
+public:
+  S2() : a(0) {}
+  S2(S2 &s2) : a(s2.a) {}
+  static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
+  static const float S2sc;
+};
+const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+S2 b;                     // expected-note 2 {{'b' defined here}}
+const S2 ba[5];           // expected-note 2 {{'ba' defined here}}
+class S3 {
+  int a;
+
+public:
+  S3() : a(0) {}
+  S3(const S3 &s3) : a(s3.a) {}
+  S3 operator+=(const S3 &arg1) { return arg1; }
+};
+int operator+=(const S3 &arg1, const S3 &arg2) { return 5; }
+S3 c;               // expected-note 2 {{'c' defined here}}
+const S3 ca[5];     // expected-note 2 {{'ca' defined here}}
+extern const int f; // expected-note 4 {{'f' declared here}}
+class S4 {          // expected-note {{'S4' declared here}}
+  int a;
+  S4();
+  S4(const S4 &s4);
+  S4 &operator+=(const S4 &arg) { return (*this); }
+
+public:
+  S4(int v) : a(v) {}
+};
+S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; }
+class S5 {
+  int a;
+  S5() : a(0) {}
+  S5(const S5 &s5) : a(s5.a) {}
+  S5 &operator+=(const S5 &arg);
+
+public:
+  S5(int v) : a(v) {}
+};
+class S6 {
+  int a;
+
+public:
+  S6() : a(6) {}
+  operator int() { return 6; }
+} o; // expected-note 2 {{'o' defined here}}
+
+S3 h, k;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class T>       // expected-note {{declared here}}
+T tmain(T argc) {        // expected-note 2 {{'argc' defined here}}
+  const T d = T();       // expected-note 4 {{'d' defined here}}
+  const T da[5] = {T()}; // expected-note 2 {{'da' defined here}}
+  T qa[5] = {T()};
+  T i;
+  T &j = i;                        // expected-note 4 {{'j' defined here}}
+  S3 &p = k;                       // expected-note 2 {{'p' defined here}}
+  const T &r = da[(int)i];         // expected-note 2 {{'r' defined here}}
+  T &q = qa[(int)i];               // expected-note 2 {{'q' defined here}}
+  T fl;                            // expected-note {{'fl' defined here}}
+#pragma omp parallel for reduction // expected-error {{expected '(' after 'reduction'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(&& : argc)
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(^ : T) // expected-error {{'T' does not refer to a value}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(max : qa[1]) // expected-error 2 {{expected variable name}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel private(k)
+#pragma omp parallel for reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp parallel for reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel private(fl)
+#pragma omp parallel for reduction(+ : fl)
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel reduction(* : fl)
+#pragma omp parallel for reduction(+ : fl)
+  for (int i = 0; i < 10; ++i)
+    foo();
+
+  return T();
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;       // expected-note 2 {{'d' defined here}}
+  const int da[5] = {0}; // expected-note {{'da' defined here}}
+  int qa[5] = {0};
+  S4 e(4); // expected-note {{'e' defined here}}
+  S5 g(5); // expected-note {{'g' defined here}}
+  int i;
+  int &j = i;                      // expected-note 2 {{'j' defined here}}
+  S3 &p = k;                       // expected-note 2 {{'p' defined here}}
+  const int &r = da[i];            // expected-note {{'r' defined here}}
+  int &q = qa[i];                  // expected-note {{'q' defined here}}
+  float fl;                        // expected-note {{'fl' defined here}}
+#pragma omp parallel for reduction // expected-error {{expected '(' after 'reduction'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(foo : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(~ : argc) // expected-error {{expected unqualified-id}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(&& : argc)
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(max : argv[1]) // expected-error {{expected variable name}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(& : e, g) // expected-error {{reduction variable must have an accessible, unambiguous default constructor}} expected-error {{variable of type 'S5' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for private(i), reduction(+ : j), reduction(+ : q) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel private(k)
+#pragma omp parallel for reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel for reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp parallel for reduction(max : j) // expected-error {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel private(fl)
+#pragma omp parallel for reduction(+ : fl)
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel reduction(* : fl)
+#pragma omp parallel for reduction(+ : fl)
+  for (int i = 0; i < 10; ++i)
+    foo();
+
+  return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain<int>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<float>' requested here}}
+}
diff --git a/test/OpenMP/parallel_for_schedule_messages.cpp b/test/OpenMP/parallel_for_schedule_messages.cpp
new file mode 100644
index 0000000..b03758a
--- /dev/null
+++ b/test/OpenMP/parallel_for_schedule_messages.cpp
@@ -0,0 +1,91 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, typename S, int N, int ST> // expected-note {{declared here}}
+T tmain(T argc, S **argv) {
+  #pragma omp parallel for schedule // expected-error {{expected '(' after 'schedule'}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for schedule (auto // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for schedule (auto,  // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for schedule (runtime, 3)  // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  // expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+  #pragma omp parallel for schedule (guided argc
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  // expected-error@+1 2 {{argument to 'schedule' clause must be a positive integer value}}
+  #pragma omp parallel for schedule (static, ST // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for schedule (dynamic, 1)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for schedule (guided, (ST > 0) ? 1 + ST : 2)
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  // expected-error@+2 2 {{directive '#pragma omp parallel for' cannot contain more than one 'schedule' clause}}
+  // expected-error@+1 {{argument to 'schedule' clause must be a positive integer value}}
+  #pragma omp parallel for schedule (static, foobool(argc)), schedule (dynamic, true), schedule (guided, -5)
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for schedule (static, S) // expected-error {{'S' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  // expected-error@+1 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  #pragma omp parallel for schedule (guided, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for schedule (dynamic, 1)
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp parallel for schedule (static, N) // expected-error {{argument to 'schedule' clause must be a positive integer value}}
+  for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  return argc;
+}
+
+int main(int argc, char **argv) {
+  #pragma omp parallel for schedule // expected-error {{expected '(' after 'schedule'}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp parallel for schedule ( // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp parallel for schedule () // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp parallel for schedule (auto // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp parallel for schedule (auto_dynamic // expected-error {{expected 'static', 'dynamic', 'guided', 'auto' or 'runtime' in OpenMP clause 'schedule'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp parallel for schedule (auto,  // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp parallel for schedule (runtime, 3)  // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp parallel for schedule (guided, 4 // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp parallel for schedule (static, 2+2)) // expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp parallel for schedule (dynamic, foobool(1) > 0 ? 1 : 2)
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  // expected-error@+2 2 {{directive '#pragma omp parallel for' cannot contain more than one 'schedule' clause}}
+  // expected-error@+1 {{argument to 'schedule' clause must be a positive integer value}}
+  #pragma omp parallel for schedule (guided, foobool(argc)), schedule (static, true), schedule (dynamic, -5)
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp parallel for schedule (guided, S1) // expected-error {{'S1' does not refer to a value}} expected-warning {{extra tokens at the end of '#pragma omp parallel for' are ignored}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  // expected-error@+1 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  #pragma omp parallel for schedule (static, argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  // expected-error@+3 {{statement after '#pragma omp parallel for' must be a for loop}}
+  // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
+  #pragma omp parallel for schedule(dynamic, schedule(tmain<int, char, -1, -2>(argc, argv) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+  // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, 1, 0>' requested here}}
+  return tmain<int, char, 1, 0>(argc, argv);
+}
+
diff --git a/test/OpenMP/parallel_if_messages.cpp b/test/OpenMP/parallel_if_messages.cpp
new file mode 100644
index 0000000..1559692
--- /dev/null
+++ b/test/OpenMP/parallel_if_messages.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, class S> // expected-note {{declared here}}
+int tmain(T argc, S **argv) {
+  #pragma omp parallel if // expected-error {{expected '(' after 'if'}}
+  #pragma omp parallel if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp parallel if () // expected-error {{expected expression}}
+  #pragma omp parallel if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp parallel if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp parallel' are ignored}}
+  #pragma omp parallel if (argc > 0 ? argv[1] : argv[2])
+  #pragma omp parallel if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp parallel' cannot contain more than one 'if' clause}}
+  #pragma omp parallel if (S) // expected-error {{'S' does not refer to a value}}
+  #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)
+  foo();
+
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  #pragma omp parallel if // expected-error {{expected '(' after 'if'}}
+  #pragma omp parallel if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp parallel if () // expected-error {{expected expression}}
+  #pragma omp parallel if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp parallel if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp parallel' are ignored}}
+  #pragma omp parallel if (argc > 0 ? argv[1] : argv[2])
+  #pragma omp parallel if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp parallel' cannot contain more than one 'if' clause}}
+  #pragma omp parallel if (S1) // expected-error {{'S1' does not refer to a value}}
+  #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 (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 '('}}
+  foo();
+
+  return tmain(argc, argv);
+}
diff --git a/test/OpenMP/parallel_messages.cpp b/test/OpenMP/parallel_messages.cpp
index d991ccf..1e0edbc 100644
--- a/test/OpenMP/parallel_messages.cpp
+++ b/test/OpenMP/parallel_messages.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -std=c++11 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -std=c++11 -o - %s
 
 void foo() {
 }
@@ -6,8 +6,21 @@
 #pragma omp parallel // expected-error {{unexpected OpenMP directive '#pragma omp parallel'}}
 
 int main(int argc, char **argv) {
+  #pragma omp parallel { // expected-warning {{extra tokens at the end of '#pragma omp parallel' are ignored}}
+  foo();
+  #pragma omp parallel ( // expected-warning {{extra tokens at the end of '#pragma omp parallel' are ignored}}
+  foo();
+  #pragma omp parallel [ // expected-warning {{extra tokens at the end of '#pragma omp parallel' are ignored}}
+  foo();
+  #pragma omp parallel ] // expected-warning {{extra tokens at the end of '#pragma omp parallel' are ignored}}
+  foo();
+  #pragma omp parallel ) // expected-warning {{extra tokens at the end of '#pragma omp parallel' are ignored}}
+  foo();
+  #pragma omp parallel } // expected-warning {{extra tokens at the end of '#pragma omp parallel' are ignored}}
+  foo();
   #pragma omp parallel
-  #pragma omp parallel unknown() // expected-warning {{extra tokens at the end of '#pragma omp parallel' are ignored}}
+  // expected-warning@+1 {{extra tokens at the end of '#pragma omp parallel' are ignored}}
+  #pragma omp parallel unknown()
   foo();
   L1:
     foo();
diff --git a/test/OpenMP/parallel_num_threads_messages.cpp b/test/OpenMP/parallel_num_threads_messages.cpp
new file mode 100644
index 0000000..facca5e
--- /dev/null
+++ b/test/OpenMP/parallel_num_threads_messages.cpp
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, typename S, int N> // expected-note {{declared here}}
+T tmain(T argc, S **argv) {
+  #pragma omp parallel num_threads // expected-error {{expected '(' after 'num_threads'}}
+  #pragma omp parallel num_threads ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp parallel num_threads () // expected-error {{expected expression}}
+  #pragma omp parallel num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp parallel num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp parallel' are ignored}}
+  #pragma omp parallel num_threads ((argc > 0) ? argv[1] : argv[2]) // expected-error 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  #pragma omp parallel num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp parallel' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a positive integer value}}
+  #pragma omp parallel num_threads (S) // expected-error {{'S' does not refer to a value}}
+  #pragma omp parallel 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 *'}}
+  #pragma omp parallel num_threads (argc)
+  #pragma omp parallel num_threads (N) // expected-error {{argument to 'num_threads' clause must be a positive integer value}}
+  foo();
+
+  return argc;
+}
+
+int main(int argc, char **argv) {
+  #pragma omp parallel num_threads // expected-error {{expected '(' after 'num_threads'}}
+  #pragma omp parallel num_threads ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp parallel num_threads () // expected-error {{expected expression}}
+  #pragma omp parallel num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp parallel num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp parallel' are ignored}}
+  #pragma omp parallel num_threads (argc > 0 ? argv[1] : argv[2]) // expected-error {{integral }}
+  #pragma omp parallel num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp parallel' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a positive integer value}}
+  #pragma omp parallel num_threads (S1) // expected-error {{'S1' does not refer to a value}}
+  #pragma omp parallel 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 *'}}
+  #pragma omp parallel num_threads (num_threads(tmain<int, char, -1>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} expected-note {{in instantiation of function template specialization 'tmain<int, char, -1>' requested here}}
+  foo();
+
+  return tmain<int, char, 3>(argc, argv); // expected-note {{in instantiation of function template specialization 'tmain<int, char, 3>' requested here}}
+}
diff --git a/test/OpenMP/parallel_private_messages.cpp b/test/OpenMP/parallel_private_messages.cpp
index 2037d56..1cd86d2 100644
--- a/test/OpenMP/parallel_private_messages.cpp
+++ b/test/OpenMP/parallel_private_messages.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 %s
 
 void foo() {
 }
@@ -13,7 +13,7 @@
   mutable int a;
 public:
   S2():a(0) { }
-  static float S2s; // expected-note {{predetermined as shared}}
+  static float S2s; // expected-note {{static data member is predetermined as shared}}
 };
 const S2 b;
 const S2 ba[5];
@@ -22,9 +22,9 @@
 public:
   S3():a(0) { }
 };
-const S3 c; // expected-note {{predetermined as shared}}
-const S3 ca[5]; // expected-note {{predetermined as shared}}
-extern const int f; // expected-note {{predetermined as shared}}
+const S3 c; // expected-note {{global variable is predetermined as shared}}
+const S3 ca[5]; // expected-note {{global variable is predetermined as shared}}
+extern const int f; // expected-note {{global variable is predetermined as shared}}
 class S4 { // expected-note {{'S4' declared here}}
   int a;
   S4();
@@ -42,8 +42,8 @@
 #pragma omp threadprivate(threadvar) // expected-note {{defined as threadprivate or thread local}}
 
 int main(int argc, char **argv) {
-  const int d = 5; // expected-note {{predetermined as shared}}
-  const int da[5] = { 0 }; // expected-note {{predetermined as shared}}
+  const int d = 5; // expected-note {{constant variable is predetermined as shared}}
+  const int da[5] = { 0 }; // expected-note {{constant variable is predetermined as shared}}
   S4 e(4); // expected-note {{'e' defined here}}
   S5 g(5); // expected-note {{'g' defined here}}
   int i;
diff --git a/test/OpenMP/parallel_proc_bind_messages.cpp b/test/OpenMP/parallel_proc_bind_messages.cpp
new file mode 100644
index 0000000..0bb9fc7
--- /dev/null
+++ b/test/OpenMP/parallel_proc_bind_messages.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -o - %s
+
+void foo();
+
+int main(int argc, char **argv) {
+  #pragma omp parallel proc_bind // expected-error {{expected '(' after 'proc_bind'}}
+  #pragma omp parallel proc_bind ( // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp parallel proc_bind () // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}}
+  #pragma omp parallel proc_bind (master // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp parallel proc_bind (close), proc_bind(spread) // expected-error {{directive '#pragma omp parallel' cannot contain more than one 'proc_bind' clause}}
+  #pragma omp parallel proc_bind (x) // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}}
+  foo();
+
+  #pragma omp parallel proc_bind(master)
+  ++argc;
+
+  #pragma omp parallel proc_bind(close)
+  #pragma omp parallel proc_bind(spread)
+  ++argc;
+  return 0;
+}
diff --git a/test/OpenMP/parallel_reduction_messages.cpp b/test/OpenMP/parallel_reduction_messages.cpp
new file mode 100644
index 0000000..43ebc01
--- /dev/null
+++ b/test/OpenMP/parallel_reduction_messages.cpp
@@ -0,0 +1,240 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+  S2 &operator+=(const S2 &arg) { return (*this); }
+
+public:
+  S2() : a(0) {}
+  S2(S2 &s2) : a(s2.a) {}
+  static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
+  static const float S2sc;
+};
+const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+S2 b;                     // expected-note 2 {{'b' defined here}}
+const S2 ba[5];           // expected-note 2 {{'ba' defined here}}
+class S3 {
+  int a;
+
+public:
+  S3() : a(0) {}
+  S3(const S3 &s3) : a(s3.a) {}
+  S3 operator+=(const S3 &arg1) { return arg1; }
+};
+int operator+=(const S3 &arg1, const S3 &arg2) { return 5; }
+S3 c;               // expected-note 2 {{'c' defined here}}
+const S3 ca[5];     // expected-note 2 {{'ca' defined here}}
+extern const int f; // expected-note 4 {{'f' declared here}}
+class S4 {          // expected-note {{'S4' declared here}}
+  int a;
+  S4();
+  S4(const S4 &s4);
+  S4 &operator+=(const S4 &arg) { return (*this); }
+
+public:
+  S4(int v) : a(v) {}
+};
+S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; }
+class S5 {
+  int a;
+  S5() : a(0) {}
+  S5(const S5 &s5) : a(s5.a) {}
+  S5 &operator+=(const S5 &arg);
+
+public:
+  S5(int v) : a(v) {}
+};
+class S6 {
+  int a;
+
+public:
+  S6() : a(6) {}
+  operator int() { return 6; }
+} o; // expected-note 2 {{'o' defined here}}
+
+S3 h, k;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class T>       // expected-note {{declared here}}
+T tmain(T argc) {        // expected-note 2 {{'argc' defined here}}
+  const T d = T();       // expected-note 4 {{'d' defined here}}
+  const T da[5] = {T()}; // expected-note 2 {{'da' defined here}}
+  T qa[5] = {T()};
+  T i;
+  T &j = i;                    // expected-note 4 {{'j' defined here}}
+  S3 &p = k;                   // expected-note 2 {{'p' defined here}}
+  const T &r = da[(int)i];     // expected-note 2 {{'r' defined here}}
+  T &q = qa[(int)i];           // expected-note 2 {{'q' defined here}}
+  T fl;                        // expected-note {{'fl' defined here}}
+#pragma omp parallel reduction // expected-error {{expected '(' after 'reduction'}}
+  foo();
+#pragma omp parallel reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp parallel' are ignored}}
+  foo();
+#pragma omp parallel reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp parallel reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp parallel reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  foo();
+#pragma omp parallel reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+  foo();
+#pragma omp parallel reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  foo();
+#pragma omp parallel reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  foo();
+#pragma omp parallel reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  foo();
+#pragma omp parallel reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name}}
+  foo();
+#pragma omp parallel reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+  foo();
+#pragma omp parallel reduction(&& : argc)
+  foo();
+#pragma omp parallel reduction(^ : T) // expected-error {{'T' does not refer to a value}}
+  foo();
+#pragma omp parallel reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}}
+  foo();
+#pragma omp parallel reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
+  foo();
+#pragma omp parallel reduction(max : qa[1]) // expected-error 2 {{expected variable name}}
+  foo();
+#pragma omp parallel reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}}
+  foo();
+#pragma omp parallel reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}}
+  foo();
+#pragma omp parallel reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}}
+  foo();
+#pragma omp parallel reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  foo();
+#pragma omp parallel reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+  foo();
+#pragma omp parallel reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
+  foo();
+#pragma omp parallel reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+  foo();
+#pragma omp parallel reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}}
+  foo();
+#pragma omp parallel private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  foo();
+#pragma omp parallel private(k)
+#pragma omp parallel reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  foo();
+#pragma omp parallel reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}}
+  foo();
+#pragma omp parallel reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
+  foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp parallel reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  foo();
+#pragma omp parallel
+#pragma omp for private(fl)
+  for (int i = 0; i < 10; ++i)
+#pragma omp parallel reduction(+ : fl)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(- : fl)
+  for (int i = 0; i < 10; ++i)
+#pragma omp parallel reduction(+ : fl)
+    foo();
+
+  return T();
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;       // expected-note 2 {{'d' defined here}}
+  const int da[5] = {0}; // expected-note {{'da' defined here}}
+  int qa[5] = {0};
+  S4 e(4); // expected-note {{'e' defined here}}
+  S5 g(5); // expected-note {{'g' defined here}}
+  int i;
+  int &j = i;                  // expected-note 2 {{'j' defined here}}
+  S3 &p = k;                   // expected-note 2 {{'p' defined here}}
+  const int &r = da[i];        // expected-note {{'r' defined here}}
+  int &q = qa[i];              // expected-note {{'q' defined here}}
+  float fl;                    // expected-note {{'fl' defined here}}
+#pragma omp parallel reduction // expected-error {{expected '(' after 'reduction'}}
+  foo();
+#pragma omp parallel reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp parallel' are ignored}}
+  foo();
+#pragma omp parallel reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp parallel reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp parallel reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  foo();
+#pragma omp parallel reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+  foo();
+#pragma omp parallel reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  foo();
+#pragma omp parallel reduction(foo : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+  foo();
+#pragma omp parallel reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp parallel reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  foo();
+#pragma omp parallel reduction(~ : argc) // expected-error {{expected unqualified-id}}
+  foo();
+#pragma omp parallel reduction(&& : argc)
+  foo();
+#pragma omp parallel reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
+  foo();
+#pragma omp parallel reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}}
+  foo();
+#pragma omp parallel reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}}
+  foo();
+#pragma omp parallel reduction(max : argv[1]) // expected-error {{expected variable name}}
+  foo();
+#pragma omp parallel reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}}
+  foo();
+#pragma omp parallel reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}}
+  foo();
+#pragma omp parallel reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}}
+  foo();
+#pragma omp parallel reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  foo();
+#pragma omp parallel reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+  foo();
+#pragma omp parallel reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
+  foo();
+#pragma omp parallel reduction(& : e, g) // expected-error {{reduction variable must have an accessible, unambiguous default constructor}} expected-error {{variable of type 'S5' is not valid for specified reduction operation}}
+  foo();
+#pragma omp parallel reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+  foo();
+#pragma omp parallel reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}}
+  foo();
+#pragma omp parallel private(i), reduction(+ : j), reduction(+ : q) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  foo();
+#pragma omp parallel private(k)
+#pragma omp parallel reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  foo();
+#pragma omp parallel reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
+  foo();
+#pragma omp parallel reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
+  foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp parallel reduction(max : j) // expected-error {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  foo();
+#pragma omp parallel
+#pragma omp for private(fl)
+  for (int i = 0; i < 10; ++i)
+#pragma omp parallel reduction(+ : fl)
+    foo();
+#pragma omp parallel
+#pragma omp for reduction(- : fl)
+  for (int i = 0; i < 10; ++i)
+#pragma omp parallel reduction(+ : fl)
+    foo();
+
+  return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain<int>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<float>' requested here}}
+}
diff --git a/test/OpenMP/parallel_sections_ast_print.cpp b/test/OpenMP/parallel_sections_ast_print.cpp
new file mode 100644
index 0000000..43665f7
--- /dev/null
+++ b/test/OpenMP/parallel_sections_ast_print.cpp
@@ -0,0 +1,144 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+void foo() {}
+
+template <class T>
+struct S {
+  operator T() { return T(); }
+  static T TS;
+#pragma omp threadprivate(TS)
+};
+
+// CHECK:      template <class T = int> struct S {
+// CHECK:        static int TS;
+// CHECK-NEXT:   #pragma omp threadprivate(S<int>::TS)
+// CHECK-NEXT: }
+// CHECK:      template <class T = long> struct S {
+// CHECK:        static long TS;
+// CHECK-NEXT:   #pragma omp threadprivate(S<long>::TS)
+// CHECK-NEXT: }
+// CHECK:      template <class T> struct S {
+// CHECK:        static T TS;
+// CHECK-NEXT:   #pragma omp threadprivate(S::TS)
+// CHECK:      };
+
+template <typename T, int C>
+T tmain(T argc, T *argv) {
+  T b = argc, c, d, e, f, g;
+  static T a;
+  S<T> s;
+#pragma omp parallel sections
+  {
+    a = 2;
+  }
+#pragma omp parallel sections default(none), private(argc, b) firstprivate(argv) shared(d) if (argc > 0) num_threads(C) copyin(S < T > ::TS) proc_bind(master) reduction(+ : c) reduction(max : e)
+  {
+    foo();
+  }
+#pragma omp parallel sections if (C) num_threads(s) proc_bind(close) reduction(^ : e, f) reduction(&& : g) lastprivate(b, c)
+  {
+    foo();
+#pragma omp section
+    foo();
+  }
+  return 0;
+}
+
+// CHECK: template <typename T = int, int C = 5> int tmain(int argc, int *argv) {
+// CHECK-NEXT: int b = argc, c, d, e, f, g;
+// CHECK-NEXT: static int a;
+// CHECK-NEXT: S<int> s;
+// CHECK-NEXT: #pragma omp parallel sections
+// CHECK-NEXT: {
+// CHECK-NEXT: a = 2;
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp parallel sections default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) num_threads(5) copyin(S<int>::TS) proc_bind(master) reduction(+: c) reduction(max: e)
+// CHECK-NEXT: {
+// CHECK-NEXT: foo();
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp parallel sections if(5) num_threads(s) proc_bind(close) reduction(^: e,f) reduction(&&: g) lastprivate(b,c)
+// CHECK-NEXT: {
+// CHECK-NEXT: foo();
+// CHECK-NEXT: #pragma omp section
+// CHECK-NEXT: foo();
+// CHECK-NEXT: }
+// CHECK: template <typename T = long, int C = 1> long tmain(long argc, long *argv) {
+// CHECK-NEXT: long b = argc, c, d, e, f, g;
+// CHECK-NEXT: static long a;
+// CHECK-NEXT: S<long> s;
+// CHECK-NEXT: #pragma omp parallel sections
+// CHECK-NEXT: {
+// CHECK-NEXT: a = 2;
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp parallel sections default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) num_threads(1) copyin(S<long>::TS) proc_bind(master) reduction(+: c) reduction(max: e)
+// CHECK-NEXT: {
+// CHECK-NEXT: foo();
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp parallel sections if(1) num_threads(s) proc_bind(close) reduction(^: e,f) reduction(&&: g) lastprivate(b,c)
+// CHECK-NEXT: {
+// CHECK-NEXT: foo();
+// CHECK-NEXT: #pragma omp section
+// CHECK-NEXT: foo();
+// CHECK-NEXT: }
+// CHECK: template <typename T, int C> T tmain(T argc, T *argv) {
+// CHECK-NEXT: T b = argc, c, d, e, f, g;
+// CHECK-NEXT: static T a;
+// CHECK-NEXT: S<T> s;
+// CHECK-NEXT: #pragma omp parallel sections
+// CHECK-NEXT: {
+// CHECK-NEXT: a = 2;
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp parallel sections default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) num_threads(C) copyin(S<T>::TS) proc_bind(master) reduction(+: c) reduction(max: e)
+// CHECK-NEXT: {
+// CHECK-NEXT: foo();
+// CHECK-NEXT: }
+// CHECK-NEXT: #pragma omp parallel sections if(C) num_threads(s) proc_bind(close) reduction(^: e,f) reduction(&&: g) lastprivate(b,c)
+// CHECK-NEXT: {
+// CHECK-NEXT: foo();
+// CHECK-NEXT: #pragma omp section
+// CHECK-NEXT: foo();
+// CHECK-NEXT: }
+
+enum Enum {};
+
+int main(int argc, char **argv) {
+  long x;
+  int b = argc, c, d, e, f, g;
+  static int a;
+#pragma omp threadprivate(a)
+  Enum ee;
+// CHECK: Enum ee;
+#pragma omp parallel sections
+  // CHECK-NEXT: #pragma omp parallel sections
+  {
+    a = 2;
+  }
+// CHECK-NEXT: {
+// CHECK-NEXT: a = 2;
+// CHECK-NEXT: }
+#pragma omp parallel sections default(none), private(argc, b) firstprivate(argv) if (argc > 0) num_threads(ee) copyin(a) proc_bind(spread) reduction(| : c, d) reduction(* : e) lastprivate(argv)
+  // CHECK-NEXT: #pragma omp parallel sections default(none) private(argc,b) firstprivate(argv) if(argc > 0) num_threads(ee) copyin(a) proc_bind(spread) reduction(|: c,d) reduction(*: e) lastprivate(argv)
+  {
+    foo();
+#pragma omp section
+    foo();
+#pragma omp section
+    foo();
+  }
+  // CHECK-NEXT: {
+  // CHECK-NEXT: foo();
+  // CHECK-NEXT: #pragma omp section
+  // CHECK-NEXT: foo();
+  // CHECK-NEXT: #pragma omp section
+  // CHECK-NEXT: foo();
+  // CHECK-NEXT: }
+  return tmain<int, 5>(b, &b) + tmain<long, 1>(x, &x);
+}
+
+#endif
diff --git a/test/OpenMP/parallel_sections_copyin_messages.cpp b/test/OpenMP/parallel_sections_copyin_messages.cpp
new file mode 100644
index 0000000..500417e
--- /dev/null
+++ b/test/OpenMP/parallel_sections_copyin_messages.cpp
@@ -0,0 +1,105 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+  S2 &operator=(S2 &s2) { return *this; }
+};
+class S3 {
+  int a;
+
+public:
+  S3() : a(0) {}
+  S3 &operator=(S3 &s3) { return *this; }
+};
+class S4 { // expected-note {{'S4' declared here}}
+  int a;
+  S4();
+  S4 &operator=(const S4 &s4);
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note {{'S5' declared here}}
+  int a;
+  S5() : a(0) {}
+  S5 &operator=(const S5 &s5) { return *this; }
+
+public:
+  S5(int v) : a(v) {}
+};
+template <class T>
+class ST {
+public:
+  static T s;
+};
+
+S2 k;
+S3 h;
+S4 l(3); // expected-note {{'l' defined here}}
+S5 m(4); // expected-note {{'m' defined here}}
+#pragma omp threadprivate(h, k, l, m)
+
+int main(int argc, char **argv) {
+  int i;
+#pragma omp parallel sections copyin // expected-error {{expected '(' after 'copyin'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections copyin( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections copyin() // expected-error {{expected expression}}
+  {
+    foo();
+  }
+#pragma omp parallel sections copyin(k // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections copyin(h, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections copyin(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections copyin(l) // expected-error {{copyin variable must have an accessible, unambiguous copy assignment operator}}
+  {
+    foo();
+  }
+#pragma omp parallel sections copyin(S1) // expected-error {{'S1' does not refer to a value}}
+  {
+    foo();
+  }
+#pragma omp parallel sections copyin(argv[1]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections copyin(i) // expected-error {{copyin variable must be threadprivate}}
+  {
+    foo();
+  }
+#pragma omp parallel sections copyin(m) // expected-error {{copyin variable must have an accessible, unambiguous copy assignment operator}}
+  {
+    foo();
+  }
+#pragma omp parallel sections copyin(ST < int > ::s) // expected-error {{copyin variable must be threadprivate}}
+  {
+    foo();
+  }
+
+  return 0;
+}
diff --git a/test/OpenMP/parallel_sections_default_messages.cpp b/test/OpenMP/parallel_sections_default_messages.cpp
new file mode 100644
index 0000000..55d5d4f
--- /dev/null
+++ b/test/OpenMP/parallel_sections_default_messages.cpp
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -o - %s
+
+void foo();
+
+int main(int argc, char **argv) {
+#pragma omp parallel sections default // expected-error {{expected '(' after 'default'}}
+  {
+#pragma omp parallel sections default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+    {
+#pragma omp parallel sections default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
+      {
+#pragma omp parallel sections default(none // expected-error {{expected ')'}} expected-note {{to match this '('}}
+        {
+#pragma omp parallel sections default(shared), default(shared) // expected-error {{directive '#pragma omp parallel sections' cannot contain more than one 'default' clause}}
+          {
+#pragma omp parallel sections default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
+            {
+              foo();
+            }
+          }
+        }
+      }
+    }
+  }
+
+#pragma omp parallel sections default(none)
+  {
+    ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
+  }
+
+#pragma omp parallel sections default(none)
+  {
+#pragma omp parallel sections default(shared)
+    {
+      ++argc;
+    }
+  }
+  return 0;
+}
diff --git a/test/OpenMP/parallel_sections_firstprivate_messages.cpp b/test/OpenMP/parallel_sections_firstprivate_messages.cpp
new file mode 100644
index 0000000..ffd2b0c
--- /dev/null
+++ b/test/OpenMP/parallel_sections_firstprivate_messages.cpp
@@ -0,0 +1,295 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+  S2(S2 &s2) : a(s2.a) {}
+  static float S2s;
+  static const float S2sc;
+};
+const float S2::S2sc = 0;
+const S2 b;
+const S2 ba[5];
+class S3 {
+  int a;
+  S3 &operator=(const S3 &s3);
+
+public:
+  S3() : a(0) {}
+  S3(S3 &s3) : a(s3.a) {}
+};
+const S3 c;
+const S3 ca[5];
+extern const int f;
+class S4 { // expected-note 2 {{'S4' declared here}}
+  int a;
+  S4();
+  S4(const S4 &s4);
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note 4 {{'S5' declared here}}
+  int a;
+  S5(const S5 &s5) : a(s5.a) {}
+
+public:
+  S5() : a(0) {}
+  S5(int v) : a(v) {}
+};
+class S6 {
+  int a;
+  S6() : a(0) {}
+
+public:
+  S6(const S6 &s6) : a(s6.a) {}
+  S6(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(int argc, char **argv) {
+  I e(4); // expected-note {{'e' defined here}}
+  C g(5); // expected-note 2 {{'g' defined here}}
+  int i;
+  int &j = i;                              // expected-note {{'j' defined here}}
+#pragma omp parallel sections firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate() // expected-error {{expected expression}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(argc)
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(a, b) // expected-error {{firstprivate variable with incomplete type 'S1'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(argv[1]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
+  {
+    foo();
+  }
+#pragma omp parallel sections linear(i) // expected-error {{unexpected OpenMP clause 'linear' in directive '#pragma omp parallel sections'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;
+#pragma omp parallel sections firstprivate(i)
+    {
+      foo();
+    }
+    v += i;
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp parallel sections firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(i)
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(g) firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  {
+    foo();
+  }
+#pragma omp parallel private(i)
+#pragma omp parallel sections firstprivate(i)
+  {
+    foo();
+  }
+#pragma omp parallel reduction(+ : i)
+#pragma omp parallel sections firstprivate(i)
+  {
+    foo();
+  }
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;
+  const int da[5] = {0};
+  S4 e(4); // expected-note {{'e' defined here}}
+  S5 g(5); // expected-note 2 {{'g' defined here}}
+  S3 m;
+  S6 n(2);
+  int i;
+  int &j = i;                              // expected-note {{'j' defined here}}
+#pragma omp parallel sections firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate() // expected-error {{expected expression}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(argc)
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(argv[1]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(2 * 2) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(ba) // OK
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(ca) // OK
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(da) // OK
+  {
+    foo();
+  }
+  int xa;
+#pragma omp parallel sections firstprivate(xa) // OK
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(S2::S2s) // OK
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(S2::S2sc) // OK
+  {
+    foo();
+  }
+#pragma omp parallel sections safelen(5) // expected-error {{unexpected OpenMP clause 'safelen' in directive '#pragma omp parallel sections'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(m) // OK
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(xa), firstprivate(xa) // expected-error {{private variable cannot be firstprivate}} expected-note {{defined as private}}
+  {
+    foo();
+  }
+#pragma omp parallel shared(xa)
+#pragma omp parallel sections firstprivate(xa) // OK: may be firstprivate
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(g) firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(n) firstprivate(n) // OK
+  {
+    foo();
+  }
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;
+#pragma omp parallel sections firstprivate(i)
+    {
+      foo();
+    }
+    v += i;
+  }
+#pragma omp parallel private(i)
+#pragma omp parallel sections firstprivate(i)
+  {
+    foo();
+  }
+#pragma omp parallel reduction(+ : i)
+#pragma omp parallel sections firstprivate(i)
+  {
+    foo();
+  }
+
+  return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}}
+}
diff --git a/test/OpenMP/parallel_sections_if_messages.cpp b/test/OpenMP/parallel_sections_if_messages.cpp
new file mode 100644
index 0000000..4af0d85
--- /dev/null
+++ b/test/OpenMP/parallel_sections_if_messages.cpp
@@ -0,0 +1,113 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, class S> // expected-note {{declared here}}
+int tmain(T argc, S **argv) {
+  #pragma omp parallel sections if // expected-error {{expected '(' after 'if'}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if () // expected-error {{expected expression}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp parallel sections' are ignored}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if (argc > 0 ? argv[1] : argv[2])
+  {
+    foo();
+  }
+  #pragma omp parallel sections if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp parallel sections' cannot contain more than one 'if' clause}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if (S) // expected-error {{'S' does not refer to a value}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if(argc)
+  {
+    foo();
+  }
+
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  #pragma omp parallel sections if // expected-error {{expected '(' after 'if'}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if () // expected-error {{expected expression}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp parallel sections' are ignored}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if (argc > 0 ? argv[1] : argv[2])
+  {
+    foo();
+  }
+  #pragma omp parallel sections if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp parallel sections' cannot contain more than one 'if' clause}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if (S1) // expected-error {{'S1' does not refer to a value}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+  #pragma omp parallel sections if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+
+  return tmain(argc, argv);
+}
diff --git a/test/OpenMP/parallel_sections_lastprivate_messages.cpp b/test/OpenMP/parallel_sections_lastprivate_messages.cpp
new file mode 100644
index 0000000..c71c115
--- /dev/null
+++ b/test/OpenMP/parallel_sections_lastprivate_messages.cpp
@@ -0,0 +1,269 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+  S2(S2 &s2) : a(s2.a) {}
+  static float S2s; // expected-note {{static data member is predetermined as shared}}
+  static const float S2sc;
+};
+const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const S2 b;
+const S2 ba[5];
+class S3 { // expected-note 2 {{'S3' declared here}}
+  int a;
+  S3 &operator=(const S3 &s3);
+
+public:
+  S3() : a(0) {}
+  S3(S3 &s3) : a(s3.a) {}
+};
+const S3 c;         // expected-note {{global variable is predetermined as shared}}
+const S3 ca[5];     // expected-note {{global variable is predetermined as shared}}
+extern const int f; // expected-note {{global variable is predetermined as shared}}
+class S4 {          // expected-note 3 {{'S4' declared here}}
+  int a;
+  S4();
+  S4(const S4 &s4);
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note {{'S5' declared here}}
+  int a;
+  S5() : a(0) {}
+
+public:
+  S5(const S5 &s5) : a(s5.a) {}
+  S5(int v) : a(v) {}
+};
+class S6 {
+  int a;
+  S6() : a(0) {}
+
+public:
+  S6(const S6 &s6) : a(s6.a) {}
+  S6(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(int argc, char **argv) {
+  I e(4); // expected-note {{'e' defined here}}
+  I g(5); // expected-note {{'g' defined here}}
+  int i;
+  int &j = i;                             // expected-note {{'j' defined here}}
+#pragma omp parallel sections lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate() // expected-error {{expected expression}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(argc)
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(a, b) // expected-error {{lastprivate variable with incomplete type 'S1'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(argv[1]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(e, g) // expected-error 2 {{lastprivate variable must have an accessible, unambiguous default constructor}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+  {
+    foo();
+  }
+#pragma omp parallel sections linear(i) // expected-error {{unexpected OpenMP clause 'linear' in directive '#pragma omp parallel sections'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;
+#pragma omp parallel sections lastprivate(i)
+    {
+      foo();
+    }
+    v += i;
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp parallel sections lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(i)
+  {
+    foo();
+  }
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;       // expected-note {{constant variable is predetermined as shared}}
+  const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+  S4 e(4);               // expected-note {{'e' defined here}}
+  S5 g(5);               // expected-note {{'g' defined here}}
+  S3 m;                  // expected-note 2 {{'m' defined here}}
+  S6 n(2);
+  int i;
+  int &j = i;                             // expected-note {{'j' defined here}}
+#pragma omp parallel sections lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate() // expected-error {{expected expression}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(argc)
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(argv[1]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(2 * 2) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(ba)
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+  {
+    foo();
+  }
+  int xa;
+#pragma omp parallel sections lastprivate(xa) // OK
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+  {
+    foo();
+  }
+#pragma omp parallel sections safelen(5) // expected-error {{unexpected OpenMP clause 'safelen' in directive '#pragma omp parallel sections'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(e, g) // expected-error 2 {{lastprivate variable must have an accessible, unambiguous default constructor}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(m) // expected-error {{lastprivate variable must have an accessible, unambiguous copy assignment operator}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(xa), lastprivate(xa) // expected-error {{private variable cannot be lastprivate}} expected-note {{defined as private}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(i)
+  {
+    foo();
+  }
+#pragma omp parallel private(xa)
+#pragma omp parallel sections lastprivate(xa)
+  {
+    foo();
+  }
+#pragma omp parallel reduction(+ : xa)
+#pragma omp parallel sections lastprivate(xa)
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}}
+  {
+    foo();
+  }
+#pragma omp parallel sections firstprivate(m) lastprivate(m) // expected-error {{lastprivate variable must have an accessible, unambiguous copy assignment operator}}
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(n) firstprivate(n) // OK
+  {
+    foo();
+  }
+  return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}}
+}
diff --git a/test/OpenMP/parallel_sections_messages.cpp b/test/OpenMP/parallel_sections_messages.cpp
new file mode 100644
index 0000000..f587509
--- /dev/null
+++ b/test/OpenMP/parallel_sections_messages.cpp
@@ -0,0 +1,85 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -std=c++11 -o - %s
+
+void foo() {
+}
+
+#pragma omp parallel sections // expected-error {{unexpected OpenMP directive '#pragma omp parallel sections'}}
+
+int main(int argc, char **argv) {
+#pragma omp parallel sections {// expected-warning {{extra tokens at the end of '#pragma omp parallel sections' are ignored}}
+  {
+    foo();
+  }
+#pragma omp parallel sections( // expected-warning {{extra tokens at the end of '#pragma omp parallel sections' are ignored}}
+  {
+    foo();
+  }
+#pragma omp parallel sections[ // expected-warning {{extra tokens at the end of '#pragma omp parallel sections' are ignored}}
+  {
+    foo();
+  }
+#pragma omp parallel sections] // expected-warning {{extra tokens at the end of '#pragma omp parallel sections' are ignored}}
+  {
+    foo();
+  }
+#pragma omp parallel sections) // expected-warning {{extra tokens at the end of '#pragma omp parallel sections' are ignored}}
+  {
+    foo();
+  }
+#pragma omp parallel sections } // expected-warning {{extra tokens at the end of '#pragma omp parallel sections' are ignored}}
+  {
+    foo();
+  }
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp parallel sections' are ignored}}
+#pragma omp parallel sections unknown()
+  {
+    foo();
+#pragma omp section
+  L1:
+    foo();
+  }
+#pragma omp parallel sections
+  {
+    ;
+  }
+#pragma omp parallel sections
+  {
+    goto L1; // expected-error {{use of undeclared label 'L1'}}
+  }
+
+  for (int i = 0; i < 10; ++i) {
+    switch (argc) {
+    case (0):
+#pragma omp parallel sections
+    {
+      foo();
+      break;    // expected-error {{'break' statement not in loop or switch statement}}
+      continue; // expected-error {{'continue' statement not in loop statement}}
+    }
+    default:
+      break;
+    }
+  }
+#pragma omp parallel sections default(none)
+  {
+    ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
+  }
+
+  goto L2; // expected-error {{use of undeclared label 'L2'}}
+#pragma omp parallel sections
+  {
+  L2:
+    foo();
+  }
+#pragma omp parallel sections
+  {
+    return 1; // expected-error {{cannot return from OpenMP region}}
+  }
+
+  [[]] // expected-error {{an attribute list cannot appear here}}
+#pragma omp parallel sections
+  {
+  }
+
+  return 0;
+}
diff --git a/test/OpenMP/parallel_sections_misc_messages.c b/test/OpenMP/parallel_sections_misc_messages.c
new file mode 100644
index 0000000..94f1241
--- /dev/null
+++ b/test/OpenMP/parallel_sections_misc_messages.c
@@ -0,0 +1,260 @@
+// RUN: %clang_cc1 -fsyntax-only -fopenmp=libiomp5 -verify %s
+
+void foo();
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp parallel sections'}}
+#pragma omp parallel sections
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp parallel sections'}}
+#pragma omp parallel sections foo
+
+void test_no_clause() {
+  int i;
+#pragma omp parallel sections
+  {
+    foo();
+  }
+
+// expected-error@+2 {{the statement for '#pragma omp parallel sections' must be a compound statement}}
+#pragma omp parallel sections
+  ++i;
+
+#pragma omp parallel sections
+  {
+    foo();
+    foo(); // expected-error {{statement in 'omp parallel sections' directive must be enclosed into a section region}}
+  }
+
+}
+
+void test_branch_protected_scope() {
+  int i = 0;
+L1:
+  ++i;
+
+  int x[24];
+
+#pragma omp parallel sections
+  {
+    if (i == 5)
+      goto L1; // expected-error {{use of undeclared label 'L1'}}
+    else if (i == 6)
+      return; // expected-error {{cannot return from OpenMP region}}
+    else if (i == 7)
+      goto L2;
+    else if (i == 8) {
+    L2:
+      x[i]++;
+    }
+#pragma omp section
+    if (i == 5)
+      goto L1; // expected-error {{use of undeclared label 'L1'}}
+    else if (i == 6)
+      return; // expected-error {{cannot return from OpenMP region}}
+    else if (i == 7)
+      goto L3;
+    else if (i == 8) {
+    L3:
+      x[i]++;
+    }
+  }
+
+  if (x[0] == 0)
+    goto L2; // expected-error {{use of undeclared label 'L2'}}
+  else if (x[1] == 1)
+    goto L1;
+  goto L3; // expected-error {{use of undeclared label 'L3'}}
+}
+
+void test_invalid_clause() {
+  int i;
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp parallel sections' are ignored}}
+#pragma omp parallel sections foo bar
+  {
+    foo();
+// expected-error@+1 {{unexpected OpenMP clause 'nowait' in directive '#pragma omp section'}}
+#pragma omp section nowait
+    ;
+  }
+}
+
+void test_non_identifiers() {
+  int i, x;
+
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp parallel sections' are ignored}}
+#pragma omp parallel sections;
+  {
+    foo();
+  }
+// expected-error@+2 {{unexpected OpenMP clause 'linear' in directive '#pragma omp parallel sections'}}
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp parallel sections' are ignored}}
+#pragma omp parallel sections linear(x);
+  {
+    foo();
+  }
+
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp parallel sections' are ignored}}
+#pragma omp parallel sections private(x);
+  {
+    foo();
+  }
+
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp parallel sections' are ignored}}
+#pragma omp parallel sections, private(x);
+  {
+    foo();
+  }
+}
+
+void test_private() {
+  int i;
+// expected-error@+2 {{expected expression}}
+// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp parallel sections private(
+  {
+    foo();
+  }
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp parallel sections private(,
+  {
+    foo();
+  }
+// expected-error@+1 2 {{expected expression}}
+#pragma omp parallel sections private(, )
+  {
+    foo();
+  }
+// expected-error@+1 {{expected expression}}
+#pragma omp parallel sections private()
+  {
+    foo();
+  }
+// expected-error@+1 {{expected expression}}
+#pragma omp parallel sections private(int)
+  {
+    foo();
+  }
+// expected-error@+1 {{expected variable name}}
+#pragma omp parallel sections private(0)
+  {
+    foo();
+  }
+
+  int x, y, z;
+#pragma omp parallel sections private(x)
+  {
+    foo();
+  }
+#pragma omp parallel sections private(x, y)
+  {
+    foo();
+  }
+#pragma omp parallel sections private(x, y, z)
+  {
+    foo();
+  }
+}
+
+void test_lastprivate() {
+  int i;
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 {{expected expression}}
+#pragma omp parallel sections lastprivate(
+  {
+    foo();
+  }
+
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp parallel sections lastprivate(,
+  {
+    foo();
+  }
+// expected-error@+1 2 {{expected expression}}
+#pragma omp parallel sections lastprivate(, )
+  {
+    foo();
+  }
+// expected-error@+1 {{expected expression}}
+#pragma omp parallel sections lastprivate()
+  {
+    foo();
+  }
+// expected-error@+1 {{expected expression}}
+#pragma omp parallel sections lastprivate(int)
+  {
+    foo();
+  }
+// expected-error@+1 {{expected variable name}}
+#pragma omp parallel sections lastprivate(0)
+  {
+    foo();
+  }
+
+  int x, y, z;
+#pragma omp parallel sections lastprivate(x)
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(x, y)
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(x, y, z)
+  {
+    foo();
+  }
+}
+
+void test_firstprivate() {
+  int i;
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 {{expected expression}}
+#pragma omp parallel sections firstprivate(
+  {
+    foo();
+  }
+
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp parallel sections firstprivate(,
+  {
+    foo();
+  }
+// expected-error@+1 2 {{expected expression}}
+#pragma omp parallel sections firstprivate(, )
+  {
+    foo();
+  }
+// expected-error@+1 {{expected expression}}
+#pragma omp parallel sections firstprivate()
+  {
+    foo();
+  }
+// expected-error@+1 {{expected expression}}
+#pragma omp parallel sections firstprivate(int)
+  {
+    foo();
+  }
+// expected-error@+1 {{expected variable name}}
+#pragma omp parallel sections firstprivate(0)
+  {
+    foo();
+  }
+
+  int x, y, z;
+#pragma omp parallel sections lastprivate(x) firstprivate(x)
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(x, y) firstprivate(x, y)
+  {
+    foo();
+  }
+#pragma omp parallel sections lastprivate(x, y, z) firstprivate(x, y, z)
+  {
+    foo();
+  }
+}
+
diff --git a/test/OpenMP/parallel_sections_num_threads_messages.cpp b/test/OpenMP/parallel_sections_num_threads_messages.cpp
new file mode 100644
index 0000000..927e8d7
--- /dev/null
+++ b/test/OpenMP/parallel_sections_num_threads_messages.cpp
@@ -0,0 +1,63 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, typename S, int N> // expected-note {{declared here}}
+T tmain(T argc, S **argv) {
+  #pragma omp parallel sections num_threads // expected-error {{expected '(' after 'num_threads'}}
+  {foo();}
+  #pragma omp parallel sections num_threads ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {foo();}
+  #pragma omp parallel sections num_threads () // expected-error {{expected expression}}
+  {foo();}
+  #pragma omp parallel sections num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {foo();}
+  #pragma omp parallel sections num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp parallel sections' are ignored}}
+  {foo();}
+  #pragma omp parallel sections num_threads ((argc > 0) ? argv[1] : argv[2]) // expected-error 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  {foo();}
+  #pragma omp parallel sections num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp parallel sections' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a positive integer value}}
+  {foo();}
+  #pragma omp parallel sections num_threads (S) // expected-error {{'S' does not refer to a value}}
+  {foo();}
+  #pragma omp parallel sections num_threads (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error 2 {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  {foo();}
+  #pragma omp parallel sections num_threads (argc)
+  {foo();}
+  #pragma omp parallel sections num_threads (N) // expected-error {{argument to 'num_threads' clause must be a positive integer value}}
+  {foo();}
+
+  return argc;
+}
+
+int main(int argc, char **argv) {
+  #pragma omp parallel sections num_threads // expected-error {{expected '(' after 'num_threads'}}
+  {foo();}
+  #pragma omp parallel sections num_threads ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {foo();}
+  #pragma omp parallel sections num_threads () // expected-error {{expected expression}}
+  {foo();}
+  #pragma omp parallel sections num_threads (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {foo();}
+  #pragma omp parallel sections num_threads (argc)) // expected-warning {{extra tokens at the end of '#pragma omp parallel sections' are ignored}}
+  {foo();}
+  #pragma omp parallel sections num_threads (argc > 0 ? argv[1] : argv[2]) // expected-error {{integral }}
+  {foo();}
+  #pragma omp parallel sections num_threads (foobool(argc)), num_threads (true), num_threads (-5) // expected-error 2 {{directive '#pragma omp parallel sections' cannot contain more than one 'num_threads' clause}} expected-error {{argument to 'num_threads' clause must be a positive integer value}}
+  {foo();}
+  #pragma omp parallel sections num_threads (S1) // expected-error {{'S1' does not refer to a value}}
+  {foo();}
+  #pragma omp parallel sections num_threads (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expression must have integral or unscoped enumeration type, not 'char *'}}
+  {foo();}
+  #pragma omp parallel sections num_threads (num_threads(tmain<int, char, -1>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} expected-note {{in instantiation of function template specialization 'tmain<int, char, -1>' requested here}}
+  {foo();}
+
+  return tmain<int, char, 3>(argc, argv); // expected-note {{in instantiation of function template specialization 'tmain<int, char, 3>' requested here}}
+}
diff --git a/test/OpenMP/parallel_sections_private_messages.cpp b/test/OpenMP/parallel_sections_private_messages.cpp
new file mode 100644
index 0000000..7d39c7e
--- /dev/null
+++ b/test/OpenMP/parallel_sections_private_messages.cpp
@@ -0,0 +1,204 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+};
+const S2 b;
+const S2 ba[5];
+class S3 {
+  int a;
+
+public:
+  S3() : a(0) {}
+};
+const S3 ca[5];
+class S4 { // expected-note {{'S4' declared here}}
+  int a;
+  S4();
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note {{'S5' declared here}}
+  int a;
+  S5() : a(0) {}
+
+public:
+  S5(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(I argc, C **argv) {
+  I e(4);
+  I g(5);
+  int i;
+  int &j = i;                         // expected-note {{'j' defined here}}
+#pragma omp parallel sections private // expected-error {{expected '(' after 'private'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private() // expected-error {{expected expression}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(argc)
+  {
+    foo();
+  }
+#pragma omp parallel sections private(S1) // expected-error {{'S1' does not refer to a value}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(argv[1]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(e, g)
+  {
+    foo();
+  }
+#pragma omp parallel sections private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
+  {
+    foo();
+  }
+#pragma omp parallel sections copyprivate(h) // expected-error {{unexpected OpenMP clause 'copyprivate' in directive '#pragma omp parallel sections'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;
+#pragma omp parallel sections private(i)
+    {
+      foo();
+    }
+    v += i;
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp parallel sections private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(i)
+  {
+    foo();
+  }
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  S4 e(4); // expected-note {{'e' defined here}}
+  S5 g(5); // expected-note {{'g' defined here}}
+  int i;
+  int &j = i;                         // expected-note {{'j' defined here}}
+#pragma omp parallel sections private // expected-error {{expected '(' after 'private'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private() // expected-error {{expected expression}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(argc)
+  {
+    foo();
+  }
+#pragma omp parallel sections private(S1) // expected-error {{'S1' does not refer to a value}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(argv[1]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(e, g) // expected-error 2 {{private variable must have an accessible, unambiguous default constructor}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
+  {
+    foo();
+  }
+#pragma omp parallel sections copyprivate(h) // expected-error {{unexpected OpenMP clause 'copyprivate' in directive '#pragma omp parallel sections'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+  {
+    int i;
+#pragma omp parallel sections private(i)
+    {
+      foo();
+    }
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp parallel sections private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(i)
+  {
+    foo();
+  }
+
+  return 0;
+}
+
diff --git a/test/OpenMP/parallel_sections_proc_bind_messages.cpp b/test/OpenMP/parallel_sections_proc_bind_messages.cpp
new file mode 100644
index 0000000..9e58a73
--- /dev/null
+++ b/test/OpenMP/parallel_sections_proc_bind_messages.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -o - %s
+
+void foo();
+
+int main(int argc, char **argv) {
+#pragma omp parallel sections proc_bind // expected-error {{expected '(' after 'proc_bind'}}
+  { foo(); }
+#pragma omp parallel sections proc_bind( // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  { foo(); }
+#pragma omp parallel sections proc_bind() // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}}
+  { foo(); }
+#pragma omp parallel sections proc_bind(master // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  { foo(); }
+#pragma omp parallel sections proc_bind(close), proc_bind(spread) // expected-error {{directive '#pragma omp parallel sections' cannot contain more than one 'proc_bind' clause}}
+  { foo(); }
+#pragma omp parallel sections proc_bind(x) // expected-error {{expected 'master', 'close' or 'spread' in OpenMP clause 'proc_bind'}}
+  { foo(); }
+
+#pragma omp parallel sections proc_bind(master)
+  { ++argc; }
+
+#pragma omp parallel sections proc_bind(close)
+  {
+#pragma omp parallel sections proc_bind(spread)
+    { ++argc; }
+  }
+  return 0;
+}
diff --git a/test/OpenMP/parallel_sections_reduction_messages.cpp b/test/OpenMP/parallel_sections_reduction_messages.cpp
new file mode 100644
index 0000000..8b02f23
--- /dev/null
+++ b/test/OpenMP/parallel_sections_reduction_messages.cpp
@@ -0,0 +1,358 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+  S2 &operator+=(const S2 &arg) { return (*this); }
+
+public:
+  S2() : a(0) {}
+  S2(S2 &s2) : a(s2.a) {}
+  static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
+  static const float S2sc;
+};
+const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+S2 b;                     // expected-note 2 {{'b' defined here}}
+const S2 ba[5];           // expected-note 2 {{'ba' defined here}}
+class S3 {
+  int a;
+
+public:
+  S3() : a(0) {}
+  S3(const S3 &s3) : a(s3.a) {}
+  S3 operator+=(const S3 &arg1) { return arg1; }
+};
+int operator+=(const S3 &arg1, const S3 &arg2) { return 5; }
+S3 c;               // expected-note 2 {{'c' defined here}}
+const S3 ca[5];     // expected-note 2 {{'ca' defined here}}
+extern const int f; // expected-note 4 {{'f' declared here}}
+class S4 {          // expected-note {{'S4' declared here}}
+  int a;
+  S4();
+  S4(const S4 &s4);
+  S4 &operator+=(const S4 &arg) { return (*this); }
+
+public:
+  S4(int v) : a(v) {}
+};
+S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; }
+class S5 {
+  int a;
+  S5() : a(0) {}
+  S5(const S5 &s5) : a(s5.a) {}
+  S5 &operator+=(const S5 &arg);
+
+public:
+  S5(int v) : a(v) {}
+};
+class S6 {
+  int a;
+
+public:
+  S6() : a(6) {}
+  operator int() { return 6; }
+} o; // expected-note 2 {{'o' defined here}}
+
+S3 h, k;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class T>       // expected-note {{declared here}}
+T tmain(T argc) {        // expected-note 2 {{'argc' defined here}}
+  const T d = T();       // expected-note 4 {{'d' defined here}}
+  const T da[5] = {T()}; // expected-note 2 {{'da' defined here}}
+  T qa[5] = {T()};
+  T i;
+  T &j = i;                             // expected-note 4 {{'j' defined here}}
+  S3 &p = k;                            // expected-note 2 {{'p' defined here}}
+  const T &r = da[(int)i];              // expected-note 2 {{'r' defined here}}
+  T &q = qa[(int)i];                    // expected-note 2 {{'q' defined here}}
+  T fl;                                 // expected-note {{'fl' defined here}}
+#pragma omp parallel sections reduction // expected-error {{expected '(' after 'reduction'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp parallel sections' are ignored}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(&& : argc)
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(^ : T) // expected-error {{'T' does not refer to a value}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(max : qa[1]) // expected-error 2 {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  {
+    foo();
+  }
+#pragma omp parallel private(k)
+#pragma omp parallel sections reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp parallel sections reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  {
+    foo();
+  }
+#pragma omp parallel private(fl)
+#pragma omp parallel sections reduction(+ : fl)
+  {
+    foo();
+  }
+#pragma omp parallel reduction(* : fl)
+#pragma omp parallel sections reduction(+ : fl)
+  {
+    foo();
+  }
+
+  return T();
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;       // expected-note 2 {{'d' defined here}}
+  const int da[5] = {0}; // expected-note {{'da' defined here}}
+  int qa[5] = {0};
+  S4 e(4); // expected-note {{'e' defined here}}
+  S5 g(5); // expected-note {{'g' defined here}}
+  int i;
+  int &j = i;                           // expected-note 2 {{'j' defined here}}
+  S3 &p = k;                            // expected-note 2 {{'p' defined here}}
+  const int &r = da[i];                 // expected-note {{'r' defined here}}
+  int &q = qa[i];                       // expected-note {{'q' defined here}}
+  float fl;                             // expected-note {{'fl' defined here}}
+#pragma omp parallel sections reduction // expected-error {{expected '(' after 'reduction'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp parallel sections' are ignored}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(foo : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(~ : argc) // expected-error {{expected unqualified-id}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(&& : argc)
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(max : argv[1]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(& : e, g) // expected-error {{reduction variable must have an accessible, unambiguous default constructor}} expected-error {{variable of type 'S5' is not valid for specified reduction operation}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}}
+  {
+    foo();
+  }
+#pragma omp parallel sections private(i), reduction(+ : j), reduction(+ : q) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  {
+    foo();
+  }
+#pragma omp parallel private(k)
+#pragma omp parallel sections reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
+  {
+    foo();
+  }
+#pragma omp parallel sections reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp parallel sections reduction(max : j) // expected-error {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  {
+    foo();
+  }
+#pragma omp parallel private(fl)
+#pragma omp parallel sections reduction(+ : fl)
+  {
+    foo();
+  }
+#pragma omp parallel reduction(* : fl)
+#pragma omp parallel sections reduction(+ : fl)
+  {
+    foo();
+  }
+
+  return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain<int>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<float>' requested here}}
+}
diff --git a/test/OpenMP/parallel_sections_shared_messages.cpp b/test/OpenMP/parallel_sections_shared_messages.cpp
new file mode 100644
index 0000000..d4915c8
--- /dev/null
+++ b/test/OpenMP/parallel_sections_shared_messages.cpp
@@ -0,0 +1,110 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+extern S1 a;
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+  S2(S2 &s2) : a(s2.a) {}
+};
+const S2 b;
+const S2 ba[5];
+class S3 {
+  int a;
+
+public:
+  S3() : a(0) {}
+  S3(S3 &s3) : a(s3.a) {}
+};
+const S3 c;
+const S3 ca[5];
+extern const int f;
+class S4 {
+  int a;
+  S4();
+  S4(const S4 &s4);
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 {
+  int a;
+  S5() : a(0) {}
+  S5(const S5 &s5) : a(s5.a) {}
+
+public:
+  S5(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note {{defined as threadprivate or thread local}}
+
+int main(int argc, char **argv) {
+  const int d = 5;
+  const int da[5] = {0};
+  S4 e(4);
+  S5 g(5);
+  int i;
+  int &j = i;
+#pragma omp parallel sections shared // expected-error {{expected '(' after 'shared'}}
+  { foo(); }
+#pragma omp parallel sections shared( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  { foo(); }
+#pragma omp parallel sections shared() // expected-error {{expected expression}}
+  { foo(); }
+#pragma omp parallel sections shared(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  { foo(); }
+#pragma omp parallel sections shared(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  { foo(); }
+#pragma omp parallel sections shared(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  { foo(); }
+#pragma omp parallel sections shared(argc)
+  { foo(); }
+#pragma omp parallel sections shared(S1) // expected-error {{'S1' does not refer to a value}}
+  { foo(); }
+#pragma omp parallel sections shared(a, b, c, d, f)
+  { foo(); }
+#pragma omp parallel sections shared(argv[1]) // expected-error {{expected variable name}}
+  { foo(); }
+#pragma omp parallel sections shared(ba)
+  { foo(); }
+#pragma omp parallel sections shared(ca)
+  { foo(); }
+#pragma omp parallel sections shared(da)
+  { foo(); }
+#pragma omp parallel sections shared(e, g)
+  { foo(); }
+#pragma omp parallel sections shared(h) // expected-error {{threadprivate or thread local variable cannot be shared}}
+  { foo(); }
+#pragma omp parallel sections private(i), shared(i) // expected-error {{private variable cannot be shared}} expected-note {{defined as private}}
+  { foo(); }
+#pragma omp parallel sections firstprivate(i), shared(i) // expected-error {{firstprivate variable cannot be shared}} expected-note {{defined as firstprivate}}
+  { foo(); }
+#pragma omp parallel sections private(i)
+  {
+#pragma omp parallel sections shared(i)
+    {
+#pragma omp parallel sections shared(j)
+      { foo(); }
+    }
+  }
+#pragma omp parallel sections firstprivate(i)
+  {
+#pragma omp parallel sections shared(i)
+    {
+#pragma omp parallel sections shared(j)
+      { foo(); }
+    }
+  }
+
+  return 0;
+}
diff --git a/test/OpenMP/parallel_shared_messages.cpp b/test/OpenMP/parallel_shared_messages.cpp
index 211d392..8363989 100644
--- a/test/OpenMP/parallel_shared_messages.cpp
+++ b/test/OpenMP/parallel_shared_messages.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 %s
 
 void foo() {
 }
diff --git a/test/OpenMP/predefined_macro.c b/test/OpenMP/predefined_macro.c
index 3a81186..c9829ce 100644
--- a/test/OpenMP/predefined_macro.c
+++ b/test/OpenMP/predefined_macro.c
@@ -1,32 +1,32 @@
-// RUN: %clang_cc1 -fopenmp -verify -DFOPENMP -o - %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -verify -DFOPENMP -o - %s
 // RUN: %clang_cc1 -verify -o - %s
 // expected-no-diagnostics
 #ifdef FOPENMP
-// -fopenmp option is specified
+// -fopenmp=libiomp5 option is specified
 #ifndef _OPENMP
 #error "No _OPENMP macro is defined with -fopenmp option"
-#elsif _OPENMP != 201107
+#elsif _OPENMP != 201307
 #error "_OPENMP has incorrect value"
 #endif //_OPENMP
 #else
-// No -fopenmp option is specified
+// No -fopenmp=libiomp5 option is specified
 #ifdef _OPENMP
 #error "_OPENMP macro is defined without -fopenmp option"
 #endif // _OPENMP
 #endif // FOPENMP
 
-// RUN: %clang_cc1 -fopenmp -verify -DFOPENMP -o - %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -verify -DFOPENMP -o - %s
 // RUN: %clang_cc1 -verify -o - %s
 // expected-no-diagnostics
 #ifdef FOPENMP
-// -fopenmp option is specified
+// -fopenmp=libiomp5 option is specified
 #ifndef _OPENMP
 #error "No _OPENMP macro is defined with -fopenmp option"
-#elsif _OPENMP != 201107
+#elsif _OPENMP != 201307
 #error "_OPENMP has incorrect value"
 #endif // _OPENMP
 #else
-// No -fopenmp option is specified
+// No -fopenmp=libiomp5 option is specified
 #ifdef _OPENMP
 #error "_OPENMP macro is defined without -fopenmp option"
 #endif // _OPENMP
diff --git a/test/OpenMP/sections_ast_print.cpp b/test/OpenMP/sections_ast_print.cpp
new file mode 100644
index 0000000..b1a2e03
--- /dev/null
+++ b/test/OpenMP/sections_ast_print.cpp
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+void foo() {}
+
+template <class T, int N>
+T tmain(T argc) {
+  T b = argc, c, d, e, f, g;
+  static T a;
+// CHECK: static T a;
+#pragma omp parallel
+#pragma omp sections private(argc, b), firstprivate(c, d), lastprivate(d, f) reduction(- : g) nowait
+  {
+    foo();
+  }
+  // CHECK-NEXT: #pragma omp parallel
+  // CHECK-NEXT: #pragma omp sections private(argc,b) firstprivate(c,d) lastprivate(d,f) reduction(-: g) nowait
+  // CHECK-NEXT: {
+  // CHECK-NEXT: foo();
+  // CHECK-NEXT: }
+  return T();
+}
+
+int main(int argc, char **argv) {
+  int b = argc, c, d, e, f, g;
+  static int a;
+// CHECK: static int a;
+#pragma omp parallel
+#pragma omp sections private(argc, b), firstprivate(argv, c), lastprivate(d, f) reduction(+ : g) nowait
+  {
+#pragma omp section
+    foo();
+#pragma omp section
+    foo();
+  }
+  // CHECK-NEXT: #pragma omp parallel
+  // CHECK-NEXT: #pragma omp sections private(argc,b) firstprivate(argv,c) lastprivate(d,f) reduction(+: g) nowait
+  // CHECK-NEXT: {
+  // CHECK-NEXT: #pragma omp section
+  // CHECK-NEXT: foo();
+  // CHECK-NEXT: #pragma omp section
+  // CHECK-NEXT: foo();
+  // CHECK-NEXT: }
+  return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0]));
+}
+
+#endif
diff --git a/test/OpenMP/sections_firstprivate_messages.cpp b/test/OpenMP/sections_firstprivate_messages.cpp
new file mode 100644
index 0000000..b030ce5
--- /dev/null
+++ b/test/OpenMP/sections_firstprivate_messages.cpp
@@ -0,0 +1,335 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+  S2(S2 &s2) : a(s2.a) {}
+  static float S2s;
+  static const float S2sc;
+};
+const float S2::S2sc = 0;
+const S2 b;
+const S2 ba[5];
+class S3 {
+  int a;
+  S3 &operator=(const S3 &s3);
+
+public:
+  S3() : a(0) {}
+  S3(S3 &s3) : a(s3.a) {}
+};
+const S3 c;
+const S3 ca[5];
+extern const int f;
+class S4 { // expected-note 2 {{'S4' declared here}}
+  int a;
+  S4();
+  S4(const S4 &s4);
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note 4 {{'S5' declared here}}
+  int a;
+  S5(const S5 &s5) : a(s5.a) {}
+
+public:
+  S5() : a(0) {}
+  S5(int v) : a(v) {}
+};
+class S6 {
+  int a;
+  S6() : a(0) {}
+
+public:
+  S6(const S6 &s6) : a(s6.a) {}
+  S6(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(int argc, char **argv) {
+  I e(4); // expected-note {{'e' defined here}}
+  C g(5); // expected-note 2 {{'g' defined here}}
+  int i;
+  int &j = i; // expected-note {{'j' defined here}}
+#pragma omp parallel
+#pragma omp sections firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate() // expected-error {{expected expression}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(argc)
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(a, b) // expected-error {{firstprivate variable with incomplete type 'S1'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(argv[1]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections linear(i) // expected-error {{unexpected OpenMP clause 'linear' in directive '#pragma omp sections'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;                           // expected-note {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp sections' directive into a parallel or another task region?}}
+#pragma omp sections firstprivate(i) // expected-error {{private variable cannot be firstprivate}}
+    {
+      foo();
+    }
+    v += i;
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp sections firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(i)
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(g) firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  {
+    foo();
+  }
+#pragma omp parallel private(i)      // expected-note {{defined as private}}
+#pragma omp sections firstprivate(i) // expected-error {{firstprivate variable must be shared}}
+  {
+    foo();
+  }
+#pragma omp parallel reduction(+ : i) // expected-note {{defined as reduction}}
+#pragma omp sections firstprivate(i)  // expected-error {{firstprivate variable must be shared}}
+  {
+    foo();
+  }
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;
+  const int da[5] = {0};
+  S4 e(4); // expected-note {{'e' defined here}}
+  S5 g(5); // expected-note 2 {{'g' defined here}}
+  S3 m;
+  S6 n(2);
+  int i;
+  int &j = i; // expected-note {{'j' defined here}}
+#pragma omp parallel
+#pragma omp sections firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate() // expected-error {{expected expression}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(argc)
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(argv[1]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(2 * 2) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(ba) // OK
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(ca) // OK
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(da) // OK
+  {
+    foo();
+  }
+  int xa;
+#pragma omp parallel
+#pragma omp sections firstprivate(xa) // OK
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(S2::S2s) // OK
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(S2::S2sc) // OK
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections safelen(5) // expected-error {{unexpected OpenMP clause 'safelen' in directive '#pragma omp sections'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(m) // OK
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections private(xa), firstprivate(xa) // expected-error {{private variable cannot be firstprivate}} expected-note {{defined as private}}
+  {
+    foo();
+  }
+#pragma omp parallel shared(xa)
+#pragma omp sections firstprivate(xa) // OK: may be firstprivate
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(g) firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(n) firstprivate(n) // OK
+  {
+    foo();
+  }
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;                           // expected-note {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp sections' directive into a parallel or another task region?}}
+#pragma omp sections firstprivate(i) // expected-error {{private variable cannot be firstprivate}}
+    {
+      foo();
+    }
+    v += i;
+  }
+#pragma omp parallel private(i)      // expected-note {{defined as private}}
+#pragma omp sections firstprivate(i) // expected-error {{firstprivate variable must be shared}}
+  {
+    foo();
+  }
+#pragma omp parallel reduction(+ : i) // expected-note {{defined as reduction}}
+#pragma omp sections firstprivate(i)  // expected-error {{firstprivate variable must be shared}}
+  {
+    foo();
+  }
+
+  return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}}
+}
diff --git a/test/OpenMP/sections_lastprivate_messages.cpp b/test/OpenMP/sections_lastprivate_messages.cpp
new file mode 100644
index 0000000..54c6005
--- /dev/null
+++ b/test/OpenMP/sections_lastprivate_messages.cpp
@@ -0,0 +1,309 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+  S2(S2 &s2) : a(s2.a) {}
+  static float S2s; // expected-note {{static data member is predetermined as shared}}
+  static const float S2sc;
+};
+const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const S2 b;
+const S2 ba[5];
+class S3 { // expected-note 2 {{'S3' declared here}}
+  int a;
+  S3 &operator=(const S3 &s3);
+
+public:
+  S3() : a(0) {}
+  S3(S3 &s3) : a(s3.a) {}
+};
+const S3 c;         // expected-note {{global variable is predetermined as shared}}
+const S3 ca[5];     // expected-note {{global variable is predetermined as shared}}
+extern const int f; // expected-note {{global variable is predetermined as shared}}
+class S4 {          // expected-note 3 {{'S4' declared here}}
+  int a;
+  S4();
+  S4(const S4 &s4);
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note {{'S5' declared here}}
+  int a;
+  S5() : a(0) {}
+
+public:
+  S5(const S5 &s5) : a(s5.a) {}
+  S5(int v) : a(v) {}
+};
+class S6 {
+  int a;
+  S6() : a(0) {}
+
+public:
+  S6(const S6 &s6) : a(s6.a) {}
+  S6(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(int argc, char **argv) {
+  I e(4); // expected-note {{'e' defined here}}
+  I g(5); // expected-note {{'g' defined here}}
+  int i;
+  int &j = i; // expected-note {{'j' defined here}}
+#pragma omp parallel
+#pragma omp sections lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate() // expected-error {{expected expression}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(argc)
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(a, b) // expected-error {{lastprivate variable with incomplete type 'S1'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(argv[1]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(e, g) // expected-error 2 {{lastprivate variable must have an accessible, unambiguous default constructor}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections linear(i) // expected-error {{unexpected OpenMP clause 'linear' in directive '#pragma omp sections'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;                          // expected-note {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp sections' directive into a parallel or another task region?}}
+#pragma omp sections lastprivate(i) // expected-error {{lastprivate variable must be shared}}
+    {
+      foo();
+    }
+    v += i;
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp sections lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(i)
+  {
+    foo();
+  }
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;       // expected-note {{constant variable is predetermined as shared}}
+  const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+  S4 e(4);               // expected-note {{'e' defined here}}
+  S5 g(5);               // expected-note {{'g' defined here}}
+  S3 m;                  // expected-note 2 {{'m' defined here}}
+  S6 n(2);
+  int i;
+  int &j = i; // expected-note {{'j' defined here}}
+#pragma omp parallel
+#pragma omp sections lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate() // expected-error {{expected expression}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(argc)
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(argv[1]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(2 * 2) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(ba)
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+  {
+    foo();
+  }
+  int xa;
+#pragma omp parallel
+#pragma omp sections lastprivate(xa) // OK
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections safelen(5) // expected-error {{unexpected OpenMP clause 'safelen' in directive '#pragma omp sections'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(e, g) // expected-error 2 {{lastprivate variable must have an accessible, unambiguous default constructor}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(m) // expected-error {{lastprivate variable must have an accessible, unambiguous copy assignment operator}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections private(xa), lastprivate(xa) // expected-error {{private variable cannot be lastprivate}} expected-note {{defined as private}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(i)
+  {
+    foo();
+  }
+#pragma omp parallel private(xa)     // expected-note {{defined as private}}
+#pragma omp sections lastprivate(xa) // expected-error {{lastprivate variable must be shared}}
+  {
+    foo();
+  }
+#pragma omp parallel reduction(+ : xa) // expected-note {{defined as reduction}}
+#pragma omp sections lastprivate(xa)   // expected-error {{lastprivate variable must be shared}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections firstprivate(m) lastprivate(m) // expected-error {{lastprivate variable must have an accessible, unambiguous copy assignment operator}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(n) firstprivate(n) // OK
+  {
+    foo();
+  }
+  return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}}
+}
diff --git a/test/OpenMP/sections_misc_messages.c b/test/OpenMP/sections_misc_messages.c
new file mode 100644
index 0000000..0297513
--- /dev/null
+++ b/test/OpenMP/sections_misc_messages.c
@@ -0,0 +1,299 @@
+// RUN: %clang_cc1 -fsyntax-only -fopenmp=libiomp5 -verify %s
+
+void foo();
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp sections'}}
+#pragma omp sections
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp sections'}}
+#pragma omp sections foo
+
+void test_no_clause() {
+  int i;
+#pragma omp sections
+  {
+    foo();
+  }
+
+// expected-error@+2 {{the statement for '#pragma omp sections' must be a compound statement}}
+#pragma omp sections
+  ++i;
+
+#pragma omp sections
+  {
+    foo();
+    foo(); // expected-error {{statement in 'omp sections' directive must be enclosed into a section region}}
+  }
+}
+
+void test_branch_protected_scope() {
+  int i = 0;
+L1:
+  ++i;
+
+  int x[24];
+
+#pragma omp parallel
+#pragma omp sections
+  {
+    if (i == 5)
+      goto L1; // expected-error {{use of undeclared label 'L1'}}
+    else if (i == 6)
+      return; // expected-error {{cannot return from OpenMP region}}
+    else if (i == 7)
+      goto L2;
+    else if (i == 8) {
+    L2:
+      x[i]++;
+    }
+#pragma omp section
+    if (i == 5)
+      goto L1; // expected-error {{use of undeclared label 'L1'}}
+    else if (i == 6)
+      return; // expected-error {{cannot return from OpenMP region}}
+    else if (i == 7)
+      goto L3;
+    else if (i == 8) {
+    L3:
+      x[i]++;
+    }
+  }
+
+  if (x[0] == 0)
+    goto L2; // expected-error {{use of undeclared label 'L2'}}
+  else if (x[1] == 1)
+    goto L1;
+  goto L3; // expected-error {{use of undeclared label 'L3'}}
+}
+
+void test_invalid_clause() {
+  int i;
+#pragma omp parallel
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp sections' are ignored}}
+#pragma omp sections foo bar
+  {
+    foo();
+// expected-error@+1 {{unexpected OpenMP clause 'nowait' in directive '#pragma omp section'}}
+#pragma omp section nowait
+    ;
+  }
+}
+
+void test_non_identifiers() {
+  int i, x;
+
+#pragma omp parallel
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp sections' are ignored}}
+#pragma omp sections;
+  {
+    foo();
+  }
+#pragma omp parallel
+// expected-error@+2 {{unexpected OpenMP clause 'linear' in directive '#pragma omp sections'}}
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp sections' are ignored}}
+#pragma omp sections linear(x);
+  {
+    foo();
+  }
+
+#pragma omp parallel
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp sections' are ignored}}
+#pragma omp sections private(x);
+  {
+    foo();
+  }
+
+#pragma omp parallel
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp sections' are ignored}}
+#pragma omp sections, private(x);
+  {
+    foo();
+  }
+}
+
+void test_private() {
+  int i;
+#pragma omp parallel
+// expected-error@+2 {{expected expression}}
+// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp sections private(
+  {
+    foo();
+  }
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp sections private(,
+  {
+    foo();
+  }
+#pragma omp parallel
+// expected-error@+1 2 {{expected expression}}
+#pragma omp sections private(, )
+  {
+    foo();
+  }
+#pragma omp parallel
+// expected-error@+1 {{expected expression}}
+#pragma omp sections private()
+  {
+    foo();
+  }
+#pragma omp parallel
+// expected-error@+1 {{expected expression}}
+#pragma omp sections private(int)
+  {
+    foo();
+  }
+#pragma omp parallel
+// expected-error@+1 {{expected variable name}}
+#pragma omp sections private(0)
+  {
+    foo();
+  }
+
+  int x, y, z;
+#pragma omp parallel
+#pragma omp sections private(x)
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections private(x, y)
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections private(x, y, z)
+  {
+    foo();
+  }
+}
+
+void test_lastprivate() {
+  int i;
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 {{expected expression}}
+#pragma omp sections lastprivate(
+  {
+    foo();
+  }
+
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp sections lastprivate(,
+  {
+    foo();
+  }
+#pragma omp parallel
+// expected-error@+1 2 {{expected expression}}
+#pragma omp sections lastprivate(, )
+  {
+    foo();
+  }
+#pragma omp parallel
+// expected-error@+1 {{expected expression}}
+#pragma omp sections lastprivate()
+  {
+    foo();
+  }
+#pragma omp parallel
+// expected-error@+1 {{expected expression}}
+#pragma omp sections lastprivate(int)
+  {
+    foo();
+  }
+#pragma omp parallel
+// expected-error@+1 {{expected variable name}}
+#pragma omp sections lastprivate(0)
+  {
+    foo();
+  }
+
+  int x, y, z;
+#pragma omp parallel
+#pragma omp sections lastprivate(x)
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(x, y)
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(x, y, z)
+  {
+    foo();
+  }
+}
+
+void test_firstprivate() {
+  int i;
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 {{expected expression}}
+#pragma omp sections firstprivate(
+  {
+    foo();
+  }
+
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp sections firstprivate(,
+  {
+    foo();
+  }
+#pragma omp parallel
+// expected-error@+1 2 {{expected expression}}
+#pragma omp sections firstprivate(, )
+  {
+    foo();
+  }
+#pragma omp parallel
+// expected-error@+1 {{expected expression}}
+#pragma omp sections firstprivate()
+  {
+    foo();
+  }
+#pragma omp parallel
+// expected-error@+1 {{expected expression}}
+#pragma omp sections firstprivate(int)
+  {
+    foo();
+  }
+#pragma omp parallel
+// expected-error@+1 {{expected variable name}}
+#pragma omp sections firstprivate(0)
+  {
+    foo();
+  }
+
+  int x, y, z;
+#pragma omp parallel
+#pragma omp sections lastprivate(x) firstprivate(x)
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(x, y) firstprivate(x, y)
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections lastprivate(x, y, z) firstprivate(x, y, z)
+  {
+    foo();
+  }
+}
+
+void test_nowait() {
+#pragma omp parallel
+#pragma omp sections nowait nowait // expected-error {{directive '#pragma omp sections' cannot contain more than one 'nowait' clause}}
+  {
+    ;
+  }
+}
diff --git a/test/OpenMP/sections_private_messages.cpp b/test/OpenMP/sections_private_messages.cpp
new file mode 100644
index 0000000..7f5aa84
--- /dev/null
+++ b/test/OpenMP/sections_private_messages.cpp
@@ -0,0 +1,204 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+};
+const S2 b;
+const S2 ba[5];
+class S3 {
+  int a;
+
+public:
+  S3() : a(0) {}
+};
+const S3 ca[5];
+class S4 { // expected-note {{'S4' declared here}}
+  int a;
+  S4();
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note {{'S5' declared here}}
+  int a;
+  S5() : a(0) {}
+
+public:
+  S5(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(I argc, C **argv) {
+  I e(4);
+  I g(5);
+  int i;
+  int &j = i;                // expected-note {{'j' defined here}}
+#pragma omp sections private // expected-error {{expected '(' after 'private'}}
+  {
+    foo();
+  }
+#pragma omp sections private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp sections private() // expected-error {{expected expression}}
+  {
+    foo();
+  }
+#pragma omp sections private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp sections private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp sections private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp sections private(argc)
+  {
+    foo();
+  }
+#pragma omp sections private(S1) // expected-error {{'S1' does not refer to a value}}
+  {
+    foo();
+  }
+#pragma omp sections private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
+  {
+    foo();
+  }
+#pragma omp sections private(argv[1]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp sections private(e, g)
+  {
+    foo();
+  }
+#pragma omp sections private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
+  {
+    foo();
+  }
+#pragma omp sections shared(i) // expected-error {{unexpected OpenMP clause 'shared' in directive '#pragma omp sections'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;
+#pragma omp sections private(i)
+    {
+      foo();
+    }
+    v += i;
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp sections private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}}
+  {
+    foo();
+  }
+#pragma omp sections private(i)
+  {
+    foo();
+  }
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  S4 e(4); // expected-note {{'e' defined here}}
+  S5 g(5); // expected-note {{'g' defined here}}
+  int i;
+  int &j = i;                // expected-note {{'j' defined here}}
+#pragma omp sections private // expected-error {{expected '(' after 'private'}}
+  {
+    foo();
+  }
+#pragma omp sections private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp sections private() // expected-error {{expected expression}}
+  {
+    foo();
+  }
+#pragma omp sections private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp sections private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp sections private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp sections private(argc)
+  {
+    foo();
+  }
+#pragma omp sections private(S1) // expected-error {{'S1' does not refer to a value}}
+  {
+    foo();
+  }
+#pragma omp sections private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
+  {
+    foo();
+  }
+#pragma omp sections private(argv[1]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp sections private(e, g) // expected-error 2 {{private variable must have an accessible, unambiguous default constructor}}
+  {
+    foo();
+  }
+#pragma omp sections private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
+  {
+    foo();
+  }
+#pragma omp sections shared(i) // expected-error {{unexpected OpenMP clause 'shared' in directive '#pragma omp sections'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+  {
+    int i;
+#pragma omp sections private(i)
+    {
+      foo();
+    }
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp sections private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}}
+  {
+    foo();
+  }
+#pragma omp sections private(i)
+  {
+    foo();
+  }
+
+  return 0;
+}
+
diff --git a/test/OpenMP/sections_reduction_messages.cpp b/test/OpenMP/sections_reduction_messages.cpp
new file mode 100644
index 0000000..8c4bdcc
--- /dev/null
+++ b/test/OpenMP/sections_reduction_messages.cpp
@@ -0,0 +1,413 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+  S2 &operator+=(const S2 &arg) { return (*this); }
+
+public:
+  S2() : a(0) {}
+  S2(S2 &s2) : a(s2.a) {}
+  static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
+  static const float S2sc;
+};
+const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+S2 b;                     // expected-note 2 {{'b' defined here}}
+const S2 ba[5];           // expected-note 2 {{'ba' defined here}}
+class S3 {
+  int a;
+
+public:
+  S3() : a(0) {}
+  S3(const S3 &s3) : a(s3.a) {}
+  S3 operator+=(const S3 &arg1) { return arg1; }
+};
+int operator+=(const S3 &arg1, const S3 &arg2) { return 5; }
+S3 c;               // expected-note 2 {{'c' defined here}}
+const S3 ca[5];     // expected-note 2 {{'ca' defined here}}
+extern const int f; // expected-note 4 {{'f' declared here}}
+class S4 {          // expected-note {{'S4' declared here}}
+  int a;
+  S4();
+  S4(const S4 &s4);
+  S4 &operator+=(const S4 &arg) { return (*this); }
+
+public:
+  S4(int v) : a(v) {}
+};
+S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; }
+class S5 {
+  int a;
+  S5() : a(0) {}
+  S5(const S5 &s5) : a(s5.a) {}
+  S5 &operator+=(const S5 &arg);
+
+public:
+  S5(int v) : a(v) {}
+};
+class S6 {
+  int a;
+
+public:
+  S6() : a(6) {}
+  operator int() { return 6; }
+} o; // expected-note 2 {{'o' defined here}}
+
+S3 h, k;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class T>       // expected-note {{declared here}}
+T tmain(T argc) {        // expected-note 2 {{'argc' defined here}}
+  const T d = T();       // expected-note 4 {{'d' defined here}}
+  const T da[5] = {T()}; // expected-note 2 {{'da' defined here}}
+  T qa[5] = {T()};
+  T i;
+  T &j = i;                // expected-note 4 {{'j' defined here}}
+  S3 &p = k;               // expected-note 2 {{'p' defined here}}
+  const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}}
+  T &q = qa[(int)i];       // expected-note 2 {{'q' defined here}}
+  T fl;                    // expected-note {{'fl' defined here}}
+#pragma omp parallel
+#pragma omp sections reduction // expected-error {{expected '(' after 'reduction'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp sections' are ignored}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(&& : argc)
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(^ : T) // expected-error {{'T' does not refer to a value}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(max : qa[1]) // expected-error 2 {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  {
+    foo();
+  }
+#pragma omp parallel private(k)
+#pragma omp sections reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp sections reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  {
+    foo();
+  }
+#pragma omp parallel private(fl)       // expected-note 2 {{defined as private}}
+#pragma omp sections reduction(+ : fl) // expected-error 2 {{reduction variable must be shared}}
+  {
+    foo();
+  }
+#pragma omp parallel reduction(* : fl) // expected-note 2 {{defined as reduction}}
+#pragma omp sections reduction(+ : fl) // expected-error 2 {{reduction variable must be shared}}
+  {
+    foo();
+  }
+
+  return T();
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;       // expected-note 2 {{'d' defined here}}
+  const int da[5] = {0}; // expected-note {{'da' defined here}}
+  int qa[5] = {0};
+  S4 e(4); // expected-note {{'e' defined here}}
+  S5 g(5); // expected-note {{'g' defined here}}
+  int i;
+  int &j = i;           // expected-note 2 {{'j' defined here}}
+  S3 &p = k;            // expected-note 2 {{'p' defined here}}
+  const int &r = da[i]; // expected-note {{'r' defined here}}
+  int &q = qa[i];       // expected-note {{'q' defined here}}
+  float fl;             // expected-note {{'fl' defined here}}
+#pragma omp parallel
+#pragma omp sections reduction // expected-error {{expected '(' after 'reduction'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp sections' are ignored}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(foo : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(~ : argc) // expected-error {{expected unqualified-id}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(&& : argc)
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(max : argv[1]) // expected-error {{expected variable name}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(& : e, g) // expected-error {{reduction variable must have an accessible, unambiguous default constructor}} expected-error {{variable of type 'S5' is not valid for specified reduction operation}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections private(i), reduction(+ : j), reduction(+ : q) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  {
+    foo();
+  }
+#pragma omp parallel private(k)
+#pragma omp sections reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
+  {
+    foo();
+  }
+#pragma omp parallel
+#pragma omp sections reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
+  {
+    foo();
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp sections reduction(max : j) // expected-error {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  {
+    foo();
+  }
+#pragma omp parallel private(fl)       // expected-note {{defined as private}}
+#pragma omp sections reduction(+ : fl) // expected-error {{reduction variable must be shared}}
+  {
+    foo();
+  }
+#pragma omp parallel reduction(* : fl) // expected-note {{defined as reduction}}
+#pragma omp sections reduction(+ : fl) // expected-error {{reduction variable must be shared}}
+  {
+    foo();
+  }
+
+  return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain<int>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<float>' requested here}}
+}
diff --git a/test/OpenMP/simd_aligned_messages.cpp b/test/OpenMP/simd_aligned_messages.cpp
new file mode 100644
index 0000000..84cf40c
--- /dev/null
+++ b/test/OpenMP/simd_aligned_messages.cpp
@@ -0,0 +1,201 @@
+// RUN: %clang_cc1 -x c++ -std=c++11 -verify -fopenmp=libiomp5 %s
+
+struct B {
+  static int ib[20]; // expected-note 0 {{'B::ib' declared here}}
+  static constexpr int bfoo() { return 8; }
+};
+namespace X {
+  B x; // expected-note {{'x' defined here}}
+};
+constexpr int bfoo() { return 4; }
+
+int **z;
+const int C1 = 1;
+const int C2 = 2;
+void test_aligned_colons(int *&rp)
+{
+  int *B = 0;
+  #pragma omp simd aligned(B:bfoo())
+  for (int i = 0; i < 10; ++i) ;
+  // expected-error@+1 {{unexpected ':' in nested name specifier; did you mean '::'}}
+  #pragma omp simd aligned(B::ib:B:bfoo())
+  for (int i = 0; i < 10; ++i) ;
+  #pragma omp simd aligned(B:B::bfoo())
+  for (int i = 0; i < 10; ++i) ;
+  // expected-error@+1 {{unexpected ':' in nested name specifier; did you mean '::'?}}
+  #pragma omp simd aligned(z:B:bfoo())
+  for (int i = 0; i < 10; ++i) ;
+  #pragma omp simd aligned(B:B::bfoo())
+  for (int i = 0; i < 10; ++i) ;
+  // expected-error@+2 {{integral constant expression must have integral or unscoped enumeration type, not 'int **'}}
+  // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'B'}}
+  #pragma omp simd aligned(X::x : ::z)
+  for (int i = 0; i < 10; ++i) ;
+  // expected-error@+1 {{integral constant expression must have integral or unscoped enumeration type, not 'B'}}
+  #pragma omp simd aligned(B,rp,::z: X::x)
+  for (int i = 0; i < 10; ++i) ;
+  #pragma omp simd aligned(::z)
+  for (int i = 0; i < 10; ++i) ;
+  // expected-error@+1 {{expected variable name}}
+  #pragma omp simd aligned(B::bfoo())
+  for (int i = 0; i < 10; ++i) ;
+  #pragma omp simd aligned(B::ib,B:C1+C2)
+  for (int i = 0; i < 10; ++i) ;
+}
+
+// expected-note@+1 {{'num' defined here}}
+template<int L, class T, class N> T test_template(T* arr, N num) {
+  N i;
+  T sum = (T)0;
+  T ind2 = - num * L;
+  // Negative number is passed as L.
+  // expected-error@+1 {{argument to 'aligned' clause must be a positive integer value}}
+  #pragma omp simd aligned(arr:L)
+  for (i = 0; i < num; ++i) {
+    T cur = arr[(int)ind2];
+    ind2 += L;
+    sum += cur;
+  }
+  // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
+  #pragma omp simd aligned(num:4)
+  for (i = 0; i < num; ++i);
+  return T();
+}
+
+template<int LEN> int test_warn() {
+  int *ind2 = 0;
+  // expected-error@+1 {{argument to 'aligned' clause must be a positive integer value}}
+  #pragma omp simd aligned(ind2:LEN)
+  for (int i = 0; i < 100; i++) {
+    ind2 += LEN;
+  }
+  return 0;
+}
+
+struct S1; // expected-note 2 {{declared here}}
+extern S1 a; // expected-note {{'a' declared here}}
+class S2 {
+  mutable int a;
+public:
+  S2():a(0) { }
+};
+const S2 b; // expected-note 1 {{'b' defined here}}
+const S2 ba[5];
+class S3 {
+  int a;
+public:
+  S3():a(0) { }
+};
+const S3 ca[5];
+class S4 {
+  int a;
+  S4();
+public:
+  S4(int v):a(v) { }
+};
+class S5 {
+  int a;
+  S5():a(0) {}
+public:
+  S5(int v):a(v) { }
+};
+
+S3 h; // expected-note 2 {{'h' defined here}}
+#pragma omp threadprivate(h)
+
+template<class I, class C> int foomain(I argc, C **argv) {
+  I e(argc);
+  I g(argc);
+  int i; // expected-note {{declared here}} expected-note {{'i' defined here}}
+  // expected-note@+2 {{declared here}}
+  // expected-note@+1 {{reference to 'i' is not a constant expression}}
+  int &j = i;
+  #pragma omp simd aligned // expected-error {{expected '(' after 'aligned'}}
+  for (I k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (I k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned () // expected-error {{expected expression}}
+  for (I k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (I k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (I k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (I k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned (argc : 5)
+  for (I k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned (S1) // expected-error {{'S1' does not refer to a value}}
+  for (I k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned (argv[1]) // expected-error {{expected variable name}}
+  for (I k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned(e, g)
+  for (I k = 0; k < argc; ++k) ++k;
+  // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S3'}}
+  #pragma omp simd aligned(h)
+  for (I k = 0; k < argc; ++k) ++k;
+  // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
+  #pragma omp simd aligned(i)
+  for (I k = 0; k < argc; ++k) ++k;
+  #pragma omp parallel
+  {
+    int *v = 0;
+    I i;
+    #pragma omp simd aligned(v:16)
+    for (I k = 0; k < argc; ++k) { i = k; v += 2; }
+  }
+  float *f;
+  #pragma omp simd aligned(f)
+  for (I k = 0; k < argc; ++k) ++k;
+  int v = 0;
+  // expected-note@+2 {{initializer of 'j' is not a constant expression}}
+  // expected-error@+1 {{expression is not an integral constant expression}}
+  #pragma omp simd aligned(f:j)
+  for (I k = 0; k < argc; ++k) { ++k; v += j; }
+  #pragma omp simd aligned(f)
+  for (I k = 0; k < argc; ++k) ++k;
+  return 0;
+}
+
+// expected-note@+1 2 {{'argc' defined here}}
+int main(int argc, char **argv) {
+  double darr[100];
+  // expected-note@+1 {{in instantiation of function template specialization 'test_template<-4, double, int>' requested here}}
+  test_template<-4>(darr, 4);
+  test_warn<4>(); // ok
+  // expected-note@+1 {{in instantiation of function template specialization 'test_warn<0>' requested here}}
+  test_warn<0>();
+
+  int i;
+  int &j = i;
+  #pragma omp simd aligned // expected-error {{expected '(' after 'aligned'}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned () // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned (argv // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+  // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
+  #pragma omp simd aligned (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+  // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
+  #pragma omp simd aligned (argc)
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned (S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k) ++k;
+  // expected-error@+2 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S1'}}
+  // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S2'}}
+  #pragma omp simd aligned (a, b) 
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned (argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+  // expected-error@+1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S3'}}
+  #pragma omp simd aligned(h)
+  for (int k = 0; k < argc; ++k) ++k;
+  int *pargc = &argc;
+  foomain<int*,char>(pargc,argv);
+  return 0;
+}
+
diff --git a/test/OpenMP/simd_ast_print.cpp b/test/OpenMP/simd_ast_print.cpp
new file mode 100644
index 0000000..4628612
--- /dev/null
+++ b/test/OpenMP/simd_ast_print.cpp
@@ -0,0 +1,126 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+void foo() {}
+int g_ind = 1;
+template<class T, class N> T reduct(T* arr, N num) {
+  N i;
+  N ind;
+  N myind;
+  T sum = (T)0;
+// CHECK: T sum = (T)0;
+#pragma omp simd private(myind, g_ind), linear(ind), aligned(arr)
+// CHECK-NEXT: #pragma omp simd private(myind,g_ind) linear(ind) aligned(arr)
+  for (i = 0; i < num; ++i) {
+    myind = ind;
+    T cur = arr[myind];
+    ind += g_ind;
+    sum += cur;
+  }
+}
+
+template<class T> struct S {
+  S(const T &a)
+    :m_a(a)
+  {}
+  T result(T *v) const {
+    T res;
+    T val;
+    T lin = 0;
+// CHECK: T res;
+// CHECK: T val;
+// CHECK: T lin = 0;
+    #pragma omp simd private(val)  safelen(7) linear(lin : -5) lastprivate(res)
+// CHECK-NEXT: #pragma omp simd private(val) safelen(7) linear(lin: -5) lastprivate(res)
+    for (T i = 7; i < m_a; ++i) {
+      val = v[i-7] + m_a;
+      res = val;
+      lin -= 5;
+    }
+    const T clen = 3;
+// CHECK: T clen = 3;
+    #pragma omp simd safelen(clen-1)
+// CHECK-NEXT: #pragma omp simd safelen(clen - 1)
+    for(T i = clen+2; i < 20; ++i) {
+// CHECK-NEXT: for (T i = clen + 2; i < 20; ++i) {
+      v[i] = v[v-clen] + 1;
+// CHECK-NEXT: v[i] = v[v - clen] + 1;
+    }
+// CHECK-NEXT: }
+    return res;
+  }
+  ~S()
+  {}
+  T m_a;
+};
+
+template<int LEN> struct S2 {
+  static void func(int n, float *a, float *b, float *c) {
+    int k1 = 0, k2 = 0;
+#pragma omp simd safelen(LEN) linear(k1,k2:LEN) aligned(a:LEN)
+    for(int i = 0; i < n; i++) {
+      c[i] = a[i] + b[i];
+      c[k1] = a[k1] + b[k1];
+      c[k2] = a[k2] + b[k2];
+      k1 = k1 + LEN;
+      k2 = k2 + LEN;
+    }
+  }
+};
+
+// S2<4>::func is called below in main.
+// CHECK: template <int LEN = 4> struct S2 {
+// CHECK-NEXT: static void func(int n, float *a, float *b, float *c)     {
+// CHECK-NEXT:   int k1 = 0, k2 = 0;
+// CHECK-NEXT: #pragma omp simd safelen(4) linear(k1,k2: 4) aligned(a: 4)
+// CHECK-NEXT:   for (int i = 0; i < n; i++) {
+// CHECK-NEXT:     c[i] = a[i] + b[i];
+// CHECK-NEXT:     c[k1] = a[k1] + b[k1];
+// CHECK-NEXT:     c[k2] = a[k2] + b[k2];
+// CHECK-NEXT:     k1 = k1 + 4;
+// CHECK-NEXT:     k2 = k2 + 4;
+// CHECK-NEXT:   }
+// CHECK-NEXT: }
+
+int main (int argc, char **argv) {
+  int b = argc, c, d, e, f, g;
+  int k1=0,k2=0;
+  static int *a;
+// CHECK: static int *a;
+#pragma omp simd
+// CHECK-NEXT: #pragma omp simd
+  for (int i=0; i < 2; ++i)*a=2;
+// CHECK-NEXT: for (int i = 0; i < 2; ++i)
+// CHECK-NEXT: *a = 2;
+#pragma omp simd private(argc, b),lastprivate(d,f) collapse(2) aligned(a : 4)
+  for (int i = 0; i < 10; ++i)
+  for (int j = 0; j < 10; ++j) {foo(); k1 += 8; k2 += 8;}
+// CHECK-NEXT: #pragma omp simd private(argc,b) lastprivate(d,f) collapse(2) aligned(a: 4)
+// CHECK-NEXT: for (int i = 0; i < 10; ++i)
+// CHECK-NEXT: for (int j = 0; j < 10; ++j) {
+// CHECK-NEXT: foo();
+// CHECK-NEXT: k1 += 8;
+// CHECK-NEXT: k2 += 8;
+// CHECK-NEXT: }
+  for (int i = 0; i < 10; ++i)foo();
+// CHECK-NEXT: for (int i = 0; i < 10; ++i)
+// CHECK-NEXT: foo();
+  const int CLEN = 4;
+// CHECK-NEXT: const int CLEN = 4;
+  #pragma omp simd aligned(a:CLEN) linear(a:CLEN) safelen(CLEN) collapse( 1 )
+// CHECK-NEXT: #pragma omp simd aligned(a: CLEN) linear(a: CLEN) safelen(CLEN) collapse(1)
+  for (int i = 0; i < 10; ++i)foo();
+// CHECK-NEXT: for (int i = 0; i < 10; ++i)
+// CHECK-NEXT: foo();
+
+  float arr[16];
+  S2<4>::func(0,arr,arr,arr);
+  return (0);
+}
+
+#endif
diff --git a/test/OpenMP/simd_collapse_messages.cpp b/test/OpenMP/simd_collapse_messages.cpp
new file mode 100644
index 0000000..56523b3
--- /dev/null
+++ b/test/OpenMP/simd_collapse_messages.cpp
@@ -0,0 +1,83 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, typename S, int N, int ST> // expected-note {{declared here}}
+T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
+  #pragma omp 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 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 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 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 positive integer value}}
+  #pragma omp 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 simd collapse (1)) // expected-warning {{extra tokens at the end of '#pragma omp simd' are ignored}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp simd collapse ((ST > 0) ? 1 + ST : 2) // expected-note 2 {{as specified in 'collapse' clause}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST]; // expected-error 2 {{expected 2 for loops after '#pragma omp simd', but found only 1}}
+  // expected-error@+3 2 {{directive '#pragma omp simd' cannot contain more than one 'collapse' clause}}
+  // expected-error@+2 2 {{argument to 'collapse' clause must be a positive integer value}}
+  // expected-error@+1 2 {{expression is not an integral constant expression}}
+  #pragma omp 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 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];
+  // expected-error@+1 2 {{expression is not an integral constant expression}}
+  #pragma omp simd collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp simd collapse (1)
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp simd collapse (N) // expected-error {{argument to 'collapse' clause must be a positive integer value}}
+  for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp simd collapse (2) // expected-note {{as specified in 'collapse' clause}}
+  foo(); // expected-error {{expected 2 for loops after '#pragma omp simd'}}
+  return argc;
+}
+
+int main(int argc, char **argv) {
+  #pragma omp 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 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 simd collapse () // expected-error {{expected expression}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp simd collapse (4 // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{as specified in 'collapse' clause}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}}
+  #pragma omp simd collapse (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp simd' are ignored}} expected-note {{as specified in 'collapse' clause}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4]; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}}
+  #pragma omp simd collapse (foobool(1) > 0 ? 1 : 2) // expected-error {{expression is not an integral constant expression}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  // expected-error@+3 {{expression is not an integral constant expression}}
+  // expected-error@+2 2 {{directive '#pragma omp simd' cannot contain more than one 'collapse' clause}}
+  // expected-error@+1 2 {{argument to 'collapse' clause must be a positive integer value}}
+  #pragma omp 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 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];
+  // expected-error@+1 {{expression is not an integral constant expression}}
+  #pragma omp simd collapse (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp simd collapse (2) // expected-note {{as specified in 'collapse' clause}}
+  foo(); // expected-error {{expected 2 for loops after '#pragma omp simd'}}
+  // expected-error@+3 {{statement after '#pragma omp simd' must be a for loop}}
+  // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
+  #pragma omp simd collapse(collapse(tmain<int, char, -1, -2>(argc, argv) // expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}}
+  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/simd_lastprivate_messages.cpp b/test/OpenMP/simd_lastprivate_messages.cpp
new file mode 100644
index 0000000..55f6058
--- /dev/null
+++ b/test/OpenMP/simd_lastprivate_messages.cpp
@@ -0,0 +1,208 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+  S2(S2 &s2) : a(s2.a) {}
+  static float S2s; // expected-note {{static data member is predetermined as shared}}
+  static const float S2sc;
+};
+const float S2::S2sc = 0; // expected-note {{static data member is predetermined as shared}}
+const S2 b;
+const S2 ba[5];
+class S3 { // expected-note {{'S3' declared here}}
+  int a;
+  S3 &operator=(const S3 &s3);
+
+public:
+  S3() : a(0) {}
+  S3(S3 &s3) : a(s3.a) {}
+};
+const S3 c;         // expected-note {{global variable is predetermined as shared}}
+const S3 ca[5];     // expected-note {{global variable is predetermined as shared}}
+extern const int f; // expected-note {{global variable is predetermined as shared}}
+class S4 {          // expected-note {{'S4' declared here}}
+  int a;
+  S4();
+  S4(const S4 &s4);
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note {{'S5' declared here}}
+  int a;
+  S5() : a(0) {}
+
+public:
+  S5(const S5 &s5) : a(s5.a) {}
+  S5(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(I argc, C **argv) {
+  I e(4);
+  I g(5);
+  int i;
+  int &j = i;                // expected-note {{'j' defined here}}
+#pragma omp simd lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp simd lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp simd lastprivate() // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp simd lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp simd lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp simd lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp simd lastprivate(argc)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp simd lastprivate(a, b) // expected-error {{lastprivate variable with incomplete type 'S1'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp simd lastprivate(argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp simd lastprivate(e, g)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp simd lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp simd firstprivate(i) // expected-error {{unexpected OpenMP clause 'firstprivate' in directive '#pragma omp simd'}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;
+#pragma omp simd lastprivate(i)
+    for (int k = 0; k < argc; ++k) {
+      i = k;
+      v += i;
+    }
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp simd lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}}
+  for (int k = 0; k < argc; ++k)
+    ++k;
+#pragma omp simd lastprivate(i)
+  for (int k = 0; k < argc; ++k)
+    ++k;
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;       // expected-note {{constant variable is predetermined as shared}}
+  const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+  S4 e(4);               // expected-note {{'e' defined here}}
+  S5 g(5);               // expected-note {{'g' defined here}}
+  S3 m;                  // expected-note {{'m' defined here}}
+  int i;
+  int &j = i;                // expected-note {{'j' defined here}}
+#pragma omp simd lastprivate // expected-error {{expected '(' after 'lastprivate'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate() // expected-error {{expected expression}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate(argc)
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate(a, b, c, d, f) // expected-error {{lastprivate variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate(argv[1]) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate(2 * 2) // expected-error {{expected variable name}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate(ba)
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate(ca) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate(da) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+  int xa;
+#pragma omp simd lastprivate(xa) // OK
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate(S2::S2s) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate(S2::S2sc) // expected-error {{shared variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd firstprivate(g) // expected-error {{unexpected OpenMP clause 'firstprivate' in directive '#pragma omp simd'}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate(e, g) // expected-error 2 {{lastprivate variable must have an accessible, unambiguous default constructor}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate(m) // expected-error {{lastprivate variable must have an accessible, unambiguous copy assignment operator}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate(h) // expected-error {{threadprivate or thread local variable cannot be lastprivate}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd private(xa), lastprivate(xa) // expected-error {{private variable cannot be lastprivate}} expected-note {{defined as private}}
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp simd lastprivate(i) // expected-note {{defined as lastprivate}}
+  for (i = 0; i < argc; ++i) // expected-error {{loop iteration variable in the associated loop of 'omp simd' directive may not be lastprivate, predetermined as linear}}
+    foo();
+#pragma omp parallel private(xa)
+#pragma omp simd lastprivate(xa) // OK: may be lastprivate
+  for (i = 0; i < argc; ++i)
+    foo();
+#pragma omp parallel
+#pragma omp simd lastprivate(j) // expected-error {{arguments of OpenMP clause 'lastprivate' cannot be of reference type}}
+  for (i = 0; i < argc; ++i)
+    foo();
+  return 0;
+}
diff --git a/test/OpenMP/simd_linear_messages.cpp b/test/OpenMP/simd_linear_messages.cpp
new file mode 100644
index 0000000..b8b7831
--- /dev/null
+++ b/test/OpenMP/simd_linear_messages.cpp
@@ -0,0 +1,206 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %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 simd linear(B:bfoo())
+  for (int i = 0; i < 10; ++i) ;
+  // expected-error@+1 {{unexpected ':' in nested name specifier; did you mean '::'}}
+  #pragma omp simd linear(B::ib:B:bfoo())
+  for (int i = 0; i < 10; ++i) ;
+  // expected-error@+1 {{use of undeclared identifier 'ib'; did you mean 'B::ib'}}
+  #pragma omp simd linear(B:ib)
+  for (int i = 0; i < 10; ++i) ;
+  // expected-error@+1 {{unexpected ':' in nested name specifier; did you mean '::'?}}
+  #pragma omp simd linear(z:B:ib)
+  for (int i = 0; i < 10; ++i) ;
+  #pragma omp simd linear(B:B::bfoo())
+  for (int i = 0; i < 10; ++i) ;
+  #pragma omp simd linear(X::x : ::z)
+  for (int i = 0; i < 10; ++i) ;
+  #pragma omp simd linear(B,::z, X::x)
+  for (int i = 0; i < 10; ++i) ;
+  #pragma omp simd linear(::z)
+  for (int i = 0; i < 10; ++i) ;
+  // expected-error@+1 {{expected variable name}}
+  #pragma omp simd linear(B::bfoo())
+  for (int i = 0; i < 10; ++i) ;
+  #pragma omp 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}}
+  // expected-error@+1 {{argument of a linear clause should be of integral or pointer type}}
+#pragma omp simd linear(ind2:L)
+  for (i = 0; i < num; ++i) {
+    T cur = arr[(int)ind2];
+    ind2 += L;
+    sum += cur;
+  }
+  return T();
+}
+
+template<int LEN> int test_warn() {
+  int ind2 = 0;
+  // expected-warning@+1 {{zero linear step (ind2 should probably be const)}}
+  #pragma omp simd linear(ind2:LEN)
+  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; // expected-note {{'j' defined here}}
+  #pragma omp simd linear // expected-error {{expected '(' after 'linear'}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd linear () // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp 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 simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd linear (argc : 5)
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd linear (S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k) ++k;
+  // expected-error@+2 {{linear variable with incomplete type 'S1'}}
+  // expected-error@+1 {{const-qualified variable cannot be linear}}
+  #pragma omp simd linear (a, b:B::ib)
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd linear (argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd linear(e, g)
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd linear(i)
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp parallel
+  {
+    int v = 0;
+    int i;
+    #pragma omp simd linear(v:i)
+    for (int k = 0; k < argc; ++k) { i = k; v += i; }
+  }
+  #pragma omp simd linear(j) // expected-error {{arguments of OpenMP clause 'linear' cannot be of reference type}}
+  for (int k = 0; k < argc; ++k) ++k;
+  int v = 0;
+  #pragma omp simd linear(v:j)
+  for (int k = 0; k < argc; ++k) { ++k; v += j; }
+  #pragma omp simd linear(i)
+  for (int k = 0; k < argc; ++k) ++k;
+  return 0;
+}
+
+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; // expected-note {{'j' defined here}}
+  #pragma omp simd linear // expected-error {{expected '(' after 'linear'}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd linear () // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp 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 simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd linear (argc)
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd linear (S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k) ++k;
+  // expected-error@+2 {{linear variable with incomplete type 'S1'}}
+  // expected-error@+1 {{const-qualified variable cannot be linear}}
+  #pragma omp simd linear (a, b) 
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd linear (argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+  // expected-error@+2 {{argument of a linear clause should be of integral or pointer type, not 'S4'}}
+  // expected-error@+1 {{argument of a linear clause should be of integral or pointer type, not 'S5'}}
+  #pragma omp simd linear(e, g)
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp parallel
+  {
+    int i;
+    #pragma omp simd linear(i)
+    for (int k = 0; k < argc; ++k) ++k;
+    #pragma omp simd linear(i : 4)
+    for (int k = 0; k < argc; ++k) { ++k; i += 4; }
+  }
+  #pragma omp simd linear(j) // expected-error {{arguments of OpenMP clause 'linear' cannot be of reference type 'int &'}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd linear(i)
+  for (int k = 0; k < argc; ++k) ++k;
+
+  foomain<int,char>(argc,argv);
+  return 0;
+}
+
diff --git a/test/OpenMP/simd_loop_messages.cpp b/test/OpenMP/simd_loop_messages.cpp
new file mode 100644
index 0000000..ea663fd
--- /dev/null
+++ b/test/OpenMP/simd_loop_messages.cpp
@@ -0,0 +1,579 @@
+// RUN: %clang_cc1 -fsyntax-only -fopenmp=libiomp5 -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify %s
+
+static int sii;
+#pragma omp threadprivate(sii) // expected-note {{defined as threadprivate or thread local}}
+
+int test_iteration_spaces() {
+  const int N = 100;
+  float a[N], b[N], c[N];
+  int ii, jj, kk;
+  float fii;
+  double dii;
+  #pragma omp simd
+  for (int i = 0; i < 10; i+=1) {
+    c[i] = a[i] + b[i];
+  }
+  #pragma omp simd
+  for (char i = 0; i < 10; i++) {
+    c[i] = a[i] + b[i];
+  }
+  #pragma omp simd
+  for (char i = 0; i < 10; i+='\1') {
+    c[i] = a[i] + b[i];
+  }
+  #pragma omp simd
+  for (long long i = 0; i < 10; i++) {
+    c[i] = a[i] + b[i];
+  }
+  // expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'double'}}
+  #pragma omp simd
+  for (long long i = 0; i < 10; i+=1.5) {
+    c[i] = a[i] + b[i];
+  }
+  #pragma omp simd
+  for (long long i = 0; i < 'z'; i+=1u) {
+    c[i] = a[i] + b[i];
+  }
+  // expected-error@+2 {{variable must be of integer or random access iterator type}}
+  #pragma omp simd
+  for (float fi = 0; fi < 10.0; fi++) {
+    c[(int)fi] = a[(int)fi] + b[(int)fi];
+  }
+  // expected-error@+2 {{variable must be of integer or random access iterator type}}
+  #pragma omp simd
+  for (double fi = 0; fi < 10.0; fi++) {
+    c[(int)fi] = a[(int)fi] + b[(int)fi];
+  }
+  // expected-error@+2 {{variable must be of integer or random access iterator type}}
+  #pragma omp simd
+  for (int &ref = ii; ref < 10; ref++) {
+  }
+  // expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
+  #pragma omp simd
+  for (int i; i < 10; i++)
+    c[i] = a[i];
+
+  // expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
+  #pragma omp simd
+  for (int i = 0, j = 0; i < 10; ++i)
+    c[i] = a[i];
+
+  // expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
+  #pragma omp simd
+  for (;ii < 10; ++ii)
+    c[ii] = a[ii];
+
+  // expected-warning@+3 {{expression result unused}}
+  // expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
+  #pragma omp simd
+  for (ii + 1;ii < 10; ++ii)
+    c[ii] = a[ii];
+
+  // expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
+  #pragma omp simd
+  for (c[ii] = 0;ii < 10; ++ii)
+    c[ii] = a[ii];
+
+  // Ok to skip parenthesises.
+  #pragma omp simd
+  for (((ii)) = 0;ii < 10; ++ii)
+    c[ii] = a[ii];
+
+  // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+  #pragma omp simd
+  for (int i = 0; i; i++)
+    c[i] = a[i];
+
+  // expected-error@+3 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+  // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'i'}}
+  #pragma omp simd
+  for (int i = 0; jj < kk; ii++)
+    c[i] = a[i];
+
+  // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+  #pragma omp simd
+  for (int i = 0; !!i; i++)
+    c[i] = a[i];
+
+  // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+  #pragma omp simd
+  for (int i = 0; i != 1; i++)
+    c[i] = a[i];
+
+  // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
+  #pragma omp simd
+  for (int i = 0; ; i++)
+    c[i] = a[i];
+
+  // Ok.
+  #pragma omp simd
+  for (int i = 11; i > 10; i--)
+    c[i] = a[i];
+
+  // Ok.
+  #pragma omp simd
+  for (int i = 0; i < 10; ++i)
+    c[i] = a[i];
+
+    // Ok.
+  #pragma omp simd
+  for (ii = 0; ii < 10; ++ii)
+    c[ii] = a[ii];
+
+  // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  #pragma omp simd
+  for (ii = 0; ii < 10; ++jj)
+    c[ii] = a[jj];
+
+  // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  #pragma omp simd
+  for (ii = 0; ii < 10; ++ ++ ii)
+    c[ii] = a[ii];
+
+  // Ok but undefined behavior (in general, cannot check that incr
+  // is really loop-invariant).
+  #pragma omp simd
+  for (ii = 0; ii < 10; ii = ii + ii)
+    c[ii] = a[ii];
+
+  // expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'float'}}
+  #pragma omp simd
+  for (ii = 0; ii < 10; ii = ii + 1.0f)
+    c[ii] = a[ii];
+
+  // Ok - step was converted to integer type.
+  #pragma omp simd
+  for (ii = 0; ii < 10; ii = ii + (int)1.1f)
+    c[ii] = a[ii];
+
+  // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  #pragma omp simd
+  for (ii = 0; ii < 10; jj = ii + 2)
+    c[ii] = a[ii];
+
+  // expected-warning@+3 {{relational comparison result unused}}
+  // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  #pragma omp simd
+  for (ii = 0; ii < 10; jj > kk + 2)
+    c[ii] = a[ii];
+
+  // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  #pragma omp simd
+  for (ii = 0; ii < 10;)
+    c[ii] = a[ii];
+
+  // expected-warning@+3 {{expression result unused}}
+  // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  #pragma omp simd
+  for (ii = 0; ii < 10; !ii)
+    c[ii] = a[ii];
+
+  // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  #pragma omp simd
+  for (ii = 0; ii < 10; ii ? ++ii : ++jj)
+    c[ii] = a[ii];
+
+  // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
+  #pragma omp simd
+  for (ii = 0; ii < 10; ii = ii < 10)
+    c[ii] = a[ii];
+
+  // expected-note@+3 {{loop step is expected to be positive due to this condition}}
+  // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+  #pragma omp simd
+  for (ii = 0; ii < 10; ii = ii + 0)
+    c[ii] = a[ii];
+
+  // expected-note@+3 {{loop step is expected to be positive due to this condition}}
+  // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+  #pragma omp simd
+  for (ii = 0; ii < 10; ii = ii + (int)(0.8 - 0.45))
+    c[ii] = a[ii];
+
+  // expected-note@+3 {{loop step is expected to be positive due to this condition}}
+  // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+  #pragma omp simd
+  for (ii = 0; (ii) < 10; ii-=25)
+    c[ii] = a[ii];
+
+  // expected-note@+3 {{loop step is expected to be positive due to this condition}}
+  // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+  #pragma omp simd
+  for (ii = 0; (ii < 10); ii-=0)
+    c[ii] = a[ii];
+
+  // expected-note@+3 {{loop step is expected to be negative due to this condition}}
+  // expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}}
+  #pragma omp simd
+  for (ii = 0; ii > 10; (ii+=0))
+    c[ii] = a[ii];
+
+  // expected-note@+3 {{loop step is expected to be positive due to this condition}}
+  // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+  #pragma omp simd
+  for (ii = 0; ii < 10; (ii) = (1-1)+(ii))
+    c[ii] = a[ii];
+
+  // expected-note@+3 {{loop step is expected to be negative due to this condition}}
+  // expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}}
+  #pragma omp simd
+  for ((ii = 0); ii > 10; (ii-=0))
+    c[ii] = a[ii];
+
+  // expected-note@+3 {{loop step is expected to be positive due to this condition}}
+  // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
+  #pragma omp simd
+  for (ii = 0; (ii < 10); (ii-=0))
+    c[ii] = a[ii];
+
+  // expected-note@+2  {{defined as private}}
+  // expected-error@+2 {{loop iteration variable in the associated loop of 'omp simd' directive may not be private, predetermined as linear}}
+  #pragma omp simd private(ii)
+  for (ii = 0; ii < 10; ii++)
+    c[ii] = a[ii];
+
+  // expected-error@+3 {{unexpected OpenMP clause 'shared' in directive '#pragma omp simd'}}
+  // expected-note@+2  {{defined as shared}}
+  // expected-error@+2 {{loop iteration variable in the associated loop of 'omp simd' directive may not be shared, predetermined as linear}}
+  #pragma omp simd shared(ii)
+  for (ii = 0; ii < 10; ii++)
+    c[ii] = a[ii];
+
+  #pragma omp simd linear(ii)
+  for (ii = 0; ii < 10; ii++)
+    c[ii] = a[ii];
+
+  #pragma omp simd lastprivate(ii) linear(jj) collapse(2) // expected-note {{defined as linear}}
+  for (ii = 0; ii < 10; ii++)
+  for (jj = 0; jj < 10; jj++) // expected-error {{loop iteration variable in the associated loop of 'omp simd' directive may not be linear, predetermined as lastprivate}}
+    c[ii] = a[jj];
+
+
+  #pragma omp parallel
+  {
+    // expected-error@+2 {{loop iteration variable in the associated loop of 'omp simd' directive may not be threadprivate or thread local, predetermined as linear}}
+    #pragma omp simd
+    for (sii = 0; sii < 10; sii+=1)
+      c[sii] = a[sii];
+  }
+
+  // expected-error@+2 {{statement after '#pragma omp simd' must be a for loop}}
+  #pragma omp simd
+  for (auto &item : a) {
+    item = item + 1;
+  }
+
+  // expected-note@+3 {{loop step is expected to be positive due to this condition}}
+  // expected-error@+2 {{increment expression must cause 'i' to increase on each iteration of OpenMP for loop}}
+  #pragma omp simd
+  for (unsigned i = 9; i < 10; i--) {
+    c[i] = a[i] + b[i];
+  }
+
+  int (*lb)[4] = nullptr;
+  #pragma omp simd
+  for (int (*p)[4] = lb; p < lb + 8; ++p) {
+  }
+
+  // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  #pragma omp simd
+  for (int a{0}; a<10; ++a) {
+  }
+
+  return 0;
+}
+
+// Iterators allowed in openmp for-loops.
+namespace std {
+struct random_access_iterator_tag { };
+template <class Iter> struct iterator_traits {
+  typedef typename Iter::difference_type difference_type;
+  typedef typename Iter::iterator_category iterator_category;
+};
+template <class Iter>
+typename iterator_traits<Iter>::difference_type
+distance(Iter first, Iter last) { return first - last; }
+}
+class Iter0 {
+  public:
+    Iter0() { }
+    Iter0(const Iter0 &) { }
+    Iter0 operator ++() { return *this; }
+    Iter0 operator --() { return *this; }
+    bool operator <(Iter0 a) { return true; }
+};
+int operator -(Iter0 a, Iter0 b) { return 0; }
+class Iter1 {
+  public:
+    Iter1(float f=0.0f, double d=0.0) { }
+    Iter1(const Iter1 &) { }
+    Iter1 operator ++() { return *this; }
+    Iter1 operator --() { return *this; }
+    bool operator <(Iter1 a) { return true; }
+    bool operator >=(Iter1 a) { return false; }
+};
+class GoodIter {
+  public:
+    GoodIter() { }
+    GoodIter(const GoodIter &) { }
+    GoodIter(int fst, int snd) { }
+    GoodIter &operator =(const GoodIter &that) { return *this; }
+    GoodIter &operator =(const Iter0 &that) { return *this; }
+    GoodIter &operator +=(int x) { return *this; }
+    explicit GoodIter(void *) { }
+    GoodIter operator ++() { return *this; }
+    GoodIter operator --() { return *this; }
+    bool operator !() { return true; }
+    bool operator <(GoodIter a) { return true; }
+    bool operator <=(GoodIter a) { return true; }
+    bool operator >=(GoodIter a) { return false; }
+    typedef int difference_type;
+    typedef std::random_access_iterator_tag iterator_category;
+};
+int operator -(GoodIter a, GoodIter b) { return 0; }
+GoodIter operator -(GoodIter a) { return a; }
+GoodIter operator -(GoodIter a, int v) { return GoodIter(); }
+GoodIter operator +(GoodIter a, int v) { return GoodIter(); }
+GoodIter operator -(int v, GoodIter a) { return GoodIter(); }
+GoodIter operator +(int v, GoodIter a) { return GoodIter(); }
+
+int test_with_random_access_iterator() {
+  GoodIter begin, end;
+  Iter0 begin0, end0;
+  #pragma omp simd
+  for (GoodIter I = begin; I < end; ++I)
+    ++I;
+  // expected-error@+2 {{variable must be of integer or random access iterator type}}
+  #pragma omp simd
+  for (GoodIter &I = begin; I < end; ++I)
+    ++I;
+  #pragma omp simd
+  for (GoodIter I = begin; I >= end; --I)
+    ++I;
+  // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  #pragma omp simd
+  for (GoodIter I(begin); I < end; ++I)
+    ++I;
+  // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  #pragma omp simd
+  for (GoodIter I(nullptr); I < end; ++I)
+    ++I;
+  // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  #pragma omp simd
+  for (GoodIter I(0); I < end; ++I)
+    ++I;
+  // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  #pragma omp simd
+  for (GoodIter I(1,2); I < end; ++I)
+    ++I;
+  #pragma omp simd
+  for (begin = GoodIter(0); begin < end; ++begin)
+    ++begin;
+  #pragma omp simd
+  for (begin = begin0; begin < end; ++begin)
+    ++begin;
+  // expected-error@+2 {{initialization clause of OpenMP for loop must be of the form 'var = init' or 'T var = init'}}
+  #pragma omp simd
+  for (++begin; begin < end; ++begin)
+    ++begin;
+  #pragma omp simd
+  for (begin = end; begin < end; ++begin)
+    ++begin;
+  // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+  #pragma omp simd
+  for (GoodIter I = begin; I - I; ++I)
+    ++I;
+  // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+  #pragma omp simd
+  for (GoodIter I = begin; begin < end; ++I)
+    ++I;
+  // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
+  #pragma omp simd
+  for (GoodIter I = begin; !I; ++I)
+    ++I;
+  // expected-note@+3 {{loop step is expected to be negative due to this condition}}
+  // expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+  #pragma omp simd
+  for (GoodIter I = begin; I >= end; I = I + 1)
+    ++I;
+  #pragma omp simd
+  for (GoodIter I = begin; I >= end; I = I - 1)
+    ++I;
+  // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}}
+  #pragma omp simd
+  for (GoodIter I = begin; I >= end; I = -I)
+    ++I;
+  // expected-note@+3 {{loop step is expected to be negative due to this condition}}
+  // expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+  #pragma omp simd
+  for (GoodIter I = begin; I >= end; I = 2 + I)
+    ++I;
+  // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}}
+  #pragma omp simd
+  for (GoodIter I = begin; I >= end; I = 2 - I)
+    ++I;
+  #pragma omp simd
+  for (Iter0 I = begin0; I < end0; ++I)
+    ++I;
+  // Initializer is constructor without params.
+  // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  #pragma omp simd
+  for (Iter0 I; I < end0; ++I)
+    ++I;
+  Iter1 begin1, end1;
+  #pragma omp simd
+  for (Iter1 I = begin1; I < end1; ++I)
+    ++I;
+  // expected-note@+3 {{loop step is expected to be negative due to this condition}}
+  // expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+  #pragma omp simd
+  for (Iter1 I = begin1; I >= end1; ++I)
+    ++I;
+  // Initializer is constructor with all default params.
+  // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
+  #pragma omp simd
+  for (Iter1 I; I < end1; ++I) {
+  }
+  return 0;
+}
+
+template <typename IT, int ST> class TC {
+  public:
+    int dotest_lt(IT begin, IT end) {
+      // expected-note@+3 {{loop step is expected to be positive due to this condition}}
+      // expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}}
+      #pragma omp simd
+      for (IT I = begin; I < end; I = I + ST) {
+        ++I;
+      }
+      // expected-note@+3 {{loop step is expected to be positive due to this condition}}
+      // expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}}
+      #pragma omp simd
+      for (IT I = begin; I <= end; I += ST) {
+        ++I;
+      }
+      #pragma omp simd
+      for (IT I = begin; I < end; ++I) {
+        ++I;
+      }
+    }
+
+    static IT step() {
+      return IT(ST);
+    }
+};
+template <typename IT, int ST=0> int dotest_gt(IT begin, IT end) {
+  // expected-note@+3 2 {{loop step is expected to be negative due to this condition}}
+  // expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+  #pragma omp simd
+  for (IT I = begin; I >= end; I = I + ST) {
+    ++I;
+  }
+  // expected-note@+3 2 {{loop step is expected to be negative due to this condition}}
+  // expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+  #pragma omp simd
+  for (IT I = begin; I >= end; I += ST) {
+    ++I;
+  }
+
+  // expected-note@+3 {{loop step is expected to be negative due to this condition}}
+  // expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
+  #pragma omp simd
+  for (IT I = begin; I >= end; ++I) {
+    ++I;
+  }
+
+  #pragma omp simd
+  for (IT I = begin; I < end; I+=TC<int,ST>::step()) {
+    ++I;
+  }
+}
+
+void test_with_template() {
+  GoodIter begin, end;
+  TC<GoodIter, 100> t1;
+  TC<GoodIter, -100> t2;
+  t1.dotest_lt(begin, end);
+  t2.dotest_lt(begin, end); // expected-note {{in instantiation of member function 'TC<GoodIter, -100>::dotest_lt' requested here}}
+  dotest_gt(begin, end); // expected-note {{in instantiation of function template specialization 'dotest_gt<GoodIter, 0>' requested here}}
+  dotest_gt<unsigned, -10>(0, 100); // expected-note {{in instantiation of function template specialization 'dotest_gt<unsigned int, -10>' requested here}}
+}
+
+void test_loop_break() {
+  const int N = 100;
+  float a[N], b[N], c[N];
+  #pragma omp simd
+  for (int i = 0; i < 10; i++) {
+    c[i] = a[i] + b[i];
+    for (int j = 0; j < 10; ++j) {
+      if (a[i] > b[j])
+        break; // OK in nested loop
+    }
+    switch(i) {
+      case 1:
+        b[i]++;
+        break;
+      default:
+        break;
+    }
+    if (c[i] > 10)
+      break; // expected-error {{'break' statement cannot be used in OpenMP for loop}}
+
+    if (c[i] > 11)
+      break; // expected-error {{'break' statement cannot be used in OpenMP for loop}}
+  }
+
+  #pragma omp simd
+  for (int i = 0; i < 10; i++) {
+    for (int j = 0; j < 10; j++) {
+      c[i] = a[i] + b[i];
+      if (c[i] > 10) {
+        if (c[i] < 20) {
+          break; // OK
+        }
+      }
+    }
+  }
+}
+
+void test_loop_eh() {
+  const int N = 100;
+  float a[N], b[N], c[N];
+  #pragma omp simd
+  for (int i = 0; i < 10; i++) {
+    c[i] = a[i] + b[i];
+    try { // expected-error {{'try' statement cannot be used in OpenMP simd region}}
+      for (int j = 0; j < 10; ++j) {
+        if (a[i] > b[j])
+          throw a[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}}
+      }
+      throw a[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}}
+    }
+    catch (float f) {
+      if (f > 0.1)
+        throw a[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}}
+      return; // expected-error {{cannot return from OpenMP region}}
+    }
+    switch(i) {
+      case 1:
+        b[i]++;
+        break;
+      default:
+        break;
+    }
+    for (int j = 0; j < 10; j++) {
+      if (c[i] > 10)
+        throw c[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}}
+    }
+  }
+  if (c[9] > 10)
+    throw c[9]; // OK
+
+  #pragma omp simd
+  for (int i = 0; i < 10; ++i) {
+    struct S {
+      void g() { throw 0; }
+    };
+  }
+}
+
diff --git a/test/OpenMP/simd_metadata.c b/test/OpenMP/simd_metadata.c
new file mode 100644
index 0000000..a0588ad
--- /dev/null
+++ b/test/OpenMP/simd_metadata.c
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -fopenmp=libiomp5 -emit-llvm %s -o - | FileCheck %s
+
+void h1(float *c, float *a, float *b, int size)
+{
+// CHECK-LABEL: define void @h1
+  int t = 0;
+#pragma omp simd safelen(16) linear(t)
+  for (int i = 0; i < size; ++i) {
+    c[i] = a[i] * a[i] + b[i] * b[t];
+    ++t;
+// do not emit parallel_loop_access metadata due to usage of safelen clause.
+// CHECK-NOT: store float {{.+}}, float* {{.+}}, align {{.+}}, !llvm.mem.parallel_loop_access {{![0-9]+}}
+  }
+}
+
+void h2(float *c, float *a, float *b, int size)
+{
+// CHECK-LABEL: define void @h2
+  int t = 0;
+#pragma omp simd linear(t)
+  for (int i = 0; i < size; ++i) {
+    c[i] = a[i] * a[i] + b[i] * b[t];
+    ++t;
+// CHECK: store float {{.+}}, float* {{.+}}, align {{.+}}, !llvm.mem.parallel_loop_access [[LOOP_H2_HEADER:![0-9]+]]
+  }
+}
+
+void h3(float *c, float *a, float *b, int size)
+{
+// CHECK-LABEL: define void @h3
+#pragma omp simd
+  for (int i = 0; i < size; ++i) {
+    for (int j = 0; j < size; ++j) {
+      c[j*i] = a[i] * b[j];
+    }
+  }
+// do not emit parallel_loop_access for nested loop.
+// CHECK-NOT: store float {{.+}}, float* {{.+}}, align {{.+}}, !llvm.mem.parallel_loop_access {{![0-9]+}}
+}
+
+// Metadata for h1:
+// CHECK: [[LOOP_H1_HEADER:![0-9]+]] = metadata !{metadata [[LOOP_H1_HEADER]], metadata [[LOOP_WIDTH_16:![0-9]+]], metadata [[LOOP_VEC_ENABLE:![0-9]+]]}
+// CHECK: [[LOOP_WIDTH_16]] = metadata !{metadata !"llvm.loop.vectorize.width", i32 16}
+// CHECK: [[LOOP_VEC_ENABLE]] = metadata !{metadata !"llvm.loop.vectorize.enable", i1 true}
+//
+// Metadata for h2:
+// CHECK: [[LOOP_H2_HEADER]] = metadata !{metadata [[LOOP_H2_HEADER]], metadata [[LOOP_VEC_ENABLE]]}
+//
+// Metadata for h3:
+// CHECK: [[LOOP_H3_HEADER:![0-9]+]] = metadata !{metadata [[LOOP_H3_HEADER]], metadata [[LOOP_VEC_ENABLE]]}
+//
diff --git a/test/OpenMP/simd_misc_messages.c b/test/OpenMP/simd_misc_messages.c
new file mode 100644
index 0000000..67edc6d
--- /dev/null
+++ b/test/OpenMP/simd_misc_messages.c
@@ -0,0 +1,555 @@
+// RUN: %clang_cc1 -fsyntax-only -fopenmp=libiomp5 -verify %s
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp simd'}}
+#pragma omp simd
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp simd'}}
+#pragma omp simd foo
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp simd'}}
+#pragma omp simd safelen(4)
+
+void test_no_clause()
+{
+  int i;
+  #pragma omp simd
+  for (i = 0; i < 16; ++i) ;
+
+  // expected-error@+2 {{statement after '#pragma omp simd' must be a for loop}}
+  #pragma omp simd
+  ++i;
+}
+
+void test_branch_protected_scope()
+{
+  int i = 0;
+L1:
+  ++i;
+
+  int x[24];
+
+  #pragma omp 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 simd' are ignored}}
+  #pragma omp 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 simd' are ignored}}
+  #pragma omp simd;
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+2 {{unexpected OpenMP clause 'firstprivate' in directive '#pragma omp simd'}}
+  // expected-warning@+1 {{extra tokens at the end of '#pragma omp simd' are ignored}}
+  #pragma omp simd firstprivate(x);
+  for (i = 0; i < 16; ++i) ;
+
+  // expected-warning@+1 {{extra tokens at the end of '#pragma omp simd' are ignored}}
+  #pragma omp simd private(x);
+  for (i = 0; i < 16; ++i) ;
+
+  // expected-warning@+1 {{extra tokens at the end of '#pragma omp simd' are ignored}}
+  #pragma omp simd , private(x);
+  for (i = 0; i < 16; ++i) ;
+}
+
+extern int foo();
+void test_safelen()
+{
+  int i;
+  // expected-error@+1 {{expected '('}}
+  #pragma omp simd safelen
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+  #pragma omp simd safelen(
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected expression}}
+  #pragma omp simd safelen()
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+  #pragma omp simd safelen(,
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected expression}}  expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+  #pragma omp simd safelen(,)
+  for (i = 0; i < 16; ++i) ;
+  // expected-warning@+2 {{extra tokens at the end of '#pragma omp simd' are ignored}}
+  // expected-error@+1 {{expected '('}}
+  #pragma omp simd safelen 4)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+2 {{expected ')'}}
+  // expected-note@+1 {{to match this '('}}
+  #pragma omp simd safelen(4
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+2 {{expected ')'}}
+  // expected-note@+1 {{to match this '('}}
+  #pragma omp simd safelen(4,
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+2 {{expected ')'}}
+  // expected-note@+1 {{to match this '('}}
+  #pragma omp simd safelen(4,)
+  for (i = 0; i < 16; ++i) ;
+  // xxpected-error@+1 {{expected expression}}
+  #pragma omp simd safelen(4)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+2 {{expected ')'}}
+  // expected-note@+1 {{to match this '('}}
+  #pragma omp simd safelen(4 4)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+2 {{expected ')'}}
+  // expected-note@+1 {{to match this '('}}
+  #pragma omp simd safelen(4,,4)
+  for (i = 0; i < 16; ++i) ;
+  #pragma omp simd safelen(4)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+2 {{expected ')'}}
+  // expected-note@+1 {{to match this '('}}
+  #pragma omp simd safelen(4,8)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expression is not an integer constant expression}}
+  #pragma omp simd safelen(2.5)
+  for (i = 0; i < 16; ++i);
+  // expected-error@+1 {{expression is not an integer constant expression}}
+  #pragma omp simd safelen(foo())
+  for (i = 0; i < 16; ++i);
+  // expected-error@+1 {{argument to 'safelen' clause must be a positive integer value}}
+  #pragma omp simd safelen(-5)
+  for (i = 0; i < 16; ++i);
+  // expected-error@+1 {{argument to 'safelen' clause must be a positive integer value}}
+  #pragma omp simd safelen(0)
+  for (i = 0; i < 16; ++i);
+  // expected-error@+1 {{argument to 'safelen' clause must be a positive integer value}}
+  #pragma omp simd safelen(5-5)
+  for (i = 0; i < 16; ++i);
+}
+
+void test_collapse()
+{
+  int i;
+  // expected-error@+1 {{expected '('}}
+  #pragma omp 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 simd collapse(
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected expression}}
+  #pragma omp 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 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 simd collapse(,)
+  for (i = 0; i < 16; ++i) ;
+  // expected-warning@+2 {{extra tokens at the end of '#pragma omp simd' are ignored}}
+  // expected-error@+1 {{expected '('}}
+  #pragma omp 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 simd collapse(4
+  for (i = 0; i < 16; ++i) ; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}}
+  // expected-error@+2 {{expected ')'}}
+  // expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+  #pragma omp simd collapse(4,
+  for (i = 0; i < 16; ++i) ; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}}
+  // expected-error@+2 {{expected ')'}}
+  // expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+  #pragma omp simd collapse(4,)
+  for (i = 0; i < 16; ++i) ; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}}
+  // xxpected-error@+1 {{expected expression}} expected-note@+1 {{as specified in 'collapse' clause}}
+  #pragma omp simd collapse(4)
+  for (i = 0; i < 16; ++i) ; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}}
+  // expected-error@+2 {{expected ')'}}
+  // expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+  #pragma omp simd collapse(4 4)
+  for (i = 0; i < 16; ++i) ; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}}
+  // expected-error@+2 {{expected ')'}}
+  // expected-note@+1 {{to match this '('}} expected-note@+1 {{as specified in 'collapse' clause}}
+  #pragma omp simd collapse(4,,4)
+  for (i = 0; i < 16; ++i) ; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}}
+  #pragma omp simd collapse(4)
+  for (int i1 = 0; i1 < 16; ++i1)
+    for (int i2 = 0; i2 < 16; ++i2)
+      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 simd collapse(4,8)
+  for (i = 0; i < 16; ++i) ; // expected-error {{expected 4 for loops after '#pragma omp simd', but found only 1}}
+  // expected-error@+1 {{expression is not an integer constant expression}}
+  #pragma omp simd collapse(2.5)
+  for (i = 0; i < 16; ++i);
+  // expected-error@+1 {{expression is not an integer constant expression}}
+  #pragma omp simd collapse(foo())
+  for (i = 0; i < 16; ++i);
+  // expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}}
+  #pragma omp simd collapse(-5)
+  for (i = 0; i < 16; ++i);
+  // expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}}
+  #pragma omp simd collapse(0)
+  for (i = 0; i < 16; ++i);
+  // expected-error@+1 {{argument to 'collapse' clause must be a positive integer value}}
+  #pragma omp simd collapse(5-5)
+  for (i = 0; i < 16; ++i);
+}
+
+void test_linear()
+{
+  int i;
+  // expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+  #pragma omp simd linear(
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+2 {{expected expression}}
+  // expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+  #pragma omp simd linear(,
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+2 {{expected expression}}
+  // expected-error@+1 {{expected expression}}
+  #pragma omp simd linear(,)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected expression}}
+  #pragma omp simd linear()
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected expression}}
+  #pragma omp simd linear(int)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected variable name}}
+  #pragma omp simd linear(0)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{use of undeclared identifier 'x'}}
+  #pragma omp simd linear(x)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+2 {{use of undeclared identifier 'x'}}
+  // expected-error@+1 {{use of undeclared identifier 'y'}}
+  #pragma omp simd linear(x, y)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+3 {{use of undeclared identifier 'x'}}
+  // expected-error@+2 {{use of undeclared identifier 'y'}}
+  // expected-error@+1 {{use of undeclared identifier 'z'}}
+  #pragma omp simd linear(x, y, z)
+  for (i = 0; i < 16; ++i) ;
+
+  int x, y;
+  // expected-error@+1 {{expected expression}}
+  #pragma omp simd linear(x:)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+  #pragma omp simd linear(x:,)
+  for (i = 0; i < 16; ++i) ;
+  #pragma omp simd linear(x:1)
+  for (i = 0; i < 16; ++i) ;
+  #pragma omp simd linear(x:2*2)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+  #pragma omp simd linear(x:1,y)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+  #pragma omp simd linear(x:1,y,z:1)
+  for (i = 0; i < 16; ++i) ;
+
+  // expected-note@+2 {{defined as linear}}
+  // expected-error@+1 {{linear variable cannot be linear}}
+  #pragma omp simd linear(x) linear(x)
+  for (i = 0; i < 16; ++i) ;
+
+  // expected-note@+2 {{defined as private}}
+  // expected-error@+1 {{private variable cannot be linear}}
+  #pragma omp simd private(x) linear(x)
+  for (i = 0; i < 16; ++i) ;
+
+  // expected-note@+2 {{defined as linear}}
+  // expected-error@+1 {{linear variable cannot be private}}
+  #pragma omp simd linear(x) private(x)
+  for (i = 0; i < 16; ++i) ;
+
+  // expected-warning@+1 {{zero linear step (x and other variables in clause should probably be const)}}
+  #pragma omp simd linear(x,y:0)
+  for (i = 0; i < 16; ++i) ;
+
+  // expected-note@+2 {{defined as linear}}
+  // expected-error@+1 {{linear variable cannot be lastprivate}}
+  #pragma omp simd linear(x) lastprivate(x)
+  for (i = 0; i < 16; ++i) ;
+
+  // expected-note@+2 {{defined as lastprivate}}
+  // expected-error@+1 {{lastprivate variable cannot be linear}}
+  #pragma omp simd lastprivate(x) linear(x) 
+  for (i = 0; i < 16; ++i) ;
+
+}
+
+void test_aligned()
+{
+  int i;
+  // expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+  #pragma omp simd aligned(
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+2 {{expected expression}}
+  // expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+  #pragma omp simd aligned(,
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+2 {{expected expression}}
+  // expected-error@+1 {{expected expression}}
+  #pragma omp simd aligned(,)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected expression}}
+  #pragma omp simd aligned()
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected expression}}
+  #pragma omp simd aligned(int)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected variable name}}
+  #pragma omp simd aligned(0)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{use of undeclared identifier 'x'}}
+  #pragma omp simd aligned(x)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+2 {{use of undeclared identifier 'x'}}
+  // expected-error@+1 {{use of undeclared identifier 'y'}}
+  #pragma omp simd aligned(x, y)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+3 {{use of undeclared identifier 'x'}}
+  // expected-error@+2 {{use of undeclared identifier 'y'}}
+  // expected-error@+1 {{use of undeclared identifier 'z'}}
+  #pragma omp simd aligned(x, y, z)
+  for (i = 0; i < 16; ++i) ;
+
+  int *x, y, z[25]; // expected-note 4 {{'y' defined here}}
+  #pragma omp simd aligned(x)
+  for (i = 0; i < 16; ++i) ;
+  #pragma omp simd aligned(z)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected expression}}
+  #pragma omp simd aligned(x:)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected expression}} expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+  #pragma omp simd aligned(x:,)
+  for (i = 0; i < 16; ++i) ;
+  #pragma omp simd aligned(x:1)
+  for (i = 0; i < 16; ++i) ;
+  #pragma omp simd aligned(x:2*2)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+  #pragma omp simd aligned(x:1,y)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+  #pragma omp simd aligned(x:1,y,z:1)
+  for (i = 0; i < 16; ++i) ;
+
+  // expected-error@+1 {{argument of aligned clause should be array or pointer, not 'int'}}
+  #pragma omp simd aligned(x, y)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{argument of aligned clause should be array or pointer, not 'int'}}
+  #pragma omp simd aligned(x, y, z)
+  for (i = 0; i < 16; ++i) ;
+
+  // expected-note@+2 {{defined as aligned}}
+  // expected-error@+1 {{a variable cannot appear in more than one aligned clause}}
+  #pragma omp simd aligned(x) aligned(z,x)
+  for (i = 0; i < 16; ++i) ;
+
+  // expected-note@+3 {{defined as aligned}}
+  // expected-error@+2 {{a variable cannot appear in more than one aligned clause}}
+  // expected-error@+1 2 {{argument of aligned clause should be array or pointer, not 'int'}}
+  #pragma omp simd aligned(x,y,z) aligned(y,z)
+  for (i = 0; i < 16; ++i) ;
+}
+
+void test_private()
+{
+  int i;
+  // expected-error@+2 {{expected expression}}
+  // expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+  #pragma omp 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 simd private(,
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 2 {{expected expression}}
+  #pragma omp simd private(,)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected expression}}
+  #pragma omp simd private()
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected expression}}
+  #pragma omp simd private(int)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected variable name}}
+  #pragma omp simd private(0)
+  for (i = 0; i < 16; ++i) ;
+
+  int x, y, z;
+  #pragma omp simd private(x)
+  for (i = 0; i < 16; ++i) ;
+  #pragma omp simd private(x, y)
+  for (i = 0; i < 16; ++i) ;
+  #pragma omp simd private(x, y, z)
+  for (i = 0; i < 16; ++i) {
+    x = y * i + z;
+  }
+}
+
+void test_firstprivate()
+{
+  int i;
+  // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}}
+  // expected-error@+2 {{unexpected OpenMP clause 'firstprivate' in directive '#pragma omp simd'}}
+  // expected-error@+1 {{expected expression}}
+  #pragma omp simd firstprivate(
+  for (i = 0; i < 16; ++i) ;
+}
+
+void test_lastprivate()
+{
+  int i;
+  // expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+  // expected-error@+1 {{expected expression}}
+  #pragma omp simd lastprivate(
+  for (i = 0; i < 16; ++i) ;
+
+  // expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+  // expected-error@+1 2 {{expected expression}}
+  #pragma omp simd lastprivate(,
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 2 {{expected expression}}
+  #pragma omp simd lastprivate(,)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected expression}}
+  #pragma omp simd lastprivate()
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected expression}}
+  #pragma omp simd lastprivate(int)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected variable name}}
+  #pragma omp simd lastprivate(0)
+  for (i = 0; i < 16; ++i) ;
+
+  int x, y, z;
+  #pragma omp simd lastprivate(x)
+  for (i = 0; i < 16; ++i) ;
+  #pragma omp simd lastprivate(x, y)
+  for (i = 0; i < 16; ++i) ;
+  #pragma omp simd lastprivate(x, y, z)
+  for (i = 0; i < 16; ++i) ;
+}
+
+void test_reduction()
+{
+  int i, x, y;
+  // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}}
+  // expected-error@+2 {{expected identifier}}
+  // expected-warning@+1 {{missing ':' after reduction identifier - ignoring}}
+  #pragma omp simd reduction(
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+2 {{expected identifier}}
+  // expected-warning@+1 {{missing ':' after reduction identifier - ignoring}}
+  #pragma omp simd reduction()
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+2 {{expected expression}}
+  // expected-warning@+1 {{missing ':' after reduction identifier - ignoring}}
+  #pragma omp simd reduction(x)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected identifier}}
+  #pragma omp simd reduction(:x)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}}
+  // expected-error@+2 {{expected identifier}}
+  // expected-warning@+1 {{missing ':' after reduction identifier - ignoring}}
+  #pragma omp simd reduction(,
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}}
+  // expected-error@+2 {{expected expression}}
+  // expected-warning@+1 {{missing ':' after reduction identifier - ignoring}}
+  #pragma omp simd reduction(+
+  for (i = 0; i < 16; ++i) ;
+
+  // expected-error@+3 {{expected ')'}} expected-note@+3 {{to match this '('}}
+  //
+  // expected-error@+1 {{expected expression}}
+  #pragma omp simd reduction(+:
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected expression}}
+  #pragma omp simd reduction(+:)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected expression}}
+  #pragma omp simd reduction(+:,y)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected expression}}
+  #pragma omp simd reduction(+:x,+:y)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+2 {{expected identifier}}
+  // expected-warning@+1 {{missing ':' after reduction identifier - ignoring}}
+  #pragma omp simd reduction(%:x)
+  for (i = 0; i < 16; ++i) ;
+
+  #pragma omp simd reduction(+:x)
+  for (i = 0; i < 16; ++i) ;
+  #pragma omp simd reduction(*:x)
+  for (i = 0; i < 16; ++i) ;
+  #pragma omp simd reduction(-:x)
+  for (i = 0; i < 16; ++i) ;
+  #pragma omp simd reduction(&:x)
+  for (i = 0; i < 16; ++i) ;
+  #pragma omp simd reduction(|:x)
+  for (i = 0; i < 16; ++i) ;
+  #pragma omp simd reduction(^:x)
+  for (i = 0; i < 16; ++i) ;
+  #pragma omp simd reduction(&&:x)
+  for (i = 0; i < 16; ++i) ;
+  #pragma omp simd reduction(||:x)
+  for (i = 0; i < 16; ++i) ;
+  #pragma omp simd reduction(max:x)
+  for (i = 0; i < 16; ++i) ;
+  #pragma omp simd reduction(min:x)
+  for (i = 0; i < 16; ++i) ;
+  struct X { int x; };
+  struct X X;
+  // expected-error@+1 {{expected variable name}}
+  #pragma omp simd reduction(+:X.x)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error@+1 {{expected variable name}}
+  #pragma omp simd reduction(+:x+x)
+  for (i = 0; i < 16; ++i) ;
+}
+
+void test_loop_messages()
+{
+  float a[100], b[100], c[100];
+  // expected-error@+2 {{variable must be of integer or pointer type}}
+  #pragma omp simd
+  for (float fi = 0; fi < 10.0; fi++) {
+    c[(int)fi] = a[(int)fi] + b[(int)fi];
+  }
+  // expected-error@+2 {{variable must be of integer or pointer type}}
+  #pragma omp simd
+  for (double fi = 0; fi < 10.0; fi++) {
+    c[(int)fi] = a[(int)fi] + b[(int)fi];
+  }
+}
+
diff --git a/test/OpenMP/simd_private_messages.cpp b/test/OpenMP/simd_private_messages.cpp
new file mode 100644
index 0000000..e5e4fe5
--- /dev/null
+++ b/test/OpenMP/simd_private_messages.cpp
@@ -0,0 +1,134 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+public:
+  S2():a(0) { }
+};
+const S2 b;
+const S2 ba[5];
+class S3 {
+  int a;
+public:
+  S3():a(0) { }
+};
+const S3 ca[5];
+class S4 { // expected-note {{'S4' declared here}}
+  int a;
+  S4();
+public:
+  S4(int v):a(v) { }
+};
+class S5 { // expected-note {{'S5' declared here}}
+  int a;
+  S5():a(0) {}
+public:
+  S5(int v):a(v) { }
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template<class I, class C> int foomain(I argc, C **argv) {
+  I e(4);
+  I g(5);
+  int i;
+  int &j = i; // expected-note {{'j' defined here}}
+  #pragma omp simd private // expected-error {{expected '(' after 'private'}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd private ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd private () // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd private (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp 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 simd private (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd private (argc)
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd private (S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd private (a, b) // expected-error {{private variable with incomplete type 'S1'}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd private (argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd private(e, g)
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd shared(i) // expected-error {{unexpected OpenMP clause 'shared' in directive '#pragma omp simd'}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp parallel
+  {
+    int v = 0;
+    int i;
+    #pragma omp simd private(i)
+    for (int k = 0; k < argc; ++k) { i = k; v += i; }
+  }
+  #pragma omp parallel shared(i)
+  #pragma omp parallel private(i)
+  #pragma omp simd private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd private(i)
+  for (int k = 0; k < argc; ++k) ++k;
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  S4 e(4); // expected-note {{'e' defined here}}
+  S5 g(5); // expected-note {{'g' defined here}}
+  int i;
+  int &j = i; // expected-note {{'j' defined here}}
+  #pragma omp simd private // expected-error {{expected '(' after 'private'}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd private ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd private () // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd private (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp 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 simd private (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd private (argc)
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd private (S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd private (a, b) // expected-error {{private variable with incomplete type 'S1'}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd private (argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd private(e, g) // expected-error 2 {{private variable must have an accessible, unambiguous default constructor}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd shared(i) // expected-error {{unexpected OpenMP clause 'shared' in directive '#pragma omp simd'}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp parallel
+  {
+    int i;
+    #pragma omp simd private(i)
+    for (int k = 0; k < argc; ++k) ++k;
+  }
+  #pragma omp parallel shared(i)
+  #pragma omp parallel private(i)
+  #pragma omp simd private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd private(i)
+  for (int k = 0; k < argc; ++k) ++k;
+
+  return 0;
+}
+
diff --git a/test/OpenMP/simd_reduction_messages.cpp b/test/OpenMP/simd_reduction_messages.cpp
new file mode 100644
index 0000000..347a5c1
--- /dev/null
+++ b/test/OpenMP/simd_reduction_messages.cpp
@@ -0,0 +1,298 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+  S2 &operator+=(const S2 &arg) { return (*this); }
+
+public:
+  S2() : a(0) {}
+  S2(S2 &s2) : a(s2.a) {}
+  static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
+  static const float S2sc;
+};
+const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+S2 b;                     // expected-note 2 {{'b' defined here}}
+const S2 ba[5];           // expected-note 2 {{'ba' defined here}}
+class S3 {
+  int a;
+
+public:
+  S3() : a(0) {}
+  S3(const S3 &s3) : a(s3.a) {}
+  S3 operator+=(const S3 &arg1) { return arg1; }
+};
+int operator+=(const S3 &arg1, const S3 &arg2) { return 5; }
+S3 c;               // expected-note 2 {{'c' defined here}}
+const S3 ca[5];     // expected-note 2 {{'ca' defined here}}
+extern const int f; // expected-note 4 {{'f' declared here}}
+class S4 {          // expected-note {{'S4' declared here}}
+  int a;
+  S4();
+  S4(const S4 &s4);
+  S4 &operator+=(const S4 &arg) { return (*this); }
+
+public:
+  S4(int v) : a(v) {}
+};
+S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; }
+class S5 {
+  int a;
+  S5() : a(0) {}
+  S5(const S5 &s5) : a(s5.a) {}
+  S5 &operator+=(const S5 &arg);
+
+public:
+  S5(int v) : a(v) {}
+};
+class S6 {
+  int a;
+
+public:
+  S6() : a(6) {}
+  operator int() { return 6; }
+} o; // expected-note 2 {{'o' defined here}}
+
+S3 h, k;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class T>       // expected-note {{declared here}}
+T tmain(T argc) {        // expected-note 2 {{'argc' defined here}}
+  const T d = T();       // expected-note 4 {{'d' defined here}}
+  const T da[5] = {T()}; // expected-note 2 {{'da' defined here}}
+  T qa[5] = {T()};
+  T i;
+  T &j = i;                        // expected-note 4 {{'j' defined here}}
+  S3 &p = k;                       // expected-note 2 {{'p' defined here}}
+  const T &r = da[(int)i];         // expected-note 2 {{'r' defined here}}
+  T &q = qa[(int)i];               // expected-note 2 {{'q' defined here}}
+  T fl;                            // expected-note {{'fl' defined here}}
+#pragma omp simd reduction // expected-error {{expected '(' after 'reduction'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp simd' are ignored}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(&& : argc)
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(^ : T) // expected-error {{'T' does not refer to a value}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(max : qa[1]) // expected-error 2 {{expected variable name}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd private(i), reduction(+ : j), reduction(+ : q) // expected-error 4 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(+ : j), reduction(+ : q) // OK
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel private(k)
+#pragma omp simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp simd reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel private(fl)
+#pragma omp simd reduction(+ : fl)
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel reduction(* : fl)
+#pragma omp simd reduction(+ : fl)
+  for (int i = 0; i < 10; ++i)
+    foo();
+
+  return T();
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;       // expected-note 2 {{'d' defined here}}
+  const int da[5] = {0}; // expected-note {{'da' defined here}}
+  int qa[5] = {0};
+  S4 e(4); // expected-note {{'e' defined here}}
+  S5 g(5); // expected-note {{'g' defined here}}
+  int i;
+  int &j = i;                      // expected-note 2 {{'j' defined here}}
+  S3 &p = k;                       // expected-note 2 {{'p' defined here}}
+  const int &r = da[i];            // expected-note {{'r' defined here}}
+  int &q = qa[i];                  // expected-note {{'q' defined here}}
+  float fl;                        // expected-note {{'fl' defined here}}
+#pragma omp simd reduction // expected-error {{expected '(' after 'reduction'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction + // expected-error {{expected '(' after 'reduction'}} expected-warning {{extra tokens at the end of '#pragma omp simd' are ignored}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected expression}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(foo : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(~ : argc) // expected-error {{expected unqualified-id}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(&& : argc)
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(max : argv[1]) // expected-error {{expected variable name}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(^ : fl) // expected-error {{variable of type 'float' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(& : e, g) // expected-error {{reduction variable must have an accessible, unambiguous default constructor}} expected-error {{variable of type 'S5' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(+ : o) // expected-error {{variable of type 'class S6' is not valid for specified reduction operation}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd private(i), reduction(+ : j), reduction(+ : q) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel private(k)
+#pragma omp simd reduction(+ : p), reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp simd reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp simd reduction(max : j) // expected-error {{argument of OpenMP clause 'reduction' must reference the same object in all threads}}
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel private(fl)
+#pragma omp simd reduction(+ : fl)
+  for (int i = 0; i < 10; ++i)
+    foo();
+#pragma omp parallel reduction(* : fl)
+#pragma omp simd reduction(+ : fl)
+  for (int i = 0; i < 10; ++i)
+    foo();
+
+  return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain<int>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<float>' requested here}}
+}
diff --git a/test/OpenMP/simd_safelen_messages.cpp b/test/OpenMP/simd_safelen_messages.cpp
new file mode 100644
index 0000000..0e7e80d
--- /dev/null
+++ b/test/OpenMP/simd_safelen_messages.cpp
@@ -0,0 +1,79 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, typename S, int N, int ST> // expected-note {{declared here}}
+T tmain(T argc, S **argv) { //expected-note 2 {{declared here}}
+  #pragma omp 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 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 simd safelen () // 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 simd safelen (argc 
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  // expected-error@+1 {{argument to 'safelen' clause must be a positive integer value}}
+  #pragma omp simd safelen (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 simd safelen (1)) // expected-warning {{extra tokens at the end of '#pragma omp simd' are ignored}}
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp simd safelen ((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 simd' cannot contain more than one 'safelen' clause}}
+  // expected-error@+2 2 {{argument to 'safelen' clause must be a positive integer value}}
+  // expected-error@+1 2 {{expression is not an integral constant expression}}
+  #pragma omp simd safelen (foobool(argc)), safelen (true), safelen (-5)
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp 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];
+  // expected-error@+1 2 {{expression is not an integral constant expression}}
+  #pragma omp 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 simd safelen (4)
+  for (int i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  #pragma omp simd safelen (N) // expected-error {{argument to 'safelen' clause must be a positive integer value}}
+  for (T i = ST; i < N; i++) argv[0][i] = argv[0][i] - argv[0][i-ST];
+  return argc;
+}
+
+int main(int argc, char **argv) {
+  #pragma omp 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 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 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 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 simd safelen (2+2)) // expected-warning {{extra tokens at the end of '#pragma omp simd' are ignored}}
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp simd 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];
+  // expected-error@+3 {{expression is not an integral constant expression}}
+  // expected-error@+2 2 {{directive '#pragma omp simd' cannot contain more than one 'safelen' clause}}
+  // expected-error@+1 2 {{argument to 'safelen' clause must be a positive integer value}}
+  #pragma omp simd safelen (foobool(argc)), safelen (true), safelen (-5) 
+  for (int i = 4; i < 12; i++) argv[0][i] = argv[0][i] - argv[0][i-4];
+  #pragma omp 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];
+  // expected-error@+1 {{expression is not an integral constant expression}}
+  #pragma omp 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-error@+3 {{statement after '#pragma omp simd' must be a for loop}}
+  // expected-note@+1 {{in instantiation of function template specialization 'tmain<int, char, -1, -2>' requested here}}
+  #pragma omp simd safelen(safelen(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, 12, 4>' requested here}}
+  return tmain<int, char, 12, 4>(argc, argv);
+}
+
diff --git a/test/OpenMP/single_ast_print.cpp b/test/OpenMP/single_ast_print.cpp
new file mode 100644
index 0000000..65a007e
--- /dev/null
+++ b/test/OpenMP/single_ast_print.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+void foo() {}
+
+template <class T, int N>
+T tmain(T argc) {
+  T b = argc, c, d, e, f, g;
+  static T a;
+// CHECK: static T a;
+#pragma omp parallel private(g)
+#pragma omp single private(argc, b), firstprivate(c, d), nowait copyprivate(g)
+  foo();
+  // CHECK-NEXT: #pragma omp parallel private(g)
+  // CHECK-NEXT: #pragma omp single private(argc,b) firstprivate(c,d) nowait copyprivate(g)
+  // CHECK-NEXT: foo();
+  return T();
+}
+
+int main(int argc, char **argv) {
+  int b = argc, c, d, e, f, g;
+  static int a;
+// CHECK: static int a;
+#pragma omp parallel private(g)
+#pragma omp single private(argc, b), firstprivate(argv, c), nowait copyprivate(g)
+  foo();
+  // CHECK-NEXT: #pragma omp parallel private(g)
+  // CHECK-NEXT: #pragma omp single private(argc,b) firstprivate(argv,c) nowait copyprivate(g)
+  // CHECK-NEXT: foo();
+  return (tmain<int, 5>(argc) + tmain<char, 1>(argv[0][0]));
+}
+
+#endif
diff --git a/test/OpenMP/single_copyprivate_messages.cpp b/test/OpenMP/single_copyprivate_messages.cpp
new file mode 100644
index 0000000..f07ab12
--- /dev/null
+++ b/test/OpenMP/single_copyprivate_messages.cpp
@@ -0,0 +1,157 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+struct S1; // expected-note 2 {{declared here}}
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+  S2 &operator=(S2 &s2) { return *this; }
+};
+class S3 {
+  int a;
+
+public:
+  S3() : a(0) {}
+  S3 &operator=(S3 &s3) { return *this; }
+};
+class S4 { // expected-note 2 {{'S4' declared here}}
+  int a;
+  S4();
+  S4 &operator=(const S4 &s4);
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note 2 {{'S5' declared here}}
+  int a;
+  S5() : a(0) {}
+  S5 &operator=(const S5 &s5) { return *this; }
+
+public:
+  S5(int v) : a(v) {}
+};
+
+S2 k;
+S3 h;
+S4 l(3); // expected-note 2 {{'l' defined here}}
+S5 m(4); // expected-note 2 {{'m' defined here}}
+#pragma omp threadprivate(h, k, l, m)
+
+template <class T, class C>
+T tmain(T argc, C **argv) {
+  T i;
+#pragma omp parallel
+#pragma omp single copyprivate // expected-error {{expected '(' after 'copyprivate'}}
+#pragma omp parallel
+#pragma omp single copyprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp parallel
+#pragma omp single copyprivate() // expected-error {{expected expression}}
+#pragma omp parallel
+#pragma omp single copyprivate(k // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp parallel
+#pragma omp single copyprivate(h, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp parallel
+#pragma omp single copyprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+#pragma omp parallel
+#pragma omp single copyprivate(l) // expected-error {{copyprivate variable must have an accessible, unambiguous copy assignment operator}}
+#pragma omp parallel
+#pragma omp single copyprivate(S1) // expected-error {{'S1' does not refer to a value}}
+#pragma omp parallel
+#pragma omp single copyprivate(argv[1]) // expected-error {{expected variable name}}
+#pragma omp parallel // expected-note {{implicitly determined as shared}}
+#pragma omp single copyprivate(i) // expected-error {{copyprivate variable must be threadprivate or private in the enclosing context}}
+#pragma omp parallel
+#pragma omp single copyprivate(m) // expected-error {{copyprivate variable must have an accessible, unambiguous copy assignment operator}}
+  foo();
+#pragma omp parallel private(i)
+  {
+#pragma omp single copyprivate(i)
+    foo();
+  }
+#pragma omp parallel shared(i) // expected-note {{defined as shared}}
+  {
+#pragma omp single copyprivate(i) // expected-error {{copyprivate variable must be threadprivate or private in the enclosing context}}
+    foo();
+  }
+#pragma omp parallel private(i)
+#pragma omp parallel default(shared) // expected-note {{implicitly determined as shared}}
+  {
+#pragma omp single copyprivate(i) // expected-error {{copyprivate variable must be threadprivate or private in the enclosing context}}
+    foo();
+  }
+#pragma omp parallel private(i)
+#pragma omp parallel // expected-note {{implicitly determined as shared}}
+  {
+#pragma omp single copyprivate(i) // expected-error {{copyprivate variable must be threadprivate or private in the enclosing context}}
+    foo();
+  }
+#pragma omp parallel
+#pragma omp single private(i) copyprivate(i) // expected-error {{private variable cannot be copyprivate}} expected-note {{defined as private}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(i) copyprivate(i) // expected-error {{firstprivate variable cannot be copyprivate}} expected-note {{defined as firstprivate}}
+  foo();
+
+  return T();
+}
+
+int main(int argc, char **argv) {
+  int i;
+#pragma omp parallel
+#pragma omp single copyprivate // expected-error {{expected '(' after 'copyprivate'}}
+#pragma omp parallel
+#pragma omp single copyprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp parallel
+#pragma omp single copyprivate() // expected-error {{expected expression}}
+#pragma omp parallel
+#pragma omp single copyprivate(k // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp parallel
+#pragma omp single copyprivate(h, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp parallel
+#pragma omp single copyprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+#pragma omp parallel
+#pragma omp single copyprivate(l) // expected-error {{copyprivate variable must have an accessible, unambiguous copy assignment operator}}
+#pragma omp parallel
+#pragma omp single copyprivate(S1) // expected-error {{'S1' does not refer to a value}}
+#pragma omp parallel
+#pragma omp single copyprivate(argv[1]) // expected-error {{expected variable name}}
+#pragma omp parallel // expected-note {{implicitly determined as shared}}
+#pragma omp single copyprivate(i) // expected-error {{copyprivate variable must be threadprivate or private in the enclosing context}}
+#pragma omp parallel
+#pragma omp single copyprivate(m) // expected-error {{copyprivate variable must have an accessible, unambiguous copy assignment operator}}
+  foo();
+#pragma omp parallel private(i)
+  {
+#pragma omp single copyprivate(i)
+    foo();
+  }
+#pragma omp parallel shared(i) // expected-note {{defined as shared}}
+  {
+#pragma omp single copyprivate(i) // expected-error {{copyprivate variable must be threadprivate or private in the enclosing context}}
+    foo();
+  }
+#pragma omp parallel private(i)
+#pragma omp parallel default(shared) // expected-note {{implicitly determined as shared}}
+  {
+#pragma omp single copyprivate(i) // expected-error {{copyprivate variable must be threadprivate or private in the enclosing context}}
+    foo();
+  }
+#pragma omp parallel private(i)
+#pragma omp parallel // expected-note {{implicitly determined as shared}}
+  {
+#pragma omp single copyprivate(i) // expected-error {{copyprivate variable must be threadprivate or private in the enclosing context}}
+    foo();
+  }
+#pragma omp parallel
+#pragma omp single private(i) copyprivate(i) // expected-error {{private variable cannot be copyprivate}} expected-note {{defined as private}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(i) copyprivate(i) // expected-error {{firstprivate variable cannot be copyprivate}} expected-note {{defined as firstprivate}}
+  foo();
+
+  return tmain(argc, argv); // expected-note {{in instantiation of function template specialization 'tmain<int, char>' requested here}}
+}
diff --git a/test/OpenMP/single_firstprivate_messages.cpp b/test/OpenMP/single_firstprivate_messages.cpp
new file mode 100644
index 0000000..6d49882
--- /dev/null
+++ b/test/OpenMP/single_firstprivate_messages.cpp
@@ -0,0 +1,239 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+  S2(S2 &s2) : a(s2.a) {}
+  static float S2s;
+  static const float S2sc;
+};
+const float S2::S2sc = 0;
+const S2 b;
+const S2 ba[5];
+class S3 {
+  int a;
+  S3 &operator=(const S3 &s3);
+
+public:
+  S3() : a(0) {}
+  S3(S3 &s3) : a(s3.a) {}
+};
+const S3 c;
+const S3 ca[5];
+extern const int f;
+class S4 { // expected-note 2 {{'S4' declared here}}
+  int a;
+  S4();
+  S4(const S4 &s4);
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note 4 {{'S5' declared here}}
+  int a;
+  S5(const S5 &s5) : a(s5.a) {}
+
+public:
+  S5() : a(0) {}
+  S5(int v) : a(v) {}
+};
+class S6 {
+  int a;
+  S6() : a(0) {}
+
+public:
+  S6(const S6 &s6) : a(s6.a) {}
+  S6(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(int argc, char **argv) {
+  I e(4); // expected-note {{'e' defined here}}
+  C g(5); // expected-note 2 {{'g' defined here}}
+  int i;
+  int &j = i; // expected-note {{'j' defined here}}
+#pragma omp parallel
+#pragma omp single firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate() // expected-error {{expected expression}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(argc)
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(a, b) // expected-error {{firstprivate variable with incomplete type 'S1'}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(argv[1]) // expected-error {{expected variable name}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
+  foo();
+#pragma omp parallel
+#pragma omp single linear(i) // expected-error {{unexpected OpenMP clause 'linear' in directive '#pragma omp single'}}
+  foo();
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;                         // expected-note {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp single' directive into a parallel or another task region?}}
+#pragma omp single firstprivate(i) // expected-error {{private variable cannot be firstprivate}}
+    foo();
+    v += i;
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp single firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(i)
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  foo();
+#pragma omp parallel private(i)    // expected-note {{defined as private}}
+#pragma omp single firstprivate(i) // expected-error {{firstprivate variable must be shared}}
+  foo();
+#pragma omp parallel reduction(+ : i) // expected-note {{defined as reduction}}
+#pragma omp single firstprivate(i)    // expected-error {{firstprivate variable must be shared}}
+  foo();
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  const int d = 5;
+  const int da[5] = {0};
+  S4 e(4); // expected-note {{'e' defined here}}
+  S5 g(5); // expected-note 2 {{'g' defined here}}
+  S3 m;
+  S6 n(2);
+  int i;
+  int &j = i; // expected-note {{'j' defined here}}
+#pragma omp parallel
+#pragma omp single firstprivate // expected-error {{expected '(' after 'firstprivate'}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate() // expected-error {{expected expression}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(argc)
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(S1) // expected-error {{'S1' does not refer to a value}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(argv[1]) // expected-error {{expected variable name}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(2 * 2) // expected-error {{expected variable name}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(ba) // OK
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(ca) // OK
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(da) // OK
+  foo();
+  int xa;
+#pragma omp parallel
+#pragma omp single firstprivate(xa) // OK
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(S2::S2s) // OK
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(S2::S2sc) // OK
+  foo();
+#pragma omp parallel
+#pragma omp single safelen(5) // expected-error {{unexpected OpenMP clause 'safelen' in directive '#pragma omp single'}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(e, g) // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(m) // OK
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(h) // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
+  foo();
+#pragma omp parallel
+#pragma omp single private(xa), firstprivate(xa) // expected-error {{private variable cannot be firstprivate}} expected-note {{defined as private}}
+  foo();
+#pragma omp parallel shared(xa)
+#pragma omp single firstprivate(xa) // OK: may be firstprivate
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(g) // expected-error {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+  foo();
+#pragma omp parallel
+#pragma omp single firstprivate(n) // OK
+  foo();
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;                         // expected-note {{variable with automatic storage duration is predetermined as private; perhaps you forget to enclose 'omp single' directive into a parallel or another task region?}}
+#pragma omp single firstprivate(i) // expected-error {{private variable cannot be firstprivate}}
+    foo();
+    v += i;
+  }
+#pragma omp parallel private(i)    // expected-note {{defined as private}}
+#pragma omp single firstprivate(i) // expected-error {{firstprivate variable must be shared}}
+  foo();
+#pragma omp parallel reduction(+ : i) // expected-note {{defined as reduction}}
+#pragma omp single firstprivate(i)    // expected-error {{firstprivate variable must be shared}}
+  foo();
+
+  return foomain<S4, S5>(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<S4, S5>' requested here}}
+}
diff --git a/test/OpenMP/single_misc_messages.c b/test/OpenMP/single_misc_messages.c
new file mode 100644
index 0000000..7c10ca0
--- /dev/null
+++ b/test/OpenMP/single_misc_messages.c
@@ -0,0 +1,156 @@
+// RUN: %clang_cc1 -fsyntax-only -fopenmp=libiomp5 -verify %s
+
+void foo();
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp single'}}
+#pragma omp single
+
+// expected-error@+1 {{unexpected OpenMP directive '#pragma omp single'}}
+#pragma omp single foo
+
+void test_no_clause() {
+  int i;
+#pragma omp single
+  foo();
+
+#pragma omp single
+  ++i;
+}
+
+void test_branch_protected_scope() {
+  int i = 0;
+L1:
+  ++i;
+
+  int x[24];
+
+#pragma omp parallel
+#pragma omp single
+  {
+    if (i == 5)
+      goto L1; // expected-error {{use of undeclared label 'L1'}}
+    else if (i == 6)
+      return; // expected-error {{cannot return from OpenMP region}}
+    else if (i == 7)
+      goto L2;
+    else if (i == 8) {
+    L2:
+      x[i]++;
+    }
+  }
+
+  if (x[0] == 0)
+    goto L2; // expected-error {{use of undeclared label 'L2'}}
+  else if (x[1] == 1)
+    goto L1;
+}
+
+void test_invalid_clause() {
+  int i;
+#pragma omp parallel
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp single' are ignored}}
+#pragma omp single foo bar
+  foo();
+}
+
+void test_non_identifiers() {
+  int i, x;
+
+#pragma omp parallel
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp single' are ignored}}
+#pragma omp single;
+  foo();
+#pragma omp parallel
+// expected-error@+2 {{unexpected OpenMP clause 'linear' in directive '#pragma omp single'}}
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp single' are ignored}}
+#pragma omp single linear(x);
+  foo();
+
+#pragma omp parallel
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp single' are ignored}}
+#pragma omp single private(x);
+  foo();
+
+#pragma omp parallel
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp single' are ignored}}
+#pragma omp single, private(x);
+  foo();
+}
+
+void test_private() {
+  int i;
+#pragma omp parallel
+// expected-error@+2 {{expected expression}}
+// expected-error@+1 {{expected ')'}} expected-note@+1 {{to match this '('}}
+#pragma omp single private(
+  foo();
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp single private(,
+  foo();
+#pragma omp parallel
+// expected-error@+1 2 {{expected expression}}
+#pragma omp single private(, )
+  foo();
+#pragma omp parallel
+// expected-error@+1 {{expected expression}}
+#pragma omp single private()
+  foo();
+#pragma omp parallel
+// expected-error@+1 {{expected expression}}
+#pragma omp single private(int)
+  foo();
+#pragma omp parallel
+// expected-error@+1 {{expected variable name}}
+#pragma omp single private(0)
+  foo();
+
+  int x, y, z;
+#pragma omp parallel
+#pragma omp single private(x)
+  foo();
+#pragma omp parallel
+#pragma omp single private(x, y)
+  foo();
+#pragma omp parallel
+#pragma omp single private(x, y, z)
+  foo();
+}
+
+void test_firstprivate() {
+  int i;
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 {{expected expression}}
+#pragma omp single firstprivate(
+  foo();
+
+#pragma omp parallel
+// expected-error@+2 {{expected ')'}} expected-note@+2 {{to match this '('}}
+// expected-error@+1 2 {{expected expression}}
+#pragma omp single firstprivate(,
+  foo();
+#pragma omp parallel
+// expected-error@+1 2 {{expected expression}}
+#pragma omp single firstprivate(, )
+  foo();
+#pragma omp parallel
+// expected-error@+1 {{expected expression}}
+#pragma omp single firstprivate()
+  foo();
+#pragma omp parallel
+// expected-error@+1 {{expected expression}}
+#pragma omp single firstprivate(int)
+  foo();
+#pragma omp parallel
+// expected-error@+1 {{expected variable name}}
+#pragma omp single firstprivate(0)
+  foo();
+}
+
+void test_nowait() {
+#pragma omp single nowait nowait // expected-error {{directive '#pragma omp single' cannot contain more than one 'nowait' clause}}
+  for (int i = 0; i < 16; ++i)
+    ;
+}
diff --git a/test/OpenMP/single_private_messages.cpp b/test/OpenMP/single_private_messages.cpp
new file mode 100644
index 0000000..1414a92
--- /dev/null
+++ b/test/OpenMP/single_private_messages.cpp
@@ -0,0 +1,140 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note 2 {{declared here}} expected-note 2 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+};
+const S2 b;
+const S2 ba[5];
+class S3 {
+  int a;
+
+public:
+  S3() : a(0) {}
+};
+const S3 ca[5];
+class S4 { // expected-note {{'S4' declared here}}
+  int a;
+  S4();
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note {{'S5' declared here}}
+  int a;
+  S5() : a(0) {}
+
+public:
+  S5(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class I, class C>
+int foomain(I argc, C **argv) {
+  I e(4);
+  I g(5);
+  int i;
+  int &j = i;                // expected-note {{'j' defined here}}
+#pragma omp single private // expected-error {{expected '(' after 'private'}}
+  foo();
+#pragma omp single private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp single private() // expected-error {{expected expression}}
+  foo();
+#pragma omp single private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp single private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp single private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  foo();
+#pragma omp single private(argc)
+  foo();
+#pragma omp single private(S1) // expected-error {{'S1' does not refer to a value}}
+  foo();
+#pragma omp single private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
+  foo();
+#pragma omp single private(argv[1]) // expected-error {{expected variable name}}
+  foo();
+#pragma omp single private(e, g)
+  foo();
+#pragma omp single private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
+  foo();
+#pragma omp single shared(i) // expected-error {{unexpected OpenMP clause 'shared' in directive '#pragma omp single'}}
+  foo();
+#pragma omp parallel
+  {
+    int v = 0;
+    int i;
+#pragma omp single private(i)
+    foo();
+    v += i;
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp single private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}}
+  foo();
+#pragma omp single private(i)
+  foo();
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  S4 e(4); // expected-note {{'e' defined here}}
+  S5 g(5); // expected-note {{'g' defined here}}
+  int i;
+  int &j = i;                // expected-note {{'j' defined here}}
+#pragma omp single private // expected-error {{expected '(' after 'private'}}
+  foo();
+#pragma omp single private( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp single private() // expected-error {{expected expression}}
+  foo();
+#pragma omp single private(argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp single private(argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp single private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  foo();
+#pragma omp single private(argc)
+  foo();
+#pragma omp single private(S1) // expected-error {{'S1' does not refer to a value}}
+  foo();
+#pragma omp single private(a, b) // expected-error {{private variable with incomplete type 'S1'}}
+  foo();
+#pragma omp single private(argv[1]) // expected-error {{expected variable name}}
+  foo();
+#pragma omp single private(e, g) // expected-error 2 {{private variable must have an accessible, unambiguous default constructor}}
+  foo();
+#pragma omp single private(h) // expected-error {{threadprivate or thread local variable cannot be private}}
+  foo();
+#pragma omp single shared(i) // expected-error {{unexpected OpenMP clause 'shared' in directive '#pragma omp single'}}
+  foo();
+#pragma omp parallel
+  {
+    int i;
+#pragma omp single private(i)
+    foo();
+  }
+#pragma omp parallel shared(i)
+#pragma omp parallel private(i)
+#pragma omp single private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type}}
+  foo();
+#pragma omp single private(i)
+  foo();
+
+  return 0;
+}
+
diff --git a/test/OpenMP/task_ast_print.cpp b/test/OpenMP/task_ast_print.cpp
new file mode 100644
index 0000000..2b43c0b
--- /dev/null
+++ b/test/OpenMP/task_ast_print.cpp
@@ -0,0 +1,96 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+void foo() {}
+
+template <class T>
+struct S {
+  operator T() { return T(); }
+  static T TS;
+#pragma omp threadprivate(TS)
+};
+
+// CHECK:      template <class T = int> struct S {
+// CHECK:        static int TS;
+// CHECK-NEXT:   #pragma omp threadprivate(S<int>::TS)
+// CHECK-NEXT: }
+// CHECK:      template <class T = long> struct S {
+// CHECK:        static long TS;
+// CHECK-NEXT:   #pragma omp threadprivate(S<long>::TS)
+// CHECK-NEXT: }
+// CHECK:      template <class T> struct S {
+// CHECK:        static T TS;
+// CHECK-NEXT:   #pragma omp threadprivate(S::TS)
+// CHECK:      };
+
+template <typename T, int C>
+T tmain(T argc, T *argv) {
+  T b = argc, c, d, e, f, g;
+  static T a;
+  S<T> s;
+#pragma omp task untied
+  a = 2;
+#pragma omp task default(none), private(argc, b) firstprivate(argv) shared(d) if (argc > 0) final(S<T>::TS > 0)
+  foo();
+#pragma omp task if (C) mergeable
+  foo();
+  return 0;
+}
+
+// CHECK: template <typename T = int, int C = 5> int tmain(int argc, int *argv) {
+// CHECK-NEXT: int b = argc, c, d, e, f, g;
+// CHECK-NEXT: static int a;
+// CHECK-NEXT: S<int> s;
+// CHECK-NEXT: #pragma omp task untied
+// CHECK-NEXT: a = 2;
+// CHECK-NEXT: #pragma omp task default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) final(S<int>::TS > 0)
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp task if(5) mergeable
+// CHECK-NEXT: foo()
+// CHECK: template <typename T = long, int C = 1> long tmain(long argc, long *argv) {
+// CHECK-NEXT: long b = argc, c, d, e, f, g;
+// CHECK-NEXT: static long a;
+// CHECK-NEXT: S<long> s;
+// CHECK-NEXT: #pragma omp task untied
+// CHECK-NEXT: a = 2;
+// CHECK-NEXT: #pragma omp task default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) final(S<long>::TS > 0)
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp task if(1) mergeable
+// CHECK-NEXT: foo()
+// CHECK: template <typename T, int C> T tmain(T argc, T *argv) {
+// CHECK-NEXT: T b = argc, c, d, e, f, g;
+// CHECK-NEXT: static T a;
+// CHECK-NEXT: S<T> s;
+// CHECK-NEXT: #pragma omp task untied
+// CHECK-NEXT: a = 2;
+// CHECK-NEXT: #pragma omp task default(none) private(argc,b) firstprivate(argv) shared(d) if(argc > 0) final(S<T>::TS > 0)
+// CHECK-NEXT: foo()
+// CHECK-NEXT: #pragma omp task if(C) mergeable
+// 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 task untied mergeable
+  // CHECK-NEXT: #pragma omp task untied mergeable
+  a = 2;
+// CHECK-NEXT: a = 2;
+#pragma omp task default(none), private(argc, b) firstprivate(argv) if (argc > 0) final(a > 0)
+  // CHECK-NEXT: #pragma omp task default(none) private(argc,b) firstprivate(argv) if(argc > 0) final(a > 0)
+  foo();
+  // CHECK-NEXT: foo();
+  return tmain<int, 5>(b, &b) + tmain<long, 1>(x, &x);
+}
+
+#endif
diff --git a/test/OpenMP/task_default_messages.cpp b/test/OpenMP/task_default_messages.cpp
new file mode 100644
index 0000000..8da6b1a
--- /dev/null
+++ b/test/OpenMP/task_default_messages.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -o - %s
+
+void foo();
+
+int main(int argc, char **argv) {
+#pragma omp task default                          // expected-error {{expected '(' after 'default'}}
+#pragma omp task default(                         // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp task default()                        // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
+#pragma omp task default(none                     // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp task default(shared), default(shared) // expected-error {{directive '#pragma omp task' cannot contain more than one 'default' clause}}
+#pragma omp task default(x)                       // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}}
+  foo();
+
+#pragma omp task default(none)
+  ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
+
+#pragma omp task default(none)
+#pragma omp task default(shared)
+  ++argc;
+  return 0;
+}
diff --git a/test/OpenMP/task_final_messages.cpp b/test/OpenMP/task_final_messages.cpp
new file mode 100644
index 0000000..0b52e6a
--- /dev/null
+++ b/test/OpenMP/task_final_messages.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, class S> // expected-note {{declared here}}
+int tmain(T argc, S **argv) {
+  #pragma omp task final // expected-error {{expected '(' after 'final'}}
+  #pragma omp task final ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp task final () // expected-error {{expected expression}}
+  #pragma omp task final (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp task final (argc)) // expected-warning {{extra tokens at the end of '#pragma omp task' are ignored}}
+  #pragma omp task final (argc > 0 ? argv[1] : argv[2])
+  #pragma omp task final (foobool(argc)), final (true) // expected-error {{directive '#pragma omp task' cannot contain more than one 'final' clause}}
+  #pragma omp task final (S) // expected-error {{'S' does not refer to a value}}
+  #pragma omp task final (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp task final (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp task final(argc)
+  foo();
+
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  #pragma omp task final // expected-error {{expected '(' after 'final'}}
+  #pragma omp task final ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp task final () // expected-error {{expected expression}}
+  #pragma omp task final (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp task final (argc)) // expected-warning {{extra tokens at the end of '#pragma omp task' are ignored}}
+  #pragma omp task final (argc > 0 ? argv[1] : argv[2])
+  #pragma omp task final (foobool(argc)), final (true) // expected-error {{directive '#pragma omp task' cannot contain more than one 'final' clause}}
+  #pragma omp task final (S1) // expected-error {{'S1' does not refer to a value}}
+  #pragma omp task final (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp task final (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp task final (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp task final(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+
+  return tmain(argc, argv);
+}
diff --git a/test/OpenMP/task_firstprivate_messages.cpp b/test/OpenMP/task_firstprivate_messages.cpp
new file mode 100644
index 0000000..85d3f9f
--- /dev/null
+++ b/test/OpenMP/task_firstprivate_messages.cpp
@@ -0,0 +1,86 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 %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(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 { // expected-note {{'S4' declared here}}
+  int a;
+  S4();
+  S4(const S4 &s4);
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note {{'S5' declared here}}
+  int a;
+  S5() : a(0) {}
+  S5(const S5 &s5) : a(s5.a) {}
+
+public:
+  S5(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note {{defined as threadprivate or thread local}}
+
+int main(int argc, char **argv) {
+  const int d = 5;
+  const int da[5] = {0};
+  S4 e(4); // expected-note {{'e' defined here}}
+  S5 g(5); // expected-note {{'g' defined here}}
+  int i;
+  int &j = i;                                               // expected-note {{'j' defined here}}
+#pragma omp task firstprivate                               // expected-error {{expected '(' after 'firstprivate'}}
+#pragma omp task firstprivate(                              // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp task firstprivate()                             // expected-error {{expected expression}}
+#pragma omp task firstprivate(argc                          // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp task firstprivate(argc,                         // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp task firstprivate(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+#pragma omp task firstprivate(argc)
+#pragma omp task firstprivate(S1)            // expected-error {{'S1' does not refer to a value}}
+#pragma omp task firstprivate(a, b, c, d, f) // expected-error {{firstprivate variable with incomplete type 'S1'}}
+#pragma omp task firstprivate(argv[1])       // expected-error {{expected variable name}}
+#pragma omp task firstprivate(ba)
+#pragma omp task firstprivate(ca)
+#pragma omp task firstprivate(da)
+#pragma omp task firstprivate(S2::S2s)
+#pragma omp task firstprivate(S2::S2sc)
+#pragma omp task firstprivate(e, g)          // expected-error 2 {{firstprivate variable must have an accessible, unambiguous copy constructor}}
+#pragma omp task firstprivate(h)             // expected-error {{threadprivate or thread local variable cannot be firstprivate}}
+#pragma omp task private(i), firstprivate(i) // expected-error {{private variable cannot be firstprivate}} expected-note{{defined as private}}
+  foo();
+#pragma omp task shared(i)
+#pragma omp task firstprivate(i)
+#pragma omp task firstprivate(j) // expected-error {{arguments of OpenMP clause 'firstprivate' cannot be of reference type}}
+  foo();
+
+  return 0;
+}
diff --git a/test/OpenMP/task_if_messages.cpp b/test/OpenMP/task_if_messages.cpp
new file mode 100644
index 0000000..51900c0
--- /dev/null
+++ b/test/OpenMP/task_if_messages.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+
+template <class T, class S> // expected-note {{declared here}}
+int tmain(T argc, S **argv) {
+  #pragma omp task if // expected-error {{expected '(' after 'if'}}
+  #pragma omp task if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp task if () // expected-error {{expected expression}}
+  #pragma omp task if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp task if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp task' are ignored}}
+  #pragma omp task if (argc > 0 ? argv[1] : argv[2])
+  #pragma omp task if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp task' cannot contain more than one 'if' clause}}
+  #pragma omp task if (S) // expected-error {{'S' does not refer to a value}}
+  #pragma omp task if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp task if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp task if(argc)
+  foo();
+
+  return 0;
+}
+
+int main(int argc, char **argv) {
+  #pragma omp task if // expected-error {{expected '(' after 'if'}}
+  #pragma omp task if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp task if () // expected-error {{expected expression}}
+  #pragma omp task if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp task if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp task' are ignored}}
+  #pragma omp task if (argc > 0 ? argv[1] : argv[2])
+  #pragma omp task if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp task' cannot contain more than one 'if' clause}}
+  #pragma omp task if (S1) // expected-error {{'S1' does not refer to a value}}
+  #pragma omp task if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp task if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp task if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  #pragma omp task if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+
+  return tmain(argc, argv);
+}
diff --git a/test/OpenMP/task_messages.cpp b/test/OpenMP/task_messages.cpp
new file mode 100644
index 0000000..88c339a
--- /dev/null
+++ b/test/OpenMP/task_messages.cpp
@@ -0,0 +1,275 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -std=c++11 -o - %s
+
+void foo() {
+}
+
+#pragma omp task // expected-error {{unexpected OpenMP directive '#pragma omp task'}}
+
+class S { // expected-note 6 {{'S' declared here}}
+  S(const S &s) { a = s.a + 12; }
+  int a;
+
+public:
+  S() : a(0) {}
+  S(int a) : a(a) {}
+  operator int() { return a; }
+  S &operator++() { return *this; }
+  S operator+(const S &) { return *this; }
+};
+
+template <class T>
+int foo() {
+  T a; // expected-note 3 {{'a' defined here}}
+  T &b = a; // expected-note 4 {{'b' defined here}}
+  int r;
+#pragma omp task default(none)
+#pragma omp task default(shared)
+  ++a;
+// expected-error@+2 {{predetermined as a firstprivate in a task construct variable must have an accessible, unambiguous copy constructor}}
+#pragma omp task default(none)
+#pragma omp task
+// expected-note@+1 {{used here}}
+  ++a;
+#pragma omp task
+// expected-error@+1 {{predetermined as a firstprivate in a task construct variable must have an accessible, unambiguous copy constructor}}
+#pragma omp task
+  // expected-note@+1 {{used here}}
+  ++a;
+#pragma omp task default(shared)
+#pragma omp task
+  ++a;
+#pragma omp task
+#pragma omp parallel
+  ++a;
+// expected-error@+2 {{predetermined as a firstprivate in a task construct variable cannot be of reference type 'int &'}}
+// expected-error@+1 {{predetermined as a firstprivate in a task construct variable cannot be of reference type 'S &'}}
+#pragma omp task
+  // expected-note@+1 2 {{used here}}
+  ++b;
+// expected-error@+3 {{predetermined as a firstprivate in a task construct variable cannot be of reference type 'int &'}}
+// expected-error@+2 {{predetermined as a firstprivate in a task construct variable cannot be of reference type 'S &'}}
+// expected-error@+1 {{predetermined as a firstprivate in a task construct variable must have an accessible, unambiguous copy constructor}}
+#pragma omp task
+// expected-note@+1 3 {{used here}}
+#pragma omp parallel shared(a, b)
+  ++a, ++b;
+// expected-note@+1 3 {{defined as reduction}}
+#pragma omp parallel reduction(+ : r)
+// expected-error@+1 {{argument of a reduction clause of a parallel construct must not appear in a firstprivate clause on a task construct}}
+#pragma omp task firstprivate(r)
+  // expected-error@+1 2 {{reduction variables may not be accessed in an explicit task}}
+  ++r;
+// expected-note@+1 2 {{defined as reduction}}
+#pragma omp parallel reduction(+ : r)
+#pragma omp task default(shared)
+  // expected-error@+1 2 {{reduction variables may not be accessed in an explicit task}}
+  ++r;
+// expected-note@+1 2 {{defined as reduction}}
+#pragma omp parallel reduction(+ : r)
+#pragma omp task
+  // expected-error@+1 2 {{reduction variables may not be accessed in an explicit task}}
+  ++r;
+#pragma omp parallel
+// expected-note@+1 3 {{defined as reduction}}
+#pragma omp for reduction(+ : r)
+  for (int i = 0; i < 10; ++i)
+// expected-error@+1 {{argument of a reduction clause of a for construct must not appear in a firstprivate clause on a task construct}}
+#pragma omp task firstprivate(r)
+    // expected-error@+1 2 {{reduction variables may not be accessed in an explicit task}}
+    ++r;
+#pragma omp parallel
+// expected-note@+1 2 {{defined as reduction}}
+#pragma omp for reduction(+ : r)
+  for (int i = 0; i < 10; ++i)
+#pragma omp task default(shared)
+    // expected-error@+1 2 {{reduction variables may not be accessed in an explicit task}}
+    ++r;
+#pragma omp parallel
+// expected-note@+1 2 {{defined as reduction}}
+#pragma omp for reduction(+ : r)
+  for (int i = 0; i < 10; ++i)
+#pragma omp task
+    // expected-error@+1 2 {{reduction variables may not be accessed in an explicit task}}
+    ++r;
+// expected-note@+1 {{non-shared variable in a task construct is predetermined as firstprivate}}
+#pragma omp task
+// expected-error@+2 {{reduction variable must be shared}}
+// expected-error@+1 {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+#pragma omp for reduction(+ : r)
+  ++r;
+// expected-error@+1 {{directive '#pragma omp task' cannot contain more than one 'untied' clause}}
+#pragma omp task untied untied
+  ++r;
+// expected-error@+1 {{directive '#pragma omp task' cannot contain more than one 'mergeable' clause}}
+#pragma omp task mergeable mergeable
+  ++r;
+  return a + b;
+}
+
+int main(int argc, char **argv) {
+  int a;
+  int &b = a; // expected-note 2 {{'b' defined here}}
+  S sa;       // expected-note 3 {{'sa' defined here}}
+  S &sb = sa; // expected-note 2 {{'sb' defined here}}
+  int r;
+#pragma omp task { // expected-warning {{extra tokens at the end of '#pragma omp task' are ignored}}
+  foo();
+#pragma omp task( // expected-warning {{extra tokens at the end of '#pragma omp task' are ignored}}
+  foo();
+#pragma omp task[ // expected-warning {{extra tokens at the end of '#pragma omp task' are ignored}}
+  foo();
+#pragma omp task] // expected-warning {{extra tokens at the end of '#pragma omp task' are ignored}}
+  foo();
+#pragma omp task) // expected-warning {{extra tokens at the end of '#pragma omp task' are ignored}}
+  foo();
+#pragma omp task } // expected-warning {{extra tokens at the end of '#pragma omp task' are ignored}}
+  foo();
+#pragma omp task
+// expected-warning@+1 {{extra tokens at the end of '#pragma omp task' are ignored}}
+#pragma omp task unknown()
+  foo();
+L1:
+  foo();
+#pragma omp task
+  ;
+#pragma omp task
+  {
+    goto L1; // expected-error {{use of undeclared label 'L1'}}
+    argc++;
+  }
+
+  for (int i = 0; i < 10; ++i) {
+    switch (argc) {
+    case (0):
+#pragma omp task
+    {
+      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 task 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 task
+L2:
+  foo();
+#pragma omp task
+  {
+    return 1; // expected-error {{cannot return from OpenMP region}}
+  }
+
+  [[]] // expected-error {{an attribute list cannot appear here}}
+#pragma omp task
+      for (int n = 0; n < 100; ++n) {
+  }
+
+#pragma omp task default(none)
+#pragma omp task default(shared)
+  ++a;
+#pragma omp task default(none)
+#pragma omp task
+  ++a;
+#pragma omp task default(shared)
+#pragma omp task
+  ++a;
+#pragma omp task
+#pragma omp parallel
+  ++a;
+// expected-error@+1 {{predetermined as a firstprivate in a task construct variable cannot be of reference type 'int &'}}
+#pragma omp task
+  // expected-note@+1 {{used here}}
+  ++b;
+// expected-error@+1 {{predetermined as a firstprivate in a task construct variable cannot be of reference type 'int &'}}
+#pragma omp task
+// expected-note@+1 {{used here}}
+#pragma omp parallel shared(a, b)
+  ++a, ++b;
+#pragma omp task default(none)
+#pragma omp task default(shared)
+  ++sa;
+#pragma omp task default(none)
+// expected-error@+1 {{predetermined as a firstprivate in a task construct variable must have an accessible, unambiguous copy constructor}}
+#pragma omp task
+// expected-note@+1 {{used here}}
+  ++sa;
+#pragma omp task
+// expected-error@+1 {{predetermined as a firstprivate in a task construct variable must have an accessible, unambiguous copy constructor}}
+#pragma omp task
+// expected-note@+1 {{used here}}
+  ++sa;
+#pragma omp task default(shared)
+#pragma omp task
+  ++sa;
+#pragma omp task
+#pragma omp parallel
+  ++sa;
+// expected-error@+1 {{predetermined as a firstprivate in a task construct variable cannot be of reference type 'S &'}}
+#pragma omp task
+  // expected-note@+1 {{used here}}
+  ++sb;
+// expected-error@+2 {{predetermined as a firstprivate in a task construct variable cannot be of reference type 'S &'}}
+// expected-error@+1 {{predetermined as a firstprivate in a task construct variable must have an accessible, unambiguous copy constructor}}
+#pragma omp task
+// expected-note@+1 2 {{used here}}
+#pragma omp parallel shared(sa, sb)
+  ++sa, ++sb;
+// expected-note@+1 2 {{defined as reduction}}
+#pragma omp parallel reduction(+ : r)
+// expected-error@+1 {{argument of a reduction clause of a parallel construct must not appear in a firstprivate clause on a task construct}}
+#pragma omp task firstprivate(r)
+  // expected-error@+1 {{reduction variables may not be accessed in an explicit task}}
+  ++r;
+// expected-note@+1 {{defined as reduction}}
+#pragma omp parallel reduction(+ : r)
+#pragma omp task default(shared)
+  // expected-error@+1 {{reduction variables may not be accessed in an explicit task}}
+  ++r;
+// expected-note@+1 {{defined as reduction}}
+#pragma omp parallel reduction(+ : r)
+#pragma omp task
+  // expected-error@+1 {{reduction variables may not be accessed in an explicit task}}
+  ++r;
+#pragma omp parallel
+// expected-note@+1 2 {{defined as reduction}}
+#pragma omp for reduction(+ : r)
+  for (int i = 0; i < 10; ++i)
+// expected-error@+1 {{argument of a reduction clause of a for construct must not appear in a firstprivate clause on a task construct}}
+#pragma omp task firstprivate(r)
+    // expected-error@+1 {{reduction variables may not be accessed in an explicit task}}
+    ++r;
+#pragma omp parallel
+// expected-note@+1 {{defined as reduction}}
+#pragma omp for reduction(+ : r)
+  for (int i = 0; i < 10; ++i)
+#pragma omp task default(shared)
+    // expected-error@+1 {{reduction variables may not be accessed in an explicit task}}
+    ++r;
+#pragma omp parallel
+// expected-note@+1 {{defined as reduction}}
+#pragma omp for reduction(+ : r)
+  for (int i = 0; i < 10; ++i)
+#pragma omp task
+    // expected-error@+1 {{reduction variables may not be accessed in an explicit task}}
+    ++r;
+// expected-note@+1 {{non-shared variable in a task construct is predetermined as firstprivate}}
+#pragma omp task
+// expected-error@+2 {{reduction variable must be shared}}
+// expected-error@+1 {{region cannot be closely nested inside 'task' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+#pragma omp for reduction(+ : r)
+  ++r;
+// expected-error@+1 {{directive '#pragma omp task' cannot contain more than one 'untied' clause}}
+#pragma omp task untied untied
+  ++r;
+// expected-error@+1 {{directive '#pragma omp task' cannot contain more than one 'mergeable' clause}}
+#pragma omp task mergeable mergeable
+  ++r;
+  // expected-note@+2 {{in instantiation of function template specialization 'foo<int>' requested here}}
+  // expected-note@+1 {{in instantiation of function template specialization 'foo<S>' requested here}}
+  return foo<int>() + foo<S>();
+}
+
diff --git a/test/OpenMP/task_private_messages.cpp b/test/OpenMP/task_private_messages.cpp
new file mode 100644
index 0000000..0be238d
--- /dev/null
+++ b/test/OpenMP/task_private_messages.cpp
@@ -0,0 +1,85 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 %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 {          // expected-note {{'S4' declared here}}
+  int a;
+  S4();
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 { // expected-note {{'S5' declared here}}
+  int a;
+  S5() : a(0) {}
+
+public:
+  S5(int v) : a(v) {}
+};
+
+int threadvar;
+#pragma omp threadprivate(threadvar) // expected-note {{defined as threadprivate or thread local}}
+
+int main(int argc, char **argv) {
+  const int d = 5;       // expected-note {{constant variable is predetermined as shared}}
+  const int da[5] = {0}; // expected-note {{constant variable is predetermined as shared}}
+  S4 e(4);               // expected-note {{'e' defined here}}
+  S5 g(5);               // expected-note {{'g' defined here}}
+  int i;
+  int &j = i;                                          // expected-note {{'j' defined here}}
+#pragma omp task private                               // expected-error {{expected '(' after 'private'}}
+#pragma omp task private(                              // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp task private()                             // expected-error {{expected expression}}
+#pragma omp task private(argc                          // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp task private(argc,                         // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma omp task private(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+#pragma omp task private(argc argv)                    // expected-error {{expected ',' or ')' in 'private' clause}}
+#pragma omp task private(S1)                           // expected-error {{'S1' does not refer to a value}}
+#pragma omp task private(a, b, c, d, f)                // expected-error {{a private variable with incomplete type 'S1'}} expected-error 3 {{shared variable cannot be private}}
+#pragma omp task private(argv[1])                      // expected-error {{expected variable name}}
+#pragma omp task private(ba)
+#pragma omp task private(ca)           // expected-error {{shared variable cannot be private}}
+#pragma omp task private(da)           // expected-error {{shared variable cannot be private}}
+#pragma omp task private(S2::S2s)      // expected-error {{shared variable cannot be private}}
+#pragma omp task private(e, g)         // expected-error 2 {{private variable must have an accessible, unambiguous default constructor}}
+#pragma omp task private(threadvar)    // expected-error {{threadprivate or thread local variable cannot be private}}
+#pragma omp task shared(i), private(i) // expected-error {{shared variable cannot be private}} expected-note {{defined as shared}}
+  foo();
+#pragma omp task firstprivate(i) private(i) // expected-error {{firstprivate variable cannot be private}} expected-note {{defined as firstprivate}}
+  foo();
+#pragma omp task private(i)
+#pragma omp task private(j) // expected-error {{arguments of OpenMP clause 'private' cannot be of reference type 'int &'}}
+  foo();
+#pragma omp task firstprivate(i)
+  for (int k = 0; k < 10; ++k) {
+#pragma omp task private(i)
+    foo();
+  }
+
+  return 0;
+}
diff --git a/test/OpenMP/task_shared_messages.cpp b/test/OpenMP/task_shared_messages.cpp
new file mode 100644
index 0000000..7479237
--- /dev/null
+++ b/test/OpenMP/task_shared_messages.cpp
@@ -0,0 +1,102 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+  return argc;
+}
+
+struct S1; // expected-note {{declared here}}
+extern S1 a;
+class S2 {
+  mutable int a;
+
+public:
+  S2() : a(0) {}
+  S2(S2 &s2) : a(s2.a) {}
+};
+const S2 b;
+const S2 ba[5];
+class S3 {
+  int a;
+
+public:
+  S3() : a(0) {}
+  S3(S3 &s3) : a(s3.a) {}
+};
+const S3 c;
+const S3 ca[5];
+extern const int f;
+class S4 {
+  int a;
+  S4();
+  S4(const S4 &s4);
+
+public:
+  S4(int v) : a(v) {}
+};
+class S5 {
+  int a;
+  S5() : a(0) {}
+  S5(const S5 &s5) : a(s5.a) {}
+
+public:
+  S5(int v) : a(v) {}
+};
+
+S3 h;
+#pragma omp threadprivate(h) // expected-note {{defined as threadprivate or thread local}}
+
+int main(int argc, char **argv) {
+  const int d = 5;
+  const int da[5] = {0};
+  S4 e(4);
+  S5 g(5);
+  int i;
+  int &j = i;
+#pragma omp task shared                               // expected-error {{expected '(' after 'shared'}}
+  foo();
+#pragma omp task shared(                              // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp task shared()                             // expected-error {{expected expression}}
+  foo();
+#pragma omp task shared(argc                          // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp task shared(argc,                         // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  foo();
+#pragma omp task shared(argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  foo();
+#pragma omp task shared(argc)
+  foo();
+#pragma omp task shared(S1) // expected-error {{'S1' does not refer to a value}}
+  foo();
+#pragma omp task shared(a, b, c, d, f)
+  foo();
+#pragma omp task shared(argv[1]) // expected-error {{expected variable name}}
+  foo();
+#pragma omp task shared(ba)
+  foo();
+#pragma omp task shared(ca)
+  foo();
+#pragma omp task shared(da)
+  foo();
+#pragma omp task shared(e, g)
+  foo();
+#pragma omp task shared(h)             // expected-error {{threadprivate or thread local variable cannot be shared}}
+  foo();
+#pragma omp task private(i), shared(i) // expected-error {{private variable cannot be shared}} expected-note {{defined as private}}
+  foo();
+#pragma omp task firstprivate(i), shared(i) // expected-error {{firstprivate variable cannot be shared}} expected-note {{defined as firstprivate}}
+  foo();
+#pragma omp parallel private(i)
+#pragma omp task shared(i)
+#pragma omp task shared(j)
+  foo();
+#pragma omp parallel firstprivate(i)
+#pragma omp task shared(i)
+#pragma omp task shared(j)
+  foo();
+
+  return 0;
+}
diff --git a/test/OpenMP/taskwait_ast_print.cpp b/test/OpenMP/taskwait_ast_print.cpp
new file mode 100644
index 0000000..9942622
--- /dev/null
+++ b/test/OpenMP/taskwait_ast_print.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+void foo() {}
+
+template <class T>
+T tmain(T argc) {
+  static T a;
+#pragma omp taskwait
+  return a + argc;
+}
+// CHECK:      static int a;
+// CHECK-NEXT: #pragma omp taskwait
+// CHECK:      static char a;
+// CHECK-NEXT: #pragma omp taskwait
+// CHECK:      static T a;
+// CHECK-NEXT: #pragma omp taskwait
+
+int main(int argc, char **argv) {
+  static int a;
+// CHECK: static int a;
+#pragma omp taskwait
+  // CHECK-NEXT: #pragma omp taskwait
+  return tmain(argc) + tmain(argv[0][0]) + a;
+}
+
+#endif
diff --git a/test/OpenMP/taskwait_messages.cpp b/test/OpenMP/taskwait_messages.cpp
new file mode 100644
index 0000000..f325c73
--- /dev/null
+++ b/test/OpenMP/taskwait_messages.cpp
@@ -0,0 +1,110 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 %s
+
+template <class T>
+T tmain(T argc) {
+#pragma omp taskwait
+  ;
+#pragma omp taskwait untied  // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp taskwait'}}
+#pragma omp taskwait unknown // expected-warning {{extra tokens at the end of '#pragma omp taskwait' are ignored}}
+  if (argc)
+#pragma omp taskwait // expected-error {{'#pragma omp taskwait' cannot be an immediate substatement}}
+    if (argc) {
+#pragma omp taskwait
+    }
+  while (argc)
+#pragma omp taskwait // expected-error {{'#pragma omp taskwait' cannot be an immediate substatement}}
+    while (argc) {
+#pragma omp taskwait
+    }
+  do
+#pragma omp taskwait // expected-error {{'#pragma omp taskwait' cannot be an immediate substatement}}
+    while (argc)
+      ;
+  do {
+#pragma omp taskwait
+  } while (argc);
+  switch (argc)
+#pragma omp taskwait // expected-error {{'#pragma omp taskwait' cannot be an immediate substatement}}
+    switch (argc)
+    case 1:
+#pragma omp taskwait // expected-error {{'#pragma omp taskwait' cannot be an immediate substatement}}
+  switch (argc)
+  case 1: {
+#pragma omp taskwait
+  }
+  switch (argc) {
+#pragma omp taskwait
+  case 1:
+#pragma omp taskwait // expected-error {{'#pragma omp taskwait' cannot be an immediate substatement}}
+    break;
+  default: {
+#pragma omp taskwait
+  } break;
+  }
+  for (;;)
+#pragma omp taskwait // expected-error {{'#pragma omp taskwait' cannot be an immediate substatement}}
+    for (;;) {
+#pragma omp taskwait
+    }
+label:
+#pragma omp taskwait // expected-error {{'#pragma omp taskwait' cannot be an immediate substatement}}
+label1 : {
+#pragma omp taskwait
+}
+
+  return T();
+}
+
+int main(int argc, char **argv) {
+#pragma omp taskwait
+  ;
+#pragma omp taskwait untied  // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp taskwait'}}
+#pragma omp taskwait unknown // expected-warning {{extra tokens at the end of '#pragma omp taskwait' are ignored}}
+  if (argc)
+#pragma omp taskwait // expected-error {{'#pragma omp taskwait' cannot be an immediate substatement}}
+    if (argc) {
+#pragma omp taskwait
+    }
+  while (argc)
+#pragma omp taskwait // expected-error {{'#pragma omp taskwait' cannot be an immediate substatement}}
+    while (argc) {
+#pragma omp taskwait
+    }
+  do
+#pragma omp taskwait // expected-error {{'#pragma omp taskwait' cannot be an immediate substatement}}
+    while (argc)
+      ;
+  do {
+#pragma omp taskwait
+  } while (argc);
+  switch (argc)
+#pragma omp taskwait // expected-error {{'#pragma omp taskwait' cannot be an immediate substatement}}
+    switch (argc)
+    case 1:
+#pragma omp taskwait // expected-error {{'#pragma omp taskwait' cannot be an immediate substatement}}
+  switch (argc)
+  case 1: {
+#pragma omp taskwait
+  }
+  switch (argc) {
+#pragma omp taskwait
+  case 1:
+#pragma omp taskwait // expected-error {{'#pragma omp taskwait' cannot be an immediate substatement}}
+    break;
+  default: {
+#pragma omp taskwait
+  } break;
+  }
+  for (;;)
+#pragma omp taskwait // expected-error {{'#pragma omp taskwait' cannot be an immediate substatement}}
+    for (;;) {
+#pragma omp taskwait
+    }
+label:
+#pragma omp taskwait // expected-error {{'#pragma omp taskwait' cannot be an immediate substatement}}
+label1 : {
+#pragma omp taskwait
+}
+
+  return tmain(argc);
+}
diff --git a/test/OpenMP/taskyield_ast_print.cpp b/test/OpenMP/taskyield_ast_print.cpp
new file mode 100644
index 0000000..4c3ca47
--- /dev/null
+++ b/test/OpenMP/taskyield_ast_print.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+void foo() {}
+
+template <class T>
+T tmain(T argc) {
+  static T a;
+#pragma omp taskyield
+  return a + argc;
+}
+// CHECK:      static int a;
+// CHECK-NEXT: #pragma omp taskyield
+// CHECK:      static char a;
+// CHECK-NEXT: #pragma omp taskyield
+// CHECK:      static T a;
+// CHECK-NEXT: #pragma omp taskyield
+
+int main(int argc, char **argv) {
+  static int a;
+// CHECK: static int a;
+#pragma omp taskyield
+  // CHECK-NEXT: #pragma omp taskyield
+  return tmain(argc) + tmain(argv[0][0]) + a;
+}
+
+#endif
diff --git a/test/OpenMP/taskyield_messages.cpp b/test/OpenMP/taskyield_messages.cpp
new file mode 100644
index 0000000..7c35559
--- /dev/null
+++ b/test/OpenMP/taskyield_messages.cpp
@@ -0,0 +1,110 @@
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 %s
+
+template <class T>
+T tmain(T argc) {
+#pragma omp taskyield
+  ;
+#pragma omp taskyield untied  // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp taskyield'}}
+#pragma omp taskyield unknown // expected-warning {{extra tokens at the end of '#pragma omp taskyield' are ignored}}
+  if (argc)
+#pragma omp taskyield // expected-error {{'#pragma omp taskyield' cannot be an immediate substatement}}
+    if (argc) {
+#pragma omp taskyield
+    }
+  while (argc)
+#pragma omp taskyield // expected-error {{'#pragma omp taskyield' cannot be an immediate substatement}}
+    while (argc) {
+#pragma omp taskyield
+    }
+  do
+#pragma omp taskyield // expected-error {{'#pragma omp taskyield' cannot be an immediate substatement}}
+    while (argc)
+      ;
+  do {
+#pragma omp taskyield
+  } while (argc);
+  switch (argc)
+#pragma omp taskyield // expected-error {{'#pragma omp taskyield' cannot be an immediate substatement}}
+    switch (argc)
+    case 1:
+#pragma omp taskyield // expected-error {{'#pragma omp taskyield' cannot be an immediate substatement}}
+  switch (argc)
+  case 1: {
+#pragma omp taskyield
+  }
+  switch (argc) {
+#pragma omp taskyield
+  case 1:
+#pragma omp taskyield // expected-error {{'#pragma omp taskyield' cannot be an immediate substatement}}
+    break;
+  default: {
+#pragma omp taskyield
+  } break;
+  }
+  for (;;)
+#pragma omp taskyield // expected-error {{'#pragma omp taskyield' cannot be an immediate substatement}}
+    for (;;) {
+#pragma omp taskyield
+    }
+label:
+#pragma omp taskyield // expected-error {{'#pragma omp taskyield' cannot be an immediate substatement}}
+label1 : {
+#pragma omp taskyield
+}
+
+  return T();
+}
+
+int main(int argc, char **argv) {
+#pragma omp taskyield
+  ;
+#pragma omp taskyield untied  // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp taskyield'}}
+#pragma omp taskyield unknown // expected-warning {{extra tokens at the end of '#pragma omp taskyield' are ignored}}
+  if (argc)
+#pragma omp taskyield // expected-error {{'#pragma omp taskyield' cannot be an immediate substatement}}
+    if (argc) {
+#pragma omp taskyield
+    }
+  while (argc)
+#pragma omp taskyield // expected-error {{'#pragma omp taskyield' cannot be an immediate substatement}}
+    while (argc) {
+#pragma omp taskyield
+    }
+  do
+#pragma omp taskyield // expected-error {{'#pragma omp taskyield' cannot be an immediate substatement}}
+    while (argc)
+      ;
+  do {
+#pragma omp taskyield
+  } while (argc);
+  switch (argc)
+#pragma omp taskyield // expected-error {{'#pragma omp taskyield' cannot be an immediate substatement}}
+    switch (argc)
+    case 1:
+#pragma omp taskyield // expected-error {{'#pragma omp taskyield' cannot be an immediate substatement}}
+  switch (argc)
+  case 1: {
+#pragma omp taskyield
+  }
+  switch (argc) {
+#pragma omp taskyield
+  case 1:
+#pragma omp taskyield // expected-error {{'#pragma omp taskyield' cannot be an immediate substatement}}
+    break;
+  default: {
+#pragma omp taskyield
+  } break;
+  }
+  for (;;)
+#pragma omp taskyield // expected-error {{'#pragma omp taskyield' cannot be an immediate substatement}}
+    for (;;) {
+#pragma omp taskyield
+    }
+label:
+#pragma omp taskyield // expected-error {{'#pragma omp taskyield' cannot be an immediate substatement}}
+label1 : {
+#pragma omp taskyield
+}
+
+  return tmain(argc);
+}
diff --git a/test/OpenMP/threadprivate_ast_print.cpp b/test/OpenMP/threadprivate_ast_print.cpp
index 72bf6f4..4d0d40e 100644
--- a/test/OpenMP/threadprivate_ast_print.cpp
+++ b/test/OpenMP/threadprivate_ast_print.cpp
@@ -1,9 +1,7 @@
-// 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
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp=libiomp5 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print
 // expected-no-diagnostics
-// FIXME: This test has been crashing since r186647.
-// REQUIRES: disabled
 
 #ifndef HEADER
 #define HEADER
@@ -28,9 +26,16 @@
 #pragma omp threadprivate(d, b)
 // CHECK-NEXT: #pragma omp threadprivate(d,b)
 
+template <class T>
+struct ST {
+  static T m;
+  #pragma omp threadprivate(m)
+};
+
 template <class T> T foo() {
   static T v;
   #pragma omp threadprivate(v)
+  v = ST<T>::m;
   return v;
 }
 //CHECK: template <class T = int> int foo() {
diff --git a/test/OpenMP/threadprivate_messages.cpp b/test/OpenMP/threadprivate_messages.cpp
index 4858549..491f30a 100644
--- a/test/OpenMP/threadprivate_messages.cpp
+++ b/test/OpenMP/threadprivate_messages.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp -ferror-limit 100 %s
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -verify -fopenmp=libiomp5 -ferror-limit 100 %s
 
 #pragma omp threadprivate // expected-error {{expected '(' after 'threadprivate'}}
 #pragma omp threadprivate( // expected-error {{expected identifier}} expected-error {{expected ')'}} expected-note {{to match this '('}}
@@ -24,13 +24,22 @@
   return (a);
 }
 
+#pragma omp threadprivate (a) (
+// expected-error@-1 {{'#pragma omp threadprivate' must precede all references to variable 'a'}} expected-warning@-1 {{extra tokens at the end of '#pragma omp threadprivate' are ignored}}
+#pragma omp threadprivate (a) [ // expected-error {{'#pragma omp threadprivate' must precede all references to variable 'a'}} expected-warning {{extra tokens at the end of '#pragma omp threadprivate' are ignored}}
+#pragma omp threadprivate (a) { // expected-error {{'#pragma omp threadprivate' must precede all references to variable 'a'}} expected-warning {{extra tokens at the end of '#pragma omp threadprivate' are ignored}}
+#pragma omp threadprivate (a) ) // expected-error {{'#pragma omp threadprivate' must precede all references to variable 'a'}} expected-warning {{extra tokens at the end of '#pragma omp threadprivate' are ignored}}
+#pragma omp threadprivate (a) ] // expected-error {{'#pragma omp threadprivate' must precede all references to variable 'a'}} expected-warning {{extra tokens at the end of '#pragma omp threadprivate' are ignored}}
+#pragma omp threadprivate (a) } // expected-error {{'#pragma omp threadprivate' must precede all references to variable 'a'}} expected-warning {{extra tokens at the end of '#pragma omp threadprivate' are ignored}}
 #pragma omp threadprivate a // expected-error {{expected '(' after 'threadprivate'}}
 #pragma omp threadprivate(d // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{'#pragma omp threadprivate' must precede all references to variable 'd'}}
 #pragma omp threadprivate(d)) // expected-error {{'#pragma omp threadprivate' must precede all references to variable 'd'}} expected-warning {{extra tokens at the end of '#pragma omp threadprivate' are ignored}}
 int x, y;
 #pragma omp threadprivate(x)) // expected-warning {{extra tokens at the end of '#pragma omp threadprivate' are ignored}}
-#pragma omp threadprivate(y)), // expected-warning {{extra tokens at the end of '#pragma omp threadprivate' are ignored}}
-#pragma omp threadprivate(a,d)  // expected-error {{'#pragma omp threadprivate' must precede all references to variable 'a'}} expected-error {{'#pragma omp threadprivate' must precede all references to variable 'd'}}
+#pragma omp threadprivate(y)),
+// expected-warning@-1 {{extra tokens at the end of '#pragma omp threadprivate' are ignored}}
+#pragma omp threadprivate(a,d)
+// expected-error@-1 {{'#pragma omp threadprivate' must precede all references to variable 'a'}} expected-error@-1 {{'#pragma omp threadprivate' must precede all references to variable 'd'}}
 #pragma omp threadprivate(d.a) // expected-error {{expected identifier}}
 #pragma omp threadprivate((float)a) // expected-error {{expected unqualified-id}}
 int foa; // expected-note {{'foa' declared here}}
@@ -46,17 +55,17 @@
 int &f = a; // expected-note {{'f' defined here}}
 #pragma omp threadprivate (f) // expected-error {{arguments of '#pragma omp threadprivate' cannot be of reference type 'int &'}}
 
-class Class {
+class TestClass {
   private:
     int a; // expected-note {{declared here}}
     static int b; // expected-note {{'b' declared here}}
-    Class() : a(0){}
+    TestClass() : a(0){}
   public:
-    Class (int aaa) : a(aaa) {}
+    TestClass (int aaa) : a(aaa) {}
 #pragma omp threadprivate (b, a) // expected-error {{'a' is not a global variable, static local variable or static data member}}
 } g(10);
 #pragma omp threadprivate (b) // expected-error {{use of undeclared identifier 'b'}}
-#pragma omp threadprivate (Class::b) // expected-error {{'#pragma omp threadprivate' must appear in the scope of the 'Class::b' variable declaration}}
+#pragma omp threadprivate (TestClass::b) // expected-error {{'#pragma omp threadprivate' must appear in the scope of the 'TestClass::b' variable declaration}}
 #pragma omp threadprivate (g)
 
 namespace ns {
@@ -90,19 +99,21 @@
 int o; // expected-note {{candidate found by name lookup is 'o'}}
 #pragma omp threadprivate (o)
 namespace {
-int o; // expected-note {{candidate found by name lookup is '<anonymous namespace>::o'}}
+int o; // expected-note {{candidate found by name lookup is '(anonymous namespace)::o'}}
 #pragma omp threadprivate (o)
-#pragma omp threadprivate (o) // expected-error {{'#pragma omp threadprivate' must precede all references to variable '<anonymous namespace>::o'}}
+#pragma omp threadprivate (o) // expected-error {{'#pragma omp threadprivate' must precede all references to variable '(anonymous namespace)::o'}}
 }
 #pragma omp threadprivate (o) // expected-error {{reference to 'o' is ambiguous}}
 #pragma omp threadprivate (::o) // expected-error {{'#pragma omp threadprivate' must precede all references to variable 'o'}}
 
 int main(int argc, char **argv) { // expected-note {{'argc' defined here}}
 
-  int x, y = argc; // expected-note {{'y' defined here}}
+  int x, y = argc; // expected-note 2 {{'y' defined here}}
   static double d1;
   static double d2;
   static double d3; // expected-note {{'d3' defined here}}
+  static TestClass LocalClass(y); // expected-error {{variable with local storage in initial value of threadprivate variable}}
+#pragma omp threadprivate(LocalClass)
 
   d.a = a;
   d2++;
diff --git a/test/PCH/Inputs/chain-selectors2.h b/test/PCH/Inputs/chain-selectors2.h
index d54244d..741da92 100644
--- a/test/PCH/Inputs/chain-selectors2.h
+++ b/test/PCH/Inputs/chain-selectors2.h
@@ -1,6 +1,8 @@
 @interface Y
   -(void)f;
   -(void)f2;
+  -(void)x;
+  -(void)y;
   -(void)e;
 @end
 
diff --git a/test/PCH/Inputs/cuda.h b/test/PCH/Inputs/cuda.h
new file mode 100644
index 0000000..a9a4595
--- /dev/null
+++ b/test/PCH/Inputs/cuda.h
@@ -0,0 +1,20 @@
+/* Minimal declarations for CUDA support.  Testing purposes only. */
+
+#include <stddef.h>
+
+#define __constant__ __attribute__((constant))
+#define __device__ __attribute__((device))
+#define __global__ __attribute__((global))
+#define __host__ __attribute__((host))
+#define __shared__ __attribute__((shared))
+#define __launch_bounds__(...) __attribute__((launch_bounds(__VA_ARGS__)))
+
+struct dim3 {
+  unsigned x, y, z;
+  __host__ __device__ dim3(unsigned x, unsigned y = 1, unsigned z = 1) : x(x), y(y), z(z) {}
+};
+
+typedef struct cudaStream *cudaStream_t;
+
+int cudaConfigureCall(dim3 gridSize, dim3 blockSize, size_t sharedSize = 0,
+                      cudaStream_t stream = 0);
diff --git a/test/PCH/chain-pending-instantiations.cpp b/test/PCH/chain-pending-instantiations.cpp
index e49abcd..e87d336 100644
--- a/test/PCH/chain-pending-instantiations.cpp
+++ b/test/PCH/chain-pending-instantiations.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -emit-llvm -o - -chain-include %s -chain-include %s | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -triple i686-pc-linux -o - -chain-include %s -chain-include %s | FileCheck %s
 // CHECK: define linkonce_odr %{{[^ ]+}} @_ZN1AI1BE3getEv
 #if !defined(PASS1)
 #define PASS1
diff --git a/test/PCH/chain-selectors.m b/test/PCH/chain-selectors.m
index f2bfc4b..2551c64 100644
--- a/test/PCH/chain-selectors.m
+++ b/test/PCH/chain-selectors.m
@@ -18,9 +18,9 @@
   // FIXME: Can't verify notes in headers
   //[a f2];
 
-  (void)@selector(x); // expected-warning {{creating selector for nonexistent method 'x'}}
-  (void)@selector(y); // expected-warning {{creating selector for nonexistent method 'y'}}
-  (void)@selector(e); // expected-warning {{creating selector for nonexistent method 'e'}}
+  (void)@selector(x); // expected-warning {{no method with selector 'x' is implemented in this translation unit}}
+  (void)@selector(y); // expected-warning {{no method with selector 'y' is implemented in this translation unit}}
+  (void)@selector(e); // expected-warning {{no method with selector 'e' is implemented in this translation unit}}
 }
 
 @implementation X (Blah)
diff --git a/test/PCH/cuda-kernel-call.cu b/test/PCH/cuda-kernel-call.cu
index ef12c59..ffb0c14 100644
--- a/test/PCH/cuda-kernel-call.cu
+++ b/test/PCH/cuda-kernel-call.cu
@@ -5,7 +5,7 @@
 #define HEADER
 // Header.
 
-#include "../SemaCUDA/cuda.h"
+#include "Inputs/cuda.h"
 
 void kcall(void (*kp)()) {
   kp<<<1, 1>>>();
diff --git a/test/PCH/cxx-key-functions.cpp b/test/PCH/cxx-key-functions.cpp
new file mode 100644
index 0000000..9e7411c
--- /dev/null
+++ b/test/PCH/cxx-key-functions.cpp
@@ -0,0 +1,97 @@
+// RUN: %clang_cc1 -x c++ -include %s -emit-llvm-only %s
+// RUN: %clang_cc1 -x c++ -emit-pch %s -o %t
+// RUN: %clang_cc1 -include-pch %t -emit-llvm-only %s
+
+#ifndef HEADER
+#define HEADER
+
+struct S00 { virtual void f(); };
+struct S01 { virtual void f(); };
+struct S02 { virtual void f(); };
+struct S03 { virtual void f(); };
+struct S04 { virtual void f(); };
+struct S05 { virtual void f(); };
+struct S06 { virtual void f(); };
+struct S07 { virtual void f(); };
+struct S08 { virtual void f(); };
+struct S09 { virtual void f(); };
+struct S10 { virtual void f(); };
+struct S11 { virtual void f(); };
+struct S12 { virtual void f(); };
+struct S13 { virtual void f(); };
+struct S14 { virtual void f(); };
+struct S15 { virtual void f(); };
+struct S16 { virtual void f(); };
+struct S17 { virtual void f(); };
+struct S18 { virtual void f(); };
+struct S19 { virtual void f(); };
+struct S20 { virtual void f(); };
+struct S21 { virtual void f(); };
+struct S22 { virtual void f(); };
+struct S23 { virtual void f(); };
+struct S24 { virtual void f(); };
+struct S25 { virtual void f(); };
+struct S26 { virtual void f(); };
+struct S27 { virtual void f(); };
+struct S28 { virtual void f(); };
+struct S29 { virtual void f(); };
+struct S30 { virtual void f(); };
+struct S31 { virtual void f(); };
+struct S32 { virtual void f(); };
+struct S33 { virtual void f(); };
+struct S34 { virtual void f(); };
+struct S35 { virtual void f(); };
+struct S36 { virtual void f(); };
+struct S37 { virtual void f(); };
+struct S38 { virtual void f(); };
+struct S39 { virtual void f(); };
+struct S40 { virtual void f(); };
+struct S41 { virtual void f(); };
+struct S42 { virtual void f(); };
+struct S43 { virtual void f(); };
+struct S44 { virtual void f(); };
+struct S45 { virtual void f(); };
+struct S46 { virtual void f(); };
+struct S47 { virtual void f(); };
+struct S48 { virtual void f(); };
+struct S49 { virtual void f(); };
+struct S50 { virtual void f(); };
+struct S51 { virtual void f(); };
+struct S52 { virtual void f(); };
+struct S53 { virtual void f(); };
+struct S54 { virtual void f(); };
+struct S55 { virtual void f(); };
+struct S56 { virtual void f(); };
+struct S57 { virtual void f(); };
+struct S58 { virtual void f(); };
+struct S59 { virtual void f(); };
+struct S60 { virtual void f(); };
+struct S61 { virtual void f(); };
+struct S62 { virtual void f(); };
+struct S63 { virtual void f(); };
+struct S64 { virtual void f(); };
+struct S65 { virtual void f(); };
+struct S66 { virtual void f(); };
+struct S67 { virtual void f(); };
+struct S68 { virtual void f(); };
+struct S69 { virtual void f(); };
+
+struct Test {
+  // Deserializing this key function should cause the key functions
+  // table to get resized.
+  virtual void f(S00, S01, S02, S03, S04, S05, S06, S07, S08, S09,
+                 S10, S11, S12, S13, S14, S15, S16, S17, S18, S19,
+                 S20, S21, S22, S23, S24, S25, S26, S27, S28, S29,
+                 S30, S31, S32, S33, S34, S35, S36, S37, S38, S39,
+                 S40, S41, S42, S43, S44, S45, S46, S47, S48, S49,
+                 S50, S51, S52, S53, S54, S55, S56, S57, S58, S59,
+                 S60, S61, S62, S63, S64, S65, S66, S67, S68, S69);
+  virtual void g();
+};
+
+#else
+
+void Test::g() {}
+void h(Test &t) { t.g(); }
+
+#endif
diff --git a/test/PCH/cxx-mangling.cpp b/test/PCH/cxx-mangling.cpp
new file mode 100644
index 0000000..d086f26
--- /dev/null
+++ b/test/PCH/cxx-mangling.cpp
@@ -0,0 +1,28 @@
+// Test without PCH.
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -include %s %s -emit-llvm -o - | FileCheck %s
+//
+// Test with PCH.
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -x c++-header %s -emit-pch -o %t
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -include-pch %t %s -emit-llvm -o - | FileCheck %s
+
+#ifndef HEADER
+#define HEADER
+
+struct A {
+  struct { int a; } a;
+  struct { int b; } b;
+};
+
+#else
+
+template<typename T> void f(T) {}
+
+// CHECK-LABEL: define void @_Z1g1A(
+void g(A a) {
+  // CHECK: call void @_Z1fIN1AUt0_EEvT_(
+  f(a.b);
+  // CHECK: call void @_Z1fIN1AUt_EEvT_(
+  f(a.a);
+}
+
+#endif
diff --git a/test/PCH/cxx-reference.cpp b/test/PCH/cxx-reference.cpp
index a1a44e6..becb935 100644
--- a/test/PCH/cxx-reference.cpp
+++ b/test/PCH/cxx-reference.cpp
@@ -1,6 +1,6 @@
 // Test this without pch.
-// RUN: %clang_cc1 -x c++ -std=c++11 -include %S/cxx-reference.h -fsyntax-only -emit-llvm -o - %s
+// RUN: %clang_cc1 -x c++ -triple %itanium_abi_triple -std=c++11 -include %S/cxx-reference.h -fsyntax-only -emit-llvm -o - %s
 
 // Test with pch.
-// RUN: %clang_cc1 -x c++ -std=c++11 -emit-pch -o %t %S/cxx-reference.h
-// RUN: %clang_cc1 -x c++ -std=c++11 -include-pch %t -fsyntax-only -emit-llvm -o - %s 
+// RUN: %clang_cc1 -x c++ -triple %itanium_abi_triple -std=c++11 -emit-pch -o %t %S/cxx-reference.h
+// RUN: %clang_cc1 -x c++ -triple %itanium_abi_triple -std=c++11 -include-pch %t -fsyntax-only -emit-llvm -o - %s 
diff --git a/test/PCH/cxx-required-decls.cpp b/test/PCH/cxx-required-decls.cpp
index 8c4b11c..c2f8e2f 100644
--- a/test/PCH/cxx-required-decls.cpp
+++ b/test/PCH/cxx-required-decls.cpp
@@ -1,9 +1,9 @@
 // Test this without pch.
-// RUN: %clang_cc1 -include %S/cxx-required-decls.h %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -include %S/cxx-required-decls.h %s -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s
 
 // Test with pch.
-// RUN: %clang_cc1 -x c++-header -emit-pch -o %t %S/cxx-required-decls.h
-// RUN: %clang_cc1 -include-pch %t %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -x c++-header -triple %itanium_abi_triple -emit-pch -o %t %S/cxx-required-decls.h
+// RUN: %clang_cc1 -include-pch %t %s -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s
 
 // CHECK: @_ZL5globS = internal global %struct.S zeroinitializer
 // CHECK: @_ZL3bar = internal global i32 0, align 4
diff --git a/test/PCH/cxx-templates.cpp b/test/PCH/cxx-templates.cpp
index e5ddd86..52ea875 100644
--- a/test/PCH/cxx-templates.cpp
+++ b/test/PCH/cxx-templates.cpp
@@ -1,24 +1,24 @@
 // Test this without pch.
-// RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -fexceptions -include %S/cxx-templates.h -verify %s -ast-dump -o -
-// RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -fexceptions -include %S/cxx-templates.h %s -emit-llvm -o - -DNO_ERRORS | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -include %S/cxx-templates.h -verify %s -ast-dump -o -
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -include %S/cxx-templates.h %s -emit-llvm -o - -DNO_ERRORS | FileCheck %s
 
 // Test with pch.
-// RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -fexceptions -x c++-header -emit-pch -o %t %S/cxx-templates.h
-// RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -fexceptions -include-pch %t -verify %s -ast-dump  -o -
-// RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -fexceptions -include-pch %t %s -emit-llvm -o - -error-on-deserialized-decl doNotDeserialize -DNO_ERRORS | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -x c++-header -emit-pch -o %t %S/cxx-templates.h
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -include-pch %t -verify %s -ast-dump  -o -
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -include-pch %t %s -emit-llvm -o - -error-on-deserialized-decl doNotDeserialize -DNO_ERRORS | FileCheck %s
 
 // Test with modules.
-// RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -fexceptions -fmodules -x c++-header -emit-pch -o %t %S/cxx-templates.h
-// RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -fexceptions -fmodules -include-pch %t -verify %s -ast-dump  -o -
-// RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -fexceptions -fmodules -include-pch %t %s -emit-llvm -o - -error-on-deserialized-decl doNotDeserialize -DNO_ERRORS | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -fmodules -x c++-header -emit-pch -o %t %S/cxx-templates.h
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -fmodules -include-pch %t -verify %s -ast-dump  -o -
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fexceptions -fmodules -include-pch %t %s -emit-llvm -o - -error-on-deserialized-decl doNotDeserialize -DNO_ERRORS | FileCheck %s
 
 // Test with pch and delayed template parsing.
-// RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -fdelayed-template-parsing -fexceptions -x c++-header -emit-pch -o %t %S/cxx-templates.h
-// RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -fdelayed-template-parsing -fexceptions -include-pch %t -verify %s -ast-dump  -o -
-// RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -fdelayed-template-parsing -fexceptions -include-pch %t %s -emit-llvm -o - -DNO_ERRORS | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fdelayed-template-parsing -fexceptions -x c++-header -emit-pch -o %t %S/cxx-templates.h
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fdelayed-template-parsing -fexceptions -include-pch %t -verify %s -ast-dump  -o -
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fcxx-exceptions -fdelayed-template-parsing -fexceptions -include-pch %t %s -emit-llvm -o - -DNO_ERRORS | FileCheck %s
 
-// CHECK: define weak_odr void @_ZN2S4IiE1mEv
-// CHECK: define linkonce_odr void @_ZN2S3IiE1mEv
+// CHECK: define weak_odr {{.*}}void @_ZN2S4IiE1mEv
+// CHECK: define linkonce_odr {{.*}}void @_ZN2S3IiE1mEv
 
 struct A {
   typedef int type;
diff --git a/test/PCH/cxx-templates.h b/test/PCH/cxx-templates.h
index 992f478..c4a8447 100644
--- a/test/PCH/cxx-templates.h
+++ b/test/PCH/cxx-templates.h
@@ -311,3 +311,50 @@
     return sizeof(arr);
   }
 }
+
+namespace rdar15468709a {
+  template<typename> struct decay {};
+
+  template<typename FooParamTy> auto foo(FooParamTy fooParam) -> decltype(fooParam);
+  template<typename BarParamTy> auto bar(BarParamTy barParam) -> decay<decltype(barParam)>;
+
+  struct B {};
+
+  void crash() {
+    B some;
+    bar(some);
+  }
+}
+
+namespace rdar15468709b {
+  template<typename> struct decay {};
+
+  template<typename... Foos> int returnsInt(Foos... foos);
+
+  template<typename... FooParamTy> auto foo(FooParamTy... fooParam) -> decltype(returnsInt(fooParam...));
+  template<typename... BarParamTy> auto bar(BarParamTy... barParam) -> decay<decltype(returnsInt(barParam...))>;
+
+  struct B {};
+
+  void crash() {
+    B some;
+    bar(some);
+  }
+}
+
+namespace rdar15468709c {
+  template<typename> struct decay {};
+
+  template<class... Foos> int returnsInt(Foos... foos);
+
+  template<typename FooParamTy> void foo(FooParamTy fooParam) { decltype(fooParam) a; }
+  template<typename BarParamTy> auto bar(BarParamTy barParam) -> decay<decltype(barParam)>;
+
+  struct B {};
+
+  void crash() {
+    B some;
+    bar(some);
+  }
+}
+
diff --git a/test/PCH/cxx-traits.cpp b/test/PCH/cxx-traits.cpp
index 938f36f..ffdfccc 100644
--- a/test/PCH/cxx-traits.cpp
+++ b/test/PCH/cxx-traits.cpp
@@ -2,9 +2,11 @@
 // RUN: %clang_cc1 -include %S/cxx-traits.h -std=c++11 -fsyntax-only -verify %s
 
 // RUN: %clang_cc1 -x c++-header -std=c++11 -emit-pch -o %t %S/cxx-traits.h
-// RUN: %clang_cc1 -std=c++11 -include-pch %t -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -include-pch %t -DPCH -fsyntax-only -verify %s
 
+#ifdef PCH
 // expected-no-diagnostics
+#endif
 
 bool _Is_pod_comparator = __is_pod<int>::__value;
 bool _Is_empty_check = __is_empty<int>::__value;
diff --git a/test/PCH/cxx-traits.h b/test/PCH/cxx-traits.h
index 8b62002..e6f2feb 100644
--- a/test/PCH/cxx-traits.h
+++ b/test/PCH/cxx-traits.h
@@ -1,12 +1,12 @@
 // Header for PCH test cxx-traits.cpp
 
 template<typename _Tp>
-struct __is_pod {
+struct __is_pod { // expected-warning {{keyword '__is_pod' will be made available as an identifier for the remainder of the translation unit}}
   enum { __value };
 };
 
 template<typename _Tp>
-struct __is_empty {
+struct __is_empty { // expected-warning {{keyword '__is_empty' will be made available as an identifier for the remainder of the translation unit}}
   enum { __value };
 };
 
diff --git a/test/PCH/cxx11-exception-spec.cpp b/test/PCH/cxx11-exception-spec.cpp
index 446619e..8c7388a 100644
--- a/test/PCH/cxx11-exception-spec.cpp
+++ b/test/PCH/cxx11-exception-spec.cpp
@@ -1,18 +1,47 @@
-// RUN: %clang_cc1 -pedantic-errors -std=c++11 -emit-pch %s -o %t
-// RUN: %clang_cc1 -pedantic-errors -std=c++11 -include-pch %t -verify %s
+// RUN: %clang_cc1 -pedantic-errors -std=c++11 -emit-pch %s -o %t.1
+// RUN: %clang_cc1 -pedantic-errors -std=c++11 -include-pch %t.1 -emit-pch %s -o %t.2
+// RUN: %clang_cc1 -pedantic-errors -std=c++11 -include-pch %t.2 -verify %s
+// RUN: %clang_cc1 -pedantic-errors -std=c++11 -include-pch %t.2 -emit-llvm-only %s
 // expected-no-diagnostics
 
-#ifndef HEADER_INCLUDED
+#ifndef PHASE1_DONE
+#define PHASE1_DONE
 
-#define HEADER_INCLUDED
+template<int n> int f() noexcept(n % 2) { return 0; }
+template<int n> int g() noexcept(n % 2);
 
-template<bool b> int f() noexcept(b) {}
-decltype(f<false>()) a;
-decltype(f<true>()) b;
+decltype(f<2>()) f0;
+decltype(f<3>()) f1;
+template int f<4>();
+template int f<5>();
+decltype(f<6>()) f6;
+decltype(f<7>()) f7;
+
+struct A {
+  A();
+  A(const A&);
+};
+
+decltype(g<0>()) g0;
+
+#elif !defined(PHASE2_DONE)
+#define PHASE2_DONE
+
+template int f<6>();
+template int f<7>();
+decltype(f<8>()) f8;
+decltype(f<9>()) f9;
+template int f<10>();
+template int f<11>();
+
+A::A() = default;
+A::A(const A&) = default;
+
+int g0val = g<0>();
 
 #else
 
-static_assert(!noexcept(f<false>()), "");
-static_assert(noexcept(f<true>()), "");
+static_assert(!noexcept(f<0>()), "");
+static_assert(noexcept(f<1>()), "");
 
 #endif
diff --git a/test/PCH/cxx11-inheriting-ctors.cpp b/test/PCH/cxx11-inheriting-ctors.cpp
new file mode 100644
index 0000000..79f78ba
--- /dev/null
+++ b/test/PCH/cxx11-inheriting-ctors.cpp
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -std=c++11 -include-pch %t -verify %s
+
+// expected-no-diagnostics
+
+#ifndef HEADER_INCLUDED
+#define HEADER_INCLUDED
+
+struct Base {
+  Base(int) {}
+
+  template <typename T>
+  Base(T) {}
+};
+
+struct Test : Base {
+  using Base::Base;
+};
+
+template <typename T>
+struct Test2 : Base {
+  using Base::Base;
+};
+
+template <typename B>
+struct Test3 : B {
+  using B::B;
+};
+
+#else
+
+Test test1a(42);
+Test test1b(nullptr);
+Test2<int> test2a(42);
+Test2<int> test2b(nullptr);
+Test3<Base> test3a(42);
+Test3<Base> test3b(nullptr);
+
+#endif // HEADER_INCLUDED
diff --git a/test/PCH/different-diagnostic-level.c b/test/PCH/different-diagnostic-level.c
new file mode 100644
index 0000000..ac1a0da
--- /dev/null
+++ b/test/PCH/different-diagnostic-level.c
@@ -0,0 +1,17 @@
+// RUN: %clang -x c-header %s -Weverything -o %t.h.pch
+// RUN: %clang -x c %s -w -include %t.h -fsyntax-only -Xclang -verify
+
+#ifndef HEADER
+#define HEADER
+
+extern int foo;
+
+#else
+
+void f() {
+  int a = foo;
+  // Make sure we parsed this by getting an error.
+  int b = bar; // expected-error {{undeclared}}
+}
+
+#endif
diff --git a/test/PCH/different-linker-version.c b/test/PCH/different-linker-version.c
new file mode 100644
index 0000000..9e2f38f
--- /dev/null
+++ b/test/PCH/different-linker-version.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -target-linker-version 100 -emit-pch %s -o %t.h.pch
+// RUN: %clang_cc1 -target-linker-version 200 %s -include-pch %t.h.pch -fsyntax-only -verify
+
+#ifndef HEADER
+#define HEADER
+
+extern int foo;
+
+#else
+
+void f() {
+  int a = foo;
+  // Make sure we parsed this by getting an error.
+  int b = bar; // expected-error {{undeclared}}
+}
+
+#endif
diff --git a/test/PCH/field-designator.c b/test/PCH/field-designator.c
index 763cfda..6f318fd 100644
--- a/test/PCH/field-designator.c
+++ b/test/PCH/field-designator.c
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -cc1 %s -include %s
-// RUN: %clang_cc1 -cc1 %s -emit-pch -o %t.pch
-// RUN: %clang_cc1 -cc1 %s -include-pch %t.pch
+// RUN: %clang_cc1 %s -include %s
+// RUN: %clang_cc1 %s -emit-pch -o %t.pch
+// RUN: %clang_cc1 %s -include-pch %t.pch
 
 // rdar://12239321 Make sure we don't emit a bogus
 //     error: field designator 'e' does not refer to a non-static data member
diff --git a/test/PCH/irgen-rdar13114142.mm b/test/PCH/irgen-rdar13114142.mm
index 7a9cfba..288c39d 100644
--- a/test/PCH/irgen-rdar13114142.mm
+++ b/test/PCH/irgen-rdar13114142.mm
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 %s -emit-pch -o %t.pch
-// RUN: %clang_cc1 %s -emit-llvm -include-pch %t.pch -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -emit-pch -o %t.pch
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -emit-llvm -include-pch %t.pch -o - | FileCheck %s
 
 #ifndef HEADER
 #define HEADER
diff --git a/test/PCH/local_static.cpp b/test/PCH/local_static.cpp
new file mode 100644
index 0000000..1085d81
--- /dev/null
+++ b/test/PCH/local_static.cpp
@@ -0,0 +1,20 @@
+// Test this without PCH.
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9.0 -include %S/local_static.h -fsyntax-only %s -emit-llvm -o %t.no_pch.ll %s
+// RUN: FileCheck --input-file %t.no_pch.ll %s
+
+// Test with PCH.
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9.0 -x c++-header -emit-pch -o %t.pch %S/local_static.h
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9.0 -include-pch %t.pch -emit-llvm -o %t.pch.ll %s
+// RUN: FileCheck --input-file %t.pch.ll %s
+
+void test(Bar &b) {
+  b.f<int>();
+  static int s;
+}
+
+// Check if the mangling of static and local extern variables
+// are correct and preserved by PCH.
+
+// CHECK: @_ZZ4testR3BarE1s = internal global i32 0, align 4
+// CHECK: @_ZZN3Bar1fIiEEvvE1y = linkonce_odr constant i32 0, align 4
+
diff --git a/test/PCH/local_static.h b/test/PCH/local_static.h
new file mode 100644
index 0000000..a69382a
--- /dev/null
+++ b/test/PCH/local_static.h
@@ -0,0 +1,7 @@
+class Bar {
+public:
+  template<typename T>
+  void f() {
+    static const T y = 0;
+  }
+};
diff --git a/test/PCH/macro-undef.cpp b/test/PCH/macro-undef.cpp
new file mode 100644
index 0000000..c0ce2de
--- /dev/null
+++ b/test/PCH/macro-undef.cpp
@@ -0,0 +1,36 @@
+// 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
+
+#ifndef HEADER
+#define HEADER
+
+#define NULL 0
+template<typename T>
+void *f() {
+  void *p;  // @11
+  return p; // @12
+}
+#undef NULL
+template<typename T>
+void *g() {
+  void *p;  // @17
+  return p; // @18
+}
+
+#else
+
+// expected-warning@12 {{uninitialized}}
+// expected-note@11 {{initialize}}
+// CHECK: fix-it:"{{.*}}":{11:10-11:10}:" = NULL"
+
+// expected-warning@18 {{uninitialized}}
+// expected-note@17 {{initialize}}
+// CHECK: fix-it:"{{.*}}":{17:10-17:10}:" = 0"
+
+int main() {
+  f<int>(); // expected-note {{instantiation}}
+  g<int>(); // expected-note {{instantiation}}
+}
+
+#endif
diff --git a/test/PCH/modified-module-dependency.m b/test/PCH/modified-module-dependency.m
new file mode 100644
index 0000000..3db8f3d
--- /dev/null
+++ b/test/PCH/modified-module-dependency.m
@@ -0,0 +1,20 @@
+// RUN: rm -rf %t-dir
+// RUN: mkdir -p %t-dir
+// RUN: echo '@import test;' > %t-dir/prefix.h
+// RUN: echo 'void foo(void);' > %t-dir/test.h
+// RUN: cp %S/modified-module-dependency.module.map %t-dir/module.map
+
+// Precompile prefix.pch.
+// RUN: %clang_cc1 -x objective-c -I %t-dir -fmodules -fmodules-cache-path=%t-dir/cache -fdisable-module-hash -emit-pch %t-dir/prefix.h -o %t-dir/prefix.pch
+
+// Modify the dependency.
+// RUN: echo ' ' >> %t-dir/test.h
+
+// Run and check the diagnostics.
+// RUN: not %clang_cc1 -x objective-c -I %t-dir -include-pch %t-dir/prefix.pch -fmodules -fmodules-cache-path=%t-dir/cache -fdisable-module-hash -fsyntax-only %s 2> %t-dir/log
+// RUN: FileCheck %s < %t-dir/log
+
+// CHECK: file '[[TEST_H:.*[/\\]test\.h]]' has been modified since the precompiled header '[[PREFIX_PCH:.*/prefix\.pch]]' was built
+// CHECK: '[[TEST_H]]' required by '[[TEST_PCM:.*[/\\]test\.pcm]]'
+// CHECK: '[[TEST_PCM]]' required by '[[PREFIX_PCH]]'
+// CHECK: please rebuild precompiled header '[[PREFIX_PCH]]'
diff --git a/test/PCH/modified-module-dependency.module.map b/test/PCH/modified-module-dependency.module.map
new file mode 100644
index 0000000..b470677
--- /dev/null
+++ b/test/PCH/modified-module-dependency.module.map
@@ -0,0 +1,4 @@
+module test {
+  header "test.h"
+  export *
+}
diff --git a/test/PCH/objc_container.m b/test/PCH/objc_container.m
index 0f25d32..44aac70 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: attributes #0 = { nounwind {{.*}} }
-// CHECK: attributes #1 = { nonlazybind }
+// CHECK-IR: attributes #0 = { nounwind {{.*}} }
+// CHECK-IR: attributes #1 = { nonlazybind }
diff --git a/test/PCH/objc_literals.mm b/test/PCH/objc_literals.mm
index 59f3381..777046e 100644
--- a/test/PCH/objc_literals.mm
+++ b/test/PCH/objc_literals.mm
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -emit-pch -x objective-c++ -std=c++0x -o %t %s
-// RUN: %clang_cc1 -include-pch %t -x objective-c++ -std=c++0x  -verify %s
-// RUN: %clang_cc1 -include-pch %t -x objective-c++ -std=c++0x  -ast-print %s | FileCheck -check-prefix=CHECK-PRINT %s
-// RUN: %clang_cc1 -include-pch %t -x objective-c++ -std=c++0x  -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-IR %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-pch -x objective-c++ -std=c++0x -o %t %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -include-pch %t -x objective-c++ -std=c++0x -verify %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -include-pch %t -x objective-c++ -std=c++0x -ast-print %s | FileCheck -check-prefix=CHECK-PRINT %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -include-pch %t -x objective-c++ -std=c++0x -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-IR %s
 
 // expected-no-diagnostics
 
diff --git a/test/PCH/objcxx-ivar-class.mm b/test/PCH/objcxx-ivar-class.mm
index a83d7e7..329f06f 100644
--- a/test/PCH/objcxx-ivar-class.mm
+++ b/test/PCH/objcxx-ivar-class.mm
@@ -1,15 +1,15 @@
 // Test this without pch.
-// RUN: not %clang_cc1 -include %S/objcxx-ivar-class.h -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -include %S/objcxx-ivar-class.h -triple %itanium_abi_triple %s -emit-llvm -o - | FileCheck %s
 
 // Test with pch.
-// RUN: %clang_cc1 -x objective-c++-header -emit-pch -o %t %S/objcxx-ivar-class.h
-// RUN: not %clang_cc1 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -x objective-c++-header -triple %itanium_abi_triple -emit-pch -o %t %S/objcxx-ivar-class.h
+// RUN: %clang_cc1 -include-pch %t -triple %itanium_abi_triple %s -emit-llvm -o - | FileCheck %s
 
 // CHECK: [C position]
 // CHECK: call {{.*}} @_ZN1SC1ERKS_
 
 // CHECK: [C setPosition:]
-// CHECK: call %struct.S* @_ZN1SaSERKS_
+// CHECK: = call {{.*}}%struct.S* @_ZN1SaSERKS_
 
 // CHECK: [C .cxx_destruct]
 // CHECK: [C .cxx_construct]
diff --git a/test/PCH/pr18806.cpp b/test/PCH/pr18806.cpp
new file mode 100644
index 0000000..c28320d
--- /dev/null
+++ b/test/PCH/pr18806.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -std=c++11 -emit-pch -o %t %s
+// RUN: %clang_cc1 -std=c++11 -include-pch %t -verify %s
+
+// expected-no-diagnostics
+
+// Before the patch, this test triggered an assert violation in
+// ASTContext::getSubstTemplateTypeParmType.
+
+#ifndef HEADER_INCLUDED
+#define HEADER_INCLUDED
+
+template <typename T>
+using Id = T;
+
+template <typename X>
+struct Class1 {
+  template <typename Y, typename = decltype(Y())>
+  struct Nested1;
+};
+
+template <typename A>
+struct Class2 {
+  template <typename B, typename = Id<decltype(B())>>
+  struct Nested2;
+};
+
+#else
+
+Class2<char> test;
+
+#endif
diff --git a/test/PCH/pr4489.c b/test/PCH/pr4489.c
index 033e55b..574e33f 100644
--- a/test/PCH/pr4489.c
+++ b/test/PCH/pr4489.c
@@ -2,12 +2,6 @@
 // RUN: echo > %t.empty.c
 // RUN: %clang -include %t -x c %t.empty.c -emit-llvm -S -o -
 
-// FIXME: This test is forcibly disabled, it is flaky on the clang-i686-xp-msvc9
-// buildbot.
-//
-// RUN: false
-// XFAIL: *
-
 // PR 4489: Crash with PCH
 // PR 4492: Crash with PCH (round two)
 // PR 4509: Crash with PCH (round three)
diff --git a/test/PCH/pragma-loop.cpp b/test/PCH/pragma-loop.cpp
new file mode 100644
index 0000000..1456a27
--- /dev/null
+++ b/test/PCH/pragma-loop.cpp
@@ -0,0 +1,90 @@
+// RUN: %clang_cc1 -emit-pch -o %t.a %s
+// RUN: %clang_cc1 -include-pch %t.a %s -ast-print -o - | FileCheck %s
+
+// FIXME: A bug in ParsedAttributes causes the order of the attributes to be
+// reversed. The checks are consequently in the reverse order below.
+
+// CHECK: #pragma clang loop unroll_count(16)
+// CHECK: #pragma clang loop interleave_count(8)
+// CHECK: #pragma clang loop vectorize_width(4)
+// CHECK: #pragma clang loop unroll(disable)
+// CHECK: #pragma clang loop interleave(disable)
+// CHECK: #pragma clang loop vectorize(enable)
+// CHECK: #pragma clang loop unroll(enable)
+// CHECK: #pragma clang loop interleave(enable)
+// CHECK: #pragma clang loop vectorize(disable)
+// CHECK: #pragma unroll
+// CHECK: #pragma unroll (32)
+
+#ifndef HEADER
+#define HEADER
+
+class pragma_test {
+public:
+  inline void run1(int *List, int Length) {
+    int i = 0;
+#pragma clang loop vectorize_width(4)
+#pragma clang loop interleave_count(8)
+#pragma clang loop unroll_count(16)
+    while (i < Length) {
+      List[i] = i;
+      i++;
+    }
+  }
+
+  inline void run2(int *List, int Length) {
+    int i = 0;
+#pragma clang loop vectorize(enable)
+#pragma clang loop interleave(disable)
+#pragma clang loop unroll(disable)
+    while (i - 1 < Length) {
+      List[i] = i;
+      i++;
+    }
+  }
+
+  inline void run3(int *List, int Length) {
+    int i = 0;
+#pragma clang loop vectorize(disable)
+#pragma clang loop interleave(enable)
+#pragma clang loop unroll(enable)
+    while (i - 3 < Length) {
+      List[i] = i;
+      i++;
+    }
+  }
+
+  inline void run4(int *List, int Length) {
+    int i = 0;
+#pragma unroll
+    while (i - 3 < Length) {
+      List[i] = i;
+      i++;
+    }
+  }
+
+  inline void run5(int *List, int Length) {
+    int i = 0;
+#pragma unroll 32
+    while (i - 3 < Length) {
+      List[i] = i;
+      i++;
+    }
+  }
+};
+
+#else
+
+void test() {
+  int List[100];
+
+  pragma_test pt;
+
+  pt.run1(List, 100);
+  pt.run2(List, 100);
+  pt.run3(List, 100);
+  pt.run4(List, 100);
+  pt.run5(List, 100);
+}
+
+#endif
diff --git a/test/PCH/pragma-optimize.c b/test/PCH/pragma-optimize.c
new file mode 100644
index 0000000..2206fe7
--- /dev/null
+++ b/test/PCH/pragma-optimize.c
@@ -0,0 +1,27 @@
+// Test this without pch.
+// RUN: %clang_cc1 %s -include %s -verify -fsyntax-only
+
+// Test with pch.
+// RUN: %clang_cc1 %s -emit-pch -o %t
+// RUN: %clang_cc1 %s -emit-llvm -include-pch %t -o - | FileCheck %s
+
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+#pragma clang optimize off
+
+#else
+
+int a;
+
+void f() {
+  a = 12345;
+}
+
+// Check that the function is decorated with optnone
+
+// CHECK-DAG: @f() [[ATTRF:#[0-9]+]]
+// CHECK-DAG: attributes [[ATTRF]] = { {{.*}}noinline{{.*}}optnone{{.*}} }
+
+#endif
diff --git a/test/PCH/single-token-macro.c b/test/PCH/single-token-macro.c
index 52873bf..aa02f65 100644
--- a/test/PCH/single-token-macro.c
+++ b/test/PCH/single-token-macro.c
@@ -12,6 +12,11 @@
 #ifndef HEADER
 #define HEADER
 
+#ifdef __stdcall
+// __stdcall is defined as __attribute__((__stdcall__)) for targeting mingw32.
+#undef __stdcall
+#endif
+
 #define __stdcall
 #define STDCALL __stdcall
 
diff --git a/test/PCH/stmt-attrs.cpp b/test/PCH/stmt-attrs.cpp
new file mode 100644
index 0000000..3d7c7a2
--- /dev/null
+++ b/test/PCH/stmt-attrs.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -std=c++11 -emit-pch -o %t.a %s

+// RUN: %clang_cc1 -std=c++11 -include-pch %t.a %s -ast-print -o - | FileCheck %s

+

+#ifndef HEADER

+#define HEADER

+

+inline void test(int i) {

+  switch (i) {

+    case 1:

+      // Notice that the NullStmt has two attributes.

+      // CHECK: {{\[\[clang::fallthrough\]\] \[\[clang::fallthrough\]\]}}

+      [[clang::fallthrough]] [[clang::fallthrough]];

+    case 2:

+      break;

+  }

+}

+

+#else

+

+void foo(void) {

+  test(1);

+}

+

+#endif

diff --git a/test/PCH/thread-safety-attrs.cpp b/test/PCH/thread-safety-attrs.cpp
index a588c0e..3e6f029 100644
--- a/test/PCH/thread-safety-attrs.cpp
+++ b/test/PCH/thread-safety-attrs.cpp
@@ -209,33 +209,33 @@
 
 void sls_fun_bad_1() {
   sls_mu.Unlock(); // \
-    // expected-warning{{unlocking 'sls_mu' that was not locked}}
+    // expected-warning{{releasing mutex 'sls_mu' that was not held}}
 }
 
 void sls_fun_bad_2() {
   sls_mu.Lock();
   sls_mu.Lock(); // \
-    // expected-warning{{locking 'sls_mu' that is already locked}}
+    // expected-warning{{acquiring mutex 'sls_mu' that is already held}}
   sls_mu.Unlock();
 }
 
 void sls_fun_bad_3() {
   sls_mu.Lock(); // expected-note {{mutex acquired here}}
-} // expected-warning{{mutex 'sls_mu' is still locked at the end of function}}
+} // expected-warning{{mutex 'sls_mu' is still held at the end of function}}
 
 void sls_fun_bad_4() {
   if (getBool())
     sls_mu.Lock();  // expected-note{{mutex acquired here}}
   else
     sls_mu2.Lock(); // expected-note{{mutex acquired here}}
-} // expected-warning{{mutex 'sls_mu' is not locked on every path through here}}  \
-  // expected-warning{{mutex 'sls_mu2' is not locked on every path through here}}
+} // expected-warning{{mutex 'sls_mu' is not held on every path through here}}  \
+  // expected-warning{{mutex 'sls_mu2' is not held on every path through here}}
 
 void sls_fun_bad_5() {
   sls_mu.Lock(); // expected-note {{mutex acquired here}}
   if (getBool())
     sls_mu.Unlock();
-} // expected-warning{{mutex 'sls_mu' is not locked on every path through here}}
+} // expected-warning{{mutex 'sls_mu' is not held on every path through here}}
 
 void sls_fun_bad_6() {
   if (getBool()) {
@@ -248,8 +248,8 @@
     }
   }
   sls_mu.Unlock(); // \
-    expected-warning{{mutex 'sls_mu' is not locked on every path through here}}\
-    expected-warning{{unlocking 'sls_mu' that was not locked}}
+    expected-warning{{mutex 'sls_mu' is not held on every path through here}}\
+    expected-warning{{releasing mutex 'sls_mu' that was not held}}
 }
 
 void sls_fun_bad_7() {
@@ -259,7 +259,7 @@
     if (getBool()) {
       if (getBool()) {
         continue; // \
-        expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
+        expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
       }
     }
     sls_mu.Lock(); // expected-note {{mutex acquired here}}
@@ -271,14 +271,14 @@
   sls_mu.Lock(); // expected-note{{mutex acquired here}}
 
   do {
-    sls_mu.Unlock(); // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
+    sls_mu.Unlock(); // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
   } while (getBool());
 }
 
 void sls_fun_bad_9() {
   do {
     sls_mu.Lock();  // \
-      // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}} \
+      // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}} \
       // expected-note{{mutex acquired here}}
   } while (getBool());
   sls_mu.Unlock();
@@ -286,18 +286,18 @@
 
 void sls_fun_bad_10() {
   sls_mu.Lock();  // expected-note 2{{mutex acquired here}}
-  while(getBool()) {  // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
+  while(getBool()) {  // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
     sls_mu.Unlock();
   }
-} // expected-warning{{mutex 'sls_mu' is still locked at the end of function}}
+} // expected-warning{{mutex 'sls_mu' is still held at the end of function}}
 
 void sls_fun_bad_11() {
   while (getBool()) { // \
-      expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
+      expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
     sls_mu.Lock(); // expected-note {{mutex acquired here}}
   }
   sls_mu.Unlock(); // \
-    // expected-warning{{unlocking 'sls_mu' that was not locked}}
+    // expected-warning{{releasing mutex 'sls_mu' that was not held}}
 }
 
 void sls_fun_bad_12() {
@@ -306,7 +306,7 @@
     sls_mu.Unlock();
     if (getBool()) {
       if (getBool()) {
-        break; // expected-warning{{mutex 'sls_mu' is not locked on every path through here}}
+        break; // expected-warning{{mutex 'sls_mu' is not held on every path through here}}
       }
     }
     sls_mu.Lock();
diff --git a/test/PCH/verify_pch.m b/test/PCH/verify_pch.m
new file mode 100644
index 0000000..dcfb286
--- /dev/null
+++ b/test/PCH/verify_pch.m
@@ -0,0 +1,30 @@
+// Setup:
+// RUN: rm -rf %t
+// RUN: mkdir -p %t/usr/include
+// RUN: echo '// empty' > %t/usr/include/sys_header.h
+// RUN: cp %s %t.h
+//
+// Precompile
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -isysroot %t -x objective-c-header -emit-pch -o %t.pch %t.h
+
+// Verify successfully
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -isysroot %t -verify-pch %t.pch
+
+// Incompatible lang options ignored
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -isysroot %t -x objective-c -fno-builtin -verify-pch %t.pch
+
+// Stale dependency
+// RUN: echo ' ' >> %t.h
+// RUN: not %clang_cc1 -triple x86_64-apple-darwin10 -isysroot %t -verify-pch %t.pch 2> %t.log.2
+// RUN: FileCheck -check-prefix=CHECK-STALE-DEP %s < %t.log.2
+// CHECK-STALE-DEP: file '{{.*}}.h' has been modified since the precompiled header '{{.*}}.pch' was built
+
+// Stale dependency in system header
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -isysroot %t -x objective-c-header -emit-pch -o %t.pch %t.h
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -isysroot %t -verify-pch %t.pch
+// RUN: echo ' ' >> %t/usr/include/sys_header.h
+// RUN: not %clang_cc1 -triple x86_64-apple-darwin10 -isysroot %t -verify-pch %t.pch 2> %t.log.3
+// RUN: FileCheck -check-prefix=CHECK-STALE-SYS-H %s < %t.log.3
+// CHECK-STALE-SYS-H: file '{{.*}}sys_header.h' has been modified since the precompiled header '{{.*}}.pch' was built
+
+#include <sys_header.h>
diff --git a/test/Parser/DelayedTemplateParsing.cpp b/test/Parser/DelayedTemplateParsing.cpp
index 73128c4..eff3120 100644
--- a/test/Parser/DelayedTemplateParsing.cpp
+++ b/test/Parser/DelayedTemplateParsing.cpp
@@ -121,3 +121,63 @@
 constexpr int Var = Fun(20);
 }
 
+template <typename T>
+auto invalidTrailingRetType() -> Bogus {} // expected-error {{unknown type name 'Bogus'}}
+
+namespace PR19613 {
+
+struct HeapTypeConfig {
+  static void from_bitset();
+};
+
+template <class Config>
+struct TypeImpl  {
+  struct BitsetType;
+
+  static void Any() {
+    BitsetType::New();
+  }
+};
+
+template<class Config>
+struct TypeImpl<Config>::BitsetType {
+  static void New() {
+    Config::from_bitset();
+  }
+};
+
+static void f() {
+  TypeImpl<HeapTypeConfig>::Any();
+}
+
+template<typename A> struct S {
+  template<typename B> struct T;
+};
+template<typename A> template<typename B> struct S<A>::T {
+  template<typename C, typename D> struct U;
+  template<typename C> struct U<C, C> {
+    template<typename E> static int f() {
+      return sizeof(A) + sizeof(B) + sizeof(C) + sizeof(E);
+    }
+  };
+};
+
+static void g() {
+  S<int>::T<int>::U<int,int>::f<int>();
+}
+
+template<typename T> struct SS {
+  template<typename U> struct X;
+  template<typename U> struct X<U*>;
+};
+template<typename T> template<typename U> struct SS<T>::X<U*> {
+  static int f() {
+    return sizeof(T) + sizeof(U);
+  }
+};
+
+static void h() {
+  SS<int>::X<int*>::f();
+}
+
+}
diff --git a/test/Parser/MicrosoftExtensions.c b/test/Parser/MicrosoftExtensions.c
index 5e11393..d7ea20b 100644
--- a/test/Parser/MicrosoftExtensions.c
+++ b/test/Parser/MicrosoftExtensions.c
@@ -1,124 +1,79 @@
-// RUN: %clang_cc1 -triple i386-mingw32 -fsyntax-only -verify -fms-extensions  -Wno-missing-declarations -x objective-c++ %s
-__stdcall int func0();
-int __stdcall func();
-typedef int (__cdecl *tptr)();
-void (*__fastcall fastpfunc)();
-struct __declspec(uuid("00000000-0000-0000-C000-000000000046")) __declspec(novtable) IUnknown {}; /* expected-warning{{__declspec attribute 'novtable' is not supported}} */
-extern __declspec(dllimport) void __stdcall VarR4FromDec();
+// RUN: %clang_cc1 -triple i386-mingw32 -fsyntax-only -Wno-missing-declarations -verify -fms-extensions  %s
+__stdcall int func0(void);
+int __stdcall func(void);
+typedef int (__cdecl *tptr)(void);
+void (*__fastcall fastpfunc)(void);
+extern __declspec(dllimport) void __stdcall VarR4FromDec(void);
 __declspec(deprecated) __declspec(deprecated) char * __cdecl ltoa( long _Val, char * _DstBuf, int _Radix);
-__declspec(safebuffers) __declspec(noalias) __declspec(restrict) void * __cdecl xxx( void * _Memory ); /* expected-warning{{__declspec attribute 'safebuffers' is not supported}} expected-warning{{__declspec attribute 'noalias' is not supported}} expected-warning{{__declspec attribute 'restrict' is not supported}} */
+__declspec(safebuffers) __declspec(noalias) __declspec(restrict) void * __cdecl xxx(void *_Memory); /* expected-warning{{__declspec attribute 'safebuffers' is not supported}} expected-warning{{__declspec attribute 'noalias' is not supported}} expected-warning{{__declspec attribute 'restrict' is not supported}} */
 typedef __w64 unsigned long ULONG_PTR, *PULONG_PTR;
 
-void * __ptr64 PtrToPtr64(const void *p)
-{
+void * __ptr64 PtrToPtr64(const void *p) {
   return((void * __ptr64) (unsigned __int64) (ULONG_PTR)p );
 }
-void * __ptr32 PtrToPtr32(const void *p)
-{
+
+void * __ptr32 PtrToPtr32(const void *p) {
   return((void * __ptr32) (unsigned __int32) (ULONG_PTR)p );
 }
 
-void __forceinline InterlockedBitTestAndSet (long *Base, long Bit)
-{
-  // FIXME: Re-enable this once MS inline asm stabilizes.
-#if 0
-  __asm {
-    mov eax, Bit
-    mov ecx, Base
-    lock bts [ecx], eax
-    setc al
-  };
-#endif
+/* Both inline and __forceinline is OK. */
+inline void __forceinline pr8264(void) {}
+__forceinline void inline pr8264_1(void) {}
+void inline __forceinline pr8264_2(void) {}
+void __forceinline inline pr8264_3(void) {}
+/* But duplicate __forceinline causes warning. */
+void __forceinline __forceinline pr8264_4(void) {  /* expected-warning{{duplicate '__forceinline' declaration specifier}} */
 }
 
-// Both inline and __forceinline is OK.
-inline void __forceinline pr8264() {
-}
-__forceinline void inline pr8264_1() {
-}
-void inline __forceinline pr8264_2() {
-}
-void __forceinline inline pr8264_3() {
-}
-// But duplicate __forceinline causes warning.
-void __forceinline __forceinline pr8264_4() {  // expected-warning{{duplicate '__forceinline' declaration specifier}}
-}
+_inline int foo99(void) { return 99; }
 
-_inline int foo99() { return 99; }
-
-void test_ms_alignof_alias() {
+void test_ms_alignof_alias(void) {
   unsigned int s = _alignof(int);
   s = __builtin_alignof(int);
 }
 
-void *_alloca(int);
-
-void foo() {
-  __declspec(align(16)) int *buffer = (int *)_alloca(9);
-}
-
-typedef bool (__stdcall __stdcall *blarg)(int);
-
-void local_callconv()
-{
-  bool (__stdcall *p)(int);
-}
-
-// Charify extension.
+/* Charify extension. */
 #define FOO(x) #@x
 char x = FOO(a);
 
 typedef enum E { e1 };
 
+enum __declspec(deprecated) E2 { i, j, k }; /* expected-note {{'E2' has been explicitly marked deprecated here}} */
+__declspec(deprecated) enum E3 { a, b, c } e; /* expected-note {{'e' has been explicitly marked deprecated here}} */
 
-enum __declspec(deprecated) E2 { i, j, k }; // expected-note {{declared here}}
-__declspec(deprecated) enum E3 { a, b, c } e; // expected-note {{declared here}}
-
-void deprecated_enum_test(void)
-{
-  // Test to make sure the deprecated warning follows the right thing
-  enum E2 e1;  // expected-warning {{'E2' is deprecated}}
-  enum E3 e2; // No warning expected, the deprecation follows the variable
-  enum E3 e3 = e;  // expected-warning {{'e' is deprecated}}
+void deprecated_enum_test(void) {
+  /* Test to make sure the deprecated warning follows the right thing */
+  enum E2 e1;  /* expected-warning {{'E2' is deprecated}} */
+  enum E3 e2; /* No warning expected, the deprecation follows the variable */
+  enum E3 e3 = e;  /* expected-warning {{'e' is deprecated}} */
 }
 
 /* Microsoft attribute tests */
-[repeatable][source_annotation_attribute( Parameter|ReturnValue )]
-struct SA_Post{ SA_Post(); int attr; };
-
 [returnvalue:SA_Post( attr=1)]
 int foo1([SA_Post(attr=1)] void *param);
 
-
-
-void ms_intrinsics(int a)
-{
+void ms_intrinsics(int a) {
   __noop();
   __assume(a);
   __debugbreak();
 }
 
-struct __declspec(frobble) S1 {};	/* expected-warning {{unknown __declspec attribute 'frobble' ignored}} */
+struct __declspec(frobble) S1 {};	/* expected-warning {{__declspec attribute 'frobble' is not supported}} */
 struct __declspec(12) S2 {};	/* expected-error {{__declspec attributes must be an identifier or string literal}} */
 struct __declspec("testing") S3 {}; /* expected-warning {{__declspec attribute '"testing"' is not supported}} */
 
+/* declspecs with arguments cannot have an empty argument list, even if the
+   arguments are optional. */
+__declspec(deprecated()) void dep_func_test(void); /* expected-error {{parentheses must be omitted if 'deprecated' attribute's argument list is empty}} */
+__declspec(deprecated) void dep_func_test2(void);
+__declspec(deprecated("")) void dep_func_test3(void);
+
 /* Ensure multiple declspec attributes are supported */
 struct __declspec(align(8) deprecated) S4 {};
 
 /* But multiple declspecs must still be legal */
-struct __declspec(deprecated frobble "testing") S5 {};  /* expected-warning {{unknown __declspec attribute 'frobble' ignored}} expected-warning {{__declspec attribute '"testing"' is not supported}} */
-struct __declspec(unknown(12) deprecated) S6 {};	/* expected-warning {{unknown __declspec attribute 'unknown' ignored}}*/
-
-struct S7 {
-	int foo() { return 12; }
-	__declspec(property(get=foo) deprecated) int t; // expected-note {{declared here}}
-};
-
-/* Technically, this is legal (though it does nothing) */
-__declspec() void quux( void ) {
-  struct S7 s;
-  int i = s.t;	/* expected-warning {{'t' is deprecated}} */
-}
+struct __declspec(deprecated frobble "testing") S5 {};  /* expected-warning {{__declspec attribute 'frobble' is not supported}} expected-warning {{__declspec attribute '"testing"' is not supported}} */
+struct __declspec(unknown(12) deprecated) S6 {};	/* expected-warning {{__declspec attribute 'unknown' is not supported}}*/
 
 int * __sptr psp;
 int * __uptr pup;
diff --git a/test/Parser/MicrosoftExtensions.cpp b/test/Parser/MicrosoftExtensions.cpp
index efb5c3c..0174ec2 100644
--- a/test/Parser/MicrosoftExtensions.cpp
+++ b/test/Parser/MicrosoftExtensions.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -std=c++11 -fsyntax-only -Wno-unused-value -Wmicrosoft -verify -fms-extensions -fms-compatibility -fdelayed-template-parsing
+// RUN: %clang_cc1 %s -triple i386-mingw32 -std=c++11 -fsyntax-only -Wno-unused-value -Wmicrosoft -verify -fms-extensions -fms-compatibility -fdelayed-template-parsing
 
 /* Microsoft attribute tests */
 [repeatable][source_annotation_attribute( Parameter|ReturnValue )]
@@ -50,7 +50,7 @@
 struct __declspec(uuid("0000000-0000-0000-Z234-000000000047")) uuid_attr_bad4 { };// expected-error {{uuid attribute contains a malformed GUID}}
 struct __declspec(uuid("000000000000-0000-1234-000000000047")) uuid_attr_bad5 { };// expected-error {{uuid attribute contains a malformed GUID}}
 
-
+__declspec(uuid("000000A0-0000-0000-C000-000000000046")) int i; // expected-warning {{'uuid' attribute only applies to classes}}
 
 struct __declspec(uuid("000000A0-0000-0000-C000-000000000046"))
 struct_with_uuid { };
@@ -227,104 +227,30 @@
 
 __int64 x7 = __int64(0);
 
-
-namespace If_exists_test {
-
-class IF_EXISTS {
-private:
-    typedef int Type;
-};
-
-int __if_exists_test() {
-  int b=0;
-  __if_exists(IF_EXISTS::Type) {
-     b++;
-     b++;
-  }
-  __if_exists(IF_EXISTS::Type_not) {
-     this wont compile.
-  }
-  __if_not_exists(IF_EXISTS::Type) {
-     this wont compile.
-  }
-  __if_not_exists(IF_EXISTS::Type_not) {
-     b++;
-     b++;
-  }
-}
-
-
-__if_exists(IF_EXISTS::Type) {
-  int var23;
-}
-
-__if_exists(IF_EXISTS::Type_not) {
- this wont compile.
-}
-
-__if_not_exists(IF_EXISTS::Type) {
- this wont compile.
-}
-
-__if_not_exists(IF_EXISTS::Type_not) {
-  int var244;
-}
-
-int __if_exists_init_list() {
-
-  int array1[] = {
-    0,
-    __if_exists(IF_EXISTS::Type) {2, }
-    3
-  };
-
-  int array2[] = {
-    0,
-    __if_exists(IF_EXISTS::Type_not) { this wont compile }
-    3
-  };
-
-  int array3[] = {
-    0,
-    __if_not_exists(IF_EXISTS::Type_not) {2, }
-    3
-  };
-
-  int array4[] = {
-    0,
-    __if_not_exists(IF_EXISTS::Type) { this wont compile }
-    3
-  };
-
-}
-
-
-class IF_EXISTS_CLASS_TEST {
-  __if_exists(IF_EXISTS::Type) {
-    // __if_exists, __if_not_exists can nest
-    __if_not_exists(IF_EXISTS::Type_not) {
-      int var123;
-    }
-    int var23;
-  }
-
-  __if_exists(IF_EXISTS::Type_not) {
-   this wont compile.
-  }
-
-  __if_not_exists(IF_EXISTS::Type) {
-   this wont compile.
-  }
-
-  __if_not_exists(IF_EXISTS::Type_not) {
-    int var244;
-  }
-};
-
-}
-
-
 int __identifier(generic) = 3;
+int __identifier(int) = 4;
+struct __identifier(class) { __identifier(class) *__identifier(for); };
+__identifier(class) __identifier(struct) = { &__identifier(struct) };
+
+int __identifier for; // expected-error {{missing '(' after '__identifier'}}
+int __identifier(else} = __identifier(for); // expected-error {{missing ')' after identifier}} expected-note {{to match this '('}}
+#define identifier_weird(x) __identifier(x
+int k = identifier_weird(if)); // expected-error {{use of undeclared identifier 'if'}}
+
+// This is a bit weird, but the alternative tokens aren't keywords, and this
+// behavior matches MSVC. FIXME: Consider supporting this anyway.
+extern int __identifier(and) r; // expected-error {{cannot convert '&&' token to an identifier}}
+
+void f() {
+  __identifier(() // expected-error {{cannot convert '(' token to an identifier}}
+  __identifier(void) // expected-error {{use of undeclared identifier 'void'}}
+  __identifier()) // expected-error {{cannot convert ')' token to an identifier}}
+  // FIXME: We should pick a friendlier display name for this token kind.
+  __identifier(1) // expected-error {{cannot convert <numeric_constant> token to an identifier}}
+  __identifier(+) // expected-error {{cannot convert '+' token to an identifier}}
+  __identifier("foo") // expected-error {{cannot convert <string_literal> token to an identifier}}
+  __identifier(;) // expected-error {{cannot convert ';' token to an identifier}}
+}
 
 class inline_definition_pure_spec {
    virtual int f() = 0 { return 0; }// expected-warning {{function definition with pure-specifier is a Microsoft extension}}
@@ -403,3 +329,35 @@
   sp.V11++;
   ++sp.V11;
 }
+
+//expected-warning@+1 {{C++ operator 'and' (aka '&&') used as a macro name}}
+#define and foo
+
+struct __declspec(uuid("00000000-0000-0000-C000-000000000046")) __declspec(novtable) IUnknown {}; // expected-warning{{__declspec attribute 'novtable' is not supported}}
+
+typedef bool (__stdcall __stdcall *blarg)(int);
+
+void local_callconv() {
+  bool (__stdcall *p)(int);
+}
+
+struct S7 {
+	int foo() { return 12; }
+	__declspec(property(get=foo) deprecated) int t; // expected-note {{'t' has been explicitly marked deprecated here}}
+};
+
+// Technically, this is legal (though it does nothing)
+__declspec() void quux( void ) {
+  struct S7 s;
+  int i = s.t;	// expected-warning {{'t' is deprecated}}
+}
+
+void *_alloca(int);
+
+void foo(void) {
+  __declspec(align(16)) int *buffer = (int *)_alloca(9);
+}
+
+template <int *>
+struct NullptrArg {};
+NullptrArg<nullptr> a;
diff --git a/test/Parser/MicrosoftExtensionsInlineAsm.c b/test/Parser/MicrosoftExtensionsInlineAsm.c
new file mode 100644
index 0000000..a973152
--- /dev/null
+++ b/test/Parser/MicrosoftExtensionsInlineAsm.c
@@ -0,0 +1,13 @@
+// REQUIRES: x86-registered-target
+// RUN: %clang_cc1 -triple i386-mingw32 -fsyntax-only -verify -fms-extensions  %s
+// expected-no-diagnostics
+
+void __forceinline InterlockedBitTestAndSet (long *Base, long Bit)
+{
+  __asm {
+    mov eax, Bit
+    mov ecx, Base
+    lock bts [ecx], eax
+    setc al
+  };
+}
diff --git a/test/Parser/altivec-csk-bool.c b/test/Parser/altivec-csk-bool.c
index ba6fa3b..c1c2539 100644
--- a/test/Parser/altivec-csk-bool.c
+++ b/test/Parser/altivec-csk-bool.c
@@ -1,4 +1,5 @@
-// RUN: %clang -target powerpc64-unknown-linux-gnu -maltivec -fsyntax-only %s
+// RUN: %clang_cc1 -triple powerpc64-unknown-linux-gnu -faltivec -fsyntax-only %s
+// RUN: %clang_cc1 -triple powerpc64le-unknown-linux-gnu -faltivec -fsyntax-only %s
 
 // PR16456: Verify that bool, true, false are treated as context-sensitive
 // keywords (and therefore available for use as identifiers) when in
diff --git a/test/Parser/altivec.c b/test/Parser/altivec.c
index 0bdc3dc..0b8147a 100644
--- a/test/Parser/altivec.c
+++ b/test/Parser/altivec.c
@@ -1,4 +1,6 @@
 // RUN: %clang_cc1 -triple=powerpc-apple-darwin8 -faltivec -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple=powerpc64-unknown-linux-gnu -faltivec -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple=powerpc64le-unknown-linux-gnu -faltivec -fsyntax-only -verify %s
 
 __vector char vv_c;
 __vector signed char vv_sc;
@@ -103,8 +105,8 @@
   gccvector unsigned int gv = v;
   gccvector int gvi = (gccvector int)v;
   __attribute__((vector_size(8))) unsigned int gv8;
-  gv8 = gccv;     // expected-error {{assigning to '__attribute__((__vector_size__(2 * sizeof(unsigned int)))) unsigned int' from incompatible type '__attribute__((__vector_size__(4 * sizeof(unsigned int)))) unsigned int'}}
-  av = gv8;       // expected-error {{assigning to '__vector unsigned int' from incompatible type '__attribute__((__vector_size__(2 * sizeof(unsigned int)))) unsigned int'}}
+  gv8 = gccv;     // expected-error {{assigning to '__attribute__((__vector_size__(2 * sizeof(unsigned int)))) unsigned int' (vector of 2 'unsigned int' values) from incompatible type '__attribute__((__vector_size__(4 * sizeof(unsigned int)))) unsigned int' (vector of 4 'unsigned int' values)}}
+  av = gv8;       // expected-error {{assigning to '__vector unsigned int' (vector of 4 'unsigned int' values) from incompatible type '__attribute__((__vector_size__(2 * sizeof(unsigned int)))) unsigned int' (vector of 2 'unsigned int' values)}}
 
   v = gccv;
   __vector unsigned int tv = gccv;
diff --git a/test/Parser/arm-windows-calling-convention-handling.c b/test/Parser/arm-windows-calling-convention-handling.c
new file mode 100644
index 0000000..7717aad
--- /dev/null
+++ b/test/Parser/arm-windows-calling-convention-handling.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -triple thumbv7-windows -fms-compatibility -fsyntax-only -verify %s
+
+int __cdecl cdecl(int a, int b, int c, int d) { // expected-warning {{calling convention '__cdecl' ignored for this target}}
+  return a + b + c + d;
+}
+
+float __stdcall stdcall(float a, float b, float c, float d) { // expected-warning {{calling convention '__stdcall' ignored for this target}}
+  return a + b + c + d;
+}
+
diff --git a/test/Parser/asm.c b/test/Parser/asm.c
index b95e08b..dabb010 100644
--- a/test/Parser/asm.c
+++ b/test/Parser/asm.c
@@ -23,3 +23,16 @@
 // <rdar://problem/10465079> - Don't crash on wide string literals in 'asm'.
 int foo asm (L"bar"); // expected-error {{cannot use wide string literal in 'asm'}}
 
+asm() // expected-error {{expected string literal in 'asm'}}
+// expected-error@-1 {{expected ';' after top-level asm block}}
+
+asm(; // expected-error {{expected string literal in 'asm'}}
+
+asm("") // expected-error {{expected ';' after top-level asm block}}
+
+// Unterminated asm strings at the end of the file were causing us to crash, so
+// this needs to be last. rdar://15624081
+// expected-warning@+3 {{missing terminating '"' character}}
+// expected-error@+2 {{expected string literal in 'asm'}}
+// expected-error@+1 {{expected ';' after top-level asm block}}
+asm("
diff --git a/test/Parser/attr-availability.c b/test/Parser/attr-availability.c
index 06bebba..d812296 100644
--- a/test/Parser/attr-availability.c
+++ b/test/Parser/attr-availability.c
@@ -20,6 +20,8 @@
 
 void f7() __attribute__((availability(macosx,message=L"wide"))); // expected-error {{expected string literal for optional message in 'availability' attribute}}
 
+void f8() __attribute__((availability(macosx,message="a" L"b"))); // expected-error {{expected string literal for optional message in 'availability' attribute}}
+
 // rdar://10095131
 enum E{
     gorf __attribute__((availability(macosx,introduced=8.5, message = 10.0))), // expected-error {{expected string literal for optional message in 'availability' attribute}}
diff --git a/test/Parser/attributes.c b/test/Parser/attributes.c
index 376ed2e..3d69c72 100644
--- a/test/Parser/attributes.c
+++ b/test/Parser/attributes.c
@@ -65,27 +65,27 @@
 
 
 int testFundef1(int *a) __attribute__((nonnull(1))) { // \
-    // expected-warning {{GCC does not allow nonnull attribute in this position on a function definition}}
+    // expected-warning {{GCC does not allow 'nonnull' attribute in this position on a function definition}}
   return *a;
 }
 
 // noreturn is lifted to type qualifier
 void testFundef2() __attribute__((noreturn)) { // \
-    // expected-warning {{GCC does not allow noreturn attribute in this position on a function definition}}
+    // expected-warning {{GCC does not allow 'noreturn' attribute in this position on a function definition}}
   testFundef2();
 }
 
 int testFundef3(int *a) __attribute__((nonnull(1), // \
-    // expected-warning {{GCC does not allow nonnull attribute in this position on a function definition}}
+    // expected-warning {{GCC does not allow 'nonnull' attribute in this position on a function definition}}
                                      pure)) { // \
-    // expected-warning {{GCC does not allow pure attribute in this position on a function definition}}
+    // expected-warning {{GCC does not allow 'pure' attribute in this position on a function definition}}
   return *a;
 }
 
 int testFundef4(int *a) __attribute__((nonnull(1))) // \
-    // expected-warning {{GCC does not allow nonnull attribute in this position on a function definition}}
+    // expected-warning {{GCC does not allow 'nonnull' attribute in this position on a function definition}}
                       __attribute((pure)) { // \
-    // expected-warning {{GCC does not allow pure attribute in this position on a function definition}}
+    // expected-warning {{GCC does not allow 'pure' attribute in this position on a function definition}}
   return *a;
 }
 
@@ -94,5 +94,4 @@
 
 __attribute__((pure)) int testFundef6(int a) { return a; }
 
-
-
+void deprecatedTestFun(void) __attribute__((deprecated()));
diff --git a/test/Parser/attributes.mm b/test/Parser/attributes.mm
index d92e3d3..024606b 100644
--- a/test/Parser/attributes.mm
+++ b/test/Parser/attributes.mm
@@ -14,11 +14,11 @@
 @interface EXP I @end // expected-error {{postfix attributes are not allowed on Objective-C directives, place them in front of '@interface'}}
 EXP @interface I2 @end
 
-@implementation EXP I @end // expected-error-re {{postfix attributes are not allowed on Objective-C directives$}}
+@implementation EXP I @end // expected-error-re {{postfix attributes are not allowed on Objective-C directives{{$}}}}
 // FIXME: Prefix attribute recovery skips until ';'
 EXP @implementation I2 @end; // expected-error {{prefix attribute must be followed by an interface or protocol}}
 
-@class EXP OC; // expected-error-re {{postfix attributes are not allowed on Objective-C directives$}}
+@class EXP OC; // expected-error-re {{postfix attributes are not allowed on Objective-C directives{{$}}}}
 EXP @class OC2; // expected-error {{prefix attribute must be followed by an interface or protocol}}
 
 @protocol EXP P @end // expected-error {{postfix attributes are not allowed on Objective-C directives, place them in front of '@protocol'}}
diff --git a/test/Parser/bad-control.c b/test/Parser/bad-control.c
index 480d81b..72614eb 100644
--- a/test/Parser/bad-control.c
+++ b/test/Parser/bad-control.c
@@ -7,3 +7,18 @@
 void foo2() { 
   continue; /* expected-error {{'continue' statement not in loop statement}} */
 }
+
+int pr8880_9 (int first) {
+  switch(({ if (first) { first = 0; break; } 1; })) { // expected-error {{'break' statement not in loop or switch statement}}
+  case 2: return 2;
+  default: return 0;
+  }
+}
+
+void pr8880_24() {
+  for (({break;});;); // expected-error {{'break' statement not in loop or switch statement}}
+}
+
+void pr8880_25() {
+  for (({continue;});;); // expected-error {{'continue' statement not in loop statement}}
+}
diff --git a/test/Parser/brackets.c b/test/Parser/brackets.c
new file mode 100644
index 0000000..2750d0e
--- /dev/null
+++ b/test/Parser/brackets.c
@@ -0,0 +1,79 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: cp %s %t
+// RUN: not %clang_cc1 -fixit %t -x c -DFIXIT
+// RUN: %clang_cc1 -fsyntax-only %t -x c -DFIXIT
+// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s -strict-whitespace
+
+void test1() {
+  int a[] = {0,1,1,2,3};
+  int []b = {0,1,4,9,16};
+  // expected-error@-1{{brackets go after the identifier}}
+  // CHECK: {{^}}  int []b = {0,1,4,9,16};
+  // CHECK: {{^}}      ~~ ^
+  // CHECK: {{^}}         []
+  // CHECK: fix-it:{{.*}}:{[[@LINE-5]]:7-[[@LINE-5]]:9}:""
+  // CHECK: fix-it:{{.*}}:{[[@LINE-6]]:10-[[@LINE-6]]:10}:"[]"
+
+  int c = a[0];
+  int d = b[0]; // No undeclared identifer error here.
+
+  int *e = a;
+  int *f = b; // No undeclared identifer error here.
+}
+
+struct S {
+  int [1][1]x;
+  // expected-error@-1{{brackets go after the identifier}}
+  // CHECK: {{^}}  int [1][1]x;
+  // CHECK: {{^}}      ~~~~~~ ^
+  // CHECK: {{^}}             [1][1]
+  // CHECK: fix-it:{{.*}}:{[[@LINE-5]]:7-[[@LINE-5]]:13}:""
+  // CHECK: fix-it:{{.*}}:{[[@LINE-6]]:14-[[@LINE-6]]:14}:"[1][1]"
+} s;
+
+#ifndef FIXIT
+void test2() {
+  int [][][];
+  // expected-error@-1{{expected identifier or '('}}
+  // CHECK: {{^}}  int [][][];
+  // CHECK: {{^}}      ^
+  // CHECK-NOT: fix-it
+  struct T {
+    int [];
+    // expected-error@-1{{expected member name or ';' after declaration specifiers}}
+    // CHECK: {{^}}    int [];
+    // CHECK: {{^}}    ~~~ ^
+    // CHECK-NOT: fix-it
+  };
+}
+
+void test3() {
+  int [5] *;
+  // expected-error@-1{{expected identifier or '('}}
+  // CHECK: {{^}}  int [5] *;
+  // CHECK: {{^}}           ^
+  // CHECK-NOT: fix-it
+  // expected-error@-5{{brackets go after the identifier}}
+  // CHECK: {{^}}  int [5] *;
+  // CHECK: {{^}}      ~~~~ ^
+  // CHECK: {{^}}          ()[5]
+  // CHECK: fix-it:{{.*}}:{[[@LINE-9]]:7-[[@LINE-9]]:11}:""
+  // CHECK: fix-it:{{.*}}:{[[@LINE-10]]:11-[[@LINE-10]]:11}:"("
+  // CHECK: fix-it:{{.*}}:{[[@LINE-11]]:12-[[@LINE-11]]:12}:")[5]"
+
+  int [5] * a;
+  // expected-error@-1{{brackets go after the identifier}}
+  // CHECK: {{^}}  int [5] * a;
+  // CHECK: {{^}}      ~~~~   ^
+  // CHECK: {{^}}          (  )[5]
+  // CHECK: fix-it:{{.*}}:{[[@LINE-5]]:7-[[@LINE-5]]:11}:""
+  // CHECK: fix-it:{{.*}}:{[[@LINE-6]]:11-[[@LINE-6]]:11}:"("
+  // CHECK: fix-it:{{.*}}:{[[@LINE-7]]:14-[[@LINE-7]]:14}:")[5]"
+
+  int *b[5] = a;  // expected-error{{}} a should not be corrected to type b
+
+  int (*c)[5] = a;  // a should be the same type as c
+}
+#endif
+
+// CHECK: 8 errors generated.
diff --git a/test/Parser/brackets.cpp b/test/Parser/brackets.cpp
new file mode 100644
index 0000000..f418c11
--- /dev/null
+++ b/test/Parser/brackets.cpp
@@ -0,0 +1,153 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: cp %s %t
+// RUN: not %clang_cc1 -fixit %t -x c++ -DFIXIT
+// RUN: %clang_cc1 -fsyntax-only %t -x c++ -DFIXIT
+// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s -strict-whitespace
+
+void test1() {
+  int a[] = {0,1,1,2,3};
+  int []b = {0,1,4,9,16};
+  // expected-error@-1{{brackets go after the unqualified-id}}
+  // CHECK: {{^}}  int []b = {0,1,4,9,16};
+  // CHECK: {{^}}      ~~ ^
+  // CHECK: {{^}}         []
+  // CHECK: fix-it:{{.*}}:{[[@LINE-5]]:7-[[@LINE-5]]:9}:""
+  // CHECK: fix-it:{{.*}}:{[[@LINE-6]]:10-[[@LINE-6]]:10}:"[]"
+
+  int c = a[0];
+  int d = b[0];  // No undeclared identifer error here.
+
+  int *e = a;
+  int *f = b;  // No undeclared identifer error here.
+
+  int[1] g[2];
+  // expected-error@-1{{brackets go after the unqualified-id}}
+  // CHECK: {{^}}  int[1] g[2];
+  // CHECK: {{^}}     ~~~     ^
+  // CHECK: {{^}}             [1]
+  // CHECK: fix-it:{{.*}}:{[[@LINE-5]]:6-[[@LINE-5]]:9}:""
+  // CHECK: fix-it:{{.*}}:{[[@LINE-6]]:14-[[@LINE-6]]:14}:"[1]"
+}
+
+void test2() {
+  int [3] (*a) = 0;
+  // expected-error@-1{{brackets go after the unqualified-id}}
+  // CHECK: {{^}}  int [3] (*a) = 0;
+  // CHECK: {{^}}      ~~~~    ^
+  // CHECK: {{^}}              [3]
+  // CHECK: fix-it:{{.*}}:{[[@LINE-5]]:7-[[@LINE-5]]:11}:""
+  // CHECK: fix-it:{{.*}}:{[[@LINE-6]]:15-[[@LINE-6]]:15}:"[3]"
+
+#ifndef FIXIT
+  // Make sure a is corrected to be like type y, instead of like type z.
+  int (*b)[3] = a;
+  int (*c[3]) = a;  // expected-error{{}}
+#endif
+}
+
+struct A {
+  static int [1][1]x;
+  // expected-error@-1{{brackets go after the unqualified-id}}
+  // CHECK: {{^}}  static int [1][1]x;
+  // CHECK: {{^}}             ~~~~~~ ^
+  // CHECK: {{^}}                    [1][1]
+  // CHECK: fix-it:{{.*}}:{[[@LINE-5]]:14-[[@LINE-5]]:20}:""
+  // CHECK: fix-it:{{.*}}:{[[@LINE-6]]:21-[[@LINE-6]]:21}:"[1][1]"
+};
+
+int [1][1]A::x = { {42} };
+// expected-error@-1{{brackets go after the unqualified-id}}
+// CHECK: {{^}}int [1][1]A::x = { {42} };
+// CHECK: {{^}}    ~~~~~~    ^
+// CHECK: {{^}}              [1][1]
+// CHECK: fix-it:{{.*}}:{[[@LINE-5]]:5-[[@LINE-5]]:11}:""
+// CHECK: fix-it:{{.*}}:{[[@LINE-6]]:15-[[@LINE-6]]:15}:"[1][1]"
+
+struct B { static int (*x)[5]; };
+int [5] *B::x = 0;
+// expected-error@-1{{brackets go after the unqualified-id}}
+// CHECK: {{^}}int [5] *B::x = 0;
+// CHECK: {{^}}    ~~~~     ^
+// CHECK: {{^}}        (    )[5]
+// CHECK: fix-it:{{.*}}:{[[@LINE-5]]:5-[[@LINE-5]]:9}:""
+// CHECK: fix-it:{{.*}}:{[[@LINE-6]]:9-[[@LINE-6]]:9}:"("
+// CHECK: fix-it:{{.*}}:{[[@LINE-7]]:14-[[@LINE-7]]:14}:")[5]"
+
+void test3() {
+  int [3] *a;
+  // expected-error@-1{{brackets go after the unqualified-id}}
+  // CHECK: {{^}}  int [3] *a;
+  // CHECK: {{^}}      ~~~~  ^
+  // CHECK: {{^}}          ( )[3]
+  // CHECK: fix-it:{{.*}}:{[[@LINE-5]]:7-[[@LINE-5]]:11}:""
+  // CHECK: fix-it:{{.*}}:{[[@LINE-6]]:11-[[@LINE-6]]:11}:"("
+  // CHECK: fix-it:{{.*}}:{[[@LINE-7]]:13-[[@LINE-7]]:13}:")[3]"
+
+  int (*b)[3] = a;  // no error
+}
+
+void test4() {
+  int [2] a;
+  // expected-error@-1{{brackets go after the unqualified-id}}
+  // CHECK: {{^}}  int [2] a;
+  // CHECK: {{^}}      ~~~~ ^
+  // CHECK: {{^}}           [2]
+  // CHECK: fix-it:{{.*}}:{[[@LINE-5]]:7-[[@LINE-5]]:11}:""
+  // CHECK: fix-it:{{.*}}:{[[@LINE-6]]:12-[[@LINE-6]]:12}:"[2]"
+
+  int [2] &b = a;
+  // expected-error@-1{{brackets go after the unqualified-id}}
+  // CHECK: {{^}}  int [2] &b = a;
+  // CHECK: {{^}}      ~~~~  ^
+  // CHECK: {{^}}          ( )[2]
+  // CHECK: fix-it:{{.*}}:{[[@LINE-5]]:7-[[@LINE-5]]:11}:""
+  // CHECK: fix-it:{{.*}}:{[[@LINE-6]]:11-[[@LINE-6]]:11}:"("
+  // CHECK: fix-it:{{.*}}:{[[@LINE-7]]:13-[[@LINE-7]]:13}:")[2]"
+
+}
+
+namespace test5 {
+#ifndef FIXIT
+int [][][];
+// expected-error@-1{{expected unqualified-id}}
+// CHECK: {{^}}int [][][];
+// CHECK: {{^}}    ^
+
+struct C {
+  int [];
+  // expected-error@-1{{expected member name or ';' after declaration specifiers}}
+  // CHECK: {{^}}  int [];
+  // CHECK: {{^}}  ~~~ ^
+};
+
+#endif
+}
+
+namespace test6 {
+struct A {
+  static int arr[3];
+};
+int [3] ::test6::A::arr = {1,2,3};
+// expected-error@-1{{brackets go after the unqualified-id}}
+// CHECK: {{^}}int [3] ::test6::A::arr = {1,2,3};
+// CHECK: {{^}}    ~~~~               ^
+// CHECK: {{^}}                       [3]
+// CHECK: fix-it:{{.*}}:{[[@LINE-5]]:5-[[@LINE-5]]:9}:""
+// CHECK: fix-it:{{.*}}:{[[@LINE-6]]:24-[[@LINE-6]]:24}:"[3]"
+
+}
+
+namespace test7 {
+class A{};
+void test() {
+  int [3] A::*a;
+  // expected-error@-1{{brackets go after the unqualified-id}}
+  // CHECK: {{^}}  int [3] A::*a;
+  // CHECK: {{^}}      ~~~~     ^
+  // CHECK: {{^}}          (    )[3]
+  // CHECK: fix-it:{{.*}}:{[[@LINE-5]]:7-[[@LINE-5]]:11}:""
+  // CHECK: fix-it:{{.*}}:{[[@LINE-6]]:11-[[@LINE-6]]:11}:"("
+  // CHECK: fix-it:{{.*}}:{[[@LINE-7]]:16-[[@LINE-7]]:16}:")[3]"
+}
+}
+// CHECK: 14 errors generated.
diff --git a/test/Parser/builtin_classify_type.c b/test/Parser/builtin_classify_type.c
index ff483b2..63fd8e2 100644
--- a/test/Parser/builtin_classify_type.c
+++ b/test/Parser/builtin_classify_type.c
@@ -9,7 +9,7 @@
   struct foo s;
 
   static int ary[__builtin_classify_type(a)];
-  static int ary2[(__builtin_classify_type)(a)]; // expected-error{{variable length array declaration can not have 'static' storage duration}}
+  static int ary2[(__builtin_classify_type)(a)]; // expected-error{{variable length array declaration cannot have 'static' storage duration}}
   static int ary3[(*__builtin_classify_type)(a)]; // expected-error{{builtin functions must be directly called}}
 
   int result;
diff --git a/test/Parser/check-objc2-syntax-1.m b/test/Parser/check-objc2-syntax-1.m
index 9aff963..364f826 100644
--- a/test/Parser/check-objc2-syntax-1.m
+++ b/test/Parser/check-objc2-syntax-1.m
@@ -1,5 +1,7 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
-// expected-no-diagnostics
+
+// rdar://15505492
+@import Foundation; // expected-error {{use of '@import' when modules are disabled}}
 
 @interface Subclass 
 + (int)magicNumber;
diff --git a/test/Parser/compound_literal.c b/test/Parser/compound_literal.c
index 9a0e4a6..0054499 100644
--- a/test/Parser/compound_literal.c
+++ b/test/Parser/compound_literal.c
@@ -1,6 +1,8 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -x c++ %s
 // expected-no-diagnostics
 int main() {
   char *s;
-  s = (char []){"whatever"}; 
+  s = (char []){"whatever"};
+  s = (char(*)){s};
 }
diff --git a/test/Parser/cuda-kernel-call-c++11.cu b/test/Parser/cuda-kernel-call-c++11.cu
new file mode 100644
index 0000000..8f833f7
--- /dev/null
+++ b/test/Parser/cuda-kernel-call-c++11.cu
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
+
+template<typename> struct S {};
+template<typename> void f();
+
+
+void foo(void) {
+  // In C++11 mode, all of these are expected to parse correctly, and the CUDA
+  // language should not interfere with that.
+
+  // expected-no-diagnostics
+
+  S<S<S<int>>> s3;
+
+  S<S<S<S<int>>>> s4;
+
+  S<S<S<S<S<int>>>>> s5;
+
+  (void)(&f<S<S<int>>>==0);
+}
diff --git a/test/Parser/cuda-kernel-call.cu b/test/Parser/cuda-kernel-call.cu
index 92e46e3..1970c55 100644
--- a/test/Parser/cuda-kernel-call.cu
+++ b/test/Parser/cuda-kernel-call.cu
@@ -10,7 +10,8 @@
 
   foo<<<>>>();  // expected-error {{expected expression}}
 
-  S<S<S<int>>> s; // expected-error 2{{use '> >'}}
+  // The following two are parse errors because -std=c++11 is not enabled.
 
+  S<S<S<int>>> s; // expected-error 2{{use '> >'}}
   (void)(&f<S<S<int>>>==0); // expected-error 2{{use '> >'}}
 }
diff --git a/test/Parser/cxx-altivec.cpp b/test/Parser/cxx-altivec.cpp
index be00e49..565decc 100644
--- a/test/Parser/cxx-altivec.cpp
+++ b/test/Parser/cxx-altivec.cpp
@@ -1,4 +1,6 @@
 // RUN: %clang_cc1 -triple=powerpc-apple-darwin8 -faltivec -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -triple=powerpc64-unknown-linux-gnu -faltivec -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -triple=powerpc64le-unknown-linux-gnu -faltivec -fsyntax-only -verify -std=c++11 %s
 
 __vector char vv_c;
 __vector signed char vv_sc;
@@ -93,8 +95,8 @@
   gccvector unsigned int gv = v;
   gccvector int gvi = (gccvector int)v;
   __attribute__((vector_size(8))) unsigned int gv8;
-  gv8 = gccv;     // expected-error {{assigning to '__attribute__((__vector_size__(2 * sizeof(unsigned int)))) unsigned int' from incompatible type '__attribute__((__vector_size__(4 * sizeof(unsigned int)))) unsigned int'}}
-  av = gv8;       // expected-error {{assigning to '__vector unsigned int' from incompatible type '__attribute__((__vector_size__(2 * sizeof(unsigned int)))) unsigned int'}}
+  gv8 = gccv;     // expected-error {{assigning to '__attribute__((__vector_size__(2 * sizeof(unsigned int)))) unsigned int' (vector of 2 'unsigned int' values) from incompatible type '__attribute__((__vector_size__(4 * sizeof(unsigned int)))) unsigned int' (vector of 4 'unsigned int' values)}}
+  av = gv8;       // expected-error {{assigning to '__vector unsigned int' (vector of 4 'unsigned int' values) from incompatible type '__attribute__((__vector_size__(2 * sizeof(unsigned int)))) unsigned int' (vector of 2 'unsigned int' values)}}
 
   v = gccv;
   __vector unsigned int tv = gccv;
diff --git a/test/Parser/cxx-ambig-decl-expr-xfail.cpp b/test/Parser/cxx-ambig-decl-expr-xfail.cpp
index ac4accb..85c3468 100644
--- a/test/Parser/cxx-ambig-decl-expr-xfail.cpp
+++ b/test/Parser/cxx-ambig-decl-expr-xfail.cpp
@@ -1,5 +1,7 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 // XFAIL: *
+// FIXME: This is PR7655
+
 struct X { 
   template<typename T> X(T);
   X(int, int);
diff --git a/test/Parser/cxx-casting.cpp b/test/Parser/cxx-casting.cpp
index 69680e4..d2c97b8 100644
--- a/test/Parser/cxx-casting.cpp
+++ b/test/Parser/cxx-casting.cpp
@@ -90,5 +90,22 @@
               // expected-error {{expected unqualified-id}}
 }
 
+// Ensure that a C-style cast doesn't turn off colon protection.
+void PR19748() {
+  struct A {};
+  int A = 0, b;
+  int test1 = true ? (int)A : b;
+
+  struct f {};
+  extern B f(), (*p)();
+  (true ? (B(*)())f : p)();
+}
+
+void PR19751(int n) {
+  struct T { void operator++(int); };
+  (T())++; // ok, not an ill-formed cast to function type
+  (T())++n; // expected-error {{C-style cast from 'int' to 'T ()' is not allowed}}
+}
+
 // PR13619. Must be at end of file.
 int n = reinterpret_cast // expected-error {{expected '<'}} expected-error {{expected ';'}}
diff --git a/test/Parser/cxx-class.cpp b/test/Parser/cxx-class.cpp
index 5fac797..80cd828 100644
--- a/test/Parser/cxx-class.cpp
+++ b/test/Parser/cxx-class.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic -fcxx-exceptions %s
 class C;
 class C {
 public:
@@ -113,6 +113,32 @@
   }
 }
 
+class pr16989 {
+  void tpl_mem(int *) {
+    return;
+    class C2 {
+      void f();
+    };
+    void C2::f() {} // expected-error{{function definition is not allowed here}}
+  };
+};
+
+namespace CtorErrors {
+  struct A {
+    A(NonExistent); // expected-error {{unknown type name 'NonExistent'}}
+  };
+  struct B {
+    B(NonExistent) : n(0) {} // expected-error {{unknown type name 'NonExistent'}}
+    int n;
+  };
+  struct C {
+    C(NonExistent) try {} catch (...) {} // expected-error {{unknown type name 'NonExistent'}}
+  };
+  struct D {
+    D(NonExistent) {} // expected-error {{unknown type name 'NonExistent'}}
+  };
+}
+
 // PR11109 must appear at the end of the source file
 class pr11109r3 { // expected-note{{to match this '{'}}
   public // expected-error{{expected ':'}} expected-error{{expected '}'}} expected-error{{expected ';' after class}}
diff --git a/test/Parser/cxx-decl.cpp b/test/Parser/cxx-decl.cpp
index 0627250..be79eb4 100644
--- a/test/Parser/cxx-decl.cpp
+++ b/test/Parser/cxx-decl.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -fsyntax-only -triple i386-linux -pedantic -fcxx-exceptions -fexceptions %s
+// RUN: %clang_cc1 -verify -fsyntax-only -triple i386-linux -pedantic-errors -fcxx-exceptions -fexceptions %s
 
-const char const *x10; // expected-warning {{duplicate 'const' declaration specifier}}
+const char const *x10; // expected-error {{duplicate 'const' declaration specifier}}
 
 int x(*g); // expected-error {{use of undeclared identifier 'g'}}
 
@@ -46,7 +46,7 @@
   void foo() __asm__("baz");
 };
 
-enum { fooenum = 1, }; // expected-warning {{commas at the end of enumerator lists are a C++11 extension}}
+enum { fooenum = 1, }; // expected-error {{commas at the end of enumerator lists are a C++11 extension}}
 
 struct a {
   int Type : fooenum;
@@ -81,7 +81,7 @@
   (global5),
   *global6,
   &global7 = global1,
-  &&global8 = static_cast<int&&>(global1), // expected-warning 2{{rvalue reference}}
+  &&global8 = static_cast<int&&>(global1), // expected-error 2{{rvalue reference}}
   S::a,
   global9,
   global10 = 0,
@@ -108,9 +108,9 @@
 class Class1;
 
 class Class2 {
-}  // no ;
+} // expected-error {{expected ';' after class}}
 
-typedef Class1<Class2> Type1; // expected-error {{cannot combine with previous 'class' declaration specifier}}
+typedef Class1<Class2> Type1;
 
 // rdar : // 8307865
 struct CodeCompleteConsumer {
@@ -181,7 +181,7 @@
 }
 
 namespace PR15017 {
-  template<typename T = struct X { int i; }> struct S {}; // expected-error {{'PR15017::X' can not be defined in a type specifier}}
+  template<typename T = struct X { int i; }> struct S {}; // expected-error {{'PR15017::X' cannot be defined in a type specifier}}
 }
 
 // Ensure we produce at least some diagnostic for attributes in C++98.
@@ -212,14 +212,14 @@
   template<typename T> struct X {};
   X<int N> x; // expected-error {{type-id cannot have a name}}
 
-  using T = int (*T)(); // expected-error {{type-id cannot have a name}} expected-warning {{C++11}}
+  using T = int (*T)(); // expected-error {{type-id cannot have a name}} expected-error {{C++11}}
 }
 
 namespace PR17255 {
 void foo() {
   typename A::template B<>; // expected-error {{use of undeclared identifier 'A'}} \
                             // expected-error {{expected a qualified name after 'typename'}} \
-                            // expected-warning {{'template' keyword outside of a template}}
+                            // expected-error {{'template' keyword outside of a template}}
 }
 }
 
@@ -232,6 +232,13 @@
   FooBar::~FooBar() {} // expected-error {{undeclared}} expected-error {{expected the class name}}
 }
 
+namespace DuplicateFriend {
+  struct A {
+    friend void friend f(); // expected-warning {{duplicate 'friend' declaration specifier}}
+    friend struct B friend; // expected-warning {{duplicate 'friend' declaration specifier}}
+  };
+}
+
 // PR8380
 extern ""      // expected-error {{unknown linkage language}}
 test6a { ;// expected-error {{C++ requires a type specifier for all declarations}} \
diff --git a/test/Parser/cxx-friend.cpp b/test/Parser/cxx-friend.cpp
index a3b89cc..ace0ff2 100644
--- a/test/Parser/cxx-friend.cpp
+++ b/test/Parser/cxx-friend.cpp
@@ -30,7 +30,7 @@
   void f(A *a) { a->f(); }
 };
 
-void bar() {} // expected-note {{previous definition is here}}
+inline void bar() {} // expected-note {{previous definition is here}}
 class E {
   friend void bar() {} // expected-error {{redefinition of 'bar'}}
 };
diff --git a/test/Parser/cxx-reference.cpp b/test/Parser/cxx-reference.cpp
index d21412c..b62638b 100644
--- a/test/Parser/cxx-reference.cpp
+++ b/test/Parser/cxx-reference.cpp
@@ -10,7 +10,7 @@
 
 typedef int & A;
 
-void g(const A aref) {
+void g(const A aref) { // expected-warning {{'const' qualifier on reference type 'A' (aka 'int &') has no effect}}
 }
 
 int & const X = val; // expected-error {{'const' qualifier may not be applied to a reference}}
diff --git a/test/Parser/cxx-template-argument.cpp b/test/Parser/cxx-template-argument.cpp
index 8bf2a4f..bbd53b2 100644
--- a/test/Parser/cxx-template-argument.cpp
+++ b/test/Parser/cxx-template-argument.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s -fdelayed-template-parsing
 
 template<typename T> struct A {};
 
diff --git a/test/Parser/cxx-template-decl.cpp b/test/Parser/cxx-template-decl.cpp
index 81269ce..8b2b120 100644
--- a/test/Parser/cxx-template-decl.cpp
+++ b/test/Parser/cxx-template-decl.cpp
@@ -1,4 +1,8 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s -fdelayed-template-parsing -DDELAYED_TEMPLATE_PARSING
+// RUN: %clang_cc1 -fsyntax-only -verify -std=gnu++1z %s
+
+
 
 // Errors
 export class foo { };   // expected-error {{expected template}}
@@ -21,6 +25,11 @@
 template <template <typename> > struct Err2;       // expected-error {{template template parameter requires 'class' after the parameter list}}
 template <template <typename> Foo> struct Err3;    // expected-error {{template template parameter requires 'class' after the parameter list}}
 
+template <template <typename> typename Foo> struct Cxx1z;
+#if __cplusplus <= 201402L
+// expected-warning@-2 {{extension}}
+#endif
+
 // Template function declarations
 template <typename T> void foo();
 template <typename T, typename U> void foo();
@@ -102,7 +111,11 @@
 template<int Size> 
 void f(int& i) {
   i = Size;
+ #ifdef DELAYED_TEMPLATE_PARSING
+  Size = i; 
+ #else
   Size = i; // expected-error{{expression is not assignable}}
+ #endif
 }
 
 template<typename T>
@@ -127,3 +140,73 @@
   template <typename T>
   void N::bar(typename T::x) { }
 }
+
+// This PR occurred only in template parsing mode.
+namespace PR17637 {
+template <int>
+struct L {
+  template <typename T>
+  struct O {
+    template <typename U>
+    static void Fun(U);
+  };
+};
+
+template <int k>
+template <typename T>
+template <typename U>
+void L<k>::O<T>::Fun(U) {}
+
+void Instantiate() { L<0>::O<int>::Fun(0); }
+
+}
+
+namespace explicit_partial_specializations {
+typedef char (&oneT)[1];
+typedef char (&twoT)[2];
+typedef char (&threeT)[3];
+typedef char (&fourT)[4];
+typedef char (&fiveT)[5];
+typedef char (&sixT)[6];
+
+char one[1];
+char two[2];
+char three[3];
+char four[4];
+char five[5];
+char six[6];
+
+template<bool b> struct bool_ { typedef int type; };
+template<> struct bool_<false> {  };
+
+#define XCAT(x,y) x ## y
+#define CAT(x,y) XCAT(x,y)
+#define sassert(_b_) bool_<(_b_)>::type CAT(var, __LINE__);
+
+
+template <int>
+struct L {
+  template <typename T>
+  struct O {
+    template <typename U>
+    static oneT Fun(U);
+    
+  };
+};
+template <int k>
+template <typename T>
+template <typename U>
+oneT L<k>::O<T>::Fun(U) { return one; }
+
+template<>
+template<>
+template<typename U>
+oneT L<0>::O<char>::Fun(U) { return one; }
+
+
+void Instantiate() { 
+  sassert(sizeof(L<0>::O<int>::Fun(0)) == sizeof(one)); 
+  sassert(sizeof(L<0>::O<char>::Fun(0)) == sizeof(one));
+}
+
+}
diff --git a/test/Parser/cxx-using-declaration.cpp b/test/Parser/cxx-using-declaration.cpp
index 320fd09..17237a3 100644
--- a/test/Parser/cxx-using-declaration.cpp
+++ b/test/Parser/cxx-using-declaration.cpp
@@ -33,7 +33,7 @@
     template <typename TYPE> int funcE(TYPE arg) { return(arg); }
 }
 
-using E::funcE<int>; // expected-error{{using declaration can not refer to a template specialization}}
+using E::funcE<int>; // expected-error{{using declaration cannot refer to a template specialization}}
 
 namespace F {
     struct X;
diff --git a/test/Parser/cxx0x-ambig.cpp b/test/Parser/cxx0x-ambig.cpp
index 4c22ed3..b06f432 100644
--- a/test/Parser/cxx0x-ambig.cpp
+++ b/test/Parser/cxx0x-ambig.cpp
@@ -48,7 +48,7 @@
   };
   // This could be a bit-field.
   struct S2 {
-    enum E : T { a = 1, b = 2, c = 3, 4 }; // expected-error {{non-integral type}} expected-error {{expected '}'}} expected-note {{to match}}
+    enum E : T { a = 1, b = 2, c = 3, 4 }; // expected-error {{non-integral type}} expected-error {{expected identifier}}
   };
   struct S3 {
     enum E : int { a = 1, b = 2, c = 3, d }; // ok, defines an enum
@@ -64,7 +64,7 @@
   };
   // This could be a bit-field.
   struct S6 {
-    enum E : int { 1 }; // expected-error {{expected '}'}} expected-note {{to match}}
+    enum E : int { 1 }; // expected-error {{expected identifier}}
   };
 
   struct U {
diff --git a/test/Parser/cxx0x-attributes.cpp b/test/Parser/cxx0x-attributes.cpp
index b02add9..f8abc76 100644
--- a/test/Parser/cxx0x-attributes.cpp
+++ b/test/Parser/cxx0x-attributes.cpp
@@ -48,13 +48,13 @@
 alignas(8) int aligned_attr;
 [[test::valid(for 42 [very] **** '+' symbols went on a trip and had a "good"_time; the end.)]] int garbage_attr; // expected-warning {{unknown attribute 'valid' ignored}}
 [[,,,static, class, namespace,, inline, constexpr, mutable,, bitand, bitor::compl(!.*_ Cx.!U^*R),,,]] int more_garbage_attr; // expected-warning {{unknown attribute 'static' ignored}} \
-	// expected-warning {{unknown attribute 'class' ignored}} \
-	// expected-warning {{unknown attribute 'namespace' ignored}} \
-	// expected-warning {{unknown attribute 'inline' ignored}} \
-	// expected-warning {{unknown attribute 'constexpr' ignored}} \
-	// expected-warning {{unknown attribute 'mutable' ignored}} \
-	// expected-warning {{unknown attribute 'bitand' ignored}} \
-        // expected-warning {{unknown attribute 'compl' ignored}}
+    // expected-warning {{unknown attribute 'class' ignored}} \
+    // expected-warning {{unknown attribute 'namespace' ignored}} \
+    // expected-warning {{unknown attribute 'inline' ignored}} \
+    // expected-warning {{unknown attribute 'constexpr' ignored}} \
+    // expected-warning {{unknown attribute 'mutable' ignored}} \
+    // expected-warning {{unknown attribute 'bitand' ignored}} \
+    // expected-warning {{unknown attribute 'compl' ignored}}
 [[u8"invalid!"]] int invalid_string_attr; // expected-error {{expected ']'}}
 void fn_attr () [[]];
 void noexcept_fn_attr () noexcept [[]];
@@ -78,11 +78,11 @@
 class c final [(int){0}];
 
 class base {};
-class [[]] [[]] final_class 
+class [[]] [[]] final_class
   alignas(float) [[]] final // expected-error {{an attribute list cannot appear here}}
   alignas(float) [[]] [[]] alignas(float): base{}; // expected-error {{an attribute list cannot appear here}}
 
-class [[]] [[]] final_class_another 
+class [[]] [[]] final_class_another
   [[]] [[]] alignas(16) final // expected-error {{an attribute list cannot appear here}}
   [[]] [[]] alignas(16) [[]]{}; // expected-error {{an attribute list cannot appear here}}
 
@@ -120,7 +120,7 @@
 
 [[]] using ns::i; // expected-error {{an attribute list cannot appear here}}
 [[unknown]] using namespace ns; // expected-warning {{unknown attribute 'unknown' ignored}}
-[[noreturn]] using namespace ns; // expected-error {{'noreturn' attribute only applies to functions and methods}}
+[[noreturn]] using namespace ns; // expected-error {{'noreturn' attribute only applies to functions}}
 
 using [[]] alignas(4) [[]] ns::i; // expected-error {{an attribute list cannot appear here}}
 using [[]] alignas(4) [[]] foobar = int; // expected-error {{an attribute list cannot appear here}} expected-error {{'alignas' attribute only applies to}}
@@ -146,7 +146,7 @@
 using ns::i [[]]; // expected-error {{an attribute list cannot appear here}}
 using [[]] ns::i; // expected-error {{an attribute list cannot appear here}}
 using T [[unknown]] = int; // expected-warning {{unknown attribute 'unknown' ignored}}
-using T [[noreturn]] = int; // expected-error {{'noreturn' attribute only applies to functions and methods}}
+using T [[noreturn]] = int; // expected-error {{'noreturn' attribute only applies to functions}}
 using V = int; // expected-note {{previous}}
 using V [[gnu::vector_size(16)]] = int; // expected-error {{redefinition with different types}}
 
@@ -210,16 +210,16 @@
     [[]] continue;
   } while (0);
   [[]] while (0);
-  
+
   [[]] switch (i) {
     [[]] case 0:
     [[]] default:
       [[]] break;
   }
-  
+
   [[]] goto there;
   [[]] there:
-  
+
   [[]] try {
   } [[]] catch (...) { // expected-error {{an attribute list cannot appear here}}
   }
@@ -281,7 +281,8 @@
 
 namespace arguments {
   void f[[gnu::format(printf, 1, 2)]](const char*, ...);
-  void g() [[unknown::foo(arguments of attributes from unknown namespace other than 'gnu' namespace are ignored... blah...)]]; // expected-warning {{unknown attribute 'foo' ignored}}
+  void g() [[unknown::foo(ignore arguments for unknown attributes, even with symbols!)]]; // expected-warning {{unknown attribute 'foo' ignored}}
+  [[deprecated("with argument")]] int i;
 }
 
 // Forbid attributes on decl specifiers.
@@ -297,7 +298,7 @@
 int v5()[[gnu::unused]]; // expected-warning {{attribute 'unused' ignored}}
 
 [[attribute_declaration]]; // expected-warning {{unknown attribute 'attribute_declaration' ignored}}
-[[noreturn]]; // expected-error {{'noreturn' attribute only applies to functions and methods}}
+[[noreturn]]; // expected-error {{'noreturn' attribute only applies to functions}}
 [[carries_dependency]]; // expected-error {{'carries_dependency' attribute only applies to functions, methods, and parameters}}
 
 class A {
@@ -309,8 +310,10 @@
   // GCC's tokenizer treats const and __const as the same token.
   [[gnu::const]] int *f1();
   [[gnu::__const]] int *f2();
+  [[gnu::__const__]] int *f3();
   void f(const int *);
   void g() { f(f1()); f(f2()); }
+  void h() { f(f3()); }
 }
 
 namespace GccASan {
@@ -319,3 +322,10 @@
   [[gnu::no_address_safety_analysis]] void f3();
   [[gnu::no_sanitize_address]] void f4();
 }
+
+namespace {
+  [[deprecated]] void bar();
+  [[deprecated("hello")]] void baz();
+  [[deprecated()]] void foo(); // expected-error {{parentheses must be omitted if 'deprecated' attribute's argument list is empty}}
+  [[gnu::deprecated()]] void quux();
+}
diff --git a/test/Parser/cxx0x-decl.cpp b/test/Parser/cxx0x-decl.cpp
index 257c56c..a0334cd 100644
--- a/test/Parser/cxx0x-decl.cpp
+++ b/test/Parser/cxx0x-decl.cpp
@@ -104,3 +104,21 @@
   using [[gnu::aligned(1)]] T = int; // expected-error {{an attribute list cannot appear here}}
   using T = int [[gnu::aligned(1)]]; // expected-error {{'aligned' attribute cannot be applied to types}}
 }
+
+namespace DuplicateSpecifier {
+  constexpr constexpr int f(); // expected-warning {{duplicate 'constexpr' declaration specifier}}
+  constexpr int constexpr a = 0; // expected-warning {{duplicate 'constexpr' declaration specifier}}
+
+  struct A {
+    friend constexpr int constexpr friend f(); // expected-warning {{duplicate 'friend' declaration specifier}} \
+                                               // expected-warning {{duplicate 'constexpr' declaration specifier}}
+    friend struct A friend; // expected-warning {{duplicate 'friend'}} expected-error {{'friend' must appear first}}
+  };
+}
+
+struct Base { virtual void f() = 0; virtual void g() = 0; virtual void h() = 0; };
+struct MemberComponentOrder : Base {
+  void f() override __asm__("foobar") __attribute__(( )) {}
+  void g() __attribute__(( )) override;
+  void h() __attribute__(( )) override {}
+};
diff --git a/test/Parser/cxx0x-for-range.cpp b/test/Parser/cxx0x-for-range.cpp
index f920ef9..c3276eb 100644
--- a/test/Parser/cxx0x-for-range.cpp
+++ b/test/Parser/cxx0x-for-range.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits -std=c++11 %s 2>&1 | FileCheck %s
 
 template<typename T, typename U>
 struct pair {};
@@ -28,3 +28,35 @@
 
   return n;
 }
+
+namespace PR19176 {
+struct Vector {
+  struct iterator {
+    int &operator*();
+    iterator &operator++();
+    iterator &operator++(int);
+    bool operator==(const iterator &) const;
+  };
+  iterator begin();
+  iterator end();
+};
+
+void f() {
+  Vector v;
+  int a[] = {1, 2, 3, 4};
+  for (auto foo   =     a) // expected-error {{range-based 'for' statement uses ':', not '='}}
+    // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:19-[[@LINE-1]]:20}:":"
+    (void)foo;
+  for (auto i
+      =
+      v) // expected-error@-1 {{range-based 'for' statement uses ':', not '='}}
+    // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:7-[[@LINE-2]]:8}:":"
+    (void)i;
+#define FORRANGE(v, a) for (DECLVARWITHINIT(v) a)  // expected-note {{expanded from macro}}
+#define DECLAUTOVAR(v) auto v
+#define DECLVARWITHINIT(v) DECLAUTOVAR(v) =  // expected-note {{expanded from macro}}
+  FORRANGE(i, a) {  // expected-error {{range-based 'for' statement uses ':', not '='}}
+
+  }
+}
+}
diff --git a/test/Parser/cxx0x-lambda-expressions.cpp b/test/Parser/cxx0x-lambda-expressions.cpp
index 289d03c..8cfe7f3 100644
--- a/test/Parser/cxx0x-lambda-expressions.cpp
+++ b/test/Parser/cxx0x-lambda-expressions.cpp
@@ -2,6 +2,8 @@
 
 enum E { e };
 
+constexpr int id(int n) { return n; }
+
 class C {
 
   int f() {
@@ -34,12 +36,18 @@
     typedef int T; 
     const int b = 0; 
     const int c = 1;
-    int a1[1] = {[b] (T()) {}}; // expected-error{{no viable conversion from '<lambda}}
+    int d;
+    int a1[1] = {[b] (T()) {}}; // expected-error{{no viable conversion from '(lambda}}
     int a2[1] = {[b] = 1 };
-    int a3[1] = {[b,c] = 1 }; // expected-error{{expected body of lambda expression}}
+    int a3[1] = {[b,c] = 1 }; // expected-error{{expected ']'}} expected-note {{to match}}
     int a4[1] = {[&b] = 1 }; // expected-error{{integral constant expression must have integral or unscoped enumeration type, not 'const int *'}}
     int a5[3] = { []{return 0;}() };
     int a6[1] = {[this] = 1 }; // expected-error{{integral constant expression must have integral or unscoped enumeration type, not 'C *'}}
+    int a7[1] = {[d(0)] { return d; } ()}; // expected-warning{{extension}}
+    int a8[1] = {[d = 0] { return d; } ()}; // expected-warning{{extension}}
+    int a9[1] = {[d = 0] = 1}; // expected-error{{is not an integral constant expression}}
+    int a10[1] = {[id(0)] { return id; } ()}; // expected-warning{{extension}}
+    int a11[1] = {[id(0)] = 1};
   }
 
   void delete_lambda(int *p) {
@@ -64,4 +72,22 @@
       return x + 2;
     } ();
   }
+
+  void attributes() {
+    [] [[]] {}; // expected-error {{lambda requires '()' before attribute specifier}}
+    [] __attribute__((noreturn)) {}; // expected-error {{lambda requires '()' before attribute specifier}}
+    []() [[]]
+      mutable {}; // expected-error {{expected body of lambda expression}}
+
+    []() [[]] {};
+    []() [[]] -> void {};
+    []() mutable [[]] -> void {};
+    []() mutable noexcept [[]] -> void {};
+
+    // Testing GNU-style attributes on lambdas -- the attribute is specified
+    // before the mutable specifier instead of after (unlike C++11).
+    []() __attribute__((noreturn)) mutable { while(1); };
+    []() mutable
+      __attribute__((noreturn)) { while(1); }; // expected-error {{expected body of lambda expression}}
+  }
 };
diff --git a/test/Parser/cxx0x-member-initializers.cpp b/test/Parser/cxx0x-member-initializers.cpp
index 43e99b1..4d14394 100644
--- a/test/Parser/cxx0x-member-initializers.cpp
+++ b/test/Parser/cxx0x-member-initializers.cpp
@@ -37,3 +37,7 @@
   bool d1 = T1<int, T1<int, int>>::V < 3, d2;
   T1<int, int()> e = T1<int, int()>();
 };
+
+struct PR19993 {
+  static int n = delete; // expected-error {{only functions can have deleted definitions}}
+};
diff --git a/test/Parser/cxx0x-rvalue-reference.cpp b/test/Parser/cxx0x-rvalue-reference.cpp
index e57e601..613b828 100644
--- a/test/Parser/cxx0x-rvalue-reference.cpp
+++ b/test/Parser/cxx0x-rvalue-reference.cpp
@@ -3,7 +3,7 @@
 int && r1(int &&a);
 
 typedef int && R;
-void r2(const R a) {
+void r2(const R a) { // expected-warning {{'const' qualifier on reference type 'R' (aka 'int &&') has no effect}}
   int & &&ar = a; // expected-error{{'ar' declared as a reference to a reference}}
 }
 
diff --git a/test/Parser/cxx11-type-specifier.cpp b/test/Parser/cxx11-type-specifier.cpp
index c66462a..1676623 100644
--- a/test/Parser/cxx11-type-specifier.cpp
+++ b/test/Parser/cxx11-type-specifier.cpp
@@ -15,8 +15,8 @@
 
   // These parse as type definitions, not as type references with braced
   // initializers. Sad but true...
-  (void) new struct S {}; // expected-error{{'S' can not be defined in a type specifier}}
-  (void) new enum E { e }; // expected-error{{'E' can not be defined in a type specifier}}
+  (void) new struct S {}; // expected-error{{'S' cannot be defined in a type specifier}}
+  (void) new enum E { e }; // expected-error{{'E' cannot be defined in a type specifier}}
 }
 
 // And for trailing-type-specifier-seq
diff --git a/test/Parser/cxx11-user-defined-literals.cpp b/test/Parser/cxx11-user-defined-literals.cpp
index 613c0b9..b89a574 100644
--- a/test/Parser/cxx11-user-defined-literals.cpp
+++ b/test/Parser/cxx11-user-defined-literals.cpp
@@ -15,7 +15,7 @@
 #elif __has_include("foo"_bar) // expected-error {{expected "FILENAME" or <FILENAME>}}
 #endif
 
-extern "C++"_x {} // expected-error {{user-defined suffix cannot be used here}} expected-error {{unknown linkage language}}
+extern "C++"_x {} // expected-error {{user-defined suffix cannot be used here}}
 
 int f() {
   asm("mov %eax, %rdx"_foo); // expected-error {{user-defined suffix cannot be used here}}
@@ -111,3 +111,35 @@
 U"" // expected-error {{cannot have an encoding prefix}}
 "" _also_not_char(const char *);
 void operator "" u8"" "\u0123" "hello"_all_of_the_things ""(const char*); // expected-error {{must be '""'}}
+
+// Make sure we treat UCNs and UTF-8 as equivalent.
+int operator""_µs(unsigned long long) {} // expected-note {{previous}}
+int hundred_µs = 50_µs + 50_\u00b5s;
+int operator""_\u00b5s(unsigned long long) {} // expected-error {{redefinition of 'operator "" _µs'}}
+
+int operator""_\U0000212B(long double) {} // expected-note {{previous}}
+int hundred_Å = 50.0_Å + 50._\U0000212B;
+int operator""_Å(long double) {} // expected-error {{redefinition of 'operator "" _Å'}}
+
+int operator""_𐀀(char) {} // expected-note {{previous}}
+int 𐀀 = '4'_𐀀 + '2'_\U00010000;
+int operator""_\U00010000(char) {} // expected-error {{redefinition of 'operator "" _𐀀'}}
+
+// These all declare the same function.
+int operator""_℮""_\u212e""_\U0000212e""(const char*, size_t);
+int operator""_\u212e""_\U0000212e""_℮""(const char*, size_t);
+int operator""_\U0000212e""_℮""_\u212e""(const char*, size_t);
+int mix_ucn_utf8 = ""_℮""_\u212e""_\U0000212e"";
+
+void operator""_℮""_ℯ(unsigned long long) {} // expected-error {{differing user-defined suffixes ('_℮' and '_ℯ') in string literal concatenation}}
+void operator""_℮""_\u212f(unsigned long long) {} // expected-error {{differing user-defined suffixes ('_℮' and '_ℯ') in string literal concatenation}}
+void operator""_\u212e""_ℯ(unsigned long long) {} // expected-error {{differing user-defined suffixes ('_℮' and '_ℯ') in string literal concatenation}}
+void operator""_\u212e""_\u212f(unsigned long long) {} // expected-error {{differing user-defined suffixes ('_℮' and '_ℯ') in string literal concatenation}}
+
+void operator""_℮""_℮(unsigned long long) {} // expected-note {{previous}}
+void operator""_\u212e""_\u212e(unsigned long long) {} // expected-error {{redefinition}}
+
+#define ¢ *0.01 // expected-error {{macro name must be an identifier}}
+constexpr int operator""_¢(long double d) { return d * 100; } // expected-error {{non-ASCII}}
+constexpr int operator""_¢(unsigned long long n) { return n; } // expected-error {{non-ASCII}}
+static_assert(0.02_¢ == 2_¢, ""); // expected-error 2{{non-ASCII}}
diff --git a/test/Parser/declarators.c b/test/Parser/declarators.c
index 210a8e2..39d9dc9 100644
--- a/test/Parser/declarators.c
+++ b/test/Parser/declarators.c
@@ -100,6 +100,7 @@
 
 void test16(i) int i j; { } // expected-error {{expected ';' at end of declaration}}
 void test17(i, j) int i, j k; { } // expected-error {{expected ';' at end of declaration}}
+void knrNoSemi(i) int i { } // expected-error {{expected ';' at end of declaration}}
 
 
 // PR12595
@@ -113,3 +114,37 @@
   struct S { int n; }: // expected-error {{expected ';'}}
 
 };
+
+// PR10982
+enum E11 {
+  A1 = 1,
+};
+
+enum E12 {
+  ,  // expected-error{{expected identifier}}
+  A2
+};
+void func_E12(enum E12 *p) { *p = A2; }
+
+enum E13 {
+  1D,  // expected-error{{expected identifier}}
+  A3
+};
+void func_E13(enum E13 *p) { *p = A3; }
+
+enum E14 {
+  A4 12,  // expected-error{{expected '= constant-expression' or end of enumerator definition}}
+  A4a
+};
+void func_E14(enum E14 *p) { *p = A4a; }
+
+enum E15 {
+  A5=12 4,  // expected-error{{expected '}' or ','}}
+  A5a
+};
+void func_E15(enum E15 *p) { *p = A5a; }
+
+enum E16 {
+  A6;  // expected-error{{expected '= constant-expression' or end of enumerator definition}}
+  A6a
+};
diff --git a/test/Parser/diag-crash.c b/test/Parser/diag-crash.c
new file mode 100644
index 0000000..4f1265f
--- /dev/null
+++ b/test/Parser/diag-crash.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Avoid preprocessor diag crash caused by a parser diag left in flight.
+
+int foo: // expected-error {{expected ';' after top level declarator}}
+#endif   // expected-error {{#endif without #if}}
diff --git a/test/Parser/eof.cpp b/test/Parser/eof.cpp
new file mode 100644
index 0000000..3c966c5
--- /dev/null
+++ b/test/Parser/eof.cpp
@@ -0,0 +1,13 @@
+// RUN: not %clang_cc1 %s -fsyntax-only 2>&1 | FileCheck %s
+
+// CHECK: error: expected member name or ';' after declaration specifiers
+// CHECK: error: expected '}'
+// CHECK: note: to match this '{'
+// CHECK: error: expected ';' after class
+// CHECK: error: anonymous structs and classes must be class members
+// CHECK: 4 errors generated.
+
+// Do not add anything to the end of this file.  This requires the whitespace
+// plus EOF after the template keyword.
+
+class { template     
diff --git a/test/Parser/expressions.c b/test/Parser/expressions.c
index 95d6fb3..64b4447 100644
--- a/test/Parser/expressions.c
+++ b/test/Parser/expressions.c
@@ -67,3 +67,9 @@
   int x3 = __alignof int;         // expected-error {{expected parentheses around type name in __alignof expression}}
   int x4 = _Alignof int;          // expected-error {{expected parentheses around type name in _Alignof expression}}
 }
+
+void callee(double, double);
+void test8() {
+  callee(foobar,   // expected-error {{use of undeclared identifier 'foobar'}}
+         fizbin);  // expected-error {{use of undeclared identifier 'fizbin'}}
+}
diff --git a/test/Parser/ms-if-exists.cpp b/test/Parser/ms-if-exists.cpp
new file mode 100644
index 0000000..79cc571
--- /dev/null
+++ b/test/Parser/ms-if-exists.cpp
@@ -0,0 +1,117 @@
+// RUN: %clang_cc1 %s -std=c++11 -fsyntax-only -Wmicrosoft -verify -fms-extensions
+
+class MayExist {
+private:
+  typedef int Type;
+};
+
+void test_if_exists_stmts() {
+  int b = 0;
+  __if_exists(MayExist::Type) {
+    b++;
+    b++;
+  }
+  __if_exists(MayExist::Type_not) {
+    this will not compile.
+  }
+  __if_not_exists(MayExist::Type) {
+    this will not compile.
+  }
+  __if_not_exists(MayExist::Type_not) {
+    b++;
+    b++;
+  }
+}
+
+int if_exists_creates_no_scope() {
+  __if_exists(MayExist::Type) {
+    int x;  // 'x' is declared in the parent scope.
+  }
+  __if_not_exists(MayExist::Type_not) {
+    x++;
+  }
+  return x;
+}
+
+__if_exists(MayExist::Type) {
+  int var23;
+}
+
+__if_exists(MayExist::Type_not) {
+  this will not compile.
+}
+
+__if_not_exists(MayExist::Type) {
+  this will not compile.
+}
+
+__if_not_exists(MayExist::Type_not) {
+  int var244;
+}
+
+void test_if_exists_init_list() {
+
+  int array1[] = {
+    0,
+    __if_exists(MayExist::Type) {2, }
+    3
+  };
+
+  int array2[] = {
+    0,
+    __if_exists(MayExist::Type_not) { this will not compile }
+    3
+  };
+
+  int array3[] = {
+    0,
+    __if_not_exists(MayExist::Type_not) {2, }
+    3
+  };
+
+  int array4[] = {
+    0,
+    __if_not_exists(MayExist::Type) { this will not compile }
+    3
+  };
+
+}
+
+
+class IfExistsClassScope {
+  __if_exists(MayExist::Type) {
+    // __if_exists, __if_not_exists can nest
+    __if_not_exists(MayExist::Type_not) {
+      int var123;
+    }
+    int var23;
+  }
+
+  __if_exists(MayExist::Type_not) {
+   this will not compile.
+  }
+
+  __if_not_exists(MayExist::Type) {
+   this will not compile.
+  }
+
+  __if_not_exists(MayExist::Type_not) {
+    int var244;
+  }
+};
+
+void test_nested_if_exists() {
+  __if_exists(MayExist::Type) {
+    int x = 42;
+    __if_not_exists(MayExist::Type_not) {
+      x++;
+    }
+  }
+}
+
+void test_attribute_on_if_exists() {
+  [[clang::fallthrough]] // expected-error {{an attribute list cannot appear here}}
+  __if_exists(MayExist::Type) {
+    int x;
+  }
+}
diff --git a/test/Parser/ms-inline-asm-nested-braces.c b/test/Parser/ms-inline-asm-nested-braces.c
new file mode 100644
index 0000000..58b055b
--- /dev/null
+++ b/test/Parser/ms-inline-asm-nested-braces.c
@@ -0,0 +1,9 @@
+// REQUIRES: x86-registered-target
+// RUN: %clang_cc1 %s -triple i386-apple-darwin10 -verify -fasm-blocks
+
+int t_fail() { // expected-note {{to match this}}
+  __asm
+  { // expected-note {{to match this}}
+    { // expected-note {{to match this}}
+      {
+      } // expected-error 3 {{expected}}
diff --git a/test/Parser/ms-inline-asm.c b/test/Parser/ms-inline-asm.c
index dff19b4..00508f5 100644
--- a/test/Parser/ms-inline-asm.c
+++ b/test/Parser/ms-inline-asm.c
@@ -1,4 +1,4 @@
-// REQUIRES: disabled
+// REQUIRES: x86-registered-target
 // RUN: %clang_cc1 %s -triple i386-apple-darwin10 -verify -fasm-blocks
 
 #define M __asm int 0x2c
@@ -34,6 +34,20 @@
 void t9() {
   __asm nop __asm nop ; __asm nop
 }
+void t10() {
+  __asm {
+    mov eax, 0
+    __asm {
+      mov eax, 1
+      {
+        mov eax, 2
+      }
+    }
+  }
+}
+void t11() {
+  do { __asm mov eax, 0 __asm { __asm mov edx, 1 } } while(0);
+}
 int t_fail() { // expected-note {{to match this}}
   __asm 
   __asm { // expected-error 3 {{expected}} expected-note {{to match this}}
diff --git a/test/Parser/namespace-alias-attr.cpp b/test/Parser/namespace-alias-attr.cpp
index ba80922..0baba84 100644
--- a/test/Parser/namespace-alias-attr.cpp
+++ b/test/Parser/namespace-alias-attr.cpp
@@ -4,5 +4,5 @@
 {
 }
 
-namespace B __attribute__ (( static )) = A; // expected-error{{attributes can not be specified on namespace alias}}
+namespace B __attribute__ (( static )) = A; // expected-error{{attributes cannot be specified on namespace alias}}
 
diff --git a/test/Parser/objc-error-qualified-implementation.m b/test/Parser/objc-error-qualified-implementation.m
index 8bbd502..6647372 100644
--- a/test/Parser/objc-error-qualified-implementation.m
+++ b/test/Parser/objc-error-qualified-implementation.m
@@ -6,24 +6,24 @@
 
 @interface I @end
 
-@implementation I<P> @end // expected-error {{@implementation declaration can not be protocol qualified}}
+@implementation I<P> @end // expected-error {{@implementation declaration cannot be protocol qualified}}
 
 @interface J < P,P >
 @end
 
 
-@implementation J < P,P > // expected-error {{@implementation declaration can not be protocol qualified}}
+@implementation J < P,P > // expected-error {{@implementation declaration cannot be protocol qualified}}
 @end
 
 @interface K @end
 
-@implementation K <P // expected-error {{@implementation declaration can not be protocol qualified}}
+@implementation K <P // expected-error {{@implementation declaration cannot be protocol qualified}}
 @end // expected-error {{expected '>'}}
 
 // rdar://13920026
-@implementation I (Cat) <P>  // expected-error {{@implementation declaration can not be protocol qualified}}
+@implementation I (Cat) <P>  // expected-error {{@implementation declaration cannot be protocol qualified}}
 - (void) Meth {}
 @end
 
-@implementation I (Cat1) <P // expected-error {{@implementation declaration can not be protocol qualified}}
+@implementation I (Cat1) <P // expected-error {{@implementation declaration cannot be protocol qualified}}
 @end // expected-error {{expected '>'}}
diff --git a/test/Parser/objcbridge-related-attribute.m b/test/Parser/objcbridge-related-attribute.m
new file mode 100644
index 0000000..209448b
--- /dev/null
+++ b/test/Parser/objcbridge-related-attribute.m
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s
+// rdar://15499111
+
+typedef struct __attribute__((objc_bridge_related(NSColor,colorWithCGColor:,CGColor))) CGColor *CGColorRefOk;
+typedef struct __attribute__((objc_bridge_related(NSColor,,CGColor))) CGColor *CGColorRef1Ok;
+typedef struct __attribute__((objc_bridge_related(NSColor,,))) CGColor *CGColorRef2Ok;
+typedef struct __attribute__((objc_bridge_related(NSColor,colorWithCGColor:,))) CGColor *CGColorRef3Ok;
+
+typedef struct __attribute__((objc_bridge_related(,colorWithCGColor:,CGColor))) CGColor *CGColorRef1NotOk; // expected-error {{expected a related ObjectiveC class name, e.g., 'NSColor'}}
+typedef struct __attribute__((objc_bridge_related(NSColor,colorWithCGColor,CGColor))) CGColor *CGColorRef2NotOk; // expected-error {{expected a class method selector with single argument, e.g., 'colorWithCGColor:'}}
+typedef struct __attribute__((objc_bridge_related(NSColor,colorWithCGColor::,CGColor))) CGColor *CGColorRef3NotOk; // expected-error {{expected a class method selector with single argument, e.g., 'colorWithCGColor:'}}
+typedef struct __attribute__((objc_bridge_related(12,colorWithCGColor:,CGColor))) CGColor *CGColorRef4NotOk; // expected-error {{expected a related ObjectiveC class name, e.g., 'NSColor'}}
+typedef struct __attribute__((objc_bridge_related(NSColor,+:,CGColor))) CGColor *CGColorRef5NotOk; // expected-error {{expected ','}}
+typedef struct __attribute__((objc_bridge_related(NSColor,colorWithCGColor:,+))) CGColor *CGColorRef6NotOk; // expected-error {{expected ')'}}
+
diff --git a/test/Parser/objcxx11-attributes.mm b/test/Parser/objcxx11-attributes.mm
index c1d8c41..4bff215 100644
--- a/test/Parser/objcxx11-attributes.mm
+++ b/test/Parser/objcxx11-attributes.mm
@@ -13,12 +13,12 @@
   int a[ [noreturn getSize] ];
 
   // ... but is interpreted as an attribute where possible.
-  int b[ [noreturn] ]; // expected-error {{'noreturn' attribute only applies to functions and methods}}
+  int b[ [noreturn] ]; // expected-error {{'noreturn' attribute only applies to functions}}
 
   int c[ [noreturn getSize] + 1 ];
 
   // An array size which is computed by a lambda is not OK.
-  int d[ [noreturn] { return 3; } () ]; // expected-error {{expected ']'}} expected-error {{'noreturn' attribute only applies}}
+  int d[ [noreturn] { return 3; } () ]; // expected-error {{expected ']'}} expected-error {{'noreturn' attribute only applies to functions}}
 
   // A message send which contains a message send is OK.
   [ [ X alloc ] init ];
diff --git a/test/Parser/opencl-astype.cl b/test/Parser/opencl-astype.cl
index d4c547e..72f98a4 100644
--- a/test/Parser/opencl-astype.cl
+++ b/test/Parser/opencl-astype.cl
@@ -11,7 +11,7 @@
   typedef __attribute__(( ext_vector_type(4) ))  double double4;
   
   float4 f4;
-  double4 d4 = __builtin_astype(f4, double4); // expected-error{{invalid reinterpretation: sizes of 'double4' and 'float4' must match}}
+  double4 d4 = __builtin_astype(f4, double4); // expected-error{{invalid reinterpretation: sizes of 'double4' (vector of 4 'double' values) and 'float4' (vector of 4 'float' values) must match}}
   
   // Verify int4->float3, float3->int4 works.
   int4 i4;
diff --git a/test/Parser/opencl-keywords.cl b/test/Parser/opencl-keywords.cl
new file mode 100644
index 0000000..5bc7054
--- /dev/null
+++ b/test/Parser/opencl-keywords.cl
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only
+// expected-no-diagnostics
+
+void f(half *h) {
+  bool b;
+  int wchar_t;
+  int constexpr;
+}
diff --git a/test/Parser/pragma-loop.cpp b/test/Parser/pragma-loop.cpp
new file mode 100644
index 0000000..23f185d
--- /dev/null
+++ b/test/Parser/pragma-loop.cpp
@@ -0,0 +1,166 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+// Note that this puts the expected lines before the directives to work around
+// limitations in the -verify mode.
+
+void test(int *List, int Length) {
+  int i = 0;
+
+#pragma clang loop vectorize(enable)
+#pragma clang loop interleave(enable)
+#pragma clang loop unroll(enable)
+  while (i + 1 < Length) {
+    List[i] = i;
+  }
+
+#pragma clang loop vectorize_width(4)
+#pragma clang loop interleave_count(8)
+#pragma clang loop unroll_count(16)
+  while (i < Length) {
+    List[i] = i;
+  }
+
+#pragma clang loop vectorize(disable)
+#pragma clang loop interleave(disable)
+#pragma clang loop unroll(disable)
+  while (i - 1 < Length) {
+    List[i] = i;
+  }
+
+#pragma clang loop vectorize_width(4) interleave_count(8) unroll_count(16)
+  while (i - 2 < Length) {
+    List[i] = i;
+  }
+
+#pragma clang loop interleave_count(16)
+  while (i - 3 < Length) {
+    List[i] = i;
+  }
+
+  int VList[Length];
+#pragma clang loop vectorize(disable) interleave(disable) unroll(disable)
+  for (int j : VList) {
+    VList[j] = List[j];
+  }
+
+/* expected-error {{expected '('}} */ #pragma clang loop vectorize
+/* expected-error {{expected '('}} */ #pragma clang loop interleave
+/* expected-error {{expected '('}} */ #pragma clang loop unroll
+
+/* expected-error {{expected ')'}} */ #pragma clang loop vectorize(enable
+/* expected-error {{expected ')'}} */ #pragma clang loop interleave(enable
+/* expected-error {{expected ')'}} */ #pragma clang loop unroll(enable
+
+/* expected-error {{expected ')'}} */ #pragma clang loop vectorize_width(4
+/* expected-error {{expected ')'}} */ #pragma clang loop interleave_count(4
+/* expected-error {{expected ')'}} */ #pragma clang loop unroll_count(4
+
+/* expected-error {{missing argument to '#pragma clang loop vectorize'; expected a positive integer value}} */ #pragma clang loop vectorize()
+/* expected-error {{missing argument to '#pragma clang loop interleave_count'; expected a positive integer value}} */ #pragma clang loop interleave_count()
+/* expected-error {{missing argument to '#pragma clang loop unroll'; expected a positive integer value}} */ #pragma clang loop unroll()
+
+/* expected-error {{missing option}} */ #pragma clang loop
+/* expected-error {{invalid option 'badkeyword'}} */ #pragma clang loop badkeyword
+/* expected-error {{invalid option 'badkeyword'}} */ #pragma clang loop badkeyword(enable)
+/* expected-error {{invalid option 'badkeyword'}} */ #pragma clang loop vectorize(enable) badkeyword(4)
+/* expected-warning {{extra tokens at end of '#pragma clang loop'}} */ #pragma clang loop vectorize(enable) ,
+
+  while (i-4 < Length) {
+    List[i] = i;
+  }
+
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop vectorize_width(0)
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop interleave_count(0)
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop unroll_count(0)
+  while (i-5 < Length) {
+    List[i] = i;
+  }
+
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop vectorize_width(3000000000)
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop interleave_count(3000000000)
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop unroll_count(3000000000)
+  while (i-6 < Length) {
+    List[i] = i;
+  }
+
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop vectorize_width(badvalue)
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop interleave_count(badvalue)
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop unroll_count(badvalue)
+  while (i-6 < Length) {
+    List[i] = i;
+  }
+
+/* expected-error {{invalid argument; expected 'enable' or 'disable'}} */ #pragma clang loop vectorize(badidentifier)
+/* expected-error {{invalid argument; expected 'enable' or 'disable'}} */ #pragma clang loop interleave(badidentifier)
+/* expected-error {{invalid argument; expected 'enable' or 'disable'}} */ #pragma clang loop unroll(badidentifier)
+  while (i-7 < Length) {
+    List[i] = i;
+  }
+
+// PR20069 - Loop pragma arguments that are not identifiers or numeric
+// constants crash FE.
+/* expected-error {{invalid argument; expected 'enable' or 'disable'}} */ #pragma clang loop vectorize(()
+/* expected-error {{invalid argument; expected 'enable' or 'disable'}} */ #pragma clang loop interleave(*)
+/* expected-error {{invalid argument; expected 'enable' or 'disable'}} */ #pragma clang loop unroll(=)
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop vectorize_width(^)
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop interleave_count(/)
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop unroll_count(==)
+  while (i-8 < Length) {
+    List[i] = i;
+  }
+
+#pragma clang loop vectorize(enable)
+/* expected-error {{expected a for, while, or do-while loop to follow '#pragma clang loop'}} */ int j = Length;
+  List[0] = List[1];
+
+  while (j-1 < Length) {
+    List[j] = j;
+  }
+
+// FIXME: A bug in ParsedAttributes causes the order of the attributes to be
+// processed in reverse. Consequently, the errors occur on the first of pragma
+// of the next three tests rather than the last, and the order of the kinds
+// is also reversed.
+
+/* expected-error {{incompatible directives 'vectorize(disable)' and 'vectorize_width(4)'}} */ #pragma clang loop vectorize_width(4)
+#pragma clang loop vectorize(disable)
+/* expected-error {{incompatible directives 'interleave(disable)' and 'interleave_count(4)'}} */ #pragma clang loop interleave_count(4)
+#pragma clang loop interleave(disable)
+/* expected-error {{incompatible directives 'unroll(disable)' and 'unroll_count(4)'}} */ #pragma clang loop unroll_count(4)
+#pragma clang loop unroll(disable)
+  while (i-8 < Length) {
+    List[i] = i;
+  }
+
+/* expected-error {{duplicate directives 'vectorize(disable)' and 'vectorize(enable)'}} */ #pragma clang loop vectorize(enable)
+#pragma clang loop vectorize(disable)
+/* expected-error {{duplicate directives 'interleave(disable)' and 'interleave(enable)'}} */ #pragma clang loop interleave(enable)
+#pragma clang loop interleave(disable)
+/* expected-error {{duplicate directives 'unroll(disable)' and 'unroll(enable)'}} */ #pragma clang loop unroll(enable)
+#pragma clang loop unroll(disable)
+  while (i-9 < Length) {
+    List[i] = i;
+  }
+
+/* expected-error {{incompatible directives 'vectorize(disable)' and 'vectorize_width(4)'}} */ #pragma clang loop vectorize(disable)
+#pragma clang loop vectorize_width(4)
+/* expected-error {{incompatible directives 'interleave(disable)' and 'interleave_count(4)'}} */ #pragma clang loop interleave(disable)
+#pragma clang loop interleave_count(4)
+/* expected-error {{incompatible directives 'unroll(disable)' and 'unroll_count(4)'}} */ #pragma clang loop unroll(disable)
+#pragma clang loop unroll_count(4)
+  while (i-10 < Length) {
+    List[i] = i;
+  }
+
+/* expected-error {{duplicate directives 'vectorize_width(4)' and 'vectorize_width(8)'}} */ #pragma clang loop vectorize_width(8)
+#pragma clang loop vectorize_width(4)
+/* expected-error {{duplicate directives 'interleave_count(4)' and 'interleave_count(8)'}} */ #pragma clang loop interleave_count(8)
+#pragma clang loop interleave_count(4)
+/* expected-error {{duplicate directives 'unroll_count(4)' and 'unroll_count(8)'}} */ #pragma clang loop unroll_count(8)
+#pragma clang loop unroll_count(4)
+  while (i-11 < Length) {
+    List[i] = i;
+  }
+
+#pragma clang loop interleave(enable)
+/* expected-error {{expected statement}} */ }
diff --git a/test/Parser/pragma-optimize-diagnostics.cpp b/test/Parser/pragma-optimize-diagnostics.cpp
new file mode 100644
index 0000000..af11a4e
--- /dev/null
+++ b/test/Parser/pragma-optimize-diagnostics.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+#pragma clang optimize off
+
+#pragma clang optimize on
+
+// Extra arguments
+#pragma clang optimize on top of spaghetti  // expected-error {{unexpected extra argument 'top' to '#pragma clang optimize'}}
+
+// Wrong argument
+#pragma clang optimize something_wrong  // expected-error {{unexpected argument 'something_wrong' to '#pragma clang optimize'; expected 'on' or 'off'}}
+
+// No argument
+#pragma clang optimize // expected-error {{missing argument to '#pragma clang optimize'; expected 'on' or 'off'}}
+
+// Check that macros can be used in the pragma
+#define OFF off
+#define ON on
+#pragma clang optimize OFF
+#pragma clang optimize ON
+
+// Check that _Pragma can also be used to address the use case where users want
+// to define optimization control macros to abstract out which compiler they are
+// using.
+#define OPT_OFF _Pragma("clang optimize off")
+#define OPT_ON _Pragma("clang optimize on")
+OPT_OFF
+OPT_ON
diff --git a/test/Parser/pragma-unroll.cpp b/test/Parser/pragma-unroll.cpp
new file mode 100644
index 0000000..1d89e63
--- /dev/null
+++ b/test/Parser/pragma-unroll.cpp
@@ -0,0 +1,89 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+// Note that this puts the expected lines before the directives to work around
+// limitations in the -verify mode.
+
+void test(int *List, int Length) {
+  int i = 0;
+
+#pragma unroll
+  while (i + 1 < Length) {
+    List[i] = i;
+  }
+
+#pragma unroll 4
+  while (i - 1 < Length) {
+    List[i] = i;
+  }
+
+#pragma unroll(8)
+  while (i - 2 < Length) {
+    List[i] = i;
+  }
+
+#pragma unroll
+#pragma unroll(8)
+  while (i - 3 < Length) {
+    List[i] = i;
+  }
+
+#pragma clang loop unroll(enable)
+#pragma unroll(8)
+  while (i - 4 < Length) {
+    List[i] = i;
+  }
+
+#pragma unroll
+#pragma clang loop unroll_count(4)
+  while (i - 5 < Length) {
+    List[i] = i;
+  }
+
+/* expected-error {{expected ')'}} */ #pragma unroll(4
+/* expected-error {{missing argument to '#pragma unroll'; expected a positive integer value}} */ #pragma unroll()
+/* expected-warning {{extra tokens at end of '#pragma unroll'}} */ #pragma unroll 1 2
+  while (i-6 < Length) {
+    List[i] = i;
+  }
+
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma unroll(()
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma unroll -
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma unroll(0)
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma unroll 0
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma unroll(3000000000)
+/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma unroll 3000000000
+  while (i-8 < Length) {
+    List[i] = i;
+  }
+
+#pragma unroll
+/* expected-error {{expected a for, while, or do-while loop to follow '#pragma unroll'}} */ int j = Length;
+#pragma unroll 4
+/* expected-error {{expected a for, while, or do-while loop to follow '#pragma unroll'}} */ int k = Length;
+
+/* expected-error {{incompatible directives 'unroll(disable)' and '#pragma unroll(4)'}} */ #pragma unroll 4
+#pragma clang loop unroll(disable)
+  while (i-10 < Length) {
+    List[i] = i;
+  }
+
+/* expected-error {{duplicate directives '#pragma unroll' and '#pragma unroll'}} */ #pragma unroll
+#pragma unroll
+  while (i-14 < Length) {
+    List[i] = i;
+  }
+
+/* expected-error {{duplicate directives 'unroll(enable)' and '#pragma unroll'}} */ #pragma unroll
+#pragma clang loop unroll(enable)
+  while (i-15 < Length) {
+    List[i] = i;
+  }
+
+/* expected-error {{duplicate directives '#pragma unroll(4)' and '#pragma unroll(4)'}} */ #pragma unroll 4
+#pragma unroll(4)
+  while (i-16 < Length) {
+    List[i] = i;
+  }
+
+#pragma unroll
+/* expected-error {{expected statement}} */ }
diff --git a/test/Parser/recovery.cpp b/test/Parser/recovery.cpp
index 0000f5c..5608b50 100644
--- a/test/Parser/recovery.cpp
+++ b/test/Parser/recovery.cpp
@@ -66,3 +66,139 @@
 struct Redefined { // expected-error {{redefinition}}
   Redefined() {}
 };
+
+struct MissingSemi5;
+namespace N {
+  typedef int afterMissingSemi4;
+  extern MissingSemi5 afterMissingSemi5;
+}
+
+struct MissingSemi1 {} // expected-error {{expected ';' after struct}}
+static int afterMissingSemi1();
+
+class MissingSemi2 {} // expected-error {{expected ';' after class}}
+MissingSemi1 *afterMissingSemi2;
+
+enum MissingSemi3 {} // expected-error {{expected ';' after enum}}
+::MissingSemi1 afterMissingSemi3;
+
+extern N::afterMissingSemi4 afterMissingSemi4b;
+union MissingSemi4 { MissingSemi4(int); } // expected-error {{expected ';' after union}}
+N::afterMissingSemi4 (afterMissingSemi4b);
+
+int afterMissingSemi5b;
+struct MissingSemi5 { MissingSemi5(int); } // ok, no missing ';' here
+N::afterMissingSemi5 (afterMissingSemi5b);
+
+template<typename T> struct MissingSemiT {
+} // expected-error {{expected ';' after struct}}
+MissingSemiT<int> msi;
+
+struct MissingSemiInStruct {
+  struct Inner1 {} // expected-error {{expected ';' after struct}}
+  static MissingSemi5 ms1;
+
+  struct Inner2 {} // ok, no missing ';' here
+  static MissingSemi1;
+
+  struct Inner3 {} // expected-error {{expected ';' after struct}}
+  static MissingSemi5 *p;
+};
+
+void MissingSemiInFunction() {
+  struct Inner1 {} // expected-error {{expected ';' after struct}}
+  if (true) {}
+
+  // FIXME: It would be nice to at least warn on this.
+  struct Inner2 { Inner2(int); } // ok, no missing ';' here
+  k = l;
+
+  struct Inner3 {} // expected-error {{expected ';' after struct}}
+  Inner1 i1;
+
+  struct Inner4 {} // ok, no missing ';' here
+  Inner5;
+}
+
+namespace NS {
+  template<typename T> struct Foo {};
+}
+struct MissingSemiThenTemplate1 {} // expected-error {{expected ';' after struct}}
+NS::Foo<int> missingSemiBeforeFunctionReturningTemplateId1();
+
+using NS::Foo;
+struct MissingSemiThenTemplate2 {} // expected-error {{expected ';' after struct}}
+Foo<int> missingSemiBeforeFunctionReturningTemplateId2();
+
+namespace PR17084 {
+enum class EnumID {};
+template <typename> struct TempID;
+template <> struct TempID<BadType> : BadType, EnumID::Garbage; // expected-error{{use of undeclared identifier 'BadType'}}
+}
+
+namespace pr15133 {
+  namespace ns {
+    const int V1 = 1;   // expected-note {{declared here}}
+  }
+  struct C1 {
+    enum E1 { V2 = 2 }; // expected-note {{declared here}}
+    static const int V3 = 3; // expected-note {{declared here}}
+  };
+  enum E2 {
+    V4 = 4,   // expected-note {{declared here}}
+    V6        // expected-note {{declared here}}
+  };
+  enum class EC3 { V0 = 0, V5 = 5 }; // expected-note {{declared here}}
+  void func_3();
+
+  void func_1(int x) {
+    switch(x) {
+    case 0: break;
+    case ns::V1:: break; // expected-error{{'V1' cannot appear before '::' because it is not a class, namespace, or scoped enumeration; did you mean ':'?}}
+    case C1::V2:: break; // expected-error{{'V2' cannot appear before '::' because it is not a class, namespace, or scoped enumeration; did you mean ':'?}}
+    case C1::V3:: break; // expected-error{{'V3' cannot appear before '::' because it is not a class, namespace, or scoped enumeration; did you mean ':'?}}
+    case V4:: break; // expected-error{{'V4' cannot appear before '::' because it is not a class, namespace, or scoped enumeration; did you mean ':'?}}
+    case V6:: func_3();   // expected-error{{'V6' cannot appear before '::' because it is not a class, namespace, or scoped enumeration; did you mean ':'?}}
+    }
+  }
+  void func_2(EC3 x) {
+    switch(x) {
+    case EC3::V0:  break;
+    case EC3::V5:: break; // expected-error{{'V5' cannot appear before '::' because it is not a class, namespace, or scoped enumeration; did you mean ':'?}}
+    }
+  }
+
+  template<class T> struct TS1 {
+    typedef int A;
+  };
+  template<class T> void func(int x) {
+    switch(x) {
+    case TS1<T>::A:: break;  // expected-error{{expected unqualified-id}}
+    }
+  };
+  void mainf() {
+    func<int>(1);
+  }
+
+  struct S {
+    static int n;  // expected-note{{declared here}}
+    int nn;        // expected-note 2 {{declared here}}
+  };
+
+  int func_3(int x) {
+    return x ? S::n :: 0;  // expected-error{{'n' cannot appear before '::' because it is not a class, namespace, or scoped enumeration; did you mean ':'?}}
+  }
+  int func_4(int x, S &s) {
+    return x ? s.nn :: x;  // expected-error{{'nn' cannot appear before '::' because it is not a class, namespace, or scoped enumeration; did you mean ':'?}}
+  }
+  int func_5(int x, S &s) {
+    return x ? s.nn :: S::n;  // expected-error{{'nn' cannot appear before '::' because it is not a class, namespace, or scoped enumeration; did you mean ':'?}}
+  }
+
+  struct S2 {
+    struct S3;
+  };
+
+  struct S2 :: S3 :: public S2 {  // expected-error{{'public' cannot be a part of nested name specifier; did you mean ':'?}}
+  };
+}
diff --git a/test/Parser/switch-recovery.cpp b/test/Parser/switch-recovery.cpp
index 63b5802..5345170 100644
--- a/test/Parser/switch-recovery.cpp
+++ b/test/Parser/switch-recovery.cpp
@@ -170,3 +170,53 @@
     default: // expected-error {{label at end of compound statement: expected statement}}
   }
 }
+
+void pr19022_1() {
+  switch (int x)  // expected-error {{variable declaration in condition must have an initializer}}
+  case v: ;  // expected-error {{use of undeclared identifier 'v'}}
+}
+
+void pr19022_1a(int x) {
+  switch(x) {
+  case 1  // expected-error{{expected ':' after 'case'}} \
+          // expected-error{{label at end of compound statement: expected statement}}
+  }
+}
+
+void pr19022_1b(int x) {
+  switch(x) {
+  case v  // expected-error{{use of undeclared identifier 'v'}}
+  }
+ }
+
+void pr19022_2() {
+  switch (int x)  // expected-error {{variable declaration in condition must have an initializer}}
+  case v1: case v2: ;  // expected-error {{use of undeclared identifier 'v1'}} \
+                       // expected-error {{use of undeclared identifier 'v2'}}
+}
+
+void pr19022_3(int x) {
+  switch (x)
+  case 1: case v2: ;  // expected-error {{use of undeclared identifier 'v2'}}
+}
+
+int pr19022_4(int x) {
+  switch(x) {
+  case 1  // expected-error{{expected ':' after 'case'}} expected-note{{previous case defined here}}
+  case 1 : return x;  // expected-error{{duplicate case value '1'}}
+  }
+}
+
+void pr19022_5(int x) {
+  switch(x) {
+  case 1: case
+  }  // expected-error{{expected expression}}
+}
+
+namespace pr19022 {
+int baz5() {}
+bool bar0() {
+  switch (int foo0)  //expected-error{{variable declaration in condition must have an initializer}}
+  case bar5: ;  // expected-error{{use of undeclared identifier 'bar5'}}
+}
+}
diff --git a/test/Parser/warn-cuda-compat.cu b/test/Parser/warn-cuda-compat.cu
new file mode 100644
index 0000000..c3aad6f
--- /dev/null
+++ b/test/Parser/warn-cuda-compat.cu
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -Wno-cuda-compat -Werror %s
+// RUN: %clang_cc1 -Wcuda-compat -verify %s
+// RUN: %clang_cc1 -x c++ -Wcuda-compat -Werror %s
+
+// Note that this puts the expected lines before the directives to work around
+// limitations in the -verify mode.
+
+void test(int *List, int Length) {
+/* expected-warning {{argument to '#pragma unroll' should not be in parentheses in CUDA C/C++}} */#pragma unroll(4)
+  for (int i = 0; i < Length; ++i) {
+    List[i] = i;
+  }
+}
diff --git a/test/Parser/warn-semicolon-before-method-body.m b/test/Parser/warn-semicolon-before-method-body.m
index be408eb..abdf9f2 100644
--- a/test/Parser/warn-semicolon-before-method-body.m
+++ b/test/Parser/warn-semicolon-before-method-body.m
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -fsyntax-only -Wsemicolon-before-method-body -verify %s
 // RUN: %clang_cc1 -fsyntax-only -Wsemicolon-before-method-body -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
 
-// Allow optional semicolon in objc method definiton after method prototype,
+// Allow optional semicolon in objc method definition after method prototype,
 // warn about it and suggest a fixit.
 
 @interface NSObject
diff --git a/test/Preprocessor/Inputs/headermap-rel/Foo.framework/Headers/Foo.h b/test/Preprocessor/Inputs/headermap-rel/Foo.framework/Headers/Foo.h
new file mode 100644
index 0000000..04ffb5a
--- /dev/null
+++ b/test/Preprocessor/Inputs/headermap-rel/Foo.framework/Headers/Foo.h
@@ -0,0 +1,2 @@
+
+Foo.h is parsed
diff --git a/test/Preprocessor/Inputs/headermap-rel/foo.hmap b/test/Preprocessor/Inputs/headermap-rel/foo.hmap
new file mode 100644
index 0000000..783c64e
--- /dev/null
+++ b/test/Preprocessor/Inputs/headermap-rel/foo.hmap
Binary files differ
diff --git a/test/Preprocessor/Inputs/headermap-rel2/Product/someheader.h b/test/Preprocessor/Inputs/headermap-rel2/Product/someheader.h
new file mode 100644
index 0000000..ca2e521
--- /dev/null
+++ b/test/Preprocessor/Inputs/headermap-rel2/Product/someheader.h
@@ -0,0 +1 @@
+#define A 2
diff --git a/test/Preprocessor/Inputs/headermap-rel2/project-headers.hmap b/test/Preprocessor/Inputs/headermap-rel2/project-headers.hmap
new file mode 100644
index 0000000..a0770fb
--- /dev/null
+++ b/test/Preprocessor/Inputs/headermap-rel2/project-headers.hmap
Binary files differ
diff --git a/test/Preprocessor/Inputs/headermap-rel2/system/usr/include/someheader.h b/test/Preprocessor/Inputs/headermap-rel2/system/usr/include/someheader.h
new file mode 100644
index 0000000..ab2a05d
--- /dev/null
+++ b/test/Preprocessor/Inputs/headermap-rel2/system/usr/include/someheader.h
@@ -0,0 +1 @@
+#define A 1
diff --git a/test/Preprocessor/Inputs/microsoft-header-search/a/b/include3.h b/test/Preprocessor/Inputs/microsoft-header-search/a/b/include3.h
new file mode 100644
index 0000000..3f477e7
--- /dev/null
+++ b/test/Preprocessor/Inputs/microsoft-header-search/a/b/include3.h
@@ -0,0 +1,5 @@
+#pragma once
+
+#include "findme.h"
+
+#include "falsepos.h"
diff --git a/test/Preprocessor/Inputs/microsoft-header-search/a/findme.h b/test/Preprocessor/Inputs/microsoft-header-search/a/findme.h
new file mode 100644
index 0000000..b809c90
--- /dev/null
+++ b/test/Preprocessor/Inputs/microsoft-header-search/a/findme.h
@@ -0,0 +1,3 @@
+#pragma once
+
+#warning findme.h successfully included using MS search rules
\ No newline at end of file
diff --git a/test/Preprocessor/Inputs/microsoft-header-search/a/include2.h b/test/Preprocessor/Inputs/microsoft-header-search/a/include2.h
new file mode 100644
index 0000000..99640ae
--- /dev/null
+++ b/test/Preprocessor/Inputs/microsoft-header-search/a/include2.h
@@ -0,0 +1,6 @@
+#pragma once
+
+#include "b/include3.h"
+#pragma once
+
+#include "b/include3.h"
\ No newline at end of file
diff --git a/test/Preprocessor/Inputs/microsoft-header-search/falsepos.h b/test/Preprocessor/Inputs/microsoft-header-search/falsepos.h
new file mode 100644
index 0000000..cb85969
--- /dev/null
+++ b/test/Preprocessor/Inputs/microsoft-header-search/falsepos.h
@@ -0,0 +1,3 @@
+#pragma once
+
+#warning successfully resolved the falsepos.h header
diff --git a/test/Preprocessor/Inputs/microsoft-header-search/findme.h b/test/Preprocessor/Inputs/microsoft-header-search/findme.h
new file mode 100644
index 0000000..aeaf795
--- /dev/null
+++ b/test/Preprocessor/Inputs/microsoft-header-search/findme.h
@@ -0,0 +1,3 @@
+#pragma once
+
+#error Wrong findme.h included, MSVC header search incorrect
\ No newline at end of file
diff --git a/test/Preprocessor/Inputs/microsoft-header-search/include1.h b/test/Preprocessor/Inputs/microsoft-header-search/include1.h
new file mode 100644
index 0000000..f00fac7
--- /dev/null
+++ b/test/Preprocessor/Inputs/microsoft-header-search/include1.h
@@ -0,0 +1,6 @@
+#pragma once
+
+#include "a/include2.h"
+#pragma once
+
+#include "a/include2.h"
\ No newline at end of file
diff --git a/test/Preprocessor/aarch64-target-features.c b/test/Preprocessor/aarch64-target-features.c
index 9978f91..137a1d8 100644
--- a/test/Preprocessor/aarch64-target-features.c
+++ b/test/Preprocessor/aarch64-target-features.c
@@ -1,4 +1,5 @@
 // RUN: %clang -target aarch64-none-linux-gnu -x c -E -dM %s -o - | FileCheck %s
+// RUN: %clang -target arm64-none-linux-gnu -x c -E -dM %s -o - | FileCheck %s
 
 // CHECK: __AARCH64EL__ 1
 // CHECK: __ARM_64BIT_STATE 1
@@ -9,6 +10,7 @@
 // CHECK: __ARM_ARCH_PROFILE 'A'
 // CHECK-NOT: __ARM_FEATURE_BIG_ENDIAN
 // CHECK: __ARM_FEATURE_CLZ 1
+// CHECK-NOT: __ARM_FEATURE_CRC32 1
 // CHECK-NOT: __ARM_FEATURE_CRYPTO 1
 // CHECK: __ARM_FEATURE_DIV 1
 // CHECK: __ARM_FEATURE_FMA 1
@@ -17,24 +19,85 @@
 // CHECK: __ARM_FP16_FORMAT_IEEE 1
 // CHECK-NOT: __ARM_FP_FAST 1
 // CHECK: __ARM_FP_FENV_ROUNDING 1
-// CHECK-NOT: __ARM_NEON 1
-// CHECK-NOT: __ARM_NEON_FP 7
+// CHECK: __ARM_NEON 1
+// CHECK: __ARM_NEON_FP 0xe
 // CHECK: __ARM_PCS_AAPCS64 1
 // CHECK-NOT: __ARM_SIZEOF_MINIMAL_ENUM 1
 // CHECK-NOT: __ARM_SIZEOF_WCHAR_T 2
 
-// RUN: %clang -target aarch64-none-linux-gnu -mfpu=crypto-neon-fp-armv8 -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-CRYPTO %s
+// RUN: %clang -target aarch64-none-linux-gnu -march=armv8-a+crypto -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-CRYPTO %s
+// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a+crypto -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-CRYPTO %s
 // CHECK-CRYPTO: __ARM_FEATURE_CRYPTO 1
 
+// RUN: %clang -target aarch64-none-linux-gnu -mcrc -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-CRC32 %s
+// RUN: %clang -target arm64-none-linux-gnu -mcrc -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-CRC32 %s
+// RUN: %clang -target aarch64-none-linux-gnu -march=armv8-a+crc -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-CRC32 %s
+// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a+crc -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-CRC32 %s
+// CHECK-CRC32: __ARM_FEATURE_CRC32 1
+
 // RUN: %clang -target aarch64-none-linux-gnu -ffast-math -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-FASTMATH %s
+// RUN: %clang -target arm64-none-linux-gnu -ffast-math -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-FASTMATH %s
 // CHECK-FASTMATH: __ARM_FP_FAST 1
 
 // RUN: %clang -target aarch64-none-linux-gnu -fshort-wchar -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SHORTWCHAR %s
+// RUN: %clang -target arm64-none-linux-gnu -fshort-wchar -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SHORTWCHAR %s
 // CHECK-SHORTWCHAR: __ARM_SIZEOF_WCHAR_T 2
 
 // RUN: %clang -target aarch64-none-linux-gnu -fshort-enums -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SHORTENUMS %s
+// RUN: %clang -target arm64-none-linux-gnu -fshort-enums -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SHORTENUMS %s
 // CHECK-SHORTENUMS: __ARM_SIZEOF_MINIMAL_ENUM 1
 
-// RUN: %clang -target aarch64-none-linux-gnu -mfpu=neon -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-NEON %s
+// RUN: %clang -target aarch64-none-linux-gnu -march=armv8-a+simd -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-NEON %s
+// RUN: %clang -target arm64-none-linux-gnu -march=armv8-a+simd -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-NEON %s
 // CHECK-NEON: __ARM_NEON 1
-// CHECK-NEON: __ARM_NEON_FP 7
+// CHECK-NEON: __ARM_NEON_FP 0xe
+
+// RUN: %clang -target aarch64 -march=arm64 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-ARCH-NOT-ACCEPT %s
+// RUN: %clang -target aarch64 -march=aarch64 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-ARCH-NOT-ACCEPT %s
+// CHECK-ARCH-NOT-ACCEPT: error: the clang compiler does not support
+
+// RUN: %clang -target aarch64 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-GENERIC %s
+// RUN: %clang -target aarch64 -march=armv8-a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-GENERIC %s
+// CHECK-GENERIC: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+neon"
+
+// RUN: %clang -target aarch64 -mtune=cyclone -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MTUNE-CYCLONE %s
+// CHECK-MTUNE-CYCLONE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+neon" "-target-feature" "+zcm" "-target-feature" "+zcz"
+
+// RUN: %clang -target aarch64 -mcpu=cyclone -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-CYCLONE %s
+// RUN: %clang -target aarch64 -mcpu=cortex-a53 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-A53 %s
+// RUN: %clang -target aarch64 -mcpu=cortex-a57 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-A57 %s
+// CHECK-MCPU-CYCLONE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+neon" "-target-feature" "+crc" "-target-feature" "+crypto" "-target-feature" "+zcm" "-target-feature" "+zcz"
+// CHECK-MCPU-A53: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+neon" "-target-feature" "+crc" "-target-feature" "+crypto"
+// CHECK-MCPU-A57: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+neon" "-target-feature" "+crc" "-target-feature" "+crypto"
+
+// RUN: %clang -target aarch64 -march=armv8-a+fp+simd+crc+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MARCH-1 %s
+// RUN: %clang -target aarch64 -march=armv8-a+nofp+nosimd+nocrc+nocrypto+fp+simd+crc+crypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MARCH-1 %s
+// RUN: %clang -target aarch64 -march=armv8-a+nofp+nosimd+nocrc+nocrypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MARCH-2 %s
+// RUN: %clang -target aarch64 -march=armv8-a+fp+simd+crc+crypto+nofp+nosimd+nocrc+nocrypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MARCH-2 %s
+// RUN: %clang -target aarch64 -march=armv8-a+nosimd -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MARCH-3 %s
+// CHECK-MARCH-1: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+fp-armv8" "-target-feature" "+neon" "-target-feature" "+crc" "-target-feature" "+crypto"
+// CHECK-MARCH-2: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "-fp-armv8" "-target-feature" "-neon" "-target-feature" "-crc" "-target-feature" "-crypto"
+// CHECK-MARCH-3: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "-neon"
+
+// RUN: %clang -target aarch64 -mcpu=cyclone+nocrypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-1 %s
+// RUN: %clang -target aarch64 -mcpu=cyclone+crypto+nocrypto -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-1 %s
+// RUN: %clang -target aarch64 -mcpu=generic+crc -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-2 %s
+// RUN: %clang -target aarch64 -mcpu=generic+nocrc+crc -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-2 %s
+// RUN: %clang -target aarch64 -mcpu=cortex-a53+nosimd -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-3 %s
+// CHECK-MCPU-1: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+neon" "-target-feature" "+crc" "-target-feature" "-crypto" "-target-feature" "+zcm" "-target-feature" "+zcz"
+// CHECK-MCPU-2: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+neon" "-target-feature" "+crc"
+// CHECK-MCPU-3: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "-neon"
+
+// RUN: %clang -target aarch64 -mcpu=cyclone+nocrc+nocrypto -march=armv8-a -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-MARCH %s
+// RUN: %clang -target aarch64 -march=armv8-a -mcpu=cyclone+nocrc+nocrypto  -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-MARCH %s
+// CHECK-MCPU-MARCH: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+neon" "-target-feature" "+zcm" "-target-feature" "+zcz"
+
+// RUN: %clang -target aarch64 -mcpu=cortex-a53 -mtune=cyclone -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-MTUNE %s
+// RUN: %clang -target aarch64 -mtune=cyclone -mcpu=cortex-a53  -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MCPU-MTUNE %s
+// CHECK-MCPU-MTUNE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+neon" "-target-feature" "+crc" "-target-feature" "+crypto" "-target-feature" "+zcm" "-target-feature" "+zcz"
+
+// RUN: %clang -target aarch64 -mcpu=generic+neon -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-ERROR-NEON %s
+// RUN: %clang -target aarch64 -mcpu=generic+noneon -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-ERROR-NEON %s
+// RUN: %clang -target aarch64 -march=armv8-a+neon -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-ERROR-NEON %s
+// RUN: %clang -target aarch64 -march=armv8-a+noneon -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-ERROR-NEON %s
+// CHECK-ERROR-NEON: error: [no]neon is not accepted as modifier, please use [no]simd instead
diff --git a/test/Preprocessor/arm-acle-6.4.c b/test/Preprocessor/arm-acle-6.4.c
new file mode 100644
index 0000000..a656f76
--- /dev/null
+++ b/test/Preprocessor/arm-acle-6.4.c
@@ -0,0 +1,40 @@
+// RUN: %clang -target arm-eabi -mcpu=cortex-m0 -x c -E -dM %s -o - | FileCheck %s -check-prefix CHECK-CORTEX-M0
+
+// CHECK-CORTEX-M0: __ARM_32BIT_STATE 1
+// CHECK-CORTEX-M0: __ARM_ARCH 6
+// CHECK-CORTEX-M0-NOT: __ARM_ARCH_ISA_ARM
+// CHECK-CORTEX-M0: __ARM_ARCH_ISA_THUMB 1
+// CHECK-CORTEX-M0: __ARM_ARCH_PROFILE 'M'
+
+// RUN: %clang -target arm-eabi -mcpu=arm810 -x c -E -dM %s -o - | FileCheck %s -check-prefix CHECK-ARM810
+
+// CHECK-ARM810: __ARM_32BIT_STATE 1
+// CHECK-ARM810: __ARM_ARCH 4
+// CHECK-ARM810: __ARM_ARCH_ISA_ARM 1
+// CHECK-ARM810-NOT: __ARM_ARCH_ISA_THUMB
+// CHECK-ARM810-NOT: __ARM_ARCH_PROFILE
+
+// RUN: %clang -target arm-eabi -mcpu=arm7tdmi -x c -E -dM %s -o - | FileCheck %s -check-prefix CHECK-ARM7TDMI
+
+// CHECK-ARM7TDMI: __ARM_32BIT_STATE 1
+// CHECK-ARM7TDMI: __ARM_ARCH 4
+// CHECK-ARM7TDMI: __ARM_ARCH_ISA_ARM 1
+// CHECK-ARM7TDMI: __ARM_ARCH_ISA_THUMB 1
+// CHECK-ARM7TDMI-NOT: __ARM_ARCH_PROFILE
+
+// RUN: %clang -target arm-eabi -mcpu=cortex-a7 -x c -E -dM %s -o - | FileCheck %s -check-prefix CHECK-CORTEX-A7
+
+// CHECK-CORTEX-A7: __ARM_32BIT_STATE 1
+// CHECK-CORTEX-A7: __ARM_ARCH 7
+// CHECK-CORTEX-A7: __ARM_ARCH_ISA_ARM 1
+// CHECK-CORTEX-A7: __ARM_ARCH_ISA_THUMB 2
+// CHECK-CORTEX-A7: __ARM_ARCH_PROFILE 'A'
+
+// RUN: %clang -target arm-eabi -mcpu=cortex-r4 -x c -E -dM %s -o - | FileCheck %s -check-prefix CHECK-CORTEX-R4
+
+// CHECK-CORTEX-R4: __ARM_32BIT_STATE 1
+// CHECK-CORTEX-R4: __ARM_ARCH 7
+// CHECK-CORTEX-R4: __ARM_ARCH_ISA_ARM 1
+// CHECK-CORTEX-R4: __ARM_ARCH_ISA_THUMB 2
+// CHECK-CORTEX-R4: __ARM_ARCH_PROFILE 'R'
+
diff --git a/test/Preprocessor/arm-target-features.c b/test/Preprocessor/arm-target-features.c
index ae93a3d..08fe29a 100644
--- a/test/Preprocessor/arm-target-features.c
+++ b/test/Preprocessor/arm-target-features.c
@@ -8,7 +8,7 @@
 // CHECK-V7: __ARMEL__ 1
 // CHECK-V7: __ARM_ARCH 7
 // CHECK-V7: __ARM_ARCH_7A__ 1
-// CHECK-NOT-V7: __ARM_FEATURE_CRC32
+// CHECK-V7-NOT: __ARM_FEATURE_CRC32
 
 // RUN: %clang -target armv8a -mfloat-abi=hard -x c -E -dM %s | FileCheck --check-prefix=CHECK-V8-BAREHF %s
 // CHECK-V8-BAREHF: __ARMEL__ 1
@@ -68,6 +68,15 @@
 // RUN: %clang -target armv8a-eabi -x c -E -dM %s -o - | FileCheck --check-prefix=THUMBV8A-EABI %s
 // THUMBV8A-EABI:#define __ARM_ARCH_EXT_IDIV__ 1
 
+// RUN: %clang -target arm-none-linux-gnu -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-DEFS %s
+// CHECK-DEFS:#define __ARM_SIZEOF_MINIMAL_ENUM 4
+// CHECK-DEFS:#define __ARM_SIZEOF_WCHAR_T 4
+
+// RUN: %clang -target arm-none-linux-gnu -fshort-wchar -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SHORTWCHAR %s
+// CHECK-SHORTWCHAR:#define __ARM_SIZEOF_WCHAR_T 2
+
+// RUN: %clang -target arm-none-linux-gnu -fshort-enums -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SHORTENUMS %s
+// CHECK-SHORTENUMS:#define __ARM_SIZEOF_MINIMAL_ENUM 1
 
 // Test that -mhwdiv has the right effect for a target CPU which has hwdiv enabled by default.
 // RUN: %clang -target armv7 -mcpu=cortex-a15 -x c -E -dM %s -o - | FileCheck --check-prefix=DEFAULTHWDIV-ARM %s
@@ -94,6 +103,39 @@
 // RUN: %clang -target arm -mthumb -mcpu=cortex-a15 -mhwdiv=none -x c -E -dM %s -o - | FileCheck --check-prefix=DEFAULTHWDIV-NONEHWDIV-THUMB %s
 // DEFAULTHWDIV-NONEHWDIV-THUMB-NOT:#define __ARM_ARCH_EXT_IDIV__
 
+
+// Check that -mfpu works properly for Cortex-A7 (enabled by default).
+// RUN: %clang -target armv7-none-linux-gnueabi -mcpu=cortex-a7 -x c -E -dM %s -o - | FileCheck --check-prefix=DEFAULTFPU-A7 %s
+// RUN: %clang -target armv7-none-linux-gnueabi -mthumb -mcpu=cortex-a7 -x c -E -dM %s -o - | FileCheck --check-prefix=DEFAULTFPU-A7 %s
+// DEFAULTFPU-A7:#define __ARM_NEON__ 1
+// DEFAULTFPU-A7:#define __ARM_VFPV4__ 1
+
+// RUN: %clang -target armv7-none-linux-gnueabi -mcpu=cortex-a7 -mfpu=none -x c -E -dM %s -o - | FileCheck --check-prefix=FPUNONE-A7 %s
+// RUN: %clang -target armv7-none-linux-gnueabi -mthumb -mcpu=cortex-a7 -mfpu=none -x c -E -dM %s -o - | FileCheck --check-prefix=FPUNONE-A7 %s
+// FPUNONE-A7-NOT:#define __ARM_NEON__ 1
+// FPUNONE-A7-NOT:#define __ARM_VFPV4__ 1
+
+// RUN: %clang -target armv7-none-linux-gnueabi -mcpu=cortex-a7 -mfpu=vfp4 -x c -E -dM %s -o - | FileCheck --check-prefix=NONEON-A7 %s
+// RUN: %clang -target armv7-none-linux-gnueabi -mthumb -mcpu=cortex-a7 -mfpu=vfp4 -x c -E -dM %s -o - | FileCheck --check-prefix=NONEON-A7 %s
+// NONEON-A7-NOT:#define __ARM_NEON__ 1
+// NONEON-A7:#define __ARM_VFPV4__ 1
+
+// Check that -mfpu works properly for Cortex-A5 (enabled by default).
+// RUN: %clang -target armv7-none-linux-gnueabi -mcpu=cortex-a5 -x c -E -dM %s -o - | FileCheck --check-prefix=DEFAULTFPU-A5 %s
+// RUN: %clang -target armv7-none-linux-gnueabi -mthumb -mcpu=cortex-a5 -x c -E -dM %s -o - | FileCheck --check-prefix=DEFAULTFPU-A5 %s
+// DEFAULTFPU-A5:#define __ARM_NEON__ 1
+// DEFAULTFPU-A5:#define __ARM_VFPV4__ 1
+
+// RUN: %clang -target armv7-none-linux-gnueabi -mcpu=cortex-a5 -mfpu=none -x c -E -dM %s -o - | FileCheck --check-prefix=FPUNONE-A5 %s
+// RUN: %clang -target armv7-none-linux-gnueabi -mthumb -mcpu=cortex-a5 -mfpu=none -x c -E -dM %s -o - | FileCheck --check-prefix=FPUNONE-A5 %s
+// FPUNONE-A5-NOT:#define __ARM_NEON__ 1
+// FPUNONE-A5-NOT:#define __ARM_VFPV4__ 1
+
+// RUN: %clang -target armv7-none-linux-gnueabi -mcpu=cortex-a5 -mfpu=vfp3-d16 -x c -E -dM %s -o - | FileCheck --check-prefix=NONEON-A5 %s
+// RUN: %clang -target armv7-none-linux-gnueabi -mthumb -mcpu=cortex-a5 -mfpu=vfp3-d16 -x c -E -dM %s -o - | FileCheck --check-prefix=NONEON-A5 %s
+// NONEON-A5-NOT:#define __ARM_NEON__ 1
+// NONEON-A5:#define __ARM_VFPV4__ 1
+
 // FIXME: add check for further predefines
 // Test whether predefines are as expected when targeting cortex-a5.
 // RUN: %clang -target armv7 -mcpu=cortex-a5 -x c -E -dM %s -o - | FileCheck --check-prefix=A5-ARM %s
@@ -102,6 +144,20 @@
 // RUN: %clang -target armv7 -mthumb -mcpu=cortex-a5 -x c -E -dM %s -o - | FileCheck --check-prefix=A5-THUMB %s
 // A5-THUMB-NOT:#define __ARM_ARCH_EXT_IDIV__
 
+// RUN: %clang -target armv7 -mcpu=cortex-a5 -x c -E -dM %s -o - | FileCheck --check-prefix=A5 %s
+// RUN: %clang -target armv7 -mthumb -mcpu=cortex-a5 -x c -E -dM %s -o - | FileCheck --check-prefix=A5 %s
+// A5:#define __ARM_ARCH 7
+// A5:#define __ARM_ARCH_7A__ 1
+// A5:#define __ARM_ARCH_PROFILE 'A'
+
+// Test whether predefines are as expected when targeting cortex-a7.
+// RUN: %clang -target armv7 -mcpu=cortex-a7 -x c -E -dM %s -o - | FileCheck --check-prefix=A7 %s
+// RUN: %clang -target armv7 -mthumb -mcpu=cortex-a7 -x c -E -dM %s -o - | FileCheck --check-prefix=A7 %s
+// A7:#define __ARM_ARCH 7
+// A7:#define __ARM_ARCH_7A__ 1
+// A7:#define __ARM_ARCH_EXT_IDIV__ 1
+// A7:#define __ARM_ARCH_PROFILE 'A'
+
 // Test whether predefines are as expected when targeting cortex-a8.
 // RUN: %clang -target armv7 -mcpu=cortex-a8 -x c -E -dM %s -o - | FileCheck --check-prefix=A8-ARM %s
 // A8-ARM-NOT:#define __ARM_ARCH_EXT_IDIV__
@@ -116,6 +172,26 @@
 // RUN: %clang -target armv7 -mthumb -mcpu=cortex-a9 -x c -E -dM %s -o - | FileCheck --check-prefix=A9-THUMB %s
 // A9-THUMB-NOT:#define __ARM_ARCH_EXT_IDIV__
 
+
+// Check that -mfpu works properly for Cortex-A12 (enabled by default).
+// RUN: %clang -target armv7-none-linux-gnueabi -mcpu=cortex-a12 -x c -E -dM %s -o - | FileCheck --check-prefix=DEFAULTFPU-A12 %s
+// RUN: %clang -target armv7-none-linux-gnueabi -mthumb -mcpu=cortex-a12 -x c -E -dM %s -o - | FileCheck --check-prefix=DEFAULTFPU-A12 %s
+// DEFAULTFPU-A12:#define __ARM_NEON__ 1
+// DEFAULTFPU-A12:#define __ARM_VFPV4__ 1
+
+// RUN: %clang -target armv7-none-linux-gnueabi -mcpu=cortex-a12 -mfpu=none -x c -E -dM %s -o - | FileCheck --check-prefix=FPUNONE-A12 %s
+// RUN: %clang -target armv7-none-linux-gnueabi -mthumb -mcpu=cortex-a12 -mfpu=none -x c -E -dM %s -o - | FileCheck --check-prefix=FPUNONE-A12 %s
+// FPUNONE-A12-NOT:#define __ARM_NEON__ 1
+// FPUNONE-A12-NOT:#define __ARM_VFPV4__ 1
+
+// Test whether predefines are as expected when targeting cortex-a12.
+// RUN: %clang -target armv7 -mcpu=cortex-a12 -x c -E -dM %s -o - | FileCheck --check-prefix=A12 %s
+// RUN: %clang -target armv7 -mthumb -mcpu=cortex-a12 -x c -E -dM %s -o - | FileCheck --check-prefix=A12 %s
+// A12:#define __ARM_ARCH 7
+// A12:#define __ARM_ARCH_7A__ 1
+// A12:#define __ARM_ARCH_EXT_IDIV__ 1
+// A12:#define __ARM_ARCH_PROFILE 'A'
+
 // Test whether predefines are as expected when targeting cortex-a15.
 // RUN: %clang -target armv7 -mcpu=cortex-a15 -x c -E -dM %s -o - | FileCheck --check-prefix=A15-ARM %s
 // A15-ARM:#define __ARM_ARCH_EXT_IDIV__ 1
@@ -155,3 +231,13 @@
 // Test whether predefines are as expected when targeting cortex-m4.
 // RUN: %clang -target armv7 -mthumb -mcpu=cortex-m4 -x c -E -dM %s -o - | FileCheck --check-prefix=M4-THUMB %s
 // M4-THUMB:#define __ARM_ARCH_EXT_IDIV__ 1
+
+// Test whether predefines are as expected when targeting krait.
+// RUN: %clang -target armv7 -mcpu=krait -x c -E -dM %s -o - | FileCheck --check-prefix=KRAIT-ARM %s
+// KRAIT-ARM:#define __ARM_ARCH_EXT_IDIV__ 1
+// KRAIT-ARM:#define  __ARM_VFPV4__ 1
+
+// RUN: %clang -target armv7 -mthumb -mcpu=krait -x c -E -dM %s -o - | FileCheck --check-prefix=KRAIT-THUMB %s
+// KRAIT-THUMB:#define __ARM_ARCH_EXT_IDIV__ 1
+// KRAIT-THUMB:#define  __ARM_VFPV4__ 1
+
diff --git a/test/Preprocessor/cxx_oper_keyword.cpp b/test/Preprocessor/cxx_oper_keyword.cpp
index 3fc246d..89a094d 100644
--- a/test/Preprocessor/cxx_oper_keyword.cpp
+++ b/test/Preprocessor/cxx_oper_keyword.cpp
@@ -1,7 +1,31 @@
-// RUN: not %clang_cc1 %s -E
-// RUN: %clang_cc1 %s -E -fno-operator-names
+// RUN: %clang_cc1 %s -E -verify -DOPERATOR_NAMES
+// RUN: %clang_cc1 %s -E -verify -fno-operator-names
 
-// Not valid in C++ unless -fno-operator-names is passed.
+#ifndef OPERATOR_NAMES
+//expected-error@+3 {{token is not a valid binary operator in a preprocessor subexpression}}
+#endif
+// Valid because 'and' is a spelling of '&&'
+#if defined foo and bar
+#endif
+
+// Not valid in C++ unless -fno-operator-names is passed:
+
+#ifdef OPERATOR_NAMES
+//expected-error@+2 {{C++ operator 'and' (aka '&&') used as a macro name}}
+#endif
 #define and foo
 
+#ifdef OPERATOR_NAMES
+//expected-error@+2 {{C++ operator 'xor' (aka '^') used as a macro name}}
+#endif
+#if defined xor
+#endif
 
+// For error recovery we continue as though the identifier was a macro name regardless of -fno-operator-names.
+#ifdef OPERATOR_NAMES
+//expected-error@+3 {{C++ operator 'and' (aka '&&') used as a macro name}}
+#endif
+//expected-warning@+2 {{and is defined}}
+#ifdef and
+#warning and is defined
+#endif
diff --git a/test/Preprocessor/cxx_oper_keyword_ms_compat.cpp b/test/Preprocessor/cxx_oper_keyword_ms_compat.cpp
index 1c6ef90..8e1351e 100644
--- a/test/Preprocessor/cxx_oper_keyword_ms_compat.cpp
+++ b/test/Preprocessor/cxx_oper_keyword_ms_compat.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 %s -E -fms-compatibility
+// RUN: %clang_cc1 %s -E -verify -fms-extensions
+// expected-no-diagnostics
 
 bool f() {
   // Check that operators still work before redefining them.
@@ -7,6 +8,13 @@
 #endif
 }
 
+#ifdef and
+#endif
+
+// The second 'and' is a valid C++ operator name for '&&'.
+#if defined and and defined(and)
+#endif
+
 // All c++ keywords should be #define-able in ms mode.
 // (operators like "and" aren't normally, the rest always is.)
 #define and
diff --git a/test/Preprocessor/has_attribute.c b/test/Preprocessor/has_attribute.c
index 555c2b3..5fe060e 100644
--- a/test/Preprocessor/has_attribute.c
+++ b/test/Preprocessor/has_attribute.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -E %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple arm-unknown-linux -E %s -o - | FileCheck %s
 
 // CHECK: always_inline
 #if __has_attribute(always_inline)
@@ -38,3 +38,13 @@
 #if !__has_attribute(volatile)
 int has_no_volatile_attribute();
 #endif
+
+// CHECK: has_arm_interrupt
+#if __has_attribute(interrupt)
+  int has_arm_interrupt();
+#endif
+
+// CHECK: does_not_have_dllexport
+#if !__has_attribute(dllexport)
+  int does_not_have_dllexport();
+#endif
diff --git a/test/Preprocessor/header_lookup1.c b/test/Preprocessor/header_lookup1.c
index d090936..336aba6 100644
--- a/test/Preprocessor/header_lookup1.c
+++ b/test/Preprocessor/header_lookup1.c
@@ -1,2 +1,2 @@
-// RUN: %clang -fno-ms-extensions %s -E | grep 'stddef.h.*3'
+// RUN: %clang_cc1 %s -E | grep 'stddef.h.*3'
 #include <stddef.h>
diff --git a/test/Preprocessor/headermap-rel.c b/test/Preprocessor/headermap-rel.c
new file mode 100644
index 0000000..38500a7
--- /dev/null
+++ b/test/Preprocessor/headermap-rel.c
@@ -0,0 +1,12 @@
+
+// This uses a headermap with this entry:
+//   Foo.h -> Foo/Foo.h
+
+// RUN: %clang_cc1 -E %s -o %t.i -I %S/Inputs/headermap-rel/foo.hmap -F %S/Inputs/headermap-rel
+// RUN: FileCheck %s -input-file %t.i
+
+// CHECK: Foo.h is parsed
+// CHECK: Foo.h is parsed
+
+#include "Foo.h"
+#include "Foo.h"
diff --git a/test/Preprocessor/headermap-rel2.c b/test/Preprocessor/headermap-rel2.c
new file mode 100644
index 0000000..430854d
--- /dev/null
+++ b/test/Preprocessor/headermap-rel2.c
@@ -0,0 +1,14 @@
+// This uses a headermap with this entry:
+//   someheader.h -> Product/someheader.h
+
+// RUN: %clang_cc1 -triple x86_64-apple-darwin13 -v -fsyntax-only %s -iquote %S/Inputs/headermap-rel2/project-headers.hmap -isysroot %S/Inputs/headermap-rel2/system -I %S/Inputs/headermap-rel2 -H
+// RUN: %clang_cc1 -triple x86_64-apple-darwin13 -fsyntax-only %s -iquote %S/Inputs/headermap-rel2/project-headers.hmap -isysroot %S/Inputs/headermap-rel2/system -I %S/Inputs/headermap-rel2 -H 2> %t.out
+// RUN: FileCheck %s -input-file %t.out
+
+// CHECK: Product/someheader.h
+// CHECK: system/usr/include{{[/\\]+}}someheader.h
+// CHECK: system/usr/include{{[/\\]+}}someheader.h
+
+#include "someheader.h"
+#include <someheader.h>
+#include <someheader.h>
diff --git a/test/Preprocessor/ifdef-recover.c b/test/Preprocessor/ifdef-recover.c
index 3d652dc..a648135 100644
--- a/test/Preprocessor/ifdef-recover.c
+++ b/test/Preprocessor/ifdef-recover.c
@@ -1,15 +1,22 @@
-/* RUN: not %clang_cc1 -E %s 2>&1 >/dev/null | grep error: | count 3
+/* RUN: %clang_cc1 -E -verify %s
  */
 
+/* expected-error@+1 {{macro name missing}} */
 #ifdef
-
 #endif
 
-/* End of function-like macro invocation in #ifdef */
+/* expected-error@+1 {{macro name must be an identifier}} */
+#ifdef !
+#endif
+
+/* expected-error@+1 {{macro name missing}} */
+#if defined
+#endif
+
 /* PR1936 */
+/* expected-error@+2 {{unterminated function-like macro invocation}} expected-error@+2 {{expected value in expression}} expected-note@+1 {{macro 'f' defined here}} */
 #define f(x) x
 #if f(2
 #endif
 
 int x;
-
diff --git a/test/Preprocessor/ignore-pragmas.c b/test/Preprocessor/ignore-pragmas.c
new file mode 100644
index 0000000..e2f9ef3
--- /dev/null
+++ b/test/Preprocessor/ignore-pragmas.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -E %s -Wall -verify
+// RUN: %clang_cc1 -Eonly %s -Wall -verify
+// RUN: %clang -M -Wall %s -Xclang -verify
+// RUN: %clang -E -frewrite-includes %s -Wall -Xclang -verify
+// RUN: %clang -E -dD -dM %s -Wall -Xclang -verify
+// expected-no-diagnostics
+
+#pragma GCC visibility push (default)
+#pragma weak
+#pragma this_pragma_does_not_exist
diff --git a/test/Preprocessor/init.c b/test/Preprocessor/init.c
index 8486e94..7b73ce0 100644
--- a/test/Preprocessor/init.c
+++ b/test/Preprocessor/init.c
@@ -9,13 +9,23 @@
 // BLOCKS:#define __block __attribute__((__blocks__(byref)))
 //
 //
+// RUN: %clang_cc1 -x c++ -std=c++1z -E -dM < /dev/null | FileCheck -check-prefix CXX1Z %s
+//
+// CXX1Z:#define __GNUG__
+// CXX1Z:#define __GXX_EXPERIMENTAL_CXX0X__ 1
+// CXX1Z:#define __GXX_RTTI 1
+// CXX1Z:#define __GXX_WEAK__ 1
+// CXX1Z:#define __cplusplus 201406L
+// CXX1Z:#define __private_extern__ extern
+//
+//
 // RUN: %clang_cc1 -x c++ -std=c++1y -E -dM < /dev/null | FileCheck -check-prefix CXX1Y %s
 //
 // CXX1Y:#define __GNUG__
 // CXX1Y:#define __GXX_EXPERIMENTAL_CXX0X__ 1
 // CXX1Y:#define __GXX_RTTI 1
 // CXX1Y:#define __GXX_WEAK__ 1
-// CXX1Y:#define __cplusplus 201305L
+// CXX1Y:#define __cplusplus 201402L
 // CXX1Y:#define __private_extern__ extern
 //
 //
@@ -85,11 +95,19 @@
 // FREESTANDING:#define __STDC_HOSTED__ 0
 //
 //
+// RUN: %clang_cc1 -x c++ -std=gnu++1z -E -dM < /dev/null | FileCheck -check-prefix GXX1Z %s
+//
+// GXX1Z:#define __GNUG__
+// GXX1Z:#define __GXX_WEAK__ 1
+// GXX1Z:#define __cplusplus 201406L
+// GXX1Z:#define __private_extern__ extern
+//
+//
 // RUN: %clang_cc1 -x c++ -std=gnu++1y -E -dM < /dev/null | FileCheck -check-prefix GXX1Y %s
 //
 // GXX1Y:#define __GNUG__
 // GXX1Y:#define __GXX_WEAK__ 1
-// GXX1Y:#define __cplusplus 201305L
+// GXX1Y:#define __cplusplus 201402L
 // GXX1Y:#define __private_extern__ extern
 //
 //
@@ -196,18 +214,603 @@
 // SCHAR:#define __clang__ 1
 //
 // RUN: %clang_cc1 -E -dM -fshort-wchar < /dev/null | FileCheck -check-prefix SHORTWCHAR %s
+// wchar_t is u16 for targeting Win32.
+// FIXME: Implement and check x86_64-cygwin.
+// RUN: %clang_cc1 -E -dM -fno-short-wchar -triple=x86_64-w64-mingw32 < /dev/null | FileCheck -check-prefix SHORTWCHAR %s
 //
 // SHORTWCHAR: #define __SIZEOF_WCHAR_T__ 2
-// SHORTWCHAR: #define __WCHAR_MAX__ 65535U
+// SHORTWCHAR: #define __WCHAR_MAX__ 65535
 // SHORTWCHAR: #define __WCHAR_TYPE__ unsigned short
 // SHORTWCHAR: #define __WCHAR_WIDTH__ 16
 //
+// RUN: %clang_cc1 -E -dM -fno-short-wchar -triple=i686-unknown-unknown < /dev/null | FileCheck -check-prefix SHORTWCHAR2 %s
+// RUN: %clang_cc1 -E -dM -fno-short-wchar -triple=x86_64-unknown-unknown < /dev/null | FileCheck -check-prefix SHORTWCHAR2 %s
+//
+// SHORTWCHAR2: #define __SIZEOF_WCHAR_T__ 4
+// SHORTWCHAR2: #define __WCHAR_WIDTH__ 32
+// Other definitions vary from platform to platform
+
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=aarch64-none-none < /dev/null | FileCheck -check-prefix AARCH64 %s
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=arm64-none-none < /dev/null | FileCheck -check-prefix AARCH64 %s
+//
+// AARCH64:#define _LP64 1
+// AARCH64-NOT:#define __AARCH64EB__ 1
+// AARCH64:#define __AARCH64EL__ 1
+// AARCH64-NOT:#define __AARCH_BIG_ENDIAN 1
+// AARCH64:#define __ARM_64BIT_STATE 1
+// AARCH64:#define __ARM_ARCH 8
+// AARCH64:#define __ARM_ARCH_ISA_A64 1
+// AARCH64-NOT:#define __ARM_BIG_ENDIAN 1
+// AARCH64:#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
+// AARCH64:#define __CHAR16_TYPE__ unsigned short
+// AARCH64:#define __CHAR32_TYPE__ unsigned int
+// AARCH64:#define __CHAR_BIT__ 8
+// AARCH64:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
+// AARCH64:#define __DBL_DIG__ 15
+// AARCH64:#define __DBL_EPSILON__ 2.2204460492503131e-16
+// AARCH64:#define __DBL_HAS_DENORM__ 1
+// AARCH64:#define __DBL_HAS_INFINITY__ 1
+// AARCH64:#define __DBL_HAS_QUIET_NAN__ 1
+// AARCH64:#define __DBL_MANT_DIG__ 53
+// AARCH64:#define __DBL_MAX_10_EXP__ 308
+// AARCH64:#define __DBL_MAX_EXP__ 1024
+// AARCH64:#define __DBL_MAX__ 1.7976931348623157e+308
+// AARCH64:#define __DBL_MIN_10_EXP__ (-307)
+// AARCH64:#define __DBL_MIN_EXP__ (-1021)
+// AARCH64:#define __DBL_MIN__ 2.2250738585072014e-308
+// AARCH64:#define __DECIMAL_DIG__ 36
+// AARCH64:#define __FLT_DENORM_MIN__ 1.40129846e-45F
+// AARCH64:#define __FLT_DIG__ 6
+// AARCH64:#define __FLT_EPSILON__ 1.19209290e-7F
+// AARCH64:#define __FLT_EVAL_METHOD__ 0
+// AARCH64:#define __FLT_HAS_DENORM__ 1
+// AARCH64:#define __FLT_HAS_INFINITY__ 1
+// AARCH64:#define __FLT_HAS_QUIET_NAN__ 1
+// AARCH64:#define __FLT_MANT_DIG__ 24
+// AARCH64:#define __FLT_MAX_10_EXP__ 38
+// AARCH64:#define __FLT_MAX_EXP__ 128
+// AARCH64:#define __FLT_MAX__ 3.40282347e+38F
+// AARCH64:#define __FLT_MIN_10_EXP__ (-37)
+// AARCH64:#define __FLT_MIN_EXP__ (-125)
+// AARCH64:#define __FLT_MIN__ 1.17549435e-38F
+// AARCH64:#define __FLT_RADIX__ 2
+// AARCH64:#define __INT16_C_SUFFIX__ {{$}}
+// AARCH64:#define __INT16_FMTd__ "hd"
+// AARCH64:#define __INT16_FMTi__ "hi"
+// AARCH64:#define __INT16_MAX__ 32767
+// AARCH64:#define __INT16_TYPE__ short
+// AARCH64:#define __INT32_C_SUFFIX__ {{$}}
+// AARCH64:#define __INT32_FMTd__ "d"
+// AARCH64:#define __INT32_FMTi__ "i"
+// AARCH64:#define __INT32_MAX__ 2147483647
+// AARCH64:#define __INT32_TYPE__ int
+// AARCH64:#define __INT64_C_SUFFIX__ L
+// AARCH64:#define __INT64_FMTd__ "ld"
+// AARCH64:#define __INT64_FMTi__ "li"
+// AARCH64:#define __INT64_MAX__ 9223372036854775807L
+// AARCH64:#define __INT64_TYPE__ long int
+// AARCH64:#define __INT8_C_SUFFIX__ {{$}}
+// AARCH64:#define __INT8_FMTd__ "hhd"
+// AARCH64:#define __INT8_FMTi__ "hhi"
+// AARCH64:#define __INT8_MAX__ 127
+// AARCH64:#define __INT8_TYPE__ signed char
+// AARCH64:#define __INTMAX_C_SUFFIX__ L
+// AARCH64:#define __INTMAX_FMTd__ "ld"
+// AARCH64:#define __INTMAX_FMTi__ "li"
+// AARCH64:#define __INTMAX_MAX__ 9223372036854775807L
+// AARCH64:#define __INTMAX_TYPE__ long int
+// AARCH64:#define __INTMAX_WIDTH__ 64
+// AARCH64:#define __INTPTR_FMTd__ "ld"
+// AARCH64:#define __INTPTR_FMTi__ "li"
+// AARCH64:#define __INTPTR_MAX__ 9223372036854775807L
+// AARCH64:#define __INTPTR_TYPE__ long int
+// AARCH64:#define __INTPTR_WIDTH__ 64
+// AARCH64:#define __INT_FAST16_FMTd__ "hd"
+// AARCH64:#define __INT_FAST16_FMTi__ "hi"
+// AARCH64:#define __INT_FAST16_MAX__ 32767
+// AARCH64:#define __INT_FAST16_TYPE__ short
+// AARCH64:#define __INT_FAST32_FMTd__ "d"
+// AARCH64:#define __INT_FAST32_FMTi__ "i"
+// AARCH64:#define __INT_FAST32_MAX__ 2147483647
+// AARCH64:#define __INT_FAST32_TYPE__ int
+// AARCH64:#define __INT_FAST64_FMTd__ "ld"
+// AARCH64:#define __INT_FAST64_FMTi__ "li"
+// AARCH64:#define __INT_FAST64_MAX__ 9223372036854775807L
+// AARCH64:#define __INT_FAST64_TYPE__ long int
+// AARCH64:#define __INT_FAST8_FMTd__ "hhd"
+// AARCH64:#define __INT_FAST8_FMTi__ "hhi"
+// AARCH64:#define __INT_FAST8_MAX__ 127
+// AARCH64:#define __INT_FAST8_TYPE__ signed char
+// AARCH64:#define __INT_LEAST16_FMTd__ "hd"
+// AARCH64:#define __INT_LEAST16_FMTi__ "hi"
+// AARCH64:#define __INT_LEAST16_MAX__ 32767
+// AARCH64:#define __INT_LEAST16_TYPE__ short
+// AARCH64:#define __INT_LEAST32_FMTd__ "d"
+// AARCH64:#define __INT_LEAST32_FMTi__ "i"
+// AARCH64:#define __INT_LEAST32_MAX__ 2147483647
+// AARCH64:#define __INT_LEAST32_TYPE__ int
+// AARCH64:#define __INT_LEAST64_FMTd__ "ld"
+// AARCH64:#define __INT_LEAST64_FMTi__ "li"
+// AARCH64:#define __INT_LEAST64_MAX__ 9223372036854775807L
+// AARCH64:#define __INT_LEAST64_TYPE__ long int
+// AARCH64:#define __INT_LEAST8_FMTd__ "hhd"
+// AARCH64:#define __INT_LEAST8_FMTi__ "hhi"
+// AARCH64:#define __INT_LEAST8_MAX__ 127
+// AARCH64:#define __INT_LEAST8_TYPE__ signed char
+// AARCH64:#define __INT_MAX__ 2147483647
+// AARCH64:#define __LDBL_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966L
+// AARCH64:#define __LDBL_DIG__ 33
+// AARCH64:#define __LDBL_EPSILON__ 1.92592994438723585305597794258492732e-34L
+// AARCH64:#define __LDBL_HAS_DENORM__ 1
+// AARCH64:#define __LDBL_HAS_INFINITY__ 1
+// AARCH64:#define __LDBL_HAS_QUIET_NAN__ 1
+// AARCH64:#define __LDBL_MANT_DIG__ 113
+// AARCH64:#define __LDBL_MAX_10_EXP__ 4932
+// AARCH64:#define __LDBL_MAX_EXP__ 16384
+// AARCH64:#define __LDBL_MAX__ 1.18973149535723176508575932662800702e+4932L
+// AARCH64:#define __LDBL_MIN_10_EXP__ (-4931)
+// AARCH64:#define __LDBL_MIN_EXP__ (-16381)
+// AARCH64:#define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L
+// AARCH64:#define __LONG_LONG_MAX__ 9223372036854775807LL
+// AARCH64:#define __LONG_MAX__ 9223372036854775807L
+// AARCH64:#define __LP64__ 1
+// AARCH64:#define __POINTER_WIDTH__ 64
+// AARCH64:#define __PTRDIFF_TYPE__ long int
+// AARCH64:#define __PTRDIFF_WIDTH__ 64
+// AARCH64:#define __SCHAR_MAX__ 127
+// AARCH64:#define __SHRT_MAX__ 32767
+// AARCH64:#define __SIG_ATOMIC_MAX__ 2147483647
+// AARCH64:#define __SIG_ATOMIC_WIDTH__ 32
+// AARCH64:#define __SIZEOF_DOUBLE__ 8
+// AARCH64:#define __SIZEOF_FLOAT__ 4
+// AARCH64:#define __SIZEOF_INT128__ 16
+// AARCH64:#define __SIZEOF_INT__ 4
+// AARCH64:#define __SIZEOF_LONG_DOUBLE__ 16
+// AARCH64:#define __SIZEOF_LONG_LONG__ 8
+// AARCH64:#define __SIZEOF_LONG__ 8
+// AARCH64:#define __SIZEOF_POINTER__ 8
+// AARCH64:#define __SIZEOF_PTRDIFF_T__ 8
+// AARCH64:#define __SIZEOF_SHORT__ 2
+// AARCH64:#define __SIZEOF_SIZE_T__ 8
+// AARCH64:#define __SIZEOF_WCHAR_T__ 4
+// AARCH64:#define __SIZEOF_WINT_T__ 4
+// AARCH64:#define __SIZE_MAX__ 18446744073709551615UL
+// AARCH64:#define __SIZE_TYPE__ long unsigned int
+// AARCH64:#define __SIZE_WIDTH__ 64
+// AARCH64:#define __UINT16_C_SUFFIX__ {{$}}
+// AARCH64:#define __UINT16_MAX__ 65535
+// AARCH64:#define __UINT16_TYPE__ unsigned short
+// AARCH64:#define __UINT32_C_SUFFIX__ U
+// AARCH64:#define __UINT32_MAX__ 4294967295U
+// AARCH64:#define __UINT32_TYPE__ unsigned int
+// AARCH64:#define __UINT64_C_SUFFIX__ UL
+// AARCH64:#define __UINT64_MAX__ 18446744073709551615UL
+// AARCH64:#define __UINT64_TYPE__ long unsigned int
+// AARCH64:#define __UINT8_C_SUFFIX__ {{$}}
+// AARCH64:#define __UINT8_MAX__ 255
+// AARCH64:#define __UINT8_TYPE__ unsigned char
+// AARCH64:#define __UINTMAX_C_SUFFIX__ UL
+// AARCH64:#define __UINTMAX_MAX__ 18446744073709551615UL
+// AARCH64:#define __UINTMAX_TYPE__ long unsigned int
+// AARCH64:#define __UINTMAX_WIDTH__ 64
+// AARCH64:#define __UINTPTR_MAX__ 18446744073709551615UL
+// AARCH64:#define __UINTPTR_TYPE__ long unsigned int
+// AARCH64:#define __UINTPTR_WIDTH__ 64
+// AARCH64:#define __UINT_FAST16_MAX__ 65535
+// AARCH64:#define __UINT_FAST16_TYPE__ unsigned short
+// AARCH64:#define __UINT_FAST32_MAX__ 4294967295U
+// AARCH64:#define __UINT_FAST32_TYPE__ unsigned int
+// AARCH64:#define __UINT_FAST64_MAX__ 18446744073709551615UL
+// AARCH64:#define __UINT_FAST64_TYPE__ long unsigned int
+// AARCH64:#define __UINT_FAST8_MAX__ 255
+// AARCH64:#define __UINT_FAST8_TYPE__ unsigned char
+// AARCH64:#define __UINT_LEAST16_MAX__ 65535
+// AARCH64:#define __UINT_LEAST16_TYPE__ unsigned short
+// AARCH64:#define __UINT_LEAST32_MAX__ 4294967295U
+// AARCH64:#define __UINT_LEAST32_TYPE__ unsigned int
+// AARCH64:#define __UINT_LEAST64_MAX__ 18446744073709551615UL
+// AARCH64:#define __UINT_LEAST64_TYPE__ long unsigned int
+// AARCH64:#define __UINT_LEAST8_MAX__ 255
+// AARCH64:#define __UINT_LEAST8_TYPE__ unsigned char
+// AARCH64:#define __USER_LABEL_PREFIX__ _
+// AARCH64:#define __WCHAR_MAX__ 4294967295U
+// AARCH64:#define __WCHAR_TYPE__ unsigned int
+// AARCH64:#define __WCHAR_UNSIGNED__ 1
+// AARCH64:#define __WCHAR_WIDTH__ 32
+// AARCH64:#define __WINT_TYPE__ int
+// AARCH64:#define __WINT_WIDTH__ 32
+// AARCH64:#define __aarch64__ 1
+//
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=aarch64_be-none-none < /dev/null | FileCheck -check-prefix AARCH64-BE %s
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=arm64_be-none-none < /dev/null | FileCheck -check-prefix AARCH64-BE %s
+//
+// AARCH64-BE:#define _LP64 1
+// AARCH64-BE:#define __AARCH64EB__ 1
+// AARCH64-BE-NOT:#define __AARCH64EL__ 1
+// AARCH64-BE:#define __AARCH_BIG_ENDIAN 1
+// AARCH64-BE:#define __ARM_64BIT_STATE 1
+// AARCH64-BE:#define __ARM_ARCH 8
+// AARCH64-BE:#define __ARM_ARCH_ISA_A64 1
+// AARCH64-BE:#define __ARM_BIG_ENDIAN 1
+// AARCH64-BE:#define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__
+// AARCH64-BE:#define __CHAR16_TYPE__ unsigned short
+// AARCH64-BE:#define __CHAR32_TYPE__ unsigned int
+// AARCH64-BE:#define __CHAR_BIT__ 8
+// AARCH64-BE:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
+// AARCH64-BE:#define __DBL_DIG__ 15
+// AARCH64-BE:#define __DBL_EPSILON__ 2.2204460492503131e-16
+// AARCH64-BE:#define __DBL_HAS_DENORM__ 1
+// AARCH64-BE:#define __DBL_HAS_INFINITY__ 1
+// AARCH64-BE:#define __DBL_HAS_QUIET_NAN__ 1
+// AARCH64-BE:#define __DBL_MANT_DIG__ 53
+// AARCH64-BE:#define __DBL_MAX_10_EXP__ 308
+// AARCH64-BE:#define __DBL_MAX_EXP__ 1024
+// AARCH64-BE:#define __DBL_MAX__ 1.7976931348623157e+308
+// AARCH64-BE:#define __DBL_MIN_10_EXP__ (-307)
+// AARCH64-BE:#define __DBL_MIN_EXP__ (-1021)
+// AARCH64-BE:#define __DBL_MIN__ 2.2250738585072014e-308
+// AARCH64-BE:#define __DECIMAL_DIG__ 36
+// AARCH64-BE:#define __FLT_DENORM_MIN__ 1.40129846e-45F
+// AARCH64-BE:#define __FLT_DIG__ 6
+// AARCH64-BE:#define __FLT_EPSILON__ 1.19209290e-7F
+// AARCH64-BE:#define __FLT_EVAL_METHOD__ 0
+// AARCH64-BE:#define __FLT_HAS_DENORM__ 1
+// AARCH64-BE:#define __FLT_HAS_INFINITY__ 1
+// AARCH64-BE:#define __FLT_HAS_QUIET_NAN__ 1
+// AARCH64-BE:#define __FLT_MANT_DIG__ 24
+// AARCH64-BE:#define __FLT_MAX_10_EXP__ 38
+// AARCH64-BE:#define __FLT_MAX_EXP__ 128
+// AARCH64-BE:#define __FLT_MAX__ 3.40282347e+38F
+// AARCH64-BE:#define __FLT_MIN_10_EXP__ (-37)
+// AARCH64-BE:#define __FLT_MIN_EXP__ (-125)
+// AARCH64-BE:#define __FLT_MIN__ 1.17549435e-38F
+// AARCH64-BE:#define __FLT_RADIX__ 2
+// AARCH64-BE:#define __INT16_C_SUFFIX__ {{$}}
+// AARCH64-BE:#define __INT16_FMTd__ "hd"
+// AARCH64-BE:#define __INT16_FMTi__ "hi"
+// AARCH64-BE:#define __INT16_MAX__ 32767
+// AARCH64-BE:#define __INT16_TYPE__ short
+// AARCH64-BE:#define __INT32_C_SUFFIX__ {{$}}
+// AARCH64-BE:#define __INT32_FMTd__ "d"
+// AARCH64-BE:#define __INT32_FMTi__ "i"
+// AARCH64-BE:#define __INT32_MAX__ 2147483647
+// AARCH64-BE:#define __INT32_TYPE__ int
+// AARCH64-BE:#define __INT64_C_SUFFIX__ L
+// AARCH64-BE:#define __INT64_FMTd__ "ld"
+// AARCH64-BE:#define __INT64_FMTi__ "li"
+// AARCH64-BE:#define __INT64_MAX__ 9223372036854775807L
+// AARCH64-BE:#define __INT64_TYPE__ long int
+// AARCH64-BE:#define __INT8_C_SUFFIX__ {{$}}
+// AARCH64-BE:#define __INT8_FMTd__ "hhd"
+// AARCH64-BE:#define __INT8_FMTi__ "hhi"
+// AARCH64-BE:#define __INT8_MAX__ 127
+// AARCH64-BE:#define __INT8_TYPE__ signed char
+// AARCH64-BE:#define __INTMAX_C_SUFFIX__ L
+// AARCH64-BE:#define __INTMAX_FMTd__ "ld"
+// AARCH64-BE:#define __INTMAX_FMTi__ "li"
+// AARCH64-BE:#define __INTMAX_MAX__ 9223372036854775807L
+// AARCH64-BE:#define __INTMAX_TYPE__ long int
+// AARCH64-BE:#define __INTMAX_WIDTH__ 64
+// AARCH64-BE:#define __INTPTR_FMTd__ "ld"
+// AARCH64-BE:#define __INTPTR_FMTi__ "li"
+// AARCH64-BE:#define __INTPTR_MAX__ 9223372036854775807L
+// AARCH64-BE:#define __INTPTR_TYPE__ long int
+// AARCH64-BE:#define __INTPTR_WIDTH__ 64
+// AARCH64-BE:#define __INT_FAST16_FMTd__ "hd"
+// AARCH64-BE:#define __INT_FAST16_FMTi__ "hi"
+// AARCH64-BE:#define __INT_FAST16_MAX__ 32767
+// AARCH64-BE:#define __INT_FAST16_TYPE__ short
+// AARCH64-BE:#define __INT_FAST32_FMTd__ "d"
+// AARCH64-BE:#define __INT_FAST32_FMTi__ "i"
+// AARCH64-BE:#define __INT_FAST32_MAX__ 2147483647
+// AARCH64-BE:#define __INT_FAST32_TYPE__ int
+// AARCH64-BE:#define __INT_FAST64_FMTd__ "ld"
+// AARCH64-BE:#define __INT_FAST64_FMTi__ "li"
+// AARCH64-BE:#define __INT_FAST64_MAX__ 9223372036854775807L
+// AARCH64-BE:#define __INT_FAST64_TYPE__ long int
+// AARCH64-BE:#define __INT_FAST8_FMTd__ "hhd"
+// AARCH64-BE:#define __INT_FAST8_FMTi__ "hhi"
+// AARCH64-BE:#define __INT_FAST8_MAX__ 127
+// AARCH64-BE:#define __INT_FAST8_TYPE__ signed char
+// AARCH64-BE:#define __INT_LEAST16_FMTd__ "hd"
+// AARCH64-BE:#define __INT_LEAST16_FMTi__ "hi"
+// AARCH64-BE:#define __INT_LEAST16_MAX__ 32767
+// AARCH64-BE:#define __INT_LEAST16_TYPE__ short
+// AARCH64-BE:#define __INT_LEAST32_FMTd__ "d"
+// AARCH64-BE:#define __INT_LEAST32_FMTi__ "i"
+// AARCH64-BE:#define __INT_LEAST32_MAX__ 2147483647
+// AARCH64-BE:#define __INT_LEAST32_TYPE__ int
+// AARCH64-BE:#define __INT_LEAST64_FMTd__ "ld"
+// AARCH64-BE:#define __INT_LEAST64_FMTi__ "li"
+// AARCH64-BE:#define __INT_LEAST64_MAX__ 9223372036854775807L
+// AARCH64-BE:#define __INT_LEAST64_TYPE__ long int
+// AARCH64-BE:#define __INT_LEAST8_FMTd__ "hhd"
+// AARCH64-BE:#define __INT_LEAST8_FMTi__ "hhi"
+// AARCH64-BE:#define __INT_LEAST8_MAX__ 127
+// AARCH64-BE:#define __INT_LEAST8_TYPE__ signed char
+// AARCH64-BE:#define __INT_MAX__ 2147483647
+// AARCH64-BE:#define __LDBL_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966L
+// AARCH64-BE:#define __LDBL_DIG__ 33
+// AARCH64-BE:#define __LDBL_EPSILON__ 1.92592994438723585305597794258492732e-34L
+// AARCH64-BE:#define __LDBL_HAS_DENORM__ 1
+// AARCH64-BE:#define __LDBL_HAS_INFINITY__ 1
+// AARCH64-BE:#define __LDBL_HAS_QUIET_NAN__ 1
+// AARCH64-BE:#define __LDBL_MANT_DIG__ 113
+// AARCH64-BE:#define __LDBL_MAX_10_EXP__ 4932
+// AARCH64-BE:#define __LDBL_MAX_EXP__ 16384
+// AARCH64-BE:#define __LDBL_MAX__ 1.18973149535723176508575932662800702e+4932L
+// AARCH64-BE:#define __LDBL_MIN_10_EXP__ (-4931)
+// AARCH64-BE:#define __LDBL_MIN_EXP__ (-16381)
+// AARCH64-BE:#define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L
+// AARCH64-BE:#define __LONG_LONG_MAX__ 9223372036854775807LL
+// AARCH64-BE:#define __LONG_MAX__ 9223372036854775807L
+// AARCH64-BE:#define __LP64__ 1
+// AARCH64-BE:#define __POINTER_WIDTH__ 64
+// AARCH64-BE:#define __PTRDIFF_TYPE__ long int
+// AARCH64-BE:#define __PTRDIFF_WIDTH__ 64
+// AARCH64-BE:#define __SCHAR_MAX__ 127
+// AARCH64-BE:#define __SHRT_MAX__ 32767
+// AARCH64-BE:#define __SIG_ATOMIC_MAX__ 2147483647
+// AARCH64-BE:#define __SIG_ATOMIC_WIDTH__ 32
+// AARCH64-BE:#define __SIZEOF_DOUBLE__ 8
+// AARCH64-BE:#define __SIZEOF_FLOAT__ 4
+// AARCH64-BE:#define __SIZEOF_INT128__ 16
+// AARCH64-BE:#define __SIZEOF_INT__ 4
+// AARCH64-BE:#define __SIZEOF_LONG_DOUBLE__ 16
+// AARCH64-BE:#define __SIZEOF_LONG_LONG__ 8
+// AARCH64-BE:#define __SIZEOF_LONG__ 8
+// AARCH64-BE:#define __SIZEOF_POINTER__ 8
+// AARCH64-BE:#define __SIZEOF_PTRDIFF_T__ 8
+// AARCH64-BE:#define __SIZEOF_SHORT__ 2
+// AARCH64-BE:#define __SIZEOF_SIZE_T__ 8
+// AARCH64-BE:#define __SIZEOF_WCHAR_T__ 4
+// AARCH64-BE:#define __SIZEOF_WINT_T__ 4
+// AARCH64-BE:#define __SIZE_MAX__ 18446744073709551615UL
+// AARCH64-BE:#define __SIZE_TYPE__ long unsigned int
+// AARCH64-BE:#define __SIZE_WIDTH__ 64
+// AARCH64-BE:#define __UINT16_C_SUFFIX__ {{$}}
+// AARCH64-BE:#define __UINT16_MAX__ 65535
+// AARCH64-BE:#define __UINT16_TYPE__ unsigned short
+// AARCH64-BE:#define __UINT32_C_SUFFIX__ U
+// AARCH64-BE:#define __UINT32_MAX__ 4294967295U
+// AARCH64-BE:#define __UINT32_TYPE__ unsigned int
+// AARCH64-BE:#define __UINT64_C_SUFFIX__ UL
+// AARCH64-BE:#define __UINT64_MAX__ 18446744073709551615UL
+// AARCH64-BE:#define __UINT64_TYPE__ long unsigned int
+// AARCH64-BE:#define __UINT8_C_SUFFIX__ {{$}}
+// AARCH64-BE:#define __UINT8_MAX__ 255
+// AARCH64-BE:#define __UINT8_TYPE__ unsigned char
+// AARCH64-BE:#define __UINTMAX_C_SUFFIX__ UL
+// AARCH64-BE:#define __UINTMAX_MAX__ 18446744073709551615UL
+// AARCH64-BE:#define __UINTMAX_TYPE__ long unsigned int
+// AARCH64-BE:#define __UINTMAX_WIDTH__ 64
+// AARCH64-BE:#define __UINTPTR_MAX__ 18446744073709551615UL
+// AARCH64-BE:#define __UINTPTR_TYPE__ long unsigned int
+// AARCH64-BE:#define __UINTPTR_WIDTH__ 64
+// AARCH64-BE:#define __UINT_FAST16_MAX__ 65535
+// AARCH64-BE:#define __UINT_FAST16_TYPE__ unsigned short
+// AARCH64-BE:#define __UINT_FAST32_MAX__ 4294967295U
+// AARCH64-BE:#define __UINT_FAST32_TYPE__ unsigned int
+// AARCH64-BE:#define __UINT_FAST64_MAX__ 18446744073709551615UL
+// AARCH64-BE:#define __UINT_FAST64_TYPE__ long unsigned int
+// AARCH64-BE:#define __UINT_FAST8_MAX__ 255
+// AARCH64-BE:#define __UINT_FAST8_TYPE__ unsigned char
+// AARCH64-BE:#define __UINT_LEAST16_MAX__ 65535
+// AARCH64-BE:#define __UINT_LEAST16_TYPE__ unsigned short
+// AARCH64-BE:#define __UINT_LEAST32_MAX__ 4294967295U
+// AARCH64-BE:#define __UINT_LEAST32_TYPE__ unsigned int
+// AARCH64-BE:#define __UINT_LEAST64_MAX__ 18446744073709551615UL
+// AARCH64-BE:#define __UINT_LEAST64_TYPE__ long unsigned int
+// AARCH64-BE:#define __UINT_LEAST8_MAX__ 255
+// AARCH64-BE:#define __UINT_LEAST8_TYPE__ unsigned char
+// AARCH64-BE:#define __USER_LABEL_PREFIX__ _
+// AARCH64-BE:#define __WCHAR_MAX__ 4294967295U
+// AARCH64-BE:#define __WCHAR_TYPE__ unsigned int
+// AARCH64-BE:#define __WCHAR_UNSIGNED__ 1
+// AARCH64-BE:#define __WCHAR_WIDTH__ 32
+// AARCH64-BE:#define __WINT_TYPE__ int
+// AARCH64-BE:#define __WINT_WIDTH__ 32
+// AARCH64-BE:#define __aarch64__ 1
+//
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=aarch64-netbsd < /dev/null | FileCheck -check-prefix AARCH64-NETBSD %s
+//
+// AARCH64-NETBSD:#define _LP64 1
+// AARCH64-NETBSD-NOT:#define __AARCH64EB__ 1
+// AARCH64-NETBSD:#define __AARCH64EL__ 1
+// AARCH64-NETBSD-NOT:#define __AARCH_BIG_ENDIAN 1
+// AARCH64-NETBSD:#define __ARM_64BIT_STATE 1
+// AARCH64-NETBSD:#define __ARM_ARCH 8
+// AARCH64-NETBSD:#define __ARM_ARCH_ISA_A64 1
+// AARCH64-NETBSD-NOT:#define __ARM_BIG_ENDIAN 1
+// AARCH64-NETBSD:#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
+// AARCH64-NETBSD:#define __CHAR16_TYPE__ unsigned short
+// AARCH64-NETBSD:#define __CHAR32_TYPE__ unsigned int
+// AARCH64-NETBSD:#define __CHAR_BIT__ 8
+// AARCH64-NETBSD:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
+// AARCH64-NETBSD:#define __DBL_DIG__ 15
+// AARCH64-NETBSD:#define __DBL_EPSILON__ 2.2204460492503131e-16
+// AARCH64-NETBSD:#define __DBL_HAS_DENORM__ 1
+// AARCH64-NETBSD:#define __DBL_HAS_INFINITY__ 1
+// AARCH64-NETBSD:#define __DBL_HAS_QUIET_NAN__ 1
+// AARCH64-NETBSD:#define __DBL_MANT_DIG__ 53
+// AARCH64-NETBSD:#define __DBL_MAX_10_EXP__ 308
+// AARCH64-NETBSD:#define __DBL_MAX_EXP__ 1024
+// AARCH64-NETBSD:#define __DBL_MAX__ 1.7976931348623157e+308
+// AARCH64-NETBSD:#define __DBL_MIN_10_EXP__ (-307)
+// AARCH64-NETBSD:#define __DBL_MIN_EXP__ (-1021)
+// AARCH64-NETBSD:#define __DBL_MIN__ 2.2250738585072014e-308
+// AARCH64-NETBSD:#define __DECIMAL_DIG__ 36
+// AARCH64-NETBSD:#define __ELF__ 1
+// AARCH64-NETBSD:#define __FLT_DENORM_MIN__ 1.40129846e-45F
+// AARCH64-NETBSD:#define __FLT_DIG__ 6
+// AARCH64-NETBSD:#define __FLT_EPSILON__ 1.19209290e-7F
+// AARCH64-NETBSD:#define __FLT_EVAL_METHOD__ 0
+// AARCH64-NETBSD:#define __FLT_HAS_DENORM__ 1
+// AARCH64-NETBSD:#define __FLT_HAS_INFINITY__ 1
+// AARCH64-NETBSD:#define __FLT_HAS_QUIET_NAN__ 1
+// AARCH64-NETBSD:#define __FLT_MANT_DIG__ 24
+// AARCH64-NETBSD:#define __FLT_MAX_10_EXP__ 38
+// AARCH64-NETBSD:#define __FLT_MAX_EXP__ 128
+// AARCH64-NETBSD:#define __FLT_MAX__ 3.40282347e+38F
+// AARCH64-NETBSD:#define __FLT_MIN_10_EXP__ (-37)
+// AARCH64-NETBSD:#define __FLT_MIN_EXP__ (-125)
+// AARCH64-NETBSD:#define __FLT_MIN__ 1.17549435e-38F
+// AARCH64-NETBSD:#define __FLT_RADIX__ 2
+// AARCH64-NETBSD:#define __INT16_C_SUFFIX__ {{$}}
+// AARCH64-NETBSD:#define __INT16_FMTd__ "hd"
+// AARCH64-NETBSD:#define __INT16_FMTi__ "hi"
+// AARCH64-NETBSD:#define __INT16_MAX__ 32767
+// AARCH64-NETBSD:#define __INT16_TYPE__ short
+// AARCH64-NETBSD:#define __INT32_C_SUFFIX__ {{$}}
+// AARCH64-NETBSD:#define __INT32_FMTd__ "d"
+// AARCH64-NETBSD:#define __INT32_FMTi__ "i"
+// AARCH64-NETBSD:#define __INT32_MAX__ 2147483647
+// AARCH64-NETBSD:#define __INT32_TYPE__ int
+// AARCH64-NETBSD:#define __INT64_C_SUFFIX__ LL
+// AARCH64-NETBSD:#define __INT64_FMTd__ "lld"
+// AARCH64-NETBSD:#define __INT64_FMTi__ "lli"
+// AARCH64-NETBSD:#define __INT64_MAX__ 9223372036854775807L
+// AARCH64-NETBSD:#define __INT64_TYPE__ long long int
+// AARCH64-NETBSD:#define __INT8_C_SUFFIX__ {{$}}
+// AARCH64-NETBSD:#define __INT8_FMTd__ "hhd"
+// AARCH64-NETBSD:#define __INT8_FMTi__ "hhi"
+// AARCH64-NETBSD:#define __INT8_MAX__ 127
+// AARCH64-NETBSD:#define __INT8_TYPE__ signed char
+// AARCH64-NETBSD:#define __INTMAX_C_SUFFIX__ LL
+// AARCH64-NETBSD:#define __INTMAX_FMTd__ "lld"
+// AARCH64-NETBSD:#define __INTMAX_FMTi__ "lli"
+// AARCH64-NETBSD:#define __INTMAX_MAX__ 9223372036854775807LL
+// AARCH64-NETBSD:#define __INTMAX_TYPE__ long long int
+// AARCH64-NETBSD:#define __INTMAX_WIDTH__ 64
+// AARCH64-NETBSD:#define __INTPTR_FMTd__ "ld"
+// AARCH64-NETBSD:#define __INTPTR_FMTi__ "li"
+// AARCH64-NETBSD:#define __INTPTR_MAX__ 9223372036854775807L
+// AARCH64-NETBSD:#define __INTPTR_TYPE__ long int
+// AARCH64-NETBSD:#define __INTPTR_WIDTH__ 64
+// AARCH64-NETBSD:#define __INT_FAST16_FMTd__ "hd"
+// AARCH64-NETBSD:#define __INT_FAST16_FMTi__ "hi"
+// AARCH64-NETBSD:#define __INT_FAST16_MAX__ 32767
+// AARCH64-NETBSD:#define __INT_FAST16_TYPE__ short
+// AARCH64-NETBSD:#define __INT_FAST32_FMTd__ "d"
+// AARCH64-NETBSD:#define __INT_FAST32_FMTi__ "i"
+// AARCH64-NETBSD:#define __INT_FAST32_MAX__ 2147483647
+// AARCH64-NETBSD:#define __INT_FAST32_TYPE__ int
+// AARCH64-NETBSD:#define __INT_FAST64_FMTd__ "ld"
+// AARCH64-NETBSD:#define __INT_FAST64_FMTi__ "li"
+// AARCH64-NETBSD:#define __INT_FAST64_MAX__ 9223372036854775807L
+// AARCH64-NETBSD:#define __INT_FAST64_TYPE__ long int
+// AARCH64-NETBSD:#define __INT_FAST8_FMTd__ "hhd"
+// AARCH64-NETBSD:#define __INT_FAST8_FMTi__ "hhi"
+// AARCH64-NETBSD:#define __INT_FAST8_MAX__ 127
+// AARCH64-NETBSD:#define __INT_FAST8_TYPE__ signed char
+// AARCH64-NETBSD:#define __INT_LEAST16_FMTd__ "hd"
+// AARCH64-NETBSD:#define __INT_LEAST16_FMTi__ "hi"
+// AARCH64-NETBSD:#define __INT_LEAST16_MAX__ 32767
+// AARCH64-NETBSD:#define __INT_LEAST16_TYPE__ short
+// AARCH64-NETBSD:#define __INT_LEAST32_FMTd__ "d"
+// AARCH64-NETBSD:#define __INT_LEAST32_FMTi__ "i"
+// AARCH64-NETBSD:#define __INT_LEAST32_MAX__ 2147483647
+// AARCH64-NETBSD:#define __INT_LEAST32_TYPE__ int
+// AARCH64-NETBSD:#define __INT_LEAST64_FMTd__ "ld"
+// AARCH64-NETBSD:#define __INT_LEAST64_FMTi__ "li"
+// AARCH64-NETBSD:#define __INT_LEAST64_MAX__ 9223372036854775807L
+// AARCH64-NETBSD:#define __INT_LEAST64_TYPE__ long int
+// AARCH64-NETBSD:#define __INT_LEAST8_FMTd__ "hhd"
+// AARCH64-NETBSD:#define __INT_LEAST8_FMTi__ "hhi"
+// AARCH64-NETBSD:#define __INT_LEAST8_MAX__ 127
+// AARCH64-NETBSD:#define __INT_LEAST8_TYPE__ signed char
+// AARCH64-NETBSD:#define __INT_MAX__ 2147483647
+// AARCH64-NETBSD:#define __LDBL_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966L
+// AARCH64-NETBSD:#define __LDBL_DIG__ 33
+// AARCH64-NETBSD:#define __LDBL_EPSILON__ 1.92592994438723585305597794258492732e-34L
+// AARCH64-NETBSD:#define __LDBL_HAS_DENORM__ 1
+// AARCH64-NETBSD:#define __LDBL_HAS_INFINITY__ 1
+// AARCH64-NETBSD:#define __LDBL_HAS_QUIET_NAN__ 1
+// AARCH64-NETBSD:#define __LDBL_MANT_DIG__ 113
+// AARCH64-NETBSD:#define __LDBL_MAX_10_EXP__ 4932
+// AARCH64-NETBSD:#define __LDBL_MAX_EXP__ 16384
+// AARCH64-NETBSD:#define __LDBL_MAX__ 1.18973149535723176508575932662800702e+4932L
+// AARCH64-NETBSD:#define __LDBL_MIN_10_EXP__ (-4931)
+// AARCH64-NETBSD:#define __LDBL_MIN_EXP__ (-16381)
+// AARCH64-NETBSD:#define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L
+// AARCH64-NETBSD:#define __LITTLE_ENDIAN__ 1
+// AARCH64-NETBSD:#define __LONG_LONG_MAX__ 9223372036854775807LL
+// AARCH64-NETBSD:#define __LONG_MAX__ 9223372036854775807L
+// AARCH64-NETBSD:#define __LP64__ 1
+// AARCH64-NETBSD:#define __NetBSD__ 1
+// AARCH64-NETBSD:#define __POINTER_WIDTH__ 64
+// AARCH64-NETBSD:#define __PTRDIFF_TYPE__ long int
+// AARCH64-NETBSD:#define __PTRDIFF_WIDTH__ 64
+// AARCH64-NETBSD:#define __SCHAR_MAX__ 127
+// AARCH64-NETBSD:#define __SHRT_MAX__ 32767
+// AARCH64-NETBSD:#define __SIG_ATOMIC_MAX__ 2147483647
+// AARCH64-NETBSD:#define __SIG_ATOMIC_WIDTH__ 32
+// AARCH64-NETBSD:#define __SIZEOF_DOUBLE__ 8
+// AARCH64-NETBSD:#define __SIZEOF_FLOAT__ 4
+// AARCH64-NETBSD:#define __SIZEOF_INT__ 4
+// AARCH64-NETBSD:#define __SIZEOF_LONG_DOUBLE__ 16
+// AARCH64-NETBSD:#define __SIZEOF_LONG_LONG__ 8
+// AARCH64-NETBSD:#define __SIZEOF_LONG__ 8
+// AARCH64-NETBSD:#define __SIZEOF_POINTER__ 8
+// AARCH64-NETBSD:#define __SIZEOF_PTRDIFF_T__ 8
+// AARCH64-NETBSD:#define __SIZEOF_SHORT__ 2
+// AARCH64-NETBSD:#define __SIZEOF_SIZE_T__ 8
+// AARCH64-NETBSD:#define __SIZEOF_WCHAR_T__ 4
+// AARCH64-NETBSD:#define __SIZEOF_WINT_T__ 4
+// AARCH64-NETBSD:#define __SIZE_MAX__ 18446744073709551615UL
+// AARCH64-NETBSD:#define __SIZE_TYPE__ long unsigned int
+// AARCH64-NETBSD:#define __SIZE_WIDTH__ 64
+// AARCH64-NETBSD:#define __UINT16_C_SUFFIX__ {{$}}
+// AARCH64-NETBSD:#define __UINT16_MAX__ 65535
+// AARCH64-NETBSD:#define __UINT16_TYPE__ unsigned short
+// AARCH64-NETBSD:#define __UINT32_C_SUFFIX__ U
+// AARCH64-NETBSD:#define __UINT32_MAX__ 4294967295U
+// AARCH64-NETBSD:#define __UINT32_TYPE__ unsigned int
+// AARCH64-NETBSD:#define __UINT64_C_SUFFIX__ ULL
+// AARCH64-NETBSD:#define __UINT64_MAX__ 18446744073709551615ULL
+// AARCH64-NETBSD:#define __UINT64_TYPE__ long long unsigned int
+// AARCH64-NETBSD:#define __UINT8_C_SUFFIX__ {{$}}
+// AARCH64-NETBSD:#define __UINT8_MAX__ 255
+// AARCH64-NETBSD:#define __UINT8_TYPE__ unsigned char
+// AARCH64-NETBSD:#define __UINTMAX_C_SUFFIX__ ULL
+// AARCH64-NETBSD:#define __UINTMAX_MAX__ 18446744073709551615ULL
+// AARCH64-NETBSD:#define __UINTMAX_TYPE__ long long unsigned int
+// AARCH64-NETBSD:#define __UINTMAX_WIDTH__ 64
+// AARCH64-NETBSD:#define __UINTPTR_MAX__ 18446744073709551615UL
+// AARCH64-NETBSD:#define __UINTPTR_TYPE__ long unsigned int
+// AARCH64-NETBSD:#define __UINTPTR_WIDTH__ 64
+// AARCH64-NETBSD:#define __UINT_FAST16_MAX__ 65535
+// AARCH64-NETBSD:#define __UINT_FAST16_TYPE__ unsigned short
+// AARCH64-NETBSD:#define __UINT_FAST32_MAX__ 4294967295U
+// AARCH64-NETBSD:#define __UINT_FAST32_TYPE__ unsigned int
+// AARCH64-NETBSD:#define __UINT_FAST64_MAX__ 18446744073709551615UL
+// AARCH64-NETBSD:#define __UINT_FAST64_TYPE__ long unsigned int
+// AARCH64-NETBSD:#define __UINT_FAST8_MAX__ 255
+// AARCH64-NETBSD:#define __UINT_FAST8_TYPE__ unsigned char
+// AARCH64-NETBSD:#define __UINT_LEAST16_MAX__ 65535
+// AARCH64-NETBSD:#define __UINT_LEAST16_TYPE__ unsigned short
+// AARCH64-NETBSD:#define __UINT_LEAST32_MAX__ 4294967295U
+// AARCH64-NETBSD:#define __UINT_LEAST32_TYPE__ unsigned int
+// AARCH64-NETBSD:#define __UINT_LEAST64_MAX__ 18446744073709551615UL
+// AARCH64-NETBSD:#define __UINT_LEAST64_TYPE__ long unsigned int
+// AARCH64-NETBSD:#define __UINT_LEAST8_MAX__ 255
+// AARCH64-NETBSD:#define __UINT_LEAST8_TYPE__ unsigned char
+// AARCH64-NETBSD:#define __USER_LABEL_PREFIX__
+// AARCH64-NETBSD:#define __WCHAR_MAX__ 2147483647
+// AARCH64-NETBSD:#define __WCHAR_TYPE__ int
+// AARCH64-NETBSD:#define __WCHAR_WIDTH__ 32
+// AARCH64-NETBSD:#define __WINT_TYPE__ int
+// AARCH64-NETBSD:#define __WINT_WIDTH__ 32
+// AARCH64-NETBSD:#define __aarch64__ 1
+
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=arm-none-none < /dev/null | FileCheck -check-prefix ARM %s
 //
 // ARM-NOT:#define _LP64
 // ARM:#define __APCS_32__ 1
+// ARM-NOT:#define __ARMEB__ 1
 // ARM:#define __ARMEL__ 1
 // ARM:#define __ARM_ARCH_6J__ 1
+// ARM-NOT:#define __ARM_BIG_ENDIAN 1
 // ARM:#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
 // ARM:#define __CHAR16_TYPE__ unsigned short
 // ARM:#define __CHAR32_TYPE__ unsigned int
@@ -241,16 +844,69 @@
 // ARM:#define __FLT_MIN_EXP__ (-125)
 // ARM:#define __FLT_MIN__ 1.17549435e-38F
 // ARM:#define __FLT_RADIX__ 2
+// ARM:#define __INT16_C_SUFFIX__ {{$}}
+// ARM:#define __INT16_FMTd__ "hd"
+// ARM:#define __INT16_FMTi__ "hi"
+// ARM:#define __INT16_MAX__ 32767
 // ARM:#define __INT16_TYPE__ short
+// ARM:#define __INT32_C_SUFFIX__ {{$}}
+// ARM:#define __INT32_FMTd__ "d"
+// ARM:#define __INT32_FMTi__ "i"
+// ARM:#define __INT32_MAX__ 2147483647
 // ARM:#define __INT32_TYPE__ int
 // ARM:#define __INT64_C_SUFFIX__ LL
+// ARM:#define __INT64_FMTd__ "lld"
+// ARM:#define __INT64_FMTi__ "lli"
+// ARM:#define __INT64_MAX__ 9223372036854775807LL
 // ARM:#define __INT64_TYPE__ long long int
-// ARM:#define __INT8_TYPE__ char
+// ARM:#define __INT8_C_SUFFIX__ {{$}}
+// ARM:#define __INT8_FMTd__ "hhd"
+// ARM:#define __INT8_FMTi__ "hhi"
+// ARM:#define __INT8_MAX__ 127
+// ARM:#define __INT8_TYPE__ signed char
+// ARM:#define __INTMAX_C_SUFFIX__ LL
+// ARM:#define __INTMAX_FMTd__ "lld"
+// ARM:#define __INTMAX_FMTi__ "lli"
 // ARM:#define __INTMAX_MAX__ 9223372036854775807LL
 // ARM:#define __INTMAX_TYPE__ long long int
 // ARM:#define __INTMAX_WIDTH__ 64
+// ARM:#define __INTPTR_FMTd__ "ld"
+// ARM:#define __INTPTR_FMTi__ "li"
+// ARM:#define __INTPTR_MAX__ 2147483647L
 // ARM:#define __INTPTR_TYPE__ long int
 // ARM:#define __INTPTR_WIDTH__ 32
+// ARM:#define __INT_FAST16_FMTd__ "hd"
+// ARM:#define __INT_FAST16_FMTi__ "hi"
+// ARM:#define __INT_FAST16_MAX__ 32767
+// ARM:#define __INT_FAST16_TYPE__ short
+// ARM:#define __INT_FAST32_FMTd__ "d"
+// ARM:#define __INT_FAST32_FMTi__ "i"
+// ARM:#define __INT_FAST32_MAX__ 2147483647
+// ARM:#define __INT_FAST32_TYPE__ int
+// ARM:#define __INT_FAST64_FMTd__ "lld"
+// ARM:#define __INT_FAST64_FMTi__ "lli"
+// ARM:#define __INT_FAST64_MAX__ 9223372036854775807LL
+// ARM:#define __INT_FAST64_TYPE__ long long int
+// ARM:#define __INT_FAST8_FMTd__ "hhd"
+// ARM:#define __INT_FAST8_FMTi__ "hhi"
+// ARM:#define __INT_FAST8_MAX__ 127
+// ARM:#define __INT_FAST8_TYPE__ signed char
+// ARM:#define __INT_LEAST16_FMTd__ "hd"
+// ARM:#define __INT_LEAST16_FMTi__ "hi"
+// ARM:#define __INT_LEAST16_MAX__ 32767
+// ARM:#define __INT_LEAST16_TYPE__ short
+// ARM:#define __INT_LEAST32_FMTd__ "d"
+// ARM:#define __INT_LEAST32_FMTi__ "i"
+// ARM:#define __INT_LEAST32_MAX__ 2147483647
+// ARM:#define __INT_LEAST32_TYPE__ int
+// ARM:#define __INT_LEAST64_FMTd__ "lld"
+// ARM:#define __INT_LEAST64_FMTi__ "lli"
+// ARM:#define __INT_LEAST64_MAX__ 9223372036854775807LL
+// ARM:#define __INT_LEAST64_TYPE__ long long int
+// ARM:#define __INT_LEAST8_FMTd__ "hhd"
+// ARM:#define __INT_LEAST8_FMTi__ "hhi"
+// ARM:#define __INT_LEAST8_MAX__ 127
+// ARM:#define __INT_LEAST8_TYPE__ signed char
 // ARM:#define __INT_MAX__ 2147483647
 // ARM:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
 // ARM:#define __LDBL_DIG__ 15
@@ -275,6 +931,7 @@
 // ARM:#define __REGISTER_PREFIX__
 // ARM:#define __SCHAR_MAX__ 127
 // ARM:#define __SHRT_MAX__ 32767
+// ARM:#define __SIG_ATOMIC_MAX__ 2147483647
 // ARM:#define __SIG_ATOMIC_WIDTH__ 32
 // ARM:#define __SIZEOF_DOUBLE__ 8
 // ARM:#define __SIZEOF_FLOAT__ 4
@@ -292,7 +949,41 @@
 // ARM:#define __SIZE_TYPE__ unsigned int
 // ARM:#define __SIZE_WIDTH__ 32
 // ARM:#define __THUMB_INTERWORK__ 1
+// ARM:#define __UINT16_C_SUFFIX__ {{$}}
+// ARM:#define __UINT16_MAX__ 65535
+// ARM:#define __UINT16_TYPE__ unsigned short
+// ARM:#define __UINT32_C_SUFFIX__ U
+// ARM:#define __UINT32_MAX__ 4294967295U
+// ARM:#define __UINT32_TYPE__ unsigned int
+// ARM:#define __UINT64_C_SUFFIX__ ULL
+// ARM:#define __UINT64_MAX__ 18446744073709551615ULL
+// ARM:#define __UINT64_TYPE__ long long unsigned int
+// ARM:#define __UINT8_C_SUFFIX__ {{$}}
+// ARM:#define __UINT8_MAX__ 255
+// ARM:#define __UINT8_TYPE__ unsigned char
+// ARM:#define __UINTMAX_C_SUFFIX__ ULL
+// ARM:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // ARM:#define __UINTMAX_TYPE__ long long unsigned int
+// ARM:#define __UINTMAX_WIDTH__ 64
+// ARM:#define __UINTPTR_MAX__ 4294967295U
+// ARM:#define __UINTPTR_TYPE__ long unsigned int
+// ARM:#define __UINTPTR_WIDTH__ 32
+// ARM:#define __UINT_FAST16_MAX__ 65535
+// ARM:#define __UINT_FAST16_TYPE__ unsigned short
+// ARM:#define __UINT_FAST32_MAX__ 4294967295U
+// ARM:#define __UINT_FAST32_TYPE__ unsigned int
+// ARM:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// ARM:#define __UINT_FAST64_TYPE__ long long unsigned int
+// ARM:#define __UINT_FAST8_MAX__ 255
+// ARM:#define __UINT_FAST8_TYPE__ unsigned char
+// ARM:#define __UINT_LEAST16_MAX__ 65535
+// ARM:#define __UINT_LEAST16_TYPE__ unsigned short
+// ARM:#define __UINT_LEAST32_MAX__ 4294967295U
+// ARM:#define __UINT_LEAST32_TYPE__ unsigned int
+// ARM:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// ARM:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// ARM:#define __UINT_LEAST8_MAX__ 255
+// ARM:#define __UINT_LEAST8_TYPE__ unsigned char
 // ARM:#define __USER_LABEL_PREFIX__ _
 // ARM:#define __WCHAR_MAX__ 4294967295U
 // ARM:#define __WCHAR_TYPE__ unsigned int
@@ -302,13 +993,205 @@
 // ARM:#define __arm 1
 // ARM:#define __arm__ 1
 
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=armeb-none-none < /dev/null | FileCheck -check-prefix ARM-BE %s
+//
+// ARM-BE-NOT:#define _LP64
+// ARM-BE:#define __APCS_32__ 1
+// ARM-BE:#define __ARMEB__ 1
+// ARM-BE-NOT:#define __ARMEL__ 1
+// ARM-BE:#define __ARM_ARCH_6J__ 1
+// ARM-BE:#define __ARM_BIG_ENDIAN 1
+// ARM-BE:#define __BIG_ENDIAN__ 1
+// ARM-BE:#define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__
+// ARM-BE:#define __CHAR16_TYPE__ unsigned short
+// ARM-BE:#define __CHAR32_TYPE__ unsigned int
+// ARM-BE:#define __CHAR_BIT__ 8
+// ARM-BE:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
+// ARM-BE:#define __DBL_DIG__ 15
+// ARM-BE:#define __DBL_EPSILON__ 2.2204460492503131e-16
+// ARM-BE:#define __DBL_HAS_DENORM__ 1
+// ARM-BE:#define __DBL_HAS_INFINITY__ 1
+// ARM-BE:#define __DBL_HAS_QUIET_NAN__ 1
+// ARM-BE:#define __DBL_MANT_DIG__ 53
+// ARM-BE:#define __DBL_MAX_10_EXP__ 308
+// ARM-BE:#define __DBL_MAX_EXP__ 1024
+// ARM-BE:#define __DBL_MAX__ 1.7976931348623157e+308
+// ARM-BE:#define __DBL_MIN_10_EXP__ (-307)
+// ARM-BE:#define __DBL_MIN_EXP__ (-1021)
+// ARM-BE:#define __DBL_MIN__ 2.2250738585072014e-308
+// ARM-BE:#define __DECIMAL_DIG__ 17
+// ARM-BE:#define __FLT_DENORM_MIN__ 1.40129846e-45F
+// ARM-BE:#define __FLT_DIG__ 6
+// ARM-BE:#define __FLT_EPSILON__ 1.19209290e-7F
+// ARM-BE:#define __FLT_EVAL_METHOD__ 0
+// ARM-BE:#define __FLT_HAS_DENORM__ 1
+// ARM-BE:#define __FLT_HAS_INFINITY__ 1
+// ARM-BE:#define __FLT_HAS_QUIET_NAN__ 1
+// ARM-BE:#define __FLT_MANT_DIG__ 24
+// ARM-BE:#define __FLT_MAX_10_EXP__ 38
+// ARM-BE:#define __FLT_MAX_EXP__ 128
+// ARM-BE:#define __FLT_MAX__ 3.40282347e+38F
+// ARM-BE:#define __FLT_MIN_10_EXP__ (-37)
+// ARM-BE:#define __FLT_MIN_EXP__ (-125)
+// ARM-BE:#define __FLT_MIN__ 1.17549435e-38F
+// ARM-BE:#define __FLT_RADIX__ 2
+// ARM-BE:#define __INT16_C_SUFFIX__ {{$}}
+// ARM-BE:#define __INT16_FMTd__ "hd"
+// ARM-BE:#define __INT16_FMTi__ "hi"
+// ARM-BE:#define __INT16_MAX__ 32767
+// ARM-BE:#define __INT16_TYPE__ short
+// ARM-BE:#define __INT32_C_SUFFIX__ {{$}}
+// ARM-BE:#define __INT32_FMTd__ "d"
+// ARM-BE:#define __INT32_FMTi__ "i"
+// ARM-BE:#define __INT32_MAX__ 2147483647
+// ARM-BE:#define __INT32_TYPE__ int
+// ARM-BE:#define __INT64_C_SUFFIX__ LL
+// ARM-BE:#define __INT64_FMTd__ "lld"
+// ARM-BE:#define __INT64_FMTi__ "lli"
+// ARM-BE:#define __INT64_MAX__ 9223372036854775807LL
+// ARM-BE:#define __INT64_TYPE__ long long int
+// ARM-BE:#define __INT8_C_SUFFIX__ {{$}}
+// ARM-BE:#define __INT8_FMTd__ "hhd"
+// ARM-BE:#define __INT8_FMTi__ "hhi"
+// ARM-BE:#define __INT8_MAX__ 127
+// ARM-BE:#define __INT8_TYPE__ signed char
+// ARM-BE:#define __INTMAX_C_SUFFIX__ LL
+// ARM-BE:#define __INTMAX_FMTd__ "lld"
+// ARM-BE:#define __INTMAX_FMTi__ "lli"
+// ARM-BE:#define __INTMAX_MAX__ 9223372036854775807LL
+// ARM-BE:#define __INTMAX_TYPE__ long long int
+// ARM-BE:#define __INTMAX_WIDTH__ 64
+// ARM-BE:#define __INTPTR_FMTd__ "ld"
+// ARM-BE:#define __INTPTR_FMTi__ "li"
+// ARM-BE:#define __INTPTR_MAX__ 2147483647L
+// ARM-BE:#define __INTPTR_TYPE__ long int
+// ARM-BE:#define __INTPTR_WIDTH__ 32
+// ARM-BE:#define __INT_FAST16_FMTd__ "hd"
+// ARM-BE:#define __INT_FAST16_FMTi__ "hi"
+// ARM-BE:#define __INT_FAST16_MAX__ 32767
+// ARM-BE:#define __INT_FAST16_TYPE__ short
+// ARM-BE:#define __INT_FAST32_FMTd__ "d"
+// ARM-BE:#define __INT_FAST32_FMTi__ "i"
+// ARM-BE:#define __INT_FAST32_MAX__ 2147483647
+// ARM-BE:#define __INT_FAST32_TYPE__ int
+// ARM-BE:#define __INT_FAST64_FMTd__ "lld"
+// ARM-BE:#define __INT_FAST64_FMTi__ "lli"
+// ARM-BE:#define __INT_FAST64_MAX__ 9223372036854775807LL
+// ARM-BE:#define __INT_FAST64_TYPE__ long long int
+// ARM-BE:#define __INT_FAST8_FMTd__ "hhd"
+// ARM-BE:#define __INT_FAST8_FMTi__ "hhi"
+// ARM-BE:#define __INT_FAST8_MAX__ 127
+// ARM-BE:#define __INT_FAST8_TYPE__ signed char
+// ARM-BE:#define __INT_LEAST16_FMTd__ "hd"
+// ARM-BE:#define __INT_LEAST16_FMTi__ "hi"
+// ARM-BE:#define __INT_LEAST16_MAX__ 32767
+// ARM-BE:#define __INT_LEAST16_TYPE__ short
+// ARM-BE:#define __INT_LEAST32_FMTd__ "d"
+// ARM-BE:#define __INT_LEAST32_FMTi__ "i"
+// ARM-BE:#define __INT_LEAST32_MAX__ 2147483647
+// ARM-BE:#define __INT_LEAST32_TYPE__ int
+// ARM-BE:#define __INT_LEAST64_FMTd__ "lld"
+// ARM-BE:#define __INT_LEAST64_FMTi__ "lli"
+// ARM-BE:#define __INT_LEAST64_MAX__ 9223372036854775807LL
+// ARM-BE:#define __INT_LEAST64_TYPE__ long long int
+// ARM-BE:#define __INT_LEAST8_FMTd__ "hhd"
+// ARM-BE:#define __INT_LEAST8_FMTi__ "hhi"
+// ARM-BE:#define __INT_LEAST8_MAX__ 127
+// ARM-BE:#define __INT_LEAST8_TYPE__ signed char
+// ARM-BE:#define __INT_MAX__ 2147483647
+// ARM-BE:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
+// ARM-BE:#define __LDBL_DIG__ 15
+// ARM-BE:#define __LDBL_EPSILON__ 2.2204460492503131e-16L
+// ARM-BE:#define __LDBL_HAS_DENORM__ 1
+// ARM-BE:#define __LDBL_HAS_INFINITY__ 1
+// ARM-BE:#define __LDBL_HAS_QUIET_NAN__ 1
+// ARM-BE:#define __LDBL_MANT_DIG__ 53
+// ARM-BE:#define __LDBL_MAX_10_EXP__ 308
+// ARM-BE:#define __LDBL_MAX_EXP__ 1024
+// ARM-BE:#define __LDBL_MAX__ 1.7976931348623157e+308L
+// ARM-BE:#define __LDBL_MIN_10_EXP__ (-307)
+// ARM-BE:#define __LDBL_MIN_EXP__ (-1021)
+// ARM-BE:#define __LDBL_MIN__ 2.2250738585072014e-308L
+// ARM-BE:#define __LONG_LONG_MAX__ 9223372036854775807LL
+// ARM-BE:#define __LONG_MAX__ 2147483647L
+// ARM-BE-NOT:#define __LP64__
+// ARM-BE:#define __POINTER_WIDTH__ 32
+// ARM-BE:#define __PTRDIFF_TYPE__ int
+// ARM-BE:#define __PTRDIFF_WIDTH__ 32
+// ARM-BE:#define __REGISTER_PREFIX__
+// ARM-BE:#define __SCHAR_MAX__ 127
+// ARM-BE:#define __SHRT_MAX__ 32767
+// ARM-BE:#define __SIG_ATOMIC_MAX__ 2147483647
+// ARM-BE:#define __SIG_ATOMIC_WIDTH__ 32
+// ARM-BE:#define __SIZEOF_DOUBLE__ 8
+// ARM-BE:#define __SIZEOF_FLOAT__ 4
+// ARM-BE:#define __SIZEOF_INT__ 4
+// ARM-BE:#define __SIZEOF_LONG_DOUBLE__ 8
+// ARM-BE:#define __SIZEOF_LONG_LONG__ 8
+// ARM-BE:#define __SIZEOF_LONG__ 4
+// ARM-BE:#define __SIZEOF_POINTER__ 4
+// ARM-BE:#define __SIZEOF_PTRDIFF_T__ 4
+// ARM-BE:#define __SIZEOF_SHORT__ 2
+// ARM-BE:#define __SIZEOF_SIZE_T__ 4
+// ARM-BE:#define __SIZEOF_WCHAR_T__ 4
+// ARM-BE:#define __SIZEOF_WINT_T__ 4
+// ARM-BE:#define __SIZE_MAX__ 4294967295U
+// ARM-BE:#define __SIZE_TYPE__ unsigned int
+// ARM-BE:#define __SIZE_WIDTH__ 32
+// ARM-BE:#define __THUMB_INTERWORK__ 1
+// ARM-BE:#define __UINT16_C_SUFFIX__ {{$}}
+// ARM-BE:#define __UINT16_MAX__ 65535
+// ARM-BE:#define __UINT16_TYPE__ unsigned short
+// ARM-BE:#define __UINT32_C_SUFFIX__ U
+// ARM-BE:#define __UINT32_MAX__ 4294967295U
+// ARM-BE:#define __UINT32_TYPE__ unsigned int
+// ARM-BE:#define __UINT64_C_SUFFIX__ ULL
+// ARM-BE:#define __UINT64_MAX__ 18446744073709551615ULL
+// ARM-BE:#define __UINT64_TYPE__ long long unsigned int
+// ARM-BE:#define __UINT8_C_SUFFIX__ {{$}}
+// ARM-BE:#define __UINT8_MAX__ 255
+// ARM-BE:#define __UINT8_TYPE__ unsigned char
+// ARM-BE:#define __UINTMAX_C_SUFFIX__ ULL
+// ARM-BE:#define __UINTMAX_MAX__ 18446744073709551615ULL
+// ARM-BE:#define __UINTMAX_TYPE__ long long unsigned int
+// ARM-BE:#define __UINTMAX_WIDTH__ 64
+// ARM-BE:#define __UINTPTR_MAX__ 4294967295U
+// ARM-BE:#define __UINTPTR_TYPE__ long unsigned int
+// ARM-BE:#define __UINTPTR_WIDTH__ 32
+// ARM-BE:#define __UINT_FAST16_MAX__ 65535
+// ARM-BE:#define __UINT_FAST16_TYPE__ unsigned short
+// ARM-BE:#define __UINT_FAST32_MAX__ 4294967295U
+// ARM-BE:#define __UINT_FAST32_TYPE__ unsigned int
+// ARM-BE:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// ARM-BE:#define __UINT_FAST64_TYPE__ long long unsigned int
+// ARM-BE:#define __UINT_FAST8_MAX__ 255
+// ARM-BE:#define __UINT_FAST8_TYPE__ unsigned char
+// ARM-BE:#define __UINT_LEAST16_MAX__ 65535
+// ARM-BE:#define __UINT_LEAST16_TYPE__ unsigned short
+// ARM-BE:#define __UINT_LEAST32_MAX__ 4294967295U
+// ARM-BE:#define __UINT_LEAST32_TYPE__ unsigned int
+// ARM-BE:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// ARM-BE:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// ARM-BE:#define __UINT_LEAST8_MAX__ 255
+// ARM-BE:#define __UINT_LEAST8_TYPE__ unsigned char
+// ARM-BE:#define __USER_LABEL_PREFIX__ _
+// ARM-BE:#define __WCHAR_MAX__ 4294967295U
+// ARM-BE:#define __WCHAR_TYPE__ unsigned int
+// ARM-BE:#define __WCHAR_WIDTH__ 32
+// ARM-BE:#define __WINT_TYPE__ int
+// ARM-BE:#define __WINT_WIDTH__ 32
+// ARM-BE:#define __arm 1
+// ARM-BE:#define __arm__ 1
+
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=arm-none-linux-gnueabi -target-feature +soft-float -target-feature +soft-float-abi < /dev/null | FileCheck -check-prefix ARMEABISOFTFP %s
 //
-// ARM-NOT:#define _LP64
+// ARMEABISOFTFP-NOT:#define _LP64
 // ARMEABISOFTFP:#define __APCS_32__ 1
+// ARMEABISOFTFP-NOT:#define __ARMEB__ 1
 // ARMEABISOFTFP:#define __ARMEL__ 1
 // ARMEABISOFTFP:#define __ARM_ARCH 6
 // ARMEABISOFTFP:#define __ARM_ARCH_6J__ 1
+// ARMEABISOFTFP-NOT:#define __ARM_BIG_ENDIAN 1
 // ARMEABISOFTFP:#define __ARM_EABI__ 1
 // ARMEABISOFTFP:#define __ARM_PCS 1
 // ARMEABISOFTFP-NOT:#define __ARM_PCS_VFP 1
@@ -345,16 +1228,69 @@
 // ARMEABISOFTFP:#define __FLT_MIN_EXP__ (-125)
 // ARMEABISOFTFP:#define __FLT_MIN__ 1.17549435e-38F
 // ARMEABISOFTFP:#define __FLT_RADIX__ 2
+// ARMEABISOFTFP:#define __INT16_C_SUFFIX__ {{$}}
+// ARMEABISOFTFP:#define __INT16_FMTd__ "hd"
+// ARMEABISOFTFP:#define __INT16_FMTi__ "hi"
+// ARMEABISOFTFP:#define __INT16_MAX__ 32767
 // ARMEABISOFTFP:#define __INT16_TYPE__ short
+// ARMEABISOFTFP:#define __INT32_C_SUFFIX__ {{$}}
+// ARMEABISOFTFP:#define __INT32_FMTd__ "d"
+// ARMEABISOFTFP:#define __INT32_FMTi__ "i"
+// ARMEABISOFTFP:#define __INT32_MAX__ 2147483647
 // ARMEABISOFTFP:#define __INT32_TYPE__ int
 // ARMEABISOFTFP:#define __INT64_C_SUFFIX__ LL
+// ARMEABISOFTFP:#define __INT64_FMTd__ "lld"
+// ARMEABISOFTFP:#define __INT64_FMTi__ "lli"
+// ARMEABISOFTFP:#define __INT64_MAX__ 9223372036854775807LL
 // ARMEABISOFTFP:#define __INT64_TYPE__ long long int
-// ARMEABISOFTFP:#define __INT8_TYPE__ char
+// ARMEABISOFTFP:#define __INT8_C_SUFFIX__ {{$}}
+// ARMEABISOFTFP:#define __INT8_FMTd__ "hhd"
+// ARMEABISOFTFP:#define __INT8_FMTi__ "hhi"
+// ARMEABISOFTFP:#define __INT8_MAX__ 127
+// ARMEABISOFTFP:#define __INT8_TYPE__ signed char
+// ARMEABISOFTFP:#define __INTMAX_C_SUFFIX__ LL
+// ARMEABISOFTFP:#define __INTMAX_FMTd__ "lld"
+// ARMEABISOFTFP:#define __INTMAX_FMTi__ "lli"
 // ARMEABISOFTFP:#define __INTMAX_MAX__ 9223372036854775807LL
 // ARMEABISOFTFP:#define __INTMAX_TYPE__ long long int
 // ARMEABISOFTFP:#define __INTMAX_WIDTH__ 64
+// ARMEABISOFTFP:#define __INTPTR_FMTd__ "ld"
+// ARMEABISOFTFP:#define __INTPTR_FMTi__ "li"
+// ARMEABISOFTFP:#define __INTPTR_MAX__ 2147483647L
 // ARMEABISOFTFP:#define __INTPTR_TYPE__ long int
 // ARMEABISOFTFP:#define __INTPTR_WIDTH__ 32
+// ARMEABISOFTFP:#define __INT_FAST16_FMTd__ "hd"
+// ARMEABISOFTFP:#define __INT_FAST16_FMTi__ "hi"
+// ARMEABISOFTFP:#define __INT_FAST16_MAX__ 32767
+// ARMEABISOFTFP:#define __INT_FAST16_TYPE__ short
+// ARMEABISOFTFP:#define __INT_FAST32_FMTd__ "d"
+// ARMEABISOFTFP:#define __INT_FAST32_FMTi__ "i"
+// ARMEABISOFTFP:#define __INT_FAST32_MAX__ 2147483647
+// ARMEABISOFTFP:#define __INT_FAST32_TYPE__ int
+// ARMEABISOFTFP:#define __INT_FAST64_FMTd__ "lld"
+// ARMEABISOFTFP:#define __INT_FAST64_FMTi__ "lli"
+// ARMEABISOFTFP:#define __INT_FAST64_MAX__ 9223372036854775807LL
+// ARMEABISOFTFP:#define __INT_FAST64_TYPE__ long long int
+// ARMEABISOFTFP:#define __INT_FAST8_FMTd__ "hhd"
+// ARMEABISOFTFP:#define __INT_FAST8_FMTi__ "hhi"
+// ARMEABISOFTFP:#define __INT_FAST8_MAX__ 127
+// ARMEABISOFTFP:#define __INT_FAST8_TYPE__ signed char
+// ARMEABISOFTFP:#define __INT_LEAST16_FMTd__ "hd"
+// ARMEABISOFTFP:#define __INT_LEAST16_FMTi__ "hi"
+// ARMEABISOFTFP:#define __INT_LEAST16_MAX__ 32767
+// ARMEABISOFTFP:#define __INT_LEAST16_TYPE__ short
+// ARMEABISOFTFP:#define __INT_LEAST32_FMTd__ "d"
+// ARMEABISOFTFP:#define __INT_LEAST32_FMTi__ "i"
+// ARMEABISOFTFP:#define __INT_LEAST32_MAX__ 2147483647
+// ARMEABISOFTFP:#define __INT_LEAST32_TYPE__ int
+// ARMEABISOFTFP:#define __INT_LEAST64_FMTd__ "lld"
+// ARMEABISOFTFP:#define __INT_LEAST64_FMTi__ "lli"
+// ARMEABISOFTFP:#define __INT_LEAST64_MAX__ 9223372036854775807LL
+// ARMEABISOFTFP:#define __INT_LEAST64_TYPE__ long long int
+// ARMEABISOFTFP:#define __INT_LEAST8_FMTd__ "hhd"
+// ARMEABISOFTFP:#define __INT_LEAST8_FMTi__ "hhi"
+// ARMEABISOFTFP:#define __INT_LEAST8_MAX__ 127
+// ARMEABISOFTFP:#define __INT_LEAST8_TYPE__ signed char
 // ARMEABISOFTFP:#define __INT_MAX__ 2147483647
 // ARMEABISOFTFP:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
 // ARMEABISOFTFP:#define __LDBL_DIG__ 15
@@ -379,6 +1315,7 @@
 // ARMEABISOFTFP:#define __REGISTER_PREFIX__
 // ARMEABISOFTFP:#define __SCHAR_MAX__ 127
 // ARMEABISOFTFP:#define __SHRT_MAX__ 32767
+// ARMEABISOFTFP:#define __SIG_ATOMIC_MAX__ 2147483647
 // ARMEABISOFTFP:#define __SIG_ATOMIC_WIDTH__ 32
 // ARMEABISOFTFP:#define __SIZEOF_DOUBLE__ 8
 // ARMEABISOFTFP:#define __SIZEOF_FLOAT__ 4
@@ -397,7 +1334,41 @@
 // ARMEABISOFTFP:#define __SIZE_WIDTH__ 32
 // ARMEABISOFTFP:#define __SOFTFP__ 1
 // ARMEABISOFTFP:#define __THUMB_INTERWORK__ 1
+// ARMEABISOFTFP:#define __UINT16_C_SUFFIX__ {{$}}
+// ARMEABISOFTFP:#define __UINT16_MAX__ 65535
+// ARMEABISOFTFP:#define __UINT16_TYPE__ unsigned short
+// ARMEABISOFTFP:#define __UINT32_C_SUFFIX__ U
+// ARMEABISOFTFP:#define __UINT32_MAX__ 4294967295U
+// ARMEABISOFTFP:#define __UINT32_TYPE__ unsigned int
+// ARMEABISOFTFP:#define __UINT64_C_SUFFIX__ ULL
+// ARMEABISOFTFP:#define __UINT64_MAX__ 18446744073709551615ULL
+// ARMEABISOFTFP:#define __UINT64_TYPE__ long long unsigned int
+// ARMEABISOFTFP:#define __UINT8_C_SUFFIX__ {{$}}
+// ARMEABISOFTFP:#define __UINT8_MAX__ 255
+// ARMEABISOFTFP:#define __UINT8_TYPE__ unsigned char
+// ARMEABISOFTFP:#define __UINTMAX_C_SUFFIX__ ULL
+// ARMEABISOFTFP:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // ARMEABISOFTFP:#define __UINTMAX_TYPE__ long long unsigned int
+// ARMEABISOFTFP:#define __UINTMAX_WIDTH__ 64
+// ARMEABISOFTFP:#define __UINTPTR_MAX__ 4294967295U
+// ARMEABISOFTFP:#define __UINTPTR_TYPE__ long unsigned int
+// ARMEABISOFTFP:#define __UINTPTR_WIDTH__ 32
+// ARMEABISOFTFP:#define __UINT_FAST16_MAX__ 65535
+// ARMEABISOFTFP:#define __UINT_FAST16_TYPE__ unsigned short
+// ARMEABISOFTFP:#define __UINT_FAST32_MAX__ 4294967295U
+// ARMEABISOFTFP:#define __UINT_FAST32_TYPE__ unsigned int
+// ARMEABISOFTFP:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// ARMEABISOFTFP:#define __UINT_FAST64_TYPE__ long long unsigned int
+// ARMEABISOFTFP:#define __UINT_FAST8_MAX__ 255
+// ARMEABISOFTFP:#define __UINT_FAST8_TYPE__ unsigned char
+// ARMEABISOFTFP:#define __UINT_LEAST16_MAX__ 65535
+// ARMEABISOFTFP:#define __UINT_LEAST16_TYPE__ unsigned short
+// ARMEABISOFTFP:#define __UINT_LEAST32_MAX__ 4294967295U
+// ARMEABISOFTFP:#define __UINT_LEAST32_TYPE__ unsigned int
+// ARMEABISOFTFP:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// ARMEABISOFTFP:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// ARMEABISOFTFP:#define __UINT_LEAST8_MAX__ 255
+// ARMEABISOFTFP:#define __UINT_LEAST8_TYPE__ unsigned char
 // ARMEABISOFTFP:#define __USER_LABEL_PREFIX__
 // ARMEABISOFTFP:#define __WCHAR_MAX__ 4294967295U
 // ARMEABISOFTFP:#define __WCHAR_TYPE__ unsigned int
@@ -409,11 +1380,13 @@
 
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=arm-none-linux-gnueabi < /dev/null | FileCheck -check-prefix ARMEABIHARDFP %s
 //
-// ARM-NOT:#define _LP64
+// ARMEABIHARDFP-NOT:#define _LP64
 // ARMEABIHARDFP:#define __APCS_32__ 1
+// ARMEABIHARDFP-NOT:#define __ARMEB__ 1
 // ARMEABIHARDFP:#define __ARMEL__ 1
 // ARMEABIHARDFP:#define __ARM_ARCH 6
 // ARMEABIHARDFP:#define __ARM_ARCH_6J__ 1
+// ARMEABIHARDFP-NOT:#define __ARM_BIG_ENDIAN 1
 // ARMEABIHARDFP:#define __ARM_EABI__ 1
 // ARMEABIHARDFP:#define __ARM_PCS 1
 // ARMEABIHARDFP:#define __ARM_PCS_VFP 1
@@ -450,16 +1423,69 @@
 // ARMEABIHARDFP:#define __FLT_MIN_EXP__ (-125)
 // ARMEABIHARDFP:#define __FLT_MIN__ 1.17549435e-38F
 // ARMEABIHARDFP:#define __FLT_RADIX__ 2
+// ARMEABIHARDFP:#define __INT16_C_SUFFIX__ {{$}}
+// ARMEABIHARDFP:#define __INT16_FMTd__ "hd"
+// ARMEABIHARDFP:#define __INT16_FMTi__ "hi"
+// ARMEABIHARDFP:#define __INT16_MAX__ 32767
 // ARMEABIHARDFP:#define __INT16_TYPE__ short
+// ARMEABIHARDFP:#define __INT32_C_SUFFIX__ {{$}}
+// ARMEABIHARDFP:#define __INT32_FMTd__ "d"
+// ARMEABIHARDFP:#define __INT32_FMTi__ "i"
+// ARMEABIHARDFP:#define __INT32_MAX__ 2147483647
 // ARMEABIHARDFP:#define __INT32_TYPE__ int
 // ARMEABIHARDFP:#define __INT64_C_SUFFIX__ LL
+// ARMEABIHARDFP:#define __INT64_FMTd__ "lld"
+// ARMEABIHARDFP:#define __INT64_FMTi__ "lli"
+// ARMEABIHARDFP:#define __INT64_MAX__ 9223372036854775807LL
 // ARMEABIHARDFP:#define __INT64_TYPE__ long long int
-// ARMEABIHARDFP:#define __INT8_TYPE__ char
+// ARMEABIHARDFP:#define __INT8_C_SUFFIX__ {{$}}
+// ARMEABIHARDFP:#define __INT8_FMTd__ "hhd"
+// ARMEABIHARDFP:#define __INT8_FMTi__ "hhi"
+// ARMEABIHARDFP:#define __INT8_MAX__ 127
+// ARMEABIHARDFP:#define __INT8_TYPE__ signed char
+// ARMEABIHARDFP:#define __INTMAX_C_SUFFIX__ LL
+// ARMEABIHARDFP:#define __INTMAX_FMTd__ "lld"
+// ARMEABIHARDFP:#define __INTMAX_FMTi__ "lli"
 // ARMEABIHARDFP:#define __INTMAX_MAX__ 9223372036854775807LL
 // ARMEABIHARDFP:#define __INTMAX_TYPE__ long long int
 // ARMEABIHARDFP:#define __INTMAX_WIDTH__ 64
+// ARMEABIHARDFP:#define __INTPTR_FMTd__ "ld"
+// ARMEABIHARDFP:#define __INTPTR_FMTi__ "li"
+// ARMEABIHARDFP:#define __INTPTR_MAX__ 2147483647L
 // ARMEABIHARDFP:#define __INTPTR_TYPE__ long int
 // ARMEABIHARDFP:#define __INTPTR_WIDTH__ 32
+// ARMEABIHARDFP:#define __INT_FAST16_FMTd__ "hd"
+// ARMEABIHARDFP:#define __INT_FAST16_FMTi__ "hi"
+// ARMEABIHARDFP:#define __INT_FAST16_MAX__ 32767
+// ARMEABIHARDFP:#define __INT_FAST16_TYPE__ short
+// ARMEABIHARDFP:#define __INT_FAST32_FMTd__ "d"
+// ARMEABIHARDFP:#define __INT_FAST32_FMTi__ "i"
+// ARMEABIHARDFP:#define __INT_FAST32_MAX__ 2147483647
+// ARMEABIHARDFP:#define __INT_FAST32_TYPE__ int
+// ARMEABIHARDFP:#define __INT_FAST64_FMTd__ "lld"
+// ARMEABIHARDFP:#define __INT_FAST64_FMTi__ "lli"
+// ARMEABIHARDFP:#define __INT_FAST64_MAX__ 9223372036854775807LL
+// ARMEABIHARDFP:#define __INT_FAST64_TYPE__ long long int
+// ARMEABIHARDFP:#define __INT_FAST8_FMTd__ "hhd"
+// ARMEABIHARDFP:#define __INT_FAST8_FMTi__ "hhi"
+// ARMEABIHARDFP:#define __INT_FAST8_MAX__ 127
+// ARMEABIHARDFP:#define __INT_FAST8_TYPE__ signed char
+// ARMEABIHARDFP:#define __INT_LEAST16_FMTd__ "hd"
+// ARMEABIHARDFP:#define __INT_LEAST16_FMTi__ "hi"
+// ARMEABIHARDFP:#define __INT_LEAST16_MAX__ 32767
+// ARMEABIHARDFP:#define __INT_LEAST16_TYPE__ short
+// ARMEABIHARDFP:#define __INT_LEAST32_FMTd__ "d"
+// ARMEABIHARDFP:#define __INT_LEAST32_FMTi__ "i"
+// ARMEABIHARDFP:#define __INT_LEAST32_MAX__ 2147483647
+// ARMEABIHARDFP:#define __INT_LEAST32_TYPE__ int
+// ARMEABIHARDFP:#define __INT_LEAST64_FMTd__ "lld"
+// ARMEABIHARDFP:#define __INT_LEAST64_FMTi__ "lli"
+// ARMEABIHARDFP:#define __INT_LEAST64_MAX__ 9223372036854775807LL
+// ARMEABIHARDFP:#define __INT_LEAST64_TYPE__ long long int
+// ARMEABIHARDFP:#define __INT_LEAST8_FMTd__ "hhd"
+// ARMEABIHARDFP:#define __INT_LEAST8_FMTi__ "hhi"
+// ARMEABIHARDFP:#define __INT_LEAST8_MAX__ 127
+// ARMEABIHARDFP:#define __INT_LEAST8_TYPE__ signed char
 // ARMEABIHARDFP:#define __INT_MAX__ 2147483647
 // ARMEABIHARDFP:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
 // ARMEABIHARDFP:#define __LDBL_DIG__ 15
@@ -484,6 +1510,7 @@
 // ARMEABIHARDFP:#define __REGISTER_PREFIX__
 // ARMEABIHARDFP:#define __SCHAR_MAX__ 127
 // ARMEABIHARDFP:#define __SHRT_MAX__ 32767
+// ARMEABIHARDFP:#define __SIG_ATOMIC_MAX__ 2147483647
 // ARMEABIHARDFP:#define __SIG_ATOMIC_WIDTH__ 32
 // ARMEABIHARDFP:#define __SIZEOF_DOUBLE__ 8
 // ARMEABIHARDFP:#define __SIZEOF_FLOAT__ 4
@@ -502,7 +1529,41 @@
 // ARMEABIHARDFP:#define __SIZE_WIDTH__ 32
 // ARMEABIHARDFP-NOT:#define __SOFTFP__ 1
 // ARMEABIHARDFP:#define __THUMB_INTERWORK__ 1
+// ARMEABIHARDFP:#define __UINT16_C_SUFFIX__ {{$}}
+// ARMEABIHARDFP:#define __UINT16_MAX__ 65535
+// ARMEABIHARDFP:#define __UINT16_TYPE__ unsigned short
+// ARMEABIHARDFP:#define __UINT32_C_SUFFIX__ U
+// ARMEABIHARDFP:#define __UINT32_MAX__ 4294967295U
+// ARMEABIHARDFP:#define __UINT32_TYPE__ unsigned int
+// ARMEABIHARDFP:#define __UINT64_C_SUFFIX__ ULL
+// ARMEABIHARDFP:#define __UINT64_MAX__ 18446744073709551615ULL
+// ARMEABIHARDFP:#define __UINT64_TYPE__ long long unsigned int
+// ARMEABIHARDFP:#define __UINT8_C_SUFFIX__ {{$}}
+// ARMEABIHARDFP:#define __UINT8_MAX__ 255
+// ARMEABIHARDFP:#define __UINT8_TYPE__ unsigned char
+// ARMEABIHARDFP:#define __UINTMAX_C_SUFFIX__ ULL
+// ARMEABIHARDFP:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // ARMEABIHARDFP:#define __UINTMAX_TYPE__ long long unsigned int
+// ARMEABIHARDFP:#define __UINTMAX_WIDTH__ 64
+// ARMEABIHARDFP:#define __UINTPTR_MAX__ 4294967295U
+// ARMEABIHARDFP:#define __UINTPTR_TYPE__ long unsigned int
+// ARMEABIHARDFP:#define __UINTPTR_WIDTH__ 32
+// ARMEABIHARDFP:#define __UINT_FAST16_MAX__ 65535
+// ARMEABIHARDFP:#define __UINT_FAST16_TYPE__ unsigned short
+// ARMEABIHARDFP:#define __UINT_FAST32_MAX__ 4294967295U
+// ARMEABIHARDFP:#define __UINT_FAST32_TYPE__ unsigned int
+// ARMEABIHARDFP:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// ARMEABIHARDFP:#define __UINT_FAST64_TYPE__ long long unsigned int
+// ARMEABIHARDFP:#define __UINT_FAST8_MAX__ 255
+// ARMEABIHARDFP:#define __UINT_FAST8_TYPE__ unsigned char
+// ARMEABIHARDFP:#define __UINT_LEAST16_MAX__ 65535
+// ARMEABIHARDFP:#define __UINT_LEAST16_TYPE__ unsigned short
+// ARMEABIHARDFP:#define __UINT_LEAST32_MAX__ 4294967295U
+// ARMEABIHARDFP:#define __UINT_LEAST32_TYPE__ unsigned int
+// ARMEABIHARDFP:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// ARMEABIHARDFP:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// ARMEABIHARDFP:#define __UINT_LEAST8_MAX__ 255
+// ARMEABIHARDFP:#define __UINT_LEAST8_TYPE__ unsigned char
 // ARMEABIHARDFP:#define __USER_LABEL_PREFIX__
 // ARMEABIHARDFP:#define __WCHAR_MAX__ 4294967295U
 // ARMEABIHARDFP:#define __WCHAR_TYPE__ unsigned int
@@ -512,6 +1573,198 @@
 // ARMEABIHARDFP:#define __arm 1
 // ARMEABIHARDFP:#define __arm__ 1
 
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=arm-netbsd-eabi < /dev/null | FileCheck -check-prefix ARM-NETBSD %s
+//
+// ARM-NETBSD-NOT:#define _LP64
+// ARM-NETBSD:#define __APCS_32__ 1
+// ARM-NETBSD-NOT:#define __ARMEB__ 1
+// ARM-NETBSD:#define __ARMEL__ 1
+// ARM-NETBSD:#define __ARM_ARCH_6J__ 1
+// ARM-NETBSD:#define __ARM_DWARF_EH__ 1
+// ARM-NETBSD:#define __ARM_EABI__ 1
+// ARM-NETBSD-NOT:#define __ARM_BIG_ENDIAN 1
+// ARM-NETBSD:#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
+// ARM-NETBSD:#define __CHAR16_TYPE__ unsigned short
+// ARM-NETBSD:#define __CHAR32_TYPE__ unsigned int
+// ARM-NETBSD:#define __CHAR_BIT__ 8
+// ARM-NETBSD:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
+// ARM-NETBSD:#define __DBL_DIG__ 15
+// ARM-NETBSD:#define __DBL_EPSILON__ 2.2204460492503131e-16
+// ARM-NETBSD:#define __DBL_HAS_DENORM__ 1
+// ARM-NETBSD:#define __DBL_HAS_INFINITY__ 1
+// ARM-NETBSD:#define __DBL_HAS_QUIET_NAN__ 1
+// ARM-NETBSD:#define __DBL_MANT_DIG__ 53
+// ARM-NETBSD:#define __DBL_MAX_10_EXP__ 308
+// ARM-NETBSD:#define __DBL_MAX_EXP__ 1024
+// ARM-NETBSD:#define __DBL_MAX__ 1.7976931348623157e+308
+// ARM-NETBSD:#define __DBL_MIN_10_EXP__ (-307)
+// ARM-NETBSD:#define __DBL_MIN_EXP__ (-1021)
+// ARM-NETBSD:#define __DBL_MIN__ 2.2250738585072014e-308
+// ARM-NETBSD:#define __DECIMAL_DIG__ 17
+// ARM-NETBSD:#define __FLT_DENORM_MIN__ 1.40129846e-45F
+// ARM-NETBSD:#define __FLT_DIG__ 6
+// ARM-NETBSD:#define __FLT_EPSILON__ 1.19209290e-7F
+// ARM-NETBSD:#define __FLT_EVAL_METHOD__ 0
+// ARM-NETBSD:#define __FLT_HAS_DENORM__ 1
+// ARM-NETBSD:#define __FLT_HAS_INFINITY__ 1
+// ARM-NETBSD:#define __FLT_HAS_QUIET_NAN__ 1
+// ARM-NETBSD:#define __FLT_MANT_DIG__ 24
+// ARM-NETBSD:#define __FLT_MAX_10_EXP__ 38
+// ARM-NETBSD:#define __FLT_MAX_EXP__ 128
+// ARM-NETBSD:#define __FLT_MAX__ 3.40282347e+38F
+// ARM-NETBSD:#define __FLT_MIN_10_EXP__ (-37)
+// ARM-NETBSD:#define __FLT_MIN_EXP__ (-125)
+// ARM-NETBSD:#define __FLT_MIN__ 1.17549435e-38F
+// ARM-NETBSD:#define __FLT_RADIX__ 2
+// ARM-NETBSD:#define __INT16_C_SUFFIX__ {{$}}
+// ARM-NETBSD:#define __INT16_FMTd__ "hd"
+// ARM-NETBSD:#define __INT16_FMTi__ "hi"
+// ARM-NETBSD:#define __INT16_MAX__ 32767
+// ARM-NETBSD:#define __INT16_TYPE__ short
+// ARM-NETBSD:#define __INT32_C_SUFFIX__ {{$}}
+// ARM-NETBSD:#define __INT32_FMTd__ "d"
+// ARM-NETBSD:#define __INT32_FMTi__ "i"
+// ARM-NETBSD:#define __INT32_MAX__ 2147483647
+// ARM-NETBSD:#define __INT32_TYPE__ int
+// ARM-NETBSD:#define __INT64_C_SUFFIX__ LL
+// ARM-NETBSD:#define __INT64_FMTd__ "lld"
+// ARM-NETBSD:#define __INT64_FMTi__ "lli"
+// ARM-NETBSD:#define __INT64_MAX__ 9223372036854775807LL
+// ARM-NETBSD:#define __INT64_TYPE__ long long int
+// ARM-NETBSD:#define __INT8_C_SUFFIX__ {{$}}
+// ARM-NETBSD:#define __INT8_FMTd__ "hhd"
+// ARM-NETBSD:#define __INT8_FMTi__ "hhi"
+// ARM-NETBSD:#define __INT8_MAX__ 127
+// ARM-NETBSD:#define __INT8_TYPE__ signed char
+// ARM-NETBSD:#define __INTMAX_C_SUFFIX__ LL
+// ARM-NETBSD:#define __INTMAX_FMTd__ "lld"
+// ARM-NETBSD:#define __INTMAX_FMTi__ "lli"
+// ARM-NETBSD:#define __INTMAX_MAX__ 9223372036854775807LL
+// ARM-NETBSD:#define __INTMAX_TYPE__ long long int
+// ARM-NETBSD:#define __INTMAX_WIDTH__ 64
+// ARM-NETBSD:#define __INTPTR_FMTd__ "ld"
+// ARM-NETBSD:#define __INTPTR_FMTi__ "li"
+// ARM-NETBSD:#define __INTPTR_MAX__ 2147483647L
+// ARM-NETBSD:#define __INTPTR_TYPE__ long int
+// ARM-NETBSD:#define __INTPTR_WIDTH__ 32
+// ARM-NETBSD:#define __INT_FAST16_FMTd__ "hd"
+// ARM-NETBSD:#define __INT_FAST16_FMTi__ "hi"
+// ARM-NETBSD:#define __INT_FAST16_MAX__ 32767
+// ARM-NETBSD:#define __INT_FAST16_TYPE__ short
+// ARM-NETBSD:#define __INT_FAST32_FMTd__ "d"
+// ARM-NETBSD:#define __INT_FAST32_FMTi__ "i"
+// ARM-NETBSD:#define __INT_FAST32_MAX__ 2147483647
+// ARM-NETBSD:#define __INT_FAST32_TYPE__ int
+// ARM-NETBSD:#define __INT_FAST64_FMTd__ "lld"
+// ARM-NETBSD:#define __INT_FAST64_FMTi__ "lli"
+// ARM-NETBSD:#define __INT_FAST64_MAX__ 9223372036854775807LL
+// ARM-NETBSD:#define __INT_FAST64_TYPE__ long long int
+// ARM-NETBSD:#define __INT_FAST8_FMTd__ "hhd"
+// ARM-NETBSD:#define __INT_FAST8_FMTi__ "hhi"
+// ARM-NETBSD:#define __INT_FAST8_MAX__ 127
+// ARM-NETBSD:#define __INT_FAST8_TYPE__ signed char
+// ARM-NETBSD:#define __INT_LEAST16_FMTd__ "hd"
+// ARM-NETBSD:#define __INT_LEAST16_FMTi__ "hi"
+// ARM-NETBSD:#define __INT_LEAST16_MAX__ 32767
+// ARM-NETBSD:#define __INT_LEAST16_TYPE__ short
+// ARM-NETBSD:#define __INT_LEAST32_FMTd__ "d"
+// ARM-NETBSD:#define __INT_LEAST32_FMTi__ "i"
+// ARM-NETBSD:#define __INT_LEAST32_MAX__ 2147483647
+// ARM-NETBSD:#define __INT_LEAST32_TYPE__ int
+// ARM-NETBSD:#define __INT_LEAST64_FMTd__ "lld"
+// ARM-NETBSD:#define __INT_LEAST64_FMTi__ "lli"
+// ARM-NETBSD:#define __INT_LEAST64_MAX__ 9223372036854775807LL
+// ARM-NETBSD:#define __INT_LEAST64_TYPE__ long long int
+// ARM-NETBSD:#define __INT_LEAST8_FMTd__ "hhd"
+// ARM-NETBSD:#define __INT_LEAST8_FMTi__ "hhi"
+// ARM-NETBSD:#define __INT_LEAST8_MAX__ 127
+// ARM-NETBSD:#define __INT_LEAST8_TYPE__ signed char
+// ARM-NETBSD:#define __INT_MAX__ 2147483647
+// ARM-NETBSD:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
+// ARM-NETBSD:#define __LDBL_DIG__ 15
+// ARM-NETBSD:#define __LDBL_EPSILON__ 2.2204460492503131e-16L
+// ARM-NETBSD:#define __LDBL_HAS_DENORM__ 1
+// ARM-NETBSD:#define __LDBL_HAS_INFINITY__ 1
+// ARM-NETBSD:#define __LDBL_HAS_QUIET_NAN__ 1
+// ARM-NETBSD:#define __LDBL_MANT_DIG__ 53
+// ARM-NETBSD:#define __LDBL_MAX_10_EXP__ 308
+// ARM-NETBSD:#define __LDBL_MAX_EXP__ 1024
+// ARM-NETBSD:#define __LDBL_MAX__ 1.7976931348623157e+308L
+// ARM-NETBSD:#define __LDBL_MIN_10_EXP__ (-307)
+// ARM-NETBSD:#define __LDBL_MIN_EXP__ (-1021)
+// ARM-NETBSD:#define __LDBL_MIN__ 2.2250738585072014e-308L
+// ARM-NETBSD:#define __LITTLE_ENDIAN__ 1
+// ARM-NETBSD:#define __LONG_LONG_MAX__ 9223372036854775807LL
+// ARM-NETBSD:#define __LONG_MAX__ 2147483647L
+// ARM-NETBSD-NOT:#define __LP64__
+// ARM-NETBSD:#define __POINTER_WIDTH__ 32
+// ARM-NETBSD:#define __PTRDIFF_TYPE__ long int
+// ARM-NETBSD:#define __PTRDIFF_WIDTH__ 32
+// ARM-NETBSD:#define __REGISTER_PREFIX__
+// ARM-NETBSD:#define __SCHAR_MAX__ 127
+// ARM-NETBSD:#define __SHRT_MAX__ 32767
+// ARM-NETBSD:#define __SIG_ATOMIC_MAX__ 2147483647
+// ARM-NETBSD:#define __SIG_ATOMIC_WIDTH__ 32
+// ARM-NETBSD:#define __SIZEOF_DOUBLE__ 8
+// ARM-NETBSD:#define __SIZEOF_FLOAT__ 4
+// ARM-NETBSD:#define __SIZEOF_INT__ 4
+// ARM-NETBSD:#define __SIZEOF_LONG_DOUBLE__ 8
+// ARM-NETBSD:#define __SIZEOF_LONG_LONG__ 8
+// ARM-NETBSD:#define __SIZEOF_LONG__ 4
+// ARM-NETBSD:#define __SIZEOF_POINTER__ 4
+// ARM-NETBSD:#define __SIZEOF_PTRDIFF_T__ 4
+// ARM-NETBSD:#define __SIZEOF_SHORT__ 2
+// ARM-NETBSD:#define __SIZEOF_SIZE_T__ 4
+// ARM-NETBSD:#define __SIZEOF_WCHAR_T__ 4
+// ARM-NETBSD:#define __SIZEOF_WINT_T__ 4
+// ARM-NETBSD:#define __SIZE_MAX__ 4294967295U
+// ARM-NETBSD:#define __SIZE_TYPE__ long unsigned int
+// ARM-NETBSD:#define __SIZE_WIDTH__ 32
+// ARM-NETBSD:#define __THUMB_INTERWORK__ 1
+// ARM-NETBSD:#define __UINT16_C_SUFFIX__ {{$}}
+// ARM-NETBSD:#define __UINT16_MAX__ 65535
+// ARM-NETBSD:#define __UINT16_TYPE__ unsigned short
+// ARM-NETBSD:#define __UINT32_C_SUFFIX__ U
+// ARM-NETBSD:#define __UINT32_MAX__ 4294967295U
+// ARM-NETBSD:#define __UINT32_TYPE__ unsigned int
+// ARM-NETBSD:#define __UINT64_C_SUFFIX__ ULL
+// ARM-NETBSD:#define __UINT64_MAX__ 18446744073709551615ULL
+// ARM-NETBSD:#define __UINT64_TYPE__ long long unsigned int
+// ARM-NETBSD:#define __UINT8_C_SUFFIX__ {{$}}
+// ARM-NETBSD:#define __UINT8_MAX__ 255
+// ARM-NETBSD:#define __UINT8_TYPE__ unsigned char
+// ARM-NETBSD:#define __UINTMAX_C_SUFFIX__ UL
+// ARM-NETBSD:#define __UINTMAX_MAX__ 18446744073709551615ULL
+// ARM-NETBSD:#define __UINTMAX_TYPE__ long long unsigned int
+// ARM-NETBSD:#define __UINTMAX_WIDTH__ 64
+// ARM-NETBSD:#define __UINTPTR_MAX__ 4294967295U
+// ARM-NETBSD:#define __UINTPTR_TYPE__ long unsigned int
+// ARM-NETBSD:#define __UINTPTR_WIDTH__ 32
+// ARM-NETBSD:#define __UINT_FAST16_MAX__ 65535
+// ARM-NETBSD:#define __UINT_FAST16_TYPE__ unsigned short
+// ARM-NETBSD:#define __UINT_FAST32_MAX__ 4294967295U
+// ARM-NETBSD:#define __UINT_FAST32_TYPE__ unsigned int
+// ARM-NETBSD:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// ARM-NETBSD:#define __UINT_FAST64_TYPE__ long long unsigned int
+// ARM-NETBSD:#define __UINT_FAST8_MAX__ 255
+// ARM-NETBSD:#define __UINT_FAST8_TYPE__ unsigned char
+// ARM-NETBSD:#define __UINT_LEAST16_MAX__ 65535
+// ARM-NETBSD:#define __UINT_LEAST16_TYPE__ unsigned short
+// ARM-NETBSD:#define __UINT_LEAST32_MAX__ 4294967295U
+// ARM-NETBSD:#define __UINT_LEAST32_TYPE__ unsigned int
+// ARM-NETBSD:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// ARM-NETBSD:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// ARM-NETBSD:#define __UINT_LEAST8_MAX__ 255
+// ARM-NETBSD:#define __UINT_LEAST8_TYPE__ unsigned char
+// ARM-NETBSD:#define __USER_LABEL_PREFIX__
+// ARM-NETBSD:#define __WCHAR_MAX__ 2147483647
+// ARM-NETBSD:#define __WCHAR_TYPE__ int
+// ARM-NETBSD:#define __WCHAR_WIDTH__ 32
+// ARM-NETBSD:#define __WINT_TYPE__ int
+// ARM-NETBSD:#define __WINT_WIDTH__ 32
+// ARM-NETBSD:#define __arm 1
+// ARM-NETBSD:#define __arm__ 1
+
 // RUN: %clang -target arm -arch armv7s -x c -E -dM %s -o - | FileCheck --check-prefix=ARM-DARWIN-NO-EABI %s
 // RUN: %clang -target arm -arch armv6m -x c -E -dM %s -o - | FileCheck --check-prefix=ARM-DARWIN-NO-EABI %s
 // RUN: %clang -target arm -arch armv7m -x c -E -dM %s -o - | FileCheck --check-prefix=ARM-DARWIN-NO-EABI %s
@@ -539,6 +1792,38 @@
 // RUN: %clang -target arm -mthumb -mhwdiv=arm -x c -E -dM %s -o - | FileCheck --check-prefix=ARMHWDIV-THUMB-FALSE %s
 // ARMHWDIV-THUMB-FALSE-NOT:#define __ARM_ARCH_EXT_IDIV__
 
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=armv8-none-none < /dev/null | FileCheck -check-prefix ARMv8 %s
+// ARMv8: #define __THUMB_INTERWORK__ 1
+// ARMv8-NOT: #define __thumb2__
+
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=armebv8-none-none < /dev/null | FileCheck -check-prefix ARMebv8 %s
+// ARMebv8: #define __THUMB_INTERWORK__ 1
+// ARMebv8-NOT: #define __thumb2__
+
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=thumbv8 < /dev/null | FileCheck -check-prefix Thumbv8 %s
+// Thumbv8: #define __THUMB_INTERWORK__ 1
+// Thumbv8: #define __thumb2__
+
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=thumbebv8 < /dev/null | FileCheck -check-prefix Thumbebv8 %s
+// Thumbebv8: #define __THUMB_INTERWORK__ 1
+// Thumbebv8: #define __thumb2__
+
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=thumbv5 < /dev/null | FileCheck -check-prefix Thumbv5 %s
+// Thumbv5: #define __THUMB_INTERWORK__ 1
+// Thumbv5-NOT: #define __thumb2__
+
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=thumbv6t2 < /dev/null | FileCheck -check-prefix Thumbv6t2 %s
+// Thumbv6t2: #define __THUMB_INTERWORK__ 1
+// Thumbv6t2: #define __thumb2__
+
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=thumbv7 < /dev/null | FileCheck -check-prefix Thumbv7 %s
+// Thumbv7: #define __THUMB_INTERWORK__ 1
+// Thumbv7: #define __thumb2__
+
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=thumbebv7 < /dev/null | FileCheck -check-prefix Thumbebv7 %s
+// Thumbebv7: #define __THUMB_INTERWORK__ 1
+// Thumbebv7: #define __thumb2__
+
 //
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=i386-none-none < /dev/null | FileCheck -check-prefix I386 %s
 //
@@ -576,16 +1861,69 @@
 // I386:#define __FLT_MIN_EXP__ (-125)
 // I386:#define __FLT_MIN__ 1.17549435e-38F
 // I386:#define __FLT_RADIX__ 2
+// I386:#define __INT16_C_SUFFIX__ {{$}}
+// I386:#define __INT16_FMTd__ "hd"
+// I386:#define __INT16_FMTi__ "hi"
+// I386:#define __INT16_MAX__ 32767
 // I386:#define __INT16_TYPE__ short
+// I386:#define __INT32_C_SUFFIX__ {{$}}
+// I386:#define __INT32_FMTd__ "d"
+// I386:#define __INT32_FMTi__ "i"
+// I386:#define __INT32_MAX__ 2147483647
 // I386:#define __INT32_TYPE__ int
 // I386:#define __INT64_C_SUFFIX__ LL
+// I386:#define __INT64_FMTd__ "lld"
+// I386:#define __INT64_FMTi__ "lli"
+// I386:#define __INT64_MAX__ 9223372036854775807LL
 // I386:#define __INT64_TYPE__ long long int
-// I386:#define __INT8_TYPE__ char
+// I386:#define __INT8_C_SUFFIX__ {{$}}
+// I386:#define __INT8_FMTd__ "hhd"
+// I386:#define __INT8_FMTi__ "hhi"
+// I386:#define __INT8_MAX__ 127
+// I386:#define __INT8_TYPE__ signed char
+// I386:#define __INTMAX_C_SUFFIX__ LL
+// I386:#define __INTMAX_FMTd__ "lld"
+// I386:#define __INTMAX_FMTi__ "lli"
 // I386:#define __INTMAX_MAX__ 9223372036854775807LL
 // I386:#define __INTMAX_TYPE__ long long int
 // I386:#define __INTMAX_WIDTH__ 64
+// I386:#define __INTPTR_FMTd__ "d"
+// I386:#define __INTPTR_FMTi__ "i"
+// I386:#define __INTPTR_MAX__ 2147483647
 // I386:#define __INTPTR_TYPE__ int
 // I386:#define __INTPTR_WIDTH__ 32
+// I386:#define __INT_FAST16_FMTd__ "hd"
+// I386:#define __INT_FAST16_FMTi__ "hi"
+// I386:#define __INT_FAST16_MAX__ 32767
+// I386:#define __INT_FAST16_TYPE__ short
+// I386:#define __INT_FAST32_FMTd__ "d"
+// I386:#define __INT_FAST32_FMTi__ "i"
+// I386:#define __INT_FAST32_MAX__ 2147483647
+// I386:#define __INT_FAST32_TYPE__ int
+// I386:#define __INT_FAST64_FMTd__ "lld"
+// I386:#define __INT_FAST64_FMTi__ "lli"
+// I386:#define __INT_FAST64_MAX__ 9223372036854775807LL
+// I386:#define __INT_FAST64_TYPE__ long long int
+// I386:#define __INT_FAST8_FMTd__ "hhd"
+// I386:#define __INT_FAST8_FMTi__ "hhi"
+// I386:#define __INT_FAST8_MAX__ 127
+// I386:#define __INT_FAST8_TYPE__ signed char
+// I386:#define __INT_LEAST16_FMTd__ "hd"
+// I386:#define __INT_LEAST16_FMTi__ "hi"
+// I386:#define __INT_LEAST16_MAX__ 32767
+// I386:#define __INT_LEAST16_TYPE__ short
+// I386:#define __INT_LEAST32_FMTd__ "d"
+// I386:#define __INT_LEAST32_FMTi__ "i"
+// I386:#define __INT_LEAST32_MAX__ 2147483647
+// I386:#define __INT_LEAST32_TYPE__ int
+// I386:#define __INT_LEAST64_FMTd__ "lld"
+// I386:#define __INT_LEAST64_FMTi__ "lli"
+// I386:#define __INT_LEAST64_MAX__ 9223372036854775807LL
+// I386:#define __INT_LEAST64_TYPE__ long long int
+// I386:#define __INT_LEAST8_FMTd__ "hhd"
+// I386:#define __INT_LEAST8_FMTi__ "hhi"
+// I386:#define __INT_LEAST8_MAX__ 127
+// I386:#define __INT_LEAST8_TYPE__ signed char
 // I386:#define __INT_MAX__ 2147483647
 // I386:#define __LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L
 // I386:#define __LDBL_DIG__ 18
@@ -611,6 +1949,7 @@
 // I386:#define __REGISTER_PREFIX__ 
 // I386:#define __SCHAR_MAX__ 127
 // I386:#define __SHRT_MAX__ 32767
+// I386:#define __SIG_ATOMIC_MAX__ 2147483647
 // I386:#define __SIG_ATOMIC_WIDTH__ 32
 // I386:#define __SIZEOF_DOUBLE__ 8
 // I386:#define __SIZEOF_FLOAT__ 4
@@ -627,7 +1966,41 @@
 // I386:#define __SIZE_MAX__ 4294967295U
 // I386:#define __SIZE_TYPE__ unsigned int
 // I386:#define __SIZE_WIDTH__ 32
+// I386:#define __UINT16_C_SUFFIX__ {{$}}
+// I386:#define __UINT16_MAX__ 65535
+// I386:#define __UINT16_TYPE__ unsigned short
+// I386:#define __UINT32_C_SUFFIX__ U
+// I386:#define __UINT32_MAX__ 4294967295U
+// I386:#define __UINT32_TYPE__ unsigned int
+// I386:#define __UINT64_C_SUFFIX__ ULL
+// I386:#define __UINT64_MAX__ 18446744073709551615ULL
+// I386:#define __UINT64_TYPE__ long long unsigned int
+// I386:#define __UINT8_C_SUFFIX__ {{$}}
+// I386:#define __UINT8_MAX__ 255
+// I386:#define __UINT8_TYPE__ unsigned char
+// I386:#define __UINTMAX_C_SUFFIX__ ULL
+// I386:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // I386:#define __UINTMAX_TYPE__ long long unsigned int
+// I386:#define __UINTMAX_WIDTH__ 64
+// I386:#define __UINTPTR_MAX__ 4294967295U
+// I386:#define __UINTPTR_TYPE__ unsigned int
+// I386:#define __UINTPTR_WIDTH__ 32
+// I386:#define __UINT_FAST16_MAX__ 65535
+// I386:#define __UINT_FAST16_TYPE__ unsigned short
+// I386:#define __UINT_FAST32_MAX__ 4294967295U
+// I386:#define __UINT_FAST32_TYPE__ unsigned int
+// I386:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// I386:#define __UINT_FAST64_TYPE__ long long unsigned int
+// I386:#define __UINT_FAST8_MAX__ 255
+// I386:#define __UINT_FAST8_TYPE__ unsigned char
+// I386:#define __UINT_LEAST16_MAX__ 65535
+// I386:#define __UINT_LEAST16_TYPE__ unsigned short
+// I386:#define __UINT_LEAST32_MAX__ 4294967295U
+// I386:#define __UINT_LEAST32_TYPE__ unsigned int
+// I386:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// I386:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// I386:#define __UINT_LEAST8_MAX__ 255
+// I386:#define __UINT_LEAST8_TYPE__ unsigned char
 // I386:#define __USER_LABEL_PREFIX__ _
 // I386:#define __WCHAR_MAX__ 2147483647
 // I386:#define __WCHAR_TYPE__ int
@@ -674,16 +2047,69 @@
 // I386-LINUX:#define __FLT_MIN_EXP__ (-125)
 // I386-LINUX:#define __FLT_MIN__ 1.17549435e-38F
 // I386-LINUX:#define __FLT_RADIX__ 2
+// I386-LINUX:#define __INT16_C_SUFFIX__ {{$}}
+// I386-LINUX:#define __INT16_FMTd__ "hd"
+// I386-LINUX:#define __INT16_FMTi__ "hi"
+// I386-LINUX:#define __INT16_MAX__ 32767
 // I386-LINUX:#define __INT16_TYPE__ short
+// I386-LINUX:#define __INT32_C_SUFFIX__ {{$}}
+// I386-LINUX:#define __INT32_FMTd__ "d"
+// I386-LINUX:#define __INT32_FMTi__ "i"
+// I386-LINUX:#define __INT32_MAX__ 2147483647
 // I386-LINUX:#define __INT32_TYPE__ int
 // I386-LINUX:#define __INT64_C_SUFFIX__ LL
+// I386-LINUX:#define __INT64_FMTd__ "lld"
+// I386-LINUX:#define __INT64_FMTi__ "lli"
+// I386-LINUX:#define __INT64_MAX__ 9223372036854775807LL
 // I386-LINUX:#define __INT64_TYPE__ long long int
-// I386-LINUX:#define __INT8_TYPE__ char
+// I386-LINUX:#define __INT8_C_SUFFIX__ {{$}}
+// I386-LINUX:#define __INT8_FMTd__ "hhd"
+// I386-LINUX:#define __INT8_FMTi__ "hhi"
+// I386-LINUX:#define __INT8_MAX__ 127
+// I386-LINUX:#define __INT8_TYPE__ signed char
+// I386-LINUX:#define __INTMAX_C_SUFFIX__ LL
+// I386-LINUX:#define __INTMAX_FMTd__ "lld"
+// I386-LINUX:#define __INTMAX_FMTi__ "lli"
 // I386-LINUX:#define __INTMAX_MAX__ 9223372036854775807LL
 // I386-LINUX:#define __INTMAX_TYPE__ long long int
 // I386-LINUX:#define __INTMAX_WIDTH__ 64
+// I386-LINUX:#define __INTPTR_FMTd__ "d"
+// I386-LINUX:#define __INTPTR_FMTi__ "i"
+// I386-LINUX:#define __INTPTR_MAX__ 2147483647
 // I386-LINUX:#define __INTPTR_TYPE__ int
 // I386-LINUX:#define __INTPTR_WIDTH__ 32
+// I386-LINUX:#define __INT_FAST16_FMTd__ "hd"
+// I386-LINUX:#define __INT_FAST16_FMTi__ "hi"
+// I386-LINUX:#define __INT_FAST16_MAX__ 32767
+// I386-LINUX:#define __INT_FAST16_TYPE__ short
+// I386-LINUX:#define __INT_FAST32_FMTd__ "d"
+// I386-LINUX:#define __INT_FAST32_FMTi__ "i"
+// I386-LINUX:#define __INT_FAST32_MAX__ 2147483647
+// I386-LINUX:#define __INT_FAST32_TYPE__ int
+// I386-LINUX:#define __INT_FAST64_FMTd__ "lld"
+// I386-LINUX:#define __INT_FAST64_FMTi__ "lli"
+// I386-LINUX:#define __INT_FAST64_MAX__ 9223372036854775807LL
+// I386-LINUX:#define __INT_FAST64_TYPE__ long long int
+// I386-LINUX:#define __INT_FAST8_FMTd__ "hhd"
+// I386-LINUX:#define __INT_FAST8_FMTi__ "hhi"
+// I386-LINUX:#define __INT_FAST8_MAX__ 127
+// I386-LINUX:#define __INT_FAST8_TYPE__ signed char
+// I386-LINUX:#define __INT_LEAST16_FMTd__ "hd"
+// I386-LINUX:#define __INT_LEAST16_FMTi__ "hi"
+// I386-LINUX:#define __INT_LEAST16_MAX__ 32767
+// I386-LINUX:#define __INT_LEAST16_TYPE__ short
+// I386-LINUX:#define __INT_LEAST32_FMTd__ "d"
+// I386-LINUX:#define __INT_LEAST32_FMTi__ "i"
+// I386-LINUX:#define __INT_LEAST32_MAX__ 2147483647
+// I386-LINUX:#define __INT_LEAST32_TYPE__ int
+// I386-LINUX:#define __INT_LEAST64_FMTd__ "lld"
+// I386-LINUX:#define __INT_LEAST64_FMTi__ "lli"
+// I386-LINUX:#define __INT_LEAST64_MAX__ 9223372036854775807LL
+// I386-LINUX:#define __INT_LEAST64_TYPE__ long long int
+// I386-LINUX:#define __INT_LEAST8_FMTd__ "hhd"
+// I386-LINUX:#define __INT_LEAST8_FMTi__ "hhi"
+// I386-LINUX:#define __INT_LEAST8_MAX__ 127
+// I386-LINUX:#define __INT_LEAST8_TYPE__ signed char
 // I386-LINUX:#define __INT_MAX__ 2147483647
 // I386-LINUX:#define __LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L
 // I386-LINUX:#define __LDBL_DIG__ 18
@@ -709,6 +2135,7 @@
 // I386-LINUX:#define __REGISTER_PREFIX__ 
 // I386-LINUX:#define __SCHAR_MAX__ 127
 // I386-LINUX:#define __SHRT_MAX__ 32767
+// I386-LINUX:#define __SIG_ATOMIC_MAX__ 2147483647
 // I386-LINUX:#define __SIG_ATOMIC_WIDTH__ 32
 // I386-LINUX:#define __SIZEOF_DOUBLE__ 8
 // I386-LINUX:#define __SIZEOF_FLOAT__ 4
@@ -725,7 +2152,41 @@
 // I386-LINUX:#define __SIZE_MAX__ 4294967295U
 // I386-LINUX:#define __SIZE_TYPE__ unsigned int
 // I386-LINUX:#define __SIZE_WIDTH__ 32
+// I386-LINUX:#define __UINT16_C_SUFFIX__ {{$}}
+// I386-LINUX:#define __UINT16_MAX__ 65535
+// I386-LINUX:#define __UINT16_TYPE__ unsigned short
+// I386-LINUX:#define __UINT32_C_SUFFIX__ U
+// I386-LINUX:#define __UINT32_MAX__ 4294967295U
+// I386-LINUX:#define __UINT32_TYPE__ unsigned int
+// I386-LINUX:#define __UINT64_C_SUFFIX__ ULL
+// I386-LINUX:#define __UINT64_MAX__ 18446744073709551615ULL
+// I386-LINUX:#define __UINT64_TYPE__ long long unsigned int
+// I386-LINUX:#define __UINT8_C_SUFFIX__ {{$}}
+// I386-LINUX:#define __UINT8_MAX__ 255
+// I386-LINUX:#define __UINT8_TYPE__ unsigned char
+// I386-LINUX:#define __UINTMAX_C_SUFFIX__ ULL
+// I386-LINUX:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // I386-LINUX:#define __UINTMAX_TYPE__ long long unsigned int
+// I386-LINUX:#define __UINTMAX_WIDTH__ 64
+// I386-LINUX:#define __UINTPTR_MAX__ 4294967295U
+// I386-LINUX:#define __UINTPTR_TYPE__ unsigned int
+// I386-LINUX:#define __UINTPTR_WIDTH__ 32
+// I386-LINUX:#define __UINT_FAST16_MAX__ 65535
+// I386-LINUX:#define __UINT_FAST16_TYPE__ unsigned short
+// I386-LINUX:#define __UINT_FAST32_MAX__ 4294967295U
+// I386-LINUX:#define __UINT_FAST32_TYPE__ unsigned int
+// I386-LINUX:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// I386-LINUX:#define __UINT_FAST64_TYPE__ long long unsigned int
+// I386-LINUX:#define __UINT_FAST8_MAX__ 255
+// I386-LINUX:#define __UINT_FAST8_TYPE__ unsigned char
+// I386-LINUX:#define __UINT_LEAST16_MAX__ 65535
+// I386-LINUX:#define __UINT_LEAST16_TYPE__ unsigned short
+// I386-LINUX:#define __UINT_LEAST32_MAX__ 4294967295U
+// I386-LINUX:#define __UINT_LEAST32_TYPE__ unsigned int
+// I386-LINUX:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// I386-LINUX:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// I386-LINUX:#define __UINT_LEAST8_MAX__ 255
+// I386-LINUX:#define __UINT_LEAST8_TYPE__ unsigned char
 // I386-LINUX:#define __USER_LABEL_PREFIX__
 // I386-LINUX:#define __WCHAR_MAX__ 2147483647
 // I386-LINUX:#define __WCHAR_TYPE__ int
@@ -772,16 +2233,69 @@
 // I386-NETBSD:#define __FLT_MIN_EXP__ (-125)
 // I386-NETBSD:#define __FLT_MIN__ 1.17549435e-38F
 // I386-NETBSD:#define __FLT_RADIX__ 2
+// I386-NETBSD:#define __INT16_C_SUFFIX__ {{$}}
+// I386-NETBSD:#define __INT16_FMTd__ "hd"
+// I386-NETBSD:#define __INT16_FMTi__ "hi"
+// I386-NETBSD:#define __INT16_MAX__ 32767
 // I386-NETBSD:#define __INT16_TYPE__ short
+// I386-NETBSD:#define __INT32_C_SUFFIX__ {{$}}
+// I386-NETBSD:#define __INT32_FMTd__ "d"
+// I386-NETBSD:#define __INT32_FMTi__ "i"
+// I386-NETBSD:#define __INT32_MAX__ 2147483647
 // I386-NETBSD:#define __INT32_TYPE__ int
 // I386-NETBSD:#define __INT64_C_SUFFIX__ LL
+// I386-NETBSD:#define __INT64_FMTd__ "lld"
+// I386-NETBSD:#define __INT64_FMTi__ "lli"
+// I386-NETBSD:#define __INT64_MAX__ 9223372036854775807LL
 // I386-NETBSD:#define __INT64_TYPE__ long long int
-// I386-NETBSD:#define __INT8_TYPE__ char
+// I386-NETBSD:#define __INT8_C_SUFFIX__ {{$}}
+// I386-NETBSD:#define __INT8_FMTd__ "hhd"
+// I386-NETBSD:#define __INT8_FMTi__ "hhi"
+// I386-NETBSD:#define __INT8_MAX__ 127
+// I386-NETBSD:#define __INT8_TYPE__ signed char
+// I386-NETBSD:#define __INTMAX_C_SUFFIX__ LL
+// I386-NETBSD:#define __INTMAX_FMTd__ "lld"
+// I386-NETBSD:#define __INTMAX_FMTi__ "lli"
 // I386-NETBSD:#define __INTMAX_MAX__ 9223372036854775807LL
 // I386-NETBSD:#define __INTMAX_TYPE__ long long int
 // I386-NETBSD:#define __INTMAX_WIDTH__ 64
+// I386-NETBSD:#define __INTPTR_FMTd__ "d"
+// I386-NETBSD:#define __INTPTR_FMTi__ "i"
+// I386-NETBSD:#define __INTPTR_MAX__ 2147483647
 // I386-NETBSD:#define __INTPTR_TYPE__ int
 // I386-NETBSD:#define __INTPTR_WIDTH__ 32
+// I386-NETBSD:#define __INT_FAST16_FMTd__ "hd"
+// I386-NETBSD:#define __INT_FAST16_FMTi__ "hi"
+// I386-NETBSD:#define __INT_FAST16_MAX__ 32767
+// I386-NETBSD:#define __INT_FAST16_TYPE__ short
+// I386-NETBSD:#define __INT_FAST32_FMTd__ "d"
+// I386-NETBSD:#define __INT_FAST32_FMTi__ "i"
+// I386-NETBSD:#define __INT_FAST32_MAX__ 2147483647
+// I386-NETBSD:#define __INT_FAST32_TYPE__ int
+// I386-NETBSD:#define __INT_FAST64_FMTd__ "lld"
+// I386-NETBSD:#define __INT_FAST64_FMTi__ "lli"
+// I386-NETBSD:#define __INT_FAST64_MAX__ 9223372036854775807LL
+// I386-NETBSD:#define __INT_FAST64_TYPE__ long long int
+// I386-NETBSD:#define __INT_FAST8_FMTd__ "hhd"
+// I386-NETBSD:#define __INT_FAST8_FMTi__ "hhi"
+// I386-NETBSD:#define __INT_FAST8_MAX__ 127
+// I386-NETBSD:#define __INT_FAST8_TYPE__ signed char
+// I386-NETBSD:#define __INT_LEAST16_FMTd__ "hd"
+// I386-NETBSD:#define __INT_LEAST16_FMTi__ "hi"
+// I386-NETBSD:#define __INT_LEAST16_MAX__ 32767
+// I386-NETBSD:#define __INT_LEAST16_TYPE__ short
+// I386-NETBSD:#define __INT_LEAST32_FMTd__ "d"
+// I386-NETBSD:#define __INT_LEAST32_FMTi__ "i"
+// I386-NETBSD:#define __INT_LEAST32_MAX__ 2147483647
+// I386-NETBSD:#define __INT_LEAST32_TYPE__ int
+// I386-NETBSD:#define __INT_LEAST64_FMTd__ "lld"
+// I386-NETBSD:#define __INT_LEAST64_FMTi__ "lli"
+// I386-NETBSD:#define __INT_LEAST64_MAX__ 9223372036854775807LL
+// I386-NETBSD:#define __INT_LEAST64_TYPE__ long long int
+// I386-NETBSD:#define __INT_LEAST8_FMTd__ "hhd"
+// I386-NETBSD:#define __INT_LEAST8_FMTi__ "hhi"
+// I386-NETBSD:#define __INT_LEAST8_MAX__ 127
+// I386-NETBSD:#define __INT_LEAST8_TYPE__ signed char
 // I386-NETBSD:#define __INT_MAX__ 2147483647
 // I386-NETBSD:#define __LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L
 // I386-NETBSD:#define __LDBL_DIG__ 18
@@ -807,6 +2321,7 @@
 // I386-NETBSD:#define __REGISTER_PREFIX__ 
 // I386-NETBSD:#define __SCHAR_MAX__ 127
 // I386-NETBSD:#define __SHRT_MAX__ 32767
+// I386-NETBSD:#define __SIG_ATOMIC_MAX__ 2147483647
 // I386-NETBSD:#define __SIG_ATOMIC_WIDTH__ 32
 // I386-NETBSD:#define __SIZEOF_DOUBLE__ 8
 // I386-NETBSD:#define __SIZEOF_FLOAT__ 4
@@ -823,7 +2338,41 @@
 // I386-NETBSD:#define __SIZE_MAX__ 4294967295U
 // I386-NETBSD:#define __SIZE_TYPE__ unsigned int
 // I386-NETBSD:#define __SIZE_WIDTH__ 32
+// I386-NETBSD:#define __UINT16_C_SUFFIX__ {{$}}
+// I386-NETBSD:#define __UINT16_MAX__ 65535
+// I386-NETBSD:#define __UINT16_TYPE__ unsigned short
+// I386-NETBSD:#define __UINT32_C_SUFFIX__ U
+// I386-NETBSD:#define __UINT32_MAX__ 4294967295U
+// I386-NETBSD:#define __UINT32_TYPE__ unsigned int
+// I386-NETBSD:#define __UINT64_C_SUFFIX__ ULL
+// I386-NETBSD:#define __UINT64_MAX__ 18446744073709551615ULL
+// I386-NETBSD:#define __UINT64_TYPE__ long long unsigned int
+// I386-NETBSD:#define __UINT8_C_SUFFIX__ {{$}}
+// I386-NETBSD:#define __UINT8_MAX__ 255
+// I386-NETBSD:#define __UINT8_TYPE__ unsigned char
+// I386-NETBSD:#define __UINTMAX_C_SUFFIX__ ULL
+// I386-NETBSD:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // I386-NETBSD:#define __UINTMAX_TYPE__ long long unsigned int
+// I386-NETBSD:#define __UINTMAX_WIDTH__ 64
+// I386-NETBSD:#define __UINTPTR_MAX__ 4294967295U
+// I386-NETBSD:#define __UINTPTR_TYPE__ unsigned int
+// I386-NETBSD:#define __UINTPTR_WIDTH__ 32
+// I386-NETBSD:#define __UINT_FAST16_MAX__ 65535
+// I386-NETBSD:#define __UINT_FAST16_TYPE__ unsigned short
+// I386-NETBSD:#define __UINT_FAST32_MAX__ 4294967295U
+// I386-NETBSD:#define __UINT_FAST32_TYPE__ unsigned int
+// I386-NETBSD:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// I386-NETBSD:#define __UINT_FAST64_TYPE__ long long unsigned int
+// I386-NETBSD:#define __UINT_FAST8_MAX__ 255
+// I386-NETBSD:#define __UINT_FAST8_TYPE__ unsigned char
+// I386-NETBSD:#define __UINT_LEAST16_MAX__ 65535
+// I386-NETBSD:#define __UINT_LEAST16_TYPE__ unsigned short
+// I386-NETBSD:#define __UINT_LEAST32_MAX__ 4294967295U
+// I386-NETBSD:#define __UINT_LEAST32_TYPE__ unsigned int
+// I386-NETBSD:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// I386-NETBSD:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// I386-NETBSD:#define __UINT_LEAST8_MAX__ 255
+// I386-NETBSD:#define __UINT_LEAST8_TYPE__ unsigned char
 // I386-NETBSD:#define __USER_LABEL_PREFIX__
 // I386-NETBSD:#define __WCHAR_MAX__ 2147483647
 // I386-NETBSD:#define __WCHAR_TYPE__ int
@@ -848,13 +2397,14 @@
 // MIPS32BE:#define _ABIO32 1
 // MIPS32BE-NOT:#define _LP64
 // MIPS32BE:#define _MIPSEB 1
-// MIPS32BE:#define _MIPS_ARCH "mips32"
-// MIPS32BE:#define _MIPS_ARCH_MIPS32 1
+// MIPS32BE:#define _MIPS_ARCH "mips32r2"
+// MIPS32BE:#define _MIPS_ARCH_MIPS32R2 1
 // MIPS32BE:#define _MIPS_FPSET 16
 // MIPS32BE:#define _MIPS_SIM _ABIO32
 // MIPS32BE:#define _MIPS_SZINT 32
 // MIPS32BE:#define _MIPS_SZLONG 32
 // MIPS32BE:#define _MIPS_SZPTR 32
+// MIPS32BE:#define __BIG_ENDIAN__ 1
 // MIPS32BE:#define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__
 // MIPS32BE:#define __CHAR16_TYPE__ unsigned short
 // MIPS32BE:#define __CHAR32_TYPE__ unsigned int
@@ -889,16 +2439,69 @@
 // MIPS32BE:#define __FLT_MIN_EXP__ (-125)
 // MIPS32BE:#define __FLT_MIN__ 1.17549435e-38F
 // MIPS32BE:#define __FLT_RADIX__ 2
+// MIPS32BE:#define __INT16_C_SUFFIX__ {{$}}
+// MIPS32BE:#define __INT16_FMTd__ "hd"
+// MIPS32BE:#define __INT16_FMTi__ "hi"
+// MIPS32BE:#define __INT16_MAX__ 32767
 // MIPS32BE:#define __INT16_TYPE__ short
+// MIPS32BE:#define __INT32_C_SUFFIX__ {{$}}
+// MIPS32BE:#define __INT32_FMTd__ "d"
+// MIPS32BE:#define __INT32_FMTi__ "i"
+// MIPS32BE:#define __INT32_MAX__ 2147483647
 // MIPS32BE:#define __INT32_TYPE__ int
 // MIPS32BE:#define __INT64_C_SUFFIX__ LL
+// MIPS32BE:#define __INT64_FMTd__ "lld"
+// MIPS32BE:#define __INT64_FMTi__ "lli"
+// MIPS32BE:#define __INT64_MAX__ 9223372036854775807LL
 // MIPS32BE:#define __INT64_TYPE__ long long int
-// MIPS32BE:#define __INT8_TYPE__ char
+// MIPS32BE:#define __INT8_C_SUFFIX__ {{$}}
+// MIPS32BE:#define __INT8_FMTd__ "hhd"
+// MIPS32BE:#define __INT8_FMTi__ "hhi"
+// MIPS32BE:#define __INT8_MAX__ 127
+// MIPS32BE:#define __INT8_TYPE__ signed char
+// MIPS32BE:#define __INTMAX_C_SUFFIX__ LL
+// MIPS32BE:#define __INTMAX_FMTd__ "lld"
+// MIPS32BE:#define __INTMAX_FMTi__ "lli"
 // MIPS32BE:#define __INTMAX_MAX__ 9223372036854775807LL
 // MIPS32BE:#define __INTMAX_TYPE__ long long int
 // MIPS32BE:#define __INTMAX_WIDTH__ 64
+// MIPS32BE:#define __INTPTR_FMTd__ "ld"
+// MIPS32BE:#define __INTPTR_FMTi__ "li"
+// MIPS32BE:#define __INTPTR_MAX__ 2147483647L
 // MIPS32BE:#define __INTPTR_TYPE__ long int
 // MIPS32BE:#define __INTPTR_WIDTH__ 32
+// MIPS32BE:#define __INT_FAST16_FMTd__ "hd"
+// MIPS32BE:#define __INT_FAST16_FMTi__ "hi"
+// MIPS32BE:#define __INT_FAST16_MAX__ 32767
+// MIPS32BE:#define __INT_FAST16_TYPE__ short
+// MIPS32BE:#define __INT_FAST32_FMTd__ "d"
+// MIPS32BE:#define __INT_FAST32_FMTi__ "i"
+// MIPS32BE:#define __INT_FAST32_MAX__ 2147483647
+// MIPS32BE:#define __INT_FAST32_TYPE__ int
+// MIPS32BE:#define __INT_FAST64_FMTd__ "lld"
+// MIPS32BE:#define __INT_FAST64_FMTi__ "lli"
+// MIPS32BE:#define __INT_FAST64_MAX__ 9223372036854775807LL
+// MIPS32BE:#define __INT_FAST64_TYPE__ long long int
+// MIPS32BE:#define __INT_FAST8_FMTd__ "hhd"
+// MIPS32BE:#define __INT_FAST8_FMTi__ "hhi"
+// MIPS32BE:#define __INT_FAST8_MAX__ 127
+// MIPS32BE:#define __INT_FAST8_TYPE__ signed char
+// MIPS32BE:#define __INT_LEAST16_FMTd__ "hd"
+// MIPS32BE:#define __INT_LEAST16_FMTi__ "hi"
+// MIPS32BE:#define __INT_LEAST16_MAX__ 32767
+// MIPS32BE:#define __INT_LEAST16_TYPE__ short
+// MIPS32BE:#define __INT_LEAST32_FMTd__ "d"
+// MIPS32BE:#define __INT_LEAST32_FMTi__ "i"
+// MIPS32BE:#define __INT_LEAST32_MAX__ 2147483647
+// MIPS32BE:#define __INT_LEAST32_TYPE__ int
+// MIPS32BE:#define __INT_LEAST64_FMTd__ "lld"
+// MIPS32BE:#define __INT_LEAST64_FMTi__ "lli"
+// MIPS32BE:#define __INT_LEAST64_MAX__ 9223372036854775807LL
+// MIPS32BE:#define __INT_LEAST64_TYPE__ long long int
+// MIPS32BE:#define __INT_LEAST8_FMTd__ "hhd"
+// MIPS32BE:#define __INT_LEAST8_FMTi__ "hhi"
+// MIPS32BE:#define __INT_LEAST8_MAX__ 127
+// MIPS32BE:#define __INT_LEAST8_TYPE__ signed char
 // MIPS32BE:#define __INT_MAX__ 2147483647
 // MIPS32BE:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
 // MIPS32BE:#define __LDBL_DIG__ 15
@@ -925,6 +2528,7 @@
 // MIPS32BE:#define __REGISTER_PREFIX__ 
 // MIPS32BE:#define __SCHAR_MAX__ 127
 // MIPS32BE:#define __SHRT_MAX__ 32767
+// MIPS32BE:#define __SIG_ATOMIC_MAX__ 2147483647
 // MIPS32BE:#define __SIG_ATOMIC_WIDTH__ 32
 // MIPS32BE:#define __SIZEOF_DOUBLE__ 8
 // MIPS32BE:#define __SIZEOF_FLOAT__ 4
@@ -944,7 +2548,41 @@
 // MIPS32BE:#define __STDC_HOSTED__ 0
 // MIPS32BE:#define __STDC_VERSION__ 199901L
 // MIPS32BE:#define __STDC__ 1
+// MIPS32BE:#define __UINT16_C_SUFFIX__ {{$}}
+// MIPS32BE:#define __UINT16_MAX__ 65535
+// MIPS32BE:#define __UINT16_TYPE__ unsigned short
+// MIPS32BE:#define __UINT32_C_SUFFIX__ U
+// MIPS32BE:#define __UINT32_MAX__ 4294967295U
+// MIPS32BE:#define __UINT32_TYPE__ unsigned int
+// MIPS32BE:#define __UINT64_C_SUFFIX__ ULL
+// MIPS32BE:#define __UINT64_MAX__ 18446744073709551615ULL
+// MIPS32BE:#define __UINT64_TYPE__ long long unsigned int
+// MIPS32BE:#define __UINT8_C_SUFFIX__ {{$}}
+// MIPS32BE:#define __UINT8_MAX__ 255
+// MIPS32BE:#define __UINT8_TYPE__ unsigned char
+// MIPS32BE:#define __UINTMAX_C_SUFFIX__ ULL
+// MIPS32BE:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // MIPS32BE:#define __UINTMAX_TYPE__ long long unsigned int
+// MIPS32BE:#define __UINTMAX_WIDTH__ 64
+// MIPS32BE:#define __UINTPTR_MAX__ 4294967295U
+// MIPS32BE:#define __UINTPTR_TYPE__ long unsigned int
+// MIPS32BE:#define __UINTPTR_WIDTH__ 32
+// MIPS32BE:#define __UINT_FAST16_MAX__ 65535
+// MIPS32BE:#define __UINT_FAST16_TYPE__ unsigned short
+// MIPS32BE:#define __UINT_FAST32_MAX__ 4294967295U
+// MIPS32BE:#define __UINT_FAST32_TYPE__ unsigned int
+// MIPS32BE:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// MIPS32BE:#define __UINT_FAST64_TYPE__ long long unsigned int
+// MIPS32BE:#define __UINT_FAST8_MAX__ 255
+// MIPS32BE:#define __UINT_FAST8_TYPE__ unsigned char
+// MIPS32BE:#define __UINT_LEAST16_MAX__ 65535
+// MIPS32BE:#define __UINT_LEAST16_TYPE__ unsigned short
+// MIPS32BE:#define __UINT_LEAST32_MAX__ 4294967295U
+// MIPS32BE:#define __UINT_LEAST32_TYPE__ unsigned int
+// MIPS32BE:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// MIPS32BE:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// MIPS32BE:#define __UINT_LEAST8_MAX__ 255
+// MIPS32BE:#define __UINT_LEAST8_TYPE__ unsigned char
 // MIPS32BE:#define __USER_LABEL_PREFIX__ _
 // MIPS32BE:#define __WCHAR_MAX__ 2147483647
 // MIPS32BE:#define __WCHAR_TYPE__ int
@@ -953,7 +2591,7 @@
 // MIPS32BE:#define __WINT_WIDTH__ 32
 // MIPS32BE:#define __clang__ 1
 // MIPS32BE:#define __llvm__ 1
-// MIPS32BE:#define __mips 1
+// MIPS32BE:#define __mips 32
 // MIPS32BE:#define __mips__ 1
 // MIPS32BE:#define __mips_fpr 32
 // MIPS32BE:#define __mips_hard_float 1
@@ -967,8 +2605,8 @@
 // MIPS32EL:#define _ABIO32 1
 // MIPS32EL-NOT:#define _LP64
 // MIPS32EL:#define _MIPSEL 1
-// MIPS32EL:#define _MIPS_ARCH "mips32"
-// MIPS32EL:#define _MIPS_ARCH_MIPS32 1
+// MIPS32EL:#define _MIPS_ARCH "mips32r2"
+// MIPS32EL:#define _MIPS_ARCH_MIPS32R2 1
 // MIPS32EL:#define _MIPS_FPSET 16
 // MIPS32EL:#define _MIPS_SIM _ABIO32
 // MIPS32EL:#define _MIPS_SZINT 32
@@ -1008,16 +2646,69 @@
 // MIPS32EL:#define __FLT_MIN_EXP__ (-125)
 // MIPS32EL:#define __FLT_MIN__ 1.17549435e-38F
 // MIPS32EL:#define __FLT_RADIX__ 2
+// MIPS32EL:#define __INT16_C_SUFFIX__ {{$}}
+// MIPS32EL:#define __INT16_FMTd__ "hd"
+// MIPS32EL:#define __INT16_FMTi__ "hi"
+// MIPS32EL:#define __INT16_MAX__ 32767
 // MIPS32EL:#define __INT16_TYPE__ short
+// MIPS32EL:#define __INT32_C_SUFFIX__ {{$}}
+// MIPS32EL:#define __INT32_FMTd__ "d"
+// MIPS32EL:#define __INT32_FMTi__ "i"
+// MIPS32EL:#define __INT32_MAX__ 2147483647
 // MIPS32EL:#define __INT32_TYPE__ int
 // MIPS32EL:#define __INT64_C_SUFFIX__ LL
+// MIPS32EL:#define __INT64_FMTd__ "lld"
+// MIPS32EL:#define __INT64_FMTi__ "lli"
+// MIPS32EL:#define __INT64_MAX__ 9223372036854775807LL
 // MIPS32EL:#define __INT64_TYPE__ long long int
-// MIPS32EL:#define __INT8_TYPE__ char
+// MIPS32EL:#define __INT8_C_SUFFIX__ {{$}}
+// MIPS32EL:#define __INT8_FMTd__ "hhd"
+// MIPS32EL:#define __INT8_FMTi__ "hhi"
+// MIPS32EL:#define __INT8_MAX__ 127
+// MIPS32EL:#define __INT8_TYPE__ signed char
+// MIPS32EL:#define __INTMAX_C_SUFFIX__ LL
+// MIPS32EL:#define __INTMAX_FMTd__ "lld"
+// MIPS32EL:#define __INTMAX_FMTi__ "lli"
 // MIPS32EL:#define __INTMAX_MAX__ 9223372036854775807LL
 // MIPS32EL:#define __INTMAX_TYPE__ long long int
 // MIPS32EL:#define __INTMAX_WIDTH__ 64
+// MIPS32EL:#define __INTPTR_FMTd__ "ld"
+// MIPS32EL:#define __INTPTR_FMTi__ "li"
+// MIPS32EL:#define __INTPTR_MAX__ 2147483647L
 // MIPS32EL:#define __INTPTR_TYPE__ long int
 // MIPS32EL:#define __INTPTR_WIDTH__ 32
+// MIPS32EL:#define __INT_FAST16_FMTd__ "hd"
+// MIPS32EL:#define __INT_FAST16_FMTi__ "hi"
+// MIPS32EL:#define __INT_FAST16_MAX__ 32767
+// MIPS32EL:#define __INT_FAST16_TYPE__ short
+// MIPS32EL:#define __INT_FAST32_FMTd__ "d"
+// MIPS32EL:#define __INT_FAST32_FMTi__ "i"
+// MIPS32EL:#define __INT_FAST32_MAX__ 2147483647
+// MIPS32EL:#define __INT_FAST32_TYPE__ int
+// MIPS32EL:#define __INT_FAST64_FMTd__ "lld"
+// MIPS32EL:#define __INT_FAST64_FMTi__ "lli"
+// MIPS32EL:#define __INT_FAST64_MAX__ 9223372036854775807LL
+// MIPS32EL:#define __INT_FAST64_TYPE__ long long int
+// MIPS32EL:#define __INT_FAST8_FMTd__ "hhd"
+// MIPS32EL:#define __INT_FAST8_FMTi__ "hhi"
+// MIPS32EL:#define __INT_FAST8_MAX__ 127
+// MIPS32EL:#define __INT_FAST8_TYPE__ signed char
+// MIPS32EL:#define __INT_LEAST16_FMTd__ "hd"
+// MIPS32EL:#define __INT_LEAST16_FMTi__ "hi"
+// MIPS32EL:#define __INT_LEAST16_MAX__ 32767
+// MIPS32EL:#define __INT_LEAST16_TYPE__ short
+// MIPS32EL:#define __INT_LEAST32_FMTd__ "d"
+// MIPS32EL:#define __INT_LEAST32_FMTi__ "i"
+// MIPS32EL:#define __INT_LEAST32_MAX__ 2147483647
+// MIPS32EL:#define __INT_LEAST32_TYPE__ int
+// MIPS32EL:#define __INT_LEAST64_FMTd__ "lld"
+// MIPS32EL:#define __INT_LEAST64_FMTi__ "lli"
+// MIPS32EL:#define __INT_LEAST64_MAX__ 9223372036854775807LL
+// MIPS32EL:#define __INT_LEAST64_TYPE__ long long int
+// MIPS32EL:#define __INT_LEAST8_FMTd__ "hhd"
+// MIPS32EL:#define __INT_LEAST8_FMTi__ "hhi"
+// MIPS32EL:#define __INT_LEAST8_MAX__ 127
+// MIPS32EL:#define __INT_LEAST8_TYPE__ signed char
 // MIPS32EL:#define __INT_MAX__ 2147483647
 // MIPS32EL:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
 // MIPS32EL:#define __LDBL_DIG__ 15
@@ -1032,6 +2723,7 @@
 // MIPS32EL:#define __LDBL_MIN_10_EXP__ (-307)
 // MIPS32EL:#define __LDBL_MIN_EXP__ (-1021)
 // MIPS32EL:#define __LDBL_MIN__ 2.2250738585072014e-308L
+// MIPS32EL:#define __LITTLE_ENDIAN__ 1
 // MIPS32EL:#define __LONG_LONG_MAX__ 9223372036854775807LL
 // MIPS32EL:#define __LONG_MAX__ 2147483647L
 // MIPS32EL-NOT:#define __LP64__
@@ -1044,6 +2736,7 @@
 // MIPS32EL:#define __REGISTER_PREFIX__ 
 // MIPS32EL:#define __SCHAR_MAX__ 127
 // MIPS32EL:#define __SHRT_MAX__ 32767
+// MIPS32EL:#define __SIG_ATOMIC_MAX__ 2147483647
 // MIPS32EL:#define __SIG_ATOMIC_WIDTH__ 32
 // MIPS32EL:#define __SIZEOF_DOUBLE__ 8
 // MIPS32EL:#define __SIZEOF_FLOAT__ 4
@@ -1060,7 +2753,41 @@
 // MIPS32EL:#define __SIZE_MAX__ 4294967295U
 // MIPS32EL:#define __SIZE_TYPE__ unsigned int
 // MIPS32EL:#define __SIZE_WIDTH__ 32
+// MIPS32EL:#define __UINT16_C_SUFFIX__ {{$}}
+// MIPS32EL:#define __UINT16_MAX__ 65535
+// MIPS32EL:#define __UINT16_TYPE__ unsigned short
+// MIPS32EL:#define __UINT32_C_SUFFIX__ U
+// MIPS32EL:#define __UINT32_MAX__ 4294967295U
+// MIPS32EL:#define __UINT32_TYPE__ unsigned int
+// MIPS32EL:#define __UINT64_C_SUFFIX__ ULL
+// MIPS32EL:#define __UINT64_MAX__ 18446744073709551615ULL
+// MIPS32EL:#define __UINT64_TYPE__ long long unsigned int
+// MIPS32EL:#define __UINT8_C_SUFFIX__ {{$}}
+// MIPS32EL:#define __UINT8_MAX__ 255
+// MIPS32EL:#define __UINT8_TYPE__ unsigned char
+// MIPS32EL:#define __UINTMAX_C_SUFFIX__ ULL
+// MIPS32EL:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // MIPS32EL:#define __UINTMAX_TYPE__ long long unsigned int
+// MIPS32EL:#define __UINTMAX_WIDTH__ 64
+// MIPS32EL:#define __UINTPTR_MAX__ 4294967295U
+// MIPS32EL:#define __UINTPTR_TYPE__ long unsigned int
+// MIPS32EL:#define __UINTPTR_WIDTH__ 32
+// MIPS32EL:#define __UINT_FAST16_MAX__ 65535
+// MIPS32EL:#define __UINT_FAST16_TYPE__ unsigned short
+// MIPS32EL:#define __UINT_FAST32_MAX__ 4294967295U
+// MIPS32EL:#define __UINT_FAST32_TYPE__ unsigned int
+// MIPS32EL:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// MIPS32EL:#define __UINT_FAST64_TYPE__ long long unsigned int
+// MIPS32EL:#define __UINT_FAST8_MAX__ 255
+// MIPS32EL:#define __UINT_FAST8_TYPE__ unsigned char
+// MIPS32EL:#define __UINT_LEAST16_MAX__ 65535
+// MIPS32EL:#define __UINT_LEAST16_TYPE__ unsigned short
+// MIPS32EL:#define __UINT_LEAST32_MAX__ 4294967295U
+// MIPS32EL:#define __UINT_LEAST32_TYPE__ unsigned int
+// MIPS32EL:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// MIPS32EL:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// MIPS32EL:#define __UINT_LEAST8_MAX__ 255
+// MIPS32EL:#define __UINT_LEAST8_TYPE__ unsigned char
 // MIPS32EL:#define __USER_LABEL_PREFIX__ _
 // MIPS32EL:#define __WCHAR_MAX__ 2147483647
 // MIPS32EL:#define __WCHAR_TYPE__ int
@@ -1069,7 +2796,7 @@
 // MIPS32EL:#define __WINT_WIDTH__ 32
 // MIPS32EL:#define __clang__ 1
 // MIPS32EL:#define __llvm__ 1
-// MIPS32EL:#define __mips 1
+// MIPS32EL:#define __mips 32
 // MIPS32EL:#define __mips__ 1
 // MIPS32EL:#define __mips_fpr 32
 // MIPS32EL:#define __mips_hard_float 1
@@ -1083,13 +2810,14 @@
 // MIPS64BE:#define _ABI64 3
 // MIPS64BE:#define _LP64 1
 // MIPS64BE:#define _MIPSEB 1
-// MIPS64BE:#define _MIPS_ARCH "mips64"
-// MIPS64BE:#define _MIPS_ARCH_MIPS64 1
+// MIPS64BE:#define _MIPS_ARCH "mips64r2"
+// MIPS64BE:#define _MIPS_ARCH_MIPS64R2 1
 // MIPS64BE:#define _MIPS_FPSET 32
 // MIPS64BE:#define _MIPS_SIM _ABI64
 // MIPS64BE:#define _MIPS_SZINT 32
 // MIPS64BE:#define _MIPS_SZLONG 64
 // MIPS64BE:#define _MIPS_SZPTR 64
+// MIPS64BE:#define __BIG_ENDIAN__ 1
 // MIPS64BE:#define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__
 // MIPS64BE:#define __CHAR16_TYPE__ unsigned short
 // MIPS64BE:#define __CHAR32_TYPE__ unsigned int
@@ -1124,16 +2852,69 @@
 // MIPS64BE:#define __FLT_MIN_EXP__ (-125)
 // MIPS64BE:#define __FLT_MIN__ 1.17549435e-38F
 // MIPS64BE:#define __FLT_RADIX__ 2
+// MIPS64BE:#define __INT16_C_SUFFIX__ {{$}}
+// MIPS64BE:#define __INT16_FMTd__ "hd"
+// MIPS64BE:#define __INT16_FMTi__ "hi"
+// MIPS64BE:#define __INT16_MAX__ 32767
 // MIPS64BE:#define __INT16_TYPE__ short
+// MIPS64BE:#define __INT32_C_SUFFIX__ {{$}}
+// MIPS64BE:#define __INT32_FMTd__ "d"
+// MIPS64BE:#define __INT32_FMTi__ "i"
+// MIPS64BE:#define __INT32_MAX__ 2147483647
 // MIPS64BE:#define __INT32_TYPE__ int
 // MIPS64BE:#define __INT64_C_SUFFIX__ LL
+// MIPS64BE:#define __INT64_FMTd__ "lld"
+// MIPS64BE:#define __INT64_FMTi__ "lli"
+// MIPS64BE:#define __INT64_MAX__ 9223372036854775807L
 // MIPS64BE:#define __INT64_TYPE__ long long int
-// MIPS64BE:#define __INT8_TYPE__ char
+// MIPS64BE:#define __INT8_C_SUFFIX__ {{$}}
+// MIPS64BE:#define __INT8_FMTd__ "hhd"
+// MIPS64BE:#define __INT8_FMTi__ "hhi"
+// MIPS64BE:#define __INT8_MAX__ 127
+// MIPS64BE:#define __INT8_TYPE__ signed char
+// MIPS64BE:#define __INTMAX_C_SUFFIX__ LL
+// MIPS64BE:#define __INTMAX_FMTd__ "lld"
+// MIPS64BE:#define __INTMAX_FMTi__ "lli"
 // MIPS64BE:#define __INTMAX_MAX__ 9223372036854775807LL
 // MIPS64BE:#define __INTMAX_TYPE__ long long int
 // MIPS64BE:#define __INTMAX_WIDTH__ 64
+// MIPS64BE:#define __INTPTR_FMTd__ "ld"
+// MIPS64BE:#define __INTPTR_FMTi__ "li"
+// MIPS64BE:#define __INTPTR_MAX__ 9223372036854775807L
 // MIPS64BE:#define __INTPTR_TYPE__ long int
 // MIPS64BE:#define __INTPTR_WIDTH__ 64
+// MIPS64BE:#define __INT_FAST16_FMTd__ "hd"
+// MIPS64BE:#define __INT_FAST16_FMTi__ "hi"
+// MIPS64BE:#define __INT_FAST16_MAX__ 32767
+// MIPS64BE:#define __INT_FAST16_TYPE__ short
+// MIPS64BE:#define __INT_FAST32_FMTd__ "d"
+// MIPS64BE:#define __INT_FAST32_FMTi__ "i"
+// MIPS64BE:#define __INT_FAST32_MAX__ 2147483647
+// MIPS64BE:#define __INT_FAST32_TYPE__ int
+// MIPS64BE:#define __INT_FAST64_FMTd__ "ld"
+// MIPS64BE:#define __INT_FAST64_FMTi__ "li"
+// MIPS64BE:#define __INT_FAST64_MAX__ 9223372036854775807L
+// MIPS64BE:#define __INT_FAST64_TYPE__ long int
+// MIPS64BE:#define __INT_FAST8_FMTd__ "hhd"
+// MIPS64BE:#define __INT_FAST8_FMTi__ "hhi"
+// MIPS64BE:#define __INT_FAST8_MAX__ 127
+// MIPS64BE:#define __INT_FAST8_TYPE__ signed char
+// MIPS64BE:#define __INT_LEAST16_FMTd__ "hd"
+// MIPS64BE:#define __INT_LEAST16_FMTi__ "hi"
+// MIPS64BE:#define __INT_LEAST16_MAX__ 32767
+// MIPS64BE:#define __INT_LEAST16_TYPE__ short
+// MIPS64BE:#define __INT_LEAST32_FMTd__ "d"
+// MIPS64BE:#define __INT_LEAST32_FMTi__ "i"
+// MIPS64BE:#define __INT_LEAST32_MAX__ 2147483647
+// MIPS64BE:#define __INT_LEAST32_TYPE__ int
+// MIPS64BE:#define __INT_LEAST64_FMTd__ "ld"
+// MIPS64BE:#define __INT_LEAST64_FMTi__ "li"
+// MIPS64BE:#define __INT_LEAST64_MAX__ 9223372036854775807L
+// MIPS64BE:#define __INT_LEAST64_TYPE__ long int
+// MIPS64BE:#define __INT_LEAST8_FMTd__ "hhd"
+// MIPS64BE:#define __INT_LEAST8_FMTi__ "hhi"
+// MIPS64BE:#define __INT_LEAST8_MAX__ 127
+// MIPS64BE:#define __INT_LEAST8_TYPE__ signed char
 // MIPS64BE:#define __INT_MAX__ 2147483647
 // MIPS64BE:#define __LDBL_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966L
 // MIPS64BE:#define __LDBL_DIG__ 33
@@ -1160,6 +2941,7 @@
 // MIPS64BE:#define __REGISTER_PREFIX__ 
 // MIPS64BE:#define __SCHAR_MAX__ 127
 // MIPS64BE:#define __SHRT_MAX__ 32767
+// MIPS64BE:#define __SIG_ATOMIC_MAX__ 2147483647
 // MIPS64BE:#define __SIG_ATOMIC_WIDTH__ 32
 // MIPS64BE:#define __SIZEOF_DOUBLE__ 8
 // MIPS64BE:#define __SIZEOF_FLOAT__ 4
@@ -1176,7 +2958,41 @@
 // MIPS64BE:#define __SIZE_MAX__ 18446744073709551615UL
 // MIPS64BE:#define __SIZE_TYPE__ long unsigned int
 // MIPS64BE:#define __SIZE_WIDTH__ 64
+// MIPS64BE:#define __UINT16_C_SUFFIX__ {{$}}
+// MIPS64BE:#define __UINT16_MAX__ 65535
+// MIPS64BE:#define __UINT16_TYPE__ unsigned short
+// MIPS64BE:#define __UINT32_C_SUFFIX__ U
+// MIPS64BE:#define __UINT32_MAX__ 4294967295U
+// MIPS64BE:#define __UINT32_TYPE__ unsigned int
+// MIPS64BE:#define __UINT64_C_SUFFIX__ ULL
+// MIPS64BE:#define __UINT64_MAX__ 18446744073709551615ULL
+// MIPS64BE:#define __UINT64_TYPE__ long long unsigned int
+// MIPS64BE:#define __UINT8_C_SUFFIX__ {{$}}
+// MIPS64BE:#define __UINT8_MAX__ 255
+// MIPS64BE:#define __UINT8_TYPE__ unsigned char
+// MIPS64BE:#define __UINTMAX_C_SUFFIX__ ULL
+// MIPS64BE:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // MIPS64BE:#define __UINTMAX_TYPE__ long long unsigned int
+// MIPS64BE:#define __UINTMAX_WIDTH__ 64
+// MIPS64BE:#define __UINTPTR_MAX__ 18446744073709551615UL
+// MIPS64BE:#define __UINTPTR_TYPE__ long unsigned int
+// MIPS64BE:#define __UINTPTR_WIDTH__ 64
+// MIPS64BE:#define __UINT_FAST16_MAX__ 65535
+// MIPS64BE:#define __UINT_FAST16_TYPE__ unsigned short
+// MIPS64BE:#define __UINT_FAST32_MAX__ 4294967295U
+// MIPS64BE:#define __UINT_FAST32_TYPE__ unsigned int
+// MIPS64BE:#define __UINT_FAST64_MAX__ 18446744073709551615UL
+// MIPS64BE:#define __UINT_FAST64_TYPE__ long unsigned int
+// MIPS64BE:#define __UINT_FAST8_MAX__ 255
+// MIPS64BE:#define __UINT_FAST8_TYPE__ unsigned char
+// MIPS64BE:#define __UINT_LEAST16_MAX__ 65535
+// MIPS64BE:#define __UINT_LEAST16_TYPE__ unsigned short
+// MIPS64BE:#define __UINT_LEAST32_MAX__ 4294967295U
+// MIPS64BE:#define __UINT_LEAST32_TYPE__ unsigned int
+// MIPS64BE:#define __UINT_LEAST64_MAX__ 18446744073709551615UL
+// MIPS64BE:#define __UINT_LEAST64_TYPE__ long unsigned int
+// MIPS64BE:#define __UINT_LEAST8_MAX__ 255
+// MIPS64BE:#define __UINT_LEAST8_TYPE__ unsigned char
 // MIPS64BE:#define __USER_LABEL_PREFIX__ _
 // MIPS64BE:#define __WCHAR_MAX__ 2147483647
 // MIPS64BE:#define __WCHAR_TYPE__ int
@@ -1185,7 +3001,7 @@
 // MIPS64BE:#define __WINT_WIDTH__ 32
 // MIPS64BE:#define __clang__ 1
 // MIPS64BE:#define __llvm__ 1
-// MIPS64BE:#define __mips 1
+// MIPS64BE:#define __mips 64
 // MIPS64BE:#define __mips64 1
 // MIPS64BE:#define __mips64__ 1
 // MIPS64BE:#define __mips__ 1
@@ -1201,8 +3017,8 @@
 // MIPS64EL:#define _ABI64 3
 // MIPS64EL:#define _LP64 1
 // MIPS64EL:#define _MIPSEL 1
-// MIPS64EL:#define _MIPS_ARCH "mips64"
-// MIPS64EL:#define _MIPS_ARCH_MIPS64 1
+// MIPS64EL:#define _MIPS_ARCH "mips64r2"
+// MIPS64EL:#define _MIPS_ARCH_MIPS64R2 1
 // MIPS64EL:#define _MIPS_FPSET 32
 // MIPS64EL:#define _MIPS_SIM _ABI64
 // MIPS64EL:#define _MIPS_SZINT 32
@@ -1242,16 +3058,69 @@
 // MIPS64EL:#define __FLT_MIN_EXP__ (-125)
 // MIPS64EL:#define __FLT_MIN__ 1.17549435e-38F
 // MIPS64EL:#define __FLT_RADIX__ 2
+// MIPS64EL:#define __INT16_C_SUFFIX__ {{$}}
+// MIPS64EL:#define __INT16_FMTd__ "hd"
+// MIPS64EL:#define __INT16_FMTi__ "hi"
+// MIPS64EL:#define __INT16_MAX__ 32767
 // MIPS64EL:#define __INT16_TYPE__ short
+// MIPS64EL:#define __INT32_C_SUFFIX__ {{$}}
+// MIPS64EL:#define __INT32_FMTd__ "d"
+// MIPS64EL:#define __INT32_FMTi__ "i"
+// MIPS64EL:#define __INT32_MAX__ 2147483647
 // MIPS64EL:#define __INT32_TYPE__ int
 // MIPS64EL:#define __INT64_C_SUFFIX__ LL
+// MIPS64EL:#define __INT64_FMTd__ "lld"
+// MIPS64EL:#define __INT64_FMTi__ "lli"
+// MIPS64EL:#define __INT64_MAX__ 9223372036854775807L
 // MIPS64EL:#define __INT64_TYPE__ long long int
-// MIPS64EL:#define __INT8_TYPE__ char
+// MIPS64EL:#define __INT8_C_SUFFIX__ {{$}}
+// MIPS64EL:#define __INT8_FMTd__ "hhd"
+// MIPS64EL:#define __INT8_FMTi__ "hhi"
+// MIPS64EL:#define __INT8_MAX__ 127
+// MIPS64EL:#define __INT8_TYPE__ signed char
+// MIPS64EL:#define __INTMAX_C_SUFFIX__ LL
+// MIPS64EL:#define __INTMAX_FMTd__ "lld"
+// MIPS64EL:#define __INTMAX_FMTi__ "lli"
 // MIPS64EL:#define __INTMAX_MAX__ 9223372036854775807LL
 // MIPS64EL:#define __INTMAX_TYPE__ long long int
 // MIPS64EL:#define __INTMAX_WIDTH__ 64
+// MIPS64EL:#define __INTPTR_FMTd__ "ld"
+// MIPS64EL:#define __INTPTR_FMTi__ "li"
+// MIPS64EL:#define __INTPTR_MAX__ 9223372036854775807L
 // MIPS64EL:#define __INTPTR_TYPE__ long int
 // MIPS64EL:#define __INTPTR_WIDTH__ 64
+// MIPS64EL:#define __INT_FAST16_FMTd__ "hd"
+// MIPS64EL:#define __INT_FAST16_FMTi__ "hi"
+// MIPS64EL:#define __INT_FAST16_MAX__ 32767
+// MIPS64EL:#define __INT_FAST16_TYPE__ short
+// MIPS64EL:#define __INT_FAST32_FMTd__ "d"
+// MIPS64EL:#define __INT_FAST32_FMTi__ "i"
+// MIPS64EL:#define __INT_FAST32_MAX__ 2147483647
+// MIPS64EL:#define __INT_FAST32_TYPE__ int
+// MIPS64EL:#define __INT_FAST64_FMTd__ "ld"
+// MIPS64EL:#define __INT_FAST64_FMTi__ "li"
+// MIPS64EL:#define __INT_FAST64_MAX__ 9223372036854775807L
+// MIPS64EL:#define __INT_FAST64_TYPE__ long int
+// MIPS64EL:#define __INT_FAST8_FMTd__ "hhd"
+// MIPS64EL:#define __INT_FAST8_FMTi__ "hhi"
+// MIPS64EL:#define __INT_FAST8_MAX__ 127
+// MIPS64EL:#define __INT_FAST8_TYPE__ signed char
+// MIPS64EL:#define __INT_LEAST16_FMTd__ "hd"
+// MIPS64EL:#define __INT_LEAST16_FMTi__ "hi"
+// MIPS64EL:#define __INT_LEAST16_MAX__ 32767
+// MIPS64EL:#define __INT_LEAST16_TYPE__ short
+// MIPS64EL:#define __INT_LEAST32_FMTd__ "d"
+// MIPS64EL:#define __INT_LEAST32_FMTi__ "i"
+// MIPS64EL:#define __INT_LEAST32_MAX__ 2147483647
+// MIPS64EL:#define __INT_LEAST32_TYPE__ int
+// MIPS64EL:#define __INT_LEAST64_FMTd__ "ld"
+// MIPS64EL:#define __INT_LEAST64_FMTi__ "li"
+// MIPS64EL:#define __INT_LEAST64_MAX__ 9223372036854775807L
+// MIPS64EL:#define __INT_LEAST64_TYPE__ long int
+// MIPS64EL:#define __INT_LEAST8_FMTd__ "hhd"
+// MIPS64EL:#define __INT_LEAST8_FMTi__ "hhi"
+// MIPS64EL:#define __INT_LEAST8_MAX__ 127
+// MIPS64EL:#define __INT_LEAST8_TYPE__ signed char
 // MIPS64EL:#define __INT_MAX__ 2147483647
 // MIPS64EL:#define __LDBL_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966L
 // MIPS64EL:#define __LDBL_DIG__ 33
@@ -1266,6 +3135,7 @@
 // MIPS64EL:#define __LDBL_MIN_10_EXP__ (-4931)
 // MIPS64EL:#define __LDBL_MIN_EXP__ (-16381)
 // MIPS64EL:#define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L
+// MIPS64EL:#define __LITTLE_ENDIAN__ 1
 // MIPS64EL:#define __LONG_LONG_MAX__ 9223372036854775807LL
 // MIPS64EL:#define __LONG_MAX__ 9223372036854775807L
 // MIPS64EL:#define __LP64__ 1
@@ -1278,6 +3148,7 @@
 // MIPS64EL:#define __REGISTER_PREFIX__ 
 // MIPS64EL:#define __SCHAR_MAX__ 127
 // MIPS64EL:#define __SHRT_MAX__ 32767
+// MIPS64EL:#define __SIG_ATOMIC_MAX__ 2147483647
 // MIPS64EL:#define __SIG_ATOMIC_WIDTH__ 32
 // MIPS64EL:#define __SIZEOF_DOUBLE__ 8
 // MIPS64EL:#define __SIZEOF_FLOAT__ 4
@@ -1294,7 +3165,41 @@
 // MIPS64EL:#define __SIZE_MAX__ 18446744073709551615UL
 // MIPS64EL:#define __SIZE_TYPE__ long unsigned int
 // MIPS64EL:#define __SIZE_WIDTH__ 64
+// MIPS64EL:#define __UINT16_C_SUFFIX__ {{$}}
+// MIPS64EL:#define __UINT16_MAX__ 65535
+// MIPS64EL:#define __UINT16_TYPE__ unsigned short
+// MIPS64EL:#define __UINT32_C_SUFFIX__ U
+// MIPS64EL:#define __UINT32_MAX__ 4294967295U
+// MIPS64EL:#define __UINT32_TYPE__ unsigned int
+// MIPS64EL:#define __UINT64_C_SUFFIX__ ULL
+// MIPS64EL:#define __UINT64_MAX__ 18446744073709551615ULL
+// MIPS64EL:#define __UINT64_TYPE__ long long unsigned int
+// MIPS64EL:#define __UINT8_C_SUFFIX__ {{$}}
+// MIPS64EL:#define __UINT8_MAX__ 255
+// MIPS64EL:#define __UINT8_TYPE__ unsigned char
+// MIPS64EL:#define __UINTMAX_C_SUFFIX__ ULL
+// MIPS64EL:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // MIPS64EL:#define __UINTMAX_TYPE__ long long unsigned int
+// MIPS64EL:#define __UINTMAX_WIDTH__ 64
+// MIPS64EL:#define __UINTPTR_MAX__ 18446744073709551615UL
+// MIPS64EL:#define __UINTPTR_TYPE__ long unsigned int
+// MIPS64EL:#define __UINTPTR_WIDTH__ 64
+// MIPS64EL:#define __UINT_FAST16_MAX__ 65535
+// MIPS64EL:#define __UINT_FAST16_TYPE__ unsigned short
+// MIPS64EL:#define __UINT_FAST32_MAX__ 4294967295U
+// MIPS64EL:#define __UINT_FAST32_TYPE__ unsigned int
+// MIPS64EL:#define __UINT_FAST64_MAX__ 18446744073709551615UL
+// MIPS64EL:#define __UINT_FAST64_TYPE__ long unsigned int
+// MIPS64EL:#define __UINT_FAST8_MAX__ 255
+// MIPS64EL:#define __UINT_FAST8_TYPE__ unsigned char
+// MIPS64EL:#define __UINT_LEAST16_MAX__ 65535
+// MIPS64EL:#define __UINT_LEAST16_TYPE__ unsigned short
+// MIPS64EL:#define __UINT_LEAST32_MAX__ 4294967295U
+// MIPS64EL:#define __UINT_LEAST32_TYPE__ unsigned int
+// MIPS64EL:#define __UINT_LEAST64_MAX__ 18446744073709551615UL
+// MIPS64EL:#define __UINT_LEAST64_TYPE__ long unsigned int
+// MIPS64EL:#define __UINT_LEAST8_MAX__ 255
+// MIPS64EL:#define __UINT_LEAST8_TYPE__ unsigned char
 // MIPS64EL:#define __USER_LABEL_PREFIX__ _
 // MIPS64EL:#define __WCHAR_MAX__ 2147483647
 // MIPS64EL:#define __WCHAR_TYPE__ int
@@ -1303,7 +3208,7 @@
 // MIPS64EL:#define __WINT_WIDTH__ 32
 // MIPS64EL:#define __clang__ 1
 // MIPS64EL:#define __llvm__ 1
-// MIPS64EL:#define __mips 1
+// MIPS64EL:#define __mips 64
 // MIPS64EL:#define __mips64 1
 // MIPS64EL:#define __mips64__ 1
 // MIPS64EL:#define __mips__ 1
@@ -1313,6 +3218,62 @@
 // MIPS64EL:#define _mips 1
 // MIPS64EL:#define mips 1
 //
+// Check MIPS arch and isa macros
+//
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=mips-none-none \
+// RUN:            < /dev/null \
+// RUN:   | FileCheck -check-prefix MIPS-ARCH-DEF32 %s
+//
+// MIPS-ARCH-DEF32:#define _MIPS_ARCH "mips32r2"
+// MIPS-ARCH-DEF32:#define _MIPS_ARCH_MIPS32R2 1
+// MIPS-ARCH-DEF32:#define _MIPS_ISA _MIPS_ISA_MIPS32
+// MIPS-ARCH-DEF32:#define __mips_isa_rev 2
+//
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=mips-none-nones \
+// RUN:            -target-cpu mips32 < /dev/null \
+// RUN:   | FileCheck -check-prefix MIPS-ARCH-32 %s
+//
+// MIPS-ARCH-32:#define _MIPS_ARCH "mips32"
+// MIPS-ARCH-32:#define _MIPS_ARCH_MIPS32 1
+// MIPS-ARCH-32:#define _MIPS_ISA _MIPS_ISA_MIPS32
+// MIPS-ARCH-32:#define __mips_isa_rev 1
+//
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=mips-none-none \
+// RUN:            -target-cpu mips32r2 < /dev/null \
+// RUN:   | FileCheck -check-prefix MIPS-ARCH-32R2 %s
+//
+// MIPS-ARCH-32R2:#define _MIPS_ARCH "mips32r2"
+// MIPS-ARCH-32R2:#define _MIPS_ARCH_MIPS32R2 1
+// MIPS-ARCH-32R2:#define _MIPS_ISA _MIPS_ISA_MIPS32
+// MIPS-ARCH-32R2:#define __mips_isa_rev 2
+//
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=mips64-none-none \
+// RUN:            < /dev/null \
+// RUN:   | FileCheck -check-prefix MIPS-ARCH-DEF64 %s
+//
+// MIPS-ARCH-DEF64:#define _MIPS_ARCH "mips64r2"
+// MIPS-ARCH-DEF64:#define _MIPS_ARCH_MIPS64R2 1
+// MIPS-ARCH-DEF64:#define _MIPS_ISA _MIPS_ISA_MIPS64
+// MIPS-ARCH-DEF64:#define __mips_isa_rev 2
+//
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=mips64-none-none \
+// RUN:            -target-cpu mips64 < /dev/null \
+// RUN:   | FileCheck -check-prefix MIPS-ARCH-64 %s
+//
+// MIPS-ARCH-64:#define _MIPS_ARCH "mips64"
+// MIPS-ARCH-64:#define _MIPS_ARCH_MIPS64 1
+// MIPS-ARCH-64:#define _MIPS_ISA _MIPS_ISA_MIPS64
+// MIPS-ARCH-64:#define __mips_isa_rev 1
+//
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=mips64-none-none \
+// RUN:            -target-cpu mips64r2 < /dev/null \
+// RUN:   | FileCheck -check-prefix MIPS-ARCH-64R2 %s
+//
+// MIPS-ARCH-64R2:#define _MIPS_ARCH "mips64r2"
+// MIPS-ARCH-64R2:#define _MIPS_ARCH_MIPS64R2 1
+// MIPS-ARCH-64R2:#define _MIPS_ISA _MIPS_ISA_MIPS64
+// MIPS-ARCH-64R2:#define __mips_isa_rev 2
+//
 // Check MIPS float ABI macros
 //
 // RUN: %clang_cc1 -E -dM -ffreestanding \
@@ -1413,6 +3374,16 @@
 // MIPS64-NOMFP64:#define _MIPS_FPSET 32
 // MIPS64-NOMFP64:#define __mips_fpr 32
 //
+// RUN: %clang_cc1 -target-cpu mips32r6 \
+// RUN:   -E -dM -triple=mips-none-none < /dev/null \
+// RUN:   | FileCheck -check-prefix MIPS-XXR6 %s
+// RUN: %clang_cc1 -target-cpu mips64r6 \
+// RUN:   -E -dM -triple=mips64-none-none < /dev/null \
+// RUN:   | FileCheck -check-prefix MIPS-XXR6 %s
+// MIPS-XXR6:#define _MIPS_FPSET 32
+// MIPS-XXR6:#define __mips_fpr 64
+// MIPS-XXR6:#define __mips_nan2008 1
+//
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=msp430-none-none < /dev/null | FileCheck -check-prefix MSP430 %s
 //
 // MSP430:#define MSP430 1
@@ -1450,15 +3421,69 @@
 // MSP430:#define __FLT_MIN_EXP__ (-125)
 // MSP430:#define __FLT_MIN__ 1.17549435e-38F
 // MSP430:#define __FLT_RADIX__ 2
+// MSP430:#define __INT16_C_SUFFIX__ {{$}}
+// MSP430:#define __INT16_FMTd__ "hd"
+// MSP430:#define __INT16_FMTi__ "hi"
+// MSP430:#define __INT16_MAX__ 32767
 // MSP430:#define __INT16_TYPE__ short
 // MSP430:#define __INT32_C_SUFFIX__ L
+// MSP430:#define __INT32_FMTd__ "ld"
+// MSP430:#define __INT32_FMTi__ "li"
+// MSP430:#define __INT32_MAX__ 2147483647L
 // MSP430:#define __INT32_TYPE__ long int
-// MSP430:#define __INT8_TYPE__ char
+// MSP430:#define __INT64_C_SUFFIX__ LL
+// MSP430:#define __INT64_FMTd__ "lld"
+// MSP430:#define __INT64_FMTi__ "lli"
+// MSP430:#define __INT64_MAX__ 9223372036854775807LL
+// MSP430:#define __INT64_TYPE__ long long int
+// MSP430:#define __INT8_C_SUFFIX__ {{$}}
+// MSP430:#define __INT8_FMTd__ "hhd"
+// MSP430:#define __INT8_FMTi__ "hhi"
+// MSP430:#define __INT8_MAX__ 127
+// MSP430:#define __INT8_TYPE__ signed char
+// MSP430:#define __INTMAX_C_SUFFIX__ LL
+// MSP430:#define __INTMAX_FMTd__ "lld"
+// MSP430:#define __INTMAX_FMTi__ "lli"
 // MSP430:#define __INTMAX_MAX__ 9223372036854775807LL
 // MSP430:#define __INTMAX_TYPE__ long long int
 // MSP430:#define __INTMAX_WIDTH__ 64
+// MSP430:#define __INTPTR_FMTd__ "d"
+// MSP430:#define __INTPTR_FMTi__ "i"
+// MSP430:#define __INTPTR_MAX__ 32767
 // MSP430:#define __INTPTR_TYPE__ int
 // MSP430:#define __INTPTR_WIDTH__ 16
+// MSP430:#define __INT_FAST16_FMTd__ "hd"
+// MSP430:#define __INT_FAST16_FMTi__ "hi"
+// MSP430:#define __INT_FAST16_MAX__ 32767
+// MSP430:#define __INT_FAST16_TYPE__ short
+// MSP430:#define __INT_FAST32_FMTd__ "ld"
+// MSP430:#define __INT_FAST32_FMTi__ "li"
+// MSP430:#define __INT_FAST32_MAX__ 2147483647L
+// MSP430:#define __INT_FAST32_TYPE__ long int
+// MSP430:#define __INT_FAST64_FMTd__ "lld"
+// MSP430:#define __INT_FAST64_FMTi__ "lli"
+// MSP430:#define __INT_FAST64_MAX__ 9223372036854775807LL
+// MSP430:#define __INT_FAST64_TYPE__ long long int
+// MSP430:#define __INT_FAST8_FMTd__ "hhd"
+// MSP430:#define __INT_FAST8_FMTi__ "hhi"
+// MSP430:#define __INT_FAST8_MAX__ 127
+// MSP430:#define __INT_FAST8_TYPE__ signed char
+// MSP430:#define __INT_LEAST16_FMTd__ "hd"
+// MSP430:#define __INT_LEAST16_FMTi__ "hi"
+// MSP430:#define __INT_LEAST16_MAX__ 32767
+// MSP430:#define __INT_LEAST16_TYPE__ short
+// MSP430:#define __INT_LEAST32_FMTd__ "ld"
+// MSP430:#define __INT_LEAST32_FMTi__ "li"
+// MSP430:#define __INT_LEAST32_MAX__ 2147483647L
+// MSP430:#define __INT_LEAST32_TYPE__ long int
+// MSP430:#define __INT_LEAST64_FMTd__ "lld"
+// MSP430:#define __INT_LEAST64_FMTi__ "lli"
+// MSP430:#define __INT_LEAST64_MAX__ 9223372036854775807LL
+// MSP430:#define __INT_LEAST64_TYPE__ long long int
+// MSP430:#define __INT_LEAST8_FMTd__ "hhd"
+// MSP430:#define __INT_LEAST8_FMTi__ "hhi"
+// MSP430:#define __INT_LEAST8_MAX__ 127
+// MSP430:#define __INT_LEAST8_TYPE__ signed char
 // MSP430:#define __INT_MAX__ 32767
 // MSP430:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
 // MSP430:#define __LDBL_DIG__ 15
@@ -1473,6 +3498,7 @@
 // MSP430:#define __LDBL_MIN_10_EXP__ (-307)
 // MSP430:#define __LDBL_MIN_EXP__ (-1021)
 // MSP430:#define __LDBL_MIN__ 2.2250738585072014e-308L
+// MSP430:#define __LITTLE_ENDIAN__ 1
 // MSP430:#define __LONG_LONG_MAX__ 9223372036854775807LL
 // MSP430:#define __LONG_MAX__ 2147483647L
 // MSP430-NOT:#define __LP64__
@@ -1482,6 +3508,7 @@
 // MSP430:#define __PTRDIFF_WIDTH__ 16 
 // MSP430:#define __SCHAR_MAX__ 127
 // MSP430:#define __SHRT_MAX__ 32767
+// MSP430:#define __SIG_ATOMIC_MAX__ 2147483647
 // MSP430:#define __SIG_ATOMIC_WIDTH__ 32
 // MSP430:#define __SIZEOF_DOUBLE__ 8
 // MSP430:#define __SIZEOF_FLOAT__ 4
@@ -1495,10 +3522,44 @@
 // MSP430:#define __SIZEOF_SIZE_T__ 2
 // MSP430:#define __SIZEOF_WCHAR_T__ 2
 // MSP430:#define __SIZEOF_WINT_T__ 2
-// MSP430:#define __SIZE_MAX__ 65535U
+// MSP430:#define __SIZE_MAX__ 65535
 // MSP430:#define __SIZE_TYPE__ unsigned int
 // MSP430:#define __SIZE_WIDTH__ 16
+// MSP430:#define __UINT16_C_SUFFIX__ U
+// MSP430:#define __UINT16_MAX__ 65535
+// MSP430:#define __UINT16_TYPE__ unsigned short
+// MSP430:#define __UINT32_C_SUFFIX__ UL
+// MSP430:#define __UINT32_MAX__ 4294967295UL
+// MSP430:#define __UINT32_TYPE__ long unsigned int
+// MSP430:#define __UINT64_C_SUFFIX__ ULL
+// MSP430:#define __UINT64_MAX__ 18446744073709551615ULL
+// MSP430:#define __UINT64_TYPE__ long long unsigned int
+// MSP430:#define __UINT8_C_SUFFIX__ {{$}}
+// MSP430:#define __UINT8_MAX__ 255
+// MSP430:#define __UINT8_TYPE__ unsigned char
+// MSP430:#define __UINTMAX_C_SUFFIX__ ULL
+// MSP430:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // MSP430:#define __UINTMAX_TYPE__ long long unsigned int
+// MSP430:#define __UINTMAX_WIDTH__ 64
+// MSP430:#define __UINTPTR_MAX__ 65535
+// MSP430:#define __UINTPTR_TYPE__ unsigned int
+// MSP430:#define __UINTPTR_WIDTH__ 16
+// MSP430:#define __UINT_FAST16_MAX__ 65535
+// MSP430:#define __UINT_FAST16_TYPE__ unsigned short
+// MSP430:#define __UINT_FAST32_MAX__ 4294967295UL
+// MSP430:#define __UINT_FAST32_TYPE__ long unsigned int
+// MSP430:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// MSP430:#define __UINT_FAST64_TYPE__ long long unsigned int
+// MSP430:#define __UINT_FAST8_MAX__ 255
+// MSP430:#define __UINT_FAST8_TYPE__ unsigned char
+// MSP430:#define __UINT_LEAST16_MAX__ 65535
+// MSP430:#define __UINT_LEAST16_TYPE__ unsigned short
+// MSP430:#define __UINT_LEAST32_MAX__ 4294967295UL
+// MSP430:#define __UINT_LEAST32_TYPE__ long unsigned int
+// MSP430:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// MSP430:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// MSP430:#define __UINT_LEAST8_MAX__ 255
+// MSP430:#define __UINT_LEAST8_TYPE__ unsigned char
 // MSP430:#define __USER_LABEL_PREFIX__ _
 // MSP430:#define __WCHAR_MAX__ 32767
 // MSP430:#define __WCHAR_TYPE__ int
@@ -1545,16 +3606,69 @@
 // NVPTX32:#define __FLT_MIN_EXP__ (-125)
 // NVPTX32:#define __FLT_MIN__ 1.17549435e-38F
 // NVPTX32:#define __FLT_RADIX__ 2
+// NVPTX32:#define __INT16_C_SUFFIX__ {{$}}
+// NVPTX32:#define __INT16_FMTd__ "hd"
+// NVPTX32:#define __INT16_FMTi__ "hi"
+// NVPTX32:#define __INT16_MAX__ 32767
 // NVPTX32:#define __INT16_TYPE__ short
+// NVPTX32:#define __INT32_C_SUFFIX__ {{$}}
+// NVPTX32:#define __INT32_FMTd__ "d"
+// NVPTX32:#define __INT32_FMTi__ "i"
+// NVPTX32:#define __INT32_MAX__ 2147483647
 // NVPTX32:#define __INT32_TYPE__ int
 // NVPTX32:#define __INT64_C_SUFFIX__ LL
+// NVPTX32:#define __INT64_FMTd__ "lld"
+// NVPTX32:#define __INT64_FMTi__ "lli"
+// NVPTX32:#define __INT64_MAX__ 9223372036854775807L
 // NVPTX32:#define __INT64_TYPE__ long long int
-// NVPTX32:#define __INT8_TYPE__ char
+// NVPTX32:#define __INT8_C_SUFFIX__ {{$}}
+// NVPTX32:#define __INT8_FMTd__ "hhd"
+// NVPTX32:#define __INT8_FMTi__ "hhi"
+// NVPTX32:#define __INT8_MAX__ 127
+// NVPTX32:#define __INT8_TYPE__ signed char
+// NVPTX32:#define __INTMAX_C_SUFFIX__ LL
+// NVPTX32:#define __INTMAX_FMTd__ "lld"
+// NVPTX32:#define __INTMAX_FMTi__ "lli"
 // NVPTX32:#define __INTMAX_MAX__ 9223372036854775807LL
 // NVPTX32:#define __INTMAX_TYPE__ long long int
 // NVPTX32:#define __INTMAX_WIDTH__ 64
-// NVPTX32:#define __INTPTR_TYPE__ unsigned int
+// NVPTX32:#define __INTPTR_FMTd__ "d"
+// NVPTX32:#define __INTPTR_FMTi__ "i"
+// NVPTX32:#define __INTPTR_MAX__ 2147483647
+// NVPTX32:#define __INTPTR_TYPE__ int
 // NVPTX32:#define __INTPTR_WIDTH__ 32
+// NVPTX32:#define __INT_FAST16_FMTd__ "hd"
+// NVPTX32:#define __INT_FAST16_FMTi__ "hi"
+// NVPTX32:#define __INT_FAST16_MAX__ 32767
+// NVPTX32:#define __INT_FAST16_TYPE__ short
+// NVPTX32:#define __INT_FAST32_FMTd__ "d"
+// NVPTX32:#define __INT_FAST32_FMTi__ "i"
+// NVPTX32:#define __INT_FAST32_MAX__ 2147483647
+// NVPTX32:#define __INT_FAST32_TYPE__ int
+// NVPTX32:#define __INT_FAST64_FMTd__ "ld"
+// NVPTX32:#define __INT_FAST64_FMTi__ "li"
+// NVPTX32:#define __INT_FAST64_MAX__ 9223372036854775807L
+// NVPTX32:#define __INT_FAST64_TYPE__ long int
+// NVPTX32:#define __INT_FAST8_FMTd__ "hhd"
+// NVPTX32:#define __INT_FAST8_FMTi__ "hhi"
+// NVPTX32:#define __INT_FAST8_MAX__ 127
+// NVPTX32:#define __INT_FAST8_TYPE__ signed char
+// NVPTX32:#define __INT_LEAST16_FMTd__ "hd"
+// NVPTX32:#define __INT_LEAST16_FMTi__ "hi"
+// NVPTX32:#define __INT_LEAST16_MAX__ 32767
+// NVPTX32:#define __INT_LEAST16_TYPE__ short
+// NVPTX32:#define __INT_LEAST32_FMTd__ "d"
+// NVPTX32:#define __INT_LEAST32_FMTi__ "i"
+// NVPTX32:#define __INT_LEAST32_MAX__ 2147483647
+// NVPTX32:#define __INT_LEAST32_TYPE__ int
+// NVPTX32:#define __INT_LEAST64_FMTd__ "ld"
+// NVPTX32:#define __INT_LEAST64_FMTi__ "li"
+// NVPTX32:#define __INT_LEAST64_MAX__ 9223372036854775807L
+// NVPTX32:#define __INT_LEAST64_TYPE__ long int
+// NVPTX32:#define __INT_LEAST8_FMTd__ "hhd"
+// NVPTX32:#define __INT_LEAST8_FMTi__ "hhi"
+// NVPTX32:#define __INT_LEAST8_MAX__ 127
+// NVPTX32:#define __INT_LEAST8_TYPE__ signed char
 // NVPTX32:#define __INT_MAX__ 2147483647
 // NVPTX32:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
 // NVPTX32:#define __LDBL_DIG__ 15
@@ -1569,6 +3683,7 @@
 // NVPTX32:#define __LDBL_MIN_10_EXP__ (-307)
 // NVPTX32:#define __LDBL_MIN_EXP__ (-1021)
 // NVPTX32:#define __LDBL_MIN__ 2.2250738585072014e-308L
+// NVPTX32:#define __LITTLE_ENDIAN__ 1
 // NVPTX32:#define __LONG_LONG_MAX__ 9223372036854775807LL
 // NVPTX32:#define __LONG_MAX__ 9223372036854775807L
 // NVPTX32-NOT:#define __LP64__
@@ -1580,6 +3695,7 @@
 // NVPTX32:#define __PTX__ 1
 // NVPTX32:#define __SCHAR_MAX__ 127
 // NVPTX32:#define __SHRT_MAX__ 32767
+// NVPTX32:#define __SIG_ATOMIC_MAX__ 2147483647
 // NVPTX32:#define __SIG_ATOMIC_WIDTH__ 32
 // NVPTX32:#define __SIZEOF_DOUBLE__ 8
 // NVPTX32:#define __SIZEOF_FLOAT__ 4
@@ -1596,7 +3712,41 @@
 // NVPTX32:#define __SIZE_MAX__ 4294967295U
 // NVPTX32:#define __SIZE_TYPE__ unsigned int
 // NVPTX32:#define __SIZE_WIDTH__ 32
+// NVPTX32:#define __UINT16_C_SUFFIX__ {{$}}
+// NVPTX32:#define __UINT16_MAX__ 65535
+// NVPTX32:#define __UINT16_TYPE__ unsigned short
+// NVPTX32:#define __UINT32_C_SUFFIX__ U
+// NVPTX32:#define __UINT32_MAX__ 4294967295U
+// NVPTX32:#define __UINT32_TYPE__ unsigned int
+// NVPTX32:#define __UINT64_C_SUFFIX__ ULL
+// NVPTX32:#define __UINT64_MAX__ 18446744073709551615ULL
+// NVPTX32:#define __UINT64_TYPE__ long long unsigned int
+// NVPTX32:#define __UINT8_C_SUFFIX__ {{$}}
+// NVPTX32:#define __UINT8_MAX__ 255
+// NVPTX32:#define __UINT8_TYPE__ unsigned char
+// NVPTX32:#define __UINTMAX_C_SUFFIX__ ULL
+// NVPTX32:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // NVPTX32:#define __UINTMAX_TYPE__ long long unsigned int
+// NVPTX32:#define __UINTMAX_WIDTH__ 64
+// NVPTX32:#define __UINTPTR_MAX__ 4294967295U
+// NVPTX32:#define __UINTPTR_TYPE__ unsigned int
+// NVPTX32:#define __UINTPTR_WIDTH__ 32
+// NVPTX32:#define __UINT_FAST16_MAX__ 65535
+// NVPTX32:#define __UINT_FAST16_TYPE__ unsigned short
+// NVPTX32:#define __UINT_FAST32_MAX__ 4294967295U
+// NVPTX32:#define __UINT_FAST32_TYPE__ unsigned int
+// NVPTX32:#define __UINT_FAST64_MAX__ 18446744073709551615UL
+// NVPTX32:#define __UINT_FAST64_TYPE__ long unsigned int
+// NVPTX32:#define __UINT_FAST8_MAX__ 255
+// NVPTX32:#define __UINT_FAST8_TYPE__ unsigned char
+// NVPTX32:#define __UINT_LEAST16_MAX__ 65535
+// NVPTX32:#define __UINT_LEAST16_TYPE__ unsigned short
+// NVPTX32:#define __UINT_LEAST32_MAX__ 4294967295U
+// NVPTX32:#define __UINT_LEAST32_TYPE__ unsigned int
+// NVPTX32:#define __UINT_LEAST64_MAX__ 18446744073709551615UL
+// NVPTX32:#define __UINT_LEAST64_TYPE__ long unsigned int
+// NVPTX32:#define __UINT_LEAST8_MAX__ 255
+// NVPTX32:#define __UINT_LEAST8_TYPE__ unsigned char
 // NVPTX32:#define __USER_LABEL_PREFIX__ _
 // NVPTX32:#define __WCHAR_MAX__ 2147483647
 // NVPTX32:#define __WCHAR_TYPE__ int
@@ -1642,16 +3792,69 @@
 // NVPTX64:#define __FLT_MIN_EXP__ (-125)
 // NVPTX64:#define __FLT_MIN__ 1.17549435e-38F
 // NVPTX64:#define __FLT_RADIX__ 2
+// NVPTX64:#define __INT16_C_SUFFIX__ {{$}}
+// NVPTX64:#define __INT16_FMTd__ "hd"
+// NVPTX64:#define __INT16_FMTi__ "hi"
+// NVPTX64:#define __INT16_MAX__ 32767
 // NVPTX64:#define __INT16_TYPE__ short
+// NVPTX64:#define __INT32_C_SUFFIX__ {{$}}
+// NVPTX64:#define __INT32_FMTd__ "d"
+// NVPTX64:#define __INT32_FMTi__ "i"
+// NVPTX64:#define __INT32_MAX__ 2147483647
 // NVPTX64:#define __INT32_TYPE__ int
 // NVPTX64:#define __INT64_C_SUFFIX__ LL
+// NVPTX64:#define __INT64_FMTd__ "lld"
+// NVPTX64:#define __INT64_FMTi__ "lli"
+// NVPTX64:#define __INT64_MAX__ 9223372036854775807L
 // NVPTX64:#define __INT64_TYPE__ long long int
-// NVPTX64:#define __INT8_TYPE__ char
+// NVPTX64:#define __INT8_C_SUFFIX__ {{$}}
+// NVPTX64:#define __INT8_FMTd__ "hhd"
+// NVPTX64:#define __INT8_FMTi__ "hhi"
+// NVPTX64:#define __INT8_MAX__ 127
+// NVPTX64:#define __INT8_TYPE__ signed char
+// NVPTX64:#define __INTMAX_C_SUFFIX__ LL
+// NVPTX64:#define __INTMAX_FMTd__ "lld"
+// NVPTX64:#define __INTMAX_FMTi__ "lli"
 // NVPTX64:#define __INTMAX_MAX__ 9223372036854775807LL
 // NVPTX64:#define __INTMAX_TYPE__ long long int
 // NVPTX64:#define __INTMAX_WIDTH__ 64
-// NVPTX64:#define __INTPTR_TYPE__ long long unsigned int
+// NVPTX64:#define __INTPTR_FMTd__ "lld"
+// NVPTX64:#define __INTPTR_FMTi__ "lli"
+// NVPTX64:#define __INTPTR_MAX__ 9223372036854775807LL
+// NVPTX64:#define __INTPTR_TYPE__ long long int
 // NVPTX64:#define __INTPTR_WIDTH__ 64
+// NVPTX64:#define __INT_FAST16_FMTd__ "hd"
+// NVPTX64:#define __INT_FAST16_FMTi__ "hi"
+// NVPTX64:#define __INT_FAST16_MAX__ 32767
+// NVPTX64:#define __INT_FAST16_TYPE__ short
+// NVPTX64:#define __INT_FAST32_FMTd__ "d"
+// NVPTX64:#define __INT_FAST32_FMTi__ "i"
+// NVPTX64:#define __INT_FAST32_MAX__ 2147483647
+// NVPTX64:#define __INT_FAST32_TYPE__ int
+// NVPTX64:#define __INT_FAST64_FMTd__ "ld"
+// NVPTX64:#define __INT_FAST64_FMTi__ "li"
+// NVPTX64:#define __INT_FAST64_MAX__ 9223372036854775807L
+// NVPTX64:#define __INT_FAST64_TYPE__ long int
+// NVPTX64:#define __INT_FAST8_FMTd__ "hhd"
+// NVPTX64:#define __INT_FAST8_FMTi__ "hhi"
+// NVPTX64:#define __INT_FAST8_MAX__ 127
+// NVPTX64:#define __INT_FAST8_TYPE__ signed char
+// NVPTX64:#define __INT_LEAST16_FMTd__ "hd"
+// NVPTX64:#define __INT_LEAST16_FMTi__ "hi"
+// NVPTX64:#define __INT_LEAST16_MAX__ 32767
+// NVPTX64:#define __INT_LEAST16_TYPE__ short
+// NVPTX64:#define __INT_LEAST32_FMTd__ "d"
+// NVPTX64:#define __INT_LEAST32_FMTi__ "i"
+// NVPTX64:#define __INT_LEAST32_MAX__ 2147483647
+// NVPTX64:#define __INT_LEAST32_TYPE__ int
+// NVPTX64:#define __INT_LEAST64_FMTd__ "ld"
+// NVPTX64:#define __INT_LEAST64_FMTi__ "li"
+// NVPTX64:#define __INT_LEAST64_MAX__ 9223372036854775807L
+// NVPTX64:#define __INT_LEAST64_TYPE__ long int
+// NVPTX64:#define __INT_LEAST8_FMTd__ "hhd"
+// NVPTX64:#define __INT_LEAST8_FMTi__ "hhi"
+// NVPTX64:#define __INT_LEAST8_MAX__ 127
+// NVPTX64:#define __INT_LEAST8_TYPE__ signed char
 // NVPTX64:#define __INT_MAX__ 2147483647
 // NVPTX64:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
 // NVPTX64:#define __LDBL_DIG__ 15
@@ -1666,6 +3869,7 @@
 // NVPTX64:#define __LDBL_MIN_10_EXP__ (-307)
 // NVPTX64:#define __LDBL_MIN_EXP__ (-1021)
 // NVPTX64:#define __LDBL_MIN__ 2.2250738585072014e-308L
+// NVPTX64:#define __LITTLE_ENDIAN__ 1
 // NVPTX64:#define __LONG_LONG_MAX__ 9223372036854775807LL
 // NVPTX64:#define __LONG_MAX__ 9223372036854775807L
 // NVPTX64:#define __LP64__ 1
@@ -1677,6 +3881,7 @@
 // NVPTX64:#define __PTX__ 1
 // NVPTX64:#define __SCHAR_MAX__ 127
 // NVPTX64:#define __SHRT_MAX__ 32767
+// NVPTX64:#define __SIG_ATOMIC_MAX__ 2147483647
 // NVPTX64:#define __SIG_ATOMIC_WIDTH__ 32
 // NVPTX64:#define __SIZEOF_DOUBLE__ 8
 // NVPTX64:#define __SIZEOF_FLOAT__ 4
@@ -1693,7 +3898,41 @@
 // NVPTX64:#define __SIZE_MAX__ 18446744073709551615UL
 // NVPTX64:#define __SIZE_TYPE__ long long unsigned int
 // NVPTX64:#define __SIZE_WIDTH__ 64
+// NVPTX64:#define __UINT16_C_SUFFIX__ {{$}}
+// NVPTX64:#define __UINT16_MAX__ 65535
+// NVPTX64:#define __UINT16_TYPE__ unsigned short
+// NVPTX64:#define __UINT32_C_SUFFIX__ U
+// NVPTX64:#define __UINT32_MAX__ 4294967295U
+// NVPTX64:#define __UINT32_TYPE__ unsigned int
+// NVPTX64:#define __UINT64_C_SUFFIX__ ULL
+// NVPTX64:#define __UINT64_MAX__ 18446744073709551615ULL
+// NVPTX64:#define __UINT64_TYPE__ long long unsigned int
+// NVPTX64:#define __UINT8_C_SUFFIX__ {{$}}
+// NVPTX64:#define __UINT8_MAX__ 255
+// NVPTX64:#define __UINT8_TYPE__ unsigned char
+// NVPTX64:#define __UINTMAX_C_SUFFIX__ ULL
+// NVPTX64:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // NVPTX64:#define __UINTMAX_TYPE__ long long unsigned int
+// NVPTX64:#define __UINTMAX_WIDTH__ 64
+// NVPTX64:#define __UINTPTR_MAX__ 18446744073709551615ULL
+// NVPTX64:#define __UINTPTR_TYPE__ long long unsigned int
+// NVPTX64:#define __UINTPTR_WIDTH__ 64
+// NVPTX64:#define __UINT_FAST16_MAX__ 65535
+// NVPTX64:#define __UINT_FAST16_TYPE__ unsigned short
+// NVPTX64:#define __UINT_FAST32_MAX__ 4294967295U
+// NVPTX64:#define __UINT_FAST32_TYPE__ unsigned int
+// NVPTX64:#define __UINT_FAST64_MAX__ 18446744073709551615UL
+// NVPTX64:#define __UINT_FAST64_TYPE__ long unsigned int
+// NVPTX64:#define __UINT_FAST8_MAX__ 255
+// NVPTX64:#define __UINT_FAST8_TYPE__ unsigned char
+// NVPTX64:#define __UINT_LEAST16_MAX__ 65535
+// NVPTX64:#define __UINT_LEAST16_TYPE__ unsigned short
+// NVPTX64:#define __UINT_LEAST32_MAX__ 4294967295U
+// NVPTX64:#define __UINT_LEAST32_TYPE__ unsigned int
+// NVPTX64:#define __UINT_LEAST64_MAX__ 18446744073709551615UL
+// NVPTX64:#define __UINT_LEAST64_TYPE__ long unsigned int
+// NVPTX64:#define __UINT_LEAST8_MAX__ 255
+// NVPTX64:#define __UINT_LEAST8_TYPE__ unsigned char
 // NVPTX64:#define __USER_LABEL_PREFIX__ _
 // NVPTX64:#define __WCHAR_MAX__ 2147483647
 // NVPTX64:#define __WCHAR_TYPE__ int
@@ -1743,16 +3982,69 @@
 // PPC603E:#define __FLT_MIN_EXP__ (-125)
 // PPC603E:#define __FLT_MIN__ 1.17549435e-38F
 // PPC603E:#define __FLT_RADIX__ 2
+// PPC603E:#define __INT16_C_SUFFIX__ {{$}}
+// PPC603E:#define __INT16_FMTd__ "hd"
+// PPC603E:#define __INT16_FMTi__ "hi"
+// PPC603E:#define __INT16_MAX__ 32767
 // PPC603E:#define __INT16_TYPE__ short
+// PPC603E:#define __INT32_C_SUFFIX__ {{$}}
+// PPC603E:#define __INT32_FMTd__ "d"
+// PPC603E:#define __INT32_FMTi__ "i"
+// PPC603E:#define __INT32_MAX__ 2147483647
 // PPC603E:#define __INT32_TYPE__ int
 // PPC603E:#define __INT64_C_SUFFIX__ LL
+// PPC603E:#define __INT64_FMTd__ "lld"
+// PPC603E:#define __INT64_FMTi__ "lli"
+// PPC603E:#define __INT64_MAX__ 9223372036854775807LL
 // PPC603E:#define __INT64_TYPE__ long long int
-// PPC603E:#define __INT8_TYPE__ char
+// PPC603E:#define __INT8_C_SUFFIX__ {{$}}
+// PPC603E:#define __INT8_FMTd__ "hhd"
+// PPC603E:#define __INT8_FMTi__ "hhi"
+// PPC603E:#define __INT8_MAX__ 127
+// PPC603E:#define __INT8_TYPE__ signed char
+// PPC603E:#define __INTMAX_C_SUFFIX__ LL
+// PPC603E:#define __INTMAX_FMTd__ "lld"
+// PPC603E:#define __INTMAX_FMTi__ "lli"
 // PPC603E:#define __INTMAX_MAX__ 9223372036854775807LL
 // PPC603E:#define __INTMAX_TYPE__ long long int
 // PPC603E:#define __INTMAX_WIDTH__ 64
+// PPC603E:#define __INTPTR_FMTd__ "ld"
+// PPC603E:#define __INTPTR_FMTi__ "li"
+// PPC603E:#define __INTPTR_MAX__ 2147483647L
 // PPC603E:#define __INTPTR_TYPE__ long int
 // PPC603E:#define __INTPTR_WIDTH__ 32
+// PPC603E:#define __INT_FAST16_FMTd__ "hd"
+// PPC603E:#define __INT_FAST16_FMTi__ "hi"
+// PPC603E:#define __INT_FAST16_MAX__ 32767
+// PPC603E:#define __INT_FAST16_TYPE__ short
+// PPC603E:#define __INT_FAST32_FMTd__ "d"
+// PPC603E:#define __INT_FAST32_FMTi__ "i"
+// PPC603E:#define __INT_FAST32_MAX__ 2147483647
+// PPC603E:#define __INT_FAST32_TYPE__ int
+// PPC603E:#define __INT_FAST64_FMTd__ "lld"
+// PPC603E:#define __INT_FAST64_FMTi__ "lli"
+// PPC603E:#define __INT_FAST64_MAX__ 9223372036854775807LL
+// PPC603E:#define __INT_FAST64_TYPE__ long long int
+// PPC603E:#define __INT_FAST8_FMTd__ "hhd"
+// PPC603E:#define __INT_FAST8_FMTi__ "hhi"
+// PPC603E:#define __INT_FAST8_MAX__ 127
+// PPC603E:#define __INT_FAST8_TYPE__ signed char
+// PPC603E:#define __INT_LEAST16_FMTd__ "hd"
+// PPC603E:#define __INT_LEAST16_FMTi__ "hi"
+// PPC603E:#define __INT_LEAST16_MAX__ 32767
+// PPC603E:#define __INT_LEAST16_TYPE__ short
+// PPC603E:#define __INT_LEAST32_FMTd__ "d"
+// PPC603E:#define __INT_LEAST32_FMTi__ "i"
+// PPC603E:#define __INT_LEAST32_MAX__ 2147483647
+// PPC603E:#define __INT_LEAST32_TYPE__ int
+// PPC603E:#define __INT_LEAST64_FMTd__ "lld"
+// PPC603E:#define __INT_LEAST64_FMTi__ "lli"
+// PPC603E:#define __INT_LEAST64_MAX__ 9223372036854775807LL
+// PPC603E:#define __INT_LEAST64_TYPE__ long long int
+// PPC603E:#define __INT_LEAST8_FMTd__ "hhd"
+// PPC603E:#define __INT_LEAST8_FMTi__ "hhi"
+// PPC603E:#define __INT_LEAST8_MAX__ 127
+// PPC603E:#define __INT_LEAST8_TYPE__ signed char
 // PPC603E:#define __INT_MAX__ 2147483647
 // PPC603E:#define __LDBL_DENORM_MIN__ 4.94065645841246544176568792868221e-324L
 // PPC603E:#define __LDBL_DIG__ 31
@@ -1780,6 +4072,7 @@
 // PPC603E:#define __REGISTER_PREFIX__
 // PPC603E:#define __SCHAR_MAX__ 127
 // PPC603E:#define __SHRT_MAX__ 32767
+// PPC603E:#define __SIG_ATOMIC_MAX__ 2147483647
 // PPC603E:#define __SIG_ATOMIC_WIDTH__ 32
 // PPC603E:#define __SIZEOF_DOUBLE__ 8
 // PPC603E:#define __SIZEOF_FLOAT__ 4
@@ -1796,7 +4089,41 @@
 // PPC603E:#define __SIZE_MAX__ 4294967295U
 // PPC603E:#define __SIZE_TYPE__ long unsigned int
 // PPC603E:#define __SIZE_WIDTH__ 32
+// PPC603E:#define __UINT16_C_SUFFIX__ {{$}}
+// PPC603E:#define __UINT16_MAX__ 65535
+// PPC603E:#define __UINT16_TYPE__ unsigned short
+// PPC603E:#define __UINT32_C_SUFFIX__ U
+// PPC603E:#define __UINT32_MAX__ 4294967295U
+// PPC603E:#define __UINT32_TYPE__ unsigned int
+// PPC603E:#define __UINT64_C_SUFFIX__ ULL
+// PPC603E:#define __UINT64_MAX__ 18446744073709551615ULL
+// PPC603E:#define __UINT64_TYPE__ long long unsigned int
+// PPC603E:#define __UINT8_C_SUFFIX__ {{$}}
+// PPC603E:#define __UINT8_MAX__ 255
+// PPC603E:#define __UINT8_TYPE__ unsigned char
+// PPC603E:#define __UINTMAX_C_SUFFIX__ ULL
+// PPC603E:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // PPC603E:#define __UINTMAX_TYPE__ long long unsigned int
+// PPC603E:#define __UINTMAX_WIDTH__ 64
+// PPC603E:#define __UINTPTR_MAX__ 4294967295U
+// PPC603E:#define __UINTPTR_TYPE__ long unsigned int
+// PPC603E:#define __UINTPTR_WIDTH__ 32
+// PPC603E:#define __UINT_FAST16_MAX__ 65535
+// PPC603E:#define __UINT_FAST16_TYPE__ unsigned short
+// PPC603E:#define __UINT_FAST32_MAX__ 4294967295U
+// PPC603E:#define __UINT_FAST32_TYPE__ unsigned int
+// PPC603E:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// PPC603E:#define __UINT_FAST64_TYPE__ long long unsigned int
+// PPC603E:#define __UINT_FAST8_MAX__ 255
+// PPC603E:#define __UINT_FAST8_TYPE__ unsigned char
+// PPC603E:#define __UINT_LEAST16_MAX__ 65535
+// PPC603E:#define __UINT_LEAST16_TYPE__ unsigned short
+// PPC603E:#define __UINT_LEAST32_MAX__ 4294967295U
+// PPC603E:#define __UINT_LEAST32_TYPE__ unsigned int
+// PPC603E:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// PPC603E:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// PPC603E:#define __UINT_LEAST8_MAX__ 255
+// PPC603E:#define __UINT_LEAST8_TYPE__ unsigned char
 // PPC603E:#define __USER_LABEL_PREFIX__ _
 // PPC603E:#define __WCHAR_MAX__ 2147483647
 // PPC603E:#define __WCHAR_TYPE__ int
@@ -1853,16 +4180,69 @@
 // PPC64:#define __FLT_MIN_EXP__ (-125)
 // PPC64:#define __FLT_MIN__ 1.17549435e-38F
 // PPC64:#define __FLT_RADIX__ 2
+// PPC64:#define __INT16_C_SUFFIX__ {{$}}
+// PPC64:#define __INT16_FMTd__ "hd"
+// PPC64:#define __INT16_FMTi__ "hi"
+// PPC64:#define __INT16_MAX__ 32767
 // PPC64:#define __INT16_TYPE__ short
+// PPC64:#define __INT32_C_SUFFIX__ {{$}}
+// PPC64:#define __INT32_FMTd__ "d"
+// PPC64:#define __INT32_FMTi__ "i"
+// PPC64:#define __INT32_MAX__ 2147483647
 // PPC64:#define __INT32_TYPE__ int
 // PPC64:#define __INT64_C_SUFFIX__ L
+// PPC64:#define __INT64_FMTd__ "ld"
+// PPC64:#define __INT64_FMTi__ "li"
+// PPC64:#define __INT64_MAX__ 9223372036854775807L
 // PPC64:#define __INT64_TYPE__ long int
-// PPC64:#define __INT8_TYPE__ char
+// PPC64:#define __INT8_C_SUFFIX__ {{$}}
+// PPC64:#define __INT8_FMTd__ "hhd"
+// PPC64:#define __INT8_FMTi__ "hhi"
+// PPC64:#define __INT8_MAX__ 127
+// PPC64:#define __INT8_TYPE__ signed char
+// PPC64:#define __INTMAX_C_SUFFIX__ L
+// PPC64:#define __INTMAX_FMTd__ "ld"
+// PPC64:#define __INTMAX_FMTi__ "li"
 // PPC64:#define __INTMAX_MAX__ 9223372036854775807L
 // PPC64:#define __INTMAX_TYPE__ long int
 // PPC64:#define __INTMAX_WIDTH__ 64
+// PPC64:#define __INTPTR_FMTd__ "ld"
+// PPC64:#define __INTPTR_FMTi__ "li"
+// PPC64:#define __INTPTR_MAX__ 9223372036854775807L
 // PPC64:#define __INTPTR_TYPE__ long int
 // PPC64:#define __INTPTR_WIDTH__ 64
+// PPC64:#define __INT_FAST16_FMTd__ "hd"
+// PPC64:#define __INT_FAST16_FMTi__ "hi"
+// PPC64:#define __INT_FAST16_MAX__ 32767
+// PPC64:#define __INT_FAST16_TYPE__ short
+// PPC64:#define __INT_FAST32_FMTd__ "d"
+// PPC64:#define __INT_FAST32_FMTi__ "i"
+// PPC64:#define __INT_FAST32_MAX__ 2147483647
+// PPC64:#define __INT_FAST32_TYPE__ int
+// PPC64:#define __INT_FAST64_FMTd__ "ld"
+// PPC64:#define __INT_FAST64_FMTi__ "li"
+// PPC64:#define __INT_FAST64_MAX__ 9223372036854775807L
+// PPC64:#define __INT_FAST64_TYPE__ long int
+// PPC64:#define __INT_FAST8_FMTd__ "hhd"
+// PPC64:#define __INT_FAST8_FMTi__ "hhi"
+// PPC64:#define __INT_FAST8_MAX__ 127
+// PPC64:#define __INT_FAST8_TYPE__ signed char
+// PPC64:#define __INT_LEAST16_FMTd__ "hd"
+// PPC64:#define __INT_LEAST16_FMTi__ "hi"
+// PPC64:#define __INT_LEAST16_MAX__ 32767
+// PPC64:#define __INT_LEAST16_TYPE__ short
+// PPC64:#define __INT_LEAST32_FMTd__ "d"
+// PPC64:#define __INT_LEAST32_FMTi__ "i"
+// PPC64:#define __INT_LEAST32_MAX__ 2147483647
+// PPC64:#define __INT_LEAST32_TYPE__ int
+// PPC64:#define __INT_LEAST64_FMTd__ "ld"
+// PPC64:#define __INT_LEAST64_FMTi__ "li"
+// PPC64:#define __INT_LEAST64_MAX__ 9223372036854775807L
+// PPC64:#define __INT_LEAST64_TYPE__ long int
+// PPC64:#define __INT_LEAST8_FMTd__ "hhd"
+// PPC64:#define __INT_LEAST8_FMTi__ "hhi"
+// PPC64:#define __INT_LEAST8_MAX__ 127
+// PPC64:#define __INT_LEAST8_TYPE__ signed char
 // PPC64:#define __INT_MAX__ 2147483647
 // PPC64:#define __LDBL_DENORM_MIN__ 4.94065645841246544176568792868221e-324L
 // PPC64:#define __LDBL_DIG__ 31
@@ -1891,6 +4271,7 @@
 // PPC64:#define __REGISTER_PREFIX__ 
 // PPC64:#define __SCHAR_MAX__ 127
 // PPC64:#define __SHRT_MAX__ 32767
+// PPC64:#define __SIG_ATOMIC_MAX__ 2147483647
 // PPC64:#define __SIG_ATOMIC_WIDTH__ 32
 // PPC64:#define __SIZEOF_DOUBLE__ 8
 // PPC64:#define __SIZEOF_FLOAT__ 4
@@ -1907,7 +4288,41 @@
 // PPC64:#define __SIZE_MAX__ 18446744073709551615UL
 // PPC64:#define __SIZE_TYPE__ long unsigned int
 // PPC64:#define __SIZE_WIDTH__ 64
+// PPC64:#define __UINT16_C_SUFFIX__ {{$}}
+// PPC64:#define __UINT16_MAX__ 65535
+// PPC64:#define __UINT16_TYPE__ unsigned short
+// PPC64:#define __UINT32_C_SUFFIX__ U
+// PPC64:#define __UINT32_MAX__ 4294967295U
+// PPC64:#define __UINT32_TYPE__ unsigned int
+// PPC64:#define __UINT64_C_SUFFIX__ UL
+// PPC64:#define __UINT64_MAX__ 18446744073709551615UL
+// PPC64:#define __UINT64_TYPE__ long unsigned int
+// PPC64:#define __UINT8_C_SUFFIX__ {{$}}
+// PPC64:#define __UINT8_MAX__ 255
+// PPC64:#define __UINT8_TYPE__ unsigned char
+// PPC64:#define __UINTMAX_C_SUFFIX__ UL
+// PPC64:#define __UINTMAX_MAX__ 18446744073709551615UL
 // PPC64:#define __UINTMAX_TYPE__ long unsigned int
+// PPC64:#define __UINTMAX_WIDTH__ 64
+// PPC64:#define __UINTPTR_MAX__ 18446744073709551615UL
+// PPC64:#define __UINTPTR_TYPE__ long unsigned int
+// PPC64:#define __UINTPTR_WIDTH__ 64
+// PPC64:#define __UINT_FAST16_MAX__ 65535
+// PPC64:#define __UINT_FAST16_TYPE__ unsigned short
+// PPC64:#define __UINT_FAST32_MAX__ 4294967295U
+// PPC64:#define __UINT_FAST32_TYPE__ unsigned int
+// PPC64:#define __UINT_FAST64_MAX__ 18446744073709551615UL
+// PPC64:#define __UINT_FAST64_TYPE__ long unsigned int
+// PPC64:#define __UINT_FAST8_MAX__ 255
+// PPC64:#define __UINT_FAST8_TYPE__ unsigned char
+// PPC64:#define __UINT_LEAST16_MAX__ 65535
+// PPC64:#define __UINT_LEAST16_TYPE__ unsigned short
+// PPC64:#define __UINT_LEAST32_MAX__ 4294967295U
+// PPC64:#define __UINT_LEAST32_TYPE__ unsigned int
+// PPC64:#define __UINT_LEAST64_MAX__ 18446744073709551615UL
+// PPC64:#define __UINT_LEAST64_TYPE__ long unsigned int
+// PPC64:#define __UINT_LEAST8_MAX__ 255
+// PPC64:#define __UINT_LEAST8_TYPE__ unsigned char
 // PPC64:#define __USER_LABEL_PREFIX__ _
 // PPC64:#define __WCHAR_MAX__ 2147483647
 // PPC64:#define __WCHAR_TYPE__ int
@@ -1929,6 +4344,7 @@
 // PPC64LE:#define _ARCH_PWR6 1
 // PPC64LE:#define _ARCH_PWR6X 1
 // PPC64LE:#define _ARCH_PWR7 1
+// PPC64LE:#define _CALL_ELF 2
 // PPC64LE:#define _LITTLE_ENDIAN 1
 // PPC64LE:#define _LP64 1
 // PPC64LE:#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
@@ -1965,16 +4381,69 @@
 // PPC64LE:#define __FLT_MIN_EXP__ (-125)
 // PPC64LE:#define __FLT_MIN__ 1.17549435e-38F
 // PPC64LE:#define __FLT_RADIX__ 2
+// PPC64LE:#define __INT16_C_SUFFIX__ {{$}}
+// PPC64LE:#define __INT16_FMTd__ "hd"
+// PPC64LE:#define __INT16_FMTi__ "hi"
+// PPC64LE:#define __INT16_MAX__ 32767
 // PPC64LE:#define __INT16_TYPE__ short
+// PPC64LE:#define __INT32_C_SUFFIX__ {{$}}
+// PPC64LE:#define __INT32_FMTd__ "d"
+// PPC64LE:#define __INT32_FMTi__ "i"
+// PPC64LE:#define __INT32_MAX__ 2147483647
 // PPC64LE:#define __INT32_TYPE__ int
 // PPC64LE:#define __INT64_C_SUFFIX__ L
+// PPC64LE:#define __INT64_FMTd__ "ld"
+// PPC64LE:#define __INT64_FMTi__ "li"
+// PPC64LE:#define __INT64_MAX__ 9223372036854775807L
 // PPC64LE:#define __INT64_TYPE__ long int
-// PPC64LE:#define __INT8_TYPE__ char
+// PPC64LE:#define __INT8_C_SUFFIX__ {{$}}
+// PPC64LE:#define __INT8_FMTd__ "hhd"
+// PPC64LE:#define __INT8_FMTi__ "hhi"
+// PPC64LE:#define __INT8_MAX__ 127
+// PPC64LE:#define __INT8_TYPE__ signed char
+// PPC64LE:#define __INTMAX_C_SUFFIX__ L
+// PPC64LE:#define __INTMAX_FMTd__ "ld"
+// PPC64LE:#define __INTMAX_FMTi__ "li"
 // PPC64LE:#define __INTMAX_MAX__ 9223372036854775807L
 // PPC64LE:#define __INTMAX_TYPE__ long int
 // PPC64LE:#define __INTMAX_WIDTH__ 64
+// PPC64LE:#define __INTPTR_FMTd__ "ld"
+// PPC64LE:#define __INTPTR_FMTi__ "li"
+// PPC64LE:#define __INTPTR_MAX__ 9223372036854775807L
 // PPC64LE:#define __INTPTR_TYPE__ long int
 // PPC64LE:#define __INTPTR_WIDTH__ 64
+// PPC64LE:#define __INT_FAST16_FMTd__ "hd"
+// PPC64LE:#define __INT_FAST16_FMTi__ "hi"
+// PPC64LE:#define __INT_FAST16_MAX__ 32767
+// PPC64LE:#define __INT_FAST16_TYPE__ short
+// PPC64LE:#define __INT_FAST32_FMTd__ "d"
+// PPC64LE:#define __INT_FAST32_FMTi__ "i"
+// PPC64LE:#define __INT_FAST32_MAX__ 2147483647
+// PPC64LE:#define __INT_FAST32_TYPE__ int
+// PPC64LE:#define __INT_FAST64_FMTd__ "ld"
+// PPC64LE:#define __INT_FAST64_FMTi__ "li"
+// PPC64LE:#define __INT_FAST64_MAX__ 9223372036854775807L
+// PPC64LE:#define __INT_FAST64_TYPE__ long int
+// PPC64LE:#define __INT_FAST8_FMTd__ "hhd"
+// PPC64LE:#define __INT_FAST8_FMTi__ "hhi"
+// PPC64LE:#define __INT_FAST8_MAX__ 127
+// PPC64LE:#define __INT_FAST8_TYPE__ signed char
+// PPC64LE:#define __INT_LEAST16_FMTd__ "hd"
+// PPC64LE:#define __INT_LEAST16_FMTi__ "hi"
+// PPC64LE:#define __INT_LEAST16_MAX__ 32767
+// PPC64LE:#define __INT_LEAST16_TYPE__ short
+// PPC64LE:#define __INT_LEAST32_FMTd__ "d"
+// PPC64LE:#define __INT_LEAST32_FMTi__ "i"
+// PPC64LE:#define __INT_LEAST32_MAX__ 2147483647
+// PPC64LE:#define __INT_LEAST32_TYPE__ int
+// PPC64LE:#define __INT_LEAST64_FMTd__ "ld"
+// PPC64LE:#define __INT_LEAST64_FMTi__ "li"
+// PPC64LE:#define __INT_LEAST64_MAX__ 9223372036854775807L
+// PPC64LE:#define __INT_LEAST64_TYPE__ long int
+// PPC64LE:#define __INT_LEAST8_FMTd__ "hhd"
+// PPC64LE:#define __INT_LEAST8_FMTi__ "hhi"
+// PPC64LE:#define __INT_LEAST8_MAX__ 127
+// PPC64LE:#define __INT_LEAST8_TYPE__ signed char
 // PPC64LE:#define __INT_MAX__ 2147483647
 // PPC64LE:#define __LDBL_DENORM_MIN__ 4.94065645841246544176568792868221e-324L
 // PPC64LE:#define __LDBL_DIG__ 31
@@ -2004,6 +4473,7 @@
 // PPC64LE:#define __REGISTER_PREFIX__ 
 // PPC64LE:#define __SCHAR_MAX__ 127
 // PPC64LE:#define __SHRT_MAX__ 32767
+// PPC64LE:#define __SIG_ATOMIC_MAX__ 2147483647
 // PPC64LE:#define __SIG_ATOMIC_WIDTH__ 32
 // PPC64LE:#define __SIZEOF_DOUBLE__ 8
 // PPC64LE:#define __SIZEOF_FLOAT__ 4
@@ -2020,7 +4490,41 @@
 // PPC64LE:#define __SIZE_MAX__ 18446744073709551615UL
 // PPC64LE:#define __SIZE_TYPE__ long unsigned int
 // PPC64LE:#define __SIZE_WIDTH__ 64
+// PPC64LE:#define __UINT16_C_SUFFIX__ {{$}}
+// PPC64LE:#define __UINT16_MAX__ 65535
+// PPC64LE:#define __UINT16_TYPE__ unsigned short
+// PPC64LE:#define __UINT32_C_SUFFIX__ U
+// PPC64LE:#define __UINT32_MAX__ 4294967295U
+// PPC64LE:#define __UINT32_TYPE__ unsigned int
+// PPC64LE:#define __UINT64_C_SUFFIX__ UL
+// PPC64LE:#define __UINT64_MAX__ 18446744073709551615UL
+// PPC64LE:#define __UINT64_TYPE__ long unsigned int
+// PPC64LE:#define __UINT8_C_SUFFIX__ {{$}}
+// PPC64LE:#define __UINT8_MAX__ 255
+// PPC64LE:#define __UINT8_TYPE__ unsigned char
+// PPC64LE:#define __UINTMAX_C_SUFFIX__ UL
+// PPC64LE:#define __UINTMAX_MAX__ 18446744073709551615UL
 // PPC64LE:#define __UINTMAX_TYPE__ long unsigned int
+// PPC64LE:#define __UINTMAX_WIDTH__ 64
+// PPC64LE:#define __UINTPTR_MAX__ 18446744073709551615UL
+// PPC64LE:#define __UINTPTR_TYPE__ long unsigned int
+// PPC64LE:#define __UINTPTR_WIDTH__ 64
+// PPC64LE:#define __UINT_FAST16_MAX__ 65535
+// PPC64LE:#define __UINT_FAST16_TYPE__ unsigned short
+// PPC64LE:#define __UINT_FAST32_MAX__ 4294967295U
+// PPC64LE:#define __UINT_FAST32_TYPE__ unsigned int
+// PPC64LE:#define __UINT_FAST64_MAX__ 18446744073709551615UL
+// PPC64LE:#define __UINT_FAST64_TYPE__ long unsigned int
+// PPC64LE:#define __UINT_FAST8_MAX__ 255
+// PPC64LE:#define __UINT_FAST8_TYPE__ unsigned char
+// PPC64LE:#define __UINT_LEAST16_MAX__ 65535
+// PPC64LE:#define __UINT_LEAST16_TYPE__ unsigned short
+// PPC64LE:#define __UINT_LEAST32_MAX__ 4294967295U
+// PPC64LE:#define __UINT_LEAST32_TYPE__ unsigned int
+// PPC64LE:#define __UINT_LEAST64_MAX__ 18446744073709551615UL
+// PPC64LE:#define __UINT_LEAST64_TYPE__ long unsigned int
+// PPC64LE:#define __UINT_LEAST8_MAX__ 255
+// PPC64LE:#define __UINT_LEAST8_TYPE__ unsigned char
 // PPC64LE:#define __USER_LABEL_PREFIX__ _
 // PPC64LE:#define __WCHAR_MAX__ 2147483647
 // PPC64LE:#define __WCHAR_TYPE__ int
@@ -2190,6 +4694,34 @@
 // PPCPOWER7:#define _ARCH_PWR6X 1
 // PPCPOWER7:#define _ARCH_PWR7 1
 //
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-cpu pwr8 -fno-signed-char < /dev/null | FileCheck -check-prefix PPCPWR8 %s
+//
+// PPCPWR8:#define _ARCH_PPC 1
+// PPCPWR8:#define _ARCH_PPC64 1
+// PPCPWR8:#define _ARCH_PPCGR 1
+// PPCPWR8:#define _ARCH_PPCSQ 1
+// PPCPWR8:#define _ARCH_PWR4 1
+// PPCPWR8:#define _ARCH_PWR5 1
+// PPCPWR8:#define _ARCH_PWR5X 1
+// PPCPWR8:#define _ARCH_PWR6 1
+// PPCPWR8:#define _ARCH_PWR6X 1
+// PPCPWR8:#define _ARCH_PWR7 1
+// PPCPWR8:#define _ARCH_PWR8 1
+//
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-cpu power8 -fno-signed-char < /dev/null | FileCheck -check-prefix PPCPOWER8 %s
+//
+// PPCPOWER8:#define _ARCH_PPC 1
+// PPCPOWER8:#define _ARCH_PPC64 1
+// PPCPOWER8:#define _ARCH_PPCGR 1
+// PPCPOWER8:#define _ARCH_PPCSQ 1
+// PPCPOWER8:#define _ARCH_PWR4 1
+// PPCPOWER8:#define _ARCH_PWR5 1
+// PPCPOWER8:#define _ARCH_PWR5X 1
+// PPCPOWER8:#define _ARCH_PWR6 1
+// PPCPOWER8:#define _ARCH_PWR6X 1
+// PPCPOWER8:#define _ARCH_PWR7 1
+// PPCPOWER8:#define _ARCH_PWR8 1
+//
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-unknown-linux-gnu -fno-signed-char < /dev/null | FileCheck -check-prefix PPC64-LINUX %s
 //
 // PPC64-LINUX:#define _ARCH_PPC 1
@@ -2231,16 +4763,69 @@
 // PPC64-LINUX:#define __FLT_MIN_EXP__ (-125)
 // PPC64-LINUX:#define __FLT_MIN__ 1.17549435e-38F
 // PPC64-LINUX:#define __FLT_RADIX__ 2
+// PPC64-LINUX:#define __INT16_C_SUFFIX__ {{$}}
+// PPC64-LINUX:#define __INT16_FMTd__ "hd"
+// PPC64-LINUX:#define __INT16_FMTi__ "hi"
+// PPC64-LINUX:#define __INT16_MAX__ 32767
 // PPC64-LINUX:#define __INT16_TYPE__ short
+// PPC64-LINUX:#define __INT32_C_SUFFIX__ {{$}}
+// PPC64-LINUX:#define __INT32_FMTd__ "d"
+// PPC64-LINUX:#define __INT32_FMTi__ "i"
+// PPC64-LINUX:#define __INT32_MAX__ 2147483647
 // PPC64-LINUX:#define __INT32_TYPE__ int
 // PPC64-LINUX:#define __INT64_C_SUFFIX__ L
+// PPC64-LINUX:#define __INT64_FMTd__ "ld"
+// PPC64-LINUX:#define __INT64_FMTi__ "li"
+// PPC64-LINUX:#define __INT64_MAX__ 9223372036854775807L
 // PPC64-LINUX:#define __INT64_TYPE__ long int
-// PPC64-LINUX:#define __INT8_TYPE__ char
+// PPC64-LINUX:#define __INT8_C_SUFFIX__ {{$}}
+// PPC64-LINUX:#define __INT8_FMTd__ "hhd"
+// PPC64-LINUX:#define __INT8_FMTi__ "hhi"
+// PPC64-LINUX:#define __INT8_MAX__ 127
+// PPC64-LINUX:#define __INT8_TYPE__ signed char
+// PPC64-LINUX:#define __INTMAX_C_SUFFIX__ L
+// PPC64-LINUX:#define __INTMAX_FMTd__ "ld"
+// PPC64-LINUX:#define __INTMAX_FMTi__ "li"
 // PPC64-LINUX:#define __INTMAX_MAX__ 9223372036854775807L
 // PPC64-LINUX:#define __INTMAX_TYPE__ long int
 // PPC64-LINUX:#define __INTMAX_WIDTH__ 64
+// PPC64-LINUX:#define __INTPTR_FMTd__ "ld"
+// PPC64-LINUX:#define __INTPTR_FMTi__ "li"
+// PPC64-LINUX:#define __INTPTR_MAX__ 9223372036854775807L
 // PPC64-LINUX:#define __INTPTR_TYPE__ long int
 // PPC64-LINUX:#define __INTPTR_WIDTH__ 64
+// PPC64-LINUX:#define __INT_FAST16_FMTd__ "hd"
+// PPC64-LINUX:#define __INT_FAST16_FMTi__ "hi"
+// PPC64-LINUX:#define __INT_FAST16_MAX__ 32767
+// PPC64-LINUX:#define __INT_FAST16_TYPE__ short
+// PPC64-LINUX:#define __INT_FAST32_FMTd__ "d"
+// PPC64-LINUX:#define __INT_FAST32_FMTi__ "i"
+// PPC64-LINUX:#define __INT_FAST32_MAX__ 2147483647
+// PPC64-LINUX:#define __INT_FAST32_TYPE__ int
+// PPC64-LINUX:#define __INT_FAST64_FMTd__ "ld"
+// PPC64-LINUX:#define __INT_FAST64_FMTi__ "li"
+// PPC64-LINUX:#define __INT_FAST64_MAX__ 9223372036854775807L
+// PPC64-LINUX:#define __INT_FAST64_TYPE__ long int
+// PPC64-LINUX:#define __INT_FAST8_FMTd__ "hhd"
+// PPC64-LINUX:#define __INT_FAST8_FMTi__ "hhi"
+// PPC64-LINUX:#define __INT_FAST8_MAX__ 127
+// PPC64-LINUX:#define __INT_FAST8_TYPE__ signed char
+// PPC64-LINUX:#define __INT_LEAST16_FMTd__ "hd"
+// PPC64-LINUX:#define __INT_LEAST16_FMTi__ "hi"
+// PPC64-LINUX:#define __INT_LEAST16_MAX__ 32767
+// PPC64-LINUX:#define __INT_LEAST16_TYPE__ short
+// PPC64-LINUX:#define __INT_LEAST32_FMTd__ "d"
+// PPC64-LINUX:#define __INT_LEAST32_FMTi__ "i"
+// PPC64-LINUX:#define __INT_LEAST32_MAX__ 2147483647
+// PPC64-LINUX:#define __INT_LEAST32_TYPE__ int
+// PPC64-LINUX:#define __INT_LEAST64_FMTd__ "ld"
+// PPC64-LINUX:#define __INT_LEAST64_FMTi__ "li"
+// PPC64-LINUX:#define __INT_LEAST64_MAX__ 9223372036854775807L
+// PPC64-LINUX:#define __INT_LEAST64_TYPE__ long int
+// PPC64-LINUX:#define __INT_LEAST8_FMTd__ "hhd"
+// PPC64-LINUX:#define __INT_LEAST8_FMTi__ "hhi"
+// PPC64-LINUX:#define __INT_LEAST8_MAX__ 127
+// PPC64-LINUX:#define __INT_LEAST8_TYPE__ signed char
 // PPC64-LINUX:#define __INT_MAX__ 2147483647
 // PPC64-LINUX:#define __LDBL_DENORM_MIN__ 4.94065645841246544176568792868221e-324L
 // PPC64-LINUX:#define __LDBL_DIG__ 31
@@ -2269,6 +4854,7 @@
 // PPC64-LINUX:#define __REGISTER_PREFIX__
 // PPC64-LINUX:#define __SCHAR_MAX__ 127
 // PPC64-LINUX:#define __SHRT_MAX__ 32767
+// PPC64-LINUX:#define __SIG_ATOMIC_MAX__ 2147483647
 // PPC64-LINUX:#define __SIG_ATOMIC_WIDTH__ 32
 // PPC64-LINUX:#define __SIZEOF_DOUBLE__ 8
 // PPC64-LINUX:#define __SIZEOF_FLOAT__ 4
@@ -2285,7 +4871,41 @@
 // PPC64-LINUX:#define __SIZE_MAX__ 18446744073709551615UL
 // PPC64-LINUX:#define __SIZE_TYPE__ long unsigned int
 // PPC64-LINUX:#define __SIZE_WIDTH__ 64
+// PPC64-LINUX:#define __UINT16_C_SUFFIX__ {{$}}
+// PPC64-LINUX:#define __UINT16_MAX__ 65535
+// PPC64-LINUX:#define __UINT16_TYPE__ unsigned short
+// PPC64-LINUX:#define __UINT32_C_SUFFIX__ U
+// PPC64-LINUX:#define __UINT32_MAX__ 4294967295U
+// PPC64-LINUX:#define __UINT32_TYPE__ unsigned int
+// PPC64-LINUX:#define __UINT64_C_SUFFIX__ UL
+// PPC64-LINUX:#define __UINT64_MAX__ 18446744073709551615UL
+// PPC64-LINUX:#define __UINT64_TYPE__ long unsigned int
+// PPC64-LINUX:#define __UINT8_C_SUFFIX__ {{$}}
+// PPC64-LINUX:#define __UINT8_MAX__ 255
+// PPC64-LINUX:#define __UINT8_TYPE__ unsigned char
+// PPC64-LINUX:#define __UINTMAX_C_SUFFIX__ UL
+// PPC64-LINUX:#define __UINTMAX_MAX__ 18446744073709551615UL
 // PPC64-LINUX:#define __UINTMAX_TYPE__ long unsigned int
+// PPC64-LINUX:#define __UINTMAX_WIDTH__ 64
+// PPC64-LINUX:#define __UINTPTR_MAX__ 18446744073709551615UL
+// PPC64-LINUX:#define __UINTPTR_TYPE__ long unsigned int
+// PPC64-LINUX:#define __UINTPTR_WIDTH__ 64
+// PPC64-LINUX:#define __UINT_FAST16_MAX__ 65535
+// PPC64-LINUX:#define __UINT_FAST16_TYPE__ unsigned short
+// PPC64-LINUX:#define __UINT_FAST32_MAX__ 4294967295U
+// PPC64-LINUX:#define __UINT_FAST32_TYPE__ unsigned int
+// PPC64-LINUX:#define __UINT_FAST64_MAX__ 18446744073709551615UL
+// PPC64-LINUX:#define __UINT_FAST64_TYPE__ long unsigned int
+// PPC64-LINUX:#define __UINT_FAST8_MAX__ 255
+// PPC64-LINUX:#define __UINT_FAST8_TYPE__ unsigned char
+// PPC64-LINUX:#define __UINT_LEAST16_MAX__ 65535
+// PPC64-LINUX:#define __UINT_LEAST16_TYPE__ unsigned short
+// PPC64-LINUX:#define __UINT_LEAST32_MAX__ 4294967295U
+// PPC64-LINUX:#define __UINT_LEAST32_TYPE__ unsigned int
+// PPC64-LINUX:#define __UINT_LEAST64_MAX__ 18446744073709551615UL
+// PPC64-LINUX:#define __UINT_LEAST64_TYPE__ long unsigned int
+// PPC64-LINUX:#define __UINT_LEAST8_MAX__ 255
+// PPC64-LINUX:#define __UINT_LEAST8_TYPE__ unsigned char
 // PPC64-LINUX:#define __USER_LABEL_PREFIX__
 // PPC64-LINUX:#define __WCHAR_MAX__ 2147483647
 // PPC64-LINUX:#define __WCHAR_TYPE__ int
@@ -2338,16 +4958,69 @@
 // PPC:#define __FLT_MIN_EXP__ (-125)
 // PPC:#define __FLT_MIN__ 1.17549435e-38F
 // PPC:#define __FLT_RADIX__ 2
+// PPC:#define __INT16_C_SUFFIX__ {{$}}
+// PPC:#define __INT16_FMTd__ "hd"
+// PPC:#define __INT16_FMTi__ "hi"
+// PPC:#define __INT16_MAX__ 32767
 // PPC:#define __INT16_TYPE__ short
+// PPC:#define __INT32_C_SUFFIX__ {{$}}
+// PPC:#define __INT32_FMTd__ "d"
+// PPC:#define __INT32_FMTi__ "i"
+// PPC:#define __INT32_MAX__ 2147483647
 // PPC:#define __INT32_TYPE__ int
 // PPC:#define __INT64_C_SUFFIX__ LL
+// PPC:#define __INT64_FMTd__ "lld"
+// PPC:#define __INT64_FMTi__ "lli"
+// PPC:#define __INT64_MAX__ 9223372036854775807LL
 // PPC:#define __INT64_TYPE__ long long int
-// PPC:#define __INT8_TYPE__ char
+// PPC:#define __INT8_C_SUFFIX__ {{$}}
+// PPC:#define __INT8_FMTd__ "hhd"
+// PPC:#define __INT8_FMTi__ "hhi"
+// PPC:#define __INT8_MAX__ 127
+// PPC:#define __INT8_TYPE__ signed char
+// PPC:#define __INTMAX_C_SUFFIX__ LL
+// PPC:#define __INTMAX_FMTd__ "lld"
+// PPC:#define __INTMAX_FMTi__ "lli"
 // PPC:#define __INTMAX_MAX__ 9223372036854775807LL
 // PPC:#define __INTMAX_TYPE__ long long int
 // PPC:#define __INTMAX_WIDTH__ 64
+// PPC:#define __INTPTR_FMTd__ "ld"
+// PPC:#define __INTPTR_FMTi__ "li"
+// PPC:#define __INTPTR_MAX__ 2147483647L
 // PPC:#define __INTPTR_TYPE__ long int
 // PPC:#define __INTPTR_WIDTH__ 32
+// PPC:#define __INT_FAST16_FMTd__ "hd"
+// PPC:#define __INT_FAST16_FMTi__ "hi"
+// PPC:#define __INT_FAST16_MAX__ 32767
+// PPC:#define __INT_FAST16_TYPE__ short
+// PPC:#define __INT_FAST32_FMTd__ "d"
+// PPC:#define __INT_FAST32_FMTi__ "i"
+// PPC:#define __INT_FAST32_MAX__ 2147483647
+// PPC:#define __INT_FAST32_TYPE__ int
+// PPC:#define __INT_FAST64_FMTd__ "lld"
+// PPC:#define __INT_FAST64_FMTi__ "lli"
+// PPC:#define __INT_FAST64_MAX__ 9223372036854775807LL
+// PPC:#define __INT_FAST64_TYPE__ long long int
+// PPC:#define __INT_FAST8_FMTd__ "hhd"
+// PPC:#define __INT_FAST8_FMTi__ "hhi"
+// PPC:#define __INT_FAST8_MAX__ 127
+// PPC:#define __INT_FAST8_TYPE__ signed char
+// PPC:#define __INT_LEAST16_FMTd__ "hd"
+// PPC:#define __INT_LEAST16_FMTi__ "hi"
+// PPC:#define __INT_LEAST16_MAX__ 32767
+// PPC:#define __INT_LEAST16_TYPE__ short
+// PPC:#define __INT_LEAST32_FMTd__ "d"
+// PPC:#define __INT_LEAST32_FMTi__ "i"
+// PPC:#define __INT_LEAST32_MAX__ 2147483647
+// PPC:#define __INT_LEAST32_TYPE__ int
+// PPC:#define __INT_LEAST64_FMTd__ "lld"
+// PPC:#define __INT_LEAST64_FMTi__ "lli"
+// PPC:#define __INT_LEAST64_MAX__ 9223372036854775807LL
+// PPC:#define __INT_LEAST64_TYPE__ long long int
+// PPC:#define __INT_LEAST8_FMTd__ "hhd"
+// PPC:#define __INT_LEAST8_FMTi__ "hhi"
+// PPC:#define __INT_LEAST8_MAX__ 127
+// PPC:#define __INT_LEAST8_TYPE__ signed char
 // PPC:#define __INT_MAX__ 2147483647
 // PPC:#define __LDBL_DENORM_MIN__ 4.94065645841246544176568792868221e-324L
 // PPC:#define __LDBL_DIG__ 31
@@ -2375,6 +5048,7 @@
 // PPC:#define __REGISTER_PREFIX__ 
 // PPC:#define __SCHAR_MAX__ 127
 // PPC:#define __SHRT_MAX__ 32767
+// PPC:#define __SIG_ATOMIC_MAX__ 2147483647
 // PPC:#define __SIG_ATOMIC_WIDTH__ 32
 // PPC:#define __SIZEOF_DOUBLE__ 8
 // PPC:#define __SIZEOF_FLOAT__ 4
@@ -2391,7 +5065,41 @@
 // PPC:#define __SIZE_MAX__ 4294967295U
 // PPC:#define __SIZE_TYPE__ long unsigned int
 // PPC:#define __SIZE_WIDTH__ 32
+// PPC:#define __UINT16_C_SUFFIX__ {{$}}
+// PPC:#define __UINT16_MAX__ 65535
+// PPC:#define __UINT16_TYPE__ unsigned short
+// PPC:#define __UINT32_C_SUFFIX__ U
+// PPC:#define __UINT32_MAX__ 4294967295U
+// PPC:#define __UINT32_TYPE__ unsigned int
+// PPC:#define __UINT64_C_SUFFIX__ ULL
+// PPC:#define __UINT64_MAX__ 18446744073709551615ULL
+// PPC:#define __UINT64_TYPE__ long long unsigned int
+// PPC:#define __UINT8_C_SUFFIX__ {{$}}
+// PPC:#define __UINT8_MAX__ 255
+// PPC:#define __UINT8_TYPE__ unsigned char
+// PPC:#define __UINTMAX_C_SUFFIX__ ULL
+// PPC:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // PPC:#define __UINTMAX_TYPE__ long long unsigned int
+// PPC:#define __UINTMAX_WIDTH__ 64
+// PPC:#define __UINTPTR_MAX__ 4294967295U
+// PPC:#define __UINTPTR_TYPE__ long unsigned int
+// PPC:#define __UINTPTR_WIDTH__ 32
+// PPC:#define __UINT_FAST16_MAX__ 65535
+// PPC:#define __UINT_FAST16_TYPE__ unsigned short
+// PPC:#define __UINT_FAST32_MAX__ 4294967295U
+// PPC:#define __UINT_FAST32_TYPE__ unsigned int
+// PPC:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// PPC:#define __UINT_FAST64_TYPE__ long long unsigned int
+// PPC:#define __UINT_FAST8_MAX__ 255
+// PPC:#define __UINT_FAST8_TYPE__ unsigned char
+// PPC:#define __UINT_LEAST16_MAX__ 65535
+// PPC:#define __UINT_LEAST16_TYPE__ unsigned short
+// PPC:#define __UINT_LEAST32_MAX__ 4294967295U
+// PPC:#define __UINT_LEAST32_TYPE__ unsigned int
+// PPC:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// PPC:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// PPC:#define __UINT_LEAST8_MAX__ 255
+// PPC:#define __UINT_LEAST8_TYPE__ unsigned char
 // PPC:#define __USER_LABEL_PREFIX__ _
 // PPC:#define __WCHAR_MAX__ 2147483647
 // PPC:#define __WCHAR_TYPE__ int
@@ -2440,16 +5148,69 @@
 // PPC-LINUX:#define __FLT_MIN_EXP__ (-125)
 // PPC-LINUX:#define __FLT_MIN__ 1.17549435e-38F
 // PPC-LINUX:#define __FLT_RADIX__ 2
+// PPC-LINUX:#define __INT16_C_SUFFIX__ {{$}}
+// PPC-LINUX:#define __INT16_FMTd__ "hd"
+// PPC-LINUX:#define __INT16_FMTi__ "hi"
+// PPC-LINUX:#define __INT16_MAX__ 32767
 // PPC-LINUX:#define __INT16_TYPE__ short
+// PPC-LINUX:#define __INT32_C_SUFFIX__ {{$}}
+// PPC-LINUX:#define __INT32_FMTd__ "d"
+// PPC-LINUX:#define __INT32_FMTi__ "i"
+// PPC-LINUX:#define __INT32_MAX__ 2147483647
 // PPC-LINUX:#define __INT32_TYPE__ int
 // PPC-LINUX:#define __INT64_C_SUFFIX__ LL
+// PPC-LINUX:#define __INT64_FMTd__ "lld"
+// PPC-LINUX:#define __INT64_FMTi__ "lli"
+// PPC-LINUX:#define __INT64_MAX__ 9223372036854775807LL
 // PPC-LINUX:#define __INT64_TYPE__ long long int
-// PPC-LINUX:#define __INT8_TYPE__ char
+// PPC-LINUX:#define __INT8_C_SUFFIX__ {{$}}
+// PPC-LINUX:#define __INT8_FMTd__ "hhd"
+// PPC-LINUX:#define __INT8_FMTi__ "hhi"
+// PPC-LINUX:#define __INT8_MAX__ 127
+// PPC-LINUX:#define __INT8_TYPE__ signed char
+// PPC-LINUX:#define __INTMAX_C_SUFFIX__ LL
+// PPC-LINUX:#define __INTMAX_FMTd__ "lld"
+// PPC-LINUX:#define __INTMAX_FMTi__ "lli"
 // PPC-LINUX:#define __INTMAX_MAX__ 9223372036854775807LL
 // PPC-LINUX:#define __INTMAX_TYPE__ long long int
 // PPC-LINUX:#define __INTMAX_WIDTH__ 64
+// PPC-LINUX:#define __INTPTR_FMTd__ "d"
+// PPC-LINUX:#define __INTPTR_FMTi__ "i"
+// PPC-LINUX:#define __INTPTR_MAX__ 2147483647
 // PPC-LINUX:#define __INTPTR_TYPE__ int
 // PPC-LINUX:#define __INTPTR_WIDTH__ 32
+// PPC-LINUX:#define __INT_FAST16_FMTd__ "hd"
+// PPC-LINUX:#define __INT_FAST16_FMTi__ "hi"
+// PPC-LINUX:#define __INT_FAST16_MAX__ 32767
+// PPC-LINUX:#define __INT_FAST16_TYPE__ short
+// PPC-LINUX:#define __INT_FAST32_FMTd__ "d"
+// PPC-LINUX:#define __INT_FAST32_FMTi__ "i"
+// PPC-LINUX:#define __INT_FAST32_MAX__ 2147483647
+// PPC-LINUX:#define __INT_FAST32_TYPE__ int
+// PPC-LINUX:#define __INT_FAST64_FMTd__ "lld"
+// PPC-LINUX:#define __INT_FAST64_FMTi__ "lli"
+// PPC-LINUX:#define __INT_FAST64_MAX__ 9223372036854775807LL
+// PPC-LINUX:#define __INT_FAST64_TYPE__ long long int
+// PPC-LINUX:#define __INT_FAST8_FMTd__ "hhd"
+// PPC-LINUX:#define __INT_FAST8_FMTi__ "hhi"
+// PPC-LINUX:#define __INT_FAST8_MAX__ 127
+// PPC-LINUX:#define __INT_FAST8_TYPE__ signed char
+// PPC-LINUX:#define __INT_LEAST16_FMTd__ "hd"
+// PPC-LINUX:#define __INT_LEAST16_FMTi__ "hi"
+// PPC-LINUX:#define __INT_LEAST16_MAX__ 32767
+// PPC-LINUX:#define __INT_LEAST16_TYPE__ short
+// PPC-LINUX:#define __INT_LEAST32_FMTd__ "d"
+// PPC-LINUX:#define __INT_LEAST32_FMTi__ "i"
+// PPC-LINUX:#define __INT_LEAST32_MAX__ 2147483647
+// PPC-LINUX:#define __INT_LEAST32_TYPE__ int
+// PPC-LINUX:#define __INT_LEAST64_FMTd__ "lld"
+// PPC-LINUX:#define __INT_LEAST64_FMTi__ "lli"
+// PPC-LINUX:#define __INT_LEAST64_MAX__ 9223372036854775807LL
+// PPC-LINUX:#define __INT_LEAST64_TYPE__ long long int
+// PPC-LINUX:#define __INT_LEAST8_FMTd__ "hhd"
+// PPC-LINUX:#define __INT_LEAST8_FMTi__ "hhi"
+// PPC-LINUX:#define __INT_LEAST8_MAX__ 127
+// PPC-LINUX:#define __INT_LEAST8_TYPE__ signed char
 // PPC-LINUX:#define __INT_MAX__ 2147483647
 // PPC-LINUX:#define __LDBL_DENORM_MIN__ 4.94065645841246544176568792868221e-324L
 // PPC-LINUX:#define __LDBL_DIG__ 31
@@ -2477,6 +5238,7 @@
 // PPC-LINUX:#define __REGISTER_PREFIX__
 // PPC-LINUX:#define __SCHAR_MAX__ 127
 // PPC-LINUX:#define __SHRT_MAX__ 32767
+// PPC-LINUX:#define __SIG_ATOMIC_MAX__ 2147483647
 // PPC-LINUX:#define __SIG_ATOMIC_WIDTH__ 32
 // PPC-LINUX:#define __SIZEOF_DOUBLE__ 8
 // PPC-LINUX:#define __SIZEOF_FLOAT__ 4
@@ -2493,7 +5255,41 @@
 // PPC-LINUX:#define __SIZE_MAX__ 4294967295U
 // PPC-LINUX:#define __SIZE_TYPE__ unsigned int
 // PPC-LINUX:#define __SIZE_WIDTH__ 32
+// PPC-LINUX:#define __UINT16_C_SUFFIX__ {{$}}
+// PPC-LINUX:#define __UINT16_MAX__ 65535
+// PPC-LINUX:#define __UINT16_TYPE__ unsigned short
+// PPC-LINUX:#define __UINT32_C_SUFFIX__ U
+// PPC-LINUX:#define __UINT32_MAX__ 4294967295U
+// PPC-LINUX:#define __UINT32_TYPE__ unsigned int
+// PPC-LINUX:#define __UINT64_C_SUFFIX__ ULL
+// PPC-LINUX:#define __UINT64_MAX__ 18446744073709551615ULL
+// PPC-LINUX:#define __UINT64_TYPE__ long long unsigned int
+// PPC-LINUX:#define __UINT8_C_SUFFIX__ {{$}}
+// PPC-LINUX:#define __UINT8_MAX__ 255
+// PPC-LINUX:#define __UINT8_TYPE__ unsigned char
+// PPC-LINUX:#define __UINTMAX_C_SUFFIX__ ULL
+// PPC-LINUX:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // PPC-LINUX:#define __UINTMAX_TYPE__ long long unsigned int
+// PPC-LINUX:#define __UINTMAX_WIDTH__ 64
+// PPC-LINUX:#define __UINTPTR_MAX__ 4294967295U
+// PPC-LINUX:#define __UINTPTR_TYPE__ unsigned int
+// PPC-LINUX:#define __UINTPTR_WIDTH__ 32
+// PPC-LINUX:#define __UINT_FAST16_MAX__ 65535
+// PPC-LINUX:#define __UINT_FAST16_TYPE__ unsigned short
+// PPC-LINUX:#define __UINT_FAST32_MAX__ 4294967295U
+// PPC-LINUX:#define __UINT_FAST32_TYPE__ unsigned int
+// PPC-LINUX:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// PPC-LINUX:#define __UINT_FAST64_TYPE__ long long unsigned int
+// PPC-LINUX:#define __UINT_FAST8_MAX__ 255
+// PPC-LINUX:#define __UINT_FAST8_TYPE__ unsigned char
+// PPC-LINUX:#define __UINT_LEAST16_MAX__ 65535
+// PPC-LINUX:#define __UINT_LEAST16_TYPE__ unsigned short
+// PPC-LINUX:#define __UINT_LEAST32_MAX__ 4294967295U
+// PPC-LINUX:#define __UINT_LEAST32_TYPE__ unsigned int
+// PPC-LINUX:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// PPC-LINUX:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// PPC-LINUX:#define __UINT_LEAST8_MAX__ 255
+// PPC-LINUX:#define __UINT_LEAST8_TYPE__ unsigned char
 // PPC-LINUX:#define __USER_LABEL_PREFIX__
 // PPC-LINUX:#define __WCHAR_MAX__ 2147483647
 // PPC-LINUX:#define __WCHAR_TYPE__ int
@@ -2542,16 +5338,69 @@
 // PPC-DARWIN:#define __FLT_MIN_EXP__ (-125)
 // PPC-DARWIN:#define __FLT_MIN__ 1.17549435e-38F
 // PPC-DARWIN:#define __FLT_RADIX__ 2
+// PPC-DARWIN:#define __INT16_C_SUFFIX__ {{$}}
+// PPC-DARWIN:#define __INT16_FMTd__ "hd"
+// PPC-DARWIN:#define __INT16_FMTi__ "hi"
+// PPC-DARWIN:#define __INT16_MAX__ 32767
 // PPC-DARWIN:#define __INT16_TYPE__ short
+// PPC-DARWIN:#define __INT32_C_SUFFIX__ {{$}}
+// PPC-DARWIN:#define __INT32_FMTd__ "d"
+// PPC-DARWIN:#define __INT32_FMTi__ "i"
+// PPC-DARWIN:#define __INT32_MAX__ 2147483647
 // PPC-DARWIN:#define __INT32_TYPE__ int
 // PPC-DARWIN:#define __INT64_C_SUFFIX__ LL
+// PPC-DARWIN:#define __INT64_FMTd__ "lld"
+// PPC-DARWIN:#define __INT64_FMTi__ "lli"
+// PPC-DARWIN:#define __INT64_MAX__ 9223372036854775807LL
 // PPC-DARWIN:#define __INT64_TYPE__ long long int
-// PPC-DARWIN:#define __INT8_TYPE__ char
+// PPC-DARWIN:#define __INT8_C_SUFFIX__ {{$}}
+// PPC-DARWIN:#define __INT8_FMTd__ "hhd"
+// PPC-DARWIN:#define __INT8_FMTi__ "hhi"
+// PPC-DARWIN:#define __INT8_MAX__ 127
+// PPC-DARWIN:#define __INT8_TYPE__ signed char
+// PPC-DARWIN:#define __INTMAX_C_SUFFIX__ LL
+// PPC-DARWIN:#define __INTMAX_FMTd__ "lld"
+// PPC-DARWIN:#define __INTMAX_FMTi__ "lli"
 // PPC-DARWIN:#define __INTMAX_MAX__ 9223372036854775807LL
 // PPC-DARWIN:#define __INTMAX_TYPE__ long long int
 // PPC-DARWIN:#define __INTMAX_WIDTH__ 64
+// PPC-DARWIN:#define __INTPTR_FMTd__ "ld"
+// PPC-DARWIN:#define __INTPTR_FMTi__ "li"
+// PPC-DARWIN:#define __INTPTR_MAX__ 2147483647L
 // PPC-DARWIN:#define __INTPTR_TYPE__ long int
 // PPC-DARWIN:#define __INTPTR_WIDTH__ 32
+// PPC-DARWIN:#define __INT_FAST16_FMTd__ "hd"
+// PPC-DARWIN:#define __INT_FAST16_FMTi__ "hi"
+// PPC-DARWIN:#define __INT_FAST16_MAX__ 32767
+// PPC-DARWIN:#define __INT_FAST16_TYPE__ short
+// PPC-DARWIN:#define __INT_FAST32_FMTd__ "d"
+// PPC-DARWIN:#define __INT_FAST32_FMTi__ "i"
+// PPC-DARWIN:#define __INT_FAST32_MAX__ 2147483647
+// PPC-DARWIN:#define __INT_FAST32_TYPE__ int
+// PPC-DARWIN:#define __INT_FAST64_FMTd__ "lld"
+// PPC-DARWIN:#define __INT_FAST64_FMTi__ "lli"
+// PPC-DARWIN:#define __INT_FAST64_MAX__ 9223372036854775807LL
+// PPC-DARWIN:#define __INT_FAST64_TYPE__ long long int
+// PPC-DARWIN:#define __INT_FAST8_FMTd__ "hhd"
+// PPC-DARWIN:#define __INT_FAST8_FMTi__ "hhi"
+// PPC-DARWIN:#define __INT_FAST8_MAX__ 127
+// PPC-DARWIN:#define __INT_FAST8_TYPE__ signed char
+// PPC-DARWIN:#define __INT_LEAST16_FMTd__ "hd"
+// PPC-DARWIN:#define __INT_LEAST16_FMTi__ "hi"
+// PPC-DARWIN:#define __INT_LEAST16_MAX__ 32767
+// PPC-DARWIN:#define __INT_LEAST16_TYPE__ short
+// PPC-DARWIN:#define __INT_LEAST32_FMTd__ "d"
+// PPC-DARWIN:#define __INT_LEAST32_FMTi__ "i"
+// PPC-DARWIN:#define __INT_LEAST32_MAX__ 2147483647
+// PPC-DARWIN:#define __INT_LEAST32_TYPE__ int
+// PPC-DARWIN:#define __INT_LEAST64_FMTd__ "lld"
+// PPC-DARWIN:#define __INT_LEAST64_FMTi__ "lli"
+// PPC-DARWIN:#define __INT_LEAST64_MAX__ 9223372036854775807LL
+// PPC-DARWIN:#define __INT_LEAST64_TYPE__ long long int
+// PPC-DARWIN:#define __INT_LEAST8_FMTd__ "hhd"
+// PPC-DARWIN:#define __INT_LEAST8_FMTi__ "hhi"
+// PPC-DARWIN:#define __INT_LEAST8_MAX__ 127
+// PPC-DARWIN:#define __INT_LEAST8_TYPE__ signed char
 // PPC-DARWIN:#define __INT_MAX__ 2147483647
 // PPC-DARWIN:#define __LDBL_DENORM_MIN__ 4.94065645841246544176568792868221e-324L
 // PPC-DARWIN:#define __LDBL_DIG__ 31
@@ -2582,6 +5431,7 @@
 // PPC-DARWIN:#define __REGISTER_PREFIX__ 
 // PPC-DARWIN:#define __SCHAR_MAX__ 127
 // PPC-DARWIN:#define __SHRT_MAX__ 32767
+// PPC-DARWIN:#define __SIG_ATOMIC_MAX__ 2147483647
 // PPC-DARWIN:#define __SIG_ATOMIC_WIDTH__ 32
 // PPC-DARWIN:#define __SIZEOF_DOUBLE__ 8
 // PPC-DARWIN:#define __SIZEOF_FLOAT__ 4
@@ -2601,7 +5451,41 @@
 // PPC-DARWIN:#define __STDC_HOSTED__ 0
 // PPC-DARWIN:#define __STDC_VERSION__ 199901L
 // PPC-DARWIN:#define __STDC__ 1
+// PPC-DARWIN:#define __UINT16_C_SUFFIX__ {{$}}
+// PPC-DARWIN:#define __UINT16_MAX__ 65535
+// PPC-DARWIN:#define __UINT16_TYPE__ unsigned short
+// PPC-DARWIN:#define __UINT32_C_SUFFIX__ U
+// PPC-DARWIN:#define __UINT32_MAX__ 4294967295U
+// PPC-DARWIN:#define __UINT32_TYPE__ unsigned int
+// PPC-DARWIN:#define __UINT64_C_SUFFIX__ ULL
+// PPC-DARWIN:#define __UINT64_MAX__ 18446744073709551615ULL
+// PPC-DARWIN:#define __UINT64_TYPE__ long long unsigned int
+// PPC-DARWIN:#define __UINT8_C_SUFFIX__ {{$}}
+// PPC-DARWIN:#define __UINT8_MAX__ 255
+// PPC-DARWIN:#define __UINT8_TYPE__ unsigned char
+// PPC-DARWIN:#define __UINTMAX_C_SUFFIX__ ULL
+// PPC-DARWIN:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // PPC-DARWIN:#define __UINTMAX_TYPE__ long long unsigned int
+// PPC-DARWIN:#define __UINTMAX_WIDTH__ 64
+// PPC-DARWIN:#define __UINTPTR_MAX__ 4294967295U
+// PPC-DARWIN:#define __UINTPTR_TYPE__ long unsigned int
+// PPC-DARWIN:#define __UINTPTR_WIDTH__ 32
+// PPC-DARWIN:#define __UINT_FAST16_MAX__ 65535
+// PPC-DARWIN:#define __UINT_FAST16_TYPE__ unsigned short
+// PPC-DARWIN:#define __UINT_FAST32_MAX__ 4294967295U
+// PPC-DARWIN:#define __UINT_FAST32_TYPE__ unsigned int
+// PPC-DARWIN:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// PPC-DARWIN:#define __UINT_FAST64_TYPE__ long long unsigned int
+// PPC-DARWIN:#define __UINT_FAST8_MAX__ 255
+// PPC-DARWIN:#define __UINT_FAST8_TYPE__ unsigned char
+// PPC-DARWIN:#define __UINT_LEAST16_MAX__ 65535
+// PPC-DARWIN:#define __UINT_LEAST16_TYPE__ unsigned short
+// PPC-DARWIN:#define __UINT_LEAST32_MAX__ 4294967295U
+// PPC-DARWIN:#define __UINT_LEAST32_TYPE__ unsigned int
+// PPC-DARWIN:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// PPC-DARWIN:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// PPC-DARWIN:#define __UINT_LEAST8_MAX__ 255
+// PPC-DARWIN:#define __UINT_LEAST8_TYPE__ unsigned char
 // PPC-DARWIN:#define __USER_LABEL_PREFIX__ _
 // PPC-DARWIN:#define __WCHAR_MAX__ 2147483647
 // PPC-DARWIN:#define __WCHAR_TYPE__ int
@@ -2646,16 +5530,69 @@
 // S390X:#define __FLT_MIN_EXP__ (-125)
 // S390X:#define __FLT_MIN__ 1.17549435e-38F
 // S390X:#define __FLT_RADIX__ 2
+// S390X:#define __INT16_C_SUFFIX__ {{$}}
+// S390X:#define __INT16_FMTd__ "hd"
+// S390X:#define __INT16_FMTi__ "hi"
+// S390X:#define __INT16_MAX__ 32767
 // S390X:#define __INT16_TYPE__ short
+// S390X:#define __INT32_C_SUFFIX__ {{$}}
+// S390X:#define __INT32_FMTd__ "d"
+// S390X:#define __INT32_FMTi__ "i"
+// S390X:#define __INT32_MAX__ 2147483647
 // S390X:#define __INT32_TYPE__ int
-// S390X:#define __INT64_C_SUFFIX__ L
+// S390X:#define __INT64_C_SUFFIX__ LL
+// S390X:#define __INT64_FMTd__ "lld"
+// S390X:#define __INT64_FMTi__ "lli"
+// S390X:#define __INT64_MAX__ 9223372036854775807LL
 // S390X:#define __INT64_TYPE__ long long int
-// S390X:#define __INT8_TYPE__ char
+// S390X:#define __INT8_C_SUFFIX__ {{$}}
+// S390X:#define __INT8_FMTd__ "hhd"
+// S390X:#define __INT8_FMTi__ "hhi"
+// S390X:#define __INT8_MAX__ 127
+// S390X:#define __INT8_TYPE__ signed char
+// S390X:#define __INTMAX_C_SUFFIX__ LL
+// S390X:#define __INTMAX_FMTd__ "lld"
+// S390X:#define __INTMAX_FMTi__ "lli"
 // S390X:#define __INTMAX_MAX__ 9223372036854775807LL
 // S390X:#define __INTMAX_TYPE__ long long int
 // S390X:#define __INTMAX_WIDTH__ 64
+// S390X:#define __INTPTR_FMTd__ "ld"
+// S390X:#define __INTPTR_FMTi__ "li"
+// S390X:#define __INTPTR_MAX__ 9223372036854775807L
 // S390X:#define __INTPTR_TYPE__ long int
 // S390X:#define __INTPTR_WIDTH__ 64
+// S390X:#define __INT_FAST16_FMTd__ "hd"
+// S390X:#define __INT_FAST16_FMTi__ "hi"
+// S390X:#define __INT_FAST16_MAX__ 32767
+// S390X:#define __INT_FAST16_TYPE__ short
+// S390X:#define __INT_FAST32_FMTd__ "d"
+// S390X:#define __INT_FAST32_FMTi__ "i"
+// S390X:#define __INT_FAST32_MAX__ 2147483647
+// S390X:#define __INT_FAST32_TYPE__ int
+// S390X:#define __INT_FAST64_FMTd__ "ld"
+// S390X:#define __INT_FAST64_FMTi__ "li"
+// S390X:#define __INT_FAST64_MAX__ 9223372036854775807L
+// S390X:#define __INT_FAST64_TYPE__ long int
+// S390X:#define __INT_FAST8_FMTd__ "hhd"
+// S390X:#define __INT_FAST8_FMTi__ "hhi"
+// S390X:#define __INT_FAST8_MAX__ 127
+// S390X:#define __INT_FAST8_TYPE__ signed char
+// S390X:#define __INT_LEAST16_FMTd__ "hd"
+// S390X:#define __INT_LEAST16_FMTi__ "hi"
+// S390X:#define __INT_LEAST16_MAX__ 32767
+// S390X:#define __INT_LEAST16_TYPE__ short
+// S390X:#define __INT_LEAST32_FMTd__ "d"
+// S390X:#define __INT_LEAST32_FMTi__ "i"
+// S390X:#define __INT_LEAST32_MAX__ 2147483647
+// S390X:#define __INT_LEAST32_TYPE__ int
+// S390X:#define __INT_LEAST64_FMTd__ "ld"
+// S390X:#define __INT_LEAST64_FMTi__ "li"
+// S390X:#define __INT_LEAST64_MAX__ 9223372036854775807L
+// S390X:#define __INT_LEAST64_TYPE__ long int
+// S390X:#define __INT_LEAST8_FMTd__ "hhd"
+// S390X:#define __INT_LEAST8_FMTi__ "hhi"
+// S390X:#define __INT_LEAST8_MAX__ 127
+// S390X:#define __INT_LEAST8_TYPE__ signed char
 // S390X:#define __INT_MAX__ 2147483647
 // S390X:#define __LDBL_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966L
 // S390X:#define __LDBL_DIG__ 33
@@ -2678,6 +5615,7 @@
 // S390X:#define __PTRDIFF_WIDTH__ 64
 // S390X:#define __SCHAR_MAX__ 127
 // S390X:#define __SHRT_MAX__ 32767
+// S390X:#define __SIG_ATOMIC_MAX__ 2147483647
 // S390X:#define __SIG_ATOMIC_WIDTH__ 32
 // S390X:#define __SIZEOF_DOUBLE__ 8
 // S390X:#define __SIZEOF_FLOAT__ 4
@@ -2693,7 +5631,41 @@
 // S390X:#define __SIZEOF_WINT_T__ 4
 // S390X:#define __SIZE_TYPE__ long unsigned int
 // S390X:#define __SIZE_WIDTH__ 64
+// S390X:#define __UINT16_C_SUFFIX__ {{$}}
+// S390X:#define __UINT16_MAX__ 65535
+// S390X:#define __UINT16_TYPE__ unsigned short
+// S390X:#define __UINT32_C_SUFFIX__ U
+// S390X:#define __UINT32_MAX__ 4294967295U
+// S390X:#define __UINT32_TYPE__ unsigned int
+// S390X:#define __UINT64_C_SUFFIX__ ULL
+// S390X:#define __UINT64_MAX__ 18446744073709551615ULL
+// S390X:#define __UINT64_TYPE__ long long unsigned int
+// S390X:#define __UINT8_C_SUFFIX__ {{$}}
+// S390X:#define __UINT8_MAX__ 255
+// S390X:#define __UINT8_TYPE__ unsigned char
+// S390X:#define __UINTMAX_C_SUFFIX__ ULL
+// S390X:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // S390X:#define __UINTMAX_TYPE__ long long unsigned int
+// S390X:#define __UINTMAX_WIDTH__ 64
+// S390X:#define __UINTPTR_MAX__ 18446744073709551615UL
+// S390X:#define __UINTPTR_TYPE__ long unsigned int
+// S390X:#define __UINTPTR_WIDTH__ 64
+// S390X:#define __UINT_FAST16_MAX__ 65535
+// S390X:#define __UINT_FAST16_TYPE__ unsigned short
+// S390X:#define __UINT_FAST32_MAX__ 4294967295U
+// S390X:#define __UINT_FAST32_TYPE__ unsigned int
+// S390X:#define __UINT_FAST64_MAX__ 18446744073709551615UL
+// S390X:#define __UINT_FAST64_TYPE__ long unsigned int
+// S390X:#define __UINT_FAST8_MAX__ 255
+// S390X:#define __UINT_FAST8_TYPE__ unsigned char
+// S390X:#define __UINT_LEAST16_MAX__ 65535
+// S390X:#define __UINT_LEAST16_TYPE__ unsigned short
+// S390X:#define __UINT_LEAST32_MAX__ 4294967295U
+// S390X:#define __UINT_LEAST32_TYPE__ unsigned int
+// S390X:#define __UINT_LEAST64_MAX__ 18446744073709551615UL
+// S390X:#define __UINT_LEAST64_TYPE__ long unsigned int
+// S390X:#define __UINT_LEAST8_MAX__ 255
+// S390X:#define __UINT_LEAST8_TYPE__ unsigned char
 // S390X:#define __USER_LABEL_PREFIX__ _
 // S390X:#define __WCHAR_MAX__ 2147483647
 // S390X:#define __WCHAR_TYPE__ int
@@ -2706,6 +5678,7 @@
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=sparc-none-none < /dev/null | FileCheck -check-prefix SPARC %s
 //
 // SPARC-NOT:#define _LP64
+// SPARC:#define __BIG_ENDIAN__ 1
 // SPARC:#define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__
 // SPARC:#define __CHAR16_TYPE__ unsigned short
 // SPARC:#define __CHAR32_TYPE__ unsigned int
@@ -2739,16 +5712,69 @@
 // SPARC:#define __FLT_MIN_EXP__ (-125)
 // SPARC:#define __FLT_MIN__ 1.17549435e-38F
 // SPARC:#define __FLT_RADIX__ 2
+// SPARC:#define __INT16_C_SUFFIX__ {{$}}
+// SPARC:#define __INT16_FMTd__ "hd"
+// SPARC:#define __INT16_FMTi__ "hi"
+// SPARC:#define __INT16_MAX__ 32767
 // SPARC:#define __INT16_TYPE__ short
+// SPARC:#define __INT32_C_SUFFIX__ {{$}}
+// SPARC:#define __INT32_FMTd__ "d"
+// SPARC:#define __INT32_FMTi__ "i"
+// SPARC:#define __INT32_MAX__ 2147483647
 // SPARC:#define __INT32_TYPE__ int
 // SPARC:#define __INT64_C_SUFFIX__ LL
+// SPARC:#define __INT64_FMTd__ "lld"
+// SPARC:#define __INT64_FMTi__ "lli"
+// SPARC:#define __INT64_MAX__ 9223372036854775807LL
 // SPARC:#define __INT64_TYPE__ long long int
-// SPARC:#define __INT8_TYPE__ char
+// SPARC:#define __INT8_C_SUFFIX__ {{$}}
+// SPARC:#define __INT8_FMTd__ "hhd"
+// SPARC:#define __INT8_FMTi__ "hhi"
+// SPARC:#define __INT8_MAX__ 127
+// SPARC:#define __INT8_TYPE__ signed char
+// SPARC:#define __INTMAX_C_SUFFIX__ LL
+// SPARC:#define __INTMAX_FMTd__ "lld"
+// SPARC:#define __INTMAX_FMTi__ "lli"
 // SPARC:#define __INTMAX_MAX__ 9223372036854775807LL
 // SPARC:#define __INTMAX_TYPE__ long long int
 // SPARC:#define __INTMAX_WIDTH__ 64
+// SPARC:#define __INTPTR_FMTd__ "ld"
+// SPARC:#define __INTPTR_FMTi__ "li"
+// SPARC:#define __INTPTR_MAX__ 2147483647L
 // SPARC:#define __INTPTR_TYPE__ long int
 // SPARC:#define __INTPTR_WIDTH__ 32
+// SPARC:#define __INT_FAST16_FMTd__ "hd"
+// SPARC:#define __INT_FAST16_FMTi__ "hi"
+// SPARC:#define __INT_FAST16_MAX__ 32767
+// SPARC:#define __INT_FAST16_TYPE__ short
+// SPARC:#define __INT_FAST32_FMTd__ "d"
+// SPARC:#define __INT_FAST32_FMTi__ "i"
+// SPARC:#define __INT_FAST32_MAX__ 2147483647
+// SPARC:#define __INT_FAST32_TYPE__ int
+// SPARC:#define __INT_FAST64_FMTd__ "lld"
+// SPARC:#define __INT_FAST64_FMTi__ "lli"
+// SPARC:#define __INT_FAST64_MAX__ 9223372036854775807LL
+// SPARC:#define __INT_FAST64_TYPE__ long long int
+// SPARC:#define __INT_FAST8_FMTd__ "hhd"
+// SPARC:#define __INT_FAST8_FMTi__ "hhi"
+// SPARC:#define __INT_FAST8_MAX__ 127
+// SPARC:#define __INT_FAST8_TYPE__ signed char
+// SPARC:#define __INT_LEAST16_FMTd__ "hd"
+// SPARC:#define __INT_LEAST16_FMTi__ "hi"
+// SPARC:#define __INT_LEAST16_MAX__ 32767
+// SPARC:#define __INT_LEAST16_TYPE__ short
+// SPARC:#define __INT_LEAST32_FMTd__ "d"
+// SPARC:#define __INT_LEAST32_FMTi__ "i"
+// SPARC:#define __INT_LEAST32_MAX__ 2147483647
+// SPARC:#define __INT_LEAST32_TYPE__ int
+// SPARC:#define __INT_LEAST64_FMTd__ "lld"
+// SPARC:#define __INT_LEAST64_FMTi__ "lli"
+// SPARC:#define __INT_LEAST64_MAX__ 9223372036854775807LL
+// SPARC:#define __INT_LEAST64_TYPE__ long long int
+// SPARC:#define __INT_LEAST8_FMTd__ "hhd"
+// SPARC:#define __INT_LEAST8_FMTi__ "hhi"
+// SPARC:#define __INT_LEAST8_MAX__ 127
+// SPARC:#define __INT_LEAST8_TYPE__ signed char
 // SPARC:#define __INT_MAX__ 2147483647
 // SPARC:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
 // SPARC:#define __LDBL_DIG__ 15
@@ -2772,6 +5798,7 @@
 // SPARC:#define __REGISTER_PREFIX__
 // SPARC:#define __SCHAR_MAX__ 127
 // SPARC:#define __SHRT_MAX__ 32767
+// SPARC:#define __SIG_ATOMIC_MAX__ 2147483647
 // SPARC:#define __SIG_ATOMIC_WIDTH__ 32
 // SPARC:#define __SIZEOF_DOUBLE__ 8
 // SPARC:#define __SIZEOF_FLOAT__ 4
@@ -2788,7 +5815,41 @@
 // SPARC:#define __SIZE_MAX__ 4294967295U
 // SPARC:#define __SIZE_TYPE__ long unsigned int
 // SPARC:#define __SIZE_WIDTH__ 32
+// SPARC:#define __UINT16_C_SUFFIX__ {{$}}
+// SPARC:#define __UINT16_MAX__ 65535
+// SPARC:#define __UINT16_TYPE__ unsigned short
+// SPARC:#define __UINT32_C_SUFFIX__ U
+// SPARC:#define __UINT32_MAX__ 4294967295U
+// SPARC:#define __UINT32_TYPE__ unsigned int
+// SPARC:#define __UINT64_C_SUFFIX__ ULL
+// SPARC:#define __UINT64_MAX__ 18446744073709551615ULL
+// SPARC:#define __UINT64_TYPE__ long long unsigned int
+// SPARC:#define __UINT8_C_SUFFIX__ {{$}}
+// SPARC:#define __UINT8_MAX__ 255
+// SPARC:#define __UINT8_TYPE__ unsigned char
+// SPARC:#define __UINTMAX_C_SUFFIX__ ULL
+// SPARC:#define __UINTMAX_MAX__ 18446744073709551615ULL
 // SPARC:#define __UINTMAX_TYPE__ long long unsigned int
+// SPARC:#define __UINTMAX_WIDTH__ 64
+// SPARC:#define __UINTPTR_MAX__ 4294967295U
+// SPARC:#define __UINTPTR_TYPE__ long unsigned int
+// SPARC:#define __UINTPTR_WIDTH__ 32
+// SPARC:#define __UINT_FAST16_MAX__ 65535
+// SPARC:#define __UINT_FAST16_TYPE__ unsigned short
+// SPARC:#define __UINT_FAST32_MAX__ 4294967295U
+// SPARC:#define __UINT_FAST32_TYPE__ unsigned int
+// SPARC:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// SPARC:#define __UINT_FAST64_TYPE__ long long unsigned int
+// SPARC:#define __UINT_FAST8_MAX__ 255
+// SPARC:#define __UINT_FAST8_TYPE__ unsigned char
+// SPARC:#define __UINT_LEAST16_MAX__ 65535
+// SPARC:#define __UINT_LEAST16_TYPE__ unsigned short
+// SPARC:#define __UINT_LEAST32_MAX__ 4294967295U
+// SPARC:#define __UINT_LEAST32_TYPE__ unsigned int
+// SPARC:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// SPARC:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// SPARC:#define __UINT_LEAST8_MAX__ 255
+// SPARC:#define __UINT_LEAST8_TYPE__ unsigned char
 // SPARC:#define __USER_LABEL_PREFIX__ _
 // SPARC:#define __VERSION__ "4.2.1 Compatible
 // SPARC:#define __WCHAR_MAX__ 2147483647
@@ -2804,6 +5865,7 @@
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=tce-none-none < /dev/null | FileCheck -check-prefix TCE %s
 //
 // TCE-NOT:#define _LP64
+// TCE:#define __BIG_ENDIAN__ 1
 // TCE:#define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__
 // TCE:#define __CHAR16_TYPE__ unsigned short
 // TCE:#define __CHAR32_TYPE__ unsigned int
@@ -2837,14 +5899,56 @@
 // TCE:#define __FLT_MIN_EXP__ (-125)
 // TCE:#define __FLT_MIN__ 1.17549435e-38F
 // TCE:#define __FLT_RADIX__ 2
+// TCE:#define __INT16_C_SUFFIX__ {{$}}
+// TCE:#define __INT16_FMTd__ "hd"
+// TCE:#define __INT16_FMTi__ "hi"
+// TCE:#define __INT16_MAX__ 32767
 // TCE:#define __INT16_TYPE__ short
+// TCE:#define __INT32_C_SUFFIX__ {{$}}
+// TCE:#define __INT32_FMTd__ "d"
+// TCE:#define __INT32_FMTi__ "i"
+// TCE:#define __INT32_MAX__ 2147483647
 // TCE:#define __INT32_TYPE__ int
-// TCE:#define __INT8_TYPE__ char
+// TCE:#define __INT8_C_SUFFIX__ {{$}}
+// TCE:#define __INT8_FMTd__ "hhd"
+// TCE:#define __INT8_FMTi__ "hhi"
+// TCE:#define __INT8_MAX__ 127
+// TCE:#define __INT8_TYPE__ signed char
+// TCE:#define __INTMAX_C_SUFFIX__ L
+// TCE:#define __INTMAX_FMTd__ "ld"
+// TCE:#define __INTMAX_FMTi__ "li"
 // TCE:#define __INTMAX_MAX__ 2147483647L
 // TCE:#define __INTMAX_TYPE__ long int
 // TCE:#define __INTMAX_WIDTH__ 32
+// TCE:#define __INTPTR_FMTd__ "d"
+// TCE:#define __INTPTR_FMTi__ "i"
+// TCE:#define __INTPTR_MAX__ 2147483647
 // TCE:#define __INTPTR_TYPE__ int
 // TCE:#define __INTPTR_WIDTH__ 32
+// TCE:#define __INT_FAST16_FMTd__ "hd"
+// TCE:#define __INT_FAST16_FMTi__ "hi"
+// TCE:#define __INT_FAST16_MAX__ 32767
+// TCE:#define __INT_FAST16_TYPE__ short
+// TCE:#define __INT_FAST32_FMTd__ "d"
+// TCE:#define __INT_FAST32_FMTi__ "i"
+// TCE:#define __INT_FAST32_MAX__ 2147483647
+// TCE:#define __INT_FAST32_TYPE__ int
+// TCE:#define __INT_FAST8_FMTd__ "hhd"
+// TCE:#define __INT_FAST8_FMTi__ "hhi"
+// TCE:#define __INT_FAST8_MAX__ 127
+// TCE:#define __INT_FAST8_TYPE__ signed char
+// TCE:#define __INT_LEAST16_FMTd__ "hd"
+// TCE:#define __INT_LEAST16_FMTi__ "hi"
+// TCE:#define __INT_LEAST16_MAX__ 32767
+// TCE:#define __INT_LEAST16_TYPE__ short
+// TCE:#define __INT_LEAST32_FMTd__ "d"
+// TCE:#define __INT_LEAST32_FMTi__ "i"
+// TCE:#define __INT_LEAST32_MAX__ 2147483647
+// TCE:#define __INT_LEAST32_TYPE__ int
+// TCE:#define __INT_LEAST8_FMTd__ "hhd"
+// TCE:#define __INT_LEAST8_FMTi__ "hhi"
+// TCE:#define __INT_LEAST8_MAX__ 127
+// TCE:#define __INT_LEAST8_TYPE__ signed char
 // TCE:#define __INT_MAX__ 2147483647
 // TCE:#define __LDBL_DENORM_MIN__ 1.40129846e-45L
 // TCE:#define __LDBL_DIG__ 6
@@ -2867,6 +5971,7 @@
 // TCE:#define __PTRDIFF_WIDTH__ 32
 // TCE:#define __SCHAR_MAX__ 127
 // TCE:#define __SHRT_MAX__ 32767
+// TCE:#define __SIG_ATOMIC_MAX__ 2147483647
 // TCE:#define __SIG_ATOMIC_WIDTH__ 32
 // TCE:#define __SIZEOF_DOUBLE__ 4
 // TCE:#define __SIZEOF_FLOAT__ 4
@@ -2885,7 +5990,34 @@
 // TCE:#define __SIZE_WIDTH__ 32
 // TCE:#define __TCE_V1__ 1
 // TCE:#define __TCE__ 1
+// TCE:#define __UINT16_C_SUFFIX__ {{$}}
+// TCE:#define __UINT16_MAX__ 65535
+// TCE:#define __UINT16_TYPE__ unsigned short
+// TCE:#define __UINT32_C_SUFFIX__ U
+// TCE:#define __UINT32_MAX__ 4294967295U
+// TCE:#define __UINT32_TYPE__ unsigned int
+// TCE:#define __UINT8_C_SUFFIX__ {{$}}
+// TCE:#define __UINT8_MAX__ 255
+// TCE:#define __UINT8_TYPE__ unsigned char
+// TCE:#define __UINTMAX_C_SUFFIX__ UL
+// TCE:#define __UINTMAX_MAX__ 4294967295UL
 // TCE:#define __UINTMAX_TYPE__ long unsigned int
+// TCE:#define __UINTMAX_WIDTH__ 32
+// TCE:#define __UINTPTR_MAX__ 4294967295U
+// TCE:#define __UINTPTR_TYPE__ unsigned int
+// TCE:#define __UINTPTR_WIDTH__ 32
+// TCE:#define __UINT_FAST16_MAX__ 65535
+// TCE:#define __UINT_FAST16_TYPE__ unsigned short
+// TCE:#define __UINT_FAST32_MAX__ 4294967295U
+// TCE:#define __UINT_FAST32_TYPE__ unsigned int
+// TCE:#define __UINT_FAST8_MAX__ 255
+// TCE:#define __UINT_FAST8_TYPE__ unsigned char
+// TCE:#define __UINT_LEAST16_MAX__ 65535
+// TCE:#define __UINT_LEAST16_TYPE__ unsigned short
+// TCE:#define __UINT_LEAST32_MAX__ 4294967295U
+// TCE:#define __UINT_LEAST32_TYPE__ unsigned int
+// TCE:#define __UINT_LEAST8_MAX__ 255
+// TCE:#define __UINT_LEAST8_TYPE__ unsigned char
 // TCE:#define __USER_LABEL_PREFIX__ _
 // TCE:#define __WCHAR_MAX__ 2147483647
 // TCE:#define __WCHAR_TYPE__ int
@@ -2899,6 +6031,7 @@
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=x86_64-none-none < /dev/null | FileCheck -check-prefix X86_64 %s
 //
 // X86_64:#define _LP64 1
+// X86_64-NOT:#define _LP32 1
 // X86_64:#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
 // X86_64:#define __CHAR16_TYPE__ unsigned short
 // X86_64:#define __CHAR32_TYPE__ unsigned int
@@ -2932,16 +6065,69 @@
 // X86_64:#define __FLT_MIN_EXP__ (-125)
 // X86_64:#define __FLT_MIN__ 1.17549435e-38F
 // X86_64:#define __FLT_RADIX__ 2
+// X86_64:#define __INT16_C_SUFFIX__ {{$}}
+// X86_64:#define __INT16_FMTd__ "hd"
+// X86_64:#define __INT16_FMTi__ "hi"
+// X86_64:#define __INT16_MAX__ 32767
 // X86_64:#define __INT16_TYPE__ short
+// X86_64:#define __INT32_C_SUFFIX__ {{$}}
+// X86_64:#define __INT32_FMTd__ "d"
+// X86_64:#define __INT32_FMTi__ "i"
+// X86_64:#define __INT32_MAX__ 2147483647
 // X86_64:#define __INT32_TYPE__ int
 // X86_64:#define __INT64_C_SUFFIX__ L
+// X86_64:#define __INT64_FMTd__ "ld"
+// X86_64:#define __INT64_FMTi__ "li"
+// X86_64:#define __INT64_MAX__ 9223372036854775807L
 // X86_64:#define __INT64_TYPE__ long int
-// X86_64:#define __INT8_TYPE__ char
+// X86_64:#define __INT8_C_SUFFIX__ {{$}}
+// X86_64:#define __INT8_FMTd__ "hhd"
+// X86_64:#define __INT8_FMTi__ "hhi"
+// X86_64:#define __INT8_MAX__ 127
+// X86_64:#define __INT8_TYPE__ signed char
+// X86_64:#define __INTMAX_C_SUFFIX__ L
+// X86_64:#define __INTMAX_FMTd__ "ld"
+// X86_64:#define __INTMAX_FMTi__ "li"
 // X86_64:#define __INTMAX_MAX__ 9223372036854775807L
 // X86_64:#define __INTMAX_TYPE__ long int
 // X86_64:#define __INTMAX_WIDTH__ 64
+// X86_64:#define __INTPTR_FMTd__ "ld"
+// X86_64:#define __INTPTR_FMTi__ "li"
+// X86_64:#define __INTPTR_MAX__ 9223372036854775807L
 // X86_64:#define __INTPTR_TYPE__ long int
 // X86_64:#define __INTPTR_WIDTH__ 64
+// X86_64:#define __INT_FAST16_FMTd__ "hd"
+// X86_64:#define __INT_FAST16_FMTi__ "hi"
+// X86_64:#define __INT_FAST16_MAX__ 32767
+// X86_64:#define __INT_FAST16_TYPE__ short
+// X86_64:#define __INT_FAST32_FMTd__ "d"
+// X86_64:#define __INT_FAST32_FMTi__ "i"
+// X86_64:#define __INT_FAST32_MAX__ 2147483647
+// X86_64:#define __INT_FAST32_TYPE__ int
+// X86_64:#define __INT_FAST64_FMTd__ "ld"
+// X86_64:#define __INT_FAST64_FMTi__ "li"
+// X86_64:#define __INT_FAST64_MAX__ 9223372036854775807L
+// X86_64:#define __INT_FAST64_TYPE__ long int
+// X86_64:#define __INT_FAST8_FMTd__ "hhd"
+// X86_64:#define __INT_FAST8_FMTi__ "hhi"
+// X86_64:#define __INT_FAST8_MAX__ 127
+// X86_64:#define __INT_FAST8_TYPE__ signed char
+// X86_64:#define __INT_LEAST16_FMTd__ "hd"
+// X86_64:#define __INT_LEAST16_FMTi__ "hi"
+// X86_64:#define __INT_LEAST16_MAX__ 32767
+// X86_64:#define __INT_LEAST16_TYPE__ short
+// X86_64:#define __INT_LEAST32_FMTd__ "d"
+// X86_64:#define __INT_LEAST32_FMTi__ "i"
+// X86_64:#define __INT_LEAST32_MAX__ 2147483647
+// X86_64:#define __INT_LEAST32_TYPE__ int
+// X86_64:#define __INT_LEAST64_FMTd__ "ld"
+// X86_64:#define __INT_LEAST64_FMTi__ "li"
+// X86_64:#define __INT_LEAST64_MAX__ 9223372036854775807L
+// X86_64:#define __INT_LEAST64_TYPE__ long int
+// X86_64:#define __INT_LEAST8_FMTd__ "hhd"
+// X86_64:#define __INT_LEAST8_FMTi__ "hhi"
+// X86_64:#define __INT_LEAST8_MAX__ 127
+// X86_64:#define __INT_LEAST8_TYPE__ signed char
 // X86_64:#define __INT_MAX__ 2147483647
 // X86_64:#define __LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L
 // X86_64:#define __LDBL_DIG__ 18
@@ -2960,6 +6146,7 @@
 // X86_64:#define __LONG_LONG_MAX__ 9223372036854775807LL
 // X86_64:#define __LONG_MAX__ 9223372036854775807L
 // X86_64:#define __LP64__ 1
+// X86_64-NOT:#define __ILP32__ 1
 // X86_64:#define __MMX__ 1
 // X86_64:#define __NO_MATH_INLINES 1
 // X86_64:#define __POINTER_WIDTH__ 64
@@ -2968,6 +6155,7 @@
 // X86_64:#define __REGISTER_PREFIX__ 
 // X86_64:#define __SCHAR_MAX__ 127
 // X86_64:#define __SHRT_MAX__ 32767
+// X86_64:#define __SIG_ATOMIC_MAX__ 2147483647
 // X86_64:#define __SIG_ATOMIC_WIDTH__ 32
 // X86_64:#define __SIZEOF_DOUBLE__ 8
 // X86_64:#define __SIZEOF_FLOAT__ 4
@@ -2988,7 +6176,41 @@
 // X86_64:#define __SSE2__ 1
 // X86_64:#define __SSE_MATH__ 1
 // X86_64:#define __SSE__ 1
+// X86_64:#define __UINT16_C_SUFFIX__ {{$}}
+// X86_64:#define __UINT16_MAX__ 65535
+// X86_64:#define __UINT16_TYPE__ unsigned short
+// X86_64:#define __UINT32_C_SUFFIX__ U
+// X86_64:#define __UINT32_MAX__ 4294967295U
+// X86_64:#define __UINT32_TYPE__ unsigned int
+// X86_64:#define __UINT64_C_SUFFIX__ UL
+// X86_64:#define __UINT64_MAX__ 18446744073709551615UL
+// X86_64:#define __UINT64_TYPE__ long unsigned int
+// X86_64:#define __UINT8_C_SUFFIX__ {{$}}
+// X86_64:#define __UINT8_MAX__ 255
+// X86_64:#define __UINT8_TYPE__ unsigned char
+// X86_64:#define __UINTMAX_C_SUFFIX__ UL
+// X86_64:#define __UINTMAX_MAX__ 18446744073709551615UL
 // X86_64:#define __UINTMAX_TYPE__ long unsigned int
+// X86_64:#define __UINTMAX_WIDTH__ 64
+// X86_64:#define __UINTPTR_MAX__ 18446744073709551615UL
+// X86_64:#define __UINTPTR_TYPE__ long unsigned int
+// X86_64:#define __UINTPTR_WIDTH__ 64
+// X86_64:#define __UINT_FAST16_MAX__ 65535
+// X86_64:#define __UINT_FAST16_TYPE__ unsigned short
+// X86_64:#define __UINT_FAST32_MAX__ 4294967295U
+// X86_64:#define __UINT_FAST32_TYPE__ unsigned int
+// X86_64:#define __UINT_FAST64_MAX__ 18446744073709551615UL
+// X86_64:#define __UINT_FAST64_TYPE__ long unsigned int
+// X86_64:#define __UINT_FAST8_MAX__ 255
+// X86_64:#define __UINT_FAST8_TYPE__ unsigned char
+// X86_64:#define __UINT_LEAST16_MAX__ 65535
+// X86_64:#define __UINT_LEAST16_TYPE__ unsigned short
+// X86_64:#define __UINT_LEAST32_MAX__ 4294967295U
+// X86_64:#define __UINT_LEAST32_TYPE__ unsigned int
+// X86_64:#define __UINT_LEAST64_MAX__ 18446744073709551615UL
+// X86_64:#define __UINT_LEAST64_TYPE__ long unsigned int
+// X86_64:#define __UINT_LEAST8_MAX__ 255
+// X86_64:#define __UINT_LEAST8_TYPE__ unsigned char
 // X86_64:#define __USER_LABEL_PREFIX__ _
 // X86_64:#define __WCHAR_MAX__ 2147483647
 // X86_64:#define __WCHAR_TYPE__ int
@@ -3000,6 +6222,200 @@
 // X86_64:#define __x86_64 1
 // X86_64:#define __x86_64__ 1
 //
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=x86_64-none-none-gnux32 < /dev/null | FileCheck -check-prefix X32 %s
+//
+// X32:#define _ILP32 1
+// X32-NOT:#define _LP64 1
+// X32:#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
+// X32:#define __CHAR16_TYPE__ unsigned short
+// X32:#define __CHAR32_TYPE__ unsigned int
+// X32:#define __CHAR_BIT__ 8
+// X32:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
+// X32:#define __DBL_DIG__ 15
+// X32:#define __DBL_EPSILON__ 2.2204460492503131e-16
+// X32:#define __DBL_HAS_DENORM__ 1
+// X32:#define __DBL_HAS_INFINITY__ 1
+// X32:#define __DBL_HAS_QUIET_NAN__ 1
+// X32:#define __DBL_MANT_DIG__ 53
+// X32:#define __DBL_MAX_10_EXP__ 308
+// X32:#define __DBL_MAX_EXP__ 1024
+// X32:#define __DBL_MAX__ 1.7976931348623157e+308
+// X32:#define __DBL_MIN_10_EXP__ (-307)
+// X32:#define __DBL_MIN_EXP__ (-1021)
+// X32:#define __DBL_MIN__ 2.2250738585072014e-308
+// X32:#define __DECIMAL_DIG__ 21
+// X32:#define __FLT_DENORM_MIN__ 1.40129846e-45F
+// X32:#define __FLT_DIG__ 6
+// X32:#define __FLT_EPSILON__ 1.19209290e-7F
+// X32:#define __FLT_EVAL_METHOD__ 0
+// X32:#define __FLT_HAS_DENORM__ 1
+// X32:#define __FLT_HAS_INFINITY__ 1
+// X32:#define __FLT_HAS_QUIET_NAN__ 1
+// X32:#define __FLT_MANT_DIG__ 24
+// X32:#define __FLT_MAX_10_EXP__ 38
+// X32:#define __FLT_MAX_EXP__ 128
+// X32:#define __FLT_MAX__ 3.40282347e+38F
+// X32:#define __FLT_MIN_10_EXP__ (-37)
+// X32:#define __FLT_MIN_EXP__ (-125)
+// X32:#define __FLT_MIN__ 1.17549435e-38F
+// X32:#define __FLT_RADIX__ 2
+// X32:#define __ILP32__ 1
+// X32-NOT:#define __LP64__ 1
+// X32:#define __INT16_C_SUFFIX__ {{$}}
+// X32:#define __INT16_FMTd__ "hd"
+// X32:#define __INT16_FMTi__ "hi"
+// X32:#define __INT16_MAX__ 32767
+// X32:#define __INT16_TYPE__ short
+// X32:#define __INT32_C_SUFFIX__ {{$}}
+// X32:#define __INT32_FMTd__ "d"
+// X32:#define __INT32_FMTi__ "i"
+// X32:#define __INT32_MAX__ 2147483647
+// X32:#define __INT32_TYPE__ int
+// X32:#define __INT64_C_SUFFIX__ L
+// X32:#define __INT64_FMTd__ "lld"
+// X32:#define __INT64_FMTi__ "lli"
+// X32:#define __INT64_MAX__ 9223372036854775807L
+// X32:#define __INT64_TYPE__ long long int
+// X32:#define __INT8_C_SUFFIX__ {{$}}
+// X32:#define __INT8_FMTd__ "hhd"
+// X32:#define __INT8_FMTi__ "hhi"
+// X32:#define __INT8_MAX__ 127
+// X32:#define __INT8_TYPE__ signed char
+// X32:#define __INTMAX_C_SUFFIX__ LL
+// X32:#define __INTMAX_FMTd__ "lld"
+// X32:#define __INTMAX_FMTi__ "lli"
+// X32:#define __INTMAX_MAX__ 9223372036854775807L
+// X32:#define __INTMAX_TYPE__ long long int
+// X32:#define __INTMAX_WIDTH__ 64
+// X32:#define __INTPTR_FMTd__ "d"
+// X32:#define __INTPTR_FMTi__ "i"
+// X32:#define __INTPTR_MAX__ 2147483647
+// X32:#define __INTPTR_TYPE__ int
+// X32:#define __INTPTR_WIDTH__ 32
+// X32:#define __INT_FAST16_FMTd__ "hd"
+// X32:#define __INT_FAST16_FMTi__ "hi"
+// X32:#define __INT_FAST16_MAX__ 32767
+// X32:#define __INT_FAST16_TYPE__ short
+// X32:#define __INT_FAST32_FMTd__ "d"
+// X32:#define __INT_FAST32_FMTi__ "i"
+// X32:#define __INT_FAST32_MAX__ 2147483647
+// X32:#define __INT_FAST32_TYPE__ int
+// X32:#define __INT_FAST64_FMTd__ "lld"
+// X32:#define __INT_FAST64_FMTi__ "lli"
+// X32:#define __INT_FAST64_MAX__ 9223372036854775807L
+// X32:#define __INT_FAST64_TYPE__ long long int
+// X32:#define __INT_FAST8_FMTd__ "hhd"
+// X32:#define __INT_FAST8_FMTi__ "hhi"
+// X32:#define __INT_FAST8_MAX__ 127
+// X32:#define __INT_FAST8_TYPE__ signed char
+// X32:#define __INT_LEAST16_FMTd__ "hd"
+// X32:#define __INT_LEAST16_FMTi__ "hi"
+// X32:#define __INT_LEAST16_MAX__ 32767
+// X32:#define __INT_LEAST16_TYPE__ short
+// X32:#define __INT_LEAST32_FMTd__ "d"
+// X32:#define __INT_LEAST32_FMTi__ "i"
+// X32:#define __INT_LEAST32_MAX__ 2147483647
+// X32:#define __INT_LEAST32_TYPE__ int
+// X32:#define __INT_LEAST64_FMTd__ "lld"
+// X32:#define __INT_LEAST64_FMTi__ "lli"
+// X32:#define __INT_LEAST64_MAX__ 9223372036854775807L
+// X32:#define __INT_LEAST64_TYPE__ long long int
+// X32:#define __INT_LEAST8_FMTd__ "hhd"
+// X32:#define __INT_LEAST8_FMTi__ "hhi"
+// X32:#define __INT_LEAST8_MAX__ 127
+// X32:#define __INT_LEAST8_TYPE__ signed char
+// X32:#define __INT_MAX__ 2147483647
+// X32:#define __LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L
+// X32:#define __LDBL_DIG__ 18
+// X32:#define __LDBL_EPSILON__ 1.08420217248550443401e-19L
+// X32:#define __LDBL_HAS_DENORM__ 1
+// X32:#define __LDBL_HAS_INFINITY__ 1
+// X32:#define __LDBL_HAS_QUIET_NAN__ 1
+// X32:#define __LDBL_MANT_DIG__ 64
+// X32:#define __LDBL_MAX_10_EXP__ 4932
+// X32:#define __LDBL_MAX_EXP__ 16384
+// X32:#define __LDBL_MAX__ 1.18973149535723176502e+4932L
+// X32:#define __LDBL_MIN_10_EXP__ (-4931)
+// X32:#define __LDBL_MIN_EXP__ (-16381)
+// X32:#define __LDBL_MIN__ 3.36210314311209350626e-4932L
+// X32:#define __LITTLE_ENDIAN__ 1
+// X32:#define __LONG_LONG_MAX__ 9223372036854775807LL
+// X32:#define __LONG_MAX__ 2147483647L
+// X32:#define __MMX__ 1
+// X32:#define __NO_MATH_INLINES 1
+// X32:#define __POINTER_WIDTH__ 32
+// X32:#define __PTRDIFF_TYPE__ int
+// X32:#define __PTRDIFF_WIDTH__ 32
+// X32:#define __REGISTER_PREFIX__ 
+// X32:#define __SCHAR_MAX__ 127
+// X32:#define __SHRT_MAX__ 32767
+// X32:#define __SIG_ATOMIC_MAX__ 2147483647
+// X32:#define __SIG_ATOMIC_WIDTH__ 32
+// X32:#define __SIZEOF_DOUBLE__ 8
+// X32:#define __SIZEOF_FLOAT__ 4
+// X32:#define __SIZEOF_INT__ 4
+// X32:#define __SIZEOF_LONG_DOUBLE__ 16
+// X32:#define __SIZEOF_LONG_LONG__ 8
+// X32:#define __SIZEOF_LONG__ 4
+// X32:#define __SIZEOF_POINTER__ 4
+// X32:#define __SIZEOF_PTRDIFF_T__ 4
+// X32:#define __SIZEOF_SHORT__ 2
+// X32:#define __SIZEOF_SIZE_T__ 4
+// X32:#define __SIZEOF_WCHAR_T__ 4
+// X32:#define __SIZEOF_WINT_T__ 4
+// X32:#define __SIZE_MAX__ 4294967295U
+// X32:#define __SIZE_TYPE__ unsigned int
+// X32:#define __SIZE_WIDTH__ 32
+// X32:#define __SSE2_MATH__ 1
+// X32:#define __SSE2__ 1
+// X32:#define __SSE_MATH__ 1
+// X32:#define __SSE__ 1
+// X32:#define __UINT16_C_SUFFIX__ {{$}}
+// X32:#define __UINT16_MAX__ 65535
+// X32:#define __UINT16_TYPE__ unsigned short
+// X32:#define __UINT32_C_SUFFIX__ U
+// X32:#define __UINT32_MAX__ 4294967295U
+// X32:#define __UINT32_TYPE__ unsigned int
+// X32:#define __UINT64_C_SUFFIX__ UL
+// X32:#define __UINT64_MAX__ 18446744073709551615ULL
+// X32:#define __UINT64_TYPE__ long long unsigned int
+// X32:#define __UINT8_C_SUFFIX__ {{$}}
+// X32:#define __UINT8_MAX__ 255
+// X32:#define __UINT8_TYPE__ unsigned char
+// X32:#define __UINTMAX_C_SUFFIX__ ULL
+// X32:#define __UINTMAX_MAX__ 18446744073709551615ULL
+// X32:#define __UINTMAX_TYPE__ long long unsigned int
+// X32:#define __UINTMAX_WIDTH__ 64
+// X32:#define __UINTPTR_MAX__ 4294967295U
+// X32:#define __UINTPTR_TYPE__ unsigned int
+// X32:#define __UINTPTR_WIDTH__ 32
+// X32:#define __UINT_FAST16_MAX__ 65535
+// X32:#define __UINT_FAST16_TYPE__ unsigned short
+// X32:#define __UINT_FAST32_MAX__ 4294967295U
+// X32:#define __UINT_FAST32_TYPE__ unsigned int
+// X32:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// X32:#define __UINT_FAST64_TYPE__ long long unsigned int
+// X32:#define __UINT_FAST8_MAX__ 255
+// X32:#define __UINT_FAST8_TYPE__ unsigned char
+// X32:#define __UINT_LEAST16_MAX__ 65535
+// X32:#define __UINT_LEAST16_TYPE__ unsigned short
+// X32:#define __UINT_LEAST32_MAX__ 4294967295U
+// X32:#define __UINT_LEAST32_TYPE__ unsigned int
+// X32:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// X32:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// X32:#define __UINT_LEAST8_MAX__ 255
+// X32:#define __UINT_LEAST8_TYPE__ unsigned char
+// X32:#define __USER_LABEL_PREFIX__ _
+// X32:#define __WCHAR_MAX__ 2147483647
+// X32:#define __WCHAR_TYPE__ int
+// X32:#define __WCHAR_WIDTH__ 32
+// X32:#define __WINT_TYPE__ int
+// X32:#define __WINT_WIDTH__ 32
+// X32:#define __amd64 1
+// X32:#define __amd64__ 1
+// X32:#define __x86_64 1
+// X32:#define __x86_64__ 1
+//
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=x86_64-pc-linux-gnu < /dev/null | FileCheck -check-prefix X86_64-LINUX %s
 //
 // X86_64-LINUX:#define _LP64 1
@@ -3036,16 +6452,69 @@
 // X86_64-LINUX:#define __FLT_MIN_EXP__ (-125)
 // X86_64-LINUX:#define __FLT_MIN__ 1.17549435e-38F
 // X86_64-LINUX:#define __FLT_RADIX__ 2
+// X86_64-LINUX:#define __INT16_C_SUFFIX__ {{$}}
+// X86_64-LINUX:#define __INT16_FMTd__ "hd"
+// X86_64-LINUX:#define __INT16_FMTi__ "hi"
+// X86_64-LINUX:#define __INT16_MAX__ 32767
 // X86_64-LINUX:#define __INT16_TYPE__ short
+// X86_64-LINUX:#define __INT32_C_SUFFIX__ {{$}}
+// X86_64-LINUX:#define __INT32_FMTd__ "d"
+// X86_64-LINUX:#define __INT32_FMTi__ "i"
+// X86_64-LINUX:#define __INT32_MAX__ 2147483647
 // X86_64-LINUX:#define __INT32_TYPE__ int
 // X86_64-LINUX:#define __INT64_C_SUFFIX__ L
+// X86_64-LINUX:#define __INT64_FMTd__ "ld"
+// X86_64-LINUX:#define __INT64_FMTi__ "li"
+// X86_64-LINUX:#define __INT64_MAX__ 9223372036854775807L
 // X86_64-LINUX:#define __INT64_TYPE__ long int
-// X86_64-LINUX:#define __INT8_TYPE__ char
+// X86_64-LINUX:#define __INT8_C_SUFFIX__ {{$}}
+// X86_64-LINUX:#define __INT8_FMTd__ "hhd"
+// X86_64-LINUX:#define __INT8_FMTi__ "hhi"
+// X86_64-LINUX:#define __INT8_MAX__ 127
+// X86_64-LINUX:#define __INT8_TYPE__ signed char
+// X86_64-LINUX:#define __INTMAX_C_SUFFIX__ L
+// X86_64-LINUX:#define __INTMAX_FMTd__ "ld"
+// X86_64-LINUX:#define __INTMAX_FMTi__ "li"
 // X86_64-LINUX:#define __INTMAX_MAX__ 9223372036854775807L
 // X86_64-LINUX:#define __INTMAX_TYPE__ long int
 // X86_64-LINUX:#define __INTMAX_WIDTH__ 64
+// X86_64-LINUX:#define __INTPTR_FMTd__ "ld"
+// X86_64-LINUX:#define __INTPTR_FMTi__ "li"
+// X86_64-LINUX:#define __INTPTR_MAX__ 9223372036854775807L
 // X86_64-LINUX:#define __INTPTR_TYPE__ long int
 // X86_64-LINUX:#define __INTPTR_WIDTH__ 64
+// X86_64-LINUX:#define __INT_FAST16_FMTd__ "hd"
+// X86_64-LINUX:#define __INT_FAST16_FMTi__ "hi"
+// X86_64-LINUX:#define __INT_FAST16_MAX__ 32767
+// X86_64-LINUX:#define __INT_FAST16_TYPE__ short
+// X86_64-LINUX:#define __INT_FAST32_FMTd__ "d"
+// X86_64-LINUX:#define __INT_FAST32_FMTi__ "i"
+// X86_64-LINUX:#define __INT_FAST32_MAX__ 2147483647
+// X86_64-LINUX:#define __INT_FAST32_TYPE__ int
+// X86_64-LINUX:#define __INT_FAST64_FMTd__ "ld"
+// X86_64-LINUX:#define __INT_FAST64_FMTi__ "li"
+// X86_64-LINUX:#define __INT_FAST64_MAX__ 9223372036854775807L
+// X86_64-LINUX:#define __INT_FAST64_TYPE__ long int
+// X86_64-LINUX:#define __INT_FAST8_FMTd__ "hhd"
+// X86_64-LINUX:#define __INT_FAST8_FMTi__ "hhi"
+// X86_64-LINUX:#define __INT_FAST8_MAX__ 127
+// X86_64-LINUX:#define __INT_FAST8_TYPE__ signed char
+// X86_64-LINUX:#define __INT_LEAST16_FMTd__ "hd"
+// X86_64-LINUX:#define __INT_LEAST16_FMTi__ "hi"
+// X86_64-LINUX:#define __INT_LEAST16_MAX__ 32767
+// X86_64-LINUX:#define __INT_LEAST16_TYPE__ short
+// X86_64-LINUX:#define __INT_LEAST32_FMTd__ "d"
+// X86_64-LINUX:#define __INT_LEAST32_FMTi__ "i"
+// X86_64-LINUX:#define __INT_LEAST32_MAX__ 2147483647
+// X86_64-LINUX:#define __INT_LEAST32_TYPE__ int
+// X86_64-LINUX:#define __INT_LEAST64_FMTd__ "ld"
+// X86_64-LINUX:#define __INT_LEAST64_FMTi__ "li"
+// X86_64-LINUX:#define __INT_LEAST64_MAX__ 9223372036854775807L
+// X86_64-LINUX:#define __INT_LEAST64_TYPE__ long int
+// X86_64-LINUX:#define __INT_LEAST8_FMTd__ "hhd"
+// X86_64-LINUX:#define __INT_LEAST8_FMTi__ "hhi"
+// X86_64-LINUX:#define __INT_LEAST8_MAX__ 127
+// X86_64-LINUX:#define __INT_LEAST8_TYPE__ signed char
 // X86_64-LINUX:#define __INT_MAX__ 2147483647
 // X86_64-LINUX:#define __LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L
 // X86_64-LINUX:#define __LDBL_DIG__ 18
@@ -3072,6 +6541,7 @@
 // X86_64-LINUX:#define __REGISTER_PREFIX__ 
 // X86_64-LINUX:#define __SCHAR_MAX__ 127
 // X86_64-LINUX:#define __SHRT_MAX__ 32767
+// X86_64-LINUX:#define __SIG_ATOMIC_MAX__ 2147483647
 // X86_64-LINUX:#define __SIG_ATOMIC_WIDTH__ 32
 // X86_64-LINUX:#define __SIZEOF_DOUBLE__ 8
 // X86_64-LINUX:#define __SIZEOF_FLOAT__ 4
@@ -3092,7 +6562,41 @@
 // X86_64-LINUX:#define __SSE2__ 1
 // X86_64-LINUX:#define __SSE_MATH__ 1
 // X86_64-LINUX:#define __SSE__ 1
+// X86_64-LINUX:#define __UINT16_C_SUFFIX__ {{$}}
+// X86_64-LINUX:#define __UINT16_MAX__ 65535
+// X86_64-LINUX:#define __UINT16_TYPE__ unsigned short
+// X86_64-LINUX:#define __UINT32_C_SUFFIX__ U
+// X86_64-LINUX:#define __UINT32_MAX__ 4294967295U
+// X86_64-LINUX:#define __UINT32_TYPE__ unsigned int
+// X86_64-LINUX:#define __UINT64_C_SUFFIX__ UL
+// X86_64-LINUX:#define __UINT64_MAX__ 18446744073709551615UL
+// X86_64-LINUX:#define __UINT64_TYPE__ long unsigned int
+// X86_64-LINUX:#define __UINT8_C_SUFFIX__ {{$}}
+// X86_64-LINUX:#define __UINT8_MAX__ 255
+// X86_64-LINUX:#define __UINT8_TYPE__ unsigned char
+// X86_64-LINUX:#define __UINTMAX_C_SUFFIX__ UL
+// X86_64-LINUX:#define __UINTMAX_MAX__ 18446744073709551615UL
 // X86_64-LINUX:#define __UINTMAX_TYPE__ long unsigned int
+// X86_64-LINUX:#define __UINTMAX_WIDTH__ 64
+// X86_64-LINUX:#define __UINTPTR_MAX__ 18446744073709551615UL
+// X86_64-LINUX:#define __UINTPTR_TYPE__ long unsigned int
+// X86_64-LINUX:#define __UINTPTR_WIDTH__ 64
+// X86_64-LINUX:#define __UINT_FAST16_MAX__ 65535
+// X86_64-LINUX:#define __UINT_FAST16_TYPE__ unsigned short
+// X86_64-LINUX:#define __UINT_FAST32_MAX__ 4294967295U
+// X86_64-LINUX:#define __UINT_FAST32_TYPE__ unsigned int
+// X86_64-LINUX:#define __UINT_FAST64_MAX__ 18446744073709551615UL
+// X86_64-LINUX:#define __UINT_FAST64_TYPE__ long unsigned int
+// X86_64-LINUX:#define __UINT_FAST8_MAX__ 255
+// X86_64-LINUX:#define __UINT_FAST8_TYPE__ unsigned char
+// X86_64-LINUX:#define __UINT_LEAST16_MAX__ 65535
+// X86_64-LINUX:#define __UINT_LEAST16_TYPE__ unsigned short
+// X86_64-LINUX:#define __UINT_LEAST32_MAX__ 4294967295U
+// X86_64-LINUX:#define __UINT_LEAST32_TYPE__ unsigned int
+// X86_64-LINUX:#define __UINT_LEAST64_MAX__ 18446744073709551615UL
+// X86_64-LINUX:#define __UINT_LEAST64_TYPE__ long unsigned int
+// X86_64-LINUX:#define __UINT_LEAST8_MAX__ 255
+// X86_64-LINUX:#define __UINT_LEAST8_TYPE__ unsigned char
 // X86_64-LINUX:#define __USER_LABEL_PREFIX__
 // X86_64-LINUX:#define __WCHAR_MAX__ 2147483647
 // X86_64-LINUX:#define __WCHAR_TYPE__ int
@@ -3146,16 +6650,69 @@
 // X86_64-NETBSD:#define __FLT_MIN_EXP__ (-125)
 // X86_64-NETBSD:#define __FLT_MIN__ 1.17549435e-38F
 // X86_64-NETBSD:#define __FLT_RADIX__ 2
+// X86_64-NETBSD:#define __INT16_C_SUFFIX__ {{$}}
+// X86_64-NETBSD:#define __INT16_FMTd__ "hd"
+// X86_64-NETBSD:#define __INT16_FMTi__ "hi"
+// X86_64-NETBSD:#define __INT16_MAX__ 32767
 // X86_64-NETBSD:#define __INT16_TYPE__ short
+// X86_64-NETBSD:#define __INT32_C_SUFFIX__ {{$}}
+// X86_64-NETBSD:#define __INT32_FMTd__ "d"
+// X86_64-NETBSD:#define __INT32_FMTi__ "i"
+// X86_64-NETBSD:#define __INT32_MAX__ 2147483647
 // X86_64-NETBSD:#define __INT32_TYPE__ int
 // X86_64-NETBSD:#define __INT64_C_SUFFIX__ L
+// X86_64-NETBSD:#define __INT64_FMTd__ "ld"
+// X86_64-NETBSD:#define __INT64_FMTi__ "li"
+// X86_64-NETBSD:#define __INT64_MAX__ 9223372036854775807L
 // X86_64-NETBSD:#define __INT64_TYPE__ long int
-// X86_64-NETBSD:#define __INT8_TYPE__ char
+// X86_64-NETBSD:#define __INT8_C_SUFFIX__ {{$}}
+// X86_64-NETBSD:#define __INT8_FMTd__ "hhd"
+// X86_64-NETBSD:#define __INT8_FMTi__ "hhi"
+// X86_64-NETBSD:#define __INT8_MAX__ 127
+// X86_64-NETBSD:#define __INT8_TYPE__ signed char
+// X86_64-NETBSD:#define __INTMAX_C_SUFFIX__ L
+// X86_64-NETBSD:#define __INTMAX_FMTd__ "ld"
+// X86_64-NETBSD:#define __INTMAX_FMTi__ "li"
 // X86_64-NETBSD:#define __INTMAX_MAX__ 9223372036854775807L
 // X86_64-NETBSD:#define __INTMAX_TYPE__ long int
 // X86_64-NETBSD:#define __INTMAX_WIDTH__ 64
+// X86_64-NETBSD:#define __INTPTR_FMTd__ "ld"
+// X86_64-NETBSD:#define __INTPTR_FMTi__ "li"
+// X86_64-NETBSD:#define __INTPTR_MAX__ 9223372036854775807L
 // X86_64-NETBSD:#define __INTPTR_TYPE__ long int
 // X86_64-NETBSD:#define __INTPTR_WIDTH__ 64
+// X86_64-NETBSD:#define __INT_FAST16_FMTd__ "hd"
+// X86_64-NETBSD:#define __INT_FAST16_FMTi__ "hi"
+// X86_64-NETBSD:#define __INT_FAST16_MAX__ 32767
+// X86_64-NETBSD:#define __INT_FAST16_TYPE__ short
+// X86_64-NETBSD:#define __INT_FAST32_FMTd__ "d"
+// X86_64-NETBSD:#define __INT_FAST32_FMTi__ "i"
+// X86_64-NETBSD:#define __INT_FAST32_MAX__ 2147483647
+// X86_64-NETBSD:#define __INT_FAST32_TYPE__ int
+// X86_64-NETBSD:#define __INT_FAST64_FMTd__ "ld"
+// X86_64-NETBSD:#define __INT_FAST64_FMTi__ "li"
+// X86_64-NETBSD:#define __INT_FAST64_MAX__ 9223372036854775807L
+// X86_64-NETBSD:#define __INT_FAST64_TYPE__ long int
+// X86_64-NETBSD:#define __INT_FAST8_FMTd__ "hhd"
+// X86_64-NETBSD:#define __INT_FAST8_FMTi__ "hhi"
+// X86_64-NETBSD:#define __INT_FAST8_MAX__ 127
+// X86_64-NETBSD:#define __INT_FAST8_TYPE__ signed char
+// X86_64-NETBSD:#define __INT_LEAST16_FMTd__ "hd"
+// X86_64-NETBSD:#define __INT_LEAST16_FMTi__ "hi"
+// X86_64-NETBSD:#define __INT_LEAST16_MAX__ 32767
+// X86_64-NETBSD:#define __INT_LEAST16_TYPE__ short
+// X86_64-NETBSD:#define __INT_LEAST32_FMTd__ "d"
+// X86_64-NETBSD:#define __INT_LEAST32_FMTi__ "i"
+// X86_64-NETBSD:#define __INT_LEAST32_MAX__ 2147483647
+// X86_64-NETBSD:#define __INT_LEAST32_TYPE__ int
+// X86_64-NETBSD:#define __INT_LEAST64_FMTd__ "ld"
+// X86_64-NETBSD:#define __INT_LEAST64_FMTi__ "li"
+// X86_64-NETBSD:#define __INT_LEAST64_MAX__ 9223372036854775807L
+// X86_64-NETBSD:#define __INT_LEAST64_TYPE__ long int
+// X86_64-NETBSD:#define __INT_LEAST8_FMTd__ "hhd"
+// X86_64-NETBSD:#define __INT_LEAST8_FMTi__ "hhi"
+// X86_64-NETBSD:#define __INT_LEAST8_MAX__ 127
+// X86_64-NETBSD:#define __INT_LEAST8_TYPE__ signed char
 // X86_64-NETBSD:#define __INT_MAX__ 2147483647
 // X86_64-NETBSD:#define __LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L
 // X86_64-NETBSD:#define __LDBL_DIG__ 18
@@ -3182,6 +6739,7 @@
 // X86_64-NETBSD:#define __REGISTER_PREFIX__ 
 // X86_64-NETBSD:#define __SCHAR_MAX__ 127
 // X86_64-NETBSD:#define __SHRT_MAX__ 32767
+// X86_64-NETBSD:#define __SIG_ATOMIC_MAX__ 2147483647
 // X86_64-NETBSD:#define __SIG_ATOMIC_WIDTH__ 32
 // X86_64-NETBSD:#define __SIZEOF_DOUBLE__ 8
 // X86_64-NETBSD:#define __SIZEOF_FLOAT__ 4
@@ -3202,7 +6760,41 @@
 // X86_64-NETBSD:#define __SSE2__ 1
 // X86_64-NETBSD:#define __SSE_MATH__ 1
 // X86_64-NETBSD:#define __SSE__ 1
+// X86_64-NETBSD:#define __UINT16_C_SUFFIX__ {{$}}
+// X86_64-NETBSD:#define __UINT16_MAX__ 65535
+// X86_64-NETBSD:#define __UINT16_TYPE__ unsigned short
+// X86_64-NETBSD:#define __UINT32_C_SUFFIX__ U
+// X86_64-NETBSD:#define __UINT32_MAX__ 4294967295U
+// X86_64-NETBSD:#define __UINT32_TYPE__ unsigned int
+// X86_64-NETBSD:#define __UINT64_C_SUFFIX__ UL
+// X86_64-NETBSD:#define __UINT64_MAX__ 18446744073709551615UL
+// X86_64-NETBSD:#define __UINT64_TYPE__ long unsigned int
+// X86_64-NETBSD:#define __UINT8_C_SUFFIX__ {{$}}
+// X86_64-NETBSD:#define __UINT8_MAX__ 255
+// X86_64-NETBSD:#define __UINT8_TYPE__ unsigned char
+// X86_64-NETBSD:#define __UINTMAX_C_SUFFIX__ UL
+// X86_64-NETBSD:#define __UINTMAX_MAX__ 18446744073709551615UL
 // X86_64-NETBSD:#define __UINTMAX_TYPE__ long unsigned int
+// X86_64-NETBSD:#define __UINTMAX_WIDTH__ 64
+// X86_64-NETBSD:#define __UINTPTR_MAX__ 18446744073709551615UL
+// X86_64-NETBSD:#define __UINTPTR_TYPE__ long unsigned int
+// X86_64-NETBSD:#define __UINTPTR_WIDTH__ 64
+// X86_64-NETBSD:#define __UINT_FAST16_MAX__ 65535
+// X86_64-NETBSD:#define __UINT_FAST16_TYPE__ unsigned short
+// X86_64-NETBSD:#define __UINT_FAST32_MAX__ 4294967295U
+// X86_64-NETBSD:#define __UINT_FAST32_TYPE__ unsigned int
+// X86_64-NETBSD:#define __UINT_FAST64_MAX__ 18446744073709551615UL
+// X86_64-NETBSD:#define __UINT_FAST64_TYPE__ long unsigned int
+// X86_64-NETBSD:#define __UINT_FAST8_MAX__ 255
+// X86_64-NETBSD:#define __UINT_FAST8_TYPE__ unsigned char
+// X86_64-NETBSD:#define __UINT_LEAST16_MAX__ 65535
+// X86_64-NETBSD:#define __UINT_LEAST16_TYPE__ unsigned short
+// X86_64-NETBSD:#define __UINT_LEAST32_MAX__ 4294967295U
+// X86_64-NETBSD:#define __UINT_LEAST32_TYPE__ unsigned int
+// X86_64-NETBSD:#define __UINT_LEAST64_MAX__ 18446744073709551615UL
+// X86_64-NETBSD:#define __UINT_LEAST64_TYPE__ long unsigned int
+// X86_64-NETBSD:#define __UINT_LEAST8_MAX__ 255
+// X86_64-NETBSD:#define __UINT_LEAST8_TYPE__ unsigned char
 // X86_64-NETBSD:#define __USER_LABEL_PREFIX__
 // X86_64-NETBSD:#define __WCHAR_MAX__ 2147483647
 // X86_64-NETBSD:#define __WCHAR_TYPE__ int
@@ -3216,16 +6808,20 @@
 //
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=sparc64-none-none < /dev/null | FileCheck -check-prefix SPARCV9 %s
 // SPARCV9:#define __INT64_TYPE__ long int
+// SPARCV9:#define __INTMAX_C_SUFFIX__ L
 // SPARCV9:#define __INTMAX_TYPE__ long int
 // SPARCV9:#define __INTPTR_TYPE__ long int
 // SPARCV9:#define __LONG_MAX__ 9223372036854775807L
 // SPARCV9:#define __LP64__ 1
 // SPARCV9:#define __SIZEOF_LONG__ 8
 // SPARCV9:#define __SIZEOF_POINTER__ 8
+// SPARCV9:#define __UINTPTR_TYPE__ long unsigned int
 //
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=sparc64-none-openbsd < /dev/null | FileCheck -check-prefix SPARC64-OBSD %s
 // SPARC64-OBSD:#define __INT64_TYPE__ long long int
+// SPARC64-OBSD:#define __INTMAX_C_SUFFIX__ LL
 // SPARC64-OBSD:#define __INTMAX_TYPE__ long long int
+// SPARC64-OBSD:#define __UINTMAX_C_SUFFIX__ ULL
 // SPARC64-OBSD:#define __UINTMAX_TYPE__ long long unsigned int
 //
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=x86_64-pc-kfreebsd-gnu < /dev/null | FileCheck -check-prefix KFREEBSD-DEFINE %s
@@ -3251,4 +6847,6 @@
 // PPC64-FREEBSD-NOT: #define __LONG_DOUBLE_128__ 1
 //
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=xcore-none-none < /dev/null | FileCheck -check-prefix XCORE %s
+// XCORE:#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
+// XCORE:#define __LITTLE_ENDIAN__ 1
 // XCORE:#define __XS1B__ 1
diff --git a/test/Preprocessor/macho-embedded-predefines.c b/test/Preprocessor/macho-embedded-predefines.c
new file mode 100644
index 0000000..74f2919
--- /dev/null
+++ b/test/Preprocessor/macho-embedded-predefines.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -E -dM -triple thumbv7m-apple-unknown-macho -target-cpu cortex-m3 %s | FileCheck %s -check-prefix CHECK-7M
+
+// CHECK-7M: #define __APPLE_CC__
+// CHECK-7M: #define __APPLE__
+// CHECK-7M: #define __ARM_ARCH_7M__
+// CHECK-7M-NOT: #define __MACH__
+
+// RUN: %clang_cc1 -E -dM -triple thumbv7em-apple-unknown-macho -target-cpu cortex-m4 %s | FileCheck %s -check-prefix CHECK-7EM
+
+// CHECK-7EM: #define __APPLE_CC__
+// CHECK-7EM: #define __APPLE__
+// CHECK-7EM: #define __ARM_ARCH_7EM__
+// CHECK-7EM-NOT: #define __MACH__
+
+// RUN: %clang_cc1 -E -dM -triple thumbv6m-apple-unknown-macho -target-cpu cortex-m0 %s | FileCheck %s -check-prefix CHECK-6M
+
+// CHECK-6M: #define __APPLE_CC__
+// CHECK-6M: #define __APPLE__
+// CHECK-6M: #define __ARM_ARCH_6M__
+// CHECK-6M-NOT: #define __MACH__
diff --git a/test/Preprocessor/macro-multiline.c b/test/Preprocessor/macro-multiline.c
new file mode 100644
index 0000000..5261928
--- /dev/null
+++ b/test/Preprocessor/macro-multiline.c
@@ -0,0 +1,7 @@
+// RUN: printf -- "-DX=A\nTHIS_SHOULD_NOT_EXIST_IN_THE_OUTPUT" | xargs -0 %clang -E %s | FileCheck -strict-whitespace %s
+// REQUIRES: shell
+
+// Per GCC -D semantics, \n and anything that follows is ignored.
+
+// CHECK: {{^START A END$}}
+START X END
diff --git a/test/Preprocessor/macro-multiline.c.ignoreme b/test/Preprocessor/macro-multiline.c.ignoreme
deleted file mode 100644
index df7c40a..0000000
--- a/test/Preprocessor/macro-multiline.c.ignoreme
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: %clang -E %s "-DX=A
-// RUN: THIS_SHOULD_NOT_EXIST_IN_THE_OUTPUT" > %t
-// RUN: grep "GOOD: A" %t
-// RUN: not grep THIS_SHOULD_NOT_EXIST_IN_THE_OUTPUT %t
-// rdar://6762183
-
-GOOD: X
-
diff --git a/test/Preprocessor/macro_arg_empty.c b/test/Preprocessor/macro_arg_empty.c
new file mode 100644
index 0000000..b5ecaa2
--- /dev/null
+++ b/test/Preprocessor/macro_arg_empty.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -E %s | FileCheck --strict-whitespace %s
+
+#define FOO(x) x
+#define BAR(x) x x
+#define BAZ(x) [x] [ x] [x ]
+[FOO()] [ FOO()] [FOO() ] [BAR()] [ BAR()] [BAR() ] BAZ()
+// CHECK: [] [ ] [ ] [ ] [ ] [ ] [] [ ] [ ]
diff --git a/test/Preprocessor/macro_expand_empty.c b/test/Preprocessor/macro_expand_empty.c
index 3fb6394..5507728 100644
--- a/test/Preprocessor/macro_expand_empty.c
+++ b/test/Preprocessor/macro_expand_empty.c
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only %s
+// RUN: %clang_cc1 -E %s | FileCheck --strict-whitespace %s
+
 // Check that this doesn't crash
 
 #define IDENTITY1(x) x
@@ -12,3 +13,9 @@
 #define IDENTITY9(x) IDENTITY8(x) IDENTITY8(x) IDENTITY8(x) IDENTITY8(x)
 #define IDENTITY0(x) IDENTITY9(x) IDENTITY9(x) IDENTITY9(x) IDENTITY9(x)
 IDENTITY0()
+
+#define FOO() BAR() second
+#define BAR()
+first // CHECK: {{^}}first{{$}}
+FOO() // CHECK: {{^}} second{{$}}
+third // CHECK: {{^}}third{{$}}
diff --git a/test/Preprocessor/macro_paste_commaext.c b/test/Preprocessor/macro_paste_commaext.c
index 7cfe43d..fdb8f98 100644
--- a/test/Preprocessor/macro_paste_commaext.c
+++ b/test/Preprocessor/macro_paste_commaext.c
@@ -1,8 +1,8 @@
 // RUN: %clang_cc1 %s -E | grep 'V);'
 // RUN: %clang_cc1 %s -E | grep 'W, 1, 2);'
 // RUN: %clang_cc1 %s -E | grep 'X, 1, 2);'
-// RUN: %clang_cc1 %s -E | grep 'Y, );'
-// RUN: %clang_cc1 %s -E | grep 'Z, );'
+// RUN: %clang_cc1 %s -E | grep 'Y,);'
+// RUN: %clang_cc1 %s -E | grep 'Z,);'
 
 #define debug(format, ...) format, ## __VA_ARGS__)
 debug(V);
diff --git a/test/Preprocessor/macro_paste_spacing.c b/test/Preprocessor/macro_paste_spacing.c
index 6498ffc..481d457 100644
--- a/test/Preprocessor/macro_paste_spacing.c
+++ b/test/Preprocessor/macro_paste_spacing.c
@@ -1,7 +1,21 @@
-// RUN: %clang_cc1 %s -E | grep "^xy$"
+// RUN: %clang_cc1 -E %s | FileCheck --strict-whitespace %s
 
 #define A  x ## y
 blah
 
 A
+// CHECK: {{^}}xy{{$}}
 
+#define B(x, y) [v ## w] [ v##w] [v##w ] [w ## x] [ w##x] [w##x ] [x ## y] [ x##y] [x##y ] [y ## z] [ y##z] [y##z ]
+B(x,y)
+// CHECK: [vw] [ vw] [vw ] [wx] [ wx] [wx ] [xy] [ xy] [xy ] [yz] [ yz] [yz ]
+B(x,)
+// CHECK: [vw] [ vw] [vw ] [wx] [ wx] [wx ] [x] [ x] [x ] [z] [ z] [z ]
+B(,y)
+// CHECK: [vw] [ vw] [vw ] [w] [ w] [w ] [y] [ y] [y ] [yz] [ yz] [yz ]
+B(,)
+// CHECK: [vw] [ vw] [vw ] [w] [ w] [w ] [] [ ] [ ] [z] [ z] [z ]
+
+#define C(x, y, z) [x ## y ## z]
+C(,,) C(a,,) C(,b,) C(,,c) C(a,b,) C(a,,c) C(,b,c) C(a,b,c)
+// CHECK: [] [a] [b] [c] [ab] [ac] [bc] [abc]
diff --git a/test/Preprocessor/macro_redefined.c b/test/Preprocessor/macro_redefined.c
new file mode 100644
index 0000000..f7d3d6d
--- /dev/null
+++ b/test/Preprocessor/macro_redefined.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 %s -Eonly -verify -Wno-all -Wmacro-redefined -DCLI_MACRO=1 -DWMACRO_REDEFINED
+// RUN: %clang_cc1 %s -Eonly -verify -Wno-all -Wno-macro-redefined -DCLI_MACRO=1
+
+#ifndef WMACRO_REDEFINED
+// expected-no-diagnostics
+#endif
+
+#ifdef WMACRO_REDEFINED
+// expected-note@1 {{previous definition is here}}
+// expected-warning@+2 {{macro redefined}}
+#endif
+#define CLI_MACRO
+
+#ifdef WMACRO_REDEFINED
+// expected-note@+3 {{previous definition is here}}
+// expected-warning@+3 {{macro redefined}}
+#endif
+#define REGULAR_MACRO
+#define REGULAR_MACRO 1
diff --git a/test/Preprocessor/macro_space.c b/test/Preprocessor/macro_space.c
index 8a47a3b..13e531f 100644
--- a/test/Preprocessor/macro_space.c
+++ b/test/Preprocessor/macro_space.c
@@ -1,6 +1,36 @@
 // RUN: %clang_cc1 -E %s | FileCheck --strict-whitespace %s
 
-#define XX
-! XX,
+#define FOO1()
+#define FOO2(x)x
+#define FOO3(x) x
+#define FOO4(x)x x
+#define FOO5(x) x x
+#define FOO6(x) [x]
+#define FOO7(x) [ x]
+#define FOO8(x) [x ]
 
-// CHECK: {{^}}! ,{{$}}
+#define TEST(FOO,x) FOO <FOO()> < FOO()> <FOO ()> <FOO( )> <FOO() > <FOO()x> <FOO() x> < FOO()x>
+
+TEST(FOO1,)
+// CHECK: FOO1 <> < > <> <> < > <> < > < >
+
+TEST(FOO2,)
+// CHECK: FOO2 <> < > <> <> < > <> < > < >
+
+TEST(FOO3,)
+// CHECK: FOO3 <> < > <> <> < > <> < > < >
+
+TEST(FOO4,)
+// CHECK: FOO4 < > < > < > < > < > < > < > < >
+
+TEST(FOO5,)
+// CHECK: FOO5 < > < > < > < > < > < > < > < >
+
+TEST(FOO6,)
+// CHECK: FOO6 <[]> < []> <[]> <[]> <[] > <[]> <[] > < []>
+
+TEST(FOO7,)
+// CHECK: FOO7 <[ ]> < [ ]> <[ ]> <[ ]> <[ ] > <[ ]> <[ ] > < [ ]>
+
+TEST(FOO8,)
+// CHECK: FOO8 <[ ]> < [ ]> <[ ]> <[ ]> <[ ] > <[ ]> <[ ] > < [ ]>
diff --git a/test/Preprocessor/microsoft-header-search.c b/test/Preprocessor/microsoft-header-search.c
new file mode 100644
index 0000000..2cdc54e
--- /dev/null
+++ b/test/Preprocessor/microsoft-header-search.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -I%S/Inputs/microsoft-header-search %s -fms-compatibility -verify
+
+// expected-warning@Inputs/microsoft-header-search/a/findme.h:3 {{findme.h successfully included using MS search rules}}
+// expected-warning@Inputs/microsoft-header-search/a/b/include3.h:3 {{#include resolved using non-portable MSVC search rules as}}
+
+// expected-warning@Inputs/microsoft-header-search/falsepos.h:3 {{successfully resolved the falsepos.h header}}
+
+#include "Inputs/microsoft-header-search/include1.h"
diff --git a/test/Preprocessor/predefined-arch-macros.c b/test/Preprocessor/predefined-arch-macros.c
index 26298f9..cba458e 100644
--- a/test/Preprocessor/predefined-arch-macros.c
+++ b/test/Preprocessor/predefined-arch-macros.c
@@ -1437,6 +1437,76 @@
 // CHECK_BDVER3_M64: #define __tune_bdver3__ 1
 // CHECK_BDVER3_M64: #define __x86_64 1
 // CHECK_BDVER3_M64: #define __x86_64__ 1
+// RUN: %clang -march=bdver4 -m32 -E -dM %s -o - 2>&1 \
+// RUN:     -target i386-unknown-linux \
+// RUN:   | FileCheck %s -check-prefix=CHECK_BDVER4_M32
+// CHECK_BDVER4_M32-NOT: #define __3dNOW_A__ 1
+// CHECK_BDVER4_M32-NOT: #define __3dNOW__ 1
+// CHECK_BDVER4_M32: #define __AES__ 1
+// CHECK_BDVER4_M32: #define __AVX2__ 1
+// CHECK_BDVER4_M32: #define __AVX__ 1
+// CHECK_BDVER4_M32: #define __BMI2__ 1
+// CHECK_BDVER4_M32: #define __BMI__ 1
+// CHECK_BDVER4_M32: #define __F16C__ 1
+// CHECK_BDVER4_M32: #define __FMA4__ 1
+// CHECK_BDVER4_M32: #define __FMA__ 1
+// CHECK_BDVER4_M32: #define __LZCNT__ 1
+// CHECK_BDVER4_M32: #define __MMX__ 1
+// CHECK_BDVER4_M32: #define __PCLMUL__ 1
+// CHECK_BDVER4_M32: #define __POPCNT__ 1
+// CHECK_BDVER4_M32: #define __PRFCHW__ 1
+// CHECK_BDVER4_M32: #define __SSE2_MATH__ 1
+// CHECK_BDVER4_M32: #define __SSE2__ 1
+// CHECK_BDVER4_M32: #define __SSE3__ 1
+// CHECK_BDVER4_M32: #define __SSE4A__ 1
+// CHECK_BDVER4_M32: #define __SSE4_1__ 1
+// CHECK_BDVER4_M32: #define __SSE4_2__ 1
+// CHECK_BDVER4_M32: #define __SSE_MATH__ 1
+// CHECK_BDVER4_M32: #define __SSE__ 1
+// CHECK_BDVER4_M32: #define __SSSE3__ 1
+// CHECK_BDVER4_M32: #define __TBM__ 1
+// CHECK_BDVER4_M32: #define __XOP__ 1
+// CHECK_BDVER4_M32: #define __bdver4 1
+// CHECK_BDVER4_M32: #define __bdver4__ 1
+// CHECK_BDVER4_M32: #define __i386 1
+// CHECK_BDVER4_M32: #define __i386__ 1
+// CHECK_BDVER4_M32: #define __tune_bdver4__ 1
+// RUN: %clang -march=bdver4 -m64 -E -dM %s -o - 2>&1 \
+// RUN:     -target i386-unknown-linux \
+// RUN:   | FileCheck %s -check-prefix=CHECK_BDVER4_M64
+// CHECK_BDVER4_M64-NOT: #define __3dNOW_A__ 1
+// CHECK_BDVER4_M64-NOT: #define __3dNOW__ 1
+// CHECK_BDVER4_M64: #define __AES__ 1
+// CHECK_BDVER4_M64: #define __AVX2__ 1
+// CHECK_BDVER4_M64: #define __AVX__ 1
+// CHECK_BDVER4_M64: #define __BMI2__ 1
+// CHECK_BDVER4_M64: #define __BMI__ 1
+// CHECK_BDVER4_M64: #define __F16C__ 1
+// CHECK_BDVER4_M64: #define __FMA4__ 1
+// CHECK_BDVER4_M64: #define __FMA__ 1
+// CHECK_BDVER4_M64: #define __LZCNT__ 1
+// CHECK_BDVER4_M64: #define __MMX__ 1
+// CHECK_BDVER4_M64: #define __PCLMUL__ 1
+// CHECK_BDVER4_M64: #define __POPCNT__ 1
+// CHECK_BDVER4_M64: #define __PRFCHW__ 1
+// CHECK_BDVER4_M64: #define __SSE2_MATH__ 1
+// CHECK_BDVER4_M64: #define __SSE2__ 1
+// CHECK_BDVER4_M64: #define __SSE3__ 1
+// CHECK_BDVER4_M64: #define __SSE4A__ 1
+// CHECK_BDVER4_M64: #define __SSE4_1__ 1
+// CHECK_BDVER4_M64: #define __SSE4_2__ 1
+// CHECK_BDVER4_M64: #define __SSE_MATH__ 1
+// CHECK_BDVER4_M64: #define __SSE__ 1
+// CHECK_BDVER4_M64: #define __SSSE3__ 1
+// CHECK_BDVER4_M64: #define __TBM__ 1
+// CHECK_BDVER4_M64: #define __XOP__ 1
+// CHECK_BDVER4_M64: #define __amd64 1
+// CHECK_BDVER4_M64: #define __amd64__ 1
+// CHECK_BDVER4_M64: #define __bdver4 1
+// CHECK_BDVER4_M64: #define __bdver4__ 1
+// CHECK_BDVER4_M64: #define __tune_bdver4__ 1
+// CHECK_BDVER4_M64: #define __x86_64 1
+// CHECK_BDVER4_M64: #define __x86_64__ 1
 //
 // End X86/GCC/Linux tests ------------------
 
diff --git a/test/Preprocessor/predefined-macros.c b/test/Preprocessor/predefined-macros.c
index 11449f9..1db9080 100644
--- a/test/Preprocessor/predefined-macros.c
+++ b/test/Preprocessor/predefined-macros.c
@@ -1,14 +1,86 @@
 // This test verifies that the correct macros are predefined.
 //
 // RUN: %clang_cc1 %s -E -dM -triple i686-pc-win32 -fms-extensions -fms-compatibility \
-// RUN:     -fmsc-version=1300 -o - | FileCheck %s --check-prefix=CHECK-MS
+// RUN:     -fms-compatibility-version=13.00 -o - | FileCheck %s --check-prefix=CHECK-MS
 // CHECK-MS: #define _INTEGRAL_MAX_BITS 64
 // CHECK-MS: #define _MSC_EXTENSIONS 1
 // CHECK-MS: #define _MSC_VER 1300
 // CHECK-MS: #define _M_IX86 600
 // CHECK-MS: #define _M_IX86_FP
 // CHECK-MS: #define _WIN32 1
-// CHECK-MS-NOT: #define __GNUC__
+// CHECK-MS-NOT: #define __STRICT_ANSI__
+// CHECK-MS-NOT: GCC
+// CHECK-MS-NOT: GNU
+// CHECK-MS-NOT: GXX
+//
+// RUN: %clang_cc1 %s -E -dM -triple x86_64-pc-win32 -fms-extensions -fms-compatibility \
+// RUN:     -fms-compatibility-version=13.00 -o - | FileCheck %s --check-prefix=CHECK-MS64
+// CHECK-MS64: #define _INTEGRAL_MAX_BITS 64
+// CHECK-MS64: #define _MSC_EXTENSIONS 1
+// CHECK-MS64: #define _MSC_VER 1300
+// CHECK-MS64: #define _M_AMD64 1
+// CHECK-MS64: #define _M_X64 1
+// CHECK-MS64: #define _WIN64 1
+// CHECK-MS64-NOT: #define __STRICT_ANSI__
+// CHECK-MS64-NOT: GCC
+// CHECK-MS64-NOT: GNU
+// CHECK-MS64-NOT: GXX
+//
+// RUN: %clang_cc1 %s -E -dM -triple i686-pc-win32 -fms-compatibility \
+// RUN:     -o - | FileCheck %s --check-prefix=CHECK-MS-STDINT
+// CHECK-MS-STDINT-NOT:#define __INT16_MAX__ 32767
+// CHECK-MS-STDINT-NOT:#define __INT32_MAX__ 2147483647
+// CHECK-MS-STDINT-NOT:#define __INT64_MAX__ 9223372036854775807LL
+// CHECK-MS-STDINT-NOT:#define __INT8_MAX__ 127
+// CHECK-MS-STDINT-NOT:#define __INTPTR_MAX__ 2147483647
+// CHECK-MS-STDINT-NOT:#define __INT_FAST16_MAX__ 32767
+// CHECK-MS-STDINT-NOT:#define __INT_FAST16_TYPE__ short
+// CHECK-MS-STDINT-NOT:#define __INT_FAST32_MAX__ 2147483647
+// CHECK-MS-STDINT-NOT:#define __INT_FAST32_TYPE__ int
+// CHECK-MS-STDINT-NOT:#define __INT_FAST64_MAX__ 9223372036854775807LL
+// CHECK-MS-STDINT-NOT:#define __INT_FAST64_TYPE__ long long int
+// CHECK-MS-STDINT-NOT:#define __INT_FAST8_MAX__ 127
+// CHECK-MS-STDINT-NOT:#define __INT_FAST8_TYPE__ char
+// CHECK-MS-STDINT-NOT:#define __INT_LEAST16_MAX__ 32767
+// CHECK-MS-STDINT-NOT:#define __INT_LEAST16_TYPE__ short
+// CHECK-MS-STDINT-NOT:#define __INT_LEAST32_MAX__ 2147483647
+// CHECK-MS-STDINT-NOT:#define __INT_LEAST32_TYPE__ int
+// CHECK-MS-STDINT-NOT:#define __INT_LEAST64_MAX__ 9223372036854775807LL
+// CHECK-MS-STDINT-NOT:#define __INT_LEAST64_TYPE__ long long int
+// CHECK-MS-STDINT-NOT:#define __INT_LEAST8_MAX__ 127
+// CHECK-MS-STDINT-NOT:#define __INT_LEAST8_TYPE__ char
+// CHECK-MS-STDINT-NOT:#define __UINT16_C_SUFFIX__ U
+// CHECK-MS-STDINT-NOT:#define __UINT16_MAX__ 65535U
+// CHECK-MS-STDINT-NOT:#define __UINT16_TYPE__ unsigned short
+// CHECK-MS-STDINT-NOT:#define __UINT32_C_SUFFIX__ U
+// CHECK-MS-STDINT-NOT:#define __UINT32_MAX__ 4294967295U
+// CHECK-MS-STDINT-NOT:#define __UINT32_TYPE__ unsigned int
+// CHECK-MS-STDINT-NOT:#define __UINT64_C_SUFFIX__ ULL
+// CHECK-MS-STDINT-NOT:#define __UINT64_MAX__ 18446744073709551615ULL
+// CHECK-MS-STDINT-NOT:#define __UINT64_TYPE__ long long unsigned int
+// CHECK-MS-STDINT-NOT:#define __UINT8_C_SUFFIX__ U
+// CHECK-MS-STDINT-NOT:#define __UINT8_MAX__ 255U
+// CHECK-MS-STDINT-NOT:#define __UINT8_TYPE__ unsigned char
+// CHECK-MS-STDINT-NOT:#define __UINTMAX_MAX__ 18446744073709551615ULL
+// CHECK-MS-STDINT-NOT:#define __UINTPTR_MAX__ 4294967295U
+// CHECK-MS-STDINT-NOT:#define __UINTPTR_TYPE__ unsigned int
+// CHECK-MS-STDINT-NOT:#define __UINTPTR_WIDTH__ 32
+// CHECK-MS-STDINT-NOT:#define __UINT_FAST16_MAX__ 65535U
+// CHECK-MS-STDINT-NOT:#define __UINT_FAST16_TYPE__ unsigned short
+// CHECK-MS-STDINT-NOT:#define __UINT_FAST32_MAX__ 4294967295U
+// CHECK-MS-STDINT-NOT:#define __UINT_FAST32_TYPE__ unsigned int
+// CHECK-MS-STDINT-NOT:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
+// CHECK-MS-STDINT-NOT:#define __UINT_FAST64_TYPE__ long long unsigned int
+// CHECK-MS-STDINT-NOT:#define __UINT_FAST8_MAX__ 255U
+// CHECK-MS-STDINT-NOT:#define __UINT_FAST8_TYPE__ unsigned char
+// CHECK-MS-STDINT-NOT:#define __UINT_LEAST16_MAX__ 65535U
+// CHECK-MS-STDINT-NOT:#define __UINT_LEAST16_TYPE__ unsigned short
+// CHECK-MS-STDINT-NOT:#define __UINT_LEAST32_MAX__ 4294967295U
+// CHECK-MS-STDINT-NOT:#define __UINT_LEAST32_TYPE__ unsigned int
+// CHECK-MS-STDINT-NOT:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
+// CHECK-MS-STDINT-NOT:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// CHECK-MS-STDINT-NOT:#define __UINT_LEAST8_MAX__ 255U
+// CHECK-MS-STDINT-NOT:#define __UINT_LEAST8_TYPE__ unsigned char
 //
 // RUN: %clang_cc1 %s -E -dM -ffast-math -o - \
 // RUN:   | FileCheck %s --check-prefix=CHECK-FAST-MATH
diff --git a/test/Preprocessor/print-pragma-microsoft.c b/test/Preprocessor/print-pragma-microsoft.c
new file mode 100644
index 0000000..5c4fb4f
--- /dev/null
+++ b/test/Preprocessor/print-pragma-microsoft.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 %s -fsyntax-only -fms-extensions -E -o - | FileCheck %s
+
+#define BAR "2"
+#pragma comment(linker, "bar=" BAR)
+// CHECK: #pragma comment(linker, "bar=" "2")
+#pragma comment(user, "Compiled on " __DATE__ " at " __TIME__)
+// CHECK: #pragma comment(user, "Compiled on " "{{[^"]*}}" " at " "{{[^"]*}}")
+
+#define KEY1 "KEY1"
+#define KEY2 "KEY2"
+#define VAL1 "VAL1\""
+#define VAL2 "VAL2"
+
+#pragma detect_mismatch(KEY1 KEY2, VAL1 VAL2)
+// CHECK: #pragma detect_mismatch("KEY1" "KEY2", "VAL1\"" "VAL2")
+
+#define _CRT_PACKING 8
+#pragma pack(push, _CRT_PACKING)
+// CHECK: #pragma pack(push, 8)
+#pragma pack(pop)
diff --git a/test/Preprocessor/stdint.c b/test/Preprocessor/stdint.c
index b92cfe7..94d5b0b 100644
--- a/test/Preprocessor/stdint.c
+++ b/test/Preprocessor/stdint.c
@@ -1,20 +1,20 @@
 // RUN: %clang_cc1 -E -ffreestanding -triple=arm-none-none %s | FileCheck -check-prefix ARM %s
 //
-// ARM:typedef signed long long int int64_t;
-// ARM:typedef unsigned long long int uint64_t;
+// ARM:typedef long long int int64_t;
+// ARM:typedef long long unsigned int uint64_t;
 // ARM:typedef int64_t int_least64_t;
 // ARM:typedef uint64_t uint_least64_t;
 // ARM:typedef int64_t int_fast64_t;
 // ARM:typedef uint64_t uint_fast64_t;
 //
-// ARM:typedef signed int int32_t;
+// ARM:typedef int int32_t;
 // ARM:typedef unsigned int uint32_t;
 // ARM:typedef int32_t int_least32_t;
 // ARM:typedef uint32_t uint_least32_t;
 // ARM:typedef int32_t int_fast32_t;
 // ARM:typedef uint32_t uint_fast32_t;
 // 
-// ARM:typedef signed short int16_t;
+// ARM:typedef short int16_t;
 // ARM:typedef unsigned short uint16_t;
 // ARM:typedef int16_t int_least16_t;
 // ARM:typedef uint16_t uint_least16_t;
@@ -108,21 +108,21 @@
 //
 // RUN: %clang_cc1 -E -ffreestanding -triple=i386-none-none %s | FileCheck -check-prefix I386 %s
 //
-// I386:typedef signed long long int int64_t;
-// I386:typedef unsigned long long int uint64_t;
+// I386:typedef long long int int64_t;
+// I386:typedef long long unsigned int uint64_t;
 // I386:typedef int64_t int_least64_t;
 // I386:typedef uint64_t uint_least64_t;
 // I386:typedef int64_t int_fast64_t;
 // I386:typedef uint64_t uint_fast64_t;
 //
-// I386:typedef signed int int32_t;
+// I386:typedef int int32_t;
 // I386:typedef unsigned int uint32_t;
 // I386:typedef int32_t int_least32_t;
 // I386:typedef uint32_t uint_least32_t;
 // I386:typedef int32_t int_fast32_t;
 // I386:typedef uint32_t uint_fast32_t;
 //
-// I386:typedef signed short int16_t;
+// I386:typedef short int16_t;
 // I386:typedef unsigned short uint16_t;
 // I386:typedef int16_t int_least16_t;
 // I386:typedef uint16_t uint_least16_t;
@@ -215,21 +215,21 @@
 //
 // RUN: %clang_cc1 -E -ffreestanding -triple=mips-none-none %s | FileCheck -check-prefix MIPS %s
 //
-// MIPS:typedef signed long long int int64_t;
-// MIPS:typedef unsigned long long int uint64_t;
+// MIPS:typedef long long int int64_t;
+// MIPS:typedef long long unsigned int uint64_t;
 // MIPS:typedef int64_t int_least64_t;
 // MIPS:typedef uint64_t uint_least64_t;
 // MIPS:typedef int64_t int_fast64_t;
 // MIPS:typedef uint64_t uint_fast64_t;
 //
-// MIPS:typedef signed int int32_t;
+// MIPS:typedef int int32_t;
 // MIPS:typedef unsigned int uint32_t;
 // MIPS:typedef int32_t int_least32_t;
 // MIPS:typedef uint32_t uint_least32_t;
 // MIPS:typedef int32_t int_fast32_t;
 // MIPS:typedef uint32_t uint_fast32_t;
 //
-// MIPS:typedef signed short int16_t;
+// MIPS:typedef short int16_t;
 // MIPS:typedef unsigned short uint16_t;
 // MIPS:typedef int16_t int_least16_t;
 // MIPS:typedef uint16_t uint_least16_t;
@@ -322,21 +322,21 @@
 //
 // RUN: %clang_cc1 -E -ffreestanding -triple=mips64-none-none %s | FileCheck -check-prefix MIPS64 %s
 //
-// MIPS64:typedef signed long long int int64_t;
-// MIPS64:typedef unsigned long long int uint64_t;
+// MIPS64:typedef long long int int64_t;
+// MIPS64:typedef long long unsigned int uint64_t;
 // MIPS64:typedef int64_t int_least64_t;
 // MIPS64:typedef uint64_t uint_least64_t;
 // MIPS64:typedef int64_t int_fast64_t;
 // MIPS64:typedef uint64_t uint_fast64_t;
 //
-// MIPS64:typedef signed int int32_t;
+// MIPS64:typedef int int32_t;
 // MIPS64:typedef unsigned int uint32_t;
 // MIPS64:typedef int32_t int_least32_t;
 // MIPS64:typedef uint32_t uint_least32_t;
 // MIPS64:typedef int32_t int_fast32_t;
 // MIPS64:typedef uint32_t uint_fast32_t;
 //
-// MIPS64:typedef signed short int16_t;
+// MIPS64:typedef short int16_t;
 // MIPS64:typedef unsigned short uint16_t;
 // MIPS64:typedef int16_t int_least16_t;
 // MIPS64:typedef uint16_t uint_least16_t;
@@ -429,14 +429,14 @@
 //
 // RUN: %clang_cc1 -E -ffreestanding -triple=msp430-none-none %s | FileCheck -check-prefix MSP430 %s
 //
-// MSP430:typedef signed long int int32_t;
-// MSP430:typedef unsigned long int uint32_t;
+// MSP430:typedef long int int32_t;
+// MSP430:typedef long unsigned int uint32_t;
 // MSP430:typedef int32_t int_least32_t;
 // MSP430:typedef uint32_t uint_least32_t;
 // MSP430:typedef int32_t int_fast32_t;
 // MSP430:typedef uint32_t uint_fast32_t;
 //
-// MSP430:typedef signed short int16_t;
+// MSP430:typedef short int16_t;
 // MSP430:typedef unsigned short uint16_t;
 // MSP430:typedef int16_t int_least16_t;
 // MSP430:typedef uint16_t uint_least16_t;
@@ -529,21 +529,21 @@
 //
 // RUN: %clang_cc1 -E -ffreestanding -triple=powerpc64-none-none %s | FileCheck -check-prefix PPC64 %s
 //
-// PPC64:typedef signed long int int64_t;
-// PPC64:typedef unsigned long int uint64_t;
+// PPC64:typedef long int int64_t;
+// PPC64:typedef long unsigned int uint64_t;
 // PPC64:typedef int64_t int_least64_t;
 // PPC64:typedef uint64_t uint_least64_t;
 // PPC64:typedef int64_t int_fast64_t;
 // PPC64:typedef uint64_t uint_fast64_t;
 //
-// PPC64:typedef signed int int32_t;
+// PPC64:typedef int int32_t;
 // PPC64:typedef unsigned int uint32_t;
 // PPC64:typedef int32_t int_least32_t;
 // PPC64:typedef uint32_t uint_least32_t;
 // PPC64:typedef int32_t int_fast32_t;
 // PPC64:typedef uint32_t uint_fast32_t;
 //
-// PPC64:typedef signed short int16_t;
+// PPC64:typedef short int16_t;
 // PPC64:typedef unsigned short uint16_t;
 // PPC64:typedef int16_t int_least16_t;
 // PPC64:typedef uint16_t uint_least16_t;
@@ -637,21 +637,21 @@
 // RUN: %clang_cc1 -E -ffreestanding -triple=powerpc-none-none %s | FileCheck -check-prefix PPC %s
 //
 //
-// PPC:typedef signed long long int int64_t;
-// PPC:typedef unsigned long long int uint64_t;
+// PPC:typedef long long int int64_t;
+// PPC:typedef long long unsigned int uint64_t;
 // PPC:typedef int64_t int_least64_t;
 // PPC:typedef uint64_t uint_least64_t;
 // PPC:typedef int64_t int_fast64_t;
 // PPC:typedef uint64_t uint_fast64_t;
 //
-// PPC:typedef signed int int32_t;
+// PPC:typedef int int32_t;
 // PPC:typedef unsigned int uint32_t;
 // PPC:typedef int32_t int_least32_t;
 // PPC:typedef uint32_t uint_least32_t;
 // PPC:typedef int32_t int_fast32_t;
 // PPC:typedef uint32_t uint_fast32_t;
 //
-// PPC:typedef signed short int16_t;
+// PPC:typedef short int16_t;
 // PPC:typedef unsigned short uint16_t;
 // PPC:typedef int16_t int_least16_t;
 // PPC:typedef uint16_t uint_least16_t;
@@ -744,21 +744,21 @@
 //
 // RUN: %clang_cc1 -E -ffreestanding -triple=s390x-none-none %s | FileCheck -check-prefix S390X %s
 //
-// S390X:typedef signed long long int int64_t;
-// S390X:typedef unsigned long long int uint64_t;
+// S390X:typedef long long int int64_t;
+// S390X:typedef long long unsigned int uint64_t;
 // S390X:typedef int64_t int_least64_t;
 // S390X:typedef uint64_t uint_least64_t;
 // S390X:typedef int64_t int_fast64_t;
 // S390X:typedef uint64_t uint_fast64_t;
 //
-// S390X:typedef signed int int32_t;
+// S390X:typedef int int32_t;
 // S390X:typedef unsigned int uint32_t;
 // S390X:typedef int32_t int_least32_t;
 // S390X:typedef uint32_t uint_least32_t;
 // S390X:typedef int32_t int_fast32_t;
 // S390X:typedef uint32_t uint_fast32_t;
 //
-// S390X:typedef signed short int16_t;
+// S390X:typedef short int16_t;
 // S390X:typedef unsigned short uint16_t;
 // S390X:typedef int16_t int_least16_t;
 // S390X:typedef uint16_t uint_least16_t;
@@ -851,21 +851,21 @@
 //
 // RUN: %clang_cc1 -E -ffreestanding -triple=sparc-none-none %s | FileCheck -check-prefix SPARC %s
 //
-// SPARC:typedef signed long long int int64_t;
-// SPARC:typedef unsigned long long int uint64_t;
+// SPARC:typedef long long int int64_t;
+// SPARC:typedef long long unsigned int uint64_t;
 // SPARC:typedef int64_t int_least64_t;
 // SPARC:typedef uint64_t uint_least64_t;
 // SPARC:typedef int64_t int_fast64_t;
 // SPARC:typedef uint64_t uint_fast64_t;
 //
-// SPARC:typedef signed int int32_t;
+// SPARC:typedef int int32_t;
 // SPARC:typedef unsigned int uint32_t;
 // SPARC:typedef int32_t int_least32_t;
 // SPARC:typedef uint32_t uint_least32_t;
 // SPARC:typedef int32_t int_fast32_t;
 // SPARC:typedef uint32_t uint_fast32_t;
 //
-// SPARC:typedef signed short int16_t;
+// SPARC:typedef short int16_t;
 // SPARC:typedef unsigned short uint16_t;
 // SPARC:typedef int16_t int_least16_t;
 // SPARC:typedef uint16_t uint_least16_t;
@@ -958,14 +958,14 @@
 //
 // RUN: %clang_cc1 -E -ffreestanding -triple=tce-none-none %s | FileCheck -check-prefix TCE %s
 //
-// TCE:typedef signed int int32_t;
+// TCE:typedef int int32_t;
 // TCE:typedef unsigned int uint32_t;
 // TCE:typedef int32_t int_least32_t;
 // TCE:typedef uint32_t uint_least32_t;
 // TCE:typedef int32_t int_fast32_t;
 // TCE:typedef uint32_t uint_fast32_t;
 //
-// TCE:typedef signed short int16_t;
+// TCE:typedef short int16_t;
 // TCE:typedef unsigned short uint16_t;
 // TCE:typedef int16_t int_least16_t;
 // TCE:typedef uint16_t uint_least16_t;
@@ -1059,21 +1059,21 @@
 // RUN: %clang_cc1 -E -ffreestanding -triple=x86_64-none-none %s | FileCheck -check-prefix X86_64 %s
 //
 //
-// X86_64:typedef signed long int int64_t;
-// X86_64:typedef unsigned long int uint64_t;
+// X86_64:typedef long int int64_t;
+// X86_64:typedef long unsigned int uint64_t;
 // X86_64:typedef int64_t int_least64_t;
 // X86_64:typedef uint64_t uint_least64_t;
 // X86_64:typedef int64_t int_fast64_t;
 // X86_64:typedef uint64_t uint_fast64_t;
 //
-// X86_64:typedef signed int int32_t;
+// X86_64:typedef int int32_t;
 // X86_64:typedef unsigned int uint32_t;
 // X86_64:typedef int32_t int_least32_t;
 // X86_64:typedef uint32_t uint_least32_t;
 // X86_64:typedef int32_t int_fast32_t;
 // X86_64:typedef uint32_t uint_fast32_t;
 //
-// X86_64:typedef signed short int16_t;
+// X86_64:typedef short int16_t;
 // X86_64:typedef unsigned short uint16_t;
 // X86_64:typedef int16_t int_least16_t;
 // X86_64:typedef uint16_t uint_least16_t;
@@ -1173,27 +1173,27 @@
 //
 // RUN: %clang_cc1 -E -ffreestanding -triple=i386-mingw32 %s | FileCheck -check-prefix I386_MINGW32 %s
 //
-// I386_MINGW32:WCHAR_MAX_ 65535U
-// I386_MINGW32:WCHAR_MIN_ 0U
+// I386_MINGW32:WCHAR_MAX_ 65535
+// I386_MINGW32:WCHAR_MIN_ 0
 //
 //
 // RUN: %clang_cc1 -E -ffreestanding -triple=xcore-none-none %s | FileCheck -check-prefix XCORE %s
 //
-// XCORE:typedef signed long long int int64_t;
-// XCORE:typedef unsigned long long int uint64_t;
+// XCORE:typedef long long int int64_t;
+// XCORE:typedef long long unsigned int uint64_t;
 // XCORE:typedef int64_t int_least64_t;
 // XCORE:typedef uint64_t uint_least64_t;
 // XCORE:typedef int64_t int_fast64_t;
 // XCORE:typedef uint64_t uint_fast64_t;
 //
-// XCORE:typedef signed int int32_t;
+// XCORE:typedef int int32_t;
 // XCORE:typedef unsigned int uint32_t;
 // XCORE:typedef int32_t int_least32_t;
 // XCORE:typedef uint32_t uint_least32_t;
 // XCORE:typedef int32_t int_fast32_t;
 // XCORE:typedef uint32_t uint_fast32_t;
 //
-// XCORE:typedef signed short int16_t;
+// XCORE:typedef short int16_t;
 // XCORE:typedef unsigned short uint16_t;
 // XCORE:typedef int16_t int_least16_t;
 // XCORE:typedef uint16_t uint_least16_t;
@@ -1269,7 +1269,7 @@
 // XCORE:WINT_MIN_ 0U
 // XCORE:WINT_MAX_ 4294967295U
 //
-// XCORE:WCHAR_MAX_ 255U
+// XCORE:WCHAR_MAX_ 255
 // XCORE:WCHAR_MIN_ 0
 //
 // XCORE:INT8_C_(0) 0
diff --git a/test/Preprocessor/ucn-allowed-chars.c b/test/Preprocessor/ucn-allowed-chars.c
index d49aa9c..d7d67fe 100644
--- a/test/Preprocessor/ucn-allowed-chars.c
+++ b/test/Preprocessor/ucn-allowed-chars.c
@@ -17,7 +17,7 @@
 // Identifier initial characters
 extern char \u0E50; // C++03, C11, C++11
 extern char \u0300; // disallowed initially in C11/C++11, always in C99/C++03
-
+extern char \u0D61; // C99, C11, C++03, C++11
 
 
 
diff --git a/test/Preprocessor/ucn-pp-identifier.c b/test/Preprocessor/ucn-pp-identifier.c
index 6936ed9..f045e38 100644
--- a/test/Preprocessor/ucn-pp-identifier.c
+++ b/test/Preprocessor/ucn-pp-identifier.c
@@ -24,9 +24,9 @@
 #endif
 
 // Make sure we reject disallowed UCNs
-#define \ufffe // expected-error {{macro names must be identifiers}}
-#define \U10000000  // expected-error {{macro names must be identifiers}}
-#define \u0061  // expected-error {{character 'a' cannot be specified by a universal character name}} expected-error {{macro names must be identifiers}}
+#define \ufffe // expected-error {{macro name must be an identifier}}
+#define \U10000000  // expected-error {{macro name must be an identifier}}
+#define \u0061  // expected-error {{character 'a' cannot be specified by a universal character name}} expected-error {{macro name must be an identifier}}
 
 // FIXME: Not clear what our behavior should be here; \u0024 is "$".
 #define a\u0024  // expected-warning {{whitespace}}
diff --git a/test/Preprocessor/woa-defaults.c b/test/Preprocessor/woa-defaults.c
new file mode 100644
index 0000000..6eab3b9
--- /dev/null
+++ b/test/Preprocessor/woa-defaults.c
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -dM -triple armv7-windows -E %s | FileCheck %s
+// RUN: %clang_cc1 -dM -fno-signed-char -triple armv7-windows -E %s \
+// RUN:   | FileCheck %s -check-prefix CHECK-UNSIGNED-CHAR
+
+// CHECK: #define _INTEGRAL_MAX_BITS 64
+// CHECK: #define _M_ARM 7
+// CHECK: #define _M_ARMT _M_ARM
+// CHECK: #define _M_ARM_FP 31
+// CHECK: #define _M_ARM_NT 1
+// CHECK: #define _M_THUMB _M_ARM
+// CHECK: #define _WIN32 1
+
+// CHECK: #define __ARM_PCS 1
+// CHECK: #define __ARM_PCS_VFP 1
+// CHECK: #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
+// CHECK: #define __SIZEOF_DOUBLE__ 8
+// CHECK: #define __SIZEOF_FLOAT__ 4
+// CHECK: #define __SIZEOF_INT__ 4
+// CHECK: #define __SIZEOF_LONG_DOUBLE__ 8
+// CHECK: #define __SIZEOF_LONG_LONG__ 8
+// CHECK: #define __SIZEOF_LONG__ 4
+// CHECK: #define __SIZEOF_POINTER__ 4
+// CHECK: #define __SIZEOF_PTRDIFF_T__ 4
+// CHECK: #define __SIZEOF_SHORT__ 2
+// CHECK: #define __SIZEOF_SIZE_T__ 4
+// CHECK: #define __SIZEOF_WCHAR_T__ 2
+// CHECK: #define __SIZEOF_WINT_T__ 4
+
+// CHECK-NOT: __THUMB_INTERWORK__
+// CHECK-NOT: __ARM_EABI__
+// CHECK-NOT: _CHAR_UNSIGNED
+
+// CHECK-UNSIGNED-CHAR: #define _CHAR_UNSIGNED 1
diff --git a/test/Preprocessor/woa-wchar_t.c b/test/Preprocessor/woa-wchar_t.c
new file mode 100644
index 0000000..eb9a862
--- /dev/null
+++ b/test/Preprocessor/woa-wchar_t.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -dM -triple armv7-windows -E %s | FileCheck %s
+// RUN: %clang_cc1 -dM -fno-signed-char -triple armv7-windows -E %s | FileCheck %s
+
+// CHECK: #define __WCHAR_TYPE__ unsigned short
+
diff --git a/test/Preprocessor/x86_target_features.c b/test/Preprocessor/x86_target_features.c
index 751c8ae..7bc5cd8 100644
--- a/test/Preprocessor/x86_target_features.c
+++ b/test/Preprocessor/x86_target_features.c
@@ -193,16 +193,16 @@
 // SHA: #define __SSE2__ 1
 // SHA-NOT: #define __SSE3__ 1
 
-// run: %clang -target i386-unknown-unknown -march=pentiumpro -msha -mno-sha -x c -e -dm -o - %s | filecheck --check-prefix=SHANOSHA %s
+// RUN: %clang -target i386-unknown-unknown -march=pentiumpro -msha -mno-sha -x c -E -dM -o - %s | FileCheck --check-prefix=SHANOSHA %s
 
 // SHANOSHA-NOT: #define __SHA__ 1
 // SHANOSHA-NOT: #define __SSE2__ 1
 
-// run: %clang -target i386-unknown-unknown -march=pentiumpro -msha -mno-sse2 -x c -e -dm -o - %s | filecheck --check-prefix=SHANOSSE2 %s
+// RUN: %clang -target i386-unknown-unknown -march=pentiumpro -msha -mno-sse2 -x c -E -dM -o - %s | FileCheck --check-prefix=SHANOSSE2 %s
 
-// SHANOSSSE2-NOT: #define __SHA__ 1
-// SHANOSSSE2-NOT: #define __SSE2__ 1
-// SHANOSSSE2-NOT: #define __SSE3__ 1
+// SHANOSSE2-NOT: #define __SHA__ 1
+// SHANOSSE2-NOT: #define __SSE2__ 1
+// SHANOSSE2-NOT: #define __SSE3__ 1
 
 // RUN: %clang -target i386-unknown-unknown -march=atom -mtbm -x c -E -dM -o - %s | FileCheck --check-prefix=TBM %s
 
diff --git a/test/Profile/Inputs/c-attributes.proftext b/test/Profile/Inputs/c-attributes.proftext
new file mode 100644
index 0000000..e4d4694
--- /dev/null
+++ b/test/Profile/Inputs/c-attributes.proftext
@@ -0,0 +1,34 @@
+hot_100_percent
+2
+2
+100000
+4999950000
+
+hot_40_percent
+2
+2
+40000
+799980000
+
+normal_func
+2
+2
+20000
+199990000
+
+cold_func
+2
+2
+500
+124750
+
+main
+219169028
+6
+1
+0
+100000
+40000
+20000
+500
+
diff --git a/test/Profile/Inputs/c-captured.proftext b/test/Profile/Inputs/c-captured.proftext
new file mode 100644
index 0000000..c1baefc
--- /dev/null
+++ b/test/Profile/Inputs/c-captured.proftext
@@ -0,0 +1,25 @@
+c-captured.c:__captured_stmt
+10
+2
+1
+1
+
+c-captured.c:__captured_stmt1
+266
+3
+1
+10
+1
+
+main
+0
+1
+1
+
+debug_captured
+650
+3
+1
+1
+1
+
diff --git a/test/Profile/Inputs/c-counter-overflows.proftext b/test/Profile/Inputs/c-counter-overflows.proftext
new file mode 100644
index 0000000..5a3633e
--- /dev/null
+++ b/test/Profile/Inputs/c-counter-overflows.proftext
@@ -0,0 +1,12 @@
+main
+285734896137
+8
+1
+68719476720
+64424509425
+68719476720
+21474836475
+21474836475
+21474836475
+4294967295
+
diff --git a/test/Profile/Inputs/c-general.proftext b/test/Profile/Inputs/c-general.proftext
new file mode 100644
index 0000000..19e5bd3
--- /dev/null
+++ b/test/Profile/Inputs/c-general.proftext
@@ -0,0 +1,157 @@
+simple_loops
+16515
+4
+1
+100
+100
+75
+
+conditionals
+74917022372782735
+11
+1
+100
+50
+50
+33
+33
+16
+99
+100
+99
+100
+
+early_exits
+44128811889290
+9
+1
+0
+51
+1
+25
+1
+25
+1
+0
+
+jumps
+2016037664281362839
+22
+1
+1
+0
+1
+0
+0
+1
+0
+1
+2
+3
+2
+0
+3
+0
+1
+1
+1
+10
+0
+10
+9
+
+switches
+2745195701975551402
+19
+1
+1
+1
+15
+7
+1
+0
+2
+2
+3
+3
+4
+4
+0
+4
+4
+5
+1
+0
+
+big_switch
+10218718452081869619
+17
+1
+32
+32
+1
+0
+1
+1
+11
+11
+1
+1
+15
+15
+1
+1
+2
+2
+
+boolean_operators
+291222909838
+8
+1
+100
+34
+66
+17
+34
+33
+50
+
+boolop_loops
+9760565944591
+9
+1
+50
+51
+50
+26
+50
+51
+50
+26
+
+conditional_operator
+848
+3
+1
+0
+1
+
+do_fallthrough
+16586
+4
+1
+10
+2
+8
+
+main
+0
+1
+1
+
+c-general.c:static_func
+4
+2
+1
+10
+
diff --git a/test/Profile/Inputs/c-outdated-data.proftext b/test/Profile/Inputs/c-outdated-data.proftext
new file mode 100644
index 0000000..d57a6e9
--- /dev/null
+++ b/test/Profile/Inputs/c-outdated-data.proftext
@@ -0,0 +1,12 @@
+no_usable_data
+650
+3
+1
+0
+0
+
+main
+0
+1
+1
+
diff --git a/test/Profile/Inputs/c-unprofiled-blocks.proftext b/test/Profile/Inputs/c-unprofiled-blocks.proftext
new file mode 100644
index 0000000..87b48e1
--- /dev/null
+++ b/test/Profile/Inputs/c-unprofiled-blocks.proftext
@@ -0,0 +1,32 @@
+never_called
+44257542701577
+9
+0
+0
+0
+0
+0
+0
+0
+0
+0
+
+main
+1
+1
+1
+
+dead_code
+2859007309808137
+10
+1
+0
+0
+0
+0
+0
+0
+0
+0
+0
+
diff --git a/test/Profile/Inputs/c-unprofiled.proftext b/test/Profile/Inputs/c-unprofiled.proftext
new file mode 100644
index 0000000..d2ef7ae
--- /dev/null
+++ b/test/Profile/Inputs/c-unprofiled.proftext
@@ -0,0 +1,10 @@
+function_in_header
+10
+2
+1
+0
+
+main
+0
+1
+1
diff --git a/test/Profile/Inputs/cxx-class.proftext b/test/Profile/Inputs/cxx-class.proftext
new file mode 100644
index 0000000..b4645ed
--- /dev/null
+++ b/test/Profile/Inputs/cxx-class.proftext
@@ -0,0 +1,41 @@
+_Z14simple_wrapperv
+4
+2
+1
+100
+
+main
+0
+1
+1
+
+_ZN6SimpleD1Ev
+10
+2
+0
+0
+
+_ZN6SimpleD2Ev
+10
+2
+100
+99
+
+_ZN6Simple6methodEv
+10
+2
+100
+99
+
+_ZN6SimpleC1Ei
+10
+2
+0
+0
+
+_ZN6SimpleC2Ei
+10
+2
+100
+99
+
diff --git a/test/Profile/Inputs/cxx-lambda.proftext b/test/Profile/Inputs/cxx-lambda.proftext
new file mode 100644
index 0000000..36646b5
--- /dev/null
+++ b/test/Profile/Inputs/cxx-lambda.proftext
@@ -0,0 +1,20 @@
+cxx-lambda.cpp:_ZZ7lambdasvENK3$_0clEi
+654
+3
+10
+9
+9
+
+main
+0
+1
+1
+
+_Z7lambdasv
+41226
+4
+1
+1
+10
+1
+
diff --git a/test/Profile/Inputs/cxx-templates.proftext b/test/Profile/Inputs/cxx-templates.proftext
new file mode 100644
index 0000000..5ea8400
--- /dev/null
+++ b/test/Profile/Inputs/cxx-templates.proftext
@@ -0,0 +1,17 @@
+main
+0
+1
+1
+
+_Z4loopILj0EEvv
+4
+2
+1
+0
+
+_Z4loopILj100EEvv
+4
+2
+1
+100
+
diff --git a/test/Profile/Inputs/cxx-throws.proftext b/test/Profile/Inputs/cxx-throws.proftext
new file mode 100644
index 0000000..4016eca
--- /dev/null
+++ b/test/Profile/Inputs/cxx-throws.proftext
@@ -0,0 +1,18 @@
+_Z6throwsv
+18359008150154
+9
+1
+100
+100
+66
+33
+17
+50
+33
+100
+
+main
+0
+1
+1
+
diff --git a/test/Profile/Inputs/objc-general.proftext b/test/Profile/Inputs/objc-general.proftext
new file mode 100644
index 0000000..8d6771f
--- /dev/null
+++ b/test/Profile/Inputs/objc-general.proftext
@@ -0,0 +1,17 @@
+objc-general.m:__13+[A foreach:]_block_invoke
+10
+2
+2
+1
+
+objc-general.m:+[A foreach:]
+6
+2
+1
+2
+
+main
+0
+1
+1
+
diff --git a/test/Profile/Inputs/profiled_header.h b/test/Profile/Inputs/profiled_header.h
new file mode 100644
index 0000000..fa649d4
--- /dev/null
+++ b/test/Profile/Inputs/profiled_header.h
@@ -0,0 +1,3 @@
+void function_in_header(int i) {
+  if (i) {}
+}
diff --git a/test/Profile/README b/test/Profile/README
new file mode 100644
index 0000000..3b66765
--- /dev/null
+++ b/test/Profile/README
@@ -0,0 +1,16 @@
+These are tests for instrumentation based profiling.  This specifically means
+the -fprofile-instr-generate and -fprofile-instr-use driver flags.
+
+Tests in this directory should usually test both:
+
+  - the generation of instrumentation (-fprofile-instr-generate), and
+  - the use of profile data from instrumented runs (-fprofile-instr-use).
+
+In order to test -fprofile-instr-use without actually running an instrumented
+program, .profdata files are checked into Inputs/.
+
+The input source files must include a main function such that building with
+-fprofile-instr-generate and running the resulting program generates the same
+.profdata file that is consumed by the tests for -fprofile-instr-use.  Even
+tests that only check -fprofile-instr-use should include such a main function,
+so that profile data can be regenerated as the .profdata file format evolves.
diff --git a/test/Profile/c-attributes.c b/test/Profile/c-attributes.c
new file mode 100644
index 0000000..2dcc180
--- /dev/null
+++ b/test/Profile/c-attributes.c
@@ -0,0 +1,48 @@
+// Test that instrumentation based profiling sets function attributes correctly.
+
+// RUN: llvm-profdata merge %S/Inputs/c-attributes.proftext -o %t.profdata
+// RUN: %clang %s -o - -mllvm -disable-llvm-optzns -emit-llvm -S -fprofile-instr-use=%t.profdata | FileCheck %s
+
+extern int atoi(const char *);
+
+// CHECK: hot_100_percent(i32{{.*}}%i) [[HOT:#[0-9]+]]
+void hot_100_percent(int i) {
+  while (i > 0)
+    i--;
+}
+
+// CHECK: hot_40_percent(i32{{.*}}%i) [[HOT]]
+void hot_40_percent(int i) {
+  while (i > 0)
+    i--;
+}
+
+// CHECK: normal_func(i32{{.*}}%i) [[NORMAL:#[0-9]+]]
+void normal_func(int i) {
+  while (i > 0)
+    i--;
+}
+
+// CHECK: cold_func(i32{{.*}}%i) [[COLD:#[0-9]+]]
+void cold_func(int i) {
+  while (i > 0)
+    i--;
+}
+
+// CHECK: attributes [[HOT]] = { inlinehint nounwind {{.*}} }
+// CHECK: attributes [[NORMAL]] = { nounwind {{.*}} }
+// CHECK: attributes [[COLD]] = { cold nounwind {{.*}} }
+
+int main(int argc, const char *argv[]) {
+  int max = atoi(argv[1]);
+  int i;
+  for (i = 0; i < max; i++)
+    hot_100_percent(i);
+  for (i = 0; i < max * 4 / 10; i++)
+    hot_40_percent(i);
+  for (i = 0; i < max * 2 / 10; i++)
+    normal_func(i);
+  for (i = 0; i < max / 200; i++)
+    cold_func(i);
+  return 0;
+}
diff --git a/test/Profile/c-captured.c b/test/Profile/c-captured.c
new file mode 100644
index 0000000..ef7fb31
--- /dev/null
+++ b/test/Profile/c-captured.c
@@ -0,0 +1,59 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-captured.c %s -o - -emit-llvm -fprofile-instr-generate | FileCheck -check-prefix=PGOGEN -check-prefix=PGOALL %s
+
+// RUN: llvm-profdata merge %S/Inputs/c-captured.proftext -o %t.profdata
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-captured.c %s -o - -emit-llvm -fprofile-instr-use=%t.profdata | FileCheck -check-prefix=PGOUSE -check-prefix=PGOALL %s
+
+// PGOGEN: @[[DCC:__llvm_profile_counters_debug_captured]] = hidden global [3 x i64] zeroinitializer
+// PGOGEN: @[[CSC:__llvm_profile_counters___captured_stmt]] = internal global [2 x i64] zeroinitializer
+// PGOGEN: @[[C1C:__llvm_profile_counters___captured_stmt1]] = internal global [3 x i64] zeroinitializer
+
+// PGOALL-LABEL: define void @debug_captured()
+// PGOGEN: store {{.*}} @[[DCC]], i64 0, i64 0
+void debug_captured() {
+  int x = 10;
+
+  // Check both debug_captured counters, so we can do this all in one pass
+  // PGOGEN: store {{.*}} @[[DCC]], i64 0, i64 1
+  // PGOUSE: br {{.*}} !prof ![[DC1:[0-9]+]]
+  // PGOGEN: store {{.*}} @[[DCC]], i64 0, i64 2
+  // PGOUSE: br {{.*}} !prof ![[DC2:[0-9]+]]
+  // PGOALL: ret
+
+  // PGOALL-LABEL: define internal void @__captured_stmt(
+  // PGOGEN: store {{.*}} @[[CSC]], i64 0, i64 0
+  #pragma clang __debug captured
+  {
+    // PGOGEN: store {{.*}} @[[CSC]], i64 0, i64 1
+    // PGOUSE: br {{.*}} !prof ![[CS1:[0-9]+]]
+    if (x) {}
+    // PGOALL: ret
+  }
+
+  if (x) {} // This is DC1. Checked above.
+
+  // PGOALL-LABEL: define internal void @__captured_stmt1(
+  // PGOGEN: store {{.*}} @[[C1C]], i64 0, i64 0
+  #pragma clang __debug captured
+  {
+    // PGOGEN: store {{.*}} @[[C1C]], i64 0, i64 1
+    // PGOUSE: br {{.*}} !prof ![[C11:[0-9]+]]
+    for (int i = 0; i < x; ++i) {}
+    // PGOGEN: store {{.*}} @[[C1C]], i64 0, i64 2
+    // PGOUSE: br {{.*}} !prof ![[C12:[0-9]+]]
+    if (x) {}
+    // PGOALL: ret
+  }
+
+  if (x) {} // This is DC2. Checked above.
+}
+
+// PGOUSE-DAG: ![[DC1]] = metadata !{metadata !"branch_weights", i32 2, i32 1}
+// PGOUSE-DAG: ![[DC2]] = metadata !{metadata !"branch_weights", i32 2, i32 1}
+// PGOUSE-DAG: ![[CS1]] = metadata !{metadata !"branch_weights", i32 2, i32 1}
+// PGOUSE-DAG: ![[C11]] = metadata !{metadata !"branch_weights", i32 11, i32 2}
+// PGOUSE-DAG: ![[C12]] = metadata !{metadata !"branch_weights", i32 2, i32 1}
+
+int main(int argc, const char *argv[]) {
+  debug_captured();
+  return 0;
+}
diff --git a/test/Profile/c-counter-overflows.c b/test/Profile/c-counter-overflows.c
new file mode 100644
index 0000000..f6f8f73
--- /dev/null
+++ b/test/Profile/c-counter-overflows.c
@@ -0,0 +1,49 @@
+// Test that big branch weights get scaled down to 32-bits, rather than just
+// truncated.
+
+// RUN: llvm-profdata merge %S/Inputs/c-counter-overflows.proftext -o %t.profdata
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-counter-overflows.c %s -o - -emit-llvm -fprofile-instr-use=%t.profdata | FileCheck %s
+
+typedef unsigned long long uint64_t;
+
+int main(int argc, const char *argv[]) {
+  // Need counts higher than 32-bits.
+  // CHECK: br {{.*}} !prof ![[FOR:[0-9]+]]
+  // max   = 0xffffffff0
+  // scale = 0xffffffff0 / 0xffffffff + 1 = 17
+  // loop-body: 0xffffffff0 / 17 + 1 = 0xf0f0f0f0 + 1 = 4042322161 => -252645135
+  // loop-exit: 0x000000001 / 17 + 1 = 0x00000000 + 1 =          1 =>          1
+  for (uint64_t I = 0; I < 0xffffffff0; ++I) {
+    // max   = 0xffffffff * 15 = 0xefffffff1
+    // scale = 0xefffffff1 / 0xffffffff + 1 = 16
+    // CHECK: br {{.*}} !prof ![[IF:[0-9]+]]
+    if (I & 0xf) {
+      // 0xefffffff1 / 16 + 1 = 0xefffffff + 1 = 4026531840 => -268435456
+    } else {
+      // 0x0ffffffff / 16 + 1 = 0x0fffffff + 1 =  268435456 =>  268435456
+    }
+
+    // max   = 0xffffffff * 5 = 0x4fffffffb
+    // scale = 0x4fffffffb / 0xffffffff + 1 = 6
+    // CHECK: ], !prof ![[SWITCH:[0-9]+]]
+    switch ((I & 0xf) / 5) {
+    case 0:
+      // 0x4fffffffb / 6 = 0xd5555554 + 1 = 3579139413 => -715827883
+      break;
+    case 1:
+      // 0x4fffffffb / 6 = 0xd5555554 + 1 = 3579139413 => -715827883
+      break;
+    case 2:
+      // 0x4fffffffb / 6 = 0xd5555554 + 1 = 3579139413 => -715827883
+      break;
+    default:
+      // 0x0ffffffff / 6 = 0x2aaaaaaa + 1 =  715827883 =>  715827883
+      break;
+    }
+  }
+  return 0;
+}
+
+// CHECK-DAG: ![[FOR]] = metadata !{metadata !"branch_weights", i32 -252645135, i32 1}
+// CHECK-DAG: ![[IF]]  = metadata !{metadata !"branch_weights", i32 -268435456, i32 268435456}
+// CHECK-DAG: ![[SWITCH]] = metadata !{metadata !"branch_weights", i32 715827883, i32 -715827883, i32 -715827883, i32 -715827883}
diff --git a/test/Profile/c-general.c b/test/Profile/c-general.c
new file mode 100644
index 0000000..442fdd3
--- /dev/null
+++ b/test/Profile/c-general.c
@@ -0,0 +1,544 @@
+// Test instrumentation of general constructs in C.
+
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-general.c %s -o - -emit-llvm -fprofile-instr-generate | FileCheck -check-prefix=PGOGEN %s
+
+// RUN: llvm-profdata merge %S/Inputs/c-general.proftext -o %t.profdata
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-general.c %s -o - -emit-llvm -fprofile-instr-use=%t.profdata | FileCheck -check-prefix=PGOUSE %s
+
+// PGOGEN: @[[SLC:__llvm_profile_counters_simple_loops]] = hidden global [4 x i64] zeroinitializer
+// PGOGEN: @[[IFC:__llvm_profile_counters_conditionals]] = hidden global [11 x i64] zeroinitializer
+// PGOGEN: @[[EEC:__llvm_profile_counters_early_exits]] = hidden global [9 x i64] zeroinitializer
+// PGOGEN: @[[JMC:__llvm_profile_counters_jumps]] = hidden global [22 x i64] zeroinitializer
+// PGOGEN: @[[SWC:__llvm_profile_counters_switches]] = hidden global [19 x i64] zeroinitializer
+// PGOGEN: @[[BSC:__llvm_profile_counters_big_switch]] = hidden global [17 x i64] zeroinitializer
+// PGOGEN: @[[BOC:__llvm_profile_counters_boolean_operators]] = hidden global [8 x i64] zeroinitializer
+// PGOGEN: @[[BLC:__llvm_profile_counters_boolop_loops]] = hidden global [9 x i64] zeroinitializer
+// PGOGEN: @[[COC:__llvm_profile_counters_conditional_operator]] = hidden global [3 x i64] zeroinitializer
+// PGOGEN: @[[MAC:__llvm_profile_counters_main]] = hidden global [1 x i64] zeroinitializer
+// PGOGEN: @[[STC:__llvm_profile_counters_static_func]] = internal global [2 x i64] zeroinitializer
+
+// PGOGEN-LABEL: @simple_loops()
+// PGOUSE-LABEL: @simple_loops()
+// PGOGEN: store {{.*}} @[[SLC]], i64 0, i64 0
+void simple_loops() {
+  int i;
+  // PGOGEN: store {{.*}} @[[SLC]], i64 0, i64 1
+  // PGOUSE: br {{.*}} !prof ![[SL1:[0-9]+]]
+  for (i = 0; i < 100; ++i) {
+  }
+  // PGOGEN: store {{.*}} @[[SLC]], i64 0, i64 2
+  // PGOUSE: br {{.*}} !prof ![[SL2:[0-9]+]]
+  while (i > 0)
+    i--;
+  // PGOGEN: store {{.*}} @[[SLC]], i64 0, i64 3
+  // PGOUSE: br {{.*}} !prof ![[SL3:[0-9]+]]
+  do {} while (i++ < 75);
+
+  // PGOGEN-NOT: store {{.*}} @[[SLC]],
+  // PGOUSE-NOT: br {{.*}} !prof ![0-9]+
+}
+
+// PGOGEN-LABEL: @conditionals()
+// PGOUSE-LABEL: @conditionals()
+// PGOGEN: store {{.*}} @[[IFC]], i64 0, i64 0
+void conditionals() {
+  // PGOGEN: store {{.*}} @[[IFC]], i64 0, i64 1
+  // PGOUSE: br {{.*}} !prof ![[IF1:[0-9]+]]
+  for (int i = 0; i < 100; ++i) {
+    // PGOGEN: store {{.*}} @[[IFC]], i64 0, i64 2
+    // PGOUSE: br {{.*}} !prof ![[IF2:[0-9]+]]
+    if (i % 2) {
+      // PGOGEN: store {{.*}} @[[IFC]], i64 0, i64 3
+      // PGOUSE: br {{.*}} !prof ![[IF3:[0-9]+]]
+      if (i) {}
+    // PGOGEN: store {{.*}} @[[IFC]], i64 0, i64 4
+    // PGOUSE: br {{.*}} !prof ![[IF4:[0-9]+]]
+    } else if (i % 3) {
+      // PGOGEN: store {{.*}} @[[IFC]], i64 0, i64 5
+      // PGOUSE: br {{.*}} !prof ![[IF5:[0-9]+]]
+      if (i) {}
+    } else {
+      // PGOGEN: store {{.*}} @[[IFC]], i64 0, i64 6
+      // PGOUSE: br {{.*}} !prof ![[IF6:[0-9]+]]
+      if (i) {}
+    }
+
+    // PGOGEN: store {{.*}} @[[IFC]], i64 0, i64 8
+    // PGOGEN: store {{.*}} @[[IFC]], i64 0, i64 7
+    // PGOUSE: br {{.*}} !prof ![[IF7:[0-9]+]]
+    if (1 && i) {}
+    // PGOGEN: store {{.*}} @[[IFC]], i64 0, i64 10
+    // PGOGEN: store {{.*}} @[[IFC]], i64 0, i64 9
+    // PGOUSE: br {{.*}} !prof ![[IF8:[0-9]+]]
+    if (0 || i) {}
+  }
+
+  // PGOGEN-NOT: store {{.*}} @[[IFC]],
+  // PGOUSE-NOT: br {{.*}} !prof ![0-9]+
+}
+
+// PGOGEN-LABEL: @early_exits()
+// PGOUSE-LABEL: @early_exits()
+// PGOGEN: store {{.*}} @[[EEC]], i64 0, i64 0
+void early_exits() {
+  int i = 0;
+
+  // PGOGEN: store {{.*}} @[[EEC]], i64 0, i64 1
+  // PGOUSE: br {{.*}} !prof ![[EE1:[0-9]+]]
+  if (i) {}
+
+  // PGOGEN: store {{.*}} @[[EEC]], i64 0, i64 2
+  // PGOUSE: br {{.*}} !prof ![[EE2:[0-9]+]]
+  while (i < 100) {
+    i++;
+    // PGOGEN: store {{.*}} @[[EEC]], i64 0, i64 3
+    // PGOUSE: br {{.*}} !prof ![[EE3:[0-9]+]]
+    if (i > 50)
+      break;
+    // PGOGEN: store {{.*}} @[[EEC]], i64 0, i64 4
+    // PGOUSE: br {{.*}} !prof ![[EE4:[0-9]+]]
+    if (i % 2)
+      continue;
+  }
+
+  // PGOGEN: store {{.*}} @[[EEC]], i64 0, i64 5
+  // PGOUSE: br {{.*}} !prof ![[EE5:[0-9]+]]
+  if (i) {}
+
+  // PGOGEN: store {{.*}} @[[EEC]], i64 0, i64 6
+  do {
+    // PGOGEN: store {{.*}} @[[EEC]], i64 0, i64 7
+    // PGOUSE: br {{.*}} !prof ![[EE6:[0-9]+]]
+    if (i > 75)
+      return;
+    else
+      i++;
+  // PGOUSE: br {{.*}} !prof ![[EE7:[0-9]+]]
+  } while (i < 100);
+
+  // PGOGEN: store {{.*}} @[[EEC]], i64 0, i64 8
+  // Never reached -> no weights
+  if (i) {}
+
+  // PGOGEN-NOT: store {{.*}} @[[EEC]],
+  // PGOUSE-NOT: br {{.*}} !prof ![0-9]+
+}
+
+// PGOGEN-LABEL: @jumps()
+// PGOUSE-LABEL: @jumps()
+// PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 0
+void jumps() {
+  int i;
+
+  // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 1
+  // PGOUSE: br {{.*}} !prof ![[JM1:[0-9]+]]
+  for (i = 0; i < 2; ++i) {
+    goto outofloop;
+    // Never reached -> no weights
+    if (i) {}
+  }
+// PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 3
+outofloop:
+  // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 4
+  // PGOUSE: br {{.*}} !prof ![[JM2:[0-9]+]]
+  if (i) {}
+
+  goto loop1;
+
+  // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 5
+  // PGOUSE: br {{.*}} !prof ![[JM3:[0-9]+]]
+  while (i) {
+  // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 6
+  loop1:
+    // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 7
+    // PGOUSE: br {{.*}} !prof ![[JM4:[0-9]+]]
+    if (i) {}
+  }
+
+  goto loop2;
+// PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 8
+first:
+// PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 9
+second:
+// PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 10
+third:
+  i++;
+  // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 11
+  // PGOUSE: br {{.*}} !prof ![[JM5:[0-9]+]]
+  if (i < 3)
+    goto loop2;
+
+  // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 12
+  // PGOUSE: br {{.*}} !prof ![[JM6:[0-9]+]]
+  while (i < 3) {
+  // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 13
+  loop2:
+    // PGOUSE: switch {{.*}} [
+    // PGOUSE: ], !prof ![[JM7:[0-9]+]]
+    switch (i) {
+    // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 15
+    case 0:
+      goto first;
+    // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 16
+    case 1:
+      goto second;
+    // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 17
+    case 2:
+      goto third;
+    }
+    // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 14
+  }
+
+  // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 18
+  // PGOUSE: br {{.*}} !prof ![[JM8:[0-9]+]]
+  for (i = 0; i < 10; ++i) {
+    goto withinloop;
+    // never reached -> no weights
+    if (i) {}
+  // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 20
+  withinloop:
+    // PGOGEN: store {{.*}} @[[JMC]], i64 0, i64 21
+    // PGOUSE: br {{.*}} !prof ![[JM9:[0-9]+]]
+    if (i) {}
+  }
+
+  // PGOGEN-NOT: store {{.*}} @[[JMC]],
+  // PGOUSE-NOT: br {{.*}} !prof ![0-9]+
+}
+
+// PGOGEN-LABEL: @switches()
+// PGOUSE-LABEL: @switches()
+// PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 0
+void switches() {
+  static int weights[] = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5};
+
+  // No cases -> no weights
+  switch (weights[0]) {
+  // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 2
+  default:
+    break;
+  }
+  // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 1
+
+  // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 3
+  // PGOUSE: br {{.*}} !prof ![[SW1:[0-9]+]]
+  for (int i = 0, len = sizeof(weights) / sizeof(weights[0]); i < len; ++i) {
+    // PGOUSE: switch {{.*}} [
+    // PGOUSE: ], !prof ![[SW2:[0-9]+]]
+    switch (i[weights]) {
+    // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 5
+    case 1:
+      // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 6
+      // PGOUSE: br {{.*}} !prof ![[SW3:[0-9]+]]
+      if (i) {}
+      // fallthrough
+    // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 7
+    case 2:
+      // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 8
+      // PGOUSE: br {{.*}} !prof ![[SW4:[0-9]+]]
+      if (i) {}
+      break;
+    // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 9
+    case 3:
+      // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 10
+      // PGOUSE: br {{.*}} !prof ![[SW5:[0-9]+]]
+      if (i) {}
+      continue;
+    // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 11
+    case 4:
+      // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 12
+      // PGOUSE: br {{.*}} !prof ![[SW6:[0-9]+]]
+      if (i) {}
+      // PGOUSE: switch {{.*}} [
+      // PGOUSE: ], !prof ![[SW7:[0-9]+]]
+      switch (i) {
+      // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 14
+      case 6 ... 9:
+        // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 15
+        // PGOUSE: br {{.*}} !prof ![[SW8:[0-9]+]]
+        if (i) {}
+        continue;
+      }
+      // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 13
+
+    // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 16
+    default:
+      // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 17
+      // PGOUSE: br {{.*}} !prof ![[SW9:[0-9]+]]
+      if (i == len - 1)
+        return;
+    }
+    // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 4
+  }
+
+  // PGOGEN: store {{.*}} @[[SWC]], i64 0, i64 18
+  // Never reached -> no weights
+  if (weights[0]) {}
+
+  // PGOGEN-NOT: store {{.*}} @[[SWC]],
+  // PGOUSE-NOT: br {{.*}} !prof ![0-9]+
+}
+
+// PGOGEN-LABEL: @big_switch()
+// PGOUSE-LABEL: @big_switch()
+// PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 0
+void big_switch() {
+  // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 1
+  // PGOUSE: br {{.*}} !prof ![[BS1:[0-9]+]]
+  for (int i = 0; i < 32; ++i) {
+    // PGOUSE: switch {{.*}} [
+    // PGOUSE: ], !prof ![[BS2:[0-9]+]]
+    switch (1 << i) {
+    // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 3
+    case (1 << 0):
+      // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 4
+      // PGOUSE: br {{.*}} !prof ![[BS3:[0-9]+]]
+      if (i) {}
+      // fallthrough
+    // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 5
+    case (1 << 1):
+      // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 6
+      // PGOUSE: br {{.*}} !prof ![[BS4:[0-9]+]]
+      if (i) {}
+      break;
+    // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 7
+    case (1 << 2) ... (1 << 12):
+      // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 8
+      // PGOUSE: br {{.*}} !prof ![[BS5:[0-9]+]]
+      if (i) {}
+      break;
+    // The branch for the large case range above appears after the case body
+    // PGOUSE: br {{.*}} !prof ![[BS6:[0-9]+]]
+
+    // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 9
+    case (1 << 13):
+      // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 10
+      // PGOUSE: br {{.*}} !prof ![[BS7:[0-9]+]]
+      if (i) {}
+      break;
+    // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 11
+    case (1 << 14) ... (1 << 28):
+      // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 12
+      // PGOUSE: br {{.*}} !prof ![[BS8:[0-9]+]]
+      if (i) {}
+      break;
+    // The branch for the large case range above appears after the case body
+    // PGOUSE: br {{.*}} !prof ![[BS9:[0-9]+]]
+
+    // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 13
+    case (1 << 29) ... ((1 << 29) + 1):
+      // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 14
+      // PGOUSE: br {{.*}} !prof ![[BS10:[0-9]+]]
+      if (i) {}
+      break;
+    // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 15
+    default:
+      // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 16
+      // PGOUSE: br {{.*}} !prof ![[BS11:[0-9]+]]
+      if (i) {}
+      break;
+    }
+    // PGOGEN: store {{.*}} @[[BSC]], i64 0, i64 2
+  }
+
+  // PGOGEN-NOT: store {{.*}} @[[BSC]],
+  // PGOUSE-NOT: br {{.*}} !prof ![0-9]+
+  // PGOUSE: ret void
+}
+
+// PGOGEN-LABEL: @boolean_operators()
+// PGOUSE-LABEL: @boolean_operators()
+// PGOGEN: store {{.*}} @[[BOC]], i64 0, i64 0
+void boolean_operators() {
+  int v;
+  // PGOGEN: store {{.*}} @[[BOC]], i64 0, i64 1
+  // PGOUSE: br {{.*}} !prof ![[BO1:[0-9]+]]
+  for (int i = 0; i < 100; ++i) {
+    // PGOGEN: store {{.*}} @[[BOC]], i64 0, i64 2
+    // PGOUSE: br {{.*}} !prof ![[BO2:[0-9]+]]
+    v = i % 3 || i;
+
+    // PGOGEN: store {{.*}} @[[BOC]], i64 0, i64 3
+    // PGOUSE: br {{.*}} !prof ![[BO3:[0-9]+]]
+    v = i % 3 && i;
+
+    // PGOGEN: store {{.*}} @[[BOC]], i64 0, i64 5
+    // PGOGEN: store {{.*}} @[[BOC]], i64 0, i64 4
+    // PGOUSE: br {{.*}} !prof ![[BO4:[0-9]+]]
+    // PGOUSE: br {{.*}} !prof ![[BO5:[0-9]+]]
+    v = i % 3 || i % 2 || i;
+
+    // PGOGEN: store {{.*}} @[[BOC]], i64 0, i64 7
+    // PGOGEN: store {{.*}} @[[BOC]], i64 0, i64 6
+    // PGOUSE: br {{.*}} !prof ![[BO6:[0-9]+]]
+    // PGOUSE: br {{.*}} !prof ![[BO7:[0-9]+]]
+    v = i % 2 && i % 3 && i;
+  }
+
+  // PGOGEN-NOT: store {{.*}} @[[BOC]],
+  // PGOUSE-NOT: br {{.*}} !prof ![0-9]+
+}
+
+// PGOGEN-LABEL: @boolop_loops()
+// PGOUSE-LABEL: @boolop_loops()
+// PGOGEN: store {{.*}} @[[BLC]], i64 0, i64 0
+void boolop_loops() {
+  int i = 100;
+
+  // PGOGEN: store {{.*}} @[[BLC]], i64 0, i64 2
+  // PGOGEN: store {{.*}} @[[BLC]], i64 0, i64 1
+  // PGOUSE: br {{.*}} !prof ![[BL1:[0-9]+]]
+  // PGOUSE: br {{.*}} !prof ![[BL2:[0-9]+]]
+  while (i && i > 50)
+    i--;
+
+  // PGOGEN: store {{.*}} @[[BLC]], i64 0, i64 4
+  // PGOGEN: store {{.*}} @[[BLC]], i64 0, i64 3
+  // PGOUSE: br {{.*}} !prof ![[BL3:[0-9]+]]
+  // PGOUSE: br {{.*}} !prof ![[BL4:[0-9]+]]
+  while ((i % 2) || (i > 0))
+    i--;
+
+  // PGOGEN: store {{.*}} @[[BLC]], i64 0, i64 6
+  // PGOGEN: store {{.*}} @[[BLC]], i64 0, i64 5
+  // PGOUSE: br {{.*}} !prof ![[BL5:[0-9]+]]
+  // PGOUSE: br {{.*}} !prof ![[BL6:[0-9]+]]
+  for (i = 100; i && i > 50; --i);
+
+  // PGOGEN: store {{.*}} @[[BLC]], i64 0, i64 8
+  // PGOGEN: store {{.*}} @[[BLC]], i64 0, i64 7
+  // PGOUSE: br {{.*}} !prof ![[BL7:[0-9]+]]
+  // PGOUSE: br {{.*}} !prof ![[BL8:[0-9]+]]
+  for (; (i % 2) || (i > 0); --i);
+
+  // PGOGEN-NOT: store {{.*}} @[[BLC]],
+  // PGOUSE-NOT: br {{.*}} !prof ![0-9]+
+}
+
+// PGOGEN-LABEL: @conditional_operator()
+// PGOUSE-LABEL: @conditional_operator()
+// PGOGEN: store {{.*}} @[[COC]], i64 0, i64 0
+void conditional_operator() {
+  int i = 100;
+
+  // PGOGEN: store {{.*}} @[[COC]], i64 0, i64 1
+  // PGOUSE: br {{.*}} !prof ![[CO1:[0-9]+]]
+  int j = i < 50 ? i : 1;
+
+  // PGOGEN: store {{.*}} @[[COC]], i64 0, i64 2
+  // PGOUSE: br {{.*}} !prof ![[CO2:[0-9]+]]
+  int k = i ?: 0;
+
+  // PGOGEN-NOT: store {{.*}} @[[COC]],
+  // PGOUSE-NOT: br {{.*}} !prof ![0-9]+
+}
+
+void do_fallthrough() {
+  for (int i = 0; i < 10; ++i) {
+    int j = 0;
+    do {
+      // The number of exits out of this do-loop via the break statement
+      // exceeds the counter value for the loop (which does not include the
+      // fallthrough count). Make sure that does not violate any assertions.
+      if (i < 8) break;
+      j++;
+    } while (j < 2);
+  }
+}
+
+// PGOGEN-LABEL: @static_func()
+// PGOUSE-LABEL: @static_func()
+// PGOGEN: store {{.*}} @[[STC]], i64 0, i64 0
+static void static_func() {
+  // PGOGEN: store {{.*}} @[[STC]], i64 0, i64 1
+  // PGOUSE: br {{.*}} !prof ![[ST1:[0-9]+]]
+  for (int i = 0; i < 10; ++i) {
+  }
+}
+
+// PGOUSE-DAG: ![[SL1]] = metadata !{metadata !"branch_weights", i32 101, i32 2}
+// PGOUSE-DAG: ![[SL2]] = metadata !{metadata !"branch_weights", i32 101, i32 2}
+// PGOUSE-DAG: ![[SL3]] = metadata !{metadata !"branch_weights", i32 76, i32 2}
+
+// PGOUSE-DAG: ![[EE1]] = metadata !{metadata !"branch_weights", i32 1, i32 2}
+// PGOUSE-DAG: ![[EE2]] = metadata !{metadata !"branch_weights", i32 52, i32 1}
+// PGOUSE-DAG: ![[EE3]] = metadata !{metadata !"branch_weights", i32 2, i32 51}
+// PGOUSE-DAG: ![[EE4]] = metadata !{metadata !"branch_weights", i32 26, i32 26}
+// PGOUSE-DAG: ![[EE5]] = metadata !{metadata !"branch_weights", i32 2, i32 1}
+// PGOUSE-DAG: ![[EE6]] = metadata !{metadata !"branch_weights", i32 2, i32 26}
+// PGOUSE-DAG: ![[EE7]] = metadata !{metadata !"branch_weights", i32 26, i32 1}
+
+// PGOUSE-DAG: ![[IF1]] = metadata !{metadata !"branch_weights", i32 101, i32 2}
+// PGOUSE-DAG: ![[IF2]] = metadata !{metadata !"branch_weights", i32 51, i32 51}
+// PGOUSE-DAG: ![[IF3]] = metadata !{metadata !"branch_weights", i32 51, i32 1}
+// PGOUSE-DAG: ![[IF4]] = metadata !{metadata !"branch_weights", i32 34, i32 18}
+// PGOUSE-DAG: ![[IF5]] = metadata !{metadata !"branch_weights", i32 34, i32 1}
+// PGOUSE-DAG: ![[IF6]] = metadata !{metadata !"branch_weights", i32 17, i32 2}
+// PGOUSE-DAG: ![[IF7]] = metadata !{metadata !"branch_weights", i32 100, i32 2}
+// PGOUSE-DAG: ![[IF8]] = metadata !{metadata !"branch_weights", i32 100, i32 2}
+
+// PGOUSE-DAG: ![[JM1]] = metadata !{metadata !"branch_weights", i32 2, i32 1}
+// PGOUSE-DAG: ![[JM2]] = metadata !{metadata !"branch_weights", i32 1, i32 2}
+// PGOUSE-DAG: ![[JM3]] = metadata !{metadata !"branch_weights", i32 1, i32 2}
+// PGOUSE-DAG: ![[JM4]] = metadata !{metadata !"branch_weights", i32 1, i32 2}
+// PGOUSE-DAG: ![[JM5]] = metadata !{metadata !"branch_weights", i32 3, i32 2}
+// PGOUSE-DAG: ![[JM6]] = metadata !{metadata !"branch_weights", i32 1, i32 2}
+// PGOUSE-DAG: ![[JM7]] = metadata !{metadata !"branch_weights", i32 1, i32 2, i32 2, i32 2}
+// PGOUSE-DAG: ![[JM8]] = metadata !{metadata !"branch_weights", i32 11, i32 2}
+// PGOUSE-DAG: ![[JM9]] = metadata !{metadata !"branch_weights", i32 10, i32 2}
+
+// PGOUSE-DAG: ![[SW1]] = metadata !{metadata !"branch_weights", i32 16, i32 1}
+// PGOUSE-DAG: ![[SW2]] = metadata !{metadata !"branch_weights", i32 6, i32 2, i32 3, i32 4, i32 5}
+// PGOUSE-DAG: ![[SW3]] = metadata !{metadata !"branch_weights", i32 1, i32 2}
+// PGOUSE-DAG: ![[SW4]] = metadata !{metadata !"branch_weights", i32 3, i32 2}
+// PGOUSE-DAG: ![[SW5]] = metadata !{metadata !"branch_weights", i32 4, i32 1}
+// PGOUSE-DAG: ![[SW6]] = metadata !{metadata !"branch_weights", i32 5, i32 1}
+// PGOUSE-DAG: ![[SW7]] = metadata !{metadata !"branch_weights", i32 1, i32 2, i32 2, i32 2, i32 2}
+// PGOUSE-DAG: ![[SW8]] = metadata !{metadata !"branch_weights", i32 5, i32 1}
+// PGOUSE-DAG: ![[SW9]] = metadata !{metadata !"branch_weights", i32 2, i32 5}
+
+// PGOUSE-DAG: ![[BS1]] = metadata !{metadata !"branch_weights", i32 33, i32 2}
+// PGOUSE-DAG: ![[BS2]] = metadata !{metadata !"branch_weights", i32 29, i32 2, i32 2, i32 2, i32 2, i32 1}
+// PGOUSE-DAG: ![[BS3]] = metadata !{metadata !"branch_weights", i32 1, i32 2}
+// PGOUSE-DAG: ![[BS4]] = metadata !{metadata !"branch_weights", i32 2, i32 2}
+// PGOUSE-DAG: ![[BS5]] = metadata !{metadata !"branch_weights", i32 12, i32 1}
+// PGOUSE-DAG: ![[BS6]] = metadata !{metadata !"branch_weights", i32 12, i32 3}
+// PGOUSE-DAG: ![[BS7]] = metadata !{metadata !"branch_weights", i32 2, i32 1}
+// PGOUSE-DAG: ![[BS8]] = metadata !{metadata !"branch_weights", i32 16, i32 1}
+// PGOUSE-DAG: ![[BS9]] = metadata !{metadata !"branch_weights", i32 16, i32 14}
+// PGOUSE-DAG: ![[BS10]] = metadata !{metadata !"branch_weights", i32 2, i32 1}
+// PGOUSE-DAG: ![[BS11]] = metadata !{metadata !"branch_weights", i32 3, i32 1}
+
+// PGOUSE-DAG: ![[BO1]] = metadata !{metadata !"branch_weights", i32 101, i32 2}
+// PGOUSE-DAG: ![[BO2]] = metadata !{metadata !"branch_weights", i32 67, i32 35}
+// PGOUSE-DAG: ![[BO3]] = metadata !{metadata !"branch_weights", i32 67, i32 35}
+// PGOUSE-DAG: ![[BO4]] = metadata !{metadata !"branch_weights", i32 67, i32 35}
+// PGOUSE-DAG: ![[BO5]] = metadata !{metadata !"branch_weights", i32 18, i32 18}
+// PGOUSE-DAG: ![[BO6]] = metadata !{metadata !"branch_weights", i32 51, i32 51}
+// PGOUSE-DAG: ![[BO7]] = metadata !{metadata !"branch_weights", i32 34, i32 18}
+// PGOUSE-DAG: ![[BL1]] = metadata !{metadata !"branch_weights", i32 52, i32 1}
+// PGOUSE-DAG: ![[BL2]] = metadata !{metadata !"branch_weights", i32 51, i32 2}
+// PGOUSE-DAG: ![[BL3]] = metadata !{metadata !"branch_weights", i32 26, i32 27}
+// PGOUSE-DAG: ![[BL4]] = metadata !{metadata !"branch_weights", i32 51, i32 2}
+// PGOUSE-DAG: ![[BL5]] = metadata !{metadata !"branch_weights", i32 52, i32 1}
+// PGOUSE-DAG: ![[BL6]] = metadata !{metadata !"branch_weights", i32 51, i32 2}
+// PGOUSE-DAG: ![[BL7]] = metadata !{metadata !"branch_weights", i32 26, i32 27}
+// PGOUSE-DAG: ![[BL8]] = metadata !{metadata !"branch_weights", i32 51, i32 2}
+// PGOUSE-DAG: ![[CO1]] = metadata !{metadata !"branch_weights", i32 1, i32 2}
+// PGOUSE-DAG: ![[CO2]] = metadata !{metadata !"branch_weights", i32 2, i32 1}
+// PGOUSE-DAG: ![[ST1]] = metadata !{metadata !"branch_weights", i32 11, i32 2}
+
+int main(int argc, const char *argv[]) {
+  simple_loops();
+  conditionals();
+  early_exits();
+  jumps();
+  switches();
+  big_switch();
+  boolean_operators();
+  boolop_loops();
+  conditional_operator();
+  do_fallthrough();
+  static_func();
+  return 0;
+}
diff --git a/test/Profile/c-linkage-available_externally.c b/test/Profile/c-linkage-available_externally.c
new file mode 100644
index 0000000..aa1080b
--- /dev/null
+++ b/test/Profile/c-linkage-available_externally.c
@@ -0,0 +1,12 @@
+// Make sure instrementation data from available_externally functions doesn't
+// get thrown out.
+// RUN: %clang_cc1 -O2 -triple x86_64-apple-macosx10.9 -main-file-name c-linkage-available_externally.c %s -o - -emit-llvm -fprofile-instr-generate | FileCheck %s
+
+// CHECK: @__llvm_profile_counters_foo = linkonce_odr hidden global [1 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8
+// CHECK: @__llvm_profile_name_foo = linkonce_odr hidden constant [3 x i8] c"foo", section "__DATA,__llvm_prf_names", align 1
+// CHECK: @__llvm_profile_data_foo = linkonce_odr hidden constant { i32, i32, i64, i8*, i64* } { i32 3, i32 1, i64 {{[0-9]+}}, i8* getelementptr inbounds ([3 x i8]* @__llvm_profile_name_foo, i32 0, i32 0), i64* getelementptr inbounds ([1 x i64]* @__llvm_profile_counters_foo, i32 0, i32 0) }, section "__DATA,__llvm_prf_data", align 8
+inline int foo(void) { return 1; }
+
+int main(void) {
+  return foo();
+}
diff --git a/test/Profile/c-linkage.c b/test/Profile/c-linkage.c
new file mode 100644
index 0000000..3b0fa1a
--- /dev/null
+++ b/test/Profile/c-linkage.c
@@ -0,0 +1,37 @@
+// Check the data structures emitted by instrumentation.
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-linkage.c %s -o - -emit-llvm -fprofile-instr-generate | FileCheck %s
+
+// CHECK: @__llvm_profile_runtime = external global i32
+// CHECK: @__llvm_profile_counters_foo = hidden global [1 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8
+// CHECK: @__llvm_profile_name_foo = hidden constant [3 x i8] c"foo", section "__DATA,__llvm_prf_names", align 1
+// CHECK: @__llvm_profile_data_foo = hidden constant { i32, i32, i64, i8*, i64* } { i32 3, i32 1, i64 {{[0-9]+}}, i8* getelementptr inbounds ([3 x i8]* @__llvm_profile_name_foo, i32 0, i32 0), i64* getelementptr inbounds ([1 x i64]* @__llvm_profile_counters_foo, i32 0, i32 0) }, section "__DATA,__llvm_prf_data", align 8
+void foo(void) { }
+
+// CHECK: @__llvm_profile_counters_foo_weak = weak hidden global [5 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8
+// CHECK: @__llvm_profile_name_foo_weak = weak hidden constant [8 x i8] c"foo_weak", section "__DATA,__llvm_prf_names", align 1
+// CHECK: @__llvm_profile_data_foo_weak = weak hidden constant { i32, i32, i64, i8*, i64* } { i32 8, i32 5, i64 {{[0-9]+}}, i8* getelementptr inbounds ([8 x i8]* @__llvm_profile_name_foo_weak, i32 0, i32 0), i64* getelementptr inbounds ([5 x i64]* @__llvm_profile_counters_foo_weak, i32 0, i32 0) }, section "__DATA,__llvm_prf_data", align 8
+void foo_weak(void) __attribute__((weak));
+void foo_weak(void) { if (0){} if (0){} if (0){} if (0){} }
+
+// CHECK: @__llvm_profile_counters_main = hidden global [1 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8
+// CHECK: @__llvm_profile_name_main = hidden constant [4 x i8] c"main", section "__DATA,__llvm_prf_names", align 1
+// CHECK: @__llvm_profile_data_main = hidden constant { i32, i32, i64, i8*, i64* } { i32 4, i32 1, i64 {{[0-9]+}}, i8* getelementptr inbounds ([4 x i8]* @__llvm_profile_name_main, i32 0, i32 0), i64* getelementptr inbounds ([1 x i64]* @__llvm_profile_counters_main, i32 0, i32 0) }, section "__DATA,__llvm_prf_data", align 8
+static void foo_internal(void);
+int main(void) {
+  foo();
+  foo_internal();
+  foo_weak();
+  return 0;
+}
+
+// CHECK: @__llvm_profile_counters_foo_internal = internal global [3 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8
+// CHECK: @__llvm_profile_name_foo_internal = internal constant [24 x i8] c"c-linkage.c:foo_internal", section "__DATA,__llvm_prf_names", align 1
+// CHECK: @__llvm_profile_data_foo_internal = internal constant { i32, i32, i64, i8*, i64* } { i32 24, i32 3, i64 {{[0-9]+}}, i8* getelementptr inbounds ([24 x i8]* @__llvm_profile_name_foo_internal, i32 0, i32 0), i64* getelementptr inbounds ([3 x i64]* @__llvm_profile_counters_foo_internal, i32 0, i32 0) }, section "__DATA,__llvm_prf_data", align 8
+static void foo_internal(void) { if (0){} if (0){} }
+
+// CHECK: @llvm.used = appending global [5 x i8*] [i8* bitcast (i32 ()* @__llvm_profile_runtime_user to i8*), i8* bitcast ({ i32, i32, i64, i8*, i64* }* @__llvm_profile_data_foo to i8*), i8* bitcast ({ i32, i32, i64, i8*, i64* }* @__llvm_profile_data_foo_weak to i8*), i8* bitcast ({ i32, i32, i64, i8*, i64* }* @__llvm_profile_data_main to i8*), i8* bitcast ({ i32, i32, i64, i8*, i64* }* @__llvm_profile_data_foo_internal to i8*)], section "llvm.metadata"
+
+// CHECK: define linkonce_odr i32 @__llvm_profile_runtime_user() {{.*}} {
+// CHECK:   %[[REG:.*]] = load i32* @__llvm_profile_runtime
+// CHECK:   ret i32 %[[REG]]
+// CHECK: }
diff --git a/test/Profile/c-outdated-data.c b/test/Profile/c-outdated-data.c
new file mode 100644
index 0000000..d0503ac
--- /dev/null
+++ b/test/Profile/c-outdated-data.c
@@ -0,0 +1,28 @@
+// Test that outdated data is ignored.
+
+// FIXME: It would be nice to use -verify here instead of FileCheck, but -verify
+// doesn't play well with warnings that have no line number.
+
+// RUN: llvm-profdata merge %S/Inputs/c-outdated-data.proftext -o %t.profdata
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-outdated-data.c %s -o /dev/null -emit-llvm -fprofile-instr-use=%t.profdata -Wprofile-instr-dropped 2>&1 | FileCheck %s
+// CHECK: warning: profile data may be out of date: of 3 functions, 1 has no data and 1 has mismatched data that will be ignored
+
+void no_usable_data() {
+  int i = 0;
+
+  if (i) {}
+
+#ifdef GENERATE_OUTDATED_DATA
+  if (i) {}
+#endif
+}
+
+#ifndef GENERATE_OUTDATED_DATA
+void no_data() {
+}
+#endif
+
+int main(int argc, const char *argv[]) {
+  no_usable_data();
+  return 0;
+}
diff --git a/test/Profile/c-unprofiled-blocks.c b/test/Profile/c-unprofiled-blocks.c
new file mode 100644
index 0000000..58bef9e
--- /dev/null
+++ b/test/Profile/c-unprofiled-blocks.c
@@ -0,0 +1,69 @@
+// Blocks that we have no profile data for (ie, it was never reached in training
+// runs) shouldn't have any branch weight metadata added.
+
+// RUN: llvm-profdata merge %S/Inputs/c-unprofiled-blocks.proftext -o %t.profdata
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-unprofiled-blocks.c %s -o - -emit-llvm -fprofile-instr-use=%t.profdata | FileCheck -check-prefix=PGOUSE %s
+
+// PGOUSE-LABEL: @never_called(i32 %i)
+int never_called(int i) {
+  // PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}{{$}}
+  if (i) {}
+
+  // PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}{{$}}
+  for (i = 0; i < 100; ++i) {
+  }
+
+  // PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}{{$}}
+  while (--i) {}
+
+  // PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}{{$}}
+  do {} while (i++ < 75);
+
+  // PGOUSE: switch {{.*}} [
+  // PGOUSE-NEXT: i32 12
+  // PGOUSE-NEXT: i32 82
+  // PGOUSE-NEXT: ]{{$}}
+  switch (i) {
+  case 12: return 3;
+  case 82: return 0;
+  default: return 89;
+  }
+}
+
+// PGOUSE-LABEL: @dead_code(i32 %i)
+int dead_code(int i) {
+  // PGOUSE: br {{.*}}, !prof !{{[0-9]+}}
+  if (i) {
+    // This branch is never reached.
+
+    // PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}{{$}}
+    if (!i) {}
+
+    // PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}{{$}}
+    for (i = 0; i < 100; ++i) {
+    }
+
+    // PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}{{$}}
+    while (--i) {}
+
+    // PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}{{$}}
+    do {} while (i++ < 75);
+
+    // PGOUSE: switch {{.*}} [
+    // PGOUSE-NEXT: i32 12
+    // PGOUSE-NEXT: i32 82
+    // PGOUSE-NEXT: ]{{$}}
+    switch (i) {
+    case 12: return 3;
+    case 82: return 0;
+    default: return 89;
+    }
+  }
+  return 2;
+}
+
+// PGOUSE-LABEL: @main(i32 %argc, i8** %argv)
+int main(int argc, const char *argv[]) {
+  dead_code(0);
+  return 0;
+}
diff --git a/test/Profile/c-unprofiled.c b/test/Profile/c-unprofiled.c
new file mode 100644
index 0000000..275cd2d
--- /dev/null
+++ b/test/Profile/c-unprofiled.c
@@ -0,0 +1,26 @@
+// Test that unprofiled files are recognized. Here, we have two functions in the
+// profile, main() and function_in_header, but we use the profile on a file that
+// has the profile-less some_unprofiled_function so that the only profiled code
+// in #included in a header.
+
+// FIXME: It would be nice to use -verify here instead of FileCheck, but -verify
+// doesn't play well with warnings that have no line number.
+
+// RUN: llvm-profdata merge %S/Inputs/c-unprofiled.proftext -o %t.profdata
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-unprofiled.c -I %S/Inputs/ %s -o /dev/null -emit-llvm -fprofile-instr-use=%t.profdata -Wprofile-instr-unprofiled 2>&1 | FileCheck %s
+
+// CHECK: warning: no profile data available for file "c-unprofiled.c"
+
+#include "profiled_header.h"
+
+#ifdef GENERATE_OUTDATED_DATA
+int main(int argc, const char *argv[]) {
+  function_in_header(0);
+  return 0;
+}
+#else
+void some_unprofiled_function(int i) {
+  if (i)
+    function_in_header(i);
+}
+#endif
diff --git a/test/Profile/cxx-class.cpp b/test/Profile/cxx-class.cpp
new file mode 100644
index 0000000..1a0c84b
--- /dev/null
+++ b/test/Profile/cxx-class.cpp
@@ -0,0 +1,78 @@
+// Tests for instrumentation of C++ methods, constructors, and destructors.
+
+// RUN: %clang %s -o - -emit-llvm -S -fprofile-instr-generate -fno-exceptions -target %itanium_abi_triple > %tgen
+// RUN: FileCheck --input-file=%tgen -check-prefix=CTRGEN %s
+// 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: llvm-profdata merge %S/Inputs/cxx-class.proftext -o %t.profdata
+// RUN: %clang %s -o - -emit-llvm -S -fprofile-instr-use=%t.profdata -fno-exceptions -target %itanium_abi_triple > %tuse
+// RUN: FileCheck --input-file=%tuse -check-prefix=CTRUSE %s
+// 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
+
+class Simple {
+  int Member;
+public:
+  // CTRGEN-LABEL: define {{.*}} @_ZN6SimpleC2Ei(
+  // CTRUSE-LABEL: define {{.*}} @_ZN6SimpleC2Ei(
+  // CTRGEN: store {{.*}} @[[SCC:__llvm_profile_counters__ZN6SimpleC2Ei]], i64 0, i64 0
+  explicit Simple(int Member) : Member(Member) {
+    // CTRGEN: store {{.*}} @[[SCC]], i64 0, i64 1
+    // CTRUSE: br {{.*}} !prof ![[SC1:[0-9]+]]
+    if (Member) {}
+    // CTRGEN-NOT: store {{.*}} @[[SCC]],
+    // CTRUSE-NOT: br {{.*}} !prof ![0-9]+
+    // CTRUSE: ret
+  }
+  // CTRUSE: ![[SC1]] = metadata !{metadata !"branch_weights", i32 100, i32 2}
+
+  // DTRGEN-LABEL: define {{.*}} @_ZN6SimpleD2Ev(
+  // DTRUSE-LABEL: define {{.*}} @_ZN6SimpleD2Ev(
+  // DTRGEN: store {{.*}} @[[SDC:__llvm_profile_counters__ZN6SimpleD2Ev]], i64 0, i64 0
+  ~Simple() {
+    // DTRGEN: store {{.*}} @[[SDC]], i64 0, i64 1
+    // DTRUSE: br {{.*}} !prof ![[SD1:[0-9]+]]
+    if (Member) {}
+    // DTRGEN-NOT: store {{.*}} @[[SDC]],
+    // DTRUSE-NOT: br {{.*}} !prof ![0-9]+
+    // DTRUSE: ret
+  }
+  // DTRUSE: ![[SD1]] = metadata !{metadata !"branch_weights", i32 100, i32 2}
+
+  // MTHGEN-LABEL: define {{.*}} @_ZN6Simple6methodEv(
+  // MTHUSE-LABEL: define {{.*}} @_ZN6Simple6methodEv(
+  // MTHGEN: store {{.*}} @[[SMC:__llvm_profile_counters__ZN6Simple6methodEv]], i64 0, i64 0
+  void method() {
+    // MTHGEN: store {{.*}} @[[SMC]], i64 0, i64 1
+    // MTHUSE: br {{.*}} !prof ![[SM1:[0-9]+]]
+    if (Member) {}
+    // MTHGEN-NOT: store {{.*}} @[[SMC]],
+    // MTHUSE-NOT: br {{.*}} !prof ![0-9]+
+    // MTHUSE: ret
+  }
+  // MTHUSE: ![[SM1]] = metadata !{metadata !"branch_weights", i32 100, i32 2}
+};
+
+// WRPGEN-LABEL: define {{.*}} @_Z14simple_wrapperv(
+// WRPUSE-LABEL: define {{.*}} @_Z14simple_wrapperv(
+// WRPGEN: store {{.*}} @[[SWC:__llvm_profile_counters__Z14simple_wrapperv]], i64 0, i64 0
+void simple_wrapper() {
+  // WRPGEN: store {{.*}} @[[SWC]], i64 0, i64 1
+  // WRPUSE: br {{.*}} !prof ![[SW1:[0-9]+]]
+  for (int I = 0; I < 100; ++I) {
+    Simple S(I);
+    S.method();
+  }
+  // WRPGEN-NOT: store {{.*}} @[[SWC]],
+  // WRPUSE-NOT: br {{.*}} !prof ![0-9]+
+  // WRPUSE: ret
+}
+// WRPUSE: ![[SW1]] = metadata !{metadata !"branch_weights", i32 101, i32 2}
+
+int main(int argc, const char *argv[]) {
+  simple_wrapper();
+  return 0;
+}
diff --git a/test/Profile/cxx-implicit.cpp b/test/Profile/cxx-implicit.cpp
new file mode 100644
index 0000000..79840ad
--- /dev/null
+++ b/test/Profile/cxx-implicit.cpp
@@ -0,0 +1,17 @@
+// Ensure that implicit methods aren't instrumented.
+
+// RUN: %clang_cc1 -x c++ %s -triple %itanium_abi_triple -main-file-name cxx-implicit.cpp -o - -emit-llvm -fprofile-instr-generate | FileCheck %s
+
+// An implicit constructor is generated for Base. We should not emit counters
+// for it.
+// CHECK-NOT: @__llvm_profile_counters__ZN4BaseC2Ev =
+
+struct Base {
+  virtual void foo();
+};
+
+struct Derived : public Base {
+  Derived();
+};
+
+Derived::Derived() {}
diff --git a/test/Profile/cxx-lambda.cpp b/test/Profile/cxx-lambda.cpp
new file mode 100644
index 0000000..6c37a86
--- /dev/null
+++ b/test/Profile/cxx-lambda.cpp
@@ -0,0 +1,58 @@
+// Tests for instrumentation of C++11 lambdas
+
+// RUN: %clang_cc1 -x c++ %s -triple %itanium_abi_triple -main-file-name cxx-lambda.cpp -std=c++11 -o - -emit-llvm -fprofile-instr-generate > %tgen
+// RUN: FileCheck --input-file=%tgen -check-prefix=PGOGEN %s
+// RUN: FileCheck --input-file=%tgen -check-prefix=LMBGEN %s
+
+// RUN: llvm-profdata merge %S/Inputs/cxx-lambda.proftext -o %t.profdata
+// RUN: %clang_cc1 -x c++ %s -triple %itanium_abi_triple -main-file-name cxx-lambda.cpp -std=c++11 -o - -emit-llvm -fprofile-instr-use=%t.profdata > %tuse
+// RUN: FileCheck --input-file=%tuse -check-prefix=PGOUSE %s
+// RUN: FileCheck --input-file=%tuse -check-prefix=LMBUSE %s
+
+// PGOGEN: @[[LWC:__llvm_profile_counters__Z7lambdasv]] = hidden global [4 x i64] zeroinitializer
+// PGOGEN: @[[MAC:__llvm_profile_counters_main]] = hidden global [1 x i64] zeroinitializer
+// LMBGEN: @[[LFC:"__llvm_profile_counters__ZZ7lambdasvENK3\$_0clEi"]] = internal global [3 x i64] zeroinitializer
+
+// PGOGEN-LABEL: define void @_Z7lambdasv()
+// PGOUSE-LABEL: define void @_Z7lambdasv()
+// PGOGEN: store {{.*}} @[[LWC]], i64 0, i64 0
+void lambdas() {
+  int i = 1;
+
+  // LMBGEN-LABEL: define internal{{( zeroext)?}} i1 @"_ZZ7lambdasvENK3$_0clEi"(
+  // LMBUSE-LABEL: define internal{{( zeroext)?}} i1 @"_ZZ7lambdasvENK3$_0clEi"(
+  // LMBGEN: store {{.*}} @[[LFC]], i64 0, i64 0
+  auto f = [&i](int k) {
+    // LMBGEN: store {{.*}} @[[LFC]], i64 0, i64 1
+    // LMBUSE: br {{.*}} !prof ![[LF1:[0-9]+]]
+    if (i > 0) {}
+    // LMBGEN: store {{.*}} @[[LFC]], i64 0, i64 2
+    // LMBUSE: br {{.*}} !prof ![[LF2:[0-9]+]]
+    return k && i;
+  };
+
+  // PGOGEN: store {{.*}} @[[LWC]], i64 0, i64 1
+  // PGOUSE: br {{.*}} !prof ![[LW1:[0-9]+]]
+  if (i) {}
+
+  // PGOGEN: store {{.*}} @[[LWC]], i64 0, i64 2
+  // PGOUSE: br {{.*}} !prof ![[LW2:[0-9]+]]
+  for (i = 0; i < 10; ++i)
+    f(9 - i);
+
+  // PGOGEN: store {{.*}} @[[LWC]], i64 0, i64 3
+  // PGOUSE: br {{.*}} !prof ![[LW3:[0-9]+]]
+  if (i) {}
+}
+
+// PGOUSE-DAG: ![[LW1]] = metadata !{metadata !"branch_weights", i32 2, i32 1}
+// PGOUSE-DAG: ![[LW2]] = metadata !{metadata !"branch_weights", i32 11, i32 2}
+// PGOUSE-DAG: ![[LW3]] = metadata !{metadata !"branch_weights", i32 2, i32 1}
+
+// LMBUSE-DAG: ![[LF1]] = metadata !{metadata !"branch_weights", i32 10, i32 2}
+// LMBUSE-DAG: ![[LF2]] = metadata !{metadata !"branch_weights", i32 10, i32 2}
+
+int main(int argc, const char *argv[]) {
+  lambdas();
+  return 0;
+}
diff --git a/test/Profile/cxx-linkage.cpp b/test/Profile/cxx-linkage.cpp
new file mode 100644
index 0000000..df896e7
--- /dev/null
+++ b/test/Profile/cxx-linkage.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9.0 -emit-llvm -main-file-name cxx-linkage.cpp %s -o - -fprofile-instr-generate | FileCheck %s
+
+// CHECK: @__llvm_profile_runtime = external global i32
+// CHECK: @__llvm_profile_counters__Z3foov = hidden global [1 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8
+// CHECK: @__llvm_profile_name__Z3foov = hidden constant [7 x i8] c"_Z3foov", section "__DATA,__llvm_prf_names", align 1
+// CHECK: @__llvm_profile_data__Z3foov = hidden constant { i32, i32, i64, i8*, i64* } { i32 7, i32 1, i64 {{[0-9]+}}, i8* getelementptr inbounds ([7 x i8]* @__llvm_profile_name__Z3foov, i32 0, i32 0), i64* getelementptr inbounds ([1 x i64]* @__llvm_profile_counters__Z3foov, i32 0, i32 0) }, section "__DATA,__llvm_prf_data", align 8
+void foo(void) { }
+
+// CHECK: @__llvm_profile_counters__Z8foo_weakv = weak hidden global [5 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8
+// CHECK: @__llvm_profile_name__Z8foo_weakv = weak hidden constant [12 x i8] c"_Z8foo_weakv", section "__DATA,__llvm_prf_names", align 1
+// CHECK: @__llvm_profile_data__Z8foo_weakv = weak hidden constant { i32, i32, i64, i8*, i64* } { i32 12, i32 5, i64 {{[0-9]+}}, i8* getelementptr inbounds ([12 x i8]* @__llvm_profile_name__Z8foo_weakv, i32 0, i32 0), i64* getelementptr inbounds ([5 x i64]* @__llvm_profile_counters__Z8foo_weakv, i32 0, i32 0) }, section "__DATA,__llvm_prf_data", align 8
+void foo_weak(void) __attribute__((weak));
+void foo_weak(void) { if (0){} if (0){} if (0){} if (0){} }
+
+// CHECK: @__llvm_profile_counters_main = hidden global [1 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8
+// CHECK: @__llvm_profile_name_main = hidden constant [4 x i8] c"main", section "__DATA,__llvm_prf_names", align 1
+// CHECK: @__llvm_profile_data_main = hidden constant { i32, i32, i64, i8*, i64* } { i32 4, i32 1, i64 {{[0-9]+}}, i8* getelementptr inbounds ([4 x i8]* @__llvm_profile_name_main, i32 0, i32 0), i64* getelementptr inbounds ([1 x i64]* @__llvm_profile_counters_main, i32 0, i32 0) }, section "__DATA,__llvm_prf_data", align 8
+inline void foo_inline(void);
+int main(void) {
+  foo();
+  foo_inline();
+  foo_weak();
+  return 0;
+}
+
+// CHECK: @__llvm_profile_counters__Z10foo_inlinev = linkonce_odr hidden global [7 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8
+// CHECK: @__llvm_profile_name__Z10foo_inlinev = linkonce_odr hidden constant [15 x i8] c"_Z10foo_inlinev", section "__DATA,__llvm_prf_names", align 1
+// CHECK: @__llvm_profile_data__Z10foo_inlinev = linkonce_odr hidden constant { i32, i32, i64, i8*, i64* } { i32 15, i32 7, i64 {{[0-9]+}}, i8* getelementptr inbounds ([15 x i8]* @__llvm_profile_name__Z10foo_inlinev, i32 0, i32 0), i64* getelementptr inbounds ([7 x i64]* @__llvm_profile_counters__Z10foo_inlinev, i32 0, i32 0) }, section "__DATA,__llvm_prf_data", align 8
+inline void foo_inline(void) { if (0){} if (0){} if (0){} if (0){} if (0){} if (0){}}
+
+// CHECK: @llvm.used = appending global [5 x i8*] [i8* bitcast (i32 ()* @__llvm_profile_runtime_user to i8*), i8* bitcast ({ i32, i32, i64, i8*, i64* }* @__llvm_profile_data__Z3foov to i8*), i8* bitcast ({ i32, i32, i64, i8*, i64* }* @__llvm_profile_data__Z8foo_weakv to i8*), i8* bitcast ({ i32, i32, i64, i8*, i64* }* @__llvm_profile_data_main to i8*), i8* bitcast ({ i32, i32, i64, i8*, i64* }* @__llvm_profile_data__Z10foo_inlinev to i8*)], section "llvm.metadata"
+
+// CHECK: define linkonce_odr i32 @__llvm_profile_runtime_user() {{.*}} {
+// CHECK:   %[[REG:.*]] = load i32* @__llvm_profile_runtime
+// CHECK:   ret i32 %[[REG]]
+// CHECK: }
diff --git a/test/Profile/cxx-templates.cpp b/test/Profile/cxx-templates.cpp
new file mode 100644
index 0000000..55ab36f
--- /dev/null
+++ b/test/Profile/cxx-templates.cpp
@@ -0,0 +1,42 @@
+// Tests for instrumentation of templated code. Each instantiation of a template
+// should be instrumented separately.
+
+// RUN: %clang_cc1 -x c++ %s -triple %itanium_abi_triple -main-file-name cxx-templates.cpp -std=c++11 -o - -emit-llvm -fprofile-instr-generate > %tgen
+// RUN: FileCheck --input-file=%tgen -check-prefix=T0GEN -check-prefix=ALL %s
+// RUN: FileCheck --input-file=%tgen -check-prefix=T100GEN -check-prefix=ALL %s
+
+// RUN: llvm-profdata merge %S/Inputs/cxx-templates.proftext -o %t.profdata
+// RUN: %clang_cc1 -x c++ %s -triple %itanium_abi_triple -main-file-name cxx-templates.cpp -std=c++11 -o - -emit-llvm -fprofile-instr-use=%t.profdata > %tuse
+// RUN: FileCheck --input-file=%tuse -check-prefix=T0USE -check-prefix=ALL %s
+// RUN: FileCheck --input-file=%tuse -check-prefix=T100USE -check-prefix=ALL %s
+
+// T0GEN: @[[T0C:__llvm_profile_counters__Z4loopILj0EEvv]] = linkonce_odr hidden global [2 x i64] zeroinitializer
+// T100GEN: @[[T100C:__llvm_profile_counters__Z4loopILj100EEvv]] = linkonce_odr hidden global [2 x i64] zeroinitializer
+
+// T0GEN-LABEL: define linkonce_odr void @_Z4loopILj0EEvv()
+// T0USE-LABEL: define linkonce_odr void @_Z4loopILj0EEvv()
+// T100GEN-LABEL: define linkonce_odr void @_Z4loopILj100EEvv()
+// T100USE-LABEL: define linkonce_odr void @_Z4loopILj100EEvv()
+template <unsigned N> void loop() {
+  // ALL-NOT: ret
+  // T0GEN: store {{.*}} @[[T0C]], i64 0, i64 0
+  // T100GEN: store {{.*}} @[[T100C]], i64 0, i64 0
+
+  // ALL-NOT: ret
+  // T0GEN: store {{.*}} @[[T0C]], i64 0, i64 1
+  // T0USE: br {{.*}} !prof ![[T01:[0-9]+]]
+  // T100GEN: store {{.*}} @[[T100C]], i64 0, i64 1
+  // T100USE: br {{.*}} !prof ![[T1001:[0-9]+]]
+  for (unsigned I = 0; I < N; ++I) {}
+
+  // ALL: ret
+}
+
+// T0USE-DAG: ![[T01]] = metadata !{metadata !"branch_weights", i32 1, i32 2}
+// T100USE-DAG: ![[T1001]] = metadata !{metadata !"branch_weights", i32 101, i32 2}
+
+int main(int argc, const char *argv[]) {
+  loop<0>();
+  loop<100>();
+  return 0;
+}
diff --git a/test/Profile/cxx-throws.cpp b/test/Profile/cxx-throws.cpp
new file mode 100644
index 0000000..9ea5ace
--- /dev/null
+++ b/test/Profile/cxx-throws.cpp
@@ -0,0 +1,73 @@
+// Test instrumentation of C++ exception handling constructs.
+
+// FIXME: Don't seek bb labels, like "if.else"
+// REQUIRES: asserts
+
+// RUN: %clangxx %s -o - -emit-llvm -S -fprofile-instr-generate -target %itanium_abi_triple | FileCheck -check-prefix=PGOGEN %s
+// RUN: %clangxx %s -o - -emit-llvm -S -fprofile-instr-generate -target %itanium_abi_triple | FileCheck -check-prefix=PGOGEN-EXC %s
+
+// RUN: llvm-profdata merge %S/Inputs/cxx-throws.proftext -o %t.profdata
+// RUN: %clang %s -o - -emit-llvm -S -fprofile-instr-use=%t.profdata -target %itanium_abi_triple | FileCheck -check-prefix=PGOUSE %s
+// RUN: %clang %s -o - -emit-llvm -S -fprofile-instr-use=%t.profdata -target %itanium_abi_triple | FileCheck -check-prefix=PGOUSE-EXC %s
+
+// PGOGEN: @[[THC:__llvm_profile_counters__Z6throwsv]] = hidden global [9 x i64] zeroinitializer
+// PGOGEN-EXC: @[[THC:__llvm_profile_counters__Z6throwsv]] = hidden global [9 x i64] zeroinitializer
+
+// PGOGEN-LABEL: @_Z6throwsv()
+// PGOUSE-LABEL: @_Z6throwsv()
+// PGOGEN: store {{.*}} @[[THC]], i64 0, i64 0
+void throws() {
+  // PGOGEN: store {{.*}} @[[THC]], i64 0, i64 1
+  // PGOUSE: br {{.*}} !prof ![[TH1:[0-9]+]]
+  for (int i = 0; i < 100; ++i) {
+    try {
+      // PGOGEN: store {{.*}} @[[THC]], i64 0, i64 3
+      // PGOUSE: br {{.*}} !prof ![[TH2:[0-9]+]]
+      if (i % 3) {
+        // PGOGEN: store {{.*}} @[[THC]], i64 0, i64 4
+        // PGOUSE: br {{.*}} !prof ![[TH3:[0-9]+]]
+        if (i < 50)
+          throw 1;
+      } else {
+        // The catch block may be emitted after the throw above, we can skip it
+        // by looking for an else block, but this will break if anyone puts an
+        // else in the catch
+        // PGOUSE: if.else{{.*}}:
+        // PGOGEN: if.else{{.*}}:
+
+        // PGOGEN: store {{.*}} @[[THC]], i64 0, i64 5
+        // PGOUSE: br {{.*}} !prof ![[TH4:[0-9]+]]
+        if (i >= 50)
+          throw 0;
+      }
+    } catch (int e) {
+      // PGOUSE-EXC: catch{{.*}}:
+      // PGOGEN-EXC: catch{{.*}}:
+
+      // PGOGEN-EXC: store {{.*}} @[[THC]], i64 0, i64 6
+      // PGOGEN-EXC: store {{.*}} @[[THC]], i64 0, i64 7
+      // PGOUSE-EXC: br {{.*}} !prof ![[TH5:[0-9]+]]
+      if (e) {}
+    }
+    // PGOGEN: store {{.*}} @[[THC]], i64 0, i64 2
+
+    // PGOGEN: store {{.*}} @[[THC]], i64 0, i64 8
+    // PGOUSE: br {{.*}} !prof ![[TH6:[0-9]+]]
+    if (i < 100) {}
+  }
+
+  // PGOUSE-NOT: br {{.*}} !prof ![0-9]+
+  // PGOUSE: ret void
+}
+
+// PGOUSE-DAG: ![[TH1]] = metadata !{metadata !"branch_weights", i32 101, i32 2}
+// PGOUSE-DAG: ![[TH2]] = metadata !{metadata !"branch_weights", i32 67, i32 35}
+// PGOUSE-DAG: ![[TH3]] = metadata !{metadata !"branch_weights", i32 34, i32 34}
+// PGOUSE-DAG: ![[TH4]] = metadata !{metadata !"branch_weights", i32 18, i32 18}
+// PGOUSE-EXC: ![[TH5]] = metadata !{metadata !"branch_weights", i32 34, i32 18}
+// PGOUSE-DAG: ![[TH6]] = metadata !{metadata !"branch_weights", i32 101, i32 1}
+
+int main(int argc, const char *argv[]) {
+  throws();
+  return 0;
+}
diff --git a/test/Profile/objc-general.m b/test/Profile/objc-general.m
new file mode 100644
index 0000000..ba06f91
--- /dev/null
+++ b/test/Profile/objc-general.m
@@ -0,0 +1,75 @@
+// Test instrumentation of general constructs in objective C.
+
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name objc-general.m %s -o - -emit-llvm -fblocks -fprofile-instr-generate | FileCheck -check-prefix=PGOGEN %s
+
+// RUN: llvm-profdata merge %S/Inputs/objc-general.proftext -o %t.profdata
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name objc-general.m %s -o - -emit-llvm -fblocks -fprofile-instr-use=%t.profdata | FileCheck -check-prefix=PGOUSE %s
+
+#ifdef HAVE_FOUNDATION
+
+// Use this to build an instrumented version to regenerate the input file.
+#import <Foundation/Foundation.h>
+
+#else
+
+// Minimal definitions to get this to compile without Foundation.h.
+
+@protocol NSObject
+@end
+
+@interface NSObject <NSObject>
+- (id)init;
++ (id)alloc;
+@end
+
+struct NSFastEnumerationState;
+@interface NSArray : NSObject
+- (unsigned long) countByEnumeratingWithState: (struct NSFastEnumerationState*) state
+                  objects: (id*) buffer
+                  count: (unsigned long) bufferSize;
++(NSArray*) arrayWithObjects: (id) first, ...;
+@end;
+#endif
+
+// PGOGEN: @[[FRC:"__llvm_profile_counters_\+\[A foreach:\]"]] = internal global [2 x i64] zeroinitializer
+// PGOGEN: @[[BLC:"__llvm_profile_counters___13\+\[A foreach:\]_block_invoke"]] = internal global [2 x i64] zeroinitializer
+// PGOGEN: @[[MAC:__llvm_profile_counters_main]] = hidden global [1 x i64] zeroinitializer
+
+@interface A : NSObject
++ (void)foreach: (NSArray *)array;
+@end
+
+@implementation A
+// PGOGEN: define {{.*}}+[A foreach:]
+// PGOUSE: define {{.*}}+[A foreach:]
+// PGOGEN: store {{.*}} @[[FRC]], i64 0, i64 0
++ (void)foreach: (NSArray *)array
+{
+  __block id result;
+  // PGOGEN: store {{.*}} @[[FRC]], i64 0, i64 1
+  // PGOUSE: br {{.*}} !prof ![[FR1:[0-9]+]]
+  // PGOUSE: br {{.*}} !prof ![[FR2:[0-9]+]]
+  for (id x in array) {
+    // PGOGEN: define {{.*}}_block_invoke
+    // PGOUSE: define {{.*}}_block_invoke
+    // PGOGEN: store {{.*}} @[[BLC]], i64 0, i64 0
+    ^{ static int init = 0;
+      // PGOGEN: store {{.*}} @[[BLC]], i64 0, i64 1
+      // PGOUSE: br {{.*}} !prof ![[BL1:[0-9]+]]
+       if (init)
+         result = x;
+       init = 1; }();
+  }
+}
+@end
+
+// PGOUSE-DAG: ![[FR1]] = metadata !{metadata !"branch_weights", i32 2, i32 3}
+// PGOUSE-DAG: ![[FR2]] = metadata !{metadata !"branch_weights", i32 3, i32 2}
+// PGOUSE-DAG: ![[BL1]] = metadata !{metadata !"branch_weights", i32 2, i32 2}
+
+int main(int argc, const char *argv[]) {
+  A *a = [[A alloc] init];
+  NSArray *array = [NSArray arrayWithObjects: @"0", @"1", (void*)0];
+  [A foreach: array];
+  return 0;
+}
diff --git a/test/Rewriter/dllimport-typedef.c b/test/Rewriter/dllimport-typedef.c
deleted file mode 100644
index 97610dd..0000000
--- a/test/Rewriter/dllimport-typedef.c
+++ /dev/null
@@ -1,17 +0,0 @@
-// RUN: not %clang_cc1 -triple i686-pc-win32 -fms-extensions -fsyntax-only %s 2>&1 | FileCheck -check-prefix=CHECK-NEG %s
-// RUN: not %clang_cc1 -triple i686-pc-win32 -fsyntax-only %s 2>&1 | FileCheck -check-prefix=CHECK-POS %s
-
-// Do not report an error with including dllimport in the typedef when -fms-extensions is specified.
-// Addresses <rdar://problem/7653870>.
-typedef __declspec(dllimport) int CB(void);
-
-// This function is added just to trigger a diagnostic.  This way we can test how many
-// diagnostics we expect.
-void bar() { return 1; }
-
-// CHECK-NEG: error: void function 'bar' should not return a value
-// CHECK-NEG: 1 error generated
-// CHECK-POS: warning: 'dllimport' attribute only applies to variables and functions
-// CHECK-POS: error: void function 'bar' should not return a value
-// CHECK-POS: 1 warning and 1 error generated
-
diff --git a/test/Rewriter/finally.m b/test/Rewriter/finally.m
index f46b4b0..e60ba9e 100644
--- a/test/Rewriter/finally.m
+++ b/test/Rewriter/finally.m
@@ -3,7 +3,7 @@
 int main() {
   @try {
     printf("executing try"); // expected-warning{{implicitly declaring library function 'printf' with type 'int (const char *, ...)'}} \
-        // expected-note{{please include the header <stdio.h> or explicitly provide a declaration for 'printf'}}
+        // expected-note{{include the header <stdio.h> or explicitly provide a declaration for 'printf'}}
     return(0); // expected-warning{{rewriter doesn't support user-specified control flow semantics for @try/@finally (code may not execute properly)}}
   } @finally {
     printf("executing finally");
diff --git a/test/Rewriter/lit.local.cfg b/test/Rewriter/lit.local.cfg
index 5bbc711..69b733b 100644
--- a/test/Rewriter/lit.local.cfg
+++ b/test/Rewriter/lit.local.cfg
@@ -1,2 +1,3 @@
-if config.root.clang_rewriter == 0:
+# The Objective-C rewriters are currently grouped with ARCMT.
+if config.root.clang_arcmt == 0:
     config.unsupported = True
diff --git a/test/Rewriter/missing-dllimport.c b/test/Rewriter/missing-dllimport.c
index 127989b..a09ebff 100644
--- a/test/Rewriter/missing-dllimport.c
+++ b/test/Rewriter/missing-dllimport.c
@@ -1,19 +1,8 @@
-// RUN: not %clang_cc1 -triple i686-pc-win32 -fms-extensions -fsyntax-only %s 2>&1 | FileCheck -check-prefix=CHECK-NEG %s
-// RUN: not %clang_cc1 -triple i686-pc-win32 -fsyntax-only %s 2>&1 | FileCheck -check-prefix=CHECK-POS %s
+// RUN: %clang_cc1 -triple i686-pc-win32 -verify %s
 
-// Do not report that 'foo()' is redeclared without dllimport attribute with -fms-extensions
+// Do not report that 'foo()' is redeclared without dllimport attribute.
 // specified.  Addresses <rdar://problem/7653912>.
 
+// expected-no-diagnostics
 __declspec(dllimport) int __cdecl foo(void);
 inline int __cdecl foo() { return 0; }
-
-// This function is added just to trigger a diagnostic.  This way we can test how many
-// diagnostics we expect.
-void bar() { return 1; }
-
-// CHECK-NEG: error: void function 'bar' should not return a value
-// CHECK-NEG: 1 error generated
-// CHECK-POS: warning: 'foo' redeclared without dllimport attribute: previous dllimport ignored
-// CHECK-POS: error: void function 'bar' should not return a value
-// CHECK-POS: 1 warning and 1 error generated
-
diff --git a/test/Rewriter/no-integrated-preprocessing-64bit.m b/test/Rewriter/no-integrated-preprocessing-64bit.m
index 6318449..ea63c0b 100644
--- a/test/Rewriter/no-integrated-preprocessing-64bit.m
+++ b/test/Rewriter/no-integrated-preprocessing-64bit.m
@@ -1,4 +1,4 @@
-// RUN: %clang -target x86_64-unkown-unknown -fms-extensions -rewrite-objc %s -o - | FileCheck %s
+// RUN: %clang -target x86_64-unknown-unknown -fms-extensions -rewrite-objc %s -o - | FileCheck %s
 // rdar://12189793
 
 #ifdef __cplusplus
diff --git a/test/Rewriter/no-integrated-preprocessing.m b/test/Rewriter/no-integrated-preprocessing.m
index e4cc301..bc27a63 100644
--- a/test/Rewriter/no-integrated-preprocessing.m
+++ b/test/Rewriter/no-integrated-preprocessing.m
@@ -1,4 +1,4 @@
-// RUN: %clang -arch i386 -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: %clang -target i386-unknown-unknown -fms-extensions -rewrite-objc %s -o %t-rw.cpp
 // RUN: FileCheck %s < %t-rw.cpp
 // rdar://12189793
 
@@ -23,4 +23,4 @@
 // CHECK: static struct _class_ro_t _OBJC_CLASS_RO_$_MYINTF
 // CHECK-NEXT: 0, 0, 0,
 // CHECK-NEXT: 0,
-// CHECK-NEST: "MYINTF",
+// CHECK-NEXT: "MYINTF",
diff --git a/test/Rewriter/protocol-rewrite-1.m b/test/Rewriter/protocol-rewrite-1.m
index 541b7ee..0c5104f 100644
--- a/test/Rewriter/protocol-rewrite-1.m
+++ b/test/Rewriter/protocol-rewrite-1.m
@@ -1,4 +1,7 @@
-// RUN: %clang_cc1 -rewrite-objc -fobjc-runtime=macosx-fragile-10.5  %s -o -
+// RUN: %clang_cc1 -x objective-c -Wno-objc-root-class -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: FileCheck  --input-file=%t-rw.cpp %s
+// rdar://9846759
+// rdar://15517895
 
 typedef struct MyWidget {
   int a;
@@ -46,3 +49,25 @@
 
   return 0;
 }
+
+// rdar://15517895
+@class NSObject;
+
+@interface NSProtocolChecker
++ (id)protocolCheckerWithTarget:(NSObject *)anObject protocol:(Protocol *)aProtocol;
+@end
+
+@protocol NSConnectionVersionedProtocol
+@end
+
+
+@interface NSConnection @end
+
+@implementation NSConnection
+- (void) Meth {
+  [NSProtocolChecker protocolCheckerWithTarget:0 protocol:@protocol(NSConnectionVersionedProtocol)];
+}
+@end
+
+// CHECK: static struct _protocol_t *_OBJC_PROTOCOL_REFERENCE_$_NSConnectionVersionedProtocol = &_OBJC_PROTOCOL_NSConnectionVersionedProtocol
+// CHECK: sel_registerName("protocolCheckerWithTarget:protocol:"), (NSObject *)0, (Protocol *)_OBJC_PROTOCOL_REFERENCE_$_NSConnectionVersionedProtocol
diff --git a/test/Sema/2007-10-01-BuildArrayRef.c b/test/Sema/2007-10-01-BuildArrayRef.c
index 4692731..2552934 100644
--- a/test/Sema/2007-10-01-BuildArrayRef.c
+++ b/test/Sema/2007-10-01-BuildArrayRef.c
@@ -1,9 +1,9 @@
-// RUN: not %clang_cc1_only -c %s -o - > /dev/null
+// RUN: %clang_cc1 -fsyntax-only -verify %s
 // PR 1603
 void func()
 {
    const int *arr;
-   arr[0] = 1;  // expected-error {{assignment of read-only location}}
+   arr[0] = 1;  // expected-error {{read-only variable is not assignable}}
 }
 
 struct foo {
@@ -15,6 +15,6 @@
 {
   const struct foo *fp;
   fp = &sfoo;
-  fp[0].bar = 1;  // expected-error {{ assignment of read-only member}}
+  fp[0].bar = 1;  // expected-error {{read-only variable is not assignable}}
   return sfoo.bar;
 }
diff --git a/test/Sema/2009-03-09-WeakDeclarations-1.c b/test/Sema/2009-03-09-WeakDeclarations-1.c
index f219de6..c0035a4 100644
--- a/test/Sema/2009-03-09-WeakDeclarations-1.c
+++ b/test/Sema/2009-03-09-WeakDeclarations-1.c
@@ -1,12 +1,12 @@
-// RUN: %clang_cc1 %s -triple i686-apple-darwin
+// RUN: %clang_cc1 -verify %s -triple i686-apple-darwin
 // Insist upon warnings for inappropriate weak attributes.
 
 // O.K.
 extern int ext_weak_import __attribute__ ((__weak_import__));
 
 // These are inappropriate, and should generate warnings:
-int decl_weak_import __attribute__ ((__weak_import__)); // expected-warning {'weak_import' attribute cannot be specified on a definition}
-int decl_initialized_weak_import __attribute__ ((__weak_import__)) = 13; // expected-warning {'weak_import' attribute cannot be specified on a definition}
+int decl_weak_import __attribute__ ((__weak_import__)); // expected-warning {{'weak_import' attribute cannot be specified on a definition}}
+int decl_initialized_weak_import __attribute__ ((__weak_import__)) = 13; // expected-warning {{'weak_import' attribute cannot be specified on a definition}}
 
 // O.K.
 extern int ext_f(void) __attribute__ ((__weak_import__));
diff --git a/test/Sema/2009-04-22-UnknownSize.c b/test/Sema/2009-04-22-UnknownSize.c
index 9f71740..60bd8d2 100644
--- a/test/Sema/2009-04-22-UnknownSize.c
+++ b/test/Sema/2009-04-22-UnknownSize.c
@@ -1,4 +1,4 @@
-// RUN: not %clang_cc1 %s -emit-llvm -o -
+// RUN: not %clang_cc1 -fsyntax-only -verify %s
 // PR2958
 static struct foo s; // expected-error { tentative definition has type 'struct foo' that is never completed }
 struct foo *p = &s;
diff --git a/test/Sema/2009-07-17-VoidParameter.c b/test/Sema/2009-07-17-VoidParameter.c
index 68d1b1e..b838b02 100644
--- a/test/Sema/2009-07-17-VoidParameter.c
+++ b/test/Sema/2009-07-17-VoidParameter.c
@@ -1,4 +1,4 @@
-// RUN: not %clang_cc1 -emit-llvm %s -o -
+// RUN: %clang_cc1 -verify -fsyntax-only %s
 // PR4214
 typedef void vt;
-void (*func_ptr)(vt my_vt); // expected-error {argument may not have 'void' type}
+void (*func_ptr)(vt my_vt); // expected-error {{argument may not have 'void' type}}
diff --git a/test/Sema/Inputs/ms-keyword-system-header.h b/test/Sema/Inputs/ms-keyword-system-header.h
new file mode 100644
index 0000000..dda4c2a
--- /dev/null
+++ b/test/Sema/Inputs/ms-keyword-system-header.h
@@ -0,0 +1,9 @@
+/* "System header" for testing GNU libc keyword conflict workarounds */
+
+typedef union {
+  union w *__uptr;
+#if defined(MS) && defined(NOT_SYSTEM)
+  // expected-warning@-2 {{keyword '__uptr' will be made available as an identifier here}}
+#endif
+  int *__iptr;
+} WS __attribute__((__transparent_union__));
diff --git a/test/Sema/Inputs/warn-unreachable.h b/test/Sema/Inputs/warn-unreachable.h
new file mode 100644
index 0000000..394242f
--- /dev/null
+++ b/test/Sema/Inputs/warn-unreachable.h
@@ -0,0 +1,7 @@
+// Test that this unreachable code warning is
+// not reported because it is in a header.
+
+void foo_unreachable_header() {
+  return;
+  foo_unreachable_header(); // no-warning
+}
\ No newline at end of file
diff --git a/test/Sema/MicrosoftCompatibility.c b/test/Sema/MicrosoftCompatibility.c
index 6330c15..a193b26 100644
--- a/test/Sema/MicrosoftCompatibility.c
+++ b/test/Sema/MicrosoftCompatibility.c
@@ -16,6 +16,8 @@
 }
 
 __declspec(align(32768)) struct S1 { int a; } s;	/* expected-error {{requested alignment must be 8192 bytes or smaller}} */
-struct __declspec(aligned) S2 {}; /* expected-warning {{unknown __declspec attribute 'aligned' ignored}} */
+struct __declspec(aligned) S2 {}; /* expected-warning {{__declspec attribute 'aligned' is not supported}} */
 
 struct __declspec(appdomain) S3 {}; /* expected-warning {{__declspec attribute 'appdomain' is not supported}} */
+
+__declspec(__noreturn__) void f7(void); /* expected-warning {{__declspec attribute '__noreturn__' is not supported}} */
diff --git a/test/Sema/MicrosoftExtensions.c b/test/Sema/MicrosoftExtensions.c
index a6caf7a..429dd94 100644
--- a/test/Sema/MicrosoftExtensions.c
+++ b/test/Sema/MicrosoftExtensions.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -fsyntax-only -Wno-unused-value -Wmicrosoft -verify -fms-extensions
+// RUN: %clang_cc1 -triple i686-windows %s -fsyntax-only -Wno-unused-value -Wmicrosoft -verify -fms-extensions
 
 
 struct A
@@ -20,10 +20,7 @@
    int D[];
 };
 
-
-
-
-
+struct __declspec(uuid("00000000-0000-0000-C000-000000000046")) IUnknown {}; /* expected-error {{'uuid' attribute is not supported in C}} */
 
 typedef struct notnested {
   long bad1;
@@ -90,11 +87,11 @@
   AA; // expected-warning {{anonymous structs are a Microsoft extension}}
 } BB;
 
-__declspec(deprecated("This is deprecated")) enum DE1 { one, two } e1; // expected-note {{'e1' declared here}}
-struct __declspec(deprecated) DS1 { int i; float f; }; // expected-note {{declared here}}
+__declspec(deprecated("This is deprecated")) enum DE1 { one, two } e1; // expected-note {{'e1' has been explicitly marked deprecated here}}
+struct __declspec(deprecated) DS1 { int i; float f; }; // expected-note {{'DS1' has been explicitly marked deprecated here}}
 
 #define MY_TEXT		"This is also deprecated"
-__declspec(deprecated(MY_TEXT)) void Dfunc1( void ) {} // expected-note {{'Dfunc1' declared here}}
+__declspec(deprecated(MY_TEXT)) void Dfunc1( void ) {} // expected-note {{'Dfunc1' has been explicitly marked deprecated here}}
 
 struct __declspec(deprecated(123)) DS2 {};	// expected-error {{'deprecated' attribute requires a string}}
 
@@ -134,3 +131,17 @@
 
 typedef int *T;
 T __ptr32 wrong10; // expected-error {{'__ptr32' attribute only applies to pointer arguments}}
+
+typedef char *my_va_list;
+void __va_start(my_va_list *ap, ...); // expected-note {{passing argument to parameter 'ap' here}}
+void vmyprintf(const char *f, my_va_list ap);
+void myprintf(const char *f, ...) {
+  my_va_list ap;
+  if (1) {
+    __va_start(&ap, f);
+    vmyprintf(f, ap);
+    ap = 0;
+  } else {
+    __va_start(ap, f); // expected-warning {{incompatible pointer types passing 'my_va_list'}}
+  }
+}
diff --git a/test/Sema/__try.c b/test/Sema/__try.c
index 1641402..a355de9 100644
--- a/test/Sema/__try.c
+++ b/test/Sema/__try.c
@@ -170,3 +170,22 @@
   (void)GetExceptionInformation(); // expected-error{{only allowed in __except filter expression}}
   (void)AbnormalTermination();  // expected-error{{only allowed in __finally block}}
 }
+
+void test_seh_leave_stmt() {
+  __leave; // expected-error{{'__leave' statement not in __try block}}
+
+  __try {
+    __leave;
+    __leave 4; // expected-error{{expected ';' after __leave statement}}
+  } __except(1) {
+    __leave; // expected-error{{'__leave' statement not in __try block}}
+  }
+
+  __try {
+    __leave;
+  } __finally {
+    __leave; // expected-error{{'__leave' statement not in __try block}}
+  }
+  __leave; // expected-error{{'__leave' statement not in __try block}}
+}
+
diff --git a/test/Sema/aarch64-neon-ranges.c b/test/Sema/aarch64-neon-ranges.c
new file mode 100644
index 0000000..3a170b8
--- /dev/null
+++ b/test/Sema/aarch64-neon-ranges.c
@@ -0,0 +1,218 @@
+// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -ffreestanding -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple arm64-linux-gnu -target-feature +neon -ffreestanding -fsyntax-only -verify %s
+
+#include <arm_neon.h>
+
+void test_vext_8bit(int8x8_t small, int8x16_t big) {
+  vext_s8(small, small, 7);
+  vext_u8(small, small, 7);
+  vext_p8(small, small, 7);
+  vextq_s8(big, big, 15);
+  vextq_u8(big, big, 15);
+  vextq_p8(big, big, 15);
+
+  vext_s8(small, small, 8); // expected-error {{argument should be a value from 0 to 7}}
+  vext_u8(small, small, 8); // expected-error {{argument should be a value from 0 to 7}}
+  vext_p8(small, small, 8); // expected-error {{argument should be a value from 0 to 7}}
+  vextq_s8(big, big, 16); // expected-error {{argument should be a value from 0 to 15}}
+  vextq_u8(big, big, 16); // expected-error {{argument should be a value from 0 to 15}}
+  vextq_p8(big, big, 16); // expected-error {{argument should be a value from 0 to 15}}
+}
+
+void test_mul_lane_f64(float64x1_t small, float64x2_t big, float64x2_t rhs) {
+  vmul_lane_f64(small, small, 0);
+  vmul_laneq_f64(small, big, 1);
+  vmulq_lane_f64(big, small, 0);
+  vmulq_laneq_f64(big, big, 1);
+  vfma_lane_f64(small, small, small, 0);
+  vfma_laneq_f64(small, small, big, 1);
+  vfmaq_lane_f64(big, big, small, 0);
+  vfmaq_laneq_f64(big, big, big, 1);
+
+  vmul_lane_f64(small, small, 1); // expected-error {{argument should be a value from 0 to 0}}
+  vmul_laneq_f64(small, big, 2); // expected-error {{argument should be a value from 0 to 1}}
+  vfma_lane_f64(small, small, small, 1); // expected-error {{argument should be a value from 0 to 0}}
+  vfma_laneq_f64(small, small, big, 2); // expected-error {{argument should be a value from 0 to 1}}
+  vfmaq_laneq_f64(big, big, big, 2); // expected-error {{argument should be a value from 0 to 1}}
+}
+
+void test_ld1st1(int8x8_t small, int8x16_t big, void *addr) {
+  vld1_lane_s8(addr, small, 7);
+  vld1_lane_s16(addr, small, 3);
+  vld1_lane_s32(addr, small, 1);
+  vld1_lane_s64(addr, small, 0);
+
+  vld1q_lane_s8(addr, big, 15);
+  vld1q_lane_s16(addr, big, 7);
+  vld1q_lane_s32(addr, big, 3);
+  vld1q_lane_s64(addr, big, 1);
+
+  vld1_lane_s8(addr, small, 8); // expected-error {{argument should be a value from 0 to 7}}
+  vld1_lane_s16(addr, small, 4); // expected-error {{argument should be a value from 0 to 3}}
+  vld1_lane_s32(addr, small, 2); // expected-error {{argument should be a value from 0 to 1}}
+  vld1_lane_s64(addr, small, 1); // expected-error {{argument should be a value from 0 to 0}}
+
+  vld1q_lane_s8(addr, big, 16); // expected-error {{argument should be a value from 0 to 15}}
+  vld1q_lane_s16(addr, big, 8); // expected-error {{argument should be a value from 0 to 7}}
+  vld1q_lane_s32(addr, big, 4); // expected-error {{argument should be a value from 0 to 3}}
+  vld1q_lane_s64(addr, big, 2); // expected-error {{argument should be a value from 0 to 1}}
+
+  vst1_lane_s8(addr, small, 7);
+  vst1_lane_s16(addr, small, 3);
+  vst1_lane_s32(addr, small, 1);
+  vst1_lane_s64(addr, small, 0);
+
+  vst1q_lane_s8(addr, big, 15);
+  vst1q_lane_s16(addr, big, 7);
+  vst1q_lane_s32(addr, big, 3);
+  vst1q_lane_s64(addr, big, 1);
+
+  vst1_lane_s8(addr, small, 8); // expected-error {{argument should be a value from 0 to 7}}
+  vst1_lane_s16(addr, small, 4); // expected-error {{argument should be a value from 0 to 3}}
+  vst1_lane_s32(addr, small, 2); // expected-error {{argument should be a value from 0 to 1}}
+  vst1_lane_s64(addr, small, 1); // expected-error {{argument should be a value from 0 to 0}}
+
+  vst1q_lane_s8(addr, big, 16); // expected-error {{argument should be a value from 0 to 15}}
+  vst1q_lane_s16(addr, big, 8); // expected-error {{argument should be a value from 0 to 7}}
+  vst1q_lane_s32(addr, big, 4); // expected-error {{argument should be a value from 0 to 3}}
+  vst1q_lane_s64(addr, big, 2); // expected-error {{argument should be a value from 0 to 1}}
+}
+
+void test_ld2st2(int8x8x2_t small8, int8x16x2_t big8,
+                 int16x4x2_t small16, int16x8x2_t big16,
+                 int32x2x2_t small32, int32x4x2_t big32,
+                 int64x1x2_t small64, int64x2x2_t big64,
+                 void *addr) {
+  vld2_lane_s8(addr, small8, 7);
+  vld2_lane_s16(addr, small16, 3);
+  vld2_lane_s32(addr, small32, 1);
+  vld2_lane_s64(addr, small64, 0);
+
+  vld2q_lane_s8(addr, big8, 15);
+  vld2q_lane_s16(addr, big16, 7);
+  vld2q_lane_s32(addr, big32, 3);
+  vld2q_lane_s64(addr, big64, 1);
+
+  vld2_lane_s8(addr, small8, 8); // expected-error {{argument should be a value from 0 to 7}}
+  vld2_lane_s16(addr, small16, 4); // expected-error {{argument should be a value from 0 to 3}}
+  vld2_lane_s32(addr, small32, 2); // expected-error {{argument should be a value from 0 to 1}}
+  vld2_lane_s64(addr, small64, 1); // expected-error {{argument should be a value from 0 to 0}}
+
+  vld2q_lane_s8(addr, big8, 16); // expected-error {{argument should be a value from 0 to 15}}
+  vld2q_lane_s16(addr, big16, 8); // expected-error {{argument should be a value from 0 to 7}}
+  vld2q_lane_s32(addr, big32, 4); // expected-error {{argument should be a value from 0 to 3}}
+  vld2q_lane_s64(addr, big64, 2); // expected-error {{argument should be a value from 0 to 1}}
+
+  vst2_lane_s8(addr, small8, 7);
+  vst2_lane_s16(addr, small16, 3);
+  vst2_lane_s32(addr, small32, 1);
+  vst2_lane_s64(addr, small64, 0);
+
+  vst2q_lane_s8(addr, big8, 15);
+  vst2q_lane_s16(addr, big16, 7);
+  vst2q_lane_s32(addr, big32, 3);
+  vst2q_lane_s64(addr, big64, 1);
+
+  vst2_lane_s8(addr, small8, 8); // expected-error {{argument should be a value from 0 to 7}}
+  vst2_lane_s16(addr, small16, 4); // expected-error {{argument should be a value from 0 to 3}}
+  vst2_lane_s32(addr, small32, 2); // expected-error {{argument should be a value from 0 to 1}}
+  vst2_lane_s64(addr, small64, 1); // expected-error {{argument should be a value from 0 to 0}}
+
+  vst2q_lane_s8(addr, big8, 16); // expected-error {{argument should be a value from 0 to 15}}
+  vst2q_lane_s16(addr, big16, 8); // expected-error {{argument should be a value from 0 to 7}}
+  vst2q_lane_s32(addr, big32, 4); // expected-error {{argument should be a value from 0 to 3}}
+  vst2q_lane_s64(addr, big64, 2); // expected-error {{argument should be a value from 0 to 1}}
+}
+
+void test_ld3st3(int8x8x3_t small8, int8x16x3_t big8,
+                 int16x4x3_t small16, int16x8x3_t big16,
+                 int32x2x3_t small32, int32x4x3_t big32,
+                 int64x1x3_t small64, int64x2x3_t big64,
+                 void *addr) {
+  vld3_lane_s8(addr, small8, 7);
+  vld3_lane_s16(addr, small16, 3);
+  vld3_lane_s32(addr, small32, 1);
+  vld3_lane_s64(addr, small64, 0);
+
+  vld3q_lane_s8(addr, big8, 15);
+  vld3q_lane_s16(addr, big16, 7);
+  vld3q_lane_s32(addr, big32, 3);
+  vld3q_lane_s64(addr, big64, 1);
+
+  vld3_lane_s8(addr, small8, 8); // expected-error {{argument should be a value from 0 to 7}}
+  vld3_lane_s16(addr, small16, 4); // expected-error {{argument should be a value from 0 to 3}}
+  vld3_lane_s32(addr, small32, 2); // expected-error {{argument should be a value from 0 to 1}}
+  vld3_lane_s64(addr, small64, 1); // expected-error {{argument should be a value from 0 to 0}}
+
+  vld3q_lane_s8(addr, big8, 16); // expected-error {{argument should be a value from 0 to 15}}
+  vld3q_lane_s16(addr, big16, 8); // expected-error {{argument should be a value from 0 to 7}}
+  vld3q_lane_s32(addr, big32, 4); // expected-error {{argument should be a value from 0 to 3}}
+  vld3q_lane_s64(addr, big64, 2); // expected-error {{argument should be a value from 0 to 1}}
+
+  vst3_lane_s8(addr, small8, 7);
+  vst3_lane_s16(addr, small16, 3);
+  vst3_lane_s32(addr, small32, 1);
+  vst3_lane_s64(addr, small64, 0);
+
+  vst3q_lane_s8(addr, big8, 15);
+  vst3q_lane_s16(addr, big16, 7);
+  vst3q_lane_s32(addr, big32, 3);
+  vst3q_lane_s64(addr, big64, 1);
+
+  vst3_lane_s8(addr, small8, 8); // expected-error {{argument should be a value from 0 to 7}}
+  vst3_lane_s16(addr, small16, 4); // expected-error {{argument should be a value from 0 to 3}}
+  vst3_lane_s32(addr, small32, 2); // expected-error {{argument should be a value from 0 to 1}}
+  vst3_lane_s64(addr, small64, 1); // expected-error {{argument should be a value from 0 to 0}}
+
+  vst3q_lane_s8(addr, big8, 16); // expected-error {{argument should be a value from 0 to 15}}
+  vst3q_lane_s16(addr, big16, 8); // expected-error {{argument should be a value from 0 to 7}}
+  vst3q_lane_s32(addr, big32, 4); // expected-error {{argument should be a value from 0 to 3}}
+  vst3q_lane_s64(addr, big64, 2); // expected-error {{argument should be a value from 0 to 1}}
+}
+
+void test_ld4st4(int8x8x4_t small8, int8x16x4_t big8,
+                 int16x4x4_t small16, int16x8x4_t big16,
+                 int32x2x4_t small32, int32x4x4_t big32,
+                 int64x1x4_t small64, int64x2x4_t big64,
+                 void *addr) {
+  vld4_lane_s8(addr, small8, 7);
+  vld4_lane_s16(addr, small16, 3);
+  vld4_lane_s32(addr, small32, 1);
+  vld4_lane_s64(addr, small64, 0);
+
+  vld4q_lane_s8(addr, big8, 15);
+  vld4q_lane_s16(addr, big16, 7);
+  vld4q_lane_s32(addr, big32, 3);
+  vld4q_lane_s64(addr, big64, 1);
+
+  vld4_lane_s8(addr, small8, 8); // expected-error {{argument should be a value from 0 to 7}}
+  vld4_lane_s16(addr, small16, 4); // expected-error {{argument should be a value from 0 to 3}}
+  vld4_lane_s32(addr, small32, 2); // expected-error {{argument should be a value from 0 to 1}}
+  vld4_lane_s64(addr, small64, 1); // expected-error {{argument should be a value from 0 to 0}}
+
+  vld4q_lane_s8(addr, big8, 16); // expected-error {{argument should be a value from 0 to 15}}
+  vld4q_lane_s16(addr, big16, 8); // expected-error {{argument should be a value from 0 to 7}}
+  vld4q_lane_s32(addr, big32, 4); // expected-error {{argument should be a value from 0 to 3}}
+  vld4q_lane_s64(addr, big64, 2); // expected-error {{argument should be a value from 0 to 1}}
+
+  vst4_lane_s8(addr, small8, 7);
+  vst4_lane_s16(addr, small16, 3);
+  vst4_lane_s32(addr, small32, 1);
+  vst4_lane_s64(addr, small64, 0);
+
+  vst4q_lane_s8(addr, big8, 15);
+  vst4q_lane_s16(addr, big16, 7);
+  vst4q_lane_s32(addr, big32, 3);
+  vst4q_lane_s64(addr, big64, 1);
+
+  vst4_lane_s8(addr, small8, 8); // expected-error {{argument should be a value from 0 to 7}}
+  vst4_lane_s16(addr, small16, 4); // expected-error {{argument should be a value from 0 to 3}}
+  vst4_lane_s32(addr, small32, 2); // expected-error {{argument should be a value from 0 to 1}}
+  vst4_lane_s64(addr, small64, 1); // expected-error {{argument should be a value from 0 to 0}}
+
+  vst4q_lane_s8(addr, big8, 16); // expected-error {{argument should be a value from 0 to 15}}
+  vst4q_lane_s16(addr, big16, 8); // expected-error {{argument should be a value from 0 to 7}}
+  vst4q_lane_s32(addr, big32, 4); // expected-error {{argument should be a value from 0 to 3}}
+  vst4q_lane_s64(addr, big64, 2); // expected-error {{argument should be a value from 0 to 1}}
+}
+
diff --git a/test/Sema/aarch64-neon-vector-types.c b/test/Sema/aarch64-neon-vector-types.c
index 894cf6d..4cc1e2c 100644
--- a/test/Sema/aarch64-neon-vector-types.c
+++ b/test/Sema/aarch64-neon-vector-types.c
@@ -1,19 +1,36 @@
 // RUN: %clang_cc1 %s -triple aarch64-none-linux-gnu -target-feature +neon -fsyntax-only -verify
+// RUN: %clang_cc1 %s -triple aarch64-none-linux-gnu -target-feature +neon -DUSE_LONG -fsyntax-only -verify
+// RUN: %clang_cc1 %s -triple arm64-none-linux-gnu -target-feature +neon -fsyntax-only -verify
+// RUN: %clang_cc1 %s -triple arm64-none-linux-gnu -target-feature +neon -DUSE_LONG -fsyntax-only -verify
 
 typedef float float32_t;
 typedef unsigned char poly8_t;
 typedef unsigned short poly16_t;
+
+// Both "long" and "long long" should work for 64-bit arch like aarch64.
+// stdint.h in gnu libc is using "long" for 64-bit arch.
+#if USE_LONG
+typedef long int64_t;
+typedef unsigned long uint64_t;
+#else
+typedef long long int64_t;
 typedef unsigned long long uint64_t;
+#endif
+typedef uint64_t poly64_t;
 
 // Define some valid Neon types.
 typedef __attribute__((neon_vector_type(2))) int int32x2_t;
 typedef __attribute__((neon_vector_type(4))) int int32x4_t;
+typedef __attribute__((neon_vector_type(1))) int64_t int64x1_t;
+typedef __attribute__((neon_vector_type(2))) int64_t int64x2_t;
 typedef __attribute__((neon_vector_type(1))) uint64_t uint64x1_t;
 typedef __attribute__((neon_vector_type(2))) uint64_t uint64x2_t;
 typedef __attribute__((neon_vector_type(2))) float32_t float32x2_t;
 typedef __attribute__((neon_vector_type(4))) float32_t float32x4_t;
 typedef __attribute__((neon_polyvector_type(16))) poly8_t  poly8x16_t;
 typedef __attribute__((neon_polyvector_type(8)))  poly16_t poly16x8_t;
+typedef __attribute__((neon_polyvector_type(1)))  poly64_t poly64x1_t;
+typedef __attribute__((neon_polyvector_type(2)))  poly64_t poly64x2_t;
 
 // The attributes must have a single argument.
 typedef __attribute__((neon_vector_type(2, 4))) int only_one_arg; // expected-error{{attribute takes one argument}}
diff --git a/test/Sema/align-x86.c b/test/Sema/align-x86.c
index 6b93a48..f112c63 100644
--- a/test/Sema/align-x86.c
+++ b/test/Sema/align-x86.c
@@ -23,6 +23,10 @@
 short chk1[__alignof__(g4) == 1 ? 1 : -1];
 short chk2[__alignof__(g4.a) == 1 ? 1 : -1];
 
+double g6[3];
+short chk1[__alignof__(g6) == 8 ? 1 : -1];
+short chk2[__alignof__(double[3]) == 8 ? 1 : -1];
+
 
 // PR5637
 
diff --git a/test/Sema/alloc_size.c b/test/Sema/alloc_size.c
deleted file mode 100644
index 053323a..0000000
--- a/test/Sema/alloc_size.c
+++ /dev/null
@@ -1,27 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-
-void* my_malloc(unsigned char) __attribute__((alloc_size(1)));
-void* my_calloc(unsigned char, short) __attribute__((alloc_size(1,2)));
-void* my_realloc(void*, unsigned) __attribute__((alloc_size(2)));
-
-
-void* fn1(int) __attribute__((alloc_size("xpto"))); // expected-error{{'alloc_size' attribute requires parameter 1 to be an integer constant}}
-
-void* fn2(void*) __attribute__((alloc_size(1))); // expected-error{{'alloc_size' attribute requires an integer constant}}
-
-void* fn3(unsigned) __attribute__((alloc_size(0))); // expected-error{{attribute parameter 1 is out of bounds}}
-void* fn4(unsigned) __attribute__((alloc_size(2))); // expected-error{{attribute parameter 1 is out of bounds}}
-
-void fn5(unsigned) __attribute__((alloc_size(1))); // expected-warning{{only applies to functions that return a pointer}}
-char fn6(unsigned) __attribute__((alloc_size(1))); // expected-warning{{only applies to functions that return a pointer}}
-
-void* fn7(unsigned) __attribute__((alloc_size)); // expected-error {{attribute takes at least 1 argument}}
-
-void *fn8(int, int) __attribute__((alloc_size(1, 1))); // OK
-
-void* fn9(unsigned) __attribute__((alloc_size(12345678901234567890123))); // expected-error {{integer constant is larger than the largest unsigned integer type}} // expected-error {{attribute parameter 1 is out of bounds}}
-
-void* fn10(size_t, size_t) __attribute__((alloc_size(1,2))); // expected-error{{redefinition of parameter}} \
-                                                             // expected-error{{a parameter list without types is only allowed in a function definition}} \
-                                                             // expected-error{{attribute parameter 1 is out of bounds}}
-void* fn11() __attribute__((alloc_size(1))); // expected-error{{attribute parameter 1 is out of bounds}}
diff --git a/test/Sema/arm-asm.c b/test/Sema/arm-asm.c
index 3fc0eeb..e48718b 100644
--- a/test/Sema/arm-asm.c
+++ b/test/Sema/arm-asm.c
@@ -5,3 +5,8 @@
   asm volatile ("lw (r1), %0[val]": "=&b"(Val)); // expected-error {{invalid output constraint '=&b' in asm}}
   return;
 }
+
+void test_64bit_r(void) {
+  long long foo = 0, bar = 0;
+  asm volatile("INST %0, %1" : "=r"(foo) : "r"(bar));
+}
diff --git a/test/Sema/arm-interrupt-attr.c b/test/Sema/arm-interrupt-attr.c
index b2cedc2..e8f21ad 100644
--- a/test/Sema/arm-interrupt-attr.c
+++ b/test/Sema/arm-interrupt-attr.c
@@ -1,9 +1,9 @@
 // RUN: %clang_cc1 %s -triple arm-apple-darwin -verify -fsyntax-only
 
-__attribute__((interrupt(IRQ))) void foo() {} // expected-error {{'interrupt' attribute requires a string}} 
+__attribute__((interrupt(IRQ))) void foo() {} // expected-error {{'interrupt' attribute requires a string}}
 __attribute__((interrupt("irq"))) void foo1() {} // expected-warning {{'interrupt' attribute argument not supported: irq}}
 
-__attribute__((interrupt("IRQ", 1))) void foo2() {} // expected-error {{attribute takes no more than 1 argument}}
+__attribute__((interrupt("IRQ", 1))) void foo2() {} // expected-error {{'interrupt' attribute takes no more than 1 argument}}
 
 __attribute__((interrupt("IRQ"))) void foo3() {}
 __attribute__((interrupt("FIQ"))) void foo4() {}
diff --git a/test/Sema/arm-neon-types.c b/test/Sema/arm-neon-types.c
index a49de12..a5ee708 100644
--- a/test/Sema/arm-neon-types.c
+++ b/test/Sema/arm-neon-types.c
@@ -17,7 +17,7 @@
 float32x2_t test3(uint32x2_t x) {
   // FIXME: The "incompatible result type" error is due to pr10112 and should be
   // removed when that is fixed.
-  return vcvt_n_f32_u32(x, 0); // expected-error {{argument should be a value from 1 to 32}} expected-error {{incompatible result type}}
+  return vcvt_n_f32_u32(x, 0); // expected-error {{argument should be a value from 1 to 32}}
 }
 
 typedef signed int vSInt32 __attribute__((__vector_size__(16)));
diff --git a/test/Sema/arm64-inline-asm.c b/test/Sema/arm64-inline-asm.c
new file mode 100644
index 0000000..08eb669
--- /dev/null
+++ b/test/Sema/arm64-inline-asm.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple arm64-apple-ios7.1 -fsyntax-only -verify %s
+// expected-no-diagnostics
+
+void foo() {
+  asm volatile("USE(%0)" :: "z"(0LL));
+  asm volatile("USE(%x0)" :: "z"(0LL));
+  asm volatile("USE(%w0)" :: "z"(0));
+
+}
diff --git a/test/Sema/arm64-neon-args.c b/test/Sema/arm64-neon-args.c
new file mode 100644
index 0000000..315a704
--- /dev/null
+++ b/test/Sema/arm64-neon-args.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -triple arm64-apple-darwin -target-feature +neon -fsyntax-only -ffreestanding -verify %s
+// RUN: %clang_cc1 -triple arm64_be-none-linux-gnu -target-feature +neon -fsyntax-only -ffreestanding -verify %s
+
+#include <arm_neon.h>
+
+// rdar://13527900
+void vcopy_reject(float32x4_t vOut0, float32x4_t vAlpha, int t) {
+  vcopyq_laneq_f32(vOut0, 1, vAlpha, t); // expected-error {{argument to '__builtin_neon_vgetq_lane_f32' must be a constant integer}}
+}
+
+// rdar://problem/15256199
+float32x4_t test_vmlsq_lane(float32x4_t accum, float32x4_t lhs, float32x2_t rhs) {
+  return vmlsq_lane_f32(accum, lhs, rhs, 1);
+}
diff --git a/test/Sema/arm_acle.c b/test/Sema/arm_acle.c
new file mode 100644
index 0000000..866626f
--- /dev/null
+++ b/test/Sema/arm_acle.c
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -triple armv8 -target-cpu cortex-a57 -fsyntax-only -ffreestanding -verify %s
+
+#include <arm_acle.h>
+/*
+ * Memory barrier intrinsics
+ * Argument for dmb, dsb, isb must be compile-time constant,
+ * otherwise an error should be raised.
+ */
+void test_dmb_const_diag(const unsigned int t) {
+  return __dmb(t);  // expected-error-re {{argument to {{.*}} must be a constant integer}}
+}
+
+void test_dsb_const_diag(const unsigned int t) {
+  return __dsb(t);  // expected-error-re {{argument to {{.*}} must be a constant integer}}
+}
+
+void test_isb_const_diag(const unsigned int t) {
+  return __isb(t);  // expected-error-re {{argument to {{.*}} must be a constant integer}}
+}
+
+/*
+ * Saturating intrinsics
+ * Second argument for SSAT and USAT intrinsics must be compile-time constant,
+ * otherwise an error should be raised.
+ */
+int32_t test_ssat_const_diag(int32_t t, const int32_t v) {
+  return __ssat(t, v);  // expected-error-re {{argument to {{.*}} must be a constant integer}}
+}
+
+int32_t test_usat_const_diag(int32_t t, const int32_t v) {
+  return __usat(t, v);  // expected-error-re {{argument to {{.*}} must be a constant integer}}
+}
diff --git a/test/Sema/array-init.c b/test/Sema/array-init.c
index ae2c742..4cc5e41 100644
--- a/test/Sema/array-init.c
+++ b/test/Sema/array-init.c
@@ -282,7 +282,12 @@
 int a6[5] = (int[]){1, 2, 3}; // expected-error{{cannot initialize array of type 'int [5]' with array of type 'int [3]'}}
 
 int nonconst_value();
-int a7[5] = (int[5]){ 1, 2, 3, 4, nonconst_value() }; // expected-error{{initializer element is not a compile-time constant}}
+int a7[5] = (int[5]){ 1,
+                      2,
+                      3,
+                      4,
+                      nonconst_value() // expected-error{{initializer element is not a compile-time constant}}
+};
 
 // <rdar://problem/10636946>
 __attribute__((weak)) const unsigned int test10_bound = 10;
diff --git a/test/Sema/asm.c b/test/Sema/asm.c
index c81f16a..89c8c57 100644
--- a/test/Sema/asm.c
+++ b/test/Sema/asm.c
@@ -1,5 +1,7 @@
 // RUN: %clang_cc1 %s -Wno-private-extern -triple i386-pc-linux-gnu -verify -fsyntax-only
 
+
+
 void f() {
   int i;
 
@@ -13,6 +15,9 @@
   asm ("foo\n" : "=a" (i) : "[" (i)); // expected-error {{invalid input constraint '[' in asm}}
   asm ("foo\n" : "=a" (i) : "[foo" (i)); // expected-error {{invalid input constraint '[foo' in asm}}
   asm ("foo\n" : "=a" (i) : "[symbolic_name]" (i)); // expected-error {{invalid input constraint '[symbolic_name]' in asm}}
+
+  asm ("foo\n" : : "" (i)); // expected-error {{invalid input constraint '' in asm}}
+  asm ("foo\n" : "=a" (i) : "" (i)); // expected-error {{invalid input constraint '' in asm}}
 }
 
 void clobbers() {
@@ -92,8 +97,6 @@
   asm("" : [foo] "=r" (i), "=r"(i) : "[foo]1"(i)); // expected-error{{invalid input constraint '[foo]1' in asm}}
 }
 
-register int g asm("dx"); // expected-error{{global register variables are not supported}}
-
 void test10(void){
   static int g asm ("g_asm") = 0;
   extern int gg asm ("gg_asm");
@@ -146,3 +149,17 @@
   __asm("0.0":"=g"(ret)); // no-error
   return ret;
 }
+
+// PR19837
+struct foo {
+  int a;
+  char b;
+};
+register struct foo bar asm("sp"); // expected-error {{bad type for named register variable}}
+register float baz asm("sp"); // expected-error {{bad type for named register variable}}
+
+double f_output_constraint(void) {
+  double result;
+  __asm("foo1": "=f" (result)); // expected-error {{invalid output constraint '=f' in asm}}
+  return result;
+}
diff --git a/test/Sema/ast-print.c b/test/Sema/ast-print.c
index 2066e18..382f0d3 100644
--- a/test/Sema/ast-print.c
+++ b/test/Sema/ast-print.c
@@ -18,3 +18,24 @@
   // CHECK: return b->b;
   return b->b;
 }
+
+int arr(int a[static 3]) {
+  // CHECK: int a[static 3]
+  return a[2];
+}
+
+int rarr(int a[restrict static 3]) {
+  // CHECK: int a[restrict static 3]
+  return a[2];
+}
+
+int varr(int n, int a[static n]) {
+  // CHECK: int a[static n]
+  return a[2];
+}
+
+int rvarr(int n, int a[restrict static n]) {
+  // CHECK: int a[restrict static n]
+  return a[2];
+}
+
diff --git a/test/Sema/atomic-compare.c b/test/Sema/atomic-compare.c
new file mode 100644
index 0000000..2eed091
--- /dev/null
+++ b/test/Sema/atomic-compare.c
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+void f(_Atomic(int) a, _Atomic(int) b) {
+  if (a > b)      {} // no warning
+  if (a < b)      {} // no warning
+  if (a >= b)     {} // no warning
+  if (a <= b)     {} // no warning
+  if (a == b)     {} // no warning
+  if (a != b)     {} // no warning
+
+  if (a == 0) {} // no warning
+  if (a > 0) {} // no warning
+  if (a > 1) {} // no warning
+  if (a > 2) {} // no warning
+
+  if (!a > 0) {}  // no warning
+  if (!a > 1)     {} // expected-warning {{comparison of constant 1 with boolean expression is always false}}
+  if (!a > 2)     {} // expected-warning {{comparison of constant 2 with boolean expression is always false}}
+  if (!a > b)     {} // no warning
+  if (!a > -1)    {} // expected-warning {{comparison of constant -1 with boolean expression is always true}}
+}
diff --git a/test/Sema/atomic-expr.c b/test/Sema/atomic-expr.c
index 5602d54..997ee90 100644
--- a/test/Sema/atomic-expr.c
+++ b/test/Sema/atomic-expr.c
@@ -58,3 +58,6 @@
   return x ? data1 : y;
 }
 
+int func_14 () {
+  return data1 == 0;
+}
diff --git a/test/Sema/atomic-ops.c b/test/Sema/atomic-ops.c
index c2d38e7..320abc5 100644
--- a/test/Sema/atomic-ops.c
+++ b/test/Sema/atomic-ops.c
@@ -1,5 +1,4 @@
 // RUN: %clang_cc1 %s -verify -fsyntax-only -triple=i686-linux-gnu -std=c11
-// RUN: %clang_cc1 %s -verify -fsyntax-only -triple=aarch64-linux-gnu -std=c11
 
 // Basic parsing/Sema tests for __c11_atomic_*
 
@@ -182,3 +181,225 @@
   flag flagvar = { 0 };
   PR16931(&flagvar); // expected-warning {{incompatible pointer types}}
 }
+
+void memory_checks(_Atomic(int) *Ap, int *p, int val) {
+  (void)__c11_atomic_load(Ap, memory_order_relaxed);
+  (void)__c11_atomic_load(Ap, memory_order_acquire);
+  (void)__c11_atomic_load(Ap, memory_order_consume);
+  (void)__c11_atomic_load(Ap, memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}}
+  (void)__c11_atomic_load(Ap, memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
+  (void)__c11_atomic_load(Ap, memory_order_seq_cst);
+  (void)__c11_atomic_load(Ap, val);
+  (void)__c11_atomic_load(Ap, -1); // expected-warning {{memory order argument to atomic operation is invalid}}
+  (void)__c11_atomic_load(Ap, 42); // expected-warning {{memory order argument to atomic operation is invalid}}
+
+  (void)__c11_atomic_store(Ap, val, memory_order_relaxed);
+  (void)__c11_atomic_store(Ap, val, memory_order_acquire); // expected-warning {{memory order argument to atomic operation is invalid}}
+  (void)__c11_atomic_store(Ap, val, memory_order_consume); // expected-warning {{memory order argument to atomic operation is invalid}}
+  (void)__c11_atomic_store(Ap, val, memory_order_release);
+  (void)__c11_atomic_store(Ap, val, memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
+  (void)__c11_atomic_store(Ap, val, memory_order_seq_cst);
+
+  (void)__c11_atomic_fetch_add(Ap, 1, memory_order_relaxed);
+  (void)__c11_atomic_fetch_add(Ap, 1, memory_order_acquire);
+  (void)__c11_atomic_fetch_add(Ap, 1, memory_order_consume);
+  (void)__c11_atomic_fetch_add(Ap, 1, memory_order_release);
+  (void)__c11_atomic_fetch_add(Ap, 1, memory_order_acq_rel);
+  (void)__c11_atomic_fetch_add(Ap, 1, memory_order_seq_cst);
+
+  (void)__c11_atomic_init(Ap, val);
+  (void)__c11_atomic_init(Ap, val);
+  (void)__c11_atomic_init(Ap, val);
+  (void)__c11_atomic_init(Ap, val);
+  (void)__c11_atomic_init(Ap, val);
+  (void)__c11_atomic_init(Ap, val);
+
+  (void)__c11_atomic_fetch_sub(Ap, val, memory_order_relaxed);
+  (void)__c11_atomic_fetch_sub(Ap, val, memory_order_acquire);
+  (void)__c11_atomic_fetch_sub(Ap, val, memory_order_consume);
+  (void)__c11_atomic_fetch_sub(Ap, val, memory_order_release);
+  (void)__c11_atomic_fetch_sub(Ap, val, memory_order_acq_rel);
+  (void)__c11_atomic_fetch_sub(Ap, val, memory_order_seq_cst);
+
+  (void)__c11_atomic_fetch_and(Ap, val, memory_order_relaxed);
+  (void)__c11_atomic_fetch_and(Ap, val, memory_order_acquire);
+  (void)__c11_atomic_fetch_and(Ap, val, memory_order_consume);
+  (void)__c11_atomic_fetch_and(Ap, val, memory_order_release);
+  (void)__c11_atomic_fetch_and(Ap, val, memory_order_acq_rel);
+  (void)__c11_atomic_fetch_and(Ap, val, memory_order_seq_cst);
+
+  (void)__c11_atomic_fetch_or(Ap, val, memory_order_relaxed);
+  (void)__c11_atomic_fetch_or(Ap, val, memory_order_acquire);
+  (void)__c11_atomic_fetch_or(Ap, val, memory_order_consume);
+  (void)__c11_atomic_fetch_or(Ap, val, memory_order_release);
+  (void)__c11_atomic_fetch_or(Ap, val, memory_order_acq_rel);
+  (void)__c11_atomic_fetch_or(Ap, val, memory_order_seq_cst);
+
+  (void)__c11_atomic_fetch_xor(Ap, val, memory_order_relaxed);
+  (void)__c11_atomic_fetch_xor(Ap, val, memory_order_acquire);
+  (void)__c11_atomic_fetch_xor(Ap, val, memory_order_consume);
+  (void)__c11_atomic_fetch_xor(Ap, val, memory_order_release);
+  (void)__c11_atomic_fetch_xor(Ap, val, memory_order_acq_rel);
+  (void)__c11_atomic_fetch_xor(Ap, val, memory_order_seq_cst);
+
+  (void)__c11_atomic_exchange(Ap, val, memory_order_relaxed);
+  (void)__c11_atomic_exchange(Ap, val, memory_order_acquire);
+  (void)__c11_atomic_exchange(Ap, val, memory_order_consume);
+  (void)__c11_atomic_exchange(Ap, val, memory_order_release);
+  (void)__c11_atomic_exchange(Ap, val, memory_order_acq_rel);
+  (void)__c11_atomic_exchange(Ap, val, memory_order_seq_cst);
+
+  (void)__c11_atomic_compare_exchange_strong(Ap, p, val, memory_order_relaxed, memory_order_relaxed);
+  (void)__c11_atomic_compare_exchange_strong(Ap, p, val, memory_order_acquire, memory_order_relaxed);
+  (void)__c11_atomic_compare_exchange_strong(Ap, p, val, memory_order_consume, memory_order_relaxed);
+  (void)__c11_atomic_compare_exchange_strong(Ap, p, val, memory_order_release, memory_order_relaxed);
+  (void)__c11_atomic_compare_exchange_strong(Ap, p, val, memory_order_acq_rel, memory_order_relaxed);
+  (void)__c11_atomic_compare_exchange_strong(Ap, p, val, memory_order_seq_cst, memory_order_relaxed);
+
+  (void)__c11_atomic_compare_exchange_weak(Ap, p, val, memory_order_relaxed, memory_order_relaxed);
+  (void)__c11_atomic_compare_exchange_weak(Ap, p, val, memory_order_acquire, memory_order_relaxed);
+  (void)__c11_atomic_compare_exchange_weak(Ap, p, val, memory_order_consume, memory_order_relaxed);
+  (void)__c11_atomic_compare_exchange_weak(Ap, p, val, memory_order_release, memory_order_relaxed);
+  (void)__c11_atomic_compare_exchange_weak(Ap, p, val, memory_order_acq_rel, memory_order_relaxed);
+  (void)__c11_atomic_compare_exchange_weak(Ap, p, val, memory_order_seq_cst, memory_order_relaxed);
+
+  (void)__atomic_load_n(p, memory_order_relaxed);
+  (void)__atomic_load_n(p, memory_order_acquire);
+  (void)__atomic_load_n(p, memory_order_consume);
+  (void)__atomic_load_n(p, memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}}
+  (void)__atomic_load_n(p, memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
+  (void)__atomic_load_n(p, memory_order_seq_cst);
+
+  (void)__atomic_load(p, p, memory_order_relaxed);
+  (void)__atomic_load(p, p, memory_order_acquire);
+  (void)__atomic_load(p, p, memory_order_consume);
+  (void)__atomic_load(p, p, memory_order_release); // expected-warning {{memory order argument to atomic operation is invalid}}
+  (void)__atomic_load(p, p, memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
+  (void)__atomic_load(p, p, memory_order_seq_cst);
+
+  (void)__atomic_store(p, p, memory_order_relaxed);
+  (void)__atomic_store(p, p, memory_order_acquire); // expected-warning {{memory order argument to atomic operation is invalid}}
+  (void)__atomic_store(p, p, memory_order_consume); // expected-warning {{memory order argument to atomic operation is invalid}}
+  (void)__atomic_store(p, p, memory_order_release);
+  (void)__atomic_store(p, p, memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
+  (void)__atomic_store(p, p, memory_order_seq_cst);
+
+  (void)__atomic_store_n(p, val, memory_order_relaxed);
+  (void)__atomic_store_n(p, val, memory_order_acquire); // expected-warning {{memory order argument to atomic operation is invalid}}
+  (void)__atomic_store_n(p, val, memory_order_consume); // expected-warning {{memory order argument to atomic operation is invalid}}
+  (void)__atomic_store_n(p, val, memory_order_release);
+  (void)__atomic_store_n(p, val, memory_order_acq_rel); // expected-warning {{memory order argument to atomic operation is invalid}}
+  (void)__atomic_store_n(p, val, memory_order_seq_cst);
+
+  (void)__atomic_fetch_add(p, val, memory_order_relaxed);
+  (void)__atomic_fetch_add(p, val, memory_order_acquire);
+  (void)__atomic_fetch_add(p, val, memory_order_consume);
+  (void)__atomic_fetch_add(p, val, memory_order_release);
+  (void)__atomic_fetch_add(p, val, memory_order_acq_rel);
+  (void)__atomic_fetch_add(p, val, memory_order_seq_cst);
+
+  (void)__atomic_fetch_sub(p, val, memory_order_relaxed);
+  (void)__atomic_fetch_sub(p, val, memory_order_acquire);
+  (void)__atomic_fetch_sub(p, val, memory_order_consume);
+  (void)__atomic_fetch_sub(p, val, memory_order_release);
+  (void)__atomic_fetch_sub(p, val, memory_order_acq_rel);
+  (void)__atomic_fetch_sub(p, val, memory_order_seq_cst);
+
+  (void)__atomic_add_fetch(p, val, memory_order_relaxed);
+  (void)__atomic_add_fetch(p, val, memory_order_acquire);
+  (void)__atomic_add_fetch(p, val, memory_order_consume);
+  (void)__atomic_add_fetch(p, val, memory_order_release);
+  (void)__atomic_add_fetch(p, val, memory_order_acq_rel);
+  (void)__atomic_add_fetch(p, val, memory_order_seq_cst);
+
+  (void)__atomic_sub_fetch(p, val, memory_order_relaxed);
+  (void)__atomic_sub_fetch(p, val, memory_order_acquire);
+  (void)__atomic_sub_fetch(p, val, memory_order_consume);
+  (void)__atomic_sub_fetch(p, val, memory_order_release);
+  (void)__atomic_sub_fetch(p, val, memory_order_acq_rel);
+  (void)__atomic_sub_fetch(p, val, memory_order_seq_cst);
+
+  (void)__atomic_fetch_and(p, val, memory_order_relaxed);
+  (void)__atomic_fetch_and(p, val, memory_order_acquire);
+  (void)__atomic_fetch_and(p, val, memory_order_consume);
+  (void)__atomic_fetch_and(p, val, memory_order_release);
+  (void)__atomic_fetch_and(p, val, memory_order_acq_rel);
+  (void)__atomic_fetch_and(p, val, memory_order_seq_cst);
+
+  (void)__atomic_fetch_or(p, val, memory_order_relaxed);
+  (void)__atomic_fetch_or(p, val, memory_order_acquire);
+  (void)__atomic_fetch_or(p, val, memory_order_consume);
+  (void)__atomic_fetch_or(p, val, memory_order_release);
+  (void)__atomic_fetch_or(p, val, memory_order_acq_rel);
+  (void)__atomic_fetch_or(p, val, memory_order_seq_cst);
+
+  (void)__atomic_fetch_xor(p, val, memory_order_relaxed);
+  (void)__atomic_fetch_xor(p, val, memory_order_acquire);
+  (void)__atomic_fetch_xor(p, val, memory_order_consume);
+  (void)__atomic_fetch_xor(p, val, memory_order_release);
+  (void)__atomic_fetch_xor(p, val, memory_order_acq_rel);
+  (void)__atomic_fetch_xor(p, val, memory_order_seq_cst);
+
+  (void)__atomic_fetch_nand(p, val, memory_order_relaxed);
+  (void)__atomic_fetch_nand(p, val, memory_order_acquire);
+  (void)__atomic_fetch_nand(p, val, memory_order_consume);
+  (void)__atomic_fetch_nand(p, val, memory_order_release);
+  (void)__atomic_fetch_nand(p, val, memory_order_acq_rel);
+  (void)__atomic_fetch_nand(p, val, memory_order_seq_cst);
+
+  (void)__atomic_and_fetch(p, val, memory_order_relaxed);
+  (void)__atomic_and_fetch(p, val, memory_order_acquire);
+  (void)__atomic_and_fetch(p, val, memory_order_consume);
+  (void)__atomic_and_fetch(p, val, memory_order_release);
+  (void)__atomic_and_fetch(p, val, memory_order_acq_rel);
+  (void)__atomic_and_fetch(p, val, memory_order_seq_cst);
+
+  (void)__atomic_or_fetch(p, val, memory_order_relaxed);
+  (void)__atomic_or_fetch(p, val, memory_order_acquire);
+  (void)__atomic_or_fetch(p, val, memory_order_consume);
+  (void)__atomic_or_fetch(p, val, memory_order_release);
+  (void)__atomic_or_fetch(p, val, memory_order_acq_rel);
+  (void)__atomic_or_fetch(p, val, memory_order_seq_cst);
+
+  (void)__atomic_xor_fetch(p, val, memory_order_relaxed);
+  (void)__atomic_xor_fetch(p, val, memory_order_acquire);
+  (void)__atomic_xor_fetch(p, val, memory_order_consume);
+  (void)__atomic_xor_fetch(p, val, memory_order_release);
+  (void)__atomic_xor_fetch(p, val, memory_order_acq_rel);
+  (void)__atomic_xor_fetch(p, val, memory_order_seq_cst);
+
+  (void)__atomic_nand_fetch(p, val, memory_order_relaxed);
+  (void)__atomic_nand_fetch(p, val, memory_order_acquire);
+  (void)__atomic_nand_fetch(p, val, memory_order_consume);
+  (void)__atomic_nand_fetch(p, val, memory_order_release);
+  (void)__atomic_nand_fetch(p, val, memory_order_acq_rel);
+  (void)__atomic_nand_fetch(p, val, memory_order_seq_cst);
+
+  (void)__atomic_exchange_n(p, val, memory_order_relaxed);
+  (void)__atomic_exchange_n(p, val, memory_order_acquire);
+  (void)__atomic_exchange_n(p, val, memory_order_consume);
+  (void)__atomic_exchange_n(p, val, memory_order_release);
+  (void)__atomic_exchange_n(p, val, memory_order_acq_rel);
+  (void)__atomic_exchange_n(p, val, memory_order_seq_cst);
+
+  (void)__atomic_exchange(p, p, p, memory_order_relaxed);
+  (void)__atomic_exchange(p, p, p, memory_order_acquire);
+  (void)__atomic_exchange(p, p, p, memory_order_consume);
+  (void)__atomic_exchange(p, p, p, memory_order_release);
+  (void)__atomic_exchange(p, p, p, memory_order_acq_rel);
+  (void)__atomic_exchange(p, p, p, memory_order_seq_cst);
+
+  (void)__atomic_compare_exchange(p, p, p, 0, memory_order_relaxed, memory_order_relaxed);
+  (void)__atomic_compare_exchange(p, p, p, 0, memory_order_acquire, memory_order_relaxed);
+  (void)__atomic_compare_exchange(p, p, p, 0, memory_order_consume, memory_order_relaxed);
+  (void)__atomic_compare_exchange(p, p, p, 0, memory_order_release, memory_order_relaxed);
+  (void)__atomic_compare_exchange(p, p, p, 0, memory_order_acq_rel, memory_order_relaxed);
+  (void)__atomic_compare_exchange(p, p, p, 0, memory_order_seq_cst, memory_order_relaxed);
+
+  (void)__atomic_compare_exchange_n(p, p, val, 0, memory_order_relaxed, memory_order_relaxed);
+  (void)__atomic_compare_exchange_n(p, p, val, 0, memory_order_acquire, memory_order_relaxed);
+  (void)__atomic_compare_exchange_n(p, p, val, 0, memory_order_consume, memory_order_relaxed);
+  (void)__atomic_compare_exchange_n(p, p, val, 0, memory_order_release, memory_order_relaxed);
+  (void)__atomic_compare_exchange_n(p, p, val, 0, memory_order_acq_rel, memory_order_relaxed);
+  (void)__atomic_compare_exchange_n(p, p, val, 0, memory_order_seq_cst, memory_order_relaxed);
+}
diff --git a/test/Sema/attr-alias-elf.c b/test/Sema/attr-alias-elf.c
index 88bd7b7..f14514d 100644
--- a/test/Sema/attr-alias-elf.c
+++ b/test/Sema/attr-alias-elf.c
@@ -52,3 +52,18 @@
 
 extern int a4 __attribute__((alias("b4"))); // expected-error {{alias must point to a defined variable or function}}
 typedef int b4;
+
+void test2_bar() {}
+void test2_foo() __attribute__((weak, alias("test2_bar")));
+void test2_zed() __attribute__((alias("test2_foo"))); // expected-warning {{alias will always resolve to test2_bar even if weak definition of alias test2_foo is overridden}}
+
+void test3_bar() { }
+void test3_foo() __attribute__((section("test"))); // expected-warning {{alias will not be in section 'test' but in the same section as the aliasee}}
+void test3_foo() __attribute__((alias("test3_bar")));
+
+__attribute__((section("test"))) void test4_bar() { }
+void test4_foo() __attribute__((section("test")));
+void test4_foo() __attribute__((alias("test4_bar")));
+
+int test5_bar = 0;
+extern struct incomplete_type test5_foo __attribute__((alias("test5_bar")));
diff --git a/test/Sema/attr-aligned.c b/test/Sema/attr-aligned.c
index 92f2742..0a2698e 100644
--- a/test/Sema/attr-aligned.c
+++ b/test/Sema/attr-aligned.c
@@ -1,6 +1,7 @@
 // RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -verify %s
 
 int x __attribute__((aligned(3))); // expected-error {{requested alignment is not a power of 2}}
+int y __attribute__((aligned(1 << 29))); // expected-error {{requested alignment must be 268435456 bytes or smaller}}
 
 // PR3254
 short g0[3] __attribute__((aligned));
@@ -20,6 +21,12 @@
 char a2[__alignof__(a) == 1? : -1] = { 0 };
 char a3[sizeof(a) == 1? : -1] = { 0 };
 
+typedef long long __attribute__((aligned(1))) underaligned_longlong;
+char a4[__alignof__(underaligned_longlong) == 1 ?: -1] = {0};
+
+typedef long long __attribute__((aligned(1))) underaligned_complex_longlong;
+char a5[__alignof__(underaligned_complex_longlong) == 1 ?: -1] = {0};
+
 // rdar://problem/8335865
 int b __attribute__((aligned(2)));
 char b1[__alignof__(b) == 2 ?: -1] = {0};
@@ -32,7 +39,18 @@
 char d1[__alignof__(d) == 2 ?: -1] = {0};
 char d2[__alignof__(d.member) == 2 ?: -1] = {0};
 
-struct E { int member __attribute__((align(2))); } __attribute__((packed));
+struct E { int member __attribute__((aligned(2))); } __attribute__((packed));
 struct E e;
 char e1[__alignof__(e) == 2 ?: -1] = {0};
 char e2[__alignof__(e.member) == 2 ?: -1] = {0};
+
+typedef char overaligned_char __attribute__((aligned(16)));
+typedef overaligned_char array_with_overaligned_char[11];
+typedef char array_with_align_attr[11] __attribute__((aligned(16)));
+
+char f0[__alignof__(array_with_overaligned_char) == 16 ? 1 : -1] = { 0 };
+char f1[__alignof__(array_with_align_attr) == 16 ? 1 : -1] = { 0 };
+array_with_overaligned_char F2;
+char f2[__alignof__(F2) == 16 ? 1 : -1] = { 0 };
+array_with_align_attr F3;
+char f3[__alignof__(F3) == 16 ? 1 : -1] = { 0 };
diff --git a/test/Sema/attr-availability-ios.c b/test/Sema/attr-availability-ios.c
index 329068c..6462d58 100644
--- a/test/Sema/attr-availability-ios.c
+++ b/test/Sema/attr-availability-ios.c
@@ -1,14 +1,14 @@
 // RUN: %clang_cc1 "-triple" "x86_64-apple-ios3.0" -fsyntax-only -verify %s
 
-void f0(int) __attribute__((availability(ios,introduced=2.0,deprecated=2.1))); // expected-note {{'f0' declared here}}
+void f0(int) __attribute__((availability(ios,introduced=2.0,deprecated=2.1))); // expected-note {{'f0' has been explicitly marked deprecated here}}
 void f1(int) __attribute__((availability(ios,introduced=2.1)));
-void f2(int) __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{'f2' declared here}}
+void f2(int) __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{'f2' has been explicitly marked deprecated here}}
 void f3(int) __attribute__((availability(ios,introduced=3.0)));
 void f4(int) __attribute__((availability(macosx,introduced=10.1,deprecated=10.3,obsoleted=10.5), availability(ios,introduced=2.0,deprecated=2.1,obsoleted=3.0))); // expected-note{{explicitly marked unavailable}}
 
-void f5(int) __attribute__((availability(ios,introduced=2.0))) __attribute__((availability(ios,deprecated=3.0))); // expected-note {{'f5' declared here}}
+void f5(int) __attribute__((availability(ios,introduced=2.0))) __attribute__((availability(ios,deprecated=3.0))); // expected-note {{'f5' has been explicitly marked deprecated here}}
 void f6(int) __attribute__((availability(ios,deprecated=3.0)));
-void f6(int) __attribute__((availability(ios,introduced=2.0))); // expected-note {{'f6' declared here}}
+void f6(int) __attribute__((availability(ios,introduced=2.0))); // expected-note {{'f6' has been explicitly marked deprecated here}}
 
 void test() {
   f0(0); // expected-warning{{'f0' is deprecated: first deprecated in iOS 2.1}}
diff --git a/test/Sema/attr-availability-macosx.c b/test/Sema/attr-availability-macosx.c
index 468e930..38f149b 100644
--- a/test/Sema/attr-availability-macosx.c
+++ b/test/Sema/attr-availability-macosx.c
@@ -2,10 +2,10 @@
 
 void f0(int) __attribute__((availability(macosx,introduced=10.4,deprecated=10.6)));
 void f1(int) __attribute__((availability(macosx,introduced=10.5)));
-void f2(int) __attribute__((availability(macosx,introduced=10.4,deprecated=10.5))); // expected-note {{'f2' declared here}}
+void f2(int) __attribute__((availability(macosx,introduced=10.4,deprecated=10.5))); // expected-note {{'f2' has been explicitly marked deprecated here}}
 void f3(int) __attribute__((availability(macosx,introduced=10.6)));
 void f4(int) __attribute__((availability(macosx,introduced=10.1,deprecated=10.3,obsoleted=10.5), availability(ios,introduced=2.0,deprecated=3.0))); // expected-note{{explicitly marked unavailable}}
-void f5(int) __attribute__((availability(ios,introduced=3.2), availability(macosx,unavailable))); // expected-note{{function has been explicitly marked unavailable here}}
+void f5(int) __attribute__((availability(ios,introduced=3.2), availability(macosx,unavailable))); // expected-note{{'f5' has been explicitly marked unavailable here}}
 
 void test() {
   f0(0);
diff --git a/test/Sema/attr-availability.c b/test/Sema/attr-availability.c
index ac6a187..b7a8e6e 100644
--- a/test/Sema/attr-availability.c
+++ b/test/Sema/attr-availability.c
@@ -8,10 +8,10 @@
 
 // rdar://10095131
 extern void 
-ATSFontGetName(const char *oName) __attribute__((availability(macosx,introduced=8.0,deprecated=9.0, message="use CTFontCopyFullName"))); // expected-note {{'ATSFontGetName' declared here}}
+ATSFontGetName(const char *oName) __attribute__((availability(macosx,introduced=8.0,deprecated=9.0, message="use CTFontCopyFullName"))); // expected-note {{'ATSFontGetName' has been explicitly marked deprecated here}}
 
 extern void
-ATSFontGetPostScriptName(int flags) __attribute__((availability(macosx,introduced=8.0,obsoleted=9.0, message="use ATSFontGetFullPostScriptName"))); // expected-note {{function has been explicitly marked unavailable here}}
+ATSFontGetPostScriptName(int flags) __attribute__((availability(macosx,introduced=8.0,obsoleted=9.0, message="use ATSFontGetFullPostScriptName"))); // expected-note {{'ATSFontGetPostScriptName' has been explicitly marked unavailable here}}
 
 void test_10095131() {
   ATSFontGetName("Hello"); // expected-warning {{'ATSFontGetName' is deprecated: first deprecated in OS X 9.0 - use CTFontCopyFullName}}
diff --git a/test/Sema/attr-bounded.c b/test/Sema/attr-bounded.c
new file mode 100644
index 0000000..bf71fed
--- /dev/null
+++ b/test/Sema/attr-bounded.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only %s

+// Make sure OpenBSD's bounded extension is accepted.

+

+typedef long ssize_t;

+typedef unsigned long size_t;

+typedef struct FILE FILE;

+

+ssize_t read(int, void *, size_t)

+    __attribute__((__bounded__(__buffer__,2,3)));

+int readlink(const char *, char *, size_t)

+    __attribute__((__bounded__(__string__,2,3)));

+size_t fread(void *, size_t, size_t, FILE *)

+    __attribute__((__bounded__(__size__,1,3,2)));

+char *getwd(char *)

+    __attribute__((__bounded__(__minbytes__,1,1024)));
\ No newline at end of file
diff --git a/test/Sema/attr-capabilities.c b/test/Sema/attr-capabilities.c
new file mode 100644
index 0000000..cdbd2f3
--- /dev/null
+++ b/test/Sema/attr-capabilities.c
@@ -0,0 +1,62 @@
+// RUN: %clang_cc1 -fsyntax-only -Wthread-safety -verify %s
+
+typedef int __attribute__((capability("role"))) ThreadRole;
+struct __attribute__((shared_capability("mutex"))) Mutex {};
+struct NotACapability {};
+
+// Test an invalid capability name
+struct __attribute__((capability("wrong"))) IncorrectName {}; // expected-warning {{invalid capability name 'wrong'; capability name must be 'mutex' or 'role'}}
+
+int Test1 __attribute__((capability("test1")));  // expected-error {{'capability' attribute only applies to structs or typedefs}}
+int Test2 __attribute__((shared_capability("test2"))); // expected-error {{'shared_capability' attribute only applies to structs or typedefs}}
+int Test3 __attribute__((acquire_capability("test3")));  // expected-warning {{'acquire_capability' attribute only applies to functions}}
+int Test4 __attribute__((try_acquire_capability("test4"))); // expected-error {{'try_acquire_capability' attribute only applies to functions}}
+int Test5 __attribute__((release_capability("test5"))); // expected-warning {{'release_capability' attribute only applies to functions}}
+
+struct __attribute__((capability(12))) Test3 {}; // expected-error {{'capability' attribute requires a string}}
+struct __attribute__((shared_capability(Test2))) Test4 {}; // expected-error {{'shared_capability' attribute requires a string}}
+
+struct __attribute__((capability)) Test5 {}; // expected-error {{'capability' attribute takes one argument}}
+struct __attribute__((shared_capability("test1", 12))) Test6 {}; // expected-error {{'shared_capability' attribute takes one argument}}
+
+struct NotACapability BadCapability;
+ThreadRole GUI, Worker;
+void Func1(void) __attribute__((requires_capability(GUI))) {}
+void Func2(void) __attribute__((requires_shared_capability(Worker))) {}
+
+void Func3(void) __attribute__((requires_capability)) {}  // expected-error {{'requires_capability' attribute takes at least 1 argument}}
+void Func4(void) __attribute__((requires_shared_capability)) {}  // expected-error {{'requires_shared_capability' attribute takes at least 1 argument}}
+
+void Func5(void) __attribute__((requires_capability(1))) {}  // expected-warning {{'requires_capability' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
+void Func6(void) __attribute__((requires_shared_capability(BadCapability))) {}  // expected-warning {{'requires_shared_capability' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'struct NotACapability'}}
+
+void Func7(void) __attribute__((assert_capability(GUI))) {}
+void Func8(void) __attribute__((assert_shared_capability(GUI))) {}
+
+void Func9(void) __attribute__((assert_capability())) {} // expected-error {{'assert_capability' attribute takes one argument}}
+void Func10(void) __attribute__((assert_shared_capability())) {} // expected-error {{'assert_shared_capability' attribute takes one argument}}
+
+void Func11(void) __attribute__((acquire_capability(GUI))) {}
+void Func12(void) __attribute__((acquire_shared_capability(GUI))) {}
+
+void Func15(void) __attribute__((release_capability(GUI))) {}
+void Func16(void) __attribute__((release_shared_capability(GUI))) {}
+void Func17(void) __attribute__((release_generic_capability(GUI))) {}
+
+void Func21(void) __attribute__((try_acquire_capability(1))) {}
+void Func22(void) __attribute__((try_acquire_shared_capability(1))) {}
+
+void Func23(void) __attribute__((try_acquire_capability(1, GUI))) {}
+void Func24(void) __attribute__((try_acquire_shared_capability(1, GUI))) {}
+
+void Func25(void) __attribute__((try_acquire_capability())) {} // expected-error {{'try_acquire_capability' attribute takes at least 1 argument}}
+void Func26(void) __attribute__((try_acquire_shared_capability())) {} // expected-error {{'try_acquire_shared_capability' attribute takes at least 1 argument}}
+
+// Test that boolean logic works with capability attributes
+void Func27(void) __attribute__((requires_capability(!GUI)));
+void Func28(void) __attribute__((requires_capability(GUI && Worker)));
+void Func29(void) __attribute__((requires_capability(GUI || Worker)));
+void Func30(void) __attribute__((requires_capability((Worker || Worker) && !GUI)));
+
+int AlsoNotACapability;
+void Func31(void) __attribute__((requires_capability(GUI && AlsoNotACapability))); // expected-warning {{'requires_capability' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
diff --git a/test/Sema/attr-cleanup.c b/test/Sema/attr-cleanup.c
index f5cbc38..26f283a 100644
--- a/test/Sema/attr-cleanup.c
+++ b/test/Sema/attr-cleanup.c
@@ -38,7 +38,7 @@
   __attribute((cleanup(c4))) void* g;
 }
 
-void c5(void*) __attribute__((deprecated));  // expected-note{{'c5' declared here}}
+void c5(void*) __attribute__((deprecated));  // expected-note{{'c5' has been explicitly marked deprecated here}}
 void t5() {
   int i __attribute__((cleanup(c5)));  // expected-warning {{'c5' is deprecated}}
 }
diff --git a/test/Sema/attr-coldhot.c b/test/Sema/attr-coldhot.c
index 253b189..abadf88 100644
--- a/test/Sema/attr-coldhot.c
+++ b/test/Sema/attr-coldhot.c
@@ -6,5 +6,5 @@
 int var1 __attribute__((__cold__)); // expected-warning{{'__cold__' attribute only applies to functions}}
 int var2 __attribute__((__hot__)); // expected-warning{{'__hot__' attribute only applies to functions}}
 
-int qux() __attribute__((__hot__)) __attribute__((__cold__)); // expected-error{{'__hot__' and cold attributes are not compatible}}
-int baz() __attribute__((__cold__)) __attribute__((__hot__)); // expected-error{{'__cold__' and hot attributes are not compatible}}
+int qux() __attribute__((__hot__)) __attribute__((__cold__)); // expected-error{{'__hot__' and 'cold' attributes are not compatible}}
+int baz() __attribute__((__cold__)) __attribute__((__hot__)); // expected-error{{'__cold__' and 'hot' attributes are not compatible}}
diff --git a/test/Sema/attr-deprecated-message.c b/test/Sema/attr-deprecated-message.c
index f48d13e..c683061 100644
--- a/test/Sema/attr-deprecated-message.c
+++ b/test/Sema/attr-deprecated-message.c
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 %s -verify -fsyntax-only
 // rdar: // 6734520
 
-typedef int INT1 __attribute__((deprecated("Please avoid INT1"))); // expected-note 3 {{'INT1' declared here}}
+typedef int INT1 __attribute__((deprecated("Please avoid INT1"))); // expected-note 3 {{'INT1' has been explicitly marked deprecated here}}
 
 typedef INT1 INT2 __attribute__ ((__deprecated__("Please avoid INT2")));
 
@@ -12,16 +12,16 @@
 INT1 should_be_unavailable; // expected-warning {{'INT1' is deprecated: Please avoid INT1}}
 INT1a should_not_be_deprecated;
 
-INT1 f1(void) __attribute__ ((deprecated("Please avoid f1"))); // expected-note {{'f1' declared here}}
+INT1 f1(void) __attribute__ ((deprecated("Please avoid f1"))); // expected-note {{'f1' has been explicitly marked deprecated here}}
 INT1 f2(void); // expected-warning {{'INT1' is deprecated: Please avoid INT1}}
 
-typedef enum {red, green, blue} Color __attribute__((deprecated("Please avoid Color"))); // expected-note {{'Color' declared here}}
+typedef enum {red, green, blue} Color __attribute__((deprecated("Please avoid Color"))); // expected-note {{'Color' has been explicitly marked deprecated here}}
  
 
 Color c1; // expected-warning {{'Color' is deprecated: Please avoid Color}}
 
 int g1;
-int g2 __attribute__ ((deprecated("Please avoid g2"))); // expected-note {{'g2' declared here}}
+int g2 __attribute__ ((deprecated("Please avoid g2"))); // expected-note {{'g2' has been explicitly marked deprecated here}}
 
 int func1()
 {
diff --git a/test/Sema/attr-deprecated.c b/test/Sema/attr-deprecated.c
index 8124ab0..c9e3dd5 100644
--- a/test/Sema/attr-deprecated.c
+++ b/test/Sema/attr-deprecated.c
@@ -1,10 +1,10 @@
 // RUN: %clang_cc1 %s -verify -fsyntax-only
 
-int f() __attribute__((deprecated)); // expected-note 2 {{declared here}}
+int f() __attribute__((deprecated)); // expected-note 2 {{'f' has been explicitly marked deprecated here}}
 void g() __attribute__((deprecated));
-void g(); // expected-note {{declared here}}
+void g(); // expected-note {{'g' has been explicitly marked deprecated here}}
 
-extern int var __attribute__((deprecated)); // expected-note {{declared here}}
+extern int var __attribute__((deprecated)); // expected-note {{'var' has been explicitly marked deprecated here}}
 
 int a() {
   int (*ptr)() = f; // expected-warning {{'f' is deprecated}}
@@ -17,13 +17,13 @@
 }
 
 // test if attributes propagate to variables
-extern int var; // expected-note {{declared here}}
+extern int var; // expected-note {{'var' has been explicitly marked deprecated here}}
 int w() {
   return var; // expected-warning {{'var' is deprecated}}
 }
 
 int old_fn() __attribute__ ((deprecated));
-int old_fn(); // expected-note {{declared here}}
+int old_fn(); // expected-note {{'old_fn' has been explicitly marked deprecated here}}
 int (*fn_ptr)() = old_fn; // expected-warning {{'old_fn' is deprecated}}
 
 int old_fn() {
@@ -32,7 +32,7 @@
 
 
 struct foo {
-  int x __attribute__((deprecated)); // expected-note 3 {{declared here}}
+  int x __attribute__((deprecated)); // expected-note 3 {{'x' has been explicitly marked deprecated here}}
 };
 
 void test1(struct foo *F) {
@@ -41,11 +41,11 @@
   struct foo f2 = { 17 }; // expected-warning {{'x' is deprecated}}
 }
 
-typedef struct foo foo_dep __attribute__((deprecated)); // expected-note 12 {{declared here}}
+typedef struct foo foo_dep __attribute__((deprecated)); // expected-note 12 {{'foo_dep' has been explicitly marked deprecated here}}
 foo_dep *test2;    // expected-warning {{'foo_dep' is deprecated}}
 
 struct __attribute__((deprecated, 
-                      invalid_attribute)) bar_dep ;  // expected-warning {{unknown attribute 'invalid_attribute' ignored}} expected-note 2 {{declared here}}
+                      invalid_attribute)) bar_dep ;  // expected-warning {{unknown attribute 'invalid_attribute' ignored}} expected-note 2 {{'bar_dep' has been explicitly marked deprecated here}}
 
 struct bar_dep *test3;   // expected-warning {{'bar_dep' is deprecated}}
 
@@ -102,9 +102,9 @@
         test19;
 
 // rdar://problem/8518751
-enum __attribute__((deprecated)) Test20 { // expected-note {{declared here}}
-  test20_a __attribute__((deprecated)), // expected-note {{declared here}}
-  test20_b // expected-note {{declared here}}
+enum __attribute__((deprecated)) Test20 { // expected-note {{'Test20' has been explicitly marked deprecated here}}
+  test20_a __attribute__((deprecated)), // expected-note {{'test20_a' has been explicitly marked deprecated here}}
+  test20_b // expected-note {{'test20_b' has been explicitly marked deprecated here}}
 };
 void test20() {
   enum Test20 f; // expected-warning {{'Test20' is deprecated}}
@@ -122,5 +122,5 @@
 };
 
 typedef int test23_ty __attribute((deprecated)); // expected-note {{previous definition is here}}
-typedef int test23_ty; // expected-note {{'test23_ty' declared here}} expected-warning {{redefinition of typedef 'test23_ty' is a C11 feature}}
+typedef int test23_ty; // expected-note {{'test23_ty' has been explicitly marked deprecated here}} expected-warning {{redefinition of typedef 'test23_ty' is a C11 feature}}
 test23_ty test23_v; // expected-warning {{'test23_ty' is deprecated}}
diff --git a/test/Sema/attr-malloc.c b/test/Sema/attr-malloc.c
index 2cec84d..c78d15c 100644
--- a/test/Sema/attr-malloc.c
+++ b/test/Sema/attr-malloc.c
@@ -1,5 +1,5 @@
-// RUN: %clang -Xclang -verify -fsyntax-only %s
-// RUN: %clang -emit-llvm -S -o %t %s
+// RUN: %clang_cc1 -verify -fsyntax-only %s
+// RUN: %clang_cc1 -emit-llvm -o %t %s
 
 #include <stddef.h>
 
diff --git a/test/Sema/attr-msp430.c b/test/Sema/attr-msp430.c
new file mode 100644
index 0000000..d08cd8e
--- /dev/null
+++ b/test/Sema/attr-msp430.c
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -triple msp430-unknown-unknown -fsyntax-only -verify %s

+

+int i;

+void f(void) __attribute__((interrupt(i))); /* expected-error {{'interrupt' attribute requires an integer constant}} */

+

+void f2(void) __attribute__((interrupt(12)));

diff --git a/test/Sema/attr-noduplicate.c b/test/Sema/attr-noduplicate.c
new file mode 100644
index 0000000..2a77de5
--- /dev/null
+++ b/test/Sema/attr-noduplicate.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+int a __attribute__((noduplicate)); // expected-warning {{'noduplicate' attribute only applies to functions}}
+
+void t1() __attribute__((noduplicate));
+
+void t2() __attribute__((noduplicate(2))); // expected-error {{'noduplicate' attribute takes no arguments}}
+
diff --git a/test/Sema/attr-ownership.c b/test/Sema/attr-ownership.c
index e31b429..2aa9f9f 100644
--- a/test/Sema/attr-ownership.c
+++ b/test/Sema/attr-ownership.c
@@ -1,12 +1,12 @@
 // RUN: %clang_cc1 %s -verify
 
 void f1(void) __attribute__((ownership_takes("foo"))); // expected-error {{'ownership_takes' attribute requires parameter 1 to be an identifier}}
-void *f2(void) __attribute__((ownership_returns(foo, 1, 2)));  // expected-error {{attribute takes no more than 1 argument}}
+void *f2(void) __attribute__((ownership_returns(foo, 1, 2)));  // expected-error {{'ownership_returns' attribute takes no more than 1 argument}}
 void f3(void) __attribute__((ownership_holds(foo, 1))); // expected-error {{'ownership_holds' attribute parameter 1 is out of bounds}}
 void *f4(void) __attribute__((ownership_returns(foo)));
-void f5(void) __attribute__((ownership_holds(foo)));  // expected-error {{attribute takes at least 2 arguments}}
+void f5(void) __attribute__((ownership_holds(foo)));  // expected-error {{'ownership_holds' attribute takes at least 2 arguments}}
 void f6(void) __attribute__((ownership_holds(foo, 1, 2, 3)));  // expected-error {{'ownership_holds' attribute parameter 1 is out of bounds}}
-void f7(void) __attribute__((ownership_takes(foo)));  // expected-error {{attribute takes at least 2 arguments}}
+void f7(void) __attribute__((ownership_takes(foo)));  // expected-error {{'ownership_takes' attribute takes at least 2 arguments}}
 void f8(int *i, int *j, int k) __attribute__((ownership_holds(foo, 1, 2, 4)));  // expected-error {{'ownership_holds' attribute parameter 3 is out of bounds}}
 
 int f9 __attribute__((ownership_takes(foo, 1)));  // expected-warning {{'ownership_takes' attribute only applies to functions}}
diff --git a/test/Sema/attr-section.c b/test/Sema/attr-section.c
index 396892a..812de06 100644
--- a/test/Sema/attr-section.c
+++ b/test/Sema/attr-section.c
@@ -10,10 +10,12 @@
 
 // PR6007
 void test() {
-  __attribute__((section("NEAR,x"))) int n1; // expected-error {{'section' attribute is not valid on local variables}}
+  __attribute__((section("NEAR,x"))) int n1; // expected-error {{'section' attribute only applies to functions and global variables}}
   __attribute__((section("NEAR,x"))) static int n2; // ok.
 }
 
 // pr9356
 void __attribute__((section("foo,zed"))) test2(void); // expected-note {{previous attribute is here}}
 void __attribute__((section("bar,zed"))) test2(void) {} // expected-warning {{section does not match previous declaration}}
+
+enum __attribute__((section("NEAR,x"))) e { one }; // expected-error {{'section' attribute only applies to functions and global variables}}
diff --git a/test/Sema/attr-unavailable-message.c b/test/Sema/attr-unavailable-message.c
index ebdf945..400a2c6 100644
--- a/test/Sema/attr-unavailable-message.c
+++ b/test/Sema/attr-unavailable-message.c
@@ -1,8 +1,8 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 // rdar: //6734520
 
-int foo(int)  __attribute__((__unavailable__("USE IFOO INSTEAD"))); // expected-note {{function has been explicitly marked unavailable here}}
-double dfoo(double)  __attribute__((__unavailable__("NO LONGER"))); // expected-note 2 {{function has been explicitly marked unavailable here}}
+int foo(int)  __attribute__((__unavailable__("USE IFOO INSTEAD"))); // expected-note {{'foo' has been explicitly marked unavailable here}}
+double dfoo(double)  __attribute__((__unavailable__("NO LONGER"))); // expected-note 2 {{'dfoo' has been explicitly marked unavailable here}}
 
 void bar() __attribute__((__unavailable__)); // expected-note {{explicitly marked unavailable}}
 
@@ -34,13 +34,13 @@
 
 // rdar://10201690
 enum foo {
-    a = 1, // expected-note {{declared here}}
-    b __attribute__((deprecated())) = 2, // expected-note {{declared here}}
+    a = 1, // expected-note {{'a' has been explicitly marked deprecated here}}
+    b __attribute__((deprecated())) = 2, // expected-note {{'b' has been explicitly marked deprecated here}}
     c = 3
 }__attribute__((deprecated()));
 
-enum fee { // expected-note {{declaration has been explicitly marked unavailable here}}
-    r = 1, // expected-note {{declaration has been explicitly marked unavailable here}}
+enum fee { // expected-note {{'fee' has been explicitly marked unavailable here}}
+    r = 1, // expected-note {{'r' has been explicitly marked unavailable here}}
     s = 2,
     t = 3
 }__attribute__((unavailable()));
diff --git a/test/Sema/attr-used.c b/test/Sema/attr-used.c
index accc7b6..4e3bda7 100644
--- a/test/Sema/attr-used.c
+++ b/test/Sema/attr-used.c
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -verify -fsyntax-only -Wno-private-extern %s
 
-extern int l0 __attribute__((used)); // expected-warning {{used attribute ignored}}
-__private_extern__ int l1 __attribute__((used)); // expected-warning {{used attribute ignored}}
+extern int l0 __attribute__((used)); // expected-warning {{'used' attribute ignored}}
+__private_extern__ int l1 __attribute__((used)); // expected-warning {{'used' attribute ignored}}
 
 struct __attribute__((used)) s { // expected-warning {{'used' attribute only applies to variables and functions}}
   int x;
@@ -13,8 +13,8 @@
 }
 
 void f1() {
-  static int a __attribute__((used)); 
-  int b __attribute__((used)); // expected-warning {{used attribute ignored}}
+  static int a __attribute__((used));
+  int b __attribute__((used)); // expected-warning {{'used' attribute ignored}}
 }
 
 static void __attribute__((used)) f0(void);
diff --git a/test/Sema/big-endian-neon-initializers.c b/test/Sema/big-endian-neon-initializers.c
new file mode 100644
index 0000000..ffe3109
--- /dev/null
+++ b/test/Sema/big-endian-neon-initializers.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 %s -triple arm64_be -target-feature +neon -verify -fsyntax-only -ffreestanding
+// RUN: %clang_cc1 %s -triple armebv7 -target-cpu cortex-a8 -verify -fsyntax-only -ffreestanding
+
+#include <arm_neon.h>
+
+int32x4_t x = {1, 2, 3, 4}; // expected-warning{{vector initializers are not compatible with NEON intrinsics}} expected-note{{consider using vld1q_s32() to initialize a vector from memory, or vcombine_s32(vcreate_s32(), vcreate_s32()) to initialize from integer constants}}
+int16x4_t y = {1, 2, 3, 4}; // expected-warning{{vector initializers are not compatible with NEON intrinsics}} expected-note{{consider using vld1_s16() to initialize a vector from memory, or vcreate_s16() to initialize from an integer constant}}
+int64x2_t z = {1, 2}; // expected-warning{{vector initializers are not compatible with NEON intrinsics}} expected-note{{consider using vld1q_s64() to initialize a vector from memory, or vcombine_s64(vcreate_s64(), vcreate_s64()) to initialize from integer constants}}
+float32x2_t b = {1, 2}; // expected-warning{{vector initializers are not compatible with NEON intrinsics}} expected-note{{consider using vld1_f32() to initialize a vector from memory, or vcreate_f32() to initialize from an integer constant}}
+
+// No warning expected here.
+typedef int v4si __attribute__ ((vector_size (16)));
+v4si c = {1, 2, 3, 4};
diff --git a/test/Sema/bitfield-layout.c b/test/Sema/bitfield-layout.c
index d226391..2abd139 100644
--- a/test/Sema/bitfield-layout.c
+++ b/test/Sema/bitfield-layout.c
@@ -9,6 +9,21 @@
 CHECK_SIZE(struct, a, 5)
 CHECK_ALIGN(struct, a, 1)
 
+// Zero-width bit-fields with packed
+struct __attribute__((packed)) a2 { short x : 9; char : 0; int y : 17; };
+CHECK_SIZE(struct, a2, 5)
+CHECK_ALIGN(struct, a2, 1)
+
+// Zero-width bit-fields at the end of packed struct
+struct __attribute__((packed)) a3 { short x : 9; int : 0; };
+CHECK_SIZE(struct, a3, 4)
+CHECK_ALIGN(struct, a3, 1)
+
+// For comparison, non-zero-width bit-fields at the end of packed struct
+struct __attribute__((packed)) a4 { short x : 9; int : 1; };
+CHECK_SIZE(struct, a4, 2)
+CHECK_ALIGN(struct, a4, 1)
+
 union b {char x; int : 0; char y;};
 CHECK_SIZE(union, b, 1)
 CHECK_ALIGN(union, b, 1)
diff --git a/test/Sema/block-misc.c b/test/Sema/block-misc.c
index 2260458..b4732b5 100644
--- a/test/Sema/block-misc.c
+++ b/test/Sema/block-misc.c
@@ -131,7 +131,7 @@
   static void *P = ^{  // expected-error {{initializer element is not a compile-time constant}}
 
     void *Q = ^{
-      // References test14's "X": outer block is non constant.
+      // References test14's "X": outer block is non-constant.
       return X+4;
     };
   };
diff --git a/test/Sema/block-return.c b/test/Sema/block-return.c
index 6b4d998..08e9249 100644
--- a/test/Sema/block-return.c
+++ b/test/Sema/block-return.c
@@ -82,7 +82,7 @@
   int (*yy)(const char *s) = funk; // expected-warning {{incompatible pointer types initializing 'int (*)(const char *)' with an expression of type 'int (char *)'}}
   
   int (^nested)(char *s) = ^(char *str) { void (^nest)(void) = ^(void) { printf("%s\n", str); }; next(); return 1; }; // expected-warning{{implicitly declaring library function 'printf' with type 'int (const char *, ...)'}} \
-  // expected-note{{please include the header <stdio.h> or explicitly provide a declaration for 'printf'}}
+  // expected-note{{include the header <stdio.h> or explicitly provide a declaration for 'printf'}}
 }
 
 typedef void (^bptr)(void);
diff --git a/test/Sema/bool-compare.c b/test/Sema/bool-compare.c
new file mode 100644
index 0000000..3f1f286
--- /dev/null
+++ b/test/Sema/bool-compare.c
@@ -0,0 +1,162 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+
+void f(int x, int y, int z) {
+  int a,b;
+
+
+  if ((a > 2) > 1) {} // expected-warning {{comparison of constant 1 with boolean expression is always false}}
+
+  if (a > b)      {} // no warning
+  if (a < b)      {} // no warning
+  if (a >= b)     {} // no warning
+  if (a <= b)     {} // no warning
+  if (a == b)     {} // no warning
+  if (a != b)     {} // no warning
+
+  if (a > 0) {} // no warning
+  if (a > 1) {} // no warning
+  if (a > 2) {} // no warning
+
+  if (a >= 0) {} // no warning
+  if (a >= 1) {} // no warning
+  if (a >= 2) {} // no warning
+  if (a >= -1) {} // no warning
+
+  if (a <= 0) {} // no warning
+  if (a <= 1) {} // no warning
+  if (a <= 2) {} // no warning
+  if (a <= -1) {} // no warning
+
+
+  if (!a > 0) {}  // no warning
+  if (!a > 1)     {} // expected-warning {{comparison of constant 1 with boolean expression is always false}}
+  if (!a > 2)     {} // expected-warning {{comparison of constant 2 with boolean expression is always false}}
+  if (!a > y)     {} // no warning
+  if (!a > b)     {} // no warning
+  if (!a > -1)    {} // expected-warning {{comparison of constant -1 with boolean expression is always true}}
+
+  if (!a < 0)     {} // expected-warning {{comparison of constant 0 with boolean expression is always false}}
+  if (!a < 1)     {} // no warning
+  if (!a < 2)     {} // expected-warning {{comparison of constant 2 with boolean expression is always true}}
+  if (!a < y)     {} // no warning
+  if (!a < b)     {} // no warning
+  if (!a < -1)    {} // expected-warning {{comparison of constant -1 with boolean expression is always false}}
+
+  if (!a >= 0)    {} // expected-warning {{comparison of constant 0 with boolean expression is always true}}
+  if (!a >= 1)    {} // no warning
+  if (!a >= 2)    {} // expected-warning {{comparison of constant 2 with boolean expression is always false}}
+  if (!a >= y)    {} // no warning
+  if (!a >= b)    {} // no warning
+  if (!a >= -1)   {} // expected-warning {{comparison of constant -1 with boolean expression is always true}}
+
+  if (!a <= 0)    {} // no warning
+  if (!a <= 1)    {} // expected-warning {{comparison of constant 1 with boolean expression is always true}}
+  if (!a <= 2)    {} // expected-warning {{comparison of constant 2 with boolean expression is always true}}
+  if (!a <= y)    {} // no warning
+  if (!a <= b)    {} // no warning
+  if (!a <= -1)   {} // expected-warning {{comparison of constant -1 with boolean expression is always false}}
+
+  if ((a||b) > 0) {} // no warning
+  if ((a||b) > 1) {} // expected-warning {{comparison of constant 1 with boolean expression is always false}}
+  if ((a||b) > 4) {} // expected-warning {{comparison of constant 4 with boolean expression is always false}}
+  if ((a||b) > -1) {}// expected-warning {{comparison of constant -1 with boolean expression is always true}}
+
+  if ((a&&b) > 0) {} // no warning
+  if ((a&&b) > 1) {} // expected-warning {{comparison of constant 1 with boolean expression is always false}}
+  if ((a&&b) > 4) {} // expected-warning {{comparison of constant 4 with boolean expression is always false}}
+
+  if ((a<y) > 0)  {} // no warning
+  if ((a<y) > 1)  {} // expected-warning {{comparison of constant 1 with boolean expression is always false}}
+  if ((a<y) > 4)  {} // expected-warning {{comparison of constant 4 with boolean expression is always false}}
+  if ((a<y) > z)  {} // no warning
+  if ((a<y) > -1) {} // expected-warning {{comparison of constant -1 with boolean expression is always true}}
+
+  if ((a<y) == 0) {} // no warning
+  if ((a<y) == 1) {} // no warning
+  if ((a<y) == 2) {} // expected-warning {{comparison of constant 2 with boolean expression is always false}}
+  if ((a<y) == z) {} // no warning
+  if ((a<y) == -1) {}// expected-warning {{comparison of constant -1 with boolean expression is always false}}
+
+  if ((a<y) != 0) {} // no warning
+  if ((a<y) != 1) {} // no warning
+  if ((a<y) != 2) {} // expected-warning {{comparison of constant 2 with boolean expression is always true}}
+  if ((a<y) != z) {} // no warning
+  if ((a<y) != -1) {}// expected-warning {{comparison of constant -1 with boolean expression is always true}}
+
+  if ((a<y) == z) {} // no warning
+  if (a>y<z)      {} // no warning
+  if ((a<y) > z)  {} // no warning
+  if((a<y)>(z<y)) {} // no warning
+  if((a<y)==(z<y)){} // no warning
+  if((a<y)!=(z<y)){} // no warning
+  if((z==x)<(y==z)){}// no warning
+  if((a<y)!=((z==x)<(y==z))){} //no warning
+
+
+  if (0 > !a)     {} // expected-warning {{comparison of constant 0 with boolean expression is always false}}
+  if (1 > !a)     {} // no warning
+  if (2 > !a)     {} // expected-warning {{comparison of constant 2 with boolean expression is always true}}
+  if (y > !a)     {} // no warning
+  if (-1 > !a)    {} // expected-warning {{comparison of constant -1 with boolean expression is always false}}
+
+  if (0 < !a)     {} // no warning
+  if (1 < !a)     {} // expected-warning {{comparison of constant 1 with boolean expression is always false}}
+  if (2 < !a)     {} // expected-warning {{comparison of constant 2 with boolean expression is always false}}
+  if (y < !a)     {} // no warning
+  if (-1 < !a)    {} // expected-warning {{comparison of constant -1 with boolean expression is always true}}
+
+  if (0 >= !a)    {} // no warning
+  if (1 >= !a)    {} // expected-warning {{comparison of constant 1 with boolean expression is always true}}
+  if (2 >= !a)    {} // expected-warning {{comparison of constant 2 with boolean expression is always true}}
+  if (y >= !a)    {} // no warning
+  if (-1 >= !a)   {} // expected-warning {{comparison of constant -1 with boolean expression is always false}}
+
+  if (0 <= !a)    {} // expected-warning {{comparison of constant 0 with boolean expression is always true}}
+  if (1 <= !a)    {} // no warning
+  if (2 <= !a)    {} // expected-warning {{comparison of constant 2 with boolean expression is always false}}
+  if (y <= !a)    {} // no warning
+  if (-1 <= !a)   {} // expected-warning {{comparison of constant -1 with boolean expression is always true}}
+
+  if (0 > (a||b)) {} // expected-warning {{comparison of constant 0 with boolean expression is always false}}
+  if (1 > (a||b)) {} // no warning
+  if (4 > (a||b)) {} // expected-warning {{comparison of constant 4 with boolean expression is always true}}
+
+  if (0 > (a&&b)) {} // expected-warning {{comparison of constant 0 with boolean expression is always false}}
+  if (1 > (a&&b)) {} // no warning
+  if (4 > (a&&b)) {} // expected-warning {{comparison of constant 4 with boolean expression is always true}}
+
+  if (0 > (a<y))  {} // expected-warning {{comparison of constant 0 with boolean expression is always false}}
+  if (1 > (a<y))  {} // no warning
+  if (4 > (a<y))  {} // expected-warning {{comparison of constant 4 with boolean expression is always true}}
+  if (z > (a<y))  {} // no warning
+  if (-1 > (a<y)) {} // expected-warning {{comparison of constant -1 with boolean expression is always false}}
+
+  if (0 == (a<y)) {} // no warning
+  if (1 == (a<y)) {} // no warning
+  if (2 == (a<y)) {} // expected-warning {{comparison of constant 2 with boolean expression is always false}}
+  if (z == (a<y)) {} // no warning
+  if (-1 == (a<y)){} // expected-warning {{comparison of constant -1 with boolean expression is always false}}
+
+  if (0 !=(a<y))  {} // no warning
+  if (1 !=(a<y))  {} // no warning
+  if (2 !=(a<y))  {} // expected-warning {{comparison of constant 2 with boolean expression is always true}}
+  if (z !=(a<y))  {} // no warning
+  if (-1 !=(a<y)) {} // expected-warning {{comparison of constant -1 with boolean expression is always true}}
+
+  if (z ==(a<y))  {}    // no warning
+  if (z<a>y)      {}        // no warning
+  if (z > (a<y))  {}    // no warning
+  if((z<y)>(a<y)) {}   // no warning
+  if((z<y)==(a<y)){}  // no warning
+  if((z<y)!=(a<y)){}  // no warning
+  if((y==z)<(z==x)){}  // no warning
+  if(((z==x)<(y==z))!=(a<y)){}  // no warning
+
+  if(((z==x)<(-1==z))!=(a<y)){} // no warning
+  if(((z==x)<(z==-1))!=(a<y)){} // no warning
+  if(((z==x)<-1)!=(a<y)){} // expected-warning {{comparison of constant -1 with boolean expression is always false}}
+  if(((z==x)< 2)!=(a<y)){} // expected-warning {{comparison of constant 2 with boolean expression is always true}}
+  if(((z==x)<(z>2))!=(a<y)){} // no warning
+
+}
diff --git a/test/Sema/builtin-assume.c b/test/Sema/builtin-assume.c
new file mode 100644
index 0000000..1f6a3a0
--- /dev/null
+++ b/test/Sema/builtin-assume.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -triple i386-mingw32 -fms-extensions -fsyntax-only -verify %s
+
+int foo(int *a, int i) {
+  __assume(i != 4);
+  __assume(++i > 2); //expected-warning {{the argument to __assume has side effects that will be discarded}}
+
+  int test = sizeof(struct{char qq[(__assume(i != 5), 7)];});
+
+  return a[i];
+}
+
diff --git a/test/Sema/builtin-clear_cache.c b/test/Sema/builtin-clear_cache.c
index e21aad7..3193f31 100644
--- a/test/Sema/builtin-clear_cache.c
+++ b/test/Sema/builtin-clear_cache.c
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 -triple armv7-none-linux-gnu -fsyntax-only -verify %s
 // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple arm64-none-linux-gnu -fsyntax-only -verify %s
 // expected-no-diagnostics
 
 void __clear_cache(void *a, void *b) {}
diff --git a/test/Sema/builtins-aarch64.c b/test/Sema/builtins-aarch64.c
index b055753..b4d8aae 100644
--- a/test/Sema/builtins-aarch64.c
+++ b/test/Sema/builtins-aarch64.c
@@ -1,5 +1,7 @@
 // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -fsyntax-only -verify %s
 // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -DTEST1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple arm64-none-linux-gnu -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple arm64-none-linux-gnu -DTEST1 -fsyntax-only -verify %s
 
 #ifdef TEST1
 void __clear_cache(void *start, void *end);
diff --git a/test/Sema/builtins-arm-exclusive.c b/test/Sema/builtins-arm-exclusive.c
index 8c78403..4e6a96b 100644
--- a/test/Sema/builtins-arm-exclusive.c
+++ b/test/Sema/builtins-arm-exclusive.c
@@ -55,6 +55,57 @@
   return res;
 }
 
+int test_ldaex(char *addr) {
+  int sum = 0;
+  sum += __builtin_arm_ldaex(addr);
+  sum += __builtin_arm_ldaex((short *)addr);
+  sum += __builtin_arm_ldaex((int *)addr);
+  sum += __builtin_arm_ldaex((long long *)addr);
+  sum += __builtin_arm_ldaex((float *)addr);
+  sum += __builtin_arm_ldaex((double *)addr);
+  sum += *__builtin_arm_ldaex((int **)addr);
+  sum += __builtin_arm_ldaex((struct Simple **)addr)->a;
+  sum += __builtin_arm_ldaex((volatile char *)addr);
+  sum += __builtin_arm_ldaex((const volatile char *)addr);
+
+  // In principle this might be valid, but stick to ints and floats for scalar
+  // types at the moment.
+  sum += __builtin_arm_ldaex((struct Simple *)addr).a; // expected-error {{address argument to atomic builtin must be a pointer to}}
+
+  sum += __builtin_arm_ldaex((__int128 *)addr); // expected-error {{__int128 is not supported on this target}} expected-error {{address argument to load or store exclusive builtin must be a pointer to 1,2,4 or 8 byte type}}
+
+  __builtin_arm_ldaex(); // expected-error {{too few arguments to function call}}
+  __builtin_arm_ldaex(1, 2); // expected-error {{too many arguments to function call}}
+  return sum;
+}
+
+int test_stlex(char *addr) {
+  int res = 0;
+  struct Simple var = {0};
+  res |= __builtin_arm_stlex(4, addr);
+  res |= __builtin_arm_stlex(42, (short *)addr);
+  res |= __builtin_arm_stlex(42, (int *)addr);
+  res |= __builtin_arm_stlex(42, (long long *)addr);
+  res |= __builtin_arm_stlex(2.71828f, (float *)addr);
+  res |= __builtin_arm_stlex(3.14159, (double *)addr);
+  res |= __builtin_arm_stlex(&var, (struct Simple **)addr);
+
+  res |= __builtin_arm_stlex(42, (volatile char *)addr);
+  res |= __builtin_arm_stlex(42, (char *const)addr);
+  res |= __builtin_arm_stlex(42, (const char *)addr); // expected-warning {{passing 'const char *' to parameter of type 'volatile char *' discards qualifiers}}
+
+
+  res |= __builtin_arm_stlex(var, (struct Simple *)addr); // expected-error {{address argument to atomic builtin must be a pointer to}}
+  res |= __builtin_arm_stlex(var, (struct Simple **)addr); // expected-error {{passing 'struct Simple' to parameter of incompatible type 'struct Simple *'}}
+  res |= __builtin_arm_stlex(&var, (struct Simple **)addr).a; // expected-error {{is not a structure or union}}
+
+  res |= __builtin_arm_stlex(1, (__int128 *)addr); // expected-error {{__int128 is not supported on this target}} expected-error {{address argument to load or store exclusive builtin must be a pointer to 1,2,4 or 8 byte type}}
+
+  __builtin_arm_stlex(1); // expected-error {{too few arguments to function call}}
+  __builtin_arm_stlex(1, 2, 3); // expected-error {{too many arguments to function call}}
+  return res;
+}
+
 void test_clrex() {
   __builtin_arm_clrex();
   __builtin_arm_clrex(1); // expected-error {{too many arguments to function call}}
diff --git a/test/Sema/builtins-arm.c b/test/Sema/builtins-arm.c
index 3ac1da0..6c367d3 100644
--- a/test/Sema/builtins-arm.c
+++ b/test/Sema/builtins-arm.c
@@ -31,4 +31,10 @@
   *ptr = '0'; // expected-error {{incomplete type 'void' is not assignable}}
 }
 
+void test3() {
+  __builtin_arm_dsb(16); // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_arm_dmb(17); // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_arm_isb(18); // expected-error {{argument should be a value from 0 to 15}}
+}
+
 #endif
diff --git a/test/Sema/builtins-arm64-exclusive.c b/test/Sema/builtins-arm64-exclusive.c
new file mode 100644
index 0000000..4d678cc
--- /dev/null
+++ b/test/Sema/builtins-arm64-exclusive.c
@@ -0,0 +1,108 @@
+// RUN: %clang_cc1 -triple arm64-apple-ios7.0 -fsyntax-only -verify %s
+
+struct Simple {
+  char a, b;
+};
+
+int test_ldrex(char *addr) {
+  int sum = 0;
+  sum += __builtin_arm_ldrex(addr);
+  sum += __builtin_arm_ldrex((short *)addr);
+  sum += __builtin_arm_ldrex((int *)addr);
+  sum += __builtin_arm_ldrex((long long *)addr);
+  sum += __builtin_arm_ldrex((__int128 *)addr);
+  sum += __builtin_arm_ldrex((float *)addr);
+  sum += __builtin_arm_ldrex((double *)addr);
+  sum += *__builtin_arm_ldrex((int **)addr);
+  sum += __builtin_arm_ldrex((struct Simple **)addr)->a;
+  sum += __builtin_arm_ldrex((volatile char *)addr);
+  sum += __builtin_arm_ldrex((const volatile char *)addr);
+
+  // In principle this might be valid, but stick to ints and floats for scalar
+  // types at the moment.
+  sum += __builtin_arm_ldrex((struct Simple *)addr).a; // expected-error {{address argument to atomic builtin must be a pointer to}}
+
+  __builtin_arm_ldrex(); // expected-error {{too few arguments to function call}}
+  __builtin_arm_ldrex(1, 2); // expected-error {{too many arguments to function call}}
+  return sum;
+}
+
+int test_strex(char *addr) {
+  int res = 0;
+  struct Simple var = {0};
+  res |= __builtin_arm_strex(4, addr);
+  res |= __builtin_arm_strex(42, (short *)addr);
+  res |= __builtin_arm_strex(42, (int *)addr);
+  res |= __builtin_arm_strex(42, (long long *)addr);
+  res |= __builtin_arm_strex(42, (__int128 *)addr);
+  res |= __builtin_arm_strex(2.71828f, (float *)addr);
+  res |= __builtin_arm_strex(3.14159, (double *)addr);
+  res |= __builtin_arm_strex(&var, (struct Simple **)addr);
+
+  res |= __builtin_arm_strex(42, (volatile char *)addr);
+  res |= __builtin_arm_strex(42, (char *const)addr);
+  res |= __builtin_arm_strex(42, (const char *)addr); // expected-warning {{passing 'const char *' to parameter of type 'volatile char *' discards qualifiers}}
+
+
+  res |= __builtin_arm_strex(var, (struct Simple *)addr); // expected-error {{address argument to atomic builtin must be a pointer to}}
+  res |= __builtin_arm_strex(var, (struct Simple **)addr); // expected-error {{passing 'struct Simple' to parameter of incompatible type 'struct Simple *'}}
+  res |= __builtin_arm_strex(&var, (struct Simple **)addr).a; // expected-error {{is not a structure or union}}
+
+  __builtin_arm_strex(1); // expected-error {{too few arguments to function call}}
+  __builtin_arm_strex(1, 2, 3); // expected-error {{too many arguments to function call}}
+  return res;
+}
+
+int test_ldaex(char *addr) {
+  int sum = 0;
+  sum += __builtin_arm_ldaex(addr);
+  sum += __builtin_arm_ldaex((short *)addr);
+  sum += __builtin_arm_ldaex((int *)addr);
+  sum += __builtin_arm_ldaex((long long *)addr);
+  sum += __builtin_arm_ldaex((__int128 *)addr);
+  sum += __builtin_arm_ldaex((float *)addr);
+  sum += __builtin_arm_ldaex((double *)addr);
+  sum += *__builtin_arm_ldaex((int **)addr);
+  sum += __builtin_arm_ldaex((struct Simple **)addr)->a;
+  sum += __builtin_arm_ldaex((volatile char *)addr);
+  sum += __builtin_arm_ldaex((const volatile char *)addr);
+
+  // In principle this might be valid, but stick to ints and floats for scalar
+  // types at the moment.
+  sum += __builtin_arm_ldaex((struct Simple *)addr).a; // expected-error {{address argument to atomic builtin must be a pointer to}}
+
+  __builtin_arm_ldaex(); // expected-error {{too few arguments to function call}}
+  __builtin_arm_ldaex(1, 2); // expected-error {{too many arguments to function call}}
+  return sum;
+}
+
+int test_stlex(char *addr) {
+  int res = 0;
+  struct Simple var = {0};
+  res |= __builtin_arm_stlex(4, addr);
+  res |= __builtin_arm_stlex(42, (short *)addr);
+  res |= __builtin_arm_stlex(42, (int *)addr);
+  res |= __builtin_arm_stlex(42, (long long *)addr);
+  res |= __builtin_arm_stlex(42, (__int128 *)addr);
+  res |= __builtin_arm_stlex(2.71828f, (float *)addr);
+  res |= __builtin_arm_stlex(3.14159, (double *)addr);
+  res |= __builtin_arm_stlex(&var, (struct Simple **)addr);
+
+  res |= __builtin_arm_stlex(42, (volatile char *)addr);
+  res |= __builtin_arm_stlex(42, (char *const)addr);
+  res |= __builtin_arm_stlex(42, (const char *)addr); // expected-warning {{passing 'const char *' to parameter of type 'volatile char *' discards qualifiers}}
+
+
+  res |= __builtin_arm_stlex(var, (struct Simple *)addr); // expected-error {{address argument to atomic builtin must be a pointer to}}
+  res |= __builtin_arm_stlex(var, (struct Simple **)addr); // expected-error {{passing 'struct Simple' to parameter of incompatible type 'struct Simple *'}}
+  res |= __builtin_arm_stlex(&var, (struct Simple **)addr).a; // expected-error {{is not a structure or union}}
+
+  __builtin_arm_stlex(1); // expected-error {{too few arguments to function call}}
+  __builtin_arm_stlex(1, 2, 3); // expected-error {{too many arguments to function call}}
+  return res;
+}
+
+void test_clrex() {
+  __builtin_arm_clrex();
+  __builtin_arm_clrex(1); // expected-error {{too many arguments to function call}}
+}
diff --git a/test/Sema/builtins-arm64.c b/test/Sema/builtins-arm64.c
new file mode 100644
index 0000000..113f4fc
--- /dev/null
+++ b/test/Sema/builtins-arm64.c
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -triple arm64-apple-ios -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple arm64-apple-ios -DTEST1 -fsyntax-only -verify %s
+
+#ifdef TEST1
+void __clear_cache(void *start, void *end);
+#endif
+
+void test_clear_cache_chars(char *start, char *end) {
+  __clear_cache(start, end);
+}
+
+void test_clear_cache_voids(void *start, void *end) {
+  __clear_cache(start, end);
+}
+
+void test_clear_cache_no_args() {
+  __clear_cache(); // expected-error {{too few arguments to function call}}
+}
+
+void test_memory_barriers() {
+  __builtin_arm_dmb(16); // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_arm_dsb(17); // expected-error {{argument should be a value from 0 to 15}}
+  __builtin_arm_isb(18); // expected-error {{argument should be a value from 0 to 15}}
+}
diff --git a/test/Sema/builtins-gnu-mode.c b/test/Sema/builtins-gnu-mode.c
index 718803e..d93b6fd 100644
--- a/test/Sema/builtins-gnu-mode.c
+++ b/test/Sema/builtins-gnu-mode.c
@@ -13,14 +13,6 @@
 int strcasecmp;
 int strncasecmp;
 int _exit;
-int vfork;
-int _setjmp;
-int __sigsetjmp;
-int sigsetjmp;
-int setjmp_syscall;
-int savectx;
-int qsetjmp;
-int getcontext;
 int _longjmp;
 int siglongjmp;
 int strlcpy;
diff --git a/test/Sema/builtins.c b/test/Sema/builtins.c
index 8ca33c8..7647100 100644
--- a/test/Sema/builtins.c
+++ b/test/Sema/builtins.c
@@ -197,3 +197,8 @@
   __noop(1); // expected-warning {{implicit declaration}}
   __debugbreak(); // expected-warning {{implicit declaration}}
 }
+
+void unavailable() {
+  __builtin_operator_new(0); // expected-error {{'__builtin_operator_new' is only available in C++}}
+  __builtin_operator_delete(0); // expected-error {{'__builtin_operator_delete' is only available in C++}}
+}
diff --git a/test/Sema/c89.c b/test/Sema/c89.c
index b746d38..c9e81f1 100644
--- a/test/Sema/c89.c
+++ b/test/Sema/c89.c
@@ -111,6 +111,8 @@
 
 void main() {} /* expected-error {{'main' must return 'int'}} */
 
+const int main() {} /* expected-error {{'main' must return 'int'}} */
+
 long long ll1 = /* expected-warning {{'long long' is an extension when C99 mode is not enabled}} */
          -42LL; /* expected-warning {{'long long' is an extension when C99 mode is not enabled}} */
 unsigned long long ull1 = /* expected-warning {{'long long' is an extension when C99 mode is not enabled}} */
diff --git a/test/Sema/callingconv.c b/test/Sema/callingconv.c
index 500c0fb..f9fa9fe 100644
--- a/test/Sema/callingconv.c
+++ b/test/Sema/callingconv.c
@@ -66,3 +66,5 @@
 typedef void typedef_fun_t(int);
 typedef_fun_t typedef_fun; // expected-note {{previous declaration is here}}
 void __attribute__((stdcall)) typedef_fun(int x) { } // expected-error {{function declared 'stdcall' here was previously declared without calling convention}}
+
+struct type_test {} __attribute__((stdcall));  // expected-warning {{'stdcall' attribute only applies to functions and methods}}
diff --git a/test/Sema/const-eval.c b/test/Sema/const-eval.c
index 16d028e..883cced 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
+// RUN: %clang_cc1 -fsyntax-only -verify -triple i686-linux %s -Wno-tautological-pointer-compare
 
 #define EVAL_EXPR(testno, expr) int test##testno = sizeof(struct{char qq[expr];});
 int x;
diff --git a/test/Sema/constant-builtins-2.c b/test/Sema/constant-builtins-2.c
index d2d221c..a4baecb 100644
--- a/test/Sema/constant-builtins-2.c
+++ b/test/Sema/constant-builtins-2.c
@@ -112,49 +112,53 @@
 //long double  g21 = __builtin_powil(2.0L, 4);
 
 #define BITSIZE(x) (sizeof(x) * 8)
-char g22[__builtin_clz(1) == BITSIZE(int) - 1 ? 1 : -1];
-char g23[__builtin_clz(7) == BITSIZE(int) - 3 ? 1 : -1];
-char g24[__builtin_clz(1 << (BITSIZE(int) - 1)) == 0 ? 1 : -1];
-int g25 = __builtin_clz(0); // expected-error {{not a compile-time constant}}
-char g26[__builtin_clzl(0xFL) == BITSIZE(long) - 4 ? 1 : -1];
-char g27[__builtin_clzll(0xFFLL) == BITSIZE(long long) - 8 ? 1 : -1];
+char clz1[__builtin_clz(1) == BITSIZE(int) - 1 ? 1 : -1];
+char clz2[__builtin_clz(7) == BITSIZE(int) - 3 ? 1 : -1];
+char clz3[__builtin_clz(1 << (BITSIZE(int) - 1)) == 0 ? 1 : -1];
+int clz4 = __builtin_clz(0); // expected-error {{not a compile-time constant}}
+char clz5[__builtin_clzl(0xFL) == BITSIZE(long) - 4 ? 1 : -1];
+char clz6[__builtin_clzll(0xFFLL) == BITSIZE(long long) - 8 ? 1 : -1];
+char clz7[__builtin_clzs(0x1) == BITSIZE(short) - 1 ? 1 : -1];
+char clz8[__builtin_clzs(0xf) == BITSIZE(short) - 4 ? 1 : -1];
+char clz9[__builtin_clzs(0xfff) == BITSIZE(short) - 12 ? 1 : -1];
 
-char g28[__builtin_ctz(1) == 0 ? 1 : -1];
-char g29[__builtin_ctz(8) == 3 ? 1 : -1];
-char g30[__builtin_ctz(1 << (BITSIZE(int) - 1)) == BITSIZE(int) - 1 ? 1 : -1];
-int g31 = __builtin_ctz(0); // expected-error {{not a compile-time constant}}
-char g32[__builtin_ctzl(0x10L) == 4 ? 1 : -1];
-char g33[__builtin_ctzll(0x100LL) == 8 ? 1 : -1];
+char ctz1[__builtin_ctz(1) == 0 ? 1 : -1];
+char ctz2[__builtin_ctz(8) == 3 ? 1 : -1];
+char ctz3[__builtin_ctz(1 << (BITSIZE(int) - 1)) == BITSIZE(int) - 1 ? 1 : -1];
+int ctz4 = __builtin_ctz(0); // expected-error {{not a compile-time constant}}
+char ctz5[__builtin_ctzl(0x10L) == 4 ? 1 : -1];
+char ctz6[__builtin_ctzll(0x100LL) == 8 ? 1 : -1];
+char ctz7[__builtin_ctzs(1 << (BITSIZE(short) - 1)) == BITSIZE(short) - 1 ? 1 : -1];
 
-char g34[__builtin_popcount(0) == 0 ? 1 : -1];
-char g35[__builtin_popcount(0xF0F0) == 8 ? 1 : -1];
-char g36[__builtin_popcount(~0) == BITSIZE(int) ? 1 : -1];
-char g37[__builtin_popcount(~0L) == BITSIZE(int) ? 1 : -1];
-char g38[__builtin_popcountl(0L) == 0 ? 1 : -1];
-char g39[__builtin_popcountl(0xF0F0L) == 8 ? 1 : -1];
-char g40[__builtin_popcountl(~0L) == BITSIZE(long) ? 1 : -1];
-char g41[__builtin_popcountll(0LL) == 0 ? 1 : -1];
-char g42[__builtin_popcountll(0xF0F0LL) == 8 ? 1 : -1];
-char g43[__builtin_popcountll(~0LL) == BITSIZE(long long) ? 1 : -1];
+char popcount1[__builtin_popcount(0) == 0 ? 1 : -1];
+char popcount2[__builtin_popcount(0xF0F0) == 8 ? 1 : -1];
+char popcount3[__builtin_popcount(~0) == BITSIZE(int) ? 1 : -1];
+char popcount4[__builtin_popcount(~0L) == BITSIZE(int) ? 1 : -1];
+char popcount5[__builtin_popcountl(0L) == 0 ? 1 : -1];
+char popcount6[__builtin_popcountl(0xF0F0L) == 8 ? 1 : -1];
+char popcount7[__builtin_popcountl(~0L) == BITSIZE(long) ? 1 : -1];
+char popcount8[__builtin_popcountll(0LL) == 0 ? 1 : -1];
+char popcount9[__builtin_popcountll(0xF0F0LL) == 8 ? 1 : -1];
+char popcount10[__builtin_popcountll(~0LL) == BITSIZE(long long) ? 1 : -1];
 
-char g44[__builtin_parity(0) == 0 ? 1 : -1];
-char g45[__builtin_parity(0xb821) == 0 ? 1 : -1];
-char g46[__builtin_parity(0xb822) == 0 ? 1 : -1];
-char g47[__builtin_parity(0xb823) == 1 ? 1 : -1];
-char g48[__builtin_parity(0xb824) == 0 ? 1 : -1];
-char g49[__builtin_parity(0xb825) == 1 ? 1 : -1];
-char g50[__builtin_parity(0xb826) == 1 ? 1 : -1];
-char g51[__builtin_parity(~0) == 0 ? 1 : -1];
-char g52[__builtin_parityl(1L << (BITSIZE(long) - 1)) == 1 ? 1 : -1];
-char g53[__builtin_parityll(1LL << (BITSIZE(long long) - 1)) == 1 ? 1 : -1];
+char parity1[__builtin_parity(0) == 0 ? 1 : -1];
+char parity2[__builtin_parity(0xb821) == 0 ? 1 : -1];
+char parity3[__builtin_parity(0xb822) == 0 ? 1 : -1];
+char parity4[__builtin_parity(0xb823) == 1 ? 1 : -1];
+char parity5[__builtin_parity(0xb824) == 0 ? 1 : -1];
+char parity6[__builtin_parity(0xb825) == 1 ? 1 : -1];
+char parity7[__builtin_parity(0xb826) == 1 ? 1 : -1];
+char parity8[__builtin_parity(~0) == 0 ? 1 : -1];
+char parity9[__builtin_parityl(1L << (BITSIZE(long) - 1)) == 1 ? 1 : -1];
+char parity10[__builtin_parityll(1LL << (BITSIZE(long long) - 1)) == 1 ? 1 : -1];
 
-char g54[__builtin_ffs(0) == 0 ? 1 : -1];
-char g55[__builtin_ffs(1) == 1 ? 1 : -1];
-char g56[__builtin_ffs(0xfbe71) == 1 ? 1 : -1];
-char g57[__builtin_ffs(0xfbe70) == 5 ? 1 : -1];
-char g58[__builtin_ffs(1U << (BITSIZE(int) - 1)) == BITSIZE(int) ? 1 : -1];
-char g59[__builtin_ffsl(0x10L) == 5 ? 1 : -1];
-char g60[__builtin_ffsll(0x100LL) == 9 ? 1 : -1];
+char ffs1[__builtin_ffs(0) == 0 ? 1 : -1];
+char ffs2[__builtin_ffs(1) == 1 ? 1 : -1];
+char ffs3[__builtin_ffs(0xfbe71) == 1 ? 1 : -1];
+char ffs4[__builtin_ffs(0xfbe70) == 5 ? 1 : -1];
+char ffs5[__builtin_ffs(1U << (BITSIZE(int) - 1)) == BITSIZE(int) ? 1 : -1];
+char ffs6[__builtin_ffsl(0x10L) == 5 ? 1 : -1];
+char ffs7[__builtin_ffsll(0x100LL) == 9 ? 1 : -1];
 #undef BITSIZE
 
 // GCC misc stuff
diff --git a/test/Sema/constructor-attribute.c b/test/Sema/constructor-attribute.c
index 3825916..1bb69fc 100644
--- a/test/Sema/constructor-attribute.c
+++ b/test/Sema/constructor-attribute.c
@@ -3,13 +3,13 @@
 int x __attribute__((constructor)); // expected-warning {{'constructor' attribute only applies to functions}}
 int f() __attribute__((constructor));
 int f() __attribute__((constructor(1)));
-int f() __attribute__((constructor(1,2))); // expected-error {{attribute takes no more than 1 argument}}
-int f() __attribute__((constructor(1.0))); // expected-error {{'constructor' attribute requires parameter 1 to be an integer constant}}
+int f() __attribute__((constructor(1,2))); // expected-error {{'constructor' attribute takes no more than 1 argument}}
+int f() __attribute__((constructor(1.0))); // expected-error {{'constructor' attribute requires an integer constant}}
 
 int x __attribute__((destructor)); // expected-warning {{'destructor' attribute only applies to functions}}
 int f() __attribute__((destructor));
 int f() __attribute__((destructor(1)));
-int f() __attribute__((destructor(1,2))); // expected-error {{attribute takes no more than 1 argument}}
-int f() __attribute__((destructor(1.0))); // expected-error {{'destructor' attribute requires parameter 1 to be an integer constant}}
+int f() __attribute__((destructor(1,2))); // expected-error {{'destructor' attribute takes no more than 1 argument}}
+int f() __attribute__((destructor(1.0))); // expected-error {{'destructor' attribute requires an integer constant}}
 
 
diff --git a/test/Sema/conversion.c b/test/Sema/conversion.c
index a591ac0..89c34c6 100644
--- a/test/Sema/conversion.c
+++ b/test/Sema/conversion.c
@@ -417,3 +417,15 @@
   si = si / sl;
   si = sl / si; // expected-warning {{implicit conversion loses integer precision: 'long' to 'int'}}
 }
+
+// rdar://16502418
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+typedef __attribute__ ((ext_vector_type(16),__aligned__(32))) uint16_t ushort16;
+typedef __attribute__ ((ext_vector_type( 8),__aligned__( 32))) uint32_t uint8;
+
+void test27(ushort16 constants) {
+    uint8 pairedConstants = (uint8) constants;
+    ushort16 crCbScale = pairedConstants.s4; // expected-warning {{implicit conversion loses integer precision: 'uint32_t' (aka 'unsigned int') to 'ushort16'}}
+    ushort16 brBias = pairedConstants.s6; // expected-warning {{implicit conversion loses integer precision: 'uint32_t' (aka 'unsigned int') to 'ushort16'}}
+}
diff --git a/test/Sema/crash-invalid-array.c b/test/Sema/crash-invalid-array.c
index eeac391..029413b 100644
--- a/test/Sema/crash-invalid-array.c
+++ b/test/Sema/crash-invalid-array.c
@@ -1,18 +1,16 @@
-// RUN: not %clang_cc1 -O1 %s -emit-llvm
+// RUN: %clang_cc1 -triple=x86_64-apple-darwin -fsyntax-only -verify %s
 // PR6913
 
-#include <stdio.h>
-
 int main()
 {
    int x[10][10];
-   int (*p)[] = x; // expected-error {{invalid use of array with unspecified bounds}
+   int (*p)[] = x;
 
    int i;
 
    for(i = 0; i < 10; ++i)
    {
-       p[i][i] = i;
+       p[i][i] = i; // expected-error {{subscript of pointer to incomplete type 'int []'}}
    }
 }
 
diff --git a/test/Sema/decl-in-prototype.c b/test/Sema/decl-in-prototype.c
index 05b8e0a..4f581aa 100644
--- a/test/Sema/decl-in-prototype.c
+++ b/test/Sema/decl-in-prototype.c
@@ -1,12 +1,12 @@
-// RUN: %clang_cc1_only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
 
 const int AA = 5;
 
-int f1(enum {AA,BB} E) {
+int f1(enum {AA,BB} E) { // expected-warning {{will not be visible outside of this function}}
     return BB;
 }
 
-int f2(enum {AA=7,BB} E) {
+int f2(enum {AA=7,BB} E) { // expected-warning {{will not be visible outside of this function}}
     return AA;
 }
 
@@ -31,3 +31,7 @@
     struct z d;
     d.b = 4;
 }
+
+void pr19018_1 (enum e19018 { qq } x); // expected-warning{{declaration of 'enum e19018' will not be visible outside of this function}}
+enum e19018 qq; //expected-error{{tentative definition has type 'enum e19018' that is never completed}} \
+                //expected-note{{forward declaration of 'enum e19018'}}
diff --git a/test/Sema/decl-invalid.c b/test/Sema/decl-invalid.c
index 0544304..c7ec6dd 100644
--- a/test/Sema/decl-invalid.c
+++ b/test/Sema/decl-invalid.c
@@ -24,5 +24,4 @@
 
 // rdar://6880449
 register int test1;     // expected-error {{illegal storage class on file-scoped variable}}
-register int test2 __asm__("edi");  // expected-error {{global register variables are not supported}}
 
diff --git a/test/Sema/dllexport.c b/test/Sema/dllexport.c
new file mode 100644
index 0000000..6c71ad8
--- /dev/null
+++ b/test/Sema/dllexport.c
@@ -0,0 +1,150 @@
+// RUN: %clang_cc1 -triple i686-win32     -fsyntax-only -verify -std=c99 %s
+// RUN: %clang_cc1 -triple x86_64-win32   -fsyntax-only -verify -std=c11 %s
+// RUN: %clang_cc1 -triple i686-mingw32   -fsyntax-only -verify -std=c11 %s
+// RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -verify -std=c99 %s
+
+// Invalid usage.
+__declspec(dllexport) typedef int typedef1; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
+typedef __declspec(dllexport) int typedef2; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
+typedef int __declspec(dllexport) typedef3; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
+typedef __declspec(dllexport) void (*FunTy)(); // expected-warning{{'dllexport' attribute only applies to variables and functions}}
+enum __declspec(dllexport) Enum { EnumVal }; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
+struct __declspec(dllexport) Record {}; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
+
+
+
+//===----------------------------------------------------------------------===//
+// Globals
+//===----------------------------------------------------------------------===//
+
+// Export declaration.
+__declspec(dllexport) extern int ExternGlobalDecl;
+
+// dllexport implies a definition.
+__declspec(dllexport) int GlobalDef;
+
+// Export definition.
+__declspec(dllexport) int GlobalInit1 = 1;
+int __declspec(dllexport) GlobalInit2 = 1;
+
+// Declare, then export definition.
+__declspec(dllexport) extern int GlobalDeclInit;
+int GlobalDeclInit = 1;
+
+// Redeclarations
+__declspec(dllexport) extern int GlobalRedecl1;
+__declspec(dllexport)        int GlobalRedecl1;
+
+__declspec(dllexport) extern int GlobalRedecl2;
+                             int GlobalRedecl2;
+
+                      extern int GlobalRedecl3; // expected-note{{previous declaration is here}}
+int useGlobalRedecl3() { return GlobalRedecl3; }
+__declspec(dllexport) extern int GlobalRedecl3; // expected-error{{redeclaration of 'GlobalRedecl3' cannot add 'dllexport' attribute}}
+
+                      extern int GlobalRedecl4; // expected-note{{previous declaration is here}}
+__declspec(dllexport) extern int GlobalRedecl4; // expected-warning{{redeclaration of 'GlobalRedecl4' should not add 'dllexport' attribute}}
+
+
+// External linkage is required.
+__declspec(dllexport) static int StaticGlobal; // expected-error{{'StaticGlobal' must have external linkage when declared 'dllexport'}}
+
+// Export in local scope.
+void functionScope() {
+  __declspec(dllexport)        int LocalVarDecl; // expected-error{{'LocalVarDecl' must have external linkage when declared 'dllexport'}}
+  __declspec(dllexport)        int LocalVarDef = 1; // expected-error{{'LocalVarDef' must have external linkage when declared 'dllexport'}}
+  __declspec(dllexport) extern int ExternLocalVarDecl;
+  __declspec(dllexport) static int StaticLocalVar; // expected-error{{'StaticLocalVar' must have external linkage when declared 'dllexport'}}
+}
+
+
+
+//===----------------------------------------------------------------------===//
+// Functions
+//===----------------------------------------------------------------------===//
+
+// Export function declaration. Check different placements.
+__attribute__((dllexport)) void decl1A(); // Sanity check with __attribute__
+__declspec(dllexport)      void decl1B();
+
+void __attribute__((dllexport)) decl2A();
+void __declspec(dllexport)      decl2B();
+
+// Export function definition.
+__declspec(dllexport) void def() {}
+
+// Export inline function.
+__declspec(dllexport) inline void inlineFunc1() {}
+extern void inlineFunc1();
+
+inline void __attribute__((dllexport)) inlineFunc2() {}
+extern void inlineFunc2();
+
+// Redeclarations
+__declspec(dllexport) void redecl1();
+__declspec(dllexport) void redecl1();
+
+__declspec(dllexport) void redecl2();
+                      void redecl2();
+
+__declspec(dllexport) void redecl3();
+                      void redecl3() {}
+
+                      void redecl4(); // expected-note{{previous declaration is here}}
+void useRedecl4() { redecl4(); }
+__declspec(dllexport) void redecl4(); // expected-error{{redeclaration of 'redecl4' cannot add 'dllexport' attribute}}
+
+                      void redecl5(); // expected-note{{previous declaration is here}}
+void useRedecl5() { redecl5(); }
+__declspec(dllexport) inline void redecl5() {} // expected-error{{redeclaration of 'redecl5' cannot add 'dllexport' attribute}}
+
+// Allow with a warning if the decl hasn't been used yet.
+                      void redecl6(); // expected-note{{previous declaration is here}}
+__declspec(dllexport) void redecl6(); // expected-warning{{redeclaration of 'redecl6' should not add 'dllexport' attribute}}
+
+
+// External linkage is required.
+__declspec(dllexport) static int staticFunc(); // expected-error{{'staticFunc' must have external linkage when declared 'dllexport'}}
+
+
+
+//===----------------------------------------------------------------------===//
+// Precedence
+//===----------------------------------------------------------------------===//
+
+// dllexport takes precedence over dllimport if both are specified.
+__attribute__((dllimport, dllexport))       extern int PrecedenceExternGlobal1A; // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllimport) __declspec(dllexport) extern int PrecedenceExternGlobal1B; // expected-warning{{'dllimport' attribute ignored}}
+
+__attribute__((dllexport, dllimport))       extern int PrecedenceExternGlobal2A; // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllexport) __declspec(dllimport) extern int PrecedenceExternGlobal2B; // expected-warning{{'dllimport' attribute ignored}}
+
+__attribute__((dllimport, dllexport))       int PrecedenceGlobal1A; // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllimport) __declspec(dllexport) int PrecedenceGlobal1B; // expected-warning{{'dllimport' attribute ignored}}
+
+__attribute__((dllexport, dllimport))       int PrecedenceGlobal2A; // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllexport) __declspec(dllimport) int PrecedenceGlobal2B; // expected-warning{{'dllimport' attribute ignored}}
+
+__declspec(dllexport) extern int PrecedenceExternGlobalRedecl1;
+__declspec(dllimport) extern int PrecedenceExternGlobalRedecl1; // expected-warning{{'dllimport' attribute ignored}}
+
+__declspec(dllimport) extern int PrecedenceExternGlobalRedecl2; // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllexport) extern int PrecedenceExternGlobalRedecl2;
+
+__declspec(dllexport) extern int PrecedenceGlobalRedecl1;
+__declspec(dllimport)        int PrecedenceGlobalRedecl1; // expected-warning{{'dllimport' attribute ignored}}
+
+__declspec(dllimport) extern int PrecedenceGlobalRedecl2; // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllexport)        int PrecedenceGlobalRedecl2;
+
+void __attribute__((dllimport, dllexport))       precedence1A() {} // expected-warning{{'dllimport' attribute ignored}}
+void __declspec(dllimport) __declspec(dllexport) precedence1B() {} // expected-warning{{'dllimport' attribute ignored}}
+
+void __attribute__((dllexport, dllimport))       precedence2A() {} // expected-warning{{'dllimport' attribute ignored}}
+void __declspec(dllexport) __declspec(dllimport) precedence2B() {} // expected-warning{{'dllimport' attribute ignored}}
+
+void __declspec(dllimport) precedenceRedecl1(); // expected-warning{{'dllimport' attribute ignored}}
+void __declspec(dllexport) precedenceRedecl1() {}
+
+void __declspec(dllexport) precedenceRedecl2();
+void __declspec(dllimport) precedenceRedecl2() {} // expected-warning{{'dllimport' attribute ignored}}
diff --git a/test/Sema/dllimport-dllexport.c b/test/Sema/dllimport-dllexport.c
deleted file mode 100644
index 80810d6..0000000
--- a/test/Sema/dllimport-dllexport.c
+++ /dev/null
@@ -1,48 +0,0 @@
-// RUN: %clang_cc1 -triple i386-mingw32 -fsyntax-only -verify %s
-// RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -verify %s
-
-inline void __attribute__((dllexport)) foo1(){} // expected-warning{{dllexport attribute ignored}}
-inline void __attribute__((dllimport)) foo2(){} // expected-warning{{dllimport attribute ignored}}
-
-void __attribute__((dllimport)) foo3(){} // expected-error{{dllimport attribute can be applied only to symbol declaration}}
-
-void __attribute__((dllimport, dllexport)) foo4(); // expected-warning{{dllimport attribute ignored}}
-
-void __attribute__((dllexport)) foo5();
-void __attribute__((dllimport)) foo5(); // expected-warning{{dllimport attribute ignored}}
-
-typedef int __attribute__((dllexport)) type6; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
-
-typedef int __attribute__((dllimport)) type7; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
-
-void __attribute__((dllimport)) foo6();
-void foo6(){} // expected-warning {{'foo6' redeclared without dllimport attribute: previous dllimport ignored}}
-
-// PR6269
-inline void __declspec(dllexport) foo7(){} // expected-warning{{dllexport attribute ignored}}
-inline void __declspec(dllimport) foo8(){} // expected-warning{{dllimport attribute ignored}}
-
-void __declspec(dllimport) foo9(){} // expected-error{{dllimport attribute can be applied only to symbol declaration}}
-
-void __declspec(dllimport) __declspec(dllexport) foo10(); // expected-warning{{dllimport attribute ignored}}
-
-void __declspec(dllexport) foo11();
-void __declspec(dllimport) foo11(); // expected-warning{{dllimport attribute ignored}}
-
-typedef int __declspec(dllexport) type1; // expected-warning{{'dllexport' attribute only applies to variables and functions}}
-
-typedef int __declspec(dllimport) type2; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
-
-void __declspec(dllimport) foo12();
-void foo12(){} // expected-warning {{'foo12' redeclared without dllimport attribute: previous dllimport ignored}}
-
-void __attribute__((dllimport)) foo13(); // expected-warning{{dllimport attribute ignored}}
-void __attribute__((dllexport)) foo13();
-
-extern int foo14 __attribute__((dllexport));
-extern int foo14 __attribute__((dllimport));  // expected-warning{{dllimport attribute ignored}}
-
-__declspec(dllimport) int foo15 = 54; // expected-warning{{'dllimport' attribute cannot be specified on a definition}}
-
-extern __declspec(dllimport) int foo17;
-int foo17 = 54; // expected-warning{{'dllimport' attribute cannot be specified on a definition}}
diff --git a/test/Sema/dllimport.c b/test/Sema/dllimport.c
new file mode 100644
index 0000000..706b0b6
--- /dev/null
+++ b/test/Sema/dllimport.c
@@ -0,0 +1,150 @@
+// RUN: %clang_cc1 -triple i686-win32     -fsyntax-only -verify -std=c99 %s
+// RUN: %clang_cc1 -triple x86_64-win32   -fsyntax-only -verify -std=c11 %s
+// RUN: %clang_cc1 -triple i686-mingw32   -fsyntax-only -verify -std=c11 %s
+// RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -verify -std=c99 %s
+
+// Invalid usage.
+__declspec(dllimport) typedef int typedef1; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
+typedef __declspec(dllimport) int typedef2; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
+typedef int __declspec(dllimport) typedef3; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
+typedef __declspec(dllimport) void (*FunTy)(); // expected-warning{{'dllimport' attribute only applies to variables and functions}}
+enum __declspec(dllimport) Enum { EnumVal }; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
+struct __declspec(dllimport) Record {}; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
+
+
+
+//===----------------------------------------------------------------------===//
+// Globals
+//===----------------------------------------------------------------------===//
+
+// Import declaration.
+__declspec(dllimport) extern int ExternGlobalDecl;
+
+// dllimport implies a declaration.
+__declspec(dllimport) int GlobalDecl;
+int **__attribute__((dllimport))* GlobalDeclChunkAttr;
+int GlobalDeclAttr __attribute__((dllimport));
+
+// Address of variables can't be used for initialization in C language modes.
+int *VarForInit = &GlobalDecl; // expected-error{{initializer element is not a compile-time constant}}
+
+// Not allowed on definitions.
+__declspec(dllimport) extern int ExternGlobalInit = 1; // expected-error{{definition of dllimport data}}
+__declspec(dllimport) int GlobalInit1 = 1; // expected-error{{definition of dllimport data}}
+int __declspec(dllimport) GlobalInit2 = 1; // expected-error{{definition of dllimport data}}
+
+// Declare, then reject definition.
+__declspec(dllimport) extern int ExternGlobalDeclInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+int ExternGlobalDeclInit = 1; // expected-warning{{'ExternGlobalDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+__declspec(dllimport) int GlobalDeclInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+int GlobalDeclInit = 1; // expected-warning{{'GlobalDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+int *__attribute__((dllimport)) GlobalDeclChunkAttrInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+int *GlobalDeclChunkAttrInit = 0; // expected-warning{{'GlobalDeclChunkAttrInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+int GlobalDeclAttrInit __attribute__((dllimport)); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+int GlobalDeclAttrInit = 1; // expected-warning{{'GlobalDeclAttrInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+// Redeclarations
+__declspec(dllimport) extern int GlobalRedecl1;
+__declspec(dllimport) extern int GlobalRedecl1;
+
+__declspec(dllimport) int GlobalRedecl2a;
+__declspec(dllimport) int GlobalRedecl2a;
+
+int *__attribute__((dllimport)) GlobalRedecl2b;
+int *__attribute__((dllimport)) GlobalRedecl2b;
+
+int GlobalRedecl2c __attribute__((dllimport));
+int GlobalRedecl2c __attribute__((dllimport));
+
+// NB: MSVC issues a warning and makes GlobalRedecl3 dllexport. We follow GCC
+// and drop the dllimport with a warning.
+__declspec(dllimport) extern int GlobalRedecl3; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+                      extern int GlobalRedecl3; // expected-warning{{'GlobalRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+// Adding an attribute on redeclaration.
+                      extern int GlobalRedecl4; // expected-note{{previous declaration is here}}
+int useGlobalRedecl4() { return GlobalRedecl4; }
+__declspec(dllimport) extern int GlobalRedecl4; // expected-error{{redeclaration of 'GlobalRedecl4' cannot add 'dllimport' attribute}}
+
+// Allow with a warning if the decl hasn't been used yet.
+                      extern int GlobalRedecl5; // expected-note{{previous declaration is here}}
+__declspec(dllimport) extern int GlobalRedecl5; // expected-warning{{redeclaration of 'GlobalRedecl5' should not add 'dllimport' attribute}}
+
+
+// External linkage is required.
+__declspec(dllimport) static int StaticGlobal; // expected-error{{'StaticGlobal' must have external linkage when declared 'dllimport'}}
+
+// Import in local scope.
+__declspec(dllimport) float LocalRedecl1; // expected-note{{previous definition is here}}
+__declspec(dllimport) float LocalRedecl2; // expected-note{{previous definition is here}}
+__declspec(dllimport) float LocalRedecl3; // expected-note{{previous definition is here}}
+void functionScope() {
+  __declspec(dllimport) int LocalRedecl1; // expected-error{{redefinition of 'LocalRedecl1' with a different type: 'int' vs 'float'}}
+  int *__attribute__((dllimport)) LocalRedecl2; // expected-error{{redefinition of 'LocalRedecl2' with a different type: 'int *' vs 'float'}}
+  int LocalRedecl3 __attribute__((dllimport)); // expected-error{{redefinition of 'LocalRedecl3' with a different type: 'int' vs 'float'}}
+
+  __declspec(dllimport)        int LocalVarDecl;
+  __declspec(dllimport)        int LocalVarDef = 1; // expected-error{{definition of dllimport data}}
+  __declspec(dllimport) extern int ExternLocalVarDecl;
+  __declspec(dllimport) extern int ExternLocalVarDef = 1; // expected-error{{definition of dllimport data}}
+  __declspec(dllimport) static int StaticLocalVar; // expected-error{{'StaticLocalVar' must have external linkage when declared 'dllimport'}}
+}
+
+
+
+//===----------------------------------------------------------------------===//
+// Functions
+//===----------------------------------------------------------------------===//
+
+// Import function declaration. Check different placements.
+__attribute__((dllimport)) void decl1A(); // Sanity check with __attribute__
+__declspec(dllimport)      void decl1B();
+
+void __attribute__((dllimport)) decl2A();
+void __declspec(dllimport)      decl2B();
+
+// Address of functions can be used for initialization in C language modes.
+// However, the address of the thunk wrapping the function is used instead of
+// the address in the import address table.
+void (*FunForInit)() = &decl2A;
+
+// Not allowed on function definitions.
+__declspec(dllimport) void def() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
+
+// Import inline function.
+__declspec(dllimport) inline void inlineFunc1() {}
+inline void __attribute__((dllimport)) inlineFunc2() {}
+
+// Redeclarations
+__declspec(dllimport) void redecl1();
+__declspec(dllimport) void redecl1();
+
+// NB: MSVC issues a warning and makes redecl2/redecl3 dllexport. We follow GCC
+// and drop the dllimport with a warning.
+__declspec(dllimport) void redecl2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+                      void redecl2(); // expected-warning{{'redecl2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+__declspec(dllimport) void redecl3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+                      void redecl3() {} // expected-warning{{'redecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+                      void redecl4(); // expected-note{{previous declaration is here}}
+void useRedecl4() { redecl4(); }
+__declspec(dllimport) void redecl4(); // expected-error{{redeclaration of 'redecl4' cannot add 'dllimport' attribute}}
+
+// Allow with a warning if the decl hasn't been used yet.
+                      void redecl5(); // expected-note{{previous declaration is here}}
+__declspec(dllimport) void redecl5(); // expected-warning{{redeclaration of 'redecl5' should not add 'dllimport' attribute}}
+
+
+// Inline redeclarations are fine.
+__declspec(dllimport) void redecl6();
+                      inline void redecl6() {}
+
+                      void redecl7(); // expected-note{{previous declaration is here}}
+__declspec(dllimport) inline void redecl7() {} // expected-warning{{redeclaration of 'redecl7' should not add 'dllimport' attribute}}
+
+// External linkage is required.
+__declspec(dllimport) static int staticFunc(); // expected-error{{'staticFunc' must have external linkage when declared 'dllimport'}}
diff --git a/test/Sema/empty1.c b/test/Sema/empty1.c
index de922f7..9a2fb67 100644
--- a/test/Sema/empty1.c
+++ b/test/Sema/empty1.c
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 %s -fsyntax-only -verify -Wc++-compat
+// RUN: %clang_cc1 %s -triple %itanium_abi_triple -fsyntax-only -verify -Wc++-compat
+
+// Note: Empty C structs are 4 bytes in the Microsoft ABI.
 
 struct emp_1 { // expected-warning {{empty struct has size 0 in C, size 1 in C++}}
 };
diff --git a/test/Sema/enable_if.c b/test/Sema/enable_if.c
new file mode 100644
index 0000000..a3c4323
--- /dev/null
+++ b/test/Sema/enable_if.c
@@ -0,0 +1,97 @@
+// RUN: %clang_cc1 %s -verify
+// RUN: %clang_cc1 %s -DCODEGEN -emit-llvm -o - | FileCheck %s
+
+#define O_CREAT 0x100
+typedef int mode_t;
+typedef unsigned long size_t;
+
+int open(const char *pathname, int flags) __attribute__((enable_if(!(flags & O_CREAT), "must specify mode when using O_CREAT"))) __attribute__((overloadable));  // expected-note{{candidate disabled: must specify mode when using O_CREAT}}
+int open(const char *pathname, int flags, mode_t mode) __attribute__((overloadable));  // expected-note{{candidate function not viable: requires 3 arguments, but 2 were provided}}
+
+void test1() {
+#ifndef CODEGEN
+  open("path", O_CREAT);  // expected-error{{no matching function for call to 'open'}}
+#endif
+  open("path", O_CREAT, 0660);
+  open("path", 0);
+  open("path", 0, 0);
+}
+
+size_t __strnlen_chk(const char *s, size_t requested_amount, size_t s_len);
+
+size_t strnlen(const char *s, size_t maxlen)  // expected-note{{candidate function}}
+  __attribute__((overloadable))
+  __asm__("strnlen_real1");
+
+__attribute__((always_inline))
+inline size_t strnlen(const char *s, size_t maxlen)  // expected-note{{candidate function}}
+  __attribute__((overloadable))
+  __attribute__((enable_if(__builtin_object_size(s, 0) != -1,
+                           "chosen when target buffer size is known")))
+{
+  return __strnlen_chk(s, maxlen, __builtin_object_size(s, 0));
+}
+
+size_t strnlen(const char *s, size_t maxlen)  // expected-note{{candidate disabled: chosen when 'maxlen' is known to be less than or equal to the buffer size}}
+  __attribute__((overloadable))
+  __attribute__((enable_if(__builtin_object_size(s, 0) != -1,
+                           "chosen when target buffer size is known")))
+  __attribute__((enable_if(maxlen <= __builtin_object_size(s, 0),
+                           "chosen when 'maxlen' is known to be less than or equal to the buffer size")))
+  __asm__("strnlen_real2");
+
+size_t strnlen(const char *s, size_t maxlen)  // expected-note{{candidate function has been explicitly made unavailable}}
+  __attribute__((overloadable))
+  __attribute__((enable_if(__builtin_object_size(s, 0) != -1,
+                           "chosen when target buffer size is known")))
+  __attribute__((enable_if(maxlen > __builtin_object_size(s, 0),
+                           "chosen when 'maxlen' is larger than the buffer size")))
+  __attribute__((unavailable("'maxlen' is larger than the buffer size")));
+
+void test2(const char *s, int i) {
+// CHECK: define void @test2
+  const char c[123];
+  strnlen(s, i);
+// CHECK: call {{.*}}strnlen_real1
+  strnlen(s, 999);
+// CHECK: call {{.*}}strnlen_real1
+  strnlen(c, 1);
+// CHECK: call {{.*}}strnlen_real2
+  strnlen(c, i);
+// CHECK: call {{.*}}strnlen_chk
+#ifndef CODEGEN
+  strnlen(c, 999);  // expected-error{{call to unavailable function 'strnlen': 'maxlen' is larger than the buffer size}}
+#endif
+}
+
+int isdigit(int c) __attribute__((overloadable));  // expected-note{{candidate function}}
+int isdigit(int c) __attribute__((overloadable))  // expected-note{{candidate function has been explicitly made unavailable}}
+  __attribute__((enable_if(c <= -1 || c > 255, "'c' must have the value of an unsigned char or EOF")))
+  __attribute__((unavailable("'c' must have the value of an unsigned char or EOF")));
+
+void test3(int c) {
+  isdigit(c);
+  isdigit(10);
+#ifndef CODEGEN
+  isdigit(-10);  // expected-error{{call to unavailable function 'isdigit': 'c' must have the value of an unsigned char or EOF}}
+#endif
+}
+
+#ifndef CODEGEN
+__attribute__((enable_if(n == 0, "chosen when 'n' is zero"))) void f1(int n); // expected-error{{use of undeclared identifier 'n'}}
+
+int n __attribute__((enable_if(1, "always chosen"))); // expected-warning{{'enable_if' attribute only applies to functions}}
+
+void f(int n) __attribute__((enable_if("chosen when 'n' is zero", n == 0)));  // expected-error{{'enable_if' attribute requires a string}}
+
+void f(int n) __attribute__((enable_if()));  // expected-error{{'enable_if' attribute requires exactly 2 arguments}}
+
+void f(int n) __attribute__((enable_if(unresolvedid, "chosen when 'unresolvedid' is non-zero")));  // expected-error{{use of undeclared identifier 'unresolvedid'}}
+
+int global;
+void f(int n) __attribute__((enable_if(global == 0, "chosen when 'global' is zero")));  // expected-error{{'enable_if' attribute expression never produces a constant expression}}  // expected-note{{subexpression not valid in a constant expression}}
+
+const int cst = 7;
+void return_cst(void) __attribute__((overloadable)) __attribute__((enable_if(cst == 7, "chosen when 'cst' is 7")));
+void test_return_cst() { return_cst(); }
+#endif
diff --git a/test/Sema/ext_vector_casts.c b/test/Sema/ext_vector_casts.c
index 66004b0..949d673 100644
--- a/test/Sema/ext_vector_casts.c
+++ b/test/Sema/ext_vector_casts.c
@@ -1,6 +1,7 @@
-// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -fsyntax-only -verify -fno-lax-vector-conversions %s
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -fsyntax-only -verify -fno-lax-vector-conversions -Wconversion %s
 
 typedef __attribute__(( ext_vector_type(2) )) float float2;
+typedef __attribute__(( ext_vector_type(3) )) float float3;
 typedef __attribute__(( ext_vector_type(4) )) int int4;
 typedef __attribute__(( ext_vector_type(8) )) short short8;
 typedef __attribute__(( ext_vector_type(4) )) float float4;
@@ -11,12 +12,16 @@
 
 static void test() {
     float2 vec2;
+    float3 vec3;
     float4 vec4, vec4_2;
     int4 ivec4;
     short8 ish8;
     t3 vec4_3;
     int *ptr;
     int i;
+
+    vec3 += vec2; // expected-error {{can't convert between vector values of different size}}
+    vec4 += vec3; // expected-error {{can't convert between vector values of different size}}
     
     vec4 = 5.0f;
     vec4 = (float4)5.0f;
@@ -27,31 +32,30 @@
     ivec4 = (int4)5;
     ivec4 = (int4)vec4_3;
     
-    i = (int)ivec4; // expected-error {{invalid conversion between vector type 'int4' and integer type 'int' of different size}}
-    i = ivec4; // expected-error {{assigning to 'int' from incompatible type 'int4'}}
+    i = (int)ivec4; // expected-error {{invalid conversion between vector type 'int4' (vector of 4 'int' values) and integer type 'int' of different size}}
+    i = ivec4; // expected-error {{assigning to 'int' from incompatible type 'int4' (vector of 4 'int' values)}}
     
-    ivec4 = (int4)ptr; // expected-error {{invalid conversion between vector type 'int4' and scalar type 'int *'}}
+    ivec4 = (int4)ptr; // expected-error {{invalid conversion between vector type 'int4' (vector of 4 'int' values) and scalar type 'int *'}}
     
-    vec4 = (float4)vec2; // expected-error {{invalid conversion between ext-vector type 'float4' and 'float2'}}
-    
-    ish8 += 5; // expected-error {{can't convert between vector values of different size ('short8' and 'int')}}
-    ish8 += (short)5;
+    vec4 = (float4)vec2; // expected-error {{invalid conversion between ext-vector type 'float4' (vector of 4 'float' values) and 'float2' (vector of 2 'float' values)}}
+  
+    ish8 += 5;
     ivec4 *= 5;
      vec4 /= 5.2f;
-     vec4 %= 4; // expected-error {{invalid operands to binary expression ('float4' and 'int')}}
+     vec4 %= 4; // expected-error {{invalid operands to binary expression ('float4' (vector of 4 'float' values) and 'int')}}
     ivec4 %= 4;
-    ivec4 += vec4; // expected-error {{can't convert between vector values of different size ('int4' and 'float4')}}
+    ivec4 += vec4; // expected-error {{can't convert between vector values of different size ('int4' (vector of 4 'int' values) and 'float4' (vector of 4 'float' values))}}
     ivec4 += (int4)vec4;
     ivec4 -= ivec4;
     ivec4 |= ivec4;
-    ivec4 += ptr; // expected-error {{can't convert between vector values of different size ('int4' and 'int *')}}
+    ivec4 += ptr; // expected-error {{can't convert between vector and non-scalar values ('int4' (vector of 4 'int' values) and 'int *')}}
 }
 
-typedef __attribute__(( ext_vector_type(2) )) float2 vecfloat2; // expected-error{{invalid vector element type 'float2'}}
+typedef __attribute__(( ext_vector_type(2) )) float2 vecfloat2; // expected-error{{invalid vector element type 'float2' (vector of 2 'float' values)}}
 
 void inc(float2 f2) {
-  f2++; // expected-error{{cannot increment value of type 'float2'}}
-  __real f2; // expected-error{{invalid type 'float2' to __real operator}}
+  f2++; // expected-error{{cannot increment value of type 'float2' (vector of 2 'float' values)}}
+  __real f2; // expected-error{{invalid type 'float2' (vector of 2 'float' values) to __real operator}}
 }
 
 typedef enum
@@ -74,3 +78,47 @@
     return stride;
 }
 
+// rdar://16196902
+typedef __attribute__((ext_vector_type(4))) float float32x4_t;
+
+typedef float C3DVector3 __attribute__((ext_vector_type(3)));
+
+extern float32x4_t vabsq_f32(float32x4_t __a);
+
+C3DVector3 Func(const C3DVector3 a) {
+    return (C3DVector3)vabsq_f32((float32x4_t)a); // expected-error {{invalid conversion between ext-vector type 'float32x4_t' (vector of 4 'float' values) and 'C3DVector3' (vector of 3 'float' values)}}
+}
+
+// rdar://16350802
+typedef double double2 __attribute__ ((ext_vector_type(2)));
+
+static void splats(int i, long l, __uint128_t t, float f, double d) {
+  short8 vs = 0;
+  int4 vi = i;
+  ulong2 vl = (unsigned long)l;
+  float2 vf = f;
+  double2 vd = d;
+  
+  vs = 65536 + vs; // expected-warning {{implicit conversion from 'int' to 'short8' (vector of 8 'short' values) changes value from 65536 to 0}}
+  vs = vs + i; // expected-warning {{implicit conversion loses integer precision}}
+  vs = vs + 1;
+  vs = vs + 1.f; // expected-error {{can't convert between vector values of different size}}
+  
+  vi = l + vi; // expected-warning {{implicit conversion loses integer precision}}
+  vi = 1 + vi;
+  vi = vi + 2.0; // expected-error {{can't convert between vector values of different size}}
+  vi = vi + 0xffffffff; // expected-warning {{implicit conversion changes signedness}}
+  
+  vl = l + vl; // expected-warning {{implicit conversion changes signedness}}
+  vl = vl + t; // expected-warning {{implicit conversion loses integer precision}}
+  
+  vf = 1 + vf;
+  vf = l + vf;
+  vf = 2.0 + vf;
+  vf = d + vf; // expected-warning {{implicit conversion loses floating-point precision}}
+  vf = vf + 0xffffffff;
+  vf = vf + 2.1; // expected-warning {{implicit conversion loses floating-point precision}}
+  
+  vd = l + vd;
+  vd = vd + t;
+}
diff --git a/test/Sema/fn-ptr-as-fn-prototype.c b/test/Sema/fn-ptr-as-fn-prototype.c
index cf95c97..4b01b13 100644
--- a/test/Sema/fn-ptr-as-fn-prototype.c
+++ b/test/Sema/fn-ptr-as-fn-prototype.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1_only -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -ast-print %s | FileCheck %s
 
 // This testcase checks the functionality of 
 // Sema::ActOn{Start,End}FunctionDeclarator, specifically checking that
diff --git a/test/Sema/format-strings-c90.c b/test/Sema/format-strings-c90.c
index 66ca507..874d33e 100644
--- a/test/Sema/format-strings-c90.c
+++ b/test/Sema/format-strings-c90.c
@@ -1,4 +1,4 @@
-/* RUN: %clang_cc1 -fsyntax-only -verify -triple i386-apple-darwin9 -pedantic -std=c89 %s
+/* RUN: %clang_cc1 -fsyntax-only -verify -triple i386-apple-darwin9 -Wformat-non-iso -std=c89 %s
  */
 
 int scanf(const char * restrict, ...);
diff --git a/test/Sema/format-strings-darwin.c b/test/Sema/format-strings-darwin.c
index 5daf3e5..46e717e 100644
--- a/test/Sema/format-strings-darwin.c
+++ b/test/Sema/format-strings-darwin.c
@@ -1,11 +1,11 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -triple i386-apple-darwin9 -pedantic -DALLOWED %s
-// RUN: %clang_cc1 -fsyntax-only -verify -triple thumbv6-apple-ios4.0 -pedantic -DALLOWED %s
+// RUN: %clang_cc1 -fsyntax-only -verify -triple i386-apple-darwin9 -Wformat-non-iso -DALLOWED %s
+// RUN: %clang_cc1 -fsyntax-only -verify -triple thumbv6-apple-ios4.0 -Wformat-non-iso -DALLOWED %s
 
-// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-mingw32 -pedantic %s
-// RUN: %clang_cc1 -fsyntax-only -verify -triple i686-pc-win32 -pedantic %s
+// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-mingw32 -Wformat-non-iso %s
+// RUN: %clang_cc1 -fsyntax-only -verify -triple i686-pc-win32 -Wformat-non-iso %s
 
-// RUN: %clang_cc1 -fsyntax-only -verify -triple i686-linux-gnu -pedantic %s
-// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-unknown-freebsd -pedantic %s
+// RUN: %clang_cc1 -fsyntax-only -verify -triple i686-linux-gnu -Wformat-non-iso %s
+// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-unknown-freebsd -Wformat-non-iso %s
 
 int printf(const char *restrict, ...);
 int scanf(const char * restrict, ...) ;
diff --git a/test/Sema/format-strings-enum-fixed-type.cpp b/test/Sema/format-strings-enum-fixed-type.cpp
index 8b6b237..0022ccb 100644
--- a/test/Sema/format-strings-enum-fixed-type.cpp
+++ b/test/Sema/format-strings-enum-fixed-type.cpp
@@ -16,7 +16,7 @@
 // This is why we don't check for that in the expected output.
 
 void test(TestEnum input) {
-  printf("%hhd", input); // expected-warning{{format specifies type 'char' but the argument has type 'TestEnum'}}
+  printf("%hhd", input); // expected-warning{{format specifies type 'char' but the argument has underlying type 'short'}}
   printf("%hhd", Constant); // expected-warning{{format specifies type 'char'}}
   
   printf("%hd", input); // no-warning
@@ -26,7 +26,7 @@
   printf("%d", input); // no-warning
   printf("%d", Constant); // no-warning
   
-  printf("%lld", input); // expected-warning{{format specifies type 'long long' but the argument has type 'TestEnum'}}
+  printf("%lld", input); // expected-warning{{format specifies type 'long long' but the argument has underlying type 'short'}}
   printf("%lld", Constant); // expected-warning{{format specifies type 'long long'}}
 }
 
@@ -34,7 +34,7 @@
 typedef enum : unsigned long { LongConstant = ~0UL } LongEnum;
 
 void testLong(LongEnum input) {
-  printf("%u", input); // expected-warning{{format specifies type 'unsigned int' but the argument has type 'LongEnum'}}
+  printf("%u", input); // expected-warning{{format specifies type 'unsigned int' but the argument has underlying type 'unsigned long'}}
   printf("%u", LongConstant); // expected-warning{{format specifies type 'unsigned int'}}
   
   printf("%lu", input);
@@ -46,7 +46,7 @@
 typedef enum : short_t { ShortConstant = 0 } ShortEnum;
 
 void testUnderlyingTypedef(ShortEnum input) {
-  printf("%hhd", input); // expected-warning{{format specifies type 'char' but the argument has type 'ShortEnum'}}
+  printf("%hhd", input); // expected-warning{{format specifies type 'char' but the argument has underlying type 'short_t' (aka 'short')}}
   printf("%hhd", ShortConstant); // expected-warning{{format specifies type 'char'}}
   
   printf("%hd", input); // no-warning
@@ -56,7 +56,7 @@
   printf("%d", input); // no-warning
   printf("%d", ShortConstant); // no-warning
   
-  printf("%lld", input); // expected-warning{{format specifies type 'long long' but the argument has type 'ShortEnum'}}
+  printf("%lld", input); // expected-warning{{format specifies type 'long long' but the argument has underlying type 'short_t' (aka 'short')}}
   printf("%lld", ShortConstant); // expected-warning{{format specifies type 'long long'}}
 }
 
@@ -64,10 +64,10 @@
 typedef ShortEnum ShortEnum2;
 
 void testTypedefChain(ShortEnum2 input) {
-  printf("%hhd", input); // expected-warning{{format specifies type 'char' but the argument has type 'ShortEnum2' (aka 'ShortEnum')}}
+  printf("%hhd", input); // expected-warning{{format specifies type 'char' but the argument has underlying type 'short_t' (aka 'short')}}
   printf("%hd", input); // no-warning
   printf("%d", input); // no-warning
-  printf("%lld", input); // expected-warning{{format specifies type 'long long' but the argument has type 'ShortEnum2' (aka 'ShortEnum')}}
+  printf("%lld", input); // expected-warning{{format specifies type 'long long' but the argument has underlying type 'short_t' (aka 'short')}}
 }
 
 
@@ -80,13 +80,13 @@
   printf("%hhd", CharConstant); // no-warning
 
   // This is not correct but it is safe. We warn because '%hd' shows intent.
-  printf("%hd", input); // expected-warning{{format specifies type 'short' but the argument has type 'CharEnum'}}
+  printf("%hd", input); // expected-warning{{format specifies type 'short' but the argument has underlying type 'char'}}
   printf("%hd", CharConstant); // expected-warning{{format specifies type 'short'}}
   
   // This is not correct but it matches the promotion rules (and is safe).
   printf("%d", input); // no-warning
   printf("%d", CharConstant); // no-warning
   
-  printf("%lld", input); // expected-warning{{format specifies type 'long long' but the argument has type 'CharEnum'}}
+  printf("%lld", input); // expected-warning{{format specifies type 'long long' but the argument has underlying type 'char'}}
   printf("%lld", CharConstant); // expected-warning{{format specifies type 'long long'}}
 }
diff --git a/test/Sema/format-strings-enum.c b/test/Sema/format-strings-enum.c
index a6c27d0..e79f859 100644
--- a/test/Sema/format-strings-enum.c
+++ b/test/Sema/format-strings-enum.c
@@ -20,7 +20,7 @@
     printf("%d", input); // no-warning
     printf("%d", Constant); // no-warning
 
-    printf("%lld", input); // expected-warning{{format specifies type 'long long' but the argument has type 'TestEnum'}}
+    printf("%lld", input); // expected-warning-re{{format specifies type 'long long' but the argument has underlying type '{{(unsigned)?}} int'}}
     printf("%lld", Constant); // expected-warning{{format specifies type 'long long'}}
 }
 
@@ -28,7 +28,7 @@
 typedef enum { LongConstant = ~0UL } LongEnum;
 
 void testLong(LongEnum input) {
-  printf("%u", input); // expected-warning{{format specifies type 'unsigned int' but the argument has type 'LongEnum'}}
+  printf("%u", input); // expected-warning{{format specifies type 'unsigned int' but the argument has underlying type}}
   printf("%u", LongConstant); // expected-warning{{format specifies type 'unsigned int'}}
   
   printf("%lu", input);
diff --git a/test/Sema/format-strings-fixit.c b/test/Sema/format-strings-fixit.c
index 3127418..b982eb4 100644
--- a/test/Sema/format-strings-fixit.c
+++ b/test/Sema/format-strings-fixit.c
@@ -14,6 +14,7 @@
 typedef __INTMAX_TYPE__ intmax_t;
 typedef __UINTMAX_TYPE__ uintmax_t;
 typedef __PTRDIFF_TYPE__ ptrdiff_t;
+typedef __WCHAR_TYPE__ wchar_t;
 
 void test() {
   // Basic types
@@ -97,11 +98,13 @@
 
 int scanf(char const *, ...);
 
-void test2() {
+void test2(int intSAParm[static 2]) {
   char str[100];
+  char *vstr = "abc";
   short shortVar;
   unsigned short uShortVar;
   int intVar;
+  int intAVar[2];
   unsigned uIntVar;
   float floatVar;
   double doubleVar;
@@ -114,11 +117,20 @@
   intmax_t intmaxVar;
   uintmax_t uIntmaxVar;
   ptrdiff_t ptrdiffVar;
+  enum {A, B, C} enumVar;
 
+  // Some string types.
   scanf("%lf", str);
+  scanf("%lf", vstr);
+  scanf("%ls", str);
+  scanf("%ls", str);
+
+  // Some integer types.
   scanf("%f", &shortVar);
   scanf("%f", &uShortVar);
   scanf("%p", &intVar);
+  scanf("%f", intAVar);
+  scanf("%f", intSAParm);
   scanf("%Lf", &uIntVar);
   scanf("%ld", &floatVar);
   scanf("%f", &doubleVar);
@@ -127,6 +139,7 @@
   scanf("%f", &uLongVar);
   scanf("%f", &longLongVar);
   scanf("%f", &uLongLongVar);
+  scanf("%d", &enumVar); // FIXME: We ought to fix specifiers for enums.
 
   // Some named ints.
   scanf("%f", &sizeVar);
@@ -206,10 +219,15 @@
 // CHECK: printf("%La", (long double) 42);
 // CHECK: printf("%LA", (long double) 42);
 
-// CHECK: scanf("%s", str);
+// CHECK: scanf("%99s", str);
+// CHECK: scanf("%s", vstr);
+// CHECK: scanf("%99s", str);
+// CHECK: scanf("%99s", str);
 // CHECK: scanf("%hd", &shortVar);
 // CHECK: scanf("%hu", &uShortVar);
 // CHECK: scanf("%d", &intVar);
+// CHECK: scanf("%d", intAVar);
+// CHECK: scanf("%d", intSAParm);
 // CHECK: scanf("%u", &uIntVar);
 // CHECK: scanf("%f", &floatVar);
 // CHECK: scanf("%lf", &doubleVar);
@@ -218,6 +236,7 @@
 // CHECK: scanf("%lu", &uLongVar);
 // CHECK: scanf("%lld", &longLongVar);
 // CHECK: scanf("%llu", &uLongLongVar);
+// CHECK: scanf("%d", &enumVar);
 // CHECK: scanf("%zu", &sizeVar);
 // CHECK: scanf("%jd", &intmaxVar);
 // CHECK: scanf("%ju", &uIntmaxVar);
diff --git a/test/Sema/format-strings-ms.c b/test/Sema/format-strings-ms.c
index b89ee42..2ad8eae 100644
--- a/test/Sema/format-strings-ms.c
+++ b/test/Sema/format-strings-ms.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -fms-compatibility -triple=i386-pc-win32 -pedantic %s
+// RUN: %clang_cc1 -fsyntax-only -verify -fms-compatibility -triple=i386-pc-win32 -Wformat-non-iso %s
 
 int printf(const char *format, ...) __attribute__((format(printf, 1, 2)));
 
diff --git a/test/Sema/format-strings-non-iso.c b/test/Sema/format-strings-non-iso.c
index ee45946..429658c 100644
--- a/test/Sema/format-strings-non-iso.c
+++ b/test/Sema/format-strings-non-iso.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i686-linux-gnu -fsyntax-only -verify -std=c99 -pedantic %s
+// RUN: %clang_cc1 -triple i686-linux-gnu -fsyntax-only -verify -std=c99 -Wformat-non-iso %s
 
 int printf(const char *restrict, ...);
 int scanf(const char * restrict, ...);
diff --git a/test/Sema/format-strings-scanf.c b/test/Sema/format-strings-scanf.c
index d66bed5..d3a03ad 100644
--- a/test/Sema/format-strings-scanf.c
+++ b/test/Sema/format-strings-scanf.c
@@ -86,6 +86,11 @@
   scanf("%h[abc]", sp); // expected-warning{{length modifier 'h' results in undefined behavior or no effect with '[' conversion specifier}}
   scanf("%l[xyx]", ls); // no-warning
   scanf("%ll[xyx]", ls); // expected-warning {{length modifier 'll' results in undefined behavior or no effect with '[' conversion specifier}}
+
+  // PR19559
+  scanf("%[]% ]", sp); // no-warning
+  scanf("%[^]% ]", sp); // no-warning
+  scanf("%[a^]% ]", sp); // expected-warning {{invalid conversion specifier ' '}}
 }
 
 void test_alloc_extension(char **sp, wchar_t **lsp, float *fp) {
@@ -107,9 +112,9 @@
 
   // Test argument type check for the 'm' length modifier.
   scanf("%ms", fp); // expected-warning{{format specifies type 'char **' but the argument has type 'float *'}}
-  scanf("%mS", fp); // expected-warning-re{{format specifies type 'wchar_t \*\*' \(aka '[^']+'\) but the argument has type 'float \*'}}
+  scanf("%mS", fp); // expected-warning-re{{format specifies type 'wchar_t **' (aka '{{[^']+}}') but the argument has type 'float *'}}
   scanf("%mc", fp); // expected-warning{{format specifies type 'char **' but the argument has type 'float *'}}
-  scanf("%mC", fp); // expected-warning-re{{format specifies type 'wchar_t \*\*' \(aka '[^']+'\) but the argument has type 'float \*'}}
+  scanf("%mC", fp); // expected-warning-re{{format specifies type 'wchar_t **' (aka '{{[^']+}}') but the argument has type 'float *'}}
   scanf("%m[abc]", fp); // expected-warning{{format specifies type 'char **' but the argument has type 'float *'}}
 }
 
diff --git a/test/Sema/format-strings.c b/test/Sema/format-strings.c
index 6da027e..e31644a 100644
--- a/test/Sema/format-strings.c
+++ b/test/Sema/format-strings.c
@@ -1,8 +1,9 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -isystem %S/Inputs %s
 // RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -isystem %S/Inputs -fno-signed-char %s
 
-#define __need_wint_t
 #include <stdarg.h>
+#include <stddef.h>
+#define __need_wint_t
 #include <stddef.h> // For wint_t and wchar_t
 
 typedef struct _FILE FILE;
@@ -535,6 +536,21 @@
          0.0); // expected-warning{{format specifies}}
 }
 
+void pr18905() {
+  const char s1[] = "s\0%s"; // expected-note{{format string is defined here}}
+  const char s2[1] = "s"; // expected-note{{format string is defined here}}
+  const char s3[2] = "s\0%s"; // expected-warning{{initializer-string for char array is too long}}
+  const char s4[10] = "s";
+  const char s5[0] = "%s"; // expected-warning{{initializer-string for char array is too long}}
+                           // expected-note@-1{{format string is defined here}}
+
+  printf(s1); // expected-warning{{format string contains '\0' within the string body}}
+  printf(s2); // expected-warning{{format string is not null-terminated}}
+  printf(s3); // no-warning
+  printf(s4); // no-warning
+  printf(s5); // expected-warning{{format string is not null-terminated}}
+}
+
 void __attribute__((format(strfmon,1,2))) monformat(const char *fmt, ...);
 void __attribute__((format(strftime,1,0))) dateformat(const char *fmt);
 
@@ -544,7 +560,7 @@
   monformat("", 1); // expected-warning{{format string is empty}}
   monformat(str); // expected-warning{{format string is not a string literal (potentially insecure)}}
   dateformat(""); // expected-warning{{format string is empty}}
-  dateformat(str); // no-warning (using strftime non literal is not unsafe)
+  dateformat(str); // no-warning (using strftime non-literal is not unsafe)
 }
 
 // Do not warn about unused arguments coming from system headers.
diff --git a/test/Sema/i-c-e.c b/test/Sema/i-c-e.c
index 7749b6c..c6025f9 100644
--- a/test/Sema/i-c-e.c
+++ b/test/Sema/i-c-e.c
@@ -1,4 +1,4 @@
-// RUN: %clang %s -ffreestanding -Wno-int-to-pointer-cast -fsyntax-only -Xclang -verify -pedantic -fpascal-strings -std=c99
+// RUN: %clang_cc1 %s -ffreestanding -Wno-int-to-pointer-cast -fsyntax-only -verify -pedantic -fpascal-strings -std=c99
 
 #include <stdint.h>
 #include <limits.h>
diff --git a/test/Sema/implicit-builtin-decl.c b/test/Sema/implicit-builtin-decl.c
index d7ec169..3c2ff94 100644
--- a/test/Sema/implicit-builtin-decl.c
+++ b/test/Sema/implicit-builtin-decl.c
@@ -1,7 +1,9 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: not %clang_cc1 -fsyntax-only -ast-dump %s | FileCheck %s
+
 void f() {
   int *ptr = malloc(sizeof(int) * 10); // expected-warning{{implicitly declaring library function 'malloc' with type}} \
-  // expected-note{{please include the header <stdlib.h> or explicitly provide a declaration for 'malloc'}} \
+  // expected-note{{include the header <stdlib.h> or explicitly provide a declaration for 'malloc'}} \
   // expected-note{{'malloc' is a builtin with type 'void *}}
 }
 
@@ -57,3 +59,10 @@
 void longjmp(); // expected-warning{{declaration of built-in function 'longjmp' requires inclusion of the header <setjmp.h>}}
 
 extern float fmaxf(float, float);
+
+struct __jmp_buf_tag {};
+void sigsetjmp(struct __jmp_buf_tag[1], int); // expected-warning{{declaration of built-in function 'sigsetjmp' requires inclusion of the header <setjmp.h>}}
+
+// CHECK:     FunctionDecl {{.*}} <line:[[@LINE-2]]:1, col:44> col:6 sigsetjmp '
+// CHECK-NOT: FunctionDecl
+// CHECK:     ReturnsTwiceAttr {{.*}} <{{.*}}> Implicit
diff --git a/test/Sema/implicit-cast-dump.c b/test/Sema/implicit-cast-dump.c
index 87f15d0..4cd855f 100644
--- a/test/Sema/implicit-cast-dump.c
+++ b/test/Sema/implicit-cast-dump.c
@@ -5,7 +5,7 @@
 
 
 void bar() {
-  // CHECK:  FunctionDecl {{.*}} <line:{{.*}}, line:{{.*}}> bar 'void ()'
+  // CHECK:  FunctionDecl {{.*}} <line:{{.*}}, line:{{.*}}> line:{{.*}} bar 'void ()'
 
   foo1(0);
   // CHECK: ImplicitCastExpr {{.*}} <col:{{.*}}> 'void *' <NullToPointer>
diff --git a/test/Sema/inline-asm-validate.c b/test/Sema/inline-asm-validate.c
new file mode 100644
index 0000000..c32dedb
--- /dev/null
+++ b/test/Sema/inline-asm-validate.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple arm64-apple-macosx10.8.0 -fsyntax-only -verify %s
+// expected-no-diagnostics
+
+unsigned t, r, *p;
+
+int foo (void) {
+  __asm__ __volatile__( "stxr   %w[_t], %[_r], [%[_p]]" : [_t] "=&r" (t) : [_p] "p" (p), [_r] "r" (r) : "memory");
+  return 1;
+}
diff --git a/test/Sema/invalid-decl.c b/test/Sema/invalid-decl.c
index 950d51d..f0954b0 100644
--- a/test/Sema/invalid-decl.c
+++ b/test/Sema/invalid-decl.c
@@ -46,3 +46,5 @@
 void test3();
 void test3; // expected-error {{incomplete type}}
 void test3() { }
+
+void ellipsis1(...); // expected-error {{ISO C requires a named parameter before '...'}}
diff --git a/test/Sema/lit.local.cfg b/test/Sema/lit.local.cfg
new file mode 100644
index 0000000..f4ef5d2
--- /dev/null
+++ b/test/Sema/lit.local.cfg
@@ -0,0 +1,4 @@
+config.substitutions = list(config.substitutions)
+config.substitutions.insert(0,
+    (r'%clang\b',
+     """*** Do not use the driver in Sema tests. ***""") )
diff --git a/test/Sema/loop-control.c b/test/Sema/loop-control.c
new file mode 100644
index 0000000..6c33e84
--- /dev/null
+++ b/test/Sema/loop-control.c
@@ -0,0 +1,121 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -x c++ -Werror %s
+
+int pr8880_1() {
+  int first = 1;
+  for ( ; ({ if (first) { first = 0; continue; } 0; }); )
+    return 0;
+  return 1;
+}
+
+void pr8880_2(int first) {
+  for ( ; ({ if (first) { first = 0; break; } 0; }); ) {}
+}
+
+void pr8880_3(int first) {
+  for ( ; ; (void)({ if (first) { first = 0; continue; } 0; })) {}
+}
+
+void pr8880_4(int first) {
+  for ( ; ; (void)({ if (first) { first = 0; break; } 0; })) {}
+}
+
+void pr8880_5 (int first) {
+  while(({ if (first) { first = 0; continue; } 0; })) {}
+}
+
+void pr8880_6 (int first) {
+  while(({ if (first) { first = 0; break; } 0; })) {}
+}
+
+void pr8880_7 (int first) {
+  do {} while(({ if (first) { first = 0; continue; } 0; }));
+}
+
+void pr8880_8 (int first) {
+  do {} while(({ if (first) { first = 0; break; } 0; }));
+}
+
+void pr8880_10(int i) {
+  for ( ; i != 10 ; i++ )
+    for ( ; ; (void)({ ++i; continue; i;})) {} // expected-warning{{'continue' is bound to current loop, GCC binds it to the enclosing loop}}
+}
+
+void pr8880_11(int i) {
+  for ( ; i != 10 ; i++ )
+    for ( ; ; (void)({ ++i; break; i;})) {} // expected-warning{{'break' is bound to current loop, GCC binds it to the enclosing loop}}
+}
+
+void pr8880_12(int i, int j) {
+  for ( ; i != 10 ; i++ )
+    for ( ; ({if (i) continue; i;}); j++) {} // expected-warning {{'continue' is bound to current loop, GCC binds it to the enclosing loop}}
+}
+
+void pr8880_13(int i, int j) {
+  for ( ; i != 10 ; i++ )
+    for ( ; ({if (i) break; i;}); j++) {} // expected-warning{{'break' is bound to current loop, GCC binds it to the enclosing loop}}
+}
+
+void pr8880_14(int i) {
+  for ( ; i != 10 ; i++ )
+    while(({if (i) break; i;})) {} // expected-warning {{'break' is bound to current loop, GCC binds it to the enclosing loop}}
+}
+
+void pr8880_15(int i) {
+  while (--i)
+    while(({if (i) continue; i;})) {} // expected-warning {{'continue' is bound to current loop, GCC binds it to the enclosing loop}}
+}
+
+void pr8880_16(int i) {
+  for ( ; i != 10 ; i++ )
+    do {} while(({if (i) break; i;})); // expected-warning {{'break' is bound to current loop, GCC binds it to the enclosing loop}}
+}
+
+void pr8880_17(int i) {
+  for ( ; i != 10 ; i++ )
+    do {} while(({if (i) continue; i;})); // expected-warning {{'continue' is bound to current loop, GCC binds it to the enclosing loop}}
+}
+
+void pr8880_18(int x, int y) {
+  while(x > 0)
+    switch(({if(y) break; y;})) {
+    case 2: x = 0;
+    }
+}
+
+void pr8880_19(int x, int y) {
+  switch(x) {
+  case 1:
+    switch(({if(y) break; y;})) {
+    case 2: x = 0;
+    }
+  }
+}
+
+void pr8880_20(int x, int y) {
+  switch(x) {
+  case 1:
+    while(({if (y) break; y;})) {} //expected-warning {{'break' is bound to loop, GCC binds it to switch}}
+  }
+}
+
+void pr8880_21(int x, int y) {
+  switch(x) {
+  case 1:
+    do {} while(({if (y) break; y;})); //expected-warning {{'break' is bound to loop, GCC binds it to switch}}
+  }
+}
+
+void pr8880_22(int x, int y) {
+  switch(x) {
+  case 1:
+    for ( ; ; (void)({ ++y; break; y;})) {} // expected-warning{{'break' is bound to loop, GCC binds it to switc}}
+  }
+}
+
+void pr8880_23(int x, int y) {
+  switch(x) {
+  case 1:
+    for ( ; ({ ++y; break; y;}); ++y) {} // expected-warning{{'break' is bound to loop, GCC binds it to switch}}
+  }
+}
diff --git a/test/Sema/ms-inline-asm.c b/test/Sema/ms-inline-asm.c
index 1916d34..66504aa 100644
--- a/test/Sema/ms-inline-asm.c
+++ b/test/Sema/ms-inline-asm.c
@@ -1,4 +1,4 @@
-// REQUIRES: disabled
+// REQUIRES: x86-registered-target
 // RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -fasm-blocks -Wno-microsoft -verify -fsyntax-only
 
 void t1(void) { 
@@ -13,22 +13,89 @@
   }
   f();
   __asm {
-    mov eax, 1+=2 // expected-error 2 {{unknown token in expression}}
+    mov eax, 1+=2 // expected-error {{unknown token in expression}}
   }
   f();
   __asm {
-    mov eax, 1+++ // expected-error 2 {{unknown token in expression}}
+    mov eax, 1+++ // expected-error {{unknown token in expression}}
   }
   f();
   __asm {
-    mov eax, LENGTH bar // expected-error {{Unable to lookup expr!}}
+    mov eax, LENGTH bar // expected-error {{unable to lookup expression}}
   }
   f();
   __asm {
-    mov eax, SIZE bar // expected-error {{Unable to lookup expr!}}
+    mov eax, SIZE bar // expected-error {{unable to lookup expression}}
   }
   f();
   __asm {
-    mov eax, TYPE bar // expected-error {{Unable to lookup expr!}}
+    mov eax, TYPE bar // expected-error {{unable to lookup expression}}
   }
 }
+
+void rdar15318432(void) {
+  // We used to crash on this.  When LLVM called back to Clang to parse a name
+  // and do name lookup, if parsing failed, we did not restore the lexer state
+  // properly.
+
+  __asm {
+    and ecx, ~15
+  }
+
+  int x = 0;
+  __asm {
+    and ecx, x
+    and ecx, ~15
+  }
+}
+
+static int global;
+
+int t2(int *arr, int i) {
+  __asm {
+    mov eax, arr;
+    mov eax, arr[0];
+    mov eax, arr[1 + 2];
+    mov eax, arr[1 + (2 * 5) - 3 + 1<<1];
+  }
+
+  // expected-error@+1 {{cannot use base register with variable reference}}
+  __asm mov eax, arr[ebp + 1 + (2 * 5) - 3 + 1<<1]
+  // expected-error@+1 {{cannot use index register with variable reference}}
+  __asm mov eax, arr[esi * 4]
+  // expected-error@+1 {{cannot use more than one symbol in memory operand}}
+  __asm mov eax, arr[i]
+  // expected-error@+1 {{cannot use more than one symbol in memory operand}}
+  __asm mov eax, global[i]
+
+  // FIXME: Why don't we diagnose this?
+  // expected-Xerror@+1 {{cannot reference multiple local variables in assembly operand}}
+  //__asm mov eax, [arr + i];
+  return 0;
+}
+
+typedef struct {
+  int a;
+  int b;
+} A;
+
+void t3() {
+  __asm mov eax, [eax] UndeclaredId // expected-error {{unknown token in expression}}
+
+  // FIXME: Only emit one diagnostic here.
+  // expected-error@+2 {{unexpected type name 'A': expected expression}}
+  // expected-error@+1 {{unknown token in expression}}
+  __asm mov eax, [eax] A
+}
+
+void t4() {
+  // The dot in the "intel dot operator" is optional in MSVC.  MSVC also does
+  // global field lookup, but we don't.
+  __asm mov eax, [0] A.a
+  __asm mov eax, [0].A.a
+  __asm mov eax, [0].a    // expected-error {{Unable to lookup field reference!}}
+  __asm mov eax, fs:[0] A.a
+  __asm mov eax, fs:[0].A.a
+  __asm mov eax, fs:[0].a // expected-error {{Unable to lookup field reference!}}
+  __asm mov eax, fs:[0]. A.a  // expected-error {{Unexpected token type!}}
+}
diff --git a/test/Sema/ms-keyword-system-header.c b/test/Sema/ms-keyword-system-header.c
new file mode 100644
index 0000000..b4ff568
--- /dev/null
+++ b/test/Sema/ms-keyword-system-header.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fms-extensions -D MS -isystem %S/Inputs %s -fsyntax-only -verify
+// RUN: %clang_cc1 -fms-extensions -D MS -Wno-keyword-compat -I %S/Inputs %s -fsyntax-only -verify
+// RUN: %clang_cc1 -fms-extensions -D MS -D NOT_SYSTEM -I %S/Inputs %s -fsyntax-only -verify
+// RUN: %clang_cc1 -isystem %S/Inputs %s -fsyntax-only -verify
+
+// PR17824: GNU libc uses MS keyword __uptr as an identifier in C mode
+#include <ms-keyword-system-header.h>
+
+void fn() {
+  WS ws;
+  ws.__uptr = 0;
+#ifdef MS
+  // expected-error@-2 {{expected identifier}}
+#else
+  // expected-no-diagnostics
+#endif
+}
diff --git a/test/Sema/ms-wchar.c b/test/Sema/ms-wchar.c
index febaf28..ead3d97 100644
--- a/test/Sema/ms-wchar.c
+++ b/test/Sema/ms-wchar.c
@@ -12,7 +12,7 @@
 unsigned short g; // expected-error {{redefinition of 'g' with a different type: 'unsigned short' vs '__wchar_t'}}
 
 // The type of a wide string literal is actually not __wchar_t.
-__wchar_t s[] = L"Hello world!"; // expected-error-re {{array initializer must be an initializer list$}}
+__wchar_t s[] = L"Hello world!"; // expected-error-re {{array initializer must be an initializer list{{$}}}}
 
 // Do not suggest initializing with a string here, because it would not work.
-__wchar_t t[] = 1; // expected-error-re {{array initializer must be an initializer list$}}
+__wchar_t t[] = 1; // expected-error-re {{array initializer must be an initializer list{{$}}}}
diff --git a/test/Sema/ms_bitfield_layout.c b/test/Sema/ms_bitfield_layout.c
index 4a2076c..8444f46 100644
--- a/test/Sema/ms_bitfield_layout.c
+++ b/test/Sema/ms_bitfield_layout.c
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -cxx-abi microsoft -fdump-record-layouts %s 2>/dev/null \

+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple i686-pc-win32 -fms-extensions -fdump-record-layouts %s 2>/dev/null \

 // RUN:            | FileCheck %s

-// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -cxx-abi microsoft -fdump-record-layouts %s 2>/dev/null \

+// RUN: %clang_cc1 -fno-rtti -emit-llvm-only -triple x86_64-pc-win32 -fms-extensions -fdump-record-layouts %s 2>/dev/null \

 // RUN:            | FileCheck %s

 

 typedef struct A {

@@ -111,6 +111,16 @@
 // CHECK:   Alignment:16

 // CHECK:   FieldOffsets: [0, 16, 16, 16]>

 

+typedef struct I {

+	short : 8;

+	__declspec(align(16)) short : 8;

+} I;

+

+// CHECK: Type: struct I

+// CHECK:   Size:16

+// CHECK:   Alignment:16

+// CHECK:   FieldOffsets: [0, 8]

+

 #pragma pack(push, 1)

 

 typedef struct A1 {

@@ -221,6 +231,16 @@
 // CHECK:   Alignment:8

 // CHECK:   FieldOffsets: [0, 32, 32, 32]>

 

+typedef struct I1 {

+	short : 8;

+	__declspec(align(16)) short : 8;

+} I1;

+

+// CHECK: Type: struct I1

+// CHECK:   Size:16

+// CHECK:   Alignment:8

+// CHECK:   FieldOffsets: [0, 8]

+

 #pragma pack(pop)

 

 int x[

@@ -232,6 +252,7 @@
 sizeof(F ) +

 sizeof(G ) +

 sizeof(H ) +

+sizeof(I ) +

 sizeof(A1) +

 sizeof(B1) +

 sizeof(C1) +

@@ -240,4 +261,5 @@
 sizeof(F1) +

 sizeof(G1) +

 sizeof(H1) +

+sizeof(I1) +

 0];

diff --git a/test/Sema/ms_class_layout.cpp b/test/Sema/ms_class_layout.cpp
index bb8052e..896d3ed 100644
--- a/test/Sema/ms_class_layout.cpp
+++ b/test/Sema/ms_class_layout.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts -cxx-abi microsoft %s 2>&1 \
+// RUN: %clang_cc1 -emit-llvm-only -triple i686-pc-win32 -fdump-record-layouts %s 2>/dev/null \
 // RUN:            | FileCheck %s
 
 #pragma pack(push, 8)
@@ -289,7 +289,7 @@
 // CHECK-NEXT:  8 |     (D vftable pointer)
 // CHECK-NEXT: 16 |     double a
 // CHECK-NEXT: sizeof=24, align=8
-// CHECK-NEXT: nvsize=8, nvalign=4
+// CHECK-NEXT: nvsize=8, nvalign=8
 
 // CHECK: %struct.H = type { %struct.G, i32*, %class.D }
 
@@ -354,7 +354,7 @@
 // CHECK-NEXT:    | [sizeof=40, align=8
 // CHECK-NEXT:    |  nvsize=24, nvalign=8]
 
-// CHECK: struct.O = type { i32 (...)**, [4 x i8], %struct.H.base, %struct.G, [4 x i8], %class.D }
+// CHECK: struct.O = type { i32 (...)**, [4 x i8], %struct.H.base, %struct.G, %class.D }
 // CHECK: struct.O.base = type { i32 (...)**, [4 x i8], %struct.H.base, %struct.G, [4 x i8] }
 
 
@@ -428,10 +428,10 @@
 // CHECK-NEXT: nvsize=12, nvalign=4
 
 // CHECK: %struct.f = type { i32 (...)** }
-// CHECK: %struct.s = type { i32 (...)**, i32*, i32, [4 x i8], %struct.f }
+// CHECK: %struct.s = type { i32 (...)**, i32*, i32, i32, %struct.f }
 // CHECK: %class.IA = type { i32 (...)** }
-// CHECK: %class.ICh = type { i32 (...)**, i32*, [4 x i8], %class.IA }
-// CHECK: %struct.sd = type { i32*, i32, i8, [7 x i8], %struct.f, %struct.s.base, [4 x i8], %class.IA, %class.ICh.base }
+// CHECK: %class.ICh = type { i32 (...)**, i32*, i32, %class.IA }
+// CHECK: %struct.sd = type { i32*, i32, i8, i32, %struct.f, %struct.s.base, i32, %class.IA, %class.ICh.base }
 
 // CHECK:       0 | struct AV
 // CHECK-NEXT:  0 |   (AV vftable pointer)
@@ -457,7 +457,7 @@
 
 // CHECK: %struct.AV = type { i32 (...)** }
 // CHECK: %struct.BV = type { %struct.AV }
-// CHECK: %struct.CV = type { i32*, [4 x i8], %struct.BV }
+// CHECK: %struct.CV = type { i32*, i32, %struct.BV }
 // CHECK: %struct.CV.base = type { i32* }
 
 // CHECK:       0 | struct DV
@@ -470,12 +470,12 @@
 // CHECK: %struct.DV = type { %struct.BV }
 
 // CHECK:       0 | struct EV
-// CHECK-NEXT:  4 |   struct CV (base)
-// CHECK-NEXT:  4 |     (CV vbtable pointer)
 // CHECK-NEXT:  0 |   struct DV (primary base)
 // CHECK-NEXT:  0 |     struct BV (primary base)
 // CHECK-NEXT:  0 |       struct AV (primary base)
 // CHECK-NEXT:  0 |         (AV vftable pointer)
+// CHECK-NEXT:  4 |   struct CV (base)
+// CHECK-NEXT:  4 |     (CV vbtable pointer)
 // CHECK-NEXT:  8 |   (vtordisp for vbase BV)
 // CHECK-NEXT: 12 |   struct BV (virtual base)
 // CHECK-NEXT: 12 |     struct AV (primary base)
@@ -483,7 +483,7 @@
 // CHECK-NEXT: sizeof=16, align=4
 // CHECK-NEXT: nvsize=8, nvalign=4
 
-// CHECK: %struct.EV = type { %struct.DV, %struct.CV.base, [4 x i8], %struct.BV }
+// CHECK: %struct.EV = type { %struct.DV, %struct.CV.base, i32, %struct.BV }
 // CHECK: %struct.EV.base = type { %struct.DV, %struct.CV.base }
 
 // Overriding a method means that all the vbases containing that
diff --git a/test/Sema/neon-vector-types.c b/test/Sema/neon-vector-types.c
index d8dd412..03f669e 100644
--- a/test/Sema/neon-vector-types.c
+++ b/test/Sema/neon-vector-types.c
@@ -4,7 +4,7 @@
 typedef float float32_t;
 typedef signed char poly8_t;
 typedef short poly16_t;
-typedef unsigned long long uint64_t;
+typedef unsigned __INT64_TYPE__ uint64_t;
 
 // Define some valid Neon types.
 typedef __attribute__((neon_vector_type(2))) int int32x2_t;
@@ -23,7 +23,6 @@
 typedef __attribute__((neon_vector_type(2.0))) int non_int_width; // expected-error{{'neon_vector_type' attribute requires an integer constant}}
 
 // Only certain element types are allowed.
-typedef __attribute__((neon_vector_type(2))) double double_elt; // expected-error{{invalid vector element type}}
 typedef __attribute__((neon_vector_type(4))) void* ptr_elt; // expected-error{{invalid vector element type}}
 typedef __attribute__((neon_polyvector_type(4))) float32_t bad_poly_elt; // expected-error{{invalid vector element type}}
 struct aggr { signed char c; };
diff --git a/test/Sema/nonnull.c b/test/Sema/nonnull.c
index 4e61711..b1f6920 100644
--- a/test/Sema/nonnull.c
+++ b/test/Sema/nonnull.c
@@ -20,3 +20,37 @@
 }
 
 void foo(const char *str) __attribute__((nonnull("foo"))); // expected-error{{'nonnull' attribute requires parameter 1 to be an integer constant}}
+void bar(int i) __attribute__((nonnull(1))); // expected-warning {{'nonnull' attribute only applies to pointer arguments}} expected-warning {{'nonnull' attribute applied to function with no pointer arguments}}
+
+void baz(__attribute__((nonnull)) const char *str);
+void baz2(__attribute__((nonnull(1))) const char *str); // expected-warning {{'nonnull' attribute when used on parameters takes no arguments}}
+void baz3(__attribute__((nonnull)) int x); // expected-warning {{'nonnull' attribute only applies to pointer arguments}}
+
+void test_baz() {
+  baz(0); // expected-warning {{null passed to a callee which requires a non-null argument}}
+  baz2(0); // no-warning
+  baz3(0); // no-warning
+}
+
+void test_void_returns_nonnull(void) __attribute__((returns_nonnull)); // expected-warning {{'returns_nonnull' attribute only applies to return values that are pointers}}
+int test_int_returns_nonnull(void) __attribute__((returns_nonnull)); // expected-warning {{'returns_nonnull' attribute only applies to return values that are pointers}}
+void *test_ptr_returns_nonnull(void) __attribute__((returns_nonnull)); // no-warning
+
+int i __attribute__((nonnull)); // expected-warning {{'nonnull' attribute only applies to functions, methods, and parameters}}
+int j __attribute__((returns_nonnull)); // expected-warning {{'returns_nonnull' attribute only applies to functions and methods}}
+void *test_no_fn_proto() __attribute__((returns_nonnull)); // no-warning
+void *test_with_fn_proto(void) __attribute__((returns_nonnull)); // no-warning
+
+__attribute__((returns_nonnull))
+void *test_bad_returns_null(void) {
+  return 0; // expected-warning {{null returned from function that requires a non-null return value}}
+}
+
+void PR18795(int (*g)(const char *h, ...) __attribute__((nonnull(1))) __attribute__((nonnull))) {
+  g(0); // expected-warning{{null passed to a callee which requires a non-null argument}}
+}
+void PR18795_helper() {
+  PR18795(0); // expected-warning{{null passed to a callee which requires a non-null argument}}
+}
+
+
diff --git a/test/Sema/overloadable.c b/test/Sema/overloadable.c
index b93c39f..bdd4714 100644
--- a/test/Sema/overloadable.c
+++ b/test/Sema/overloadable.c
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 
-int var __attribute__((overloadable)); // expected-error{{'overloadable' attribute can only be applied to a function}}
+int var __attribute__((overloadable)); // expected-error{{'overloadable' attribute only applies to functions}}
 void params(void) __attribute__((overloadable(12))); // expected-error {{'overloadable' attribute takes no arguments}}
 
 int *f(int) __attribute__((overloadable)); // expected-note 2{{previous overload of function is here}}
diff --git a/test/Sema/pragma-ms_struct.c b/test/Sema/pragma-ms_struct.c
index 6533320..e2c5ff1 100644
--- a/test/Sema/pragma-ms_struct.c
+++ b/test/Sema/pragma-ms_struct.c
@@ -25,7 +25,7 @@
 } __attribute__((__ms_struct__)) t1;
 
 struct S {
-		   double __attribute__((ms_struct)) d;	// expected-warning {{'ms_struct' attribute ignored}}
+		   double __attribute__((ms_struct)) d;	// expected-warning {{'ms_struct' attribute only applies to struct or union}}
                    unsigned long bf_1 : 12;
                    unsigned long : 0;
                    unsigned long bf_2 : 12;
@@ -36,7 +36,7 @@
   A = 0,
   B,
   C
-} __attribute__((ms_struct)) e1; // expected-warning {{'ms_struct' attribute ignored}}
+} __attribute__((ms_struct)) e1; // expected-warning {{'ms_struct' attribute only applies to struct or union}}
 
 // rdar://10513599
 #pragma ms_struct on
@@ -52,10 +52,12 @@
 void *pv1;
 Foo foo;
 unsigned short fInited : 1;
-void *pv2;		
-} PackOddity;		
+void *pv2;
+} PackOddity;
 
 #pragma ms_struct off
 
 static int arr[sizeof(PackOddity) == 40 ? 1 : -1];
 
+struct __declspec(ms_struct) bad { // expected-warning {{__declspec attribute 'ms_struct' is not supported}}
+};
diff --git a/test/Sema/pragma-pack-apple.c b/test/Sema/pragma-pack-apple.c
index 5b33c03..426d984 100644
--- a/test/Sema/pragma-pack-apple.c
+++ b/test/Sema/pragma-pack-apple.c
@@ -1,5 +1,5 @@
-// RUN: %clang -fsyntax-only %s 2>&1 | FileCheck %s
-// RUN: %clang -fsyntax-only -fapple-pragma-pack %s 2>&1 | FileCheck -check-prefix=CHECK-APPLE %s
+// RUN: %clang_cc1 -fsyntax-only %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -fsyntax-only -fapple-pragma-pack %s 2>&1 | FileCheck -check-prefix=CHECK-APPLE %s
 
 #pragma pack(push,1)
 #pragma pack(2)
diff --git a/test/Sema/pragma-section.c b/test/Sema/pragma-section.c
new file mode 100644
index 0000000..2906fab
--- /dev/null
+++ b/test/Sema/pragma-section.c
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions %s -triple x86_64-pc-win32
+
+#pragma const_seg(".my_const") // expected-note 2 {{#pragma entered here}}
+extern const int a;
+const int a = 1; // expected-note 2 {{declared here}}
+#pragma data_seg(".my_const") // expected-note {{#pragma entered here}}
+int b = 1; // expected-error {{'b' causes a section type conflict with 'a'}}
+#pragma data_seg()
+int c = 1;
+__declspec(allocate(".my_const")) int d = 1; // expected-error {{'d' causes a section type conflict with 'a'}}
+#pragma data_seg("\u") // expected-error {{\u used with no following hex digits}}
+#pragma data_seg("a" L"b") // expected-warning {{expected non-wide string literal in '#pragma data_seg'}}
+
+#pragma section(".my_seg", execute) // expected-note 2 {{#pragma entered her}}
+__declspec(allocate(".my_seg")) int int_my_seg;
+#pragma code_seg(".my_seg")
+void fn_my_seg(void){}
+
+__declspec(allocate(".bad_seg")) int int_bad_seg = 1; // expected-note {{declared here}}
+#pragma code_seg(".bad_seg") // expected-note {{#pragma entered here}}
+void fn_bad_seg(void){} // expected-error {{'fn_bad_seg' causes a section type conflict with 'int_bad_seg'}}
+
+#pragma bss_seg // expected-warning {{missing '(' after '#pragma bss_seg' - ignoring}}
+#pragma bss_seg(L".my_seg") // expected-warning {{expected push, pop or a string literal for the section name in '#pragma bss_seg' - ignored}}
+#pragma bss_seg(1) // expected-warning {{expected push, pop or a string literal for the section name in '#pragma bss_seg' - ignored}}
+#pragma bss_seg(push)
+#pragma bss_seg(push, ".my_seg")
+#pragma bss_seg(push, 1) // expected-warning {{expected a stack label or a string literal for the section name in '#pragma bss_seg'}}
+#pragma bss_seg ".my_seg" // expected-warning {{missing '(' after '#pragma bss_seg' - ignoring}}
+#pragma bss_seg(push, my_label, 1) // expected-warning {{expected a string literal for the section name in '#pragma bss_seg' - ignored}}
+#pragma bss_seg(".my_seg", 1) // expected-warning {{missing ')' after '#pragma bss_seg' - ignoring}}
+#pragma bss_seg(".my_seg" // expected-warning {{missing ')' after '#pragma bss_seg' - ignoring}}
+
+#pragma section // expected-warning {{missing '(' after '#pragma section' - ignoring}}
+#pragma section( // expected-warning {{expected a string literal for the section name in '#pragma section' - ignored}}
+#pragma section(L".my_seg") // expected-warning {{expected a string literal for the section name in '#pragma section' - ignored}}
+#pragma section(".my_seg" // expected-warning {{missing ')' after '#pragma section' - ignoring}}
+#pragma section(".my_seg" 1  // expected-warning {{missing ')' after '#pragma section' - ignoring}}
+#pragma section(".my_seg",  // expected-warning {{expected action or ')' in '#pragma section' - ignored}}
+#pragma section(".my_seg", read) // expected-error {{this causes a section type conflict with a prior #pragma section}}
+#pragma section(".my_seg", bogus) // expected-warning {{unknown action 'bogus' for '#pragma section' - ignored}}
+#pragma section(".my_seg", nopage) // expected-warning {{known but unsupported action 'nopage' for '#pragma section' - ignored}}
+#pragma section(".my_seg", read, write) // expected-error {{this causes a section type conflict with a prior #pragma section}}
+#pragma section(".my_seg", read, write, 1) //  expected-warning {{expected action or ')' in '#pragma section' - ignored}}
diff --git a/test/Sema/private-extern.c b/test/Sema/private-extern.c
index e9b67d5..0c13c92 100644
--- a/test/Sema/private-extern.c
+++ b/test/Sema/private-extern.c
@@ -13,10 +13,10 @@
 int g3; // expected-note{{previous definition}}
 static int g3; // expected-error{{static declaration of 'g3' follows non-static declaration}}
 
-extern int g4; // expected-note{{previous definition}}
+extern int g4; // expected-note{{previous declaration}}
 static int g4; // expected-error{{static declaration of 'g4' follows non-static declaration}}
 
-__private_extern__ int g5; // expected-note{{previous definition}}
+__private_extern__ int g5; // expected-note{{previous declaration}}
 static int g5; // expected-error{{static declaration of 'g5' follows non-static declaration}}
 
 void f0() {
@@ -30,12 +30,12 @@
 }
 
 void f2() {
-  extern int g8; // expected-note{{previous definition}}
+  extern int g8; // expected-note{{previous declaration}}
   int g8; // expected-error {{non-extern declaration of 'g8' follows extern declaration}}
 }
 
 void f3() {
-  __private_extern__ int g9; // expected-note{{previous definition}}
+  __private_extern__ int g9; // expected-note{{previous declaration}}
   int g9; // expected-error {{non-extern declaration of 'g9' follows extern declaration}}
 }
 
diff --git a/test/Sema/return-noreturn.c b/test/Sema/return-noreturn.c
index 6d521eb..2aa0b91 100644
--- a/test/Sema/return-noreturn.c
+++ b/test/Sema/return-noreturn.c
@@ -2,7 +2,7 @@
 
 int j;
 void test1() { // expected-warning {{function 'test1' could be declared with attribute 'noreturn'}}
-  ^ (void) { while (1) { } }(); // expected-warning {{block could be declared with attribute 'noreturn'}}
+  ^ (void) { while (1) { } }();
   ^ (void) { if (j) while (1) { } }();
   while (1) { }
 }
@@ -40,3 +40,13 @@
 _Noreturn void test5() {
   test2_positive();
 }
+
+// rdar://16274746
+void test6()
+{
+    (void)^{ 
+       for(;;)
+        ;
+     };
+}
+
diff --git a/test/Sema/return.c b/test/Sema/return.c
index 7e7c8b7..2a58a6e 100644
--- a/test/Sema/return.c
+++ b/test/Sema/return.c
@@ -1,4 +1,4 @@
-// RUN: %clang %s -fsyntax-only -Wignored-qualifiers -Wno-error=return-type -Xclang -verify -fblocks -Wno-unreachable-code -Wno-unused-value
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -fsyntax-only -Wignored-qualifiers -Wno-error=return-type -verify -fblocks -Wno-unreachable-code -Wno-unused-value
 
 // clang emits the following warning by default.
 // With GCC, -pedantic, -Wreturn-type or -Wall are required to produce the 
@@ -275,3 +275,44 @@
     return 5;
   }
 }
+
+// PR18999
+int test35() {
+lbl:
+  if (1)
+    goto lbl;
+}
+
+// PR19074.
+void abort(void) __attribute__((noreturn));
+#define av_assert0(cond) do {\
+    if (!(cond)) {\
+      abort();\
+    }\
+  } while (0)
+
+int PR19074(int x) {
+  switch(x) {
+  case 0:
+    return 0;
+  default:
+    av_assert0(0);
+  } // no-warning
+}
+
+int PR19074_positive(int x) {
+  switch(x) {
+  case 0:
+    return 0;
+  default:
+    break;
+  }
+} // expected-warning {{control may reach end of non-void function}}
+
+// sizeof(long) test.
+int sizeof_long() {
+  if (sizeof(long) == 4)
+    return 1;
+  if (sizeof(long) == 8)
+    return 2;
+} // no-warning
diff --git a/test/Sema/sentinel-attribute.c b/test/Sema/sentinel-attribute.c
index e5cbf6e..46f1350 100644
--- a/test/Sema/sentinel-attribute.c
+++ b/test/Sema/sentinel-attribute.c
@@ -5,7 +5,7 @@
 void f2(int a, ...) __attribute__ ((sentinel(1)));
 
 void f3(int a, ...) __attribute__ ((sentinel("hello"))); //expected-error{{'sentinel' attribute requires parameter 1 to be an integer constant}}
-void f4(int a, ...) __attribute__ ((sentinel(1, 2, 3))); //expected-error{{attribute takes no more than 2 arguments}}
+void f4(int a, ...) __attribute__ ((sentinel(1, 2, 3))); //expected-error{{'sentinel' attribute takes no more than 2 arguments}}
 void f4(int a, ...) __attribute__ ((sentinel(-1))); //expected-error{{parameter 1 less than zero}}
 void f4(int a, ...) __attribute__ ((sentinel(0, 2))); // expected-error{{parameter 2 not 0 or 1}}
 
diff --git a/test/Sema/shift.c b/test/Sema/shift.c
index 142d83c..d355544 100644
--- a/test/Sema/shift.c
+++ b/test/Sema/shift.c
@@ -1,4 +1,4 @@
-// RUN: %clang -Wall -Wshift-sign-overflow -ffreestanding -fsyntax-only -Xclang -verify %s
+// RUN: %clang_cc1 -Wall -Wshift-sign-overflow -ffreestanding -fsyntax-only -verify %s
 
 #include <limits.h>
 
diff --git a/test/Sema/statements.c b/test/Sema/statements.c
index f01ee40..8cd30b0 100644
--- a/test/Sema/statements.c
+++ b/test/Sema/statements.c
@@ -36,7 +36,7 @@
 
 // PR6034
 void test11(int bit) {
-  switch (bit) // expected-warning {{switch statement has empty body}} expected-note {{put the semicolon on a separate line to silence this warning}}
+  switch (bit)
   switch (env->fpscr)  // expected-error {{use of undeclared identifier 'env'}}
   {
   }
@@ -90,9 +90,6 @@
   }
 }
 
-// PR 8880
-// FIXME: Clang should reject this, since GCC does.  Previously this
-// was causing a crash in the CFG builder.
 int test_pr8880() {
   int first = 1;
   for ( ; ({ if (first) { first = 0; continue; } 0; }); )
diff --git a/test/Sema/static-init.c b/test/Sema/static-init.c
index bbf9038..a2ed551 100644
--- a/test/Sema/static-init.c
+++ b/test/Sema/static-init.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-bool-conversion %s
 
 typedef __typeof((int*) 0 - (int*) 0) intptr_t;
 
diff --git a/test/Sema/struct-decl.c b/test/Sema/struct-decl.c
index 8d3d74d..055f14b 100644
--- a/test/Sema/struct-decl.c
+++ b/test/Sema/struct-decl.c
@@ -66,3 +66,6 @@
   struct hiding_1 *p = hiding_1();
   struct hiding_2 *q = hiding_2;
 }
+
+struct PreserveAttributes {};
+typedef struct __attribute__((noreturn)) PreserveAttributes PreserveAttributes_t; // expected-warning {{'noreturn' attribute only applies to functions and methods}}
diff --git a/test/Sema/switch.c b/test/Sema/switch.c
index e37d5da..092378d 100644
--- a/test/Sema/switch.c
+++ b/test/Sema/switch.c
@@ -109,14 +109,14 @@
   switch(a) {
     case A:
     case B:
-    case 3: // expected-warning{{case value not in enumerated type 'enum <anonymous enum}}
+    case 3: // expected-warning{{case value not in enumerated type 'enum (anonymous enum}}
       break;
   }
   switch(a) {
     case A:
     case B:
-    case 3 ... //expected-warning{{case value not in enumerated type 'enum <anonymous enum}}
-        4: //expected-warning{{case value not in enumerated type 'enum <anonymous enum}}
+    case 3 ... //expected-warning{{case value not in enumerated type 'enum (anonymous enum}}
+        4: //expected-warning{{case value not in enumerated type 'enum (anonymous enum}}
       break;
   }
   switch(a) {
@@ -124,16 +124,16 @@
       break;
   }
   switch(a) {
-    case 0 ... 2: //expected-warning{{case value not in enumerated type 'enum <anonymous enum}}
+    case 0 ... 2: //expected-warning{{case value not in enumerated type 'enum (anonymous enum}}
       break;
   }
   switch(a) {
-    case 1 ... 3: //expected-warning{{case value not in enumerated type 'enum <anonymous enum}}
+    case 1 ... 3: //expected-warning{{case value not in enumerated type 'enum (anonymous enum}}
       break;
   }
   switch(a) {
-    case 0 ...  //expected-warning{{case value not in enumerated type 'enum <anonymous enum}}
-      3:  //expected-warning{{case value not in enumerated type 'enum <anonymous enum}}
+    case 0 ...  //expected-warning{{case value not in enumerated type 'enum (anonymous enum}}
+      3:  //expected-warning{{case value not in enumerated type 'enum (anonymous enum}}
       break;
   }
 
@@ -167,11 +167,11 @@
     C = 1
   } a;
   switch(a) {
-    case 0: //expected-warning{{case value not in enumerated type 'enum <anonymous enum}}
+    case 0: //expected-warning{{case value not in enumerated type 'enum (anonymous enum}}
     case 1:
-    case 2: //expected-warning{{case value not in enumerated type 'enum <anonymous enum}}
+    case 2: //expected-warning{{case value not in enumerated type 'enum (anonymous enum}}
     case 3:
-    case 4: //expected-warning{{case value not in enumerated type 'enum <anonymous enum}}
+    case 4: //expected-warning{{case value not in enumerated type 'enum (anonymous enum}}
       break;
   }
 }
@@ -184,14 +184,14 @@
     D = 12
   } a;
   switch(a) {
-    case 0 ...  //expected-warning{{case value not in enumerated type 'enum <anonymous enum}}
-	    1:  //expected-warning{{case value not in enumerated type 'enum <anonymous enum}}
+    case 0 ...  //expected-warning{{case value not in enumerated type 'enum (anonymous enum}}
+	    1:  //expected-warning{{case value not in enumerated type 'enum (anonymous enum}}
     case 2 ... 4:
-    case 5 ...  //expected-warning{{case value not in enumerated type 'enum <anonymous enum}}	
-	      9:  //expected-warning{{case value not in enumerated type 'enum <anonymous enum}}
+    case 5 ...  //expected-warning{{case value not in enumerated type 'enum (anonymous enum}}	
+	      9:  //expected-warning{{case value not in enumerated type 'enum (anonymous enum}}
     case 10 ... 12:
-    case 13 ...  //expected-warning{{case value not in enumerated type 'enum <anonymous enum}}
-              16: //expected-warning{{case value not in enumerated type 'enum <anonymous enum}}
+    case 13 ...  //expected-warning{{case value not in enumerated type 'enum (anonymous enum}}
+              16: //expected-warning{{case value not in enumerated type 'enum (anonymous enum}}
       break;
   }
 }
@@ -349,3 +349,29 @@
       break;
   }
 }
+
+// Allow the warning 'case value not in enumerated type' to be silenced with
+// the following pattern.
+//
+// If 'case' expression refers to a static const variable of the correct enum
+// type, then we count this as a sufficient declaration of intent by the user,
+// so we silence the warning.
+enum ExtendedEnum1 {
+  EE1_a,
+  EE1_b
+};
+
+enum ExtendedEnum1_unrelated { EE1_misc };
+
+static const enum ExtendedEnum1 EE1_c = 100;
+static const enum ExtendedEnum1_unrelated EE1_d = 101;
+
+void switch_on_ExtendedEnum1(enum ExtendedEnum1 e) {
+  switch(e) {
+  case EE1_a: break;
+  case EE1_b: break;
+  case EE1_c: break; // no-warning
+  case EE1_d: break; // expected-warning {{case value not in enumerated type 'enum ExtendedEnum1'}}
+  }
+}
+
diff --git a/test/Sema/tentative-decls.c b/test/Sema/tentative-decls.c
index bf2b1e4..6026242 100644
--- a/test/Sema/tentative-decls.c
+++ b/test/Sema/tentative-decls.c
@@ -23,7 +23,7 @@
 int i1 = 2; // expected-error {{redefinition of 'i1'}}
 int i1;
 int i1;
-extern int i5; // expected-note {{previous definition is here}}
+extern int i5; // expected-note {{previous declaration is here}}
 static int i5; // expected-error{{static declaration of 'i5' follows non-static declaration}}
 
 static int i2 = 5; // expected-note 1 {{previous definition is here}}
@@ -49,7 +49,7 @@
 int redef[11]; // expected-error{{redefinition of 'redef'}}
 
 void func() {
-  extern int i6; // expected-note {{previous definition is here}}
+  extern int i6; // expected-note {{previous declaration is here}}
   static int i6; // expected-error{{static declaration of 'i6' follows non-static declaration}}
 }
 
diff --git a/test/Sema/thread-specifier.c b/test/Sema/thread-specifier.c
index bf1ce9e..3968ae1 100644
--- a/test/Sema/thread-specifier.c
+++ b/test/Sema/thread-specifier.c
@@ -21,7 +21,7 @@
 __thread __private_extern__ int t4;
 struct t5 { __thread int x; };
 #ifdef __cplusplus
-// expected-error-re@-2 {{'(__thread|_Thread_local|thread_local)' is only allowed on variable declarations}}
+// expected-error-re@-2 {{'{{__thread|_Thread_local|thread_local}}' is only allowed on variable declarations}}
 #else
 // FIXME: The 'is only allowed on variable declarations' diagnostic is better here.
 // expected-error@-5 {{type name does not allow storage class to be specified}}
@@ -47,18 +47,18 @@
   static __thread int t10;
   __thread __private_extern__ int t11;
 #if __cplusplus < 201103L
-  __thread auto int t12a; // expected-error-re {{cannot combine with previous '(__thread|_Thread_local)' declaration specifier}}
+  __thread auto int t12a; // expected-error-re {{cannot combine with previous '{{__thread|_Thread_local}}' declaration specifier}}
   auto __thread int t12b; // expected-error {{cannot combine with previous 'auto' declaration specifier}}
 #elif !defined(CXX11)
-  __thread auto t12a = 0; // expected-error-re {{'_Thread_local' variables must have global storage}}
-  auto __thread t12b = 0; // expected-error-re {{'_Thread_local' variables must have global storage}}
+  __thread auto t12a = 0; // expected-error {{'_Thread_local' variables must have global storage}}
+  auto __thread t12b = 0; // expected-error {{'_Thread_local' variables must have global storage}}
 #endif
-  __thread register int t13a; // expected-error-re {{cannot combine with previous '(__thread|_Thread_local|thread_local)' declaration specifier}}
+  __thread register int t13a; // expected-error-re {{cannot combine with previous '{{__thread|_Thread_local|thread_local}}' declaration specifier}}
   register __thread int t13b; // expected-error {{cannot combine with previous 'register' declaration specifier}}
 }
 
-__thread typedef int t14; // expected-error-re {{cannot combine with previous '(__thread|_Thread_local|thread_local)' declaration specifier}}
-__thread int t15; // expected-note {{previous declaration is here}}
+__thread typedef int t14; // expected-error-re {{cannot combine with previous '{{__thread|_Thread_local|thread_local}}' declaration specifier}}
+__thread int t15; // expected-note {{previous definition is here}}
 extern int t15; // expected-error {{non-thread-local declaration of 't15' follows thread-local declaration}}
 extern int t16; // expected-note {{previous declaration is here}}
 __thread int t16; // expected-error {{thread-local declaration of 't16' follows non-thread-local declaration}}
@@ -107,4 +107,17 @@
 #endif
 #endif
 
+#ifdef __cplusplus
+struct HasCtor {
+  HasCtor();
+};
+__thread HasCtor var_with_ctor;
+#if !defined(CXX11)
+// expected-error@-2 {{initializer for thread-local variable must be a constant expression}}
+#if __cplusplus >= 201103L
+// expected-note@-4 {{use 'thread_local' to allow this}}
+#endif
+#endif
+#endif
+
 __thread int aggregate[10] = {0};
diff --git a/test/Sema/tls.c b/test/Sema/tls.c
index 4e5cfef..a3fdc8e 100644
--- a/test/Sema/tls.c
+++ b/test/Sema/tls.c
@@ -9,9 +9,8 @@
 // RUN: not %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only %s
 // RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -fsyntax-only %s
 
-// FIXME: I thought it was supported actually?
-// RUN: not %clang_cc1 -triple x86_64-pc-win32 -fsyntax-only %s
-// RUN: not %clang_cc1 -triple i386-pc-win32 -fsyntax-only %s
+// RUN: %clang_cc1 -triple x86_64-pc-win32 -fsyntax-only %s
+// RUN: %clang_cc1 -triple i386-pc-win32 -fsyntax-only %s
 
 // OpenBSD does not suppport TLS.
 // RUN: not %clang_cc1 -triple x86_64-pc-openbsd -fsyntax-only %s
@@ -20,4 +19,8 @@
 // Haiku does not suppport TLS.
 // RUN: not %clang_cc1 -triple i586-pc-haiku -fsyntax-only %s
 
+// Bitrig suppports TLS.
+// RUN: %clang_cc1 -triple x86_64-pc-bitrig -fsyntax-only %s
+// RUN: %clang_cc1 -triple armv6-unknown-bitrig -fsyntax-only %s
+
 __thread int x;
diff --git a/test/Sema/transparent-union.c b/test/Sema/transparent-union.c
index ab1ba18..8ef70bb 100644
--- a/test/Sema/transparent-union.c
+++ b/test/Sema/transparent-union.c
@@ -1,4 +1,4 @@
-// RUN: %clang -fsyntax-only -Xclang -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
 typedef union {
   int *ip;
   float *fp;
@@ -67,7 +67,25 @@
 
 typedef int int4 __attribute__((ext_vector_type(4)));
 typedef union {
-  int4 vec; // expected-warning{{first field of a transparent union cannot have vector type 'int4'; transparent_union attribute ignored}}
+  int4 vec; // expected-warning{{first field of a transparent union cannot have vector type 'int4' (vector of 4 'int' values); transparent_union attribute ignored}}
 } TU5 __attribute__((transparent_union));
 
-  
+union pr15134 {
+  unsigned int u;
+  struct {
+    unsigned int expo:2;
+    unsigned int mant:30;
+  } __attribute__((packed));
+  // The packed attribute is acceptable because it defines a less strict
+  // alignment than required by the first field of the transparent union.
+} __attribute__((transparent_union));
+
+union pr15134v2 {
+  struct { // expected-note {{alignment of first field is 32 bits}}
+    unsigned int u1;
+    unsigned int u2;
+  };
+  struct {  // expected-warning {{alignment of field '' (64 bits) does not match the alignment of the first field in transparent union; transparent_union attribute ignored}}
+    unsigned int u3;
+  } __attribute__((aligned(8)));
+} __attribute__((transparent_union));
diff --git a/test/Sema/typedef-retain.c b/test/Sema/typedef-retain.c
index a7173b7..d216466 100644
--- a/test/Sema/typedef-retain.c
+++ b/test/Sema/typedef-retain.c
@@ -5,11 +5,11 @@
 typedef int4* int4p;
 
 void test1(float4 a, int4 *result, int i) {
-    result[i] = a; // expected-error {{assigning to 'int4' from incompatible type 'float4'}}
+    result[i] = a; // expected-error {{assigning to 'int4' (vector of 4 'int' values) from incompatible type 'float4' (vector of 4 'float' values)}}
 }
 
 void test2(float4 a, int4p result, int i) {
-    result[i] = a; // expected-error {{assigning to 'int4' from incompatible type 'float4'}}
+    result[i] = a; // expected-error {{assigning to 'int4' (vector of 4 'int' values) from incompatible type 'float4' (vector of 4 'float' values)}}
 }
 
 // PR2039
diff --git a/test/Sema/typeof-use-deprecated.c b/test/Sema/typeof-use-deprecated.c
index 1518c83..ba72b12 100644
--- a/test/Sema/typeof-use-deprecated.c
+++ b/test/Sema/typeof-use-deprecated.c
@@ -1,25 +1,25 @@
 // RUN: %clang_cc1 %s -verify -fsyntax-only
 
-struct s { int a; } __attribute__((deprecated)) x;  // expected-warning {{'s' is deprecated}} expected-note 2 {{'s' declared here}}
+struct s { int a; } __attribute__((deprecated)) x;  // expected-warning {{'s' is deprecated}} expected-note 2 {{'s' has been explicitly marked deprecated here}}
 
 typeof(x) y;  // expected-warning {{'s' is deprecated}}
 
-union un{ int a; } __attribute__((deprecated)) u;  // expected-warning {{'un' is deprecated}} expected-note 2 {{'un' declared here}}
+union un{ int a; } __attribute__((deprecated)) u;  // expected-warning {{'un' is deprecated}} expected-note 2 {{'un' has been explicitly marked deprecated here}}
 
 typeof(     u) z; // expected-warning {{'un' is deprecated}}
 
-enum E{ one} __attribute__((deprecated))  e; // expected-warning {{'E' is deprecated}} expected-note 2 {{'E' declared here}}
+enum E{ one} __attribute__((deprecated))  e; // expected-warning {{'E' is deprecated}} expected-note 2 {{'E' has been explicitly marked deprecated here}}
 
 typeof( e) w; // expected-warning {{'E' is deprecated}}
 
-struct foo { int x; } __attribute__((deprecated)); // expected-note {{'foo' declared here}}
-typedef struct foo bar __attribute__((deprecated)); // expected-note {{'bar' declared here}}
+struct foo { int x; } __attribute__((deprecated)); // expected-note {{'foo' has been explicitly marked deprecated here}}
+typedef struct foo bar __attribute__((deprecated)); // expected-note {{'bar' has been explicitly marked deprecated here}}
 bar x1;	// expected-warning {{'bar' is deprecated}}
 
 int main() { typeof(x1) y; }	// expected-warning {{'foo' is deprecated}}
 
 struct gorf { int x; };
-typedef struct gorf T __attribute__((deprecated));  // expected-note {{'T' declared here}}
+typedef struct gorf T __attribute__((deprecated));  // expected-note {{'T' has been explicitly marked deprecated here}}
 T t;	// expected-warning {{'T' is deprecated}}
 void wee() { typeof(t) y; }
 
diff --git a/test/Sema/types.c b/test/Sema/types.c
index dac0bfe..778a5fe 100644
--- a/test/Sema/types.c
+++ b/test/Sema/types.c
@@ -53,7 +53,7 @@
 int __attribute__ ((vector_size (8), vector_size (8))) v;  // expected-error {{invalid vector element type}}
 
 void test(int i) {
-  char c = (char __attribute__((align(8)))) i; // expected-warning {{'align' attribute ignored when parsing type}}
+  char c = (char __attribute__((aligned(8)))) i; // expected-warning {{'aligned' attribute ignored when parsing type}}
 }
 
 // http://llvm.org/PR11082
@@ -72,3 +72,12 @@
 // no support for vector enum type
 enum { e_2 } x3 __attribute__((vector_size(64))); // expected-error {{invalid vector element type}}
 
+int x4 __attribute__((ext_vector_type(64)));  // expected-error {{'ext_vector_type' attribute only applies to types}}
+
+// rdar://16492792
+typedef __attribute__ ((ext_vector_type(32),__aligned__(32))) unsigned char uchar32;
+
+void convert() {
+    uchar32 r = 0;
+    r.s[ 1234 ] = 1; // expected-error {{illegal vector component name 's'}}
+}
diff --git a/test/Sema/unused-expr.c b/test/Sema/unused-expr.c
index ea08631..43d8150 100644
--- a/test/Sema/unused-expr.c
+++ b/test/Sema/unused-expr.c
@@ -7,11 +7,11 @@
 void bar(volatile int *VP, int *P, int A,
          _Complex double C, volatile _Complex double VC) {
   
-  VP < P;              // expected-warning {{expression result unused}}
+  VP < P;              // expected-warning {{relational comparison result unused}}
   (void)A;
   (void)foo(1,2);      // no warning.
   
-  A < foo(1, 2);       // expected-warning {{expression result unused}}
+  A < foo(1, 2);       // expected-warning {{relational comparison result unused}}
 
   foo(1,2)+foo(4,3);   // expected-warning {{expression result unused}}
 
@@ -54,23 +54,23 @@
   int b = 0;
 
   if (a)
-    b < 1; // expected-warning{{expression result unused}}
+    b < 1; // expected-warning{{relational comparison result unused}}
   else
-    b < 2; // expected-warning{{expression result unused}}
+    b < 2; // expected-warning{{relational comparison result unused}}
     
   while (1)
-    b < 3; // expected-warning{{expression result unused}}
+    b < 3; // expected-warning{{relational comparison result unused}}
 
   do
-    b < 4; // expected-warning{{expression result unused}}
+    b < 4; // expected-warning{{relational comparison result unused}}
   while (1);
   
   for (;;)
-    b < 5; // expected-warning{{expression result unused}}
+    b < 5; // expected-warning{{relational comparison result unused}}
     
-  for (b < 1;;) {} // expected-warning{{expression result unused}}
+  for (b < 1;;) {} // expected-warning{{relational comparison result unused}}
   for (;b < 1;) {}
-  for (;;b < 1) {} // expected-warning{{expression result unused}}
+  for (;;b < 1) {} // expected-warning{{relational comparison result unused}}
 }
 
 // rdar://7186119
@@ -91,7 +91,7 @@
   fn1();  // expected-warning {{ignoring return value of function declared with warn_unused_result attribute}}
   fn2(92, 21);  // expected-warning {{ignoring return value of function declared with pure attribute}}
   fn3(42);  // expected-warning {{ignoring return value of function declared with const attribute}}
-  __builtin_fabsf(0); // expected-warning {{ignoring return value of function declared with const attribute}}
+  __builtin_abs(0); // expected-warning {{ignoring return value of function declared with const attribute}}
   (void)0, fn1();  // expected-warning {{ignoring return value of function declared with warn_unused_result attribute}}
   return 0;
 }
diff --git a/test/Sema/var-redecl.c b/test/Sema/var-redecl.c
index 363458b..0e30aa2 100644
--- a/test/Sema/var-redecl.c
+++ b/test/Sema/var-redecl.c
@@ -58,5 +58,5 @@
 
 // PR3645
 static int a;
-extern int a; // expected-note {{previous definition is here}}
+extern int a; // expected-note {{previous declaration is here}}
 int a;	// expected-error {{non-static declaration of 'a' follows static declaration}}
diff --git a/test/Sema/variadic-promotion.c b/test/Sema/variadic-promotion.c
index b248774..01d8e93 100644
--- a/test/Sema/variadic-promotion.c
+++ b/test/Sema/variadic-promotion.c
@@ -6,7 +6,7 @@
   variadic(3, *f16, f32, f64);
 
 // CHECK: ImplicitCastExpr {{.*}} 'double' <FloatingCast>
-// CHECK-NEXT: 'half'
+// CHECK-NEXT: '__fp16'
 
 // CHECK: ImplicitCastExpr {{.*}} 'double' <FloatingCast>
 // CHECK-NEXT: 'float'
diff --git a/test/Sema/vector-assign.c b/test/Sema/vector-assign.c
index f01eb45..ad3406e 100644
--- a/test/Sema/vector-assign.c
+++ b/test/Sema/vector-assign.c
@@ -12,30 +12,30 @@
   v2f v4;
   v4ss v5;
   
-  v1 = v2; // expected-warning {{incompatible vector types assigning to 'v2s' from 'v2u'}}
-  v1 = v3; // expected-error {{assigning to 'v2s' from incompatible type 'v1s'}}
-  v1 = v4; // expected-warning {{incompatible vector types assigning to 'v2s' from 'v2f'}}
-  v1 = v5; // expected-warning {{incompatible vector types assigning to 'v2s' from 'v4ss'}}
+  v1 = v2; // expected-warning {{incompatible vector types assigning to 'v2s' (vector of 2 'int' values) from 'v2u' (vector of 2 'unsigned int' values)}}
+  v1 = v3; // expected-error {{assigning to 'v2s' (vector of 2 'int' values) from incompatible type 'v1s' (vector of 1 'int' value)}}
+  v1 = v4; // expected-warning {{incompatible vector types assigning to 'v2s' (vector of 2 'int' values) from 'v2f' (vector of 2 'float' values)}}
+  v1 = v5; // expected-warning {{incompatible vector types assigning to 'v2s' (vector of 2 'int' values) from 'v4ss' (vector of 4 'short' values)}}
   
-  v2 = v1; // expected-warning {{incompatible vector types assigning to 'v2u' from 'v2s'}}
-  v2 = v3; // expected-error {{assigning to 'v2u' from incompatible type 'v1s'}}
-  v2 = v4; // expected-warning {{incompatible vector types assigning to 'v2u' from 'v2f'}}
-  v2 = v5; // expected-warning {{incompatible vector types assigning to 'v2u' from 'v4ss'}}
+  v2 = v1; // expected-warning {{incompatible vector types assigning to 'v2u' (vector of 2 'unsigned int' values) from 'v2s' (vector of 2 'int' values)}}
+  v2 = v3; // expected-error {{assigning to 'v2u' (vector of 2 'unsigned int' values) from incompatible type 'v1s' (vector of 1 'int' value)}}
+  v2 = v4; // expected-warning {{incompatible vector types assigning to 'v2u' (vector of 2 'unsigned int' values) from 'v2f' (vector of 2 'float' values)}}
+  v2 = v5; // expected-warning {{incompatible vector types assigning to 'v2u' (vector of 2 'unsigned int' values) from 'v4ss' (vector of 4 'short' values)}}
   
-  v3 = v1; // expected-error {{assigning to 'v1s' from incompatible type 'v2s'}}
-  v3 = v2; // expected-error {{assigning to 'v1s' from incompatible type 'v2u'}}
-  v3 = v4; // expected-error {{assigning to 'v1s' from incompatible type 'v2f'}}
-  v3 = v5; // expected-error {{assigning to 'v1s' from incompatible type 'v4ss'}}
+  v3 = v1; // expected-error {{assigning to 'v1s' (vector of 1 'int' value) from incompatible type 'v2s' (vector of 2 'int' values)}}
+  v3 = v2; // expected-error {{assigning to 'v1s' (vector of 1 'int' value) from incompatible type 'v2u' (vector of 2 'unsigned int' values)}}
+  v3 = v4; // expected-error {{assigning to 'v1s' (vector of 1 'int' value) from incompatible type 'v2f' (vector of 2 'float' values)}}
+  v3 = v5; // expected-error {{assigning to 'v1s' (vector of 1 'int' value) from incompatible type 'v4ss'}}
   
-  v4 = v1; // expected-warning {{incompatible vector types assigning to 'v2f' from 'v2s'}}
-  v4 = v2; // expected-warning {{incompatible vector types assigning to 'v2f' from 'v2u'}}
-  v4 = v3; // expected-error {{assigning to 'v2f' from incompatible type 'v1s'}}
-  v4 = v5; // expected-warning {{incompatible vector types assigning to 'v2f' from 'v4ss'}}
+  v4 = v1; // expected-warning {{incompatible vector types assigning to 'v2f' (vector of 2 'float' values) from 'v2s' (vector of 2 'int' values)}}
+  v4 = v2; // expected-warning {{incompatible vector types assigning to 'v2f' (vector of 2 'float' values) from 'v2u' (vector of 2 'unsigned int' values)}}
+  v4 = v3; // expected-error {{assigning to 'v2f' (vector of 2 'float' values) from incompatible type 'v1s' (vector of 1 'int' value)}}
+  v4 = v5; // expected-warning {{incompatible vector types assigning to 'v2f' (vector of 2 'float' values) from 'v4ss' (vector of 4 'short' values)}}
   
-  v5 = v1; // expected-warning {{incompatible vector types assigning to 'v4ss' from 'v2s'}}
-  v5 = v2; // expected-warning {{incompatible vector types assigning to 'v4ss' from 'v2u'}}
-  v5 = v3; // expected-error {{assigning to 'v4ss' from incompatible type 'v1s'}}
-  v5 = v4; // expected-warning {{incompatible vector types assigning to 'v4ss' from 'v2f'}}
+  v5 = v1; // expected-warning {{incompatible vector types assigning to 'v4ss' (vector of 4 'short' values) from 'v2s' (vector of 2 'int' values)}}
+  v5 = v2; // expected-warning {{incompatible vector types assigning to 'v4ss' (vector of 4 'short' values) from 'v2u' (vector of 2 'unsigned int' values)}}
+  v5 = v3; // expected-error {{assigning to 'v4ss' (vector of 4 'short' values) from incompatible type 'v1s' (vector of 1 'int' value)}}
+  v5 = v4; // expected-warning {{incompatible vector types assigning to 'v4ss' (vector of 4 'short' values) from 'v2f'}}
 }
 
 // PR2263
diff --git a/test/Sema/vector-cast.c b/test/Sema/vector-cast.c
index 7fa6e86..0415c13 100644
--- a/test/Sema/vector-cast.c
+++ b/test/Sema/vector-cast.c
@@ -11,28 +11,46 @@
   t3 v3;
   
   v2 = (t2)v1; // expected-error {{invalid conversion between vector type \
-'t2' and 't1' of different size}}
+'t2' (vector of 16 'char' values) and 't1' (vector of 1 'long long' value) of different size}}
   v1 = (t1)v2; // expected-error {{invalid conversion between vector type \
-'t1' and 't2' of different size}}
+'t1' (vector of 1 'long long' value) and 't2' (vector of 16 'char' values) of different size}}
   v3 = (t3)v2;
   
   v1 = (t1)(char *)10; // expected-error {{invalid conversion between vector \
-type 't1' and scalar type 'char *'}}
+type 't1' (vector of 1 'long long' value) and scalar type 'char *'}}
   v1 = (t1)(long long)10;
   v1 = (t1)(short)10; // expected-error {{invalid conversion between vector \
-type 't1' and integer type 'short' of different size}}
+type 't1' (vector of 1 'long long' value) and integer type 'short' of different size}}
   
   long long r1 = (long long)v1;
   short r2 = (short)v1; // expected-error {{invalid conversion between vector \
-type 't1' and integer type 'short' of different size}}
+type 't1' (vector of 1 'long long' value) and integer type 'short' of different size}}
   char *r3 = (char *)v1; // expected-error {{invalid conversion between vector\
- type 't1' and scalar type 'char *'}}
+ type 't1' (vector of 1 'long long' value) and scalar type 'char *'}}
 }
 
 
 void f2(t2 X); // expected-note{{passing argument to parameter 'X' here}}
 
 void f3(t3 Y) {
-  f2(Y);  // expected-warning {{incompatible vector types passing 't3' to parameter of type 't2'}}
+  f2(Y);  // expected-warning {{incompatible vector types passing 't3' (vector of 4 'float' values) to parameter of type 't2' (vector of 16 'char' values)}}
 }
 
+typedef float float2 __attribute__ ((vector_size (8)));
+
+void f4() {
+  float2 f2;
+  double d;
+  f2 += d;
+  d += f2;
+}
+
+// rdar://15931426
+// Don't permit a lax conversion to and from a pointer type.
+typedef short short_sizeof_pointer __attribute__((vector_size(sizeof(void*))));
+void f5() {
+  short_sizeof_pointer v;
+  void *ptr;
+  v = ptr; // expected-error-re {{assigning to 'short_sizeof_pointer' (vector of {{[0-9]+}} 'short' values) from incompatible type 'void *'}}
+  ptr = v; // expected-error {{assigning to 'void *' from incompatible type 'short_sizeof_pointer'}}
+}
diff --git a/test/Sema/vector-init.c b/test/Sema/vector-init.c
index 5be040a..9f27bb8 100644
--- a/test/Sema/vector-init.c
+++ b/test/Sema/vector-init.c
@@ -40,5 +40,5 @@
 void test3() {
   extern short8 test3_helper(void);
   longlong2 arr1[2] = { test3_helper(), test3_helper() };
-  short4 arr2[2] = { test3_helper(), test3_helper() }; // expected-error 2 {{initializing 'short4' with an expression of incompatible type 'short8'}}
+  short4 arr2[2] = { test3_helper(), test3_helper() }; // expected-error 2 {{initializing 'short4' (vector of 4 'short' values) with an expression of incompatible type 'short8' (vector of 8 'short' values)}}
 }
diff --git a/test/Sema/vector-ops.c b/test/Sema/vector-ops.c
index 652a076..f295341 100644
--- a/test/Sema/vector-ops.c
+++ b/test/Sema/vector-ops.c
@@ -10,14 +10,14 @@
 
   // Unary operators
   (void)(~v2ua);
-  (void)(~v2fa); // expected-error{{invalid argument type 'v2f' to unary}}
+  (void)(~v2fa); // expected-error{{invalid argument type 'v2f' (vector of 2 'float' values) to unary}}
 
   // Comparison operators
-  v2ua = (v2ua==v2sa); // expected-warning{{incompatible vector types assigning to 'v2u' from 'int __attribute__((ext_vector_type(2)))'}}
+  v2ua = (v2ua==v2sa); // expected-warning{{incompatible vector types assigning to 'v2u' (vector of 2 'unsigned int' values) from 'int __attribute__((ext_vector_type(2)))' (vector of 2 'int' values)}}
   v2sa = (v2ua==v2sa);
   
   // Arrays
-  int array1[v2ua]; // expected-error{{size of array has non-integer type 'v2u'}}
+  int array1[v2ua]; // expected-error{{size of array has non-integer type 'v2u' (vector of 2 'unsigned int' values)}}
   int array2[17];
   // FIXME: error message below needs type!
   (void)(array2[v2ua]); // expected-error{{array subscript is not an integer}}
diff --git a/test/Sema/vla.c b/test/Sema/vla.c
index 4fd6361..e03dda8 100644
--- a/test/Sema/vla.c
+++ b/test/Sema/vla.c
@@ -19,7 +19,7 @@
 // PR2352
 void f2(unsigned int m)
 {
-  extern int e1[2][m]; // expected-error {{variable length array declaration can not have 'extern' linkage}}
+  extern int e1[2][m]; // expected-error {{variable length array declaration cannot have 'extern' linkage}}
 
   e1[0][0] = 0;
   
@@ -34,10 +34,10 @@
 
 void f3()
 {
-  static int a[i]; // expected-error {{variable length array declaration can not have 'static' storage duration}}
-  extern int b[i]; // expected-error {{variable length array declaration can not have 'extern' linkage}}
+  static int a[i]; // expected-error {{variable length array declaration cannot have 'static' storage duration}}
+  extern int b[i]; // expected-error {{variable length array declaration cannot have 'extern' linkage}}
 
-  extern int (*c1)[i]; // expected-error {{variably modified type declaration can not have 'extern' linkage}}
+  extern int (*c1)[i]; // expected-error {{variably modified type declaration cannot have 'extern' linkage}}
   static int (*d)[i];
 }
 
diff --git a/test/Sema/warn-absolute-value-header.c b/test/Sema/warn-absolute-value-header.c
new file mode 100644
index 0000000..0c7c3a8
--- /dev/null
+++ b/test/Sema/warn-absolute-value-header.c
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -verify %s -Wabsolute-value
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only %s -Wabsolute-value -fdiagnostics-parseable-fixits 2>&1 | FileCheck %s
+
+int abs(int);
+
+// Wrong signature
+int fabsf(int);
+// expected-warning@-1{{incompatible redeclaration of library function 'fabsf'}}
+// expected-note@-2{{'fabsf' is a builtin with type 'float (float)'}}
+
+void test_int(int i, unsigned u, long long ll, float f, double d) {
+  (void)abs(i);
+
+  // Remove abs call
+  (void)abs(u);
+  // expected-warning@-1{{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2{{remove the call to 'abs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:""
+
+  int llabs;
+  (void)llabs;
+  // Conflict in names, no notes
+  (void)abs(ll);
+  // expected-warning@-1{{absolute value function 'abs' given an argument of type 'long long' but has parameter of type 'int' which may cause truncation of value}}
+
+  // Conflict in names, no notes
+  (void)abs(f);
+  // expected-warning@-1{{using integer absolute value function 'abs' when argument is of floating point type}}
+
+  // Suggest header.
+  (void)abs(d);
+  // expected-warning@-1{{using integer absolute value function 'abs' when argument is of floating point type}}
+  // expected-note@-2{{use function 'fabs' instead}}
+  // expected-note@-3{{include the header <math.h> or explicitly provide a declaration for 'fabs'}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:9-[[@LINE-4]]:12}:"fabs"
+}
diff --git a/test/Sema/warn-absolute-value.c b/test/Sema/warn-absolute-value.c
new file mode 100644
index 0000000..70601db
--- /dev/null
+++ b/test/Sema/warn-absolute-value.c
@@ -0,0 +1,782 @@
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -verify %s -Wabsolute-value
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only %s -Wabsolute-value -fdiagnostics-parseable-fixits 2>&1 | FileCheck %s
+
+int abs(int);
+long int labs(long int);
+long long int llabs(long long int);
+
+float fabsf(float);
+double fabs(double);
+long double fabsl(long double);
+
+float cabsf(float _Complex);
+double cabs(double _Complex);
+long double cabsl(long double _Complex);
+
+void test_int(int x) {
+  (void)abs(x);
+  (void)labs(x);
+  (void)llabs(x);
+
+  (void)fabsf(x);
+  // expected-warning@-1 {{using floating point absolute value function 'fabsf' when argument is of integer type}}
+  // expected-note@-2 {{use function 'abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"abs"
+  (void)fabs(x);
+  // expected-warning@-1 {{using floating point absolute value function 'fabs' when argument is of integer type}}
+  // expected-note@-2 {{use function 'abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"abs"
+  (void)fabsl(x);
+  // expected-warning@-1 {{using floating point absolute value function 'fabsl' when argument is of integer type}}
+  // expected-note@-2 {{use function 'abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"abs"
+
+  (void)cabsf(x);
+  // expected-warning@-1 {{using complex absolute value function 'cabsf' when argument is of integer type}}
+  // expected-note@-2 {{use function 'abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"abs"
+  (void)cabs(x);
+  // expected-warning@-1 {{using complex absolute value function 'cabs' when argument is of integer type}}
+  // expected-note@-2 {{use function 'abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"abs"
+  (void)cabsl(x);
+  // expected-warning@-1 {{using complex absolute value function 'cabsl' when argument is of integer type}}
+  // expected-note@-2 {{use function 'abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"abs"
+
+  (void)__builtin_abs(x);
+  (void)__builtin_labs(x);
+  (void)__builtin_llabs(x);
+
+  (void)__builtin_fabsf(x);
+  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsf' when argument is of integer type}}
+  // expected-note@-2 {{use function '__builtin_abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_abs"
+  (void)__builtin_fabs(x);
+  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabs' when argument is of integer type}}
+  // expected-note@-2 {{use function '__builtin_abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_abs"
+  (void)__builtin_fabsl(x);
+  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsl' when argument is of integer type}}
+  // expected-note@-2 {{use function '__builtin_abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_abs"
+
+  (void)__builtin_cabsf(x);
+  // expected-warning@-1 {{using complex absolute value function '__builtin_cabsf' when argument is of integer type}}
+  // expected-note@-2 {{use function '__builtin_abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_abs"
+  (void)__builtin_cabs(x);
+  // expected-warning@-1 {{using complex absolute value function '__builtin_cabs' when argument is of integer type}}
+  // expected-note@-2 {{use function '__builtin_abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_abs"
+  (void)__builtin_cabsl(x);
+  // expected-warning@-1 {{using complex absolute value function '__builtin_cabsl' when argument is of integer type}}
+  // expected-note@-2 {{use function '__builtin_abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_abs"
+}
+
+void test_long(long x) {
+  (void)abs(x);  // no warning - int and long are same length for this target
+  (void)labs(x);
+  (void)llabs(x);
+
+  (void)fabsf(x);
+  // expected-warning@-1 {{using floating point absolute value function 'fabsf' when argument is of integer type}}
+  // expected-note@-2 {{use function 'labs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"labs"
+  (void)fabs(x);
+  // expected-warning@-1 {{using floating point absolute value function 'fabs' when argument is of integer type}}
+  // expected-note@-2 {{use function 'labs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"labs"
+  (void)fabsl(x);
+  // expected-warning@-1 {{using floating point absolute value function 'fabsl' when argument is of integer type}}
+  // expected-note@-2 {{use function 'labs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"labs"
+
+  (void)cabsf(x);
+  // expected-warning@-1 {{using complex absolute value function 'cabsf' when argument is of integer type}}
+  // expected-note@-2 {{use function 'labs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"labs"
+  (void)cabs(x);
+  // expected-warning@-1 {{using complex absolute value function 'cabs' when argument is of integer type}}
+  // expected-note@-2 {{use function 'labs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"labs"
+  (void)cabsl(x);
+  // expected-warning@-1 {{using complex absolute value function 'cabsl' when argument is of integer type}}
+  // expected-note@-2 {{use function 'labs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"labs"
+
+  (void)__builtin_abs(x);  // no warning - int and long are same length for
+                           // this target
+  (void)__builtin_labs(x);
+  (void)__builtin_llabs(x);
+
+  (void)__builtin_fabsf(x);
+  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsf' when argument is of integer type}}
+  // expected-note@-2 {{use function '__builtin_labs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_labs"
+  (void)__builtin_fabs(x);
+  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabs' when argument is of integer type}}
+  // expected-note@-2 {{use function '__builtin_labs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_labs"
+  (void)__builtin_fabsl(x);
+  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsl' when argument is of integer type}}
+  // expected-note@-2 {{use function '__builtin_labs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_labs"
+
+  (void)__builtin_cabsf(x);
+  // expected-warning@-1 {{using complex absolute value function '__builtin_cabsf' when argument is of integer type}}
+  // expected-note@-2 {{use function '__builtin_labs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_labs"
+  (void)__builtin_cabs(x);
+  // expected-warning@-1 {{using complex absolute value function '__builtin_cabs' when argument is of integer type}}
+  // expected-note@-2 {{use function '__builtin_labs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_labs"
+  (void)__builtin_cabsl(x);
+  // expected-warning@-1 {{using complex absolute value function '__builtin_cabsl' when argument is of integer type}}
+  // expected-note@-2 {{use function '__builtin_labs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_labs"
+}
+
+void test_long_long(long long x) {
+  (void)abs(x);
+  // expected-warning@-1{{absolute value function 'abs' given an argument of type 'long long' but has parameter of type 'int' which may cause truncation of value}}
+  // expected-note@-2{{use function 'llabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:"llabs"
+  (void)labs(x);
+  // expected-warning@-1{{absolute value function 'labs' given an argument of type 'long long' but has parameter of type 'long' which may cause truncation of value}}
+  // expected-note@-2{{use function 'llabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"llabs"
+  (void)llabs(x);
+
+  (void)fabsf(x);
+  // expected-warning@-1 {{using floating point absolute value function 'fabsf' when argument is of integer type}}
+  // expected-note@-2 {{use function 'llabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"llabs"
+  (void)fabs(x);
+  // expected-warning@-1 {{using floating point absolute value function 'fabs' when argument is of integer type}}
+  // expected-note@-2 {{use function 'llabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"llabs"
+  (void)fabsl(x);
+  // expected-warning@-1 {{using floating point absolute value function 'fabsl' when argument is of integer type}}
+  // expected-note@-2 {{use function 'llabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"llabs"
+
+  (void)cabsf(x);
+  // expected-warning@-1 {{using complex absolute value function 'cabsf' when argument is of integer type}}
+  // expected-note@-2 {{use function 'llabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"llabs"
+  (void)cabs(x);
+  // expected-warning@-1 {{using complex absolute value function 'cabs' when argument is of integer type}}
+  // expected-note@-2 {{use function 'llabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"llabs"
+  (void)cabsl(x);
+  // expected-warning@-1 {{using complex absolute value function 'cabsl' when argument is of integer type}}
+  // expected-note@-2 {{use function 'llabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"llabs"
+
+  (void)__builtin_abs(x);
+  // expected-warning@-1{{absolute value function '__builtin_abs' given an argument of type 'long long' but has parameter of type 'int' which may cause truncation of value}}
+  // expected-note@-2{{use function '__builtin_llabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:22}:"__builtin_llabs"
+  (void)__builtin_labs(x);
+  // expected-warning@-1{{absolute value function '__builtin_labs' given an argument of type 'long long' but has parameter of type 'long' which may cause truncation of value}}
+  // expected-note@-2{{use function '__builtin_llabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_llabs"
+  (void)__builtin_llabs(x);
+
+  (void)__builtin_fabsf(x);
+  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsf' when argument is of integer type}}
+  // expected-note@-2 {{use function '__builtin_llabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_llabs"
+  (void)__builtin_fabs(x);
+  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabs' when argument is of integer type}}
+  // expected-note@-2 {{use function '__builtin_llabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_llabs"
+  (void)__builtin_fabsl(x);
+  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsl' when argument is of integer type}}
+  // expected-note@-2 {{use function '__builtin_llabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_llabs"
+
+  (void)__builtin_cabsf(x);
+  // expected-warning@-1 {{using complex absolute value function '__builtin_cabsf' when argument is of integer type}}
+  // expected-note@-2 {{use function '__builtin_llabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_llabs"
+  (void)__builtin_cabs(x);
+  // expected-warning@-1 {{using complex absolute value function '__builtin_cabs' when argument is of integer type}}
+  // expected-note@-2 {{use function '__builtin_llabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_llabs"
+  (void)__builtin_cabsl(x);
+  // expected-warning@-1 {{using complex absolute value function '__builtin_cabsl' when argument is of integer type}}
+  // expected-note@-2 {{use function '__builtin_llabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_llabs"
+}
+
+void test_float(float x) {
+  (void)abs(x);
+  // expected-warning@-1 {{using integer absolute value function 'abs' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'fabsf' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:"fabsf"
+  (void)labs(x);
+  // expected-warning@-1 {{using integer absolute value function 'labs' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'fabsf' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"fabsf"
+  (void)llabs(x);
+  // expected-warning@-1 {{using integer absolute value function 'llabs' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'fabsf' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"fabsf"
+
+  (void)fabsf(x);
+  (void)fabs(x);
+  (void)fabsl(x);
+
+  (void)cabsf(x);
+  // expected-warning@-1 {{using complex absolute value function 'cabsf' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'fabsf' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"fabsf"
+  (void)cabs(x);
+  // expected-warning@-1 {{using complex absolute value function 'cabs' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'fabsf' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"fabsf"
+  (void)cabsl(x);
+  // expected-warning@-1 {{using complex absolute value function 'cabsl' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'fabsf' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"fabsf"
+
+  (void)__builtin_abs(x);
+  // expected-warning@-1 {{using integer absolute value function '__builtin_abs' when argument is of floating point type}}
+  // expected-note@-2 {{use function '__builtin_fabsf' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:22}:"__builtin_fabsf"
+  (void)__builtin_labs(x);
+  // expected-warning@-1 {{using integer absolute value function '__builtin_labs' when argument is of floating point type}}
+  // expected-note@-2 {{use function '__builtin_fabsf' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_fabsf"
+  (void)__builtin_llabs(x);
+  // expected-warning@-1 {{using integer absolute value function '__builtin_llabs' when argument is of floating point type}}
+  // expected-note@-2 {{use function '__builtin_fabsf' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_fabsf"
+
+  (void)__builtin_fabsf(x);
+  (void)__builtin_fabs(x);
+  (void)__builtin_fabsl(x);
+
+  (void)__builtin_cabsf(x);
+  // expected-warning@-1 {{using complex absolute value function '__builtin_cabsf' when argument is of floating point type}}
+  // expected-note@-2 {{use function '__builtin_fabsf' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_fabsf"
+  (void)__builtin_cabs(x);
+  // expected-warning@-1 {{using complex absolute value function '__builtin_cabs' when argument is of floating point type}}
+  // expected-note@-2 {{use function '__builtin_fabsf' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_fabsf"
+  (void)__builtin_cabsl(x);
+  // expected-warning@-1 {{using complex absolute value function '__builtin_cabsl' when argument is of floating point type}}
+  // expected-note@-2 {{use function '__builtin_fabsf' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_fabsf"
+}
+
+void test_double(double x) {
+  (void)abs(x);
+  // expected-warning@-1 {{using integer absolute value function 'abs' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'fabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:"fabs"
+  (void)labs(x);
+  // expected-warning@-1 {{using integer absolute value function 'labs' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'fabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"fabs"
+  (void)llabs(x);
+  // expected-warning@-1 {{using integer absolute value function 'llabs' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'fabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"fabs"
+
+  (void)fabsf(x);
+  // expected-warning@-1{{absolute value function 'fabsf' given an argument of type 'double' but has parameter of type 'float' which may cause truncation of value}}
+  // expected-note@-2{{use function 'fabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"fabs"
+  (void)fabs(x);
+  (void)fabsl(x);
+
+  (void)cabsf(x);
+  // expected-warning@-1 {{using complex absolute value function 'cabsf' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'fabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"fabs"
+  (void)cabs(x);
+  // expected-warning@-1 {{using complex absolute value function 'cabs' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'fabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"fabs"
+  (void)cabsl(x);
+  // expected-warning@-1 {{using complex absolute value function 'cabsl' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'fabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"fabs"
+
+  (void)__builtin_abs(x);
+  // expected-warning@-1 {{using integer absolute value function '__builtin_abs' when argument is of floating point type}}
+  // expected-note@-2 {{use function '__builtin_fabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:22}:"__builtin_fabs"
+  (void)__builtin_labs(x);
+  // expected-warning@-1 {{using integer absolute value function '__builtin_labs' when argument is of floating point type}}
+  // expected-note@-2 {{use function '__builtin_fabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_fabs"
+  (void)__builtin_llabs(x);
+  // expected-warning@-1 {{using integer absolute value function '__builtin_llabs' when argument is of floating point type}}
+  // expected-note@-2 {{use function '__builtin_fabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_fabs"
+
+  (void)__builtin_fabsf(x);
+  // expected-warning@-1{{absolute value function '__builtin_fabsf' given an argument of type 'double' but has parameter of type 'float' which may cause truncation of value}}
+  // expected-note@-2{{use function '__builtin_fabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_fabs"
+  (void)__builtin_fabs(x);
+  (void)__builtin_fabsl(x);
+
+  (void)__builtin_cabsf(x);
+  // expected-warning@-1 {{using complex absolute value function '__builtin_cabsf' when argument is of floating point type}}
+  // expected-note@-2 {{use function '__builtin_fabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_fabs"
+  (void)__builtin_cabs(x);
+  // expected-warning@-1 {{using complex absolute value function '__builtin_cabs' when argument is of floating point type}}
+  // expected-note@-2 {{use function '__builtin_fabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_fabs"
+  (void)__builtin_cabsl(x);
+  // expected-warning@-1 {{using complex absolute value function '__builtin_cabsl' when argument is of floating point type}}
+  // expected-note@-2 {{use function '__builtin_fabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_fabs"
+}
+
+void test_long_double(long double x) {
+  (void)abs(x);
+  // expected-warning@-1 {{using integer absolute value function 'abs' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'fabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:"fabsl"
+  (void)labs(x);
+  // expected-warning@-1 {{using integer absolute value function 'labs' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'fabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"fabsl"
+  (void)llabs(x);
+  // expected-warning@-1 {{using integer absolute value function 'llabs' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'fabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"fabsl"
+
+  (void)fabsf(x);
+  // expected-warning@-1{{absolute value function 'fabsf' given an argument of type 'long double' but has parameter of type 'float' which may cause truncation of value}}
+  // expected-note@-2{{use function 'fabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"fabsl"
+  (void)fabs(x);
+  // expected-warning@-1{{absolute value function 'fabs' given an argument of type 'long double' but has parameter of type 'double' which may cause truncation of value}}
+  // expected-note@-2{{use function 'fabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"fabsl"
+  (void)fabsl(x);
+
+  (void)cabsf(x);
+  // expected-warning@-1 {{using complex absolute value function 'cabsf' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'fabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"fabsl"
+  (void)cabs(x);
+  // expected-warning@-1 {{using complex absolute value function 'cabs' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'fabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"fabsl"
+  (void)cabsl(x);
+  // expected-warning@-1 {{using complex absolute value function 'cabsl' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'fabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"fabsl"
+
+  (void)__builtin_abs(x);
+  // expected-warning@-1 {{using integer absolute value function '__builtin_abs' when argument is of floating point type}}
+  // expected-note@-2 {{use function '__builtin_fabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:22}:"__builtin_fabsl"
+  (void)__builtin_labs(x);
+  // expected-warning@-1 {{using integer absolute value function '__builtin_labs' when argument is of floating point type}}
+  // expected-note@-2 {{use function '__builtin_fabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_fabsl"
+  (void)__builtin_llabs(x);
+  // expected-warning@-1 {{using integer absolute value function '__builtin_llabs' when argument is of floating point type}}
+  // expected-note@-2 {{use function '__builtin_fabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_fabsl"
+
+  (void)__builtin_fabsf(x);
+  // expected-warning@-1{{absolute value function '__builtin_fabsf' given an argument of type 'long double' but has parameter of type 'float' which may cause truncation of value}}
+  // expected-note@-2{{use function '__builtin_fabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_fabsl"
+  (void)__builtin_fabs(x);
+  // expected-warning@-1{{absolute value function '__builtin_fabs' given an argument of type 'long double' but has parameter of type 'double' which may cause truncation of value}}
+  // expected-note@-2{{use function '__builtin_fabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_fabsl"
+  (void)__builtin_fabsl(x);
+
+  (void)__builtin_cabsf(x);
+  // expected-warning@-1 {{using complex absolute value function '__builtin_cabsf' when argument is of floating point type}}
+  // expected-note@-2 {{use function '__builtin_fabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_fabsl"
+  (void)__builtin_cabs(x);
+  // expected-warning@-1 {{using complex absolute value function '__builtin_cabs' when argument is of floating point type}}
+  // expected-note@-2 {{use function '__builtin_fabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_fabsl"
+  (void)__builtin_cabsl(x);
+  // expected-warning@-1 {{using complex absolute value function '__builtin_cabsl' when argument is of floating point type}}
+  // expected-note@-2 {{use function '__builtin_fabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_fabsl"
+}
+
+void test_complex_float(_Complex float x) {
+  (void)abs(x);
+  // expected-warning@-1 {{using integer absolute value function 'abs' when argument is of complex type}}
+  // expected-note@-2 {{use function 'cabsf' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:"cabsf"
+  (void)labs(x);
+  // expected-warning@-1 {{using integer absolute value function 'labs' when argument is of complex type}}
+  // expected-note@-2 {{use function 'cabsf' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabsf"
+  (void)llabs(x);
+  // expected-warning@-1 {{using integer absolute value function 'llabs' when argument is of complex type}}
+  // expected-note@-2 {{use function 'cabsf' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsf"
+
+  (void)fabsf(x);
+  // expected-warning@-1 {{using floating point absolute value function 'fabsf' when argument is of complex type}}
+  // expected-note@-2 {{use function 'cabsf' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsf"
+  (void)fabs(x);
+  // expected-warning@-1 {{using floating point absolute value function 'fabs' when argument is of complex type}}
+  // expected-note@-2 {{use function 'cabsf' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabsf"
+  (void)fabsl(x);
+  // expected-warning@-1 {{using floating point absolute value function 'fabsl' when argument is of complex type}}
+  // expected-note@-2 {{use function 'cabsf' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsf"
+
+  (void)cabsf(x);
+  (void)cabs(x);
+  (void)cabsl(x);
+
+  (void)__builtin_abs(x);
+  // expected-warning@-1 {{using integer absolute value function '__builtin_abs' when argument is of complex type}}
+  // expected-note@-2 {{use function '__builtin_cabsf' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:22}:"__builtin_cabsf"
+  (void)__builtin_labs(x);
+  // expected-warning@-1 {{using integer absolute value function '__builtin_labs' when argument is of complex type}}
+  // expected-note@-2 {{use function '__builtin_cabsf' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabsf"
+  (void)__builtin_llabs(x);
+  // expected-warning@-1 {{using integer absolute value function '__builtin_llabs' when argument is of complex type}}
+  // expected-note@-2 {{use function '__builtin_cabsf' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsf"
+
+  (void)__builtin_fabsf(x);
+  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsf' when argument is of complex type}}
+  // expected-note@-2 {{use function '__builtin_cabsf' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsf"
+  (void)__builtin_fabs(x);
+  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabs' when argument is of complex type}}
+  // expected-note@-2 {{use function '__builtin_cabsf' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabsf"
+  (void)__builtin_fabsl(x);
+  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsl' when argument is of complex type}}
+  // expected-note@-2 {{use function '__builtin_cabsf' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsf"
+
+  (void)__builtin_cabsf(x);
+  (void)__builtin_cabs(x);
+  (void)__builtin_cabsl(x);
+}
+
+void test_complex_double(_Complex double x) {
+  (void)abs(x);
+  // expected-warning@-1 {{using integer absolute value function 'abs' when argument is of complex type}}
+  // expected-note@-2 {{use function 'cabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:"cabs"
+  (void)labs(x);
+  // expected-warning@-1 {{using integer absolute value function 'labs' when argument is of complex type}}
+  // expected-note@-2 {{use function 'cabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabs"
+  (void)llabs(x);
+  // expected-warning@-1 {{using integer absolute value function 'llabs' when argument is of complex type}}
+  // expected-note@-2 {{use function 'cabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabs"
+
+  (void)fabsf(x);
+  // expected-warning@-1 {{using floating point absolute value function 'fabsf' when argument is of complex type}}
+  // expected-note@-2 {{use function 'cabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabs"
+  (void)fabs(x);
+  // expected-warning@-1 {{using floating point absolute value function 'fabs' when argument is of complex type}}
+  // expected-note@-2 {{use function 'cabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabs"
+  (void)fabsl(x);
+  // expected-warning@-1 {{using floating point absolute value function 'fabsl' when argument is of complex type}}
+  // expected-note@-2 {{use function 'cabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabs"
+
+  (void)cabsf(x);
+  // expected-warning@-1 {{absolute value function 'cabsf' given an argument of type '_Complex double' but has parameter of type '_Complex float' which may cause truncation of value}}
+  // expected-note@-2 {{use function 'cabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabs"
+  (void)cabs(x);
+  (void)cabsl(x);
+
+  (void)__builtin_abs(x);
+  // expected-warning@-1 {{using integer absolute value function '__builtin_abs' when argument is of complex type}}
+  // expected-note@-2 {{use function '__builtin_cabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:22}:"__builtin_cabs"
+  (void)__builtin_labs(x);
+  // expected-warning@-1 {{using integer absolute value function '__builtin_labs' when argument is of complex type}}
+  // expected-note@-2 {{use function '__builtin_cabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabs"
+  (void)__builtin_llabs(x);
+  // expected-warning@-1 {{using integer absolute value function '__builtin_llabs' when argument is of complex type}}
+  // expected-note@-2 {{use function '__builtin_cabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabs"
+
+  (void)__builtin_fabsf(x);
+  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsf' when argument is of complex type}}
+  // expected-note@-2 {{use function '__builtin_cabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabs"
+  (void)__builtin_fabs(x);
+  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabs' when argument is of complex type}}
+  // expected-note@-2 {{use function '__builtin_cabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabs"
+  (void)__builtin_fabsl(x);
+  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsl' when argument is of complex type}}
+  // expected-note@-2 {{use function '__builtin_cabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabs"
+
+  (void)__builtin_cabsf(x);
+  // expected-warning@-1 {{absolute value function '__builtin_cabsf' given an argument of type '_Complex double' but has parameter of type '_Complex float' which may cause truncation of value}}
+  // expected-note@-2 {{use function '__builtin_cabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabs"
+  (void)__builtin_cabs(x);
+  (void)__builtin_cabsl(x);
+}
+
+void test_complex_long_double(_Complex long double x) {
+  (void)abs(x);
+  // expected-warning@-1 {{using integer absolute value function 'abs' when argument is of complex type}}
+  // expected-note@-2 {{use function 'cabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:"cabsl"
+  (void)labs(x);
+  // expected-warning@-1 {{using integer absolute value function 'labs' when argument is of complex type}}
+  // expected-note@-2 {{use function 'cabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabsl"
+  (void)llabs(x);
+  // expected-warning@-1 {{using integer absolute value function 'llabs' when argument is of complex type}}
+  // expected-note@-2 {{use function 'cabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsl"
+
+  (void)fabsf(x);
+  // expected-warning@-1 {{using floating point absolute value function 'fabsf' when argument is of complex type}}
+  // expected-note@-2 {{use function 'cabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsl"
+  (void)fabs(x);
+  // expected-warning@-1 {{using floating point absolute value function 'fabs' when argument is of complex type}}
+  // expected-note@-2 {{use function 'cabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabsl"
+  (void)fabsl(x);
+  // expected-warning@-1 {{using floating point absolute value function 'fabsl' when argument is of complex type}}
+  // expected-note@-2 {{use function 'cabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsl"
+
+  (void)cabsf(x);
+  // expected-warning@-1 {{absolute value function 'cabsf' given an argument of type '_Complex long double' but has parameter of type '_Complex float' which may cause truncation of value}}
+  // expected-note@-2 {{use function 'cabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsl"
+  (void)cabs(x);
+  // expected-warning@-1 {{absolute value function 'cabs' given an argument of type '_Complex long double' but has parameter of type '_Complex double' which may cause truncation of value}}
+  // expected-note@-2 {{use function 'cabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabsl"
+  (void)cabsl(x);
+
+  (void)__builtin_abs(x);
+  // expected-warning@-1 {{using integer absolute value function '__builtin_abs' when argument is of complex type}}
+  // expected-note@-2 {{use function '__builtin_cabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:22}:"__builtin_cabsl"
+  (void)__builtin_labs(x);
+  // expected-warning@-1 {{using integer absolute value function '__builtin_labs' when argument is of complex type}}
+  // expected-note@-2 {{use function '__builtin_cabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabsl"
+  (void)__builtin_llabs(x);
+  // expected-warning@-1 {{using integer absolute value function '__builtin_llabs' when argument is of complex type}}
+  // expected-note@-2 {{use function '__builtin_cabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsl"
+
+  (void)__builtin_fabsf(x);
+  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsf' when argument is of complex type}}
+  // expected-note@-2 {{use function '__builtin_cabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsl"
+  (void)__builtin_fabs(x);
+  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabs' when argument is of complex type}}
+  // expected-note@-2 {{use function '__builtin_cabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabsl"
+  (void)__builtin_fabsl(x);
+  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsl' when argument is of complex type}}
+  // expected-note@-2 {{use function '__builtin_cabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsl"
+
+  (void)__builtin_cabsf(x);
+  // expected-warning@-1 {{absolute value function '__builtin_cabsf' given an argument of type '_Complex long double' but has parameter of type '_Complex float' which may cause truncation of value}}
+  // expected-note@-2 {{use function '__builtin_cabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsl"
+  (void)__builtin_cabs(x);
+  // expected-warning@-1 {{absolute value function '__builtin_cabs' given an argument of type '_Complex long double' but has parameter of type '_Complex double' which may cause truncation of value}}
+  // expected-note@-2 {{use function '__builtin_cabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabsl"
+  (void)__builtin_cabsl(x);
+}
+
+void test_unsigned_int(unsigned int x) {
+  (void)abs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2 {{remove the call to 'abs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:""
+  (void)labs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2 {{remove the call to 'labs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:""
+  (void)llabs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2 {{remove the call to 'llabs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:""
+
+  (void)fabsf(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2 {{remove the call to 'fabsf' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:""
+  (void)fabs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2 {{remove the call to 'fabs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:""
+  (void)fabsl(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2 {{remove the call to 'fabsl' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:""
+
+  (void)cabsf(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2 {{remove the call to 'cabsf' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:""
+  (void)cabs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2 {{remove the call to 'cabs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:""
+  (void)cabsl(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2 {{remove the call to 'cabsl' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:""
+
+  (void)__builtin_abs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2 {{remove the call to '__builtin_abs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:22}:""
+  (void)__builtin_labs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2 {{remove the call to '__builtin_labs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:""
+  (void)__builtin_llabs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2 {{remove the call to '__builtin_llabs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:""
+
+  (void)__builtin_fabsf(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2 {{remove the call to '__builtin_fabsf' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:""
+  (void)__builtin_fabs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2 {{remove the call to '__builtin_fabs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:""
+  (void)__builtin_fabsl(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2 {{remove the call to '__builtin_fabsl' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:""
+
+  (void)__builtin_cabsf(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2 {{remove the call to '__builtin_cabsf' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:""
+  (void)__builtin_cabs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2 {{remove the call to '__builtin_cabs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:""
+  (void)__builtin_cabsl(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2 {{remove the call to '__builtin_cabsl' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:""
+}
+
+void test_unsigned_long(unsigned long x) {
+  (void)abs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+  // expected-note@-2 {{remove the call to 'abs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:""
+  (void)labs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+  // expected-note@-2 {{remove the call to 'labs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:""
+  (void)llabs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+  // expected-note@-2 {{remove the call to 'llabs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:""
+
+  (void)fabsf(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+  // expected-note@-2 {{remove the call to 'fabsf' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:""
+  (void)fabs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+  // expected-note@-2 {{remove the call to 'fabs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:""
+  (void)fabsl(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+  // expected-note@-2 {{remove the call to 'fabsl' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:""
+
+  (void)cabsf(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+  // expected-note@-2 {{remove the call to 'cabsf' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:""
+  (void)cabs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+  // expected-note@-2 {{remove the call to 'cabs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:""
+  (void)cabsl(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+  // expected-note@-2 {{remove the call to 'cabsl' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:""
+
+  (void)__builtin_abs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+  // expected-note@-2 {{remove the call to '__builtin_abs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:22}:""
+  (void)__builtin_labs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+  // expected-note@-2 {{remove the call to '__builtin_labs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:""
+  (void)__builtin_llabs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+  // expected-note@-2 {{remove the call to '__builtin_llabs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:""
+
+  (void)__builtin_fabsf(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+  // expected-note@-2 {{remove the call to '__builtin_fabsf' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:""
+  (void)__builtin_fabs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+  // expected-note@-2 {{remove the call to '__builtin_fabs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:""
+  (void)__builtin_fabsl(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+  // expected-note@-2 {{remove the call to '__builtin_fabsl' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:""
+
+  (void)__builtin_cabsf(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+  // expected-note@-2 {{remove the call to '__builtin_cabsf' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:""
+  (void)__builtin_cabs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+  // expected-note@-2 {{remove the call to '__builtin_cabs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:""
+  (void)__builtin_cabsl(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+  // expected-note@-2 {{remove the call to '__builtin_cabsl' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:""
+}
+
diff --git a/test/Sema/warn-bitwise-compare.c b/test/Sema/warn-bitwise-compare.c
new file mode 100644
index 0000000..175f8f5
--- /dev/null
+++ b/test/Sema/warn-bitwise-compare.c
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wtautological-compare %s
+
+#define mydefine 2
+
+void f(int x) {
+  if ((8 & x) == 3) {}  // expected-warning {{bitwise comparison always evaluates to false}}
+  if ((x & 8) == 4) {}  // expected-warning {{bitwise comparison always evaluates to false}}
+  if ((x & 8) != 4) {}  // expected-warning {{bitwise comparison always evaluates to true}}
+  if ((2 & x) != 4) {}  // expected-warning {{bitwise comparison always evaluates to true}}
+  if ((x | 4) == 3) {}  // expected-warning {{bitwise comparison always evaluates to false}}
+  if ((x | 3) != 4) {}  // expected-warning {{bitwise comparison always evaluates to true}}
+  if ((5 | x) != 3) {}  // expected-warning {{bitwise comparison always evaluates to true}}
+  if ((x & 0x15) == 0x13) {} // expected-warning {{bitwise comparison always evaluates to false}}
+  if ((0x23 | x) == 0x155){} // expected-warning {{bitwise comparison always evaluates to false}}
+
+  if ((x & 8) == 8) {}
+  if ((x & 8) != 8) {}
+  if ((x | 4) == 4) {}
+  if ((x | 4) != 4) {}
+
+  if ((x & 9) == 8) {}
+  if ((x & 9) != 8) {}
+  if ((x | 4) == 5) {}
+  if ((x | 4) != 5) {}
+
+  if ((x & mydefine) == 8) {}
+  if ((x | mydefine) == 4) {}
+}
diff --git a/test/Sema/warn-documentation-almost-trailing.c b/test/Sema/warn-documentation-almost-trailing.c
index fa17cac..9ff71a3 100644
--- a/test/Sema/warn-documentation-almost-trailing.c
+++ b/test/Sema/warn-documentation-almost-trailing.c
@@ -9,6 +9,5 @@
   int y; /*< comment */ // expected-warning {{not a Doxygen trailing comment}}
 };
 
-// CHECK: fix-it:"{{.*}}":{8:10-8:13}:"///<"
-// CHECK: fix-it:"{{.*}}":{9:10-9:13}:"/**<"
-
+// CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:10-[[@LINE-4]]:13}:"///<"
+// CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:10-[[@LINE-4]]:13}:"/**<"
diff --git a/test/Sema/warn-documentation-fixits.cpp b/test/Sema/warn-documentation-fixits.cpp
index a5a477f..675d86c 100644
--- a/test/Sema/warn-documentation-fixits.cpp
+++ b/test/Sema/warn-documentation-fixits.cpp
@@ -70,6 +70,11 @@
 /// \t bbb IS_DOXYGEN_END
 int Bar();
 
+// expected-warning@+2  {{unknown command tag name 'encode'; did you mean 'endcode'?}}
+// expected-warning@+1  {{'\endcode' command does not terminate a verbatim text block}}
+/// \encode PR18051
+int PR18051();
+
 // CHECK: fix-it:"{{.*}}":{5:12-5:22}:"a"
 // CHECK: fix-it:"{{.*}}":{9:12-9:15}:"aaa"
 // CHECK: fix-it:"{{.*}}":{13:13-13:23}:"T"
@@ -83,3 +88,4 @@
 // CHECK: fix-it:"{{.*}}":{58:30-58:30}:" MY_ATTR_DEPRECATED"
 // CHECK: fix-it:"{{.*}}":{63:6-63:11}:"return"
 // CHECK: fix-it:"{{.*}}":{67:6-67:11}:"foobar"
+// CHECK: fix-it:"{{.*}}":{75:6-75:12}:"endcode"
diff --git a/test/Sema/warn-documentation.cpp b/test/Sema/warn-documentation.cpp
index 7166a49..4375cfc 100644
--- a/test/Sema/warn-documentation.cpp
+++ b/test/Sema/warn-documentation.cpp
@@ -4,35 +4,43 @@
 // RUN: c-index-test -test-load-source all -comments-xml-schema=%S/../../bindings/xml/comment-xml-schema.rng %s | FileCheck %s -check-prefix=WRONG
 // WRONG-NOT: CommentXMLInvalid
 
+// expected-warning@+2 {{HTML tag 'a' requires an end tag}}
 // expected-warning@+1 {{expected quoted string after equals sign}}
 /// <a href=>
 int test_html1(int);
 
+// expected-warning@+2 {{HTML tag 'a' requires an end tag}}
 // expected-warning@+1 {{expected quoted string after equals sign}}
 /// <a href==>
 int test_html2(int);
 
+// expected-warning@+3 {{HTML tag 'a' requires an end tag}}
 // expected-warning@+2 {{expected quoted string after equals sign}}
 // expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}}
 /// <a href= blah
 int test_html3(int);
 
+// expected-warning@+2 {{HTML tag 'a' requires an end tag}}
 // expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}}
 /// <a =>
 int test_html4(int);
 
+// expected-warning@+2 {{HTML tag 'a' requires an end tag}}
 // expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}}
 /// <a "aaa">
 int test_html5(int);
 
+// expected-warning@+2 {{HTML tag 'a' requires an end tag}}
 // expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}}
 /// <a a="b" =>
 int test_html6(int);
 
+// expected-warning@+2 {{HTML tag 'a' requires an end tag}}
 // expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}}
 /// <a a="b" "aaa">
 int test_html7(int);
 
+// expected-warning@+2 {{HTML tag 'a' requires an end tag}}
 // expected-warning@+1 {{HTML start tag prematurely ended, expected attribute name or '>'}}
 /// <a a="b" =
 int test_html8(int);
@@ -67,6 +75,8 @@
 /// Bbb</p>
 int test_html_nesting4(int);
 
+// expected-warning@+3 {{HTML tag 'b' requires an end tag}}
+// expected-warning@+2 {{HTML tag 'i' requires an end tag}}
 // expected-warning@+1 {{HTML end tag does not match any start tag}}
 /// <b><i>Meow</a>
 int test_html_nesting5(int);
@@ -81,6 +91,9 @@
 /// <b><i>Meow</b></i>
 int test_html_nesting7(int);
 
+// expected-warning@+1 {{HTML tag 'b' requires an end tag}}
+/// <b>Meow
+int test_html_nesting8(int);
 
 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
 /// \brief\returns Aaa
@@ -167,7 +180,13 @@
 
 // expected-warning@+1 {{'\param' command used in a comment that is not attached to a function declaration}}
 /// \param a Blah blah.
-int test_param1;
+int test_param1_backslash;
+
+// rdar://13066276
+// Check that the diagnostic uses the same command marker as the comment.
+// expected-warning@+1 {{'@param' command used in a comment that is not attached to a function declaration}}
+/// @param a Blah blah.
+int test_param1_at;
 
 // expected-warning@+1 {{empty paragraph passed to '\param' command}}
 /// \param
@@ -269,41 +288,85 @@
 /// \param x2 Ccc.
 int test_param22(int x1, int x2, int x3);
 
-// expected-warning@+2 {{parameter 'bbb' not found in the function declaration}} expected-note@+2 {{did you mean 'ccc'?}}
-/// \param aaa Meow.
-/// \param bbb Bbb.
-/// \returns aaa.
-typedef int test_param23(int aaa, int ccc);
+//===---
+// Test that we treat typedefs to some non-function types as functions for the
+// purposes of documentation comment parsing.
+//===---
+
+namespace foo {
+  inline namespace bar {
+    template<typename>
+    struct function_wrapper {};
+
+    template<unsigned>
+    struct not_a_function_wrapper {};
+  }
+};
 
 // expected-warning@+2 {{parameter 'bbb' not found in the function declaration}} expected-note@+2 {{did you mean 'ccc'?}}
 /// \param aaa Meow.
 /// \param bbb Bbb.
 /// \returns aaa.
-typedef int (*test_param24)(int aaa, int ccc);
+typedef int test_function_like_typedef1(int aaa, int ccc);
 
 // expected-warning@+2 {{parameter 'bbb' not found in the function declaration}} expected-note@+2 {{did you mean 'ccc'?}}
 /// \param aaa Meow.
 /// \param bbb Bbb.
 /// \returns aaa.
-typedef int (* const test_param25)(int aaa, int ccc);
+typedef int (*test_function_like_typedef2)(int aaa, int ccc);
 
 // expected-warning@+2 {{parameter 'bbb' not found in the function declaration}} expected-note@+2 {{did you mean 'ccc'?}}
 /// \param aaa Meow.
 /// \param bbb Bbb.
 /// \returns aaa.
-typedef int (C::*test_param26)(int aaa, int ccc);
+typedef int (* const test_function_like_typedef3)(int aaa, int ccc);
 
-typedef int (*test_param27)(int aaa);
+// expected-warning@+2 {{parameter 'bbb' not found in the function declaration}} expected-note@+2 {{did you mean 'ccc'?}}
+/// \param aaa Meow.
+/// \param bbb Bbb.
+/// \returns aaa.
+typedef int (C::*test_function_like_typedef4)(int aaa, int ccc);
+
+// expected-warning@+2 {{parameter 'bbb' not found in the function declaration}} expected-note@+2 {{did you mean 'ccc'?}}
+/// \param aaa Meow.
+/// \param bbb Bbb.
+/// \returns aaa.
+typedef foo::function_wrapper<int (int aaa, int ccc)> test_function_like_typedef5;
+
+// expected-warning@+2 {{parameter 'bbb' not found in the function declaration}} expected-note@+2 {{did you mean 'ccc'?}}
+/// \param aaa Meow.
+/// \param bbb Bbb.
+/// \returns aaa.
+typedef foo::function_wrapper<int (int aaa, int ccc)> *test_function_like_typedef6;
+
+// expected-warning@+2 {{parameter 'bbb' not found in the function declaration}} expected-note@+2 {{did you mean 'ccc'?}}
+/// \param aaa Meow.
+/// \param bbb Bbb.
+/// \returns aaa.
+typedef foo::function_wrapper<int (int aaa, int ccc)> &test_function_like_typedef7;
+
+// expected-warning@+2 {{parameter 'bbb' not found in the function declaration}} expected-note@+2 {{did you mean 'ccc'?}}
+/// \param aaa Meow.
+/// \param bbb Bbb.
+/// \returns aaa.
+typedef foo::function_wrapper<int (int aaa, int ccc)> &&test_function_like_typedef8;
+
+
+typedef int (*test_not_function_like_typedef1)(int aaa);
 
 // expected-warning@+1 {{'\param' command used in a comment that is not attached to a function declaration}}
 /// \param aaa Meow.
-typedef test_param27 test_param28;
+typedef test_not_function_like_typedef1 test_not_function_like_typedef2;
 
 // rdar://13066276
+// Check that the diagnostic uses the same command marker as the comment.
 // expected-warning@+1 {{'@param' command used in a comment that is not attached to a function declaration}}
 /// @param aaa Meow.
-typedef unsigned int test_param29;
+typedef unsigned int test_not_function_like_typedef3;
 
+// expected-warning@+1 {{'\param' command used in a comment that is not attached to a function declaration}}
+/// \param aaa Meow.
+typedef foo::not_a_function_wrapper<1> test_not_function_like_typedef4;
 
 /// \param aaa Aaa
 /// \param ... Vararg
@@ -321,6 +384,26 @@
 int test_vararg_param4();
 
 
+/// \param aaa Aaa
+/// \param ... Vararg
+template<typename T>
+int test_template_vararg_param1(int aaa, ...);
+
+/// \param ... Vararg
+template<typename T>
+int test_template_vararg_param2(...);
+
+// expected-warning@+1 {{parameter '...' not found in the function declaration}} expected-note@+1 {{did you mean 'aaa'?}}
+/// \param ... Vararg
+template<typename T>
+int test_template_vararg_param3(int aaa);
+
+// expected-warning@+1 {{parameter '...' not found in the function declaration}}
+/// \param ... Vararg
+template<typename T>
+int test_template_vararg_param4();
+
+
 // expected-warning@+1 {{'\tparam' command used in a comment that is not attached to a template declaration}}
 /// \tparam T Aaa
 int test_tparam1;
@@ -503,7 +586,13 @@
 
 // expected-warning@+1 {{'\returns' command used in a comment that is not attached to a function or method declaration}}
 /// \returns Aaa
-int test_returns_wrong_decl_1;
+int test_returns_wrong_decl_1_backslash;
+
+// rdar://13066276
+// Check that the diagnostic uses the same command marker as the comment.
+// expected-warning@+1 {{'@returns' command used in a comment that is not attached to a function or method declaration}}
+/// @returns Aaa
+int test_returns_wrong_decl_1_at;
 
 // expected-warning@+1 {{'\return' command used in a comment that is not attached to a function or method declaration}}
 /// \return Aaa
@@ -555,11 +644,6 @@
 /// \returns Aaa
 namespace test_returns_wrong_decl_10 { };
 
-// rdar://13066276
-// expected-warning@+1 {{'@returns' command used in a comment that is not attached to a function or method declaration}}
-/// @returns Aaa
-typedef unsigned int test_returns_wrong_decl_11;
-
 // rdar://13094352
 // expected-warning@+1 {{'@function' command should be used in a comment attached to a function declaration}}
 /*!	@function test_function
diff --git a/test/Sema/warn-main-return-type.c b/test/Sema/warn-main-return-type.c
index c6f3a0c..f8bcbc5 100644
--- a/test/Sema/warn-main-return-type.c
+++ b/test/Sema/warn-main-return-type.c
@@ -22,8 +22,8 @@
   return 0.0;
 }
 
-// Currently we suggest to replace only 'float' here because we don't store
-// enough source locations.
+// TODO: Store qualifier source locations for return types so
+// we can replace the full type with this fix-it.
 //
 // expected-error@+3 {{conflicting types for 'main}}
 // expected-warning@+2 {{return type of 'main' is not 'int'}}
@@ -35,9 +35,11 @@
 
 typedef void *(*fptr)(int a);
 
-// expected-error@+2 {{conflicting types for 'main}}
-// expected-warning@+1 {{return type of 'main' is not 'int'}}
+// expected-error@+3 {{conflicting types for 'main}}
+// expected-warning@+2 {{return type of 'main' is not 'int'}}
+// expected-note@+1 {{change return type to 'int'}}
 fptr main() {
+// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:1-[[@LINE-1]]:5}:"int"
   return (fptr) 0;
 }
 
diff --git a/test/Sema/warn-missing-variable-declarations.c b/test/Sema/warn-missing-variable-declarations.c
index 631d3d2..e5ce97d 100644
--- a/test/Sema/warn-missing-variable-declarations.c
+++ b/test/Sema/warn-missing-variable-declarations.c
@@ -1,4 +1,4 @@
-// RUN: %clang -Wmissing-variable-declarations -fsyntax-only -Xclang -verify %s
+// RUN: %clang_cc1 -Wmissing-variable-declarations -fsyntax-only -verify %s
 
 int vbad1; // expected-warning{{no previous extern declaration for non-static variable 'vbad1'}}
 
diff --git a/test/Sema/warn-null.c b/test/Sema/warn-null.c
index 8ac8c5c..3bf2aed 100644
--- a/test/Sema/warn-null.c
+++ b/test/Sema/warn-null.c
@@ -1,6 +1,14 @@
-// RUN: %clang_cc1 %s -verify -fsyntax-only
+// RUN: %clang_cc1 %s -verify
 
-// PR10837: warn if a non-pointer-typed expression is folded to a null pointer
+#define SOME_ADDR (unsigned long long)0
+
+// PR10837: Warn if a non-pointer-typed expression is folded to a null pointer
 int *p = 0;
-int *q = '\0';  // expected-warning{{expression which evaluates to zero treated as a null pointer constant}}
-int *r = (1 - 1);  // expected-warning{{expression which evaluates to zero treated as a null pointer constant}}
+int *q = '\0'; // expected-warning{{expression which evaluates to zero treated as a null pointer constant}}
+int *r = (1 - 1); // expected-warning{{expression which evaluates to zero treated as a null pointer constant}}
+void f() {
+  p = 0;
+  q = '\0'; // expected-warning{{expression which evaluates to zero treated as a null pointer constant}}
+  r = 1 - 1; // expected-warning{{expression which evaluates to zero treated as a null pointer constant}}
+  p = SOME_ADDR; // expected-warning{{expression which evaluates to zero treated as a null pointer constant}}
+}
diff --git a/test/Sema/warn-outof-range-assign-enum.c b/test/Sema/warn-outof-range-assign-enum.c
index 43eea0c..edd4e37 100644
--- a/test/Sema/warn-outof-range-assign-enum.c
+++ b/test/Sema/warn-outof-range-assign-enum.c
@@ -11,6 +11,24 @@
 CCTestEnum test = 50; // expected-warning {{integer constant not in range of enumerated type 'CCTestEnum'}}
 CCTestEnum test1 = -50; // expected-warning {{integer constant not in range of enumerated type 'CCTestEnum'}}
 
+// Explicit cast should silence the warning.
+static const CCTestEnum SilenceWithCast1 = 51; // expected-warning {{integer constant not in range of enumerated type 'CCTestEnum'}}
+static const CCTestEnum SilenceWithCast2 = (CCTestEnum) 51; // no-warning
+static const CCTestEnum SilenceWithCast3 = (const CCTestEnum) 51; // no-warning
+static const CCTestEnum SilenceWithCast4 = (const volatile CCTestEnum) 51; // no-warning
+
+void SilenceWithCastLocalVar() {
+  CCTestEnum SilenceWithCast1 = 51; // expected-warning {{integer constant not in range of enumerated type 'CCTestEnum'}}
+  CCTestEnum SilenceWithCast2 = (CCTestEnum) 51; // no-warning
+  CCTestEnum SilenceWithCast3 = (const CCTestEnum) 51; // no-warning
+  CCTestEnum SilenceWithCast4 = (const volatile CCTestEnum) 51; // no-warning
+
+  const CCTestEnum SilenceWithCast1c = 51; // expected-warning {{integer constant not in range of enumerated type 'CCTestEnum'}}
+  const CCTestEnum SilenceWithCast2c = (CCTestEnum) 51; // no-warning
+  const CCTestEnum SilenceWithCast3c = (const CCTestEnum) 51; // no-warning
+  const CCTestEnum SilenceWithCast4c = (const volatile CCTestEnum) 51; // no-warning
+}
+
 CCTestEnum foo(CCTestEnum r) {
   return 20; // expected-warning {{integer constant not in range of enumerated type 'CCTestEnum'}}
 }
diff --git a/test/Sema/warn-overlap.c b/test/Sema/warn-overlap.c
new file mode 100644
index 0000000..44d6ad5
--- /dev/null
+++ b/test/Sema/warn-overlap.c
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wtautological-overlap-compare %s
+
+#define mydefine 2
+
+void f(int x) {
+  int y = 0;
+
+  // > || <
+  if (x > 2 || x < 1) { }
+  if (x > 2 || x < 2) { }
+  if (x != 2 || x != 3) { } // expected-warning {{overlapping comparisons always evaluate to true}}
+  if (x > 2 || x < 3) { } // expected-warning {{overlapping comparisons always evaluate to true}}
+  if (x > 0 || x < 0) { }
+
+  if (x > 2 || x <= 1) { }
+  if (x > 2 || x <= 2) { } // expected-warning {{overlapping comparisons always evaluate to true}}
+  if (x > 2 || x <= 3) { } // expected-warning {{overlapping comparisons always evaluate to true}}
+
+  if (x >= 2 || x < 1) { }
+  if (x >= 2 || x < 2) { } // expected-warning {{overlapping comparisons always evaluate to true}}
+  if (x >= 2 || x < 3) { } // expected-warning {{overlapping comparisons always evaluate to true}}
+
+  if (x >= 2 || x <= 1) { } // expected-warning {{overlapping comparisons always evaluate to true}}
+  if (x >= 2 || x <= 2) { } // expected-warning {{overlapping comparisons always evaluate to true}}
+  if (x >= 2 || x <= 3) { } // expected-warning {{overlapping comparisons always evaluate to true}}
+  if (x >= 0 || x <= 0) { } // expected-warning {{overlapping comparisons always evaluate to true}}
+
+  // > && <
+  if (x > 2 && x < 1) { }  // expected-warning {{overlapping comparisons always evaluate to false}}
+  if (x > 2 && x < 2) { }  // expected-warning {{overlapping comparisons always evaluate to false}}
+  if (x > 2 && x < 3) { }  // expected-warning {{overlapping comparisons always evaluate to false}}
+  if (x > 0 && x < 1) { }  // expected-warning {{overlapping comparisons always evaluate to false}}
+
+  if (x > 2 && x <= 1) { }  // expected-warning {{overlapping comparisons always evaluate to false}}
+  if (x > 2 && x <= 2) { }  // expected-warning {{overlapping comparisons always evaluate to false}}
+  if (x > 2 && x <= 3) { }
+
+  if (x >= 2 && x < 1) { }  // expected-warning {{overlapping comparisons always evaluate to false}}
+  if (x >= 2 && x < 2) { }  // expected-warning {{overlapping comparisons always evaluate to false}}
+  if (x >= 2 && x < 3) { }
+  if (x >= 0 && x < 0) { }  // expected-warning {{overlapping comparisons always evaluate to false}}
+
+  if (x >= 2 && x <= 1) { }  // expected-warning {{overlapping comparisons always evaluate to false}}
+  if (x >= 2 && x <= 2) { }
+  if (x >= 2 && x <= 3) { }
+
+  // !=, ==, ..
+  if (x != 2 || x != 3) { }  // expected-warning {{overlapping comparisons always evaluate to true}}
+  if (x != 2 || x < 3) { }   // expected-warning {{overlapping comparisons always evaluate to true}}
+  if (x == 2 && x == 3) { }  // expected-warning {{overlapping comparisons always evaluate to false}}
+  if (x == 2 && x > 3) { }   // expected-warning {{overlapping comparisons always evaluate to false}}
+  if (x == 3 && x < 0) { }  // expected-warning {{overlapping comparisons always evaluate to false}}
+  if (3 == x && x < 0) { }  // expected-warning {{overlapping comparisons always evaluate to false}}
+
+  if (x == mydefine && x > 3) { }
+  if (x == (mydefine + 1) && x > 3) { }
+}
+
+// Don't generate a warning here.
+void array_out_of_bounds() {
+  int x;
+  int buffer[4];
+  x = (-7 > 0) ? (buffer[-7]) : 0;
+}
diff --git a/test/Sema/warn-thread-safety-analysis.c b/test/Sema/warn-thread-safety-analysis.c
index 1918ace..6d41e40 100644
--- a/test/Sema/warn-thread-safety-analysis.c
+++ b/test/Sema/warn-thread-safety-analysis.c
@@ -1,4 +1,4 @@
-// RUN: %clang -fsyntax-only -verify -Wthread-safety -Wthread-safety-beta -fcxx-exceptions %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety -Wthread-safety-beta %s
 
 #define LOCKABLE            __attribute__ ((lockable))
 #define SCOPED_LOCKABLE     __attribute__ ((scoped_lockable))
@@ -31,15 +31,12 @@
   struct Mutex *mu_;
 };
 
-// Define mutex lock/unlock functions.
-void mutex_exclusive_lock(struct Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu) {
-}
-
-void mutex_shared_lock(struct Mutex *mu) SHARED_LOCK_FUNCTION(mu) {
-}
-
-void mutex_unlock(struct Mutex *mu) UNLOCK_FUNCTION(mu) {
-}
+// Declare mutex lock/unlock functions.
+void mutex_exclusive_lock(struct Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu);
+void mutex_shared_lock(struct Mutex *mu) SHARED_LOCK_FUNCTION(mu);
+void mutex_unlock(struct Mutex *mu) UNLOCK_FUNCTION(mu);
+void mutex_shared_unlock(struct Mutex *mu) __attribute__((release_shared_capability(mu)));
+void mutex_exclusive_unlock(struct Mutex *mu) __attribute__((release_capability(mu)));
 
 // Define global variables.
 struct Mutex mu1;
@@ -77,14 +74,14 @@
 
 int main() {
 
-  Foo_fun1(1); // expected-warning{{calling function 'Foo_fun1' requires shared lock on 'mu2'}} \
-                  expected-warning{{calling function 'Foo_fun1' requires exclusive lock on 'mu1'}}
+  Foo_fun1(1); // expected-warning{{calling function 'Foo_fun1' requires holding mutex 'mu2'}} \
+                  expected-warning{{calling function 'Foo_fun1' requires holding mutex 'mu1' exclusively}}
 
   mutex_exclusive_lock(&mu1);
   mutex_shared_lock(&mu2);
   Foo_fun1(1);
 
-  mutex_shared_lock(&mu1); // expected-warning{{locking 'mu1' that is already locked}}
+  mutex_shared_lock(&mu1); // expected-warning{{acquiring mutex 'mu1' that is already held}}
   mutex_unlock(&mu1);
   mutex_unlock(&mu2);
   mutex_shared_lock(&mu1);
@@ -98,13 +95,13 @@
   mutex_unlock(&mu1);
 
   mutex_exclusive_lock(&mu1);
-  Foo_func3(4);  // expected-warning{{cannot call function 'Foo_func3' while mutex 'mu1' is locked}}
+  Foo_func3(4);  // expected-warning{{cannot call function 'Foo_func3' while mutex 'mu1' is held}}
   mutex_unlock(&mu1);
 
   Foo_func3(5);
 
-  set_value(&a_, 0); // expected-warning{{calling function 'setA' requires exclusive lock on 'foo_.mu_'}}
-  get_value(b_); // expected-warning{{calling function 'getB' requires shared lock on 'foo_.mu_'}}
+  set_value(&a_, 0); // expected-warning{{calling function 'set_value' requires holding mutex 'foo_.mu_' exclusively}}
+  get_value(b_); // expected-warning{{calling function 'get_value' requires holding mutex 'foo_.mu_'}}
   mutex_exclusive_lock(foo_.mu_);
   set_value(&a_, 1);
   mutex_unlock(foo_.mu_);
@@ -112,12 +109,20 @@
   (void)(get_value(b_) == 1);
   mutex_unlock(foo_.mu_);
 
-  c_ = 0; // expected-warning{{writing variable 'c_' requires locking any mutex exclusively}}
-  (void)(*d_ == 0); // expected-warning{{reading the value pointed to by 'd_' requires locking any mutex}}
+  c_ = 0; // expected-warning{{writing variable 'c_' requires holding any mutex exclusively}}
+  (void)(*d_ == 0); // expected-warning{{reading the value pointed to by 'd_' requires holding any mutex}}
   mutex_exclusive_lock(foo_.mu_);
   c_ = 1;
   (void)(*d_ == 1);
   mutex_unlock(foo_.mu_);
 
+  mutex_exclusive_lock(&mu1);
+  mutex_shared_unlock(&mu1); // expected-warning {{releasing mutex 'mu1' using shared access, expected exclusive access}}
+  mutex_exclusive_unlock(&mu1);
+
+  mutex_shared_lock(&mu1);
+  mutex_exclusive_unlock(&mu1); // expected-warning {{releasing mutex 'mu1' using exclusive access, expected shared access}}
+  mutex_shared_unlock(&mu1);
+
   return 0;
 }
diff --git a/test/Sema/warn-type-safety.c b/test/Sema/warn-type-safety.c
index dfab8f8..0431386 100644
--- a/test/Sema/warn-type-safety.c
+++ b/test/Sema/warn-type-safety.c
@@ -57,6 +57,8 @@
     __attribute__(( type_tag_for_datatype(mpi,int,layout_compatible,not_a_flag) )); // expected-error {{invalid comparison flag 'not_a_flag'}}
 
 
+void datatype_wrong7(void) __attribute__((type_tag_for_datatype(datatype_wrong7, int))); // expected-error {{'type_tag_for_datatype' attribute only applies to variables}}
+
 // Using a tag with kind A in a place where the function requires kind B should
 // warn.
 
@@ -156,5 +158,3 @@
   F_func(float_ptr, 0xFFFFFFFFFFFFFFFFULL); // expected-warning {{argument type 'float *' doesn't match specified 'f' type tag that requires 'int *'}}
   F_func(float_ptr, 0xFFFFFFFFULL);
 }
-
-
diff --git a/test/Sema/warn-unreachable.c b/test/Sema/warn-unreachable.c
index fd74b5c..31beff9 100644
--- a/test/Sema/warn-unreachable.c
+++ b/test/Sema/warn-unreachable.c
@@ -1,4 +1,6 @@
-// RUN: %clang %s -fsyntax-only -Xclang -verify -fblocks -Wunreachable-code -Wno-unused-value -Wno-covered-switch-default
+// RUN: %clang_cc1 %s -fsyntax-only -verify -fblocks -Wunreachable-code-aggressive -Wno-unused-value -Wno-covered-switch-default -I %S/Inputs
+
+#include "warn-unreachable.h"
 
 int halt() __attribute__((noreturn));
 int live();
@@ -107,7 +109,7 @@
     case C3:
       return 1;
     default: {
-      int i = 0; // expected-warning{{will never be executed}}
+      int i = 0; // no-warning
       ++i;
       return i;
     }
@@ -134,10 +136,263 @@
 
 // Test case for <rdar://problem/11005770>.  We should treat code guarded
 // by 'x & 0' and 'x * 0' as unreachable.
-void calledFun();
+int calledFun();
 void test_mul_and_zero(int x) {
   if (x & 0) calledFun(); // expected-warning {{will never be executed}}
   if (0 & x) calledFun(); // expected-warning {{will never be executed}}
   if (x * 0) calledFun(); // expected-warning {{will never be executed}}
   if (0 * x) calledFun(); // expected-warning {{will never be executed}}
 }
+
+void raze() __attribute__((noreturn));
+void warn_here();
+
+int test_break_preceded_by_noreturn(int i) {
+  switch (i) {
+    case 1:
+      raze();
+      break; // expected-warning {{'break' will never be executed}}
+    case 2:
+      raze();
+      break; // expected-warning {{'break' will never be executed}}
+      warn_here(); // expected-warning {{will never be executed}}
+    case 3:
+      return 1;
+      break; // expected-warning {{will never be executed}}
+    default:
+      break;
+      break; // expected-warning {{will never be executed}}
+  }
+  return i;
+}
+
+// Don't warn about unreachable 'default' cases, as that is covered
+// by -Wcovered-switch-default.
+typedef enum { Value1 = 1 } MyEnum;
+void unreachable_default(MyEnum e) {
+  switch (e) {
+  case Value1:
+    calledFun();
+    break;
+  case 2: // expected-warning {{case value not in enumerated type 'MyEnum'}}
+    calledFun();
+    break;
+  default:
+    calledFun(); // no-warning
+    break;
+  }
+}
+void unreachable_in_default(MyEnum e) {
+  switch (e) {
+  default:
+    raze();
+    calledFun(); // expected-warning {{will never be executed}}
+    break;
+  }
+}
+
+// Don't warn about trivial dead returns.
+int trivial_dead_return() {
+  raze();
+  return ((0)); // expected-warning {{'return' will never be executed}}
+}
+
+void trivial_dead_return_void() {
+  raze();
+  return; // expected-warning {{'return' will never be executed}}
+}
+
+MyEnum trivial_dead_return_enum() {
+  raze();
+  return Value1; // expected-warning {{'return' will never be executed}}
+}
+
+MyEnum trivial_dead_return_enum_2(int x) {
+  switch (x) {
+    case 1: return 1;
+    case 2: return 2;
+    case 3: return 3;
+    default: return 4;
+  }
+
+  return 2; // expected-warning {{will never be executed}}
+}
+
+const char *trivial_dead_return_cstr() {
+  raze();
+  return ""; // expected-warning {{return' will never be executed}}
+}
+
+char trivial_dead_return_char() {
+  raze();
+  return ' '; // expected-warning {{return' will never be executed}}
+}
+
+MyEnum nontrivial_dead_return_enum_2(int x) {
+  switch (x) {
+    case 1: return 1;
+    case 2: return 2;
+    case 3: return 3;
+    default: return 4;
+  }
+
+  return calledFun(); // expected-warning {{will never be executed}}
+}
+
+enum X { A, B, C };
+
+int covered_switch(enum X x) {
+  switch (x) {
+  case A: return 1;
+  case B: return 2;
+  case C: return 3;
+  }
+  return 4; // no-warning
+}
+
+// Test unreachable code depending on configuration values
+#define CONFIG_CONSTANT 1
+int test_config_constant(int x) {
+  if (!CONFIG_CONSTANT) {
+    calledFun(); // no-warning
+    return 1;
+  }
+  if (!1) { // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
+    calledFun(); // expected-warning {{will never be executed}}
+    return 1;
+  }
+  if (sizeof(int) > sizeof(char)) {
+    calledFun(); // no-warning
+    return 1;
+  }
+  if (x > 10)
+    return CONFIG_CONSTANT ? calledFun() : calledFun(); // no-warning
+  else
+    return 1 ? // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
+      calledFun() :
+      calledFun(); // expected-warning {{will never be executed}}
+}
+
+int sizeof_int(int x, int y) {
+  if (sizeof(long) == sizeof(int))
+    return 1; // no-warning
+  if (sizeof(long) != sizeof(int))
+    return 0; // no-warning
+  if (x && y && sizeof(long) < sizeof(char))
+    return 0; // no-warning
+  return 2; // no-warning
+}
+
+enum MyEnum2 {
+  ME_A = CONFIG_CONSTANT,
+  ME_B = 1
+};
+
+int test_MyEnum() {
+  if (!ME_A)
+    return 1; // no-warning
+  if (ME_A)
+    return 2; // no-warning
+  if (ME_B)
+    return 3;
+  if (!ME_B) // expected-warning {{will never be executed}}
+    return 4; // expected-warning {{will never be executed}}
+  return 5;
+}
+
+// Test for idiomatic do..while.
+int test_do_while(int x) {
+  do {
+    if (x == calledFun())
+      break;
+    ++x;
+    break;
+  }
+  while (0); // no-warning
+  return x;
+}
+
+int test_do_while_nontrivial_cond(int x) {
+  do {
+    if (x == calledFun())
+      break;
+    ++x;
+    break;
+  }
+  while (calledFun()); // expected-warning {{will never be executed}}
+  return x;
+}
+
+// Diagnostic control: -Wunreachable-code-return.
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunreachable-code-return"
+
+void trivial_dead_return_void_SUPPRESSED() {
+  raze();
+  return; // no-warning
+}
+
+MyEnum trivial_dead_return_enum_SUPPRESSED() {
+  raze();
+  return Value1; // no-warning
+}
+
+#pragma clang diagnostic pop
+
+// Diagnostic control: -Wunreachable-code-break.
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunreachable-code-break"
+
+int test_break_preceded_by_noreturn_SUPPRESSED(int i) {
+  switch (i) {
+    case 1:
+      raze();
+      break; // no-warning
+    case 2:
+      raze();
+      break; // no-warning
+      warn_here(); // expected-warning {{will never be executed}}
+    case 3:
+      return 1;
+      break; // no-warning
+    default:
+      break;
+      break; // no-warning
+  }
+  return i;
+}
+
+#pragma clang diagnostic pop
+
+// Test "silencing" with parentheses.
+void test_with_paren_silencing(int x) {
+  if (0) calledFun(); // expected-warning {{will never be executed}} expected-note {{silence by adding parentheses to mark code as explicitly dead}}
+  if ((0)) calledFun(); // no-warning
+
+  if (1) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
+    calledFun();
+  else
+    calledFun(); // expected-warning {{will never be executed}}
+
+  if ((1))
+    calledFun();
+  else
+    calledFun(); // no-warning
+  
+  if (!1) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
+    calledFun(); // expected-warning {{code will never be executed}}
+  else
+    calledFun();
+  
+  if ((!1))
+    calledFun(); // no-warning
+  else
+    calledFun();
+  
+  if (!(1))
+    calledFun(); // no-warning
+  else
+    calledFun();
+}
diff --git a/test/Sema/wchar.c b/test/Sema/wchar.c
index 13c2f58..74e482a 100644
--- a/test/Sema/wchar.c
+++ b/test/Sema/wchar.c
@@ -1,5 +1,5 @@
-// RUN: %clang %s -fsyntax-only -Xclang -verify
-// RUN: %clang %s -fsyntax-only -fshort-wchar -Xclang -verify -DSHORT_WCHAR
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+// RUN: %clang_cc1 %s -fsyntax-only -fshort-wchar -verify -DSHORT_WCHAR
 
 typedef __WCHAR_TYPE__ wchar_t;
 
diff --git a/test/SemaCUDA/Inputs/cuda.h b/test/SemaCUDA/Inputs/cuda.h
new file mode 100644
index 0000000..a9a4595
--- /dev/null
+++ b/test/SemaCUDA/Inputs/cuda.h
@@ -0,0 +1,20 @@
+/* Minimal declarations for CUDA support.  Testing purposes only. */
+
+#include <stddef.h>
+
+#define __constant__ __attribute__((constant))
+#define __device__ __attribute__((device))
+#define __global__ __attribute__((global))
+#define __host__ __attribute__((host))
+#define __shared__ __attribute__((shared))
+#define __launch_bounds__(...) __attribute__((launch_bounds(__VA_ARGS__)))
+
+struct dim3 {
+  unsigned x, y, z;
+  __host__ __device__ dim3(unsigned x, unsigned y = 1, unsigned z = 1) : x(x), y(y), z(z) {}
+};
+
+typedef struct cudaStream *cudaStream_t;
+
+int cudaConfigureCall(dim3 gridSize, dim3 blockSize, size_t sharedSize = 0,
+                      cudaStream_t stream = 0);
diff --git a/test/SemaCUDA/cuda.h b/test/SemaCUDA/cuda.h
deleted file mode 100644
index 26a8df0..0000000
--- a/test/SemaCUDA/cuda.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Minimal declarations for CUDA support.  Testing purposes only. */
-
-#include <stddef.h>
-
-#define __constant__ __attribute__((constant))
-#define __device__ __attribute__((device))
-#define __global__ __attribute__((global))
-#define __host__ __attribute__((host))
-#define __shared__ __attribute__((shared))
-
-struct dim3 {
-  unsigned x, y, z;
-  __host__ __device__ dim3(unsigned x, unsigned y = 1, unsigned z = 1) : x(x), y(y), z(z) {}
-};
-
-typedef struct cudaStream *cudaStream_t;
-
-int cudaConfigureCall(dim3 gridSize, dim3 blockSize, size_t sharedSize = 0,
-                      cudaStream_t stream = 0);
diff --git a/test/SemaCUDA/function-target.cu b/test/SemaCUDA/function-target.cu
index c7a55e2..51bc8c9 100644
--- a/test/SemaCUDA/function-target.cu
+++ b/test/SemaCUDA/function-target.cu
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 
-#include "cuda.h"
+#include "Inputs/cuda.h"
 
 __host__ void h1h(void);
 __device__ void h1d(void); // expected-note {{candidate function not viable: call to __device__ function from __host__ function}}
diff --git a/test/SemaCUDA/kernel-call.cu b/test/SemaCUDA/kernel-call.cu
index 91b1d49..9a3d86c 100644
--- a/test/SemaCUDA/kernel-call.cu
+++ b/test/SemaCUDA/kernel-call.cu
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 
-#include "cuda.h"
+#include "Inputs/cuda.h"
 
 __global__ void g1(int x) {}
 
diff --git a/test/SemaCUDA/launch_bounds.cu b/test/SemaCUDA/launch_bounds.cu
new file mode 100644
index 0000000..bed7658
--- /dev/null
+++ b/test/SemaCUDA/launch_bounds.cu
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+#include "Inputs/cuda.h"
+
+__launch_bounds__(128, 7) void Test1(void);
+__launch_bounds__(128) void Test2(void);
+
+__launch_bounds__(1, 2, 3) void Test3(void); // expected-error {{'launch_bounds' attribute takes no more than 2 arguments}}
+
+// FIXME: the error should read that the attribute takes exactly one or two arguments, but there
+// is no support for such a diagnostic currently.
+__launch_bounds__() void Test4(void); // expected-error {{'launch_bounds' attribute takes no more than 2 arguments}}
+
+int Test5 __launch_bounds__(128, 7); // expected-warning {{'launch_bounds' attribute only applies to functions and methods}}
diff --git a/test/SemaCUDA/lit.local.cfg b/test/SemaCUDA/lit.local.cfg
new file mode 100644
index 0000000..f4ef5d2
--- /dev/null
+++ b/test/SemaCUDA/lit.local.cfg
@@ -0,0 +1,4 @@
+config.substitutions = list(config.substitutions)
+config.substitutions.insert(0,
+    (r'%clang\b',
+     """*** Do not use the driver in Sema tests. ***""") )
diff --git a/test/SemaCUDA/qualifiers.cu b/test/SemaCUDA/qualifiers.cu
index 1346d65..42a80b8 100644
--- a/test/SemaCUDA/qualifiers.cu
+++ b/test/SemaCUDA/qualifiers.cu
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 
-#include "cuda.h"
+#include "Inputs/cuda.h"
 
 __global__ void g1(int x) {}
 __global__ int g2(int x) { // expected-error {{must have void return type}}
diff --git a/test/SemaCXX/MicrosoftCompatibility.cpp b/test/SemaCXX/MicrosoftCompatibility.cpp
index 05037ac..fb7d975 100644
--- a/test/SemaCXX/MicrosoftCompatibility.cpp
+++ b/test/SemaCXX/MicrosoftCompatibility.cpp
@@ -3,6 +3,7 @@
 
 typedef unsigned short char16_t;
 typedef unsigned int char32_t;
+struct _Atomic {};
 
 typename decltype(3) a; // expected-warning {{expected a qualified name after 'typename'}}
 
@@ -21,6 +22,12 @@
 }
 
 
+namespace ms_predefined_types {
+  // ::type_info is a built-in forward class declaration.
+  void f(const type_info &a);
+  void f(size_t);
+}
+
 
 namespace ms_protected_scope {
   struct C { C(); };
@@ -105,6 +112,9 @@
 class B : public A {
 private:   
   using A::f;
+  void g() {
+    f(); // no diagnostic
+  }
 };
 
 class C : public B { 
@@ -114,6 +124,27 @@
 
 }
 
+namespace using_tag_redeclaration
+{
+  struct S;
+  namespace N {
+    using ::using_tag_redeclaration::S;
+    struct S {}; // expected-note {{previous definition is here}}
+  }
+  void f() {
+    N::S s1;
+    S s2;
+  }
+  void g() {
+    struct S; // expected-note {{forward declaration of 'S'}}
+    S s3; // expected-error {{variable has incomplete type 'S'}}
+  }
+  void h() {
+    using ::using_tag_redeclaration::S;
+    struct S {}; // expected-error {{redefinition of 'S'}}
+  }
+}
+
 
 namespace MissingTypename {
 
diff --git a/test/SemaCXX/MicrosoftExtensions.cpp b/test/SemaCXX/MicrosoftExtensions.cpp
index c5b45a2..6d221a4 100644
--- a/test/SemaCXX/MicrosoftExtensions.cpp
+++ b/test/SemaCXX/MicrosoftExtensions.cpp
@@ -1,10 +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
 
 
-// ::type_info is predeclared with forward class declartion
-void f(const type_info &a);
-
-
 // Microsoft doesn't validate exception specification.
 namespace microsoft_exception_spec {
 
@@ -37,11 +33,11 @@
 // MSVC allows type definition in anonymous union and struct
 struct A
 {
-  union 
+  union
   {
     int a;
     struct B  // expected-warning {{types declared in an anonymous union are a Microsoft extension}}
-    { 
+    {
       int c;
     } d;
 
@@ -63,7 +59,7 @@
     {
       int c2;
     } d2;
-    
+
 	union C2  // expected-warning {{types declared in an anonymous struct are a Microsoft extension}}
     {
       int e2;
@@ -78,7 +74,7 @@
 // __stdcall handling
 struct M {
     int __stdcall addP();
-    float __stdcall subtractP(); 
+    float __stdcall subtractP();
 };
 
 // __unaligned handling
@@ -90,7 +86,7 @@
 void m1() {
   h1<int>(&M::addP);
   h1(&M::subtractP);
-} 
+}
 
 
 
@@ -98,7 +94,7 @@
 
 void f(long long);
 void f(int);
- 
+
 int main()
 {
   // This is an ambiguous call in standard C++.
@@ -123,10 +119,11 @@
 
 class AAA {
 __declspec(dllimport) void f(void) { }
-void f2(void);
+void f2(void); // expected-note{{previous declaration is here}}
 };
 
-__declspec(dllimport) void AAA::f2(void) { // expected-error {{dllimport attribute can be applied only to symbol}}
+__declspec(dllimport) void AAA::f2(void) { // expected-error{{dllimport cannot be applied to non-inline function definition}}
+                                           // expected-error@-1{{redeclaration of 'AAA::f2' cannot add 'dllimport' attribute}}
 
 }
 
@@ -147,11 +144,14 @@
 void static_func(); // expected-note {{previous declaration is here}}
 
 
-static void static_func() // expected-warning {{static declaration of 'static_func' follows non-static declaration}}
+static void static_func() // expected-warning {{redeclaring non-static 'static_func' as static is a Microsoft extension}}
 {
 
 }
 
+extern const int static_var; // expected-note {{previous declaration is here}}
+static const int static_var = 3; // expected-warning {{redeclaring non-static 'static_var' as static is a Microsoft extension}}
+
 long function_prototype(int a);
 long (*function_ptr)(int a);
 
@@ -176,29 +176,6 @@
    b = reinterpret_cast<bool>(ptr); // expected-error {{cast from pointer to smaller type 'bool' loses information}}
 }
 
-namespace friend_as_a_forward_decl {
-
-class A {
-  class Nested {
-    friend class B;
-    B* b;
-  };
-  B* b;
-};
-B* global_b;
-
-
-void f()
-{
-  class Local {
-    friend class Z;
-    Z* b;
-  };
-  Z* b;
-}
-
-}
-
 struct PR11150 {
   class X {
     virtual void f() = 0;
@@ -307,7 +284,7 @@
   __declspec(property(get=GetV, put=SetV)) T V;
   T GetV() { return 0; }
   void SetV(T v) {}
-  void f() { V = this->V; V < this->V; }
+  bool f() { V = this->V; return V < this->V; }
   void g() { V++; }
   void h() { V*=2; }
 };
@@ -368,18 +345,18 @@
 
 namespace rdar14250378 {
   class Bar {};
-  
+
   namespace NyNamespace {
     class Foo {
     public:
       Bar* EnsureBar();
     };
-    
+
     class Baz : public Foo {
     public:
       friend class Bar;
     };
-    
+
     Bar* Foo::EnsureBar() {
       return 0;
     }
@@ -410,3 +387,14 @@
 
 // expected-error@+1 {{base 'SealedType' is marked 'sealed'}}
 struct InheritFromSealed : SealedType {};
+
+void AfterClassBody() {
+  // expected-warning@+1 {{attribute 'deprecated' is ignored, place it after "struct" to apply attribute to type declaration}}
+  struct D {} __declspec(deprecated);
+
+  struct __declspec(align(4)) S {} __declspec(align(8)) s1;
+  S s2;
+  _Static_assert(__alignof(S) == 4, "");
+  _Static_assert(__alignof(s1) == 8, "");
+  _Static_assert(__alignof(s2) == 4, "");
+}
diff --git a/test/SemaCXX/PR19955.cpp b/test/SemaCXX/PR19955.cpp
new file mode 100644
index 0000000..cbbe2fe
--- /dev/null
+++ b/test/SemaCXX/PR19955.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple i686-win32 -verify -std=c++11 %s
+// RUN: %clang_cc1 -triple i686-mingw32 -verify -std=c++11 %s
+
+extern int __attribute__((dllimport)) var;
+constexpr int *varp = &var; // expected-error {{must be initialized by a constant expression}}
+
+extern __attribute__((dllimport)) void fun();
+constexpr void (*funp)(void) = &fun; // expected-error {{must be initialized by a constant expression}}
+
+template <void (*)()>
+struct S {};
+S<&fun> x;
+
+template <int *>
+struct U {};
+U<&var> y;
diff --git a/test/SemaCXX/PR20110.cpp b/test/SemaCXX/PR20110.cpp
new file mode 100644
index 0000000..e540a73
--- /dev/null
+++ b/test/SemaCXX/PR20110.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// expected-no-diagnostics
+
+// FIXME: These templates should trigger errors in C++11 mode.
+
+template <char const *p>
+class A {
+  char const *get_p() { return *p; }
+};
+template <int p>
+class B {
+  char const *get_p() { return p; }
+};
+
diff --git a/test/SemaCXX/PR8012.cpp b/test/SemaCXX/PR8012.cpp
index 9cfc2b0..0a43af7 100644
--- a/test/SemaCXX/PR8012.cpp
+++ b/test/SemaCXX/PR8012.cpp
@@ -1,3 +1,3 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
 
-void foo (int operator+); // expected-error{{cannot be the name of a parameter}}
+void foo(int operator+); // expected-error{{'operator+' cannot be the name of a parameter}}
diff --git a/test/SemaCXX/__try.cpp b/test/SemaCXX/__try.cpp
index 1c45581..28a3701 100644
--- a/test/SemaCXX/__try.cpp
+++ b/test/SemaCXX/__try.cpp
@@ -1,5 +1,4 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -fborland-extensions -fcxx-exceptions %s
-// expected-no-diagnostics
 
 // This test is from http://docwiki.embarcadero.com/RADStudio/en/Try
 
@@ -77,3 +76,14 @@
 template void Finally<void>();
 
 }
+
+void test___leave() {
+  // Most tests are in __try.c.
+
+  // Clang accepts try with __finally. MSVC doesn't. (Maybe a Borland thing?)
+  // __leave in mixed blocks isn't supported.
+  try {
+    __leave; // expected-error{{'__leave' statement not in __try block}}
+  } __finally {
+  }
+}
diff --git a/test/SemaCXX/abstract.cpp b/test/SemaCXX/abstract.cpp
index d7e2d0a..b521196 100644
--- a/test/SemaCXX/abstract.cpp
+++ b/test/SemaCXX/abstract.cpp
@@ -268,16 +268,16 @@
 }
 
 namespace pr12658 {
-  class C {

-    public:

-      C(int v){}

-      virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f' in 'C'}}

-  };

-

-  void foo( C& c ) {}

-

-  void bar( void ) {

-    foo(C(99)); // expected-error {{allocating an object of abstract class type 'pr12658::C'}}

+  class C {
+    public:
+      C(int v){}
+      virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f' in 'C'}}
+  };
+
+  void foo( C& c ) {}
+
+  void bar( void ) {
+    foo(C(99)); // expected-error {{allocating an object of abstract class type 'pr12658::C'}}
   }
 }
 
diff --git a/test/SemaCXX/access.cpp b/test/SemaCXX/access.cpp
index 5ccd418..5fa1509 100644
--- a/test/SemaCXX/access.cpp
+++ b/test/SemaCXX/access.cpp
@@ -136,3 +136,25 @@
     };
   }
 }
+
+namespace LocalExternVar {
+  class test {
+  private:
+    struct private_struct { // expected-note 2{{here}}
+      int x;
+    };
+    int use_private();
+  };
+
+  int test::use_private() {
+    extern int array[sizeof(test::private_struct)]; // ok
+    return array[0];
+  }
+
+  int f() {
+    extern int array[sizeof(test::private_struct)]; // expected-error {{private}}
+    return array[0];
+  }
+
+  int array[sizeof(test::private_struct)]; // expected-error {{private}}
+}
diff --git a/test/SemaCXX/addr-of-overloaded-function-casting.cpp b/test/SemaCXX/addr-of-overloaded-function-casting.cpp
index 784c8a0..edf4c13 100644
--- a/test/SemaCXX/addr-of-overloaded-function-casting.cpp
+++ b/test/SemaCXX/addr-of-overloaded-function-casting.cpp
@@ -1,8 +1,8 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 void g();
 
-void f(); // expected-note 9{{candidate function}}
-void f(int); // expected-note 9{{candidate function}}
+void f(); // expected-note 11{{candidate function}}
+void f(int); // expected-note 11{{candidate function}}
 
 template <class T>
 void t(T); // expected-note 3{{candidate function}} \
@@ -58,4 +58,13 @@
   { bool b = static_cast<int (&)(char)>(t); } // expected-error{{does not match required}}
   
   { bool b = static_cast<void (&)(char)>(f); } // expected-error{{does not match}}
+
+  {
+    // The error should be reported when casting overloaded function to the
+    // compatible function type (not to be confused with function pointer or
+    // function reference type.)
+    typedef void (FnType)(int);
+    FnType a = static_cast<FnType>(f); // expected-error{{address of overloaded function}}
+    FnType b = (FnType)(f); // expected-error{{address of overloaded function}}
+  }
 }
diff --git a/test/SemaCXX/addr-of-overloaded-function.cpp b/test/SemaCXX/addr-of-overloaded-function.cpp
index 230a1eb..358fe8d 100644
--- a/test/SemaCXX/addr-of-overloaded-function.cpp
+++ b/test/SemaCXX/addr-of-overloaded-function.cpp
@@ -84,7 +84,7 @@
 
   void h() {
     // Do not suggest '()' since an int argument is required
-    q1<int>; // expected-error-re{{reference to non-static member function must be called$}}
+    q1<int>; // expected-error-re{{reference to non-static member function must be called{{$}}}}
     // Suggest '()' since there's a default value for the only argument & the
     // type argument is already provided
     q2<int>; // expected-error{{reference to non-static member function must be called; did you mean to call it with no arguments?}}
@@ -92,7 +92,7 @@
     // already provided
     q3<int>; // expected-error{{reference to non-static member function must be called; did you mean to call it with no arguments?}}
     // Do not suggest '()' since another type argument is required
-    q4<int>; // expected-error-re{{reference to non-static member function must be called$}}
+    q4<int>; // expected-error-re{{reference to non-static member function must be called{{$}}}}
     // Suggest '()' since the type parameter has a default value
     q5; // expected-error{{reference to non-static member function must be called; did you mean to call it with no arguments?}}
   }
@@ -220,20 +220,20 @@
 
   void QualifierTest() {
     void (Qualifiers::*X)();
-    X = &Qualifiers::C; // expected-error {{assigning to 'void (test1::Qualifiers::*)()' from incompatible type 'void (test1::Qualifiers::*)() const': different qualifiers (none vs const)}}
-    X = &Qualifiers::V; // expected-error{{assigning to 'void (test1::Qualifiers::*)()' from incompatible type 'void (test1::Qualifiers::*)() volatile': different qualifiers (none vs volatile)}}
-    X = &Qualifiers::R; // expected-error{{assigning to 'void (test1::Qualifiers::*)()' from incompatible type 'void (test1::Qualifiers::*)() restrict': different qualifiers (none vs restrict)}}
-    X = &Qualifiers::CV; // expected-error{{assigning to 'void (test1::Qualifiers::*)()' from incompatible type 'void (test1::Qualifiers::*)() const volatile': different qualifiers (none vs const and volatile)}}
-    X = &Qualifiers::CR; // expected-error{{assigning to 'void (test1::Qualifiers::*)()' from incompatible type 'void (test1::Qualifiers::*)() const restrict': different qualifiers (none vs const and restrict)}}
-    X = &Qualifiers::VR; // expected-error{{assigning to 'void (test1::Qualifiers::*)()' from incompatible type 'void (test1::Qualifiers::*)() volatile restrict': different qualifiers (none vs volatile and restrict)}}
-    X = &Qualifiers::CVR; // expected-error{{assigning to 'void (test1::Qualifiers::*)()' from incompatible type 'void (test1::Qualifiers::*)() const volatile restrict': different qualifiers (none vs const, volatile, and restrict)}}
+    X = &Qualifiers::C; // expected-error-re {{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const': different qualifiers (none vs const)}}
+    X = &Qualifiers::V; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} volatile': different qualifiers (none vs volatile)}}
+    X = &Qualifiers::R; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} restrict': different qualifiers (none vs restrict)}}
+    X = &Qualifiers::CV; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const volatile': different qualifiers (none vs const and volatile)}}
+    X = &Qualifiers::CR; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const restrict': different qualifiers (none vs const and restrict)}}
+    X = &Qualifiers::VR; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} volatile restrict': different qualifiers (none vs volatile and restrict)}}
+    X = &Qualifiers::CVR; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const volatile restrict': different qualifiers (none vs const, volatile, and restrict)}}
   }
 
   struct Dummy {
     void N() {};
   };
 
-  void (Qualifiers::*X)() = &Dummy::N; // expected-error{{cannot initialize a variable of type 'void (test1::Qualifiers::*)()' with an rvalue of type 'void (test1::Dummy::*)()': different classes ('test1::Qualifiers' vs 'test1::Dummy')}}
+  void (Qualifiers::*X)() = &Dummy::N; // expected-error-re{{cannot initialize a variable of type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' with an rvalue of type 'void (test1::Dummy::*)(){{( __attribute__\(\(thiscall\)\))?}}': different classes ('test1::Qualifiers' vs 'test1::Dummy')}}
 }
 
 template <typename T> class PR16561 {
diff --git a/test/SemaCXX/aggregate-initialization.cpp b/test/SemaCXX/aggregate-initialization.cpp
index 885bf70..4e41774 100644
--- a/test/SemaCXX/aggregate-initialization.cpp
+++ b/test/SemaCXX/aggregate-initialization.cpp
@@ -49,7 +49,7 @@
   A(int);
   ~A();
   
-  A(const A&) = delete; // expected-note 2 {{function has been explicitly marked deleted here}}
+  A(const A&) = delete; // expected-note 2 {{'A' has been explicitly marked deleted here}}
 };
 
 struct B {
diff --git a/test/SemaCXX/alias-template.cpp b/test/SemaCXX/alias-template.cpp
index db9c82a..89efc50 100644
--- a/test/SemaCXX/alias-template.cpp
+++ b/test/SemaCXX/alias-template.cpp
@@ -102,10 +102,10 @@
 };
 
 namespace TagName {
-  template<typename Z> using S = struct { int n; }; // expected-error {{can not be defined}}
-  template<typename Z> using T = class { int n; }; // expected-error {{can not be defined}}
-  template<typename Z> using U = enum { a, b, c }; // expected-error {{can not be defined}}
-  template<typename Z> using V = struct V { int n; }; // expected-error {{'TagName::V' can not be defined in a type alias template}}
+  template<typename Z> using S = struct { int n; }; // expected-error {{cannot be defined}}
+  template<typename Z> using T = class { int n; }; // expected-error {{cannot be defined}}
+  template<typename Z> using U = enum { a, b, c }; // expected-error {{cannot be defined}}
+  template<typename Z> using V = struct V { int n; }; // expected-error {{'TagName::V' cannot be defined in a type alias template}}
 }
 
 namespace StdExample {
@@ -136,7 +136,7 @@
 namespace VoidArg {
   template<typename Z> using V = void;
   V<int> f(int); // ok
-  V<char> g(V<double>); // expected-error {{empty parameter list defined with a type alias of 'void' not allowed}}
+  V<char> g(V<double>); // ok (DR577)
 }
 
 namespace Curried {
diff --git a/test/SemaCXX/alignof.cpp b/test/SemaCXX/alignof.cpp
index f0b89ee..011f459 100644
--- a/test/SemaCXX/alignof.cpp
+++ b/test/SemaCXX/alignof.cpp
@@ -62,3 +62,18 @@
 long long int test14[2];
 
 static_assert(alignof(test14) == 8, "foo"); // expected-warning {{'alignof' applied to an expression is a GNU extension}}
+
+// PR19992
+static_assert(alignof(int[]) == alignof(int), ""); // ok
+
+namespace alignof_array_expr {
+  alignas(32) extern int n[];
+  static_assert(alignof(n) == 32, ""); // expected-warning {{GNU extension}}
+
+  template<int> struct S {
+    static int a[];
+  };
+  template<int N> int S<N>::a[N];
+  // ok, does not complete type of S<-1>::a
+  static_assert(alignof(S<-1>::a) == alignof(int), ""); // expected-warning {{GNU extension}}
+}
diff --git a/test/SemaCXX/anonymous-struct.cpp b/test/SemaCXX/anonymous-struct.cpp
index 8a61041..1b5dc13 100644
--- a/test/SemaCXX/anonymous-struct.cpp
+++ b/test/SemaCXX/anonymous-struct.cpp
@@ -14,3 +14,10 @@
   static struct {
   };
 };
+
+template <class T> void foo(T);
+typedef struct { // expected-note {{use a tag name here to establish linkage prior to definition}} expected-note {{declared here}}
+  void test() {
+    foo(this); // expected-warning {{template argument uses unnamed type}}
+  }
+} A; // expected-error {{unsupported: typedef changes linkage of anonymous type, but linkage was already computed}}
diff --git a/test/SemaCXX/anonymous-union-cxx11.cpp b/test/SemaCXX/anonymous-union-cxx11.cpp
index 9f987a9..b0dd1a8 100644
--- a/test/SemaCXX/anonymous-union-cxx11.cpp
+++ b/test/SemaCXX/anonymous-union-cxx11.cpp
@@ -12,3 +12,12 @@
     (void)sizeof(bar::member);
   }
 }
+
+namespace PR20021 {
+class C {
+  union {
+    static_assert(true, "");
+    int i;
+  };
+};
+}
diff --git a/test/SemaCXX/ast-print.cpp b/test/SemaCXX/ast-print.cpp
index a1975b4..4851571 100644
--- a/test/SemaCXX/ast-print.cpp
+++ b/test/SemaCXX/ast-print.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -ast-print %s | FileCheck %s
+// RUN: %clang_cc1 -ast-print %s -std=gnu++11 | FileCheck %s
 
 // CHECK: r;
 // CHECK-NEXT: (r->method());
@@ -164,3 +164,47 @@
 void test14() {
   struct X { union { int x; } x; };
 }
+
+
+// CHECK: float test15() {
+// CHECK:     return __builtin_asinf(1.F);
+// CHECK: }
+// CHECK-NOT: extern "C"
+float test15() {
+  return __builtin_asinf(1.0F);
+}
+
+namespace PR18776 {
+struct A {
+  operator void *();
+  explicit operator bool();
+  A operator&(A);
+};
+
+// CHECK: struct A
+// CHECK-NEXT: {{^[ ]*operator}} void *();
+// CHECK-NEXT: {{^[ ]*explicit}} operator bool();
+
+void bar(void *);
+
+void foo() {
+  A a, b;
+  bar(a & b);
+// CHECK: bar(a & b);
+  if (a & b)
+// CHECK: if (a & b)
+    return;
+}
+};
+
+namespace {
+void test(int i) {
+  switch (i) {
+    case 1:
+      // CHECK: {{\[\[clang::fallthrough\]\]}}
+      [[clang::fallthrough]];
+    case 2:
+      break;
+  }
+}
+}
diff --git a/test/SemaCXX/atomic-type.cpp b/test/SemaCXX/atomic-type.cpp
new file mode 100644
index 0000000..ae18eab
--- /dev/null
+++ b/test/SemaCXX/atomic-type.cpp
@@ -0,0 +1,85 @@
+// RUN: %clang_cc1 -verify -pedantic %s -std=c++98
+// RUN: %clang_cc1 -verify -pedantic %s -std=c++11
+
+template<typename T> struct atomic {
+  _Atomic(T) value;
+
+  void f() _Atomic; // expected-error {{expected ';' at end of declaration list}}
+};
+
+template<typename T> struct user {
+  struct inner { char n[sizeof(T)]; };
+  atomic<inner> i;
+};
+
+user<int> u;
+
+// Test overloading behavior of atomics.
+struct A { };
+
+int &ovl1(_Atomic(int));
+int &ovl1(_Atomic int); // ok, redeclaration
+long &ovl1(_Atomic(long));
+float &ovl1(_Atomic(float));
+double &ovl1(_Atomic(A const *const *));
+double &ovl1(A const *const *_Atomic);
+short &ovl1(_Atomic(A **));
+
+void test_overloading(int i, float f, _Atomic(int) ai, _Atomic(float) af,
+                      long l, _Atomic(long) al, A const *const *acc,
+                      A const ** ac, A **a) {
+  int& ir1 = ovl1(i);
+  int& ir2 = ovl1(ai);
+  long& lr1 = ovl1(l);
+  long& lr2 = ovl1(al);
+  float &fr1 = ovl1(f);
+  float &fr2 = ovl1(af);
+  double &dr1 = ovl1(acc);
+  double &dr2 = ovl1(ac);
+  short &sr1 = ovl1(a);
+}
+
+typedef int (A::*fp)() _Atomic; // expected-error {{expected ';' after top level declarator}} expected-warning {{does not declare anything}}
+
+typedef _Atomic(int(A::*)) atomic_mem_ptr_to_int;
+typedef int(A::*_Atomic atomic_mem_ptr_to_int);
+
+typedef _Atomic(int)(A::*mem_ptr_to_atomic_int);
+typedef _Atomic int(A::*mem_ptr_to_atomic_int);
+
+typedef _Atomic(int)&atomic_int_ref;
+typedef _Atomic int &atomic_int_ref;
+typedef _Atomic atomic_int_ref atomic_int_ref; // expected-warning {{'_Atomic' qualifier on reference type 'atomic_int_ref' (aka '_Atomic(int) &') has no effect}}
+
+typedef int &_Atomic atomic_reference_to_int; // expected-error {{'_Atomic' qualifier may not be applied to a reference}}
+typedef _Atomic(int &) atomic_reference_to_int; // expected-error {{_Atomic cannot be applied to reference type 'int &'}}
+
+struct S {
+  _Atomic union { int n; }; // expected-warning {{anonymous union cannot be '_Atomic'}}
+};
+
+namespace copy_init {
+  struct X {
+    X(int);
+    int n;
+  };
+  _Atomic(X) y = X(0);
+  _Atomic(X) z(X(0));
+  void f() { y = X(0); }
+
+  _Atomic(X) e1(0); // expected-error {{cannot initialize}}
+#if __cplusplus >= 201103L
+  _Atomic(X) e2{0}; // expected-error {{illegal initializer}}
+  _Atomic(X) a{X(0)};
+#endif
+
+  struct Y {
+    _Atomic(X) a;
+    _Atomic(int) b;
+  };
+  Y y1 = { X(0), 4 };
+  Y y2 = { 0, 4 }; // expected-error {{cannot initialize}}
+  // FIXME: It's not really clear if we should allow these. Generally, C++11
+  // allows extraneous braces around initializers.
+  Y y3 = { { X(0) }, { 4 } }; // expected-error 2{{illegal initializer type}}
+}
diff --git a/test/SemaCXX/atomic-type.cxx b/test/SemaCXX/atomic-type.cxx
deleted file mode 100644
index 947bb3c..0000000
--- a/test/SemaCXX/atomic-type.cxx
+++ /dev/null
@@ -1,58 +0,0 @@
-// RUN: %clang_cc1 -verify -pedantic %s
-
-template<typename T> struct atomic {
-  _Atomic(T) value;
-
-  void f() _Atomic; // expected-error {{expected ';' at end of declaration list}}
-};
-
-template<typename T> struct user {
-  struct inner { char n[sizeof(T)]; };
-  atomic<inner> i;
-};
-
-user<int> u;
-
-// Test overloading behavior of atomics.
-struct A { };
-
-int &ovl1(_Atomic(int));
-int &ovl1(_Atomic int); // ok, redeclaration
-long &ovl1(_Atomic(long));
-float &ovl1(_Atomic(float));
-double &ovl1(_Atomic(A const *const *));
-double &ovl1(A const *const *_Atomic);
-short &ovl1(_Atomic(A **));
-
-void test_overloading(int i, float f, _Atomic(int) ai, _Atomic(float) af,
-                      long l, _Atomic(long) al, A const *const *acc,
-                      A const ** ac, A **a) {
-  int& ir1 = ovl1(i);
-  int& ir2 = ovl1(ai);
-  long& lr1 = ovl1(l);
-  long& lr2 = ovl1(al);
-  float &fr1 = ovl1(f);
-  float &fr2 = ovl1(af);
-  double &dr1 = ovl1(acc);
-  double &dr2 = ovl1(ac);
-  short &sr1 = ovl1(a);
-}
-
-typedef int (A::*fp)() _Atomic; // expected-error {{expected ';' after top level declarator}} expected-warning {{does not declare anything}}
-
-typedef _Atomic(int(A::*)) atomic_mem_ptr_to_int;
-typedef int(A::*_Atomic atomic_mem_ptr_to_int);
-
-typedef _Atomic(int)(A::*mem_ptr_to_atomic_int);
-typedef _Atomic int(A::*mem_ptr_to_atomic_int);
-
-typedef _Atomic(int)&atomic_int_ref;
-typedef _Atomic int &atomic_int_ref;
-typedef _Atomic atomic_int_ref atomic_int_ref; // ok, qualifiers on references ignored in this case.
-
-typedef int &_Atomic atomic_reference_to_int; // expected-error {{'_Atomic' qualifier may not be applied to a reference}}
-typedef _Atomic(int &) atomic_reference_to_int; // expected-error {{_Atomic cannot be applied to reference type 'int &'}}
-
-struct S {
-  _Atomic union { int n; }; // expected-warning {{anonymous union cannot be '_Atomic'}}
-};
diff --git a/test/SemaCXX/attr-common.cpp b/test/SemaCXX/attr-common.cpp
index 58b3013..fb98639 100644
--- a/test/SemaCXX/attr-common.cpp
+++ b/test/SemaCXX/attr-common.cpp
@@ -1,3 +1,3 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 
-__attribute__((common)) int x; // expected-error {{common attribute is not supported in C++}}
+__attribute__((common)) int x; // expected-error {{'common' attribute is not supported in C++}}
diff --git a/test/SemaCXX/attr-cxx0x.cpp b/test/SemaCXX/attr-cxx0x.cpp
index e24e12e..6ba89a6 100644
--- a/test/SemaCXX/attr-cxx0x.cpp
+++ b/test/SemaCXX/attr-cxx0x.cpp
@@ -45,3 +45,8 @@
 static_assert(alignof(outer<int,char>::inner<double,short>) == alignof(int) * alignof(double), "template's alignment is wrong");
 
 static_assert(alignof(int(int)) >= 1, "alignof(function) not positive"); // expected-error{{invalid application of 'alignof' to a function type}}
+
+[[__carries_dependency__]]  // expected-warning{{unknown attribute '__carries_dependency__' ignored}}
+void func(void);
+
+alignas(4) auto PR19252 = 0;
diff --git a/test/SemaCXX/attr-deprecated.cpp b/test/SemaCXX/attr-deprecated.cpp
index b3223f3..d28eb75 100644
--- a/test/SemaCXX/attr-deprecated.cpp
+++ b/test/SemaCXX/attr-deprecated.cpp
@@ -1,10 +1,10 @@
 // RUN: %clang_cc1 %s -verify -fexceptions
 class A {
-  void f() __attribute__((deprecated)); // expected-note 2 {{declared here}}
+  void f() __attribute__((deprecated)); // expected-note 2 {{'f' has been explicitly marked deprecated here}}
   void g(A* a);
   void h(A* a) __attribute__((deprecated));
 
-  int b __attribute__((deprecated)); // expected-note 2 {{declared here}}
+  int b __attribute__((deprecated)); // expected-note 2 {{'b' has been explicitly marked deprecated here}}
 };
 
 void A::g(A* a)
@@ -26,7 +26,7 @@
 }
 
 struct B {
-  virtual void f() __attribute__((deprecated)); // expected-note 4 {{declared here}}
+  virtual void f() __attribute__((deprecated)); // expected-note 4 {{'f' has been explicitly marked deprecated here}}
   void g();
 };
 
@@ -68,20 +68,20 @@
 
 // Overloaded namespace members.
 namespace test1 {
-  void foo(int) __attribute__((deprecated)); // expected-note {{declared here}}
+  void foo(int) __attribute__((deprecated)); // expected-note {{'foo' has been explicitly marked deprecated here}}
   void test1() { foo(10); } // expected-warning {{deprecated}}
-  void foo(short) __attribute__((deprecated)); // expected-note {{declared here}}
+  void foo(short) __attribute__((deprecated)); // expected-note {{'foo' has been explicitly marked deprecated here}}
   void test2(short s) { foo(s); } // expected-warning {{deprecated}}
   void foo(long);
   void test3(long l) { foo(l); }
   struct A {
-    friend void foo(A*) __attribute__((deprecated)); // expected-note {{declared here}}
+    friend void foo(A*) __attribute__((deprecated)); // expected-note {{'foo' has been explicitly marked deprecated here}}
   };
   void test4(A *a) { foo(a); } // expected-warning {{deprecated}}
 
   namespace ns {
     struct Foo {};
-    void foo(const Foo &f) __attribute__((deprecated)); // expected-note {{declared here}}
+    void foo(const Foo &f) __attribute__((deprecated)); // expected-note {{'foo' has been explicitly marked deprecated here}}
   }
   void test5() {
     foo(ns::Foo()); // expected-warning {{deprecated}}
@@ -91,9 +91,9 @@
 // Overloaded class members.
 namespace test2 {
   struct A {
-    void foo(int) __attribute__((deprecated)); // expected-note 2 {{declared here}}
+    void foo(int) __attribute__((deprecated)); // expected-note 2 {{'foo' has been explicitly marked deprecated here}}
     void foo(long);
-    static void bar(int) __attribute__((deprecated)); // expected-note 3 {{declared here}}
+    static void bar(int) __attribute__((deprecated)); // expected-note 3 {{'bar' has been explicitly marked deprecated here}}
     static void bar(long);
 
     void test2(int i, long l);
@@ -120,12 +120,12 @@
 namespace test3 {
   struct A {
     void operator*(const A &);
-    void operator*(int) __attribute__((deprecated)); // expected-note {{declared here}}
+    void operator*(int) __attribute__((deprecated)); // expected-note {{'operator*' has been explicitly marked deprecated here}}
     void operator-(const A &) const;
   };
   void operator+(const A &, const A &);
-  void operator+(const A &, int) __attribute__((deprecated)); // expected-note {{declared here}}
-  void operator-(const A &, int) __attribute__((deprecated)); // expected-note {{declared here}}
+  void operator+(const A &, int) __attribute__((deprecated)); // expected-note {{'operator+' has been explicitly marked deprecated here}}
+  void operator-(const A &, int) __attribute__((deprecated)); // expected-note {{'operator-' has been explicitly marked deprecated here}}
 
   void test() {
     A a, b;
@@ -143,9 +143,9 @@
   struct A {
     typedef void (*intfn)(int);
     typedef void (*unintfn)(unsigned);
-    operator intfn() __attribute__((deprecated)); // expected-note {{declared here}}
+    operator intfn() __attribute__((deprecated)); // expected-note {{'operator void (*)(int)' has been explicitly marked deprecated here}}
     operator unintfn();
-    void operator ()(A &) __attribute__((deprecated)); // expected-note {{declared here}}
+    void operator ()(A &) __attribute__((deprecated)); // expected-note {{'operator()' has been explicitly marked deprecated here}}
     void operator ()(const A &);
   };
 
@@ -163,7 +163,7 @@
 
 namespace test5 {
   struct A {
-    operator int() __attribute__((deprecated)); // expected-note 3 {{declared here}}
+    operator int() __attribute__((deprecated)); // expected-note 3 {{'operator int' has been explicitly marked deprecated here}}
     operator long();
   };
   void test1(A a) {
@@ -193,8 +193,8 @@
 
 // rdar://problem/8518751
 namespace test6 {
-  enum __attribute__((deprecated)) A { // expected-note {{declared here}}
-    a0 // expected-note {{declared here}}
+  enum __attribute__((deprecated)) A { // expected-note {{'A' has been explicitly marked deprecated here}}
+    a0 // expected-note {{'a0' has been explicitly marked deprecated here}}
   };
   void testA() {
     A x; // expected-warning {{'A' is deprecated}}
@@ -202,7 +202,7 @@
   }
   
   enum B {
-    b0 __attribute__((deprecated)), // expected-note {{declared here}}
+    b0 __attribute__((deprecated)), // expected-note {{'b0' has been explicitly marked deprecated here}}
     b1
   };
   void testB() {
@@ -212,8 +212,8 @@
   }
 
   template <class T> struct C {
-    enum __attribute__((deprecated)) Enum { // expected-note {{declared here}}
-      c0 // expected-note {{declared here}}
+    enum __attribute__((deprecated)) Enum { // expected-note {{'Enum' has been explicitly marked deprecated here}}
+      c0 // expected-note {{'c0' has been explicitly marked deprecated here}}
     };
   };
   void testC() {
@@ -224,7 +224,7 @@
   template <class T> struct D {
     enum Enum {
       d0,
-      d1 __attribute__((deprecated)), // expected-note {{declared here}}
+      d1 __attribute__((deprecated)), // expected-note {{'d1' has been explicitly marked deprecated here}}
     };
   };
   void testD() {
@@ -236,8 +236,8 @@
 
 namespace test7 {
   struct X {
-    void* operator new(typeof(sizeof(void*))) __attribute__((deprecated));  // expected-note{{'operator new' declared here}}
-    void operator delete(void *) __attribute__((deprecated));  // expected-note{{'operator delete' declared here}}
+    void* operator new(typeof(sizeof(void*))) __attribute__((deprecated));  // expected-note{{'operator new' has been explicitly marked deprecated here}}
+    void operator delete(void *) __attribute__((deprecated));  // expected-note{{'operator delete' has been explicitly marked deprecated here}}
   };
 
   void test() {
@@ -247,6 +247,6 @@
 
 // rdar://problem/15044218
 typedef struct TDS {
-} TDS __attribute__((deprecated)); // expected-note {{'TDS' declared here}}
+} TDS __attribute__((deprecated)); // expected-note {{'TDS' has been explicitly marked deprecated here}}
 TDS tds; // expected-warning {{'TDS' is deprecated}}
 struct TDS tds2; // no warning, attribute only applies to the typedef.
diff --git a/test/SemaCXX/attr-flatten.cpp b/test/SemaCXX/attr-flatten.cpp
new file mode 100644
index 0000000..afcba72
--- /dev/null
+++ b/test/SemaCXX/attr-flatten.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+int i __attribute__((flatten)); // expected-error {{'flatten' attribute only applies to functions}}
+
+void f1() __attribute__((flatten));
+void f2() __attribute__((flatten(1))); // expected-error {{'flatten' attribute takes no arguments}}
+
+template <typename T>
+void tf1() __attribute__((flatten));
+
+int f3(int __attribute__((flatten)), int); // expected-error{{'flatten' attribute only applies to functions}}
+
+struct A {
+  int f __attribute__((flatten));  // expected-error{{'flatten' attribute only applies to functions}}
+  void mf1() __attribute__((flatten));
+  static void mf2() __attribute__((flatten));
+};
+
+int ci [[gnu::flatten]]; // expected-error {{'flatten' attribute only applies to functions}}
+
+[[gnu::flatten]] void cf1();
+[[gnu::flatten(1)]] void cf2(); // expected-error {{'flatten' attribute takes no arguments}}
+
+template <typename T>
+[[gnu::flatten]]
+void ctf1();
+
+int cf3(int c[[gnu::flatten]], int); // expected-error{{'flatten' attribute only applies to functions}}
+
+struct CA {
+  int f [[gnu::flatten]];  // expected-error{{'flatten' attribute only applies to functions}}
+  [[gnu::flatten]] void mf1();
+  [[gnu::flatten]] static void mf2();
+};
diff --git a/test/SemaCXX/attr-no-sanitize-address.cpp b/test/SemaCXX/attr-no-sanitize-address.cpp
index f180349..9ca2863 100644
--- a/test/SemaCXX/attr-no-sanitize-address.cpp
+++ b/test/SemaCXX/attr-no-sanitize-address.cpp
@@ -15,23 +15,23 @@
 
 int noanal_testfn(int y) {
   int x NO_SANITIZE_ADDRESS = y; // \
-    // expected-error {{'no_sanitize_address' attribute only applies to functions and methods}}
+    // expected-error {{'no_sanitize_address' attribute only applies to functions}}
   return x;
 }
 
 int noanal_test_var NO_SANITIZE_ADDRESS; // \
-  // expected-error {{'no_sanitize_address' attribute only applies to functions and methods}}
+  // expected-error {{'no_sanitize_address' attribute only applies to functions}}
 
 class NoanalFoo {
  private:
   int test_field NO_SANITIZE_ADDRESS; // \
-    // expected-error {{'no_sanitize_address' attribute only applies to functions and methods}}
+    // expected-error {{'no_sanitize_address' attribute only applies to functions}}
   void test_method() NO_SANITIZE_ADDRESS;
 };
 
 class NO_SANITIZE_ADDRESS NoanalTestClass { // \
-  // expected-error {{'no_sanitize_address' attribute only applies to functions and methods}}
+  // expected-error {{'no_sanitize_address' attribute only applies to functions}}
 };
 
 void noanal_fun_params(int lvar NO_SANITIZE_ADDRESS); // \
-  // expected-error {{'no_sanitize_address' attribute only applies to functions and methods}}
+  // expected-error {{'no_sanitize_address' attribute only applies to functions}}
diff --git a/test/SemaCXX/attr-no-sanitize-memory.cpp b/test/SemaCXX/attr-no-sanitize-memory.cpp
index d6eca1b..9cbcb03 100644
--- a/test/SemaCXX/attr-no-sanitize-memory.cpp
+++ b/test/SemaCXX/attr-no-sanitize-memory.cpp
@@ -15,23 +15,23 @@
 
 int noanal_testfn(int y) {
   int x NO_SANITIZE_MEMORY = y; // \
-    // expected-error {{'no_sanitize_memory' attribute only applies to functions and methods}}
+    // expected-error {{'no_sanitize_memory' attribute only applies to functions}}
   return x;
 }
 
 int noanal_test_var NO_SANITIZE_MEMORY; // \
-  // expected-error {{'no_sanitize_memory' attribute only applies to functions and methods}}
+  // expected-error {{'no_sanitize_memory' attribute only applies to functions}}
 
 class NoanalFoo {
  private:
   int test_field NO_SANITIZE_MEMORY; // \
-    // expected-error {{'no_sanitize_memory' attribute only applies to functions and methods}}
+    // expected-error {{'no_sanitize_memory' attribute only applies to functions}}
   void test_method() NO_SANITIZE_MEMORY;
 };
 
 class NO_SANITIZE_MEMORY NoanalTestClass { // \
-  // expected-error {{'no_sanitize_memory' attribute only applies to functions and methods}}
+  // expected-error {{'no_sanitize_memory' attribute only applies to functions}}
 };
 
 void noanal_fun_params(int lvar NO_SANITIZE_MEMORY); // \
-  // expected-error {{'no_sanitize_memory' attribute only applies to functions and methods}}
+  // expected-error {{'no_sanitize_memory' attribute only applies to functions}}
diff --git a/test/SemaCXX/attr-no-sanitize-thread.cpp b/test/SemaCXX/attr-no-sanitize-thread.cpp
index d6372bc..6cb9c71 100644
--- a/test/SemaCXX/attr-no-sanitize-thread.cpp
+++ b/test/SemaCXX/attr-no-sanitize-thread.cpp
@@ -15,23 +15,23 @@
 
 int noanal_testfn(int y) {
   int x NO_SANITIZE_THREAD = y; // \
-    // expected-error {{'no_sanitize_thread' attribute only applies to functions and methods}}
+    // expected-error {{'no_sanitize_thread' attribute only applies to functions}}
   return x;
 }
 
 int noanal_test_var NO_SANITIZE_THREAD; // \
-  // expected-error {{'no_sanitize_thread' attribute only applies to functions and methods}}
+  // expected-error {{'no_sanitize_thread' attribute only applies to functions}}
 
 class NoanalFoo {
  private:
   int test_field NO_SANITIZE_THREAD; // \
-    // expected-error {{'no_sanitize_thread' attribute only applies to functions and methods}}
+    // expected-error {{'no_sanitize_thread' attribute only applies to functions}}
   void test_method() NO_SANITIZE_THREAD;
 };
 
 class NO_SANITIZE_THREAD NoanalTestClass { // \
-  // expected-error {{'no_sanitize_thread' attribute only applies to functions and methods}}
+  // expected-error {{'no_sanitize_thread' attribute only applies to functions}}
 };
 
 void noanal_fun_params(int lvar NO_SANITIZE_THREAD); // \
-  // expected-error {{'no_sanitize_thread' attribute only applies to functions and methods}}
+  // expected-error {{'no_sanitize_thread' attribute only applies to functions}}
diff --git a/test/SemaCXX/attr-no-split-stack.cpp b/test/SemaCXX/attr-no-split-stack.cpp
new file mode 100644
index 0000000..3575e99
--- /dev/null
+++ b/test/SemaCXX/attr-no-split-stack.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+int i __attribute__((no_split_stack)); // expected-error {{'no_split_stack' attribute only applies to functions}}
+
+void f1() __attribute__((no_split_stack));
+void f2() __attribute__((no_split_stack(1))); // expected-error {{'no_split_stack' attribute takes no arguments}}
+
+template <typename T>
+void tf1() __attribute__((no_split_stack));
+
+int f3(int __attribute__((no_split_stack)), int); // expected-error{{'no_split_stack' attribute only applies to functions}}
+
+struct A {
+  int f __attribute__((no_split_stack));  // expected-error{{'no_split_stack' attribute only applies to functions}}
+  void mf1() __attribute__((no_split_stack));
+  static void mf2() __attribute__((no_split_stack));
+};
+
+int ci [[gnu::no_split_stack]]; // expected-error {{'no_split_stack' attribute only applies to functions}}
+
+[[gnu::no_split_stack]] void cf1();
+[[gnu::no_split_stack(1)]] void cf2(); // expected-error {{'no_split_stack' attribute takes no arguments}}
+
+template <typename T>
+[[gnu::no_split_stack]]
+void ctf1();
+
+int cf3(int c[[gnu::no_split_stack]], int); // expected-error{{'no_split_stack' attribute only applies to functions}}
+
+struct CA {
+  int f [[gnu::no_split_stack]];  // expected-error{{'no_split_stack' attribute only applies to functions}}
+  [[gnu::no_split_stack]] void mf1();
+  [[gnu::no_split_stack]] static void mf2();
+};
diff --git a/test/SemaCXX/attr-optnone.cpp b/test/SemaCXX/attr-optnone.cpp
new file mode 100644
index 0000000..eaa5000
--- /dev/null
+++ b/test/SemaCXX/attr-optnone.cpp
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -std=c++11 -fms-compatibility -fsyntax-only -verify %s
+
+int foo() __attribute__((optnone));
+int bar() __attribute__((optnone)) __attribute__((noinline));
+
+int baz() __attribute__((always_inline)) __attribute__((optnone)); // expected-error{{'always_inline' and 'optnone' attributes are not compatible}}
+int quz() __attribute__((optnone)) __attribute__((always_inline)); // expected-error{{'optnone' and 'always_inline' attributes are not compatible}}
+
+__forceinline __attribute__((optnone)) int bax(); // expected-error{{'__forceinline' and 'optnone' attributes are not compatible}}
+__attribute__((optnone)) __forceinline int qux(); // expected-error{{'optnone' and '__forceinline' attributes are not compatible}}
+
+int globalVar __attribute__((optnone)); // expected-warning{{'optnone' attribute only applies to functions}}
+
+int fubar(int __attribute__((optnone)), int); // expected-warning{{'optnone' attribute only applies to functions}}
+
+struct A {
+  int aField __attribute__((optnone));  // expected-warning{{'optnone' attribute only applies to functions}}
+};
+
+struct B {
+  void foo() __attribute__((optnone));
+  static void bar() __attribute__((optnone));
+};
+
+// Verify that we can specify the [[clang::optnone]] syntax as well.
+
+[[clang::optnone]]
+int foo2();
+[[clang::optnone]]
+int bar2() __attribute__((noinline));
+
+[[clang::optnone]]
+int baz2() __attribute__((always_inline)); // expected-error{{'always_inline' and 'optnone' attributes are not compatible}}
+
+[[clang::optnone]] int globalVar2; //expected-warning{{'optnone' attribute only applies to functions}}
+
+struct A2 {
+  [[clang::optnone]] int aField; // expected-warning{{'optnone' attribute only applies to functions}}
+};
+
+struct B2 {
+  [[clang::optnone]]
+  void foo();
+  [[clang::optnone]]
+  static void bar();
+};
+
diff --git a/test/SemaCXX/attr-selectany.cpp b/test/SemaCXX/attr-selectany.cpp
index 0f9776d..c27a915 100644
--- a/test/SemaCXX/attr-selectany.cpp
+++ b/test/SemaCXX/attr-selectany.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify -std=c++11 %s
 // MSVC produces similar diagnostics.
 
 __declspec(selectany) void foo() { } // expected-error{{'selectany' can only be applied to data items with external linkage}}
@@ -31,3 +31,6 @@
 };
 
 __declspec(selectany) X x(1);
+
+namespace { class Internal {}; }
+__declspec(selectany) auto x8 = Internal(); // expected-error {{'selectany' can only be applied to data items with external linkage}}
diff --git a/test/SemaCXX/attr-unavailable.cpp b/test/SemaCXX/attr-unavailable.cpp
index 2d82668..51dc8fe 100644
--- a/test/SemaCXX/attr-unavailable.cpp
+++ b/test/SemaCXX/attr-unavailable.cpp
@@ -3,7 +3,7 @@
 int &foo(int); // expected-note {{candidate}}
 double &foo(double); // expected-note {{candidate}}
 void foo(...) __attribute__((__unavailable__)); // expected-note {{candidate function}} \
-// expected-note{{function has been explicitly marked unavailable here}}
+// expected-note{{'foo' has been explicitly marked unavailable here}}
 
 void bar(...) __attribute__((__unavailable__)); // expected-note 2{{explicitly marked unavailable}}
 
@@ -37,3 +37,22 @@
   foo(sp);
   foo();
 }
+
+// Show that delayed processing of 'unavailable' is the same
+// delayed process for 'deprecated'.
+// <rdar://problem/12241361> and <rdar://problem/15584219>
+enum DeprecatedEnum { DE_A, DE_B } __attribute__((deprecated)); // expected-note {{'DeprecatedEnum' has been explicitly marked deprecated here}}
+__attribute__((deprecated)) typedef enum DeprecatedEnum DeprecatedEnum;
+typedef enum DeprecatedEnum AnotherDeprecatedEnum; // expected-warning {{'DeprecatedEnum' is deprecated}}
+
+__attribute__((deprecated))
+DeprecatedEnum testDeprecated(DeprecatedEnum X) { return X; }
+
+
+enum UnavailableEnum { UE_A, UE_B } __attribute__((unavailable)); // expected-note {{'UnavailableEnum' has been explicitly marked unavailable here}}
+__attribute__((unavailable)) typedef enum UnavailableEnum UnavailableEnum;
+typedef enum UnavailableEnum AnotherUnavailableEnum; // expected-error {{'UnavailableEnum' is unavailable}}
+
+
+__attribute__((unavailable))
+UnavailableEnum testUnavailable(UnavailableEnum X) { return X; }
diff --git a/test/SemaCXX/attr-used.cpp b/test/SemaCXX/attr-used.cpp
index 9bae3ed..65df861 100644
--- a/test/SemaCXX/attr-used.cpp
+++ b/test/SemaCXX/attr-used.cpp
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 
-extern char test1[] __attribute__((used)); // expected-warning {{used attribute ignored}}
-extern const char test2[] __attribute__((used)); // expected-warning {{used attribute ignored}}
+extern char test1[] __attribute__((used)); // expected-warning {{'used' attribute ignored}}
+extern const char test2[] __attribute__((used)); // expected-warning {{'used' attribute ignored}}
 extern const char test3[] __attribute__((used)) = "";
diff --git a/test/SemaCXX/attr-weak.cpp b/test/SemaCXX/attr-weak.cpp
index 8939a28..8ba3a95 100644
--- a/test/SemaCXX/attr-weak.cpp
+++ b/test/SemaCXX/attr-weak.cpp
@@ -1,9 +1,9 @@
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s
 
 static int test0 __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}}
 static void test1() __attribute__((weak)); // expected-error {{weak declaration cannot have internal linkage}}
 
-namespace test2 __attribute__((weak)) { // expected-warning {{'weak' attribute only applies to variables and functions}}
+namespace test2 __attribute__((weak)) { // expected-warning {{'weak' attribute only applies to variables, functions and classes}}
 }
 
 namespace {
@@ -31,6 +31,10 @@
 };
 template <class T>
 int Test7<T>::var;
-namespace { class Internal; }
+namespace { class Internal {}; }
 template struct Test7<Internal>;
 template struct Test7<int>;
+
+class __attribute__((weak)) Test8 {}; // OK
+
+__attribute__((weak)) auto Test9 = Internal(); // expected-error {{weak declaration cannot have internal linkage}}
diff --git a/test/SemaCXX/attr-weakref.cpp b/test/SemaCXX/attr-weakref.cpp
index 0c3f1d2..46ca5ab 100644
--- a/test/SemaCXX/attr-weakref.cpp
+++ b/test/SemaCXX/attr-weakref.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -verify -std=c++11 %s
 
 // GCC will accept anything as the argument of weakref. Should we
 // check for an existing decl?
@@ -34,3 +34,5 @@
 int a10() __attribute__((weakref ("foo")));
 
 static int v __attribute__((weakref(a1), alias("foo"))); // expected-error {{'weakref' attribute requires a string}}
+
+__attribute__((weakref ("foo"))) auto a11 = 1; // expected-error {{weakref declaration must have internal linkage}}
diff --git a/test/SemaCXX/bool-compare.cpp b/test/SemaCXX/bool-compare.cpp
new file mode 100644
index 0000000..fe47633
--- /dev/null
+++ b/test/SemaCXX/bool-compare.cpp
@@ -0,0 +1,207 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+
+void f(int x, int y, int z) {
+
+  bool a,b;
+
+  if(b > true)    {} // expected-warning {{comparison of true with expression of type 'bool' is always false}}
+  if(b < true)    {} // no warning
+  if(b >= true)   {} // no warning
+  if(b <= true)   {} // expected-warning {{comparison of true with expression of type 'bool' is always true}}
+  if(b == true)   {} // no warning
+  if(b != true)   {} // no warning
+
+  if(b > false)   {} // no warning
+  if(b < false)   {} // expected-warning {{comparison of false with expression of type 'bool' is always false}}
+  if(b >= false)  {} // expected-warning {{comparison of false with expression of type 'bool' is always true}}
+  if(b <= false)  {} // no warning
+  if(b == false)  {} // no warning
+  if(b != false)  {} // no warning
+
+  if(b > 1U){} // expected-warning {{comparison of constant 1 with expression of type 'bool' is always false}}
+
+  if (a > b)      {} // no warning
+  if (a < b)      {} // no warning
+  if (a >= b)     {} // no warning
+  if (a <= b)     {} // no warning
+  if (a == b)     {} // no warning
+  if (a != b)     {} // no warning
+
+  if (a > 0) {} // no warning
+  if (a > 1) {} // expected-warning {{comparison of constant 1 with expression of type 'bool' is always false}}
+  if (a > 2) {} // expected-warning {{comparison of constant 2 with expression of type 'bool' is always false}}
+
+  if (a >= 0) {} // expected-warning {{comparison of constant 0 with expression of type 'bool' is always true}}
+  if (a >= 1) {} // no warning
+  if (a >= 2) {} // expected-warning {{comparison of constant 2 with expression of type 'bool' is always false}}
+  if (a >= -1) {} // expected-warning {{comparison of constant -1 with expression of type 'bool' is always true}}
+
+  if (a <= 0) {} // no warning
+  if (a <= 1) {} // expected-warning {{comparison of constant 1 with expression of type 'bool' is always true}}
+  if (a <= 2) {} // expected-warning {{comparison of constant 2 with expression of type 'bool' is always true}}
+  if (a <= -1) {} // expected-warning {{comparison of constant -1 with expression of type 'bool' is always false}}
+
+  if (!a > 0)     {} // no warning
+  if (!a > 1)     {} // expected-warning {{comparison of constant 1 with expression of type 'bool' is always false}}
+  if (!a > 2)     {} // expected-warning {{comparison of constant 2 with expression of type 'bool' is always false}}
+  if (!a > y)     {} // no warning
+  if (!a > b)     {} // no warning
+  if (!a > -1)    {} // expected-warning {{comparison of constant -1 with expression of type 'bool' is always true}}
+
+  if (!a < 0)     {} // expected-warning {{comparison of constant 0 with expression of type 'bool' is always false}}
+  if (!a < 1)     {} // no warning
+  if (!a < 2)     {} // expected-warning {{comparison of constant 2 with expression of type 'bool' is always true}}
+  if (!a < y)     {} // no warning
+  if (!a < b)     {} // no warning
+  if (!a < -1)    {} // expected-warning {{comparison of constant -1 with expression of type 'bool' is always false}}
+
+  if (!a >= 0)    {} // expected-warning {{comparison of constant 0 with expression of type 'bool' is always true}}
+  if (!a >= 1)    {} // no warning
+  if (!a >= 2)    {} // expected-warning {{comparison of constant 2 with expression of type 'bool' is always false}}
+  if (!a >= y)    {} // no warning
+  if (!a >= b)    {} // no warning
+  if (!a >= -1)   {} // expected-warning {{comparison of constant -1 with expression of type 'bool' is always true}}
+
+  if (!a <= 0)    {} // no warning
+  if (!a <= 1)    {} // expected-warning {{comparison of constant 1 with expression of type 'bool' is always true}}
+  if (!a <= 2)    {} // expected-warning {{comparison of constant 2 with expression of type 'bool' is always true}}
+  if (!a <= y)    {} // no warning
+  if (!a <= b)    {} // no warning
+  if (!a <= -1)   {} // expected-warning {{comparison of constant -1 with expression of type 'bool' is always false}}
+
+  if ((a||b) > 0) {} // no warning
+  if ((a||b) > 1) {} // expected-warning {{comparison of constant 1 with expression of type 'bool' is always false}}
+  if ((a||b) > 4) {} // expected-warning {{comparison of constant 4 with expression of type 'bool' is always false}}
+  if ((a||b) > -1) {}// expected-warning {{comparison of constant -1 with expression of type 'bool' is always true}}
+
+  if ((a&&b) > 0) {} // no warning
+  if ((a&&b) > 1) {} // expected-warning {{comparison of constant 1 with expression of type 'bool' is always false}}
+  if ((a&&b) > 4) {} // expected-warning {{comparison of constant 4 with expression of type 'bool' is always false}}
+
+  if ((a<y) > 0)  {} // no warning
+  if ((a<y) > 1)  {} // expected-warning {{comparison of constant 1 with expression of type 'bool' is always false}}
+  if ((a<y) > 4)  {} // expected-warning {{comparison of constant 4 with expression of type 'bool' is always false}}
+  if ((a<y) > z)  {} // no warning
+  if ((a<y) > -1) {} // expected-warning {{comparison of constant -1 with expression of type 'bool' is always true}}
+
+  if ((a<y) == 0) {} // no warning
+  if ((a<y) == 1) {} // no warning
+  if ((a<y) == 2) {} // expected-warning {{comparison of constant 2 with expression of type 'bool' is always false}}
+  if ((a<y) == z) {} // no warning
+  if ((a<y) == -1) {}// expected-warning {{comparison of constant -1 with expression of type 'bool' is always false}}
+
+  if ((a<y) != 0) {} // no warning
+  if ((a<y) != 1) {} // no warning
+  if ((a<y) != 2) {} // expected-warning {{comparison of constant 2 with expression of type 'bool' is always true}}
+  if ((a<y) != z) {} // no warning
+  if ((a<y) != -1) {}// expected-warning {{comparison of constant -1 with expression of type 'bool' is always true}}
+
+  if ((a<y) == z) {} // no warning
+  if (a>y<z)      {} // no warning
+  if ((a<y) > z)  {} // no warning
+  if((a<y)>(z<y)) {} // no warning
+  if((a<y)==(z<y)){} // no warning
+  if((a<y)!=(z<y)){} // no warning
+  if((z==x)<(y==z)){}  // no warning
+  if((a<y)!=((z==x)<(y==z))){} // no warning
+
+
+  if (0 > !a)     {} // expected-warning {{comparison of constant 0 with expression of type 'bool' is always false}}
+  if (1 > !a)     {} // no warning
+  if (2 > !a)     {} // expected-warning {{comparison of constant 2 with expression of type 'bool' is always true}}
+  if (y > !a)     {} // no warning
+  if (-1 > !a)    {} // expected-warning {{comparison of constant -1 with expression of type 'bool' is always false}}
+
+  if (0 < !a)     {} // no warning
+  if (1 < !a)     {} // expected-warning {{comparison of constant 1 with expression of type 'bool' is always false}}
+  if (2 < !a)     {} // expected-warning {{comparison of constant 2 with expression of type 'bool' is always false}}
+  if (y < !a)     {} // no warning
+  if (-1 < !a)    {} // expected-warning {{comparison of constant -1 with expression of type 'bool' is always true}}
+
+
+  if (0 >= !a)    {} // no warning
+  if (1 >= !a)    {} // expected-warning {{comparison of constant 1 with expression of type 'bool' is always true}}
+  if (2 >= !a)    {} // expected-warning {{comparison of constant 2 with expression of type 'bool' is always true}}
+  if (y >= !a)    {} // no warning
+  if (-1 >= !a)   {} // expected-warning {{comparison of constant -1 with expression of type 'bool' is always false}}
+
+  if (0 <= !a)    {} // expected-warning {{comparison of constant 0 with expression of type 'bool' is always true}}
+  if (1 <= !a)    {} // no warning
+  if (2 <= !a)    {} // expected-warning {{comparison of constant 2 with expression of type 'bool' is always false}}
+  if (y <= !a)    {} //
+  if (-1 <= !a)   {} // expected-warning {{comparison of constant -1 with expression of type 'bool' is always true}}
+
+  if (0 > (a||b)) {} // expected-warning {{comparison of constant 0 with expression of type 'bool' is always false}}
+  if (1 > (a||b)) {} // no warning
+  if (4 > (a||b)) {} // expected-warning {{comparison of constant 4 with expression of type 'bool' is always true}}
+
+  if (0 > (a&&b)) {} // expected-warning {{comparison of constant 0 with expression of type 'bool' is always false}}
+  if (1 > (a&&b)) {} // no warning
+  if (4 > (a&&b)) {} // expected-warning {{comparison of constant 4 with expression of type 'bool' is always true}}
+
+  if (0 > (a<y))  {} // expected-warning {{comparison of constant 0 with expression of type 'bool' is always false}}
+  if (1 > (a<y))  {} // no warning
+  if (4 > (a<y))  {} // expected-warning {{comparison of constant 4 with expression of type 'bool' is always true}}
+  if (z > (a<y))  {} //
+  if (-1 > (a<y)) {} // expected-warning {{comparison of constant -1 with expression of type 'bool' is always false}}
+
+  if (0 == (a<y)) {} // no warning
+  if (1 == (a<y)) {} // no warning
+  if (2 == (a<y)) {} // expected-warning {{comparison of constant 2 with expression of type 'bool' is always false}}
+  if (z == (a<y)) {} // no warning
+  if (-1 == (a<y)){} // expected-warning {{comparison of constant -1 with expression of type 'bool' is always false}}
+
+  if (0 !=(a<y))  {} // no warning
+  if (1 !=(a<y))  {} // no warning
+  if (2 !=(a<y))  {} // expected-warning {{comparison of constant 2 with expression of type 'bool' is always true}}
+  if (z !=(a<y))  {} // no warning
+  if (-1 !=(a<y)) {} // expected-warning {{comparison of constant -1 with expression of type 'bool' is always true}}
+
+  if (z ==(a<y))  {} // no warning
+  if (z<a>y)      {} // no warning
+  if (z > (a<y))  {} // no warning
+  if((z<y)>(a<y)) {} // no warning
+  if((z<y)==(a<y)){} // no warning
+  if((z<y)!=(a<y)){} // no warning
+  if((y==z)<(z==x)){} // no warning
+  if(((z==x)<(y==z))!=(a<y)){}  // no warning
+
+  if(((z==x)<(-1==z))!=(a<y)){} // no warning
+  if(((z==x)<(z==-1))!=(a<y)){} // no warning
+  if(((z==x)<-1)!=(a<y)){} // expected-warning {{comparison of constant -1 with expression of type 'bool' is always false}}
+  if(((z==x)< 2)!=(a<y)){} // expected-warning {{comparison of constant 2 with expression of type 'bool' is always true}}
+  if(((z==x)<(z>2))!=(a<y)){} // no warning
+
+}
+
+
+template<typename T, typename U, typename V> struct X6 {
+  U f(T t, U u, V v) {
+    // IfStmt
+    if (t > 0)
+      return u;
+    else {
+      if (t < 0)
+        return v; // expected-error{{cannot initialize return object of type}}
+    }
+    bool r;
+    // FIXME: We should warn here, DiagRuntimeBehavior does currently not detect this.
+    if(r<0){}
+
+    if (T x = t) {
+      t = x;
+    }
+    return v; // expected-error{{cannot initialize return object of type}}
+  }
+};
+
+struct ConvertibleToInt {
+  operator int() const;
+};
+
+template struct X6<ConvertibleToInt, float, char>;
+template struct X6<bool, int, int*>; // expected-note{{instantiation}}
+
+
+
diff --git a/test/SemaCXX/c99-variable-length-array.cpp b/test/SemaCXX/c99-variable-length-array.cpp
index bb620c7..237f564 100644
--- a/test/SemaCXX/c99-variable-length-array.cpp
+++ b/test/SemaCXX/c99-variable-length-array.cpp
@@ -140,3 +140,24 @@
   }
   int test = f<int>(0); // expected-note {{instantiation of}}
 }
+
+namespace pr18633 {
+  struct A1 {
+    static const int sz;
+    static const int sz2;
+  };
+  const int A1::sz2 = 11;
+  template<typename T>
+  void func () {
+    int arr[A1::sz]; // expected-warning{{variable length arrays are a C99 feature}}
+  }
+  template<typename T>
+  void func2 () {
+    int arr[A1::sz2];
+  }
+  const int A1::sz = 12;
+  void func2() {
+    func<int>();
+    func2<int>();
+  }
+}
diff --git a/test/SemaCXX/calling-conv-compat.cpp b/test/SemaCXX/calling-conv-compat.cpp
index 2d52386..cebac9f 100644
--- a/test/SemaCXX/calling-conv-compat.cpp
+++ b/test/SemaCXX/calling-conv-compat.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -std=c++11 -fms-extensions -cxx-abi microsoft -verify -triple i686-pc-win32 %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -fms-extensions -verify -triple i686-pc-win32 %s
 
 // Pointers to free functions
 void            free_func_default();
@@ -351,24 +351,25 @@
 typedef void (__stdcall  fun_stdcall)();
 typedef void (__fastcall fun_fastcall)();
 
-// FIXME: Adjust cdecl to thiscall when forming a member pointer.
-//fun_default  A::*td1 = &A::method_thiscall;
-fun_cdecl    A::*td2 = &A::method_cdecl;
+fun_default  A::*td1 = &A::method_thiscall;
+fun_cdecl    A::*td2 = &A::method_thiscall;
 fun_stdcall  A::*td3 = &A::method_stdcall;
 fun_fastcall A::*td4 = &A::method_fastcall;
 
 // Round trip the function type through a template, and verify that only cdecl
 // gets adjusted.
-template<typename Fn> struct X {
-  typedef Fn A::*p;
-};
+template<typename Fn> struct X { typedef Fn A::*p; };
 
-// FIXME: Adjust cdecl to thiscall when forming a member pointer.
-//X<void            ()>::p tmpl1 = &A::method_thiscall;
-//X<void __cdecl    ()>::p tmpl2 = &A::method_thiscall;
+X<void            ()>::p tmpl1 = &A::method_thiscall;
+X<void __cdecl    ()>::p tmpl2 = &A::method_thiscall;
 X<void __stdcall  ()>::p tmpl3 = &A::method_stdcall;
 X<void __fastcall ()>::p tmpl4 = &A::method_fastcall;
 
+X<fun_default >::p tmpl5 = &A::method_thiscall;
+X<fun_cdecl   >::p tmpl6 = &A::method_thiscall;
+X<fun_stdcall >::p tmpl7 = &A::method_stdcall;
+X<fun_fastcall>::p tmpl8 = &A::method_fastcall;
+
 } // end namespace MemberPointers
 
 // Test that lambdas that capture nothing convert to cdecl function pointers.
diff --git a/test/SemaCXX/compare.cpp b/test/SemaCXX/compare.cpp
index 8214f78..ef0a524 100644
--- a/test/SemaCXX/compare.cpp
+++ b/test/SemaCXX/compare.cpp
@@ -225,7 +225,7 @@
 }
 
 // Test comparison of short to unsigned.  If tautological compare does not
-// trigger, then the signed comparision warning will.
+// trigger, then the signed comparison warning will.
 void test4(short s) {
   // A is max short plus 1.  All zero and positive shorts are smaller than it.
   // All negative shorts are cast towards the max unsigned range.  Relation
diff --git a/test/SemaCXX/conditional-expr.cpp b/test/SemaCXX/conditional-expr.cpp
index 5abee4a..538de58 100644
--- a/test/SemaCXX/conditional-expr.cpp
+++ b/test/SemaCXX/conditional-expr.cpp
@@ -75,6 +75,7 @@
   int i1 = ToBool() ? 0 : 1;
 
   // p2 (one or both void, and throwing)
+  Fields flds;
   i1 ? throw 0 : throw 1;
   i1 ? test() : throw 1;
   i1 ? throw 0 : test();
@@ -85,8 +86,16 @@
   i1 = i1 ? 0 : (throw 0);
   i1 ? 0 : test(); // expected-error {{right operand to ? is void, but left operand is of type 'int'}}
   i1 ? test() : 0; // expected-error {{left operand to ? is void, but right operand is of type 'int'}}
-  (i1 ? throw 0 : i1) = 0; // expected-error {{expression is not assignable}}
-  (i1 ? i1 : throw 0) = 0; // expected-error {{expression is not assignable}}
+  (i1 ? throw 0 : i1) = 0;
+  (i1 ? i1 : throw 0) = 0;
+  (i1 ? (throw 0) : i1) = 0;
+  (i1 ? i1 : (throw 0)) = 0;
+  (i1 ? (void)(throw 0) : i1) = 0; // expected-error {{left operand to ? is void, but right operand is of type 'int'}}
+  (i1 ? i1 : (void)(throw 0)) = 0; // expected-error {{right operand to ? is void, but left operand is of type 'int'}}
+  int &throwRef1 = (i1 ? flds.i1 : throw 0);
+  int &throwRef2 = (i1 ? throw 0 : flds.i1);
+  int &throwRef3 = (i1 ? flds.b1 : throw 0); // expected-error {{non-const reference cannot bind to bit-field}}
+  int &throwRef4 = (i1 ? throw 0 : flds.b1); // expected-error {{non-const reference cannot bind to bit-field}}
 
   // p3 (one or both class type, convert to each other)
   // b1 (lvalues)
@@ -151,7 +160,6 @@
   &(i1 ? i1 : i2); // expected-error {{cannot take the address of an rvalue}}
 
   // p4 (lvalue, same type)
-  Fields flds;
   int &ir1 = i1 ? flds.i1 : flds.i2;
   (i1 ? flds.b1 : flds.i2) = 0;
   (i1 ? flds.i1 : flds.b2) = 0;
@@ -219,8 +227,8 @@
   // *must* create a separate temporary copy of class objects. This can only
   // be properly tested at runtime, though.
 
-  const Abstract &a = true ? static_cast<const Abstract&>(Derived1()) : Derived2(); // expected-error {{allocating an object of abstract class type 'const Abstract'}}
-  true ? static_cast<const Abstract&>(Derived1()) : throw 3; // expected-error {{allocating an object of abstract class type 'const Abstract'}}
+  const Abstract &abstract1 = true ? static_cast<const Abstract&>(Derived1()) : Derived2(); // expected-error {{allocating an object of abstract class type 'const Abstract'}}
+  const Abstract &abstract2 = true ? static_cast<const Abstract&>(Derived1()) : throw 3; // ok
 }
 
 namespace PR6595 {
@@ -367,3 +375,12 @@
   const volatile int &cvir2 = b ? cvi : vi;
   const volatile int &cvir3 = b ? ci : vi; // expected-error{{volatile lvalue reference to type 'const volatile int' cannot bind to a temporary of type 'int'}}
 }
+
+namespace PR17052 {
+  struct X {
+    int i_;
+    bool b_;
+
+    int &test() { return b_ ? i_ : throw 1; }
+  };
+}
diff --git a/test/SemaCXX/const-cast.cpp b/test/SemaCXX/const-cast.cpp
index 1fe350d..cb9937c 100644
--- a/test/SemaCXX/const-cast.cpp
+++ b/test/SemaCXX/const-cast.cpp
@@ -60,7 +60,7 @@
   // Function pointers.
   f fp2 = const_cast<f>(fp1); // expected-error {{const_cast to 'f' (aka 'int (*)(int)'), which is not a reference, pointer-to-object, or pointer-to-data-member}}
   void (A::*mfn)() = 0;
-  (void)const_cast<void (A::*)()>(mfn); // expected-error {{const_cast to 'void (A::*)()', which is not a reference, pointer-to-object, or pointer-to-data-member}}
+  (void)const_cast<void (A::*)()>(mfn); // expected-error-re {{const_cast to 'void (A::*)(){{( __attribute__\(\(thiscall\)\))?}}', which is not a reference, pointer-to-object, or pointer-to-data-member}}
   (void)const_cast<int&&>(0); // expected-error {{const_cast from rvalue to reference type 'int &&'}} expected-warning {{C++11}}
   return **var3;
 }
diff --git a/test/SemaCXX/constant-expression-cxx11.cpp b/test/SemaCXX/constant-expression-cxx11.cpp
index 6724be7..09d93fa 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
+// 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
 
 namespace StaticAssertFoldTest {
 
@@ -823,6 +823,19 @@
 
 }
 
+struct This {
+  constexpr int f() const { return 0; }
+  static constexpr int g() { return 0; }
+  void h() {
+    constexpr int x = f(); // expected-error {{must be initialized by a constant}}
+    // expected-note@-1 {{implicit use of 'this' pointer is only allowed within the evaluation of a call to a 'constexpr' member function}}
+    constexpr int y = this->f(); // expected-error {{must be initialized by a constant}}
+    // expected-note-re@-1 {{{{^}}use of 'this' pointer}}
+    constexpr int z = g();
+    static_assert(z == 0, "");
+  }
+};
+
 }
 
 namespace Temporaries {
@@ -860,6 +873,12 @@
 constexpr bool b(int n) { return &n; }
 static_assert(b(0), "");
 
+struct NonLiteral {
+  NonLiteral();
+  int f();
+};
+constexpr int k = NonLiteral().f(); // expected-error {{constant expression}} expected-note {{non-literal type 'Temporaries::NonLiteral'}}
+
 }
 
 namespace Union {
@@ -1863,3 +1882,13 @@
   constexpr char d[] = { 'f', 'o', 'o' }; // no nul terminator.
   constexpr int bad = __builtin_strlen(d); // expected-error {{constant expression}} expected-note {{one-past-the-end}}
 }
+
+namespace PR19010 {
+  struct Empty {};
+  struct Empty2 : Empty {};
+  struct Test : Empty2 {
+    constexpr Test() {}
+    Empty2 array[2];
+  };
+  void test() { constexpr Test t; }
+}
diff --git a/test/SemaCXX/constant-expression.cpp b/test/SemaCXX/constant-expression.cpp
index 942bf41..e01acdd 100644
--- a/test/SemaCXX/constant-expression.cpp
+++ b/test/SemaCXX/constant-expression.cpp
@@ -124,3 +124,20 @@
   struct Y { bool b; X x; }; // expected-error {{field has incomplete type 'test3::X'}}
   int f() { return Y().b; }
 }
+
+// PR18283
+namespace test4 {
+  template <int> struct A {};
+  int const i = { 42 };
+  // i can be used as non-type template-parameter as "const int x = { 42 };" is
+  // equivalent to "const int x = 42;" as per C++03 8.5/p13.
+  typedef A<i> Ai; // ok
+}
+
+// rdar://16064952
+namespace rdar16064952 {
+  template < typename T > void fn1() {
+   T b;
+   unsigned w = ({int a = b.val[sizeof(0)]; 0; }); // expected-warning {{use of GNU statement expression extension}}
+  }
+}
diff --git a/test/SemaCXX/constexpr-value-init.cpp b/test/SemaCXX/constexpr-value-init.cpp
index e5b7db5..9ad1129 100644
--- a/test/SemaCXX/constexpr-value-init.cpp
+++ b/test/SemaCXX/constexpr-value-init.cpp
@@ -9,7 +9,7 @@
   A a;
 };
 
-constexpr A a; // ok, zero initialization preceeds static initialization
+constexpr A a; // ok, zero initialization precedes static initialization
 void f() {
   constexpr A a; // expected-error {{constant expression}} expected-note {{in call to 'A()'}}
 }
diff --git a/test/SemaCXX/constructor-initializer.cpp b/test/SemaCXX/constructor-initializer.cpp
index 1757632..81dc19e 100644
--- a/test/SemaCXX/constructor-initializer.cpp
+++ b/test/SemaCXX/constructor-initializer.cpp
@@ -94,7 +94,7 @@
                            Derived::Base1(), // expected-error {{type 'Derived::Base1' is not a direct or virtual base of 'Current'}}
                            Derived::V(),
                            ::NonExisting(), // expected-error {{member initializer 'NonExisting' does not name a non-static data member or}}
-                           INT::NonExisting()  {} // expected-error {{expected a class or namespace}} \
+                           INT::NonExisting()  {} // expected-error {{'INT' (aka 'int') is not a class, namespace, or scoped enumeration}} \
                                                   // expected-error {{member initializer 'NonExisting' does not name a non-static data member or}}
 };
 
@@ -232,15 +232,14 @@
 // <rdar://problem/8308215>: don't crash.
 // Lots of questionable recovery here;  errors can change.
 namespace test3 {
-  class A : public std::exception {}; // expected-error {{undeclared identifier}} expected-error {{expected class name}} expected-note 4 {{candidate}}
+  class A : public std::exception {}; // expected-error {{undeclared identifier}} expected-error {{expected class name}} expected-note 2 {{candidate}}
   class B : public A {
   public:
     B(const String& s, int e=0) // expected-error {{unknown type name}} 
       : A(e), m_String(s) , m_ErrorStr(__null) {} // expected-error {{no matching constructor}} expected-error {{does not name}}
     B(const B& e)
       : A(e), m_String(e.m_String), m_ErrorStr(__null) { // expected-error {{does not name}} \
-      // expected-error {{no member named 'm_String' in 'test3::B'}} \
-      // expected-error {{no matching}}
+      // expected-error {{no member named 'm_String' in 'test3::B'}}
     }
   };
 }
diff --git a/test/SemaCXX/constructor.cpp b/test/SemaCXX/constructor.cpp
index f3b910d..fa930bd 100644
--- a/test/SemaCXX/constructor.cpp
+++ b/test/SemaCXX/constructor.cpp
@@ -17,6 +17,8 @@
   
   int Foo(int, int); // expected-error{{constructor cannot have a return type}} \
   // expected-error{{member 'Foo' has the same name as its class}}
+
+  volatile Foo(float); // expected-error{{constructor cannot have a return type}}
 };
 
 Foo::Foo(const Foo&) { }
diff --git a/test/SemaCXX/conversion-function.cpp b/test/SemaCXX/conversion-function.cpp
index 7eaed54..40ac33b 100644
--- a/test/SemaCXX/conversion-function.cpp
+++ b/test/SemaCXX/conversion-function.cpp
@@ -26,6 +26,9 @@
 public:
   void operator bool(int, ...) const; // expected-error{{conversion function cannot have a return type}} \
   // expected-error{{conversion function cannot have any parameters}}
+
+  operator bool(int a = 4, int b = 6) const; // expected-error{{conversion function cannot have any parameters}}
+  
   
   operator float(...) const;  // expected-error{{conversion function cannot be variadic}}
   
@@ -405,3 +408,14 @@
 
   A f(const C c) { return c; }
 }
+
+namespace PR18234 {
+  struct A {
+    operator enum E { e } (); // expected-error {{'PR18234::A::E' cannot be defined in a type specifier}}
+    operator struct S { int n; } (); // expected-error {{'PR18234::A::S' cannot be defined in a type specifier}}
+  } a;
+  A::S s = a;
+  A::E e = a; // expected-note {{here}}
+  bool k1 = e == A::e; // expected-error {{no member named 'e'}}
+  bool k2 = e.n == 0;
+}
diff --git a/test/SemaCXX/crashes.cpp b/test/SemaCXX/crashes.cpp
index 0b15bb0..1570d12 100644
--- a/test/SemaCXX/crashes.cpp
+++ b/test/SemaCXX/crashes.cpp
@@ -218,3 +218,16 @@
   template class basic_stringbuf<char>;
 }
 
+namespace pr16989 {
+  class C {
+    template <class T>
+    C tpl_mem(T *) { return }    // expected-error{{expected expression}}
+    void mem(int *p) {
+      tpl_mem(p);
+    }
+  };
+  class C2 {
+    void f();
+  };
+  void C2::f() {}
+}
diff --git a/test/SemaCXX/cstyle-cast.cpp b/test/SemaCXX/cstyle-cast.cpp
index 468c8ec..afac6a1 100644
--- a/test/SemaCXX/cstyle-cast.cpp
+++ b/test/SemaCXX/cstyle-cast.cpp
@@ -227,6 +227,6 @@
   void (structure::*psf)() = 0;
   (void)(int (structure::*)())(psf);
 
-  (void)(void (structure::*)())(psi); // expected-error {{C-style cast from 'const int structure::*' to 'void (structure::*)()' is not allowed}}
-  (void)(int structure::*)(psf); // expected-error {{C-style cast from 'void (structure::*)()' to 'int structure::*' is not allowed}}
+  (void)(void (structure::*)())(psi); // expected-error-re {{C-style cast from 'const int structure::*' to 'void (structure::*)(){{( __attribute__\(\(thiscall\)\))?}}' is not allowed}}
+  (void)(int structure::*)(psf); // expected-error-re {{C-style cast from 'void (structure::*)(){{( __attribute__\(\(thiscall\)\))?}}' to 'int structure::*' is not allowed}}
 }
diff --git a/test/SemaCXX/cxx-altivec.cpp b/test/SemaCXX/cxx-altivec.cpp
new file mode 100644
index 0000000..baacbac
--- /dev/null
+++ b/test/SemaCXX/cxx-altivec.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -triple=powerpc-apple-darwin8 -faltivec -fsyntax-only -verify %s
+
+struct Vector {
+	__vector float xyzw;
+} __attribute__((vecreturn)) __attribute__((vecreturn));  // expected-error {{'vecreturn' attribute cannot be repeated}}
diff --git a/test/SemaCXX/cxx0x-compat.cpp b/test/SemaCXX/cxx0x-compat.cpp
index ffbd20f..a58a7f8 100644
--- a/test/SemaCXX/cxx0x-compat.cpp
+++ b/test/SemaCXX/cxx0x-compat.cpp
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -std=c++98 -Wc++11-compat -verify %s
-// RUN: %clang_cc1 -fsyntax-only -std=c++1y -Wc++11-compat -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++1z -Wc++11-compat -verify %s
 
 #if __cplusplus < 201103L
 
@@ -44,5 +44,6 @@
 #else
 
 auto init_capture = [a(0)] {}; // expected-warning {{initialized lambda captures are incompatible with C++ standards before C++1y}}
+static_assert(true); // expected-warning {{incompatible with C++ standards before C++1z}}
 
 #endif
diff --git a/test/SemaCXX/cxx0x-cursory-default-delete.cpp b/test/SemaCXX/cxx0x-cursory-default-delete.cpp
index b1078dc..07a7842 100644
--- a/test/SemaCXX/cxx0x-cursory-default-delete.cpp
+++ b/test/SemaCXX/cxx0x-cursory-default-delete.cpp
@@ -80,3 +80,7 @@
 // (but not normal definitions)
 struct S { S(); };
 S::S() __attribute((pure)) = default;
+
+using size_t = decltype(sizeof(0));
+void *operator new(size_t) = delete; // expected-error {{deleted definition must be first declaration}} expected-note {{implicit}}
+void operator delete(void *) noexcept = delete; // expected-error {{deleted definition must be first declaration}} expected-note {{implicit}}
diff --git a/test/SemaCXX/cxx0x-delegating-ctors.cpp b/test/SemaCXX/cxx0x-delegating-ctors.cpp
index a34ee4f..2e1abf5 100644
--- a/test/SemaCXX/cxx0x-delegating-ctors.cpp
+++ b/test/SemaCXX/cxx0x-delegating-ctors.cpp
@@ -43,7 +43,7 @@
 }
 
 struct deleted_dtor {
-  ~deleted_dtor() = delete; // expected-note{{function has been explicitly marked deleted here}}
+  ~deleted_dtor() = delete; // expected-note{{'~deleted_dtor' has been explicitly marked deleted here}}
   deleted_dtor();
   deleted_dtor(int) : deleted_dtor() // expected-error{{attempt to use a deleted function}}
   {}
diff --git a/test/SemaCXX/cxx0x-deleted-default-ctor.cpp b/test/SemaCXX/cxx0x-deleted-default-ctor.cpp
index 0cebc10..b9af679 100644
--- a/test/SemaCXX/cxx0x-deleted-default-ctor.cpp
+++ b/test/SemaCXX/cxx0x-deleted-default-ctor.cpp
@@ -59,7 +59,7 @@
 good_const gc;
 
 struct no_default {
-  no_default() = delete; // expected-note 3{{deleted here}}
+  no_default() = delete; // expected-note 4{{deleted here}}
 };
 struct no_dtor {
   ~no_dtor() = delete; // expected-note 2{{deleted here}}
@@ -114,7 +114,7 @@
 defaulted_delete dd; // expected-error {{call to implicitly-deleted default constructor}}
 
 struct late_delete {
-  no_default nd;
+  no_default nd; // expected-note {{because field 'nd' has a deleted default constructor}}
   late_delete();
 };
 late_delete::late_delete() = default; // expected-error {{would delete it}}
diff --git a/test/SemaCXX/cxx0x-initializer-constructor.cpp b/test/SemaCXX/cxx0x-initializer-constructor.cpp
index dc179f8..3ea5309 100644
--- a/test/SemaCXX/cxx0x-initializer-constructor.cpp
+++ b/test/SemaCXX/cxx0x-initializer-constructor.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -fexceptions -verify %s
 
 struct one { char c[1]; };
 struct two { char c[2]; };
@@ -75,8 +75,8 @@
     { F<0> f = {}; }
     // Narrowing conversions don't affect viability. The next two choose
     // the initializer_list constructor.
-    { F<3> f{1, 1.0}; } // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}}
-    { F<3> f = {1, 1.0}; } // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}}
+    { F<3> f{1, 1.0}; } // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{silence}}
+    { F<3> f = {1, 1.0}; } // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{silence}}
     { F<3> f{1, 2, 3, 4, 5, 6, 7, 8}; }
     { F<3> f = {1, 2, 3, 4, 5, 6, 7, 8}; }
     { F<3> f{1, 2, 3, 4, 5, 6, 7, 8}; }
@@ -304,7 +304,6 @@
   B b {}; // calls default constructor
 }
 
-
 // PR13470, <rdar://problem/11974632>
 namespace PR13470 {
   struct W {
@@ -365,3 +364,42 @@
     yi.h(); // ok, all diagnostics produced in template definition
   }
 }
+
+namespace PR19729 {
+  struct A {
+    A(int);
+    A(const A&) = delete;
+  };
+  struct B {
+    void *operator new(std::size_t, A);
+  };
+  B *p = new ({123}) B;
+}
+
+namespace PR11410 {
+  struct A {
+    A() = delete; // expected-note 2{{deleted here}}
+    A(int);
+  };
+
+  A a[3] = {
+    {1}, {2}
+  }; // expected-error {{call to deleted constructor}} \
+        expected-note {{in implicit initialization of array element 2 with omitted initializer}}
+
+  struct B {
+    A a; // expected-note {{in implicit initialization of field 'a'}}
+  } b = {
+  }; // expected-error {{call to deleted constructor}}
+
+  struct C {
+    C(int = 0); // expected-note 2{{candidate}}
+    C(float = 0); // expected-note 2{{candidate}}
+  };
+  C c[3] = {
+    0, 1
+  }; // expected-error {{ambiguous}} expected-note {{in implicit initialization of array element 2}}
+  C c2[3] = {
+    [0] = 1, [2] = 3
+  }; // expected-error {{ambiguous}} expected-note {{in implicit initialization of array element 1}}
+}
diff --git a/test/SemaCXX/cxx0x-initializer-scalars.cpp b/test/SemaCXX/cxx0x-initializer-scalars.cpp
index 627855e..1475dcf 100644
--- a/test/SemaCXX/cxx0x-initializer-scalars.cpp
+++ b/test/SemaCXX/cxx0x-initializer-scalars.cpp
@@ -45,8 +45,8 @@
     { const int a{1, 2}; } // expected-error {{excess elements}}
     { const int a = {1, 2}; } // expected-error {{excess elements}}
     // FIXME: Redundant warnings.
-    { const short a{100000}; } // expected-error {{cannot be narrowed}} expected-note {{inserting an explicit cast}} expected-warning {{changes value}}
-    { const short a = {100000}; } // expected-error {{cannot be narrowed}} expected-note {{inserting an explicit cast}} expected-warning {{changes value}}
+    { const short a{100000}; } // expected-error {{cannot be narrowed}} expected-note {{insert an explicit cast}} expected-warning {{changes value}}
+    { const short a = {100000}; } // expected-error {{cannot be narrowed}} expected-note {{insert an explicit cast}} expected-warning {{changes value}}
     { if (const int a{1}) static_assert(a == 1, ""); }
     { if (const int a = {1}) static_assert(a == 1, ""); }
   }
diff --git a/test/SemaCXX/cxx0x-initializer-stdinitializerlist-system-header.cpp b/test/SemaCXX/cxx0x-initializer-stdinitializerlist-system-header.cpp
new file mode 100644
index 0000000..7747457
--- /dev/null
+++ b/test/SemaCXX/cxx0x-initializer-stdinitializerlist-system-header.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -Wsystem-headers %s
+
+// libstdc++4.6 in debug mode has explicit default constructors.
+// stlport has this for all containers.
+#ifdef BE_THE_HEADER
+#pragma clang system_header
+namespace std {
+namespace __debug {
+template <class T>
+class vector {
+public:
+  explicit vector() {} // expected-warning{{should not be explicit}}
+};
+}
+}
+#else
+
+#define BE_THE_HEADER
+#include __FILE__
+
+struct { int a, b; std::__debug::vector<int> c; } e[] = { {1, 1} }; // expected-note{{used in initialization here}}
+
+#endif
diff --git a/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp b/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
index d4098a4..70f7c64 100644
--- a/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
+++ b/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
@@ -225,3 +225,37 @@
   void f(std::initializer_list<S>);
   void g(S s) { f({S()}); }
 }
+
+namespace PR18013 {
+  int f();
+  std::initializer_list<long (*)()> x = {f}; // expected-error {{cannot initialize an array element of type 'long (*const)()' with an lvalue of type 'int ()': different return type ('long' vs 'int')}}
+}
+
+namespace DR1070 {
+  struct S {
+    S(std::initializer_list<int>);
+  };
+  S s[3] = { {1, 2, 3}, {4, 5} }; // ok
+  S *p = new S[3] { {1, 2, 3}, {4, 5} }; // ok
+}
+
+namespace ListInitInstantiate {
+  struct A {
+    A(std::initializer_list<A>);
+    A(std::initializer_list<int>);
+  };
+  struct B : A {
+    B(int);
+  };
+  template<typename T> struct X {
+    X();
+    A a;
+  };
+  template<typename T> X<T>::X() : a{B{0}, B{1}} {}
+
+  X<int> x;
+
+  int f(const A&);
+  template<typename T> void g() { int k = f({0}); }
+  template void g<int>();
+}
diff --git a/test/SemaCXX/cxx0x-type-convert-construct.cpp b/test/SemaCXX/cxx0x-type-convert-construct.cpp
index 6a7fe45..25a43d7 100644
--- a/test/SemaCXX/cxx0x-type-convert-construct.cpp
+++ b/test/SemaCXX/cxx0x-type-convert-construct.cpp
@@ -9,9 +9,9 @@
   Ustr = U"a UTF-32 string"; // expected-error {{assigning to 'char32_t *' from incompatible type 'const char32_t [16]'}}
 
   char *Rstr;
-  Rstr = R"foo(a raw string)foo"; // expected-warning{{conversion from string literal to 'char *' is deprecated}}
+  Rstr = R"foo(a raw string)foo"; // expected-warning{{ISO C++11 does not allow conversion from string literal to 'char *'}}
   wchar_t *LRstr;
-  LRstr = LR"foo(a wide raw string)foo"; // expected-warning{{conversion from string literal to 'wchar_t *' is deprecated}}
+  LRstr = LR"foo(a wide raw string)foo"; // expected-warning{{ISO C++11 does not allow conversion from string literal to 'wchar_t *'}}
   char *u8Rstr;
   u8Rstr = u8R"foo(a UTF-8 raw string)foo"; // expected-error {{assigning to 'char *' from incompatible type 'const char [19]'}}
   char16_t *uRstr;
diff --git a/test/SemaCXX/cxx11-attr-print.cpp b/test/SemaCXX/cxx11-attr-print.cpp
index 01325d3..999eaed 100644
--- a/test/SemaCXX/cxx11-attr-print.cpp
+++ b/test/SemaCXX/cxx11-attr-print.cpp
@@ -42,9 +42,6 @@
 // CHECK: {{\[}}[noreturn]];
 void f4 [[noreturn]] ();
 
-// CHECK: {{\[}}[std::noreturn]];
-void f5 [[std::noreturn]] ();
-
 // CHECK: __attribute__((gnu_inline));
 inline void f6() __attribute__((gnu_inline));
 
diff --git a/test/SemaCXX/cxx11-gnu-attrs.cpp b/test/SemaCXX/cxx11-gnu-attrs.cpp
index 22d61a1..9f18224 100644
--- a/test/SemaCXX/cxx11-gnu-attrs.cpp
+++ b/test/SemaCXX/cxx11-gnu-attrs.cpp
@@ -19,8 +19,6 @@
 void aligned_fn [[gnu::aligned(32)]] ();
 struct [[gnu::aligned(8)]] aligned_struct {};
 
-[[gnu::malloc, gnu::alloc_size(1,2)]] void *alloc_size(int a, int b);
-
 void always_inline [[gnu::always_inline]] ();
 
 __thread int tls_model [[gnu::tls_model("local-exec")]];
diff --git a/test/SemaCXX/cxx11-inheriting-ctors.cpp b/test/SemaCXX/cxx11-inheriting-ctors.cpp
index 67d5521..04aa117 100644
--- a/test/SemaCXX/cxx11-inheriting-ctors.cpp
+++ b/test/SemaCXX/cxx11-inheriting-ctors.cpp
@@ -26,3 +26,11 @@
     return 0;
   }
 }
+
+namespace WrongIdent {
+  struct A {};
+  struct B : A {};
+  struct C : B {
+    using B::A;
+  };
+}
diff --git a/test/SemaCXX/cxx11-unused.cpp b/test/SemaCXX/cxx11-unused.cpp
new file mode 100644
index 0000000..1e25bd5
--- /dev/null
+++ b/test/SemaCXX/cxx11-unused.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s -Wunused-parameter
+
+// PR19303 : Make sure we don't get a unused expression warning for deleted and
+// defaulted functions
+
+// expected-no-diagnostics
+
+class A {
+public:
+  int x;
+  A() = default;
+  ~A() = default;
+  A(const A &other) = delete;
+
+  template <typename T>
+  void SetX(T x) {
+    this->x = x;
+  };
+
+  void SetX1(int x);
+};
+
+template <>
+void A::SetX(A x) = delete;
+
+class B {
+public:
+  B() = default;
+  ~B() = default;
+  B(const B &other);
+};
+
+B::B(const B &other) = default;
diff --git a/test/SemaCXX/cxx11-user-defined-literals.cpp b/test/SemaCXX/cxx11-user-defined-literals.cpp
index f8bbcd9..cb77964 100644
--- a/test/SemaCXX/cxx11-user-defined-literals.cpp
+++ b/test/SemaCXX/cxx11-user-defined-literals.cpp
@@ -141,3 +141,27 @@
   int operator"" _b(); // expected-error {{no function template matches function template specialization}}
   int main() { return 0_b; } // expected-error {{no matching literal operator for call to 'operator "" _b'}}
 }
+
+namespace bad_names {
+  template<char...> int operator""_x();
+
+  template<typename T> void f() {
+    class T:: // expected-error {{anonymous class}} expected-warning {{does not declare anything}}
+        operator // expected-error {{expected identifier}}
+            ""_q<'a'>;
+
+    T::template operator""_q<'a'>(); // expected-error {{non-namespace scope 'T::' cannot have a literal operator member}} expected-error +{{}}
+    T::template operator""_q<'a'>::X; // expected-error {{non-namespace scope 'T::' cannot have a literal operator member}} expected-error +{{}}
+    T::operator""_q<'a'>(); // expected-error {{non-namespace scope 'T::' cannot have a literal operator member}} expected-error +{{}}
+    typename T::template operator""_q<'a'> a; // expected-error {{non-namespace scope 'T::' cannot have a literal operator member}} expected-error +{{}}
+    typename T::operator""_q(""); // expected-error +{{}} expected-note {{to match}}
+    T::operator""_q(""); // expected-error {{non-namespace scope 'T::' cannot have a literal operator member}}
+
+    bad_names::operator""_x<'a', 'b', 'c'>();
+  };
+
+  struct S {};
+  void g() {
+    S::operator""_q(); // expected-error {{non-namespace scope 'S::' cannot have a literal operator member}}
+  }
+}
diff --git a/test/SemaCXX/cxx1y-deduced-return-type.cpp b/test/SemaCXX/cxx1y-deduced-return-type.cpp
index d3308b3..6086416 100644
--- a/test/SemaCXX/cxx1y-deduced-return-type.cpp
+++ b/test/SemaCXX/cxx1y-deduced-return-type.cpp
@@ -261,6 +261,13 @@
 
 namespace Constexpr {
   constexpr auto f1(int n) { return n; }
+  template<typename T> struct X { constexpr auto f() {} }; // PR18746
+  template<typename T> struct Y { constexpr T f() {} }; // expected-note {{control reached end of constexpr function}}
+  void f() {
+    X<int>().f();
+    Y<void>().f();
+    constexpr int q = Y<int>().f(); // expected-error {{must be initialized by a constant expression}} expected-note {{in call to '&Y<int>()->f()'}}
+  }
   struct NonLiteral { ~NonLiteral(); } nl; // expected-note {{user-provided destructor}}
   constexpr auto f2(int n) { return nl; } // expected-error {{return type 'Constexpr::NonLiteral' is not a literal type}}
 }
diff --git a/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp b/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp
index 8bd4f42..b08d58a 100644
--- a/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp
+++ b/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp
@@ -1358,6 +1358,21 @@
 int run_char = X<int>{}.foo('a');
 int run_int = X<double>{}.foo(4);
 }
-
 #endif // MS_EXTENSIONS
 
+namespace nsdmi_capturing_this {
+struct X {
+  int m = 10;
+  int n = [this](auto) { return m; }(20);
+};
+
+template<class T>
+struct XT {
+  T m = 10;
+  T n = [this](auto) { return m; }(20);
+};
+
+XT<int> xt{};
+
+
+}
diff --git a/test/SemaCXX/cxx1y-generic-lambdas-variadics.cpp b/test/SemaCXX/cxx1y-generic-lambdas-variadics.cpp
new file mode 100644
index 0000000..b0b86e3
--- /dev/null
+++ b/test/SemaCXX/cxx1y-generic-lambdas-variadics.cpp
@@ -0,0 +1,100 @@
+// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks %s
+// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s -DDELAYED_TEMPLATE_PARSING
+// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fms-extensions %s -DMS_EXTENSIONS
+// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fdelayed-template-parsing -fms-extensions %s -DMS_EXTENSIONS -DDELAYED_TEMPLATE_PARSING
+
+namespace explicit_argument_variadics {
+
+
+template<class ... Ts> void print(Ts ... ) { }
+
+struct X { };
+struct Y { };
+struct Z { };
+
+int test() { 
+  {
+    auto L = [](auto ... as) { };
+    L.operator()<bool>(true);
+  }
+  {
+    auto L = [](auto a) { };
+    L.operator()<bool>(false);
+  }
+  {
+    auto L = [](auto a, auto b) { };
+    L.operator()<bool>(false, 'a');
+  }
+  {
+    auto L = [](auto a, auto b) { };
+    L.operator()<bool, char>(false, 'a');
+  }
+  {
+    auto L = [](auto a, auto b, auto ... cs) { };
+    L.operator()<bool, char>(false, 'a');
+    L.operator()<bool, char, const char*>(false, 'a', "jim");    
+  }
+
+  {
+    auto L = [](auto ... As) {
+    };
+    L.operator()<bool, double>(false, 3.14, "abc");
+  }
+  {
+    auto L = [](auto A, auto B, auto ... As) {
+    };
+    L.operator()<bool>(false, 3.14, "abc");
+    L.operator()<bool, char>(false, 3.14, "abc"); //expected-warning{{implicit conversion}}
+    L.operator()<X, Y, bool, Z>(X{}, Y{}, 3.14, Z{}, X{}); //expected-warning{{implicit conversion}}
+  }
+  {
+    auto L = [](auto ... As) {
+      print("\nL::As = ", As ...);
+      return [](decltype(As) ... as, auto ... Bs) {
+        print("\nL::Inner::as = ", as ...);
+        print("\nL::Inner::Bs = ", Bs ...);
+        return 4;
+      };
+    };
+    auto M = L.operator()<bool, double>(false, 3.14, "abc");
+    M(false, 6.26, "jim", true);
+    M.operator()<bool>(true, 6.26, "jim", false, 3.14);
+  }
+  {
+    auto L = [](auto A, auto ... As) {
+      print("\nL::As = ", As ...);
+      return [](decltype(As) ... as, decltype(A) a, auto ... Bs) {
+        print("\nL::Inner::as = ", as ...);
+        print("\nL::Inner::Bs = ", Bs ...);
+        return 4;
+      };
+    };
+    auto M = L.operator()<bool, double>(false, 3.14, "abc");
+    M(6.26, "jim", true);
+    M.operator()<X>(6.26, "jim", false, X{}, Y{}, Z{});
+  }
+  
+  return 0;
+}
+ int run = test();
+} // end ns explicit_argument_extension
+
+
+
+#ifdef PR18499_FIXED
+namespace variadic_expansion {
+  void f(int &, char &);
+
+  template <typename ... T> void g(T &... t) {
+    f([&a(t)]()->decltype(auto) {
+      return a;
+    }() ...);
+    f([&a(f([&b(t)]()->decltype(auto) { return b; }()...), t)]()->decltype(auto) {
+      return a;
+    }()...);
+  }
+
+  void h(int i, char c) { g(i, c); }
+}
+#endif
+
diff --git a/test/SemaCXX/cxx1y-generic-lambdas.cpp b/test/SemaCXX/cxx1y-generic-lambdas.cpp
index a8518a3..dc85748 100644
--- a/test/SemaCXX/cxx1y-generic-lambdas.cpp
+++ b/test/SemaCXX/cxx1y-generic-lambdas.cpp
@@ -3,6 +3,17 @@
 // RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fms-extensions %s -DMS_EXTENSIONS
 // RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fdelayed-template-parsing -fms-extensions %s -DMS_EXTENSIONS -DDELAYED_TEMPLATE_PARSING
 
+template<class F, class ...Rest> struct first_impl { typedef F type; };
+template<class ...Args> using first = typename first_impl<Args...>::type;
+
+namespace simple_explicit_capture {
+  void test() {
+    int i;
+    auto L = [i](auto a) { return i + a; };
+    L(3.14);
+  }
+}
+
 namespace explicit_call {
 int test() {
   auto L = [](auto a) { return a; };
@@ -489,8 +500,6 @@
 
 template<class ... Ts> void print(Ts ... ts) { }
 
-template<class F, class ... Rest> using first = F;
-
 template<class ... Ts> auto fooV(Ts ... ts) {
   auto L = [](auto ... a) { 
     auto M = [](decltype(a) ... b) {  
@@ -560,7 +569,6 @@
 namespace variadic_tests_1 {
 template<class ... Ts> void print(Ts ... ts) { }
 
-template<class F, class ... Rest> using FirstType = F;
 template<class F, class ... Rest> F& FirstArg(F& f, Rest...) { return f; }
  
 template<class ... Ts> int fooV(Ts ... ts) {
@@ -574,7 +582,7 @@
       };  
       N('a');
       N(N);
-      N(FirstType<Ts...>{});
+      N(first<Ts...>{});
     };
     M(a...);
     print("a = ", a..., "\n");    
@@ -599,7 +607,7 @@
       };  
       N('a');
       N(N);
-      N(FirstType<Ts...>{});
+      N(first<Ts...>{});
     };
     M(a...);
     return M;
@@ -619,7 +627,7 @@
         };  
         N('a');
         N(N);
-        N(FirstType<Ts...>{});
+        N(first<Ts...>{});
         return N;
       };
       M(a...);
@@ -763,7 +771,6 @@
 
 
 namespace fptr_with_decltype_return_type {
-template<class F, class ... Ts> using FirstType = F;
 template<class F, class ... Rest> F& FirstArg(F& f, Rest& ... r) { return f; };
 template<class ... Ts> auto vfun(Ts&& ... ts) {
   print(ts...);
@@ -774,7 +781,7 @@
  {
    auto L = [](auto ... As) {
     return [](auto b) ->decltype(b) {   
-      vfun([](decltype(As) a) -> decltype(a) { return a; } ...)(FirstType<decltype(As)...>{});
+      vfun([](decltype(As) a) -> decltype(a) { return a; } ...)(first<decltype(As)...>{});
       return decltype(b){};
     };
    };
@@ -844,5 +851,65 @@
   [=] { v.size(); };
 }
 
+}
 
-}
\ No newline at end of file
+namespace inclass_lambdas_within_nested_classes {
+namespace ns1 {
+
+struct X1 {  
+  struct X2 {
+    enum { E = [](auto i) { return i; }(3) }; //expected-error{{inside of a constant expression}}\
+                                          //expected-error{{not an integral constant}}
+    int L = ([] (int i) { return i; })(2);
+    void foo(int i = ([] (int i) { return i; })(2)) { }
+    int B : ([](int i) { return i; })(3); //expected-error{{inside of a constant expression}}\
+                                          //expected-error{{not an integral constant}}
+    int arr[([](int i) { return i; })(3)]; //expected-error{{inside of a constant expression}}\
+                                           //expected-error{{must have a constant size}}
+    int (*fp)(int) = [](int i) { return i; };
+    void fooptr(int (*fp)(char) = [](char c) { return 0; }) { }
+    int L2 = ([](auto i) { return i; })(2);
+    void fooG(int i = ([] (auto i) { return i; })(2)) { }
+    int BG : ([](auto i) { return i; })(3); //expected-error{{inside of a constant expression}}  \
+                                             //expected-error{{not an integral constant}}
+    int arrG[([](auto i) { return i; })(3)]; //expected-error{{inside of a constant expression}}\
+                                           //expected-error{{must have a constant size}}
+    int (*fpG)(int) = [](auto i) { return i; };
+    void fooptrG(int (*fp)(char) = [](auto c) { return 0; }) { }
+  };
+};
+} //end ns
+
+namespace ns2 {
+struct X1 {  
+  template<class T>
+  struct X2 {
+    int L = ([] (T i) { return i; })(2);
+    void foo(int i = ([] (int i) { return i; })(2)) { }
+    int B : ([](T i) { return i; })(3); //expected-error{{inside of a constant expression}}\
+                                          //expected-error{{not an integral constant}}
+    int arr[([](T i) { return i; })(3)]; //expected-error{{inside of a constant expression}}\
+                                           //expected-error{{must have a constant size}}
+    int (*fp)(T) = [](T i) { return i; };
+    void fooptr(T (*fp)(char) = [](char c) { return 0; }) { }
+    int L2 = ([](auto i) { return i; })(2);
+    void fooG(T i = ([] (auto i) { return i; })(2)) { }
+    int BG : ([](auto i) { return i; })(3); //expected-error{{not an integral constant}}
+    int arrG[([](auto i) { return i; })(3)]; //expected-error{{must have a constant size}}
+    int (*fpG)(T) = [](auto i) { return i; };
+    void fooptrG(T (*fp)(char) = [](auto c) { return 0; }) { }
+    template<class U = char> int fooG2(T (*fp)(U) = [](auto a) { return 0; }) { return 0; }
+    template<class U = char> int fooG3(T (*fp)(U) = [](auto a) { return 0; });
+  };
+};
+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}}
+int run1 = x2.fooG2();
+int run2 = x2.fooG3();
+} // end ns
+
+
+
+} //end ns inclass_lambdas_within_nested_classes
diff --git a/test/SemaCXX/cxx1y-init-captures.cpp b/test/SemaCXX/cxx1y-init-captures.cpp
index d737a4a..64fe50a 100644
--- a/test/SemaCXX/cxx1y-init-captures.cpp
+++ b/test/SemaCXX/cxx1y-init-captures.cpp
@@ -1,14 +1,169 @@
-// RUN: %clang_cc1 -std=c++1y %s -verify
+// RUN: %clang_cc1 -std=c++1y %s -verify -emit-llvm-only
 
-// expected-no-diagnostics
 namespace variadic_expansion {
-  void f(int &, char &);
-
-  template <typename ... T> void g(T &... t) {
+  int f(int &, char &) { return 0; }
+  template<class ... Ts> char fv(Ts ... ts) { return 0; }
+  // FIXME: why do we get 2 error messages
+  template <typename ... T> void g(T &... t) { //expected-note3{{declared here}}
     f([&a(t)]()->decltype(auto) {
       return a;
     }() ...);
+    
+    auto L = [x = f([&a(t)]()->decltype(auto) { return a; }()...)]() { return x; };
+    const int y = 10;
+    auto M = [x = y, 
+                &z = y](T& ... t) { }; 
+    auto N = [x = y, 
+                &z = y, n = f(t...), 
+                o = f([&a(t)](T& ... t)->decltype(auto) { return a; }(t...)...), t...](T& ... s) { 
+                  fv([&a(t)]()->decltype(auto) { 
+                    return a;
+                  }() ...);
+                };                 
+    auto N2 = [x = y,                     //expected-note3{{begins here}}
+                &z = y, n = f(t...), 
+                o = f([&a(t)](T& ... t)->decltype(auto) { return a; }(t...)...)](T& ... s) { 
+                  fv([&a(t)]()->decltype(auto) { //expected-error 3{{captured}}
+                    return a;
+                  }() ...);
+                };                 
+
   }
 
-  void h(int i, char c) { g(i, c); }
+  void h(int i, char c) { g(i, c); } //expected-note{{in instantiation}}
 }
+
+namespace odr_use_within_init_capture {
+
+int test() {
+  
+  { // no captures
+    const int x = 10;
+    auto L = [z = x + 2](int a) {
+      auto M = [y = x - 2](char b) {
+        return y;
+      };
+      return M;
+    };
+        
+  }
+  { // should not capture
+    const int x = 10;
+    auto L = [&z = x](int a) {
+      return a;;
+    };
+        
+  }
+  {
+    const int x = 10;
+    auto L = [k = x](char a) { //expected-note {{declared}}
+      return [](int b) { //expected-note {{begins}}
+        return [j = k](int c) { //expected-error {{cannot be implicitly captured}}
+          return c;
+        };
+      };
+    };
+  }
+  {
+    const int x = 10;
+    auto L = [k = x](char a) { 
+      return [=](int b) { 
+        return [j = k](int c) { 
+          return c;
+        };
+      };
+    };
+  }
+  {
+    const int x = 10;
+    auto L = [k = x](char a) { 
+      return [k](int b) { 
+        return [j = k](int c) { 
+          return c;
+        };
+      };
+    };
+  }
+
+  return 0;
+}
+
+int run = test();
+
+}
+
+namespace odr_use_within_init_capture_template {
+
+template<class T = int>
+int test(T t = T{}) {
+
+  { // no captures
+    const T x = 10;
+    auto L = [z = x](char a) {
+      auto M = [y = x](T b) {
+        return y;
+      };
+      return M;
+    };
+        
+  }
+  { // should not capture
+    const T x = 10;
+    auto L = [&z = x](T a) {
+      return a;;
+    };
+        
+  }
+  { // will need to capture x in outer lambda
+    const T x = 10; //expected-note {{declared}}
+    auto L = [z = x](char a) { //expected-note {{begins}}
+      auto M = [&y = x](T b) { //expected-error {{cannot be implicitly captured}}
+        return y;
+      };
+      return M;
+    };
+        
+  }
+  { // will need to capture x in outer lambda
+    const T x = 10; 
+    auto L = [=,z = x](char a) { 
+      auto M = [&y = x](T b) { 
+        return y;
+      };
+      return M;
+    };
+        
+  }
+  { // will need to capture x in outer lambda
+    const T x = 10; 
+    auto L = [x, z = x](char a) { 
+      auto M = [&y = x](T b) { 
+        return y;
+      };
+      return M;
+    };
+  }
+  { // will need to capture x in outer lambda
+    const int x = 10; //expected-note 2{{declared}}
+    auto L = [z = x](char a) { //expected-note 2{{begins}}
+      auto M = [&y = x](T b) { //expected-error 2{{cannot be implicitly captured}}
+        return y;
+      };
+      return M;
+    };     
+  }
+  {
+    // no captures
+    const T x = 10;
+    auto L = [z = 
+                  [z = x, &y = x](char a) { return z + y; }('a')](char a) 
+      { return z; };
+  
+  }
+  
+  return 0;
+}
+
+int run = test(); //expected-note {{instantiation}}
+
+}
\ No newline at end of file
diff --git a/test/SemaCXX/cxx1y-variable-templates_in_class.cpp b/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
index 94d0f16..1e5e834 100644
--- a/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
+++ b/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
@@ -39,11 +39,11 @@
   template<typename T> CONST T B1::right<T,int> = T(5);
 
   class B2 {
-    template<typename T, typename T0> static CONST T right = T(100);  // expected-note {{previous definition is here}}
-    template<typename T> static CONST T right<T,int> = T(5);          // expected-note {{previous definition is here}}
+    template<typename T, typename T0> static CONST T right = T(100);  // expected-note {{previous initialization is here}}
+    template<typename T> static CONST T right<T,int> = T(5);          // expected-note {{previous initialization is here}}
   };
-  template<typename T, typename T0> CONST T B2::right = T(100);   // expected-error {{redefinition of 'right'}}
-  template<typename T> CONST T B2::right<T,int> = T(5);           // expected-error {{redefinition of 'right'}}
+  template<typename T, typename T0> CONST T B2::right = T(100);   // expected-error {{static data member 'right' already has an initializer}}
+  template<typename T> CONST T B2::right<T,int> = T(5);           // expected-error {{static data member 'right' already has an initializer}}
 
   class B3 {
     template<typename T, typename T0> static CONST T right = T(100);
@@ -291,6 +291,30 @@
     template<typename T> template<typename...U> T A<T>::y<tuple<U...> >[] = { U()... };
     static_assert(sizeof(A<int>::y<tuple<char, char, char> >) == 12, "");
   }
+
+  namespace bad_reference {
+    struct S {
+      template<typename T> static int A; // expected-note 4{{here}}
+    };
+
+    template<typename T> void f() {
+      typename T::template A<int> a; // expected-error {{template name refers to non-type template 'S::A'}}
+    }
+    template<typename T> void g() {
+      T::template A<int>::B = 0; // expected-error {{template name refers to non-type template 'S::A'}}
+    }
+    template<typename T> void h() {
+      class T::template A<int> c; // expected-error {{template name refers to non-type template 'S::A'}}
+    }
+
+    template<typename T>
+    struct X : T::template A<int> {}; // expected-error {{template name refers to non-type template 'S::A'}}
+
+    template void f<S>(); // expected-note {{in instantiation of}}
+    template void g<S>(); // expected-note {{in instantiation of}}
+    template void h<S>(); // expected-note {{in instantiation of}}
+    template struct X<S>; // expected-note {{in instantiation of}}
+  }
 }
 
 namespace in_nested_classes {
diff --git a/test/SemaCXX/cxx1y-variable-templates_top_level.cpp b/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
index b6e8762..4e62941 100644
--- a/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
+++ b/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
@@ -81,7 +81,7 @@
     template<typename T> T v; // expected-note {{previous definition is here}}
     template<typename T> int v; // expected-error {{redefinition of 'v'}}
     
-    template<typename T> int v1; // expected-note {{previous template declaration is here}}
+    template<typename T> extern int v1; // expected-note {{previous template declaration is here}}
     template<int I> int v1;      // expected-error {{template parameter has a different kind in template redeclaration}}
   }
   namespace pvt_use {
@@ -90,11 +90,8 @@
   }
 
   namespace pvt_diff_params {
-    // FIXME: (?) Redefinitions should simply be not allowed, whether the
-    // template parameters match or not. However, this current behaviour also
-    // matches that of class templates...
-    template<typename T, typename> T v;   // expected-note 2{{previous template declaration is here}}
-    template<typename T> T v;   // expected-error {{too few template parameters in template redeclaration}}
+    template<typename T, typename> T v;   // expected-note {{previous template declaration is here}}
+    template<typename T> T v;   // expected-error {{too few template parameters in template redeclaration}} expected-note {{previous template declaration is here}}
     template<typename T, typename, typename> T v; // expected-error {{too many template parameters in template redeclaration}}
   }
 
@@ -327,7 +324,7 @@
   template<typename T> T v = {1234};  // expected-warning {{implicit conversion from 'int' to 'char' changes value from 1234 to}}
 #ifndef PRECXX11
   // expected-error@-2 {{constant expression evaluates to 1234 which cannot be narrowed to type 'char'}}\
-  // expected-note@-2 {{override this message by inserting an explicit cast}}
+  // expected-note@-2 {{insert an explicit cast to silence this issue}}
 #endif
   int k = v<char>;        // expected-note {{in instantiation of variable template specialization 'narrowing::v<char>' requested here}}
 }
@@ -391,7 +388,7 @@
   
   namespace n1 {
     template<typename T> 
-    T pi1a = T(3.1415926535897932385);
+    T pi1a = T(3.1415926535897932385); // expected-note {{explicitly specialized declaration is here}}
 #ifndef PRECXX11
 // expected-note@-2 {{explicit instantiation refers here}}
 #endif
@@ -413,7 +410,7 @@
 #endif
     float f1 = pi1a<float>;
     
-    template<> double pi1a<double> = 5.2;  // expected-error {{no variable template matches specialization}}
+    template<> double pi1a<double> = 5.2;  // expected-error {{variable template specialization of 'pi1a' must originally be declared in namespace 'n1'}}
     double d1 = pi1a<double>;
   }
   
@@ -432,3 +429,32 @@
   }
 }
 
+namespace nested_name {
+  template<typename T> int a; // expected-note {{variable template 'a' declared here}}
+  a<int>::b c; // expected-error {{qualified name refers into a specialization of variable template 'a'}}
+
+  class a<int> {}; // expected-error {{identifier followed by '<' indicates a class template specialization but 'a' refers to a variable template}}
+  enum a<int> {}; // expected-error {{expected identifier or '{'}} expected-warning {{does not declare anything}}
+}
+
+namespace PR18530 {
+  template<typename T> int a;
+  int a<int>; // expected-error {{requires 'template<>'}}
+}
+
+namespace PR19152 {
+#ifndef PRECXX11
+  template<typename T> const auto x = 1;
+  static_assert(x<int> == 1, "");
+#endif
+}
+
+namespace PR19169 {
+  template <typename T> int* f();
+  template <typename T> void f();
+  template<> int f<double>; // expected-error {{no variable template matches specialization; did you mean to use 'f' as function template instead?}}
+  
+  template <typename T> void g();
+  template<> int g<double>; // expected-error {{no variable template matches specialization; did you mean to use 'g' as function template instead?}}
+}
+
diff --git a/test/SemaCXX/cxx98-compat.cpp b/test/SemaCXX/cxx98-compat.cpp
index 9690638..96af954 100644
--- a/test/SemaCXX/cxx98-compat.cpp
+++ b/test/SemaCXX/cxx98-compat.cpp
@@ -23,7 +23,7 @@
 class Variadic3 {};
 
 alignas(8) int with_alignas; // expected-warning {{'alignas' is incompatible with C++98}}
-int with_attribute [[ ]]; // expected-warning {{attributes are incompatible with C++98}}
+int with_attribute [[ ]]; // expected-warning {{C++11 attribute syntax is incompatible with C++98}}
 
 void Literals() {
   (void)u8"str"; // expected-warning {{unicode literals are incompatible with C++98}}
@@ -219,18 +219,11 @@
 class PrivateMember {
   struct ImPrivate {};
 };
-template<typename T> typename T::ImPrivate SFINAEAccessControl(T t) { // expected-warning {{substitution failure due to access control is incompatible with C++98}} expected-note {{while substituting deduced template arguments into function template 'SFINAEAccessControl' [with T = PrivateMember]}}
+template<typename T> typename T::ImPrivate SFINAEAccessControl(T t) { // expected-warning {{substitution failure due to access control is incompatible with C++98}}
   return typename T::ImPrivate();
 }
 int SFINAEAccessControl(...) { return 0; }
-int CheckSFINAEAccessControl = SFINAEAccessControl(PrivateMember());
-
-template<typename T>
-struct FriendRedefinition {
-  friend void Friend() {} // expected-warning {{friend function 'Friend' would be implicitly redefined in C++98}} expected-note {{previous}}
-};
-FriendRedefinition<int> FriendRedef1;
-FriendRedefinition<char> FriendRedef2; // expected-note {{requested here}}
+int CheckSFINAEAccessControl = SFINAEAccessControl(PrivateMember()); // expected-note {{while substituting deduced template arguments into function template 'SFINAEAccessControl' [with T = PrivateMember]}}
 
 namespace CopyCtorIssues {
   struct Private {
@@ -386,38 +379,22 @@
 // expected-warning@-4 {{variable templates are a C++1y extension}}
 #endif
 
+// No diagnostic for specializations of variable templates; we will have
+// diagnosed the primary template.
 template<typename T> T* var<T*> = new T();
-#ifdef CXX1YCOMPAT
-// expected-warning@-2 {{variable templates are incompatible with C++ standards before C++1y}}
-#else
-// expected-warning@-4 {{variable templates are a C++1y extension}}
-#endif
-
 template<> int var<int> = 10;
-#ifdef CXX1YCOMPAT
-// expected-warning@-2 {{variable templates are incompatible with C++ standards before C++1y}}
-#else
-// expected-warning@-4 {{variable templates are a C++1y extension}}
-#endif
-
 template int var<int>;
 float fvar = var<float>;
 
-class A {  
+class A {
   template<typename T> static T var = T(10);
 #ifdef CXX1YCOMPAT
 // expected-warning@-2 {{variable templates are incompatible with C++ standards before C++1y}}
 #else
 // expected-warning@-4 {{variable templates are a C++1y extension}}
 #endif
-  
-  template<typename T> static T* var<T*> = new T(); 
-#ifdef CXX1YCOMPAT
-// expected-warning@-2 {{variable templates are incompatible with C++ standards before C++1y}}
-#else
-// expected-warning@-4 {{variable templates are a C++1y extension}}
-#endif
 
+  template<typename T> static T* var<T*> = new T(); 
 };
 
 struct B {  template<typename T> static T v; };
@@ -435,19 +412,7 @@
 #endif
 
 template<typename T> T* B::v<T*> = new T();
-#ifdef CXX1YCOMPAT
-// expected-warning@-2 {{variable templates are incompatible with C++ standards before C++1y}}
-#else
-// expected-warning@-4 {{variable templates are a C++1y extension}}
-#endif
-
 template<> int B::v<int> = 10;
-#ifdef CXX1YCOMPAT
-// expected-warning@-2 {{variable templates are incompatible with C++ standards before C++1y}}
-#else
-// expected-warning@-4 {{variable templates are a C++1y extension}}
-#endif
-
 template int B::v<int>;
 float fsvar = B::v<float>;
 
diff --git a/test/SemaCXX/dcl_init_aggr.cpp b/test/SemaCXX/dcl_init_aggr.cpp
index 8c5e654..432c116 100644
--- a/test/SemaCXX/dcl_init_aggr.cpp
+++ b/test/SemaCXX/dcl_init_aggr.cpp
@@ -46,7 +46,7 @@
 };
 struct TooFewError { // expected-error{{implicit default constructor for}}
   int a;
-  NoDefaultConstructor nodef; // expected-note{{member is declared here}}
+  NoDefaultConstructor nodef; // expected-note{{member is declared here}} expected-note 2{{in implicit initialization of field 'nodef'}}
 };
 TooFewError too_few_okay = { 1, 1 };
 TooFewError too_few_error = { 1 }; // expected-error{{no matching constructor}}
@@ -54,7 +54,7 @@
 TooFewError too_few_okay2[2] = { 1, 1 }; // expected-note{{implicit default constructor for 'TooFewError' first required here}}
 TooFewError too_few_error2[2] = { 1 }; // expected-error{{no matching constructor}}
 
-NoDefaultConstructor too_few_error3[3] = { }; // expected-error {{no matching constructor}}
+NoDefaultConstructor too_few_error3[3] = { }; // expected-error {{no matching constructor}} expected-note {{implicit initialization of array element 0}}
 
 // C++ [dcl.init.aggr]p8
 struct Empty { };
diff --git a/test/SemaCXX/decl-expr-ambiguity.cpp b/test/SemaCXX/decl-expr-ambiguity.cpp
index 8164b2b..6abfb2f 100644
--- a/test/SemaCXX/decl-expr-ambiguity.cpp
+++ b/test/SemaCXX/decl-expr-ambiguity.cpp
@@ -33,7 +33,7 @@
   extern T f3();
   __typeof(*T()) f4(); // expected-warning {{empty parentheses interpreted as a function declaration}} expected-note {{replace parentheses with an initializer}}
   typedef void *V;
-  __typeof(*V()) f5();
+  __typeof(*V()) f5(); // expected-error {{ISO C++ does not allow indirection on operand of type 'V' (aka 'void *')}}
   T multi1,
     multi2(); // expected-warning {{empty parentheses interpreted as a function declaration}} expected-note {{replace parentheses with an initializer}}
   T(d)[5]; // expected-error {{redefinition of 'd'}}
diff --git a/test/SemaCXX/decl-microsoft-call-conv.cpp b/test/SemaCXX/decl-microsoft-call-conv.cpp
index e47a5c2..eb6c850 100644
--- a/test/SemaCXX/decl-microsoft-call-conv.cpp
+++ b/test/SemaCXX/decl-microsoft-call-conv.cpp
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -triple i686-pc-win32 -cxx-abi microsoft -fms-extensions -verify %s
+// RUN: %clang_cc1 -triple i686-pc-win32 -fms-extensions -verify %s
+// RUN: %clang_cc1 -triple i686-pc-mingw32 -verify %s
+// RUN: %clang_cc1 -triple i686-pc-mingw32 -fms-extensions -verify %s
 
 typedef void void_fun_t();
 typedef void __cdecl cdecl_fun_t();
@@ -176,3 +178,56 @@
   void bah() {}
   void baz() { zed(bah); }
 }
+
+namespace test4 {
+  class foo {
+    template <typename T> static void bar(T v);
+  };
+  extern template void foo::bar(const void *);
+}
+
+namespace test5 {
+  template <class T>
+  class valarray {
+    void bar();
+  };
+  extern template void valarray<int>::bar();
+}
+
+namespace test6 {
+  struct foo {
+    int bar();
+  };
+  typedef int bar_t();
+  void zed(bar_t foo::*) {
+  }
+  void baz() {
+    zed(&foo::bar);
+  }
+}
+
+namespace test7 {
+  template <typename T>
+  struct S {
+    void f(T t) {
+      t = 42;
+    }
+  };
+  template<> void S<void*>::f(void*);
+  void g(S<void*> s, void* p) {
+    s.f(p);
+  }
+}
+
+namespace test8 {
+  template <typename T>
+  struct S {
+    void f(T t) { // expected-note {{previous declaration is here}}
+      t = 42; // expected-error {{assigning to 'void *' from incompatible type 'int'}}
+    }
+  };
+  template<> void __cdecl S<void*>::f(void*); // expected-error {{function declared 'cdecl' here was previously declared without calling convention}}
+  void g(S<void*> s, void* p) {
+    s.f(p); // expected-note {{in instantiation of member function 'test8::S<void *>::f' requested here}}
+  }
+}
diff --git a/test/SemaCXX/declspec-thread.cpp b/test/SemaCXX/declspec-thread.cpp
new file mode 100644
index 0000000..0ace9a6
--- /dev/null
+++ b/test/SemaCXX/declspec-thread.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -triple i686-pc-win32 -std=c++11 -fms-extensions -verify %s
+
+__thread __declspec(thread) int a; // expected-error {{already has a thread-local storage specifier}}
+__declspec(thread) __thread int b; // expected-error {{already has a thread-local storage specifier}}
+__declspec(thread) int c(); // expected-warning {{only applies to variables}}
+__declspec(thread) int d;
+int foo();
+__declspec(thread) int e = foo(); // expected-error {{must be a constant expression}} expected-note {{thread_local}}
+
+struct HasCtor { HasCtor(); int x; };
+__declspec(thread) HasCtor f; // expected-error {{must be a constant expression}} expected-note {{thread_local}}
+
+struct HasDtor { ~HasDtor(); int x; };
+__declspec(thread) HasDtor g; // expected-error {{non-trivial destruction}} expected-note {{thread_local}}
+
+struct HasDefaultedDefaultCtor {
+  HasDefaultedDefaultCtor() = default;
+  int x;
+};
+__declspec(thread) HasDefaultedDefaultCtor h;
+
+struct HasConstexprCtor {
+  constexpr HasConstexprCtor(int x) : x(x) {}
+  int x;
+};
+__declspec(thread) HasConstexprCtor i(42);
+
+int foo() {
+  __declspec(thread) int a; // expected-error {{must have global storage}}
+  static __declspec(thread) int b;
+}
+
+extern __declspec(thread) int fwd_thread_var;
+__declspec(thread) int fwd_thread_var = 5;
+
+extern int fwd_thread_var_mismatch; // expected-note {{previous declaration}}
+__declspec(thread) int fwd_thread_var_mismatch = 5; // expected-error-re {{thread-local {{.*}} follows non-thread-local}}
+
+extern __declspec(thread) int thread_mismatch_2; // expected-note {{previous declaration}}
+int thread_mismatch_2 = 5; // expected-error-re {{non-thread-local {{.*}} follows thread-local}}
+
+typedef __declspec(thread) int tls_int_t; // expected-warning {{only applies to variables}}
diff --git a/test/SemaCXX/decltype.cpp b/test/SemaCXX/decltype.cpp
index d6e85d2..f1900b2 100644
--- a/test/SemaCXX/decltype.cpp
+++ b/test/SemaCXX/decltype.cpp
@@ -16,6 +16,27 @@
   float &fr = f2(AC().a);
 }
 
+template <class T>
+struct Future {
+  explicit Future(T v);
+
+  template <class F>
+  auto call(F&& fn) -> decltype(fn(T())) {
+    return fn(T());
+  }
+
+  template <class B, class F>
+  auto then(F&& fn) -> decltype(call(fn))
+  {
+    return fn(T());
+  }
+};
+
+void rdar16527205() {
+  Future<int> f1(42);
+  f1.call([](int){ return Future<float>(0); });
+}
+
 namespace pr10154 {
   class A{
       A(decltype(nullptr) param);
@@ -45,6 +66,16 @@
   U &r = S<int>::f();
 }
 
+namespace PR18876 {
+  struct A { ~A() = delete; }; // expected-note +{{here}}
+  A f();
+  decltype(f()) *a; // ok, function call
+  decltype(A()) *b; // expected-error {{attempt to use a deleted function}}
+  decltype(0, f()) *c; // ok, function call on RHS of comma
+  decltype(0, A()) *d; // expected-error {{attempt to use a deleted function}}
+  decltype(f(), 0) *e; // expected-error {{attempt to use a deleted function}}
+}
+
 template<typename>
 class conditional {
 };
diff --git a/test/SemaCXX/default1.cpp b/test/SemaCXX/default1.cpp
index b661776..23466fa 100644
--- a/test/SemaCXX/default1.cpp
+++ b/test/SemaCXX/default1.cpp
@@ -62,3 +62,6 @@
     j(2, 3); // expected-error{{too many arguments to function call, expected at most single argument 'f', have 2}}
   }
 }
+
+int pr20055_f(int x = 0, int y = UNDEFINED); // expected-error{{use of undeclared identifier}}
+int pr20055_v = pr20055_f(0);
diff --git a/test/SemaCXX/deleted-function.cpp b/test/SemaCXX/deleted-function.cpp
index e78e7ed..d7ef9b2 100644
--- a/test/SemaCXX/deleted-function.cpp
+++ b/test/SemaCXX/deleted-function.cpp
@@ -15,9 +15,9 @@
 void ov(double) = delete; // expected-note {{candidate function has been explicitly deleted}}
 
 struct WithDel {
-  WithDel() = delete; // expected-note {{function has been explicitly marked deleted here}}
-  void fn() = delete; // expected-note {{function has been explicitly marked deleted here}}
-  operator int() = delete; // expected-note {{function has been explicitly marked deleted here}}
+  WithDel() = delete; // expected-note {{'WithDel' has been explicitly marked deleted here}}
+  void fn() = delete; // expected-note {{'fn' has been explicitly marked deleted here}}
+  operator int() = delete; // expected-note {{'operator int' has been explicitly marked deleted here}}
   void operator +(int) = delete;
 
   int i = delete; // expected-error {{only functions can have deleted definitions}}
diff --git a/test/SemaCXX/deleted-operator.cpp b/test/SemaCXX/deleted-operator.cpp
index 9f53e71..df67978 100644
--- a/test/SemaCXX/deleted-operator.cpp
+++ b/test/SemaCXX/deleted-operator.cpp
@@ -13,6 +13,7 @@
 }
 
 struct DelOpDel {
-  virtual ~DelOpDel() {} // expected-error {{deleted function}}
-  void operator delete(void*) = delete; // expected-note {{deleted here}}
+  // FIXME: In MS ABI, we error twice below.
+  virtual ~DelOpDel() {} // expected-error 1-2 {{attempt to use a deleted function}}
+  void operator delete(void*) = delete; // expected-note 1-2 {{deleted here}}
 };
diff --git a/test/SemaCXX/deprecated.cpp b/test/SemaCXX/deprecated.cpp
index 0335a80..2fe6d59 100644
--- a/test/SemaCXX/deprecated.cpp
+++ b/test/SemaCXX/deprecated.cpp
@@ -24,12 +24,15 @@
   register int m asm("rbx"); // no-warning
 
   int k = to_int(n); // no-warning
-
   bool b;
   ++b; // expected-warning {{incrementing expression of type bool is deprecated}}
 
-  // FIXME: This is ill-formed in C++11.
-  char *p = "foo"; // expected-warning {{conversion from string literal to 'char *' is deprecated}}
+  char *p = "foo";
+#if __cplusplus < 201103L
+  // expected-warning@-2 {{conversion from string literal to 'char *' is deprecated}}
+#else
+  // expected-warning@-4 {{ISO C++11 does not allow conversion from string literal to 'char *'}}
+#endif
 }
 
 struct S { int n; };
diff --git a/test/SemaCXX/destructor.cpp b/test/SemaCXX/destructor.cpp
index e511be0..5305ff5 100644
--- a/test/SemaCXX/destructor.cpp
+++ b/test/SemaCXX/destructor.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -verify %s
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -fsyntax-only -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -verify %s
+// RUN: %clang_cc1 -std=c++11 -triple %ms_abi_triple -DMSABI -fsyntax-only -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -verify %s
 class A {
 public:
   ~A();
@@ -83,6 +84,12 @@
 }
 
 namespace PR6709 {
+#ifdef MSABI
+  // This bug, "Clang instantiates destructor for function argument" is intended
+  // behaviour in the Microsoft ABI because the callee needs to destruct the arguments.
+  // expected-error@+3 {{indirection requires pointer operand ('int' invalid)}}
+  // expected-note@+3 {{in instantiation of member function 'PR6709::X<int>::~X' requested here}}
+#endif
   template<class T> class X { T v; ~X() { ++*v; } };
   void a(X<int> x) {}
 }
@@ -100,10 +107,16 @@
       T::deleteIt(p); // expected-error {{type 'int' cannot be used prior to '::'}}
     }
 
+#ifdef MSABI
+    // expected-note@+2 {{in instantiation of member function 'test6::A<int>::operator delete' requested here}}
+#endif
     virtual ~A() {}
   };
 
-  class B : A<int> { B(); }; // expected-note {{in instantiation of member function 'test6::A<int>::operator delete' requested here}}
+#ifndef MSABI
+    // expected-note@+2 {{in instantiation of member function 'test6::A<int>::operator delete' requested here}}
+#endif
+  class B : A<int> { B(); };
   B::B() {}
 }
 
@@ -182,7 +195,7 @@
 
 struct D: B {}; // expected-warning {{has virtual functions but non-virtual destructor}}
 
-struct F final: B {}; // expected-warning {{has virtual functions but non-virtual destructor}}
+struct F final : B {};
 
 struct VB {
   virtual void foo();
@@ -367,3 +380,9 @@
 namespace PR16892 {
   auto p = &A::~A; // expected-error{{taking the address of a destructor}}
 }
+
+namespace PR20238 {
+struct S {
+  volatile ~S() { } // expected-error{{destructor cannot have a return type}}
+};
+}
diff --git a/test/SemaCXX/dllexport.cpp b/test/SemaCXX/dllexport.cpp
new file mode 100644
index 0000000..69e1a06
--- /dev/null
+++ b/test/SemaCXX/dllexport.cpp
@@ -0,0 +1,1010 @@
+// RUN: %clang_cc1 -triple i686-win32     -fsyntax-only -verify -std=c++11 -DMS %s
+// RUN: %clang_cc1 -triple x86_64-win32   -fsyntax-only -verify -std=c++1y -DMS %s
+// RUN: %clang_cc1 -triple i686-mingw32   -fsyntax-only -verify -std=c++1y %s
+// RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -verify -std=c++11 %s
+
+// Helper structs to make templates more expressive.
+struct ImplicitInst_Exported {};
+struct ExplicitDecl_Exported {};
+struct ExplicitInst_Exported {};
+struct ExplicitSpec_Exported {};
+struct ExplicitSpec_Def_Exported {};
+struct ExplicitSpec_InlineDef_Exported {};
+struct ExplicitSpec_NotExported {};
+namespace { struct Internal {}; }
+struct External { int v; };
+
+
+// Invalid usage.
+__declspec(dllexport) typedef int typedef1; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
+typedef __declspec(dllexport) int typedef2; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
+typedef int __declspec(dllexport) typedef3; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
+typedef __declspec(dllexport) void (*FunTy)(); // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
+enum __declspec(dllexport) Enum {}; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
+#if __has_feature(cxx_strong_enums)
+  enum class __declspec(dllexport) EnumClass {}; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
+#endif
+
+
+
+//===----------------------------------------------------------------------===//
+// Globals
+//===----------------------------------------------------------------------===//
+
+// Export declaration.
+__declspec(dllexport) extern int ExternGlobalDecl;
+
+// dllexport implies a definition.
+__declspec(dllexport) int GlobalDef;
+
+// Export definition.
+__declspec(dllexport) int GlobalInit1 = 1;
+int __declspec(dllexport) GlobalInit2 = 1;
+
+// Declare, then export definition.
+__declspec(dllexport) extern int GlobalDeclInit;
+int GlobalDeclInit = 1;
+
+// Redeclarations
+__declspec(dllexport) extern int GlobalRedecl1;
+__declspec(dllexport)        int GlobalRedecl1;
+
+__declspec(dllexport) extern int GlobalRedecl2;
+                             int GlobalRedecl2;
+
+                      extern int GlobalRedecl3; // expected-note{{previous declaration is here}}
+__declspec(dllexport) extern int GlobalRedecl3; // expected-warning{{redeclaration of 'GlobalRedecl3' should not add 'dllexport' attribute}}
+
+// External linkage is required.
+__declspec(dllexport) static int StaticGlobal; // expected-error{{'StaticGlobal' must have external linkage when declared 'dllexport'}}
+__declspec(dllexport) Internal InternalTypeGlobal; // expected-error{{'InternalTypeGlobal' must have external linkage when declared 'dllexport'}}
+namespace    { __declspec(dllexport) int InternalGlobal; } // expected-error{{'(anonymous namespace)::InternalGlobal' must have external linkage when declared 'dllexport'}}
+namespace ns { __declspec(dllexport) int ExternalGlobal; }
+
+__declspec(dllexport) auto InternalAutoTypeGlobal = Internal(); // expected-error{{'InternalAutoTypeGlobal' must have external linkage when declared 'dllexport'}}
+__declspec(dllexport) auto ExternalAutoTypeGlobal = External();
+
+// Export in local scope.
+void functionScope() {
+  __declspec(dllexport)        int LocalVarDecl; // expected-error{{'LocalVarDecl' must have external linkage when declared 'dllexport'}}
+  __declspec(dllexport)        int LocalVarDef = 1; // expected-error{{'LocalVarDef' must have external linkage when declared 'dllexport'}}
+  __declspec(dllexport) extern int ExternLocalVarDecl;
+  __declspec(dllexport) static int StaticLocalVar; // expected-error{{'StaticLocalVar' must have external linkage when declared 'dllexport'}}
+}
+
+
+
+//===----------------------------------------------------------------------===//
+// Variable templates
+//===----------------------------------------------------------------------===//
+#if __has_feature(cxx_variable_templates)
+
+// Export declaration.
+template<typename T> __declspec(dllexport) extern int ExternVarTmplDecl;
+
+// dllexport implies a definition.
+template<typename T> __declspec(dllexport) int VarTmplDef;
+
+// Export definition.
+template<typename T> __declspec(dllexport) int VarTmplInit1 = 1;
+template<typename T> int __declspec(dllexport) VarTmplInit2 = 1;
+
+// Declare, then export definition.
+template<typename T> __declspec(dllexport) extern int VarTmplDeclInit;
+template<typename T>                              int VarTmplDeclInit = 1;
+
+// Redeclarations
+template<typename T> __declspec(dllexport) extern int VarTmplRedecl1;
+template<typename T> __declspec(dllexport)        int VarTmplRedecl1 = 1;
+
+template<typename T> __declspec(dllexport) extern int VarTmplRedecl2;
+template<typename T>                              int VarTmplRedecl2 = 1;
+
+template<typename T>                       extern int VarTmplRedecl3; // expected-note{{previous declaration is here}}
+template<typename T> __declspec(dllexport) extern int VarTmplRedecl3; // expected-error{{redeclaration of 'VarTmplRedecl3' cannot add 'dllexport' attribute}}
+
+// External linkage is required.
+template<typename T> __declspec(dllexport) static int StaticVarTmpl; // expected-error{{'StaticVarTmpl' must have external linkage when declared 'dllexport'}}
+template<typename T> __declspec(dllexport) Internal InternalTypeVarTmpl; // expected-error{{'InternalTypeVarTmpl' must have external linkage when declared 'dllexport'}}
+namespace    { template<typename T> __declspec(dllexport) int InternalVarTmpl; } // expected-error{{'(anonymous namespace)::InternalVarTmpl' must have external linkage when declared 'dllexport'}}
+namespace ns { template<typename T> __declspec(dllexport) int ExternalVarTmpl = 1; }
+
+template<typename T> __declspec(dllexport) auto InternalAutoTypeVarTmpl = Internal(); // expected-error{{'InternalAutoTypeVarTmpl' must have external linkage when declared 'dllexport'}}
+template<typename T> __declspec(dllexport) auto ExternalAutoTypeVarTmpl = External();
+template External ExternalAutoTypeVarTmpl<ExplicitInst_Exported>;
+
+
+template<typename T> int VarTmpl = 1;
+template<typename T> __declspec(dllexport) int ExportedVarTmpl = 1;
+
+// Export implicit instantiation of an exported variable template.
+int useVarTmpl() { return ExportedVarTmpl<ImplicitInst_Exported>; }
+
+// Export explicit instantiation declaration of an exported variable template.
+extern template int ExportedVarTmpl<ExplicitDecl_Exported>;
+       template int ExportedVarTmpl<ExplicitDecl_Exported>;
+
+// Export explicit instantiation definition of an exported variable template.
+template __declspec(dllexport) int ExportedVarTmpl<ExplicitInst_Exported>;
+
+// Export specialization of an exported variable template.
+template<> __declspec(dllexport) int ExportedVarTmpl<ExplicitSpec_Exported>;
+template<> __declspec(dllexport) int ExportedVarTmpl<ExplicitSpec_Def_Exported> = 1;
+
+// Not exporting specialization of an exported variable template without
+// explicit dllexport.
+template<> int ExportedVarTmpl<ExplicitSpec_NotExported>;
+
+
+// Export explicit instantiation declaration of a non-exported variable template.
+extern template __declspec(dllexport) int VarTmpl<ExplicitDecl_Exported>;
+       template __declspec(dllexport) int VarTmpl<ExplicitDecl_Exported>;
+
+// Export explicit instantiation definition of a non-exported variable template.
+template __declspec(dllexport) int VarTmpl<ExplicitInst_Exported>;
+
+// Export specialization of a non-exported variable template.
+template<> __declspec(dllexport) int VarTmpl<ExplicitSpec_Exported>;
+template<> __declspec(dllexport) int VarTmpl<ExplicitSpec_Def_Exported> = 1;
+
+#endif // __has_feature(cxx_variable_templates)
+
+
+
+//===----------------------------------------------------------------------===//
+// Functions
+//===----------------------------------------------------------------------===//
+
+// Export function declaration. Check different placements.
+__attribute__((dllexport)) void decl1A(); // Sanity check with __attribute__
+__declspec(dllexport)      void decl1B();
+
+void __attribute__((dllexport)) decl2A();
+void __declspec(dllexport)      decl2B();
+
+// Export function definition.
+__declspec(dllexport) void def() {}
+
+// extern "C"
+extern "C" __declspec(dllexport) void externC() {}
+
+// Export inline function.
+__declspec(dllexport) inline void inlineFunc1() {}
+inline void __attribute__((dllexport)) inlineFunc2() {}
+
+__declspec(dllexport) inline void inlineDecl();
+                             void inlineDecl() {}
+
+__declspec(dllexport) void inlineDef();
+               inline void inlineDef() {}
+
+// Redeclarations
+__declspec(dllexport) void redecl1();
+__declspec(dllexport) void redecl1() {}
+
+__declspec(dllexport) void redecl2();
+                      void redecl2() {}
+
+                      void redecl3(); // expected-note{{previous declaration is here}}
+__declspec(dllexport) void redecl3(); // expected-warning{{redeclaration of 'redecl3' should not add 'dllexport' attribute}}
+
+                      void redecl4(); // expected-note{{previous declaration is here}}
+__declspec(dllexport) inline void redecl4() {} // expected-warning{{redeclaration of 'redecl4' should not add 'dllexport' attribute}}
+
+// Friend functions
+struct FuncFriend {
+  friend __declspec(dllexport) void friend1();
+  friend __declspec(dllexport) void friend2();
+  friend                       void friend3(); // expected-note{{previous declaration is here}}
+  friend                       void friend4(); // expected-note{{previous declaration is here}}
+};
+__declspec(dllexport) void friend1() {}
+                      void friend2() {}
+__declspec(dllexport) void friend3() {} // expected-warning{{redeclaration of 'friend3' should not add 'dllexport' attribute}}
+__declspec(dllexport) inline void friend4() {} // expected-warning{{redeclaration of 'friend4' should not add 'dllexport' attribute}}
+
+// Implicit declarations can be redeclared with dllexport.
+__declspec(dllexport) void* operator new(__SIZE_TYPE__ n);
+
+// External linkage is required.
+__declspec(dllexport) static int staticFunc(); // expected-error{{'staticFunc' must have external linkage when declared 'dllexport'}}
+__declspec(dllexport) Internal internalRetFunc(); // expected-error{{'internalRetFunc' must have external linkage when declared 'dllexport'}}
+namespace    { __declspec(dllexport) void internalFunc() {} } // expected-error{{'(anonymous namespace)::internalFunc' must have external linkage when declared 'dllexport'}}
+namespace ns { __declspec(dllexport) void externalFunc() {} }
+
+// Export deleted function.
+__declspec(dllexport) void deletedFunc() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
+__declspec(dllexport) inline void deletedInlineFunc() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
+
+
+
+//===----------------------------------------------------------------------===//
+// Function templates
+//===----------------------------------------------------------------------===//
+
+// Export function template declaration. Check different placements.
+template<typename T> __declspec(dllexport) void funcTmplDecl1();
+template<typename T> void __declspec(dllexport) funcTmplDecl2();
+
+// Export function template definition.
+template<typename T> __declspec(dllexport) void funcTmplDef() {}
+
+// Export inline function template.
+template<typename T> __declspec(dllexport) inline void inlineFuncTmpl1() {}
+template<typename T> inline void __attribute__((dllexport)) inlineFuncTmpl2() {}
+
+template<typename T> __declspec(dllexport) inline void inlineFuncTmplDecl();
+template<typename T>                              void inlineFuncTmplDecl() {}
+
+template<typename T> __declspec(dllexport) void inlineFuncTmplDef();
+template<typename T>                inline void inlineFuncTmplDef() {}
+
+// Redeclarations
+template<typename T> __declspec(dllexport) void funcTmplRedecl1();
+template<typename T> __declspec(dllexport) void funcTmplRedecl1() {}
+
+template<typename T> __declspec(dllexport) void funcTmplRedecl2();
+template<typename T>                       void funcTmplRedecl2() {}
+
+template<typename T>                       void funcTmplRedecl3(); // expected-note{{previous declaration is here}}
+template<typename T> __declspec(dllexport) void funcTmplRedecl3(); // expected-error{{redeclaration of 'funcTmplRedecl3' cannot add 'dllexport' attribute}}
+
+template<typename T>                       void funcTmplRedecl4(); // expected-note{{previous declaration is here}}
+template<typename T> __declspec(dllexport) inline void funcTmplRedecl4() {} // expected-error{{redeclaration of 'funcTmplRedecl4' cannot add 'dllexport' attribute}}
+
+// Function template friends
+struct FuncTmplFriend {
+  template<typename T> friend __declspec(dllexport) void funcTmplFriend1();
+  template<typename T> friend __declspec(dllexport) void funcTmplFriend2();
+  template<typename T> friend                       void funcTmplFriend3(); // expected-note{{previous declaration is here}}
+  template<typename T> friend                       void funcTmplFriend4(); // expected-note{{previous declaration is here}}
+};
+template<typename T> __declspec(dllexport) void funcTmplFriend1() {}
+template<typename T>                       void funcTmplFriend2() {}
+template<typename T> __declspec(dllexport) void funcTmplFriend3() {} // expected-error{{redeclaration of 'funcTmplFriend3' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport) inline void funcTmplFriend4() {} // expected-error{{redeclaration of 'funcTmplFriend4' cannot add 'dllexport' attribute}}
+
+// External linkage is required.
+template<typename T> __declspec(dllexport) static int staticFuncTmpl(); // expected-error{{'staticFuncTmpl' must have external linkage when declared 'dllexport'}}
+template<typename T> __declspec(dllexport) Internal internalRetFuncTmpl(); // expected-error{{'internalRetFuncTmpl' must have external linkage when declared 'dllexport'}}
+namespace    { template<typename T> __declspec(dllexport) void internalFuncTmpl(); } // expected-error{{'(anonymous namespace)::internalFuncTmpl' must have external linkage when declared 'dllexport'}}
+namespace ns { template<typename T> __declspec(dllexport) void externalFuncTmpl(); }
+
+
+template<typename T> void funcTmpl() {}
+template<typename T> __declspec(dllexport) void exportedFuncTmplDecl();
+template<typename T> __declspec(dllexport) void exportedFuncTmpl() {}
+
+// Export implicit instantiation of an exported function template.
+void useFunTmplDecl() { exportedFuncTmplDecl<ImplicitInst_Exported>(); }
+void useFunTmplDef() { exportedFuncTmpl<ImplicitInst_Exported>(); }
+
+// Export explicit instantiation declaration of an exported function template.
+extern template void exportedFuncTmpl<ExplicitDecl_Exported>();
+       template void exportedFuncTmpl<ExplicitDecl_Exported>();
+
+// Export explicit instantiation definition of an exported function template.
+template void exportedFuncTmpl<ExplicitInst_Exported>();
+
+// Export specialization of an exported function template.
+template<> __declspec(dllexport) void exportedFuncTmpl<ExplicitSpec_Exported>();
+template<> __declspec(dllexport) void exportedFuncTmpl<ExplicitSpec_Def_Exported>() {}
+template<> __declspec(dllexport) inline void exportedFuncTmpl<ExplicitSpec_InlineDef_Exported>() {}
+
+// Not exporting specialization of an exported function template without
+// explicit dllexport.
+template<> void exportedFuncTmpl<ExplicitSpec_NotExported>() {}
+
+
+// Export explicit instantiation declaration of a non-exported function template.
+extern template __declspec(dllexport) void funcTmpl<ExplicitDecl_Exported>();
+       template __declspec(dllexport) void funcTmpl<ExplicitDecl_Exported>();
+
+// Export explicit instantiation definition of a non-exported function template.
+template __declspec(dllexport) void funcTmpl<ExplicitInst_Exported>();
+
+// Export specialization of a non-exported function template.
+template<> __declspec(dllexport) void funcTmpl<ExplicitSpec_Exported>();
+template<> __declspec(dllexport) void funcTmpl<ExplicitSpec_Def_Exported>() {}
+template<> __declspec(dllexport) inline void funcTmpl<ExplicitSpec_InlineDef_Exported>() {}
+
+
+
+//===----------------------------------------------------------------------===//
+// Classes
+//===----------------------------------------------------------------------===//
+
+class __declspec(dllexport) ClassDecl;
+
+class __declspec(dllexport) ClassDef {};
+
+#ifdef MS
+// expected-warning@+3{{'dllexport' attribute ignored}}
+#endif
+template <typename T> struct PartiallySpecializedClassTemplate {};
+template <typename T> struct __declspec(dllexport) PartiallySpecializedClassTemplate<T*> { void f() {} };
+
+template <typename T> struct ExpliciallySpecializedClassTemplate {};
+template <> struct __declspec(dllexport) ExpliciallySpecializedClassTemplate<int> { void f() {} };
+
+
+//===----------------------------------------------------------------------===//
+// Classes with template base classes
+//===----------------------------------------------------------------------===//
+
+template <typename T> class ClassTemplate {};
+template <typename T> class __declspec(dllexport) ExportedClassTemplate {};
+template <typename T> class __declspec(dllimport) ImportedClassTemplate {};
+
+template <typename T> struct ExplicitlySpecializedTemplate { void func() {} };
+#ifdef MS
+// expected-note@+2{{class template 'ExplicitlySpecializedTemplate<int>' was explicitly specialized here}}
+#endif
+template <> struct ExplicitlySpecializedTemplate<int> { void func() {} };
+template <typename T> struct ExplicitlyExportSpecializedTemplate { void func() {} };
+template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func() {} };
+template <typename T> struct ExplicitlyImportSpecializedTemplate { void func() {} };
+template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func() {} };
+
+template <typename T> struct ExplicitlyInstantiatedTemplate { void func() {} };
+#ifdef MS
+// expected-note@+2{{class template 'ExplicitlyInstantiatedTemplate<int>' was instantiated here}}
+#endif
+template struct ExplicitlyInstantiatedTemplate<int>;
+template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func() {} };
+template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>;
+template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func() {} };
+template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate<int>;
+
+// ClassTemplate<int> gets exported.
+class __declspec(dllexport) DerivedFromTemplate : public ClassTemplate<int> {};
+
+// ClassTemplate<int> is already exported.
+class __declspec(dllexport) DerivedFromTemplate2 : public ClassTemplate<int> {};
+
+// ExportedTemplate is explicitly exported.
+class __declspec(dllexport) DerivedFromExportedTemplate : public ExportedClassTemplate<int> {};
+
+// ImportedTemplate is explicitly imported.
+class __declspec(dllexport) DerivedFromImportedTemplate : public ImportedClassTemplate<int> {};
+
+#ifdef MS
+// expected-note@+4{{class template 'ClassTemplate<double>' was instantiated here}}
+// expected-warning@+4{{propagating dll attribute to already instantiated base class template without dll attribute is not supported}}
+// expected-note@+3{{attribute is here}}
+#endif
+class DerivedFromTemplateD : public ClassTemplate<double> {};
+class __declspec(dllexport) DerivedFromTemplateD2 : public ClassTemplate<double> {};
+
+#ifdef MS
+// expected-note@+4{{class template 'ClassTemplate<bool>' was instantiated here}}
+// expected-warning@+4{{propagating dll attribute to already instantiated base class template with different dll attribute is not supported}}
+// expected-note@+3{{attribute is here}}
+#endif
+class __declspec(dllimport) DerivedFromTemplateB : public ClassTemplate<bool> {};
+class __declspec(dllexport) DerivedFromTemplateB2 : public ClassTemplate<bool> {};
+
+#ifdef MS
+// expected-warning@+3{{propagating dll attribute to explicitly specialized base class template without dll attribute is not supported}}
+// expected-note@+2{{attribute is here}}
+#endif
+struct __declspec(dllexport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate<int> {};
+
+// Base class alredy specialized with export attribute.
+struct __declspec(dllexport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {};
+
+// Base class already specialized with import attribute.
+struct __declspec(dllexport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {};
+
+#ifdef MS
+// expected-warning@+3{{propagating dll attribute to already instantiated base class template without dll attribute is not supported}}
+// expected-note@+2{{attribute is here}}
+#endif
+struct __declspec(dllexport) DerivedFromExplicitlyInstantiatedTemplate : public ExplicitlyInstantiatedTemplate<int> {};
+
+// Base class already instantiated with export attribute.
+struct __declspec(dllexport) DerivedFromExplicitlyExportInstantiatedTemplate : public ExplicitlyExportInstantiatedTemplate<int> {};
+
+// Base class already instantiated with import attribute.
+struct __declspec(dllexport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate<int> {};
+
+
+//===----------------------------------------------------------------------===//
+// Precedence
+//===----------------------------------------------------------------------===//
+
+// dllexport takes precedence over dllimport if both are specified.
+__attribute__((dllimport, dllexport))       extern int PrecedenceExternGlobal1A; // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllimport) __declspec(dllexport) extern int PrecedenceExternGlobal1B; // expected-warning{{'dllimport' attribute ignored}}
+
+__attribute__((dllexport, dllimport))       extern int PrecedenceExternGlobal2A; // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllexport) __declspec(dllimport) extern int PrecedenceExternGlobal2B; // expected-warning{{'dllimport' attribute ignored}}
+
+__attribute__((dllimport, dllexport))       int PrecedenceGlobal1A; // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllimport) __declspec(dllexport) int PrecedenceGlobal1B; // expected-warning{{'dllimport' attribute ignored}}
+
+__attribute__((dllexport, dllimport))       int PrecedenceGlobal2A; // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllexport) __declspec(dllimport) int PrecedenceGlobal2B; // expected-warning{{'dllimport' attribute ignored}}
+
+__declspec(dllexport) extern int PrecedenceExternGlobalRedecl1;
+__declspec(dllimport) extern int PrecedenceExternGlobalRedecl1; // expected-warning{{'dllimport' attribute ignored}}
+
+__declspec(dllimport) extern int PrecedenceExternGlobalRedecl2; // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllexport) extern int PrecedenceExternGlobalRedecl2;
+
+__declspec(dllexport) extern int PrecedenceGlobalRedecl1;
+__declspec(dllimport)        int PrecedenceGlobalRedecl1; // expected-warning{{'dllimport' attribute ignored}}
+
+__declspec(dllimport) extern int PrecedenceGlobalRedecl2; // expected-warning{{'dllimport' attribute ignored}}
+__declspec(dllexport)        int PrecedenceGlobalRedecl2;
+
+void __attribute__((dllimport, dllexport))       precedence1A() {} // expected-warning{{'dllimport' attribute ignored}}
+void __declspec(dllimport) __declspec(dllexport) precedence1B() {} // expected-warning{{'dllimport' attribute ignored}}
+
+void __attribute__((dllexport, dllimport))       precedence2A() {} // expected-warning{{'dllimport' attribute ignored}}
+void __declspec(dllexport) __declspec(dllimport) precedence2B() {} // expected-warning{{'dllimport' attribute ignored}}
+
+void __declspec(dllimport) precedenceRedecl1(); // expected-warning{{'dllimport' attribute ignored}}
+void __declspec(dllexport) precedenceRedecl1() {}
+
+void __declspec(dllexport) precedenceRedecl2();
+void __declspec(dllimport) precedenceRedecl2() {} // expected-warning{{'dllimport' attribute ignored}}
+
+
+
+//===----------------------------------------------------------------------===//
+// Class members
+//===----------------------------------------------------------------------===//
+
+// Export individual members of a class.
+struct ExportMembers {
+  struct Nested {
+    __declspec(dllexport) void normalDef();
+  };
+
+  __declspec(dllexport)                void normalDecl();
+  __declspec(dllexport)                void normalDef();
+  __declspec(dllexport)                void normalInclass() {}
+  __declspec(dllexport)                void normalInlineDef();
+  __declspec(dllexport)         inline void normalInlineDecl();
+  __declspec(dllexport) virtual        void virtualDecl();
+  __declspec(dllexport) virtual        void virtualDef();
+  __declspec(dllexport) virtual        void virtualInclass() {}
+  __declspec(dllexport) virtual        void virtualInlineDef();
+  __declspec(dllexport) virtual inline void virtualInlineDecl();
+  __declspec(dllexport) static         void staticDecl();
+  __declspec(dllexport) static         void staticDef();
+  __declspec(dllexport) static         void staticInclass() {}
+  __declspec(dllexport) static         void staticInlineDef();
+  __declspec(dllexport) static  inline void staticInlineDecl();
+
+protected:
+  __declspec(dllexport)                void protectedDef();
+private:
+  __declspec(dllexport)                void privateDef();
+public:
+
+  __declspec(dllexport)                int  Field; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
+  __declspec(dllexport) static         int  StaticField;
+  __declspec(dllexport) static         int  StaticFieldDef;
+  __declspec(dllexport) static  const  int  StaticConstField;
+  __declspec(dllexport) static  const  int  StaticConstFieldDef;
+  __declspec(dllexport) static  const  int  StaticConstFieldEqualInit = 1;
+  __declspec(dllexport) static  const  int  StaticConstFieldBraceInit{1};
+  __declspec(dllexport) constexpr static int ConstexprField = 1;
+  __declspec(dllexport) constexpr static int ConstexprFieldDef = 1;
+};
+
+       void ExportMembers::Nested::normalDef() {}
+       void ExportMembers::normalDef() {}
+inline void ExportMembers::normalInlineDef() {}
+       void ExportMembers::normalInlineDecl() {}
+       void ExportMembers::virtualDef() {}
+inline void ExportMembers::virtualInlineDef() {}
+       void ExportMembers::virtualInlineDecl() {}
+       void ExportMembers::staticDef() {}
+inline void ExportMembers::staticInlineDef() {}
+       void ExportMembers::staticInlineDecl() {}
+       void ExportMembers::protectedDef() {}
+       void ExportMembers::privateDef() {}
+
+       int  ExportMembers::StaticFieldDef;
+const  int  ExportMembers::StaticConstFieldDef = 1;
+constexpr int ExportMembers::ConstexprFieldDef;
+
+
+// Export on member definitions.
+struct ExportMemberDefs {
+  __declspec(dllexport)                void normalDef();
+  __declspec(dllexport)                void normalInlineDef();
+  __declspec(dllexport)         inline void normalInlineDecl();
+  __declspec(dllexport) virtual        void virtualDef();
+  __declspec(dllexport) virtual        void virtualInlineDef();
+  __declspec(dllexport) virtual inline void virtualInlineDecl();
+  __declspec(dllexport) static         void staticDef();
+  __declspec(dllexport) static         void staticInlineDef();
+  __declspec(dllexport) static  inline void staticInlineDecl();
+
+  __declspec(dllexport) static         int  StaticField;
+  __declspec(dllexport) static  const  int  StaticConstField;
+  __declspec(dllexport) constexpr static int ConstexprField = 1;
+};
+
+__declspec(dllexport)        void ExportMemberDefs::normalDef() {}
+__declspec(dllexport) inline void ExportMemberDefs::normalInlineDef() {}
+__declspec(dllexport)        void ExportMemberDefs::normalInlineDecl() {}
+__declspec(dllexport)        void ExportMemberDefs::virtualDef() {}
+__declspec(dllexport) inline void ExportMemberDefs::virtualInlineDef() {}
+__declspec(dllexport)        void ExportMemberDefs::virtualInlineDecl() {}
+__declspec(dllexport)        void ExportMemberDefs::staticDef() {}
+__declspec(dllexport) inline void ExportMemberDefs::staticInlineDef() {}
+__declspec(dllexport)        void ExportMemberDefs::staticInlineDecl() {}
+
+__declspec(dllexport)        int  ExportMemberDefs::StaticField;
+__declspec(dllexport) const  int  ExportMemberDefs::StaticConstField = 1;
+__declspec(dllexport) constexpr int ExportMemberDefs::ConstexprField;
+
+
+// Export special member functions.
+struct ExportSpecials {
+  __declspec(dllexport) ExportSpecials() {}
+  __declspec(dllexport) ~ExportSpecials();
+  __declspec(dllexport) inline ExportSpecials(const ExportSpecials&);
+  __declspec(dllexport) ExportSpecials& operator=(const ExportSpecials&);
+  __declspec(dllexport) ExportSpecials(ExportSpecials&&);
+  __declspec(dllexport) ExportSpecials& operator=(ExportSpecials&&);
+};
+
+ExportSpecials::~ExportSpecials() {}
+ExportSpecials::ExportSpecials(const ExportSpecials&) {}
+inline ExportSpecials& ExportSpecials::operator=(const ExportSpecials&) { return *this; }
+ExportSpecials::ExportSpecials(ExportSpecials&&) {}
+ExportSpecials& ExportSpecials::operator=(ExportSpecials&&) { return *this; }
+
+
+// Export allocation functions.
+extern "C" void* malloc(__SIZE_TYPE__ size);
+extern "C" void free(void* p);
+struct ExportAlloc {
+  __declspec(dllexport) void* operator new(__SIZE_TYPE__);
+  __declspec(dllexport) void* operator new[](__SIZE_TYPE__);
+  __declspec(dllexport) void operator delete(void*);
+  __declspec(dllexport) void operator delete[](void*);
+};
+void* ExportAlloc::operator new(__SIZE_TYPE__ n) { return malloc(n); }
+void* ExportAlloc::operator new[](__SIZE_TYPE__ n) { return malloc(n); }
+void ExportAlloc::operator delete(void* p) { free(p); }
+void ExportAlloc::operator delete[](void* p) { free(p); }
+
+
+// Export deleted member functions.
+struct ExportDeleted {
+  __declspec(dllexport) ExportDeleted() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
+  __declspec(dllexport) ~ExportDeleted() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
+  __declspec(dllexport) ExportDeleted(const ExportDeleted&) = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
+  __declspec(dllexport) ExportDeleted& operator=(const ExportDeleted&) = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
+  __declspec(dllexport) ExportDeleted(ExportDeleted&&) = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
+  __declspec(dllexport) ExportDeleted& operator=(ExportDeleted&&) = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
+  __declspec(dllexport) void deleted() = delete; // expected-error{{attribute 'dllexport' cannot be applied to a deleted function}}
+};
+
+
+// Export defaulted member functions.
+struct ExportDefaulted {
+  __declspec(dllexport) ExportDefaulted() = default;
+  __declspec(dllexport) ~ExportDefaulted() = default;
+  __declspec(dllexport) ExportDefaulted(const ExportDefaulted&) = default;
+  __declspec(dllexport) ExportDefaulted& operator=(const ExportDefaulted&) = default;
+  __declspec(dllexport) ExportDefaulted(ExportDefaulted&&) = default;
+  __declspec(dllexport) ExportDefaulted& operator=(ExportDefaulted&&) = default;
+};
+
+
+// Export defaulted member function definitions.
+struct ExportDefaultedDefs {
+  __declspec(dllexport) ExportDefaultedDefs();
+  __declspec(dllexport) ~ExportDefaultedDefs();
+
+  __declspec(dllexport) inline ExportDefaultedDefs(const ExportDefaultedDefs&);
+  __declspec(dllexport) ExportDefaultedDefs& operator=(const ExportDefaultedDefs&);
+
+  __declspec(dllexport) ExportDefaultedDefs(ExportDefaultedDefs&&);
+  __declspec(dllexport) ExportDefaultedDefs& operator=(ExportDefaultedDefs&&);
+};
+
+// Export definitions.
+__declspec(dllexport) ExportDefaultedDefs::ExportDefaultedDefs() = default;
+ExportDefaultedDefs::~ExportDefaultedDefs() = default;
+
+// Export inline declaration and definition.
+__declspec(dllexport) ExportDefaultedDefs::ExportDefaultedDefs(const ExportDefaultedDefs&) = default;
+inline ExportDefaultedDefs& ExportDefaultedDefs::operator=(const ExportDefaultedDefs&) = default;
+
+__declspec(dllexport) ExportDefaultedDefs::ExportDefaultedDefs(ExportDefaultedDefs&&) = default;
+ExportDefaultedDefs& ExportDefaultedDefs::operator=(ExportDefaultedDefs&&) = default;
+
+
+// Redeclarations cannot add dllexport.
+struct MemberRedecl {
+                 void normalDef();         // expected-note{{previous declaration is here}}
+                 void normalInlineDef();   // expected-note{{previous declaration is here}}
+          inline void normalInlineDecl();  // expected-note{{previous declaration is here}}
+  virtual        void virtualDef();        // expected-note{{previous declaration is here}}
+  virtual        void virtualInlineDef();  // expected-note{{previous declaration is here}}
+  virtual inline void virtualInlineDecl(); // expected-note{{previous declaration is here}}
+  static         void staticDef();         // expected-note{{previous declaration is here}}
+  static         void staticInlineDef();   // expected-note{{previous declaration is here}}
+  static  inline void staticInlineDecl();  // expected-note{{previous declaration is here}}
+
+  static         int  StaticField;         // expected-note{{previous declaration is here}}
+  static  const  int  StaticConstField;    // expected-note{{previous declaration is here}}
+  constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
+};
+
+__declspec(dllexport)        void MemberRedecl::normalDef() {}         // expected-error{{redeclaration of 'MemberRedecl::normalDef' cannot add 'dllexport' attribute}}
+__declspec(dllexport) inline void MemberRedecl::normalInlineDef() {}   // expected-error{{redeclaration of 'MemberRedecl::normalInlineDef' cannot add 'dllexport' attribute}}
+__declspec(dllexport)        void MemberRedecl::normalInlineDecl() {}  // expected-error{{redeclaration of 'MemberRedecl::normalInlineDecl' cannot add 'dllexport' attribute}}
+__declspec(dllexport)        void MemberRedecl::virtualDef() {}        // expected-error{{redeclaration of 'MemberRedecl::virtualDef' cannot add 'dllexport' attribute}}
+__declspec(dllexport) inline void MemberRedecl::virtualInlineDef() {}  // expected-error{{redeclaration of 'MemberRedecl::virtualInlineDef' cannot add 'dllexport' attribute}}
+__declspec(dllexport)        void MemberRedecl::virtualInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::virtualInlineDecl' cannot add 'dllexport' attribute}}
+__declspec(dllexport)        void MemberRedecl::staticDef() {}         // expected-error{{redeclaration of 'MemberRedecl::staticDef' cannot add 'dllexport' attribute}}
+__declspec(dllexport) inline void MemberRedecl::staticInlineDef() {}   // expected-error{{redeclaration of 'MemberRedecl::staticInlineDef' cannot add 'dllexport' attribute}}
+__declspec(dllexport)        void MemberRedecl::staticInlineDecl() {}  // expected-error{{redeclaration of 'MemberRedecl::staticInlineDecl' cannot add 'dllexport' attribute}}
+
+__declspec(dllexport)        int  MemberRedecl::StaticField = 1;       // expected-error{{redeclaration of 'MemberRedecl::StaticField' cannot add 'dllexport' attribute}}
+__declspec(dllexport) const  int  MemberRedecl::StaticConstField = 1;  // expected-error{{redeclaration of 'MemberRedecl::StaticConstField' cannot add 'dllexport' attribute}}
+__declspec(dllexport) constexpr int MemberRedecl::ConstexprField;      // expected-error{{redeclaration of 'MemberRedecl::ConstexprField' cannot add 'dllexport' attribute}}
+
+
+
+//===----------------------------------------------------------------------===//
+// Class member templates
+//===----------------------------------------------------------------------===//
+
+struct ExportMemberTmpl {
+  template<typename T> __declspec(dllexport)               void normalDecl();
+  template<typename T> __declspec(dllexport)               void normalDef();
+  template<typename T> __declspec(dllexport)               void normalInclass() {}
+  template<typename T> __declspec(dllexport)               void normalInlineDef();
+  template<typename T> __declspec(dllexport)        inline void normalInlineDecl();
+  template<typename T> __declspec(dllexport) static        void staticDecl();
+  template<typename T> __declspec(dllexport) static        void staticDef();
+  template<typename T> __declspec(dllexport) static        void staticInclass() {}
+  template<typename T> __declspec(dllexport) static        void staticInlineDef();
+  template<typename T> __declspec(dllexport) static inline void staticInlineDecl();
+
+#if __has_feature(cxx_variable_templates)
+  template<typename T> __declspec(dllexport) static        int  StaticField;
+  template<typename T> __declspec(dllexport) static        int  StaticFieldDef;
+  template<typename T> __declspec(dllexport) static const  int  StaticConstField;
+  template<typename T> __declspec(dllexport) static const  int  StaticConstFieldDef;
+  template<typename T> __declspec(dllexport) static const  int  StaticConstFieldEqualInit = 1;
+  template<typename T> __declspec(dllexport) static const  int  StaticConstFieldBraceInit{1};
+  template<typename T> __declspec(dllexport) constexpr static int ConstexprField = 1;
+  template<typename T> __declspec(dllexport) constexpr static int ConstexprFieldDef = 1;
+#endif // __has_feature(cxx_variable_templates)
+};
+
+template<typename T>        void ExportMemberTmpl::normalDef() {}
+template<typename T> inline void ExportMemberTmpl::normalInlineDef() {}
+template<typename T>        void ExportMemberTmpl::normalInlineDecl() {}
+template<typename T>        void ExportMemberTmpl::staticDef() {}
+template<typename T> inline void ExportMemberTmpl::staticInlineDef() {}
+template<typename T>        void ExportMemberTmpl::staticInlineDecl() {}
+
+#if __has_feature(cxx_variable_templates)
+template<typename T>        int  ExportMemberTmpl::StaticFieldDef;
+template<typename T> const  int  ExportMemberTmpl::StaticConstFieldDef = 1;
+template<typename T> constexpr int ExportMemberTmpl::ConstexprFieldDef;
+#endif // __has_feature(cxx_variable_templates)
+
+
+// Redeclarations cannot add dllexport.
+struct MemTmplRedecl {
+  template<typename T>               void normalDef();         // expected-note{{previous declaration is here}}
+  template<typename T>               void normalInlineDef();   // expected-note{{previous declaration is here}}
+  template<typename T>        inline void normalInlineDecl();  // expected-note{{previous declaration is here}}
+  template<typename T> static        void staticDef();         // expected-note{{previous declaration is here}}
+  template<typename T> static        void staticInlineDef();   // expected-note{{previous declaration is here}}
+  template<typename T> static inline void staticInlineDecl();  // expected-note{{previous declaration is here}}
+
+#if __has_feature(cxx_variable_templates)
+  template<typename T> static        int  StaticField;         // expected-note{{previous declaration is here}}
+  template<typename T> static const  int  StaticConstField;    // expected-note{{previous declaration is here}}
+  template<typename T> constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
+#endif // __has_feature(cxx_variable_templates)
+};
+
+template<typename T> __declspec(dllexport)        void MemTmplRedecl::normalDef() {}        // expected-error{{redeclaration of 'MemTmplRedecl::normalDef' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport) inline void MemTmplRedecl::normalInlineDef() {}  // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDef' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport)        void MemTmplRedecl::normalInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDecl' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport)        void MemTmplRedecl::staticDef() {}        // expected-error{{redeclaration of 'MemTmplRedecl::staticDef' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport) inline void MemTmplRedecl::staticInlineDef() {}  // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDef' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport)        void MemTmplRedecl::staticInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDecl' cannot add 'dllexport' attribute}}
+
+#if __has_feature(cxx_variable_templates)
+template<typename T> __declspec(dllexport)        int  MemTmplRedecl::StaticField = 1;      // expected-error{{redeclaration of 'MemTmplRedecl::StaticField' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport) const  int  MemTmplRedecl::StaticConstField = 1; // expected-error{{redeclaration of 'MemTmplRedecl::StaticConstField' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport) constexpr int MemTmplRedecl::ConstexprField;     // expected-error{{redeclaration of 'MemTmplRedecl::ConstexprField' cannot add 'dllexport' attribute}}
+#endif // __has_feature(cxx_variable_templates)
+
+
+
+struct MemFunTmpl {
+  template<typename T>                              void normalDef() {}
+  template<typename T> __declspec(dllexport)        void exportedNormal() {}
+  template<typename T>                       static void staticDef() {}
+  template<typename T> __declspec(dllexport) static void exportedStatic() {}
+};
+
+// Export implicit instantiation of an exported member function template.
+void useMemFunTmpl() {
+  MemFunTmpl().exportedNormal<ImplicitInst_Exported>();
+  MemFunTmpl().exportedStatic<ImplicitInst_Exported>();
+}
+
+// Export explicit instantiation declaration of an exported member function
+// template.
+extern template void MemFunTmpl::exportedNormal<ExplicitDecl_Exported>();
+       template void MemFunTmpl::exportedNormal<ExplicitDecl_Exported>();
+
+extern template void MemFunTmpl::exportedStatic<ExplicitDecl_Exported>();
+       template void MemFunTmpl::exportedStatic<ExplicitDecl_Exported>();
+
+// Export explicit instantiation definition of an exported member function
+// template.
+template void MemFunTmpl::exportedNormal<ExplicitInst_Exported>();
+template void MemFunTmpl::exportedStatic<ExplicitInst_Exported>();
+
+// Export specialization of an exported member function template.
+template<> __declspec(dllexport) void MemFunTmpl::exportedNormal<ExplicitSpec_Exported>();
+template<> __declspec(dllexport) void MemFunTmpl::exportedNormal<ExplicitSpec_Def_Exported>() {}
+template<> __declspec(dllexport) inline void MemFunTmpl::exportedNormal<ExplicitSpec_InlineDef_Exported>() {}
+
+template<> __declspec(dllexport) void MemFunTmpl::exportedStatic<ExplicitSpec_Exported>();
+template<> __declspec(dllexport) void MemFunTmpl::exportedStatic<ExplicitSpec_Def_Exported>() {}
+template<> __declspec(dllexport) inline void MemFunTmpl::exportedStatic<ExplicitSpec_InlineDef_Exported>() {}
+
+// Not exporting specialization of an exported member function template without
+// explicit dllexport.
+template<> void MemFunTmpl::exportedNormal<ExplicitSpec_NotExported>() {}
+template<> void MemFunTmpl::exportedStatic<ExplicitSpec_NotExported>() {}
+
+
+// Export explicit instantiation declaration of a non-exported member function
+// template.
+extern template __declspec(dllexport) void MemFunTmpl::normalDef<ExplicitDecl_Exported>();
+       template __declspec(dllexport) void MemFunTmpl::normalDef<ExplicitDecl_Exported>();
+
+extern template __declspec(dllexport) void MemFunTmpl::staticDef<ExplicitDecl_Exported>();
+       template __declspec(dllexport) void MemFunTmpl::staticDef<ExplicitDecl_Exported>();
+
+// Export explicit instantiation definition of a non-exported member function
+// template.
+template __declspec(dllexport) void MemFunTmpl::normalDef<ExplicitInst_Exported>();
+template __declspec(dllexport) void MemFunTmpl::staticDef<ExplicitInst_Exported>();
+
+// Export specialization of a non-exported member function template.
+template<> __declspec(dllexport) void MemFunTmpl::normalDef<ExplicitSpec_Exported>();
+template<> __declspec(dllexport) void MemFunTmpl::normalDef<ExplicitSpec_Def_Exported>() {}
+template<> __declspec(dllexport) inline void MemFunTmpl::normalDef<ExplicitSpec_InlineDef_Exported>() {}
+
+template<> __declspec(dllexport) void MemFunTmpl::staticDef<ExplicitSpec_Exported>();
+template<> __declspec(dllexport) void MemFunTmpl::staticDef<ExplicitSpec_Def_Exported>() {}
+template<> __declspec(dllexport) inline void MemFunTmpl::staticDef<ExplicitSpec_InlineDef_Exported>() {}
+
+
+
+#if __has_feature(cxx_variable_templates)
+struct MemVarTmpl {
+  template<typename T>                       static const int StaticVar = 1;
+  template<typename T> __declspec(dllexport) static const int ExportedStaticVar = 1;
+};
+template<typename T> const int MemVarTmpl::StaticVar;
+template<typename T> const int MemVarTmpl::ExportedStaticVar;
+
+// Export implicit instantiation of an exported member variable template.
+int useMemVarTmpl() { return MemVarTmpl::ExportedStaticVar<ImplicitInst_Exported>; }
+
+// Export explicit instantiation declaration of an exported member variable
+// template.
+extern template const int MemVarTmpl::ExportedStaticVar<ExplicitDecl_Exported>;
+       template const int MemVarTmpl::ExportedStaticVar<ExplicitDecl_Exported>;
+
+// Export explicit instantiation definition of an exported member variable
+// template.
+template const int MemVarTmpl::ExportedStaticVar<ExplicitInst_Exported>;
+
+// Export specialization of an exported member variable template.
+template<> __declspec(dllexport) const int MemVarTmpl::ExportedStaticVar<ExplicitSpec_Exported>;
+template<> __declspec(dllexport) const int MemVarTmpl::ExportedStaticVar<ExplicitSpec_Def_Exported> = 1;
+
+// Not exporting specialization of an exported member variable template without
+// explicit dllexport.
+template<> const int MemVarTmpl::ExportedStaticVar<ExplicitSpec_NotExported>;
+
+
+// Export explicit instantiation declaration of a non-exported member variable
+// template.
+extern template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitDecl_Exported>;
+       template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitDecl_Exported>;
+
+// Export explicit instantiation definition of a non-exported member variable
+// template.
+template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitInst_Exported>;
+
+// Export specialization of a non-exported member variable template.
+template<> __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitSpec_Exported>;
+template<> __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitSpec_Def_Exported> = 1;
+
+#endif // __has_feature(cxx_variable_templates)
+
+
+
+//===----------------------------------------------------------------------===//
+// Class template members
+//===----------------------------------------------------------------------===//
+
+// Export individual members of a class template.
+template<typename T>
+struct ExportClassTmplMembers {
+  __declspec(dllexport)                void normalDecl();
+  __declspec(dllexport)                void normalDef();
+  __declspec(dllexport)                void normalInclass() {}
+  __declspec(dllexport)                void normalInlineDef();
+  __declspec(dllexport)         inline void normalInlineDecl();
+  __declspec(dllexport) virtual        void virtualDecl();
+  __declspec(dllexport) virtual        void virtualDef();
+  __declspec(dllexport) virtual        void virtualInclass() {}
+  __declspec(dllexport) virtual        void virtualInlineDef();
+  __declspec(dllexport) virtual inline void virtualInlineDecl();
+  __declspec(dllexport) static         void staticDecl();
+  __declspec(dllexport) static         void staticDef();
+  __declspec(dllexport) static         void staticInclass() {}
+  __declspec(dllexport) static         void staticInlineDef();
+  __declspec(dllexport) static  inline void staticInlineDecl();
+
+protected:
+  __declspec(dllexport)                void protectedDef();
+private:
+  __declspec(dllexport)                void privateDef();
+public:
+
+  __declspec(dllexport)                int  Field; // expected-warning{{'dllexport' attribute only applies to variables, functions and classes}}
+  __declspec(dllexport) static         int  StaticField;
+  __declspec(dllexport) static         int  StaticFieldDef;
+  __declspec(dllexport) static  const  int  StaticConstField;
+  __declspec(dllexport) static  const  int  StaticConstFieldDef;
+  __declspec(dllexport) static  const  int  StaticConstFieldEqualInit = 1;
+  __declspec(dllexport) static  const  int  StaticConstFieldBraceInit{1};
+  __declspec(dllexport) constexpr static int ConstexprField = 1;
+  __declspec(dllexport) constexpr static int ConstexprFieldDef = 1;
+};
+
+template<typename T>        void ExportClassTmplMembers<T>::normalDef() {}
+template<typename T> inline void ExportClassTmplMembers<T>::normalInlineDef() {}
+template<typename T>        void ExportClassTmplMembers<T>::normalInlineDecl() {}
+template<typename T>        void ExportClassTmplMembers<T>::virtualDef() {}
+template<typename T> inline void ExportClassTmplMembers<T>::virtualInlineDef() {}
+template<typename T>        void ExportClassTmplMembers<T>::virtualInlineDecl() {}
+template<typename T>        void ExportClassTmplMembers<T>::staticDef() {}
+template<typename T> inline void ExportClassTmplMembers<T>::staticInlineDef() {}
+template<typename T>        void ExportClassTmplMembers<T>::staticInlineDecl() {}
+template<typename T>        void ExportClassTmplMembers<T>::protectedDef() {}
+template<typename T>        void ExportClassTmplMembers<T>::privateDef() {}
+
+template<typename T>        int  ExportClassTmplMembers<T>::StaticFieldDef;
+template<typename T> const  int  ExportClassTmplMembers<T>::StaticConstFieldDef = 1;
+template<typename T> constexpr int ExportClassTmplMembers<T>::ConstexprFieldDef;
+
+template struct ExportClassTmplMembers<ImplicitInst_Exported>;
+
+
+// Redeclarations cannot add dllexport.
+template<typename T>
+struct CTMR /*ClassTmplMemberRedecl*/ {
+                 void normalDef();         // expected-note{{previous declaration is here}}
+                 void normalInlineDef();   // expected-note{{previous declaration is here}}
+          inline void normalInlineDecl();  // expected-note{{previous declaration is here}}
+  virtual        void virtualDef();        // expected-note{{previous declaration is here}}
+  virtual        void virtualInlineDef();  // expected-note{{previous declaration is here}}
+  virtual inline void virtualInlineDecl(); // expected-note{{previous declaration is here}}
+  static         void staticDef();         // expected-note{{previous declaration is here}}
+  static         void staticInlineDef();   // expected-note{{previous declaration is here}}
+  static  inline void staticInlineDecl();  // expected-note{{previous declaration is here}}
+
+  static         int  StaticField;         // expected-note{{previous declaration is here}}
+  static  const  int  StaticConstField;    // expected-note{{previous declaration is here}}
+  constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
+};
+
+template<typename T> __declspec(dllexport)        void CTMR<T>::normalDef() {}         // expected-error{{redeclaration of 'CTMR::normalDef' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport) inline void CTMR<T>::normalInlineDef() {}   // expected-error{{redeclaration of 'CTMR::normalInlineDef' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport)        void CTMR<T>::normalInlineDecl() {}  // expected-error{{redeclaration of 'CTMR::normalInlineDecl' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport)        void CTMR<T>::virtualDef() {}        // expected-error{{redeclaration of 'CTMR::virtualDef' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport) inline void CTMR<T>::virtualInlineDef() {}  // expected-error{{redeclaration of 'CTMR::virtualInlineDef' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport)        void CTMR<T>::virtualInlineDecl() {} // expected-error{{redeclaration of 'CTMR::virtualInlineDecl' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport)        void CTMR<T>::staticDef() {}         // expected-error{{redeclaration of 'CTMR::staticDef' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport) inline void CTMR<T>::staticInlineDef() {}   // expected-error{{redeclaration of 'CTMR::staticInlineDef' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport)        void CTMR<T>::staticInlineDecl() {}  // expected-error{{redeclaration of 'CTMR::staticInlineDecl' cannot add 'dllexport' attribute}}
+
+template<typename T> __declspec(dllexport)        int  CTMR<T>::StaticField = 1;       // expected-error{{redeclaration of 'CTMR::StaticField' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport) const  int  CTMR<T>::StaticConstField = 1;  // expected-error{{redeclaration of 'CTMR::StaticConstField' cannot add 'dllexport' attribute}}
+template<typename T> __declspec(dllexport) constexpr int CTMR<T>::ConstexprField;      // expected-error{{redeclaration of 'CTMR::ConstexprField' cannot add 'dllexport' attribute}}
+
+
+
+//===----------------------------------------------------------------------===//
+// Class template member templates
+//===----------------------------------------------------------------------===//
+
+template<typename T>
+struct ExportClsTmplMemTmpl {
+  template<typename U> __declspec(dllexport)               void normalDecl();
+  template<typename U> __declspec(dllexport)               void normalDef();
+  template<typename U> __declspec(dllexport)               void normalInclass() {}
+  template<typename U> __declspec(dllexport)               void normalInlineDef();
+  template<typename U> __declspec(dllexport)        inline void normalInlineDecl();
+  template<typename U> __declspec(dllexport) static        void staticDecl();
+  template<typename U> __declspec(dllexport) static        void staticDef();
+  template<typename U> __declspec(dllexport) static        void staticInclass() {}
+  template<typename U> __declspec(dllexport) static        void staticInlineDef();
+  template<typename U> __declspec(dllexport) static inline void staticInlineDecl();
+
+#if __has_feature(cxx_variable_templates)
+  template<typename U> __declspec(dllexport) static        int  StaticField;
+  template<typename U> __declspec(dllexport) static        int  StaticFieldDef;
+  template<typename U> __declspec(dllexport) static const  int  StaticConstField;
+  template<typename U> __declspec(dllexport) static const  int  StaticConstFieldDef;
+  template<typename U> __declspec(dllexport) static const  int  StaticConstFieldEqualInit = 1;
+  template<typename U> __declspec(dllexport) static const  int  StaticConstFieldBraceInit{1};
+  template<typename U> __declspec(dllexport) constexpr static int ConstexprField = 1;
+  template<typename U> __declspec(dllexport) constexpr static int ConstexprFieldDef = 1;
+#endif // __has_feature(cxx_variable_templates)
+};
+
+template<typename T> template<typename U>        void ExportClsTmplMemTmpl<T>::normalDef() {}
+template<typename T> template<typename U> inline void ExportClsTmplMemTmpl<T>::normalInlineDef() {}
+template<typename T> template<typename U>        void ExportClsTmplMemTmpl<T>::normalInlineDecl() {}
+template<typename T> template<typename U>        void ExportClsTmplMemTmpl<T>::staticDef() {}
+template<typename T> template<typename U> inline void ExportClsTmplMemTmpl<T>::staticInlineDef() {}
+template<typename T> template<typename U>        void ExportClsTmplMemTmpl<T>::staticInlineDecl() {}
+
+#if __has_feature(cxx_variable_templates)
+template<typename T> template<typename U>        int  ExportClsTmplMemTmpl<T>::StaticFieldDef;
+template<typename T> template<typename U> const  int  ExportClsTmplMemTmpl<T>::StaticConstFieldDef = 1;
+template<typename T> template<typename U> constexpr int ExportClsTmplMemTmpl<T>::ConstexprFieldDef;
+#endif // __has_feature(cxx_variable_templates)
+
+
+// Redeclarations cannot add dllexport.
+template<typename T>
+struct CTMTR /*ClassTmplMemberTmplRedecl*/ {
+  template<typename U>               void normalDef();         // expected-note{{previous declaration is here}}
+  template<typename U>               void normalInlineDef();   // expected-note{{previous declaration is here}}
+  template<typename U>        inline void normalInlineDecl();  // expected-note{{previous declaration is here}}
+  template<typename U> static        void staticDef();         // expected-note{{previous declaration is here}}
+  template<typename U> static        void staticInlineDef();   // expected-note{{previous declaration is here}}
+  template<typename U> static inline void staticInlineDecl();  // expected-note{{previous declaration is here}}
+
+#if __has_feature(cxx_variable_templates)
+  template<typename U> static        int  StaticField;         // expected-note{{previous declaration is here}}
+  template<typename U> static const  int  StaticConstField;    // expected-note{{previous declaration is here}}
+  template<typename U> constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
+#endif // __has_feature(cxx_variable_templates)
+};
+
+template<typename T> template<typename U> __declspec(dllexport)        void CTMTR<T>::normalDef() {}         // expected-error{{redeclaration of 'CTMTR::normalDef' cannot add 'dllexport' attribute}}
+template<typename T> template<typename U> __declspec(dllexport) inline void CTMTR<T>::normalInlineDef() {}   // expected-error{{redeclaration of 'CTMTR::normalInlineDef' cannot add 'dllexport' attribute}}
+template<typename T> template<typename U> __declspec(dllexport)        void CTMTR<T>::normalInlineDecl() {}  // expected-error{{redeclaration of 'CTMTR::normalInlineDecl' cannot add 'dllexport' attribute}}
+template<typename T> template<typename U> __declspec(dllexport)        void CTMTR<T>::staticDef() {}         // expected-error{{redeclaration of 'CTMTR::staticDef' cannot add 'dllexport' attribute}}
+template<typename T> template<typename U> __declspec(dllexport) inline void CTMTR<T>::staticInlineDef() {}   // expected-error{{redeclaration of 'CTMTR::staticInlineDef' cannot add 'dllexport' attribute}}
+template<typename T> template<typename U> __declspec(dllexport)        void CTMTR<T>::staticInlineDecl() {}  // expected-error{{redeclaration of 'CTMTR::staticInlineDecl' cannot add 'dllexport' attribute}}
+
+#if __has_feature(cxx_variable_templates)
+template<typename T> template<typename U> __declspec(dllexport)        int  CTMTR<T>::StaticField = 1;       // expected-error{{redeclaration of 'CTMTR::StaticField' cannot add 'dllexport' attribute}}
+template<typename T> template<typename U> __declspec(dllexport) const  int  CTMTR<T>::StaticConstField = 1;  // expected-error{{redeclaration of 'CTMTR::StaticConstField' cannot add 'dllexport' attribute}}
+template<typename T> template<typename U> __declspec(dllexport) constexpr int CTMTR<T>::ConstexprField;      // expected-error{{redeclaration of 'CTMTR::ConstexprField' cannot add 'dllexport' attribute}}
+#endif // __has_feature(cxx_variable_templates)
+
+// FIXME: Precedence rules seem to be different for classes.
diff --git a/test/SemaCXX/dllimport.cpp b/test/SemaCXX/dllimport.cpp
new file mode 100644
index 0000000..7bd2ddc
--- /dev/null
+++ b/test/SemaCXX/dllimport.cpp
@@ -0,0 +1,1085 @@
+// RUN: %clang_cc1 -triple i686-win32     -fsyntax-only -verify -std=c++11 -DMS %s
+// RUN: %clang_cc1 -triple x86_64-win32   -fsyntax-only -verify -std=c++1y -DMS %s
+// RUN: %clang_cc1 -triple i686-mingw32   -fsyntax-only -verify -std=c++1y %s
+// RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -verify -std=c++11 %s
+
+// Helper structs to make templates more expressive.
+struct ImplicitInst_Imported {};
+struct ExplicitDecl_Imported {};
+struct ExplicitInst_Imported {};
+struct ExplicitSpec_Imported {};
+struct ExplicitSpec_Def_Imported {};
+struct ExplicitSpec_InlineDef_Imported {};
+struct ExplicitSpec_NotImported {};
+namespace { struct Internal {}; }
+
+
+// Invalid usage.
+__declspec(dllimport) typedef int typedef1; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
+typedef __declspec(dllimport) int typedef2; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
+typedef int __declspec(dllimport) typedef3; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
+typedef __declspec(dllimport) void (*FunTy)(); // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
+enum __declspec(dllimport) Enum {}; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
+#if __has_feature(cxx_strong_enums)
+  enum class __declspec(dllimport) EnumClass {}; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
+#endif
+
+
+
+//===----------------------------------------------------------------------===//
+// Globals
+//===----------------------------------------------------------------------===//
+
+// Import declaration.
+__declspec(dllimport) extern int ExternGlobalDecl;
+
+// dllimport implies a declaration.
+__declspec(dllimport) int GlobalDecl;
+int **__attribute__((dllimport))* GlobalDeclChunkAttr;
+int GlobalDeclAttr __attribute__((dllimport));
+
+// Not allowed on definitions.
+__declspec(dllimport) extern int ExternGlobalInit = 1; // expected-error{{definition of dllimport data}}
+__declspec(dllimport) int GlobalInit1 = 1; // expected-error{{definition of dllimport data}}
+int __declspec(dllimport) GlobalInit2 = 1; // expected-error{{definition of dllimport data}}
+
+// Declare, then reject definition.
+__declspec(dllimport) extern int ExternGlobalDeclInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+int ExternGlobalDeclInit = 1; // expected-warning{{'ExternGlobalDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+__declspec(dllimport) int GlobalDeclInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+int GlobalDeclInit = 1; // expected-warning{{'GlobalDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+int *__attribute__((dllimport)) GlobalDeclChunkAttrInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+int *GlobalDeclChunkAttrInit = 0; // expected-warning{{'GlobalDeclChunkAttrInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+int GlobalDeclAttrInit __attribute__((dllimport)); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+int GlobalDeclAttrInit = 1; // expected-warning{{'GlobalDeclAttrInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+// Redeclarations
+__declspec(dllimport) extern int GlobalRedecl1;
+__declspec(dllimport) extern int GlobalRedecl1;
+
+__declspec(dllimport) int GlobalRedecl2a;
+__declspec(dllimport) int GlobalRedecl2a;
+
+int *__attribute__((dllimport)) GlobalRedecl2b;
+int *__attribute__((dllimport)) GlobalRedecl2b;
+
+int GlobalRedecl2c __attribute__((dllimport));
+int GlobalRedecl2c __attribute__((dllimport));
+
+// NB: MSVC issues a warning and makes GlobalRedecl3 dllexport. We follow GCC
+// and drop the dllimport with a warning.
+__declspec(dllimport) extern int GlobalRedecl3; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+                      extern int GlobalRedecl3; // expected-warning{{'GlobalRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+                      extern int GlobalRedecl4; // expected-note{{previous declaration is here}}
+__declspec(dllimport) extern int GlobalRedecl4; // expected-warning{{redeclaration of 'GlobalRedecl4' should not add 'dllimport' attribute}}
+
+// External linkage is required.
+__declspec(dllimport) static int StaticGlobal; // expected-error{{'StaticGlobal' must have external linkage when declared 'dllimport'}}
+__declspec(dllimport) Internal InternalTypeGlobal; // expected-error{{'InternalTypeGlobal' must have external linkage when declared 'dllimport'}}
+namespace    { __declspec(dllimport) int InternalGlobal; } // expected-error{{'(anonymous namespace)::InternalGlobal' must have external linkage when declared 'dllimport'}}
+namespace ns { __declspec(dllimport) int ExternalGlobal; }
+
+__declspec(dllimport) auto InternalAutoTypeGlobal = Internal(); // expected-error{{'InternalAutoTypeGlobal' must have external linkage when declared 'dllimport'}}
+                                                                // expected-error@-1{{definition of dllimport data}}
+
+// Import in local scope.
+__declspec(dllimport) float LocalRedecl1; // expected-note{{previous definition is here}}
+__declspec(dllimport) float LocalRedecl2; // expected-note{{previous definition is here}}
+__declspec(dllimport) float LocalRedecl3; // expected-note{{previous definition is here}}
+void functionScope() {
+  __declspec(dllimport) int LocalRedecl1; // expected-error{{redefinition of 'LocalRedecl1' with a different type: 'int' vs 'float'}}
+  int *__attribute__((dllimport)) LocalRedecl2; // expected-error{{redefinition of 'LocalRedecl2' with a different type: 'int *' vs 'float'}}
+  int LocalRedecl3 __attribute__((dllimport)); // expected-error{{redefinition of 'LocalRedecl3' with a different type: 'int' vs 'float'}}
+
+  __declspec(dllimport)        int LocalVarDecl;
+  __declspec(dllimport)        int LocalVarDef = 1; // expected-error{{definition of dllimport data}}
+  __declspec(dllimport) extern int ExternLocalVarDecl;
+  __declspec(dllimport) extern int ExternLocalVarDef = 1; // expected-error{{definition of dllimport data}}
+  __declspec(dllimport) static int StaticLocalVar; // expected-error{{'StaticLocalVar' must have external linkage when declared 'dllimport'}}
+}
+
+
+
+//===----------------------------------------------------------------------===//
+// Variable templates
+//===----------------------------------------------------------------------===//
+#if __has_feature(cxx_variable_templates)
+
+// Import declaration.
+template<typename T> __declspec(dllimport) extern int ExternVarTmplDecl;
+
+// dllimport implies a declaration.
+template<typename T> __declspec(dllimport) int VarTmplDecl;
+
+// Not allowed on definitions.
+template<typename T> __declspec(dllimport) extern int ExternVarTmplInit = 1; // expected-error{{definition of dllimport data}}
+template<typename T> __declspec(dllimport) int VarTmplInit1 = 1; // expected-error{{definition of dllimport data}}
+template<typename T> int __declspec(dllimport) VarTmplInit2 = 1; // expected-error{{definition of dllimport data}}
+
+// Declare, then reject definition.
+template<typename T> __declspec(dllimport) extern int ExternVarTmplDeclInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+template<typename T>                              int ExternVarTmplDeclInit = 1; // expected-warning{{'ExternVarTmplDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+template<typename T> __declspec(dllimport) int VarTmplDeclInit; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+template<typename T>                       int VarTmplDeclInit = 1; // expected-warning{{'VarTmplDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+// Redeclarations
+template<typename T> __declspec(dllimport) extern int VarTmplRedecl1;
+template<typename T> __declspec(dllimport) extern int VarTmplRedecl1;
+
+template<typename T> __declspec(dllimport) int VarTmplRedecl2;
+template<typename T> __declspec(dllimport) int VarTmplRedecl2;
+
+template<typename T> __declspec(dllimport) extern int VarTmplRedecl3; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+template<typename T>                       extern int VarTmplRedecl3; // expected-warning{{'VarTmplRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+template<typename T>                       extern int VarTmplRedecl4; // expected-note{{previous declaration is here}}
+template<typename T> __declspec(dllimport) extern int VarTmplRedecl4; // expected-error{{redeclaration of 'VarTmplRedecl4' cannot add 'dllimport' attribute}}
+
+// External linkage is required.
+template<typename T> __declspec(dllimport) static int StaticVarTmpl; // expected-error{{'StaticVarTmpl' must have external linkage when declared 'dllimport'}}
+template<typename T> __declspec(dllimport) Internal InternalTypeVarTmpl; // expected-error{{'InternalTypeVarTmpl' must have external linkage when declared 'dllimport'}}
+namespace    { template<typename T> __declspec(dllimport) int InternalVarTmpl; } // expected-error{{'(anonymous namespace)::InternalVarTmpl' must have external linkage when declared 'dllimport'}}
+namespace ns { template<typename T> __declspec(dllimport) int ExternalVarTmpl; }
+
+template<typename T> __declspec(dllimport) auto InternalAutoTypeVarTmpl = Internal(); // expected-error{{definition of dllimport data}} // expected-error{{'InternalAutoTypeVarTmpl' must have external linkage when declared 'dllimport'}}
+
+
+template<typename T> int VarTmpl;
+template<typename T> __declspec(dllimport) int ImportedVarTmpl;
+
+// Import implicit instantiation of an imported variable template.
+int useVarTmpl() { return ImportedVarTmpl<ImplicitInst_Imported>; }
+
+// Import explicit instantiation declaration of an imported variable template.
+extern template int ImportedVarTmpl<ExplicitDecl_Imported>;
+
+// An explicit instantiation definition of an imported variable template cannot
+// be imported because the template must be defined which is illegal.
+
+// Import specialization of an imported variable template.
+template<> __declspec(dllimport) int ImportedVarTmpl<ExplicitSpec_Imported>;
+template<> __declspec(dllimport) int ImportedVarTmpl<ExplicitSpec_Def_Imported> = 1; // expected-error{{definition of dllimport data}}
+
+// Not importing specialization of an imported variable template without
+// explicit dllimport.
+template<> int ImportedVarTmpl<ExplicitSpec_NotImported>;
+
+
+// Import explicit instantiation declaration of a non-imported variable template.
+extern template __declspec(dllimport) int VarTmpl<ExplicitDecl_Imported>;
+
+// Import explicit instantiation definition of a non-imported variable template.
+template __declspec(dllimport) int VarTmpl<ExplicitInst_Imported>;
+
+// Import specialization of a non-imported variable template.
+template<> __declspec(dllimport) int VarTmpl<ExplicitSpec_Imported>;
+template<> __declspec(dllimport) int VarTmpl<ExplicitSpec_Def_Imported> = 1; // expected-error{{definition of dllimport data}}
+
+#endif // __has_feature(cxx_variable_templates)
+
+
+
+//===----------------------------------------------------------------------===//
+// Functions
+//===----------------------------------------------------------------------===//
+
+// Import function declaration. Check different placements.
+__attribute__((dllimport)) void decl1A(); // Sanity check with __attribute__
+__declspec(dllimport)      void decl1B();
+
+void __attribute__((dllimport)) decl2A();
+void __declspec(dllimport)      decl2B();
+
+// Not allowed on function definitions.
+__declspec(dllimport) void def() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
+
+// extern  "C"
+extern "C" __declspec(dllimport) void externC();
+
+// Import inline function.
+__declspec(dllimport) inline void inlineFunc1() {}
+inline void __attribute__((dllimport)) inlineFunc2() {}
+
+__declspec(dllimport) inline void inlineDecl();
+                             void inlineDecl() {}
+
+__declspec(dllimport) void inlineDef();
+               inline void inlineDef() {}
+
+// Redeclarations
+__declspec(dllimport) void redecl1();
+__declspec(dllimport) void redecl1();
+
+// NB: MSVC issues a warning and makes redecl2/redecl3 dllexport. We follow GCC
+// and drop the dllimport with a warning.
+__declspec(dllimport) void redecl2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+                      void redecl2(); // expected-warning{{'redecl2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+__declspec(dllimport) void redecl3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+                      void redecl3() {} // expected-warning{{'redecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+                      void redecl4(); // expected-note{{previous declaration is here}}
+__declspec(dllimport) void redecl4(); // expected-warning{{redeclaration of 'redecl4' should not add 'dllimport' attribute}}
+
+                      void redecl5(); // expected-note{{previous declaration is here}}
+__declspec(dllimport) inline void redecl5() {} // expected-warning{{redeclaration of 'redecl5' should not add 'dllimport' attribute}}
+
+// Friend functions
+struct FuncFriend {
+  friend __declspec(dllimport) void friend1();
+  friend __declspec(dllimport) void friend2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+  friend __declspec(dllimport) void friend3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+  friend                       void friend4(); // expected-note{{previous declaration is here}}
+  friend                       void friend5(); // expected-note{{previous declaration is here}}
+};
+__declspec(dllimport) void friend1();
+                      void friend2(); // expected-warning{{'friend2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+                      void friend3() {} // expected-warning{{'friend3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+__declspec(dllimport) void friend4(); // expected-warning{{redeclaration of 'friend4' should not add 'dllimport' attribute}}
+__declspec(dllimport) inline void friend5() {} // expected-warning{{redeclaration of 'friend5' should not add 'dllimport' attribute}}
+
+// Implicit declarations can be redeclared with dllimport.
+__declspec(dllimport) void* operator new(__SIZE_TYPE__ n);
+
+// External linkage is required.
+__declspec(dllimport) static int staticFunc(); // expected-error{{'staticFunc' must have external linkage when declared 'dllimport'}}
+__declspec(dllimport) Internal internalRetFunc(); // expected-error{{'internalRetFunc' must have external linkage when declared 'dllimport'}}
+namespace    { __declspec(dllimport) void internalFunc(); } // expected-error{{'(anonymous namespace)::internalFunc' must have external linkage when declared 'dllimport'}}
+namespace ns { __declspec(dllimport) void externalFunc(); }
+
+// Import deleted functions.
+// FIXME: Deleted functions are definitions so a missing inline is diagnosed
+// here which is irrelevant. But because the delete keyword is parsed later
+// there is currently no straight-forward way to avoid this diagnostic.
+__declspec(dllimport) void deletedFunc() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}} expected-error{{dllimport cannot be applied to non-inline function definition}}
+__declspec(dllimport) inline void deletedInlineFunc() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
+
+
+
+//===----------------------------------------------------------------------===//
+// Function templates
+//===----------------------------------------------------------------------===//
+
+// Import function template declaration. Check different placements.
+template<typename T> __declspec(dllimport) void funcTmplDecl1();
+template<typename T> void __declspec(dllimport) funcTmplDecl2();
+
+// Import function template definition.
+template<typename T> __declspec(dllimport) void funcTmplDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
+
+// Import inline function template.
+template<typename T> __declspec(dllimport) inline void inlineFuncTmpl1() {}
+template<typename T> inline void __attribute__((dllimport)) inlineFuncTmpl2() {}
+
+template<typename T> __declspec(dllimport) inline void inlineFuncTmplDecl();
+template<typename T>                              void inlineFuncTmplDecl() {}
+
+template<typename T> __declspec(dllimport) void inlineFuncTmplDef();
+template<typename T>                inline void inlineFuncTmplDef() {}
+
+// Redeclarations
+template<typename T> __declspec(dllimport) void funcTmplRedecl1();
+template<typename T> __declspec(dllimport) void funcTmplRedecl1();
+
+template<typename T> __declspec(dllimport) void funcTmplRedecl2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+template<typename T>                       void funcTmplRedecl2(); // expected-warning{{'funcTmplRedecl2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+template<typename T> __declspec(dllimport) void funcTmplRedecl3(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+template<typename T>                       void funcTmplRedecl3() {} // expected-warning{{'funcTmplRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+template<typename T>                       void funcTmplRedecl4(); // expected-note{{previous declaration is here}}
+template<typename T> __declspec(dllimport) void funcTmplRedecl4(); // expected-error{{redeclaration of 'funcTmplRedecl4' cannot add 'dllimport' attribute}}
+
+template<typename T>                       void funcTmplRedecl5(); // expected-note{{previous declaration is here}}
+template<typename T> __declspec(dllimport) inline void funcTmplRedecl5() {} // expected-error{{redeclaration of 'funcTmplRedecl5' cannot add 'dllimport' attribute}}
+
+// Function template friends
+struct FuncTmplFriend {
+  template<typename T> friend __declspec(dllimport) void funcTmplFriend1();
+  template<typename T> friend __declspec(dllimport) void funcTmplFriend2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+  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}}
+  template<typename T> friend __declspec(dllimport) inline void funcTmplFriend5();
+};
+template<typename T> __declspec(dllimport) void funcTmplFriend1();
+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}}
+template<typename T>                       inline void funcTmplFriend5() {}
+
+// External linkage is required.
+template<typename T> __declspec(dllimport) static int staticFuncTmpl(); // expected-error{{'staticFuncTmpl' must have external linkage when declared 'dllimport'}}
+template<typename T> __declspec(dllimport) Internal internalRetFuncTmpl(); // expected-error{{'internalRetFuncTmpl' must have external linkage when declared 'dllimport'}}
+namespace    { template<typename T> __declspec(dllimport) void internalFuncTmpl(); } // expected-error{{'(anonymous namespace)::internalFuncTmpl' must have external linkage when declared 'dllimport'}}
+namespace ns { template<typename T> __declspec(dllimport) void externalFuncTmpl(); }
+
+
+template<typename T> void funcTmpl() {}
+template<typename T> inline void inlineFuncTmpl() {}
+template<typename T> __declspec(dllimport) void importedFuncTmplDecl();
+template<typename T> __declspec(dllimport) inline void importedFuncTmpl() {}
+
+// Import implicit instantiation of an imported function template.
+void useFunTmplDecl() { importedFuncTmplDecl<ImplicitInst_Imported>(); }
+void useFunTmplDef() { importedFuncTmpl<ImplicitInst_Imported>(); }
+
+// Import explicit instantiation declaration of an imported function template.
+extern template void importedFuncTmpl<ExplicitDecl_Imported>();
+
+// Import explicit instantiation definition of an imported function template.
+// NB: MSVC fails this instantiation without explicit dllimport which is most
+// likely a bug because an implicit instantiation is accepted.
+template void importedFuncTmpl<ExplicitInst_Imported>();
+
+// Import specialization of an imported function template. A definition must be
+// declared inline.
+template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Imported>();
+template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Def_Imported>() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
+template<> __declspec(dllimport) inline void importedFuncTmpl<ExplicitSpec_InlineDef_Imported>() {}
+
+// Not importing specialization of an imported function template without
+// explicit dllimport.
+template<> void importedFuncTmpl<ExplicitSpec_NotImported>() {}
+
+
+// Import explicit instantiation declaration of a non-imported function template.
+extern template __declspec(dllimport) void funcTmpl<ExplicitDecl_Imported>();
+extern template __declspec(dllimport) void inlineFuncTmpl<ExplicitDecl_Imported>();
+
+// Import explicit instantiation definition of a non-imported function template.
+template __declspec(dllimport) void funcTmpl<ExplicitInst_Imported>();
+template __declspec(dllimport) void inlineFuncTmpl<ExplicitInst_Imported>();
+
+// Import specialization of a non-imported function template. A definition must
+// be declared inline.
+template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Imported>();
+template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Def_Imported>() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
+template<> __declspec(dllimport) inline void funcTmpl<ExplicitSpec_InlineDef_Imported>() {}
+
+
+//===----------------------------------------------------------------------===//
+// Class members
+//===----------------------------------------------------------------------===//
+
+// Import individual members of a class.
+struct ImportMembers {
+  struct Nested {
+    __declspec(dllimport) void normalDecl();
+    __declspec(dllimport) void normalDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+  };
+
+  __declspec(dllimport)                void normalDecl();
+  __declspec(dllimport)                void normalDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+  __declspec(dllimport)                void normalInclass() {}
+  __declspec(dllimport)                void normalInlineDef();
+  __declspec(dllimport)         inline void normalInlineDecl();
+  __declspec(dllimport) virtual        void virtualDecl();
+  __declspec(dllimport) virtual        void virtualDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+  __declspec(dllimport) virtual        void virtualInclass() {}
+  __declspec(dllimport) virtual        void virtualInlineDef();
+  __declspec(dllimport) virtual inline void virtualInlineDecl();
+  __declspec(dllimport) static         void staticDecl();
+  __declspec(dllimport) static         void staticDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+  __declspec(dllimport) static         void staticInclass() {}
+  __declspec(dllimport) static         void staticInlineDef();
+  __declspec(dllimport) static  inline void staticInlineDecl();
+
+protected:
+  __declspec(dllimport)                void protectedDecl();
+private:
+  __declspec(dllimport)                void privateDecl();
+public:
+
+  __declspec(dllimport)                int  Field; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
+  __declspec(dllimport) static         int  StaticField;
+  __declspec(dllimport) static         int  StaticFieldDef; // expected-note{{attribute is here}}
+  __declspec(dllimport) static  const  int  StaticConstField;
+  __declspec(dllimport) static  const  int  StaticConstFieldDef; // expected-note{{attribute is here}}
+  __declspec(dllimport) static  const  int  StaticConstFieldEqualInit = 1;
+  __declspec(dllimport) static  const  int  StaticConstFieldBraceInit{1};
+  __declspec(dllimport) constexpr static int ConstexprField = 1;
+  __declspec(dllimport) constexpr static int ConstexprFieldDef = 1; // expected-note{{attribute is here}}
+};
+
+       void ImportMembers::Nested::normalDef() {} // expected-warning{{'ImportMembers::Nested::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+       void ImportMembers::normalDef() {} // expected-warning{{'ImportMembers::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+inline void ImportMembers::normalInlineDef() {}
+       void ImportMembers::normalInlineDecl() {}
+       void ImportMembers::virtualDef() {} // expected-warning{{'ImportMembers::virtualDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+inline void ImportMembers::virtualInlineDef() {}
+       void ImportMembers::virtualInlineDecl() {}
+       void ImportMembers::staticDef() {} // expected-warning{{'ImportMembers::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+inline void ImportMembers::staticInlineDef() {}
+       void ImportMembers::staticInlineDecl() {}
+
+       int  ImportMembers::StaticFieldDef; // expected-error{{definition of dllimport static field not allowed}}
+const  int  ImportMembers::StaticConstFieldDef = 1; // expected-error{{definition of dllimport static field not allowed}}
+constexpr int ImportMembers::ConstexprFieldDef; // expected-error{{definition of dllimport static field not allowed}}
+
+
+// Import on member definitions.
+struct ImportMemberDefs {
+  __declspec(dllimport)                void normalDef();
+  __declspec(dllimport)                void normalInlineDef();
+  __declspec(dllimport)         inline void normalInlineDecl();
+  __declspec(dllimport) virtual        void virtualDef();
+  __declspec(dllimport) virtual        void virtualInlineDef();
+  __declspec(dllimport) virtual inline void virtualInlineDecl();
+  __declspec(dllimport) static         void staticDef();
+  __declspec(dllimport) static         void staticInlineDef();
+  __declspec(dllimport) static  inline void staticInlineDecl();
+
+  __declspec(dllimport) static         int  StaticField;
+  __declspec(dllimport) static  const  int  StaticConstField;
+  __declspec(dllimport) constexpr static int ConstexprField = 1;
+};
+
+__declspec(dllimport)        void ImportMemberDefs::normalDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
+__declspec(dllimport) inline void ImportMemberDefs::normalInlineDef() {}
+__declspec(dllimport)        void ImportMemberDefs::normalInlineDecl() {}
+__declspec(dllimport)        void ImportMemberDefs::virtualDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
+__declspec(dllimport) inline void ImportMemberDefs::virtualInlineDef() {}
+__declspec(dllimport)        void ImportMemberDefs::virtualInlineDecl() {}
+__declspec(dllimport)        void ImportMemberDefs::staticDef() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
+__declspec(dllimport) inline void ImportMemberDefs::staticInlineDef() {}
+__declspec(dllimport)        void ImportMemberDefs::staticInlineDecl() {}
+
+__declspec(dllimport)        int  ImportMemberDefs::StaticField; // expected-error{{definition of dllimport static field not allowed}} expected-note{{attribute is here}}
+__declspec(dllimport) const  int  ImportMemberDefs::StaticConstField = 1; // expected-error{{definition of dllimport static field not allowed}} expected-note{{attribute is here}}
+__declspec(dllimport) constexpr int ImportMemberDefs::ConstexprField; // expected-error{{definition of dllimport static field not allowed}} expected-note{{attribute is here}}
+
+
+// Import special member functions.
+struct ImportSpecials {
+  __declspec(dllimport) ImportSpecials();
+  __declspec(dllimport) ~ImportSpecials();
+  __declspec(dllimport) ImportSpecials(const ImportSpecials&);
+  __declspec(dllimport) ImportSpecials& operator=(const ImportSpecials&);
+  __declspec(dllimport) ImportSpecials(ImportSpecials&&);
+  __declspec(dllimport) ImportSpecials& operator=(ImportSpecials&&);
+};
+
+
+// Import deleted member functions.
+struct ImportDeleted {
+  __declspec(dllimport) ImportDeleted() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
+  __declspec(dllimport) ~ImportDeleted() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
+  __declspec(dllimport) ImportDeleted(const ImportDeleted&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
+  __declspec(dllimport) ImportDeleted& operator=(const ImportDeleted&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
+  __declspec(dllimport) ImportDeleted(ImportDeleted&&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
+  __declspec(dllimport) ImportDeleted& operator=(ImportDeleted&&) = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
+  __declspec(dllimport) void deleted() = delete; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
+};
+
+
+// Import allocation functions.
+struct ImportAlloc {
+  __declspec(dllimport) void* operator new(__SIZE_TYPE__);
+  __declspec(dllimport) void* operator new[](__SIZE_TYPE__);
+  __declspec(dllimport) void operator delete(void*);
+  __declspec(dllimport) void operator delete[](void*);
+};
+
+
+// Import defaulted member functions.
+struct ImportDefaulted {
+  __declspec(dllimport) ImportDefaulted() = default;
+  __declspec(dllimport) ~ImportDefaulted() = default;
+  __declspec(dllimport) ImportDefaulted(const ImportDefaulted&) = default;
+  __declspec(dllimport) ImportDefaulted& operator=(const ImportDefaulted&) = default;
+  __declspec(dllimport) ImportDefaulted(ImportDefaulted&&) = default;
+  __declspec(dllimport) ImportDefaulted& operator=(ImportDefaulted&&) = default;
+};
+
+
+// Import defaulted member function definitions.
+struct ImportDefaultedDefs {
+  __declspec(dllimport) ImportDefaultedDefs();
+  __declspec(dllimport) ~ImportDefaultedDefs(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+
+  __declspec(dllimport) inline ImportDefaultedDefs(const ImportDefaultedDefs&);
+  __declspec(dllimport) ImportDefaultedDefs& operator=(const ImportDefaultedDefs&);
+
+  __declspec(dllimport) ImportDefaultedDefs(ImportDefaultedDefs&&);
+  __declspec(dllimport) ImportDefaultedDefs& operator=(ImportDefaultedDefs&&); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+};
+
+// Not allowed on definitions.
+__declspec(dllimport) ImportDefaultedDefs::ImportDefaultedDefs() = default; // expected-error{{dllimport cannot be applied to non-inline function definition}}
+
+// dllimport cannot be dropped.
+ImportDefaultedDefs::~ImportDefaultedDefs() = default; // expected-warning{{'ImportDefaultedDefs::~ImportDefaultedDefs' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+// Import inline declaration and definition.
+__declspec(dllimport) ImportDefaultedDefs::ImportDefaultedDefs(const ImportDefaultedDefs&) = default;
+inline ImportDefaultedDefs& ImportDefaultedDefs::operator=(const ImportDefaultedDefs&) = default;
+
+__declspec(dllimport) ImportDefaultedDefs::ImportDefaultedDefs(ImportDefaultedDefs&&) = default; // expected-error{{dllimport cannot be applied to non-inline function definition}}
+ImportDefaultedDefs& ImportDefaultedDefs::operator=(ImportDefaultedDefs&&) = default; // expected-warning{{'ImportDefaultedDefs::operator=' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+
+
+// Redeclarations cannot add dllimport.
+struct MemberRedecl {
+                 void normalDef();         // expected-note{{previous declaration is here}}
+                 void normalInlineDef();   // expected-note{{previous declaration is here}}
+          inline void normalInlineDecl();  // expected-note{{previous declaration is here}}
+  virtual        void virtualDef();        // expected-note{{previous declaration is here}}
+  virtual        void virtualInlineDef();  // expected-note{{previous declaration is here}}
+  virtual inline void virtualInlineDecl(); // expected-note{{previous declaration is here}}
+  static         void staticDef();         // expected-note{{previous declaration is here}}
+  static         void staticInlineDef();   // expected-note{{previous declaration is here}}
+  static  inline void staticInlineDecl();  // expected-note{{previous declaration is here}}
+
+  static         int  StaticField;         // expected-note{{previous declaration is here}}
+  static  const  int  StaticConstField;    // expected-note{{previous declaration is here}}
+  constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
+};
+
+__declspec(dllimport)        void MemberRedecl::normalDef() {}         // expected-error{{redeclaration of 'MemberRedecl::normalDef' cannot add 'dllimport' attribute}}
+                                                                       // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
+__declspec(dllimport) inline void MemberRedecl::normalInlineDef() {}   // expected-error{{redeclaration of 'MemberRedecl::normalInlineDef' cannot add 'dllimport' attribute}}
+__declspec(dllimport)        void MemberRedecl::normalInlineDecl() {}  // expected-error{{redeclaration of 'MemberRedecl::normalInlineDecl' cannot add 'dllimport' attribute}}
+__declspec(dllimport)        void MemberRedecl::virtualDef() {}        // expected-error{{redeclaration of 'MemberRedecl::virtualDef' cannot add 'dllimport' attribute}}
+                                                                       // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
+__declspec(dllimport) inline void MemberRedecl::virtualInlineDef() {}  // expected-error{{redeclaration of 'MemberRedecl::virtualInlineDef' cannot add 'dllimport' attribute}}
+__declspec(dllimport)        void MemberRedecl::virtualInlineDecl() {} // expected-error{{redeclaration of 'MemberRedecl::virtualInlineDecl' cannot add 'dllimport' attribute}}
+__declspec(dllimport)        void MemberRedecl::staticDef() {}         // expected-error{{redeclaration of 'MemberRedecl::staticDef' cannot add 'dllimport' attribute}}
+                                                                       // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
+__declspec(dllimport) inline void MemberRedecl::staticInlineDef() {}   // expected-error{{redeclaration of 'MemberRedecl::staticInlineDef' cannot add 'dllimport' attribute}}
+__declspec(dllimport)        void MemberRedecl::staticInlineDecl() {}  // expected-error{{redeclaration of 'MemberRedecl::staticInlineDecl' cannot add 'dllimport' attribute}}
+
+__declspec(dllimport)        int  MemberRedecl::StaticField = 1;       // expected-error{{redeclaration of 'MemberRedecl::StaticField' cannot add 'dllimport' attribute}}
+                                                                       // expected-error@-1{{definition of dllimport static field not allowed}}
+                                                                       // expected-note@-2{{attribute is here}}
+__declspec(dllimport) const  int  MemberRedecl::StaticConstField = 1;  // expected-error{{redeclaration of 'MemberRedecl::StaticConstField' cannot add 'dllimport' attribute}}
+                                                                       // expected-error@-1{{definition of dllimport static field not allowed}}
+                                                                       // expected-note@-2{{attribute is here}}
+__declspec(dllimport) constexpr int MemberRedecl::ConstexprField;      // expected-error{{redeclaration of 'MemberRedecl::ConstexprField' cannot add 'dllimport' attribute}}
+                                                                       // expected-error@-1{{definition of dllimport static field not allowed}}
+                                                                       // expected-note@-2{{attribute is here}}
+
+
+
+//===----------------------------------------------------------------------===//
+// Class member templates
+//===----------------------------------------------------------------------===//
+
+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}}
+  template<typename T> __declspec(dllimport)               void normalInclass() {}
+  template<typename T> __declspec(dllimport)               void normalInlineDef();
+  template<typename T> __declspec(dllimport)        inline void normalInlineDecl();
+  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}}
+  template<typename T> __declspec(dllimport) static        void staticInclass() {}
+  template<typename T> __declspec(dllimport) static        void staticInlineDef();
+  template<typename T> __declspec(dllimport) static inline void staticInlineDecl();
+
+#if __has_feature(cxx_variable_templates)
+  template<typename T> __declspec(dllimport) static        int  StaticField;
+  template<typename T> __declspec(dllimport) static        int  StaticFieldDef; // expected-note{{attribute is here}}
+  template<typename T> __declspec(dllimport) static const  int  StaticConstField;
+  template<typename T> __declspec(dllimport) static const  int  StaticConstFieldDef; // expected-note{{attribute is here}}
+  template<typename T> __declspec(dllimport) static const  int  StaticConstFieldEqualInit = 1;
+  template<typename T> __declspec(dllimport) static const  int  StaticConstFieldBraceInit{1};
+  template<typename T> __declspec(dllimport) constexpr static int ConstexprField = 1;
+  template<typename T> __declspec(dllimport) constexpr static int ConstexprFieldDef = 1; // expected-note{{attribute is here}}
+#endif // __has_feature(cxx_variable_templates)
+};
+
+template<typename T>        void ImportMemberTmpl::normalDef() {} // expected-warning{{'ImportMemberTmpl::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+template<typename T> inline void ImportMemberTmpl::normalInlineDef() {}
+template<typename T>        void ImportMemberTmpl::normalInlineDecl() {}
+template<typename T>        void ImportMemberTmpl::staticDef() {} // expected-warning{{'ImportMemberTmpl::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+template<typename T> inline void ImportMemberTmpl::staticInlineDef() {}
+template<typename T>        void ImportMemberTmpl::staticInlineDecl() {}
+
+#if __has_feature(cxx_variable_templates)
+template<typename T>        int  ImportMemberTmpl::StaticFieldDef; // expected-error{{definition of dllimport static field not allowed}}
+template<typename T> const  int  ImportMemberTmpl::StaticConstFieldDef = 1; // expected-error{{definition of dllimport static field not allowed}}
+template<typename T> constexpr int ImportMemberTmpl::ConstexprFieldDef; // expected-error{{definition of dllimport static field not allowed}}
+#endif // __has_feature(cxx_variable_templates)
+
+
+// Redeclarations cannot add dllimport.
+struct MemTmplRedecl {
+  template<typename T>               void normalDef();         // expected-note{{previous declaration is here}}
+  template<typename T>               void normalInlineDef();   // expected-note{{previous declaration is here}}
+  template<typename T>        inline void normalInlineDecl();  // expected-note{{previous declaration is here}}
+  template<typename T> static        void staticDef();         // expected-note{{previous declaration is here}}
+  template<typename T> static        void staticInlineDef();   // expected-note{{previous declaration is here}}
+  template<typename T> static inline void staticInlineDecl();  // expected-note{{previous declaration is here}}
+
+#if __has_feature(cxx_variable_templates)
+  template<typename T> static        int  StaticField;         // expected-note{{previous declaration is here}}
+  template<typename T> static const  int  StaticConstField;    // expected-note{{previous declaration is here}}
+  template<typename T> constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
+#endif // __has_feature(cxx_variable_templates)
+};
+
+template<typename T> __declspec(dllimport)        void MemTmplRedecl::normalDef() {}        // expected-error{{redeclaration of 'MemTmplRedecl::normalDef' cannot add 'dllimport' attribute}}
+                                                                                            // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
+template<typename T> __declspec(dllimport) inline void MemTmplRedecl::normalInlineDef() {}  // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDef' cannot add 'dllimport' attribute}}
+template<typename T> __declspec(dllimport)        void MemTmplRedecl::normalInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDecl' cannot add 'dllimport' attribute}}
+template<typename T> __declspec(dllimport)        void MemTmplRedecl::staticDef() {}        // expected-error{{redeclaration of 'MemTmplRedecl::staticDef' cannot add 'dllimport' attribute}}
+                                                                                            // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
+template<typename T> __declspec(dllimport) inline void MemTmplRedecl::staticInlineDef() {}  // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDef' cannot add 'dllimport' attribute}}
+template<typename T> __declspec(dllimport)        void MemTmplRedecl::staticInlineDecl() {} // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDecl' cannot add 'dllimport' attribute}}
+
+#if __has_feature(cxx_variable_templates)
+template<typename T> __declspec(dllimport)        int  MemTmplRedecl::StaticField = 1;      // expected-error{{redeclaration of 'MemTmplRedecl::StaticField' cannot add 'dllimport' attribute}}
+                                                                                            // expected-error@-1{{definition of dllimport static field not allowed}}
+                                                                                            // expected-note@-2{{attribute is here}}
+template<typename T> __declspec(dllimport) const  int  MemTmplRedecl::StaticConstField = 1; // expected-error{{redeclaration of 'MemTmplRedecl::StaticConstField' cannot add 'dllimport' attribute}}
+                                                                                            // expected-error@-1{{definition of dllimport static field not allowed}}
+                                                                                            // expected-note@-2{{attribute is here}}
+template<typename T> __declspec(dllimport) constexpr int MemTmplRedecl::ConstexprField;     // expected-error{{redeclaration of 'MemTmplRedecl::ConstexprField' cannot add 'dllimport' attribute}}
+                                                                                            // expected-error@-1{{definition of dllimport static field not allowed}}
+                                                                                            // expected-note@-2{{attribute is here}}
+#endif // __has_feature(cxx_variable_templates)
+
+
+
+struct MemFunTmpl {
+  template<typename T>                              void normalDef() {}
+  template<typename T> __declspec(dllimport)        void importedNormal() {}
+  template<typename T>                       static void staticDef() {}
+  template<typename T> __declspec(dllimport) static void importedStatic() {}
+};
+
+// Import implicit instantiation of an imported member function template.
+void useMemFunTmpl() {
+  MemFunTmpl().importedNormal<ImplicitInst_Imported>();
+  MemFunTmpl().importedStatic<ImplicitInst_Imported>();
+}
+
+// Import explicit instantiation declaration of an imported member function
+// template.
+extern template void MemFunTmpl::importedNormal<ExplicitDecl_Imported>();
+extern template void MemFunTmpl::importedStatic<ExplicitDecl_Imported>();
+
+// Import explicit instantiation definition of an imported member function
+// template.
+// NB: MSVC fails this instantiation without explicit dllimport.
+template void MemFunTmpl::importedNormal<ExplicitInst_Imported>();
+template void MemFunTmpl::importedStatic<ExplicitInst_Imported>();
+
+// Import specialization of an imported member function template.
+template<> __declspec(dllimport) void MemFunTmpl::importedNormal<ExplicitSpec_Imported>();
+template<> __declspec(dllimport) void MemFunTmpl::importedNormal<ExplicitSpec_Def_Imported>() {} // error on mingw
+template<> __declspec(dllimport) inline void MemFunTmpl::importedNormal<ExplicitSpec_InlineDef_Imported>() {}
+#ifndef MSABI
+// expected-error@-3{{dllimport cannot be applied to non-inline function definition}}
+#endif
+
+template<> __declspec(dllimport) void MemFunTmpl::importedStatic<ExplicitSpec_Imported>();
+template<> __declspec(dllimport) void MemFunTmpl::importedStatic<ExplicitSpec_Def_Imported>() {} // error on mingw
+template<> __declspec(dllimport) inline void MemFunTmpl::importedStatic<ExplicitSpec_InlineDef_Imported>() {}
+#ifndef MSABI
+// expected-error@-3{{dllimport cannot be applied to non-inline function definition}}
+#endif
+
+// Not importing specialization of an imported member function template without
+// explicit dllimport.
+template<> void MemFunTmpl::importedNormal<ExplicitSpec_NotImported>() {}
+template<> void MemFunTmpl::importedStatic<ExplicitSpec_NotImported>() {}
+
+
+// Import explicit instantiation declaration of a non-imported member function
+// template.
+extern template __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitDecl_Imported>();
+extern template __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitDecl_Imported>();
+
+// Import explicit instantiation definition of a non-imported member function
+// template.
+template __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitInst_Imported>();
+template __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitInst_Imported>();
+
+// Import specialization of a non-imported member function template.
+template<> __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitSpec_Imported>();
+template<> __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitSpec_Def_Imported>() {} // error on mingw
+template<> __declspec(dllimport) inline void MemFunTmpl::normalDef<ExplicitSpec_InlineDef_Imported>() {}
+#ifndef MSABI
+// expected-error@-3{{dllimport cannot be applied to non-inline function definition}}
+#endif
+
+template<> __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitSpec_Imported>();
+template<> __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitSpec_Def_Imported>() {} // error on mingw
+template<> __declspec(dllimport) inline void MemFunTmpl::staticDef<ExplicitSpec_InlineDef_Imported>() {}
+#ifndef MSABI
+// expected-error@-3{{dllimport cannot be applied to non-inline function definition}}
+#endif
+
+
+
+#if __has_feature(cxx_variable_templates)
+struct MemVarTmpl {
+  template<typename T>                       static const int StaticVar = 1;
+  template<typename T> __declspec(dllimport) static const int ImportedStaticVar = 1;
+};
+
+// Import implicit instantiation of an imported member variable template.
+int useMemVarTmpl() { return MemVarTmpl::ImportedStaticVar<ImplicitInst_Imported>; }
+
+// Import explicit instantiation declaration of an imported member variable
+// template.
+extern template const int MemVarTmpl::ImportedStaticVar<ExplicitDecl_Imported>;
+
+// An explicit instantiation definition of an imported member variable template
+// cannot be imported because the template must be defined which is illegal. The
+// in-class initializer does not count.
+
+// Import specialization of an imported member variable template.
+template<> __declspec(dllimport) const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_Imported>;
+template<> __declspec(dllimport) const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_Def_Imported> = 1;
+                                                                                // expected-error@-1{{definition of dllimport static field not allowed}}
+                                                                                // expected-note@-2{{attribute is here}}
+
+// Not importing specialization of a member variable template without explicit
+// dllimport.
+template<> const int MemVarTmpl::ImportedStaticVar<ExplicitSpec_NotImported>;
+
+
+// Import explicit instantiation declaration of a non-imported member variable
+// template.
+extern template __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitDecl_Imported>;
+
+// An explicit instantiation definition of a non-imported member variable template
+// cannot be imported because the template must be defined which is illegal. The
+// in-class initializer does not count.
+
+// Import specialization of a non-imported member variable template.
+template<> __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitSpec_Imported>;
+template<> __declspec(dllimport) const int MemVarTmpl::StaticVar<ExplicitSpec_Def_Imported> = 1;
+                                                                                // expected-error@-1{{definition of dllimport static field not allowed}}
+                                                                                // expected-note@-2{{attribute is here}}
+
+#endif // __has_feature(cxx_variable_templates)
+
+
+
+//===----------------------------------------------------------------------===//
+// Class template members
+//===----------------------------------------------------------------------===//
+
+// Import individual members of a class template.
+template<typename T>
+struct ImportClassTmplMembers {
+  __declspec(dllimport)                void normalDecl();
+  __declspec(dllimport)                void normalDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+  __declspec(dllimport)                void normalInclass() {}
+  __declspec(dllimport)                void normalInlineDef();
+  __declspec(dllimport)         inline void normalInlineDecl();
+  __declspec(dllimport) virtual        void virtualDecl();
+  __declspec(dllimport) virtual        void virtualDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+  __declspec(dllimport) virtual        void virtualInclass() {}
+  __declspec(dllimport) virtual        void virtualInlineDef();
+  __declspec(dllimport) virtual inline void virtualInlineDecl();
+  __declspec(dllimport) static         void staticDecl();
+  __declspec(dllimport) static         void staticDef(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
+  __declspec(dllimport) static         void staticInclass() {}
+  __declspec(dllimport) static         void staticInlineDef();
+  __declspec(dllimport) static  inline void staticInlineDecl();
+
+protected:
+  __declspec(dllimport)                void protectedDecl();
+private:
+  __declspec(dllimport)                void privateDecl();
+public:
+
+  __declspec(dllimport)                int  Field; // expected-warning{{'dllimport' attribute only applies to variables, functions and classes}}
+  __declspec(dllimport) static         int  StaticField;
+  __declspec(dllimport) static         int  StaticFieldDef; // expected-note{{attribute is here}}
+  __declspec(dllimport) static  const  int  StaticConstField;
+  __declspec(dllimport) static  const  int  StaticConstFieldDef; // expected-note{{attribute is here}}
+  __declspec(dllimport) static  const  int  StaticConstFieldEqualInit = 1;
+  __declspec(dllimport) static  const  int  StaticConstFieldBraceInit{1};
+  __declspec(dllimport) constexpr static int ConstexprField = 1;
+  __declspec(dllimport) constexpr static int ConstexprFieldDef = 1; // expected-note{{attribute is here}}
+};
+
+// NB: MSVC is inconsistent here and disallows *InlineDef on class templates,
+// but allows it on classes. We allow both.
+template<typename T>        void ImportClassTmplMembers<T>::normalDef() {} // expected-warning{{'ImportClassTmplMembers::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+template<typename T> inline void ImportClassTmplMembers<T>::normalInlineDef() {}
+template<typename T>        void ImportClassTmplMembers<T>::normalInlineDecl() {}
+template<typename T>        void ImportClassTmplMembers<T>::virtualDef() {} // expected-warning{{'ImportClassTmplMembers::virtualDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+template<typename T> inline void ImportClassTmplMembers<T>::virtualInlineDef() {}
+template<typename T>        void ImportClassTmplMembers<T>::virtualInlineDecl() {}
+template<typename T>        void ImportClassTmplMembers<T>::staticDef() {} // expected-warning{{'ImportClassTmplMembers::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+template<typename T> inline void ImportClassTmplMembers<T>::staticInlineDef() {}
+template<typename T>        void ImportClassTmplMembers<T>::staticInlineDecl() {}
+
+template<typename T>        int  ImportClassTmplMembers<T>::StaticFieldDef; // expected-warning{{definition of dllimport static field}}
+template<typename T> const  int  ImportClassTmplMembers<T>::StaticConstFieldDef = 1; // expected-warning{{definition of dllimport static field}}
+template<typename T> constexpr int ImportClassTmplMembers<T>::ConstexprFieldDef; // expected-warning{{definition of dllimport static field}}
+
+
+// Redeclarations cannot add dllimport.
+template<typename T>
+struct CTMR /*ClassTmplMemberRedecl*/ {
+                 void normalDef();         // expected-note{{previous declaration is here}}
+                 void normalInlineDef();   // expected-note{{previous declaration is here}}
+          inline void normalInlineDecl();  // expected-note{{previous declaration is here}}
+  virtual        void virtualDef();        // expected-note{{previous declaration is here}}
+  virtual        void virtualInlineDef();  // expected-note{{previous declaration is here}}
+  virtual inline void virtualInlineDecl(); // expected-note{{previous declaration is here}}
+  static         void staticDef();         // expected-note{{previous declaration is here}}
+  static         void staticInlineDef();   // expected-note{{previous declaration is here}}
+  static  inline void staticInlineDecl();  // expected-note{{previous declaration is here}}
+
+  static         int  StaticField;         // expected-note{{previous declaration is here}}
+  static  const  int  StaticConstField;    // expected-note{{previous declaration is here}}
+  constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
+};
+
+template<typename T> __declspec(dllimport)        void CTMR<T>::normalDef() {}         // expected-error{{redeclaration of 'CTMR::normalDef' cannot add 'dllimport' attribute}}
+                                                                                       // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
+template<typename T> __declspec(dllimport) inline void CTMR<T>::normalInlineDef() {}   // expected-error{{redeclaration of 'CTMR::normalInlineDef' cannot add 'dllimport' attribute}}
+template<typename T> __declspec(dllimport)        void CTMR<T>::normalInlineDecl() {}  // expected-error{{redeclaration of 'CTMR::normalInlineDecl' cannot add 'dllimport' attribute}}
+template<typename T> __declspec(dllimport)        void CTMR<T>::virtualDef() {}        // expected-error{{redeclaration of 'CTMR::virtualDef' cannot add 'dllimport' attribute}}
+                                                                                       // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
+template<typename T> __declspec(dllimport) inline void CTMR<T>::virtualInlineDef() {}  // expected-error{{redeclaration of 'CTMR::virtualInlineDef' cannot add 'dllimport' attribute}}
+template<typename T> __declspec(dllimport)        void CTMR<T>::virtualInlineDecl() {} // expected-error{{redeclaration of 'CTMR::virtualInlineDecl' cannot add 'dllimport' attribute}}
+template<typename T> __declspec(dllimport)        void CTMR<T>::staticDef() {}         // expected-error{{redeclaration of 'CTMR::staticDef' cannot add 'dllimport' attribute}}
+                                                                                       // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
+template<typename T> __declspec(dllimport) inline void CTMR<T>::staticInlineDef() {}   // expected-error{{redeclaration of 'CTMR::staticInlineDef' cannot add 'dllimport' attribute}}
+template<typename T> __declspec(dllimport)        void CTMR<T>::staticInlineDecl() {}  // expected-error{{redeclaration of 'CTMR::staticInlineDecl' cannot add 'dllimport' attribute}}
+
+template<typename T> __declspec(dllimport)        int  CTMR<T>::StaticField = 1;       // expected-error{{redeclaration of 'CTMR::StaticField' cannot add 'dllimport' attribute}}
+                                                                                       // expected-warning@-1{{definition of dllimport static field}}
+                                                                                       // expected-note@-2{{attribute is here}}
+template<typename T> __declspec(dllimport) const  int  CTMR<T>::StaticConstField = 1;  // expected-error{{redeclaration of 'CTMR::StaticConstField' cannot add 'dllimport' attribute}}
+                                                                                       // expected-warning@-1{{definition of dllimport static field}}
+                                                                                       // expected-note@-2{{attribute is here}}
+template<typename T> __declspec(dllimport) constexpr int CTMR<T>::ConstexprField;      // expected-error{{redeclaration of 'CTMR::ConstexprField' cannot add 'dllimport' attribute}}
+                                                                                       // expected-warning@-1{{definition of dllimport static field}}
+                                                                                       // expected-note@-2{{attribute is here}}
+
+
+
+//===----------------------------------------------------------------------===//
+// Class template member templates
+//===----------------------------------------------------------------------===//
+
+template<typename T>
+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}}
+  template<typename U> __declspec(dllimport)               void normalInclass() {}
+  template<typename U> __declspec(dllimport)               void normalInlineDef();
+  template<typename U> __declspec(dllimport)        inline void normalInlineDecl();
+  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}}
+  template<typename U> __declspec(dllimport) static        void staticInclass() {}
+  template<typename U> __declspec(dllimport) static        void staticInlineDef();
+  template<typename U> __declspec(dllimport) static inline void staticInlineDecl();
+
+#if __has_feature(cxx_variable_templates)
+  template<typename U> __declspec(dllimport) static        int  StaticField;
+  template<typename U> __declspec(dllimport) static        int  StaticFieldDef; // expected-note{{attribute is here}}
+  template<typename U> __declspec(dllimport) static const  int  StaticConstField;
+  template<typename U> __declspec(dllimport) static const  int  StaticConstFieldDef; // expected-note{{attribute is here}}
+  template<typename U> __declspec(dllimport) static const  int  StaticConstFieldEqualInit = 1;
+  template<typename U> __declspec(dllimport) static const  int  StaticConstFieldBraceInit{1};
+  template<typename U> __declspec(dllimport) constexpr static int ConstexprField = 1;
+  template<typename U> __declspec(dllimport) constexpr static int ConstexprFieldDef = 1; // expected-note{{attribute is here}}
+#endif // __has_feature(cxx_variable_templates)
+};
+
+template<typename T> template<typename U>        void ImportClsTmplMemTmpl<T>::normalDef() {} // expected-warning{{'ImportClsTmplMemTmpl::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
+template<typename T> template<typename U> inline void ImportClsTmplMemTmpl<T>::normalInlineDef() {}
+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}}
+template<typename T> template<typename U> inline void ImportClsTmplMemTmpl<T>::staticInlineDef() {}
+template<typename T> template<typename U>        void ImportClsTmplMemTmpl<T>::staticInlineDecl() {}
+
+#if __has_feature(cxx_variable_templates)
+template<typename T> template<typename U>        int  ImportClsTmplMemTmpl<T>::StaticFieldDef; // expected-warning{{definition of dllimport static field}}
+template<typename T> template<typename U> const  int  ImportClsTmplMemTmpl<T>::StaticConstFieldDef = 1; // expected-warning{{definition of dllimport static field}}
+template<typename T> template<typename U> constexpr int ImportClsTmplMemTmpl<T>::ConstexprFieldDef; // expected-warning{{definition of dllimport static field}}
+#endif // __has_feature(cxx_variable_templates)
+
+
+// Redeclarations cannot add dllimport.
+template<typename T>
+struct CTMTR /*ClassTmplMemberTmplRedecl*/ {
+  template<typename U>               void normalDef();         // expected-note{{previous declaration is here}}
+  template<typename U>               void normalInlineDef();   // expected-note{{previous declaration is here}}
+  template<typename U>        inline void normalInlineDecl();  // expected-note{{previous declaration is here}}
+  template<typename U> static        void staticDef();         // expected-note{{previous declaration is here}}
+  template<typename U> static        void staticInlineDef();   // expected-note{{previous declaration is here}}
+  template<typename U> static inline void staticInlineDecl();  // expected-note{{previous declaration is here}}
+
+#if __has_feature(cxx_variable_templates)
+  template<typename U> static        int  StaticField;         // expected-note{{previous declaration is here}}
+  template<typename U> static const  int  StaticConstField;    // expected-note{{previous declaration is here}}
+  template<typename U> constexpr static int ConstexprField = 1; // expected-note{{previous declaration is here}}
+#endif // __has_feature(cxx_variable_templates)
+};
+
+template<typename T> template<typename U> __declspec(dllimport)        void CTMTR<T>::normalDef() {}         // expected-error{{redeclaration of 'CTMTR::normalDef' cannot add 'dllimport' attribute}}
+                                                                                                             // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
+template<typename T> template<typename U> __declspec(dllimport) inline void CTMTR<T>::normalInlineDef() {}   // expected-error{{redeclaration of 'CTMTR::normalInlineDef' cannot add 'dllimport' attribute}}
+template<typename T> template<typename U> __declspec(dllimport)        void CTMTR<T>::normalInlineDecl() {}  // expected-error{{redeclaration of 'CTMTR::normalInlineDecl' cannot add 'dllimport' attribute}}
+template<typename T> template<typename U> __declspec(dllimport)        void CTMTR<T>::staticDef() {}         // expected-error{{redeclaration of 'CTMTR::staticDef' cannot add 'dllimport' attribute}}
+                                                                                                             // expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
+template<typename T> template<typename U> __declspec(dllimport) inline void CTMTR<T>::staticInlineDef() {}   // expected-error{{redeclaration of 'CTMTR::staticInlineDef' cannot add 'dllimport' attribute}}
+template<typename T> template<typename U> __declspec(dllimport)        void CTMTR<T>::staticInlineDecl() {}  // expected-error{{redeclaration of 'CTMTR::staticInlineDecl' cannot add 'dllimport' attribute}}
+
+#if __has_feature(cxx_variable_templates)
+template<typename T> template<typename U> __declspec(dllimport)        int  CTMTR<T>::StaticField = 1;       // expected-error{{redeclaration of 'CTMTR::StaticField' cannot add 'dllimport' attribute}}
+                                                                                                             // expected-warning@-1{{definition of dllimport static field}}
+                                                                                                             // expected-note@-2{{attribute is here}}
+template<typename T> template<typename U> __declspec(dllimport) const  int  CTMTR<T>::StaticConstField = 1;  // expected-error{{redeclaration of 'CTMTR::StaticConstField' cannot add 'dllimport' attribute}}
+                                                                                                             // expected-warning@-1{{definition of dllimport static field}}
+                                                                                                             // expected-note@-2{{attribute is here}}
+template<typename T> template<typename U> __declspec(dllimport) constexpr int CTMTR<T>::ConstexprField;      // expected-error{{redeclaration of 'CTMTR::ConstexprField' cannot add 'dllimport' attribute}}
+                                                                                                             // expected-warning@-1{{definition of dllimport static field}}
+                                                                                                             // expected-note@-2{{attribute is here}}
+#endif // __has_feature(cxx_variable_templates)
+
+
+
+//===----------------------------------------------------------------------===//
+// Classes
+//===----------------------------------------------------------------------===//
+
+class __declspec(dllimport) ClassDecl;
+
+class __declspec(dllimport) ClassDef { };
+
+template <typename T> class ClassTemplate {};
+
+#ifdef MS
+// expected-note@+5{{previous attribute is here}}
+// expected-note@+4{{previous attribute is here}}
+// expected-error@+4{{attribute 'dllexport' cannot be applied to member of 'dllimport' class}}
+// expected-error@+4{{attribute 'dllimport' cannot be applied to member of 'dllimport' class}}
+#endif
+class __declspec(dllimport) ImportClassWithDllMember {
+  void __declspec(dllexport) foo();
+  void __declspec(dllimport) bar();
+};
+
+#ifdef MS
+// expected-note@+5{{previous attribute is here}}
+// expected-note@+4{{previous attribute is here}}
+// expected-error@+4{{attribute 'dllimport' cannot be applied to member of 'dllexport' class}}
+// expected-error@+4{{attribute 'dllexport' cannot be applied to member of 'dllexport' class}}
+#endif
+class __declspec(dllexport) ExportClassWithDllMember {
+  void __declspec(dllimport) foo();
+  void __declspec(dllexport) bar();
+};
+
+namespace ImportedExplicitSpecialization {
+template <typename T> struct S { static int x; };
+template <typename T> int S<T>::x = sizeof(T);
+template <> struct __declspec(dllimport) S<int> { static int x; }; // expected-note{{attribute is here}}
+int S<int>::x = -1; // expected-error{{definition of dllimport static field not allowed}}
+}
+
+namespace PR19988 {
+// Don't error about applying delete to dllimport member function when instantiating.
+template <typename> struct __declspec(dllimport) S {
+  void foo() = delete;
+};
+S<int> s;
+}
+
+#ifdef MS
+// expected-warning@+3{{'dllimport' attribute ignored}}
+#endif
+template <typename T> struct PartiallySpecializedClassTemplate {};
+template <typename T> struct __declspec(dllimport) PartiallySpecializedClassTemplate<T*> { void f() {} };
+
+template <typename T> struct ExpliciallySpecializedClassTemplate {};
+template <> struct __declspec(dllimport) ExpliciallySpecializedClassTemplate<int> { void f() {} };
+
+
+//===----------------------------------------------------------------------===//
+// Classes with template base classes
+//===----------------------------------------------------------------------===//
+
+template <typename T> class __declspec(dllexport) ExportedClassTemplate {};
+
+template <typename T> class __declspec(dllimport) ImportedClassTemplate {};
+
+// ClassTemplate<int> gets imported.
+class __declspec(dllimport) DerivedFromTemplate : public ClassTemplate<int> {};
+
+// ClassTemplate<int> is already imported.
+class __declspec(dllimport) DerivedFromTemplate2 : public ClassTemplate<int> {};
+
+// ImportedClassTemplate is expliitly imported.
+class __declspec(dllimport) DerivedFromImportedTemplate : public ImportedClassTemplate<int> {};
+
+// ExportedClassTemplate is explicitly exported.
+class __declspec(dllimport) DerivedFromExportedTemplate : public ExportedClassTemplate<int> {};
+
+#ifdef MS
+// expected-note@+4{{class template 'ClassTemplate<double>' was instantiated here}}
+// expected-warning@+4{{propagating dll attribute to already instantiated base class template without dll attribute is not supported}}
+// expected-note@+3{{attribute is here}}
+#endif
+class DerivedFromTemplateD : public ClassTemplate<double> {};
+class __declspec(dllimport) DerivedFromTemplateD2 : public ClassTemplate<double> {};
+
+#ifdef MS
+// expected-note@+4{{class template 'ClassTemplate<bool>' was instantiated here}}
+// expected-warning@+4{{propagating dll attribute to already instantiated base class template with different dll attribute is not supported}}
+// expected-note@+3{{attribute is here}}
+#endif
+class __declspec(dllexport) DerivedFromTemplateB : public ClassTemplate<bool> {};
+class __declspec(dllimport) DerivedFromTemplateB2 : public ClassTemplate<bool> {};
+
+template <typename T> struct ExplicitlySpecializedTemplate { void func() {} };
+#ifdef MS
+// expected-note@+2{{class template 'ExplicitlySpecializedTemplate<int>' was explicitly specialized here}}
+#endif
+template <> struct ExplicitlySpecializedTemplate<int> { void func() {} };
+template <typename T> struct ExplicitlyExportSpecializedTemplate { void func() {} };
+template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func() {} };
+template <typename T> struct ExplicitlyImportSpecializedTemplate { void func() {} };
+template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func() {} };
+
+template <typename T> struct ExplicitlyInstantiatedTemplate { void func() {} };
+#ifdef MS
+// expected-note@+2{{class template 'ExplicitlyInstantiatedTemplate<int>' was instantiated here}}
+#endif
+template struct ExplicitlyInstantiatedTemplate<int>;
+template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func() {} };
+template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>;
+template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func() {} };
+template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate<int>;
+
+#ifdef MS
+// expected-warning@+3{{propagating dll attribute to explicitly specialized base class template without dll attribute is not supported}}
+// expected-note@+2{{attribute is here}}
+#endif
+struct __declspec(dllimport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate<int> {};
+
+// Base class already specialized with export attribute.
+struct __declspec(dllimport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {};
+
+// Base class already specialized with import attribute.
+struct __declspec(dllimport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {};
+
+#ifdef MS
+// expected-warning@+3{{propagating dll attribute to already instantiated base class template without dll attribute is not supported}}
+// expected-note@+2{{attribute is here}}
+#endif
+struct __declspec(dllimport) DerivedFromExplicitlyInstantiatedTemplate : public ExplicitlyInstantiatedTemplate<int> {};
+
+// Base class already instantiated with export attribute.
+struct __declspec(dllimport) DerivedFromExplicitlyExportInstantiatedTemplate : public ExplicitlyExportInstantiatedTemplate<int> {};
+
+// Base class already instantiated with import attribute.
+struct __declspec(dllimport) DerivedFromExplicitlyImportInstantiatedTemplate : public ExplicitlyImportInstantiatedTemplate<int> {};
diff --git a/test/SemaCXX/elaborated-type-specifier.cpp b/test/SemaCXX/elaborated-type-specifier.cpp
index 1b1770a..81c5cb4 100644
--- a/test/SemaCXX/elaborated-type-specifier.cpp
+++ b/test/SemaCXX/elaborated-type-specifier.cpp
@@ -43,3 +43,12 @@
   if (s5 == s5_2) return 1; // expected-error {{comparison of distinct pointer types ('struct S5 *' and 'struct S5 *')}}
   return 0;
 }
+
+namespace test5 {
+  struct A {
+    class __attribute__((visibility("hidden"))) B {};
+
+    void test(class __attribute__((visibility("hidden"), noreturn)) B b) { // expected-warning {{'noreturn' attribute only applies to functions and methods}}
+    }
+  };
+}
diff --git a/test/SemaCXX/enable_if.cpp b/test/SemaCXX/enable_if.cpp
new file mode 100644
index 0000000..e9dc242
--- /dev/null
+++ b/test/SemaCXX/enable_if.cpp
@@ -0,0 +1,79 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+typedef int (*fp)(int);
+int surrogate(int);
+
+struct X {
+  X() = default;  // expected-note{{candidate constructor not viable: requires 0 arguments, but 1 was provided}}
+  X(const X&) = default;  // expected-note{{candidate constructor not viable: no known conversion from 'bool' to 'const X' for 1st argument}}
+  X(bool b) __attribute__((enable_if(b, "chosen when 'b' is true")));  // expected-note{{candidate disabled: chosen when 'b' is true}}
+
+  void f(int n) __attribute__((enable_if(n == 0, "chosen when 'n' is zero")));
+  void f(int n) __attribute__((enable_if(n == 1, "chosen when 'n' is one")));  // expected-note{{member declaration nearly matches}} expected-note{{candidate disabled: chosen when 'n' is one}}
+
+  static void s(int n) __attribute__((enable_if(n == 0, "chosen when 'n' is zero")));  // expected-note2{{candidate disabled: chosen when 'n' is zero}}
+
+  void conflict(int n) __attribute__((enable_if(n+n == 10, "chosen when 'n' is five")));  // expected-note{{candidate function}}
+  void conflict(int n) __attribute__((enable_if(n*2 == 10, "chosen when 'n' is five")));  // expected-note{{candidate function}}
+
+  operator long() __attribute__((enable_if(true, "chosen on your platform")));
+  operator int() __attribute__((enable_if(false, "chosen on other platform")));
+
+  operator fp() __attribute__((enable_if(false, "never enabled"))) { return surrogate; }  // expected-note{{conversion candidate of type 'int (*)(int)'}}  // FIXME: the message is not displayed
+};
+
+void X::f(int n) __attribute__((enable_if(n == 0, "chosen when 'n' is zero")))  // expected-note{{member declaration nearly matches}} expected-note{{candidate disabled: chosen when 'n' is zero}}
+{
+}
+
+void X::f(int n) __attribute__((enable_if(n == 2, "chosen when 'n' is two")))  // expected-error{{out-of-line definition of 'f' does not match any declaration in 'X'}} expected-note{{candidate disabled: chosen when 'n' is two}}
+{
+}
+
+X x1(true);
+X x2(false); // expected-error{{no matching constructor for initialization of 'X'}}
+
+__attribute__((deprecated)) constexpr int old() { return 0; }  // expected-note2{{'old' has been explicitly marked deprecated here}}
+void deprec1(int i) __attribute__((enable_if(old() == 0, "chosen when old() is zero")));  // expected-warning{{'old' is deprecated}}
+void deprec2(int i) __attribute__((enable_if(old() == 0, "chosen when old() is zero")));  // expected-warning{{'old' is deprecated}}
+
+void overloaded(int);
+void overloaded(long);
+
+struct Nothing { };
+template<typename T> void typedep(T t) __attribute__((enable_if(t, "")));  // expected-note{{candidate disabled:}}  expected-error{{value of type 'Nothing' is not contextually convertible to 'bool'}}
+template<int N> void valuedep() __attribute__((enable_if(N == 1, "")));
+
+// FIXME: we skip potential constant expression evaluation on value dependent
+// enable-if expressions
+int not_constexpr();
+template<int N> void valuedep() __attribute__((enable_if(N == not_constexpr(), "")));
+
+template <typename T> void instantiationdep() __attribute__((enable_if(sizeof(sizeof(T)) != 0, "")));
+
+void test() {
+  X x;
+  x.f(0);
+  x.f(1);
+  x.f(2);  // no error, suppressed by erroneous out-of-line definition
+  x.f(3);  // expected-error{{no matching member function for call to 'f'}}
+
+  x.s(0);
+  x.s(1);  // expected-error{{no matching member function for call to 's'}}
+
+  X::s(0);
+  X::s(1);  // expected-error{{no matching member function for call to 's'}}
+
+  x.conflict(5);  // expected-error{{call to member function 'conflict' is ambiguous}}
+
+  deprec2(0);
+
+  overloaded(x);
+
+  int i = x(1);  // expected-error{{no matching function for call to object of type 'X'}}
+
+  Nothing n;
+  typedep(0);  // expected-error{{no matching function for call to 'typedep'}}
+  typedep(1);
+  typedep(n);  // expected-note{{in instantiation of function template specialization 'typedep<Nothing>' requested here}}
+}
diff --git a/test/SemaCXX/enum-bitfield.cpp b/test/SemaCXX/enum-bitfield.cpp
index 63445ca..ec849b7 100644
--- a/test/SemaCXX/enum-bitfield.cpp
+++ b/test/SemaCXX/enum-bitfield.cpp
@@ -16,3 +16,15 @@
   enum E : int(2);
   enum E : Z(); // expected-error{{integral constant expression must have integral or unscoped enumeration type, not 'Z'}}
 };
+
+namespace pr18587 {
+struct A {
+  enum class B {
+    C
+  };
+};
+const int C = 4;
+struct D {
+  A::B : C;
+};
+}
diff --git a/test/SemaCXX/enum-scoped.cpp b/test/SemaCXX/enum-scoped.cpp
index c686944..1eed228 100644
--- a/test/SemaCXX/enum-scoped.cpp
+++ b/test/SemaCXX/enum-scoped.cpp
@@ -78,22 +78,22 @@
 // All the redeclarations below are done twice on purpose. Tests that the type
 // of the declaration isn't changed.
 
-enum class Redeclare2; // expected-note{{previous use is here}} expected-note{{previous use is here}}
+enum class Redeclare2; // expected-note{{previous declaration is here}} expected-note{{previous declaration is here}}
 enum Redeclare2; // expected-error{{previously declared as scoped}}
 enum Redeclare2; // expected-error{{previously declared as scoped}}
 
-enum Redeclare3 : int; // expected-note{{previous use is here}} expected-note{{previous use is here}}
+enum Redeclare3 : int; // expected-note{{previous declaration is here}} expected-note{{previous declaration is here}}
 enum Redeclare3; // expected-error{{previously declared with fixed underlying type}}
 enum Redeclare3; // expected-error{{previously declared with fixed underlying type}}
 
 enum class Redeclare5;
 enum class Redeclare5 : int; // ok
 
-enum Redeclare6 : int; // expected-note{{previous use is here}} expected-note{{previous use is here}}
+enum Redeclare6 : int;   // expected-note{{previous declaration is here}} expected-note{{previous declaration is here}}
 enum Redeclare6 : short; // expected-error{{redeclared with different underlying type}}
 enum Redeclare6 : short; // expected-error{{redeclared with different underlying type}}
 
-enum class Redeclare7; // expected-note{{previous use is here}} expected-note{{previous use is here}}
+enum class Redeclare7;         // expected-note{{previous declaration is here}} expected-note{{previous declaration is here}}
 enum class Redeclare7 : short; // expected-error{{redeclared with different underlying type}}
 enum class Redeclare7 : short; // expected-error{{redeclared with different underlying type}}
 
@@ -272,6 +272,11 @@
   A f(A a) { return -a; } // expected-error {{invalid argument type 'PR16900::A' to unary expression}}
 }
 
+namespace PR18551 {
+  enum class A { A };
+  bool f() { return !A::A; } // expected-error {{invalid argument type 'PR18551::A' to unary expression}}
+}
+
 namespace rdar15124329 {
   enum class B : bool { F, T };
 
@@ -282,3 +287,17 @@
   static_assert(T2 == B::T, "");
 }
 
+namespace PR18044 {
+  enum class E { a };
+
+  int E::e = 0; // expected-error {{does not refer into a class}}
+  void E::f() {} // expected-error {{does not refer into a class}}
+  struct E::S {}; // expected-error {{no struct named 'S'}}
+  struct T : E::S {}; // expected-error {{expected class name}}
+  enum E::E {}; // expected-error {{no enum named 'E'}}
+  int E::*p; // expected-error {{does not point into a class}}
+  using E::f; // expected-error {{no member named 'f'}}
+
+  using E::a; // ok!
+  E b = a;
+}
diff --git a/test/SemaCXX/err_init_conversion_failed.cpp b/test/SemaCXX/err_init_conversion_failed.cpp
index 0652e7a..e31f215 100644
--- a/test/SemaCXX/err_init_conversion_failed.cpp
+++ b/test/SemaCXX/err_init_conversion_failed.cpp
@@ -43,3 +43,19 @@
   const float4 V = (float4){ in, out };
   // expected-error@-1{{cannot initialize a compound literal initializer}}
 }
+
+namespace template_test {
+class S {
+public:
+   void foo(int);
+};
+
+template <class P> struct S2 {
+  void (P::*a)(const int &);
+};
+
+void test_15() {
+  S2<S> X = {&S::foo};
+  // expected-error-re@-1{{cannot initialize a member subobject of type 'void (template_test::S::*)(const int &){{( __attribute__\(\(thiscall\)\))?}}' with an rvalue of type 'void (template_test::S::*)(int){{( __attribute__\(\(thiscall\)\))?}}': type mismatch at 1st parameter ('const int &' vs 'int')}}
+}
+}
diff --git a/test/SemaCXX/explicit.cpp b/test/SemaCXX/explicit.cpp
index 1c4d770..aa28bd8 100644
--- a/test/SemaCXX/explicit.cpp
+++ b/test/SemaCXX/explicit.cpp
@@ -246,3 +246,8 @@
   explicit explicit Test(int x);  // expected-warning{{duplicate 'explicit' declaration specifier}}
   };
 }
+
+namespace PR18777 {
+  struct S { explicit operator bool() const; } s;
+  int *p = new int(s); // expected-error {{no viable conversion}}
+}
diff --git a/test/SemaCXX/expression-traits.cpp b/test/SemaCXX/expression-traits.cpp
index 3a00687..51bb90e 100644
--- a/test/SemaCXX/expression-traits.cpp
+++ b/test/SemaCXX/expression-traits.cpp
@@ -520,20 +520,19 @@
     // 5.16 Conditional operator [expr.cond]
     //
     // 2 If either the second or the third operand has type (possibly
-    // cv-qualified) void, then the lvalue-to-rvalue (4.1),
-    // array-to-pointer (4.2), and function-to-pointer (4.3) standard
-    // conversions are performed on the second and third operands, and one
-    // of the following shall hold:
+    // cv-qualified) void, one of the following shall hold:
     //
     // - The second or the third operand (but not both) is a
-    // throw-expression (15.1); the result is of the type of the other and
-    // is an rvalue.
+    // (possibly parenthesized) throw-expression (15.1); the result
+    // is of the type and value category of the other.
 
     Class classLvalue;
     ASSERT_RVALUE(cond ? throw 1 : (void)0);
     ASSERT_RVALUE(cond ? (void)0 : throw 1);
-    ASSERT_RVALUE(cond ? throw 1 : classLvalue);
-    ASSERT_RVALUE(cond ? classLvalue : throw 1);
+    ASSERT_RVALUE(cond ? throw 1 : 0);
+    ASSERT_RVALUE(cond ? 0 : throw 1);
+    ASSERT_LVALUE(cond ? throw 1 : classLvalue);
+    ASSERT_LVALUE(cond ? classLvalue : throw 1);
 
     // - Both the second and the third operands have type void; the result
     // is of type void and is an rvalue. [Note: this includes the case
diff --git a/test/SemaCXX/expressions.cpp b/test/SemaCXX/expressions.cpp
index 2635fb8..1a50c99 100644
--- a/test/SemaCXX/expressions.cpp
+++ b/test/SemaCXX/expressions.cpp
@@ -118,3 +118,20 @@
   (void)s1.foo();
   (void)s2.foo();
 }
+
+namespace pr16992 {
+  typedef int T;
+  unsigned getsz() {
+    return (sizeof T());
+  }
+}
+
+void test4() {
+  #define X 0
+  #define Y 1
+  bool r1 = X || Y;
+
+  #define Y2 2
+  bool r2 = X || Y2; // expected-warning {{use of logical '||' with constant operand}} \
+                     // expected-note {{use '|' for a bitwise operation}}
+}
diff --git a/test/SemaCXX/flexible-array-test.cpp b/test/SemaCXX/flexible-array-test.cpp
index f287711..e58f19a 100644
--- a/test/SemaCXX/flexible-array-test.cpp
+++ b/test/SemaCXX/flexible-array-test.cpp
@@ -36,14 +36,20 @@
 }
 
 struct S {
-	virtual void foo();
+  virtual void foo();
 };
 
 struct X {
    int blah;
-   S strings[];	// expected-error {{flexible array member 'strings' of non-POD element type 'S []'}}
+   S strings[];
 };
 
+S a, b = a;
+S f(X &x) {
+  a = b;
+  return x.strings[0];
+}
+
 class A {
   int s;
   char c[];
@@ -71,3 +77,14 @@
 };
 
 }
+
+struct NonTrivDtor { ~NonTrivDtor(); };
+// FIXME: It's not clear whether we should disallow examples like this. GCC accepts.
+struct FlexNonTrivDtor {
+  int n;
+  NonTrivDtor ntd[]; // expected-error {{flexible array member 'ntd' of type 'NonTrivDtor []' with non-trivial destruction}}
+  ~FlexNonTrivDtor() {
+    for (int i = n; i != 0; --i)
+      ntd[i-1].~NonTrivDtor();
+  }
+};
diff --git a/test/SemaCXX/for-range-dereference.cpp b/test/SemaCXX/for-range-dereference.cpp
index bf3187d..7377199 100644
--- a/test/SemaCXX/for-range-dereference.cpp
+++ b/test/SemaCXX/for-range-dereference.cpp
@@ -11,7 +11,7 @@
 
 struct DeletedEnd : public T {
   Data *begin();
-  Data *end() = delete; //expected-note {{function has been explicitly marked deleted here}}
+  Data *end() = delete; //expected-note {{'end' has been explicitly marked deleted here}}
 };
 
 struct DeletedADLBegin { };
diff --git a/test/SemaCXX/for-range-examples.cpp b/test/SemaCXX/for-range-examples.cpp
index b3cf9c3..2f777fb 100644
--- a/test/SemaCXX/for-range-examples.cpp
+++ b/test/SemaCXX/for-range-examples.cpp
@@ -176,8 +176,9 @@
 
     // Make sure these don't crash. Better diagnostics would be nice.
     for (: {1, 2, 3}) {} // expected-error {{expected expression}} expected-error {{expected ';'}}
-    for (x : {1, 2, 3}) {} // expected-error {{undeclared identifier}} expected-error {{expected ';'}}
-    for (y : {1, 2, 3}) {} // expected-error {{must declare a variable}} expected-warning {{result unused}}
+    for (1 : {1, 2, 3}) {} // expected-error {{must declare a variable}} expected-warning {{result unused}}
+    for (+x : {1, 2, 3}) {} // expected-error {{undeclared identifier}} expected-error {{expected ';'}}
+    for (+y : {1, 2, 3}) {} // expected-error {{must declare a variable}} expected-warning {{result unused}}
   }
 }
 
@@ -209,3 +210,32 @@
       // expected-error@-1 {{cannot build range expression with array function parameter 'arr' since parameter with array type 'test6::vector []' is treated as pointer type 'test6::vector *'}}
   }
 }
+
+namespace test7 {
+  void f() {
+    int arr[5], b;
+    for (a : arr) {} // expected-warning {{extension}}
+    // FIXME: Give a -Wshadow for this by default?
+    for (b : arr) {} // expected-warning {{extension}}
+    for (arr : arr) {} // expected-warning {{extension}}
+    for (c alignas(8) : arr) { // expected-warning {{extension}}
+      static_assert(alignof(c) == 8, ""); // expected-warning {{extension}}
+    }
+    // FIXME: We should reject this, but don't, because we only check the
+    // attribute before we deduce the 'auto' type.
+    for (d alignas(1) : arr) {} // expected-warning {{extension}}
+    for (e [[deprecated]] : arr) { e = 0; } // expected-warning {{deprecated}} expected-note {{here}} expected-warning {{extension}}
+  }
+}
+
+namespace pr18587 {
+  class Arg {};
+  struct Cont {
+    int *begin();
+    int *end();
+  };
+  void AddAllArgs(Cont &x) {
+    for (auto Arg: x) {
+    }
+  }
+}
diff --git a/test/SemaCXX/format-strings.cpp b/test/SemaCXX/format-strings.cpp
index 299aa81..4177570 100644
--- a/test/SemaCXX/format-strings.cpp
+++ b/test/SemaCXX/format-strings.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -pedantic -fblocks %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -Wformat-non-iso -fblocks %s
 
 #include <stdarg.h>
 
diff --git a/test/SemaCXX/friend.cpp b/test/SemaCXX/friend.cpp
index aed2ab2..0358910 100644
--- a/test/SemaCXX/friend.cpp
+++ b/test/SemaCXX/friend.cpp
@@ -288,3 +288,11 @@
     ::test10::f10_d(z);
   }
 }
+
+namespace test11 {
+  class __attribute__((visibility("hidden"))) B;
+
+  class A {
+    friend class __attribute__((visibility("hidden"), noreturn)) B; // expected-warning {{'noreturn' attribute only applies to functions and methods}}
+  };
+}
diff --git a/test/SemaCXX/funcdname.cpp b/test/SemaCXX/funcdname.cpp
new file mode 100644
index 0000000..d63d3f5
--- /dev/null
+++ b/test/SemaCXX/funcdname.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -std=c++1y -triple i386-pc-win32 -fms-compatibility -fms-extensions -fsyntax-only -verify %s
+// expected-no-diagnostics
+
+int foo() {
+  static_assert(sizeof(__FUNCDNAME__) == 12, "?foo@@YAHXZ");
+  return 0;
+}
+
+// Within templates.
+template <typename T>
+int baz() {
+  static_assert(sizeof(__FUNCDNAME__) == 16, "??$baz@H@@YAHXZ");
+
+  return 0;
+}
+
+struct A {
+  A() {
+    static_assert(sizeof(__FUNCDNAME__) == 13, "??0A@@QAE@XZ");
+  }
+  ~A() {
+    static_assert(sizeof(__FUNCDNAME__) == 13, "??1A@@QAE@XZ");
+  }
+};
+
+int main() {
+  static_assert(sizeof(__FUNCDNAME__) == 5, "main");
+
+  baz<int>();
+
+  return 0;
+}
diff --git a/test/SemaCXX/functional-cast.cpp b/test/SemaCXX/functional-cast.cpp
index f8e0c46..f5ca76c 100644
--- a/test/SemaCXX/functional-cast.cpp
+++ b/test/SemaCXX/functional-cast.cpp
@@ -305,8 +305,8 @@
   (void)structureimfp(psf);
 
   typedef void (structure::*structurevmfp)();
-  (void)structurevmfp(psi); // expected-error {{functional-style cast from 'const int structure::*' to 'structurevmfp' (aka 'void (structure::*)()') is not allowed}}
-  (void)structureimp(psf); // expected-error {{functional-style cast from 'void (structure::*)()' to 'structureimp' (aka 'int structure::*') is not allowed}}
+  (void)structurevmfp(psi); // expected-error-re {{functional-style cast from 'const int structure::*' to 'structurevmfp' (aka 'void (structure::*)(){{( __attribute__\(\(thiscall\)\))?}}') is not allowed}}
+  (void)structureimp(psf); // expected-error-re {{functional-style cast from 'void (structure::*)(){{( __attribute__\(\(thiscall\)\))?}}' to 'structureimp' (aka 'int structure::*') is not allowed}}
 }
 
 // ---------------- misc ------------------
diff --git a/test/SemaCXX/goto.cpp b/test/SemaCXX/goto.cpp
index 24bcb7c..042ec3c 100644
--- a/test/SemaCXX/goto.cpp
+++ b/test/SemaCXX/goto.cpp
@@ -118,7 +118,7 @@
 
 namespace test12 {
   struct A { A(); A(const A&); ~A(); };
-  void test(A a) { // expected-note {{jump enters lifetime of block}} FIXME: wierd location
+  void test(A a) { // expected-note {{jump enters lifetime of block}} FIXME: weird location
     goto lbl; // expected-error {{goto into protected scope}}
     (void) ^{ (void) a; };
   lbl:
diff --git a/test/SemaCXX/implicit-member-functions.cpp b/test/SemaCXX/implicit-member-functions.cpp
index b5f7fe1..de679fe 100644
--- a/test/SemaCXX/implicit-member-functions.cpp
+++ b/test/SemaCXX/implicit-member-functions.cpp
@@ -58,13 +58,13 @@
   };
   struct B;
   struct A {
+    // expected-note@-1 {{while substituting deduced template arguments}}
     typedef B type;
     template<typename T,
              typename = typename InvokeCopyConstructor<typename T::type>::type>
     // expected-note@-1 {{in instantiation of template class}}
     A(const T &);
     // expected-note@-1 {{in instantiation of default argument}}
-    // expected-note@-2 {{while substituting deduced template arguments}}
   };
   struct B { // expected-note {{candidate constructor (the implicit move }}
     B(); // expected-note {{candidate constructor not viable}}
diff --git a/test/SemaCXX/implicit-virtual-member-functions.cpp b/test/SemaCXX/implicit-virtual-member-functions.cpp
index cd547f5..f88a55c 100644
--- a/test/SemaCXX/implicit-virtual-member-functions.cpp
+++ b/test/SemaCXX/implicit-virtual-member-functions.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple %itanium_abi_triple -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple %ms_abi_triple -DMSABI -verify %s
 struct A {
   virtual ~A();
 };
@@ -9,8 +10,12 @@
   void operator delete (void *, int); // expected-note {{'operator delete' declared here}}
 };
 
+#ifdef MSABI
+B b; // expected-note {{implicit destructor for 'B' first required here}}
+#else
 void B::f() { // expected-note {{implicit destructor for 'B' first required here}}
 }
+#endif
 
 struct C : A { // expected-error {{no suitable member 'operator delete' in 'C'}}
   C();
@@ -26,4 +31,3 @@
 void f() {
   new D; // expected-note {{implicit destructor for 'D' first required here}}
 }
-
diff --git a/test/SemaCXX/init-priority-attr.cpp b/test/SemaCXX/init-priority-attr.cpp
index a91eb60..a2e6df2 100644
--- a/test/SemaCXX/init-priority-attr.cpp
+++ b/test/SemaCXX/init-priority-attr.cpp
@@ -25,8 +25,7 @@
 
 Two koo[4]  __attribute__((init_priority(1.13))); // expected-error {{'init_priority' attribute requires an integer constant}}
 
-
-Two func()  __attribute__((init_priority(1001))); // expected-error {{can only use 'init_priority' attribute on file-scope definitions of objects of class type}}
+Two func()  __attribute__((init_priority(1001))); // expected-error {{'init_priority' attribute only applies to variables}}
 
 int i  __attribute__((init_priority(1001))); // expected-error {{can only use 'init_priority' attribute on file-scope definitions of objects of class type}}
 
diff --git a/test/SemaCXX/lambda-expressions.cpp b/test/SemaCXX/lambda-expressions.cpp
index e290424..9a53e46 100644
--- a/test/SemaCXX/lambda-expressions.cpp
+++ b/test/SemaCXX/lambda-expressions.cpp
@@ -282,4 +282,84 @@
     };
     L l; 
   }
-}
\ No newline at end of file
+}
+
+// PR18477: don't try to capture 'this' from an NSDMI encountered while parsing
+// a lambda.
+namespace NSDMIs_in_lambdas {
+  template<typename T> struct S { int a = 0; int b = a; };
+  void f() { []() { S<int> s; }; }
+
+  auto x = []{ struct S { int n, m = n; }; };
+  auto y = [&]{ struct S { int n, m = n; }; }; // expected-error {{non-local lambda expression cannot have a capture-default}}
+  void g() { auto z = [&]{ struct S { int n, m = n; }; }; }
+}
+
+namespace CaptureIncomplete {
+  struct Incomplete; // expected-note 2{{forward decl}}
+  void g(const Incomplete &a);
+  void f(Incomplete &a) {
+    (void) [a] {}; // expected-error {{incomplete}}
+    (void) [&a] {};
+
+    (void) [=] { g(a); }; // expected-error {{incomplete}}
+    (void) [&] { f(a); };
+  }
+}
+
+namespace CaptureAbstract {
+  struct S {
+    virtual void f() = 0; // expected-note {{unimplemented}}
+    int n = 0;
+  };
+  struct T : S {
+    constexpr T() {}
+    void f();
+  };
+  void f() {
+    constexpr T t = T();
+    S &s = const_cast<T&>(t);
+    // FIXME: Once we properly compute odr-use per DR712, this should be
+    // accepted (and should not capture 's').
+    [=] { return s.n; }; // expected-error {{abstract}}
+  }
+}
+
+namespace PR18128 {
+  auto l = [=]{}; // expected-error {{non-local lambda expression cannot have a capture-default}}
+
+  struct S {
+    int n;
+    int (*f())[true ? 1 : ([=]{ return n; }(), 0)];
+    // expected-error@-1 {{non-local lambda expression cannot have a capture-default}}
+    // expected-error@-2 {{invalid use of non-static data member 'n'}}
+    // expected-error@-3 {{a lambda expression may not appear inside of a constant expression}}
+    int g(int k = ([=]{ return n; }(), 0));
+    // expected-error@-1 {{non-local lambda expression cannot have a capture-default}}
+    // expected-error@-2 {{invalid use of non-static data member 'n'}}
+
+    int a = [=]{ return n; }(); // ok
+    int b = [=]{ return [=]{ return n; }(); }(); // ok
+    int c = []{ int k = 0; return [=]{ return k; }(); }(); // ok
+    int d = []{ return [=]{ return n; }(); }(); // expected-error {{'this' cannot be implicitly captured in this context}}
+  };
+}
+
+namespace PR18473 {
+  template<typename T> void f() {
+    T t(0);
+    (void) [=]{ int n = t; }; // expected-error {{deleted}}
+  }
+
+  template void f<int>();
+  struct NoCopy {
+    NoCopy(int);
+    NoCopy(const NoCopy &) = delete; // expected-note {{deleted}}
+    operator int() const;
+  };
+  template void f<NoCopy>(); // expected-note {{instantiation}}
+}
+
+void PR19249() {
+  auto x = [&x]{}; // expected-error {{cannot appear in its own init}}
+}
diff --git a/test/SemaCXX/linkage.cpp b/test/SemaCXX/linkage.cpp
index 13d295a..8a2013f 100644
--- a/test/SemaCXX/linkage.cpp
+++ b/test/SemaCXX/linkage.cpp
@@ -5,6 +5,8 @@
 
 // RUN: %clang_cc1 -Werror -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s
 
+// CHECK: @_ZZN5test61A3fooEvE3bar = linkonce_odr global i32 0, align 4
+
 // PR8926
 namespace test0 {
   typedef struct {
@@ -103,3 +105,20 @@
     };
   }
 }
+
+// Test that we don't compute linkage too hastily before we're done
+// processing a record decl.  rdar://15928125
+namespace test6 {
+  typedef struct {
+    int foo() {
+      // Tested at top of file.
+      static int bar = 0;
+      return bar++;
+    }
+  } A;
+
+  void test() {
+    A a;
+    a.foo();
+  }
+}
diff --git a/test/SemaCXX/linkage2.cpp b/test/SemaCXX/linkage2.cpp
index 075f5e7..a7eb15f 100644
--- a/test/SemaCXX/linkage2.cpp
+++ b/test/SemaCXX/linkage2.cpp
@@ -213,3 +213,7 @@
   void pr16247_bar(int) {}
   void pr16247_bar(double) {}
 }
+namespace PR18964 {
+  unsigned &*foo; //expected-error{{'foo' declared as a pointer to a reference of type}}
+  extern struct {} *foo; // don't assert
+}
diff --git a/test/SemaCXX/member-expr.cpp b/test/SemaCXX/member-expr.cpp
index 239aecf..e0955ae 100644
--- a/test/SemaCXX/member-expr.cpp
+++ b/test/SemaCXX/member-expr.cpp
@@ -193,7 +193,7 @@
   };
 
   template <class T> void call_func(T t) {
-    t->func();  // expected-error-re 2 {{member reference type 'PR15045::bar' is not a pointer$}} \
+    t->func();  // expected-error-re 2 {{member reference type 'PR15045::bar' is not a pointer{{$}}}} \
                 // expected-note {{did you mean to use '.' instead?}}
   }
 
@@ -207,7 +207,7 @@
 
     // Make sure a fixit isn't given in the case that the '->' isn't actually
     // the problem (the problem is with the return value of an operator->).
-    f->func();  // expected-error-re {{member reference type 'PR15045::bar' is not a pointer$}}
+    f->func();  // expected-error-re {{member reference type 'PR15045::bar' is not a pointer{{$}}}}
 
     call_func(e);  // expected-note {{in instantiation of function template specialization 'PR15045::call_func<PR15045::bar>' requested here}}
 
diff --git a/test/SemaCXX/member-init.cpp b/test/SemaCXX/member-init.cpp
index 6e4fd5d..d8a00b3 100644
--- a/test/SemaCXX/member-init.cpp
+++ b/test/SemaCXX/member-init.cpp
@@ -100,3 +100,13 @@
   };
   void f(Sprite& x) { x = x; }
 }
+
+namespace PR18560 {
+  struct X { int m; };
+
+  template<typename T = X,
+           typename U = decltype(T::m)>
+  int f();
+
+  struct Y { int b = f(); };
+}
diff --git a/test/SemaCXX/member-pointer-ms.cpp b/test/SemaCXX/member-pointer-ms.cpp
index aee8e2e..e7c4ae9 100644
--- a/test/SemaCXX/member-pointer-ms.cpp
+++ b/test/SemaCXX/member-pointer-ms.cpp
@@ -1,5 +1,6 @@
-// RUN: %clang_cc1 -std=c++11 -cxx-abi microsoft -fms-compatibility -fsyntax-only -triple=i386-pc-win32 -verify %s
-// RUN: %clang_cc1 -std=c++11 -cxx-abi microsoft -fms-compatibility -fsyntax-only -triple=x86_64-pc-win32 -verify %s
+// RUN: %clang_cc1 -std=c++11 -fms-compatibility -fsyntax-only -triple=i386-pc-win32 -verify -DVMB %s
+// RUN: %clang_cc1 -std=c++11 -fms-compatibility -fsyntax-only -triple=x86_64-pc-win32 -verify -DVMB %s
+// RUN: %clang_cc1 -std=c++11 -fms-compatibility -fsyntax-only -triple=x86_64-pc-win32 -verify -DVMV -fms-memptr-rep=virtual %s
 //
 // This file should also give no diagnostics when run through cl.exe from MSVS
 // 2012, which supports C++11 and static_assert.  It should pass for both 64-bit
@@ -18,22 +19,73 @@
   int f;
 };
 
+#ifdef VMB
 enum {
+  kSingleDataAlign             = 1 * sizeof(int),
+  kSingleFunctionAlign         = 1 * sizeof(void *),
+  kMultipleDataAlign           = 1 * sizeof(int),
+  // Everything with more than 1 field is 8 byte aligned, except virtual data
+  // member pointers on x64 (ugh).
+  kMultipleFunctionAlign       = 8,
+#ifdef _M_X64
+  kVirtualDataAlign            = 4,
+#else
+  kVirtualDataAlign            = 8,
+#endif
+  kVirtualFunctionAlign        = 8,
+  kUnspecifiedDataAlign        = 8,
+  kUnspecifiedFunctionAlign    = 8,
+
   kSingleDataSize             = 1 * sizeof(int),
   kSingleFunctionSize         = 1 * sizeof(void *),
   kMultipleDataSize           = 1 * sizeof(int),
   kMultipleFunctionSize       = 2 * sizeof(void *),
   kVirtualDataSize            = 2 * sizeof(int),
   kVirtualFunctionSize        = 2 * sizeof(int) + 1 * sizeof(void *),
-  // Unspecified is weird, it's 1 more slot than virtual.
-  kUnspecifiedDataSize        = kVirtualDataSize + 1 * sizeof(int),
-  kUnspecifiedFunctionSize    = kVirtualFunctionSize + 1 * sizeof(void *),
+  kUnspecifiedDataSize        = 3 * sizeof(int),
+  kUnspecifiedFunctionSize    = 2 * sizeof(int) + 2 * sizeof(void *),
 };
+#elif VMV
+enum {
+  // Everything with more than 1 field is 8 byte aligned, except virtual data
+  // member pointers on x64 (ugh).
+#ifdef _M_X64
+  kVirtualDataAlign = 4,
+#else
+  kVirtualDataAlign = 8,
+#endif
+  kMultipleDataAlign = kVirtualDataAlign,
+  kSingleDataAlign = kVirtualDataAlign,
+
+  kUnspecifiedFunctionAlign = 8,
+  kVirtualFunctionAlign = kUnspecifiedFunctionAlign,
+  kMultipleFunctionAlign = kUnspecifiedFunctionAlign,
+  kSingleFunctionAlign = kUnspecifiedFunctionAlign,
+
+  kUnspecifiedDataSize = 3 * sizeof(int),
+  kVirtualDataSize = kUnspecifiedDataSize,
+  kMultipleDataSize = kUnspecifiedDataSize,
+  kSingleDataSize = kUnspecifiedDataSize,
+
+  kUnspecifiedFunctionSize = 2 * sizeof(int) + 2 * sizeof(void *),
+  kVirtualFunctionSize = kUnspecifiedFunctionSize,
+  kMultipleFunctionSize = kUnspecifiedFunctionSize,
+  kSingleFunctionSize = kUnspecifiedFunctionSize,
+};
+#else
+#error "test doesn't yet support this mode!"
+#endif
 
 // incomplete types
+#ifdef VMB
 class __single_inheritance IncSingle;
 class __multiple_inheritance IncMultiple;
 class __virtual_inheritance IncVirtual;
+#else
+class IncSingle;
+class IncMultiple;
+class IncVirtual;
+#endif
 static_assert(sizeof(int IncSingle::*)        == kSingleDataSize, "");
 static_assert(sizeof(int IncMultiple::*)      == kMultipleDataSize, "");
 static_assert(sizeof(int IncVirtual::*)       == kVirtualDataSize, "");
@@ -41,6 +93,13 @@
 static_assert(sizeof(void (IncMultiple::*)()) == kMultipleFunctionSize, "");
 static_assert(sizeof(void (IncVirtual::*)())  == kVirtualFunctionSize, "");
 
+static_assert(__alignof(int IncSingle::*)        == kSingleDataAlign, "");
+static_assert(__alignof(int IncMultiple::*)      == kMultipleDataAlign, "");
+static_assert(__alignof(int IncVirtual::*)       == kVirtualDataAlign, "");
+static_assert(__alignof(void (IncSingle::*)())   == kSingleFunctionAlign, "");
+static_assert(__alignof(void (IncMultiple::*)()) == kMultipleFunctionAlign, "");
+static_assert(__alignof(void (IncVirtual::*)())  == kVirtualFunctionAlign, "");
+
 // An incomplete type with an unspecified inheritance model seems to take one
 // more slot than virtual.  It's not clear what it's used for yet.
 class IncUnspecified;
@@ -62,9 +121,15 @@
 
 // Test both declared and defined templates.
 template <typename T> class X;
+#ifdef VMB
 template <> class __single_inheritance   X<IncSingle>;
 template <> class __multiple_inheritance X<IncMultiple>;
 template <> class __virtual_inheritance  X<IncVirtual>;
+#else
+template <> class X<IncSingle>;
+template <> class X<IncMultiple>;
+template <> class X<IncVirtual>;
+#endif
 // Don't declare X<IncUnspecified>.
 static_assert(sizeof(int X<IncSingle>::*)           == kSingleDataSize, "");
 static_assert(sizeof(int X<IncMultiple>::*)         == kMultipleDataSize, "");
@@ -117,9 +182,7 @@
 
 static_assert(sizeof(variable_forces_sizing) == kUnspecifiedDataSize, "");
 static_assert(sizeof(MemPtr1) == kUnspecifiedDataSize, "");
-// FIXME: Clang fails this assert because it locks in the inheritance model at
-// the point of the typedef instead of the first usage, while MSVC does not.
-//static_assert(sizeof(MemPtr2) == kSingleDataSize, "");
+static_assert(sizeof(MemPtr2) == kSingleDataSize, "");
 
 struct MemPtrInBody {
   typedef int MemPtrInBody::*MemPtr;
@@ -164,5 +227,48 @@
   void (T::*func_ptr)();
 };
 
+#ifdef VMB
 int Virtual::*CastTest = reinterpret_cast<int Virtual::*>(&AA::x);
   // expected-error@-1 {{cannot reinterpret_cast from member pointer type}}
+#endif
+
+namespace ErrorTest {
+template <typename T, typename U> struct __single_inheritance A;
+  // expected-warning@-1 {{inheritance model ignored on primary template}}
+template <typename T> struct __multiple_inheritance A<T, T>;
+  // expected-warning@-1 {{inheritance model ignored on partial specialization}}
+template <> struct __single_inheritance A<int, float>;
+
+struct B {}; // expected-note {{B defined here}}
+struct __multiple_inheritance B; // expected-error{{inheritance model does not match definition}}
+
+struct __multiple_inheritance C {}; // expected-error{{inheritance model does not match definition}}
+ // expected-note@-1 {{C defined here}}
+
+struct __virtual_inheritance D;
+struct D : virtual B {};
+}
+#ifdef VMB
+#pragma pointers_to_members(full_generality, multiple_inheritance)
+struct TrulySingleInheritance;
+static_assert(sizeof(int TrulySingleInheritance::*) == kMultipleDataSize, "");
+#pragma pointers_to_members(best_case)
+// This definition shouldn't conflict with the increased generality that the
+// multiple_inheritance model gave to TrulySingleInheritance.
+struct TrulySingleInheritance {};
+
+// Even if a definition proceeds the first mention of a pointer to member, we
+// still give the record the fully general representation.
+#pragma pointers_to_members(full_generality, virtual_inheritance)
+struct SingleInheritanceAsVirtualAfterPragma {};
+static_assert(sizeof(int SingleInheritanceAsVirtualAfterPragma::*) == 12, "");
+
+#pragma pointers_to_members(best_case)
+
+// The above holds even if the pragma comes after the definition.
+struct SingleInheritanceAsVirtualBeforePragma {};
+#pragma pointers_to_members(virtual_inheritance)
+static_assert(sizeof(int SingleInheritanceAsVirtualBeforePragma::*) == 12, "");
+
+#pragma pointers_to_members(single) // expected-error{{unexpected 'single'}}
+#endif
diff --git a/test/SemaCXX/member-pointer.cpp b/test/SemaCXX/member-pointer.cpp
index 4e8b4a8..b8631bc 100644
--- a/test/SemaCXX/member-pointer.cpp
+++ b/test/SemaCXX/member-pointer.cpp
@@ -7,12 +7,13 @@
 struct E : A {};
 struct F : D, E {};
 struct G : virtual D {};
+class H : A {}; // expected-note 2{{implicitly declared private here}}
 
 int A::*pdi1;
 int (::A::*pdi2);
 int (A::*pfi)(int);
 
-int B::*pbi; // expected-error {{expected a class or namespace}}
+int B::*pbi; // expected-error {{'B' is not a class, namespace, or scoped enumeration}}
 int C::*pci; // expected-error {{'pci' does not point into a class}}
 void A::*pdv; // expected-error {{'pdv' declared as a member pointer to void}}
 int& A::*pdr; // expected-error {{'pdr' declared as a member pointer to a reference}}
@@ -115,8 +116,11 @@
   (void)(d.*pai);
   (void)(pd->*pai);
   F f, *ptrf = &f;
-  (void)(f.*pai); // expected-error {{left hand operand to .* must be a class compatible with the right hand operand, but is 'F'}}
-  (void)(ptrf->*pai); // expected-error {{left hand operand to ->* must be a pointer to class compatible with the right hand operand, but is 'F *'}}
+  (void)(f.*pai); // expected-error {{ambiguous conversion from derived class 'F' to base class 'A'}}
+  (void)(ptrf->*pai); // expected-error {{ambiguous conversion from derived class 'F' to base class 'A'}}
+  H h, *ptrh = &h;
+  (void)(h.*pai); // expected-error {{cannot cast 'H' to its private base class 'A'}}
+  (void)(ptrh->*pai); // expected-error {{cannot cast 'H' to its private base class 'A'}}
 
   (void)(hm.*i); // expected-error {{pointer-to-member}}
   (void)(phm->*i); // expected-error {{pointer-to-member}}
diff --git a/test/SemaCXX/microsoft-cxx0x.cpp b/test/SemaCXX/microsoft-cxx0x.cpp
index 79bd7c3..58ab940 100644
--- a/test/SemaCXX/microsoft-cxx0x.cpp
+++ b/test/SemaCXX/microsoft-cxx0x.cpp
@@ -6,7 +6,7 @@
      unsigned int a;
 };
 int b = 3;
-A var = {  b }; // expected-warning {{ cannot be narrowed }} expected-note {{override}}
+A var = {  b }; // expected-warning {{ cannot be narrowed }} expected-note {{insert an explicit cast to silence this issue}}
 
 
 namespace PR13433 {
diff --git a/test/SemaCXX/microsoft-dtor-lookup-cxx11.cpp b/test/SemaCXX/microsoft-dtor-lookup-cxx11.cpp
new file mode 100644
index 0000000..5a399aa
--- /dev/null
+++ b/test/SemaCXX/microsoft-dtor-lookup-cxx11.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple i686-pc-win32 -std=c++11 -verify %s
+
+struct S {
+  virtual ~S() = delete; // expected-note {{'~S' has been explicitly marked deleted here}}
+  void operator delete(void*, int);
+  void operator delete(void*, double);
+} s; // expected-error {{attempt to use a deleted function}}
+
+struct T { // expected-note{{virtual destructor requires an unambiguous, accessible 'operator delete'}}
+  virtual ~T() = default; // expected-note {{explicitly defaulted function was implicitly deleted here}}
+  void operator delete(void*, int);
+  void operator delete(void*, double);
+} t; // expected-error {{attempt to use a deleted function}}
diff --git a/test/SemaCXX/microsoft-dtor-lookup.cpp b/test/SemaCXX/microsoft-dtor-lookup.cpp
index d264bab..412749f 100644
--- a/test/SemaCXX/microsoft-dtor-lookup.cpp
+++ b/test/SemaCXX/microsoft-dtor-lookup.cpp
@@ -1,12 +1,11 @@
-// RUN: %clang_cc1 -triple i686-pc-win32 -cxx-abi itanium -fsyntax-only %s
-// RUN: %clang_cc1 -triple i686-pc-win32 -cxx-abi microsoft -verify -DMSVC_ABI %s
+// RUN: %clang_cc1 -fexceptions -fcxx-exceptions -std=c++11 -triple %itanium_abi_triple -fsyntax-only %s
+// RUN: %clang_cc1 -fexceptions -fcxx-exceptions -std=c++11 -triple %ms_abi_triple -verify %s
 
 namespace Test1 {
 
 // Should be accepted under the Itanium ABI (first RUN line) but rejected
 // under the Microsoft ABI (second RUN line), as Microsoft ABI requires
-// operator delete() lookups to be done at all virtual destructor declaration
-// points.
+// operator delete() lookups to be done when vtables are marked used.
 
 struct A {
   void operator delete(void *); // expected-note {{member found by ambiguous name lookup}}
@@ -24,6 +23,10 @@
   virtual ~VC(); // expected-error {{member 'operator delete' found in multiple base classes of different types}}
 };
 
+void f(VC vc) {
+  // This marks VC's vtable used.
+}
+
 }
 
 namespace Test2 {
@@ -32,14 +35,13 @@
 // requires a dtor for B, but we can't implicitly define it because ~A is
 // private.  bar should be able to call A's private dtor without error, even
 // though MSVC rejects bar.
-
 class A {
 private:
-  ~A(); // expected-note 2{{declared private here}}
+  ~A();
   int a;
 };
 
-struct B : public A { // expected-error {{base class 'Test2::A' has private destructor}}
+struct B : public A { // expected-note {{destructor of 'B' is implicitly deleted because base class 'Test2::A' has an inaccessible destructor}}
   int b;
 };
 
@@ -53,8 +55,8 @@
   C o;
 };
 
-void foo(B b) { } // expected-note {{implicit destructor for 'Test2::B' first required here}}
-void bar(A a) { } // expected-error {{variable of type 'Test2::A' has private destructor}}
+void foo(B b) { } // expected-error {{attempt to use a deleted function}}
+void bar(A a) { } // no error; MSVC rejects this, but we skip the direct access check.
 void baz(D d) { } // no error
 
 }
@@ -64,13 +66,13 @@
 
 class A {
   A();
-  ~A(); // expected-note 2{{implicitly declared private here}}
+  ~A(); // expected-note {{implicitly declared private here}}
   friend void bar(A);
   int a;
 };
 
 void bar(A a) { }
-void baz(A a) { } // expected-error {{variable of type 'Test3::A' has private destructor}}
+void baz(A a) { } // no error; MSVC rejects this, but the standard allows it.
 
 // MSVC accepts foo() but we reject it for consistency with Itanium.  MSVC also
 // rejects this if A has a copy ctor or if we call A's ctor.
@@ -85,3 +87,45 @@
 class A;
 void foo(A a);
 }
+
+#ifdef MSVC_ABI
+namespace Test5 {
+// Do the operator delete access control check from the context of the dtor.
+class A {
+ protected:
+  void operator delete(void *);
+};
+class B : public A {
+  virtual ~B();
+};
+B *test() {
+  // Previously, marking the vtable used here would do the operator delete
+  // lookup from this context, which doesn't have access.
+  return new B;
+}
+}
+#endif
+
+namespace Test6 {
+class A {
+protected:
+  void operator delete(void *);
+};
+class B : public A {
+  virtual ~B();
+public:
+  virtual void m_fn1();
+};
+void fn1(B *b) { b->m_fn1(); }
+}
+
+namespace Test7 {
+class A {
+protected:
+  void operator delete(void *);
+};
+struct B : public A {
+  virtual ~B();
+};
+void fn1(B b) {}
+}
diff --git a/test/SemaCXX/microsoft-new-delete.cpp b/test/SemaCXX/microsoft-new-delete.cpp
index e0d25dc..6c9be22 100644
--- a/test/SemaCXX/microsoft-new-delete.cpp
+++ b/test/SemaCXX/microsoft-new-delete.cpp
@@ -1,5 +1,4 @@
-// RUN: %clang_cc1 -fms-compatibility -fsyntax-only -verify %s
-// expected-no-diagnostics
+// RUN: %clang_cc1 -fms-compatibility -fsyntax-only -verify -std=c++11 %s
 
 #include <stddef.h>
 
@@ -10,3 +9,26 @@
   // Expect no error in MSVC compatibility mode
   int *p = new(arbitrary) int[4];
 }
+
+class noncopyable { noncopyable(const noncopyable&); } extern nc; // expected-note {{here}}
+void *operator new[](size_t, noncopyable);
+void *operator new(size_t, const noncopyable&);
+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, const int &);
+void *r = new (bf.n) int[4]; // expected-error {{non-const reference cannot bind to bit-field}}
+
+struct base {};
+struct derived : private base {} der; // expected-note {{here}}
+void *operator new[](size_t, base &);
+void *operator new(size_t, derived &);
+void *s = new (der) int[4]; // expected-error {{private}}
+
+struct explicit_ctor { explicit explicit_ctor(int); };
+struct explicit_ctor_tag {} ect;
+void *operator new[](size_t, explicit_ctor_tag, explicit_ctor);
+void *operator new(size_t, explicit_ctor_tag, int);
+void *t = new (ect, 0) int[4];
+void *u = new (ect, {0}) int[4];
diff --git a/test/SemaCXX/microsoft-varargs-diagnostics.cpp b/test/SemaCXX/microsoft-varargs-diagnostics.cpp
new file mode 100644
index 0000000..0b76fdd
--- /dev/null
+++ b/test/SemaCXX/microsoft-varargs-diagnostics.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -triple thumbv7-windows -fms-compatibility -fsyntax-only %s -verify
+
+extern "C" {
+typedef char * va_list;
+}
+
+void test_no_arguments(int i, ...) {
+  __va_start(); // expected-error{{too few arguments to function call, expected at least 3, have 0}}
+}
+
+void test_one_argument(int i, ...) {
+  va_list ap;
+  __va_start(&ap); // expected-error{{too few arguments to function call, expected at least 3, have 1}}
+}
+
+void test_two_arguments(int i, ...) {
+  va_list ap;
+  __va_start(&ap, &i); // expected-error{{too few arguments to function call, expected at least 3, have 2}}
+}
+
+void test_non_last_argument(int i, int j, ...) {
+  va_list ap;
+  __va_start(&ap, &i, 4);
+  // expected-error@-1{{passing 'int *' to parameter of incompatible type 'const char *': type mismatch at 2nd parameter ('int *' vs 'const char *')}}
+  // expected-error@-2{{passing 'int' to parameter of incompatible type 'unsigned int': type mismatch at 3rd parameter ('int' vs 'unsigned int')}}
+}
+
+void test_stack_allocated(int i, ...) {
+  va_list ap;
+  int j;
+  __va_start(&ap, &j, 4);
+  // expected-error@-1{{passing 'int *' to parameter of incompatible type 'const char *': type mismatch at 2nd parameter ('int *' vs 'const char *')}}
+  // expected-error@-2{{passing 'int' to parameter of incompatible type 'unsigned int': type mismatch at 3rd parameter ('int' vs 'unsigned int')}}
+}
+
+void test_non_pointer_addressof(int i, ...) {
+  va_list ap;
+  __va_start(&ap, 1, 4);
+  // expected-error@-1{{passing 'int' to parameter of incompatible type 'const char *': type mismatch at 2nd parameter ('int' vs 'const char *')}}
+  // expected-error@-2{{passing 'int' to parameter of incompatible type 'unsigned int': type mismatch at 3rd parameter ('int' vs 'unsigned int')}}
+}
+
diff --git a/test/SemaCXX/microsoft-varargs.cpp b/test/SemaCXX/microsoft-varargs.cpp
new file mode 100644
index 0000000..35f31a9
--- /dev/null
+++ b/test/SemaCXX/microsoft-varargs.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -triple thumbv7-windows -fms-compatibility -fsyntax-only %s -verify
+// expected-no-diagnostics
+
+extern "C" {
+typedef char * va_list;
+void __va_start(va_list *, ...);
+}
+
+int test___va_start(int i, ...) {
+  va_list ap;
+  __va_start(&ap, ( &reinterpret_cast<const char &>(i) ),
+             ( (sizeof(i) + 4 - 1) & ~(4 - 1) ),
+             ( &reinterpret_cast<const char &>(i) ));
+  return (*(int *)((ap += ( (sizeof(int) + 4 - 1) & ~(4 - 1) ) + ( ((va_list)0 - (ap)) & (__alignof(int) - 1) )) - ( (sizeof(int) + 4 - 1) & ~(4 - 1) )));
+}
+
+int builtin(int i, ...) {
+  __builtin_va_list ap;
+  __builtin_va_start(ap, i);
+  return __builtin_va_arg(ap, int);
+}
+
diff --git a/test/SemaCXX/missing-members.cpp b/test/SemaCXX/missing-members.cpp
index 619bc61..96bed07 100644
--- a/test/SemaCXX/missing-members.cpp
+++ b/test/SemaCXX/missing-members.cpp
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 namespace A {
   namespace B {
-    class C { }; // expected-note 2 {{'A::B::C' declared here}}
+    class C { }; // expected-note {{'A::B::C' declared here}}
     struct S { };
     union U { };
   }
@@ -18,13 +18,12 @@
 }
 
 void g() {
-  A::B::D::E; // expected-error {{no member named 'D' in namespace 'A::B'}}
+  A::B::D::E; // expected-error-re {{no member named 'D' in namespace 'A::B'{{$}}}}
   // FIXME: The typo corrections below should be suppressed since A::B::C
   // doesn't have a member named D.
   B::B::C::D; // expected-error {{no member named 'C' in 'B::B'; did you mean 'A::B::C'?}} \
-              // expected-error {{no member named 'D' in 'A::B::C'}}
-  ::C::D; // expected-error {{no member named 'C' in the global namespace; did you mean 'A::B::C'?}}\
-          // expected-error {{no member named 'D' in 'A::B::C'}}
+              // expected-error-re {{no member named 'D' in 'A::B::C'{{$}}}}
+  ::C::D; // expected-error-re {{no member named 'C' in the global namespace{{$}}}}
 }
 
 int A::B::i = 10; // expected-error {{no member named 'i' in namespace 'A::B'}}
diff --git a/test/SemaCXX/ms-friend-lookup.cpp b/test/SemaCXX/ms-friend-lookup.cpp
new file mode 100644
index 0000000..c63160f
--- /dev/null
+++ b/test/SemaCXX/ms-friend-lookup.cpp
@@ -0,0 +1,104 @@
+// RUN: %clang_cc1 %s -triple i686-pc-win32 -std=c++11 -Wmicrosoft -fms-compatibility -verify
+// RUN: not %clang_cc1 %s -triple i686-pc-win32 -std=c++11 -Wmicrosoft -fms-compatibility -fdiagnostics-parseable-fixits 2>&1 | FileCheck %s
+
+struct X;
+namespace name_at_tu_scope {
+struct Y {
+  friend struct X; // expected-warning-re {{unqualified friend declaration {{.*}} is a Microsoft extension}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:17-[[@LINE-1]]:17}:"::"
+};
+}
+
+namespace enclosing_friend_decl {
+struct B;
+namespace ns {
+struct A {
+  friend struct B; // expected-warning-re {{unqualified friend declaration {{.*}} is a Microsoft extension}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:17-[[@LINE-1]]:17}:"enclosing_friend_decl::"
+protected:
+  A();
+};
+}
+struct B {
+  static void f() { ns::A x; }
+};
+}
+
+namespace enclosing_friend_qualified {
+struct B;
+namespace ns {
+struct A {
+  friend struct enclosing_friend_qualified::B; // Adding name specifiers fixes it.
+protected:
+  A();
+};
+}
+struct B {
+  static void f() { ns::A x; }
+};
+}
+
+namespace enclosing_friend_no_tag {
+struct B;
+namespace ns {
+struct A {
+  friend B; // Removing the tag decl fixes it.
+protected:
+  A();
+};
+}
+struct B {
+  static void f() { ns::A x; }
+};
+}
+
+namespace enclosing_friend_func {
+void f();
+namespace ns {
+struct A {
+  // Amusingly, in MSVC, this declares ns::f(), and doesn't find the outer f().
+  friend void f();
+protected:
+  A(); // expected-note {{declared protected here}}
+};
+}
+void f() { ns::A x; } // expected-error {{calling a protected constructor of class 'enclosing_friend_func::ns::A'}}
+}
+
+namespace test_nns_fixit_hint {
+namespace name1 {
+namespace name2 {
+struct X;
+struct name2;
+namespace name3 {
+struct Y {
+  friend struct X; // expected-warning-re {{unqualified friend declaration {{.*}} is a Microsoft extension}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:17-[[@LINE-1]]:17}:"name1::name2::"
+};
+}
+}
+}
+}
+
+// A friend declaration injects a forward declaration into the nearest enclosing
+// non-member scope.
+namespace friend_as_a_forward_decl {
+
+class A {
+  class Nested {
+    friend class B;
+    B *b;
+  };
+  B *b;
+};
+B *global_b;
+
+void f() {
+  class Local {
+    friend class Z;
+    Z *b;
+  };
+  Z *b;
+}
+
+}
diff --git a/test/SemaCXX/ms-interface.cpp b/test/SemaCXX/ms-interface.cpp
index 3625f70..e7386ce 100644
--- a/test/SemaCXX/ms-interface.cpp
+++ b/test/SemaCXX/ms-interface.cpp
@@ -10,7 +10,7 @@
   bool operator!();
   // expected-error@+1 {{operator 'operator int' is not permitted within an interface type}}
   operator int();
-  // expected-error@+1 {{nested class I1::<anonymous> is not permitted within an interface type}}
+  // expected-error@+1 {{nested class I1::(anonymous) is not permitted within an interface type}}
   struct { int a; };
   void fn2() {
     struct A { }; // should be ignored: not a nested class
diff --git a/test/SemaCXX/ms_integer_suffix.cpp b/test/SemaCXX/ms_integer_suffix.cpp
new file mode 100644
index 0000000..6b4594d
--- /dev/null
+++ b/test/SemaCXX/ms_integer_suffix.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fms-extensions -verify %s
+// expected-no-diagnostics
+
+#ifdef __SIZEOF_INT8__
+static_assert(sizeof(0i8) == __SIZEOF_INT8__, "");
+#endif
+#ifdef __SIZEOF_INT16__
+static_assert(sizeof(0i16) == __SIZEOF_INT16__, "");
+#endif
+#ifdef __SIZEOF_INT32__
+static_assert(sizeof(0i32) == __SIZEOF_INT32__, "");
+#endif
+#ifdef __SIZEOF_INT64__
+static_assert(sizeof(0i64) == __SIZEOF_INT64__, "");
+#endif
+#ifdef __SIZEOF_INT128__
+static_assert(sizeof(0i128) == __SIZEOF_INT128__, "");
+#endif
diff --git a/test/SemaCXX/ms_struct.cpp b/test/SemaCXX/ms_struct.cpp
index 37fa9a7..2832b56 100644
--- a/test/SemaCXX/ms_struct.cpp
+++ b/test/SemaCXX/ms_struct.cpp
@@ -1,5 +1,6 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -triple i686-apple-darwin9 -std=c++11 %s
-// expected-no-diagnostics
+// RUN: %clang_cc1 -fsyntax-only -Wno-error=incompatible-ms-struct -verify -triple i686-apple-darwin9 -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-error=incompatible-ms-struct -verify -triple armv7-apple-darwin9 -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -DTEST_FOR_ERROR -verify -triple armv7-apple-darwin9 -std=c++11 %s
 
 #pragma ms_struct on
 
@@ -9,10 +10,29 @@
 };
 
 struct B : public A {
+#ifdef TEST_FOR_ERROR
+  // expected-error@-2 {{ms_struct may not produce MSVC-compatible layouts for classes with base classes or virtual functions}}
+#else
+  // expected-warning@-4 {{ms_struct may not produce MSVC-compatible layouts for classes with base classes or virtual functions}}
+#endif
   unsigned long c:16;
 	int d;
   B();
 };
 
 static_assert(__builtin_offsetof(B, d) == 12,
-  "We can't allocate the bitfield into the padding under ms_struct");
\ No newline at end of file
+  "We can't allocate the bitfield into the padding under ms_struct");
+
+// rdar://16178895
+struct C {
+#ifdef TEST_FOR_ERROR
+  // expected-error@-2 {{ms_struct may not produce MSVC-compatible layouts for classes with base classes or virtual functions}}
+#else
+  // expected-warning@-4 {{ms_struct may not produce MSVC-compatible layouts for classes with base classes or virtual functions}}
+#endif
+  virtual void foo();
+  long long n;
+};
+
+static_assert(__builtin_offsetof(C, n) == 8,
+              "long long field in ms_struct should be 8-byte aligned");
diff --git a/test/SemaCXX/nested-name-spec.cpp b/test/SemaCXX/nested-name-spec.cpp
index df4f1b2..bdeb00d 100644
--- a/test/SemaCXX/nested-name-spec.cpp
+++ b/test/SemaCXX/nested-name-spec.cpp
@@ -8,13 +8,12 @@
     static int Ag1();
     static int Ag2();
   };
-  int ax;
+  int ax; // expected-note {{'ax' declared here}}
   void Af();
 }
 
 A:: ; // expected-error {{expected unqualified-id}}
-// FIXME: there is a member 'ax'; it's just not a class.
-::A::ax::undef ex3; // expected-error {{no member named 'ax'}}
+::A::ax::undef ex3; // expected-error {{'ax' is not a class, namespace, or scoped enumeration}}
 A::undef1::undef2 ex4; // expected-error {{no member named 'undef1'}}
 
 int A::C::Ag1() { return 0; }
@@ -85,10 +84,13 @@
 
 void f3() {
   N::x = 0; // expected-error {{use of undeclared identifier 'N'}}
-  int N;
-  N::x = 0; // expected-error {{expected a class or namespace}}
+  // FIXME: Consider including the kind of entity that 'N' is ("variable 'N'
+  // declared here", "template 'X' declared here", etc) to help explain what it
+  // is if it's 'not a class, namespace, or scoped enumeration'.
+  int N; // expected-note {{'N' declared here}}
+  N::x = 0; // expected-error {{'N' is not a class, namespace, or scoped enumeration}}
   { int A;           A::ax = 0; }
-  { typedef int A;   A::ax = 0; } // expected-error{{expected a class or namespace}}
+  { typedef int A;   A::ax = 0; } // expected-error{{'A' (aka 'int') is not a class, namespace, or scoped enumeration}}
   { typedef A::C A;  A::ax = 0; } // expected-error {{no member named 'ax'}}
   { typedef A::C A;  A::cx = 0; }
 }
@@ -114,7 +116,7 @@
     };
 
     void f() {
-      return E::X; // expected-error{{expected a class or namespace}}
+      return E::X; // expected-error{{'E::Nested::E' is not a class, namespace, or scoped enumeration}}
     }
   }
 }
@@ -143,7 +145,7 @@
   void g(int&); // expected-note{{type of 1st parameter of member declaration does not match definition ('int &' vs 'const int &')}}
 } 
 
-void A::f() {} // expected-error-re{{out-of-line definition of 'f' does not match any declaration in namespace 'A'$}}
+void A::f() {} // expected-error-re{{out-of-line definition of 'f' does not match any declaration in namespace 'A'{{$}}}}
 
 void A::g(const int&) { } // expected-error{{out-of-line definition of 'g' does not match any declaration in namespace 'A'}}
 
@@ -160,7 +162,7 @@
   void f();
   // FIXME: if we move this to a separate definition of N, things break!
 }
-void ::global_func2(int) { } // expected-error{{extra qualification on member 'global_func2'}}
+void ::global_func2(int) { } // expected-warning{{extra qualification on member 'global_func2'}}
 
 void N::f() { } // okay
 
@@ -308,4 +310,103 @@
 }
 
 namespace TypedefNamespace { typedef int F; };
-TypedefNamespace::F::NonexistentName BadNNSWithCXXScopeSpec; // expected-error {{expected a class or namespace}}
+TypedefNamespace::F::NonexistentName BadNNSWithCXXScopeSpec; // expected-error {{'F' (aka 'int') is not a class, namespace, or scoped enumeration}}
+
+namespace PR18587 {
+
+struct C1 {
+  int a, b, c;
+  typedef int C2;
+  struct B1 {
+    struct B2 {
+      int a, b, c;
+    };
+  };
+};
+struct C2 { static const unsigned N1 = 1; };
+struct B1 {
+  enum E1 { B2 = 2 };
+  static const int B3 = 3;
+};
+const int N1 = 2;
+
+// Function declarators
+struct S1a { int f(C1::C2); };
+struct S1b { int f(C1:C2); };  // expected-error{{unexpected ':' in nested name specifier; did you mean '::'?}}
+
+struct S2a {
+  C1::C2 f(C1::C2);
+};
+struct S2c {
+  C1::C2 f(C1:C2);  // expected-error{{unexpected ':' in nested name specifier; did you mean '::'?}}
+};
+
+struct S3a {
+  int f(C1::C2), C2 : N1;
+  int g : B1::B2;
+};
+struct S3b {
+  int g : B1:B2;  // expected-error{{unexpected ':' in nested name specifier; did you mean '::'?}}
+};
+
+// Inside square brackets
+struct S4a {
+  int f[C2::N1];
+};
+struct S4b {
+  int f[C2:N1];  // expected-error{{unexpected ':' in nested name specifier; did you mean '::'?}}
+};
+
+struct S5a {
+  int f(int xx[B1::B3 ? C2::N1 : B1::B2]);
+};
+struct S5b {
+  int f(int xx[B1::B3 ? C2::N1 : B1:B2]);  // expected-error{{unexpected ':' in nested name specifier; did you mean '::'?}}
+};
+struct S5c {
+  int f(int xx[B1:B3 ? C2::N1 : B1::B2]);  // expected-error{{unexpected ':' in nested name specifier; did you mean '::'?}}
+};
+
+// Bit fields
+struct S6a {
+  C1::C2 m1 : B1::B2;
+};
+struct S6c {
+  C1::C2 m1 : B1:B2;  // expected-error{{unexpected ':' in nested name specifier; did you mean '::'?}}
+};
+struct S6d {
+  int C2:N1;
+};
+struct S6e {
+  static const int N = 3;
+  B1::E1 : N;
+};
+struct S6g {
+  C1::C2 : B1:B2;  // expected-error{{unexpected ':' in nested name specifier; did you mean '::'?}}
+  B1::E1 : B1:B2;  // expected-error{{unexpected ':' in nested name specifier; did you mean '::'?}}
+};
+
+// Template parameters
+template <int N> struct T1 {
+  int a,b,c;
+  static const unsigned N1 = N;
+  typedef unsigned C1;
+};
+T1<C2::N1> var_1a;
+T1<C2:N1> var_1b;  // expected-error{{unexpected ':' in nested name specifier; did you mean '::'?}}
+template<int N> int F() {}
+int (*X1)() = (B1::B2 ? F<1> : F<2>);
+int (*X2)() = (B1:B2 ? F<1> : F<2>);  // expected-error{{unexpected ':' in nested name specifier; did you mean '::'?}}
+
+// Bit fields + templates
+struct S7a {
+  T1<B1::B2>::C1 m1 : T1<B1::B2>::N1;
+};
+struct S7b {
+  T1<B1:B2>::C1 m1 : T1<B1::B2>::N1;  // expected-error{{unexpected ':' in nested name specifier; did you mean '::'?}}
+};
+struct S7c {
+  T1<B1::B2>::C1 m1 : T1<B1:B2>::N1;  // expected-error{{unexpected ':' in nested name specifier; did you mean '::'?}}
+};
+
+}
diff --git a/test/SemaCXX/new-delete-cxx0x.cpp b/test/SemaCXX/new-delete-cxx0x.cpp
index c404fab..899cb4c 100644
--- a/test/SemaCXX/new-delete-cxx0x.cpp
+++ b/test/SemaCXX/new-delete-cxx0x.cpp
@@ -2,8 +2,8 @@
 
 void ugly_news(int *ip) {
   // These are ill-formed according to one reading of C++98, and at the least
-  // have undefined behavior. But they're well-formed, and defined to throw
-  // std::bad_array_new_length, in C++11.
+  // have undefined behavior.
+  // FIXME: They're ill-formed in C++11.
   (void)new int[-1]; // expected-warning {{array size is negative}}
   (void)new int[2000000000]; // expected-warning {{array is too large}}
 }
@@ -22,5 +22,12 @@
 void fn() {
   (void) new int[2] {1, 2};
   (void) new S[2] {1, 2};
-  (void) new T[2] {1, 2}; // expected-error {{no matching constructor}}
+  // C++11 [expr.new]p19:
+  //   If the new-expression creates an object or an array of objects of class
+  //   type, access and ambiguity control are done for the allocation function,
+  //   the deallocation function (12.5), and the constructor (12.1).
+  //
+  // Note that this happens even if the array bound is constant and the
+  // initializer initializes every array element.
+  (void) new T[2] {1, 2}; // expected-error {{no matching constructor}} expected-note {{in implicit initialization of array element 2}}
 }
diff --git a/test/SemaCXX/new-delete.cpp b/test/SemaCXX/new-delete.cpp
index 7facd10..cb43458 100644
--- a/test/SemaCXX/new-delete.cpp
+++ b/test/SemaCXX/new-delete.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -triple=i686-pc-linux-gnu
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple=i686-pc-linux-gnu -Wno-new-returns-null
 
 #include <stddef.h>
 
@@ -517,3 +517,10 @@
     return 0;
   }
 };
+
+namespace PR18544 {
+  inline void *operator new(size_t); // expected-error {{'operator new' cannot be declared inside a namespace}}
+}
+
+// PR19968
+inline void* operator new(); // expected-error {{'operator new' must have at least one parameter}}
diff --git a/test/SemaCXX/new-null.cpp b/test/SemaCXX/new-null.cpp
new file mode 100644
index 0000000..b2be0c5
--- /dev/null
+++ b/test/SemaCXX/new-null.cpp
@@ -0,0 +1,63 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++98
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+
+typedef __SIZE_TYPE__ size_t;
+
+#if __cplusplus >= 201103L
+struct S1 {
+   void *operator new(size_t n) {
+     return nullptr; // expected-warning {{'operator new' should not return a null pointer unless it is declared 'throw()' or 'noexcept'}}
+   }
+   void *operator new[](size_t n) noexcept {
+     return __null;
+   }
+};
+#endif
+
+struct S2 {
+   static size_t x;
+   void *operator new(size_t n) throw() {
+     return 0;
+   }
+   void *operator new[](size_t n) {
+     return (void*)0;
+#if __cplusplus >= 201103L
+     // expected-warning@-2 {{'operator new[]' should not return a null pointer unless it is declared 'throw()' or 'noexcept'}}
+#else
+     // expected-warning-re@-4 {{'operator new[]' should not return a null pointer unless it is declared 'throw()'{{$}}}}
+#endif
+   }
+};
+
+struct S3 {
+   void *operator new(size_t n) {
+     return 1-1;
+#if __cplusplus >= 201103L
+     // expected-error@-2 {{cannot initialize return object of type 'void *' with an rvalue of type 'int'}}
+#else
+     // expected-warning@-4 {{expression which evaluates to zero treated as a null pointer constant of type 'void *'}}
+     // expected-warning@-5 {{'operator new' should not return a null pointer unless it is declared 'throw()'}}
+#endif
+   }
+   void *operator new[](size_t n) {
+     return (void*)(1-1); // expected-warning {{'operator new[]' should not return a null pointer unless it is declared 'throw()'}}
+   }
+};
+
+#if __cplusplus >= 201103L
+template<bool B> struct S4 {
+  void *operator new(size_t n) noexcept(B) {
+    return 0; // expected-warning {{'operator new' should not return a null pointer}}
+  }
+};
+template struct S4<true>;
+template struct S4<false>; // expected-note {{in instantiation of}}
+#endif
+
+template<typename ...T> struct S5 { // expected-warning 0-1{{extension}}
+  void *operator new(size_t n) throw(T...) {
+    return 0; // expected-warning {{'operator new' should not return a null pointer}}
+  }
+};
+template struct S5<>;
+template struct S5<int>; // expected-note {{in instantiation of}}
diff --git a/test/SemaCXX/nonnull.cpp b/test/SemaCXX/nonnull.cpp
new file mode 100644
index 0000000..9ff6d11
--- /dev/null
+++ b/test/SemaCXX/nonnull.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<int I>
+struct TS {
+  __attribute__((returns_nonnull))
+  void *value_dependent(void) {
+    return I; // no-warning
+  }
+
+  __attribute__((returns_nonnull))
+  void *value_independent(void) {
+    return 0; // expected-warning {{null returned from function that requires a non-null return value}}
+  }
+};
+
diff --git a/test/SemaCXX/ns_returns_retained_block_return.cpp b/test/SemaCXX/ns_returns_retained_block_return.cpp
new file mode 100644
index 0000000..9d04536
--- /dev/null
+++ b/test/SemaCXX/ns_returns_retained_block_return.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fblocks -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fblocks -fobjc-arc -fsyntax-only -verify %s
+// expected-no-diagnostics
+// rdar://17259812
+
+typedef void (^BT) ();
+
+class S {
+  BT br() __attribute__((ns_returns_retained)) {
+    return ^{};
+  }
+ BT br1() __attribute__((ns_returns_retained));
+};
+
+BT S::br1() {
+    return ^{};
+}
diff --git a/test/SemaCXX/null_in_arithmetic_ops.cpp b/test/SemaCXX/null_in_arithmetic_ops.cpp
index a919213..3b42ab4 100644
--- a/test/SemaCXX/null_in_arithmetic_ops.cpp
+++ b/test/SemaCXX/null_in_arithmetic_ops.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsyntax-only -fblocks -Wnull-arithmetic -verify -Wno-string-plus-int %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsyntax-only -fblocks -Wnull-arithmetic -verify -Wno-string-plus-int -Wno-tautological-pointer-compare %s
 #include <stddef.h>
 
 void f() {
diff --git a/test/SemaCXX/nullptr_in_arithmetic_ops.cpp b/test/SemaCXX/nullptr_in_arithmetic_ops.cpp
index 9671353..60b4670 100644
--- a/test/SemaCXX/nullptr_in_arithmetic_ops.cpp
+++ b/test/SemaCXX/nullptr_in_arithmetic_ops.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fblocks -std=c++11 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-tautological-pointer-compare -fblocks -std=c++11 -verify %s
 
 void foo() {
   int a;
diff --git a/test/SemaCXX/old-style-cast.cpp b/test/SemaCXX/old-style-cast.cpp
new file mode 100644
index 0000000..73a78e4
--- /dev/null
+++ b/test/SemaCXX/old-style-cast.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -fsyntax-only -verify -Wold-style-cast %s
+
+void test1() {
+  long x = (long)12; // expected-warning {{use of old-style cast}}
+  (long)x; // expected-warning {{use of old-style cast}} expected-warning {{expression result unused}}
+  (void**)x; // expected-warning {{use of old-style cast}} expected-warning {{expression result unused}}
+  long y = static_cast<long>(12);
+  (void)y;
+  typedef void VOID;
+  (VOID)y;
+}
diff --git a/test/SemaCXX/operator-arrow-depth.cpp b/test/SemaCXX/operator-arrow-depth.cpp
index 3e2ba8e..769dae0 100644
--- a/test/SemaCXX/operator-arrow-depth.cpp
+++ b/test/SemaCXX/operator-arrow-depth.cpp
@@ -9,7 +9,7 @@
 template<int N> struct B {
   A<N-1> operator->(); // expected-note +{{'operator->' declared here produces an object of type 'A<}}
 #if MAX != 2
-  // expected-note-re@-2 {{(skipping (120|2) 'operator->'s in backtrace)}}
+  // expected-note-re@-2 {{(skipping {{120|2}} 'operator->'s in backtrace)}}
 #endif
 };
 
@@ -22,5 +22,5 @@
 int n = good->n;
 
 B<MAX/2 + 1> bad;
-int m = bad->n; // expected-error-re {{use of 'operator->' on type 'B<(2|10|128) / 2 \+ 1>' would invoke a sequence of more than (2|10|128) 'operator->' calls}}
+int m = bad->n; // expected-error-re {{use of 'operator->' on type 'B<{{2|10|128}} / 2 + 1>' would invoke a sequence of more than {{2|10|128}} 'operator->' calls}}
                 // expected-note@-1 {{use -foperator-arrow-depth=N to increase 'operator->' limit}}
diff --git a/test/SemaCXX/overload-0x.cpp b/test/SemaCXX/overload-0x.cpp
index 677d16a..1c185a5 100644
--- a/test/SemaCXX/overload-0x.cpp
+++ b/test/SemaCXX/overload-0x.cpp
@@ -1,7 +1,11 @@
-// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s 
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
 
 namespace test0 {
-  struct A { // expected-note {{candidate function (the implicit copy assignment operator) not viable: 'this' argument has type 'const test0::A', but method is not marked const}} expected-note {{candidate function (the implicit move assignment operator) not viable: 'this' argument has type 'const test0::A', but method is not marked const}}
+  struct A { // expected-note {{candidate function (the implicit copy assignment operator) not viable: 'this' argument has type 'const test0::A', but method is not marked const}}
+#if __cplusplus >= 201103L
+  // expected-note@-2 {{candidate function (the implicit move assignment operator) not viable: 'this' argument has type 'const test0::A', but method is not marked const}}
+#endif
     A &operator=(void*); // expected-note {{candidate function not viable: 'this' argument has type 'const test0::A', but method is not marked const}}
   };
 
@@ -9,3 +13,79 @@
     a = "help"; // expected-error {{no viable overloaded '='}}
   }
 }
+
+namespace PR16314 {
+  void f(char*);
+  int &f(...);
+  void x()
+  {
+    int &n = f("foo");
+#if __cplusplus < 201103L
+    // expected-warning@-2 {{conversion from string literal to 'char *' is deprecated}}
+    // expected-error@-3 {{non-const lvalue reference to type 'int' cannot bind to a temporary of type 'void'}}
+#endif
+  }
+}
+
+namespace warn_if_best {
+  int f(char *);
+  void f(double);
+  void x()
+  {
+    int n = f("foo");
+#if __cplusplus < 201103L
+    // expected-warning@-2 {{conversion from string literal to 'char *' is deprecated}}
+#else
+    // expected-warning@-4 {{ISO C++11 does not allow conversion from string literal to 'char *'}}
+#endif
+  }
+}
+
+namespace userdefined_vs_illformed {
+  struct X { X(const char *); };
+
+  void *f(char *p); // best for C++03
+  double f(X x);  // best for C++11
+  void g()
+  {
+    double d = f("foo");
+#if __cplusplus < 201103L
+    // expected-warning@-2 {{conversion from string literal to 'char *' is deprecated}}
+    // expected-error@-3 {{cannot initialize a variable of type 'double' with an rvalue of type 'void *'}}
+#endif
+  }
+}
+
+namespace sfinae_test {
+  int f(int, char*);
+
+  template<int T>
+  struct S { typedef int type; };
+
+  template<>
+  struct S<sizeof(int)> { typedef void type; };
+
+  // C++11: SFINAE failure
+  // C++03: ok
+  template<typename T> int cxx11_ignored(T, typename S<sizeof(f(T(), "foo"))>::type *);
+#if __cplusplus < 201103L
+  // expected-warning@-2 {{conversion from string literal to 'char *' is deprecated}}
+#else
+  // expected-note@-4 {{candidate template ignored: substitution failure}}
+#endif
+
+  // C++11: better than latter
+  // C++03: worse than latter
+  template<typename T> void g(T, ...);
+  template<typename T> int g(T, typename S<sizeof(f(T(), "foo"))>::type *);
+#if __cplusplus < 201103L
+  // expected-warning@-2 {{conversion from string literal to 'char *' is deprecated}}
+#endif
+
+  int a = cxx11_ignored(0, 0);
+  int b = g(0, 0);
+#if __cplusplus >= 201103L
+  // expected-error@-3 {{no matching function for call to 'cxx11_ignored'}}
+  // expected-error@-3 {{cannot initialize a variable of type 'int' with an rvalue of type 'void'}}
+#endif
+}
diff --git a/test/SemaCXX/overload-call.cpp b/test/SemaCXX/overload-call.cpp
index 615b10a..19ce144 100644
--- a/test/SemaCXX/overload-call.cpp
+++ b/test/SemaCXX/overload-call.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s
+// RUN: %clang_cc1 -pedantic -verify %s
 int* f(int) { return 0; }
 float* f(float) { return 0; }
 void f();
@@ -580,3 +580,31 @@
   void f(const volatile int &, int);
   void g() { f(0, 0); }
 }
+
+void test5() {
+  struct {
+    typedef void F1(int);
+    typedef void F2(double);
+    operator F1*();  // expected-note{{conversion candidate}}
+    operator F2*();  // expected-note{{conversion candidate}}
+  } callable;
+  callable();  // expected-error{{no matching function for call}}
+}
+
+namespace PR20218 {
+  void f(void (*const &)()); // expected-note 2{{candidate}}
+  void f(void (&&)()) = delete; // expected-note 2{{candidate}} expected-warning 2{{extension}}
+  void g(void (&&)()) = delete; // expected-note 2{{candidate}} expected-warning 2{{extension}}
+  void g(void (*const &)()); // expected-note 2{{candidate}}
+
+  void x();
+  typedef void (&fr)();
+  struct Y { operator fr(); } y;
+
+  void h() {
+    f(x); // expected-error {{ambiguous}}
+    g(x); // expected-error {{ambiguous}}
+    f(y); // expected-error {{ambiguous}}
+    g(y); // expected-error {{ambiguous}}
+  }
+}
diff --git a/test/SemaCXX/overloaded-operator.cpp b/test/SemaCXX/overloaded-operator.cpp
index 99105cb..feb7c71 100644
--- a/test/SemaCXX/overloaded-operator.cpp
+++ b/test/SemaCXX/overloaded-operator.cpp
@@ -452,3 +452,70 @@
     Result = 1; // expected-error {{no viable overloaded '='}} // expected-note {{type 'PointerUnion<int *, float *>' is incomplete}}
   }
 }
+
+namespace PR14995 {
+  struct B {};
+  template<typename ...T> void operator++(B, T...) {}
+
+  void f() {
+    B b;
+    b++;  // ok
+    ++b;  // ok
+  }
+
+  template<typename... T>
+  struct C {
+    void operator-- (T...) {}
+  };
+
+  void g() {
+    C<int> postfix;
+    C<> prefix;
+    postfix--;  // ok
+    --prefix;  // ok
+  }
+
+  struct D {};
+  template<typename T> void operator++(D, T) {}
+
+  void h() {
+    D d;
+    d++;  // ok
+    ++d; // expected-error{{cannot increment value of type 'PR14995::D'}}
+  }
+
+  template<typename...T> struct E {
+    void operator++(T...) {} // expected-error{{parameter of overloaded post-increment operator must have type 'int' (not 'char')}}
+  };
+
+  E<char> e; // expected-note {{in instantiation of template class 'PR14995::E<char>' requested here}}
+  
+  struct F {
+    template<typename... T>
+    int operator++ (T...) {}
+  };
+
+  int k1 = F().operator++(0, 0);
+  int k2 = F().operator++('0');
+  // expected-error@-5 {{overloaded 'operator++' must be a unary or binary operator}}
+  // expected-note@-3 {{in instantiation of function template specialization 'PR14995::F::operator++<int, int>' requested here}}
+  // expected-error@-4 {{no matching member function for call to 'operator++'}}
+  // expected-note@-8 {{candidate template ignored: substitution failure}}
+  // expected-error@-9 {{parameter of overloaded post-increment operator must have type 'int' (not 'char')}}
+  // expected-note@-6 {{in instantiation of function template specialization 'PR14995::F::operator++<char>' requested here}}
+  // expected-error@-7 {{no matching member function for call to 'operator++'}}
+  // expected-note@-12 {{candidate template ignored: substitution failure}}
+} // namespace PR14995
+
+namespace ConversionVersusTemplateOrdering {
+  struct A {
+    operator short() = delete;
+    template <typename T> operator T();
+  } a;
+  struct B {
+    template <typename T> operator T();
+    operator short() = delete;
+  } b;
+  int x = a;
+  int y = b;
+}
diff --git a/test/SemaCXX/pr13394-crash-on-invalid.cpp b/test/SemaCXX/pr13394-crash-on-invalid.cpp
index 841e3c2..304ee92 100644
--- a/test/SemaCXX/pr13394-crash-on-invalid.cpp
+++ b/test/SemaCXX/pr13394-crash-on-invalid.cpp
@@ -8,12 +8,12 @@
 }
 namespace gatekeeper_v1 {
   namespace gatekeeper_factory_v1 {
-    struct closure_t { // expected-note {{'closure_t' declared here}}
+    struct closure_t { // expected-note {{'closure_t' declared here}} expected-note {{'gatekeeper_factory_v1::closure_t' declared here}}
       gatekeeper_v1::closure_t* create(); // expected-error {{no type named 'closure_t' in namespace 'gatekeeper_v1'; did you mean simply 'closure_t'?}}
     };
   }
   // FIXME: Typo correction should remove the 'gatekeeper_v1::' name specifier
-  gatekeeper_v1::closure_t *x; // expected-error-re {{no type named 'closure_t' in namespace 'gatekeeper_v1'$}}
+  gatekeeper_v1::closure_t *x; // expected-error {{no type named 'closure_t' in namespace 'gatekeeper_v1'; did you mean 'gatekeeper_factory_v1::closure_t'}}
 }
 
 namespace Foo {
diff --git a/test/SemaCXX/pr18284-crash-on-invalid.cpp b/test/SemaCXX/pr18284-crash-on-invalid.cpp
new file mode 100644
index 0000000..5b1cb21
--- /dev/null
+++ b/test/SemaCXX/pr18284-crash-on-invalid.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// Don't crash (PR18284).
+
+namespace n1 {
+class A { };
+class C { A a; };
+
+A::RunTest() {} // expected-error {{C++ requires a type specifier for all declarations}}
+
+void f() {
+  new C;
+}
+} // namespace n1
+
+namespace n2 {
+class A { };
+class C : public A { };
+
+A::RunTest() {} // expected-error {{C++ requires a type specifier for all declarations}}
+
+void f() {
+  new C;
+}
+} // namespace n2
diff --git a/test/SemaCXX/pr9812.c b/test/SemaCXX/pr9812.c
new file mode 100644
index 0000000..cbbe44b
--- /dev/null
+++ b/test/SemaCXX/pr9812.c
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+#define bool _Bool
+int test1(int argc, char** argv)
+{
+    bool signed;  // expected-error {{'bool' cannot be signed or unsigned}} expected-warning {{declaration does not declare anything}}
+
+    return 0;
+}
+#undef bool
+
+typedef int bool;
+
+int test2(int argc, char** argv)
+{
+    bool signed; // expected-error {{'type-name' cannot be signed or unsigned}} expected-warning {{declaration does not declare anything}}
+    _Bool signed; // expected-error {{'_Bool' cannot be signed or unsigned}} expected-warning {{declaration does not declare anything}}
+
+    return 0;
+}
+
diff --git a/test/SemaCXX/pr9812.cpp b/test/SemaCXX/pr9812.cpp
new file mode 100644
index 0000000..2cd0bed
--- /dev/null
+++ b/test/SemaCXX/pr9812.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+int test(int, char**)
+{
+    bool signed; // expected-error {{'bool' cannot be signed or unsigned}} expected-warning {{declaration does not declare anything}}
+
+    return 0;
+}
+
diff --git a/test/SemaCXX/pragma-init_seg.cpp b/test/SemaCXX/pragma-init_seg.cpp
new file mode 100644
index 0000000..e18d0e6
--- /dev/null
+++ b/test/SemaCXX/pragma-init_seg.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions %s -triple x86_64-pc-win32
+// RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions %s -triple i386-apple-darwin13.3.0
+
+#ifndef __APPLE__
+#pragma init_seg(L".my_seg") // expected-warning {{expected 'compiler', 'lib', 'user', or a string literal}}
+#pragma init_seg( // expected-warning {{expected 'compiler', 'lib', 'user', or a string literal}}
+#pragma init_seg asdf // expected-warning {{missing '('}}
+#pragma init_seg) // expected-warning {{missing '('}}
+#pragma init_seg("a" "b") // no warning
+#pragma init_seg("a", "b") // expected-warning {{missing ')'}}
+#pragma init_seg("a") asdf // expected-warning {{extra tokens at end of '#pragma init_seg'}}
+#pragma init_seg("\x") // expected-error {{\x used with no following hex digits}}
+#pragma init_seg("a" L"b") // expected-warning {{expected non-wide string literal in '#pragma init_seg'}}
+
+#pragma init_seg(compiler)
+#else
+#pragma init_seg(compiler) // expected-warning {{'#pragma init_seg' is only supported when targeting a Microsoft environment}}
+#endif
+
+int f();
+int __declspec(thread) x = f(); // expected-error {{initializer for thread-local variable must be a constant expression}}
diff --git a/test/SemaCXX/pragma-optimize.cpp b/test/SemaCXX/pragma-optimize.cpp
new file mode 100644
index 0000000..0f03b81
--- /dev/null
+++ b/test/SemaCXX/pragma-optimize.cpp
@@ -0,0 +1,113 @@
+// RUN: %clang_cc1 -x c++ -std=c++11 -triple x86_64-unknown-linux -emit-llvm -O2 < %s | FileCheck %s
+
+#pragma clang optimize off
+
+// This is a macro definition and therefore its text is not present after
+// preprocessing. The pragma has no effect here.
+#define CREATE_FUNC(name)        \
+int name (int param) {           \
+    return param;                \
+}                                \
+
+// This is a declaration and therefore it is not decorated with `optnone`.
+extern int foo(int a, int b);
+// CHECK-DAG: @_Z3fooii{{.*}} [[ATTRFOO:#[0-9]+]]
+
+// This is a definition and therefore it will be decorated with `optnone`.
+int bar(int x, int y) {
+    for(int i = 0; i < x; ++i)
+        y += x;
+    return y + foo(x, y);
+}
+// CHECK-DAG: @_Z3barii{{.*}} [[ATTRBAR:#[0-9]+]]
+
+// The function "int created (int param)" created by the macro invocation
+// is also decorated with the `optnone` attribute because it is within a
+// region of code affected by the functionality (not because of the position
+// of the macro definition).
+CREATE_FUNC (created)
+// CHECK-DAG: @_Z7createdi{{.*}} [[ATTRCREATED:#[0-9]+]]
+
+class MyClass {
+    public:
+        // The declaration of the method is not decorated with `optnone`.
+        int method(int blah);
+};
+
+// The definition of the method instead is decorated with `optnone`.
+int MyClass::method(int blah) {
+    return blah + 1;
+}
+// CHECK-DAG: @_ZN7MyClass6methodEi{{.*}} [[ATTRMETHOD:#[0-9]+]]
+
+// A template declaration will not be decorated with `optnone`.
+template <typename T> T twice (T param);
+
+// The template definition will be decorated with the attribute `optnone`.
+template <typename T> T thrice (T param) {
+    return 3 * param;
+}
+
+// This function definition will not be decorated with `optnone` because the
+// attribute would conflict with `always_inline`.
+int __attribute__((always_inline)) baz(int z) {
+    return foo(z, 2);
+}
+// CHECK-DAG: @_Z3bazi{{.*}} [[ATTRBAZ:#[0-9]+]]
+
+#pragma clang optimize on
+
+// The function "int wombat(int param)" created by the macro is not
+// decorated with `optnone`, because the pragma applies its effects only
+// after preprocessing. The position of the macro definition is not
+// relevant.
+CREATE_FUNC (wombat)
+// CHECK-DAG: @_Z6wombati{{.*}} [[ATTRWOMBAT:#[0-9]+]]
+
+// This instantiation of the "twice" template function with a "float" type
+// will not have an `optnone` attribute because the template declaration was
+// not affected by the pragma.
+float container (float par) {
+    return twice(par);
+}
+// CHECK-DAG: @_Z9containerf{{.*}} [[ATTRCONTAINER:#[0-9]+]]
+// CHECK-DAG: @_Z5twiceIfET_S0_{{.*}} [[ATTRTWICE:#[0-9]+]]
+
+// This instantiation of the "thrice" template function with a "float" type
+// will have an `optnone` attribute because the template definition was
+// affected by the pragma.
+float container2 (float par) {
+    return thrice(par);
+}
+// CHECK-DAG: @_Z10container2f{{.*}} [[ATTRCONTAINER2:#[0-9]+]]
+// CHECK-DAG: @_Z6thriceIfET_S0_{{.*}} [[ATTRTHRICEFLOAT:#[0-9]+]]
+
+
+// A template specialization is a new definition and it will not be
+// decorated with an `optnone` attribute because it is now outside of the
+// affected region.
+template<> int thrice(int par) {
+    return (par << 1) + par;
+}
+int container3 (int par) {
+    return thrice(par);
+}
+// CHECK-DAG: @_Z10container3i{{.*}} [[ATTRCONTAINER3:#[0-9]+]]
+// CHECK-DAG: @_Z6thriceIiET_S0_{{.*}} [[ATTRTHRICEINT:#[0-9]+]]
+
+
+// Check for both noinline and optnone on each function that should have them.
+// CHECK-DAG: attributes [[ATTRBAR]] = { {{.*}}noinline{{.*}}optnone{{.*}} }
+// CHECK-DAG: attributes [[ATTRCREATED]] = { {{.*}}noinline{{.*}}optnone{{.*}} }
+// CHECK-DAG: attributes [[ATTRMETHOD]] = { {{.*}}noinline{{.*}}optnone{{.*}} }
+// CHECK-DAG: attributes [[ATTRTHRICEFLOAT]] = { {{.*}}noinline{{.*}}optnone{{.*}} }
+
+// Check that the other functions do NOT have optnone.
+// CHECK-DAG-NOT: attributes [[ATTRFOO]] = { {{.*}}optnone{{.*}} }
+// CHECK-DAG-NOT: attributes [[ATTRBAZ]] = { {{.*}}optnone{{.*}} }
+// CHECK-DAG-NOT: attributes [[ATTRWOMBAT]] = { {{.*}}optnone{{.*}} }
+// CHECK-DAG-NOT: attributes [[ATTRCONTAINER]] = { {{.*}}optnone{{.*}} }
+// CHECK-DAG-NOT: attributes [[ATTRTWICE]] = { {{.*}}optnone{{.*}} }
+// CHECK-DAG-NOT: attributes [[ATTRCONTAINER2]] = { {{.*}}optnone{{.*}} }
+// CHECK-DAG-NOT: attributes [[ATTRCONTAINER3]] = { {{.*}}optnone{{.*}} }
+// CHECK-DAG-NOT: attributes [[ATTRTHRICEINT]] = { {{.*}}optnone{{.*}} }
diff --git a/test/SemaCXX/pragma-vtordisp.cpp b/test/SemaCXX/pragma-vtordisp.cpp
new file mode 100644
index 0000000..49841c5
--- /dev/null
+++ b/test/SemaCXX/pragma-vtordisp.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -std=c++11 -fms-extensions -fms-compatibility -fsyntax-only -triple=i386-pc-win32 -verify %s
+
+struct A { int a; };
+
+#pragma vtordisp(pop) // expected-warning {{#pragma vtordisp(pop, ...) failed: stack empty}}
+#pragma vtordisp(push, 0)
+#pragma vtordisp(push, 1)
+#pragma vtordisp(push, 2)
+struct B : virtual A { int b; };
+#pragma vtordisp(pop)
+#pragma vtordisp(pop)
+#pragma vtordisp(pop)
+#pragma vtordisp(pop) // expected-warning {{#pragma vtordisp(pop, ...) failed: stack empty}}
+
+#pragma vtordisp(push, 3) // expected-warning {{expected integer between 0 and 2 inclusive in '#pragma vtordisp' - ignored}}
+#pragma vtordisp()
+
+#define ONE 1
+#pragma vtordisp(push, ONE)
+#define TWO 1
+#pragma vtordisp(push, TWO)
+
+// Test a reset.
+#pragma vtordisp()
+#pragma vtordisp(pop) // expected-warning {{#pragma vtordisp(pop, ...) failed: stack empty}}
+
+#pragma vtordisp(      // expected-warning {{unknown action for '#pragma vtordisp' - ignored}}
+#pragma vtordisp(asdf) // expected-warning {{unknown action for '#pragma vtordisp' - ignored}}
+#pragma vtordisp(,)    // expected-warning {{unknown action for '#pragma vtordisp' - ignored}}
+#pragma vtordisp       // expected-warning {{missing '(' after '#pragma vtordisp' - ignoring}}
+#pragma vtordisp(3)    // expected-warning {{expected integer between 0 and 2 inclusive in '#pragma vtordisp' - ignored}}
+#pragma vtordisp(), stuff // expected-warning {{extra tokens}}
+
+struct C {
+// FIXME: Our implementation based on token insertion makes it impossible for
+// the pragma to appear everywhere we should support it.
+//#pragma vtordisp()
+  struct D : virtual A {
+  };
+};
diff --git a/test/SemaCXX/pragma-weak.cpp b/test/SemaCXX/pragma-weak.cpp
index 057cf6b..c1ff206 100644
--- a/test/SemaCXX/pragma-weak.cpp
+++ b/test/SemaCXX/pragma-weak.cpp
@@ -6,3 +6,6 @@
   void foo() {
   };
 }
+
+extern "C" int Test;
+#pragma weak test = Test
diff --git a/test/SemaCXX/primary-base.cpp b/test/SemaCXX/primary-base.cpp
index 0b6aaef..d305aa3 100644
--- a/test/SemaCXX/primary-base.cpp
+++ b/test/SemaCXX/primary-base.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only -verify %s
 // expected-no-diagnostics
 class A { virtual void f(); };
 class B : virtual A { };
diff --git a/test/SemaCXX/qualified-id-lookup.cpp b/test/SemaCXX/qualified-id-lookup.cpp
index 23164fa..8eef6f4 100644
--- a/test/SemaCXX/qualified-id-lookup.cpp
+++ b/test/SemaCXX/qualified-id-lookup.cpp
@@ -94,7 +94,7 @@
 void test_a() {
   a::a::i = 3; // expected-error{{no member named 'i' in namespace 'a::a'; did you mean 'a::a::a::i'?}}
   a::a::a::i = 4;
-  a::a::j = 3; // expected-error-re{{no member named 'j' in namespace 'a::a'$}}
+  a::a::j = 3; // expected-error-re{{no member named 'j' in namespace 'a::a'{{$}}}}
 }
   
 struct Undef { // expected-note{{definition of 'Undef' is not complete until the closing '}'}}
diff --git a/test/SemaCXX/references.cpp b/test/SemaCXX/references.cpp
index 37fc2a8..cfe7dc1 100644
--- a/test/SemaCXX/references.cpp
+++ b/test/SemaCXX/references.cpp
@@ -85,9 +85,19 @@
   typedef int& intref;
   typedef intref& intrefref; // C++ DR 106: reference collapsing
 
-  typedef intref const intref_c; // okay. FIXME: how do we verify that this is the same type as intref?
+  typedef intref const intref_c; // expected-warning {{'const' qualifier on reference type 'intref' (aka 'int &') has no effect}}
+  typedef intref_c intref; // ok, same type
+
+  typedef intref volatile intref; // expected-warning {{'volatile' qualifier on reference type 'intref' (aka 'int &') has no effect}}
+  typedef intref _Atomic intref; // expected-warning {{'_Atomic' qualifier on reference type 'intref' (aka 'int &') has no effect}}
+
+  void restrict_ref(__restrict intref); // ok
+  void restrict_ref(int &__restrict); // ok
 }
 
+template<typename T> int const_param(const T) {}
+int const_ref_param = const_param<int&>(const_ref_param); // no-warning
+
 
 class string {
   char *Data;
diff --git a/test/SemaCXX/reinterpret-cast.cpp b/test/SemaCXX/reinterpret-cast.cpp
index a4bc432..4284032 100644
--- a/test/SemaCXX/reinterpret-cast.cpp
+++ b/test/SemaCXX/reinterpret-cast.cpp
@@ -96,12 +96,12 @@
   void (structure::*psf)() = 0;
   (void)reinterpret_cast<int (structure::*)()>(psf);
 
-  (void)reinterpret_cast<void (structure::*)()>(psi); // expected-error {{reinterpret_cast from 'const int structure::*' to 'void (structure::*)()' is not allowed}}
-  (void)reinterpret_cast<int structure::*>(psf); // expected-error {{reinterpret_cast from 'void (structure::*)()' to 'int structure::*' is not allowed}}
+  (void)reinterpret_cast<void (structure::*)()>(psi); // expected-error-re {{reinterpret_cast from 'const int structure::*' to 'void (structure::*)(){{( __attribute__\(\(thiscall\)\))?}}' is not allowed}}
+  (void)reinterpret_cast<int structure::*>(psf); // expected-error-re {{reinterpret_cast from 'void (structure::*)(){{( __attribute__\(\(thiscall\)\))?}}' to 'int structure::*' is not allowed}}
 
   // Cannot cast from integers to member pointers, not even the null pointer
   // literal.
-  (void)reinterpret_cast<void (structure::*)()>(0); // expected-error {{reinterpret_cast from 'int' to 'void (structure::*)()' is not allowed}}
+  (void)reinterpret_cast<void (structure::*)()>(0); // expected-error-re {{reinterpret_cast from 'int' to 'void (structure::*)(){{( __attribute__\(\(thiscall\)\))?}}' is not allowed}}
   (void)reinterpret_cast<int structure::*>(0); // expected-error {{reinterpret_cast from 'int' to 'int structure::*' is not allowed}}
 }
 
diff --git a/test/SemaCXX/return-noreturn.cpp b/test/SemaCXX/return-noreturn.cpp
index 617de00..531dc23 100644
--- a/test/SemaCXX/return-noreturn.cpp
+++ b/test/SemaCXX/return-noreturn.cpp
@@ -40,6 +40,14 @@
     switch (x) default: L1: L2: case 4: { pr6884_abort_struct(); }
   }
 
+  // FIXME: detect noreturn destructors triggered by calls to delete.
+  int f7(int x) {
+    switch (x) default: L1: L2: case 4: {
+      pr6884_abort_struct *p = new pr6884_abort_struct();
+      delete p;
+    }
+  } // expected-warning {{control reaches end of non-void function}}
+
   // Test that these constructs work even when extraneous blocks are created
   // before and after the switch due to implicit destructors.
   int g1(int x) {
@@ -138,3 +146,25 @@
     PR9412_t<PR9412_Exact>(); // expected-note {{in instantiation of function template specialization 'PR9412_t<0>' requested here}}
 }
 
+#if __cplusplus >= 201103L
+namespace LambdaVsTemporaryDtor {
+  struct Y { ~Y(); };
+  struct X { template<typename T> X(T, Y = Y()) {} };
+
+  struct Fatal { ~Fatal() __attribute__((noreturn)); };
+  struct FatalCopy { FatalCopy(); FatalCopy(const FatalCopy&, Fatal F = Fatal()); };
+
+  void foo();
+
+  int bar() {
+    X work([](){ Fatal(); });
+    foo();
+  } // expected-warning {{control reaches end of non-void function}}
+
+  int baz() {
+    FatalCopy fc;
+    X work([fc](){});
+    foo();
+  } // ok, initialization of lambda does not return
+}
+#endif
diff --git a/test/SemaCXX/return-stack-addr.cpp b/test/SemaCXX/return-stack-addr.cpp
index fbbaf83..7670798e 100644
--- a/test/SemaCXX/return-stack-addr.cpp
+++ b/test/SemaCXX/return-stack-addr.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
 
 int* ret_local() {
   int x = 1;
@@ -108,6 +108,11 @@
   return const_cast<int*>(&x);  // expected-warning {{address of stack memory}}
 }
 
+struct A { virtual ~A(); }; struct B : A {};
+A* ret_cpp_dynamic_cast(B b) {
+  return dynamic_cast<A*>(&b); // expected-warning {{address of stack memory}}
+}
+
 // PR 7999 - handle the case where a field is itself a reference.
 template <typename T> struct PR7999 {
   PR7999(T& t) : value(t) {}
@@ -137,5 +142,17 @@
   }
 }
 
-// TODO: test case for dynamic_cast.  clang does not yet have
-// support for C++ classes to write such a test case.
+// Don't warn about returning a local variable from a surrounding function if
+// we're within a lambda-expression.
+void ret_from_lambda() {
+  int a;
+  int &b = a;
+  (void) [&]() -> int& { return a; };
+  (void) [&]() -> int& { return b; };
+  (void) [=]() mutable -> int& { return a; };
+  (void) [=]() mutable -> int& { return b; };
+  (void) [&]() -> int& { int a; return a; }; // expected-warning {{reference to stack}}
+  (void) [=]() -> int& { int a; return a; }; // expected-warning {{reference to stack}}
+  (void) [&]() -> int& { int &a = b; return a; };
+  (void) [=]() mutable -> int& { int &a = b; return a; };
+}
diff --git a/test/SemaCXX/return.cpp b/test/SemaCXX/return.cpp
index 580f0a7..98dbd51 100644
--- a/test/SemaCXX/return.cpp
+++ b/test/SemaCXX/return.cpp
@@ -102,3 +102,13 @@
     }
   };
 }
+
+// rdar://15366494
+// pr17759
+namespace ctor_returns_void {
+  void f() {}
+  struct S { 
+    S() { return f(); }; // expected-error {{constructor 'S' must not return void expression}}
+    ~S() { return f(); } // expected-error {{destructor '~S' must not return void expression}}
+  };
+}
diff --git a/test/SemaCXX/rval-references-examples.cpp b/test/SemaCXX/rval-references-examples.cpp
index 110ae26..8a5b562 100644
--- a/test/SemaCXX/rval-references-examples.cpp
+++ b/test/SemaCXX/rval-references-examples.cpp
@@ -4,7 +4,7 @@
 class unique_ptr {
   T *ptr;
 
-  unique_ptr(const unique_ptr&) = delete; // expected-note 3{{function has been explicitly marked deleted here}}
+  unique_ptr(const unique_ptr&) = delete; // expected-note 3{{'unique_ptr' has been explicitly marked deleted here}}
   unique_ptr &operator=(const unique_ptr&) = delete; // expected-note{{candidate function has been explicitly deleted}}
 public:
   unique_ptr() : ptr(0) { }
diff --git a/test/SemaCXX/scope-check.cpp b/test/SemaCXX/scope-check.cpp
index 90c9317..dc15dc8 100644
--- a/test/SemaCXX/scope-check.cpp
+++ b/test/SemaCXX/scope-check.cpp
@@ -1,6 +1,18 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -fblocks -fcxx-exceptions %s -Wno-unreachable-code
 // RUN: %clang_cc1 -fsyntax-only -verify -fblocks -fcxx-exceptions -std=gnu++11 %s -Wno-unreachable-code
 
+namespace testInvalid {
+Invalid inv; // expected-error {{unknown type name}}
+// Make sure this doesn't assert.
+void fn()
+{
+    int c = 0;
+    if (inv)
+Here: ;
+    goto Here;
+}
+}
+
 namespace test0 {
   struct D { ~D(); };
 
@@ -226,7 +238,7 @@
     static void *ips[] = { &&l0 };
     const C c0 = 17;
   l0: // expected-note {{possible target of indirect goto}}
-    const C &c1 = 42; // expected-note {{jump exits scope of variable with non-trivial destructor}}
+    const C &c1 = 42; // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}}
     const C &c2 = c0;
     goto *ip; // expected-error {{indirect goto might cross protected scopes}}
   }
@@ -241,7 +253,7 @@
   void f(void **ip) {
     static void *ips[] = { &&l0 };
   l0: // expected-note {{possible target of indirect goto}}
-    const int &c1 = C(1).i; // expected-note {{jump exits scope of variable with non-trivial destructor}}
+    const int &c1 = C(1).i; // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}}
     goto *ip;  // expected-error {{indirect goto might cross protected scopes}}
   }
 }
@@ -295,15 +307,137 @@
 }
 #endif
 
-// This test must be last, because the error prohibits further jump diagnostics.
-namespace testInvalid {
-Invalid inv; // expected-error {{unknown type name}}
-// Make sure this doesn't assert.
-void fn()
-{
-    int c = 0;
-    if (inv)
-Here: ;
-    goto Here;
+namespace test18 {
+  struct A { ~A(); };
+  struct B { const int &r; const A &a; };
+  int f() {
+    void *p = &&x;
+    const A a = A();
+  x:
+    B b = { 0, a }; // ok
+    goto *p;
+  }
+  int g() {
+    void *p = &&x;
+  x: // expected-note {{possible target of indirect goto}}
+    B b = { 0, A() }; // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}}
+    goto *p; // expected-error {{indirect goto might cross protected scopes}}
+  }
 }
+
+#if __cplusplus >= 201103L
+namespace std {
+  typedef decltype(sizeof(int)) size_t;
+  template<typename T> struct initializer_list {
+    const T *begin;
+    size_t size;
+    initializer_list(const T *, size_t);
+  };
+}
+namespace test19 {
+  struct A { ~A(); };
+
+  int f() {
+    void *p = &&x;
+    A a;
+  x: // expected-note {{possible target of indirect goto}}
+    std::initializer_list<A> il = { a }; // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}}
+    goto *p; // expected-error {{indirect goto might cross protected scopes}}
+  }
+}
+
+namespace test20 {
+  struct A { ~A(); };
+  struct B {
+    const A &a;
+  };
+
+  int f() {
+    void *p = &&x;
+    A a;
+  x:
+    std::initializer_list<B> il = {
+      a,
+      a
+    };
+    goto *p;
+  }
+  int g() {
+    void *p = &&x;
+    A a;
+  x: // expected-note {{possible target of indirect goto}}
+    std::initializer_list<B> il = {
+      a,
+      { A() } // expected-note {{jump exits scope of lifetime-extended temporary with non-trivial destructor}}
+    };
+    goto *p; // expected-error {{indirect goto might cross protected scopes}}
+  }
+}
+#endif
+
+namespace test21 {
+  template<typename T> void f() {
+  goto x; // expected-error {{protected scope}}
+    T t; // expected-note {{bypasses}}
+ x: return;
+  }
+
+  template void f<int>();
+  struct X { ~X(); };
+  template void f<X>(); // expected-note {{instantiation of}}
+}
+
+namespace PR18217 {
+  typedef int *X;
+
+  template <typename T>
+  class MyCl {
+    T mem;
+  };
+
+  class Source {
+    MyCl<X> m;
+  public:
+    int getKind() const;
+  };
+
+  bool b;
+  template<typename TT>
+  static void foo(const Source &SF, MyCl<TT *> Source::*m) {
+    switch (SF.getKind()) {
+      case 1: return;
+      case 2: break;
+      case 3:
+      case 4: return;
+    };
+    if (b) {
+      auto &y = const_cast<MyCl<TT *> &>(SF.*m); // expected-warning 0-1{{extension}}
+    }
+  }
+
+  int Source::getKind() const {
+    foo(*this, &Source::m);
+    return 0;
+  }
+}
+
+namespace test_recovery {
+  // Test that jump scope checking recovers when there are unspecified errors
+  // in the function declaration or body.
+
+  void test(nexist, int c) { // expected-error {{}}
+    nexist_fn(); // expected-error {{}}
+    goto nexist_label; // expected-error {{use of undeclared label}}
+    goto a0; // expected-error {{goto into protected scope}}
+    int a = 0; // expected-note {{jump bypasses variable initialization}}
+    a0:;
+
+    switch (c) {
+    case $: // expected-error {{}}
+    case 0:
+      int x = 56; // expected-note {{jump bypasses variable initialization}}
+    case 1: // expected-error {{switch case is in protected scope}}
+      x = 10;
+    }
+  }
 }
diff --git a/test/SemaCXX/sourceranges.cpp b/test/SemaCXX/sourceranges.cpp
index 1f25d5b..9ba003a 100644
--- a/test/SemaCXX/sourceranges.cpp
+++ b/test/SemaCXX/sourceranges.cpp
@@ -12,7 +12,7 @@
 typedef int C;
 }
 
-// CHECK: VarDecl {{0x[0-9a-fA-F]+}} <line:16:1, col:36> ImplicitConstrArray 'foo::A [2]'
+// CHECK: VarDecl {{0x[0-9a-fA-F]+}} <line:16:1, col:36> col:15 ImplicitConstrArray 'foo::A [2]'
 static foo::A ImplicitConstrArray[2];
 
 int main() {
@@ -28,3 +28,12 @@
   // CHECK: CXXConstructExpr {{0x[0-9a-fA-F]+}} <col:10, col:17> 'foo::A'
   return foo::A();
 }
+
+void destruct(foo::A *a1, foo::A *a2, P<int> *p1) {
+  // CHECK: MemberExpr {{0x[0-9a-fA-F]+}} <col:3, col:8> '<bound member function type>' ->~A
+  a1->~A();
+  // CHECK: MemberExpr {{0x[0-9a-fA-F]+}} <col:3, col:16> '<bound member function type>' ->~A
+  a2->foo::A::~A();
+  // CHECK: MemberExpr {{0x[0-9a-fA-F]+}} <col:3, col:13> '<bound member function type>' ->~P
+  p1->~P<int>();
+}
diff --git a/test/SemaCXX/static-assert.cpp b/test/SemaCXX/static-assert.cpp
index 4a7560b..7de4d07 100644
--- a/test/SemaCXX/static-assert.cpp
+++ b/test/SemaCXX/static-assert.cpp
@@ -48,3 +48,6 @@
 struct X { ~X(); };
 StaticAssertProtected<int> sap1;
 StaticAssertProtected<X> sap2; // expected-note {{instantiation}}
+
+static_assert(true); // expected-warning {{C++1z extension}}
+static_assert(false); // expected-error-re {{failed{{$}}}} expected-warning {{extension}}
diff --git a/test/SemaCXX/static-cast.cpp b/test/SemaCXX/static-cast.cpp
index 7fb016e..06fd8636e 100644
--- a/test/SemaCXX/static-cast.cpp
+++ b/test/SemaCXX/static-cast.cpp
@@ -9,6 +9,8 @@
 struct G1 : public B {};
 struct G2 : public B {};
 struct H : public G1, public G2 {}; // Ambiguous path to B.
+struct I;                           // Incomplete.
+struct J;                           // Incomplete.
 
 enum Enum { En1, En2 };
 enum Onom { On1, On2 };
@@ -131,6 +133,7 @@
   // Bad code below
   (void)static_cast<int A::*>((int H::*)0); // expected-error {{ambiguous conversion from pointer to member of derived class 'H' to pointer to member of base class 'A':}}
   (void)static_cast<int A::*>((int F::*)0); // expected-error {{conversion from pointer to member of class 'F' to pointer to member of class 'A' via virtual base 'B' is not allowed}}
+  (void)static_cast<int I::*>((int J::*)0); // expected-error {{static_cast from 'int J::*' to 'int I::*' is not allowed}}
 }
 
 // PR 5261 - static_cast should instantiate template if possible
@@ -192,6 +195,6 @@
     (void)static_cast<void (A::*)()>(&B::f);
     (void)static_cast<void (B::*)()>(&B::f);
     (void)static_cast<void (C::*)()>(&B::f);
-    (void)static_cast<void (D::*)()>(&B::f); // expected-error{{address of overloaded function 'f' cannot be static_cast to type 'void (PR6072::D::*)()'}}
+    (void)static_cast<void (D::*)()>(&B::f); // expected-error-re{{address of overloaded function 'f' cannot be static_cast to type 'void (PR6072::D::*)(){{( __attribute__\(\(thiscall\)\))?}}'}}
   }
 }
diff --git a/test/SemaCXX/switch-implicit-fallthrough-blocks.cpp b/test/SemaCXX/switch-implicit-fallthrough-blocks.cpp
new file mode 100644
index 0000000..9a16f2b
--- /dev/null
+++ b/test/SemaCXX/switch-implicit-fallthrough-blocks.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=c++11 -Wimplicit-fallthrough %s
+
+void fallthrough_in_blocks() {
+  void (^block)() = ^{
+    int x = 0;
+    switch (x) {
+    case 0:
+      x++;
+      [[clang::fallthrough]]; // no diagnostics
+    case 1:
+      x++;
+    default: // \
+        expected-warning{{unannotated fall-through between switch labels}} \
+        expected-note{{insert 'break;' to avoid fall-through}}
+      break;
+    }
+  };
+  block();
+}
diff --git a/test/SemaCXX/switch-implicit-fallthrough.cpp b/test/SemaCXX/switch-implicit-fallthrough.cpp
index d795923..0bc43cd 100644
--- a/test/SemaCXX/switch-implicit-fallthrough.cpp
+++ b/test/SemaCXX/switch-implicit-fallthrough.cpp
@@ -229,6 +229,59 @@
   return n;
 }
 
+// Fallthrough annotations in local classes used to generate "fallthrough
+// annotation does not directly precede switch label" warning.
+void fallthrough_in_local_class() {
+  class C {
+    void f(int x) {
+      switch (x) {
+        case 0:
+          x++;
+          [[clang::fallthrough]]; // no diagnostics
+        case 1:
+          x++;
+        default: // \
+            expected-warning{{unannotated fall-through between switch labels}} \
+            expected-note{{insert 'break;' to avoid fall-through}}
+          break;
+      }
+    }
+  };
+}
+
+// Fallthrough annotations in lambdas used to generate "fallthrough
+// annotation does not directly precede switch label" warning.
+void fallthrough_in_lambda() {
+  (void)[] {
+    int x = 0;
+    switch (x) {
+    case 0:
+      x++;
+      [[clang::fallthrough]]; // no diagnostics
+    case 1:
+      x++;
+    default: // \
+        expected-warning{{unannotated fall-through between switch labels}} \
+        expected-note{{insert 'break;' to avoid fall-through}}
+      break;
+    }
+  };
+}
+
+namespace PR18983 {
+  void fatal() __attribute__((noreturn));
+  int num();
+  void test() {
+    switch (num()) {
+    case 1:
+      fatal();
+      // Don't issue a warning.
+    case 2:
+      break;
+    }
+  }
+}
+
 int fallthrough_targets(int n) {
   [[clang::fallthrough]]; // expected-error{{fallthrough annotation is outside switch statement}}
 
@@ -247,21 +300,3 @@
   }
   return n;
 }
-
-// Fallthrough annotations in local classes used to generate "fallthrough
-// annotation does not directly precede switch label" warning.
-void fallthrough_in_local_class() {
-  class C {
-    void f(int x) {
-      switch (x) {
-        case 0:
-          x++;
-          [[clang::fallthrough]]; // no diagnostics
-        case 1:
-          x++;
-          break;
-      }
-    }
-  };
-}
-
diff --git a/test/SemaCXX/template-implicit-vars.cpp b/test/SemaCXX/template-implicit-vars.cpp
new file mode 100644
index 0000000..25d35fb
--- /dev/null
+++ b/test/SemaCXX/template-implicit-vars.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only %s -std=c++11 -ast-dump | FileCheck %s
+template<typename T>
+void f(T t) {
+  T a[] = {t};
+  for (auto x : a) {}
+}
+
+void g() {
+  f(1);
+}
+// CHECK: VarDecl {{.*}} implicit used __range
+// CHECK: VarDecl {{.*}} implicit used __range
+// CHECK: VarDecl {{.*}} implicit used __begin
+// CHECK: VarDecl {{.*}} implicit used __end
diff --git a/test/SemaCXX/trailing-return-0x.cpp b/test/SemaCXX/trailing-return-0x.cpp
index f7e3433..cf5e659 100644
--- a/test/SemaCXX/trailing-return-0x.cpp
+++ b/test/SemaCXX/trailing-return-0x.cpp
@@ -17,7 +17,9 @@
     return 0;
 }
 
-auto g(); // expected-error{{return without trailing return type}}
+auto g(); // expected-error{{return without trailing return type; deduced return types are a C++1y extension}}
+decltype(auto) g2(); // expected-warning{{extension}} expected-error-re{{{{^}}deduced return types are a C++1y extension}}
+auto badness = g2();
 
 int h() -> int; // expected-error{{trailing return type must specify return type 'auto', not 'int'}}
 
diff --git a/test/SemaCXX/type-definition-in-specifier.cpp b/test/SemaCXX/type-definition-in-specifier.cpp
index a614e6c..43443a0 100644
--- a/test/SemaCXX/type-definition-in-specifier.cpp
+++ b/test/SemaCXX/type-definition-in-specifier.cpp
@@ -13,13 +13,54 @@
 void f0() {
   typedef struct S1 { int x; } S1_typedef;
 
-  (void)((struct S2 { int x; }*)0); // expected-error{{can not be defined}}
+  (void)((struct S2 { int x; }*)0); // expected-error{{cannot be defined}}
 
   struct S3 { int x; } s3;
 
-  (void)static_cast<struct S4 { int x; } *>(0); // expected-error{{can not be defined}}
+  (void)static_cast<struct S4 { int x; } *>(0); // expected-error{{cannot be defined}}
 }
 
 struct S5 { int x; } f1() { return S5(); } // expected-error{{result type}}
 
 void f2(struct S6 { int x; } p); // expected-error{{parameter type}}
+
+struct pr19018 {
+  short foo6 (enum bar0 {qq} bar3); // expected-error{{cannot be defined in a parameter type}}
+};
+
+void pr19018_1 (enum e19018_1 {qq} x); // expected-error{{cannot be defined in a parameter type}}
+void pr19018_1a (enum e19018_1 {qq} x); // expected-error{{cannot be defined in a parameter type}}
+e19018_1 x2;  // expected-error{{unknown type name 'e19018_1'}}
+
+void pr19018_2 (enum {qq} x); // expected-error{{cannot be defined in a parameter type}}
+void pr19018_3 (struct s19018_2 {int qq;} x); // expected-error{{cannot be defined in a parameter type}}
+void pr19018_4 (struct {int qq;} x); // expected-error{{cannot be defined in a parameter type}}
+void pr19018_5 (struct { void qq(); } x); // expected-error{{cannot be defined in a parameter type}}
+void pr19018_5 (struct s19018_2 { void qq(); } x); // expected-error{{cannot be defined in a parameter type}}
+
+struct pr19018a {
+  static int xx;
+  void func1(enum t19018 {qq} x); // expected-error{{cannot be defined in a parameter type}}
+  void func2(enum t19018 {qq} x); // expected-error{{cannot be defined in a parameter type}}
+  void func3(enum {qq} x);        // expected-error{{cannot be defined in a parameter type}}
+  void func4(struct t19018 {int qq;} x);  // expected-error{{cannot be defined in a parameter type}}
+  void func5(struct {int qq;} x); // expected-error{{cannot be defined in a parameter type}}
+  void func6(struct { void qq(); } x); // expected-error{{cannot be defined in a parameter type}}
+  void func7(struct t19018 { void qq(); } x); // expected-error{{cannot be defined in a parameter type}}
+  void func8(struct { int qq() { return xx; }; } x); // expected-error{{cannot be defined in a parameter type}}
+  void func9(struct t19018 { int qq() { return xx; }; } x); // expected-error{{cannot be defined in a parameter type}}
+};
+
+struct s19018b {
+  void func1 (enum en_2 {qq} x); // expected-error{{cannot be defined in a parameter type}}
+  en_2 x1;  // expected-error{{unknown type name 'en_2'}}
+  void func2 (enum en_3 {qq} x); // expected-error{{cannot be defined in a parameter type}}
+  enum en_3 x2; // expected-error{{ISO C++ forbids forward references to 'enum' types}} \
+                // expected-error{{field has incomplete type 'enum en_3'}} \
+                // expected-note{{forward declaration of 'en_3'}}
+};
+
+struct pr18963 {
+  short bar5 (struct foo4 {} bar2); // expected-error{{'foo4' cannot be defined in a parameter type}}
+  long foo5 (float foo6 = foo4);  // expected-error{{use of undeclared identifier 'foo4'}}
+};
diff --git a/test/SemaCXX/type-traits.cpp b/test/SemaCXX/type-traits.cpp
index 3e47921..3b94ef0 100644
--- a/test/SemaCXX/type-traits.cpp
+++ b/test/SemaCXX/type-traits.cpp
@@ -112,6 +112,14 @@
 struct HasNoThrowConstructorWithArgs {
   HasNoThrowConstructorWithArgs(HasCons i = HasCons(0)) throw();
 };
+struct HasMultipleDefaultConstructor1 {
+  HasMultipleDefaultConstructor1() throw();
+  HasMultipleDefaultConstructor1(int i = 0);
+};
+struct HasMultipleDefaultConstructor2 {
+  HasMultipleDefaultConstructor2(int i = 0);
+  HasMultipleDefaultConstructor2() throw();
+};
 
 struct HasNoThrowCopy { HasNoThrowCopy(const HasNoThrowCopy&) throw(); };
 struct HasMultipleCopy {
@@ -1475,6 +1483,10 @@
   { int arr[F(__has_nothrow_move_assign(NoDefaultMoveAssignDueToUDCopyCtor))]; }
   { int arr[F(__has_nothrow_move_assign(NoDefaultMoveAssignDueToUDCopyAssign))]; }
   { int arr[F(__has_nothrow_move_assign(NoDefaultMoveAssignDueToDtor))]; }
+
+
+  { int arr[T(__is_nothrow_assignable(HasNoThrowMoveAssign, HasNoThrowMoveAssign))]; }
+  { int arr[F(__is_nothrow_assignable(HasThrowMoveAssign, HasThrowMoveAssign))]; }
 }
 
 void has_trivial_move_assign() {
@@ -1562,6 +1574,9 @@
   { int arr[F(__has_nothrow_constructor(void))]; }
   { int arr[F(__has_nothrow_constructor(cvoid))]; }
   { int arr[F(__has_nothrow_constructor(HasTemplateCons))]; }
+
+  { int arr[F(__has_nothrow_constructor(HasMultipleDefaultConstructor1))]; }
+  { int arr[F(__has_nothrow_constructor(HasMultipleDefaultConstructor2))]; }
 }
 
 void has_virtual_destructor() {
@@ -1931,6 +1946,30 @@
                                          TrivialMoveButNotCopy&&)))]; }
 }
 
+void constructible_checks() {
+  { int arr[T(__is_constructible(HasNoThrowConstructorWithArgs))]; }
+  { int arr[F(__is_nothrow_constructible(HasNoThrowConstructorWithArgs))]; } // MSVC doesn't look into default args and gets this wrong.
+
+  { int arr[T(__is_constructible(HasNoThrowConstructorWithArgs, HasCons))]; }
+  { int arr[T(__is_nothrow_constructible(HasNoThrowConstructorWithArgs, HasCons))]; }
+
+  { int arr[T(__is_constructible(NonTrivialDefault))]; }
+  { int arr[F(__is_nothrow_constructible(NonTrivialDefault))]; }
+
+  { int arr[T(__is_constructible(int))]; }
+  { int arr[T(__is_nothrow_constructible(int))]; }
+
+  { int arr[F(__is_constructible(NonPOD))]; }
+  { int arr[F(__is_nothrow_constructible(NonPOD))]; }
+
+  { int arr[T(__is_constructible(NonPOD, int))]; }
+  { int arr[F(__is_nothrow_constructible(NonPOD, int))]; }
+
+  // PR19178
+  { int arr[F(__is_constructible(Abstract))]; }
+  { int arr[F(__is_nothrow_constructible(Abstract))]; }
+}
+
 // Instantiation of __is_trivially_constructible
 template<typename T, typename ...Args>
 struct is_trivially_constructible {
@@ -1956,6 +1995,7 @@
   { int arr[F((is_trivially_constructible<int, int*>::value))]; }
   { int arr[F((is_trivially_constructible<NonTrivialDefault>::value))]; }
   { int arr[F((is_trivially_constructible<ThreeArgCtor, int*, char*, int&>::value))]; }
+  { int arr[F((is_trivially_constructible<Abstract>::value))]; } // PR19178
 }
 
 void array_rank() {
diff --git a/test/SemaCXX/typeid-ref.cpp b/test/SemaCXX/typeid-ref.cpp
index d01fd31..7e5dbdd 100644
--- a/test/SemaCXX/typeid-ref.cpp
+++ b/test/SemaCXX/typeid-ref.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
 namespace std {
   class type_info;
 }
@@ -7,6 +7,6 @@
 
 void f() {
   // CHECK: @_ZTS1X = linkonce_odr constant
-  // CHECK: @_ZTI1X = linkonce_odr unnamed_addr constant 
+  // CHECK: @_ZTI1X = linkonce_odr constant 
   (void)typeid(X&);
 }
diff --git a/test/SemaCXX/types_compatible_p.cpp b/test/SemaCXX/types_compatible_p.cpp
index 4aa9a1c..29e0640 100644
--- a/test/SemaCXX/types_compatible_p.cpp
+++ b/test/SemaCXX/types_compatible_p.cpp
@@ -1,5 +1,9 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -x c++ %s
+// RUN: %clang_cc1 -fsyntax-only -x c %s
 
-bool f() {
-  return __builtin_types_compatible_p(int, const int); // expected-error{{C++}}
+// Test that GNU C extension __builtin_types_compatible_p() is not available in C++ mode.
+
+int f() {
+  return __builtin_types_compatible_p(int, const int); // expected-error{{expected '(' for function-style cast or type construction}} \
+                                                       // expected-error{{expected expression}}
 }
diff --git a/test/SemaCXX/typo-correction-pt2.cpp b/test/SemaCXX/typo-correction-pt2.cpp
index 2da52b3..88a7073 100644
--- a/test/SemaCXX/typo-correction-pt2.cpp
+++ b/test/SemaCXX/typo-correction-pt2.cpp
@@ -5,10 +5,19 @@
 // attempt within a single file (which is to avoid having very broken files take
 // minutes to finally be rejected by the parser).
 
+namespace PR12951 {
+// If there are two corrections that have the same identifier and edit distance
+// and only differ by their namespaces, don't suggest either as a correction
+// since both are equally likely corrections.
+namespace foobar { struct Thing {}; }
+namespace bazquux { struct Thing {}; }
+void f() { Thing t; } // expected-error{{unknown type name 'Thing'}}
+}
+
 namespace bogus_keyword_suggestion {
 void test() {
-   status = "OK";  // expected-error-re {{use of undeclared identifier 'status'$}}
-   return status;  // expected-error-re {{use of undeclared identifier 'status'$}}
+   status = "OK";  // expected-error-re {{use of undeclared identifier 'status'{{$}}}}
+   return status;  // expected-error-re {{use of undeclared identifier 'status'{{$}}}}
  }
 }
 
@@ -33,7 +42,7 @@
 };
 // should be void T::f();
 void f() {
- data_struct->foo();  // expected-error-re{{use of undeclared identifier 'data_struct'$}}
+ data_struct->foo();  // expected-error-re{{use of undeclared identifier 'data_struct'{{$}}}}
 }
 
 namespace PR12287 {
@@ -116,9 +125,9 @@
 void testAccess() {
   Figure obj;
   switch (obj.type()) {  // expected-warning {{enumeration values 'SQUARE', 'TRIANGLE', and 'CIRCLE' not handled in switch}}
-  case SQUARE:  // expected-error-re {{use of undeclared identifier 'SQUARE'$}}
-  case TRIANGLE:  // expected-error-re {{use of undeclared identifier 'TRIANGLE'$}}
-  case CIRCE:  // expected-error-re {{use of undeclared identifier 'CIRCE'$}}
+  case SQUARE:  // expected-error-re {{use of undeclared identifier 'SQUARE'{{$}}}}
+  case TRIANGLE:  // expected-error-re {{use of undeclared identifier 'TRIANGLE'{{$}}}}
+  case CIRCE:  // expected-error-re {{use of undeclared identifier 'CIRCE'{{$}}}}
     break;
   }
 }
@@ -126,13 +135,13 @@
 
 long readline(const char *, char *, unsigned long);
 void assign_to_unknown_var() {
-    deadline_ = 1;  // expected-error-re {{use of undeclared identifier 'deadline_'$}}
+    deadline_ = 1;  // expected-error-re {{use of undeclared identifier 'deadline_'{{$}}}}
 }
 
 namespace no_ns_before_dot {
 namespace re2 {}
 void test() {
-    req.set_check(false);  // expected-error-re {{use of undeclared identifier 'req'$}}
+    req.set_check(false);  // expected-error-re {{use of undeclared identifier 'req'{{$}}}}
 }
 }
 
@@ -181,3 +190,113 @@
   MessageHeaders::ParseMessageHeaders(5, 4); // expected-error {{no member named 'ParseMessageHeaders' in 'fix_class_name_qualifier::MessageHeaders'; did you mean 'MessageUtils::ParseMessageHeaders'?}}
 }
 }
+
+namespace PR18213 {  // expected-note {{'PR18213' declared here}}
+struct WrapperInfo {
+  int i;
+};
+
+template <typename T> struct Wrappable {
+  static WrapperInfo kWrapperInfo;
+};
+
+// Note the space before "::PR18213" is intended and needed, as it highlights
+// the actual typo, which is the leading "::".
+// TODO: Suggest removing the "::" from "::PR18213" (the right correction)
+// instead of incorrectly suggesting dropping "PR18213::WrapperInfo::".
+template <>
+PR18213::WrapperInfo ::PR18213::Wrappable<int>::kWrapperInfo = { 0 };  // expected-error {{no member named 'PR18213' in 'PR18213::WrapperInfo'; did you mean simply 'PR18213'?}} \
+                                                                       // expected-error {{C++ requires a type specifier for all declarations}}
+}
+
+namespace PR18651 {
+struct {
+  int x;
+} a, b;
+
+int y = x;  // expected-error-re {{use of undeclared identifier 'x'{{$}}}}
+}
+
+namespace PR18685 {
+template <class C, int I, int J>
+class SetVector {
+ public:
+  SetVector() {}
+};
+
+template <class C, int I>
+class SmallSetVector : public SetVector<C, I, 8> {};
+
+class foo {};
+SmallSetVector<foo*, 2> fooSet;
+}
+
+PR18685::BitVector Map;  // expected-error-re {{no type named 'BitVector' in namespace 'PR18685'{{$}}}}
+
+namespace shadowed_template {
+template <typename T> class Fizbin {};  // expected-note {{'::shadowed_template::Fizbin' declared here}}
+class Baz {
+   int Fizbin();
+   // TODO: Teach the parser to recover from the typo correction instead of
+   // continuing to treat the template name as an implicit-int declaration.
+   Fizbin<int> qux;  // expected-error {{unknown type name 'Fizbin'; did you mean '::shadowed_template::Fizbin'?}} \
+                     // expected-error {{expected member name or ';' after declaration specifiers}}
+};
+}
+
+namespace PR18852 {
+void func() {
+  struct foo {
+    void bar() {}
+  };
+  bar();  // expected-error-re {{use of undeclared identifier 'bar'{{$}}}}
+}
+
+class Thread {
+ public:
+  void Start();
+  static void Stop();  // expected-note {{'Thread::Stop' declared here}}
+};
+
+class Manager {
+ public:
+  void Start(int);  // expected-note {{'Start' declared here}}
+  void Stop(int);  // expected-note {{'Stop' declared here}}
+};
+
+void test(Manager *m) {
+  // Don't suggest Thread::Start as a correction just because it has the same
+  // (unqualified) name and accepts the right number of args; this is a method
+  // call on an object in an unrelated class.
+  m->Start();  // expected-error-re {{too few arguments to function call, expected 1, have 0{{$}}}}
+  m->Stop();  // expected-error-re {{too few arguments to function call, expected 1, have 0{{$}}}}
+  Stop();  // expected-error {{use of undeclared identifier 'Stop'; did you mean 'Thread::Stop'?}}
+}
+
+}
+
+namespace std {
+class bernoulli_distribution {
+ public:
+  double p() const;
+};
+}
+void test() {
+  // Make sure that typo correction doesn't suggest changing 'p' to
+  // 'std::bernoulli_distribution::p' as that is most likely wrong.
+  if (p)  // expected-error-re {{use of undeclared identifier 'p'{{$}}}}
+    return;
+}
+
+namespace PR19681 {
+  struct TypoA {};
+  struct TypoB {
+    void test();
+  private:
+    template<typename T> void private_memfn(T);  // expected-note{{declared here}}
+  };
+  void TypoB::test() {
+    // FIXME: should suggest 'PR19681::TypoB::private_memfn' instead of '::PR19681::TypoB::private_memfn'
+    (void)static_cast<void(TypoB::*)(int)>(&TypoA::private_memfn);  // expected-error{{no member named 'private_memfn' in 'PR19681::TypoA'; did you mean '::PR19681::TypoB::private_memfn'?}}
+  }
+}
diff --git a/test/SemaCXX/typo-correction.cpp b/test/SemaCXX/typo-correction.cpp
index 4047e6a..e8160b0 100644
--- a/test/SemaCXX/typo-correction.cpp
+++ b/test/SemaCXX/typo-correction.cpp
@@ -202,15 +202,6 @@
   };
 }
 
-namespace PR12951 {
-// If there are two corrections that have the same identifier and edit distance
-// and only differ by their namespaces, don't suggest either as a correction
-// since both are equally likely corrections.
-namespace foobar { struct Thing {}; }
-namespace bazquux { struct Thing {}; }
-void f() { Thing t; } // expected-error{{unknown type name 'Thing'}}
-}
-
 namespace PR13051 {
   template<typename T> struct S {
     template<typename U> void f();
@@ -282,13 +273,13 @@
 namespace b6956809_test2 {
   template<typename T> struct Err { typename T::error n; };  // expected-error{{type 'void *' cannot be used prior to '::' because it has no members}}
   struct S {
-    template<typename T> typename Err<T>::type method(T);  // expected-note{{in instantiation of template class 'b6956809_test2::Err<void *>' requested here}}  expected-note{{while substituting deduced template arguments into function template 'method' [with T = void *]}}
+    template<typename T> typename Err<T>::type method(T);  // expected-note{{in instantiation of template class 'b6956809_test2::Err<void *>' requested here}}
     template<typename T> int method(T *);
   };
 
   void test() {
     S s;
-    int k = s.methodd((void*)0);  // expected-error{{no member named 'methodd' in 'b6956809_test2::S'; did you mean 'method'?}}
+    int k = s.methodd((void*)0);  // expected-error{{no member named 'methodd' in 'b6956809_test2::S'; did you mean 'method'?}} expected-note{{while substituting deduced template arguments into function template 'method' [with T = void *]}}
   }
 }
 
@@ -299,6 +290,6 @@
 int flibberdy();  // expected-note{{'flibberdy' declared here}}
 int no_correction() {
   return hibberdy() +  // expected-error{{use of undeclared identifier 'hibberdy'; did you mean 'flibberdy'?}}
-         gibberdy();  // expected-error-re{{use of undeclared identifier 'gibberdy'$}}
+         gibberdy();  // expected-error-re{{use of undeclared identifier 'gibberdy'{{$}}}}
 };
 }
diff --git a/test/SemaCXX/undefined-inline.cpp b/test/SemaCXX/undefined-inline.cpp
index ad719ae..18973ef 100644
--- a/test/SemaCXX/undefined-inline.cpp
+++ b/test/SemaCXX/undefined-inline.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple i686-pc-win32 -verify %s
 // PR14993
 
 namespace test1 {
@@ -55,3 +55,9 @@
   void test() { foo(); }
   inline void foo() __attribute__((gnu_inline));
 }
+
+namespace test11 {
+  inline void foo() __attribute__((dllexport));
+  inline void bar() __attribute__((dllimport));
+  void test() { foo(); bar(); }
+}
diff --git a/test/SemaCXX/undefined-internal.cpp b/test/SemaCXX/undefined-internal.cpp
index 1b76a86..f32036a 100644
--- a/test/SemaCXX/undefined-internal.cpp
+++ b/test/SemaCXX/undefined-internal.cpp
@@ -15,9 +15,9 @@
 
 namespace test2 {
   namespace {
-    void foo(); // expected-warning {{function 'test2::<anonymous namespace>::foo' has internal linkage but is not defined}}
-    extern int var; // expected-warning {{variable 'test2::<anonymous namespace>::var' has internal linkage but is not defined}}
-    template <class T> void bar(); // expected-warning {{function 'test2::<anonymous namespace>::bar<int>' has internal linkage but is not defined}}
+    void foo(); // expected-warning {{function 'test2::(anonymous namespace)::foo' has internal linkage but is not defined}}
+    extern int var; // expected-warning {{variable 'test2::(anonymous namespace)::var' has internal linkage but is not defined}}
+    template <class T> void bar(); // expected-warning {{function 'test2::(anonymous namespace)::bar<int>' has internal linkage but is not defined}}
   }
   void test() {
     foo(); // expected-note {{used here}}
@@ -49,11 +49,11 @@
 namespace test4 {
   namespace {
     struct A {
-      A(); // expected-warning {{function 'test4::<anonymous namespace>::A::A' has internal linkage but is not defined}}
-      ~A();// expected-warning {{function 'test4::<anonymous namespace>::A::~A' has internal linkage but is not defined}}
-      virtual void foo(); // expected-warning {{function 'test4::<anonymous namespace>::A::foo' has internal linkage but is not defined}}
+      A(); // expected-warning {{function 'test4::(anonymous namespace)::A::A' has internal linkage but is not defined}}
+      ~A();// expected-warning {{function 'test4::(anonymous namespace)::A::~A' has internal linkage but is not defined}}
+      virtual void foo(); // expected-warning {{function 'test4::(anonymous namespace)::A::foo' has internal linkage but is not defined}}
       virtual void bar() = 0;
-      virtual void baz(); // expected-warning {{function 'test4::<anonymous namespace>::A::baz' has internal linkage but is not defined}}
+      virtual void baz(); // expected-warning {{function 'test4::(anonymous namespace)::A::baz' has internal linkage but is not defined}}
     };
   }
 
@@ -75,8 +75,8 @@
   }
 
   template <class N> struct B {
-    static int var; // expected-warning {{variable 'test5::B<test5::<anonymous>::A>::var' has internal linkage but is not defined}}
-    static void foo(); // expected-warning {{function 'test5::B<test5::<anonymous>::A>::foo' has internal linkage but is not defined}}
+    static int var; // expected-warning {{variable 'test5::B<test5::(anonymous namespace)::A>::var' has internal linkage but is not defined}}
+    static void foo(); // expected-warning {{function 'test5::B<test5::(anonymous namespace)::A>::foo' has internal linkage but is not defined}}
   };
 
   void test() {
@@ -175,7 +175,7 @@
 namespace OverloadUse {
   namespace {
     void f();
-    void f(int); // expected-warning {{function 'OverloadUse::<anonymous namespace>::f' has internal linkage but is not defined}}
+    void f(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}}
@@ -193,7 +193,7 @@
 
 namespace test8 {
   typedef struct {
-    void bar(); // expected-warning {{function 'test8::<anonymous struct>::bar' has internal linkage but is not defined}}
+    void bar(); // expected-warning {{function 'test8::(anonymous struct)::bar' has internal linkage but is not defined}}
     void foo() {
       bar(); // expected-note {{used here}}
     }
@@ -204,7 +204,7 @@
   namespace {
     struct X {
       virtual void notused() = 0;
-      virtual void used() = 0; // expected-warning {{function 'test9::<anonymous namespace>::X::used' has internal linkage but is not defined}}
+      virtual void used() = 0; // expected-warning {{function 'test9::(anonymous namespace)::X::used' has internal linkage but is not defined}}
     };
   }
   void test(X &x) {
@@ -217,7 +217,7 @@
   namespace {
     struct X {
       virtual void notused() = 0;
-      virtual void used() = 0; // expected-warning {{function 'test10::<anonymous namespace>::X::used' has internal linkage but is not defined}}
+      virtual void used() = 0; // expected-warning {{function 'test10::(anonymous namespace)::X::used' has internal linkage but is not defined}}
 
       void test() {
         notused();
@@ -244,11 +244,11 @@
     };
 
     struct B {
-      bool operator()() const;  // expected-warning {{function 'test11::<anonymous namespace>::B::operator()' has internal linkage but is not defined}}
-      void operator!() const;  // expected-warning {{function 'test11::<anonymous namespace>::B::operator!' has internal linkage but is not defined}}
-      bool operator+(const B&) const;  // expected-warning {{function 'test11::<anonymous namespace>::B::operator+' has internal linkage but is not defined}}
-      int operator[](int) const;  // expected-warning {{function 'test11::<anonymous namespace>::B::operator[]' has internal linkage but is not defined}}
-      const B* operator->() const;  // expected-warning {{function 'test11::<anonymous namespace>::B::operator->' has internal linkage but is not defined}}
+      bool operator()() const;  // expected-warning {{function 'test11::(anonymous namespace)::B::operator()' has internal linkage but is not defined}}
+      void operator!() const;  // expected-warning {{function 'test11::(anonymous namespace)::B::operator!' has internal linkage but is not defined}}
+      bool operator+(const B&) const;  // expected-warning {{function 'test11::(anonymous namespace)::B::operator+' has internal linkage but is not defined}}
+      int operator[](int) const;  // expected-warning {{function 'test11::(anonymous namespace)::B::operator[]' has internal linkage but is not defined}}
+      const B* operator->() const;  // expected-warning {{function 'test11::(anonymous namespace)::B::operator->' has internal linkage but is not defined}}
       int member;
     };
   }
@@ -278,18 +278,18 @@
     struct Cls {
       virtual void f(int) = 0;
       virtual void f(int, double) = 0;
-      void g(int);  // expected-warning {{function 'test12::<anonymous namespace>::Cls::g' has internal linkage but is not defined}}
+      void g(int);  // expected-warning {{function 'test12::(anonymous namespace)::Cls::g' has internal linkage but is not defined}}
       void g(int, double);
       virtual operator T1() = 0;
       virtual operator T2() = 0;
       virtual operator T3&() = 0;
-      operator T4();  // expected-warning {{function 'test12::<anonymous namespace>::Cls::operator T4' has internal linkage but is not defined}}
-      operator T5();  // expected-warning {{function 'test12::<anonymous namespace>::Cls::operator T5' has internal linkage but is not defined}}
-      operator T6&();  // expected-warning {{function 'test12::<anonymous namespace>::Cls::operator class test12::T6 &' has internal linkage but is not defined}}
+      operator T4();  // expected-warning {{function 'test12::(anonymous namespace)::Cls::operator T4' has internal linkage but is not defined}}
+      operator T5();  // expected-warning {{function 'test12::(anonymous namespace)::Cls::operator T5' has internal linkage but is not defined}}
+      operator T6&();  // expected-warning {{function 'test12::(anonymous namespace)::Cls::operator test12::T6 &' has internal linkage but is not defined}}
     };
 
     struct Cls2 {
-      Cls2(T7);  // expected-warning {{function 'test12::<anonymous namespace>::Cls2::Cls2' has internal linkage but is not defined}}
+      Cls2(T7);  // expected-warning {{function 'test12::(anonymous namespace)::Cls2::Cls2' has internal linkage but is not defined}}
     };
   }
 
diff --git a/test/SemaCXX/underlying_type.cpp b/test/SemaCXX/underlying_type.cpp
index 7bca06b..2a972b1 100644
--- a/test/SemaCXX/underlying_type.cpp
+++ b/test/SemaCXX/underlying_type.cpp
@@ -41,3 +41,17 @@
  
 static_assert(is_same_type<underlying_type<foo>::type, unsigned>::value,
               "foo has the wrong underlying type");
+
+namespace PR19966 {
+  void PR19966(enum Invalid) { // expected-note 2{{forward declaration of}}
+    // expected-error@-1 {{ISO C++ forbids forward references to 'enum'}}
+    // expected-error@-2 {{variable has incomplete type}}
+    __underlying_type(Invalid) dont_crash;
+    // expected-error@-1 {{cannot determine underlying type of incomplete enumeration type 'PR19966::Invalid'}}
+  }
+  enum E { // expected-note {{forward declaration of 'E'}}
+    a = (__underlying_type(E)){}
+    // expected-error@-1 {{cannot determine underlying type of incomplete enumeration type 'PR19966::E'}}
+    // expected-error@-2 {{constant expression}}
+  };
+}
diff --git a/test/SemaCXX/uninit-variables.cpp b/test/SemaCXX/uninit-variables.cpp
index 687bfd2..4dcd348 100644
--- a/test/SemaCXX/uninit-variables.cpp
+++ b/test/SemaCXX/uninit-variables.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wuninitialized -fsyntax-only -fcxx-exceptions %s -verify
+// RUN: %clang_cc1 -fsyntax-only -Wuninitialized -fsyntax-only -fcxx-exceptions %s -verify -std=c++1y
 
 // Stub out types for 'typeid' to work.
 namespace std { class type_info {}; }
@@ -147,3 +147,6 @@
   consume_const_ref(n);
   return n; // expected-warning {{uninitialized when used here}}
 }
+
+// Don't crash here.
+auto PR19996 = [a=0]{int t; return a;};
diff --git a/test/SemaCXX/uninitialized.cpp b/test/SemaCXX/uninitialized.cpp
index 4991ebe..677a141 100644
--- a/test/SemaCXX/uninitialized.cpp
+++ b/test/SemaCXX/uninitialized.cpp
@@ -117,7 +117,7 @@
   A a20{a20};  // expected-warning {{variable 'a20' is uninitialized when used within its own initialization}}
   A a21 = {a21};  // expected-warning {{variable 'a21' is uninitialized when used within its own initialization}}
 
-  // FIXME: Make the local uninitialized warning consistant with the global
+  // FIXME: Make the local uninitialized warning consistent with the global
   // uninitialized checking.
   A *a22 = new A(a22->count);  // expected-warning {{variable 'a22' is uninitialized when used within its own initialization}}
   A *a23 = new A(a23->ONE);  // expected-warning {{variable 'a23' is uninitialized when used within its own initialization}}
diff --git a/test/SemaCXX/unreachable-code.cpp b/test/SemaCXX/unreachable-code.cpp
index 743290e..fd006c0 100644
--- a/test/SemaCXX/unreachable-code.cpp
+++ b/test/SemaCXX/unreachable-code.cpp
@@ -1,17 +1,29 @@
-// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -Wunreachable-code -fblocks -verify %s
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -Wunreachable-code-aggressive -fblocks -verify %s
 
 int j;
-void bar() { }
+int bar();
 int test1() {
   for (int i = 0;
        i != 10;
-       ++i) {  // expected-warning {{will never be executed}}
+       ++i) {  // expected-warning {{loop will run at most once (loop increment never executed)}}
     if (j == 23) // missing {}'s
       bar();
       return 1;
   }
   return 0;
-  return 1;    // expected-warning {{will never be executed}}
+  return 1; // expected-warning {{will never be executed}}
+}
+
+int test1_B() {
+  for (int i = 0;
+       i != 10;
+       ++i) {  // expected-warning {{loop will run at most once (loop increment never executed)}}
+    if (j == 23) // missing {}'s
+      bar();
+      return 1;
+  }
+  return 0;
+  return bar(); // expected-warning {{will never be executed}}
 }
 
 void test2(int i) {
diff --git a/test/SemaCXX/using-decl-1.cpp b/test/SemaCXX/using-decl-1.cpp
index 24d92f1..40f80a7 100644
--- a/test/SemaCXX/using-decl-1.cpp
+++ b/test/SemaCXX/using-decl-1.cpp
@@ -1,4 +1,5 @@
-// 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
 
 extern "C" { void f(bool); }
 
@@ -160,3 +161,97 @@
 }
 using N::M::FFF; // expected-error {{no member named 'FFF' in namespace 'using_suggestion_val_dropped_nested_specifier::N::M'; did you mean 'N::FFF'?}}
 }
+
+namespace UsingDeclVsHiddenName {
+  namespace A {
+    enum HiddenTag1 {}; // expected-note {{previous use is here}}
+    enum HiddenTag2 {}; // expected-note {{target}}
+    int HiddenFn1; // expected-note {{target}}
+    int HiddenFn2; // expected-note {{target}}
+    int HiddenLocalExtern1;
+    int HiddenLocalExtern2;
+  }
+
+  namespace B {
+    using A::HiddenTag1;
+    using A::HiddenFn1; // expected-note {{using declaration}}
+    using A::HiddenLocalExtern1;
+
+    struct S {
+      friend struct HiddenTag1; // expected-error {{tag type that does not match previous}}
+      friend struct HiddenTag2; // expected-note {{conflicting declaration}}
+      friend void HiddenFn1(); // expected-error {{cannot befriend target of using declaration}}
+      friend void HiddenFn2(); // expected-note {{conflicting declaration}}
+      void f() {
+        // OK, these are not in the scope of namespace B, even though they're
+        // members of the namespace.
+        void HiddenLocalExtern1();
+        void HiddenLocalExtern2();
+      }
+    };
+
+    using A::HiddenTag2; // expected-error {{conflicts with declaration already in scope}}
+    using A::HiddenFn2; // expected-error {{conflicts with declaration already in scope}}
+    using A::HiddenLocalExtern2;
+  }
+}
+
+namespace PR19171 {
+  struct Z {
+    Z();
+  };
+
+  typedef struct {
+    Z i;
+  } S;
+
+  struct Y : S {
+    using S::S;
+#if __cplusplus < 201103L
+    // expected-error@-2 {{no member named 'S' in 'PR19171::S'}}
+#endif
+  };
+
+  // [namespace.udecl]p3: In a using-declaration used as a member-declaration,
+  // the nested-name-specifier shall name a base class of the class being defined.
+  // If such a using-declaration names a constructor, the nested-name-specifier
+  // shall name a direct base class of the class being defined;
+
+  struct B_blah { };
+  struct C_blah : B_blah { C_blah(int); }; // expected-note 0-1{{declared here}}
+  struct D1 : C_blah {
+    // FIXME: We should be able to correct this in C++11 mode.
+    using B_blah::C_blah; // expected-error-re {{no member named 'C_blah' in 'PR19171::B_blah'{{$}}}}
+  };
+  struct D2 : C_blah {
+    // Somewhat bizarrely, this names the injected-class-name of B_blah within
+    // C_blah, and is valid.
+    using C_blah::B_blah;
+  };
+  struct D3 : C_blah {
+    using C_blah::D_blah;
+#if __cplusplus < 201103L
+    // expected-error-re@-2 {{no member named 'D_blah' in 'PR19171::C_blah'{{$}}}}
+#else
+    // expected-error@-4 {{no member named 'D_blah' in 'PR19171::C_blah'; did you mean 'C_blah'?}}
+#endif
+  };
+#if __cplusplus >= 201103L
+  D3 d3(0); // ok
+#endif
+
+  struct E { };
+  struct EE { int EE; };
+  struct F : E {
+    using E::EE; // expected-error-re {{no member named 'EE' in 'PR19171::E'{{$}}}}
+  };
+}
+
+namespace TypoCorrectTemplateMember {
+  struct A {
+    template<typename T> void foobar(T); // expected-note {{'foobar' declared here}}
+  };
+  struct B : A {
+    using A::goobar; // expected-error {{no member named 'goobar' in 'TypoCorrectTemplateMember::A'; did you mean 'foobar'?}}
+  };
+}
diff --git a/test/SemaCXX/vararg-class.cpp b/test/SemaCXX/vararg-class.cpp
new file mode 100644
index 0000000..08f521c
--- /dev/null
+++ b/test/SemaCXX/vararg-class.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -verify -Wclass-varargs -std=c++98 %s
+// RUN: %clang_cc1 -verify -Wclass-varargs -std=c++11 %s
+
+struct A {};
+struct B { ~B(); };
+class C { char *c_str(); };
+struct D { char *c_str(); };
+struct E { E(); };
+struct F { F(); char *c_str(); };
+
+void v(...);
+void w(const char*, ...) __attribute__((format(printf, 1, 2)));
+
+void test(A a, B b, C c, D d, E e, F f) {
+  v(a); // expected-warning-re {{passing object of class type 'A' through variadic function{{$}}}}
+  v(b); // expected-error-re {{cannot pass object of non-{{POD|trivial}} type 'B' through variadic function; call will abort at runtime}}
+  v(c); // expected-warning {{passing object of class type 'C' through variadic function; did you mean to call '.c_str()'?}}
+  v(d); // expected-warning {{passing object of class type 'D' through variadic function; did you mean to call '.c_str()'?}}
+  v(e);
+  v(f);
+#if __cplusplus < 201103L
+  // expected-error@-3 {{cannot pass object of non-POD type 'E' through variadic function; call will abort at runtime}}
+  // expected-error@-3 {{cannot pass object of non-POD type 'F' through variadic function; call will abort at runtime}}
+#else
+  // expected-warning-re@-6 {{passing object of class type 'E' through variadic function{{$}}}}
+  // expected-warning@-6 {{passing object of class type 'F' through variadic function; did you mean to call '.c_str()'?}}
+#endif
+
+  v(d.c_str());
+  v(f.c_str());
+  v(0);
+  v('x');
+
+  w("%s", a); // expected-warning {{format specifies type 'char *' but the argument has type 'A'}}
+  w("%s", b); // expected-error-re {{cannot pass non-{{POD|trivial}} object of type 'B' to variadic function; expected type from format string was 'char *'}}
+  w("%s", c); // expected-warning {{format specifies type 'char *' but the argument has type 'C'}}
+  w("%s", d); // expected-warning {{format specifies type 'char *' but the argument has type 'D'}}
+  w("%s", e);
+  w("%s", f);
+#if __cplusplus < 201103L
+  // expected-error@-3 {{cannot pass non-POD object of type 'E' to variadic function; expected type from format string was 'char *'}}
+  // expected-error@-3 {{cannot pass non-POD object of type 'F' to variadic function; expected type from format string was 'char *'}}
+  // expected-note@-4 {{did you mean to call the c_str() method?}}
+#else
+  // expected-warning@-7 {{format specifies type 'char *' but the argument has type 'E'}}
+  // expected-warning@-7 {{format specifies type 'char *' but the argument has type 'F'}}
+#endif
+}
diff --git a/test/SemaCXX/vector-casts.cpp b/test/SemaCXX/vector-casts.cpp
index 681a07e..2ccd597 100644
--- a/test/SemaCXX/vector-casts.cpp
+++ b/test/SemaCXX/vector-casts.cpp
@@ -2,6 +2,7 @@
 typedef int __v2si __attribute__((__vector_size__(8)));
 typedef short __v4hi __attribute__((__vector_size__(8)));
 typedef short __v8hi __attribute__((__vector_size__(16)));
+typedef short __v3hi __attribute__((__ext_vector_type__(3)));
 
 struct S { }; // expected-note 2 {{candidate constructor}}
 
@@ -22,19 +23,43 @@
   (void)reinterpret_cast<__v2si>(ll);
   (void)(__v2si)(ll);
 
-  (void)reinterpret_cast<S>(v2si); // expected-error {{reinterpret_cast from '__v2si' to 'S' is not allowed}}
-  (void)(S)v2si; // expected-error {{no matching conversion for C-style cast from '__v2si' to 'S'}}
-  (void)reinterpret_cast<__v2si>(s); // expected-error {{reinterpret_cast from 'S' to '__v2si' is not allowed}}
-  (void)(__v2si)s; // expected-error {{cannot convert 'S' to '__v2si' without a conversion operator}}
+  (void)reinterpret_cast<S>(v2si); // expected-error {{reinterpret_cast from '__v2si' (vector of 2 'int' values) to 'S' is not allowed}}
+  (void)(S)v2si; // expected-error {{no matching conversion for C-style cast from '__v2si' (vector of 2 'int' values) to 'S'}}
+  (void)reinterpret_cast<__v2si>(s); // expected-error {{reinterpret_cast from 'S' to '__v2si' (vector of 2 'int' values) is not allowed}}
+  (void)(__v2si)s; // expected-error {{cannot convert 'S' to '__v2si' (vector of 2 'int' values) without a conversion operator}}
   
-  (void)reinterpret_cast<unsigned char>(v2si); // expected-error {{reinterpret_cast from vector '__v2si' to scalar 'unsigned char' of different size}}
-  (void)(unsigned char)v2si; // expected-error {{C-style cast from vector '__v2si' to scalar 'unsigned char' of different size}}
-  (void)reinterpret_cast<__v2si>(c); // expected-error {{reinterpret_cast from scalar 'unsigned char' to vector '__v2si' of different size}}
+  (void)reinterpret_cast<unsigned char>(v2si); // expected-error {{reinterpret_cast from vector '__v2si' (vector of 2 'int' values) to scalar 'unsigned char' of different size}}
+  (void)(unsigned char)v2si; // expected-error {{C-style cast from vector '__v2si' (vector of 2 'int' values) to scalar 'unsigned char' of different size}}
+  (void)reinterpret_cast<__v2si>(c); // expected-error {{reinterpret_cast from scalar 'unsigned char' to vector '__v2si' (vector of 2 'int' values) of different size}}
 
-  (void)reinterpret_cast<__v8hi>(v4hi); // expected-error {{reinterpret_cast from vector '__v4hi' to vector '__v8hi' of different size}}
-  (void)(__v8hi)v4hi; // expected-error {{C-style cast from vector '__v4hi' to vector '__v8hi' of different size}}
-  (void)reinterpret_cast<__v4hi>(v8hi); // expected-error {{reinterpret_cast from vector '__v8hi' to vector '__v4hi' of different size}}
-  (void)(__v4hi)v8hi; // expected-error {{C-style cast from vector '__v8hi' to vector '__v4hi' of different size}}
+  (void)reinterpret_cast<__v8hi>(v4hi); // expected-error {{reinterpret_cast from vector '__v4hi' (vector of 4 'short' values) to vector '__v8hi' (vector of 8 'short' values) of different size}}
+  (void)(__v8hi)v4hi; // expected-error {{C-style cast from vector '__v4hi' (vector of 4 'short' values) to vector '__v8hi' (vector of 8 'short' values) of different size}}
+  (void)reinterpret_cast<__v4hi>(v8hi); // expected-error {{reinterpret_cast from vector '__v8hi' (vector of 8 'short' values) to vector '__v4hi' (vector of 4 'short' values) of different size}}
+  (void)(__v4hi)v8hi; // expected-error {{C-style cast from vector '__v8hi' (vector of 8 'short' values) to vector '__v4hi' (vector of 4 'short' values) of different size}}
 }
 
+struct testvec {
+  __v2si v;
+  void madd(const testvec& rhs) {
+    v = v + rhs; // expected-error {{can't convert between vector and non-scalar values}}
+  }
+  void madd2(testvec rhs) {
+    v = v + rhs; // expected-error {{can't convert between vector and non-scalar values}}
+  }
+};
 
+// rdar://15931426
+//   Conversions for return values.
+__v4hi threeToFour(__v3hi v) { // expected-note {{not viable}}
+  return v; // expected-error {{cannot initialize return object}}
+}
+__v3hi fourToThree(__v4hi v) { // expected-note {{not viable}}
+  return v; // expected-error {{cannot initialize return object}}
+}
+//   Conversions for calls.
+void call3to4(__v4hi v) {
+  (void) threeToFour(v); // expected-error {{no matching function for call}}
+}
+void call4to3(__v3hi v) {
+  (void) fourToThree(v); // expected-error {{no matching function for call}}
+}
diff --git a/test/SemaCXX/vector.cpp b/test/SemaCXX/vector.cpp
index 7957c23..bcd7fed 100644
--- a/test/SemaCXX/vector.cpp
+++ b/test/SemaCXX/vector.cpp
@@ -24,8 +24,8 @@
   f1(ll16e); // expected-error{{call to 'f1' is ambiguous}}
 }
 
-void f2(char16_e); // expected-note{{no known conversion from 'longlong16_e' to 'char16_e' for 1st argument}} \
-       // expected-note{{candidate function not viable: no known conversion from 'convertible_to<longlong16_e>' to 'char16_e' for 1st argument}}
+void f2(char16_e); // expected-note{{no known conversion from 'longlong16_e' (vector of 2 'long long' values) to 'char16_e' (vector of 16 'char' values) for 1st argument}} \
+       // expected-note{{candidate function not viable: no known conversion from 'convertible_to<longlong16_e>' to 'char16_e' (vector of 16 'char' values) for 1st argument}}
 
 void f2_test(char16 c16, longlong16 ll16, char16_e c16e, longlong16_e ll16e) {
   f2(c16);
@@ -85,7 +85,7 @@
   (void)static_cast<longlong16>(ll16);
   (void)static_cast<longlong16_e>(ll16);
   (void)static_cast<char16>(ll16e);
-  (void)static_cast<char16_e>(ll16e); // expected-error{{static_cast from 'longlong16_e' to 'char16_e' is not allowed}}
+  (void)static_cast<char16_e>(ll16e); // expected-error{{static_cast from 'longlong16_e' (vector of 2 'long long' values) to 'char16_e' (vector of 16 'char' values) is not allowed}}
   (void)static_cast<longlong16>(ll16e);
   (void)static_cast<longlong16_e>(ll16e);
 
@@ -194,11 +194,11 @@
 typedef double dblx2 __attribute__((__vector_size__(16)));
 typedef double dblx4 __attribute__((__vector_size__(32)));
 
-void accept_fltx2(fltx2); // expected-note{{candidate function not viable: no known conversion from 'double' to 'fltx2' for 1st argument}}
+void accept_fltx2(fltx2); // expected-note{{candidate function not viable: no known conversion from 'double' to 'fltx2' (vector of 2 'float' values) for 1st argument}}
 void accept_fltx4(fltx4);
 void accept_dblx2(dblx2);
 void accept_dblx4(dblx4);
-void accept_bool(bool); // expected-note{{candidate function not viable: no known conversion from 'fltx2' to 'bool' for 1st argument}}
+void accept_bool(bool); // expected-note{{candidate function not viable: no known conversion from 'fltx2' (vector of 2 'float' values) to 'bool' for 1st argument}}
 
 void test(fltx2 fltx2_val, fltx4 fltx4_val, dblx2 dblx2_val, dblx4 dblx4_val) {
   // Exact matches
diff --git a/test/SemaCXX/virtual-base-used.cpp b/test/SemaCXX/virtual-base-used.cpp
index 04518ce..c46cf5a 100644
--- a/test/SemaCXX/virtual-base-used.cpp
+++ b/test/SemaCXX/virtual-base-used.cpp
@@ -1,42 +1,89 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple %itanium_abi_triple -verify %s
+// RUN: %clang_cc1 -fsyntax-only -triple %ms_abi_triple -DMSABI -verify %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.
+
+#ifdef MSABI
+// expected-note@+2 3 {{declared private here}}
+#endif
 class NoDestroy { ~NoDestroy(); }; // expected-note 3 {{declared private here}}
 struct A {
   virtual ~A();
 };
 
+#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}}
+#endif
 struct D : public virtual B {
   virtual void foo();
   ~D();
 };
+#ifdef MSABI
+D d; // expected-note {{implicit default constructor for 'D' first required here}}
+#else
 void D::foo() { // expected-note {{implicit destructor for 'B' first required here}}
 }
+#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}}
+#endif
 struct F : public E { // expected-note {{implicit destructor for 'E' first required here}}
 };
+#ifdef MSABI
+// expected-note@+2 {{implicit default constructor for 'F' first required here}}
+#endif
 struct G : public virtual F {
   virtual void foo();
   ~G();
 };
+#ifdef MSABI
+G g; // expected-note {{implicit default constructor for 'G' first required here}}
+#else
 void G::foo() { // expected-note {{implicit destructor for 'F' first required here}}
 }
+#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}}
 };
+#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}}
+#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}}
+#endif
 struct J : public I {
   virtual void foo();
   ~J();
 };
+#ifdef MSABI
+J j; // expected-note {{implicit default constructor for 'J' first required here}}
+#else
 void J::foo() { // expected-note {{implicit destructor for 'H' first required here}}
 }
+#endif
diff --git a/test/SemaCXX/virtual-override-x86.cpp b/test/SemaCXX/virtual-override-x86.cpp
index 75d8af3..1d9d1fb 100644
--- a/test/SemaCXX/virtual-override-x86.cpp
+++ b/test/SemaCXX/virtual-override-x86.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple=i686-pc-unknown -fsyntax-only -verify %s -std=c++11 -cxx-abi microsoft
+// RUN: %clang_cc1 -triple=i686-pc-win32 -fsyntax-only -verify %s -std=c++11
 
 namespace PR14339 {
   class A {
diff --git a/test/SemaCXX/virtual-override.cpp b/test/SemaCXX/virtual-override.cpp
index b477438..e95acab 100644
--- a/test/SemaCXX/virtual-override.cpp
+++ b/test/SemaCXX/virtual-override.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+// RUN: %clang_cc1 -fsyntax-only -triple %itanium_abi_triple -verify %s -std=c++11
+// RUN: %clang_cc1 -fsyntax-only -triple %ms_abi_triple -verify %s -std=c++11
 namespace T1 {
 
 class A {
diff --git a/test/SemaCXX/vla.cpp b/test/SemaCXX/vla.cpp
index d63b633..dae6450 100644
--- a/test/SemaCXX/vla.cpp
+++ b/test/SemaCXX/vla.cpp
@@ -3,3 +3,17 @@
 // PR11925
 int n;
 int (&f())[n]; // expected-error {{function declaration cannot have variably modified type}}
+
+namespace PR18581 {
+  template<typename T> struct pod {};
+  template<typename T> struct error {
+    typename T::error e; // expected-error {{cannot be used prior to '::'}}
+  };
+  struct incomplete; // expected-note {{forward declaration}}
+
+  void f(int n) {
+    pod<int> a[n];
+    error<int> b[n]; // expected-note {{instantiation}}
+    incomplete c[n]; // expected-error {{incomplete}}
+  }
+}
diff --git a/test/SemaCXX/vtordisp-mode.cpp b/test/SemaCXX/vtordisp-mode.cpp
new file mode 100644
index 0000000..dc91534
--- /dev/null
+++ b/test/SemaCXX/vtordisp-mode.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple i686-pc-win32 -std=c++11 -vtordisp-mode=0 -DVTORDISP_MODE=0 %s -verify
+// RUN: %clang_cc1 -triple i686-pc-win32 -std=c++11 -vtordisp-mode=1 -DVTORDISP_MODE=1 %s -verify
+// RUN: %clang_cc1 -triple i686-pc-win32 -std=c++11 -vtordisp-mode=2 -DVTORDISP_MODE=2 %s -verify
+
+// expected-no-diagnostics
+
+struct A {
+  A();
+  virtual void foo();
+};
+
+// At /vd1, there is a vtordisp before A.
+struct B : virtual A {
+  B();
+  virtual void foo();
+  virtual void bar();
+};
+
+// At /vd2, there is a vtordisp before B, but only because it has its own
+// vftable.
+struct C : virtual B {
+  C();
+};
+
+// There are two vfptrs, two vbptrs, and some number of vtordisps.
+static_assert(sizeof(C) == 2 * 4 + 2 * 4 + 4 * VTORDISP_MODE, "size mismatch");
diff --git a/test/SemaCXX/warn-absolute-value-header.cpp b/test/SemaCXX/warn-absolute-value-header.cpp
new file mode 100644
index 0000000..925be38
--- /dev/null
+++ b/test/SemaCXX/warn-absolute-value-header.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -verify %s -Wabsolute-value
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only %s -Wabsolute-value -fdiagnostics-parseable-fixits 2>&1 | FileCheck %s
+
+extern "C" {
+  int abs(int);
+  float fabsf(float);
+}
+
+namespace std {
+  int abs(int);
+  float abs(float);
+}
+
+void test(long long ll, double d, int i, float f) {
+  // Suggest including cmath
+  (void)abs(d);
+  // expected-warning@-1{{using integer absolute value function 'abs' when argument is of floating point type}}
+  // expected-note@-2{{use function 'std::abs' instead}}
+  // expected-note@-3{{include the header <cmath> or explicitly provide a declaration for 'std::abs'}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:9-[[@LINE-4]]:12}:"std::abs"
+
+  (void)fabsf(d);
+  // expected-warning@-1{{absolute value function 'fabsf' given an argument of type 'double' but has parameter of type 'float' which may cause truncation of value}}
+  // expected-note@-2{{use function 'std::abs' instead}}
+  // expected-note@-3{{include the header <cmath> or explicitly provide a declaration for 'std::abs'}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:9-[[@LINE-4]]:14}:"std::abs"
+
+  // Suggest including cstdlib
+  (void)abs(ll);
+  // expected-warning@-1{{absolute value function 'abs' given an argument of type 'long long' but has parameter of type 'int' which may cause truncation of value}}
+  // expected-note@-2{{use function 'std::abs' instead}}
+  // expected-note@-3{{include the header <cstdlib> or explicitly provide a declaration for 'std::abs'}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:9-[[@LINE-4]]:12}:"std::abs"
+  (void)fabsf(ll);
+  // expected-warning@-1{{using floating point absolute value function 'fabsf' when argument is of integer type}}
+  // expected-note@-2{{use function 'std::abs' instead}}
+  // expected-note@-3{{include the header <cstdlib> or explicitly provide a declaration for 'std::abs'}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:9-[[@LINE-4]]:14}:"std::abs"
+
+  // Proper function already called, no warnings.
+  (void)abs(i);
+  (void)fabsf(f);
+
+  // Declarations found, suggest name change.
+  (void)fabsf(i);
+  // expected-warning@-1{{using floating point absolute value function 'fabsf' when argument is of integer type}}
+  // expected-note@-2{{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+  (void)abs(f);
+  // expected-warning@-1{{using integer absolute value function 'abs' when argument is of floating point type}}
+  // expected-note@-2{{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:"std::abs"
+}
diff --git a/test/SemaCXX/warn-absolute-value.cpp b/test/SemaCXX/warn-absolute-value.cpp
new file mode 100644
index 0000000..8a8a6fd
--- /dev/null
+++ b/test/SemaCXX/warn-absolute-value.cpp
@@ -0,0 +1,823 @@
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -verify %s -Wabsolute-value -std=c++11
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only %s -Wabsolute-value -fdiagnostics-parseable-fixits -std=c++11 2>&1 | FileCheck %s
+
+extern "C" {
+int abs(int);
+long int labs(long int);
+long long int llabs(long long int);
+
+float fabsf(float);
+double fabs(double);
+long double fabsl(long double);
+
+float cabsf(float _Complex);
+double cabs(double _Complex);
+long double cabsl(long double _Complex);
+}
+
+namespace std {
+
+inline namespace __1 {
+int abs(int);
+long int abs(long int);
+long long int abs(long long int);
+}
+
+float abs(float);
+double abs(double);
+long double abs(long double);
+
+template <typename T>
+double abs(T);
+
+}
+
+void test_int(int x) {
+  (void)std::abs(x);
+
+  (void)abs(x);
+  (void)labs(x);
+  (void)llabs(x);
+
+  (void)fabsf(x);
+  // expected-warning@-1 {{using floating point absolute value function 'fabsf' when argument is of integer type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+  (void)fabs(x);
+  // expected-warning@-1 {{using floating point absolute value function 'fabs' when argument is of integer type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"std::abs"
+  (void)fabsl(x);
+  // expected-warning@-1 {{using floating point absolute value function 'fabsl' when argument is of integer type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+
+  (void)cabsf(x);
+  // expected-warning@-1 {{using complex absolute value function 'cabsf' when argument is of integer type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+  (void)cabs(x);
+  // expected-warning@-1 {{using complex absolute value function 'cabs' when argument is of integer type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"std::abs"
+  (void)cabsl(x);
+  // expected-warning@-1 {{using complex absolute value function 'cabsl' when argument is of integer type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+
+  (void)__builtin_abs(x);
+  (void)__builtin_labs(x);
+  (void)__builtin_llabs(x);
+
+  (void)__builtin_fabsf(x);
+  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsf' when argument is of integer type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+  (void)__builtin_fabs(x);
+  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabs' when argument is of integer type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"std::abs"
+  (void)__builtin_fabsl(x);
+  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsl' when argument is of integer type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+
+  (void)__builtin_cabsf(x);
+  // expected-warning@-1 {{using complex absolute value function '__builtin_cabsf' when argument is of integer type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+  (void)__builtin_cabs(x);
+  // expected-warning@-1 {{using complex absolute value function '__builtin_cabs' when argument is of integer type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"std::abs"
+  (void)__builtin_cabsl(x);
+  // expected-warning@-1 {{using complex absolute value function '__builtin_cabsl' when argument is of integer type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+}
+
+void test_long(long x) {
+  (void)std::abs(x);
+
+  (void)abs(x);  // no warning - int and long are same length for this target
+  (void)labs(x);
+  (void)llabs(x);
+
+  (void)fabsf(x);
+  // expected-warning@-1 {{using floating point absolute value function 'fabsf' when argument is of integer type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+  (void)fabs(x);
+  // expected-warning@-1 {{using floating point absolute value function 'fabs' when argument is of integer type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"std::abs"
+  (void)fabsl(x);
+  // expected-warning@-1 {{using floating point absolute value function 'fabsl' when argument is of integer type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+
+  (void)cabsf(x);
+  // expected-warning@-1 {{using complex absolute value function 'cabsf' when argument is of integer type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+  (void)cabs(x);
+  // expected-warning@-1 {{using complex absolute value function 'cabs' when argument is of integer type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"std::abs"
+  (void)cabsl(x);
+  // expected-warning@-1 {{using complex absolute value function 'cabsl' when argument is of integer type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+
+  (void)__builtin_abs(x);  // no warning - int and long are same length for
+                           // this target
+  (void)__builtin_labs(x);
+  (void)__builtin_llabs(x);
+
+  (void)__builtin_fabsf(x);
+  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsf' when argument is of integer type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+  (void)__builtin_fabs(x);
+  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabs' when argument is of integer type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"std::abs"
+  (void)__builtin_fabsl(x);
+  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsl' when argument is of integer type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+
+  (void)__builtin_cabsf(x);
+  // expected-warning@-1 {{using complex absolute value function '__builtin_cabsf' when argument is of integer type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+  (void)__builtin_cabs(x);
+  // expected-warning@-1 {{using complex absolute value function '__builtin_cabs' when argument is of integer type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"std::abs"
+  (void)__builtin_cabsl(x);
+  // expected-warning@-1 {{using complex absolute value function '__builtin_cabsl' when argument is of integer type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+}
+
+void test_long_long(long long x) {
+  (void)std::abs(x);
+
+  (void)abs(x);
+  // expected-warning@-1{{absolute value function 'abs' given an argument of type 'long long' but has parameter of type 'int' which may cause truncation of value}}
+  // expected-note@-2{{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:"std::abs"
+  (void)labs(x);
+  // expected-warning@-1{{absolute value function 'labs' given an argument of type 'long long' but has parameter of type 'long' which may cause truncation of value}}
+  // expected-note@-2{{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"std::abs"
+  (void)llabs(x);
+
+  (void)fabsf(x);
+  // expected-warning@-1 {{using floating point absolute value function 'fabsf' when argument is of integer type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+  (void)fabs(x);
+  // expected-warning@-1 {{using floating point absolute value function 'fabs' when argument is of integer type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"std::abs"
+  (void)fabsl(x);
+  // expected-warning@-1 {{using floating point absolute value function 'fabsl' when argument is of integer type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+
+  (void)cabsf(x);
+  // expected-warning@-1 {{using complex absolute value function 'cabsf' when argument is of integer type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+  (void)cabs(x);
+  // expected-warning@-1 {{using complex absolute value function 'cabs' when argument is of integer type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"std::abs"
+  (void)cabsl(x);
+  // expected-warning@-1 {{using complex absolute value function 'cabsl' when argument is of integer type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+
+  (void)__builtin_abs(x);
+  // expected-warning@-1{{absolute value function '__builtin_abs' given an argument of type 'long long' but has parameter of type 'int' which may cause truncation of value}}
+  // expected-note@-2{{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:22}:"std::abs"
+  (void)__builtin_labs(x);
+  // expected-warning@-1{{absolute value function '__builtin_labs' given an argument of type 'long long' but has parameter of type 'long' which may cause truncation of value}}
+  // expected-note@-2{{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"std::abs"
+  (void)__builtin_llabs(x);
+
+  (void)__builtin_fabsf(x);
+  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsf' when argument is of integer type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+  (void)__builtin_fabs(x);
+  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabs' when argument is of integer type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"std::abs"
+  (void)__builtin_fabsl(x);
+  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsl' when argument is of integer type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+
+  (void)__builtin_cabsf(x);
+  // expected-warning@-1 {{using complex absolute value function '__builtin_cabsf' when argument is of integer type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+  (void)__builtin_cabs(x);
+  // expected-warning@-1 {{using complex absolute value function '__builtin_cabs' when argument is of integer type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"std::abs"
+  (void)__builtin_cabsl(x);
+  // expected-warning@-1 {{using complex absolute value function '__builtin_cabsl' when argument is of integer type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+}
+
+void test_float(float x) {
+  (void)std::abs(x);
+
+  (void)abs(x);
+  // expected-warning@-1 {{using integer absolute value function 'abs' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:"std::abs"
+  (void)labs(x);
+  // expected-warning@-1 {{using integer absolute value function 'labs' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"std::abs"
+  (void)llabs(x);
+  // expected-warning@-1 {{using integer absolute value function 'llabs' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+
+  (void)fabsf(x);
+  (void)fabs(x);
+  (void)fabsl(x);
+
+  (void)cabsf(x);
+  // expected-warning@-1 {{using complex absolute value function 'cabsf' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+  (void)cabs(x);
+  // expected-warning@-1 {{using complex absolute value function 'cabs' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"std::abs"
+  (void)cabsl(x);
+  // expected-warning@-1 {{using complex absolute value function 'cabsl' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+
+  (void)__builtin_abs(x);
+  // expected-warning@-1 {{using integer absolute value function '__builtin_abs' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:22}:"std::abs"
+  (void)__builtin_labs(x);
+  // expected-warning@-1 {{using integer absolute value function '__builtin_labs' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"std::abs"
+  (void)__builtin_llabs(x);
+  // expected-warning@-1 {{using integer absolute value function '__builtin_llabs' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+
+  (void)__builtin_fabsf(x);
+  (void)__builtin_fabs(x);
+  (void)__builtin_fabsl(x);
+
+  (void)__builtin_cabsf(x);
+  // expected-warning@-1 {{using complex absolute value function '__builtin_cabsf' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+  (void)__builtin_cabs(x);
+  // expected-warning@-1 {{using complex absolute value function '__builtin_cabs' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"std::abs"
+  (void)__builtin_cabsl(x);
+  // expected-warning@-1 {{using complex absolute value function '__builtin_cabsl' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+}
+
+void test_double(double x) {
+  (void)std::abs(x);
+
+  (void)abs(x);
+  // expected-warning@-1 {{using integer absolute value function 'abs' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:"std::abs"
+  (void)labs(x);
+  // expected-warning@-1 {{using integer absolute value function 'labs' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"std::abs"
+  (void)llabs(x);
+  // expected-warning@-1 {{using integer absolute value function 'llabs' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+
+  (void)fabsf(x);
+  // expected-warning@-1{{absolute value function 'fabsf' given an argument of type 'double' but has parameter of type 'float' which may cause truncation of value}}
+  // expected-note@-2{{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+  (void)fabs(x);
+  (void)fabsl(x);
+
+  (void)cabsf(x);
+  // expected-warning@-1 {{using complex absolute value function 'cabsf' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+  (void)cabs(x);
+  // expected-warning@-1 {{using complex absolute value function 'cabs' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"std::abs"
+  (void)cabsl(x);
+  // expected-warning@-1 {{using complex absolute value function 'cabsl' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+
+  (void)__builtin_abs(x);
+  // expected-warning@-1 {{using integer absolute value function '__builtin_abs' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:22}:"std::abs"
+  (void)__builtin_labs(x);
+  // expected-warning@-1 {{using integer absolute value function '__builtin_labs' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"std::abs"
+  (void)__builtin_llabs(x);
+  // expected-warning@-1 {{using integer absolute value function '__builtin_llabs' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+
+  (void)__builtin_fabsf(x);
+  // expected-warning@-1{{absolute value function '__builtin_fabsf' given an argument of type 'double' but has parameter of type 'float' which may cause truncation of value}}
+  // expected-note@-2{{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+  (void)__builtin_fabs(x);
+  (void)__builtin_fabsl(x);
+
+  (void)__builtin_cabsf(x);
+  // expected-warning@-1 {{using complex absolute value function '__builtin_cabsf' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+  (void)__builtin_cabs(x);
+  // expected-warning@-1 {{using complex absolute value function '__builtin_cabs' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"std::abs"
+  (void)__builtin_cabsl(x);
+  // expected-warning@-1 {{using complex absolute value function '__builtin_cabsl' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+}
+
+void test_long_double(long double x) {
+  (void)std::abs(x);
+
+  (void)abs(x);
+  // expected-warning@-1 {{using integer absolute value function 'abs' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:"std::abs"
+  (void)labs(x);
+  // expected-warning@-1 {{using integer absolute value function 'labs' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"std::abs"
+  (void)llabs(x);
+  // expected-warning@-1 {{using integer absolute value function 'llabs' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+
+  (void)fabsf(x);
+  // expected-warning@-1{{absolute value function 'fabsf' given an argument of type 'long double' but has parameter of type 'float' which may cause truncation of value}}
+  // expected-note@-2{{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+  (void)fabs(x);
+  // expected-warning@-1{{absolute value function 'fabs' given an argument of type 'long double' but has parameter of type 'double' which may cause truncation of value}}
+  // expected-note@-2{{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"std::abs"
+  (void)fabsl(x);
+
+  (void)cabsf(x);
+  // expected-warning@-1 {{using complex absolute value function 'cabsf' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+  (void)cabs(x);
+  // expected-warning@-1 {{using complex absolute value function 'cabs' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"std::abs"
+  (void)cabsl(x);
+  // expected-warning@-1 {{using complex absolute value function 'cabsl' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"std::abs"
+
+  (void)__builtin_abs(x);
+  // expected-warning@-1 {{using integer absolute value function '__builtin_abs' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:22}:"std::abs"
+  (void)__builtin_labs(x);
+  // expected-warning@-1 {{using integer absolute value function '__builtin_labs' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"std::abs"
+  (void)__builtin_llabs(x);
+  // expected-warning@-1 {{using integer absolute value function '__builtin_llabs' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+
+  (void)__builtin_fabsf(x);
+  // expected-warning@-1{{absolute value function '__builtin_fabsf' given an argument of type 'long double' but has parameter of type 'float' which may cause truncation of value}}
+  // expected-note@-2{{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+  (void)__builtin_fabs(x);
+  // expected-warning@-1{{absolute value function '__builtin_fabs' given an argument of type 'long double' but has parameter of type 'double' which may cause truncation of value}}
+  // expected-note@-2{{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"std::abs"
+  (void)__builtin_fabsl(x);
+
+  (void)__builtin_cabsf(x);
+  // expected-warning@-1 {{using complex absolute value function '__builtin_cabsf' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+  (void)__builtin_cabs(x);
+  // expected-warning@-1 {{using complex absolute value function '__builtin_cabs' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"std::abs"
+  (void)__builtin_cabsl(x);
+  // expected-warning@-1 {{using complex absolute value function '__builtin_cabsl' when argument is of floating point type}}
+  // expected-note@-2 {{use function 'std::abs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"std::abs"
+}
+
+void test_complex_float(_Complex float x) {
+  (void)abs(x);
+  // expected-warning@-1 {{using integer absolute value function 'abs' when argument is of complex type}}
+  // expected-note@-2 {{use function 'cabsf' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:"cabsf"
+  (void)labs(x);
+  // expected-warning@-1 {{using integer absolute value function 'labs' when argument is of complex type}}
+  // expected-note@-2 {{use function 'cabsf' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabsf"
+  (void)llabs(x);
+  // expected-warning@-1 {{using integer absolute value function 'llabs' when argument is of complex type}}
+  // expected-note@-2 {{use function 'cabsf' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsf"
+
+  (void)fabsf(x);
+  // expected-warning@-1 {{using floating point absolute value function 'fabsf' when argument is of complex type}}
+  // expected-note@-2 {{use function 'cabsf' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsf"
+  (void)fabs(x);
+  // expected-warning@-1 {{using floating point absolute value function 'fabs' when argument is of complex type}}
+  // expected-note@-2 {{use function 'cabsf' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabsf"
+  (void)fabsl(x);
+  // expected-warning@-1 {{using floating point absolute value function 'fabsl' when argument is of complex type}}
+  // expected-note@-2 {{use function 'cabsf' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsf"
+
+  (void)cabsf(x);
+  (void)cabs(x);
+  (void)cabsl(x);
+
+  (void)__builtin_abs(x);
+  // expected-warning@-1 {{using integer absolute value function '__builtin_abs' when argument is of complex type}}
+  // expected-note@-2 {{use function '__builtin_cabsf' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:22}:"__builtin_cabsf"
+  (void)__builtin_labs(x);
+  // expected-warning@-1 {{using integer absolute value function '__builtin_labs' when argument is of complex type}}
+  // expected-note@-2 {{use function '__builtin_cabsf' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabsf"
+  (void)__builtin_llabs(x);
+  // expected-warning@-1 {{using integer absolute value function '__builtin_llabs' when argument is of complex type}}
+  // expected-note@-2 {{use function '__builtin_cabsf' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsf"
+
+  (void)__builtin_fabsf(x);
+  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsf' when argument is of complex type}}
+  // expected-note@-2 {{use function '__builtin_cabsf' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsf"
+  (void)__builtin_fabs(x);
+  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabs' when argument is of complex type}}
+  // expected-note@-2 {{use function '__builtin_cabsf' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabsf"
+  (void)__builtin_fabsl(x);
+  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsl' when argument is of complex type}}
+  // expected-note@-2 {{use function '__builtin_cabsf' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsf"
+
+  (void)__builtin_cabsf(x);
+  (void)__builtin_cabs(x);
+  (void)__builtin_cabsl(x);
+}
+
+void test_complex_double(_Complex double x) {
+  (void)abs(x);
+  // expected-warning@-1 {{using integer absolute value function 'abs' when argument is of complex type}}
+  // expected-note@-2 {{use function 'cabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:"cabs"
+  (void)labs(x);
+  // expected-warning@-1 {{using integer absolute value function 'labs' when argument is of complex type}}
+  // expected-note@-2 {{use function 'cabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabs"
+  (void)llabs(x);
+  // expected-warning@-1 {{using integer absolute value function 'llabs' when argument is of complex type}}
+  // expected-note@-2 {{use function 'cabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabs"
+
+  (void)fabsf(x);
+  // expected-warning@-1 {{using floating point absolute value function 'fabsf' when argument is of complex type}}
+  // expected-note@-2 {{use function 'cabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabs"
+  (void)fabs(x);
+  // expected-warning@-1 {{using floating point absolute value function 'fabs' when argument is of complex type}}
+  // expected-note@-2 {{use function 'cabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabs"
+  (void)fabsl(x);
+  // expected-warning@-1 {{using floating point absolute value function 'fabsl' when argument is of complex type}}
+  // expected-note@-2 {{use function 'cabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabs"
+
+  (void)cabsf(x);
+  // expected-warning@-1 {{absolute value function 'cabsf' given an argument of type '_Complex double' but has parameter of type '_Complex float' which may cause truncation of value}}
+  // expected-note@-2 {{use function 'cabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabs"
+  (void)cabs(x);
+  (void)cabsl(x);
+
+  (void)__builtin_abs(x);
+  // expected-warning@-1 {{using integer absolute value function '__builtin_abs' when argument is of complex type}}
+  // expected-note@-2 {{use function '__builtin_cabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:22}:"__builtin_cabs"
+  (void)__builtin_labs(x);
+  // expected-warning@-1 {{using integer absolute value function '__builtin_labs' when argument is of complex type}}
+  // expected-note@-2 {{use function '__builtin_cabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabs"
+  (void)__builtin_llabs(x);
+  // expected-warning@-1 {{using integer absolute value function '__builtin_llabs' when argument is of complex type}}
+  // expected-note@-2 {{use function '__builtin_cabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabs"
+
+  (void)__builtin_fabsf(x);
+  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsf' when argument is of complex type}}
+  // expected-note@-2 {{use function '__builtin_cabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabs"
+  (void)__builtin_fabs(x);
+  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabs' when argument is of complex type}}
+  // expected-note@-2 {{use function '__builtin_cabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabs"
+  (void)__builtin_fabsl(x);
+  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsl' when argument is of complex type}}
+  // expected-note@-2 {{use function '__builtin_cabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabs"
+
+  (void)__builtin_cabsf(x);
+  // expected-warning@-1 {{absolute value function '__builtin_cabsf' given an argument of type '_Complex double' but has parameter of type '_Complex float' which may cause truncation of value}}
+  // expected-note@-2 {{use function '__builtin_cabs' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabs"
+  (void)__builtin_cabs(x);
+  (void)__builtin_cabsl(x);
+}
+
+void test_complex_long_double(_Complex long double x) {
+  (void)abs(x);
+  // expected-warning@-1 {{using integer absolute value function 'abs' when argument is of complex type}}
+  // expected-note@-2 {{use function 'cabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:"cabsl"
+  (void)labs(x);
+  // expected-warning@-1 {{using integer absolute value function 'labs' when argument is of complex type}}
+  // expected-note@-2 {{use function 'cabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabsl"
+  (void)llabs(x);
+  // expected-warning@-1 {{using integer absolute value function 'llabs' when argument is of complex type}}
+  // expected-note@-2 {{use function 'cabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsl"
+
+  (void)fabsf(x);
+  // expected-warning@-1 {{using floating point absolute value function 'fabsf' when argument is of complex type}}
+  // expected-note@-2 {{use function 'cabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsl"
+  (void)fabs(x);
+  // expected-warning@-1 {{using floating point absolute value function 'fabs' when argument is of complex type}}
+  // expected-note@-2 {{use function 'cabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabsl"
+  (void)fabsl(x);
+  // expected-warning@-1 {{using floating point absolute value function 'fabsl' when argument is of complex type}}
+  // expected-note@-2 {{use function 'cabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsl"
+
+  (void)cabsf(x);
+  // expected-warning@-1 {{absolute value function 'cabsf' given an argument of type '_Complex long double' but has parameter of type '_Complex float' which may cause truncation of value}}
+  // expected-note@-2 {{use function 'cabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsl"
+  (void)cabs(x);
+  // expected-warning@-1 {{absolute value function 'cabs' given an argument of type '_Complex long double' but has parameter of type '_Complex double' which may cause truncation of value}}
+  // expected-note@-2 {{use function 'cabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabsl"
+  (void)cabsl(x);
+
+  (void)__builtin_abs(x);
+  // expected-warning@-1 {{using integer absolute value function '__builtin_abs' when argument is of complex type}}
+  // expected-note@-2 {{use function '__builtin_cabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:22}:"__builtin_cabsl"
+  (void)__builtin_labs(x);
+  // expected-warning@-1 {{using integer absolute value function '__builtin_labs' when argument is of complex type}}
+  // expected-note@-2 {{use function '__builtin_cabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabsl"
+  (void)__builtin_llabs(x);
+  // expected-warning@-1 {{using integer absolute value function '__builtin_llabs' when argument is of complex type}}
+  // expected-note@-2 {{use function '__builtin_cabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsl"
+
+  (void)__builtin_fabsf(x);
+  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsf' when argument is of complex type}}
+  // expected-note@-2 {{use function '__builtin_cabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsl"
+  (void)__builtin_fabs(x);
+  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabs' when argument is of complex type}}
+  // expected-note@-2 {{use function '__builtin_cabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabsl"
+  (void)__builtin_fabsl(x);
+  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsl' when argument is of complex type}}
+  // expected-note@-2 {{use function '__builtin_cabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsl"
+
+  (void)__builtin_cabsf(x);
+  // expected-warning@-1 {{absolute value function '__builtin_cabsf' given an argument of type '_Complex long double' but has parameter of type '_Complex float' which may cause truncation of value}}
+  // expected-note@-2 {{use function '__builtin_cabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsl"
+  (void)__builtin_cabs(x);
+  // expected-warning@-1 {{absolute value function '__builtin_cabs' given an argument of type '_Complex long double' but has parameter of type '_Complex double' which may cause truncation of value}}
+  // expected-note@-2 {{use function '__builtin_cabsl' instead}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabsl"
+  (void)__builtin_cabsl(x);
+}
+
+void test_unsigned_int(unsigned int x) {
+  (void)std::abs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2 {{remove the call to 'std::abs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:17}:""
+
+  (void)abs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2 {{remove the call to 'abs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:""
+  (void)labs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2 {{remove the call to 'labs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:""
+  (void)llabs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2 {{remove the call to 'llabs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:""
+
+  (void)fabsf(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2 {{remove the call to 'fabsf' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:""
+  (void)fabs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2 {{remove the call to 'fabs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:""
+  (void)fabsl(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2 {{remove the call to 'fabsl' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:""
+
+  (void)cabsf(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2 {{remove the call to 'cabsf' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:""
+  (void)cabs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2 {{remove the call to 'cabs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:""
+  (void)cabsl(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2 {{remove the call to 'cabsl' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:""
+
+  (void)__builtin_abs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2 {{remove the call to '__builtin_abs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:22}:""
+  (void)__builtin_labs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2 {{remove the call to '__builtin_labs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:""
+  (void)__builtin_llabs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2 {{remove the call to '__builtin_llabs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:""
+
+  (void)__builtin_fabsf(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2 {{remove the call to '__builtin_fabsf' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:""
+  (void)__builtin_fabs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2 {{remove the call to '__builtin_fabs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:""
+  (void)__builtin_fabsl(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2 {{remove the call to '__builtin_fabsl' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:""
+
+  (void)__builtin_cabsf(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2 {{remove the call to '__builtin_cabsf' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:""
+  (void)__builtin_cabs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2 {{remove the call to '__builtin_cabs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:""
+  (void)__builtin_cabsl(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned int' has no effect}}
+  // expected-note@-2 {{remove the call to '__builtin_cabsl' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:""
+}
+
+void test_unsigned_long(unsigned long x) {
+  (void)std::abs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+  // expected-note@-2 {{remove the call to 'std::abs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:17}:""
+
+  (void)abs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+  // expected-note@-2 {{remove the call to 'abs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:""
+  (void)labs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+  // expected-note@-2 {{remove the call to 'labs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:""
+  (void)llabs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+  // expected-note@-2 {{remove the call to 'llabs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:""
+
+  (void)fabsf(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+  // expected-note@-2 {{remove the call to 'fabsf' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:""
+  (void)fabs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+  // expected-note@-2 {{remove the call to 'fabs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:""
+  (void)fabsl(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+  // expected-note@-2 {{remove the call to 'fabsl' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:""
+
+  (void)cabsf(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+  // expected-note@-2 {{remove the call to 'cabsf' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:""
+  (void)cabs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+  // expected-note@-2 {{remove the call to 'cabs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:""
+  (void)cabsl(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+  // expected-note@-2 {{remove the call to 'cabsl' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:""
+
+  (void)__builtin_abs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+  // expected-note@-2 {{remove the call to '__builtin_abs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:22}:""
+  (void)__builtin_labs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+  // expected-note@-2 {{remove the call to '__builtin_labs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:""
+  (void)__builtin_llabs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+  // expected-note@-2 {{remove the call to '__builtin_llabs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:""
+
+  (void)__builtin_fabsf(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+  // expected-note@-2 {{remove the call to '__builtin_fabsf' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:""
+  (void)__builtin_fabs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+  // expected-note@-2 {{remove the call to '__builtin_fabs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:""
+  (void)__builtin_fabsl(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+  // expected-note@-2 {{remove the call to '__builtin_fabsl' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:""
+
+  (void)__builtin_cabsf(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+  // expected-note@-2 {{remove the call to '__builtin_cabsf' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:""
+  (void)__builtin_cabs(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+  // expected-note@-2 {{remove the call to '__builtin_cabs' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:""
+  (void)__builtin_cabsl(x);
+  // expected-warning@-1 {{taking the absolute value of unsigned type 'unsigned long' has no effect}}
+  // expected-note@-2 {{remove the call to '__builtin_cabsl' since unsigned values cannot be negative}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:""
+}
+
diff --git a/test/SemaCXX/warn-address.cpp b/test/SemaCXX/warn-address.cpp
new file mode 100644
index 0000000..219edfd
--- /dev/null
+++ b/test/SemaCXX/warn-address.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-bool-conversion -Wno-string-compare -Wno-tautological-compare -Waddress %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void foo();
+int arr[5];
+int global;
+const char* str = "";
+
+void test() {
+  if (foo) {}            // expected-warning{{always evaluate to 'true'}} \
+                         // expected-note{{silence}}
+  if (arr) {}            // expected-warning{{always evaluate to 'true'}}
+  if (&global) {}        // expected-warning{{always evaluate to 'true'}}
+  if (foo == 0) {}       // expected-warning{{always false}} \
+                         // expected-note{{silence}}
+  if (arr == 0) {}       // expected-warning{{always false}}
+  if (&global == 0) {}   // expected-warning{{always false}}
+
+  if (str == "foo") {}   // expected-warning{{unspecified}}
+}
diff --git a/test/SemaCXX/warn-bad-memaccess.cpp b/test/SemaCXX/warn-bad-memaccess.cpp
index 7a7459a..e86610a 100644
--- a/test/SemaCXX/warn-bad-memaccess.cpp
+++ b/test/SemaCXX/warn-bad-memaccess.cpp
@@ -24,6 +24,11 @@
 struct X1 { virtual void f(); } x1;
 struct X2 : virtual S1 {} x2;
 
+struct ContainsDynamic { X1 dynamic; } contains_dynamic;
+struct DeepContainsDynamic { ContainsDynamic m; } deep_contains_dynamic;
+struct ContainsArrayDynamic { X1 dynamic[1]; } contains_array_dynamic;
+struct ContainsPointerDynamic { X1 *dynamic; } contains_pointer_dynamic;
+
 void test_warn() {
   memset(&x1, 0, sizeof x1); // \
       // expected-warning {{destination for this 'memset' call is a pointer to dynamic class}} \
@@ -33,22 +38,22 @@
       // expected-note {{explicitly cast the pointer to silence this warning}}
 
   memmove(&x1, 0, sizeof x1); // \
-      // expected-warning{{destination for this 'memmove' call is a pointer to dynamic class 'struct X1'; vtable pointer will be overwritten}} \
+      // expected-warning{{destination for this 'memmove' call is a pointer to dynamic class 'X1'; vtable pointer will be overwritten}} \
       // expected-note {{explicitly cast the pointer to silence this warning}}
   memmove(0, &x1, sizeof x1); // \
-      // expected-warning{{source of this 'memmove' call is a pointer to dynamic class 'struct X1'; vtable pointer will be moved}} \
+      // expected-warning{{source of this 'memmove' call is a pointer to dynamic class 'X1'; vtable pointer will be moved}} \
       // expected-note {{explicitly cast the pointer to silence this warning}}
   memcpy(&x1, 0, sizeof x1); // \
-      // expected-warning{{destination for this 'memcpy' call is a pointer to dynamic class 'struct X1'; vtable pointer will be overwritten}} \
+      // expected-warning{{destination for this 'memcpy' call is a pointer to dynamic class 'X1'; vtable pointer will be overwritten}} \
       // expected-note {{explicitly cast the pointer to silence this warning}}
   memcpy(0, &x1, sizeof x1); // \
-      // expected-warning{{source of this 'memcpy' call is a pointer to dynamic class 'struct X1'; vtable pointer will be copied}} \
+      // expected-warning{{source of this 'memcpy' call is a pointer to dynamic class 'X1'; vtable pointer will be copied}} \
       // expected-note {{explicitly cast the pointer to silence this warning}}
   memcmp(&x1, 0, sizeof x1); // \
-      // expected-warning{{first operand of this 'memcmp' call is a pointer to dynamic class 'struct X1'; vtable pointer will be compared}} \
+      // expected-warning{{first operand of this 'memcmp' call is a pointer to dynamic class 'X1'; vtable pointer will be compared}} \
       // expected-note {{explicitly cast the pointer to silence this warning}}
   memcmp(0, &x1, sizeof x1); // \
-      // expected-warning{{second operand of this 'memcmp' call is a pointer to dynamic class 'struct X1'; vtable pointer will be compared}} \
+      // expected-warning{{second operand of this 'memcmp' call is a pointer to dynamic class 'X1'; vtable pointer will be compared}} \
       // expected-note {{explicitly cast the pointer to silence this warning}}
 
   __builtin_memset(&x1, 0, sizeof x1); // \
@@ -90,6 +95,16 @@
   __builtin___memcpy_chk(0, &x1, sizeof x1, sizeof x1); //                    \
       // expected-warning{{source of this '__builtin___memcpy_chk' call is a pointer to dynamic class}} \
       // expected-note {{explicitly cast the pointer to silence this warning}}
+
+  // expected-warning@+2 {{destination for this 'memset' call is a pointer to class containing a dynamic class 'X1'}}
+  // expected-note@+1 {{explicitly cast the pointer to silence this warning}}
+  memset(&contains_dynamic, 0, sizeof(contains_dynamic));
+  // expected-warning@+2 {{destination for this 'memset' call is a pointer to class containing a dynamic class 'X1'}}
+  // expected-note@+1 {{explicitly cast the pointer to silence this warning}}
+  memset(&deep_contains_dynamic, 0, sizeof(deep_contains_dynamic));
+  // expected-warning@+2 {{destination for this 'memset' call is a pointer to class containing a dynamic class 'X1'}}
+  // expected-note@+1 {{explicitly cast the pointer to silence this warning}}
+  memset(&contains_array_dynamic, 0, sizeof(contains_array_dynamic));
 }
 
 void test_nowarn(void *void_ptr) {
@@ -107,6 +122,8 @@
   memset(&s3, 0, sizeof s3);
   memset(&c1, 0, sizeof c1);
 
+  memset(&contains_pointer_dynamic, 0, sizeof(contains_pointer_dynamic));
+
   // Unevaluated code shouldn't warn.
   (void)sizeof memset(&x1, 0, sizeof x1);
 
diff --git a/test/SemaCXX/warn-bool-conversion.cpp b/test/SemaCXX/warn-bool-conversion.cpp
index b3d136e..b462894 100644
--- a/test/SemaCXX/warn-bool-conversion.cpp
+++ b/test/SemaCXX/warn-bool-conversion.cpp
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 
+namespace BooleanFalse {
 int* j = false; // expected-warning{{initialization of pointer of type 'int *' to null from a constant boolean expression}}
 
 void foo(int* i, int *j=(false)) // expected-warning{{initialization of pointer of type 'int *' to null from a constant boolean expression}}
@@ -22,3 +23,98 @@
 // isn't flagged.
 template <int N> struct S {};
 S<sizeof(f(false))> s;
+
+}
+
+namespace Function {
+void f1();
+
+struct S {
+  static void f2();
+};
+
+extern void f3() __attribute__((weak_import));
+
+struct S2 {
+  static void f4() __attribute__((weak_import));
+};
+
+bool f5();
+bool f6(int);
+
+void bar() {
+  bool b;
+
+  b = f1; // expected-warning {{address of function 'f1' will always evaluate to 'true'}} \
+             expected-note {{prefix with the address-of operator to silence this warning}}
+  if (f1) {} // expected-warning {{address of function 'f1' will always evaluate to 'true'}} \
+                expected-note {{prefix with the address-of operator to silence this warning}}
+  b = S::f2; // expected-warning {{address of function 'S::f2' will always evaluate to 'true'}} \
+                expected-note {{prefix with the address-of operator to silence this warning}}
+  if (S::f2) {} // expected-warning {{address of function 'S::f2' will always evaluate to 'true'}} \
+                   expected-note {{prefix with the address-of operator to silence this warning}}
+  b = f5; // expected-warning {{address of function 'f5' will always evaluate to 'true'}} \
+             expected-note {{prefix with the address-of operator to silence this warning}} \
+             expected-note {{suffix with parentheses to turn this into a function call}}
+  b = f6; // expected-warning {{address of function 'f6' will always evaluate to 'true'}} \
+             expected-note {{prefix with the address-of operator to silence this warning}}
+
+  // implicit casts of weakly imported symbols are ok:
+  b = f3;
+  if (f3) {}
+  b = S2::f4;
+  if (S2::f4) {}
+}
+}
+
+namespace Array {
+  #define GetValue(ptr)  ((ptr) ? ptr[0] : 0)
+  extern int a[] __attribute__((weak));
+  int b[] = {8,13,21};
+  struct {
+    int x[10];
+  } c;
+  const char str[] = "text";
+  void ignore() {
+    if (a) {}
+    if (a) {}
+    (void)GetValue(b);
+  }
+  void test() {
+    if (b) {}
+    // expected-warning@-1{{address of array 'b' will always evaluate to 'true'}}
+    if (b) {}
+    // expected-warning@-1{{address of array 'b' will always evaluate to 'true'}}
+    if (c.x) {}
+    // expected-warning@-1{{address of array 'c.x' will always evaluate to 'true'}}
+    if (str) {}
+    // expected-warning@-1{{address of array 'str' will always evaluate to 'true'}}
+  }
+}
+
+namespace Pointer {
+  extern int a __attribute__((weak));
+  int b;
+  static int c;
+  class S {
+  public:
+    static int a;
+    int b;
+  };
+  void ignored() {
+    if (&a) {}
+  }
+  void test() {
+    S s;
+    if (&b) {}
+    // expected-warning@-1{{address of 'b' will always evaluate to 'true'}}
+    if (&c) {}
+    // expected-warning@-1{{address of 'c' will always evaluate to 'true'}}
+    if (&s.a) {}
+    // expected-warning@-1{{address of 's.a' will always evaluate to 'true'}}
+    if (&s.b) {}
+    // expected-warning@-1{{address of 's.b' will always evaluate to 'true'}}
+    if (&S::a) {}
+    // expected-warning@-1{{address of 'S::a' will always evaluate to 'true'}}
+  }
+}
diff --git a/test/SemaCXX/warn-consumed-analysis.cpp b/test/SemaCXX/warn-consumed-analysis.cpp
index 64fdc00..977b862 100644
--- a/test/SemaCXX/warn-consumed-analysis.cpp
+++ b/test/SemaCXX/warn-consumed-analysis.cpp
@@ -51,7 +51,7 @@
 
 class CONSUMABLE(unconsumed) DestructorTester {
 public:
-  DestructorTester() RETURN_TYPESTATE(unconsumed);
+  DestructorTester();
   DestructorTester(int);
   
   void operator*() CALLABLE_WHEN("unconsumed");
@@ -82,11 +82,21 @@
 void testInitialization() {
   ConsumableClass<int> var0;
   ConsumableClass<int> var1 = ConsumableClass<int>();
-  
-  var0 = ConsumableClass<int>();
-  
+  ConsumableClass<int> var2(42);
+  ConsumableClass<int> var3(var2);  // copy constructor
+  ConsumableClass<int> var4(var0);  // copy consumed value
+
   *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
   *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}}
+  *var2;
+  *var3;
+  *var4; // expected-warning {{invalid invocation of method 'operator*' on object 'var4' while it is in the 'consumed' state}}
+
+  var0 = ConsumableClass<int>(42);
+  *var0;
+  
+  var0 = var1;
+  *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}}
   
   if (var0.isValid()) {
     *var0;
@@ -98,19 +108,16 @@
 }
 
 void testDestruction() {
-  DestructorTester D0(42), D1(42);
+  DestructorTester D0(42), D1(42), D2;
   
   *D0;
   *D1;
-  
-  DestructorTester D2;
-  *D2;
+  *D2; // expected-warning {{invalid invocation of method 'operator*' on object 'D2' while it is in the 'consumed' state}}
   
   D0.~DestructorTester(); // expected-warning {{invalid invocation of method '~DestructorTester' on object 'D0' while it is in the 'unconsumed' state}}
   
   return; // expected-warning {{invalid invocation of method '~DestructorTester' on object 'D0' while it is in the 'unconsumed' state}} \
-             expected-warning {{invalid invocation of method '~DestructorTester' on object 'D1' while it is in the 'unconsumed' state}} \
-             expected-warning {{invalid invocation of method '~DestructorTester' on object 'D2' while it is in the 'unconsumed' state}}
+             expected-warning {{invalid invocation of method '~DestructorTester' on object 'D1' while it is in the 'unconsumed' state}}
 }
 
 void testTempValue() {
@@ -427,6 +434,29 @@
   testParamTypestateCallee(Var0, Var1); // expected-warning {{argument not in expected state; expected 'consumed', observed 'unconsumed'}}
 }
 
+
+void consumeFunc(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
+struct ParamTest {
+  static void consumeFuncStatic(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
+  void consumeFuncMeth(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
+  void operator<<(ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
+};
+
+void operator>>(ParamTest& pt, ConsumableClass<int> P PARAM_TYPESTATE(unconsumed));
+
+
+void testFunctionParams() {
+  // Make sure we handle the different kinds of functions.
+  ConsumableClass<int> P;
+
+  consumeFunc(P);                   // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
+  ParamTest::consumeFuncStatic(P);  // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
+  ParamTest pt;
+  pt.consumeFuncMeth(P);            // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
+  pt << P;                          // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
+  pt >> P;                          // expected-warning {{argument not in expected state; expected 'unconsumed', observed 'consumed'}}
+}
+
 void baf3(ConsumableClass<int> var) {
   *var;
 }
@@ -645,12 +675,17 @@
 } // end namespace ContinueICETest
 
 
-namespace InitializerAssertionFailTest {
+namespace StatusUseCaseTests {
 
-class CONSUMABLE(unconsumed) Status {
+class CONSUMABLE(unconsumed)
+      __attribute__((consumable_auto_cast_state))
+      __attribute__((consumable_set_state_on_read))
+    Status {
   int code;
 
 public:
+  static Status OK;
+
   Status() RETURN_TYPESTATE(consumed);
   Status(int c) RETURN_TYPESTATE(unconsumed);
 
@@ -660,6 +695,8 @@
   Status& operator=(const Status &other) CALLABLE_WHEN("unknown", "consumed");
   Status& operator=(Status &&other) CALLABLE_WHEN("unknown", "consumed");
 
+  bool operator==(const Status &other) const SET_TYPESTATE(consumed);
+
   bool check()  const SET_TYPESTATE(consumed);
   void ignore() const SET_TYPESTATE(consumed);
   // Status& markAsChecked() { return *this; }
@@ -667,13 +704,22 @@
   void clear() CALLABLE_WHEN("unknown", "consumed") SET_TYPESTATE(consumed);
 
   ~Status() CALLABLE_WHEN("unknown", "consumed");
+
+  operator bool() const; // Will not consume the object.
 };
 
 
 bool   cond();
 Status doSomething();
 void   handleStatus(const Status& s RETURN_TYPESTATE(consumed));
-void   handleStatusPtr(const Status* s);
+void   handleStatusRef(Status& s);
+void   handleStatusPtr(Status* s);
+void   handleStatusUnmarked(const Status& s);
+
+void   log(const char* msg);
+void   fail() __attribute__((noreturn));
+void   checkStat(const Status& s);
+
 
 void testSimpleTemporaries0() {
   doSomething(); // expected-warning {{invalid invocation of method '~Status' on a temporary object while it is in the 'unconsumed' state}}
@@ -691,6 +737,19 @@
   Status s = doSomething();
 }  // expected-warning {{invalid invocation of method '~Status' on object 's' while it is in the 'unconsumed' state}}
 
+void testTemporariesWithControlFlow(bool a) {
+  bool b = false || doSomething(); // expected-warning {{invalid invocation of method '~Status' on a temporary object while it is in the 'unconsumed' state}}
+}
+
+Status testSimpleTemporariesReturn0() {
+  return doSomething();
+}
+
+Status testSimpleTemporariesReturn1() {
+  Status s = doSomething();
+  return s;
+}
+
 void testSimpleTemporaries4() {
   Status s = doSomething();
   s.check();
@@ -702,8 +761,17 @@
 }
 
 void testSimpleTemporaries6() {
-  Status s = doSomething();
-  handleStatus(s);
+  Status s1 = doSomething();
+  handleStatus(s1);
+
+  Status s2 = doSomething();
+  handleStatusRef(s2);
+
+  Status s3 = doSomething();
+  handleStatusPtr(&s3);
+
+  Status s4 = doSomething();
+  handleStatusUnmarked(s4);
 }
 
 void testSimpleTemporaries7() {
@@ -745,38 +813,58 @@
 }
 
 void testTemporariesAndConstructors0() {
-  Status s(doSomething());
+  Status s(doSomething());    // Test the copy constructor.
   s.check();
 }
 
-void testTemporariesAndConstructors1() {
-  // Test the copy constructor.
-  
-  Status s1 = doSomething();
-  Status s2(s1);
-  s2.check();
-}  // expected-warning {{invalid invocation of method '~Status' on object 's1' while it is in the 'unconsumed' state}}
+void testTemporariesAndConstructors1F() {
+  Status s1 = doSomething();  // Test the copy constructor.
+  Status s2 = s1;
+} // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}}
 
-void testTemporariesAndConstructors2() {
-  // Test the move constructor.
-  
-  Status s1 = doSomething();
-  Status s2(static_cast<Status&&>(s1));
+void testTemporariesAndConstructors1S() {
+  Status s1 = doSomething();  // Test the copy constructor.
+  Status s2(s1);
   s2.check();
 }
 
-void testTemporariesAndOperators0() {
+void testTemporariesAndConstructors2F() {
+  // Test the move constructor.
+  Status s1 = doSomething();
+  Status s2 = static_cast<Status&&>(s1);
+} // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}}
+
+void testTemporariesAndConstructors2S() {
+  // Test the move constructor.
+  Status s1 = doSomething();
+  Status s2 = static_cast<Status&&>(s1);
+  s2.check();
+}
+
+void testTemporariesAndOperators0F() {
   // Test the assignment operator.
-  
+  Status s1 = doSomething();
+  Status s2;
+  s2 = s1;
+} // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}}
+
+void testTemporariesAndOperators0S() {
+  // Test the assignment operator.
   Status s1 = doSomething();
   Status s2;
   s2 = s1;
   s2.check();
-} // expected-warning {{invalid invocation of method '~Status' on object 's1' while it is in the 'unconsumed' state}}
+}
 
-void testTemporariesAndOperators1() {
+void testTemporariesAndOperators1F() {
   // Test the move assignment operator.
-  
+  Status s1 = doSomething();
+  Status s2;
+  s2 = static_cast<Status&&>(s1);
+} // expected-warning {{invalid invocation of method '~Status' on object 's2' while it is in the 'unconsumed' state}}
+
+void testTemporariesAndOperators1S() {
+  // Test the move assignment operator.
   Status s1 = doSomething();
   Status s2;
   s2 = static_cast<Status&&>(s1);
@@ -791,5 +879,62 @@
   s2.check();
 }
 
+Status testReturnAutocast() {
+  Status s = doSomething();
+  s.check();  // consume s
+  return s;   // should autocast back to unconsumed
+}
+
+
+namespace TestParens {
+
+void test3() {
+  checkStat((doSomething()));
+}
+
+void test4() {
+  Status s = (doSomething());
+  s.check();
+}
+
+void test5() {
+  (doSomething()).check();
+}
+
+void test6() {
+  if ((doSomething()) == Status::OK)
+    return;
+}
+
+} // end namespace TestParens
+
 } // end namespace InitializerAssertionFailTest
 
+
+namespace std {
+  void move();
+  template<class T>
+  void move(T&&);
+
+  namespace __1 {
+    void move();
+    template<class T>
+    void move(T&&);
+  }
+}
+
+namespace PR18260 {
+  class X {
+    public:
+      void move();
+  } x;
+
+  void test() {
+    x.move();
+    std::move();
+    std::move(x);
+    std::__1::move();
+    std::__1::move(x);
+  }
+} // end namespace PR18260
+
diff --git a/test/SemaCXX/warn-consumed-parsing.cpp b/test/SemaCXX/warn-consumed-parsing.cpp
index 0a91636..5c0a04f 100644
--- a/test/SemaCXX/warn-consumed-parsing.cpp
+++ b/test/SemaCXX/warn-consumed-parsing.cpp
@@ -17,9 +17,9 @@
 }
 
 class AttrTester0 {
-  void consumes()       __attribute__ ((set_typestate())); // expected-error {{attribute takes one argument}}
-  bool testUnconsumed() __attribute__ ((test_typestate())); // expected-error {{attribute takes one argument}}
-  void callableWhen()   __attribute__ ((callable_when())); // expected-error {{attribute takes at least 1 argument}}
+  void consumes()       __attribute__ ((set_typestate())); // expected-error {{'set_typestate' attribute takes one argument}}
+  bool testUnconsumed() __attribute__ ((test_typestate())); // expected-error {{'test_typestate' attribute takes one argument}}
+  void callableWhen()   __attribute__ ((callable_when())); // expected-error {{'callable_when' attribute takes at least 1 argument}}
 };
 
 int var0 SET_TYPESTATE(consumed); // expected-warning {{'set_typestate' attribute only applies to methods}}
@@ -53,3 +53,13 @@
 };
 
 class CONSUMABLE(42) AttrTester3; // expected-error {{'consumable' attribute requires an identifier}}
+
+
+class CONSUMABLE(unconsumed)
+      __attribute__((consumable_auto_cast_state))
+      __attribute__((consumable_set_state_on_read))
+      Status {
+};
+
+
+
diff --git a/test/SemaCXX/warn-exit-time-destructors.cpp b/test/SemaCXX/warn-exit-time-destructors.cpp
index f49134b..124576a 100644
--- a/test/SemaCXX/warn-exit-time-destructors.cpp
+++ b/test/SemaCXX/warn-exit-time-destructors.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wexit-time-destructors %s -verify
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -Wexit-time-destructors %s -verify
 
 namespace test1 {
   struct A { ~A(); };
@@ -23,5 +23,23 @@
   static A &e = b[5];
   static A &f = c[5][7];
 }
+}
 
+namespace test3 {
+  struct A { ~A() = default; };
+  A a;
+
+  struct B { ~B(); };
+  struct C : B { ~C() = default; };
+  C c; // expected-warning {{exit-time destructor}}
+
+  class D {
+    friend struct E;
+    ~D() = default;
+  };
+  struct E : D {
+    D d;
+    ~E() = default;
+  };
+  E e;
 }
diff --git a/test/SemaCXX/warn-float-conversion.cpp b/test/SemaCXX/warn-float-conversion.cpp
new file mode 100644
index 0000000..22c3304
--- /dev/null
+++ b/test/SemaCXX/warn-float-conversion.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s -Wfloat-conversion
+
+bool ReturnBool(float f) {
+  return f;  //expected-warning{{conversion}}
+}
+
+char ReturnChar(float f) {
+  return f;  //expected-warning{{conversion}}
+}
+
+int ReturnInt(float f) {
+  return f;  //expected-warning{{conversion}}
+}
+
+long ReturnLong(float f) {
+  return f;  //expected-warning{{conversion}}
+}
+
+void Convert(float f, double d, long double ld) {
+  bool b;
+  char c;
+  int i;
+  long l;
+
+  b = f;  //expected-warning{{conversion}}
+  b = d;  //expected-warning{{conversion}}
+  b = ld;  //expected-warning{{conversion}}
+  c = f;  //expected-warning{{conversion}}
+  c = d;  //expected-warning{{conversion}}
+  c = ld;  //expected-warning{{conversion}}
+  i = f;  //expected-warning{{conversion}}
+  i = d;  //expected-warning{{conversion}}
+  i = ld;  //expected-warning{{conversion}}
+  l = f;  //expected-warning{{conversion}}
+  l = d;  //expected-warning{{conversion}}
+  l = ld;  //expected-warning{{conversion}}
+}
+
diff --git a/test/SemaCXX/warn-func-as-bool.cpp b/test/SemaCXX/warn-func-as-bool.cpp
deleted file mode 100644
index b5df744..0000000
--- a/test/SemaCXX/warn-func-as-bool.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-// RUN: %clang_cc1 -x c++ -verify -fsyntax-only %s
-
-void f1();
-
-struct S {
-  static void f2();
-};
-
-extern void f3() __attribute__((weak_import));
-
-struct S2 {
-  static void f4() __attribute__((weak_import));
-};
-
-bool f5();
-bool f6(int);
-
-void bar() {
-  bool b;
-
-  b = f1; // expected-warning {{address of function 'f1' will always evaluate to 'true'}} \
-             expected-note {{prefix with the address-of operator to silence this warning}}
-  if (f1) {} // expected-warning {{address of function 'f1' will always evaluate to 'true'}} \
-                expected-note {{prefix with the address-of operator to silence this warning}}
-  b = S::f2; // expected-warning {{address of function 'S::f2' will always evaluate to 'true'}} \
-                expected-note {{prefix with the address-of operator to silence this warning}}
-  if (S::f2) {} // expected-warning {{address of function 'S::f2' will always evaluate to 'true'}} \
-                   expected-note {{prefix with the address-of operator to silence this warning}}
-  b = f5; // expected-warning {{address of function 'f5' will always evaluate to 'true'}} \
-             expected-note {{prefix with the address-of operator to silence this warning}} \
-             expected-note {{suffix with parentheses to turn this into a function call}}
-  b = f6; // expected-warning {{address of function 'f6' will always evaluate to 'true'}} \
-             expected-note {{prefix with the address-of operator to silence this warning}}
-
-  // implicit casts of weakly imported symbols are ok:
-  b = f3;
-  if (f3) {}
-  b = S2::f4;
-  if (S2::f4) {}
-}
diff --git a/test/SemaCXX/warn-global-constructors.cpp b/test/SemaCXX/warn-global-constructors.cpp
index f57f0de..90d8558 100644
--- a/test/SemaCXX/warn-global-constructors.cpp
+++ b/test/SemaCXX/warn-global-constructors.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wglobal-constructors %s -verify
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -Wglobal-constructors %s -verify
 
 int opaque_int();
 
@@ -101,3 +101,22 @@
   int a;
   A b = { a };
 }
+
+namespace pr19253 {
+  struct A { ~A() = default; };
+  A a;
+
+  struct B { ~B(); };
+  struct C : B { ~C() = default; };
+  C c; // expected-warning {{global destructor}}
+
+  class D {
+    friend struct E;
+    ~D() = default;
+  };
+  struct E : D {
+    D d;
+    ~E() = default;
+  };
+  E e;
+}
diff --git a/test/SemaCXX/warn-infinite-recursion.cpp b/test/SemaCXX/warn-infinite-recursion.cpp
new file mode 100644
index 0000000..e1b7c54
--- /dev/null
+++ b/test/SemaCXX/warn-infinite-recursion.cpp
@@ -0,0 +1,152 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -Winfinite-recursion
+
+void a() {  // expected-warning{{call itself}}
+  a();
+}
+
+void b(int x) {  // expected-warning{{call itself}}
+  if (x)
+    b(x);
+  else
+    b(x+1);
+}
+
+void c(int x) {
+  if (x)
+    c(5);
+}
+
+void d(int x) {  // expected-warning{{call itself}}
+  if (x)
+    ++x;
+  return d(x);
+}
+
+// Doesn't warn on mutually recursive functions
+void e();
+void f();
+
+void e() { f(); }
+void f() { e(); }
+
+// Don't warn on infinite loops
+void g() {
+  while (true)
+    g();
+
+  g();
+}
+
+void h(int x) {
+  while (x < 5) {
+    h(x+1);
+  }
+}
+
+void i(int x) {  // expected-warning{{call itself}}
+  while (x < 5) {
+    --x;
+  }
+  i(0);
+}
+
+int j() {  // expected-warning{{call itself}}
+  return 5 + j();
+}
+
+class S {
+  static void a();
+  void b();
+};
+
+void S::a() {  // expected-warning{{call itself}}
+  return a();
+}
+
+void S::b() {  // expected-warning{{call itself}}
+  int i = 0;
+  do {
+    ++i;
+    b();
+  } while (i > 5);
+}
+
+template<class member>
+struct T {
+  member m;
+  void a() { return a(); }  // expected-warning{{call itself}}
+  static void b() { return b(); }  // expected-warning{{call itself}}
+};
+
+void test_T() {
+  T<int> foo;
+  foo.a();  // expected-note{{in instantiation}}
+  foo.b();  // expected-note{{in instantiation}}
+}
+
+class U {
+  U* u;
+  void Fun() {  // expected-warning{{call itself}}
+    u->Fun();
+  }
+};
+
+// No warnings on templated functions
+// sum<0>() is instantiated, does recursively call itself, but never runs.
+template <int value>
+int sum() {
+  return value + sum<value/2>();
+}
+
+template<>
+int sum<1>() { return 1; }
+
+template<int x, int y>
+int calculate_value() {
+  if (x != y)
+    return sum<x - y>();  // This instantiates sum<0>() even if never called.
+  else
+    return 0;
+}
+
+int value = calculate_value<1,1>();
+
+void DoSomethingHere();
+
+// DoStuff<0,0>() is instantiated, but never called.
+template<int First, int Last>
+int DoStuff() {
+  if (First + 1 == Last) {
+    // This branch gets removed during <0, 0> instantiation in so CFG for this
+    // function goes straight to the else branch.
+    DoSomethingHere();
+  } else {
+    DoStuff<First, (First + Last)/2>();
+    DoStuff<(First + Last)/2, Last>();
+  }
+  return 0;
+}
+int stuff = DoStuff<0, 1>();
+
+template<int x>
+struct Wrapper {
+  static int run() {
+    // Similar to the above, Wrapper<0>::run() will discard the if statement.
+    if (x == 1)
+      return 0;
+    return Wrapper<x/2>::run();
+  }
+  static int run2() {  // expected-warning{{call itself}}
+    return run2();
+  }
+};
+
+template <int x>
+int test_wrapper() {
+  if (x != 0)
+    return Wrapper<x>::run() +
+           Wrapper<x>::run2();  // expected-note{{instantiation}}
+  return 0;
+}
+
+int wrapper_sum = test_wrapper<2>();  // expected-note{{instantiation}}
diff --git a/test/SemaCXX/warn-memsize-comparison.cpp b/test/SemaCXX/warn-memsize-comparison.cpp
new file mode 100644
index 0000000..54c410e
--- /dev/null
+++ b/test/SemaCXX/warn-memsize-comparison.cpp
@@ -0,0 +1,93 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+//
+
+typedef __SIZE_TYPE__ size_t;
+extern "C" void *memset(void *, int, size_t);
+extern "C" void *memmove(void *s1, const void *s2, size_t n);
+extern "C" void *memcpy(void *s1, const void *s2, size_t n);
+extern "C" void *memcmp(void *s1, const void *s2, size_t n);
+extern "C" int strncmp(const char *s1, const char *s2, size_t n);
+extern "C" int strncasecmp(const char *s1, const char *s2, size_t n);
+extern "C" char *strncpy(char *dst, const char *src, size_t n);
+extern "C" char *strncat(char *dst, const char *src, size_t n);
+extern "C" char *strndup(const  char *src, size_t n);
+extern "C" size_t strlcpy(char *dst, const char *src, size_t size);
+extern "C" size_t strlcat(char *dst, const char *src, size_t size);
+
+void f() {
+  char b1[80], b2[80];
+  if (memset(b1, 0, sizeof(b1) != 0)) {} // \
+    expected-warning{{size argument in 'memset' call is a comparison}} \
+    expected-note {{did you mean to compare}} \
+    expected-note {{explicitly cast the argument}}
+  if (memset(b1, 0, sizeof(b1)) != 0) {}
+
+  if (memmove(b1, b2, sizeof(b1) == 0)) {} // \
+    expected-warning{{size argument in 'memmove' call is a comparison}} \
+    expected-note {{did you mean to compare}} \
+    expected-note {{explicitly cast the argument}}
+  if (memmove(b1, b2, sizeof(b1)) == 0) {}
+
+  if (memcpy(b1, b2, sizeof(b1) < 0)) {} // \
+    expected-warning{{size argument in 'memcpy' call is a comparison}} \
+    expected-note {{did you mean to compare}} \
+    expected-note {{explicitly cast the argument}}
+  if (memcpy(b1, b2, sizeof(b1)) < 0) {}
+
+  if (memcmp(b1, b2, sizeof(b1) <= 0)) {} // \
+    expected-warning{{size argument in 'memcmp' call is a comparison}} \
+    expected-note {{did you mean to compare}} \
+    expected-note {{explicitly cast the argument}}
+  if (memcmp(b1, b2, sizeof(b1)) <= 0) {}
+
+  if (strncmp(b1, b2, sizeof(b1) > 0)) {} // \
+    expected-warning{{size argument in 'strncmp' call is a comparison}} \
+    expected-note {{did you mean to compare}} \
+    expected-note {{explicitly cast the argument}}
+  if (strncmp(b1, b2, sizeof(b1)) > 0) {}
+
+  if (strncasecmp(b1, b2, sizeof(b1) >= 0)) {} // \
+    expected-warning{{size argument in 'strncasecmp' call is a comparison}} \
+    expected-note {{did you mean to compare}} \
+    expected-note {{explicitly cast the argument}}
+  if (strncasecmp(b1, b2, sizeof(b1)) >= 0) {}
+
+  if (strncpy(b1, b2, sizeof(b1) == 0 || true)) {} // \
+    expected-warning{{size argument in 'strncpy' call is a comparison}} \
+    expected-note {{did you mean to compare}} \
+    expected-note {{explicitly cast the argument}}
+  if (strncpy(b1, b2, sizeof(b1)) == 0 || true) {}
+
+  if (strncat(b1, b2, sizeof(b1) - 1 >= 0 && true)) {} // \
+    expected-warning{{size argument in 'strncat' call is a comparison}} \
+    expected-note {{did you mean to compare}} \
+    expected-note {{explicitly cast the argument}}
+  if (strncat(b1, b2, sizeof(b1) - 1) >= 0 && true) {}
+
+  if (strndup(b1, sizeof(b1) != 0)) {} // \
+    expected-warning{{size argument in 'strndup' call is a comparison}} \
+    expected-note {{did you mean to compare}} \
+    expected-note {{explicitly cast the argument}}
+  if (strndup(b1, sizeof(b1)) != 0) {}
+
+  if (strlcpy(b1, b2, sizeof(b1) != 0)) {} // \
+    expected-warning{{size argument in 'strlcpy' call is a comparison}} \
+    expected-note {{did you mean to compare}} \
+    expected-note {{explicitly cast the argument}}
+  if (strlcpy(b1, b2, sizeof(b1)) != 0) {}
+
+  if (strlcat(b1, b2, sizeof(b1) != 0)) {} // \
+    expected-warning{{size argument in 'strlcat' call is a comparison}} \
+    expected-note {{did you mean to compare}} \
+    expected-note {{explicitly cast the argument}}
+  if (strlcat(b1, b2, sizeof(b1)) != 0) {}
+
+  if (memset(b1, 0, sizeof(b1) / 2)) {}
+  if (memset(b1, 0, sizeof(b1) >> 2)) {}
+  if (memset(b1, 0, 4 << 2)) {}
+  if (memset(b1, 0, 4 + 2)) {}
+  if (memset(b1, 0, 4 - 2)) {}
+  if (memset(b1, 0, 4 * 2)) {}
+
+  if (memset(b1, 0, (size_t)(sizeof(b1) != 0))) {}
+}
diff --git a/test/SemaCXX/warn-new-overaligned.cpp b/test/SemaCXX/warn-new-overaligned.cpp
index 42a4e35..710973c 100644
--- a/test/SemaCXX/warn-new-overaligned.cpp
+++ b/test/SemaCXX/warn-new-overaligned.cpp
@@ -38,7 +38,7 @@
   } __attribute__((aligned(256)));
 
   void* operator new(unsigned long) {
-    return 0;
+    return 0; // expected-warning {{'operator new' should not return a null pointer unless it is declared 'throw()'}}
   }
 
   SeparateCacheLines<int> high_contention_data[10];
@@ -59,7 +59,7 @@
   } __attribute__((aligned(256)));
 
   void* operator new[](unsigned long) {
-    return 0;
+    return 0; // expected-warning {{'operator new[]' should not return a null pointer unless it is declared 'throw()'}}
   }
 
   SeparateCacheLines<int> high_contention_data[10];
diff --git a/test/SemaCXX/warn-reinterpret-base-class.cpp b/test/SemaCXX/warn-reinterpret-base-class.cpp
index 36b8fda..0231f19 100644
--- a/test/SemaCXX/warn-reinterpret-base-class.cpp
+++ b/test/SemaCXX/warn-reinterpret-base-class.cpp
@@ -1,5 +1,8 @@
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -Wreinterpret-base-class -Wno-unused-volatile-lvalue %s
-// RUN: not %clang_cc1 -std=c++11 -fsyntax-only -fdiagnostics-parseable-fixits -Wreinterpret-base-class -Wno-unused-volatile-lvalue %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -triple %itanium_abi_triple -verify -Wreinterpret-base-class -Wno-unused-volatile-lvalue %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -triple %ms_abi_triple -DMSABI -verify -Wreinterpret-base-class -Wno-unused-volatile-lvalue %s
+
+// RUN: not %clang_cc1 -std=c++11 -fsyntax-only -triple %itanium_abi_triple -fdiagnostics-parseable-fixits -Wreinterpret-base-class -Wno-unused-volatile-lvalue %s 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -std=c++11 -fsyntax-only -triple %ms_abi_triple -fdiagnostics-parseable-fixits -Wreinterpret-base-class -Wno-unused-volatile-lvalue %s 2>&1 | FileCheck %s
 
 // PR 13824
 class A {
@@ -288,6 +291,11 @@
   (void)reinterpret_cast<I *>(f);
   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
 
+#ifdef MSABI
+  // In MS ABI mode, A is at non-zero offset in H.
+  // expected-warning@+3 {{'reinterpret_cast' to class 'H *' from its base at non-zero offset 'A *' behaves differently from 'static_cast'}}
+  // expected-note@+2 {{use 'static_cast'}}
+#endif
   (void)reinterpret_cast<H *>(a);
 
   // expected-warning@+2 {{'reinterpret_cast' to class 'L' (aka 'const F *volatile') from its base at non-zero offset 'E *' behaves differently from 'static_cast'}}
@@ -309,6 +317,12 @@
   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:25}:"static_cast"
 
   (void)reinterpret_cast<E *>(h);
+
+#ifdef MSABI
+  // In MS ABI mode, A is at non-zero offset in H.
+  // expected-warning@+3 {{'reinterpret_cast' from class 'H *' to its base at non-zero offset 'A *' behaves differently from 'static_cast'}}
+  // expected-note@+2 {{use 'static_cast'}}
+#endif
   (void)reinterpret_cast<A *>(h);
 
   // expected-warning@+2 {{'reinterpret_cast' from class 'I *' to its virtual base 'F *' behaves differently from 'static_cast'}}
diff --git a/test/SemaCXX/warn-self-assign.cpp b/test/SemaCXX/warn-self-assign.cpp
index fcdb2ab..7d558c6 100644
--- a/test/SemaCXX/warn-self-assign.cpp
+++ b/test/SemaCXX/warn-self-assign.cpp
@@ -8,6 +8,9 @@
   b = a = b;
   a = a = a; // expected-warning{{explicitly assigning}}
   a = b = b = a;
+  a &= a; // expected-warning{{explicitly assigning}}
+  a |= a; // expected-warning{{explicitly assigning}}
+  a ^= a;
 }
 
 // Dummy type.
diff --git a/test/SemaCXX/warn-shadow.cpp b/test/SemaCXX/warn-shadow.cpp
index 68e9467..5ad2233 100644
--- a/test/SemaCXX/warn-shadow.cpp
+++ b/test/SemaCXX/warn-shadow.cpp
@@ -22,7 +22,7 @@
 using namespace yy;
 
 void foo() {
-  int i; // expected-warning {{declaration shadows a variable in namespace '<anonymous>'}}
+  int i; // expected-warning {{declaration shadows a variable in namespace '(anonymous)'}}
   int j; // expected-warning {{declaration shadows a variable in namespace 'one::two'}}
   int m;
 }
diff --git a/test/SemaCXX/warn-sign-conversion.cpp b/test/SemaCXX/warn-sign-conversion.cpp
index ba2bc9b..746b124 100644
--- a/test/SemaCXX/warn-sign-conversion.cpp
+++ b/test/SemaCXX/warn-sign-conversion.cpp
@@ -25,23 +25,23 @@
     int c1 = 1 ? i : Foo<bool>::C;
     int c2 = 1 ? Foo<bool>::C : i;
 
-    int d1a = 1 ? i : Foo<bool>::D; // expected-warning {{test1::Foo<bool>::<anonymous enum at }}
-    int d1b = 1 ? i : Foo<bool>::D; // expected-warning {{warn-sign-conversion.cpp:13:5>' to 'int'}}
-    int d2a = 1 ? Foo<bool>::D : i; // expected-warning {{operand of ? changes signedness: 'test1::Foo<bool>::<anonymous enum at }}
-    int d2b = 1 ? Foo<bool>::D : i; // expected-warning {{warn-sign-conversion.cpp:13:5>' to 'int'}}
-    int d3a = 1 ? B : Foo<bool>::D; // expected-warning {{operand of ? changes signedness: 'test1::Foo<bool>::<anonymous enum at }}
-    int d3b = 1 ? B : Foo<bool>::D; // expected-warning {{warn-sign-conversion.cpp:13:5>' to 'int'}}
-    int d4a = 1 ? Foo<bool>::D : B; // expected-warning {{operand of ? changes signedness: 'test1::Foo<bool>::<anonymous enum at }}
-    int d4b = 1 ? Foo<bool>::D : B; // expected-warning {{warn-sign-conversion.cpp:13:5>' to 'int'}}
+    int d1a = 1 ? i : Foo<bool>::D; // expected-warning {{test1::Foo<bool>::(anonymous enum at }}
+    int d1b = 1 ? i : Foo<bool>::D; // expected-warning {{warn-sign-conversion.cpp:13:5)' to 'int'}}
+    int d2a = 1 ? Foo<bool>::D : i; // expected-warning {{operand of ? changes signedness: 'test1::Foo<bool>::(anonymous enum at }}
+    int d2b = 1 ? Foo<bool>::D : i; // expected-warning {{warn-sign-conversion.cpp:13:5)' to 'int'}}
+    int d3a = 1 ? B : Foo<bool>::D; // expected-warning {{operand of ? changes signedness: 'test1::Foo<bool>::(anonymous enum at }}
+    int d3b = 1 ? B : Foo<bool>::D; // expected-warning {{warn-sign-conversion.cpp:13:5)' to 'int'}}
+    int d4a = 1 ? Foo<bool>::D : B; // expected-warning {{operand of ? changes signedness: 'test1::Foo<bool>::(anonymous enum at }}
+    int d4b = 1 ? Foo<bool>::D : B; // expected-warning {{warn-sign-conversion.cpp:13:5)' to 'int'}}
 
-    int e1a = 1 ? i : E; // expected-warning {{operand of ? changes signedness: 'test1::<anonymous enum at }}
-    int e1b = 1 ? i : E; // expected-warning {{warn-sign-conversion.cpp:16:3>' to 'int'}}
-    int e2a = 1 ? E : i; // expected-warning {{operand of ? changes signedness: 'test1::<anonymous enum at }}
-    int e2b = 1 ? E : i; // expected-warning {{warn-sign-conversion.cpp:16:3>' to 'int'}}
-    int e3a = 1 ? E : B; // expected-warning {{operand of ? changes signedness: 'test1::<anonymous enum at }}
-    int e3b = 1 ? E : B; // expected-warning {{warn-sign-conversion.cpp:16:3>' to 'int'}}
-    int e4a = 1 ? B : E; // expected-warning {{operand of ? changes signedness: 'test1::<anonymous enum at }}
-    int e4b = 1 ? B : E; // expected-warning {{warn-sign-conversion.cpp:16:3>' to 'int'}}
+    int e1a = 1 ? i : E; // expected-warning {{operand of ? changes signedness: 'test1::(anonymous enum at }}
+    int e1b = 1 ? i : E; // expected-warning {{warn-sign-conversion.cpp:16:3)' to 'int'}}
+    int e2a = 1 ? E : i; // expected-warning {{operand of ? changes signedness: 'test1::(anonymous enum at }}
+    int e2b = 1 ? E : i; // expected-warning {{warn-sign-conversion.cpp:16:3)' to 'int'}}
+    int e3a = 1 ? E : B; // expected-warning {{operand of ? changes signedness: 'test1::(anonymous enum at }}
+    int e3b = 1 ? E : B; // expected-warning {{warn-sign-conversion.cpp:16:3)' to 'int'}}
+    int e4a = 1 ? B : E; // expected-warning {{operand of ? changes signedness: 'test1::(anonymous enum at }}
+    int e4b = 1 ? B : E; // expected-warning {{warn-sign-conversion.cpp:16:3)' to 'int'}}
   }
 }
 
diff --git a/test/SemaCXX/warn-string-conversion.cpp b/test/SemaCXX/warn-string-conversion.cpp
index 23960e4..b26126f 100644
--- a/test/SemaCXX/warn-string-conversion.cpp
+++ b/test/SemaCXX/warn-string-conversion.cpp
@@ -1,14 +1,20 @@
 // RUN: %clang_cc1 -fsyntax-only -Wstring-conversion -verify %s
 
 // Warn on cases where a string literal is converted into a bool.
-// An exception is made for this in logical operators.
+// An exception is made for this in logical and operators.
 void assert(bool condition);
 void test0() {
   bool b0 = "hi"; // expected-warning{{implicit conversion turns string literal into bool: 'const char [3]' to 'bool'}}
   b0 = ""; // expected-warning{{implicit conversion turns string literal into bool: 'const char [1]' to 'bool'}}
+  b0 = 0 || ""; // expected-warning{{implicit conversion turns string literal into bool: 'const char [1]' to 'bool'}}
+  b0 = "" || 0; // expected-warning{{implicit conversion turns string literal into bool: 'const char [1]' to 'bool'}}
   b0 = 0 && "";
+  b0 = "" && 0;
   assert("error"); // expected-warning{{implicit conversion turns string literal into bool: 'const char [6]' to 'bool'}}
+  assert(0 || "error"); // expected-warning{{implicit conversion turns string literal into bool: 'const char [6]' to 'bool'}}
+  assert("error" || 0); // expected-warning{{implicit conversion turns string literal into bool: 'const char [6]' to 'bool'}}
   assert(0 && "error");
+  assert("error" && 0);
 
   while("hi") {} // expected-warning{{implicit conversion turns string literal into bool: 'const char [3]' to 'bool'}}
   do {} while("hi"); // expected-warning{{implicit conversion turns string literal into bool: 'const char [3]' to 'bool'}}
diff --git a/test/SemaCXX/warn-sysheader-macro.cpp b/test/SemaCXX/warn-sysheader-macro.cpp
new file mode 100644
index 0000000..c884617
--- /dev/null
+++ b/test/SemaCXX/warn-sysheader-macro.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -verify -fsyntax-only -Wshadow -Wold-style-cast %s
+
+// Test that macro expansions from system headers don't trigger 'syntactic'
+// warnings that are not actionable.
+
+#ifdef IS_SYSHEADER
+#pragma clang system_header
+
+#define SANITY(a) (a / 0)
+
+#define SHADOW(a) __extension__({ int v = a; v; })
+
+#define OLD_STYLE_CAST(a) ((int) (a))
+
+#else
+
+#define IS_SYSHEADER
+#include __FILE__
+
+void testSanity() {
+  // Validate that the test is set up correctly
+  int i = SANITY(0); // expected-warning {{division by zero is undefined}}
+}
+
+void PR16093() {
+  // no -Wshadow in system macro expansion
+  int i = SHADOW(SHADOW(1));
+}
+
+void PR18147() {
+  // no -Wold_style_cast in system macro expansion
+  int i = OLD_STYLE_CAST(0);
+}
+
+#endif
diff --git a/test/SemaCXX/warn-tautological-compare.cpp b/test/SemaCXX/warn-tautological-compare.cpp
new file mode 100644
index 0000000..b44f3f9
--- /dev/null
+++ b/test/SemaCXX/warn-tautological-compare.cpp
@@ -0,0 +1,138 @@
+// Force x86-64 because some of our heuristics are actually based
+// on integer sizes.
+
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -fsyntax-only -verify -std=c++11 %s
+
+namespace RuntimeBehavior {
+  // Avoid emitting tautological compare warnings when the code already has
+  // compile time checks on variable sizes.
+
+  const int kintmax = 2147483647;
+  void test0(short x) {
+    if (sizeof(x) < sizeof(int) || x < kintmax) {}
+
+    if (x < kintmax) {}
+    // expected-warning@-1{{comparison of constant 2147483647 with expression of type 'short' is always true}}
+  }
+
+  void test1(short x) {
+    if (x < kintmax) {}
+    // expected-warning@-1{{comparison of constant 2147483647 with expression of type 'short' is always true}}
+
+    if (sizeof(x) < sizeof(int))
+      return;
+
+    if (x < kintmax) {}
+  }
+}
+
+namespace ArrayCompare {
+  #define GetValue(ptr)  ((ptr != 0) ? ptr[0] : 0)
+  extern int a[] __attribute__((weak));
+  int b[] = {8,13,21};
+  struct {
+    int x[10];
+  } c;
+  const char str[] = "text";
+  void ignore() {
+    if (a == 0) {}
+    if (a != 0) {}
+    (void)GetValue(b);
+  }
+  void test() {
+    if (b == 0) {}
+    // expected-warning@-1{{comparison of array 'b' equal to a null pointer is always false}}
+    if (b != 0) {}
+    // expected-warning@-1{{comparison of array 'b' not equal to a null pointer is always true}}
+    if (0 == b) {}
+    // expected-warning@-1{{comparison of array 'b' equal to a null pointer is always false}}
+    if (0 != b) {}
+    // expected-warning@-1{{comparison of array 'b' not equal to a null pointer is always true}}
+    if (c.x == 0) {}
+    // expected-warning@-1{{comparison of array 'c.x' equal to a null pointer is always false}}
+    if (c.x != 0) {}
+    // expected-warning@-1{{comparison of array 'c.x' not equal to a null pointer is always true}}
+    if (str == 0) {}
+    // expected-warning@-1{{comparison of array 'str' equal to a null pointer is always false}}
+    if (str != 0) {}
+    // expected-warning@-1{{comparison of array 'str' not equal to a null pointer is always true}}
+  }
+}
+
+namespace FunctionCompare {
+  #define CallFunction(f) ((f != 0) ? f() : 0)
+  extern void a()  __attribute__((weak));
+  void fun1();
+  int fun2();
+  int* fun3();
+  int* fun4(int);
+  class S {
+  public:
+    static int foo();
+  };
+  void ignore() {
+    if (a == 0) {}
+    if (0 != a) {}
+    (void)CallFunction(fun2);
+  }
+  void test() {
+    if (fun1 == 0) {}
+    // expected-warning@-1{{comparison of function 'fun1' equal to a null pointer is always false}}
+    // expected-note@-2{{prefix with the address-of operator to silence this warning}}
+    if (fun2 == 0) {}
+    // expected-warning@-1{{comparison of function 'fun2' equal to a null pointer is always false}}
+    // expected-note@-2{{prefix with the address-of operator to silence this warning}}
+    // expected-note@-3{{suffix with parentheses to turn this into a function call}}
+    if (fun3 == 0) {}
+    // expected-warning@-1{{comparison of function 'fun3' equal to a null pointer is always false}}
+    // expected-note@-2{{prefix with the address-of operator to silence this warning}}
+    // expected-note@-3{{suffix with parentheses to turn this into a function call}}
+    if (fun4 == 0) {}
+    // expected-warning@-1{{comparison of function 'fun4' equal to a null pointer is always false}}
+    // expected-note@-2{{prefix with the address-of operator to silence this warning}}
+    if (nullptr != fun1) {}
+    // expected-warning@-1{{comparison of function 'fun1' not equal to a null pointer is always true}}
+    // expected-note@-2{{prefix with the address-of operator to silence this warning}}
+    if (nullptr != fun2) {}
+    // expected-warning@-1{{comparison of function 'fun2' not equal to a null pointer is always true}}
+    // expected-note@-2{{prefix with the address-of operator to silence this warning}}
+    if (nullptr != fun3) {}
+    // expected-warning@-1{{comparison of function 'fun3' not equal to a null pointer is always true}}
+    // expected-note@-2{{prefix with the address-of operator to silence this warning}}
+    // expected-note@-3{{suffix with parentheses to turn this into a function call}}
+    if (nullptr != fun4) {}
+    // expected-warning@-1{{comparison of function 'fun4' not equal to a null pointer is always true}}
+    // expected-note@-2{{prefix with the address-of operator to silence this warning}}
+    if (S::foo == 0) {}
+    // expected-warning@-1{{comparison of function 'S::foo' equal to a null pointer is always false}}
+    // expected-note@-2{{prefix with the address-of operator to silence this warning}}
+    // expected-note@-3{{suffix with parentheses to turn this into a function call}}
+  }
+}
+
+namespace PointerCompare {
+  extern int a __attribute__((weak));
+  int b;
+  static int c;
+  class S {
+  public:
+    static int a;
+    int b;
+  };
+  void ignored() {
+    if (&a == 0) {}
+  }
+  void test() {
+    S s;
+    if (&b == 0) {}
+    // expected-warning@-1{{comparison of address of 'b' equal to a null pointer is always false}}
+    if (&c == 0) {}
+    // expected-warning@-1{{comparison of address of 'c' equal to a null pointer is always false}}
+    if (&s.a == 0) {}
+    // expected-warning@-1{{comparison of address of 's.a' equal to a null pointer is always false}}
+    if (&s.b == 0) {}
+    // expected-warning@-1{{comparison of address of 's.b' equal to a null pointer is always false}}
+    if (&S::a == 0) {}
+    // expected-warning@-1{{comparison of address of 'S::a' equal to a null pointer is always false}}
+  }
+}
diff --git a/test/SemaCXX/warn-tautological-undefined-compare.cpp b/test/SemaCXX/warn-tautological-undefined-compare.cpp
new file mode 100644
index 0000000..ce05bfc
--- /dev/null
+++ b/test/SemaCXX/warn-tautological-undefined-compare.cpp
@@ -0,0 +1,112 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wtautological-undefined-compare %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-tautological-compare -Wtautological-undefined-compare %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wtautological-compare %s
+
+void test1(int &x) {
+  if (x == 1) { }
+  if (&x == 0) { }
+  // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+  if (&x != 0) { }
+  // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+}
+
+class test2 {
+  test2() : x(y) {}
+
+  void foo() {
+    if (this == 0) { }
+    // expected-warning@-1{{'this' pointer cannot be null in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+    if (this != 0) { }
+    // expected-warning@-1{{'this' pointer cannot be null in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+  }
+
+  void bar() {
+    if (x == 1) { }
+    if (&x == 0) { }
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+    if (&x != 0) { }
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+  }
+
+  int &x;
+  int y;
+};
+
+namespace function_return_reference {
+  int& get_int();
+  // expected-note@-1 4{{'get_int' returns a reference}}
+  class B {
+  public:
+    static int &stat();
+    // expected-note@-1 4{{'stat' returns a reference}}
+    int &get();
+    // expected-note@-1 8{{'get' returns a reference}}
+  };
+
+  void test() {
+    if (&get_int() == 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+    if (&(get_int()) == 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+
+    if (&get_int() != 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+    if (&(get_int()) != 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+
+    if (&B::stat() == 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+    if (&(B::stat()) == 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+
+    if (&B::stat() != 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+    if (&(B::stat()) != 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+
+    B b;
+    if (&b.get() == 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+    if (&(b.get()) == 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+
+    if (&b.get() != 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+    if (&(b.get()) != 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+
+    B* b_ptr = &b;
+    if (&b_ptr->get() == 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+    if (&(b_ptr->get()) == 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+
+    if (&b_ptr->get() != 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+    if (&(b_ptr->get()) != 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+
+    int& (B::*m_ptr)() = &B::get;
+    if (&(b.*m_ptr)() == 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+    if (&((b.*m_ptr)()) == 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+
+    if (&(b.*m_ptr)() != 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+    if (&((b.*m_ptr)()) != 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+
+    int& (*f_ptr)() = &get_int;
+    if (&(*f_ptr)() == 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+    if (&((*f_ptr)()) == 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false}}
+
+    if (&(*f_ptr)() != 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+    if (&((*f_ptr)()) != 0) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to true}}
+  }
+}
diff --git a/test/SemaCXX/warn-thread-safety-analysis.cpp b/test/SemaCXX/warn-thread-safety-analysis.cpp
index 8ed5466..34a33aa 100644
--- a/test/SemaCXX/warn-thread-safety-analysis.cpp
+++ b/test/SemaCXX/warn-thread-safety-analysis.cpp
@@ -208,33 +208,33 @@
 
 void sls_fun_bad_1() {
   sls_mu.Unlock(); // \
-    // expected-warning{{unlocking 'sls_mu' that was not locked}}
+    // expected-warning{{releasing mutex 'sls_mu' that was not held}}
 }
 
 void sls_fun_bad_2() {
   sls_mu.Lock();
   sls_mu.Lock(); // \
-    // expected-warning{{locking 'sls_mu' that is already locked}}
+    // expected-warning{{acquiring mutex 'sls_mu' that is already held}}
   sls_mu.Unlock();
 }
 
 void sls_fun_bad_3() {
   sls_mu.Lock(); // expected-note {{mutex acquired here}}
-} // expected-warning{{mutex 'sls_mu' is still locked at the end of function}}
+} // expected-warning{{mutex 'sls_mu' is still held at the end of function}}
 
 void sls_fun_bad_4() {
   if (getBool())
     sls_mu.Lock();  // expected-note{{mutex acquired here}}
   else
     sls_mu2.Lock(); // expected-note{{mutex acquired here}}
-} // expected-warning{{mutex 'sls_mu' is not locked on every path through here}}  \
-  // expected-warning{{mutex 'sls_mu2' is not locked on every path through here}}
+} // expected-warning{{mutex 'sls_mu' is not held on every path through here}}  \
+  // expected-warning{{mutex 'sls_mu2' is not held on every path through here}}
 
 void sls_fun_bad_5() {
   sls_mu.Lock(); // expected-note {{mutex acquired here}}
   if (getBool())
     sls_mu.Unlock();
-} // expected-warning{{mutex 'sls_mu' is not locked on every path through here}}
+} // expected-warning{{mutex 'sls_mu' is not held on every path through here}}
 
 void sls_fun_bad_6() {
   if (getBool()) {
@@ -247,8 +247,8 @@
     }
   }
   sls_mu.Unlock(); // \
-    expected-warning{{mutex 'sls_mu' is not locked on every path through here}}\
-    expected-warning{{unlocking 'sls_mu' that was not locked}}
+    expected-warning{{mutex 'sls_mu' is not held on every path through here}}\
+    expected-warning{{releasing mutex 'sls_mu' that was not held}}
 }
 
 void sls_fun_bad_7() {
@@ -258,7 +258,7 @@
     if (getBool()) {
       if (getBool()) {
         continue; // \
-        expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
+        expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
       }
     }
     sls_mu.Lock(); // expected-note {{mutex acquired here}}
@@ -270,14 +270,14 @@
   sls_mu.Lock(); // expected-note{{mutex acquired here}}
 
   do {
-    sls_mu.Unlock(); // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
+    sls_mu.Unlock(); // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
   } while (getBool());
 }
 
 void sls_fun_bad_9() {
   do {
     sls_mu.Lock();  // \
-      // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}} \
+      // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}} \
       // expected-note{{mutex acquired here}}
   } while (getBool());
   sls_mu.Unlock();
@@ -285,18 +285,18 @@
 
 void sls_fun_bad_10() {
   sls_mu.Lock();  // expected-note 2{{mutex acquired here}}
-  while(getBool()) {  // expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
+  while(getBool()) {  // expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
     sls_mu.Unlock();
   }
-} // expected-warning{{mutex 'sls_mu' is still locked at the end of function}}
+} // expected-warning{{mutex 'sls_mu' is still held at the end of function}}
 
 void sls_fun_bad_11() {
   while (getBool()) { // \
-      expected-warning{{expecting mutex 'sls_mu' to be locked at start of each loop}}
+      expected-warning{{expecting mutex 'sls_mu' to be held at start of each loop}}
     sls_mu.Lock(); // expected-note {{mutex acquired here}}
   }
   sls_mu.Unlock(); // \
-    // expected-warning{{unlocking 'sls_mu' that was not locked}}
+    // expected-warning{{releasing mutex 'sls_mu' that was not held}}
 }
 
 void sls_fun_bad_12() {
@@ -305,7 +305,7 @@
     sls_mu.Unlock();
     if (getBool()) {
       if (getBool()) {
-        break; // expected-warning{{mutex 'sls_mu' is not locked on every path through here}}
+        break; // expected-warning{{mutex 'sls_mu' is not held on every path through here}}
       }
     }
     sls_mu.Lock();
@@ -334,19 +334,19 @@
 
 void aa_fun_bad_1() {
   glock.globalUnlock(); // \
-    // expected-warning{{unlocking 'aa_mu' that was not locked}}
+    // expected-warning{{releasing mutex 'aa_mu' that was not held}}
 }
 
 void aa_fun_bad_2() {
   glock.globalLock();
   glock.globalLock(); // \
-    // expected-warning{{locking 'aa_mu' that is already locked}}
+    // expected-warning{{acquiring mutex 'aa_mu' that is already held}}
   glock.globalUnlock();
 }
 
 void aa_fun_bad_3() {
   glock.globalLock(); // expected-note{{mutex acquired here}}
-} // expected-warning{{mutex 'aa_mu' is still locked at the end of function}}
+} // expected-warning{{mutex 'aa_mu' is still held at the end of function}}
 
 //--------------------------------------------------//
 // Regression tests for unusual method names
@@ -359,17 +359,17 @@
   // FIXME: can't currently check inside constructors and destructors.
   WeirdMethods() {
     wmu.Lock(); // EXPECTED-NOTE {{mutex acquired here}}
-  } // EXPECTED-WARNING {{mutex 'wmu' is still locked at the end of function}}
+  } // EXPECTED-WARNING {{mutex 'wmu' is still held at the end of function}}
   ~WeirdMethods() {
     wmu.Lock(); // EXPECTED-NOTE {{mutex acquired here}}
-  } // EXPECTED-WARNING {{mutex 'wmu' is still locked at the end of function}}
+  } // EXPECTED-WARNING {{mutex 'wmu' is still held at the end of function}}
   void operator++() {
     wmu.Lock(); // expected-note {{mutex acquired here}}
-  } // expected-warning {{mutex 'wmu' is still locked at the end of function}}
+  } // expected-warning {{mutex 'wmu' is still held at the end of function}}
   operator int*() {
     wmu.Lock(); // expected-note {{mutex acquired here}}
     return 0;
-  } // expected-warning {{mutex 'wmu' is still locked at the end of function}}
+  } // expected-warning {{mutex 'wmu' is still held at the end of function}}
 };
 
 //-----------------------------------------------//
@@ -386,13 +386,13 @@
                  __attribute__((pt_guarded_by(sls_mu)));
   void testFoo() {
     pgb_field = &x; // \
-      // expected-warning {{writing variable 'pgb_field' requires locking 'sls_mu2' exclusively}}
-    *pgb_field = x; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \
-      // expected-warning {{writing the value pointed to by 'pgb_field' requires locking 'sls_mu' exclusively}}
-    x = *pgb_field; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \
-      // expected-warning {{reading the value pointed to by 'pgb_field' requires locking 'sls_mu'}}
-    (*pgb_field)++; // expected-warning {{reading variable 'pgb_field' requires locking 'sls_mu2'}} \
-      // expected-warning {{writing the value pointed to by 'pgb_field' requires locking 'sls_mu' exclusively}}
+      // expected-warning {{writing variable 'pgb_field' requires holding mutex 'sls_mu2' exclusively}}
+    *pgb_field = x; // expected-warning {{reading variable 'pgb_field' requires holding mutex 'sls_mu2'}} \
+      // expected-warning {{writing the value pointed to by 'pgb_field' requires holding mutex 'sls_mu' exclusively}}
+    x = *pgb_field; // expected-warning {{reading variable 'pgb_field' requires holding mutex 'sls_mu2'}} \
+      // expected-warning {{reading the value pointed to by 'pgb_field' requires holding mutex 'sls_mu'}}
+    (*pgb_field)++; // expected-warning {{reading variable 'pgb_field' requires holding mutex 'sls_mu2'}} \
+      // expected-warning {{writing the value pointed to by 'pgb_field' requires holding mutex 'sls_mu' exclusively}}
   }
 };
 
@@ -402,7 +402,7 @@
 
   void testFoo() {
     gb_field = 0; // \
-      // expected-warning {{writing variable 'gb_field' requires locking 'sls_mu' exclusively}}
+      // expected-warning {{writing variable 'gb_field' requires holding mutex 'sls_mu' exclusively}}
   }
 
   void testNoAnal() __attribute__((no_thread_safety_analysis)) {
@@ -435,59 +435,59 @@
 
 void gb_bad_0() {
   sls_guard_var = 1; // \
-    // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
+    // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
 }
 
 void gb_bad_1() {
   int x = sls_guard_var; // \
-    // expected-warning{{reading variable 'sls_guard_var' requires locking any mutex}}
+    // expected-warning{{reading variable 'sls_guard_var' requires holding any mutex}}
 }
 
 void gb_bad_2() {
   sls_guardby_var = 1; // \
-    // expected-warning {{writing variable 'sls_guardby_var' requires locking 'sls_mu' exclusively}}
+    // expected-warning {{writing variable 'sls_guardby_var' requires holding mutex 'sls_mu' exclusively}}
 }
 
 void gb_bad_3() {
   int x = sls_guardby_var; // \
-    // expected-warning {{reading variable 'sls_guardby_var' requires locking 'sls_mu'}}
+    // expected-warning {{reading variable 'sls_guardby_var' requires holding mutex 'sls_mu'}}
 }
 
 void gb_bad_4() {
   *pgb_gvar = 1; // \
-    // expected-warning {{writing the value pointed to by 'pgb_gvar' requires locking any mutex exclusively}}
+    // expected-warning {{writing the value pointed to by 'pgb_gvar' requires holding any mutex exclusively}}
 }
 
 void gb_bad_5() {
   int x = *pgb_gvar; // \
-    // expected-warning {{reading the value pointed to by 'pgb_gvar' requires locking any mutex}}
+    // expected-warning {{reading the value pointed to by 'pgb_gvar' requires holding any mutex}}
 }
 
 void gb_bad_6() {
   *pgb_var = 1; // \
-    // expected-warning {{writing the value pointed to by 'pgb_var' requires locking 'sls_mu' exclusively}}
+    // expected-warning {{writing the value pointed to by 'pgb_var' requires holding mutex 'sls_mu' exclusively}}
 }
 
 void gb_bad_7() {
   int x = *pgb_var; // \
-    // expected-warning {{reading the value pointed to by 'pgb_var' requires locking 'sls_mu'}}
+    // expected-warning {{reading the value pointed to by 'pgb_var' requires holding mutex 'sls_mu'}}
 }
 
 void gb_bad_8() {
   GBFoo G;
   G.gb_field = 0; // \
-    // expected-warning {{writing variable 'gb_field' requires locking 'sls_mu'}}
+    // expected-warning {{writing variable 'gb_field' requires holding mutex 'sls_mu'}}
 }
 
 void gb_bad_9() {
   sls_guard_var++; // \
-    // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
+    // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
   sls_guard_var--; // \
-    // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
+    // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
   ++sls_guard_var; // \
-    // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
+    // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
   --sls_guard_var;// \
-    // expected-warning{{writing variable 'sls_guard_var' requires locking any mutex exclusively}}
+    // expected-warning{{writing variable 'sls_guard_var' requires holding any mutex exclusively}}
 }
 
 //-----------------------------------------------//
@@ -503,11 +503,11 @@
 
   void test() {
     a = 0; // \
-      // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
+      // expected-warning{{writing variable 'a' requires holding mutex 'mu' exclusively}}
     b = a; // \
-      // expected-warning {{reading variable 'a' requires locking 'mu'}}
+      // expected-warning {{reading variable 'a' requires holding mutex 'mu'}}
     c = 0; // \
-      // expected-warning {{writing variable 'c' requires locking 'mu' exclusively}}
+      // expected-warning {{writing variable 'c' requires holding mutex 'mu' exclusively}}
   }
 
   int c __attribute__((guarded_by(mu)));
@@ -549,7 +549,7 @@
   LateFoo fooB;
   fooA.mu.Lock();
   fooB.a = 5; // \
-    // expected-warning{{writing variable 'a' requires locking 'fooB.mu' exclusively}} \
+    // expected-warning{{writing variable 'a' requires holding mutex 'fooB.mu' exclusively}} \
     // expected-note{{found near match 'fooA.mu'}}
   fooA.mu.Unlock();
 }
@@ -560,7 +560,7 @@
   b1.mu1_.Lock();
   int res = b1.a_ + b3->b_;
   b3->b_ = *b1.q; // \
-    // expected-warning{{reading the value pointed to by 'q' requires locking 'b1.mu'}}
+    // expected-warning{{reading the value pointed to by 'q' requires holding mutex 'b1.mu'}}
   b1.mu1_.Unlock();
   b1.b_ = res;
   mu.Unlock();
@@ -570,7 +570,7 @@
   LateBar BarA;
   BarA.FooPointer->mu.Lock();
   BarA.Foo.a = 2; // \
-    // expected-warning{{writing variable 'a' requires locking 'BarA.Foo.mu' exclusively}} \
+    // expected-warning{{writing variable 'a' requires holding mutex 'BarA.Foo.mu' exclusively}} \
     // expected-note{{found near match 'BarA.FooPointer->mu'}}
   BarA.FooPointer->mu.Unlock();
 }
@@ -579,7 +579,7 @@
   LateBar BarA;
   BarA.Foo.mu.Lock();
   BarA.FooPointer->a = 2; // \
-    // expected-warning{{writing variable 'a' requires locking 'BarA.FooPointer->mu' exclusively}} \
+    // expected-warning{{writing variable 'a' requires holding mutex 'BarA.FooPointer->mu' exclusively}} \
     // expected-note{{found near match 'BarA.Foo.mu'}}
   BarA.Foo.mu.Unlock();
 }
@@ -588,7 +588,7 @@
   LateBar BarA;
   BarA.Foo.mu.Lock();
   BarA.Foo2.a = 2; // \
-    // expected-warning{{writing variable 'a' requires locking 'BarA.Foo2.mu' exclusively}} \
+    // expected-warning{{writing variable 'a' requires holding mutex 'BarA.Foo2.mu' exclusively}} \
     // expected-note{{found near match 'BarA.Foo.mu'}}
   BarA.Foo.mu.Unlock();
 }
@@ -608,11 +608,11 @@
 
 void shared_fun_1() {
   sls_mu.ReaderLock(); // \
-    // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
+    // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
   do {
     sls_mu.Unlock();
     sls_mu.Lock();  // \
-      // expected-note {{the other lock of mutex 'sls_mu' is here}}
+      // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
   } while (getBool());
   sls_mu.Unlock();
 }
@@ -638,20 +638,20 @@
 void shared_fun_8() {
   if (getBool())
     sls_mu.Lock(); // \
-      // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
+      // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
   else
     sls_mu.ReaderLock(); // \
-      // expected-note {{the other lock of mutex 'sls_mu' is here}}
+      // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
   sls_mu.Unlock();
 }
 
 void shared_bad_0() {
   sls_mu.Lock();  // \
-    // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
+    // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
   do {
     sls_mu.Unlock();
     sls_mu.ReaderLock();  // \
-      // expected-note {{the other lock of mutex 'sls_mu' is here}}
+      // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
   } while (getBool());
   sls_mu.Unlock();
 }
@@ -659,10 +659,10 @@
 void shared_bad_1() {
   if (getBool())
     sls_mu.Lock(); // \
-      // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
+      // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
   else
     sls_mu.ReaderLock(); // \
-      // expected-note {{the other lock of mutex 'sls_mu' is here}}
+      // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
   *pgb_var = 1;
   sls_mu.Unlock();
 }
@@ -670,10 +670,10 @@
 void shared_bad_2() {
   if (getBool())
     sls_mu.ReaderLock(); // \
-      // expected-warning {{mutex 'sls_mu' is locked exclusively and shared in the same scope}}
+      // expected-warning {{mutex 'sls_mu' is acquired exclusively and shared in the same scope}}
   else
     sls_mu.Lock(); // \
-      // expected-note {{the other lock of mutex 'sls_mu' is here}}
+      // expected-note {{the other acquisition of mutex 'sls_mu' is here}}
   *pgb_var = 1;
   sls_mu.Unlock();
 }
@@ -762,49 +762,49 @@
 
 void es_bad_0() {
   Bar.aa_elr_fun(); // \
-    // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}}
+    // expected-warning {{calling function 'aa_elr_fun' requires holding mutex 'aa_mu' exclusively}}
 }
 
 void es_bad_1() {
   aa_mu.ReaderLock();
   Bar.aa_elr_fun(); // \
-    // expected-warning {{calling function 'aa_elr_fun' requires exclusive lock on 'aa_mu'}}
+    // expected-warning {{calling function 'aa_elr_fun' requires holding mutex 'aa_mu' exclusively}}
   aa_mu.Unlock();
 }
 
 void es_bad_2() {
   Bar.aa_elr_fun_s(); // \
-    // expected-warning {{calling function 'aa_elr_fun_s' requires shared lock on 'aa_mu'}}
+    // expected-warning {{calling function 'aa_elr_fun_s' requires holding mutex 'aa_mu'}}
 }
 
 void es_bad_3() {
   MyLRFoo.test(); // \
-    // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}}
+    // expected-warning {{calling function 'test' requires holding mutex 'sls_mu' exclusively}}
 }
 
 void es_bad_4() {
   MyLRFoo.testShared(); // \
-    // expected-warning {{calling function 'testShared' requires shared lock on 'sls_mu2'}}
+    // expected-warning {{calling function 'testShared' requires holding mutex 'sls_mu2'}}
 }
 
 void es_bad_5() {
   sls_mu.ReaderLock();
   MyLRFoo.test(); // \
-    // expected-warning {{calling function 'test' requires exclusive lock on 'sls_mu'}}
+    // expected-warning {{calling function 'test' requires holding mutex 'sls_mu' exclusively}}
   sls_mu.Unlock();
 }
 
 void es_bad_6() {
   sls_mu.Lock();
   Bar.le_fun(); // \
-    // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is locked}}
+    // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is held}}
   sls_mu.Unlock();
 }
 
 void es_bad_7() {
   sls_mu.ReaderLock();
   Bar.le_fun(); // \
-    // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is locked}}
+    // expected-warning {{cannot call function 'le_fun' while mutex 'sls_mu' is held}}
   sls_mu.Unlock();
 }
 
@@ -1209,7 +1209,7 @@
 {
   int x;
   mu_.Lock();
-  x = foo(); // expected-warning {{calling function 'foo' requires exclusive lock on 'mu2'}}
+  x = foo(); // expected-warning {{calling function 'foo' requires holding mutex 'mu2' exclusively}}
   a_ = x + 1;
   mu_.Unlock();
   if (x > 5) {
@@ -1223,13 +1223,13 @@
 {
   Foo f1, *f2;
   f1.mu_.Lock();
-  f1.bar(); // expected-warning {{cannot call function 'bar' while mutex 'f1.mu_' is locked}}
+  f1.bar(); // expected-warning {{cannot call function 'bar' while mutex 'f1.mu_' is held}}
   mu2.Lock();
   f1.foo();
   mu2.Unlock();
   f1.mu_.Unlock();
   f2->mu_.Lock();
-  f2->bar(); // expected-warning {{cannot call function 'bar' while mutex 'f2->mu_' is locked}}
+  f2->bar(); // expected-warning {{cannot call function 'bar' while mutex 'f2->mu_' is held}}
   f2->mu_.Unlock();
   mu2.Lock();
   w = 2;
@@ -1258,7 +1258,7 @@
   b1->MyLock();
   b1->a_ = 5;
   b2->a_ = 3; // \
-    // expected-warning {{writing variable 'a_' requires locking 'b2->mu1_' exclusively}} \
+    // expected-warning {{writing variable 'a_' requires holding mutex 'b2->mu1_' exclusively}} \
     // expected-note {{found near match 'b1->mu1_'}}
   b2->MyLock();
   b2->MyUnlock();
@@ -1288,18 +1288,18 @@
 {
   int x;
   b3->mu1_.Lock();
-  res = b1.a_ + b3->b_; // expected-warning {{reading variable 'a_' requires locking 'b1.mu1_'}} \
-    // expected-warning {{writing variable 'res' requires locking 'mu' exclusively}} \
+  res = b1.a_ + b3->b_; // expected-warning {{reading variable 'a_' requires holding mutex 'b1.mu1_'}} \
+    // expected-warning {{writing variable 'res' requires holding mutex 'mu' exclusively}} \
     // expected-note {{found near match 'b3->mu1_'}}
-  *p = i; // expected-warning {{reading variable 'p' requires locking 'mu'}} \
-    // expected-warning {{writing the value pointed to by 'p' requires locking 'mu' exclusively}}
-  b1.a_ = res + b3->b_; // expected-warning {{reading variable 'res' requires locking 'mu'}} \
-    // expected-warning {{writing variable 'a_' requires locking 'b1.mu1_' exclusively}} \
+  *p = i; // expected-warning {{reading variable 'p' requires holding mutex 'mu'}} \
+    // expected-warning {{writing the value pointed to by 'p' requires holding mutex 'mu' exclusively}}
+  b1.a_ = res + b3->b_; // expected-warning {{reading variable 'res' requires holding mutex 'mu'}} \
+    // expected-warning {{writing variable 'a_' requires holding mutex 'b1.mu1_' exclusively}} \
     // expected-note {{found near match 'b3->mu1_'}}
-  b3->b_ = *b1.q; // expected-warning {{reading the value pointed to by 'q' requires locking 'mu'}}
+  b3->b_ = *b1.q; // expected-warning {{reading the value pointed to by 'q' requires holding mutex 'mu'}}
   b3->mu1_.Unlock();
-  b1.b_ = res; // expected-warning {{reading variable 'res' requires locking 'mu'}}
-  x = res; // expected-warning {{reading variable 'res' requires locking 'mu'}}
+  b1.b_ = res; // expected-warning {{reading variable 'res' requires holding mutex 'mu'}}
+  x = res; // expected-warning {{reading variable 'res' requires holding mutex 'mu'}}
   return x;
 }
 } // end namespace thread_annot_lock_21
@@ -1321,10 +1321,10 @@
      child->Func(new_foo); // There shouldn't be any warning here as the
                            // acquired lock is not in child.
      child->bar(7); // \
-       // expected-warning {{calling function 'bar' requires exclusive lock on 'child->lock_'}} \
+       // expected-warning {{calling function 'bar' requires holding mutex 'child->lock_' exclusively}} \
        // expected-note {{found near match 'lock_'}}
      child->a_ = 5; // \
-       // expected-warning {{writing variable 'a_' requires locking 'child->lock_' exclusively}} \
+       // expected-warning {{writing variable 'a_' requires holding mutex 'child->lock_' exclusively}} \
        // expected-note {{found near match 'lock_'}}
      lock_.Unlock();
   }
@@ -1362,7 +1362,7 @@
   lock_.Lock();
 
   child->lock_.Lock();
-  child->Func(new_foo); // expected-warning {{cannot call function 'Func' while mutex 'child->lock_' is locked}}
+  child->Func(new_foo); // expected-warning {{cannot call function 'Func' while mutex 'child->lock_' is held}}
   child->bar(7);
   child->a_ = 5;
   child->lock_.Unlock();
@@ -1401,8 +1401,8 @@
  public:
   void f1() EXCLUSIVE_LOCKS_REQUIRED(mu2) EXCLUSIVE_LOCKS_REQUIRED(mu1) {
     x = 5;
-    f2(); // expected-warning {{cannot call function 'f2' while mutex 'mu1' is locked}} \
-      // expected-warning {{cannot call function 'f2' while mutex 'mu2' is locked}}
+    f2(); // expected-warning {{cannot call function 'f2' while mutex 'mu1' is held}} \
+      // expected-warning {{cannot call function 'f2' while mutex 'mu2' is held}}
   }
 };
 
@@ -1410,8 +1410,8 @@
 
 void func()
 {
-  foo->f1(); // expected-warning {{calling function 'f1' requires exclusive lock on 'foo->mu2'}} \
-             // expected-warning {{calling function 'f1' requires exclusive lock on 'foo->mu1'}}
+  foo->f1(); // expected-warning {{calling function 'f1' requires holding mutex 'foo->mu2' exclusively}} \
+             // expected-warning {{calling function 'f1' requires holding mutex 'foo->mu1' exclusively}}
 }
 } // end namespace thread_annot_lock_42
 
@@ -1434,14 +1434,14 @@
   Child *c;
   Base *b = c;
 
-  b->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'b->mu_'}}
+  b->func1(); // expected-warning {{calling function 'func1' requires holding mutex 'b->mu_' exclusively}}
   b->mu_.Lock();
-  b->func2(); // expected-warning {{cannot call function 'func2' while mutex 'b->mu_' is locked}}
+  b->func2(); // expected-warning {{cannot call function 'func2' while mutex 'b->mu_' is held}}
   b->mu_.Unlock();
 
-  c->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'c->mu_'}}
+  c->func1(); // expected-warning {{calling function 'func1' requires holding mutex 'c->mu_' exclusively}}
   c->mu_.Lock();
-  c->func2(); // expected-warning {{cannot call function 'func2' while mutex 'c->mu_' is locked}}
+  c->func2(); // expected-warning {{cannot call function 'func2' while mutex 'c->mu_' is held}}
   c->mu_.Unlock();
 }
 } // end namespace thread_annot_lock_46
@@ -1468,10 +1468,10 @@
 void main()
 {
   Foo a;
-  a.method1(1); // expected-warning {{calling function 'method1' requires shared lock on 'a.mu1'}} \
-    // expected-warning {{calling function 'method1' requires shared lock on 'mu'}} \
-    // expected-warning {{calling function 'method1' requires shared lock on 'a.mu2'}} \
-    // expected-warning {{calling function 'method1' requires shared lock on 'mu3'}}
+  a.method1(1); // expected-warning {{calling function 'method1' requires holding mutex 'a.mu1'}} \
+    // expected-warning {{calling function 'method1' requires holding mutex 'mu'}} \
+    // expected-warning {{calling function 'method1' requires holding mutex 'a.mu2'}} \
+    // expected-warning {{calling function 'method1' requires holding mutex 'mu3'}}
 }
 } // end namespace thread_annot_lock_67_modified
 
@@ -1516,14 +1516,14 @@
       DataLocker dlr;
       dlr.lockData(d1);   // expected-note {{mutex acquired here}}
       dlr.unlockData(d2); // \
-        // expected-warning {{unlocking 'd2->mu' that was not locked}}
-    } // expected-warning {{mutex 'd1->mu' is still locked at the end of function}}
+        // expected-warning {{releasing mutex 'd2->mu' that was not held}}
+    } // expected-warning {{mutex 'd1->mu' is still held at the end of function}}
 
     void bar4(MyData* d1, MyData* d2) {
       DataLocker dlr;
       dlr.lockData(d1);
       foo(d2); // \
-        // expected-warning {{calling function 'foo' requires exclusive lock on 'd2->mu'}} \
+        // expected-warning {{calling function 'foo' requires holding mutex 'd2->mu' exclusively}} \
         // expected-note {{found near match 'd1->mu'}}
       dlr.unlockData(d1);
     }
@@ -1566,8 +1566,8 @@
   template<typename U>
   struct IndirectLock {
     int DoNaughtyThings(T *t) {
-      u->n = 0; // expected-warning {{reading variable 'u' requires locking 'm'}}
-      return t->s->n; // expected-warning {{reading variable 's' requires locking 't->m'}}
+      u->n = 0; // expected-warning {{reading variable 'u' requires holding mutex 'm'}}
+      return t->s->n; // expected-warning {{reading variable 's' requires holding mutex 't->m'}}
     }
   };
 
@@ -1583,7 +1583,7 @@
   template<typename U> struct W {
     V v;
     void f(U u) {
-      v.p->f(u); // expected-warning {{reading variable 'p' requires locking 'v.m'}}
+      v.p->f(u); // expected-warning {{reading variable 'p' requires holding mutex 'v.m'}}
     }
   };
   template struct W<int>; // expected-note {{here}}
@@ -1620,7 +1620,7 @@
   void foo3() {
     MutexLock mulock_a(&mu1);
     MutexLock mulock_b(&mu1); // \
-      // expected-warning {{locking 'mu1' that is already locked}}
+      // expected-warning {{acquiring mutex 'mu1' that is already held}}
   }
 
   void foo4() {
@@ -1646,7 +1646,7 @@
 void foo() EXCLUSIVE_LOCKS_REQUIRED(fooObj.mu_);
 
 void bar() {
-  foo();  // expected-warning {{calling function 'foo' requires exclusive lock on 'fooObj.mu_'}}
+  foo();  // expected-warning {{calling function 'foo' requires holding mutex 'fooObj.mu_' exclusively}}
   fooObj.mu_.Lock();
   foo();
   fooObj.mu_.Unlock();
@@ -1722,7 +1722,7 @@
     if (cond)
       b = true;
     if (b) {    // b should be unknown at this point, because of the join point
-      a = 8;    // expected-warning {{writing variable 'a' requires locking 'mu' exclusively}}
+      a = 8;    // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
     }
     if (b2) {   // b2 should be known at this point.
       a = 8;
@@ -1748,7 +1748,7 @@
 
     while (cond) {
       if (b) {   // b should be uknown at this point b/c of the loop
-        a = 10;  // expected-warning {{writing variable 'a' requires locking 'mu' exclusively}}
+        a = 10;  // expected-warning {{writing variable 'a' requires holding mutex 'mu' exclusively}}
       }
       b = !b;
     }
@@ -1876,7 +1876,7 @@
 
   f1.mu_.Unlock();
   bt.barTD(&f1);  // \
-    // expected-warning {{calling function 'barTD' requires exclusive lock on 'f1.mu_'}} \
+    // expected-warning {{calling function 'barTD' requires holding mutex 'f1.mu_' exclusively}} \
     // expected-note {{found near match 'bt.fooBase.mu_'}}
 
   bt.fooBase.mu_.Unlock();
@@ -1885,7 +1885,7 @@
 
   Cell<int> cell;
   cell.data = 0; // \
-    // expected-warning {{writing variable 'data' requires locking 'cell.mu_' exclusively}}
+    // expected-warning {{writing variable 'data' requires holding mutex 'cell.mu_' exclusively}}
   cell.foo();
   cell.mu_.Lock();
   cell.fooEx();
@@ -1954,7 +1954,7 @@
 void test() {
   Foo myfoo;
   myfoo.foo1(&myfoo);  // \
-    // expected-warning {{calling function 'foo1' requires exclusive lock on 'myfoo.mu_'}}
+    // expected-warning {{calling function 'foo1' requires holding mutex 'myfoo.mu_' exclusively}}
   myfoo.mu_.Lock();
   myfoo.foo1(&myfoo);
   myfoo.mu_.Unlock();
@@ -1980,7 +1980,7 @@
       if (bar()) {
         // ...
         if (foo())
-          continue; // expected-warning {{expecting mutex 'm' to be locked at start of each loop}}
+          continue; // expected-warning {{expecting mutex 'm' to be held at start of each loop}}
         //...
       }
       // ...
@@ -2069,21 +2069,21 @@
   Foo myFoo;
 
   myFoo.foo2();        // \
-    // expected-warning {{calling function 'foo2' requires exclusive lock on 'myFoo.mu_'}}
+    // expected-warning {{calling function 'foo2' requires holding mutex 'myFoo.mu_' exclusively}}
   myFoo.foo3(&myFoo);  // \
-    // expected-warning {{calling function 'foo3' requires exclusive lock on 'myFoo.mu_'}}
+    // expected-warning {{calling function 'foo3' requires holding mutex 'myFoo.mu_' exclusively}}
   myFoo.fooT1(dummy);  // \
-    // expected-warning {{calling function 'fooT1' requires exclusive lock on 'myFoo.mu_'}}
+    // expected-warning {{calling function 'fooT1' requires holding mutex 'myFoo.mu_' exclusively}}
 
   myFoo.fooT2(dummy);  // \
-    // expected-warning {{calling function 'fooT2' requires exclusive lock on 'myFoo.mu_'}}
+    // expected-warning {{calling function 'fooT2' requires holding mutex 'myFoo.mu_' exclusively}}
 
   fooF1(&myFoo);  // \
-    // expected-warning {{calling function 'fooF1' requires exclusive lock on 'myFoo.mu_'}}
+    // expected-warning {{calling function 'fooF1' requires holding mutex 'myFoo.mu_' exclusively}}
   fooF2(&myFoo);  // \
-    // expected-warning {{calling function 'fooF2' requires exclusive lock on 'myFoo.mu_'}}
+    // expected-warning {{calling function 'fooF2' requires holding mutex 'myFoo.mu_' exclusively}}
   fooF3(&myFoo);  // \
-    // expected-warning {{calling function 'fooF3' requires exclusive lock on 'myFoo.mu_'}}
+    // expected-warning {{calling function 'fooF3' requires holding mutex 'myFoo.mu_' exclusively}}
 
   myFoo.mu_.Lock();
   myFoo.foo2();
@@ -2099,7 +2099,7 @@
 
   FooT<int> myFooT;
   myFooT.foo();  // \
-    // expected-warning {{calling function 'foo' requires exclusive lock on 'myFooT.mu_'}}
+    // expected-warning {{calling function 'foo' requires holding mutex 'myFooT.mu_' exclusively}}
 }
 
 } // end namespace FunctionDefinitionTest
@@ -2127,7 +2127,7 @@
 
   void test() {
     foo = 2;  // \
-      // expected-warning {{writing variable 'foo' requires locking 'this' exclusively}}
+      // expected-warning {{writing variable 'foo' requires holding mutex 'this' exclusively}}
   }
 };
 
@@ -2192,11 +2192,11 @@
 
   void foo() {
     a = 0; // \
-      // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+      // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
     b = 0; // \
-      // expected-warning {{writing variable 'b' requires locking 'mu_' exclusively}}
+      // expected-warning {{writing variable 'b' requires holding mutex 'mu_' exclusively}}
     c = 0; // \
-      // expected-warning {{writing variable 'c' requires locking 'mu_' exclusively}}
+      // expected-warning {{writing variable 'c' requires holding mutex 'mu_' exclusively}}
   }
 
 private:
@@ -2283,31 +2283,31 @@
 
   bar.getFoo().mu_.Lock();
   bar.getFooey().a = 0; // \
-    // expected-warning {{writing variable 'a' requires locking 'bar.getFooey().mu_' exclusively}} \
+    // expected-warning {{writing variable 'a' requires holding mutex 'bar.getFooey().mu_' exclusively}} \
     // expected-note {{found near match 'bar.getFoo().mu_'}}
   bar.getFoo().mu_.Unlock();
 
   bar.getFoo2(a).mu_.Lock();
   bar.getFoo2(b).a = 0; // \
-    // expected-warning {{writing variable 'a' requires locking 'bar.getFoo2(b).mu_' exclusively}} \
+    // expected-warning {{writing variable 'a' requires holding mutex 'bar.getFoo2(b).mu_' exclusively}} \
     // expected-note {{found near match 'bar.getFoo2(a).mu_'}}
   bar.getFoo2(a).mu_.Unlock();
 
   bar.getFoo3(a, b).mu_.Lock();
   bar.getFoo3(a, c).a = 0;  // \
-    // expected-warning {{writing variable 'a' requires locking 'bar.getFoo3(a,c).mu_' exclusively}} \
+    // expected-warning {{writing variable 'a' requires holding mutex 'bar.getFoo3(a,c).mu_' exclusively}} \
     // expected-note {{'bar.getFoo3(a,b).mu_'}}
   bar.getFoo3(a, b).mu_.Unlock();
 
   getBarFoo(bar, a).mu_.Lock();
   getBarFoo(bar, b).a = 0;  // \
-    // expected-warning {{writing variable 'a' requires locking 'getBarFoo(bar,b).mu_' exclusively}} \
+    // expected-warning {{writing variable 'a' requires holding mutex 'getBarFoo(bar,b).mu_' exclusively}} \
     // expected-note {{'getBarFoo(bar,a).mu_'}}
   getBarFoo(bar, a).mu_.Unlock();
 
   (a > 0 ? fooArray[1] : fooArray[b]).mu_.Lock();
   (a > 0 ? fooArray[b] : fooArray[c]).a = 0; // \
-    // expected-warning {{writing variable 'a' requires locking '((a#_)#_#fooArray[b]).mu_' exclusively}} \
+    // expected-warning {{writing variable 'a' requires holding mutex '((a#_)#_#fooArray[b]).mu_' exclusively}} \
     // expected-note {{'((a#_)#_#fooArray[_]).mu_'}}
   (a > 0 ? fooArray[1] : fooArray[b]).mu_.Unlock();
 }
@@ -2356,19 +2356,19 @@
 
 // Calls getMu() directly to lock and unlock
 void test1(Foo* f1, Foo* f2) {
-  f1->a = 0;       // expected-warning {{writing variable 'a' requires locking 'f1->mu_' exclusively}}
-  f1->foo();       // expected-warning {{calling function 'foo' requires exclusive lock on 'f1->mu_'}}
+  f1->a = 0;       // expected-warning {{writing variable 'a' requires holding mutex 'f1->mu_' exclusively}}
+  f1->foo();       // expected-warning {{calling function 'foo' requires holding mutex 'f1->mu_' exclusively}}
 
-  f1->foo2(f2);    // expected-warning {{calling function 'foo2' requires exclusive lock on 'f1->mu_'}} \
-                   // expected-warning {{calling function 'foo2' requires exclusive lock on 'f2->mu_'}}
-  Foo::sfoo(f1);   // expected-warning {{calling function 'sfoo' requires exclusive lock on 'f1->mu_'}}
+  f1->foo2(f2);    // expected-warning {{calling function 'foo2' requires holding mutex 'f1->mu_' exclusively}} \
+                   // expected-warning {{calling function 'foo2' requires holding mutex 'f2->mu_' exclusively}}
+  Foo::sfoo(f1);   // expected-warning {{calling function 'sfoo' requires holding mutex 'f1->mu_' exclusively}}
 
   f1->getMu()->Lock();
 
   f1->a = 0;
   f1->foo();
   f1->foo2(f2); // \
-    // expected-warning {{calling function 'foo2' requires exclusive lock on 'f2->mu_'}} \
+    // expected-warning {{calling function 'foo2' requires holding mutex 'f2->mu_' exclusively}} \
     // expected-note {{found near match 'f1->mu_'}}
 
   Foo::getMu(f2)->Lock();
@@ -2398,19 +2398,19 @@
 // Use getMu() within other attributes.
 // This requires at lest levels of substitution, more in the case of
 void test2(Bar* b1, Bar* b2) {
-  b1->b = 0;       // expected-warning {{writing variable 'b' requires locking 'b1->mu_' exclusively}}
-  b1->bar();       // expected-warning {{calling function 'bar' requires exclusive lock on 'b1->mu_'}}
-  b1->bar2(b2);    // expected-warning {{calling function 'bar2' requires exclusive lock on 'b1->mu_'}} \
-                   // expected-warning {{calling function 'bar2' requires exclusive lock on 'b2->mu_'}}
-  Bar::sbar(b1);   // expected-warning {{calling function 'sbar' requires exclusive lock on 'b1->mu_'}}
-  Bar::sbar2(b1);  // expected-warning {{calling function 'sbar2' requires exclusive lock on 'b1->mu_'}}
+  b1->b = 0;       // expected-warning {{writing variable 'b' requires holding mutex 'b1->mu_' exclusively}}
+  b1->bar();       // expected-warning {{calling function 'bar' requires holding mutex 'b1->mu_' exclusively}}
+  b1->bar2(b2);    // expected-warning {{calling function 'bar2' requires holding mutex 'b1->mu_' exclusively}} \
+                   // expected-warning {{calling function 'bar2' requires holding mutex 'b2->mu_' exclusively}}
+  Bar::sbar(b1);   // expected-warning {{calling function 'sbar' requires holding mutex 'b1->mu_' exclusively}}
+  Bar::sbar2(b1);  // expected-warning {{calling function 'sbar2' requires holding mutex 'b1->mu_' exclusively}}
 
   b1->getMu()->Lock();
 
   b1->b = 0;
   b1->bar();
   b1->bar2(b2);  // \
-    // expected-warning {{calling function 'bar2' requires exclusive lock on 'b2->mu_'}} \
+    // expected-warning {{calling function 'bar2' requires holding mutex 'b2->mu_' exclusively}} \
     // // expected-note {{found near match 'b1->mu_'}}
 
   b2->getMu()->Lock();
@@ -2476,13 +2476,13 @@
   ReleasableMutexLock rlock(&mu_);
   a = 0;
   rlock.Release();
-  a = 1;  // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+  a = 1;  // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
 }
 
 void Foo::test4() {
   ReleasableMutexLock rlock(&mu_);
   rlock.Release();
-  rlock.Release();  // expected-warning {{unlocking 'mu_' that was not locked}}
+  rlock.Release();  // expected-warning {{releasing mutex 'mu_' that was not held}}
 }
 
 void Foo::test5() {
@@ -2491,7 +2491,7 @@
     rlock.Release();
   }
   // no warning on join point for managed lock.
-  rlock.Release();  // expected-warning {{unlocking 'mu_' that was not locked}}
+  rlock.Release();  // expected-warning {{releasing mutex 'mu_' that was not held}}
 }
 
 
@@ -2560,12 +2560,12 @@
 
   void foo1() EXCLUSIVE_LOCKS_REQUIRED(mutex_) {  // expected-note {{mutex acquired here}}
     mutex_.Unlock();
-  }  // expected-warning {{expecting mutex 'mutex_' to be locked at the end of function}}
+  }  // expected-warning {{expecting mutex 'mutex_' to be held at the end of function}}
 
 
   void foo2() SHARED_LOCKS_REQUIRED(mutex_) {   // expected-note {{mutex acquired here}}
     mutex_.Unlock();
-  }  // expected-warning {{expecting mutex 'mutex_' to be locked at the end of function}}
+  }  // expected-warning {{expecting mutex 'mutex_' to be held at the end of function}}
 };
 
 } // end namespace UnlockBug
@@ -2599,7 +2599,7 @@
 
   void test2() {
     WTF_ScopedLockable wtf(&mu_);  // expected-note {{mutex acquired here}}
-  }  // expected-warning {{mutex 'mu_' is still locked at the end of function}}
+  }  // expected-warning {{mutex 'mu_' is still held at the end of function}}
 
   void test3() {
     if (c) {
@@ -2622,7 +2622,7 @@
     if (c) {
       WTF_ScopedLockable wtf(&mu_);  // expected-note {{mutex acquired here}}
     }
-  } // expected-warning {{mutex 'mu_' is not locked on every path through here}}
+  } // expected-warning {{mutex 'mu_' is not held on every path through here}}
 
   void test6() {
     if (c) {
@@ -2631,7 +2631,7 @@
     else {
       WTF_ScopedLockable wtf(&mu_);  // expected-note {{mutex acquired here}}
     }
-  } // expected-warning {{mutex 'mu_' is not locked on every path through here}}
+  } // expected-warning {{mutex 'mu_' is not held on every path through here}}
 };
 
 
@@ -2655,7 +2655,7 @@
     ReaderMutexLock lock(getMutexPtr().get());
     int b = a;
   }
-  int b = a;  // expected-warning {{reading variable 'a' requires locking 'getMutexPtr()'}}
+  int b = a;  // expected-warning {{reading variable 'a' requires holding mutex 'getMutexPtr()'}}
 }
 
 } // end namespace TemporaryCleanupExpr
@@ -2686,9 +2686,9 @@
 };
 
 void Foo::test0() {
-  a = 0;  // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
-  b = 0;  // expected-warning {{writing variable 'b' requires locking 'mu_' exclusively}}
-  c = 0;  // expected-warning {{writing variable 'c' requires locking 'mu_' exclusively}}
+  a = 0;  // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
+  b = 0;  // expected-warning {{writing variable 'b' requires holding mutex 'mu_' exclusively}}
+  c = 0;  // expected-warning {{writing variable 'c' requires holding mutex 'mu_' exclusively}}
 }
 
 void Foo::test1() {
@@ -2772,10 +2772,10 @@
 
 void Foo::test8() {
   mu_->Lock();
-  mu_.get()->Lock();    // expected-warning {{locking 'mu_' that is already locked}}
-  (*mu_).Lock();        // expected-warning {{locking 'mu_' that is already locked}}
+  mu_.get()->Lock();    // expected-warning {{acquiring mutex 'mu_' that is already held}}
+  (*mu_).Lock();        // expected-warning {{acquiring mutex 'mu_' that is already held}}
   mu_.get()->Unlock();
-  Unlock();             // expected-warning {{unlocking 'mu_' that was not locked}}
+  Unlock();             // expected-warning {{releasing mutex 'mu_' that was not held}}
 }
 
 
@@ -2790,9 +2790,9 @@
 
 
 void Bar::test0() {
-  foo->a = 0;         // expected-warning {{writing variable 'a' requires locking 'foo->mu_' exclusively}}
-  (*foo).b = 0;       // expected-warning {{writing variable 'b' requires locking 'foo->mu_' exclusively}}
-  foo.get()->c = 0;   // expected-warning {{writing variable 'c' requires locking 'foo->mu_' exclusively}}
+  foo->a = 0;         // expected-warning {{writing variable 'a' requires holding mutex 'foo->mu_' exclusively}}
+  (*foo).b = 0;       // expected-warning {{writing variable 'b' requires holding mutex 'foo->mu_' exclusively}}
+  foo.get()->c = 0;   // expected-warning {{writing variable 'c' requires holding mutex 'foo->mu_' exclusively}}
 }
 
 
@@ -2906,9 +2906,9 @@
   foo.unlock();
 
   foo.lock();
-  foo.lock();     // expected-warning {{locking 'foo' that is already locked}}
+  foo.lock();     // expected-warning {{acquiring mutex 'foo' that is already held}}
   foo.unlock();
-  foo.unlock();   // expected-warning {{unlocking 'foo' that was not locked}}
+  foo.unlock();   // expected-warning {{releasing mutex 'foo' that was not held}}
 }
 
 
@@ -2919,10 +2919,10 @@
   foo.unlock1();
 
   foo.lock1();
-  foo.lock1();    // expected-warning {{locking 'foo.mu1_' that is already locked}}
+  foo.lock1();    // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}}
   foo.a = 0;
   foo.unlock1();
-  foo.unlock1();  // expected-warning {{unlocking 'foo.mu1_' that was not locked}}
+  foo.unlock1();  // expected-warning {{releasing mutex 'foo.mu1_' that was not held}}
 }
 
 
@@ -2933,10 +2933,10 @@
   foo.unlock1();
 
   foo.slock1();
-  foo.slock1();    // expected-warning {{locking 'foo.mu1_' that is already locked}}
+  foo.slock1();    // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}}
   int d2 = foo.a;
   foo.unlock1();
-  foo.unlock1();   // expected-warning {{unlocking 'foo.mu1_' that was not locked}}
+  foo.unlock1();   // expected-warning {{releasing mutex 'foo.mu1_' that was not held}}
   return d1 + d2;
 }
 
@@ -2951,17 +2951,17 @@
 
   foo.lock3();
   foo.lock3(); // \
-    // expected-warning {{locking 'foo.mu1_' that is already locked}} \
-    // expected-warning {{locking 'foo.mu2_' that is already locked}} \
-    // expected-warning {{locking 'foo.mu3_' that is already locked}}
+    // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}} \
+    // expected-warning {{acquiring mutex 'foo.mu2_' that is already held}} \
+    // expected-warning {{acquiring mutex 'foo.mu3_' that is already held}}
   foo.a = 0;
   foo.b = 0;
   foo.c = 0;
   foo.unlock3();
   foo.unlock3(); // \
-    // expected-warning {{unlocking 'foo.mu1_' that was not locked}} \
-    // expected-warning {{unlocking 'foo.mu2_' that was not locked}} \
-    // expected-warning {{unlocking 'foo.mu3_' that was not locked}}
+    // expected-warning {{releasing mutex 'foo.mu1_' that was not held}} \
+    // expected-warning {{releasing mutex 'foo.mu2_' that was not held}} \
+    // expected-warning {{releasing mutex 'foo.mu3_' that was not held}}
 }
 
 
@@ -2975,17 +2975,17 @@
 
   foo.locklots();
   foo.locklots(); // \
-    // expected-warning {{locking 'foo.mu1_' that is already locked}} \
-    // expected-warning {{locking 'foo.mu2_' that is already locked}} \
-    // expected-warning {{locking 'foo.mu3_' that is already locked}}
+    // expected-warning {{acquiring mutex 'foo.mu1_' that is already held}} \
+    // expected-warning {{acquiring mutex 'foo.mu2_' that is already held}} \
+    // expected-warning {{acquiring mutex 'foo.mu3_' that is already held}}
   foo.a = 0;
   foo.b = 0;
   foo.c = 0;
   foo.unlocklots();
   foo.unlocklots(); // \
-    // expected-warning {{unlocking 'foo.mu1_' that was not locked}} \
-    // expected-warning {{unlocking 'foo.mu2_' that was not locked}} \
-    // expected-warning {{unlocking 'foo.mu3_' that was not locked}}
+    // expected-warning {{releasing mutex 'foo.mu1_' that was not held}} \
+    // expected-warning {{releasing mutex 'foo.mu2_' that was not held}} \
+    // expected-warning {{releasing mutex 'foo.mu3_' that was not held}}
 }
 
 }  // end namespace DuplicateAttributeTest
@@ -3010,7 +3010,7 @@
 
 void Foo::test1() {
   if (tryLockMutexP() == 0) {
-    a = 0;  // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+    a = 0;  // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
     return;
   }
   a = 0;
@@ -3032,14 +3032,14 @@
   }
 
   if (tryLockMutexI() == 0) {
-    a = 0;   // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+    a = 0;   // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
     return;
   }
   a = 0;
   unlock();
 
   if (0 == tryLockMutexI()) {
-    a = 0;   // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+    a = 0;   // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
     return;
   }
   a = 0;
@@ -3051,7 +3051,7 @@
   }
 
   if (mu_.TryLock() == false) {
-    a = 0;   // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+    a = 0;   // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
     return;
   }
   a = 0;
@@ -3062,12 +3062,12 @@
     unlock();
   }
   else {
-    a = 0;  // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+    a = 0;  // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
   }
 
 #if __has_feature(cxx_nullptr)
   if (tryLockMutexP() == nullptr) {
-    a = 0;  // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+    a = 0;  // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
     return;
   }
   a = 0;
@@ -3103,26 +3103,26 @@
   Graph g2;
   Node n1;
 
-  n1.a = 0;   // expected-warning {{writing variable 'a' requires locking '&ExistentialPatternMatching::Graph::mu_' exclusively}}
-  n1.foo();   // expected-warning {{calling function 'foo' requires exclusive lock on '&ExistentialPatternMatching::Graph::mu_'}}
+  n1.a = 0;   // expected-warning {{writing variable 'a' requires holding mutex '&ExistentialPatternMatching::Graph::mu_' exclusively}}
+  n1.foo();   // expected-warning {{calling function 'foo' requires holding mutex '&ExistentialPatternMatching::Graph::mu_' exclusively}}
   n1.foo2();
 
   g1.mu_.Lock();
   n1.a = 0;
   n1.foo();
-  n1.foo2();  // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is locked}}
+  n1.foo2();  // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}}
   g1.mu_.Unlock();
 
   g2.mu_.Lock();
   n1.a = 0;
   n1.foo();
-  n1.foo2();  // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is locked}}
+  n1.foo2();  // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}}
   g2.mu_.Unlock();
 
   LockAllGraphs();
   n1.a = 0;
   n1.foo();
-  n1.foo2();  // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is locked}}
+  n1.foo2();  // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is held}}
   UnlockAllGraphs();
 
   LockAllGraphs();
@@ -3132,7 +3132,7 @@
   g2.mu_.Unlock();
 
   LockAllGraphs();
-  g1.mu_.Lock();  // expected-warning {{locking 'g1.mu_' that is already locked}}
+  g1.mu_.Lock();  // expected-warning {{acquiring mutex 'g1.mu_' that is already held}}
   g1.mu_.Unlock();
 }
 
@@ -3260,9 +3260,9 @@
       beginNoWarnOnWrites();
     }
     a = 0; // \
-      // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+      // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
     endNoWarnOnWrites();  // \
-      // expected-warning {{unlocking '*' that was not locked}}
+      // expected-warning {{releasing mutex '*' that was not held}}
   }
 
 
@@ -3390,17 +3390,17 @@
 
 
 void test1() {
-  Foo f;           // expected-warning {{calling function 'Foo' requires exclusive lock on 'mu_'}}
-  int a = f[0];    // expected-warning {{calling function 'operator[]' requires exclusive lock on 'mu_'}}
-}                  // expected-warning {{calling function '~Foo' requires exclusive lock on 'mu_'}}
+  Foo f;           // expected-warning {{calling function 'Foo' requires holding mutex 'mu_' exclusively}}
+  int a = f[0];    // expected-warning {{calling function 'operator[]' requires holding mutex 'mu_' exclusively}}
+}                  // expected-warning {{calling function '~Foo' requires holding mutex 'mu_' exclusively}}
 
 
 void test2() {
   Bar::mu_.Lock();
   {
-    Bar b;         // expected-warning {{cannot call function 'Bar' while mutex 'mu_' is locked}}
-    int a = b[0];  // expected-warning {{cannot call function 'operator[]' while mutex 'mu_' is locked}}
-  }                // expected-warning {{cannot call function '~Bar' while mutex 'mu_' is locked}}
+    Bar b;         // expected-warning {{cannot call function 'Bar' while mutex 'mu_' is held}}
+    int a = b[0];  // expected-warning {{cannot call function 'operator[]' while mutex 'mu_' is held}}
+  }                // expected-warning {{cannot call function '~Bar' while mutex 'mu_' is held}}
   Bar::mu_.Unlock();
 }
 
@@ -3499,7 +3499,7 @@
 void Foo::test() {
   Cell<int> cell;
   elr(&cell); // \
-    // expected-warning {{calling function 'elr' requires exclusive lock on 'cell.mu_'}}
+    // expected-warning {{calling function 'elr' requires holding mutex 'cell.mu_' exclusively}}
 }
 
 
@@ -3512,7 +3512,7 @@
 void globalTest() {
   Cell<int> cell;
   globalELR(&cell); // \
-    // expected-warning {{calling function 'globalELR' requires exclusive lock on 'cell.mu_'}}
+    // expected-warning {{calling function 'globalELR' requires holding mutex 'cell.mu_' exclusively}}
 }
 
 
@@ -3533,7 +3533,7 @@
 void globalTest2() {
   Cell<int> cell;
   globalELR2(&cell); // \
-    // expected-warning {{calling function 'globalELR2' requires exclusive lock on 'cell.mu_'}}
+    // expected-warning {{calling function 'globalELR2' requires holding mutex 'cell.mu_' exclusively}}
 }
 
 
@@ -3550,7 +3550,7 @@
   Cell<int> cell;
   FooT<int> foo;
   foo.elr(&cell); // \
-    // expected-warning {{calling function 'elr' requires exclusive lock on 'cell.mu_'}}
+    // expected-warning {{calling function 'elr' requires holding mutex 'cell.mu_' exclusively}}
 }
 
 }  // end namespace TemplateFunctionParamRemapTest
@@ -3616,8 +3616,14 @@
                        EXCLUSIVE_TRYLOCK_FUNCTION(true, mu2_);
   bool readertrylock() SHARED_TRYLOCK_FUNCTION(true, mu1_)
                        SHARED_TRYLOCK_FUNCTION(true, mu2_);
+  void assertBoth() ASSERT_EXCLUSIVE_LOCK(mu1_)
+                    ASSERT_EXCLUSIVE_LOCK(mu2_);
+  void assertShared() ASSERT_SHARED_LOCK(mu1_)
+                      ASSERT_SHARED_LOCK(mu2_);
 
   void test();
+  void testAssert();
+  void testAssertShared();
 };
 
 
@@ -3676,6 +3682,21 @@
   }
 }
 
+// Force duplication of attributes
+void Foo::assertBoth() { }
+void Foo::assertShared() { }
+
+void Foo::testAssert() {
+  assertBoth();
+  a = 0;
+  b = 0;
+}
+
+void Foo::testAssertShared() {
+  assertShared();
+  int zz = a + b;
+}
+
 
 }  // end namespace MultipleAttributeTest
 
@@ -3717,24 +3738,24 @@
   // method call tests
   void test() {
     data_.setValue(0);         // FIXME -- should be writing \
-      // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
+      // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
     int a = data_.getValue();  // \
-      // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
+      // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
 
     datap1_->setValue(0);      // FIXME -- should be writing \
-      // expected-warning {{reading variable 'datap1_' requires locking 'mu_'}}
+      // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}}
     a = datap1_->getValue();   // \
-      // expected-warning {{reading variable 'datap1_' requires locking 'mu_'}}
+      // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}}
 
     datap2_->setValue(0);      // FIXME -- should be writing \
-      // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
+      // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
     a = datap2_->getValue();   // \
-      // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
+      // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
 
     (*datap2_).setValue(0);    // FIXME -- should be writing \
-      // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
+      // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
     a = (*datap2_).getValue(); // \
-      // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
+      // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
 
     mu_.Lock();
     data_.setValue(1);
@@ -3752,31 +3773,31 @@
 
   // operator tests
   void test2() {
-    data_    = Data(1);   // expected-warning {{writing variable 'data_' requires locking 'mu_' exclusively}}
-    *datap1_ = data_;     // expected-warning {{reading variable 'datap1_' requires locking 'mu_'}} \
-                          // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
-    *datap2_ = data_;     // expected-warning {{writing the value pointed to by 'datap2_' requires locking 'mu_' exclusively}} \
-                          // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
-    data_ = *datap1_;     // expected-warning {{writing variable 'data_' requires locking 'mu_' exclusively}} \
-                          // expected-warning {{reading variable 'datap1_' requires locking 'mu_'}}
-    data_ = *datap2_;     // expected-warning {{writing variable 'data_' requires locking 'mu_' exclusively}} \
-                          // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
+    data_    = Data(1);   // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}}
+    *datap1_ = data_;     // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}} \
+                          // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
+    *datap2_ = data_;     // expected-warning {{writing the value pointed to by 'datap2_' requires holding mutex 'mu_' exclusively}} \
+                          // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
+    data_ = *datap1_;     // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}} \
+                          // expected-warning {{reading variable 'datap1_' requires holding mutex 'mu_'}}
+    data_ = *datap2_;     // expected-warning {{writing variable 'data_' requires holding mutex 'mu_' exclusively}} \
+                          // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
 
-    data_[0] = 0;         // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
-    (*datap2_)[0] = 0;    // expected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
+    data_[0] = 0;         // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
+    (*datap2_)[0] = 0;    // expected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
 
-    data_();              // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
+    data_();              // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
   }
 
   // const operator tests
   void test3() const {
-    Data mydat(data_);      // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
+    Data mydat(data_);      // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
 
     //FIXME
-    //showDataCell(data_);    // xpected-warning {{reading variable 'data_' requires locking 'mu_'}}
-    //showDataCell(*datap2_); // xpected-warning {{reading the value pointed to by 'datap2_' requires locking 'mu_'}}
+    //showDataCell(data_);    // xpected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
+    //showDataCell(*datap2_); // xpected-warning {{reading the value pointed to by 'datap2_' requires holding mutex 'mu_'}}
 
-    int a = data_[0];       // expected-warning {{reading variable 'data_' requires locking 'mu_'}}
+    int a = data_[0];       // expected-warning {{reading variable 'data_' requires holding mutex 'mu_'}}
   }
 
 private:
@@ -3820,31 +3841,31 @@
   Foo* foop PT_GUARDED_BY(mu_);
 
   void test() {
-    foo.myMethod();      // expected-warning {{reading variable 'foo' requires locking 'mu_'}}
+    foo.myMethod();      // expected-warning {{reading variable 'foo' requires holding mutex 'mu_'}}
 
-    int fa = foo.a;      // expected-warning {{reading variable 'foo' requires locking 'mu_'}}
-    foo.a  = fa;         // expected-warning {{writing variable 'foo' requires locking 'mu_' exclusively}}
+    int fa = foo.a;      // expected-warning {{reading variable 'foo' requires holding mutex 'mu_'}}
+    foo.a  = fa;         // expected-warning {{writing variable 'foo' requires holding mutex 'mu_' exclusively}}
 
-    fa = foop->a;        // expected-warning {{reading the value pointed to by 'foop' requires locking 'mu_'}}
-    foop->a = fa;        // expected-warning {{writing the value pointed to by 'foop' requires locking 'mu_' exclusively}}
+    fa = foop->a;        // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}}
+    foop->a = fa;        // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_' exclusively}}
 
-    fa = (*foop).a;      // expected-warning {{reading the value pointed to by 'foop' requires locking 'mu_'}}
-    (*foop).a = fa;      // expected-warning {{writing the value pointed to by 'foop' requires locking 'mu_' exclusively}}
+    fa = (*foop).a;      // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}}
+    (*foop).a = fa;      // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_' exclusively}}
 
-    foo.c  = Cell(0);    // expected-warning {{writing variable 'foo' requires locking 'mu_'}} \
-                         // expected-warning {{writing variable 'c' requires locking 'foo.cell_mu_' exclusively}}
-    foo.c.cellMethod();  // expected-warning {{reading variable 'foo' requires locking 'mu_'}} \
-                         // expected-warning {{reading variable 'c' requires locking 'foo.cell_mu_'}}
+    foo.c  = Cell(0);    // expected-warning {{writing variable 'foo' requires holding mutex 'mu_'}} \
+                         // expected-warning {{writing variable 'c' requires holding mutex 'foo.cell_mu_' exclusively}}
+    foo.c.cellMethod();  // expected-warning {{reading variable 'foo' requires holding mutex 'mu_'}} \
+                         // expected-warning {{reading variable 'c' requires holding mutex 'foo.cell_mu_'}}
 
-    foop->c  = Cell(0);    // expected-warning {{writing the value pointed to by 'foop' requires locking 'mu_'}} \
-                           // expected-warning {{writing variable 'c' requires locking 'foop->cell_mu_' exclusively}}
-    foop->c.cellMethod();  // expected-warning {{reading the value pointed to by 'foop' requires locking 'mu_'}} \
-                           // expected-warning {{reading variable 'c' requires locking 'foop->cell_mu_'}}
+    foop->c  = Cell(0);    // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_'}} \
+                           // expected-warning {{writing variable 'c' requires holding mutex 'foop->cell_mu_' exclusively}}
+    foop->c.cellMethod();  // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}} \
+                           // expected-warning {{reading variable 'c' requires holding mutex 'foop->cell_mu_'}}
 
-    (*foop).c  = Cell(0);    // expected-warning {{writing the value pointed to by 'foop' requires locking 'mu_'}} \
-                             // expected-warning {{writing variable 'c' requires locking 'foop->cell_mu_' exclusively}}
-    (*foop).c.cellMethod();  // expected-warning {{reading the value pointed to by 'foop' requires locking 'mu_'}} \
-                             // expected-warning {{reading variable 'c' requires locking 'foop->cell_mu_'}}
+    (*foop).c  = Cell(0);    // expected-warning {{writing the value pointed to by 'foop' requires holding mutex 'mu_'}} \
+                             // expected-warning {{writing variable 'c' requires holding mutex 'foop->cell_mu_' exclusively}}
+    (*foop).c.cellMethod();  // expected-warning {{reading the value pointed to by 'foop' requires holding mutex 'mu_'}} \
+                             // expected-warning {{reading variable 'c' requires holding mutex 'foop->cell_mu_'}}
   };
 };
 
@@ -3917,34 +3938,34 @@
   void lockBad() EXCLUSIVE_LOCK_FUNCTION(mu_) {    // expected-note {{mutex acquired here}}
     mu2_.Lock();
     mu2_.Unlock();
-  }  // expected-warning {{expecting mutex 'mu_' to be locked at the end of function}}
+  }  // expected-warning {{expecting mutex 'mu_' to be held at the end of function}}
 
   void readerLockBad() SHARED_LOCK_FUNCTION(mu_) {  // expected-note {{mutex acquired here}}
     mu2_.Lock();
     mu2_.Unlock();
-  }  // expected-warning {{expecting mutex 'mu_' to be locked at the end of function}}
+  }  // expected-warning {{expecting mutex 'mu_' to be held at the end of function}}
 
   void unlockBad() UNLOCK_FUNCTION(mu_) {  // expected-note {{mutex acquired here}}
     mu2_.Lock();
     mu2_.Unlock();
-  }  // expected-warning {{mutex 'mu_' is still locked at the end of function}}
+  }  // expected-warning {{mutex 'mu_' is still held at the end of function}}
 
   // Check locking the wrong thing.
   void lockBad2() EXCLUSIVE_LOCK_FUNCTION(mu_) {   // expected-note {{mutex acquired here}}
     mu2_.Lock();            // expected-note {{mutex acquired here}}
-  } // expected-warning {{expecting mutex 'mu_' to be locked at the end of function}} \
-    // expected-warning {{mutex 'mu2_' is still locked at the end of function}}
+  } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}} \
+    // expected-warning {{mutex 'mu2_' is still held at the end of function}}
 
 
   void readerLockBad2() SHARED_LOCK_FUNCTION(mu_) {   // expected-note {{mutex acquired here}}
     mu2_.ReaderLock();      // expected-note {{mutex acquired here}}
-  } // expected-warning {{expecting mutex 'mu_' to be locked at the end of function}} \
-    // expected-warning {{mutex 'mu2_' is still locked at the end of function}}
+  } // expected-warning {{expecting mutex 'mu_' to be held at the end of function}} \
+    // expected-warning {{mutex 'mu2_' is still held at the end of function}}
 
 
   void unlockBad2() UNLOCK_FUNCTION(mu_) {  // expected-note {{mutex acquired here}}
-    mu2_.Unlock();  // expected-warning {{unlocking 'mu2_' that was not locked}}
-  }  // expected-warning {{mutex 'mu_' is still locked at the end of function}}
+    mu2_.Unlock();  // expected-warning {{releasing mutex 'mu2_' that was not held}}
+  }  // expected-warning {{mutex 'mu_' is still held at the end of function}}
 
 private:
   Mutex mu_;
@@ -3971,7 +3992,7 @@
   void test2() {
     mu_.AssertReaderHeld();
     int b = a;
-    a = 0;   // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+    a = 0;   // expected-warning {{writing variable 'a' requires holding mutex 'mu_' exclusively}}
   }
 
   void test3() {
@@ -4032,7 +4053,7 @@
     else {
       mu_.Lock();  // expected-note {{mutex acquired here}}
     }
-  }  // expected-warning {{mutex 'mu_' is still locked at the end of function}}
+  }  // expected-warning {{mutex 'mu_' is still held at the end of function}}
 
   void test10() {
     if (c) {
@@ -4041,7 +4062,7 @@
     else {
       mu_.AssertHeld();
     }
-  }  // expected-warning {{mutex 'mu_' is still locked at the end of function}}
+  }  // expected-warning {{mutex 'mu_' is still held at the end of function}}
 
   void assertMu() ASSERT_EXCLUSIVE_LOCK(mu_);
 
@@ -4178,52 +4199,52 @@
 
   void test2() {
     mu1.ReaderLock();
-    if (*a == 0) doSomething();      // expected-warning {{reading the value pointed to by 'a' requires locking 'mu2'}}
-    *a = 0;                          // expected-warning {{writing the value pointed to by 'a' requires locking 'mu2' exclusively}}
+    if (*a == 0) doSomething();      // expected-warning {{reading the value pointed to by 'a' requires holding mutex 'mu2'}}
+    *a = 0;                          // expected-warning {{writing the value pointed to by 'a' requires holding mutex 'mu2' exclusively}}
 
-    if (c->a == 0) doSomething();    // expected-warning {{reading the value pointed to by 'c' requires locking 'mu2'}}
-    c->a = 0;                        // expected-warning {{writing the value pointed to by 'c' requires locking 'mu2' exclusively}}
+    if (c->a == 0) doSomething();    // expected-warning {{reading the value pointed to by 'c' requires holding mutex 'mu2'}}
+    c->a = 0;                        // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}
 
-    if ((*c).a == 0) doSomething();  // expected-warning {{reading the value pointed to by 'c' requires locking 'mu2'}}
-    (*c).a = 0;                      // expected-warning {{writing the value pointed to by 'c' requires locking 'mu2' exclusively}}
+    if ((*c).a == 0) doSomething();  // expected-warning {{reading the value pointed to by 'c' requires holding mutex 'mu2'}}
+    (*c).a = 0;                      // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}
 
-    if (a[0] == 42) doSomething();     // expected-warning {{reading the value pointed to by 'a' requires locking 'mu2'}}
-    a[0] = 57;                         // expected-warning {{writing the value pointed to by 'a' requires locking 'mu2' exclusively}}
-    if (c[0].a == 42) doSomething();   // expected-warning {{reading the value pointed to by 'c' requires locking 'mu2'}}
-    c[0].a = 57;                       // expected-warning {{writing the value pointed to by 'c' requires locking 'mu2' exclusively}}
+    if (a[0] == 42) doSomething();     // expected-warning {{reading the value pointed to by 'a' requires holding mutex 'mu2'}}
+    a[0] = 57;                         // expected-warning {{writing the value pointed to by 'a' requires holding mutex 'mu2' exclusively}}
+    if (c[0].a == 42) doSomething();   // expected-warning {{reading the value pointed to by 'c' requires holding mutex 'mu2'}}
+    c[0].a = 57;                       // expected-warning {{writing the value pointed to by 'c' requires holding mutex 'mu2' exclusively}}
     mu1.Unlock();
   }
 
   void test3() {
     mu2.Lock();
-    if (*a == 0) doSomething();      // expected-warning {{reading variable 'a' requires locking 'mu1'}}
-    *a = 0;                          // expected-warning {{reading variable 'a' requires locking 'mu1'}}
+    if (*a == 0) doSomething();      // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
+    *a = 0;                          // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
 
-    if (c->a == 0) doSomething();    // expected-warning {{reading variable 'c' requires locking 'mu1'}}
-    c->a = 0;                        // expected-warning {{reading variable 'c' requires locking 'mu1'}}
+    if (c->a == 0) doSomething();    // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
+    c->a = 0;                        // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
 
-    if ((*c).a == 0) doSomething();  // expected-warning {{reading variable 'c' requires locking 'mu1'}}
-    (*c).a = 0;                      // expected-warning {{reading variable 'c' requires locking 'mu1'}}
+    if ((*c).a == 0) doSomething();  // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
+    (*c).a = 0;                      // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
 
-    if (a[0] == 42) doSomething();     // expected-warning {{reading variable 'a' requires locking 'mu1'}}
-    a[0] = 57;                         // expected-warning {{reading variable 'a' requires locking 'mu1'}}
-    if (c[0].a == 42) doSomething();   // expected-warning {{reading variable 'c' requires locking 'mu1'}}
-    c[0].a = 57;                       // expected-warning {{reading variable 'c' requires locking 'mu1'}}
+    if (a[0] == 42) doSomething();     // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
+    a[0] = 57;                         // expected-warning {{reading variable 'a' requires holding mutex 'mu1'}}
+    if (c[0].a == 42) doSomething();   // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
+    c[0].a = 57;                       // expected-warning {{reading variable 'c' requires holding mutex 'mu1'}}
     mu2.Unlock();
   }
 
   void test4() {  // Literal arrays
-    if (sa[0] == 42) doSomething();     // expected-warning {{reading variable 'sa' requires locking 'mu1'}}
-    sa[0] = 57;                         // expected-warning {{writing variable 'sa' requires locking 'mu1' exclusively}}
-    if (sc[0].a == 42) doSomething();   // expected-warning {{reading variable 'sc' requires locking 'mu1'}}
-    sc[0].a = 57;                       // expected-warning {{writing variable 'sc' requires locking 'mu1' exclusively}}
+    if (sa[0] == 42) doSomething();     // expected-warning {{reading variable 'sa' requires holding mutex 'mu1'}}
+    sa[0] = 57;                         // expected-warning {{writing variable 'sa' requires holding mutex 'mu1' exclusively}}
+    if (sc[0].a == 42) doSomething();   // expected-warning {{reading variable 'sc' requires holding mutex 'mu1'}}
+    sc[0].a = 57;                       // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}}
 
-    if (*sa == 42) doSomething();       // expected-warning {{reading variable 'sa' requires locking 'mu1'}}
-    *sa = 57;                           // expected-warning {{writing variable 'sa' requires locking 'mu1' exclusively}}
-    if ((*sc).a == 42) doSomething();   // expected-warning {{reading variable 'sc' requires locking 'mu1'}}
-    (*sc).a = 57;                       // expected-warning {{writing variable 'sc' requires locking 'mu1' exclusively}}
-    if (sc->a == 42) doSomething();     // expected-warning {{reading variable 'sc' requires locking 'mu1'}}
-    sc->a = 57;                         // expected-warning {{writing variable 'sc' requires locking 'mu1' exclusively}}
+    if (*sa == 42) doSomething();       // expected-warning {{reading variable 'sa' requires holding mutex 'mu1'}}
+    *sa = 57;                           // expected-warning {{writing variable 'sa' requires holding mutex 'mu1' exclusively}}
+    if ((*sc).a == 42) doSomething();   // expected-warning {{reading variable 'sc' requires holding mutex 'mu1'}}
+    (*sc).a = 57;                       // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}}
+    if (sc->a == 42) doSomething();     // expected-warning {{reading variable 'sc' requires holding mutex 'mu1'}}
+    sc->a = 57;                         // expected-warning {{writing variable 'sc' requires holding mutex 'mu1' exclusively}}
   }
 
   void test5() {
@@ -4268,15 +4289,15 @@
   void test2() {
     mu2.Lock();
 
-    sp.get();                      // expected-warning {{reading variable 'sp' requires locking 'mu1'}}
-    if (*sp == 0) doSomething();   // expected-warning {{reading variable 'sp' requires locking 'mu1'}}
-    *sp = 0;                       // expected-warning {{reading variable 'sp' requires locking 'mu1'}}
-    sq->a = 0;                     // expected-warning {{reading variable 'sq' requires locking 'mu1'}}
+    sp.get();                      // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
+    if (*sp == 0) doSomething();   // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
+    *sp = 0;                       // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
+    sq->a = 0;                     // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}}
 
-    if (sp[0] == 0) doSomething();   // expected-warning {{reading variable 'sp' requires locking 'mu1'}}
-    sp[0] = 0;                       // expected-warning {{reading variable 'sp' requires locking 'mu1'}}
-    if (sq[0].a == 0) doSomething(); // expected-warning {{reading variable 'sq' requires locking 'mu1'}}
-    sq[0].a = 0;                     // expected-warning {{reading variable 'sq' requires locking 'mu1'}}
+    if (sp[0] == 0) doSomething();   // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
+    sp[0] = 0;                       // expected-warning {{reading variable 'sp' requires holding mutex 'mu1'}}
+    if (sq[0].a == 0) doSomething(); // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}}
+    sq[0].a = 0;                     // expected-warning {{reading variable 'sq' requires holding mutex 'mu1'}}
 
     mu2.Unlock();
   }
@@ -4285,14 +4306,14 @@
     mu1.Lock();
 
     sp.get();
-    if (*sp == 0) doSomething();   // expected-warning {{reading the value pointed to by 'sp' requires locking 'mu2'}}
-    *sp = 0;                       // expected-warning {{reading the value pointed to by 'sp' requires locking 'mu2'}}
-    sq->a = 0;                     // expected-warning {{reading the value pointed to by 'sq' requires locking 'mu2'}}
+    if (*sp == 0) doSomething();   // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
+    *sp = 0;                       // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
+    sq->a = 0;                     // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}}
 
-    if (sp[0] == 0) doSomething();   // expected-warning {{reading the value pointed to by 'sp' requires locking 'mu2'}}
-    sp[0] = 0;                       // expected-warning {{reading the value pointed to by 'sp' requires locking 'mu2'}}
-    if (sq[0].a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'sq' requires locking 'mu2'}}
-    sq[0].a = 0;                     // expected-warning {{reading the value pointed to by 'sq' requires locking 'mu2'}}
+    if (sp[0] == 0) doSomething();   // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
+    sp[0] = 0;                       // expected-warning {{reading the value pointed to by 'sp' requires holding mutex 'mu2'}}
+    if (sq[0].a == 0) doSomething(); // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}}
+    sq[0].a = 0;                     // expected-warning {{reading the value pointed to by 'sq' requires holding mutex 'mu2'}}
 
     mu1.Unlock();
   }
@@ -4300,3 +4321,60 @@
 
 }  // end namespace PtGuardedByTest
 
+
+namespace NonMemberCalleeICETest {
+
+class A {
+  void Run() {
+  (RunHelper)();  // expected-warning {{calling function 'RunHelper' requires holding mutex 'M' exclusively}}
+ }
+
+ void RunHelper() __attribute__((exclusive_locks_required(M)));
+ Mutex M;
+};
+
+}  // end namespace NonMemberCalleeICETest
+
+
+namespace pt_guard_attribute_type {
+  int i PT_GUARDED_BY(sls_mu);  // expected-warning {{'pt_guarded_by' only applies to pointer types; type here is 'int'}}
+  int j PT_GUARDED_VAR;  // expected-warning {{'pt_guarded_var' only applies to pointer types; type here is 'int'}}
+
+  void test() {
+    int i PT_GUARDED_BY(sls_mu);  // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
+    int j PT_GUARDED_VAR;  // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
+
+    typedef int PT_GUARDED_BY(sls_mu) bad1;  // expected-warning {{'pt_guarded_by' attribute only applies to fields and global variables}}
+    typedef int PT_GUARDED_VAR bad2;  // expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
+  }
+}  // end namespace pt_guard_attribute_type
+
+
+namespace ThreadAttributesOnLambdas {
+
+class Foo {
+  Mutex mu_;
+
+  void LockedFunction() EXCLUSIVE_LOCKS_REQUIRED(mu_);
+
+  void test() {
+    auto func1 = [this]() EXCLUSIVE_LOCKS_REQUIRED(mu_) {
+      LockedFunction();
+    };
+
+    auto func2 = [this]() NO_THREAD_SAFETY_ANALYSIS {
+      LockedFunction();
+    };
+
+    auto func3 = [this]() EXCLUSIVE_LOCK_FUNCTION(mu_) {
+      mu_.Lock();
+    };
+
+    func1();  // expected-warning {{calling function 'operator()' requires holding mutex 'mu_' exclusively}}
+    func2();
+    func3();
+    mu_.Unlock();
+  }
+};
+
+}  // end namespace ThreadAttributesOnLambdas
diff --git a/test/SemaCXX/warn-thread-safety-parsing.cpp b/test/SemaCXX/warn-thread-safety-parsing.cpp
index 1bd4e43..6f9e7de 100644
--- a/test/SemaCXX/warn-thread-safety-parsing.cpp
+++ b/test/SemaCXX/warn-thread-safety-parsing.cpp
@@ -109,26 +109,26 @@
 
 int noanal_testfn(int y) {
   int x NO_THREAD_SAFETY_ANALYSIS = y; // \
-    // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}
+    // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions}}
   return x;
 };
 
 int noanal_test_var NO_THREAD_SAFETY_ANALYSIS; // \
-  // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}
+  // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions}}
 
 class NoanalFoo {
  private:
   int test_field NO_THREAD_SAFETY_ANALYSIS; // \
-    // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}
+    // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions}}
   void test_method() NO_THREAD_SAFETY_ANALYSIS;
 };
 
 class NO_THREAD_SAFETY_ANALYSIS NoanalTestClass { // \
-  // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}
+  // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions}}
 };
 
 void noanal_fun_params(int lvar NO_THREAD_SAFETY_ANALYSIS); // \
-  // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}
+  // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions}}
 
 
 //-----------------------------------------//
@@ -229,28 +229,28 @@
 };
 
 void l_test_function() LOCKABLE;  // \
-  // expected-warning {{'lockable' attribute only applies to classes}}
+  // expected-warning {{'lockable' attribute only applies to struct, union or class}}
 
 int l_testfn(int y) {
   int x LOCKABLE = y; // \
-    // expected-warning {{'lockable' attribute only applies to classes}}
+    // expected-warning {{'lockable' attribute only applies to struct, union or class}}
   return x;
 }
 
 int l_test_var LOCKABLE; // \
-  // expected-warning {{'lockable' attribute only applies to classes}}
+  // expected-warning {{'lockable' attribute only applies to struct, union or class}}
 
 class LFoo {
  private:
   int test_field LOCKABLE; // \
-    // expected-warning {{'lockable' attribute only applies to classes}}
+    // expected-warning {{'lockable' attribute only applies to struct, union or class}}
   void test_method() LOCKABLE; // \
-    // expected-warning {{'lockable' attribute only applies to classes}}
+    // expected-warning {{'lockable' attribute only applies to struct, union or class}}
 };
 
 
 void l_function_params(int lvar LOCKABLE); // \
-  // expected-warning {{'lockable' attribute only applies to classes}}
+  // expected-warning {{'lockable' attribute only applies to struct, union or class}}
 
 
 //-----------------------------------------//
@@ -269,28 +269,28 @@
 };
 
 void sl_test_function() SCOPED_LOCKABLE;  // \
-  // expected-warning {{'scoped_lockable' attribute only applies to classes}}
+  // expected-warning {{'scoped_lockable' attribute only applies to struct, union or class}}
 
 int sl_testfn(int y) {
   int x SCOPED_LOCKABLE = y; // \
-    // expected-warning {{'scoped_lockable' attribute only applies to classes}}
+    // expected-warning {{'scoped_lockable' attribute only applies to struct, union or class}}
   return x;
 }
 
 int sl_test_var SCOPED_LOCKABLE; // \
-  // expected-warning {{'scoped_lockable' attribute only applies to classes}}
+  // expected-warning {{'scoped_lockable' attribute only applies to struct, union or class}}
 
 class SLFoo {
  private:
   int test_field SCOPED_LOCKABLE; // \
-    // expected-warning {{'scoped_lockable' attribute only applies to classes}}
+    // expected-warning {{'scoped_lockable' attribute only applies to struct, union or class}}
   void test_method() SCOPED_LOCKABLE; // \
-    // expected-warning {{'scoped_lockable' attribute only applies to classes}}
+    // expected-warning {{'scoped_lockable' attribute only applies to struct, union or class}}
 };
 
 
 void sl_function_params(int lvar SCOPED_LOCKABLE); // \
-  // expected-warning {{'scoped_lockable' attribute only applies to classes}}
+  // expected-warning {{'scoped_lockable' attribute only applies to struct, union or class}}
 
 
 //-----------------------------------------//
@@ -353,13 +353,13 @@
 
 // illegal attribute arguments
 int gb_var_arg_bad_1 GUARDED_BY(1); // \
-  // expected-warning {{'guarded_by' attribute requires arguments that are class type or point to class type; type here is 'int'}}
+  // expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
 int gb_var_arg_bad_2 GUARDED_BY("mu"); // \
   // expected-warning {{ignoring 'guarded_by' attribute because its argument is invalid}}
 int gb_var_arg_bad_3 GUARDED_BY(muDoublePointer); // \
-  // expected-warning {{'guarded_by' attribute requires arguments that are class type or point to class type; type here is 'class Mutex **'}}
+  // expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
 int gb_var_arg_bad_4 GUARDED_BY(umu); // \
-  // expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'lockable' attribute; type here is 'class UnlockableMu'}}
+  // expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'UnlockableMu'}}
 
 //3.
 // Thread Safety analysis tests
@@ -424,13 +424,13 @@
 
 // illegal attribute arguments
 int * pgb_var_arg_bad_1 PT_GUARDED_BY(1); // \
-  // expected-warning {{'pt_guarded_by' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'pt_guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
 int * pgb_var_arg_bad_2 PT_GUARDED_BY("mu"); // \
   // expected-warning {{ignoring 'pt_guarded_by' attribute because its argument is invalid}}
 int * pgb_var_arg_bad_3 PT_GUARDED_BY(muDoublePointer); // \
-  // expected-warning {{'pt_guarded_by' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'pt_guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
 int * pgb_var_arg_bad_4 PT_GUARDED_BY(umu); // \
-  // expected-warning {{'pt_guarded_by' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+  // expected-warning {{'pt_guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute}}
 
 
 //-----------------------------------------//
@@ -446,12 +446,12 @@
 Mutex mu_aa ACQUIRED_AFTER(mu1);
 
 Mutex aa_var_noargs __attribute__((acquired_after)); // \
-  // expected-error {{attribute takes at least 1 argument}}
+  // expected-error {{'acquired_after' attribute takes at least 1 argument}}
 
 class AAFoo {
  private:
   Mutex aa_field_noargs __attribute__((acquired_after)); // \
-    // expected-error {{attribute takes at least 1 argument}}
+    // expected-error {{'acquired_after' attribute takes at least 1 argument}}
   Mutex aa_field_args ACQUIRED_AFTER(mu1);
 };
 
@@ -485,15 +485,15 @@
 
 // illegal attribute arguments
 Mutex aa_var_arg_bad_1 ACQUIRED_AFTER(1); // \
-  // expected-warning {{'acquired_after' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'acquired_after' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
 Mutex aa_var_arg_bad_2 ACQUIRED_AFTER("mu"); // \
   // expected-warning {{ignoring 'acquired_after' attribute because its argument is invalid}}
 Mutex aa_var_arg_bad_3 ACQUIRED_AFTER(muDoublePointer); // \
-  // expected-warning {{'acquired_after' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'acquired_after' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
 Mutex aa_var_arg_bad_4 ACQUIRED_AFTER(umu); // \
-  // expected-warning {{'acquired_after' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+  // expected-warning {{'acquired_after' attribute requires arguments whose type is annotated with 'capability' attribute}}
 UnlockableMu aa_var_arg_bad_5 ACQUIRED_AFTER(mu_aa); // \
-  // expected-warning {{'acquired_after' attribute can only be applied in a context annotated with 'lockable' attribute}}
+  // expected-warning {{'acquired_after' attribute can only be applied in a context annotated with 'capability("mutex")' attribute}}
 
 //-----------------------------------------//
 //  Acquired Before (ab)
@@ -506,12 +506,12 @@
 Mutex mu_ab ACQUIRED_BEFORE(mu1);
 
 Mutex ab_var_noargs __attribute__((acquired_before)); // \
-  // expected-error {{attribute takes at least 1 argument}}
+  // expected-error {{'acquired_before' attribute takes at least 1 argument}}
 
 class ABFoo {
  private:
   Mutex ab_field_noargs __attribute__((acquired_before)); // \
-    // expected-error {{attribute takes at least 1 argument}}
+    // expected-error {{'acquired_before' attribute takes at least 1 argument}}
   Mutex ab_field_args ACQUIRED_BEFORE(mu1);
 };
 
@@ -548,15 +548,15 @@
 
 // illegal attribute arguments
 Mutex ab_var_arg_bad_1 ACQUIRED_BEFORE(1); // \
-  // expected-warning {{'acquired_before' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'acquired_before' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
 Mutex ab_var_arg_bad_2 ACQUIRED_BEFORE("mu"); // \
   // expected-warning {{ignoring 'acquired_before' attribute because its argument is invalid}}
 Mutex ab_var_arg_bad_3 ACQUIRED_BEFORE(muDoublePointer); // \
-  // expected-warning {{'acquired_before' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'acquired_before' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
 Mutex ab_var_arg_bad_4 ACQUIRED_BEFORE(umu); // \
-  // expected-warning {{'acquired_before' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+  // expected-warning {{'acquired_before' attribute requires arguments whose type is annotated with 'capability' attribute}}
 UnlockableMu ab_var_arg_bad_5 ACQUIRED_BEFORE(mu_ab); // \
-  // expected-warning {{'acquired_before' attribute can only be applied in a context annotated with 'lockable' attribute}}
+  // expected-warning {{'acquired_before' attribute can only be applied in a context annotated with 'capability("mutex")' attribute}}
 
 
 //-----------------------------------------//
@@ -577,26 +577,26 @@
 
 int elf_testfn(int y) {
   int x EXCLUSIVE_LOCK_FUNCTION() = y; // \
-    // expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}}
+    // expected-warning {{'exclusive_lock_function' attribute only applies to functions}}
   return x;
 };
 
 int elf_test_var EXCLUSIVE_LOCK_FUNCTION(); // \
-  // expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}}
+  // expected-warning {{'exclusive_lock_function' attribute only applies to functions}}
 
 class ElfFoo {
  private:
   int test_field EXCLUSIVE_LOCK_FUNCTION(); // \
-    // expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}}
+    // expected-warning {{'exclusive_lock_function' attribute only applies to functions}}
   void test_method() EXCLUSIVE_LOCK_FUNCTION();
 };
 
 class EXCLUSIVE_LOCK_FUNCTION() ElfTestClass { // \
-  // expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}}
+  // expected-warning {{'exclusive_lock_function' attribute only applies to functions}}
 };
 
 void elf_fun_params(int lvar EXCLUSIVE_LOCK_FUNCTION()); // \
-  // expected-warning {{'exclusive_lock_function' attribute only applies to functions and methods}}
+  // expected-warning {{'exclusive_lock_function' attribute only applies to functions}}
 
 // Check argument parsing.
 
@@ -617,9 +617,9 @@
 int elf_function_bad_2() EXCLUSIVE_LOCK_FUNCTION("mu"); // \
   // expected-warning {{ignoring 'exclusive_lock_function' attribute because its argument is invalid}}
 int elf_function_bad_3() EXCLUSIVE_LOCK_FUNCTION(muDoublePointer); // \
-  // expected-warning {{'exclusive_lock_function' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'exclusive_lock_function' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
 int elf_function_bad_4() EXCLUSIVE_LOCK_FUNCTION(umu); // \
-  // expected-warning {{'exclusive_lock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+  // expected-warning {{'exclusive_lock_function' attribute requires arguments whose type is annotated with 'capability' attribute}}
 
 int elf_function_bad_1() EXCLUSIVE_LOCK_FUNCTION(1); // \
   // expected-error {{'exclusive_lock_function' attribute parameter 1 is out of bounds: no parameters to index into}}
@@ -649,25 +649,25 @@
 
 int slf_testfn(int y) {
   int x SHARED_LOCK_FUNCTION() = y; // \
-    // expected-warning {{'shared_lock_function' attribute only applies to functions and methods}}
+    // expected-warning {{'shared_lock_function' attribute only applies to functions}}
   return x;
 };
 
 int slf_test_var SHARED_LOCK_FUNCTION(); // \
-  // expected-warning {{'shared_lock_function' attribute only applies to functions and methods}}
+  // expected-warning {{'shared_lock_function' attribute only applies to functions}}
 
 void slf_fun_params(int lvar SHARED_LOCK_FUNCTION()); // \
-  // expected-warning {{'shared_lock_function' attribute only applies to functions and methods}}
+  // expected-warning {{'shared_lock_function' attribute only applies to functions}}
 
 class SlfFoo {
  private:
   int test_field SHARED_LOCK_FUNCTION(); // \
-    // expected-warning {{'shared_lock_function' attribute only applies to functions and methods}}
+    // expected-warning {{'shared_lock_function' attribute only applies to functions}}
   void test_method() SHARED_LOCK_FUNCTION();
 };
 
 class SHARED_LOCK_FUNCTION() SlfTestClass { // \
-  // expected-warning {{'shared_lock_function' attribute only applies to functions and methods}}
+  // expected-warning {{'shared_lock_function' attribute only applies to functions}}
 };
 
 // Check argument parsing.
@@ -689,9 +689,9 @@
 int slf_function_bad_2() SHARED_LOCK_FUNCTION("mu"); // \
   // expected-warning {{ignoring 'shared_lock_function' attribute because its argument is invalid}}
 int slf_function_bad_3() SHARED_LOCK_FUNCTION(muDoublePointer); // \
-  // expected-warning {{'shared_lock_function' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'shared_lock_function' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
 int slf_function_bad_4() SHARED_LOCK_FUNCTION(umu); // \
-  // expected-warning {{'shared_lock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+  // expected-warning {{'shared_lock_function' attribute requires arguments whose type is annotated with 'capability' attribute}}
 
 int slf_function_bad_1() SHARED_LOCK_FUNCTION(1); // \
   // expected-error {{'shared_lock_function' attribute parameter 1 is out of bounds: no parameters to index into}}
@@ -715,7 +715,7 @@
 // plus an optional list of locks (vars/fields)
 
 void etf_function() __attribute__((exclusive_trylock_function));  // \
-  // expected-error {{attribute takes at least 1 argument}}
+  // expected-error {{'exclusive_trylock_function' attribute takes at least 1 argument}}
 
 void etf_function_args() EXCLUSIVE_TRYLOCK_FUNCTION(1, mu2);
 
@@ -725,26 +725,26 @@
 
 int etf_testfn(int y) {
   int x EXCLUSIVE_TRYLOCK_FUNCTION(1) = y; // \
-    // expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}}
+    // expected-warning {{'exclusive_trylock_function' attribute only applies to functions}}
   return x;
 };
 
 int etf_test_var EXCLUSIVE_TRYLOCK_FUNCTION(1); // \
-  // expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}}
+  // expected-warning {{'exclusive_trylock_function' attribute only applies to functions}}
 
 class EtfFoo {
  private:
   int test_field EXCLUSIVE_TRYLOCK_FUNCTION(1); // \
-    // expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}}
+    // expected-warning {{'exclusive_trylock_function' attribute only applies to functions}}
   void test_method() EXCLUSIVE_TRYLOCK_FUNCTION(1);
 };
 
 class EXCLUSIVE_TRYLOCK_FUNCTION(1) EtfTestClass { // \
-  // expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}}
+  // expected-warning {{'exclusive_trylock_function' attribute only applies to functions}}
 };
 
 void etf_fun_params(int lvar EXCLUSIVE_TRYLOCK_FUNCTION(1)); // \
-  // expected-warning {{'exclusive_trylock_function' attribute only applies to functions and methods}}
+  // expected-warning {{'exclusive_trylock_function' attribute only applies to functions}}
 
 // Check argument parsing.
 
@@ -771,9 +771,9 @@
 int etf_function_bad_4() EXCLUSIVE_TRYLOCK_FUNCTION(1, "mu"); // \
   // expected-warning {{ignoring 'exclusive_trylock_function' attribute because its argument is invalid}}
 int etf_function_bad_5() EXCLUSIVE_TRYLOCK_FUNCTION(1, muDoublePointer); // \
-  // expected-warning {{'exclusive_trylock_function' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'exclusive_trylock_function' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
 int etf_function_bad_6() EXCLUSIVE_TRYLOCK_FUNCTION(1, umu); // \
-  // expected-warning {{'exclusive_trylock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+  // expected-warning {{'exclusive_trylock_function' attribute requires arguments whose type is annotated with 'capability' attribute}}
 
 
 //-----------------------------------------//
@@ -788,7 +788,7 @@
 // plus an optional list of locks (vars/fields)
 
 void stf_function() __attribute__((shared_trylock_function));  // \
-  // expected-error {{attribute takes at least 1 argument}}
+  // expected-error {{'shared_trylock_function' attribute takes at least 1 argument}}
 
 void stf_function_args() SHARED_TRYLOCK_FUNCTION(1, mu2);
 
@@ -798,26 +798,26 @@
 
 int stf_testfn(int y) {
   int x SHARED_TRYLOCK_FUNCTION(1) = y; // \
-    // expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}}
+    // expected-warning {{'shared_trylock_function' attribute only applies to functions}}
   return x;
 };
 
 int stf_test_var SHARED_TRYLOCK_FUNCTION(1); // \
-  // expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}}
+  // expected-warning {{'shared_trylock_function' attribute only applies to functions}}
 
 void stf_fun_params(int lvar SHARED_TRYLOCK_FUNCTION(1)); // \
-  // expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}}
+  // expected-warning {{'shared_trylock_function' attribute only applies to functions}}
 
 
 class StfFoo {
  private:
   int test_field SHARED_TRYLOCK_FUNCTION(1); // \
-    // expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}}
+    // expected-warning {{'shared_trylock_function' attribute only applies to functions}}
   void test_method() SHARED_TRYLOCK_FUNCTION(1);
 };
 
 class SHARED_TRYLOCK_FUNCTION(1) StfTestClass { // \
-    // expected-warning {{'shared_trylock_function' attribute only applies to functions and methods}}
+    // expected-warning {{'shared_trylock_function' attribute only applies to functions}}
 };
 
 // Check argument parsing.
@@ -845,9 +845,9 @@
 int stf_function_bad_4() SHARED_TRYLOCK_FUNCTION(1, "mu"); // \
   // expected-warning {{ignoring 'shared_trylock_function' attribute because its argument is invalid}}
 int stf_function_bad_5() SHARED_TRYLOCK_FUNCTION(1, muDoublePointer); // \
-  // expected-warning {{'shared_trylock_function' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'shared_trylock_function' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
 int stf_function_bad_6() SHARED_TRYLOCK_FUNCTION(1, umu); // \
-  // expected-warning {{'shared_trylock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+  // expected-warning {{'shared_trylock_function' attribute requires arguments whose type is annotated with 'capability' attribute}}
 
 
 //-----------------------------------------//
@@ -868,26 +868,26 @@
 
 int uf_testfn(int y) {
   int x UNLOCK_FUNCTION() = y; // \
-    // expected-warning {{'unlock_function' attribute only applies to functions and methods}}
+    // expected-warning {{'unlock_function' attribute only applies to functions}}
   return x;
 };
 
 int uf_test_var UNLOCK_FUNCTION(); // \
-  // expected-warning {{'unlock_function' attribute only applies to functions and methods}}
+  // expected-warning {{'unlock_function' attribute only applies to functions}}
 
 class UfFoo {
  private:
   int test_field UNLOCK_FUNCTION(); // \
-    // expected-warning {{'unlock_function' attribute only applies to functions and methods}}
+    // expected-warning {{'unlock_function' attribute only applies to functions}}
   void test_method() UNLOCK_FUNCTION();
 };
 
 class NO_THREAD_SAFETY_ANALYSIS UfTestClass { // \
-  // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}
+  // expected-warning {{'no_thread_safety_analysis' attribute only applies to functions}}
 };
 
 void uf_fun_params(int lvar UNLOCK_FUNCTION()); // \
-  // expected-warning {{'unlock_function' attribute only applies to functions and methods}}
+  // expected-warning {{'unlock_function' attribute only applies to functions}}
 
 // Check argument parsing.
 
@@ -908,9 +908,9 @@
 int uf_function_bad_2() UNLOCK_FUNCTION("mu"); // \
   // expected-warning {{ignoring 'unlock_function' attribute because its argument is invalid}}
 int uf_function_bad_3() UNLOCK_FUNCTION(muDoublePointer); // \
-  // expected-warning {{'unlock_function' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'unlock_function' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
 int uf_function_bad_4() UNLOCK_FUNCTION(umu); // \
-  // expected-warning {{'unlock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+  // expected-warning {{'unlock_function' attribute requires arguments whose type is annotated with 'capability' attribute}}
 
 int uf_function_bad_1() UNLOCK_FUNCTION(1); // \
   // expected-error {{'unlock_function' attribute parameter 1 is out of bounds: no parameters to index into}}
@@ -944,25 +944,25 @@
 
 int lr_testfn(int y) {
   int x LOCK_RETURNED(mu1) = y; // \
-    // expected-warning {{'lock_returned' attribute only applies to functions and methods}}
+    // expected-warning {{'lock_returned' attribute only applies to functions}}
   return x;
 };
 
 int lr_test_var LOCK_RETURNED(mu1); // \
-  // expected-warning {{'lock_returned' attribute only applies to functions and methods}}
+  // expected-warning {{'lock_returned' attribute only applies to functions}}
 
 void lr_fun_params(int lvar LOCK_RETURNED(mu1)); // \
-  // expected-warning {{'lock_returned' attribute only applies to functions and methods}}
+  // expected-warning {{'lock_returned' attribute only applies to functions}}
 
 class LrFoo {
  private:
   int test_field LOCK_RETURNED(mu1); // \
-    // expected-warning {{'lock_returned' attribute only applies to functions and methods}}
+    // expected-warning {{'lock_returned' attribute only applies to functions}}
   void test_method() LOCK_RETURNED(mu1);
 };
 
 class LOCK_RETURNED(mu1) LrTestClass { // \
-    // expected-warning {{'lock_returned' attribute only applies to functions and methods}}
+    // expected-warning {{'lock_returned' attribute only applies to functions}}
 };
 
 // Check argument parsing.
@@ -980,13 +980,13 @@
 
 // illegal attribute arguments
 int lr_function_bad_1() LOCK_RETURNED(1); // \
-  // expected-warning {{'lock_returned' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'lock_returned' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
 int lr_function_bad_2() LOCK_RETURNED("mu"); // \
   // expected-warning {{ignoring 'lock_returned' attribute because its argument is invalid}}
 int lr_function_bad_3() LOCK_RETURNED(muDoublePointer); // \
-  // expected-warning {{'lock_returned' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'lock_returned' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
 int lr_function_bad_4() LOCK_RETURNED(umu); // \
-  // expected-warning {{'lock_returned' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+  // expected-warning {{'lock_returned' attribute requires arguments whose type is annotated with 'capability' attribute}}
 
 
 
@@ -1001,7 +1001,7 @@
 // takes one or more arguments, all locks (vars/fields)
 
 void le_function() __attribute__((locks_excluded)); // \
-  // expected-error {{attribute takes at least 1 argument}}
+  // expected-error {{'locks_excluded' attribute takes at least 1 argument}}
 
 void le_function_arg() LOCKS_EXCLUDED(mu1);
 
@@ -1011,25 +1011,25 @@
 
 int le_testfn(int y) {
   int x LOCKS_EXCLUDED(mu1) = y; // \
-    // expected-warning {{'locks_excluded' attribute only applies to functions and methods}}
+    // expected-warning {{'locks_excluded' attribute only applies to functions}}
   return x;
 };
 
 int le_test_var LOCKS_EXCLUDED(mu1); // \
-  // expected-warning {{'locks_excluded' attribute only applies to functions and methods}}
+  // expected-warning {{'locks_excluded' attribute only applies to functions}}
 
 void le_fun_params(int lvar LOCKS_EXCLUDED(mu1)); // \
-  // expected-warning {{'locks_excluded' attribute only applies to functions and methods}}
+  // expected-warning {{'locks_excluded' attribute only applies to functions}}
 
 class LeFoo {
  private:
   int test_field LOCKS_EXCLUDED(mu1); // \
-    // expected-warning {{'locks_excluded' attribute only applies to functions and methods}}
+    // expected-warning {{'locks_excluded' attribute only applies to functions}}
   void test_method() LOCKS_EXCLUDED(mu1);
 };
 
 class LOCKS_EXCLUDED(mu1) LeTestClass { // \
-  // expected-warning {{'locks_excluded' attribute only applies to functions and methods}}
+  // expected-warning {{'locks_excluded' attribute only applies to functions}}
 };
 
 // Check argument parsing.
@@ -1047,13 +1047,13 @@
 
 // illegal attribute arguments
 int le_function_bad_1() LOCKS_EXCLUDED(1); // \
-  // expected-warning {{'locks_excluded' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'locks_excluded' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
 int le_function_bad_2() LOCKS_EXCLUDED("mu"); // \
   // expected-warning {{ignoring 'locks_excluded' attribute because its argument is invalid}}
 int le_function_bad_3() LOCKS_EXCLUDED(muDoublePointer); // \
-  // expected-warning {{'locks_excluded' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'locks_excluded' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
 int le_function_bad_4() LOCKS_EXCLUDED(umu); // \
-  // expected-warning {{'locks_excluded' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+  // expected-warning {{'locks_excluded' attribute requires arguments whose type is annotated with 'capability' attribute}}
 
 
 
@@ -1068,7 +1068,7 @@
 // takes one or more arguments, all locks (vars/fields)
 
 void elr_function() __attribute__((exclusive_locks_required)); // \
-  // expected-error {{attribute takes at least 1 argument}}
+  // expected-error {{'exclusive_locks_required' attribute takes at least 1 argument}}
 
 void elr_function_arg() EXCLUSIVE_LOCKS_REQUIRED(mu1);
 
@@ -1078,25 +1078,25 @@
 
 int elr_testfn(int y) {
   int x EXCLUSIVE_LOCKS_REQUIRED(mu1) = y; // \
-    // expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}}
+    // expected-warning {{'exclusive_locks_required' attribute only applies to functions}}
   return x;
 };
 
 int elr_test_var EXCLUSIVE_LOCKS_REQUIRED(mu1); // \
-  // expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}}
+  // expected-warning {{'exclusive_locks_required' attribute only applies to functions}}
 
 void elr_fun_params(int lvar EXCLUSIVE_LOCKS_REQUIRED(mu1)); // \
-  // expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}}
+  // expected-warning {{'exclusive_locks_required' attribute only applies to functions}}
 
 class ElrFoo {
  private:
   int test_field EXCLUSIVE_LOCKS_REQUIRED(mu1); // \
-    // expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}}
+    // expected-warning {{'exclusive_locks_required' attribute only applies to functions}}
   void test_method() EXCLUSIVE_LOCKS_REQUIRED(mu1);
 };
 
 class EXCLUSIVE_LOCKS_REQUIRED(mu1) ElrTestClass { // \
-  // expected-warning {{'exclusive_locks_required' attribute only applies to functions and methods}}
+  // expected-warning {{'exclusive_locks_required' attribute only applies to functions}}
 };
 
 // Check argument parsing.
@@ -1114,13 +1114,13 @@
 
 // illegal attribute arguments
 int elr_function_bad_1() EXCLUSIVE_LOCKS_REQUIRED(1); // \
-  // expected-warning {{'exclusive_locks_required' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'exclusive_locks_required' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
 int elr_function_bad_2() EXCLUSIVE_LOCKS_REQUIRED("mu"); // \
   // expected-warning {{ignoring 'exclusive_locks_required' attribute because its argument is invalid}}
 int elr_function_bad_3() EXCLUSIVE_LOCKS_REQUIRED(muDoublePointer); // \
-  // expected-warning {{'exclusive_locks_required' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'exclusive_locks_required' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
 int elr_function_bad_4() EXCLUSIVE_LOCKS_REQUIRED(umu); // \
-  // expected-warning {{'exclusive_locks_required' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+  // expected-warning {{'exclusive_locks_required' attribute requires arguments whose type is annotated with 'capability' attribute}}
 
 
 
@@ -1136,7 +1136,7 @@
 // takes one or more arguments, all locks (vars/fields)
 
 void slr_function() __attribute__((shared_locks_required)); // \
-  // expected-error {{attribute takes at least 1 argument}}
+  // expected-error {{'shared_locks_required' attribute takes at least 1 argument}}
 
 void slr_function_arg() SHARED_LOCKS_REQUIRED(mu1);
 
@@ -1146,25 +1146,25 @@
 
 int slr_testfn(int y) {
   int x SHARED_LOCKS_REQUIRED(mu1) = y; // \
-    // expected-warning {{'shared_locks_required' attribute only applies to functions and methods}}
+    // expected-warning {{'shared_locks_required' attribute only applies to functions}}
   return x;
 };
 
 int slr_test_var SHARED_LOCKS_REQUIRED(mu1); // \
-  // expected-warning {{'shared_locks_required' attribute only applies to functions and methods}}
+  // expected-warning {{'shared_locks_required' attribute only applies to functions}}
 
 void slr_fun_params(int lvar SHARED_LOCKS_REQUIRED(mu1)); // \
-  // expected-warning {{'shared_locks_required' attribute only applies to functions and methods}}
+  // expected-warning {{'shared_locks_required' attribute only applies to functions}}
 
 class SlrFoo {
  private:
   int test_field SHARED_LOCKS_REQUIRED(mu1); // \
-    // expected-warning {{'shared_locks_required' attribute only applies to functions and methods}}
+    // expected-warning {{'shared_locks_required' attribute only applies to functions}}
   void test_method() SHARED_LOCKS_REQUIRED(mu1);
 };
 
 class SHARED_LOCKS_REQUIRED(mu1) SlrTestClass { // \
-  // expected-warning {{'shared_locks_required' attribute only applies to functions and methods}}
+  // expected-warning {{'shared_locks_required' attribute only applies to functions}}
 };
 
 // Check argument parsing.
@@ -1182,13 +1182,13 @@
 
 // illegal attribute arguments
 int slr_function_bad_1() SHARED_LOCKS_REQUIRED(1); // \
-  // expected-warning {{'shared_locks_required' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'shared_locks_required' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
 int slr_function_bad_2() SHARED_LOCKS_REQUIRED("mu"); // \
   // expected-warning {{ignoring 'shared_locks_required' attribute because its argument is invalid}}
 int slr_function_bad_3() SHARED_LOCKS_REQUIRED(muDoublePointer); // \
-  // expected-warning {{'shared_locks_required' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'shared_locks_required' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
 int slr_function_bad_4() SHARED_LOCKS_REQUIRED(umu); // \
-  // expected-warning {{'shared_locks_required' attribute requires arguments whose type is annotated with 'lockable' attribute}}
+  // expected-warning {{'shared_locks_required' attribute requires arguments whose type is annotated with 'capability' attribute}}
 
 
 //-----------------------------------------//
@@ -1430,7 +1430,7 @@
   int a GUARDED_BY(mu1_);
   int b GUARDED_BY(mu2_);
   int c GUARDED_BY(mu3_);  // \
-    // expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'lockable' attribute; type here is 'class InheritanceTest::Derived3'}}
+    // expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'InheritanceTest::Derived3'}}
 
   void foo() EXCLUSIVE_LOCKS_REQUIRED(mu1_, mu2_) {
     a = 0;
diff --git a/test/SemaCXX/warn-undefined-bool-conversion.cpp b/test/SemaCXX/warn-undefined-bool-conversion.cpp
new file mode 100644
index 0000000..1f8baa0
--- /dev/null
+++ b/test/SemaCXX/warn-undefined-bool-conversion.cpp
@@ -0,0 +1,97 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wundefined-bool-conversion %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-bool-conversion -Wundefined-bool-conversion %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wbool-conversion %s
+
+void test1(int &x) {
+  if (x == 1) { }
+  if (&x) { }
+  // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+
+  if (!&x) { }
+  // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+}
+
+class test2 {
+  test2() : x(y) {}
+
+  void foo() {
+    if (this) { }
+    // expected-warning@-1{{'this' pointer cannot be null in well-defined C++ code; pointer may be assumed to always convert to true}}
+
+    if (!this) { }
+    // expected-warning@-1{{'this' pointer cannot be null in well-defined C++ code; pointer may be assumed to always convert to true}}
+  }
+
+  void bar() {
+    if (x == 1) { }
+    if (&x) { }
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+
+    if (!&x) { }
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+  }
+
+  int &x;
+  int y;
+};
+
+namespace function_return_reference {
+  int& get_int();
+  // expected-note@-1 3{{'get_int' returns a reference}}
+  class B {
+  public:
+    static int &stat();
+    // expected-note@-1 3{{'stat' returns a reference}}
+    int &get();
+    // expected-note@-1 6{{'get' returns a reference}}
+  };
+
+  void test() {
+    if (&get_int()) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+    if (&(get_int())) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+    if (!&get_int()) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+
+    if (&B::stat()) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+    if (&(B::stat())) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+    if (!&B::stat()) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+
+    B b;
+    if (&b.get()) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+    if (&(b.get())) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+    if (!&b.get()) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+
+    B* b_ptr = &b;
+    if (&b_ptr->get()) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+    if (&(b_ptr->get())) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+    if (!&b_ptr->get()) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+
+    int& (B::*m_ptr)() = &B::get;
+    if (&(b.*m_ptr)()) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+    if (&((b.*m_ptr)())) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+    if (!&(b.*m_ptr)()) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+
+    int& (*f_ptr)() = &get_int;
+    if (&(*f_ptr)()) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+    if (&((*f_ptr)())) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+    if (!&(*f_ptr)()) {}
+    // expected-warning@-1{{reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true}}
+  }
+}
diff --git a/test/SemaCXX/warn-unreachable.cpp b/test/SemaCXX/warn-unreachable.cpp
index dd07125..b08467a 100644
--- a/test/SemaCXX/warn-unreachable.cpp
+++ b/test/SemaCXX/warn-unreachable.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -fcxx-exceptions -fexceptions -fsyntax-only -verify -fblocks -Wunreachable-code -Wno-unused-value
+// RUN: %clang_cc1 %s -fcxx-exceptions -fexceptions -fsyntax-only -verify -fblocks -std=c++11 -Wunreachable-code-aggressive -Wno-unused-value -Wno-tautological-compare
 
 int &halt() __attribute__((noreturn));
 int &live();
@@ -107,3 +107,303 @@
   dead(); // expected-warning {{will never be executed}}
 }
 
+// Handle 'try' code dominating a dead return.
+enum PR19040_test_return_t
+{ PR19040_TEST_FAILURE };
+namespace PR19040_libtest
+{
+  class A {
+  public:
+    ~A ();
+  };
+}
+PR19040_test_return_t PR19040_fn1 ()
+{
+    try
+    {
+        throw PR19040_libtest::A ();
+    } catch (...)
+    {
+        return PR19040_TEST_FAILURE;
+    }
+    return PR19040_TEST_FAILURE; // expected-warning {{will never be executed}}
+}
+
+__attribute__((noreturn))
+void raze();
+
+namespace std {
+template<typename T> struct basic_string {
+  basic_string(const T* x) {}
+  ~basic_string() {};
+};
+typedef basic_string<char> string;
+}
+
+std::string testStr() {
+  raze();
+  return ""; // expected-warning {{'return' will never be executed}}
+}
+
+std::string testStrWarn(const char *s) {
+  raze();
+  return s; // expected-warning {{will never be executed}}
+}
+
+bool testBool() {
+  raze();
+  return true; // expected-warning {{'return' will never be executed}}
+}
+
+static const bool ConditionVar = 1;
+int test_global_as_conditionVariable() {
+  if (ConditionVar)
+    return 1;
+  return 0; // no-warning
+}
+
+// Handle unreachable temporary destructors.
+class A {
+public:
+  A();
+  ~A();
+};
+
+__attribute__((noreturn))
+void raze(const A& x);
+
+void test_with_unreachable_tmp_dtors(int x) {
+  raze(x ? A() : A()); // no-warning
+}
+
+// Test sizeof - sizeof in enum declaration.
+enum { BrownCow = sizeof(long) - sizeof(char) };
+enum { CowBrown = 8 - 1 };
+
+
+int test_enum_sizeof_arithmetic() {
+  if (BrownCow)
+    return 1;
+  return 2;
+}
+
+int test_enum_arithmetic() {
+  if (CowBrown)
+    return 1;
+  return 2; // expected-warning {{never be executed}}
+}
+
+int test_arithmetic() {
+  if (8 -1)
+    return 1;
+  return 2; // expected-warning {{never be executed}}
+}
+
+int test_treat_const_bool_local_as_config_value() {
+  const bool controlValue = false;
+  if (!controlValue)
+    return 1;
+  test_treat_const_bool_local_as_config_value(); // no-warning
+  return 0;
+}
+
+int test_treat_non_const_bool_local_as_non_config_value() {
+  bool controlValue = false;
+  if (!controlValue)
+    return 1;
+  // There is no warning here because 'controlValue' isn't really
+  // a control value at all.  The CFG will not treat this
+  // branch as unreachable.
+  test_treat_non_const_bool_local_as_non_config_value(); // no-warning
+  return 0;
+}
+
+void test_do_while(int x) {
+  // Handle trivial expressions with
+  // implicit casts to bool.
+  do {
+    break;
+  } while (0); // no-warning
+}
+
+class Frobozz {
+public:
+  Frobozz(int x);
+  ~Frobozz();
+};
+
+Frobozz test_return_object(int flag) {
+  return Frobozz(flag);
+  return Frobozz(42);  // expected-warning {{'return' will never be executed}}
+}
+
+Frobozz test_return_object_control_flow(int flag) {
+  return Frobozz(flag);
+  return Frobozz(flag ? 42 : 24); // expected-warning {{code will never be executed}}
+}
+
+void somethingToCall();
+
+static constexpr bool isConstExprConfigValue() { return true; }
+
+int test_const_expr_config_value() {
+ if (isConstExprConfigValue()) {
+   somethingToCall();
+   return 0;
+ }
+ somethingToCall(); // no-warning
+ return 1;
+}
+int test_const_expr_config_value_2() {
+ if (!isConstExprConfigValue()) {
+   somethingToCall(); // no-warning
+   return 0;
+ }
+ somethingToCall();
+ return 1;
+}
+
+class Frodo {
+public:
+  static const bool aHobbit = true;
+};
+
+void test_static_class_var() {
+  if (Frodo::aHobbit)
+    somethingToCall();
+  else
+    somethingToCall(); // no-warning
+}
+
+void test_static_class_var(Frodo &F) {
+  if (F.aHobbit)
+    somethingToCall();
+  else
+    somethingToCall(); // no-warning
+}
+
+void test_unreachable_for_null_increment() {
+  for (unsigned i = 0; i < 10 ; ) // no-warning
+    break;
+}
+
+void test_unreachable_forrange_increment() {
+  int x[10] = { 0 };
+  for (auto i : x) { // expected-warning {{loop will run at most once (loop increment never executed)}}
+    break;
+  }
+}
+
+void calledFun() {}
+
+// Test "silencing" with parentheses.
+void test_with_paren_silencing(int x) {
+  if (false) calledFun(); // expected-warning {{will never be executed}} expected-note {{silence by adding parentheses to mark code as explicitly dead}}
+  if ((false)) calledFun(); // no-warning
+
+  if (true) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
+    calledFun();
+  else
+    calledFun(); // expected-warning {{will never be executed}}
+
+  if ((true))
+    calledFun();
+  else
+    calledFun(); // no-warning
+  
+  if (!true) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
+    calledFun(); // expected-warning {{code will never be executed}}
+  else
+    calledFun();
+  
+  if ((!true))
+    calledFun(); // no-warning
+  else
+    calledFun();
+  
+  if (!(true))
+    calledFun(); // no-warning
+  else
+    calledFun();
+}
+
+void test_with_paren_silencing_impcast(int x) {
+  if (0) calledFun(); // expected-warning {{will never be executed}} expected-note {{silence by adding parentheses to mark code as explicitly dead}}
+  if ((0)) calledFun(); // no-warning
+
+  if (1) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
+    calledFun();
+  else
+    calledFun(); // expected-warning {{will never be executed}}
+
+  if ((1))
+    calledFun();
+  else
+    calledFun(); // no-warning
+  
+  if (!1) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
+    calledFun(); // expected-warning {{code will never be executed}}
+  else
+    calledFun();
+  
+  if ((!1))
+    calledFun(); // no-warning
+  else
+    calledFun();
+  
+  if (!(1))
+    calledFun(); // no-warning
+  else
+    calledFun();
+}
+
+void tautological_compare(bool x, int y) {
+  if (x > 10)           // expected-note {{silence}}
+    calledFun();        // expected-warning {{will never be executed}}
+  if (10 < x)           // expected-note {{silence}}
+    calledFun();        // expected-warning {{will never be executed}}
+  if (x == 10)          // expected-note {{silence}}
+    calledFun();        // expected-warning {{will never be executed}}
+
+  if (x < 10)           // expected-note {{silence}}
+    calledFun();
+  else
+    calledFun();        // expected-warning {{will never be executed}}
+  if (10 > x)           // expected-note {{silence}}
+    calledFun();
+  else
+    calledFun();        // expected-warning {{will never be executed}}
+  if (x != 10)          // expected-note {{silence}}
+    calledFun();
+  else
+    calledFun();        // expected-warning {{will never be executed}}
+
+  if (y != 5 && y == 5) // expected-note {{silence}}
+    calledFun();        // expected-warning {{will never be executed}}
+
+  if (y > 5 && y < 4)   // expected-note {{silence}}
+    calledFun();        // expected-warning {{will never be executed}}
+
+  if (y < 10 || y > 5)  // expected-note {{silence}}
+    calledFun();
+  else
+    calledFun();        // expected-warning {{will never be executed}}
+
+  // TODO: Extend warning to the following code:
+  if (x < -1)
+    calledFun();
+  if (x == -1)
+    calledFun();
+
+  if (x != -1)
+    calledFun();
+  else
+    calledFun();
+  if (-1 > x)
+    calledFun();
+  else
+    calledFun();
+
+  if (y == -1 && y != -1)
+    calledFun();
+}
diff --git a/test/SemaCXX/warn-unused-attribute.cpp b/test/SemaCXX/warn-unused-attribute.cpp
index 72f96ee..f52de3b 100644
--- a/test/SemaCXX/warn-unused-attribute.cpp
+++ b/test/SemaCXX/warn-unused-attribute.cpp
@@ -1,20 +1,20 @@
 // RUN: %clang_cc1 -fsyntax-only -Wunused-variable -verify %s
-struct __attribute__((warn_unused)) Test
-{
-    Test();
-    ~Test();
-    void use();
+struct __attribute__((warn_unused)) Test {
+  Test();
+  ~Test();
+  void use();
 };
 
-struct TestNormal
-{
-    TestNormal();
+struct TestNormal {
+  TestNormal();
 };
 
-int main()
-{
-   Test unused;         // expected-warning {{unused variable 'unused'}}
-   Test used;
-   TestNormal normal;
-   used.use();
+int main(void) {
+  Test unused;         // expected-warning {{unused variable 'unused'}}
+  Test used;
+  TestNormal normal;
+  used.use();
+
+  int i __attribute__((warn_unused)) = 12; // expected-warning {{'warn_unused' attribute only applies to struct, union or class}}
+  return i;
 }
diff --git a/test/SemaCXX/warn-unused-comparison.cpp b/test/SemaCXX/warn-unused-comparison.cpp
index 0153f21..3afad58 100644
--- a/test/SemaCXX/warn-unused-comparison.cpp
+++ b/test/SemaCXX/warn-unused-comparison.cpp
@@ -3,6 +3,10 @@
 struct A {
   bool operator==(const A&);
   bool operator!=(const A&);
+  bool operator<(const A&);
+  bool operator>(const A&);
+  bool operator<=(const A&);
+  bool operator>=(const A&);
   A operator|=(const A&);
   operator bool();
 };
@@ -15,6 +19,11 @@
           // expected-note {{use '=' to turn this equality comparison into an assignment}}
   x != 7; // expected-warning {{inequality comparison result unused}} \
           // expected-note {{use '|=' to turn this inequality comparison into an or-assignment}}
+  x < 7;  // expected-warning {{relational comparison result unused}}
+  x > 7;  // expected-warning {{relational comparison result unused}}
+  x <= 7; // expected-warning {{relational comparison result unused}}
+  x >= 7; // expected-warning {{relational comparison result unused}}
+
   7 == x; // expected-warning {{equality comparison result unused}}
   p == p; // expected-warning {{equality comparison result unused}} \
           // expected-note {{use '=' to turn this equality comparison into an assignment}} \
@@ -25,6 +34,11 @@
           // expected-note {{use '=' to turn this equality comparison into an assignment}}
   a != b; // expected-warning {{inequality comparison result unused}} \
           // expected-note {{use '|=' to turn this inequality comparison into an or-assignment}}
+  a < b;  // expected-warning {{relational comparison result unused}}
+  a > b;  // expected-warning {{relational comparison result unused}}
+  a <= b; // expected-warning {{relational comparison result unused}}
+  a >= b; // expected-warning {{relational comparison result unused}}
+
   A() == b; // expected-warning {{equality comparison result unused}}
   if (42) x == 7; // expected-warning {{equality comparison result unused}} \
                   // expected-note {{use '=' to turn this equality comparison into an assignment}}
@@ -92,3 +106,30 @@
 
   X<int> x;
 }
+
+namespace PR19724 {
+class stream {
+} cout, cin;
+
+stream &operator<(stream &s, int);
+bool operator<(stream &s, stream &s2);
+
+void test() {
+  cout < 5;    // no warning, operator returns a reference
+  cout < cin;  // expected-warning {{relational comparison result unused}}
+}
+}
+
+namespace PR19791 {
+struct S {
+  void operator!=(int);
+  int operator==(int);
+};
+
+void test() {
+  S s;
+  s != 1;
+  s == 1;  // expected-warning{{equality comparison result unused}}
+           // expected-note@-1{{use '=' to turn this equality comparison into an assignment}}
+}
+}
diff --git a/test/SemaCXX/warn-unused-filescoped.cpp b/test/SemaCXX/warn-unused-filescoped.cpp
index b0af5b3..df4c47e 100644
--- a/test/SemaCXX/warn-unused-filescoped.cpp
+++ b/test/SemaCXX/warn-unused-filescoped.cpp
@@ -32,6 +32,13 @@
   inline void bar(int, int) { }
 };
 
+namespace pr19713 {
+#if __cplusplus >= 201103L
+  static constexpr int constexpr1() { return 1; }
+  constexpr int constexpr2() { return 2; }
+#endif
+}
+
 #else
 #define HEADER
 #include "warn-unused-filescoped.cpp"
@@ -193,4 +200,12 @@
 static void func() {}
 }
 
+namespace pr19713 {
+#if __cplusplus >= 201103L
+  // FIXME: We should warn on both of these.
+  static constexpr int constexpr3() { return 1; } // expected-warning {{unused}}
+  constexpr int constexpr4() { return 2; }
+#endif
+}
+
 #endif
diff --git a/test/SemaCXX/warn-unused-label-error.cpp b/test/SemaCXX/warn-unused-label-error.cpp
new file mode 100644
index 0000000..66b616f
--- /dev/null
+++ b/test/SemaCXX/warn-unused-label-error.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fsyntax-only -Wunused-variable -Wunused-label -verify %s
+
+static int unused_local_static;
+
+namespace PR8455 {
+  void f() {
+    A: // expected-warning {{unused label 'A'}}
+      __attribute__((unused)) int i; // attribute applies to variable
+    B: // attribute applies to label
+      __attribute__((unused)); int j; // expected-warning {{unused variable 'j'}}
+  }
+
+  void g() {
+    C: // unused label 'C' will not appear here because an error has occurred
+      __attribute__((unused))
+      #pragma weak unused_local_static  // expected-error {{expected ';' after __attribute__}}
+      ;
+  }
+
+  void h() {
+    D: // expected-warning {{unused label 'D'}}
+      #pragma weak unused_local_static
+      __attribute__((unused))  // expected-warning {{declaration does not declare anything}}
+      ;
+  }
+}
diff --git a/test/SemaCXX/warn-unused-value.cpp b/test/SemaCXX/warn-unused-value.cpp
index 5e43d3e..4e1347c 100644
--- a/test/SemaCXX/warn-unused-value.cpp
+++ b/test/SemaCXX/warn-unused-value.cpp
@@ -32,7 +32,7 @@
 }
 
 namespace test2 {
-  extern "C" {
+  extern "C++" {
     namespace std {
       template<typename T> struct basic_string {
         struct X {};
diff --git a/test/SemaCXX/warn-unused-variables.cpp b/test/SemaCXX/warn-unused-variables.cpp
index 93d2f6f..8dcbe72 100644
--- a/test/SemaCXX/warn-unused-variables.cpp
+++ b/test/SemaCXX/warn-unused-variables.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wunused-variable -Wunused-label -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wunused-variable -Wunused-label -Wno-c++1y-extensions -verify %s
 template<typename T> void f() {
   T t;
   t = 17;
@@ -115,6 +115,28 @@
   }
 }
 
+namespace PR19305 {
+  template<typename T> int n = 0; // no warning
+  int a = n<int>;
+
+  template<typename T> const int l = 0; // no warning
+  int b = l<int>;
+
+  // PR19558
+  template<typename T> const int o = 0; // no warning
+  template<typename T> const int o<T*> = 0; // no warning
+  int c = o<int*>;
+
+  template<> int o<void> = 0; // no warning
+  int d = o<void>;
+
+  // FIXME: It'd be nice to warn here.
+  template<typename T> int m = 0;
+  template<typename T> int m<T*> = 0;
+
+  template<> const int m<void> = 0; // expected-warning {{unused variable}}
+}
+
 namespace ctor_with_cleanups {
   struct S1 {
     ~S1();
@@ -128,26 +150,3 @@
 }
 
 #include "Inputs/warn-unused-variables.h"
-
-namespace PR8455 {
-  void f() {
-    A: // expected-warning {{unused label 'A'}}
-      __attribute__((unused)) int i; // attribute applies to variable
-    B: // attribute applies to label
-      __attribute__((unused)); int j; // expected-warning {{unused variable 'j'}}
-  }
-
-  void g() {
-    C: // unused label 'C' will not appear here because an error occurs
-      __attribute__((unused))
-      #pragma weak unused_local_static  // expected-error {{expected ';' after __attribute__}}
-      ;
-  }
-
-  void h() {
-    D: // expected-warning {{unused label 'D'}}
-      #pragma weak unused_local_static
-      __attribute__((unused))  // expected-warning {{declaration does not declare anything}}
-      ;
-  }
-}
diff --git a/test/SemaCXX/warn-weak-vtables.cpp b/test/SemaCXX/warn-weak-vtables.cpp
index 135e034..671ff29 100644
--- a/test/SemaCXX/warn-weak-vtables.cpp
+++ b/test/SemaCXX/warn-weak-vtables.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 %s -fsyntax-only -verify -Wweak-vtables -Wweak-template-vtables
+// RUN: %clang_cc1 %s -fsyntax-only -verify -triple %itanium_abi_triple -Wweak-vtables -Wweak-template-vtables
+// RUN: %clang_cc1 %s -fsyntax-only -triple %ms_abi_triple -Werror -Wno-weak-vtables -Wno-weak-template-vtables
 
 struct A { // expected-warning {{'A' has no out-of-line virtual method definitions; its vtable will be emitted in every translation unit}}
   virtual void f() { } 
diff --git a/test/SemaCXX/windows-arm-valist.cpp b/test/SemaCXX/windows-arm-valist.cpp
new file mode 100644
index 0000000..d12be65
--- /dev/null
+++ b/test/SemaCXX/windows-arm-valist.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple thumbv7--windows-msvc -std=c++11 -verify -fsyntax-only %s
+// expected-no-diagnostics
+
+#include <stdarg.h>
+
+template <typename lhs_, typename rhs_>
+struct is_same { enum { value = 0 }; };
+
+template <typename type_>
+struct is_same<type_, type_> { enum { value = 1 }; };
+
+void check() {
+  va_list va;
+  char *cp;
+  static_assert(is_same<decltype(va), decltype(cp)>::value,
+                "type mismatch for va_list");
+}
diff --git a/test/SemaCXX/writable-strings-deprecated.cpp b/test/SemaCXX/writable-strings-deprecated.cpp
index b8f605b..f925833 100644
--- a/test/SemaCXX/writable-strings-deprecated.cpp
+++ b/test/SemaCXX/writable-strings-deprecated.cpp
@@ -1,14 +1,25 @@
 // RUN: %clang_cc1 -fsyntax-only -Wno-deprecated-writable-strings -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-deprecated -Wdeprecated-increment-bool -verify %s
 // RUN: %clang_cc1 -fsyntax-only -fwritable-strings -verify %s
 // RUN: %clang_cc1 -fsyntax-only -Wno-write-strings -verify %s
 // RUN: %clang_cc1 -fsyntax-only -Werror=c++11-compat -verify %s -DERROR
+// RUN: %clang_cc1 -fsyntax-only -Werror=deprecated -Wno-error=deprecated-increment-bool -verify %s -DERROR
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s -Wno-deprecated -Wdeprecated-increment-bool
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s -pedantic-errors -DERROR
 // rdar://8827606
 
 char *fun(void)
 {
    return "foo";
+#if __cplusplus >= 201103L
 #ifdef ERROR
-   // expected-error@-2 {{deprecated}}
+   // expected-error@-3 {{ISO C++11 does not allow conversion from string literal to 'char *'}}
+#else
+   // expected-warning@-5 {{ISO C++11 does not allow conversion from string literal to 'char *'}}
+#endif
+#elif defined(ERROR)
+   // expected-error@-8 {{deprecated}}
 #endif
 }
 
diff --git a/test/SemaObjC/arc-decls.m b/test/SemaObjC/arc-decls.m
index f8e80c7..7fcf576 100644
--- a/test/SemaObjC/arc-decls.m
+++ b/test/SemaObjC/arc-decls.m
@@ -51,20 +51,28 @@
 }
 
 // rdar://9157348
+// rdar://15757510
 
 @interface J
-@property (retain) id newFoo; // expected-note {{property declared here}}
-@property (strong) id copyBar; // expected-note {{property declared here}}
-@property (copy) id allocBaz; // expected-note {{property declared here}}
+@property (retain) id newFoo; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}}
+@property (strong) id copyBar;  // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}}
+@property (copy) id allocBaz; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}}
 @property (copy, nonatomic) id new;
+@property (retain) id newDFoo; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}}
+@property (strong) id copyDBar; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}}
+@property (copy) id allocDBaz; // expected-error {{property follows Cocoa naming convention for returning 'owned' objects}}
 @end
 
 @implementation J
-@synthesize newFoo;	// expected-error {{property's synthesized getter follows Cocoa naming convention for returning}}
-@synthesize copyBar;	// expected-error {{property's synthesized getter follows Cocoa naming convention for returning}}
-@synthesize allocBaz;	// expected-error {{property's synthesized getter follows Cocoa naming convention for returning}}
+@synthesize newFoo;
+@synthesize copyBar;
+@synthesize allocBaz;
 @synthesize new;
 - new {return 0; };
+
+@dynamic newDFoo;
+@dynamic copyDBar; 
+@dynamic allocDBaz;
 @end
 
 
@@ -113,8 +121,13 @@
 
 @interface SomeClassOwnedByController
 @property (readonly) ControllerClass *controller; // expected-note {{property declared here}}
+
+// rdar://15465916
+@property (readonly, weak) ControllerClass *weak_controller;
 @end
 
 @interface SomeClassOwnedByController ()
 @property (readwrite, weak) ControllerClass *controller; // expected-warning {{primary property declaration is implicitly strong while redeclaration in class extension is weak}}
+
+@property (readwrite, weak) ControllerClass *weak_controller;
 @end
diff --git a/test/SemaObjC/arc-invalid.m b/test/SemaObjC/arc-invalid.m
index c736ed4..07b6480 100644
--- a/test/SemaObjC/arc-invalid.m
+++ b/test/SemaObjC/arc-invalid.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fblocks -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fblocks -Wno-objc-root-class -verify %s
 
 // rdar://problem/10982793
 // [p foo] in ARC creates a cleanup.
@@ -16,3 +16,29 @@
   __autoreleasing id p; // expected-note {{'p' declared here}}
   takeBlock(^{ (void) p; }); // expected-error {{cannot capture __autoreleasing variable in a block}}
 }
+
+// rdar://17024681
+@class WebFrame;
+@interface WebView  // expected-note {{previous definition is here}}
+- (WebFrame *)mainFrame;
+@end
+
+@interface WebView  // expected-error {{duplicate interface definition for class 'WebView'}}
+@property (nonatomic, readonly, strong) WebFrame *mainFrame;
+@end
+
+@interface UIWebDocumentView
+- (WebView *)webView;
+@end
+
+@interface UIWebBrowserView : UIWebDocumentView
+@end
+
+@interface StoreBanner @end
+
+@implementation StoreBanner
++ (void)readMetaTagContentForUIWebBrowserView:(UIWebBrowserView *)browserView
+{
+  [[browserView webView] mainFrame];
+}
+@end
diff --git a/test/SemaObjC/arc-jump-block.m b/test/SemaObjC/arc-jump-block.m
index 26a1fc8..9b06c5a 100644
--- a/test/SemaObjC/arc-jump-block.m
+++ b/test/SemaObjC/arc-jump-block.m
@@ -84,7 +84,7 @@
 @end
 
 // Test 2.  rdar://problem/11150919
-int test2(id obj, int state) { // expected-note {{jump enters lifetime of block}} FIXME: wierd location
+int test2(id obj, int state) { // expected-note {{jump enters lifetime of block}} FIXME: weird location
   switch (state) {
   case 0:
     (void) ^{ (void) obj; };
diff --git a/test/SemaObjC/arc-objcbridge-related-attribute.m b/test/SemaObjC/arc-objcbridge-related-attribute.m
new file mode 100644
index 0000000..59daef1
--- /dev/null
+++ b/test/SemaObjC/arc-objcbridge-related-attribute.m
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -fsyntax-only -x objective-c -fobjc-arc -verify -Wno-objc-root-class %s
+// rdar://15499111
+
+typedef struct __attribute__((objc_bridge_related(NSColor,colorWithCGColor:,CGColor))) CGColor *CGColorRef; // expected-note 5 {{declared here}}
+typedef struct __attribute__((objc_bridge_related(NSColor,,CGColor1))) CGColor1 *CGColorRef1;
+typedef struct __attribute__((objc_bridge_related(NSColor,,))) CGColor2 *CGColorRef2;
+
+@interface NSColor // expected-note 5 {{declared here}}
++ (NSColor *)colorWithCGColor:(CGColorRef)cgColor;
+- (CGColorRef)CGColor;
+- (CGColorRef1)CGColor1;
+@end
+
+@interface NSTextField 
+- (void)setBackgroundColor:(NSColor *)color;
+- (NSColor *)backgroundColor;
+@end
+
+void foo(NSColor*); // expected-note {{passing argument to parameter here}}
+
+NSColor * Test1(NSTextField *textField, CGColorRef newColor) {
+  foo(newColor); // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *'; use '+colorWithCGColor:' method for this conversion}}
+  textField.backgroundColor = newColor; // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *__strong'; use '+colorWithCGColor:' method for this conversion}}
+  return newColor; // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *'; use '+colorWithCGColor:' method for this conversion}}
+}
+
+NSColor * Test2(NSTextField *textField, CGColorRef1 newColor) {
+  foo(newColor); // expected-warning {{incompatible pointer types passing 'CGColorRef1' (aka 'struct CGColor1 *') to parameter of type 'NSColor *'}}
+  textField.backgroundColor = newColor; // expected-warning {{incompatible pointer types assigning to 'NSColor *__strong' from 'CGColorRef1' (aka 'struct CGColor1 *')}}
+  return newColor; // expected-warning {{incompatible pointer types returning 'CGColorRef1' (aka 'struct CGColor1 *') from a function with result type 'NSColor *'}}
+}
+
+CGColorRef Test3(NSTextField *textField, CGColorRef newColor) {
+  newColor = textField.backgroundColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'struct CGColor *'); use '-CGColor' method for this conversion}}
+  return textField.backgroundColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'struct CGColor *'); use '-CGColor' method for this conversion}}
+}
+
+CGColorRef2 Test4(NSTextField *textField, CGColorRef2 newColor) {
+  newColor = textField.backgroundColor; // expected-warning {{incompatible pointer types assigning}}
+  return textField.backgroundColor; // expected-warning {{incompatible pointer types returning}}
+}
diff --git a/test/SemaObjC/arc-property-lifetime.m b/test/SemaObjC/arc-property-lifetime.m
index ed72e8c..4874ff3 100644
--- a/test/SemaObjC/arc-property-lifetime.m
+++ b/test/SemaObjC/arc-property-lifetime.m
@@ -154,7 +154,7 @@
 @property  id prop;
 @property  __strong id strong_prop;
 @property  (strong) id strong_attr_prop;
-@property  (strong) __strong id realy_strong_attr_prop;
+@property  (strong) __strong id really_strong_attr_prop;
 + (id) alloc;
 - (id) init;
 - (id) implicit;
@@ -165,7 +165,7 @@
         f.prop = [[Baz alloc] init];
         f.strong_prop = [[Baz alloc] init];
         f.strong_attr_prop = [[Baz alloc] init];
-        f.realy_strong_attr_prop = [[Baz alloc] init];
+        f.really_strong_attr_prop = [[Baz alloc] init];
         f.implicit = [[Baz alloc] init];
 }
 
diff --git a/test/SemaObjC/arc-unavailable-for-weakref.m b/test/SemaObjC/arc-unavailable-for-weakref.m
index eab5f2c..8274802 100644
--- a/test/SemaObjC/arc-unavailable-for-weakref.m
+++ b/test/SemaObjC/arc-unavailable-for-weakref.m
@@ -90,3 +90,5 @@
 __attribute__((objc_arc_weak_reference_unavailable(1)))	// expected-error {{'objc_arc_weak_reference_unavailable' attribute takes no arguments}}
 @interface I3
 @end
+
+int I4 __attribute__((objc_arc_weak_reference_unavailable)); // expected-error {{'objc_arc_weak_reference_unavailable' attribute only applies to Objective-C interfaces}}
diff --git a/test/SemaObjC/arc-unavailable-system-function.m b/test/SemaObjC/arc-unavailable-system-function.m
index b0b70db..54ceaaf 100644
--- a/test/SemaObjC/arc-unavailable-system-function.m
+++ b/test/SemaObjC/arc-unavailable-system-function.m
@@ -3,7 +3,7 @@
 
 # 1 "<command line>"
 # 1 "/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h" 1 3
-id * foo(); // expected-note {{function has been explicitly marked unavailable here}}
+id * foo(); // expected-note {{'foo' has been explicitly marked unavailable here}}
 
 # 1 "arc-unavailable-system-function.m" 2
 void ret() {
diff --git a/test/SemaObjC/arc.m b/test/SemaObjC/arc.m
index 060af24..ba7c09f 100644
--- a/test/SemaObjC/arc.m
+++ b/test/SemaObjC/arc.m
@@ -285,7 +285,7 @@
   b = (nil == vp);
 
   b = (vp == op); // expected-error {{implicit conversion of Objective-C pointer type 'id' to C pointer type 'void *' requires a bridged cast}} expected-note {{use __bridge}} expected-note {{use CFBridgingRetain call}}
-  b = (op == vp); // expected-error {{implicit conversion of C pointer type 'void *' to Objective-C pointer type 'id' requires a bridged cast}} expected-note {{use __bridge}} expected-note {{use CFBridgingRelease call}}
+  b = (op == vp);
 }
 
 void test12(id collection) {
@@ -782,3 +782,19 @@
     }
   }
 }
+
+// rdar://16627903
+extern void abort();
+#define TKAssertEqual(a, b) do{\
+    __typeof(a) a_res = (a);\
+    __typeof(b) b_res = (b);\
+    if ((a_res) != (b_res)) {\
+        abort();\
+    }\
+}while(0)
+
+int garf() {
+  id object;
+  TKAssertEqual(object, nil);
+  TKAssertEqual(object, (id)nil);
+}
diff --git a/test/SemaObjC/attr-availability.m b/test/SemaObjC/attr-availability.m
index fddcd50..7990b12 100644
--- a/test/SemaObjC/attr-availability.m
+++ b/test/SemaObjC/attr-availability.m
@@ -1,11 +1,11 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin9.0.0 -fsyntax-only -verify %s
 
 @protocol P
-- (void)proto_method __attribute__((availability(macosx,introduced=10.1,deprecated=10.2))); // expected-note 2 {{method 'proto_method' declared here}}
+- (void)proto_method __attribute__((availability(macosx,introduced=10.1,deprecated=10.2))); // expected-note 2 {{'proto_method' has been explicitly marked deprecated here}}
 @end
 
 @interface A <P>
-- (void)method __attribute__((availability(macosx,introduced=10.1,deprecated=10.2))); // expected-note {{method 'method' declared here}}
+- (void)method __attribute__((availability(macosx,introduced=10.1,deprecated=10.2))); // expected-note {{'method' has been explicitly marked deprecated here}}
 
 - (void)overridden __attribute__((availability(macosx,introduced=10.3))); // expected-note{{overridden method is here}}
 - (void)overridden2 __attribute__((availability(macosx,introduced=10.3)));
@@ -37,7 +37,7 @@
 // using a deprecated method when that method is re-implemented in a
 // subclass where the redeclared method is not deprecated.
 @interface C
-- (void) method __attribute__((availability(macosx,introduced=10.1,deprecated=10.2))); // expected-note {{method 'method' declared here}}
+- (void) method __attribute__((availability(macosx,introduced=10.1,deprecated=10.2))); // expected-note {{'method' has been explicitly marked deprecated here}}
 @end
 
 @interface D : C
diff --git a/test/SemaObjC/attr-deprecated.m b/test/SemaObjC/attr-deprecated.m
index aa4b479..ca30d0a 100644
--- a/test/SemaObjC/attr-deprecated.m
+++ b/test/SemaObjC/attr-deprecated.m
@@ -2,10 +2,10 @@
 // RUN: %clang_cc1 -x objective-c++ -fsyntax-only -verify -Wno-objc-root-class %s
 
 @interface A {
-  int X __attribute__((deprecated)); // expected-note 2 {{declared here}}
+  int X __attribute__((deprecated)); // expected-note 2 {{'X' has been explicitly marked deprecated here}}
 }
-+ (void)F __attribute__((deprecated)); // expected-note 2 {{declared here}}
-- (void)f __attribute__((deprecated)); // expected-note 4 {{declared here}}
++ (void)F __attribute__((deprecated)); // expected-note 2 {{'F' has been explicitly marked deprecated here}}
+- (void)f __attribute__((deprecated)); // expected-note 4 {{'f' has been explicitly marked deprecated here}}
 @end
 
 @implementation A
@@ -43,7 +43,7 @@
 @end
 
 @protocol P
-- (void)p __attribute__((deprecated)); // expected-note {{declared here}}
+- (void)p __attribute__((deprecated)); // expected-note {{'p' has been explicitly marked deprecated here}}
 @end
 
 void t1(A *a)
@@ -72,7 +72,7 @@
 
 @interface Bar 
 
-@property (assign, setter = MySetter:) int FooBar __attribute__ ((deprecated)); // expected-note 2 {{declared here}}
+@property (assign, setter = MySetter:) int FooBar __attribute__ ((deprecated)); // expected-note 2 {{'FooBar' has been explicitly marked deprecated here}}
 - (void) MySetter : (int) value;
 @end
 
@@ -84,7 +84,7 @@
 
 
 __attribute ((deprecated))  
-@interface DEPRECATED { // expected-note 2 {{declared here}}
+@interface DEPRECATED { // expected-note 2 {{'DEPRECATED' has been explicitly marked deprecated here}}
   @public int ivar; 
   DEPRECATED *ivar2; // no warning.
 } 
@@ -108,8 +108,8 @@
 
 
 @interface Test2
-@property int test2 __attribute__((deprecated)); // expected-note 4 {{declared here}} \
-						 // expected-note 2 {{property 'test2' is declared deprecated here}}
+@property int test2 __attribute__((deprecated)); // expected-note 2 {{property 'test2' is declared deprecated here}} expected-note 3 {{'test2' has been explicitly marked deprecated here}} \
+						 // expected-note {{'setTest2:' has been explicitly marked deprecated here}}
 @end
 
 void test(Test2 *foo) {
@@ -127,7 +127,7 @@
 
 typedef struct {
 	int x;
-} footype __attribute((deprecated)); // expected-note 2 {{declared here}}
+} footype __attribute((deprecated)); // expected-note 2 {{'footype' has been explicitly marked deprecated here}}
 
 @interface foo {
 	footype a; // expected-warning {{'footype' is deprecated}}
@@ -142,7 +142,7 @@
 +(void)cmeth;
 @end
 
-typedef NewI DeprI __attribute__((deprecated("blah"))); // expected-note 4 {{'DeprI' declared here}}
+typedef NewI DeprI __attribute__((deprecated("blah"))); // expected-note 4 {{'DeprI' has been explicitly marked deprecated here}}
 
 @interface SI : DeprI // expected-warning {{'DeprI' is deprecated: blah}}
 -(DeprI*)meth; // expected-warning {{'DeprI' is deprecated: blah}}
@@ -154,3 +154,76 @@
   return 0;
 }
 @end
+
+// <rdar://problem/15407366> and <rdar://problem/15466783>:
+// - Using deprecated class name inside class should not warn about deprecation.
+// - Implementations of deprecated classes should not result in deprecation warnings.
+__attribute__((deprecated))
+@interface DeprecatedClassA
+@end
+
+__attribute__((deprecated))
+@interface DeprecatedClassB
+// The self-reference return value should not be
+// flagged as the use of a deprecated declaration.
++ (DeprecatedClassB *)sharedInstance; // no-warning
+
+// Since this class is deprecated, returning a reference
+// to another deprecated class is fine as they may
+// have been deprecated together.  From a user's
+// perspective they are all deprecated.
++ (DeprecatedClassA *)somethingElse; // no-warning
+@end
+
+@implementation DeprecatedClassB
++ (DeprecatedClassB *)sharedInstance
+{
+  // This self-reference should not
+  // be flagged as a use of a deprecated
+  // declaration.
+  static DeprecatedClassB *x; // no-warning
+  return x;
+}
++ (DeprecatedClassA *)somethingElse {
+  // Since this class is deprecated, referencing
+  // another deprecated class is also OK.
+  static DeprecatedClassA *x; // no-warning
+  return x;
+}
+
+@end
+
+// rdar://16068470
+@interface TestBase
+@property (nonatomic, strong) id object __attribute__((deprecated("deprecated"))); // expected-note {{'object' has been explicitly marked deprecated here}} \
+expected-note {{property 'object' is declared deprecated here}} \
+expected-note {{'setObject:' has been explicitly marked deprecated here}}
+@end
+
+@interface TestDerived : TestBase
+@property (nonatomic, strong) id object;
+@end
+
+@interface TestUse @end
+
+@implementation TestBase @end
+
+@implementation TestDerived @end
+
+@implementation TestUse
+
+- (void) use
+{
+    TestBase *base = (id)0;
+    TestDerived *derived = (id)0;
+    id object = (id)0;
+
+    base.object = object; // expected-warning {{'object' is deprecated: deprecated}}
+    derived.object = object;
+
+    [base setObject:object];  // expected-warning {{'setObject:' is deprecated: deprecated}}
+    [derived setObject:object];
+}
+
+@end
+
diff --git a/test/SemaObjC/attr-designated-init.m b/test/SemaObjC/attr-designated-init.m
new file mode 100644
index 0000000..5350657
--- /dev/null
+++ b/test/SemaObjC/attr-designated-init.m
@@ -0,0 +1,412 @@
+// RUN: %clang_cc1 -fsyntax-only -Wno-incomplete-implementation -verify -fblocks %s
+
+#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
+
+void fnfoo(void) NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface or class extension declarations}}
+
+@protocol P1
+-(id)init NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface or class extension declarations}}
+@end
+
+__attribute__((objc_root_class))
+@interface I1
+-(void)meth NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface or class extension declarations}}
+-(id)init NS_DESIGNATED_INITIALIZER;
++(id)init NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface or class extension declarations}}
+@end
+
+@interface I1(cat)
+-(id)init2 NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface or class extension declarations}}
+@end
+
+@interface I1()
+-(id)init3 NS_DESIGNATED_INITIALIZER;
+@end
+
+@implementation I1
+-(void)meth {}
+-(id)init NS_DESIGNATED_INITIALIZER { return 0; } // expected-error {{only applies to init methods of interface or class extension declarations}}
++(id)init { return 0; }
+-(id)init3 { return 0; }
+-(id)init4 NS_DESIGNATED_INITIALIZER { return 0; } // expected-error {{only applies to init methods of interface or class extension declarations}} \
+									 			   // expected-warning {{convenience initializer missing a 'self' call to another initializer}}
+@end
+
+__attribute__((objc_root_class))
+@interface B1
+-(id)initB1 NS_DESIGNATED_INITIALIZER; // expected-note 6 {{method marked as designated initializer of the class here}}
+-(id)initB2;
+@end
+
+@interface B1()
+-(id)initB3 NS_DESIGNATED_INITIALIZER; // expected-note 4 {{method marked as designated initializer of the class here}}
+@end;
+
+@implementation B1
+-(id)initB1 { return 0; }
+-(id)initB2 { return 0; } // expected-warning {{convenience initializer missing a 'self' call to another initializer}}
+-(id)initB3 { return 0; }
+@end
+
+@interface S1 : B1
+-(id)initS1 NS_DESIGNATED_INITIALIZER; // expected-note {{method marked as designated initializer of the class here}}
+-(id)initS2 NS_DESIGNATED_INITIALIZER;
+-(id)initS3 NS_DESIGNATED_INITIALIZER; // expected-note 2 {{method marked as designated initializer of the class here}}
+-(id)initB1;
+@end
+
+@interface S1()
+-(id)initS4 NS_DESIGNATED_INITIALIZER; // expected-note 2 {{method marked as designated initializer of the class here}}
+@end
+
+@implementation S1
+-(id)initS1 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
+  return 0;
+}
+-(id)initS2 {
+  return [super initB1];
+}
+-(id)initS3 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
+  return [super initB2]; // expected-warning {{designated initializer invoked a non-designated initializer}}
+}
+-(id)initS4 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
+  return [self initB1]; // expected-warning {{designated initializer should only invoke a designated initializer on 'super'}}
+}
+-(id)initB1 {
+  return [self initS1];
+}
+-(id)initB3 {
+  return [self initS1];
+}
+@end
+
+@interface S2 : B1
+-(id)initB1;
+@end
+
+@interface SS2 : S2
+-(id)initSS1 NS_DESIGNATED_INITIALIZER;
+@end
+
+@implementation SS2 // expected-warning {{method override for the designated initializer of the superclass '-initB1' not found}} \
+                    // expected-warning {{method override for the designated initializer of the superclass '-initB3' not found}}
+-(id)initSS1 {
+  return [super initB1];
+}
+@end
+
+@interface S3 : B1
+-(id)initS1 NS_DESIGNATED_INITIALIZER; // expected-note {{method marked as designated initializer of the class here}}
+@end
+
+@interface SS3 : S3
+-(id)initSS1 NS_DESIGNATED_INITIALIZER; // expected-note 2 {{method marked as designated initializer of the class here}}
+@end
+
+@implementation SS3 // expected-warning {{method override for the designated initializer of the superclass '-initS1' not found}}
+-(id)initSS1 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
+  return [super initB1]; // expected-warning {{designated initializer invoked a non-designated initializer}}
+}
+@end
+
+@interface S4 : B1
+-(id)initB1;
+-(id)initB3;
+@end
+
+@implementation S4
+-(id)initB1 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
+  return 0;
+}
+-(id)initB3 {
+  return [super initB3];
+}
+@end
+
+@interface S5 : B1
+-(void)meth;
+@end
+
+@implementation S5
+-(id)initB1 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
+  return 0;
+}
+-(id)initB3 {
+  [self initB1]; // expected-warning {{designated initializer should only invoke a designated initializer on 'super'}}
+  S5 *s;
+  [s initB1];
+  [self meth];
+  void (^blk)(void) = ^{
+    [self initB1]; // expected-warning {{designated initializer should only invoke a designated initializer on 'super'}}
+  };
+  return [super initB3];
+}
+-(void)meth {}
+@end
+
+@interface S6 : B1
+-(id)initS1 NS_DESIGNATED_INITIALIZER;
+-(id)initS2;
+-(id)initS3;
+-(id)initS4;
+@end
+
+@implementation S6 // expected-warning {{method override for the designated initializer of the superclass '-initB1' not found}} \
+                   // expected-warning {{method override for the designated initializer of the superclass '-initB3' not found}}
+-(id)initS1 {
+  return [super initB1];
+}
+-(id)initS2 { // expected-warning {{convenience initializer missing a 'self' call to another initializer}}
+  return [super initB1]; // expected-warning {{convenience initializer should not invoke an initializer on 'super'}}
+}
+-(id)initS3 {
+  return [self initB1];
+}
+-(id)initS4 {
+  return [self initS1];
+}
+-(id)initS5 {
+  [super initB1]; // expected-warning {{convenience initializer should not invoke an initializer on 'super'}}
+  void (^blk)(void) = ^{
+    [super initB1]; // expected-warning {{convenience initializer should not invoke an initializer on 'super'}}
+  };
+  return [self initS1];
+}
+-(id)initS6 { // expected-warning {{convenience initializer missing a 'self' call to another initializer}}
+  S6 *s;
+  return [s initS1];
+}
+@end
+
+@interface SS4 : S4
+-(id)initB1;
+@end
+
+@implementation SS4
+-(id)initB1 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
+  return 0;
+}
+@end
+
+@interface S7 : B1
+-(id)initB1;
+-(id)initB3;
+-(id)initNewOne;
+@end
+
+@interface SS7 : S7
+-(id)initB1;
+@end
+
+@implementation SS7
+-(id)initB1 {
+  return 0;
+}
+@end
+
+__attribute__((objc_root_class))
+@interface B2
+-(id)init;
+@end
+
+@interface S8: B2
+-(id)initS8 NS_DESIGNATED_INITIALIZER;
+@end
+
+@implementation S8
+-(id)initS8
+{
+  return [super init];
+}
+@end
+
+@interface S9 : B1
+-(id)initB1;
+-(id)initB3;
+@end
+
+@interface S9(secondInit)
+-(id)initNewOne;
+@end
+
+@interface SS9 : S9
+-(id)initB1;
+@end
+
+@implementation SS9
+-(id)initB1 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
+  return 0;
+}
+@end
+
+// rdar://16261494
+@class GEOPDAnalyticMetadata; // expected-note {{forward declaration of class here}}
+
+@implementation GEOPDAnalyticMetadata (PlaceCardExtras) // expected-error {{cannot find interface declaration for 'GEOPDAnalyticMetadata'}}
+- (instancetype)initInProcess
+{
+    return ((void*)0);
+}
+@end
+
+// rdar://16305460
+__attribute__((objc_root_class))
+@interface MyObject
+- (instancetype)initWithStuff:(id)stuff __attribute__((objc_designated_initializer));
+- (instancetype)init __attribute__((unavailable));
+@end
+
+@implementation MyObject
+- (instancetype)init
+{
+   return ((void*)0);
+}
+@end
+
+// rdar://16323233
+__attribute__((objc_root_class))
+@interface B4 
+-(id)initB4 NS_DESIGNATED_INITIALIZER; // expected-note 4 {{method marked as designated initializer of the class here}}
+-(id)initNonDI;
+@end
+
+@interface rdar16323233 : B4
+-(id)initS4 NS_DESIGNATED_INITIALIZER;
+@end
+
+@implementation rdar16323233
+-(id)initS4 {
+    static id sSharedObject = (void*)0;
+    (void)^(void) {
+        sSharedObject = [super initB4];
+    };
+    return 0;
+}
+-(id)initB4 {
+   return [self initS4];
+}
+@end
+
+@interface S1B4 : B4
+@end
+@implementation S1B4
+-(id)initB4 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
+   return [super initNonDI]; // expected-warning {{designated initializer invoked a non-designated initializer}}
+}
+@end
+
+@interface S2B4 : B4
+-(id)initB4;
+@end
+@implementation S2B4
+-(id)initB4 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
+   return [super initNonDI]; // expected-warning {{designated initializer invoked a non-designated initializer}}
+}
+@end
+
+@interface S3B4 : B4
+@end
+@implementation S3B4
+-(id)initNew {
+  return [super initB4];
+}
+-(id)initB4 {
+   return [self initNew];
+}
+@end
+
+@interface S4B4 : B4
+-(id)initNew;
+@end
+@implementation S4B4
+-(id)initNew {
+  return [super initB4];
+}
+-(id)initB4 {
+   return [self initNew];
+}
+@end
+
+@interface S5B4 : B4
+-(id)initB4;
+@end
+@implementation S5B4
+-(id)initNew {
+  return [super initB4];
+}
+-(id)initB4 {
+   return [self initNew];
+}
+@end
+
+@interface S6B4 : B4
+-(id)initNew;
+-(id)initB4;
+@end
+@implementation S6B4
+-(id)initNew {
+  return [super initB4];
+}
+-(id)initB4 {
+   return [self initNew];
+}
+@end
+
+__attribute__((objc_root_class))
+@interface NSObject
+-(instancetype) init NS_DESIGNATED_INITIALIZER; // expected-note {{method marked as designated initializer of the class here}}
+@end
+
+@interface Test3 : NSObject
+@end
+
+@implementation Test3
+-(instancetype) initWithBasePath:(id)path {
+  return [super init];
+}
+-(instancetype) init {
+  return [self initWithBasePath:0];
+}
+@end
+
+@interface Test1 : NSObject
+-(instancetype) init NS_DESIGNATED_INITIALIZER;
+@end
+@implementation Test1
+-(instancetype) init {
+  return self;
+}
+@end
+
+
+@interface Test2 : NSObject
+@end
+@interface SubTest2 : Test2
+@end
+@implementation SubTest2
+-(instancetype) init { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
+  return self;
+}
+@end
+
+__attribute__((objc_root_class))
+@interface RootNoDI
+-(id)init;
+@end
+
+@interface Base : RootNoDI
+@end
+
+@implementation Base
+@end
+
+@interface Derived : Base
+- (instancetype)initWithInt:(int)n NS_DESIGNATED_INITIALIZER;
+@end
+
+@implementation Derived
+- (instancetype)initWithInt:(int)n
+{
+  return [super init];
+}
+@end
diff --git a/test/SemaObjC/attr-ns-bridged.m b/test/SemaObjC/attr-ns-bridged.m
deleted file mode 100644
index 1ab60a2..0000000
--- a/test/SemaObjC/attr-ns-bridged.m
+++ /dev/null
@@ -1,15 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-
-typedef struct __attribute__((ns_bridged)) test0s *test0ref;
-
-void test0func(void) __attribute__((ns_bridged)); // expected-error {{'ns_bridged' attribute only applies to structs}}
-
-union __attribute__((ns_bridged)) test0u; // expected-error {{'ns_bridged' attribute only applies to structs}}
-
-struct __attribute__((ns_bridged(Test1))) test1s;
-
-@class Test2;
-struct __attribute__((ns_bridged(Test2))) test2s;
-
-void Test3(void); // expected-note {{declared here}}
-struct __attribute__((ns_bridged(Test3))) test3s; // expected-error {{parameter of 'ns_bridged' attribute does not name an Objective-C class}}
diff --git a/test/SemaObjC/block-type-safety.m b/test/SemaObjC/block-type-safety.m
index 56342ba..b2c4398 100644
--- a/test/SemaObjC/block-type-safety.m
+++ b/test/SemaObjC/block-type-safety.m
@@ -23,6 +23,7 @@
 }
 
 @protocol NSObject;
+@class NSObject;
 
 void r2 (id<NSObject> (^f) (void)) {
   id o = f();
@@ -155,3 +156,45 @@
         return NSOrderedSame;
    }];
 }
+
+// rdar://16739120
+@protocol P1 @end
+@protocol P2 @end
+
+void Test() {
+void (^aBlock)();
+id anId = aBlock;  // OK
+
+id<P1,P2> anQualId = aBlock;  // expected-error {{initializing 'id<P1,P2>' with an expression of incompatible type 'void (^)()'}}
+
+NSArray* anArray = aBlock; // expected-error {{initializing 'NSArray *' with an expression of incompatible type 'void (^)()'}}
+
+aBlock = anId; // OK
+
+id<P1,P2> anQualId1;
+aBlock = anQualId1; // expected-error {{assigning to 'void (^)()' from incompatible type 'id<P1,P2>'}}
+
+NSArray* anArray1;
+aBlock = anArray1; // expected-error {{assigning to 'void (^)()' from incompatible type 'NSArray *'}}
+}
+
+void Test2() {
+  void (^aBlock)();
+  id<NSObject> anQualId1 = aBlock; // Ok
+  id<NSObject, NSCopying> anQualId2 = aBlock; // Ok
+  id<NSObject, NSCopying, NSObject, NSCopying> anQualId3 = aBlock; // Ok
+  id <P1>  anQualId4  = aBlock; // expected-error {{initializing 'id<P1>' with an expression of incompatible type 'void (^)()'}}
+  id<NSObject, P1, NSCopying> anQualId5 = aBlock; // expected-error {{initializing 'id<NSObject,P1,NSCopying>' with an expression of incompatible type 'void (^)()'}}
+  id<NSCopying> anQualId6 = aBlock; // Ok
+}
+
+void Test3() {
+  void (^aBlock)();
+  NSObject *NSO = aBlock; // Ok
+  NSObject<NSObject> *NSO1 = aBlock; // Ok
+  NSObject<NSObject, NSCopying> *NSO2 = aBlock; // Ok
+  NSObject<NSObject, NSCopying, NSObject, NSCopying> *NSO3 = aBlock; // Ok
+  NSObject <P1>  *NSO4  = aBlock; // expected-error {{initializing 'NSObject<P1> *' with an expression of incompatible type 'void (^)()'}}
+  NSObject<NSObject, P1, NSCopying> *NSO5 = aBlock; // expected-error {{initializing 'NSObject<NSObject,P1,NSCopying> *' with an expression of incompatible type 'void (^)()'}}
+  NSObject<NSCopying> *NSO6 = aBlock; // Ok
+}
diff --git a/test/SemaObjC/builtin_objc_lib_functions.m b/test/SemaObjC/builtin_objc_lib_functions.m
index d8713dd..2496bf2 100644
--- a/test/SemaObjC/builtin_objc_lib_functions.m
+++ b/test/SemaObjC/builtin_objc_lib_functions.m
@@ -1,29 +1,29 @@
 // RUN: %clang_cc1 -x objective-c %s -fsyntax-only -verify
 // rdar://8592641
 Class f0() { return objc_getClass("a"); } // expected-warning {{implicitly declaring library function 'objc_getClass' with type 'id (const char *)'}} \
-					  // expected-note {{please include the header <objc/runtime.h> or explicitly provide a declaration for 'objc_getClass'}}
+					  // expected-note {{include the header <objc/runtime.h> or explicitly provide a declaration for 'objc_getClass'}}
 
 // rdar://8735023
 Class f1() { return objc_getMetaClass("a"); } // expected-warning {{implicitly declaring library function 'objc_getMetaClass' with type 'id (const char *)'}} \
-					  // expected-note {{please include the header <objc/runtime.h> or explicitly provide a declaration for 'objc_getMetaClass'}}
+					  // expected-note {{include the header <objc/runtime.h> or explicitly provide a declaration for 'objc_getMetaClass'}}
 
 void f2(id val) { objc_enumerationMutation(val); } // expected-warning {{implicitly declaring library function 'objc_enumerationMutation' with type 'void (id)'}} \
-						   // expected-note {{please include the header <objc/runtime.h> or explicitly provide a declaration for 'objc_enumerationMutation'}}
+						   // expected-note {{include the header <objc/runtime.h> or explicitly provide a declaration for 'objc_enumerationMutation'}}
 
 long double f3(id self, SEL op) { return objc_msgSend_fpret(self, op); } // expected-warning {{implicitly declaring library function 'objc_msgSend_fpret' with type 'long double (id, SEL, ...)'}} \
-    // expected-note {{please include the header <objc/message.h> or explicitly provide a declaration for 'objc_msgSend_fpret'}}
+    // expected-note {{include the header <objc/message.h> or explicitly provide a declaration for 'objc_msgSend_fpret'}}
 
 id f4(struct objc_super *super, SEL op) { // expected-warning {{declaration of 'struct objc_super' will not be visible outside of this function}}
   return objc_msgSendSuper(super, op); // expected-warning {{implicitly declaring library function 'objc_msgSendSuper' with type 'id (struct objc_super *, SEL, ...)'}} \
-					// expected-note {{please include the header <objc/message.h> or explicitly provide a declaration for 'objc_msgSendSuper'}}
+					// expected-note {{include the header <objc/message.h> or explicitly provide a declaration for 'objc_msgSendSuper'}}
 }
 
 id f5(id val, id *dest) {
   return objc_assign_strongCast(val, dest); // expected-warning {{implicitly declaring library function 'objc_assign_strongCast' with type 'id (id, id *)'}} \
-					    // expected-note {{please include the header <objc/objc-auto.h> or explicitly provide a declaration for 'objc_assign_strongCast'}}
+					    // expected-note {{include the header <objc/objc-auto.h> or explicitly provide a declaration for 'objc_assign_strongCast'}}
 }
 
 int f6(Class exceptionClass, id exception) {
   return objc_exception_match(exceptionClass, exception); // expected-warning {{implicitly declaring library function 'objc_exception_match' with type 'int (id, id)'}} \
-  							  // expected-note {{please include the header <objc/objc-exception.h> or explicitly provide a declaration for 'objc_exception_match'}}
+  							  // expected-note {{include the header <objc/objc-exception.h> or explicitly provide a declaration for 'objc_exception_match'}}
 }
diff --git a/test/SemaObjC/builtin_objc_nslog.m b/test/SemaObjC/builtin_objc_nslog.m
index c940b16..cc6f194 100644
--- a/test/SemaObjC/builtin_objc_nslog.m
+++ b/test/SemaObjC/builtin_objc_nslog.m
@@ -4,10 +4,10 @@
 
 void f1(id arg) {
   NSLog(@"%@", arg); // expected-warning {{implicitly declaring library function 'NSLog' with type 'void (id, ...)'}} \
-  // expected-note {{please include the header <Foundation/NSObjCRuntime.h> or explicitly provide a declaration for 'NSLog'}}
+  // expected-note {{include the header <Foundation/NSObjCRuntime.h> or explicitly provide a declaration for 'NSLog'}}
 }
 
 void f2(id str, va_list args) {
   NSLogv(@"%@", args); // expected-warning {{implicitly declaring library function 'NSLogv' with type }} \
-  // expected-note {{please include the header <Foundation/NSObjCRuntime.h> or explicitly provide a declaration for 'NSLogv'}}
+  // expected-note {{include the header <Foundation/NSObjCRuntime.h> or explicitly provide a declaration for 'NSLogv'}}
 }
diff --git a/test/SemaObjC/category-1.m b/test/SemaObjC/category-1.m
index 18b872a..89ac550 100644
--- a/test/SemaObjC/category-1.m
+++ b/test/SemaObjC/category-1.m
@@ -2,7 +2,8 @@
 
 @interface MyClass1 @end
 
-@protocol p1,p2,p3;
+@protocol p1,p2,p3; // expected-note {{protocol 'p1' has no definition}} \
+                    // expected-note {{protocol 'p2' has no definition}}
 
 @interface MyClass1 (Category1)  <p1> // expected-warning {{cannot find protocol definition for 'p1'}} expected-note {{previous definition is here}}
 @end
@@ -65,13 +66,13 @@
 -(void) im0; // expected-note {{method 'im0' declared here}}
 @end
 
-@interface MultipleCat_I @end // expected-note {{required for direct or indirect protocol 'MultipleCat_P'}}
+@interface MultipleCat_I @end
 
 @interface MultipleCat_I()  @end
 
 @interface MultipleCat_I() <MultipleCat_P>  @end
 
-@implementation MultipleCat_I // expected-warning {{method 'im0' in protocol not implemented}}
+@implementation MultipleCat_I // expected-warning {{method 'im0' in protocol 'MultipleCat_P' not implemented}}
 @end
 
 // <rdar://problem/7680391> - Handle nameless categories with no name that refer
diff --git a/test/SemaObjC/check-objcbridge-related-attribute-lookup.m b/test/SemaObjC/check-objcbridge-related-attribute-lookup.m
new file mode 100644
index 0000000..39b66bc
--- /dev/null
+++ b/test/SemaObjC/check-objcbridge-related-attribute-lookup.m
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -fsyntax-only -x objective-c -verify -Wno-objc-root-class %s
+// rdar://15499111
+
+typedef struct __attribute__((objc_bridge_related(NSColor,colorXWithCGColor:,CXGColor))) CGColor *CGColorRef; // expected-note 2 {{declared here}}
+
+typedef struct __attribute__((objc_bridge_related(XNSColor,colorWithCGColor:,CGColor))) CGColor1 *CGColorRef1; // expected-note 2 {{declared here}}
+
+typedef struct __attribute__((objc_bridge_related(PNsColor,colorWithCGColor:,CGColor))) CGColor2 *CGColorRef2; // expected-note 2 {{declared here}}
+
+@interface NSColor
++ (NSColor *)colorWithCGColor:(CGColorRef)cgColor;
+- (CGColorRef)CGColor;
+@end
+
+@interface NSTextField 
+- (void)setBackgroundColor:(NSColor *)color;
+- (NSColor *)backgroundColor;
+@end
+
+typedef int PNsColor; // expected-note 2 {{declared here}}
+
+NSColor * Test1(NSTextField *textField, CGColorRef newColor) {
+ textField.backgroundColor = newColor; // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *'; use '+colorXWithCGColor:' method for this conversion}} \
+					// expected-warning {{incompatible pointer types assigning to 'NSColor *' from 'CGColorRef' (aka 'struct CGColor *')}}
+ newColor = textField.backgroundColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'struct CGColor *'); use '-CXGColor' method for this conversion}} \
+					// expected-warning {{incompatible pointer types assigning to 'CGColorRef' (aka 'struct CGColor *') from 'NSColor *'}}
+}
+NSColor * Test2(NSTextField *textField, CGColorRef1 newColor) {
+ textField.backgroundColor = newColor; // expected-error {{could not find Objective-C class 'XNSColor' to convert 'CGColorRef1' (aka 'struct CGColor1 *') to 'NSColor *'}} \
+				       // expected-warning {{incompatible pointer types assigning to 'NSColor *' from 'CGColorRef1' (aka 'struct CGColor1 *')}}
+ newColor = textField.backgroundColor ; // expected-error {{could not find Objective-C class 'XNSColor' to convert 'NSColor *' to 'CGColorRef1' (aka 'struct CGColor1 *')}} \
+					// expected-warning {{incompatible pointer types assigning to 'CGColorRef1' (aka 'struct CGColor1 *') from 'NSColor *'}}
+}
+
+NSColor * Test3(NSTextField *textField, CGColorRef2 newColor) {
+ textField.backgroundColor = newColor; // expected-error {{'PNsColor' must be name of an Objective-C class to be able to convert 'CGColorRef2' (aka 'struct CGColor2 *') to 'NSColor *'}} \
+					// expected-warning {{incompatible pointer types assigning to 'NSColor *' from 'CGColorRef2' (aka 'struct CGColor2 *')}}
+ newColor = textField.backgroundColor; // expected-error {{'PNsColor' must be name of an Objective-C class to be able to convert 'NSColor *' to 'CGColorRef2' (aka 'struct CGColor2 *')}} \
+					// expected-warning {{incompatible pointer types assigning to 'CGColorRef2' (aka 'struct CGColor2 *') from 'NSColor *'}}
+}
+
diff --git a/test/SemaObjC/class-def-test-1.m b/test/SemaObjC/class-def-test-1.m
index 7931cc3..98a887e 100644
--- a/test/SemaObjC/class-def-test-1.m
+++ b/test/SemaObjC/class-def-test-1.m
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
 
-@protocol SUPER;
+@protocol SUPER; // expected-note {{protocol 'SUPER' has no definition}}
 
 @interface SUPER <SUPER> @end // expected-warning {{cannot find protocol definition for 'SUPER'}}
 
diff --git a/test/SemaObjC/class-extension-dup-methods.m b/test/SemaObjC/class-extension-dup-methods.m
index 692ff8c..5f463ae 100644
--- a/test/SemaObjC/class-extension-dup-methods.m
+++ b/test/SemaObjC/class-extension-dup-methods.m
@@ -13,3 +13,16 @@
 + (int)  InstMeth;
 - (int) OK;
 @end
+
+// rdar://16312105
+@class NSObject;
+
+__attribute__((objc_root_class)) @interface AppDelegate
++ (void)someMethodWithArgument:(NSObject *)argument;
++ (void)someMethodWithArgument:(NSObject *)argument : (NSObject*) argument2; // expected-note {{previous declaration is here}}
+@end
+
+@interface AppDelegate ()
+- (void)someMethodWithArgument:(float)argument; // OK. No warning to be issued here.
++ (void)someMethodWithArgument:(float)argument : (float)argument2; // expected-error {{duplicate declaration of method 'someMethodWithArgument::'}}
+@end
diff --git a/test/SemaObjC/class-property-access.m b/test/SemaObjC/class-property-access.m
index 735b51a..d57b986 100644
--- a/test/SemaObjC/class-property-access.m
+++ b/test/SemaObjC/class-property-access.m
@@ -11,3 +11,46 @@
   return Test.one.two;
 }
 
+// rdar://16650575
+__attribute__((objc_root_class))
+@interface RootClass { 
+  Class isa; 
+}
+
+@property int property;
+-(int)method;
+- (void) setMethod : (int)arg;
++(int)classMethod;
+@end
+
+@interface Subclass : RootClass @end
+void Test1() { 
+    // now okay
+    (void)RootClass.property;
+    (void)Subclass.property;
+    (void)RootClass.method;
+    (void)Subclass.method;
+
+    RootClass.property = 1;
+    Subclass.property = 2;
+    RootClass.method = 3;
+    Subclass.method = 4;
+
+    // okay
+    (void)RootClass.classMethod;
+    (void)Subclass.classMethod;
+
+    // also okay
+    (void)[RootClass property];
+    (void)[Subclass property];
+    [RootClass method];
+    [Subclass method];
+    [RootClass classMethod];
+    [Subclass classMethod];
+
+    // also okay
+    [RootClass setProperty : 1];
+    [Subclass setProperty : 2];
+    [RootClass setMethod : 3];
+    [Subclass setMethod : 4];
+}
diff --git a/test/SemaObjC/class-proto-1.m b/test/SemaObjC/class-proto-1.m
index 02c40aa..51a8993 100644
--- a/test/SemaObjC/class-proto-1.m
+++ b/test/SemaObjC/class-proto-1.m
@@ -2,7 +2,8 @@
 
 @interface INTF1 @end
 
-@protocol p1,p2,p3;
+@protocol p1,p2,p3; // expected-note {{protocol 'p2' has no definition}} \
+                    // expected-note {{protocol 'p3' has no definition}}
 
 @protocol p1;
 
@@ -34,3 +35,14 @@
 
 @interface I4 : U2 <p1,p2>
 @end
+
+// rdar://16111182
+@interface NSObject @end
+
+@protocol UndefinedParentProtocol; // expected-note {{protocol 'UndefinedParentProtocol' has no definition}}
+
+@protocol UndefinedProtocol <UndefinedParentProtocol>
+@end
+
+@interface SomeObject : NSObject <UndefinedProtocol> // expected-warning {{cannot find protocol definition for 'UndefinedProtocol'}}
+@end
diff --git a/test/SemaObjC/class-unavail-warning.m b/test/SemaObjC/class-unavail-warning.m
index b2bd388..3ebf3e7 100644
--- a/test/SemaObjC/class-unavail-warning.m
+++ b/test/SemaObjC/class-unavail-warning.m
@@ -1,8 +1,8 @@
-// RUN: %clang_cc1  -fsyntax-only -verify %s
+// RUN: %clang_cc1  -fsyntax-only  -triple x86_64-apple-darwin10 -verify %s
 // rdar://9092208
 
 __attribute__((unavailable("not available")))
-@interface MyClass { // expected-note 8 {{declaration has been explicitly marked unavailable here}}
+@interface MyClass { // expected-note 8 {{'MyClass' has been explicitly marked unavailable here}}
 @public
     void *_test;
     MyClass *ivar; // no error.
@@ -15,7 +15,7 @@
 
 @end
 
-@interface Foo {
+@interface Gorf {
   MyClass *ivar; // expected-error {{unavailable}}
 }
 - (MyClass *)meth; // expected-error {{unavailable}}
@@ -40,3 +40,30 @@
 
  return 0;
 }
+
+// rdar://16681279
+@interface NSObject @end
+
+__attribute__((visibility("default"))) __attribute__((availability(macosx,unavailable)))
+@interface Foo : NSObject @end // expected-note 3 {{'Foo' has been explicitly marked unavailable here}}
+@interface AppDelegate  : NSObject
+@end
+
+@class Foo;
+
+@implementation AppDelegate
+- (void) applicationDidFinishLaunching
+{
+  Foo *foo = 0; // expected-error {{'Foo' is unavailable}}
+}
+@end
+
+@class Foo;
+Foo *g_foo = 0; // expected-error {{'Foo' is unavailable}}
+
+@class Foo;
+@class Foo;
+@class Foo;
+Foo * f_func() { // expected-error {{'Foo' is unavailable}}
+  return 0; 
+}
diff --git a/test/SemaObjC/cocoa.m b/test/SemaObjC/cocoa.m
deleted file mode 100644
index a8cfb72..0000000
--- a/test/SemaObjC/cocoa.m
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: %clang -arch x86_64 %s -fsyntax-only -Xclang -print-stats 
-#ifdef __APPLE__
-#include <Cocoa/Cocoa.h>
-#endif
-
diff --git a/test/SemaObjC/compare-qualified-class.m b/test/SemaObjC/compare-qualified-class.m
index 0f415b6..60ef851 100644
--- a/test/SemaObjC/compare-qualified-class.m
+++ b/test/SemaObjC/compare-qualified-class.m
@@ -25,6 +25,6 @@
     
     return classA == classB  || classA == classC ||
            classC == classA ||
-           classA == classD; // expected-warning {{comparison of distinct pointer types ('Class<SomeProtocol> *' and 'Class<SomeProtocol1> *')}}
+           classA == classD; // expected-warning {{comparison of distinct pointer types ('Class<SomeProtocol>' and 'Class<SomeProtocol1>')}}
 }
 
diff --git a/test/SemaObjC/compare-qualified-id.m b/test/SemaObjC/compare-qualified-id.m
index 02fa86e..7da7749 100644
--- a/test/SemaObjC/compare-qualified-id.m
+++ b/test/SemaObjC/compare-qualified-id.m
@@ -15,7 +15,7 @@
 @interface NSMutableDictionary : NSDictionary  - (void)removeObjectForKey:(id)aKey; @end // expected-note {{receiver is instance of class declared here}}
 extern NSString * const NSTaskDidTerminateNotification;
 
-@interface XCPropertyExpansionContext : NSObject <NSCopying> { // expected-note {{required for direct or indirect protocol 'NSCopying'}}
+@interface XCPropertyExpansionContext : NSObject <NSCopying> {
   NSMutableDictionary * _propNamesToPropValuesCache;
 } @end
 
@@ -23,7 +23,7 @@
 - (NSString *)evaluateAsStringInContext:(XCPropertyExpansionContext *)context withNestingState:(const void *)state;
 @end
 
-@implementation XCPropertyExpansionContext // expected-warning {{method 'copyWithZone:' in protocol not implemented}}
+@implementation XCPropertyExpansionContext // expected-warning {{method 'copyWithZone:' in protocol 'NSCopying' not implemented}}
 - (NSString *)expandedValueForProperty:(NSString *)property {
   id <XCPropertyValues> cachedValueNode = [_propNamesToPropValuesCache objectForKey:property]; // expected-warning {{method '-objectForKey:' not found (return type defaults to 'id')}}
   if (cachedValueNode == ((void *)0)) { }
diff --git a/test/SemaObjC/comptypes-legal.m b/test/SemaObjC/comptypes-legal.m
index d83d559..05f1897 100644
--- a/test/SemaObjC/comptypes-legal.m
+++ b/test/SemaObjC/comptypes-legal.m
@@ -35,3 +35,20 @@
   // Since registerFunc: expects a Derived object as it's second argument, I don't know why this would be legal.
   [Derived registerFunc: ExternFunc];  // expected-warning{{incompatible pointer types sending 'NSObject *(NSObject *, NSObject *)' to parameter of type 'FuncSignature *'}}
 }
+
+// rdar://10751015
+@protocol NSCopying @end
+@interface I
+- (void) Meth : (id <NSCopying>)aKey; // expected-note {{passing argument to parameter 'aKey' here}}
+@end
+
+@class ForwarClass; // expected-note 3 {{conformance of forward class ForwarClass to protocol NSCopying can not be confirmed}}
+
+ForwarClass *Test10751015 (I* pi, ForwarClass *ns_forward) {
+
+  [pi Meth : ns_forward ]; // expected-warning {{sending 'ForwarClass *' to parameter of incompatible type 'id<NSCopying>'}}
+
+  id <NSCopying> id_ns = ns_forward; // expected-warning {{initializing 'id<NSCopying>' with an expression of incompatible type 'ForwarClass *'}}
+
+  return id_ns; // expected-warning {{returning 'id<NSCopying>' from a function with incompatible result type 'ForwarClass *'}}
+}
diff --git a/test/SemaObjC/conditional-expr.m b/test/SemaObjC/conditional-expr.m
index 049a095..d8862c5 100644
--- a/test/SemaObjC/conditional-expr.m
+++ b/test/SemaObjC/conditional-expr.m
@@ -96,8 +96,8 @@
   return a ? x : p;
 }
 
-void f8(int a, A<P0> *x, A *y) {
-  [ (a ? x : y ) intProp ];
+int f8(int a, A<P0> *x, A *y) {
+  return [ (a ? x : y ) intProp ];
 }
 
 void f9(int a, A<P0> *x, A<P1> *y) {
diff --git a/test/SemaObjC/continuation-class-property.m b/test/SemaObjC/continuation-class-property.m
index 2a8e508..83aa796 100644
--- a/test/SemaObjC/continuation-class-property.m
+++ b/test/SemaObjC/continuation-class-property.m
@@ -61,3 +61,15 @@
 @property (nonatomic, readwrite, assign) struct S1 *httpRequest3;
 @property (nonatomic, readwrite, assign) struct S2 *httpRequest4;
 @end
+
+// rdar://15859862
+@protocol ADCameraJSO_Bindings
+@property (nonatomic, readonly) NSString *currentPictureURI;
+@end
+
+@interface ADCameraJSO
+@end
+
+@interface ADCameraJSO()  <ADCameraJSO_Bindings>
+@property (nonatomic, copy) NSString *currentPictureURI;
+@end
diff --git a/test/SemaObjC/dealloc.m b/test/SemaObjC/dealloc.m
index 59218d2..c1bd0b5 100644
--- a/test/SemaObjC/dealloc.m
+++ b/test/SemaObjC/dealloc.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -fblocks -verify %s
-// RUN: not %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -fblocks -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -fblocks -Wdealloc-in-category -verify %s
+// RUN: not %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -fblocks -Wdealloc-in-category -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
 // rdar://11987838
 
 @protocol NSObject
@@ -23,3 +23,33 @@
 
 @end
 
+// rdar://15397430
+@interface Base
+- (void)dealloc;
+@end
+
+@interface Subclass : Base
+@end 
+
+@interface Subclass (CAT)
+- (void)dealloc;
+@end
+
+@implementation Subclass (CAT)
+- (void)dealloc { // expected-warning {{-dealloc is being overridden in a category}}
+}
+@end
+
+// rdar://15919775
+@interface NSObject @end
+@interface NSError:NSObject
+@end
+
+@interface NSError(CAT)
+- (NSError *)MCCopyAsPrimaryError __attribute__((objc_method_family(new)));
+@end
+@implementation NSError(CAT)
+- (NSError *)MCCopyAsPrimaryError {
+  return 0;
+}
+@end
diff --git a/test/SemaObjC/default-synthesize-3.m b/test/SemaObjC/default-synthesize-3.m
index 1c32665..c915974 100644
--- a/test/SemaObjC/default-synthesize-3.m
+++ b/test/SemaObjC/default-synthesize-3.m
@@ -37,7 +37,7 @@
 @interface Deep(CAT)  // expected-error {{attributes may not be specified on a category}}
 @end
 
-__attribute ((objc_requires_property_definitions)) // expected-error {{objc_requires_property_definitions attribute may only be specified on a class}} 
+__attribute ((objc_requires_property_definitions)) // expected-error {{'objc_requires_property_definitions' attribute only applies to Objective-C interfaces}}
 @protocol P @end
 
 // rdar://13388503
@@ -172,12 +172,44 @@
 @interface Okay : NSObject<Fooing>
 @end
 
-@implementation Okay // expected-warning 2 {{auto property synthesis will not synthesize property declared in a protocol}}
+@implementation Okay // expected-warning {{auto property synthesis will not synthesize property 'muahahaha' declared in protocol 'Fooing'}} expected-warning {{auto property synthesis will not synthesize property 'hoho' declared in protocol 'SubFooling'}}
 @end
 
 @interface Fail : FooObject
 @end
 
-@implementation Fail // expected-warning 2 {{auto property synthesis will not synthesize property declared in a protocol}}
+@implementation Fail // expected-warning {{auto property synthesis will not synthesize property 'muahahaha' declared in protocol 'Fooing'}} expected-warning {{auto property synthesis will not synthesize property 'hoho' declared in protocol 'SubFooling'}}
 @end
 
+// rdar://16089191
+@class NSURL;
+
+@interface Root
+- (void)setFileURL : (NSURL *) arg;
+- (void)setFile : (NSURL *) arg;
+- (NSURL *)fileSys;
+- (void)setFileSys : (NSURL *) arg;
+- (NSURL *)fileKerl;
+@end
+
+@interface SuperClass : Root
+- (NSURL *)fileURL;
+- (NSURL *)file;
+- (NSURL *)fileLog;
+- (void)setFileLog : (NSURL *) arg;
+- (void)setFileKerl : (NSURL *) arg;
+@end
+
+@protocol r16089191Protocol
+@property (readonly) NSURL *fileURL;
+@property (copy) NSURL *file;
+@property (copy) NSURL *fileSys;
+@property (copy) NSURL *fileLog;
+@property (copy) NSURL *fileKerl;
+@end
+
+@interface SubClass : SuperClass <r16089191Protocol>
+@end
+
+@implementation SubClass
+@end
diff --git a/test/SemaObjC/default-synthesize.m b/test/SemaObjC/default-synthesize.m
index dd16c13..9356b9f 100644
--- a/test/SemaObjC/default-synthesize.m
+++ b/test/SemaObjC/default-synthesize.m
@@ -136,5 +136,5 @@
 @interface MyClass <MyProtocol> 
 @end
  
-@implementation MyClass // expected-warning {{auto property synthesis will not synthesize property declared in a protocol}}
+@implementation MyClass // expected-warning {{auto property synthesis will not synthesize property 'requiredString' declared in protocol 'MyProtocol'}}
 @end
diff --git a/test/SemaObjC/deprecate_function_containers.m b/test/SemaObjC/deprecate_function_containers.m
new file mode 100644
index 0000000..531cf11
--- /dev/null
+++ b/test/SemaObjC/deprecate_function_containers.m
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1  -fsyntax-only -fblocks -verify -Wno-objc-root-class %s
+// rdar://10414277
+
+@protocol P
+void p_foo() {} // expected-warning {{function definition inside an Objective-C container is deprecated}}
+@end
+
+@interface I
+void foo() {} // expected-warning {{function definition inside an Objective-C container is deprecated}}
+inline void v_foo() {} // expected-warning {{function definition inside an Objective-C container is deprecated}}
+static int s_foo() {return 0; } // expected-warning {{function definition inside an Objective-C container is deprecated}}
+static inline int si_val() { return 1; } // expected-warning {{function definition inside an Objective-C container is deprecated}}
+@end
+
+@interface I(CAT)
+void cat_foo() {} // expected-warning {{function definition inside an Objective-C container is deprecated}}
+@end
+
+@implementation I
+inline void v_imp_foo() {} 
+@end
+
+@implementation I(CAT)
+void cat_imp_foo() {} 
+@end
+
+// rdar://16859666
+@interface PrototypeState
+
+@property (strong, readwrite) id moin1; // expected-note {{property declared here}}
+
+static inline void prototype_observe_moin1(void (^callback)(id)) { // expected-warning {{function definition inside an Objective-C container is deprecated}}
+        (void)^(PrototypeState *prototypeState){
+            callback(prototypeState.moin1); // expected-error {{use of Objective-C property in function nested in Objective-C container not supported, move function outside its container}}
+        };
+}
+@end
diff --git a/test/SemaObjC/encode-typeof-test.m b/test/SemaObjC/encode-typeof-test.m
new file mode 100644
index 0000000..2cda973
--- /dev/null
+++ b/test/SemaObjC/encode-typeof-test.m
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1  -fsyntax-only -verify -Wno-objc-root-class %s
+// rdar://16655340
+@protocol X, Y, Z;
+@class Foo;
+
+@protocol Proto
+@end
+
+@interface Intf <Proto>
+{
+id <X> IVAR_x;
+id <X, Y> IVAR_xy;
+id <X, Y, Z> IVAR_xyz;
+Foo <X, Y, Z> *IVAR_Fooxyz;
+Class <X> IVAR_Classx;
+}
+@end
+
+@implementation Intf 
+@end
+
+int main()
+{
+    int i;
+    typeof(@encode(typeof(i))) e = @encode(typeof(Intf)); // expected-warning {{initializer-string for char array is too long}}
+}
diff --git a/test/SemaObjC/error-missing-getter.m b/test/SemaObjC/error-missing-getter.m
index 3dce858..13dc8e5 100644
--- a/test/SemaObjC/error-missing-getter.m
+++ b/test/SemaObjC/error-missing-getter.m
@@ -27,7 +27,8 @@
     if (TestClass.setterOnly) { // expected-error {{no getter method for read from property}}
       TestClass.setterOnly = 1;
     }
-    func(TestClass.setterOnly + 1, x); // expected-error {{no getter method for read from property}}
+    func(TestClass.setterOnly + 1, x); // expected-error {{no getter method for read from property}} \
+                                       // expected-error {{use of undeclared identifier 'x'}}
     int i = TestClass.setterOnly + 1;  // expected-error {{no getter method for read from property}}
     return TestClass.setterOnly + 1;   // expected-error {{no getter method for read from property}}
 }
diff --git a/test/SemaObjC/format-arg-attribute.m b/test/SemaObjC/format-arg-attribute.m
index e770373..79f5656 100644
--- a/test/SemaObjC/format-arg-attribute.m
+++ b/test/SemaObjC/format-arg-attribute.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -Werror -Wformat-nonliteral -verify -fsyntax-only %s
+// RUN: %clang_cc1 -verify -fsyntax-only %s
 
 @class NSString;
 
@@ -9,9 +9,9 @@
 extern void fc2 (const NSString *) __attribute__((format_arg())); // expected-error {{'format_arg' attribute takes one argument}}
 extern void fc3 (const NSString *) __attribute__((format_arg(1, 2))); // expected-error {{'format_arg' attribute takes one argument}}
 
-struct s1 { int i; } __attribute__((format_arg(1)));  // expected-error {{'format_arg' attribute only applies to functions}}
-union u1 { int i; } __attribute__((format_arg(1)));  // expected-error {{'format_arg' attribute only applies to functions}}
-enum e1 { E1V0 } __attribute__((format_arg(1))); // expected-error {{'format_arg' attribute only applies to functions}}
+struct s1 { int i; } __attribute__((format_arg(1)));  // expected-warning {{'format_arg' attribute only applies to functions}}
+union u1 { int i; } __attribute__((format_arg(1)));  // expected-warning {{'format_arg' attribute only applies to functions}}
+enum e1 { E1V0 } __attribute__((format_arg(1))); // expected-warning {{'format_arg' attribute only applies to functions}}
 
 extern NSString *ff3 (const NSString *) __attribute__((format_arg(3-2)));
 extern NSString *ff4 (const NSString *) __attribute__((format_arg(foo))); // expected-error {{use of undeclared identifier 'foo'}}
@@ -25,23 +25,3 @@
 extern int fi3 (const NSString *) __attribute__((format_arg(1)));  // expected-error {{function does not return NSString}}
 extern NSString *fi4 (const NSString *) __attribute__((format_arg(1))); 
 extern NSString *fi5 (const NSString *) __attribute__((format_arg(1))); 
-
-// rdar://15242010
-@interface NSString
-+ (id)stringWithFormat:(NSString *)format, ... __attribute__((format(__NSString__, 1, 2)));
-@end
-
-@interface NSBundle
-- (NSString *)localizedStringForKey:(NSString *)key value:(NSString *)value table:(NSString *)tableName __attribute__ ((format_arg(1)));
-+ (NSBundle *)mainBundle;
-@end
-
-
-NSString* localizedFormat(NSString* string) __attribute__ ((format_arg(1)));
-
-int main()
-{
-  [NSString stringWithFormat:[[NSBundle mainBundle] localizedStringForKey:@"foo %d" value:@"bar %d" table:0], 42];
-
-  [NSString stringWithFormat:localizedFormat(@"foo %d"), 42];
-}
diff --git a/test/SemaObjC/format-strings-objc.m b/test/SemaObjC/format-strings-objc.m
index 2667e30..49567a7 100644
--- a/test/SemaObjC/format-strings-objc.m
+++ b/test/SemaObjC/format-strings-objc.m
@@ -116,6 +116,9 @@
   NSLog(ns2); // expected-warning {{more '%' conversions than data arguments}}
   NSString * ns3 = ns1;
   NSLog(ns3); // expected-warning {{format string is not a string literal}}}
+
+  NSString * const ns6 = @"split" " string " @"%s"; // expected-note {{format string is defined here}}
+  NSLog(ns6); // expected-warning {{more '%' conversions than data arguments}}
 }
 
 // Do not emit warnings when using NSLocalizedString
diff --git a/test/SemaObjC/forward-protocol-incomplete-impl-warn.m b/test/SemaObjC/forward-protocol-incomplete-impl-warn.m
index c3efeba..c235e32 100644
--- a/test/SemaObjC/forward-protocol-incomplete-impl-warn.m
+++ b/test/SemaObjC/forward-protocol-incomplete-impl-warn.m
@@ -12,9 +12,9 @@
 
 @protocol DVTInvalidation;
 
-@interface IBImageCatalogDocument : NSObject <DVTInvalidation> // expected-note {{required for direct or indirect protocol 'DVTInvalidation'}}
+@interface IBImageCatalogDocument : NSObject <DVTInvalidation>
 @end
 
-@implementation IBImageCatalogDocument // expected-warning {{auto property synthesis will not synthesize property declared in a protocol}} \ 
-				       // expected-warning {{method 'invalidate' in protocol not implemented}}
+@implementation IBImageCatalogDocument // expected-warning {{auto property synthesis will not synthesize property 'Prop' declared in protocol 'DVTInvalidation'}} \
+				       // expected-warning {{method 'invalidate' in protocol 'DVTInvalidation' not implemented}}
 @end
diff --git a/test/SemaObjC/ibaction.m b/test/SemaObjC/ibaction.m
index 9c59d7a..43c927c 100644
--- a/test/SemaObjC/ibaction.m
+++ b/test/SemaObjC/ibaction.m
@@ -4,12 +4,12 @@
 {
   __attribute__((iboutlet)) id myoutlet;
 }
-+ (void) __attribute__((ibaction)) myClassMethod:(id)msg; // expected-warning{{ibaction attribute can only be applied to Objective-C instance methods}}
++ (void) __attribute__((ibaction)) myClassMethod:(id)msg; // expected-warning{{'ibaction' attribute only applies to Objective-C instance methods}}
 - (void) __attribute__((ibaction)) myMessage:(id)msg;
 @end
 
 @implementation Foo
-+ (void) __attribute__((ibaction)) myClassMethod:(id)msg {} // expected-warning{{ibaction attribute can only be applied to Objective-C instance methods}}
++ (void) __attribute__((ibaction)) myClassMethod:(id)msg {} // expected-warning{{'ibaction' attribute only applies to Objective-C instance methods}}
 // Normally attributes should not be attached to method definitions, but
 // we allow 'ibaction' to be attached because it can be expanded from
 // the IBAction macro.
diff --git a/test/SemaObjC/iboutlet.m b/test/SemaObjC/iboutlet.m
index 3c7f958..63eac9a 100644
--- a/test/SemaObjC/iboutlet.m
+++ b/test/SemaObjC/iboutlet.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -Wno-objc-root-class -verify %s
-// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -Wno-objc-root-class -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -Wno-objc-root-class -Wreceiver-is-weak -Warc-repeated-use-of-weak -fobjc-runtime-has-weak -verify %s
+// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -fobjc-arc -Wno-objc-root-class -Wreceiver-is-weak -Warc-repeated-use-of-weak -fobjc-runtime-has-weak -verify %s
 // rdar://11448209
 
 #define READONLY readonly
@@ -40,3 +40,15 @@
 @implementation RKTFHView
 @synthesize synthReadOnlyReadWrite=_synthReadOnlyReadWrite;
 @end
+
+// rdar://15885642
+@interface WeakOutlet 
+@property IBOutlet __weak WeakOutlet* WeakProp;
+@end
+
+WeakOutlet* func() {
+  __weak WeakOutlet* pwi;
+  pwi.WeakProp = (WeakOutlet*)0;
+  pwi.WeakProp = pwi.WeakProp;
+  return pwi.WeakProp;
+}
diff --git a/test/SemaObjC/incomplete-implementation.m b/test/SemaObjC/incomplete-implementation.m
index 4b8d600..74dea2a 100644
--- a/test/SemaObjC/incomplete-implementation.m
+++ b/test/SemaObjC/incomplete-implementation.m
@@ -39,3 +39,29 @@
 
 @end
 
+// rdar://15580969
+typedef char BOOL;
+
+@protocol NSObject
+- (BOOL)isEqual:(id)object;
+@end
+
+@interface NSObject <NSObject>
+@end
+
+@protocol NSApplicationDelegate <NSObject>
+- (void)ImpleThisMethod; // expected-note {{method 'ImpleThisMethod' declared here}}
+@end
+
+@interface AppDelegate : NSObject <NSApplicationDelegate>
+@end
+
+@implementation AppDelegate (MRRCategory)
+
+- (BOOL)isEqual:(id)object
+{
+    return __objc_no;
+}
+
+- (void)ImpleThisMethod {} // expected-warning {{category is implementing a method which will also be implemented by its primary class}}
+@end
diff --git a/test/SemaObjC/ivar-lookup-resolution-builtin.m b/test/SemaObjC/ivar-lookup-resolution-builtin.m
index dd11b51..94ed325 100644
--- a/test/SemaObjC/ivar-lookup-resolution-builtin.m
+++ b/test/SemaObjC/ivar-lookup-resolution-builtin.m
@@ -29,7 +29,7 @@
 - (int) InstMethod
 {
   return index;	// expected-warning {{implicitly declaring library function 'index'}}	\
-                // expected-note {{please include the header <strings.h> or explicitly provide a declaration for 'index'}} \
+                // expected-note {{include the header <strings.h> or explicitly provide a declaration for 'index'}} \
                 // expected-warning {{incompatible pointer to integer conversion returning}}
 }
 + (int) ClassMethod
diff --git a/test/SemaObjC/method-attributes.m b/test/SemaObjC/method-attributes.m
index b402d52..1b0a900 100644
--- a/test/SemaObjC/method-attributes.m
+++ b/test/SemaObjC/method-attributes.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fsyntax-only -Wno-objc-root-class %s
+// RUN: %clang_cc1 -triple i386-unknown-unknown -verify -fsyntax-only -Wno-objc-root-class %s
 
 @class NSString;
 
@@ -7,26 +7,28 @@
 - (NSString *)stringByAppendingFormat:(NSString *)format, ... __attribute__((format(__NSString__, 1, 2)));
 -(void) m0 __attribute__((noreturn));
 -(void) m1 __attribute__((unused));
+-(void) m2 __attribute__((stdcall));
+-(void) m3 __attribute__((optnone));
 @end
 
 
 @interface INTF
 - (int) foo1: (int)arg1 __attribute__((deprecated));
 
-- (int) foo: (int)arg1;  // expected-note {{method 'foo:' declared here}}
+- (int) foo: (int)arg1;
 
-- (int) foo2: (int)arg1 __attribute__((deprecated)) __attribute__((unavailable)); // expected-note {{method 'foo2:' declared here}}
+- (int) foo2: (int)arg1 __attribute__((deprecated)) __attribute__((unavailable));
 - (int) foo3: (int)arg1 __attribute__((deprecated)) __attribute__((unavailable)) __attribute__((ns_consumes_self));
 @end
 
 @implementation INTF
-- (int) foo: (int)arg1  __attribute__((deprecated)){ // expected-warning {{attributes on method implementation and its declaration must match}}
+- (int) foo: (int)arg1  __attribute__((deprecated)){
         return 10;
 }
 - (int) foo1: (int)arg1 {
         return 10;
 }
-- (int) foo2: (int)arg1 __attribute__((deprecated)) {  // expected-warning {{attributes on method implementation and its declaration must match}}
+- (int) foo2: (int)arg1 __attribute__((deprecated)) {
         return 10;
 }
 - (int) foo3: (int)arg1 __attribute__((deprecated)) __attribute__((unavailable)) __attribute__((ns_consumes_self)) {return 0; }
@@ -39,7 +41,7 @@
 
 @interface Foo 
 - (void)doSomething1:(id)sender;
-- (void)doSomething2:(id)sender; // expected-note {{method 'doSomething2:' declared here}}
+- (void)doSomething2:(id)sender;
 @end
 
 @implementation Foo
@@ -52,7 +54,7 @@
 @end
 @implementation Bar
 - (IBAction)doSomething1:(id)sender {}
-- (IBAction)doSomething2:(id)sender {} // expected-warning {{attributes on method implementation and its declaration must match}}
+- (IBAction)doSomething2:(id)sender {}
 - (IBAction)doSomething3:(id)sender {}
 @end
 
@@ -63,7 +65,7 @@
 -(id)method __attribute__((deprecated));
 -(id)method1;
 -(id)method2 __attribute__((aligned(16)));
-- (id) method3: (int)arg1 __attribute__((aligned(16)))  __attribute__((deprecated)) __attribute__((unavailable)); // expected-note {{method 'method3:' declared here}}
+- (id) method3: (int)arg1 __attribute__((aligned(16)))  __attribute__((deprecated)) __attribute__((unavailable));
 - (id) method4: (int)arg1 __attribute__((aligned(16)))  __attribute__((deprecated)) __attribute__((unavailable)); 
 @end
 
@@ -77,10 +79,23 @@
 -(id)method2 {
     return self;
 }
-- (id) method3: (int)arg1 __attribute__((deprecated)) __attribute__((unavailable)) {  // expected-warning {{attributes on method implementation and its declaration must match}}
+- (id) method3: (int)arg1 __attribute__((deprecated)) __attribute__((unavailable)) {
         return self;
 }
 - (id) method4: (int)arg1 __attribute__((aligned(16))) __attribute__((deprecated)) __attribute__((unavailable)) {
   return self;
 }
 @end
+
+__attribute__((cdecl))  // expected-warning {{'cdecl' attribute only applies to functions and methods}}
+@interface Complain 
+@end
+
+// rdar://15450637
+@interface rdar15450637 : NSObject
+@property int p __attribute__((section("__TEXT,foo")));
+
+- (id) IMethod :(int) count, ...  __attribute__((section("__TEXT,foo")));
+
++ (void) CMethod : (id) Obj __attribute__((section("__TEXT,fee")));
+@end
diff --git a/test/SemaObjC/method-sentinel-attr.m b/test/SemaObjC/method-sentinel-attr.m
index d230be5..82ee373 100644
--- a/test/SemaObjC/method-sentinel-attr.m
+++ b/test/SemaObjC/method-sentinel-attr.m
@@ -13,7 +13,7 @@
 - (void) foo8 : (int)x, ... __attribute__ ((__sentinel__("a")));  // expected-error {{'__sentinel__' attribute requires parameter 1 to be an integer constant}}
 - (void) foo9 : (int)x, ... __attribute__ ((__sentinel__(-1)));  // expected-error {{'sentinel' parameter 1 less than zero}}
 - (void) foo10 : (int)x, ... __attribute__ ((__sentinel__(1,1)));
-- (void) foo11 : (int)x, ... __attribute__ ((__sentinel__(1,1,3)));  // expected-error {{attribute takes no more than 2 arguments}}
+- (void) foo11 : (int)x, ... __attribute__ ((__sentinel__(1,1,3)));  // expected-error {{'__sentinel__' attribute takes no more than 2 arguments}}
 - (void) foo12 : (int)x, ... ATTR; // expected-note {{method has been explicitly marked sentinel here}}
 
 // rdar://7975788
diff --git a/test/SemaObjC/method-undef-category-warn-1.m b/test/SemaObjC/method-undef-category-warn-1.m
index 98d732b..c951db2 100644
--- a/test/SemaObjC/method-undef-category-warn-1.m
+++ b/test/SemaObjC/method-undef-category-warn-1.m
@@ -8,20 +8,20 @@
 - (void) Pmeth1;  // expected-note {{method 'Pmeth1' declared here}}
 @end
 
-@interface MyClass1(CAT) <P> // expected-note {{required for direct or indirect protocol 'P'}}
+@interface MyClass1(CAT) <P>
 - (void) meth2;              // expected-note {{method 'meth2' declared here}}
 @end
 
-@implementation MyClass1(CAT) // expected-warning {{method 'Pmeth' in protocol not implemented}} \
+@implementation MyClass1(CAT) // expected-warning {{method 'Pmeth' in protocol 'P' not implemented}} \
                               // expected-warning {{method definition for 'meth2' not found}}
 - (void) Pmeth1{}
 @end
 
-@interface MyClass1(DOG) <P> // expected-note {{required for direct or indirect protocol 'P'}}
+@interface MyClass1(DOG) <P>
 - (void)ppp;                 // expected-note {{method 'ppp' declared here}}
 @end
 
-@implementation MyClass1(DOG) // expected-warning {{method 'Pmeth1' in protocol not implemented}} \
+@implementation MyClass1(DOG) // expected-warning {{method 'Pmeth1' in protocol 'P' not implemented}} \
                               // expected-warning {{method definition for 'ppp' not found}}
 - (void) Pmeth {}
 @end
diff --git a/test/SemaObjC/method-undef-extension-warn-1.m b/test/SemaObjC/method-undef-extension-warn-1.m
index fbc21bd..819d6ed 100644
--- a/test/SemaObjC/method-undef-extension-warn-1.m
+++ b/test/SemaObjC/method-undef-extension-warn-1.m
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
 
-@interface MyClass // expected-note {{required for direct or indirect protocol 'P'}}
+@interface MyClass
 @end
 
 @protocol P
@@ -18,7 +18,7 @@
 - (void)categoryMethod;
 @end
 
-@implementation MyClass // expected-warning {{method 'Pmeth1' in protocol not implemented}} \
+@implementation MyClass // expected-warning {{method 'Pmeth1' in protocol 'P' not implemented}} \
                         // expected-warning {{method definition for 'meth2' not found}}
 - (void)Pmeth {}
 @end
diff --git a/test/SemaObjC/nonnull.m b/test/SemaObjC/nonnull.m
index 902105b..a345edd 100644
--- a/test/SemaObjC/nonnull.m
+++ b/test/SemaObjC/nonnull.m
@@ -74,6 +74,9 @@
 @interface NSObject 
 - (void)doSomethingWithNonNullPointer:(void *)ptr :(int)iarg : (void*)ptr1 __attribute__((nonnull(1, 3)));
 + (void)doSomethingClassyWithNonNullPointer:(void *)ptr __attribute__((nonnull(1)));
+- (void*)returnsCNonNull __attribute__((returns_nonnull)); // no-warning
+- (id)returnsObjCNonNull __attribute__((returns_nonnull)); // no-warning
+- (int)returnsIntNonNull __attribute__((returns_nonnull)); // expected-warning {{'returns_nonnull' attribute only applies to return values that are pointers}}
 @end
 
 extern void DoSomethingNotNull(void *db) __attribute__((nonnull(1)));
@@ -82,6 +85,7 @@
 {
   void * vp;
 }
+- (void*) testRetNull __attribute__((returns_nonnull));
 @end
 
 @implementation IMP
@@ -93,5 +97,29 @@
   DoSomethingNotNull(NULL); // expected-warning {{null passed to a callee which requires a non-null argument}}
   [object doSomethingWithNonNullPointer:vp:1:vp];
 }
+- (void*) testRetNull {
+  return 0; // expected-warning {{null returned from method that requires a non-null return value}}
+}
 @end
 
+__attribute__((objc_root_class))
+@interface TestNonNullParameters
+- (void) doNotPassNullParameterNonPointerArg:(int)__attribute__((nonnull))x; // expected-warning {{'nonnull' attribute only applies to pointer arguments}}
+- (void) doNotPassNullParameter:(id)__attribute__((nonnull))x;
+- (void) doNotPassNullParameterArgIndex:(id)__attribute__((nonnull(1)))x; // expected-warning {{'nonnull' attribute when used on parameters takes no arguments}}
+- (void) doNotPassNullOnMethod:(id)x __attribute__((nonnull(1)));
+@end
+
+void test(TestNonNullParameters *f) {
+  [f doNotPassNullParameter:0]; // expected-warning {{null passed to a callee which requires a non-null argument}}
+  [f doNotPassNullParameterArgIndex:0]; // no-warning
+  [f doNotPassNullOnMethod:0]; // expected-warning {{null passed to a callee which requires a non-null argument}}
+}
+
+
+void PR18795(int (^g)(const char *h, ...) __attribute__((nonnull(1))) __attribute__((nonnull))) {
+  g(0); // expected-warning{{null passed to a callee which requires a non-null argument}}
+}
+void PR18795_helper() {
+  PR18795(0); // expected-warning{{null passed to a callee which requires a non-null argument}}
+}
diff --git a/test/SemaObjC/ns_returns_retained_block_return.m b/test/SemaObjC/ns_returns_retained_block_return.m
new file mode 100644
index 0000000..e5a96ca
--- /dev/null
+++ b/test/SemaObjC/ns_returns_retained_block_return.m
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1  -fblocks -fsyntax-only -verify -Wno-objc-root-class %s
+// RUN: %clang_cc1 -x objective-c++ -fblocks -fsyntax-only -verify -Wno-objc-root-class %s
+// RUN: %clang_cc1  -fblocks -fobjc-arc -fsyntax-only -verify -Wno-objc-root-class %s
+// RUN: %clang_cc1 -x objective-c++ -fblocks -fobjc-arc -fsyntax-only -verify -Wno-objc-root-class %s
+// expected-no-diagnostics
+// rdar://17259812
+
+typedef void (^BT) ();
+
+BT foo()  __attribute__((ns_returns_retained));
+
+@interface I
+BT foo()  __attribute__((ns_returns_retained));
+- (BT) Meth __attribute__((ns_returns_retained));
++ (BT) ClsMeth __attribute__((ns_returns_retained));
+@end
+
+@implementation I
+BT foo()  __attribute__((ns_returns_retained)) {return ^{}; }
+- (BT) Meth {return ^{}; }
++ (BT) ClsMeth {return ^{}; }
+@end
diff --git a/test/SemaObjC/nsobject-attribute.m b/test/SemaObjC/nsobject-attribute.m
index ead222c..6bd2d5d 100644
--- a/test/SemaObjC/nsobject-attribute.m
+++ b/test/SemaObjC/nsobject-attribute.m
@@ -6,7 +6,7 @@
 static int count;
 static CGColorRef tmp = 0;
 
-typedef struct S1  __attribute__ ((NSObject)) CGColorRef1; // expected-error {{__attribute ((NSObject)) is for pointer types only}}
+typedef struct S1  __attribute__ ((NSObject)) CGColorRef1; // expected-error {{'NSObject' attribute is for pointer types only}}
 typedef void *  __attribute__ ((NSObject)) CGColorRef2; // no-warning
 typedef void * CFTypeRef;
 
@@ -48,18 +48,18 @@
 // rdar://10453342
 @interface I
 {
-   __attribute__((NSObject)) void * color; // expected-warning {{__attribute ((NSObject)) may be put on a typedef only, attribute is ignored}}
+   __attribute__((NSObject)) void * color; // expected-warning {{'NSObject' attribute may be put on a typedef only; attribute is ignored}}
 }
   // <rdar://problem/10930507>
 @property (nonatomic, retain) __attribute__((NSObject)) CGColorRefNoNSObject color; // // no-warning
 @end
 void test_10453342() {
-    char* __attribute__((NSObject)) string2 = 0; // expected-warning {{__attribute ((NSObject)) may be put on a typedef only, attribute is ignored}}
+    char* __attribute__((NSObject)) string2 = 0; // expected-warning {{'NSObject' attribute may be put on a typedef only; attribute is ignored}}
 }
 
 // rdar://11569860
 @interface A { int i; }
-@property(retain) __attribute__((NSObject)) int i; // expected-error {{__attribute ((NSObject)) is for pointer types only}} \
+@property(retain) __attribute__((NSObject)) int i; // expected-error {{'NSObject' attribute is for pointer types only}} \
   						   // expected-error {{property with 'retain (or strong)' attribute must be of object type}}
 @end
 
diff --git a/test/SemaObjC/objc-asm-attribute-neg-test.m b/test/SemaObjC/objc-asm-attribute-neg-test.m
new file mode 100644
index 0000000..2fb6643
--- /dev/null
+++ b/test/SemaObjC/objc-asm-attribute-neg-test.m
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1  -fsyntax-only -verify -Wno-objc-root-class %s
+// rdar://16462586
+
+__attribute__((objc_runtime_name)) // expected-error {{'objc_runtime_name' attribute takes one argument}}
+@interface BInterface
+@end
+
+__attribute__((objc_runtime_name(123))) // expected-error {{'objc_runtime_name' attribute requires a string}}
+@protocol BProtocol1
+@end
+
+__attribute__((objc_runtime_name("MySecretNamespace.Protocol")))
+@protocol Protocol
+@end
+
+__attribute__((objc_runtime_name("MySecretNamespace.Message")))
+@interface Message <Protocol> { 
+__attribute__((objc_runtime_name("MySecretNamespace.Message"))) // expected-error {{'objc_runtime_name' attribute only applies to interface or protocol declarations}}
+  id MyIVAR;
+}
+__attribute__((objc_runtime_name("MySecretNamespace.Message")))
+@property int MyProperty; // expected-error {{prefix attribute must be followed by an interface or protocol}}}}
+
+- (int) getMyProperty __attribute__((objc_runtime_name("MySecretNamespace.Message"))); // expected-error {{'objc_runtime_name' attribute only applies to interface or protocol declarations}}
+
+- (void) setMyProperty : (int) arg __attribute__((objc_runtime_name("MySecretNamespace.Message"))); // expected-error {{'objc_runtime_name' attribute only applies to interface or protocol declarations}}
+
+@end
+
+__attribute__((objc_runtime_name("MySecretNamespace.ForwardClass")))
+@class ForwardClass; // expected-error {{prefix attribute must be followed by an interface or protocol}}
+
+__attribute__((objc_runtime_name("MySecretNamespace.ForwardProtocol")))
+@protocol ForwardProtocol;
+
+__attribute__((objc_runtime_name("MySecretNamespace.Message")))
+@implementation Message // expected-error {{prefix attribute must be followed by an interface or protocol}}
+__attribute__((objc_runtime_name("MySecretNamespace.Message")))
+- (id) MyMethod {
+  return MyIVAR;
+}
+@end
diff --git a/test/SemaObjC/objc-container-subscripting-attr.m b/test/SemaObjC/objc-container-subscripting-attr.m
new file mode 100644
index 0000000..17110c4
--- /dev/null
+++ b/test/SemaObjC/objc-container-subscripting-attr.m
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1  -fsyntax-only -verify -Wno-objc-root-class %s
+// rdar://16842487
+// pr19682
+
+@interface Subscriptable
+- (id)objectForKeyedSubscript:(id)sub __attribute__((unavailable)); // expected-note 2 {{'objectForKeyedSubscript:' has been explicitly marked unavailable here}}
+- (void)setObject:(id)object forKeyedSubscript:(id)key __attribute__((unavailable)); // expected-note {{'setObject:forKeyedSubscript:' has been explicitly marked unavailable here}}
+@end
+
+id test(Subscriptable *obj) {
+  obj[obj] = obj;  // expected-error {{'setObject:forKeyedSubscript:' is unavailable}}
+  return obj[obj]; // expected-error {{'objectForKeyedSubscript:' is unavailable}}
+}
+
+id control(Subscriptable *obj) {
+  return [obj objectForKeyedSubscript:obj]; // expected-error {{'objectForKeyedSubscript:' is unavailable}}
+}
+
diff --git a/test/SemaObjC/objc-literal-nsnumber.m b/test/SemaObjC/objc-literal-nsnumber.m
index 26bca18..a2d3728 100644
--- a/test/SemaObjC/objc-literal-nsnumber.m
+++ b/test/SemaObjC/objc-literal-nsnumber.m
@@ -1,10 +1,12 @@
-// RUN: %clang_cc1  -fsyntax-only -fblocks -verify %s
+// RUN: %clang_cc1  -fsyntax-only -fblocks -triple x86_64-apple-darwin10 -verify %s
 // rdar://10111397
 
 #if __LP64__
 typedef unsigned long NSUInteger;
+typedef long NSInteger;
 #else
 typedef unsigned int NSUInteger;
+typedef int NSInteger;
 #endif
 
 @interface NSObject
@@ -13,10 +15,23 @@
 
 @interface NSNumber : NSObject
 + (NSNumber *)numberWithChar:(char)value;
++ (NSNumber *)numberWithUnsignedChar:(unsigned char)value;
++ (NSNumber *)numberWithShort:(short)value;
++ (NSNumber *)numberWithUnsignedShort:(unsigned short)value;
 + (NSNumber *)numberWithInt:(int)value;
++ (NSNumber *)numberWithUnsignedInt:(unsigned int)value;
++ (NSNumber *)numberWithLong:(long)value;
++ (NSNumber *)numberWithUnsignedLong:(unsigned long)value;
++ (NSNumber *)numberWithLongLong:(long long)value;
++ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value;
 + (NSNumber *)numberWithFloat:(float)value;
++ (NSNumber *)numberWithInteger:(NSInteger)value ;
++ (NSNumber *)numberWithUnsignedInteger:(NSUInteger)value ;
 @end
 
+// rdar://16417427
+int big = 1391126400;
+int thousand = 1000;
 int main() {
   NSNumber * N = @3.1415926535;  // expected-error {{declaration of 'numberWithDouble:' is missing in NSNumber class}}
   NSNumber *noNumber = @__objc_yes; // expected-error {{declaration of 'numberWithBool:' is missing in NSNumber class}}
@@ -32,6 +47,9 @@
   int five = 5;
   @-five; // expected-error{{@- must be followed by a number to form an NSNumber object}}
   @+five; // expected-error{{@+ must be followed by a number to form an NSNumber object}}
+  NSNumber *av = @(1391126400000);
+  NSNumber *bv = @(1391126400 * 1000); // expected-warning {{overflow in expression; result is -443003904 with type 'int'}}
+  NSNumber *cv = @(big * thousand);
 }
 
 // Dictionary test
diff --git a/test/SemaObjC/objc-mixed-bridge-attribute.m b/test/SemaObjC/objc-mixed-bridge-attribute.m
new file mode 100644
index 0000000..83fb4d3
--- /dev/null
+++ b/test/SemaObjC/objc-mixed-bridge-attribute.m
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
+// expected-no-diagnostics
+// rdar://17238954
+
+typedef const struct __attribute__((objc_bridge(NSAttributedString))) __CFAttributedString *CFAttributedStringRef;
+
+typedef struct __attribute__((objc_bridge_mutable(NSMutableAttributedString))) __CFAttributedString *CFMutableAttributedStringRef;
+
+@interface NSAttributedString
+@end
+
+@interface NSMutableAttributedString
+@end
+
+struct __CFAttributedString {
+};
+
+void Test1(CFAttributedStringRef attrStr, CFMutableAttributedStringRef mutable_attrStr)
+{
+  id x = (NSAttributedString *) attrStr;
+  id x1 =(NSAttributedString *) mutable_attrStr;
+  id x2 = (NSMutableAttributedString *) attrStr;
+  id x3 = (NSMutableAttributedString *) mutable_attrStr;
+}
+
+void Test2(NSAttributedString *ns_attrStr, NSMutableAttributedString *ns_mutable_attr_Str) {
+  CFAttributedStringRef cfsr = (CFAttributedStringRef) ns_attrStr;
+  CFMutableAttributedStringRef cfsr1 = (CFMutableAttributedStringRef) ns_attrStr;
+  CFAttributedStringRef cfsr2 = (CFAttributedStringRef) ns_mutable_attr_Str;
+  CFMutableAttributedStringRef cfsr3 = (CFMutableAttributedStringRef) ns_mutable_attr_Str;
+}
+
+// Tests with no definition declaration for struct __NDCFAttributedString.
+typedef const struct __attribute__((objc_bridge(NSAttributedString))) __NDCFAttributedString *NDCFAttributedStringRef;
+
+typedef struct __attribute__((objc_bridge_mutable(NSMutableAttributedString))) __NDCFAttributedString *NDCFMutableAttributedStringRef;
+
+void Test3(NDCFAttributedStringRef attrStr, NDCFMutableAttributedStringRef mutable_attrStr)
+{
+  id x = (NSAttributedString *) attrStr;
+  id x1 =(NSAttributedString *) mutable_attrStr;
+  id x2 = (NSMutableAttributedString *) attrStr;
+  id x3 = (NSMutableAttributedString *) mutable_attrStr;
+}
+
+void Test4(NSAttributedString *ns_attrStr, NSMutableAttributedString *ns_mutable_attr_Str) {
+  NDCFAttributedStringRef cfsr = (NDCFAttributedStringRef) ns_attrStr;
+  NDCFMutableAttributedStringRef cfsr1 = (NDCFMutableAttributedStringRef) ns_attrStr;
+  NDCFAttributedStringRef cfsr2 = (NDCFAttributedStringRef) ns_mutable_attr_Str;
+  NDCFMutableAttributedStringRef cfsr3 = (NDCFMutableAttributedStringRef) ns_mutable_attr_Str;
+}
diff --git a/test/SemaObjC/objcbridge-attribute-arc.m b/test/SemaObjC/objcbridge-attribute-arc.m
new file mode 100644
index 0000000..ee2bf07
--- /dev/null
+++ b/test/SemaObjC/objcbridge-attribute-arc.m
@@ -0,0 +1,223 @@
+// RUN: %clang_cc1 -fsyntax-only -x objective-c -fobjc-arc -verify -Wno-objc-root-class %s
+// rdar://15454846
+
+typedef struct __attribute__ ((objc_bridge(NSError))) __CFErrorRef * CFErrorRef; // expected-note 5 {{declared here}}
+
+typedef struct __attribute__ ((objc_bridge(MyError))) __CFMyErrorRef * CFMyErrorRef; // expected-note 1 {{declared here}}
+
+typedef struct __attribute__((objc_bridge(12))) __CFMyColor  *CFMyColorRef; // expected-error {{parameter of 'objc_bridge' attribute must be a single name of an Objective-C class}}
+
+typedef struct __attribute__ ((objc_bridge)) __CFArray *CFArrayRef; // expected-error {{'objc_bridge' attribute takes one argument}}
+
+typedef void *  __attribute__ ((objc_bridge(NSURL))) CFURLRef;  // expected-error {{'objc_bridge' attribute only applies to struct or union}}
+
+typedef void * CFStringRef __attribute__ ((objc_bridge(NSString))); // expected-error {{'objc_bridge' attribute only applies to struct or union}}
+
+typedef struct __attribute__((objc_bridge(NSLocale, NSError))) __CFLocale *CFLocaleRef;// expected-error {{use of undeclared identifier 'NSError'}}
+
+typedef struct __CFData __attribute__((objc_bridge(NSData))) CFDataRef; // expected-error {{'objc_bridge' attribute only applies to struct or union}}
+
+typedef struct __attribute__((objc_bridge(NSDictionary))) __CFDictionary * CFDictionaryRef;
+
+typedef struct __CFSetRef * CFSetRef __attribute__((objc_bridge(NSSet))); // expected-error {{'objc_bridge' attribute only applies to struct or union}};
+
+typedef union __CFUColor __attribute__((objc_bridge(NSUColor))) * CFUColorRef; // expected-error {{'objc_bridge' attribute only applies to struct or union}};
+
+typedef union __CFUColor __attribute__((objc_bridge(NSUColor))) *CFUColor1Ref; // expected-error {{'objc_bridge' attribute only applies to struct or union}};
+
+typedef union __attribute__((objc_bridge(NSUColor))) __CFUPrimeColor XXX;
+typedef XXX *CFUColor2Ref;
+
+@interface I
+{
+   __attribute__((objc_bridge(NSError))) void * color; // expected-error {{'objc_bridge' attribute only applies to struct or union}};
+}
+@end
+
+@protocol NSTesting @end
+@class NSString;
+
+typedef struct __attribute__((objc_bridge(NSTesting))) __CFError *CFTestingRef; // expected-note {{declared here}}
+
+id Test1(CFTestingRef cf) {
+  return (NSString *)cf; // expected-error {{CF object of type 'CFTestingRef' (aka 'struct __CFError *') is bridged to 'NSTesting', which is not an Objective-C class}} \
+                         // expected-error {{cast of C pointer type 'CFTestingRef' (aka 'struct __CFError *') to Objective-C pointer type 'NSString *' requires a bridged cast}} \
+                         // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+                         // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFTestingRef' (aka 'struct __CFError *') into ARC}}
+}
+
+typedef CFErrorRef CFErrorRef1;
+
+typedef CFErrorRef1 CFErrorRef2; // expected-note 2 {{declared here}}
+
+@protocol P1 @end
+@protocol P2 @end
+@protocol P3 @end
+@protocol P4 @end
+@protocol P5 @end
+
+@interface NSError<P1, P2, P3> @end // expected-note 5 {{declared here}}
+
+@interface MyError : NSError // expected-note 1 {{declared here}}
+@end
+
+@interface NSUColor @end
+
+@class NSString;
+
+void Test2(CFErrorRef2 cf, NSError *ns, NSString *str, Class c, CFUColor2Ref cf2) {
+  (void)(NSString *)cf; // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, not 'NSString'}} \
+                        // expected-error {{cast of C pointer type 'CFErrorRef2' (aka 'struct __CFErrorRef *') to Objective-C pointer type 'NSString *' requires a bridged cast}} \
+                        // expected-note {{__bridge to convert directly (no change in ownership)}} \
+                        // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka 'struct __CFErrorRef *') into ARC}}
+  (void)(NSError *)cf; // expected-error {{cast of C pointer type 'CFErrorRef2' (aka 'struct __CFErrorRef *') to Objective-C pointer type 'NSError *' requires a bridged cast}} \
+                       // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+                       // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka 'struct __CFErrorRef *') into ARC}}
+  (void)(MyError*)cf; // expected-error {{cast of C pointer type 'CFErrorRef2' (aka 'struct __CFErrorRef *') to Objective-C pointer type 'MyError *' requires a bridged cast}} \
+                        // expected-note {{__bridge to convert directly (no change in ownership)}} \
+                        // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka 'struct __CFErrorRef *') into ARC}}
+  (void)(NSUColor *)cf2; // expected-error {{cast of C pointer type 'CFUColor2Ref' (aka 'union __CFUPrimeColor *') to Objective-C pointer type 'NSUColor *' requires a bridged cast}} \
+                         // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+                         // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFUColor2Ref' (aka 'union __CFUPrimeColor *') into ARC}}
+  (void)(CFErrorRef)ns; // expected-error {{cast of Objective-C pointer type 'NSError *' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \
+                        // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+ 			// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
+  (void)(CFErrorRef)str;  // expected-warning {{'NSString' cannot bridge to 'CFErrorRef' (aka 'struct __CFErrorRef *')}} \\
+                          // expected-error {{cast of Objective-C pointer type 'NSString *' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \
+                        // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+ 			// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
+  (void)(Class)cf; // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, not 'Class'}} \\
+                   // expected-error {{cast of C pointer type 'CFErrorRef2' (aka 'struct __CFErrorRef *') to Objective-C pointer type 'Class' requires a bridged cast}} \
+ 			// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka 'struct __CFErrorRef *') into ARC}}
+  (void)(CFErrorRef)c; // expected-warning {{'__unsafe_unretained Class' cannot bridge to 'CFErrorRef' (aka 'struct __CFErrorRef *}} \\
+                       // expected-error {{cast of Objective-C pointer type 'Class' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \
+			// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
+}
+
+
+void Test3(CFErrorRef cf, NSError *ns) {
+  (void)(id)cf; // expected-error {{cast of C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') to Objective-C pointer type 'id' requires a bridged cast}} \
+		// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+		// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef' (aka 'struct __CFErrorRef *') into ARC}}
+ (void)(id<P1, P2>)cf; // expected-error {{cast of C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') to Objective-C pointer type 'id<P1,P2>' requires a bridged cast}} \
+		// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+		// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef' (aka 'struct __CFErrorRef *') into ARC}}
+ (void)(id<P1, P2, P4>)cf; // expected-warning {{'CFErrorRef' (aka 'struct __CFErrorRef *') bridges to NSError, not 'id<P1,P2,P4>'}} \
+                           // expected-error {{cast of C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') to Objective-C pointer type 'id<P1,P2,P4>' requires a bridged cast}} \
+		// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+		// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef' (aka 'struct __CFErrorRef *') into ARC}}
+}
+
+void Test4(CFMyErrorRef cf) {
+   (void)(id)cf; // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') to Objective-C pointer type 'id' requires a bridged cast}} \
+			// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') into ARC}}
+ (void)(id<P1, P2>)cf; // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') to Objective-C pointer type 'id<P1,P2>' requires a bridged cast}} \
+			// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') into ARC}}
+ (void)(id<P1, P2, P3>)cf; // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') to Objective-C pointer type 'id<P1,P2,P3>' requires a bridged cast}} \
+			// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') into ARC}}
+ (void)(id<P2, P3>)cf; // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') to Objective-C pointer type 'id<P2,P3>' requires a bridged cast}} \
+			// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') into ARC}}
+ (void)(id<P1, P2, P4>)cf; // expected-warning {{'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') bridges to MyError, not 'id<P1,P2,P4>'}} \
+                           // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') to Objective-C pointer type 'id<P1,P2,P4>' requires a bridged cast}} \
+				// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+				// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') into ARC}}
+}
+
+void Test5(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12, id<P2, P3> P23) {
+ (void)(CFErrorRef)ID; // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \
+			// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
+ (void)(CFErrorRef)P123; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3>' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \
+			// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
+ (void)(CFErrorRef)P1234; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3,P4>' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \
+			// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
+ (void)(CFErrorRef)P12; // expected-error {{cast of Objective-C pointer type 'id<P1,P2>' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \
+			// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
+ (void)(CFErrorRef)P23; // expected-error {{cast of Objective-C pointer type 'id<P2,P3>' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \
+			// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
+}
+
+void Test6(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12, id<P2, P3> P23) {
+
+ (void)(CFMyErrorRef)ID; // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') requires a bridged cast}} \
+				// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+				// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *')}}
+ (void)(CFMyErrorRef)P123; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3>' to C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') requires a bridged cast}} \
+				// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+				// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *')}}
+ (void)(CFMyErrorRef)P1234; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3,P4>' to C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') requires a bridged cast}} \
+				// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+				// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *')}}
+ (void)(CFMyErrorRef)P12; // expected-error {{cast of Objective-C pointer type 'id<P1,P2>' to C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') requires a bridged cast}} \
+				// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+				// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *')}}
+ (void)(CFMyErrorRef)P23; // expected-error {{cast of Objective-C pointer type 'id<P2,P3>' to C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') requires a bridged cast}} \
+				// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+				// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *')}}
+}
+
+typedef struct __attribute__ ((objc_bridge(MyPersonalError))) __CFMyPersonalErrorRef * CFMyPersonalErrorRef;  // expected-note 1 {{declared here}}
+
+@interface MyPersonalError : NSError <P4> // expected-note 1 {{declared here}}
+@end
+
+void Test7(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12, id<P2, P3> P23) {
+ (void)(CFMyPersonalErrorRef)ID; // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') requires a bridged cast}} \
+				 // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+				 // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *')}}
+ (void)(CFMyPersonalErrorRef)P123; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3>' to C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') requires a bridged cast}} \
+				 // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+				 // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *')}}
+ (void)(CFMyPersonalErrorRef)P1234; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3,P4>' to C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') requires a bridged cast}} \
+				 // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+				 // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *')}}
+ (void)(CFMyPersonalErrorRef)P12; // expected-error {{cast of Objective-C pointer type 'id<P1,P2>' to C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') requires a bridged cast}} \
+				 // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+				 // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *')}}
+ (void)(CFMyPersonalErrorRef)P23; // expected-error {{cast of Objective-C pointer type 'id<P2,P3>' to C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') requires a bridged cast}} \
+				 // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+				 // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *')}}
+}
+
+void Test8(CFMyPersonalErrorRef cf) {
+  (void)(id)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') to Objective-C pointer type 'id' requires a bridged cast}} \
+		// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+		// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') into ARC}}
+  (void)(id<P1>)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1>' requires a bridged cast}} \
+		// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+		// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') into ARC}}
+  (void)(id<P1, P2>)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1,P2>' requires a bridged cast}} \
+		// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+		// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') into ARC}}
+  (void)(id<P1, P2, P3>)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1,P2,P3>' requires a bridged cast}} \
+		// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+		// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') into ARC}}
+  (void)(id<P1, P2, P3, P4>)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1,P2,P3,P4>' requires a bridged cast}} \
+		// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+		// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') into ARC}}
+  (void)(id<P1, P2, P3, P4, P5>)cf; // expected-warning {{'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') bridges to MyPersonalError, not 'id<P1,P2,P3,P4,P5>'}} \
+                                    // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1,P2,P3,P4,P5>' requires a bridged cast}} \
+		// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+		// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') into ARC}}
+}
+
+void Test9(CFErrorRef2 cf, NSError *ns, NSString *str, Class c, CFUColor2Ref cf2) {
+  (void)(__bridge NSString *)cf; // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, not 'NSString'}}
+  (void)(__bridge NSError *)cf; // okay
+  (void)(__bridge MyError*)cf; // okay,
+  (void)(__bridge NSUColor *)cf2; // okay
+  (void)(__bridge CFErrorRef)ns; // okay
+  (void)(__bridge CFErrorRef)str;  // expected-warning {{'NSString' cannot bridge to 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
+  (void)(__bridge Class)cf; // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, not 'Class'}}
+  (void)(__bridge CFErrorRef)c; // expected-warning {{'__unsafe_unretained Class' cannot bridge to 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
+}
diff --git a/test/SemaObjC/objcbridge-attribute.m b/test/SemaObjC/objcbridge-attribute.m
index cc5eb21..a268cae 100644
--- a/test/SemaObjC/objcbridge-attribute.m
+++ b/test/SemaObjC/objcbridge-attribute.m
@@ -1,34 +1,36 @@
-// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -verify -Wno-objc-root-class %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
 // rdar://15454846
 
-typedef struct __attribute__ ((objc_bridge(NSError))) __CFErrorRef * CFErrorRef; // expected-note 2 {{declared here}}
+typedef struct __attribute__ ((objc_bridge(NSError))) __CFErrorRef * CFErrorRef; // expected-note 3 {{declared here}}
+
+typedef struct __attribute__ ((objc_bridge(MyError))) __CFMyErrorRef * CFMyErrorRef; // expected-note 1 {{declared here}}
 
 typedef struct __attribute__((objc_bridge(12))) __CFMyColor  *CFMyColorRef; // expected-error {{parameter of 'objc_bridge' attribute must be a single name of an Objective-C class}}
 
-typedef struct __attribute__ ((objc_bridge)) __CFArray *CFArrayRef; // expected-error {{parameter of 'objc_bridge' attribute must be a single name of an Objective-C class}}
+typedef struct __attribute__ ((objc_bridge)) __CFArray *CFArrayRef; // expected-error {{'objc_bridge' attribute takes one argument}}
 
-typedef void *  __attribute__ ((objc_bridge(NSURL))) CFURLRef;  // expected-error {{'objc_bridge' attribute must be applied to a struct or union}}
+typedef void *  __attribute__ ((objc_bridge(NSURL))) CFURLRef;  // expected-error {{'objc_bridge' attribute only applies to struct or union}}
 
-typedef void * CFStringRef __attribute__ ((objc_bridge(NSString))); // expected-error {{'objc_bridge' attribute must be applied to a struct or union}}
+typedef void * CFStringRef __attribute__ ((objc_bridge(NSString))); // expected-error {{'objc_bridge' attribute only applies to struct or union}}
 
 typedef struct __attribute__((objc_bridge(NSLocale, NSError))) __CFLocale *CFLocaleRef;// expected-error {{use of undeclared identifier 'NSError'}}
 
-typedef struct __CFData __attribute__((objc_bridge(NSData))) CFDataRef; // expected-error {{'objc_bridge' attribute must be applied to a struct or union}}
+typedef struct __CFData __attribute__((objc_bridge(NSData))) CFDataRef; // expected-error {{'objc_bridge' attribute only applies to struct or union}}
 
-typedef struct __attribute__((objc_bridge(NSDictionary))) __CFDictionary * CFDictionaryRef;
+typedef struct __attribute__((objc_bridge(NSDictionary))) __CFDictionary * CFDictionaryRef; // expected-note {{declared here}}
 
-typedef struct __CFSetRef * CFSetRef __attribute__((objc_bridge(NSSet))); // expected-error {{'objc_bridge' attribute must be applied to a struct or union}};
+typedef struct __CFSetRef * CFSetRef __attribute__((objc_bridge(NSSet))); // expected-error {{'objc_bridge' attribute only applies to struct or union}};
 
-typedef union __CFUColor __attribute__((objc_bridge(NSUColor))) * CFUColorRef; // expected-error {{'objc_bridge' attribute must be applied to a struct or union}};
+typedef union __CFUColor __attribute__((objc_bridge(NSUColor))) * CFUColorRef; // expected-error {{'objc_bridge' attribute only applies to struct or union}};
 
-typedef union __CFUColor __attribute__((objc_bridge(NSUColor))) *CFUColor1Ref; // expected-error {{'objc_bridge' attribute must be applied to a struct or union}};
+typedef union __CFUColor __attribute__((objc_bridge(NSUColor))) *CFUColor1Ref; // expected-error {{'objc_bridge' attribute only applies to struct or union}};
 
 typedef union __attribute__((objc_bridge(NSUColor))) __CFUPrimeColor XXX;
 typedef XXX *CFUColor2Ref;
 
 @interface I
 {
-   __attribute__((objc_bridge(NSError))) void * color; // expected-error {{'objc_bridge' attribute must be applied to a struct or union}};
+   __attribute__((objc_bridge(NSError))) void * color; // expected-error {{'objc_bridge' attribute only applies to struct or union}};
 }
 @end
 
@@ -43,11 +45,17 @@
 
 typedef CFErrorRef CFErrorRef1;
 
-typedef CFErrorRef1 CFErrorRef2;
+typedef CFErrorRef1 CFErrorRef2; // expected-note {{declared here}}
 
-@interface NSError @end
+@protocol P1 @end
+@protocol P2 @end
+@protocol P3 @end
+@protocol P4 @end
+@protocol P5 @end
 
-@interface MyError : NSError
+@interface NSError<P1, P2, P3> @end // expected-note 3 {{declared here}}
+
+@interface MyError : NSError // expected-note 1 {{declared here}}
 @end
 
 @interface NSUColor @end
@@ -64,3 +72,64 @@
   (void)(Class)cf; // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, not 'Class'}}
   (void)(CFErrorRef)c; // expected-warning {{'Class' cannot bridge to 'CFErrorRef'}}
 }
+
+
+void Test3(CFErrorRef cf, NSError *ns) {
+  (void)(id)cf; // okay
+ (void)(id<P1, P2>)cf; // okay
+ (void)(id<P1, P2, P4>)cf; // expected-warning {{'CFErrorRef' (aka 'struct __CFErrorRef *') bridges to NSError, not 'id<P1,P2,P4>'}}
+}
+
+void Test4(CFMyErrorRef cf) {
+   (void)(id)cf; // okay
+ (void)(id<P1, P2>)cf; // ok
+ (void)(id<P1, P2, P3>)cf; // ok
+ (void)(id<P2, P3>)cf; // ok
+ (void)(id<P1, P2, P4>)cf; // expected-warning {{'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') bridges to MyError, not 'id<P1,P2,P4>'}}
+}
+
+void Test5(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12, id<P2, P3> P23) {
+ (void)(CFErrorRef)ID; // ok
+ (void)(CFErrorRef)P123; // ok
+ (void)(CFErrorRef)P1234; // ok
+ (void)(CFErrorRef)P12; // ok 
+ (void)(CFErrorRef)P23; // ok
+}
+
+void Test6(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12, id<P2, P3> P23) {
+
+ (void)(CFMyErrorRef)ID; // ok
+ (void)(CFMyErrorRef)P123; // ok
+ (void)(CFMyErrorRef)P1234; // ok
+ (void)(CFMyErrorRef)P12; // ok
+ (void)(CFMyErrorRef)P23; // ok
+}
+
+typedef struct __attribute__ ((objc_bridge(MyPersonalError))) __CFMyPersonalErrorRef * CFMyPersonalErrorRef;  // expected-note 1 {{declared here}}
+
+@interface MyPersonalError : NSError <P4> // expected-note 1 {{declared here}}
+@end
+
+void Test7(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12, id<P2, P3> P23) {
+ (void)(CFMyPersonalErrorRef)ID; // ok
+ (void)(CFMyPersonalErrorRef)P123; // ok
+ (void)(CFMyPersonalErrorRef)P1234; // ok
+ (void)(CFMyPersonalErrorRef)P12; // ok
+ (void)(CFMyPersonalErrorRef)P23; // ok
+}
+
+void Test8(CFMyPersonalErrorRef cf) {
+  (void)(id)cf; // ok
+  (void)(id<P1>)cf; // ok
+  (void)(id<P1, P2>)cf; // ok
+  (void)(id<P1, P2, P3>)cf; // ok
+  (void)(id<P1, P2, P3, P4>)cf; // ok
+  (void)(id<P1, P2, P3, P4, P5>)cf; // expected-warning {{'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') bridges to MyPersonalError, not 'id<P1,P2,P3,P4,P5>'}}
+}
+
+CFDictionaryRef bar() __attribute__((cf_returns_not_retained));
+@class NSNumber;
+
+void Test9() {
+  NSNumber *w2 = (NSNumber*) bar(); // expected-error {{CF object of type 'CFDictionaryRef' (aka 'struct __CFDictionary *') is bridged to 'NSDictionary', which is not an Objective-C class}}
+}
diff --git a/test/SemaObjC/objcbridge-related-attribute.m b/test/SemaObjC/objcbridge-related-attribute.m
new file mode 100644
index 0000000..06c2e87
--- /dev/null
+++ b/test/SemaObjC/objcbridge-related-attribute.m
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -fsyntax-only -x objective-c -verify -Wno-objc-root-class %s
+// rdar://15499111
+
+typedef struct __attribute__((objc_bridge_related(NSColor,colorWithCGColor:,CGColor))) CGColor *CGColorRef; // expected-note 5 {{declared here}}
+typedef struct __attribute__((objc_bridge_related(NSColor,,CGColor1))) CGColor1 *CGColorRef1;
+typedef struct __attribute__((objc_bridge_related(NSColor,,))) CGColor2 *CGColorRef2;
+
+@interface NSColor // expected-note 5 {{declared here}}
++ (NSColor *)colorWithCGColor:(CGColorRef)cgColor;
+- (CGColorRef)CGColor;
+- (CGColorRef1)CGColor1;
+@end
+
+@interface NSTextField 
+- (void)setBackgroundColor:(NSColor *)color;
+- (NSColor *)backgroundColor;
+@end
+
+void foo(NSColor*); // expected-note {{passing argument to parameter here}}
+
+NSColor * Test1(NSTextField *textField, CGColorRef newColor) {
+  foo(newColor); // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *'; use '+colorWithCGColor:' method for this conversion}}
+  textField.backgroundColor = newColor; // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *'; use '+colorWithCGColor:' method for this conversion}}
+  return newColor; // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *'; use '+colorWithCGColor:' method for this conversion}}
+}
+
+NSColor * Test2(NSTextField *textField, CGColorRef1 newColor) {
+  foo(newColor); // expected-warning {{incompatible pointer types passing 'CGColorRef1'}}
+  textField.backgroundColor = newColor; // expected-warning {{incompatible pointer types assigning}}
+  return newColor; // expected-warning {{incompatible pointer types returning}}
+}
+
+CGColorRef Test3(NSTextField *textField, CGColorRef newColor) {
+  newColor = textField.backgroundColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'struct CGColor *'); use '-CGColor' method for this conversion}}
+  return textField.backgroundColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'struct CGColor *'); use '-CGColor' method for this conversion}}
+}
+
+CGColorRef2 Test4(NSTextField *textField, CGColorRef2 newColor) {
+  newColor = textField.backgroundColor; // expected-warning {{incompatible pointer types assigning}}
+  return textField.backgroundColor; // expected-warning {{incompatible pointer types returning}}
+}
diff --git a/test/SemaObjC/objcbridgemutable-attribute.m b/test/SemaObjC/objcbridgemutable-attribute.m
new file mode 100644
index 0000000..4ec8de0
--- /dev/null
+++ b/test/SemaObjC/objcbridgemutable-attribute.m
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
+// rdar://15498044
+
+typedef struct __attribute__((objc_bridge_mutable(NSMutableDictionary))) __CFDictionary * CFMutableDictionaryRef; // expected-note {{declared here}}
+
+typedef struct __attribute__((objc_bridge_mutable(12))) __CFDictionaryB1 * CFMutableDictionaryB1Ref; // expected-error {{parameter of 'objc_bridge_mutable' attribute must be a single name of an Objective-C class}}
+
+typedef struct __attribute__((objc_bridge_mutable(P))) __CFDictionaryB2 * CFMutableDictionaryB2Ref; // expected-note {{declared here}}
+
+typedef struct __attribute__((objc_bridge_mutable(NSMutableDictionary, Unknown))) __CFDictionaryB3 * CFMutableDictionaryB3Ref;  // expected-error {{use of undeclared identifier 'Unknown'}}
+
+typedef struct __attribute__((objc_bridge_mutable)) __CFDictionaryB4 * CFMutableDictionaryB4Ref;  // expected-error {{'objc_bridge_mutable' attribute takes one argument}}
+
+@interface NSDictionary
+@end
+
+@interface NSMutableDictionary : NSDictionary
+@end
+
+@protocol P @end
+
+void Test(NSMutableDictionary *md, NSDictionary *nd, CFMutableDictionaryRef mcf, CFMutableDictionaryB2Ref bmcf) {
+
+  (void) (CFMutableDictionaryRef)md;
+  (void) (CFMutableDictionaryRef)nd; // expected-warning {{'NSDictionary' cannot bridge to 'CFMutableDictionaryRef' (aka 'struct __CFDictionary *')}}
+  (void) (NSDictionary *)mcf;  // expected-warning {{'CFMutableDictionaryRef' (aka 'struct __CFDictionary *') bridges to NSMutableDictionary, not 'NSDictionary'}}
+  (void) (NSMutableDictionary *)mcf; // ok;
+  (void) (NSMutableDictionary *)bmcf; // expected-error {{CF object of type 'CFMutableDictionaryB2Ref' (aka 'struct __CFDictionaryB2 *') is bridged to 'P', which is not an Objective-C class}}
+  
+}
+
diff --git a/test/SemaObjC/opaque-is-access-warn.m b/test/SemaObjC/opaque-is-access-warn.m
new file mode 100644
index 0000000..ac0f724
--- /dev/null
+++ b/test/SemaObjC/opaque-is-access-warn.m
@@ -0,0 +1,24 @@
+// RUN: %clang -target x86_64-apple-darwin -arch arm64 -mios-version-min=7 -fsyntax-only -Wdeprecated-objc-isa-usage %s -Xclang -verify
+// RUN: %clang -target x86_64-apple-darwin -arch arm64 -mios-version-min=7 -fsyntax-only %s -Xclang -verify
+// RUN: %clang -target x86_64-apple-darwin -mios-simulator-version-min=7 -fsyntax-only -Wdeprecated-objc-isa-usage %s -Xclang -verify
+// rdar://10709102
+
+typedef struct objc_object {
+  struct objc_class *isa;
+} *id;
+
+@interface NSObject {
+  struct objc_class *isa;
+}
+@end
+@interface Whatever : NSObject
++self;
+@end
+
+static void func() {
+
+  id x;
+
+  [(*x).isa self]; // expected-error {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}}
+  [x->isa self];   // expected-error {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}}
+}
diff --git a/test/SemaObjC/opaque-is-access.m b/test/SemaObjC/opaque-is-access.m
new file mode 100644
index 0000000..89d91b3
--- /dev/null
+++ b/test/SemaObjC/opaque-is-access.m
@@ -0,0 +1,23 @@
+// RUN: %clang -target x86_64-apple-darwin -arch arm64 -mios-version-min=7 -fsyntax-only %s -Xclang -verify
+// RUN: %clang -target x86_64-apple-darwin -arch x86_64 -mios-simulator-version-min=7 -fsyntax-only %s -Xclang -verify
+// rdar://10709102
+
+typedef struct objc_object {
+  struct objc_class *isa;
+} *id;
+
+@interface NSObject {
+  struct objc_class *isa;
+}
+@end
+@interface Whatever : NSObject
++self;
+@end
+
+static void func() {
+
+  id x;
+
+  [(*x).isa self]; // expected-error {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}}
+  [x->isa self];   // expected-error {{direct access to Objective-C's isa is deprecated in favor of object_getClass()}}
+}
diff --git a/test/SemaObjC/overriding-property-in-class-extension.m b/test/SemaObjC/overriding-property-in-class-extension.m
index 8c0e1b9..77efd55 100644
--- a/test/SemaObjC/overriding-property-in-class-extension.m
+++ b/test/SemaObjC/overriding-property-in-class-extension.m
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1  -fsyntax-only -verify -Weverything %s
+// expected-no-diagnostics
 // rdar://12103434
 
 @class NSString;
@@ -7,7 +8,7 @@
 
 @interface MyClass  : NSObject
 
-@property (nonatomic, copy, readonly) NSString* name; // expected-warning {{property attributes 'readonly' and 'copy' are mutually exclusive}}
+@property (nonatomic, copy, readonly) NSString* name;
 
 @end
 
diff --git a/test/SemaObjC/property-10.m b/test/SemaObjC/property-10.m
index 8cb8ec6..b2aaf2b 100644
--- a/test/SemaObjC/property-10.m
+++ b/test/SemaObjC/property-10.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wreadonly-setter-attrs -verify %s  -fblocks
+// RUN: %clang_cc1 -fsyntax-only -verify %s  -fblocks
 
 // Check property attribute consistency.
 
diff --git a/test/SemaObjC/property-12.m b/test/SemaObjC/property-12.m
index c4a7555..5fc311a 100644
--- a/test/SemaObjC/property-12.m
+++ b/test/SemaObjC/property-12.m
@@ -1,15 +1,15 @@
-// RUN: %clang_cc1 -fsyntax-only -Wno-objc-root-class -Wreadonly-setter-attrs -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-objc-root-class -verify %s
 
 @protocol P0
-@property(readonly,assign) id X; // expected-warning {{property attributes 'readonly' and 'assign' are mutually exclusive}}
+@property(readonly,assign) id X;
 @end
 
 @protocol P1
-@property(readonly,retain) id X; // expected-warning {{property attributes 'readonly' and 'retain' are mutually exclusive}}
+@property(readonly,retain) id X;
 @end
 
 @protocol P2
-@property(readonly,copy) id X; // expected-warning {{property attributes 'readonly' and 'copy' are mutually exclusive}}
+@property(readonly,copy) id X;
 @end
 
 @protocol P3
diff --git a/test/SemaObjC/property-deprecated-warning.m b/test/SemaObjC/property-deprecated-warning.m
index 7e10356..4beb23a 100644
--- a/test/SemaObjC/property-deprecated-warning.m
+++ b/test/SemaObjC/property-deprecated-warning.m
@@ -5,7 +5,7 @@
 typedef signed char BOOL;
 
 @protocol P
-@property(nonatomic,assign) id ptarget __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{property 'ptarget' is declared deprecated here}} expected-note {{method 'ptarget' declared here}}
+@property(nonatomic,assign) id ptarget __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{property 'ptarget' is declared deprecated here}} expected-note {{'ptarget' has been explicitly marked deprecated here}}
 @end
 
 @protocol P1<P>
@@ -14,7 +14,7 @@
 
 
 @interface UITableViewCell<P1>
-@property(nonatomic,assign) id target __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{property 'target' is declared deprecated here}} expected-note {{method 'setTarget:' declared here}}
+@property(nonatomic,assign) id target __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{property 'target' is declared deprecated here}} expected-note {{'setTarget:' has been explicitly marked deprecated here}}
 @end
 
 @interface PSTableCell : UITableViewCell
@@ -22,9 +22,9 @@
 @end
 
 @interface UITableViewCell(UIDeprecated)
-@property(nonatomic,assign) id dep_target  __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note 2 {{method 'dep_target' declared here}} \
+@property(nonatomic,assign) id dep_target  __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note 2 {{'dep_target' has been explicitly marked deprecated here}} \
                                                                                     // expected-note 4 {{property 'dep_target' is declared deprecated here}} \
-                                                                                    // expected-note 2 {{method 'setDep_target:' declared here}}
+                                                                                    // expected-note 2 {{'setDep_target:' has been explicitly marked deprecated here}}
 @end
 
 @implementation PSTableCell
@@ -55,9 +55,9 @@
 
 
 @interface CustomAccessorNames
-@property(getter=isEnabled,assign) BOOL enabled __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{method 'isEnabled' declared here}} expected-note {{property 'enabled' is declared deprecated here}}
+@property(getter=isEnabled,assign) BOOL enabled __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{'isEnabled' has been explicitly marked deprecated here}} expected-note {{property 'enabled' is declared deprecated here}}
 
-@property(setter=setNewDelegate:,assign) id delegate __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{method 'setNewDelegate:' declared here}} expected-note {{property 'delegate' is declared deprecated here}}
+@property(setter=setNewDelegate:,assign) id delegate __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{'setNewDelegate:' has been explicitly marked deprecated here}} expected-note {{property 'delegate' is declared deprecated here}}
 @end
 
 void testCustomAccessorNames(CustomAccessorNames *obj) {
@@ -78,3 +78,28 @@
     return [obj ptarget];  // no-warning
   return [obj2 ptarget];   // expected-warning {{'ptarget' is deprecated: first deprecated in iOS 3.0}}
 }
+
+// rdar://15951801
+@interface Foo
+{
+  int _x;
+}
+@property(nonatomic,readonly) int x;
+- (void)setX:(int)x __attribute__ ((deprecated)); // expected-note 2 {{'setX:' has been explicitly marked deprecated here}}
+- (int)x __attribute__ ((unavailable)); // expected-note {{'x' has been explicitly marked unavailable here}}
+@end
+
+@implementation Foo
+- (void)setX:(int)x {
+	_x = x;
+}
+- (int)x {
+  return _x;
+}
+@end
+
+void testUserAccessorAttributes(Foo *foo) {
+        [foo setX:5678]; // expected-warning {{'setX:' is deprecated}}
+	foo.x = foo.x; // expected-error {{property access is using 'x' method which is unavailable}} \
+		       // expected-warning {{property access is using 'setX:' method which is deprecated}}
+}
diff --git a/test/SemaObjC/property-in-class-extension-1.m b/test/SemaObjC/property-in-class-extension-1.m
index 51837fd..ab461ef 100644
--- a/test/SemaObjC/property-in-class-extension-1.m
+++ b/test/SemaObjC/property-in-class-extension-1.m
@@ -8,20 +8,19 @@
 
 @property (nonatomic, readonly) NSString* addingMemoryModel;
 
-@property (nonatomic, copy, readonly) NSString* matchingMemoryModel; // expected-warning {{property attributes 'readonly' and 'copy' are mutually exclusive}}
+@property (nonatomic, copy, readonly) NSString* matchingMemoryModel;
 
-@property (nonatomic, retain, readonly) NSString* addingNoNewMemoryModel; // expected-warning {{property attributes 'readonly' and 'retain' are mutually exclusive}}
+@property (nonatomic, retain, readonly) NSString* addingNoNewMemoryModel;
 
 @property (readonly) NSString* none;
 @property (readonly) NSString* none1;
 
-@property (assign, readonly) NSString* changeMemoryModel; // expected-note {{property declared here}} \
-                                                          // expected-warning {{property attributes 'readonly' and 'assign' are mutually exclusive}}
+@property (assign, readonly) NSString* changeMemoryModel; // expected-note {{property declared here}}
 
 @property (readonly) __weak id weak_prop;
 @property (readonly) __weak id weak_prop1;
 
-@property (assign, readonly) NSString* assignProperty; // expected-warning {{property attributes 'readonly' and 'assign' are mutually exclusive}}
+@property (assign, readonly) NSString* assignProperty;
 
 @property (readonly) NSString* readonlyProp;
 
diff --git a/test/SemaObjC/property-inherited.m b/test/SemaObjC/property-inherited.m
index f5f1b42..cd223dd 100644
--- a/test/SemaObjC/property-inherited.m
+++ b/test/SemaObjC/property-inherited.m
@@ -44,3 +44,29 @@
 @property(assign) Data *p_base;	
 @property(assign) NSData *p_data;	// expected-warning{{property type 'NSData *' is incompatible with type 'NSMutableData *' inherited from 'Base'}}
 @end
+
+// rdar://15967517
+@protocol P1
+@property (nonatomic) void* selected;
+@end
+
+@protocol P2
+@property (nonatomic) void* selected; // expected-note {{property declared here}}
+@end
+
+@interface MKAnnotationView <P1>
+@property (nonatomic) void* selected; // expected-note {{property declared here}}
+@property (nonatomic) char selected2;
+@end
+
+@interface Parent : MKAnnotationView <P2>
+@property (nonatomic) void* selected1; // expected-note {{property declared here}}
+@property (nonatomic) char selected2;
+@end
+
+@interface Child : Parent
+@property (nonatomic) char selected; // expected-warning {{property type 'char' is incompatible with type 'void *' inherited from 'MKAnnotationView'}} \
+				     // expected-warning {{property type 'char' is incompatible with type 'void *' inherited from 'P2'}}
+@property (nonatomic) char selected1; // expected-warning {{property type 'char' is incompatible with type 'void *' inherited from 'Parent'}}
+@property (nonatomic) char selected2;
+@end
diff --git a/test/SemaObjC/property-noninherited-availability-attr.m b/test/SemaObjC/property-noninherited-availability-attr.m
index 0c2a5d3..dfa72d1 100644
--- a/test/SemaObjC/property-noninherited-availability-attr.m
+++ b/test/SemaObjC/property-noninherited-availability-attr.m
@@ -1,17 +1,16 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.8.0 -fsyntax-only -verify %s
 
-// This test case shows that 'availablity' and 'deprecated' does not inherit
+// This test case shows that 'availability' and 'deprecated' do not inherit
 // when a property is redeclared in a subclass.  This is intentional.
 
 @interface NSObject @end
 @protocol myProtocol
-@property int myProtocolProperty __attribute__((availability(macosx,introduced=10.7,deprecated=10.8))); // expected-note {{method 'myProtocolProperty' declared here}} \
+@property int myProtocolProperty __attribute__((availability(macosx,introduced=10.7,deprecated=10.8))); // expected-note {{'myProtocolProperty' has been explicitly marked deprecated here}} \
                                                                                                         // expected-note {{property 'myProtocolProperty' is declared deprecated here}}
 @end
 
 @interface Foo : NSObject
-@property int myProperty __attribute__((availability(macosx,introduced=10.7,deprecated=10.8)));  // expected-note {{'myProperty' declared here}} \
-								// expected-note {{method 'myProperty' declared here}} \
+@property int myProperty __attribute__((availability(macosx,introduced=10.7,deprecated=10.8)));  // expected-note 2 {{'myProperty' has been explicitly marked deprecated here}} \
 								// expected-note {{property 'myProperty' is declared deprecated here}}
 @end
 
@@ -22,13 +21,13 @@
 
 void test(Foo *y, Bar *x, id<myProtocol> z) {
   y.myProperty = 0; // expected-warning {{'myProperty' is deprecated: first deprecated in OS X 10.8}}
-  [y myProperty];   // expected-warning {{'myProperty' is deprecated: first deprecated in OS X 10.8}} 
+  (void)[y myProperty];   // expected-warning {{'myProperty' is deprecated: first deprecated in OS X 10.8}} 
 
   x.myProperty = 1; // no-warning
-  [x myProperty]; // no-warning
+  (void)[x myProperty]; // no-warning
 
   x.myProtocolProperty = 0; // no-warning
 
-  [x myProtocolProperty]; // no-warning
-  [z myProtocolProperty]; // expected-warning {{'myProtocolProperty' is deprecated: first deprecated in OS X 10.8}}
+  (void)[x myProtocolProperty]; // no-warning
+  (void)[z myProtocolProperty]; // expected-warning {{'myProtocolProperty' is deprecated: first deprecated in OS X 10.8}}
 }
diff --git a/test/SemaObjC/property-typecheck-1.m b/test/SemaObjC/property-typecheck-1.m
index 58d0f21..5fb05c8 100644
--- a/test/SemaObjC/property-typecheck-1.m
+++ b/test/SemaObjC/property-typecheck-1.m
@@ -93,7 +93,7 @@
  return container.pieces; // expected-warning {{type of property 'pieces' does not match type of accessor 'pieces'}}
 }
 
-- (id)firstPeice
+- (id)firstPiece
 {
   return container.first;
 }
diff --git a/test/SemaObjC/protocol-attribute.m b/test/SemaObjC/protocol-attribute.m
index b2aecc2..52bd441 100644
--- a/test/SemaObjC/protocol-attribute.m
+++ b/test/SemaObjC/protocol-attribute.m
@@ -6,7 +6,7 @@
 Class <FwProto> cFw = 0;  // expected-error {{'FwProto' is unavailable}}
 
 
-__attribute ((deprecated)) @protocol MyProto1 // expected-note 7 {{declared here}}
+__attribute ((deprecated)) @protocol MyProto1 // expected-note 7 {{'MyProto1' has been explicitly marked deprecated here}}
 @end
 
 @protocol Proto2  <MyProto1>  // expected-warning {{'MyProto1' is deprecated}}
diff --git a/test/SemaObjC/protocols-suppress-conformance.m b/test/SemaObjC/protocols-suppress-conformance.m
new file mode 100644
index 0000000..299e44e
--- /dev/null
+++ b/test/SemaObjC/protocols-suppress-conformance.m
@@ -0,0 +1,207 @@
+// RUN: %clang_cc1  -triple x86_64-apple-darwin11 -fsyntax-only -verify %s -Wno-objc-root-class
+
+// Mark this protocol as requiring all of its methods and properties
+// to be explicitly implemented in the adopting class.
+__attribute__((objc_protocol_requires_explicit_implementation))
+@protocol Protocol
+- (void) theBestOfTimes; // expected-note {{method 'theBestOfTimes' declared here}}
+@property (readonly) id theWorstOfTimes; // expected-note {{property declared here}}
+@end
+
+// In this example, ClassA adopts the protocol.  We won't
+// provide the implementation here, but this protocol will
+// be adopted later by a subclass.
+@interface ClassA <Protocol>
+- (void) theBestOfTimes;
+@property (readonly) id theWorstOfTimes;
+@end
+
+// This class subclasses ClassA (which also adopts 'Protocol').
+@interface ClassB : ClassA <Protocol>
+@end
+
+@implementation ClassB // expected-warning {{property 'theWorstOfTimes' requires method 'theWorstOfTimes' to be defined - use @synthesize, @dynamic or provide a method implementation in this class implementation}}
+@end
+
+@interface ClassB_Good : ClassA <Protocol>
+@end
+
+@implementation ClassB_Good // no-warning
+- (void) theBestOfTimes {}
+@dynamic theWorstOfTimes;
+@end
+
+@interface ClassB_AlsoGood : ClassA <Protocol>
+@property (readonly) id theWorstOfTimes;
+@end
+
+// Default synthesis acts as if @dynamic
+// had been written for 'theWorstOfTimes' because
+// it is declared in ClassA.  This is okay, since
+// the author of ClassB_AlsoGood needs explicitly
+// write @property in the @interface.
+@implementation ClassB_AlsoGood // no-warning
+- (void) theBestOfTimes {}
+@end
+
+// Test that inherited protocols do not get the explicit conformance requirement.
+@protocol Inherited
+- (void) fairIsFoul;
+@end
+
+__attribute__((objc_protocol_requires_explicit_implementation))
+@protocol Derived <Inherited>
+- (void) foulIsFair; // expected-note {{method 'foulIsFair' declared here}}
+@end
+
+@interface ClassC <Inherited>
+@end
+
+@interface ClassD : ClassC <Derived>
+@end
+
+@implementation ClassD // expected-warning {{method 'foulIsFair' in protocol 'Derived' not implemented}}
+@end
+
+// Test that the attribute is used correctly.
+__attribute__((objc_protocol_requires_explicit_implementation(1+2))) // expected-error {{attribute takes no arguments}}
+@protocol AnotherProtocol @end
+
+// Cannot put the attribute on classes or other non-protocol declarations.
+__attribute__((objc_protocol_requires_explicit_implementation)) // expected-error {{attribute only applies to Objective-C protocols}}
+@interface AnotherClass @end
+
+__attribute__((objc_protocol_requires_explicit_implementation)) // expected-error {{attribute only applies to Objective-C protocols}}
+int x;
+
+// Test that inherited protocols with the attribute
+// are treated properly.
+__attribute__((objc_protocol_requires_explicit_implementation))
+@protocol ProtocolA
+@required
+- (void)rlyeh; // expected-note 2 {{method 'rlyeh' declared here}}
+- (void)innsmouth; // expected-note 2 {{method 'innsmouth' declared here}}
+@end
+
+@protocol ProtocolB <ProtocolA>
+@required
+- (void)dunwich;
+- (void)innsmouth; // expected-note {{method 'innsmouth' declared here}}
+@end
+
+__attribute__((objc_protocol_requires_explicit_implementation))
+@protocol ProtocolB_Explicit <ProtocolA>
+@required
+- (void)dunwich;
+- (void)innsmouth; // expected-note 2 {{method 'innsmouth' declared here}}
+@end
+
+@protocol ProtocolC
+@required
+- (void)rlyeh;
+- (void)innsmouth;
+- (void)dunwich;
+@end
+
+@interface MyObject <ProtocolC> @end
+
+// Provide two variants of a base class, one that adopts ProtocolA and
+// one that does not.
+@interface Lovecraft <ProtocolA> @end
+@interface Lovecraft_2 @end
+
+// Provide two variants of a subclass that conform to ProtocolB.  One
+// subclasses from a class that conforms to ProtocolA, the other that
+// does not.
+//
+// From those, provide two variants that conformat to ProtocolB_Explicit
+// instead.
+@interface Shoggoth : Lovecraft <ProtocolB> @end
+@interface Shoggoth_2 : Lovecraft_2 <ProtocolB> @end
+@interface Shoggoth_Explicit : Lovecraft <ProtocolB_Explicit> @end
+@interface Shoggoth_2_Explicit : Lovecraft_2 <ProtocolB_Explicit> @end
+
+@implementation MyObject
+- (void)innsmouth {}
+- (void)rlyeh {}
+- (void)dunwich {}
+@end
+
+@implementation Lovecraft
+- (void)innsmouth {}
+- (void)rlyeh {}
+@end
+
+@implementation Shoggoth
+- (void)dunwich {}
+@end
+
+@implementation Shoggoth_2 // expected-warning {{method 'innsmouth' in protocol 'ProtocolB' not implemented}}\
+                           // expected-warning {{method 'rlyeh' in protocol 'ProtocolA' not implemented}}\
+                           // expected-warning {{'innsmouth' in protocol 'ProtocolA' not implemented}} 
+- (void)dunwich {}
+@end
+
+@implementation Shoggoth_Explicit // expected-warning {{method 'innsmouth' in protocol 'ProtocolB_Explicit' not implemented}}
+- (void)dunwich {}
+@end
+
+@implementation Shoggoth_2_Explicit // expected-warning {{method 'innsmouth' in protocol 'ProtocolB_Explicit' not implemented}}\
+                                    // expected-warning {{method 'rlyeh' in protocol 'ProtocolA' not implemented}}\
+                                    // expected-warning {{method 'innsmouth' in protocol 'ProtocolA' not implemented}}
+- (void)dunwich {}
+@end
+
+// Categories adopting a protocol with explicit conformance need to implement that protocol.
+@interface Parent
+- (void) theBestOfTimes;
+@property (readonly) id theWorstOfTimes;
+@end
+
+@interface Derived : Parent
+@end
+
+@interface Derived (MyCat) <Protocol>
+@end
+
+@implementation Derived (MyCat) // expected-warning {{method 'theBestOfTimes' in protocol 'Protocol' not implemented}}
+@end
+
+__attribute__((objc_protocol_requires_explicit_implementation))  // expected-error{{attribute 'objc_protocol_requires_explicit_implementation' can only be applied to @protocol definitions, not forward declarations}}
+@protocol NotDefined;
+
+// Another complete hierarchy.
+ __attribute__((objc_protocol_requires_explicit_implementation))
+@protocol Ex2FooBar
+- (void)methodA;
+@end
+
+ __attribute__((objc_protocol_requires_explicit_implementation))
+@protocol Ex2ProtocolA
+- (void)methodB;
+@end
+
+ __attribute__((objc_protocol_requires_explicit_implementation))
+@protocol Ex2ProtocolB <Ex2ProtocolA>
+- (void)methodA; // expected-note {{method 'methodA' declared here}}
+@end
+
+// NOT required
+@protocol Ex2ProtocolC <Ex2ProtocolA>
+- (void)methodB;
+- (void)methodA;
+@end
+
+@interface Ex2ClassA <Ex2ProtocolC, Ex2FooBar>
+@end
+@implementation Ex2ClassA
+- (void)methodB {}
+- (void)methodA {}
+@end
+
+@interface Ex2ClassB : Ex2ClassA <Ex2ProtocolB>
+@end
+
+@implementation Ex2ClassB // expected-warning {{method 'methodA' in protocol 'Ex2ProtocolB' not implemented}}
+@end
+
diff --git a/test/SemaObjC/selector-1.m b/test/SemaObjC/selector-1.m
index 186e19f..4efa0d7 100644
--- a/test/SemaObjC/selector-1.m
+++ b/test/SemaObjC/selector-1.m
@@ -1,20 +1,31 @@
-// RUN: %clang_cc1 -verify %s 
-// expected-no-diagnostics
+// RUN: %clang_cc1  -Wselector-type-mismatch -verify %s 
 
 @interface I
-- (id) compare: (char) arg1;
+- (id) compare: (char) arg1; // expected-note {{method 'compare:' declared here}}
 - length;
 @end
 
 @interface J
-- (id) compare: (id) arg1;
+- (id) compare: (id) arg1; // expected-note {{method 'compare:' declared here}}
 @end
 
 SEL func()
 {
-	return @selector(compare:);	// Non warning on multiple selector found.
+	return @selector(compare:);	// expected-warning {{several methods with selector 'compare:' of mismatched types are found for the @selector expression}}
 }
 
+// rdar://16458579
+void Test16458579() {
+ SEL s = @selector((retain));
+ SEL s1 = @selector((meth1:));
+ SEL s2 = @selector((retainArgument::));
+ SEL s3 = @selector((retainArgument:::::));
+ SEL s4 = @selector((retainArgument:with:));
+ SEL s5 = @selector((meth1:with:with:));
+ SEL s6 = @selector((getEnum:enum:bool:));
+ SEL s7 = @selector((char:float:double:unsigned:short:long:));
+ SEL s9 = @selector((:enum:bool:));
+}
 int main() {
  SEL s = @selector(retain);
  SEL s1 = @selector(meth1:);
@@ -27,3 +38,26 @@
 
  SEL s9 = @selector(:enum:bool:);
 }
+
+// rdar://15794055
+@interface NSObject @end
+
+@class NSNumber;
+
+@interface XBRecipe : NSObject
+@property (nonatomic, assign) float finalVolume; // expected-note {{method 'setFinalVolume:' declared here}}
+@end
+
+@interface XBDocument : NSObject
+@end
+
+@interface XBDocument ()
+- (void)setFinalVolume:(NSNumber *)finalVolumeNumber; // expected-note {{method 'setFinalVolume:' declared here}}
+@end
+
+@implementation XBDocument
+- (void)setFinalVolume:(NSNumber *)finalVolumeNumber
+{
+    (void)@selector(setFinalVolume:); // expected-warning {{several methods with selector 'setFinalVolume:' of mismatched types are found for the @selector expression}}
+}
+@end
diff --git a/test/SemaObjC/selector-3.m b/test/SemaObjC/selector-3.m
index d782c78..dfd216a 100644
--- a/test/SemaObjC/selector-3.m
+++ b/test/SemaObjC/selector-3.m
@@ -14,7 +14,7 @@
 - (void) foo
 {
   SEL a,b,c;
-  a = @selector(b1ar);  // expected-warning {{creating selector for nonexistent method 'b1ar'}}
+  a = @selector(b1ar);
   b = @selector(bar);
 }
 @end
@@ -25,7 +25,7 @@
 
 SEL func()
 {
-    return  @selector(length);  // expected-warning {{creating selector for nonexistent method 'length'}}
+    return  @selector(length);  // expected-warning {{no method with selector 'length' is implemented in this translation unit}}
 }
 
 // rdar://9545564
@@ -69,7 +69,7 @@
 
 @implementation INTF
 - (void) Meth {
-  if( [cnx respondsToSelector:MySelector(@selector( _setQueue: ))] ) // expected-warning {{creating selector for nonexistent method '_setQueue:'}} 
+  if( [cnx respondsToSelector:MySelector(@selector( _setQueue: ))] )
   {
   }
 
@@ -84,23 +84,23 @@
 
 // rdar://14007194
 @interface UxTechTest : NSObject
-- (int) invalidate : (id)Arg; // expected-warning {{multiple selectors named 'invalidate:' found}}
-+ (int) C_invalidate : (int)arg; // expected-warning {{multiple selectors named 'C_invalidate:' found}}
+- (int) invalidate : (id)Arg;
++ (int) C_invalidate : (int)arg;
 @end
 
 @interface UxTechTest(CAT)
-- (char) invalidate : (int)arg; // expected-note {{also found}}
-+ (int) C_invalidate : (char)arg; // expected-note {{also found}}
+- (char) invalidate : (int)arg;
++ (int) C_invalidate : (char)arg;
 @end
 
 @interface NSPort : NSObject
-- (double) invalidate : (void*)Arg1; // expected-note {{also found}}
-+ (int) C_invalidate : (id*)arg; // expected-note {{also found}}
+- (double) invalidate : (void*)Arg1;
++ (int) C_invalidate : (id*)arg;
 @end
 
 
 @interface USEText : NSPort
-- (int) invalidate : (int)arg; // expected-note {{also found}}
+- (int) invalidate : (int)arg;
 @end
 
 @implementation USEText
@@ -110,3 +110,27 @@
 @interface USETextSub : USEText
 - (int) invalidate : (id)arg;
 @end
+
+// rdar://16428638
+@interface I16428638
+- (int) compare: (I16428638 *) arg1; // commenting out this line avoids the warning
+@end
+
+@interface J16428638
+- (int) compare: (J16428638 *) arg1;
+@end
+
+@implementation J16428638
+- (void)method {
+    SEL s = @selector(compare:); // spurious warning
+    (void)s;
+}
+- (int) compare: (J16428638 *) arg1 {
+    return 0;
+}
+@end
+
+void test16428638() {
+    SEL s = @selector(compare:);
+    (void)s;
+}
diff --git a/test/SemaObjC/selector-4.m b/test/SemaObjC/selector-4.m
new file mode 100644
index 0000000..59a8233
--- /dev/null
+++ b/test/SemaObjC/selector-4.m
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -Wselector -x objective-c %s -include %s -verify
+// expected-no-diagnostics
+// rdar://16600230
+
+#ifndef INCLUDED
+#define INCLUDED
+
+#pragma clang system_header
+
+@interface NSObject @end
+@interface NSString @end
+
+@interface NSString (NSStringExtensionMethods)
+- (void)compare:(NSString *)string;
+@end
+
+@interface MyObject : NSObject
+@end
+
+#else
+int main() {
+    (void)@selector(compare:);
+}
+
+@implementation MyObject
+
+@end
+#endif
diff --git a/test/SemaObjC/selector-overload.m b/test/SemaObjC/selector-overload.m
index 53ba6f7..447607a 100644
--- a/test/SemaObjC/selector-overload.m
+++ b/test/SemaObjC/selector-overload.m
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 %s -fsyntax-only
+// FIXME: This test needs needs to be run with -verify
 
 @interface NSObject
 + alloc;
diff --git a/test/SemaObjC/special-dep-unavail-warning.m b/test/SemaObjC/special-dep-unavail-warning.m
index a179647..9e16b33 100644
--- a/test/SemaObjC/special-dep-unavail-warning.m
+++ b/test/SemaObjC/special-dep-unavail-warning.m
@@ -4,48 +4,48 @@
 @interface B
 - (void) depInA;
 - (void) unavailMeth __attribute__((unavailable)); // expected-note {{has been explicitly marked unavailable here}}
-- (void) depInA1 __attribute__((deprecated));
+- (void) depInA1 __attribute__((deprecated)); // expected-note {{'depInA1' has been explicitly marked deprecated here}}
 - (void) unavailMeth1;
-- (void) depInA2 __attribute__((deprecated));
+- (void) depInA2 __attribute__((deprecated)); // expected-note {{'depInA2' has been explicitly marked deprecated here}}
 - (void) unavailMeth2 __attribute__((unavailable)); // expected-note {{has been explicitly marked unavailable here}}
 - (void) depunavailInA;
 - (void) depunavailInA1 __attribute__((deprecated)) __attribute__((unavailable)); // expected-note {{has been explicitly marked unavailable here}}
-- (void)FuzzyMeth __attribute__((deprecated));
+- (void)FuzzyMeth __attribute__((deprecated)); // expected-note {{'FuzzyMeth' has been explicitly marked deprecated here}}
 - (void)FuzzyMeth1 __attribute__((unavailable));
 @end
 
 @interface A
 - (void) unavailMeth1 __attribute__((unavailable)); // expected-note {{has been explicitly marked unavailable here}}
-- (void) depInA __attribute__((deprecated));
+- (void) depInA __attribute__((deprecated)); // expected-note {{'depInA' has been explicitly marked deprecated here}}
 - (void) depInA2 __attribute__((deprecated));
 - (void) depInA1;
 - (void) unavailMeth2 __attribute__((unavailable)); 
 - (void) depunavailInA __attribute__((deprecated)) __attribute__((unavailable)); // expected-note {{has been explicitly marked unavailable here}}
 - (void) depunavailInA1;
 - (void)FuzzyMeth __attribute__((unavailable));
-- (void)FuzzyMeth1 __attribute__((deprecated));
+- (void)FuzzyMeth1 __attribute__((deprecated)); // expected-note {{'FuzzyMeth1' has been explicitly marked deprecated here}}
 @end
 
 
-@class C;	// expected-note 5 {{forward declaration of class here}}
+@class C;	// expected-note 10 {{forward declaration of class here}}
 
 void test(C *c) {
-  [c depInA]; // expected-warning {{'depInA' maybe deprecated because receiver type is unknown}}
-  [c unavailMeth]; // expected-warning {{'unavailMeth' maybe unavailable because receiver type is unknown}}
-  [c depInA1]; // expected-warning {{'depInA1' maybe deprecated because receiver type is unknown}}
-  [c unavailMeth1]; // expected-warning {{'unavailMeth1' maybe unavailable because receiver type is unknown}}
-  [c depInA2]; // expected-warning {{'depInA2' maybe deprecated because receiver type is unknown}}
-  [c unavailMeth2]; // expected-warning {{'unavailMeth2' maybe unavailable because receiver type is unknown}}
-  [c depunavailInA]; // expected-warning {{'depunavailInA' maybe unavailable because receiver type is unknown}} 
-  [c depunavailInA1];// expected-warning {{'depunavailInA1' maybe unavailable because receiver type is unknown}}
-  [c FuzzyMeth];      // expected-warning {{'FuzzyMeth' maybe deprecated because receiver type is unknown}}
-  [c FuzzyMeth1]; // expected-warning {{'FuzzyMeth1' maybe deprecated because receiver type is unknown}}
+  [c depInA]; // expected-warning {{'depInA' may be deprecated because the receiver type is unknown}}
+  [c unavailMeth]; // expected-warning {{'unavailMeth' may be unavailable because the receiver type is unknown}}
+  [c depInA1]; // expected-warning {{'depInA1' may be deprecated because the receiver type is unknown}}
+  [c unavailMeth1]; // expected-warning {{'unavailMeth1' may be unavailable because the receiver type is unknown}}
+  [c depInA2]; // expected-warning {{'depInA2' may be deprecated because the receiver type is unknown}}
+  [c unavailMeth2]; // expected-warning {{'unavailMeth2' may be unavailable because the receiver type is unknown}}
+  [c depunavailInA]; // expected-warning {{'depunavailInA' may be unavailable because the receiver type is unknown}} 
+  [c depunavailInA1];// expected-warning {{'depunavailInA1' may be unavailable because the receiver type is unknown}}
+  [c FuzzyMeth];      // expected-warning {{'FuzzyMeth' may be deprecated because the receiver type is unknown}}
+  [c FuzzyMeth1]; // expected-warning {{'FuzzyMeth1' may be deprecated because the receiver type is unknown}}
 
 }
 
 // rdar://10268422
 __attribute ((deprecated))
-@interface DEPRECATED // expected-note {{declared here}}
+@interface DEPRECATED // expected-note {{'DEPRECATED' has been explicitly marked deprecated here}}
 +(id)new;
 @end
 
diff --git a/test/SemaObjC/tentative-property-decl.m b/test/SemaObjC/tentative-property-decl.m
index aa7df52..a9649b6 100644
--- a/test/SemaObjC/tentative-property-decl.m
+++ b/test/SemaObjC/tentative-property-decl.m
@@ -1,10 +1,11 @@
 // RUN: %clang_cc1 -fsyntax-only -Weverything -verify %s
+// expected-no-diagnostics
 // rdar://11656982
-/** Normally, a property cannot be both 'readonly' and having a "write" attribute
+/** A property may not be both 'readonly' and having a memory management attribute
     (copy/retain/etc.). But, property declaration in primary class and protcols
     are tentative as they may be overridden into a 'readwrite' property in class 
-    extensions. Postpone diagnosing such warnings until the class implementation 
-    is seen.
+    extensions. So, do not issue any warning on 'readonly' and memory management
+    attributes in a property.
 */
 
 @interface Super {
@@ -14,8 +15,8 @@
 @class NSString;
 
 @interface MyClass : Super
-@property(nonatomic, copy, readonly) NSString *prop; // expected-warning {{property attributes 'readonly' and 'copy' are mutually exclusive}}
-@property(nonatomic, copy, readonly) id warnProp; // expected-warning {{property attributes 'readonly' and 'copy' are mutually exclusive}}
+@property(nonatomic, copy, readonly) NSString *prop;
+@property(nonatomic, copy, readonly) id warnProp;
 @end
 
 @interface MyClass ()
@@ -29,8 +30,8 @@
 
 
 @protocol P
-@property(nonatomic, copy, readonly) NSString *prop; // expected-warning {{property attributes 'readonly' and 'copy' are mutually exclusive}}
-@property(nonatomic, copy, readonly) id warnProp; // expected-warning {{property attributes 'readonly' and 'copy' are mutually exclusive}}
+@property(nonatomic, copy, readonly) NSString *prop;
+@property(nonatomic, copy, readonly) id warnProp;
 @end
 
 @interface YourClass : Super <P>
diff --git a/test/SemaObjC/undef-protocol-methods-1.m b/test/SemaObjC/undef-protocol-methods-1.m
index 25b1dad..4858faf 100644
--- a/test/SemaObjC/undef-protocol-methods-1.m
+++ b/test/SemaObjC/undef-protocol-methods-1.m
@@ -22,13 +22,10 @@
 + (void) cls_meth : (int) arg1;   // expected-note {{method 'cls_meth:' declared here}}
 @end
 
-@interface INTF <PROTO> // expected-note 3 {{required for direct or indirect protocol 'PROTO'}} \
-			// expected-note 2 {{required for direct or indirect protocol 'P1'}} \
-			// expected-note 2 {{required for direct or indirect protocol 'P3'}} \
-			// expected-note 2 {{required for direct or indirect protocol 'P2'}}
+@interface INTF <PROTO>
 @end
 
-@implementation INTF // expected-warning 9 {{in protocol not implemented}}
+@implementation INTF // expected-warning 9 {{in protocol '}}
 - (void) DefP1proto{}
 + (void) DefClsP3Proto{}
 @end
diff --git a/test/SemaObjC/unsued-backing-ivar-warning.m b/test/SemaObjC/unsued-backing-ivar-warning.m
deleted file mode 100644
index c07dea7..0000000
--- a/test/SemaObjC/unsued-backing-ivar-warning.m
+++ /dev/null
@@ -1,76 +0,0 @@
-// RUN: %clang_cc1  -fsyntax-only -Wunused-property-ivar -verify -Wno-objc-root-class %s
-// rdar://14989999
-
-@interface NSObject @end
-
-@interface Example : NSObject
-@property (nonatomic, copy) id t; // expected-note {{property declared here}}
-@property (nonatomic, copy) id u; // expected-note {{property declared here}}
-@property (nonatomic, copy) id v; // expected-note {{property declared here}}
-@property (nonatomic, copy) id w;
-@property (nonatomic, copy) id x; // expected-note {{property declared here}}
-@property (nonatomic, copy) id y; // expected-note {{property declared here}}
-@property (nonatomic, copy) id z;
-@property (nonatomic, copy) id ok;
-@end
-
-@implementation Example
-- (void) setX:(id)newX {  // expected-warning {{ivar '_x' which backs the property is not referenced in this property's accessor}}
-    _y = newX;
-}
-- (id) y { // expected-warning {{ivar '_y' which backs the property is not referenced in this property's accessor}}
-  return _v;
-}
-
-- (void) setV:(id)newV { // expected-warning {{ivar '_v' which backs the property is not referenced in this property's accessor}}
-    _y = newV;
-}
-
-// No warning here because there is no backing ivar.
-// both setter/getter are user defined.
-- (void) setW:(id)newW {
-    _y = newW;
-}
-- (id) w {
-  return _v;
-}
-
-- (id) u { // expected-warning {{ivar '_u' which backs the property is not referenced in this property's accessor}}
-  return _v;
-}
-
-@synthesize ok = okIvar;
-- (void) setOk:(id)newOk {
-    okIvar = newOk;
-}
-
-@synthesize t = tIvar;
-- (void) setT:(id)newT { // expected-warning {{ivar 'tIvar' which backs the property is not referenced in this property's accessor}}
-    okIvar = newT;
-}
-@end
-
-// rdar://15473432
-typedef char BOOL;
-@interface CalDAVServerVersion {
-  BOOL _supportsTimeRangeFilterWithoutEndDate;
-}
-@property (nonatomic, readonly,nonatomic) BOOL supportsTimeRangeFilterWithoutEndDate;
-@end
-
-@interface CalDAVConcreteServerVersion : CalDAVServerVersion {
-}
-@end
-
-@interface CalendarServerVersion : CalDAVConcreteServerVersion
-@end
-
-@implementation CalDAVServerVersion
-@synthesize supportsTimeRangeFilterWithoutEndDate=_supportsTimeRangeFilterWithoutEndDate;
-@end
-
-@implementation CalendarServerVersion
--(BOOL)supportsTimeRangeFilterWithoutEndDate {
-  return 0;
-}
-@end
diff --git a/test/SemaObjC/unused-backing-ivar-warning.m b/test/SemaObjC/unused-backing-ivar-warning.m
new file mode 100644
index 0000000..52067c7
--- /dev/null
+++ b/test/SemaObjC/unused-backing-ivar-warning.m
@@ -0,0 +1,203 @@
+// RUN: %clang_cc1  -fsyntax-only -Wunused-property-ivar -verify -Wno-objc-root-class %s
+// rdar://14989999
+
+@interface NSObject @end
+
+@interface Example : NSObject
+@property (nonatomic, copy) id t; // expected-note {{property declared here}}
+@property (nonatomic, copy) id u; // expected-note {{property declared here}}
+@property (nonatomic, copy) id v; // expected-note {{property declared here}}
+@property (nonatomic, copy) id w;
+@property (nonatomic, copy) id x; // expected-note {{property declared here}}
+@property (nonatomic, copy) id y; // expected-note {{property declared here}}
+@property (nonatomic, copy) id z;
+@property (nonatomic, copy) id ok;
+@end
+
+@implementation Example
+- (void) setX:(id)newX {  // expected-warning {{ivar '_x' which backs the property is not referenced in this property's accessor}}
+    _y = newX;
+}
+- (id) y { // expected-warning {{ivar '_y' which backs the property is not referenced in this property's accessor}}
+  return _v;
+}
+
+- (void) setV:(id)newV { // expected-warning {{ivar '_v' which backs the property is not referenced in this property's accessor}}
+    _y = newV;
+}
+
+// No warning here because there is no backing ivar.
+// both setter/getter are user defined.
+- (void) setW:(id)newW {
+    _y = newW;
+}
+- (id) w {
+  return _v;
+}
+
+- (id) u { // expected-warning {{ivar '_u' which backs the property is not referenced in this property's accessor}}
+  return _v;
+}
+
+@synthesize ok = okIvar;
+- (void) setOk:(id)newOk {
+    okIvar = newOk;
+}
+
+@synthesize t = tIvar;
+- (void) setT:(id)newT { // expected-warning {{ivar 'tIvar' which backs the property is not referenced in this property's accessor}}
+    okIvar = newT;
+}
+@end
+
+// rdar://15473432
+typedef char BOOL;
+@interface CalDAVServerVersion {
+  BOOL _supportsTimeRangeFilterWithoutEndDate;
+}
+@property (nonatomic, readonly,nonatomic) BOOL supportsTimeRangeFilterWithoutEndDate;
+@end
+
+@interface CalDAVConcreteServerVersion : CalDAVServerVersion {
+}
+@end
+
+@interface CalendarServerVersion : CalDAVConcreteServerVersion
+@end
+
+@implementation CalDAVServerVersion
+@synthesize supportsTimeRangeFilterWithoutEndDate=_supportsTimeRangeFilterWithoutEndDate;
+@end
+
+@implementation CalendarServerVersion
+-(BOOL)supportsTimeRangeFilterWithoutEndDate {
+  return 0;
+}
+@end
+
+// rdar://15630719
+@interface CDBModifyRecordsOperation : NSObject
+@property (nonatomic, assign) BOOL atomic;
+@end
+
+@class NSString;
+
+@implementation CDBModifyRecordsOperation
+- (void)setAtomic:(BOOL)atomic {
+  if (atomic == __objc_yes) {
+    NSString *recordZoneID = 0;
+  }
+  _atomic = atomic;
+}
+@end
+
+// rdar://15728901
+@interface GATTOperation : NSObject {
+    long operation;
+}
+@property(assign) long operation;
+@end
+
+@implementation GATTOperation
+@synthesize operation;
++ (id) operation {
+    return 0;
+}
+@end
+
+// rdar://15727327
+@interface Radar15727327 : NSObject
+@property (assign, readonly) long p;
+@property (assign) long q; // expected-note 2 {{property declared here}}
+@property (assign, readonly) long r; // expected-note {{property declared here}}
+- (long)Meth;
+@end
+
+@implementation Radar15727327
+@synthesize p;
+@synthesize q;
+@synthesize r;
+- (long)Meth { return p; }
+- (long) p { [self Meth]; return 0;  }
+- (long) q { return 0; } // expected-warning {{ivar 'q' which backs the property is not referenced in this property's accessor}}
+- (void) setQ : (long) val { } // expected-warning {{ivar 'q' which backs the property is not referenced in this property's accessor}}
+- (long) r { [self Meth]; return p; } // expected-warning {{ivar 'r' which backs the property is not referenced in this property's accessor}}
+@end
+
+@interface I1
+@property (readonly) int p1;
+@property (readonly) int p2; // expected-note {{property declared here}}
+@end
+
+@implementation I1
+@synthesize p1=_p1;
+@synthesize p2=_p2;
+
+-(int)p1 {
+  return [self getP1];
+}
+-(int)getP1 {
+  return _p1;
+}
+-(int)getP2 {
+  return _p2;
+}
+-(int)p2 {  // expected-warning {{ivar '_p2' which backs the property is not referenced in this property's accessor}}
+  Radar15727327 *o;
+  return [o Meth];
+}
+@end
+
+// rdar://15873425
+@protocol MyProtocol
+@property (nonatomic, readonly) int myProperty;
+@end
+
+@interface MyFirstClass : NSObject <MyProtocol>
+@end
+
+@interface MySecondClass : NSObject <MyProtocol>
+@end
+
+@implementation MyFirstClass
+@synthesize myProperty;
+@end
+
+@implementation MySecondClass
+@dynamic myProperty;
+-(int)myProperty  // should not warn; property is dynamic
+{
+    return 0;
+}
+@end
+
+// rdar://15890251
+@class NSURL;
+
+@protocol MCCIDURLProtocolDataProvider
+@required
+@property(strong, atomic, readonly) NSURL *cidURL;
+@property(strong, atomic, readonly) NSURL *cidURL1; // expected-note {{property declared here}}
+@end
+
+@interface UnrelatedClass : NSObject <MCCIDURLProtocolDataProvider>
+@end
+
+@implementation UnrelatedClass
+@synthesize cidURL = _cidURL;
+@synthesize cidURL1 = _cidURL1;
+@end
+
+@interface MUIWebAttachmentController : NSObject <MCCIDURLProtocolDataProvider>
+@end
+
+
+@implementation MUIWebAttachmentController
+- (NSURL *)cidURL {
+    return 0;
+}
+@synthesize cidURL1  = _cidURL1;
+- (NSURL *)cidURL1 { // expected-warning {{ivar '_cidURL1' which backs the property is not referenced in this property's accessor}}
+    return 0;
+}
+@end
diff --git a/test/SemaObjC/unused.m b/test/SemaObjC/unused.m
index 3fd1cf0..6ea3fe8 100644
--- a/test/SemaObjC/unused.m
+++ b/test/SemaObjC/unused.m
@@ -72,3 +72,35 @@
 - (void) b {}
 - (void) a { [self b]; }
 @end
+
+// Test that objc_precise_lifetime suppresses
+// unused variable warnings.
+extern void rdar15596883_foo(void);
+void rdar15596883(id x) {
+  __attribute__((objc_precise_lifetime)) id y = x; // no-warning
+  rdar15596883_foo();
+}
+
+@interface PropertyObject : NSObject 
+@property int length;
+@end
+
+@protocol P
+@property int property;
+@end
+
+void test3(PropertyObject *o)
+{
+  [o length]; // expected-warning {{property access result unused - getters should not be used for side effects}}
+  (void)[o length];
+}
+
+void test4(id o)
+{
+  [o length]; // No warning.
+}
+
+void test5(id <P> p)
+{
+    [p property]; // expected-warning {{property access result unused - getters should not be used for side effects}}
+}
diff --git a/test/SemaObjC/warn-deprecated-implementations.m b/test/SemaObjC/warn-deprecated-implementations.m
index f63962f..6e208b5 100644
--- a/test/SemaObjC/warn-deprecated-implementations.m
+++ b/test/SemaObjC/warn-deprecated-implementations.m
@@ -11,13 +11,13 @@
 @end
 
 @interface A()
-- (void) E __attribute__((deprecated)); // expected-note {{method 'E' declared here}}
+- (void) E __attribute__((deprecated));
 @end
 
 @implementation A
 + (void)F { }	// No warning, implementing its own deprecated method
 - (void) D {} //  expected-warning {{Implementing deprecated method}}
-- (void) E {} //  expected-warning {{Implementing deprecated method}}
+- (void) E {} // No warning, implementing deprecated method in its class extension.
 @end
 
 @interface A(CAT)
@@ -29,7 +29,7 @@
 @end
 
 __attribute__((deprecated))
-@interface CL // expected-note 2 {{class declared here}} // expected-note 2 {{declared here}}
+@interface CL // expected-note 2 {{class declared here}} // expected-note 2 {{'CL' has been explicitly marked deprecated here}}
 @end
 
 @implementation CL // expected-warning {{Implementing deprecated class}}
@@ -53,3 +53,15 @@
 - (void) B {} // expected-warning {{Implementing deprecated method}}
 @end
 
+@interface Test
+@end
+
+@interface Test()
+- (id)initSpecialInPrivateHeader __attribute__((deprecated));
+@end
+
+@implementation Test
+- (id)initSpecialInPrivateHeader {
+  return (void *)0;
+}
+@end
diff --git a/test/SemaObjC/warn-forward-class-attr-deprecated.m b/test/SemaObjC/warn-forward-class-attr-deprecated.m
index 854ff69..cb118c3 100644
--- a/test/SemaObjC/warn-forward-class-attr-deprecated.m
+++ b/test/SemaObjC/warn-forward-class-attr-deprecated.m
@@ -4,7 +4,7 @@
 @class ABGroupImportFilesScope; // expected-note {{forward declaration of class here}}
 
 @interface I1
-- (id) filenames __attribute__((deprecated));
+- (id) filenames __attribute__((deprecated)); // expected-note {{'filenames' has been explicitly marked deprecated here}}
 @end
 
 @interface I2
@@ -16,7 +16,7 @@
 @implementation I2
 - (id) Meth : (ABGroupImportFilesScope*) scope
 {
-  id p =  [self initWithAccount : 0 filenames :[scope filenames]]; // expected-warning {{'filenames' maybe deprecated because receiver type is unknown}}
+  id p =  [self initWithAccount : 0 filenames :[scope filenames]]; // expected-warning {{'filenames' may be deprecated because the receiver type is unknown}}
   return 0;
 }
 - (id) filenames { return 0; }
diff --git a/test/SemaObjC/warn-protocol-method-deprecated.m b/test/SemaObjC/warn-protocol-method-deprecated.m
index 928694d..70dd394 100644
--- a/test/SemaObjC/warn-protocol-method-deprecated.m
+++ b/test/SemaObjC/warn-protocol-method-deprecated.m
@@ -3,7 +3,7 @@
 
 @protocol TestProtocol 
 - (void)newProtocolMethod;
-- (void)deprecatedProtocolMethod __attribute__((deprecated)); // expected-note 2 {{method 'deprecatedProtocolMethod' declared here}}
+- (void)deprecatedProtocolMethod __attribute__((deprecated)); // expected-note 2 {{'deprecatedProtocolMethod' has been explicitly marked deprecated here}}
 @end
 
 @interface NSObject @end
@@ -11,7 +11,7 @@
 @interface TestClass : NSObject <TestProtocol>
 
 - (void)newInstanceMethod;
-- (void)deprecatedInstanceMethod __attribute__((deprecated)); // expected-note {{method 'deprecatedInstanceMethod' declared here}}
+- (void)deprecatedInstanceMethod __attribute__((deprecated)); // expected-note {{'deprecatedInstanceMethod' has been explicitly marked deprecated here}}
 
 @end
 
diff --git a/test/SemaObjC/warn-retain-cycle.m b/test/SemaObjC/warn-retain-cycle.m
index eb4e966..4398d29 100644
--- a/test/SemaObjC/warn-retain-cycle.m
+++ b/test/SemaObjC/warn-retain-cycle.m
@@ -122,8 +122,8 @@
   // Sanity check that we are really whitelisting 'addOperationWithBlock:' and not doing
   // something funny.
   [myOperationQueue addSomethingElse:^() { // expected-note {{block will be retained by an object strongly retained by the captured object}}
-    if (count > 20) { // expected-warning {{capturing 'self' strongly in this block is likely to lead to a retain cycle}}
-      doSomething(count);
+    if (count > 20) {
+      doSomething(count); // expected-warning {{capturing 'self' strongly in this block is likely to lead to a retain cycle}}
     }
   }];
 }
@@ -184,3 +184,17 @@
   })];
 }
 
+// rdar://16944538
+void func(int someCondition) {
+
+__block void(^myBlock)(void) = ^{
+        if (someCondition) {
+            doSomething(1);
+            myBlock();
+        }
+        else {
+	    myBlock = ((void*)0);
+        }
+   };
+
+}
diff --git a/test/SemaObjC/warn-thread-safety-analysis.m b/test/SemaObjC/warn-thread-safety-analysis.m
new file mode 100644
index 0000000..0e29ff2
--- /dev/null
+++ b/test/SemaObjC/warn-thread-safety-analysis.m
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wthread-safety -Wthread-safety-beta -Wno-objc-root-class %s
+
+struct __attribute__ ((lockable)) Mutex {};
+
+struct Mutex mu1;
+
+int Foo_fun1(int i) __attribute__ ((exclusive_locks_required((mu1)))) {
+  return i;
+}
+
+@interface test
+@end
+
+@implementation test
+- (void) PR19541 {
+  Foo_fun1(1); // expected-warning{{calling function 'Foo_fun1' requires holding mutex 'mu1' exclusively}}
+}
+
+@end
diff --git a/test/SemaObjC/warn-unreachable.m b/test/SemaObjC/warn-unreachable.m
index 832cbd2..3667676 100644
--- a/test/SemaObjC/warn-unreachable.m
+++ b/test/SemaObjC/warn-unreachable.m
@@ -1,4 +1,4 @@
-// RUN: %clang %s -fsyntax-only -Xclang -verify -fblocks -Wunreachable-code -Wno-unused-value -Wno-covered-switch-default
+// RUN: %clang %s -fsyntax-only -Xclang -verify -fblocks -Wunreachable-code-aggressive -Wno-unused-value -Wno-covered-switch-default
 
 // This previously triggered a warning from -Wunreachable-code because of
 // a busted CFG.
@@ -15,3 +15,70 @@
   return; // expected-warning {{will never be executed}}
 }
 
+#define NO __objc_no
+#define YES __objc_yes
+#define CONFIG NO
+
+// Test that 'NO' and 'YES' are not treated as configuration macros.
+int test_NO() {
+  if (NO)
+    return 1; // expected-warning {{will never be executed}}
+  else
+    return 0;
+}
+
+int test_YES() {
+  if (YES)
+    return 1;
+  else
+    return 0; // expected-warning {{will never be executed}}
+}
+
+int test_CONFIG() {
+  if (CONFIG)
+    return 1;
+  else
+    return 0;
+}
+
+// FIXME: This should at some point report a warning
+// that the loop increment is unreachable.
+void test_loop_increment(id container) {
+  for (id x in container) { // no-warning
+    break;
+  }
+}
+
+void calledFun() {}
+
+// Test "silencing" with parentheses.
+void test_with_paren_silencing(int x) {
+  if (NO) calledFun(); // expected-warning {{will never be executed}} expected-note {{silence by adding parentheses to mark code as explicitly dead}}
+  if ((NO)) calledFun(); // no-warning
+
+  if (YES) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
+    calledFun();
+  else
+    calledFun(); // expected-warning {{will never be executed}}
+
+  if ((YES))
+    calledFun();
+  else
+    calledFun(); // no-warning
+  
+  if (!YES) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
+    calledFun(); // expected-warning {{code will never be executed}}
+  else
+    calledFun();
+  
+  if ((!YES))
+    calledFun(); // no-warning
+  else
+    calledFun();
+  
+  if (!(YES))
+    calledFun(); // no-warning
+  else
+    calledFun();
+}
+
diff --git a/test/SemaObjCXX/arc-system-header.mm b/test/SemaObjCXX/arc-system-header.mm
index 3358e5f..b97e2f3 100644
--- a/test/SemaObjCXX/arc-system-header.mm
+++ b/test/SemaObjCXX/arc-system-header.mm
@@ -6,4 +6,4 @@
   a->data.void_ptr = 0;
   a->data.a_b.b = 0; // expected-error{{'a_b' is unavailable: this system field has retaining ownership}}
 }
-// expected-note@arc-system-header.h:10{{declaration has been explicitly marked unavailable here}}
+// expected-note@arc-system-header.h:10{{'a_b' has been explicitly marked unavailable here}}
diff --git a/test/SemaObjCXX/arc-templates.mm b/test/SemaObjCXX/arc-templates.mm
index b3519b9..ebede64 100644
--- a/test/SemaObjCXX/arc-templates.mm
+++ b/test/SemaObjCXX/arc-templates.mm
@@ -302,3 +302,19 @@
     float &fr2 = takePtr<A>(a);
   }
 }
+
+namespace rdar15713945 {
+  template <class T> int &f(__strong T &);
+  template <class T> float &f(__weak T &);
+  template <class T> double &f(__unsafe_unretained T &);
+  template <class T> char &f(T &);
+
+  void foo() {
+    __strong NSString * const strong = 0;
+    int &ir = (f)(strong);
+    __weak NSString * const weak = 0;
+    float &fr = (f)(weak);
+    __unsafe_unretained NSString * const unsafe = 0;
+    double &dr = (f)(unsafe);
+  }
+}
diff --git a/test/SemaObjCXX/contextual-convert-to-id.mm b/test/SemaObjCXX/contextual-convert-to-id.mm
index 602d6c2..47a9d07 100644
--- a/test/SemaObjCXX/contextual-convert-to-id.mm
+++ b/test/SemaObjCXX/contextual-convert-to-id.mm
@@ -8,6 +8,10 @@
 - unknownMethod;
 @end
 
+@interface C : A
+- knownMethod;
+@end
+
 template<typename T> struct RetainPtr {
   explicit operator T*() const;
 };
@@ -17,6 +21,16 @@
   [a unknownMethod]; // expected-warning{{'A' may not respond to 'unknownMethod'}}
 }
 
+void explicitCast(RetainPtr<A> a, RetainPtr<B> b, RetainPtr<C> c) {
+  (void)(A*)a;
+  (void)(A*)b; // expected-error{{cannot convert 'RetainPtr<B>' to 'A *' without a conversion operator}}
+  (void)(A*)c;
+  (void)(C*)a;
+  (void)static_cast<A*>(a);
+  (void)static_cast<A*>(b);  // expected-error{{cannot convert 'RetainPtr<B>' to 'A *' without a conversion operator}}
+  (void)static_cast<A*>(c);
+}
+
 struct Incomplete; // expected-note{{forward declaration}}
 
 void methodCallToIncomplete(Incomplete &incomplete) {
@@ -31,3 +45,8 @@
   [a knownMethod];
   [a unknownMethod];
 }
+
+void explicitCast(IdPtr a) {
+  (void)(A*)a;
+  (void)static_cast<A*>(a);
+}
diff --git a/test/SemaObjCXX/crash.mm b/test/SemaObjCXX/crash.mm
index 345f72e..521b923 100644
--- a/test/SemaObjCXX/crash.mm
+++ b/test/SemaObjCXX/crash.mm
@@ -14,10 +14,10 @@
 @implementation Test
 
 struct EvilStruct {
-} // note the missing semicolon
+} // expected-error {{expected ';' after struct}}
 
-  typedef std::pair<int, int> IntegerPair; // expected-error{{typedef declarator cannot be qualified}} \
-// expected-error{{typedef name must be an identifier}} \
-// expected-error{{expected ';' after top level declarator}}
+  typedef std::pair<int, int> IntegerPair;
+
+template<typename...Ts> void f(Ts); // expected-error {{unexpanded}} expected-warning {{extension}}
 
 @end
diff --git a/test/SemaObjCXX/exceptions-fragile.mm b/test/SemaObjCXX/exceptions-fragile.mm
index 54d9f83..ff5a0cb 100644
--- a/test/SemaObjCXX/exceptions-fragile.mm
+++ b/test/SemaObjCXX/exceptions-fragile.mm
@@ -6,7 +6,7 @@
 namespace test0 {
   void test() {
     try {
-    } catch (NSException *e) { // expected-warning {{can not catch an exception thrown with @throw in C++ in the non-unified exception model}}
+    } catch (NSException *e) { // expected-warning {{cannot catch an exception thrown with @throw in C++ in the non-unified exception model}}
     }
   }
 }
diff --git a/test/SemaObjCXX/instantiate-property-access.mm b/test/SemaObjCXX/instantiate-property-access.mm
new file mode 100644
index 0000000..8d5c201
--- /dev/null
+++ b/test/SemaObjCXX/instantiate-property-access.mm
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// expected-no-diagnostics
+
+class C {};
+bool operator == (C c1, C c2);
+
+bool operator == (C c1, int i);
+bool operator == (int i, C c2);
+
+C operator += (C c1, C c2);
+
+enum TextureType { TextureType3D  };
+
+@interface Texture
+@property  int textureType;
+@property  C c;
+@end
+
+template <typename> class Framebuffer {
+public:
+  Texture **color_attachment;  
+  Framebuffer();
+};
+
+template <typename T> Framebuffer<T>::Framebuffer() {
+  (void)(color_attachment[0].textureType == TextureType3D);
+  color_attachment[0].textureType += 1;
+  (void)(color_attachment[0].c == color_attachment[0].c);
+  (void)(color_attachment[0].c == 1);
+  (void)(1 == color_attachment[0].c);
+}
+
+void foo() {
+  Framebuffer<int>();
+}
diff --git a/test/SemaObjCXX/lit.local.cfg b/test/SemaObjCXX/lit.local.cfg
new file mode 100644
index 0000000..f4ef5d2
--- /dev/null
+++ b/test/SemaObjCXX/lit.local.cfg
@@ -0,0 +1,4 @@
+config.substitutions = list(config.substitutions)
+config.substitutions.insert(0,
+    (r'%clang\b',
+     """*** Do not use the driver in Sema tests. ***""") )
diff --git a/test/SemaObjCXX/microsoft-abi-byval.mm b/test/SemaObjCXX/microsoft-abi-byval.mm
index f0c4caa..a44f240 100644
--- a/test/SemaObjCXX/microsoft-abi-byval.mm
+++ b/test/SemaObjCXX/microsoft-abi-byval.mm
@@ -1,7 +1,8 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -cxx-abi microsoft -Wno-objc-root-class %s
+// RUN: %clang_cc1 -fsyntax-only -verify -triple %ms_abi_triple -Wno-objc-root-class %s
+// expected-no-diagnostics
 
 class Foo {
-  ~Foo(); // expected-note {{implicitly declared private here}}
+  ~Foo();
 };
 
 @interface bar
@@ -9,6 +10,6 @@
 @end
 
 @implementation bar
-- (void) my_method: (Foo)arg { // expected-error {{variable of type 'Foo' has private destructor}}
+- (void) my_method: (Foo)arg { // no error; MS ABI will call Foo's dtor, but we skip the access check.
 }
 @end
diff --git a/test/SemaObjCXX/objcbridge-attribute-arc.mm b/test/SemaObjCXX/objcbridge-attribute-arc.mm
new file mode 100644
index 0000000..43c8e2b
--- /dev/null
+++ b/test/SemaObjCXX/objcbridge-attribute-arc.mm
@@ -0,0 +1,210 @@
+// RUN: %clang_cc1 -fsyntax-only -x objective-c++ -fobjc-arc -verify -Wno-objc-root-class %s
+// rdar://15454846
+
+typedef struct __attribute__ ((objc_bridge(NSError))) __CFErrorRef * CFErrorRef; // expected-note 5 {{declared here}}
+
+typedef struct __attribute__ ((objc_bridge(MyError))) __CFMyErrorRef * CFMyErrorRef; // expected-note 1 {{declared here}}
+
+typedef struct __attribute__((objc_bridge(12))) __CFMyColor  *CFMyColorRef; // expected-error {{parameter of 'objc_bridge' attribute must be a single name of an Objective-C class}}
+
+typedef struct __attribute__ ((objc_bridge)) __CFArray *CFArrayRef; // expected-error {{'objc_bridge' attribute takes one argument}}
+
+typedef struct __attribute__((objc_bridge(NSLocale, NSError))) __CFLocale *CFLocaleRef;// expected-error {{use of undeclared identifier 'NSError'}}
+
+typedef struct __attribute__((objc_bridge(NSDictionary))) __CFDictionary * CFDictionaryRef;
+
+typedef union __attribute__((objc_bridge(NSUColor))) __CFUPrimeColor XXX;
+typedef XXX *CFUColor2Ref;
+
+@interface I
+{
+}
+@end
+
+@protocol NSTesting @end
+@class NSString;
+
+typedef struct __attribute__((objc_bridge(NSTesting))) __CFError *CFTestingRef; // expected-note {{declared here}}
+
+id Test1(CFTestingRef cf) {
+  return (NSString *)cf; // expected-error {{CF object of type 'CFTestingRef' (aka '__CFError *') is bridged to 'NSTesting', which is not an Objective-C class}} \
+                         // expected-error {{cast of C pointer type 'CFTestingRef' (aka '__CFError *') to Objective-C pointer type 'NSString *' requires a bridged cast}} \
+                         // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+                         // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFTestingRef' (aka '__CFError *') into ARC}}
+}
+
+typedef CFErrorRef CFErrorRef1;
+
+typedef CFErrorRef1 CFErrorRef2; // expected-note 2 {{declared here}}
+
+@protocol P1 @end
+@protocol P2 @end
+@protocol P3 @end
+@protocol P4 @end
+@protocol P5 @end
+
+@interface NSError<P1, P2, P3> @end // expected-note 5 {{declared here}}
+
+@interface MyError : NSError // expected-note 1 {{declared here}}
+@end
+
+@interface NSUColor @end
+
+@class NSString;
+
+void Test2(CFErrorRef2 cf, NSError *ns, NSString *str, Class c, CFUColor2Ref cf2) {
+  (void)(NSString *)cf; // expected-warning {{'CFErrorRef2' (aka '__CFErrorRef *') bridges to NSError, not 'NSString'}} \
+                        // expected-error {{cast of C pointer type 'CFErrorRef2' (aka '__CFErrorRef *') to Objective-C pointer type 'NSString *' requires a bridged cast}} \
+                        // expected-note {{__bridge to convert directly (no change in ownership)}} \
+                        // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka '__CFErrorRef *') into ARC}}
+  (void)(NSError *)cf; // expected-error {{cast of C pointer type 'CFErrorRef2' (aka '__CFErrorRef *') to Objective-C pointer type 'NSError *' requires a bridged cast}} \
+                       // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+                       // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka '__CFErrorRef *') into ARC}}
+  (void)(MyError*)cf; // expected-error {{cast of C pointer type 'CFErrorRef2' (aka '__CFErrorRef *') to Objective-C pointer type 'MyError *' requires a bridged cast}} \
+                        // expected-note {{__bridge to convert directly (no change in ownership)}} \
+                        // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka '__CFErrorRef *') into ARC}}
+  (void)(NSUColor *)cf2; // expected-error {{cast of C pointer type 'CFUColor2Ref' (aka '__CFUPrimeColor *') to Objective-C pointer type 'NSUColor *' requires a bridged cast}} \
+                         // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+                         // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFUColor2Ref' (aka '__CFUPrimeColor *') into ARC}}
+  (void)(CFErrorRef)ns; // expected-error {{cast of Objective-C pointer type 'NSError *' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+                        // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+ 			// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
+  (void)(CFErrorRef)str;  // expected-warning {{'NSString' cannot bridge to 'CFErrorRef' (aka '__CFErrorRef *')}} \\
+                          // expected-error {{cast of Objective-C pointer type 'NSString *' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+                        // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+ 			// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
+  (void)(Class)cf; // expected-warning {{'CFErrorRef2' (aka '__CFErrorRef *') bridges to NSError, not 'Class'}} \\
+                   // expected-error {{cast of C pointer type 'CFErrorRef2' (aka '__CFErrorRef *') to Objective-C pointer type 'Class' requires a bridged cast}} \
+ 			// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka '__CFErrorRef *') into ARC}}
+  (void)(CFErrorRef)c; // expected-warning {{'__unsafe_unretained Class' cannot bridge to 'CFErrorRef' (aka '__CFErrorRef *}} \\
+                       // expected-error {{cast of Objective-C pointer type 'Class' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+			// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
+}
+
+
+void Test3(CFErrorRef cf, NSError *ns) {
+  (void)(id)cf; // expected-error {{cast of C pointer type 'CFErrorRef' (aka '__CFErrorRef *') to Objective-C pointer type 'id' requires a bridged cast}} \
+		// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+		// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef' (aka '__CFErrorRef *') into ARC}}
+ (void)(id<P1, P2>)cf; // expected-error {{cast of C pointer type 'CFErrorRef' (aka '__CFErrorRef *') to Objective-C pointer type 'id<P1,P2>' requires a bridged cast}} \
+		// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+		// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef' (aka '__CFErrorRef *') into ARC}}
+ (void)(id<P1, P2, P4>)cf; // expected-warning {{'CFErrorRef' (aka '__CFErrorRef *') bridges to NSError, not 'id<P1,P2,P4>'}} \
+                           // expected-error {{cast of C pointer type 'CFErrorRef' (aka '__CFErrorRef *') to Objective-C pointer type 'id<P1,P2,P4>' requires a bridged cast}} \
+		// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+		// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef' (aka '__CFErrorRef *') into ARC}}
+}
+
+void Test4(CFMyErrorRef cf) {
+   (void)(id)cf; // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') to Objective-C pointer type 'id' requires a bridged cast}} \
+			// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *') into ARC}}
+ (void)(id<P1, P2>)cf; // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') to Objective-C pointer type 'id<P1,P2>' requires a bridged cast}} \
+			// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *') into ARC}}
+ (void)(id<P1, P2, P3>)cf; // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') to Objective-C pointer type 'id<P1,P2,P3>' requires a bridged cast}} \
+			// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *') into ARC}}
+ (void)(id<P2, P3>)cf; // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') to Objective-C pointer type 'id<P2,P3>' requires a bridged cast}} \
+			// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *') into ARC}}
+ (void)(id<P1, P2, P4>)cf; // expected-warning {{'CFMyErrorRef' (aka '__CFMyErrorRef *') bridges to MyError, not 'id<P1,P2,P4>'}} \
+                           // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') to Objective-C pointer type 'id<P1,P2,P4>' requires a bridged cast}} \
+				// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+				// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *') into ARC}}
+}
+
+void Test5(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12, id<P2, P3> P23) {
+ (void)(CFErrorRef)ID; // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+			// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
+ (void)(CFErrorRef)P123; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3>' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+			// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
+ (void)(CFErrorRef)P1234; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3,P4>' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+			// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
+ (void)(CFErrorRef)P12; // expected-error {{cast of Objective-C pointer type 'id<P1,P2>' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+			// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
+ (void)(CFErrorRef)P23; // expected-error {{cast of Objective-C pointer type 'id<P2,P3>' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+			// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
+}
+
+void Test6(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12, id<P2, P3> P23) {
+
+ (void)(CFMyErrorRef)ID; // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') requires a bridged cast}} \
+				// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+				// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *')}}
+ (void)(CFMyErrorRef)P123; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3>' to C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') requires a bridged cast}} \
+				// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+				// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *')}}
+ (void)(CFMyErrorRef)P1234; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3,P4>' to C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') requires a bridged cast}} \
+				// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+				// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *')}}
+ (void)(CFMyErrorRef)P12; // expected-error {{cast of Objective-C pointer type 'id<P1,P2>' to C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') requires a bridged cast}} \
+				// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+				// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *')}}
+ (void)(CFMyErrorRef)P23; // expected-error {{cast of Objective-C pointer type 'id<P2,P3>' to C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') requires a bridged cast}} \
+				// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+				// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *')}}
+}
+
+typedef struct __attribute__ ((objc_bridge(MyPersonalError))) __CFMyPersonalErrorRef * CFMyPersonalErrorRef;  // expected-note 1 {{declared here}}
+
+@interface MyPersonalError : NSError <P4> // expected-note 1 {{declared here}}
+@end
+
+void Test7(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12, id<P2, P3> P23) {
+ (void)(CFMyPersonalErrorRef)ID; // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') requires a bridged cast}} \
+				 // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+				 // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *')}}
+ (void)(CFMyPersonalErrorRef)P123; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3>' to C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') requires a bridged cast}} \
+				 // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+				 // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *')}}
+ (void)(CFMyPersonalErrorRef)P1234; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3,P4>' to C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') requires a bridged cast}} \
+				 // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+				 // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *')}}
+ (void)(CFMyPersonalErrorRef)P12; // expected-error {{cast of Objective-C pointer type 'id<P1,P2>' to C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') requires a bridged cast}} \
+				 // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+				 // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *')}}
+ (void)(CFMyPersonalErrorRef)P23; // expected-error {{cast of Objective-C pointer type 'id<P2,P3>' to C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') requires a bridged cast}} \
+				 // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+				 // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *')}}
+}
+
+void Test8(CFMyPersonalErrorRef cf) {
+  (void)(id)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') to Objective-C pointer type 'id' requires a bridged cast}} \
+		// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+		// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') into ARC}}
+  (void)(id<P1>)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1>' requires a bridged cast}} \
+		// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+		// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') into ARC}}
+  (void)(id<P1, P2>)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1,P2>' requires a bridged cast}} \
+		// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+		// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') into ARC}}
+  (void)(id<P1, P2, P3>)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1,P2,P3>' requires a bridged cast}} \
+		// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+		// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') into ARC}}
+  (void)(id<P1, P2, P3, P4>)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1,P2,P3,P4>' requires a bridged cast}} \
+		// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+		// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') into ARC}}
+  (void)(id<P1, P2, P3, P4, P5>)cf; // expected-warning {{'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') bridges to MyPersonalError, not 'id<P1,P2,P3,P4,P5>'}} \
+                                    // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1,P2,P3,P4,P5>' requires a bridged cast}} \
+		// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+		// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') into ARC}}
+}
+
+void Test9(CFErrorRef2 cf, NSError *ns, NSString *str, Class c, CFUColor2Ref cf2) {
+  (void)(__bridge NSString *)cf; // expected-warning {{'CFErrorRef2' (aka '__CFErrorRef *') bridges to NSError, not 'NSString'}}
+  (void)(__bridge NSError *)cf; // okay
+  (void)(__bridge MyError*)cf; // okay,
+  (void)(__bridge NSUColor *)cf2; // okay
+  (void)(__bridge CFErrorRef)ns; // okay
+  (void)(__bridge CFErrorRef)str;  // expected-warning {{'NSString' cannot bridge to 'CFErrorRef' (aka '__CFErrorRef *')}}
+  (void)(__bridge Class)cf; // expected-warning {{'CFErrorRef2' (aka '__CFErrorRef *') bridges to NSError, not 'Class'}}
+  (void)(__bridge CFErrorRef)c; // expected-warning {{'__unsafe_unretained Class' cannot bridge to 'CFErrorRef' (aka '__CFErrorRef *')}}
+}
diff --git a/test/SemaObjCXX/objcbridge-attribute.mm b/test/SemaObjCXX/objcbridge-attribute.mm
new file mode 100644
index 0000000..e777774
--- /dev/null
+++ b/test/SemaObjCXX/objcbridge-attribute.mm
@@ -0,0 +1,210 @@
+// RUN: %clang_cc1 -fsyntax-only -x objective-c++ -fobjc-arc -verify -Wno-objc-root-class %s
+// rdar://15454846
+
+typedef struct __attribute__ ((objc_bridge(NSError))) __CFErrorRef * CFErrorRef; // expected-note 5 {{declared here}}
+
+typedef struct __attribute__ ((objc_bridge(MyError))) __CFMyErrorRef * CFMyErrorRef; // expected-note 1 {{declared here}}
+
+typedef struct __attribute__((objc_bridge(12))) __CFMyColor  *CFMyColorRef; // expected-error {{parameter of 'objc_bridge' attribute must be a single name of an Objective-C class}}
+
+typedef struct __attribute__ ((objc_bridge)) __CFArray *CFArrayRef; // expected-error {{'objc_bridge' attribute takes one argument}}
+
+typedef struct __attribute__((objc_bridge(NSLocale, NSError))) __CFLocale *CFLocaleRef;// expected-error {{use of undeclared identifier 'NSError'}}
+
+typedef struct __attribute__((objc_bridge(NSDictionary))) __CFDictionary * CFDictionaryRef;
+
+typedef union __attribute__((objc_bridge(NSUColor))) __CFUPrimeColor XXX;
+typedef XXX *CFUColor2Ref;
+
+@interface I
+{
+}
+@end
+
+@protocol NSTesting @end
+@class NSString;
+
+typedef struct __attribute__((objc_bridge(NSTesting))) __CFError *CFTestingRef; // expected-note {{declared here}}
+
+id Test1(CFTestingRef cf) {
+  return (NSString *)cf; // expected-error {{CF object of type 'CFTestingRef' (aka '__CFError *') is bridged to 'NSTesting', which is not an Objective-C class}} \
+                         // expected-error {{cast of C pointer type 'CFTestingRef' (aka '__CFError *') to Objective-C pointer type 'NSString *' requires a bridged cast}} \
+                         // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+                         // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFTestingRef' (aka '__CFError *') into ARC}}
+}
+
+typedef CFErrorRef CFErrorRef1;
+
+typedef CFErrorRef1 CFErrorRef2; // expected-note 2 {{declared here}}
+
+@protocol P1 @end
+@protocol P2 @end
+@protocol P3 @end
+@protocol P4 @end
+@protocol P5 @end
+
+@interface NSError<P1, P2, P3> @end // expected-note 5 {{declared here}}
+
+@interface MyError : NSError // expected-note 1 {{declared here}}
+@end
+
+@interface NSUColor @end
+
+@class NSString;
+
+void Test2(CFErrorRef2 cf, NSError *ns, NSString *str, Class c, CFUColor2Ref cf2) {
+  (void)(NSString *)cf; // expected-warning {{'CFErrorRef2' (aka '__CFErrorRef *') bridges to NSError, not 'NSString'}} \
+                        // expected-error {{cast of C pointer type 'CFErrorRef2' (aka '__CFErrorRef *') to Objective-C pointer type 'NSString *' requires a bridged cast}} \
+                        // expected-note {{__bridge to convert directly (no change in ownership)}} \
+                        // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka '__CFErrorRef *') into ARC}}
+  (void)(NSError *)cf; // expected-error {{cast of C pointer type 'CFErrorRef2' (aka '__CFErrorRef *') to Objective-C pointer type 'NSError *' requires a bridged cast}} \
+                       // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+                       // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka '__CFErrorRef *') into ARC}}
+  (void)(MyError*)cf; // expected-error {{cast of C pointer type 'CFErrorRef2' (aka '__CFErrorRef *') to Objective-C pointer type 'MyError *' requires a bridged cast}} \
+                        // expected-note {{__bridge to convert directly (no change in ownership)}} \
+                        // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka '__CFErrorRef *') into ARC}}
+  (void)(NSUColor *)cf2; // expected-error {{cast of C pointer type 'CFUColor2Ref' (aka '__CFUPrimeColor *') to Objective-C pointer type 'NSUColor *' requires a bridged cast}} \
+                         // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+                         // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFUColor2Ref' (aka '__CFUPrimeColor *') into ARC}}
+  (void)(CFErrorRef)ns; // expected-error {{cast of Objective-C pointer type 'NSError *' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+                        // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+ 			// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
+  (void)(CFErrorRef)str;  // expected-warning {{'NSString' cannot bridge to 'CFErrorRef' (aka '__CFErrorRef *')}} \\
+                          // expected-error {{cast of Objective-C pointer type 'NSString *' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+                        // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+ 			// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
+  (void)(Class)cf; // expected-warning {{'CFErrorRef2' (aka '__CFErrorRef *') bridges to NSError, not 'Class'}} \\
+                   // expected-error {{cast of C pointer type 'CFErrorRef2' (aka '__CFErrorRef *') to Objective-C pointer type 'Class' requires a bridged cast}} \
+ 			// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka '__CFErrorRef *') into ARC}}
+  (void)(CFErrorRef)c; // expected-warning {{'__unsafe_unretained Class' cannot bridge to 'CFErrorRef' (aka '__CFErrorRef *')}} \
+                       // expected-error {{cast of Objective-C pointer type 'Class' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+			// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
+}
+
+
+void Test3(CFErrorRef cf, NSError *ns) {
+  (void)(id)cf; // expected-error {{cast of C pointer type 'CFErrorRef' (aka '__CFErrorRef *') to Objective-C pointer type 'id' requires a bridged cast}} \
+		// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+		// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef' (aka '__CFErrorRef *') into ARC}}
+ (void)(id<P1, P2>)cf; // expected-error {{cast of C pointer type 'CFErrorRef' (aka '__CFErrorRef *') to Objective-C pointer type 'id<P1,P2>' requires a bridged cast}} \
+		// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+		// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef' (aka '__CFErrorRef *') into ARC}}
+ (void)(id<P1, P2, P4>)cf; // expected-warning {{'CFErrorRef' (aka '__CFErrorRef *') bridges to NSError, not 'id<P1,P2,P4>'}} \
+                           // expected-error {{cast of C pointer type 'CFErrorRef' (aka '__CFErrorRef *') to Objective-C pointer type 'id<P1,P2,P4>' requires a bridged cast}} \
+		// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+		// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef' (aka '__CFErrorRef *') into ARC}}
+}
+
+void Test4(CFMyErrorRef cf) {
+   (void)(id)cf; // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') to Objective-C pointer type 'id' requires a bridged cast}} \
+			// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *') into ARC}}
+ (void)(id<P1, P2>)cf; // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') to Objective-C pointer type 'id<P1,P2>' requires a bridged cast}} \
+			// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *') into ARC}}
+ (void)(id<P1, P2, P3>)cf; // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') to Objective-C pointer type 'id<P1,P2,P3>' requires a bridged cast}} \
+			// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *') into ARC}}
+ (void)(id<P2, P3>)cf; // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') to Objective-C pointer type 'id<P2,P3>' requires a bridged cast}} \
+			// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *') into ARC}}
+ (void)(id<P1, P2, P4>)cf; // expected-warning {{'CFMyErrorRef' (aka '__CFMyErrorRef *') bridges to MyError, not 'id<P1,P2,P4>'}} \
+                           // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') to Objective-C pointer type 'id<P1,P2,P4>' requires a bridged cast}} \
+				// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+				// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *') into ARC}}
+}
+
+void Test5(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12, id<P2, P3> P23) {
+ (void)(CFErrorRef)ID; // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+			// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
+ (void)(CFErrorRef)P123; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3>' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+			// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
+ (void)(CFErrorRef)P1234; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3,P4>' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+			// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
+ (void)(CFErrorRef)P12; // expected-error {{cast of Objective-C pointer type 'id<P1,P2>' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+			// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
+ (void)(CFErrorRef)P23; // expected-error {{cast of Objective-C pointer type 'id<P2,P3>' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+			// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
+}
+
+void Test6(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12, id<P2, P3> P23) {
+
+ (void)(CFMyErrorRef)ID; // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') requires a bridged cast}} \
+				// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+				// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *')}}
+ (void)(CFMyErrorRef)P123; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3>' to C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') requires a bridged cast}} \
+				// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+				// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *')}}
+ (void)(CFMyErrorRef)P1234; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3,P4>' to C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') requires a bridged cast}} \
+				// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+				// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *')}}
+ (void)(CFMyErrorRef)P12; // expected-error {{cast of Objective-C pointer type 'id<P1,P2>' to C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') requires a bridged cast}} \
+				// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+				// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *')}}
+ (void)(CFMyErrorRef)P23; // expected-error {{cast of Objective-C pointer type 'id<P2,P3>' to C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') requires a bridged cast}} \
+				// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+				// expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *')}}
+}
+
+typedef struct __attribute__ ((objc_bridge(MyPersonalError))) __CFMyPersonalErrorRef * CFMyPersonalErrorRef;  // expected-note 1 {{declared here}}
+
+@interface MyPersonalError : NSError <P4> // expected-note 1 {{declared here}}
+@end
+
+void Test7(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12, id<P2, P3> P23) {
+ (void)(CFMyPersonalErrorRef)ID; // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') requires a bridged cast}} \
+				 // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+				 // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *')}}
+ (void)(CFMyPersonalErrorRef)P123; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3>' to C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') requires a bridged cast}} \
+				 // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+				 // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *')}}
+ (void)(CFMyPersonalErrorRef)P1234; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3,P4>' to C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') requires a bridged cast}} \
+				 // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+				 // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *')}}
+ (void)(CFMyPersonalErrorRef)P12; // expected-error {{cast of Objective-C pointer type 'id<P1,P2>' to C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') requires a bridged cast}} \
+				 // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+				 // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *')}}
+ (void)(CFMyPersonalErrorRef)P23; // expected-error {{cast of Objective-C pointer type 'id<P2,P3>' to C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') requires a bridged cast}} \
+				 // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+				 // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *')}}
+}
+
+void Test8(CFMyPersonalErrorRef cf) {
+  (void)(id)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') to Objective-C pointer type 'id' requires a bridged cast}} \
+		// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+		// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') into ARC}}
+  (void)(id<P1>)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1>' requires a bridged cast}} \
+		// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+		// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') into ARC}}
+  (void)(id<P1, P2>)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1,P2>' requires a bridged cast}} \
+		// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+		// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') into ARC}}
+  (void)(id<P1, P2, P3>)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1,P2,P3>' requires a bridged cast}} \
+		// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+		// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') into ARC}}
+  (void)(id<P1, P2, P3, P4>)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1,P2,P3,P4>' requires a bridged cast}} \
+		// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+		// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') into ARC}}
+  (void)(id<P1, P2, P3, P4, P5>)cf; // expected-warning {{'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') bridges to MyPersonalError, not 'id<P1,P2,P3,P4,P5>'}} \
+                                    // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1,P2,P3,P4,P5>' requires a bridged cast}} \
+		// expected-note {{use __bridge to convert directly (no change in ownership)}} \
+		// expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') into ARC}}
+}
+
+void Test9(CFErrorRef2 cf, NSError *ns, NSString *str, Class c, CFUColor2Ref cf2) {
+  (void)(__bridge NSString *)cf; // expected-warning {{'CFErrorRef2' (aka '__CFErrorRef *') bridges to NSError, not 'NSString'}}
+  (void)(__bridge NSError *)cf; // okay
+  (void)(__bridge MyError*)cf; // okay,
+  (void)(__bridge NSUColor *)cf2; // okay
+  (void)(__bridge CFErrorRef)ns; // okay
+  (void)(__bridge CFErrorRef)str;  // expected-warning {{'NSString' cannot bridge to 'CFErrorRef' (aka '__CFErrorRef *')}}
+  (void)(__bridge Class)cf; // expected-warning {{'CFErrorRef2' (aka '__CFErrorRef *') bridges to NSError, not 'Class'}}
+  (void)(__bridge CFErrorRef)c; // expected-warning {{'__unsafe_unretained Class' cannot bridge to 'CFErrorRef' (aka '__CFErrorRef *')}}
+}
diff --git a/test/SemaObjCXX/objcbridge-related-attribute.mm b/test/SemaObjCXX/objcbridge-related-attribute.mm
new file mode 100644
index 0000000..51fd03e
--- /dev/null
+++ b/test/SemaObjCXX/objcbridge-related-attribute.mm
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -fsyntax-only -x objective-c++ -verify -Wno-objc-root-class %s
+// rdar://15499111
+typedef struct __attribute__((objc_bridge_related(NSColor,colorWithCGColor:,CGColor))) CGColor *CGColorRef; // expected-note 6 {{declared here}}
+
+@interface NSColor // expected-note 6 {{declared here}}
++ (NSColor *)colorWithCGColor:(CGColorRef)cgColor;
+- (CGColorRef)CGColor;
+@end
+
+@interface NSTextField
+- (void)setBackgroundColor:(NSColor *)color;
+- (NSColor *)backgroundColor;
+@end
+
+
+NSColor *Test1(NSColor *nsColor, CGColorRef newColor) {
+  nsColor = newColor; // expected-error {{'CGColorRef' (aka 'CGColor *') must be explicitly converted to 'NSColor *'; use '+colorWithCGColor:' method for this conversion}}
+  NSColor *ns = newColor; // expected-error {{'CGColorRef' (aka 'CGColor *') must be explicitly converted to 'NSColor *'; use '+colorWithCGColor:' method for this conversion}} 
+  return newColor; // expected-error {{'CGColorRef' (aka 'CGColor *') must be explicitly converted to 'NSColor *'; use '+colorWithCGColor:' method for this conversion}} 
+}
+
+CGColorRef Test2(NSColor *newColor, CGColorRef cgColor) {
+  cgColor = newColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'CGColor *'); use '-CGColor' method for this conversion}}
+  CGColorRef cg = newColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'CGColor *'); use '-CGColor' method for this conversion}} 
+  return newColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'CGColor *'); use '-CGColor' method for this conversion}}
+}
+
diff --git a/test/SemaObjCXX/objcbridge-static-cast.mm b/test/SemaObjCXX/objcbridge-static-cast.mm
new file mode 100644
index 0000000..97cc5c0
--- /dev/null
+++ b/test/SemaObjCXX/objcbridge-static-cast.mm
@@ -0,0 +1,135 @@
+// RUN: %clang_cc1 -fsyntax-only -x objective-c++ -fobjc-arc -verify -Wno-objc-root-class %s
+// rdar://16756639
+
+typedef struct __attribute__ ((objc_bridge(NSError))) __CFErrorRef * CFErrorRef; // expected-note 3 {{declared here}}
+
+typedef struct __attribute__ ((objc_bridge(MyError))) __CFMyErrorRef * CFMyErrorRef; // expected-note 1 {{declared here}}
+
+typedef struct __attribute__((objc_bridge(12))) __CFMyColor  *CFMyColorRef; // expected-error {{parameter of 'objc_bridge' attribute must be a single name of an Objective-C class}}
+
+typedef struct __attribute__ ((objc_bridge)) __CFArray *CFArrayRef; // expected-error {{'objc_bridge' attribute takes one argument}}
+
+typedef struct __attribute__((objc_bridge(NSLocale, NSError))) __CFLocale *CFLocaleRef;// expected-error {{use of undeclared identifier 'NSError'}}
+
+typedef struct __attribute__((objc_bridge(NSDictionary))) __CFDictionary * CFDictionaryRef;
+
+typedef union __attribute__((objc_bridge(NSUColor))) __CFUPrimeColor XXX;
+typedef XXX *CFUColor2Ref;
+
+@interface I
+{
+}
+@end
+
+@protocol NSTesting @end
+@class NSString;
+
+typedef struct __attribute__((objc_bridge(NSTesting))) __CFError *CFTestingRef; // expected-note {{declared here}}
+
+id Test1(CFTestingRef cf) {
+  return static_cast<NSString *>(cf); // expected-error {{CF object of type 'CFTestingRef' (aka '__CFError *') is bridged to 'NSTesting', which is not an Objective-C class}} \
+                         // expected-error {{cast of C pointer type 'CFTestingRef' (aka '__CFError *') to Objective-C pointer type 'NSString *' requires a bridged cast}} \
+			 // expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
+                         // expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFTestingRef' (aka '__CFError *') into ARC}}
+}
+
+typedef CFErrorRef CFErrorRef1;
+
+typedef CFErrorRef1 CFErrorRef2; // expected-note 1 {{declared here}}
+
+@protocol P1 @end
+@protocol P2 @end
+@protocol P3 @end
+@protocol P4 @end
+@protocol P5 @end
+
+@interface NSError<P1, P2, P3> @end // expected-note 3 {{declared here}}
+
+@interface MyError : NSError // expected-note 1 {{declared here}}
+@end
+
+@interface NSUColor @end
+
+@class NSString;
+
+void Test2(CFErrorRef2 cf, NSError *ns, NSString *str, Class c, CFUColor2Ref cf2) {
+  (void)static_cast<NSString *>(cf); // expected-warning {{'CFErrorRef2' (aka '__CFErrorRef *') bridges to NSError, not 'NSString'}} \
+                        // expected-error {{cast of C pointer type 'CFErrorRef2' (aka '__CFErrorRef *') to Objective-C pointer type 'NSString *' requires a bridged cast}} \
+                        // expected-note {{__bridge with C-style cast to convert directly (no change in ownership)}} \
+                        // expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFErrorRef2' (aka '__CFErrorRef *') into ARC}}
+  (void)static_cast<NSError *>(cf); // expected-error {{cast of C pointer type 'CFErrorRef2' (aka '__CFErrorRef *') to Objective-C pointer type 'NSError *' requires a bridged cast}} \
+                       // expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
+                       // expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFErrorRef2' (aka '__CFErrorRef *') into ARC}}
+  (void)static_cast<MyError*>(cf); // expected-error {{cast of C pointer type 'CFErrorRef2' (aka '__CFErrorRef *') to Objective-C pointer type 'MyError *' requires a bridged cast}} \
+                        // expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
+                        // expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFErrorRef2' (aka '__CFErrorRef *') into ARC}}
+  (void)static_cast<NSUColor *>(cf2); // expected-error {{cast of C pointer type 'CFUColor2Ref' (aka '__CFUPrimeColor *') to Objective-C pointer type 'NSUColor *' requires a bridged cast}} \
+                         // expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
+                         // expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFUColor2Ref' (aka '__CFUPrimeColor *') into ARC}}
+  (void)static_cast<CFErrorRef>(ns); // expected-error {{cast of Objective-C pointer type 'NSError *' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+                        // expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
+ 			// expected-note {{use __bridge_retained with C-style cast to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
+  (void)static_cast<CFErrorRef>(str);  // expected-warning {{'NSString' cannot bridge to 'CFErrorRef' (aka '__CFErrorRef *')}} \\
+                          // expected-error {{cast of Objective-C pointer type 'NSString *' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+                        // expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
+ 			// expected-note {{use __bridge_retained with C-style cast to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
+  (void)static_cast<Class>(cf); // expected-warning {{'CFErrorRef2' (aka '__CFErrorRef *') bridges to NSError, not 'Class'}} \\
+                   // expected-error {{cast of C pointer type 'CFErrorRef2' (aka '__CFErrorRef *') to Objective-C pointer type 'Class' requires a bridged cast}} \
+ 			// expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFErrorRef2' (aka '__CFErrorRef *') into ARC}}
+  (void)static_cast<CFErrorRef>(c); // expected-warning {{'Class' cannot bridge to 'CFErrorRef' (aka '__CFErrorRef *}} \\
+                       // expected-error {{cast of Objective-C pointer type 'Class' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+			// expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_retained with C-style cast to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
+}
+
+
+void Test3(CFErrorRef cf, NSError *ns) {
+  (void)static_cast<id>(cf); // expected-error {{cast of C pointer type 'CFErrorRef' (aka '__CFErrorRef *') to Objective-C pointer type 'id' requires a bridged cast}} \
+		// expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
+		// expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFErrorRef' (aka '__CFErrorRef *') into ARC}}
+ (void)static_cast< id<P1, P2> >(cf); // expected-error {{cast of C pointer type 'CFErrorRef' (aka '__CFErrorRef *') to Objective-C pointer type 'id<P1,P2>' requires a bridged cast}} \
+		// expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
+		// expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFErrorRef' (aka '__CFErrorRef *') into ARC}}
+ (void)static_cast< id<P1, P2, P4> >(cf); // expected-warning {{'CFErrorRef' (aka '__CFErrorRef *') bridges to NSError, not 'id<P1,P2,P4>'}} \
+                           // expected-error {{cast of C pointer type 'CFErrorRef' (aka '__CFErrorRef *') to Objective-C pointer type 'id<P1,P2,P4>' requires a bridged cast}} \
+		// expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
+		// expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFErrorRef' (aka '__CFErrorRef *') into ARC}}
+}
+
+void Test4(CFMyErrorRef cf) {
+   (void)static_cast<id>(cf); // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') to Objective-C pointer type 'id' requires a bridged cast}} \
+			// expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *') into ARC}}
+ (void)static_cast< id<P1, P2> >(cf); // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') to Objective-C pointer type 'id<P1,P2>' requires a bridged cast}} \
+			// expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *') into ARC}}
+ (void)static_cast< id<P1, P2, P3> >(cf); // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') to Objective-C pointer type 'id<P1,P2,P3>' requires a bridged cast}} \
+			// expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *') into ARC}}
+ (void)static_cast< id<P2, P3> >(cf); // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') to Objective-C pointer type 'id<P2,P3>' requires a bridged cast}} \
+			// expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *') into ARC}}
+ (void)static_cast< id<P1, P2, P4> >(cf); // expected-warning {{'CFMyErrorRef' (aka '__CFMyErrorRef *') bridges to MyError, not 'id<P1,P2,P4>'}} \
+                           // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') to Objective-C pointer type 'id<P1,P2,P4>' requires a bridged cast}} \
+				// expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
+				// expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *') into ARC}}
+}
+
+void Test5(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12, id<P2, P3> P23) {
+ (void)static_cast<CFErrorRef>(ID); // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+			// expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_retained with C-style cast to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
+ (void)static_cast<CFErrorRef>(P123); // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3>' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+			// expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_retained with C-style cast to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
+ (void)static_cast<CFErrorRef>(P1234); // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3,P4>' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+			// expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_retained with C-style cast to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
+ (void)static_cast<CFErrorRef>(P12); // expected-error {{cast of Objective-C pointer type 'id<P1,P2>' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+			// expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_retained with C-style cast to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
+ (void)static_cast<CFErrorRef>(P23); // expected-error {{cast of Objective-C pointer type 'id<P2,P3>' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+			// expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
+			// expected-note {{use __bridge_retained with C-style cast to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
+}
diff --git a/test/SemaObjCXX/old-style-cast.mm b/test/SemaObjCXX/old-style-cast.mm
new file mode 100644
index 0000000..5dbac09
--- /dev/null
+++ b/test/SemaObjCXX/old-style-cast.mm
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -Wold-style-cast -verify %s
+// expected-no-diagnostics
+
+// We don't currently have a way to write ARC/C++ bridge casts in terms of C++
+// casts, so ensure we don't emit an old-style-cast warning in these cases.
+
+id test(void *opaqueInput) {
+  id someObjCObject = (__bridge id)opaqueInput;
+  void *someCFObject = (__bridge_retained void *)someObjCObject;
+  return (__bridge_transfer id)someCFObject;
+}
diff --git a/test/SemaObjCXX/propert-dot-error.mm b/test/SemaObjCXX/propert-dot-error.mm
index 2a462e4..e28204c 100644
--- a/test/SemaObjCXX/propert-dot-error.mm
+++ b/test/SemaObjCXX/propert-dot-error.mm
@@ -53,7 +53,7 @@
 
 // PR9759
 class Forward;
-@interface D {
+@interface D { // expected-note 2 {{'D' declared here}}
 @public
   int ivar;
 }
@@ -64,6 +64,6 @@
 void testD(D *d) {
   d.Forward::property = 17; // expected-error{{property access cannot be qualified with 'Forward::'}}
   d->Forward::ivar = 12; // expected-error{{instance variable access cannot be qualified with 'Forward::'}}
-  d.D::property = 17; // expected-error{{expected a class or namespace}}
-  d->D::ivar = 12; // expected-error{{expected a class or namespace}}
+  d.D::property = 17; // expected-error{{'D' is not a class, namespace, or scoped enumeration}}
+  d->D::ivar = 12; // expected-error{{'D' is not a class, namespace, or scoped enumeration}}
 }
diff --git a/test/SemaObjCXX/property-invalid-type.mm b/test/SemaObjCXX/property-invalid-type.mm
new file mode 100644
index 0000000..5b8a848
--- /dev/null
+++ b/test/SemaObjCXX/property-invalid-type.mm
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
+
+@interface I
+{
+  A* response; // expected-error {{unknown type name 'A'}}
+}
+@end
+@interface I ()
+@property A* response;  // expected-error {{unknown type name 'A'}}
+@property  int helper;
+@end
+@implementation I
+@synthesize response;
+- (void) foo :(A*) a   // expected-error {{expected a type}}
+{
+  self.response = a;
+}
+@end
+
+void foo(I *i)
+{
+  i.helper;
+}
diff --git a/test/SemaObjCXX/warn-objc-literal-conversion.mm b/test/SemaObjCXX/warn-objc-literal-conversion.mm
new file mode 100644
index 0000000..4464561
--- /dev/null
+++ b/test/SemaObjCXX/warn-objc-literal-conversion.mm
@@ -0,0 +1,74 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wobjc-literal-conversion %s
+
+@class NSString;
+
+@interface NSNumber
++ (NSNumber *)numberWithChar:(char)value;
++ (NSNumber *)numberWithInt:(int)value;
++ (NSNumber *)numberWithLongLong:(long long)value;
++ (NSNumber *)numberWithFloat:(float)value;
++ (NSNumber *)numberWithDouble:(double)value;
++ (NSNumber *)numberWithBool:(bool)value;
+@end
+
+@interface NSArray
++ (id)arrayWithObjects:(const id [])objects count:(int)cnt;
+@end
+
+@interface NSDictionary
++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt;
+@end
+
+void char_test() {
+  if (@'a') {}
+  // expected-warning@-1{{implicit boolean conversion of Objective-C object literal always evaluates to true}}
+}
+
+void int_test() {
+  if (@12) {}
+  // expected-warning@-1{{implicit boolean conversion of Objective-C object literal always evaluates to true}}
+  if (@-12) {}
+  // expected-warning@-1{{implicit boolean conversion of Objective-C object literal always evaluates to true}}
+  if (@12LL) {}
+  // expected-warning@-1{{implicit boolean conversion of Objective-C object literal always evaluates to true}}
+  if (@-12LL) {}
+  // expected-warning@-1{{implicit boolean conversion of Objective-C object literal always evaluates to true}}
+}
+
+void float_test() {
+  if (@12.55) {}
+  // expected-warning@-1{{implicit boolean conversion of Objective-C object literal always evaluates to true}}
+  if (@-12.55) {}
+  // expected-warning@-1{{implicit boolean conversion of Objective-C object literal always evaluates to true}}
+  if (@12.55F) {}
+  // expected-warning@-1{{implicit boolean conversion of Objective-C object literal always evaluates to true}}
+  if (@-12.55F) {}
+  // expected-warning@-1{{implicit boolean conversion of Objective-C object literal always evaluates to true}}
+}
+
+void bool_test() {
+  if (@true) {}
+  // expected-warning@-1{{implicit boolean conversion of Objective-C object literal always evaluates to true}}
+  if (@false) {}
+  // expected-warning@-1{{implicit boolean conversion of Objective-C object literal always evaluates to true}}
+}
+
+void string_test() {
+  if (@"asdf") {}
+  // expected-warning@-1{{implicit boolean conversion of Objective-C object literal always evaluates to true}}
+}
+
+void array_test() {
+  if (@[ @313, @331, @367, @379 ]) {}
+  // expected-warning@-1{{implicit boolean conversion of Objective-C object literal always evaluates to true}}
+}
+
+void dictionary_test() {
+  if (@{ @0: @0, @1: @1, @2: @1, @3: @3 }) {}
+  // expected-warning@-1{{implicit boolean conversion of Objective-C object literal always evaluates to true}}
+}
+
+void objc_bool_test () {
+  if (__objc_yes) {}
+  if (__objc_no) {}
+}
diff --git a/test/SemaOpenCL/address-spaces.cl b/test/SemaOpenCL/address-spaces.cl
index 6ab10b3..b188ea4 100644
--- a/test/SemaOpenCL/address-spaces.cl
+++ b/test/SemaOpenCL/address-spaces.cl
@@ -11,3 +11,29 @@
   ip = &li; // expected-error {{assigning '__local int *' to 'int *' changes address space of pointer}}
   ip = &ci; // expected-error {{assigning '__constant int *' to 'int *' changes address space of pointer}}
 }
+
+void explicit_cast(global int* g, local int* l, constant int* c, private int* p)
+{
+  g = (global int*) l;    // expected-error {{casting '__local int *' to type '__global int *' changes address space of pointer}}
+  g = (global int*) c;    // expected-error {{casting '__constant int *' to type '__global int *' changes address space of pointer}}
+  g = (global int*) p;    // expected-error {{casting 'int *' to type '__global int *' changes address space of pointer}}
+
+  l = (local int*) g;     // expected-error {{casting '__global int *' to type '__local int *' changes address space of pointer}}
+  l = (local int*) c;     // expected-error {{casting '__constant int *' to type '__local int *' changes address space of pointer}}
+  l = (local int*) p;     // expected-error {{casting 'int *' to type '__local int *' changes address space of pointer}}
+
+  c = (constant int*) g;  // expected-error {{casting '__global int *' to type '__constant int *' changes address space of pointer}}
+  c = (constant int*) l;  // expected-error {{casting '__local int *' to type '__constant int *' changes address space of pointer}}
+  c = (constant int*) p;  // expected-error {{casting 'int *' to type '__constant int *' changes address space of pointer}}
+
+  p = (private int*) g;   // expected-error {{casting '__global int *' to type 'int *' changes address space of pointer}}
+  p = (private int*) l;   // expected-error {{casting '__local int *' to type 'int *' changes address space of pointer}}
+  p = (private int*) c;   // expected-error {{casting '__constant int *' to type 'int *' changes address space of pointer}}
+}
+
+void ok_explicit_casts(global int *g, global int* g2, local int* l, local int* l2, private int* p, private int* p2)
+{
+  g = (global int*) g2;
+  l = (local int*) l2;
+  p = (private int*) p2;
+}
diff --git a/test/SemaOpenCL/array-parameters.cl b/test/SemaOpenCL/array-parameters.cl
new file mode 100644
index 0000000..200acac
--- /dev/null
+++ b/test/SemaOpenCL/array-parameters.cl
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only
+// expected-no-diagnostics
+
+kernel void foo(global int a[], local int b[], constant int c[4]) { }
+
+void bar(global int a[], local int b[], constant int c[4], int d[]) { }
diff --git a/test/SemaOpenCL/event_t.cl b/test/SemaOpenCL/event_t.cl
index 5ab5c10..e098839 100644
--- a/test/SemaOpenCL/event_t.cl
+++ b/test/SemaOpenCL/event_t.cl
@@ -4,7 +4,7 @@
 
 constant struct evt_s {
   event_t evt;  // expected-error {{the event_t type cannot be used to declare a structure or union field}}
-} evt_str;
+} evt_str = {0};
 
 void foo(event_t evt); // expected-note {{passing argument to parameter 'evt' here}}
 
diff --git a/test/SemaOpenCL/extern.cl b/test/SemaOpenCL/extern.cl
new file mode 100644
index 0000000..ee5e072
--- /dev/null
+++ b/test/SemaOpenCL/extern.cl
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -x cl -cl-std=CL1.2 -emit-llvm %s -o - -verify | FileCheck %s
+// expected-no-diagnostics
+
+// CHECK: @foo = external global float
+extern constant float foo;
+
+kernel void test(global float* buf) {
+  buf[0] += foo;
+}
diff --git a/test/SemaOpenCL/func_ptr.cl b/test/SemaOpenCL/func_ptr.cl
new file mode 100644
index 0000000..f21a3d3
--- /dev/null
+++ b/test/SemaOpenCL/func_ptr.cl
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only
+
+void foo(void*);
+
+void bar()
+{
+  // declaring a function pointer is an error
+  void (*fptr)(int); // expected-error{{pointers to functions are not allowed}}
+
+  // taking the address of a function is an error
+  foo((void*)foo); // expected-error{{taking address of function is not allowed}}
+  foo(&foo); // expected-error{{taking address of function is not allowed}}
+
+  // just calling a function is correct
+  foo(0);
+}
diff --git a/test/SemaOpenCL/half.cl b/test/SemaOpenCL/half.cl
index 0e6acb7..11abf64 100644
--- a/test/SemaOpenCL/half.cl
+++ b/test/SemaOpenCL/half.cl
@@ -3,7 +3,7 @@
 #pragma OPENCL EXTENSION cl_khr_fp16 : disable
 
 half half_disabled(half *p, // expected-error{{declaring function return value of type 'half' is not allowed}}
-                   half h)  // expected-error{{declaring function argument of type 'half' is not allowed}} 
+                   half h)  // expected-error{{declaring function parameter of type 'half' is not allowed}}
 {
   half a[2]; // expected-error{{declaring variable of type 'half [2]' is not allowed}}
   half b;    // expected-error{{declaring variable of type 'half' is not allowed}}
diff --git a/test/SemaOpenCL/invalid-constant.cl b/test/SemaOpenCL/invalid-constant.cl
new file mode 100644
index 0000000..c45811f
--- /dev/null
+++ b/test/SemaOpenCL/invalid-constant.cl
@@ -0,0 +1,2 @@
+// RUN: %clang_cc1 -verify %s 
+constant int no_init; // expected-error {{variable in constant address space must be initialized}}
diff --git a/test/SemaOpenCL/invalid-kernel-attrs.cl b/test/SemaOpenCL/invalid-kernel-attrs.cl
index 668dc2a..4b4fdf7 100644
--- a/test/SemaOpenCL/invalid-kernel-attrs.cl
+++ b/test/SemaOpenCL/invalid-kernel-attrs.cl
@@ -14,3 +14,24 @@
 
 kernel __attribute__((work_group_size_hint(1,2,3))) __attribute__((work_group_size_hint(3,2,1))) void kernel7() {}  //expected-warning{{attribute 'work_group_size_hint' is already applied with different parameters}}
 
+__attribute__((reqd_work_group_size(8,16,32))) void kernel8(){} // expected-error {{attribute 'reqd_work_group_size' can only be applied to a kernel}}
+
+__attribute__((work_group_size_hint(8,16,32))) void kernel9(){} // expected-error {{attribute 'work_group_size_hint' can only be applied to a kernel}}
+
+__attribute__((vec_type_hint(char))) void kernel10(){} // expected-error {{attribute 'vec_type_hint' can only be applied to a kernel}}
+
+constant int foo1 __attribute__((reqd_work_group_size(8,16,32))) = 0; // expected-error {{'reqd_work_group_size' attribute only applies to functions}}
+
+constant int foo2 __attribute__((work_group_size_hint(8,16,32))) = 0; // expected-error {{'work_group_size_hint' attribute only applies to functions}}
+
+constant int foo3 __attribute__((vec_type_hint(char))) = 0; // expected-error {{'vec_type_hint' attribute only applies to functions}}
+
+void f_kernel_image2d_t( kernel image2d_t image ) { // expected-error {{'kernel' attribute only applies to functions}}
+  int __kernel x; // expected-error {{'__kernel' attribute only applies to functions}}
+  read_only int i; // expected-error {{'read_only' attribute only applies to parameters}}
+  __write_only int j; // expected-error {{'__write_only' attribute only applies to parameters}}
+}
+
+kernel __attribute__((reqd_work_group_size(1,2,0))) void kernel11(){} // expected-error {{'reqd_work_group_size' attribute must be greater than 0}}
+kernel __attribute__((reqd_work_group_size(1,0,2))) void kernel12(){} // expected-error {{'reqd_work_group_size' attribute must be greater than 0}}
+kernel __attribute__((reqd_work_group_size(0,1,2))) void kernel13(){} // expected-error {{'reqd_work_group_size' attribute must be greater than 0}}
diff --git a/test/SemaOpenCL/invalid-kernel.cl b/test/SemaOpenCL/invalid-kernel.cl
index c12bd84..9a50673 100644
--- a/test/SemaOpenCL/invalid-kernel.cl
+++ b/test/SemaOpenCL/invalid-kernel.cl
@@ -2,6 +2,10 @@
 
 kernel void no_ptrptr(global int **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_privatearray(__private int i[]) { } // expected-error {{kernel parameter cannot be declared as a pointer to the __private address space}}
+
 kernel int bar()  { // expected-error {{kernel must have void return type}}
   return 6;
 }
@@ -13,3 +17,15 @@
 int main() { // expected-error {{function cannot be called 'main'}}
   return 0;
 }
+
+int* global x(int* x) { // expected-error {{return value cannot be qualified with address space}}
+  return x + 1;
+}
+
+int* local x(int* x) { // expected-error {{return value cannot be qualified with address space}}
+  return x + 1;
+}
+
+int* constant x(int* x) { // expected-error {{return value cannot be qualified with address space}}
+  return x + 1;
+}
diff --git a/test/SemaOpenCL/lit.local.cfg b/test/SemaOpenCL/lit.local.cfg
new file mode 100644
index 0000000..f4ef5d2
--- /dev/null
+++ b/test/SemaOpenCL/lit.local.cfg
@@ -0,0 +1,4 @@
+config.substitutions = list(config.substitutions)
+config.substitutions.insert(0,
+    (r'%clang\b',
+     """*** Do not use the driver in Sema tests. ***""") )
diff --git a/test/SemaOpenCL/sizeof.cl b/test/SemaOpenCL/sizeof.cl
new file mode 100644
index 0000000..69fc430
--- /dev/null
+++ b/test/SemaOpenCL/sizeof.cl
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+kernel void test(global int* buf) {
+  buf[0] = sizeof(void); // expected-error {{invalid application of 'sizeof' to a void type}}
+}
diff --git a/test/SemaOpenCL/vector_conv_invalid.cl b/test/SemaOpenCL/vector_conv_invalid.cl
index e6ef5a4..90cec26 100644
--- a/test/SemaOpenCL/vector_conv_invalid.cl
+++ b/test/SemaOpenCL/vector_conv_invalid.cl
@@ -7,8 +7,8 @@
 
 void vector_conv_invalid() {
   uint4 u = (uint4)(1);
-  int4 i = u; // expected-error{{initializing 'int4' with an expression of incompatible type 'uint4'}}
-  int4 e = (int4)u; // expected-error{{invalid conversion between ext-vector type 'int4' and 'uint4'}}
+  int4 i = u; // expected-error{{initializing 'int4' (vector of 4 'int' values) with an expression of incompatible type 'uint4' (vector of 4 'unsigned int' values)}}
+  int4 e = (int4)u; // expected-error{{invalid conversion between ext-vector type 'int4' (vector of 4 'int' values) and 'uint4' (vector of 4 'unsigned int' values)}}
 
-  uint3 u4 = (uint3)u; // expected-error{{invalid conversion between ext-vector type 'uint3' and 'uint4'}}
+  uint3 u4 = (uint3)u; // expected-error{{invalid conversion between ext-vector type 'uint3' (vector of 3 'unsigned int' values) and 'uint4' (vector of 4 'unsigned int' values)}}
 }
diff --git a/test/SemaTemplate/attributes.cpp b/test/SemaTemplate/attributes.cpp
index 5a06a70..1d46058 100644
--- a/test/SemaTemplate/attributes.cpp
+++ b/test/SemaTemplate/attributes.cpp
@@ -22,7 +22,7 @@
   template<unsigned Size, unsigned Align>
   class my_aligned_storage
   {
-    __attribute__((align(Align))) char storage[Size];
+    __attribute__((aligned(Align))) char storage[Size];
   };
   
   template<typename T>
diff --git a/test/SemaTemplate/class-template-decl.cpp b/test/SemaTemplate/class-template-decl.cpp
index e65da2b..b721aab 100644
--- a/test/SemaTemplate/class-template-decl.cpp
+++ b/test/SemaTemplate/class-template-decl.cpp
@@ -14,6 +14,13 @@
   template<typename T> class D; // expected-error{{templates must have C++ linkage}}
 }
 
+extern "C" {
+  class PR17968 {
+    template<typename T> class D; // expected-error{{templates must have C++ linkage}}
+    template<typename T> void f(); // expected-error{{templates must have C++ linkage}}
+  };
+}
+
 template<class U> class A; // expected-note{{previous template declaration is here}}
 
 template<int N> class A; // expected-error{{template parameter has a different kind in template redeclaration}}
diff --git a/test/SemaTemplate/class-template-spec.cpp b/test/SemaTemplate/class-template-spec.cpp
index f9015b3..0292c1b 100644
--- a/test/SemaTemplate/class-template-spec.cpp
+++ b/test/SemaTemplate/class-template-spec.cpp
@@ -91,7 +91,7 @@
 namespace M {
   template<> struct ::N::B<short> { }; // expected-error{{class template specialization of 'B' not in a namespace enclosing 'N'}}
 
-  template<> struct ::A<long double>; // expected-error{{originally}}
+  template<> struct ::A<long double>; // expected-error{{must occur at global scope}}
 }
 
 template<> struct N::B<char> { 
@@ -119,3 +119,61 @@
   };
 
 }
+
+namespace PR18009 {
+  template <typename T> struct A {
+    template <int N, int M> struct S;
+    template <int N> struct S<N, sizeof(T)> {};
+  };
+  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}}
+        > {};
+  };
+  B<int>::S<8, sizeof(int) + 8> s; // expected-error {{undefined}}
+
+  template<int A> struct outer {
+    template<int B, int C> struct inner {};
+    template<int C> struct inner<A * 2, C> {};
+  };
+}
+
+namespace PR16519 {
+  template<typename T, T...N> struct integer_sequence { typedef T value_type; }; // expected-warning {{extension}}
+
+  template<typename T> struct __make_integer_sequence;
+  template<typename T, T N> using make_integer_sequence = typename __make_integer_sequence<T>::template make<N, N % 2>::type; // expected-warning {{extension}}
+
+  template<typename T, typename T::value_type ...Extra> struct __make_integer_sequence_impl; // expected-warning {{extension}}
+  template<typename T, T ...N, T ...Extra> struct __make_integer_sequence_impl<integer_sequence<T, N...>, Extra...> { // expected-warning 2{{extension}}
+    typedef integer_sequence<T, N..., sizeof...(N) + N..., Extra...> type;
+  };
+
+  template<typename T> struct __make_integer_sequence {
+    template<T N, T Parity, typename = void> struct make;
+    template<typename Dummy> struct make<0, 0, Dummy> { typedef integer_sequence<T> type; };
+    template<typename Dummy> struct make<1, 1, Dummy> { typedef integer_sequence<T, 0> type; };
+    template<T N, typename Dummy> struct make<N, 0, Dummy> : __make_integer_sequence_impl<make_integer_sequence<T, N/2> > {};
+    template<T N, typename Dummy> struct make<N, 1, Dummy> : __make_integer_sequence_impl<make_integer_sequence<T, N/2>, N - 1> {};
+  };
+
+  using X = make_integer_sequence<int, 5>; // expected-warning {{extension}}
+  using X = integer_sequence<int, 0, 1, 2, 3, 4>; // expected-warning {{extension}}
+}
+
+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}}
+  > 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,
+      T N = 0 // expected-note {{template parameter is declared here}}
+  > struct S;
+  template<typename T> struct S<T> {}; // expected-error {{non-type template argument specializes a template parameter with dependent type 'T'}}
+}
diff --git a/test/SemaTemplate/constexpr-instantiate.cpp b/test/SemaTemplate/constexpr-instantiate.cpp
index 95d6c23..e8e3e7d 100644
--- a/test/SemaTemplate/constexpr-instantiate.cpp
+++ b/test/SemaTemplate/constexpr-instantiate.cpp
@@ -154,7 +154,7 @@
       constexpr S2() {}
       constexpr operator int() const { return 123456; }
     };
-    int k2 = sizeof(short{S2(S2())}); // expected-error {{cannot be narrowed}} expected-note {{override}}
+    int k2 = sizeof(short{S2(S2())}); // expected-error {{cannot be narrowed}} expected-note {{insert an explicit cast to silence this issue}}
   }
 
   namespace PR12288 {
diff --git a/test/SemaTemplate/dependent-expr.cpp b/test/SemaTemplate/dependent-expr.cpp
index 01ac42e..7195c9d 100644
--- a/test/SemaTemplate/dependent-expr.cpp
+++ b/test/SemaTemplate/dependent-expr.cpp
@@ -79,3 +79,24 @@
     return ((void*)(((unsigned long)(x)|0x1ul)));
   }
 };
+
+// Regression test for crasher in r194540.
+namespace PR10837 {
+  typedef void t(int);
+  template<typename> struct A {
+    void f();
+    static t g;
+  };
+  t *p;
+  template<typename T> void A<T>::f() {
+    p = g;
+  }
+  template struct A<int>;
+}
+
+namespace PR18152 {
+  template<int N> struct A {
+    static const int n = {N};
+  };
+  template struct A<0>;
+}
diff --git a/test/SemaTemplate/dependent-names.cpp b/test/SemaTemplate/dependent-names.cpp
index 4d4aafa..011e073 100644
--- a/test/SemaTemplate/dependent-names.cpp
+++ b/test/SemaTemplate/dependent-names.cpp
@@ -232,7 +232,7 @@
       struct Data {};
     }
 
-    std::ostream &print(std::ostream &out, int); // expected-note-re {{should be declared prior to the call site$}}
+    std::ostream &print(std::ostream &out, int); // expected-note-re {{should be declared prior to the call site{{$}}}}
     std::ostream &print(std::ostream &out, ns::Data); // expected-note {{should be declared prior to the call site or in namespace 'PR10053::my_file2_a::ns'}}
     std::ostream &print(std::ostream &out, std::vector<ns2::Data>); // expected-note {{should be declared prior to the call site or in namespace 'PR10053::my_file2_a::ns2'}}
     std::ostream &print(std::ostream &out, std::pair<ns::Data, ns2::Data>); // expected-note {{should be declared prior to the call site or in an associated namespace of one of its arguments}}
@@ -397,5 +397,20 @@
   struct X {};
 };
 using size_t = decltype(sizeof(0));
-void *operator new(size_t, OperatorNew::X); // expected-note-re {{should be declared prior to the call site$}}
+void *operator new(size_t, OperatorNew::X); // expected-note-re {{should be declared prior to the call site{{$}}}}
 template void OperatorNew::f(OperatorNew::X); // expected-note {{instantiation of}}
+
+namespace PR19936 {
+  template<typename T> decltype(*T()) f() {} // expected-note {{previous}}
+  template<typename T> decltype(T() * T()) g() {} // expected-note {{previous}}
+
+  // Create some overloaded operators so we build an overload operator call
+  // instead of a builtin operator call for the dependent expression.
+  enum E {};
+  int operator*(E);
+  int operator*(E, E);
+
+  // Check that they still profile the same.
+  template<typename T> decltype(*T()) f() {} // expected-error {{redefinition}}
+  template<typename T> decltype(T() * T()) g() {} // expected-error {{redefinition}}
+}
diff --git a/test/SemaTemplate/dependent-type-identity.cpp b/test/SemaTemplate/dependent-type-identity.cpp
index 731013c..a796834 100644
--- a/test/SemaTemplate/dependent-type-identity.cpp
+++ b/test/SemaTemplate/dependent-type-identity.cpp
@@ -98,3 +98,27 @@
   template <typename T>
   T TemplateClass2<T>::member[TemplateClass2<T>::SIZE];
 }
+
+namespace PR18275 {
+  template<typename T> struct A {
+    void f(const int);
+    void g(int);
+    void h(const T);
+    void i(T);
+  };
+
+  template<typename T>
+  void A<T>::f(int x) { x = 0; }
+
+  template<typename T>
+  void A<T>::g(const int x) { x = 0; } // expected-error {{not assignable}}
+
+  template<typename T>
+  void A<T>::h(T) {} // FIXME: Should reject this. Type is different from prior decl if T is an array type.
+
+  template<typename T>
+  void A<T>::i(const T) {} // FIXME: Should reject this. Type is different from prior decl if T is an array type.
+
+  template struct A<int>;
+  template struct A<int[1]>;
+}
diff --git a/test/SemaTemplate/explicit-instantiation.cpp b/test/SemaTemplate/explicit-instantiation.cpp
index d040464..c28c5d1 100644
--- a/test/SemaTemplate/explicit-instantiation.cpp
+++ b/test/SemaTemplate/explicit-instantiation.cpp
@@ -16,7 +16,7 @@
   } 
   T* f0(T*, T*) { return T(); } // expected-warning{{expression which evaluates to zero treated as a null pointer constant of type 'int *'}}
 
-  template <typename U> T f0(T, U) { return T(); } // expected-note {{candidate template ignored: could not match 'int (int, U)' against 'int (int) const'}} \
+  template <typename U> T f0(T, U) { return T(); } // expected-note-re {{candidate template ignored: could not match 'int (int, U){{( __attribute__\(\(thiscall\)\))?}}' against 'int (int){{( __attribute__\(\(thiscall\)\))?}} const'}} \
                                                    // expected-note {{candidate template ignored: could not match 'int' against 'int *'}}
 };
 
diff --git a/test/SemaTemplate/explicit-specialization-member.cpp b/test/SemaTemplate/explicit-specialization-member.cpp
index 9ddbc04..e8dc4d2 100644
--- a/test/SemaTemplate/explicit-specialization-member.cpp
+++ b/test/SemaTemplate/explicit-specialization-member.cpp
@@ -28,3 +28,32 @@
   };
   template<> struct S<int>::U { static const int n = sizeof(int); }; // expected-error {{explicit specialization of 'U' after instantiation}}
 }
+
+namespace PR18246 {
+  template<typename T>
+  class Baz {
+  public:
+    template<int N> void bar();
+  };
+
+  template<typename T>
+  template<int N>
+  void Baz<T>::bar() { // expected-note {{couldn't infer template argument 'N'}}
+  }
+
+  // FIXME: We shouldn't try to match this against a prior declaration if
+  // template parameter matching failed.
+  template<typename T>
+  void Baz<T>::bar<0>() { // expected-error {{cannot specialize a member of an unspecialized template}} \
+                          // expected-error {{no function template matches}}
+  }
+}
+
+namespace PR19340 {
+template<typename T> struct Helper {
+  template<int N> static void func(const T *m) {} // expected-note {{failed template argument deduction}}
+};
+
+template<typename T> void Helper<T>::func<2>() {} // expected-error {{cannot specialize a member}} \
+                                                  // expected-error {{no function template matches}}
+}
diff --git a/test/SemaTemplate/inject-templated-friend-post.cpp b/test/SemaTemplate/inject-templated-friend-post.cpp
index c86f718..b8b9a32 100644
--- a/test/SemaTemplate/inject-templated-friend-post.cpp
+++ b/test/SemaTemplate/inject-templated-friend-post.cpp
@@ -1,12 +1,17 @@
-// RUN: %clang %s -std=c++98 -S -emit-llvm -o - | grep -e "define linkonce_odr.*_ZlsR11std_ostreamRK8StreamerI3FooE"
-// RUN: %clang %s -std=c++98 -S -emit-llvm -o - -DPROTOTYPE | grep -e "define linkonce_odr.*_ZlsR11std_ostreamRK8StreamerI3FooE"
-// RUN: %clang %s -std=c++98 -S -emit-llvm -o - -DINSTANTIATE | grep -e "define linkonce_odr.*_ZlsR11std_ostreamRK8StreamerI3FooE"
-// RUN: %clang %s -std=c++98 -S -emit-llvm -o - -DPROTOTYPE -DINSTANTIATE | grep -e "define linkonce_odr.*_ZlsR11std_ostreamRK8StreamerI3FooE"
+// RUN: %clang_cc1 %s -std=c++98 -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -std=c++98 -triple %itanium_abi_triple -emit-llvm -o - -DPROTOTYPE | FileCheck --check-prefix=CHECK-PROTOTYPE %s
+// RUN: %clang_cc1 %s -std=c++98 -triple %itanium_abi_triple -emit-llvm -o - -DINSTANTIATE | FileCheck --check-prefix=CHECK-INSTANTIATE %s
+// RUN: %clang_cc1 %s -std=c++98 -triple %itanium_abi_triple -emit-llvm -o - -DPROTOTYPE -DINSTANTIATE | FileCheck --check-prefix=CHECK-PROTOTYPE-INSTANTIATE %s
 // RUN: %clang_cc1 %s -DREDEFINE -verify
 // RUN: %clang_cc1 %s -DPROTOTYPE -DREDEFINE -verify
 // PR8007: friend function not instantiated, reordered version.
 // Corresponds to http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38392
 
+// CHECK: define linkonce_odr{{.*}}_ZlsR11std_ostreamRK8StreamerI3FooE
+// CHECK-PROTOTYPE: define linkonce_odr{{.*}}_ZlsR11std_ostreamRK8StreamerI3FooE
+// CHECK-INSTANTIATE: define linkonce_odr{{.*}}_ZlsR11std_ostreamRK8StreamerI3FooE
+// CHECK-PROTOTYPE-INSTANTIATE: define linkonce_odr{{.*}}_ZlsR11std_ostreamRK8StreamerI3FooE
+
 struct std_ostream
 {
   int dummy;
@@ -19,7 +24,7 @@
 
 typedef struct Foo {} Foo;
 
-std_ostream& operator << (std_ostream&, const Streamer<Foo>&);
+inline std_ostream& operator << (std_ostream&, const Streamer<Foo>&);
 
 void test(const Streamer<Foo>& foo)
 {
diff --git a/test/SemaTemplate/inject-templated-friend.cpp b/test/SemaTemplate/inject-templated-friend.cpp
index 7be613b..f0f287c 100644
--- a/test/SemaTemplate/inject-templated-friend.cpp
+++ b/test/SemaTemplate/inject-templated-friend.cpp
@@ -1,7 +1,9 @@
-// RUN: %clang %s -S -emit-llvm -o - | grep -e "define linkonce_odr.*_ZlsR11std_ostreamRK8StreamerI3FooE"
+// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o - | FileCheck %s
 // RUN: %clang_cc1 %s -DREDEFINE -verify
 // PR8007: friend function not instantiated.
 
+// CHECK: define linkonce_odr{{.*}}_ZlsR11std_ostreamRK8StreamerI3FooE
+
 struct std_ostream
 {
   int dummy;
@@ -27,7 +29,7 @@
 
 typedef struct Foo {} Foo;
 
-std_ostream& operator << (std_ostream&, const Streamer<Foo>&);
+inline std_ostream& operator << (std_ostream&, const Streamer<Foo>&);
 #ifdef REDEFINE
 std_ostream& operator << (std_ostream& o, const Streamer<Foo>&) // expected-note{{is here}}
 {
diff --git a/test/SemaTemplate/instantiate-complete.cpp b/test/SemaTemplate/instantiate-complete.cpp
index 68d5ae3..a29e9d3 100644
--- a/test/SemaTemplate/instantiate-complete.cpp
+++ b/test/SemaTemplate/instantiate-complete.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple %ms_abi_triple -DMSABI -fsyntax-only -verify %s
 
 // Tests various places where requiring a complete type involves
 // instantiation of that type.
@@ -7,6 +8,9 @@
 struct X {
   X(T);
 
+#ifdef MSABI
+// expected-error@+2{{data member instantiated with function type 'long (long)'}}
+#endif
   T f; // expected-error{{data member instantiated with function type 'float (int)'}} \
        // expected-error{{data member instantiated with function type 'int (int)'}} \
        // expected-error{{data member instantiated with function type 'char (char)'}} \
@@ -40,7 +44,11 @@
 
 void test_memptr(X<long> *p1, long X<long>::*pm1,
                  X<long(long)> *p2, 
+#ifdef MSABI
+                 long (X<long(long)>::*pm2)(long)) { // expected-note{{in instantiation of template class 'X<long (long)>' requested here}}
+#else
                  long (X<long(long)>::*pm2)(long)) {
+#endif
   (void)(p1->*pm1);
 }
 
diff --git a/test/SemaTemplate/instantiate-decl-init.cpp b/test/SemaTemplate/instantiate-decl-init.cpp
index 9658fc1..f5daa79 100644
--- a/test/SemaTemplate/instantiate-decl-init.cpp
+++ b/test/SemaTemplate/instantiate-decl-init.cpp
@@ -45,3 +45,23 @@
   NonTrivial array[N];
 }
 template<> void f1<2>();
+
+namespace PR20346 {
+  struct S { short inner_s; };
+
+  struct outer_struct {
+    wchar_t arr[32];
+    S outer_s;
+  };
+
+  template <class T>
+  void OpenFileSession() {
+    // Ensure that we don't think the ImplicitValueInitExpr generated here
+    // during the initial parse only initializes the first array element!
+    outer_struct asdfasdf = {};
+  };
+
+  void foo() {
+    OpenFileSession<int>();
+  }
+}
diff --git a/test/SemaTemplate/instantiate-default-assignment-operator.cpp b/test/SemaTemplate/instantiate-default-assignment-operator.cpp
index 31cdef5..6794671 100644
--- a/test/SemaTemplate/instantiate-default-assignment-operator.cpp
+++ b/test/SemaTemplate/instantiate-default-assignment-operator.cpp
@@ -13,5 +13,5 @@
   a1 = a2;
 
   B b1, b2;
-  b1 = b2; 
+  b1 = b2;
 }
diff --git a/test/SemaTemplate/instantiate-enum.cpp b/test/SemaTemplate/instantiate-enum.cpp
index 5353a92..3da8eb4 100644
--- a/test/SemaTemplate/instantiate-enum.cpp
+++ b/test/SemaTemplate/instantiate-enum.cpp
@@ -25,3 +25,18 @@
 
   template void f<int>();
 }
+
+namespace EnumScoping {
+
+template <typename T>
+class C {
+  enum {
+    value = 42
+  };
+};
+
+void f(int i, C<int>::C c) {
+  int value;
+}
+
+}
diff --git a/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp b/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp
index 5f43ea2..a376f0e 100644
--- a/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp
+++ b/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp
@@ -1,8 +1,11 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -ftemplate-depth 16 -fcxx-exceptions -fexceptions %s
+// RUN: %clang_cc1 -fsyntax-only -verify -triple %itanium_abi_triple -std=c++11 -ftemplate-depth 16 -fcxx-exceptions -fexceptions %s
 
 // DR1330: an exception specification for a function template is only
 // instantiated when it is needed.
 
+// Note: the test is Itanium-specific because it depends on key functions in the
+// PR12763 namespace.
+
 template<typename T> void f1(T*) throw(T); // expected-error{{incomplete type 'Incomplete' is not allowed in exception specification}}
 struct Incomplete; // expected-note{{forward}}
 
diff --git a/test/SemaTemplate/instantiate-exception-spec.cpp b/test/SemaTemplate/instantiate-exception-spec.cpp
index d4f12df..993ee8d 100644
--- a/test/SemaTemplate/instantiate-exception-spec.cpp
+++ b/test/SemaTemplate/instantiate-exception-spec.cpp
@@ -1,11 +1,9 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 
-// FIXME: the "note" should be down at the call site!
-template<typename T> void f1(T*) throw(T); // expected-error{{incomplete type 'Incomplete' is not allowed in exception specification}} \
-                         // expected-note{{instantiation of}}
+template<typename T> void f1(T*) throw(T); // expected-error{{incomplete type 'Incomplete' is not allowed in exception specification}}
 struct Incomplete; // expected-note{{forward}}
 
 void test_f1(Incomplete *incomplete_p, int *int_p) {
   f1(int_p);
-  f1(incomplete_p); 
+  f1(incomplete_p); // expected-note{{instantiation of}}
 }
diff --git a/test/SemaTemplate/instantiate-function-2.cpp b/test/SemaTemplate/instantiate-function-2.cpp
index 19a8b61..f5089c9 100644
--- a/test/SemaTemplate/instantiate-function-2.cpp
+++ b/test/SemaTemplate/instantiate-function-2.cpp
@@ -64,3 +64,28 @@
     (f)(17);
   }
 }
+
+namespace rdar15464547 {
+  class A {
+    A();
+  };
+
+  template <typename R> class B {
+  public:
+    static void meth1();
+    static void meth2();
+  };
+
+  A::A() {
+    extern int compile_time_assert_failed;
+    B<int>::meth2();
+  }
+
+  template <typename R> void B<R>::meth1() {
+    extern int compile_time_assert_failed;
+  }
+
+  template <typename R> void B<R>::meth2() {
+    extern int compile_time_assert_failed;
+  }
+}
diff --git a/test/SemaTemplate/instantiate-function-params.cpp b/test/SemaTemplate/instantiate-function-params.cpp
index 5bfae53..556a818 100644
--- a/test/SemaTemplate/instantiate-function-params.cpp
+++ b/test/SemaTemplate/instantiate-function-params.cpp
@@ -7,12 +7,12 @@
 };
 template <class Model, void (Model::*)()> struct wrap_constraints { };
 template <class Model> 
-inline char has_constraints_(Model* ,  // expected-note 2{{while substituting deduced template arguments into function template 'has_constraints_' [with }} \
-                             // expected-note 3{{candidate template ignored}}
+inline char has_constraints_(Model* , // expected-note 3{{candidate template ignored}}
                                wrap_constraints<Model,&Model::constraints>* = 0); // expected-note 2{{in instantiation}}
 
 template <class Model> struct not_satisfied {
-  static const bool value = sizeof( has_constraints_((Model*)0)  == 1); // expected-error 3{{no matching function}}
+  static const bool value = sizeof( has_constraints_((Model*)0)  == 1); // expected-error 3{{no matching function}} \
+  // expected-note 2{{while substituting deduced template arguments into function template 'has_constraints_' [with }}
 };
 template <class ModelFn> struct requirement_;
 template <void(*)()> struct instantiate {
diff --git a/test/SemaTemplate/instantiate-local-class.cpp b/test/SemaTemplate/instantiate-local-class.cpp
index c151fbb..c9897b9 100644
--- a/test/SemaTemplate/instantiate-local-class.cpp
+++ b/test/SemaTemplate/instantiate-local-class.cpp
@@ -1,5 +1,4 @@
-// RUN: %clang_cc1 -verify %s
-// expected-no-diagnostics
+// RUN: %clang_cc1 -verify -std=c++11 %s
 template<typename T>
 void f0() {
   struct X;
@@ -66,3 +65,132 @@
 
   template void foo<Y>();
 }
+
+namespace TemplatePacksAndLambdas {
+  template <typename ...T> int g(T...);
+  struct S {
+    template <typename ...T> static void f(int f = g([]{ static T t; return ++t; }()...)) {}
+  };
+  void h() { S::f<int, int, int>(); }
+}
+
+namespace PR9685 {
+  template <class Thing> void forEach(Thing t) { t.func(); }
+
+  template <typename T> void doIt() {
+    struct Functor {
+      void func() { (void)i; }
+      int i;
+    };
+
+    forEach(Functor());
+  }
+
+  void call() {
+    doIt<int>();
+  }
+}
+
+namespace PR12702 {
+  struct S {
+    template <typename F> bool apply(F f) { return f(); }
+  };
+
+  template <typename> struct T {
+    void foo() {
+      struct F {
+        int x;
+
+        bool operator()() { return x == 0; }
+      };
+
+      S().apply(F());
+    }
+  };
+
+  void call() { T<int>().foo(); }
+}
+
+namespace PR17139 {
+  template <class T> void foo(const T &t) { t.foo(); }
+
+  template <class F> void bar(F *f) {
+    struct B {
+      F *fn;
+      void foo() const { fn(); }
+    } b = { f };
+    foo(b);
+  }
+
+  void go() {}
+
+  void test() { bar(go); }
+}
+
+namespace PR17740 {
+class C {
+public:
+  template <typename T> static void foo(T function);
+  template <typename T> static void bar(T function);
+  template <typename T> static void func(T function);
+};
+
+template <typename T> void C::foo(T function) { function(); }
+
+template <typename T> void C::bar(T function) {
+  foo([&function]() { function(); });
+}
+
+template <typename T> void C::func(T function) {
+  struct Struct {
+    T mFunction;
+
+    Struct(T function) : mFunction(function) {};
+
+    void operator()() {
+      mFunction();
+    };
+  };
+
+  bar(Struct(function));
+}
+
+void call() {
+  C::func([]() {});
+}
+}
+
+namespace PR14373 {
+  struct function {
+    template <typename _Functor> function(_Functor __f) { __f(); }
+  };
+  template <typename Func> function exec_func(Func f) {
+    struct functor {
+      functor(Func f) : func(f) {}
+      void operator()() const { func(); }
+      Func func;
+    };
+    return functor(f);
+  }
+  struct Type {
+    void operator()() const {}
+  };
+  int call() {
+    exec_func(Type());
+    return 0;
+  }
+}
+
+namespace PR18907 {
+template <typename>
+class C : public C<int> {}; // expected-error{{within its own definition}}
+
+template <typename X>
+void F() {
+  struct A : C<X> {};
+}
+
+struct B {
+  void f() { F<int>(); }
+};
+}
diff --git a/test/SemaTemplate/instantiate-member-pointers.cpp b/test/SemaTemplate/instantiate-member-pointers.cpp
index 0db90e3..4757870 100644
--- a/test/SemaTemplate/instantiate-member-pointers.cpp
+++ b/test/SemaTemplate/instantiate-member-pointers.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
 struct Y {
   int x;
 };
@@ -65,3 +65,10 @@
   }
   S<int> s; 
 }
+
+namespace PR18192 {
+  struct A { struct { int n; }; };
+  template<int A::*> struct X {};
+  constexpr int A::*p = &A::n;
+  X<p> x; // expected-error{{not a pointer to member constant}}
+}
diff --git a/test/SemaTemplate/instantiate-method.cpp b/test/SemaTemplate/instantiate-method.cpp
index 5e9da3f..58cb897 100644
--- a/test/SemaTemplate/instantiate-method.cpp
+++ b/test/SemaTemplate/instantiate-method.cpp
@@ -178,7 +178,7 @@
 namespace SameSignatureAfterInstantiation {
   template<typename T> struct S {
     void f(T *); // expected-note {{previous}}
-    void f(const T*); // expected-error {{multiple overloads of 'f' instantiate to the same signature 'void (const int *)'}}
+    void f(const T*); // expected-error-re {{multiple overloads of 'f' instantiate to the same signature 'void (const int *){{( __attribute__\(\(thiscall\)\))?}}'}}
   };
   S<const int> s; // expected-note {{instantiation}}
 }
diff --git a/test/SemaTemplate/instantiate-var-template.cpp b/test/SemaTemplate/instantiate-var-template.cpp
new file mode 100644
index 0000000..bd7c433
--- /dev/null
+++ b/test/SemaTemplate/instantiate-var-template.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -verify -std=c++1y %s
+
+namespace PR17846 {
+  template <typename T> constexpr T pi = T(3.14);
+  template <typename T> constexpr T tau = 2 * pi<T>;
+  constexpr double tau_double = tau<double>;
+  static_assert(tau_double == 6.28, "");
+}
+
+namespace PR17848 {
+  template<typename T> constexpr T var = 12345;
+  template<typename T> constexpr T f() { return var<T>; }
+  constexpr int k = f<int>();
+  static_assert(k == 12345, "");
+}
+
+namespace NonDependent {
+  template<typename T> constexpr T a = 0;
+  template<typename T> constexpr T b = a<int>;
+  static_assert(b<int> == 0, "");
+}
+
+namespace InstantiationDependent {
+  int f(int);
+  void f(char);
+
+  template<int> constexpr int a = 1;
+  template<typename T> constexpr T b = a<sizeof(sizeof(f(T())))>; // expected-error {{invalid application of 'sizeof' to an incomplete type 'void'}}
+
+  static_assert(b<int> == 1, "");
+  static_assert(b<char> == 1, ""); // expected-note {{in instantiation of}} expected-error {{not an integral constant}}
+
+  template<typename T> void f() {
+    static_assert(a<sizeof(sizeof(f(T())))> == 0, ""); // expected-error {{static_assert failed}}
+  }
+}
diff --git a/test/SemaTemplate/instantiation-backtrace.cpp b/test/SemaTemplate/instantiation-backtrace.cpp
index f640836..39dfb0b 100644
--- a/test/SemaTemplate/instantiation-backtrace.cpp
+++ b/test/SemaTemplate/instantiation-backtrace.cpp
@@ -39,13 +39,13 @@
   template <class T1, class T2>
     typename ResultTy<T2>::error Deduce( void (T1::*member)(T2) ) {} // \
     // expected-note {{instantiation of template class 'PR13365::ResultTy<int &>'}} \
-    // expected-note {{substituting deduced template arguments into function template 'Deduce' [with T1 = PR13365::Cls, T2 = int &]}} \
     // expected-note {{substitution failure [with T1 = PR13365::Cls, T2 = int &]}}
 
   struct Cls {
     void method(int&);
   };
   void test() {
-    Deduce(&Cls::method); // expected-error {{no matching function}}
+    Deduce(&Cls::method); // expected-error {{no matching function}} \
+                          // expected-note {{substituting deduced template arguments into function template 'Deduce' [with T1 = PR13365::Cls, T2 = int &]}}
   }
 }
diff --git a/test/SemaTemplate/instantiation-depth-subst-2.cpp b/test/SemaTemplate/instantiation-depth-subst-2.cpp
index ef2a5c7..c9df093 100644
--- a/test/SemaTemplate/instantiation-depth-subst-2.cpp
+++ b/test/SemaTemplate/instantiation-depth-subst-2.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -verify %s -ftemplate-depth 2
 
 template<int N> struct S { };
-template<typename T> S<T() + T()> operator+(T, T); // expected-error {{instantiation exceeded maximum depth}} expected-note 3{{while substituting}}
+template<typename T> S<T() + T()> operator+(T, T); // expected-error {{instantiation exceeded maximum depth}} expected-note 2{{while substituting}}
 S<0> s;
-int k = s + s;
+int k = s + s; // expected-note {{while substituting}}
diff --git a/test/SemaTemplate/instantiation-depth-subst.cpp b/test/SemaTemplate/instantiation-depth-subst.cpp
index 06795f9..2a3e422 100644
--- a/test/SemaTemplate/instantiation-depth-subst.cpp
+++ b/test/SemaTemplate/instantiation-depth-subst.cpp
@@ -3,7 +3,7 @@
 // PR9793
 template<typename T> auto f(T t) -> decltype(f(t)); // \
 // expected-error {{recursive template instantiation exceeded maximum depth of 2}} \
-// expected-note 3 {{while substituting}}
+// expected-note 2 {{while substituting}}
 
 struct S {};
-int k = f(S{});
+int k = f(S{}); // expected-note {{while substituting}}
diff --git a/test/SemaTemplate/instantiation-order.cpp b/test/SemaTemplate/instantiation-order.cpp
index e058a5b..9cac256 100644
--- a/test/SemaTemplate/instantiation-order.cpp
+++ b/test/SemaTemplate/instantiation-order.cpp
@@ -5,11 +5,11 @@
 template <class T> struct A { using X = typename T::X; }; // expected-error {{no members}}
 template <class T> typename T::X f(typename A<T>::X);
 template <class T> void f(...) {}
-template <class T> auto g(typename A<T>::X) -> typename T::X; // expected-note {{here}} expected-note {{substituting}}
+template <class T> auto g(typename A<T>::X) -> typename T::X; // expected-note {{here}}
 template <class T> void g(...) {}
 
 void h()
 {
   f<int>(0); // ok, SFINAE in return type
-  g<int>(0); // not ok, substitution inside A<int> is a hard error
+  g<int>(0); // not ok, substitution inside A<int> is a hard error // expected-note {{substituting}}
 }
diff --git a/test/SemaTemplate/ms-class-specialization-class-scope.cpp b/test/SemaTemplate/ms-class-specialization-class-scope.cpp
new file mode 100644
index 0000000..3ebb1c9
--- /dev/null
+++ b/test/SemaTemplate/ms-class-specialization-class-scope.cpp
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify %s -Wno-microsoft
+// RUN: %clang_cc1 -fms-extensions -fdelayed-template-parsing -fsyntax-only -verify %s -Wno-microsoft
+
+class A {
+public:
+  template<typename T> struct X { typedef int x; };
+
+  X<int>::x a; // expected-note {{implicit instantiation first required here}}
+
+  template<> struct X<int>; // expected-error {{explicit specialization of 'A::X<int>' after instantiation}}
+  template<> struct X<char>; // expected-note {{forward declaration}}
+
+  X<char>::x b; // expected-error {{incomplete type 'A::X<char>' named in nested name specifier}}
+
+  template<> struct X<double> {
+    typedef int y;
+  };
+
+  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>'}}
+};
+
+A::X<void>::x axv;
+A::X<float>::x axf; // expected-error {{no type named 'x'}}
+
+template<class T> class B {
+public:
+  template<typename U> struct X { typedef int x; };
+
+  typename X<int>::x a; // expected-note {{implicit instantiation first required here}}
+
+  template<> struct X<int>; // expected-error {{explicit specialization of 'X<int>' after instantiation}}
+  template<> struct X<char>; // expected-note {{forward declaration}}
+
+  typename X<char>::x b; // expected-error {{incomplete type 'B<float>::X<char>' named in nested name specifier}}
+
+  template<> struct X<double> {
+    typedef int y;
+  };
+
+  typename X<double>::y c;
+
+  template<> struct X<float> {}; // expected-note {{previous definition is here}}
+  template<> struct X<T> {}; // expected-error {{redefinition of 'X<float>'}}
+};
+
+B<float> b; // expected-note {{in instantiation of}}
diff --git a/test/SemaTemplate/ms-class-specialization-duplicate.cpp b/test/SemaTemplate/ms-class-specialization-duplicate.cpp
new file mode 100644
index 0000000..183fdfc
--- /dev/null
+++ b/test/SemaTemplate/ms-class-specialization-duplicate.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fms-compatibility -fdelayed-template-parsing -fsyntax-only -verify %s
+
+template <typename T>
+class A {
+};
+typedef int TInt;
+
+template class A<int>;  // expected-note {{previous explicit instantiation is here}}
+template class A<TInt>; // expected-warning {{duplicate explicit instantiation of 'A<int>' ignored as a Microsoft extension}}
diff --git a/test/SemaTemplate/ms-delayed-default-template-args.cpp b/test/SemaTemplate/ms-delayed-default-template-args.cpp
new file mode 100644
index 0000000..ca9ddb0
--- /dev/null
+++ b/test/SemaTemplate/ms-delayed-default-template-args.cpp
@@ -0,0 +1,96 @@
+// RUN: %clang_cc1 -fms-compatibility -std=c++11 %s -verify
+
+// MSVC should compile this file without errors.
+
+namespace test_basic {
+template <typename T = Baz> // expected-warning {{using the undeclared type 'Baz' as a default template argument is a Microsoft extension}}
+struct Foo { T x; };
+typedef int Baz;
+template struct Foo<>;
+}
+
+namespace test_namespace {
+namespace nested {
+template <typename T = Baz> // expected-warning {{using the undeclared type 'Baz' as a default template argument is a Microsoft extension}}
+struct Foo {
+  static_assert(sizeof(T) == 4, "should get int, not double");
+};
+typedef int Baz;
+}
+typedef double Baz;
+template struct nested::Foo<>;
+}
+
+namespace test_inner_class_template {
+struct Outer {
+  template <typename T = Baz> // expected-warning {{using the undeclared type 'Baz' as a default template argument is a Microsoft extension}}
+  struct Foo {
+    static_assert(sizeof(T) == 4, "should get int, not double");
+  };
+  typedef int Baz;
+};
+typedef double Baz;
+template struct Outer::Foo<>;
+}
+
+namespace test_nontype_param {
+template <typename T> struct Bar { T x; };
+typedef int Qux;
+template <Bar<Qux> *P>
+struct Foo {
+};
+Bar<int> g;
+template struct Foo<&g>;
+}
+
+// MSVC accepts this, but Clang doesn't.
+namespace test_template_instantiation_arg {
+template <typename T> struct Bar { T x; };
+template <typename T = Bar<Weber>>  // expected-error {{use of undeclared identifier 'Weber'}}
+struct Foo {
+  static_assert(sizeof(T) == 4, "Bar should have gotten int");
+  // FIXME: These diagnostics are bad.
+}; // expected-error {{expected ',' or '>' in template-parameter-list}}
+// expected-warning@-1 {{does not declare anything}}
+typedef int Weber;
+}
+
+#ifdef __clang__
+// These are negative test cases that MSVC doesn't compile either.  Try to use
+// unique undeclared identifiers so typo correction doesn't find types declared
+// above.
+
+namespace test_undeclared_nontype_parm_type {
+template <Zargon N> // expected-error {{unknown type name 'Zargon'}}
+struct Foo { int x[N]; };
+typedef int Zargon;
+template struct Foo<4>;
+}
+
+namespace test_undeclared_nontype_parm_type_no_name {
+template <typename T, Asdf> // expected-error {{unknown type name 'Asdf'}}
+struct Foo { T x; };
+template struct Foo<int, 0>;
+}
+
+namespace test_undeclared_type_arg {
+template <typename T>
+struct Foo { T x; };
+template struct Foo<Yodel>; // expected-error {{use of undeclared identifier 'Yodel'}}
+}
+
+namespace test_undeclared_nontype_parm_arg {
+// Bury an undeclared type as a template argument to the type of a non-type
+// template parameter.
+template <typename T> struct Bar { T x; };
+
+template <Bar<Xylophone> *P> // expected-error {{use of undeclared identifier 'Xylophone'}}
+// expected-note@-1 {{template parameter is declared here}}
+struct Foo { };
+
+typedef int Xylophone;
+Bar<Xylophone> g;
+template struct Foo<&g>; // expected-error {{cannot be converted}}
+}
+
+#endif
diff --git a/test/SemaTemplate/ms-function-specialization-class-scope.cpp b/test/SemaTemplate/ms-function-specialization-class-scope.cpp
index 9efb02c..5da0083 100644
--- a/test/SemaTemplate/ms-function-specialization-class-scope.cpp
+++ b/test/SemaTemplate/ms-function-specialization-class-scope.cpp
@@ -1,93 +1,77 @@
 // RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify %s
 // RUN: %clang_cc1 -fms-extensions -fdelayed-template-parsing -fsyntax-only -verify %s
 
-
 class A {
 public:
-	template <class U>
-    A(U p) {
-	}
-	template <>
-    A(int p) { // expected-warning{{explicit specialization of 'A' within class scope is a Microsoft extension}}
-	}
-	
-	template <class U>
-    void f(U p) { 
-	}
-
-	template <>
-    void f(int p) { // expected-warning{{explicit specialization of 'f' within class scope is a Microsoft extension}}
-	}
-
-	void f(int p) { 
-    }
-};
-
-void test1()
-{
-   A a(3);
-   char* b ;
-   a.f(b);
-   a.f<int>(99);
-   a.f(100);
-}
-
-
-
-
-template <class T>
-class B {
-public:
-	template <class U>
-    B(U p) { 
-	}
-	template <>
-    B(int p) { // expected-warning{{explicit specialization of 'B<T>' within class scope is a Microsoft extension}}
-	}
-	
-	template <class U>
-    void f(U p) {
-	  T y = 9;
-	}
-
-
-    template <>
-    void f(int p) { // expected-warning{{explicit specialization of 'f' within class scope is a Microsoft extension}}
-	  T a = 3;
-	}
-
-	void f(int p) { 
- 	  T a = 3;
-    }
-};
-
-void test2()
-{
-   B<char> b(3);
-   char* ptr;
-   b.f(ptr);
-   b.f<int>(99);
-   b.f(100);
-}
-
-
-namespace PR12709 {
-
-template<class T>
-class TemplateClass {
-  void member_function() {
-    specialized_member_template<false>();
+  template<class U> A(U p) {}
+  template<> A(int p) {
+    // expected-warning@-1 {{explicit specialization of 'A' within class scope is a Microsoft extension}}
   }
 
-  template<bool b>
-  void specialized_member_template() {}
+  template<class U> void f(U p) {}
 
-  template<>
-  void specialized_member_template<false>() {}  // expected-warning{{explicit specialization of 'specialized_member_template' within class scope is a Microsoft extension}}
+  template<> void f(int p) {
+    // expected-warning@-1 {{explicit specialization of 'f' within class scope is a Microsoft extension}}
+  }
+
+  void f(int p) {}
 };
 
-void f() {
-  TemplateClass<int> t;
+void test1() {
+  A a(3);
+  char *b;
+  a.f(b);
+  a.f<int>(99);
+  a.f(100);
 }
 
+template<class T> class B {
+public:
+  template<class U> B(U p) {}
+  template<> B(int p) {
+    // expected-warning@-1 {{explicit specialization of 'B<T>' within class scope is a Microsoft extension}}
+  }
+
+  template<class U> void f(U p) { T y = 9; }
+
+  template<> void f(int p) {
+    // expected-warning@-1 {{explicit specialization of 'f' within class scope is a Microsoft extension}}
+    T a = 3;
+  }
+
+  void f(int p) { T a = 3; }
+};
+
+void test2() {
+  B<char> b(3);
+  char *ptr;
+  b.f(ptr);
+  b.f<int>(99);
+  b.f(100);
+}
+
+namespace PR12709 {
+  template<class T> class TemplateClass {
+    void member_function() { specialized_member_template<false>(); }
+
+    template<bool b> void specialized_member_template() {}
+
+    template<> void specialized_member_template<false>() {
+      // expected-warning@-1 {{explicit specialization of 'specialized_member_template' within class scope is a Microsoft extension}}
+    }
+  };
+
+  void f() { TemplateClass<int> t; }
+}
+
+namespace Duplicates {
+  template<typename T> struct A {
+    template<typename U> void f();
+    template<> void f<int>() {} // expected-warning {{Microsoft extension}}
+    template<> void f<T>() {} // expected-warning {{Microsoft extension}}
+  };
+
+  // FIXME: We should diagnose the duplicate explicit specialization definitions
+  // here.
+  template struct A<int>;
 }
diff --git a/test/SemaTemplate/ms-if-exists.cpp b/test/SemaTemplate/ms-if-exists.cpp
index 04f4a63..9b95bba 100644
--- a/test/SemaTemplate/ms-if-exists.cpp
+++ b/test/SemaTemplate/ms-if-exists.cpp
@@ -48,11 +48,11 @@
     { }
   }
 
-  int array2[] = {

-    0, 

-    __if_exists(T::bar) {2, }// expected-warning{{dependent __if_exists declarations are ignored}}

-    3

-  };

+  int array2[] = {
+    0, 
+    __if_exists(T::bar) {2, }// expected-warning{{dependent __if_exists declarations are ignored}}
+    3
+  };
 }
 
 template void f(HasFoo); // expected-note{{in instantiation of function template specialization 'f<HasFoo>' requested here}}
diff --git a/test/SemaTemplate/ms-lookup-template-base-classes.cpp b/test/SemaTemplate/ms-lookup-template-base-classes.cpp
index 72ce056..40f73c0 100644
--- a/test/SemaTemplate/ms-lookup-template-base-classes.cpp
+++ b/test/SemaTemplate/ms-lookup-template-base-classes.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fms-compatibility -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++1y -fms-compatibility -fno-spell-checking -fsyntax-only -verify %s
 
 
 template <class T>
@@ -64,7 +64,7 @@
 class B : public A<T> {
 public:
   void f() {
-    var = 3;
+    var = 3; // expected-warning {{use of undeclared identifier 'var'; unqualified lookup into dependent bases of class template 'B' is a Microsoft extension}}
   }
 };
 
@@ -160,7 +160,7 @@
 class A : public T {
 public:
   void f(int hWnd) {
-    m_hWnd = 1;
+    m_hWnd = 1; // expected-warning {{use of undeclared identifier 'm_hWnd'; unqualified lookup into dependent bases of class template 'A' is a Microsoft extension}}
   }
 };
 
@@ -176,7 +176,7 @@
 template <class T>
 class Base {
  public:
-  bool base_fun(void* p) { return false; }  // expected-note {{must qualify identifier to find this declaration in dependent base clas}}
+  bool base_fun(void* p) { return false; }  // expected-note {{must qualify identifier to find this declaration in dependent base class}}
   operator T*() const { return 0; }
 };
 
@@ -204,25 +204,27 @@
   static int sa;
 };
 template <typename T> struct B : T {
-  int     foo() { return a; }
-  int    *bar() { return &a; }
+  int     foo() { return a; }           // expected-warning {{lookup into dependent bases}}
+  int    *bar() { return &a; }          // expected-warning {{lookup into dependent bases}}
   int     baz() { return T::a; }
   int T::*qux() { return &T::a; }
   static int T::*stuff() { return &T::a; }
   static int stuff1() { return T::sa; }
   static int *stuff2() { return &T::sa; }
+  static int stuff3() { return sa; }    // expected-warning {{lookup into dependent bases}}
+  static int *stuff4() { return &sa; }  // expected-warning {{lookup into dependent bases}}
 };
 
 template <typename T> struct C : T {
-  int     foo() { return b; }      // expected-error {{no member named 'b' in 'PR16014::C<PR16014::A>'}}
-  int    *bar() { return &b; }     // expected-error {{no member named 'b' in 'PR16014::C<PR16014::A>'}}
+  int     foo() { return b; }      // expected-error {{no member named 'b' in 'PR16014::C<PR16014::A>'}} expected-warning {{lookup into dependent bases}}
+  int    *bar() { return &b; }     // expected-error {{no member named 'b' in 'PR16014::C<PR16014::A>'}} expected-warning {{lookup into dependent bases}}
   int     baz() { return T::b; }   // expected-error {{no member named 'b' in 'PR16014::A'}}
   int T::*qux() { return &T::b; }  // expected-error {{no member named 'b' in 'PR16014::A'}}
   int T::*fuz() { return &U::a; }  // expected-error {{use of undeclared identifier 'U'}}
 };
 
 template struct B<A>;
-template struct C<A>;  // expected-note-re 1+ {{in instantiation of member function 'PR16014::C<PR16014::A>::.*' requested here}}
+template struct C<A>;  // expected-note-re 1+ {{in instantiation of member function 'PR16014::C<PR16014::A>::{{.*}}' requested here}}
 
 template <typename T> struct D : T {
   struct Inner {
@@ -236,3 +238,225 @@
 template struct D<A>;
 
 }
+
+namespace PR19233 {
+template <class T>
+struct A : T {
+  void foo() {
+    ::undef(); // expected-error {{no member named 'undef' in the global namespace}}
+  }
+  void bar() {
+    ::UndefClass::undef(); // expected-error {{no member named 'UndefClass' in the global namespace}}
+  }
+  void baz() {
+    B::qux(); // expected-error {{use of undeclared identifier 'B'}}
+  }
+};
+
+struct B { void qux(); };
+struct C : B { };
+template struct A<C>; // No error!  B is a base of A<C>, and qux is available.
+
+struct D { };
+template struct A<D>; // expected-note {{in instantiation of member function 'PR19233::A<PR19233::D>::baz' requested here}}
+
+}
+
+namespace nonmethod_missing_this {
+template <typename T> struct Base { int y = 42; };
+template <typename T> struct Derived : Base<T> {
+  int x = y; // expected-warning {{lookup into dependent bases}}
+  auto foo(int j) -> decltype(y * j) { // expected-warning {{lookup into dependent bases}}
+    return y * j; // expected-warning {{lookup into dependent bases}}
+  }
+  int bar() {
+    return [&] { return y; }(); // expected-warning {{lookup into dependent bases}}
+  }
+};
+template struct Derived<int>;
+}
+
+namespace typedef_in_base {
+template <typename T> struct A { typedef T NameFromBase; };
+template <typename T> struct B : A<T> {
+  NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}}
+};
+static_assert(sizeof(B<int>) == 4, "");
+}
+
+namespace struct_in_base {
+template <typename T> struct A { struct NameFromBase {}; };
+template <typename T> struct B : A<T> {
+  NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}}
+};
+static_assert(sizeof(B<int>) == 1, "");
+}
+
+namespace enum_in_base {
+template <typename T> struct A { enum NameFromBase { X }; };
+template <typename T> struct B : A<T> {
+  NameFromBase m; // expected-warning {{found via unqualified lookup into dependent bases}}
+};
+static_assert(sizeof(B<int>) == sizeof(A<int>::NameFromBase), "");
+}
+
+namespace two_types_in_base {
+template <typename T> struct A { typedef T NameFromBase; };
+template <typename T> struct B { struct NameFromBase { T m; }; };
+template <typename T> struct C : A<T>, B<T> {
+  NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}}
+};
+static_assert(sizeof(C<int>) == 4, "");
+}
+
+namespace type_and_decl_in_base {
+template <typename T> struct A { typedef T NameFromBase; };
+template <typename T> struct B { static const T NameFromBase = 42; };
+template <typename T> struct C : A<T>, B<T> {
+  NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}}
+};
+}
+
+namespace classify_type_from_base {
+template <typename T> struct A { struct NameFromBase {}; };
+template <typename T> struct B : A<T> {
+  A<NameFromBase> m; // expected-warning {{found via unqualified lookup into dependent bases}}
+};
+}
+
+namespace classify_nontype_from_base {
+// MSVC does not do lookup of non-type declarations from dependent template base
+// classes.  The extra lookup only applies to types.
+template <typename T> struct A { void NameFromBase() {} };
+template <void (*F)()> struct B { };
+template <typename T> struct C : A<T> {
+  B<C::NameFromBase> a; // correct
+  B<NameFromBase> b; // expected-error {{use of undeclared identifier 'NameFromBase'}}
+};
+}
+
+namespace template_in_base {
+template <typename T> struct A {
+  template <typename U> struct NameFromBase { U x; };
+};
+template <typename T> struct B : A<T> {
+  // Correct form.
+  typename B::template NameFromBase<T> m;
+};
+template <typename T> struct C : A<T> {
+  // Incorrect form.
+  NameFromBase<T> m; // expected-error {{unknown type name 'NameFromBase'}}
+  //expected-error@-1 {{expected member name or ';' after declaration specifiers}}
+};
+}
+
+namespace type_in_inner_class_in_base {
+template <typename T>
+struct A {
+  struct B { typedef T NameFromBase; };
+};
+template <typename T>
+struct C : A<T>::B { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}}
+}
+
+namespace type_in_inner_template_class_in_base {
+template <typename T>
+struct A {
+  template <typename U> struct B { typedef U InnerType; };
+};
+template <typename T>
+struct C : A<T>::template B<T> {
+  NameFromBase m; // expected-error {{unknown type name 'NameFromBase'}}
+};
+}
+
+namespace have_nondependent_base {
+template <typename T>
+struct A {
+  // Nothing, lookup should fail.
+};
+template <typename T>
+struct B : A<T> { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}}
+struct C : A<int> { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}}
+}
+
+namespace type_in_base_of_dependent_base {
+struct A { typedef int NameFromBase; };
+template <typename T>
+struct B : A {};
+// FIXME: MSVC accepts this.
+template <typename T>
+struct C : B<T> { NameFromBase m; }; // expected-error {{unknown type name 'NameFromBase'}}
+}
+
+namespace lookup_in_function_contexts {
+template <typename T> struct A { typedef T NameFromBase; };
+template <typename T>
+struct B : A<T> {
+  // expected-warning@+1 {{lookup into dependent bases}}
+  static auto lateSpecifiedFunc() -> decltype(NameFromBase()) {
+    return {};
+  }
+
+  static void memberFunc() {
+    NameFromBase x; // expected-warning {{lookup into dependent bases}}
+  }
+
+  static void funcLocalClass() {
+    struct X {
+      NameFromBase x; // expected-warning {{lookup into dependent bases}}
+    } y;
+  }
+
+  void localClassMethod() {
+    struct X {
+      void bar() {
+        NameFromBase m; // expected-warning {{lookup into dependent bases}}
+      }
+    } x;
+    x.bar();
+  }
+
+  static void funcLambda() {
+    auto l = []() {
+      NameFromBase x; // expected-warning {{lookup into dependent bases}}
+    };
+    l();
+  }
+
+  static constexpr int constexprFunc() {
+    NameFromBase x = {}; // expected-warning {{lookup into dependent bases}}
+    return sizeof(x);
+  }
+
+  static auto autoFunc() {
+    NameFromBase x; // expected-warning {{lookup into dependent bases}}
+    return x;
+  }
+};
+
+// Force us to parse the methods.
+template struct B<int>;
+}
+
+namespace function_template_deduction {
+// Overloaded function templates.
+template <int N> int f() { return N; }
+template <typename T> int f() { return sizeof(T); }
+
+// Dependent base class with type.
+template <typename T>
+struct A { typedef T NameFromBase; };
+template <typename T>
+struct B : A<T> {
+  // expected-warning@+1 {{found via unqualified lookup into dependent bases}}
+  int x = f<NameFromBase>();
+};
+
+// Dependent base class with enum.
+template <typename T> struct C { enum { NameFromBase = 4 }; };
+template <typename T> struct D : C<T> {
+  // expected-warning@+1 {{use of undeclared identifier 'NameFromBase'; unqualified lookup into dependent bases}}
+  int x = f<NameFromBase>();
+};
+}
diff --git a/test/SemaTemplate/ms-sizeof-missing-typename.cpp b/test/SemaTemplate/ms-sizeof-missing-typename.cpp
new file mode 100644
index 0000000..ff8984f
--- /dev/null
+++ b/test/SemaTemplate/ms-sizeof-missing-typename.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -std=c++11 -fms-compatibility -fsyntax-only -verify %s
+
+// If we were even more clever, we'd tell the user to use one set of parens to
+// get the size of this type, so they don't get errors after inserting typename.
+
+namespace basic {
+template <typename T> int type_f() { return sizeof T::type; }  // expected-error {{missing 'typename' prior to dependent type name 'X::type'}}
+template <typename T> int type_g() { return sizeof(T::type); }  // expected-warning {{missing 'typename' prior to dependent type name 'X::type'}}
+template <typename T> int type_h() { return sizeof((T::type)); }  // expected-error {{missing 'typename' prior to dependent type name 'X::type'}}
+template <typename T> int value_f() { return sizeof T::not_a_type; }
+template <typename T> int value_g() { return sizeof(T::not_a_type); }
+template <typename T> int value_h() { return sizeof((T::not_a_type)); }
+struct X {
+  typedef int type;
+  static const int not_a_type;
+};
+int bar() {
+  return
+      type_f<X>() + // expected-note-re {{in instantiation {{.*}} requested here}}
+      type_g<X>() + // expected-note-re {{in instantiation {{.*}} requested here}}
+      type_h<X>() + // expected-note-re {{in instantiation {{.*}} requested here}}
+      value_f<X>() +
+      value_f<X>() +
+      value_f<X>();
+}
+}
+
+namespace nested_sizeof {
+template <typename T>
+struct Foo {
+  enum {
+    // expected-warning@+2 {{use 'template' keyword to treat 'InnerTemplate' as a dependent template name}}
+    // expected-warning@+1 {{missing 'typename' prior to dependent type name 'Bar::InnerType'}}
+    x1 = sizeof(typename T::/*template*/ InnerTemplate<sizeof(/*typename*/ T::InnerType)>),
+    // expected-warning@+1 {{missing 'typename' prior to dependent type name 'Bar::InnerType'}}
+    x2 = sizeof(typename T::template InnerTemplate<sizeof(/*typename*/ T::InnerType)>),
+    // expected-warning@+1 {{use 'template' keyword to treat 'InnerTemplate' as a dependent template name}}
+    y1 = sizeof(typename T::/*template*/ InnerTemplate<sizeof(T::InnerVar)>),
+    y2 = sizeof(typename T::template InnerTemplate<sizeof(T::InnerVar)>),
+    z = sizeof(T::template InnerTemplate<sizeof(T::InnerVar)>::x),
+  };
+};
+struct Bar {
+  template <int N>
+  struct InnerTemplate { int x[N]; };
+  typedef double InnerType;
+  static const int InnerVar = 42;
+};
+template struct Foo<Bar>; // expected-note-re {{in instantiation {{.*}} requested here}}
+}
+
+namespace ambiguous_missing_parens {
+// expected-error@+1 {{'Q::U' instantiated to a class template, not a function template}}
+template <typename T> void f() { int a = sizeof T::template U<0> + 4; }
+struct Q {
+  // expected-error@+1 {{class template declared here}}
+  template <int> struct U {};
+};
+// expected-note-re@+1 {{in instantiation {{.*}} requested here}}
+template void f<Q>();
+}
diff --git a/test/SemaTemplate/operator-template.cpp b/test/SemaTemplate/operator-template.cpp
index 30d6ccf..4166250 100644
--- a/test/SemaTemplate/operator-template.cpp
+++ b/test/SemaTemplate/operator-template.cpp
@@ -12,7 +12,6 @@
 template<class X>struct B{typedef X Y;};
 template<class X>bool operator==(B<X>*,typename B<X>::Y); // \
 // expected-error{{overloaded 'operator==' must have at least one parameter of class or enumeration type}} \
-// expected-note{{in instantiation of function template specialization}} \
 // expected-note{{candidate template ignored: substitution failure [with X = int]}}
-int a(B<int> x) { return operator==(&x,1); } // expected-error{{no matching function for call to 'operator=='}}
-
+int a(B<int> x) { return operator==(&x,1); } // expected-error{{no matching function for call to 'operator=='}} \
+// expected-note{{in instantiation of function template specialization}}
diff --git a/test/SemaTemplate/pack-deduction.cpp b/test/SemaTemplate/pack-deduction.cpp
new file mode 100644
index 0000000..f3f969e
--- /dev/null
+++ b/test/SemaTemplate/pack-deduction.cpp
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+template<typename ...T> struct X {};
+
+template<typename T, typename U> struct P {};
+
+namespace Nested {
+  template<typename ...T> int f1(X<T, T...>... a); // expected-note +{{conflicting types for parameter 'T'}}
+  template<typename ...T> int f2(P<X<T...>, T> ...a); // expected-note +{{conflicting types for parameter 'T'}}
+
+  int a1 = f1(X<int, int, double>(), X<double, int, double>());
+  int a2 = f1(X<int, int>());
+  int a3 = f1(X<int>(), X<double>()); // expected-error {{no matching}}
+  int a4 = f1(X<int, int>(), X<int>()); // expected-error {{no matching}}
+  int a5 = f1(X<int>(), X<int, int>()); // expected-error {{no matching}}
+  int a6 = f1(X<int, int, int>(), X<int, int, int>(), X<int, int, int, int>()); // expected-error {{no matching}}
+
+  int b1 = f2(P<X<int, double>, int>(), P<X<int, double>, double>());
+  int b2 = f2(P<X<int, double>, int>(), P<X<int, double>, double>(), P<X<int, double>, char>()); // expected-error {{no matching}}
+}
+
+namespace PR14841 {
+  template<typename T, typename U> struct A {};
+  template<typename ...Ts> void f(A<Ts...>); // expected-note {{substitution failure [with Ts = <char, short, int>]: too many template arg}}
+
+  void g(A<char, short> a) {
+    f(a);
+    f<char>(a);
+    f<char, short>(a);
+    f<char, short, int>(a); // expected-error {{no matching function}}
+  }
+}
+
+namespace RetainExprPacks {
+  int f(int a, int b, int c);
+  template<typename ...Ts> struct X {};
+  template<typename ...Ts> int g(X<Ts...>, decltype(f(Ts()...)));
+  int n = g<int, int>(X<int, int, int>(), 0);
+}
diff --git a/test/SemaTemplate/resolve-single-template-id.cpp b/test/SemaTemplate/resolve-single-template-id.cpp
index 7fb16eb..bebca76 100644
--- a/test/SemaTemplate/resolve-single-template-id.cpp
+++ b/test/SemaTemplate/resolve-single-template-id.cpp
@@ -45,9 +45,15 @@
   +oneT<int>;  // expected-warning {{expression result unused}}
   -oneT<int>;  //expected-error {{invalid argument type}}
   oneT<int> == 0;   // expected-warning {{equality comparison result unused}} \
-                    // expected-note {{use '=' to turn this equality comparison into an assignment}}
-  0 == oneT<int>;   // expected-warning {{equality comparison result unused}}
-  0 != oneT<int>;    // expected-warning {{inequality comparison result unused}}
+                    // expected-note {{use '=' to turn this equality comparison into an assignment}} \
+                    // expected-warning {{comparison of function 'oneT<int>' equal to a null pointer is always false}} \
+                    // expected-note {{prefix with the address-of operator to silence this warning}}
+  0 == oneT<int>;   // expected-warning {{equality comparison result unused}} \
+                    // expected-warning {{comparison of function 'oneT<int>' equal to a null pointer is always false}} \
+                    // expected-note {{prefix with the address-of operator to silence this warning}}
+  0 != oneT<int>;   // expected-warning {{inequality comparison result unused}} \
+                    // expected-warning {{comparison of function 'oneT<int>' not equal to a null pointer is always true}} \
+                    // expected-note {{prefix with the address-of operator to silence this warning}}
   (false ? one : oneT<int>);   // expected-warning {{expression result unused}}
   void (*p1)(int); p1 = oneT<int>;
   
@@ -61,15 +67,17 @@
   b = (void (*)()) twoT<int>;
   
   one < one; //expected-warning {{self-comparison always evaluates to false}} \
-             //expected-warning {{expression result unused}}         
+             //expected-warning {{relational comparison result unused}}         
 
   oneT<int> < oneT<int>;  //expected-warning {{self-comparison always evaluates to false}} \
-                          //expected-warning {{expression result unused}}
+                          //expected-warning {{relational comparison result unused}}
 
   two < two; //expected-error 2 {{reference to overloaded function could not be resolved; did you mean to call it with no arguments?}} expected-error {{invalid operands to binary expression ('void' and 'void')}}
   twoT<int> < twoT<int>; //expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}} {{cannot resolve overloaded function 'twoT' from context}}
   oneT<int> == 0;   // expected-warning {{equality comparison result unused}} \
-                    // expected-note {{use '=' to turn this equality comparison into an assignment}}
+                    // expected-note {{use '=' to turn this equality comparison into an assignment}} \
+                    // expected-warning {{comparison of function 'oneT<int>' equal to a null pointer is always false}} \
+                    // expected-note {{prefix with the address-of operator to silence this warning}}
 
 }
 
diff --git a/test/SemaTemplate/temp_arg_nontype.cpp b/test/SemaTemplate/temp_arg_nontype.cpp
index 8f6cc19..91b0c6e 100644
--- a/test/SemaTemplate/temp_arg_nontype.cpp
+++ b/test/SemaTemplate/temp_arg_nontype.cpp
@@ -82,7 +82,7 @@
 template<int (Z::*pmf)(int)> struct A6; // expected-note{{template parameter is declared here}}
 A6<&Z::foo> *a17_1;
 A6<&Z::bar> *a17_2;
-A6<&Z::baz> *a17_3; // expected-error{{non-type template argument of type 'double (Z::*)(double)' cannot be converted to a value of type 'int (Z::*)(int)'}}
+A6<&Z::baz> *a17_3; // expected-error-re{{non-type template argument of type 'double (Z::*)(double){{( __attribute__\(\(thiscall\)\))?}}' cannot be converted to a value of type 'int (Z::*)(int){{( __attribute__\(\(thiscall\)\))?}}'}}
 
 
 template<int Z::*pm> struct A7;  // expected-note{{template parameter is declared here}}
diff --git a/test/SemaTemplate/temp_arg_nontype_cxx11.cpp b/test/SemaTemplate/temp_arg_nontype_cxx11.cpp
index d773c64..15c9c25 100644
--- a/test/SemaTemplate/temp_arg_nontype_cxx11.cpp
+++ b/test/SemaTemplate/temp_arg_nontype_cxx11.cpp
@@ -8,3 +8,18 @@
     f<int[3], int*, nullptr>(); // expected-note{{in instantiation of}}
   }
 }
+
+namespace CanonicalNullptr {
+  template<typename T> struct get { typedef T type; };
+  struct X {};
+  template<typename T, typename get<T *>::type P = nullptr> struct A {};
+  template<typename T, typename get<decltype((T(), nullptr))>::type P = nullptr> struct B {};
+  template<typename T, typename get<T X::*>::type P = nullptr> struct C {};
+
+  template<typename T> A<T> MakeA();
+  template<typename T> B<T> MakeB();
+  template<typename T> C<T> MakeC();
+  A<int> a = MakeA<int>();
+  B<int> b = MakeB<int>();
+  C<int> c = MakeC<int>();
+}
diff --git a/test/SemaTemplate/typename-specifier.cpp b/test/SemaTemplate/typename-specifier.cpp
index 733dc7f..602e903 100644
--- a/test/SemaTemplate/typename-specifier.cpp
+++ b/test/SemaTemplate/typename-specifier.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wno-unused
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wno-unused -fms-compatibility -DMSVC
 namespace N {
   struct A {
     typedef int type;
@@ -136,19 +137,106 @@
   };
 
   void foo() {
-    pair<ExampleItemSet::iterator, int> i; // expected-error {{template argument for template type parameter must be a type; did you forget 'typename'?}}
-    pair<this->ExampleItemSet::iterator, int> i; // expected-error-re {{template argument for template type parameter must be a type$}}
-    pair<ExampleItemSet::operator[], int> i; // expected-error-re {{template argument for template type parameter must be a type$}}
+#ifdef MSVC
+    // expected-warning@+4 {{omitted 'typename' is a Microsoft extension}}
+#else
+    // expected-error@+2 {{template argument for template type parameter must be a type; did you forget 'typename'?}}
+#endif
+    pair<ExampleItemSet::iterator, int> i;
+    pair<this->ExampleItemSet::iterator, int> i; // expected-error-re {{template argument for template type parameter must be a type{{$}}}}
+    pair<ExampleItemSet::operator[], int> i; // expected-error-re {{template argument for template type parameter must be a type{{$}}}}
   }
-  pair<ExampleItemSet::iterator, int> elt; // expected-error {{template argument for template type parameter must be a type; did you forget 'typename'?}}
+#ifdef MSVC
+    // expected-warning@+4 {{omitted 'typename' is a Microsoft extension}}
+#else
+  // expected-error@+2 {{template argument for template type parameter must be a type; did you forget 'typename'?}}
+#endif
+  pair<ExampleItemSet::iterator, int> elt;
 
 
   typedef map<int, ExampleItem*> ExampleItemMap;
 
   static void bar() {
-    pair<ExampleItemMap::iterator, int> i; // expected-error {{template argument for template type parameter must be a type; did you forget 'typename'?}}
+#ifdef MSVC
+    // expected-warning@+4 {{omitted 'typename' is a Microsoft extension}}
+#else
+    // expected-error@+2 {{template argument for template type parameter must be a type; did you forget 'typename'?}}
+#endif
+    pair<ExampleItemMap::iterator, int> i;
   }
-  pair<ExampleItemMap::iterator, int> entry; // expected-error {{template argument for template type parameter must be a type; did you forget 'typename'?}}
+#ifdef MSVC
+    // expected-warning@+4 {{omitted 'typename' is a Microsoft extension}}
+#else
+  // expected-error@+2 {{template argument for template type parameter must be a type; did you forget 'typename'?}}
+#endif
+  pair<ExampleItemMap::iterator, int> entry;
   pair<bar, int> foobar; // expected-error {{template argument for template type parameter must be a type}}
 };
 } // namespace missing_typename
+
+namespace missing_typename_and_base {
+template <class T> struct Bar {}; // expected-note 1+ {{template parameter is declared here}}
+template <typename T>
+struct Foo : T {
+
+  // FIXME: MSVC accepts this code.
+  Bar<TypeInBase> x; // expected-error {{use of undeclared identifier 'TypeInBase'}}
+
+#ifdef MSVC
+  // expected-warning@+4 {{omitted 'typename' is a Microsoft extension}}
+#else
+  // expected-error@+2 {{must be a type; did you forget 'typename'?}}
+#endif
+  Bar<T::TypeInBase> y;
+
+#ifdef MSVC
+  // expected-warning@+4 {{omitted 'typename' is a Microsoft extension}}
+#else
+  // expected-error@+2 {{must be a type; did you forget 'typename'?}}
+#endif
+  Bar<T::NestedRD::TypeInNestedRD> z;
+
+};
+struct Base {
+  typedef int TypeInBase;
+  struct NestedRD {
+    typedef int TypeInNestedRD;
+  };
+};
+Foo<Base> x;
+} // namespace missing_typename_and_base
+
+namespace func_type_vs_construct_tmp {
+template <typename> struct S { typedef int type; };
+template <typename T> void f();
+template <int N> void f();
+
+// expected-error@+1 {{missing 'typename' prior to dependent type name 'S<int>::type'}}
+template <typename T> void g() { f</*typename*/ S<T>::type(int())>(); }
+
+// Adding typename does fix the diagnostic.
+template <typename T> void h() { f<typename S<T>::type(int())>(); }
+
+void j() {
+  g<int>(); // expected-note-re {{in instantiation {{.*}} requested here}}
+  h<int>();
+}
+} // namespace func_type_vs_construct_tmp
+
+namespace pointer_vs_multiply {
+int x;
+// expected-error@+1 {{missing 'typename' prior to dependent type name 'B::type_or_int'}}
+template <typename T> void g() { T::type_or_int * x; }
+// expected-error@+1 {{typename specifier refers to non-type member 'type_or_int' in 'pointer_vs_multiply::A'}}
+template <typename T> void h() { typename T::type_or_int * x; }
+
+struct A { static const int type_or_int = 5; }; // expected-note {{referenced member 'type_or_int' is declared here}}
+struct B { typedef int type_or_int; };
+
+void j() {
+  g<A>();
+  g<B>(); // expected-note-re {{in instantiation {{.*}} requested here}}
+  h<A>(); // expected-note-re {{in instantiation {{.*}} requested here}}
+  h<B>();
+}
+} // namespace pointer_vs_multiply
diff --git a/test/SemaTemplate/virtual-member-functions.cpp b/test/SemaTemplate/virtual-member-functions.cpp
index 439d8f8..a23bf4e 100644
--- a/test/SemaTemplate/virtual-member-functions.cpp
+++ b/test/SemaTemplate/virtual-member-functions.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple %ms_abi_triple -DMSABI -fsyntax-only -verify %s
 
 namespace PR5557 {
 template <class T> struct A {
@@ -43,7 +44,7 @@
 
 template<typename T>
 struct HasOutOfLineKey {
-  HasOutOfLineKey() { } 
+  HasOutOfLineKey() { } // expected-note{{in instantiation of member function 'HasOutOfLineKey<int>::f' requested here}}
   virtual T *f(float *fp);
 };
 
@@ -52,7 +53,7 @@
   return fp; // expected-error{{cannot initialize return object of type 'int *' with an lvalue of type 'float *'}}
 }
 
-HasOutOfLineKey<int> out_of_line; // expected-note{{in instantiation of member function 'HasOutOfLineKey<int>::f' requested here}}
+HasOutOfLineKey<int> out_of_line; // expected-note{{in instantiation of member function 'HasOutOfLineKey<int>::HasOutOfLineKey' requested here}}
 
 namespace std {
   class type_info;
@@ -71,8 +72,13 @@
 
   int f() { return B<int>::value; }
 
+#ifdef MSABI
+  void test_typeid(B<float>::Inner bfi) { // expected-note{{implicit destructor}}
+    (void)typeid(bfi);
+#else
   void test_typeid(B<float>::Inner bfi) {
     (void)typeid(bfi); // expected-note{{implicit destructor}}
+#endif
   }
 
   template<typename T>
@@ -80,7 +86,7 @@
     void f() { }
   };
 
-  void test_X(X<int> xi, X<float> xf) {
+  void test_X(X<int> &xi, X<float> &xf) {
     xi.f();
   }
 }
@@ -96,3 +102,53 @@
   Y* f(X<void>* x) { return dynamic_cast<Y*>(x); } // expected-note {{in instantiation of member function 'DynamicCast::X<void>::foo' requested here}}
   Y* f2(X<void>* x) { return dynamic_cast<Y*>(x); }
 }
+
+namespace avoid_using_vtable {
+// We shouldn't emit the vtable for this code, in any ABI.  If we emit the
+// vtable, we emit an implicit virtual dtor, which calls ~RefPtr, which requires
+// a complete type for DeclaredOnly.
+//
+// Previously we would reference the vtable in the MS C++ ABI, even though we
+// don't need to emit either the ctor or the dtor.  In the Itanium C++ ABI, the
+// 'trace' method is the key function, so even though we use the vtable, we
+// don't emit it.
+
+template <typename T>
+struct RefPtr {
+  T *m_ptr;
+  ~RefPtr() { m_ptr->deref(); }
+};
+struct DeclaredOnly;
+struct Base {
+  virtual ~Base();
+};
+
+struct AvoidVTable : Base {
+  RefPtr<DeclaredOnly> m_insertionStyle;
+  virtual void trace();
+  AvoidVTable();
+};
+// Don't call the dtor, because that will emit an implicit dtor, and require a
+// complete type for DeclaredOnly.
+void foo() { new AvoidVTable; }
+}
+
+namespace vtable_uses_incomplete {
+// Opposite of the previous test that avoids a vtable, this one tests that we
+// use the vtable when the ctor is defined inline.
+template <typename T>
+struct RefPtr {
+  T *m_ptr;
+  ~RefPtr() { m_ptr->deref(); }  // expected-error {{member access into incomplete type 'vtable_uses_incomplete::DeclaredOnly'}}
+};
+struct DeclaredOnly; // expected-note {{forward declaration of 'vtable_uses_incomplete::DeclaredOnly'}}
+struct Base {
+  virtual ~Base();
+};
+
+struct UsesVTable : Base {
+  RefPtr<DeclaredOnly> m_insertionStyle;
+  virtual void trace();
+  UsesVTable() {} // expected-note {{in instantiation of member function 'vtable_uses_incomplete::RefPtr<vtable_uses_incomplete::DeclaredOnly>::~RefPtr' requested here}}
+};
+}
diff --git a/test/Tooling/lit.local.cfg b/test/Tooling/lit.local.cfg
new file mode 100644
index 0000000..da2a68b
--- /dev/null
+++ b/test/Tooling/lit.local.cfg
@@ -0,0 +1,2 @@
+if config.root.clang_staticanalyzer == 0:
+    config.unsupported = True
diff --git a/test/Tooling/multi-jobs.cpp b/test/Tooling/multi-jobs.cpp
index cef8443..980ade4 100644
--- a/test/Tooling/multi-jobs.cpp
+++ b/test/Tooling/multi-jobs.cpp
@@ -1,7 +1,6 @@
 // RUN: not clang-check "%s" -- -no-integrated-as -c 2>&1 | FileCheck %s
+// The following test uses multiple time the same '-no-integrated-as' flag in order to make sure those flags are really skipped, and not just overwritten by luck :
+// RUN: not clang-check "%s" -- -target x86_64-win32 -c -no-integrated-as -no-integrated-as -no-integrated-as 2>&1 | FileCheck %s
 
 // CHECK: C++ requires
 invalid;
-
-// MSVC targeted drivers (*-win32) are incapable of invoking external assembler.
-// XFAIL: win32
diff --git a/test/Unit/lit.cfg b/test/Unit/lit.cfg
index f39fded..4fa6e78 100644
--- a/test/Unit/lit.cfg
+++ b/test/Unit/lit.cfg
@@ -3,6 +3,7 @@
 # Configuration file for the 'lit' test runner.
 
 import os
+import platform
 
 import lit.formats
 import lit.util
@@ -85,10 +86,23 @@
     lit_config.load_config(config, site_cfg)
     raise SystemExit
 
-# If necessary, point the dynamic loader at libLLVM.so.
-if config.enable_shared:
-    shlibpath = config.environment.get(config.shlibpath_var,'')
-    if shlibpath:
-        shlibpath = os.pathsep + shlibpath
-    shlibpath = config.shlibdir + shlibpath
-    config.environment[config.shlibpath_var] = shlibpath
+shlibpath_var = ''
+if platform.system() == 'Linux':
+    shlibpath_var = 'LD_LIBRARY_PATH'
+elif platform.system() == 'Darwin':
+    shlibpath_var = 'DYLD_LIBRARY_PATH'
+elif platform.system() == 'Windows':
+    shlibpath_var = 'PATH'
+
+# 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,
+                                 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/Unit/lit.site.cfg.in b/test/Unit/lit.site.cfg.in
index a255cdc..37e8cb0 100644
--- a/test/Unit/lit.site.cfg.in
+++ b/test/Unit/lit.site.cfg.in
@@ -10,7 +10,6 @@
 config.clang_obj_root = "@CLANG_BINARY_DIR@"
 config.enable_shared = @ENABLE_SHARED@
 config.shlibdir = "@SHLIBDIR@"
-config.shlibpath_var = "@SHLIBPATH_VAR@"
 config.target_triple = "@TARGET_TRIPLE@"
 
 # Support substitution of the tools_dir, libs_dirs, and build_mode with user
diff --git a/include/clang/Driver/CC1Options.h b/test/VFS/Inputs/Foo.framework/Headers/Foo.h
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/VFS/Inputs/Foo.framework/Headers/Foo.h
diff --git a/test/VFS/Inputs/Foo.framework/Modules/module.modulemap b/test/VFS/Inputs/Foo.framework/Modules/module.modulemap
new file mode 100644
index 0000000..0aab69f
--- /dev/null
+++ b/test/VFS/Inputs/Foo.framework/Modules/module.modulemap
@@ -0,0 +1,3 @@
+framework module Foo {
+  umbrella header "Foo.h"
+}
diff --git a/include/clang/Driver/CC1Options.h b/test/VFS/Inputs/Foo.h
similarity index 100%
copy from include/clang/Driver/CC1Options.h
copy to test/VFS/Inputs/Foo.h
diff --git a/test/VFS/Inputs/Incomplete.h b/test/VFS/Inputs/Incomplete.h
new file mode 100644
index 0000000..29fafc3
--- /dev/null
+++ b/test/VFS/Inputs/Incomplete.h
@@ -0,0 +1 @@
+// does not include IncompleteVFS.h or IncompleteReal.h
diff --git a/test/VFS/Inputs/IncompleteVFS.h b/test/VFS/Inputs/IncompleteVFS.h
new file mode 100644
index 0000000..22cfe7d
--- /dev/null
+++ b/test/VFS/Inputs/IncompleteVFS.h
@@ -0,0 +1 @@
+// IncompleteVFS.h
diff --git a/test/VFS/Inputs/actual_header.h b/test/VFS/Inputs/actual_header.h
new file mode 100644
index 0000000..f61e586
--- /dev/null
+++ b/test/VFS/Inputs/actual_header.h
@@ -0,0 +1 @@
+void bar(void);
diff --git a/test/VFS/Inputs/actual_module.map b/test/VFS/Inputs/actual_module.map
new file mode 100644
index 0000000..d2f5b64
--- /dev/null
+++ b/test/VFS/Inputs/actual_module.map
@@ -0,0 +1,8 @@
+module not_real {
+  header "not_real.h"
+  export *
+}
+module import_some_frame {
+  header "import_some_frame.h"
+  export *
+}
diff --git a/test/VFS/Inputs/actual_module2.map b/test/VFS/Inputs/actual_module2.map
new file mode 100644
index 0000000..24f8602
--- /dev/null
+++ b/test/VFS/Inputs/actual_module2.map
@@ -0,0 +1,5 @@
+module not_real {
+  header "not_real.h"
+  export *
+  explicit module from_second_vfs { }
+}
diff --git a/test/VFS/Inputs/external-names.h b/test/VFS/Inputs/external-names.h
new file mode 100644
index 0000000..8b0baa3
--- /dev/null
+++ b/test/VFS/Inputs/external-names.h
@@ -0,0 +1,4 @@
+void foo(char **c) {
+  *c = __FILE__;
+  int x = c; // produce a diagnostic
+}
diff --git a/test/VFS/Inputs/import_some_frame.h b/test/VFS/Inputs/import_some_frame.h
new file mode 100644
index 0000000..c1f68c8
--- /dev/null
+++ b/test/VFS/Inputs/import_some_frame.h
@@ -0,0 +1,2 @@
+#import <SomeFramework/public_header.h>
+#import <SomeFramework/public_header2.h>
diff --git a/test/VFS/Inputs/include_real.h b/test/VFS/Inputs/include_real.h
new file mode 100644
index 0000000..0750c65
--- /dev/null
+++ b/test/VFS/Inputs/include_real.h
@@ -0,0 +1 @@
+#include "real.h"
diff --git a/test/VFS/Inputs/incomplete-umbrella.modulemap b/test/VFS/Inputs/incomplete-umbrella.modulemap
new file mode 100644
index 0000000..5afac92
--- /dev/null
+++ b/test/VFS/Inputs/incomplete-umbrella.modulemap
@@ -0,0 +1,5 @@
+framework module Incomplete {
+  umbrella header "Incomplete.h"
+  export *
+  module * { export * }
+}
diff --git a/test/VFS/Inputs/invalid-yaml.yaml b/test/VFS/Inputs/invalid-yaml.yaml
new file mode 100644
index 0000000..2a6c666
--- /dev/null
+++ b/test/VFS/Inputs/invalid-yaml.yaml
@@ -0,0 +1,4 @@
+{
+  'version': 0,
+  'roots': []
+]
diff --git a/test/VFS/Inputs/missing-key.yaml b/test/VFS/Inputs/missing-key.yaml
new file mode 100644
index 0000000..5d18c24
--- /dev/null
+++ b/test/VFS/Inputs/missing-key.yaml
@@ -0,0 +1,4 @@
+{
+  'version': 0,
+  'roots': [ { 'name' : 'foo', 'external-contents': 'bar' } ]
+}
diff --git a/test/VFS/Inputs/public_header.h b/test/VFS/Inputs/public_header.h
new file mode 100644
index 0000000..09d9969
--- /dev/null
+++ b/test/VFS/Inputs/public_header.h
@@ -0,0 +1,2 @@
+#import <SomeFramework/public_header2.h>
+void from_framework(void);
diff --git a/test/VFS/Inputs/public_header2.h b/test/VFS/Inputs/public_header2.h
new file mode 100644
index 0000000..d883613
--- /dev/null
+++ b/test/VFS/Inputs/public_header2.h
@@ -0,0 +1 @@
+// public_header2.h
diff --git a/test/VFS/Inputs/some_frame_module.map b/test/VFS/Inputs/some_frame_module.map
new file mode 100644
index 0000000..3ce59b2
--- /dev/null
+++ b/test/VFS/Inputs/some_frame_module.map
@@ -0,0 +1,5 @@
+framework module SomeFramework {
+  umbrella header "public_header.h"
+  export *
+  module * { export * }
+}
diff --git a/test/VFS/Inputs/unknown-key.yaml b/test/VFS/Inputs/unknown-key.yaml
new file mode 100644
index 0000000..ec7d826
--- /dev/null
+++ b/test/VFS/Inputs/unknown-key.yaml
@@ -0,0 +1,5 @@
+{
+  'version': 0,
+  'unknown-key': 'value',
+  'roots': []
+}
diff --git a/test/VFS/Inputs/unknown-value.yaml b/test/VFS/Inputs/unknown-value.yaml
new file mode 100644
index 0000000..4e90b21
--- /dev/null
+++ b/test/VFS/Inputs/unknown-value.yaml
@@ -0,0 +1,5 @@
+{
+  'version': 0,
+  'case-sensitive': 'Maybe?',
+  'roots': []
+}
diff --git a/test/VFS/Inputs/use-external-names.yaml b/test/VFS/Inputs/use-external-names.yaml
new file mode 100644
index 0000000..b9ea634
--- /dev/null
+++ b/test/VFS/Inputs/use-external-names.yaml
@@ -0,0 +1,7 @@
+{
+  'version': 0,
+  'use-external-names': EXTERNAL_NAMES,
+  'roots': [{ 'type': 'file', 'name': 'OUT_DIR/external-names.h',
+             'external-contents': 'INPUT_DIR/external-names.h'
+           }]
+}
diff --git a/test/VFS/Inputs/vfsoverlay.yaml b/test/VFS/Inputs/vfsoverlay.yaml
new file mode 100644
index 0000000..f395d45
--- /dev/null
+++ b/test/VFS/Inputs/vfsoverlay.yaml
@@ -0,0 +1,53 @@
+{
+  'version': 0,
+  'roots': [
+    { 'name': 'OUT_DIR', 'type': 'directory',
+      'contents': [
+        { 'name': 'not_real.h', 'type': 'file',
+          'external-contents': 'INPUT_DIR/actual_header.h'
+        },
+        { 'name': 'import_some_frame.h', 'type': 'file',
+          'external-contents': 'INPUT_DIR/import_some_frame.h'
+        },
+        { 'name': 'module.map', 'type': 'file',
+          'external-contents': 'INPUT_DIR/actual_module.map'
+        },
+        { 'name': 'include_real.h', 'type': 'file',
+          'external-contents': 'INPUT_DIR/include_real.h'
+        },
+        { 'name': 'SomeFramework.framework', 'type': 'directory',
+          'contents': [
+            { 'name': 'Headers', 'type': 'directory',
+              'contents': [
+                { 'name': 'public_header.h', 'type': 'file',
+                  'external-contents': 'INPUT_DIR/public_header.h' },
+                { 'name': 'public_header2.h', 'type': 'file',
+                  'external-contents': 'INPUT_DIR/public_header2.h' }
+              ]
+            }
+          ]
+        },
+        { 'name': 'Foo.framework/Headers/Foo.h', 'type': 'file',
+          'external-contents': 'INPUT_DIR/Foo.h'
+        },
+        { 'name': 'Incomplete.framework', 'type': 'directory',
+          'contents': [
+            { 'name': 'Headers', 'type': 'directory',
+              'contents': [
+                { 'name': 'Incomplete.h', 'type': 'file',
+                  'external-contents': 'INPUT_DIR/Incomplete.h'
+                },
+                { 'name': 'IncompleteVFS.h', 'type': 'file',
+                  'external-contents': 'INPUT_DIR/IncompleteVFS.h'
+                }
+              ]
+            },
+            { 'name': 'Modules/module.modulemap', 'type': 'file',
+              'external-contents': 'INPUT_DIR/incomplete-umbrella.modulemap'
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}
diff --git a/test/VFS/Inputs/vfsoverlay2.yaml b/test/VFS/Inputs/vfsoverlay2.yaml
new file mode 100644
index 0000000..ae2a0ce
--- /dev/null
+++ b/test/VFS/Inputs/vfsoverlay2.yaml
@@ -0,0 +1,12 @@
+{
+  'version': 0,
+  'roots': [
+    { 'name': 'OUT_DIR', 'type': 'directory',
+      'contents': [
+        { 'name': 'module.map', 'type': 'file',
+          'external-contents': 'INPUT_DIR/actual_module2.map'
+        }
+      ]
+    }
+  ]
+}
diff --git a/test/VFS/external-names.c b/test/VFS/external-names.c
new file mode 100644
index 0000000..aa0bd67
--- /dev/null
+++ b/test/VFS/external-names.c
@@ -0,0 +1,35 @@
+// RUN: sed -e "s:INPUT_DIR:%S/Inputs:g" -e "s:OUT_DIR:%t:g" -e "s:EXTERNAL_NAMES:true:" %S/Inputs/use-external-names.yaml > %t.external.yaml
+// RUN: sed -e "s:INPUT_DIR:%S/Inputs:g" -e "s:OUT_DIR:%t:g" -e "s:EXTERNAL_NAMES:false:" %S/Inputs/use-external-names.yaml > %t.yaml
+// REQUIRES: shell
+
+#include "external-names.h"
+
+////
+// Preprocessor (__FILE__ macro and # directives):
+
+// RUN: %clang_cc1 -I %t -ivfsoverlay %t.external.yaml -E %s | FileCheck -check-prefix=CHECK-PP-EXTERNAL %s
+// CHECK-PP-EXTERNAL: # {{[0-9]*}} "[[NAME:.*Inputs.external-names.h]]"
+// CHECK-PP-EXTERNAL-NEXT: void foo(char **c) {
+// CHECK-PP-EXTERNAL-NEXT: *c = "[[NAME]]";
+
+// RUN: %clang_cc1 -I %t -ivfsoverlay %t.yaml -E %s | FileCheck -check-prefix=CHECK-PP %s
+// CHECK-PP-NOT: Inputs
+
+////
+// Diagnostics:
+
+// RUN: %clang_cc1 -I %t -ivfsoverlay %t.external.yaml -fsyntax-only %s 2>&1 | FileCheck -check-prefix=CHECK-DIAG-EXTERNAL %s
+// CHECK-DIAG-EXTERNAL: {{.*}}Inputs{{.}}external-names.h:{{[0-9]*:[0-9]*}}: warning: incompatible pointer
+
+// RUN: %clang_cc1 -I %t -ivfsoverlay %t.yaml -fsyntax-only %s 2>&1 | FileCheck -check-prefix=CHECK-DIAG %s
+// CHECK-DIAG-NOT: Inputs
+
+////
+// Debug info
+
+// RUN: %clang_cc1 -I %t -ivfsoverlay %t.external.yaml -triple %itanium_abi_triple -g -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-DEBUG-EXTERNAL %s
+// CHECK-DEBUG-EXTERNAL: ![[Num:[0-9]*]] = metadata !{metadata !"{{.*}}Inputs{{.}}external-names.h
+// CHECK-DEBUG-EXTERNAL: metadata !{i32 {{[0-9]*}}, metadata ![[Num]]{{.*}}DW_TAG_file_type
+
+// RUN: %clang_cc1 -I %t -ivfsoverlay %t.yaml -triple %itanium_abi_triple -g -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-DEBUG %s
+// CHECK-DEBUG-NOT: Inputs
diff --git a/test/VFS/framework-import.m b/test/VFS/framework-import.m
new file mode 100644
index 0000000..b40bc54
--- /dev/null
+++ b/test/VFS/framework-import.m
@@ -0,0 +1,9 @@
+// RUN: sed -e "s:INPUT_DIR:%S/Inputs:g" -e "s:OUT_DIR:%t:g" %S/Inputs/vfsoverlay.yaml > %t.yaml
+// RUN: %clang_cc1 -Werror -F %t -ivfsoverlay %t.yaml -fsyntax-only %s
+// REQUIRES: shell
+
+#import <SomeFramework/public_header.h>
+
+void foo() {
+  from_framework();
+}
diff --git a/test/VFS/implicit-include.c b/test/VFS/implicit-include.c
new file mode 100644
index 0000000..acf665b
--- /dev/null
+++ b/test/VFS/implicit-include.c
@@ -0,0 +1,7 @@
+// RUN: sed -e "s:INPUT_DIR:%S/Inputs:g" -e "s:OUT_DIR:%t:g" %S/Inputs/vfsoverlay.yaml > %t.yaml
+// RUN: %clang_cc1 -Werror -ivfsoverlay %t.yaml -I %t -include "not_real.h" -fsyntax-only %s
+// REQUIRES: shell
+
+void foo() {
+  bar();
+}
diff --git a/test/VFS/include-mixed-real-and-virtual.c b/test/VFS/include-mixed-real-and-virtual.c
new file mode 100644
index 0000000..e1f5f95
--- /dev/null
+++ b/test/VFS/include-mixed-real-and-virtual.c
@@ -0,0 +1,14 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: echo "void baz(void);" > %t/real.h
+// RUN: sed -e "s:INPUT_DIR:%S/Inputs:g" -e "s:OUT_DIR:%t:g" %S/Inputs/vfsoverlay.yaml > %t.yaml
+// RUN: %clang_cc1 -Werror -ivfsoverlay %t.yaml -I %t -fsyntax-only %s
+// REQUIRES: shell
+
+#include "not_real.h"
+#include "real.h"
+
+void foo() {
+  bar();
+  baz();
+}
diff --git a/test/VFS/include-real-from-virtual.c b/test/VFS/include-real-from-virtual.c
new file mode 100644
index 0000000..65707b5
--- /dev/null
+++ b/test/VFS/include-real-from-virtual.c
@@ -0,0 +1,12 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: echo "void baz(void);" > %t/real.h
+// RUN: sed -e "s:INPUT_DIR:%S/Inputs:g" -e "s:OUT_DIR:%t:g" %S/Inputs/vfsoverlay.yaml > %t.yaml
+// RUN: %clang_cc1 -Werror -ivfsoverlay %t.yaml -I %t -fsyntax-only %s
+// REQUIRES: shell
+
+#include "include_real.h"
+
+void foo() {
+  baz();
+}
diff --git a/test/VFS/include-virtual-from-real.c b/test/VFS/include-virtual-from-real.c
new file mode 100644
index 0000000..c8f6059
--- /dev/null
+++ b/test/VFS/include-virtual-from-real.c
@@ -0,0 +1,12 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: echo '#include "not_real.h"' > %t/include_not_real.h
+// RUN: sed -e "s:INPUT_DIR:%S/Inputs:g" -e "s:OUT_DIR:%t:g" %S/Inputs/vfsoverlay.yaml > %t.yaml
+// RUN: %clang_cc1 -Werror -ivfsoverlay %t.yaml -I %t -fsyntax-only %s
+// REQUIRES: shell
+
+#include "include_not_real.h"
+
+void foo() {
+  bar();
+}
diff --git a/test/VFS/include.c b/test/VFS/include.c
new file mode 100644
index 0000000..8cd04dd
--- /dev/null
+++ b/test/VFS/include.c
@@ -0,0 +1,9 @@
+// RUN: sed -e "s:INPUT_DIR:%S/Inputs:g" -e "s:OUT_DIR:%t:g" %S/Inputs/vfsoverlay.yaml > %t.yaml
+// RUN: %clang_cc1 -Werror -I %t -ivfsoverlay %t.yaml -fsyntax-only %s
+// REQUIRES: shell
+
+#include "not_real.h"
+
+void foo() {
+  bar();
+}
diff --git a/test/VFS/incomplete-umbrella.m b/test/VFS/incomplete-umbrella.m
new file mode 100644
index 0000000..4e138cc
--- /dev/null
+++ b/test/VFS/incomplete-umbrella.m
@@ -0,0 +1,12 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t/Incomplete.framework/Headers
+// RUN: echo '// IncompleteReal.h' > %t/Incomplete.framework/Headers/IncompleteReal.h
+// RUN: sed -e "s:INPUT_DIR:%S/Inputs:g" -e "s:OUT_DIR:%t:g" %S/Inputs/vfsoverlay.yaml > %t.yaml
+// RUN: not %clang_cc1 -Werror -fmodules -fmodules-cache-path=%t \
+// RUN:     -ivfsoverlay %t.yaml -F %t -fsyntax-only %s 2>&1 | FileCheck %s
+// REQUIRES: shell
+
+@import Incomplete;
+// CHECK: umbrella header for module 'Incomplete' {{.*}}IncompleteVFS.h
+// CHECK: umbrella header for module 'Incomplete' {{.*}}IncompleteReal.h
+// CHECK: could not build module 'Incomplete'
diff --git a/test/VFS/module-import.m b/test/VFS/module-import.m
new file mode 100644
index 0000000..d2adcfe
--- /dev/null
+++ b/test/VFS/module-import.m
@@ -0,0 +1,27 @@
+// RUN: rm -rf %t
+// RUN: sed -e "s:INPUT_DIR:%S/Inputs:g" -e "s:OUT_DIR:%t:g" %S/Inputs/vfsoverlay.yaml > %t.yaml
+// RUN: %clang_cc1 -Werror -fmodules -fmodules-cache-path=%t -ivfsoverlay %t.yaml -I %t -fsyntax-only %s
+// REQUIRES: shell
+
+@import not_real;
+
+void foo() {
+  bar();
+}
+
+// Import a submodule that is defined in actual_module2.map, which is only
+// mapped in vfsoverlay2.yaml.
+#ifdef IMPORT2
+@import not_real.from_second_module;
+// CHECK-VFS2: error: no submodule
+#endif
+
+// Override the module map (vfsoverlay2 on top)
+// RUN: sed -e "s:INPUT_DIR:%S/Inputs:g" -e "s:OUT_DIR:%t:g" %S/Inputs/vfsoverlay2.yaml > %t2.yaml
+// RUN: %clang_cc1 -Werror -fmodules -fmodules-cache-path=%t -ivfsoverlay %t.yaml -ivfsoverlay %t2.yaml -I %t -fsyntax-only %s
+
+// vfsoverlay2 not present
+// RUN: not %clang_cc1 -Werror -fmodules -fmodules-cache-path=%t -ivfsoverlay %t.yaml -I %t -fsyntax-only %s -DIMPORT2 2>&1 | FileCheck -check-prefix=CHECK-VFS2 %s
+
+// vfsoverlay2 on the bottom
+// RUN: not %clang_cc1 -Werror -fmodules -fmodules-cache-path=%t -ivfsoverlay %t2.yaml -ivfsoverlay %t.yaml -I %t -fsyntax-only %s -DIMPORT2 2>&1 | FileCheck -check-prefix=CHECK-VFS2 %s
diff --git a/test/VFS/parse-errors.c b/test/VFS/parse-errors.c
new file mode 100644
index 0000000..7194efc
--- /dev/null
+++ b/test/VFS/parse-errors.c
@@ -0,0 +1,14 @@
+// RUN: not %clang_cc1 -ivfsoverlay %S/Inputs/invalid-yaml.yaml -fsyntax-only %s 2>&1 | FileCheck %s
+// CHECK: invalid virtual filesystem overlay file
+
+// RUN: not %clang_cc1 -ivfsoverlay %S/Inputs/missing-key.yaml -fsyntax-only %s 2>&1 | FileCheck -check-prefix=CHECK-MISSING-TYPE %s
+// CHECK-MISSING-TYPE: missing key 'type'
+// CHECK-MISSING-TYPE: invalid virtual filesystem overlay file
+
+// RUN: not %clang_cc1 -ivfsoverlay %S/Inputs/unknown-key.yaml -fsyntax-only %s 2>&1 | FileCheck -check-prefix=CHECK-UNKNOWN-KEY %s
+// CHECK-UNKNOWN-KEY: unknown key
+// CHECK-UNKNOWN-KEY: invalid virtual filesystem overlay file
+
+// RUN: not %clang_cc1 -ivfsoverlay %S/Inputs/unknown-value.yaml -fsyntax-only %s 2>&1 | FileCheck -check-prefix=CHECK-UNKNOWN-VALUE %s
+// CHECK-UNKNOWN-VALUE: expected boolean value
+// CHECK-UNKNOWN-VALUE: invalid virtual filesystem overlay file
diff --git a/test/VFS/real-path-found-first.m b/test/VFS/real-path-found-first.m
new file mode 100644
index 0000000..f494c6e
--- /dev/null
+++ b/test/VFS/real-path-found-first.m
@@ -0,0 +1,74 @@
+// This test is for cases where we lookup a file by its 'real' path before we
+// use its VFS-mapped path. If we accidentally use the real path in header
+// search, we will not find a module for the headers.  To test that we
+// intentionally rebuild modules, since the precompiled module file refers to
+// the dependency files by real path.
+
+// REQUIRES: shell
+// RUN: rm -rf %t %t-cache %t.pch
+// RUN: mkdir -p %t/SomeFramework.framework/Modules
+// RUN: cp %S/Inputs/some_frame_module.map %t/SomeFramework.framework/Modules/module.modulemap
+// RUN: sed -e "s:INPUT_DIR:%S/Inputs:g" -e "s:OUT_DIR:%t:g" %S/Inputs/vfsoverlay.yaml > %t.yaml
+
+// Build
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t-cache -F %t \
+// RUN:     -ivfsoverlay %t.yaml -fsyntax-only %s -verify -Wauto-import \
+// RUN:     -Werror=non-modular-include-in-framework-module
+
+// Rebuild
+// RUN: echo ' ' >> %t/SomeFramework.framework/Modules/module.modulemap
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t-cache -F %t \
+// RUN:     -ivfsoverlay %t.yaml -fsyntax-only %s -verify -Wauto-import \
+// RUN:     -Werror=non-modular-include-in-framework-module
+
+// Load from PCH
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t-cache -F %t \
+// RUN:     -ivfsoverlay %t.yaml -emit-pch  %s -o %t.pch \
+// RUN:     -Werror=non-modular-include-in-framework-module \
+// RUN:     -fmodules-ignore-macro=WITH_PREFIX
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t-cache -F %t \
+// RUN:     -ivfsoverlay %t.yaml -include-pch %t.pch -fsyntax-only  %s \
+// RUN:     -Werror=non-modular-include-in-framework-module -DWITH_PREFIX \
+// RUN:     -fmodules-ignore-macro=WITH_PREFIX
+
+// While indexing
+// RUN: c-index-test -index-file %s -fmodules -fmodules-cache-path=%t-cache -F %t \
+// RUN:     -ivfsoverlay %t.yaml -fsyntax-only -Wauto-import \
+// RUN:     -Werror=non-modular-include-in-framework-module | FileCheck %s
+// RUN: echo ' ' >> %t/SomeFramework.framework/Modules/module.modulemap
+// RUN: c-index-test -index-file %s -fmodules -fmodules-cache-path=%t-cache -F %t \
+// RUN:     -ivfsoverlay %t.yaml -fsyntax-only -Wauto-import \
+// RUN:     -Werror=non-modular-include-in-framework-module | FileCheck %s
+// CHECK: warning: treating
+// CHECK-NOT: error
+
+// With a VFS-mapped module map file
+// RUN: mv %t/SomeFramework.framework/Modules/module.modulemap %t/hide_module.map
+// RUN: echo "{ 'version': 0, 'roots': [ { " > %t2.yaml
+// RUN: echo "'name': '%t/SomeFramework.framework/Modules/module.modulemap'," >> %t2.yaml
+// RUN: echo "'type': 'file', 'external-contents': '%t/hide_module.map' } ] }" >> %t2.yaml
+
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t-cache -F %t \
+// RUN:     -ivfsoverlay %t.yaml -ivfsoverlay %t2.yaml -fsyntax-only %s -verify \
+// RUN:     -Wauto-import -Werror=non-modular-include-in-framework-module
+// RUN: echo ' ' >> %t/hide_module.map
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t-cache -F %t \
+// RUN:     -ivfsoverlay %t.yaml -ivfsoverlay %t2.yaml -fsyntax-only %s -verify \
+// RUN:     -Wauto-import -Werror=non-modular-include-in-framework-module
+
+// Within a module build
+// RUN: echo '@import import_some_frame;' | \
+// RUN:   %clang_cc1 -fmodules -fmodules-cache-path=%t-cache -F %t \
+// RUN:      -ivfsoverlay %t.yaml -ivfsoverlay %t2.yaml -fsyntax-only - \
+// RUN:      -Werror=non-modular-include-in-framework-module -x objective-c -I %t
+// RUN: echo ' ' >> %t/hide_module.map
+// RUN: echo '@import import_some_frame;' | \
+// RUN:   %clang_cc1 -fmodules -fmodules-cache-path=%t-cache -F %t \
+// RUN:      -ivfsoverlay %t.yaml -ivfsoverlay %t2.yaml -fsyntax-only - \
+// RUN:      -Werror=non-modular-include-in-framework-module -x objective-c -I %t
+
+#ifndef WITH_PREFIX
+#import <SomeFramework/public_header.h> // expected-warning{{treating}}
+#import <SomeFramework/public_header2.h> // expected-warning{{treating}}
+@import SomeFramework.public_header2;
+#endif
diff --git a/test/VFS/relative-path.c b/test/VFS/relative-path.c
new file mode 100644
index 0000000..e7101fb
--- /dev/null
+++ b/test/VFS/relative-path.c
@@ -0,0 +1,11 @@
+// RUN: mkdir -p %t
+// RUN: cd %t
+// RUN: sed -e "s:INPUT_DIR:%S/Inputs:g" -e "s:OUT_DIR:%t:g" %S/Inputs/vfsoverlay.yaml > %t.yaml
+// RUN: %clang_cc1 -Werror -I . -ivfsoverlay %t.yaml -fsyntax-only %s
+// REQUIRES: shell
+
+#include "not_real.h"
+
+void foo() {
+  bar();
+}
diff --git a/test/VFS/umbrella-mismatch.m b/test/VFS/umbrella-mismatch.m
new file mode 100644
index 0000000..c731294
--- /dev/null
+++ b/test/VFS/umbrella-mismatch.m
@@ -0,0 +1,8 @@
+// RUN: rm -rf %t
+// RUN: sed -e "s:INPUT_DIR:%S/Inputs:g" -e "s:OUT_DIR:%S/Inputs:g" %S/Inputs/vfsoverlay.yaml > %t.yaml
+// REQUIRES: shell
+
+// RUN: %clang_cc1 -Werror -fmodules -fmodules-cache-path=%t -ivfsoverlay %t.yaml -F %S/Inputs -fsyntax-only %s -verify
+// RUN: %clang_cc1 -Werror -fmodules -fmodules-cache-path=%t -F %S/Inputs -fsyntax-only %s -verify
+// expected-no-diagnostics
+@import Foo;
diff --git a/test/lit.cfg b/test/lit.cfg
index d08bf66..0f3e97f 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -54,7 +54,7 @@
 config.test_format = lit.formats.ShTest(execute_external)
 
 # suffixes: A list of file extensions to treat as test files.
-config.suffixes = ['.c', '.cpp', '.m', '.mm', '.cu', '.ll', '.cl', '.s']
+config.suffixes = ['.c', '.cpp', '.m', '.mm', '.cu', '.ll', '.cl', '.s', '.S']
 
 # excludes: A list of directories to exclude from the testsuite. The 'Inputs'
 # subdirectories contain auxiliary inputs for various tests in their parent
@@ -104,11 +104,14 @@
 
 # Tweak the PATH to include the tools dir and the scripts dir.
 if clang_obj_root is not None:
-    # @LOCALMOD
-    llvm_tools_dir = FixMsysPath(getattr(config, 'llvm_tools_dir', None))
+    clang_tools_dir = FixMsysPath(getattr(config, 'clang_tools_dir', None)) # @LOCALMOD
+    if not clang_tools_dir:
+        lit_config.fatal('No Clang tools dir set!')
+    llvm_tools_dir = FixMsysPath(getattr(config, 'llvm_tools_dir', None)) # @LOCALMOD
     if not llvm_tools_dir:
         lit_config.fatal('No LLVM tools dir set!')
-    path = os.path.pathsep.join((llvm_tools_dir, config.environment['PATH']))
+    path = os.path.pathsep.join((
+            clang_tools_dir, llvm_tools_dir, config.environment['PATH']))
     config.environment['PATH'] = path
     llvm_libs_dir = getattr(config, 'llvm_libs_dir', None)
     if not llvm_libs_dir:
@@ -122,6 +125,11 @@
     if symbolizer in os.environ:
         config.environment[symbolizer] = os.environ[symbolizer]
 
+# Propagate options for sanitizers.
+for options in ['ASAN_OPTIONS']:
+    if options in os.environ:
+        config.environment[options] = os.environ[options]
+
 ###
 
 # Check that the object root is known.
@@ -202,6 +210,22 @@
 if not lit_config.quiet:
     lit_config.note('using clang: %r' % config.clang)
 
+# Plugins (loadable modules)
+# TODO: This should be supplied by Makefile or autoconf.
+if sys.platform in ['win32', 'cygwin']:
+    has_plugins = (config.enable_shared == 1)
+else:
+    has_plugins = True
+
+if has_plugins and config.llvm_plugin_ext:
+    config.available_features.add('plugins')
+
+config.substitutions.append( ('%llvmshlibdir', config.llvm_shlib_dir) )
+config.substitutions.append( ('%pluginext', config.llvm_plugin_ext) )
+
+if config.clang_examples:
+    config.available_features.add('examples')
+
 # Note that when substituting %clang_cc1 also fill in the include directory of
 # the builtin headers. Those are part of even a freestanding environment, but
 # Clang relies on the driver to locate them.
@@ -219,6 +243,31 @@
     # Ensure the result is an ascii string, across Python2.5+ - Python3.
     return str(dir.decode('ascii'))
 
+def makeItaniumABITriple(triple):
+    m = re.match(r'(\w+)-(\w+)-(\w+)', triple)
+    if not m:
+      lit_config.fatal("Could not turn '%s' into Itanium ABI triple" % triple)
+    if m.group(3).lower() != 'win32':
+      # All non-win32 triples use the Itanium ABI.
+      return triple
+    return m.group(1) + '-' + m.group(2) + '-mingw32'
+
+def makeMSABITriple(triple):
+    m = re.match(r'(\w+)-(\w+)-(\w+)', triple)
+    if not m:
+      lit_config.fatal("Could not turn '%s' into MS ABI triple" % triple)
+    isa = m.group(1).lower()
+    vendor = m.group(2).lower()
+    os = m.group(3).lower()
+    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): 
+      # 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_cc1', '%s -cc1 -internal-isystem %s'
                               % (config.clang,
                                  getClangBuiltinIncludeDir(config.clang))) )
@@ -230,6 +279,8 @@
                               ' --driver-mode=g++ '))
 config.substitutions.append( ('%clang', ' ' + config.clang + ' ') )
 config.substitutions.append( ('%test_debuginfo', ' ' + config.llvm_src_root + '/utils/test_debuginfo.pl ') )
+config.substitutions.append( ('%itanium_abi_triple', makeItaniumABITriple(config.target_triple)) )
+config.substitutions.append( ('%ms_abi_triple', makeMSABITriple(config.target_triple)) )
 
 # FIXME: Find nicer way to prohibit this.
 config.substitutions.append(
@@ -252,10 +303,51 @@
     (' %clang-cl ',
      """*** invalid substitution, use '%clang_cl'. ***""") )
 
+# For each occurrence of a clang tool name as its own word, replace it
+# with the full path to the build directory holding that tool.  This
+# ensures that we are testing the tools just built and not some random
+# tools that might happen to be in the user's PATH.
+tool_dirs = os.path.pathsep.join((clang_tools_dir, llvm_tools_dir))
+
+# Regex assertions to reject neighbor hyphens/dots (seen in some tests).
+# For example, don't match 'clang-check-' or '.clang-format'.
+NoPreHyphenDot = r"(?<!(-|\.))"
+NoPostHyphenDot = r"(?!(-|\.))"
+
+for pattern in [r"\bFileCheck\b",
+                r"\bc-index-test\b",
+                NoPreHyphenDot + r"\bclang-check\b" + NoPostHyphenDot,
+                NoPreHyphenDot + r"\bclang-format\b" + NoPostHyphenDot,
+                NoPreHyphenDot + r"\bclang-interpreter\b" + NoPostHyphenDot,
+                # FIXME: Some clang test uses opt?
+                NoPreHyphenDot + r"\bopt\b" + NoPostHyphenDot,
+                # Handle these specially as they are strings searched
+                # for during testing.
+                r"\| \bcount\b",
+                r"\| \bnot\b"]:
+    # Extract the tool name from the pattern.  This relies on the tool
+    # name being surrounded by \b word match operators.  If the
+    # pattern starts with "| ", include it in the string to be
+    # substituted.
+    tool_match = re.match(r"^(\\)?((\| )?)\W+b([0-9A-Za-z-_]+)\\b\W*$",
+                          pattern)
+    tool_pipe = tool_match.group(2)
+    tool_name = tool_match.group(4)
+    tool_path = lit.util.which(tool_name, tool_dirs)
+    if not tool_path:
+        # Warn, but still provide a substitution.
+        lit_config.note('Did not find ' + tool_name + ' in ' + tool_dirs)
+        tool_path = clang_tools_dir + '/' + tool_name
+    config.substitutions.append((pattern, tool_pipe + tool_path))
+
 ###
 
 # Set available features we allow tests to conditionalize on.
 #
+# Enabled/disabled features
+if config.clang_staticanalyzer != 0:
+    config.available_features.add("staticanalyzer")
+
 # As of 2011.08, crash-recovery tests still do not pass on FreeBSD.
 if platform.system() not in ['FreeBSD']:
     config.available_features.add('crash-recovery')
@@ -268,12 +360,27 @@
 if not platform.system() in ['Windows'] or not execute_external:
     config.available_features.add('shell-preserves-root')
 
+# For tests that require Darwin to run.
+# This is used by debuginfo-tests/*block*.m and debuginfo-tests/foreach.m.
+if platform.system() in ['Darwin']:
+    config.available_features.add('system-darwin')
+elif platform.system() in ['Windows']:
+    # For tests that require Windows to run.
+    config.available_features.add('system-windows')
+
 # ANSI escape sequences in non-dumb terminal
 if platform.system() not in ['Windows']:
     config.available_features.add('ansi-escape-sequences')
 
-# Native compilation: host arch == target arch
-if config.host_arch in config.target_triple:
+# Capability to print utf8 to the terminal.
+# Windows expects codepage, unless Wide API.
+if platform.system() not in ['Windows']:
+    config.available_features.add('utf8-capable-terminal')
+
+# Native compilation: Check if triples match.
+# FIXME: Consider cases that target can be executed
+# even if host_triple were different from target_triple.
+if config.host_triple == config.target_triple:
     config.available_features.add("native")
 
 # Case-insensitive file system
@@ -295,6 +402,14 @@
 if os.path.exists("/dev/fd/0") and sys.platform not in ['cygwin']:
     config.available_features.add('dev-fd-fs')
 
+# DW2 Target
+if not re.match(r'.*-win32$', config.target_triple):
+    config.available_features.add('dw2')
+
+# Not set on native MS environment.
+if not re.match(r'.*-win32$', config.target_triple):
+    config.available_features.add('non-ms-sdk')
+
 # [PR8833] LLP64-incompatible tests
 if not re.match(r'^x86_64.*-(win32|mingw32)$', config.target_triple):
     config.available_features.add('LP64')
@@ -303,40 +418,36 @@
 if not re.match(r'.*-(cygwin|mingw32)$', config.target_triple):
     config.available_features.add('clang-driver')
 
-# Registered Targets
-def get_llc_props(tool):
-    set_of_targets = set()
-    enable_assertions = False
+# [PR18856] Depends to remove opened file. On win32, a file could be removed
+# only if all handles were closed.
+if platform.system() not in ['Windows']:
+    config.available_features.add('can-remove-opened-file')
 
-    cmd = subprocess.Popen([tool, '-version'], stdout=subprocess.PIPE)
+# Returns set of available features, registered-target(s) and asserts.
+def get_llvm_config_props():
+    set_of_features = set()
 
-    # Parse the stdout to get the list of registered targets.
-    parse_targets = False
-    for line in cmd.stdout:
-        line = line.decode('ascii')
-        if parse_targets:
-            m = re.match( r'(.*) - ', line)
-            if m is not None:
-                set_of_targets.add(m.group(1).strip() + '-registered-target')
-            else:
-                break
-        elif "Registered Targets:" in line:
-            parse_targets = True
+    cmd = subprocess.Popen(
+        [
+            os.path.join(llvm_tools_dir, 'llvm-config'),
+            '--assertion-mode',
+            '--targets-built',
+            ],
+        stdout=subprocess.PIPE
+        )
+    # 1st line corresponds to --assertion-mode, "ON" or "OFF".
+    line = cmd.stdout.readline().strip().decode('ascii')
+    if line == "ON":
+        set_of_features.add('asserts')
 
-        if re.search(r'with assertions', line):
-            enable_assertions = True
+    # 2nd line corresponds to --targets-built, like;
+    # AArch64 ARM CppBackend X86
+    for arch in cmd.stdout.readline().decode('ascii').split():
+        set_of_features.add(arch.lower() + '-registered-target')
 
-    return {"set_of_targets":    set_of_targets,
-            "enable_assertions": enable_assertions}
+    return set_of_features
 
-llc_props = get_llc_props(os.path.join(llvm_tools_dir, 'llc'))
-if len(llc_props['set_of_targets']) > 0:
-    config.available_features.update(llc_props['set_of_targets'])
-else:
-    lit_config.fatal('No Targets Registered with the LLVM Tools!')
-
-if llc_props['enable_assertions']:
-    config.available_features.add('asserts')
+config.available_features.update(get_llvm_config_props())
 
 if lit.util.which('xmllint'):
     config.available_features.add('xmllint')
@@ -344,6 +455,8 @@
 # Sanitizers.
 if config.llvm_use_sanitizer == "Address":
     config.available_features.add("asan")
+else:
+    config.available_features.add("not_asan")
 if (config.llvm_use_sanitizer == "Memory" or
         config.llvm_use_sanitizer == "MemoryWithOrigins"):
     config.available_features.add("msan")
@@ -372,18 +485,4 @@
 if use_gmalloc:
      config.environment.update({'DYLD_INSERT_LIBRARIES' : gmalloc_path_str})
 
-# On Darwin, support relocatable SDKs by providing Clang with a
-# default system root path.
-if 'darwin' in config.target_triple:
-    try:
-        cmd = subprocess.Popen(['xcrun', '--show-sdk-path'],
-                               stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-        out, err = cmd.communicate()
-        out = out.strip()
-        res = cmd.wait()
-    except OSError:
-        res = -1
-    if res == 0 and out:
-        sdk_path = out
-        lit_config.note('using SDKROOT: %r' % sdk_path)
-        config.environment['SDKROOT'] = sdk_path
+lit.util.usePlatformSdkOnDarwin(config, lit_config)
diff --git a/test/lit.site.cfg.in b/test/lit.site.cfg.in
index 9a4fa33..1f0b960 100644
--- a/test/lit.site.cfg.in
+++ b/test/lit.site.cfg.in
@@ -6,19 +6,26 @@
 config.llvm_obj_root = "@LLVM_BINARY_DIR@"
 config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
 config.llvm_libs_dir = "@LLVM_LIBS_DIR@"
+config.llvm_shlib_dir = "@SHLIBDIR@"
+config.llvm_plugin_ext = "@LLVM_PLUGIN_EXT@"
 config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@"
 config.clang_obj_root = "@CLANG_BINARY_DIR@"
+config.clang_tools_dir = "@CLANG_TOOLS_DIR@"
+config.host_triple = "@LLVM_HOST_TRIPLE@"
 config.target_triple = "@TARGET_TRIPLE@"
 config.llvm_use_sanitizer = "@LLVM_USE_SANITIZER@"
 config.clang_arcmt = @ENABLE_CLANG_ARCMT@
 config.clang_staticanalyzer = @ENABLE_CLANG_STATIC_ANALYZER@
-config.clang_rewriter = @ENABLE_CLANG_REWRITER@
+config.clang_examples = @ENABLE_CLANG_EXAMPLES@
+config.enable_shared = @ENABLE_SHARED@
 config.host_arch = "@HOST_ARCH@"
 
 # Support substitution of the tools and libs dirs with user parameters. This is
 # used when we can't determine the tool dir at configuration time.
 try:
+    config.clang_tools_dir = config.clang_tools_dir % lit_config.params
     config.llvm_tools_dir = config.llvm_tools_dir % lit_config.params
+    config.llvm_shlib_dir = config.llvm_shlib_dir % lit_config.params
     config.llvm_libs_dir = config.llvm_libs_dir % lit_config.params
 except KeyError:
     e = sys.exc_info()[1]
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index fef0adc..90b2225 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -1,15 +1,16 @@
 add_subdirectory(diagtool)
 add_subdirectory(driver)
-if(CLANG_ENABLE_REWRITER)
-  add_subdirectory(clang-format)
-endif()
+add_subdirectory(clang-format)
+add_subdirectory(clang-format-vs)
+
+add_subdirectory(c-index-test)
+add_subdirectory(libclang)
 
 if(CLANG_ENABLE_ARCMT)
-  add_subdirectory(libclang)
-  add_subdirectory(c-index-test)
   add_subdirectory(arcmt-test)
   add_subdirectory(c-arcmt-test)
 endif()
+
 if(CLANG_ENABLE_STATIC_ANALYZER)
   add_subdirectory(clang-check)
 endif()
diff --git a/tools/Makefile b/tools/Makefile
index 94032d2..2ee1299 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -12,11 +12,7 @@
 include $(CLANG_LEVEL)/../../Makefile.config
 
 DIRS := 
-PARALLEL_DIRS := driver diagtool
-
-ifeq ($(ENABLE_CLANG_REWRITER),1)
-  PARALLEL_DIRS += clang-format
-endif
+PARALLEL_DIRS := clang-format driver diagtool
 
 ifeq ($(ENABLE_CLANG_STATIC_ANALYZER), 1)
   PARALLEL_DIRS += clang-check
diff --git a/tools/arcmt-test/CMakeLists.txt b/tools/arcmt-test/CMakeLists.txt
index 3d85d05..0cb2c0f 100644
--- a/tools/arcmt-test/CMakeLists.txt
+++ b/tools/arcmt-test/CMakeLists.txt
@@ -1,9 +1,5 @@
 set(LLVM_LINK_COMPONENTS
-  ${LLVM_TARGETS_TO_BUILD}
-  asmparser
-  bitreader
   support
-  mc
   )
 
 add_clang_executable(arcmt-test
@@ -12,6 +8,7 @@
 
 target_link_libraries(arcmt-test
   clangARCMigrate
-  clangEdit
-  clangRewriteCore
+  clangBasic
+  clangFrontend
+  clangLex
   )
diff --git a/tools/arcmt-test/Makefile b/tools/arcmt-test/Makefile
index 4b9b8db..d9d44bb 100644
--- a/tools/arcmt-test/Makefile
+++ b/tools/arcmt-test/Makefile
@@ -18,7 +18,7 @@
 
 include $(CLANG_LEVEL)/../../Makefile.config
 LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option
-USEDLIBS = clangARCMigrate.a clangRewriteCore.a \
+USEDLIBS = clangARCMigrate.a clangRewrite.a \
 		 clangFrontend.a clangDriver.a clangSerialization.a clangParse.a \
 		 clangSema.a clangEdit.a clangAnalysis.a clangAST.a clangLex.a \
 		 clangBasic.a
diff --git a/tools/arcmt-test/arcmt-test.cpp b/tools/arcmt-test/arcmt-test.cpp
index 50426e3..a59a869 100644
--- a/tools/arcmt-test/arcmt-test.cpp
+++ b/tools/arcmt-test/arcmt-test.cpp
@@ -16,7 +16,7 @@
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Signals.h"
-#include "llvm/Support/system_error.h"
+#include <system_error>
 
 using namespace clang;
 using namespace arcmt;
@@ -81,19 +81,19 @@
 
 public:
   PrintTransforms(raw_ostream &OS)
-    : Ctx(0), OS(OS) { }
+    : Ctx(nullptr), OS(OS) {}
 
-  virtual void start(ASTContext &ctx) { Ctx = &ctx; }
-  virtual void finish() { Ctx = 0; }
+  void start(ASTContext &ctx) override { Ctx = &ctx; }
+  void finish() override { Ctx = nullptr; }
 
-  virtual void insert(SourceLocation loc, StringRef text) {
+  void insert(SourceLocation loc, StringRef text) override {
     assert(Ctx);
     OS << "Insert: ";
     printSourceLocation(loc, *Ctx, OS);
     OS << " \"" << text << "\"\n";
   }
 
-  virtual void remove(CharSourceRange range) {
+  void remove(CharSourceRange range) override {
     assert(Ctx);
     OS << "Remove: ";
     printSourceRange(range, *Ctx, OS);
@@ -112,7 +112,7 @@
   IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
       new DiagnosticsEngine(DiagID, &*DiagOpts, DiagClient));
   // Chain in -verify checker, if requested.
-  VerifyDiagnosticConsumer *verifyDiag = 0;
+  VerifyDiagnosticConsumer *verifyDiag = nullptr;
   if (VerifyDiags) {
     verifyDiag = new VerifyDiagnosticConsumer(*Diags);
     Diags->setClient(verifyDiag);
@@ -139,10 +139,8 @@
   PreprocessorOptions PPOpts;
   remapper.applyMappings(PPOpts);
   // The changed files will be in memory buffers, print them.
-  for (unsigned i = 0, e = PPOpts.RemappedFileBuffers.size(); i != e; ++i) {
-    const llvm::MemoryBuffer *mem = PPOpts.RemappedFileBuffers[i].second;
-    OS << mem->getBuffer();
-  }
+  for (const auto &RB : PPOpts.RemappedFileBuffers)
+    OS << RB.second->getBuffer();
 }
 
 static bool performTransformations(StringRef resourcesPath,
@@ -178,7 +176,7 @@
                                  origCI.getMigratorOpts().NoFinalizeRemoval);
   assert(!transforms.empty());
 
-  OwningPtr<PrintTransforms> transformPrinter;
+  std::unique_ptr<PrintTransforms> transformPrinter;
   if (OutputTransformations)
     transformPrinter.reset(new PrintTransforms(llvm::outs()));
 
@@ -207,17 +205,15 @@
 static bool filesCompareEqual(StringRef fname1, StringRef fname2) {
   using namespace llvm;
 
-  OwningPtr<MemoryBuffer> file1;
-  MemoryBuffer::getFile(fname1, file1);
+  ErrorOr<std::unique_ptr<MemoryBuffer>> file1 = MemoryBuffer::getFile(fname1);
   if (!file1)
     return false;
-  
-  OwningPtr<MemoryBuffer> file2;
-  MemoryBuffer::getFile(fname2, file2);
+
+  ErrorOr<std::unique_ptr<MemoryBuffer>> file2 = MemoryBuffer::getFile(fname2);
   if (!file2)
     return false;
 
-  return file1->getBuffer() == file2->getBuffer();
+  return file1.get()->getBuffer() == file2.get()->getBuffer();
 }
 
 static bool verifyTransformedFiles(ArrayRef<std::string> resultFiles) {
@@ -238,18 +234,19 @@
     resultMap[sys::path::stem(fname)] = fname;
   }
 
-  OwningPtr<MemoryBuffer> inputBuf;
+  ErrorOr<std::unique_ptr<MemoryBuffer>> inputBuf = std::error_code();
   if (RemappingsFile.empty())
-    MemoryBuffer::getSTDIN(inputBuf);
+    inputBuf = MemoryBuffer::getSTDIN();
   else
-    MemoryBuffer::getFile(RemappingsFile, inputBuf);
+    inputBuf = MemoryBuffer::getFile(RemappingsFile);
   if (!inputBuf) {
     errs() << "error: could not read remappings input\n";
     return true;
   }
 
   SmallVector<StringRef, 8> strs;
-  inputBuf->getBuffer().split(strs, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
+  inputBuf.get()->getBuffer().split(strs, "\n", /*MaxSplit=*/-1,
+                                    /*KeepEmpty=*/false);
 
   if (strs.empty()) {
     errs() << "error: no files to verify from stdin\n";
diff --git a/tools/c-arcmt-test/CMakeLists.txt b/tools/c-arcmt-test/CMakeLists.txt
index 1e72261..9014ccc 100644
--- a/tools/c-arcmt-test/CMakeLists.txt
+++ b/tools/c-arcmt-test/CMakeLists.txt
@@ -1,8 +1,3 @@
-set( LLVM_LINK_COMPONENTS
-  support
-  mc
-  )
-
 add_clang_executable(c-arcmt-test
   c-arcmt-test.c
   )
diff --git a/tools/c-arcmt-test/Makefile b/tools/c-arcmt-test/Makefile
index 4a01c72..e7d5be7 100644
--- a/tools/c-arcmt-test/Makefile
+++ b/tools/c-arcmt-test/Makefile
@@ -27,9 +27,13 @@
 # when -static is given to linker on cygming.
 USEDLIBS = clang.a \
 	   clangARCMigrate.a \
+	   clangIndex.a \
+	   clangFormat.a \
+	   clangTooling.a \
 	   clangRewriteFrontend.a \
-	   clangRewriteCore.a \
-	   clangIndex.a clangFrontend.a clangDriver.a \
+	   clangRewrite.a \
+	   clangFrontend.a clangDriver.a \
+	   clangStaticAnalyzerCheckers.a clangStaticAnalyzerCore.a \
 	   clangSerialization.a clangParse.a clangSema.a \
 	   clangAnalysis.a clangEdit.a clangAST.a clangLex.a clangBasic.a
 
diff --git a/tools/c-arcmt-test/c-arcmt-test.c b/tools/c-arcmt-test/c-arcmt-test.c
index 56a4132..3bbb2d5 100644
--- a/tools/c-arcmt-test/c-arcmt-test.c
+++ b/tools/c-arcmt-test/c-arcmt-test.c
@@ -97,14 +97,20 @@
 void thread_runner(void *client_data_v) {
   thread_info *client_data = client_data_v;
   client_data->result = carcmttest_main(client_data->argc, client_data->argv);
-#ifdef __CYGWIN__
-  fflush(stdout);  /* stdout is not flushed on Cygwin. */
-#endif
+}
+
+static void flush_atexit(void) {
+  /* stdout, and surprisingly even stderr, are not always flushed on process
+   * and thread exit, particularly when the system is under heavy load. */
+  fflush(stdout);
+  fflush(stderr);
 }
 
 int main(int argc, const char **argv) {
   thread_info client_data;
 
+  atexit(flush_atexit);
+
 #if defined(_WIN32)
   if (getenv("LIBCLANG_LOGGING") == NULL)
     putenv("LIBCLANG_LOGGING=1");
diff --git a/tools/c-index-test/CMakeLists.txt b/tools/c-index-test/CMakeLists.txt
index d850411..113172a 100644
--- a/tools/c-index-test/CMakeLists.txt
+++ b/tools/c-index-test/CMakeLists.txt
@@ -1,8 +1,3 @@
-set( LLVM_LINK_COMPONENTS
-  support
-  mc
-  )
-
 add_clang_executable(c-index-test
   c-index-test.c
   )
@@ -10,7 +5,7 @@
 if(NOT MSVC)
   set_property(
     SOURCE c-index-test.c
-    PROPERTY COMPILE_FLAGS "-std=c89"
+    PROPERTY COMPILE_FLAGS "-std=gnu89"
     )
 endif()
 
diff --git a/tools/c-index-test/Makefile b/tools/c-index-test/Makefile
index b38d654..42bfbb0 100644
--- a/tools/c-index-test/Makefile
+++ b/tools/c-index-test/Makefile
@@ -27,7 +27,7 @@
 # Note that 'USEDLIBS' must include all of the core clang libraries
 # when -static is given to linker on cygming.
 USEDLIBS = clang.a \
-	   clangIndex.a clangFormat.a clangRewriteCore.a \
+	   clangIndex.a clangFormat.a clangRewrite.a \
 	   clangFrontend.a clangDriver.a \
 	   clangTooling.a \
 	   clangSerialization.a clangParse.a clangSema.a \
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index 90a6528..07be22a 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -1,8 +1,10 @@
 /* c-index-test.c */
 
+#include "clang/Config/config.h"
 #include "clang-c/Index.h"
 #include "clang-c/CXCompilationDatabase.h"
-#include "llvm/Config/config.h"
+#include "clang-c/BuildSystem.h"
+#include "clang-c/Documentation.h"
 #include <ctype.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -78,8 +80,33 @@
   return options;
 }
 
+/** \brief Returns 0 in case of success, non-zero in case of a failure. */
 static int checkForErrors(CXTranslationUnit TU);
 
+static void describeLibclangFailure(enum CXErrorCode Err) {
+  switch (Err) {
+  case CXError_Success:
+    fprintf(stderr, "Success\n");
+    return;
+
+  case CXError_Failure:
+    fprintf(stderr, "Failure (no details available)\n");
+    return;
+
+  case CXError_Crashed:
+    fprintf(stderr, "Failure: libclang crashed\n");
+    return;
+
+  case CXError_InvalidArguments:
+    fprintf(stderr, "Failure: invalid arguments passed to a libclang routine\n");
+    return;
+
+  case CXError_ASTReadError:
+    fprintf(stderr, "Failure: AST deserialization error occurred\n");
+    return;
+  }
+}
+
 static void PrintExtent(FILE *out, unsigned begin_line, unsigned begin_column,
                         unsigned end_line, unsigned end_column) {
   fprintf(out, "[%d:%d - %d:%d]", begin_line, begin_column,
@@ -88,10 +115,11 @@
 
 static unsigned CreateTranslationUnit(CXIndex Idx, const char *file,
                                       CXTranslationUnit *TU) {
-
-  *TU = clang_createTranslationUnit(Idx, file);
-  if (!*TU) {
+  enum CXErrorCode Err = clang_createTranslationUnit2(Idx, file, TU);
+  if (Err != CXError_Success) {
     fprintf(stderr, "Unable to load translation unit from '%s'!\n", file);
+    describeLibclangFailure(Err);
+    *TU = 0;
     return 0;
   }
   return 1;
@@ -107,20 +135,25 @@
   free(unsaved_files);
 }
 
-int parse_remapped_files(int argc, const char **argv, int start_arg,
-                         struct CXUnsavedFile **unsaved_files,
-                         int *num_unsaved_files) {
+static int parse_remapped_files_with_opt(const char *opt_name,
+                                         int argc, const char **argv,
+                                         int start_arg,
+                                         struct CXUnsavedFile **unsaved_files,
+                                         int *num_unsaved_files) {
   int i;
   int arg;
-  int prefix_len = strlen("-remap-file=");
+  int prefix_len = strlen(opt_name);
+  int arg_indices[20];
   *unsaved_files = 0;
   *num_unsaved_files = 0;
 
   /* Count the number of remapped files. */
   for (arg = start_arg; arg < argc; ++arg) {
-    if (strncmp(argv[arg], "-remap-file=", prefix_len))
-      break;
+    if (strncmp(argv[arg], opt_name, prefix_len))
+      continue;
 
+    assert(*num_unsaved_files < (int)(sizeof(arg_indices)/sizeof(int)));
+    arg_indices[*num_unsaved_files] = arg;
     ++*num_unsaved_files;
   }
 
@@ -130,17 +163,17 @@
   *unsaved_files
     = (struct CXUnsavedFile *)malloc(sizeof(struct CXUnsavedFile) *
                                      *num_unsaved_files);
-  for (arg = start_arg, i = 0; i != *num_unsaved_files; ++i, ++arg) {
+  for (i = 0; i != *num_unsaved_files; ++i) {
     struct CXUnsavedFile *unsaved = *unsaved_files + i;
-    const char *arg_string = argv[arg] + prefix_len;
+    const char *arg_string = argv[arg_indices[i]] + prefix_len;
     int filename_len;
     char *filename;
     char *contents;
     FILE *to_file;
-    const char *semi = strchr(arg_string, ';');
-    if (!semi) {
+    const char *sep = strchr(arg_string, ',');
+    if (!sep) {
       fprintf(stderr,
-              "error: -remap-file=from;to argument is missing semicolon\n");
+              "error: %sfrom:to argument is missing comma\n", opt_name);
       free_remapped_files(*unsaved_files, i);
       *unsaved_files = 0;
       *num_unsaved_files = 0;
@@ -148,10 +181,10 @@
     }
 
     /* Open the file that we're remapping to. */
-    to_file = fopen(semi + 1, "rb");
+    to_file = fopen(sep + 1, "rb");
     if (!to_file) {
       fprintf(stderr, "error: cannot open file %s that we are remapping to\n",
-              semi + 1);
+              sep + 1);
       free_remapped_files(*unsaved_files, i);
       *unsaved_files = 0;
       *num_unsaved_files = 0;
@@ -167,7 +200,7 @@
     contents = (char *)malloc(unsaved->Length + 1);
     if (fread(contents, 1, unsaved->Length, to_file) != unsaved->Length) {
       fprintf(stderr, "error: unexpected %s reading 'to' file %s\n",
-              (feof(to_file) ? "EOF" : "error"), semi + 1);
+              (feof(to_file) ? "EOF" : "error"), sep + 1);
       fclose(to_file);
       free_remapped_files(*unsaved_files, i);
       free(contents);
@@ -182,7 +215,7 @@
     fclose(to_file);
 
     /* Copy the file name that we're remapping from. */
-    filename_len = semi - arg_string;
+    filename_len = sep - arg_string;
     filename = (char *)malloc(filename_len + 1);
     memcpy(filename, arg_string, filename_len);
     filename[filename_len] = 0;
@@ -192,6 +225,48 @@
   return 0;
 }
 
+static int parse_remapped_files(int argc, const char **argv, int start_arg,
+                                struct CXUnsavedFile **unsaved_files,
+                                int *num_unsaved_files) {
+  return parse_remapped_files_with_opt("-remap-file=", argc, argv, start_arg,
+      unsaved_files, num_unsaved_files);
+}
+
+static int parse_remapped_files_with_try(int try_idx,
+                                         int argc, const char **argv,
+                                         int start_arg,
+                                         struct CXUnsavedFile **unsaved_files,
+                                         int *num_unsaved_files) {
+  struct CXUnsavedFile *unsaved_files_no_try_idx;
+  int num_unsaved_files_no_try_idx;
+  struct CXUnsavedFile *unsaved_files_try_idx;
+  int num_unsaved_files_try_idx;
+  int ret;
+  char opt_name[32];
+
+  ret = parse_remapped_files(argc, argv, start_arg,
+      &unsaved_files_no_try_idx, &num_unsaved_files_no_try_idx);
+  if (ret)
+    return ret;
+
+  sprintf(opt_name, "-remap-file-%d=", try_idx);
+  ret = parse_remapped_files_with_opt(opt_name, argc, argv, start_arg,
+      &unsaved_files_try_idx, &num_unsaved_files_try_idx);
+  if (ret)
+    return ret;
+
+  *num_unsaved_files = num_unsaved_files_no_try_idx + num_unsaved_files_try_idx;
+  *unsaved_files
+    = (struct CXUnsavedFile *)realloc(unsaved_files_no_try_idx,
+                                      sizeof(struct CXUnsavedFile) *
+                                        *num_unsaved_files);
+  memcpy(*unsaved_files + num_unsaved_files_no_try_idx,
+         unsaved_files_try_idx, sizeof(struct CXUnsavedFile) *
+            num_unsaved_files_try_idx);
+  free(unsaved_files_try_idx);
+  return 0;
+}
+
 static const char *parse_comments_schema(int argc, const char **argv) {
   const char *CommentsSchemaArg = "-comments-xml-schema=";
   const char *CommentSchemaFile = NULL;
@@ -467,33 +542,23 @@
   printf("]");
 }
 
-typedef struct {
-  const char *CommentSchemaFile;
+static void ValidateCommentXML(const char *Str, const char *CommentSchemaFile) {
 #ifdef CLANG_HAVE_LIBXML
   xmlRelaxNGParserCtxtPtr RNGParser;
   xmlRelaxNGPtr Schema;
-#endif
-} CommentXMLValidationData;
-
-static void ValidateCommentXML(const char *Str,
-                               CommentXMLValidationData *ValidationData) {
-#ifdef CLANG_HAVE_LIBXML
   xmlDocPtr Doc;
   xmlRelaxNGValidCtxtPtr ValidationCtxt;
   int status;
 
-  if (!ValidationData || !ValidationData->CommentSchemaFile)
+  if (!CommentSchemaFile)
     return;
 
-  if (!ValidationData->RNGParser) {
-    ValidationData->RNGParser =
-        xmlRelaxNGNewParserCtxt(ValidationData->CommentSchemaFile);
-    ValidationData->Schema = xmlRelaxNGParse(ValidationData->RNGParser);
-  }
-  if (!ValidationData->RNGParser) {
+  RNGParser = xmlRelaxNGNewParserCtxt(CommentSchemaFile);
+  if (!RNGParser) {
     printf(" libXMLError");
     return;
   }
+  Schema = xmlRelaxNGParse(RNGParser);
 
   Doc = xmlParseDoc((const xmlChar *) Str);
 
@@ -503,7 +568,7 @@
     return;
   }
 
-  ValidationCtxt = xmlRelaxNGNewValidCtxt(ValidationData->Schema);
+  ValidationCtxt = xmlRelaxNGNewValidCtxt(Schema);
   status = xmlRelaxNGValidateDoc(ValidationCtxt, Doc);
   if (!status)
     printf(" CommentXMLValid");
@@ -515,11 +580,13 @@
 
   xmlRelaxNGFreeValidCtxt(ValidationCtxt);
   xmlFreeDoc(Doc);
+  xmlRelaxNGFree(Schema);
+  xmlRelaxNGFreeParserCtxt(RNGParser);
 #endif
 }
 
 static void PrintCursorComments(CXCursor Cursor,
-                                CommentXMLValidationData *ValidationData) {
+                                const char *CommentSchemaFile) {
   {
     CXString RawComment;
     const char *RawCommentCString;
@@ -550,7 +617,7 @@
         CXString XML;
         XML = clang_FullComment_getAsXML(Comment);
         PrintCXStringWithPrefix("FullCommentAsXML", XML);
-        ValidateCommentXML(clang_getCString(XML), ValidationData);
+        ValidateCommentXML(clang_getCString(XML), CommentSchemaFile);
         clang_disposeString(XML);
       }
 
@@ -572,8 +639,7 @@
   return (int)lhs->col - (int)rhs->col;
 }
 
-static void PrintCursor(CXCursor Cursor,
-                        CommentXMLValidationData *ValidationData) {
+static void PrintCursor(CXCursor Cursor, const char *CommentSchemaFile) {
   CXTranslationUnit TU = clang_Cursor_getTranslationUnit(Cursor);
   if (clang_isInvalid(Cursor.kind)) {
     CXString ks = clang_getCursorKindSpelling(Cursor.kind);
@@ -694,6 +760,8 @@
       printf(" (static)");
     if (clang_CXXMethod_isVirtual(Cursor))
       printf(" (virtual)");
+    if (clang_CXXMethod_isConst(Cursor))
+      printf(" (const)");
     if (clang_CXXMethod_isPureVirtual(Cursor))
       printf(" (pure)");
     if (clang_Cursor_isVariadic(Cursor))
@@ -792,7 +860,7 @@
         PrintRange(RefNameRange, "RefName");
     }
 
-    PrintCursorComments(Cursor, ValidationData);
+    PrintCursorComments(Cursor, CommentSchemaFile);
 
     {
       unsigned PropAttrs = clang_Cursor_getObjCPropertyAttributes(Cursor, 0);
@@ -909,7 +977,6 @@
         PrintExtent(out, start_line, start_column, end_line, end_column);
         fprintf(out, " with \"%s\"\n", clang_getCString(insertion_text));
       }
-      break;
     }
     clang_disposeString(insertion_text);
   }
@@ -962,7 +1029,7 @@
 typedef struct {
   CXTranslationUnit TU;
   enum CXCursorKind *Filter;
-  CommentXMLValidationData ValidationData;
+  const char *CommentSchemaFile;
 } VisitorData;
 
 
@@ -976,7 +1043,7 @@
     clang_getSpellingLocation(Loc, 0, &line, &column, 0);
     printf("// %s: %s:%d:%d: ", FileCheckPrefix,
            GetCursorSource(Cursor), line, column);
-    PrintCursor(Cursor, &Data->ValidationData);
+    PrintCursor(Cursor, Data->CommentSchemaFile);
     PrintCursorExtent(Cursor);
     if (clang_isDeclaration(Cursor.kind)) {
       enum CX_CXXAccessSpecifier access = clang_getCXXAccessSpecifier(Cursor);
@@ -1046,7 +1113,7 @@
       } else if (Ref.kind != CXCursor_FunctionDecl) {
         printf("// %s: %s:%d:%d: ", FileCheckPrefix, GetCursorSource(Ref),
                curLine, curColumn);
-        PrintCursor(Ref, &Data->ValidationData);
+        PrintCursor(Ref, Data->CommentSchemaFile);
         printf("\n");
       }
     }
@@ -1189,11 +1256,11 @@
     }
     /* Print the argument types if they exist. */
     {
-      int numArgs = clang_Cursor_getNumArguments(cursor);
-      if (numArgs != -1 && numArgs != 0) {
+      int NumArgs = clang_Cursor_getNumArguments(cursor);
+      if (NumArgs != -1 && NumArgs != 0) {
         int i;
         printf(" [args=");
-        for (i = 0; i < numArgs; ++i) {
+        for (i = 0; i < NumArgs; ++i) {
           CXType T = clang_getCursorType(clang_Cursor_getArgument(cursor, i));
           if (T.kind != CXType_Invalid) {
             PrintTypeAndTypeKind(T, " [%s] [%s]");
@@ -1202,8 +1269,30 @@
         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. */
+    {
+      CXType PT = clang_getPointeeType(T);
+      if (PT.kind != CXType_Invalid) {
+        PrintTypeAndTypeKind(PT, " [pointeetype=%s] [pointeekind=%s]");
+      }
+    }
 
     printf("\n");
   }
@@ -1235,18 +1324,25 @@
   }
   /* Print the record field offset if applicable. */
   {
-    const char *FieldName = clang_getCString(clang_getCursorSpelling(cursor));
+    CXString FieldSpelling = clang_getCursorSpelling(cursor);
+    const char *FieldName = clang_getCString(FieldSpelling);
     /* recurse to get the root anonymous record parent */
     CXCursor Parent, Root;
-    if (clang_getCursorKind(cursor) == CXCursor_FieldDecl ) {
-      const char *RootParentName;
-      Root = Parent = p;
+    if (clang_getCursorKind(cursor) == CXCursor_FieldDecl) {
+      CXString RootParentSpelling;
+      const char *RootParentName = 0;
+      Parent = p;
       do {
+        if (RootParentName != 0)
+          clang_disposeString(RootParentSpelling);
+
         Root = Parent;
-        RootParentName = clang_getCString(clang_getCursorSpelling(Root));
+        RootParentSpelling = clang_getCursorSpelling(Root);
+        RootParentName = clang_getCString(RootParentSpelling);
         Parent = clang_getCursorSemanticParent(Root);
-      } while ( clang_getCursorType(Parent).kind == CXType_Record &&
-                !strcmp(RootParentName, "") );
+      } while (clang_getCursorType(Parent).kind == CXType_Record &&
+               !strcmp(RootParentName, ""));
+      clang_disposeString(RootParentSpelling);
       /* if RootParentName is "", record is anonymous. */
       {
         long long Offset = clang_Type_getOffsetOf(clang_getCursorType(Root),
@@ -1254,6 +1350,7 @@
         printf(" [offsetof=%lld]", Offset);
       }
     }
+    clang_disposeString(FieldSpelling);
   }
   /* Print if its a bitfield */
   {
@@ -1323,11 +1420,7 @@
 
     Data.TU = TU;
     Data.Filter = ck;
-    Data.ValidationData.CommentSchemaFile = CommentSchemaFile;
-#ifdef CLANG_HAVE_LIBXML
-    Data.ValidationData.RNGParser = NULL;
-    Data.ValidationData.Schema = NULL;
-#endif
+    Data.CommentSchemaFile = CommentSchemaFile;
     clang_visitChildren(clang_getTranslationUnitCursor(TU), Visitor, &Data);
   }
 
@@ -1372,8 +1465,9 @@
   const char *CommentSchemaFile;
   struct CXUnsavedFile *unsaved_files = 0;
   int num_unsaved_files = 0;
+  enum CXErrorCode Err;
   int result;
-  
+
   Idx = clang_createIndex(/* excludeDeclsFromPCH */
                           (!strcmp(filter, "local") || 
                            !strcmp(filter, "local-display"))? 1 : 0,
@@ -1389,13 +1483,14 @@
     return -1;
   }
 
-  TU = clang_parseTranslationUnit(Idx, 0,
-                                  argv + num_unsaved_files,
-                                  argc - num_unsaved_files,
-                                  unsaved_files, num_unsaved_files, 
-                                  getDefaultParsingOptions());
-  if (!TU) {
+  Err = clang_parseTranslationUnit2(Idx, 0,
+                                    argv + num_unsaved_files,
+                                    argc - num_unsaved_files,
+                                    unsaved_files, num_unsaved_files,
+                                    getDefaultParsingOptions(), &TU);
+  if (Err != CXError_Success) {
     fprintf(stderr, "Unable to load translation unit!\n");
+    describeLibclangFailure(Err);
     free_remapped_files(unsaved_files, num_unsaved_files);
     clang_disposeIndex(Idx);
     return 1;
@@ -1415,7 +1510,9 @@
   CXTranslationUnit TU;
   struct CXUnsavedFile *unsaved_files = 0;
   int num_unsaved_files = 0;
-  int result;
+  int compiler_arg_idx = 0;
+  enum CXErrorCode Err;
+  int result, i;
   int trial;
   int remap_after_trial = 0;
   char *endptr = 0;
@@ -1428,15 +1525,25 @@
     clang_disposeIndex(Idx);
     return -1;
   }
+
+  for (i = 0; i < argc; ++i) {
+    if (strcmp(argv[i], "--") == 0)
+      break;
+  }
+  if (i < argc)
+    compiler_arg_idx = i+1;
+  if (num_unsaved_files > compiler_arg_idx)
+    compiler_arg_idx = num_unsaved_files;
   
   /* Load the initial translation unit -- we do this without honoring remapped
    * files, so that we have a way to test results after changing the source. */
-  TU = clang_parseTranslationUnit(Idx, 0,
-                                  argv + num_unsaved_files,
-                                  argc - num_unsaved_files,
-                                  0, 0, getDefaultParsingOptions());
-  if (!TU) {
+  Err = clang_parseTranslationUnit2(Idx, 0,
+                                    argv + compiler_arg_idx,
+                                    argc - compiler_arg_idx,
+                                    0, 0, getDefaultParsingOptions(), &TU);
+  if (Err != CXError_Success) {
     fprintf(stderr, "Unable to load translation unit!\n");
+    describeLibclangFailure(Err);
     free_remapped_files(unsaved_files, num_unsaved_files);
     clang_disposeIndex(Idx);
     return 1;
@@ -1451,11 +1558,22 @@
   }
 
   for (trial = 0; trial < trials; ++trial) {
-    if (clang_reparseTranslationUnit(TU,
-                             trial >= remap_after_trial ? num_unsaved_files : 0,
-                             trial >= remap_after_trial ? unsaved_files : 0,
-                                     clang_defaultReparseOptions(TU))) {
+    free_remapped_files(unsaved_files, num_unsaved_files);
+    if (parse_remapped_files_with_try(trial, argc, argv, 0,
+                                      &unsaved_files, &num_unsaved_files)) {
+      clang_disposeTranslationUnit(TU);
+      clang_disposeIndex(Idx);
+      return -1;
+    }
+
+    Err = clang_reparseTranslationUnit(
+        TU,
+        trial >= remap_after_trial ? num_unsaved_files : 0,
+        trial >= remap_after_trial ? unsaved_files : 0,
+        clang_defaultReparseOptions(TU));
+    if (Err != CXError_Success) {
       fprintf(stderr, "Unable to reparse translation unit!\n");
+      describeLibclangFailure(Err);
       clang_disposeTranslationUnit(TU);
       free_remapped_files(unsaved_files, num_unsaved_files);
       clang_disposeIndex(Idx);
@@ -1669,7 +1787,8 @@
   return 0;
 }
 
-void print_completion_string(CXCompletionString completion_string, FILE *file) {
+static void print_completion_string(CXCompletionString completion_string,
+                                    FILE *file) {
   int I, N;
 
   N = clang_getNumCompletionChunks(completion_string);
@@ -1703,9 +1822,8 @@
 
 }
 
-void print_completion_result(CXCompletionResult *completion_result,
-                             CXClientData client_data) {
-  FILE *file = (FILE *)client_data;
+static void print_completion_result(CXCompletionResult *completion_result,
+                                    FILE *file) {
   CXString ks = clang_getCursorKindSpelling(completion_result->CursorKind);
   unsigned annotationCount;
   enum CXCursorKind ParentKind;
@@ -1877,7 +1995,8 @@
   struct CXUnsavedFile *unsaved_files = 0;
   int num_unsaved_files = 0;
   CXCodeCompleteResults *results = 0;
-  CXTranslationUnit TU = 0;
+  enum CXErrorCode Err;
+  CXTranslationUnit TU;
   unsigned I, Repeats = 1;
   unsigned completionOptions = clang_defaultCodeCompleteOptions();
   
@@ -1902,21 +2021,27 @@
   
   if (getenv("CINDEXTEST_EDITING"))
     Repeats = 5;
-  
-  TU = clang_parseTranslationUnit(CIdx, 0,
-                                  argv + num_unsaved_files + 2,
-                                  argc - num_unsaved_files - 2,
-                                  0, 0, getDefaultParsingOptions());
-  if (!TU) {
+
+  Err = clang_parseTranslationUnit2(CIdx, 0,
+                                    argv + num_unsaved_files + 2,
+                                    argc - num_unsaved_files - 2,
+                                    0, 0, getDefaultParsingOptions(), &TU);
+  if (Err != CXError_Success) {
     fprintf(stderr, "Unable to load translation unit!\n");
+    describeLibclangFailure(Err);
     return 1;
   }
 
-  if (clang_reparseTranslationUnit(TU, 0, 0, clang_defaultReparseOptions(TU))) {
+  Err = clang_reparseTranslationUnit(TU, 0, 0,
+                                     clang_defaultReparseOptions(TU));
+
+  if (Err != CXError_Success) {
     fprintf(stderr, "Unable to reparse translation init!\n");
+    describeLibclangFailure(Err);
+    clang_disposeTranslationUnit(TU);
     return 1;
   }
-  
+
   for (I = 0; I != Repeats; ++I) {
     results = clang_codeCompleteAt(TU, filename, line, column,
                                    unsaved_files, num_unsaved_files,
@@ -2003,6 +2128,7 @@
   int errorCode;
   struct CXUnsavedFile *unsaved_files = 0;
   int num_unsaved_files = 0;
+  enum CXErrorCode Err;
   CXTranslationUnit TU;
   CXCursor Cursor;
   CursorSourceLocation *Locations = 0;
@@ -2036,15 +2162,15 @@
   /* Parse the translation unit. When we're testing clang_getCursor() after
      reparsing, don't remap unsaved files until the second parse. */
   CIdx = clang_createIndex(1, 1);
-  TU = clang_parseTranslationUnit(CIdx, argv[argc - 1],
-                                  argv + num_unsaved_files + 1 + NumLocations,
-                                  argc - num_unsaved_files - 2 - NumLocations,
-                                  unsaved_files,
-                                  Repeats > 1? 0 : num_unsaved_files,
-                                  getDefaultParsingOptions());
-                                                 
-  if (!TU) {
+  Err = clang_parseTranslationUnit2(CIdx, argv[argc - 1],
+                                   argv + num_unsaved_files + 1 + NumLocations,
+                                   argc - num_unsaved_files - 2 - NumLocations,
+                                   unsaved_files,
+                                   Repeats > 1? 0 : num_unsaved_files,
+                                   getDefaultParsingOptions(), &TU);
+  if (Err != CXError_Success) {
     fprintf(stderr, "unable to parse input\n");
+    describeLibclangFailure(Err);
     return -1;
   }
 
@@ -2052,11 +2178,14 @@
     return -1;
 
   for (I = 0; I != Repeats; ++I) {
-    if (Repeats > 1 &&
-        clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files, 
-                                     clang_defaultReparseOptions(TU))) {
-      clang_disposeTranslationUnit(TU);
-      return 1;
+    if (Repeats > 1) {
+      Err = clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,
+                                         clang_defaultReparseOptions(TU));
+      if (Err != CXError_Success) {
+        describeLibclangFailure(Err);
+        clang_disposeTranslationUnit(TU);
+        return 1;
+      }
     }
 
     if (checkForErrors(TU) != 0)
@@ -2101,7 +2230,8 @@
         }
         clang_disposeString(Spelling);
         if (clang_Cursor_getObjCSelectorIndex(Cursor) != -1)
-          printf(" Selector index=%d",clang_Cursor_getObjCSelectorIndex(Cursor));
+          printf(" Selector index=%d",
+                 clang_Cursor_getObjCSelectorIndex(Cursor));
         if (clang_Cursor_isDynamicCall(Cursor))
           printf(" Dynamic-call");
         if (Cursor.kind == CXCursor_ObjCMessageExpr) {
@@ -2121,9 +2251,9 @@
             astFilename = clang_getFileName(astFile);
             name = clang_Module_getFullName(mod);
             numHeaders = clang_Module_getNumTopLevelHeaders(TU, mod);
-            printf(" ModuleName=%s (%s) Headers(%d):",
+            printf(" ModuleName=%s (%s) system=%d Headers(%d):",
                    clang_getCString(name), clang_getCString(astFilename),
-                   numHeaders);
+                   clang_Module_isSystem(mod), numHeaders);
             clang_disposeString(name);
             clang_disposeString(astFilename);
             for (i = 0; i < numHeaders; ++i) {
@@ -2169,6 +2299,7 @@
   int errorCode;
   struct CXUnsavedFile *unsaved_files = 0;
   int num_unsaved_files = 0;
+  enum CXErrorCode Err;
   CXTranslationUnit TU;
   CXCursor Cursor;
   CursorSourceLocation *Locations = 0;
@@ -2202,15 +2333,16 @@
   /* Parse the translation unit. When we're testing clang_getCursor() after
      reparsing, don't remap unsaved files until the second parse. */
   CIdx = clang_createIndex(1, 1);
-  TU = clang_parseTranslationUnit(CIdx, argv[argc - 1],
-                                  argv + num_unsaved_files + 1 + NumLocations,
-                                  argc - num_unsaved_files - 2 - NumLocations,
-                                  unsaved_files,
-                                  Repeats > 1? 0 : num_unsaved_files,
-                                  getDefaultParsingOptions());
-                                                 
-  if (!TU) {
+  Err = clang_parseTranslationUnit2(CIdx, argv[argc - 1],
+                                    argv + num_unsaved_files + 1 + NumLocations,
+                                    argc - num_unsaved_files - 2 - NumLocations,
+                                    unsaved_files,
+                                    Repeats > 1? 0 : num_unsaved_files,
+                                    getDefaultParsingOptions(), &TU);
+  if (Err != CXError_Success) {
     fprintf(stderr, "unable to parse input\n");
+    describeLibclangFailure(Err);
+    clang_disposeTranslationUnit(TU);
     return -1;
   }
 
@@ -2218,11 +2350,14 @@
     return -1;
 
   for (I = 0; I != Repeats; ++I) {
-    if (Repeats > 1 &&
-        clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files, 
-                                     clang_defaultReparseOptions(TU))) {
-      clang_disposeTranslationUnit(TU);
-      return 1;
+    if (Repeats > 1) {
+      Err = clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,
+                                         clang_defaultReparseOptions(TU));
+      if (Err != CXError_Success) {
+        describeLibclangFailure(Err);
+        clang_disposeTranslationUnit(TU);
+        return 1;
+      }
     }
 
     if (checkForErrors(TU) != 0)
@@ -2273,6 +2408,7 @@
   CXIndex CIdx;
   struct CXUnsavedFile *unsaved_files = 0;
   int num_unsaved_files = 0;
+  enum CXErrorCode Err;
   CXTranslationUnit TU;
   const char **Filenames = 0;
   unsigned NumFilenames = 0;
@@ -2302,15 +2438,17 @@
   /* Parse the translation unit. When we're testing clang_getCursor() after
      reparsing, don't remap unsaved files until the second parse. */
   CIdx = clang_createIndex(1, 1);
-  TU = clang_parseTranslationUnit(CIdx, argv[argc - 1],
-                                  argv + num_unsaved_files + 1 + NumFilenames,
-                                  argc - num_unsaved_files - 2 - NumFilenames,
-                                  unsaved_files,
-                                  Repeats > 1? 0 : num_unsaved_files,
-                                  getDefaultParsingOptions());
+  Err = clang_parseTranslationUnit2(
+      CIdx, argv[argc - 1],
+      argv + num_unsaved_files + 1 + NumFilenames,
+      argc - num_unsaved_files - 2 - NumFilenames,
+      unsaved_files,
+      Repeats > 1 ? 0 : num_unsaved_files, getDefaultParsingOptions(), &TU);
 
-  if (!TU) {
+  if (Err != CXError_Success) {
     fprintf(stderr, "unable to parse input\n");
+    describeLibclangFailure(Err);
+    clang_disposeTranslationUnit(TU);
     return -1;
   }
 
@@ -2318,11 +2456,14 @@
     return -1;
 
   for (I = 0; I != Repeats; ++I) {
-    if (Repeats > 1 &&
-        clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,
-                                     clang_defaultReparseOptions(TU))) {
-      clang_disposeTranslationUnit(TU);
-      return 1;
+    if (Repeats > 1) {
+      Err = clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,
+                                         clang_defaultReparseOptions(TU));
+      if (Err != CXError_Success) {
+        describeLibclangFailure(Err);
+        clang_disposeTranslationUnit(TU);
+        return 1;
+      }
     }
 
     if (checkForErrors(TU) != 0)
@@ -2390,6 +2531,11 @@
   p->filenames[p->num_files++] = strdup(file);
 }
 
+typedef struct IndexDataStringList_ {
+  struct IndexDataStringList_ *next;
+  char data[1]; /* Dynamically sized. */
+} IndexDataStringList;
+
 typedef struct {
   const char *check_prefix;
   int first_check_printed;
@@ -2397,8 +2543,20 @@
   int abort;
   const char *main_filename;
   ImportedASTFilesData *importedASTs;
+  IndexDataStringList *strings;
+  CXTranslationUnit TU;
 } IndexData;
 
+static void free_client_data(IndexData *index_data) {
+  IndexDataStringList *node = index_data->strings;
+  while (node) {
+    IndexDataStringList *next = node->next;
+    free(node);
+    node = next;
+  }
+  index_data->strings = NULL;
+}
+
 static void printCheck(IndexData *data) {
   if (data->check_prefix) {
     if (data->first_check_printed) {
@@ -2459,8 +2617,11 @@
   }
 }
 
-static CXIdxClientContainer makeClientContainer(const CXIdxEntityInfo *info,
+static CXIdxClientContainer makeClientContainer(CXClientData *client_data,
+                                                const CXIdxEntityInfo *info,
                                                 CXIdxLoc loc) {
+  IndexData *index_data;
+  IndexDataStringList *node;
   const char *name;
   char *newStr;
   CXIdxClientFile file;
@@ -2471,10 +2632,18 @@
     name = "<anon-tag>";
 
   clang_indexLoc_getFileLocation(loc, &file, 0, &line, &column, 0);
-  /* FIXME: free these.*/
-  newStr = (char *)malloc(strlen(name) +
-                          digitCount(line) + digitCount(column) + 3);
+
+  node =
+      (IndexDataStringList *)malloc(sizeof(IndexDataStringList) + strlen(name) +
+                                    digitCount(line) + digitCount(column) + 2);
+  newStr = node->data;
   sprintf(newStr, "%s:%d:%d", name, line, column);
+
+  /* Remember string so it can be freed later. */
+  index_data = (IndexData *)client_data;
+  node->next = index_data->strings;
+  index_data->strings = node;
+
   return (CXIdxClientContainer)newStr;
 }
 
@@ -2645,6 +2814,7 @@
 static CXIdxClientFile index_ppIncludedFile(CXClientData client_data,
                                             const CXIdxIncludedFileInfo *info) {
   IndexData *index_data;
+  CXModule Mod;
   index_data = (IndexData *)client_data;
   printCheck(index_data);
 
@@ -2653,8 +2823,18 @@
   printf(" | name: \"%s\"", info->filename);
   printf(" | hash loc: ");
   printCXIndexLoc(info->hashLoc, client_data);
-  printf(" | isImport: %d | isAngled: %d | isModule: %d\n",
+  printf(" | isImport: %d | isAngled: %d | isModule: %d",
          info->isImport, info->isAngled, info->isModuleImport);
+  
+  Mod = clang_getModuleForFile(index_data->TU, (CXFile)info->file);
+  if (Mod) {
+    CXString str = clang_Module_getFullName(Mod);
+    const char *cstr = clang_getCString(str);
+    printf(" | module: %s", cstr);
+    clang_disposeString(str);
+  }
+
+  printf("\n");
 
   return (CXIdxClientFile)info->file;
 }
@@ -2688,8 +2868,8 @@
   return (CXIdxClientFile)info->file;
 }
 
-static CXIdxClientContainer index_startedTranslationUnit(CXClientData client_data,
-                                                   void *reserved) {
+static CXIdxClientContainer
+index_startedTranslationUnit(CXClientData client_data, void *reserved) {
   IndexData *index_data;
   index_data = (IndexData *)client_data;
   printCheck(index_data);
@@ -2790,13 +2970,15 @@
   }
 
   if (info->declAsContainer)
-    clang_index_setClientContainer(info->declAsContainer,
-                              makeClientContainer(info->entityInfo, info->loc));
+    clang_index_setClientContainer(
+        info->declAsContainer,
+        makeClientContainer(client_data, info->entityInfo, info->loc));
 }
 
 static void index_indexEntityReference(CXClientData client_data,
                                        const CXIdxEntityRefInfo *info) {
-  printEntityInfo("[indexEntityReference]", client_data, info->referencedEntity);
+  printEntityInfo("[indexEntityReference]", client_data,
+                  info->referencedEntity);
   printf(" | cursor: ");
   PrintCursor(info->cursor, NULL);
   printf(" | loc: ");
@@ -2861,15 +3043,21 @@
   index_data.abort = 0;
   index_data.main_filename = "";
   index_data.importedASTs = importedASTs;
+  index_data.strings = NULL;
+  index_data.TU = NULL;
 
   index_opts = getIndexOptions();
   result = clang_indexSourceFile(idxAction, &index_data,
                                  &IndexCB,sizeof(IndexCB), index_opts,
                                  0, args, num_args, 0, 0, 0,
                                  getDefaultParsingOptions());
+  if (result != CXError_Success)
+    describeLibclangFailure(result);
+
   if (index_data.fail_for_error)
     result = -1;
 
+  free_client_data(&index_data);
   return result;
 }
 
@@ -2892,6 +3080,8 @@
   index_data.abort = 0;
   index_data.main_filename = "";
   index_data.importedASTs = importedASTs;
+  index_data.strings = NULL;
+  index_data.TU = TU;
 
   index_opts = getIndexOptions();
   result = clang_indexTranslationUnit(idxAction, &index_data,
@@ -2901,6 +3091,7 @@
     result = -1;
 
   clang_disposeTranslationUnit(TU);
+  free_client_data(&index_data);
   return result;
 }
 
@@ -3118,6 +3309,8 @@
   CXSourceLocation startLoc, endLoc;
   CXFile file = 0;
   CXCursor *cursors = 0;
+  CXSourceRangeList *skipped_ranges = 0;
+  enum CXErrorCode Err;
   unsigned i;
 
   input += strlen("-test-annotate-tokens=");
@@ -3131,14 +3324,15 @@
   }
 
   CIdx = clang_createIndex(0, 1);
-  TU = clang_parseTranslationUnit(CIdx, argv[argc - 1],
-                                  argv + num_unsaved_files + 2,
-                                  argc - num_unsaved_files - 3,
-                                  unsaved_files,
-                                  num_unsaved_files,
-                                  getDefaultParsingOptions());
-  if (!TU) {
+  Err = clang_parseTranslationUnit2(CIdx, argv[argc - 1],
+                                    argv + num_unsaved_files + 2,
+                                    argc - num_unsaved_files - 3,
+                                    unsaved_files,
+                                    num_unsaved_files,
+                                    getDefaultParsingOptions(), &TU);
+  if (Err != CXError_Success) {
     fprintf(stderr, "unable to parse input\n");
+    describeLibclangFailure(Err);
     clang_disposeIndex(CIdx);
     free(filename);
     free_remapped_files(unsaved_files, num_unsaved_files);
@@ -3153,9 +3347,11 @@
 
   if (getenv("CINDEXTEST_EDITING")) {
     for (i = 0; i < 5; ++i) {
-      if (clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,
-                                       clang_defaultReparseOptions(TU))) {
+      Err = clang_reparseTranslationUnit(TU, num_unsaved_files, unsaved_files,
+                                         clang_defaultReparseOptions(TU));
+      if (Err != CXError_Success) {
         fprintf(stderr, "Unable to reparse translation unit!\n");
+        describeLibclangFailure(Err);
         errorCode = -1;
         goto teardown;
       }
@@ -3206,6 +3402,19 @@
     goto teardown;
   }
 
+  skipped_ranges = clang_getSkippedRanges(TU, file);
+  for (i = 0; i != skipped_ranges->count; ++i) {
+    unsigned start_line, start_column, end_line, end_column;
+    clang_getSpellingLocation(clang_getRangeStart(skipped_ranges->ranges[i]),
+                              0, &start_line, &start_column, 0);
+    clang_getSpellingLocation(clang_getRangeEnd(skipped_ranges->ranges[i]),
+                              0, &end_line, &end_column, 0);
+    printf("Skipping: ");
+    PrintExtent(stdout, start_line, start_column, end_line, end_column);
+    printf("\n");
+  }
+  clang_disposeSourceRangeList(skipped_ranges);
+
   for (i = 0; i != num_tokens; ++i) {
     const char *kind = "<unknown>";
     CXString spelling = clang_getTokenSpelling(TU, tokens[i]);
@@ -3506,6 +3715,7 @@
   CXTranslationUnit TU;
   struct CXUnsavedFile *unsaved_files = 0;
   int num_unsaved_files = 0;
+  enum CXErrorCode Err;
   int result = 0;
   
   Idx = clang_createIndex(/* excludeDeclsFromPCH */1, /* displayDiagnostics=*/1);
@@ -3514,18 +3724,19 @@
     clang_disposeIndex(Idx);
     return -1;
   }
-  
-  TU = clang_parseTranslationUnit(Idx, 0,
-                                  argv + num_unsaved_files,
-                                  argc - num_unsaved_files,
-                                  unsaved_files,
-                                  num_unsaved_files,
-                                  CXTranslationUnit_Incomplete |
-                                  CXTranslationUnit_DetailedPreprocessingRecord|
-                                    CXTranslationUnit_ForSerialization);
-  if (!TU) {
+
+  Err = clang_parseTranslationUnit2(
+      Idx, 0, argv + num_unsaved_files, argc - num_unsaved_files,
+      unsaved_files, num_unsaved_files,
+      CXTranslationUnit_Incomplete |
+          CXTranslationUnit_DetailedPreprocessingRecord |
+          CXTranslationUnit_ForSerialization,
+      &TU);
+  if (Err != CXError_Success) {
     fprintf(stderr, "Unable to load translation unit!\n");
+    describeLibclangFailure(Err);
     free_remapped_files(unsaved_files, num_unsaved_files);
+    clang_disposeTranslationUnit(TU);
     clang_disposeIndex(Idx);
     return 1;
   }
@@ -3697,6 +3908,7 @@
     clang_disposeString(FileName);
     clang_disposeString(DiagSpelling);
     clang_disposeString(DiagOption);
+    clang_disposeString(DiagCat);
   }  
 }
 
@@ -3721,6 +3933,11 @@
   return 0;
 }
 
+static int perform_print_build_session_timestamp(void) {
+  printf("%lld\n", clang_getBuildSessionTimestamp());
+  return 0;
+}
+
 /******************************************************************************/
 /* Command line processing.                                                   */
 /******************************************************************************/
@@ -3777,6 +3994,8 @@
   fprintf(stderr,
     "       c-index-test -compilation-db [lookup <filename>] database\n");
   fprintf(stderr,
+    "       c-index-test -print-build-session-timestamp\n");
+  fprintf(stderr,
     "       c-index-test -read-diagnostics <file>\n\n");
   fprintf(stderr,
     " <symbol filter> values:\n%s",
@@ -3876,6 +4095,8 @@
     return write_pch_file(argv[2], argc - 3, argv + 3);
   else if (argc > 2 && strcmp(argv[1], "-compilation-db") == 0)
     return perform_test_compilation_db(argv[argc-1], argc - 3, argv + 2);
+  else if (argc == 2 && strcmp(argv[1], "-print-build-session-timestamp") == 0)
+    return perform_print_build_session_timestamp();
 
   print_usage();
   return 1;
@@ -3895,14 +4116,20 @@
 void thread_runner(void *client_data_v) {
   thread_info *client_data = client_data_v;
   client_data->result = cindextest_main(client_data->argc, client_data->argv);
-#ifdef __CYGWIN__
-  fflush(stdout);  /* stdout is not flushed on Cygwin. */
-#endif
+}
+
+static void flush_atexit(void) {
+  /* stdout, and surprisingly even stderr, are not always flushed on process
+   * and thread exit, particularly when the system is under heavy load. */
+  fflush(stdout);
+  fflush(stderr);
 }
 
 int main(int argc, const char **argv) {
   thread_info client_data;
 
+  atexit(flush_atexit);
+
 #ifdef CLANG_HAVE_LIBXML
   LIBXML_TEST_VERSION
 #endif
diff --git a/tools/clang-check/CMakeLists.txt b/tools/clang-check/CMakeLists.txt
index 2070de3..8b9cd88 100644
--- a/tools/clang-check/CMakeLists.txt
+++ b/tools/clang-check/CMakeLists.txt
@@ -1,9 +1,6 @@
 set(LLVM_LINK_COMPONENTS
-  ${LLVM_TARGETS_TO_BUILD}
-  asmparser
-  bitreader
-  support
-  mc
+  Option
+  Support
   )
 
 add_clang_executable(clang-check
@@ -11,10 +8,13 @@
   )
 
 target_link_libraries(clang-check
-  clangTooling
+  clangAST
   clangBasic
+  clangDriver
+  clangFrontend
   clangRewriteFrontend
   clangStaticAnalyzerFrontend
+  clangTooling
   )
 
 install(TARGETS clang-check
diff --git a/tools/clang-check/ClangCheck.cpp b/tools/clang-check/ClangCheck.cpp
index 701db52..cc8d43c 100644
--- a/tools/clang-check/ClangCheck.cpp
+++ b/tools/clang-check/ClangCheck.cpp
@@ -20,20 +20,18 @@
 #include "clang/Driver/Options.h"
 #include "clang/Frontend/ASTConsumers.h"
 #include "clang/Frontend/CompilerInstance.h"
-#include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
 #include "clang/Rewrite/Frontend/FixItRewriter.h"
 #include "clang/Rewrite/Frontend/FrontendActions.h"
+#include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
 #include "clang/Tooling/CommonOptionsParser.h"
 #include "clang/Tooling/Tooling.h"
-#include "llvm/Support/CommandLine.h"
+#include "llvm/Option/OptTable.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Signals.h"
-#include "llvm/Option/OptTable.h"
 
 using namespace clang::driver;
 using namespace clang::tooling;
 using namespace llvm;
-using namespace llvm::opt;
 
 static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
 static cl::extrahelp MoreHelp(
@@ -51,34 +49,42 @@
     "\n"
 );
 
-static OwningPtr<OptTable> Options(createDriverOptTable());
-static cl::opt<bool> ASTDump(
-    "ast-dump",
-    cl::desc(Options->getOptionHelpText(options::OPT_ast_dump)));
-static cl::opt<bool> ASTList(
-    "ast-list",
-    cl::desc(Options->getOptionHelpText(options::OPT_ast_list)));
-static cl::opt<bool> ASTPrint(
-    "ast-print",
-    cl::desc(Options->getOptionHelpText(options::OPT_ast_print)));
+static cl::OptionCategory ClangCheckCategory("clang-check options");
+static std::unique_ptr<opt::OptTable> Options(createDriverOptTable());
+static cl::opt<bool>
+ASTDump("ast-dump", cl::desc(Options->getOptionHelpText(options::OPT_ast_dump)),
+        cl::cat(ClangCheckCategory));
+static cl::opt<bool>
+ASTList("ast-list", cl::desc(Options->getOptionHelpText(options::OPT_ast_list)),
+        cl::cat(ClangCheckCategory));
+static cl::opt<bool>
+ASTPrint("ast-print",
+         cl::desc(Options->getOptionHelpText(options::OPT_ast_print)),
+         cl::cat(ClangCheckCategory));
 static cl::opt<std::string> ASTDumpFilter(
     "ast-dump-filter",
-    cl::desc(Options->getOptionHelpText(options::OPT_ast_dump_filter)));
-static cl::opt<bool> Analyze(
-    "analyze",
-    cl::desc(Options->getOptionHelpText(options::OPT_analyze)));
+    cl::desc(Options->getOptionHelpText(options::OPT_ast_dump_filter)),
+    cl::cat(ClangCheckCategory));
+static cl::opt<bool>
+Analyze("analyze", cl::desc(Options->getOptionHelpText(options::OPT_analyze)),
+        cl::cat(ClangCheckCategory));
 
-static cl::opt<bool> Fixit(
-    "fixit",
-    cl::desc(Options->getOptionHelpText(options::OPT_fixit)));
+static cl::opt<bool>
+Fixit("fixit", cl::desc(Options->getOptionHelpText(options::OPT_fixit)),
+      cl::cat(ClangCheckCategory));
 static cl::opt<bool> FixWhatYouCan(
     "fix-what-you-can",
-    cl::desc(Options->getOptionHelpText(options::OPT_fix_what_you_can)));
+    cl::desc(Options->getOptionHelpText(options::OPT_fix_what_you_can)),
+    cl::cat(ClangCheckCategory));
 
-static cl::list<std::string> ArgsAfter("extra-arg",
-    cl::desc("Additional argument to append to the compiler command line"));
-static cl::list<std::string> ArgsBefore("extra-arg-before",
-    cl::desc("Additional argument to prepend to the compiler command line"));
+static cl::list<std::string> ArgsAfter(
+    "extra-arg",
+    cl::desc("Additional argument to append to the compiler command line"),
+    cl::cat(ClangCheckCategory));
+static cl::list<std::string> ArgsBefore(
+    "extra-arg-before",
+    cl::desc("Additional argument to prepend to the compiler command line"),
+    cl::cat(ClangCheckCategory));
 
 namespace {
 
@@ -90,7 +96,7 @@
     FixWhatYouCan = ::FixWhatYouCan;
   }
 
-  std::string RewriteFilename(const std::string& filename, int &fd) {
+  std::string RewriteFilename(const std::string& filename, int &fd) override {
     assert(llvm::sys::path::is_absolute(filename) &&
            "clang-fixit expects absolute paths only.");
 
@@ -117,15 +123,15 @@
       : clang::FixItRewriter(Diags, SourceMgr, LangOpts, FixItOpts) {
   }
 
-  virtual bool IncludeInDiagnosticCounts() const { return false; }
+  bool IncludeInDiagnosticCounts() const override { return false; }
 };
 
 /// \brief Subclasses \c clang::FixItAction so that we can install the custom
 /// \c FixItRewriter.
 class FixItAction : public clang::FixItAction {
 public:
-  virtual bool BeginSourceFileAction(clang::CompilerInstance& CI,
-                                     StringRef Filename) {
+  bool BeginSourceFileAction(clang::CompilerInstance& CI,
+                             StringRef Filename) override {
     FixItOpts.reset(new FixItOptions);
     Rewriter.reset(new FixItRewriter(CI.getDiagnostics(), CI.getSourceManager(),
                                      CI.getLangOpts(), FixItOpts.get()));
@@ -146,7 +152,7 @@
   }
 
   virtual CommandLineArguments
-  Adjust(const CommandLineArguments &Args) LLVM_OVERRIDE {
+  Adjust(const CommandLineArguments &Args) override {
     CommandLineArguments Return(Args);
 
     CommandLineArguments::iterator I;
@@ -187,7 +193,7 @@
 
 int main(int argc, const char **argv) {
   llvm::sys::PrintStackTraceOnErrorSignal();
-  CommonOptionsParser OptionsParser(argc, argv);
+  CommonOptionsParser OptionsParser(argc, argv, ClangCheckCategory);
   ClangTool Tool(OptionsParser.getCompilations(),
                  OptionsParser.getSourcePathList());
 
@@ -209,7 +215,7 @@
         Analyze ? "--analyze" : "-fsyntax-only", InsertAdjuster::BEGIN));
 
   clang_check::ClangCheckActionFactory CheckFactory;
-  FrontendActionFactory *FrontendFactory;
+  std::unique_ptr<FrontendActionFactory> FrontendFactory;
 
   // Choose the correct factory based on the selected mode.
   if (Analyze)
@@ -219,5 +225,5 @@
   else
     FrontendFactory = newFrontendActionFactory(&CheckFactory);
 
-  return Tool.run(FrontendFactory);
+  return Tool.run(FrontendFactory.get());
 }
diff --git a/tools/clang-check/Makefile b/tools/clang-check/Makefile
index cf088d2..e98a131 100644
--- a/tools/clang-check/Makefile
+++ b/tools/clang-check/Makefile
@@ -20,6 +20,6 @@
            clangTooling.a clangParse.a clangSema.a \
            clangStaticAnalyzerFrontend.a clangStaticAnalyzerCheckers.a \
            clangStaticAnalyzerCore.a clangAnalysis.a clangRewriteFrontend.a \
-           clangRewriteCore.a clangEdit.a clangAST.a clangLex.a clangBasic.a
+           clangRewrite.a clangEdit.a clangAST.a clangLex.a clangBasic.a
 
 include $(CLANG_LEVEL)/Makefile
diff --git a/tools/clang-format-vs/CMakeLists.txt b/tools/clang-format-vs/CMakeLists.txt
new file mode 100644
index 0000000..b110192
--- /dev/null
+++ b/tools/clang-format-vs/CMakeLists.txt
@@ -0,0 +1,23 @@
+option(BUILD_CLANG_FORMAT_VS_PLUGIN "Build clang-format VS plugin" OFF)
+if (BUILD_CLANG_FORMAT_VS_PLUGIN)
+  add_custom_target(clang_format_exe_for_vsix
+      ${CMAKE_COMMAND} -E copy_if_different
+      "${LLVM_TOOLS_BINARY_DIR}/${CMAKE_CFG_INTDIR}/clang-format.exe"
+      "${CMAKE_CURRENT_SOURCE_DIR}/ClangFormat/clang-format.exe"
+      DEPENDS clang-format)
+
+  if (NOT CLANG_FORMAT_VS_VERSION)
+    set(CLANG_FORMAT_VS_VERSION "${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}")
+  endif()
+
+  configure_file("source.extension.vsixmanifest.in"
+      "${CMAKE_CURRENT_SOURCE_DIR}/ClangFormat/source.extension.vsixmanifest")
+
+  add_custom_target(clang_format_vsix ALL
+      devenv "${CMAKE_CURRENT_SOURCE_DIR}/ClangFormat.sln" /Build Release
+      DEPENDS clang_format_exe_for_vsix "${CMAKE_CURRENT_SOURCE_DIR}/ClangFormat/source.extension.vsixmanifest"
+      COMMAND ${CMAKE_COMMAND} -E copy_if_different
+      "${CMAKE_CURRENT_SOURCE_DIR}/ClangFormat/bin/Release/ClangFormat.vsix"
+      "${LLVM_TOOLS_BINARY_DIR}/${CMAKE_CFG_INTDIR}/ClangFormat.vsix"
+      DEPENDS clang_format_exe_for_vsix)
+endif()
diff --git a/tools/clang-format-vs/ClangFormat/ClangFormat.csproj b/tools/clang-format-vs/ClangFormat/ClangFormat.csproj
index 65ccaba..2f49221 100644
--- a/tools/clang-format-vs/ClangFormat/ClangFormat.csproj
+++ b/tools/clang-format-vs/ClangFormat/ClangFormat.csproj
@@ -178,6 +178,9 @@
     <None Include="Resources\Images_32bit.bmp" />

   </ItemGroup>

   <ItemGroup>

+    <Content Include="clang-format.exe">

+      <IncludeInVSIX>true</IncludeInVSIX>

+    </Content>

     <Content Include="Resources\Package.ico" />

   </ItemGroup>

   <ItemGroup>

diff --git a/tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs b/tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs
index 797d467..c3aa8fe 100644
--- a/tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs
+++ b/tools/clang-format-vs/ClangFormat/ClangFormatPackage.cs
@@ -22,6 +22,7 @@
 using System.ComponentModel;

 using System.ComponentModel.Design;

 using System.IO;

+using System.Reflection;

 using System.Runtime.InteropServices;

 using System.Xml.Linq;

 

@@ -128,9 +129,12 @@
         /// </summary>

         private string RunClangFormat(string text, int offset, int length, string path)

         {

+            string vsixPath = Path.GetDirectoryName(

+                typeof(ClangFormatPackage).Assembly.Location);

+

             System.Diagnostics.Process process = new System.Diagnostics.Process();

             process.StartInfo.UseShellExecute = false;

-            process.StartInfo.FileName = "clang-format.exe";

+            process.StartInfo.FileName = vsixPath + "\\clang-format.exe";

             // Poor man's escaping - this will not work when quotes are already escaped

             // in the input (but we don't need more).

             string style = GetStyle().Replace("\"", "\\\"");

diff --git a/tools/clang-format-vs/ClangFormat/source.extension.vsixmanifest b/tools/clang-format-vs/ClangFormat/source.extension.vsixmanifest
deleted file mode 100644
index 39d30f0..0000000
--- a/tools/clang-format-vs/ClangFormat/source.extension.vsixmanifest
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Vsix Version="1.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2010">

-  <Identifier Id="20dbc914-1c7a-4992-b236-ef58b37850eb">

-    <Name>ClangFormat</Name>

-    <Author>LLVM</Author>

-    <Version>1.0</Version>

-    <Description xml:space="preserve">Information about my package</Description>

-    <Locale>1033</Locale>

-    <InstalledByMsi>false</InstalledByMsi>

-    <SupportedProducts>

-      <VisualStudio Version="10.0">

-        <Edition>Pro</Edition>

-      </VisualStudio>

-      <VisualStudio Version="11.0">

-        <Edition>Pro</Edition>

-      </VisualStudio>

-      <VisualStudio Version="12.0">

-        <Edition>Pro</Edition>

-      </VisualStudio>

-    </SupportedProducts>

-    <SupportedFrameworkRuntimeEdition MinVersion="4.0" MaxVersion="4.0" />

-  </Identifier>

-  <References>

-        <Reference Id="Microsoft.VisualStudio.MPF" MinVersion="10.0">

-            <Name>Visual Studio MPF</Name>

-        </Reference>

-  </References>

-  <Content>

-    <VsPackage>|%CurrentProject%;PkgdefProjectOutputGroup|</VsPackage>

-  </Content>

-</Vsix>

diff --git a/tools/clang-format-vs/README b/tools/clang-format-vs/README
deleted file mode 100644
index 240821c..0000000
--- a/tools/clang-format-vs/README
+++ /dev/null
@@ -1,6 +0,0 @@
-This directory contains a VSPackage project to generate a visual studio extension

-for clang-format.

-

-Build prerequisites are:

-- Visual Studio 2012 Professional

-- Visual Studio SDK (http://www.microsoft.com/en-us/download/details.aspx?id=30668)
\ No newline at end of file
diff --git a/tools/clang-format-vs/README.txt b/tools/clang-format-vs/README.txt
new file mode 100644
index 0000000..b87df6e
--- /dev/null
+++ b/tools/clang-format-vs/README.txt
@@ -0,0 +1,13 @@
+This directory contains a VSPackage project to generate a Visual Studio extension

+for clang-format.

+

+Build prerequisites are:

+- Visual Studio 2012 Professional

+- Visual Studio 2010 Professional

+- Visual Studio 2010 SDK.

+

+clang-format.exe must be copied into the ClangFormat/ directory before building.

+It will be bundled into the .vsix file.

+

+The extension can be built manually from ClangFormat.sln (e.g. by opening it in

+Visual Studio), or with cmake by setting the BUILD_CLANG_FORMAT_VS_PLUGIN flag.

diff --git a/tools/clang-format-vs/source.extension.vsixmanifest.in b/tools/clang-format-vs/source.extension.vsixmanifest.in
new file mode 100644
index 0000000..ed0e72e
--- /dev/null
+++ b/tools/clang-format-vs/source.extension.vsixmanifest.in
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>

+<Vsix Version="1.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2010">

+  <Identifier Id="20dbc914-1c7a-4992-b236-ef58b37850eb">

+    <Name>ClangFormat</Name>

+    <Author>LLVM</Author>

+    <Version>@CLANG_FORMAT_VS_VERSION@</Version>

+    <Description xml:space="preserve">A tool to format C/C++/Obj-C code.</Description>

+    <Locale>1033</Locale>

+    <InstalledByMsi>false</InstalledByMsi>

+    <SupportedProducts>

+      <VisualStudio Version="10.0">

+        <Edition>Pro</Edition>

+      </VisualStudio>

+      <VisualStudio Version="11.0">

+        <Edition>Pro</Edition>

+      </VisualStudio>

+      <VisualStudio Version="12.0">

+        <Edition>Pro</Edition>

+      </VisualStudio>

+    </SupportedProducts>

+    <SupportedFrameworkRuntimeEdition MinVersion="4.0" MaxVersion="4.0" />

+  </Identifier>

+  <References>

+        <Reference Id="Microsoft.VisualStudio.MPF" MinVersion="10.0">

+            <Name>Visual Studio MPF</Name>

+        </Reference>

+  </References>

+  <Content>

+    <VsPackage>|%CurrentProject%;PkgdefProjectOutputGroup|</VsPackage>

+  </Content>

+</Vsix>

diff --git a/tools/clang-format/CMakeLists.txt b/tools/clang-format/CMakeLists.txt
index 7bb3fbf..f80a3ec 100644
--- a/tools/clang-format/CMakeLists.txt
+++ b/tools/clang-format/CMakeLists.txt
@@ -1,15 +1,15 @@
 set(LLVM_LINK_COMPONENTS support)
-set(LLVM_USED_LIBS clangFormat clangTooling clangBasic clangAST)
 
 add_clang_executable(clang-format
   ClangFormat.cpp
   )
 
 target_link_libraries(clang-format
-  clangFormat
-  clangTooling
   clangBasic
-  clangRewriteFrontend
+  clangFormat
+  clangLex
+  clangRewrite
+  clangTooling
   )
 
 install(TARGETS clang-format RUNTIME DESTINATION bin)
diff --git a/tools/clang-format/ClangFormat.cpp b/tools/clang-format/ClangFormat.cpp
index 768165b..cebb275 100644
--- a/tools/clang-format/ClangFormat.cpp
+++ b/tools/clang-format/ClangFormat.cpp
@@ -17,13 +17,14 @@
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/SourceManager.h"
+#include "clang/Basic/Version.h"
 #include "clang/Format/Format.h"
 #include "clang/Lex/Lexer.h"
 #include "clang/Rewrite/Core/Rewriter.h"
+#include "llvm/ADT/StringMap.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Signals.h"
-#include "llvm/ADT/StringMap.h"
 
 using namespace llvm;
 
@@ -31,7 +32,7 @@
 
 // Mark all our options with this category, everything else (except for -version
 // and -help) will be hidden.
-cl::OptionCategory ClangFormatCategory("Clang-format options");
+static cl::OptionCategory ClangFormatCategory("Clang-format options");
 
 static cl::list<unsigned>
     Offsets("offset",
@@ -62,6 +63,14 @@
     Style("style",
           cl::desc(clang::format::StyleOptionHelpDescription),
           cl::init("file"), cl::cat(ClangFormatCategory));
+static cl::opt<std::string>
+FallbackStyle("fallback-style",
+              cl::desc("The name of the predefined style used as a\n"
+                       "fallback in case clang-format is invoked with\n"
+                       "-style=file, but can not find the .clang-format\n"
+                       "file to use.\n"
+                       "Use -fallback-style=none to skip formatting."),
+              cl::init("LLVM"), cl::cat(ClangFormatCategory));
 
 static cl::opt<std::string>
 AssumeFilename("assume-filename",
@@ -94,7 +103,7 @@
 namespace clang {
 namespace format {
 
-static FileID createInMemoryFile(StringRef FileName, const MemoryBuffer *Source,
+static FileID createInMemoryFile(StringRef FileName, MemoryBuffer *Source,
                                  SourceManager &Sources, FileManager &Files) {
   const FileEntry *Entry = Files.getVirtualFile(FileName == "-" ? "<stdin>" :
                                                     FileName,
@@ -173,6 +182,26 @@
   return false;
 }
 
+static void outputReplacementXML(StringRef Text) {
+  size_t From = 0;
+  size_t Index;
+  while ((Index = Text.find_first_of("\n\r", From)) != StringRef::npos) {
+    llvm::outs() << Text.substr(From, Index - From);
+    switch (Text[Index]) {
+    case '\n':
+      llvm::outs() << "&#10;";
+      break;
+    case '\r':
+      llvm::outs() << "&#13;";
+      break;
+    default:
+      llvm_unreachable("Unexpected character encountered!");
+    }
+    From = Index + 1;
+  }
+  llvm::outs() << Text.substr(From);
+}
+
 // Returns true on error.
 static bool format(StringRef FileName) {
   FileManager Files((FileSystemOptions()));
@@ -180,11 +209,13 @@
       IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
       new DiagnosticOptions);
   SourceManager Sources(Diagnostics, Files);
-  OwningPtr<MemoryBuffer> Code;
-  if (error_code ec = MemoryBuffer::getFileOrSTDIN(FileName, Code)) {
-    llvm::errs() << ec.message() << "\n";
+  ErrorOr<std::unique_ptr<MemoryBuffer>> CodeOrErr =
+      MemoryBuffer::getFileOrSTDIN(FileName);
+  if (std::error_code EC = CodeOrErr.getError()) {
+    llvm::errs() << EC.message() << "\n";
     return true;
   }
+  std::unique_ptr<llvm::MemoryBuffer> Code = std::move(CodeOrErr.get());
   if (Code->getBufferSize() == 0)
     return false; // Empty files are formatted correctly.
   FileID ID = createInMemoryFile(FileName, Code.get(), Sources, Files);
@@ -192,8 +223,8 @@
   if (fillRanges(Sources, ID, Code.get(), Ranges))
     return true;
 
-  FormatStyle FormatStyle =
-      getStyle(Style, (FileName == "-") ? AssumeFilename : FileName);
+  FormatStyle FormatStyle = getStyle(
+      Style, (FileName == "-") ? AssumeFilename : FileName, FallbackStyle);
   Lexer Lex(ID, Sources.getBuffer(ID), Sources,
             getFormattingLangOpts(FormatStyle.Standard));
   tooling::Replacements Replaces = reformat(FormatStyle, Lex, Sources, Ranges);
@@ -205,8 +236,9 @@
          I != E; ++I) {
       llvm::outs() << "<replacement "
                    << "offset='" << I->getOffset() << "' "
-                   << "length='" << I->getLength() << "'>"
-                   << I->getReplacementText() << "</replacement>\n";
+                   << "length='" << I->getLength() << "'>";
+      outputReplacementXML(I->getReplacementText());
+      llvm::outs() << "</replacement>\n";
     }
     llvm::outs() << "</replacements>\n";
   } else {
@@ -217,8 +249,8 @@
         return true;
     } else {
       if (Cursor.getNumOccurrences() != 0)
-        outs() << "{ \"Cursor\": " << tooling::shiftedCodePosition(
-                                          Replaces, Cursor) << " }\n";
+        outs() << "{ \"Cursor\": "
+               << tooling::shiftedCodePosition(Replaces, Cursor) << " }\n";
       Rewrite.getEditBuffer(ID).write(outs());
     }
   }
@@ -228,6 +260,11 @@
 }  // namespace format
 }  // namespace clang
 
+static void PrintVersion() {
+  raw_ostream &OS = outs();
+  OS << clang::getClangToolFullVersion("clang-format") << '\n';
+}
+
 int main(int argc, const char **argv) {
   llvm::sys::PrintStackTraceOnErrorSignal();
 
@@ -241,6 +278,7 @@
       I->second->setHiddenFlag(cl::ReallyHidden);
   }
 
+  cl::SetVersionPrinter(PrintVersion);
   cl::ParseCommandLineOptions(
       argc, argv,
       "A tool to format C/C++/Obj-C code.\n\n"
@@ -256,7 +294,8 @@
   if (DumpConfig) {
     std::string Config =
         clang::format::configurationAsText(clang::format::getStyle(
-            Style, FileNames.empty() ? AssumeFilename : FileNames[0]));
+            Style, FileNames.empty() ? AssumeFilename : FileNames[0],
+            FallbackStyle));
     llvm::outs() << Config << "\n";
     return 0;
   }
diff --git a/tools/clang-format/Makefile b/tools/clang-format/Makefile
index 4902244..a26ef59 100644
--- a/tools/clang-format/Makefile
+++ b/tools/clang-format/Makefile
@@ -18,7 +18,7 @@
 LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option
 USEDLIBS = clangFormat.a clangTooling.a clangFrontend.a clangSerialization.a \
 	   clangDriver.a clangParse.a clangSema.a clangAnalysis.a \
-           clangRewriteFrontend.a clangRewriteCore.a clangEdit.a clangAST.a \
+           clangRewriteFrontend.a clangRewrite.a clangEdit.a clangAST.a \
            clangLex.a clangBasic.a 
 
 include $(CLANG_LEVEL)/Makefile
diff --git a/tools/clang-format/clang-format-diff.py b/tools/clang-format/clang-format-diff.py
index 60b8fb7..d6d0d44 100755
--- a/tools/clang-format/clang-format-diff.py
+++ b/tools/clang-format/clang-format-diff.py
@@ -15,9 +15,10 @@
 
 This script reads input from a unified diff and reformats all the changed
 lines. This is useful to reformat all the lines touched by a specific patch.
-Example usage for git users:
+Example usage for git/svn users:
 
   git diff -U0 HEAD^ | clang-format-diff.py -p1 -i
+  svn diff --diff-cmd=diff -x-U0 | clang-format-diff.py -i
 
 """
 
@@ -37,12 +38,20 @@
 def main():
   parser = argparse.ArgumentParser(description=
                                    'Reformat changed lines in diff. Without -i '
-                                   'option just output the diff that would be'
+                                   'option just output the diff that would be '
                                    'introduced.')
   parser.add_argument('-i', action='store_true', default=False,
                       help='apply edits to files instead of displaying a diff')
-  parser.add_argument('-p', default=0,
+  parser.add_argument('-p', metavar='NUM', default=0,
                       help='strip the smallest prefix containing P slashes')
+  parser.add_argument('-regex', metavar='PATTERN', default=None,
+                      help='custom pattern selecting file paths to reformat '
+                      '(case sensitive, overrides -iregex)')
+  parser.add_argument('-iregex', metavar='PATTERN', default=
+                      r'.*\.(cpp|cc|c\+\+|cxx|c|cl|h|hpp|m|mm|inc|js|proto'
+                      r'|protodevel)',
+                      help='custom pattern selecting file paths to reformat '
+                      '(case insensitive, overridden by -regex)')
   parser.add_argument(
       '-style',
       help=
@@ -59,10 +68,12 @@
     if filename == None:
       continue
 
-    # FIXME: Add other types containing C++/ObjC code.
-    if not (filename.endswith(".cpp") or filename.endswith(".cc") or
-            filename.endswith(".h")):
-      continue
+    if args.regex is not None:
+      if not re.match('^%s$' % args.regex, filename):
+        continue
+    else:
+      if not re.match('^%s$' % args.iregex, filename, re.IGNORECASE):
+        continue
 
     match = re.search('^@@.*\+(\d+)(,(\d+))?', line)
     if match:
@@ -85,11 +96,8 @@
     if args.style:
       command.extend(['-style', args.style])
     p = subprocess.Popen(command, stdout=subprocess.PIPE,
-                         stderr=subprocess.PIPE,
-                         stdin=subprocess.PIPE)
+                         stderr=None, stdin=subprocess.PIPE)
     stdout, stderr = p.communicate()
-    if stderr:
-      print stderr
     if p.returncode != 0:
       sys.exit(p.returncode);
 
@@ -102,7 +110,7 @@
                                   '(before formatting)', '(after formatting)')
       diff_string = string.join(diff, '')
       if len(diff_string) > 0:
-        print diff_string
+        sys.stdout.write(diff_string)
 
 if __name__ == '__main__':
   main()
diff --git a/tools/clang-format/clang-format.py b/tools/clang-format/clang-format.py
index f5a5756..16a1879 100644
--- a/tools/clang-format/clang-format.py
+++ b/tools/clang-format/clang-format.py
@@ -32,48 +32,51 @@
 # used.
 style = 'file'
 
-# Get the current text.
-buf = vim.current.buffer
-text = '\n'.join(buf)
+def main():
+  # Get the current text.
+  buf = vim.current.buffer
+  text = '\n'.join(buf)
 
-# Determine range to format.
-cursor = int(vim.eval('line2byte(line("."))+col(".")')) - 2
-lines = '%s:%s' % (vim.current.range.start + 1, vim.current.range.end + 1)
+  # Determine range to format.
+  lines = '%s:%s' % (vim.current.range.start + 1, vim.current.range.end + 1)
 
-# Avoid flashing an ugly, ugly cmd prompt on Windows when invoking clang-format.
-startupinfo = None
-if sys.platform.startswith('win32'):
-  startupinfo = subprocess.STARTUPINFO()
-  startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
-  startupinfo.wShowWindow = subprocess.SW_HIDE
+  # Determine the cursor position.
+  cursor = int(vim.eval('line2byte(line("."))+col(".")')) - 2
+  if cursor < 0:
+    print 'Couldn\'t determine cursor position. Is your file empty?'
+    return
 
-# Call formatter.
-command = [binary, '-lines', lines, '-style', style, '-cursor', str(cursor)]
-if vim.current.buffer.name:
-  command.extend(['-assume-filename', vim.current.buffer.name])
-p = subprocess.Popen(command,
-                     stdout=subprocess.PIPE, stderr=subprocess.PIPE,
-                     stdin=subprocess.PIPE, startupinfo=startupinfo)
-stdout, stderr = p.communicate(input=text)
+  # Avoid flashing an ugly, ugly cmd prompt on Windows when invoking clang-format.
+  startupinfo = None
+  if sys.platform.startswith('win32'):
+    startupinfo = subprocess.STARTUPINFO()
+    startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
+    startupinfo.wShowWindow = subprocess.SW_HIDE
 
-# If successful, replace buffer contents.
-if stderr:
-  message = stderr.splitlines()[0]
-  parts = message.split(' ', 2)
-  if len(parts) > 2:
-    message = parts[2]
-  print 'Formatting failed: %s (total %d warnings, %d errors)' % (
-      message, stderr.count('warning:'), stderr.count('error:'))
+  # Call formatter.
+  command = [binary, '-lines', lines, '-style', style, '-cursor', str(cursor)]
+  if vim.current.buffer.name:
+    command.extend(['-assume-filename', vim.current.buffer.name])
+  p = subprocess.Popen(command,
+                       stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+                       stdin=subprocess.PIPE, startupinfo=startupinfo)
+  stdout, stderr = p.communicate(input=text)
 
-if not stdout:
-  print ('No output from clang-format (crashed?).\n' +
-      'Please report to bugs.llvm.org.')
-else:
-  lines = stdout.split('\n')
-  output = json.loads(lines[0])
-  lines = lines[1:]
-  sequence = difflib.SequenceMatcher(None, vim.current.buffer, lines)
-  for op in reversed(sequence.get_opcodes()):
-    if op[0] is not 'equal':
-      vim.current.buffer[op[1]:op[2]] = lines[op[3]:op[4]]
-  vim.command('goto %d' % (output['Cursor'] + 1))
+  # If successful, replace buffer contents.
+  if stderr:
+    print stderr
+
+  if not stdout:
+    print ('No output from clang-format (crashed?).\n' +
+        'Please report to bugs.llvm.org.')
+  else:
+    lines = stdout.split('\n')
+    output = json.loads(lines[0])
+    lines = lines[1:]
+    sequence = difflib.SequenceMatcher(None, vim.current.buffer, lines)
+    for op in reversed(sequence.get_opcodes()):
+      if op[0] is not 'equal':
+        vim.current.buffer[op[1]:op[2]] = lines[op[3]:op[4]]
+    vim.command('goto %d' % (output['Cursor'] + 1))
+
+main()
diff --git a/tools/clang-format/git-clang-format b/tools/clang-format/git-clang-format
index b0737ed..c40b74d 100755
--- a/tools/clang-format/git-clang-format
+++ b/tools/clang-format/git-clang-format
@@ -75,6 +75,9 @@
       'm',  # ObjC
       'mm',  # ObjC++
       'cc', 'cp', 'cpp', 'c++', 'cxx', 'hpp',  # C++
+      # Other languages that clang-format supports
+      'proto', 'protodevel',  # Protocol Buffers
+      'js',  # JavaScript
       ])
 
   p = argparse.ArgumentParser(
diff --git a/tools/diag-build/diag-build.sh b/tools/diag-build/diag-build.sh
index 4fef8fb..018288d 100755
--- a/tools/diag-build/diag-build.sh
+++ b/tools/diag-build/diag-build.sh
@@ -1,5 +1,14 @@
 #!/bin/bash
 
+# diag-build: a tool showing enabled warnings in a project.
+#
+# diag-build acts as a wrapper for 'diagtool show-enabled', in the same way
+# that scan-build acts as a wrapper for the static analyzer. The common case is
+# simple: use 'diag-build make' or 'diag-build xcodebuild' to list the warnings
+# enabled for the first compilation command we see. Other build systems require
+# you to manually specify "dry-run" and "use $CC and $CXX"; if there is a build
+# system you are interested in, please add it to the switch statement.
+
 print_usage () {
     echo 'Usage: diag-build.sh [-v] xcodebuild [flags]'
     echo '       diag-build.sh [-v] make [flags]'
diff --git a/tools/diagtool/CMakeLists.txt b/tools/diagtool/CMakeLists.txt
index 8aa2d21..e88c2ab 100644
--- a/tools/diagtool/CMakeLists.txt
+++ b/tools/diagtool/CMakeLists.txt
@@ -1,9 +1,5 @@
 set(LLVM_LINK_COMPONENTS
-  ${LLVM_TARGETS_TO_BUILD}
-  asmparser
-  bitreader
-  support
-  mc
+  Support
   )
 
 add_clang_executable(diagtool
@@ -15,14 +11,8 @@
   TreeView.cpp
 )
 
-add_dependencies(diagtool
-  ClangDiagnosticIndexName
-  )
-
 target_link_libraries(diagtool
   clangBasic
-  clangLex
-  clangSema
   clangFrontend
   )
 
diff --git a/tools/diagtool/DiagTool.cpp b/tools/diagtool/DiagTool.cpp
index c3428c9..44bc83e 100644
--- a/tools/diagtool/DiagTool.cpp
+++ b/tools/diagtool/DiagTool.cpp
@@ -32,7 +32,7 @@
 
 DiagTool *DiagTools::getTool(llvm::StringRef toolCmd) {
   ToolMap::iterator it = getTools(tools)->find(toolCmd);
-  return (it == getTools(tools)->end()) ? 0 : it->getValue();
+  return (it == getTools(tools)->end()) ? nullptr : it->getValue();
 }
 
 void DiagTools::registerTool(DiagTool *tool) {
diff --git a/tools/diagtool/DiagTool.h b/tools/diagtool/DiagTool.h
index 93d531b..b1e69f3 100644
--- a/tools/diagtool/DiagTool.h
+++ b/tools/diagtool/DiagTool.h
@@ -62,7 +62,7 @@
 public:\
   CLSNAME() : DiagTool(NAME, DESC) {}\
   virtual ~CLSNAME() {}\
-  virtual int run(unsigned argc, char *argv[], llvm::raw_ostream &out);\
+  int run(unsigned argc, char *argv[], llvm::raw_ostream &out) override;\
 };\
 diagtool::RegisterDiagTool<CLSNAME> Register##CLSNAME;\
 }
diff --git a/tools/diagtool/DiagnosticNames.cpp b/tools/diagtool/DiagnosticNames.cpp
index 155c62d..a08da89 100644
--- a/tools/diagtool/DiagnosticNames.cpp
+++ b/tools/diagtool/DiagnosticNames.cpp
@@ -50,11 +50,11 @@
 }
 
 const DiagnosticRecord &diagtool::getDiagnosticForID(short DiagID) {
-  DiagnosticRecord Key = {0, DiagID, 0};
+  DiagnosticRecord Key = {nullptr, DiagID, 0};
 
   const DiagnosticRecord *Result =
-    std::lower_bound(BuiltinDiagnosticsByID,
-                     llvm::array_endof(BuiltinDiagnosticsByID),
+    std::lower_bound(std::begin(BuiltinDiagnosticsByID),
+                     std::end(BuiltinDiagnosticsByID),
                      Key, orderByID);
   assert(Result && "diagnostic not found; table may be out of date");
   return *Result;
@@ -81,7 +81,7 @@
 }
 
 GroupRecord::subgroup_iterator GroupRecord::subgroup_end() const {
-  return 0;
+  return nullptr;
 }
 
 GroupRecord::diagnostics_iterator GroupRecord::diagnostics_begin() const {
@@ -89,7 +89,7 @@
 }
 
 GroupRecord::diagnostics_iterator GroupRecord::diagnostics_end() const {
-  return 0;
+  return nullptr;
 }
 
 llvm::ArrayRef<GroupRecord> diagtool::getDiagnosticGroups() {
diff --git a/tools/diagtool/DiagnosticNames.h b/tools/diagtool/DiagnosticNames.h
index a3321fa..2571b19 100644
--- a/tools/diagtool/DiagnosticNames.h
+++ b/tools/diagtool/DiagnosticNames.h
@@ -48,7 +48,7 @@
       friend struct GroupRecord;
       group_iterator(const short *Start) : CurrentID(Start) {
         if (CurrentID && *CurrentID == -1)
-          CurrentID = 0;
+          CurrentID = nullptr;
       }
 
     public:
@@ -70,7 +70,7 @@
       group_iterator &operator++() {
         ++CurrentID;
         if (*CurrentID == -1)
-          CurrentID = 0;
+          CurrentID = nullptr;
         return *this;
       }
 
diff --git a/tools/diagtool/ShowEnabledWarnings.cpp b/tools/diagtool/ShowEnabledWarnings.cpp
index bcc7520..903d1f1 100644
--- a/tools/diagtool/ShowEnabledWarnings.cpp
+++ b/tools/diagtool/ShowEnabledWarnings.cpp
@@ -44,6 +44,7 @@
   switch (Level) {
   case DiagnosticsEngine::Ignored: return ' ';
   case DiagnosticsEngine::Note:    return '-';
+  case DiagnosticsEngine::Remark:  return 'R';
   case DiagnosticsEngine::Warning: return 'W';
   case DiagnosticsEngine::Error:   return 'E';
   case DiagnosticsEngine::Fatal:   return 'F';
@@ -63,18 +64,18 @@
     new DiagnosticsEngine(DiagIDs, new DiagnosticOptions(), DiagsBuffer));
 
   // Try to build a CompilerInvocation.
-  OwningPtr<CompilerInvocation> Invocation(
-    createInvocationFromCommandLine(ArrayRef<const char *>(argv, argc),
-                                    InterimDiags));
+  std::unique_ptr<CompilerInvocation> Invocation(
+      createInvocationFromCommandLine(ArrayRef<const char *>(argv, argc),
+                                      InterimDiags));
   if (!Invocation)
-    return NULL;
+    return nullptr;
 
   // Build the diagnostics parser
   IntrusiveRefCntPtr<DiagnosticsEngine> FinalDiags =
     CompilerInstance::createDiagnostics(&Invocation->getDiagnosticOpts());
   if (!FinalDiags)
-    return NULL;
-  
+    return nullptr;
+
   // Flush any errors created when initializing everything. This could happen
   // for invalid command lines, which will probably give non-sensical results.
   DiagsBuffer->FlushDiagnostics(*FinalDiags);
diff --git a/tools/diagtool/TreeView.cpp b/tools/diagtool/TreeView.cpp
index fd548ef..3647e39 100644
--- a/tools/diagtool/TreeView.cpp
+++ b/tools/diagtool/TreeView.cpp
@@ -6,10 +6,6 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-//
-// This diagnostic tool 
-//
-//===----------------------------------------------------------------------===//
 
 #include "DiagTool.h"
 #include "DiagnosticNames.h"
@@ -22,118 +18,129 @@
 #include "llvm/Support/Format.h"
 #include "llvm/Support/Process.h"
 
-DEF_DIAGTOOL("tree",
-             "Show warning flags in a tree view",
-             TreeView)
-  
+DEF_DIAGTOOL("tree", "Show warning flags in a tree view", TreeView)
+
 using namespace clang;
 using namespace diagtool;
 
-static void printUsage() {
-  llvm::errs() << "Usage: diagtool tree [--flags-only] [<diagnostic-group>]\n";
-}
-
-static bool showColors(llvm::raw_ostream &out) {
+static bool hasColors(const llvm::raw_ostream &out) {
   if (&out != &llvm::errs() && &out != &llvm::outs())
     return false;
   return llvm::errs().is_displayed() && llvm::outs().is_displayed();
 }
 
-static void setColor(bool ShowColors, llvm::raw_ostream &out,
-                     llvm::raw_ostream::Colors Color) {
-  if (ShowColors)
-    out << llvm::sys::Process::OutputColor(Color, false, false);
-}
+class TreePrinter {
+public:
+  llvm::raw_ostream &out;
+  const bool ShowColors;
+  bool FlagsOnly;
 
-static void resetColor(bool ShowColors, llvm::raw_ostream &out) {
-  if (ShowColors)
-    out << llvm::sys::Process::ResetColor();
-}
+  TreePrinter(llvm::raw_ostream &out)
+      : out(out), ShowColors(hasColors(out)), FlagsOnly(false) {}
 
-static clang::DiagnosticsEngine::Level getLevel(unsigned DiagID) {
-  // FIXME: This feels like a hack.
-  static clang::DiagnosticsEngine Diags(new DiagnosticIDs,
-                                        new DiagnosticOptions);
-  return Diags.getDiagnosticLevel(DiagID, SourceLocation());
-}
-
-static void printGroup(llvm::raw_ostream &out, const GroupRecord &Group,
-                       bool FlagsOnly, unsigned Indent = 0) {
-  out.indent(Indent * 2);
-  
-  bool ShowColors = showColors(out);
-  setColor(ShowColors, out, llvm::raw_ostream::YELLOW);
-  out << "-W" << Group.getName() << "\n";
-  resetColor(ShowColors, out);
-  
-  ++Indent;
-  for (GroupRecord::subgroup_iterator I = Group.subgroup_begin(),
-                                      E = Group.subgroup_end();
-       I != E; ++I) {
-    printGroup(out, *I, FlagsOnly, Indent);
+  void setColor(llvm::raw_ostream::Colors Color) {
+    if (ShowColors)
+      out << llvm::sys::Process::OutputColor(Color, false, false);
   }
 
-  if (!FlagsOnly) {
-    for (GroupRecord::diagnostics_iterator I = Group.diagnostics_begin(),
-                                           E = Group.diagnostics_end();
+  void resetColor() {
+    if (ShowColors)
+      out << llvm::sys::Process::ResetColor();
+  }
+
+  static bool isIgnored(unsigned DiagID) {
+    // FIXME: This feels like a hack.
+    static clang::DiagnosticsEngine Diags(new DiagnosticIDs,
+                                          new DiagnosticOptions);
+    return Diags.isIgnored(DiagID, SourceLocation());
+  }
+
+  void printGroup(const GroupRecord &Group, unsigned Indent = 0) {
+    out.indent(Indent * 2);
+
+    setColor(llvm::raw_ostream::YELLOW);
+    out << "-W" << Group.getName() << "\n";
+    resetColor();
+
+    ++Indent;
+    for (GroupRecord::subgroup_iterator I = Group.subgroup_begin(),
+                                        E = Group.subgroup_end();
          I != E; ++I) {
-      if (ShowColors) {
-        if (getLevel(I->DiagID) != DiagnosticsEngine::Ignored) {
-          setColor(ShowColors, out, llvm::raw_ostream::GREEN);
-        }
+      printGroup(*I, Indent);
+    }
+
+    if (!FlagsOnly) {
+      for (GroupRecord::diagnostics_iterator I = Group.diagnostics_begin(),
+                                             E = Group.diagnostics_end();
+           I != E; ++I) {
+        if (ShowColors && !isIgnored(I->DiagID))
+          setColor(llvm::raw_ostream::GREEN);
+        out.indent(Indent * 2);
+        out << I->getName();
+        resetColor();
+        out << "\n";
       }
-      out.indent(Indent * 2);
-      out << I->getName();
-      resetColor(ShowColors, out);
-      out << "\n";
-    }
-  }
-}
-
-static int showGroup(llvm::raw_ostream &out, StringRef RootGroup,
-                     bool FlagsOnly) {
-  ArrayRef<GroupRecord> AllGroups = getDiagnosticGroups();
-
-  if (RootGroup.size() > UINT16_MAX) {
-    llvm::errs() << "No such diagnostic group exists\n";
-    return 1;
-  }
-
-  const GroupRecord *Found =
-    std::lower_bound(AllGroups.begin(), AllGroups.end(), RootGroup);
-  
-  if (Found == AllGroups.end() || Found->getName() != RootGroup) {
-    llvm::errs() << "No such diagnostic group exists\n";
-    return 1;
-  }
-  
-  printGroup(out, *Found, FlagsOnly);
-  
-  return 0;
-}
-
-static int showAll(llvm::raw_ostream &out, bool FlagsOnly) {
-  ArrayRef<GroupRecord> AllGroups = getDiagnosticGroups();
-  llvm::DenseSet<unsigned> NonRootGroupIDs;
-
-  for (ArrayRef<GroupRecord>::iterator I = AllGroups.begin(),
-                                       E = AllGroups.end();
-       I != E; ++I) {
-    for (GroupRecord::subgroup_iterator SI = I->subgroup_begin(),
-                                        SE = I->subgroup_end();
-         SI != SE; ++SI) {
-      NonRootGroupIDs.insert((unsigned)SI.getID());
     }
   }
 
-  assert(NonRootGroupIDs.size() < AllGroups.size());
+  int showGroup(StringRef RootGroup) {
+    ArrayRef<GroupRecord> AllGroups = getDiagnosticGroups();
 
-  for (unsigned i = 0, e = AllGroups.size(); i != e; ++i) {
-    if (!NonRootGroupIDs.count(i))
-      printGroup(out, AllGroups[i], FlagsOnly);
+    if (RootGroup.size() > UINT16_MAX) {
+      llvm::errs() << "No such diagnostic group exists\n";
+      return 1;
+    }
+
+    const GroupRecord *Found =
+        std::lower_bound(AllGroups.begin(), AllGroups.end(), RootGroup);
+
+    if (Found == AllGroups.end() || Found->getName() != RootGroup) {
+      llvm::errs() << "No such diagnostic group exists\n";
+      return 1;
+    }
+
+    printGroup(*Found);
+
+    return 0;
   }
 
-  return 0;
+  int showAll() {
+    ArrayRef<GroupRecord> AllGroups = getDiagnosticGroups();
+    llvm::DenseSet<unsigned> NonRootGroupIDs;
+
+    for (ArrayRef<GroupRecord>::iterator I = AllGroups.begin(),
+                                         E = AllGroups.end();
+         I != E; ++I) {
+      for (GroupRecord::subgroup_iterator SI = I->subgroup_begin(),
+                                          SE = I->subgroup_end();
+           SI != SE; ++SI) {
+        NonRootGroupIDs.insert((unsigned)SI.getID());
+      }
+    }
+
+    assert(NonRootGroupIDs.size() < AllGroups.size());
+
+    for (unsigned i = 0, e = AllGroups.size(); i != e; ++i) {
+      if (!NonRootGroupIDs.count(i))
+        printGroup(AllGroups[i]);
+    }
+
+    return 0;
+  }
+
+  void showKey() {
+    if (ShowColors) {
+      out << '\n';
+      setColor(llvm::raw_ostream::GREEN);
+      out << "GREEN";
+      resetColor();
+      out << " = enabled by default\n\n";
+    }
+  }
+};
+
+static void printUsage() {
+  llvm::errs() << "Usage: diagtool tree [--flags-only] [<diagnostic-group>]\n";
 }
 
 int TreeView::run(unsigned int argc, char **argv, llvm::raw_ostream &out) {
@@ -147,7 +154,7 @@
       ++argv;
     }
   }
-  
+
   bool ShowAll = false;
   StringRef RootGroup;
 
@@ -168,17 +175,8 @@
     return -1;
   }
 
-  if (showColors(out)) {
-    out << '\n';
-    setColor(true, out, llvm::raw_ostream::GREEN);
-    out << "GREEN";
-    resetColor(true, out);
-    out << " = enabled by default\n\n";
-  }
-  
-  if (ShowAll)
-    return showAll(out, FlagsOnly);
-
-  return showGroup(out, RootGroup, FlagsOnly);
+  TreePrinter TP(out);
+  TP.FlagsOnly = FlagsOnly;
+  TP.showKey();
+  return ShowAll ? TP.showAll() : TP.showGroup(RootGroup);
 }
-
diff --git a/tools/driver/CMakeLists.txt b/tools/driver/CMakeLists.txt
index c94bc77..805aebf 100644
--- a/tools/driver/CMakeLists.txt
+++ b/tools/driver/CMakeLists.txt
@@ -1,16 +1,30 @@
 set( LLVM_LINK_COMPONENTS
   ${LLVM_TARGETS_TO_BUILD}
-  asmparser
-  bitreader
-  bitwriter
-  irreader
-  codegen
-  instrumentation
-  ipo
-  linker
-  selectiondag
+  Analysis
+  CodeGen
+  Core
+  IPA
+  IPO
+  InstCombine
+  Instrumentation
+  MC
+  MCParser
+  ObjCARCOpts
+  Option
+  ScalarOpts
+  Support
+  TransformUtils
+  Vectorize
   )
 
+option(CLANG_PLUGIN_SUPPORT "Build clang with plugin support" ON)
+
+# Support plugins. This must be before add_clang_executable as it reads
+# LLVM_NO_DEAD_STRIP.
+if(CLANG_PLUGIN_SUPPORT)
+  set(LLVM_NO_DEAD_STRIP 1)
+endif()
+
 add_clang_executable(clang
   driver.cpp
   cc1_main.cpp
@@ -18,44 +32,18 @@
   )
 
 target_link_libraries(clang
-  clangFrontendTool
-  clangAST
-  clangAnalysis
   clangBasic
-  clangCodeGen
   clangDriver
-  clangEdit
   clangFrontend
-  clangLex
-  clangParse
-  clangEdit
-  clangSema
-  clangSerialization
+  clangFrontendTool
   )
 
-if(CLANG_ENABLE_STATIC_ANALYZER)
-  target_link_libraries(clang
-    clangStaticAnalyzerFrontend
-    clangStaticAnalyzerCheckers
-    clangStaticAnalyzerCore
-    )
-endif()
-
-if(CLANG_ENABLE_ARCMT)
-  target_link_libraries(clang
-    clangARCMigrate
-    )
-endif()
-
-if(CLANG_ENABLE_REWRITER)
-  target_link_libraries(clang
-    clangRewriteCore
-    clangRewriteFrontend
-    )
-endif()
-
 set_target_properties(clang PROPERTIES VERSION ${CLANG_EXECUTABLE_VERSION})
-set_target_properties(clang PROPERTIES ENABLE_EXPORTS 1)
+
+# Support plugins.
+if(CLANG_PLUGIN_SUPPORT)
+  set_target_properties(clang PROPERTIES ENABLE_EXPORTS 1)
+endif()
 
 add_dependencies(clang clang-headers)
 
@@ -65,21 +53,23 @@
   set(clang_binary "clang${CMAKE_EXECUTABLE_SUFFIX}")
 else()
   set(CLANGXX_LINK_OR_COPY copy)
-  set(clang_binary "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/clang${CMAKE_EXECUTABLE_SUFFIX}")
+  set(clang_binary "${LLVM_RUNTIME_OUTPUT_INTDIR}/clang${CMAKE_EXECUTABLE_SUFFIX}")
 endif()
 
 # Create the clang++ symlink in the build directory.
-set(clang_pp "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/clang++${CMAKE_EXECUTABLE_SUFFIX}")
+set(clang_pp "${LLVM_RUNTIME_OUTPUT_INTDIR}/clang++${CMAKE_EXECUTABLE_SUFFIX}")
 add_custom_command(TARGET clang POST_BUILD
-    COMMAND ${CMAKE_COMMAND} -E ${CLANGXX_LINK_OR_COPY} "${clang_binary}" "${clang_pp}")
+    COMMAND ${CMAKE_COMMAND} -E ${CLANGXX_LINK_OR_COPY} "${clang_binary}" "${clang_pp}"
+    WORKING_DIRECTORY "${LLVM_RUNTIME_OUTPUT_INTDIR}")
 
 set_property(DIRECTORY APPEND
   PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${clang_pp})
 
 # Create the clang-cl symlink in the build directory.
-set(clang_cl "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/clang-cl${CMAKE_EXECUTABLE_SUFFIX}")
+set(clang_cl "${LLVM_RUNTIME_OUTPUT_INTDIR}/clang-cl${CMAKE_EXECUTABLE_SUFFIX}")
 add_custom_command(TARGET clang POST_BUILD
-    COMMAND ${CMAKE_COMMAND} -E ${CLANGXX_LINK_OR_COPY} "${clang_binary}" "${clang_cl}")
+    COMMAND ${CMAKE_COMMAND} -E ${CLANGXX_LINK_OR_COPY} "${clang_binary}" "${clang_cl}"
+    WORKING_DIRECTORY "${LLVM_RUNTIME_OUTPUT_INTDIR}")
 
 set_property(DIRECTORY APPEND
   PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${clang_cl})
@@ -121,3 +111,11 @@
   target_link_libraries(clang "-Wl,-order_file,${CLANG_ORDER_FILE}")
 endif()
 
+if(WITH_POLLY AND LINK_POLLY_INTO_TOOLS)
+  target_link_libraries(clang Polly)
+  if(POLLY_LINK_LIBS)
+    foreach(lib ${POLLY_LINK_LIBS})
+      target_link_libraries(clang ${lib})
+    endforeach(lib)
+  endif(POLLY_LINK_LIBS)
+endif(WITH_POLLY AND LINK_POLLY_INTO_TOOLS)
diff --git a/tools/driver/Makefile b/tools/driver/Makefile
index f7a9f8f..347702e 100644
--- a/tools/driver/Makefile
+++ b/tools/driver/Makefile
@@ -11,12 +11,6 @@
 TOOLNAME = clang
 TOOLALIAS = clang++
 
-# We don't currently expect production Clang builds to be interested in
-# plugins. This is important for startup performance.
-ifdef CLANG_IS_PRODUCTION
-TOOL_NO_EXPORTS := 1
-endif
-
 ifdef CLANG_ORDER_FILE
 TOOL_ORDER_FILE := $(CLANG_ORDER_FILE)
 endif
@@ -29,10 +23,20 @@
 # LINK_COMPONENTS before including Makefile.rules
 include $(CLANG_LEVEL)/../../Makefile.config
 
+# Have the option of not supporting plugins. This is important for startup
+# performance.
+ifeq ($(CLANG_PLUGIN_SUPPORT), 1)
+NO_DEAD_STRIP := 1
+else
+TOOL_NO_EXPORTS := 1
+endif
+
 LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader bitwriter codegen \
-                   instrumentation ipo irreader linker selectiondag option
+                   instrumentation ipo irreader linker objcarcopts option \
+                   profiledata selectiondag
 USEDLIBS = clangFrontendTool.a clangFrontend.a clangDriver.a \
-           clangSerialization.a clangCodeGen.a clangParse.a clangSema.a
+           clangSerialization.a clangCodeGen.a clangParse.a clangSema.a \
+           clangRewriteFrontend.a clangRewrite.a
 
 ifeq ($(ENABLE_CLANG_STATIC_ANALYZER),1)
 USEDLIBS += clangStaticAnalyzerFrontend.a clangStaticAnalyzerCheckers.a \
@@ -43,11 +47,7 @@
 USEDLIBS += clangARCMigrate.a
 endif
 
-ifeq ($(ENABLE_CLANG_REWRITER),1)
-USEDLIBS += clangRewriteFrontend.a clangRewriteCore.a
-endif
-
-USEDLIBS += clangAnalysis.a clangEdit.a clangAST.a clangBasic.a clangLex.a
+USEDLIBS += clangAnalysis.a clangEdit.a clangAST.a clangLex.a clangBasic.a
 
 include $(CLANG_LEVEL)/Makefile
 
diff --git a/tools/driver/cc1_main.cpp b/tools/driver/cc1_main.cpp
index 5b3b5ad..990c4fc 100644
--- a/tools/driver/cc1_main.cpp
+++ b/tools/driver/cc1_main.cpp
@@ -21,6 +21,7 @@
 #include "clang/Frontend/FrontendDiagnostic.h"
 #include "clang/Frontend/TextDiagnosticBuffer.h"
 #include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "clang/Frontend/Utils.h"
 #include "clang/FrontendTool/Utils.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/LinkAllPasses.h"
@@ -56,9 +57,15 @@
   exit(GenCrashDiag ? 70 : 1);
 }
 
+#ifdef LINK_POLLY_INTO_TOOLS
+namespace polly {
+void initializePollyPasses(llvm::PassRegistry &Registry);
+}
+#endif
+
 int cc1_main(const char **ArgBegin, const char **ArgEnd,
              const char *Argv0, void *MainAddr) {
-  OwningPtr<CompilerInstance> Clang(new CompilerInstance());
+  std::unique_ptr<CompilerInstance> Clang(new CompilerInstance());
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
 
   // Initialize targets first, so that --version shows registered targets.
@@ -67,6 +74,11 @@
   llvm::InitializeAllAsmPrinters();
   llvm::InitializeAllAsmParsers();
 
+#ifdef LINK_POLLY_INTO_TOOLS
+  llvm::PassRegistry &Registry = *llvm::PassRegistry::getPassRegistry();
+  polly::initializePollyPasses(Registry);
+#endif
+
   // Buffer diagnostics from argument parsing so that we can output them using a
   // well formed diagnostic object.
   IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
@@ -112,7 +124,7 @@
   if (Clang->getFrontendOpts().DisableFree) {
     if (llvm::AreStatisticsEnabled() || Clang->getFrontendOpts().ShowStats)
       llvm::PrintStatistics();
-    Clang.take();
+    BuryPointer(Clang.release());
     return !Success;
   }
 
diff --git a/tools/driver/cc1as_main.cpp b/tools/driver/cc1as_main.cpp
index 31cd236..77cc3f8 100644
--- a/tools/driver/cc1as_main.cpp
+++ b/tools/driver/cc1as_main.cpp
@@ -14,13 +14,11 @@
 
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/DiagnosticOptions.h"
-#include "clang/Driver/CC1AsOptions.h"
 #include "clang/Driver/DriverDiagnostic.h"
 #include "clang/Driver/Options.h"
 #include "clang/Frontend/FrontendDiagnostic.h"
 #include "clang/Frontend/TextDiagnosticPrinter.h"
 #include "clang/Frontend/Utils.h"
-#include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/IR/DataLayout.h"
@@ -29,12 +27,14 @@
 #include "llvm/MC/MCCodeEmitter.h"
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCNaCl.h" // @LOCALMOD
 #include "llvm/MC/MCObjectFileInfo.h"
 #include "llvm/MC/MCParser/MCAsmParser.h"
 #include "llvm/MC/MCRegisterInfo.h"
 #include "llvm/MC/MCStreamer.h"
 #include "llvm/MC/MCSubtargetInfo.h"
 #include "llvm/MC/MCTargetAsmParser.h"
+#include "llvm/MC/MCTargetOptions.h"
 #include "llvm/Option/Arg.h"
 #include "llvm/Option/ArgList.h"
 #include "llvm/Option/OptTable.h"
@@ -53,9 +53,11 @@
 #include "llvm/Support/TargetSelect.h"
 #include "llvm/Support/Timer.h"
 #include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/system_error.h"
+#include <memory>
+#include <system_error>
 using namespace clang;
 using namespace clang::driver;
+using namespace clang::driver::options;
 using namespace llvm;
 using namespace llvm::opt;
 
@@ -85,6 +87,8 @@
   unsigned NoInitialTextSection : 1;
   unsigned SaveTemporaryLabels : 1;
   unsigned GenDwarfForAssembly : 1;
+  unsigned CompressDebugSections : 1;
+  unsigned DwarfVersion;
   std::string DwarfDebugFlags;
   std::string DwarfDebugProducer;
   std::string DebugCompilationDir;
@@ -135,6 +139,7 @@
     ShowEncoding = 0;
     RelaxAll = 0;
     NoExecStack = 0;
+    DwarfVersion = 3;
   }
 
   static bool CreateFromArgs(AssemblerInvocation &Res, const char **ArgBegin,
@@ -147,26 +152,29 @@
                                          const char **ArgBegin,
                                          const char **ArgEnd,
                                          DiagnosticsEngine &Diags) {
-  using namespace clang::driver::cc1asoptions;
   bool Success = true;
 
   // Parse the arguments.
-  OwningPtr<OptTable> OptTbl(createCC1AsOptTable());
+  std::unique_ptr<OptTable> OptTbl(createDriverOptTable());
+
+  const unsigned IncludedFlagsBitmask = options::CC1AsOption;
   unsigned MissingArgIndex, MissingArgCount;
-  OwningPtr<InputArgList> Args(
-    OptTbl->ParseArgs(ArgBegin, ArgEnd,MissingArgIndex, MissingArgCount));
+  std::unique_ptr<InputArgList> Args(
+      OptTbl->ParseArgs(ArgBegin, ArgEnd, MissingArgIndex, MissingArgCount,
+                        IncludedFlagsBitmask));
 
   // Check for missing argument error.
   if (MissingArgCount) {
     Diags.Report(diag::err_drv_missing_argument)
-      << Args->getArgString(MissingArgIndex) << MissingArgCount;
+        << Args->getArgString(MissingArgIndex) << MissingArgCount;
     Success = false;
   }
 
   // Issue errors on unknown arguments.
-  for (arg_iterator it = Args->filtered_begin(cc1asoptions::OPT_UNKNOWN),
-         ie = Args->filtered_end(); it != ie; ++it) {
-    Diags.Report(diag::err_drv_unknown_argument) << (*it) ->getAsString(*Args);
+  for (arg_iterator it = Args->filtered_begin(OPT_UNKNOWN),
+                    ie = Args->filtered_end();
+       it != ie; ++it) {
+    Diags.Report(diag::err_drv_unknown_argument) << (*it)->getAsString(*Args);
     Success = false;
   }
 
@@ -185,7 +193,14 @@
   Opts.IncludePaths = Args->getAllArgValues(OPT_I);
   Opts.NoInitialTextSection = Args->hasArg(OPT_n);
   Opts.SaveTemporaryLabels = Args->hasArg(OPT_msave_temp_labels);
-  Opts.GenDwarfForAssembly = Args->hasArg(OPT_g);
+  Opts.GenDwarfForAssembly = Args->hasArg(OPT_g_Flag);
+  Opts.CompressDebugSections = Args->hasArg(OPT_compress_debug_sections);
+  if (Args->hasArg(OPT_gdwarf_2))
+    Opts.DwarfVersion = 2;
+  if (Args->hasArg(OPT_gdwarf_3))
+    Opts.DwarfVersion = 3;
+  if (Args->hasArg(OPT_gdwarf_4))
+    Opts.DwarfVersion = 4;
   Opts.DwarfDebugFlags = Args->getLastArgValue(OPT_dwarf_debug_flags);
   Opts.DwarfDebugProducer = Args->getLastArgValue(OPT_dwarf_debug_producer);
   Opts.DebugCompilationDir = Args->getLastArgValue(OPT_fdebug_compilation_dir);
@@ -251,11 +266,12 @@
   std::string Error;
   raw_fd_ostream *Out =
       new raw_fd_ostream(Opts.OutputPath.c_str(), Error,
-                         (Binary ? sys::fs::F_Binary : sys::fs::F_None));
+                         (Binary ? sys::fs::F_None : sys::fs::F_Text));
   if (!Error.empty()) {
     Diags.Report(diag::err_fe_unable_to_open_output)
       << Opts.OutputPath << Error;
-    return 0;
+    delete Out;
+    return nullptr;
   }
 
   return new formatted_raw_ostream(*Out, formatted_raw_ostream::DELETE_STREAM);
@@ -265,43 +281,48 @@
                              DiagnosticsEngine &Diags) {
   // Get the target specific parser.
   std::string Error;
-  const Target *TheTarget(TargetRegistry::lookupTarget(Opts.Triple, Error));
-  if (!TheTarget) {
-    Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;
-    return false;
-  }
+  const Target *TheTarget = TargetRegistry::lookupTarget(Opts.Triple, Error);
+  if (!TheTarget)
+    return Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;
 
-  OwningPtr<MemoryBuffer> BufferPtr;
-  if (error_code ec = MemoryBuffer::getFileOrSTDIN(Opts.InputFile, BufferPtr)) {
-    Error = ec.message();
-    Diags.Report(diag::err_fe_error_reading) << Opts.InputFile;
-    return false;
+  ErrorOr<std::unique_ptr<MemoryBuffer>> Buffer =
+      MemoryBuffer::getFileOrSTDIN(Opts.InputFile);
+
+  if (std::error_code EC = Buffer.getError()) {
+    Error = EC.message();
+    return Diags.Report(diag::err_fe_error_reading) << Opts.InputFile;
   }
-  MemoryBuffer *Buffer = BufferPtr.take();
 
   SourceMgr SrcMgr;
 
   // Tell SrcMgr about this buffer, which is what the parser will pick up.
-  SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());
+  SrcMgr.AddNewSourceBuffer(Buffer->release(), SMLoc());
 
   // Record the location of the include directories so that the lexer can find
   // it later.
   SrcMgr.setIncludeDirs(Opts.IncludePaths);
 
-  OwningPtr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(Opts.Triple));
+  std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(Opts.Triple));
   assert(MRI && "Unable to create target register info!");
 
-  OwningPtr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, Opts.Triple));
+  std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, Opts.Triple));
   assert(MAI && "Unable to create target asm info!");
 
+  // Ensure MCAsmInfo initialization occurs before any use, otherwise sections
+  // may be created with a combination of default and explicit settings.
+  if (Opts.CompressDebugSections)
+    MAI->setCompressDebugSections(true);
+
   bool IsBinary = Opts.OutputType == AssemblerInvocation::FT_Obj;
-  formatted_raw_ostream *Out = GetOutputStream(Opts, Diags, IsBinary);
+  std::unique_ptr<formatted_raw_ostream> Out(
+      GetOutputStream(Opts, Diags, IsBinary));
   if (!Out)
-    return false;
+    return true;
 
   // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and
   // MCObjectFileInfo needs a MCContext reference in order to initialize itself.
-  OwningPtr<MCObjectFileInfo> MOFI(new MCObjectFileInfo());
+  std::unique_ptr<MCObjectFileInfo> MOFI(new MCObjectFileInfo());
+
   MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &SrcMgr);
   // FIXME: Assembler behavior can change with -static.
   MOFI->InitMCObjectFileInfo(Opts.Triple,
@@ -318,6 +339,7 @@
     Ctx.setCompilationDir(Opts.DebugCompilationDir);
   if (!Opts.MainFileName.empty())
     Ctx.setMainFileName(StringRef(Opts.MainFileName));
+  Ctx.setDwarfVersion(Opts.DwarfVersion);
 
   // Build up the feature string from the target feature list.
   std::string FS;
@@ -327,26 +349,24 @@
       FS += "," + Opts.Features[i];
   }
 
-  OwningPtr<MCStreamer> Str;
+  std::unique_ptr<MCStreamer> Str;
 
-  OwningPtr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
-  OwningPtr<MCSubtargetInfo>
-    STI(TheTarget->createMCSubtargetInfo(Opts.Triple, Opts.CPU, FS));
+  std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
+  std::unique_ptr<MCSubtargetInfo> STI(
+      TheTarget->createMCSubtargetInfo(Opts.Triple, Opts.CPU, FS));
 
   // FIXME: There is a bit of code duplication with addPassesToEmitFile.
   if (Opts.OutputType == AssemblerInvocation::FT_Asm) {
     MCInstPrinter *IP =
       TheTarget->createMCInstPrinter(Opts.OutputAsmVariant, *MAI, *MCII, *MRI,
                                      *STI);
-    MCCodeEmitter *CE = 0;
-    MCAsmBackend *MAB = 0;
+    MCCodeEmitter *CE = nullptr;
+    MCAsmBackend *MAB = nullptr;
     if (Opts.ShowEncoding) {
       CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx);
       MAB = TheTarget->createMCAsmBackend(*MRI, Opts.Triple, Opts.CPU);
     }
     Str.reset(TheTarget->createAsmStreamer(Ctx, *Out, /*asmverbose*/true,
-                                           /*useLoc*/ true,
-                                           /*useCFI*/ true,
                                            /*useDwarfDirectory*/ true,
                                            IP, CE, MAB,
                                            Opts.ShowInst));
@@ -359,31 +379,41 @@
     MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, Opts.Triple,
                                                       Opts.CPU);
     Str.reset(TheTarget->createMCObjectStreamer(Opts.Triple, Ctx, *MAB, *Out,
-                                                CE, Opts.RelaxAll,
+                                                CE, *STI, Opts.RelaxAll,
                                                 Opts.NoExecStack));
+    // @LOCALMOD-BEGIN
+    Triple T(Opts.Triple);
+    if (T.isOSNaCl())
+      initializeNaClMCStreamer(*Str.get(), Ctx, T);
+    // @LOCALMOD-END
     Str.get()->InitSections();
   }
 
-  OwningPtr<MCAsmParser> Parser(createMCAsmParser(SrcMgr, Ctx,
-                                                  *Str.get(), *MAI));
-  OwningPtr<MCTargetAsmParser> TAP(TheTarget->createMCAsmParser(*STI, *Parser, *MCII));
-  if (!TAP) {
-    Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;
-    return false;
+  bool Failed = false;
+
+  std::unique_ptr<MCAsmParser> Parser(
+      createMCAsmParser(SrcMgr, Ctx, *Str.get(), *MAI));
+
+  // FIXME: init MCTargetOptions from sanitizer flags here.
+  MCTargetOptions Options;
+  std::unique_ptr<MCTargetAsmParser> TAP(
+      TheTarget->createMCAsmParser(*STI, *Parser, *MCII, Options));
+  if (!TAP)
+    Failed = Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;
+
+  if (!Failed) {
+    Parser->setTargetParser(*TAP.get());
+    Failed = Parser->Run(Opts.NoInitialTextSection);
   }
 
-  Parser->setTargetParser(*TAP.get());
+  // Close the output stream early.
+  Out.reset();
 
-  bool Success = !Parser->Run(Opts.NoInitialTextSection);
-
-  // Close the output.
-  delete Out;
-
-  // Delete output on errors.
-  if (!Success && Opts.OutputPath != "-")
+  // Delete output file if there were errors.
+  if (Failed && Opts.OutputPath != "-")
     sys::fs::remove(Opts.OutputPath);
 
-  return Success;
+  return Failed;
 }
 
 static void LLVMErrorHandler(void *UserData, const std::string &Message,
@@ -426,10 +456,10 @@
   if (!AssemblerInvocation::CreateFromArgs(Asm, ArgBegin, ArgEnd, Diags))
     return 1;
 
-  // Honor -help.
   if (Asm.ShowHelp) {
-    OwningPtr<OptTable> Opts(driver::createCC1AsOptTable());
-    Opts->PrintHelp(llvm::outs(), "clang -cc1as", "Clang Integrated Assembler");
+    std::unique_ptr<OptTable> Opts(driver::createDriverOptTable());
+    Opts->PrintHelp(llvm::outs(), "clang -cc1as", "Clang Integrated Assembler",
+                    /*Include=*/driver::options::CC1AsOption, /*Exclude=*/0);
     return 0;
   }
 
@@ -450,18 +480,17 @@
     Args[0] = "clang (LLVM option parsing)";
     for (unsigned i = 0; i != NumArgs; ++i)
       Args[i + 1] = Asm.LLVMArgs[i].c_str();
-    Args[NumArgs + 1] = 0;
+    Args[NumArgs + 1] = nullptr;
     llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args);
   }
 
   // Execute the invocation, unless there were parsing errors.
-  bool Success = false;
-  if (!Diags.hasErrorOccurred())
-    Success = ExecuteAssembler(Asm, Diags);
+  bool Failed = Diags.hasErrorOccurred() || ExecuteAssembler(Asm, Diags);
 
   // If any timers were active but haven't been destroyed yet, print their
   // results now.
   TimerGroup::printAll(errs());
 
-  return !Success;
+  return !!Failed;
 }
+
diff --git a/tools/driver/driver.cpp b/tools/driver/driver.cpp
index 3a6a09b..9f93837 100644
--- a/tools/driver/driver.cpp
+++ b/tools/driver/driver.cpp
@@ -22,10 +22,10 @@
 #include "clang/Frontend/TextDiagnosticPrinter.h"
 #include "clang/Frontend/Utils.h"
 #include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/Config/llvm-config.h"
 #include "llvm/Option/ArgList.h"
 #include "llvm/Option/OptTable.h"
 #include "llvm/Option/Option.h"
@@ -45,7 +45,8 @@
 #include "llvm/Support/TargetSelect.h"
 #include "llvm/Support/Timer.h"
 #include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/system_error.h"
+#include <memory>
+#include <system_error>
 using namespace clang;
 using namespace clang::driver;
 using namespace llvm::opt;
@@ -169,7 +170,7 @@
     OS = &llvm::nulls();
   }
 
-  *OS << "### QA_OVERRIDE_GCC3_OPTIONS: " << OverrideStr << "\n";
+  *OS << "### CCC_OVERRIDE_OPTIONS: " << OverrideStr << "\n";
 
   // This does not need to be efficient.
 
@@ -213,22 +214,25 @@
     const char *Suffix;
     const char *ModeFlag;
   } suffixes [] = {
-    { "clang",     0 },
+    { "clang",     nullptr },
     { "clang++",   "--driver-mode=g++" },
     { "clang-c++", "--driver-mode=g++" },
-    { "clang-cc",  0 },
+    { "clang-cc",  nullptr },
     { "clang-cpp", "--driver-mode=cpp" },
     { "clang-g++", "--driver-mode=g++" },
-    { "clang-gcc", 0 },
+    { "clang-gcc", nullptr },
     { "clang-cl",  "--driver-mode=cl"  },
-    { "cc",        0 },
+    { "cc",        nullptr },
     { "cpp",       "--driver-mode=cpp" },
     { "cl" ,       "--driver-mode=cl"  },
     { "++",        "--driver-mode=g++" },
   };
   std::string ProgName(llvm::sys::path::stem(ArgVector[0]));
+#ifdef LLVM_ON_WIN32
+  // Transform to lowercase for case insensitive file systems.
   std::transform(ProgName.begin(), ProgName.end(), ProgName.begin(),
                  toLowercase);
+#endif
   StringRef ProgNameRef(ProgName);
   StringRef Prefix;
 
@@ -281,7 +285,7 @@
   class StringSetSaver : public llvm::cl::StringSaver {
   public:
     StringSetSaver(std::set<std::string> &Storage) : Storage(Storage) {}
-    const char *SaveString(const char *Str) LLVM_OVERRIDE {
+    const char *SaveString(const char *Str) override {
       return SaveStringInSet(Storage, Str);
     }
   private:
@@ -295,8 +299,8 @@
 
   SmallVector<const char *, 256> argv;
   llvm::SpecificBumpPtrAllocator<char> ArgAllocator;
-  llvm::error_code EC = llvm::sys::Process::GetArgumentVector(
-      argv, llvm::ArrayRef<const char *>(argv_, argc_), ArgAllocator);
+  std::error_code EC = llvm::sys::Process::GetArgumentVector(
+      argv, ArrayRef<const char *>(argv_, argc_), ArgAllocator);
   if (EC) {
     llvm::errs() << "error: couldn't get arguments: " << EC.message() << '\n';
     return 1;
@@ -330,9 +334,9 @@
     }
   }
 
-  // Handle QA_OVERRIDE_GCC3_OPTIONS and CCC_ADD_ARGS, used for editing a
-  // command line behind the scenes.
-  if (const char *OverrideStr = ::getenv("QA_OVERRIDE_GCC3_OPTIONS")) {
+  // Handle CCC_OVERRIDE_OPTIONS, used for editing a command line behind the
+  // scenes.
+  if (const char *OverrideStr = ::getenv("CCC_OVERRIDE_OPTIONS")) {
     // FIXME: Driver shouldn't take extra initial argument.
     ApplyQAOverride(argv, OverrideStr, SavedStrings);
   }
@@ -341,11 +345,10 @@
 
   IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions;
   {
-    OwningPtr<OptTable> Opts(createDriverOptTable());
+    std::unique_ptr<OptTable> Opts(createDriverOptTable());
     unsigned MissingArgIndex, MissingArgCount;
-    OwningPtr<InputArgList> Args(Opts->ParseArgs(argv.begin()+1, argv.end(),
-                                                 MissingArgIndex,
-                                                 MissingArgCount));
+    std::unique_ptr<InputArgList> Args(Opts->ParseArgs(
+        argv.begin() + 1, argv.end(), MissingArgIndex, MissingArgCount));
     // We ignore MissingArgCount and the return value of ParseDiagnosticArgs.
     // Any errors that would be diagnosed here will also be diagnosed later,
     // when the DiagnosticsEngine actually exists.
@@ -368,7 +371,7 @@
   DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagClient);
   ProcessWarningOptions(Diags, *DiagOpts, /*ReportDiags=*/false);
 
-  Driver TheDriver(Path, llvm::sys::getDefaultTargetTriple(), "a.out", Diags);
+  Driver TheDriver(Path, llvm::sys::getDefaultTargetTriple(), Diags);
 
   // Attempt to find the original path used to invoke the driver, to determine
   // the installed path. We do this manually, because we want to support that
@@ -408,7 +411,7 @@
   if (TheDriver.CCLogDiagnostics)
     TheDriver.CCLogDiagnosticsFilename = ::getenv("CC_LOG_DIAGNOSTICS_FILE");
 
-  OwningPtr<Compilation> C(TheDriver.BuildCompilation(argv));
+  std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(argv));
   int Res = 0;
   SmallVector<std::pair<int, const Command *>, 4> FailingCommands;
   if (C.get())
@@ -417,7 +420,7 @@
   // Force a crash to test the diagnostics.
   if (::getenv("FORCE_CLANG_DIAGNOSTICS_CRASH")) {
     Diags.Report(diag::err_drv_force_crash) << "FORCE_CLANG_DIAGNOSTICS_CRASH";
-    const Command *FailingCommand = 0;
+    const Command *FailingCommand = nullptr;
     FailingCommands.push_back(std::make_pair(-1, FailingCommand));
   }
 
@@ -430,8 +433,13 @@
 
     // If result status is < 0, then the driver command signalled an error.
     // If result status is 70, then the driver command reported a fatal error.
-    // In these cases, generate additional diagnostic information if possible.
-    if (CommandRes < 0 || CommandRes == 70) {
+    // On Windows, abort will return an exit code of 3.  In these cases,
+    // generate additional diagnostic information if possible.
+    bool DiagnoseCrash = CommandRes < 0 || CommandRes == 70;
+#ifdef LLVM_ON_WIN32
+    DiagnoseCrash |= CommandRes == 3;
+#endif
+    if (DiagnoseCrash) {
       TheDriver.generateCompilationDiagnostics(*C, FailingCommand);
       break;
     }
@@ -443,7 +451,7 @@
   
   llvm::llvm_shutdown();
 
-#ifdef _WIN32
+#ifdef LLVM_ON_WIN32
   // Exit status should not be negative on Win32, unless abnormal termination.
   // Once abnormal termiation was caught, negative status should not be
   // propagated.
diff --git a/tools/libclang/ARCMigrate.cpp b/tools/libclang/ARCMigrate.cpp
index 3941794..375c5f4 100644
--- a/tools/libclang/ARCMigrate.cpp
+++ b/tools/libclang/ARCMigrate.cpp
@@ -35,12 +35,16 @@
 extern "C" {
 
 CXRemapping clang_getRemappings(const char *migrate_dir_path) {
+#ifndef CLANG_ENABLE_ARCMT
+  llvm::errs() << "error: feature not enabled in this build\n";
+  return nullptr;
+#else
   bool Logging = ::getenv("LIBCLANG_LOGGING");
 
   if (!migrate_dir_path) {
     if (Logging)
       llvm::errs() << "clang_getRemappings was called with NULL parameter\n";
-    return 0;
+    return nullptr;
   }
 
   bool exists = false;
@@ -51,11 +55,11 @@
                    << "\")\n";
       llvm::errs() << "\"" << migrate_dir_path << "\" does not exist\n";
     }
-    return 0;
+    return nullptr;
   }
 
   TextDiagnosticBuffer diagBuffer;
-  OwningPtr<Remap> remap(new Remap());
+  std::unique_ptr<Remap> remap(new Remap());
 
   bool err = arcmt::getFileRemappings(remap->Vec, migrate_dir_path,&diagBuffer);
 
@@ -67,30 +71,35 @@
              I = diagBuffer.err_begin(), E = diagBuffer.err_end(); I != E; ++I)
         llvm::errs() << I->second << '\n';
     }
-    return 0;
+    return nullptr;
   }
 
-  return remap.take();
+  return remap.release();
+#endif
 }
 
 CXRemapping clang_getRemappingsFromFileList(const char **filePaths,
                                             unsigned numFiles) {
+#ifndef CLANG_ENABLE_ARCMT
+  llvm::errs() << "error: feature not enabled in this build\n";
+  return nullptr;
+#else
   bool Logging = ::getenv("LIBCLANG_LOGGING");
 
-  OwningPtr<Remap> remap(new Remap());
+  std::unique_ptr<Remap> remap(new Remap());
 
   if (numFiles == 0) {
     if (Logging)
       llvm::errs() << "clang_getRemappingsFromFileList was called with "
                       "numFiles=0\n";
-    return remap.take();
+    return remap.release();
   }
 
   if (!filePaths) {
     if (Logging)
       llvm::errs() << "clang_getRemappingsFromFileList was called with "
                       "NULL filePaths\n";
-    return 0;
+    return nullptr;
   }
 
   TextDiagnosticBuffer diagBuffer;
@@ -108,10 +117,11 @@
              I = diagBuffer.err_begin(), E = diagBuffer.err_end(); I != E; ++I)
         llvm::errs() << I->second << '\n';
     }
-    return remap.take();
+    return remap.release();
   }
 
-  return remap.take();
+  return remap.release();
+#endif
 }
 
 unsigned clang_remap_getNumFiles(CXRemapping map) {
diff --git a/tools/libclang/BuildSystem.cpp b/tools/libclang/BuildSystem.cpp
new file mode 100644
index 0000000..e9423c3
--- /dev/null
+++ b/tools/libclang/BuildSystem.cpp
@@ -0,0 +1,147 @@
+//===- BuildSystem.cpp - Utilities for use by build systems ---------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements various utilities for use by build systems.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang-c/BuildSystem.h"
+#include "CXString.h"
+#include "clang/Basic/VirtualFileSystem.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/CBindingWrapping.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/TimeValue.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+using namespace llvm::sys;
+
+unsigned long long clang_getBuildSessionTimestamp(void) {
+  return llvm::sys::TimeValue::now().toEpochTime();
+}
+
+DEFINE_SIMPLE_CONVERSION_FUNCTIONS(clang::vfs::YAMLVFSWriter,
+                                   CXVirtualFileOverlay)
+
+CXVirtualFileOverlay clang_VirtualFileOverlay_create(unsigned) {
+  return wrap(new clang::vfs::YAMLVFSWriter());
+}
+
+enum CXErrorCode
+clang_VirtualFileOverlay_addFileMapping(CXVirtualFileOverlay VFO,
+                                        const char *virtualPath,
+                                        const char *realPath) {
+  if (!VFO || !virtualPath || !realPath)
+    return CXError_InvalidArguments;
+  if (!path::is_absolute(virtualPath))
+    return CXError_InvalidArguments;
+  if (!path::is_absolute(realPath))
+    return CXError_InvalidArguments;
+
+  for (path::const_iterator
+         PI = path::begin(virtualPath),
+         PE = path::end(virtualPath); PI != PE; ++PI) {
+    StringRef Comp = *PI;
+    if (Comp == "." || Comp == "..")
+      return CXError_InvalidArguments;
+  }
+
+  unwrap(VFO)->addFileMapping(virtualPath, realPath);
+  return CXError_Success;
+}
+
+enum CXErrorCode
+clang_VirtualFileOverlay_setCaseSensitivity(CXVirtualFileOverlay VFO,
+                                            int caseSensitive) {
+  if (!VFO)
+    return CXError_InvalidArguments;
+  unwrap(VFO)->setCaseSensitivity(caseSensitive);
+  return CXError_Success;
+}
+
+enum CXErrorCode
+clang_VirtualFileOverlay_writeToBuffer(CXVirtualFileOverlay VFO, unsigned,
+                                       char **out_buffer_ptr,
+                                       unsigned *out_buffer_size) {
+  if (!VFO || !out_buffer_ptr || !out_buffer_size)
+    return CXError_InvalidArguments;
+
+  llvm::SmallString<256> Buf;
+  llvm::raw_svector_ostream OS(Buf);
+  unwrap(VFO)->write(OS);
+
+  StringRef Data = OS.str();
+  *out_buffer_ptr = (char*)malloc(Data.size());
+  *out_buffer_size = Data.size();
+  memcpy(*out_buffer_ptr, Data.data(), Data.size());
+  return CXError_Success;
+}
+
+void clang_VirtualFileOverlay_dispose(CXVirtualFileOverlay VFO) {
+  delete unwrap(VFO);
+}
+
+
+struct CXModuleMapDescriptorImpl {
+  std::string ModuleName;
+  std::string UmbrellaHeader;
+};
+
+CXModuleMapDescriptor clang_ModuleMapDescriptor_create(unsigned) {
+  return new CXModuleMapDescriptorImpl();
+}
+
+enum CXErrorCode
+clang_ModuleMapDescriptor_setFrameworkModuleName(CXModuleMapDescriptor MMD,
+                                                 const char *name) {
+  if (!MMD || !name)
+    return CXError_InvalidArguments;
+
+  MMD->ModuleName = name;
+  return CXError_Success;
+}
+
+enum CXErrorCode
+clang_ModuleMapDescriptor_setUmbrellaHeader(CXModuleMapDescriptor MMD,
+                                            const char *name) {
+  if (!MMD || !name)
+    return CXError_InvalidArguments;
+
+  MMD->UmbrellaHeader = name;
+  return CXError_Success;
+}
+
+enum CXErrorCode
+clang_ModuleMapDescriptor_writeToBuffer(CXModuleMapDescriptor MMD, unsigned,
+                                       char **out_buffer_ptr,
+                                       unsigned *out_buffer_size) {
+  if (!MMD || !out_buffer_ptr || !out_buffer_size)
+    return CXError_InvalidArguments;
+
+  llvm::SmallString<256> Buf;
+  llvm::raw_svector_ostream OS(Buf);
+  OS << "framework module " << MMD->ModuleName << " {\n";
+  OS << "  umbrella header \"";
+  OS.write_escaped(MMD->UmbrellaHeader) << "\"\n";
+  OS << '\n';
+  OS << "  export *\n";
+  OS << "  module * { export * }\n";
+  OS << "}\n";
+
+  StringRef Data = OS.str();
+  *out_buffer_ptr = (char*)malloc(Data.size());
+  *out_buffer_size = Data.size();
+  memcpy(*out_buffer_ptr, Data.data(), Data.size());
+  return CXError_Success;
+}
+
+void clang_ModuleMapDescriptor_dispose(CXModuleMapDescriptor MMD) {
+  delete MMD;
+}
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index f53e5c1..fc8703a 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -15,7 +15,6 @@
 #include "CIndexer.h"
 #include "CIndexDiagnostic.h"
 #include "CLog.h"
-#include "CXComment.h"
 #include "CXCursor.h"
 #include "CXSourceLocation.h"
 #include "CXString.h"
@@ -25,6 +24,8 @@
 #include "clang/AST/Attr.h"
 #include "clang/AST/StmtVisitor.h"
 #include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticCategories.h"
+#include "clang/Basic/DiagnosticIDs.h"
 #include "clang/Basic/Version.h"
 #include "clang/Frontend/ASTUnit.h"
 #include "clang/Frontend/CompilerInstance.h"
@@ -34,13 +35,15 @@
 #include "clang/Lex/Lexer.h"
 #include "clang/Lex/PreprocessingRecord.h"
 #include "clang/Lex/Preprocessor.h"
+#include "clang/Serialization/SerializationDiagnostic.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringSwitch.h"
-#include "llvm/Config/config.h"
+#include "llvm/Config/llvm-config.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/CrashRecoveryContext.h"
 #include "llvm/Support/Format.h"
+#include "llvm/Support/ManagedStatic.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Mutex.h"
 #include "llvm/Support/Program.h"
@@ -50,7 +53,11 @@
 #include "llvm/Support/Timer.h"
 #include "llvm/Support/raw_ostream.h"
 
-#if HAVE_PTHREAD_H
+#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
+#define USE_DARWIN_THREADS
+#endif
+
+#ifdef USE_DARWIN_THREADS
 #include <pthread.h>
 #endif
 
@@ -61,17 +68,30 @@
 
 CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
   if (!AU)
-    return 0;
+    return nullptr;
+  assert(CIdx);
   CXTranslationUnit D = new CXTranslationUnitImpl();
   D->CIdx = CIdx;
   D->TheASTUnit = AU;
   D->StringPool = new cxstring::CXStringPool();
-  D->Diagnostics = 0;
+  D->Diagnostics = nullptr;
   D->OverridenCursorsPool = createOverridenCXCursorsPool();
-  D->CommentToXML = 0;
+  D->CommentToXML = nullptr;
   return D;
 }
 
+bool cxtu::isASTReadError(ASTUnit *AU) {
+  for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
+                                     DEnd = AU->stored_diag_end();
+       D != DEnd; ++D) {
+    if (D->getLevel() >= DiagnosticsEngine::Error &&
+        DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
+            diag::DiagCat_AST_Deserialization_Issue)
+      return true;
+  }
+  return false;
+}
+
 cxtu::CXTUOwner::~CXTUOwner() {
   if (TU)
     clang_disposeTranslationUnit(TU);
@@ -298,7 +318,7 @@
     if (Outer.isInvalid())
       return false;
 
-    llvm::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
+    std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
     Length = 0;
     Unit->findFileRegionDecls(File, Offset, Length, Decls);
   }
@@ -306,7 +326,7 @@
   assert(!Decls.empty());
 
   bool VisitedAtLeastOnce = false;
-  DeclContext *CurDC = 0;
+  DeclContext *CurDC = nullptr;
   SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
   for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
     Decl *D = *DIt;
@@ -335,7 +355,7 @@
       FileDI_current = &DIt;
       FileDE_current = DE;
     } else {
-      FileDI_current = 0;
+      FileDI_current = nullptr;
     }
 
     if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
@@ -769,7 +789,7 @@
     // If we have a function declared directly (without the use of a typedef),
     // visit just the return type. Otherwise, just visit the function's type
     // now.
-    if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getResultLoc())) ||
+    if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
         (!FTL && Visit(TL)))
       return true;
     
@@ -779,8 +799,9 @@
         return true;
     
     // Visit the declaration name.
-    if (VisitDeclarationNameInfo(ND->getNameInfo()))
-      return true;
+    if (!isa<CXXDestructorDecl>(ND))
+      if (VisitDeclarationNameInfo(ND->getNameInfo()))
+        return true;
     
     // FIXME: Visit explicitly-specified template arguments!
     
@@ -795,13 +816,11 @@
     if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
       // Find the initializers that were written in the source.
       SmallVector<CXXCtorInitializer *, 4> WrittenInits;
-      for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
-                                          IEnd = Constructor->init_end();
-           I != IEnd; ++I) {
-        if (!(*I)->isWritten())
+      for (auto *I : Constructor->inits()) {
+        if (!I->isWritten())
           continue;
       
-        WrittenInits.push_back(*I);
+        WrittenInits.push_back(I);
       }
       
       // Sort the initializers in source order
@@ -895,14 +914,12 @@
 }
 
 bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
-  if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo())
+  if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
     if (Visit(TSInfo->getTypeLoc()))
       return true;
 
-  for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
-       PEnd = ND->param_end();
-       P != PEnd; ++P) {
-    if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
+  for (const auto *P : ND->params()) {
+    if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
       return true;
   }
 
@@ -934,19 +951,6 @@
   }
 }
 
-namespace {
-  struct ContainerDeclsSort {
-    SourceManager &SM;
-    ContainerDeclsSort(SourceManager &sm) : SM(sm) {}
-    bool operator()(Decl *A, Decl *B) {
-      SourceLocation L_A = A->getLocStart();
-      SourceLocation L_B = B->getLocStart();
-      assert(L_A.isValid() && L_B.isValid());
-      return SM.isBeforeInTranslationUnit(L_A, L_B);
-    }
-  };
-}
-
 bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
   // FIXME: Eventually convert back to just 'VisitDeclContext()'.  Essentially
   // an @implementation can lexically contain Decls that are not properly
@@ -978,18 +982,21 @@
 
   // Get all the Decls in the DeclContext, and sort them with the
   // additional ones we've collected.  Then visit them.
-  for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
-       I!=E; ++I) {
-    Decl *subDecl = *I;
-    if (!subDecl || subDecl->getLexicalDeclContext() != D ||
-        subDecl->getLocStart().isInvalid())
+  for (auto *SubDecl : D->decls()) {
+    if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
+        SubDecl->getLocStart().isInvalid())
       continue;
-    DeclsInContainer.push_back(subDecl);
+    DeclsInContainer.push_back(SubDecl);
   }
 
   // Now sort the Decls so that they appear in lexical order.
   std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
-            ContainerDeclsSort(SM));
+            [&SM](Decl *A, Decl *B) {
+    SourceLocation L_A = A->getLocStart();
+    SourceLocation L_B = B->getLocStart();
+    assert(L_A.isValid() && L_B.isValid());
+    return SM.isBeforeInTranslationUnit(L_A, L_B);
+  });
 
   // Now visit the decls.
   for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
@@ -1517,11 +1524,11 @@
 
 bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL, 
                                          bool SkipResultType) {
-  if (!SkipResultType && Visit(TL.getResultLoc()))
+  if (!SkipResultType && Visit(TL.getReturnLoc()))
     return true;
 
-  for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
-    if (Decl *D = TL.getArg(I))
+  for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
+    if (Decl *D = TL.getParam(I))
       if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
         return true;
 
@@ -1542,6 +1549,10 @@
   return Visit(TL.getOriginalLoc());
 }
 
+bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
+  return Visit(TL.getOriginalLoc());
+}
+
 bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
                                              TemplateSpecializationTypeLoc TL) {
   // Visit the template name.
@@ -1651,9 +1662,8 @@
       return true;
 
   if (D->isCompleteDefinition()) {
-    for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
-         E = D->bases_end(); I != E; ++I) {
-      if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
+    for (const auto &I : D->bases()) {
+      if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
         return true;
     }
   }
@@ -1662,9 +1672,8 @@
 }
 
 bool CursorVisitor::VisitAttributes(Decl *D) {
-  for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
-       i != e; ++i)
-    if (Visit(MakeCXCursor(*i, D, TU)))
+  for (const auto *I : D->attrs())
+    if (Visit(MakeCXCursor(I, D, TU)))
         return true;
 
   return false;
@@ -1699,7 +1708,7 @@
 public:
   DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
     VisitorJob(parent, VisitorJob::DeclVisitKind,
-               D, isFirst ? (void*) 1 : (void*) 0) {}
+               D, isFirst ? (void*) 1 : (void*) nullptr) {}
   static bool classof(const VisitorJob *VJ) {
     return VJ->getKind() == DeclVisitKind;
   }
@@ -1775,6 +1784,8 @@
       return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
     case Stmt::DependentScopeDeclRefExprClass:
       return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
+    case Stmt::OMPCriticalDirectiveClass:
+      return cast<OMPCriticalDirective>(S)->getDirectiveName();
     }
   }
 };
@@ -1835,8 +1846,6 @@
   void VisitStmt(const Stmt *S);
   void VisitSwitchStmt(const SwitchStmt *S);
   void VisitWhileStmt(const WhileStmt *W);
-  void VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E);
-  void VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E);
   void VisitTypeTraitExpr(const TypeTraitExpr *E);
   void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
   void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
@@ -1848,6 +1857,20 @@
   void VisitLambdaExpr(const LambdaExpr *E);
   void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
   void VisitOMPParallelDirective(const OMPParallelDirective *D);
+  void VisitOMPSimdDirective(const OMPSimdDirective *D);
+  void VisitOMPForDirective(const OMPForDirective *D);
+  void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
+  void VisitOMPSectionDirective(const OMPSectionDirective *D);
+  void VisitOMPSingleDirective(const OMPSingleDirective *D);
+  void VisitOMPMasterDirective(const OMPMasterDirective *D);
+  void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
+  void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
+  void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
+  void VisitOMPTaskDirective(const OMPTaskDirective *D);
+  void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
+  void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
+  void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
+  void VisitOMPFlushDirective(const OMPFlushDirective *D);
 
 private:
   void AddDeclarationNameInfo(const Stmt *S);
@@ -1920,14 +1943,46 @@
 #include "clang/Basic/OpenMPKinds.def"
 };
 
+void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
+  Visitor->AddStmt(C->getCondition());
+}
+
+void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
+  Visitor->AddStmt(C->getCondition());
+}
+
+void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
+  Visitor->AddStmt(C->getNumThreads());
+}
+
+void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
+  Visitor->AddStmt(C->getSafelen());
+}
+
+void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
+  Visitor->AddStmt(C->getNumForLoops());
+}
+
 void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
 
+void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
+
+void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
+  Visitor->AddStmt(C->getChunkSize());
+}
+
+void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
+
+void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
+
+void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
+
+void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
+
 template<typename T>
 void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
-  for (typename T::varlist_const_iterator I = Node->varlist_begin(),
-                                          E = Node->varlist_end();
-         I != E; ++I)
-    Visitor->AddStmt(*I);
+  for (const auto *I : Node->varlists())
+    Visitor->AddStmt(I);
 }
 
 void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
@@ -1937,9 +1992,34 @@
                                         const OMPFirstprivateClause *C) {
   VisitOMPClauseList(C);
 }
+void OMPClauseEnqueue::VisitOMPLastprivateClause(
+                                        const OMPLastprivateClause *C) {
+  VisitOMPClauseList(C);
+}
 void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
   VisitOMPClauseList(C);
 }
+void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
+  VisitOMPClauseList(C);
+}
+void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
+  VisitOMPClauseList(C);
+  Visitor->AddStmt(C->getStep());
+}
+void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
+  VisitOMPClauseList(C);
+  Visitor->AddStmt(C->getAlignment());
+}
+void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
+  VisitOMPClauseList(C);
+}
+void
+OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
+  VisitOMPClauseList(C);
+}
+void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
+  VisitOMPClauseList(C);
+}
 }
 
 void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
@@ -2062,9 +2142,8 @@
 void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
   unsigned size = WL.size();
   bool isFirst = true;
-  for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
-       D != DEnd; ++D) {
-    AddDecl(*D, isFirst);
+  for (const auto *D : S->decls()) {
+    AddDecl(D, isFirst);
     isFirst = false;
   }
   if (size == WL.size())
@@ -2181,15 +2260,6 @@
   AddDecl(W->getConditionVariable());
 }
 
-void EnqueueVisitor::VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) {
-  AddTypeLoc(E->getQueriedTypeSourceInfo());
-}
-
-void EnqueueVisitor::VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E) {
-  AddTypeLoc(E->getRhsTypeSourceInfo());
-  AddTypeLoc(E->getLhsTypeSourceInfo());
-}
-
 void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
   for (unsigned I = E->getNumArgs(); I > 0; --I)
     AddTypeLoc(E->getArg(I-1));
@@ -2243,6 +2313,66 @@
   VisitOMPExecutableDirective(D);
 }
 
+void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
+  VisitOMPExecutableDirective(D);
+}
+
+void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
+  VisitOMPExecutableDirective(D);
+}
+
+void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
+  VisitOMPExecutableDirective(D);
+}
+
+void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
+  VisitOMPExecutableDirective(D);
+}
+
+void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
+  VisitOMPExecutableDirective(D);
+}
+
+void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
+  VisitOMPExecutableDirective(D);
+}
+
+void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
+  VisitOMPExecutableDirective(D);
+  AddDeclarationNameInfo(D);
+}
+
+void
+EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
+  VisitOMPExecutableDirective(D);
+}
+
+void EnqueueVisitor::VisitOMPParallelSectionsDirective(
+    const OMPParallelSectionsDirective *D) {
+  VisitOMPExecutableDirective(D);
+}
+
+void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
+  VisitOMPExecutableDirective(D);
+}
+
+void
+EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
+  VisitOMPExecutableDirective(D);
+}
+
+void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
+  VisitOMPExecutableDirective(D);
+}
+
+void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
+  VisitOMPExecutableDirective(D);
+}
+
+void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
+  VisitOMPExecutableDirective(D);
+}
+
 void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
   EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
 }
@@ -2338,7 +2468,7 @@
           case CXChildVisit_Continue: break;
           case CXChildVisit_Recurse:
             if (PostChildrenVisitor)
-              WL.push_back(PostChildrenVisit(0, Cursor));
+              WL.push_back(PostChildrenVisit(nullptr, Cursor));
             EnqueueWorkList(WL, S);
             break;
         }
@@ -2444,12 +2574,12 @@
                          TL.getAs<FunctionProtoTypeLoc>()) {
             if (E->hasExplicitParameters()) {
               // Visit parameters.
-              for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I)
-                if (Visit(MakeCXCursor(Proto.getArg(I), TU)))
+              for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
+                if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
                   return true;
             } else {
               // Visit result type.
-              if (Visit(Proto.getResultLoc()))
+              if (Visit(Proto.getReturnLoc()))
                 return true;
             }
           }
@@ -2467,7 +2597,7 @@
 }
 
 bool CursorVisitor::Visit(const Stmt *S) {
-  VisitorWorkList *WL = 0;
+  VisitorWorkList *WL = nullptr;
   if (!WorkListFreeList.empty()) {
     WL = WorkListFreeList.back();
     WL->clear();
@@ -2485,10 +2615,10 @@
 
 namespace {
 typedef SmallVector<SourceRange, 4> RefNamePieces;
-RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr, 
-                          const DeclarationNameInfo &NI, 
-                          const SourceRange &QLoc, 
-                          const ASTTemplateArgumentListInfo *TemplateArgs = 0){
+RefNamePieces
+buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
+            const DeclarationNameInfo &NI, const SourceRange &QLoc,
+            const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
   const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
   const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
   const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
@@ -2528,9 +2658,6 @@
 // Misc. API hooks.
 //===----------------------------------------------------------------------===//               
 
-static llvm::sys::Mutex EnableMultithreadingMutex;
-static bool EnabledMultithreading;
-
 static void fatal_error_handler(void *user_data, const std::string& reason,
                                 bool gen_crash_diag) {
   // Write the result out to stderr avoiding errs() because raw_ostreams can
@@ -2539,22 +2666,28 @@
   ::abort();
 }
 
+namespace {
+struct RegisterFatalErrorHandler {
+  RegisterFatalErrorHandler() {
+    llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
+  }
+};
+}
+
+static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
+
 extern "C" {
 CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
                           int displayDiagnostics) {
   // We use crash recovery to make some of our APIs more reliable, implicitly
   // enable it.
-  llvm::CrashRecoveryContext::Enable();
+  if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
+    llvm::CrashRecoveryContext::Enable();
 
-  // Enable support for multithreading in LLVM.
-  {
-    llvm::sys::ScopedLock L(EnableMultithreadingMutex);
-    if (!EnabledMultithreading) {
-      llvm::install_fatal_error_handler(fatal_error_handler, 0);
-      llvm::llvm_start_multithreaded();
-      EnabledMultithreading = true;
-    }
-  }
+  // Look through the managed static to trigger construction of the managed
+  // static which registers our fatal error handler. This ensures it is only
+  // registered once.
+  (void)*RegisterFatalErrorHandlerOnce;
 
   CIndexer *CIdxr = new CIndexer();
   if (excludeDeclarationsFromPCH)
@@ -2594,11 +2727,26 @@
   else
     llvm::CrashRecoveryContext::Disable();
 }
-  
+
 CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
                                               const char *ast_filename) {
-  if (!CIdx || !ast_filename)
-    return 0;
+  CXTranslationUnit TU;
+  enum CXErrorCode Result =
+      clang_createTranslationUnit2(CIdx, ast_filename, &TU);
+  (void)Result;
+  assert((TU && Result == CXError_Success) ||
+         (!TU && Result != CXError_Success));
+  return TU;
+}
+
+enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
+                                              const char *ast_filename,
+                                              CXTranslationUnit *out_TU) {
+  if (out_TU)
+    *out_TU = nullptr;
+
+  if (!CIdx || !ast_filename || !out_TU)
+    return CXError_InvalidArguments;
 
   LOG_FUNC_SECTION {
     *Log << ast_filename;
@@ -2608,20 +2756,20 @@
   FileSystemOptions FileSystemOpts;
 
   IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
-  ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
-                                  CXXIdx->getOnlyLocalDecls(),
-                                  0, 0,
-                                  /*CaptureDiagnostics=*/true,
-                                  /*AllowPCHWithCompilerErrors=*/true,
-                                  /*UserFilesAreVolatile=*/true);
-  return MakeCXTranslationUnit(CXXIdx, TU);
+  ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
+                                         CXXIdx->getOnlyLocalDecls(), None,
+                                         /*CaptureDiagnostics=*/true,
+                                         /*AllowPCHWithCompilerErrors=*/true,
+                                         /*UserFilesAreVolatile=*/true);
+  *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
+  return *out_TU ? CXError_Success : CXError_Failure;
 }
 
 unsigned clang_defaultEditingTranslationUnitOptions() {
   return CXTranslationUnit_PrecompiledPreamble | 
          CXTranslationUnit_CacheCompletionResults;
 }
-  
+
 CXTranslationUnit
 clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
                                           const char *source_filename,
@@ -2641,25 +2789,30 @@
   const char *source_filename;
   const char *const *command_line_args;
   int num_command_line_args;
-  struct CXUnsavedFile *unsaved_files;
-  unsigned num_unsaved_files;
+  ArrayRef<CXUnsavedFile> unsaved_files;
   unsigned options;
-  CXTranslationUnit result;
+  CXTranslationUnit *out_TU;
+  CXErrorCode &result;
 };
 static void clang_parseTranslationUnit_Impl(void *UserData) {
-  ParseTranslationUnitInfo *PTUI =
-    static_cast<ParseTranslationUnitInfo*>(UserData);
+  const ParseTranslationUnitInfo *PTUI =
+      static_cast<ParseTranslationUnitInfo *>(UserData);
   CXIndex CIdx = PTUI->CIdx;
   const char *source_filename = PTUI->source_filename;
   const char * const *command_line_args = PTUI->command_line_args;
   int num_command_line_args = PTUI->num_command_line_args;
-  struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
-  unsigned num_unsaved_files = PTUI->num_unsaved_files;
   unsigned options = PTUI->options;
-  PTUI->result = 0;
+  CXTranslationUnit *out_TU = PTUI->out_TU;
 
-  if (!CIdx)
+  // Set up the initial return values.
+  if (out_TU)
+    *out_TU = nullptr;
+
+  // Check arguments.
+  if (!CIdx || !out_TU) {
+    PTUI->result = CXError_InvalidArguments;
     return;
+  }
 
   CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
 
@@ -2670,7 +2823,7 @@
   // FIXME: Add a flag for modules.
   TranslationUnitKind TUKind
     = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
-  bool CacheCodeCompetionResults
+  bool CacheCodeCompletionResults
     = options & CXTranslationUnit_CacheCompletionResults;
   bool IncludeBriefCommentsInCodeCompletion
     = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
@@ -2684,25 +2837,23 @@
   // Recover resources if we crash before exiting this function.
   llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
     llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
-    DiagCleanup(Diags.getPtr());
+    DiagCleanup(Diags.get());
 
-  OwningPtr<std::vector<ASTUnit::RemappedFile> >
-    RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
+  std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
+      new std::vector<ASTUnit::RemappedFile>());
 
   // Recover resources if we crash before exiting this function.
   llvm::CrashRecoveryContextCleanupRegistrar<
     std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
 
-  for (unsigned I = 0; I != num_unsaved_files; ++I) {
-    StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
-    const llvm::MemoryBuffer *Buffer
-      = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
-    RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
-                                            Buffer));
+  for (auto &UF : PTUI->unsaved_files) {
+    llvm::MemoryBuffer *MB =
+        llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
+    RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
   }
 
-  OwningPtr<std::vector<const char *> >
-    Args(new std::vector<const char*>());
+  std::unique_ptr<std::vector<const char *>> Args(
+      new std::vector<const char *>());
 
   // Recover resources if we crash before exiting this method.
   llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
@@ -2742,27 +2893,15 @@
   }
   
   unsigned NumErrors = Diags->getClient()->getNumErrors();
-  OwningPtr<ASTUnit> ErrUnit;
-  OwningPtr<ASTUnit> Unit(
-    ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0 
-                                 /* vector::data() not portable */,
-                                 Args->size() ? (&(*Args)[0] + Args->size()) :0,
-                                 Diags,
-                                 CXXIdx->getClangResourcesPath(),
-                                 CXXIdx->getOnlyLocalDecls(),
-                                 /*CaptureDiagnostics=*/true,
-                                 RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
-                                 RemappedFiles->size(),
-                                 /*RemappedFilesKeepOriginalName=*/true,
-                                 PrecompilePreamble,
-                                 TUKind,
-                                 CacheCodeCompetionResults,
-                                 IncludeBriefCommentsInCodeCompletion,
-                                 /*AllowPCHWithCompilerErrors=*/true,
-                                 SkipFunctionBodies,
-                                 /*UserFilesAreVolatile=*/true,
-                                 ForSerialization,
-                                 &ErrUnit));
+  std::unique_ptr<ASTUnit> ErrUnit;
+  std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
+      Args->data(), Args->data() + Args->size(), Diags,
+      CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
+      /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
+      /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
+      CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
+      /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
+      /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
 
   if (NumErrors != Diags->getClient()->getNumErrors()) {
     // Make sure to check that 'Unit' is non-NULL.
@@ -2770,24 +2909,60 @@
       printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
   }
 
-  PTUI->result = MakeCXTranslationUnit(CXXIdx, Unit.take());
+  if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
+    PTUI->result = CXError_ASTReadError;
+  } else {
+    *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
+    PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
+  }
 }
-CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
-                                             const char *source_filename,
-                                         const char * const *command_line_args,
-                                             int num_command_line_args,
-                                            struct CXUnsavedFile *unsaved_files,
-                                             unsigned num_unsaved_files,
-                                             unsigned options) {
+
+CXTranslationUnit
+clang_parseTranslationUnit(CXIndex CIdx,
+                           const char *source_filename,
+                           const char *const *command_line_args,
+                           int num_command_line_args,
+                           struct CXUnsavedFile *unsaved_files,
+                           unsigned num_unsaved_files,
+                           unsigned options) {
+  CXTranslationUnit TU;
+  enum CXErrorCode Result = clang_parseTranslationUnit2(
+      CIdx, source_filename, command_line_args, num_command_line_args,
+      unsaved_files, num_unsaved_files, options, &TU);
+  (void)Result;
+  assert((TU && Result == CXError_Success) ||
+         (!TU && Result != CXError_Success));
+  return TU;
+}
+
+enum CXErrorCode clang_parseTranslationUnit2(
+    CXIndex CIdx,
+    const char *source_filename,
+    const char *const *command_line_args,
+    int num_command_line_args,
+    struct CXUnsavedFile *unsaved_files,
+    unsigned num_unsaved_files,
+    unsigned options,
+    CXTranslationUnit *out_TU) {
   LOG_FUNC_SECTION {
     *Log << source_filename << ": ";
     for (int i = 0; i != num_command_line_args; ++i)
       *Log << command_line_args[i] << " ";
   }
 
-  ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
-                                    num_command_line_args, unsaved_files,
-                                    num_unsaved_files, options, 0 };
+  if (num_unsaved_files && !unsaved_files)
+    return CXError_InvalidArguments;
+
+  CXErrorCode result = CXError_Failure;
+  ParseTranslationUnitInfo PTUI = {
+      CIdx,
+      source_filename,
+      command_line_args,
+      num_command_line_args,
+      llvm::makeArrayRef(unsaved_files, num_unsaved_files),
+      options,
+      out_TU,
+      result};
   llvm::CrashRecoveryContext CRC;
 
   if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
@@ -2810,13 +2985,14 @@
     fprintf(stderr, "],\n");
     fprintf(stderr, "  'options' : %d,\n", options);
     fprintf(stderr, "}\n");
-    
-    return 0;
+
+    return CXError_Crashed;
   } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
-    PrintLibclangResourceUsage(PTUI.result);
+    if (CXTranslationUnit *TU = PTUI.out_TU)
+      PrintLibclangResourceUsage(*TU);
   }
-  
-  return PTUI.result;
+
+  return result;
 }
 
 unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
@@ -2852,8 +3028,10 @@
     *Log << TU << ' ' << FileName;
   }
 
-  if (!TU)
+  if (isNotUsableTU(TU)) {
+    LOG_BAD_TU(TU);
     return CXSaveError_InvalidTU;
+  }
 
   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
   ASTUnit::ConcurrencyCheck Check(*CXXUnit);
@@ -2896,7 +3074,8 @@
   if (CTUnit) {
     // If the translation unit has been marked as unsafe to free, just discard
     // it.
-    if (cxtu::getASTUnit(CTUnit)->isUnsafeToFree())
+    ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
+    if (Unit && Unit->isUnsafeToFree())
       return;
 
     delete cxtu::getASTUnit(CTUnit);
@@ -2914,28 +3093,28 @@
 
 struct ReparseTranslationUnitInfo {
   CXTranslationUnit TU;
-  unsigned num_unsaved_files;
-  struct CXUnsavedFile *unsaved_files;
+  ArrayRef<CXUnsavedFile> unsaved_files;
   unsigned options;
-  int result;
+  CXErrorCode &result;
 };
 
 static void clang_reparseTranslationUnit_Impl(void *UserData) {
-  ReparseTranslationUnitInfo *RTUI =
-    static_cast<ReparseTranslationUnitInfo*>(UserData);
+  const ReparseTranslationUnitInfo *RTUI =
+      static_cast<ReparseTranslationUnitInfo *>(UserData);
   CXTranslationUnit TU = RTUI->TU;
-  if (!TU)
+  unsigned options = RTUI->options;
+  (void) options;
+
+  // Check arguments.
+  if (isNotUsableTU(TU)) {
+    LOG_BAD_TU(TU);
+    RTUI->result = CXError_InvalidArguments;
     return;
+  }
 
   // Reset the associated diagnostics.
   delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
-  TU->Diagnostics = 0;
-
-  unsigned num_unsaved_files = RTUI->num_unsaved_files;
-  struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
-  unsigned options = RTUI->options;
-  (void) options;
-  RTUI->result = 1;
+  TU->Diagnostics = nullptr;
 
   CIndexer *CXXIdx = TU->CIdx;
   if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
@@ -2943,25 +3122,24 @@
 
   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
   ASTUnit::ConcurrencyCheck Check(*CXXUnit);
-  
-  OwningPtr<std::vector<ASTUnit::RemappedFile> >
-    RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
-  
+
+  std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
+      new std::vector<ASTUnit::RemappedFile>());
+
   // Recover resources if we crash before exiting this function.
   llvm::CrashRecoveryContextCleanupRegistrar<
     std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
-  
-  for (unsigned I = 0; I != num_unsaved_files; ++I) {
-    StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
-    const llvm::MemoryBuffer *Buffer
-      = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
-    RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
-                                            Buffer));
+
+  for (auto &UF : RTUI->unsaved_files) {
+    llvm::MemoryBuffer *MB =
+        llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
+    RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
   }
-  
-  if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
-                        RemappedFiles->size()))
-    RTUI->result = 0;
+
+  if (!CXXUnit->Reparse(*RemappedFiles.get()))
+    RTUI->result = CXError_Success;
+  else if (isASTReadError(CXXUnit))
+    RTUI->result = CXError_ASTReadError;
 }
 
 int clang_reparseTranslationUnit(CXTranslationUnit TU,
@@ -2972,12 +3150,17 @@
     *Log << TU;
   }
 
-  ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
-                                      options, 0 };
+  if (num_unsaved_files && !unsaved_files)
+    return CXError_InvalidArguments;
+
+  CXErrorCode result = CXError_Failure;
+  ReparseTranslationUnitInfo RTUI = {
+      TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
+      result};
 
   if (getenv("LIBCLANG_NOTHREADS")) {
     clang_reparseTranslationUnit_Impl(&RTUI);
-    return RTUI.result;
+    return result;
   }
 
   llvm::CrashRecoveryContext CRC;
@@ -2985,25 +3168,29 @@
   if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
     fprintf(stderr, "libclang: crash detected during reparsing\n");
     cxtu::getASTUnit(TU)->setUnsafeToFree(true);
-    return 1;
+    return CXError_Crashed;
   } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
     PrintLibclangResourceUsage(TU);
 
-  return RTUI.result;
+  return result;
 }
 
 
 CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
-  if (!CTUnit)
+  if (isNotUsableTU(CTUnit)) {
+    LOG_BAD_TU(CTUnit);
     return cxstring::createEmpty();
+  }
 
   ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
   return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
 }
 
 CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
-  if (!TU)
+  if (isNotUsableTU(TU)) {
+    LOG_BAD_TU(TU);
     return clang_getNullCursor();
+  }
 
   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
   return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
@@ -3033,8 +3220,10 @@
 }
 
 CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
-  if (!TU)
-    return 0;
+  if (isNotUsableTU(TU)) {
+    LOG_BAD_TU(TU);
+    return nullptr;
+  }
 
   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
 
@@ -3042,8 +3231,14 @@
   return const_cast<FileEntry *>(FMgr.getFile(file_name));
 }
 
-unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
-  if (!TU || !file)
+unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
+                                            CXFile file) {
+  if (isNotUsableTU(TU)) {
+    LOG_BAD_TU(TU);
+    return 0;
+  }
+
+  if (!file)
     return 0;
 
   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
@@ -3114,8 +3309,8 @@
     if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) || 
         isa<ParmVarDecl>(SizeOfPack->getPack()))
       return SizeOfPack->getPack();
-  
-  return 0;
+
+  return nullptr;
 }
 
 static SourceLocation getLocationFromExpr(const Expr *E) {
@@ -3309,6 +3504,22 @@
   }
 
   if (clang_isExpression(C.kind)) {
+    const Expr *E = getCursorExpr(C);
+
+    if (C.kind == CXCursor_ObjCStringLiteral ||
+        C.kind == CXCursor_StringLiteral) {
+      const StringLiteral *SLit;
+      if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
+        SLit = OSL->getString();
+      } else {
+        SLit = cast<StringLiteral>(E);
+      }
+      SmallString<256> Buf;
+      llvm::raw_svector_ostream OS(Buf);
+      SLit->outputString(OS);
+      return cxstring::createDup(OS.str());
+    }
+
     const Decl *D = getDeclFromExpr(getCursorExpr(C));
     if (D)
       return getDeclSpelling(D);
@@ -3740,6 +3951,8 @@
       return cxstring::createRef("SEHExceptStmt");
   case CXCursor_SEHFinallyStmt:
       return cxstring::createRef("SEHFinallyStmt");
+  case CXCursor_SEHLeaveStmt:
+      return cxstring::createRef("SEHLeaveStmt");
   case CXCursor_NullStmt:
       return cxstring::createRef("NullStmt");
   case CXCursor_InvalidFile:
@@ -3770,6 +3983,20 @@
     return cxstring::createRef("asm label");
   case CXCursor_PackedAttr:
     return cxstring::createRef("attribute(packed)");
+  case CXCursor_PureAttr:
+    return cxstring::createRef("attribute(pure)");
+  case CXCursor_ConstAttr:
+    return cxstring::createRef("attribute(const)");
+  case CXCursor_NoDuplicateAttr:
+    return cxstring::createRef("attribute(noduplicate)");
+  case CXCursor_CUDAConstantAttr:
+    return cxstring::createRef("attribute(constant)");
+  case CXCursor_CUDADeviceAttr:
+    return cxstring::createRef("attribute(device)");
+  case CXCursor_CUDAGlobalAttr:
+    return cxstring::createRef("attribute(global)");
+  case CXCursor_CUDAHostAttr:
+    return cxstring::createRef("attribute(host)");
   case CXCursor_PreprocessingDirective:
     return cxstring::createRef("preprocessing directive");
   case CXCursor_MacroDefinition:
@@ -3819,7 +4046,35 @@
   case CXCursor_ModuleImportDecl:
     return cxstring::createRef("ModuleImport");
   case CXCursor_OMPParallelDirective:
-      return cxstring::createRef("OMPParallelDirective");
+    return cxstring::createRef("OMPParallelDirective");
+  case CXCursor_OMPSimdDirective:
+    return cxstring::createRef("OMPSimdDirective");
+  case CXCursor_OMPForDirective:
+    return cxstring::createRef("OMPForDirective");
+  case CXCursor_OMPSectionsDirective:
+    return cxstring::createRef("OMPSectionsDirective");
+  case CXCursor_OMPSectionDirective:
+    return cxstring::createRef("OMPSectionDirective");
+  case CXCursor_OMPSingleDirective:
+    return cxstring::createRef("OMPSingleDirective");
+  case CXCursor_OMPMasterDirective:
+    return cxstring::createRef("OMPMasterDirective");
+  case CXCursor_OMPCriticalDirective:
+    return cxstring::createRef("OMPCriticalDirective");
+  case CXCursor_OMPParallelForDirective:
+    return cxstring::createRef("OMPParallelForDirective");
+  case CXCursor_OMPParallelSectionsDirective:
+    return cxstring::createRef("OMPParallelSectionsDirective");
+  case CXCursor_OMPTaskDirective:
+    return cxstring::createRef("OMPTaskDirective");
+  case CXCursor_OMPTaskyieldDirective:
+    return cxstring::createRef("OMPTaskyieldDirective");
+  case CXCursor_OMPBarrierDirective:
+    return cxstring::createRef("OMPBarrierDirective");
+  case CXCursor_OMPTaskwaitDirective:
+    return cxstring::createRef("OMPTaskwaitDirective");
+  case CXCursor_OMPFlushDirective:
+    return cxstring::createRef("OMPFlushDirective");
   }
 
   llvm_unreachable("Unhandled CXCursorKind");
@@ -3936,8 +4191,10 @@
 }
 
 CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
-  if (!TU)
+  if (isNotUsableTU(TU)) {
+    LOG_BAD_TU(TU);
     return clang_getNullCursor();
+  }
 
   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
   ASTUnit::ConcurrencyCheck Check(*CXXUnit);
@@ -3953,10 +4210,11 @@
     CXString SearchFileName, ResultFileName, KindSpelling, USR;
     const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
     CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
-    
-    clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
+
+    clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
+                          nullptr);
     clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
-                               &ResultColumn, 0);
+                          &ResultColumn, nullptr);
     SearchFileName = clang_getFileName(SearchFile);
     ResultFileName = clang_getFileName(ResultFile);
     KindSpelling = clang_getCursorKindSpelling(Result.kind);
@@ -3980,7 +4238,7 @@
       CXFile DefinitionFile;
       unsigned DefinitionLine, DefinitionColumn;
       clang_getFileLocation(DefinitionLoc, &DefinitionFile,
-                                 &DefinitionLine, &DefinitionColumn, 0);
+                            &DefinitionLine, &DefinitionColumn, nullptr);
       CXString DefinitionFileName = clang_getFileName(DefinitionFile);
       *Log << llvm::format("  -> %s(%s:%d:%d)",
                      clang_getCString(DefinitionKindSpelling),
@@ -4007,9 +4265,9 @@
   // when visiting a DeclStmt currently, the AST should be enhanced to be able
   // to provide that kind of info.
   if (clang_isDeclaration(X.kind))
-    X.data[1] = 0;
+    X.data[1] = nullptr;
   if (clang_isDeclaration(Y.kind))
-    Y.data[1] = 0;
+    Y.data[1] = nullptr;
 
   return X == Y;
 }
@@ -4587,7 +4845,7 @@
   case Decl::CXXConstructor:
   case Decl::CXXDestructor:
   case Decl::CXXConversion: {
-    const FunctionDecl *Def = 0;
+    const FunctionDecl *Def = nullptr;
     if (cast<FunctionDecl>(D)->getBody(Def))
       return MakeCXCursor(Def, TU);
     return clang_getNullCursor();
@@ -4603,7 +4861,7 @@
   }
 
   case Decl::FunctionTemplate: {
-    const FunctionDecl *Def = 0;
+    const FunctionDecl *Def = nullptr;
     if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
       return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
     return clang_getNullCursor();
@@ -4897,6 +5155,11 @@
     break;
   }
 
+  if (isNotUsableTU(TU)) {
+    LOG_BAD_TU(TU);
+    return cxstring::createEmpty();
+  }
+
   // We have to find the starting buffer pointer the hard way, by
   // deconstructing the source location.
   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
@@ -4916,6 +5179,11 @@
 }
 
 CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
+  if (isNotUsableTU(TU)) {
+    LOG_BAD_TU(TU);
+    return clang_getNullLocation();
+  }
+
   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
   if (!CXXUnit)
     return clang_getNullLocation();
@@ -4925,6 +5193,11 @@
 }
 
 CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
+  if (isNotUsableTU(TU)) {
+    LOG_BAD_TU(TU);
+    return clang_getNullRange();
+  }
+
   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
   if (!CXXUnit)
     return clang_getNullRange();
@@ -4995,10 +5268,10 @@
       CXTok.ptr_data = II;
     } else if (Tok.is(tok::comment)) {
       CXTok.int_data[0] = CXToken_Comment;
-      CXTok.ptr_data = 0;
+      CXTok.ptr_data = nullptr;
     } else {
       CXTok.int_data[0] = CXToken_Punctuation;
-      CXTok.ptr_data = 0;
+      CXTok.ptr_data = nullptr;
     }
     CXTokens.push_back(CXTok);
     previousWasAt = Tok.is(tok::at);
@@ -5012,12 +5285,14 @@
   }
 
   if (Tokens)
-    *Tokens = 0;
+    *Tokens = nullptr;
   if (NumTokens)
     *NumTokens = 0;
 
-  if (!TU)
+  if (isNotUsableTU(TU)) {
+    LOG_BAD_TU(TU);
     return;
+  }
 
   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
   if (!CXXUnit || !Tokens || !NumTokens)
@@ -5075,18 +5350,26 @@
     unsigned BeforeChildrenTokenIdx;
   };
   SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
-  
+
+  CXToken &getTok(unsigned Idx) {
+    assert(Idx < NumTokens);
+    return Tokens[Idx];
+  }
+  const CXToken &getTok(unsigned Idx) const {
+    assert(Idx < NumTokens);
+    return Tokens[Idx];
+  }
   bool MoreTokens() const { return TokIdx < NumTokens; }
   unsigned NextToken() const { return TokIdx; }
   void AdvanceToken() { ++TokIdx; }
   SourceLocation GetTokenLoc(unsigned tokI) {
-    return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
+    return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
   }
   bool isFunctionMacroToken(unsigned tokI) const {
-    return Tokens[tokI].int_data[3] != 0;
+    return getTok(tokI).int_data[3] != 0;
   }
   SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
-    return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[3]);
+    return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
   }
 
   void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
@@ -5223,10 +5506,8 @@
         if (Method->getObjCDeclQualifier())
           HasContextSensitiveKeywords = true;
         else {
-          for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
-                                                 PEnd = Method->param_end();
-               P != PEnd; ++P) {
-            if ((*P)->getObjCDeclQualifier()) {
+          for (const auto *P : Method->params()) {
+            if (P->getObjCDeclQualifier()) {
               HasContextSensitiveKeywords = true;
               break;
             }
@@ -5333,7 +5614,7 @@
   // This can happen for C++ constructor expressions whose range generally
   // include the variable declaration, e.g.:
   //  MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
-  if (clang_isExpression(cursorK)) {
+  if (clang_isExpression(cursorK) && MoreTokens()) {
     const Expr *E = getCursorExpr(cursor);
     if (const Decl *D = getCursorParentDecl(cursor)) {
       const unsigned I = NextToken();
@@ -5455,14 +5736,23 @@
   }
 
 private:
+  CXToken &getTok(unsigned Idx) {
+    assert(Idx < NumTokens);
+    return Tokens[Idx];
+  }
+  const CXToken &getTok(unsigned Idx) const {
+    assert(Idx < NumTokens);
+    return Tokens[Idx];
+  }
+
   SourceLocation getTokenLoc(unsigned tokI) {
-    return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
+    return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
   }
 
   void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
     // The third field is reserved and currently not used. Use it here
     // to mark macro arg expanded tokens with their expanded locations.
-    Tokens[tokI].int_data[3] = loc.getRawEncoding();
+    getTok(tokI).int_data[3] = loc.getRawEncoding();
   }
 };
 
@@ -5552,15 +5842,14 @@
       if (lexNext(Lex, Tok, NextIdx, NumTokens))
         break;
 
-      MacroInfo *MI = 0;
-      if (Tok.is(tok::raw_identifier) &&
-          StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
+      MacroInfo *MI = nullptr;
+      if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
         if (lexNext(Lex, Tok, NextIdx, NumTokens))
           break;
 
         if (Tok.is(tok::raw_identifier)) {
-          StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
-          IdentifierInfo &II = PP.getIdentifierTable().get(Name);
+          IdentifierInfo &II =
+              PP.getIdentifierTable().get(Tok.getRawIdentifier());
           SourceLocation MappedTokLoc =
               CXXUnit->mapLocationToPreamble(Tok.getLocation());
           MI = getMacroInfo(II, MappedTokLoc, TU);
@@ -5720,7 +6009,11 @@
 void clang_annotateTokens(CXTranslationUnit TU,
                           CXToken *Tokens, unsigned NumTokens,
                           CXCursor *Cursors) {
-  if (!TU || NumTokens == 0 || !Tokens || !Cursors) {
+  if (isNotUsableTU(TU)) {
+    LOG_BAD_TU(TU);
+    return;
+  }
+  if (NumTokens == 0 || !Tokens || !Cursors) {
     LOG_FUNC_SECTION { *Log << "<null input>"; }
     return;
   }
@@ -5890,28 +6183,30 @@
                                                 int availability_size) {
   bool HadAvailAttr = false;
   int N = 0;
-  for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
-       ++A) {
-    if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
+  for (auto A : D->attrs()) {
+    if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
       HadAvailAttr = true;
       if (always_deprecated)
         *always_deprecated = 1;
-      if (deprecated_message)
+      if (deprecated_message) {
+        clang_disposeString(*deprecated_message);
         *deprecated_message = cxstring::createDup(Deprecated->getMessage());
+      }
       continue;
     }
     
-    if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
+    if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
       HadAvailAttr = true;
       if (always_unavailable)
         *always_unavailable = 1;
       if (unavailable_message) {
+        clang_disposeString(*unavailable_message);
         *unavailable_message = cxstring::createDup(Unavailable->getMessage());
       }
       continue;
     }
     
-    if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
+    if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
       HadAvailAttr = true;
       if (N < availability_size) {
         availability[N].Platform
@@ -5988,7 +6283,7 @@
  /// function template.
 static const Decl *maybeGetTemplateCursor(const Decl *D) {
   if (!D)
-    return 0;
+    return nullptr;
 
   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
     if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
@@ -6040,8 +6335,8 @@
 
 CXFile clang_getIncludedFile(CXCursor cursor) {
   if (cursor.kind != CXCursor_InclusionDirective)
-    return 0;
-  
+    return nullptr;
+
   const InclusionDirective *ID = getCursorInclusionDirective(cursor);
   return const_cast<FileEntry *>(ID->getFile());
 }
@@ -6172,17 +6467,6 @@
   return cxstring::createNull();
 }
 
-CXComment clang_Cursor_getParsedComment(CXCursor C) {
-  if (!clang_isDeclaration(C.kind))
-    return cxcomment::createCXComment(NULL, NULL);
-
-  const Decl *D = getCursorDecl(C);
-  const ASTContext &Context = getCursorContext(C);
-  const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
-
-  return cxcomment::createCXComment(FC, getCursorTU(C));
-}
-
 CXModule clang_Cursor_getModule(CXCursor C) {
   if (C.kind == CXCursor_ModuleImportDecl) {
     if (const ImportDecl *ImportD =
@@ -6190,19 +6474,39 @@
       return ImportD->getImportedModule();
   }
 
-  return 0;
+  return nullptr;
+}
+
+CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
+  if (isNotUsableTU(TU)) {
+    LOG_BAD_TU(TU);
+    return nullptr;
+  }
+  if (!File)
+    return nullptr;
+  FileEntry *FE = static_cast<FileEntry *>(File);
+  
+  ASTUnit &Unit = *cxtu::getASTUnit(TU);
+  HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
+  ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
+  
+  if (Module *Mod = Header.getModule()) {
+    if (Header.getRole() != ModuleMap::ExcludedHeader)
+      return Mod;
+  }
+  return nullptr;
 }
 
 CXFile clang_Module_getASTFile(CXModule CXMod) {
   if (!CXMod)
-    return 0;
+    return nullptr;
   Module *Mod = static_cast<Module*>(CXMod);
   return const_cast<FileEntry *>(Mod->getASTFile());
 }
 
 CXModule clang_Module_getParent(CXModule CXMod) {
   if (!CXMod)
-    return 0;
+    return nullptr;
   Module *Mod = static_cast<Module*>(CXMod);
   return Mod->Parent;
 }
@@ -6221,9 +6525,20 @@
   return cxstring::createDup(Mod->getFullModuleName());
 }
 
+int clang_Module_isSystem(CXModule CXMod) {
+  if (!CXMod)
+    return 0;
+  Module *Mod = static_cast<Module*>(CXMod);
+  return Mod->IsSystem;
+}
+
 unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
                                             CXModule CXMod) {
-  if (!TU || !CXMod)
+  if (isNotUsableTU(TU)) {
+    LOG_BAD_TU(TU);
+    return 0;
+  }
+  if (!CXMod)
     return 0;
   Module *Mod = static_cast<Module*>(CXMod);
   FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
@@ -6233,8 +6548,12 @@
 
 CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
                                       CXModule CXMod, unsigned Index) {
-  if (!TU || !CXMod)
-    return 0;
+  if (isNotUsableTU(TU)) {
+    LOG_BAD_TU(TU);
+    return nullptr;
+  }
+  if (!CXMod)
+    return nullptr;
   Module *Mod = static_cast<Module*>(CXMod);
   FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
 
@@ -6242,7 +6561,7 @@
   if (Index < TopHeaders.size())
     return const_cast<FileEntry *>(TopHeaders[Index]);
 
-  return 0;
+  return nullptr;
 }
 
 } // end: extern "C"
@@ -6256,27 +6575,29 @@
   if (!clang_isDeclaration(C.kind))
     return 0;
 
-  const CXXMethodDecl *Method = 0;
   const Decl *D = cxcursor::getCursorDecl(C);
-  if (const FunctionTemplateDecl *FunTmpl =
-          dyn_cast_or_null<FunctionTemplateDecl>(D))
-    Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
-  else
-    Method = dyn_cast_or_null<CXXMethodDecl>(D);
+  const CXXMethodDecl *Method =
+      D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
   return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
 }
 
+unsigned clang_CXXMethod_isConst(CXCursor C) {
+  if (!clang_isDeclaration(C.kind))
+    return 0;
+
+  const Decl *D = cxcursor::getCursorDecl(C);
+  const CXXMethodDecl *Method =
+      D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
+  return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
+}
+
 unsigned clang_CXXMethod_isStatic(CXCursor C) {
   if (!clang_isDeclaration(C.kind))
     return 0;
   
-  const CXXMethodDecl *Method = 0;
   const Decl *D = cxcursor::getCursorDecl(C);
-  if (const FunctionTemplateDecl *FunTmpl =
-          dyn_cast_or_null<FunctionTemplateDecl>(D))
-    Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
-  else
-    Method = dyn_cast_or_null<CXXMethodDecl>(D);
+  const CXXMethodDecl *Method =
+      D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
   return (Method && Method->isStatic()) ? 1 : 0;
 }
 
@@ -6284,13 +6605,9 @@
   if (!clang_isDeclaration(C.kind))
     return 0;
   
-  const CXXMethodDecl *Method = 0;
   const Decl *D = cxcursor::getCursorDecl(C);
-  if (const FunctionTemplateDecl *FunTmpl =
-          dyn_cast_or_null<FunctionTemplateDecl>(D))
-    Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
-  else
-    Method = dyn_cast_or_null<CXXMethodDecl>(D);
+  const CXXMethodDecl *Method =
+      D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
   return (Method && Method->isVirtual()) ? 1 : 0;
 }
 } // end: extern "C"
@@ -6376,13 +6693,14 @@
 }
 
 CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
-  if (!TU) {
-    CXTUResourceUsage usage = { (void*) 0, 0, 0 };
+  if (isNotUsableTU(TU)) {
+    LOG_BAD_TU(TU);
+    CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
     return usage;
   }
   
   ASTUnit *astUnit = cxtu::getASTUnit(TU);
-  OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
+  std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
   ASTContext &astContext = astUnit->getASTContext();
   
   // How much memory is used by AST nodes and types?
@@ -6404,7 +6722,7 @@
   // How much memory is used for caching global code completion results?
   unsigned long completionBytes = 0;
   if (GlobalCodeCompletionAllocator *completionAllocator =
-      astUnit->getCachedCompletionAllocator().getPtr()) {
+      astUnit->getCachedCompletionAllocator().get()) {
     completionBytes = completionAllocator->getTotalMemory();
   }
   createCXTUResourceUsageEntry(*entries,
@@ -6459,11 +6777,11 @@
   createCXTUResourceUsageEntry(*entries,
                                CXTUResourceUsage_Preprocessor_HeaderSearch,
                                pp.getHeaderSearchInfo().getTotalMemory());
-  
+
   CXTUResourceUsage usage = { (void*) entries.get(),
                             (unsigned) entries->size(),
-                            entries->size() ? &(*entries)[0] : 0 };
-  entries.take();
+                            entries->size() ? &(*entries)[0] : nullptr };
+  entries.release();
   return usage;
 }
 
@@ -6472,6 +6790,52 @@
     delete (MemUsageEntries*) usage.data;
 }
 
+CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
+  CXSourceRangeList *skipped = new CXSourceRangeList;
+  skipped->count = 0;
+  skipped->ranges = nullptr;
+
+  if (isNotUsableTU(TU)) {
+    LOG_BAD_TU(TU);
+    return skipped;
+  }
+
+  if (!file)
+    return skipped;
+
+  ASTUnit *astUnit = cxtu::getASTUnit(TU);
+  PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
+  if (!ppRec)
+    return skipped;
+
+  ASTContext &Ctx = astUnit->getASTContext();
+  SourceManager &sm = Ctx.getSourceManager();
+  FileEntry *fileEntry = static_cast<FileEntry *>(file);
+  FileID wantedFileID = sm.translateFile(fileEntry);
+
+  const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
+  std::vector<SourceRange> wantedRanges;
+  for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
+       i != ei; ++i) {
+    if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
+      wantedRanges.push_back(*i);
+  }
+
+  skipped->count = wantedRanges.size();
+  skipped->ranges = new CXSourceRange[skipped->count];
+  for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
+    skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
+
+  return skipped;
+}
+
+void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
+  if (ranges) {
+    delete[] ranges->ranges;
+    delete ranges;
+  }
+}
+
 } // end extern "C"
 
 void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
@@ -6517,8 +6881,7 @@
   if (getenv("LIBCLANG_BGPRIO_DISABLE"))
     return;
 
-  // FIXME: Move to llvm/Support and make it cross-platform.
-#ifdef __APPLE__
+#ifdef USE_DARWIN_THREADS
   setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
 #endif
 }
@@ -6530,7 +6893,7 @@
   for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(), 
                                   DEnd = Unit->stored_diag_end();
        D != DEnd; ++D) {
-    CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
+    CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
     CXString Msg = clang_formatDiagnostic(&Diag,
                                 clang_defaultDiagnosticDisplayOptions());
     fprintf(stderr, "%s\n", clang_getCString(Msg));
@@ -6548,9 +6911,9 @@
                                  SourceLocation MacroDefLoc,
                                  CXTranslationUnit TU){
   if (MacroDefLoc.isInvalid() || !TU)
-    return 0;
+    return nullptr;
   if (!II.hadMacroDefinition())
-    return 0;
+    return nullptr;
 
   ASTUnit *Unit = cxtu::getASTUnit(TU);
   Preprocessor &PP = Unit->getPreprocessor();
@@ -6563,16 +6926,16 @@
     }
   }
 
-  return 0;
+  return nullptr;
 }
 
 const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
                                        CXTranslationUnit TU) {
   if (!MacroDef || !TU)
-    return 0;
+    return nullptr;
   const IdentifierInfo *II = MacroDef->getName();
   if (!II)
-    return 0;
+    return nullptr;
 
   return getMacroInfo(*II, MacroDef->getLocation(), TU);
 }
@@ -6581,12 +6944,12 @@
                                                          const Token &Tok,
                                                          CXTranslationUnit TU) {
   if (!MI || !TU)
-    return 0;
+    return nullptr;
   if (Tok.isNot(tok::raw_identifier))
-    return 0;
+    return nullptr;
 
   if (MI->getNumTokens() == 0)
-    return 0;
+    return nullptr;
   SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
                        MI->getDefinitionEndLoc());
   ASTUnit *Unit = cxtu::getASTUnit(TU);
@@ -6594,27 +6957,26 @@
   // Check that the token is inside the definition and not its argument list.
   SourceManager &SM = Unit->getSourceManager();
   if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
-    return 0;
+    return nullptr;
   if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
-    return 0;
+    return nullptr;
 
   Preprocessor &PP = Unit->getPreprocessor();
   PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
   if (!PPRec)
-    return 0;
+    return nullptr;
 
-  StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
-  IdentifierInfo &II = PP.getIdentifierTable().get(Name);
+  IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
   if (!II.hadMacroDefinition())
-    return 0;
+    return nullptr;
 
   // Check that the identifier is not one of the macro arguments.
   if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
-    return 0;
+    return nullptr;
 
   MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
   if (!InnerMD)
-    return 0;
+    return nullptr;
 
   return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
 }
@@ -6623,18 +6985,18 @@
                                                          SourceLocation Loc,
                                                          CXTranslationUnit TU) {
   if (Loc.isInvalid() || !MI || !TU)
-    return 0;
+    return nullptr;
 
   if (MI->getNumTokens() == 0)
-    return 0;
+    return nullptr;
   ASTUnit *Unit = cxtu::getASTUnit(TU);
   Preprocessor &PP = Unit->getPreprocessor();
   if (!PP.getPreprocessingRecord())
-    return 0;
+    return nullptr;
   Loc = Unit->getSourceManager().getSpellingLoc(Loc);
   Token Tok;
   if (PP.getRawToken(Loc, Tok))
-    return 0;
+    return nullptr;
 
   return checkForMacroInMacroDefinition(MI, Tok, TU);
 }
@@ -6655,9 +7017,9 @@
         LogOS << " (" << Unit->getASTFileName() << ')';
       return *this;
     }
+  } else {
+    LogOS << "<NULL TU>";
   }
-
-  LogOS << "<NULL TU>";
   return *this;
 }
 
@@ -6676,7 +7038,7 @@
 Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
   CXFile File;
   unsigned Line, Column;
-  clang_getFileLocation(Loc, &File, &Line, &Column, 0);
+  clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
   CXString FileName = clang_getFileName(File);
   *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
   clang_disposeString(FileName);
@@ -6689,11 +7051,11 @@
 
   CXFile BFile;
   unsigned BLine, BColumn;
-  clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
+  clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
 
   CXFile EFile;
   unsigned ELine, EColumn;
-  clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
+  clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
 
   CXString BFileName = clang_getFileName(BFile);
   if (BFile == EFile) {
@@ -6721,18 +7083,20 @@
   return *this;
 }
 
+static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
+
 cxindex::Logger::~Logger() {
   LogOS.flush();
 
-  llvm::sys::ScopedLock L(EnableMultithreadingMutex);
+  llvm::sys::ScopedLock L(*LoggingMutex);
 
   static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
 
   raw_ostream &OS = llvm::errs();
   OS << "[libclang:" << Name << ':';
 
-  // FIXME: Portability.
-#if HAVE_PTHREAD_H && __APPLE__
+#ifdef USE_DARWIN_THREADS
+  // TODO: Portability.
   mach_port_t tid = pthread_mach_thread_np(pthread_self());
   OS << tid << ':';
 #endif
diff --git a/tools/libclang/CIndexCXX.cpp b/tools/libclang/CIndexCXX.cpp
index a3d2364..78e89d9 100644
--- a/tools/libclang/CIndexCXX.cpp
+++ b/tools/libclang/CIndexCXX.cpp
@@ -89,8 +89,8 @@
   const Decl *D = getCursorDecl(C);
   if (!D)
     return clang_getNullCursor();
-  
-  Decl *Template = 0;
+
+  Decl *Template = nullptr;
   if (const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) {
     if (const ClassTemplatePartialSpecializationDecl *PartialSpec
           = dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord))
diff --git a/tools/libclang/CIndexCodeCompletion.cpp b/tools/libclang/CIndexCodeCompletion.cpp
index 865bb58..0d88003 100644
--- a/tools/libclang/CIndexCodeCompletion.cpp
+++ b/tools/libclang/CIndexCodeCompletion.cpp
@@ -30,13 +30,13 @@
 #include "clang/Sema/Sema.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringExtras.h"
-#include "llvm/Support/Atomic.h"
 #include "llvm/Support/CrashRecoveryContext.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Program.h"
 #include "llvm/Support/Timer.h"
 #include "llvm/Support/raw_ostream.h"
+#include <atomic>
 #include <cstdio>
 #include <cstdlib>
 #include <string>
@@ -153,7 +153,7 @@
                                          unsigned chunk_number) {
   CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
   if (!CCStr || chunk_number >= CCStr->size())
-    return 0;
+    return nullptr;
 
   switch ((*CCStr)[chunk_number].Kind) {
   case CodeCompletionString::CK_TypedText:
@@ -176,7 +176,7 @@
   case CodeCompletionString::CK_Equal:
   case CodeCompletionString::CK_HorizontalSpace:
   case CodeCompletionString::CK_VerticalSpace:
-    return 0;
+    return nullptr;
 
   case CodeCompletionString::CK_Optional:
     // Note: treated as an empty text block.
@@ -249,12 +249,15 @@
 /// AllocatedCXCodeCompleteResults outlives the CXTranslationUnit, so we can
 /// not rely on the StringPool in the TU.
 struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
-  AllocatedCXCodeCompleteResults(const FileSystemOptions& FileSystemOpts);
+  AllocatedCXCodeCompleteResults(IntrusiveRefCntPtr<FileManager> FileMgr);
   ~AllocatedCXCodeCompleteResults();
   
   /// \brief Diagnostics produced while performing code completion.
   SmallVector<StoredDiagnostic, 8> Diagnostics;
 
+  /// \brief Allocated API-exposed wrappters for Diagnostics.
+  SmallVector<CXStoredDiagnostic *, 8> DiagnosticsWrappers;
+
   IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
   
   /// \brief Diag object
@@ -263,8 +266,6 @@
   /// \brief Language options used to adjust source locations.
   LangOptions LangOpts;
 
-  FileSystemOptions FileSystemOpts;
-
   /// \brief File manager, used for diagnostics.
   IntrusiveRefCntPtr<FileManager> FileMgr;
 
@@ -315,30 +316,25 @@
 /// currently active.
 ///
 /// Used for debugging purposes only.
-static llvm::sys::cas_flag CodeCompletionResultObjects;
+static std::atomic<unsigned> CodeCompletionResultObjects;
   
 AllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults(
-                                      const FileSystemOptions& FileSystemOpts)
-  : CXCodeCompleteResults(),
-    DiagOpts(new DiagnosticOptions),
-    Diag(new DiagnosticsEngine(
-                   IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
-                   &*DiagOpts)),
-    FileSystemOpts(FileSystemOpts),
-    FileMgr(new FileManager(FileSystemOpts)),
-    SourceMgr(new SourceManager(*Diag, *FileMgr)),
-    CodeCompletionAllocator(new clang::GlobalCodeCompletionAllocator),
-    Contexts(CXCompletionContext_Unknown),
-    ContainerKind(CXCursor_InvalidCode),
-    ContainerIsIncomplete(1)
-{ 
-  if (getenv("LIBCLANG_OBJTRACKING")) {
-    llvm::sys::AtomicIncrement(&CodeCompletionResultObjects);
-    fprintf(stderr, "+++ %d completion results\n", CodeCompletionResultObjects);
-  }    
+    IntrusiveRefCntPtr<FileManager> FileMgr)
+    : CXCodeCompleteResults(),
+      DiagOpts(new DiagnosticOptions),
+      Diag(new DiagnosticsEngine(
+          IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), &*DiagOpts)),
+      FileMgr(FileMgr), SourceMgr(new SourceManager(*Diag, *FileMgr)),
+      CodeCompletionAllocator(new clang::GlobalCodeCompletionAllocator),
+      Contexts(CXCompletionContext_Unknown),
+      ContainerKind(CXCursor_InvalidCode), ContainerIsIncomplete(1) {
+  if (getenv("LIBCLANG_OBJTRACKING"))
+    fprintf(stderr, "+++ %u completion results\n",
+            ++CodeCompletionResultObjects);
 }
   
 AllocatedCXCodeCompleteResults::~AllocatedCXCodeCompleteResults() {
+  llvm::DeleteContainerPointers(DiagnosticsWrappers);
   delete [] Results;
 
   for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I)
@@ -346,10 +342,9 @@
   for (unsigned I = 0, N = TemporaryBuffers.size(); I != N; ++I)
     delete TemporaryBuffers[I];
 
-  if (getenv("LIBCLANG_OBJTRACKING")) {
-    llvm::sys::AtomicDecrement(&CodeCompletionResultObjects);
-    fprintf(stderr, "--- %d completion results\n", CodeCompletionResultObjects);
-  }    
+  if (getenv("LIBCLANG_OBJTRACKING"))
+    fprintf(stderr, "--- %u completion results\n",
+            --CodeCompletionResultObjects);
 }
   
 } // end extern "C"
@@ -539,11 +534,11 @@
         AllocatedResults(Results), CCTUInfo(Results.CodeCompletionAllocator),
         TU(TranslationUnit) { }
     ~CaptureCompletionResults() { Finish(); }
-    
-    virtual void ProcessCodeCompleteResults(Sema &S, 
-                                            CodeCompletionContext Context,
-                                            CodeCompletionResult *Results,
-                                            unsigned NumResults) {
+
+    void ProcessCodeCompleteResults(Sema &S, 
+                                    CodeCompletionContext Context,
+                                    CodeCompletionResult *Results,
+                                    unsigned NumResults) override {
       StoredResults.reserve(StoredResults.size() + NumResults);
       for (unsigned I = 0; I != NumResults; ++I) {
         CodeCompletionString *StoredCompletion        
@@ -573,8 +568,8 @@
       }
       
       QualType baseType = Context.getBaseType();
-      NamedDecl *D = NULL;
-      
+      NamedDecl *D = nullptr;
+
       if (!baseType.isNull()) {
         // Get the declaration for a class/struct/union/enum type
         if (const TagType *Tag = baseType->getAs<TagType>())
@@ -592,8 +587,8 @@
                  baseType->getAs<InjectedClassNameType>())
           D = Injected->getDecl();
       }
-      
-      if (D != NULL) {
+
+      if (D != nullptr) {
         CXCursor cursor = cxcursor::MakeCXCursor(D, *TU);
 
         AllocatedResults.ContainerKind = clang_getCursorKind(cursor);
@@ -603,7 +598,7 @@
         clang_disposeString(CursorUSR);
 
         const Type *type = baseType.getTypePtrOrNull();
-        if (type != NULL) {
+        if (type) {
           AllocatedResults.ContainerIsIncomplete = type->isIncompleteType();
         }
         else {
@@ -616,10 +611,10 @@
         AllocatedResults.ContainerIsIncomplete = 1;
       }
     }
-    
-    virtual void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
-                                           OverloadCandidate *Candidates,
-                                           unsigned NumCandidates) {
+
+    void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
+                                   OverloadCandidate *Candidates,
+                                   unsigned NumCandidates) override {
       StoredResults.reserve(StoredResults.size() + NumCandidates);
       for (unsigned I = 0; I != NumCandidates; ++I) {
         CodeCompletionString *StoredCompletion
@@ -632,13 +627,13 @@
         StoredResults.push_back(R);
       }
     }
-    
-    virtual CodeCompletionAllocator &getAllocator() { 
+
+    CodeCompletionAllocator &getAllocator() override {
       return *AllocatedResults.CodeCompletionAllocator;
     }
 
-    virtual CodeCompletionTUInfo &getCodeCompletionTUInfo() { return CCTUInfo; }
-    
+    CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo;}
+
   private:
     void Finish() {
       AllocatedResults.Results = new CXCompletionResult [StoredResults.size()];
@@ -656,8 +651,7 @@
   const char *complete_filename;
   unsigned complete_line;
   unsigned complete_column;
-  struct CXUnsavedFile *unsaved_files;
-  unsigned num_unsaved_files;
+  ArrayRef<CXUnsavedFile> unsaved_files;
   unsigned options;
   CXCodeCompleteResults *result;
 };
@@ -667,11 +661,9 @@
   const char *complete_filename = CCAI->complete_filename;
   unsigned complete_line = CCAI->complete_line;
   unsigned complete_column = CCAI->complete_column;
-  struct CXUnsavedFile *unsaved_files = CCAI->unsaved_files;
-  unsigned num_unsaved_files = CCAI->num_unsaved_files;
   unsigned options = CCAI->options;
   bool IncludeBriefComments = options & CXCodeComplete_IncludeBriefComments;
-  CCAI->result = 0;
+  CCAI->result = nullptr;
 
 #ifdef UDP_CODE_COMPLETION_LOGGER
 #ifdef UDP_CODE_COMPLETION_LOGGER_PORT
@@ -679,8 +671,13 @@
 #endif
 #endif
 
-  bool EnableLogging = getenv("LIBCLANG_CODE_COMPLETION_LOGGING") != 0;
-  
+  bool EnableLogging = getenv("LIBCLANG_CODE_COMPLETION_LOGGING") != nullptr;
+
+  if (cxtu::isNotUsableTU(TU)) {
+    LOG_BAD_TU(TU);
+    return;
+  }
+
   ASTUnit *AST = cxtu::getASTUnit(TU);
   if (!AST)
     return;
@@ -693,22 +690,21 @@
 
   // Perform the remapping of source files.
   SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
-  for (unsigned I = 0; I != num_unsaved_files; ++I) {
-    StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
-    const llvm::MemoryBuffer *Buffer
-      = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
-    RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename,
-                                           Buffer));
+
+  for (auto &UF : CCAI->unsaved_files) {
+    llvm::MemoryBuffer *MB =
+        llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
+    RemappedFiles.push_back(std::make_pair(UF.Filename, MB));
   }
-  
+
   if (EnableLogging) {
     // FIXME: Add logging.
   }
 
   // Parse the resulting source file to find code-completion results.
-  AllocatedCXCodeCompleteResults *Results = 
-        new AllocatedCXCodeCompleteResults(AST->getFileSystemOpts());
-  Results->Results = 0;
+  AllocatedCXCodeCompleteResults *Results = new AllocatedCXCodeCompleteResults(
+      &AST->getFileManager());
+  Results->Results = nullptr;
   Results->NumResults = 0;
   
   // Create a code-completion consumer to capture the results.
@@ -718,7 +714,7 @@
 
   // Perform completion.
   AST->CodeComplete(complete_filename, complete_line, complete_column,
-                    RemappedFiles.data(), RemappedFiles.size(), 
+                    RemappedFiles,
                     (options & CXCodeComplete_IncludeMacros),
                     (options & CXCodeComplete_IncludeCodePatterns),
                     IncludeBriefComments,
@@ -726,7 +722,9 @@
                     *Results->Diag, Results->LangOpts, *Results->SourceMgr,
                     *Results->FileMgr, Results->Diagnostics,
                     Results->TemporaryBuffers);
-  
+
+  Results->DiagnosticsWrappers.resize(Results->Diagnostics.size());
+
   // Keep a reference to the allocator used for cached global completions, so
   // that we can be sure that the memory used by our code completion strings
   // doesn't get freed due to subsequent reparses (while the code completion
@@ -821,9 +819,12 @@
          << complete_filename << ':' << complete_line << ':' << complete_column;
   }
 
-  CodeCompleteAtInfo CCAI = { TU, complete_filename, complete_line,
-                              complete_column, unsaved_files, num_unsaved_files,
-                              options, 0 };
+  if (num_unsaved_files && !unsaved_files)
+    return nullptr;
+
+  CodeCompleteAtInfo CCAI = {TU, complete_filename, complete_line,
+    complete_column, llvm::makeArrayRef(unsaved_files, num_unsaved_files),
+    options, nullptr};
 
   if (getenv("LIBCLANG_NOTHREADS")) {
     clang_codeCompleteAt_Impl(&CCAI);
@@ -835,7 +836,7 @@
   if (!RunSafely(CRC, clang_codeCompleteAt_Impl, &CCAI)) {
     fprintf(stderr, "libclang: crash detected in code completion\n");
     cxtu::getASTUnit(TU)->setUnsafeToFree(true);
-    return 0;
+    return nullptr;
   } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
     PrintLibclangResourceUsage(TU);
 
@@ -871,9 +872,13 @@
   AllocatedCXCodeCompleteResults *Results
     = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
   if (!Results || Index >= Results->Diagnostics.size())
-    return 0;
+    return nullptr;
 
-  return new CXStoredDiagnostic(Results->Diagnostics[Index], Results->LangOpts);
+  CXStoredDiagnostic *Diag = Results->DiagnosticsWrappers[Index];
+  if (!Diag)
+    Results->DiagnosticsWrappers[Index] = Diag =
+        new CXStoredDiagnostic(Results->Diagnostics[Index], Results->LangOpts);
+  return Diag;
 }
 
 unsigned long long
@@ -893,8 +898,8 @@
     static_cast<AllocatedCXCodeCompleteResults *>(ResultsIn);
   if (!Results)
     return CXCursor_InvalidCode;
-  
-  if (IsIncomplete != NULL) {
+
+  if (IsIncomplete != nullptr) {
     *IsIncomplete = Results->ContainerIsIncomplete;
   }
   
diff --git a/tools/libclang/CIndexDiagnostic.cpp b/tools/libclang/CIndexDiagnostic.cpp
index 0e9dde8..0d97ebd 100644
--- a/tools/libclang/CIndexDiagnostic.cpp
+++ b/tools/libclang/CIndexDiagnostic.cpp
@@ -51,32 +51,35 @@
       Message(Msg), Loc(L) {}
 
   virtual ~CXDiagnosticCustomNoteImpl() {}
-  
-  CXDiagnosticSeverity getSeverity() const {
+
+  CXDiagnosticSeverity getSeverity() const override {
     return CXDiagnostic_Note;
   }
-  
-  CXSourceLocation getLocation() const {
+
+  CXSourceLocation getLocation() const override {
     return Loc;
   }
-  
-  CXString getSpelling() const {
+
+  CXString getSpelling() const override {
     return cxstring::createRef(Message.c_str());
   }
-  
-  CXString getDiagnosticOption(CXString *Disable) const {
+
+  CXString getDiagnosticOption(CXString *Disable) const override {
     if (Disable)
       *Disable = cxstring::createEmpty();
     return cxstring::createEmpty();
   }
-  
-  unsigned getCategory() const { return 0; }
-  CXString getCategoryText() const { return cxstring::createEmpty(); }
 
-  unsigned getNumRanges() const { return 0; }
-  CXSourceRange getRange(unsigned Range) const { return clang_getNullRange(); }
-  unsigned getNumFixIts() const { return 0; }
-  CXString getFixIt(unsigned FixIt, CXSourceRange *ReplacementRange) const {
+  unsigned getCategory() const override { return 0; }
+  CXString getCategoryText() const override { return cxstring::createEmpty(); }
+
+  unsigned getNumRanges() const override { return 0; }
+  CXSourceRange getRange(unsigned Range) const override {
+    return clang_getNullRange();
+  }
+  unsigned getNumFixIts() const override { return 0; }
+  CXString getFixIt(unsigned FixIt,
+                    CXSourceRange *ReplacementRange) const override {
     if (ReplacementRange)
       *ReplacementRange = clang_getNullRange();
     return cxstring::createEmpty();
@@ -93,9 +96,9 @@
   
   virtual ~CXDiagnosticRenderer() {}
 
-  virtual void beginDiagnostic(DiagOrStoredDiag D,
-                               DiagnosticsEngine::Level Level) {    
-    
+  void beginDiagnostic(DiagOrStoredDiag D,
+                       DiagnosticsEngine::Level Level) override {
+
     const StoredDiagnostic *SD = D.dyn_cast<const StoredDiagnostic*>();
     if (!SD)
       return;
@@ -109,13 +112,13 @@
     if (Level != DiagnosticsEngine::Note)
       CurrentSet = &CD->getChildDiagnostics();
   }
-  
-  virtual void emitDiagnosticMessage(SourceLocation Loc, PresumedLoc PLoc,
-                                     DiagnosticsEngine::Level Level,
-                                     StringRef Message,
-                                     ArrayRef<CharSourceRange> Ranges,
-                                     const SourceManager *SM,
-                                     DiagOrStoredDiag D) {
+
+  void emitDiagnosticMessage(SourceLocation Loc, PresumedLoc PLoc,
+                             DiagnosticsEngine::Level Level,
+                             StringRef Message,
+                             ArrayRef<CharSourceRange> Ranges,
+                             const SourceManager *SM,
+                             DiagOrStoredDiag D) override {
     if (!D.isNull())
       return;
     
@@ -127,20 +130,20 @@
     CXDiagnosticImpl *CD = new CXDiagnosticCustomNoteImpl(Message, L);
     CurrentSet->appendDiagnostic(CD);
   }
-  
-  virtual void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
-                                 DiagnosticsEngine::Level Level,
-                                 ArrayRef<CharSourceRange> Ranges,
-                                 const SourceManager &SM) {}
 
-  virtual void emitCodeContext(SourceLocation Loc,
-                               DiagnosticsEngine::Level Level,
-                               SmallVectorImpl<CharSourceRange>& Ranges,
-                               ArrayRef<FixItHint> Hints,
-                               const SourceManager &SM) {}
-  
-  virtual void emitNote(SourceLocation Loc, StringRef Message,
-                        const SourceManager *SM) {
+  void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
+                         DiagnosticsEngine::Level Level,
+                         ArrayRef<CharSourceRange> Ranges,
+                         const SourceManager &SM) override {}
+
+  void emitCodeContext(SourceLocation Loc,
+                       DiagnosticsEngine::Level Level,
+                       SmallVectorImpl<CharSourceRange>& Ranges,
+                       ArrayRef<FixItHint> Hints,
+                       const SourceManager &SM) override {}
+
+  void emitNote(SourceLocation Loc, StringRef Message,
+                const SourceManager *SM) override {
     CXSourceLocation L;
     if (SM)
       L = translateSourceLocation(*SM, LangOpts, Loc);
@@ -183,7 +186,7 @@
       // Diagnostics in the ASTUnit were updated, reset the associated
       // diagnostics.
       delete Set;
-      TU->Diagnostics = 0;
+      TU->Diagnostics = nullptr;
     }
   }
 
@@ -208,26 +211,39 @@
 extern "C" {
 
 unsigned clang_getNumDiagnostics(CXTranslationUnit Unit) {
+  if (cxtu::isNotUsableTU(Unit)) {
+    LOG_BAD_TU(Unit);
+    return 0;
+  }
   if (!cxtu::getASTUnit(Unit))
     return 0;
   return lazyCreateDiags(Unit, /*checkIfChanged=*/true)->getNumDiagnostics();
 }
 
 CXDiagnostic clang_getDiagnostic(CXTranslationUnit Unit, unsigned Index) {
+  if (cxtu::isNotUsableTU(Unit)) {
+    LOG_BAD_TU(Unit);
+    return nullptr;
+  }
+
   CXDiagnosticSet D = clang_getDiagnosticSetFromTU(Unit);
   if (!D)
-    return 0;
+    return nullptr;
 
   CXDiagnosticSetImpl *Diags = static_cast<CXDiagnosticSetImpl*>(D);
   if (Index >= Diags->getNumDiagnostics())
-    return 0;
+    return nullptr;
 
   return Diags->getDiagnostic(Index);
 }
-  
+
 CXDiagnosticSet clang_getDiagnosticSetFromTU(CXTranslationUnit Unit) {
+  if (cxtu::isNotUsableTU(Unit)) {
+    LOG_BAD_TU(Unit);
+    return nullptr;
+  }
   if (!cxtu::getASTUnit(Unit))
-    return 0;
+    return nullptr;
   return static_cast<CXDiagnostic>(lazyCreateDiags(Unit));
 }
 
@@ -251,7 +267,7 @@
     CXFile File;
     unsigned Line, Column;
     clang_getSpellingLocation(clang_getDiagnosticLocation(Diagnostic),
-                              &File, &Line, &Column, 0);
+                              &File, &Line, &Column, nullptr);
     if (File) {
       CXString FName = clang_getFileName(File);
       Out << clang_getCString(FName) << ":" << Line << ":";
@@ -269,10 +285,10 @@
           unsigned StartLine, StartColumn, EndLine, EndColumn;
           clang_getSpellingLocation(clang_getRangeStart(Range),
                                     &StartFile, &StartLine, &StartColumn,
-                                    0);
+                                    nullptr);
           clang_getSpellingLocation(clang_getRangeEnd(Range),
-                                    &EndFile, &EndLine, &EndColumn, 0);
-          
+                                    &EndFile, &EndLine, &EndColumn, nullptr);
+
           if (StartFile != EndFile || StartFile != File)
             continue;
           
@@ -310,7 +326,7 @@
     bool NeedComma = false;
 
     if (Options & CXDiagnostic_DisplayOption) {
-      CXString OptionName = clang_getDiagnosticOption(Diagnostic, 0);
+      CXString OptionName = clang_getDiagnosticOption(Diagnostic, nullptr);
       if (const char *OptionText = clang_getCString(OptionName)) {
         if (OptionText[0]) {
           Out << " [" << OptionText;
@@ -396,7 +412,7 @@
 }
   
 CXString clang_getDiagnosticCategoryName(unsigned Category) {
-  // Kept for backwards compatibility.
+  // Kept for backward compatibility.
   return cxstring::createRef(DiagnosticIDs::getCategoryNameFromID(Category));
 }
   
@@ -437,9 +453,10 @@
 }
 
 void clang_disposeDiagnosticSet(CXDiagnosticSet Diags) {
-  CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl*>(Diags);
-  if (D->isExternallyManaged())
-    delete D;
+  if (CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl *>(Diags)) {
+    if (D->isExternallyManaged())
+      delete D;
+  }
 }
   
 CXDiagnostic clang_getDiagnosticInSet(CXDiagnosticSet Diags,
@@ -447,15 +464,15 @@
   if (CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl*>(Diags))
     if (Index < D->getNumDiagnostics())
       return D->getDiagnostic(Index);
-  return 0;  
+  return nullptr;
 }
   
 CXDiagnosticSet clang_getChildDiagnostics(CXDiagnostic Diag) {
   if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag)) {
     CXDiagnosticSetImpl &ChildDiags = D->getChildDiagnostics();
-    return ChildDiags.empty() ? 0 : (CXDiagnosticSet) &ChildDiags;
+    return ChildDiags.empty() ? nullptr : (CXDiagnosticSet) &ChildDiags;
   }
-  return 0;
+  return nullptr;
 }
 
 unsigned clang_getNumDiagnosticsInSet(CXDiagnosticSet Diags) {
diff --git a/tools/libclang/CIndexDiagnostic.h b/tools/libclang/CIndexDiagnostic.h
index b1c3978..31ae902 100644
--- a/tools/libclang/CIndexDiagnostic.h
+++ b/tools/libclang/CIndexDiagnostic.h
@@ -121,35 +121,35 @@
   virtual ~CXStoredDiagnostic() {}
   
   /// \brief Return the severity of the diagnostic.
-  virtual CXDiagnosticSeverity getSeverity() const;
-  
+  CXDiagnosticSeverity getSeverity() const override;
+
   /// \brief Return the location of the diagnostic.
-  virtual CXSourceLocation getLocation() const;
+  CXSourceLocation getLocation() const override;
 
   /// \brief Return the spelling of the diagnostic.
-  virtual CXString getSpelling() const;
+  CXString getSpelling() const override;
 
   /// \brief Return the text for the diagnostic option.
-  virtual CXString getDiagnosticOption(CXString *Disable) const;
-  
+  CXString getDiagnosticOption(CXString *Disable) const override;
+
   /// \brief Return the category of the diagnostic.
-  virtual unsigned getCategory() const;
-  
+  unsigned getCategory() const override;
+
   /// \brief Return the category string of the diagnostic.
-  virtual CXString getCategoryText() const;
+  CXString getCategoryText() const override;
 
   /// \brief Return the number of source ranges for the diagnostic.
-  virtual unsigned getNumRanges() const;
-  
+  unsigned getNumRanges() const override;
+
   /// \brief Return the source ranges for the diagnostic.
-  virtual CXSourceRange getRange(unsigned Range) const;
+  CXSourceRange getRange(unsigned Range) const override;
 
   /// \brief Return the number of FixIts.
-  virtual unsigned getNumFixIts() const;
+  unsigned getNumFixIts() const override;
 
   /// \brief Return the FixIt information (source range and inserted text).
-  virtual CXString getFixIt(unsigned FixIt,
-                            CXSourceRange *ReplacementRange) const;
+  CXString getFixIt(unsigned FixIt,
+                    CXSourceRange *ReplacementRange) const override;
 
   static bool classof(const CXDiagnosticImpl *D) {
     return D->getKind() == StoredDiagnosticKind;
diff --git a/tools/libclang/CIndexHigh.cpp b/tools/libclang/CIndexHigh.cpp
index c772dbb..d2baa13 100644
--- a/tools/libclang/CIndexHigh.cpp
+++ b/tools/libclang/CIndexHigh.cpp
@@ -78,7 +78,7 @@
   /// itself, so both 'C' can be highlighted.
   const Decl *getCanonical(const Decl *D) const {
     if (!D)
-      return 0;
+      return nullptr;
 
     D = D->getCanonicalDecl();
 
@@ -265,7 +265,7 @@
 static enum CXChildVisitResult findFileMacroRefVisit(CXCursor cursor,
                                                      CXCursor parent,
                                                      CXClientData client_data) {
-  const IdentifierInfo *Macro = 0;
+  const IdentifierInfo *Macro = nullptr;
   if (cursor.kind == CXCursor_MacroDefinition)
     Macro = getCursorMacroDefinition(cursor)->getName();
   else if (cursor.kind == CXCursor_MacroExpansion)
@@ -317,7 +317,7 @@
   SourceManager &SM = Unit->getSourceManager();
 
   FileID FID = SM.translateFile(File);
-  const IdentifierInfo *Macro = 0;
+  const IdentifierInfo *Macro = nullptr;
   if (Cursor.kind == CXCursor_MacroDefinition)
     Macro = getCursorMacroDefinition(Cursor)->getName();
   else
@@ -480,13 +480,12 @@
 
 CXResult clang_findIncludesInFile(CXTranslationUnit TU, CXFile file,
                              CXCursorAndRangeVisitor visitor) {
-  LogRef Log = Logger::make(LLVM_FUNCTION_NAME);
-
-  if (!TU) {
-    if (Log)
-      *Log << "Null CXTranslationUnit";
+  if (cxtu::isNotUsableTU(TU)) {
+    LOG_BAD_TU(TU);
     return CXResult_Invalid;
   }
+
+  LogRef Log = Logger::make(LLVM_FUNCTION_NAME);
   if (!file) {
     if (Log)
       *Log << "Null file";
@@ -523,7 +522,7 @@
                                              CXFile file,
                                            CXCursorAndRangeVisitorBlock block) {
   CXCursorAndRangeVisitor visitor = { block,
-                                      block ? _visitCursorAndRange : 0 };
+                                      block ? _visitCursorAndRange : nullptr };
   return clang_findReferencesInFile(cursor, file, visitor);
 }
 
@@ -531,7 +530,7 @@
                                            CXFile file,
                                            CXCursorAndRangeVisitorBlock block) {
   CXCursorAndRangeVisitor visitor = { block,
-                                      block ? _visitCursorAndRange : 0 };
+                                      block ? _visitCursorAndRange : nullptr };
   return clang_findIncludesInFile(TU, file, visitor);
 }
 
diff --git a/tools/libclang/CIndexInclusionStack.cpp b/tools/libclang/CIndexInclusionStack.cpp
index a6d3115..365609b 100644
--- a/tools/libclang/CIndexInclusionStack.cpp
+++ b/tools/libclang/CIndexInclusionStack.cpp
@@ -24,7 +24,11 @@
 extern "C" {
 void clang_getInclusions(CXTranslationUnit TU, CXInclusionVisitor CB,
                          CXClientData clientData) {
-  
+  if (cxtu::isNotUsableTU(TU)) {
+    LOG_BAD_TU(TU);
+    return;
+  }
+
   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
   SourceManager &SM = CXXUnit->getSourceManager();
   ASTContext &Ctx = CXXUnit->getASTContext();
diff --git a/tools/libclang/CIndexUSRs.cpp b/tools/libclang/CIndexUSRs.cpp
index 2b43c5b..25881c3 100644
--- a/tools/libclang/CIndexUSRs.cpp
+++ b/tools/libclang/CIndexUSRs.cpp
@@ -14,8 +14,10 @@
 #include "CIndexer.h"
 #include "CXCursor.h"
 #include "CXString.h"
+#include "CXTranslationUnit.h"
 #include "clang/Index/USRGeneration.h"
 #include "clang/Lex/PreprocessingRecord.h"
+#include "clang/Frontend/ASTUnit.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/raw_ostream.h"
 
@@ -73,10 +75,16 @@
     if (!buf)
       return cxstring::createEmpty();
 
-    buf->Data += getUSRSpacePrefix();
-    buf->Data += "macro@";
-    buf->Data +=
-        cxcursor::getCursorMacroDefinition(C)->getName()->getNameStart();
+    bool Ignore = generateUSRForMacro(cxcursor::getCursorMacroDefinition(C),
+                                      cxtu::getASTUnit(TU)->getSourceManager(),
+                                      buf->Data);
+    if (Ignore) {
+      buf->dispose();
+      return cxstring::createEmpty();
+    }
+
+    // Return the C-string, but don't make a copy since it is already in
+    // the string buffer.
     buf->Data.push_back('\0');
     return createCXString(buf);
   }
diff --git a/tools/libclang/CLog.h b/tools/libclang/CLog.h
index 57e01ae..e7419b7 100644
--- a/tools/libclang/CLog.h
+++ b/tools/libclang/CLog.h
@@ -10,6 +10,7 @@
 #ifndef LLVM_LIBCLANG_CLOG_H
 #define LLVM_LIBCLANG_CLOG_H
 
+#include "clang-c/Index.h"
 #include "clang/Basic/LLVM.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
 #include "llvm/ADT/SmallString.h"
@@ -47,7 +48,7 @@
     static const char *sCachedVar = ::getenv("LIBCLANG_LOGGING");
     return sCachedVar;
   }
-  static bool isLoggingEnabled() { return getEnvVar() != 0; }
+  static bool isLoggingEnabled() { return getEnvVar() != nullptr; }
   static bool isStackTracingEnabled() {
     if (const char *EnvOpt = Logger::getEnvVar())
       return llvm::StringRef(EnvOpt) == "2";
@@ -57,7 +58,7 @@
                      bool trace = isStackTracingEnabled()) {
     if (isLoggingEnabled())
       return new Logger(name, trace);
-    return 0;
+    return nullptr;
   }
 
   explicit Logger(llvm::StringRef name, bool trace)
@@ -95,7 +96,8 @@
 ///     *Log << "blah";
 ///   }
 /// \endcode
-#define LOG_SECTION(NAME) if (LogRef Log = clang::cxindex::Logger::make(NAME))
+#define LOG_SECTION(NAME) \
+    if (clang::cxindex::LogRef Log = clang::cxindex::Logger::make(NAME))
 #define LOG_FUNC_SECTION LOG_SECTION(LLVM_FUNCTION_NAME)
 
 #endif
diff --git a/tools/libclang/CMakeLists.txt b/tools/libclang/CMakeLists.txt
index b7bde69..e7ab63f 100644
--- a/tools/libclang/CMakeLists.txt
+++ b/tools/libclang/CMakeLists.txt
@@ -1,99 +1,110 @@
-set(LLVM_LINK_COMPONENTS
-  ${LLVM_TARGETS_TO_BUILD}
-  asmparser
-  support
-  bitreader
-  mc
-  )
-
 set(SOURCES
   ARCMigrate.cpp
+  BuildSystem.cpp
   CIndex.cpp
   CIndexCXX.cpp
   CIndexCodeCompletion.cpp
   CIndexDiagnostic.cpp
-  CIndexDiagnostic.h
   CIndexHigh.cpp
   CIndexInclusionStack.cpp
   CIndexUSRs.cpp
   CIndexer.cpp
-  CIndexer.h
   CXComment.cpp
   CXCursor.cpp
-  CXCursor.h
   CXCompilationDatabase.cpp
   CXLoadedDiagnostic.cpp
-  CXLoadedDiagnostic.h
   CXSourceLocation.cpp
-  CXSourceLocation.h
   CXStoredDiagnostic.cpp
   CXString.cpp
-  CXString.h
-  CXTranslationUnit.h
   CXType.cpp
-  CXType.h
   IndexBody.cpp
   IndexDecl.cpp
   IndexTypeSourceInfo.cpp
-  Index_Internal.h
   Indexing.cpp
   IndexingContext.cpp
+
+  ADDITIONAL_HEADERS
+  CIndexDiagnostic.h
+  CIndexer.h
+  CXCursor.h
+  CXLoadedDiagnostic.h
+  CXSourceLocation.h
+  CXString.h
+  CXTranslationUnit.h
+  CXType.h
+  Index_Internal.h
   IndexingContext.h
   ../../include/clang-c/Index.h
   )
 
-set(LIBRARIES
-  clangIndex
-  clangARCMigrate
-  clangRewriteCore
-  clangRewriteFrontend
-  clangFrontend
-  clangDriver
-  clangSerialization
-  clangSema
-  clangEdit
+set(LIBS
   clangAST
-  clangLex
-  clangTooling
   clangBasic
-  )
+  clangFrontend
+  clangIndex
+  clangLex
+  clangSema
+  clangTooling
+)
 
-set(GENERATED_HEADERS
-  ClangAttrClasses
-  ClangAttrList
-  ClangAttrParsedAttrList
-  ClangCommentNodes
-  ClangDiagnosticCommon
-  ClangDiagnosticFrontend
-  ClangDeclNodes
-  ClangStmtNodes
-  )
+if (CLANG_ENABLE_ARCMT)
+  list(APPEND LIBS clangARCMigrate)
+endif ()
 
-set(EXPORTED_SYMBOL_FILE ${CMAKE_CURRENT_SOURCE_DIR}/libclang.exports)
+option(LIBCLANG_BUILD_STATIC
+  "Build libclang as a static library (in addition to a shared one)" OFF)
+
+set(LLVM_EXPORTED_SYMBOL_FILE ${CMAKE_CURRENT_SOURCE_DIR}/libclang.exports)
+
+if(MSVC)
+  # Avoid LNK4197 not to spceify libclang.def here.
+  # Each functions is exported as "dllexport" in include/clang-c.
+  # KB835326
+  set(LLVM_EXPORTED_SYMBOL_FILE)
+endif()
 
 if( LLVM_ENABLE_PIC )
-  set(SHARED_LIBRARY TRUE)
-  add_clang_library(libclang ${SOURCES})
-  target_link_libraries(libclang ${LIBRARIES})
-  add_dependencies(libclang ${GENERATED_HEADERS} clang-headers)
+  set(ENABLE_SHARED SHARED)
+endif()
 
+if((NOT LLVM_ENABLE_PIC OR LIBCLANG_BUILD_STATIC) AND NOT WIN32)
+  set(ENABLE_STATIC STATIC)
+endif()
+
+if(WIN32)
+  set(output_name "libclang")
+else()
+  set(output_name "clang")
+endif()
+
+add_clang_library(libclang ${ENABLE_SHARED} ${ENABLE_STATIC}
+  OUTPUT_NAME ${output_name}
+  ${SOURCES}
+  DEPENDS clang-headers
+
+  LINK_LIBS
+  ${LIBS}
+
+  LINK_COMPONENTS
+  BitReader
+  Support
+  )
+
+if(ENABLE_SHARED)
   if(WIN32)
     set_target_properties(libclang
       PROPERTIES
-      OUTPUT_NAME "libclang"
       VERSION ${LIBCLANG_LIBRARY_VERSION}
       DEFINE_SYMBOL _CINDEX_LIB_)
   else()
     set_target_properties(libclang
       PROPERTIES
-      OUTPUT_NAME "clang"
       VERSION ${LIBCLANG_LIBRARY_VERSION}
       DEFINE_SYMBOL _CINDEX_LIB_)
   endif()
 
   if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
-    set(LIBCLANG_LINK_FLAGS
-      " -Wl,-compatibility_version -Wl,1 -Wl,-dead_strip")
+    set(LIBCLANG_LINK_FLAGS " -Wl,-compatibility_version -Wl,1")
     if (DEFINED ${LLVM_SUBMIT_VERSION})
       set(LIBCLANG_LINK_FLAGS
         "${LIBCLANG_LINK_FLAGS} -Wl,-current_version -Wl,${LLVM_SUBMIT_VERSION}.${LLVM_SUBMIT_SUBVERSION}")
@@ -101,26 +112,5 @@
 
     set_property(TARGET libclang APPEND_STRING PROPERTY
                  LINK_FLAGS ${LIBCLANG_LINK_FLAGS})
-    set_target_properties(libclang
-      PROPERTIES
-      INSTALL_NAME_DIR "@rpath")
   endif()
-
-
-  set(LIBCLANG_STATIC_TARGET_NAME libclang_static)
-else()
-  set(LIBCLANG_STATIC_TARGET_NAME libclang)
-endif()
-
-option(LIBCLANG_BUILD_STATIC
-  "Build libclang as a static library (in addition to a shared one)" OFF)
-
-if( (NOT LLVM_ENABLE_PIC OR LIBCLANG_BUILD_STATIC) AND NOT WIN32 )
-  add_clang_library(${LIBCLANG_STATIC_TARGET_NAME} STATIC ${SOURCES})
-  target_link_libraries(${LIBCLANG_STATIC_TARGET_NAME} ${LIBRARIES})
-  add_dependencies(${LIBCLANG_STATIC_TARGET_NAME} ${GENERATED_HEADERS} clang-headers)
-
-  set_target_properties(${LIBCLANG_STATIC_TARGET_NAME}
-    PROPERTIES
-    OUTPUT_NAME "clang")
 endif()
diff --git a/tools/libclang/CXComment.cpp b/tools/libclang/CXComment.cpp
index 2c4f269..4547031 100644
--- a/tools/libclang/CXComment.cpp
+++ b/tools/libclang/CXComment.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang-c/Index.h"
+#include "clang-c/Documentation.h"
 #include "CXComment.h"
 #include "CXCursor.h"
 #include "CXString.h"
@@ -28,6 +29,19 @@
 
 extern "C" {
 
+CXComment clang_Cursor_getParsedComment(CXCursor C) {
+  using namespace clang::cxcursor;
+
+  if (!clang_isDeclaration(C.kind))
+    return createCXComment(nullptr, nullptr);
+
+  const Decl *D = getCursorDecl(C);
+  const ASTContext &Context = getCursorContext(C);
+  const FullComment *FC = Context.getCommentForDecl(D, /*PP=*/nullptr);
+
+  return createCXComment(FC, getCursorTU(C));
+}
+
 enum CXCommentKind clang_Comment_getKind(CXComment CXC) {
   const Comment *C = getASTNode(CXC);
   if (!C)
@@ -87,7 +101,7 @@
 CXComment clang_Comment_getChild(CXComment CXC, unsigned ChildIdx) {
   const Comment *C = getASTNode(CXC);
   if (!C || ChildIdx >= C->child_count())
-    return createCXComment(NULL, NULL);
+    return createCXComment(nullptr, nullptr);
 
   return createCXComment(*(C->child_begin() + ChildIdx), CXC.TranslationUnit);
 }
@@ -239,7 +253,7 @@
 CXComment clang_BlockCommandComment_getParagraph(CXComment CXC) {
   const BlockCommandComment *BCC = getASTNodeAs<BlockCommandComment>(CXC);
   if (!BCC)
-    return createCXComment(NULL, NULL);
+    return createCXComment(nullptr, nullptr);
 
   return createCXComment(BCC->getParagraph(), CXC.TranslationUnit);
 }
diff --git a/tools/libclang/CXComment.h b/tools/libclang/CXComment.h
index 1e2561d..d9d2bde 100644
--- a/tools/libclang/CXComment.h
+++ b/tools/libclang/CXComment.h
@@ -16,6 +16,7 @@
 
 #include "CXTranslationUnit.h"
 #include "clang-c/Index.h"
+#include "clang-c/Documentation.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Comment.h"
 #include "clang/Frontend/ASTUnit.h"
@@ -43,7 +44,7 @@
 static inline const T *getASTNodeAs(CXComment CXC) {
   const comments::Comment *C = getASTNode(CXC);
   if (!C)
-    return NULL;
+    return nullptr;
 
   return dyn_cast<T>(C);
 }
diff --git a/tools/libclang/CXCompilationDatabase.cpp b/tools/libclang/CXCompilationDatabase.cpp
index 433caec..51677e7 100644
--- a/tools/libclang/CXCompilationDatabase.cpp
+++ b/tools/libclang/CXCompilationDatabase.cpp
@@ -8,7 +8,7 @@
 
 extern "C" {
 
-// FIXME: do something more usefull with the error message
+// FIXME: do something more useful with the error message
 CXCompilationDatabase
 clang_CompilationDatabase_fromDirectory(const char *BuildDir,
                                         CXCompilationDatabase_Error *ErrorCode)
@@ -40,9 +40,8 @@
 {
   std::vector<CompileCommand> CCmd;
 
-  AllocatedCXCompileCommands(const std::vector<CompileCommand>& Cmd)
-    : CCmd(Cmd)
-  { }
+  AllocatedCXCompileCommands(std::vector<CompileCommand> Cmd)
+      : CCmd(std::move(Cmd)) {}
 };
 
 CXCompileCommands
@@ -50,24 +49,23 @@
                                              const char *CompleteFileName)
 {
   if (CompilationDatabase *db = static_cast<CompilationDatabase *>(CDb)) {
-    const std::vector<CompileCommand>
-      CCmd(db->getCompileCommands(CompleteFileName));
+    std::vector<CompileCommand> CCmd(db->getCompileCommands(CompleteFileName));
     if (!CCmd.empty())
-      return new AllocatedCXCompileCommands( CCmd );
+      return new AllocatedCXCompileCommands(std::move(CCmd));
   }
 
-  return 0;
+  return nullptr;
 }
 
 CXCompileCommands
 clang_CompilationDatabase_getAllCompileCommands(CXCompilationDatabase CDb) {
   if (CompilationDatabase *db = static_cast<CompilationDatabase *>(CDb)) {
-    const std::vector<CompileCommand> CCmd(db->getAllCompileCommands());
+    std::vector<CompileCommand> CCmd(db->getAllCompileCommands());
     if (!CCmd.empty())
-      return new AllocatedCXCompileCommands( CCmd );
+      return new AllocatedCXCompileCommands(std::move(CCmd));
   }
 
-  return 0;
+  return nullptr;
 }
 
 void
@@ -92,13 +90,13 @@
 clang_CompileCommands_getCommand(CXCompileCommands Cmds, unsigned I)
 {
   if (!Cmds)
-    return 0;
+    return nullptr;
 
   AllocatedCXCompileCommands *ACC =
     static_cast<AllocatedCXCompileCommands *>(Cmds);
 
   if (I >= ACC->CCmd.size())
-    return 0;
+    return nullptr;
 
   return &ACC->CCmd[I];
 }
diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp
index c75c061..4321903 100644
--- a/tools/libclang/CXCursor.cpp
+++ b/tools/libclang/CXCursor.cpp
@@ -34,7 +34,7 @@
 
 CXCursor cxcursor::MakeCXCursorInvalid(CXCursorKind K, CXTranslationUnit TU) {
   assert(K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid);
-  CXCursor C = { K, 0, { 0, 0, TU } };
+  CXCursor C = { K, 0, { nullptr, nullptr, TU } };
   return C;
 }
 
@@ -50,6 +50,13 @@
     case attr::Annotate: return CXCursor_AnnotateAttr;
     case attr::AsmLabel: return CXCursor_AsmLabelAttr;
     case attr::Packed: return CXCursor_PackedAttr;
+    case attr::Pure: return CXCursor_PureAttr;
+    case attr::Const: return CXCursor_ConstAttr;
+    case attr::NoDuplicate: return CXCursor_NoDuplicateAttr;
+    case attr::CUDAConstant: return CXCursor_CUDAConstantAttr;
+    case attr::CUDADevice: return CXCursor_CUDADeviceAttr;
+    case attr::CUDAGlobal: return CXCursor_CUDAGlobalAttr;
+    case attr::CUDAHost: return CXCursor_CUDAHostAttr;
   }
 
   return CXCursor_UnexposedAttr;
@@ -208,12 +215,15 @@
   case Stmt::SEHFinallyStmtClass:
     K = CXCursor_SEHFinallyStmt;
     break;
+
+  case Stmt::SEHLeaveStmtClass:
+    K = CXCursor_SEHLeaveStmt;
+    break;
   
   case Stmt::ArrayTypeTraitExprClass:
   case Stmt::AsTypeExprClass:
   case Stmt::AtomicExprClass:
   case Stmt::BinaryConditionalOperatorClass:
-  case Stmt::BinaryTypeTraitExprClass:
   case Stmt::TypeTraitExprClass:
   case Stmt::CXXBindTemporaryExprClass:
   case Stmt::CXXDefaultArgExprClass:
@@ -236,7 +246,6 @@
   case Stmt::ShuffleVectorExprClass:
   case Stmt::ConvertVectorExprClass:
   case Stmt::UnaryExprOrTypeTraitExprClass:
-  case Stmt::UnaryTypeTraitExprClass:
   case Stmt::VAArgExprClass:
   case Stmt::ObjCArrayLiteralClass:
   case Stmt::ObjCDictionaryLiteralClass:
@@ -511,9 +520,50 @@
   case Stmt::OMPParallelDirectiveClass:
     K = CXCursor_OMPParallelDirective;
     break;
-  
+  case Stmt::OMPSimdDirectiveClass:
+    K = CXCursor_OMPSimdDirective;
+    break;
+  case Stmt::OMPForDirectiveClass:
+    K = CXCursor_OMPForDirective;
+    break;
+  case Stmt::OMPSectionsDirectiveClass:
+    K = CXCursor_OMPSectionsDirective;
+    break;
+  case Stmt::OMPSectionDirectiveClass:
+    K = CXCursor_OMPSectionDirective;
+    break;
+  case Stmt::OMPSingleDirectiveClass:
+    K = CXCursor_OMPSingleDirective;
+    break;
+  case Stmt::OMPMasterDirectiveClass:
+    K = CXCursor_OMPMasterDirective;
+    break;
+  case Stmt::OMPCriticalDirectiveClass:
+    K = CXCursor_OMPCriticalDirective;
+    break;
+  case Stmt::OMPParallelForDirectiveClass:
+    K = CXCursor_OMPParallelForDirective;
+    break;
+  case Stmt::OMPParallelSectionsDirectiveClass:
+    K = CXCursor_OMPParallelSectionsDirective;
+    break;
+  case Stmt::OMPTaskDirectiveClass:
+    K = CXCursor_OMPTaskDirective;
+    break;
+  case Stmt::OMPTaskyieldDirectiveClass:
+    K = CXCursor_OMPTaskyieldDirective;
+    break;
+  case Stmt::OMPBarrierDirectiveClass:
+    K = CXCursor_OMPBarrierDirective;
+    break;
+  case Stmt::OMPTaskwaitDirectiveClass:
+    K = CXCursor_OMPTaskwaitDirective;
+    break;
+  case Stmt::OMPFlushDirectiveClass:
+    K = CXCursor_OMPFlushDirective;
+    break;
   }
-  
+
   CXCursor C = { K, 0, { Parent, S, TU } };
   return C;
 }
@@ -652,7 +702,7 @@
 
 CXCursor cxcursor::MakeCursorCXXBaseSpecifier(const CXXBaseSpecifier *B,
                                               CXTranslationUnit TU){
-  CXCursor C = { CXCursor_CXXBaseSpecifier, 0, { B, 0, TU } };
+  CXCursor C = { CXCursor_CXXBaseSpecifier, 0, { B, nullptr, TU } };
   return C;  
 }
 
@@ -681,7 +731,7 @@
 
 CXCursor cxcursor::MakeMacroDefinitionCursor(const MacroDefinition *MI,
                                              CXTranslationUnit TU) {
-  CXCursor C = { CXCursor_MacroDefinition, 0, { MI, 0, TU } };
+  CXCursor C = { CXCursor_MacroDefinition, 0, { MI, nullptr, TU } };
   return C;
 }
 
@@ -692,7 +742,7 @@
 
 CXCursor cxcursor::MakeMacroExpansionCursor(MacroExpansion *MI, 
                                             CXTranslationUnit TU) {
-  CXCursor C = { CXCursor_MacroExpansion, 0, { MI, 0, TU } };
+  CXCursor C = { CXCursor_MacroExpansion, 0, { MI, nullptr, TU } };
   return C;
 }
 
@@ -722,7 +772,7 @@
 
 CXCursor cxcursor::MakeInclusionDirectiveCursor(InclusionDirective *ID, 
                                                 CXTranslationUnit TU) {
-  CXCursor C = { CXCursor_InclusionDirective, 0, { ID, 0, TU } };
+  CXCursor C = { CXCursor_InclusionDirective, 0, { ID, nullptr, TU } };
   return C;
 }
 
@@ -805,7 +855,7 @@
   if (Cursor.kind == CXCursor_ObjCSuperClassRef ||
       Cursor.kind == CXCursor_ObjCProtocolRef ||
       Cursor.kind == CXCursor_ObjCClassRef)
-    return 0;
+    return nullptr;
 
   return static_cast<const Stmt *>(Cursor.data[1]);
 }
@@ -825,7 +875,7 @@
 ASTUnit *cxcursor::getCursorASTUnit(CXCursor Cursor) {
   CXTranslationUnit TU = getCursorTU(Cursor);
   if (!TU)
-    return 0;
+    return nullptr;
   return cxtu::getASTUnit(TU);
 }
 
@@ -899,7 +949,7 @@
     return cursor;
 
   const Expr *E = getCursorExpr(cursor);
-  TypeSourceInfo *Type = 0;
+  TypeSourceInfo *Type = nullptr;
   if (const CXXUnresolvedConstructExpr *
         UnCtor = dyn_cast<CXXUnresolvedConstructExpr>(E)) {
     Type = UnCtor->getTypeSourceInfo();
@@ -982,11 +1032,11 @@
     const Decl *D = cxcursor::getCursorDecl(C);
     if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D)) {
       if (i < MD->param_size())
-        return cxcursor::MakeCXCursor(MD->param_begin()[i],
+        return cxcursor::MakeCXCursor(MD->parameters()[i],
                                       cxcursor::getCursorTU(C));
     } else if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) {
       if (i < FD->param_size())
-        return cxcursor::MakeCXCursor(FD->param_begin()[i],
+        return cxcursor::MakeCXCursor(FD->parameters()[i],
                                       cxcursor::getCursorTU(C));
     }
   }
@@ -1100,7 +1150,7 @@
                                  false);
     return String;
   }
-  return NULL;
+  return nullptr;
 }
 } // end: extern C.
 
@@ -1132,7 +1182,7 @@
                                 CXCursor **overridden,
                                 unsigned *num_overridden) {
   if (overridden)
-    *overridden = 0;
+    *overridden = nullptr;
   if (num_overridden)
     *num_overridden = 0;
   
@@ -1146,9 +1196,9 @@
     
   OverridenCursorsPool &pool =
     *static_cast<OverridenCursorsPool*>(TU->OverridenCursorsPool);
-  
-  OverridenCursorsPool::CursorVec *Vec = 0;
-  
+
+  OverridenCursorsPool::CursorVec *Vec = nullptr;
+
   if (!pool.AvailableCursors.empty()) {
     Vec = pool.AvailableCursors.back();
     pool.AvailableCursors.pop_back();
@@ -1206,7 +1256,7 @@
 }
 
 int clang_Cursor_isDynamicCall(CXCursor C) {
-  const Expr *E = 0;
+  const Expr *E = nullptr;
   if (clang_isExpression(C.kind))
     E = getCursorExpr(C);
   if (!E)
@@ -1215,7 +1265,7 @@
   if (const ObjCMessageExpr *MsgE = dyn_cast<ObjCMessageExpr>(E))
     return MsgE->getReceiverKind() == ObjCMessageExpr::Instance;
 
-  const MemberExpr *ME = 0;
+  const MemberExpr *ME = nullptr;
   if (isa<MemberExpr>(E))
     ME = cast<MemberExpr>(E);
   else if (const CallExpr *CE = dyn_cast<CallExpr>(E))
@@ -1232,7 +1282,7 @@
 
 CXType clang_Cursor_getReceiverType(CXCursor C) {
   CXTranslationUnit TU = cxcursor::getCursorTU(C);
-  const Expr *E = 0;
+  const Expr *E = nullptr;
   if (clang_isExpression(C.kind))
     E = getCursorExpr(C);
 
diff --git a/tools/libclang/CXCursor.h b/tools/libclang/CXCursor.h
index 957d519..fee3bac 100644
--- a/tools/libclang/CXCursor.h
+++ b/tools/libclang/CXCursor.h
@@ -56,7 +56,7 @@
 CXCursor MakeCXCursor(const clang::Stmt *S, const clang::Decl *Parent,
                       CXTranslationUnit TU,
                       SourceRange RegionOfInterest = SourceRange());
-CXCursor MakeCXCursorInvalid(CXCursorKind K, CXTranslationUnit TU = 0);
+CXCursor MakeCXCursorInvalid(CXCursorKind K, CXTranslationUnit TU = nullptr);
 
 /// \brief Create an Objective-C superclass reference at the given location.
 CXCursor MakeCursorObjCSuperClassRef(ObjCInterfaceDecl *Super, 
@@ -172,7 +172,7 @@
   CXCursor C;
 
   bool isPseudo() const {
-    return C.data[1] != 0;
+    return C.data[1] != nullptr;
   }
   const MacroDefinition *getAsMacroDefinition() const {
     assert(isPseudo());
diff --git a/tools/libclang/CXLoadedDiagnostic.cpp b/tools/libclang/CXLoadedDiagnostic.cpp
index b02fdd6..ddf3749 100644
--- a/tools/libclang/CXLoadedDiagnostic.cpp
+++ b/tools/libclang/CXLoadedDiagnostic.cpp
@@ -15,13 +15,13 @@
 #include "CXString.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/FileManager.h"
+#include "clang/Basic/LLVM.h"
 #include "clang/Frontend/SerializedDiagnosticPrinter.h"
+#include "llvm/ADT/Optional.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/Twine.h"
-#include "llvm/ADT/Optional.h"
-#include "clang/Basic/LLVM.h"
-#include "llvm/Support/ErrorHandling.h"
 #include "llvm/Bitcode/BitstreamReader.h"
+#include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/MemoryBuffer.h"
 using namespace clang;
 
@@ -67,13 +67,21 @@
 //===----------------------------------------------------------------------===//
 
 CXDiagnosticSeverity CXLoadedDiagnostic::getSeverity() const {
-  // FIXME: possibly refactor with logic in CXStoredDiagnostic.
-  switch (severity) {
-    case DiagnosticsEngine::Ignored: return CXDiagnostic_Ignored;
-    case DiagnosticsEngine::Note:    return CXDiagnostic_Note;
-    case DiagnosticsEngine::Warning: return CXDiagnostic_Warning;
-    case DiagnosticsEngine::Error:   return CXDiagnostic_Error;
-    case DiagnosticsEngine::Fatal:   return CXDiagnostic_Fatal;
+  // FIXME: Fail more softly if the diagnostic level is unknown?
+  auto severityAsLevel = static_cast<serialized_diags::Level>(severity);
+  assert(severity == static_cast<unsigned>(severityAsLevel) &&
+         "unknown serialized diagnostic level");
+
+  switch (severityAsLevel) {
+#define CASE(X) case serialized_diags::X: return CXDiagnostic_##X;
+  CASE(Ignored)
+  CASE(Note)
+  CASE(Warning)
+  CASE(Error)
+  CASE(Fatal)
+#undef CASE
+  // The 'Remark' level isn't represented in the stable API.
+  case serialized_diags::Remark: return CXDiagnostic_Warning;
   }
   
   llvm_unreachable("Invalid diagnostic level");
@@ -84,7 +92,7 @@
   // is a persistent diagnostic.
   uintptr_t V = (uintptr_t) DLoc;
   V |= 0x1;
-  CXSourceLocation Loc = { {  (void*) V, 0 }, 0 };
+  CXSourceLocation Loc = { {  (void*) V, nullptr }, 0 };
   return Loc;
 }  
 
@@ -175,7 +183,7 @@
 // Deserialize diagnostics.
 //===----------------------------------------------------------------------===//
 
-enum { MaxSupportedVersion = 1 };
+enum { MaxSupportedVersion = 2 };
 typedef SmallVector<uint64_t, 64> RecordData;
 enum LoadResult { Failure = 1, Success = 0 };
 enum StreamResult { Read_EndOfStream,
@@ -252,12 +260,12 @@
   FileSystemOptions FO;
   FileManager FileMgr(FO);
 
-  OwningPtr<llvm::MemoryBuffer> Buffer;
+  std::unique_ptr<llvm::MemoryBuffer> Buffer;
   Buffer.reset(FileMgr.getBufferForFile(file));
 
   if (!Buffer) {
     reportBad(CXLoadDiag_CannotLoad, ErrStr);
-    return 0;
+    return nullptr;
   }
 
   llvm::BitstreamReader StreamFile;
@@ -274,10 +282,11 @@
       Stream.Read(8) != 'G') {
     reportBad(CXLoadDiag_InvalidFile,
               "Bad header in diagnostics file");
-    return 0;
+    return nullptr;
   }
 
-  OwningPtr<CXLoadedDiagnosticSetImpl> Diags(new CXLoadedDiagnosticSetImpl());
+  std::unique_ptr<CXLoadedDiagnosticSetImpl> Diags(
+      new CXLoadedDiagnosticSetImpl());
 
   while (true) {
     unsigned BlockID = 0;
@@ -285,9 +294,9 @@
                                                BlockID, true);
     switch (Res) {
       case Read_EndOfStream:
-        return (CXDiagnosticSet) Diags.take();
+        return (CXDiagnosticSet)Diags.release();
       case Read_Failure:
-        return 0;
+        return nullptr;
       case Read_Record:
         llvm_unreachable("Top-level does not have records");
       case Read_BlockEnd:
@@ -299,16 +308,16 @@
     switch (BlockID) {
       case serialized_diags::BLOCK_META:
         if (readMetaBlock(Stream))
-          return 0;
+          return nullptr;
         break;
       case serialized_diags::BLOCK_DIAG:
         if (readDiagnosticBlock(Stream, *Diags.get(), *Diags.get()))
-          return 0;
+          return nullptr;
         break;
       default:
         if (!Stream.SkipBlock()) {
           reportInvalidFile("Malformed block at top-level of diagnostics file");
-          return 0;
+          return nullptr;
         }
         break;
     }
@@ -486,7 +495,7 @@
   unsigned fileID = Record[offset++];
   if (fileID == 0) {
     // Sentinel value.
-    Loc.file = 0;
+    Loc.file = nullptr;
     Loc.line = 0;
     Loc.column = 0;
     Loc.offset = 0;
@@ -532,8 +541,8 @@
     reportInvalidFile("malformed diagnostic block");
     return Failure;
   }
-  
-  OwningPtr<CXLoadedDiagnostic> D(new CXLoadedDiagnostic());
+
+  std::unique_ptr<CXLoadedDiagnostic> D(new CXLoadedDiagnostic());
   RecordData Record;
   
   while (true) {
@@ -560,7 +569,7 @@
         continue;
       }
       case Read_BlockEnd:
-        Diags.appendDiagnostic(D.take());        
+        Diags.appendDiagnostic(D.release());
         return Success;
       case Read_Record:
         break;
diff --git a/tools/libclang/CXLoadedDiagnostic.h b/tools/libclang/CXLoadedDiagnostic.h
index d4b11d5..c281f9b 100644
--- a/tools/libclang/CXLoadedDiagnostic.h
+++ b/tools/libclang/CXLoadedDiagnostic.h
@@ -29,36 +29,36 @@
   virtual ~CXLoadedDiagnostic();
   
   /// \brief Return the severity of the diagnostic.
-  virtual CXDiagnosticSeverity getSeverity() const;
-  
+  CXDiagnosticSeverity getSeverity() const override;
+
   /// \brief Return the location of the diagnostic.
-  virtual CXSourceLocation getLocation() const;
-  
+  CXSourceLocation getLocation() const override;
+
   /// \brief Return the spelling of the diagnostic.
-  virtual CXString getSpelling() const;
-  
+  CXString getSpelling() const override;
+
   /// \brief Return the text for the diagnostic option.
-  virtual CXString getDiagnosticOption(CXString *Disable) const;
-  
+  CXString getDiagnosticOption(CXString *Disable) const override;
+
   /// \brief Return the category of the diagnostic.
-  virtual unsigned getCategory() const;
-  
+  unsigned getCategory() const override;
+
   /// \brief Return the category string of the diagnostic.
-  virtual CXString getCategoryText() const;
-  
+  CXString getCategoryText() const override;
+
   /// \brief Return the number of source ranges for the diagnostic.
-  virtual unsigned getNumRanges() const;
-  
+  unsigned getNumRanges() const override;
+
   /// \brief Return the source ranges for the diagnostic.
-  virtual CXSourceRange getRange(unsigned Range) const;
-  
+  CXSourceRange getRange(unsigned Range) const override;
+
   /// \brief Return the number of FixIts.
-  virtual unsigned getNumFixIts() const;
-  
+  unsigned getNumFixIts() const override;
+
   /// \brief Return the FixIt information (source range and inserted text).
-  virtual CXString getFixIt(unsigned FixIt,
-                            CXSourceRange *ReplacementRange) const;
-  
+  CXString getFixIt(unsigned FixIt,
+                    CXSourceRange *ReplacementRange) const override;
+
   static bool classof(const CXDiagnosticImpl *D) {
     return D->getKind() == LoadedDiagnosticKind;
   }
diff --git a/tools/libclang/CXSourceLocation.cpp b/tools/libclang/CXSourceLocation.cpp
index 7371177..64a441e 100644
--- a/tools/libclang/CXSourceLocation.cpp
+++ b/tools/libclang/CXSourceLocation.cpp
@@ -41,7 +41,7 @@
 extern "C" {
   
 CXSourceLocation clang_getNullLocation() {
-  CXSourceLocation Result = { { 0, 0 }, 0 };
+  CXSourceLocation Result = { { nullptr, nullptr }, 0 };
   return Result;
 }
 
@@ -52,7 +52,7 @@
 }
 
 CXSourceRange clang_getNullRange() {
-  CXSourceRange Result = { { 0, 0 }, 0, 0 };
+  CXSourceRange Result = { { nullptr, nullptr }, 0, 0 };
   return Result;
 }
 
@@ -89,7 +89,7 @@
 CXSourceLocation clang_getRangeStart(CXSourceRange range) {
   // Special decoding for CXSourceLocations for CXLoadedDiagnostics.
   if ((uintptr_t)range.ptr_data[0] & 0x1) {
-    CXSourceLocation Result = { { range.ptr_data[0], 0 }, 0 };
+    CXSourceLocation Result = { { range.ptr_data[0], nullptr }, 0 };
     return Result;    
   }
   
@@ -101,7 +101,7 @@
 CXSourceLocation clang_getRangeEnd(CXSourceRange range) {
   // Special decoding for CXSourceLocations for CXLoadedDiagnostics.
   if ((uintptr_t)range.ptr_data[0] & 0x1) {
-    CXSourceLocation Result = { { range.ptr_data[1], 0 }, 0 };
+    CXSourceLocation Result = { { range.ptr_data[1], nullptr }, 0 };
     return Result;    
   }
 
@@ -122,7 +122,11 @@
                                    CXFile file,
                                    unsigned line,
                                    unsigned column) {
-  if (!TU || !file)
+  if (cxtu::isNotUsableTU(TU)) {
+    LOG_BAD_TU(TU);
+    return clang_getNullLocation();
+  }
+  if (!file)
     return clang_getNullLocation();
   if (line == 0 || column == 0)
     return clang_getNullLocation();
@@ -151,9 +155,13 @@
 CXSourceLocation clang_getLocationForOffset(CXTranslationUnit TU,
                                             CXFile file,
                                             unsigned offset) {
-  if (!TU || !file)
+  if (cxtu::isNotUsableTU(TU)) {
+    LOG_BAD_TU(TU);
     return clang_getNullLocation();
-  
+  }
+  if (!file)
+    return clang_getNullLocation();
+
   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
 
   SourceLocation SLoc 
@@ -175,7 +183,7 @@
 static void createNullLocation(CXFile *file, unsigned *line,
                                unsigned *column, unsigned *offset) {
   if (file)
-    *file = 0;
+    *file = nullptr;
   if (line)
     *line = 0;
   if (column)
@@ -186,7 +194,7 @@
 }
 
 static void createNullLocation(CXString *filename, unsigned *line,
-                               unsigned *column, unsigned *offset = 0) {
+                               unsigned *column, unsigned *offset = nullptr) {
   if (filename)
     *filename = cxstring::createEmpty();
   if (line)
diff --git a/tools/libclang/CXStoredDiagnostic.cpp b/tools/libclang/CXStoredDiagnostic.cpp
index 9731616..faaf746 100644
--- a/tools/libclang/CXStoredDiagnostic.cpp
+++ b/tools/libclang/CXStoredDiagnostic.cpp
@@ -31,6 +31,8 @@
   switch (Diag.getLevel()) {
     case DiagnosticsEngine::Ignored: return CXDiagnostic_Ignored;
     case DiagnosticsEngine::Note:    return CXDiagnostic_Note;
+    case DiagnosticsEngine::Remark:
+    // The 'Remark' level isn't represented in the stable API.
     case DiagnosticsEngine::Warning: return CXDiagnostic_Warning;
     case DiagnosticsEngine::Error:   return CXDiagnostic_Error;
     case DiagnosticsEngine::Fatal:   return CXDiagnostic_Fatal;
diff --git a/tools/libclang/CXString.cpp b/tools/libclang/CXString.cpp
index 1523034..dec8ebc 100644
--- a/tools/libclang/CXString.cpp
+++ b/tools/libclang/CXString.cpp
@@ -51,7 +51,7 @@
 
 CXString createNull() {
   CXString Str;
-  Str.data = 0;
+  Str.data = nullptr;
   Str.private_flags = CXS_Unmanaged;
   return Str;
 }
@@ -81,7 +81,11 @@
 
 CXString createRef(StringRef String) {
   // If the string is not nul-terminated, we have to make a copy.
-  // This is doing a one past end read, and should be removed!
+
+  // FIXME: This is doing a one past end read, and should be removed! For memory
+  // we don't manage, the API string can become unterminated at any time outside
+  // our control.
+
   if (!String.empty() && String.data()[String.size()] != 0)
     return createDup(String);
 
diff --git a/tools/libclang/CXString.h b/tools/libclang/CXString.h
index 7032033..ed3ed4a 100644
--- a/tools/libclang/CXString.h
+++ b/tools/libclang/CXString.h
@@ -19,8 +19,8 @@
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Compiler.h"
-#include <vector>
 #include <string>
+#include <vector>
 
 namespace clang {
 namespace cxstring {
@@ -97,6 +97,10 @@
 bool isManagedByPool(CXString str);
 
 }
+
+static inline StringRef getContents(const CXUnsavedFile &UF) {
+  return StringRef(UF.Contents, UF.Length);
+}
 }
 
 #endif
diff --git a/tools/libclang/CXTranslationUnit.h b/tools/libclang/CXTranslationUnit.h
index c0014c0..d86ed2b 100644
--- a/tools/libclang/CXTranslationUnit.h
+++ b/tools/libclang/CXTranslationUnit.h
@@ -14,8 +14,9 @@
 #ifndef LLVM_CLANG_CXTRANSLATIONUNIT_H
 #define LLVM_CLANG_CXTRANSLATIONUNIT_H
 
-#include "clang-c/Index.h"
+#include "CLog.h"
 #include "CXString.h"
+#include "clang-c/Index.h"
 
 namespace clang {
   class ASTUnit;
@@ -41,10 +42,25 @@
 
 static inline ASTUnit *getASTUnit(CXTranslationUnit TU) {
   if (!TU)
-    return 0;
+    return nullptr;
   return TU->TheASTUnit;
 }
 
+/// \returns true if the ASTUnit has a diagnostic about the AST file being
+/// corrupted.
+bool isASTReadError(ASTUnit *AU);
+
+static inline bool isNotUsableTU(CXTranslationUnit TU) {
+  return !TU;
+}
+
+#define LOG_BAD_TU(TU)                                  \
+    do {                                                \
+      LOG_FUNC_SECTION {                                \
+        *Log << "called with a bad TU: " << TU;         \
+      }                                                 \
+    } while(false)
+
 class CXTUOwner {
   CXTranslationUnitImpl *TU;
   
@@ -56,7 +72,7 @@
 
   CXTranslationUnitImpl *takeTU() {
     CXTranslationUnitImpl *retTU = TU;
-    TU = 0;
+    TU = nullptr;
     return retTU;
   }
 };
diff --git a/tools/libclang/CXType.cpp b/tools/libclang/CXType.cpp
index 1e2cb18..fe45899 100644
--- a/tools/libclang/CXType.cpp
+++ b/tools/libclang/CXType.cpp
@@ -120,7 +120,8 @@
   if (TK == CXType_Invalid)
     TK = GetTypeKind(T);
 
-  CXType CT = { TK, { TK == CXType_Invalid ? 0 : T.getAsOpaquePtr(), TU }};
+  CXType CT = { TK, { TK == CXType_Invalid ? nullptr
+                                           : T.getAsOpaquePtr(), TU } };
   return CT;
 }
 
@@ -386,7 +387,7 @@
   if (!TP)
     return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
 
-  Decl *D = 0;
+  Decl *D = nullptr;
 
 try_again:
   switch (TP->getTypeClass()) {
@@ -432,7 +433,7 @@
 }
 
 CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
-  const char *s = 0;
+  const char *s = nullptr;
 #define TKIND(X) case CXType_##X: s = ""  #X  ""; break
   switch (K) {
     TKIND(Invalid);
@@ -538,7 +539,7 @@
     return -1;
   
   if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
-    return FD->getNumArgs();
+    return FD->getNumParams();
   }
   
   if (T->getAs<FunctionNoProtoType>()) {
@@ -554,11 +555,11 @@
     return MakeCXType(QualType(), GetTU(X));
 
   if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
-    unsigned numArgs = FD->getNumArgs();
-    if (i >= numArgs)
+    unsigned numParams = FD->getNumParams();
+    if (i >= numParams)
       return MakeCXType(QualType(), GetTU(X));
-    
-    return MakeCXType(FD->getArgType(i), GetTU(X));
+
+    return MakeCXType(FD->getParamType(i), GetTU(X));
   }
   
   return MakeCXType(QualType(), GetTU(X));
@@ -570,8 +571,8 @@
     return MakeCXType(QualType(), GetTU(X));
   
   if (const FunctionType *FD = T->getAs<FunctionType>())
-    return MakeCXType(FD->getResultType(), GetTU(X));
-  
+    return MakeCXType(FD->getReturnType(), GetTU(X));
+
   return MakeCXType(QualType(), GetTU(X));
 }
 
@@ -579,7 +580,7 @@
   if (clang_isDeclaration(C.kind)) {
     const Decl *D = cxcursor::getCursorDecl(C);
     if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
-      return MakeCXType(MD->getResultType(), cxcursor::getCursorTU(C));
+      return MakeCXType(MD->getReturnType(), cxcursor::getCursorTU(C));
 
     return clang_getResultType(clang_getCursorType(C));
   }
@@ -752,15 +753,14 @@
 }
 
 static long long visitRecordForValidation(const RecordDecl *RD) {
-  for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
-       I != E; ++I){
-    QualType FQT = (*I)->getType();
+  for (const auto *I : RD->fields()){
+    QualType FQT = I->getType();
     if (FQT->isIncompleteType())
       return CXTypeLayoutError_Incomplete;
     if (FQT->isDependentType())
       return CXTypeLayoutError_Dependent;
     // recurse
-    if (const RecordType *ChildType = (*I)->getType()->getAs<RecordType>()) {
+    if (const RecordType *ChildType = I->getType()->getAs<RecordType>()) {
       if (const RecordDecl *Child = ChildType->getDecl()) {
         long long ret = visitRecordForValidation(Child);
         if (ret < 0)
@@ -855,7 +855,7 @@
     if (Ctx.getObjCEncodingForMethodDecl(OMD, encoding))
       return cxstring::createRef("?");
   } else if (const ObjCPropertyDecl *OPD = dyn_cast<ObjCPropertyDecl>(D))
-    Ctx.getObjCEncodingForPropertyDecl(OPD, NULL, encoding);
+    Ctx.getObjCEncodingForPropertyDecl(OPD, nullptr, encoding);
   else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
     Ctx.getObjCEncodingForFunctionDecl(FD, encoding);
   else {
@@ -871,4 +871,38 @@
   return cxstring::createDup(encoding);
 }
 
+int clang_Type_getNumTemplateArguments(CXType CT) {
+  QualType T = GetQualType(CT);
+  if (T.isNull())
+    return -1;
+  const CXXRecordDecl *RecordDecl = T->getAsCXXRecordDecl();
+  if (!RecordDecl)
+    return -1;
+  const ClassTemplateSpecializationDecl *TemplateDecl =
+      dyn_cast<ClassTemplateSpecializationDecl>(RecordDecl);
+  if (!TemplateDecl)
+    return -1;
+  return TemplateDecl->getTemplateArgs().size();
+}
+
+CXType clang_Type_getTemplateArgumentAsType(CXType CT, unsigned i) {
+  QualType T = GetQualType(CT);
+  if (T.isNull())
+    return MakeCXType(QualType(), GetTU(CT));
+  const CXXRecordDecl *RecordDecl = T->getAsCXXRecordDecl();
+  if (!RecordDecl)
+    return MakeCXType(QualType(), GetTU(CT));
+  const ClassTemplateSpecializationDecl *TemplateDecl =
+      dyn_cast<ClassTemplateSpecializationDecl>(RecordDecl);
+  if (!TemplateDecl)
+    return MakeCXType(QualType(), GetTU(CT));
+  const TemplateArgumentList &TA = TemplateDecl->getTemplateArgs();
+  if (TA.size() <= i)
+    return MakeCXType(QualType(), GetTU(CT));
+  const TemplateArgument &A = TA.get(i);
+  if (A.getKind() != TemplateArgument::Type)
+    return MakeCXType(QualType(), GetTU(CT));
+  return MakeCXType(A.getAsType(), GetTU(CT));
+}
+
 } // end: extern "C"
diff --git a/tools/libclang/CursorVisitor.h b/tools/libclang/CursorVisitor.h
index 53d864d..c4ec7b6 100644
--- a/tools/libclang/CursorVisitor.h
+++ b/tools/libclang/CursorVisitor.h
@@ -36,8 +36,8 @@
   const void *data[3];
   CXCursor parent;
   Kind K;
-  VisitorJob(CXCursor C, Kind k, const void *d1, const void *d2 = 0,
-             const void *d3 = 0)
+  VisitorJob(CXCursor C, Kind k, const void *d1, const void *d2 = nullptr,
+             const void *d3 = nullptr)
     : parent(C), K(k) {
     data[0] = d1;
     data[1] = d2;
@@ -147,7 +147,7 @@
                 bool VisitIncludedPreprocessingEntries = false,
                 SourceRange RegionOfInterest = SourceRange(),
                 bool VisitDeclsOnly = false,
-                PostChildrenVisitorTy PostChildrenVisitor = 0)
+                PostChildrenVisitorTy PostChildrenVisitor = nullptr)
     : TU(TU), AU(cxtu::getASTUnit(TU)),
       Visitor(Visitor), PostChildrenVisitor(PostChildrenVisitor),
       ClientData(ClientData),
@@ -155,13 +155,13 @@
       VisitIncludedEntities(VisitIncludedPreprocessingEntries),
       RegionOfInterest(RegionOfInterest),
       VisitDeclsOnly(VisitDeclsOnly),
-      DI_current(0), FileDI_current(0)
+      DI_current(nullptr), FileDI_current(nullptr)
   {
     Parent.kind = CXCursor_NoDeclFound;
-    Parent.data[0] = 0;
-    Parent.data[1] = 0;
-    Parent.data[2] = 0;
-    StmtParent = 0;
+    Parent.data[0] = nullptr;
+    Parent.data[1] = nullptr;
+    Parent.data[2] = nullptr;
+    StmtParent = nullptr;
   }
 
   ~CursorVisitor() {
diff --git a/tools/libclang/IndexBody.cpp b/tools/libclang/IndexBody.cpp
index e08a346..7dc53a6 100644
--- a/tools/libclang/IndexBody.cpp
+++ b/tools/libclang/IndexBody.cpp
@@ -8,19 +8,19 @@
 //===----------------------------------------------------------------------===//
 
 #include "IndexingContext.h"
-#include "RecursiveASTVisitor.h"
+#include "clang/AST/DataRecursiveASTVisitor.h"
 
 using namespace clang;
 using namespace cxindex;
 
 namespace {
 
-class BodyIndexer : public cxindex::RecursiveASTVisitor<BodyIndexer> {
+class BodyIndexer : public DataRecursiveASTVisitor<BodyIndexer> {
   IndexingContext &IndexCtx;
   const NamedDecl *Parent;
   const DeclContext *ParentDC;
 
-  typedef RecursiveASTVisitor<BodyIndexer> base;
+  typedef DataRecursiveASTVisitor<BodyIndexer> base;
 public:
   BodyIndexer(IndexingContext &indexCtx,
               const NamedDecl *Parent, const DeclContext *DC)
@@ -149,13 +149,13 @@
     return true;
   }
 
-  bool TraverseLambdaCapture(LambdaExpr::Capture C) {
-    if (C.capturesThis())
+  bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C) {
+    if (C->capturesThis())
       return true;
 
-    if (C.capturesVariable() && IndexCtx.shouldIndexFunctionLocalSymbols())
-      IndexCtx.handleReference(C.getCapturedVar(), C.getLocation(),
-                               Parent, ParentDC);
+    if (C->capturesVariable() && IndexCtx.shouldIndexFunctionLocalSymbols())
+      IndexCtx.handleReference(C->getCapturedVar(), C->getLocation(), Parent,
+                               ParentDC);
 
     // FIXME: Lambda init-captures.
     return true;
@@ -170,7 +170,7 @@
   if (!S)
     return;
 
-  if (DC == 0)
+  if (!DC)
     DC = Parent->getLexicalDeclContext();
   BodyIndexer(*this, Parent, DC).TraverseStmt(const_cast<Stmt*>(S));
 }
diff --git a/tools/libclang/IndexDecl.cpp b/tools/libclang/IndexDecl.cpp
index 89feb96..c8cf1d3 100644
--- a/tools/libclang/IndexDecl.cpp
+++ b/tools/libclang/IndexDecl.cpp
@@ -31,7 +31,8 @@
     return MD && !MD->isImplicit() && MD->isThisDeclarationADefinition();
   }
 
-  void handleDeclarator(const DeclaratorDecl *D, const NamedDecl *Parent = 0) {
+  void handleDeclarator(const DeclaratorDecl *D,
+                        const NamedDecl *Parent = nullptr) {
     if (!Parent) Parent = D;
 
     if (!IndexCtx.shouldIndexFunctionLocalSymbols()) {
@@ -41,10 +42,8 @@
       if (const ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) {
         IndexCtx.handleVar(Parm);
       } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
-        for (FunctionDecl::param_const_iterator PI = FD->param_begin(),
-                                                PE = FD->param_end();
-             PI != PE; ++PI) {
-          IndexCtx.handleVar(*PI);
+        for (auto PI : FD->params()) {
+          IndexCtx.handleVar(PI);
         }
       }
     }
@@ -55,11 +54,9 @@
     if (D->isImplicit())
       return;
 
-    IndexCtx.indexTypeSourceInfo(D->getResultTypeSourceInfo(), D);
-    for (ObjCMethodDecl::param_const_iterator I = D->param_begin(),
-                                              E = D->param_end();
-         I != E; ++I)
-      handleDeclarator(*I, D);
+    IndexCtx.indexTypeSourceInfo(D->getReturnTypeSourceInfo(), D);
+    for (const auto *I : D->params())
+      handleDeclarator(I, D);
 
     if (D->isThisDeclarationADefinition()) {
       const Stmt *Body = D->getBody();
@@ -75,10 +72,7 @@
 
     if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
       // Constructor initializers.
-      for (CXXConstructorDecl::init_const_iterator I = Ctor->init_begin(),
-                                                   E = Ctor->init_end();
-           I != E; ++I) {
-        CXXCtorInitializer *Init = *I;
+      for (const auto *Init : Ctor->inits()) {
         if (Init->isWritten()) {
           IndexCtx.indexTypeSourceInfo(Init->getTypeSourceInfo(), D);
           if (const FieldDecl *Member = Init->getAnyMember())
@@ -172,15 +166,11 @@
 
     // Index the ivars first to make sure the synthesized ivars are indexed
     // before indexing the methods that can reference them.
-    for (ObjCImplementationDecl::ivar_iterator
-           IvarI = D->ivar_begin(),
-           IvarE = D->ivar_end(); IvarI != IvarE; ++IvarI) {
-      IndexCtx.indexDecl(*IvarI);
-    }
-    for (DeclContext::decl_iterator
-           I = D->decls_begin(), E = D->decls_end(); I != E; ++I) {
-      if (!isa<ObjCIvarDecl>(*I))
-        IndexCtx.indexDecl(*I);
+    for (const auto *IvarI : D->ivars())
+      IndexCtx.indexDecl(IvarI);
+    for (const auto *I : D->decls()) {
+      if (!isa<ObjCIvarDecl>(I))
+        IndexCtx.indexDecl(I);
     }
 
     return true;
@@ -238,7 +228,7 @@
     
     if (ObjCIvarDecl *IvarD = D->getPropertyIvarDecl()) {
       if (!IvarD->getSynthesize())
-        IndexCtx.handleReference(IvarD, D->getPropertyIvarDeclLoc(), 0,
+        IndexCtx.handleReference(IvarD, D->getPropertyIvarDeclLoc(), nullptr,
                                  D->getDeclContext());
     }
 
@@ -268,11 +258,9 @@
     // we should do better.
 
     IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), D);
-    for (UsingDecl::shadow_iterator
-           I = D->shadow_begin(), E = D->shadow_end(); I != E; ++I) {
-      IndexCtx.handleReference((*I)->getUnderlyingDecl(), D->getLocation(),
-                               D, D->getLexicalDeclContext());
-    }
+    for (const auto *I : D->shadows())
+      IndexCtx.handleReference(I->getUnderlyingDecl(), D->getLocation(), D,
+                               D->getLexicalDeclContext());
     return true;
   }
 
@@ -341,10 +329,8 @@
 }
 
 void IndexingContext::indexDeclContext(const DeclContext *DC) {
-  for (DeclContext::decl_iterator
-         I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) {
-    indexDecl(*I);
-  }
+  for (const auto *I : DC->decls())
+    indexDecl(I);
 }
 
 void IndexingContext::indexTopLevelDecl(const Decl *D) {
diff --git a/tools/libclang/IndexTypeSourceInfo.cpp b/tools/libclang/IndexTypeSourceInfo.cpp
index 2c771c8..f13c0af 100644
--- a/tools/libclang/IndexTypeSourceInfo.cpp
+++ b/tools/libclang/IndexTypeSourceInfo.cpp
@@ -8,14 +8,14 @@
 //===----------------------------------------------------------------------===//
 
 #include "IndexingContext.h"
-#include "RecursiveASTVisitor.h"
+#include "clang/AST/DataRecursiveASTVisitor.h"
 
 using namespace clang;
 using namespace cxindex;
 
 namespace {
 
-class TypeIndexer : public cxindex::RecursiveASTVisitor<TypeIndexer> {
+class TypeIndexer : public DataRecursiveASTVisitor<TypeIndexer> {
   IndexingContext &IndexCtx;
   const NamedDecl *Parent;
   const DeclContext *ParentDC;
@@ -108,7 +108,7 @@
   if (TL.isNull())
     return;
 
-  if (DC == 0)
+  if (!DC)
     DC = Parent->getLexicalDeclContext();
   TypeIndexer(*this, Parent, DC).TraverseTypeLoc(TL);
 }
@@ -122,7 +122,7 @@
   if (NestedNameSpecifierLoc Prefix = NNS.getPrefix())
     indexNestedNameSpecifierLoc(Prefix, Parent, DC);
 
-  if (DC == 0)
+  if (!DC)
     DC = Parent->getLexicalDeclContext();
   SourceLocation Loc = NNS.getSourceRange().getBegin();
 
diff --git a/tools/libclang/Indexing.cpp b/tools/libclang/Indexing.cpp
index 99fcdb6..58af618 100644
--- a/tools/libclang/Indexing.cpp
+++ b/tools/libclang/Indexing.cpp
@@ -219,7 +219,7 @@
     assert(RegionLoc.isFileID());
     FileID RegionFID;
     unsigned RegionOffset;
-    llvm::tie(RegionFID, RegionOffset) = SM.getDecomposedLoc(RegionLoc);
+    std::tie(RegionFID, RegionOffset) = SM.getDecomposedLoc(RegionLoc);
 
     if (RegionFID != FID) {
       if (isParsedOnceInclude(FE)) {
@@ -253,8 +253,8 @@
   IndexPPCallbacks(Preprocessor &PP, IndexingContext &indexCtx)
     : PP(PP), IndexCtx(indexCtx), IsMainFileEntered(false) { }
 
-  virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
-                          SrcMgr::CharacteristicKind FileType, FileID PrevFID) {
+  void FileChanged(SourceLocation Loc, FileChangeReason Reason,
+                 SrcMgr::CharacteristicKind FileType, FileID PrevFID) override {
     if (IsMainFileEntered)
       return;
 
@@ -267,15 +267,11 @@
     }
   }
 
-  virtual void InclusionDirective(SourceLocation HashLoc,
-                                  const Token &IncludeTok,
-                                  StringRef FileName,
-                                  bool IsAngled,
-                                  CharSourceRange FilenameRange,
-                                  const FileEntry *File,
-                                  StringRef SearchPath,
-                                  StringRef RelativePath,
-                                  const Module *Imported) {
+  void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
+                          StringRef FileName, bool IsAngled,
+                          CharSourceRange FilenameRange, const FileEntry *File,
+                          StringRef SearchPath, StringRef RelativePath,
+                          const Module *Imported) override {
     bool isImport = (IncludeTok.is(tok::identifier) &&
             IncludeTok.getIdentifierInfo()->getPPKeywordID() == tok::pp_import);
     IndexCtx.ppIncludedFile(HashLoc, FileName, File, isImport, IsAngled,
@@ -283,25 +279,21 @@
   }
 
   /// MacroDefined - This hook is called whenever a macro definition is seen.
-  virtual void MacroDefined(const Token &Id, const MacroDirective *MD) {
-  }
+  void MacroDefined(const Token &Id, const MacroDirective *MD) override {}
 
   /// MacroUndefined - This hook is called whenever a macro #undef is seen.
   /// MI is released immediately following this callback.
-  virtual void MacroUndefined(const Token &MacroNameTok,
-                              const MacroDirective *MD) {
-  }
+  void MacroUndefined(const Token &MacroNameTok,
+                      const MacroDirective *MD) override {}
 
   /// MacroExpands - This is called by when a macro invocation is found.
-  virtual void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD,
-                            SourceRange Range, const MacroArgs *Args) {
-  }
+  void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD,
+                    SourceRange Range, const MacroArgs *Args) override {}
 
   /// SourceRangeSkipped - This hook is called when a source range is skipped.
   /// \param Range The SourceRange that was skipped. The range begins at the
   /// #if/#else directive and ends after the #endif/#else directive.
-  virtual void SourceRangeSkipped(SourceRange Range) {
-  }
+  void SourceRangeSkipped(SourceRange Range) override {}
 };
 
 //===----------------------------------------------------------------------===//
@@ -318,24 +310,24 @@
 
   // ASTConsumer Implementation
 
-  virtual void Initialize(ASTContext &Context) {
+  void Initialize(ASTContext &Context) override {
     IndexCtx.setASTContext(Context);
     IndexCtx.startedTranslationUnit();
   }
 
-  virtual void HandleTranslationUnit(ASTContext &Ctx) {
+  void HandleTranslationUnit(ASTContext &Ctx) override {
     if (SKCtrl)
       SKCtrl->finished();
   }
 
-  virtual bool HandleTopLevelDecl(DeclGroupRef DG) {
+  bool HandleTopLevelDecl(DeclGroupRef DG) override {
     IndexCtx.indexDeclGroupRef(DG);
     return !IndexCtx.shouldAbort();
   }
 
   /// \brief Handle the specified top-level declaration that occurred inside
   /// and ObjC container.
-  virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) {
+  void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override {
     // They will be handled after the interface is seen first.
     IndexCtx.addTUDeclInObjCContainer(D);
   }
@@ -343,9 +335,9 @@
   /// \brief This is called by the AST reader when deserializing things.
   /// The default implementation forwards to HandleTopLevelDecl but we don't
   /// care about them when indexing, so have an empty definition.
-  virtual void HandleInterestingDecl(DeclGroupRef D) {}
+  void HandleInterestingDecl(DeclGroupRef D) override {}
 
-  virtual void HandleTagDeclDefinition(TagDecl *D) {
+  void HandleTagDeclDefinition(TagDecl *D) override {
     if (!IndexCtx.shouldIndexImplicitTemplateInsts())
       return;
 
@@ -353,14 +345,14 @@
       IndexCtx.indexDecl(D);
   }
 
-  virtual void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) {
+  void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) override {
     if (!IndexCtx.shouldIndexImplicitTemplateInsts())
       return;
 
     IndexCtx.indexDecl(D);
   }
 
-  virtual bool shouldSkipFunctionBody(Decl *D) {
+  bool shouldSkipFunctionBody(Decl *D) override {
     if (!SKCtrl) {
       // Always skip bodies.
       return true;
@@ -375,7 +367,7 @@
 
     FileID FID;
     unsigned Offset;
-    llvm::tie(FID, Offset) = SM.getDecomposedLoc(Loc);
+    std::tie(FID, Offset) = SM.getDecomposedLoc(Loc);
     // Don't skip bodies from main files; this may be revisited.
     if (SM.getMainFileID() == FID)
       return false;
@@ -395,8 +387,8 @@
   SmallVector<StoredDiagnostic, 4> Errors;
 public:
 
-  virtual void HandleDiagnostic(DiagnosticsEngine::Level level,
-                                const Diagnostic &Info) {
+  void HandleDiagnostic(DiagnosticsEngine::Level level,
+                        const Diagnostic &Info) override {
     if (level >= DiagnosticsEngine::Error)
       Errors.push_back(StoredDiagnostic(level, Info));
   }
@@ -411,7 +403,7 @@
   CXTranslationUnit CXTU;
 
   SessionSkipBodyData *SKData;
-  OwningPtr<TUSkipBodyControl> SKCtrl;
+  std::unique_ptr<TUSkipBodyControl> SKCtrl;
 
 public:
   IndexingFrontendAction(CXClientData clientData,
@@ -422,8 +414,8 @@
     : IndexCtx(clientData, indexCallbacks, indexOptions, cxTU),
       CXTU(cxTU), SKData(skData) { }
 
-  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
-                                         StringRef InFile) {
+  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                 StringRef InFile) override {
     PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();
 
     if (!PPOpts.ImplicitPCHInclude.empty()) {
@@ -446,17 +438,17 @@
     return new IndexingConsumer(IndexCtx, SKCtrl.get());
   }
 
-  virtual void EndSourceFileAction() {
+  void EndSourceFileAction() override {
     indexDiagnostics(CXTU, IndexCtx);
   }
 
-  virtual TranslationUnitKind getTranslationUnitKind() {
+  TranslationUnitKind getTranslationUnitKind() override {
     if (IndexCtx.shouldIndexImplicitTemplateInsts())
       return TU_Complete;
     else
       return TU_Prefix;
   }
-  virtual bool hasCodeCompletionSupport() const { return false; }
+  bool hasCodeCompletionSupport() const override { return false; }
 };
 
 //===----------------------------------------------------------------------===//
@@ -465,7 +457,7 @@
 
 struct IndexSessionData {
   CXIndex CIdx;
-  OwningPtr<SessionSkipBodyData> SkipBodyData;
+  std::unique_ptr<SessionSkipBodyData> SkipBodyData;
 
   explicit IndexSessionData(CXIndex cIdx)
     : CIdx(cIdx), SkipBodyData(new SessionSkipBodyData) {}
@@ -480,28 +472,17 @@
   const char *source_filename;
   const char *const *command_line_args;
   int num_command_line_args;
-  struct CXUnsavedFile *unsaved_files;
-  unsigned num_unsaved_files;
+  ArrayRef<CXUnsavedFile> unsaved_files;
   CXTranslationUnit *out_TU;
   unsigned TU_options;
-  int result;
-};
-
-struct MemBufferOwner {
-  SmallVector<const llvm::MemoryBuffer *, 8> Buffers;
-  
-  ~MemBufferOwner() {
-    for (SmallVectorImpl<const llvm::MemoryBuffer *>::iterator
-           I = Buffers.begin(), E = Buffers.end(); I != E; ++I)
-      delete *I;
-  }
+  CXErrorCode &result;
 };
 
 } // anonymous namespace
 
 static void clang_indexSourceFile_Impl(void *UserData) {
-  IndexSourceFileInfo *ITUI =
-    static_cast<IndexSourceFileInfo*>(UserData);
+  const IndexSourceFileInfo *ITUI =
+      static_cast<IndexSourceFileInfo *>(UserData);
   CXIndexAction cxIdxAction = ITUI->idxAction;
   CXClientData client_data = ITUI->client_data;
   IndexerCallbacks *client_index_callbacks = ITUI->index_callbacks;
@@ -510,20 +491,21 @@
   const char *source_filename = ITUI->source_filename;
   const char * const *command_line_args = ITUI->command_line_args;
   int num_command_line_args = ITUI->num_command_line_args;
-  struct CXUnsavedFile *unsaved_files = ITUI->unsaved_files;
-  unsigned num_unsaved_files = ITUI->num_unsaved_files;
   CXTranslationUnit *out_TU  = ITUI->out_TU;
   unsigned TU_options = ITUI->TU_options;
-  ITUI->result = 1; // init as error.
-  
-  if (out_TU)
-    *out_TU = 0;
-  bool requestedToGetTU = (out_TU != 0); 
 
-  if (!cxIdxAction)
+  if (out_TU)
+    *out_TU = nullptr;
+  bool requestedToGetTU = (out_TU != nullptr);
+
+  if (!cxIdxAction) {
+    ITUI->result = CXError_InvalidArguments;
     return;
-  if (!client_index_callbacks || index_callbacks_size == 0)
+  }
+  if (!client_index_callbacks || index_callbacks_size == 0) {
+    ITUI->result = CXError_InvalidArguments;
     return;
+  }
 
   IndexerCallbacks CB;
   memset(&CB, 0, sizeof(CB));
@@ -539,7 +521,7 @@
 
   bool CaptureDiagnostics = !Logger::isLoggingEnabled();
 
-  CaptureDiagnosticConsumer *CaptureDiag = 0;
+  CaptureDiagnosticConsumer *CaptureDiag = nullptr;
   if (CaptureDiagnostics)
     CaptureDiag = new CaptureDiagnosticConsumer();
 
@@ -552,10 +534,10 @@
   // Recover resources if we crash before exiting this function.
   llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
     llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
-    DiagCleanup(Diags.getPtr());
-  
-  OwningPtr<std::vector<const char *> >
-    Args(new std::vector<const char*>());
+    DiagCleanup(Diags.get());
+
+  std::unique_ptr<std::vector<const char *>> Args(
+      new std::vector<const char *>());
 
   // Recover resources if we crash before exiting this method.
   llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
@@ -581,23 +563,23 @@
   // Recover resources if we crash before exiting this function.
   llvm::CrashRecoveryContextCleanupRegistrar<CompilerInvocation,
     llvm::CrashRecoveryContextReleaseRefCleanup<CompilerInvocation> >
-    CInvokCleanup(CInvok.getPtr());
+    CInvokCleanup(CInvok.get());
 
   if (CInvok->getFrontendOpts().Inputs.empty())
     return;
 
-  OwningPtr<MemBufferOwner> BufOwner(new MemBufferOwner());
+  typedef SmallVector<std::unique_ptr<llvm::MemoryBuffer>, 8> MemBufferOwner;
+  std::unique_ptr<MemBufferOwner> BufOwner(new MemBufferOwner);
 
   // Recover resources if we crash before exiting this method.
-  llvm::CrashRecoveryContextCleanupRegistrar<MemBufferOwner>
-    BufOwnerCleanup(BufOwner.get());
+  llvm::CrashRecoveryContextCleanupRegistrar<MemBufferOwner> BufOwnerCleanup(
+      BufOwner.get());
 
-  for (unsigned I = 0; I != num_unsaved_files; ++I) {
-    StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
-    const llvm::MemoryBuffer *Buffer
-      = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
-    CInvok->getPreprocessorOpts().addRemappedFile(unsaved_files[I].Filename, Buffer);
-    BufOwner->Buffers.push_back(Buffer);
+  for (auto &UF : ITUI->unsaved_files) {
+    llvm::MemoryBuffer *MB =
+        llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
+    BufOwner->push_back(std::unique_ptr<llvm::MemoryBuffer>(MB));
+    CInvok->getPreprocessorOpts().addRemappedFile(UF.Filename, MB);
   }
 
   // Since libclang is primarily used by batch tools dealing with
@@ -609,10 +591,16 @@
   if (index_options & CXIndexOpt_SuppressWarnings)
     CInvok->getDiagnosticOpts().IgnoreWarnings = true;
 
-  ASTUnit *Unit = ASTUnit::create(CInvok.getPtr(), Diags,
+  ASTUnit *Unit = ASTUnit::create(CInvok.get(), Diags,
                                   CaptureDiagnostics,
                                   /*UserFilesAreVolatile=*/true);
-  OwningPtr<CXTUOwner> CXTU(new CXTUOwner(MakeCXTranslationUnit(CXXIdx, Unit)));
+  if (!Unit) {
+    ITUI->result = CXError_InvalidArguments;
+    return;
+  }
+
+  std::unique_ptr<CXTUOwner> CXTU(
+      new CXTUOwner(MakeCXTranslationUnit(CXXIdx, Unit)));
 
   // Recover resources if we crash before exiting this method.
   llvm::CrashRecoveryContextCleanupRegistrar<CXTUOwner>
@@ -625,10 +613,10 @@
   if (SkipBodies)
     CInvok->getFrontendOpts().SkipFunctionBodies = true;
 
-  OwningPtr<IndexingFrontendAction> IndexAction;
+  std::unique_ptr<IndexingFrontendAction> IndexAction;
   IndexAction.reset(new IndexingFrontendAction(client_data, CB,
                                                index_options, CXTU->getTU(),
-                              SkipBodies ? IdxSession->SkipBodyData.get() : 0));
+                        SkipBodies ? IdxSession->SkipBodyData.get() : nullptr));
 
   // Recover resources if we crash before exiting this method.
   llvm::CrashRecoveryContextCleanupRegistrar<IndexingFrontendAction>
@@ -657,7 +645,7 @@
     PPOpts.DetailedRecord = false;
 
   DiagnosticErrorTrap DiagTrap(*Diags);
-  bool Success = ASTUnit::LoadFromCompilerInvocationAction(CInvok.getPtr(), Diags,
+  bool Success = ASTUnit::LoadFromCompilerInvocationAction(CInvok.get(), Diags,
                                                        IndexAction.get(),
                                                        Unit,
                                                        Persistent,
@@ -671,13 +659,18 @@
   if (DiagTrap.hasErrorOccurred() && CXXIdx->getDisplayDiagnostics())
     printDiagsToStderr(Unit);
 
+  if (isASTReadError(Unit)) {
+    ITUI->result = CXError_ASTReadError;
+    return;
+  }
+
   if (!Success)
     return;
 
   if (out_TU)
     *out_TU = CXTU->takeTU();
 
-  ITUI->result = 0; // success.
+  ITUI->result = CXError_Success;
 }
 
 //===----------------------------------------------------------------------===//
@@ -706,7 +699,7 @@
   // FIXME: Only deserialize inclusion directives.
 
   PreprocessingRecord::iterator I, E;
-  llvm::tie(I, E) = Unit.getLocalPreprocessingEntities();
+  std::tie(I, E) = Unit.getLocalPreprocessingEntities();
 
   bool isModuleFile = Unit.isModuleFile();
   for (; I != E; ++I) {
@@ -754,12 +747,20 @@
   IndexerCallbacks *client_index_callbacks = ITUI->index_callbacks;
   unsigned index_callbacks_size = ITUI->index_callbacks_size;
   unsigned index_options = ITUI->index_options;
-  ITUI->result = 1; // init as error.
 
-  if (!TU)
+  // Set up the initial return value.
+  ITUI->result = CXError_Failure;
+
+  // Check arguments.
+  if (isNotUsableTU(TU)) {
+    LOG_BAD_TU(TU);
+    ITUI->result = CXError_InvalidArguments;
     return;
-  if (!client_index_callbacks || index_callbacks_size == 0)
+  }
+  if (!client_index_callbacks || index_callbacks_size == 0) {
+    ITUI->result = CXError_InvalidArguments;
     return;
+  }
 
   CIndexer *CXXIdx = TU->CIdx;
   if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
@@ -771,15 +772,15 @@
                                   ? index_callbacks_size : sizeof(CB);
   memcpy(&CB, client_index_callbacks, ClientCBSize);
 
-  OwningPtr<IndexingContext> IndexCtx;
+  std::unique_ptr<IndexingContext> IndexCtx;
   IndexCtx.reset(new IndexingContext(client_data, CB, index_options, TU));
 
   // Recover resources if we crash before exiting this method.
   llvm::CrashRecoveryContextCleanupRegistrar<IndexingContext>
     IndexCtxCleanup(IndexCtx.get());
 
-  OwningPtr<IndexingConsumer> IndexConsumer;
-  IndexConsumer.reset(new IndexingConsumer(*IndexCtx, 0));
+  std::unique_ptr<IndexingConsumer> IndexConsumer;
+  IndexConsumer.reset(new IndexingConsumer(*IndexCtx, nullptr));
 
   // Recover resources if we crash before exiting this method.
   llvm::CrashRecoveryContextCleanupRegistrar<IndexingConsumer>
@@ -797,7 +798,7 @@
   FileManager &FileMgr = Unit->getFileManager();
 
   if (Unit->getOriginalSourceFileName().empty())
-    IndexCtx->enteredMainFile(0);
+    IndexCtx->enteredMainFile(nullptr);
   else
     IndexCtx->enteredMainFile(FileMgr.getFile(Unit->getOriginalSourceFileName()));
 
@@ -807,7 +808,7 @@
   indexTranslationUnit(*Unit, *IndexCtx);
   indexDiagnostics(TU, *IndexCtx);
 
-  ITUI->result = 0;
+  ITUI->result = CXError_Success;
 }
 
 //===----------------------------------------------------------------------===//
@@ -823,46 +824,46 @@
 const CXIdxObjCContainerDeclInfo *
 clang_index_getObjCContainerDeclInfo(const CXIdxDeclInfo *DInfo) {
   if (!DInfo)
-    return 0;
+    return nullptr;
 
   const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo);
   if (const ObjCContainerDeclInfo *
         ContInfo = dyn_cast<ObjCContainerDeclInfo>(DI))
     return &ContInfo->ObjCContDeclInfo;
 
-  return 0;
+  return nullptr;
 }
 
 const CXIdxObjCInterfaceDeclInfo *
 clang_index_getObjCInterfaceDeclInfo(const CXIdxDeclInfo *DInfo) {
   if (!DInfo)
-    return 0;
+    return nullptr;
 
   const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo);
   if (const ObjCInterfaceDeclInfo *
         InterInfo = dyn_cast<ObjCInterfaceDeclInfo>(DI))
     return &InterInfo->ObjCInterDeclInfo;
 
-  return 0;
+  return nullptr;
 }
 
 const CXIdxObjCCategoryDeclInfo *
 clang_index_getObjCCategoryDeclInfo(const CXIdxDeclInfo *DInfo){
   if (!DInfo)
-    return 0;
+    return nullptr;
 
   const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo);
   if (const ObjCCategoryDeclInfo *
         CatInfo = dyn_cast<ObjCCategoryDeclInfo>(DI))
     return &CatInfo->ObjCCatDeclInfo;
 
-  return 0;
+  return nullptr;
 }
 
 const CXIdxObjCProtocolRefListInfo *
 clang_index_getObjCProtocolRefListInfo(const CXIdxDeclInfo *DInfo) {
   if (!DInfo)
-    return 0;
+    return nullptr;
 
   const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo);
   
@@ -877,50 +878,50 @@
   if (const ObjCCategoryDeclInfo *CatInfo = dyn_cast<ObjCCategoryDeclInfo>(DI))
     return CatInfo->ObjCCatDeclInfo.protocols;
 
-  return 0;
+  return nullptr;
 }
 
 const CXIdxObjCPropertyDeclInfo *
 clang_index_getObjCPropertyDeclInfo(const CXIdxDeclInfo *DInfo) {
   if (!DInfo)
-    return 0;
+    return nullptr;
 
   const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo);
   if (const ObjCPropertyDeclInfo *PropInfo = dyn_cast<ObjCPropertyDeclInfo>(DI))
     return &PropInfo->ObjCPropDeclInfo;
 
-  return 0;
+  return nullptr;
 }
 
 const CXIdxIBOutletCollectionAttrInfo *
 clang_index_getIBOutletCollectionAttrInfo(const CXIdxAttrInfo *AInfo) {
   if (!AInfo)
-    return 0;
+    return nullptr;
 
   const AttrInfo *DI = static_cast<const AttrInfo *>(AInfo);
   if (const IBOutletCollectionInfo *
         IBInfo = dyn_cast<IBOutletCollectionInfo>(DI))
     return &IBInfo->IBCollInfo;
 
-  return 0;
+  return nullptr;
 }
 
 const CXIdxCXXClassDeclInfo *
 clang_index_getCXXClassDeclInfo(const CXIdxDeclInfo *DInfo) {
   if (!DInfo)
-    return 0;
+    return nullptr;
 
   const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo);
   if (const CXXClassDeclInfo *ClassInfo = dyn_cast<CXXClassDeclInfo>(DI))
     return &ClassInfo->CXXClassInfo;
 
-  return 0;
+  return nullptr;
 }
 
 CXIdxClientContainer
 clang_index_getClientContainer(const CXIdxContainerInfo *info) {
   if (!info)
-    return 0;
+    return nullptr;
   const ContainerInfo *Container = static_cast<const ContainerInfo *>(info);
   return Container->IndexCtx->getClientContainerForDC(Container->DC);
 }
@@ -935,7 +936,7 @@
 
 CXIdxClientEntity clang_index_getClientEntity(const CXIdxEntityInfo *info) {
   if (!info)
-    return 0;
+    return nullptr;
   const EntityInfo *Entity = static_cast<const EntityInfo *>(info);
   return Entity->IndexCtx->getClientEntity(Entity->Dcl);
 }
@@ -975,15 +976,27 @@
       *Log << command_line_args[i] << " ";
   }
 
-  IndexSourceFileInfo ITUI = { idxAction, client_data, index_callbacks,
-                               index_callbacks_size, index_options,
-                               source_filename, command_line_args,
-                               num_command_line_args, unsaved_files,
-                               num_unsaved_files, out_TU, TU_options, 0 };
+  if (num_unsaved_files && !unsaved_files)
+    return CXError_InvalidArguments;
+
+  CXErrorCode result = CXError_Failure;
+  IndexSourceFileInfo ITUI = {
+      idxAction,
+      client_data,
+      index_callbacks,
+      index_callbacks_size,
+      index_options,
+      source_filename,
+      command_line_args,
+      num_command_line_args,
+      llvm::makeArrayRef(unsaved_files, num_unsaved_files),
+      out_TU,
+      TU_options,
+      result};
 
   if (getenv("LIBCLANG_NOTHREADS")) {
     clang_indexSourceFile_Impl(&ITUI);
-    return ITUI.result;
+    return result;
   }
 
   llvm::CrashRecoveryContext CRC;
@@ -1014,8 +1027,8 @@
     if (out_TU)
       PrintLibclangResourceUsage(*out_TU);
   }
-  
-  return ITUI.result;
+
+  return result;
 }
 
 int clang_indexTranslationUnit(CXIndexAction idxAction,
@@ -1054,8 +1067,8 @@
                                     unsigned *line,
                                     unsigned *column,
                                     unsigned *offset) {
-  if (indexFile) *indexFile = 0;
-  if (file)   *file = 0;
+  if (indexFile) *indexFile = nullptr;
+  if (file)   *file = nullptr;
   if (line)   *line = 0;
   if (column) *column = 0;
   if (offset) *offset = 0;
diff --git a/tools/libclang/IndexingContext.cpp b/tools/libclang/IndexingContext.cpp
index 41ed6ea..bf6e172 100644
--- a/tools/libclang/IndexingContext.cpp
+++ b/tools/libclang/IndexingContext.cpp
@@ -30,7 +30,7 @@
     ObjCProtocolDecl *PD = *I;
     ProtEntities.push_back(EntityInfo());
     IdxCtx.getEntityInfo(PD, ProtEntities.back(), SA);
-    CXIdxObjCProtocolRefInfo ProtInfo = { 0,
+    CXIdxObjCProtocolRefInfo ProtInfo = { nullptr,
                                 MakeCursorObjCProtocolRef(PD, Loc, IdxCtx.CXTU),
                                 IdxCtx.getIndexLoc(Loc) };
     ProtInfos.push_back(ProtInfo);
@@ -58,7 +58,7 @@
     ClassInfo = other.ClassInfo;
     IBCollInfo.objcClass = &ClassInfo;
   } else
-    IBCollInfo.objcClass = 0;
+    IBCollInfo.objcClass = nullptr;
 }
 
 AttrListInfo::AttrListInfo(const Decl *D, IndexingContext &IdxCtx)
@@ -67,9 +67,7 @@
   if (!D->hasAttrs())
     return;
 
-  for (AttrVec::const_iterator AttrI = D->attr_begin(), AttrE = D->attr_end();
-         AttrI != AttrE; ++AttrI) {
-    const Attr *A = *AttrI;
+  for (const auto *A : D->attrs()) {
     CXCursor C = MakeCXCursor(A, D, IdxCtx.CXTU);
     CXIdxLoc Loc =  IdxCtx.getIndexLoc(A->getLocation());
     switch (C.kind) {
@@ -98,7 +96,7 @@
         IBAttr->getInterfaceLoc()->getTypeLoc().getLocStart();
     IBInfo.IBCollInfo.attrInfo = &IBInfo;
     IBInfo.IBCollInfo.classLoc = IdxCtx.getIndexLoc(InterfaceLocStart);
-    IBInfo.IBCollInfo.objcClass = 0;
+    IBInfo.IBCollInfo.objcClass = nullptr;
     IBInfo.IBCollInfo.classCursor = clang_getNullCursor();
     QualType Ty = IBAttr->getInterface();
     if (const ObjCObjectType *ObjectTy = Ty->getAs<ObjCObjectType>()) {
@@ -125,11 +123,9 @@
 IndexingContext::CXXBasesListInfo::CXXBasesListInfo(const CXXRecordDecl *D,
                                    IndexingContext &IdxCtx,
                                    ScratchAlloc &SA) {
-  for (CXXRecordDecl::base_class_const_iterator
-         I = D->bases_begin(), E = D->bases_end(); I != E; ++I) {
-    const CXXBaseSpecifier &Base = *I;
+  for (const auto &Base : D->bases()) {
     BaseEntities.push_back(EntityInfo());
-    const NamedDecl *BaseD = 0;
+    const NamedDecl *BaseD = nullptr;
     QualType T = Base.getType();
     SourceLocation Loc = getBaseLoc(Base);
 
@@ -144,7 +140,7 @@
 
     if (BaseD)
       IdxCtx.getEntityInfo(BaseD, BaseEntities.back(), SA);
-    CXIdxBaseClassInfo BaseInfo = { 0,
+    CXIdxBaseClassInfo BaseInfo = { nullptr,
                          MakeCursorCXXBaseSpecifier(&Base, IdxCtx.CXTU),
                          IdxCtx.getIndexLoc(Loc) };
     BaseInfos.push_back(BaseInfo);
@@ -231,14 +227,15 @@
 bool IndexingContext::shouldAbort() {
   if (!CB.abortQuery)
     return false;
-  return CB.abortQuery(ClientData, 0);
+  return CB.abortQuery(ClientData, nullptr);
 }
 
 void IndexingContext::enteredMainFile(const FileEntry *File) {
   if (File && CB.enteredMainFile) {
     CXIdxClientFile idxFile =
       CB.enteredMainFile(ClientData,
-                         static_cast<CXFile>(const_cast<FileEntry *>(File)), 0);
+                         static_cast<CXFile>(const_cast<FileEntry *>(File)),
+                         nullptr);
     FileMap[File] = idxFile;
   }
 }
@@ -268,7 +265,6 @@
   Module *Mod = ImportD->getImportedModule();
   if (!Mod)
     return;
-  std::string ModuleName = Mod->getFullModuleName();
 
   CXIdxImportedASTFileInfo Info = {
                                     static_cast<CXFile>(
@@ -288,7 +284,7 @@
   CXIdxImportedASTFileInfo Info = {
                                     static_cast<CXFile>(
                                       const_cast<FileEntry *>(File)),
-                                    /*module=*/NULL,
+                                    /*module=*/nullptr,
                                     getIndexLoc(SourceLocation()),
                                     /*isImplicit=*/false
                                   };
@@ -297,9 +293,9 @@
 }
 
 void IndexingContext::startedTranslationUnit() {
-  CXIdxClientContainer idxCont = 0;
+  CXIdxClientContainer idxCont = nullptr;
   if (CB.startedTranslationUnit)
-    idxCont = CB.startedTranslationUnit(ClientData, 0);
+    idxCont = CB.startedTranslationUnit(ClientData, nullptr);
   addContainerInMap(Ctx->getTranslationUnitDecl(), idxCont);
 }
 
@@ -307,7 +303,7 @@
   if (!CB.diagnostic)
     return;
 
-  CB.diagnostic(ClientData, CXDiagSet, 0);
+  CB.diagnostic(ClientData, CXDiagSet, nullptr);
 }
 
 bool IndexingContext::handleDecl(const NamedDecl *D,
@@ -469,7 +465,8 @@
   ObjCInterfaceDeclInfo InterInfo(D);
   InterInfo.ObjCProtoListInfo = ProtInfo.getListInfo();
   InterInfo.ObjCInterDeclInfo.containerInfo = &InterInfo.ObjCContDeclInfo;
-  InterInfo.ObjCInterDeclInfo.superInfo = D->getSuperClass() ? &BaseClass : 0;
+  InterInfo.ObjCInterDeclInfo.superInfo = D->getSuperClass() ? &BaseClass
+                                                             : nullptr;
   InterInfo.ObjCInterDeclInfo.protocols = &InterInfo.ObjCProtoListInfo;
 
   return handleObjCContainer(D, D->getLocation(), getCursor(D), InterInfo);
@@ -534,7 +531,7 @@
     CatDInfo.ObjCCatDeclInfo.classCursor =
         MakeCursorObjCClassRef(IFaceD, ClassLoc, CXTU);
   } else {
-    CatDInfo.ObjCCatDeclInfo.objcClass = 0;
+    CatDInfo.ObjCCatDeclInfo.objcClass = nullptr;
     CatDInfo.ObjCCatDeclInfo.classCursor = clang_getNullCursor();
   }
   CatDInfo.ObjCCatDeclInfo.classLoc = getIndexLoc(ClassLoc);
@@ -564,11 +561,11 @@
     CatDInfo.ObjCCatDeclInfo.classCursor =
         MakeCursorObjCClassRef(IFaceD, ClassLoc, CXTU);
   } else {
-    CatDInfo.ObjCCatDeclInfo.objcClass = 0;
+    CatDInfo.ObjCCatDeclInfo.objcClass = nullptr;
     CatDInfo.ObjCCatDeclInfo.classCursor = clang_getNullCursor();
   }
   CatDInfo.ObjCCatDeclInfo.classLoc = getIndexLoc(ClassLoc);
-  CatDInfo.ObjCCatDeclInfo.protocols = 0;
+  CatDInfo.ObjCCatDeclInfo.protocols = nullptr;
 
   return handleObjCContainer(D, CategoryLoc, getCursor(D), CatDInfo);
 }
@@ -592,7 +589,8 @@
 bool IndexingContext::handleSynthesizedObjCProperty(
                                                 const ObjCPropertyImplDecl *D) {
   ObjCPropertyDecl *PD = D->getPropertyDecl();
-  return handleReference(PD, D->getLocation(), getCursor(D), 0, D->getDeclContext());
+  return handleReference(PD, D->getLocation(), getCursor(D), nullptr,
+                         D->getDeclContext());
 }
 
 bool IndexingContext::handleSynthesizedObjCMethod(const ObjCMethodDecl *D,
@@ -616,13 +614,13 @@
     getEntityInfo(Getter, GetterEntity, SA);
     DInfo.ObjCPropDeclInfo.getter = &GetterEntity;
   } else {
-    DInfo.ObjCPropDeclInfo.getter = 0;
+    DInfo.ObjCPropDeclInfo.getter = nullptr;
   }
   if (ObjCMethodDecl *Setter = D->getSetterMethodDecl()) {
     getEntityInfo(Setter, SetterEntity, SA);
     DInfo.ObjCPropDeclInfo.setter = &SetterEntity;
   } else {
-    DInfo.ObjCPropDeclInfo.setter = 0;
+    DInfo.ObjCPropDeclInfo.setter = nullptr;
   }
 
   return handleDecl(D, D->getLocation(), getCursor(D), DInfo);
@@ -705,7 +703,7 @@
                               Cursor,
                               getIndexLoc(Loc),
                               &RefEntity,
-                              Parent ? &ParentEntity : 0,
+                              Parent ? &ParentEntity : nullptr,
                               &Container };
   CB.indexEntityReference(ClientData, &Info);
   return true;
@@ -717,7 +715,7 @@
   SourceManager &SM = Ctx->getSourceManager();
   SourceLocation FileLoc = SM.getFileLoc(Loc);
   FileID FID = SM.getFileID(FileLoc);
-  return SM.getFileEntryForID(FID) == 0;
+  return SM.getFileEntryForID(FID) == nullptr;
 }
 
 void IndexingContext::addContainerInMap(const DeclContext *DC,
@@ -741,10 +739,10 @@
 
 CXIdxClientEntity IndexingContext::getClientEntity(const Decl *D) const {
   if (!D)
-    return 0;
+    return nullptr;
   EntityMapTy::const_iterator I = EntityMap.find(D);
   if (I == EntityMap.end())
-    return 0;
+    return nullptr;
   return I->second;
 }
 
@@ -803,9 +801,9 @@
   const FileEntry *FE = SM.getFileEntryForID(FID);
   if (!FE)
     return true;
-  RefFileOccurence RefOccur(FE, D);
-  std::pair<llvm::DenseSet<RefFileOccurence>::iterator, bool>
-  res = RefFileOccurences.insert(RefOccur);
+  RefFileOccurrence RefOccur(FE, D);
+  std::pair<llvm::DenseSet<RefFileOccurrence>::iterator, bool>
+  res = RefFileOccurrences.insert(RefOccur);
   if (!res.second)
     return true; // already in map.
 
@@ -853,28 +851,28 @@
 CXIdxClientContainer
 IndexingContext::getClientContainerForDC(const DeclContext *DC) const {
   if (!DC)
-    return 0;
+    return nullptr;
 
   ContainerMapTy::const_iterator I = ContainerMap.find(DC);
   if (I == ContainerMap.end())
-    return 0;
+    return nullptr;
 
   return I->second;
 }
 
 CXIdxClientFile IndexingContext::getIndexFile(const FileEntry *File) {
   if (!File)
-    return 0;
+    return nullptr;
 
   FileMapTy::iterator FI = FileMap.find(File);
   if (FI != FileMap.end())
     return FI->second;
 
-  return 0;
+  return nullptr;
 }
 
 CXIdxLoc IndexingContext::getIndexLoc(SourceLocation Loc) const {
-  CXIdxLoc idxLoc =  { {0, 0}, 0 };
+  CXIdxLoc idxLoc =  { {nullptr, nullptr}, 0 };
   if (Loc.isInvalid())
     return idxLoc;
 
@@ -1098,7 +1096,7 @@
     EntityInfo.name = SA.toCStr(II->getName());
 
   } else if (isa<TagDecl>(D) || isa<FieldDecl>(D) || isa<NamespaceDecl>(D)) {
-    EntityInfo.name = 0; // anonymous tag/field/namespace.
+    EntityInfo.name = nullptr; // anonymous tag/field/namespace.
 
   } else {
     SmallString<256> StrBuf;
@@ -1113,7 +1111,7 @@
     SmallString<512> StrBuf;
     bool Ignore = getDeclCursorUSR(D, StrBuf);
     if (Ignore) {
-      EntityInfo.USR = 0;
+      EntityInfo.USR = nullptr;
     } else {
       EntityInfo.USR = SA.copyCStr(StrBuf.str());
     }
diff --git a/tools/libclang/IndexingContext.h b/tools/libclang/IndexingContext.h
index 3437d55..c3851cd 100644
--- a/tools/libclang/IndexingContext.h
+++ b/tools/libclang/IndexingContext.h
@@ -49,8 +49,8 @@
   IntrusiveRefCntPtr<AttrListInfo> AttrList;
 
   EntityInfo() {
-    name = USR = 0;
-    attributes = 0;
+    name = USR = nullptr;
+    attributes = nullptr;
     numAttributes = 0;
   }
 };
@@ -86,9 +86,9 @@
     this->isRedeclaration = isRedeclaration;
     this->isDefinition = isDefinition;
     this->isContainer = isContainer;
-    attributes = 0;
+    attributes = nullptr;
     numAttributes = 0;
-    declAsContainer = semanticContainer = lexicalContainer = 0;
+    declAsContainer = semanticContainer = lexicalContainer = nullptr;
     flags = 0;
   }
   DeclInfo(DInfoKind K,
@@ -97,9 +97,9 @@
     this->isRedeclaration = isRedeclaration;
     this->isDefinition = isDefinition;
     this->isContainer = isContainer;
-    attributes = 0;
+    attributes = nullptr;
     numAttributes = 0;
-    declAsContainer = semanticContainer = lexicalContainer = 0;
+    declAsContainer = semanticContainer = lexicalContainer = nullptr;
     flags = 0;
   }
 };
@@ -145,7 +145,7 @@
   ObjCInterfaceDeclInfo(const ObjCInterfaceDecl *D)
     : ObjCContainerDeclInfo(Info_ObjCInterface,
                             /*isForwardRef=*/false,
-                          /*isRedeclaration=*/D->getPreviousDecl() != 0,
+                            /*isRedeclaration=*/D->getPreviousDecl() != nullptr,
                             /*isImplementation=*/false) { }
 
   static bool classof(const DeclInfo *D) {
@@ -224,7 +224,7 @@
   IBOutletCollectionInfo(CXCursor C, CXIdxLoc Loc, const Attr *A) :
     AttrInfo(CXIdxAttr_IBOutletCollection, C, Loc, A) {
     assert(C.kind == CXCursor_IBOutletCollectionAttr);
-    IBCollInfo.objcClass = 0;
+    IBCollInfo.objcClass = nullptr;
   }
 
   IBOutletCollectionInfo(const IBOutletCollectionInfo &other);
@@ -252,7 +252,7 @@
 
   const CXIdxAttrInfo *const *getAttrs() const {
     if (CXAttrs.empty())
-      return 0;
+      return nullptr;
     return CXAttrs.data();
   }
   unsigned getNumAttrs() const { return (unsigned)CXAttrs.size(); }
@@ -286,8 +286,8 @@
   ContainerMapTy ContainerMap;
   EntityMapTy EntityMap;
 
-  typedef std::pair<const FileEntry *, const Decl *> RefFileOccurence;
-  llvm::DenseSet<RefFileOccurence> RefFileOccurences;
+  typedef std::pair<const FileEntry *, const Decl *> RefFileOccurrence;
+  llvm::DenseSet<RefFileOccurrence> RefFileOccurrences;
 
   std::deque<DeclGroupRef> TUDeclsInObjCContainer;
   
@@ -333,9 +333,9 @@
 public:
   IndexingContext(CXClientData clientData, IndexerCallbacks &indexCallbacks,
                   unsigned indexOptions, CXTranslationUnit cxTU)
-    : Ctx(0), ClientData(clientData), CB(indexCallbacks),
+    : Ctx(nullptr), ClientData(clientData), CB(indexCallbacks),
       IndexOptions(indexOptions), CXTU(cxTU),
-      StrScratch(/*size=*/1024), StrAdapterCount(0) { }
+      StrScratch(), StrAdapterCount(0) { }
 
   ASTContext &getASTContext() const { return *Ctx; }
 
@@ -376,19 +376,19 @@
   void indexTagDecl(const TagDecl *D);
 
   void indexTypeSourceInfo(TypeSourceInfo *TInfo, const NamedDecl *Parent,
-                           const DeclContext *DC = 0);
+                           const DeclContext *DC = nullptr);
 
   void indexTypeLoc(TypeLoc TL, const NamedDecl *Parent,
-                    const DeclContext *DC = 0);
+                    const DeclContext *DC = nullptr);
 
   void indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
                                    const NamedDecl *Parent,
-                                   const DeclContext *DC = 0);
+                                   const DeclContext *DC = nullptr);
 
   void indexDeclContext(const DeclContext *DC);
   
   void indexBody(const Stmt *S, const NamedDecl *Parent,
-                 const DeclContext *DC = 0);
+                 const DeclContext *DC = nullptr);
 
   void handleDiagnosticSet(CXDiagnosticSet CXDiagSet);
 
@@ -431,13 +431,13 @@
   bool handleReference(const NamedDecl *D, SourceLocation Loc, CXCursor Cursor,
                        const NamedDecl *Parent,
                        const DeclContext *DC,
-                       const Expr *E = 0,
+                       const Expr *E = nullptr,
                        CXIdxEntityRefKind Kind = CXIdxEntityRef_Direct);
 
   bool handleReference(const NamedDecl *D, SourceLocation Loc,
                        const NamedDecl *Parent,
                        const DeclContext *DC,
-                       const Expr *E = 0,
+                       const Expr *E = nullptr,
                        CXIdxEntityRefKind Kind = CXIdxEntityRef_Direct);
 
   bool isNotFromSourceFile(SourceLocation Loc) const;
@@ -465,7 +465,7 @@
   bool handleDecl(const NamedDecl *D,
                   SourceLocation Loc, CXCursor Cursor,
                   DeclInfo &DInfo,
-                  const DeclContext *LexicalDC = 0);
+                  const DeclContext *LexicalDC = nullptr);
 
   bool handleObjCContainer(const ObjCContainerDecl *D,
                            SourceLocation Loc, CXCursor Cursor,
diff --git a/tools/libclang/Makefile b/tools/libclang/Makefile
index 43ecbd1..db3d4f8 100644
--- a/tools/libclang/Makefile
+++ b/tools/libclang/Makefile
@@ -17,14 +17,18 @@
 
 include $(CLANG_LEVEL)/../../Makefile.config
 LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option
-USEDLIBS = clangIndex.a clangFrontend.a clangDriver.a \
+USEDLIBS = clangIndex.a clangARCMigrate.a \
+	   clangRewriteFrontend.a \
+	   clangFormat.a \
 	   clangTooling.a \
+	   clangFrontend.a clangDriver.a \
 	   clangSerialization.a \
 	   clangParse.a clangSema.a \
-	   clangARCMigrate.a clangRewriteFrontend.a clangRewriteCore.a \
+	   clangStaticAnalyzerCheckers.a clangStaticAnalyzerCore.a \
+	   clangRewrite.a \
 	   clangAnalysis.a clangEdit.a \
+	   clangASTMatchers.a \
 	   clangAST.a clangLex.a clangBasic.a \
-	   clangFormat.a
 
 include $(CLANG_LEVEL)/Makefile
 
@@ -33,6 +37,10 @@
         LLVMLibsOptions += -Wl,-soname,lib$(LIBRARYNAME)$(SHLIBEXT)
 endif
 
+ifeq ($(ENABLE_CLANG_ARCMT),1)
+  CXX.Flags += -DCLANG_ENABLE_ARCMT
+endif
+
 ##===----------------------------------------------------------------------===##
 # FIXME: This is copied from the 'lto' makefile.  Should we share this?
 ##===----------------------------------------------------------------------===##
@@ -46,16 +54,6 @@
                            -Wl,$(LLVM_SUBMIT_VERSION).$(LLVM_SUBMIT_SUBVERSION)
     endif
 
-    # Extra options to override libtool defaults.
-    LLVMLibsOptions += -Wl,-dead_strip
-
-    # Mac OS X 10.4 and earlier tools do not allow a second -install_name on command line
-    DARWIN_VERS := $(shell echo $(TARGET_TRIPLE) | sed 's/.*darwin\([0-9]*\).*/\1/')
-    ifneq ($(DARWIN_VERS),8)
-       LLVMLibsOptions += -Wl,-install_name \
-                          -Wl,"@rpath/lib$(LIBRARYNAME)$(SHLIBEXT)"
-    endif
-
     # If we're doing an Apple-style build, add the LTO object path.
     ifeq ($(RC_XBS),YES)
        TempFile        := $(shell mkdir -p ${OBJROOT}/dSYMs ; mktemp ${OBJROOT}/dSYMs/clang-lto.XXXXXX)
diff --git a/tools/libclang/RecursiveASTVisitor.h b/tools/libclang/RecursiveASTVisitor.h
deleted file mode 100644
index 3ad5acb..0000000
--- a/tools/libclang/RecursiveASTVisitor.h
+++ /dev/null
@@ -1,2384 +0,0 @@
-//===--- RecursiveASTVisitor.h - Recursive AST Visitor ----------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-//  This file defines the RecursiveASTVisitor interface, which recursively
-//  traverses the entire AST.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_LIBCLANG_RECURSIVEASTVISITOR_H
-#define LLVM_CLANG_LIBCLANG_RECURSIVEASTVISITOR_H
-
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclFriend.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/DeclOpenMP.h"
-#include "clang/AST/DeclTemplate.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/ExprObjC.h"
-#include "clang/AST/NestedNameSpecifier.h"
-#include "clang/AST/Stmt.h"
-#include "clang/AST/StmtCXX.h"
-#include "clang/AST/StmtObjC.h"
-#include "clang/AST/StmtOpenMP.h"
-#include "clang/AST/TemplateBase.h"
-#include "clang/AST/TemplateName.h"
-#include "clang/AST/Type.h"
-#include "clang/AST/TypeLoc.h"
-
-// The following three macros are used for meta programming.  The code
-// using them is responsible for defining macro OPERATOR().
-
-// All unary operators.
-#define UNARYOP_LIST()                          \
-  OPERATOR(PostInc)   OPERATOR(PostDec)         \
-  OPERATOR(PreInc)    OPERATOR(PreDec)          \
-  OPERATOR(AddrOf)    OPERATOR(Deref)           \
-  OPERATOR(Plus)      OPERATOR(Minus)           \
-  OPERATOR(Not)       OPERATOR(LNot)            \
-  OPERATOR(Real)      OPERATOR(Imag)            \
-  OPERATOR(Extension)
-
-// All binary operators (excluding compound assign operators).
-#define BINOP_LIST() \
-  OPERATOR(PtrMemD)              OPERATOR(PtrMemI)    \
-  OPERATOR(Mul)   OPERATOR(Div)  OPERATOR(Rem)        \
-  OPERATOR(Add)   OPERATOR(Sub)  OPERATOR(Shl)        \
-  OPERATOR(Shr)                                       \
-                                                      \
-  OPERATOR(LT)    OPERATOR(GT)   OPERATOR(LE)         \
-  OPERATOR(GE)    OPERATOR(EQ)   OPERATOR(NE)         \
-  OPERATOR(And)   OPERATOR(Xor)  OPERATOR(Or)         \
-  OPERATOR(LAnd)  OPERATOR(LOr)                       \
-                                                      \
-  OPERATOR(Assign)                                    \
-  OPERATOR(Comma)
-
-// All compound assign operators.
-#define CAO_LIST()                                                      \
-  OPERATOR(Mul) OPERATOR(Div) OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) \
-  OPERATOR(Shl) OPERATOR(Shr) OPERATOR(And) OPERATOR(Or)  OPERATOR(Xor)
-
-namespace clang {
-namespace cxindex {
-
-// A helper macro to implement short-circuiting when recursing.  It
-// invokes CALL_EXPR, which must be a method call, on the derived
-// object (s.t. a user of RecursiveASTVisitor can override the method
-// in CALL_EXPR).
-#define TRY_TO(CALL_EXPR) \
-  do { if (!getDerived().CALL_EXPR) return false; } while (0)
-
-/// \brief A class that does preorder depth-first traversal on the
-/// entire Clang AST and visits each node.
-///
-/// This class performs three distinct tasks:
-///   1. traverse the AST (i.e. go to each node);
-///   2. at a given node, walk up the class hierarchy, starting from
-///      the node's dynamic type, until the top-most class (e.g. Stmt,
-///      Decl, or Type) is reached.
-///   3. given a (node, class) combination, where 'class' is some base
-///      class of the dynamic type of 'node', call a user-overridable
-///      function to actually visit the node.
-///
-/// These tasks are done by three groups of methods, respectively:
-///   1. TraverseDecl(Decl *x) does task #1.  It is the entry point
-///      for traversing an AST rooted at x.  This method simply
-///      dispatches (i.e. forwards) to TraverseFoo(Foo *x) where Foo
-///      is the dynamic type of *x, which calls WalkUpFromFoo(x) and
-///      then recursively visits the child nodes of x.
-///      TraverseStmt(Stmt *x) and TraverseType(QualType x) work
-///      similarly.
-///   2. WalkUpFromFoo(Foo *x) does task #2.  It does not try to visit
-///      any child node of x.  Instead, it first calls WalkUpFromBar(x)
-///      where Bar is the direct parent class of Foo (unless Foo has
-///      no parent), and then calls VisitFoo(x) (see the next list item).
-///   3. VisitFoo(Foo *x) does task #3.
-///
-/// These three method groups are tiered (Traverse* > WalkUpFrom* >
-/// Visit*).  A method (e.g. Traverse*) may call methods from the same
-/// tier (e.g. other Traverse*) or one tier lower (e.g. WalkUpFrom*).
-/// It may not call methods from a higher tier.
-///
-/// Note that since WalkUpFromFoo() calls WalkUpFromBar() (where Bar
-/// is Foo's super class) before calling VisitFoo(), the result is
-/// that the Visit*() methods for a given node are called in the
-/// top-down order (e.g. for a node of type NamedDecl, the order will
-/// be VisitDecl(), VisitNamedDecl(), and then VisitNamespaceDecl()).
-///
-/// This scheme guarantees that all Visit*() calls for the same AST
-/// node are grouped together.  In other words, Visit*() methods for
-/// different nodes are never interleaved.
-///
-/// Stmts are traversed internally using a data queue to avoid a stack overflow
-/// with hugely nested ASTs.
-///
-/// Clients of this visitor should subclass the visitor (providing
-/// themselves as the template argument, using the curiously recurring
-/// template pattern) and override any of the Traverse*, WalkUpFrom*,
-/// and Visit* methods for declarations, types, statements,
-/// expressions, or other AST nodes where the visitor should customize
-/// behavior.  Most users only need to override Visit*.  Advanced
-/// users may override Traverse* and WalkUpFrom* to implement custom
-/// traversal strategies.  Returning false from one of these overridden
-/// functions will abort the entire traversal.
-///
-/// By default, this visitor tries to visit every part of the explicit
-/// source code exactly once.  The default policy towards templates
-/// is to descend into the 'pattern' class or function body, not any
-/// explicit or implicit instantiations.  Explicit specializations
-/// are still visited, and the patterns of partial specializations
-/// are visited separately.  This behavior can be changed by
-/// overriding shouldVisitTemplateInstantiations() in the derived class
-/// to return true, in which case all known implicit and explicit
-/// instantiations will be visited at the same time as the pattern
-/// from which they were produced.
-template<typename Derived>
-class RecursiveASTVisitor {
-public:
-  /// \brief Return a reference to the derived class.
-  Derived &getDerived() { return *static_cast<Derived*>(this); }
-
-  /// \brief Return whether this visitor should recurse into
-  /// template instantiations.
-  bool shouldVisitTemplateInstantiations() const { return false; }
-
-  /// \brief Return whether this visitor should recurse into the types of
-  /// TypeLocs.
-  bool shouldWalkTypesOfTypeLocs() const { return true; }
-
-  /// \brief Recursively visit a statement or expression, by
-  /// dispatching to Traverse*() based on the argument's dynamic type.
-  ///
-  /// \returns false if the visitation was terminated early, true
-  /// otherwise (including when the argument is NULL).
-  bool TraverseStmt(Stmt *S);
-
-  /// \brief Recursively visit a type, by dispatching to
-  /// Traverse*Type() based on the argument's getTypeClass() property.
-  ///
-  /// \returns false if the visitation was terminated early, true
-  /// otherwise (including when the argument is a Null type).
-  bool TraverseType(QualType T);
-
-  /// \brief Recursively visit a type with location, by dispatching to
-  /// Traverse*TypeLoc() based on the argument type's getTypeClass() property.
-  ///
-  /// \returns false if the visitation was terminated early, true
-  /// otherwise (including when the argument is a Null type location).
-  bool TraverseTypeLoc(TypeLoc TL);
-
-  /// \brief Recursively visit a declaration, by dispatching to
-  /// Traverse*Decl() based on the argument's dynamic type.
-  ///
-  /// \returns false if the visitation was terminated early, true
-  /// otherwise (including when the argument is NULL).
-  bool TraverseDecl(Decl *D);
-
-  /// \brief Recursively visit a C++ nested-name-specifier.
-  ///
-  /// \returns false if the visitation was terminated early, true otherwise.
-  bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS);
-
-  /// \brief Recursively visit a C++ nested-name-specifier with location
-  /// information.
-  ///
-  /// \returns false if the visitation was terminated early, true otherwise.
-  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
-
-  /// \brief Recursively visit a name with its location information.
-  ///
-  /// \returns false if the visitation was terminated early, true otherwise.
-  bool TraverseDeclarationNameInfo(DeclarationNameInfo NameInfo);
-
-  /// \brief Recursively visit a template name and dispatch to the
-  /// appropriate method.
-  ///
-  /// \returns false if the visitation was terminated early, true otherwise.
-  bool TraverseTemplateName(TemplateName Template);
-
-  /// \brief Recursively visit a template argument and dispatch to the
-  /// appropriate method for the argument type.
-  ///
-  /// \returns false if the visitation was terminated early, true otherwise.
-  // FIXME: migrate callers to TemplateArgumentLoc instead.
-  bool TraverseTemplateArgument(const TemplateArgument &Arg);
-
-  /// \brief Recursively visit a template argument location and dispatch to the
-  /// appropriate method for the argument type.
-  ///
-  /// \returns false if the visitation was terminated early, true otherwise.
-  bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc);
-
-  /// \brief Recursively visit a set of template arguments.
-  /// This can be overridden by a subclass, but it's not expected that
-  /// will be needed -- this visitor always dispatches to another.
-  ///
-  /// \returns false if the visitation was terminated early, true otherwise.
-  // FIXME: take a TemplateArgumentLoc* (or TemplateArgumentListInfo) instead.
-  bool TraverseTemplateArguments(const TemplateArgument *Args,
-                                 unsigned NumArgs);
-
-  /// \brief Recursively visit a constructor initializer.  This
-  /// automatically dispatches to another visitor for the initializer
-  /// expression, but not for the name of the initializer, so may
-  /// be overridden for clients that need access to the name.
-  ///
-  /// \returns false if the visitation was terminated early, true otherwise.
-  bool TraverseConstructorInitializer(CXXCtorInitializer *Init);
-
-  /// \brief Recursively visit a lambda capture.
-  ///
-  /// \returns false if the visitation was terminated early, true otherwise.
-  bool TraverseLambdaCapture(LambdaExpr::Capture C);
-  
-  // ---- Methods on Stmts ----
-
-  // Declare Traverse*() for all concrete Stmt classes.
-#define ABSTRACT_STMT(STMT)
-#define STMT(CLASS, PARENT)                                     \
-  bool Traverse##CLASS(CLASS *S);
-#include "clang/AST/StmtNodes.inc"
-  // The above header #undefs ABSTRACT_STMT and STMT upon exit.
-
-  // Define WalkUpFrom*() and empty Visit*() for all Stmt classes.
-  bool WalkUpFromStmt(Stmt *S) { return getDerived().VisitStmt(S); }
-  bool VisitStmt(Stmt *S) { return true; }
-#define STMT(CLASS, PARENT)                                     \
-  bool WalkUpFrom##CLASS(CLASS *S) {                            \
-    TRY_TO(WalkUpFrom##PARENT(S));                              \
-    TRY_TO(Visit##CLASS(S));                                    \
-    return true;                                                \
-  }                                                             \
-  bool Visit##CLASS(CLASS *S) { return true; }
-#include "clang/AST/StmtNodes.inc"
-
-  // Define Traverse*(), WalkUpFrom*(), and Visit*() for unary
-  // operator methods.  Unary operators are not classes in themselves
-  // (they're all opcodes in UnaryOperator) but do have visitors.
-#define OPERATOR(NAME)                                           \
-  bool TraverseUnary##NAME(UnaryOperator *S) {                  \
-    TRY_TO(WalkUpFromUnary##NAME(S));                           \
-    StmtQueueAction StmtQueue(*this);                           \
-    StmtQueue.queue(S->getSubExpr());                           \
-    return true;                                                \
-  }                                                             \
-  bool WalkUpFromUnary##NAME(UnaryOperator *S) {                \
-    TRY_TO(WalkUpFromUnaryOperator(S));                         \
-    TRY_TO(VisitUnary##NAME(S));                                \
-    return true;                                                \
-  }                                                             \
-  bool VisitUnary##NAME(UnaryOperator *S) { return true; }
-
-  UNARYOP_LIST()
-#undef OPERATOR
-
-  // Define Traverse*(), WalkUpFrom*(), and Visit*() for binary
-  // operator methods.  Binary operators are not classes in themselves
-  // (they're all opcodes in BinaryOperator) but do have visitors.
-#define GENERAL_BINOP_FALLBACK(NAME, BINOP_TYPE)                \
-  bool TraverseBin##NAME(BINOP_TYPE *S) {                       \
-    TRY_TO(WalkUpFromBin##NAME(S));                             \
-    StmtQueueAction StmtQueue(*this);                           \
-    StmtQueue.queue(S->getLHS());                               \
-    StmtQueue.queue(S->getRHS());                               \
-    return true;                                                \
-  }                                                             \
-  bool WalkUpFromBin##NAME(BINOP_TYPE *S) {                     \
-    TRY_TO(WalkUpFrom##BINOP_TYPE(S));                          \
-    TRY_TO(VisitBin##NAME(S));                                  \
-    return true;                                                \
-  }                                                             \
-  bool VisitBin##NAME(BINOP_TYPE *S) { return true; }
-
-#define OPERATOR(NAME) GENERAL_BINOP_FALLBACK(NAME, BinaryOperator)
-  BINOP_LIST()
-#undef OPERATOR
-
-  // Define Traverse*(), WalkUpFrom*(), and Visit*() for compound
-  // assignment methods.  Compound assignment operators are not
-  // classes in themselves (they're all opcodes in
-  // CompoundAssignOperator) but do have visitors.
-#define OPERATOR(NAME) \
-  GENERAL_BINOP_FALLBACK(NAME##Assign, CompoundAssignOperator)
-
-  CAO_LIST()
-#undef OPERATOR
-#undef GENERAL_BINOP_FALLBACK
-
-  // ---- Methods on Types ----
-  // FIXME: revamp to take TypeLoc's rather than Types.
-
-  // Declare Traverse*() for all concrete Type classes.
-#define ABSTRACT_TYPE(CLASS, BASE)
-#define TYPE(CLASS, BASE) \
-  bool Traverse##CLASS##Type(CLASS##Type *T);
-#include "clang/AST/TypeNodes.def"
-  // The above header #undefs ABSTRACT_TYPE and TYPE upon exit.
-
-  // Define WalkUpFrom*() and empty Visit*() for all Type classes.
-  bool WalkUpFromType(Type *T) { return getDerived().VisitType(T); }
-  bool VisitType(Type *T) { return true; }
-#define TYPE(CLASS, BASE)                                       \
-  bool WalkUpFrom##CLASS##Type(CLASS##Type *T) {                \
-    TRY_TO(WalkUpFrom##BASE(T));                                \
-    TRY_TO(Visit##CLASS##Type(T));                              \
-    return true;                                                \
-  }                                                             \
-  bool Visit##CLASS##Type(CLASS##Type *T) { return true; }
-#include "clang/AST/TypeNodes.def"
-
-  // ---- Methods on TypeLocs ----
-  // FIXME: this currently just calls the matching Type methods
-
-  // Declare Traverse*() for all concrete Type classes.
-#define ABSTRACT_TYPELOC(CLASS, BASE)
-#define TYPELOC(CLASS, BASE) \
-  bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL);
-#include "clang/AST/TypeLocNodes.def"
-  // The above header #undefs ABSTRACT_TYPELOC and TYPELOC upon exit.
-
-  // Define WalkUpFrom*() and empty Visit*() for all TypeLoc classes.
-  bool WalkUpFromTypeLoc(TypeLoc TL) { return getDerived().VisitTypeLoc(TL); }
-  bool VisitTypeLoc(TypeLoc TL) { return true; }
-
-  // QualifiedTypeLoc and UnqualTypeLoc are not declared in
-  // TypeNodes.def and thus need to be handled specially.
-  bool WalkUpFromQualifiedTypeLoc(QualifiedTypeLoc TL) {
-    return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc());
-  }
-  bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { return true; }
-  bool WalkUpFromUnqualTypeLoc(UnqualTypeLoc TL) {
-    return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc());
-  }
-  bool VisitUnqualTypeLoc(UnqualTypeLoc TL) { return true; }
-
-  // Note that BASE includes trailing 'Type' which CLASS doesn't.
-#define TYPE(CLASS, BASE)                                       \
-  bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL) {          \
-    TRY_TO(WalkUpFrom##BASE##Loc(TL));                          \
-    TRY_TO(Visit##CLASS##TypeLoc(TL));                          \
-    return true;                                                \
-  }                                                             \
-  bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { return true; }
-#include "clang/AST/TypeNodes.def"
-
-  // ---- Methods on Decls ----
-
-  // Declare Traverse*() for all concrete Decl classes.
-#define ABSTRACT_DECL(DECL)
-#define DECL(CLASS, BASE) \
-  bool Traverse##CLASS##Decl(CLASS##Decl *D);
-#include "clang/AST/DeclNodes.inc"
-  // The above header #undefs ABSTRACT_DECL and DECL upon exit.
-
-  // Define WalkUpFrom*() and empty Visit*() for all Decl classes.
-  bool WalkUpFromDecl(Decl *D) { return getDerived().VisitDecl(D); }
-  bool VisitDecl(Decl *D) { return true; }
-#define DECL(CLASS, BASE)                                       \
-  bool WalkUpFrom##CLASS##Decl(CLASS##Decl *D) {                \
-    TRY_TO(WalkUpFrom##BASE(D));                                \
-    TRY_TO(Visit##CLASS##Decl(D));                              \
-    return true;                                                \
-  }                                                             \
-  bool Visit##CLASS##Decl(CLASS##Decl *D) { return true; }
-#include "clang/AST/DeclNodes.inc"
-
-private:
-  // These are helper methods used by more than one Traverse* method.
-  bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL);
-  bool TraverseClassInstantiations(ClassTemplateDecl *D);
-  bool TraverseVariableInstantiations(VarTemplateDecl *D);
-  bool TraverseFunctionInstantiations(FunctionTemplateDecl *D) ;
-  bool TraverseTemplateArgumentLocsHelper(const TemplateArgumentLoc *TAL,
-                                          unsigned Count);
-  bool TraverseArrayTypeLocHelper(ArrayTypeLoc TL);
-  bool TraverseRecordHelper(RecordDecl *D);
-  bool TraverseCXXRecordHelper(CXXRecordDecl *D);
-  bool TraverseDeclaratorHelper(DeclaratorDecl *D);
-  bool TraverseDeclContextHelper(DeclContext *DC);
-  bool TraverseFunctionHelper(FunctionDecl *D);
-  bool TraverseVarHelper(VarDecl *D);
-  bool TraverseOMPClause(OMPClause *C);
-#define OPENMP_CLAUSE(Name, Class)                                      \
-  bool Visit##Class(Class *C);
-#include "clang/Basic/OpenMPKinds.def"
-  /// \brief Process clauses with list of variables.
-  template <typename T>
-  void VisitOMPClauseList(T *Node);
-
-  typedef SmallVector<Stmt *, 16> StmtsTy;
-  typedef SmallVector<StmtsTy *, 4> QueuesTy;
-  
-  QueuesTy Queues;
-
-  class NewQueueRAII {
-    RecursiveASTVisitor &RAV;
-  public:
-    NewQueueRAII(StmtsTy &queue, RecursiveASTVisitor &RAV) : RAV(RAV) {
-      RAV.Queues.push_back(&queue);
-    }
-    ~NewQueueRAII() {
-      RAV.Queues.pop_back();
-    }
-  };
-
-  StmtsTy &getCurrentQueue() {
-    assert(!Queues.empty() && "base TraverseStmt was never called?");
-    return *Queues.back();
-  }
-
-public:
-  class StmtQueueAction {
-    StmtsTy &CurrQueue;
-  public:
-    explicit StmtQueueAction(RecursiveASTVisitor &RAV)
-      : CurrQueue(RAV.getCurrentQueue()) { }
-
-    void queue(Stmt *S) {
-      CurrQueue.push_back(S);
-    }
-  };
-};
-
-#define DISPATCH(NAME, CLASS, VAR) \
-  return getDerived().Traverse##NAME(static_cast<CLASS*>(VAR))
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S) {
-  if (!S)
-    return true;
-
-  StmtsTy Queue, StmtsToEnqueu;
-  Queue.push_back(S);
-  NewQueueRAII NQ(StmtsToEnqueu, *this);
-
-  while (!Queue.empty()) {
-    S = Queue.pop_back_val();
-    if (!S)
-      continue;
-
-    StmtsToEnqueu.clear();
-
-#define DISPATCH_STMT(NAME, CLASS, VAR) \
-    TRY_TO(Traverse##NAME(static_cast<CLASS*>(VAR))); break
-
-    // If we have a binary expr, dispatch to the subcode of the binop.  A smart
-    // optimizer (e.g. LLVM) will fold this comparison into the switch stmt
-    // below.
-    if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) {
-      switch (BinOp->getOpcode()) {
-#define OPERATOR(NAME) \
-      case BO_##NAME: DISPATCH_STMT(Bin##NAME, BinaryOperator, S);
-  
-      BINOP_LIST()
-#undef OPERATOR
-#undef BINOP_LIST
-  
-#define OPERATOR(NAME)                                          \
-      case BO_##NAME##Assign:                          \
-        DISPATCH_STMT(Bin##NAME##Assign, CompoundAssignOperator, S);
-  
-      CAO_LIST()
-#undef OPERATOR
-#undef CAO_LIST
-      }
-    } else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(S)) {
-      switch (UnOp->getOpcode()) {
-#define OPERATOR(NAME)                                                  \
-      case UO_##NAME: DISPATCH_STMT(Unary##NAME, UnaryOperator, S);
-  
-      UNARYOP_LIST()
-#undef OPERATOR
-#undef UNARYOP_LIST
-      }
-    } else {
-  
-      // Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt.
-      switch (S->getStmtClass()) {
-      case Stmt::NoStmtClass: break;
-#define ABSTRACT_STMT(STMT)
-#define STMT(CLASS, PARENT) \
-      case Stmt::CLASS##Class: DISPATCH_STMT(CLASS, CLASS, S);
-#include "clang/AST/StmtNodes.inc"
-      }
-    }
-
-    for (SmallVectorImpl<Stmt *>::reverse_iterator
-           RI = StmtsToEnqueu.rbegin(),
-           RE = StmtsToEnqueu.rend(); RI != RE; ++RI)
-      Queue.push_back(*RI);
-  }
-
-  return true;
-}
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseType(QualType T) {
-  if (T.isNull())
-    return true;
-
-  switch (T->getTypeClass()) {
-#define ABSTRACT_TYPE(CLASS, BASE)
-#define TYPE(CLASS, BASE) \
-  case Type::CLASS: DISPATCH(CLASS##Type, CLASS##Type, \
-                             const_cast<Type*>(T.getTypePtr()));
-#include "clang/AST/TypeNodes.def"
-  }
-
-  return true;
-}
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseTypeLoc(TypeLoc TL) {
-  if (TL.isNull())
-    return true;
-
-  switch (TL.getTypeLocClass()) {
-#define ABSTRACT_TYPELOC(CLASS, BASE)
-#define TYPELOC(CLASS, BASE) \
-  case TypeLoc::CLASS: \
-    return getDerived().Traverse##CLASS##TypeLoc(TL.castAs<CLASS##TypeLoc>());
-#include "clang/AST/TypeLocNodes.def"
-  }
-
-  return true;
-}
-
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseDecl(Decl *D) {
-  if (!D)
-    return true;
-
-  // As a syntax visitor, we want to ignore declarations for
-  // implicitly-defined declarations (ones not typed explicitly by the
-  // user).
-  if (D->isImplicit())
-    return true;
-
-  switch (D->getKind()) {
-#define ABSTRACT_DECL(DECL)
-#define DECL(CLASS, BASE) \
-  case Decl::CLASS: DISPATCH(CLASS##Decl, CLASS##Decl, D);
-#include "clang/AST/DeclNodes.inc"
- }
-
-  return true;
-}
-
-#undef DISPATCH
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifier(
-                                                    NestedNameSpecifier *NNS) {
-  if (!NNS)
-    return true;
-
-  if (NNS->getPrefix())
-    TRY_TO(TraverseNestedNameSpecifier(NNS->getPrefix()));
-
-  switch (NNS->getKind()) {
-  case NestedNameSpecifier::Identifier:
-  case NestedNameSpecifier::Namespace:
-  case NestedNameSpecifier::NamespaceAlias:
-  case NestedNameSpecifier::Global:
-    return true;
-
-  case NestedNameSpecifier::TypeSpec:
-  case NestedNameSpecifier::TypeSpecWithTemplate:
-    TRY_TO(TraverseType(QualType(NNS->getAsType(), 0)));
-  }
-
-  return true;
-}
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifierLoc(
-                                                  NestedNameSpecifierLoc NNS) {
-  if (!NNS)
-    return true;
-
-   if (NestedNameSpecifierLoc Prefix = NNS.getPrefix())
-     TRY_TO(TraverseNestedNameSpecifierLoc(Prefix));
-
-  switch (NNS.getNestedNameSpecifier()->getKind()) {
-  case NestedNameSpecifier::Identifier:
-  case NestedNameSpecifier::Namespace:
-  case NestedNameSpecifier::NamespaceAlias:
-  case NestedNameSpecifier::Global:
-    return true;
-
-  case NestedNameSpecifier::TypeSpec:
-  case NestedNameSpecifier::TypeSpecWithTemplate:
-    TRY_TO(TraverseTypeLoc(NNS.getTypeLoc()));
-    break;
-  }
-
-  return true;
-}
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseDeclarationNameInfo(
-                                                 DeclarationNameInfo NameInfo) {
-  switch (NameInfo.getName().getNameKind()) {
-  case DeclarationName::CXXConstructorName:
-  case DeclarationName::CXXDestructorName:
-  case DeclarationName::CXXConversionFunctionName:
-    if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo())
-      TRY_TO(TraverseTypeLoc(TSInfo->getTypeLoc()));
-
-    break;
-
-  case DeclarationName::Identifier:
-  case DeclarationName::ObjCZeroArgSelector:
-  case DeclarationName::ObjCOneArgSelector:
-  case DeclarationName::ObjCMultiArgSelector:
-  case DeclarationName::CXXOperatorName:
-  case DeclarationName::CXXLiteralOperatorName:
-  case DeclarationName::CXXUsingDirective:
-    break;
-  }
-
-  return true;
-}
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseTemplateName(TemplateName Template) {
-  if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
-    TRY_TO(TraverseNestedNameSpecifier(DTN->getQualifier()));
-  else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
-    TRY_TO(TraverseNestedNameSpecifier(QTN->getQualifier()));
-
-  return true;
-}
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseTemplateArgument(
-                                                const TemplateArgument &Arg) {
-  switch (Arg.getKind()) {
-  case TemplateArgument::Null:
-  case TemplateArgument::Declaration:
-  case TemplateArgument::Integral:
-  case TemplateArgument::NullPtr:
-    return true;
-
-  case TemplateArgument::Type:
-    return getDerived().TraverseType(Arg.getAsType());
-
-  case TemplateArgument::Template:
-  case TemplateArgument::TemplateExpansion:
-    return getDerived().TraverseTemplateName(
-                                          Arg.getAsTemplateOrTemplatePattern());
-
-  case TemplateArgument::Expression:
-    return getDerived().TraverseStmt(Arg.getAsExpr());
-
-  case TemplateArgument::Pack:
-    return getDerived().TraverseTemplateArguments(Arg.pack_begin(),
-                                                  Arg.pack_size());
-  }
-
-  return true;
-}
-
-// FIXME: no template name location?
-// FIXME: no source locations for a template argument pack?
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc(
-                                           const TemplateArgumentLoc &ArgLoc) {
-  const TemplateArgument &Arg = ArgLoc.getArgument();
-
-  switch (Arg.getKind()) {
-  case TemplateArgument::Null:
-  case TemplateArgument::Declaration:
-  case TemplateArgument::Integral:
-  case TemplateArgument::NullPtr:
-    return true;
-
-  case TemplateArgument::Type: {
-    // FIXME: how can TSI ever be NULL?
-    if (TypeSourceInfo *TSI = ArgLoc.getTypeSourceInfo())
-      return getDerived().TraverseTypeLoc(TSI->getTypeLoc());
-    else
-      return getDerived().TraverseType(Arg.getAsType());
-  }
-
-  case TemplateArgument::Template:
-  case TemplateArgument::TemplateExpansion:
-    if (ArgLoc.getTemplateQualifierLoc())
-      TRY_TO(getDerived().TraverseNestedNameSpecifierLoc(
-                                            ArgLoc.getTemplateQualifierLoc()));
-    return getDerived().TraverseTemplateName(
-                                         Arg.getAsTemplateOrTemplatePattern());
-
-  case TemplateArgument::Expression:
-    return getDerived().TraverseStmt(ArgLoc.getSourceExpression());
-
-  case TemplateArgument::Pack:
-    return getDerived().TraverseTemplateArguments(Arg.pack_begin(),
-                                                  Arg.pack_size());
-  }
-
-  return true;
-}
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseTemplateArguments(
-                                                  const TemplateArgument *Args,
-                                                            unsigned NumArgs) {
-  for (unsigned I = 0; I != NumArgs; ++I) {
-    TRY_TO(TraverseTemplateArgument(Args[I]));
-  }
-
-  return true;
-}
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseConstructorInitializer(
-                                                     CXXCtorInitializer *Init) {
-  if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo())
-    TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
-
-  if (Init->isWritten())
-    TRY_TO(TraverseStmt(Init->getInit()));
-  return true;
-}
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseLambdaCapture(LambdaExpr::Capture C){
-  return true;
-}
-
-// ----------------- Type traversal -----------------
-
-// This macro makes available a variable T, the passed-in type.
-#define DEF_TRAVERSE_TYPE(TYPE, CODE)                     \
-  template<typename Derived>                                           \
-  bool RecursiveASTVisitor<Derived>::Traverse##TYPE (TYPE *T) {        \
-    TRY_TO(WalkUpFrom##TYPE (T));                                      \
-    { CODE; }                                                          \
-    return true;                                                       \
-  }
-
-DEF_TRAVERSE_TYPE(BuiltinType, { })
-
-DEF_TRAVERSE_TYPE(ComplexType, {
-    TRY_TO(TraverseType(T->getElementType()));
-  })
-
-DEF_TRAVERSE_TYPE(PointerType, {
-    TRY_TO(TraverseType(T->getPointeeType()));
-  })
-
-DEF_TRAVERSE_TYPE(BlockPointerType, {
-    TRY_TO(TraverseType(T->getPointeeType()));
-  })
-
-DEF_TRAVERSE_TYPE(LValueReferenceType, {
-    TRY_TO(TraverseType(T->getPointeeType()));
-  })
-
-DEF_TRAVERSE_TYPE(RValueReferenceType, {
-    TRY_TO(TraverseType(T->getPointeeType()));
-  })
-
-DEF_TRAVERSE_TYPE(MemberPointerType, {
-    TRY_TO(TraverseType(QualType(T->getClass(), 0)));
-    TRY_TO(TraverseType(T->getPointeeType()));
-  })
-
-DEF_TRAVERSE_TYPE(DecayedType, {
-    TRY_TO(TraverseType(T->getOriginalType()));
-  })
-
-DEF_TRAVERSE_TYPE(ConstantArrayType, {
-    TRY_TO(TraverseType(T->getElementType()));
-  })
-
-DEF_TRAVERSE_TYPE(IncompleteArrayType, {
-    TRY_TO(TraverseType(T->getElementType()));
-  })
-
-DEF_TRAVERSE_TYPE(VariableArrayType, {
-    TRY_TO(TraverseType(T->getElementType()));
-    TRY_TO(TraverseStmt(T->getSizeExpr()));
-  })
-
-DEF_TRAVERSE_TYPE(DependentSizedArrayType, {
-    TRY_TO(TraverseType(T->getElementType()));
-    if (T->getSizeExpr())
-      TRY_TO(TraverseStmt(T->getSizeExpr()));
-  })
-
-DEF_TRAVERSE_TYPE(DependentSizedExtVectorType, {
-    if (T->getSizeExpr())
-      TRY_TO(TraverseStmt(T->getSizeExpr()));
-    TRY_TO(TraverseType(T->getElementType()));
-  })
-
-DEF_TRAVERSE_TYPE(VectorType, {
-    TRY_TO(TraverseType(T->getElementType()));
-  })
-
-DEF_TRAVERSE_TYPE(ExtVectorType, {
-    TRY_TO(TraverseType(T->getElementType()));
-  })
-
-DEF_TRAVERSE_TYPE(FunctionNoProtoType, {
-    TRY_TO(TraverseType(T->getResultType()));
-  })
-
-DEF_TRAVERSE_TYPE(FunctionProtoType, {
-    TRY_TO(TraverseType(T->getResultType()));
-
-    for (FunctionProtoType::arg_type_iterator A = T->arg_type_begin(),
-                                           AEnd = T->arg_type_end();
-         A != AEnd; ++A) {
-      TRY_TO(TraverseType(*A));
-    }
-
-    for (FunctionProtoType::exception_iterator E = T->exception_begin(),
-                                            EEnd = T->exception_end();
-         E != EEnd; ++E) {
-      TRY_TO(TraverseType(*E));
-    }
-  })
-
-DEF_TRAVERSE_TYPE(UnresolvedUsingType, { })
-DEF_TRAVERSE_TYPE(TypedefType, { })
-
-DEF_TRAVERSE_TYPE(TypeOfExprType, {
-    TRY_TO(TraverseStmt(T->getUnderlyingExpr()));
-  })
-
-DEF_TRAVERSE_TYPE(TypeOfType, {
-    TRY_TO(TraverseType(T->getUnderlyingType()));
-  })
-
-DEF_TRAVERSE_TYPE(DecltypeType, {
-    TRY_TO(TraverseStmt(T->getUnderlyingExpr()));
-  })
-
-DEF_TRAVERSE_TYPE(UnaryTransformType, {
-    TRY_TO(TraverseType(T->getBaseType()));
-    TRY_TO(TraverseType(T->getUnderlyingType()));
-    })
-
-DEF_TRAVERSE_TYPE(AutoType, {
-    TRY_TO(TraverseType(T->getDeducedType()));
-  })
-
-DEF_TRAVERSE_TYPE(RecordType, { })
-DEF_TRAVERSE_TYPE(EnumType, { })
-DEF_TRAVERSE_TYPE(TemplateTypeParmType, { })
-DEF_TRAVERSE_TYPE(SubstTemplateTypeParmType, { })
-DEF_TRAVERSE_TYPE(SubstTemplateTypeParmPackType, { })
-
-DEF_TRAVERSE_TYPE(TemplateSpecializationType, {
-    TRY_TO(TraverseTemplateName(T->getTemplateName()));
-    TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
-  })
-
-DEF_TRAVERSE_TYPE(InjectedClassNameType, { })
-
-DEF_TRAVERSE_TYPE(AttributedType, {
-    TRY_TO(TraverseType(T->getModifiedType()));
-  })
-
-DEF_TRAVERSE_TYPE(ParenType, {
-    TRY_TO(TraverseType(T->getInnerType()));
-  })
-
-DEF_TRAVERSE_TYPE(ElaboratedType, {
-    if (T->getQualifier()) {
-      TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
-    }
-    TRY_TO(TraverseType(T->getNamedType()));
-  })
-
-DEF_TRAVERSE_TYPE(DependentNameType, {
-    TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
-  })
-
-DEF_TRAVERSE_TYPE(DependentTemplateSpecializationType, {
-    TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
-    TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
-  })
-
-DEF_TRAVERSE_TYPE(PackExpansionType, {
-    TRY_TO(TraverseType(T->getPattern()));
-  })
-
-DEF_TRAVERSE_TYPE(ObjCInterfaceType, { })
-
-DEF_TRAVERSE_TYPE(ObjCObjectType, {
-    // We have to watch out here because an ObjCInterfaceType's base
-    // type is itself.
-    if (T->getBaseType().getTypePtr() != T)
-      TRY_TO(TraverseType(T->getBaseType()));
-  })
-
-DEF_TRAVERSE_TYPE(ObjCObjectPointerType, {
-    TRY_TO(TraverseType(T->getPointeeType()));
-  })
-
-DEF_TRAVERSE_TYPE(AtomicType, {
-    TRY_TO(TraverseType(T->getValueType()));
-  })
-
-#undef DEF_TRAVERSE_TYPE
-
-// ----------------- TypeLoc traversal -----------------
-
-// This macro makes available a variable TL, the passed-in TypeLoc.
-// If requested, it calls WalkUpFrom* for the Type in the given TypeLoc,
-// in addition to WalkUpFrom* for the TypeLoc itself, such that existing
-// clients that override the WalkUpFrom*Type() and/or Visit*Type() methods
-// continue to work.
-#define DEF_TRAVERSE_TYPELOC(TYPE, CODE)                                \
-  template<typename Derived>                                            \
-  bool RecursiveASTVisitor<Derived>::Traverse##TYPE##Loc(TYPE##Loc TL) { \
-    if (getDerived().shouldWalkTypesOfTypeLocs())                       \
-      TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE*>(TL.getTypePtr())));     \
-    TRY_TO(WalkUpFrom##TYPE##Loc(TL));                                  \
-    { CODE; }                                                           \
-    return true;                                                        \
-  }
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseQualifiedTypeLoc(
-    QualifiedTypeLoc TL) {
-  // Move this over to the 'main' typeloc tree.  Note that this is a
-  // move -- we pretend that we were really looking at the unqualified
-  // typeloc all along -- rather than a recursion, so we don't follow
-  // the normal CRTP plan of going through
-  // getDerived().TraverseTypeLoc.  If we did, we'd be traversing
-  // twice for the same type (once as a QualifiedTypeLoc version of
-  // the type, once as an UnqualifiedTypeLoc version of the type),
-  // which in effect means we'd call VisitTypeLoc twice with the
-  // 'same' type.  This solves that problem, at the cost of never
-  // seeing the qualified version of the type (unless the client
-  // subclasses TraverseQualifiedTypeLoc themselves).  It's not a
-  // perfect solution.  A perfect solution probably requires making
-  // QualifiedTypeLoc a wrapper around TypeLoc -- like QualType is a
-  // wrapper around Type* -- rather than being its own class in the
-  // type hierarchy.
-  return TraverseTypeLoc(TL.getUnqualifiedLoc());
-}
-
-DEF_TRAVERSE_TYPELOC(BuiltinType, { })
-
-// FIXME: ComplexTypeLoc is unfinished
-DEF_TRAVERSE_TYPELOC(ComplexType, {
-    TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
-  })
-
-DEF_TRAVERSE_TYPELOC(PointerType, {
-    TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
-  })
-
-DEF_TRAVERSE_TYPELOC(BlockPointerType, {
-    TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
-  })
-
-DEF_TRAVERSE_TYPELOC(LValueReferenceType, {
-    TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
-  })
-
-DEF_TRAVERSE_TYPELOC(RValueReferenceType, {
-    TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
-  })
-
-// FIXME: location of base class?
-// We traverse this in the type case as well, but how is it not reached through
-// the pointee type?
-DEF_TRAVERSE_TYPELOC(MemberPointerType, {
-    TRY_TO(TraverseType(QualType(TL.getTypePtr()->getClass(), 0)));
-    TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
-  })
-
-DEF_TRAVERSE_TYPELOC(DecayedType, {
-    TRY_TO(TraverseTypeLoc(TL.getOriginalLoc()));
-  })
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseArrayTypeLocHelper(ArrayTypeLoc TL) {
-  // This isn't available for ArrayType, but is for the ArrayTypeLoc.
-  TRY_TO(TraverseStmt(TL.getSizeExpr()));
-  return true;
-}
-
-DEF_TRAVERSE_TYPELOC(ConstantArrayType, {
-    TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
-    return TraverseArrayTypeLocHelper(TL);
-  })
-
-DEF_TRAVERSE_TYPELOC(IncompleteArrayType, {
-    TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
-    return TraverseArrayTypeLocHelper(TL);
-  })
-
-DEF_TRAVERSE_TYPELOC(VariableArrayType, {
-    TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
-    return TraverseArrayTypeLocHelper(TL);
-  })
-
-DEF_TRAVERSE_TYPELOC(DependentSizedArrayType, {
-    TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
-    return TraverseArrayTypeLocHelper(TL);
-  })
-
-// FIXME: order? why not size expr first?
-// FIXME: base VectorTypeLoc is unfinished
-DEF_TRAVERSE_TYPELOC(DependentSizedExtVectorType, {
-    if (TL.getTypePtr()->getSizeExpr())
-      TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
-    TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
-  })
-
-// FIXME: VectorTypeLoc is unfinished
-DEF_TRAVERSE_TYPELOC(VectorType, {
-    TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
-  })
-
-// FIXME: size and attributes
-// FIXME: base VectorTypeLoc is unfinished
-DEF_TRAVERSE_TYPELOC(ExtVectorType, {
-    TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
-  })
-
-DEF_TRAVERSE_TYPELOC(FunctionNoProtoType, {
-    TRY_TO(TraverseTypeLoc(TL.getResultLoc()));
-  })
-
-// FIXME: location of exception specifications (attributes?)
-DEF_TRAVERSE_TYPELOC(FunctionProtoType, {
-    TRY_TO(TraverseTypeLoc(TL.getResultLoc()));
-
-    const FunctionProtoType *T = TL.getTypePtr();
-
-    for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
-      if (TL.getArg(I)) {
-        TRY_TO(TraverseDecl(TL.getArg(I)));
-      } else if (I < T->getNumArgs()) {
-        TRY_TO(TraverseType(T->getArgType(I)));
-      }
-    }
-
-    for (FunctionProtoType::exception_iterator E = T->exception_begin(),
-                                            EEnd = T->exception_end();
-         E != EEnd; ++E) {
-      TRY_TO(TraverseType(*E));
-    }
-  })
-
-DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, { })
-DEF_TRAVERSE_TYPELOC(TypedefType, { })
-
-DEF_TRAVERSE_TYPELOC(TypeOfExprType, {
-    TRY_TO(TraverseStmt(TL.getUnderlyingExpr()));
-  })
-
-DEF_TRAVERSE_TYPELOC(TypeOfType, {
-    TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
-  })
-
-// FIXME: location of underlying expr
-DEF_TRAVERSE_TYPELOC(DecltypeType, {
-    TRY_TO(TraverseStmt(TL.getTypePtr()->getUnderlyingExpr()));
-  })
-
-DEF_TRAVERSE_TYPELOC(UnaryTransformType, {
-    TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
-  })
-
-DEF_TRAVERSE_TYPELOC(AutoType, {
-    TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
-  })
-
-DEF_TRAVERSE_TYPELOC(RecordType, { })
-DEF_TRAVERSE_TYPELOC(EnumType, { })
-DEF_TRAVERSE_TYPELOC(TemplateTypeParmType, { })
-DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmType, { })
-DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmPackType, { })
-
-// FIXME: use the loc for the template name?
-DEF_TRAVERSE_TYPELOC(TemplateSpecializationType, {
-    TRY_TO(TraverseTemplateName(TL.getTypePtr()->getTemplateName()));
-    for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
-      TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
-    }
-  })
-
-DEF_TRAVERSE_TYPELOC(InjectedClassNameType, { })
-
-DEF_TRAVERSE_TYPELOC(ParenType, {
-    TRY_TO(TraverseTypeLoc(TL.getInnerLoc()));
-  })
-
-DEF_TRAVERSE_TYPELOC(AttributedType, {
-    TRY_TO(TraverseTypeLoc(TL.getModifiedLoc()));
-  })
-
-DEF_TRAVERSE_TYPELOC(ElaboratedType, {
-    if (TL.getQualifierLoc()) {
-      TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
-    }
-    TRY_TO(TraverseTypeLoc(TL.getNamedTypeLoc()));
-  })
-
-DEF_TRAVERSE_TYPELOC(DependentNameType, {
-    TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
-  })
-
-DEF_TRAVERSE_TYPELOC(DependentTemplateSpecializationType, {
-    if (TL.getQualifierLoc()) {
-      TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
-    }
-
-    for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
-      TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
-    }
-  })
-
-DEF_TRAVERSE_TYPELOC(PackExpansionType, {
-    TRY_TO(TraverseTypeLoc(TL.getPatternLoc()));
-  })
-
-DEF_TRAVERSE_TYPELOC(ObjCInterfaceType, { })
-
-DEF_TRAVERSE_TYPELOC(ObjCObjectType, {
-    // We have to watch out here because an ObjCInterfaceType's base
-    // type is itself.
-    if (TL.getTypePtr()->getBaseType().getTypePtr() != TL.getTypePtr())
-      TRY_TO(TraverseTypeLoc(TL.getBaseLoc()));
-  })
-
-DEF_TRAVERSE_TYPELOC(ObjCObjectPointerType, {
-    TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
-  })
-
-DEF_TRAVERSE_TYPELOC(AtomicType, {
-    TRY_TO(TraverseTypeLoc(TL.getValueLoc()));
-  })
-
-#undef DEF_TRAVERSE_TYPELOC
-
-// ----------------- Decl traversal -----------------
-//
-// For a Decl, we automate (in the DEF_TRAVERSE_DECL macro) traversing
-// the children that come from the DeclContext associated with it.
-// Therefore each Traverse* only needs to worry about children other
-// than those.
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) {
-  if (!DC)
-    return true;
-
-  for (DeclContext::decl_iterator Child = DC->decls_begin(),
-           ChildEnd = DC->decls_end();
-       Child != ChildEnd; ++Child) {
-    // BlockDecls and CapturedDecls are traversed through BlockExprs and
-    // CapturedStmts respectively.
-    if (!isa<BlockDecl>(*Child) && !isa<CapturedDecl>(*Child))
-      TRY_TO(TraverseDecl(*Child));
-  }
-
-  return true;
-}
-
-// This macro makes available a variable D, the passed-in decl.
-#define DEF_TRAVERSE_DECL(DECL, CODE)                           \
-template<typename Derived>                                      \
-bool RecursiveASTVisitor<Derived>::Traverse##DECL (DECL *D) {   \
-  TRY_TO(WalkUpFrom##DECL (D));                                 \
-  { CODE; }                                                     \
-  TRY_TO(TraverseDeclContextHelper(dyn_cast<DeclContext>(D)));  \
-  return true;                                                  \
-}
-
-DEF_TRAVERSE_DECL(AccessSpecDecl, { })
-
-DEF_TRAVERSE_DECL(BlockDecl, {
-    if (TypeSourceInfo *TInfo = D->getSignatureAsWritten())
-      TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
-    TRY_TO(TraverseStmt(D->getBody()));
-    // This return statement makes sure the traversal of nodes in
-    // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
-    // is skipped - don't remove it.
-    return true;
-  })
-
-DEF_TRAVERSE_DECL(CapturedDecl, {
-    TRY_TO(TraverseStmt(D->getBody()));
-    // This return statement makes sure the traversal of nodes in
-    // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
-    // is skipped - don't remove it.
-    return true;
-  })
-
-DEF_TRAVERSE_DECL(EmptyDecl, { })
-
-DEF_TRAVERSE_DECL(FileScopeAsmDecl, {
-    TRY_TO(TraverseStmt(D->getAsmString()));
-  })
-
-DEF_TRAVERSE_DECL(ImportDecl, { })
-
-DEF_TRAVERSE_DECL(FriendDecl, {
-    // Friend is either decl or a type.
-    if (D->getFriendType())
-      TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
-    else
-      TRY_TO(TraverseDecl(D->getFriendDecl()));
-  })
-
-DEF_TRAVERSE_DECL(FriendTemplateDecl, {
-    if (D->getFriendType())
-      TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
-    else
-      TRY_TO(TraverseDecl(D->getFriendDecl()));
-    for (unsigned I = 0, E = D->getNumTemplateParameters(); I < E; ++I) {
-      TemplateParameterList *TPL = D->getTemplateParameterList(I);
-      for (TemplateParameterList::iterator ITPL = TPL->begin(),
-                                           ETPL = TPL->end();
-           ITPL != ETPL; ++ITPL) {
-        TRY_TO(TraverseDecl(*ITPL));
-      }
-    }
-  })
-
-DEF_TRAVERSE_DECL(ClassScopeFunctionSpecializationDecl, {
-  TRY_TO(TraverseDecl(D->getSpecialization()));
- })
-
-DEF_TRAVERSE_DECL(LinkageSpecDecl, { })
-
-DEF_TRAVERSE_DECL(ObjCPropertyImplDecl, {
-    // FIXME: implement this
-  })
-
-DEF_TRAVERSE_DECL(StaticAssertDecl, {
-    TRY_TO(TraverseStmt(D->getAssertExpr()));
-    TRY_TO(TraverseStmt(D->getMessage()));
-  })
-
-DEF_TRAVERSE_DECL(TranslationUnitDecl, {
-    // Code in an unnamed namespace shows up automatically in
-    // decls_begin()/decls_end().  Thus we don't need to recurse on
-    // D->getAnonymousNamespace().
-  })
-
-DEF_TRAVERSE_DECL(NamespaceAliasDecl, {
-    // We shouldn't traverse an aliased namespace, since it will be
-    // defined (and, therefore, traversed) somewhere else.
-    //
-    // This return statement makes sure the traversal of nodes in
-    // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
-    // is skipped - don't remove it.
-    return true;
-  })
-
-DEF_TRAVERSE_DECL(LabelDecl, {
-  // There is no code in a LabelDecl.
-})
-
-
-DEF_TRAVERSE_DECL(NamespaceDecl, {
-    // Code in an unnamed namespace shows up automatically in
-    // decls_begin()/decls_end().  Thus we don't need to recurse on
-    // D->getAnonymousNamespace().
-  })
-
-DEF_TRAVERSE_DECL(ObjCCompatibleAliasDecl, {
-    // FIXME: implement
-  })
-
-DEF_TRAVERSE_DECL(ObjCCategoryDecl, {
-    // FIXME: implement
-  })
-
-DEF_TRAVERSE_DECL(ObjCCategoryImplDecl, {
-    // FIXME: implement
-  })
-
-DEF_TRAVERSE_DECL(ObjCImplementationDecl, {
-    // FIXME: implement
-  })
-
-DEF_TRAVERSE_DECL(ObjCInterfaceDecl, {
-    // FIXME: implement
-  })
-
-DEF_TRAVERSE_DECL(ObjCProtocolDecl, {
-    // FIXME: implement
-  })
-
-DEF_TRAVERSE_DECL(ObjCMethodDecl, {
-    if (D->getResultTypeSourceInfo()) {
-      TRY_TO(TraverseTypeLoc(D->getResultTypeSourceInfo()->getTypeLoc()));
-    }
-    for (ObjCMethodDecl::param_iterator
-           I = D->param_begin(), E = D->param_end(); I != E; ++I) {
-      TRY_TO(TraverseDecl(*I));
-    }
-    if (D->isThisDeclarationADefinition()) {
-      TRY_TO(TraverseStmt(D->getBody()));
-    }
-    return true;
-  })
-
-DEF_TRAVERSE_DECL(ObjCPropertyDecl, {
-    // FIXME: implement
-  })
-
-DEF_TRAVERSE_DECL(UsingDecl, {
-    TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
-    TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
-  })
-
-DEF_TRAVERSE_DECL(UsingDirectiveDecl, {
-    TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
-  })
-
-DEF_TRAVERSE_DECL(UsingShadowDecl, { })
-
-DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, {
-    for (OMPThreadPrivateDecl::varlist_iterator I = D->varlist_begin(),
-                                                E = D->varlist_end();
-         I != E; ++I) {
-      TRY_TO(TraverseStmt(*I));
-    }
-  })
-
-// A helper method for TemplateDecl's children.
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper(
-    TemplateParameterList *TPL) {
-  if (TPL) {
-    for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end();
-         I != E; ++I) {
-      TRY_TO(TraverseDecl(*I));
-    }
-  }
-  return true;
-}
-
-// A helper method for traversing the implicit instantiations of a
-// class template.
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseClassInstantiations(
-    ClassTemplateDecl *D) {
-  ClassTemplateDecl::spec_iterator end = D->spec_end();
-  for (ClassTemplateDecl::spec_iterator it = D->spec_begin(); it != end; ++it) {
-    ClassTemplateSpecializationDecl* SD = *it;
-
-    switch (SD->getSpecializationKind()) {
-    // Visit the implicit instantiations with the requested pattern.
-    case TSK_Undeclared:
-    case TSK_ImplicitInstantiation:
-      TRY_TO(TraverseDecl(SD));
-      break;
-
-    // We don't need to do anything on an explicit instantiation
-    // or explicit specialization because there will be an explicit
-    // node for it elsewhere.
-    case TSK_ExplicitInstantiationDeclaration:
-    case TSK_ExplicitInstantiationDefinition:
-    case TSK_ExplicitSpecialization:
-      break;
-    }
-  }
-
-  return true;
-}
-
-DEF_TRAVERSE_DECL(ClassTemplateDecl, {
-    CXXRecordDecl* TempDecl = D->getTemplatedDecl();
-    TRY_TO(TraverseDecl(TempDecl));
-    TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
-
-    // By default, we do not traverse the instantiations of
-    // class templates since they do not appear in the user code. The
-    // following code optionally traverses them.
-    //
-    // We only traverse the class instantiations when we see the canonical
-    // declaration of the template, to ensure we only visit them once.
-    if (getDerived().shouldVisitTemplateInstantiations() &&
-        D == D->getCanonicalDecl())
-      TRY_TO(TraverseClassInstantiations(D));
-
-    // Note that getInstantiatedFromMemberTemplate() is just a link
-    // from a template instantiation back to the template from which
-    // it was instantiated, and thus should not be traversed.
-  })
-
-// A helper method for traversing the implicit instantiations of a
-// class template.
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseVariableInstantiations(
-    VarTemplateDecl *D) {
-  VarTemplateDecl::spec_iterator end = D->spec_end();
-  for (VarTemplateDecl::spec_iterator it = D->spec_begin(); it != end; ++it) {
-    VarTemplateSpecializationDecl *SD = *it;
-
-    switch (SD->getSpecializationKind()) {
-    // Visit the implicit instantiations with the requested pattern.
-    case TSK_Undeclared:
-    case TSK_ImplicitInstantiation:
-      TRY_TO(TraverseDecl(SD));
-      break;
-
-    // We don't need to do anything on an explicit instantiation
-    // or explicit specialization because there will be an explicit
-    // node for it elsewhere.
-    case TSK_ExplicitInstantiationDeclaration:
-    case TSK_ExplicitInstantiationDefinition:
-    case TSK_ExplicitSpecialization:
-      break;
-    }
-  }
-
-  return true;
-}
-
-DEF_TRAVERSE_DECL(
-    VarTemplateDecl,
-    {
-  VarDecl *TempDecl = D->getTemplatedDecl();
-  TRY_TO(TraverseDecl(TempDecl));
-  TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
-
-  // By default, we do not traverse the instantiations of
-  // variable templates since they do not appear in the user code. The
-  // following code optionally traverses them.
-  //
-  // We only traverse the variable instantiations when we see the canonical
-  // declaration of the template, to ensure we only visit them once.
-  if (getDerived().shouldVisitTemplateInstantiations() &&
-      D == D->getCanonicalDecl())
-    TRY_TO(TraverseVariableInstantiations(D));
-
-      // Note that getInstantiatedFromMemberTemplate() is just a link
-      // from a template instantiation back to the template from which
-      // it was instantiated, and thus should not be traversed.
-})
-
-// A helper method for traversing the instantiations of a
-// function while skipping its specializations.
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseFunctionInstantiations(
-    FunctionTemplateDecl *D) {
-  FunctionTemplateDecl::spec_iterator end = D->spec_end();
-  for (FunctionTemplateDecl::spec_iterator it = D->spec_begin(); it != end;
-       ++it) {
-    FunctionDecl* FD = *it;
-    switch (FD->getTemplateSpecializationKind()) {
-    case TSK_Undeclared:
-    case TSK_ImplicitInstantiation:
-      // We don't know what kind of FunctionDecl this is.
-      TRY_TO(TraverseDecl(FD));
-      break;
-
-    // No need to visit explicit instantiations, we'll find the node
-    // eventually.
-    case TSK_ExplicitInstantiationDeclaration:
-    case TSK_ExplicitInstantiationDefinition:
-      break;
-
-    case TSK_ExplicitSpecialization:
-      break;
-    }
-  }
-
-  return true;
-}
-
-DEF_TRAVERSE_DECL(FunctionTemplateDecl, {
-    TRY_TO(TraverseDecl(D->getTemplatedDecl()));
-    TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
-
-    // By default, we do not traverse the instantiations of
-    // function templates since they do not appear in the user code. The
-    // following code optionally traverses them.
-    //
-    // We only traverse the function instantiations when we see the canonical
-    // declaration of the template, to ensure we only visit them once.
-    if (getDerived().shouldVisitTemplateInstantiations() &&
-        D == D->getCanonicalDecl())
-      TRY_TO(TraverseFunctionInstantiations(D));
-  })
-
-DEF_TRAVERSE_DECL(TemplateTemplateParmDecl, {
-    // D is the "T" in something like
-    //   template <template <typename> class T> class container { };
-    TRY_TO(TraverseDecl(D->getTemplatedDecl()));
-    if (D->hasDefaultArgument()) {
-      TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
-    }
-    TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
-  })
-
-DEF_TRAVERSE_DECL(TemplateTypeParmDecl, {
-    // D is the "T" in something like "template<typename T> class vector;"
-    if (D->getTypeForDecl())
-      TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
-    if (D->hasDefaultArgument())
-      TRY_TO(TraverseTypeLoc(D->getDefaultArgumentInfo()->getTypeLoc()));
-  })
-
-DEF_TRAVERSE_DECL(TypedefDecl, {
-    TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
-    // We shouldn't traverse D->getTypeForDecl(); it's a result of
-    // declaring the typedef, not something that was written in the
-    // source.
-  })
-
-DEF_TRAVERSE_DECL(TypeAliasDecl, {
-    TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
-    // We shouldn't traverse D->getTypeForDecl(); it's a result of
-    // declaring the type alias, not something that was written in the
-    // source.
-  })
-
-DEF_TRAVERSE_DECL(TypeAliasTemplateDecl, {
-    TRY_TO(TraverseDecl(D->getTemplatedDecl()));
-    TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
-  })
-
-DEF_TRAVERSE_DECL(UnresolvedUsingTypenameDecl, {
-    // A dependent using declaration which was marked with 'typename'.
-    //   template<class T> class A : public B<T> { using typename B<T>::foo; };
-    TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
-    // We shouldn't traverse D->getTypeForDecl(); it's a result of
-    // declaring the type, not something that was written in the
-    // source.
-  })
-
-DEF_TRAVERSE_DECL(EnumDecl, {
-    if (D->getTypeForDecl())
-      TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
-
-    TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
-    // The enumerators are already traversed by
-    // decls_begin()/decls_end().
-  })
-
-
-// Helper methods for RecordDecl and its children.
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseRecordHelper(
-    RecordDecl *D) {
-  // We shouldn't traverse D->getTypeForDecl(); it's a result of
-  // declaring the type, not something that was written in the source.
-
-  TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
-  return true;
-}
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseCXXRecordHelper(
-    CXXRecordDecl *D) {
-  if (!TraverseRecordHelper(D))
-    return false;
-  if (D->isCompleteDefinition()) {
-    for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
-                                            E = D->bases_end();
-         I != E; ++I) {
-      TRY_TO(TraverseTypeLoc(I->getTypeSourceInfo()->getTypeLoc()));
-    }
-    // We don't traverse the friends or the conversions, as they are
-    // already in decls_begin()/decls_end().
-  }
-  return true;
-}
-
-DEF_TRAVERSE_DECL(RecordDecl, {
-    TRY_TO(TraverseRecordHelper(D));
-  })
-
-DEF_TRAVERSE_DECL(CXXRecordDecl, {
-    TRY_TO(TraverseCXXRecordHelper(D));
-  })
-
-DEF_TRAVERSE_DECL(ClassTemplateSpecializationDecl, {
-    // For implicit instantiations ("set<int> x;"), we don't want to
-    // recurse at all, since the instatiated class isn't written in
-    // the source code anywhere.  (Note the instatiated *type* --
-    // set<int> -- is written, and will still get a callback of
-    // TemplateSpecializationType).  For explicit instantiations
-    // ("template set<int>;"), we do need a callback, since this
-    // is the only callback that's made for this instantiation.
-    // We use getTypeAsWritten() to distinguish.
-    if (TypeSourceInfo *TSI = D->getTypeAsWritten())
-      TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
-
-    if (!getDerived().shouldVisitTemplateInstantiations() &&
-        D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization)
-      // Returning from here skips traversing the
-      // declaration context of the ClassTemplateSpecializationDecl
-      // (embedded in the DEF_TRAVERSE_DECL() macro)
-      // which contains the instantiated members of the class.
-      return true;
-  })
-
-template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper(
-    const TemplateArgumentLoc *TAL, unsigned Count) {
-  for (unsigned I = 0; I < Count; ++I) {
-    TRY_TO(TraverseTemplateArgumentLoc(TAL[I]));
-  }
-  return true;
-}
-
-DEF_TRAVERSE_DECL(ClassTemplatePartialSpecializationDecl, {
-    // The partial specialization.
-    if (TemplateParameterList *TPL = D->getTemplateParameters()) {
-      for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end();
-           I != E; ++I) {
-        TRY_TO(TraverseDecl(*I));
-      }
-    }
-    // The args that remains unspecialized.
-    TRY_TO(TraverseTemplateArgumentLocsHelper(
-                       D->getTemplateArgsAsWritten()->getTemplateArgs(),
-                       D->getTemplateArgsAsWritten()->NumTemplateArgs));
-
-    // Don't need the ClassTemplatePartialSpecializationHelper, even
-    // though that's our parent class -- we already visit all the
-    // template args here.
-    TRY_TO(TraverseCXXRecordHelper(D));
-
-    // Instantiations will have been visited with the primary template.
-  })
-
-DEF_TRAVERSE_DECL(EnumConstantDecl, {
-    TRY_TO(TraverseStmt(D->getInitExpr()));
-  })
-
-DEF_TRAVERSE_DECL(UnresolvedUsingValueDecl, {
-    // Like UnresolvedUsingTypenameDecl, but without the 'typename':
-    //    template <class T> Class A : public Base<T> { using Base<T>::foo; };
-    TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
-    TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
-  })
-
-DEF_TRAVERSE_DECL(IndirectFieldDecl, {})
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) {
-  TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
-  if (D->getTypeSourceInfo())
-    TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
-  else
-    TRY_TO(TraverseType(D->getType()));
-  return true;
-}
-
-DEF_TRAVERSE_DECL(FieldDecl, {
-    TRY_TO(TraverseDeclaratorHelper(D));
-    if (D->isBitField())
-      TRY_TO(TraverseStmt(D->getBitWidth()));
-    else if (D->hasInClassInitializer())
-      TRY_TO(TraverseStmt(D->getInClassInitializer()));
-  })
-
-DEF_TRAVERSE_DECL(MSPropertyDecl, {
-    TRY_TO(TraverseDeclaratorHelper(D));
-  })
-
-DEF_TRAVERSE_DECL(ObjCAtDefsFieldDecl, {
-    TRY_TO(TraverseDeclaratorHelper(D));
-    if (D->isBitField())
-      TRY_TO(TraverseStmt(D->getBitWidth()));
-    // FIXME: implement the rest.
-  })
-
-DEF_TRAVERSE_DECL(ObjCIvarDecl, {
-    TRY_TO(TraverseDeclaratorHelper(D));
-    if (D->isBitField())
-      TRY_TO(TraverseStmt(D->getBitWidth()));
-    // FIXME: implement the rest.
-  })
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
-  TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
-  TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
-
-  // If we're an explicit template specialization, iterate over the
-  // template args that were explicitly specified.  If we were doing
-  // this in typing order, we'd do it between the return type and
-  // the function args, but both are handled by the FunctionTypeLoc
-  // above, so we have to choose one side.  I've decided to do before.
-  if (const FunctionTemplateSpecializationInfo *FTSI =
-      D->getTemplateSpecializationInfo()) {
-    if (FTSI->getTemplateSpecializationKind() != TSK_Undeclared &&
-        FTSI->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) {
-      // A specialization might not have explicit template arguments if it has
-      // a templated return type and concrete arguments.
-      if (const ASTTemplateArgumentListInfo *TALI =
-          FTSI->TemplateArgumentsAsWritten) {
-        TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getTemplateArgs(),
-                                                  TALI->NumTemplateArgs));
-      }
-    }
-  }
-
-  // Visit the function type itself, which can be either
-  // FunctionNoProtoType or FunctionProtoType, or a typedef.  This
-  // also covers the return type and the function parameters,
-  // including exception specifications.
-  TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
-
-  if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
-    // Constructor initializers.
-    for (CXXConstructorDecl::init_iterator I = Ctor->init_begin(),
-                                           E = Ctor->init_end();
-         I != E; ++I) {
-      TRY_TO(TraverseConstructorInitializer(*I));
-    }
-  }
-
-  if (D->isThisDeclarationADefinition()) {
-    TRY_TO(TraverseStmt(D->getBody()));  // Function body.
-  }
-  return true;
-}
-
-DEF_TRAVERSE_DECL(FunctionDecl, {
-    // We skip decls_begin/decls_end, which are already covered by
-    // TraverseFunctionHelper().
-    return TraverseFunctionHelper(D);
-  })
-
-DEF_TRAVERSE_DECL(CXXMethodDecl, {
-    // We skip decls_begin/decls_end, which are already covered by
-    // TraverseFunctionHelper().
-    return TraverseFunctionHelper(D);
-  })
-
-DEF_TRAVERSE_DECL(CXXConstructorDecl, {
-    // We skip decls_begin/decls_end, which are already covered by
-    // TraverseFunctionHelper().
-    return TraverseFunctionHelper(D);
-  })
-
-// CXXConversionDecl is the declaration of a type conversion operator.
-// It's not a cast expression.
-DEF_TRAVERSE_DECL(CXXConversionDecl, {
-    // We skip decls_begin/decls_end, which are already covered by
-    // TraverseFunctionHelper().
-    return TraverseFunctionHelper(D);
-  })
-
-DEF_TRAVERSE_DECL(CXXDestructorDecl, {
-    // We skip decls_begin/decls_end, which are already covered by
-    // TraverseFunctionHelper().
-    return TraverseFunctionHelper(D);
-  })
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseVarHelper(VarDecl *D) {
-  TRY_TO(TraverseDeclaratorHelper(D));
-  // Default params are taken care of when we traverse the ParmVarDecl.
-  if (!isa<ParmVarDecl>(D))
-    TRY_TO(TraverseStmt(D->getInit()));
-  return true;
-}
-
-DEF_TRAVERSE_DECL(VarDecl, {
-    TRY_TO(TraverseVarHelper(D));
-  })
-
-DEF_TRAVERSE_DECL(VarTemplateSpecializationDecl, {
-  // For implicit instantiations, we don't want to
-  // recurse at all, since the instatiated class isn't written in
-  // the source code anywhere.
-  if (TypeSourceInfo *TSI = D->getTypeAsWritten())
-    TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
-
-  if (!getDerived().shouldVisitTemplateInstantiations() &&
-      D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization)
-    // Returning from here skips traversing the
-    // declaration context of the VarTemplateSpecializationDecl
-    // (embedded in the DEF_TRAVERSE_DECL() macro).
-    return true;
-})
-
-DEF_TRAVERSE_DECL(VarTemplatePartialSpecializationDecl,
-                  {
-  // The partial specialization.
-  if (TemplateParameterList *TPL = D->getTemplateParameters()) {
-    for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end();
-         I != E; ++I) {
-      TRY_TO(TraverseDecl(*I));
-    }
-  }
-  // The args that remains unspecialized.
-  TRY_TO(TraverseTemplateArgumentLocsHelper(
-                         D->getTemplateArgsAsWritten()->getTemplateArgs(),
-                         D->getTemplateArgsAsWritten()->NumTemplateArgs));
-
-  // Don't need the VarTemplatePartialSpecializationHelper, even
-  // though that's our parent class -- we already visit all the
-  // template args here.
-  TRY_TO(TraverseVarHelper(D));
-
-                    // Instantiations will have been visited with the primary
-                    // template.
-})
-
-DEF_TRAVERSE_DECL(ImplicitParamDecl, {
-    TRY_TO(TraverseVarHelper(D));
-  })
-
-DEF_TRAVERSE_DECL(NonTypeTemplateParmDecl, {
-    // A non-type template parameter, e.g. "S" in template<int S> class Foo ...
-    TRY_TO(TraverseDeclaratorHelper(D));
-    TRY_TO(TraverseStmt(D->getDefaultArgument()));
-  })
-
-DEF_TRAVERSE_DECL(ParmVarDecl, {
-    TRY_TO(TraverseVarHelper(D));
-
-    if (D->hasDefaultArg() &&
-        D->hasUninstantiatedDefaultArg() &&
-        !D->hasUnparsedDefaultArg())
-      TRY_TO(TraverseStmt(D->getUninstantiatedDefaultArg()));
-
-    if (D->hasDefaultArg() &&
-        !D->hasUninstantiatedDefaultArg() &&
-        !D->hasUnparsedDefaultArg())
-      TRY_TO(TraverseStmt(D->getDefaultArg()));
-  })
-
-#undef DEF_TRAVERSE_DECL
-
-// ----------------- Stmt traversal -----------------
-//
-// For stmts, we automate (in the DEF_TRAVERSE_STMT macro) iterating
-// over the children defined in children() (every stmt defines these,
-// though sometimes the range is empty).  Each individual Traverse*
-// method only needs to worry about children other than those.  To see
-// what children() does for a given class, see, e.g.,
-//   http://clang.llvm.org/doxygen/Stmt_8cpp_source.html
-
-// This macro makes available a variable S, the passed-in stmt.
-#define DEF_TRAVERSE_STMT(STMT, CODE)                                   \
-template<typename Derived>                                              \
-bool RecursiveASTVisitor<Derived>::Traverse##STMT (STMT *S) {           \
-  TRY_TO(WalkUpFrom##STMT(S));                                          \
-  StmtQueueAction StmtQueue(*this);                                     \
-  { CODE; }                                                             \
-  for (Stmt::child_range range = S->children(); range; ++range) {       \
-    StmtQueue.queue(*range);                                            \
-  }                                                                     \
-  return true;                                                          \
-}
-
-DEF_TRAVERSE_STMT(GCCAsmStmt, {
-    StmtQueue.queue(S->getAsmString());
-    for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) {
-      StmtQueue.queue(S->getInputConstraintLiteral(I));
-    }
-    for (unsigned I = 0, E = S->getNumOutputs(); I < E; ++I) {
-      StmtQueue.queue(S->getOutputConstraintLiteral(I));
-    }
-    for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) {
-      StmtQueue.queue(S->getClobberStringLiteral(I));
-    }
-    // children() iterates over inputExpr and outputExpr.
-  })
-
-DEF_TRAVERSE_STMT(MSAsmStmt, {
-    // FIXME: MS Asm doesn't currently parse Constraints, Clobbers, etc.  Once
-    // added this needs to be implemented.
-  })
-
-DEF_TRAVERSE_STMT(CXXCatchStmt, {
-    TRY_TO(TraverseDecl(S->getExceptionDecl()));
-    // children() iterates over the handler block.
-  })
-
-DEF_TRAVERSE_STMT(DeclStmt, {
-    for (DeclStmt::decl_iterator I = S->decl_begin(), E = S->decl_end();
-         I != E; ++I) {
-      TRY_TO(TraverseDecl(*I));
-    }
-    // Suppress the default iteration over children() by
-    // returning.  Here's why: A DeclStmt looks like 'type var [=
-    // initializer]'.  The decls above already traverse over the
-    // initializers, so we don't have to do it again (which
-    // children() would do).
-    return true;
-  })
-
-
-// These non-expr stmts (most of them), do not need any action except
-// iterating over the children.
-DEF_TRAVERSE_STMT(BreakStmt, { })
-DEF_TRAVERSE_STMT(CXXTryStmt, { })
-DEF_TRAVERSE_STMT(CaseStmt, { })
-DEF_TRAVERSE_STMT(CompoundStmt, { })
-DEF_TRAVERSE_STMT(ContinueStmt, { })
-DEF_TRAVERSE_STMT(DefaultStmt, { })
-DEF_TRAVERSE_STMT(DoStmt, { })
-DEF_TRAVERSE_STMT(ForStmt, { })
-DEF_TRAVERSE_STMT(GotoStmt, { })
-DEF_TRAVERSE_STMT(IfStmt, { })
-DEF_TRAVERSE_STMT(IndirectGotoStmt, { })
-DEF_TRAVERSE_STMT(LabelStmt, { })
-DEF_TRAVERSE_STMT(AttributedStmt, { })
-DEF_TRAVERSE_STMT(NullStmt, { })
-DEF_TRAVERSE_STMT(ObjCAtCatchStmt, { })
-DEF_TRAVERSE_STMT(ObjCAtFinallyStmt, { })
-DEF_TRAVERSE_STMT(ObjCAtSynchronizedStmt, { })
-DEF_TRAVERSE_STMT(ObjCAtThrowStmt, { })
-DEF_TRAVERSE_STMT(ObjCAtTryStmt, { })
-DEF_TRAVERSE_STMT(ObjCForCollectionStmt, { })
-DEF_TRAVERSE_STMT(ObjCAutoreleasePoolStmt, { })
-DEF_TRAVERSE_STMT(CXXForRangeStmt, { })
-DEF_TRAVERSE_STMT(MSDependentExistsStmt, {
-    TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
-    TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
-})
-DEF_TRAVERSE_STMT(ReturnStmt, { })
-DEF_TRAVERSE_STMT(SwitchStmt, { })
-DEF_TRAVERSE_STMT(WhileStmt, { })
-
-DEF_TRAVERSE_STMT(CXXDependentScopeMemberExpr, {
-    TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
-    TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
-    if (S->hasExplicitTemplateArgs()) {
-      TRY_TO(TraverseTemplateArgumentLocsHelper(
-          S->getTemplateArgs(), S->getNumTemplateArgs()));
-    }
-  })
-
-DEF_TRAVERSE_STMT(DeclRefExpr, {
-    TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
-    TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
-    TRY_TO(TraverseTemplateArgumentLocsHelper(
-        S->getTemplateArgs(), S->getNumTemplateArgs()));
-  })
-
-DEF_TRAVERSE_STMT(DependentScopeDeclRefExpr, {
-    TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
-    TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
-    if (S->hasExplicitTemplateArgs()) {
-      TRY_TO(TraverseTemplateArgumentLocsHelper(
-          S->getExplicitTemplateArgs().getTemplateArgs(),
-          S->getNumTemplateArgs()));
-    }
-  })
-
-DEF_TRAVERSE_STMT(MemberExpr, {
-    TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
-    TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
-    TRY_TO(TraverseTemplateArgumentLocsHelper(
-        S->getTemplateArgs(), S->getNumTemplateArgs()));
-  })
-
-DEF_TRAVERSE_STMT(ImplicitCastExpr, {
-    // We don't traverse the cast type, as it's not written in the
-    // source code.
-  })
-
-DEF_TRAVERSE_STMT(CStyleCastExpr, {
-    TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
-  })
-
-DEF_TRAVERSE_STMT(CXXFunctionalCastExpr, {
-    TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
-  })
-
-DEF_TRAVERSE_STMT(CXXConstCastExpr, {
-    TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
-  })
-
-DEF_TRAVERSE_STMT(CXXDynamicCastExpr, {
-    TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
-  })
-
-DEF_TRAVERSE_STMT(CXXReinterpretCastExpr, {
-    TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
-  })
-
-DEF_TRAVERSE_STMT(CXXStaticCastExpr, {
-    TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
-  })
-
-// InitListExpr is a tricky one, because we want to do all our work on
-// the syntactic form of the listexpr, but this method takes the
-// semantic form by default.  We can't use the macro helper because it
-// calls WalkUp*() on the semantic form, before our code can convert
-// to the syntactic form.
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseInitListExpr(InitListExpr *S) {
-  if (InitListExpr *Syn = S->getSyntacticForm())
-    S = Syn;
-  TRY_TO(WalkUpFromInitListExpr(S));
-  StmtQueueAction StmtQueue(*this);
-  // All we need are the default actions.  FIXME: use a helper function.
-  for (Stmt::child_range range = S->children(); range; ++range) {
-    StmtQueue.queue(*range);
-  }
-  return true;
-}
-
-// GenericSelectionExpr is a special case because the types and expressions
-// are interleaved.  We also need to watch out for null types (default
-// generic associations).
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::
-TraverseGenericSelectionExpr(GenericSelectionExpr *S) {
-  TRY_TO(WalkUpFromGenericSelectionExpr(S));
-  StmtQueueAction StmtQueue(*this);
-  StmtQueue.queue(S->getControllingExpr());
-  for (unsigned i = 0; i != S->getNumAssocs(); ++i) {
-    if (TypeSourceInfo *TS = S->getAssocTypeSourceInfo(i))
-      TRY_TO(TraverseTypeLoc(TS->getTypeLoc()));
-    StmtQueue.queue(S->getAssocExpr(i));
-  }
-  return true;
-}
-
-// PseudoObjectExpr is a special case because of the wierdness with
-// syntactic expressions and opaque values.
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::
-TraversePseudoObjectExpr(PseudoObjectExpr *S) {
-  TRY_TO(WalkUpFromPseudoObjectExpr(S));
-  StmtQueueAction StmtQueue(*this);
-  StmtQueue.queue(S->getSyntacticForm());
-  for (PseudoObjectExpr::semantics_iterator
-         i = S->semantics_begin(), e = S->semantics_end(); i != e; ++i) {
-    Expr *sub = *i;
-    if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(sub))
-      sub = OVE->getSourceExpr();
-    StmtQueue.queue(sub);
-  }
-  return true;
-}
-
-DEF_TRAVERSE_STMT(CXXScalarValueInitExpr, {
-    // This is called for code like 'return T()' where T is a built-in
-    // (i.e. non-class) type.
-    TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
-  })
-
-DEF_TRAVERSE_STMT(CXXNewExpr, {
-  // The child-iterator will pick up the other arguments.
-  TRY_TO(TraverseTypeLoc(S->getAllocatedTypeSourceInfo()->getTypeLoc()));
-  })
-
-DEF_TRAVERSE_STMT(OffsetOfExpr, {
-    // The child-iterator will pick up the expression representing
-    // the field.
-    // FIMXE: for code like offsetof(Foo, a.b.c), should we get
-    // making a MemberExpr callbacks for Foo.a, Foo.a.b, and Foo.a.b.c?
-    TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
-  })
-
-DEF_TRAVERSE_STMT(UnaryExprOrTypeTraitExpr, {
-    // The child-iterator will pick up the arg if it's an expression,
-    // but not if it's a type.
-    if (S->isArgumentType())
-      TRY_TO(TraverseTypeLoc(S->getArgumentTypeInfo()->getTypeLoc()));
-  })
-
-DEF_TRAVERSE_STMT(CXXTypeidExpr, {
-    // The child-iterator will pick up the arg if it's an expression,
-    // but not if it's a type.
-    if (S->isTypeOperand())
-      TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
-  })
-
-DEF_TRAVERSE_STMT(CXXUuidofExpr, {
-    // The child-iterator will pick up the arg if it's an expression,
-    // but not if it's a type.
-    if (S->isTypeOperand())
-      TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
-  })
-
-DEF_TRAVERSE_STMT(UnaryTypeTraitExpr, {
-    TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
-  })
-
-DEF_TRAVERSE_STMT(BinaryTypeTraitExpr, {
-    TRY_TO(TraverseTypeLoc(S->getLhsTypeSourceInfo()->getTypeLoc()));
-    TRY_TO(TraverseTypeLoc(S->getRhsTypeSourceInfo()->getTypeLoc()));
-  })
-
-DEF_TRAVERSE_STMT(TypeTraitExpr, {
-  for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
-    TRY_TO(TraverseTypeLoc(S->getArg(I)->getTypeLoc()));
-})
-
-DEF_TRAVERSE_STMT(ArrayTypeTraitExpr, {
-    TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
-  })
-
-DEF_TRAVERSE_STMT(ExpressionTraitExpr, {
-    StmtQueue.queue(S->getQueriedExpression());
-  })
-
-DEF_TRAVERSE_STMT(VAArgExpr, {
-    // The child-iterator will pick up the expression argument.
-    TRY_TO(TraverseTypeLoc(S->getWrittenTypeInfo()->getTypeLoc()));
-  })
-
-DEF_TRAVERSE_STMT(CXXTemporaryObjectExpr, {
-    // This is called for code like 'return T()' where T is a class type.
-    TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
-  })
-
-// Walk only the visible parts of lambda expressions.  
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseLambdaExpr(LambdaExpr *S) {
-  TRY_TO(WalkUpFromLambdaExpr(S));
-
-  for (LambdaExpr::capture_iterator C = S->explicit_capture_begin(),
-                                 CEnd = S->explicit_capture_end();
-       C != CEnd; ++C) {
-    TRY_TO(TraverseLambdaCapture(*C));
-  }
-
-  if (S->hasExplicitParameters() || S->hasExplicitResultType()) {
-    TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
-    if (S->hasExplicitParameters() && S->hasExplicitResultType()) {
-      // Visit the whole type.
-      TRY_TO(TraverseTypeLoc(TL));
-    } else if (FunctionProtoTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) {
-      if (S->hasExplicitParameters()) {
-        // Visit parameters.
-        for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I) {
-          TRY_TO(TraverseDecl(Proto.getArg(I)));
-        }
-      } else {
-        TRY_TO(TraverseTypeLoc(Proto.getResultLoc()));
-      }        
-    }
-  }
-
-  StmtQueueAction StmtQueue(*this);
-  StmtQueue.queue(S->getBody());
-  return true;
-}
-
-DEF_TRAVERSE_STMT(CXXUnresolvedConstructExpr, {
-    // This is called for code like 'T()', where T is a template argument.
-    TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
-  })
-
-// These expressions all might take explicit template arguments.
-// We traverse those if so.  FIXME: implement these.
-DEF_TRAVERSE_STMT(CXXConstructExpr, { })
-DEF_TRAVERSE_STMT(CallExpr, { })
-DEF_TRAVERSE_STMT(CXXMemberCallExpr, { })
-
-// These exprs (most of them), do not need any action except iterating
-// over the children.
-DEF_TRAVERSE_STMT(AddrLabelExpr, { })
-DEF_TRAVERSE_STMT(ArraySubscriptExpr, { })
-DEF_TRAVERSE_STMT(BlockExpr, {
-  TRY_TO(TraverseDecl(S->getBlockDecl()));
-  return true; // no child statements to loop through.
-})
-DEF_TRAVERSE_STMT(ChooseExpr, { })
-DEF_TRAVERSE_STMT(CompoundLiteralExpr, { })
-DEF_TRAVERSE_STMT(CXXBindTemporaryExpr, { })
-DEF_TRAVERSE_STMT(CXXBoolLiteralExpr, { })
-DEF_TRAVERSE_STMT(CXXDefaultArgExpr, { })
-DEF_TRAVERSE_STMT(CXXDefaultInitExpr, { })
-DEF_TRAVERSE_STMT(CXXDeleteExpr, { })
-DEF_TRAVERSE_STMT(ExprWithCleanups, { })
-DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, { })
-DEF_TRAVERSE_STMT(CXXStdInitializerListExpr, { })
-DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, {
-  TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
-  if (TypeSourceInfo *ScopeInfo = S->getScopeTypeInfo())
-    TRY_TO(TraverseTypeLoc(ScopeInfo->getTypeLoc()));
-  if (TypeSourceInfo *DestroyedTypeInfo = S->getDestroyedTypeInfo())
-    TRY_TO(TraverseTypeLoc(DestroyedTypeInfo->getTypeLoc()));
-})
-DEF_TRAVERSE_STMT(CXXThisExpr, { })
-DEF_TRAVERSE_STMT(CXXThrowExpr, { })
-DEF_TRAVERSE_STMT(UserDefinedLiteral, { })
-DEF_TRAVERSE_STMT(DesignatedInitExpr, { })
-DEF_TRAVERSE_STMT(ExtVectorElementExpr, { })
-DEF_TRAVERSE_STMT(GNUNullExpr, { })
-DEF_TRAVERSE_STMT(ImplicitValueInitExpr, { })
-DEF_TRAVERSE_STMT(ObjCBoolLiteralExpr, { })
-DEF_TRAVERSE_STMT(ObjCEncodeExpr, {
-  if (TypeSourceInfo *TInfo = S->getEncodedTypeSourceInfo())
-    TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
-})
-DEF_TRAVERSE_STMT(ObjCIsaExpr, { })
-DEF_TRAVERSE_STMT(ObjCIvarRefExpr, { })
-DEF_TRAVERSE_STMT(ObjCMessageExpr, {
-  if (TypeSourceInfo *TInfo = S->getClassReceiverTypeInfo())
-    TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
-})
-DEF_TRAVERSE_STMT(ObjCPropertyRefExpr, { })
-DEF_TRAVERSE_STMT(ObjCSubscriptRefExpr, { })
-DEF_TRAVERSE_STMT(ObjCProtocolExpr, { })
-DEF_TRAVERSE_STMT(ObjCSelectorExpr, { })
-DEF_TRAVERSE_STMT(ObjCIndirectCopyRestoreExpr, { })
-DEF_TRAVERSE_STMT(ObjCBridgedCastExpr, {
-  TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
-})
-DEF_TRAVERSE_STMT(ParenExpr, { })
-DEF_TRAVERSE_STMT(ParenListExpr, { })
-DEF_TRAVERSE_STMT(PredefinedExpr, { })
-DEF_TRAVERSE_STMT(ShuffleVectorExpr, { })
-DEF_TRAVERSE_STMT(ConvertVectorExpr, { })
-DEF_TRAVERSE_STMT(StmtExpr, { })
-DEF_TRAVERSE_STMT(UnresolvedLookupExpr, {
-  TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
-  if (S->hasExplicitTemplateArgs()) {
-    TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
-                                              S->getNumTemplateArgs()));
-  }
-})
-
-DEF_TRAVERSE_STMT(UnresolvedMemberExpr, {
-  TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
-  if (S->hasExplicitTemplateArgs()) {
-    TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
-                                              S->getNumTemplateArgs()));
-  }
-})
-
-DEF_TRAVERSE_STMT(MSPropertyRefExpr, {})
-DEF_TRAVERSE_STMT(SEHTryStmt, {})
-DEF_TRAVERSE_STMT(SEHExceptStmt, {})
-DEF_TRAVERSE_STMT(SEHFinallyStmt,{})
-DEF_TRAVERSE_STMT(CapturedStmt, {
-  TRY_TO(TraverseDecl(S->getCapturedDecl()));
-})
-
-DEF_TRAVERSE_STMT(CXXOperatorCallExpr, { })
-DEF_TRAVERSE_STMT(OpaqueValueExpr, { })
-DEF_TRAVERSE_STMT(CUDAKernelCallExpr, { })
-
-// These operators (all of them) do not need any action except
-// iterating over the children.
-DEF_TRAVERSE_STMT(BinaryConditionalOperator, { })
-DEF_TRAVERSE_STMT(ConditionalOperator, { })
-DEF_TRAVERSE_STMT(UnaryOperator, { })
-DEF_TRAVERSE_STMT(BinaryOperator, { })
-DEF_TRAVERSE_STMT(CompoundAssignOperator, { })
-DEF_TRAVERSE_STMT(CXXNoexceptExpr, { })
-DEF_TRAVERSE_STMT(PackExpansionExpr, { })
-DEF_TRAVERSE_STMT(SizeOfPackExpr, { })
-DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, { })
-DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, { })
-DEF_TRAVERSE_STMT(FunctionParmPackExpr, { })
-DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, { })
-DEF_TRAVERSE_STMT(AtomicExpr, { })
-
-// These literals (all of them) do not need any action.
-DEF_TRAVERSE_STMT(IntegerLiteral, { })
-DEF_TRAVERSE_STMT(CharacterLiteral, { })
-DEF_TRAVERSE_STMT(FloatingLiteral, { })
-DEF_TRAVERSE_STMT(ImaginaryLiteral, { })
-DEF_TRAVERSE_STMT(StringLiteral, { })
-DEF_TRAVERSE_STMT(ObjCStringLiteral, { })
-DEF_TRAVERSE_STMT(ObjCBoxedExpr, { })
-DEF_TRAVERSE_STMT(ObjCArrayLiteral, { })
-DEF_TRAVERSE_STMT(ObjCDictionaryLiteral, { })
-  
-// Traverse OpenCL: AsType, Convert.
-DEF_TRAVERSE_STMT(AsTypeExpr, { })
-
-// OpenMP directives.
-DEF_TRAVERSE_STMT(OMPParallelDirective, {
-  ArrayRef<OMPClause *> Clauses = S->clauses();
-  for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
-       I != E; ++I)
-    if (!TraverseOMPClause(*I)) return false;
-})
-
-// OpenMP clauses.
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
-  if (!C) return true;
-  switch (C->getClauseKind()) {
-#define OPENMP_CLAUSE(Name, Class)                                      \
-  case OMPC_##Name:                                                     \
-    return getDerived().Visit##Class(static_cast<Class*>(C));
-#include "clang/Basic/OpenMPKinds.def"
-  default: break;
-  }
-  return true;
-}
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPDefaultClause(OMPDefaultClause *C) {
-  return true;
-}
-
-template<typename Derived>
-template<typename T>
-void RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
-  for (typename T::varlist_iterator I = Node->varlist_begin(),
-                                    E = Node->varlist_end();
-         I != E; ++I)
-    TraverseStmt(*I);
-}
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPPrivateClause(OMPPrivateClause *C) {
-  VisitOMPClauseList(C);
-  return true;
-}
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPFirstprivateClause(
-                                                    OMPFirstprivateClause *C) {
-  VisitOMPClauseList(C);
-  return true;
-}
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::VisitOMPSharedClause(OMPSharedClause *C) {
-  VisitOMPClauseList(C);
-  return true;
-}
-
-// FIXME: look at the following tricky-seeming exprs to see if we
-// need to recurse on anything.  These are ones that have methods
-// returning decls or qualtypes or nestednamespecifier -- though I'm
-// not sure if they own them -- or just seemed very complicated, or
-// had lots of sub-types to explore.
-//
-// VisitOverloadExpr and its children: recurse on template args? etc?
-
-// FIXME: go through all the stmts and exprs again, and see which of them
-// create new types, and recurse on the types (TypeLocs?) of those.
-// Candidates:
-//
-//    http://clang.llvm.org/doxygen/classclang_1_1CXXTypeidExpr.html
-//    http://clang.llvm.org/doxygen/classclang_1_1UnaryExprOrTypeTraitExpr.html
-//    http://clang.llvm.org/doxygen/classclang_1_1TypesCompatibleExpr.html
-//    Every class that has getQualifier.
-
-#undef DEF_TRAVERSE_STMT
-
-#undef TRY_TO
-
-} // end namespace cxindex
-} // end namespace clang
-
-#endif // LLVM_CLANG_LIBCLANG_RECURSIVEASTVISITOR_H
diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports
index 9bf26c9..48eec25 100644
--- a/tools/libclang/libclang.exports
+++ b/tools/libclang/libclang.exports
@@ -2,6 +2,7 @@
 clang_CXCursorSet_insert
 clang_CXIndex_getGlobalOptions
 clang_CXIndex_setGlobalOptions
+clang_CXXMethod_isConst
 clang_CXXMethod_isPureVirtual
 clang_CXXMethod_isStatic
 clang_CXXMethod_isVirtual
@@ -29,6 +30,7 @@
 clang_Module_getFullName
 clang_Module_getNumTopLevelHeaders
 clang_Module_getTopLevelHeader
+clang_Module_isSystem
 clang_IndexAction_create
 clang_IndexAction_dispose
 clang_Range_isNull
@@ -64,6 +66,8 @@
 clang_Type_getClassType
 clang_Type_getSizeOf
 clang_Type_getOffsetOf
+clang_Type_getNumTemplateArguments
+clang_Type_getTemplateArgumentAsType
 clang_Type_getCXXRefQualifier
 clang_VerbatimBlockLineComment_getText
 clang_VerbatimLineComment_getText
@@ -87,6 +91,7 @@
 clang_createCXCursorSet
 clang_createIndex
 clang_createTranslationUnit
+clang_createTranslationUnit2
 clang_createTranslationUnitFromSourceFile
 clang_defaultCodeCompleteOptions
 clang_defaultDiagnosticDisplayOptions
@@ -101,6 +106,7 @@
 clang_disposeIndex
 clang_disposeOverriddenCursors
 clang_disposeCXPlatformAvailability
+clang_disposeSourceRangeList
 clang_disposeString
 clang_disposeTokens
 clang_disposeTranslationUnit
@@ -118,6 +124,7 @@
 clang_getArgType
 clang_getArrayElementType
 clang_getArraySize
+clang_getBuildSessionTimestamp
 clang_getCString
 clang_getCXTUResourceUsage
 clang_getCXXAccessSpecifier
@@ -188,6 +195,7 @@
 clang_getInstantiationLocation
 clang_getLocation
 clang_getLocationForOffset
+clang_getModuleForFile
 clang_getNullCursor
 clang_getNullLocation
 clang_getNullRange
@@ -207,6 +215,7 @@
 clang_getRemappings
 clang_getRemappingsFromFileList
 clang_getResultType
+clang_getSkippedRanges
 clang_getSpecializedCursorTemplate
 clang_getSpellingLocation
 clang_getTUResourceUsageName
@@ -259,6 +268,7 @@
 clang_Location_isInSystemHeader
 clang_Location_isFromMainFile
 clang_parseTranslationUnit
+clang_parseTranslationUnit2
 clang_remap_dispose
 clang_remap_getFilenames
 clang_remap_getNumFiles
@@ -279,3 +289,13 @@
 clang_CompileCommand_getArg
 clang_visitChildren
 clang_visitChildrenWithBlock
+clang_ModuleMapDescriptor_create
+clang_ModuleMapDescriptor_dispose
+clang_ModuleMapDescriptor_setFrameworkModuleName
+clang_ModuleMapDescriptor_setUmbrellaHeader
+clang_ModuleMapDescriptor_writeToBuffer
+clang_VirtualFileOverlay_addFileMapping
+clang_VirtualFileOverlay_create
+clang_VirtualFileOverlay_dispose
+clang_VirtualFileOverlay_setCaseSensitivity
+clang_VirtualFileOverlay_writeToBuffer
diff --git a/tools/scan-build/ccc-analyzer b/tools/scan-build/ccc-analyzer
index b463ec0..4c8f648 100755
--- a/tools/scan-build/ccc-analyzer
+++ b/tools/scan-build/ccc-analyzer
@@ -25,12 +25,24 @@
 # Compiler command setup.
 ##===----------------------------------------------------------------------===##
 
+# Search in the PATH if the compiler exists
+sub SearchInPath {
+    my $file = shift;
+    foreach my $dir (split (':', $ENV{PATH})) {
+        if (-x "$dir/$file") {
+            return 1;
+        }
+    }
+    return 0;
+}
+
 my $Compiler;
 my $Clang;
 my $DefaultCCompiler;
 my $DefaultCXXCompiler;
+my $IsCXX;
 
-if (`uname -a` =~ m/Darwin/) { 
+if (`uname -a` =~ m/Darwin/) {
   $DefaultCCompiler = 'clang';
   $DefaultCXXCompiler = 'clang++';
 } else {
@@ -40,17 +52,21 @@
 
 if ($FindBin::Script =~ /c\+\+-analyzer/) {
   $Compiler = $ENV{'CCC_CXX'};
-  if (!defined $Compiler) { $Compiler = $DefaultCXXCompiler; }
-  
+  if (!defined $Compiler || (! -x $Compiler && ! SearchInPath($Compiler))) { $Compiler = $DefaultCXXCompiler; }
+
   $Clang = $ENV{'CLANG_CXX'};
-  if (!defined $Clang) { $Clang = 'clang++'; }
+  if (!defined $Clang || ! -x $Clang) { $Clang = 'clang++'; }
+
+  $IsCXX = 1
 }
 else {
   $Compiler = $ENV{'CCC_CC'};
-  if (!defined $Compiler) { $Compiler = $DefaultCCompiler; }
+  if (!defined $Compiler || (! -x $Compiler && ! SearchInPath($Compiler))) { $Compiler = $DefaultCCompiler; }
 
   $Clang = $ENV{'CLANG'};
-  if (!defined $Clang) { $Clang = 'clang'; }
+  if (!defined $Clang || ! -x $Clang) { $Clang = 'clang'; }
+
+  $IsCXX = 0
 }
 
 ##===----------------------------------------------------------------------===##
@@ -64,12 +80,12 @@
 my $ResultFile;
 
 # Remove any stale files at exit.
-END { 
+END {
   if (defined $ResultFile && -z $ResultFile) {
-    `rm -f $ResultFile`;
+    unlink($ResultFile);
   }
   if (defined $CleanupFile) {
-    `rm -f $CleanupFile`;
+    unlink($CleanupFile);
   }
 }
 
@@ -95,7 +111,7 @@
   my ($Clang, $Lang, $file, $Args, $HtmlDir, $ErrorType, $ofile) = @_;
   my $Dir = "$HtmlDir/failures";
   mkpath $Dir;
-  
+
   my $prefix = "clang_crash";
   if ($ErrorType eq $ParserRejects) {
     $prefix = "clang_parser_rejects";
@@ -113,7 +129,7 @@
                                  DIR => $Dir);
   system $Clang, @$Args, "-E", "-o", $PPFile;
   close ($PPH);
-  
+
   # Create the info file.
   open (OUT, ">", "$PPFile.info.txt") or die "Cannot open $PPFile.info.txt\n";
   print OUT abs_path($file), "\n";
@@ -122,7 +138,7 @@
   close OUT;
   `uname -a >> $PPFile.info.txt 2>&1`;
   `$Compiler -v >> $PPFile.info.txt 2>&1`;
-  system 'mv',$ofile,"$PPFile.stderr.txt";
+  rename($ofile, "$PPFile.stderr.txt");
   return (basename $PPFile);
 }
 
@@ -133,7 +149,7 @@
 sub GetCCArgs {
   my $mode = shift;
   my $Args = shift;
-  
+
   pipe (FROM_CHILD, TO_PARENT);
   my $pid = fork();
   if ($pid == 0) {
@@ -141,21 +157,20 @@
     open(STDOUT,">&", \*TO_PARENT);
     open(STDERR,">&", \*TO_PARENT);
     exec $Clang, "-###", $mode, @$Args;
-  }  
+  }
   close(TO_PARENT);
   my $line;
   while (<FROM_CHILD>) {
-    next if (!/-cc1/);
+    next if (!/\s"?-cc1"?\s/);
     $line = $_;
   }
 
   waitpid($pid,0);
   close(FROM_CHILD);
-  
+
   die "could not find clang line\n" if (!defined $line);
-  # Strip the newline and initial whitspace
-  chomp $line;
-  $line =~ s/^\s+//;
+  # Strip leading and trailing whitespace characters.
+  $line =~ s/^\s+|\s+$//g;
   my @items = quotewords('\s+', 0, $line);
   my $cmd = shift @items;
   die "cannot find 'clang' in 'clang' command\n" if (!($cmd =~ /clang/));
@@ -203,7 +218,7 @@
     }
 
     # Display Ubiviz graph?
-    if (defined $ENV{'CCC_UBI'}) {   
+    if (defined $ENV{'CCC_UBI'}) {
       push @Args, "-Xclang", "-analyzer-viz-egraph-ubigraph";
     }
 
@@ -224,7 +239,7 @@
   }
   if ($Verbose == 1) {
     # We MUST print to stderr.  Some clients use the stdout output of
-    # gcc for various purposes. 
+    # gcc for various purposes.
     print STDERR join(' ', @PrintArgs);
     print STDERR "\n";
   }
@@ -235,7 +250,7 @@
   # Capture the STDERR of clang and send it to a temporary file.
   # Capture the STDOUT of clang and reroute it to ccc-analyzer's STDERR.
   # We save the output file in the 'crashes' directory if clang encounters
-  # any problems with the file.  
+  # any problems with the file.
   pipe (FROM_CHILD, TO_PARENT);
   my $pid = fork();
   if ($pid == 0) {
@@ -247,7 +262,7 @@
 
   close TO_PARENT;
   my ($ofh, $ofile) = tempfile("clang_output_XXXXXX", DIR => $HtmlDir);
-  
+
   while (<FROM_CHILD>) {
     print $ofh $_;
     print STDERR $_;
@@ -289,15 +304,15 @@
           # Have we already spotted this unhandled attribute?
           next if (defined $attributes_not_handled{$1});
           $attributes_not_handled{$1} = 1;
-        
+
           # Get the name of the attribute file.
           my $dir = "$HtmlDir/failures";
           my $afile = "$dir/attribute_ignored_$1.txt";
-        
+
           # Only create another preprocessed file if the attribute file
           # doesn't exist yet.
           next if (-e $afile);
-        
+
           # Add this file to the list of files that contained this attribute.
           # Generate a preprocessed file if we haven't already.
           if (!(defined $ppfile)) {
@@ -315,7 +330,7 @@
       }
     }
   }
-  
+
   unlink($ofile);
 }
 
@@ -349,6 +364,7 @@
   '-m32' => 0,
   '-m64' => 0,
   '-stdlib' => 0, # This is really a 1 argument, but always has '='
+  '--sysroot' => 1,
   '-target' => 1,
   '-v' => 0,
   '-mmacosx-version-min' => 0, # This is really a 1 argument, but always has '='
@@ -377,22 +393,23 @@
 );
 
 my %LangMap = (
-  'c'   => 'c',
+  'c'   => $IsCXX ? 'c++' : 'c',
   'cp'  => 'c++',
   'cpp' => 'c++',
   'cxx' => 'c++',
   'txx' => 'c++',
   'cc'  => 'c++',
   'C'   => 'c++',
-  'ii'  => 'c++',
-  'i'   => 'c-cpp-output',
+  'ii'  => 'c++-cpp-output',
+  'i'   => $IsCXX ? 'c++-cpp-output' : 'c-cpp-output',
   'm'   => 'objective-c',
   'mi'  => 'objective-c-cpp-output',
-  'mm'  => 'objective-c++'
+  'mm'  => 'objective-c++',
+  'mii' => 'objective-c++-cpp-output',
 );
 
 my %UniqueOptions = (
-  '-isysroot' => 0  
+  '-isysroot' => 0
 );
 
 ##----------------------------------------------------------------------------##
@@ -403,7 +420,10 @@
   "objective-c" => 1,
   "c" => 1,
   "c++" => 1,
-  "objective-c++" => 1
+  "objective-c++" => 1,
+  "c-cpp-output" => 1,
+  "objective-c-cpp-output" => 1,
+  "c++-cpp-output" => 1
 );
 
 ##----------------------------------------------------------------------------##
@@ -444,6 +464,9 @@
 my $OutputFormat = $ENV{'CCC_ANALYZER_OUTPUT_FORMAT'};
 if (!defined $OutputFormat) { $OutputFormat = "html"; }
 
+# Get the config options.
+my $ConfigOptions = $ENV{'CCC_ANALYZER_CONFIG'};
+
 # Determine the level of verbosity.
 my $Verbose = 0;
 if (defined $ENV{'CCC_ANALYZER_VERBOSE'}) { $Verbose = 1; }
@@ -458,7 +481,7 @@
 
 # Process the arguments.
 foreach (my $i = 0; $i < scalar(@ARGV); ++$i) {
-  my $Arg = $ARGV[$i];  
+  my $Arg = $ARGV[$i];
   my ($ArgKey) = split /=/,$Arg,2;
 
   # Modes ccc-analyzer supports
@@ -485,7 +508,7 @@
     next;
   }
   # Handle the case where there isn't a space after -iquote
-  if ($Arg =~ /-iquote.*/) {
+  if ($Arg =~ /^-iquote.*/) {
     push @CompileOpts,$Arg;
     next;
   }
@@ -502,7 +525,7 @@
   # and the linker.
   if (defined $CompilerLinkerOptionMap{$ArgKey}) {
     my $Cnt = $CompilerLinkerOptionMap{$ArgKey};
-    
+
     # Check if this is an option that should have a unique value, and if so
     # determine if the value was checked before.
     if ($UniqueOptions{$Arg}) {
@@ -512,8 +535,8 @@
       }
       $Uniqued{$Arg} = 1;
     }
-    
-    push @CompileOpts,$Arg;    
+
+    push @CompileOpts,$Arg;
     push @LinkOpts,$Arg;
 
     while ($Cnt > 0) {
@@ -523,7 +546,7 @@
     }
     next;
   }
-  
+
   # Ignored options.
   if (defined $IgnoredOptionMap{$ArgKey}) {
     my $Cnt = $IgnoredOptionMap{$ArgKey};
@@ -532,10 +555,10 @@
     }
     next;
   }
-  
+
   # Compile mode flags.
   if ($Arg =~ /^-[D,I,U](.*)$/) {
-    my $Tmp = $Arg;    
+    my $Tmp = $Arg;
     if ($1 eq '') {
       # FIXME: Check if we are going off the end.
       ++$i;
@@ -544,12 +567,12 @@
     push @CompileOpts,$Tmp;
     next;
   }
-  
-  if ($Arg =~ /-m.*/) {
+
+  if ($Arg =~ /^-m.*/) {
     push @CompileOpts,$Arg;
     next;
   }
-  
+
   # Language.
   if ($Arg eq '-x') {
     $Lang = $ARGV[$i+1];
@@ -562,7 +585,7 @@
     $Output = $ARGV[$i];
     next;
   }
-  
+
   # Get the link mode.
   if ($Arg =~ /^-[l,L,O]/) {
     if ($Arg eq '-O') { push @LinkOpts,'-O1'; }
@@ -573,12 +596,12 @@
     if ($Arg =~ /^-O/) { push @CompileOpts,$Arg; }
     next;
   }
-  
+
   if ($Arg =~ /^-std=/) {
     push @CompileOpts,$Arg;
     next;
   }
-  
+
   # Get the compiler/link mode.
   if ($Arg =~ /^-F(.+)$/) {
     my $Tmp = $Arg;
@@ -601,13 +624,13 @@
     ++$i;
     next;
   }
-  
+
   if ($Arg =~ /^-f/) {
     push @CompileOpts,$Arg;
     push @LinkOpts,$Arg;
     next;
   }
-  
+
   # Handle -Wno-.  We don't care about extra warnings, but
   # we should suppress ones that we don't want to see.
   if ($Arg =~ /^-Wno-/) {
@@ -636,7 +659,7 @@
         $FileLang = $LangMap{$1};
       }
     }
-    
+
     # FileLang still not defined?  Skip the file.
     next if (!defined $FileLang);
 
@@ -644,8 +667,8 @@
     next if (!defined $LangsAccepted{$FileLang});
 
     my @CmdArgs;
-    my @AnalyzeArgs;    
-    
+    my @AnalyzeArgs;
+
     if ($FileLang ne 'unknown') {
       push @CmdArgs, '-x', $FileLang;
     }
@@ -661,7 +684,7 @@
     if (defined $InternalStats) {
       push @AnalyzeArgs, "-analyzer-stats";
     }
-    
+
     if (defined $Analyses) {
       push @AnalyzeArgs, split '\s+', $Analyses;
     }
@@ -677,12 +700,15 @@
         my ($h, $f) = tempfile("report-XXXXXX", SUFFIX => ".plist",
                                DIR => $HtmlDir);
         $ResultFile = $f;
-        # If the HtmlDir is not set, we sould clean up the plist files.
+        # If the HtmlDir is not set, we should clean up the plist files.
         if (!defined $HtmlDir || -z $HtmlDir) {
           $CleanupFile = $f;
         }
       }
     }
+    if (defined $ConfigOptions) {
+      push @AnalyzeArgs, split '\s+', $ConfigOptions;
+    }
 
     push @CmdArgs, @CompileOpts;
     push @CmdArgs, $file;
@@ -704,4 +730,3 @@
 }
 
 exit($Status >> 8);
-
diff --git a/tools/scan-build/scan-build b/tools/scan-build/scan-build
index 0f119f6..153be2d 100755
--- a/tools/scan-build/scan-build
+++ b/tools/scan-build/scan-build
@@ -18,6 +18,8 @@
 use Digest::MD5;
 use File::Basename;
 use File::Find;
+use File::Copy qw(copy);
+use File::Path qw( rmtree mkpath );
 use Term::ANSIColor;
 use Term::ANSIColor qw(:constants);
 use Cwd qw/ getcwd abs_path /;
@@ -32,7 +34,7 @@
 my $UseColor = (defined $TERM and $TERM =~ 'xterm-.*color' and -t STDOUT
                 and defined $ENV{'SCAN_BUILD_COLOR'});
 
-# Portability: getpwuid is not implemented for Win32 (see Perl language 
+# Portability: getpwuid is not implemented for Win32 (see Perl language
 # reference, perlport), use getlogin instead.
 my $UserName = HtmlEscape(getlogin() || getpwuid($<) || 'unknown');
 my $HostName = HtmlEscape(hostname() || 'unknown');
@@ -57,7 +59,7 @@
   }
   else {
     print "$Prog: @_";
-  }  
+  }
 }
 
 sub ErrorDiag {
@@ -67,7 +69,7 @@
     print STDERR RESET;
   } else {
     print STDERR "$Prog: @_";
-  }  
+  }
 }
 
 sub DiagCrashes {
@@ -97,10 +99,10 @@
 if (grep /^--help-checkers$/, @ARGV) {
     my @options = qx($0 -h);
     foreach (@options) {
-	next unless /^ \+/;
-	s/^\s*//;
-	my ($sign, $name, @text) = split ' ', $_;
-	print $name, $/ if $sign eq '+';
+    next unless /^ \+/;
+    s/^\s*//;
+    my ($sign, $name, @text) = split ' ', $_;
+    print $name, $/ if $sign eq '+';
     }
     exit 0;
 }
@@ -118,20 +120,20 @@
 # GetHTMLRunDir - Construct an HTML directory name for the current sub-run.
 ##----------------------------------------------------------------------------##
 
-sub GetHTMLRunDir {  
-  die "Not enough arguments." if (@_ == 0);  
-  my $Dir = shift @_;    
+sub GetHTMLRunDir {
+  die "Not enough arguments." if (@_ == 0);
+  my $Dir = shift @_;
   my $TmpMode = 0;
   if (!defined $Dir) {
     $Dir = $ENV{'TMPDIR'} || $ENV{'TEMP'} || $ENV{'TMP'} || "/tmp";
     $TmpMode = 1;
   }
-  
+
   # Chop off any trailing '/' characters.
   while ($Dir =~ /\/$/) { chop $Dir; }
 
   # Get current date and time.
-  my @CurrentTime = localtime();  
+  my @CurrentTime = localtime();
   my $year  = $CurrentTime[5] + 1900;
   my $day   = $CurrentTime[3];
   my $month = $CurrentTime[4] + 1;
@@ -142,16 +144,16 @@
   my $TimeString = sprintf("%02d%02d%02d", $hour, $min, $sec);
   my $DateString = sprintf("%d-%02d-%02d-%s-$$",
                            $year, $month, $day, $TimeString);
-  
-  # Determine the run number.  
+
+  # Determine the run number.
   my $RunNumber;
-  
-  if (-d $Dir) {    
+
+  if (-d $Dir) {
     if (! -r $Dir) {
       DieDiag("directory '$Dir' exists but is not readable.\n");
-    }    
-    # Iterate over all files in the specified directory.    
-    my $max = 0;    
+    }
+    # Iterate over all files in the specified directory.
+    my $max = 0;
     opendir(DIR, $Dir);
     my @FILES = grep { -d "$Dir/$_" } readdir(DIR);
     closedir(DIR);
@@ -170,16 +172,16 @@
       next if ($x[2] != $day);
       next if ($x[3] != $TimeString);
       next if ($x[4] != $$);
-      
+
       if ($x[5] > $max) {
         $max = $x[5];
-      }      
+      }
     }
-    
+
     $RunNumber = $max + 1;
   }
   else {
-    
+
     if (-x $Dir) {
       DieDiag("'$Dir' exists but is not a directory.\n");
     }
@@ -188,14 +190,14 @@
       DieDiag("The directory '/tmp' does not exist or cannot be accessed.\n");
     }
 
-    # $Dir does not exist.  It will be automatically created by the 
-    # clang driver.  Set the run number to 1.  
+    # $Dir does not exist.  It will be automatically created by the
+    # clang driver.  Set the run number to 1.
 
     $RunNumber = 1;
   }
-  
+
   die "RunNumber must be defined!" if (!defined $RunNumber);
-  
+
   # Append the run number.
   my $NewDir;
   if ($TmpMode) {
@@ -204,29 +206,35 @@
   else {
     $NewDir = "$Dir/$DateString-$RunNumber";
   }
-  system 'mkdir','-p',$NewDir;
+
+  # Make sure that the directory does not exist in order to avoid hijack.
+  if (-e $NewDir) {
+      DieDiag("The directory '$NewDir' already exists.\n");
+  }
+
+  mkpath($NewDir);
   return $NewDir;
 }
 
 sub SetHtmlEnv {
-  
+
   die "Wrong number of arguments." if (scalar(@_) != 2);
-  
+
   my $Args = shift;
   my $Dir = shift;
-  
+
   die "No build command." if (scalar(@$Args) == 0);
-  
+
   my $Cmd = $$Args[0];
 
   if ($Cmd =~ /configure/ || $Cmd =~ /autogen/) {
     return;
   }
-  
+
   if ($Verbose) {
     Diag("Emitting reports for this run to '$Dir'.\n");
   }
-  
+
   $ENV{'CCC_ANALYZER_HTML'} = $Dir;
 }
 
@@ -236,18 +244,18 @@
 
 sub ComputeDigest {
   my $FName = shift;
-  DieDiag("Cannot read $FName to compute Digest.\n") if (! -r $FName);  
-  
+  DieDiag("Cannot read $FName to compute Digest.\n") if (! -r $FName);
+
   # Use Digest::MD5.  We don't have to be cryptographically secure.  We're
   # just looking for duplicate files that come from a non-malicious source.
   # We use Digest::MD5 because it is a standard Perl module that should
-  # come bundled on most systems.  
+  # come bundled on most systems.
   open(FILE, $FName) or DieDiag("Cannot open $FName when computing Digest.\n");
   binmode FILE;
   my $Result = Digest::MD5->new->addfile(*FILE)->hexdigest;
   close(FILE);
-  
-  # Return the digest.  
+
+  # Return the digest.
   return $Result;
 }
 
@@ -266,7 +274,7 @@
     $Prefix = $x;
     return;
   }
-  
+
   chop $Prefix while (!($x =~ /^\Q$Prefix/));
 }
 
@@ -293,7 +301,7 @@
 
   close (ROUT);
   close (RIN);
-  system("mv", "$fname.tmp", $fname);
+  rename("$fname.tmp", $fname)
 }
 
 ##----------------------------------------------------------------------------##
@@ -339,33 +347,34 @@
 my %AlreadyScanned;
 
 sub ScanFile {
-  
+
   my $Index = shift;
   my $Dir = shift;
   my $FName = shift;
   my $Stats = shift;
-  
+
   # Compute a digest for the report file.  Determine if we have already
   # scanned a file that looks just like it.
-  
+
   my $digest = ComputeDigest("$Dir/$FName");
 
   if (defined $AlreadyScanned{$digest}) {
     # Redundant file.  Remove it.
-    system ("rm", "-f", "$Dir/$FName");
+    unlink("$Dir/$FName");
     return;
   }
-  
+
   $AlreadyScanned{$digest} = 1;
-  
+
   # At this point the report file is not world readable.  Make it happen.
-  system ("chmod", "644", "$Dir/$FName");
-  
+  chmod(0644, "$Dir/$FName");
+
   # Scan the report file for tags.
   open(IN, "$Dir/$FName") or DieDiag("Cannot open '$Dir/$FName'\n");
 
   my $BugType        = "";
   my $BugFile        = "";
+  my $BugFunction    = "";
   my $BugCategory    = "";
   my $BugDescription = "";
   my $BugPathLength  = 1;
@@ -379,13 +388,17 @@
     }
     elsif (/<!-- BUGFILE (.*) -->$/) {
       $BugFile = abs_path($1);
+      if (!defined $BugFile) {
+         # The file no longer exists: use the original path.
+         $BugFile = $1;
+      }
       UpdatePrefix($BugFile);
     }
     elsif (/<!-- BUGPATHLENGTH (.*) -->$/) {
       $BugPathLength = $1;
     }
     elsif (/<!-- BUGLINE (.*) -->$/) {
-      $BugLine = $1;    
+      $BugLine = $1;
     }
     elsif (/<!-- BUGCATEGORY (.*) -->$/) {
       $BugCategory = $1;
@@ -393,10 +406,15 @@
     elsif (/<!-- BUGDESC (.*) -->$/) {
       $BugDescription = $1;
     }
+    elsif (/<!-- FUNCTIONNAME (.*) -->$/) {
+      $BugFunction = $1;
+    }
+
   }
 
+
   close(IN);
-  
+
   if (!defined $BugCategory) {
     $BugCategory = "Other";
   }
@@ -406,8 +424,8 @@
     AddStatLine($BugDescription, $Stats, $BugFile);
     return;
   }
-  
-  push @$Index,[ $FName, $BugCategory, $BugType, $BugFile, $BugLine,
+
+  push @$Index,[ $FName, $BugCategory, $BugType, $BugFile, $BugFunction, $BugLine,
                  $BugPathLength ];
 }
 
@@ -420,21 +438,21 @@
   my $Dir = shift;
 
   my $JS = Cwd::realpath("$RealBin/sorttable.js");
-  
-  DieDiag("Cannot find 'sorttable.js'.\n")
-    if (! -r $JS);  
 
-  system ("cp", $JS, "$Dir");
+  DieDiag("Cannot find 'sorttable.js'.\n")
+    if (! -r $JS);
+
+  copy($JS, "$Dir");
 
   DieDiag("Could not copy 'sorttable.js' to '$Dir'.\n")
     if (! -r "$Dir/sorttable.js");
-    
+
   my $CSS = Cwd::realpath("$RealBin/scanview.css");
-  
+
   DieDiag("Cannot find 'scanview.css'.\n")
     if (! -r $CSS);
 
-  system ("cp", $CSS, "$Dir");
+  copy($CSS, "$Dir");
 
   DieDiag("Could not copy 'scanview.css' to '$Dir'.\n")
     if (! -r $CSS);
@@ -493,9 +511,11 @@
 
 my @filesFound;
 my $baseDir;
-sub FileWanted { 
+sub FileWanted {
     my $baseDirRegEx = quotemeta $baseDir;
     my $file = $File::Find::name;
+
+    # The name of the file is generated by clang binary (HTMLDiagnostics.cpp)
     if ($file =~ /report-.*\.html$/) {
        my $relative_file = $file;
        $relative_file =~ s/$baseDirRegEx//g;
@@ -504,14 +524,14 @@
 }
 
 sub Postprocess {
-  
+
   my $Dir           = shift;
   my $BaseDir       = shift;
   my $AnalyzerStats = shift;
   my $KeepEmpty     = shift;
-  
+
   die "No directory specified." if (!defined $Dir);
-  
+
   if (! -d $Dir) {
     Diag("No bugs found.\n");
     return 0;
@@ -523,17 +543,17 @@
   if (scalar(@filesFound) == 0 and ! -e "$Dir/failures") {
     if (! $KeepEmpty) {
       Diag("Removing directory '$Dir' because it contains no reports.\n");
-      system ("rm", "-fR", $Dir);
+      rmtree($Dir) or die "Cannot rmtree '$Dir' : $!";
     }
     Diag("No bugs found.\n");
     return 0;
   }
-  
-  # Scan each report file and build an index.  
+
+  # Scan each report file and build an index.
   my @Index;
   my @Stats;
   foreach my $file (@filesFound) { ScanFile(\@Index, $Dir, $file, \@Stats); }
-  
+
   # Scan the failures directory and use the information in the .info files
   # to update the common prefix directory.
   my @failures;
@@ -542,7 +562,7 @@
     opendir(DIR, "$Dir/failures");
     @failures = grep { /[.]info.txt$/ && !/attribute_ignored/; } readdir(DIR);
     closedir(DIR);
-    opendir(DIR, "$Dir/failures");        
+    opendir(DIR, "$Dir/failures");
     @attributes_ignored = grep { /^attribute_ignored/; } readdir(DIR);
     closedir(DIR);
     foreach my $file (@failures) {
@@ -550,15 +570,15 @@
       my $Path = <IN>;
       if (defined $Path) { UpdatePrefix($Path); }
       close IN;
-    }    
+    }
   }
-  
-  # Generate an index.html file.  
-  my $FName = "$Dir/index.html";  
+
+  # Generate an index.html file.
+  my $FName = "$Dir/index.html";
   open(OUT, ">", $FName) or DieDiag("Cannot create file '$FName'\n");
-  
+
   # Print out the header.
-  
+
 print OUT <<ENDTEXT;
 <html>
 <head>
@@ -583,19 +603,19 @@
       if(Inputs[i] != SummaryCheckButton) {
         Inputs[i].checked = SummaryCheckButton.checked;
         Inputs[i].onclick();
-	  }
+      }
     }
   }
 }
 
 function returnObjById( id ) {
-    if (document.getElementById) 
+    if (document.getElementById)
         var returnVar = document.getElementById(id);
     else if (document.all)
         var returnVar = document.all[id];
-    else if (document.layers) 
+    else if (document.layers)
         var returnVar = document.layers[id];
-    return returnVar; 
+    return returnVar;
 }
 
 var NumUnchecked = 0;
@@ -652,14 +672,14 @@
     if (defined $BuildName) {
       print OUT "\n<p>Results in this analysis run are based on analyzer build <b>$BuildName</b>.</p>\n"
     }
-  
+
   my $TotalBugs = scalar(@Index);
 print OUT <<ENDTEXT;
 <table>
 <thead><tr><td>Bug Type</td><td>Quantity</td><td class="sorttable_nosort">Display?</td></tr></thead>
 <tr style="font-weight:bold"><td class="SUMM_DESC">All Bugs</td><td class="Q">$TotalBugs</td><td><center><input type="checkbox" id="AllBugsCheck" onClick="CopyCheckedStateToCheckButtons(this);" checked/></center></td></tr>
 ENDTEXT
-  
+
     my $last_category;
 
     for my $key (
@@ -669,14 +689,14 @@
         my $res = $x->[1] cmp $y->[1];
         $res = $x->[2] cmp $y->[2] if ($res == 0);
         $res
-      } keys %Totals ) 
+      } keys %Totals )
     {
       my $val = $Totals{$key};
       my $category = $val->[1];
       if (!defined $last_category or $last_category ne $category) {
         $last_category = $category;
         print OUT "<tr><th>$category</th><th colspan=2></th></tr>\n";
-      }      
+      }
       my $x = lc $key;
       $x =~ s/[ ,'":\/()]+/_/g;
       print OUT "<tr><td class=\"SUMM_DESC\">";
@@ -697,6 +717,7 @@
   <td>Bug Group</td>
   <td class="sorttable_sorted">Bug Type<span id="sorttable_sortfwdind">&nbsp;&#x25BE;</span></td>
   <td>File</td>
+  <td>Function/Method</td>
   <td class="Q">Line</td>
   <td class="Q">Path Length</td>
   <td class="sorttable_nosort"></td>
@@ -709,19 +730,19 @@
     my $regex;
     my $InFileRegex;
     my $InFilePrefix = "File:</td><td>";
-  
-    if (defined $prefix) { 
-      $regex = qr/^\Q$prefix\E/is;    
+
+    if (defined $prefix) {
+      $regex = qr/^\Q$prefix\E/is;
       $InFileRegex = qr/\Q$InFilePrefix$prefix\E/is;
-    }    
+    }
 
     for my $row ( sort { $a->[2] cmp $b->[2] } @Index ) {
       my $x = "$row->[1]:$row->[2]";
       $x = lc $x;
       $x =~ s/[ ,'":\/()]+/_/g;
-    
+
       my $ReportFile = $row->[0];
-          
+
       print OUT "<tr class=\"bt_$x\">";
       print OUT "<td class=\"DESC\">";
       print OUT $row->[1];
@@ -729,16 +750,16 @@
       print OUT "<td class=\"DESC\">";
       print OUT $row->[2];
       print OUT "</td>";
-      
-      # Update the file prefix.      
+
+      # Update the file prefix.
       my $fname = $row->[3];
 
       if (defined $regex) {
         $fname =~ s/$regex//;
         UpdateInFilePath("$Dir/$ReportFile", $InFileRegex, $InFilePrefix)
       }
-      
-      print OUT "<td>";      
+
+      print OUT "<td>";
       my @fname = split /\//,$fname;
       if ($#fname > 0) {
         while ($#fname >= 0) {
@@ -751,35 +772,39 @@
       }
       else {
         print OUT $fname;
-      }      
-      print OUT "</td>";
-      
-      # Print out the quantities.
-      for my $j ( 4 .. 5 ) {
-        print OUT "<td class=\"Q\">$row->[$j]</td>";        
       }
-      
+      print OUT "</td>";
+
+      print OUT "<td class=\"DESC\">";
+      print OUT $row->[4];
+      print OUT "</td>";
+
+      # Print out the quantities.
+      for my $j ( 5 .. 6 ) {
+        print OUT "<td class=\"Q\">$row->[$j]</td>";
+      }
+
       # Print the rest of the columns.
-      for (my $j = 6; $j <= $#{$row}; ++$j) {
+      for (my $j = 7; $j <= $#{$row}; ++$j) {
         print OUT "<td>$row->[$j]</td>"
       }
 
       # Emit the "View" link.
       print OUT "<td><a href=\"$ReportFile#EndPath\">View Report</a></td>";
-        
+
       # Emit REPORTBUG markers.
       print OUT "\n<!-- REPORTBUG id=\"$ReportFile\" -->\n";
-        
+
       # End the row.
       print OUT "</tr>\n";
     }
-  
+
     print OUT "</tbody>\n</table>\n\n";
   }
 
   if (scalar (@failures) || scalar(@attributes_ignored)) {
     print OUT "<h2>Analyzer Failures</h2>\n";
-    
+
     if (scalar @attributes_ignored) {
       print OUT "The analyzer's parser ignored the following attributes:<p>\n";
       print OUT "<table>\n";
@@ -809,7 +834,7 @@
       }
       print OUT "</table>\n";
     }
-    
+
     if (scalar @failures) {
       print OUT "<p>The analyzer had problems processing the following files:</p>\n";
       print OUT "<table>\n";
@@ -835,29 +860,33 @@
         print OUT "  <!-- REPORTPROBLEM src=\"$srcfile\" file=\"failures/$ppfile\" clangfile=\"failures/$ppfile_clang\" stderr=\"failures/$ppfile.stderr.txt\" info=\"failures/$ppfile.info.txt\" -->\n";
       }
       print OUT "</table>\n";
-    }    
+    }
     print OUT "<p>Please consider submitting preprocessed files as <a href=\"http://clang-analyzer.llvm.org/filing_bugs.html\">bug reports</a>. <!-- REPORTCRASHES --> </p>\n";
   }
-  
-  print OUT "</body></html>\n";  
+
+  print OUT "</body></html>\n";
   close(OUT);
   CopyFiles($Dir);
 
   # Make sure $Dir and $BaseDir are world readable/executable.
-  system("chmod", "755", $Dir);
-  if (defined $BaseDir) { system("chmod", "755", $BaseDir); }
+  chmod(0755, $Dir);
+  if (defined $BaseDir) { chmod(0755, $BaseDir); }
 
   # Print statistics
   print CalcStats(\@Stats) if $AnalyzerStats;
 
   my $Num = scalar(@Index);
-  Diag("$Num bugs found.\n");
+  if ($Num == 1) {
+    Diag("$Num bug found.\n");
+  } else {
+    Diag("$Num bugs found.\n");
+  }
   if ($Num > 0 && -r "$Dir/index.html") {
     Diag("Run 'scan-view $Dir' to examine bug reports.\n");
   }
-  
+
   DiagCrashes($Dir) if (scalar @failures || scalar @attributes_ignored);
-  
+
   return $Num;
 }
 
@@ -867,16 +896,16 @@
 
 sub AddIfNotPresent {
   my $Args = shift;
-  my $Arg = shift;  
+  my $Arg = shift;
   my $found = 0;
-  
+
   foreach my $k (@$Args) {
     if ($k eq $Arg) {
       $found = 1;
       last;
     }
   }
-  
+
   if ($found == 0) {
     push @$Args, $Arg;
   }
@@ -885,7 +914,8 @@
 sub SetEnv {
   my $Options = shift @_;
   foreach my $opt ('CC', 'CXX', 'CLANG', 'CLANG_CXX',
-                    'CCC_ANALYZER_ANALYSIS', 'CCC_ANALYZER_PLUGINS') {
+                    'CCC_ANALYZER_ANALYSIS', 'CCC_ANALYZER_PLUGINS',
+                    'CCC_ANALYZER_CONFIG') {
     die "$opt is undefined\n" if (!defined $opt);
     $ENV{$opt} = $Options->{$opt};
   }
@@ -906,7 +936,7 @@
 }
 
 # The flag corresponding to the --override-compiler command line option.
-my $OverrideCompiler = 0; 
+my $OverrideCompiler = 0;
 
 sub RunXcodebuild {
   my $Args = shift;
@@ -939,13 +969,13 @@
     }
   }
   close(DETECT_XCODE);
-  
-  # If --override-compiler is explicitely requested, resort to the old 
+
+  # If --override-compiler is explicitely requested, resort to the old
   # behavior regardless of Xcode version.
   if ($OverrideCompiler) {
     $oldBehavior = 1;
   }
-  
+
   if ($oldBehavior == 0) {
     my $OutputDir = $Options->{"OUTPUT_DIR"};
     my $CLANG = $Options->{"CLANG"};
@@ -959,10 +989,10 @@
 
     return (system(@$Args) >> 8);
   }
-  
+
   # Default to old behavior where we insert a bogus compiler.
   SetEnv($Options);
-  
+
   # Check if using iPhone SDK 3.0 (simulator).  If so the compiler being
   # used should be gcc-4.2.
   if (!defined $ENV{"CCC_CC"}) {
@@ -978,16 +1008,16 @@
 
   # Disable PCH files until clang supports them.
   AddIfNotPresent($Args,"GCC_PRECOMPILE_PREFIX_HEADER=NO");
-  
+
   # When 'CC' is set, xcodebuild uses it to do all linking, even if we are
   # linking C++ object files.  Set 'LDPLUSPLUS' so that xcodebuild uses 'g++'
   # (via c++-analyzer) when linking such files.
   $ENV{"LDPLUSPLUS"} = $CXXAnalyzer;
- 
-  return (system(@$Args) >> 8); 
+
+  return (system(@$Args) >> 8);
 }
 
-sub RunBuildCommand {  
+sub RunBuildCommand {
   my $Args = shift;
   my $IgnoreErrors = shift;
   my $Cmd = $Args->[0];
@@ -1001,28 +1031,28 @@
 
   # Setup the environment.
   SetEnv($Options);
-  
-  if ($Cmd =~ /(.*\/?gcc[^\/]*$)/ or 
+
+  if ($Cmd =~ /(.*\/?gcc[^\/]*$)/ or
       $Cmd =~ /(.*\/?cc[^\/]*$)/ or
       $Cmd =~ /(.*\/?llvm-gcc[^\/]*$)/ or
-      $Cmd =~ /(.*\/?clang$)/ or 
+      $Cmd =~ /(.*\/?clang$)/ or
       $Cmd =~ /(.*\/?ccc-analyzer[^\/]*$)/) {
 
     if (!($Cmd =~ /ccc-analyzer/) and !defined $ENV{"CCC_CC"}) {
-      $ENV{"CCC_CC"} = $1;      
+      $ENV{"CCC_CC"} = $1;
     }
-        
+
     shift @$Args;
     unshift @$Args, $CCAnalyzer;
   }
-  elsif ($Cmd =~ /(.*\/?g\+\+[^\/]*$)/ or 
+  elsif ($Cmd =~ /(.*\/?g\+\+[^\/]*$)/ or
         $Cmd =~ /(.*\/?c\+\+[^\/]*$)/ or
         $Cmd =~ /(.*\/?llvm-g\+\+[^\/]*$)/ or
         $Cmd =~ /(.*\/?clang\+\+$)/ or
         $Cmd =~ /(.*\/?c\+\+-analyzer[^\/]*$)/) {
     if (!($Cmd =~ /c\+\+-analyzer/) and !defined $ENV{"CCC_CXX"}) {
-      $ENV{"CCC_CXX"} = $1;      
-    }        
+      $ENV{"CCC_CXX"} = $1;
+    }
     shift @$Args;
     unshift @$Args, $CXXAnalyzer;
   }
@@ -1033,7 +1063,7 @@
       AddIfNotPresent($Args,"-k");
       AddIfNotPresent($Args,"-i");
     }
-  } 
+  }
 
   return (system(@$Args) >> 8);
 }
@@ -1043,7 +1073,7 @@
 ##----------------------------------------------------------------------------##
 
 sub DisplayHelp {
-  
+
 print <<ENDTEXT;
 USAGE: $Prog [options] <build command> [build options]
 
@@ -1057,25 +1087,25 @@
 OPTIONS:
 
  -analyze-headers
- 
+
    Also analyze functions in #included files.  By default, such functions
    are skipped unless they are called by functions within the main source file.
- 
+
  -o <output location>
-  
+
    Specifies the output directory for analyzer reports. Subdirectories will be
    created as needed to represent separate "runs" of the analyzer. If this
    option is not specified, a directory is created in /tmp (TMPDIR on Mac OS X)
    to store the reports.
 
- -h             
+ -h
  --help
 
    Display this message.
 
  -k
  --keep-going
-				  
+
    Add a "keep on going" option to the specified build command. This option
    currently supports make and xcodebuild. This is a convenience option; one
    can specify this behavior directly using build options.
@@ -1087,41 +1117,41 @@
    title will be used.
 
  -plist
- 
+
    By default the output of scan-build is a set of HTML files. This option
    outputs the results as a set of .plist files.
- 
+
  -plist-html
- 
+
    By default the output of scan-build is a set of HTML files. This option
    outputs the results as a set of HTML and .plist files.
- 
+
  --status-bugs
- 
+
    By default, the exit status of scan-build is the same as the executed build
    command. Specifying this option causes the exit status of scan-build to be 1
    if it found potential bugs and 0 otherwise.
 
- --use-cc [compiler path]   
+ --use-cc [compiler path]
  --use-cc=[compiler path]
-  
+
    scan-build analyzes a project by interposing a "fake compiler", which
    executes a real compiler for compilation and the static analyzer for analysis.
    Because of the current implementation of interposition, scan-build does not
    know what compiler your project normally uses.  Instead, it simply overrides
    the CC environment variable, and guesses your default compiler.
-   
+
    In the future, this interposition mechanism to be improved, but if you need
    scan-build to use a specific compiler for *compilation* then you can use
    this option to specify a path to that compiler.
 
  --use-c++ [compiler path]
  --use-c++=[compiler path]
- 
+
    This is the same as "-use-cc" but for C++ code.
- 
+
  -v
- 
+
    Enable verbose output from scan-build. A second and third '-v' increases
    verbosity.
 
@@ -1133,26 +1163,26 @@
 ADVANCED OPTIONS:
 
  -no-failure-reports
- 
+
    Do not create a 'failures' subdirectory that includes analyzer crash reports
    and preprocessed source files.
 
  -stats
- 
+
    Generates visitation statistics for the project being analyzed.
 
  -maxloop <loop count>
- 
+
    Specifiy the number of times a block can be visited before giving up.
    Default is 4. Increase for more comprehensive coverage at a cost of speed.
-  
+
  -internal-stats
- 
+
    Generate internal analyzer statistics.
- 
- --use-analyzer [Xcode|path to clang] 
+
+ --use-analyzer [Xcode|path to clang]
  --use-analyzer=[Xcode|path to clang]
- 
+
    scan-build 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.
@@ -1161,10 +1191,21 @@
 
    Don't remove the build results directory even if no issues were reported.
 
- --override-compiler 
-   Always resort to the ccc-analyzer even when better interposition methods 
+ --override-compiler
+   Always resort to the ccc-analyzer even when better interposition methods
    are available.
-   
+
+ -analyzer-config <options>
+
+   Provide options to pass through to the analyzer's -analyzer-config flag.
+   Several options are separated with comma: 'key1=val1,key2=val2'
+
+   Available options:
+     * stable-report-filename=true or false (default)
+       Switch the page naming to:
+       report-<filename>-<function/method name>-<id>.html
+       instead of report-XXXXXX.html
+
 CONTROLLING CHECKERS:
 
  A default group of checkers are always run unless explicitly disabled.
@@ -1172,7 +1213,7 @@
 
  -enable-checker [checker name]
  -disable-checker [checker name]
- 
+
 LOADING CHECKERS:
 
  Loading external checkers using the clang plugin interface:
@@ -1197,7 +1238,7 @@
     close FROM_CHILD;
     open(STDOUT,">&", \*TO_PARENT);
     open(STDERR,">&", \*TO_PARENT);
-    exec $Clang, ( @PluginLoadCommandline_xclang, '--analyze', '-x', $lang, '-', '-###'); 
+    exec $Clang, ( @PluginLoadCommandline_xclang, '--analyze', '-x', $lang, '-', '-###');
   }
   close(TO_PARENT);
   while(<FROM_CHILD>) {
@@ -1260,7 +1301,7 @@
           # append a dot, if an additional domain is added in the next iteration
           $aggregate .= ".";
         }
-      
+
         if ($enabled) {
           print " + ";
         }
@@ -1288,7 +1329,7 @@
 EXAMPLE
 
  scan-build -o /tmp/myhtmldir make -j4
-     
+
 The above example causes analysis reports to be deposited into a subdirectory
 of "/tmp/myhtmldir" and to run "make" with the "-j4" option. A different
 subdirectory is created each time scan-build analyzes a project. The analyzer
@@ -1336,6 +1377,7 @@
 my $StoreModel;
 my $ConstraintsModel;
 my $InternalStats;
+my @ConfigOptions;
 my $OutputFormat = "html";
 my $AnalyzerStats = 0;
 my $MaxLoop = 0;
@@ -1348,9 +1390,9 @@
 }
 
 while (@ARGV) {
-  
+
   # Scan for options we recognize.
-  
+
   my $arg = $ARGV[0];
 
   if ($arg eq "-h" or $arg eq "--help") {
@@ -1358,24 +1400,24 @@
     shift @ARGV;
     next;
   }
-  
+
   if ($arg eq '-analyze-headers') {
-    shift @ARGV;    
+    shift @ARGV;
     $AnalyzeHeaders = 1;
     next;
   }
-  
+
   if ($arg eq "-o") {
     shift @ARGV;
-        
+
     if (!@ARGV) {
       DieDiag("'-o' option requires a target directory name.\n");
     }
-    
+
     # Construct an absolute path.  Uses the current working directory
     # as a base if the original path was not absolute.
     $HtmlDir = abs_path(shift @ARGV);
-    
+
     next;
   }
 
@@ -1394,7 +1436,7 @@
 
     next;
   }
-  
+
   if ($arg eq "-k" or $arg eq "--keep-going") {
     shift @ARGV;
     $IgnoreErrors = 1;
@@ -1404,7 +1446,7 @@
   if ($arg =~ /^--use-cc(=(.+))?$/) {
     shift @ARGV;
     my $cc;
-    
+
     if (!defined $2 || $2 eq "") {
       if (!@ARGV) {
         DieDiag("'--use-cc' option requires a compiler executable name.\n");
@@ -1414,15 +1456,15 @@
     else {
       $cc = $2;
     }
-    
+
     $ENV{"CCC_CC"} = $cc;
     next;
   }
-  
+
   if ($arg =~ /^--use-c\+\+(=(.+))?$/) {
     shift @ARGV;
-    my $cxx;    
-    
+    my $cxx;
+
     if (!defined $2 || $2 eq "") {
       if (!@ARGV) {
         DieDiag("'--use-c++' option requires a compiler executable name.\n");
@@ -1432,23 +1474,23 @@
     else {
       $cxx = $2;
     }
-    
+
     $ENV{"CCC_CXX"} = $cxx;
     next;
   }
-  
+
   if ($arg eq "-v") {
     shift @ARGV;
     $Verbose++;
     next;
   }
-  
+
   if ($arg eq "-V" or $arg eq "--view") {
     shift @ARGV;
-    $ViewResults = 1;    
+    $ViewResults = 1;
     next;
   }
-  
+
   if ($arg eq "--status-bugs") {
     shift @ARGV;
     $ExitStatusFoundBugs = 1;
@@ -1460,7 +1502,7 @@
     $StoreModel = shift @ARGV;
     next;
   }
-  
+
   if ($arg eq "-constraints") {
     shift @ARGV;
     $ConstraintsModel = shift @ARGV;
@@ -1472,7 +1514,7 @@
     $InternalStats = 1;
     next;
   }
-  
+
   if ($arg eq "-plist") {
     shift @ARGV;
     $OutputFormat = "plist";
@@ -1483,7 +1525,13 @@
     $OutputFormat = "plist-html";
     next;
   }
-  
+
+  if ($arg eq "-analyzer-config") {
+    shift @ARGV;
+    push @ConfigOptions, "-analyzer-config", shift @ARGV;
+    next;
+  }
+
   if ($arg eq "-no-failure-reports") {
     $ENV{"CCC_REPORT_FAILURES"} = 0;
     next;
@@ -1514,14 +1562,14 @@
     next;
   }
   if ($arg eq "--use-analyzer") {
- 	shift @ARGV;
-  	$AnalyzerDiscoveryMethod = shift @ARGV;
-	next;
+     shift @ARGV;
+      $AnalyzerDiscoveryMethod = shift @ARGV;
+    next;
   }
   if ($arg =~ /^--use-analyzer=(.+)$/) {
     shift @ARGV;
-	$AnalyzerDiscoveryMethod = $1;
-	next;
+    $AnalyzerDiscoveryMethod = $1;
+    next;
   }
   if ($arg eq "--keep-empty") {
     shift @ARGV;
@@ -1534,9 +1582,9 @@
     $OverrideCompiler = 1;
     next;
   }
-  
+
   DieDiag("unrecognized option '$arg'\n") if ($arg =~ /^-/);
-  
+
   last;
 }
 
@@ -1554,28 +1602,28 @@
   if (!defined $Clang || ! -x $Clang) {
     if (!$RequestDisplayHelp && !$ForceDisplayHelp) {
       DieDiag("error: Cannot find an executable 'clang' relative to scan-build." .
-   	          "  Consider using --use-analyzer to pick a version of 'clang' to use for static analysis.\n");
+                 "  Consider using --use-analyzer to pick a version of 'clang' to use for static analysis.\n");
     }
   }
-} 
-else {  
+}
+else {
   if ($AnalyzerDiscoveryMethod =~ /^[Xx]code$/) {
-	my $xcrun = `which xcrun`;
+    my $xcrun = `which xcrun`;
     chomp $xcrun;
-	if ($xcrun eq "") {
-  	  DieDiag("Cannot find 'xcrun' to find 'clang' for analysis.\n");
-	}
+    if ($xcrun eq "") {
+        DieDiag("Cannot find 'xcrun' to find 'clang' for analysis.\n");
+    }
     $Clang = `$xcrun -toolchain XcodeDefault -find clang`;
-    chomp $Clang;  
+    chomp $Clang;
     if ($Clang eq "") {
-      DieDiag("No 'clang' executable found by 'xcrun'\n"); 
+      DieDiag("No 'clang' executable found by 'xcrun'\n");
     }
   }
   else {
-    $Clang = Cwd::realpath($AnalyzerDiscoveryMethod);
-	if (!defined $Clang or not -x $Clang) {
-   	  DieDiag("Cannot find an executable clang at '$AnalyzerDiscoveryMethod'\n");
-	}
+    $Clang = $AnalyzerDiscoveryMethod;
+    if (!defined $Clang or not -x $Clang) {
+         DieDiag("Cannot find an executable clang at '$AnalyzerDiscoveryMethod'\n");
+    }
   }
 }
 
@@ -1612,9 +1660,9 @@
 my $Cmd = "$AbsRealBin/libexec/ccc-analyzer";
 my $CmdCXX = "$AbsRealBin/libexec/c++-analyzer";
 
-# Portability: use less strict but portable check -e (file exists) instead of 
+# Portability: use less strict but portable check -e (file exists) instead of
 # non-portable -x (file is executable). On some windows ports -x just checks
-# file extension to determine if a file is executable (see Perl language 
+# file extension to determine if a file is executable (see Perl language
 # reference, perlport)
 if (!defined $Cmd || ! -e $Cmd) {
   $Cmd = "$AbsRealBin/ccc-analyzer";
@@ -1636,6 +1684,7 @@
 # interposition.
 my $CCC_ANALYZER_ANALYSIS = join ' ',@AnalysesToRun;
 my $CCC_ANALYZER_PLUGINS = join ' ',@PluginsToLoad;
+my $CCC_ANALYZER_CONFIG = join ' ',@ConfigOptions;
 my %Options = (
   'CC' => $Cmd,
   'CXX' => $CmdCXX,
@@ -1644,6 +1693,7 @@
   'VERBOSE' => $Verbose,
   'CCC_ANALYZER_ANALYSIS' => $CCC_ANALYZER_ANALYSIS,
   'CCC_ANALYZER_PLUGINS' => $CCC_ANALYZER_PLUGINS,
+  'CCC_ANALYZER_CONFIG' => $CCC_ANALYZER_CONFIG,
   'OUTPUT_DIR' => $HtmlDir
 );
 
@@ -1689,4 +1739,3 @@
 }
 
 exit $ExitStatus;
-
diff --git a/tools/scan-build/scan-build.1 b/tools/scan-build/scan-build.1
index 10ddc7f..3d3a9f8 100644
--- a/tools/scan-build/scan-build.1
+++ b/tools/scan-build/scan-build.1
@@ -3,7 +3,7 @@
 .\" $Id$
 .Dd May 25, 2012
 .Dt SCAN-BUILD 1
-.Os "clang" "3.1"
+.Os "clang" "3.5"
 .Sh NAME
 .Nm scan-build
 .Nd Clang static analyzer
diff --git a/tools/scan-build/scanview.css b/tools/scan-build/scanview.css
index a0406f3..cf8a5a6 100644
--- a/tools/scan-build/scanview.css
+++ b/tools/scan-build/scanview.css
@@ -10,7 +10,7 @@
   text-align:center;
   font-weight: bold; font-family: Verdana;
   white-space:nowrap;
-} 
+}
 .W { font-size:0px }
 th, td { padding:5px; padding-left:8px; text-align:left }
 td.SUMM_DESC { padding-left:12px }
@@ -21,7 +21,7 @@
 
 table.form_group {
     background-color: #ccc;
-    border: 1px solid #333; 
+    border: 1px solid #333;
     padding: 2px;
 }
 
@@ -33,7 +33,7 @@
 
 table.form {
     background-color: #999;
-    border: 1px solid #333; 
+    border: 1px solid #333;
     padding: 2px;
 }
 
diff --git a/tools/scan-build/set-xcode-analyzer b/tools/scan-build/set-xcode-analyzer
index 3076b39..8e67482 100755
--- a/tools/scan-build/set-xcode-analyzer
+++ b/tools/scan-build/set-xcode-analyzer
@@ -8,7 +8,7 @@
 if sys.version_info < (2, 7):
     print "set-xcode-analyzer requires Python 2.7 or later"
     sys.exit(1)
-    
+
 import os
 import subprocess
 import re
@@ -65,7 +65,7 @@
   parser.set_description(__doc__)
   parser.add_option("--use-checker-build", dest="path",
                     help="Use the Clang located at the provided absolute path, e.g. /Users/foo/checker-1")
-  parser.add_option("--use-xcode-clang", action="store_const", 
+  parser.add_option("--use-xcode-clang", action="store_const",
                     const="$(CLANG)", dest="default",
                     help="Use the Clang bundled with Xcode")
   (options, args) = parser.parse_args()
@@ -91,7 +91,7 @@
     print "(+) Using the Clang bundled with Xcode"
     path = options.default
     isBuiltinAnalyzer = True
-  
+
   try:
     xcode_path = subprocess.check_output(["xcode-select", "-print-path"])
   except AttributeError:
@@ -100,16 +100,15 @@
   if (xcode_path.find(".app/") != -1):
     # Cut off the 'Developer' dir, as the xcspec lies in another part
     # of the Xcode.app subtree.
-    xcode_path = os.path.dirname(xcode_path)
-  
+    xcode_path = xcode_path.rsplit('/Developer', 1)[0]
+
   foundSpec = False
   for x in FindClangSpecs(xcode_path):
     foundSpec = True
     ModifySpec(x, isBuiltinAnalyzer, path)
-    
+
   if foundSpec == False:
       print "(-) No compiler configuration file was found.  Xcode's analyzer has not been updated."
 
 if __name__ == '__main__':
   main()
-
diff --git a/tools/scan-build/sorttable.js b/tools/scan-build/sorttable.js
index 4352d3b..32faa07 100644
--- a/tools/scan-build/sorttable.js
+++ b/tools/scan-build/sorttable.js
@@ -3,19 +3,19 @@
   version 2
   7th April 2007
   Stuart Langridge, http://www.kryogenix.org/code/browser/sorttable/
-  
+
   Instructions:
   Download this file
   Add <script src="sorttable.js"></script> to your HTML
   Add class="sortable" to any table you'd like to make sortable
   Click on the headers to sort
-  
+
   Thanks to many, many people for contributions and suggestions.
   Licenced as X11: http://www.kryogenix.org/code/browser/licence.html
   This basically means: do what you want with it.
 */
 
- 
+
 var stIsIE = /*@cc_on!@*/false;
 
 sorttable = {
@@ -26,19 +26,19 @@
     arguments.callee.done = true;
     // kill the timer
     if (_timer) clearInterval(_timer);
-    
+
     if (!document.createElement || !document.getElementsByTagName) return;
-    
+
     sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/;
-    
+
     forEach(document.getElementsByTagName('table'), function(table) {
       if (table.className.search(/\bsortable\b/) != -1) {
         sorttable.makeSortable(table);
       }
     });
-    
+
   },
-  
+
   makeSortable: function(table) {
     if (table.getElementsByTagName('thead').length == 0) {
       // table doesn't have a tHead. Since it should have, create one and
@@ -49,13 +49,13 @@
     }
     // Safari doesn't support table.tHead, sigh
     if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0];
-    
+
     if (table.tHead.rows.length != 1) return; // can't cope with two header rows
-    
+
     // Sorttable v1 put rows with a class of "sortbottom" at the bottom (as
     // "total" rows, for example). This is B&R, since what you're supposed
     // to do is put them in a tfoot. So, if there are sortbottom rows,
-    // for backwards compatibility, move them to tfoot (creating it if needed).
+    // for backward compatibility, move them to tfoot (creating it if needed).
     sortbottomrows = [];
     for (var i=0; i<table.rows.length; i++) {
       if (table.rows[i].className.search(/\bsortbottom\b/) != -1) {
@@ -73,7 +73,7 @@
       }
       delete sortbottomrows;
     }
-    
+
     // work through each column and calculate its type
     headrow = table.tHead.rows[0].cells;
     for (var i=0; i<headrow.length; i++) {
@@ -92,7 +92,7 @@
 	      dean_addEvent(headrow[i],"click", function(e) {
 
           if (this.className.search(/\bsorttable_sorted\b/) != -1) {
-            // if we're already sorted by this column, just 
+            // if we're already sorted by this column, just
             // reverse the table, which is quicker
             sorttable.reverse(this.sorttable_tbody);
             this.className = this.className.replace('sorttable_sorted',
@@ -105,7 +105,7 @@
             return;
           }
           if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) {
-            // if we're already sorted by this column in reverse, just 
+            // if we're already sorted by this column in reverse, just
             // re-reverse the table, which is quicker
             sorttable.reverse(this.sorttable_tbody);
             this.className = this.className.replace('sorttable_sorted_reverse',
@@ -117,7 +117,7 @@
             this.appendChild(sortfwdind);
             return;
           }
-          
+
           // remove sorttable_sorted classes
           theadrow = this.parentNode;
           forEach(theadrow.childNodes, function(cell) {
@@ -130,7 +130,7 @@
           if (sortfwdind) { sortfwdind.parentNode.removeChild(sortfwdind); }
           sortrevind = document.getElementById('sorttable_sortrevind');
           if (sortrevind) { sortrevind.parentNode.removeChild(sortrevind); }
-          
+
           this.className += ' sorttable_sorted';
           sortfwdind = document.createElement('span');
           sortfwdind.id = "sorttable_sortfwdind";
@@ -151,18 +151,18 @@
 	        sorttable.shaker_sort(row_array, this.sorttable_sortfunction);
 	        /* and comment out this one */
 	        //row_array.sort(this.sorttable_sortfunction);
-	        
+
 	        tb = this.sorttable_tbody;
 	        for (var j=0; j<row_array.length; j++) {
 	          tb.appendChild(row_array[j][1]);
 	        }
-	        
+
 	        delete row_array;
 	      });
 	    }
     }
   },
-  
+
   guessType: function(table, column) {
     // guess the type of a column based on its first non-blank row
     sortfn = sorttable.sort_alpha;
@@ -172,7 +172,7 @@
         if (text.match(/^-?[£$¤]?[\d,.]+%?$/)) {
           return sorttable.sort_numeric;
         }
-        // check for a date: dd/mm/yyyy or dd/mm/yy 
+        // check for a date: dd/mm/yyyy or dd/mm/yy
         // can have / or . or - as separator
         // can be mm/dd as well
         possdate = text.match(sorttable.DATE_RE)
@@ -195,17 +195,17 @@
     }
     return sortfn;
   },
-  
+
   getInnerText: function(node) {
     // gets the text we want to use for sorting for a cell.
     // strips leading and trailing whitespace.
     // this is *not* a generic getInnerText function; it's special to sorttable.
     // for example, you can override the cell text with a customkey attribute.
     // it also gets .value for <input> fields.
-    
+
     hasInputs = (typeof node.getElementsByTagName == 'function') &&
                  node.getElementsByTagName('input').length;
-    
+
     if (node.getAttribute("sorttable_customkey") != null) {
       return node.getAttribute("sorttable_customkey");
     }
@@ -240,7 +240,7 @@
       }
     }
   },
-  
+
   reverse: function(tbody) {
     // reverse the rows in a tbody
     newrows = [];
@@ -252,14 +252,14 @@
     }
     delete newrows;
   },
-  
+
   /* sort functions
      each sort function takes two parameters, a and b
      you are comparing a[0] and b[0] */
   sort_numeric: function(a,b) {
     aa = parseFloat(a[0].replace(/[^0-9.-]/g,''));
     if (isNaN(aa)) aa = 0;
-    bb = parseFloat(b[0].replace(/[^0-9.-]/g,'')); 
+    bb = parseFloat(b[0].replace(/[^0-9.-]/g,''));
     if (isNaN(bb)) bb = 0;
     return aa-bb;
   },
@@ -298,7 +298,7 @@
     if (dt1<dt2) return -1;
     return 1;
   },
-  
+
   shaker_sort: function(list, comp_func) {
     // A stable sort function to allow multi-level sorting of data
     // see: http://en.wikipedia.org/wiki/Cocktail_sort
@@ -328,7 +328,7 @@
         b++;
 
     } // while(swap)
-  }  
+  }
 }
 
 /* ******************************************************************
@@ -490,4 +490,3 @@
 		resolve.forEach(object, block, context);
 	}
 };
-
diff --git a/unittests/AST/ASTContextParentMapTest.cpp b/unittests/AST/ASTContextParentMapTest.cpp
index c1910a8..0dcb175 100644
--- a/unittests/AST/ASTContextParentMapTest.cpp
+++ b/unittests/AST/ASTContextParentMapTest.cpp
@@ -12,11 +12,11 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/AST/ASTContext.h"
+#include "MatchVerifier.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/Tooling/Tooling.h"
 #include "gtest/gtest.h"
-#include "MatchVerifier.h"
 
 namespace clang {
 namespace ast_matchers {
diff --git a/unittests/AST/ASTTypeTraitsTest.cpp b/unittests/AST/ASTTypeTraitsTest.cpp
index dd73b52..0e73f76 100644
--- a/unittests/AST/ASTTypeTraitsTest.cpp
+++ b/unittests/AST/ASTTypeTraitsTest.cpp
@@ -9,8 +9,8 @@
 
 
 #include "clang/AST/ASTTypeTraits.h"
-#include "gtest/gtest.h"
 #include "MatchVerifier.h"
+#include "gtest/gtest.h"
 
 using namespace clang::ast_matchers;
 
@@ -34,6 +34,19 @@
   EXPECT_TRUE(DNT<Decl>().isSame(DNT<Decl>()));
 }
 
+TEST(ASTNodeKind, BaseDistances) {
+  unsigned Distance = 1;
+  EXPECT_TRUE(DNT<Expr>().isBaseOf(DNT<Expr>(), &Distance));
+  EXPECT_EQ(0u, Distance);
+
+  EXPECT_TRUE(DNT<Stmt>().isBaseOf(DNT<IfStmt>(), &Distance));
+  EXPECT_EQ(1u, Distance);
+
+  Distance = 3;
+  EXPECT_TRUE(DNT<DeclaratorDecl>().isBaseOf(DNT<ParmVarDecl>(), &Distance));
+  EXPECT_EQ(2u, Distance);
+}
+
 TEST(ASTNodeKind, SameBase) {
   EXPECT_TRUE(DNT<Expr>().isBaseOf(DNT<CallExpr>()));
   EXPECT_TRUE(DNT<Expr>().isBaseOf(DNT<BinaryOperator>()));
diff --git a/unittests/AST/ASTVectorTest.cpp b/unittests/AST/ASTVectorTest.cpp
index a92e86b..ce6d0a0 100644
--- a/unittests/AST/ASTVectorTest.cpp
+++ b/unittests/AST/ASTVectorTest.cpp
@@ -18,7 +18,7 @@
 using namespace clang;
 
 LLVM_ATTRIBUTE_UNUSED void CompileTest() {
-  ASTContext *C = 0;
+  ASTContext *C = nullptr;
   ASTVector<int> V;
   V.insert(*C, V.begin(), 0);
 }
diff --git a/unittests/AST/CMakeLists.txt b/unittests/AST/CMakeLists.txt
index 70f86d3..2fa1078 100644
--- a/unittests/AST/CMakeLists.txt
+++ b/unittests/AST/CMakeLists.txt
@@ -1,3 +1,7 @@
+set(LLVM_LINK_COMPONENTS
+  Support
+  )
+
 add_clang_unittest(ASTTests
   ASTContextParentMapTest.cpp
   ASTTypeTraitsTest.cpp
@@ -6,10 +10,17 @@
   CommentParser.cpp
   DeclPrinterTest.cpp
   DeclTest.cpp
+  EvaluateAsRValueTest.cpp
+  ExternalASTSourceTest.cpp
+  NamedDeclPrinterTest.cpp
   SourceLocationTest.cpp
   StmtPrinterTest.cpp
   )
 
 target_link_libraries(ASTTests
-  clangAST clangASTMatchers clangTooling
+  clangAST
+  clangASTMatchers
+  clangBasic
+  clangFrontend
+  clangTooling
   )
diff --git a/unittests/AST/CommentLexer.cpp b/unittests/AST/CommentLexer.cpp
index fc0fd77..cb8de27 100644
--- a/unittests/AST/CommentLexer.cpp
+++ b/unittests/AST/CommentLexer.cpp
@@ -61,7 +61,7 @@
 void CommentLexerTest::lexString(const char *Source,
                                  std::vector<Token> &Toks) {
   MemoryBuffer *Buf = MemoryBuffer::getMemBuffer(Source);
-  FileID File = SourceMgr.createFileIDForMemBuffer(Buf);
+  FileID File = SourceMgr.createFileID(Buf);
   SourceLocation Begin = SourceMgr.getLocForStartOfFile(File);
 
   Lexer L(Allocator, Diags, Traits, Begin, Source, Source + strlen(Source));
diff --git a/unittests/AST/CommentParser.cpp b/unittests/AST/CommentParser.cpp
index f75c636..ae1410f 100644
--- a/unittests/AST/CommentParser.cpp
+++ b/unittests/AST/CommentParser.cpp
@@ -55,12 +55,12 @@
 
 FullComment *CommentParserTest::parseString(const char *Source) {
   MemoryBuffer *Buf = MemoryBuffer::getMemBuffer(Source);
-  FileID File = SourceMgr.createFileIDForMemBuffer(Buf);
+  FileID File = SourceMgr.createFileID(Buf);
   SourceLocation Begin = SourceMgr.getLocForStartOfFile(File);
 
   Lexer L(Allocator, Diags, Traits, Begin, Source, Source + strlen(Source));
 
-  Sema S(Allocator, SourceMgr, Diags, Traits, /*PP=*/ NULL);
+  Sema S(Allocator, SourceMgr, Diags, Traits, /*PP=*/ nullptr);
   Parser P(L, S, Allocator, SourceMgr, Diags, Traits);
   FullComment *FC = P.parseFullComment();
 
@@ -74,7 +74,7 @@
   if (Tok.is(tok::eof))
     return FC;
   else
-    return NULL;
+    return nullptr;
 }
 
 ::testing::AssertionResult HasChildCount(const Comment *C, size_t Count) {
@@ -1420,6 +1420,26 @@
   }
 }
 
+TEST_F(CommentParserTest, Deprecated) {
+  const char *Sources[] = {
+    "/** @deprecated*/",
+    "/// @deprecated\n"
+  };
+
+  for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
+    FullComment *FC = parseString(Sources[i]);
+    ASSERT_TRUE(HasChildCount(FC, 2));
+
+    ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
+    {
+      BlockCommandComment *BCC;
+      ParagraphComment *PC;
+      ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "deprecated", PC));
+      ASSERT_TRUE(HasChildCount(PC, 0));
+    }
+  }
+}
+
 } // unnamed namespace
 
 } // end namespace comments
diff --git a/unittests/AST/DeclPrinterTest.cpp b/unittests/AST/DeclPrinterTest.cpp
index 44fa742..5340756 100644
--- a/unittests/AST/DeclPrinterTest.cpp
+++ b/unittests/AST/DeclPrinterTest.cpp
@@ -74,10 +74,12 @@
   PrintMatch Printer;
   MatchFinder Finder;
   Finder.addMatcher(NodeMatch, &Printer);
-  OwningPtr<FrontendActionFactory> Factory(newFrontendActionFactory(&Finder));
+  std::unique_ptr<FrontendActionFactory> Factory(
+      newFrontendActionFactory(&Finder));
 
   if (!runToolOnCodeWithArgs(Factory->create(), Code, Args, FileName))
-    return testing::AssertionFailure() << "Parsing error in \"" << Code << "\"";
+    return testing::AssertionFailure()
+      << "Parsing error in \"" << Code.str() << "\"";
 
   if (Printer.getNumFoundDecls() == 0)
     return testing::AssertionFailure()
@@ -90,8 +92,8 @@
 
   if (Printer.getPrinted() != ExpectedPrinted)
     return ::testing::AssertionFailure()
-      << "Expected \"" << ExpectedPrinted << "\", "
-         "got \"" << Printer.getPrinted() << "\"";
+      << "Expected \"" << ExpectedPrinted.str() << "\", "
+         "got \"" << Printer.getPrinted().str() << "\"";
 
   return ::testing::AssertionSuccess();
 }
@@ -142,6 +144,19 @@
                             "input.cc");
 }
 
+::testing::AssertionResult PrintedDeclCXX11nonMSCMatches(
+                                  StringRef Code,
+                                  const DeclarationMatcher &NodeMatch,
+                                  StringRef ExpectedPrinted) {
+  std::vector<std::string> Args(1, "-std=c++11");
+  Args.push_back("-fno-delayed-template-parsing");
+  return PrintedDeclMatches(Code,
+                            Args,
+                            NodeMatch,
+                            ExpectedPrinted,
+                            "input.cc");
+}
+
 ::testing::AssertionResult PrintedDeclObjCMatches(
                                   StringRef Code,
                                   const DeclarationMatcher &NodeMatch,
@@ -156,6 +171,40 @@
 
 } // unnamed namespace
 
+TEST(DeclPrinter, TestTypedef1) {
+  ASSERT_TRUE(PrintedDeclCXX98Matches(
+    "typedef int A;",
+    "A",
+    "typedef int A"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestTypedef2) {
+  ASSERT_TRUE(PrintedDeclCXX98Matches(
+    "typedef const char *A;",
+    "A",
+    "typedef const char *A"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestTypedef3) {
+  ASSERT_TRUE(PrintedDeclCXX98Matches(
+    "template <typename Y> class X {};"
+    "typedef X<int> A;",
+    "A",
+    "typedef X<int> A"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestTypedef4) {
+  ASSERT_TRUE(PrintedDeclCXX98Matches(
+    "namespace X { class Y {}; }"
+    "typedef X::Y A;",
+    "A",
+    "typedef X::Y A"));
+    // Should be: with semicolon
+}
+
 TEST(DeclPrinter, TestNamespace1) {
   ASSERT_TRUE(PrintedDeclCXX98Matches(
     "namespace A { int B; }",
@@ -340,8 +389,8 @@
   ASSERT_TRUE(PrintedDeclCXX11Matches(
     "constexpr int A(int a);",
     "A",
-    "int A(int a)"));
-    // WRONG; Should be: "constexpr int A(int a);"
+    "constexpr int A(int a)"));
+    // Should be: with semicolon
 }
 
 TEST(DeclPrinter, TestFunctionDecl8) {
@@ -370,11 +419,11 @@
 
 TEST(DeclPrinter, TestFunctionDecl11) {
   ASSERT_TRUE(PrintedDeclCXX98Matches(
-    "typedef long size_t;"
+    "typedef long ssize_t;"
     "typedef int *pInt;"
-    "void A(int a, pInt b, size_t c);",
+    "void A(int a, pInt b, ssize_t c);",
     "A",
-    "void A(int a, pInt b, size_t c)"));
+    "void A(int a, pInt b, ssize_t c)"));
     // Should be: with semicolon
 }
 
@@ -466,8 +515,7 @@
     "  constexpr A();"
     "};",
     constructorDecl(ofClass(hasName("A"))).bind("id"),
-    "A()"));
-    // WRONG; Should be: "constexpr A();"
+    "constexpr A()"));
 }
 
 TEST(DeclPrinter, TestCXXConstructorDecl8) {
@@ -498,18 +546,16 @@
     "A<T...>(const A<T...> &a)"));
 }
 
-#if !defined(_MSC_VER)
 TEST(DeclPrinter, TestCXXConstructorDecl11) {
-  ASSERT_TRUE(PrintedDeclCXX11Matches(
+  ASSERT_TRUE(PrintedDeclCXX11nonMSCMatches(
     "template<typename... T>"
     "struct A : public T... {"
     "  A(T&&... ts) : T(ts)... {}"
     "};",
     constructorDecl(ofClass(hasName("A"))).bind("id"),
-    "A<T...>(T &&ts...) : T(ts)"));
+    "A<T...>(T &&ts...) : T(ts)..."));
     // WRONG; Should be: "A(T&&... ts) : T(ts)..."
 }
-#endif
 
 TEST(DeclPrinter, TestCXXDestructorDecl1) {
   ASSERT_TRUE(PrintedDeclCXX98Matches(
@@ -517,8 +563,7 @@
     "  ~A();"
     "};",
     destructorDecl(ofClass(hasName("A"))).bind("id"),
-    "void ~A()"));
-    // WRONG; Should be: "~A();"
+    "~A()"));
 }
 
 TEST(DeclPrinter, TestCXXDestructorDecl2) {
@@ -527,8 +572,7 @@
     "  virtual ~A();"
     "};",
     destructorDecl(ofClass(hasName("A"))).bind("id"),
-    "virtual void ~A()"));
-    // WRONG; Should be: "virtual ~A();"
+    "virtual ~A()"));
 }
 
 TEST(DeclPrinter, TestCXXConversionDecl1) {
@@ -537,8 +581,7 @@
     "  operator int();"
     "};",
     methodDecl(ofClass(hasName("A"))).bind("id"),
-    "int operator int()"));
-    // WRONG; Should be: "operator int();"
+    "operator int()"));
 }
 
 TEST(DeclPrinter, TestCXXConversionDecl2) {
@@ -547,8 +590,7 @@
     "  operator bool();"
     "};",
     methodDecl(ofClass(hasName("A"))).bind("id"),
-    "bool operator _Bool()"));
-    // WRONG; Should be: "operator bool();"
+    "operator bool()"));
 }
 
 TEST(DeclPrinter, TestCXXConversionDecl3) {
@@ -558,8 +600,7 @@
     "  operator Z();"
     "};",
     methodDecl(ofClass(hasName("A"))).bind("id"),
-    "Z operator struct Z()"));
-    // WRONG; Should be: "operator Z();"
+    "operator Z()"));
 }
 
 TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction1) {
@@ -756,8 +797,8 @@
     "  void A(int a) &;"
     "};",
     "A",
-    "void A(int a)"));
-    // WRONG; Should be: "void A(int a) &;"
+    "void A(int a) &"));
+    // Should be: with semicolon
 }
 
 TEST(DeclPrinter, TestCXXMethodDecl_RefQualifier2) {
@@ -766,8 +807,8 @@
     "  void A(int a) &&;"
     "};",
     "A",
-    "void A(int a)"));
-    // WRONG; Should be: "void A(int a) &&;"
+    "void A(int a) &&"));
+    // Should be: with semicolon
 }
 
 TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification1) {
diff --git a/unittests/AST/DeclTest.cpp b/unittests/AST/DeclTest.cpp
index c845da2..87aeef4 100644
--- a/unittests/AST/DeclTest.cpp
+++ b/unittests/AST/DeclTest.cpp
@@ -20,7 +20,7 @@
 
 TEST(Decl, CleansUpAPValues) {
   MatchFinder Finder;
-  llvm::OwningPtr<FrontendActionFactory> Factory(
+  std::unique_ptr<FrontendActionFactory> Factory(
       newFrontendActionFactory(&Finder));
 
   // This is a regression test for a memory leak in APValues for structs that
diff --git a/unittests/AST/EvaluateAsRValueTest.cpp b/unittests/AST/EvaluateAsRValueTest.cpp
new file mode 100644
index 0000000..9120c93
--- /dev/null
+++ b/unittests/AST/EvaluateAsRValueTest.cpp
@@ -0,0 +1,112 @@
+//===- unittests/AST/EvaluateAsRValueTest.cpp -----------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// \file
+// \brief Unit tests for evaluation of constant initializers.
+//
+//===----------------------------------------------------------------------===//
+
+#include <map>
+#include <string>
+
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+
+#include "clang/AST/ASTConsumer.h"
+
+using namespace clang::tooling;
+
+namespace {
+// For each variable name encountered, whether its initializer was a
+// constant.
+typedef std::map<std::string, bool> VarInfoMap;
+
+/// \brief Records information on variable initializers to a map.
+class EvaluateConstantInitializersVisitor
+    : public clang::RecursiveASTVisitor<EvaluateConstantInitializersVisitor> {
+ public:
+  explicit EvaluateConstantInitializersVisitor(VarInfoMap &VarInfo)
+      : VarInfo(VarInfo) {}
+
+  /// \brief Checks that isConstantInitializer and EvaluateAsRValue agree
+  /// and don't crash.
+  ///
+  /// For each VarDecl with an initializer this also records in VarInfo
+  /// whether the initializer could be evaluated as a constant.
+  bool VisitVarDecl(const clang::VarDecl *VD) {
+    if (const clang::Expr *Init = VD->getInit()) {
+      clang::Expr::EvalResult Result;
+      bool WasEvaluated = Init->EvaluateAsRValue(Result, VD->getASTContext());
+      VarInfo[VD->getNameAsString()] = WasEvaluated;
+      EXPECT_EQ(WasEvaluated, Init->isConstantInitializer(VD->getASTContext(),
+                                                          false /*ForRef*/));
+    }
+    return true;
+  }
+
+ private:
+  VarInfoMap &VarInfo;
+};
+
+class EvaluateConstantInitializersAction : public clang::ASTFrontendAction {
+ public:
+  clang::ASTConsumer *CreateASTConsumer(clang::CompilerInstance &Compiler,
+                                        llvm::StringRef FilePath) override {
+    return new Consumer;
+  }
+
+ private:
+  class Consumer : public clang::ASTConsumer {
+   public:
+    ~Consumer() override {}
+
+    void HandleTranslationUnit(clang::ASTContext &Ctx) override {
+      VarInfoMap VarInfo;
+      EvaluateConstantInitializersVisitor Evaluator(VarInfo);
+      Evaluator.TraverseDecl(Ctx.getTranslationUnitDecl());
+      EXPECT_EQ(2u, VarInfo.size());
+      EXPECT_FALSE(VarInfo["Dependent"]);
+      EXPECT_TRUE(VarInfo["Constant"]);
+      EXPECT_EQ(2u, VarInfo.size());
+    }
+  };
+};
+}
+
+TEST(EvaluateAsRValue, FailsGracefullyForUnknownTypes) {
+  // This is a regression test; the AST library used to trigger assertion
+  // failures because it assumed that the type of initializers was always
+  // known (which is true only after template instantiation).
+  std::string ModesToTest[] = {"-std=c++03", "-std=c++11", "-std=c++1y"};
+  for (std::string const &Mode : ModesToTest) {
+    std::vector<std::string> Args(1, Mode);
+    Args.push_back("-fno-delayed-template-parsing");
+    ASSERT_TRUE(runToolOnCodeWithArgs(
+      new EvaluateConstantInitializersAction(),
+      "template <typename T>"
+      "struct vector {"
+      "  explicit vector(int size);"
+      "};"
+      "template <typename R>"
+      "struct S {"
+      "  vector<R> intervals() const {"
+      "    vector<R> Dependent(2);"
+      "    return Dependent;"
+      "  }"
+      "};"
+      "void doSomething() {"
+      "  int Constant = 2 + 2;"
+      "  (void) Constant;"
+      "}",
+      Args));
+  }
+}
diff --git a/unittests/AST/ExternalASTSourceTest.cpp b/unittests/AST/ExternalASTSourceTest.cpp
new file mode 100644
index 0000000..5cc2def
--- /dev/null
+++ b/unittests/AST/ExternalASTSourceTest.cpp
@@ -0,0 +1,83 @@
+//===- unittest/AST/ExternalASTSourceTest.cpp -----------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains tests for Clang's ExternalASTSource.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ExternalASTSource.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/CompilerInvocation.h"
+#include "clang/Frontend/FrontendActions.h"
+#include "gtest/gtest.h"
+
+using namespace clang;
+using namespace llvm;
+
+
+class TestFrontendAction : public ASTFrontendAction {
+public:
+  TestFrontendAction(ExternalASTSource *Source) : Source(Source) {}
+
+private:
+  virtual void ExecuteAction() {
+    getCompilerInstance().getASTContext().setExternalSource(Source);
+    getCompilerInstance().getASTContext().getTranslationUnitDecl()
+        ->setHasExternalVisibleStorage();
+    return ASTFrontendAction::ExecuteAction();
+  }
+
+  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                         StringRef InFile) {
+    return new ASTConsumer;
+  }
+
+  IntrusiveRefCntPtr<ExternalASTSource> Source;
+};
+
+bool testExternalASTSource(ExternalASTSource *Source,
+                           StringRef FileContents) {
+  CompilerInstance Compiler;
+  Compiler.createDiagnostics();
+
+  CompilerInvocation *Invocation = new CompilerInvocation;
+  Invocation->getPreprocessorOpts().addRemappedFile(
+    "test.cc", MemoryBuffer::getMemBuffer(FileContents));
+  const char *Args[] = { "test.cc" };
+  CompilerInvocation::CreateFromArgs(*Invocation, Args,
+                                     Args + array_lengthof(Args),
+                                     Compiler.getDiagnostics());
+  Compiler.setInvocation(Invocation);
+
+  TestFrontendAction Action(Source);
+  return Compiler.ExecuteAction(Action);
+}
+
+
+// Ensure that a failed name lookup into an external source only occurs once.
+TEST(ExternalASTSourceTest, FailedLookupOccursOnce) {
+  struct TestSource : ExternalASTSource {
+    TestSource(unsigned &Calls) : Calls(Calls) {}
+
+    bool FindExternalVisibleDeclsByName(const DeclContext*,
+                                        DeclarationName Name) {
+      if (Name.getAsString() == "j")
+        ++Calls;
+      return false;
+    }
+
+    unsigned &Calls;
+  };
+
+  unsigned Calls = 0;
+  ASSERT_TRUE(testExternalASTSource(new TestSource(Calls), "int j, k = j;"));
+  EXPECT_EQ(1u, Calls);
+}
diff --git a/unittests/AST/Makefile b/unittests/AST/Makefile
index 0282d21..e3b3d7d 100644
--- a/unittests/AST/Makefile
+++ b/unittests/AST/Makefile
@@ -12,7 +12,7 @@
 include $(CLANG_LEVEL)/../../Makefile.config
 LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option
 USEDLIBS = clangTooling.a clangFrontend.a clangSerialization.a clangDriver.a \
-           clangRewriteCore.a clangRewriteFrontend.a \
+           clangRewrite.a clangRewriteFrontend.a \
            clangParse.a clangSema.a clangAnalysis.a \
            clangEdit.a clangAST.a clangASTMatchers.a clangLex.a clangBasic.a
 
diff --git a/unittests/AST/MatchVerifier.h b/unittests/AST/MatchVerifier.h
index 5a29cde..0265f4a 100644
--- a/unittests/AST/MatchVerifier.h
+++ b/unittests/AST/MatchVerifier.h
@@ -79,7 +79,7 @@
     std::vector<std::string>& Args, Language L) {
   MatchFinder Finder;
   Finder.addMatcher(AMatcher.bind(""), this);
-  OwningPtr<tooling::FrontendActionFactory> Factory(
+  std::unique_ptr<tooling::FrontendActionFactory> Factory(
       tooling::newFrontendActionFactory(&Finder));
 
   StringRef FileName;
diff --git a/unittests/AST/NamedDeclPrinterTest.cpp b/unittests/AST/NamedDeclPrinterTest.cpp
new file mode 100644
index 0000000..4823b44
--- /dev/null
+++ b/unittests/AST/NamedDeclPrinterTest.cpp
@@ -0,0 +1,133 @@
+//===- unittests/AST/NamedDeclPrinterTest.cpp --- NamedDecl printer tests -===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains tests for NamedDecl::printQualifiedName().
+//
+// These tests have a coding convention:
+// * declaration to be printed is named 'A' unless it should have some special
+// name (e.g., 'operator+');
+// * additional helper declarations are 'Z', 'Y', 'X' and so on.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/SmallString.h"
+#include "gtest/gtest.h"
+
+using namespace clang;
+using namespace ast_matchers;
+using namespace tooling;
+
+namespace {
+
+class PrintMatch : public MatchFinder::MatchCallback {
+  SmallString<1024> Printed;
+  unsigned NumFoundDecls;
+  bool SuppressUnwrittenScope;
+
+public:
+  explicit PrintMatch(bool suppressUnwrittenScope)
+    : NumFoundDecls(0), SuppressUnwrittenScope(suppressUnwrittenScope) {}
+
+  virtual void run(const MatchFinder::MatchResult &Result) {
+    const NamedDecl *ND = Result.Nodes.getNodeAs<NamedDecl>("id");
+    if (!ND)
+      return;
+    NumFoundDecls++;
+    if (NumFoundDecls > 1)
+      return;
+
+    llvm::raw_svector_ostream Out(Printed);
+    PrintingPolicy Policy = Result.Context->getPrintingPolicy();
+    Policy.SuppressUnwrittenScope = SuppressUnwrittenScope;
+    ND->printQualifiedName(Out, Policy);
+  }
+
+  StringRef getPrinted() const {
+    return Printed;
+  }
+
+  unsigned getNumFoundDecls() const {
+    return NumFoundDecls;
+  }
+};
+
+::testing::AssertionResult
+PrintedNamedDeclMatches(StringRef Code, const std::vector<std::string> &Args,
+                        bool SuppressUnwrittenScope,
+                        const DeclarationMatcher &NodeMatch,
+                        StringRef ExpectedPrinted, StringRef FileName) {
+  PrintMatch Printer(SuppressUnwrittenScope);
+  MatchFinder Finder;
+  Finder.addMatcher(NodeMatch, &Printer);
+  std::unique_ptr<FrontendActionFactory> Factory(
+      newFrontendActionFactory(&Finder));
+
+  if (!runToolOnCodeWithArgs(Factory->create(), Code, Args, FileName))
+    return testing::AssertionFailure()
+        << "Parsing error in \"" << Code.str() << "\"";
+
+  if (Printer.getNumFoundDecls() == 0)
+    return testing::AssertionFailure()
+        << "Matcher didn't find any named declarations";
+
+  if (Printer.getNumFoundDecls() > 1)
+    return testing::AssertionFailure()
+        << "Matcher should match only one named declaration "
+           "(found " << Printer.getNumFoundDecls() << ")";
+
+  if (Printer.getPrinted() != ExpectedPrinted)
+    return ::testing::AssertionFailure()
+        << "Expected \"" << ExpectedPrinted.str() << "\", "
+           "got \"" << Printer.getPrinted().str() << "\"";
+
+  return ::testing::AssertionSuccess();
+}
+
+::testing::AssertionResult
+PrintedNamedDeclCXX98Matches(StringRef Code, StringRef DeclName,
+                             StringRef ExpectedPrinted) {
+  std::vector<std::string> Args(1, "-std=c++98");
+  return PrintedNamedDeclMatches(Code,
+                                 Args,
+                                 /*SuppressUnwrittenScope*/ false,
+                                 namedDecl(hasName(DeclName)).bind("id"),
+                                 ExpectedPrinted,
+                                 "input.cc");
+}
+
+::testing::AssertionResult
+PrintedWrittenNamedDeclCXX11Matches(StringRef Code, StringRef DeclName,
+                                    StringRef ExpectedPrinted) {
+  std::vector<std::string> Args(1, "-std=c++11");
+  return PrintedNamedDeclMatches(Code,
+                                 Args,
+                                 /*SuppressUnwrittenScope*/ true,
+                                 namedDecl(hasName(DeclName)).bind("id"),
+                                 ExpectedPrinted,
+                                 "input.cc");
+}
+
+} // unnamed namespace
+
+TEST(NamedDeclPrinter, TestNamespace1) {
+  ASSERT_TRUE(PrintedNamedDeclCXX98Matches(
+    "namespace { int A; }",
+    "A",
+    "(anonymous namespace)::A"));
+}
+
+TEST(NamedDeclPrinter, TestNamespace2) {
+  ASSERT_TRUE(PrintedWrittenNamedDeclCXX11Matches(
+    "inline namespace Z { namespace { int A; } }",
+    "A",
+    "A"));
+}
diff --git a/unittests/AST/SourceLocationTest.cpp b/unittests/AST/SourceLocationTest.cpp
index 29156bc..82bba64 100644
--- a/unittests/AST/SourceLocationTest.cpp
+++ b/unittests/AST/SourceLocationTest.cpp
@@ -17,11 +17,11 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/AST/ASTContext.h"
+#include "MatchVerifier.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/Tooling/Tooling.h"
 #include "gtest/gtest.h"
-#include "MatchVerifier.h"
 
 namespace clang {
 namespace ast_matchers {
@@ -211,6 +211,16 @@
       functionalCastExpr(), Lang_CXX11));
 }
 
+TEST(CXXConstructExpr, SourceRange) {
+  RangeVerifier<CXXConstructExpr> Verifier;
+  Verifier.expectRange(3, 14, 3, 19);
+  EXPECT_TRUE(Verifier.match(
+      "struct A { A(int, int); };\n"
+      "void f(A a);\n"
+      "void g() { f({0, 0}); }",
+      constructExpr(), Lang_CXX11));
+}
+
 TEST(CXXTemporaryObjectExpr, SourceRange) {
   RangeVerifier<CXXTemporaryObjectExpr> Verifier;
   Verifier.expectRange(2, 6, 2, 12);
@@ -253,6 +263,216 @@
       unresolvedUsingValueDecl()));
 }
 
+TEST(FriendDecl, FriendNonMemberFunctionLocation) {
+  LocationVerifier<FriendDecl> Verifier;
+  Verifier.expectLocation(2, 13);
+  EXPECT_TRUE(Verifier.match("struct A {\n"
+                             "friend void f();\n"
+                             "};\n",
+                             friendDecl()));
+}
+
+TEST(FriendDecl, FriendNonMemberFunctionRange) {
+  RangeVerifier<FriendDecl> Verifier;
+  Verifier.expectRange(2, 1, 2, 15);
+  EXPECT_TRUE(Verifier.match("struct A {\n"
+                             "friend void f();\n"
+                             "};\n",
+                             friendDecl()));
+}
+
+TEST(FriendDecl, FriendNonMemberFunctionDefinitionLocation) {
+  LocationVerifier<FriendDecl> Verifier;
+  Verifier.expectLocation(2, 12);
+  EXPECT_TRUE(Verifier.match("struct A {\n"
+                             "friend int f() { return 0; }\n"
+                             "};\n",
+                             friendDecl()));
+}
+
+TEST(FriendDecl, FriendNonMemberFunctionDefinitionRange) {
+  RangeVerifier<FriendDecl> Verifier;
+  Verifier.expectRange(2, 1, 2, 28);
+  EXPECT_TRUE(Verifier.match("struct A {\n"
+                             "friend int f() { return 0; }\n"
+                             "};\n",
+                             friendDecl()));
+}
+
+TEST(FriendDecl, FriendElaboratedTypeLocation) {
+  LocationVerifier<FriendDecl> Verifier;
+  Verifier.expectLocation(2, 8);
+  EXPECT_TRUE(Verifier.match("struct A {\n"
+                             "friend class B;\n"
+                             "};\n",
+                             friendDecl()));
+}
+
+TEST(FriendDecl, FriendElaboratedTypeRange) {
+  RangeVerifier<FriendDecl> Verifier;
+  Verifier.expectRange(2, 1, 2, 14);
+  EXPECT_TRUE(Verifier.match("struct A {\n"
+                             "friend class B;\n"
+                             "};\n",
+                             friendDecl()));
+}
+
+TEST(FriendDecl, FriendSimpleTypeLocation) {
+  LocationVerifier<FriendDecl> Verifier;
+  Verifier.expectLocation(3, 8);
+  EXPECT_TRUE(Verifier.match("class B;\n"
+                             "struct A {\n"
+                             "friend B;\n"
+                             "};\n",
+                             friendDecl(), Lang_CXX11));
+}
+
+TEST(FriendDecl, FriendSimpleTypeRange) {
+  RangeVerifier<FriendDecl> Verifier;
+  Verifier.expectRange(3, 1, 3, 8);
+  EXPECT_TRUE(Verifier.match("class B;\n"
+                             "struct A {\n"
+                             "friend B;\n"
+                             "};\n",
+                             friendDecl(), Lang_CXX11));
+}
+
+TEST(FriendDecl, FriendTemplateParameterLocation) {
+  LocationVerifier<FriendDecl> Verifier;
+  Verifier.expectLocation(3, 8);
+  EXPECT_TRUE(Verifier.match("template <typename T>\n"
+                             "struct A {\n"
+                             "friend T;\n"
+                             "};\n",
+                             friendDecl(), Lang_CXX11));
+}
+
+TEST(FriendDecl, FriendTemplateParameterRange) {
+  RangeVerifier<FriendDecl> Verifier;
+  Verifier.expectRange(3, 1, 3, 8);
+  EXPECT_TRUE(Verifier.match("template <typename T>\n"
+                             "struct A {\n"
+                             "friend T;\n"
+                             "};\n",
+                             friendDecl(), Lang_CXX11));
+}
+
+TEST(FriendDecl, FriendDecltypeLocation) {
+  LocationVerifier<FriendDecl> Verifier;
+  Verifier.expectLocation(4, 8);
+  EXPECT_TRUE(Verifier.match("struct A;\n"
+                             "A foo();\n"
+                             "struct A {\n"
+                             "friend decltype(foo());\n"
+                             "};\n",
+                             friendDecl(), Lang_CXX11));
+}
+
+TEST(FriendDecl, FriendDecltypeRange) {
+  RangeVerifier<FriendDecl> Verifier;
+  Verifier.expectRange(4, 1, 4, 8);
+  EXPECT_TRUE(Verifier.match("struct A;\n"
+                             "A foo();\n"
+                             "struct A {\n"
+                             "friend decltype(foo());\n"
+                             "};\n",
+                             friendDecl(), Lang_CXX11));
+}
+
+TEST(FriendDecl, FriendConstructorDestructorLocation) {
+  const std::string Code = "struct B {\n"
+                           "B();\n"
+                           "~B();\n"
+                           "};\n"
+                           "struct A {\n"
+                           "friend B::B(), B::~B();\n"
+                           "};\n";
+  LocationVerifier<FriendDecl> ConstructorVerifier;
+  ConstructorVerifier.expectLocation(6, 11);
+  EXPECT_TRUE(ConstructorVerifier.match(
+      Code, friendDecl(has(constructorDecl(ofClass(hasName("B")))))));
+  LocationVerifier<FriendDecl> DestructorVerifier;
+  DestructorVerifier.expectLocation(6, 19);
+  EXPECT_TRUE(DestructorVerifier.match(
+      Code, friendDecl(has(destructorDecl(ofClass(hasName("B")))))));
+}
+
+TEST(FriendDecl, FriendConstructorDestructorRange) {
+  const std::string Code = "struct B {\n"
+                           "B();\n"
+                           "~B();\n"
+                           "};\n"
+                           "struct A {\n"
+                           "friend B::B(), B::~B();\n"
+                           "};\n";
+  RangeVerifier<FriendDecl> ConstructorVerifier;
+  ConstructorVerifier.expectRange(6, 1, 6, 13);
+  EXPECT_TRUE(ConstructorVerifier.match(
+      Code, friendDecl(has(constructorDecl(ofClass(hasName("B")))))));
+  RangeVerifier<FriendDecl> DestructorVerifier;
+  DestructorVerifier.expectRange(6, 1, 6, 22);
+  EXPECT_TRUE(DestructorVerifier.match(
+      Code, friendDecl(has(destructorDecl(ofClass(hasName("B")))))));
+}
+
+TEST(FriendDecl, FriendTemplateFunctionLocation) {
+  LocationVerifier<FriendDecl> Verifier;
+  Verifier.expectLocation(3, 13);
+  EXPECT_TRUE(Verifier.match("struct A {\n"
+                             "template <typename T>\n"
+                             "friend void f();\n"
+                             "};\n",
+                             friendDecl()));
+}
+
+TEST(FriendDecl, FriendTemplateFunctionRange) {
+  RangeVerifier<FriendDecl> Verifier;
+  Verifier.expectRange(2, 1, 3, 15);
+  EXPECT_TRUE(Verifier.match("struct A {\n"
+                             "template <typename T>\n"
+                             "friend void f();\n"
+                             "};\n",
+                             friendDecl()));
+}
+
+TEST(FriendDecl, FriendTemplateClassLocation) {
+  LocationVerifier<FriendDecl> Verifier;
+  Verifier.expectLocation(3, 14);
+  EXPECT_TRUE(Verifier.match("struct A {\n"
+                             "template <typename T>\n"
+                             "friend class B;\n"
+                             "};\n",
+                             friendDecl()));
+}
+
+TEST(FriendDecl, FriendTemplateClassRange) {
+  RangeVerifier<FriendDecl> Verifier;
+  Verifier.expectRange(2, 1, 3, 14);
+  EXPECT_TRUE(Verifier.match("struct A {\n"
+                             "template <typename T>\n"
+                             "friend class B;\n"
+                             "};\n",
+                             friendDecl()));
+}
+
+TEST(FriendDecl, FriendInlineFunctionLocation) {
+  LocationVerifier<FriendDecl> Verifier;
+  Verifier.expectLocation(2, 19);
+  EXPECT_TRUE(Verifier.match("struct A {\n"
+                             "int inline friend f() { return 0; }"
+                             "};\n",
+                             friendDecl()));
+}
+
+TEST(FriendDecl, FriendInlineFunctionRange) {
+  RangeVerifier<FriendDecl> Verifier;
+  Verifier.expectRange(2, 1, 2, 35);
+  EXPECT_TRUE(Verifier.match("struct A {\n"
+                             "int inline friend f() { return 0; }"
+                             "};\n",
+                             friendDecl(), Lang_CXX11));
+}
+
 TEST(FriendDecl, InstantiationSourceRange) {
   RangeVerifier<FriendDecl> Verifier;
   Verifier.expectRange(4, 3, 4, 35);
diff --git a/unittests/AST/StmtPrinterTest.cpp b/unittests/AST/StmtPrinterTest.cpp
index 473ee13..541fb3d 100644
--- a/unittests/AST/StmtPrinterTest.cpp
+++ b/unittests/AST/StmtPrinterTest.cpp
@@ -32,8 +32,9 @@
 namespace {
 
 void PrintStmt(raw_ostream &Out, const ASTContext *Context, const Stmt *S) {
+  assert(S != nullptr && "Expected non-null Stmt");
   PrintingPolicy Policy = Context->getPrintingPolicy();
-  S->printPretty(Out, /*Helper*/ 0, Policy);
+  S->printPretty(Out, /*Helper*/ nullptr, Policy);
 }
 
 class PrintMatch : public MatchFinder::MatchCallback {
@@ -64,19 +65,20 @@
   }
 };
 
-::testing::AssertionResult PrintedStmtMatches(
-                                        StringRef Code,
-                                        const std::vector<std::string> &Args,
-                                        const DeclarationMatcher &NodeMatch,
-                                        StringRef ExpectedPrinted) {
+template <typename T>
+::testing::AssertionResult
+PrintedStmtMatches(StringRef Code, const std::vector<std::string> &Args,
+                   const T &NodeMatch, StringRef ExpectedPrinted) {
 
   PrintMatch Printer;
   MatchFinder Finder;
   Finder.addMatcher(NodeMatch, &Printer);
-  OwningPtr<FrontendActionFactory> Factory(newFrontendActionFactory(&Finder));
+  std::unique_ptr<FrontendActionFactory> Factory(
+      newFrontendActionFactory(&Finder));
 
   if (!runToolOnCodeWithArgs(Factory->create(), Code, Args))
-    return testing::AssertionFailure() << "Parsing error in \"" << Code << "\"";
+    return testing::AssertionFailure()
+      << "Parsing error in \"" << Code.str() << "\"";
 
   if (Printer.getNumFoundStmts() == 0)
     return testing::AssertionFailure()
@@ -89,12 +91,21 @@
 
   if (Printer.getPrinted() != ExpectedPrinted)
     return ::testing::AssertionFailure()
-      << "Expected \"" << ExpectedPrinted << "\", "
-         "got \"" << Printer.getPrinted() << "\"";
+      << "Expected \"" << ExpectedPrinted.str() << "\", "
+         "got \"" << Printer.getPrinted().str() << "\"";
 
   return ::testing::AssertionSuccess();
 }
 
+::testing::AssertionResult
+PrintedStmtCXX98Matches(StringRef Code, const StatementMatcher &NodeMatch,
+                        StringRef ExpectedPrinted) {
+  std::vector<std::string> Args;
+  Args.push_back("-std=c++98");
+  Args.push_back("-Wno-unused-value");
+  return PrintedStmtMatches(Code, Args, NodeMatch, ExpectedPrinted);
+}
+
 ::testing::AssertionResult PrintedStmtCXX98Matches(
                                               StringRef Code,
                                               StringRef ContainingFunction,
@@ -109,11 +120,22 @@
                             ExpectedPrinted);
 }
 
+::testing::AssertionResult
+PrintedStmtCXX11Matches(StringRef Code, const StatementMatcher &NodeMatch,
+                        StringRef ExpectedPrinted) {
+  std::vector<std::string> Args;
+  Args.push_back("-std=c++11");
+  Args.push_back("-Wno-unused-value");
+  return PrintedStmtMatches(Code, Args, NodeMatch, ExpectedPrinted);
+}
+
 ::testing::AssertionResult PrintedStmtMSMatches(
                                               StringRef Code,
                                               StringRef ContainingFunction,
                                               StringRef ExpectedPrinted) {
   std::vector<std::string> Args;
+  Args.push_back("-target");
+  Args.push_back("i686-pc-win32");
   Args.push_back("-std=c++98");
   Args.push_back("-fms-extensions");
   Args.push_back("-Wno-unused-value");
@@ -149,9 +171,9 @@
     "  1i64, -1i64, 1ui64;"
     "}",
     "A",
+    "1i8 , -1i8 , 1Ui8 , "
+    "1i16 , -1i16 , 1Ui16 , "
     "1 , -1 , 1U , "
-    "1 , -1 , 1U , "
-    "1L , -1L , 1UL , "
     "1LL , -1LL , 1ULL"));
     // Should be: with semicolon
 }
@@ -163,3 +185,32 @@
     "1.F , -1.F , 1. , -1. , 1.L , -1.L"));
     // Should be: with semicolon
 }
+
+TEST(StmtPrinter, TestCXXConversionDeclImplicit) {
+  ASSERT_TRUE(PrintedStmtCXX98Matches(
+    "struct A {"
+      "operator void *();"
+      "A operator&(A);"
+    "};"
+    "void bar(void *);"
+    "void foo(A a, A b) {"
+    "  bar(a & b);"
+    "}",
+    memberCallExpr(anything()).bind("id"),
+    "a & b"));
+}
+
+TEST(StmtPrinter, TestCXXConversionDeclExplicit) {
+  ASSERT_TRUE(PrintedStmtCXX11Matches(
+    "struct A {"
+      "operator void *();"
+      "A operator&(A);"
+    "};"
+    "void bar(void *);"
+    "void foo(A a, A b) {"
+    "  auto x = (a & b).operator void *();"
+    "}",
+    memberCallExpr(anything()).bind("id"),
+    "(a & b)"));
+    // WRONG; Should be: (a & b).operator void *()
+}
diff --git a/unittests/ASTMatchers/ASTMatchersTest.cpp b/unittests/ASTMatchers/ASTMatchersTest.cpp
index cc13c01..bd7a5a6 100644
--- a/unittests/ASTMatchers/ASTMatchersTest.cpp
+++ b/unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -12,6 +12,8 @@
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/Host.h"
 #include "gtest/gtest.h"
 
 namespace clang {
@@ -42,14 +44,15 @@
 
 TEST(Finder, DynamicOnlyAcceptsSomeMatchers) {
   MatchFinder Finder;
-  EXPECT_TRUE(Finder.addDynamicMatcher(decl(), NULL));
-  EXPECT_TRUE(Finder.addDynamicMatcher(callExpr(), NULL));
-  EXPECT_TRUE(Finder.addDynamicMatcher(constantArrayType(hasSize(42)), NULL));
+  EXPECT_TRUE(Finder.addDynamicMatcher(decl(), nullptr));
+  EXPECT_TRUE(Finder.addDynamicMatcher(callExpr(), nullptr));
+  EXPECT_TRUE(Finder.addDynamicMatcher(constantArrayType(hasSize(42)),
+                                       nullptr));
 
   // Do not accept non-toplevel matchers.
-  EXPECT_FALSE(Finder.addDynamicMatcher(isArrow(), NULL));
-  EXPECT_FALSE(Finder.addDynamicMatcher(hasSize(2), NULL));
-  EXPECT_FALSE(Finder.addDynamicMatcher(hasName("x"), NULL));
+  EXPECT_FALSE(Finder.addDynamicMatcher(isArrow(), nullptr));
+  EXPECT_FALSE(Finder.addDynamicMatcher(hasSize(2), nullptr));
+  EXPECT_FALSE(Finder.addDynamicMatcher(hasName("x"), nullptr));
 }
 
 TEST(Decl, MatchesDeclarations) {
@@ -103,12 +106,13 @@
 
 TEST(DeclarationMatcher, MatchClass) {
   DeclarationMatcher ClassMatcher(recordDecl());
-#if !defined(_MSC_VER)
-  EXPECT_FALSE(matches("", ClassMatcher));
-#else
-  // Matches class type_info.
-  EXPECT_TRUE(matches("", ClassMatcher));
-#endif
+  llvm::Triple Triple(llvm::sys::getDefaultTargetTriple());
+  if (Triple.getOS() != llvm::Triple::Win32 ||
+      Triple.getEnvironment() != llvm::Triple::MSVC)
+    EXPECT_FALSE(matches("", ClassMatcher));
+  else
+    // Matches class type_info.
+    EXPECT_TRUE(matches("", ClassMatcher));
 
   DeclarationMatcher ClassX = recordDecl(recordDecl(hasName("X")));
   EXPECT_TRUE(matches("class X;", ClassX));
@@ -663,7 +667,7 @@
       : Id(Id), ExpectedCount(ExpectedCount), Count(0),
         ExpectedName(ExpectedName) {}
 
-  void onEndOfTranslationUnit() LLVM_OVERRIDE {
+  void onEndOfTranslationUnit() override {
     if (ExpectedCount != -1)
       EXPECT_EQ(ExpectedCount, Count);
     if (!ExpectedName.empty())
@@ -694,7 +698,8 @@
         EXPECT_EQ(Nodes->getNodeAs<T>(Id), I->second.get<T>());
       return true;
     }
-    EXPECT_TRUE(M.count(Id) == 0 || M.find(Id)->second.template get<T>() == 0);
+    EXPECT_TRUE(M.count(Id) == 0 ||
+                M.find(Id)->second.template get<T>() == nullptr);
     return false;
   }
 
@@ -1000,7 +1005,7 @@
 }
 
 TEST(Matcher, Lambda) {
-  EXPECT_TRUE(matches("auto f = [&] (int i) { return i; };",
+  EXPECT_TRUE(matches("auto f = [] (int i) { return i; };",
                       lambdaExpr()));
 }
 
@@ -1012,6 +1017,17 @@
                          forRangeStmt()));
 }
 
+TEST(Matcher, SubstNonTypeTemplateParm) {
+  EXPECT_FALSE(matches("template<int N>\n"
+                       "struct A {  static const int n = 0; };\n"
+                       "struct B : public A<42> {};",
+                       substNonTypeTemplateParmExpr()));
+  EXPECT_TRUE(matches("template<int N>\n"
+                      "struct A {  static const int n = N; };\n"
+                      "struct B : public A<42> {};",
+                      substNonTypeTemplateParmExpr()));
+}
+
 TEST(Matcher, UserDefinedLiteral) {
   EXPECT_TRUE(matches("constexpr char operator \"\" _inc (const char i) {"
                       "  return i + 1;"
@@ -1038,7 +1054,7 @@
   EXPECT_TRUE(matches("namespace ns { struct A {}; }  struct B { ns::A a; };",
       fieldDecl(hasType(asString("ns::A")))));
   EXPECT_TRUE(matches("namespace { struct A {}; }  struct B { A a; };",
-      fieldDecl(hasType(asString("struct <anonymous>::A")))));
+      fieldDecl(hasType(asString("struct (anonymous namespace)::A")))));
 }
 
 TEST(Matcher, OverloadedOperatorCall) {
@@ -1079,12 +1095,19 @@
               "bool operator&&(Y x, Y y) { return true; }; "
               "Y a; Y b; bool c = a && b;",
               OpCallLessLess));
+  StatementMatcher OpStarCall =
+      operatorCallExpr(hasOverloadedOperatorName("*"));
+  EXPECT_TRUE(matches("class Y; int operator*(Y &); void f(Y &y) { *y; }",
+              OpStarCall));
   DeclarationMatcher ClassWithOpStar =
     recordDecl(hasMethod(hasOverloadedOperatorName("*")));
   EXPECT_TRUE(matches("class Y { int operator*(); };",
                       ClassWithOpStar));
   EXPECT_TRUE(notMatches("class Y { void myOperator(); };",
               ClassWithOpStar)) ;
+  DeclarationMatcher AnyOpStar = functionDecl(hasOverloadedOperatorName("*"));
+  EXPECT_TRUE(matches("class Y; int operator*(Y &);", AnyOpStar));
+  EXPECT_TRUE(matches("class Y { int operator*(); };", AnyOpStar));
 }
 
 TEST(Matcher, NestedOverloadedOperatorCalls) {
@@ -1162,6 +1185,18 @@
       "}", Reference));
 }
 
+TEST(Matcher, VarDecl_Storage) {
+  auto M = varDecl(hasName("X"), hasLocalStorage());
+  EXPECT_TRUE(matches("void f() { int X; }", M));
+  EXPECT_TRUE(notMatches("int X;", M));
+  EXPECT_TRUE(notMatches("void f() { static int X; }", M));
+
+  M = varDecl(hasName("X"), hasGlobalStorage());
+  EXPECT_TRUE(notMatches("void f() { int X; }", M));
+  EXPECT_TRUE(matches("int X;", M));
+  EXPECT_TRUE(matches("void f() { static int X; }", M));
+}
+
 TEST(Matcher, FindsVarDeclInFunctionParameter) {
   EXPECT_TRUE(matches(
       "void f(int i) {}",
@@ -1300,15 +1335,16 @@
   EXPECT_TRUE(matches("void f() { f(); }", CallFunctionF));
   EXPECT_TRUE(notMatches("void f() { }", CallFunctionF));
 
-#if !defined(_MSC_VER)
-  // FIXME: Make this work for MSVC.
-  // Dependent contexts, but a non-dependent call.
-  EXPECT_TRUE(matches("void f(); template <int N> void g() { f(); }",
-                      CallFunctionF));
-  EXPECT_TRUE(
-      matches("void f(); template <int N> struct S { void g() { f(); } };",
-              CallFunctionF));
-#endif
+  if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).getOS() !=
+      llvm::Triple::Win32) {
+    // FIXME: Make this work for MSVC.
+    // Dependent contexts, but a non-dependent call.
+    EXPECT_TRUE(matches("void f(); template <int N> void g() { f(); }",
+                        CallFunctionF));
+    EXPECT_TRUE(
+        matches("void f(); template <int N> struct S { void g() { f(); } };",
+                CallFunctionF));
+  }
 
   // Depedent calls don't match.
   EXPECT_TRUE(
@@ -1479,7 +1515,7 @@
           recordDecl(hasName("X"))))))));
 }
 
-TEST(HasName, MatchesParameterVariableDeclartions) {
+TEST(HasName, MatchesParameterVariableDeclarations) {
   EXPECT_TRUE(matches("class Y {}; class X { void x(int x) {} };",
       methodDecl(hasAnyParameter(hasName("x")))));
   EXPECT_TRUE(notMatches("class Y {}; class X { void x(int) {} };",
@@ -1527,6 +1563,19 @@
       "A<int> a;",
       classTemplateSpecializationDecl(hasAnyTemplateArgument(
           refersToDeclaration(decl())))));
+
+  EXPECT_TRUE(matches(
+      "struct B { int next; };"
+      "template<int(B::*next_ptr)> struct A {};"
+      "A<&B::next> a;",
+      templateSpecializationType(hasAnyTemplateArgument(isExpr(
+          hasDescendant(declRefExpr(to(fieldDecl(hasName("next"))))))))));
+
+  EXPECT_TRUE(notMatches(
+      "template <typename T> struct A {};"
+      "A<int> a;",
+      templateSpecializationType(hasAnyTemplateArgument(
+          refersToDeclaration(decl())))));
 }
 
 TEST(Matcher, MatchesSpecificArgument) {
@@ -1540,6 +1589,17 @@
       "A<int, bool> a;",
       classTemplateSpecializationDecl(hasTemplateArgument(
           1, refersToType(asString("int"))))));
+
+  EXPECT_TRUE(matches(
+      "template<typename T, typename U> class A {};"
+      "A<bool, int> a;",
+      templateSpecializationType(hasTemplateArgument(
+          1, refersToType(asString("int"))))));
+  EXPECT_TRUE(notMatches(
+      "template<typename T, typename U> class A {};"
+      "A<int, bool> a;",
+      templateSpecializationType(hasTemplateArgument(
+          1, refersToType(asString("int"))))));
 }
 
 TEST(Matcher, MatchesAccessSpecDecls) {
@@ -1561,6 +1621,13 @@
       methodDecl(isVirtual())));
 }
 
+TEST(Matcher, MatchesPureMethod) {
+  EXPECT_TRUE(matches("class X { virtual int f() = 0; };",
+      methodDecl(isPure(), hasName("::X::f"))));
+  EXPECT_TRUE(notMatches("class X { int f(); };",
+      methodDecl(isPure())));
+}
+
 TEST(Matcher, MatchesConstMethod) {
   EXPECT_TRUE(matches("struct A { void foo() const; };",
                       methodDecl(isConst())));
@@ -1637,6 +1704,17 @@
                  Constructor1Arg));
 }
 
+TEST(Matcher, ConstructorListInitialization) {
+  StatementMatcher ConstructorListInit = constructExpr(isListInitialization());
+
+  EXPECT_TRUE(
+      matches("class X { public: X(int); }; void x() { X x{0}; }",
+              ConstructorListInit));
+  EXPECT_FALSE(
+      matches("class X { public: X(int); }; void x() { X x(0); }",
+              ConstructorListInit));
+}
+
 TEST(Matcher,ThisExpr) {
   EXPECT_TRUE(
       matches("struct X { int a; int f () { return a; } };", thisExpr()));
@@ -1727,6 +1805,9 @@
                       constructorDecl(isImplicit())));
   EXPECT_TRUE(matches("class Foo { Foo(){} };",
                       constructorDecl(unless(isImplicit()))));
+  // The compiler added an implicit assignment operator.
+  EXPECT_TRUE(matches("struct A { int x; } a = {0}, b = a; void f() { a = b; }",
+                      methodDecl(isImplicit(), hasName("operator="))));
 }
 
 TEST(DestructorDeclaration, MatchesVirtualDestructor) {
@@ -1917,6 +1998,17 @@
   EXPECT_TRUE(notMatches("void x() { if (1) {} }", Condition));
 }
 
+TEST(IfStmt, ChildTraversalMatchers) {
+  EXPECT_TRUE(matches("void f() { if (false) true; else false; }",
+                      ifStmt(hasThen(boolLiteral(equals(true))))));
+  EXPECT_TRUE(notMatches("void f() { if (false) false; else true; }",
+                         ifStmt(hasThen(boolLiteral(equals(true))))));
+  EXPECT_TRUE(matches("void f() { if (false) false; else true; }",
+                      ifStmt(hasElse(boolLiteral(equals(true))))));
+  EXPECT_TRUE(notMatches("void f() { if (false) true; else false; }",
+                         ifStmt(hasElse(boolLiteral(equals(true))))));
+}
+
 TEST(MatchBinaryOperator, HasOperatorName) {
   StatementMatcher OperatorOr = binaryOperator(hasOperatorName("||"));
 
@@ -2339,6 +2431,14 @@
                       forStmt(hasLoopInit(anything()))));
 }
 
+TEST(For, ForRangeLoopInternals) {
+  EXPECT_TRUE(matches("void f(){ int a[] {1, 2}; for (int i : a); }",
+                      forRangeStmt(hasLoopVariable(anything()))));
+  EXPECT_TRUE(matches(
+      "void f(){ int a[] {1, 2}; for (int i : a); }",
+      forRangeStmt(hasRangeInit(declRefExpr(to(varDecl(hasName("a"))))))));
+}
+
 TEST(For, NegativeForLoopInternals) {
   EXPECT_TRUE(notMatches("void f(){ for (int i = 0; ; ++i); }",
                          forStmt(hasCondition(expr()))));
@@ -2375,6 +2475,8 @@
               whileStmt(hasBody(compoundStmt()))));
   EXPECT_TRUE(matches("void f() { do {} while(true); }",
               doStmt(hasBody(compoundStmt()))));
+  EXPECT_TRUE(matches("void f() { int p[2]; for (auto x : p) {} }",
+              forRangeStmt(hasBody(compoundStmt()))));
 }
 
 TEST(HasAnySubstatement, MatchesForTopLevelCompoundStatement) {
@@ -2608,13 +2710,13 @@
 }
 
 TEST(FunctionalCast, MatchesSimpleCase) {
-  std::string foo_class = "class Foo { public: Foo(char*); };";
+  std::string foo_class = "class Foo { public: Foo(const char*); };";
   EXPECT_TRUE(matches(foo_class + "void r() { Foo f = Foo(\"hello world\"); }",
                       functionalCastExpr()));
 }
 
 TEST(FunctionalCast, DoesNotMatchOtherCasts) {
-  std::string FooClass = "class Foo { public: Foo(char*); };";
+  std::string FooClass = "class Foo { public: Foo(const char*); };";
   EXPECT_TRUE(
       notMatches(FooClass + "void r() { Foo f = (Foo) \"hello world\"; }",
                  functionalCastExpr()));
@@ -2892,6 +2994,15 @@
   EXPECT_TRUE(matches("void x() { int a; }", declStmt()));
 }
 
+TEST(ExprWithCleanups, MatchesExprWithCleanups) {
+  EXPECT_TRUE(matches("struct Foo { ~Foo(); };"
+                      "const Foo f = Foo();",
+                      varDecl(hasInitializer(exprWithCleanups()))));
+  EXPECT_FALSE(matches("struct Foo { };"
+                      "const Foo f = Foo();",
+                      varDecl(hasInitializer(exprWithCleanups()))));
+}
+
 TEST(InitListExpression, MatchesInitListExpression) {
   EXPECT_TRUE(matches("int a[] = { 1, 2 };",
                       initListExpr(hasType(asString("int [2]")))));
@@ -2927,6 +3038,13 @@
       declRefExpr(throughUsingDecl(anything()))));
 }
 
+TEST(UsingDirectiveDeclaration, MatchesUsingNamespace) {
+  EXPECT_TRUE(matches("namespace X { int x; } using namespace X;",
+                      usingDirectiveDecl()));
+  EXPECT_FALSE(
+      matches("namespace X { int x; } using X::x;", usingDirectiveDecl()));
+}
+
 TEST(SingleDecl, IsSingleDecl) {
   StatementMatcher SingleDeclStmt =
       declStmt(hasSingleDecl(varDecl(hasInitializer(anything()))));
@@ -3530,6 +3648,27 @@
                  compoundStmt(hasParent(recordDecl()))));
 }
 
+TEST(HasParent, NoDuplicateParents) {
+  class HasDuplicateParents : public BoundNodesCallback {
+  public:
+    bool run(const BoundNodes *Nodes) override { return false; }
+    bool run(const BoundNodes *Nodes, ASTContext *Context) override {
+      const Stmt *Node = Nodes->getNodeAs<Stmt>("node");
+      std::set<const void *> Parents;
+      for (const auto &Parent : Context->getParents(*Node)) {
+        if (!Parents.insert(Parent.getMemoizationData()).second) {
+          return true;
+        }
+      }
+      return false;
+    }
+  };
+  EXPECT_FALSE(matchAndVerifyResultTrue(
+      "template <typename T> int Foo() { return 1 + 2; }\n"
+      "int x = Foo<int>() + Foo<unsigned>();",
+      stmt().bind("node"), new HasDuplicateParents()));
+}
+
 TEST(TypeMatching, MatchesTypes) {
   EXPECT_TRUE(matches("struct S {};", qualType().bind("loc")));
 }
@@ -3617,12 +3756,16 @@
 }
 
 TEST(TypeMatching, MatchesAtomicTypes) {
-  EXPECT_TRUE(matches("_Atomic(int) i;", atomicType()));
+  if (llvm::Triple(llvm::sys::getDefaultTargetTriple()).getOS() !=
+      llvm::Triple::Win32) {
+    // FIXME: Make this work for MSVC.
+    EXPECT_TRUE(matches("_Atomic(int) i;", atomicType()));
 
-  EXPECT_TRUE(matches("_Atomic(int) i;",
-                      atomicType(hasValueType(isInteger()))));
-  EXPECT_TRUE(notMatches("_Atomic(float) f;",
-                         atomicType(hasValueType(isInteger()))));
+    EXPECT_TRUE(matches("_Atomic(int) i;",
+                        atomicType(hasValueType(isInteger()))));
+    EXPECT_TRUE(notMatches("_Atomic(float) f;",
+                           atomicType(hasValueType(isInteger()))));
+  }
 }
 
 TEST(TypeMatching, MatchesAutoTypes) {
@@ -4021,7 +4164,7 @@
   virtual bool run(const BoundNodes *Nodes, ASTContext *Context) {
     const T *Node = Nodes->getNodeAs<T>(Id);
     return selectFirst<const T>(InnerId,
-                                match(InnerMatcher, *Node, *Context)) != NULL;
+                                match(InnerMatcher, *Node, *Context)) !=nullptr;
   }
 private:
   std::string Id;
@@ -4075,24 +4218,32 @@
   }
 
   bool verify(const BoundNodes &Nodes, ASTContext &Context, const Stmt *Node) {
+    // Use the original typed pointer to verify we can pass pointers to subtypes
+    // to equalsNode.
+    const T *TypedNode = cast<T>(Node);
     return selectFirst<const T>(
-        "", match(stmt(hasParent(stmt(has(stmt(equalsNode(Node)))).bind(""))),
-                  *Node, Context)) != NULL;
+               "", match(stmt(hasParent(
+                             stmt(has(stmt(equalsNode(TypedNode)))).bind(""))),
+                         *Node, Context)) != nullptr;
   }
   bool verify(const BoundNodes &Nodes, ASTContext &Context, const Decl *Node) {
+    // Use the original typed pointer to verify we can pass pointers to subtypes
+    // to equalsNode.
+    const T *TypedNode = cast<T>(Node);
     return selectFirst<const T>(
-        "", match(decl(hasParent(decl(has(decl(equalsNode(Node)))).bind(""))),
-                  *Node, Context)) != NULL;
+               "", match(decl(hasParent(
+                             decl(has(decl(equalsNode(TypedNode)))).bind(""))),
+                         *Node, Context)) != nullptr;
   }
 };
 
 TEST(IsEqualTo, MatchesNodesByIdentity) {
   EXPECT_TRUE(matchAndVerifyResultTrue(
       "class X { class Y {}; };", recordDecl(hasName("::X::Y")).bind(""),
-      new VerifyAncestorHasChildIsEqual<Decl>()));
-  EXPECT_TRUE(
-      matchAndVerifyResultTrue("void f() { if(true) {} }", ifStmt().bind(""),
-                               new VerifyAncestorHasChildIsEqual<Stmt>()));
+      new VerifyAncestorHasChildIsEqual<CXXRecordDecl>()));
+  EXPECT_TRUE(matchAndVerifyResultTrue(
+      "void f() { if (true) if(true) {} }", ifStmt().bind(""),
+      new VerifyAncestorHasChildIsEqual<IfStmt>()));
 }
 
 class VerifyStartOfTranslationUnit : public MatchFinder::MatchCallback {
@@ -4111,12 +4262,13 @@
   MatchFinder Finder;
   VerifyStartOfTranslationUnit VerifyCallback;
   Finder.addMatcher(decl(), &VerifyCallback);
-  OwningPtr<FrontendActionFactory> Factory(newFrontendActionFactory(&Finder));
+  std::unique_ptr<FrontendActionFactory> Factory(
+      newFrontendActionFactory(&Finder));
   ASSERT_TRUE(tooling::runToolOnCode(Factory->create(), "int x;"));
   EXPECT_TRUE(VerifyCallback.Called);
 
   VerifyCallback.Called = false;
-  OwningPtr<ASTUnit> AST(tooling::buildASTFromCode("int x;"));
+  std::unique_ptr<ASTUnit> AST(tooling::buildASTFromCode("int x;"));
   ASSERT_TRUE(AST.get());
   Finder.matchAST(AST->getASTContext());
   EXPECT_TRUE(VerifyCallback.Called);
@@ -4138,12 +4290,13 @@
   MatchFinder Finder;
   VerifyEndOfTranslationUnit VerifyCallback;
   Finder.addMatcher(decl(), &VerifyCallback);
-  OwningPtr<FrontendActionFactory> Factory(newFrontendActionFactory(&Finder));
+  std::unique_ptr<FrontendActionFactory> Factory(
+      newFrontendActionFactory(&Finder));
   ASSERT_TRUE(tooling::runToolOnCode(Factory->create(), "int x;"));
   EXPECT_TRUE(VerifyCallback.Called);
 
   VerifyCallback.Called = false;
-  OwningPtr<ASTUnit> AST(tooling::buildASTFromCode("int x;"));
+  std::unique_ptr<ASTUnit> AST(tooling::buildASTFromCode("int x;"));
   ASSERT_TRUE(AST.get());
   Finder.matchAST(AST->getASTContext());
   EXPECT_TRUE(VerifyCallback.Called);
@@ -4204,7 +4357,6 @@
 }
 
 TEST(EqualsBoundNodeMatcher, UsingForEachDescendant) {
-
   EXPECT_TRUE(matchAndVerifyResultTrue(
       "int f() {"
       "  if (1) {"
@@ -4238,5 +4390,37 @@
       new VerifyIdIsBoundTo<VarDecl>("d", 5)));
 }
 
+TEST(EqualsBoundNodeMatcher, UnlessDescendantsOfAncestorsMatch) {
+  EXPECT_TRUE(matchAndVerifyResultTrue(
+      "struct StringRef { int size() const; const char* data() const; };"
+      "void f(StringRef v) {"
+      "  v.data();"
+      "}",
+      memberCallExpr(
+          callee(methodDecl(hasName("data"))),
+          on(declRefExpr(to(varDecl(hasType(recordDecl(hasName("StringRef"))))
+                                .bind("var")))),
+          unless(hasAncestor(stmt(hasDescendant(memberCallExpr(
+              callee(methodDecl(anyOf(hasName("size"), hasName("length")))),
+              on(declRefExpr(to(varDecl(equalsBoundNode("var")))))))))))
+          .bind("data"),
+      new VerifyIdIsBoundTo<Expr>("data", 1)));
+
+  EXPECT_FALSE(matches(
+      "struct StringRef { int size() const; const char* data() const; };"
+      "void f(StringRef v) {"
+      "  v.data();"
+      "  v.size();"
+      "}",
+      memberCallExpr(
+          callee(methodDecl(hasName("data"))),
+          on(declRefExpr(to(varDecl(hasType(recordDecl(hasName("StringRef"))))
+                                .bind("var")))),
+          unless(hasAncestor(stmt(hasDescendant(memberCallExpr(
+              callee(methodDecl(anyOf(hasName("size"), hasName("length")))),
+              on(declRefExpr(to(varDecl(equalsBoundNode("var")))))))))))
+          .bind("data")));
+}
+
 } // end namespace ast_matchers
 } // end namespace clang
diff --git a/unittests/ASTMatchers/ASTMatchersTest.h b/unittests/ASTMatchers/ASTMatchersTest.h
index f5bcd37..2e4ee2c 100644
--- a/unittests/ASTMatchers/ASTMatchersTest.h
+++ b/unittests/ASTMatchers/ASTMatchersTest.h
@@ -40,14 +40,14 @@
       : Verified(Verified), FindResultReviewer(FindResultVerifier) {}
 
   virtual void run(const MatchFinder::MatchResult &Result) {
-    if (FindResultReviewer != NULL) {
+    if (FindResultReviewer != nullptr) {
       *Verified |= FindResultReviewer->run(&Result.Nodes, Result.Context);
     } else {
       *Verified = true;
     }
   }
 
-  void onEndOfTranslationUnit() LLVM_OVERRIDE {
+  void onEndOfTranslationUnit() override {
     if (FindResultReviewer)
       FindResultReviewer->onEndOfTranslationUnit();
   }
@@ -64,10 +64,13 @@
                                               llvm::StringRef CompileArg) {
   bool Found = false, DynamicFound = false;
   MatchFinder Finder;
-  Finder.addMatcher(AMatcher, new VerifyMatch(0, &Found));
-  if (!Finder.addDynamicMatcher(AMatcher, new VerifyMatch(0, &DynamicFound)))
+  VerifyMatch VerifyFound(nullptr, &Found);
+  Finder.addMatcher(AMatcher, &VerifyFound);
+  VerifyMatch VerifyDynamicFound(nullptr, &DynamicFound);
+  if (!Finder.addDynamicMatcher(AMatcher, &VerifyDynamicFound))
     return testing::AssertionFailure() << "Could not add dynamic matcher";
-  OwningPtr<FrontendActionFactory> Factory(newFrontendActionFactory(&Finder));
+  std::unique_ptr<FrontendActionFactory> Factory(
+      newFrontendActionFactory(&Finder));
   // Some tests use typeof, which is a gnu extension.
   std::vector<std::string> Args(1, CompileArg);
   if (!runToolOnCodeWithArgs(Factory->create(), Code, Args)) {
@@ -105,12 +108,13 @@
 matchAndVerifyResultConditionally(const std::string &Code, const T &AMatcher,
                                   BoundNodesCallback *FindResultVerifier,
                                   bool ExpectResult) {
-  OwningPtr<BoundNodesCallback> ScopedVerifier(FindResultVerifier);
+  std::unique_ptr<BoundNodesCallback> ScopedVerifier(FindResultVerifier);
   bool VerifiedResult = false;
   MatchFinder Finder;
-  Finder.addMatcher(
-      AMatcher, new VerifyMatch(FindResultVerifier, &VerifiedResult));
-  OwningPtr<FrontendActionFactory> Factory(newFrontendActionFactory(&Finder));
+  VerifyMatch VerifyVerifiedResult(FindResultVerifier, &VerifiedResult);
+  Finder.addMatcher(AMatcher, &VerifyVerifiedResult);
+  std::unique_ptr<FrontendActionFactory> Factory(
+      newFrontendActionFactory(&Finder));
   // Some tests use typeof, which is a gnu extension.
   std::vector<std::string> Args(1, "-std=gnu++98");
   if (!runToolOnCodeWithArgs(Factory->create(), Code, Args)) {
@@ -125,7 +129,7 @@
   }
 
   VerifiedResult = false;
-  OwningPtr<ASTUnit> AST(buildASTFromCodeWithArgs(Code, Args));
+  std::unique_ptr<ASTUnit> AST(buildASTFromCodeWithArgs(Code, Args));
   if (!AST.get())
     return testing::AssertionFailure() << "Parsing error in \"" << Code
                                        << "\" while building AST";
diff --git a/unittests/ASTMatchers/CMakeLists.txt b/unittests/ASTMatchers/CMakeLists.txt
index 862c6a0..3ace9fe 100644
--- a/unittests/ASTMatchers/CMakeLists.txt
+++ b/unittests/ASTMatchers/CMakeLists.txt
@@ -1,15 +1,16 @@
 set(LLVM_LINK_COMPONENTS
-  ${LLVM_TARGETS_TO_BUILD}
-  asmparser
-  bitreader
-  support
-  mc
+  Support
   )
 
 add_clang_unittest(ASTMatchersTests
   ASTMatchersTest.cpp)
 
 target_link_libraries(ASTMatchersTests
-  gtest gtest_main clangASTMatchers clangTooling)
+  clangAST
+  clangASTMatchers
+  clangBasic
+  clangFrontend
+  clangTooling
+  )
 
 add_subdirectory(Dynamic)
diff --git a/unittests/ASTMatchers/Dynamic/CMakeLists.txt b/unittests/ASTMatchers/Dynamic/CMakeLists.txt
index eb9fa54..8b95a7b 100644
--- a/unittests/ASTMatchers/Dynamic/CMakeLists.txt
+++ b/unittests/ASTMatchers/Dynamic/CMakeLists.txt
@@ -1,7 +1,16 @@
+set(LLVM_LINK_COMPONENTS
+  Support
+  )
+
 add_clang_unittest(DynamicASTMatchersTests
   VariantValueTest.cpp
   ParserTest.cpp
   RegistryTest.cpp)
 
 target_link_libraries(DynamicASTMatchersTests
-  gtest gtest_main clangASTMatchers clangDynamicASTMatchers clangTooling)
+  clangAST
+  clangASTMatchers
+  clangDynamicASTMatchers
+  clangFrontend
+  clangTooling
+  )
diff --git a/unittests/ASTMatchers/Dynamic/Makefile b/unittests/ASTMatchers/Dynamic/Makefile
index 66b183c..dfd0086 100644
--- a/unittests/ASTMatchers/Dynamic/Makefile
+++ b/unittests/ASTMatchers/Dynamic/Makefile
@@ -13,7 +13,7 @@
 include $(CLANG_LEVEL)/../../Makefile.config
 LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option
 USEDLIBS = clangTooling.a clangFrontend.a clangSerialization.a clangDriver.a \
-           clangRewriteCore.a clangRewriteFrontend.a clangParse.a clangSema.a \
+           clangRewrite.a clangRewriteFrontend.a clangParse.a clangSema.a \
            clangAnalysis.a clangEdit.a clangAST.a clangASTMatchers.a \
            clangLex.a clangBasic.a clangDynamicASTMatchers.a
 
diff --git a/unittests/ASTMatchers/Dynamic/ParserTest.cpp b/unittests/ASTMatchers/Dynamic/ParserTest.cpp
index f19ec51..4e3239f 100644
--- a/unittests/ASTMatchers/Dynamic/ParserTest.cpp
+++ b/unittests/ASTMatchers/Dynamic/ParserTest.cpp
@@ -7,14 +7,14 @@
 //
 //===-------------------------------------------------------------------===//
 
-#include <string>
-#include <vector>
-
 #include "../ASTMatchersTest.h"
 #include "clang/ASTMatchers/Dynamic/Parser.h"
 #include "clang/ASTMatchers/Dynamic/Registry.h"
-#include "gtest/gtest.h"
+#include "llvm/ADT/Optional.h"
 #include "llvm/ADT/StringMap.h"
+#include "gtest/gtest.h"
+#include <string>
+#include <vector>
 
 namespace clang {
 namespace ast_matchers {
@@ -39,15 +39,22 @@
     Errors.push_back(Error.toStringFull());
   }
 
-  VariantMatcher actOnMatcherExpression(StringRef MatcherName,
+  llvm::Optional<MatcherCtor> lookupMatcherCtor(StringRef MatcherName) {
+    const ExpectedMatchersTy::value_type *Matcher =
+        &*ExpectedMatchers.find(MatcherName);
+    return reinterpret_cast<MatcherCtor>(Matcher);
+  }
+
+  VariantMatcher actOnMatcherExpression(MatcherCtor Ctor,
                                         const SourceRange &NameRange,
                                         StringRef BindID,
                                         ArrayRef<ParserValue> Args,
                                         Diagnostics *Error) {
-    MatcherInfo ToStore = { MatcherName, NameRange, Args, BindID };
+    const ExpectedMatchersTy::value_type *Matcher =
+        reinterpret_cast<const ExpectedMatchersTy::value_type *>(Ctor);
+    MatcherInfo ToStore = { Matcher->first, NameRange, Args, BindID };
     Matchers.push_back(ToStore);
-    return VariantMatcher::SingleMatcher(
-        ExpectedMatchers.find(MatcherName)->second);
+    return VariantMatcher::SingleMatcher(Matcher->second);
   }
 
   struct MatcherInfo {
@@ -60,8 +67,9 @@
   std::vector<std::string> Errors;
   std::vector<VariantValue> Values;
   std::vector<MatcherInfo> Matchers;
-  std::map<std::string, ast_matchers::internal::Matcher<Stmt> >
-  ExpectedMatchers;
+  typedef std::map<std::string, ast_matchers::internal::Matcher<Stmt> >
+  ExpectedMatchersTy;
+  ExpectedMatchersTy ExpectedMatchers;
 };
 
 TEST(ParserTest, ParseUnsigned) {
@@ -165,6 +173,29 @@
   EXPECT_TRUE(matches("void f(int a, int x);", M));
   EXPECT_FALSE(matches("void f(int x, int a);", M));
 
+  // Test named values.
+  struct NamedSema : public Parser::RegistrySema {
+   public:
+    virtual VariantValue getNamedValue(StringRef Name) {
+      if (Name == "nameX")
+        return std::string("x");
+      if (Name == "param0")
+        return VariantMatcher::SingleMatcher(hasParameter(0, hasName("a")));
+      return VariantValue();
+    }
+  };
+  NamedSema Sema;
+  llvm::Optional<DynTypedMatcher> HasParameterWithNamedValues(
+      Parser::parseMatcherExpression(
+          "functionDecl(param0, hasParameter(1, hasName(nameX)))", &Sema,
+          &Error));
+  EXPECT_EQ("", Error.toStringFull());
+  M = HasParameterWithNamedValues->unconditionalConvertTo<Decl>();
+
+  EXPECT_TRUE(matches("void f(int a, int x);", M));
+  EXPECT_FALSE(matches("void f(int x, int a);", M));
+
+
   EXPECT_TRUE(!Parser::parseMatcherExpression(
                    "hasInitializer(\n    binaryOperator(hasLHS(\"A\")))",
                    &Error).hasValue());
@@ -194,16 +225,23 @@
       "1:5: Error parsing matcher. Found token <123> while looking for '('.",
       ParseWithError("Foo 123"));
   EXPECT_EQ(
+      "1:1: Matcher not found: Foo\n"
       "1:9: Error parsing matcher. Found token <123> while looking for ','.",
       ParseWithError("Foo(\"A\" 123)"));
   EXPECT_EQ(
+      "1:1: Error parsing argument 1 for matcher stmt.\n"
+      "1:6: Value not found: someValue",
+      ParseWithError("stmt(someValue)"));
+  EXPECT_EQ(
+      "1:1: Matcher not found: Foo\n"
       "1:4: Error parsing matcher. Found end-of-code while looking for ')'.",
       ParseWithError("Foo("));
   EXPECT_EQ("1:1: End of code found while looking for token.",
             ParseWithError(""));
   EXPECT_EQ("Input value is not a matcher expression.",
             ParseMatcherWithError("\"A\""));
-  EXPECT_EQ("1:1: Error parsing argument 1 for matcher Foo.\n"
+  EXPECT_EQ("1:1: Matcher not found: Foo\n"
+            "1:1: Error parsing argument 1 for matcher Foo.\n"
             "1:5: Invalid token <(> found when looking for a value.",
             ParseWithError("Foo(("));
   EXPECT_EQ("1:7: Expected end of code.", ParseWithError("expr()a"));
@@ -219,7 +257,7 @@
             "1:1: Matcher does not support binding.",
             ParseWithError("isArrow().bind(\"foo\")"));
   EXPECT_EQ("Input value has unresolved overloaded type: "
-            "Matcher<DoStmt|ForStmt|WhileStmt>",
+            "Matcher<DoStmt|ForStmt|WhileStmt|CXXForRangeStmt>",
             ParseMatcherWithError("hasBody(stmt())"));
 }
 
@@ -232,6 +270,20 @@
             ParseWithError("callee(\"A\")"));
 }
 
+TEST(ParserTest, Completion) {
+  std::vector<MatcherCompletion> Comps =
+      Parser::completeExpression("while", 5);
+  ASSERT_EQ(1u, Comps.size());
+  EXPECT_EQ("Stmt(", Comps[0].TypedText);
+  EXPECT_EQ("Matcher<Stmt> whileStmt(Matcher<WhileStmt>...)",
+            Comps[0].MatcherDecl);
+
+  Comps = Parser::completeExpression("whileStmt().", 12);
+  ASSERT_EQ(1u, Comps.size());
+  EXPECT_EQ("bind(\"", Comps[0].TypedText);
+  EXPECT_EQ("bind", Comps[0].MatcherDecl);
+}
+
 }  // end anonymous namespace
 }  // end namespace dynamic
 }  // end namespace ast_matchers
diff --git a/unittests/ASTMatchers/Dynamic/RegistryTest.cpp b/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
index e716484..e659b3a 100644
--- a/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
+++ b/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
@@ -7,11 +7,10 @@
 //
 //===-----------------------------------------------------------------------===//
 
-#include <vector>
-
 #include "../ASTMatchersTest.h"
 #include "clang/ASTMatchers/Dynamic/Registry.h"
 #include "gtest/gtest.h"
+#include <vector>
 
 namespace clang {
 namespace ast_matchers {
@@ -36,38 +35,94 @@
     return Out;
   }
 
+  llvm::Optional<MatcherCtor> lookupMatcherCtor(StringRef MatcherName) {
+    return Registry::lookupMatcherCtor(MatcherName);
+  }
+
   VariantMatcher constructMatcher(StringRef MatcherName,
-                                  Diagnostics *Error = NULL) {
+                                  Diagnostics *Error = nullptr) {
     Diagnostics DummyError;
     if (!Error) Error = &DummyError;
-    const VariantMatcher Out =
-        Registry::constructMatcher(MatcherName, SourceRange(), Args(), Error);
+    llvm::Optional<MatcherCtor> Ctor = lookupMatcherCtor(MatcherName);
+    VariantMatcher Out;
+    if (Ctor)
+      Out = Registry::constructMatcher(*Ctor, SourceRange(), Args(), Error);
     EXPECT_EQ("", DummyError.toStringFull());
     return Out;
   }
 
   VariantMatcher constructMatcher(StringRef MatcherName,
                                   const VariantValue &Arg1,
-                                  Diagnostics *Error = NULL) {
+                                  Diagnostics *Error = nullptr) {
     Diagnostics DummyError;
     if (!Error) Error = &DummyError;
-    const VariantMatcher Out = Registry::constructMatcher(
-        MatcherName, SourceRange(), Args(Arg1), Error);
-    EXPECT_EQ("", DummyError.toStringFull());
+    llvm::Optional<MatcherCtor> Ctor = lookupMatcherCtor(MatcherName);
+    VariantMatcher Out;
+    if (Ctor)
+      Out = Registry::constructMatcher(*Ctor, SourceRange(), Args(Arg1), Error);
+    EXPECT_EQ("", DummyError.toStringFull()) << MatcherName;
     return Out;
   }
 
   VariantMatcher constructMatcher(StringRef MatcherName,
                                   const VariantValue &Arg1,
                                   const VariantValue &Arg2,
-                                  Diagnostics *Error = NULL) {
+                                  Diagnostics *Error = nullptr) {
     Diagnostics DummyError;
     if (!Error) Error = &DummyError;
-    const VariantMatcher Out = Registry::constructMatcher(
-        MatcherName, SourceRange(), Args(Arg1, Arg2), Error);
+    llvm::Optional<MatcherCtor> Ctor = lookupMatcherCtor(MatcherName);
+    VariantMatcher Out;
+    if (Ctor)
+      Out = Registry::constructMatcher(*Ctor, SourceRange(), Args(Arg1, Arg2),
+                                       Error);
     EXPECT_EQ("", DummyError.toStringFull());
     return Out;
   }
+
+  typedef std::vector<MatcherCompletion> CompVector;
+
+  CompVector getCompletions() {
+    return Registry::getCompletions(
+        ArrayRef<std::pair<MatcherCtor, unsigned> >());
+  }
+
+  CompVector getCompletions(StringRef MatcherName1, unsigned ArgNo1) {
+    std::vector<std::pair<MatcherCtor, unsigned> > Context;
+    llvm::Optional<MatcherCtor> Ctor = lookupMatcherCtor(MatcherName1);
+    if (!Ctor)
+      return CompVector();
+    Context.push_back(std::make_pair(*Ctor, ArgNo1));
+    return Registry::getCompletions(Context);
+  }
+
+  CompVector getCompletions(StringRef MatcherName1, unsigned ArgNo1,
+                            StringRef MatcherName2, unsigned ArgNo2) {
+    std::vector<std::pair<MatcherCtor, unsigned> > Context;
+    llvm::Optional<MatcherCtor> Ctor = lookupMatcherCtor(MatcherName1);
+    if (!Ctor)
+      return CompVector();
+    Context.push_back(std::make_pair(*Ctor, ArgNo1));
+    Ctor = lookupMatcherCtor(MatcherName2);
+    if (!Ctor)
+      return CompVector();
+    Context.push_back(std::make_pair(*Ctor, ArgNo2));
+    return Registry::getCompletions(Context);
+  }
+
+  bool hasCompletion(const CompVector &Comps, StringRef TypedText,
+                     StringRef MatcherDecl = StringRef(),
+                     unsigned *Index = nullptr) {
+    for (CompVector::const_iterator I = Comps.begin(), E = Comps.end(); I != E;
+         ++I) {
+      if (I->TypedText == TypedText &&
+          (MatcherDecl.empty() || I->MatcherDecl == MatcherDecl)) {
+        if (Index)
+          *Index = I - Comps.begin();
+        return true;
+      }
+    }
+    return false;
+  }
 };
 
 TEST_F(RegistryTest, CanConstructNoArgs) {
@@ -151,6 +206,25 @@
   Code = "class Z { public: void z() { this->z(); } };";
   EXPECT_TRUE(matches(Code, CallExpr0));
   EXPECT_FALSE(matches(Code, CallExpr1));
+
+  Matcher<Decl> DeclDecl = declaratorDecl(hasTypeLoc(
+      constructMatcher(
+          "loc", constructMatcher("asString", std::string("const double *")))
+          .getTypedMatcher<TypeLoc>()));
+
+  Matcher<NestedNameSpecifierLoc> NNSL =
+      constructMatcher(
+          "loc", VariantMatcher::SingleMatcher(nestedNameSpecifier(
+                     specifiesType(hasDeclaration(recordDecl(hasName("A")))))))
+          .getTypedMatcher<NestedNameSpecifierLoc>();
+
+  Code = "const double * x = 0;";
+  EXPECT_TRUE(matches(Code, DeclDecl));
+  EXPECT_FALSE(matches(Code, NNSL));
+
+  Code = "struct A { struct B {}; }; A::B a_b;";
+  EXPECT_FALSE(matches(Code, DeclDecl));
+  EXPECT_TRUE(matches(Code, NNSL));
 }
 
 TEST_F(RegistryTest, PolymorphicMatchers) {
@@ -295,11 +369,22 @@
   EXPECT_FALSE(matches("int i = 0;", D));
   EXPECT_TRUE(matches("class Bar{};", D));
   EXPECT_FALSE(matches("class OtherBar{};", D));
+
+  D = recordDecl(
+      has(fieldDecl(hasName("Foo"))),
+      constructMatcher(
+          "unless",
+          constructMatcher("namedDecl",
+                           constructMatcher("hasName", std::string("Bar"))))
+          .getTypedMatcher<Decl>());
+
+  EXPECT_FALSE(matches("class Bar{ int Foo; };", D));
+  EXPECT_TRUE(matches("class OtherBar{ int Foo; };", D));
 }
 
 TEST_F(RegistryTest, Errors) {
   // Incorrect argument count.
-  OwningPtr<Diagnostics> Error(new Diagnostics());
+  std::unique_ptr<Diagnostics> Error(new Diagnostics());
   EXPECT_TRUE(constructMatcher("hasInitializer", Error.get()).isNull());
   EXPECT_EQ("Incorrect argument count. (Expected = 1) != (Actual = 0)",
             Error->toString());
@@ -307,6 +392,15 @@
   EXPECT_TRUE(constructMatcher("isArrow", std::string(), Error.get()).isNull());
   EXPECT_EQ("Incorrect argument count. (Expected = 0) != (Actual = 1)",
             Error->toString());
+  Error.reset(new Diagnostics());
+  EXPECT_TRUE(constructMatcher("anyOf", Error.get()).isNull());
+  EXPECT_EQ("Incorrect argument count. (Expected = (2, )) != (Actual = 0)",
+            Error->toString());
+  Error.reset(new Diagnostics());
+  EXPECT_TRUE(constructMatcher("unless", std::string(), std::string(),
+                               Error.get()).isNull());
+  EXPECT_EQ("Incorrect argument count. (Expected = (1, 1)) != (Actual = 2)",
+            Error->toString());
 
   // Bad argument type
   Error.reset(new Diagnostics());
@@ -324,7 +418,8 @@
 
   // Bad argument type with variadic.
   Error.reset(new Diagnostics());
-  EXPECT_TRUE(constructMatcher("anyOf", std::string(), Error.get()).isNull());
+  EXPECT_TRUE(constructMatcher("anyOf", std::string(), std::string(),
+                               Error.get()).isNull());
   EXPECT_EQ(
       "Incorrect type for arg 1. (Expected = Matcher<>) != (Actual = String)",
       Error->toString());
@@ -341,6 +436,47 @@
             Error->toString());
 }
 
+TEST_F(RegistryTest, Completion) {
+  CompVector Comps = getCompletions();
+  EXPECT_TRUE(hasCompletion(
+      Comps, "hasParent(", "Matcher<Decl|Stmt> hasParent(Matcher<Decl|Stmt>)"));
+  EXPECT_TRUE(hasCompletion(Comps, "whileStmt(",
+                            "Matcher<Stmt> whileStmt(Matcher<WhileStmt>...)"));
+
+  CompVector WhileComps = getCompletions("whileStmt", 0);
+
+  unsigned HasBodyIndex, HasParentIndex, AllOfIndex;
+  EXPECT_TRUE(hasCompletion(WhileComps, "hasBody(",
+                            "Matcher<WhileStmt> hasBody(Matcher<Stmt>)",
+                            &HasBodyIndex));
+  EXPECT_TRUE(hasCompletion(WhileComps, "hasParent(",
+                            "Matcher<Stmt> hasParent(Matcher<Decl|Stmt>)",
+                            &HasParentIndex));
+  EXPECT_TRUE(hasCompletion(WhileComps, "allOf(",
+                            "Matcher<T> allOf(Matcher<T>...)", &AllOfIndex));
+  EXPECT_GT(HasParentIndex, HasBodyIndex);
+  EXPECT_GT(AllOfIndex, HasParentIndex);
+
+  EXPECT_FALSE(hasCompletion(WhileComps, "whileStmt("));
+  EXPECT_FALSE(hasCompletion(WhileComps, "ifStmt("));
+
+  CompVector AllOfWhileComps =
+      getCompletions("allOf", 0, "whileStmt", 0);
+  ASSERT_EQ(AllOfWhileComps.size(), WhileComps.size());
+  EXPECT_TRUE(std::equal(WhileComps.begin(), WhileComps.end(),
+                         AllOfWhileComps.begin()));
+
+  CompVector DeclWhileComps =
+      getCompletions("decl", 0, "whileStmt", 0);
+  EXPECT_EQ(0u, DeclWhileComps.size());
+
+  CompVector NamedDeclComps = getCompletions("namedDecl", 0);
+  EXPECT_TRUE(
+      hasCompletion(NamedDeclComps, "isPublic()", "Matcher<Decl> isPublic()"));
+  EXPECT_TRUE(hasCompletion(NamedDeclComps, "hasName(\"",
+                            "Matcher<NamedDecl> hasName(string)"));
+}
+
 } // end anonymous namespace
 } // end namespace dynamic
 } // end namespace ast_matchers
diff --git a/unittests/ASTMatchers/Dynamic/VariantValueTest.cpp b/unittests/ASTMatchers/Dynamic/VariantValueTest.cpp
index d2b8a58..524b73d 100644
--- a/unittests/ASTMatchers/Dynamic/VariantValueTest.cpp
+++ b/unittests/ASTMatchers/Dynamic/VariantValueTest.cpp
@@ -26,6 +26,7 @@
   EXPECT_TRUE(Value.isUnsigned());
   EXPECT_EQ(kUnsigned, Value.getUnsigned());
 
+  EXPECT_TRUE(Value.hasValue());
   EXPECT_FALSE(Value.isString());
   EXPECT_FALSE(Value.isMatcher());
 }
@@ -38,6 +39,7 @@
   EXPECT_EQ(kString, Value.getString());
   EXPECT_EQ("String", Value.getTypeAsString());
 
+  EXPECT_TRUE(Value.hasValue());
   EXPECT_FALSE(Value.isUnsigned());
   EXPECT_FALSE(Value.isMatcher());
 }
@@ -45,6 +47,7 @@
 TEST(VariantValueTest, DynTypedMatcher) {
   VariantValue Value = VariantMatcher::SingleMatcher(stmt());
 
+  EXPECT_TRUE(Value.hasValue());
   EXPECT_FALSE(Value.isUnsigned());
   EXPECT_FALSE(Value.isString());
 
@@ -74,11 +77,13 @@
   VariantValue Value = std::string("A");
   EXPECT_TRUE(Value.isString());
   EXPECT_EQ("A", Value.getString());
+  EXPECT_TRUE(Value.hasValue());
   EXPECT_FALSE(Value.isUnsigned());
   EXPECT_FALSE(Value.isMatcher());
   EXPECT_EQ("String", Value.getTypeAsString());
 
   Value = VariantMatcher::SingleMatcher(recordDecl());
+  EXPECT_TRUE(Value.hasValue());
   EXPECT_FALSE(Value.isUnsigned());
   EXPECT_FALSE(Value.isString());
   EXPECT_TRUE(Value.isMatcher());
@@ -89,16 +94,36 @@
   Value = 17;
   EXPECT_TRUE(Value.isUnsigned());
   EXPECT_EQ(17U, Value.getUnsigned());
+  EXPECT_TRUE(Value.hasValue());
   EXPECT_FALSE(Value.isMatcher());
   EXPECT_FALSE(Value.isString());
 
   Value = VariantValue();
+  EXPECT_FALSE(Value.hasValue());
   EXPECT_FALSE(Value.isUnsigned());
   EXPECT_FALSE(Value.isString());
   EXPECT_FALSE(Value.isMatcher());
   EXPECT_EQ("Nothing", Value.getTypeAsString());
 }
 
+TEST(VariantValueTest, ImplicitBool) {
+  VariantValue Value;
+  bool IfTrue = false;
+  if (Value) {
+    IfTrue = true;
+  }
+  EXPECT_FALSE(IfTrue);
+  EXPECT_TRUE(!Value);
+
+  Value = std::string();
+  IfTrue = false;
+  if (Value) {
+    IfTrue = true;
+  }
+  EXPECT_TRUE(IfTrue);
+  EXPECT_FALSE(!Value);
+}
+
 TEST(VariantValueTest, Matcher) {
   EXPECT_TRUE(matches("class X {};", VariantValue(VariantMatcher::SingleMatcher(
                                                       recordDecl(hasName("X"))))
@@ -117,7 +142,7 @@
   EXPECT_FALSE(VariantValue(VariantMatcher::SingleMatcher(varDecl()))
                    .getMatcher()
                    .hasTypedMatcher<Stmt>());
-#if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST && !defined(_MSC_VER)
+#if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST
   // Trying to get the wrong matcher fails an assertion in Matcher<T>.  We don't
   // do this test when building with MSVC because its debug C runtime prints the
   // assertion failure message as a wide string, which gtest doesn't understand.
diff --git a/unittests/ASTMatchers/Makefile b/unittests/ASTMatchers/Makefile
index dad300c..92f2fa0 100644
--- a/unittests/ASTMatchers/Makefile
+++ b/unittests/ASTMatchers/Makefile
@@ -15,7 +15,7 @@
 include $(CLANG_LEVEL)/../../Makefile.config
 LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option
 USEDLIBS = clangTooling.a clangFrontend.a clangSerialization.a clangDriver.a \
-           clangRewriteCore.a clangRewriteFrontend.a \
+           clangRewrite.a clangRewriteFrontend.a \
            clangParse.a clangSema.a clangAnalysis.a \
            clangEdit.a clangAST.a clangASTMatchers.a clangLex.a clangBasic.a
 
diff --git a/unittests/Basic/CMakeLists.txt b/unittests/Basic/CMakeLists.txt
index 51db6ce..b8f69bf 100644
--- a/unittests/Basic/CMakeLists.txt
+++ b/unittests/Basic/CMakeLists.txt
@@ -1,7 +1,12 @@
+set(LLVM_LINK_COMPONENTS
+  Support
+  )
+
 add_clang_unittest(BasicTests
   CharInfoTest.cpp
   FileManagerTest.cpp
   SourceManagerTest.cpp
+  VirtualFileSystemTest.cpp
   )
 
 target_link_libraries(BasicTests
diff --git a/unittests/Basic/FileManagerTest.cpp b/unittests/Basic/FileManagerTest.cpp
index f8ce50d..b3bc767 100644
--- a/unittests/Basic/FileManagerTest.cpp
+++ b/unittests/Basic/FileManagerTest.cpp
@@ -11,6 +11,7 @@
 #include "clang/Basic/FileSystemOptions.h"
 #include "clang/Basic/FileSystemStatCache.h"
 #include "gtest/gtest.h"
+#include "llvm/Config/llvm-config.h"
 
 using namespace llvm;
 using namespace clang;
@@ -28,10 +29,13 @@
 
   void InjectFileOrDirectory(const char *Path, ino_t INode, bool IsFile) {
     FileData Data;
-    memset(&Data, 0, sizeof(FileData));
-    llvm::sys::fs::UniqueID ID(1, INode);
-    Data.UniqueID = ID;
+    Data.Name = Path;
+    Data.Size = 0;
+    Data.ModTime = 0;
+    Data.UniqueID = llvm::sys::fs::UniqueID(1, INode);
     Data.IsDirectory = !IsFile;
+    Data.IsNamedPipe = false;
+    Data.InPCH = false;
     StatCalls[Path] = Data;
   }
 
@@ -47,8 +51,9 @@
   }
 
   // Implement FileSystemStatCache::getStat().
-  virtual LookupResult getStat(const char *Path, FileData &Data, bool isFile,
-                               int *FileDescriptor) {
+  LookupResult getStat(const char *Path, FileData &Data, bool isFile,
+                       std::unique_ptr<vfs::File> *F,
+                       vfs::FileSystem &FS) override {
     if (StatCalls.count(Path) != 0) {
       Data = StatCalls[Path];
       return CacheExists;
@@ -72,17 +77,17 @@
 // (not NULL, correct name).
 TEST_F(FileManagerTest, getVirtualFileSetsTheDirFieldCorrectly) {
   const FileEntry *file = manager.getVirtualFile("foo.cpp", 42, 0);
-  ASSERT_TRUE(file != NULL);
+  ASSERT_TRUE(file != nullptr);
 
   const DirectoryEntry *dir = file->getDir();
-  ASSERT_TRUE(dir != NULL);
+  ASSERT_TRUE(dir != nullptr);
   EXPECT_STREQ(".", dir->getName());
 
   file = manager.getVirtualFile("x/y/z.cpp", 42, 0);
-  ASSERT_TRUE(file != NULL);
+  ASSERT_TRUE(file != nullptr);
 
   dir = file->getDir();
-  ASSERT_TRUE(dir != NULL);
+  ASSERT_TRUE(dir != nullptr);
   EXPECT_STREQ("x/y", dir->getName());
 }
 
@@ -94,9 +99,9 @@
   // by what's in the real file system.
   manager.addStatCache(new FakeStatCache);
 
-  EXPECT_EQ(NULL, manager.getDirectory("virtual/dir/foo"));
-  EXPECT_EQ(NULL, manager.getDirectory("virtual/dir"));
-  EXPECT_EQ(NULL, manager.getDirectory("virtual"));
+  EXPECT_EQ(nullptr, manager.getDirectory("virtual/dir/foo"));
+  EXPECT_EQ(nullptr, manager.getDirectory("virtual/dir"));
+  EXPECT_EQ(nullptr, manager.getDirectory("virtual"));
 }
 
 // When a virtual file is added, all of its ancestors should be created.
@@ -105,14 +110,14 @@
   manager.addStatCache(new FakeStatCache);
 
   manager.getVirtualFile("virtual/dir/bar.h", 100, 0);
-  EXPECT_EQ(NULL, manager.getDirectory("virtual/dir/foo"));
+  EXPECT_EQ(nullptr, manager.getDirectory("virtual/dir/foo"));
 
   const DirectoryEntry *dir = manager.getDirectory("virtual/dir");
-  ASSERT_TRUE(dir != NULL);
+  ASSERT_TRUE(dir != nullptr);
   EXPECT_STREQ("virtual/dir", dir->getName());
 
   dir = manager.getDirectory("virtual");
-  ASSERT_TRUE(dir != NULL);
+  ASSERT_TRUE(dir != nullptr);
   EXPECT_STREQ("virtual", dir->getName());
 }
 
@@ -123,7 +128,7 @@
   statCache->InjectDirectory("/tmp", 42);
   statCache->InjectFile("/tmp/test", 43);
 
-#ifdef _WIN32
+#ifdef LLVM_ON_WIN32
   const char *DirName = "C:.";
   const char *FileName = "C:test";
   statCache->InjectDirectory(DirName, 44);
@@ -133,14 +138,14 @@
   manager.addStatCache(statCache);
 
   const FileEntry *file = manager.getFile("/tmp/test");
-  ASSERT_TRUE(file != NULL);
+  ASSERT_TRUE(file != nullptr);
   EXPECT_STREQ("/tmp/test", file->getName());
 
   const DirectoryEntry *dir = file->getDir();
-  ASSERT_TRUE(dir != NULL);
+  ASSERT_TRUE(dir != nullptr);
   EXPECT_STREQ("/tmp", dir->getName());
 
-#ifdef _WIN32
+#ifdef LLVM_ON_WIN32
   file = manager.getFile(FileName);
   ASSERT_TRUE(file != NULL);
 
@@ -157,11 +162,11 @@
 
   manager.getVirtualFile("virtual/dir/bar.h", 100, 0);
   const FileEntry *file = manager.getFile("virtual/dir/bar.h");
-  ASSERT_TRUE(file != NULL);
+  ASSERT_TRUE(file != nullptr);
   EXPECT_STREQ("virtual/dir/bar.h", file->getName());
 
   const DirectoryEntry *dir = file->getDir();
-  ASSERT_TRUE(dir != NULL);
+  ASSERT_TRUE(dir != nullptr);
   EXPECT_STREQ("virtual/dir", dir->getName());
 }
 
@@ -178,8 +183,8 @@
 
   const FileEntry *fileFoo = manager.getFile("foo.cpp");
   const FileEntry *fileBar = manager.getFile("bar.cpp");
-  ASSERT_TRUE(fileFoo != NULL);
-  ASSERT_TRUE(fileBar != NULL);
+  ASSERT_TRUE(fileFoo != nullptr);
+  ASSERT_TRUE(fileBar != nullptr);
   EXPECT_NE(fileFoo, fileBar);
 }
 
@@ -196,12 +201,12 @@
   manager.getVirtualFile("bar.cpp", 200, 0);
 
   const FileEntry *file = manager.getFile("xyz.txt");
-  EXPECT_EQ(NULL, file);
+  EXPECT_EQ(nullptr, file);
 }
 
 // The following tests apply to Unix-like system only.
 
-#ifndef _WIN32
+#ifndef LLVM_ON_WIN32
 
 // getFile() returns the same FileEntry for real files that are aliases.
 TEST_F(FileManagerTest, getFileReturnsSameFileEntryForAliasedRealFiles) {
@@ -231,6 +236,6 @@
   EXPECT_EQ(manager.getFile("abc/foo.cpp"), manager.getFile("abc/bar.cpp"));
 }
 
-#endif  // !_WIN32
+#endif  // !LLVM_ON_WIN32
 
 } // anonymous namespace
diff --git a/unittests/Basic/SourceManagerTest.cpp b/unittests/Basic/SourceManagerTest.cpp
index d94cfe9..9ea093c 100644
--- a/unittests/Basic/SourceManagerTest.cpp
+++ b/unittests/Basic/SourceManagerTest.cpp
@@ -20,7 +20,7 @@
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Lex/PreprocessorOptions.h"
 #include "llvm/ADT/SmallString.h"
-#include "llvm/Config/config.h"
+#include "llvm/Config/llvm-config.h"
 #include "gtest/gtest.h"
 
 using namespace llvm;
@@ -38,7 +38,7 @@
       SourceMgr(Diags, FileMgr),
       TargetOpts(new TargetOptions) {
     TargetOpts->Triple = "x86_64-apple-darwin11.1.0";
-    Target = TargetInfo::CreateTargetInfo(Diags, &*TargetOpts);
+    Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
   }
 
   FileSystemOptions FileMgrOpts;
@@ -47,22 +47,27 @@
   DiagnosticsEngine Diags;
   SourceManager SourceMgr;
   LangOptions LangOpts;
-  IntrusiveRefCntPtr<TargetOptions> TargetOpts;
+  std::shared_ptr<TargetOptions> TargetOpts;
   IntrusiveRefCntPtr<TargetInfo> Target;
 };
 
 class VoidModuleLoader : public ModuleLoader {
-  virtual ModuleLoadResult loadModule(SourceLocation ImportLoc, 
-                                      ModuleIdPath Path,
-                                      Module::NameVisibilityKind Visibility,
-                                      bool IsInclusionDirective) {
+  ModuleLoadResult loadModule(SourceLocation ImportLoc, 
+                              ModuleIdPath Path,
+                              Module::NameVisibilityKind Visibility,
+                              bool IsInclusionDirective) override {
     return ModuleLoadResult();
   }
 
-  virtual void makeModuleVisible(Module *Mod,
-                                 Module::NameVisibilityKind Visibility,
-                                 SourceLocation ImportLoc,
-                                 bool Complain) { }
+  void makeModuleVisible(Module *Mod,
+                         Module::NameVisibilityKind Visibility,
+                         SourceLocation ImportLoc,
+                         bool Complain) override { }
+
+  GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override
+    { return nullptr; }
+  bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override
+    { return 0; };
 };
 
 TEST_F(SourceManagerTest, isBeforeInTranslationUnit) {
@@ -70,16 +75,17 @@
     "#define M(x) [x]\n"
     "M(foo)";
   MemoryBuffer *buf = MemoryBuffer::getMemBuffer(source);
-  FileID mainFileID = SourceMgr.createMainFileIDForMemBuffer(buf);
+  FileID mainFileID = SourceMgr.createFileID(buf);
+  SourceMgr.setMainFileID(mainFileID);
 
   VoidModuleLoader ModLoader;
   HeaderSearch HeaderInfo(new HeaderSearchOptions, SourceMgr, Diags, LangOpts, 
                           &*Target);
-  Preprocessor PP(new PreprocessorOptions(), Diags, LangOpts, Target.getPtr(),
-                  SourceMgr, HeaderInfo, ModLoader,
-                  /*IILookup =*/ 0,
-                  /*OwnsHeaderSearch =*/false,
-                  /*DelayInitialization =*/ false);
+  Preprocessor PP(new PreprocessorOptions(), Diags, LangOpts, SourceMgr,
+                  HeaderInfo, ModLoader,
+                  /*IILookup =*/nullptr,
+                  /*OwnsHeaderSearch =*/false);
+  PP.Initialize(*Target);
   PP.EnterMainSourceFile();
 
   std::vector<Token> toks;
@@ -122,7 +128,8 @@
     "int y;";
 
   MemoryBuffer *Buf = MemoryBuffer::getMemBuffer(Source);
-  FileID MainFileID = SourceMgr.createMainFileIDForMemBuffer(Buf);
+  FileID MainFileID = SourceMgr.createFileID(Buf);
+  SourceMgr.setMainFileID(MainFileID);
 
   bool Invalid;
 
@@ -161,7 +168,7 @@
   EXPECT_TRUE(Invalid);
 
   // Test with no invalid flag.
-  EXPECT_EQ(1U, SourceMgr.getColumnNumber(MainFileID, 0, NULL));
+  EXPECT_EQ(1U, SourceMgr.getColumnNumber(MainFileID, 0, nullptr));
 }
 
 #if defined(LLVM_ON_UNIX)
@@ -181,7 +188,8 @@
 
   MemoryBuffer *headerBuf = MemoryBuffer::getMemBuffer(header);
   MemoryBuffer *mainBuf = MemoryBuffer::getMemBuffer(main);
-  FileID mainFileID = SourceMgr.createMainFileIDForMemBuffer(mainBuf);
+  FileID mainFileID = SourceMgr.createFileID(mainBuf);
+  SourceMgr.setMainFileID(mainFileID);
 
   const FileEntry *headerFile = FileMgr.getVirtualFile("/test-header.h",
                                                  headerBuf->getBufferSize(), 0);
@@ -190,11 +198,11 @@
   VoidModuleLoader ModLoader;
   HeaderSearch HeaderInfo(new HeaderSearchOptions, SourceMgr, Diags, LangOpts, 
                           &*Target);
-  Preprocessor PP(new PreprocessorOptions(), Diags, LangOpts, Target.getPtr(),
-                  SourceMgr, HeaderInfo, ModLoader,
-                  /*IILookup =*/ 0,
-                  /*OwnsHeaderSearch =*/false,
-                  /*DelayInitialization =*/ false);
+  Preprocessor PP(new PreprocessorOptions(), Diags, LangOpts, SourceMgr,
+                  HeaderInfo, ModLoader,
+                  /*IILookup =*/nullptr,
+                  /*OwnsHeaderSearch =*/false);
+  PP.Initialize(*Target);
   PP.EnterMainSourceFile();
 
   std::vector<Token> toks;
@@ -279,7 +287,7 @@
 
   MemoryBuffer *headerBuf = MemoryBuffer::getMemBuffer(header);
   MemoryBuffer *mainBuf = MemoryBuffer::getMemBuffer(main);
-  SourceMgr.createMainFileIDForMemBuffer(mainBuf);
+  SourceMgr.setMainFileID(SourceMgr.createFileID(mainBuf));
 
   const FileEntry *headerFile = FileMgr.getVirtualFile("/test-header.h",
                                                  headerBuf->getBufferSize(), 0);
@@ -288,11 +296,11 @@
   VoidModuleLoader ModLoader;
   HeaderSearch HeaderInfo(new HeaderSearchOptions, SourceMgr, Diags, LangOpts, 
                           &*Target);
-  Preprocessor PP(new PreprocessorOptions(), Diags, LangOpts, Target.getPtr(),
-                  SourceMgr, HeaderInfo, ModLoader,
-                  /*IILookup =*/ 0,
-                  /*OwnsHeaderSearch =*/false,
-                  /*DelayInitialization =*/ false);
+  Preprocessor PP(new PreprocessorOptions(), Diags, LangOpts, SourceMgr,
+                  HeaderInfo, ModLoader,
+                  /*IILookup =*/nullptr,
+                  /*OwnsHeaderSearch =*/false);
+  PP.Initialize(*Target);
 
   std::vector<MacroAction> Macros;
   PP.addPPCallbacks(new MacroTracker(Macros));
diff --git a/unittests/Basic/VirtualFileSystemTest.cpp b/unittests/Basic/VirtualFileSystemTest.cpp
new file mode 100644
index 0000000..e7d361e
--- /dev/null
+++ b/unittests/Basic/VirtualFileSystemTest.cpp
@@ -0,0 +1,934 @@
+//===- unittests/Basic/VirtualFileSystem.cpp ---------------- VFS tests ---===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/VirtualFileSystem.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/SourceMgr.h"
+#include "gtest/gtest.h"
+#include <map>
+using namespace clang;
+using namespace llvm;
+using llvm::sys::fs::UniqueID;
+
+namespace {
+class DummyFileSystem : public vfs::FileSystem {
+  int FSID;   // used to produce UniqueIDs
+  int FileID; // used to produce UniqueIDs
+  std::map<std::string, vfs::Status> FilesAndDirs;
+
+  static int getNextFSID() {
+    static int Count = 0;
+    return Count++;
+  }
+
+public:
+  DummyFileSystem() : FSID(getNextFSID()), FileID(0) {}
+
+  ErrorOr<vfs::Status> status(const Twine &Path) {
+    std::map<std::string, vfs::Status>::iterator I =
+        FilesAndDirs.find(Path.str());
+    if (I == FilesAndDirs.end())
+      return make_error_code(llvm::errc::no_such_file_or_directory);
+    return I->second;
+  }
+  std::error_code openFileForRead(const Twine &Path,
+                                  std::unique_ptr<vfs::File> &Result) {
+    llvm_unreachable("unimplemented");
+  }
+  std::error_code getBufferForFile(const Twine &Name,
+                                   std::unique_ptr<MemoryBuffer> &Result,
+                                   int64_t FileSize = -1,
+                                   bool RequiresNullTerminator = true) {
+    llvm_unreachable("unimplemented");
+  }
+
+  struct DirIterImpl : public clang::vfs::detail::DirIterImpl {
+    std::map<std::string, vfs::Status> &FilesAndDirs;
+    std::map<std::string, vfs::Status>::iterator I;
+    std::string Path;
+    bool isInPath(StringRef S) {
+      if (Path.size() < S.size() && S.find(Path) == 0) {
+        auto LastSep = S.find_last_of('/');
+        if (LastSep == Path.size() || LastSep == Path.size()-1)
+          return true;
+      }
+      return false;
+    }
+    DirIterImpl(std::map<std::string, vfs::Status> &FilesAndDirs,
+                const Twine &_Path)
+        : FilesAndDirs(FilesAndDirs), I(FilesAndDirs.begin()),
+          Path(_Path.str()) {
+      for ( ; I != FilesAndDirs.end(); ++I) {
+        if (isInPath(I->first)) {
+          CurrentEntry = I->second;
+          break;
+        }
+      }
+    }
+    std::error_code increment() override {
+      ++I;
+      for ( ; I != FilesAndDirs.end(); ++I) {
+        if (isInPath(I->first)) {
+          CurrentEntry = I->second;
+          break;
+        }
+      }
+      if (I == FilesAndDirs.end())
+        CurrentEntry = vfs::Status();
+      return std::error_code();
+    }
+  };
+
+  vfs::directory_iterator dir_begin(const Twine &Dir,
+                                    std::error_code &EC) override {
+    return vfs::directory_iterator(
+        std::make_shared<DirIterImpl>(FilesAndDirs, Dir));
+  }
+
+  void addEntry(StringRef Path, const vfs::Status &Status) {
+    FilesAndDirs[Path] = Status;
+  }
+
+  void addRegularFile(StringRef Path, sys::fs::perms Perms = sys::fs::all_all) {
+    vfs::Status S(Path, Path, UniqueID(FSID, FileID++), sys::TimeValue::now(),
+                  0, 0, 1024, sys::fs::file_type::regular_file, Perms);
+    addEntry(Path, S);
+  }
+
+  void addDirectory(StringRef Path, sys::fs::perms Perms = sys::fs::all_all) {
+    vfs::Status S(Path, Path, UniqueID(FSID, FileID++), sys::TimeValue::now(),
+                  0, 0, 0, sys::fs::file_type::directory_file, Perms);
+    addEntry(Path, S);
+  }
+
+  void addSymlink(StringRef Path) {
+    vfs::Status S(Path, Path, UniqueID(FSID, FileID++), sys::TimeValue::now(),
+                  0, 0, 0, sys::fs::file_type::symlink_file, sys::fs::all_all);
+    addEntry(Path, S);
+  }
+};
+} // end anonymous namespace
+
+TEST(VirtualFileSystemTest, StatusQueries) {
+  IntrusiveRefCntPtr<DummyFileSystem> D(new DummyFileSystem());
+  ErrorOr<vfs::Status> Status((std::error_code()));
+
+  D->addRegularFile("/foo");
+  Status = D->status("/foo");
+  ASSERT_FALSE(Status.getError());
+  EXPECT_TRUE(Status->isStatusKnown());
+  EXPECT_FALSE(Status->isDirectory());
+  EXPECT_TRUE(Status->isRegularFile());
+  EXPECT_FALSE(Status->isSymlink());
+  EXPECT_FALSE(Status->isOther());
+  EXPECT_TRUE(Status->exists());
+
+  D->addDirectory("/bar");
+  Status = D->status("/bar");
+  ASSERT_FALSE(Status.getError());
+  EXPECT_TRUE(Status->isStatusKnown());
+  EXPECT_TRUE(Status->isDirectory());
+  EXPECT_FALSE(Status->isRegularFile());
+  EXPECT_FALSE(Status->isSymlink());
+  EXPECT_FALSE(Status->isOther());
+  EXPECT_TRUE(Status->exists());
+
+  D->addSymlink("/baz");
+  Status = D->status("/baz");
+  ASSERT_FALSE(Status.getError());
+  EXPECT_TRUE(Status->isStatusKnown());
+  EXPECT_FALSE(Status->isDirectory());
+  EXPECT_FALSE(Status->isRegularFile());
+  EXPECT_TRUE(Status->isSymlink());
+  EXPECT_FALSE(Status->isOther());
+  EXPECT_TRUE(Status->exists());
+
+  EXPECT_TRUE(Status->equivalent(*Status));
+  ErrorOr<vfs::Status> Status2 = D->status("/foo");
+  ASSERT_FALSE(Status2.getError());
+  EXPECT_FALSE(Status->equivalent(*Status2));
+}
+
+TEST(VirtualFileSystemTest, BaseOnlyOverlay) {
+  IntrusiveRefCntPtr<DummyFileSystem> D(new DummyFileSystem());
+  ErrorOr<vfs::Status> Status((std::error_code()));
+  EXPECT_FALSE(Status = D->status("/foo"));
+
+  IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(new vfs::OverlayFileSystem(D));
+  EXPECT_FALSE(Status = O->status("/foo"));
+
+  D->addRegularFile("/foo");
+  Status = D->status("/foo");
+  EXPECT_FALSE(Status.getError());
+
+  ErrorOr<vfs::Status> Status2((std::error_code()));
+  Status2 = O->status("/foo");
+  EXPECT_FALSE(Status2.getError());
+  EXPECT_TRUE(Status->equivalent(*Status2));
+}
+
+TEST(VirtualFileSystemTest, OverlayFiles) {
+  IntrusiveRefCntPtr<DummyFileSystem> Base(new DummyFileSystem());
+  IntrusiveRefCntPtr<DummyFileSystem> Middle(new DummyFileSystem());
+  IntrusiveRefCntPtr<DummyFileSystem> Top(new DummyFileSystem());
+  IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
+      new vfs::OverlayFileSystem(Base));
+  O->pushOverlay(Middle);
+  O->pushOverlay(Top);
+
+  ErrorOr<vfs::Status> Status1((std::error_code())),
+      Status2((std::error_code())), Status3((std::error_code())),
+      StatusB((std::error_code())), StatusM((std::error_code())),
+      StatusT((std::error_code()));
+
+  Base->addRegularFile("/foo");
+  StatusB = Base->status("/foo");
+  ASSERT_FALSE(StatusB.getError());
+  Status1 = O->status("/foo");
+  ASSERT_FALSE(Status1.getError());
+  Middle->addRegularFile("/foo");
+  StatusM = Middle->status("/foo");
+  ASSERT_FALSE(StatusM.getError());
+  Status2 = O->status("/foo");
+  ASSERT_FALSE(Status2.getError());
+  Top->addRegularFile("/foo");
+  StatusT = Top->status("/foo");
+  ASSERT_FALSE(StatusT.getError());
+  Status3 = O->status("/foo");
+  ASSERT_FALSE(Status3.getError());
+
+  EXPECT_TRUE(Status1->equivalent(*StatusB));
+  EXPECT_TRUE(Status2->equivalent(*StatusM));
+  EXPECT_TRUE(Status3->equivalent(*StatusT));
+
+  EXPECT_FALSE(Status1->equivalent(*Status2));
+  EXPECT_FALSE(Status2->equivalent(*Status3));
+  EXPECT_FALSE(Status1->equivalent(*Status3));
+}
+
+TEST(VirtualFileSystemTest, OverlayDirsNonMerged) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem());
+  IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
+      new vfs::OverlayFileSystem(Lower));
+  O->pushOverlay(Upper);
+
+  Lower->addDirectory("/lower-only");
+  Upper->addDirectory("/upper-only");
+
+  // non-merged paths should be the same
+  ErrorOr<vfs::Status> Status1 = Lower->status("/lower-only");
+  ASSERT_FALSE(Status1.getError());
+  ErrorOr<vfs::Status> Status2 = O->status("/lower-only");
+  ASSERT_FALSE(Status2.getError());
+  EXPECT_TRUE(Status1->equivalent(*Status2));
+
+  Status1 = Upper->status("/upper-only");
+  ASSERT_FALSE(Status1.getError());
+  Status2 = O->status("/upper-only");
+  ASSERT_FALSE(Status2.getError());
+  EXPECT_TRUE(Status1->equivalent(*Status2));
+}
+
+TEST(VirtualFileSystemTest, MergedDirPermissions) {
+  // merged directories get the permissions of the upper dir
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem());
+  IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
+      new vfs::OverlayFileSystem(Lower));
+  O->pushOverlay(Upper);
+
+  ErrorOr<vfs::Status> Status((std::error_code()));
+  Lower->addDirectory("/both", sys::fs::owner_read);
+  Upper->addDirectory("/both", sys::fs::owner_all | sys::fs::group_read);
+  Status = O->status("/both");
+  ASSERT_FALSE(Status.getError());
+  EXPECT_EQ(0740, Status->getPermissions());
+
+  // permissions (as usual) are not recursively applied
+  Lower->addRegularFile("/both/foo", sys::fs::owner_read);
+  Upper->addRegularFile("/both/bar", sys::fs::owner_write);
+  Status = O->status("/both/foo");
+  ASSERT_FALSE( Status.getError());
+  EXPECT_EQ(0400, Status->getPermissions());
+  Status = O->status("/both/bar");
+  ASSERT_FALSE(Status.getError());
+  EXPECT_EQ(0200, Status->getPermissions());
+}
+
+namespace {
+struct ScopedDir {
+  SmallString<128> Path;
+  ScopedDir(const Twine &Name, bool Unique=false) {
+    std::error_code EC;
+    if (Unique) {
+      EC =  llvm::sys::fs::createUniqueDirectory(Name, Path);
+    } else {
+      Path = Name.str();
+      EC = llvm::sys::fs::create_directory(Twine(Path));
+    }
+    if (EC)
+      Path = "";
+    EXPECT_FALSE(EC);
+  }
+  ~ScopedDir() {
+    if (Path != "")
+      EXPECT_FALSE(llvm::sys::fs::remove(Path.str()));
+  }
+  operator StringRef() { return Path.str(); }
+};
+}
+
+TEST(VirtualFileSystemTest, BasicRealFSIteration) {
+  ScopedDir TestDirectory("virtual-file-system-test", /*Unique*/true);
+  IntrusiveRefCntPtr<vfs::FileSystem> FS = vfs::getRealFileSystem();
+
+  std::error_code EC;
+  vfs::directory_iterator I = FS->dir_begin(Twine(TestDirectory), EC);
+  ASSERT_FALSE(EC);
+  EXPECT_EQ(vfs::directory_iterator(), I); // empty directory is empty
+
+  ScopedDir _a(TestDirectory+"/a");
+  ScopedDir _ab(TestDirectory+"/a/b");
+  ScopedDir _c(TestDirectory+"/c");
+  ScopedDir _cd(TestDirectory+"/c/d");
+
+  I = FS->dir_begin(Twine(TestDirectory), EC);
+  ASSERT_FALSE(EC);
+  ASSERT_NE(vfs::directory_iterator(), I);
+  // Check either a or c, since we can't rely on the iteration order.
+  EXPECT_TRUE(I->getName().endswith("a") || I->getName().endswith("c"));
+  I.increment(EC);
+  ASSERT_FALSE(EC);
+  ASSERT_NE(vfs::directory_iterator(), I);
+  EXPECT_TRUE(I->getName().endswith("a") || I->getName().endswith("c"));
+  I.increment(EC);
+  EXPECT_EQ(vfs::directory_iterator(), I);
+}
+
+TEST(VirtualFileSystemTest, BasicRealFSRecursiveIteration) {
+  ScopedDir TestDirectory("virtual-file-system-test", /*Unique*/true);
+  IntrusiveRefCntPtr<vfs::FileSystem> FS = vfs::getRealFileSystem();
+
+  std::error_code EC;
+  auto I = vfs::recursive_directory_iterator(*FS, Twine(TestDirectory), EC);
+  ASSERT_FALSE(EC);
+  EXPECT_EQ(vfs::recursive_directory_iterator(), I); // empty directory is empty
+
+  ScopedDir _a(TestDirectory+"/a");
+  ScopedDir _ab(TestDirectory+"/a/b");
+  ScopedDir _c(TestDirectory+"/c");
+  ScopedDir _cd(TestDirectory+"/c/d");
+
+  I = vfs::recursive_directory_iterator(*FS, Twine(TestDirectory), EC);
+  ASSERT_FALSE(EC);
+  ASSERT_NE(vfs::recursive_directory_iterator(), I);
+
+
+  std::vector<std::string> Contents;
+  for (auto E = vfs::recursive_directory_iterator(); !EC && I != E;
+       I.increment(EC)) {
+    Contents.push_back(I->getName());
+  }
+
+  // Check contents, which may be in any order
+  EXPECT_EQ(4U, Contents.size());
+  int Counts[4] = { 0, 0, 0, 0 };
+  for (const std::string &Name : Contents) {
+    ASSERT_FALSE(Name.empty());
+    int Index = Name[Name.size()-1] - 'a';
+    ASSERT_TRUE(Index >= 0 && Index < 4);
+    Counts[Index]++;
+  }
+  EXPECT_EQ(1, Counts[0]); // a
+  EXPECT_EQ(1, Counts[1]); // b
+  EXPECT_EQ(1, Counts[2]); // c
+  EXPECT_EQ(1, Counts[3]); // d
+}
+
+template <typename T, size_t N>
+std::vector<StringRef> makeStringRefVector(const T (&Arr)[N]) {
+  std::vector<StringRef> Vec;
+  for (size_t i = 0; i != N; ++i)
+    Vec.push_back(Arr[i]);
+  return Vec;
+}
+
+template <typename DirIter>
+static void checkContents(DirIter I, ArrayRef<StringRef> Expected) {
+  std::error_code EC;
+  auto ExpectedIter = Expected.begin(), ExpectedEnd = Expected.end();
+  for (DirIter E;
+       !EC && I != E && ExpectedIter != ExpectedEnd;
+       I.increment(EC), ++ExpectedIter)
+    EXPECT_EQ(*ExpectedIter, I->getName());
+
+  EXPECT_EQ(ExpectedEnd, ExpectedIter);
+  EXPECT_EQ(DirIter(), I);
+}
+
+TEST(VirtualFileSystemTest, OverlayIteration) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem());
+  IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
+      new vfs::OverlayFileSystem(Lower));
+  O->pushOverlay(Upper);
+
+  std::error_code EC;
+  checkContents(O->dir_begin("/", EC), ArrayRef<StringRef>());
+
+  Lower->addRegularFile("/file1");
+  checkContents(O->dir_begin("/", EC), ArrayRef<StringRef>("/file1"));
+
+  Upper->addRegularFile("/file2");
+  {
+    const char *Contents[] = {"/file2", "/file1"};
+    checkContents(O->dir_begin("/", EC), makeStringRefVector(Contents));
+  }
+
+  Lower->addDirectory("/dir1");
+  Lower->addRegularFile("/dir1/foo");
+  Upper->addDirectory("/dir2");
+  Upper->addRegularFile("/dir2/foo");
+  checkContents(O->dir_begin("/dir2", EC), ArrayRef<StringRef>("/dir2/foo"));
+  {
+    const char *Contents[] = {"/dir2", "/file2", "/dir1", "/file1"};
+    checkContents(O->dir_begin("/", EC), makeStringRefVector(Contents));
+  }
+}
+
+TEST(VirtualFileSystemTest, OverlayRecursiveIteration) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  IntrusiveRefCntPtr<DummyFileSystem> Middle(new DummyFileSystem());
+  IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem());
+  IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
+      new vfs::OverlayFileSystem(Lower));
+  O->pushOverlay(Middle);
+  O->pushOverlay(Upper);
+
+  std::error_code EC;
+  checkContents(vfs::recursive_directory_iterator(*O, "/", EC),
+                ArrayRef<StringRef>());
+
+  Lower->addRegularFile("/file1");
+  checkContents(vfs::recursive_directory_iterator(*O, "/", EC),
+                ArrayRef<StringRef>("/file1"));
+
+  Upper->addDirectory("/dir");
+  Upper->addRegularFile("/dir/file2");
+  {
+    const char *Contents[] = {"/dir", "/dir/file2", "/file1"};
+    checkContents(vfs::recursive_directory_iterator(*O, "/", EC),
+                  makeStringRefVector(Contents));
+  }
+
+  Lower->addDirectory("/dir1");
+  Lower->addRegularFile("/dir1/foo");
+  Lower->addDirectory("/dir1/a");
+  Lower->addRegularFile("/dir1/a/b");
+  Middle->addDirectory("/a");
+  Middle->addDirectory("/a/b");
+  Middle->addDirectory("/a/b/c");
+  Middle->addRegularFile("/a/b/c/d");
+  Middle->addRegularFile("/hiddenByUp");
+  Upper->addDirectory("/dir2");
+  Upper->addRegularFile("/dir2/foo");
+  Upper->addRegularFile("/hiddenByUp");
+  checkContents(vfs::recursive_directory_iterator(*O, "/dir2", EC),
+                ArrayRef<StringRef>("/dir2/foo"));
+  {
+    const char *Contents[] = { "/dir", "/dir/file2", "/dir2", "/dir2/foo",
+        "/hiddenByUp", "/a", "/a/b", "/a/b/c", "/a/b/c/d", "/dir1", "/dir1/a",
+        "/dir1/a/b", "/dir1/foo", "/file1" };
+    checkContents(vfs::recursive_directory_iterator(*O, "/", EC),
+                  makeStringRefVector(Contents));
+  }
+}
+
+TEST(VirtualFileSystemTest, ThreeLevelIteration) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  IntrusiveRefCntPtr<DummyFileSystem> Middle(new DummyFileSystem());
+  IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem());
+  IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
+      new vfs::OverlayFileSystem(Lower));
+  O->pushOverlay(Middle);
+  O->pushOverlay(Upper);
+
+  std::error_code EC;
+  checkContents(O->dir_begin("/", EC), ArrayRef<StringRef>());
+
+  Middle->addRegularFile("/file2");
+  checkContents(O->dir_begin("/", EC), ArrayRef<StringRef>("/file2"));
+
+  Lower->addRegularFile("/file1");
+  Upper->addRegularFile("/file3");
+  {
+    const char *Contents[] = {"/file3", "/file2", "/file1"};
+    checkContents(O->dir_begin("/", EC), makeStringRefVector(Contents));
+  }
+}
+
+TEST(VirtualFileSystemTest, HiddenInIteration) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  IntrusiveRefCntPtr<DummyFileSystem> Middle(new DummyFileSystem());
+  IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem());
+  IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
+      new vfs::OverlayFileSystem(Lower));
+  O->pushOverlay(Middle);
+  O->pushOverlay(Upper);
+
+  std::error_code EC;
+  Lower->addRegularFile("/onlyInLow", sys::fs::owner_read);
+  Lower->addRegularFile("/hiddenByMid", sys::fs::owner_read);
+  Lower->addRegularFile("/hiddenByUp", sys::fs::owner_read);
+  Middle->addRegularFile("/onlyInMid", sys::fs::owner_write);
+  Middle->addRegularFile("/hiddenByMid", sys::fs::owner_write);
+  Middle->addRegularFile("/hiddenByUp", sys::fs::owner_write);
+  Upper->addRegularFile("/onlyInUp", sys::fs::owner_all);
+  Upper->addRegularFile("/hiddenByUp", sys::fs::owner_all);
+  {
+    const char *Contents[] = {"/hiddenByUp", "/onlyInUp", "/hiddenByMid",
+                              "/onlyInMid", "/onlyInLow"};
+    checkContents(O->dir_begin("/", EC), makeStringRefVector(Contents));
+  }
+
+  // Make sure we get the top-most entry
+  {
+    std::error_code EC;
+    vfs::directory_iterator I = O->dir_begin("/", EC), E;
+    for ( ; !EC && I != E; I.increment(EC))
+      if (I->getName() == "/hiddenByUp")
+        break;
+    ASSERT_NE(E, I);
+    EXPECT_EQ(sys::fs::owner_all, I->getPermissions());
+  }
+  {
+    std::error_code EC;
+    vfs::directory_iterator I = O->dir_begin("/", EC), E;
+    for ( ; !EC && I != E; I.increment(EC))
+      if (I->getName() == "/hiddenByMid")
+        break;
+    ASSERT_NE(E, I);
+    EXPECT_EQ(sys::fs::owner_write, I->getPermissions());
+  }
+}
+
+// NOTE: in the tests below, we use '//root/' as our root directory, since it is
+// a legal *absolute* path on Windows as well as *nix.
+class VFSFromYAMLTest : public ::testing::Test {
+public:
+  int NumDiagnostics;
+
+  void SetUp() {
+    NumDiagnostics = 0;
+  }
+
+  static void CountingDiagHandler(const SMDiagnostic &, void *Context) {
+    VFSFromYAMLTest *Test = static_cast<VFSFromYAMLTest *>(Context);
+    ++Test->NumDiagnostics;
+  }
+
+  IntrusiveRefCntPtr<vfs::FileSystem>
+  getFromYAMLRawString(StringRef Content,
+                       IntrusiveRefCntPtr<vfs::FileSystem> ExternalFS) {
+    MemoryBuffer *Buffer = MemoryBuffer::getMemBuffer(Content);
+    return getVFSFromYAML(Buffer, CountingDiagHandler, this, ExternalFS);
+  }
+
+  IntrusiveRefCntPtr<vfs::FileSystem> getFromYAMLString(
+      StringRef Content,
+      IntrusiveRefCntPtr<vfs::FileSystem> ExternalFS = new DummyFileSystem()) {
+    std::string VersionPlusContent("{\n  'version':0,\n");
+    VersionPlusContent += Content.slice(Content.find('{') + 1, StringRef::npos);
+    return getFromYAMLRawString(VersionPlusContent, ExternalFS);
+  }
+};
+
+TEST_F(VFSFromYAMLTest, BasicVFSFromYAML) {
+  IntrusiveRefCntPtr<vfs::FileSystem> FS;
+  FS = getFromYAMLString("");
+  EXPECT_EQ(nullptr, FS.get());
+  FS = getFromYAMLString("[]");
+  EXPECT_EQ(nullptr, FS.get());
+  FS = getFromYAMLString("'string'");
+  EXPECT_EQ(nullptr, FS.get());
+  EXPECT_EQ(3, NumDiagnostics);
+}
+
+TEST_F(VFSFromYAMLTest, MappedFiles) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  Lower->addRegularFile("//root/foo/bar/a");
+  IntrusiveRefCntPtr<vfs::FileSystem> FS =
+      getFromYAMLString("{ 'roots': [\n"
+                        "{\n"
+                        "  'type': 'directory',\n"
+                        "  'name': '//root/',\n"
+                        "  'contents': [ {\n"
+                        "                  'type': 'file',\n"
+                        "                  'name': 'file1',\n"
+                        "                  'external-contents': '//root/foo/bar/a'\n"
+                        "                },\n"
+                        "                {\n"
+                        "                  'type': 'file',\n"
+                        "                  'name': 'file2',\n"
+                        "                  'external-contents': '//root/foo/b'\n"
+                        "                }\n"
+                        "              ]\n"
+                        "}\n"
+                        "]\n"
+                        "}",
+                        Lower);
+  ASSERT_TRUE(FS.get() != nullptr);
+
+  IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
+      new vfs::OverlayFileSystem(Lower));
+  O->pushOverlay(FS);
+
+  // file
+  ErrorOr<vfs::Status> S = O->status("//root/file1");
+  ASSERT_FALSE(S.getError());
+  EXPECT_EQ("//root/foo/bar/a", S->getName());
+
+  ErrorOr<vfs::Status> SLower = O->status("//root/foo/bar/a");
+  EXPECT_EQ("//root/foo/bar/a", SLower->getName());
+  EXPECT_TRUE(S->equivalent(*SLower));
+
+  // directory
+  S = O->status("//root/");
+  ASSERT_FALSE(S.getError());
+  EXPECT_TRUE(S->isDirectory());
+  EXPECT_TRUE(S->equivalent(*O->status("//root/"))); // non-volatile UniqueID
+
+  // broken mapping
+  EXPECT_EQ(O->status("//root/file2").getError(),
+            llvm::errc::no_such_file_or_directory);
+  EXPECT_EQ(0, NumDiagnostics);
+}
+
+TEST_F(VFSFromYAMLTest, CaseInsensitive) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  Lower->addRegularFile("//root/foo/bar/a");
+  IntrusiveRefCntPtr<vfs::FileSystem> FS =
+      getFromYAMLString("{ 'case-sensitive': 'false',\n"
+                        "  'roots': [\n"
+                        "{\n"
+                        "  'type': 'directory',\n"
+                        "  'name': '//root/',\n"
+                        "  'contents': [ {\n"
+                        "                  'type': 'file',\n"
+                        "                  'name': 'XX',\n"
+                        "                  'external-contents': '//root/foo/bar/a'\n"
+                        "                }\n"
+                        "              ]\n"
+                        "}]}",
+                        Lower);
+  ASSERT_TRUE(FS.get() != nullptr);
+
+  IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
+      new vfs::OverlayFileSystem(Lower));
+  O->pushOverlay(FS);
+
+  ErrorOr<vfs::Status> S = O->status("//root/XX");
+  ASSERT_FALSE(S.getError());
+
+  ErrorOr<vfs::Status> SS = O->status("//root/xx");
+  ASSERT_FALSE(SS.getError());
+  EXPECT_TRUE(S->equivalent(*SS));
+  SS = O->status("//root/xX");
+  EXPECT_TRUE(S->equivalent(*SS));
+  SS = O->status("//root/Xx");
+  EXPECT_TRUE(S->equivalent(*SS));
+  EXPECT_EQ(0, NumDiagnostics);
+}
+
+TEST_F(VFSFromYAMLTest, CaseSensitive) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  Lower->addRegularFile("//root/foo/bar/a");
+  IntrusiveRefCntPtr<vfs::FileSystem> FS =
+      getFromYAMLString("{ 'case-sensitive': 'true',\n"
+                        "  'roots': [\n"
+                        "{\n"
+                        "  'type': 'directory',\n"
+                        "  'name': '//root/',\n"
+                        "  'contents': [ {\n"
+                        "                  'type': 'file',\n"
+                        "                  'name': 'XX',\n"
+                        "                  'external-contents': '//root/foo/bar/a'\n"
+                        "                }\n"
+                        "              ]\n"
+                        "}]}",
+                        Lower);
+  ASSERT_TRUE(FS.get() != nullptr);
+
+  IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
+      new vfs::OverlayFileSystem(Lower));
+  O->pushOverlay(FS);
+
+  ErrorOr<vfs::Status> SS = O->status("//root/xx");
+  EXPECT_EQ(SS.getError(), llvm::errc::no_such_file_or_directory);
+  SS = O->status("//root/xX");
+  EXPECT_EQ(SS.getError(), llvm::errc::no_such_file_or_directory);
+  SS = O->status("//root/Xx");
+  EXPECT_EQ(SS.getError(), llvm::errc::no_such_file_or_directory);
+  EXPECT_EQ(0, NumDiagnostics);
+}
+
+TEST_F(VFSFromYAMLTest, IllegalVFSFile) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+
+  // invalid YAML at top-level
+  IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString("{]", Lower);
+  EXPECT_EQ(nullptr, FS.get());
+  // invalid YAML in roots
+  FS = getFromYAMLString("{ 'roots':[}", Lower);
+  // invalid YAML in directory
+  FS = getFromYAMLString(
+      "{ 'roots':[ { 'name': 'foo', 'type': 'directory', 'contents': [}",
+      Lower);
+  EXPECT_EQ(nullptr, FS.get());
+
+  // invalid configuration
+  FS = getFromYAMLString("{ 'knobular': 'true', 'roots':[] }", Lower);
+  EXPECT_EQ(nullptr, FS.get());
+  FS = getFromYAMLString("{ 'case-sensitive': 'maybe', 'roots':[] }", Lower);
+  EXPECT_EQ(nullptr, FS.get());
+
+  // invalid roots
+  FS = getFromYAMLString("{ 'roots':'' }", Lower);
+  EXPECT_EQ(nullptr, FS.get());
+  FS = getFromYAMLString("{ 'roots':{} }", Lower);
+  EXPECT_EQ(nullptr, FS.get());
+
+  // invalid entries
+  FS = getFromYAMLString(
+      "{ 'roots':[ { 'type': 'other', 'name': 'me', 'contents': '' }", Lower);
+  EXPECT_EQ(nullptr, FS.get());
+  FS = getFromYAMLString("{ 'roots':[ { 'type': 'file', 'name': [], "
+                         "'external-contents': 'other' }",
+                         Lower);
+  EXPECT_EQ(nullptr, FS.get());
+  FS = getFromYAMLString(
+      "{ 'roots':[ { 'type': 'file', 'name': 'me', 'external-contents': [] }",
+      Lower);
+  EXPECT_EQ(nullptr, FS.get());
+  FS = getFromYAMLString(
+      "{ 'roots':[ { 'type': 'file', 'name': 'me', 'external-contents': {} }",
+      Lower);
+  EXPECT_EQ(nullptr, FS.get());
+  FS = getFromYAMLString(
+      "{ 'roots':[ { 'type': 'directory', 'name': 'me', 'contents': {} }",
+      Lower);
+  EXPECT_EQ(nullptr, FS.get());
+  FS = getFromYAMLString(
+      "{ 'roots':[ { 'type': 'directory', 'name': 'me', 'contents': '' }",
+      Lower);
+  EXPECT_EQ(nullptr, FS.get());
+  FS = getFromYAMLString(
+      "{ 'roots':[ { 'thingy': 'directory', 'name': 'me', 'contents': [] }",
+      Lower);
+  EXPECT_EQ(nullptr, FS.get());
+
+  // missing mandatory fields
+  FS = getFromYAMLString("{ 'roots':[ { 'type': 'file', 'name': 'me' }", Lower);
+  EXPECT_EQ(nullptr, FS.get());
+  FS = getFromYAMLString(
+      "{ 'roots':[ { 'type': 'file', 'external-contents': 'other' }", Lower);
+  EXPECT_EQ(nullptr, FS.get());
+  FS = getFromYAMLString("{ 'roots':[ { 'name': 'me', 'contents': [] }", Lower);
+  EXPECT_EQ(nullptr, FS.get());
+
+  // duplicate keys
+  FS = getFromYAMLString("{ 'roots':[], 'roots':[] }", Lower);
+  EXPECT_EQ(nullptr, FS.get());
+  FS = getFromYAMLString(
+      "{ 'case-sensitive':'true', 'case-sensitive':'true', 'roots':[] }",
+      Lower);
+  EXPECT_EQ(nullptr, FS.get());
+  FS =
+      getFromYAMLString("{ 'roots':[{'name':'me', 'name':'you', 'type':'file', "
+                        "'external-contents':'blah' } ] }",
+                        Lower);
+  EXPECT_EQ(nullptr, FS.get());
+
+  // missing version
+  FS = getFromYAMLRawString("{ 'roots':[] }", Lower);
+  EXPECT_EQ(nullptr, FS.get());
+
+  // bad version number
+  FS = getFromYAMLRawString("{ 'version':'foo', 'roots':[] }", Lower);
+  EXPECT_EQ(nullptr, FS.get());
+  FS = getFromYAMLRawString("{ 'version':-1, 'roots':[] }", Lower);
+  EXPECT_EQ(nullptr, FS.get());
+  FS = getFromYAMLRawString("{ 'version':100000, 'roots':[] }", Lower);
+  EXPECT_EQ(nullptr, FS.get());
+  EXPECT_EQ(24, NumDiagnostics);
+}
+
+TEST_F(VFSFromYAMLTest, UseExternalName) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  Lower->addRegularFile("//root/external/file");
+
+  IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString(
+      "{ 'roots': [\n"
+      "  { 'type': 'file', 'name': '//root/A',\n"
+      "    'external-contents': '//root/external/file'\n"
+      "  },\n"
+      "  { 'type': 'file', 'name': '//root/B',\n"
+      "    'use-external-name': true,\n"
+      "    'external-contents': '//root/external/file'\n"
+      "  },\n"
+      "  { 'type': 'file', 'name': '//root/C',\n"
+      "    'use-external-name': false,\n"
+      "    'external-contents': '//root/external/file'\n"
+      "  }\n"
+      "] }", Lower);
+  ASSERT_TRUE(nullptr != FS.get());
+
+  // default true
+  EXPECT_EQ("//root/external/file", FS->status("//root/A")->getName());
+  // explicit
+  EXPECT_EQ("//root/external/file", FS->status("//root/B")->getName());
+  EXPECT_EQ("//root/C", FS->status("//root/C")->getName());
+
+  // global configuration
+  FS = getFromYAMLString(
+      "{ 'use-external-names': false,\n"
+      "  'roots': [\n"
+      "  { 'type': 'file', 'name': '//root/A',\n"
+      "    'external-contents': '//root/external/file'\n"
+      "  },\n"
+      "  { 'type': 'file', 'name': '//root/B',\n"
+      "    'use-external-name': true,\n"
+      "    'external-contents': '//root/external/file'\n"
+      "  },\n"
+      "  { 'type': 'file', 'name': '//root/C',\n"
+      "    'use-external-name': false,\n"
+      "    'external-contents': '//root/external/file'\n"
+      "  }\n"
+      "] }", Lower);
+  ASSERT_TRUE(nullptr != FS.get());
+
+  // default
+  EXPECT_EQ("//root/A", FS->status("//root/A")->getName());
+  // explicit
+  EXPECT_EQ("//root/external/file", FS->status("//root/B")->getName());
+  EXPECT_EQ("//root/C", FS->status("//root/C")->getName());
+}
+
+TEST_F(VFSFromYAMLTest, MultiComponentPath) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  Lower->addRegularFile("//root/other");
+
+  // file in roots
+  IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString(
+      "{ 'roots': [\n"
+      "  { 'type': 'file', 'name': '//root/path/to/file',\n"
+      "    'external-contents': '//root/other' }]\n"
+      "}", Lower);
+  ASSERT_TRUE(nullptr != FS.get());
+  EXPECT_FALSE(FS->status("//root/path/to/file").getError());
+  EXPECT_FALSE(FS->status("//root/path/to").getError());
+  EXPECT_FALSE(FS->status("//root/path").getError());
+  EXPECT_FALSE(FS->status("//root/").getError());
+
+  // at the start
+  FS = getFromYAMLString(
+      "{ 'roots': [\n"
+      "  { 'type': 'directory', 'name': '//root/path/to',\n"
+      "    'contents': [ { 'type': 'file', 'name': 'file',\n"
+      "                    'external-contents': '//root/other' }]}]\n"
+      "}", Lower);
+  ASSERT_TRUE(nullptr != FS.get());
+  EXPECT_FALSE(FS->status("//root/path/to/file").getError());
+  EXPECT_FALSE(FS->status("//root/path/to").getError());
+  EXPECT_FALSE(FS->status("//root/path").getError());
+  EXPECT_FALSE(FS->status("//root/").getError());
+
+  // at the end
+  FS = getFromYAMLString(
+      "{ 'roots': [\n"
+      "  { 'type': 'directory', 'name': '//root/',\n"
+      "    'contents': [ { 'type': 'file', 'name': 'path/to/file',\n"
+      "                    'external-contents': '//root/other' }]}]\n"
+      "}", Lower);
+  ASSERT_TRUE(nullptr != FS.get());
+  EXPECT_FALSE(FS->status("//root/path/to/file").getError());
+  EXPECT_FALSE(FS->status("//root/path/to").getError());
+  EXPECT_FALSE(FS->status("//root/path").getError());
+  EXPECT_FALSE(FS->status("//root/").getError());
+}
+
+TEST_F(VFSFromYAMLTest, TrailingSlashes) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  Lower->addRegularFile("//root/other");
+
+  // file in roots
+  IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString(
+      "{ 'roots': [\n"
+      "  { 'type': 'directory', 'name': '//root/path/to////',\n"
+      "    'contents': [ { 'type': 'file', 'name': 'file',\n"
+      "                    'external-contents': '//root/other' }]}]\n"
+      "}", Lower);
+  ASSERT_TRUE(nullptr != FS.get());
+  EXPECT_FALSE(FS->status("//root/path/to/file").getError());
+  EXPECT_FALSE(FS->status("//root/path/to").getError());
+  EXPECT_FALSE(FS->status("//root/path").getError());
+  EXPECT_FALSE(FS->status("//root/").getError());
+}
+
+TEST_F(VFSFromYAMLTest, DirectoryIteration) {
+  IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
+  Lower->addDirectory("//root/");
+  Lower->addDirectory("//root/foo");
+  Lower->addDirectory("//root/foo/bar");
+  Lower->addRegularFile("//root/foo/bar/a");
+  Lower->addRegularFile("//root/foo/bar/b");
+  Lower->addRegularFile("//root/file3");
+  IntrusiveRefCntPtr<vfs::FileSystem> FS =
+  getFromYAMLString("{ 'use-external-names': false,\n"
+                    "  'roots': [\n"
+                    "{\n"
+                    "  'type': 'directory',\n"
+                    "  'name': '//root/',\n"
+                    "  'contents': [ {\n"
+                    "                  'type': 'file',\n"
+                    "                  'name': 'file1',\n"
+                    "                  'external-contents': '//root/foo/bar/a'\n"
+                    "                },\n"
+                    "                {\n"
+                    "                  'type': 'file',\n"
+                    "                  'name': 'file2',\n"
+                    "                  'external-contents': '//root/foo/bar/b'\n"
+                    "                }\n"
+                    "              ]\n"
+                    "}\n"
+                    "]\n"
+                    "}",
+                    Lower);
+  ASSERT_TRUE(FS.get() != NULL);
+
+  IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
+      new vfs::OverlayFileSystem(Lower));
+  O->pushOverlay(FS);
+
+  std::error_code EC;
+  {
+    const char *Contents[] = {"//root/file1", "//root/file2", "//root/file3",
+                              "//root/foo"};
+    checkContents(O->dir_begin("//root/", EC), makeStringRefVector(Contents));
+  }
+
+  {
+    const char *Contents[] = {"//root/foo/bar/a", "//root/foo/bar/b"};
+    checkContents(O->dir_begin("//root/foo/bar", EC),
+                  makeStringRefVector(Contents));
+  }
+}
diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt
index 479b36f..936b8b2 100644
--- a/unittests/CMakeLists.txt
+++ b/unittests/CMakeLists.txt
@@ -11,13 +11,16 @@
 
 add_subdirectory(Basic)
 add_subdirectory(Lex)
+add_subdirectory(Driver)
 if(CLANG_ENABLE_STATIC_ANALYZER)
   add_subdirectory(Frontend)
 endif()
-if(CLANG_ENABLE_REWRITER)
-  add_subdirectory(ASTMatchers)
-  add_subdirectory(AST)
-  add_subdirectory(Tooling)
-  add_subdirectory(Format)
-  add_subdirectory(Sema)
+add_subdirectory(ASTMatchers)
+add_subdirectory(AST)
+add_subdirectory(Tooling)
+add_subdirectory(Format)
+add_subdirectory(Sema)
+# FIXME: Why are the libclang unit tests disabled on Windows?
+if(NOT WIN32) 
+  add_subdirectory(libclang)
 endif()
diff --git a/unittests/Driver/CMakeLists.txt b/unittests/Driver/CMakeLists.txt
new file mode 100644
index 0000000..8cc963b
--- /dev/null
+++ b/unittests/Driver/CMakeLists.txt
@@ -0,0 +1,11 @@
+set(LLVM_LINK_COMPONENTS
+  Support
+  )
+
+add_clang_unittest(ClangDriverTests
+  MultilibTest.cpp
+  )
+
+target_link_libraries(ClangDriverTests
+  clangDriver
+  )
diff --git a/unittests/Driver/Makefile b/unittests/Driver/Makefile
new file mode 100644
index 0000000..21d19f3
--- /dev/null
+++ b/unittests/Driver/Makefile
@@ -0,0 +1,16 @@
+##===- unittests/Driver/Makefile ---------------------------*- Makefile -*-===##
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+CLANG_LEVEL = ../..
+TESTNAME = Multilib
+include $(CLANG_LEVEL)/../../Makefile.config
+LINK_COMPONENTS := $(TARGETS_TO_BUILD) support option
+USEDLIBS = clangDriver.a clangBasic.a
+
+include $(CLANG_LEVEL)/unittests/Makefile
diff --git a/unittests/Driver/MultilibTest.cpp b/unittests/Driver/MultilibTest.cpp
new file mode 100644
index 0000000..dceace5
--- /dev/null
+++ b/unittests/Driver/MultilibTest.cpp
@@ -0,0 +1,356 @@
+//===- unittests/Driver/MultilibTest.cpp --- Multilib tests ---------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Unit tests for Multilib and MultilibSet
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Driver/Multilib.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "gtest/gtest.h"
+
+using namespace clang::driver;
+using namespace clang;
+
+TEST(MultilibTest, MultilibValidity) {
+
+  ASSERT_TRUE(Multilib().isValid()) << "Empty multilib is not valid";
+
+  ASSERT_TRUE(Multilib().flag("+foo").isValid())
+      << "Single indicative flag is not valid";
+
+  ASSERT_TRUE(Multilib().flag("-foo").isValid())
+      << "Single contraindicative flag is not valid";
+
+  ASSERT_FALSE(Multilib().flag("+foo").flag("-foo").isValid())
+      << "Conflicting flags should invalidate the Multilib";
+
+  ASSERT_TRUE(Multilib().flag("+foo").flag("+foo").isValid())
+      << "Multilib should be valid even if it has the same flag twice";
+
+  ASSERT_TRUE(Multilib().flag("+foo").flag("-foobar").isValid())
+      << "Seemingly conflicting prefixes shouldn't actually conflict";
+}
+
+TEST(MultilibTest, OpEqReflexivity1) {
+  Multilib M;
+  ASSERT_TRUE(M == M) << "Multilib::operator==() is not reflexive";
+}
+
+TEST(MultilibTest, OpEqReflexivity2) {
+  ASSERT_TRUE(Multilib() == Multilib())
+      << "Separately constructed default multilibs are not equal";
+}
+
+TEST(MultilibTest, OpEqReflexivity3) {
+  Multilib M1, M2;
+  M1.flag("+foo");
+  M2.flag("+foo");
+  ASSERT_TRUE(M1 == M2) << "Multilibs with the same flag should be the same";
+}
+
+TEST(MultilibTest, OpEqInequivalence1) {
+  Multilib M1, M2;
+  M1.flag("+foo");
+  M2.flag("-foo");
+  ASSERT_FALSE(M1 == M2) << "Multilibs with conflicting flags are not the same";
+  ASSERT_FALSE(M2 == M1)
+      << "Multilibs with conflicting flags are not the same (commuted)";
+}
+
+TEST(MultilibTest, OpEqInequivalence2) {
+  Multilib M1, M2;
+  M2.flag("+foo");
+  ASSERT_FALSE(M1 == M2) << "Flags make Multilibs different";
+}
+
+TEST(MultilibTest, OpEqEquivalence1) {
+  Multilib M1, M2;
+  M1.flag("+foo");
+  M2.flag("+foo").flag("+foo");
+  ASSERT_TRUE(M1 == M2) << "Flag duplication shouldn't affect equivalence";
+  ASSERT_TRUE(M2 == M1)
+      << "Flag duplication shouldn't affect equivalence (commuted)";
+}
+
+TEST(MultilibTest, OpEqEquivalence2) {
+  Multilib M1("64");
+  Multilib M2;
+  M2.gccSuffix("/64");
+  ASSERT_TRUE(M1 == M2)
+      << "Constructor argument must match Multilib::gccSuffix()";
+  ASSERT_TRUE(M2 == M1)
+      << "Constructor argument must match Multilib::gccSuffix() (commuted)";
+}
+
+TEST(MultilibTest, OpEqEquivalence3) {
+  Multilib M1("", "32");
+  Multilib M2;
+  M2.osSuffix("/32");
+  ASSERT_TRUE(M1 == M2)
+      << "Constructor argument must match Multilib::osSuffix()";
+  ASSERT_TRUE(M2 == M1)
+      << "Constructor argument must match Multilib::osSuffix() (commuted)";
+}
+
+TEST(MultilibTest, OpEqEquivalence4) {
+  Multilib M1("", "", "16");
+  Multilib M2;
+  M2.includeSuffix("/16");
+  ASSERT_TRUE(M1 == M2)
+      << "Constructor argument must match Multilib::includeSuffix()";
+  ASSERT_TRUE(M2 == M1)
+      << "Constructor argument must match Multilib::includeSuffix() (commuted)";
+}
+
+TEST(MultilibTest, OpEqInequivalence3) {
+  Multilib M1("foo");
+  Multilib M2("bar");
+  ASSERT_FALSE(M1 == M2) << "Differing gccSuffixes should be different";
+  ASSERT_FALSE(M2 == M1)
+      << "Differing gccSuffixes should be different (commuted)";
+}
+
+TEST(MultilibTest, OpEqInequivalence4) {
+  Multilib M1("", "foo");
+  Multilib M2("", "bar");
+  ASSERT_FALSE(M1 == M2) << "Differing osSuffixes should be different";
+  ASSERT_FALSE(M2 == M1)
+      << "Differing osSuffixes should be different (commuted)";
+}
+
+TEST(MultilibTest, OpEqInequivalence5) {
+  Multilib M1("", "", "foo");
+  Multilib M2("", "", "bar");
+  ASSERT_FALSE(M1 == M2) << "Differing includeSuffixes should be different";
+  ASSERT_FALSE(M2 == M1)
+      << "Differing includeSuffixes should be different (commuted)";
+}
+
+TEST(MultilibTest, Construction1) {
+  Multilib M("gcc64", "os64", "inc64");
+  ASSERT_TRUE(M.gccSuffix() == "/gcc64");
+  ASSERT_TRUE(M.osSuffix() == "/os64");
+  ASSERT_TRUE(M.includeSuffix() == "/inc64");
+}
+
+TEST(MultilibTest, Construction2) {
+  Multilib M1;
+  Multilib M2("");
+  Multilib M3("", "");
+  Multilib M4("", "", "");
+  ASSERT_TRUE(M1 == M2)
+      << "Default arguments to Multilib constructor broken (first argument)";
+  ASSERT_TRUE(M1 == M3)
+      << "Default arguments to Multilib constructor broken (second argument)";
+  ASSERT_TRUE(M1 == M4)
+      << "Default arguments to Multilib constructor broken (third argument)";
+}
+
+TEST(MultilibTest, Construction3) {
+  Multilib M = Multilib().flag("+f1").flag("+f2").flag("-f3");
+  for (Multilib::flags_list::const_iterator I = M.flags().begin(),
+                                            E = M.flags().end();
+       I != E; ++I) {
+    ASSERT_TRUE(llvm::StringSwitch<bool>(*I)
+                    .Cases("+f1", "+f2", "-f3", true)
+                    .Default(false));
+  }
+}
+
+static bool hasFlag(const Multilib &M, StringRef Flag) {
+  for (Multilib::flags_list::const_iterator I = M.flags().begin(),
+                                            E = M.flags().end();
+       I != E; ++I) {
+    if (*I == Flag)
+      return true;
+    else if (StringRef(*I).substr(1) == Flag.substr(1))
+      return false;
+  }
+  return false;
+}
+
+TEST(MultilibTest, SetConstruction1) {
+  // Single maybe
+  MultilibSet MS;
+  ASSERT_TRUE(MS.size() == 0);
+  MS.Maybe(Multilib("64").flag("+m64"));
+  ASSERT_TRUE(MS.size() == 2);
+  for (MultilibSet::const_iterator I = MS.begin(), E = MS.end(); I != E; ++I) {
+    if (I->gccSuffix() == "/64")
+      ASSERT_TRUE(I->flags()[0] == "+m64");
+    else if (I->gccSuffix() == "")
+      ASSERT_TRUE(I->flags()[0] == "-m64");
+    else
+      FAIL() << "Unrecognized gccSufix: " << I->gccSuffix();
+  }
+}
+
+TEST(MultilibTest, SetConstruction2) {
+  // Double maybe
+  MultilibSet MS;
+  MS.Maybe(Multilib("sof").flag("+sof"));
+  MS.Maybe(Multilib("el").flag("+EL"));
+  ASSERT_TRUE(MS.size() == 4);
+  for (MultilibSet::const_iterator I = MS.begin(), E = MS.end(); I != E; ++I) {
+    ASSERT_TRUE(I->isValid()) << "Multilb " << *I << " should be valid";
+    ASSERT_TRUE(llvm::StringSwitch<bool>(I->gccSuffix())
+                    .Cases("", "/sof", "/el", "/sof/el", true)
+                    .Default(false))
+        << "Multilib " << *I << " wasn't expected";
+    ASSERT_TRUE(llvm::StringSwitch<bool>(I->gccSuffix())
+                    .Case("", hasFlag(*I, "-sof"))
+                    .Case("/sof", hasFlag(*I, "+sof"))
+                    .Case("/el", hasFlag(*I, "-sof"))
+                    .Case("/sof/el", hasFlag(*I, "+sof"))
+                    .Default(false))
+        << "Multilib " << *I << " didn't have the appropriate {+,-}sof flag";
+    ASSERT_TRUE(llvm::StringSwitch<bool>(I->gccSuffix())
+                    .Case("", hasFlag(*I, "-EL"))
+                    .Case("/sof", hasFlag(*I, "-EL"))
+                    .Case("/el", hasFlag(*I, "+EL"))
+                    .Case("/sof/el", hasFlag(*I, "+EL"))
+                    .Default(false))
+        << "Multilib " << *I << " didn't have the appropriate {+,-}EL flag";
+  }
+}
+
+TEST(MultilibTest, SetPushback) {
+  MultilibSet MS;
+  MS.push_back(Multilib("one"));
+  MS.push_back(Multilib("two"));
+  ASSERT_TRUE(MS.size() == 2);
+  for (MultilibSet::const_iterator I = MS.begin(), E = MS.end(); I != E; ++I) {
+    ASSERT_TRUE(llvm::StringSwitch<bool>(I->gccSuffix())
+                    .Cases("/one", "/two", true)
+                    .Default(false));
+  }
+  MS.clear();
+  ASSERT_TRUE(MS.size() == 0);
+}
+
+TEST(MultilibTest, SetRegexFilter) {
+  MultilibSet MS;
+  MS.Maybe(Multilib("one"));
+  MS.Maybe(Multilib("two"));
+  MS.Maybe(Multilib("three"));
+  ASSERT_EQ(MS.size(), (unsigned)2 * 2 * 2)
+      << "Size before filter was incorrect. Contents:\n" << MS;
+  MS.FilterOut("/one/two/three");
+  ASSERT_EQ(MS.size(), (unsigned)2 * 2 * 2 - 1)
+      << "Size after filter was incorrect. Contents:\n" << MS;
+  for (MultilibSet::const_iterator I = MS.begin(), E = MS.end(); I != E; ++I) {
+    ASSERT_TRUE(I->gccSuffix() != "/one/two/three")
+        << "The filter should have removed " << *I;
+  }
+}
+
+TEST(MultilibTest, SetFilterObject) {
+  // Filter object
+  struct StartsWithP : public MultilibSet::FilterCallback {
+    bool operator()(const Multilib &M) const override {
+      return StringRef(M.gccSuffix()).startswith("/p");
+    }
+  };
+  MultilibSet MS;
+  MS.Maybe(Multilib("orange"));
+  MS.Maybe(Multilib("pear"));
+  MS.Maybe(Multilib("plum"));
+  ASSERT_EQ((int)MS.size(), 1 /* Default */ +
+                            1 /* pear */ +
+                            1 /* plum */ +
+                            1 /* pear/plum */ +
+                            1 /* orange */ +
+                            1 /* orange/pear */ +
+                            1 /* orange/plum */ +
+                            1 /* orange/pear/plum */ )
+      << "Size before filter was incorrect. Contents:\n" << MS;
+  MS.FilterOut(StartsWithP());
+  ASSERT_EQ((int)MS.size(), 1 /* Default */ +
+                            1 /* orange */ +
+                            1 /* orange/pear */ +
+                            1 /* orange/plum */ + 
+                            1 /* orange/pear/plum */ )
+      << "Size after filter was incorrect. Contents:\n" << MS;
+  for (MultilibSet::const_iterator I = MS.begin(), E = MS.end(); I != E; ++I) {
+    ASSERT_FALSE(StringRef(I->gccSuffix()).startswith("/p"))
+        << "The filter should have removed " << *I;
+  }
+}
+
+TEST(MultilibTest, SetSelection1) {
+  MultilibSet MS1 = MultilibSet()
+    .Maybe(Multilib("64").flag("+m64"));
+
+  Multilib::flags_list FlagM64;
+  FlagM64.push_back("+m64");
+  Multilib SelectionM64;
+  ASSERT_TRUE(MS1.select(FlagM64, SelectionM64))
+      << "Flag set was {\"+m64\"}, but selection not found";
+  ASSERT_TRUE(SelectionM64.gccSuffix() == "/64")
+      << "Selection picked " << SelectionM64 << " which was not expected";
+
+  Multilib::flags_list FlagNoM64;
+  FlagNoM64.push_back("-m64");
+  Multilib SelectionNoM64;
+  ASSERT_TRUE(MS1.select(FlagNoM64, SelectionNoM64))
+      << "Flag set was {\"-m64\"}, but selection not found";
+  ASSERT_TRUE(SelectionNoM64.gccSuffix() == "")
+      << "Selection picked " << SelectionNoM64 << " which was not expected";
+}
+
+TEST(MultilibTest, SetSelection2) {
+  MultilibSet MS2 = MultilibSet()
+    .Maybe(Multilib("el").flag("+EL"))
+    .Maybe(Multilib("sf").flag("+SF"));
+
+  for (unsigned I = 0; I < 4; ++I) {
+    bool IsEL = I & 0x1;
+    bool IsSF = I & 0x2;
+    Multilib::flags_list Flags;
+    if (IsEL)
+      Flags.push_back("+EL");
+    else
+      Flags.push_back("-EL");
+
+    if (IsSF)
+      Flags.push_back("+SF");
+    else
+      Flags.push_back("-SF");
+
+    Multilib Selection;
+    ASSERT_TRUE(MS2.select(Flags, Selection)) << "Selection failed for "
+                                              << (IsEL ? "+EL" : "-EL") << " "
+                                              << (IsSF ? "+SF" : "-SF");
+
+    std::string Suffix;
+    if (IsEL)
+      Suffix += "/el";
+    if (IsSF)
+      Suffix += "/sf";
+
+    ASSERT_EQ(Selection.gccSuffix(), Suffix) << "Selection picked " << Selection
+                                             << " which was not expected ";
+  }
+}
+
+TEST(MultilibTest, SetCombineWith) {
+  MultilibSet Coffee;
+  Coffee.push_back(Multilib("coffee"));
+  MultilibSet Milk;
+  Milk.push_back(Multilib("milk"));
+  MultilibSet Latte;
+  ASSERT_EQ(Latte.size(), (unsigned)0);
+  Latte.combineWith(Coffee);
+  ASSERT_EQ(Latte.size(), (unsigned)1);
+  Latte.combineWith(Milk);
+  ASSERT_EQ(Latte.size(), (unsigned)2);
+}
diff --git a/unittests/Format/CMakeLists.txt b/unittests/Format/CMakeLists.txt
index 16d5764..14fc22d 100644
--- a/unittests/Format/CMakeLists.txt
+++ b/unittests/Format/CMakeLists.txt
@@ -1,18 +1,14 @@
 set(LLVM_LINK_COMPONENTS
-  ${LLVM_TARGETS_TO_BUILD}
-  asmparser
-  bitreader
-  support
-  mc
+  Support
   )
 
 add_clang_unittest(FormatTests
   FormatTest.cpp
+  FormatTestJS.cpp
+  FormatTestProto.cpp
   )
 
 target_link_libraries(FormatTests
-  clangAST
   clangFormat
   clangTooling
-  clangRewriteCore
   )
diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp
index b6574c7..21bc862 100644
--- a/unittests/Format/FormatTest.cpp
+++ b/unittests/Format/FormatTest.cpp
@@ -7,16 +7,20 @@
 //
 //===----------------------------------------------------------------------===//
 
-#define DEBUG_TYPE "format-test"
-
+#include "FormatTestUtils.h"
 #include "clang/Format/Format.h"
-#include "clang/Lex/Lexer.h"
 #include "llvm/Support/Debug.h"
 #include "gtest/gtest.h"
 
+#define DEBUG_TYPE "format-test"
+
 namespace clang {
 namespace format {
 
+FormatStyle getGoogleStyle() {
+  return getGoogleStyle(FormatStyle::LK_Cpp);
+}
+
 class FormatTest : public ::testing::Test {
 protected:
   std::string format(llvm::StringRef Code, unsigned Offset, unsigned Length,
@@ -37,46 +41,6 @@
     return format(Code, 0, Code.size(), Style);
   }
 
-  std::string messUp(llvm::StringRef Code) {
-    std::string MessedUp(Code.str());
-    bool InComment = false;
-    bool InPreprocessorDirective = false;
-    bool JustReplacedNewline = false;
-    for (unsigned i = 0, e = MessedUp.size() - 1; i != e; ++i) {
-      if (MessedUp[i] == '/' && MessedUp[i + 1] == '/') {
-        if (JustReplacedNewline)
-          MessedUp[i - 1] = '\n';
-        InComment = true;
-      } else if (MessedUp[i] == '#' && (JustReplacedNewline || i == 0)) {
-        if (i != 0)
-          MessedUp[i - 1] = '\n';
-        InPreprocessorDirective = true;
-      } else if (MessedUp[i] == '\\' && MessedUp[i + 1] == '\n') {
-        MessedUp[i] = ' ';
-        MessedUp[i + 1] = ' ';
-      } else if (MessedUp[i] == '\n') {
-        if (InComment) {
-          InComment = false;
-        } else if (InPreprocessorDirective) {
-          InPreprocessorDirective = false;
-        } else {
-          JustReplacedNewline = true;
-          MessedUp[i] = ' ';
-        }
-      } else if (MessedUp[i] != ' ') {
-        JustReplacedNewline = false;
-      }
-    }
-    std::string WithoutWhitespace;
-    if (MessedUp[0] != ' ')
-      WithoutWhitespace.push_back(MessedUp[0]);
-    for (unsigned i = 1, e = MessedUp.size(); i != e; ++i) {
-      if (MessedUp[i] != ' ' || MessedUp[i - 1] != ' ')
-        WithoutWhitespace.push_back(MessedUp[i]);
-    }
-    return WithoutWhitespace;
-  }
-
   FormatStyle getLLVMStyleWithColumns(unsigned ColumnLimit) {
     FormatStyle Style = getLLVMStyle();
     Style.ColumnLimit = ColumnLimit;
@@ -91,7 +55,7 @@
 
   void verifyFormat(llvm::StringRef Code,
                     const FormatStyle &Style = getLLVMStyle()) {
-    EXPECT_EQ(Code.str(), format(messUp(Code), Style));
+    EXPECT_EQ(Code.str(), format(test::messUp(Code), Style));
   }
 
   void verifyGoogleFormat(llvm::StringRef Code) {
@@ -107,11 +71,11 @@
 };
 
 TEST_F(FormatTest, MessUp) {
-  EXPECT_EQ("1 2 3", messUp("1 2 3"));
-  EXPECT_EQ("1 2 3\n", messUp("1\n2\n3\n"));
-  EXPECT_EQ("a\n//b\nc", messUp("a\n//b\nc"));
-  EXPECT_EQ("a\n#b\nc", messUp("a\n#b\nc"));
-  EXPECT_EQ("a\n#b c d\ne", messUp("a\n#b\\\nc\\\nd\ne"));
+  EXPECT_EQ("1 2 3", test::messUp("1 2 3"));
+  EXPECT_EQ("1 2 3\n", test::messUp("1\n2\n3\n"));
+  EXPECT_EQ("a\n//b\nc", test::messUp("a\n//b\nc"));
+  EXPECT_EQ("a\n#b\nc", test::messUp("a\n#b\nc"));
+  EXPECT_EQ("a\n#b c d\ne", test::messUp("a\n#b\\\nc\\\nd\ne"));
 }
 
 //===----------------------------------------------------------------------===//
@@ -144,7 +108,7 @@
 }
 
 TEST_F(FormatTest, NestedNameSpecifiers) {
-  verifyFormat("vector< ::Type> v;");
+  verifyFormat("vector<::Type> v;");
   verifyFormat("::ns::SomeFunction(::ns::SomeOtherFunction())");
   verifyFormat("static constexpr bool Bar = decltype(bar())::value;");
 }
@@ -187,10 +151,10 @@
                    26, 0, getLLVMStyleWithColumns(12)));
   EXPECT_EQ("#define A  \\\n"
             "  int a;   \\\n"
-            "    int b;",
+            "  int b;",
             format("#define A  \\\n"
                    "  int a;   \\\n"
-                   "    int b;",
+                   "  int b;",
                    25, 0, getLLVMStyleWithColumns(12)));
 }
 
@@ -210,6 +174,51 @@
                    "\n"
                    "};"));
 
+  // Don't remove empty lines at the start of namespaces.
+  EXPECT_EQ("namespace N {\n"
+            "\n"
+            "int i;\n"
+            "}",
+            format("namespace N {\n"
+                   "\n"
+                   "int    i;\n"
+                   "}",
+                   getGoogleStyle()));
+
+  // Remove empty lines at the beginning and end of blocks.
+  EXPECT_EQ("void f() {\n"
+            "\n"
+            "  if (a) {\n"
+            "\n"
+            "    f();\n"
+            "  }\n"
+            "}",
+            format("void f() {\n"
+                   "\n"
+                   "  if (a) {\n"
+                   "\n"
+                   "    f();\n"
+                   "\n"
+                   "  }\n"
+                   "\n"
+                   "}",
+                   getLLVMStyle()));
+  EXPECT_EQ("void f() {\n"
+            "  if (a) {\n"
+            "    f();\n"
+            "  }\n"
+            "}",
+            format("void f() {\n"
+                   "\n"
+                   "  if (a) {\n"
+                   "\n"
+                   "    f();\n"
+                   "\n"
+                   "  }\n"
+                   "\n"
+                   "}",
+                   getGoogleStyle()));
+
   // Don't remove empty lines in more complex control statements.
   EXPECT_EQ("void f() {\n"
             "  if (a) {\n"
@@ -261,6 +270,17 @@
           9, 5, getLLVMStyle()));
 }
 
+TEST_F(FormatTest, RecognizesBinaryOperatorKeywords) {
+    verifyFormat("x = (a) and (b);");
+    verifyFormat("x = (a) or (b);");
+    verifyFormat("x = (a) bitand (b);");
+    verifyFormat("x = (a) bitor (b);");
+    verifyFormat("x = (a) not_eq (b);");
+    verifyFormat("x = (a) and_eq (b);");
+    verifyFormat("x = (a) or_eq (b);");
+    verifyFormat("x = (a) xor (b);");
+}
+
 //===----------------------------------------------------------------------===//
 // Tests for control statements.
 //===----------------------------------------------------------------------===//
@@ -293,7 +313,7 @@
                "  f();\n"
                "}",
                AllowsMergedIf);
-  verifyFormat("if (a) { /* Never merge this */\n"
+  verifyFormat("if (a) {/* Never merge this */\n"
                "  f();\n"
                "}",
                AllowsMergedIf);
@@ -335,6 +355,51 @@
                AllowsMergedLoops);
 }
 
+TEST_F(FormatTest, FormatShortBracedStatements) {
+  FormatStyle AllowSimpleBracedStatements = getLLVMStyle();
+  AllowSimpleBracedStatements.AllowShortBlocksOnASingleLine = true;
+
+  AllowSimpleBracedStatements.AllowShortIfStatementsOnASingleLine = true;
+  AllowSimpleBracedStatements.AllowShortLoopsOnASingleLine = true;
+
+  verifyFormat("if (true) {}", AllowSimpleBracedStatements);
+  verifyFormat("while (true) {}", AllowSimpleBracedStatements);
+  verifyFormat("for (;;) {}", AllowSimpleBracedStatements);
+  verifyFormat("if (true) { f(); }", AllowSimpleBracedStatements);
+  verifyFormat("while (true) { f(); }", AllowSimpleBracedStatements);
+  verifyFormat("for (;;) { f(); }", AllowSimpleBracedStatements);
+  verifyFormat("if (true) { //\n"
+               "  f();\n"
+               "}",
+               AllowSimpleBracedStatements);
+  verifyFormat("if (true) {\n"
+               "  f();\n"
+               "  f();\n"
+               "}",
+               AllowSimpleBracedStatements);
+
+  verifyFormat("template <int> struct A2 {\n"
+               "  struct B {};\n"
+               "};",
+               AllowSimpleBracedStatements);
+
+  AllowSimpleBracedStatements.AllowShortIfStatementsOnASingleLine = false;
+  verifyFormat("if (true) {\n"
+               "  f();\n"
+               "}",
+               AllowSimpleBracedStatements);
+
+  AllowSimpleBracedStatements.AllowShortLoopsOnASingleLine = false;
+  verifyFormat("while (true) {\n"
+               "  f();\n"
+               "}",
+               AllowSimpleBracedStatements);
+  verifyFormat("for (;;) {\n"
+               "  f();\n"
+               "}",
+               AllowSimpleBracedStatements);
+}
+
 TEST_F(FormatTest, ParseIfElse) {
   verifyFormat("if (true)\n"
                "  if (true)\n"
@@ -381,6 +446,11 @@
                "else {\n"
                "  g()\n"
                "}");
+
+  verifyFormat("if (a) {\n"
+               "} else if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
+               "               aaaaaaaaaaaaaaaaaaaaaaaaaaaa)) {\n"
+               "}");
 }
 
 TEST_F(FormatTest, FormatsForLoop) {
@@ -452,6 +522,17 @@
                "     aaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaa, aaaaaaaaaaaaa)) {\n}");
   verifyFormat("for (const aaaaaaaaaaaaaaaaaaaaa &aaaaaaaaa :\n"
                "     aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {\n}");
+  verifyFormat("for (aaaaaaaaa aaaaaaaaaaaaaaaaaaaaa :\n"
+               "     aaaaaaaaaaaa.aaaaaaaaaaaa().aaaaaaaaa().a()) {\n}");
+}
+
+TEST_F(FormatTest, ForEachLoops) {
+  verifyFormat("void f() {\n"
+               "  foreach (Item *item, itemlist) {}\n"
+               "  Q_FOREACH (Item *item, itemlist) {}\n"
+               "  BOOST_FOREACH (Item *item, itemlist) {}\n"
+               "  UNKNOWN_FORACH(Item * item, itemlist) {}\n"
+               "}");
 }
 
 TEST_F(FormatTest, FormatsWhileLoop) {
@@ -491,6 +572,9 @@
                "  f();\n"
                "  break;\n"
                "}\n"
+               "case 2: {\n"
+               "  break;\n"
+               "}\n"
                "}");
   verifyFormat("switch (x) {\n"
                "case 1: {\n"
@@ -595,6 +679,17 @@
                "    break;\n"
                "  }\n"
                "});");
+  verifyFormat("switch (a) {\n"
+               "case (b):\n"
+               "  return;\n"
+               "}");
+
+  verifyFormat("switch (a) {\n"
+               "case some_namespace::\n"
+               "    some_constant:\n"
+               "  return;\n"
+               "}",
+               getLLVMStyleWithColumns(34));
 }
 
 TEST_F(FormatTest, CaseRanges) {
@@ -637,6 +732,9 @@
   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)");
@@ -731,11 +829,10 @@
   verifyGoogleFormat("#endif  // HEADER_GUARD");
 
   verifyFormat("const char *test[] = {\n"
-               "  // A\n"
-               "  \"aaaa\",\n"
-               "  // B\n"
-               "  \"aaaaa\",\n"
-               "};");
+               "    // A\n"
+               "    \"aaaa\",\n"
+               "    // B\n"
+               "    \"aaaaa\"};");
   verifyGoogleFormat(
       "aaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
       "    aaaaaaaaaaaaaaaaaaaaaa);  // 81_cols_with_this_comment");
@@ -807,6 +904,55 @@
                    " // first\n"
                    "// at start\n"
                    "otherLine();"));
+
+  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"
+                   "}"));
+}
+
+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"));
 }
 
 TEST_F(FormatTest, CanFormatCommentsLocally) {
@@ -829,6 +975,43 @@
                    "int b;\n"
                    "int   c; // unrelated comment",
                    31, 0, getLLVMStyle()));
+
+  EXPECT_EQ("int a; // This\n"
+            "       // is\n"
+            "       // a",
+            format("int a;      // This\n"
+                   "            // is\n"
+                   "            // a",
+                   0, 0, getLLVMStyle()));
+  EXPECT_EQ("int a; // This\n"
+            "       // is\n"
+            "       // a\n"
+            "// This is b\n"
+            "int b;",
+            format("int a; // This\n"
+                   "     // is\n"
+                   "     // a\n"
+                   "// This is b\n"
+                   "int b;",
+                   0, 0, getLLVMStyle()));
+  EXPECT_EQ("int a; // This\n"
+            "       // is\n"
+            "       // a\n"
+            "\n"
+            "  // This is unrelated",
+            format("int a; // This\n"
+                   "     // is\n"
+                   "     // a\n"
+                   "\n"
+                   "  // This is unrelated",
+                   0, 0, getLLVMStyle()));
+  EXPECT_EQ("int a;\n"
+            "// This is\n"
+            "// not formatted.   ",
+            format("int a;\n"
+                   "// This is\n"
+                   "// not formatted.   ",
+                   0, 0, getLLVMStyle()));
 }
 
 TEST_F(FormatTest, RemovesTrailingWhitespaceOfComments) {
@@ -842,11 +1025,12 @@
 
 TEST_F(FormatTest, UnderstandsBlockComments) {
   verifyFormat("f(/*noSpaceAfterParameterNamingComment=*/true);");
-  EXPECT_EQ(
-      "f(aaaaaaaaaaaaaaaaaaaaaaaaa, /* Trailing comment for aa... */\n"
-      "  bbbbbbbbbbbbbbbbbbbbbbbbb);",
-      format("f(aaaaaaaaaaaaaaaaaaaaaaaaa ,   \\\n/* Trailing comment for aa... */\n"
-             "  bbbbbbbbbbbbbbbbbbbbbbbbb);"));
+  verifyFormat("void f() { g(/*aaa=*/x, /*bbb=*/!y); }");
+  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);",
@@ -869,6 +1053,11 @@
                "         /* 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) {
@@ -919,6 +1108,30 @@
             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, CorrectlyHandlesLengthOfBlockComments) {
@@ -997,14 +1210,14 @@
             format("// A comment before a macro definition\n"
                    "#define a b",
                    getLLVMStyleWithColumns(20)));
-  EXPECT_EQ("void ffffff(int aaaaaaaaa,  // wwww\n"
-            "            int a, int bbb, // xxxxxxx\n"
-            "                            // yyyyyyyyy\n"
-            "            int c, int d, int e) {}",
+  EXPECT_EQ("void\n"
+            "ffffff(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 a,\n"
-                   "    int bbb, // xxxxxxx yyyyyyyyy\n"
+                   "    int bbbbbbbbbb, // xxxxxxx yyyyyyyyyy\n"
                    "    int c, int d, int e) {}",
                    getLLVMStyleWithColumns(40)));
   EXPECT_EQ("//\t aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
@@ -1020,6 +1233,21 @@
       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"
@@ -1036,16 +1264,27 @@
                    getLLVMStyleWithColumns(50)));
   // FIXME: One day we might want to implement adjustment of leading whitespace
   // of the consecutive lines in this kind of comment:
-  EXPECT_EQ("int\n"
-            "a; // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
-            "       // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
-            "       // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
-            format("int a; // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
-                   "       // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
-                   "       // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
+  EXPECT_EQ("double\n"
+            "    a; // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
+            "          // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
+            "          // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
+            format("double a; // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
+                   "          // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n"
+                   "          // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
                    getLLVMStyleWithColumns(49)));
 }
 
+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"
@@ -1068,9 +1307,9 @@
             format("if (xxxxxxxxxx && yyy || // aaaaaa bbbbbbbb cccc\n"
                    "    zzz) q();",
                    getLLVMStyleWithColumns(40)));
-  EXPECT_EQ("fffffffff(&xxx, // aaaaaaaaaaaa\n"
-            "                // bbbbbbbbbbb\n"
-            "          zzz);",
+  EXPECT_EQ("fffffffff(\n"
+            "    &xxx, // aaaaaaaaaaaa bbbbbbbbbbb\n"
+            "    zzz);",
             format("fffffffff(&xxx, // aaaaaaaaaaaa bbbbbbbbbbb\n"
                    " zzz);",
                    getLLVMStyleWithColumns(40)));
@@ -1309,21 +1548,21 @@
 
 TEST_F(FormatTest, CommentsInStaticInitializers) {
   EXPECT_EQ(
-      "static SomeType type = { aaaaaaaaaaaaaaaaaaaa, /* comment */\n"
-      "                         aaaaaaaaaaaaaaaaaaaa /* comment */,\n"
-      "                         /* comment */ aaaaaaaaaaaaaaaaaaaa,\n"
-      "                         aaaaaaaaaaaaaaaaaaaa, // comment\n"
-      "                         aaaaaaaaaaaaaaaaaaaa };",
+      "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 };");
+  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};");
@@ -1331,23 +1570,22 @@
                      "                        // 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 } };");
+  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"
+            "    // Some comment\n"
+            "    a,\n"
             "\n"
-            "  // Comment after empty line\n"
-            "  b\n"
-            "}",
+            "    // Comment after empty line\n"
+            "    b}",
             format("S s =    {\n"
                    "      // Some comment\n"
                    "  a,\n"
@@ -1356,12 +1594,11 @@
                    "      b\n"
                    "}"));
   EXPECT_EQ("S s = {\n"
-            "  /* Some comment */\n"
-            "  a,\n"
+            "    /* Some comment */\n"
+            "    a,\n"
             "\n"
-            "  /* Comment after empty line */\n"
-            "  b\n"
-            "}",
+            "    /* Comment after empty line */\n"
+            "    b}",
             format("S s =    {\n"
                    "      /* Some comment */\n"
                    "  a,\n"
@@ -1370,10 +1607,9 @@
                    "      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"
-               "};");
+               "    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) {
@@ -1536,6 +1772,12 @@
                      " private:\n"
                      "  void f() {}\n"
                      "};");
+  verifyFormat("class A {\n"
+               "public slots:\n"
+               "  void f() {}\n"
+               "public Q_SLOTS:\n"
+               "  void f() {}\n"
+               "};");
 }
 
 TEST_F(FormatTest, SeparatesLogicalBlocks) {
@@ -1601,6 +1843,9 @@
   verifyFormat("struct aaaaaaaaaaaaaaaaaaaa\n"
                "    : public aaaaaaaaaaaaaaaaaaa<aaaaaaaaaaaaaaaaaaaaa,\n"
                "                                 aaaaaaaaaaaaaaaaaaaaaa> {};");
+  verifyFormat("template <class R, class C>\n"
+               "struct Aaaaaaaaaaaaaaaaa<R (C::*)(int) const>\n"
+               "    : Aaaaaaaaaaaaaaaaa<R (C::*)(int)> {};");
 }
 
 TEST_F(FormatTest, FormatsVariableDeclarationsAfterStructOrClass) {
@@ -1634,18 +1879,42 @@
   verifyFormat("enum X f() {\n  a();\n  return 42;\n}");
   verifyFormat("enum {\n"
                "  Bar = Foo<int, int>::value\n"
+               "};",
+               getLLVMStyleWithColumns(30));
+
+  verifyFormat("enum ShortEnum { A, B, C };");
+  verifyGoogleFormat("enum ShortEnum { A, B, C };");
+
+  EXPECT_EQ("enum KeepEmptyLines {\n"
+            "  ONE,\n"
+            "\n"
+            "  TWO,\n"
+            "\n"
+            "  THREE\n"
+            "}",
+            format("enum KeepEmptyLines {\n"
+                   "  ONE,\n"
+                   "\n"
+                   "  TWO,\n"
+                   "\n"
+                   "\n"
+                   "  THREE\n"
+                   "}"));
+  verifyFormat("enum E { // comment\n"
+               "  ONE,\n"
+               "  TWO\n"
                "};");
 }
 
 TEST_F(FormatTest, FormatsEnumsWithErrors) {
   verifyFormat("enum Type {\n"
-               "  One = 0;\n" // These semicolons should be commas.
+               "  One = 0; // These semicolons should be commas.\n"
                "  Two = 1;\n"
                "};");
   verifyFormat("namespace n {\n"
                "enum Type {\n"
                "  One,\n"
-               "  Two,\n" // missing };
+               "  Two, // missing };\n"
                "  int i;\n"
                "}\n"
                "void g() {}");
@@ -1687,13 +1956,23 @@
 
 TEST_F(FormatTest, FormatsEnumTypes) {
   verifyFormat("enum X : int {\n"
-               "  A,\n"
+               "  A, // Force multiple lines.\n"
                "  B\n"
                "};");
-  verifyFormat("enum X : std::uint32_t {\n"
-               "  A,\n"
-               "  B\n"
-               "};");
+  verifyFormat("enum X : int { A, B };");
+  verifyFormat("enum X : std::uint32_t { A, B };");
+}
+
+TEST_F(FormatTest, FormatsNSEnums) {
+  verifyGoogleFormat("typedef NS_ENUM(NSInteger, SomeName) { AAA, BBB }");
+  verifyGoogleFormat("typedef NS_ENUM(NSInteger, MyType) {\n"
+                     "  // Information about someDecentlyLongValue.\n"
+                     "  someDecentlyLongValue,\n"
+                     "  // Information about anotherDecentlyLongValue.\n"
+                     "  anotherDecentlyLongValue,\n"
+                     "  // Information about aThirdDecentlyLongValue.\n"
+                     "  aThirdDecentlyLongValue\n"
+                     "};");
 }
 
 TEST_F(FormatTest, FormatsBitfields) {
@@ -1726,7 +2005,7 @@
 
   // This code is more common than we thought; if we
   // layout this correctly the semicolon will go into
-  // its own line, which is undesireable.
+  // its own line, which is undesirable.
   verifyFormat("namespace {};");
   verifyFormat("namespace {\n"
                "class A {};\n"
@@ -1793,32 +2072,81 @@
 }
 
 TEST_F(FormatTest, FormatTryCatch) {
-  // FIXME: Handle try-catch explicitly in the UnwrappedLineParser, then we'll
-  // also not create single-line-blocks.
   verifyFormat("try {\n"
                "  throw a * b;\n"
-               "}\n"
-               "catch (int a) {\n"
+               "} catch (int a) {\n"
                "  // Do nothing.\n"
-               "}\n"
-               "catch (...) {\n"
+               "} catch (...) {\n"
                "  exit(42);\n"
                "}");
 
   // Function-level try statements.
-  verifyFormat("int f() try { return 4; }\n"
-               "catch (...) {\n"
+  verifyFormat("int f() try { return 4; } catch (...) {\n"
                "  return 5;\n"
                "}");
   verifyFormat("class A {\n"
                "  int a;\n"
-               "  A() try : a(0) {}\n"
-               "  catch (...) {\n"
+               "  A() try : a(0) {\n"
+               "  } catch (...) {\n"
                "    throw;\n"
                "  }\n"
                "};\n");
 }
 
+TEST_F(FormatTest, IncompleteTryCatchBlocks) {
+  verifyFormat("try {\n"
+               "  f();\n"
+               "} catch {\n"
+               "  g();\n"
+               "}");
+  verifyFormat("try {\n"
+               "  f();\n"
+               "} catch (A a) MACRO(x) {\n"
+               "  g();\n"
+               "} catch (B b) MACRO(x) {\n"
+               "  g();\n"
+               "}");
+}
+
+TEST_F(FormatTest, FormatTryCatchBraceStyles) {
+  FormatStyle Style = getLLVMStyle();
+  Style.BreakBeforeBraces = FormatStyle::BS_Attach;
+  verifyFormat("try {\n"
+               "  // something\n"
+               "} catch (...) {\n"
+               "  // something\n"
+               "}",
+               Style);
+  Style.BreakBeforeBraces = FormatStyle::BS_Stroustrup;
+  verifyFormat("try {\n"
+               "  // something\n"
+               "}\n"
+               "catch (...) {\n"
+               "  // something\n"
+               "}",
+               Style);
+  Style.BreakBeforeBraces = FormatStyle::BS_Allman;
+  verifyFormat("try\n"
+               "{\n"
+               "  // something\n"
+               "}\n"
+               "catch (...)\n"
+               "{\n"
+               "  // something\n"
+               "}",
+               Style);
+  Style.BreakBeforeBraces = FormatStyle::BS_GNU;
+  verifyFormat("try\n"
+               "  {\n"
+               "    // something\n"
+               "  }\n"
+               "catch (...)\n"
+               "  {\n"
+               "    // something\n"
+               "  }",
+               Style);
+}
+
 TEST_F(FormatTest, FormatObjCTryCatch) {
   verifyFormat("@try {\n"
                "  f();\n"
@@ -1832,96 +2160,93 @@
 }
 
 TEST_F(FormatTest, StaticInitializers) {
-  verifyFormat("static SomeClass SC = { 1, 'a' };");
+  verifyFormat("static SomeClass SC = {1, 'a'};");
 
   verifyFormat(
       "static SomeClass WithALoooooooooooooooooooongName = {\n"
-      "  100000000, \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"\n"
-      "};");
+      "    100000000, \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"};");
 
   // Here, everything other than the "}" would fit on a line.
   verifyFormat("static int LooooooooooooooooooooooooongVariable[1] = {\n"
-               "  100000000000000000000000\n"
-               "};");
-  EXPECT_EQ("S s = { a, b };", format("S s = {\n"
-                                      "  a,\n"
-                                      "\n"
-                                      "  b\n"
-                                      "};"));
+               "    10000000000000000000000000};");
+  EXPECT_EQ("S s = {a,\n"
+            "\n"
+            "       b};",
+            format("S s = {\n"
+                   "  a,\n"
+                   "\n"
+                   "  b\n"
+                   "};"));
 
   // FIXME: This would fit into the column limit if we'd fit "{ {" on the first
   // line. However, the formatting looks a bit off and this probably doesn't
   // happen often in practice.
   verifyFormat("static int Variable[1] = {\n"
-               "  { 1000000000000000000000000000000000000 }\n"
-               "};",
+               "    {1000000000000000000000000000000000000}};",
                getLLVMStyleWithColumns(40));
 }
 
 TEST_F(FormatTest, DesignatedInitializers) {
-  verifyFormat("const struct A a = { .a = 1, .b = 2 };");
-  verifyFormat("const struct A a = { .aaaaaaaaaa = 1,\n"
-               "                     .bbbbbbbbbb = 2,\n"
-               "                     .cccccccccc = 3,\n"
-               "                     .dddddddddd = 4,\n"
-               "                     .eeeeeeeeee = 5 };");
+  verifyFormat("const struct A a = {.a = 1, .b = 2};");
+  verifyFormat("const struct A a = {.aaaaaaaaaa = 1,\n"
+               "                    .bbbbbbbbbb = 2,\n"
+               "                    .cccccccccc = 3,\n"
+               "                    .dddddddddd = 4,\n"
+               "                    .eeeeeeeeee = 5};");
   verifyFormat("const struct Aaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaa = {\n"
-               "  .aaaaaaaaaaaaaaaaaaaaaaaaaaa = 1,\n"
-               "  .bbbbbbbbbbbbbbbbbbbbbbbbbbb = 2,\n"
-               "  .ccccccccccccccccccccccccccc = 3,\n"
-               "  .ddddddddddddddddddddddddddd = 4,\n"
-               "  .eeeeeeeeeeeeeeeeeeeeeeeeeee = 5\n"
-               "};");
+               "    .aaaaaaaaaaaaaaaaaaaaaaaaaaa = 1,\n"
+               "    .bbbbbbbbbbbbbbbbbbbbbbbbbbb = 2,\n"
+               "    .ccccccccccccccccccccccccccc = 3,\n"
+               "    .ddddddddddddddddddddddddddd = 4,\n"
+               "    .eeeeeeeeeeeeeeeeeeeeeeeeeee = 5};");
 
   verifyGoogleFormat("const struct A a = {.a = 1, .b = 2};");
 }
 
 TEST_F(FormatTest, NestedStaticInitializers) {
-  verifyFormat("static A x = { { {} } };\n");
-  verifyFormat("static A x = { { { init1, init2, init3, init4 },\n"
-               "                 { init1, init2, init3, init4 } } };");
+  verifyFormat("static A x = {{{}}};\n");
+  verifyFormat("static A x = {{{init1, init2, init3, init4},\n"
+               "               {init1, init2, init3, init4}}};",
+               getLLVMStyleWithColumns(50));
 
   verifyFormat("somes Status::global_reps[3] = {\n"
-               "  { kGlobalRef, OK_CODE, NULL, NULL, NULL },\n"
-               "  { kGlobalRef, CANCELLED_CODE, NULL, NULL, NULL },\n"
-               "  { kGlobalRef, UNKNOWN_CODE, NULL, NULL, NULL }\n"
-               "};");
+               "    {kGlobalRef, OK_CODE, NULL, NULL, NULL},\n"
+               "    {kGlobalRef, CANCELLED_CODE, NULL, NULL, NULL},\n"
+               "    {kGlobalRef, UNKNOWN_CODE, NULL, NULL, NULL}};",
+               getLLVMStyleWithColumns(60));
   verifyGoogleFormat("SomeType Status::global_reps[3] = {\n"
                      "    {kGlobalRef, OK_CODE, NULL, NULL, NULL},\n"
                      "    {kGlobalRef, CANCELLED_CODE, NULL, NULL, NULL},\n"
                      "    {kGlobalRef, UNKNOWN_CODE, NULL, NULL, NULL}};");
   verifyFormat(
-      "CGRect cg_rect = { { rect.fLeft, rect.fTop },\n"
-      "                   { rect.fRight - rect.fLeft, rect.fBottom - rect.fTop"
-      " } };");
+      "CGRect cg_rect = {{rect.fLeft, rect.fTop},\n"
+      "                  {rect.fRight - rect.fLeft, rect.fBottom - rect.fTop}};");
 
   verifyFormat(
-      "SomeArrayOfSomeType a = { { { 1, 2, 3 }, { 1, 2, 3 },\n"
-      "                            { 111111111111111111111111111111,\n"
-      "                              222222222222222222222222222222,\n"
-      "                              333333333333333333333333333333 },\n"
-      "                            { 1, 2, 3 }, { 1, 2, 3 } } };");
-  verifyFormat(
-      "SomeArrayOfSomeType a = { { { 1, 2, 3 } }, { { 1, 2, 3 } },\n"
-      "                          { { 111111111111111111111111111111,\n"
-      "                              222222222222222222222222222222,\n"
-      "                              333333333333333333333333333333 } },\n"
-      "                          { { 1, 2, 3 } }, { { 1, 2, 3 } } };");
-  verifyGoogleFormat(
       "SomeArrayOfSomeType a = {\n"
-      "    {{1, 2, 3}}, {{1, 2, 3}},\n"
+      "    {{1, 2, 3},\n"
+      "     {1, 2, 3},\n"
+      "     {111111111111111111111111111111, 222222222222222222222222222222,\n"
+      "      333333333333333333333333333333},\n"
+      "     {1, 2, 3},\n"
+      "     {1, 2, 3}}};");
+  verifyFormat(
+      "SomeArrayOfSomeType a = {\n"
+      "    {{1, 2, 3}},\n"
+      "    {{1, 2, 3}},\n"
       "    {{111111111111111111111111111111, 222222222222222222222222222222,\n"
       "      333333333333333333333333333333}},\n"
-      "    {{1, 2, 3}}, {{1, 2, 3}}};");
+      "    {{1, 2, 3}},\n"
+      "    {{1, 2, 3}}};");
 
   verifyFormat(
       "struct {\n"
       "  unsigned bit;\n"
       "  const char *const name;\n"
-      "} kBitsToOs[] = { { kOsMac, \"Mac\" },\n"
-      "                  { kOsWin, \"Windows\" },\n"
-      "                  { kOsLinux, \"Linux\" },\n"
-      "                  { kOsCrOS, \"Chrome OS\" } };");
+      "} kBitsToOs[] = {{kOsMac, \"Mac\"},\n"
+      "                 {kOsWin, \"Windows\"},\n"
+      "                 {kOsLinux, \"Linux\"},\n"
+      "                 {kOsCrOS, \"Chrome OS\"}};");
 }
 
 TEST_F(FormatTest, FormatsSmallMacroDefinitionsInSingleLine) {
@@ -1978,6 +2303,10 @@
   verifyFormat("#define A ''qqq");
   verifyFormat("#define A `qqq");
   verifyFormat("f(\"aaaa, bbbb, \"\\\"ccccc\\\"\");");
+  EXPECT_EQ("const char *c = STRINGIFY(\n"
+            "\\na : b);",
+            format("const char * c = STRINGIFY(\n"
+                   "\\na : b);"));
 }
 
 TEST_F(FormatTest, IndentsPPDirectiveInReducedSpace) {
@@ -2077,7 +2406,8 @@
 }
 
 TEST_F(FormatTest, RespectWhitespaceInMacroDefinitions) {
-  verifyFormat("#define A (1)");
+  EXPECT_EQ("#define A (x)", format("#define A (x)"));
+  EXPECT_EQ("#define A(x)", format("#define A(x)"));
 }
 
 TEST_F(FormatTest, EmptyLinesInMacroDefinitions) {
@@ -2150,7 +2480,6 @@
             "};",
             format("class A  :  public QObject {\n"
                    "     Q_Object\n"
-                   "\n"
                    "  A() {\n}\n"
                    "}  ;"));
 }
@@ -2181,6 +2510,17 @@
                    "  IPC_END_MESSAGE_MAP()\n"
                    "}"));
 
+  // Same inside macros.
+  EXPECT_EQ("#define LIST(L) \\\n"
+            "  L(A)          \\\n"
+            "  L(B)          \\\n"
+            "  L(C)",
+            format("#define LIST(L) \\\n"
+                   "  L(A) \\\n"
+                   "  L(B) \\\n"
+                   "  L(C)",
+                   getGoogleStyle()));
+
   // These must not be recognized as macros.
   EXPECT_EQ("int q() {\n"
             "  f(x);\n"
@@ -2225,44 +2565,65 @@
                    "  ifstream(x)\n >> x;\n"
                    "}\n"));
   EXPECT_EQ("int q() {\n"
-            "  f(x)\n"
+            "  F(x)\n"
             "  if (1) {\n"
             "  }\n"
-            "  f(x)\n"
+            "  F(x)\n"
             "  while (1) {\n"
             "  }\n"
-            "  f(x)\n"
-            "  g(x);\n"
-            "  f(x)\n"
+            "  F(x)\n"
+            "  G(x);\n"
+            "  F(x)\n"
             "  try {\n"
-            "    q();\n"
-            "  }\n"
-            "  catch (...) {\n"
+            "    Q();\n"
+            "  } catch (...) {\n"
             "  }\n"
             "}\n",
             format("int q() {\n"
-                   "f(x)\n"
+                   "F(x)\n"
                    "if (1) {}\n"
-                   "f(x)\n"
+                   "F(x)\n"
                    "while (1) {}\n"
-                   "f(x)\n"
-                   "g(x);\n"
-                   "f(x)\n"
-                   "try { q(); } catch (...) {}\n"
+                   "F(x)\n"
+                   "G(x);\n"
+                   "F(x)\n"
+                   "try { Q(); } catch (...) {}\n"
                    "}\n"));
   EXPECT_EQ("class A {\n"
             "  A() : t(0) {}\n"
+            "  A(int i) noexcept() : {}\n"
             "  A(X x)\n" // FIXME: function-level try blocks are broken.
             "  try : t(0) {\n"
-            "  }\n"
-            "  catch (...) {\n"
+            "  } catch (...) {\n"
             "  }\n"
             "};",
             format("class A {\n"
                    "  A()\n : t(0) {}\n"
+                   "  A(int i)\n noexcept() : {}\n"
                    "  A(X x)\n"
                    "  try : t(0) {} catch (...) {}\n"
                    "};"));
+  EXPECT_EQ(
+      "class SomeClass {\n"
+      "public:\n"
+      "  SomeClass() EXCLUSIVE_LOCK_FUNCTION(mu_);\n"
+      "};",
+      format("class SomeClass {\n"
+             "public:\n"
+             "  SomeClass()\n"
+             "  EXCLUSIVE_LOCK_FUNCTION(mu_);\n"
+             "};"));
+  EXPECT_EQ(
+      "class SomeClass {\n"
+      "public:\n"
+      "  SomeClass()\n"
+      "      EXCLUSIVE_LOCK_FUNCTION(mu_);\n"
+      "};",
+      format("class SomeClass {\n"
+             "public:\n"
+             "  SomeClass()\n"
+             "  EXCLUSIVE_LOCK_FUNCTION(mu_);\n"
+             "};", getLLVMStyleWithColumns(40)));
 }
 
 TEST_F(FormatTest, LayoutMacroDefinitionsStatementsSpanningBlocks) {
@@ -2326,7 +2687,7 @@
   EXPECT_EQ("int\n"
             "#define A\n"
             "    a;",
-            format("int\n#define A\na;", getGoogleStyle()));
+            format("int\n#define A\na;"));
   verifyFormat("functionCallTo(\n"
                "    someOtherFunction(\n"
                "        withSomeParameters, whichInSequence,\n"
@@ -2392,6 +2753,11 @@
                "#endif");
 }
 
+TEST_F(FormatTest, GraciouslyHandleIncorrectPreprocessorConditions) {
+  verifyFormat("#endif\n"
+               "#if B");
+}
+
 TEST_F(FormatTest, FormatsJoinedLinesOnSubsequentRuns) {
   FormatStyle SingleLine = getLLVMStyle();
   SingleLine.AllowShortIfStatementsOnASingleLine = true;
@@ -2450,7 +2816,7 @@
                "  struct s {\n"
                "    int i;\n"
                "  };\n"
-               "  s kBitsToOs[] = { { 10 } };\n"
+               "  s kBitsToOs[] = {{10}};\n"
                "  for (int i = 0; i < 10; ++i)\n"
                "    return;\n"
                "}");
@@ -2460,6 +2826,14 @@
                "  somethingelse();\n"
                "});",
                getLLVMStyleWithColumns(40));
+  verifyFormat("DEBUG( //\n"
+               "    { f(); }, a);");
+  verifyFormat("DEBUG( //\n"
+               "    {\n"
+               "      f(); //\n"
+               "    },\n"
+               "    a);");
+
   EXPECT_EQ("call(parameter, {\n"
             "  something();\n"
             "  // Comment too\n"
@@ -2506,6 +2880,45 @@
                "                 return;\n"
                "             },\n"
                "      a);", Style);
+}
+
+TEST_F(FormatTest, IndividualStatementsOfNestedBlocks) {
+  EXPECT_EQ("DEBUG({\n"
+            "  int i;\n"
+            "  int        j;\n"
+            "});",
+            format("DEBUG(   {\n"
+                   "  int        i;\n"
+                   "  int        j;\n"
+                   "}   )  ;",
+                   20, 1, getLLVMStyle()));
+  EXPECT_EQ("DEBUG(   {\n"
+            "  int        i;\n"
+            "  int j;\n"
+            "}   )  ;",
+            format("DEBUG(   {\n"
+                   "  int        i;\n"
+                   "  int        j;\n"
+                   "}   )  ;",
+                   41, 1, getLLVMStyle()));
+  EXPECT_EQ("DEBUG(   {\n"
+            "    int        i;\n"
+            "    int j;\n"
+            "}   )  ;",
+            format("DEBUG(   {\n"
+                   "    int        i;\n"
+                   "    int        j;\n"
+                   "}   )  ;",
+                   41, 1, getLLVMStyle()));
+  EXPECT_EQ("DEBUG({\n"
+            "  int i;\n"
+            "  int j;\n"
+            "});",
+            format("DEBUG(   {\n"
+                   "    int        i;\n"
+                   "    int        j;\n"
+                   "}   )  ;",
+                   20, 1, getLLVMStyle()));
 
   EXPECT_EQ("Debug({\n"
             "        if (aaaaaaaaaaaaaaaaaaaaaaaa)\n"
@@ -2518,18 +2931,26 @@
                    "      },\n"
                    "      a);",
                    50, 1, getLLVMStyle()));
-}
-
-TEST_F(FormatTest, IndividualStatementsOfNestedBlocks) {
   EXPECT_EQ("DEBUG({\n"
-            "  int        i;\n"
-            "  int j;\n"
+            "  DEBUG({\n"
+            "    int a;\n"
+            "    int b;\n"
+            "  }) ;\n"
             "});",
-            format("DEBUG(   {\n"
-                   "  int        i;\n"
-                   "  int        j;\n"
-                   "}   )  ;",
-                   40, 1, getLLVMStyle()));
+            format("DEBUG({\n"
+                   "  DEBUG({\n"
+                   "    int a;\n"
+                   "    int    b;\n" // Format this line only.
+                   "  }) ;\n"        // Don't touch this line.
+                   "});",
+                   35, 0, getLLVMStyle()));
+  EXPECT_EQ("DEBUG({\n"
+            "  int a; //\n"
+            "});",
+            format("DEBUG({\n"
+                   "    int a; //\n"
+                   "});",
+                   0, 0, getLLVMStyle()));
 }
 
 TEST_F(FormatTest, PutEmptyBlocksIntoOneLine) {
@@ -2574,9 +2995,21 @@
       "bool aaaaaaa =\n"
       "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaa).aaaaaaaaaaaaaaaaaaa() ||\n"
       "    bbbbbbbb();");
+  verifyFormat(
+      "bool aaaaaaa =\n"
+      "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaa).aaaaaaaaaaaaaaaaaaa() or\n"
+      "    bbbbbbbb();");
+
   verifyFormat("bool aaaaaaaaaaaaaaaaaaaaa =\n"
                "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa != bbbbbbbbbbbbbbbbbb &&\n"
                "    ccccccccc == ddddddddddd;");
+  verifyFormat("bool aaaaaaaaaaaaaaaaaaaaa =\n"
+               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa != bbbbbbbbbbbbbbbbbb and\n"
+               "    ccccccccc == ddddddddddd;");
+  verifyFormat(
+      "bool aaaaaaaaaaaaaaaaaaaaa =\n"
+      "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa not_eq bbbbbbbbbbbbbbbbbb and\n"
+      "    ccccccccc == ddddddddddd;");
 
   verifyFormat("aaaaaa = aaaaaaa(aaaaaaa, // break\n"
                "                 aaaaaa) &&\n"
@@ -2661,8 +3094,9 @@
                "            aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n"
                "        bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) {\n}");
   verifyFormat("if () {\n"
-               "} else if (aaaaa && bbbbb > // break\n"
-               "                        ccccc) {\n"
+               "} else if (aaaaa &&\n"
+               "           bbbbb > // break\n"
+               "               ccccc) {\n"
                "}");
 
   // Presence of a trailing comment used to change indentation of b.
@@ -2708,8 +3142,9 @@
                "       + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) {\n}",
                Style);
   verifyFormat("if () {\n"
-               "} else if (aaaaa && bbbbb // break\n"
-               "                    > ccccc) {\n"
+               "} else if (aaaaa\n"
+               "           && bbbbb // break\n"
+               "              > ccccc) {\n"
                "}",
                Style);
 
@@ -2720,6 +3155,16 @@
       "    + sizeof(int32_t) // Offset of CU in the .debug_info section\n"
       "    + sizeof(int8_t)  // Pointer Size (in bytes)\n"
       "    + sizeof(int8_t); // Segment Size (in bytes)");
+
+  verifyFormat("return boost::fusion::at_c<0>(iiii).second\n"
+               "       == boost::fusion::at_c<1>(iiii).second;",
+               Style);
+
+  Style.ColumnLimit = 60;
+  verifyFormat("zzzzzzzzzz\n"
+               "    = bbbbbbbbbbbbbbbbb\n"
+               "      >> aaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaa);",
+               Style);
 }
 
 TEST_F(FormatTest, ConstructorInitializers) {
@@ -2768,7 +3213,7 @@
                "          aaaaaaaaaaaaaaaaaaaaaaaaa(aaaa, aaaa)) {}");
 
   // Here a line could be saved by splitting the second initializer onto two
-  // lines, but that is not desireable.
+  // lines, but that is not desirable.
   verifyFormat("Constructor()\n"
                "    : aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaa),\n"
                "      aaaaaaaaaaa(aaaaaaaaaaa),\n"
@@ -2802,6 +3247,13 @@
                "    : aaaaa(aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa,\n"
                "            aaaaaaaaaaaaaaaaaaaaaa) {}",
                OnePerLine);
+
+  EXPECT_EQ("Constructor()\n"
+            "    : // Comment forcing unwanted break.\n"
+            "      aaaa(aaaa) {}",
+            format("Constructor() :\n"
+                   "    // Comment forcing unwanted break.\n"
+                   "    aaaa(aaaa) {}"));
 }
 
 TEST_F(FormatTest, MemoizationTests) {
@@ -2907,7 +3359,7 @@
   // 2) break after return type.
   verifyFormat(
       "Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
-      "    bbbbbbbbbbbbbb(Cccccccccccccc cccccccccccccccccccccccccc);",
+      "bbbbbbbbbbbbbb(Cccccccccccccc cccccccccccccccccccccccccc);",
       getGoogleStyle());
 
   // 3) break after (.
@@ -2919,8 +3371,8 @@
   // 4) break before after nested name specifiers.
   verifyFormat(
       "Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
-      "    SomeClasssssssssssssssssssssssssssssssssssssss::\n"
-      "        bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb(Cccccccccccccc cccccccccc);",
+      "SomeClasssssssssssssssssssssssssssssssssssssss::\n"
+      "    bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb(Cccccccccccccc cccccccccc);",
       getGoogleStyle());
 
   // However, there are exceptions, if a sufficient amount of lines can be
@@ -2934,9 +3386,9 @@
                "                                  Cccccccccccccc cccccccccc);");
   verifyFormat(
       "Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
-      "    bbbbbbbbbbb(Cccccccccccccc cccccccccc, Cccccccccccccc cccccccccc,\n"
-      "                Cccccccccccccc cccccccccc, Cccccccccccccc cccccccccc,\n"
-      "                Cccccccccccccc cccccccccc, Cccccccccccccc cccccccccc);",
+      "bbbbbbbbbbb(Cccccccccccccc cccccccccc, Cccccccccccccc cccccccccc,\n"
+      "            Cccccccccccccc cccccccccc, Cccccccccccccc cccccccccc,\n"
+      "            Cccccccccccccc cccccccccc, Cccccccccccccc cccccccccc);",
       getGoogleStyle());
   verifyFormat(
       "Aaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb(Cccccccccccccc cccccccccc,\n"
@@ -2963,9 +3415,18 @@
                "operator>(const SomeLoooooooooooooooooooooooooogType &other);");
   verifyFormat("SomeLoooooooooooooooooooooooooogType\n"
                "operator>>(const SomeLooooooooooooooooooooooooogType &other);");
+  verifyFormat("SomeLoooooooooooooooooooooooooogType\n"
+               "operator<<(const SomeLooooooooooooooooooooooooogType &other);");
+  verifyGoogleFormat(
+      "SomeLoooooooooooooooooooooooooooooogType operator>>(\n"
+      "    const SomeLooooooooogType &a, const SomeLooooooooogType &b);");
   verifyGoogleFormat(
       "SomeLoooooooooooooooooooooooooooooogType operator<<(\n"
       "    const SomeLooooooooogType &a, const SomeLooooooooogType &b);");
+  verifyFormat("void aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
+               "    int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = 1);");
+  verifyFormat("aaaaaaaaaaaaaaaaaaaaaa\n"
+               "aaaaaaaaaaaaaaaaaaaaaaaaa(int aaaaaaaaaaaaaaaaaaaaaaaa = 1);");
 }
 
 TEST_F(FormatTest, TrailingReturnType) {
@@ -3001,14 +3462,43 @@
                "                  aaaaa aaaaaaaaaaaaaaaaaaaa) OVERRIDE FINAL;");
   verifyFormat("void SomeFunction(aaaaa aaaaaaaaaaaaaaaaaaaa,\n"
                "                  aaaaa aaaaaaaaaaaaaaaaaaaa) override final;");
+  verifyFormat("virtual void aaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaa aaaa,\n"
+               "                   aaaaaaaaaaa aaaaa) const override;");
+  verifyGoogleFormat(
+      "virtual void aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()\n"
+      "    const override;");
 
-  // Unless this would lead to the first parameter being broken.
-  verifyFormat("void someLongFunction(int someLongParameter)\n"
-               "    const {}",
+  // Even if the first parameter has to be wrapped.
+  verifyFormat("void someLongFunction(\n"
+               "    int someLongParameter) const {}",
                getLLVMStyleWithColumns(46));
-  verifyFormat("void someLongFunction(int someLongParameter)\n"
-               "    const {}",
+  verifyFormat("void someLongFunction(\n"
+               "    int someLongParameter) const {}",
                Style);
+  verifyFormat("void someLongFunction(\n"
+               "    int someLongParameter) override {}",
+               Style);
+  verifyFormat("void someLongFunction(\n"
+               "    int someLongParameter) OVERRIDE {}",
+               Style);
+  verifyFormat("void someLongFunction(\n"
+               "    int someLongParameter) final {}",
+               Style);
+  verifyFormat("void someLongFunction(\n"
+               "    int someLongParameter) FINAL {}",
+               Style);
+  verifyFormat("void someLongFunction(\n"
+               "    int parameter) const override {}",
+               Style);
+
+  Style.BreakBeforeBraces = FormatStyle::BS_Allman;
+  verifyFormat("void someLongFunction(\n"
+               "    int someLongParameter) const\n"
+               "{\n"
+               "}",
+               Style);
+
+  // Unless these are unknown annotations.
   verifyFormat("void SomeFunction(aaaaaaaaaa aaaaaaaaaaaaaaa,\n"
                "                  aaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n"
                "    LONG_AND_UGLY_ANNOTATION;");
@@ -3021,6 +3511,8 @@
                "    LOCKS_EXCLUDED(aaaaaaaaaaaaa);");
   verifyFormat("void aaaaaaaaaaaa(int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) const\n"
                "    LOCKS_EXCLUDED(aaaaaaaaaaaaa) {}");
+  verifyGoogleFormat("void aaaaaaaaaaaaaa(aaaaaaaa aaa) override\n"
+                     "    AAAAAAAAAAAAAAAAAAAAAAAA(aaaaaaaaaaaaaaa);");
 
   verifyFormat(
       "void aaaaaaaaaaaaaaaaaa()\n"
@@ -3028,14 +3520,15 @@
       "                   aaaaaaaaaaaaaaaaaaaaaaaaa));");
   verifyFormat("bool aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
                "    __attribute__((unused));");
-  verifyFormat(
+  verifyGoogleFormat(
       "bool aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
-      "    GUARDED_BY(aaaaaaaaaaaa);",
-      getGoogleStyle());
-  verifyFormat(
+      "    GUARDED_BY(aaaaaaaaaaaa);");
+  verifyGoogleFormat(
       "bool aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
-      "    GUARDED_BY(aaaaaaaaaaaa);",
-      getGoogleStyle());
+      "    GUARDED_BY(aaaaaaaaaaaa);");
+  verifyGoogleFormat(
+      "bool aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa GUARDED_BY(aaaaaaaaaaaa) =\n"
+      "    aaaaaaaa::aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;");
 }
 
 TEST_F(FormatTest, BreaksDesireably) {
@@ -3079,7 +3572,7 @@
       "                      aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
       "                  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);");
 
-  // Indent consistently indenpendent of call expression.
+  // Indent consistently independent of call expression.
   verifyFormat("aaaaaaaaaaa(bbbbbbbbbbbbbbbbbbbbbbbbb.ccccccccccccccccc(\n"
                "    dddddddddddddddddddddddddddddd));\n"
                "aaaaaaaaaaa(bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb(\n"
@@ -3230,15 +3723,15 @@
       "void f() {\n"
       "  someo->Add((new util::filetools::Handler(dir))\n"
       "                 ->OnEvent1(NewPermanentCallback(\n"
-      "                       this, &HandlerHolderClass::EventHandlerCBA))\n"
+      "                     this, &HandlerHolderClass::EventHandlerCBA))\n"
       "                 ->OnEvent2(NewPermanentCallback(\n"
-      "                       this, &HandlerHolderClass::EventHandlerCBB))\n"
+      "                     this, &HandlerHolderClass::EventHandlerCBB))\n"
       "                 ->OnEvent3(NewPermanentCallback(\n"
-      "                       this, &HandlerHolderClass::EventHandlerCBC))\n"
+      "                     this, &HandlerHolderClass::EventHandlerCBC))\n"
       "                 ->OnEvent5(NewPermanentCallback(\n"
-      "                       this, &HandlerHolderClass::EventHandlerCBD))\n"
+      "                     this, &HandlerHolderClass::EventHandlerCBD))\n"
       "                 ->OnEvent6(NewPermanentCallback(\n"
-      "                       this, &HandlerHolderClass::EventHandlerCBE)));\n"
+      "                     this, &HandlerHolderClass::EventHandlerCBE)));\n"
       "}");
 
   verifyFormat(
@@ -3264,7 +3757,7 @@
                "    .has<bbbbbbbbbbbbbbbbbbbbb>();");
   verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaa()\n"
                "    .aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa<\n"
-               "         aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>();");
+               "        aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>();");
 
   // Prefer not to break after empty parentheses.
   verifyFormat("FirstToken->WhitespaceRange.getBegin().getLocWithOffset(\n"
@@ -3275,20 +3768,42 @@
   verifyFormat(
       "if (aaaaaaaaaaaaaaaaaaaaaaaaa ||\n"
       "    bbbbbbbbbbbbbbbbbbbbbbbbb && ccccccccccccccccccccccccc) {\n}");
+  verifyFormat(
+      "if (aaaaaaaaaaaaaaaaaaaaaaaaa or\n"
+      "    bbbbbbbbbbbbbbbbbbbbbbbbb and cccccccccccccccccccccccc) {\n}");
+
   verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaa && bbbbbbbbbbbbbbbbbbbbbbbbb ||\n"
                "    ccccccccccccccccccccccccc) {\n}");
+  verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaa and bbbbbbbbbbbbbbbbbbbbbbbb or\n"
+               "    ccccccccccccccccccccccccc) {\n}");
+
   verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaa || bbbbbbbbbbbbbbbbbbbbbbbbb ||\n"
                "    ccccccccccccccccccccccccc) {\n}");
+  verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaa or bbbbbbbbbbbbbbbbbbbbbbbbb or\n"
+               "    ccccccccccccccccccccccccc) {\n}");
+
   verifyFormat(
       "if ((aaaaaaaaaaaaaaaaaaaaaaaaa || bbbbbbbbbbbbbbbbbbbbbbbbb) &&\n"
       "    ccccccccccccccccccccccccc) {\n}");
+  verifyFormat(
+      "if ((aaaaaaaaaaaaaaaaaaaaaaaaa or bbbbbbbbbbbbbbbbbbbbbbbbb) and\n"
+      "    ccccccccccccccccccccccccc) {\n}");
+
   verifyFormat("return aaaa & AAAAAAAAAAAAAAAAAAAAAAAAAAAAA ||\n"
                "       bbbb & BBBBBBBBBBBBBBBBBBBBBBBBBBBBB ||\n"
                "       cccc & CCCCCCCCCCCCCCCCCCCCCCCCCC ||\n"
                "       dddd & DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD;");
+  verifyFormat("return aaaa & AAAAAAAAAAAAAAAAAAAAAAAAAAAAA or\n"
+               "       bbbb & BBBBBBBBBBBBBBBBBBBBBBBBBBBBB or\n"
+               "       cccc & CCCCCCCCCCCCCCCCCCCCCCCCCC or\n"
+               "       dddd & DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD;");
+
   verifyFormat("if ((aaaaaaaaaa != aaaaaaaaaaaaaaa ||\n"
                "     aaaaaaaaaaaaaaaaaaaaaaaa() >= aaaaaaaaaaaaaaaaaaaa) &&\n"
                "    aaaaaaaaaaaaaaa != aa) {\n}");
+  verifyFormat("if ((aaaaaaaaaa != aaaaaaaaaaaaaaa or\n"
+               "     aaaaaaaaaaaaaaaaaaaaaaaa() >= aaaaaaaaaaaaaaaaaaaa) and\n"
+               "    aaaaaaaaaaaaaaa != aa) {\n}");
 }
 
 TEST_F(FormatTest, BreaksAfterAssignments) {
@@ -3420,6 +3935,17 @@
                "                  : (bbbbbbbbbbbbbbb //\n"
                "                         ? ccccccccccccccc\n"
                "                         : ddddddddddddddd);");
+  verifyFormat(
+      "int aaaaaaaaaaaaaaaaaaaaaaaaaaa = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+      "                                      ? aaaaaaaaaaaaaaaaaaaaaaaaa +\n"
+      "                                            aaaaaaaaaaaaaaaaaaaaa +\n"
+      "                                            aaaaaaaaaaaaaaaaaaaaa\n"
+      "                                      : aaaaaaaaaa;");
+  verifyFormat(
+      "aaaaaa = aaaaaaaaaaaa\n"
+      "             ? aaaaaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+      "                          : aaaaaaaaaaaaaaaaaaaaaa\n"
+      "             : aaaaaaaaaaaaaaaaaaaaaaaaaaaa;");
 
   FormatStyle NoBinPacking = getLLVMStyle();
   NoBinPacking.BinPackParameters = false;
@@ -3495,7 +4021,7 @@
                "    aaaaaaaaaaaaaaaaaaaaaaaaaaa;",
                Style);
   verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaa =\n"
-               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ?\n" 
+               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ?\n"
                "        aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa :\n"
                "        aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;",
                Style);
@@ -3610,6 +4136,13 @@
   verifyFormat("#define A \"def\"\n"
                "f(\"abc\" A \"ghi\"\n"
                "  \"jkl\");");
+
+  verifyFormat("f(L\"a\"\n"
+               "  L\"b\")");
+  verifyFormat("#define A(X)            \\\n"
+               "  L\"aaaaa\" #X L\"bbbbbb\" \\\n"
+               "  L\"ccccc\"",
+               getLLVMStyleWithColumns(25));
 }
 
 TEST_F(FormatTest, AlwaysBreakBeforeMultilineStrings) {
@@ -3638,6 +4171,16 @@
                "     \"bbbb\"\n"
                "     \"cccc\");",
                Break);
+  verifyFormat("aaaa(qqq,\n"
+               "     L\"bbbb\"\n"
+               "     L\"cccc\");",
+               Break);
+
+  // As we break before unary operators, breaking right after them is bad.
+  verifyFormat("string foo = abc ? \"x\"\n"
+               "                   \"blah blah blah blah blah blah\"\n"
+               "                 : \"y\";",
+               Break);
 
   // Don't break if there is no column gain.
   verifyFormat("f(\"aaaa\"\n"
@@ -3688,6 +4231,18 @@
       "aaaaaaaa << (aaaaaaaaaaaaaaaaaaa << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
       "                                 << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n"
       "         << aaaaaaaaaaaaaaaaaaaaaaaaaaaaa;");
+  verifyFormat(
+      "llvm::errs() << \"a: \" << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
+      "                             aaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
+      "                             aaaaaaaaaaaaaaaaaaaaaaaaaaaa);");
+  verifyFormat(
+      "llvm::errs() << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
+      "                    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
+      "                    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n"
+      "             << bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;");
+  verifyFormat(
+      "llvm::errs() << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
+      "    aaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaa);");
 
   verifyFormat("return out << \"somepacket = {\\n\"\n"
                "           << \" aaaaaa = \" << pkt.aaaaaa << \"\\n\"\n"
@@ -3712,6 +4267,8 @@
       "  llvm::outs() << \"aaaaaaaaaaaaaaaaaaaa: \"\n"
       "               << aaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaa);\n"
       "}");
+  verifyFormat("llvm::outs() << \"aaaaaaaaaaaaaaaa: \"\n"
+               "             << aaaaaaaa.aaaaaaaaaaaa(aaa)->aaaaaaaaaaaaaa();");
 
   // Breaking before the first "<<" is generally not desirable.
   verifyFormat(
@@ -3730,6 +4287,8 @@
                getLLVMStyleWithColumns(70));
 
   // But sometimes, breaking before the first "<<" is desirable.
+  verifyFormat("Diag(aaaaaaaaaaaaaaaaaaaa, aaaaaaaa)\n"
+               "    << aaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaa);");
   verifyFormat("Diag(aaaaaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbb)\n"
                "    << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
                "    << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;");
@@ -3744,6 +4303,11 @@
   EXPECT_EQ("llvm::errs() << \"\n"
             "             << a;",
             format("llvm::errs() << \"\n<<a;"));
+
+  verifyFormat("void f() {\n"
+               "  CHECK_EQ(aaaa, (*bbbbbbbbb)->cccccc)\n"
+               "      << \"qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq\";\n"
+               "}");
 }
 
 TEST_F(FormatTest, UnderstandsEquals) {
@@ -3789,8 +4353,8 @@
 
   verifyFormat("EXPECT_CALL(SomeObject, SomeFunction(Parameter))\n"
                "    .WillRepeatedly(Return(SomeValue));");
-  verifyFormat("SomeMap[std::pair(aaaaaaaaaaaa, bbbbbbbbbbbbbbb)]\n"
-               "    .insert(ccccccccccccccccccccccc);");
+  verifyFormat("SomeMap[std::pair(aaaaaaaaaaaa, bbbbbbbbbbbbbbb)].insert(\n"
+               "    ccccccccccccccccccccccc);");
   verifyFormat("aaaaa(aaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
                "            aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa).aaaaa(aaaaa),\n"
                "      aaaaaaaaaaaaaaaaaaaaa);");
@@ -3847,6 +4411,12 @@
   verifyFormat(
       "aaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
       "    aaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaa));");
+  verifyFormat("aaaaaaaaaa = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
+               "                 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n"
+               "                 .aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa();");
+  verifyFormat("aaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
+               "               aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n"
+               "               .aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa());");
 }
 
 TEST_F(FormatTest, WrapsTemplateDeclarations) {
@@ -3877,6 +4447,10 @@
       "template <typename T1, typename T2 = char, typename T3 = char,\n"
       "          typename T4 = char>\n"
       "void f();");
+  verifyFormat("template <typename aaaaaaaaaaa, typename bbbbbbbbbbbbb,\n"
+               "          template <typename> class cccccccccccccccccccccc,\n"
+               "          typename ddddddddddddd>\n"
+               "class C {};");
   verifyFormat(
       "aaaaaaaaaaaaaaaaaaaaaaaa<aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaa>(\n"
       "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);");
@@ -3898,6 +4472,14 @@
       "                      aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>(\n"
       "        bbbbbbbbbbbbbbbbbbbbbbbb);",
       getLLVMStyleWithColumns(72));
+  EXPECT_EQ("static_cast<A< //\n"
+            "    B> *>(\n"
+            "\n"
+            "    );",
+            format("static_cast<A<//\n"
+                   "    B>*>(\n"
+                   "\n"
+                   "    );"));
 
   FormatStyle AlwaysBreak = getLLVMStyle();
   AlwaysBreak.AlwaysBreakTemplateDeclarations = true;
@@ -3953,7 +4535,7 @@
 
 TEST_F(FormatTest, UnderstandsTemplateParameters) {
   verifyFormat("A<int> a;");
-  verifyFormat("A<A<A<int> > > a;");
+  verifyFormat("A<A<A<int>>> a;");
   verifyFormat("A<A<A<int, 2>, 3>, 4> a;");
   verifyFormat("bool x = a < 1 || 2 > a;");
   verifyFormat("bool x = 5 < f<int>();");
@@ -4017,8 +4599,11 @@
                "  (a->*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)(\n"
                "      aaaa, bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb);\n"
                "}");
+  verifyFormat(
+      "(aaaaaaaaaa->*bbbbbbb)(\n"
+      "    aaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaa));");
   FormatStyle Style = getLLVMStyle();
-  Style.PointerBindsToType = true;
+  Style.PointerAlignment = FormatStyle::PAS_Left;
   verifyFormat("typedef bool* (Class::*Member)() const;", Style);
 }
 
@@ -4052,22 +4637,20 @@
   verifyFormat("#define X -1");
   verifyFormat("#define X -kConstant");
 
-  verifyFormat("const NSPoint kBrowserFrameViewPatternOffset = { -5, +3 };");
-  verifyFormat("const NSPoint kBrowserFrameViewPatternOffset = { +5, -3 };");
+  verifyFormat("const NSPoint kBrowserFrameViewPatternOffset = {-5, +3};");
+  verifyFormat("const NSPoint kBrowserFrameViewPatternOffset = {+5, -3};");
 
   verifyFormat("int a = /* confusing comment */ -1;");
   // FIXME: The space after 'i' is wrong, but hopefully, this is a rare case.
   verifyFormat("int a = i /* confusing comment */++;");
 }
 
-TEST_F(FormatTest, IndentsRelativeToUnaryOperators) {
+TEST_F(FormatTest, DoesNotIndentRelativeToUnaryOperators) {
   verifyFormat("if (!aaaaaaaaaa( // break\n"
-               "         aaaaa)) {\n"
+               "        aaaaa)) {\n"
                "}");
   verifyFormat("aaaaaaaaaa(!aaaaaaaaaa( // break\n"
-               "                aaaaa));");
-
-  // Only indent relative to unary operators if the expression is nested.
+               "               aaaaa));");
   verifyFormat("*aaa = aaaaaaa( // break\n"
                "    bbbbbb);");
 }
@@ -4088,7 +4671,7 @@
   verifyFormat("operator void *();");
   verifyFormat("operator SomeType<int>();");
   verifyFormat("operator SomeType<int, int>();");
-  verifyFormat("operator SomeType<SomeType<int> >();");
+  verifyFormat("operator SomeType<SomeType<int>>();");
   verifyFormat("void *operator new(std::size_t size);");
   verifyFormat("void *operator new[](std::size_t size);");
   verifyFormat("void operator delete(void *ptr);");
@@ -4110,6 +4693,16 @@
   verifyGoogleFormat("operator ::A();");
 
   verifyFormat("using A::operator+;");
+
+  verifyFormat("Deleted &operator=(const Deleted &)& = default;");
+  verifyFormat("Deleted &operator=(const Deleted &)&& = delete;");
+  verifyGoogleFormat("Deleted& operator=(const Deleted&)& = default;");
+  verifyGoogleFormat("Deleted& operator=(const Deleted&)&& = delete;");
+
+  verifyFormat("string // break\n"
+               "operator()() & {}");
+  verifyFormat("string // break\n"
+               "operator()() && {}");
 }
 
 TEST_F(FormatTest, UnderstandsNewAndDelete) {
@@ -4155,6 +4748,7 @@
   verifyIndependentOfContext("a * [self dostuff];");
   verifyIndependentOfContext("int x = a * (a + b);");
   verifyIndependentOfContext("(a *)(a + b);");
+  verifyIndependentOfContext("*(int *)(p & ~3UL) = 0;");
   verifyIndependentOfContext("int *pa = (int *)&a;");
   verifyIndependentOfContext("return sizeof(int **);");
   verifyIndependentOfContext("return sizeof(int ******);");
@@ -4167,18 +4761,24 @@
   verifyFormat("auto a = [](int **&, int ***) {};");
   verifyFormat("auto PointerBinding = [](const char *S) {};");
   verifyFormat("typedef typeof(int(int, int)) *MyFunc;");
+  verifyFormat("[](const decltype(*a) &value) {}");
+  verifyIndependentOfContext("typedef void (*f)(int *a);");
+  verifyIndependentOfContext("int i{a * b};");
+  verifyIndependentOfContext("aaa && aaa->f();");
 
   verifyIndependentOfContext("InvalidRegions[*R] = 0;");
 
   verifyIndependentOfContext("A<int *> a;");
   verifyIndependentOfContext("A<int **> a;");
   verifyIndependentOfContext("A<int *, int *> a;");
+  verifyIndependentOfContext("A<int *[]> a;");
   verifyIndependentOfContext(
       "const char *const p = reinterpret_cast<const char *const>(q);");
   verifyIndependentOfContext("A<int **, int **> a;");
   verifyIndependentOfContext("void f(int *a = d * e, int *b = c * d);");
   verifyFormat("for (char **a = b; *a; ++a) {\n}");
   verifyFormat("for (; a && b;) {\n}");
+  verifyFormat("bool foo = true && [] { return false; }();");
 
   verifyFormat(
       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
@@ -4208,8 +4808,8 @@
   verifyIndependentOfContext("f(b * /* confusing comment */ ++c);");
   verifyFormat(
       "int *MyValues = {\n"
-      "  *A, // Operator detection might be confused by the '{'\n"
-      "  *BB // Operator detection might be confused by previous comment\n"
+      "    *A, // Operator detection might be confused by the '{'\n"
+      "    *BB // Operator detection might be confused by previous comment\n"
       "};");
 
   verifyIndependentOfContext("if (int *a = &b)");
@@ -4244,12 +4844,65 @@
   verifyGoogleFormat("T** t = new T*();");
 
   FormatStyle PointerLeft = getLLVMStyle();
-  PointerLeft.PointerBindsToType = true;
+  PointerLeft.PointerAlignment = FormatStyle::PAS_Left;
   verifyFormat("delete *x;", PointerLeft);
+  verifyFormat("STATIC_ASSERT((a & b) == 0);");
+  verifyFormat("STATIC_ASSERT(0 == (a & b));");
+  verifyFormat("template <bool a, bool b> "
+               "typename t::if<x && y>::type f() {}");
+  verifyFormat("template <int *y> f() {}");
+  verifyFormat("vector<int *> v;");
+  verifyFormat("vector<int *const> v;");
+  verifyFormat("vector<int *const **const *> v;");
+  verifyFormat("vector<int *volatile> v;");
+  verifyFormat("vector<a * b> v;");
+  verifyFormat("foo<b && false>();");
+  verifyFormat("foo<b & 1>();");
+
+  verifyIndependentOfContext("MACRO(int *i);");
+  verifyIndependentOfContext("MACRO(auto *a);");
+  verifyIndependentOfContext("MACRO(const A *a);");
+  verifyIndependentOfContext("MACRO('0' <= c && c <= '9');");
+  // FIXME: Is there a way to make this work?
+  // verifyIndependentOfContext("MACRO(A *a);");
+
+  verifyFormat("DatumHandle const *operator->() const { return input_; }");
+
+  EXPECT_EQ("#define OP(x)                                    \\\n"
+            "  ostream &operator<<(ostream &s, const A &a) {  \\\n"
+            "    return s << a.DebugString();                 \\\n"
+            "  }",
+            format("#define OP(x) \\\n"
+                   "  ostream &operator<<(ostream &s, const A &a) { \\\n"
+                   "    return s << a.DebugString(); \\\n"
+                   "  }",
+                   getLLVMStyleWithColumns(50)));
+
+  // FIXME: We cannot handle this case yet; we might be able to figure out that
+  // foo<x> d > v; doesn't make sense.
+  verifyFormat("foo<a < b && c> d > v;");
+
+  FormatStyle PointerMiddle = getLLVMStyle();
+  PointerMiddle.PointerAlignment = FormatStyle::PAS_Middle;
+  verifyFormat("delete *x;", PointerMiddle);
+  verifyFormat("int * x;", PointerMiddle);
+  verifyFormat("template <int * y> f() {}", PointerMiddle);
+  verifyFormat("int * f(int * a) {}", PointerMiddle);
+  verifyFormat("int main(int argc, char ** argv) {}", PointerMiddle);
+  verifyFormat("Test::Test(int b) : a(b * b) {}", PointerMiddle);
+  verifyFormat("A<int *> a;", PointerMiddle);
+  verifyFormat("A<int **> a;", PointerMiddle);
+  verifyFormat("A<int *, int *> a;", PointerMiddle);
+  verifyFormat("A<int * []> a;", PointerMiddle);
+  verifyFormat("A = new SomeType * [Length]();", PointerMiddle);
+  verifyFormat("A = new SomeType * [Length];", PointerMiddle);
+  verifyFormat("T ** t = new T *;", PointerMiddle);
 }
 
 TEST_F(FormatTest, UnderstandsAttributes) {
   verifyFormat("SomeType s __attribute__((unused)) (InitValue);");
+  verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa __attribute__((unused))\n"
+               "aaaaaaaaaaaaaaaaaaaaaaa(int i);");
 }
 
 TEST_F(FormatTest, UnderstandsEllipsis) {
@@ -4258,7 +4911,7 @@
   verifyFormat("template <class... Ts> void Foo(Ts *... ts) {}");
 
   FormatStyle PointersLeft = getLLVMStyle();
-  PointersLeft.PointerBindsToType = true;
+  PointersLeft.PointerAlignment = FormatStyle::PAS_Left;
   verifyFormat("template <class... Ts> void Foo(Ts*... ts) {}", PointersLeft);
 }
 
@@ -4304,6 +4957,7 @@
                "};");
   verifyGoogleFormat("#define IF(a, b, c) if (a && (b == c))");
   verifyGoogleFormat("#define WHILE(a, b, c) while (a && (b == c))");
+  verifyFormat("#define A(a, b) (a && b)");
 }
 
 TEST_F(FormatTest, FormatsBinaryOperatorsPrecedingEquals) {
@@ -4334,13 +4988,22 @@
   verifyFormat("return (my_int)aaa;");
   verifyFormat("#define x ((int)-1)");
   verifyFormat("#define p(q) ((int *)&q)");
+  verifyFormat("fn(a)(b) + 1;");
 
-  // FIXME: Without type knowledge, this can still fall apart miserably.
-  verifyFormat("void f() { my_int a = (my_int) * b; }");
-  verifyFormat("void f() { return P ? (my_int) * P : (my_int)0; }");
-  verifyFormat("my_int a = (my_int) ~0;");
-  verifyFormat("my_int a = (my_int)++ a;");
-  verifyFormat("my_int a = (my_int) + 2;");
+  verifyFormat("void f() { my_int a = (my_int)*b; }");
+  verifyFormat("void f() { return P ? (my_int)*P : (my_int)0; }");
+  verifyFormat("my_int a = (my_int)~0;");
+  verifyFormat("my_int a = (my_int)++a;");
+  verifyFormat("my_int a = (my_int)+2;");
+  verifyFormat("my_int a = (my_int)1;");
+  verifyFormat("my_int a = (my_int *)1;");
+  verifyFormat("my_int a = (const my_int)-1;");
+  verifyFormat("my_int a = (const my_int *)-1;");
+
+  // FIXME: single value wrapped with paren will be treated as cast.
+  verifyFormat("void f(int i = (kValue)*kMask) {}");
+
+  verifyFormat("{ (void)F; }");
 
   // Don't break after a cast's
   verifyFormat("int aaaaaaaaaaaaaaaaaaaaaaaaaaa =\n"
@@ -4361,7 +5024,6 @@
   verifyFormat("void f(SmallVector<int>) {}");
   verifyFormat("void f(SmallVector<int>);");
   verifyFormat("void f(SmallVector<int>) = 0;");
-  verifyFormat("void f(int i = (kValue) * kMask) {}");
   verifyFormat("void f(int i = (kA * kB) & kMask) {}");
   verifyFormat("int a = sizeof(int) * b;");
   verifyFormat("int a = alignof(int) * b;", getGoogleStyle());
@@ -4409,26 +5071,51 @@
   verifyFormat("void f() { function(*some_pointer_var)[0] = 10; }");
 }
 
+TEST_F(FormatTest, BreaksLongVariableDeclarations) {
+  verifyFormat("LoooooooooooooooooooooooooooooooooooooooongType\n"
+               "    LoooooooooooooooooooooooooooooooooooooooongVariable;");
+  verifyFormat("LoooooooooooooooooooooooooooooooooooooooongType const\n"
+               "    LoooooooooooooooooooooooooooooooooooooooongVariable;");
+
+  // Different ways of ()-initializiation.
+  verifyFormat("LoooooooooooooooooooooooooooooooooooooooongType\n"
+               "    LoooooooooooooooooooooooooooooooooooooooongVariable(1);");
+  verifyFormat("LoooooooooooooooooooooooooooooooooooooooongType\n"
+               "    LoooooooooooooooooooooooooooooooooooooooongVariable(a);");
+  verifyFormat("LoooooooooooooooooooooooooooooooooooooooongType\n"
+               "    LoooooooooooooooooooooooooooooooooooooooongVariable({});");
+}
+
 TEST_F(FormatTest, BreaksLongDeclarations) {
   verifyFormat("typedef LoooooooooooooooooooooooooooooooooooooooongType\n"
-               "    AnotherNameForTheLongType;",
-               getGoogleStyle());
+               "    AnotherNameForTheLongType;");
   verifyFormat("typedef LongTemplateType<aaaaaaaaaaaaaaaaaaa()>\n"
-               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;",
-               getGoogleStyle());
-  verifyFormat("LoooooooooooooooooooooooooooooooooooooooongType\n"
-               "    LoooooooooooooooooooooooooooooooooooooooongVariable;",
-               getGoogleStyle());
-  verifyFormat("LoooooooooooooooooooooooooooooooooooooooongType const\n"
-               "    LoooooooooooooooooooooooooooooooooooooooongVariable;",
-               getGoogleStyle());
+               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;");
   verifyFormat("LoooooooooooooooooooooooooooooooooooooooongReturnType\n"
-               "    LoooooooooooooooooooooooooooooooongFunctionDeclaration();",
-               getGoogleStyle());
+               "LoooooooooooooooooooooooooooooooongFunctionDeclaration();");
   verifyFormat("LoooooooooooooooooooooooooooooooooooooooongReturnType\n"
                "LooooooooooooooooooooooooooooooooooongFunctionDefinition() {}");
   verifyFormat("LoooooooooooooooooooooooooooooooooooooooongReturnType const\n"
                "LooooooooooooooooooooooooooooooooooongFunctionDefinition() {}");
+  verifyFormat("decltype(LoooooooooooooooooooooooooooooooooooooooongName)\n"
+               "LooooooooooooooooooooooooooooooooooongFunctionDefinition() {}");
+  FormatStyle Indented = getLLVMStyle();
+  Indented.IndentWrappedFunctionNames = true;
+  verifyFormat("LoooooooooooooooooooooooooooooooooooooooongReturnType\n"
+               "    LoooooooooooooooooooooooooooooooongFunctionDeclaration();",
+               Indented);
+  verifyFormat(
+      "LoooooooooooooooooooooooooooooooooooooooongReturnType\n"
+      "    LooooooooooooooooooooooooooooooooooongFunctionDefinition() {}",
+      Indented);
+  verifyFormat(
+      "LoooooooooooooooooooooooooooooooooooooooongReturnType const\n"
+      "    LooooooooooooooooooooooooooooooooooongFunctionDefinition() {}",
+      Indented);
+  verifyFormat(
+      "decltype(LoooooooooooooooooooooooooooooooooooooooongName)\n"
+      "    LooooooooooooooooooooooooooooooooooongFunctionDefinition() {}",
+      Indented);
 
   // FIXME: Without the comment, this breaks after "(".
   verifyFormat("LoooooooooooooooooooooooooooooooooooooooongType  // break\n"
@@ -4485,6 +5172,13 @@
       "llvm::outs() << \"aaaaaaaaaaaa: \"\n"
       "             << (*aaaaaaaiaaaaaaa)[aaaaaaaaaaaaaaaaaaaaaaaaa]\n"
       "                                  [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa];");
+
+  verifyGoogleFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa<int>\n"
+                     "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[aaaaaaaaaaaa];");
+  verifyFormat(
+      "aaaaaaaaaaa aaaaaaaaaaaaaaa = aaaaaaaaaaaaaaaaaaaaaaaaaa->aaaaaaaaa[0]\n"
+      "                                  .aaaaaaa[0]\n"
+      "                                  .aaaaaaaaaaaaaaaaaaaaaa();");
 }
 
 TEST_F(FormatTest, LineStartsWithSpecialCharacter) {
@@ -4515,6 +5209,15 @@
   verifyFormat("#if __has_include(<strstream>)\n"
                "#include <strstream>\n"
                "#endif");
+
+  // Protocol buffer definition or missing "#".
+  verifyFormat("import \"aaaaaaaaaaaaaaaaa/aaaaaaaaaaaaaaa\";",
+               getLLVMStyleWithColumns(30));
+
+  FormatStyle Style = getLLVMStyle();
+  Style.AlwaysBreakBeforeMultilineStrings = true;
+  Style.ColumnLimit = 0;
+  verifyFormat("#import \"abc.h\"", Style);
 }
 
 //===----------------------------------------------------------------------===//
@@ -4645,134 +5348,243 @@
 
 TEST_F(FormatTest, LayoutCallsInsideBraceInitializers) {
   verifyFormat("int x = {\n"
-               "  avariable,\n"
-               "  b(alongervariable)\n"
-               "};",
+               "    avariable,\n"
+               "    b(alongervariable)};",
                getLLVMStyleWithColumns(25));
 }
 
 TEST_F(FormatTest, LayoutBraceInitializersInReturnStatement) {
-  verifyFormat("return (a)(b) { 1, 2, 3 };");
+  verifyFormat("return (a)(b){1, 2, 3};");
 }
 
-TEST_F(FormatTest, LayoutCxx11ConstructorBraceInitializers) {
-    verifyFormat("vector<int> x{ 1, 2, 3, 4 };");
-    verifyFormat("vector<T> x{ {}, {}, {}, {} };");
-    verifyFormat("f({ 1, 2 });");
-    verifyFormat("auto v = Foo{ 1 };");
-    verifyFormat("f({ 1, 2 }, { { 2, 3 }, { 4, 5 } }, c, { d });");
-    verifyFormat("Class::Class : member{ 1, 2, 3 } {}");
-    verifyFormat("new vector<int>{ 1, 2, 3 };");
-    verifyFormat("new int[3]{ 1, 2, 3 };");
-    verifyFormat("return { arg1, arg2 };");
-    verifyFormat("return { arg1, SomeType{ parameter } };");
-    verifyFormat("new T{ arg1, arg2 };");
-    verifyFormat("f(MyMap[{ composite, key }]);");
-    verifyFormat("class Class {\n"
-                 "  T member = { arg1, arg2 };\n"
-                 "};");
-    verifyFormat(
-        "foo = aaaaaaaaaaa ? vector<int>{ aaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
-        "                                 aaaaaaaaaaaaaaaaaaaa, aaaaa }\n"
-        "                  : vector<int>{ bbbbbbbbbbbbbbbbbbbbbbbbbbb,\n"
-        "                                 bbbbbbbbbbbbbbbbbbbb, bbbbb };");
-    verifyFormat("DoSomethingWithVector({} /* No data */);");
-    verifyFormat("DoSomethingWithVector({ {} /* No data */ }, { { 1, 2 } });");
-    verifyFormat(
-        "someFunction(OtherParam, BracedList{\n"
-        "                           // comment 1 (Forcing interesting break)\n"
-        "                           param1, param2,\n"
-        "                           // comment 2\n"
-        "                           param3, param4\n"
-        "                         });");
-    verifyFormat(
-        "std::this_thread::sleep_for(\n"
-        "    std::chrono::nanoseconds{ std::chrono::seconds{ 1 } } / 5);");
+TEST_F(FormatTest, LayoutCxx11BraceInitializers) {
+  verifyFormat("vector<int> x{1, 2, 3, 4};");
+  verifyFormat("vector<int> x{\n"
+               "    1, 2, 3, 4,\n"
+               "};");
+  verifyFormat("vector<T> x{{}, {}, {}, {}};");
+  verifyFormat("f({1, 2});");
+  verifyFormat("auto v = Foo{-1};");
+  verifyFormat("f({1, 2}, {{2, 3}, {4, 5}}, c, {d});");
+  verifyFormat("Class::Class : member{1, 2, 3} {}");
+  verifyFormat("new vector<int>{1, 2, 3};");
+  verifyFormat("new int[3]{1, 2, 3};");
+  verifyFormat("new int{1};");
+  verifyFormat("return {arg1, arg2};");
+  verifyFormat("return {arg1, SomeType{parameter}};");
+  verifyFormat("int count = set<int>{f(), g(), h()}.size();");
+  verifyFormat("new T{arg1, arg2};");
+  verifyFormat("f(MyMap[{composite, key}]);");
+  verifyFormat("class Class {\n"
+               "  T member = {arg1, arg2};\n"
+               "};");
+  verifyFormat("vector<int> foo = {::SomeGlobalFunction()};");
+  verifyFormat("static_assert(std::is_integral<int>{} + 0, \"\");");
+  verifyFormat("int a = std::is_integral<int>{} + 0;");
 
-    FormatStyle NoSpaces = getLLVMStyle();
-    NoSpaces.Cpp11BracedListStyle = true;
-    verifyFormat("vector<int> x{1, 2, 3, 4};", NoSpaces);
-    verifyFormat("vector<T> x{{}, {}, {}, {}};", NoSpaces);
-    verifyFormat("f({1, 2});", NoSpaces);
-    verifyFormat("auto v = Foo{-1};", NoSpaces);
-    verifyFormat("f({1, 2}, {{2, 3}, {4, 5}}, c, {d});", NoSpaces);
-    verifyFormat("Class::Class : member{1, 2, 3} {}", NoSpaces);
-    verifyFormat("new vector<int>{1, 2, 3};", NoSpaces);
-    verifyFormat("new int[3]{1, 2, 3};", NoSpaces);
-    verifyFormat("return {arg1, arg2};", NoSpaces);
-    verifyFormat("return {arg1, SomeType{parameter}};", NoSpaces);
-    verifyFormat("new T{arg1, arg2};", NoSpaces);
-    verifyFormat("f(MyMap[{composite, key}]);", NoSpaces);
-    verifyFormat("class Class {\n"
-                 "  T member = {arg1, arg2};\n"
-                 "};",
-                 NoSpaces);
-    verifyFormat("Constructor::Constructor()\n"
-                 "    : some_value{ //\n"
-                 "          aaaaaaa //\n"
-                 "      } {}",
-                 NoSpaces);
+  verifyFormat("int foo(int i) { return fo1{}(i); }");
+  verifyFormat("int foo(int i) { return fo1{}(i); }");
+  verifyFormat("auto i = decltype(x){};");
+
+  // In combination with BinPackParameters = false.
+  FormatStyle NoBinPacking = getLLVMStyle();
+  NoBinPacking.BinPackParameters = false;
+  verifyFormat("const Aaaaaa aaaaa = {aaaaa,\n"
+               "                      bbbbb,\n"
+               "                      ccccc,\n"
+               "                      ddddd,\n"
+               "                      eeeee,\n"
+               "                      ffffff,\n"
+               "                      ggggg,\n"
+               "                      hhhhhh,\n"
+               "                      iiiiii,\n"
+               "                      jjjjjj,\n"
+               "                      kkkkkk};",
+               NoBinPacking);
+  verifyFormat("const Aaaaaa aaaaa = {\n"
+               "    aaaaa,\n"
+               "    bbbbb,\n"
+               "    ccccc,\n"
+               "    ddddd,\n"
+               "    eeeee,\n"
+               "    ffffff,\n"
+               "    ggggg,\n"
+               "    hhhhhh,\n"
+               "    iiiiii,\n"
+               "    jjjjjj,\n"
+               "    kkkkkk,\n"
+               "};",
+               NoBinPacking);
+
+  // FIXME: The alignment of these trailing comments might be bad. Then again,
+  // this might be utterly useless in real code.
+  verifyFormat("Constructor::Constructor()\n"
+               "    : some_value{        //\n"
+               "                 aaaaaaa //\n"
+               "      } {}");
+
+  // In braced lists, the first comment is always assumed to belong to the
+  // first element. Thus, it can be moved to the next or previous line as
+  // appropriate.
+  EXPECT_EQ("function({// First element:\n"
+            "          1,\n"
+            "          // Second element:\n"
+            "          2});",
+            format("function({\n"
+                   "    // First element:\n"
+                   "    1,\n"
+                   "    // Second element:\n"
+                   "    2});"));
+  EXPECT_EQ("std::vector<int> MyNumbers{\n"
+            "    // First element:\n"
+            "    1,\n"
+            "    // Second element:\n"
+            "    2};",
+            format("std::vector<int> MyNumbers{// First element:\n"
+                   "                           1,\n"
+                   "                           // Second element:\n"
+                   "                           2};",
+                   getLLVMStyleWithColumns(30)));
+
+  FormatStyle ExtraSpaces = getLLVMStyle();
+  ExtraSpaces.Cpp11BracedListStyle = false;
+  ExtraSpaces.ColumnLimit = 75;
+  verifyFormat("vector<int> x{ 1, 2, 3, 4 };", ExtraSpaces);
+  verifyFormat("vector<T> x{ {}, {}, {}, {} };", ExtraSpaces);
+  verifyFormat("f({ 1, 2 });", ExtraSpaces);
+  verifyFormat("auto v = Foo{ 1 };", ExtraSpaces);
+  verifyFormat("f({ 1, 2 }, { { 2, 3 }, { 4, 5 } }, c, { d });", ExtraSpaces);
+  verifyFormat("Class::Class : member{ 1, 2, 3 } {}", ExtraSpaces);
+  verifyFormat("new vector<int>{ 1, 2, 3 };", ExtraSpaces);
+  verifyFormat("new int[3]{ 1, 2, 3 };", ExtraSpaces);
+  verifyFormat("return { arg1, arg2 };", ExtraSpaces);
+  verifyFormat("return { arg1, SomeType{ parameter } };", ExtraSpaces);
+  verifyFormat("int count = set<int>{ f(), g(), h() }.size();", ExtraSpaces);
+  verifyFormat("new T{ arg1, arg2 };", ExtraSpaces);
+  verifyFormat("f(MyMap[{ composite, key }]);", ExtraSpaces);
+  verifyFormat("class Class {\n"
+               "  T member = { arg1, arg2 };\n"
+               "};",
+               ExtraSpaces);
+  verifyFormat(
+      "foo = aaaaaaaaaaa ? vector<int>{ aaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
+      "                                 aaaaaaaaaaaaaaaaaaaa, aaaaa }\n"
+      "                  : vector<int>{ bbbbbbbbbbbbbbbbbbbbbbbbbbb,\n"
+      "                                 bbbbbbbbbbbbbbbbbbbb, bbbbb };",
+      ExtraSpaces);
+  verifyFormat("DoSomethingWithVector({} /* No data */);", ExtraSpaces);
+  verifyFormat("DoSomethingWithVector({\n"
+               "                        {} /* No data */\n"
+               "                      },\n"
+               "                      { { 1, 2 } });",
+               ExtraSpaces);
+  verifyFormat(
+      "someFunction(OtherParam,\n"
+      "             BracedList{ // comment 1 (Forcing interesting break)\n"
+      "                         param1, param2,\n"
+      "                         // comment 2\n"
+      "                         param3, param4\n"
+      "             });",
+      ExtraSpaces);
+  verifyFormat(
+      "std::this_thread::sleep_for(\n"
+      "    std::chrono::nanoseconds{ std::chrono::seconds{ 1 } } / 5);",
+      ExtraSpaces);
+  verifyFormat("std::vector<MyValues> aaaaaaaaaaaaaaaaaaa{\n"
+               "  aaaaaaa,      aaaaaaaaaa,\n"
+               "  aaaaa,        aaaaaaaaaaaaaaa,\n"
+               "  aaa,          aaaaaaaaaa,\n"
+               "  a,            aaaaaaaaaaaaaaaaaaaaa,\n"
+               "  aaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaa,\n"
+               "  aaaaaaa,      a\n"
+               "};",
+               ExtraSpaces);
+  verifyFormat("vector<int> foo = { ::SomeGlobalFunction() };", ExtraSpaces);
 }
 
 TEST_F(FormatTest, FormatsBracedListsInColumnLayout) {
-  verifyFormat("vector<int> x = { 1, 22, 333, 4444, 55555, 666666, 7777777,\n"
-               "                  1, 22, 333, 4444, 55555, 666666, 7777777,\n"
-               "                  1, 22, 333, 4444, 55555, 666666, 7777777,\n"
-               "                  1, 22, 333, 4444, 55555, 666666, 7777777,\n"
-               "                  1, 22, 333, 4444, 55555, 666666, 7777777,\n"
-               "                  1, 22, 333, 4444, 55555, 666666, 7777777 };");
-  verifyFormat("vector<int> x = { 1, 22, 333, 4444, 55555, 666666, 7777777,\n"
-               "                  // line comment\n"
-               "                  1, 22, 333, 4444, 55555, 666666, 7777777,\n"
-               "                  1, 22, 333, 4444, 55555,\n"
-               "                  // line comment\n"
-               "                  1, 22, 333, 4444, 55555, 666666, 7777777,\n"
-               "                  1, 22, 333, 4444, 55555, 666666, 7777777 };");
+  verifyFormat("vector<int> x = {1, 22, 333, 4444, 55555, 666666, 7777777,\n"
+               "                 1, 22, 333, 4444, 55555, 666666, 7777777,\n"
+               "                 1, 22, 333, 4444, 55555, 666666, 7777777,\n"
+               "                 1, 22, 333, 4444, 55555, 666666, 7777777,\n"
+               "                 1, 22, 333, 4444, 55555, 666666, 7777777,\n"
+               "                 1, 22, 333, 4444, 55555, 666666, 7777777};");
+  verifyFormat("vector<int> x = {1, 22, 333, 4444, 55555, 666666, 7777777,\n"
+               "                 // line comment\n"
+               "                 1, 22, 333, 4444, 55555, 666666, 7777777,\n"
+               "                 1, 22, 333, 4444, 55555,\n"
+               "                 // line comment\n"
+               "                 1, 22, 333, 4444, 55555, 666666, 7777777,\n"
+               "                 1, 22, 333, 4444, 55555, 666666, 7777777};");
   verifyFormat(
-      "vector<int> x = { 1,       22, 333, 4444, 55555, 666666, 7777777,\n"
-      "                  1,       22, 333, 4444, 55555, 666666, 7777777,\n"
-      "                  1,       22, 333, 4444, 55555, 666666, // comment\n"
-      "                  7777777, 1,  22,  333,  4444,  55555,  666666,\n"
-      "                  7777777, 1,  22,  333,  4444,  55555,  666666,\n"
-      "                  7777777, 1,  22,  333,  4444,  55555,  666666,\n"
-      "                  7777777 };");
+      "vector<int> x = {1,       22, 333, 4444, 55555, 666666, 7777777,\n"
+      "                 1,       22, 333, 4444, 55555, 666666, 7777777,\n"
+      "                 1,       22, 333, 4444, 55555, 666666, // comment\n"
+      "                 7777777, 1,  22,  333,  4444,  55555,  666666,\n"
+      "                 7777777, 1,  22,  333,  4444,  55555,  666666,\n"
+      "                 7777777, 1,  22,  333,  4444,  55555,  666666,\n"
+      "                 7777777};");
   verifyFormat("static const uint16_t CallerSavedRegs64Bittttt[] = {\n"
-               "  X86::RAX, X86::RDX, X86::RCX, X86::RSI, X86::RDI,\n"
-               "  X86::R8,  X86::R9,  X86::R10, X86::R11, 0\n"
-               "};");
-  verifyFormat("vector<int> x = { 1, 1, 1, 1,\n"
-               "                  1, 1, 1, 1 };",
+               "    X86::RAX, X86::RDX, X86::RCX, X86::RSI, X86::RDI,\n"
+               "    X86::R8,  X86::R9,  X86::R10, X86::R11, 0};");
+  verifyFormat("vector<int> x = {1, 1, 1, 1,\n"
+               "                 1, 1, 1, 1};",
                getLLVMStyleWithColumns(39));
-  verifyFormat("vector<int> x = { 1, 1, 1, 1,\n"
-               "                  1, 1, 1, 1 };",
+  verifyFormat("vector<int> x = {1, 1, 1, 1,\n"
+               "                 1, 1, 1, 1};",
                getLLVMStyleWithColumns(38));
   verifyFormat("vector<int> aaaaaaaaaaaaaaaaaaaaaa = {\n"
-               "  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1\n"
-               "};",
-               getLLVMStyleWithColumns(40));
+               "    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};",
+               getLLVMStyleWithColumns(43));
 
   // Trailing commas.
-  verifyFormat("vector<int> x = { 1, 1, 1, 1,\n"
-               "                  1, 1, 1, 1, };",
-               getLLVMStyleWithColumns(39));
-  verifyFormat("vector<int> x = { 1, 1, 1, 1,\n"
-               "                  1, 1, 1, 1, //\n"
+  verifyFormat("vector<int> x = {\n"
+               "    1, 1, 1, 1, 1, 1, 1, 1,\n"
                "};",
                getLLVMStyleWithColumns(39));
-  verifyFormat("vector<int> x = { 1, 1, 1, 1,\n"
-               "                  1, 1, 1, 1,\n"
-               "                  /**/ /**/ };",
+  verifyFormat("vector<int> x = {\n"
+               "    1, 1, 1, 1, 1, 1, 1, 1, //\n"
+               "};",
                getLLVMStyleWithColumns(39));
-  verifyFormat("return { { aaaaaaaaaaaaaaaaaaaaa },\n"
-               "         { aaaaaaaaaaaaaaaaaaa },\n"
-               "         { aaaaaaaaaaaaaaaaaaaaa },\n"
-               "         { aaaaaaaaaaaaaaaaa } };",
+  verifyFormat("vector<int> x = {\n"
+               "    1, 1, 1, 1, 1, 1, 1, 1,\n"
+               "    /**/ /**/\n"
+               "};",
+               getLLVMStyleWithColumns(39));
+  verifyFormat("return {{aaaaaaaaaaaaaaaaaaaaa},\n"
+               "        {aaaaaaaaaaaaaaaaaaa},\n"
+               "        {aaaaaaaaaaaaaaaaaaaaa},\n"
+               "        {aaaaaaaaaaaaaaaaa}};",
                getLLVMStyleWithColumns(60));
+
+  // With nested lists, we should either format one item per line or all nested
+  // lists one one line.
+  // FIXME: For some nested lists, we can do better.
+  verifyFormat(
+      "SomeStruct my_struct_array = {\n"
+      "    {aaaaaa, aaaaaaaa, aaaaaaaaaa, aaaaaaaaa, aaaaaaaaa, aaaaaaaaaa,\n"
+      "     aaaaaaaaaaaaa, aaaaaaa, aaa},\n"
+      "    {aaa, aaa},\n"
+      "    {aaa, aaa},\n"
+      "    {aaaa, aaaa, aaaa, aaaa, aaaa, aaaa, aaaa, aaa},\n"
+      "    {aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaa,\n"
+      "     aaaaaaaaaaaa, a, aaaaaaaaaa, aaaaaaaaa, aaa}};");
+
+  // No column layout should be used here.
+  verifyFormat("aaaaaaaaaaaaaaa = {aaaaaaaaaaaaaaaaaaaaaaaaaaa, 0, 0,\n"
+               "                   bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb};");
 }
 
 TEST_F(FormatTest, PullTrivialFunctionDefinitionsIntoSingleLine) {
+  FormatStyle DoNotMerge = getLLVMStyle();
+  DoNotMerge.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
+
   verifyFormat("void f() { return 42; }");
   verifyFormat("void f() {\n"
+               "  return 42;\n"
+               "}",
+               DoNotMerge);
+  verifyFormat("void f() {\n"
                "  // Comment\n"
                "}");
   verifyFormat("{\n"
@@ -4787,6 +5599,13 @@
   verifyFormat("void f() { int a; } // comment");
   verifyFormat("void f() {\n"
                "} // comment",
+               DoNotMerge);
+  verifyFormat("void f() {\n"
+               "  int a;\n"
+               "} // comment",
+               DoNotMerge);
+  verifyFormat("void f() {\n"
+               "} // comment",
                getLLVMStyleWithColumns(15));
 
   verifyFormat("void f() { return 42; }", getLLVMStyleWithColumns(23));
@@ -4794,13 +5613,76 @@
 
   verifyFormat("void f() {}", getLLVMStyleWithColumns(11));
   verifyFormat("void f() {\n}", getLLVMStyleWithColumns(10));
+  verifyFormat("class C {\n"
+               "  C()\n"
+               "      : iiiiiiii(nullptr),\n"
+               "        kkkkkkk(nullptr),\n"
+               "        mmmmmmm(nullptr),\n"
+               "        nnnnnnn(nullptr) {}\n"
+               "};",
+               getGoogleStyle());
+
+  FormatStyle NoColumnLimit = getLLVMStyle();
+  NoColumnLimit.ColumnLimit = 0;
+  EXPECT_EQ("A() : b(0) {}", format("A():b(0){}", NoColumnLimit));
+  EXPECT_EQ("class C {\n"
+            "  A() : b(0) {}\n"
+            "};", format("class C{A():b(0){}};", NoColumnLimit));
+  EXPECT_EQ("A()\n"
+            "    : b(0) {\n"
+            "}",
+            format("A()\n:b(0)\n{\n}", NoColumnLimit));
+
+  FormatStyle DoNotMergeNoColumnLimit = NoColumnLimit;
+  DoNotMergeNoColumnLimit.AllowShortFunctionsOnASingleLine =
+      FormatStyle::SFS_None;
+  EXPECT_EQ("A()\n"
+            "    : b(0) {\n"
+            "}",
+            format("A():b(0){}", DoNotMergeNoColumnLimit));
+  EXPECT_EQ("A()\n"
+            "    : b(0) {\n"
+            "}",
+            format("A()\n:b(0)\n{\n}", DoNotMergeNoColumnLimit));
+
+  verifyFormat("#define A          \\\n"
+               "  void f() {       \\\n"
+               "    int i;         \\\n"
+               "  }",
+               getLLVMStyleWithColumns(20));
+  verifyFormat("#define A           \\\n"
+               "  void f() { int i; }",
+               getLLVMStyleWithColumns(21));
+  verifyFormat("#define A            \\\n"
+               "  void f() {         \\\n"
+               "    int i;           \\\n"
+               "  }                  \\\n"
+               "  int j;",
+               getLLVMStyleWithColumns(22));
+  verifyFormat("#define A             \\\n"
+               "  void f() { int i; } \\\n"
+               "  int j;",
+               getLLVMStyleWithColumns(23));
+}
+
+TEST_F(FormatTest, PullInlineFunctionDefinitionsIntoSingleLine) {
+  FormatStyle MergeInlineOnly = getLLVMStyle();
+  MergeInlineOnly.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
+  verifyFormat("class C {\n"
+               "  int f() { return 42; }\n"
+               "};",
+               MergeInlineOnly);
+  verifyFormat("int f() {\n"
+               "  return 42;\n"
+               "}",
+               MergeInlineOnly);
 }
 
 TEST_F(FormatTest, UnderstandContextOfRecordTypeKeywords) {
   // Elaborate type variable declarations.
-  verifyFormat("struct foo a = { bar };\nint n;");
-  verifyFormat("class foo a = { bar };\nint n;");
-  verifyFormat("union foo a = { bar };\nint n;");
+  verifyFormat("struct foo a = {bar};\nint n;");
+  verifyFormat("class foo a = {bar};\nint n;");
+  verifyFormat("union foo a = {bar};\nint n;");
 
   // Elaborate types inside function definitions.
   verifyFormat("struct foo f() {}\nint n;");
@@ -4864,6 +5746,7 @@
 }
 
 TEST_F(FormatTest, FormatHashIfExpressions) {
+  verifyFormat("#if AAAA && BBBB");
   // FIXME: Come up with a better indentation for #elif.
   verifyFormat(
       "#if !defined(AAAAAAA) && (defined CCCCCC || defined DDDDDD) &&  \\\n"
@@ -4906,6 +5789,17 @@
                "  if (true) continue;\n"
                "}",
                ShortMergedIf);
+  ShortMergedIf.ColumnLimit = 29;
+  verifyFormat("#define A                   \\\n"
+               "  if (aaaaaaaaaa) return 1; \\\n"
+               "  return 2;",
+               ShortMergedIf);
+  ShortMergedIf.ColumnLimit = 28;
+  verifyFormat("#define A         \\\n"
+               "  if (aaaaaaaaaa) \\\n"
+               "    return 1;     \\\n"
+               "  return 2;",
+               ShortMergedIf);
 }
 
 TEST_F(FormatTest, BlockCommentsInControlLoops) {
@@ -5054,13 +5948,13 @@
 
 TEST_F(FormatTest, BlockCommentsAtEndOfLine) {
   EXPECT_EQ("a = {\n"
-            "  1111 /*    */\n"
+            "    1111 /*    */\n"
             "};",
             format("a = {1111 /*    */\n"
                    "};",
                    getLLVMStyleWithColumns(15)));
   EXPECT_EQ("a = {\n"
-            "  1111 /*      */\n"
+            "    1111 /*      */\n"
             "};",
             format("a = {1111 /*      */\n"
                    "};",
@@ -5068,8 +5962,8 @@
 
   // FIXME: The formatting is still wrong here.
   EXPECT_EQ("a = {\n"
-            "  1111 /*      a\n"
-            "          */\n"
+            "    1111 /*      a\n"
+            "            */\n"
             "};",
             format("a = {1111 /*      a */\n"
                    "};",
@@ -5156,11 +6050,6 @@
   verifyGoogleFormat("- foo:(int)foo;");
 }
 
-TEST_F(FormatTest, FormatObjCBlocks) {
-  verifyFormat("int (^Block)(int, int);");
-  verifyFormat("int (^Block1)(int, int) = ^(int i, int j)");
-}
-
 TEST_F(FormatTest, FormatObjCInterface) {
   verifyFormat("@interface Foo : NSObject <NSSomeDelegate> {\n"
                "@public\n"
@@ -5262,6 +6151,16 @@
                "}\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) {
@@ -5310,10 +6209,14 @@
                "@implementation Bar\n"
                "@end");
 
-  verifyFormat("@implementation Foo : Bar\n"
-               "+ (id)init {\n}\n"
-               "- (void)foo {\n}\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"
@@ -5372,6 +6275,10 @@
                "    int *looooooooooooooooooooooooooooongNumber;\n"
                "@property(nonatomic, assign, readonly)\n"
                "    NSString *looooooooooooooooooooooooooooongName;");
+
+  verifyFormat("@implementation PR18406\n"
+               "}\n"
+               "@end");
 }
 
 TEST_F(FormatTest, FormatObjCMethodDeclarations) {
@@ -5501,6 +6408,17 @@
       "                    der:NO]);\n"
       "}",
       getLLVMStyleWithColumns(70));
+  verifyFormat("{\n"
+               "  popup_window_.reset([[RenderWidgetPopupWindow alloc]\n"
+               "      initWithContentRect:NSMakeRect(origin_global.x,\n"
+               "                                     origin_global.y,\n"
+               "                                     pos.width(),\n"
+               "                                     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];");
 
@@ -5548,6 +6466,8 @@
   verifyFormat("[self // break\n"
                "      a:a\n"
                "    aaa:aaa];");
+  verifyFormat("bool a = ([aaaaaaaa aaaaa] == aaaaaaaaaaaaaaaaa ||\n"
+               "          [aaaaaaaa aaaaa] == aaaaaaaaaaaaaaaaaaaa);");
 }
 
 TEST_F(FormatTest, ObjCAt) {
@@ -5606,6 +6526,12 @@
   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;");
@@ -5625,26 +6551,30 @@
   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\" : @1}");
+  verifyFormat("return @{@\"one\" : @1;");
+  verifyFormat("@{@\"one\" : @1}");
 
-  verifyFormat("@{ @\"one\" : @{ @2 : @1 } }");
-  verifyFormat("@{ @\"one\" : @{ @2 : @1 }, }");
+  verifyFormat("@{@\"one\" : @{@2 : @1}}");
+  verifyFormat("@{\n"
+               "  @\"one\" : @{@2 : @1},\n"
+               "}");
 
-  verifyFormat("@{ 1 > 2 ? @\"one\" : @\"two\" : 1 > 2 ? @1 : @2 }");
+  verifyFormat("@{1 > 2 ? @\"one\" : @\"two\" : 1 > 2 ? @1 : @2}");
   verifyFormat("[self setDict:@{}");
-  verifyFormat("[self setDict:@{ @1 : @2 }");
-  verifyFormat("NSLog(@\"%@\", @{ @1 : @2, @2 : @3 }[@1]);");
+  verifyFormat("[self setDict:@{@1 : @2}");
+  verifyFormat("NSLog(@\"%@\", @{@1 : @2, @2 : @3}[@1]);");
   verifyFormat(
-      "NSDictionary *masses = @{ @\"H\" : @1.0078, @\"He\" : @4.0026 };");
+      "NSDictionary *masses = @{@\"H\" : @1.0078, @\"He\" : @4.0026};");
   verifyFormat(
-      "NSDictionary *settings = @{ AVEncoderKey : @(AVAudioQualityMax) };");
+      "NSDictionary *settings = @{AVEncoderKey : @(AVAudioQualityMax)};");
 
   verifyFormat(
       "NSDictionary *d = @{\n"
@@ -5662,6 +6592,11 @@
       "  NSFontAttributeNameeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee : "
       "regularFont,\n"
       "};");
+  verifyFormat(
+      "@{\n"
+      "  NSFontAttributeNameeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee :\n"
+      "      reeeeeeeeeeeeeeeeeeeeeeeegularFont,\n"
+      "};");
 
   // We should try to be robust in case someone forgets the "@".
   verifyFormat(
@@ -5670,6 +6605,12 @@
       "  @\"dte\" : [NSDate date],\n"
       "  @\"processInfo\" : [NSProcessInfo processInfo]\n"
       "};");
+  verifyFormat("NSMutableDictionary *dictionary =\n"
+               "    [NSMutableDictionary dictionaryWithDictionary:@{\n"
+               "      aaaaaaaaaaaaaaaaaaaaa : aaaaaaaaaaaaa,\n"
+               "      bbbbbbbbbbbbbbbbbb : bbbbb,\n"
+               "      cccccccccccccccc : ccccccccccccccc\n"
+               "    }];");
 }
 
 TEST_F(FormatTest, ObjCArrayLiterals) {
@@ -5707,6 +6648,14 @@
                "  @\"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\"] ]];");
 }
 
 TEST_F(FormatTest, ReformatRegionAdjustsIndent) {
@@ -5792,9 +6741,32 @@
             format("  int a;\n"
                    "void ffffff() {}",
                    11, 0, getLLVMStyleWithColumns(11)));
+
+  EXPECT_EQ(" void f() {\n"
+            "#define A 1\n"
+            " }",
+            format(" void f() {\n"
+                   "     #define A 1\n" // Format this line.
+                   " }",
+                   20, 0, getLLVMStyle()));
+  EXPECT_EQ(" void f() {\n"
+            "    int i;\n"
+            "#define A \\\n"
+            "    int i;  \\\n"
+            "   int j;\n"
+            "    int k;\n"
+            " }",
+            format(" void f() {\n"
+                   "    int i;\n"
+                   "#define A \\\n"
+                   "    int i;  \\\n"
+                   "   int j;\n"
+                   "      int k;\n" // Format this line.
+                   " }",
+                   67, 0, getLLVMStyle()));
 }
 
-TEST_F(FormatTest, BreakStringLiterals) {
+TEST_F(FormatTest, BreaksStringLiterals) {
   EXPECT_EQ("\"some text \"\n"
             "\"other\";",
             format("\"some text other\";", getLLVMStyleWithColumns(12)));
@@ -5954,7 +6926,17 @@
       format("#define A \"some text other\";", AlignLeft));
 }
 
-TEST_F(FormatTest, BreaksWideStringLiterals) {
+TEST_F(FormatTest, BreaksStringLiteralsWithTabs) {
+  EXPECT_EQ(
+      "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+      "(\n"
+      "    \"x\t\");",
+      format("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+             "aaaaaaa("
+             "\"x\t\");"));
+}
+
+TEST_F(FormatTest, BreaksWideAndNSStringLiterals) {
   EXPECT_EQ(
       "u8\"utf8 string \"\n"
       "u8\"literal\";",
@@ -5970,6 +6952,9 @@
   EXPECT_EQ("L\"wide string \"\n"
             "L\"literal\";",
             format("L\"wide string literal\";", getGoogleStyleWithColumns(16)));
+  EXPECT_EQ("@\"NSString \"\n"
+            "@\"literal\";",
+            format("@\"NSString literal\";", getGoogleStyleWithColumns(19)));
 }
 
 TEST_F(FormatTest, BreaksRawStringLiterals) {
@@ -6026,7 +7011,7 @@
 
 TEST_F(FormatTest, CountsCharactersInMultilineRawStringLiterals) {
   EXPECT_EQ("f(g(R\"x(raw literal)x\", a), b);",
-            format("f(g(R\"x(raw literal)x\", a), b);", getGoogleStyle()));
+            format("f(g(R\"x(raw literal)x\",   a), b);", getGoogleStyle()));
   EXPECT_EQ("fffffffffff(g(R\"x(\n"
             "multiline raw string literal xxxxxxxxxxxxxx\n"
             ")x\",\n"
@@ -6056,10 +7041,19 @@
                    getGoogleStyleWithColumns(20)));
   EXPECT_EQ("fffffffffff(R\"x(\n"
             "multiline raw string literal xxxxxxxxxxxxxx\n"
-            ")x\" +\n"
-            "            bbbbbb);",
+            ")x\" + bbbbbb);",
             format("fffffffffff(R\"x(\n"
                    "multiline raw string literal xxxxxxxxxxxxxx\n"
+                   ")x\" +   bbbbbb);",
+                   getGoogleStyleWithColumns(20)));
+  EXPECT_EQ("fffffffffff(\n"
+            "    R\"x(\n"
+            "multiline raw string literal xxxxxxxxxxxxxx\n"
+            ")x\" +\n"
+            "    bbbbbb);",
+            format("fffffffffff(\n"
+                   " R\"x(\n"
+                   "multiline raw string literal xxxxxxxxxxxxxx\n"
                    ")x\" + bbbbbb);",
                    getGoogleStyleWithColumns(20)));
 }
@@ -6073,8 +7067,14 @@
 }
 
 TEST_F(FormatTest, DoesNotTryToParseUDLiteralsInPreCpp11Code) {
+  FormatStyle Style = getLLVMStyle();
+  Style.Standard = FormatStyle::LS_Cpp03;
   EXPECT_EQ("#define x(_a) printf(\"foo\" _a);",
-            format("#define x(_a) printf(\"foo\"_a);", getLLVMStyle()));
+            format("#define x(_a) printf(\"foo\"_a);", Style));
+}
+
+TEST_F(FormatTest, UnderstandsCpp1y) {
+  verifyFormat("int bi{1'000'000};");
 }
 
 TEST_F(FormatTest, BreakStringLiteralsBeforeUnbreakableTokenSequence) {
@@ -6172,14 +7172,16 @@
   verifyFormat("void f() {\n"
                "  return g() {}\n"
                "  void h() {}");
-  verifyFormat("if (foo)\n"
-               "  return { forgot_closing_brace();\n"
-               "test();");
-  verifyFormat("int a[] = { void forgot_closing_brace() { f();\n"
+  verifyFormat("int a[] = {void forgot_closing_brace(){f();\n"
                "g();\n"
                "}");
 }
 
+TEST_F(FormatTest, DoNotPrematurelyEndUnwrappedLineForReturnStatements) {
+  verifyFormat(
+      "void f() { return C{param1, param2}.SomeCall(param1, param2); }");
+}
+
 TEST_F(FormatTest, FormatsClosingBracesInEmptyNestedBlocks) {
   verifyFormat("class X {\n"
                "  void f() {\n"
@@ -6191,6 +7193,7 @@
 TEST_F(FormatTest, ConfigurableIndentWidth) {
   FormatStyle EightIndent = getLLVMStyleWithColumns(18);
   EightIndent.IndentWidth = 8;
+  EightIndent.ContinuationIndentWidth = 8;
   verifyFormat("void f() {\n"
                "        someFunction();\n"
                "        if (true) {\n"
@@ -6205,8 +7208,7 @@
                EightIndent);
   verifyFormat("int x[] = {\n"
                "        call(),\n"
-               "        call(),\n"
-               "};",
+               "        call()};",
                EightIndent);
 }
 
@@ -6320,17 +7322,17 @@
                    Tab));
 
   Tab.UseTab = FormatStyle::UT_ForIndentation;
-  verifyFormat("T t[] = {\n"
-               "\taaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
-               "\taaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
-               "\taaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
-               "\taaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
-               "\taaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
-               "\taaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+  verifyFormat("{\n"
+               "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n"
+               "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n"
+               "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n"
+               "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n"
+               "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n"
+               "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n"
                "};",
                Tab);
   verifyFormat("enum A {\n"
-               "\ta1,\n"
+               "\ta1, // Force multiple lines\n"
                "\ta2,\n"
                "\ta3\n"
                "};",
@@ -6500,9 +7502,9 @@
                    getLLVMStyle()));
 }
 
-TEST_F(FormatTest, ConfigurableSpaceAfterControlStatementKeyword) {
+TEST_F(FormatTest, ConfigurableSpaceBeforeParens) {
   FormatStyle NoSpace = getLLVMStyle();
-  NoSpace.SpaceAfterControlStatementKeyword = false;
+  NoSpace.SpaceBeforeParens = FormatStyle::SBPO_Never;
 
   verifyFormat("while(true)\n"
                "  continue;", NoSpace);
@@ -6519,6 +7521,42 @@
                "default:\n"
                "  break;\n"
                "}", NoSpace);
+
+  FormatStyle Space = getLLVMStyle();
+  Space.SpaceBeforeParens = FormatStyle::SBPO_Always;
+
+  verifyFormat("int f ();", Space);
+  verifyFormat("void f (int a, T b) {\n"
+               "  while (true)\n"
+               "    continue;\n"
+               "}",
+               Space);
+  verifyFormat("if (true)\n"
+               "  f ();\n"
+               "else if (true)\n"
+               "  f ();",
+               Space);
+  verifyFormat("do {\n"
+               "  do_something ();\n"
+               "} while (something ());",
+               Space);
+  verifyFormat("switch (x) {\n"
+               "default:\n"
+               "  break;\n"
+               "}",
+               Space);
+  verifyFormat("A::A () : a (1) {}", Space);
+  verifyFormat("void f () __attribute__ ((asdf));", Space);
+  verifyFormat("*(&a + 1);\n"
+               "&((&a)[1]);\n"
+               "a[(b + c) * d];\n"
+               "(((a + 1) * 2) + 3) * 4;",
+               Space);
+  verifyFormat("#define A(x) x", Space);
+  verifyFormat("#define A (x) x", Space);
+  verifyFormat("#if defined(x)\n"
+               "#endif",
+               Space);
 }
 
 TEST_F(FormatTest, ConfigurableSpacesInParentheses) {
@@ -6608,10 +7646,7 @@
                "      b();\n"
                "    }\n"
                "  }\n"
-               "  void g()\n"
-               "  {\n"
-               "    return;\n"
-               "  }\n"
+               "  void g() { return; }\n"
                "}\n"
                "}",
                BreakBeforeBrace);
@@ -6629,13 +7664,40 @@
                "      b();\n"
                "    }\n"
                "  }\n"
-               "  void g()\n"
-               "  {\n"
-               "    return;\n"
-               "  }\n"
+               "  void g() { return; }\n"
                "}\n"
                "}",
                BreakBeforeBrace);
+
+  verifyFormat("#ifdef _DEBUG\n"
+               "int foo(int i = 0)\n"
+               "#else\n"
+               "int foo(int i = 5)\n"
+               "#endif\n"
+               "{\n"
+               "  return i;\n"
+               "}",
+               BreakBeforeBrace);
+
+  verifyFormat("void foo() {}\n"
+               "void bar()\n"
+               "#ifdef _DEBUG\n"
+               "{\n"
+               "  foo();\n"
+               "}\n"
+               "#else\n"
+               "{\n"
+               "}\n"
+               "#endif",
+               BreakBeforeBrace);
+
+  verifyFormat("void foobar() { int i = 5; }\n"
+               "#ifdef _DEBUG\n"
+               "void bar() {}\n"
+               "#else\n"
+               "void bar() { foobar(); }\n"
+               "#endif",
+               BreakBeforeBrace);
 }
 
 TEST_F(FormatTest, AllmanBraceBreaking) {
@@ -6653,10 +7715,7 @@
                "      b();\n"
                "    }\n"
                "  }\n"
-               "  void g()\n"
-               "  {\n"
-               "    return;\n"
-               "  }\n"
+               "  void g() { return; }\n"
                "}\n"
                "}",
                BreakBeforeBrace);
@@ -6720,6 +7779,77 @@
                "  Y = 0,\n"
                "}\n",
                BreakBeforeBrace);
+  verifyFormat("enum X\n"
+               "{\n"
+               "  Y = 0\n"
+               "}\n",
+               BreakBeforeBrace);
+
+  verifyFormat("@interface BSApplicationController ()\n"
+               "{\n"
+               "@private\n"
+               "  id _extraIvar;\n"
+               "}\n"
+               "@end\n",
+               BreakBeforeBrace);
+
+  verifyFormat("#ifdef _DEBUG\n"
+               "int foo(int i = 0)\n"
+               "#else\n"
+               "int foo(int i = 5)\n"
+               "#endif\n"
+               "{\n"
+               "  return i;\n"
+               "}",
+               BreakBeforeBrace);
+
+  verifyFormat("void foo() {}\n"
+               "void bar()\n"
+               "#ifdef _DEBUG\n"
+               "{\n"
+               "  foo();\n"
+               "}\n"
+               "#else\n"
+               "{\n"
+               "}\n"
+               "#endif",
+               BreakBeforeBrace);
+
+  verifyFormat("void foobar() { int i = 5; }\n"
+               "#ifdef _DEBUG\n"
+               "void bar() {}\n"
+               "#else\n"
+               "void bar() { foobar(); }\n"
+               "#endif",
+               BreakBeforeBrace);
+
+  // This shouldn't affect ObjC blocks..
+  verifyFormat("[self doSomeThingWithACompletionHandler:^{\n"
+               "    // ...\n"
+               "    int i;\n"
+               "}];",
+               BreakBeforeBrace);
+  verifyFormat("void (^block)(void) = ^{\n"
+               "    // ...\n"
+               "    int i;\n"
+               "};",
+               BreakBeforeBrace);
+  // .. or dict literals.
+  verifyFormat("void f()\n"
+               "{\n"
+               "  [object someMethod:@{ @\"a\" : @\"b\" }];\n"
+               "}",
+               BreakBeforeBrace);
+
+  BreakBeforeBrace.ColumnLimit = 19;
+  verifyFormat("void f() { int i; }", BreakBeforeBrace);
+  BreakBeforeBrace.ColumnLimit = 18;
+  verifyFormat("void f()\n"
+               "{\n"
+               "  int i;\n"
+               "}",
+               BreakBeforeBrace);
+  BreakBeforeBrace.ColumnLimit = 80;
 
   FormatStyle BreakBeforeBraceShortIfs = BreakBeforeBrace;
   BreakBeforeBraceShortIfs.AllowShortIfStatementsOnASingleLine = true;
@@ -6747,11 +7877,133 @@
                BreakBeforeBraceShortIfs);
 }
 
+TEST_F(FormatTest, GNUBraceBreaking) {
+  FormatStyle GNUBraceStyle = getLLVMStyle();
+  GNUBraceStyle.BreakBeforeBraces = FormatStyle::BS_GNU;
+  verifyFormat("namespace a\n"
+               "{\n"
+               "class A\n"
+               "{\n"
+               "  void f()\n"
+               "  {\n"
+               "    int a;\n"
+               "    {\n"
+               "      int b;\n"
+               "    }\n"
+               "    if (true)\n"
+               "      {\n"
+               "        a();\n"
+               "        b();\n"
+               "      }\n"
+               "  }\n"
+               "  void g() { return; }\n"
+               "}\n"
+               "}",
+               GNUBraceStyle);
+
+  verifyFormat("void f()\n"
+               "{\n"
+               "  if (true)\n"
+               "    {\n"
+               "      a();\n"
+               "    }\n"
+               "  else if (false)\n"
+               "    {\n"
+               "      b();\n"
+               "    }\n"
+               "  else\n"
+               "    {\n"
+               "      c();\n"
+               "    }\n"
+               "}\n",
+               GNUBraceStyle);
+
+  verifyFormat("void f()\n"
+               "{\n"
+               "  for (int i = 0; i < 10; ++i)\n"
+               "    {\n"
+               "      a();\n"
+               "    }\n"
+               "  while (false)\n"
+               "    {\n"
+               "      b();\n"
+               "    }\n"
+               "  do\n"
+               "    {\n"
+               "      c();\n"
+               "    }\n"
+               "  while (false);\n"
+               "}\n",
+               GNUBraceStyle);
+
+  verifyFormat("void f(int a)\n"
+               "{\n"
+               "  switch (a)\n"
+               "    {\n"
+               "    case 0:\n"
+               "      break;\n"
+               "    case 1:\n"
+               "      {\n"
+               "        break;\n"
+               "      }\n"
+               "    case 2:\n"
+               "      {\n"
+               "      }\n"
+               "      break;\n"
+               "    default:\n"
+               "      break;\n"
+               "    }\n"
+               "}\n",
+               GNUBraceStyle);
+
+  verifyFormat("enum X\n"
+               "{\n"
+               "  Y = 0,\n"
+               "}\n",
+               GNUBraceStyle);
+
+  verifyFormat("@interface BSApplicationController ()\n"
+               "{\n"
+               "@private\n"
+               "  id _extraIvar;\n"
+               "}\n"
+               "@end\n",
+               GNUBraceStyle);
+
+  verifyFormat("#ifdef _DEBUG\n"
+               "int foo(int i = 0)\n"
+               "#else\n"
+               "int foo(int i = 5)\n"
+               "#endif\n"
+               "{\n"
+               "  return i;\n"
+               "}",
+               GNUBraceStyle);
+
+  verifyFormat("void foo() {}\n"
+               "void bar()\n"
+               "#ifdef _DEBUG\n"
+               "{\n"
+               "  foo();\n"
+               "}\n"
+               "#else\n"
+               "{\n"
+               "}\n"
+               "#endif",
+               GNUBraceStyle);
+
+  verifyFormat("void foobar() { int i = 5; }\n"
+               "#ifdef _DEBUG\n"
+               "void bar() {}\n"
+               "#else\n"
+               "void bar() { foobar(); }\n"
+               "#endif",
+               GNUBraceStyle);
+}
 TEST_F(FormatTest, CatchExceptionReferenceBinding) {
   verifyFormat("void f() {\n"
                "  try {\n"
-               "  }\n"
-               "  catch (const Exception &e) {\n"
+               "  } catch (const Exception &e) {\n"
                "  }\n"
                "}\n",
                getLLVMStyle());
@@ -6760,48 +8012,102 @@
 TEST_F(FormatTest, UnderstandsPragmas) {
   verifyFormat("#pragma omp reduction(| : var)");
   verifyFormat("#pragma omp reduction(+ : var)");
+
+  EXPECT_EQ("#pragma mark Any non-hyphenated or hyphenated string "
+            "(including parentheses).",
+            format("#pragma    mark   Any non-hyphenated or hyphenated string "
+                   "(including parentheses)."));
 }
 
-bool allStylesEqual(ArrayRef<FormatStyle> Styles) {
-  for (size_t i = 1; i < Styles.size(); ++i)
-    if (!(Styles[0] == Styles[i]))
-      return false;
-  return true;
-}
+#define EXPECT_ALL_STYLES_EQUAL(Styles)                                        \
+  for (size_t i = 1; i < Styles.size(); ++i)                                   \
+    EXPECT_EQ(Styles[0], Styles[i]) << "Style #" << i << " of "                \
+                                    << Styles.size()                           \
+                                    << " differs from Style #0"
 
 TEST_F(FormatTest, GetsPredefinedStyleByName) {
-  FormatStyle Styles[3];
+  SmallVector<FormatStyle, 3> Styles;
+  Styles.resize(3);
 
   Styles[0] = getLLVMStyle();
-  EXPECT_TRUE(getPredefinedStyle("LLVM", &Styles[1]));
-  EXPECT_TRUE(getPredefinedStyle("lLvM", &Styles[2]));
-  EXPECT_TRUE(allStylesEqual(Styles));
+  EXPECT_TRUE(getPredefinedStyle("LLVM", FormatStyle::LK_Cpp, &Styles[1]));
+  EXPECT_TRUE(getPredefinedStyle("lLvM", FormatStyle::LK_Cpp, &Styles[2]));
+  EXPECT_ALL_STYLES_EQUAL(Styles);
 
   Styles[0] = getGoogleStyle();
-  EXPECT_TRUE(getPredefinedStyle("Google", &Styles[1]));
-  EXPECT_TRUE(getPredefinedStyle("gOOgle", &Styles[2]));
-  EXPECT_TRUE(allStylesEqual(Styles));
+  EXPECT_TRUE(getPredefinedStyle("Google", FormatStyle::LK_Cpp, &Styles[1]));
+  EXPECT_TRUE(getPredefinedStyle("gOOgle", FormatStyle::LK_Cpp, &Styles[2]));
+  EXPECT_ALL_STYLES_EQUAL(Styles);
 
-  Styles[0] = getChromiumStyle();
-  EXPECT_TRUE(getPredefinedStyle("Chromium", &Styles[1]));
-  EXPECT_TRUE(getPredefinedStyle("cHRoMiUM", &Styles[2]));
-  EXPECT_TRUE(allStylesEqual(Styles));
+  Styles[0] = getGoogleStyle(FormatStyle::LK_JavaScript);
+  EXPECT_TRUE(
+      getPredefinedStyle("Google", FormatStyle::LK_JavaScript, &Styles[1]));
+  EXPECT_TRUE(
+      getPredefinedStyle("gOOgle", FormatStyle::LK_JavaScript, &Styles[2]));
+  EXPECT_ALL_STYLES_EQUAL(Styles);
+
+  Styles[0] = getChromiumStyle(FormatStyle::LK_Cpp);
+  EXPECT_TRUE(getPredefinedStyle("Chromium", FormatStyle::LK_Cpp, &Styles[1]));
+  EXPECT_TRUE(getPredefinedStyle("cHRoMiUM", FormatStyle::LK_Cpp, &Styles[2]));
+  EXPECT_ALL_STYLES_EQUAL(Styles);
 
   Styles[0] = getMozillaStyle();
-  EXPECT_TRUE(getPredefinedStyle("Mozilla", &Styles[1]));
-  EXPECT_TRUE(getPredefinedStyle("moZILla", &Styles[2]));
-  EXPECT_TRUE(allStylesEqual(Styles));
+  EXPECT_TRUE(getPredefinedStyle("Mozilla", FormatStyle::LK_Cpp, &Styles[1]));
+  EXPECT_TRUE(getPredefinedStyle("moZILla", FormatStyle::LK_Cpp, &Styles[2]));
+  EXPECT_ALL_STYLES_EQUAL(Styles);
 
   Styles[0] = getWebKitStyle();
-  EXPECT_TRUE(getPredefinedStyle("WebKit", &Styles[1]));
-  EXPECT_TRUE(getPredefinedStyle("wEbKit", &Styles[2]));
-  EXPECT_TRUE(allStylesEqual(Styles));
+  EXPECT_TRUE(getPredefinedStyle("WebKit", FormatStyle::LK_Cpp, &Styles[1]));
+  EXPECT_TRUE(getPredefinedStyle("wEbKit", FormatStyle::LK_Cpp, &Styles[2]));
+  EXPECT_ALL_STYLES_EQUAL(Styles);
 
-  EXPECT_FALSE(getPredefinedStyle("qwerty", &Styles[0]));
+  Styles[0] = getGNUStyle();
+  EXPECT_TRUE(getPredefinedStyle("GNU", FormatStyle::LK_Cpp, &Styles[1]));
+  EXPECT_TRUE(getPredefinedStyle("gnU", FormatStyle::LK_Cpp, &Styles[2]));
+  EXPECT_ALL_STYLES_EQUAL(Styles);
+
+  EXPECT_FALSE(getPredefinedStyle("qwerty", FormatStyle::LK_Cpp, &Styles[0]));
 }
 
-TEST_F(FormatTest, ParsesConfiguration) {
-  FormatStyle Style = {};
+TEST_F(FormatTest, GetsCorrectBasedOnStyle) {
+  SmallVector<FormatStyle, 8> Styles;
+  Styles.resize(2);
+
+  Styles[0] = getGoogleStyle();
+  Styles[1] = getLLVMStyle();
+  EXPECT_EQ(0, parseConfiguration("BasedOnStyle: Google", &Styles[1]).value());
+  EXPECT_ALL_STYLES_EQUAL(Styles);
+
+  Styles.resize(5);
+  Styles[0] = getGoogleStyle(FormatStyle::LK_JavaScript);
+  Styles[1] = getLLVMStyle();
+  Styles[1].Language = FormatStyle::LK_JavaScript;
+  EXPECT_EQ(0, parseConfiguration("BasedOnStyle: Google", &Styles[1]).value());
+
+  Styles[2] = getLLVMStyle();
+  Styles[2].Language = FormatStyle::LK_JavaScript;
+  EXPECT_EQ(0, parseConfiguration("Language: JavaScript\n"
+                                  "BasedOnStyle: Google",
+                                  &Styles[2]).value());
+
+  Styles[3] = getLLVMStyle();
+  Styles[3].Language = FormatStyle::LK_JavaScript;
+  EXPECT_EQ(0, parseConfiguration("BasedOnStyle: Google\n"
+                                  "Language: JavaScript",
+                                  &Styles[3]).value());
+
+  Styles[4] = getLLVMStyle();
+  Styles[4].Language = FormatStyle::LK_JavaScript;
+  EXPECT_EQ(0, parseConfiguration("---\n"
+                                  "BasedOnStyle: LLVM\n"
+                                  "IndentWidth: 123\n"
+                                  "---\n"
+                                  "BasedOnStyle: Google\n"
+                                  "Language: JavaScript",
+                                  &Styles[4]).value());
+  EXPECT_ALL_STYLES_EQUAL(Styles);
+}
+
 #define CHECK_PARSE(TEXT, FIELD, VALUE)                                        \
   EXPECT_NE(VALUE, Style.FIELD);                                               \
   EXPECT_EQ(0, parseConfiguration(TEXT, &Style).value());                      \
@@ -6814,9 +8120,13 @@
   EXPECT_EQ(0, parseConfiguration(#FIELD ": false", &Style).value());          \
   EXPECT_FALSE(Style.FIELD);
 
+TEST_F(FormatTest, ParsesConfiguration) {
+  FormatStyle Style = {};
+  Style.Language = FormatStyle::LK_Cpp;
   CHECK_PARSE_BOOL(AlignEscapedNewlinesLeft);
   CHECK_PARSE_BOOL(AlignTrailingComments);
   CHECK_PARSE_BOOL(AllowAllParametersOfDeclarationOnNextLine);
+  CHECK_PARSE_BOOL(AllowShortBlocksOnASingleLine);
   CHECK_PARSE_BOOL(AllowShortIfStatementsOnASingleLine);
   CHECK_PARSE_BOOL(AllowShortLoopsOnASingleLine);
   CHECK_PARSE_BOOL(AlwaysBreakTemplateDeclarations);
@@ -6825,17 +8135,18 @@
   CHECK_PARSE_BOOL(BreakBeforeTernaryOperators);
   CHECK_PARSE_BOOL(BreakConstructorInitializersBeforeComma);
   CHECK_PARSE_BOOL(ConstructorInitializerAllOnOneLineOrOnePerLine);
-  CHECK_PARSE_BOOL(DerivePointerBinding);
+  CHECK_PARSE_BOOL(DerivePointerAlignment);
   CHECK_PARSE_BOOL(IndentCaseLabels);
+  CHECK_PARSE_BOOL(IndentWrappedFunctionNames);
+  CHECK_PARSE_BOOL(KeepEmptyLinesAtTheStartOfBlocks);
+  CHECK_PARSE_BOOL(ObjCSpaceAfterProperty);
   CHECK_PARSE_BOOL(ObjCSpaceBeforeProtocolList);
-  CHECK_PARSE_BOOL(PointerBindsToType);
   CHECK_PARSE_BOOL(Cpp11BracedListStyle);
-  CHECK_PARSE_BOOL(IndentFunctionDeclarationAfterType);
   CHECK_PARSE_BOOL(SpacesInParentheses);
   CHECK_PARSE_BOOL(SpacesInAngles);
   CHECK_PARSE_BOOL(SpaceInEmptyParentheses);
+  CHECK_PARSE_BOOL(SpacesInContainerLiterals);
   CHECK_PARSE_BOOL(SpacesInCStyleCastParentheses);
-  CHECK_PARSE_BOOL(SpaceAfterControlStatementKeyword);
   CHECK_PARSE_BOOL(SpaceBeforeAssignmentOperators);
 
   CHECK_PARSE("AccessModifierOffset: -1234", AccessModifierOffset, -1234);
@@ -6853,6 +8164,11 @@
   CHECK_PARSE("IndentWidth: 32", IndentWidth, 32u);
   CHECK_PARSE("ContinuationIndentWidth: 11", ContinuationIndentWidth, 11u);
 
+  Style.PointerAlignment = FormatStyle::PAS_Middle;
+  CHECK_PARSE("PointerAlignment: Left", PointerAlignment, FormatStyle::PAS_Left);
+  CHECK_PARSE("PointerAlignment: Right", PointerAlignment, FormatStyle::PAS_Right);
+  CHECK_PARSE("PointerAlignment: Middle", PointerAlignment, FormatStyle::PAS_Middle);
+
   Style.Standard = FormatStyle::LS_Auto;
   CHECK_PARSE("Standard: Cpp03", Standard, FormatStyle::LS_Cpp03);
   CHECK_PARSE("Standard: Cpp11", Standard, FormatStyle::LS_Cpp11);
@@ -6867,6 +8183,31 @@
   CHECK_PARSE("UseTab: ForIndentation", UseTab, FormatStyle::UT_ForIndentation);
   CHECK_PARSE("UseTab: Always", UseTab, FormatStyle::UT_Always);
 
+  Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
+  CHECK_PARSE("AllowShortFunctionsOnASingleLine: false",
+              AllowShortFunctionsOnASingleLine, FormatStyle::SFS_None);
+  CHECK_PARSE("AllowShortFunctionsOnASingleLine: true",
+              AllowShortFunctionsOnASingleLine, FormatStyle::SFS_All);
+  CHECK_PARSE("AllowShortFunctionsOnASingleLine: None",
+              AllowShortFunctionsOnASingleLine, FormatStyle::SFS_None);
+  CHECK_PARSE("AllowShortFunctionsOnASingleLine: Inline",
+              AllowShortFunctionsOnASingleLine, FormatStyle::SFS_Inline);
+  CHECK_PARSE("AllowShortFunctionsOnASingleLine: All",
+              AllowShortFunctionsOnASingleLine, FormatStyle::SFS_All);
+
+  Style.SpaceBeforeParens = FormatStyle::SBPO_Always;
+  CHECK_PARSE("SpaceBeforeParens: Never", SpaceBeforeParens,
+              FormatStyle::SBPO_Never);
+  CHECK_PARSE("SpaceBeforeParens: Always", SpaceBeforeParens,
+              FormatStyle::SBPO_Always);
+  CHECK_PARSE("SpaceBeforeParens: ControlStatements", SpaceBeforeParens,
+              FormatStyle::SBPO_ControlStatements);
+  // For backward compatibility:
+  CHECK_PARSE("SpaceAfterControlStatementKeyword: false", SpaceBeforeParens,
+              FormatStyle::SBPO_Never);
+  CHECK_PARSE("SpaceAfterControlStatementKeyword: true", SpaceBeforeParens,
+              FormatStyle::SBPO_ControlStatements);
+
   Style.ColumnLimit = 123;
   FormatStyle BaseStyle = getLLVMStyle();
   CHECK_PARSE("BasedOnStyle: LLVM", ColumnLimit, BaseStyle.ColumnLimit);
@@ -6879,6 +8220,9 @@
               FormatStyle::BS_Linux);
   CHECK_PARSE("BreakBeforeBraces: Stroustrup", BreakBeforeBraces,
               FormatStyle::BS_Stroustrup);
+  CHECK_PARSE("BreakBeforeBraces: Allman", BreakBeforeBraces,
+              FormatStyle::BS_Allman);
+  CHECK_PARSE("BreakBeforeBraces: GNU", BreakBeforeBraces, FormatStyle::BS_GNU);
 
   Style.NamespaceIndentation = FormatStyle::NI_All;
   CHECK_PARSE("NamespaceIndentation: None", NamespaceIndentation,
@@ -6888,14 +8232,144 @@
   CHECK_PARSE("NamespaceIndentation: All", NamespaceIndentation,
               FormatStyle::NI_All);
 
+  Style.ForEachMacros.clear();
+  std::vector<std::string> BoostForeach;
+  BoostForeach.push_back("BOOST_FOREACH");
+  CHECK_PARSE("ForEachMacros: [BOOST_FOREACH]", ForEachMacros, BoostForeach);
+  std::vector<std::string> BoostAndQForeach;
+  BoostAndQForeach.push_back("BOOST_FOREACH");
+  BoostAndQForeach.push_back("Q_FOREACH");
+  CHECK_PARSE("ForEachMacros: [BOOST_FOREACH, Q_FOREACH]", ForEachMacros,
+              BoostAndQForeach);
+}
+
+TEST_F(FormatTest, ParsesConfigurationWithLanguages) {
+  FormatStyle Style = {};
+  Style.Language = FormatStyle::LK_Cpp;
+  CHECK_PARSE("Language: Cpp\n"
+              "IndentWidth: 12",
+              IndentWidth, 12u);
+  EXPECT_EQ(parseConfiguration("Language: JavaScript\n"
+                               "IndentWidth: 34",
+                               &Style),
+            ParseError::Unsuitable);
+  EXPECT_EQ(12u, Style.IndentWidth);
+  CHECK_PARSE("IndentWidth: 56", IndentWidth, 56u);
+  EXPECT_EQ(FormatStyle::LK_Cpp, Style.Language);
+
+  Style.Language = FormatStyle::LK_JavaScript;
+  CHECK_PARSE("Language: JavaScript\n"
+              "IndentWidth: 12",
+              IndentWidth, 12u);
+  CHECK_PARSE("IndentWidth: 23", IndentWidth, 23u);
+  EXPECT_EQ(parseConfiguration("Language: Cpp\n"
+                               "IndentWidth: 34",
+                               &Style),
+            ParseError::Unsuitable);
+  EXPECT_EQ(23u, Style.IndentWidth);
+  CHECK_PARSE("IndentWidth: 56", IndentWidth, 56u);
+  EXPECT_EQ(FormatStyle::LK_JavaScript, Style.Language);
+
+  CHECK_PARSE("BasedOnStyle: LLVM\n"
+              "IndentWidth: 67",
+              IndentWidth, 67u);
+
+  CHECK_PARSE("---\n"
+              "Language: JavaScript\n"
+              "IndentWidth: 12\n"
+              "---\n"
+              "Language: Cpp\n"
+              "IndentWidth: 34\n"
+              "...\n",
+              IndentWidth, 12u);
+
+  Style.Language = FormatStyle::LK_Cpp;
+  CHECK_PARSE("---\n"
+              "Language: JavaScript\n"
+              "IndentWidth: 12\n"
+              "---\n"
+              "Language: Cpp\n"
+              "IndentWidth: 34\n"
+              "...\n",
+              IndentWidth, 34u);
+  CHECK_PARSE("---\n"
+              "IndentWidth: 78\n"
+              "---\n"
+              "Language: JavaScript\n"
+              "IndentWidth: 56\n"
+              "...\n",
+              IndentWidth, 78u);
+
+  Style.ColumnLimit = 123;
+  Style.IndentWidth = 234;
+  Style.BreakBeforeBraces = FormatStyle::BS_Linux;
+  Style.TabWidth = 345;
+  EXPECT_FALSE(parseConfiguration("---\n"
+                                  "IndentWidth: 456\n"
+                                  "BreakBeforeBraces: Allman\n"
+                                  "---\n"
+                                  "Language: JavaScript\n"
+                                  "IndentWidth: 111\n"
+                                  "TabWidth: 111\n"
+                                  "---\n"
+                                  "Language: Cpp\n"
+                                  "BreakBeforeBraces: Stroustrup\n"
+                                  "TabWidth: 789\n"
+                                  "...\n",
+                                  &Style));
+  EXPECT_EQ(123u, Style.ColumnLimit);
+  EXPECT_EQ(456u, Style.IndentWidth);
+  EXPECT_EQ(FormatStyle::BS_Stroustrup, Style.BreakBeforeBraces);
+  EXPECT_EQ(789u, Style.TabWidth);
+
+  EXPECT_EQ(parseConfiguration("---\n"
+                               "Language: JavaScript\n"
+                               "IndentWidth: 56\n"
+                               "---\n"
+                               "IndentWidth: 78\n"
+                               "...\n",
+                               &Style),
+            ParseError::Error);
+  EXPECT_EQ(parseConfiguration("---\n"
+                               "Language: JavaScript\n"
+                               "IndentWidth: 56\n"
+                               "---\n"
+                               "Language: JavaScript\n"
+                               "IndentWidth: 78\n"
+                               "...\n",
+                               &Style),
+            ParseError::Error);
+
+  EXPECT_EQ(FormatStyle::LK_Cpp, Style.Language);
+}
+
 #undef CHECK_PARSE
 #undef CHECK_PARSE_BOOL
+
+TEST_F(FormatTest, UsesLanguageForBasedOnStyle) {
+  FormatStyle Style = {};
+  Style.Language = FormatStyle::LK_JavaScript;
+  Style.BreakBeforeTernaryOperators = true;
+  EXPECT_EQ(0, parseConfiguration("BasedOnStyle: Google", &Style).value());
+  EXPECT_FALSE(Style.BreakBeforeTernaryOperators);
+
+  Style.BreakBeforeTernaryOperators = true;
+  EXPECT_EQ(0, parseConfiguration("---\n"
+              "BasedOnStyle: Google\n"
+              "---\n"
+              "Language: JavaScript\n"
+              "IndentWidth: 76\n"
+              "...\n", &Style).value());
+  EXPECT_FALSE(Style.BreakBeforeTernaryOperators);
+  EXPECT_EQ(76u, Style.IndentWidth);
+  EXPECT_EQ(FormatStyle::LK_JavaScript, Style.Language);
 }
 
 TEST_F(FormatTest, ConfigurationRoundTripTest) {
   FormatStyle Style = getLLVMStyle();
   std::string YAML = configurationAsText(Style);
   FormatStyle ParsedStyle = {};
+  ParsedStyle.Language = FormatStyle::LK_Cpp;
   EXPECT_EQ(0, parseConfiguration(YAML, &ParsedStyle).value());
   EXPECT_EQ(Style, ParsedStyle);
 }
@@ -6938,6 +8412,16 @@
 }
 
 TEST_F(FormatTest, SplitsUTF8Strings) {
+  // Non-printable characters' width is currently considered to be the length in
+  // bytes in UTF8. The characters can be displayed in very different manner
+  // (zero-width, single width with a substitution glyph, expanded to their code
+  // (e.g. "<8d>"), so there's no single correct way to handle them.
+  EXPECT_EQ("\"aaaaÄ\"\n"
+            "\"\xc2\x8d\";",
+            format("\"aaaaÄ\xc2\x8d\";", getLLVMStyleWithColumns(10)));
+  EXPECT_EQ("\"aaaaaaaÄ\"\n"
+            "\"\xc2\x8d\";",
+            format("\"aaaaaaaÄ\xc2\x8d\";", getLLVMStyleWithColumns(10)));
   EXPECT_EQ(
       "\"Однажды, в \"\n"
       "\"студёную \"\n"
@@ -6971,6 +8455,8 @@
 }
 
 TEST_F(FormatTest, SplitsUTF8LineComments) {
+  EXPECT_EQ("// aaaaÄ\xc2\x8d",
+            format("// aaaaÄ\xc2\x8d", getLLVMStyleWithColumns(10)));
   EXPECT_EQ("// Я из лесу\n"
             "// вышел; был\n"
             "// сильный\n"
@@ -7041,7 +8527,38 @@
                "    , b(b)\n"
                "    , c(c) {}",
                Style);
+  verifyFormat("SomeClass::Constructor()\n"
+               "    : a(a) {}",
+               Style);
 
+  Style.ColumnLimit = 0;
+  verifyFormat("SomeClass::Constructor()\n"
+               "    : a(a) {}",
+               Style);
+  verifyFormat("SomeClass::Constructor()\n"
+               "    : a(a)\n"
+               "    , b(b)\n"
+               "    , c(c) {}",
+               Style);
+  verifyFormat("SomeClass::Constructor()\n"
+               "    : a(a) {\n"
+               "  foo();\n"
+               "  bar();\n"
+               "}",
+               Style);
+
+  Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
+  verifyFormat("SomeClass::Constructor()\n"
+               "    : a(a)\n"
+               "    , b(b)\n"
+               "    , c(c) {\n}",
+               Style);
+  verifyFormat("SomeClass::Constructor()\n"
+               "    : a(a) {\n}",
+               Style);
+
+  Style.ColumnLimit = 80;
+  Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All;
   Style.ConstructorInitializerIndentWidth = 2;
   verifyFormat("SomeClass::Constructor()\n"
                "  : a(a)\n"
@@ -7058,6 +8575,10 @@
 
   Style.ConstructorInitializerAllOnOneLineOrOnePerLine = true;
   Style.ConstructorInitializerIndentWidth = 4;
+  verifyFormat("SomeClass::Constructor() : aaaaaaaa(aaaaaaaa) {}", Style);
+  verifyFormat(
+      "SomeClass::Constructor() : aaaaa(aaaaa), aaaaa(aaaaa), aaaaa(aaaaa)\n",
+      Style);
   verifyFormat(
       "SomeClass::Constructor()\n"
       "    : aaaaaaaa(aaaaaaaa), aaaaaaaa(aaaaaaaa), aaaaaaaa(aaaaaaaa) {}",
@@ -7115,13 +8636,41 @@
           "}",
           Style));
 
+  // Allow functions on a single line.
+  verifyFormat("void f() { return; }", Style);
+
   // Constructor initializers are formatted one per line with the "," on the
   // new line.
   verifyFormat("Constructor()\n"
                "    : aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaa)\n"
                "    , aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaa, // break\n"
                "                               aaaaaaaaaaaaaa)\n"
-               "    , aaaaaaaaaaaaaaaaaaaaaaa()\n{\n}",
+               "    , aaaaaaaaaaaaaaaaaaaaaaa()\n"
+               "{\n"
+               "}",
+               Style);
+  verifyFormat("SomeClass::Constructor()\n"
+               "    : a(a)\n"
+               "{\n"
+               "}",
+               Style);
+  EXPECT_EQ("SomeClass::Constructor()\n"
+            "    : a(a)\n"
+            "{\n"
+            "}",
+            format("SomeClass::Constructor():a(a){}", Style));
+  verifyFormat("SomeClass::Constructor()\n"
+               "    : a(a)\n"
+               "    , b(b)\n"
+               "    , c(c)\n"
+               "{\n"
+               "}", Style);
+  verifyFormat("SomeClass::Constructor()\n"
+               "    : a(a)\n"
+               "{\n"
+               "    foo();\n"
+               "    bar();\n"
+               "}",
                Style);
 
   // Access specifiers should be aligned left.
@@ -7157,34 +8706,53 @@
             format("#define aNumber \\\n"
                    " 10",
                    Style));
-}
 
-TEST_F(FormatTest, FormatsProtocolBufferDefinitions) {
-  // It seems that clang-format can format protocol buffer definitions
-  // (see https://code.google.com/p/protobuf/).
-  verifyFormat("message SomeMessage {\n"
-               "  required int32 field1 = 1;\n"
-               "  optional string field2 = 2 [default = \"2\"]\n"
-               "}");
+  // Keep empty and one-element array literals on a single line.
+  EXPECT_EQ("NSArray* a = [[NSArray alloc] initWithArray:@[]\n"
+            "                                  copyItems:YES];",
+            format("NSArray*a=[[NSArray alloc] initWithArray:@[]\n"
+                   "copyItems:YES];",
+                   Style));
+  EXPECT_EQ("NSArray* a = [[NSArray alloc] initWithArray:@[ @\"a\" ]\n"
+            "                                  copyItems:YES];",
+            format("NSArray*a=[[NSArray alloc]initWithArray:@[ @\"a\" ]\n"
+                   "             copyItems:YES];",
+                   Style));
+  // FIXME: This does not seem right, there should be more indentation before
+  // the array literal's entries. Nested blocks have the same problem.
+  EXPECT_EQ("NSArray* a = [[NSArray alloc] initWithArray:@[\n"
+            "    @\"a\",\n"
+            "    @\"a\"\n"
+            "]\n"
+            "                                  copyItems:YES];",
+            format("NSArray* a = [[NSArray alloc] initWithArray:@[\n"
+                   "     @\"a\",\n"
+                   "     @\"a\"\n"
+                   "     ]\n"
+                   "       copyItems:YES];",
+                   Style));
+  EXPECT_EQ(
+      "NSArray* a = [[NSArray alloc] initWithArray:@[ @\"a\", @\"a\" ]\n"
+      "                                  copyItems:YES];",
+      format("NSArray* a = [[NSArray alloc] initWithArray:@[ @\"a\", @\"a\" ]\n"
+             "   copyItems:YES];",
+             Style));
+
+  verifyFormat("[self.a b:c c:d];", Style);
+  EXPECT_EQ("[self.a b:c\n"
+            "        c:d];",
+            format("[self.a b:c\n"
+                   "c:d];",
+                   Style));
 }
 
 TEST_F(FormatTest, FormatsLambdas) {
-  verifyFormat("int c = [b]() mutable {\n"
-               "  return [&b] { return b++; }();\n"
-               "}();\n");
-  verifyFormat("int c = [&] {\n"
-               "  [=] { return b++; }();\n"
-               "}();\n");
-  verifyFormat("int c = [&, &a, a] {\n"
-               "  [=, c, &d] { return b++; }();\n"
-               "}();\n");
-  verifyFormat("int c = [&a, &a, a] {\n"
-               "  [=, a, b, &c] { return b++; }();\n"
-               "}();\n");
-  verifyFormat("auto c = { [&a, &a, a] {\n"
-               "  [=, a, b, &c] { return b++; }();\n"
-               "} }\n");
-  verifyFormat("auto c = { [&a, &a, a] { [=, a, b, &c] {}(); } }\n");
+  verifyFormat("int c = [b]() mutable { return [&b] { return b++; }(); }();\n");
+  verifyFormat("int c = [&] { [=] { return b++; }(); }();\n");
+  verifyFormat("int c = [&, &a, a] { [=, c, &d] { return b++; }(); }();\n");
+  verifyFormat("int c = [&a, &a, a] { [=, a, b, &c] { return b++; }(); }();\n");
+  verifyFormat("auto c = {[&a, &a, a] { [=, a, b, &c] { return b++; }(); }}\n");
+  verifyFormat("auto c = {[&a, &a, a] { [=, a, b, &c] {}(); }}\n");
   verifyFormat("void f() {\n"
                "  other(x.begin(), x.end(), [&](int, int) { return 1; });\n"
                "}\n");
@@ -7193,19 +8761,138 @@
                "        x.end(),   //\n"
                "        [&](int, int) { return 1; });\n"
                "}\n");
+  verifyFormat("SomeFunction([]() { // A cool function...\n"
+               "  return 43;\n"
+               "});");
+  verifyFormat("void f() {\n"
+               "  SomeFunction([](decltype(x), A *a) {});\n"
+               "}");
+  verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
+               "    [](const aaaaaaaaaa &a) { return a; });");
+
+  // Lambdas with return types.
+  verifyFormat("int c = []() -> int { return 2; }();\n");
+  verifyFormat("int c = []() -> vector<int> { return {2}; }();\n");
+  verifyFormat("Foo([]() -> std::vector<int> { return {2}; }());");
+  verifyFormat("auto aaaaaaaa = [](int i, // break for some reason\n"
+               "                   int j) -> int {\n"
+               "  return ffffffffffffffffffffffffffffffffffffffffffff(i * j);\n"
+               "};");
+
+  // Multiple lambdas in the same parentheses change indentation rules.
+  verifyFormat("SomeFunction([]() {\n"
+               "               int i = 42;\n"
+               "               return i;\n"
+               "             },\n"
+               "             []() {\n"
+               "               int j = 43;\n"
+               "               return j;\n"
+               "             });");
+
+  // More complex introducers.
+  verifyFormat("return [i, args...] {};");
 
   // Not lambdas.
-  verifyFormat("constexpr char hello[]{ \"hello\" };");
+  verifyFormat("constexpr char hello[]{\"hello\"};");
   verifyFormat("double &operator[](int i) { return 0; }\n"
                "int i;");
+  verifyFormat("std::unique_ptr<int[]> foo() {}");
+  verifyFormat("int i = a[a][a]->f();");
+  verifyFormat("int i = (*b)[a]->f();");
+
+  // Other corner cases.
+  verifyFormat("void f() {\n"
+               "  bar([]() {} // Did not respect SpacesBeforeTrailingComments\n"
+               "      );\n"
+               "}");
+
+  // Lambdas created through weird macros.
+  verifyFormat("void f() {\n"
+               "  MACRO((const AA &a) { return 1; });\n"
+               "}");
 }
 
 TEST_F(FormatTest, FormatsBlocks) {
+  verifyFormat("int (^Block)(int, int);");
+  verifyFormat("int (^Block1)(int, int) = ^(int i, int j)");
+  verifyFormat("void (^block)(int) = ^(id test) { int i; };");
+  verifyFormat("void (^block)(int) = ^(int test) { int i; };");
+  verifyFormat("void (^block)(int) = ^id(int test) { int i; };");
+  verifyFormat("void (^block)(int) = ^int(int test) { int i; };");
+
+  verifyFormat("foo(^{ bar(); });");
+  verifyFormat("foo(a, ^{ bar(); });");
+
   // FIXME: Make whitespace formatting consistent. Ask a ObjC dev how
   // it would ideally look.
   verifyFormat("[operation setCompletionBlock:^{ [self onOperationDone]; }];");
   verifyFormat("int i = {[operation setCompletionBlock : ^{ [self "
-               "onOperationDone]; }] };");
+               "onOperationDone]; }]};");
+  verifyFormat("[operation setCompletionBlock:^(int *i) { f(); }];");
+  verifyFormat("int a = [operation block:^int(int *i) { return 1; }];");
+  verifyFormat("[myObject doSomethingWith:arg1\n"
+               "                      aaa:^int(int *a) { return 1; }\n"
+               "                      bbb:f(a * bbbbbbbb)];");
+
+  verifyFormat("[operation setCompletionBlock:^{\n"
+               "    [self.delegate newDataAvailable];\n"
+               "}];",
+               getLLVMStyleWithColumns(60));
+  verifyFormat("dispatch_async(_fileIOQueue, ^{\n"
+               "    NSString *path = [self sessionFilePath];\n"
+               "    if (path) {\n"
+               "      // ...\n"
+               "    }\n"
+               "});");
+  verifyFormat("[[SessionService sharedService]\n"
+               "    loadWindowWithCompletionBlock:^(SessionWindow *window) {\n"
+               "        if (window) {\n"
+               "          [self windowDidLoad:window];\n"
+               "        } else {\n"
+               "          [self errorLoadingWindow];\n"
+               "        }\n"
+               "    }];");
+  verifyFormat("void (^largeBlock)(void) = ^{\n"
+               "    // ...\n"
+               "};\n",
+               getLLVMStyleWithColumns(40));
+  verifyFormat("[[SessionService sharedService]\n"
+               "    loadWindowWithCompletionBlock: //\n"
+               "        ^(SessionWindow *window) {\n"
+               "            if (window) {\n"
+               "              [self windowDidLoad:window];\n"
+               "            } else {\n"
+               "              [self errorLoadingWindow];\n"
+               "            }\n"
+               "        }];",
+               getLLVMStyleWithColumns(60));
+  verifyFormat("[myObject doSomethingWith:arg1\n"
+               "    firstBlock:^(Foo *a) {\n"
+               "        // ...\n"
+               "        int i;\n"
+               "    }\n"
+               "    secondBlock:^(Bar *b) {\n"
+               "        // ...\n"
+               "        int i;\n"
+               "    }\n"
+               "    thirdBlock:^Foo(Bar *b) {\n"
+               "        // ...\n"
+               "        int i;\n"
+               "    }];");
+  verifyFormat("[myObject doSomethingWith:arg1\n"
+               "               firstBlock:-1\n"
+               "              secondBlock:^(Bar *b) {\n"
+               "                  // ...\n"
+               "                  int i;\n"
+               "              }];");
+
+  verifyFormat("f(^{\n"
+               "    @autoreleasepool {\n"
+               "      if (a) {\n"
+               "        g();\n"
+               "      }\n"
+               "    }\n"
+               "});");
 }
 
 TEST_F(FormatTest, SupportsCRLF) {
@@ -7299,10 +8986,116 @@
   Spaces.Standard = FormatStyle::LS_Cpp11;
   Spaces.SpacesInAngles = true;
   verifyFormat("A< A< int > >();", Spaces);
-  
+
   Spaces.SpacesInAngles = false;
   verifyFormat("A<A<int>>();", Spaces);
 }
 
+TEST_F(FormatTest, HandleUnbalancedImplicitBracesAcrossPPBranches) {
+  std::string code = "#if A\n"
+                     "#if B\n"
+                     "a.\n"
+                     "#endif\n"
+                     "    a = 1;\n"
+                     "#else\n"
+                     "#endif\n"
+                     "#if C\n"
+                     "#else\n"
+                     "#endif\n";
+  EXPECT_EQ(code, format(code));
+}
+
+TEST_F(FormatTest, HandleConflictMarkers) {
+  // Git/SVN conflict markers.
+  EXPECT_EQ("int a;\n"
+            "void f() {\n"
+            "  callme(some(parameter1,\n"
+            "<<<<<<< text by the vcs\n"
+            "              parameter2),\n"
+            "||||||| text by the vcs\n"
+            "              parameter2),\n"
+            "         parameter3,\n"
+            "======= text by the vcs\n"
+            "              parameter2, parameter3),\n"
+            ">>>>>>> text by the vcs\n"
+            "         otherparameter);\n",
+            format("int a;\n"
+                   "void f() {\n"
+                   "  callme(some(parameter1,\n"
+                   "<<<<<<< text by the vcs\n"
+                   "  parameter2),\n"
+                   "||||||| text by the vcs\n"
+                   "  parameter2),\n"
+                   "  parameter3,\n"
+                   "======= text by the vcs\n"
+                   "  parameter2,\n"
+                   "  parameter3),\n"
+                   ">>>>>>> text by the vcs\n"
+                   "  otherparameter);\n"));
+
+  // Perforce markers.
+  EXPECT_EQ("void f() {\n"
+            "  function(\n"
+            ">>>> text by the vcs\n"
+            "      parameter,\n"
+            "==== text by the vcs\n"
+            "      parameter,\n"
+            "==== text by the vcs\n"
+            "      parameter,\n"
+            "<<<< text by the vcs\n"
+            "      parameter);\n",
+            format("void f() {\n"
+                   "  function(\n"
+                   ">>>> text by the vcs\n"
+                   "  parameter,\n"
+                   "==== text by the vcs\n"
+                   "  parameter,\n"
+                   "==== text by the vcs\n"
+                   "  parameter,\n"
+                   "<<<< text by the vcs\n"
+                   "  parameter);\n"));
+
+  EXPECT_EQ("<<<<<<<\n"
+            "|||||||\n"
+            "=======\n"
+            ">>>>>>>",
+            format("<<<<<<<\n"
+                   "|||||||\n"
+                   "=======\n"
+                   ">>>>>>>"));
+
+  EXPECT_EQ("<<<<<<<\n"
+            "|||||||\n"
+            "int i;\n"
+            "=======\n"
+            ">>>>>>>",
+            format("<<<<<<<\n"
+                   "|||||||\n"
+                   "int i;\n"
+                   "=======\n"
+                   ">>>>>>>"));
+
+  // FIXME: Handle parsing of macros around conflict markers correctly:
+  EXPECT_EQ("#define Macro \\\n"
+            "<<<<<<<\n"
+            "Something \\\n"
+            "|||||||\n"
+            "Else \\\n"
+            "=======\n"
+            "Other \\\n"
+            ">>>>>>>\n"
+            "    End int i;\n",
+            format("#define Macro \\\n"
+                   "<<<<<<<\n"
+                   "  Something \\\n"
+                   "|||||||\n"
+                   "  Else \\\n"
+                   "=======\n"
+                   "  Other \\\n"
+                   ">>>>>>>\n"
+                   "  End\n"
+                   "int i;\n"));
+}
+
 } // end namespace tooling
 } // end namespace clang
diff --git a/unittests/Format/FormatTestJS.cpp b/unittests/Format/FormatTestJS.cpp
new file mode 100644
index 0000000..f8802b8
--- /dev/null
+++ b/unittests/Format/FormatTestJS.cpp
@@ -0,0 +1,332 @@
+//===- unittest/Format/FormatTestJS.cpp - Formatting unit tests for JS ----===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "FormatTestUtils.h"
+#include "clang/Format/Format.h"
+#include "llvm/Support/Debug.h"
+#include "gtest/gtest.h"
+
+#define DEBUG_TYPE "format-test"
+
+namespace clang {
+namespace format {
+
+class FormatTestJS : public ::testing::Test {
+protected:
+  static std::string format(llvm::StringRef Code, unsigned Offset,
+                            unsigned Length, const FormatStyle &Style) {
+    DEBUG(llvm::errs() << "---\n");
+    DEBUG(llvm::errs() << Code << "\n\n");
+    std::vector<tooling::Range> Ranges(1, tooling::Range(Offset, Length));
+    tooling::Replacements Replaces = reformat(Style, Code, Ranges);
+    std::string Result = applyAllReplacements(Code, Replaces);
+    EXPECT_NE("", Result);
+    DEBUG(llvm::errs() << "\n" << Result << "\n\n");
+    return Result;
+  }
+
+  static std::string format(
+      llvm::StringRef Code,
+      const FormatStyle &Style = getGoogleStyle(FormatStyle::LK_JavaScript)) {
+    return format(Code, 0, Code.size(), Style);
+  }
+
+  static FormatStyle getGoogleJSStyleWithColumns(unsigned ColumnLimit) {
+    FormatStyle Style = getGoogleStyle(FormatStyle::LK_JavaScript);
+    Style.ColumnLimit = ColumnLimit;
+    return Style;
+  }
+
+  static void verifyFormat(
+      llvm::StringRef Code,
+      const FormatStyle &Style = getGoogleStyle(FormatStyle::LK_JavaScript)) {
+    EXPECT_EQ(Code.str(), format(test::messUp(Code), Style));
+  }
+};
+
+TEST_F(FormatTestJS, UnderstandsJavaScriptOperators) {
+  verifyFormat("a == = b;");
+  verifyFormat("a != = b;");
+
+  verifyFormat("a === b;");
+  verifyFormat("aaaaaaa ===\n    b;", getGoogleJSStyleWithColumns(10));
+  verifyFormat("a !== b;");
+  verifyFormat("aaaaaaa !==\n    b;", getGoogleJSStyleWithColumns(10));
+  verifyFormat("if (a + b + c +\n"
+               "        d !==\n"
+               "    e + f + g)\n"
+               "  q();",
+               getGoogleJSStyleWithColumns(20));
+
+  verifyFormat("a >> >= b;");
+
+  verifyFormat("a >>> b;");
+  verifyFormat("aaaaaaa >>>\n    b;", getGoogleJSStyleWithColumns(10));
+  verifyFormat("a >>>= b;");
+  verifyFormat("aaaaaaa >>>=\n    b;", getGoogleJSStyleWithColumns(10));
+  verifyFormat("if (a + b + c +\n"
+               "        d >>>\n"
+               "    e + f + g)\n"
+               "  q();",
+               getGoogleJSStyleWithColumns(20));
+  verifyFormat("var x = aaaaaaaaaa ?\n"
+               "            bbbbbb :\n"
+               "            ccc;",
+               getGoogleJSStyleWithColumns(20));
+
+  verifyFormat("var b = a.map((x) => x + 1);");
+}
+
+TEST_F(FormatTestJS, ES6DestructuringAssignment) {
+  verifyFormat("var [a, b, c] = [1, 2, 3];");
+  verifyFormat("var {a, b} = {a: 1, b: 2};");
+}
+
+TEST_F(FormatTestJS, ContainerLiterals) {
+  verifyFormat("return {\n"
+               "  link: function() {\n"
+               "    f();  //\n"
+               "  }\n"
+               "};");
+  verifyFormat("return {\n"
+               "  a: a,\n"
+               "  link: function() {\n"
+               "    f();  //\n"
+               "  }\n"
+               "};");
+  verifyFormat("return {\n"
+               "  a: a,\n"
+               "  link:\n"
+               "      function() {\n"
+               "        f();  //\n"
+               "      },\n"
+               "  link:\n"
+               "      function() {\n"
+               "        f();  //\n"
+               "      }\n"
+               "};");
+}
+
+TEST_F(FormatTestJS, SpacesInContainerLiterals) {
+  verifyFormat("var arr = [1, 2, 3];");
+  verifyFormat("var obj = {a: 1, b: 2, c: 3};");
+
+  verifyFormat("var object_literal_with_long_name = {\n"
+               "  a: 'aaaaaaaaaaaaaaaaaa',\n"
+               "  b: 'bbbbbbbbbbbbbbbbbb'\n"
+               "};");
+
+  verifyFormat("var obj = {a: 1, b: 2, c: 3};",
+               getChromiumStyle(FormatStyle::LK_JavaScript));
+  verifyFormat("someVariable = {'a': [{}]};");
+}
+
+TEST_F(FormatTestJS, SingleQuoteStrings) {
+  verifyFormat("this.function('', true);");
+}
+
+TEST_F(FormatTestJS, GoogScopes) {
+  verifyFormat("goog.scope(function() {\n"
+               "var x = a.b;\n"
+               "var y = c.d;\n"
+               "});  // goog.scope");
+}
+
+TEST_F(FormatTestJS, FormatsFreestandingFunctions) {
+  verifyFormat("function outer1(a, b) {\n"
+               "  function inner1(a, b) { return a; }\n"
+               "  inner1(a, b);\n"
+               "}\n"
+               "function outer2(a, b) {\n"
+               "  function inner2(a, b) { return a; }\n"
+               "  inner2(a, b);\n"
+               "}");
+}
+
+TEST_F(FormatTestJS, FunctionLiterals) {
+  verifyFormat("doFoo(function() { return 1; });");
+  verifyFormat("var func = function() { return 1; };");
+  verifyFormat("return {\n"
+               "  body: {\n"
+               "    setAttribute: function(key, val) { this[key] = val; },\n"
+               "    getAttribute: function(key) { return this[key]; },\n"
+               "    style: {direction: ''}\n"
+               "  }\n"
+               "};");
+  EXPECT_EQ("abc = xyz ? function() { return 1; } : function() { return -1; };",
+            format("abc=xyz?function(){return 1;}:function(){return -1;};"));
+
+  verifyFormat("var closure = goog.bind(\n"
+               "    function() {  // comment\n"
+               "      foo();\n"
+               "      bar();\n"
+               "    },\n"
+               "    this, arg1IsReallyLongAndNeeedsLineBreaks,\n"
+               "    arg3IsReallyLongAndNeeedsLineBreaks);");
+  verifyFormat("var closure = goog.bind(function() {  // comment\n"
+               "  foo();\n"
+               "  bar();\n"
+               "}, this);");
+  verifyFormat("return {\n"
+               "  a: 'E',\n"
+               "  b: function() {\n"
+               "    return function() {\n"
+               "      f();  //\n"
+               "    };\n"
+               "  }\n"
+               "};");
+
+  verifyFormat("var x = {a: function() { return 1; }};",
+               getGoogleJSStyleWithColumns(38));
+  verifyFormat("var x = {\n"
+               "  a: function() { return 1; }\n"
+               "};",
+               getGoogleJSStyleWithColumns(37));
+
+  verifyFormat("return {\n"
+               "  a: function SomeFunction() {\n"
+               "    // ...\n"
+               "    return 1;\n"
+               "  }\n"
+               "};");
+}
+
+TEST_F(FormatTestJS, MultipleFunctionLiterals) {
+  verifyFormat("promise.then(\n"
+               "    function success() {\n"
+               "      doFoo();\n"
+               "      doBar();\n"
+               "    },\n"
+               "    function error() {\n"
+               "      doFoo();\n"
+               "      doBaz();\n"
+               "    },\n"
+               "    []);\n");
+  verifyFormat("promise.then(\n"
+               "    function success() {\n"
+               "      doFoo();\n"
+               "      doBar();\n"
+               "    },\n"
+               "    [],\n"
+               "    function error() {\n"
+               "      doFoo();\n"
+               "      doBaz();\n"
+               "    });\n");
+  // FIXME: Here, we should probably break right after the "(" for consistency.
+  verifyFormat("promise.then([],\n"
+               "             function success() {\n"
+               "               doFoo();\n"
+               "               doBar();\n"
+               "             },\n"
+               "             function error() {\n"
+               "               doFoo();\n"
+               "               doBaz();\n"
+               "             });\n");
+}
+
+TEST_F(FormatTestJS, ReturnStatements) {
+  verifyFormat("function() { return [hello, world]; }");
+}
+
+TEST_F(FormatTestJS, ClosureStyleComments) {
+  verifyFormat("var x = /** @type {foo} */ (bar);");
+}
+
+TEST_F(FormatTestJS, TryCatch) {
+  verifyFormat("try {\n"
+               "  f();\n"
+               "} catch (e) {\n"
+               "  g();\n"
+               "} finally {\n"
+               "  h();\n"
+               "}");
+}
+
+TEST_F(FormatTestJS, StringLiteralConcatenation) {
+  verifyFormat("var literal = 'hello ' +\n"
+               "              'world';");
+}
+
+TEST_F(FormatTestJS, RegexLiteralClassification) {
+  // Regex literals.
+  verifyFormat("var regex = /abc/;");
+  verifyFormat("f(/abc/);");
+  verifyFormat("f(abc, /abc/);");
+  verifyFormat("some_map[/abc/];");
+  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 = a && /abc/.test(y);");
+  verifyFormat("var x = a || /abc/.test(y);");
+  verifyFormat("var x = a + /abc/.search(y);");
+  verifyFormat("var regexs = {/abc/, /abc/};");
+  verifyFormat("return /abc/;");
+
+  // Not regex literals.
+  verifyFormat("var a = a / 2 + b / 3;");
+}
+
+TEST_F(FormatTestJS, RegexLiteralSpecialCharacters) {
+  verifyFormat("var regex = /a*/;");
+  verifyFormat("var regex = /a+/;");
+  verifyFormat("var regex = /a?/;");
+  verifyFormat("var regex = /.a./;");
+  verifyFormat("var regex = /a\\*/;");
+  verifyFormat("var regex = /^a$/;");
+  verifyFormat("var regex = /\\/a/;");
+  verifyFormat("var regex = /(?:x)/;");
+  verifyFormat("var regex = /x(?=y)/;");
+  verifyFormat("var regex = /x(?!y)/;");
+  verifyFormat("var regex = /x|y/;");
+  verifyFormat("var regex = /a{2}/;");
+  verifyFormat("var regex = /a{1,3}/;");
+  verifyFormat("var regex = /[abc]/;");
+  verifyFormat("var regex = /[^abc]/;");
+  verifyFormat("var regex = /[\\b]/;");
+  verifyFormat("var regex = /\\b/;");
+  verifyFormat("var regex = /\\B/;");
+  verifyFormat("var regex = /\\d/;");
+  verifyFormat("var regex = /\\D/;");
+  verifyFormat("var regex = /\\f/;");
+  verifyFormat("var regex = /\\n/;");
+  verifyFormat("var regex = /\\r/;");
+  verifyFormat("var regex = /\\s/;");
+  verifyFormat("var regex = /\\S/;");
+  verifyFormat("var regex = /\\t/;");
+  verifyFormat("var regex = /\\v/;");
+  verifyFormat("var regex = /\\w/;");
+  verifyFormat("var regex = /\\W/;");
+  verifyFormat("var regex = /a(a)\\1/;");
+  verifyFormat("var regex = /\\0/;");
+  verifyFormat("var regex = /\\\\/g;");
+  verifyFormat("var regex = /\\a\\\\/g;");
+  verifyFormat("var regex = /\a\\//g;");
+}
+
+TEST_F(FormatTestJS, RegexLiteralModifiers) {
+  verifyFormat("var regex = /abc/g;");
+  verifyFormat("var regex = /abc/i;");
+  verifyFormat("var regex = /abc/m;");
+  verifyFormat("var regex = /abc/y;");
+}
+
+TEST_F(FormatTestJS, RegexLiteralLength) {
+  verifyFormat("var regex = /aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/;",
+               getGoogleJSStyleWithColumns(60));
+  verifyFormat("var regex =\n"
+               "    /aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/;",
+               getGoogleJSStyleWithColumns(60));
+}
+
+TEST_F(FormatTestJS, RegexLiteralExamples) {
+  verifyFormat("var regex = search.match(/(?:\?|&)times=([^?&]+)/i);");
+}
+
+} // end namespace tooling
+} // end namespace clang
diff --git a/unittests/Format/FormatTestProto.cpp b/unittests/Format/FormatTestProto.cpp
new file mode 100644
index 0000000..bfd5025
--- /dev/null
+++ b/unittests/Format/FormatTestProto.cpp
@@ -0,0 +1,114 @@
+//===- unittest/Format/FormatTestProto.cpp --------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "FormatTestUtils.h"
+#include "clang/Format/Format.h"
+#include "llvm/Support/Debug.h"
+#include "gtest/gtest.h"
+
+#define DEBUG_TYPE "format-test"
+
+namespace clang {
+namespace format {
+
+class FormatTestProto : public ::testing::Test {
+protected:
+  static std::string format(llvm::StringRef Code, unsigned Offset,
+                            unsigned Length, const FormatStyle &Style) {
+    DEBUG(llvm::errs() << "---\n");
+    DEBUG(llvm::errs() << Code << "\n\n");
+    std::vector<tooling::Range> Ranges(1, tooling::Range(Offset, Length));
+    tooling::Replacements Replaces = reformat(Style, Code, Ranges);
+    std::string Result = applyAllReplacements(Code, Replaces);
+    EXPECT_NE("", Result);
+    DEBUG(llvm::errs() << "\n" << Result << "\n\n");
+    return Result;
+  }
+
+  static std::string format(llvm::StringRef Code) {
+    FormatStyle Style = getGoogleStyle(FormatStyle::LK_Proto);
+    Style.ColumnLimit = 60; // To make writing tests easier.
+    return format(Code, 0, Code.size(), Style);
+  }
+
+  static void verifyFormat(llvm::StringRef Code) {
+    EXPECT_EQ(Code.str(), format(test::messUp(Code)));
+  }
+};
+
+TEST_F(FormatTestProto, FormatsMessages) {
+  verifyFormat("message SomeMessage {\n"
+               "  required int32 field1 = 1;\n"
+               "}");
+  verifyFormat("message SomeMessage {\n"
+               "  required .absolute.Reference field1 = 1;\n"
+               "}");
+  verifyFormat("message SomeMessage {\n"
+               "  required int32 field1 = 1;\n"
+               "  optional string field2 = 2 [default = \"2\"]\n"
+               "}");
+
+  verifyFormat("message SomeMessage {\n"
+               "  optional really.really.long.qualified.type.aaa.aaaaaaa\n"
+               "      fiiiiiiiiiiiiiiiiiiiiiiiiield = 1;\n"
+               "  optional\n"
+               "      really.really.long.qualified.type.aaa.aaaaaaa.aaaaaaaa\n"
+               "          another_fiiiiiiiiiiiiiiiiiiiiield = 2;\n"
+               "}");
+}
+
+TEST_F(FormatTestProto, FormatsEnums) {
+  verifyFormat("enum Type {\n"
+               "  UNKNOWN = 0;\n"
+               "  TYPE_A = 1;\n"
+               "  TYPE_B = 2;\n"
+               "};");
+}
+
+TEST_F(FormatTestProto, UnderstandsReturns) {
+  verifyFormat("rpc Search(SearchRequest) returns (SearchResponse);");
+}
+
+TEST_F(FormatTestProto, MessageFieldAttributes) {
+  verifyFormat("optional string test = 1 [default = \"test\"];");
+  verifyFormat("optional bool a = 1 [default = true, deprecated = true];");
+  verifyFormat("optional LongMessageType long_proto_field = 1\n"
+               "    [default = REALLY_REALLY_LONG_CONSTANT_VALUE,\n"
+               "     deprecated = true];");
+  verifyFormat("optional LongMessageType long_proto_field = 1\n"
+               "    [default = REALLY_REALLY_LONG_CONSTANT_VALUE];");
+  verifyFormat("repeated double value = 1\n"
+               "    [(aaaaaaa.aaaaaaaaa) = {aaaaaaaaaaaaaaaaa: AAAAAAAA}];");
+  verifyFormat("repeated double value = 1\n"
+               "    [(aaaaaaa.aaaaaaaaa) = {aaaaaaaaaaaaaaaa: AAAAAAAAAA,\n"
+               "                            bbbbbbbbbbbbbbbb: BBBBBBBBBB}];");
+  verifyFormat("repeated double value = 1\n"
+               "    [(aaaaaaa.aaaaaaaaa) = {aaaaaaaaaaaaaaaa: AAAAAAAAAA\n"
+               "                            bbbbbbbbbbbbbbbb: BBBBBBBBBB}];");
+  verifyFormat("repeated double value = 1\n"
+               "    [(aaaaaaa.aaaaaaaaa) = {aaaaaaaaaaaaaaaa: AAAAAAAAAA,\n"
+               "                            bbbbbbb: BBBB,\n"
+               "                            bbbb: BBB}];");
+}
+
+TEST_F(FormatTestProto, FormatsOptions) {
+  verifyFormat("option java_package = \"my.test.package\";");
+  verifyFormat("option (my_custom_option) = \"abc\";");
+}
+
+TEST_F(FormatTestProto, FormatsService) {
+  verifyFormat("service SearchService {\n"
+               "  rpc Search(SearchRequest) returns (SearchResponse) {\n"
+               "    option foo = true;\n"
+               "  }\n"
+               "};");
+}
+
+} // end namespace tooling
+} // end namespace clang
diff --git a/unittests/Format/FormatTestUtils.h b/unittests/Format/FormatTestUtils.h
new file mode 100644
index 0000000..649f5b3
--- /dev/null
+++ b/unittests/Format/FormatTestUtils.h
@@ -0,0 +1,67 @@
+//===- unittest/Format/FormatTestUtils.h - Formatting unit tests ----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines utility functions for Clang-Format related tests.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_FORMAT_TEST_UTILS_H
+#define LLVM_CLANG_FORMAT_TEST_UTILS_H
+
+#include "llvm/ADT/StringRef.h"
+
+namespace clang {
+namespace format {
+namespace test {
+
+inline std::string messUp(llvm::StringRef Code) {
+  std::string MessedUp(Code.str());
+  bool InComment = false;
+  bool InPreprocessorDirective = false;
+  bool JustReplacedNewline = false;
+  for (unsigned i = 0, e = MessedUp.size() - 1; i != e; ++i) {
+    if (MessedUp[i] == '/' && MessedUp[i + 1] == '/') {
+      if (JustReplacedNewline)
+        MessedUp[i - 1] = '\n';
+      InComment = true;
+    } else if (MessedUp[i] == '#' && (JustReplacedNewline || i == 0)) {
+      if (i != 0)
+        MessedUp[i - 1] = '\n';
+      InPreprocessorDirective = true;
+    } else if (MessedUp[i] == '\\' && MessedUp[i + 1] == '\n') {
+      MessedUp[i] = ' ';
+      MessedUp[i + 1] = ' ';
+    } else if (MessedUp[i] == '\n') {
+      if (InComment) {
+        InComment = false;
+      } else if (InPreprocessorDirective) {
+        InPreprocessorDirective = false;
+      } else {
+        JustReplacedNewline = true;
+        MessedUp[i] = ' ';
+      }
+    } else if (MessedUp[i] != ' ') {
+      JustReplacedNewline = false;
+    }
+  }
+  std::string WithoutWhitespace;
+  if (MessedUp[0] != ' ')
+    WithoutWhitespace.push_back(MessedUp[0]);
+  for (unsigned i = 1, e = MessedUp.size(); i != e; ++i) {
+    if (MessedUp[i] != ' ' || MessedUp[i - 1] != ' ')
+      WithoutWhitespace.push_back(MessedUp[i]);
+  }
+  return WithoutWhitespace;
+}
+
+} // end namespace test
+} // end namespace format
+} // end namespace clang
+
+#endif // LLVM_CLANG_FORMAT_TEST_UTILS_H
diff --git a/unittests/Format/Makefile b/unittests/Format/Makefile
index 7de127c..e6dce4d 100644
--- a/unittests/Format/Makefile
+++ b/unittests/Format/Makefile
@@ -12,7 +12,7 @@
 include $(CLANG_LEVEL)/../../Makefile.config
 LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option
 USEDLIBS = clangFormat.a clangTooling.a clangFrontend.a clangSerialization.a \
-           clangDriver.a clangParse.a clangRewriteCore.a \
+           clangDriver.a clangParse.a clangRewrite.a \
            clangRewriteFrontend.a clangSema.a clangAnalysis.a clangEdit.a \
            clangAST.a clangASTMatchers.a clangLex.a clangBasic.a
 
diff --git a/unittests/Frontend/CMakeLists.txt b/unittests/Frontend/CMakeLists.txt
index c65a163..cdc9559 100644
--- a/unittests/Frontend/CMakeLists.txt
+++ b/unittests/Frontend/CMakeLists.txt
@@ -1,14 +1,11 @@
 set(LLVM_LINK_COMPONENTS
-  ${LLVM_TARGETS_TO_BUILD}
-  asmparser
-  bitreader
-  support
-  mc
+  Support
   )
 
 add_clang_unittest(FrontendTests
   FrontendActionTest.cpp
   )
 target_link_libraries(FrontendTests
+  clangAST
   clangFrontend
   )
diff --git a/unittests/Frontend/FrontendActionTest.cpp b/unittests/Frontend/FrontendActionTest.cpp
index bcb340d..e39d00f 100644
--- a/unittests/Frontend/FrontendActionTest.cpp
+++ b/unittests/Frontend/FrontendActionTest.cpp
@@ -13,6 +13,7 @@
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/CompilerInvocation.h"
+#include "clang/Lex/Preprocessor.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "gtest/gtest.h"
@@ -24,8 +25,19 @@
 
 class TestASTFrontendAction : public ASTFrontendAction {
 public:
+  TestASTFrontendAction(bool enableIncrementalProcessing = false)
+    : EnableIncrementalProcessing(enableIncrementalProcessing) { }
+
+  bool EnableIncrementalProcessing;
   std::vector<std::string> decl_names;
 
+  virtual bool BeginSourceFileAction(CompilerInstance &ci, StringRef filename) {
+    if (EnableIncrementalProcessing)
+      ci.getPreprocessor().enableIncrementalProcessing();
+
+    return ASTFrontendAction::BeginSourceFileAction(ci, filename);
+  }
+
   virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
                                          StringRef InFile) {
     return new Visitor(decl_names);
@@ -64,10 +76,28 @@
 
   TestASTFrontendAction test_action;
   ASSERT_TRUE(compiler.ExecuteAction(test_action));
-  ASSERT_EQ(3U, test_action.decl_names.size());
-  EXPECT_EQ("__builtin_va_list", test_action.decl_names[0]);
-  EXPECT_EQ("main", test_action.decl_names[1]);
-  EXPECT_EQ("x", test_action.decl_names[2]);
+  ASSERT_EQ(2U, test_action.decl_names.size());
+  EXPECT_EQ("main", test_action.decl_names[0]);
+  EXPECT_EQ("x", test_action.decl_names[1]);
+}
+
+TEST(ASTFrontendAction, IncrementalParsing) {
+  CompilerInvocation *invocation = new CompilerInvocation;
+  invocation->getPreprocessorOpts().addRemappedFile(
+    "test.cc", MemoryBuffer::getMemBuffer("int main() { float x; }"));
+  invocation->getFrontendOpts().Inputs.push_back(FrontendInputFile("test.cc",
+                                                                   IK_CXX));
+  invocation->getFrontendOpts().ProgramAction = frontend::ParseSyntaxOnly;
+  invocation->getTargetOpts().Triple = "i386-unknown-linux-gnu";
+  CompilerInstance compiler;
+  compiler.setInvocation(invocation);
+  compiler.createDiagnostics();
+
+  TestASTFrontendAction test_action(/*enableIncrementalProcessing=*/true);
+  ASSERT_TRUE(compiler.ExecuteAction(test_action));
+  ASSERT_EQ(2U, test_action.decl_names.size());
+  EXPECT_EQ("main", test_action.decl_names[0]);
+  EXPECT_EQ("x", test_action.decl_names[1]);
 }
 
 } // anonymous namespace
diff --git a/unittests/Frontend/Makefile b/unittests/Frontend/Makefile
index 7de9fb4..a63ae18 100644
--- a/unittests/Frontend/Makefile
+++ b/unittests/Frontend/Makefile
@@ -14,7 +14,7 @@
 USEDLIBS = clangFrontendTool.a clangFrontend.a clangDriver.a \
            clangSerialization.a clangCodeGen.a clangParse.a clangSema.a \
            clangStaticAnalyzerCheckers.a clangStaticAnalyzerCore.a \
-           clangARCMigrate.a clangRewriteCore.a \
+           clangARCMigrate.a clangRewrite.a \
 		   clangRewriteFrontend.a clangEdit.a \
            clangAnalysis.a clangAST.a clangLex.a clangBasic.a
 
diff --git a/unittests/Lex/CMakeLists.txt b/unittests/Lex/CMakeLists.txt
index cb3b927..1fb57cf 100644
--- a/unittests/Lex/CMakeLists.txt
+++ b/unittests/Lex/CMakeLists.txt
@@ -1,3 +1,7 @@
+set(LLVM_LINK_COMPONENTS
+  Support
+  )
+
 add_clang_unittest(LexTests
   LexerTest.cpp
   PPCallbacksTest.cpp
@@ -5,5 +9,10 @@
   )
 
 target_link_libraries(LexTests
-  clangLex clangParse clangSema
+  clangAST
+  clangBasic
+  clangLex
+  clangParse
+  clangSema
+  clangSerialization
   )
diff --git a/unittests/Lex/LexerTest.cpp b/unittests/Lex/LexerTest.cpp
index 40ce928..2d75b52 100644
--- a/unittests/Lex/LexerTest.cpp
+++ b/unittests/Lex/LexerTest.cpp
@@ -20,7 +20,6 @@
 #include "clang/Lex/ModuleLoader.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Lex/PreprocessorOptions.h"
-#include "llvm/Config/config.h"
 #include "gtest/gtest.h"
 
 using namespace llvm;
@@ -29,17 +28,22 @@
 namespace {
 
 class VoidModuleLoader : public ModuleLoader {
-  virtual ModuleLoadResult loadModule(SourceLocation ImportLoc, 
-                                      ModuleIdPath Path,
-                                      Module::NameVisibilityKind Visibility,
-                                      bool IsInclusionDirective) {
+  ModuleLoadResult loadModule(SourceLocation ImportLoc, 
+                              ModuleIdPath Path,
+                              Module::NameVisibilityKind Visibility,
+                              bool IsInclusionDirective) override {
     return ModuleLoadResult();
   }
 
-  virtual void makeModuleVisible(Module *Mod,
-                                 Module::NameVisibilityKind Visibility,
-                                 SourceLocation ImportLoc,
-                                 bool Complain) { }
+  void makeModuleVisible(Module *Mod,
+                         Module::NameVisibilityKind Visibility,
+                         SourceLocation ImportLoc,
+                         bool Complain) override { }
+
+  GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override
+    { return nullptr; }
+  bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override
+    { return 0; };
 };
 
 // The test fixture.
@@ -53,21 +57,21 @@
       TargetOpts(new TargetOptions) 
   {
     TargetOpts->Triple = "x86_64-apple-darwin11.1.0";
-    Target = TargetInfo::CreateTargetInfo(Diags, &*TargetOpts);
+    Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
   }
 
   std::vector<Token> CheckLex(StringRef Source,
                               ArrayRef<tok::TokenKind> ExpectedTokens) {
     MemoryBuffer *buf = MemoryBuffer::getMemBuffer(Source);
-    (void) SourceMgr.createMainFileIDForMemBuffer(buf);
+    SourceMgr.setMainFileID(SourceMgr.createFileID(buf));
 
     VoidModuleLoader ModLoader;
     HeaderSearch HeaderInfo(new HeaderSearchOptions, SourceMgr, Diags, LangOpts,
-                            Target.getPtr());
-    Preprocessor PP(new PreprocessorOptions(), Diags, LangOpts, Target.getPtr(),
-                    SourceMgr, HeaderInfo, ModLoader, /*IILookup =*/ 0,
-                    /*OwnsHeaderSearch =*/ false,
-                    /*DelayInitialization =*/ false);
+                            Target.get());
+    Preprocessor PP(new PreprocessorOptions(), Diags, LangOpts, SourceMgr,
+                    HeaderInfo, ModLoader, /*IILookup =*/nullptr,
+                    /*OwnsHeaderSearch =*/false);
+    PP.Initialize(*Target);
     PP.EnterMainSourceFile();
 
     std::vector<Token> toks;
@@ -104,7 +108,7 @@
   DiagnosticsEngine Diags;
   SourceManager SourceMgr;
   LangOptions LangOpts;
-  IntrusiveRefCntPtr<TargetOptions> TargetOpts;
+  std::shared_ptr<TargetOptions> TargetOpts;
   IntrusiveRefCntPtr<TargetInfo> Target;
 };
 
diff --git a/unittests/Lex/Makefile b/unittests/Lex/Makefile
index fa233ce..071d01c 100644
--- a/unittests/Lex/Makefile
+++ b/unittests/Lex/Makefile
@@ -9,8 +9,8 @@
 
 CLANG_LEVEL = ../..
 TESTNAME = Lex
-LINK_COMPONENTS := mcparser support mc
+LINK_COMPONENTS := mcparser support mc bitreader
 USEDLIBS = clangParse.a clangSema.a clangAnalysis.a clangEdit.a \
-	clangAST.a clangLex.a clangBasic.a 
+	clangSerialization.a clangAST.a clangLex.a clangBasic.a 
 
 include $(CLANG_LEVEL)/unittests/Makefile
diff --git a/unittests/Lex/PPCallbacksTest.cpp b/unittests/Lex/PPCallbacksTest.cpp
index 9405a84..a1af754 100644
--- a/unittests/Lex/PPCallbacksTest.cpp
+++ b/unittests/Lex/PPCallbacksTest.cpp
@@ -8,7 +8,10 @@
 //===--------------------------------------------------------------===//
 
 #include "clang/Lex/Preprocessor.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
 #include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/SourceManager.h"
@@ -20,8 +23,6 @@
 #include "clang/Lex/PreprocessorOptions.h"
 #include "clang/Parse/Parser.h"
 #include "clang/Sema/Sema.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/ASTConsumer.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/Path.h"
 #include "gtest/gtest.h"
@@ -34,17 +35,22 @@
 
 // Stub out module loading.
 class VoidModuleLoader : public ModuleLoader {
-  virtual ModuleLoadResult loadModule(SourceLocation ImportLoc, 
-                                      ModuleIdPath Path,
-                                      Module::NameVisibilityKind Visibility,
-                                      bool IsInclusionDirective) {
+  ModuleLoadResult loadModule(SourceLocation ImportLoc, 
+                              ModuleIdPath Path,
+                              Module::NameVisibilityKind Visibility,
+                              bool IsInclusionDirective) override {
     return ModuleLoadResult();
   }
 
-  virtual void makeModuleVisible(Module *Mod,
-                                 Module::NameVisibilityKind Visibility,
-                                 SourceLocation ImportLoc,
-                                 bool Complain) { }
+  void makeModuleVisible(Module *Mod,
+                         Module::NameVisibilityKind Visibility,
+                         SourceLocation ImportLoc,
+                         bool Complain) override { }
+
+  GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override
+    { return nullptr; }
+  bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override
+    { return 0; };
 };
 
 // Stub to collect data from InclusionDirective callbacks.
@@ -110,14 +116,12 @@
 class PPCallbacksTest : public ::testing::Test {
 protected:
   PPCallbacksTest()
-    : FileMgr(FileMgrOpts),
-      DiagID(new DiagnosticIDs()),
-      DiagOpts(new DiagnosticOptions()),
-      Diags(DiagID, DiagOpts.getPtr(), new IgnoringDiagConsumer()),
-      SourceMgr(Diags, FileMgr) {
-    TargetOpts = new TargetOptions();
+      : FileMgr(FileMgrOpts), DiagID(new DiagnosticIDs()),
+        DiagOpts(new DiagnosticOptions()),
+        Diags(DiagID, DiagOpts.get(), new IgnoringDiagConsumer()),
+        SourceMgr(Diags, FileMgr), TargetOpts(new TargetOptions()) {
     TargetOpts->Triple = "x86_64-apple-darwin11.1.0";
-    Target = TargetInfo::CreateTargetInfo(Diags, &*TargetOpts);
+    Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
   }
 
   FileSystemOptions FileMgrOpts;
@@ -127,7 +131,7 @@
   DiagnosticsEngine Diags;
   SourceManager SourceMgr;
   LangOptions LangOpts;
-  IntrusiveRefCntPtr<TargetOptions> TargetOpts;
+  std::shared_ptr<TargetOptions> TargetOpts;
   IntrusiveRefCntPtr<TargetInfo> Target;
 
   // Register a header path as a known file and add its location
@@ -157,22 +161,20 @@
   CharSourceRange InclusionDirectiveFilenameRange(const char* SourceText, 
       const char* HeaderPath, bool SystemHeader) {
     MemoryBuffer *Buf = MemoryBuffer::getMemBuffer(SourceText);
-    (void)SourceMgr.createMainFileIDForMemBuffer(Buf);
+    SourceMgr.setMainFileID(SourceMgr.createFileID(Buf));
 
     VoidModuleLoader ModLoader;
 
     IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts = new HeaderSearchOptions();
     HeaderSearch HeaderInfo(HSOpts, SourceMgr, Diags, LangOpts,
-                            Target.getPtr());
+                            Target.get());
     AddFakeHeader(HeaderInfo, HeaderPath, SystemHeader);
 
     IntrusiveRefCntPtr<PreprocessorOptions> PPOpts = new PreprocessorOptions();
-    Preprocessor PP(PPOpts, Diags, LangOpts,
-      Target.getPtr(),
-      SourceMgr, HeaderInfo, ModLoader,
-      /*IILookup =*/ 0,
-      /*OwnsHeaderSearch =*/false,
-      /*DelayInitialization =*/ false);
+    Preprocessor PP(PPOpts, Diags, LangOpts, SourceMgr, HeaderInfo, ModLoader,
+                    /*IILookup =*/nullptr,
+                    /*OwnsHeaderSearch =*/false);
+    PP.Initialize(*Target);
     InclusionDirectiveCallbacks* Callbacks = new InclusionDirectiveCallbacks;
     PP.addPPCallbacks(Callbacks); // Takes ownership.
 
@@ -196,25 +198,25 @@
     OpenCLLangOpts.OpenCL = 1;
 
     MemoryBuffer* sourceBuf = MemoryBuffer::getMemBuffer(SourceText, "test.cl");
-    (void)SourceMgr.createMainFileIDForMemBuffer(sourceBuf);
+    SourceMgr.setMainFileID(SourceMgr.createFileID(sourceBuf));
 
     VoidModuleLoader ModLoader;
     HeaderSearch HeaderInfo(new HeaderSearchOptions, SourceMgr, Diags, 
-                            OpenCLLangOpts, Target.getPtr());
+                            OpenCLLangOpts, Target.get());
 
-    Preprocessor PP(new PreprocessorOptions(), Diags, OpenCLLangOpts, 
-                    Target.getPtr(),
-                    SourceMgr, HeaderInfo, ModLoader,
-                   /*IILookup =*/ 0,
-                    /*OwnsHeaderSearch =*/false,
-                    /*DelayInitialization =*/ false);
+    Preprocessor PP(new PreprocessorOptions(), Diags, OpenCLLangOpts, SourceMgr,
+                    HeaderInfo, ModLoader, /*IILookup =*/nullptr,
+                    /*OwnsHeaderSearch =*/false);
+    PP.Initialize(*Target);
 
     // parser actually sets correct pragma handlers for preprocessor
     // according to LangOptions, so we init Parser to register opencl
     // pragma handlers
-    ASTContext Context(OpenCLLangOpts, SourceMgr, Target.getPtr(), 
+    ASTContext Context(OpenCLLangOpts, SourceMgr,
                        PP.getIdentifierTable(), PP.getSelectorTable(), 
-                       PP.getBuiltinInfo(), 0);    
+                       PP.getBuiltinInfo());
+    Context.InitBuiltinTypes(*Target);
+
     ASTConsumer Consumer;
     Sema S(PP, Context, Consumer);
     Parser P(PP, S, false);
diff --git a/unittests/Lex/PPConditionalDirectiveRecordTest.cpp b/unittests/Lex/PPConditionalDirectiveRecordTest.cpp
index 58857fa..e63106c 100644
--- a/unittests/Lex/PPConditionalDirectiveRecordTest.cpp
+++ b/unittests/Lex/PPConditionalDirectiveRecordTest.cpp
@@ -20,7 +20,6 @@
 #include "clang/Lex/ModuleLoader.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Lex/PreprocessorOptions.h"
-#include "llvm/Config/config.h"
 #include "gtest/gtest.h"
 
 using namespace llvm;
@@ -39,7 +38,7 @@
       TargetOpts(new TargetOptions)
   {
     TargetOpts->Triple = "x86_64-apple-darwin11.1.0";
-    Target = TargetInfo::CreateTargetInfo(Diags, &*TargetOpts);
+    Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
   }
 
   FileSystemOptions FileMgrOpts;
@@ -48,22 +47,27 @@
   DiagnosticsEngine Diags;
   SourceManager SourceMgr;
   LangOptions LangOpts;
-  IntrusiveRefCntPtr<TargetOptions> TargetOpts;
+  std::shared_ptr<TargetOptions> TargetOpts;
   IntrusiveRefCntPtr<TargetInfo> Target;
 };
 
 class VoidModuleLoader : public ModuleLoader {
-  virtual ModuleLoadResult loadModule(SourceLocation ImportLoc, 
-                                      ModuleIdPath Path,
-                                      Module::NameVisibilityKind Visibility,
-                                      bool IsInclusionDirective) {
+  ModuleLoadResult loadModule(SourceLocation ImportLoc, 
+                              ModuleIdPath Path,
+                              Module::NameVisibilityKind Visibility,
+                              bool IsInclusionDirective) override {
     return ModuleLoadResult();
   }
 
-  virtual void makeModuleVisible(Module *Mod,
-                                 Module::NameVisibilityKind Visibility,
-                                 SourceLocation ImportLoc,
-                                 bool Complain) { }
+  void makeModuleVisible(Module *Mod,
+                         Module::NameVisibilityKind Visibility,
+                         SourceLocation ImportLoc,
+                         bool Complain) override { }
+
+  GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override
+    { return nullptr; }
+  bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override
+    { return 0; };
 };
 
 TEST_F(PPConditionalDirectiveRecordTest, PPRecAPI) {
@@ -87,16 +91,16 @@
       "9\n";
 
   MemoryBuffer *buf = MemoryBuffer::getMemBuffer(source);
-  SourceMgr.createMainFileIDForMemBuffer(buf);
+  SourceMgr.setMainFileID(SourceMgr.createFileID(buf));
 
   VoidModuleLoader ModLoader;
   HeaderSearch HeaderInfo(new HeaderSearchOptions, SourceMgr, Diags, LangOpts, 
-                          Target.getPtr());
-  Preprocessor PP(new PreprocessorOptions(), Diags, LangOpts,Target.getPtr(),
-                  SourceMgr, HeaderInfo, ModLoader,
-                  /*IILookup =*/ 0,
-                  /*OwnsHeaderSearch =*/false,
-                  /*DelayInitialization =*/ false);
+                          Target.get());
+  Preprocessor PP(new PreprocessorOptions(), Diags, LangOpts, SourceMgr,
+                  HeaderInfo, ModLoader,
+                  /*IILookup =*/nullptr,
+                  /*OwnsHeaderSearch =*/false);
+  PP.Initialize(*Target);
   PPConditionalDirectiveRecord *
     PPRec = new PPConditionalDirectiveRecord(SourceMgr);
   PP.addPPCallbacks(PPRec);
diff --git a/unittests/Makefile b/unittests/Makefile
index d0dfe47..95b1639 100644
--- a/unittests/Makefile
+++ b/unittests/Makefile
@@ -14,14 +14,10 @@
 
 IS_UNITTEST_LEVEL := 1
 CLANG_LEVEL := ..
-PARALLEL_DIRS = Basic Lex
+PARALLEL_DIRS = Basic Lex Driver libclang Format ASTMatchers AST Tooling Sema
 
 include $(CLANG_LEVEL)/../..//Makefile.config
 
-ifeq ($(ENABLE_CLANG_REWRITER),1)
-PARALLEL_DIRS += Format ASTMatchers AST Tooling Sema
-endif
-
 ifeq ($(ENABLE_CLANG_ARCMT),1)
 PARALLEL_DIRS += Frontend
 endif
diff --git a/unittests/Sema/CMakeLists.txt b/unittests/Sema/CMakeLists.txt
index d491655..c25db81 100644
--- a/unittests/Sema/CMakeLists.txt
+++ b/unittests/Sema/CMakeLists.txt
@@ -1,7 +1,16 @@
+set(LLVM_LINK_COMPONENTS
+  Support
+  )
+
 add_clang_unittest(SemaTests
   ExternalSemaSourceTest.cpp
   )
 
 target_link_libraries(SemaTests
-  clangAST clangASTMatchers clangTooling
+  clangAST
+  clangBasic
+  clangFrontend
+  clangParse
+  clangSema
+  clangTooling
   )
diff --git a/unittests/Sema/ExternalSemaSourceTest.cpp b/unittests/Sema/ExternalSemaSourceTest.cpp
index e27d0cd..bc0d632 100644
--- a/unittests/Sema/ExternalSemaSourceTest.cpp
+++ b/unittests/Sema/ExternalSemaSourceTest.cpp
@@ -49,7 +49,7 @@
 
 public:
   NamespaceDiagnosticWatcher(StringRef From, StringRef To)
-      : Chained(NULL), FromNS(From), ToNS("'"), SeenCount(0) {
+      : Chained(nullptr), FromNS(From), ToNS("'"), SeenCount(0) {
     ToNS.append(To);
     ToNS.append("'");
   }
@@ -95,11 +95,11 @@
 
 public:
   NamespaceTypoProvider(StringRef From, StringRef To)
-      : CorrectFrom(From), CorrectTo(To), CurrentSema(NULL), CallCount(0) {}
+      : CorrectFrom(From), CorrectTo(To), CurrentSema(nullptr), CallCount(0) {}
 
   virtual void InitializeSema(Sema &S) { CurrentSema = &S; }
 
-  virtual void ForgetSema() { CurrentSema = NULL; }
+  virtual void ForgetSema() { CurrentSema = nullptr; }
 
   virtual TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo,
                                      int LookupKind, Scope *S, CXXScopeSpec *SS,
@@ -109,17 +109,17 @@
                                      const ObjCObjectPointerType *OPT) {
     ++CallCount;
     if (CurrentSema && Typo.getName().getAsString() == CorrectFrom) {
-      DeclContext *DestContext = NULL;
+      DeclContext *DestContext = nullptr;
       ASTContext &Context = CurrentSema->getASTContext();
-      if (SS != NULL)
+      if (SS)
         DestContext = CurrentSema->computeDeclContext(*SS, EnteringContext);
-      if (DestContext == NULL)
+      if (!DestContext)
         DestContext = Context.getTranslationUnitDecl();
       IdentifierInfo *ToIdent =
           CurrentSema->getPreprocessor().getIdentifierInfo(CorrectTo);
       NamespaceDecl *NewNamespace =
           NamespaceDecl::Create(Context, DestContext, false, Typo.getBeginLoc(),
-                                Typo.getLoc(), ToIdent, NULL);
+                                Typo.getLoc(), ToIdent, nullptr);
       DestContext->addDecl(NewNamespace);
       TypoCorrection Correction(ToIdent);
       Correction.addCorrectionDecl(NewNamespace);
@@ -137,7 +137,7 @@
 class ExternalSemaSourceInstaller : public clang::ASTFrontendAction {
   std::vector<NamespaceDiagnosticWatcher *> Watchers;
   std::vector<clang::ExternalSemaSource *> Sources;
-  llvm::OwningPtr<DiagnosticConsumer> OwnedClient;
+  std::unique_ptr<DiagnosticConsumer> OwnedClient;
 
 protected:
   virtual clang::ASTConsumer *
@@ -149,7 +149,7 @@
   virtual void ExecuteAction() {
     CompilerInstance &CI = getCompilerInstance();
     ASSERT_FALSE(CI.hasSema());
-    CI.createSema(getTranslationUnitKind(), NULL);
+    CI.createSema(getTranslationUnitKind(), nullptr);
     ASSERT_TRUE(CI.hasDiagnostics());
     DiagnosticsEngine &Diagnostics = CI.getDiagnostics();
     DiagnosticConsumer *Client = Diagnostics.getClient();
@@ -178,20 +178,20 @@
 
 // Make sure that the NamespaceDiagnosticWatcher is not miscounting.
 TEST(ExternalSemaSource, SanityCheck) {
-  llvm::OwningPtr<ExternalSemaSourceInstaller> Installer(
+  std::unique_ptr<ExternalSemaSourceInstaller> Installer(
       new ExternalSemaSourceInstaller);
   NamespaceDiagnosticWatcher Watcher("AAB", "BBB");
   Installer->PushWatcher(&Watcher);
   std::vector<std::string> Args(1, "-std=c++11");
   ASSERT_TRUE(clang::tooling::runToolOnCodeWithArgs(
-      Installer.take(), "namespace AAA { } using namespace AAB;", Args));
+      Installer.release(), "namespace AAA { } using namespace AAB;", Args));
   ASSERT_EQ(0, Watcher.SeenCount);
 }
 
 // Check that when we add a NamespaceTypeProvider, we use that suggestion
 // instead of the usual suggestion we would use above.
 TEST(ExternalSemaSource, ExternalTypoCorrectionPrioritized) {
-  llvm::OwningPtr<ExternalSemaSourceInstaller> Installer(
+  std::unique_ptr<ExternalSemaSourceInstaller> Installer(
       new ExternalSemaSourceInstaller);
   NamespaceTypoProvider Provider("AAB", "BBB");
   NamespaceDiagnosticWatcher Watcher("AAB", "BBB");
@@ -199,7 +199,7 @@
   Installer->PushWatcher(&Watcher);
   std::vector<std::string> Args(1, "-std=c++11");
   ASSERT_TRUE(clang::tooling::runToolOnCodeWithArgs(
-      Installer.take(), "namespace AAA { } using namespace AAB;", Args));
+      Installer.release(), "namespace AAA { } using namespace AAB;", Args));
   ASSERT_LE(0, Provider.CallCount);
   ASSERT_EQ(1, Watcher.SeenCount);
 }
@@ -207,7 +207,7 @@
 // Check that we use the first successful TypoCorrection returned from an
 // ExternalSemaSource.
 TEST(ExternalSemaSource, ExternalTypoCorrectionOrdering) {
-  llvm::OwningPtr<ExternalSemaSourceInstaller> Installer(
+  std::unique_ptr<ExternalSemaSourceInstaller> Installer(
       new ExternalSemaSourceInstaller);
   NamespaceTypoProvider First("XXX", "BBB");
   NamespaceTypoProvider Second("AAB", "CCC");
@@ -219,7 +219,7 @@
   Installer->PushWatcher(&Watcher);
   std::vector<std::string> Args(1, "-std=c++11");
   ASSERT_TRUE(clang::tooling::runToolOnCodeWithArgs(
-      Installer.take(), "namespace AAA { } using namespace AAB;", Args));
+      Installer.release(), "namespace AAA { } using namespace AAB;", Args));
   ASSERT_LE(1, First.CallCount);
   ASSERT_LE(1, Second.CallCount);
   ASSERT_EQ(0, Third.CallCount);
@@ -229,7 +229,7 @@
 // We should only try MaybeDiagnoseMissingCompleteType if we can't otherwise
 // solve the problem.
 TEST(ExternalSemaSource, TryOtherTacticsBeforeDiagnosing) {
-  llvm::OwningPtr<ExternalSemaSourceInstaller> Installer(
+  std::unique_ptr<ExternalSemaSourceInstaller> Installer(
       new ExternalSemaSourceInstaller);
   CompleteTypeDiagnoser Diagnoser(false);
   Installer->PushSource(&Diagnoser);
@@ -237,7 +237,7 @@
   // This code hits the class template specialization/class member of a class
   // template specialization checks in Sema::RequireCompleteTypeImpl.
   ASSERT_TRUE(clang::tooling::runToolOnCodeWithArgs(
-      Installer.take(),
+      Installer.release(),
       "template <typename T> struct S { class C { }; }; S<char>::C SCInst;",
       Args));
   ASSERT_EQ(0, Diagnoser.CallCount);
@@ -246,7 +246,7 @@
 // The first ExternalSemaSource where MaybeDiagnoseMissingCompleteType returns
 // true should be the last one called.
 TEST(ExternalSemaSource, FirstDiagnoserTaken) {
-  llvm::OwningPtr<ExternalSemaSourceInstaller> Installer(
+  std::unique_ptr<ExternalSemaSourceInstaller> Installer(
       new ExternalSemaSourceInstaller);
   CompleteTypeDiagnoser First(false);
   CompleteTypeDiagnoser Second(true);
@@ -256,7 +256,7 @@
   Installer->PushSource(&Third);
   std::vector<std::string> Args(1, "-std=c++11");
   ASSERT_FALSE(clang::tooling::runToolOnCodeWithArgs(
-      Installer.take(), "class Incomplete; Incomplete IncompleteInstance;",
+      Installer.release(), "class Incomplete; Incomplete IncompleteInstance;",
       Args));
   ASSERT_EQ(1, First.CallCount);
   ASSERT_EQ(1, Second.CallCount);
diff --git a/unittests/Sema/Makefile b/unittests/Sema/Makefile
index cd1d93d..7fd5c27 100644
--- a/unittests/Sema/Makefile
+++ b/unittests/Sema/Makefile
@@ -12,7 +12,7 @@
 include $(CLANG_LEVEL)/../../Makefile.config
 LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option
 USEDLIBS = clangTooling.a clangFrontend.a clangSerialization.a clangDriver.a \
-           clangRewriteCore.a clangRewriteFrontend.a \
+           clangRewrite.a clangRewriteFrontend.a \
            clangParse.a clangSema.a clangAnalysis.a \
            clangEdit.a clangAST.a clangASTMatchers.a clangLex.a clangBasic.a
 
diff --git a/unittests/Tooling/CMakeLists.txt b/unittests/Tooling/CMakeLists.txt
index 33d7617..a41d87c 100644
--- a/unittests/Tooling/CMakeLists.txt
+++ b/unittests/Tooling/CMakeLists.txt
@@ -1,9 +1,5 @@
 set(LLVM_LINK_COMPONENTS
-  ${LLVM_TARGETS_TO_BUILD}
-  asmparser
-  bitreader
-  support
-  mc
+  Support
   )
 
 add_clang_unittest(ToolingTests
@@ -19,6 +15,10 @@
 
 target_link_libraries(ToolingTests
   clangAST
+  clangASTMatchers
+  clangBasic
+  clangFrontend
+  clangLex
+  clangRewrite
   clangTooling
-  clangRewriteCore
   )
diff --git a/unittests/Tooling/CommentHandlerTest.cpp b/unittests/Tooling/CommentHandlerTest.cpp
index f0f7797..117dfc3 100644
--- a/unittests/Tooling/CommentHandlerTest.cpp
+++ b/unittests/Tooling/CommentHandlerTest.cpp
@@ -28,7 +28,7 @@
   typedef TestVisitor<CommentHandlerVisitor> base;
 
 public:
-  CommentHandlerVisitor() : base(), PP(0), Verified(false) { }
+  CommentHandlerVisitor() : base(), PP(nullptr), Verified(false) {}
 
   ~CommentHandlerVisitor() {
     EXPECT_TRUE(Verified) << "CommentVerifier not accessed";
diff --git a/unittests/Tooling/CompilationDatabaseTest.cpp b/unittests/Tooling/CompilationDatabaseTest.cpp
index c575dff..8866e75 100644
--- a/unittests/Tooling/CompilationDatabaseTest.cpp
+++ b/unittests/Tooling/CompilationDatabaseTest.cpp
@@ -22,9 +22,9 @@
 
 static void expectFailure(StringRef JSONDatabase, StringRef Explanation) {
   std::string ErrorMessage;
-  EXPECT_EQ(NULL, JSONCompilationDatabase::loadFromBuffer(JSONDatabase,
-                                                          ErrorMessage))
-    << "Expected an error because of: " << Explanation;
+  EXPECT_EQ(nullptr, JSONCompilationDatabase::loadFromBuffer(JSONDatabase,
+                                                             ErrorMessage))
+    << "Expected an error because of: " << Explanation.str();
 }
 
 TEST(JSONCompilationDatabase, ErrsOnInvalidFormat) {
@@ -42,7 +42,7 @@
 
 static std::vector<std::string> getAllFiles(StringRef JSONDatabase,
                                             std::string &ErrorMessage) {
-  OwningPtr<CompilationDatabase> Database(
+  std::unique_ptr<CompilationDatabase> Database(
       JSONCompilationDatabase::loadFromBuffer(JSONDatabase, ErrorMessage));
   if (!Database) {
     ADD_FAILURE() << ErrorMessage;
@@ -53,7 +53,7 @@
 
 static std::vector<CompileCommand> getAllCompileCommands(StringRef JSONDatabase,
                                                     std::string &ErrorMessage) {
-  OwningPtr<CompilationDatabase> Database(
+  std::unique_ptr<CompilationDatabase> Database(
       JSONCompilationDatabase::loadFromBuffer(JSONDatabase, ErrorMessage));
   if (!Database) {
     ADD_FAILURE() << ErrorMessage;
@@ -115,7 +115,7 @@
 static CompileCommand findCompileArgsInJsonDatabase(StringRef FileName,
                                                     StringRef JSONDatabase,
                                                     std::string &ErrorMessage) {
-  OwningPtr<CompilationDatabase> Database(
+  std::unique_ptr<CompilationDatabase> Database(
       JSONCompilationDatabase::loadFromBuffer(JSONDatabase, ErrorMessage));
   if (!Database)
     return CompileCommand();
@@ -433,8 +433,8 @@
 
 TEST(ParseFixedCompilationDatabase, ReturnsNullOnEmptyArgumentList) {
   int Argc = 0;
-  OwningPtr<FixedCompilationDatabase> Database(
-      FixedCompilationDatabase::loadFromCommandLine(Argc, NULL));
+  std::unique_ptr<FixedCompilationDatabase> Database(
+      FixedCompilationDatabase::loadFromCommandLine(Argc, nullptr));
   EXPECT_FALSE(Database);
   EXPECT_EQ(0, Argc);
 }
@@ -442,7 +442,7 @@
 TEST(ParseFixedCompilationDatabase, ReturnsNullWithoutDoubleDash) {
   int Argc = 2;
   const char *Argv[] = { "1", "2" };
-  OwningPtr<FixedCompilationDatabase> Database(
+  std::unique_ptr<FixedCompilationDatabase> Database(
       FixedCompilationDatabase::loadFromCommandLine(Argc, Argv));
   EXPECT_FALSE(Database);
   EXPECT_EQ(2, Argc);
@@ -453,9 +453,9 @@
   const char *Argv[] = {
     "1", "2", "--\0no-constant-folding", "-DDEF3", "-DDEF4"
   };
-  OwningPtr<FixedCompilationDatabase> Database(
+  std::unique_ptr<FixedCompilationDatabase> Database(
       FixedCompilationDatabase::loadFromCommandLine(Argc, Argv));
-  ASSERT_TRUE(Database.isValid());
+  ASSERT_TRUE((bool)Database);
   std::vector<CompileCommand> Result =
     Database->getCompileCommands("source");
   ASSERT_EQ(1ul, Result.size());
@@ -472,9 +472,9 @@
 TEST(ParseFixedCompilationDatabase, ReturnsEmptyCommandLine) {
   int Argc = 3;
   const char *Argv[] = { "1", "2", "--\0no-constant-folding" };
-  OwningPtr<FixedCompilationDatabase> Database(
+  std::unique_ptr<FixedCompilationDatabase> Database(
       FixedCompilationDatabase::loadFromCommandLine(Argc, Argv));
-  ASSERT_TRUE(Database.isValid());
+  ASSERT_TRUE((bool)Database);
   std::vector<CompileCommand> Result =
     Database->getCompileCommands("source");
   ASSERT_EQ(1ul, Result.size());
@@ -489,9 +489,9 @@
 TEST(ParseFixedCompilationDatabase, HandlesPositionalArgs) {
   const char *Argv[] = {"1", "2", "--", "-c", "somefile.cpp", "-DDEF3"};
   int Argc = sizeof(Argv) / sizeof(char*);
-  OwningPtr<FixedCompilationDatabase> Database(
+  std::unique_ptr<FixedCompilationDatabase> Database(
       FixedCompilationDatabase::loadFromCommandLine(Argc, Argv));
-  ASSERT_TRUE(Database.isValid());
+  ASSERT_TRUE((bool)Database);
   std::vector<CompileCommand> Result =
     Database->getCompileCommands("source");
   ASSERT_EQ(1ul, Result.size());
@@ -508,9 +508,9 @@
 TEST(ParseFixedCompilationDatabase, HandlesArgv0) {
   const char *Argv[] = {"1", "2", "--", "mytool", "somefile.cpp"};
   int Argc = sizeof(Argv) / sizeof(char*);
-  OwningPtr<FixedCompilationDatabase> Database(
+  std::unique_ptr<FixedCompilationDatabase> Database(
       FixedCompilationDatabase::loadFromCommandLine(Argc, Argv));
-  ASSERT_TRUE(Database.isValid());
+  ASSERT_TRUE((bool)Database);
   std::vector<CompileCommand> Result =
     Database->getCompileCommands("source");
   ASSERT_EQ(1ul, Result.size());
diff --git a/unittests/Tooling/Makefile b/unittests/Tooling/Makefile
index 9d36f1f..46af8a1 100644
--- a/unittests/Tooling/Makefile
+++ b/unittests/Tooling/Makefile
@@ -12,7 +12,7 @@
 include $(CLANG_LEVEL)/../../Makefile.config
 LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option
 USEDLIBS = clangTooling.a clangFrontend.a clangSerialization.a clangDriver.a \
-           clangParse.a clangRewriteCore.a clangRewriteFrontend.a \
+           clangParse.a clangRewrite.a clangRewriteFrontend.a \
 	   clangSema.a clangAnalysis.a clangEdit.a \
            clangAST.a clangASTMatchers.a clangLex.a clangBasic.a
 
diff --git a/unittests/Tooling/RecursiveASTVisitorTest.cpp b/unittests/Tooling/RecursiveASTVisitorTest.cpp
index 3234767..a1a93a5 100644
--- a/unittests/Tooling/RecursiveASTVisitorTest.cpp
+++ b/unittests/Tooling/RecursiveASTVisitorTest.cpp
@@ -8,10 +8,11 @@
 //===----------------------------------------------------------------------===//
 
 #include "TestVisitor.h"
-
 #include <stack>
 
-namespace clang {
+using namespace clang;
+
+namespace {
 
 class TypeLocVisitor : public ExpectedLocationVisitor<TypeLocVisitor> {
 public:
@@ -530,6 +531,15 @@
       TypeLocVisitor::Lang_C));
 }
 
+TEST(RecursiveASTVisitor, VisitsObjCPropertyType) {
+  TypeLocVisitor Visitor;
+  Visitor.ExpectMatch("NSNumber", 2, 33);
+  EXPECT_TRUE(Visitor.runOver(
+      "@class NSNumber; \n"
+      "@interface A @property (retain) NSNumber *x; @end\n",
+      TypeLocVisitor::Lang_OBJC));
+}
+
 TEST(RecursiveASTVisitor, VisitsLambdaExpr) {
   LambdaExprVisitor Visitor;
   Visitor.ExpectMatch("", 1, 12);
@@ -551,6 +561,16 @@
                               LambdaDefaultCaptureVisitor::Lang_CXX11));
 }
 
+TEST(RecursiveASTVisitor, VisitsCopyExprOfBlockDeclCapture) {
+  DeclRefExprVisitor Visitor;
+  Visitor.ExpectMatch("x", 3, 24);
+  EXPECT_TRUE(Visitor.runOver("void f(int(^)(int)); \n"
+                              "void g() { \n"
+                              "  f([&](int x){ return x; }); \n"
+                              "}",
+                              DeclRefExprVisitor::Lang_OBJCXX11));
+}
+
 // Checks for lambda classes that are not marked as implicitly-generated.
 // (There should be none.)
 class ClassVisitor : public ExpectedLocationVisitor<ClassVisitor> {
@@ -577,4 +597,42 @@
   EXPECT_TRUE(Visitor.sawOnlyImplicitLambdaClasses());
 }
 
-} // end namespace clang
+
+
+// Check to ensure that attributes and expressions within them are being
+// visited.
+class AttrVisitor : public ExpectedLocationVisitor<AttrVisitor> {
+public:
+  bool VisitMemberExpr(MemberExpr *ME) {
+    Match(ME->getMemberDecl()->getNameAsString(), ME->getLocStart());
+    return true;
+  }
+  bool VisitAttr(Attr *A) {
+    Match("Attr", A->getLocation());
+    return true;
+  }
+  bool VisitGuardedByAttr(GuardedByAttr *A) {
+    Match("guarded_by", A->getLocation());
+    return true;
+  }
+};
+
+
+TEST(RecursiveASTVisitor, AttributesAreVisited) {
+  AttrVisitor Visitor;
+  Visitor.ExpectMatch("Attr", 4, 24);
+  Visitor.ExpectMatch("guarded_by", 4, 24);
+  Visitor.ExpectMatch("mu1",  4, 35);
+  Visitor.ExpectMatch("Attr", 5, 29);
+  Visitor.ExpectMatch("mu1",  5, 54);
+  Visitor.ExpectMatch("mu2",  5, 59);
+  EXPECT_TRUE(Visitor.runOver(
+    "class Foo {\n"
+    "  int mu1;\n"
+    "  int mu2;\n"
+    "  int a __attribute__((guarded_by(mu1)));\n"
+    "  void bar() __attribute__((exclusive_locks_required(mu1, mu2)));\n"
+    "};\n"));
+}
+
+} // end anonymous namespace
diff --git a/unittests/Tooling/RefactoringCallbacksTest.cpp b/unittests/Tooling/RefactoringCallbacksTest.cpp
index 9e086d8..c2b331c 100644
--- a/unittests/Tooling/RefactoringCallbacksTest.cpp
+++ b/unittests/Tooling/RefactoringCallbacksTest.cpp
@@ -25,7 +25,7 @@
                      RefactoringCallback &Callback) {
   MatchFinder Finder;
   Finder.addMatcher(AMatcher, &Callback);
-  OwningPtr<tooling::FrontendActionFactory> Factory(
+  std::unique_ptr<tooling::FrontendActionFactory> Factory(
       tooling::newFrontendActionFactory(&Finder));
   ASSERT_TRUE(tooling::runToolOnCode(Factory->create(), Code))
       << "Parsing error in \"" << Code << "\"";
diff --git a/unittests/Tooling/RefactoringTest.cpp b/unittests/Tooling/RefactoringTest.cpp
index 8c7bfa1..ddb974a 100644
--- a/unittests/Tooling/RefactoringTest.cpp
+++ b/unittests/Tooling/RefactoringTest.cpp
@@ -218,7 +218,7 @@
                                                 E = TemporaryFiles.end();
          I != E; ++I) {
       llvm::StringRef Name = I->second;
-      llvm::error_code EC = llvm::sys::fs::remove(Name);
+      std::error_code EC = llvm::sys::fs::remove(Name);
       (void)EC;
       assert(!EC);
     }
@@ -227,8 +227,7 @@
   FileID createFile(llvm::StringRef Name, llvm::StringRef Content) {
     SmallString<1024> Path;
     int FD;
-    llvm::error_code EC =
-        llvm::sys::fs::createTemporaryFile(Name, "", FD, Path);
+    std::error_code EC = llvm::sys::fs::createTemporaryFile(Name, "", FD, Path);
     assert(!EC);
     (void)EC;
 
@@ -236,7 +235,7 @@
     OutStream << Content;
     OutStream.close();
     const FileEntry *File = Context.Files.getFile(Path);
-    assert(File != NULL);
+    assert(File != nullptr);
 
     StringRef Found = TemporaryFiles.GetOrCreateValue(Name, Path.str()).second;
     assert(Found == Path);
@@ -252,7 +251,9 @@
     // descriptor, which might not see the changes made.
     // FIXME: Figure out whether there is a way to get the SourceManger to
     // reopen the file.
-    return Context.Files.getBufferForFile(Path, NULL)->getBuffer();
+    std::unique_ptr<const llvm::MemoryBuffer> FileBuffer(
+        Context.Files.getBufferForFile(Path, nullptr));
+    return FileBuffer->getBuffer();
   }
 
   llvm::StringMap<std::string> TemporaryFiles;
diff --git a/unittests/Tooling/RewriterTestContext.h b/unittests/Tooling/RewriterTestContext.h
index 841cd0f..fe108ad 100644
--- a/unittests/Tooling/RewriterTestContext.h
+++ b/unittests/Tooling/RewriterTestContext.h
@@ -48,12 +48,11 @@
   ~RewriterTestContext() {}
 
   FileID createInMemoryFile(StringRef Name, StringRef Content) {
-    const llvm::MemoryBuffer *Source =
-      llvm::MemoryBuffer::getMemBuffer(Content);
+    llvm::MemoryBuffer *Source = llvm::MemoryBuffer::getMemBuffer(Content);
     const FileEntry *Entry =
       Files.getVirtualFile(Name, Source->getBufferSize(), 0);
-    Sources.overrideFileContents(Entry, Source, true);
-    assert(Entry != NULL);
+    Sources.overrideFileContents(Entry, Source);
+    assert(Entry != nullptr);
     return Sources.createFileID(Entry, SourceLocation(), SrcMgr::C_User);
   }
 
@@ -62,8 +61,7 @@
   FileID createOnDiskFile(StringRef Name, StringRef Content) {
     SmallString<1024> Path;
     int FD;
-    llvm::error_code EC =
-        llvm::sys::fs::createTemporaryFile(Name, "", FD, Path);
+    std::error_code EC = llvm::sys::fs::createTemporaryFile(Name, "", FD, Path);
     assert(!EC);
     (void)EC;
 
@@ -71,7 +69,7 @@
     OutStream << Content;
     OutStream.close();
     const FileEntry *File = Files.getFile(Path);
-    assert(File != NULL);
+    assert(File != nullptr);
 
     StringRef Found = TemporaryFiles.GetOrCreateValue(Name, Path.str()).second;
     assert(Found == Path);
@@ -102,7 +100,9 @@
     // descriptor, which might not see the changes made.
     // FIXME: Figure out whether there is a way to get the SourceManger to
     // reopen the file.
-    return Files.getBufferForFile(Path, NULL)->getBuffer();
+    std::unique_ptr<const llvm::MemoryBuffer> FileBuffer(
+        Files.getBufferForFile(Path, nullptr));
+    return FileBuffer->getBuffer();
   }
 
   IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
diff --git a/unittests/Tooling/TestVisitor.h b/unittests/Tooling/TestVisitor.h
index ec751c3..205a0aa 100644
--- a/unittests/Tooling/TestVisitor.h
+++ b/unittests/Tooling/TestVisitor.h
@@ -39,7 +39,14 @@
 
   virtual ~TestVisitor() { }
 
-  enum Language { Lang_C, Lang_CXX98, Lang_CXX11, Lang_CXX=Lang_CXX98 };
+  enum Language {
+    Lang_C,
+    Lang_CXX98,
+    Lang_CXX11,
+    Lang_OBJC,
+    Lang_OBJCXX11,
+    Lang_CXX = Lang_CXX98
+  };
 
   /// \brief Runs the current AST visitor over the given code.
   bool runOver(StringRef Code, Language L = Lang_CXX) {
@@ -48,6 +55,12 @@
       case Lang_C: Args.push_back("-std=c99"); break;
       case Lang_CXX98: Args.push_back("-std=c++98"); break;
       case Lang_CXX11: Args.push_back("-std=c++11"); break;
+      case Lang_OBJC: Args.push_back("-ObjC"); break;
+      case Lang_OBJCXX11:
+        Args.push_back("-ObjC++");
+        Args.push_back("-std=c++11");
+        Args.push_back("-fblocks");
+        break;
     }
     return tooling::runToolOnCodeWithArgs(CreateTestAction(), Code, Args);
   }
diff --git a/unittests/Tooling/ToolingTest.cpp b/unittests/Tooling/ToolingTest.cpp
index 2c4a8a7..9aede04 100644
--- a/unittests/Tooling/ToolingTest.cpp
+++ b/unittests/Tooling/ToolingTest.cpp
@@ -16,8 +16,9 @@
 #include "clang/Frontend/FrontendActions.h"
 #include "clang/Tooling/CompilationDatabase.h"
 #include "clang/Tooling/Tooling.h"
-#include "gtest/gtest.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/Config/llvm-config.h"
+#include "gtest/gtest.h"
 #include <string>
 
 namespace clang {
@@ -60,12 +61,7 @@
   bool FoundTopLevelDecl = false;
   EXPECT_TRUE(runToolOnCode(
       new TestAction(new FindTopLevelDeclConsumer(&FoundTopLevelDecl)), ""));
-#if !defined(_MSC_VER)
   EXPECT_FALSE(FoundTopLevelDecl);
-#else
-  // FIXME: LangOpts.MicrosoftExt appends "class type_info;"
-  EXPECT_TRUE(FoundTopLevelDecl);
-#endif
 }
 
 namespace {
@@ -112,34 +108,34 @@
 }
 
 TEST(buildASTFromCode, FindsClassDecl) {
-  OwningPtr<ASTUnit> AST(buildASTFromCode("class X;"));
+  std::unique_ptr<ASTUnit> AST = buildASTFromCode("class X;");
   ASSERT_TRUE(AST.get());
   EXPECT_TRUE(FindClassDeclX(AST.get()));
 
-  AST.reset(buildASTFromCode("class Y;"));
+  AST = buildASTFromCode("class Y;");
   ASSERT_TRUE(AST.get());
   EXPECT_FALSE(FindClassDeclX(AST.get()));
 }
 
 TEST(newFrontendActionFactory, CreatesFrontendActionFactoryFromType) {
-  OwningPtr<FrontendActionFactory> Factory(
+  std::unique_ptr<FrontendActionFactory> Factory(
       newFrontendActionFactory<SyntaxOnlyAction>());
-  OwningPtr<FrontendAction> Action(Factory->create());
-  EXPECT_TRUE(Action.get() != NULL);
+  std::unique_ptr<FrontendAction> Action(Factory->create());
+  EXPECT_TRUE(Action.get() != nullptr);
 }
 
 struct IndependentFrontendActionCreator {
   ASTConsumer *newASTConsumer() {
-    return new FindTopLevelDeclConsumer(NULL);
+    return new FindTopLevelDeclConsumer(nullptr);
   }
 };
 
 TEST(newFrontendActionFactory, CreatesFrontendActionFactoryFromFactoryType) {
   IndependentFrontendActionCreator Creator;
-  OwningPtr<FrontendActionFactory> Factory(
+  std::unique_ptr<FrontendActionFactory> Factory(
       newFrontendActionFactory(&Creator));
-  OwningPtr<FrontendAction> Action(Factory->create());
-  EXPECT_TRUE(Action.get() != NULL);
+  std::unique_ptr<FrontendAction> Action(Factory->create());
+  EXPECT_TRUE(Action.get() != nullptr);
 }
 
 TEST(ToolInvocation, TestMapVirtualFile) {
@@ -151,7 +147,7 @@
   Args.push_back("-fsyntax-only");
   Args.push_back("test.cpp");
   clang::tooling::ToolInvocation Invocation(Args, new SyntaxOnlyAction,
-                                            Files.getPtr());
+                                            Files.get());
   Invocation.mapVirtualFile("test.cpp", "#include <abc>\n");
   Invocation.mapVirtualFile("def/abc", "\n");
   EXPECT_TRUE(Invocation.run());
@@ -170,7 +166,7 @@
   Args.push_back("-fsyntax-only");
   Args.push_back("test.cpp");
   clang::tooling::ToolInvocation Invocation(Args, new SyntaxOnlyAction,
-                                            Files.getPtr());
+                                            Files.get());
   Invocation.mapVirtualFile("test.cpp", "#include <abc>\n");
   Invocation.mapVirtualFile("def/abc", "\n");
   // Add a module.map file in the include directory of our header, so we trigger
@@ -182,7 +178,7 @@
 struct VerifyEndCallback : public SourceFileCallbacks {
   VerifyEndCallback() : BeginCalled(0), EndCalled(0), Matched(false) {}
   virtual bool handleBeginSource(CompilerInstance &CI,
-                                 StringRef Filename) LLVM_OVERRIDE {
+                                 StringRef Filename) override {
     ++BeginCalled;
     return true;
   }
@@ -197,7 +193,7 @@
   bool Matched;
 };
 
-#if !defined(_WIN32)
+#if !defined(LLVM_ON_WIN32)
 TEST(newFrontendActionFactory, InjectsSourceFileCallbacks) {
   VerifyEndCallback EndCallback;
 
@@ -210,7 +206,9 @@
   Tool.mapVirtualFile("/a.cc", "void a() {}");
   Tool.mapVirtualFile("/b.cc", "void b() {}");
 
-  Tool.run(newFrontendActionFactory(&EndCallback, &EndCallback));
+  std::unique_ptr<FrontendActionFactory> Action(
+      newFrontendActionFactory(&EndCallback, &EndCallback));
+  Tool.run(Action.get());
 
   EXPECT_TRUE(EndCallback.Matched);
   EXPECT_EQ(2u, EndCallback.BeginCalled);
@@ -241,6 +239,21 @@
                              "int skipMeNot() { an_error_here }"));
 }
 
+TEST(runToolOnCodeWithArgs, TestNoDepFile) {
+  llvm::SmallString<32> DepFilePath;
+  ASSERT_FALSE(
+      llvm::sys::fs::createTemporaryFile("depfile", "d", DepFilePath));
+  std::vector<std::string> Args;
+  Args.push_back("-MMD");
+  Args.push_back("-MT");
+  Args.push_back(DepFilePath.str());
+  Args.push_back("-MF");
+  Args.push_back(DepFilePath.str());
+  EXPECT_TRUE(runToolOnCodeWithArgs(new SkipBodyAction, "", Args));
+  EXPECT_FALSE(llvm::sys::fs::exists(DepFilePath.str()));
+  EXPECT_FALSE(llvm::sys::fs::remove(DepFilePath.str()));
+}
+
 struct CheckSyntaxOnlyAdjuster: public ArgumentsAdjuster {
   bool &Found;
   bool &Ran;
@@ -248,7 +261,7 @@
   CheckSyntaxOnlyAdjuster(bool &Found, bool &Ran) : Found(Found), Ran(Ran) { }
 
   virtual CommandLineArguments
-  Adjust(const CommandLineArguments &Args) LLVM_OVERRIDE {
+  Adjust(const CommandLineArguments &Args) override {
     Ran = true;
     for (unsigned I = 0, E = Args.size(); I != E; ++I) {
       if (Args[I] == "-fsyntax-only") {
@@ -266,10 +279,13 @@
   ClangTool Tool(Compilations, std::vector<std::string>(1, "/a.cc"));
   Tool.mapVirtualFile("/a.cc", "void a() {}");
 
+  std::unique_ptr<FrontendActionFactory> Action(
+      newFrontendActionFactory<SyntaxOnlyAction>());
+
   bool Found = false;
   bool Ran = false;
   Tool.appendArgumentsAdjuster(new CheckSyntaxOnlyAdjuster(Found, Ran));
-  Tool.run(newFrontendActionFactory<SyntaxOnlyAction>());
+  Tool.run(Action.get());
   EXPECT_TRUE(Ran);
   EXPECT_TRUE(Found);
 
@@ -277,12 +293,12 @@
   Tool.clearArgumentsAdjusters();
   Tool.appendArgumentsAdjuster(new CheckSyntaxOnlyAdjuster(Found, Ran));
   Tool.appendArgumentsAdjuster(new ClangSyntaxOnlyAdjuster());
-  Tool.run(newFrontendActionFactory<SyntaxOnlyAction>());
+  Tool.run(Action.get());
   EXPECT_TRUE(Ran);
   EXPECT_FALSE(Found);
 }
 
-#ifndef _WIN32
+#ifndef LLVM_ON_WIN32
 TEST(ClangToolTest, BuildASTs) {
   FixedCompilationDatabase Compilations("/", std::vector<std::string>());
 
@@ -294,11 +310,9 @@
   Tool.mapVirtualFile("/a.cc", "void a() {}");
   Tool.mapVirtualFile("/b.cc", "void b() {}");
 
-  std::vector<ASTUnit *> ASTs;
+  std::vector<std::unique_ptr<ASTUnit>> ASTs;
   EXPECT_EQ(0, Tool.buildASTs(ASTs));
   EXPECT_EQ(2u, ASTs.size());
-
-  llvm::DeleteContainerPointers(ASTs);
 }
 
 struct TestDiagnosticConsumer : public DiagnosticConsumer {
@@ -316,7 +330,9 @@
   Tool.mapVirtualFile("/a.cc", "int x = undeclared;");
   TestDiagnosticConsumer Consumer;
   Tool.setDiagnosticConsumer(&Consumer);
-  Tool.run(newFrontendActionFactory<SyntaxOnlyAction>());
+  std::unique_ptr<FrontendActionFactory> Action(
+      newFrontendActionFactory<SyntaxOnlyAction>());
+  Tool.run(Action.get());
   EXPECT_EQ(1u, Consumer.NumDiagnosticsSeen);
 }
 
@@ -326,7 +342,7 @@
   Tool.mapVirtualFile("/a.cc", "int x = undeclared;");
   TestDiagnosticConsumer Consumer;
   Tool.setDiagnosticConsumer(&Consumer);
-  std::vector<ASTUnit*> ASTs;
+  std::vector<std::unique_ptr<ASTUnit>> ASTs;
   Tool.buildASTs(ASTs);
   EXPECT_EQ(1u, ASTs.size());
   EXPECT_EQ(1u, Consumer.NumDiagnosticsSeen);
diff --git a/unittests/libclang/CMakeLists.txt b/unittests/libclang/CMakeLists.txt
new file mode 100644
index 0000000..1cdc45e
--- /dev/null
+++ b/unittests/libclang/CMakeLists.txt
@@ -0,0 +1,7 @@
+add_clang_unittest(libclangTests
+  LibclangTest.cpp
+  )
+
+target_link_libraries(libclangTests
+  libclang
+  )
diff --git a/unittests/libclang/LibclangTest.cpp b/unittests/libclang/LibclangTest.cpp
new file mode 100644
index 0000000..ee56e22
--- /dev/null
+++ b/unittests/libclang/LibclangTest.cpp
@@ -0,0 +1,467 @@
+//===- unittests/libclang/LibclangTest.cpp --- libclang tests -------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang-c/Index.h"
+#include "gtest/gtest.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+#include <fstream>
+#include <set>
+#define DEBUG_TYPE "libclang-test"
+
+TEST(libclang, clang_parseTranslationUnit2_InvalidArgs) {
+  EXPECT_EQ(CXError_InvalidArguments,
+            clang_parseTranslationUnit2(nullptr, nullptr, nullptr, 0, nullptr,
+                                        0, 0, nullptr));
+}
+
+TEST(libclang, clang_createTranslationUnit_InvalidArgs) {
+  EXPECT_EQ(nullptr, clang_createTranslationUnit(nullptr, nullptr));
+}
+
+TEST(libclang, clang_createTranslationUnit2_InvalidArgs) {
+  EXPECT_EQ(CXError_InvalidArguments,
+            clang_createTranslationUnit2(nullptr, nullptr, nullptr));
+
+  CXTranslationUnit TU = reinterpret_cast<CXTranslationUnit>(1);
+  EXPECT_EQ(CXError_InvalidArguments,
+            clang_createTranslationUnit2(nullptr, nullptr, &TU));
+  EXPECT_EQ(nullptr, TU);
+}
+
+namespace {
+struct TestVFO {
+  const char *Contents;
+  CXVirtualFileOverlay VFO;
+
+  TestVFO(const char *Contents) : Contents(Contents) {
+    VFO = clang_VirtualFileOverlay_create(0);
+  }
+
+  void map(const char *VPath, const char *RPath) {
+    CXErrorCode Err = clang_VirtualFileOverlay_addFileMapping(VFO, VPath, RPath);
+    EXPECT_EQ(Err, CXError_Success);
+  }
+
+  void mapError(const char *VPath, const char *RPath, CXErrorCode ExpErr) {
+    CXErrorCode Err = clang_VirtualFileOverlay_addFileMapping(VFO, VPath, RPath);
+    EXPECT_EQ(Err, ExpErr);
+  }
+
+  ~TestVFO() {
+    if (Contents) {
+      char *BufPtr;
+      unsigned BufSize;
+      clang_VirtualFileOverlay_writeToBuffer(VFO, 0, &BufPtr, &BufSize);
+      std::string BufStr(BufPtr, BufSize);
+      EXPECT_STREQ(Contents, BufStr.c_str());
+      free(BufPtr);
+    }
+    clang_VirtualFileOverlay_dispose(VFO);
+  }
+};
+}
+
+TEST(libclang, VirtualFileOverlay_Basic) {
+  const char *contents =
+      "{\n"
+      "  'version': 0,\n"
+      "  'roots': [\n"
+      "    {\n"
+      "      'type': 'directory',\n"
+      "      'name': \"/path/virtual\",\n"
+      "      'contents': [\n"
+      "        {\n"
+      "          'type': 'file',\n"
+      "          'name': \"foo.h\",\n"
+      "          'external-contents': \"/real/foo.h\"\n"
+      "        }\n"
+      "      ]\n"
+      "    }\n"
+      "  ]\n"
+      "}\n";
+  TestVFO T(contents);
+  T.map("/path/virtual/foo.h", "/real/foo.h");
+}
+
+TEST(libclang, VirtualFileOverlay_Unicode) {
+  const char *contents =
+      "{\n"
+      "  'version': 0,\n"
+      "  'roots': [\n"
+      "    {\n"
+      "      'type': 'directory',\n"
+      "      'name': \"/path/\\u266B\",\n"
+      "      'contents': [\n"
+      "        {\n"
+      "          'type': 'file',\n"
+      "          'name': \"\\u2602.h\",\n"
+      "          'external-contents': \"/real/\\u2602.h\"\n"
+      "        }\n"
+      "      ]\n"
+      "    }\n"
+      "  ]\n"
+      "}\n";
+  TestVFO T(contents);
+  T.map("/path/♫/☂.h", "/real/☂.h");
+}
+
+TEST(libclang, VirtualFileOverlay_InvalidArgs) {
+  TestVFO T(nullptr);
+  T.mapError("/path/./virtual/../foo.h", "/real/foo.h",
+             CXError_InvalidArguments);
+}
+
+TEST(libclang, VirtualFileOverlay_RemapDirectories) {
+  const char *contents =
+      "{\n"
+      "  'version': 0,\n"
+      "  'roots': [\n"
+      "    {\n"
+      "      'type': 'directory',\n"
+      "      'name': \"/another/dir\",\n"
+      "      'contents': [\n"
+      "        {\n"
+      "          'type': 'file',\n"
+      "          'name': \"foo2.h\",\n"
+      "          'external-contents': \"/real/foo2.h\"\n"
+      "        }\n"
+      "      ]\n"
+      "    },\n"
+      "    {\n"
+      "      'type': 'directory',\n"
+      "      'name': \"/path/virtual/dir\",\n"
+      "      'contents': [\n"
+      "        {\n"
+      "          'type': 'file',\n"
+      "          'name': \"foo1.h\",\n"
+      "          'external-contents': \"/real/foo1.h\"\n"
+      "        },\n"
+      "        {\n"
+      "          'type': 'file',\n"
+      "          'name': \"foo3.h\",\n"
+      "          'external-contents': \"/real/foo3.h\"\n"
+      "        },\n"
+      "        {\n"
+      "          'type': 'directory',\n"
+      "          'name': \"in/subdir\",\n"
+      "          'contents': [\n"
+      "            {\n"
+      "              'type': 'file',\n"
+      "              'name': \"foo4.h\",\n"
+      "              'external-contents': \"/real/foo4.h\"\n"
+      "            }\n"
+      "          ]\n"
+      "        }\n"
+      "      ]\n"
+      "    }\n"
+      "  ]\n"
+      "}\n";
+  TestVFO T(contents);
+  T.map("/path/virtual/dir/foo1.h", "/real/foo1.h");
+  T.map("/another/dir/foo2.h", "/real/foo2.h");
+  T.map("/path/virtual/dir/foo3.h", "/real/foo3.h");
+  T.map("/path/virtual/dir/in/subdir/foo4.h", "/real/foo4.h");
+}
+
+TEST(libclang, VirtualFileOverlay_CaseInsensitive) {
+  const char *contents =
+      "{\n"
+      "  'version': 0,\n"
+      "  'case-sensitive': 'false',\n"
+      "  'roots': [\n"
+      "    {\n"
+      "      'type': 'directory',\n"
+      "      'name': \"/path/virtual\",\n"
+      "      'contents': [\n"
+      "        {\n"
+      "          'type': 'file',\n"
+      "          'name': \"foo.h\",\n"
+      "          'external-contents': \"/real/foo.h\"\n"
+      "        }\n"
+      "      ]\n"
+      "    }\n"
+      "  ]\n"
+      "}\n";
+  TestVFO T(contents);
+  T.map("/path/virtual/foo.h", "/real/foo.h");
+  clang_VirtualFileOverlay_setCaseSensitivity(T.VFO, false);
+}
+
+TEST(libclang, VirtualFileOverlay_SharedPrefix) {
+  const char *contents =
+      "{\n"
+      "  'version': 0,\n"
+      "  'roots': [\n"
+      "    {\n"
+      "      'type': 'directory',\n"
+      "      'name': \"/path/foo\",\n"
+      "      'contents': [\n"
+      "        {\n"
+      "          'type': 'file',\n"
+      "          'name': \"bar\",\n"
+      "          'external-contents': \"/real/bar\"\n"
+      "        },\n"
+      "        {\n"
+      "          'type': 'file',\n"
+      "          'name': \"bar.h\",\n"
+      "          'external-contents': \"/real/bar.h\"\n"
+      "        }\n"
+      "      ]\n"
+      "    },\n"
+      "    {\n"
+      "      'type': 'directory',\n"
+      "      'name': \"/path/foobar\",\n"
+      "      'contents': [\n"
+      "        {\n"
+      "          'type': 'file',\n"
+      "          'name': \"baz.h\",\n"
+      "          'external-contents': \"/real/baz.h\"\n"
+      "        }\n"
+      "      ]\n"
+      "    },\n"
+      "    {\n"
+      "      'type': 'directory',\n"
+      "      'name': \"/path\",\n"
+      "      'contents': [\n"
+      "        {\n"
+      "          'type': 'file',\n"
+      "          'name': \"foobarbaz.h\",\n"
+      "          'external-contents': \"/real/foobarbaz.h\"\n"
+      "        }\n"
+      "      ]\n"
+      "    }\n"
+      "  ]\n"
+      "}\n";
+  TestVFO T(contents);
+  T.map("/path/foo/bar.h", "/real/bar.h");
+  T.map("/path/foo/bar", "/real/bar");
+  T.map("/path/foobar/baz.h", "/real/baz.h");
+  T.map("/path/foobarbaz.h", "/real/foobarbaz.h");
+}
+
+TEST(libclang, VirtualFileOverlay_AdjacentDirectory) {
+  const char *contents =
+      "{\n"
+      "  'version': 0,\n"
+      "  'roots': [\n"
+      "    {\n"
+      "      'type': 'directory',\n"
+      "      'name': \"/path/dir1\",\n"
+      "      'contents': [\n"
+      "        {\n"
+      "          'type': 'file',\n"
+      "          'name': \"foo.h\",\n"
+      "          'external-contents': \"/real/foo.h\"\n"
+      "        },\n"
+      "        {\n"
+      "          'type': 'directory',\n"
+      "          'name': \"subdir\",\n"
+      "          'contents': [\n"
+      "            {\n"
+      "              'type': 'file',\n"
+      "              'name': \"bar.h\",\n"
+      "              'external-contents': \"/real/bar.h\"\n"
+      "            }\n"
+      "          ]\n"
+      "        }\n"
+      "      ]\n"
+      "    },\n"
+      "    {\n"
+      "      'type': 'directory',\n"
+      "      'name': \"/path/dir2\",\n"
+      "      'contents': [\n"
+      "        {\n"
+      "          'type': 'file',\n"
+      "          'name': \"baz.h\",\n"
+      "          'external-contents': \"/real/baz.h\"\n"
+      "        }\n"
+      "      ]\n"
+      "    }\n"
+      "  ]\n"
+      "}\n";
+  TestVFO T(contents);
+  T.map("/path/dir1/foo.h", "/real/foo.h");
+  T.map("/path/dir1/subdir/bar.h", "/real/bar.h");
+  T.map("/path/dir2/baz.h", "/real/baz.h");
+}
+
+TEST(libclang, VirtualFileOverlay_TopLevel) {
+  const char *contents =
+      "{\n"
+      "  'version': 0,\n"
+      "  'roots': [\n"
+      "    {\n"
+      "      'type': 'directory',\n"
+      "      'name': \"/\",\n"
+      "      'contents': [\n"
+      "        {\n"
+      "          'type': 'file',\n"
+      "          'name': \"foo.h\",\n"
+      "          'external-contents': \"/real/foo.h\"\n"
+      "        }\n"
+      "      ]\n"
+      "    }\n"
+      "  ]\n"
+      "}\n";
+  TestVFO T(contents);
+  T.map("/foo.h", "/real/foo.h");
+}
+
+TEST(libclang, VirtualFileOverlay_Empty) {
+  const char *contents =
+      "{\n"
+      "  'version': 0,\n"
+      "  'roots': [\n"
+      "  ]\n"
+      "}\n";
+  TestVFO T(contents);
+}
+
+TEST(libclang, ModuleMapDescriptor) {
+  const char *Contents =
+    "framework module TestFrame {\n"
+    "  umbrella header \"TestFrame.h\"\n"
+    "\n"
+    "  export *\n"
+    "  module * { export * }\n"
+    "}\n";
+
+  CXModuleMapDescriptor MMD = clang_ModuleMapDescriptor_create(0);
+
+  clang_ModuleMapDescriptor_setFrameworkModuleName(MMD, "TestFrame");
+  clang_ModuleMapDescriptor_setUmbrellaHeader(MMD, "TestFrame.h");
+
+  char *BufPtr;
+  unsigned BufSize;
+  clang_ModuleMapDescriptor_writeToBuffer(MMD, 0, &BufPtr, &BufSize);
+  std::string BufStr(BufPtr, BufSize);
+  EXPECT_STREQ(Contents, BufStr.c_str());
+  free(BufPtr);
+  clang_ModuleMapDescriptor_dispose(MMD);
+}
+
+class LibclangReparseTest : public ::testing::Test {
+  std::set<std::string> Files;
+public:
+  std::string TestDir;
+  CXIndex Index;
+  CXTranslationUnit ClangTU;
+  unsigned TUFlags;
+
+  void SetUp() {
+    llvm::SmallString<256> Dir;
+    ASSERT_FALSE(llvm::sys::fs::createUniqueDirectory("libclang-test", Dir));
+    TestDir = Dir.str();
+    TUFlags = CXTranslationUnit_DetailedPreprocessingRecord |
+              clang_defaultEditingTranslationUnitOptions();
+    Index = clang_createIndex(0, 0);
+  }
+  void TearDown() {
+    clang_disposeTranslationUnit(ClangTU);
+    clang_disposeIndex(Index);
+    for (const std::string &Path : Files)
+      llvm::sys::fs::remove(Path);
+    llvm::sys::fs::remove(TestDir);
+  }
+  void WriteFile(std::string &Filename, const std::string &Contents) {
+    if (!llvm::sys::path::is_absolute(Filename)) {
+      llvm::SmallString<256> Path(TestDir);
+      llvm::sys::path::append(Path, Filename);
+      Filename = Path.str();
+      Files.insert(Filename);
+    }
+    std::ofstream OS(Filename);
+    OS << Contents;
+  }
+  void DisplayDiagnostics() {
+    unsigned NumDiagnostics = clang_getNumDiagnostics(ClangTU);
+    for (unsigned i = 0; i < NumDiagnostics; ++i) {
+      auto Diag = clang_getDiagnostic(ClangTU, i);
+      DEBUG(llvm::dbgs() << clang_getCString(clang_formatDiagnostic(
+          Diag, clang_defaultDiagnosticDisplayOptions())) << "\n");
+      clang_disposeDiagnostic(Diag);
+    }
+  }
+  bool ReparseTU(unsigned num_unsaved_files, CXUnsavedFile* unsaved_files) {
+    if (clang_reparseTranslationUnit(ClangTU, num_unsaved_files, unsaved_files,
+                                     clang_defaultReparseOptions(ClangTU))) {
+      DEBUG(llvm::dbgs() << "Reparse failed\n");
+      return false;
+    }
+    DisplayDiagnostics();
+    return true;
+  }
+};
+
+
+TEST_F(LibclangReparseTest, Reparse) {
+  const char *HeaderTop = "#ifndef H\n#define H\nstruct Foo { int bar;";
+  const char *HeaderBottom = "\n};\n#endif\n";
+  const char *CppFile = "#include \"HeaderFile.h\"\nint main() {"
+                         " Foo foo; foo.bar = 7; foo.baz = 8; }\n";
+  std::string HeaderName = "HeaderFile.h";
+  std::string CppName = "CppFile.cpp";
+  WriteFile(CppName, CppFile);
+  WriteFile(HeaderName, std::string(HeaderTop) + HeaderBottom);
+
+  ClangTU = clang_parseTranslationUnit(Index, CppName.c_str(), nullptr, 0,
+                                       nullptr, 0, TUFlags);
+  EXPECT_EQ(1U, clang_getNumDiagnostics(ClangTU));
+  DisplayDiagnostics();
+
+  // Immedaitely reparse.
+  ASSERT_TRUE(ReparseTU(0, nullptr /* No unsaved files. */));
+  EXPECT_EQ(1U, clang_getNumDiagnostics(ClangTU));
+
+  std::string NewHeaderContents =
+      std::string(HeaderTop) + "int baz;" + HeaderBottom;
+  WriteFile(HeaderName, NewHeaderContents);
+
+  // Reparse after fix.
+  ASSERT_TRUE(ReparseTU(0, nullptr /* No unsaved files. */));
+  EXPECT_EQ(0U, clang_getNumDiagnostics(ClangTU));
+}
+
+TEST_F(LibclangReparseTest, ReparseWithModule) {
+  const char *HeaderTop = "#ifndef H\n#define H\nstruct Foo { int bar;";
+  const char *HeaderBottom = "\n};\n#endif\n";
+  const char *MFile = "#include \"HeaderFile.h\"\nint main() {"
+                         " struct Foo foo; foo.bar = 7; foo.baz = 8; }\n";
+  const char *ModFile = "module A { header \"HeaderFile.h\" }\n";
+  std::string HeaderName = "HeaderFile.h";
+  std::string MName = "MFile.m";
+  std::string ModName = "module.modulemap";
+  WriteFile(MName, MFile);
+  WriteFile(HeaderName, std::string(HeaderTop) + HeaderBottom);
+  WriteFile(ModName, ModFile);
+
+  std::string ModulesCache = std::string("-fmodules-cache-path=") + TestDir;
+  const char *Args[] = { "-fmodules", ModulesCache.c_str(),
+                         "-I", TestDir.c_str() };
+  int NumArgs = sizeof(Args) / sizeof(Args[0]);
+  ClangTU = clang_parseTranslationUnit(Index, MName.c_str(), Args, NumArgs,
+                                       nullptr, 0, TUFlags);
+  EXPECT_EQ(1U, clang_getNumDiagnostics(ClangTU));
+  DisplayDiagnostics();
+
+  // Immedaitely reparse.
+  ASSERT_TRUE(ReparseTU(0, nullptr /* No unsaved files. */));
+  EXPECT_EQ(1U, clang_getNumDiagnostics(ClangTU));
+
+  std::string NewHeaderContents =
+      std::string(HeaderTop) + "int baz;" + HeaderBottom;
+  WriteFile(HeaderName, NewHeaderContents);
+
+  // Reparse after fix.
+  ASSERT_TRUE(ReparseTU(0, nullptr /* No unsaved files. */));
+  EXPECT_EQ(0U, clang_getNumDiagnostics(ClangTU));
+}
diff --git a/unittests/libclang/Makefile b/unittests/libclang/Makefile
new file mode 100644
index 0000000..a6590eb
--- /dev/null
+++ b/unittests/libclang/Makefile
@@ -0,0 +1,27 @@
+##===- unittests/libclang/Makefile -------------------------*- Makefile -*-===##
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+CLANG_LEVEL = ../..
+TESTNAME = libclang
+LINK_LIBS_IN_SHARED := 1
+
+include $(CLANG_LEVEL)/../../Makefile.config
+LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option
+
+# Note that 'USEDLIBS' must include all of the core clang libraries
+# when -static is given to linker on cygming.
+USEDLIBS = clang.a \
+	   clangIndex.a clangFormat.a clangRewrite.a \
+	   clangFrontend.a clangDriver.a \
+	   clangTooling.a \
+	   clangSerialization.a clangParse.a clangSema.a \
+	   clangAnalysis.a clangEdit.a clangAST.a clangLex.a \
+	   clangBasic.a
+
+include $(CLANG_LEVEL)/unittests/Makefile
diff --git a/utils/CmpDriver b/utils/CmpDriver
index 2533f54..12ce7a3 100755
--- a/utils/CmpDriver
+++ b/utils/CmpDriver
@@ -1,5 +1,10 @@
 #!/usr/bin/env python
 
+"""
+A simple utility that compares tool invocations and exit codes issued by
+compiler drivers that support -### (e.g. gcc and clang).
+"""
+
 import subprocess
 
 def splitArgs(s):
diff --git a/utils/TableGen/ClangASTNodesEmitter.cpp b/utils/TableGen/ClangASTNodesEmitter.cpp
index 682f9c7..b17a4a3 100644
--- a/utils/TableGen/ClangASTNodesEmitter.cpp
+++ b/utils/TableGen/ClangASTNodesEmitter.cpp
@@ -77,7 +77,7 @@
 
   ChildIterator i = Tree.lower_bound(Base), e = Tree.upper_bound(Base);
 
-  Record *First = 0, *Last = 0;
+  Record *First = nullptr, *Last = nullptr;
   // This might be the pseudo-node for Stmt; don't assume it has an Abstract
   // bit
   if (Base->getValue("Abstract") && !Base->getValueAsBit("Abstract"))
diff --git a/utils/TableGen/ClangAttrEmitter.cpp b/utils/TableGen/ClangAttrEmitter.cpp
index 653d7b7..1790dcb 100644
--- a/utils/TableGen/ClangAttrEmitter.cpp
+++ b/utils/TableGen/ClangAttrEmitter.cpp
@@ -12,35 +12,63 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/TableGen/Error.h"
 #include "llvm/TableGen/Record.h"
 #include "llvm/TableGen/StringMatcher.h"
 #include "llvm/TableGen/TableGenBackend.h"
 #include <algorithm>
 #include <cctype>
+#include <memory>
+#include <set>
+#include <sstream>
 
 using namespace llvm;
 
-static const std::vector<StringRef>
-getValueAsListOfStrings(Record &R, StringRef FieldName) {
-  ListInit *List = R.getValueAsListInit(FieldName);
-  assert (List && "Got a null ListInit");
+class FlattenedSpelling {
+  std::string V, N, NS;
+  bool K;
 
-  std::vector<StringRef> Strings;
-  Strings.reserve(List->getSize());
+public:
+  FlattenedSpelling(const std::string &Variety, const std::string &Name,
+                    const std::string &Namespace, bool KnownToGCC) :
+    V(Variety), N(Name), NS(Namespace), K(KnownToGCC) {}
+  explicit FlattenedSpelling(const Record &Spelling) :
+    V(Spelling.getValueAsString("Variety")),
+    N(Spelling.getValueAsString("Name")) {
 
-  for (ListInit::const_iterator i = List->begin(), e = List->end();
-       i != e;
-       ++i) {
-    assert(*i && "Got a null element in a ListInit");
-    if (StringInit *S = dyn_cast<StringInit>(*i))
-      Strings.push_back(S->getValue());
-    else
-      assert(false && "Got a non-string, non-code element in a ListInit");
+    assert(V != "GCC" && "Given a GCC spelling, which means this hasn't been"
+           "flattened!");
+    if (V == "CXX11" || V == "Pragma")
+      NS = Spelling.getValueAsString("Namespace");
+    bool Unset;
+    K = Spelling.getValueAsBitOrUnset("KnownToGCC", Unset);
   }
 
-  return Strings;
+  const std::string &variety() const { return V; }
+  const std::string &name() const { return N; }
+  const std::string &nameSpace() const { return NS; }
+  bool knownToGCC() const { return K; }
+};
+
+std::vector<FlattenedSpelling> GetFlattenedSpellings(const Record &Attr) {
+  std::vector<Record *> Spellings = Attr.getValueAsListOfDefs("Spellings");
+  std::vector<FlattenedSpelling> Ret;
+
+  for (const auto &Spelling : Spellings) {
+    if (Spelling->getValueAsString("Variety") == "GCC") {
+      // Gin up two new spelling objects to add into the list.
+      Ret.push_back(FlattenedSpelling("GNU", Spelling->getValueAsString("Name"),
+                                      "", true));
+      Ret.push_back(FlattenedSpelling(
+          "CXX11", Spelling->getValueAsString("Name"), "gnu", true));
+    } else
+      Ret.push_back(FlattenedSpelling(*Spelling));
+  }
+
+  return Ret;
 }
 
 static std::string ReadPCHRecord(StringRef type) {
@@ -50,7 +78,6 @@
     .Case("TypeSourceInfo *", "GetTypeSourceInfo(F, Record, Idx)")
     .Case("Expr *", "ReadExpr(F)")
     .Case("IdentifierInfo *", "GetIdentifierInfo(F, Record, Idx)")
-    .Case("SourceLocation", "ReadSourceLocation(F, Record, Idx)")
     .Default("Record[Idx++]");
 }
 
@@ -64,8 +91,6 @@
     .Case("Expr *", "AddStmt(" + std::string(name) + ");\n")
     .Case("IdentifierInfo *", 
           "AddIdentifierRef(" + std::string(name) + ", Record);\n")
-    .Case("SourceLocation", 
-          "AddSourceLocation(" + std::string(name) + ", Record);\n")
     .Default("Record.push_back(" + std::string(name) + ");\n");
 }
 
@@ -82,6 +107,17 @@
   return AttrName;
 }
 
+// Normalize the name by removing any and all leading and trailing underscores.
+// This is different from NormalizeAttrName in that it also handles names like
+// _pascal and __pascal.
+static StringRef NormalizeNameForSpellingComparison(StringRef Name) {
+  while (Name.startswith("_"))
+    Name = Name.substr(1, Name.size());
+  while (Name.endswith("_"))
+    Name = Name.substr(0, Name.size() - 1);
+  return Name;
+}
+
 // 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.
@@ -93,6 +129,37 @@
   return AttrSpelling;
 }
 
+typedef std::vector<std::pair<std::string, const Record *>> ParsedAttrMap;
+
+static ParsedAttrMap getParsedAttrList(const RecordKeeper &Records,
+                                       ParsedAttrMap *Dupes = nullptr) {
+  std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
+  std::set<std::string> Seen;
+  ParsedAttrMap R;
+  for (const auto *Attr : Attrs) {
+    if (Attr->getValueAsBit("SemaHandler")) {
+      std::string AN;
+      if (Attr->isSubClassOf("TargetSpecificAttr") &&
+          !Attr->isValueUnset("ParseKind")) {
+        AN = Attr->getValueAsString("ParseKind");
+
+        // If this attribute has already been handled, it does not need to be
+        // handled again.
+        if (Seen.find(AN) != Seen.end()) {
+          if (Dupes)
+            Dupes->push_back(std::make_pair(AN, Attr));
+          continue;
+        }
+        Seen.insert(AN);
+      } else
+        AN = NormalizeAttrName(Attr->getName()).str();
+
+      R.push_back(std::make_pair(AN, Attr));
+    }
+  }
+  return R;
+}
+
 namespace {
   class Argument {
     std::string lowerName, upperName;
@@ -100,7 +167,7 @@
     bool isOpt;
 
   public:
-    Argument(Record &Arg, StringRef Attr)
+    Argument(const Record &Arg, StringRef Attr)
       : lowerName(Arg.getValueAsString("Name")), upperName(lowerName),
         attrName(Attr), isOpt(false) {
       if (!lowerName.empty()) {
@@ -120,6 +187,7 @@
     // These functions print the argument contents formatted in different ways.
     virtual void writeAccessors(raw_ostream &OS) const = 0;
     virtual void writeAccessorDefinitions(raw_ostream &OS) const {}
+    virtual void writeASTVisitorTraversal(raw_ostream &OS) const {}
     virtual void writeCloneArgs(raw_ostream &OS) const = 0;
     virtual void writeTemplateInstantiationArgs(raw_ostream &OS) const = 0;
     virtual void writeTemplateInstantiation(raw_ostream &OS) const {}
@@ -138,53 +206,57 @@
 
     virtual bool isEnumArg() const { return false; }
     virtual bool isVariadicEnumArg() const { return false; }
+
+    virtual void writeImplicitCtorArgs(raw_ostream &OS) const {
+      OS << getUpperName();
+    }
   };
 
   class SimpleArgument : public Argument {
     std::string type;
 
   public:
-    SimpleArgument(Record &Arg, StringRef Attr, std::string T)
+    SimpleArgument(const Record &Arg, StringRef Attr, std::string T)
       : Argument(Arg, Attr), type(T)
     {}
 
     std::string getType() const { return type; }
 
-    void writeAccessors(raw_ostream &OS) const {
+    void writeAccessors(raw_ostream &OS) const override {
       OS << "  " << type << " get" << getUpperName() << "() const {\n";
       OS << "    return " << getLowerName() << ";\n";
       OS << "  }";
     }
-    void writeCloneArgs(raw_ostream &OS) const {
+    void writeCloneArgs(raw_ostream &OS) const override {
       OS << getLowerName();
     }
-    void writeTemplateInstantiationArgs(raw_ostream &OS) const {
+    void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
       OS << "A->get" << getUpperName() << "()";
     }
-    void writeCtorInitializers(raw_ostream &OS) const {
+    void writeCtorInitializers(raw_ostream &OS) const override {
       OS << getLowerName() << "(" << getUpperName() << ")";
     }
-    void writeCtorDefaultInitializers(raw_ostream &OS) const {
+    void writeCtorDefaultInitializers(raw_ostream &OS) const override {
       OS << getLowerName() << "()";
     }
-    void writeCtorParameters(raw_ostream &OS) const {
+    void writeCtorParameters(raw_ostream &OS) const override {
       OS << type << " " << getUpperName();
     }
-    void writeDeclarations(raw_ostream &OS) const {
+    void writeDeclarations(raw_ostream &OS) const override {
       OS << type << " " << getLowerName() << ";";
     }
-    void writePCHReadDecls(raw_ostream &OS) const {
+    void writePCHReadDecls(raw_ostream &OS) const override {
       std::string read = ReadPCHRecord(type);
       OS << "    " << type << " " << getLowerName() << " = " << read << ";\n";
     }
-    void writePCHReadArgs(raw_ostream &OS) const {
+    void writePCHReadArgs(raw_ostream &OS) const override {
       OS << getLowerName();
     }
-    void writePCHWrite(raw_ostream &OS) const {
+    void writePCHWrite(raw_ostream &OS) const override {
       OS << "    " << WritePCHRecord(type, "SA->get" +
                                            std::string(getUpperName()) + "()");
     }
-    void writeValue(raw_ostream &OS) const {
+    void writeValue(raw_ostream &OS) const override {
       if (type == "FunctionDecl *") {
         OS << "\" << get" << getUpperName()
            << "()->getNameInfo().getAsString() << \"";
@@ -192,13 +264,11 @@
         OS << "\" << get" << getUpperName() << "()->getName() << \"";
       } else if (type == "TypeSourceInfo *") {
         OS << "\" << get" << getUpperName() << "().getAsString() << \"";
-      } else if (type == "SourceLocation") {
-        OS << "\" << get" << getUpperName() << "().getRawEncoding() << \"";
       } else {
         OS << "\" << get" << getUpperName() << "() << \"";
       }
     }
-    void writeDump(raw_ostream &OS) const {
+    void writeDump(raw_ostream &OS) const override {
       if (type == "FunctionDecl *") {
         OS << "    OS << \" \";\n";
         OS << "    dumpBareDeclRef(SA->get" << getUpperName() << "());\n"; 
@@ -208,9 +278,6 @@
       } else if (type == "TypeSourceInfo *") {
         OS << "    OS << \" \" << SA->get" << getUpperName()
            << "().getAsString();\n";
-      } else if (type == "SourceLocation") {
-        OS << "    OS << \" \";\n";
-        OS << "    SA->get" << getUpperName() << "().print(OS, *SM);\n";
       } else if (type == "bool") {
         OS << "    if (SA->get" << getUpperName() << "()) OS << \" "
            << getUpperName() << "\";\n";
@@ -222,13 +289,29 @@
     }
   };
 
+  class DefaultSimpleArgument : public SimpleArgument {
+    int64_t Default;
+
+  public:
+    DefaultSimpleArgument(const Record &Arg, StringRef Attr,
+                          std::string T, int64_t Default)
+      : SimpleArgument(Arg, Attr, T), Default(Default) {}
+
+    void writeAccessors(raw_ostream &OS) const override {
+      SimpleArgument::writeAccessors(OS);
+
+      OS << "\n\n  static const " << getType() << " Default" << getUpperName()
+         << " = " << Default << ";";
+    }
+  };
+
   class StringArgument : public Argument {
   public:
-    StringArgument(Record &Arg, StringRef Attr)
+    StringArgument(const Record &Arg, StringRef Attr)
       : Argument(Arg, Attr)
     {}
 
-    void writeAccessors(raw_ostream &OS) const {
+    void writeAccessors(raw_ostream &OS) const override {
       OS << "  llvm::StringRef get" << getUpperName() << "() const {\n";
       OS << "    return llvm::StringRef(" << getLowerName() << ", "
          << getLowerName() << "Length);\n";
@@ -245,45 +328,45 @@
          << getLowerName() << "Length);\n";
       OS << "  }";
     }
-    void writeCloneArgs(raw_ostream &OS) const {
+    void writeCloneArgs(raw_ostream &OS) const override {
       OS << "get" << getUpperName() << "()";
     }
-    void writeTemplateInstantiationArgs(raw_ostream &OS) const {
+    void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
       OS << "A->get" << getUpperName() << "()";
     }
-    void writeCtorBody(raw_ostream &OS) const {
+    void writeCtorBody(raw_ostream &OS) const override {
       OS << "      std::memcpy(" << getLowerName() << ", " << getUpperName()
          << ".data(), " << getLowerName() << "Length);";
     }
-    void writeCtorInitializers(raw_ostream &OS) const {
+    void writeCtorInitializers(raw_ostream &OS) const override {
       OS << getLowerName() << "Length(" << getUpperName() << ".size()),"
          << getLowerName() << "(new (Ctx, 1) char[" << getLowerName()
          << "Length])";
     }
-    void writeCtorDefaultInitializers(raw_ostream &OS) const {
+    void writeCtorDefaultInitializers(raw_ostream &OS) const override {
       OS << getLowerName() << "Length(0)," << getLowerName() << "(0)";
     }
-    void writeCtorParameters(raw_ostream &OS) const {
+    void writeCtorParameters(raw_ostream &OS) const override {
       OS << "llvm::StringRef " << getUpperName();
     }
-    void writeDeclarations(raw_ostream &OS) const {
+    void writeDeclarations(raw_ostream &OS) const override {
       OS << "unsigned " << getLowerName() << "Length;\n";
       OS << "char *" << getLowerName() << ";";
     }
-    void writePCHReadDecls(raw_ostream &OS) const {
+    void writePCHReadDecls(raw_ostream &OS) const override {
       OS << "    std::string " << getLowerName()
          << "= ReadString(Record, Idx);\n";
     }
-    void writePCHReadArgs(raw_ostream &OS) const {
+    void writePCHReadArgs(raw_ostream &OS) const override {
       OS << getLowerName();
     }
-    void writePCHWrite(raw_ostream &OS) const {
+    void writePCHWrite(raw_ostream &OS) const override {
       OS << "    AddString(SA->get" << getUpperName() << "(), Record);\n";
     }
-    void writeValue(raw_ostream &OS) const {
+    void writeValue(raw_ostream &OS) const override {
       OS << "\\\"\" << get" << getUpperName() << "() << \"\\\"";
     }
-    void writeDump(raw_ostream &OS) const {
+    void writeDump(raw_ostream &OS) const override {
       OS << "    OS << \" \\\"\" << SA->get" << getUpperName()
          << "() << \"\\\"\";\n";
     }
@@ -291,11 +374,11 @@
 
   class AlignedArgument : public Argument {
   public:
-    AlignedArgument(Record &Arg, StringRef Attr)
+    AlignedArgument(const Record &Arg, StringRef Attr)
       : Argument(Arg, Attr)
     {}
 
-    void writeAccessors(raw_ostream &OS) const {
+    void writeAccessors(raw_ostream &OS) const override {
       OS << "  bool is" << getUpperName() << "Dependent() const;\n";
 
       OS << "  unsigned get" << getUpperName() << "(ASTContext &Ctx) const;\n";
@@ -314,7 +397,7 @@
       OS << "    return " << getLowerName() << "Type;\n";
       OS << "  }";
     }
-    void writeAccessorDefinitions(raw_ostream &OS) const {
+    void writeAccessorDefinitions(raw_ostream &OS) const override {
       OS << "bool " << getAttrName() << "Attr::is" << getUpperName()
          << "Dependent() const {\n";
       OS << "  if (is" << getLowerName() << "Expr)\n";
@@ -342,17 +425,17 @@
       OS << "    return 0; // FIXME\n";
       OS << "}\n";
     }
-    void writeCloneArgs(raw_ostream &OS) const {
+    void writeCloneArgs(raw_ostream &OS) const override {
       OS << "is" << getLowerName() << "Expr, is" << getLowerName()
          << "Expr ? static_cast<void*>(" << getLowerName()
          << "Expr) : " << getLowerName()
          << "Type";
     }
-    void writeTemplateInstantiationArgs(raw_ostream &OS) const {
+    void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
       // FIXME: move the definition in Sema::InstantiateAttrs to here.
       // In the meantime, aligned attributes are cloned.
     }
-    void writeCtorBody(raw_ostream &OS) const {
+    void writeCtorBody(raw_ostream &OS) const override {
       OS << "    if (is" << getLowerName() << "Expr)\n";
       OS << "       " << getLowerName() << "Expr = reinterpret_cast<Expr *>("
          << getUpperName() << ");\n";
@@ -361,26 +444,29 @@
          << "Type = reinterpret_cast<TypeSourceInfo *>(" << getUpperName()
          << ");";
     }
-    void writeCtorInitializers(raw_ostream &OS) const {
+    void writeCtorInitializers(raw_ostream &OS) const override {
       OS << "is" << getLowerName() << "Expr(Is" << getUpperName() << "Expr)";
     }
-    void writeCtorDefaultInitializers(raw_ostream &OS) const {
+    void writeCtorDefaultInitializers(raw_ostream &OS) const override {
       OS << "is" << getLowerName() << "Expr(false)";
     }
-    void writeCtorParameters(raw_ostream &OS) const {
+    void writeCtorParameters(raw_ostream &OS) const override {
       OS << "bool Is" << getUpperName() << "Expr, void *" << getUpperName();
     }
-    void writeDeclarations(raw_ostream &OS) const {
+    void writeImplicitCtorArgs(raw_ostream &OS) const override {
+      OS << "Is" << getUpperName() << "Expr, " << getUpperName();
+    }
+    void writeDeclarations(raw_ostream &OS) const override {
       OS << "bool is" << getLowerName() << "Expr;\n";
       OS << "union {\n";
       OS << "Expr *" << getLowerName() << "Expr;\n";
       OS << "TypeSourceInfo *" << getLowerName() << "Type;\n";
       OS << "};";
     }
-    void writePCHReadArgs(raw_ostream &OS) const {
+    void writePCHReadArgs(raw_ostream &OS) const override {
       OS << "is" << getLowerName() << "Expr, " << getLowerName() << "Ptr";
     }
-    void writePCHReadDecls(raw_ostream &OS) const {
+    void writePCHReadDecls(raw_ostream &OS) const override {
       OS << "    bool is" << getLowerName() << "Expr = Record[Idx++];\n";
       OS << "    void *" << getLowerName() << "Ptr;\n";
       OS << "    if (is" << getLowerName() << "Expr)\n";
@@ -389,7 +475,7 @@
       OS << "      " << getLowerName()
          << "Ptr = GetTypeSourceInfo(F, Record, Idx);\n";
     }
-    void writePCHWrite(raw_ostream &OS) const {
+    void writePCHWrite(raw_ostream &OS) const override {
       OS << "    Record.push_back(SA->is" << getUpperName() << "Expr());\n";
       OS << "    if (SA->is" << getUpperName() << "Expr())\n";
       OS << "      AddStmt(SA->get" << getUpperName() << "Expr());\n";
@@ -397,14 +483,16 @@
       OS << "      AddTypeSourceInfo(SA->get" << getUpperName()
          << "Type(), Record);\n";
     }
-    void writeValue(raw_ostream &OS) const {
-      OS << "\";\n"
-         << "  " << getLowerName() << "Expr->printPretty(OS, 0, Policy);\n"
-         << "  OS << \"";
+    void writeValue(raw_ostream &OS) const override {
+      OS << "\";\n";
+      OS << "    assert(is" << getLowerName() << "Expr && " << getLowerName()
+         << "Expr != nullptr);\n";
+      OS << "    " << getLowerName() << "Expr->printPretty(OS, 0, Policy);\n";
+      OS << "    OS << \"";
     }
-    void writeDump(raw_ostream &OS) const {
+    void writeDump(raw_ostream &OS) const override {
     }
-    void writeDumpChildren(raw_ostream &OS) const {
+    void writeDumpChildren(raw_ostream &OS) const override {
       OS << "    if (SA->is" << getUpperName() << "Expr()) {\n";
       OS << "      lastChild();\n";
       OS << "      dumpStmt(SA->get" << getUpperName() << "Expr());\n";
@@ -412,148 +500,157 @@
       OS << "      dumpType(SA->get" << getUpperName()
          << "Type()->getType());\n";
     }
-    void writeHasChildren(raw_ostream &OS) const {
+    void writeHasChildren(raw_ostream &OS) const override {
       OS << "SA->is" << getUpperName() << "Expr()";
     }
   };
 
   class VariadicArgument : public Argument {
-    std::string type;
+    std::string Type, ArgName, ArgSizeName, RangeName;
 
   public:
-    VariadicArgument(Record &Arg, StringRef Attr, std::string T)
-      : Argument(Arg, Attr), type(T)
-    {}
+    VariadicArgument(const Record &Arg, StringRef Attr, std::string T)
+        : Argument(Arg, Attr), Type(T), ArgName(getLowerName().str() + "_"),
+          ArgSizeName(ArgName + "Size"), RangeName(getLowerName()) {}
 
-    std::string getType() const { return type; }
+    std::string getType() const { return Type; }
 
-    void writeAccessors(raw_ostream &OS) const {
-      OS << "  typedef " << type << "* " << getLowerName() << "_iterator;\n";
-      OS << "  " << getLowerName() << "_iterator " << getLowerName()
-         << "_begin() const {\n";
-      OS << "    return " << getLowerName() << ";\n";
-      OS << "  }\n";
-      OS << "  " << getLowerName() << "_iterator " << getLowerName()
-         << "_end() const {\n";
-      OS << "    return " << getLowerName() << " + " << getLowerName()
-         << "Size;\n";
-      OS << "  }\n";
-      OS << "  unsigned " << getLowerName() << "_size() const {\n"
-         << "    return " << getLowerName() << "Size;\n";
-      OS << "  }";
+    void writeAccessors(raw_ostream &OS) const override {
+      std::string IteratorType = getLowerName().str() + "_iterator";
+      std::string BeginFn = getLowerName().str() + "_begin()";
+      std::string EndFn = getLowerName().str() + "_end()";
+      
+      OS << "  typedef " << Type << "* " << IteratorType << ";\n";
+      OS << "  " << IteratorType << " " << BeginFn << " const {"
+         << " return " << ArgName << "; }\n";
+      OS << "  " << IteratorType << " " << EndFn << " const {"
+         << " return " << ArgName << " + " << ArgSizeName << "; }\n";
+      OS << "  unsigned " << getLowerName() << "_size() const {"
+         << " return " << ArgSizeName << "; }\n";
+      OS << "  llvm::iterator_range<" << IteratorType << "> " << RangeName
+         << "() const { return llvm::make_range(" << BeginFn << ", " << EndFn
+         << "); }\n";
     }
-    void writeCloneArgs(raw_ostream &OS) const {
-      OS << getLowerName() << ", " << getLowerName() << "Size";
+    void writeCloneArgs(raw_ostream &OS) const override {
+      OS << ArgName << ", " << ArgSizeName;
     }
-    void writeTemplateInstantiationArgs(raw_ostream &OS) const {
+    void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
       // This isn't elegant, but we have to go through public methods...
       OS << "A->" << getLowerName() << "_begin(), "
          << "A->" << getLowerName() << "_size()";
     }
-    void writeCtorBody(raw_ostream &OS) const {
-      // FIXME: memcpy is not safe on non-trivial types.
-      OS << "    std::memcpy(" << getLowerName() << ", " << getUpperName()
-         << ", " << getLowerName() << "Size * sizeof(" << getType() << "));\n";
+    void writeCtorBody(raw_ostream &OS) const override {
+      OS << "    std::copy(" << getUpperName() << ", " << getUpperName()
+         << " + " << ArgSizeName << ", " << ArgName << ");";
     }
-    void writeCtorInitializers(raw_ostream &OS) const {
-      OS << getLowerName() << "Size(" << getUpperName() << "Size), "
-         << getLowerName() << "(new (Ctx, 16) " << getType() << "["
-         << getLowerName() << "Size])";
+    void writeCtorInitializers(raw_ostream &OS) const override {
+      OS << ArgSizeName << "(" << getUpperName() << "Size), "
+         << ArgName << "(new (Ctx, 16) " << getType() << "["
+         << ArgSizeName << "])";
     }
-    void writeCtorDefaultInitializers(raw_ostream &OS) const {
-      OS << getLowerName() << "Size(0), " << getLowerName() << "(0)";
+    void writeCtorDefaultInitializers(raw_ostream &OS) const override {
+      OS << ArgSizeName << "(0), " << ArgName << "(nullptr)";
     }
-    void writeCtorParameters(raw_ostream &OS) const {
+    void writeCtorParameters(raw_ostream &OS) const override {
       OS << getType() << " *" << getUpperName() << ", unsigned "
          << getUpperName() << "Size";
     }
-    void writeDeclarations(raw_ostream &OS) const {
-      OS << "  unsigned " << getLowerName() << "Size;\n";
-      OS << "  " << getType() << " *" << getLowerName() << ";";
+    void writeImplicitCtorArgs(raw_ostream &OS) const override {
+      OS << getUpperName() << ", " << getUpperName() << "Size";
     }
-    void writePCHReadDecls(raw_ostream &OS) const {
+    void writeDeclarations(raw_ostream &OS) const override {
+      OS << "  unsigned " << ArgSizeName << ";\n";
+      OS << "  " << getType() << " *" << ArgName << ";";
+    }
+    void writePCHReadDecls(raw_ostream &OS) const override {
       OS << "  unsigned " << getLowerName() << "Size = Record[Idx++];\n";
-      OS << "  SmallVector<" << type << ", 4> " << getLowerName()
+      OS << "  SmallVector<" << Type << ", 4> " << getLowerName()
          << ";\n";
       OS << "  " << getLowerName() << ".reserve(" << getLowerName()
          << "Size);\n";
       OS << "    for (unsigned i = " << getLowerName() << "Size; i; --i)\n";
       
-      std::string read = ReadPCHRecord(type);
+      std::string read = ReadPCHRecord(Type);
       OS << "    " << getLowerName() << ".push_back(" << read << ");\n";
     }
-    void writePCHReadArgs(raw_ostream &OS) const {
+    void writePCHReadArgs(raw_ostream &OS) const override {
       OS << getLowerName() << ".data(), " << getLowerName() << "Size";
     }
-    void writePCHWrite(raw_ostream &OS) const{
+    void writePCHWrite(raw_ostream &OS) const override {
       OS << "    Record.push_back(SA->" << getLowerName() << "_size());\n";
-      OS << "    for (" << getAttrName() << "Attr::" << getLowerName()
-         << "_iterator i = SA->" << getLowerName() << "_begin(), e = SA->"
-         << getLowerName() << "_end(); i != e; ++i)\n";
-      OS << "      " << WritePCHRecord(type, "(*i)");
+      OS << "    for (auto &Val : SA->" << RangeName << "())\n";
+      OS << "      " << WritePCHRecord(Type, "Val");
     }
-    void writeValue(raw_ostream &OS) const {
+    void writeValue(raw_ostream &OS) const override {
       OS << "\";\n";
       OS << "  bool isFirst = true;\n"
-         << "  for (" << getAttrName() << "Attr::" << getLowerName()
-         << "_iterator i = " << getLowerName() << "_begin(), e = "
-         << getLowerName() << "_end(); i != e; ++i) {\n"
+         << "  for (const auto &Val : " << RangeName << "()) {\n"
          << "    if (isFirst) isFirst = false;\n"
          << "    else OS << \", \";\n"
-         << "    OS << *i;\n"
+         << "    OS << Val;\n"
          << "  }\n";
       OS << "  OS << \"";
     }
-    void writeDump(raw_ostream &OS) const {
-      OS << "    for (" << getAttrName() << "Attr::" << getLowerName()
-         << "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->"
-         << getLowerName() << "_end(); I != E; ++I)\n";
-      OS << "      OS << \" \" << *I;\n";
+    void writeDump(raw_ostream &OS) const override {
+      OS << "    for (const auto &Val : SA->" << RangeName << "())\n";
+      OS << "      OS << \" \" << Val;\n";
     }
   };
 
+  // Unique the enums, but maintain the original declaration ordering.
+  std::vector<std::string>
+  uniqueEnumsInOrder(const std::vector<std::string> &enums) {
+    std::vector<std::string> uniques;
+    std::set<std::string> unique_set(enums.begin(), enums.end());
+    for (const auto &i : enums) {
+      std::set<std::string>::iterator set_i = unique_set.find(i);
+      if (set_i != unique_set.end()) {
+        uniques.push_back(i);
+        unique_set.erase(set_i);
+      }
+    }
+    return uniques;
+  }
+
   class EnumArgument : public Argument {
     std::string type;
-    std::vector<StringRef> values, enums, uniques;
+    std::vector<std::string> values, enums, uniques;
   public:
-    EnumArgument(Record &Arg, StringRef Attr)
+    EnumArgument(const Record &Arg, StringRef Attr)
       : Argument(Arg, Attr), type(Arg.getValueAsString("Type")),
-        values(getValueAsListOfStrings(Arg, "Values")),
-        enums(getValueAsListOfStrings(Arg, "Enums")),
-        uniques(enums)
+        values(Arg.getValueAsListOfStrings("Values")),
+        enums(Arg.getValueAsListOfStrings("Enums")),
+        uniques(uniqueEnumsInOrder(enums))
     {
-      // Calculate the various enum values
-      std::sort(uniques.begin(), uniques.end());
-      uniques.erase(std::unique(uniques.begin(), uniques.end()), uniques.end());
       // FIXME: Emit a proper error
       assert(!uniques.empty());
     }
 
-    bool isEnumArg() const { return true; }
+    bool isEnumArg() const override { return true; }
 
-    void writeAccessors(raw_ostream &OS) const {
+    void writeAccessors(raw_ostream &OS) const override {
       OS << "  " << type << " get" << getUpperName() << "() const {\n";
       OS << "    return " << getLowerName() << ";\n";
       OS << "  }";
     }
-    void writeCloneArgs(raw_ostream &OS) const {
+    void writeCloneArgs(raw_ostream &OS) const override {
       OS << getLowerName();
     }
-    void writeTemplateInstantiationArgs(raw_ostream &OS) const {
+    void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
       OS << "A->get" << getUpperName() << "()";
     }
-    void writeCtorInitializers(raw_ostream &OS) const {
+    void writeCtorInitializers(raw_ostream &OS) const override {
       OS << getLowerName() << "(" << getUpperName() << ")";
     }
-    void writeCtorDefaultInitializers(raw_ostream &OS) const {
+    void writeCtorDefaultInitializers(raw_ostream &OS) const override {
       OS << getLowerName() << "(" << type << "(0))";
     }
-    void writeCtorParameters(raw_ostream &OS) const {
+    void writeCtorParameters(raw_ostream &OS) const override {
       OS << type << " " << getUpperName();
     }
-    void writeDeclarations(raw_ostream &OS) const {
-      std::vector<StringRef>::const_iterator i = uniques.begin(),
-                                             e = uniques.end();
+    void writeDeclarations(raw_ostream &OS) const override {
+      std::vector<std::string>::const_iterator i = uniques.begin(),
+                                               e = uniques.end();
       // The last one needs to not have a comma.
       --e;
 
@@ -566,26 +663,25 @@
       OS << "private:\n";
       OS << "  " << type << " " << getLowerName() << ";";
     }
-    void writePCHReadDecls(raw_ostream &OS) const {
+    void writePCHReadDecls(raw_ostream &OS) const override {
       OS << "    " << getAttrName() << "Attr::" << type << " " << getLowerName()
          << "(static_cast<" << getAttrName() << "Attr::" << type
          << ">(Record[Idx++]));\n";
     }
-    void writePCHReadArgs(raw_ostream &OS) const {
+    void writePCHReadArgs(raw_ostream &OS) const override {
       OS << getLowerName();
     }
-    void writePCHWrite(raw_ostream &OS) const {
+    void writePCHWrite(raw_ostream &OS) const override {
       OS << "Record.push_back(SA->get" << getUpperName() << "());\n";
     }
-    void writeValue(raw_ostream &OS) const {
+    void writeValue(raw_ostream &OS) const override {
       OS << "\" << get" << getUpperName() << "() << \"";
     }
-    void writeDump(raw_ostream &OS) const {
+    void writeDump(raw_ostream &OS) const override {
       OS << "    switch(SA->get" << getUpperName() << "()) {\n";
-      for (std::vector<StringRef>::const_iterator I = uniques.begin(),
-           E = uniques.end(); I != E; ++I) {
-        OS << "    case " << getAttrName() << "Attr::" << *I << ":\n";
-        OS << "      OS << \" " << *I << "\";\n";
+      for (const auto &I : uniques) {
+        OS << "    case " << getAttrName() << "Attr::" << I << ":\n";
+        OS << "      OS << \" " << I << "\";\n";
         OS << "      break;\n";
       }
       OS << "    }\n";
@@ -595,7 +691,7 @@
       OS << "  static bool ConvertStrTo" << type << "(StringRef Val, ";
       OS << type << " &Out) {\n";
       OS << "    Optional<" << type << "> R = llvm::StringSwitch<Optional<";
-      OS << type << "> >(Val)\n";
+      OS << type << ">>(Val)\n";
       for (size_t I = 0; I < enums.size(); ++I) {
         OS << "      .Case(\"" << values[I] << "\", ";
         OS << getAttrName() << "Attr::" << enums[I] << ")\n";
@@ -610,30 +706,26 @@
   
   class VariadicEnumArgument: public VariadicArgument {
     std::string type, QualifiedTypeName;
-    std::vector<StringRef> values, enums, uniques;
+    std::vector<std::string> values, enums, uniques;
   public:
-    VariadicEnumArgument(Record &Arg, StringRef Attr)
+    VariadicEnumArgument(const Record &Arg, StringRef Attr)
       : VariadicArgument(Arg, Attr, Arg.getValueAsString("Type")),
         type(Arg.getValueAsString("Type")),
-        values(getValueAsListOfStrings(Arg, "Values")),
-        enums(getValueAsListOfStrings(Arg, "Enums")),
-        uniques(enums)
+        values(Arg.getValueAsListOfStrings("Values")),
+        enums(Arg.getValueAsListOfStrings("Enums")),
+        uniques(uniqueEnumsInOrder(enums))
     {
-      // Calculate the various enum values
-      std::sort(uniques.begin(), uniques.end());
-      uniques.erase(std::unique(uniques.begin(), uniques.end()), uniques.end());
-      
       QualifiedTypeName = getAttrName().str() + "Attr::" + type;
       
       // FIXME: Emit a proper error
       assert(!uniques.empty());
     }
 
-    bool isVariadicEnumArg() const { return true; }
+    bool isVariadicEnumArg() const override { return true; }
     
-    void writeDeclarations(raw_ostream &OS) const {
-      std::vector<StringRef>::const_iterator i = uniques.begin(),
-                                             e = uniques.end();
+    void writeDeclarations(raw_ostream &OS) const override {
+      std::vector<std::string>::const_iterator i = uniques.begin(),
+                                               e = uniques.end();
       // The last one needs to not have a comma.
       --e;
 
@@ -647,21 +739,20 @@
       
       VariadicArgument::writeDeclarations(OS);
     }
-    void writeDump(raw_ostream &OS) const {
+    void writeDump(raw_ostream &OS) const override {
       OS << "    for (" << getAttrName() << "Attr::" << getLowerName()
          << "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->"
          << getLowerName() << "_end(); I != E; ++I) {\n";
       OS << "      switch(*I) {\n";
-      for (std::vector<StringRef>::const_iterator UI = uniques.begin(),
-           UE = uniques.end(); UI != UE; ++UI) {
-        OS << "    case " << getAttrName() << "Attr::" << *UI << ":\n";
-        OS << "      OS << \" " << *UI << "\";\n";
+      for (const auto &UI : uniques) {
+        OS << "    case " << getAttrName() << "Attr::" << UI << ":\n";
+        OS << "      OS << \" " << UI << "\";\n";
         OS << "      break;\n";
       }
       OS << "      }\n";
       OS << "    }\n";
     }
-    void writePCHReadDecls(raw_ostream &OS) const {
+    void writePCHReadDecls(raw_ostream &OS) const override {
       OS << "    unsigned " << getLowerName() << "Size = Record[Idx++];\n";
       OS << "    SmallVector<" << QualifiedTypeName << ", 4> " << getLowerName()
          << ";\n";
@@ -671,7 +762,7 @@
       OS << "      " << getLowerName() << ".push_back(" << "static_cast<"
          << QualifiedTypeName << ">(Record[Idx++]));\n";
     }
-    void writePCHWrite(raw_ostream &OS) const{
+    void writePCHWrite(raw_ostream &OS) const override {
       OS << "    Record.push_back(SA->" << getLowerName() << "_size());\n";
       OS << "    for (" << getAttrName() << "Attr::" << getLowerName()
          << "_iterator i = SA->" << getLowerName() << "_begin(), e = SA->"
@@ -682,7 +773,7 @@
       OS << "  static bool ConvertStrTo" << type << "(StringRef Val, ";
       OS << type << " &Out) {\n";
       OS << "    Optional<" << type << "> R = llvm::StringSwitch<Optional<";
-      OS << type << "> >(Val)\n";
+      OS << type << ">>(Val)\n";
       for (size_t I = 0; I < enums.size(); ++I) {
         OS << "      .Case(\"" << values[I] << "\", ";
         OS << getAttrName() << "Attr::" << enums[I] << ")\n";
@@ -697,11 +788,11 @@
 
   class VersionArgument : public Argument {
   public:
-    VersionArgument(Record &Arg, StringRef Attr)
+    VersionArgument(const Record &Arg, StringRef Attr)
       : Argument(Arg, Attr)
     {}
 
-    void writeAccessors(raw_ostream &OS) const {
+    void writeAccessors(raw_ostream &OS) const override {
       OS << "  VersionTuple get" << getUpperName() << "() const {\n";
       OS << "    return " << getLowerName() << ";\n";
       OS << "  }\n";
@@ -710,55 +801,59 @@
       OS << "    " << getLowerName() << " = V;\n";
       OS << "  }";
     }
-    void writeCloneArgs(raw_ostream &OS) const {
+    void writeCloneArgs(raw_ostream &OS) const override {
       OS << "get" << getUpperName() << "()";
     }
-    void writeTemplateInstantiationArgs(raw_ostream &OS) const {
+    void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
       OS << "A->get" << getUpperName() << "()";
     }
-    void writeCtorBody(raw_ostream &OS) const {
-    }
-    void writeCtorInitializers(raw_ostream &OS) const {
+    void writeCtorInitializers(raw_ostream &OS) const override {
       OS << getLowerName() << "(" << getUpperName() << ")";
     }
-    void writeCtorDefaultInitializers(raw_ostream &OS) const {
+    void writeCtorDefaultInitializers(raw_ostream &OS) const override {
       OS << getLowerName() << "()";
     }
-    void writeCtorParameters(raw_ostream &OS) const {
+    void writeCtorParameters(raw_ostream &OS) const override {
       OS << "VersionTuple " << getUpperName();
     }
-    void writeDeclarations(raw_ostream &OS) const {
+    void writeDeclarations(raw_ostream &OS) const override {
       OS << "VersionTuple " << getLowerName() << ";\n";
     }
-    void writePCHReadDecls(raw_ostream &OS) const {
+    void writePCHReadDecls(raw_ostream &OS) const override {
       OS << "    VersionTuple " << getLowerName()
          << "= ReadVersionTuple(Record, Idx);\n";
     }
-    void writePCHReadArgs(raw_ostream &OS) const {
+    void writePCHReadArgs(raw_ostream &OS) const override {
       OS << getLowerName();
     }
-    void writePCHWrite(raw_ostream &OS) const {
+    void writePCHWrite(raw_ostream &OS) const override {
       OS << "    AddVersionTuple(SA->get" << getUpperName() << "(), Record);\n";
     }
-    void writeValue(raw_ostream &OS) const {
+    void writeValue(raw_ostream &OS) const override {
       OS << getLowerName() << "=\" << get" << getUpperName() << "() << \"";
     }
-    void writeDump(raw_ostream &OS) const {
+    void writeDump(raw_ostream &OS) const override {
       OS << "    OS << \" \" << SA->get" << getUpperName() << "();\n";
     }
   };
 
   class ExprArgument : public SimpleArgument {
   public:
-    ExprArgument(Record &Arg, StringRef Attr)
+    ExprArgument(const Record &Arg, StringRef Attr)
       : SimpleArgument(Arg, Attr, "Expr *")
     {}
 
-    void writeTemplateInstantiationArgs(raw_ostream &OS) const {
+    void writeASTVisitorTraversal(raw_ostream &OS) const override {
+      OS << "  if (!"
+         << "getDerived().TraverseStmt(A->get" << getUpperName() << "()))\n";
+      OS << "    return false;\n";
+    }
+
+    void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
       OS << "tempInst" << getUpperName();
     }
 
-    void writeTemplateInstantiation(raw_ostream &OS) const {
+    void writeTemplateInstantiation(raw_ostream &OS) const override {
       OS << "      " << getType() << " tempInst" << getUpperName() << ";\n";
       OS << "      {\n";
       OS << "        EnterExpressionEvaluationContext "
@@ -766,32 +861,44 @@
       OS << "        ExprResult " << "Result = S.SubstExpr("
          << "A->get" << getUpperName() << "(), TemplateArgs);\n";
       OS << "        tempInst" << getUpperName() << " = "
-         << "Result.takeAs<Expr>();\n";
+         << "Result.getAs<Expr>();\n";
       OS << "      }\n";
     }
 
-    void writeDump(raw_ostream &OS) const {
-    }
+    void writeDump(raw_ostream &OS) const override {}
 
-    void writeDumpChildren(raw_ostream &OS) const {
+    void writeDumpChildren(raw_ostream &OS) const override {
       OS << "    lastChild();\n";
       OS << "    dumpStmt(SA->get" << getUpperName() << "());\n";
     }
-    void writeHasChildren(raw_ostream &OS) const { OS << "true"; }
+    void writeHasChildren(raw_ostream &OS) const override { OS << "true"; }
   };
 
   class VariadicExprArgument : public VariadicArgument {
   public:
-    VariadicExprArgument(Record &Arg, StringRef Attr)
+    VariadicExprArgument(const Record &Arg, StringRef Attr)
       : VariadicArgument(Arg, Attr, "Expr *")
     {}
 
-    void writeTemplateInstantiationArgs(raw_ostream &OS) const {
+    void writeASTVisitorTraversal(raw_ostream &OS) const override {
+      OS << "  {\n";
+      OS << "    " << getType() << " *I = A->" << getLowerName()
+         << "_begin();\n";
+      OS << "    " << getType() << " *E = A->" << getLowerName()
+         << "_end();\n";
+      OS << "    for (; I != E; ++I) {\n";
+      OS << "      if (!getDerived().TraverseStmt(*I))\n";
+      OS << "        return false;\n";
+      OS << "    }\n";
+      OS << "  }\n";
+    }
+
+    void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
       OS << "tempInst" << getUpperName() << ", "
          << "A->" << getLowerName() << "_size()";
     }
 
-    void writeTemplateInstantiation(raw_ostream &OS) const {
+    void writeTemplateInstantiation(raw_ostream &OS) const override {
       OS << "      " << getType() << " *tempInst" << getUpperName()
          << " = new (C, 16) " << getType()
          << "[A->" << getLowerName() << "_size()];\n";
@@ -806,15 +913,14 @@
          << "_end();\n";
       OS << "        for (; I != E; ++I, ++TI) {\n";
       OS << "          ExprResult Result = S.SubstExpr(*I, TemplateArgs);\n";
-      OS << "          *TI = Result.takeAs<Expr>();\n";
+      OS << "          *TI = Result.getAs<Expr>();\n";
       OS << "        }\n";
       OS << "      }\n";
     }
 
-    void writeDump(raw_ostream &OS) const {
-    }
+    void writeDump(raw_ostream &OS) const override {}
 
-    void writeDumpChildren(raw_ostream &OS) const {
+    void writeDumpChildren(raw_ostream &OS) const override {
       OS << "    for (" << getAttrName() << "Attr::" << getLowerName()
          << "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->"
          << getLowerName() << "_end(); I != E; ++I) {\n";
@@ -824,7 +930,7 @@
       OS << "    }\n";
     }
 
-    void writeHasChildren(raw_ostream &OS) const {
+    void writeHasChildren(raw_ostream &OS) const override {
       OS << "SA->" << getLowerName() << "_begin() != "
          << "SA->" << getLowerName() << "_end()";
     }
@@ -832,11 +938,11 @@
 
   class TypeArgument : public SimpleArgument {
   public:
-    TypeArgument(Record &Arg, StringRef Attr)
+    TypeArgument(const Record &Arg, StringRef Attr)
       : SimpleArgument(Arg, Attr, "TypeSourceInfo *")
     {}
 
-    void writeAccessors(raw_ostream &OS) const {
+    void writeAccessors(raw_ostream &OS) const override {
       OS << "  QualType get" << getUpperName() << "() const {\n";
       OS << "    return " << getLowerName() << "->getType();\n";
       OS << "  }";
@@ -844,22 +950,23 @@
       OS << "    return " << getLowerName() << ";\n";
       OS << "  }";
     }
-    void writeTemplateInstantiationArgs(raw_ostream &OS) const {
+    void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
       OS << "A->get" << getUpperName() << "Loc()";
     }
-    void writePCHWrite(raw_ostream &OS) const {
+    void writePCHWrite(raw_ostream &OS) const override {
       OS << "    " << WritePCHRecord(
           getType(), "SA->get" + std::string(getUpperName()) + "Loc()");
     }
   };
 }
 
-static Argument *createArgument(Record &Arg, StringRef Attr,
-                                Record *Search = 0) {
+static std::unique_ptr<Argument>
+createArgument(const Record &Arg, StringRef Attr,
+               const Record *Search = nullptr) {
   if (!Search)
     Search = &Arg;
 
-  Argument *Ptr = 0;
+  Argument *Ptr = nullptr;
   llvm::StringRef ArgName = Search->getName();
 
   if (ArgName == "AlignedArgument") Ptr = new AlignedArgument(Arg, Attr);
@@ -869,15 +976,19 @@
     Ptr = new SimpleArgument(Arg, Attr, "FunctionDecl *");
   else if (ArgName == "IdentifierArgument")
     Ptr = new SimpleArgument(Arg, Attr, "IdentifierInfo *");
+  else if (ArgName == "DefaultBoolArgument")
+    Ptr = new DefaultSimpleArgument(Arg, Attr, "bool",
+                                    Arg.getValueAsBit("Default"));
   else if (ArgName == "BoolArgument") Ptr = new SimpleArgument(Arg, Attr, 
                                                                "bool");
+  else if (ArgName == "DefaultIntArgument")
+    Ptr = new DefaultSimpleArgument(Arg, Attr, "int",
+                                    Arg.getValueAsInt("Default"));
   else if (ArgName == "IntArgument") Ptr = new SimpleArgument(Arg, Attr, "int");
   else if (ArgName == "StringArgument") Ptr = new StringArgument(Arg, Attr);
   else if (ArgName == "TypeArgument") Ptr = new TypeArgument(Arg, Attr);
   else if (ArgName == "UnsignedArgument")
     Ptr = new SimpleArgument(Arg, Attr, "unsigned");
-  else if (ArgName == "SourceLocArgument")
-    Ptr = new SimpleArgument(Arg, Attr, "SourceLocation");
   else if (ArgName == "VariadicUnsignedArgument")
     Ptr = new VariadicArgument(Arg, Attr, "unsigned");
   else if (ArgName == "VariadicEnumArgument")
@@ -888,10 +999,10 @@
     Ptr = new VersionArgument(Arg, Attr);
 
   if (!Ptr) {
+    // Search in reverse order so that the most-derived type is handled first.
     std::vector<Record*> Bases = Search->getSuperClasses();
-    for (std::vector<Record*>::iterator i = Bases.begin(), e = Bases.end();
-         i != e; ++i) {
-      Ptr = createArgument(Arg, Attr, *i);
+    for (const auto *Base : llvm::make_range(Bases.rbegin(), Bases.rend())) {
+      Ptr = createArgument(Arg, Attr, Base).release();
       if (Ptr)
         break;
     }
@@ -900,7 +1011,7 @@
   if (Ptr && Arg.getValueAsBit("Optional"))
     Ptr->setOptional(true);
 
-  return Ptr;
+  return std::unique_ptr<Argument>(Ptr);
 }
 
 static void writeAvailabilityValue(raw_ostream &OS) {
@@ -912,14 +1023,39 @@
      << "  OS << \"";
 }
 
-static void writePrettyPrintFunction(Record &R, std::vector<Argument*> &Args,
-                                     raw_ostream &OS) {
-  std::vector<Record*> Spellings = R.getValueAsListOfDefs("Spellings");
+static void writeGetSpellingFunction(Record &R, raw_ostream &OS) {
+  std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(R);
+
+  OS << "const char *" << R.getName() << "Attr::getSpelling() const {\n";
+  if (Spellings.empty()) {
+    OS << "  return \"(No spelling)\";\n}\n\n";
+    return;
+  }
+
+  OS << "  switch (SpellingListIndex) {\n"
+        "  default:\n"
+        "    llvm_unreachable(\"Unknown attribute spelling!\");\n"
+        "    return \"(No spelling)\";\n";
+
+  for (unsigned I = 0; I < Spellings.size(); ++I)
+    OS << "  case " << I << ":\n"
+          "    return \"" << Spellings[I].name() << "\";\n";
+  // End of the switch statement.
+  OS << "  }\n";
+  // End of the getSpelling function.
+  OS << "}\n\n";
+}
+
+static void
+writePrettyPrintFunction(Record &R,
+                         const std::vector<std::unique_ptr<Argument>> &Args,
+                         raw_ostream &OS) {
+  std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(R);
 
   OS << "void " << R.getName() << "Attr::printPretty("
     << "raw_ostream &OS, const PrintingPolicy &Policy) const {\n";
 
-  if (Spellings.size() == 0) {
+  if (Spellings.empty()) {
     OS << "}\n\n";
     return;
   }
@@ -936,8 +1072,8 @@
     // The actual spelling of the name and namespace (if applicable)
     // of an attribute without considering prefix and suffix.
     llvm::SmallString<64> Spelling;
-    std::string Name = Spellings[I]->getValueAsString("Name");
-    std::string Variety = Spellings[I]->getValueAsString("Variety");
+    std::string Name = Spellings[I].name();
+    std::string Variety = Spellings[I].variety();
 
     if (Variety == "GNU") {
       Prefix = " __attribute__((";
@@ -945,8 +1081,8 @@
     } else if (Variety == "CXX11") {
       Prefix = " [[";
       Suffix = "]]";
-      std::string Namespace = Spellings[I]->getValueAsString("Namespace");
-      if (Namespace != "") {
+      std::string Namespace = Spellings[I].nameSpace();
+      if (!Namespace.empty()) {
         Spelling += Namespace;
         Spelling += "::";
       }
@@ -956,6 +1092,14 @@
     } else if (Variety == "Keyword") {
       Prefix = " ";
       Suffix = "";
+    } else if (Variety == "Pragma") {
+      Prefix = "#pragma ";
+      Suffix = "\n";
+      std::string Namespace = Spellings[I].nameSpace();
+      if (!Namespace.empty()) {
+        Spelling += Namespace;
+        Spelling += " ";
+      }
     } else {
       llvm_unreachable("Unknown attribute syntax variety!");
     }
@@ -966,18 +1110,27 @@
       "  case " << I << " : {\n"
       "    OS << \"" + Prefix.str() + Spelling.str();
 
-    if (Args.size()) OS << "(";
+    if (Variety == "Pragma") {
+      OS << " \";\n";
+      OS << "    printPrettyPragma(OS, Policy);\n";
+      OS << "    break;\n";
+      OS << "  }\n";
+      continue;
+    }
+
+    if (!Args.empty())
+      OS << "(";
     if (Spelling == "availability") {
       writeAvailabilityValue(OS);
     } else {
-      for (std::vector<Argument*>::const_iterator I = Args.begin(),
-           E = Args.end(); I != E; ++ I) {
+      for (auto I = Args.begin(), E = Args.end(); I != E; ++ I) {
         if (I != Args.begin()) OS << ", ";
         (*I)->writeValue(OS);
       }
     }
 
-    if (Args.size()) OS << ")";
+    if (!Args.empty())
+      OS << ")";
     OS << Suffix.str() + "\";\n";
 
     OS <<
@@ -992,19 +1145,18 @@
 }
 
 /// \brief Return the index of a spelling in a spelling list.
-static unsigned getSpellingListIndex(const std::vector<Record*> &SpellingList,
-                                     const Record &Spelling) {
+static unsigned
+getSpellingListIndex(const std::vector<FlattenedSpelling> &SpellingList,
+                     const FlattenedSpelling &Spelling) {
   assert(SpellingList.size() && "Spelling list is empty!");
 
   for (unsigned Index = 0; Index < SpellingList.size(); ++Index) {
-    Record *S = SpellingList[Index];
-    if (S->getValueAsString("Variety") != Spelling.getValueAsString("Variety"))
+    const FlattenedSpelling &S = SpellingList[Index];
+    if (S.variety() != Spelling.variety())
       continue;
-    if (S->getValueAsString("Variety") == "CXX11" &&
-        S->getValueAsString("Namespace") !=
-        Spelling.getValueAsString("Namespace"))
+    if (S.nameSpace() != Spelling.nameSpace())
       continue;
-    if (S->getValueAsString("Name") != Spelling.getValueAsString("Name"))
+    if (S.name() != Spelling.name())
       continue;
 
     return Index;
@@ -1013,21 +1165,19 @@
   llvm_unreachable("Unknown spelling!");
 }
 
-static void writeAttrAccessorDefinition(Record &R, raw_ostream &OS) {
+static void writeAttrAccessorDefinition(const Record &R, raw_ostream &OS) {
   std::vector<Record*> Accessors = R.getValueAsListOfDefs("Accessors");
-  for (std::vector<Record*>::const_iterator I = Accessors.begin(),
-       E = Accessors.end(); I != E; ++I) {
-    Record *Accessor = *I;
+  for (const auto *Accessor : Accessors) {
     std::string Name = Accessor->getValueAsString("Name");
-    std::vector<Record*> Spellings = Accessor->getValueAsListOfDefs(
-      "Spellings");
-    std::vector<Record*> SpellingList = R.getValueAsListOfDefs("Spellings");
+    std::vector<FlattenedSpelling> Spellings = 
+      GetFlattenedSpellings(*Accessor);
+    std::vector<FlattenedSpelling> SpellingList = GetFlattenedSpellings(R);
     assert(SpellingList.size() &&
            "Attribute with empty spelling list can't have accessors!");
 
     OS << "  bool " << Name << "() const { return SpellingListIndex == ";
     for (unsigned Index = 0; Index < Spellings.size(); ++Index) {
-      OS << getSpellingListIndex(SpellingList, *Spellings[Index]);
+      OS << getSpellingListIndex(SpellingList, Spellings[Index]);
       if (Index != Spellings.size() -1)
         OS << " ||\n    SpellingListIndex == ";
       else
@@ -1036,6 +1186,173 @@
   }
 }
 
+static bool
+SpellingNamesAreCommon(const std::vector<FlattenedSpelling>& Spellings) {
+  assert(!Spellings.empty() && "An empty list of spellings was provided");
+  std::string FirstName = NormalizeNameForSpellingComparison(
+    Spellings.front().name());
+  for (const auto &Spelling :
+       llvm::make_range(std::next(Spellings.begin()), Spellings.end())) {
+    std::string Name = NormalizeNameForSpellingComparison(Spelling.name());
+    if (Name != FirstName)
+      return false;
+  }
+  return true;
+}
+
+typedef std::map<unsigned, std::string> SemanticSpellingMap;
+static std::string
+CreateSemanticSpellings(const std::vector<FlattenedSpelling> &Spellings,
+                        SemanticSpellingMap &Map) {
+  // The enumerants are automatically generated based on the variety,
+  // namespace (if present) and name for each attribute spelling. However,
+  // care is taken to avoid trampling on the reserved namespace due to
+  // underscores.
+  std::string Ret("  enum Spelling {\n");
+  std::set<std::string> Uniques;
+  unsigned Idx = 0;
+  for (auto I = Spellings.begin(), E = Spellings.end(); I != E; ++I, ++Idx) {
+    const FlattenedSpelling &S = *I;
+    std::string Variety = S.variety();
+    std::string Spelling = S.name();
+    std::string Namespace = S.nameSpace();
+    std::string EnumName = "";
+
+    EnumName += (Variety + "_");
+    if (!Namespace.empty())
+      EnumName += (NormalizeNameForSpellingComparison(Namespace).str() +
+      "_");
+    EnumName += NormalizeNameForSpellingComparison(Spelling);
+
+    // Even if the name is not unique, this spelling index corresponds to a
+    // particular enumerant name that we've calculated.
+    Map[Idx] = EnumName;
+
+    // Since we have been stripping underscores to avoid trampling on the
+    // reserved namespace, we may have inadvertently created duplicate
+    // enumerant names. These duplicates are not considered part of the
+    // semantic spelling, and can be elided.
+    if (Uniques.find(EnumName) != Uniques.end())
+      continue;
+
+    Uniques.insert(EnumName);
+    if (I != Spellings.begin())
+      Ret += ",\n";
+    Ret += "    " + EnumName;
+  }
+  Ret += "\n  };\n\n";
+  return Ret;
+}
+
+void WriteSemanticSpellingSwitch(const std::string &VarName,
+                                 const SemanticSpellingMap &Map,
+                                 raw_ostream &OS) {
+  OS << "  switch (" << VarName << ") {\n    default: "
+    << "llvm_unreachable(\"Unknown spelling list index\");\n";
+  for (const auto &I : Map)
+    OS << "    case " << I.first << ": return " << I.second << ";\n";
+  OS << "  }\n";
+}
+
+// Emits the LateParsed property for attributes.
+static void emitClangAttrLateParsedList(RecordKeeper &Records, raw_ostream &OS) {
+  OS << "#if defined(CLANG_ATTR_LATE_PARSED_LIST)\n";
+  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
+
+  for (const auto *Attr : Attrs) {
+    bool LateParsed = Attr->getValueAsBit("LateParsed");
+
+    if (LateParsed) {
+      std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(*Attr);
+
+      // FIXME: Handle non-GNU attributes
+      for (const auto &I : Spellings) {
+        if (I.variety() != "GNU")
+          continue;
+        OS << ".Case(\"" << I.name() << "\", " << LateParsed << ")\n";
+      }
+    }
+  }
+  OS << "#endif // CLANG_ATTR_LATE_PARSED_LIST\n\n";
+}
+
+/// \brief Emits the first-argument-is-type property for attributes.
+static void emitClangAttrTypeArgList(RecordKeeper &Records, raw_ostream &OS) {
+  OS << "#if defined(CLANG_ATTR_TYPE_ARG_LIST)\n";
+  std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
+
+  for (const auto *Attr : Attrs) {
+    // Determine whether the first argument is a type.
+    std::vector<Record *> Args = Attr->getValueAsListOfDefs("Args");
+    if (Args.empty())
+      continue;
+
+    if (Args[0]->getSuperClasses().back()->getName() != "TypeArgument")
+      continue;
+
+    // All these spellings take a single type argument.
+    std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(*Attr);
+    std::set<std::string> Emitted;
+    for (const auto &S : Spellings) {
+      if (Emitted.insert(S.name()).second)
+        OS << ".Case(\"" << S.name() << "\", " << "true" << ")\n";
+    }
+  }
+  OS << "#endif // CLANG_ATTR_TYPE_ARG_LIST\n\n";
+}
+
+/// \brief Emits the parse-arguments-in-unevaluated-context property for
+/// attributes.
+static void emitClangAttrArgContextList(RecordKeeper &Records, raw_ostream &OS) {
+  OS << "#if defined(CLANG_ATTR_ARG_CONTEXT_LIST)\n";
+  ParsedAttrMap Attrs = getParsedAttrList(Records);
+  for (const auto &I : Attrs) {
+    const Record &Attr = *I.second;
+
+    if (!Attr.getValueAsBit("ParseArgumentsAsUnevaluated"))
+      continue;
+
+    // All these spellings take are parsed unevaluated.
+    std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attr);
+    std::set<std::string> Emitted;
+    for (const auto &S : Spellings) {
+      if (Emitted.insert(S.name()).second)
+        OS << ".Case(\"" << S.name() << "\", " << "true" << ")\n";
+    }
+  }
+  OS << "#endif // CLANG_ATTR_ARG_CONTEXT_LIST\n\n";
+}
+
+static bool isIdentifierArgument(Record *Arg) {
+  return !Arg->getSuperClasses().empty() &&
+    llvm::StringSwitch<bool>(Arg->getSuperClasses().back()->getName())
+    .Case("IdentifierArgument", true)
+    .Case("EnumArgument", true)
+    .Default(false);
+}
+
+// Emits the first-argument-is-identifier property for attributes.
+static void emitClangAttrIdentifierArgList(RecordKeeper &Records, raw_ostream &OS) {
+  OS << "#if defined(CLANG_ATTR_IDENTIFIER_ARG_LIST)\n";
+  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
+
+  for (const auto *Attr : Attrs) {
+    // Determine whether the first argument is an identifier.
+    std::vector<Record *> Args = Attr->getValueAsListOfDefs("Args");
+    if (Args.empty() || !isIdentifierArgument(Args[0]))
+      continue;
+
+    // All these spellings take an identifier argument.
+    std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(*Attr);
+    std::set<std::string> Emitted;
+    for (const auto &S : Spellings) {
+      if (Emitted.insert(S.name()).second)
+        OS << ".Case(\"" << S.name() << "\", " << "true" << ")\n";
+    }
+  }
+  OS << "#endif // CLANG_ATTR_IDENTIFIER_ARG_LIST\n\n";
+}
+
 namespace clang {
 
 // Emits the class definitions for attributes.
@@ -1047,9 +1364,19 @@
 
   std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
 
-  for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end();
-       i != e; ++i) {
-    Record &R = **i;
+  for (const auto *Attr : Attrs) {
+    const Record &R = *Attr;
+
+    // FIXME: Currently, documentation is generated as-needed due to the fact
+    // that there is no way to allow a generated project "reach into" the docs
+    // directory (for instance, it may be an out-of-tree build). However, we want
+    // to ensure that every attribute has a Documentation field, and produce an
+    // error if it has been neglected. Otherwise, the on-demand generation which
+    // happens server-side will fail. This code is ensuring that functionality,
+    // even though this Emitter doesn't technically need the documentation.
+    // When attribute documentation can be generated as part of the build
+    // itself, this code can be removed.
+    (void)R.getValueAsListOfDefs("Documentation");
     
     if (!R.getValueAsBit("ASTNode"))
       continue;
@@ -1057,9 +1384,8 @@
     const std::vector<Record *> Supers = R.getSuperClasses();
     assert(!Supers.empty() && "Forgot to specify a superclass for the attr");
     std::string SuperName;
-    for (std::vector<Record *>::const_reverse_iterator I = Supers.rbegin(),
-         E = Supers.rend(); I != E; ++I) {
-      const Record &R = **I;
+    for (const auto *Super : llvm::make_range(Supers.rbegin(), Supers.rend())) {
+      const Record &R = *Super;
       if (R.getName() != "TargetSpecificAttr" && SuperName.empty())
         SuperName = R.getName();
     }
@@ -1067,52 +1393,78 @@
     OS << "class " << R.getName() << "Attr : public " << SuperName << " {\n";
 
     std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
-    std::vector<Argument*> Args;
-    std::vector<Argument*>::iterator ai, ae;
+    std::vector<std::unique_ptr<Argument>> Args;
     Args.reserve(ArgRecords.size());
 
-    for (std::vector<Record*>::iterator ri = ArgRecords.begin(),
-                                        re = ArgRecords.end();
-         ri != re; ++ri) {
-      Record &ArgRecord = **ri;
-      Argument *Arg = createArgument(ArgRecord, R.getName());
-      assert(Arg);
-      Args.push_back(Arg);
-
-      Arg->writeDeclarations(OS);
+    for (const auto *ArgRecord : ArgRecords) {
+      Args.emplace_back(createArgument(*ArgRecord, R.getName()));
+      Args.back()->writeDeclarations(OS);
       OS << "\n\n";
     }
 
-    ae = Args.end();
+    OS << "\npublic:\n";
 
-    OS << "\n public:\n";
+    std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(R);
+
+    // If there are zero or one spellings, all spelling-related functionality
+    // can be elided. If all of the spellings share the same name, the spelling
+    // functionality can also be elided.
+    bool ElideSpelling = (Spellings.size() <= 1) ||
+                         SpellingNamesAreCommon(Spellings);
+
+    // This maps spelling index values to semantic Spelling enumerants.
+    SemanticSpellingMap SemanticToSyntacticMap;
+
+    if (!ElideSpelling)
+      OS << CreateSemanticSpellings(Spellings, SemanticToSyntacticMap);
+
+    OS << "  static " << R.getName() << "Attr *CreateImplicit(";
+    OS << "ASTContext &Ctx";
+    if (!ElideSpelling)
+      OS << ", Spelling S";
+    for (auto const &ai : Args) {
+      OS << ", ";
+      ai->writeCtorParameters(OS);
+    }
+    OS << ", SourceRange Loc = SourceRange()";
+    OS << ") {\n";
+    OS << "    " << R.getName() << "Attr *A = new (Ctx) " << R.getName();
+    OS << "Attr(Loc, Ctx, ";
+    for (auto const &ai : Args) {
+      ai->writeImplicitCtorArgs(OS);
+      OS << ", ";
+    }
+    OS << (ElideSpelling ? "0" : "S") << ");\n";
+    OS << "    A->setImplicit(true);\n";
+    OS << "    return A;\n  }\n\n";
+
     OS << "  " << R.getName() << "Attr(SourceRange R, ASTContext &Ctx\n";
     
     bool HasOpt = false;
-    for (ai = Args.begin(); ai != ae; ++ai) {
+    for (auto const &ai : Args) {
       OS << "              , ";
-      (*ai)->writeCtorParameters(OS);
+      ai->writeCtorParameters(OS);
       OS << "\n";
-      if ((*ai)->isOptional())
+      if (ai->isOptional())
         HasOpt = true;
     }
 
     OS << "              , ";
-    OS << "unsigned SI = 0\n";
+    OS << "unsigned SI\n";
 
     OS << "             )\n";
     OS << "    : " << SuperName << "(attr::" << R.getName() << ", R, SI)\n";
 
-    for (ai = Args.begin(); ai != ae; ++ai) {
+    for (auto const &ai : Args) {
       OS << "              , ";
-      (*ai)->writeCtorInitializers(OS);
+      ai->writeCtorInitializers(OS);
       OS << "\n";
     }
 
     OS << "  {\n";
   
-    for (ai = Args.begin(); ai != ae; ++ai) {
-      (*ai)->writeCtorBody(OS);
+    for (auto const &ai : Args) {
+      ai->writeCtorBody(OS);
       OS << "\n";
     }
     OS << "  }\n\n";
@@ -1121,54 +1473,61 @@
     // optional arguments as well.
     if (HasOpt) {
       OS << "  " << R.getName() << "Attr(SourceRange R, ASTContext &Ctx\n";
-      for (ai = Args.begin(); ai != ae; ++ai) {
-        if (!(*ai)->isOptional()) {
+      for (auto const &ai : Args) {
+        if (!ai->isOptional()) {
           OS << "              , ";
-          (*ai)->writeCtorParameters(OS);
+          ai->writeCtorParameters(OS);
           OS << "\n";
         }
       }
 
       OS << "              , ";
-      OS << "unsigned SI = 0\n";
+      OS << "unsigned SI\n";
 
       OS << "             )\n";
       OS << "    : " << SuperName << "(attr::" << R.getName() << ", R, SI)\n";
 
-      for (ai = Args.begin(); ai != ae; ++ai) {
+      for (auto const &ai : Args) {
         OS << "              , ";
-        (*ai)->writeCtorDefaultInitializers(OS);
+        ai->writeCtorDefaultInitializers(OS);
         OS << "\n";
       }
 
       OS << "  {\n";
   
-      for (ai = Args.begin(); ai != ae; ++ai) {
-        if (!(*ai)->isOptional()) {
-          (*ai)->writeCtorBody(OS);
+      for (auto const &ai : Args) {
+        if (!ai->isOptional()) {
+          ai->writeCtorBody(OS);
           OS << "\n";
         }
       }
       OS << "  }\n\n";
     }
 
-    OS << "  virtual " << R.getName() << "Attr *clone (ASTContext &C) const;\n";
-    OS << "  virtual void printPretty(raw_ostream &OS,\n"
-       << "                           const PrintingPolicy &Policy) const;\n";
+    OS << "  " << R.getName() << "Attr *clone(ASTContext &C) const override;\n";
+    OS << "  void printPretty(raw_ostream &OS,\n"
+       << "                   const PrintingPolicy &Policy) const override;\n";
+    OS << "  const char *getSpelling() const override;\n";
+    
+    if (!ElideSpelling) {
+      assert(!SemanticToSyntacticMap.empty() && "Empty semantic mapping list");
+      OS << "  Spelling getSemanticSpelling() const {\n";
+      WriteSemanticSpellingSwitch("SpellingListIndex", SemanticToSyntacticMap,
+                                  OS);
+      OS << "  }\n";
+    }
 
     writeAttrAccessorDefinition(R, OS);
 
-    for (ai = Args.begin(); ai != ae; ++ai) {
-      (*ai)->writeAccessors(OS);
+    for (auto const &ai : Args) {
+      ai->writeAccessors(OS);
       OS << "\n\n";
 
-      if ((*ai)->isEnumArg()) {
-        EnumArgument *EA = (EnumArgument *)*ai;
-        EA->writeConversion(OS);
-      } else if ((*ai)->isVariadicEnumArg()) {
-        VariadicEnumArgument *VEA = (VariadicEnumArgument *)*ai;
-        VEA->writeConversion(OS);
-      }
+      if (ai->isEnumArg())
+        static_cast<const EnumArgument *>(ai.get())->writeConversion(OS);
+      else if (ai->isVariadicEnumArg())
+        static_cast<const VariadicEnumArgument *>(ai.get())
+            ->writeConversion(OS);
     }
 
     OS << R.getValueAsString("AdditionalMembers");
@@ -1178,114 +1537,53 @@
        << "attr::" << R.getName() << "; }\n";
 
     bool LateParsed = R.getValueAsBit("LateParsed");
-    OS << "  virtual bool isLateParsed() const { return "
+    OS << "  bool isLateParsed() const override { return "
        << LateParsed << "; }\n";
 
+    if (R.getValueAsBit("DuplicatesAllowedWhileMerging"))
+      OS << "  bool duplicatesAllowed() const override { return true; }\n\n";
+
     OS << "};\n\n";
   }
 
   OS << "#endif\n";
 }
 
-static bool isIdentifierArgument(Record *Arg) {
-  return !Arg->getSuperClasses().empty() &&
-         llvm::StringSwitch<bool>(Arg->getSuperClasses().back()->getName())
-             .Case("IdentifierArgument", true)
-             .Case("EnumArgument", true)
-             .Default(false);
-}
-
-/// \brief Emits the first-argument-is-type property for attributes.
-void EmitClangAttrTypeArgList(RecordKeeper &Records, raw_ostream &OS) {
-  emitSourceFileHeader("llvm::StringSwitch code to match attributes with a "
-                       "type argument", OS);
-
-  std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
-
-  for (std::vector<Record *>::iterator I = Attrs.begin(), E = Attrs.end();
-       I != E; ++I) {
-    Record &Attr = **I;
-
-    // Determine whether the first argument is a type.
-    std::vector<Record *> Args = Attr.getValueAsListOfDefs("Args");
-    if (Args.empty())
-      continue;
-
-    if (Args[0]->getSuperClasses().back()->getName() != "TypeArgument")
-      continue;
-
-    // All these spellings take a single type argument.
-    std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings");
-    std::set<std::string> Emitted;
-    for (std::vector<Record*>::const_iterator I = Spellings.begin(),
-         E = Spellings.end(); I != E; ++I) {
-      if (Emitted.insert((*I)->getValueAsString("Name")).second)
-        OS << ".Case(\"" << (*I)->getValueAsString("Name") << "\", "
-           << "true" << ")\n";
-    }
-  }
-}
-
-// Emits the first-argument-is-identifier property for attributes.
-void EmitClangAttrIdentifierArgList(RecordKeeper &Records, raw_ostream &OS) {
-  emitSourceFileHeader("llvm::StringSwitch code to match attributes with "
-                       "an identifier argument", OS);
-
-  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
-
-  for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end();
-       I != E; ++I) {
-    Record &Attr = **I;
-
-    // Determine whether the first argument is an identifier.
-    std::vector<Record *> Args = Attr.getValueAsListOfDefs("Args");
-    if (Args.empty() || !isIdentifierArgument(Args[0]))
-      continue;
-
-    // All these spellings take an identifier argument.
-    std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings");
-    std::set<std::string> Emitted;
-    for (std::vector<Record*>::const_iterator I = Spellings.begin(),
-         E = Spellings.end(); I != E; ++I) {
-      if (Emitted.insert((*I)->getValueAsString("Name")).second)
-        OS << ".Case(\"" << (*I)->getValueAsString("Name") << "\", "
-           << "true" << ")\n";
-    }
-  }
-}
-
 // Emits the class method definitions for attributes.
 void EmitClangAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
   emitSourceFileHeader("Attribute classes' member function definitions", OS);
 
   std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
-  std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ri, re;
-  std::vector<Argument*>::iterator ai, ae;
 
-  for (; i != e; ++i) {
-    Record &R = **i;
+  for (auto *Attr : Attrs) {
+    Record &R = *Attr;
     
     if (!R.getValueAsBit("ASTNode"))
       continue;
-    
-    std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
-    std::vector<Argument*> Args;
-    for (ri = ArgRecords.begin(), re = ArgRecords.end(); ri != re; ++ri)
-      Args.push_back(createArgument(**ri, R.getName()));
 
-    for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai)
-      (*ai)->writeAccessorDefinitions(OS);
+    std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
+    std::vector<std::unique_ptr<Argument>> Args;
+    for (const auto *Arg : ArgRecords)
+      Args.emplace_back(createArgument(*Arg, R.getName()));
+
+    for (auto const &ai : Args)
+      ai->writeAccessorDefinitions(OS);
 
     OS << R.getName() << "Attr *" << R.getName()
        << "Attr::clone(ASTContext &C) const {\n";
-    OS << "  return new (C) " << R.getName() << "Attr(getLocation(), C";
-    for (ai = Args.begin(); ai != ae; ++ai) {
+    OS << "  auto *A = new (C) " << R.getName() << "Attr(getLocation(), C";
+    for (auto const &ai : Args) {
       OS << ", ";
-      (*ai)->writeCloneArgs(OS);
+      ai->writeCloneArgs(OS);
     }
-    OS << ", getSpellingListIndex());\n}\n\n";
+    OS << ", getSpellingListIndex());\n";
+    OS << "  A->Inherited = Inherited;\n";
+    OS << "  A->IsPackExpansion = IsPackExpansion;\n";
+    OS << "  A->Implicit = Implicit;\n";
+    OS << "  return A;\n}\n\n";
 
     writePrettyPrintFunction(R, Args, OS);
+    writeGetSpellingFunction(R, OS);
   }
 }
 
@@ -1335,46 +1633,30 @@
         " INHERITABLE_PARAM_ATTR(NAME)\n";
   OS << "#endif\n\n";
 
-  OS << "#ifndef MS_INHERITANCE_ATTR\n";
-  OS << "#define MS_INHERITANCE_ATTR(NAME) INHERITABLE_ATTR(NAME)\n";
-  OS << "#endif\n\n";
-
-  OS << "#ifndef LAST_MS_INHERITANCE_ATTR\n";
-  OS << "#define LAST_MS_INHERITANCE_ATTR(NAME)"
-        " MS_INHERITANCE_ATTR(NAME)\n";
-  OS << "#endif\n\n";
-
   Record *InhClass = Records.getClass("InheritableAttr");
   Record *InhParamClass = Records.getClass("InheritableParamAttr");
-  Record *MSInheritanceClass = Records.getClass("MSInheritanceAttr");
   std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"),
-                       NonInhAttrs, InhAttrs, InhParamAttrs, MSInhAttrs;
-  for (std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end();
-       i != e; ++i) {
-    if (!(*i)->getValueAsBit("ASTNode"))
+                       NonInhAttrs, InhAttrs, InhParamAttrs;
+  for (auto *Attr : Attrs) {
+    if (!Attr->getValueAsBit("ASTNode"))
       continue;
     
-    if ((*i)->isSubClassOf(InhParamClass))
-      InhParamAttrs.push_back(*i);
-    else if ((*i)->isSubClassOf(MSInheritanceClass))
-      MSInhAttrs.push_back(*i);
-    else if ((*i)->isSubClassOf(InhClass))
-      InhAttrs.push_back(*i);
+    if (Attr->isSubClassOf(InhParamClass))
+      InhParamAttrs.push_back(Attr);
+    else if (Attr->isSubClassOf(InhClass))
+      InhAttrs.push_back(Attr);
     else
-      NonInhAttrs.push_back(*i);
+      NonInhAttrs.push_back(Attr);
   }
 
   EmitAttrList(OS, "INHERITABLE_PARAM_ATTR", InhParamAttrs);
-  EmitAttrList(OS, "MS_INHERITANCE_ATTR", MSInhAttrs);
   EmitAttrList(OS, "INHERITABLE_ATTR", InhAttrs);
   EmitAttrList(OS, "ATTR", NonInhAttrs);
 
   OS << "#undef LAST_ATTR\n";
   OS << "#undef INHERITABLE_ATTR\n";
-  OS << "#undef MS_INHERITANCE_ATTR\n";
   OS << "#undef LAST_INHERITABLE_ATTR\n";
   OS << "#undef LAST_INHERITABLE_PARAM_ATTR\n";
-  OS << "#undef LAST_MS_INHERITANCE_ATTR\n";
   OS << "#undef ATTR\n";
 }
 
@@ -1385,37 +1667,36 @@
   Record *InhClass = Records.getClass("InheritableAttr");
   std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"),
                        ArgRecords;
-  std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae;
-  std::vector<Argument*> Args;
-  std::vector<Argument*>::iterator ri, re;
+  std::vector<std::unique_ptr<Argument>> Args;
 
   OS << "  switch (Kind) {\n";
   OS << "  default:\n";
-  OS << "    assert(0 && \"Unknown attribute!\");\n";
-  OS << "    break;\n";
-  for (; i != e; ++i) {
-    Record &R = **i;
+  OS << "    llvm_unreachable(\"Unknown attribute!\");\n";
+  for (const auto *Attr : Attrs) {
+    const Record &R = *Attr;
     if (!R.getValueAsBit("ASTNode"))
       continue;
     
     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";
     ArgRecords = R.getValueAsListOfDefs("Args");
     Args.clear();
-    for (ai = ArgRecords.begin(), ae = ArgRecords.end(); ai != ae; ++ai) {
-      Argument *A = createArgument(**ai, R.getName());
-      Args.push_back(A);
-      A->writePCHReadDecls(OS);
+    for (const auto *Arg : ArgRecords) {
+      Args.emplace_back(createArgument(*Arg, R.getName()));
+      Args.back()->writePCHReadDecls(OS);
     }
     OS << "    New = new (Context) " << R.getName() << "Attr(Range, Context";
-    for (ri = Args.begin(), re = Args.end(); ri != re; ++ri) {
+    for (auto const &ri : Args) {
       OS << ", ";
-      (*ri)->writePCHReadArgs(OS);
+      ri->writePCHReadArgs(OS);
     }
-    OS << ");\n";
+    OS << ", Spelling);\n";
     if (R.isSubClassOf(InhClass))
       OS << "    cast<InheritableAttr>(New)->setInherited(isInherited);\n";
+    OS << "    New->setImplicit(isImplicit);\n";
     OS << "    break;\n";
     OS << "  }\n";
   }
@@ -1428,14 +1709,13 @@
 
   Record *InhClass = Records.getClass("InheritableAttr");
   std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), Args;
-  std::vector<Record*>::iterator i = Attrs.begin(), e = Attrs.end(), ai, ae;
 
   OS << "  switch (A->getKind()) {\n";
   OS << "  default:\n";
   OS << "    llvm_unreachable(\"Unknown attribute kind!\");\n";
   OS << "    break;\n";
-  for (; i != e; ++i) {
-    Record &R = **i;
+  for (const auto *Attr : Attrs) {
+    const Record &R = *Attr;
     if (!R.getValueAsBit("ASTNode"))
       continue;
     OS << "  case attr::" << R.getName() << ": {\n";
@@ -1445,31 +1725,128 @@
          << "Attr>(A);\n";
     if (R.isSubClassOf(InhClass))
       OS << "    Record.push_back(SA->isInherited());\n";
-    for (ai = Args.begin(), ae = Args.end(); ai != ae; ++ai)
-      createArgument(**ai, R.getName())->writePCHWrite(OS);
+    OS << "    Record.push_back(A->isImplicit());\n";
+    OS << "    Record.push_back(A->getSpellingListIndex());\n";
+
+    for (const auto *Arg : Args)
+      createArgument(*Arg, R.getName())->writePCHWrite(OS);
     OS << "    break;\n";
     OS << "  }\n";
   }
   OS << "  }\n";
 }
 
+static void GenerateHasAttrSpellingStringSwitch(
+    const std::vector<Record *> &Attrs, raw_ostream &OS,
+    const std::string &Variety = "", const std::string &Scope = "") {
+  for (const auto *Attr : Attrs) {
+    // It is assumed that there will be an llvm::Triple object named T within
+    // scope that can be used to determine whether the attribute exists in
+    // a given target.
+    std::string Test;
+    if (Attr->isSubClassOf("TargetSpecificAttr")) {
+      const Record *R = Attr->getValueAsDef("Target");
+      std::vector<std::string> Arches = R->getValueAsListOfStrings("Arches");
+
+      Test += "(";
+      for (auto AI = Arches.begin(), AE = Arches.end(); AI != AE; ++AI) {
+        std::string Part = *AI;
+        Test += "T.getArch() == llvm::Triple::" + Part;
+        if (AI + 1 != AE)
+          Test += " || ";
+      }
+      Test += ")";
+
+      std::vector<std::string> OSes;
+      if (!R->isValueUnset("OSes")) {
+        Test += " && (";
+        std::vector<std::string> OSes = R->getValueAsListOfStrings("OSes");
+        for (auto AI = OSes.begin(), AE = OSes.end(); AI != AE; ++AI) {
+          std::string Part = *AI;
+
+          Test += "T.getOS() == llvm::Triple::" + Part;
+          if (AI + 1 != AE)
+            Test += " || ";
+        }
+        Test += ")";
+      }
+      
+      // If this is the C++11 variety, also add in the LangOpts test.
+      if (Variety == "CXX11")
+        Test += " && LangOpts.CPlusPlus11";
+    } else if (Variety == "CXX11")
+      // C++11 mode should be checked against LangOpts, which is presumed to be
+      // present in the caller.
+      Test = "LangOpts.CPlusPlus11";
+    else
+      Test = "true";
+
+    std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(*Attr);
+    for (const auto &S : Spellings)
+      if (Variety.empty() || (Variety == S.variety() &&
+                              (Scope.empty() || Scope == S.nameSpace())))
+        OS << "    .Case(\"" << S.name() << "\", " << Test << ")\n";
+  }
+  OS << "    .Default(false);\n";
+}
+
 // Emits the list of spellings for attributes.
-void EmitClangAttrSpellingList(RecordKeeper &Records, raw_ostream &OS) {
-  emitSourceFileHeader("llvm::StringSwitch code to match all known attributes",
-                       OS);
+void EmitClangAttrHasAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
+  emitSourceFileHeader("Code to implement the __has_attribute logic", OS);
 
-  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
-  
-  for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end(); I != E; ++I) {
-    Record &Attr = **I;
+  // Separate all of the attributes out into four group: generic, C++11, GNU,
+  // and declspecs. Then generate a big switch statement for each of them.
+  std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
+  std::vector<Record *> Declspec, GNU, Pragma;
+  std::map<std::string, std::vector<Record *>> CXX;
 
-    std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings");
-
-    for (std::vector<Record*>::const_iterator I = Spellings.begin(), E = Spellings.end(); I != E; ++I) {
-      OS << ".Case(\"" << (*I)->getValueAsString("Name") << "\", true)\n";
+  // Walk over the list of all attributes, and split them out based on the
+  // spelling variety.
+  for (auto *R : Attrs) {
+    std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(*R);
+    for (const auto &SI : Spellings) {
+      std::string Variety = SI.variety();
+      if (Variety == "GNU")
+        GNU.push_back(R);
+      else if (Variety == "Declspec")
+        Declspec.push_back(R);
+      else if (Variety == "CXX11")
+        CXX[SI.nameSpace()].push_back(R);
+      else if (Variety == "Pragma")
+        Pragma.push_back(R);
     }
   }
 
+  OS << "switch (Syntax) {\n";
+  OS << "case AttrSyntax::Generic:\n";
+  OS << "  return llvm::StringSwitch<bool>(Name)\n";
+  GenerateHasAttrSpellingStringSwitch(Attrs, OS);
+  OS << "case AttrSyntax::GNU:\n";
+  OS << "  return llvm::StringSwitch<bool>(Name)\n";
+  GenerateHasAttrSpellingStringSwitch(GNU, OS, "GNU");
+  OS << "case AttrSyntax::Declspec:\n";
+  OS << "  return llvm::StringSwitch<bool>(Name)\n";
+  GenerateHasAttrSpellingStringSwitch(Declspec, OS, "Declspec");
+  OS << "case AttrSyntax::Pragma:\n";
+  OS << "  return llvm::StringSwitch<bool>(Name)\n";
+  GenerateHasAttrSpellingStringSwitch(Pragma, OS, "Pragma");
+  OS << "case AttrSyntax::CXX: {\n";
+  // C++11-style attributes are further split out based on the Scope.
+  for (std::map<std::string, std::vector<Record *>>::iterator I = CXX.begin(),
+                                                              E = CXX.end();
+       I != E; ++I) {
+    if (I != CXX.begin())
+      OS << " else ";
+    if (I->first.empty())
+      OS << "if (!Scope || Scope->getName() == \"\") {\n";
+    else
+      OS << "if (Scope->getName() == \"" << I->first << "\") {\n";
+    OS << "  return llvm::StringSwitch<bool>(Name)\n";
+    GenerateHasAttrSpellingStringSwitch(I->second, OS, "CXX11", I->first);
+    OS << "}";
+  }
+  OS << "\n}\n";
+  OS << "}\n";
 }
 
 void EmitClangAttrSpellingListIndex(RecordKeeper &Records, raw_ostream &OS) {
@@ -1477,88 +1854,105 @@
                        "into internal identifiers", OS);
 
   OS <<
-    "  unsigned Index = 0;\n"
     "  switch (AttrKind) {\n"
     "  default:\n"
     "    llvm_unreachable(\"Unknown attribute kind!\");\n"
     "    break;\n";
 
-  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
-  for (std::vector<Record*>::const_iterator I = Attrs.begin(), E = Attrs.end();
-       I != E; ++I) {
-    Record &R = **I;
-    // We only care about attributes that participate in Sema checking, so
-    // skip those attributes that are not able to make their way to Sema.
-    if (!R.getValueAsBit("SemaHandler"))
-      continue;
-
-    std::vector<Record*> Spellings = R.getValueAsListOfDefs("Spellings");
-    // Each distinct spelling yields an attribute kind.
-    if (R.getValueAsBit("DistinctSpellings")) {
-      for (unsigned I = 0; I < Spellings.size(); ++ I) {
-        OS <<
-          "  case AT_" << Spellings[I]->getValueAsString("Name") << ": \n"
-          "    Index = " << I << ";\n"
-          "  break;\n";
-      }
-    } else {
-      OS << "  case AT_" << R.getName() << " : {\n";
-      for (unsigned I = 0; I < Spellings.size(); ++ I) {
-        SmallString<16> Namespace;
-        if (Spellings[I]->getValueAsString("Variety") == "CXX11")
-          Namespace = Spellings[I]->getValueAsString("Namespace");
-        else
-          Namespace = "";
-
-        OS << "    if (Name == \""
-          << Spellings[I]->getValueAsString("Name") << "\" && "
-          << "SyntaxUsed == "
-          << StringSwitch<unsigned>(Spellings[I]->getValueAsString("Variety"))
-            .Case("GNU", 0)
-            .Case("CXX11", 1)
-            .Case("Declspec", 2)
-            .Case("Keyword", 3)
-            .Default(0)
-          << " && Scope == \"" << Namespace << "\")\n"
-          << "        return " << I << ";\n";
-      }
-
-      OS << "    break;\n";
-      OS << "  }\n";
+  ParsedAttrMap Attrs = getParsedAttrList(Records);
+  for (const auto &I : Attrs) {
+    const Record &R = *I.second;
+    std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(R);
+    OS << "  case AT_" << I.first << ": {\n";
+    for (unsigned I = 0; I < Spellings.size(); ++ I) {
+      OS << "    if (Name == \"" << Spellings[I].name() << "\" && "
+         << "SyntaxUsed == "
+         << StringSwitch<unsigned>(Spellings[I].variety())
+                .Case("GNU", 0)
+                .Case("CXX11", 1)
+                .Case("Declspec", 2)
+                .Case("Keyword", 3)
+                .Case("Pragma", 4)
+                .Default(0)
+         << " && Scope == \"" << Spellings[I].nameSpace() << "\")\n"
+         << "        return " << I << ";\n";
     }
+
+    OS << "    break;\n";
+    OS << "  }\n";
   }
 
   OS << "  }\n";
-  OS << "  return Index;\n";
+  OS << "  return 0;\n";
 }
 
-// Emits the LateParsed property for attributes.
-void EmitClangAttrLateParsedList(RecordKeeper &Records, raw_ostream &OS) {
-  emitSourceFileHeader("llvm::StringSwitch code to match late parsed "
-                       "attributes", OS);
+// Emits code used by RecursiveASTVisitor to visit attributes
+void EmitClangAttrASTVisitor(RecordKeeper &Records, raw_ostream &OS) {
+  emitSourceFileHeader("Used by RecursiveASTVisitor to visit attributes.", OS);
 
   std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
 
-  for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end();
-       I != E; ++I) {
-    Record &Attr = **I;
-
-    bool LateParsed = Attr.getValueAsBit("LateParsed");
-
-    if (LateParsed) {
-      std::vector<Record*> Spellings =
-        Attr.getValueAsListOfDefs("Spellings");
-
-      // FIXME: Handle non-GNU attributes
-      for (std::vector<Record*>::const_iterator I = Spellings.begin(),
-           E = Spellings.end(); I != E; ++I) {
-        if ((*I)->getValueAsString("Variety") != "GNU")
-          continue;
-        OS << ".Case(\"" << (*I)->getValueAsString("Name") << "\", "
-           << LateParsed << ")\n";
-      }
-    }
+  // Write method declarations for Traverse* methods.
+  // We emit this here because we only generate methods for attributes that
+  // are declared as ASTNodes.
+  OS << "#ifdef ATTR_VISITOR_DECLS_ONLY\n\n";
+  for (const auto *Attr : Attrs) {
+    const Record &R = *Attr;
+    if (!R.getValueAsBit("ASTNode"))
+      continue;
+    OS << "  bool Traverse"
+       << R.getName() << "Attr(" << R.getName() << "Attr *A);\n";
+    OS << "  bool Visit"
+       << R.getName() << "Attr(" << R.getName() << "Attr *A) {\n"
+       << "    return true; \n"
+       << "  };\n";
   }
+  OS << "\n#else // ATTR_VISITOR_DECLS_ONLY\n\n";
+
+  // Write individual Traverse* methods for each attribute class.
+  for (const auto *Attr : Attrs) {
+    const Record &R = *Attr;
+    if (!R.getValueAsBit("ASTNode"))
+      continue;
+
+    OS << "template <typename Derived>\n"
+       << "bool VISITORCLASS<Derived>::Traverse"
+       << R.getName() << "Attr(" << R.getName() << "Attr *A) {\n"
+       << "  if (!getDerived().VisitAttr(A))\n"
+       << "    return false;\n"
+       << "  if (!getDerived().Visit" << R.getName() << "Attr(A))\n"
+       << "    return false;\n";
+
+    std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
+    for (const auto *Arg : ArgRecords)
+      createArgument(*Arg, R.getName())->writeASTVisitorTraversal(OS);
+
+    OS << "  return true;\n";
+    OS << "}\n\n";
+  }
+
+  // Write generic Traverse routine
+  OS << "template <typename Derived>\n"
+     << "bool VISITORCLASS<Derived>::TraverseAttr(Attr *A) {\n"
+     << "  if (!A)\n"
+     << "    return true;\n"
+     << "\n"
+     << "  switch (A->getKind()) {\n"
+     << "    default:\n"
+     << "      return true;\n";
+
+  for (const auto *Attr : Attrs) {
+    const Record &R = *Attr;
+    if (!R.getValueAsBit("ASTNode"))
+      continue;
+
+    OS << "    case attr::" << R.getName() << ":\n"
+       << "      return getDerived().Traverse" << R.getName() << "Attr("
+       << "cast<" << R.getName() << "Attr>(A));\n";
+  }
+  OS << "  }\n";  // end case
+  OS << "}\n";  // end function
+  OS << "#endif  // ATTR_VISITOR_DECLS_ONLY\n";
 }
 
 // Emits code to instantiate dependent attributes on templates.
@@ -1576,9 +1970,8 @@
      << "    default:\n"
      << "      break;\n";
 
-  for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end();
-       I != E; ++I) {
-    Record &R = **I;
+  for (const auto *Attr : Attrs) {
+    const Record &R = *Attr;
     if (!R.getValueAsBit("ASTNode"))
       continue;
 
@@ -1602,29 +1995,21 @@
     }
 
     std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
-    std::vector<Argument*> Args;
-    std::vector<Argument*>::iterator ai, ae;
+    std::vector<std::unique_ptr<Argument>> Args;
     Args.reserve(ArgRecords.size());
 
-    for (std::vector<Record*>::iterator ri = ArgRecords.begin(),
-                                        re = ArgRecords.end();
-         ri != re; ++ri) {
-      Record &ArgRecord = **ri;
-      Argument *Arg = createArgument(ArgRecord, R.getName());
-      assert(Arg);
-      Args.push_back(Arg);
-    }
-    ae = Args.end();
+    for (const auto *ArgRecord : ArgRecords)
+      Args.emplace_back(createArgument(*ArgRecord, R.getName()));
 
-    for (ai = Args.begin(); ai != ae; ++ai) {
-      (*ai)->writeTemplateInstantiation(OS);
-    }
+    for (auto const &ai : Args)
+      ai->writeTemplateInstantiation(OS);
+
     OS << "      return new (C) " << R.getName() << "Attr(A->getLocation(), C";
-    for (ai = Args.begin(); ai != ae; ++ai) {
+    for (auto const &ai : Args) {
       OS << ", ";
-      (*ai)->writeTemplateInstantiationArgs(OS);
+      ai->writeTemplateInstantiationArgs(OS);
     }
-    OS << ");\n    }\n";
+    OS << ", A->getSpellingListIndex());\n    }\n";
   }
   OS << "  } // end switch\n"
      << "  llvm_unreachable(\"Unknown attribute!\");\n"
@@ -1634,39 +2019,6 @@
      << "} // end namespace clang\n";
 }
 
-typedef std::vector<std::pair<std::string, Record *> > ParsedAttrMap;
-
-static ParsedAttrMap getParsedAttrList(const RecordKeeper &Records) {
-  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
-  ParsedAttrMap R;
-  for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end();
-       I != E; ++I) {
-    Record &Attr = **I;
-    
-    bool SemaHandler = Attr.getValueAsBit("SemaHandler");
-    bool DistinctSpellings = Attr.getValueAsBit("DistinctSpellings");
-
-    if (SemaHandler) {
-      if (DistinctSpellings) {
-        std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings");
-        
-        for (std::vector<Record*>::const_iterator I = Spellings.begin(),
-             E = Spellings.end(); I != E; ++I) {
-          std::string AttrName = (*I)->getValueAsString("Name");
-
-          StringRef Spelling = NormalizeAttrName(AttrName);
-          R.push_back(std::make_pair(Spelling.str(), &Attr));
-        }
-      } else {
-        StringRef AttrName = Attr.getName();
-        AttrName = NormalizeAttrName(AttrName);
-        R.push_back(std::make_pair(AttrName.str(), *I));
-      }
-    }
-  }
-  return R;
-}
-
 // Emits the list of parsed attributes.
 void EmitClangAttrParsedAttrList(RecordKeeper &Records, raw_ostream &OS) {
   emitSourceFileHeader("List of all attributes that Clang recognizes", OS);
@@ -1676,47 +2028,467 @@
   OS << "#endif\n\n";
   
   ParsedAttrMap Names = getParsedAttrList(Records);
-  for (ParsedAttrMap::iterator I = Names.begin(), E = Names.end(); I != E;
-       ++I) {
-    OS << "PARSED_ATTR(" << I->first << ")\n";
+  for (const auto &I : Names) {
+    OS << "PARSED_ATTR(" << I.first << ")\n";
   }
 }
 
-static void emitArgInfo(const Record &R, raw_ostream &OS) {
+static void emitArgInfo(const Record &R, std::stringstream &OS) {
   // This function will count the number of arguments specified for the
   // attribute and emit the number of required arguments followed by the
   // number of optional arguments.
   std::vector<Record *> Args = R.getValueAsListOfDefs("Args");
   unsigned ArgCount = 0, OptCount = 0;
-  for (std::vector<Record *>::const_iterator I = Args.begin(), E = Args.end();
-       I != E; ++I) {
-    const Record &Arg = **I;
-    Arg.getValueAsBit("Optional") ? ++OptCount : ++ArgCount;
+  for (const auto *Arg : Args) {
+    Arg->getValueAsBit("Optional") ? ++OptCount : ++ArgCount;
   }
   OS << ArgCount << ", " << OptCount;
 }
 
+static void GenerateDefaultAppertainsTo(raw_ostream &OS) {
+  OS << "static bool defaultAppertainsTo(Sema &, const AttributeList &,";
+  OS << "const Decl *) {\n";
+  OS << "  return true;\n";
+  OS << "}\n\n";
+}
+
+static std::string CalculateDiagnostic(const Record &S) {
+  // If the SubjectList object has a custom diagnostic associated with it,
+  // return that directly.
+  std::string CustomDiag = S.getValueAsString("CustomDiag");
+  if (!CustomDiag.empty())
+    return CustomDiag;
+
+  // Given the list of subjects, determine what diagnostic best fits.
+  enum {
+    Func = 1U << 0,
+    Var = 1U << 1,
+    ObjCMethod = 1U << 2,
+    Param = 1U << 3,
+    Class = 1U << 4,
+    GenericRecord = 1U << 5,
+    Type = 1U << 6,
+    ObjCIVar = 1U << 7,
+    ObjCProp = 1U << 8,
+    ObjCInterface = 1U << 9,
+    Block = 1U << 10,
+    Namespace = 1U << 11,
+    Field = 1U << 12,
+    CXXMethod = 1U << 13,
+    ObjCProtocol = 1U << 14
+  };
+  uint32_t SubMask = 0;
+
+  std::vector<Record *> Subjects = S.getValueAsListOfDefs("Subjects");
+  for (const auto *Subject : Subjects) {
+    const Record &R = *Subject;
+    std::string Name;
+
+    if (R.isSubClassOf("SubsetSubject")) {
+      PrintError(R.getLoc(), "SubsetSubjects should use a custom diagnostic");
+      // As a fallback, look through the SubsetSubject to see what its base
+      // type is, and use that. This needs to be updated if SubsetSubjects
+      // are allowed within other SubsetSubjects.
+      Name = R.getValueAsDef("Base")->getName();
+    } else
+      Name = R.getName();
+
+    uint32_t V = StringSwitch<uint32_t>(Name)
+                   .Case("Function", Func)
+                   .Case("Var", Var)
+                   .Case("ObjCMethod", ObjCMethod)
+                   .Case("ParmVar", Param)
+                   .Case("TypedefName", Type)
+                   .Case("ObjCIvar", ObjCIVar)
+                   .Case("ObjCProperty", ObjCProp)
+                   .Case("Record", GenericRecord)
+                   .Case("ObjCInterface", ObjCInterface)
+                   .Case("ObjCProtocol", ObjCProtocol)
+                   .Case("Block", Block)
+                   .Case("CXXRecord", Class)
+                   .Case("Namespace", Namespace)
+                   .Case("Field", Field)
+                   .Case("CXXMethod", CXXMethod)
+                   .Default(0);
+    if (!V) {
+      // Something wasn't in our mapping, so be helpful and let the developer
+      // know about it.
+      PrintFatalError(R.getLoc(), "Unknown subject type: " + R.getName());
+      return "";
+    }
+
+    SubMask |= V;
+  }
+
+  switch (SubMask) {
+    // For the simple cases where there's only a single entry in the mask, we
+    // don't have to resort to bit fiddling.
+    case Func:  return "ExpectedFunction";
+    case Var:   return "ExpectedVariable";
+    case Param: return "ExpectedParameter";
+    case Class: return "ExpectedClass";
+    case CXXMethod:
+      // FIXME: Currently, this maps to ExpectedMethod based on existing code,
+      // but should map to something a bit more accurate at some point.
+    case ObjCMethod:  return "ExpectedMethod";
+    case Type:  return "ExpectedType";
+    case ObjCInterface: return "ExpectedObjectiveCInterface";
+    case ObjCProtocol: return "ExpectedObjectiveCProtocol";
+    
+    // "GenericRecord" means struct, union or class; check the language options
+    // and if not compiling for C++, strip off the class part. Note that this
+    // relies on the fact that the context for this declares "Sema &S".
+    case GenericRecord:
+      return "(S.getLangOpts().CPlusPlus ? ExpectedStructOrUnionOrClass : "
+                                           "ExpectedStructOrUnion)";
+    case Func | ObjCMethod | Block: return "ExpectedFunctionMethodOrBlock";
+    case Func | ObjCMethod | Class: return "ExpectedFunctionMethodOrClass";
+    case Func | Param:
+    case Func | ObjCMethod | Param: return "ExpectedFunctionMethodOrParameter";
+    case Func | ObjCMethod: return "ExpectedFunctionOrMethod";
+    case Func | Var: return "ExpectedVariableOrFunction";
+
+    // If not compiling for C++, the class portion does not apply.
+    case Func | Var | Class:
+      return "(S.getLangOpts().CPlusPlus ? ExpectedFunctionVariableOrClass : "
+                                           "ExpectedVariableOrFunction)";
+
+    case ObjCMethod | ObjCProp: return "ExpectedMethodOrProperty";
+    case ObjCProtocol | ObjCInterface:
+      return "ExpectedObjectiveCInterfaceOrProtocol";
+    case Field | Var: return "ExpectedFieldOrGlobalVar";
+  }
+
+  PrintFatalError(S.getLoc(),
+                  "Could not deduce diagnostic argument for Attr subjects");
+
+  return "";
+}
+
+static std::string GetSubjectWithSuffix(const Record *R) {
+  std::string B = R->getName();
+  if (B == "DeclBase")
+    return "Decl";
+  return B + "Decl";
+}
+static std::string GenerateCustomAppertainsTo(const Record &Subject,
+                                              raw_ostream &OS) {
+  std::string FnName = "is" + Subject.getName();
+
+  // If this code has already been generated, simply return the previous
+  // instance of it.
+  static std::set<std::string> CustomSubjectSet;
+  std::set<std::string>::iterator I = CustomSubjectSet.find(FnName);
+  if (I != CustomSubjectSet.end())
+    return *I;
+
+  Record *Base = Subject.getValueAsDef("Base");
+
+  // Not currently support custom subjects within custom subjects.
+  if (Base->isSubClassOf("SubsetSubject")) {
+    PrintFatalError(Subject.getLoc(),
+                    "SubsetSubjects within SubsetSubjects is not supported");
+    return "";
+  }
+
+  OS << "static bool " << FnName << "(const Decl *D) {\n";
+  OS << "  if (const " << GetSubjectWithSuffix(Base) << " *S = dyn_cast<";
+  OS << GetSubjectWithSuffix(Base);
+  OS << ">(D))\n";
+  OS << "    return " << Subject.getValueAsString("CheckCode") << ";\n";
+  OS << "  return false;\n";
+  OS << "}\n\n";
+
+  CustomSubjectSet.insert(FnName);
+  return FnName;
+}
+
+static std::string GenerateAppertainsTo(const Record &Attr, raw_ostream &OS) {
+  // If the attribute does not contain a Subjects definition, then use the
+  // default appertainsTo logic.
+  if (Attr.isValueUnset("Subjects"))
+    return "defaultAppertainsTo";
+
+  const Record *SubjectObj = Attr.getValueAsDef("Subjects");
+  std::vector<Record*> Subjects = SubjectObj->getValueAsListOfDefs("Subjects");
+
+  // If the list of subjects is empty, it is assumed that the attribute
+  // appertains to everything.
+  if (Subjects.empty())
+    return "defaultAppertainsTo";
+
+  bool Warn = SubjectObj->getValueAsDef("Diag")->getValueAsBit("Warn");
+
+  // Otherwise, generate an appertainsTo check specific to this attribute which
+  // checks all of the given subjects against the Decl passed in. Return the
+  // name of that check to the caller.
+  std::string FnName = "check" + Attr.getName() + "AppertainsTo";
+  std::stringstream SS;
+  SS << "static bool " << FnName << "(Sema &S, const AttributeList &Attr, ";
+  SS << "const Decl *D) {\n";
+  SS << "  if (";
+  for (auto I = Subjects.begin(), E = Subjects.end(); I != E; ++I) {
+    // If the subject has custom code associated with it, generate a function
+    // for it. The function cannot be inlined into this check (yet) because it
+    // requires the subject to be of a specific type, and were that information
+    // inlined here, it would not support an attribute with multiple custom
+    // subjects.
+    if ((*I)->isSubClassOf("SubsetSubject")) {
+      SS << "!" << GenerateCustomAppertainsTo(**I, OS) << "(D)";
+    } else {
+      SS << "!isa<" << GetSubjectWithSuffix(*I) << ">(D)";
+    }
+
+    if (I + 1 != E)
+      SS << " && ";
+  }
+  SS << ") {\n";
+  SS << "    S.Diag(Attr.getLoc(), diag::";
+  SS << (Warn ? "warn_attribute_wrong_decl_type" :
+               "err_attribute_wrong_decl_type");
+  SS << ")\n";
+  SS << "      << Attr.getName() << ";
+  SS << CalculateDiagnostic(*SubjectObj) << ";\n";
+  SS << "    return false;\n";
+  SS << "  }\n";
+  SS << "  return true;\n";
+  SS << "}\n\n";
+
+  OS << SS.str();
+  return FnName;
+}
+
+static void GenerateDefaultLangOptRequirements(raw_ostream &OS) {
+  OS << "static bool defaultDiagnoseLangOpts(Sema &, ";
+  OS << "const AttributeList &) {\n";
+  OS << "  return true;\n";
+  OS << "}\n\n";
+}
+
+static std::string GenerateLangOptRequirements(const Record &R,
+                                               raw_ostream &OS) {
+  // If the attribute has an empty or unset list of language requirements,
+  // return the default handler.
+  std::vector<Record *> LangOpts = R.getValueAsListOfDefs("LangOpts");
+  if (LangOpts.empty())
+    return "defaultDiagnoseLangOpts";
+
+  // Generate the test condition, as well as a unique function name for the
+  // diagnostic test. The list of options should usually be short (one or two
+  // options), and the uniqueness isn't strictly necessary (it is just for
+  // codegen efficiency).
+  std::string FnName = "check", Test;
+  for (auto I = LangOpts.begin(), E = LangOpts.end(); I != E; ++I) {
+    std::string Part = (*I)->getValueAsString("Name");
+    Test += "S.LangOpts." + Part;
+    if (I + 1 != E)
+      Test += " || ";
+    FnName += Part;
+  }
+  FnName += "LangOpts";
+
+  // If this code has already been generated, simply return the previous
+  // instance of it.
+  static std::set<std::string> CustomLangOptsSet;
+  std::set<std::string>::iterator I = CustomLangOptsSet.find(FnName);
+  if (I != CustomLangOptsSet.end())
+    return *I;
+
+  OS << "static bool " << FnName << "(Sema &S, const AttributeList &Attr) {\n";
+  OS << "  if (" << Test << ")\n";
+  OS << "    return true;\n\n";
+  OS << "  S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) ";
+  OS << "<< Attr.getName();\n";
+  OS << "  return false;\n";
+  OS << "}\n\n";
+
+  CustomLangOptsSet.insert(FnName);
+  return FnName;
+}
+
+static void GenerateDefaultTargetRequirements(raw_ostream &OS) {
+  OS << "static bool defaultTargetRequirements(const llvm::Triple &) {\n";
+  OS << "  return true;\n";
+  OS << "}\n\n";
+}
+
+static std::string GenerateTargetRequirements(const Record &Attr,
+                                              const ParsedAttrMap &Dupes,
+                                              raw_ostream &OS) {
+  // If the attribute is not a target specific attribute, return the default
+  // target handler.
+  if (!Attr.isSubClassOf("TargetSpecificAttr"))
+    return "defaultTargetRequirements";
+
+  // Get the list of architectures to be tested for.
+  const Record *R = Attr.getValueAsDef("Target");
+  std::vector<std::string> Arches = R->getValueAsListOfStrings("Arches");
+  if (Arches.empty()) {
+    PrintError(Attr.getLoc(), "Empty list of target architectures for a "
+                              "target-specific attr");
+    return "defaultTargetRequirements";
+  }
+
+  // If there are other attributes which share the same parsed attribute kind,
+  // such as target-specific attributes with a shared spelling, collapse the
+  // duplicate architectures. This is required because a shared target-specific
+  // attribute has only one AttributeList::Kind enumeration value, but it
+  // applies to multiple target architectures. In order for the attribute to be
+  // considered valid, all of its architectures need to be included.
+  if (!Attr.isValueUnset("ParseKind")) {
+    std::string APK = Attr.getValueAsString("ParseKind");
+    for (const auto &I : Dupes) {
+      if (I.first == APK) {
+        std::vector<std::string> DA = I.second->getValueAsDef("Target")
+                                          ->getValueAsListOfStrings("Arches");
+        std::copy(DA.begin(), DA.end(), std::back_inserter(Arches));
+      }
+    }
+  }
+
+  std::string FnName = "isTarget", Test = "(";
+  for (auto I = Arches.begin(), E = Arches.end(); I != E; ++I) {
+    std::string Part = *I;
+    Test += "Arch == llvm::Triple::" + Part;
+    if (I + 1 != E)
+      Test += " || ";
+    FnName += Part;
+  }
+  Test += ")";
+
+  // If the target also requires OS testing, generate those tests as well.
+  bool UsesOS = false;
+  if (!R->isValueUnset("OSes")) {
+    UsesOS = true;
+    
+    // We know that there was at least one arch test, so we need to and in the
+    // OS tests.
+    Test += " && (";
+    std::vector<std::string> OSes = R->getValueAsListOfStrings("OSes");
+    for (auto I = OSes.begin(), E = OSes.end(); I != E; ++I) {
+      std::string Part = *I;
+
+      Test += "OS == llvm::Triple::" + Part;
+      if (I + 1 != E)
+        Test += " || ";
+      FnName += Part;
+    }
+    Test += ")";
+  }
+
+  // If this code has already been generated, simply return the previous
+  // instance of it.
+  static std::set<std::string> CustomTargetSet;
+  std::set<std::string>::iterator I = CustomTargetSet.find(FnName);
+  if (I != CustomTargetSet.end())
+    return *I;
+
+  OS << "static bool " << FnName << "(const llvm::Triple &T) {\n";
+  OS << "  llvm::Triple::ArchType Arch = T.getArch();\n";
+  if (UsesOS)
+    OS << "  llvm::Triple::OSType OS = T.getOS();\n";
+  OS << "  return " << Test << ";\n";
+  OS << "}\n\n";
+
+  CustomTargetSet.insert(FnName);
+  return FnName;
+}
+
+static void GenerateDefaultSpellingIndexToSemanticSpelling(raw_ostream &OS) {
+  OS << "static unsigned defaultSpellingIndexToSemanticSpelling("
+     << "const AttributeList &Attr) {\n";
+  OS << "  return UINT_MAX;\n";
+  OS << "}\n\n";
+}
+
+static std::string GenerateSpellingIndexToSemanticSpelling(const Record &Attr,
+                                                           raw_ostream &OS) {
+  // If the attribute does not have a semantic form, we can bail out early.
+  if (!Attr.getValueAsBit("ASTNode"))
+    return "defaultSpellingIndexToSemanticSpelling";
+
+  std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attr);
+
+  // If there are zero or one spellings, or all of the spellings share the same
+  // name, we can also bail out early.
+  if (Spellings.size() <= 1 || SpellingNamesAreCommon(Spellings))
+    return "defaultSpellingIndexToSemanticSpelling";
+
+  // Generate the enumeration we will use for the mapping.
+  SemanticSpellingMap SemanticToSyntacticMap;
+  std::string Enum = CreateSemanticSpellings(Spellings, SemanticToSyntacticMap);
+  std::string Name = Attr.getName() + "AttrSpellingMap";
+
+  OS << "static unsigned " << Name << "(const AttributeList &Attr) {\n";
+  OS << Enum;
+  OS << "  unsigned Idx = Attr.getAttributeSpellingListIndex();\n";
+  WriteSemanticSpellingSwitch("Idx", SemanticToSyntacticMap, OS);
+  OS << "}\n\n";
+
+  return Name;
+}
+
+static bool IsKnownToGCC(const Record &Attr) {
+  // Look at the spellings for this subject; if there are any spellings which
+  // claim to be known to GCC, the attribute is known to GCC.
+  std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attr);
+  for (const auto &I : Spellings) {
+    if (I.knownToGCC())
+      return true;
+  }
+  return false;
+}
+
 /// Emits the parsed attribute helpers
 void EmitClangAttrParsedAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
   emitSourceFileHeader("Parsed attribute helpers", OS);
 
-  ParsedAttrMap Attrs = getParsedAttrList(Records);
+  // Get the list of parsed attributes, and accept the optional list of
+  // duplicates due to the ParseKind.
+  ParsedAttrMap Dupes;
+  ParsedAttrMap Attrs = getParsedAttrList(Records, &Dupes);
 
-  OS << "static const ParsedAttrInfo AttrInfoMap[AttributeList::UnknownAttribute + 1] = {\n";
-  for (ParsedAttrMap::iterator I = Attrs.begin(), E = Attrs.end(); I != E;
-       ++I) {
+  // Generate the default appertainsTo, target and language option diagnostic,
+  // and spelling list index mapping methods.
+  GenerateDefaultAppertainsTo(OS);
+  GenerateDefaultLangOptRequirements(OS);
+  GenerateDefaultTargetRequirements(OS);
+  GenerateDefaultSpellingIndexToSemanticSpelling(OS);
+
+  // Generate the appertainsTo diagnostic methods and write their names into
+  // another mapping. At the same time, generate the AttrInfoMap object
+  // contents. Due to the reliance on generated code, use separate streams so
+  // that code will not be interleaved.
+  std::stringstream SS;
+  for (auto I = Attrs.begin(), E = Attrs.end(); I != E; ++I) {
+    // TODO: If the attribute's kind appears in the list of duplicates, that is
+    // because it is a target-specific attribute that appears multiple times.
+    // It would be beneficial to test whether the duplicates are "similar
+    // enough" to each other to not cause problems. For instance, check that
+    // the spellings are identical, and custom parsing rules match, etc.
+
     // We need to generate struct instances based off ParsedAttrInfo from
     // AttributeList.cpp.
-    OS << "  { ";
-    emitArgInfo(*I->second, OS);
-    OS << ", " << I->second->getValueAsBit("HasCustomParsing");
-    OS << " }";
+    SS << "  { ";
+    emitArgInfo(*I->second, SS);
+    SS << ", " << I->second->getValueAsBit("HasCustomParsing");
+    SS << ", " << I->second->isSubClassOf("TargetSpecificAttr");
+    SS << ", " << I->second->isSubClassOf("TypeAttr");
+    SS << ", " << IsKnownToGCC(*I->second);
+    SS << ", " << GenerateAppertainsTo(*I->second, OS);
+    SS << ", " << GenerateLangOptRequirements(*I->second, OS);
+    SS << ", " << GenerateTargetRequirements(*I->second, Dupes, OS);
+    SS << ", " << GenerateSpellingIndexToSemanticSpelling(*I->second, OS);
+    SS << " }";
 
     if (I + 1 != E)
-      OS << ",";
-    
-    OS << "  // AT_" << I->first << "\n";
+      SS << ",";
+
+    SS << "  // AT_" << I->first << "\n";
   }
+
+  OS << "static const ParsedAttrInfo AttrInfoMap[AttributeList::UnknownAttribute + 1] = {\n";
+  OS << SS.str();
   OS << "};\n\n";
 }
 
@@ -1724,50 +2496,80 @@
 void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS) {
   emitSourceFileHeader("Attribute name matcher", OS);
 
-  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
+  std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
+  std::vector<StringMatcher::StringPair> GNU, Declspec, CXX11, Keywords, Pragma;
+  std::set<std::string> Seen;
+  for (const auto *A : Attrs) {
+    const Record &Attr = *A;
 
-  std::vector<StringMatcher::StringPair> Matches;
-  for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end();
-       I != E; ++I) {
-    Record &Attr = **I;
-    
     bool SemaHandler = Attr.getValueAsBit("SemaHandler");
     bool Ignored = Attr.getValueAsBit("Ignored");
-    bool DistinctSpellings = Attr.getValueAsBit("DistinctSpellings");
     if (SemaHandler || Ignored) {
-      std::vector<Record*> Spellings = Attr.getValueAsListOfDefs("Spellings");
+      // Attribute spellings can be shared between target-specific attributes,
+      // and can be shared between syntaxes for the same attribute. For
+      // instance, an attribute can be spelled GNU<"interrupt"> for an ARM-
+      // specific attribute, or MSP430-specific attribute. Additionally, an
+      // attribute can be spelled GNU<"dllexport"> and Declspec<"dllexport">
+      // for the same semantic attribute. Ultimately, we need to map each of
+      // these to a single AttributeList::Kind value, but the StringMatcher
+      // class cannot handle duplicate match strings. So we generate a list of
+      // string to match based on the syntax, and emit multiple string matchers
+      // depending on the syntax used.
+      std::string AttrName;
+      if (Attr.isSubClassOf("TargetSpecificAttr") &&
+          !Attr.isValueUnset("ParseKind")) {
+        AttrName = Attr.getValueAsString("ParseKind");
+        if (Seen.find(AttrName) != Seen.end())
+          continue;
+        Seen.insert(AttrName);
+      } else
+        AttrName = NormalizeAttrName(StringRef(Attr.getName())).str();
 
-      for (std::vector<Record*>::const_iterator I = Spellings.begin(),
-           E = Spellings.end(); I != E; ++I) {
-        std::string RawSpelling = (*I)->getValueAsString("Name");
-        StringRef AttrName = NormalizeAttrName(DistinctSpellings
-                                                 ? StringRef(RawSpelling)
-                                                 : StringRef(Attr.getName()));
-
-        SmallString<64> Spelling;
-        if ((*I)->getValueAsString("Variety") == "CXX11") {
-          Spelling += (*I)->getValueAsString("Namespace");
+      std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attr);
+      for (const auto &S : Spellings) {
+        std::string RawSpelling = S.name();
+        std::vector<StringMatcher::StringPair> *Matches = nullptr;
+        std::string Spelling, Variety = S.variety();
+        if (Variety == "CXX11") {
+          Matches = &CXX11;
+          Spelling += S.nameSpace();
           Spelling += "::";
-        }
-        Spelling += NormalizeAttrSpelling(RawSpelling);
+        } else if (Variety == "GNU")
+          Matches = &GNU;
+        else if (Variety == "Declspec")
+          Matches = &Declspec;
+        else if (Variety == "Keyword")
+          Matches = &Keywords;
+        else if (Variety == "Pragma")
+          Matches = &Pragma;
 
+        assert(Matches && "Unsupported spelling variety found");
+
+        Spelling += NormalizeAttrSpelling(RawSpelling);
         if (SemaHandler)
-          Matches.push_back(
-            StringMatcher::StringPair(
-              StringRef(Spelling),
-              "return AttributeList::AT_" + AttrName.str() + ";"));
+          Matches->push_back(StringMatcher::StringPair(Spelling,
+                              "return AttributeList::AT_" + AttrName + ";"));
         else
-          Matches.push_back(
-            StringMatcher::StringPair(
-              StringRef(Spelling),
-              "return AttributeList::IgnoredAttribute;"));
+          Matches->push_back(StringMatcher::StringPair(Spelling,
+                              "return AttributeList::IgnoredAttribute;"));
       }
     }
   }
   
-  OS << "static AttributeList::Kind getAttrKind(StringRef Name) {\n";
-  StringMatcher("Name", Matches, OS).Emit();
-  OS << "return AttributeList::UnknownAttribute;\n"
+  OS << "static AttributeList::Kind getAttrKind(StringRef Name, ";
+  OS << "AttributeList::Syntax Syntax) {\n";
+  OS << "  if (AttributeList::AS_GNU == Syntax) {\n";
+  StringMatcher("Name", GNU, OS).Emit();
+  OS << "  } else if (AttributeList::AS_Declspec == Syntax) {\n";
+  StringMatcher("Name", Declspec, OS).Emit();
+  OS << "  } else if (AttributeList::AS_CXX11 == Syntax) {\n";
+  StringMatcher("Name", CXX11, OS).Emit();
+  OS << "  } else if (AttributeList::AS_Keyword == Syntax) {\n";
+  StringMatcher("Name", Keywords, OS).Emit();
+  OS << "  } else if (AttributeList::AS_Pragma == Syntax) {\n";
+  StringMatcher("Name", Pragma, OS).Emit();
+  OS << "  }\n";
+  OS << "  return AttributeList::UnknownAttribute;\n"
      << "}\n";
 }
 
@@ -1781,36 +2583,41 @@
     "    llvm_unreachable(\"Unknown attribute kind!\");\n"
     "    break;\n";
   std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), Args;
-  for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end();
-       I != E; ++I) {
-    Record &R = **I;
+  for (const auto *Attr : Attrs) {
+    const Record &R = *Attr;
     if (!R.getValueAsBit("ASTNode"))
       continue;
     OS << "  case attr::" << R.getName() << ": {\n";
+
+    // If the attribute has a semantically-meaningful name (which is determined
+    // by whether there is a Spelling enumeration for it), then write out the
+    // spelling used for the attribute.
+    std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(R);
+    if (Spellings.size() > 1 && !SpellingNamesAreCommon(Spellings))
+      OS << "    OS << \" \" << A->getSpelling();\n";
+
     Args = R.getValueAsListOfDefs("Args");
     if (!Args.empty()) {
       OS << "    const " << R.getName() << "Attr *SA = cast<" << R.getName()
          << "Attr>(A);\n";
-      for (std::vector<Record*>::iterator I = Args.begin(), E = Args.end();
-           I != E; ++I)
-        createArgument(**I, R.getName())->writeDump(OS);
+      for (const auto *Arg : Args)
+        createArgument(*Arg, R.getName())->writeDump(OS);
 
       // Code for detecting the last child.
       OS << "    bool OldMoreChildren = hasMoreChildren();\n";
-      OS << "    bool MoreChildren = OldMoreChildren;\n";     
+      OS << "    bool MoreChildren;\n";
 
-      for (std::vector<Record*>::iterator I = Args.begin(), E = Args.end();
-           I != E; ++I) {
+      for (auto AI = Args.begin(), AE = Args.end(); AI != AE; ++AI) {
         // More code for detecting the last child.
         OS << "    MoreChildren = OldMoreChildren";
-        for (std::vector<Record*>::iterator Next = I + 1; Next != E; ++Next) {
+        for (auto Next = AI + 1; Next != AE; ++Next) {
           OS << " || ";
           createArgument(**Next, R.getName())->writeHasChildren(OS);
         }
         OS << ";\n";
         OS << "    setMoreChildren(MoreChildren);\n";
 
-        createArgument(**I, R.getName())->writeDumpChildren(OS);
+        createArgument(**AI, R.getName())->writeDumpChildren(OS);
       }
 
       // Reset the last child.
@@ -1823,4 +2630,221 @@
   OS << "  }\n";
 }
 
+void EmitClangAttrParserStringSwitches(RecordKeeper &Records,
+                                       raw_ostream &OS) {
+  emitSourceFileHeader("Parser-related llvm::StringSwitch cases", OS);
+  emitClangAttrArgContextList(Records, OS);
+  emitClangAttrIdentifierArgList(Records, OS);
+  emitClangAttrTypeArgList(Records, OS);
+  emitClangAttrLateParsedList(Records, OS);
+}
+
+class DocumentationData {
+public:
+  const Record *Documentation;
+  const Record *Attribute;
+
+  DocumentationData(const Record &Documentation, const Record &Attribute)
+      : Documentation(&Documentation), Attribute(&Attribute) {}
+};
+
+static void WriteCategoryHeader(const Record *DocCategory,
+                                raw_ostream &OS) {
+  const std::string &Name = DocCategory->getValueAsString("Name");
+  OS << Name << "\n" << std::string(Name.length(), '=') << "\n";
+
+  // If there is content, print that as well.
+  std::string ContentStr = DocCategory->getValueAsString("Content");
+  if (!ContentStr.empty()) {
+    // Trim leading and trailing newlines and spaces.
+    StringRef Content(ContentStr);
+    while (Content.startswith("\r") || Content.startswith("\n") ||
+           Content.startswith(" ") || Content.startswith("\t"))
+           Content = Content.substr(1);
+    while (Content.endswith("\r") || Content.endswith("\n") ||
+           Content.endswith(" ") || Content.endswith("\t"))
+           Content = Content.substr(0, Content.size() - 1);
+    OS << Content;
+  }
+  OS << "\n\n";
+}
+
+enum SpellingKind {
+  GNU = 1 << 0,
+  CXX11 = 1 << 1,
+  Declspec = 1 << 2,
+  Keyword = 1 << 3,
+  Pragma = 1 << 4
+};
+
+static void WriteDocumentation(const DocumentationData &Doc,
+                               raw_ostream &OS) {
+  // FIXME: there is no way to have a per-spelling category for the attribute
+  // documentation. This may not be a limiting factor since the spellings
+  // should generally be consistently applied across the category.
+
+  std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(*Doc.Attribute);
+
+  // Determine the heading to be used for this attribute.
+  std::string Heading = Doc.Documentation->getValueAsString("Heading");
+  bool CustomHeading = !Heading.empty();
+  if (Heading.empty()) {
+    // If there's only one spelling, we can simply use that.
+    if (Spellings.size() == 1)
+      Heading = Spellings.begin()->name();
+    else {
+      std::set<std::string> Uniques;
+      for (auto I = Spellings.begin(), E = Spellings.end();
+           I != E && Uniques.size() <= 1; ++I) {
+        std::string Spelling = NormalizeNameForSpellingComparison(I->name());
+        Uniques.insert(Spelling);
+      }
+      // If the semantic map has only one spelling, that is sufficient for our
+      // needs.
+      if (Uniques.size() == 1)
+        Heading = *Uniques.begin();
+    }
+  }
+
+  // If the heading is still empty, it is an error.
+  if (Heading.empty())
+    PrintFatalError(Doc.Attribute->getLoc(),
+                    "This attribute requires a heading to be specified");
+
+  // Gather a list of unique spellings; this is not the same as the semantic
+  // spelling for the attribute. Variations in underscores and other non-
+  // semantic characters are still acceptable.
+  std::vector<std::string> Names;
+
+  unsigned SupportedSpellings = 0;
+  for (const auto &I : Spellings) {
+    SpellingKind Kind = StringSwitch<SpellingKind>(I.variety())
+                            .Case("GNU", GNU)
+                            .Case("CXX11", CXX11)
+                            .Case("Declspec", Declspec)
+                            .Case("Keyword", Keyword)
+                            .Case("Pragma", Pragma);
+
+    // Mask in the supported spelling.
+    SupportedSpellings |= Kind;
+
+    std::string Name;
+    if (Kind == CXX11 && !I.nameSpace().empty())
+      Name = I.nameSpace() + "::";
+    Name += I.name();
+
+    // If this name is the same as the heading, do not add it.
+    if (Name != Heading)
+      Names.push_back(Name);
+  }
+
+  // Print out the heading for the attribute. If there are alternate spellings,
+  // then display those after the heading.
+  if (!CustomHeading && !Names.empty()) {
+    Heading += " (";
+    for (auto I = Names.begin(), E = Names.end(); I != E; ++I) {
+      if (I != Names.begin())
+        Heading += ", ";
+      Heading += *I;
+    }
+    Heading += ")";
+  }
+  OS << Heading << "\n" << std::string(Heading.length(), '-') << "\n";
+
+  if (!SupportedSpellings)
+    PrintFatalError(Doc.Attribute->getLoc(),
+                    "Attribute has no supported spellings; cannot be "
+                    "documented");
+
+  // List what spelling syntaxes the attribute supports.
+  OS << ".. csv-table:: Supported Syntaxes\n";
+  OS << "   :header: \"GNU\", \"C++11\", \"__declspec\", \"Keyword\",";
+  OS << " \"Pragma\"\n\n";
+  OS << "   \"";
+  if (SupportedSpellings & GNU) OS << "X";
+  OS << "\",\"";
+  if (SupportedSpellings & CXX11) OS << "X";
+  OS << "\",\"";
+  if (SupportedSpellings & Declspec) OS << "X";
+  OS << "\",\"";
+  if (SupportedSpellings & Keyword) OS << "X";
+  OS << "\", \"";
+  if (SupportedSpellings & Pragma) OS << "X";
+  OS << "\"\n\n";
+
+  // If the attribute is deprecated, print a message about it, and possibly
+  // provide a replacement attribute.
+  if (!Doc.Documentation->isValueUnset("Deprecated")) {
+    OS << "This attribute has been deprecated, and may be removed in a future "
+       << "version of Clang.";
+    const Record &Deprecated = *Doc.Documentation->getValueAsDef("Deprecated");
+    std::string Replacement = Deprecated.getValueAsString("Replacement");
+    if (!Replacement.empty())
+      OS << "  This attribute has been superseded by ``"
+         << Replacement << "``.";
+    OS << "\n\n";
+  }
+
+  std::string ContentStr = Doc.Documentation->getValueAsString("Content");
+  // Trim leading and trailing newlines and spaces.
+  StringRef Content(ContentStr);
+  while (Content.startswith("\r") || Content.startswith("\n") ||
+         Content.startswith(" ") || Content.startswith("\t"))
+    Content = Content.substr(1);
+  while (Content.endswith("\r") || Content.endswith("\n") ||
+         Content.endswith(" ") || Content.endswith("\t"))
+    Content = Content.substr(0, Content.size() - 1);
+  OS << Content;
+
+  OS << "\n\n\n";
+}
+
+void EmitClangAttrDocs(RecordKeeper &Records, raw_ostream &OS) {
+  // Get the documentation introduction paragraph.
+  const Record *Documentation = Records.getDef("GlobalDocumentation");
+  if (!Documentation) {
+    PrintFatalError("The Documentation top-level definition is missing, "
+                    "no documentation will be generated.");
+    return;
+  }
+
+  OS << Documentation->getValueAsString("Intro") << "\n";
+
+  // Gather the Documentation lists from each of the attributes, based on the
+  // category provided.
+  std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
+  std::map<const Record *, std::vector<DocumentationData>> SplitDocs;
+  for (const auto *A : Attrs) {
+    const Record &Attr = *A;
+    std::vector<Record *> Docs = Attr.getValueAsListOfDefs("Documentation");
+    for (const auto *D : Docs) {
+      const Record &Doc = *D;
+      const Record *Category = Doc.getValueAsDef("Category");
+      // If the category is "undocumented", then there cannot be any other
+      // documentation categories (otherwise, the attribute would become
+      // documented).
+      std::string Cat = Category->getValueAsString("Name");
+      bool Undocumented = Cat == "Undocumented";
+      if (Undocumented && Docs.size() > 1)
+        PrintFatalError(Doc.getLoc(),
+                        "Attribute is \"Undocumented\", but has multiple "
+                        "documentation categories");      
+
+      if (!Undocumented)
+        SplitDocs[Category].push_back(DocumentationData(Doc, Attr));
+    }
+  }
+
+  // Having split the attributes out based on what documentation goes where,
+  // we can begin to generate sections of documentation.
+  for (const auto &I : SplitDocs) {
+    WriteCategoryHeader(I.first, OS);
+
+    // Walk over each of the attributes in the category and write out their
+    // documentation.
+    for (const auto &Doc : I.second)
+      WriteDocumentation(Doc, OS);
+  }
+}
+
 } // end namespace clang
diff --git a/utils/TableGen/ClangCommentHTMLTagsEmitter.cpp b/utils/TableGen/ClangCommentHTMLTagsEmitter.cpp
index bfcd2cf..22c6226 100644
--- a/utils/TableGen/ClangCommentHTMLTagsEmitter.cpp
+++ b/utils/TableGen/ClangCommentHTMLTagsEmitter.cpp
@@ -12,6 +12,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "TableGenBackends.h"
 #include "llvm/TableGen/Record.h"
 #include "llvm/TableGen/StringMatcher.h"
 #include "llvm/TableGen/TableGenBackend.h"
@@ -19,14 +20,11 @@
 
 using namespace llvm;
 
-namespace clang {
-void EmitClangCommentHTMLTags(RecordKeeper &Records, raw_ostream &OS) {
+void clang::EmitClangCommentHTMLTags(RecordKeeper &Records, raw_ostream &OS) {
   std::vector<Record *> Tags = Records.getAllDerivedDefinitions("Tag");
   std::vector<StringMatcher::StringPair> Matches;
-  for (std::vector<Record *>::iterator I = Tags.begin(), E = Tags.end();
-       I != E; ++I) {
-    Record &Tag = **I;
-    std::string Spelling = Tag.getValueAsString("Spelling");
+  for (Record *Tag : Tags) {
+    std::string Spelling = Tag->getValueAsString("Spelling");
     Matches.push_back(StringMatcher::StringPair(Spelling, "return true;"));
   }
 
@@ -38,19 +36,17 @@
      << "}\n\n";
 }
 
-void EmitClangCommentHTMLTagsProperties(RecordKeeper &Records,
-                                        raw_ostream &OS) {
+void clang::EmitClangCommentHTMLTagsProperties(RecordKeeper &Records,
+                                               raw_ostream &OS) {
   std::vector<Record *> Tags = Records.getAllDerivedDefinitions("Tag");
   std::vector<StringMatcher::StringPair> MatchesEndTagOptional;
   std::vector<StringMatcher::StringPair> MatchesEndTagForbidden;
-  for (std::vector<Record *>::iterator I = Tags.begin(), E = Tags.end();
-       I != E; ++I) {
-    Record &Tag = **I;
-    std::string Spelling = Tag.getValueAsString("Spelling");
+  for (Record *Tag : Tags) {
+    std::string Spelling = Tag->getValueAsString("Spelling");
     StringMatcher::StringPair Match(Spelling, "return true;");
-    if (Tag.getValueAsBit("EndTagOptional"))
+    if (Tag->getValueAsBit("EndTagOptional"))
       MatchesEndTagOptional.push_back(Match);
-    if (Tag.getValueAsBit("EndTagForbidden"))
+    if (Tag->getValueAsBit("EndTagForbidden"))
       MatchesEndTagForbidden.push_back(Match);
   }
 
@@ -66,5 +62,4 @@
   OS << "  return false;\n"
      << "}\n\n";
 }
-} // end namespace clang
 
diff --git a/utils/TableGen/ClangDiagnosticsEmitter.cpp b/utils/TableGen/ClangDiagnosticsEmitter.cpp
index db159d1..e517755 100644
--- a/utils/TableGen/ClangDiagnosticsEmitter.cpp
+++ b/utils/TableGen/ClangDiagnosticsEmitter.cpp
@@ -135,7 +135,7 @@
 
     const Record *ExplicitDef;
 
-    GroupInfo() : ExplicitDef(0) {}
+    GroupInfo() : ExplicitDef(nullptr) {}
   };
 } // end anonymous namespace.
 
@@ -170,7 +170,8 @@
   for (unsigned i = 0, e = Diags.size(); i != e; ++i) {
     const Record *R = Diags[i];
     DefInit *DI = dyn_cast<DefInit>(R->getValueInit("Group"));
-    if (DI == 0) continue;
+    if (!DI)
+      continue;
     assert(R->getValueAsDef("Class")->getName() != "CLASS_NOTE" &&
            "Note can't be in a DiagGroup");
     std::string GroupName = DI->getDef()->getValueAsString("GroupName");
@@ -357,8 +358,9 @@
 }
 
 bool InferPedantic::isOffByDefault(const Record *Diag) {
-  const std::string &DefMap = Diag->getValueAsDef("DefaultMapping")->getName();
-  return DefMap == "MAP_IGNORE";
+  const std::string &DefSeverity =
+      Diag->getValueAsDef("DefaultSeverity")->getValueAsString("Name");
+  return DefSeverity == "Ignored";
 }
 
 bool InferPedantic::groupInPedantic(const Record *Group, bool increment) {
@@ -472,6 +474,11 @@
   return ClsName == "CLASS_ERROR";
 }
 
+static bool isRemark(const Record &Diag) {
+  const std::string &ClsName = Diag.getValueAsDef("Class")->getName();
+  return ClsName == "CLASS_REMARK";
+}
+
 /// ClangDiagsDefsEmitter - The top-level class emits .def files containing
 /// declarations of Clang diagnostics.
 namespace clang {
@@ -502,7 +509,7 @@
   // Compute the set of diagnostics that are in -Wpedantic.
   RecordSet DiagsInPedantic;
   InferPedantic inferPedantic(DGParentMap, Diags, DiagGroups, DiagsInGroup);
-  inferPedantic.compute(&DiagsInPedantic, (RecordVec*)0);
+  inferPedantic.compute(&DiagsInPedantic, (RecordVec*)nullptr);
 
   for (unsigned i = 0, e = Diags.size(); i != e; ++i) {
     const Record &R = *Diags[i];
@@ -518,13 +525,22 @@
       }
     }
 
+    // Check that all remarks have an associated diagnostic group.
+    if (isRemark(R)) {
+      if (!isa<DefInit>(R.getValueInit("Group"))) {
+        PrintFatalError(R.getLoc(), "Error " + R.getName() +
+                                        " not in any diagnostic group");
+      }
+    }
+
     // Filter by component.
     if (!Component.empty() && Component != R.getValueAsString("Component"))
       continue;
 
     OS << "DIAG(" << R.getName() << ", ";
     OS << R.getValueAsDef("Class")->getName();
-    OS << ", diag::" << R.getValueAsDef("DefaultMapping")->getName();
+    OS << ", (unsigned)diag::Severity::"
+       << R.getValueAsDef("DefaultSeverity")->getValueAsString("Name");
 
     // Description string.
     OS << ", \"";
@@ -555,8 +571,7 @@
     else
       OS << ", false";
 
-    // Default warning show in system header bit.
-    if (R.getValueAsBit("WarningShowInSystemHeader"))
+    if (R.getValueAsBit("ShowInSystemHeader"))
       OS << ", true";
     else
       OS << ", false";
@@ -581,16 +596,240 @@
   return enumName.str();
 }
 
+/// \brief Emit the array of diagnostic subgroups.
+///
+/// The array of diagnostic subgroups contains for each group a list of its
+/// subgroups. The individual lists are separated by '-1'. Groups with no
+/// subgroups are skipped.
+///
+/// \code
+///   static const int16_t DiagSubGroups[] = {
+///     /* Empty */ -1,
+///     /* DiagSubGroup0 */ 142, -1,
+///     /* DiagSubGroup13 */ 265, 322, 399, -1
+///   }
+/// \endcode
+///
+static void emitDiagSubGroups(std::map<std::string, GroupInfo> &DiagsInGroup,
+                              RecordVec &GroupsInPedantic, raw_ostream &OS) {
+  OS << "static const int16_t DiagSubGroups[] = {\n"
+     << "  /* Empty */ -1,\n";
+  for (auto const &I : DiagsInGroup) {
+    const bool IsPedantic = I.first == "pedantic";
+
+    const std::vector<std::string> &SubGroups = I.second.SubGroups;
+    if (!SubGroups.empty() || (IsPedantic && !GroupsInPedantic.empty())) {
+      OS << "  /* DiagSubGroup" << I.second.IDNo << " */ ";
+      for (auto const &SubGroup : SubGroups) {
+        std::map<std::string, GroupInfo>::const_iterator RI =
+            DiagsInGroup.find(SubGroup);
+        assert(RI != DiagsInGroup.end() && "Referenced without existing?");
+        OS << RI->second.IDNo << ", ";
+      }
+      // Emit the groups implicitly in "pedantic".
+      if (IsPedantic) {
+        for (auto const &Group : GroupsInPedantic) {
+          const std::string &GroupName = Group->getValueAsString("GroupName");
+          std::map<std::string, GroupInfo>::const_iterator RI =
+              DiagsInGroup.find(GroupName);
+          assert(RI != DiagsInGroup.end() && "Referenced without existing?");
+          OS << RI->second.IDNo << ", ";
+        }
+      }
+
+      OS << "-1,\n";
+    }
+  }
+  OS << "};\n\n";
+}
+
+/// \brief Emit the list of diagnostic arrays.
+///
+/// This data structure is a large array that contains itself arrays of varying
+/// size. Each array represents a list of diagnostics. The different arrays are
+/// separated by the value '-1'.
+///
+/// \code
+///   static const int16_t DiagArrays[] = {
+///     /* Empty */ -1,
+///     /* DiagArray1 */ diag::warn_pragma_message,
+///                      -1,
+///     /* DiagArray2 */ diag::warn_abs_too_small,
+///                      diag::warn_unsigned_abs,
+///                      diag::warn_wrong_absolute_value_type,
+///                      -1
+///   };
+/// \endcode
+///
+static void emitDiagArrays(std::map<std::string, GroupInfo> &DiagsInGroup,
+                           RecordVec &DiagsInPedantic, raw_ostream &OS) {
+  OS << "static const int16_t DiagArrays[] = {\n"
+     << "  /* Empty */ -1,\n";
+  for (auto const &I : DiagsInGroup) {
+    const bool IsPedantic = I.first == "pedantic";
+
+    const std::vector<const Record *> &V = I.second.DiagsInGroup;
+    if (!V.empty() || (IsPedantic && !DiagsInPedantic.empty())) {
+      OS << "  /* DiagArray" << I.second.IDNo << " */ ";
+      for (auto *Record : V)
+        OS << "diag::" << Record->getName() << ", ";
+      // Emit the diagnostics implicitly in "pedantic".
+      if (IsPedantic) {
+        for (auto const &Diag : DiagsInPedantic)
+          OS << "diag::" << Diag->getName() << ", ";
+      }
+      OS << "-1,\n";
+    }
+  }
+  OS << "};\n\n";
+}
+
+/// \brief Emit a list of group names.
+///
+/// This creates a long string which by itself contains a list of pascal style
+/// strings, which consist of a length byte directly followed by the string.
+///
+/// \code
+///   static const char DiagGroupNames[] = {
+///     \000\020#pragma-messages\t#warnings\020CFString-literal"
+///   };
+/// \endcode
+static void emitDiagGroupNames(StringToOffsetTable &GroupNames,
+                               raw_ostream &OS) {
+  OS << "static const char DiagGroupNames[] = {\n";
+  GroupNames.EmitString(OS);
+  OS << "};\n\n";
+}
+
+/// \brief Emit diagnostic arrays and related data structures.
+///
+/// This creates the actual diagnostic array, an array of diagnostic subgroups
+/// and an array of subgroup names.
+///
+/// \code
+///  #ifdef GET_DIAG_ARRAYS
+///     static const int16_t DiagArrays[];
+///     static const int16_t DiagSubGroups[];
+///     static const char DiagGroupNames[];
+///  #endif
+///  \endcode
+static void emitAllDiagArrays(std::map<std::string, GroupInfo> &DiagsInGroup,
+                              RecordVec &DiagsInPedantic,
+                              RecordVec &GroupsInPedantic,
+                              StringToOffsetTable &GroupNames,
+                              raw_ostream &OS) {
+  OS << "\n#ifdef GET_DIAG_ARRAYS\n";
+  emitDiagArrays(DiagsInGroup, DiagsInPedantic, OS);
+  emitDiagSubGroups(DiagsInGroup, GroupsInPedantic, OS);
+  emitDiagGroupNames(GroupNames, OS);
+  OS << "#endif // GET_DIAG_ARRAYS\n\n";
+}
+
+/// \brief Emit diagnostic table.
+///
+/// The table is sorted by the name of the diagnostic group. Each element
+/// consists of the name of the diagnostic group (given as offset in the
+/// group name table), a reference to a list of diagnostics (optional) and a
+/// reference to a set of subgroups (optional).
+///
+/// \code
+/// #ifdef GET_DIAG_TABLE
+///  {/* abi */              159, /* DiagArray11 */ 19, /* Empty */          0},
+///  {/* aggregate-return */ 180, /* Empty */        0, /* Empty */          0},
+///  {/* all */              197, /* Empty */        0, /* DiagSubGroup13 */ 3},
+///  {/* deprecated */       1981,/* DiagArray1 */ 348, /* DiagSubGroup3 */  9},
+/// #endif
+/// \endcode
+static void emitDiagTable(std::map<std::string, GroupInfo> &DiagsInGroup,
+                          RecordVec &DiagsInPedantic,
+                          RecordVec &GroupsInPedantic,
+                          StringToOffsetTable &GroupNames, raw_ostream &OS) {
+  unsigned MaxLen = 0;
+
+  for (auto const &I: DiagsInGroup)
+    MaxLen = std::max(MaxLen, (unsigned)I.first.size());
+
+  OS << "\n#ifdef GET_DIAG_TABLE\n";
+  unsigned SubGroupIndex = 1, DiagArrayIndex = 1;
+  for (auto const &I: DiagsInGroup) {
+    // Group option string.
+    OS << "  { /* ";
+    if (I.first.find_first_not_of("abcdefghijklmnopqrstuvwxyz"
+                                   "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                                   "0123456789!@#$%^*-+=:?") !=
+        std::string::npos)
+      PrintFatalError("Invalid character in diagnostic group '" + I.first +
+                      "'");
+    OS << I.first << " */ " << std::string(MaxLen - I.first.size(), ' ');
+    // Store a pascal-style length byte at the beginning of the string.
+    std::string Name = char(I.first.size()) + I.first;
+    OS << GroupNames.GetOrAddStringOffset(Name, false) << ", ";
+
+    // Special handling for 'pedantic'.
+    const bool IsPedantic = I.first == "pedantic";
+
+    // Diagnostics in the group.
+    const std::vector<const Record *> &V = I.second.DiagsInGroup;
+    const bool hasDiags =
+        !V.empty() || (IsPedantic && !DiagsInPedantic.empty());
+    if (hasDiags) {
+      OS << "/* DiagArray" << I.second.IDNo << " */ " << DiagArrayIndex
+         << ", ";
+      if (IsPedantic)
+        DiagArrayIndex += DiagsInPedantic.size();
+      DiagArrayIndex += V.size() + 1;
+    } else {
+      OS << "/* Empty */     0, ";
+    }
+
+    // Subgroups.
+    const std::vector<std::string> &SubGroups = I.second.SubGroups;
+    const bool hasSubGroups =
+        !SubGroups.empty() || (IsPedantic && !GroupsInPedantic.empty());
+    if (hasSubGroups) {
+      OS << "/* DiagSubGroup" << I.second.IDNo << " */ " << SubGroupIndex;
+      if (IsPedantic)
+        SubGroupIndex += GroupsInPedantic.size();
+      SubGroupIndex += SubGroups.size() + 1;
+    } else {
+      OS << "/* Empty */         0";
+    }
+
+    OS << " },\n";
+  }
+  OS << "#endif // GET_DIAG_TABLE\n\n";
+}
+
+/// \brief Emit the table of diagnostic categories.
+///
+/// The table has the form of macro calls that have two parameters. The
+/// category's name as well as an enum that represents the category. The
+/// table can be used by defining the macro 'CATEGORY' and including this
+/// table right after.
+///
+/// \code
+/// #ifdef GET_CATEGORY_TABLE
+///   CATEGORY("Semantic Issue", DiagCat_Semantic_Issue)
+///   CATEGORY("Lambda Issue", DiagCat_Lambda_Issue)
+/// #endif
+/// \endcode
+static void emitCategoryTable(RecordKeeper &Records, raw_ostream &OS) {
+  DiagCategoryIDMap CategoriesByID(Records);
+  OS << "\n#ifdef GET_CATEGORY_TABLE\n";
+  for (auto const &C : CategoriesByID)
+    OS << "CATEGORY(\"" << C << "\", " << getDiagCategoryEnum(C) << ")\n";
+  OS << "#endif // GET_CATEGORY_TABLE\n\n";
+}
+
 namespace clang {
 void EmitClangDiagGroups(RecordKeeper &Records, raw_ostream &OS) {
   // Compute a mapping from a DiagGroup to all of its parents.
   DiagGroupParentMap DGParentMap(Records);
 
-  std::vector<Record*> Diags =
-    Records.getAllDerivedDefinitions("Diagnostic");
+  std::vector<Record *> Diags = Records.getAllDerivedDefinitions("Diagnostic");
 
-  std::vector<Record*> DiagGroups
-    = Records.getAllDerivedDefinitions("DiagGroup");
+  std::vector<Record *> DiagGroups =
+      Records.getAllDerivedDefinitions("DiagGroup");
 
   std::map<std::string, GroupInfo> DiagsInGroup;
   groupDiagnostics(Diags, DiagGroups, DiagsInGroup);
@@ -603,135 +842,21 @@
   InferPedantic inferPedantic(DGParentMap, Diags, DiagGroups, DiagsInGroup);
   inferPedantic.compute(&DiagsInPedantic, &GroupsInPedantic);
 
-  // Walk through the groups emitting an array for each diagnostic of the diags
-  // that are mapped to.
-  OS << "\n#ifdef GET_DIAG_ARRAYS\n";
-  unsigned MaxLen = 0;
-  OS << "static const int16_t DiagArrays[] = {\n"
-     << "  /* Empty */ -1,\n";
-  for (std::map<std::string, GroupInfo>::const_iterator
-       I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I) {
-    MaxLen = std::max(MaxLen, (unsigned)I->first.size());
-    const bool IsPedantic = I->first == "pedantic";
-
-    const std::vector<const Record*> &V = I->second.DiagsInGroup;
-    if (!V.empty() || (IsPedantic && !DiagsInPedantic.empty())) {
-      OS << "  /* DiagArray" << I->second.IDNo << " */ ";
-      for (unsigned i = 0, e = V.size(); i != e; ++i)
-        OS << "diag::" << V[i]->getName() << ", ";
-      // Emit the diagnostics implicitly in "pedantic".
-      if (IsPedantic) {
-        for (unsigned i = 0, e = DiagsInPedantic.size(); i != e; ++i)
-          OS << "diag::" << DiagsInPedantic[i]->getName() << ", ";
-      }
-      OS << "-1,\n";
-    }
-  }
-  OS << "};\n\n";
-
-  OS << "static const int16_t DiagSubGroups[] = {\n"
-     << "  /* Empty */ -1,\n";
-  for (std::map<std::string, GroupInfo>::const_iterator
-       I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I) {
-    const bool IsPedantic = I->first == "pedantic";
-
-    const std::vector<std::string> &SubGroups = I->second.SubGroups;
-    if (!SubGroups.empty() || (IsPedantic && !GroupsInPedantic.empty())) {
-      OS << "  /* DiagSubGroup" << I->second.IDNo << " */ ";
-      for (unsigned i = 0, e = SubGroups.size(); i != e; ++i) {
-        std::map<std::string, GroupInfo>::const_iterator RI =
-          DiagsInGroup.find(SubGroups[i]);
-        assert(RI != DiagsInGroup.end() && "Referenced without existing?");
-        OS << RI->second.IDNo << ", ";
-      }
-      // Emit the groups implicitly in "pedantic".
-      if (IsPedantic) {
-        for (unsigned i = 0, e = GroupsInPedantic.size(); i != e; ++i) {
-          const std::string &GroupName =
-            GroupsInPedantic[i]->getValueAsString("GroupName");
-          std::map<std::string, GroupInfo>::const_iterator RI =
-            DiagsInGroup.find(GroupName);
-          assert(RI != DiagsInGroup.end() && "Referenced without existing?");
-          OS << RI->second.IDNo << ", ";
-        }
-      }
-
-      OS << "-1,\n";
-    }
-  }
-  OS << "};\n\n";
-
   StringToOffsetTable GroupNames;
   for (std::map<std::string, GroupInfo>::const_iterator
-         I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I) {
+           I = DiagsInGroup.begin(),
+           E = DiagsInGroup.end();
+       I != E; ++I) {
     // Store a pascal-style length byte at the beginning of the string.
     std::string Name = char(I->first.size()) + I->first;
     GroupNames.GetOrAddStringOffset(Name, false);
   }
 
-  OS << "static const char DiagGroupNames[] = {\n";
-  GroupNames.EmitString(OS);
-  OS << "};\n\n";
-
-  OS << "#endif // GET_DIAG_ARRAYS\n\n";
-
-  // Emit the table now.
-  OS << "\n#ifdef GET_DIAG_TABLE\n";
-  unsigned SubGroupIndex = 1, DiagArrayIndex = 1;
-  for (std::map<std::string, GroupInfo>::const_iterator
-       I = DiagsInGroup.begin(), E = DiagsInGroup.end(); I != E; ++I) {
-    // Group option string.
-    OS << "  { /* ";
-    if (I->first.find_first_not_of("abcdefghijklmnopqrstuvwxyz"
-                                   "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-                                   "0123456789!@#$%^*-+=:?")!=std::string::npos)
-      PrintFatalError("Invalid character in diagnostic group '" +
-                      I->first + "'");
-    OS << I->first << " */ " << std::string(MaxLen-I->first.size(), ' ');
-    // Store a pascal-style length byte at the beginning of the string.
-    std::string Name = char(I->first.size()) + I->first;
-    OS << GroupNames.GetOrAddStringOffset(Name, false) << ", ";
-
-    // Special handling for 'pedantic'.
-    const bool IsPedantic = I->first == "pedantic";
-
-    // Diagnostics in the group.
-    const std::vector<const Record*> &V = I->second.DiagsInGroup;
-    const bool hasDiags = !V.empty() ||
-                          (IsPedantic && !DiagsInPedantic.empty());
-    if (hasDiags) {
-      OS << "/* DiagArray" << I->second.IDNo << " */ "
-         << DiagArrayIndex << ", ";
-      if (IsPedantic)
-        DiagArrayIndex += DiagsInPedantic.size();
-      DiagArrayIndex += V.size() + 1;
-    } else {
-      OS << "/* Empty */     0, ";
-    }
-
-    // Subgroups.
-    const std::vector<std::string> &SubGroups = I->second.SubGroups;
-    const bool hasSubGroups = !SubGroups.empty() ||
-                              (IsPedantic && !GroupsInPedantic.empty());
-    if (hasSubGroups) {
-      OS << "/* DiagSubGroup" << I->second.IDNo << " */ " << SubGroupIndex;
-      if (IsPedantic)
-        SubGroupIndex += GroupsInPedantic.size();
-      SubGroupIndex += SubGroups.size() + 1;
-    } else {
-      OS << "/* Empty */         0";
-    }
-    OS << " },\n";
-  }
-  OS << "#endif // GET_DIAG_TABLE\n\n";
-
-  // Emit the category table next.
-  DiagCategoryIDMap CategoriesByID(Records);
-  OS << "\n#ifdef GET_CATEGORY_TABLE\n";
-  for (DiagCategoryIDMap::const_iterator I = CategoriesByID.begin(),
-       E = CategoriesByID.end(); I != E; ++I)
-    OS << "CATEGORY(\"" << *I << "\", " << getDiagCategoryEnum(*I) << ")\n";
-  OS << "#endif // GET_CATEGORY_TABLE\n\n";
+  emitAllDiagArrays(DiagsInGroup, DiagsInPedantic, GroupsInPedantic, GroupNames,
+                    OS);
+  emitDiagTable(DiagsInGroup, DiagsInPedantic, GroupsInPedantic, GroupNames,
+                OS);
+  emitCategoryTable(Records, OS);
 }
 } // end namespace clang
 
@@ -748,17 +873,6 @@
 
   std::string Name;
 };
-
-struct RecordIndexElementSorter :
-  public std::binary_function<RecordIndexElement, RecordIndexElement, bool> {
-
-  bool operator()(RecordIndexElement const &Lhs,
-                  RecordIndexElement const &Rhs) const {
-    return Lhs.Name < Rhs.Name;
-  }
-
-};
-
 } // end anonymous namespace.
 
 namespace clang {
@@ -773,7 +887,9 @@
     Index.push_back(RecordIndexElement(R));
   }
 
-  std::sort(Index.begin(), Index.end(), RecordIndexElementSorter());
+  std::sort(Index.begin(), Index.end(),
+            [](const RecordIndexElement &Lhs,
+               const RecordIndexElement &Rhs) { return Lhs.Name < Rhs.Name; });
 
   for (unsigned i = 0, e = Index.size(); i != e; ++i) {
     const RecordIndexElement &R = Index[i];
diff --git a/utils/TableGen/ClangSACheckersEmitter.cpp b/utils/TableGen/ClangSACheckersEmitter.cpp
index 8c74064..115527a 100644
--- a/utils/TableGen/ClangSACheckersEmitter.cpp
+++ b/utils/TableGen/ClangSACheckersEmitter.cpp
@@ -129,7 +129,7 @@
 
   for (unsigned i = 0, e = checkers.size(); i != e; ++i) {
     Record *R = checkers[i];
-    Record *package = 0;
+    Record *package = nullptr;
     if (DefInit *
           DI = dyn_cast<DefInit>(R->getValueInit("ParentPackage")))
       package = DI->getDef();
diff --git a/utils/TableGen/NeonEmitter.cpp b/utils/TableGen/NeonEmitter.cpp
index 23c3b17..cd27fbc 100644
--- a/utils/TableGen/NeonEmitter.cpp
+++ b/utils/TableGen/NeonEmitter.cpp
@@ -18,8 +18,9 @@
 // CodeGen library.
 //
 // Additional validation code can be generated by this file when runHeader() is
-// called, rather than the normal run() entry point.  A complete set of tests
-// for Neon intrinsics can be generated by calling the runTests() entry point.
+// called, rather than the normal run() entry point.
+//
+// See also the documentation in include/clang/Basic/arm_neon.td.
 //
 //===----------------------------------------------------------------------===//
 
@@ -31,283 +32,477 @@
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/TableGen/Error.h"
 #include "llvm/TableGen/Record.h"
+#include "llvm/TableGen/SetTheory.h"
 #include "llvm/TableGen/TableGenBackend.h"
 #include <string>
+#include <sstream>
+#include <vector>
+#include <map>
+#include <algorithm>
 using namespace llvm;
 
-enum OpKind {
-  OpNone,
-  OpUnavailable,
-  OpAdd,
-  OpAddl,
-  OpAddlHi,
-  OpAddw,
-  OpAddwHi,
-  OpSub,
-  OpSubl,
-  OpSublHi,
-  OpSubw,
-  OpSubwHi,
-  OpMul,
-  OpMla,
-  OpMlal,
-  OpMullHi,
-  OpMlalHi,
-  OpMls,
-  OpMlsl,
-  OpMlslHi,
-  OpMulN,
-  OpMlaN,
-  OpMlsN,
-  OpMlalN,
-  OpMlslN,
-  OpMulLane,
-  OpMulXLane,
-  OpMullLane,
-  OpMullHiLane,
-  OpMlaLane,
-  OpMlsLane,
-  OpMlalLane,
-  OpMlalHiLane,
-  OpMlslLane,
-  OpMlslHiLane,
-  OpQDMullLane,
-  OpQDMullHiLane,
-  OpQDMlalLane,
-  OpQDMlalHiLane,
-  OpQDMlslLane,
-  OpQDMlslHiLane,
-  OpQDMulhLane,
-  OpQRDMulhLane,
-  OpFMSLane,
-  OpFMSLaneQ,
-  OpTrn1,
-  OpZip1,
-  OpUzp1,
-  OpTrn2,
-  OpZip2,
-  OpUzp2,
-  OpEq,
-  OpGe,
-  OpLe,
-  OpGt,
-  OpLt,
-  OpNeg,
-  OpNot,
-  OpAnd,
-  OpOr,
-  OpXor,
-  OpAndNot,
-  OpOrNot,
-  OpCast,
-  OpConcat,
-  OpDup,
-  OpDupLane,
-  OpHi,
-  OpLo,
-  OpSelect,
-  OpRev16,
-  OpRev32,
-  OpRev64,
-  OpXtnHi,
-  OpSqxtunHi,
-  OpQxtnHi,
-  OpFcvtnHi,
-  OpFcvtlHi,
-  OpFcvtxnHi,
-  OpReinterpret,
-  OpAddhnHi,
-  OpRAddhnHi,
-  OpSubhnHi,
-  OpRSubhnHi,
-  OpAbdl,
-  OpAbdlHi,
-  OpAba,
-  OpAbal,
-  OpAbalHi,
-  OpQDMullHi,
-  OpQDMlalHi,
-  OpQDMlslHi,
-  OpDiv,
-  OpLongHi,
-  OpNarrowHi,
-  OpMovlHi,
-  OpCopyLane,
-  OpCopyQLane,
-  OpCopyLaneQ,
-  OpScalarMulLane,
-  OpScalarMulLaneQ,
-  OpScalarMulXLane,
-  OpScalarMulXLaneQ,
-  OpScalarVMulXLane,
-  OpScalarVMulXLaneQ
-};
+namespace {
+
+// While globals are generally bad, this one allows us to perform assertions
+// liberally and somehow still trace them back to the def they indirectly
+// came from.
+static Record *CurrentRecord = nullptr;
+static void assert_with_loc(bool Assertion, const std::string &Str) {
+  if (!Assertion) {
+    if (CurrentRecord)
+      PrintFatalError(CurrentRecord->getLoc(), Str);
+    else
+      PrintFatalError(Str);
+  }
+}
 
 enum ClassKind {
   ClassNone,
-  ClassI,           // generic integer instruction, e.g., "i8" suffix
-  ClassS,           // signed/unsigned/poly, e.g., "s8", "u8" or "p8" suffix
-  ClassW,           // width-specific instruction, e.g., "8" suffix
-  ClassB,           // bitcast arguments with enum argument to specify type
-  ClassL,           // Logical instructions which are op instructions
-                    // but we need to not emit any suffix for in our
-                    // tests.
-  ClassNoTest       // Instructions which we do not test since they are
-                    // not TRUE instructions.
+  ClassI,     // generic integer instruction, e.g., "i8" suffix
+  ClassS,     // signed/unsigned/poly, e.g., "s8", "u8" or "p8" suffix
+  ClassW,     // width-specific instruction, e.g., "8" suffix
+  ClassB,     // bitcast arguments with enum argument to specify type
+  ClassL,     // Logical instructions which are op instructions
+              // but we need to not emit any suffix for in our
+              // tests.
+  ClassNoTest // Instructions which we do not test since they are
+              // not TRUE instructions.
 };
 
 /// NeonTypeFlags - Flags to identify the types for overloaded Neon
 /// builtins.  These must be kept in sync with the flags in
 /// include/clang/Basic/TargetBuiltins.h.
-namespace {
-class NeonTypeFlags {
-  enum {
-    EltTypeMask = 0xf,
-    UnsignedFlag = 0x10,
-    QuadFlag = 0x20
-  };
-  uint32_t Flags;
+namespace NeonTypeFlags {
+enum { EltTypeMask = 0xf, UnsignedFlag = 0x10, QuadFlag = 0x20 };
+
+enum EltType {
+  Int8,
+  Int16,
+  Int32,
+  Int64,
+  Poly8,
+  Poly16,
+  Poly64,
+  Poly128,
+  Float16,
+  Float32,
+  Float64
+};
+}
+
+class Intrinsic;
+class NeonEmitter;
+class Type;
+class Variable;
+
+//===----------------------------------------------------------------------===//
+// TypeSpec
+//===----------------------------------------------------------------------===//
+
+/// A TypeSpec is just a simple wrapper around a string, but gets its own type
+/// for strong typing purposes.
+///
+/// A TypeSpec can be used to create a type.
+class TypeSpec : public std::string {
+public:
+  static std::vector<TypeSpec> fromTypeSpecs(StringRef Str) {
+    std::vector<TypeSpec> Ret;
+    TypeSpec Acc;
+    for (char I : Str.str()) {
+      if (islower(I)) {
+        Acc.push_back(I);
+        Ret.push_back(TypeSpec(Acc));
+        Acc.clear();
+      } else {
+        Acc.push_back(I);
+      }
+    }
+    return Ret;
+  }
+};
+
+//===----------------------------------------------------------------------===//
+// Type
+//===----------------------------------------------------------------------===//
+
+/// A Type. Not much more to say here.
+class Type {
+private:
+  TypeSpec TS;
+
+  bool Float, Signed, Void, Poly, Constant, Pointer;
+  // ScalarForMangling and NoManglingQ are really not suited to live here as
+  // they are not related to the type. But they live in the TypeSpec (not the
+  // prototype), so this is really the only place to store them.
+  bool ScalarForMangling, NoManglingQ;
+  unsigned Bitwidth, ElementBitwidth, NumVectors;
 
 public:
-  enum EltType {
-    Int8,
-    Int16,
-    Int32,
-    Int64,
-    Poly8,
-    Poly16,
-    Poly64,
-    Float16,
-    Float32,
-    Float64
-  };
+  Type()
+      : Float(false), Signed(false), Void(true), Poly(false), Constant(false),
+        Pointer(false), ScalarForMangling(false), NoManglingQ(false),
+        Bitwidth(0), ElementBitwidth(0), NumVectors(0) {}
 
-  NeonTypeFlags(unsigned F) : Flags(F) {}
-  NeonTypeFlags(EltType ET, bool IsUnsigned, bool IsQuad) : Flags(ET) {
-    if (IsUnsigned)
-      Flags |= UnsignedFlag;
-    if (IsQuad)
-      Flags |= QuadFlag;
+  Type(TypeSpec TS, char CharMod)
+      : TS(TS), Float(false), Signed(false), Void(false), Poly(false),
+        Constant(false), Pointer(false), ScalarForMangling(false),
+        NoManglingQ(false), Bitwidth(0), ElementBitwidth(0), NumVectors(0) {
+    applyModifier(CharMod);
   }
 
-  uint32_t getFlags() const { return Flags; }
-};
-} // end anonymous namespace
+  /// Returns a type representing "void".
+  static Type getVoid() { return Type(); }
 
-namespace {
-class NeonEmitter {
-  RecordKeeper &Records;
-  StringMap<OpKind> OpMap;
-  DenseMap<Record*, ClassKind> ClassMap;
+  bool operator==(const Type &Other) const { return str() == Other.str(); }
+  bool operator!=(const Type &Other) const { return !operator==(Other); }
+
+  //
+  // Query functions
+  //
+  bool isScalarForMangling() const { return ScalarForMangling; }
+  bool noManglingQ() const { return NoManglingQ; }
+
+  bool isPointer() const { return Pointer; }
+  bool isFloating() const { return Float; }
+  bool isInteger() const { return !Float && !Poly; }
+  bool isSigned() const { return Signed; }
+  bool isScalar() const { return NumVectors == 0; }
+  bool isVector() const { return NumVectors > 0; }
+  bool isFloat() const { return Float && ElementBitwidth == 32; }
+  bool isDouble() const { return Float && ElementBitwidth == 64; }
+  bool isHalf() const { return Float && ElementBitwidth == 16; }
+  bool isPoly() const { return Poly; }
+  bool isChar() const { return ElementBitwidth == 8; }
+  bool isShort() const { return !Float && ElementBitwidth == 16; }
+  bool isInt() const { return !Float && ElementBitwidth == 32; }
+  bool isLong() const { return !Float && ElementBitwidth == 64; }
+  bool isVoid() const { return Void; }
+  unsigned getNumElements() const { return Bitwidth / ElementBitwidth; }
+  unsigned getSizeInBits() const { return Bitwidth; }
+  unsigned getElementSizeInBits() const { return ElementBitwidth; }
+  unsigned getNumVectors() const { return NumVectors; }
+
+  //
+  // Mutator functions
+  //
+  void makeUnsigned() { Signed = false; }
+  void makeSigned() { Signed = true; }
+  void makeInteger(unsigned ElemWidth, bool Sign) {
+    Float = false;
+    Poly = false;
+    Signed = Sign;
+    ElementBitwidth = ElemWidth;
+  }
+  void makeScalar() {
+    Bitwidth = ElementBitwidth;
+    NumVectors = 0;
+  }
+  void makeOneVector() {
+    assert(isVector());
+    NumVectors = 1;
+  }
+  void doubleLanes() {
+    assert_with_loc(Bitwidth != 128, "Can't get bigger than 128!");
+    Bitwidth = 128;
+  }
+  void halveLanes() {
+    assert_with_loc(Bitwidth != 64, "Can't get smaller than 64!");
+    Bitwidth = 64;
+  }
+
+  /// Return the C string representation of a type, which is the typename
+  /// defined in stdint.h or arm_neon.h.
+  std::string str() const;
+
+  /// Return the string representation of a type, which is an encoded
+  /// string for passing to the BUILTIN() macro in Builtins.def.
+  std::string builtin_str() const;
+
+  /// Return the value in NeonTypeFlags for this type.
+  unsigned getNeonEnum() const;
+
+  /// Parse a type from a stdint.h or arm_neon.h typedef name,
+  /// for example uint32x2_t or int64_t.
+  static Type fromTypedefName(StringRef Name);
+
+private:
+  /// Creates the type based on the typespec string in TS.
+  /// Sets "Quad" to true if the "Q" or "H" modifiers were
+  /// seen. This is needed by applyModifier as some modifiers
+  /// only take effect if the type size was changed by "Q" or "H".
+  void applyTypespec(bool &Quad);
+  /// Applies a prototype modifier to the type.
+  void applyModifier(char Mod);
+};
+
+//===----------------------------------------------------------------------===//
+// Variable
+//===----------------------------------------------------------------------===//
+
+/// A variable is a simple class that just has a type and a name.
+class Variable {
+  Type T;
+  std::string N;
 
 public:
-  NeonEmitter(RecordKeeper &R) : Records(R) {
-    OpMap["OP_NONE"]  = OpNone;
-    OpMap["OP_UNAVAILABLE"] = OpUnavailable;
-    OpMap["OP_ADD"]   = OpAdd;
-    OpMap["OP_ADDL"]  = OpAddl;
-    OpMap["OP_ADDLHi"] = OpAddlHi;
-    OpMap["OP_ADDW"]  = OpAddw;
-    OpMap["OP_ADDWHi"] = OpAddwHi;
-    OpMap["OP_SUB"]   = OpSub;
-    OpMap["OP_SUBL"]  = OpSubl;
-    OpMap["OP_SUBLHi"] = OpSublHi;
-    OpMap["OP_SUBW"]  = OpSubw;
-    OpMap["OP_SUBWHi"] = OpSubwHi;
-    OpMap["OP_MUL"]   = OpMul;
-    OpMap["OP_MLA"]   = OpMla;
-    OpMap["OP_MLAL"]  = OpMlal;
-    OpMap["OP_MULLHi"]  = OpMullHi;
-    OpMap["OP_MLALHi"]  = OpMlalHi;
-    OpMap["OP_MLS"]   = OpMls;
-    OpMap["OP_MLSL"]  = OpMlsl;
-    OpMap["OP_MLSLHi"] = OpMlslHi;
-    OpMap["OP_MUL_N"] = OpMulN;
-    OpMap["OP_MLA_N"] = OpMlaN;
-    OpMap["OP_MLS_N"] = OpMlsN;
-    OpMap["OP_MLAL_N"] = OpMlalN;
-    OpMap["OP_MLSL_N"] = OpMlslN;
-    OpMap["OP_MUL_LN"]= OpMulLane;
-    OpMap["OP_MULX_LN"]= OpMulXLane;
-    OpMap["OP_MULL_LN"] = OpMullLane;
-    OpMap["OP_MULLHi_LN"] = OpMullHiLane;
-    OpMap["OP_MLA_LN"]= OpMlaLane;
-    OpMap["OP_MLS_LN"]= OpMlsLane;
-    OpMap["OP_MLAL_LN"] = OpMlalLane;
-    OpMap["OP_MLALHi_LN"] = OpMlalHiLane;
-    OpMap["OP_MLSL_LN"] = OpMlslLane;
-    OpMap["OP_MLSLHi_LN"] = OpMlslHiLane;
-    OpMap["OP_QDMULL_LN"] = OpQDMullLane;
-    OpMap["OP_QDMULLHi_LN"] = OpQDMullHiLane;
-    OpMap["OP_QDMLAL_LN"] = OpQDMlalLane;
-    OpMap["OP_QDMLALHi_LN"] = OpQDMlalHiLane;
-    OpMap["OP_QDMLSL_LN"] = OpQDMlslLane;
-    OpMap["OP_QDMLSLHi_LN"] = OpQDMlslHiLane;
-    OpMap["OP_QDMULH_LN"] = OpQDMulhLane;
-    OpMap["OP_QRDMULH_LN"] = OpQRDMulhLane;
-    OpMap["OP_FMS_LN"] = OpFMSLane;
-    OpMap["OP_FMS_LNQ"] = OpFMSLaneQ;
-    OpMap["OP_TRN1"]  = OpTrn1;
-    OpMap["OP_ZIP1"]  = OpZip1;
-    OpMap["OP_UZP1"]  = OpUzp1;
-    OpMap["OP_TRN2"]  = OpTrn2;
-    OpMap["OP_ZIP2"]  = OpZip2;
-    OpMap["OP_UZP2"]  = OpUzp2;
-    OpMap["OP_EQ"]    = OpEq;
-    OpMap["OP_GE"]    = OpGe;
-    OpMap["OP_LE"]    = OpLe;
-    OpMap["OP_GT"]    = OpGt;
-    OpMap["OP_LT"]    = OpLt;
-    OpMap["OP_NEG"]   = OpNeg;
-    OpMap["OP_NOT"]   = OpNot;
-    OpMap["OP_AND"]   = OpAnd;
-    OpMap["OP_OR"]    = OpOr;
-    OpMap["OP_XOR"]   = OpXor;
-    OpMap["OP_ANDN"]  = OpAndNot;
-    OpMap["OP_ORN"]   = OpOrNot;
-    OpMap["OP_CAST"]  = OpCast;
-    OpMap["OP_CONC"]  = OpConcat;
-    OpMap["OP_HI"]    = OpHi;
-    OpMap["OP_LO"]    = OpLo;
-    OpMap["OP_DUP"]   = OpDup;
-    OpMap["OP_DUP_LN"] = OpDupLane;
-    OpMap["OP_SEL"]   = OpSelect;
-    OpMap["OP_REV16"] = OpRev16;
-    OpMap["OP_REV32"] = OpRev32;
-    OpMap["OP_REV64"] = OpRev64;
-    OpMap["OP_XTN"] = OpXtnHi;
-    OpMap["OP_SQXTUN"] = OpSqxtunHi;
-    OpMap["OP_QXTN"] = OpQxtnHi;
-    OpMap["OP_VCVT_NA_HI"] = OpFcvtnHi;
-    OpMap["OP_VCVT_EX_HI"] = OpFcvtlHi;
-    OpMap["OP_VCVTX_HI"] = OpFcvtxnHi;
-    OpMap["OP_REINT"] = OpReinterpret;
-    OpMap["OP_ADDHNHi"] = OpAddhnHi;
-    OpMap["OP_RADDHNHi"] = OpRAddhnHi;
-    OpMap["OP_SUBHNHi"] = OpSubhnHi;
-    OpMap["OP_RSUBHNHi"] = OpRSubhnHi;
-    OpMap["OP_ABDL"]  = OpAbdl;
-    OpMap["OP_ABDLHi"] = OpAbdlHi;
-    OpMap["OP_ABA"]   = OpAba;
-    OpMap["OP_ABAL"]  = OpAbal;
-    OpMap["OP_ABALHi"] = OpAbalHi;
-    OpMap["OP_QDMULLHi"] = OpQDMullHi;
-    OpMap["OP_QDMLALHi"] = OpQDMlalHi;
-    OpMap["OP_QDMLSLHi"] = OpQDMlslHi;
-    OpMap["OP_DIV"] = OpDiv;
-    OpMap["OP_LONG_HI"] = OpLongHi;
-    OpMap["OP_NARROW_HI"] = OpNarrowHi;
-    OpMap["OP_MOVL_HI"] = OpMovlHi;
-    OpMap["OP_COPY_LN"] = OpCopyLane;
-    OpMap["OP_COPYQ_LN"] = OpCopyQLane;
-    OpMap["OP_COPY_LNQ"] = OpCopyLaneQ;
-    OpMap["OP_SCALAR_MUL_LN"]= OpScalarMulLane;
-    OpMap["OP_SCALAR_MUL_LNQ"]= OpScalarMulLaneQ;
-    OpMap["OP_SCALAR_MULX_LN"]= OpScalarMulXLane;
-    OpMap["OP_SCALAR_MULX_LNQ"]= OpScalarMulXLaneQ;
-    OpMap["OP_SCALAR_VMULX_LN"]= OpScalarVMulXLane;
-    OpMap["OP_SCALAR_VMULX_LNQ"]= OpScalarVMulXLaneQ;
+  Variable() : T(Type::getVoid()), N("") {}
+  Variable(Type T, std::string N) : T(T), N(N) {}
 
+  Type getType() const { return T; }
+  std::string getName() const { return "__" + N; }
+};
+
+//===----------------------------------------------------------------------===//
+// Intrinsic
+//===----------------------------------------------------------------------===//
+
+/// The main grunt class. This represents an instantiation of an intrinsic with
+/// a particular typespec and prototype.
+class Intrinsic {
+  friend class DagEmitter;
+
+  /// The Record this intrinsic was created from.
+  Record *R;
+  /// The unmangled name and prototype.
+  std::string Name, Proto;
+  /// The input and output typespecs. InTS == OutTS except when
+  /// CartesianProductOfTypes is 1 - this is the case for vreinterpret.
+  TypeSpec OutTS, InTS;
+  /// The base class kind. Most intrinsics use ClassS, which has full type
+  /// info for integers (s32/u32). Some use ClassI, which doesn't care about
+  /// signedness (i32), while some (ClassB) have no type at all, only a width
+  /// (32).
+  ClassKind CK;
+  /// The list of DAGs for the body. May be empty, in which case we should
+  /// emit a builtin call.
+  ListInit *Body;
+  /// The architectural #ifdef guard.
+  std::string Guard;
+  /// Set if the Unvailable bit is 1. This means we don't generate a body,
+  /// just an "unavailable" attribute on a declaration.
+  bool IsUnavailable;
+  /// Is this intrinsic safe for big-endian? or does it need its arguments
+  /// reversing?
+  bool BigEndianSafe;
+
+  /// The types of return value [0] and parameters [1..].
+  std::vector<Type> Types;
+  /// The local variables defined.
+  std::map<std::string, Variable> Variables;
+  /// NeededEarly - set if any other intrinsic depends on this intrinsic.
+  bool NeededEarly;
+  /// UseMacro - set if we should implement using a macro or unset for a
+  ///            function.
+  bool UseMacro;
+  /// The set of intrinsics that this intrinsic uses/requires.
+  std::set<Intrinsic *> Dependencies;
+  /// The "base type", which is Type('d', OutTS). InBaseType is only
+  /// different if CartesianProductOfTypes = 1 (for vreinterpret).
+  Type BaseType, InBaseType;
+  /// The return variable.
+  Variable RetVar;
+  /// A postfix to apply to every variable. Defaults to "".
+  std::string VariablePostfix;
+
+  NeonEmitter &Emitter;
+  std::stringstream OS;
+
+public:
+  Intrinsic(Record *R, StringRef Name, StringRef Proto, TypeSpec OutTS,
+            TypeSpec InTS, ClassKind CK, ListInit *Body, NeonEmitter &Emitter,
+            StringRef Guard, bool IsUnavailable, bool BigEndianSafe)
+      : R(R), Name(Name.str()), Proto(Proto.str()), OutTS(OutTS), InTS(InTS),
+        CK(CK), Body(Body), Guard(Guard.str()), IsUnavailable(IsUnavailable),
+        BigEndianSafe(BigEndianSafe), NeededEarly(false), UseMacro(false),
+        BaseType(OutTS, 'd'), InBaseType(InTS, 'd'), Emitter(Emitter) {
+    // If this builtin takes an immediate argument, we need to #define it rather
+    // than use a standard declaration, so that SemaChecking can range check
+    // the immediate passed by the user.
+    if (Proto.find('i') != std::string::npos)
+      UseMacro = true;
+
+    // Pointer arguments need to use macros to avoid hiding aligned attributes
+    // from the pointer type.
+    if (Proto.find('p') != std::string::npos ||
+        Proto.find('c') != std::string::npos)
+      UseMacro = true;
+
+    // It is not permitted to pass or return an __fp16 by value, so intrinsics
+    // taking a scalar float16_t must be implemented as macros.
+    if (OutTS.find('h') != std::string::npos &&
+        Proto.find('s') != std::string::npos)
+      UseMacro = true;
+
+    // Modify the TypeSpec per-argument to get a concrete Type, and create
+    // known variables for each.
+    // Types[0] is the return value.
+    Types.push_back(Type(OutTS, Proto[0]));
+    for (unsigned I = 1; I < Proto.size(); ++I)
+      Types.push_back(Type(InTS, Proto[I]));
+  }
+
+  /// Get the Record that this intrinsic is based off.
+  Record *getRecord() const { return R; }
+  /// Get the set of Intrinsics that this intrinsic calls.
+  /// this is the set of immediate dependencies, NOT the
+  /// transitive closure.
+  const std::set<Intrinsic *> &getDependencies() const { return Dependencies; }
+  /// Get the architectural guard string (#ifdef).
+  std::string getGuard() const { return Guard; }
+  /// Get the non-mangled name.
+  std::string getName() const { return Name; }
+
+  /// Return true if the intrinsic takes an immediate operand.
+  bool hasImmediate() const {
+    return Proto.find('i') != std::string::npos;
+  }
+  /// Return the parameter index of the immediate operand.
+  unsigned getImmediateIdx() const {
+    assert(hasImmediate());
+    unsigned Idx = Proto.find('i');
+    assert(Idx > 0 && "Can't return an immediate!");
+    return Idx - 1;
+  }
+
+  /// Return true if the intrinsic takes an splat operand.
+  bool hasSplat() const { return Proto.find('a') != std::string::npos; }
+  /// Return the parameter index of the splat operand.
+  unsigned getSplatIdx() const {
+    assert(hasSplat());
+    unsigned Idx = Proto.find('a');
+    assert(Idx > 0 && "Can't return a splat!");
+    return Idx - 1;
+  }
+
+  unsigned getNumParams() const { return Proto.size() - 1; }
+  Type getReturnType() const { return Types[0]; }
+  Type getParamType(unsigned I) const { return Types[I + 1]; }
+  Type getBaseType() const { return BaseType; }
+  /// Return the raw prototype string.
+  std::string getProto() const { return Proto; }
+
+  /// Return true if the prototype has a scalar argument.
+  /// This does not return true for the "splat" code ('a').
+  bool protoHasScalar();
+
+  /// Return the index that parameter PIndex will sit at
+  /// in a generated function call. This is often just PIndex,
+  /// but may not be as things such as multiple-vector operands
+  /// and sret parameters need to be taken into accont.
+  unsigned getGeneratedParamIdx(unsigned PIndex) {
+    unsigned Idx = 0;
+    if (getReturnType().getNumVectors() > 1)
+      // Multiple vectors are passed as sret.
+      ++Idx;
+
+    for (unsigned I = 0; I < PIndex; ++I)
+      Idx += std::max(1U, getParamType(I).getNumVectors());
+
+    return Idx;
+  }
+
+  bool hasBody() const { return Body && Body->getValues().size() > 0; }
+
+  void setNeededEarly() { NeededEarly = true; }
+
+  bool operator<(const Intrinsic &Other) const {
+    // Sort lexicographically on a two-tuple (Guard, Name)
+    if (Guard != Other.Guard)
+      return Guard < Other.Guard;
+    return Name < Other.Name;
+  }
+
+  ClassKind getClassKind(bool UseClassBIfScalar = false) {
+    if (UseClassBIfScalar && !protoHasScalar())
+      return ClassB;
+    return CK;
+  }
+
+  /// Return the name, mangled with type information.
+  /// If ForceClassS is true, use ClassS (u32/s32) instead
+  /// of the intrinsic's own type class.
+  std::string getMangledName(bool ForceClassS = false);
+  /// Return the type code for a builtin function call.
+  std::string getInstTypeCode(Type T, ClassKind CK);
+  /// Return the type string for a BUILTIN() macro in Builtins.def.
+  std::string getBuiltinTypeStr();
+
+  /// Generate the intrinsic, returning code.
+  std::string generate();
+  /// Perform type checking and populate the dependency graph, but
+  /// don't generate code yet.
+  void indexBody();
+
+private:
+  std::string mangleName(std::string Name, ClassKind CK);
+
+  void initVariables();
+  std::string replaceParamsIn(std::string S);
+
+  void emitBodyAsBuiltinCall();
+
+  void generateImpl(bool ReverseArguments,
+                    StringRef NamePrefix, StringRef CallPrefix);
+  void emitReturn();
+  void emitBody(StringRef CallPrefix);
+  void emitShadowedArgs();
+  void emitArgumentReversal();
+  void emitReturnReversal();
+  void emitReverseVariable(Variable &Dest, Variable &Src);
+  void emitNewLine();
+  void emitClosingBrace();
+  void emitOpeningBrace();
+  void emitPrototype(StringRef NamePrefix);
+
+  class DagEmitter {
+    Intrinsic &Intr;
+    StringRef CallPrefix;
+
+  public:
+    DagEmitter(Intrinsic &Intr, StringRef CallPrefix) :
+      Intr(Intr), CallPrefix(CallPrefix) {
+    }
+    std::pair<Type, std::string> emitDagArg(Init *Arg, std::string ArgName);
+    std::pair<Type, std::string> emitDagSaveTemp(DagInit *DI);
+    std::pair<Type, std::string> emitDagSplat(DagInit *DI);
+    std::pair<Type, std::string> emitDagDup(DagInit *DI);
+    std::pair<Type, std::string> emitDagShuffle(DagInit *DI);
+    std::pair<Type, std::string> emitDagCast(DagInit *DI, bool IsBitCast);
+    std::pair<Type, std::string> emitDagCall(DagInit *DI);
+    std::pair<Type, std::string> emitDagNameReplace(DagInit *DI);
+    std::pair<Type, std::string> emitDagLiteral(DagInit *DI);
+    std::pair<Type, std::string> emitDagOp(DagInit *DI);
+    std::pair<Type, std::string> emitDag(DagInit *DI);
+  };
+
+};
+
+//===----------------------------------------------------------------------===//
+// NeonEmitter
+//===----------------------------------------------------------------------===//
+
+class NeonEmitter {
+  RecordKeeper &Records;
+  DenseMap<Record *, ClassKind> ClassMap;
+  std::map<std::string, std::vector<Intrinsic *>> IntrinsicMap;
+  unsigned UniqueNumber;
+
+  void createIntrinsic(Record *R, SmallVectorImpl<Intrinsic *> &Out);
+  void genBuiltinsDef(raw_ostream &OS, SmallVectorImpl<Intrinsic *> &Defs);
+  void genOverloadTypeCheckCode(raw_ostream &OS,
+                                SmallVectorImpl<Intrinsic *> &Defs);
+  void genIntrinsicRangeCheckCode(raw_ostream &OS,
+                                  SmallVectorImpl<Intrinsic *> &Defs);
+
+public:
+  /// Called by Intrinsic - this attempts to get an intrinsic that takes
+  /// the given types as arguments.
+  Intrinsic *getIntrinsic(StringRef Name, ArrayRef<Type> Types);
+
+  /// Called by Intrinsic - returns a globally-unique number.
+  unsigned getUniqueNumber() { return UniqueNumber++; }
+
+  NeonEmitter(RecordKeeper &R) : Records(R), UniqueNumber(0) {
     Record *SI = R.getClass("SInst");
     Record *II = R.getClass("IInst");
     Record *WI = R.getClass("WInst");
@@ -335,2077 +530,1706 @@
 
   // runTests - Emit tests for all the Neon intrinsics.
   void runTests(raw_ostream &o);
-
-private:
-  void emitIntrinsic(raw_ostream &OS, Record *R,
-                     StringMap<ClassKind> &EmittedMap);
-  void genBuiltinsDef(raw_ostream &OS, StringMap<ClassKind> &A64IntrinsicMap,
-                      bool isA64GenBuiltinDef);
-  void genOverloadTypeCheckCode(raw_ostream &OS,
-                                StringMap<ClassKind> &A64IntrinsicMap,
-                                bool isA64TypeCheck);
-  void genIntrinsicRangeCheckCode(raw_ostream &OS,
-                                  StringMap<ClassKind> &A64IntrinsicMap,
-                                  bool isA64RangeCheck);
-  void genTargetTest(raw_ostream &OS, StringMap<OpKind> &EmittedMap,
-                     bool isA64TestGen);
 };
+
 } // end anonymous namespace
 
-/// ParseTypes - break down a string such as "fQf" into a vector of StringRefs,
-/// which each StringRef representing a single type declared in the string.
-/// for "fQf" we would end up with 2 StringRefs, "f", and "Qf", representing
-/// 2xfloat and 4xfloat respectively.
-static void ParseTypes(Record *r, std::string &s,
-                       SmallVectorImpl<StringRef> &TV) {
-  const char *data = s.data();
-  int len = 0;
+//===----------------------------------------------------------------------===//
+// Type implementation
+//===----------------------------------------------------------------------===//
 
-  for (unsigned i = 0, e = s.size(); i != e; ++i, ++len) {
-    if (data[len] == 'P' || data[len] == 'Q' || data[len] == 'U'
-                         || data[len] == 'H' || data[len] == 'S')
-      continue;
+std::string Type::str() const {
+  if (Void)
+    return "void";
+  std::string S;
 
-    switch (data[len]) {
-      case 'c':
-      case 's':
-      case 'i':
-      case 'l':
-      case 'h':
-      case 'f':
-      case 'd':
-        break;
-      default:
-        PrintFatalError(r->getLoc(),
-                      "Unexpected letter: " + std::string(data + len, 1));
-    }
-    TV.push_back(StringRef(data, len + 1));
-    data += len + 1;
-    len = -1;
-  }
+  if (!Signed && isInteger())
+    S += "u";
+
+  if (Poly)
+    S += "poly";
+  else if (Float)
+    S += "float";
+  else
+    S += "int";
+
+  S += utostr(ElementBitwidth);
+  if (isVector())
+    S += "x" + utostr(getNumElements());
+  if (NumVectors > 1)
+    S += "x" + utostr(NumVectors);
+  S += "_t";
+
+  if (Constant)
+    S += " const";
+  if (Pointer)
+    S += " *";
+
+  return S;
 }
 
-/// Widen - Convert a type code into the next wider type.  char -> short,
-/// short -> int, etc.
-static char Widen(const char t) {
-  switch (t) {
+std::string Type::builtin_str() const {
+  std::string S;
+  if (isVoid())
+    return "v";
+
+  if (Pointer)
+    // All pointers are void pointers.
+    S += "v";
+  else if (isInteger())
+    switch (ElementBitwidth) {
+    case 8: S += "c"; break;
+    case 16: S += "s"; break;
+    case 32: S += "i"; break;
+    case 64: S += "Wi"; break;
+    case 128: S += "LLLi"; break;
+    default: llvm_unreachable("Unhandled case!");
+    }
+  else
+    switch (ElementBitwidth) {
+    case 16: S += "h"; break;
+    case 32: S += "f"; break;
+    case 64: S += "d"; break;
+    default: llvm_unreachable("Unhandled case!");
+    }
+
+  if (isChar() && !Pointer)
+    // Make chars explicitly signed.
+    S = "S" + S;
+  else if (isInteger() && !Pointer && !Signed)
+    S = "U" + S;
+
+  if (isScalar()) {
+    if (Constant) S += "C";
+    if (Pointer) S += "*";
+    return S;
+  }
+
+  std::string Ret;
+  for (unsigned I = 0; I < NumVectors; ++I)
+    Ret += "V" + utostr(getNumElements()) + S;
+
+  return Ret;
+}
+
+unsigned Type::getNeonEnum() const {
+  unsigned Addend;
+  switch (ElementBitwidth) {
+  case 8: Addend = 0; break;
+  case 16: Addend = 1; break;
+  case 32: Addend = 2; break;
+  case 64: Addend = 3; break;
+  case 128: Addend = 4; break;
+  default: llvm_unreachable("Unhandled element bitwidth!");
+  }
+
+  unsigned Base = (unsigned)NeonTypeFlags::Int8 + Addend;
+  if (Poly) {
+    // Adjustment needed because Poly32 doesn't exist.
+    if (Addend >= 2)
+      --Addend;
+    Base = (unsigned)NeonTypeFlags::Poly8 + Addend;
+  }
+  if (Float) {
+    assert(Addend != 0 && "Float8 doesn't exist!");
+    Base = (unsigned)NeonTypeFlags::Float16 + (Addend - 1);
+  }
+
+  if (Bitwidth == 128)
+    Base |= (unsigned)NeonTypeFlags::QuadFlag;
+  if (isInteger() && !Signed)
+    Base |= (unsigned)NeonTypeFlags::UnsignedFlag;
+
+  return Base;
+}
+
+Type Type::fromTypedefName(StringRef Name) {
+  Type T;
+  T.Void = false;
+  T.Float = false;
+  T.Poly = false;
+
+  if (Name.front() == 'u') {
+    T.Signed = false;
+    Name = Name.drop_front();
+  } else {
+    T.Signed = true;
+  }
+
+  if (Name.startswith("float")) {
+    T.Float = true;
+    Name = Name.drop_front(5);
+  } else if (Name.startswith("poly")) {
+    T.Poly = true;
+    Name = Name.drop_front(4);
+  } else {
+    assert(Name.startswith("int"));
+    Name = Name.drop_front(3);
+  }
+
+  unsigned I = 0;
+  for (I = 0; I < Name.size(); ++I) {
+    if (!isdigit(Name[I]))
+      break;
+  }
+  Name.substr(0, I).getAsInteger(10, T.ElementBitwidth);
+  Name = Name.drop_front(I);
+
+  T.Bitwidth = T.ElementBitwidth;
+  T.NumVectors = 1;
+
+  if (Name.front() == 'x') {
+    Name = Name.drop_front();
+    unsigned I = 0;
+    for (I = 0; I < Name.size(); ++I) {
+      if (!isdigit(Name[I]))
+        break;
+    }
+    unsigned NumLanes;
+    Name.substr(0, I).getAsInteger(10, NumLanes);
+    Name = Name.drop_front(I);
+    T.Bitwidth = T.ElementBitwidth * NumLanes;
+  } else {
+    // Was scalar.
+    T.NumVectors = 0;
+  }
+  if (Name.front() == 'x') {
+    Name = Name.drop_front();
+    unsigned I = 0;
+    for (I = 0; I < Name.size(); ++I) {
+      if (!isdigit(Name[I]))
+        break;
+    }
+    Name.substr(0, I).getAsInteger(10, T.NumVectors);
+    Name = Name.drop_front(I);
+  }
+
+  assert(Name.startswith("_t") && "Malformed typedef!");
+  return T;
+}
+
+void Type::applyTypespec(bool &Quad) {
+  std::string S = TS;
+  ScalarForMangling = false;
+  Void = false;
+  Poly = Float = false;
+  ElementBitwidth = ~0U;
+  Signed = true;
+  NumVectors = 1;
+
+  for (char I : S) {
+    switch (I) {
+    case 'S':
+      ScalarForMangling = true;
+      break;
+    case 'H':
+      NoManglingQ = true;
+      Quad = true;
+      break;
+    case 'Q':
+      Quad = true;
+      break;
+    case 'P':
+      Poly = true;
+      break;
+    case 'U':
+      Signed = false;
+      break;
     case 'c':
-      return 's';
-    case 's':
-      return 'i';
-    case 'i':
-      return 'l';
+      ElementBitwidth = 8;
+      break;
     case 'h':
-      return 'f';
-    case 'f':
-      return 'd';
-    default:
-      PrintFatalError("unhandled type in widen!");
-  }
-}
-
-/// Narrow - Convert a type code into the next smaller type.  short -> char,
-/// float -> half float, etc.
-static char Narrow(const char t) {
-  switch (t) {
+      Float = true;
+    // Fall through
     case 's':
-      return 'c';
-    case 'i':
-      return 's';
-    case 'l':
-      return 'i';
+      ElementBitwidth = 16;
+      break;
     case 'f':
-      return 'h';
+      Float = true;
+    // Fall through
+    case 'i':
+      ElementBitwidth = 32;
+      break;
     case 'd':
-      return 'f';
-    default:
-      PrintFatalError("unhandled type in narrow!");
-  }
-}
-
-static std::string GetNarrowTypestr(StringRef ty)
-{
-  std::string s;
-  for (size_t i = 0, end = ty.size(); i < end; i++) {
-    switch (ty[i]) {
-      case 's':
-        s += 'c';
-        break;
-      case 'i':
-        s += 's';
-        break;
-      case 'l':
-        s += 'i';
-        break;
-      default:
-        s += ty[i];
-        break;
-    }
-  }
-
-  return s;
-}
-
-/// For a particular StringRef, return the base type code, and whether it has
-/// the quad-vector, polynomial, or unsigned modifiers set.
-static char ClassifyType(StringRef ty, bool &quad, bool &poly, bool &usgn) {
-  unsigned off = 0;
-  // ignore scalar.
-  if (ty[off] == 'S') {
-    ++off;
-  }
-  // remember quad.
-  if (ty[off] == 'Q' || ty[off] == 'H') {
-    quad = true;
-    ++off;
-  }
-
-  // remember poly.
-  if (ty[off] == 'P') {
-    poly = true;
-    ++off;
-  }
-
-  // remember unsigned.
-  if (ty[off] == 'U') {
-    usgn = true;
-    ++off;
-  }
-
-  // base type to get the type string for.
-  return ty[off];
-}
-
-/// ModType - Transform a type code and its modifiers based on a mod code. The
-/// mod code definitions may be found at the top of arm_neon.td.
-static char ModType(const char mod, char type, bool &quad, bool &poly,
-                    bool &usgn, bool &scal, bool &cnst, bool &pntr) {
-  switch (mod) {
-    case 't':
-      if (poly) {
-        poly = false;
-        usgn = true;
-      }
-      break;
-    case 'b':
-      scal = true;
-    case 'u':
-      usgn = true;
-      poly = false;
-      if (type == 'f')
-        type = 'i';
-      if (type == 'd')
-        type = 'l';
-      break;
-    case '$':
-      scal = true;
-    case 'x':
-      usgn = false;
-      poly = false;
-      if (type == 'f')
-        type = 'i';
-      if (type == 'd')
-        type = 'l';
-      break;
-    case 'o':
-      scal = true;
-      type = 'd';
-      usgn = false;
-      break;
-    case 'y':
-      scal = true;
-    case 'f':
-      if (type == 'h')
-        quad = true;
-      type = 'f';
-      usgn = false;
-      break;
-    case 'g':
-      quad = false;
-      break;
-    case 'B':
-    case 'C':
-    case 'D':
-    case 'j':
-      quad = true;
-      break;
-    case 'w':
-      type = Widen(type);
-      quad = true;
-      break;
-    case 'n':
-      type = Widen(type);
-      break;
-    case 'i':
-      type = 'i';
-      scal = true;
-      break;
+      Float = true;
+    // Fall through
     case 'l':
-      type = 'l';
-      scal = true;
-      usgn = true;
-      break;
-    case 'z':
-      type = Narrow(type);
-      scal = true;
-      break;
-    case 'r':
-      type = Widen(type);
-      scal = true;
-      break;
-    case 's':
-    case 'a':
-      scal = true;
+      ElementBitwidth = 64;
       break;
     case 'k':
-      quad = true;
-      break;
-    case 'c':
-      cnst = true;
-    case 'p':
-      pntr = true;
-      scal = true;
-      break;
-    case 'h':
-      type = Narrow(type);
-      if (type == 'h')
-        quad = false;
-      break;
-    case 'q':
-      type = Narrow(type);
-      quad = true;
-      break;
-    case 'e':
-      type = Narrow(type);
-      usgn = true;
-      break;
-    case 'm':
-      type = Narrow(type);
-      quad = false;
+      ElementBitwidth = 128;
+      // Poly doesn't have a 128x1 type.
+      if (Poly)
+        NumVectors = 0;
       break;
     default:
-      break;
+      llvm_unreachable("Unhandled type code!");
+    }
   }
-  return type;
+  assert(ElementBitwidth != ~0U && "Bad element bitwidth!");
+
+  Bitwidth = Quad ? 128 : 64;
 }
 
-static bool IsMultiVecProto(const char p) {
-  return ((p >= '2' && p <= '4') || (p >= 'B' && p <= 'D'));
+void Type::applyModifier(char Mod) {
+  bool AppliedQuad = false;
+  applyTypespec(AppliedQuad);
+
+  switch (Mod) {
+  case 'v':
+    Void = true;
+    break;
+  case 't':
+    if (Poly) {
+      Poly = false;
+      Signed = false;
+    }
+    break;
+  case 'b':
+    Signed = false;
+    Float = false;
+    Poly = false;
+    NumVectors = 0;
+    Bitwidth = ElementBitwidth;
+    break;
+  case '$':
+    Signed = true;
+    Float = false;
+    Poly = false;
+    NumVectors = 0;
+    Bitwidth = ElementBitwidth;
+    break;
+  case 'u':
+    Signed = false;
+    Poly = false;
+    Float = false;
+    break;
+  case 'x':
+    Signed = true;
+    assert(!Poly && "'u' can't be used with poly types!");
+    Float = false;
+    break;
+  case 'o':
+    Bitwidth = ElementBitwidth = 64;
+    NumVectors = 0;
+    Float = true;
+    break;
+  case 'y':
+    Bitwidth = ElementBitwidth = 32;
+    NumVectors = 0;
+    Float = true;
+    break;
+  case 'f':
+    // Special case - if we're half-precision, a floating
+    // point argument needs to be 128-bits (double size).
+    if (isHalf())
+      Bitwidth = 128;
+    Float = true;
+    ElementBitwidth = 32;
+    break;
+  case 'F':
+    Float = true;
+    ElementBitwidth = 64;
+    break;
+  case 'g':
+    if (AppliedQuad)
+      Bitwidth /= 2;
+    break;
+  case 'j':
+    if (!AppliedQuad)
+      Bitwidth *= 2;
+    break;
+  case 'w':
+    ElementBitwidth *= 2;
+    Bitwidth *= 2;
+    break;
+  case 'n':
+    ElementBitwidth *= 2;
+    break;
+  case 'i':
+    Float = false;
+    Poly = false;
+    ElementBitwidth = Bitwidth = 32;
+    NumVectors = 0;
+    Signed = true;
+    break;
+  case 'l':
+    Float = false;
+    Poly = false;
+    ElementBitwidth = Bitwidth = 64;
+    NumVectors = 0;
+    Signed = false;
+    break;
+  case 'z':
+    ElementBitwidth /= 2;
+    Bitwidth = ElementBitwidth;
+    NumVectors = 0;
+    break;
+  case 'r':
+    ElementBitwidth *= 2;
+    Bitwidth = ElementBitwidth;
+    NumVectors = 0;
+    break;
+  case 's':
+  case 'a':
+    Bitwidth = ElementBitwidth;
+    NumVectors = 0;
+    break;
+  case 'k':
+    Bitwidth *= 2;
+    break;
+  case 'c':
+    Constant = true;
+  // Fall through
+  case 'p':
+    Pointer = true;
+    Bitwidth = ElementBitwidth;
+    NumVectors = 0;
+    break;
+  case 'h':
+    ElementBitwidth /= 2;
+    break;
+  case 'q':
+    ElementBitwidth /= 2;
+    Bitwidth *= 2;
+    break;
+  case 'e':
+    ElementBitwidth /= 2;
+    Signed = false;
+    break;
+  case 'm':
+    ElementBitwidth /= 2;
+    Bitwidth /= 2;
+    break;
+  case 'd':
+    break;
+  case '2':
+    NumVectors = 2;
+    break;
+  case '3':
+    NumVectors = 3;
+    break;
+  case '4':
+    NumVectors = 4;
+    break;
+  case 'B':
+    NumVectors = 2;
+    if (!AppliedQuad)
+      Bitwidth *= 2;
+    break;
+  case 'C':
+    NumVectors = 3;
+    if (!AppliedQuad)
+      Bitwidth *= 2;
+    break;
+  case 'D':
+    NumVectors = 4;
+    if (!AppliedQuad)
+      Bitwidth *= 2;
+    break;
+  default:
+    llvm_unreachable("Unhandled character!");
+  }
 }
 
-/// TypeString - for a modifier and type, generate the name of the typedef for
-/// that type.  QUc -> uint8x8_t.
-static std::string TypeString(const char mod, StringRef typestr) {
-  bool quad = false;
-  bool poly = false;
-  bool usgn = false;
-  bool scal = false;
-  bool cnst = false;
-  bool pntr = false;
+//===----------------------------------------------------------------------===//
+// Intrinsic implementation
+//===----------------------------------------------------------------------===//
 
-  if (mod == 'v')
-    return "void";
-  if (mod == 'i')
-    return "int";
+std::string Intrinsic::getInstTypeCode(Type T, ClassKind CK) {
+  char typeCode = '\0';
+  bool printNumber = true;
 
-  // base type to get the type string for.
-  char type = ClassifyType(typestr, quad, poly, usgn);
+  if (CK == ClassB)
+    return "";
 
-  // Based on the modifying character, change the type and width if necessary.
-  type = ModType(mod, type, quad, poly, usgn, scal, cnst, pntr);
+  if (T.isPoly())
+    typeCode = 'p';
+  else if (T.isInteger())
+    typeCode = T.isSigned() ? 's' : 'u';
+  else
+    typeCode = 'f';
 
-  SmallString<128> s;
-
-  if (usgn)
-    s.push_back('u');
-
-  switch (type) {
-    case 'c':
-      s += poly ? "poly8" : "int8";
-      if (scal)
-        break;
-      s += quad ? "x16" : "x8";
+  if (CK == ClassI) {
+    switch (typeCode) {
+    default:
       break;
     case 's':
-      s += poly ? "poly16" : "int16";
-      if (scal)
-        break;
-      s += quad ? "x8" : "x4";
+    case 'u':
+    case 'p':
+      typeCode = 'i';
       break;
-    case 'i':
-      s += "int32";
-      if (scal)
-        break;
-      s += quad ? "x4" : "x2";
-      break;
-    case 'l':
-      s += (poly && !usgn)? "poly64" : "int64";
-      if (scal)
-        break;
-      s += quad ? "x2" : "x1";
-      break;
-    case 'h':
-      s += "float16";
-      if (scal)
-        break;
-      s += quad ? "x8" : "x4";
-      break;
-    case 'f':
-      s += "float32";
-      if (scal)
-        break;
-      s += quad ? "x4" : "x2";
-      break;
-    case 'd':
-      s += "float64";
-      if (scal)
-        break;
-      s += quad ? "x2" : "x1";
-      break;
-
-    default:
-      PrintFatalError("unhandled type!");
+    }
+  }
+  if (CK == ClassB) {
+    typeCode = '\0';
   }
 
-  if (mod == '2' || mod == 'B')
-    s += "x2";
-  if (mod == '3' || mod == 'C')
-    s += "x3";
-  if (mod == '4' || mod == 'D')
-    s += "x4";
+  std::string S;
+  if (typeCode != '\0')
+    S.push_back(typeCode);
+  if (printNumber)
+    S += utostr(T.getElementSizeInBits());
 
-  // Append _t, finishing the type string typedef type.
-  s += "_t";
-
-  if (cnst)
-    s += " const";
-
-  if (pntr)
-    s += " *";
-
-  return s.str();
+  return S;
 }
 
-/// BuiltinTypeString - for a modifier and type, generate the clang
-/// BuiltinsARM.def prototype code for the function.  See the top of clang's
-/// Builtins.def for a description of the type strings.
-static std::string BuiltinTypeString(const char mod, StringRef typestr,
-                                     ClassKind ck, bool ret) {
-  bool quad = false;
-  bool poly = false;
-  bool usgn = false;
-  bool scal = false;
-  bool cnst = false;
-  bool pntr = false;
+std::string Intrinsic::getBuiltinTypeStr() {
+  ClassKind LocalCK = getClassKind(true);
+  std::string S;
 
-  if (mod == 'v')
-    return "v"; // void
-  if (mod == 'i')
-    return "i"; // int
-
-  // base type to get the type string for.
-  char type = ClassifyType(typestr, quad, poly, usgn);
-
-  // Based on the modifying character, change the type and width if necessary.
-  type = ModType(mod, type, quad, poly, usgn, scal, cnst, pntr);
-
-  // All pointers are void* pointers.  Change type to 'v' now.
-  if (pntr) {
-    usgn = false;
-    poly = false;
-    type = 'v';
-  }
-  // Treat half-float ('h') types as unsigned short ('s') types.
-  if (type == 'h') {
-    type = 's';
-    usgn = true;
-  }
-  usgn = usgn | poly | ((ck == ClassI || ck == ClassW) &&
-                         scal && type != 'f' && type != 'd');
-
-  if (scal) {
-    SmallString<128> s;
-
-    if (usgn)
-      s.push_back('U');
-    else if (type == 'c')
-      s.push_back('S'); // make chars explicitly signed
-
-    if (type == 'l') // 64-bit long
-      s += "LLi";
-    else
-      s.push_back(type);
-
-    if (cnst)
-      s.push_back('C');
-    if (pntr)
-      s.push_back('*');
-    return s.str();
-  }
+  Type RetT = getReturnType();
+  if ((LocalCK == ClassI || LocalCK == ClassW) && RetT.isScalar() &&
+      !RetT.isFloating())
+    RetT.makeInteger(RetT.getElementSizeInBits(), false);
 
   // Since the return value must be one type, return a vector type of the
   // appropriate width which we will bitcast.  An exception is made for
   // returning structs of 2, 3, or 4 vectors which are returned in a sret-like
   // fashion, storing them to a pointer arg.
-  if (ret) {
-    if (IsMultiVecProto(mod))
-      return "vv*"; // void result with void* first argument
-    if (mod == 'f' || (ck != ClassB && type == 'f'))
-      return quad ? "V4f" : "V2f";
-    if (ck != ClassB && type == 'd')
-      return quad ? "V2d" : "V1d";
-    if (ck != ClassB && type == 's')
-      return quad ? "V8s" : "V4s";
-    if (ck != ClassB && type == 'i')
-      return quad ? "V4i" : "V2i";
-    if (ck != ClassB && type == 'l')
-      return quad ? "V2LLi" : "V1LLi";
-
-    return quad ? "V16Sc" : "V8Sc";
-  }
-
-  // Non-return array types are passed as individual vectors.
-  if (mod == '2' || mod == 'B')
-    return quad ? "V16ScV16Sc" : "V8ScV8Sc";
-  if (mod == '3' || mod == 'C')
-    return quad ? "V16ScV16ScV16Sc" : "V8ScV8ScV8Sc";
-  if (mod == '4' || mod == 'D')
-    return quad ? "V16ScV16ScV16ScV16Sc" : "V8ScV8ScV8ScV8Sc";
-
-  if (mod == 'f' || (ck != ClassB && type == 'f'))
-    return quad ? "V4f" : "V2f";
-  if (ck != ClassB && type == 'd')
-    return quad ? "V2d" : "V1d";
-  if (ck != ClassB && type == 's')
-    return quad ? "V8s" : "V4s";
-  if (ck != ClassB && type == 'i')
-    return quad ? "V4i" : "V2i";
-  if (ck != ClassB && type == 'l')
-    return quad ? "V2LLi" : "V1LLi";
-
-  return quad ? "V16Sc" : "V8Sc";
-}
-
-/// InstructionTypeCode - Computes the ARM argument character code and
-/// quad status for a specific type string and ClassKind.
-static void InstructionTypeCode(const StringRef &typeStr,
-                                const ClassKind ck,
-                                bool &quad,
-                                std::string &typeCode) {
-  bool poly = false;
-  bool usgn = false;
-  char type = ClassifyType(typeStr, quad, poly, usgn);
-
-  switch (type) {
-  case 'c':
-    switch (ck) {
-    case ClassS: typeCode = poly ? "p8" : usgn ? "u8" : "s8"; break;
-    case ClassI: typeCode = "i8"; break;
-    case ClassW: typeCode = "8"; break;
-    default: break;
-    }
-    break;
-  case 's':
-    switch (ck) {
-    case ClassS: typeCode = poly ? "p16" : usgn ? "u16" : "s16"; break;
-    case ClassI: typeCode = "i16"; break;
-    case ClassW: typeCode = "16"; break;
-    default: break;
-    }
-    break;
-  case 'i':
-    switch (ck) {
-    case ClassS: typeCode = usgn ? "u32" : "s32"; break;
-    case ClassI: typeCode = "i32"; break;
-    case ClassW: typeCode = "32"; break;
-    default: break;
-    }
-    break;
-  case 'l':
-    switch (ck) {
-    case ClassS: typeCode = poly ? "p64" : usgn ? "u64" : "s64"; break;
-    case ClassI: typeCode = "i64"; break;
-    case ClassW: typeCode = "64"; break;
-    default: break;
-    }
-    break;
-  case 'h':
-    switch (ck) {
-    case ClassS:
-    case ClassI: typeCode = "f16"; break;
-    case ClassW: typeCode = "16"; break;
-    default: break;
-    }
-    break;
-  case 'f':
-    switch (ck) {
-    case ClassS:
-    case ClassI: typeCode = "f32"; break;
-    case ClassW: typeCode = "32"; break;
-    default: break;
-    }
-    break;
-  case 'd':
-    switch (ck) {
-    case ClassS:
-    case ClassI:
-      typeCode += "f64";
-      break;
-    case ClassW:
-      PrintFatalError("unhandled type!");
-    default:
-      break;
-    }
-    break;
-  default:
-    PrintFatalError("unhandled type!");
-  }
-}
-
-static char Insert_BHSD_Suffix(StringRef typestr){
-  unsigned off = 0;
-  if(typestr[off++] == 'S'){
-    while(typestr[off] == 'Q' || typestr[off] == 'H'||
-          typestr[off] == 'P' || typestr[off] == 'U')
-      ++off;
-    switch (typestr[off]){
-    default  : break;
-    case 'c' : return 'b';
-    case 's' : return 'h';
-    case 'i' :
-    case 'f' : return 's';
-    case 'l' :
-    case 'd' : return 'd';
-    }
-  }
-  return 0;
-}
-
-static bool endsWith_xN(std::string const &name) {
-  if (name.length() > 3) {
-    if (name.compare(name.length() - 3, 3, "_x2") == 0 ||
-        name.compare(name.length() - 3, 3, "_x3") == 0 ||
-        name.compare(name.length() - 3, 3, "_x4") == 0)
-      return true;
-  }
-  return false;
-}
-
-/// MangleName - Append a type or width suffix to a base neon function name,
-/// and insert a 'q' in the appropriate location if type string starts with 'Q'.
-/// E.g. turn "vst2_lane" into "vst2q_lane_f32", etc.
-/// Insert proper 'b' 'h' 's' 'd' if prefix 'S' is used.
-static std::string MangleName(const std::string &name, StringRef typestr,
-                              ClassKind ck) {
-  if (name == "vcvt_f32_f16" || name == "vcvt_f32_f64")
-    return name;
-
-  bool quad = false;
-  std::string typeCode = "";
-
-  InstructionTypeCode(typestr, ck, quad, typeCode);
-
-  std::string s = name;
-
-  if (typeCode.size() > 0) {
-    // If the name is end with _xN (N = 2,3,4), insert the typeCode before _xN.
-    if (endsWith_xN(s))
-      s.insert(s.length() - 3, "_" + typeCode);
-    else
-      s += "_" + typeCode;
-  }
-
-  if (ck == ClassB)
-    s += "_v";
-
-  // Insert a 'q' before the first '_' character so that it ends up before
-  // _lane or _n on vector-scalar operations.
-  if (typestr.find("Q") != StringRef::npos) {
-      size_t pos = s.find('_');
-      s = s.insert(pos, "q");
-  }
-  char ins = Insert_BHSD_Suffix(typestr);
-  if(ins){
-    size_t pos = s.find('_');
-    s = s.insert(pos, &ins, 1);
-  }
-
-  return s;
-}
-
-static void PreprocessInstruction(const StringRef &Name,
-                                  const std::string &InstName,
-                                  std::string &Prefix,
-                                  bool &HasNPostfix,
-                                  bool &HasLanePostfix,
-                                  bool &HasDupPostfix,
-                                  bool &IsSpecialVCvt,
-                                  size_t &TBNumber) {
-  // All of our instruction name fields from arm_neon.td are of the form
-  //   <instructionname>_...
-  // Thus we grab our instruction name via computation of said Prefix.
-  const size_t PrefixEnd = Name.find_first_of('_');
-  // If InstName is passed in, we use that instead of our name Prefix.
-  Prefix = InstName.size() == 0? Name.slice(0, PrefixEnd).str() : InstName;
-
-  const StringRef Postfix = Name.slice(PrefixEnd, Name.size());
-
-  HasNPostfix = Postfix.count("_n");
-  HasLanePostfix = Postfix.count("_lane");
-  HasDupPostfix = Postfix.count("_dup");
-  IsSpecialVCvt = Postfix.size() != 0 && Name.count("vcvt");
-
-  if (InstName.compare("vtbl") == 0 ||
-      InstName.compare("vtbx") == 0) {
-    // If we have a vtblN/vtbxN instruction, use the instruction's ASCII
-    // encoding to get its true value.
-    TBNumber = Name[Name.size()-1] - 48;
-  }
-}
-
-/// GenerateRegisterCheckPatternsForLoadStores - Given a bunch of data we have
-/// extracted, generate a FileCheck pattern for a Load Or Store
-static void
-GenerateRegisterCheckPatternForLoadStores(const StringRef &NameRef,
-                                          const std::string& OutTypeCode,
-                                          const bool &IsQuad,
-                                          const bool &HasDupPostfix,
-                                          const bool &HasLanePostfix,
-                                          const size_t Count,
-                                          std::string &RegisterSuffix) {
-  const bool IsLDSTOne = NameRef.count("vld1") || NameRef.count("vst1");
-  // If N == 3 || N == 4 and we are dealing with a quad instruction, Clang
-  // will output a series of v{ld,st}1s, so we have to handle it specially.
-  if ((Count == 3 || Count == 4) && IsQuad) {
-    RegisterSuffix += "{";
-    for (size_t i = 0; i < Count; i++) {
-      RegisterSuffix += "d{{[0-9]+}}";
-      if (HasDupPostfix) {
-        RegisterSuffix += "[]";
-      }
-      if (HasLanePostfix) {
-        RegisterSuffix += "[{{[0-9]+}}]";
-      }
-      if (i < Count-1) {
-        RegisterSuffix += ", ";
-      }
-    }
-    RegisterSuffix += "}";
+  if (RetT.getNumVectors() > 1) {
+    S += "vv*"; // void result with void* first argument
   } else {
+    if (RetT.isPoly())
+      RetT.makeInteger(RetT.getElementSizeInBits(), false);
+    if (!RetT.isScalar() && !RetT.isSigned())
+      RetT.makeSigned();
 
-    // Handle normal loads and stores.
-    RegisterSuffix += "{";
-    for (size_t i = 0; i < Count; i++) {
-      RegisterSuffix += "d{{[0-9]+}}";
-      if (HasDupPostfix) {
-        RegisterSuffix += "[]";
-      }
-      if (HasLanePostfix) {
-        RegisterSuffix += "[{{[0-9]+}}]";
-      }
-      if (IsQuad && !HasLanePostfix) {
-        RegisterSuffix += ", d{{[0-9]+}}";
-        if (HasDupPostfix) {
-          RegisterSuffix += "[]";
-        }
-      }
-      if (i < Count-1) {
-        RegisterSuffix += ", ";
-      }
-    }
-    RegisterSuffix += "}, [r{{[0-9]+}}";
+    bool ForcedVectorFloatingType = Proto[0] == 'F' || Proto[0] == 'f';
+    if (LocalCK == ClassB && !RetT.isScalar() && !ForcedVectorFloatingType)
+      // Cast to vector of 8-bit elements.
+      RetT.makeInteger(8, true);
 
-    // We only include the alignment hint if we have a vld1.*64 or
-    // a dup/lane instruction.
-    if (IsLDSTOne) {
-      if ((HasLanePostfix || HasDupPostfix) && OutTypeCode != "8") {
-        RegisterSuffix += ":" + OutTypeCode;
-      }
-    }
-
-    RegisterSuffix += "]";
+    S += RetT.builtin_str();
   }
+
+  for (unsigned I = 0; I < getNumParams(); ++I) {
+    Type T = getParamType(I);
+    if (T.isPoly())
+      T.makeInteger(T.getElementSizeInBits(), false);
+
+    bool ForcedFloatingType = Proto[I + 1] == 'F' || Proto[I + 1] == 'f';
+    if (LocalCK == ClassB && !T.isScalar() && !ForcedFloatingType)
+      T.makeInteger(8, true);
+    // Halves always get converted to 8-bit elements.
+    if (T.isHalf() && T.isVector() && !T.isScalarForMangling())
+      T.makeInteger(8, true);
+
+    if (LocalCK == ClassI)
+      T.makeSigned();
+
+    // Constant indices are always just "int".
+    if (hasImmediate() && getImmediateIdx() == I)
+      T.makeInteger(32, true);
+
+    S += T.builtin_str();
+  }
+
+  // Extra constant integer to hold type class enum for this function, e.g. s8
+  if (LocalCK == ClassB)
+    S += "i";
+
+  return S;
 }
 
-static bool HasNPostfixAndScalarArgs(const StringRef &NameRef,
-                                     const bool &HasNPostfix) {
-  return (NameRef.count("vmla") ||
-          NameRef.count("vmlal") ||
-          NameRef.count("vmlsl") ||
-          NameRef.count("vmull") ||
-          NameRef.count("vqdmlal") ||
-          NameRef.count("vqdmlsl") ||
-          NameRef.count("vqdmulh") ||
-          NameRef.count("vqdmull") ||
-          NameRef.count("vqrdmulh")) && HasNPostfix;
-}
-
-static bool IsFiveOperandLaneAccumulator(const StringRef &NameRef,
-                                         const bool &HasLanePostfix) {
-  return (NameRef.count("vmla") ||
-          NameRef.count("vmls") ||
-          NameRef.count("vmlal") ||
-          NameRef.count("vmlsl") ||
-          (NameRef.count("vmul") && NameRef.size() == 3)||
-          NameRef.count("vqdmlal") ||
-          NameRef.count("vqdmlsl") ||
-          NameRef.count("vqdmulh") ||
-          NameRef.count("vqrdmulh")) && HasLanePostfix;
-}
-
-static bool IsSpecialLaneMultiply(const StringRef &NameRef,
-                                  const bool &HasLanePostfix,
-                                  const bool &IsQuad) {
-  const bool IsVMulOrMulh = (NameRef.count("vmul") || NameRef.count("mulh"))
-                               && IsQuad;
-  const bool IsVMull = NameRef.count("mull") && !IsQuad;
-  return (IsVMulOrMulh || IsVMull) && HasLanePostfix;
-}
-
-static void NormalizeProtoForRegisterPatternCreation(const std::string &Name,
-                                                     const std::string &Proto,
-                                                     const bool &HasNPostfix,
-                                                     const bool &IsQuad,
-                                                     const bool &HasLanePostfix,
-                                                     const bool &HasDupPostfix,
-                                                     std::string &NormedProto) {
-  // Handle generic case.
-  const StringRef NameRef(Name);
-  for (size_t i = 0, end = Proto.size(); i < end; i++) {
-    switch (Proto[i]) {
-    case 'u':
-    case 'f':
-    case 'd':
-    case 's':
-    case 'x':
-    case 't':
-    case 'n':
-      NormedProto += IsQuad? 'q' : 'd';
-      break;
-    case 'w':
-    case 'k':
-      NormedProto += 'q';
-      break;
-    case 'g':
-    case 'j':
-    case 'h':
-    case 'e':
-      NormedProto += 'd';
-      break;
-    case 'i':
-      NormedProto += HasLanePostfix? 'a' : 'i';
-      break;
-    case 'a':
-      if (HasLanePostfix) {
-        NormedProto += 'a';
-      } else if (HasNPostfixAndScalarArgs(NameRef, HasNPostfix)) {
-        NormedProto += IsQuad? 'q' : 'd';
-      } else {
-        NormedProto += 'i';
-      }
-      break;
-    }
-  }
-
-  // Handle Special Cases.
-  const bool IsNotVExt = !NameRef.count("vext");
-  const bool IsVPADAL = NameRef.count("vpadal");
-  const bool Is5OpLaneAccum = IsFiveOperandLaneAccumulator(NameRef,
-                                                           HasLanePostfix);
-  const bool IsSpecialLaneMul = IsSpecialLaneMultiply(NameRef, HasLanePostfix,
-                                                      IsQuad);
-
-  if (IsSpecialLaneMul) {
-    // If
-    NormedProto[2] = NormedProto[3];
-    NormedProto.erase(3);
-  } else if (NormedProto.size() == 4 &&
-             NormedProto[0] == NormedProto[1] &&
-             IsNotVExt) {
-    // If NormedProto.size() == 4 and the first two proto characters are the
-    // same, ignore the first.
-    NormedProto = NormedProto.substr(1, 3);
-  } else if (Is5OpLaneAccum) {
-    // If we have a 5 op lane accumulator operation, we take characters 1,2,4
-    std::string tmp = NormedProto.substr(1,2);
-    tmp += NormedProto[4];
-    NormedProto = tmp;
-  } else if (IsVPADAL) {
-    // If we have VPADAL, ignore the first character.
-    NormedProto = NormedProto.substr(0, 2);
-  } else if (NameRef.count("vdup") && NormedProto.size() > 2) {
-    // If our instruction is a dup instruction, keep only the first and
-    // last characters.
-    std::string tmp = "";
-    tmp += NormedProto[0];
-    tmp += NormedProto[NormedProto.size()-1];
-    NormedProto = tmp;
-  }
-}
-
-/// GenerateRegisterCheckPatterns - Given a bunch of data we have
-/// extracted, generate a FileCheck pattern to check that an
-/// instruction's arguments are correct.
-static void GenerateRegisterCheckPattern(const std::string &Name,
-                                         const std::string &Proto,
-                                         const std::string &OutTypeCode,
-                                         const bool &HasNPostfix,
-                                         const bool &IsQuad,
-                                         const bool &HasLanePostfix,
-                                         const bool &HasDupPostfix,
-                                         const size_t &TBNumber,
-                                         std::string &RegisterSuffix) {
-
-  RegisterSuffix = "";
-
-  const StringRef NameRef(Name);
-  const StringRef ProtoRef(Proto);
-
-  if ((NameRef.count("vdup") || NameRef.count("vmov")) && HasNPostfix) {
-    return;
-  }
-
-  const bool IsLoadStore = NameRef.count("vld") || NameRef.count("vst");
-  const bool IsTBXOrTBL = NameRef.count("vtbl") || NameRef.count("vtbx");
-
-  if (IsLoadStore) {
-    // Grab N value from  v{ld,st}N using its ascii representation.
-    const size_t Count = NameRef[3] - 48;
-
-    GenerateRegisterCheckPatternForLoadStores(NameRef, OutTypeCode, IsQuad,
-                                              HasDupPostfix, HasLanePostfix,
-                                              Count, RegisterSuffix);
-  } else if (IsTBXOrTBL) {
-    RegisterSuffix += "d{{[0-9]+}}, {";
-    for (size_t i = 0; i < TBNumber-1; i++) {
-      RegisterSuffix += "d{{[0-9]+}}, ";
-    }
-    RegisterSuffix += "d{{[0-9]+}}}, d{{[0-9]+}}";
-  } else {
-    // Handle a normal instruction.
-    if (NameRef.count("vget") || NameRef.count("vset"))
-      return;
-
-    // We first normalize our proto, since we only need to emit 4
-    // different types of checks, yet have more than 4 proto types
-    // that map onto those 4 patterns.
-    std::string NormalizedProto("");
-    NormalizeProtoForRegisterPatternCreation(Name, Proto, HasNPostfix, IsQuad,
-                                             HasLanePostfix, HasDupPostfix,
-                                             NormalizedProto);
-
-    for (size_t i = 0, end = NormalizedProto.size(); i < end; i++) {
-      const char &c = NormalizedProto[i];
-      switch (c) {
-      case 'q':
-        RegisterSuffix += "q{{[0-9]+}}, ";
-        break;
-
-      case 'd':
-        RegisterSuffix += "d{{[0-9]+}}, ";
-        break;
-
-      case 'i':
-        RegisterSuffix += "#{{[0-9]+}}, ";
-        break;
-
-      case 'a':
-        RegisterSuffix += "d{{[0-9]+}}[{{[0-9]}}], ";
-        break;
-      }
-    }
-
-    // Remove extra ", ".
-    RegisterSuffix = RegisterSuffix.substr(0, RegisterSuffix.size()-2);
-  }
-}
-
-/// GenerateChecksForIntrinsic - Given a specific instruction name +
-/// typestr + class kind, generate the proper set of FileCheck
-/// Patterns to check for. We could just return a string, but instead
-/// use a vector since it provides us with the extra flexibility of
-/// emitting multiple checks, which comes in handy for certain cases
-/// like mla where we want to check for 2 different instructions.
-static void GenerateChecksForIntrinsic(const std::string &Name,
-                                       const std::string &Proto,
-                                       StringRef &OutTypeStr,
-                                       StringRef &InTypeStr,
-                                       ClassKind Ck,
-                                       const std::string &InstName,
-                                       bool IsHiddenLOp,
-                                       std::vector<std::string>& Result) {
-
-  // If Ck is a ClassNoTest instruction, just return so no test is
-  // emitted.
-  if(Ck == ClassNoTest)
-    return;
-
-  if (Name == "vcvt_f32_f16") {
-    Result.push_back("vcvt.f32.f16");
-    return;
-  }
-
-
-  // Now we preprocess our instruction given the data we have to get the
-  // data that we need.
-  // Create a StringRef for String Manipulation of our Name.
-  const StringRef NameRef(Name);
-  // Instruction Prefix.
-  std::string Prefix;
-  // The type code for our out type string.
-  std::string OutTypeCode;
-  // To handle our different cases, we need to check for different postfixes.
-  // Is our instruction a quad instruction.
-  bool IsQuad = false;
-  // Our instruction is of the form <instructionname>_n.
-  bool HasNPostfix = false;
-  // Our instruction is of the form <instructionname>_lane.
-  bool HasLanePostfix = false;
-  // Our instruction is of the form <instructionname>_dup.
-  bool HasDupPostfix  = false;
-  // Our instruction is a vcvt instruction which requires special handling.
-  bool IsSpecialVCvt = false;
-  // If we have a vtbxN or vtblN instruction, this is set to N.
-  size_t TBNumber = -1;
-  // Register Suffix
-  std::string RegisterSuffix;
-
-  PreprocessInstruction(NameRef, InstName, Prefix,
-                        HasNPostfix, HasLanePostfix, HasDupPostfix,
-                        IsSpecialVCvt, TBNumber);
-
-  InstructionTypeCode(OutTypeStr, Ck, IsQuad, OutTypeCode);
-  GenerateRegisterCheckPattern(Name, Proto, OutTypeCode, HasNPostfix, IsQuad,
-                               HasLanePostfix, HasDupPostfix, TBNumber,
-                               RegisterSuffix);
-
-  // In the following section, we handle a bunch of special cases. You can tell
-  // a special case by the fact we are returning early.
-
-  // If our instruction is a logical instruction without postfix or a
-  // hidden LOp just return the current Prefix.
-  if (Ck == ClassL || IsHiddenLOp) {
-    Result.push_back(Prefix + " " + RegisterSuffix);
-    return;
-  }
-
-  // If we have a vmov, due to the many different cases, some of which
-  // vary within the different intrinsics generated for a single
-  // instruction type, just output a vmov. (e.g. given an instruction
-  // A, A.u32 might be vmov and A.u8 might be vmov.8).
-  //
-  // FIXME: Maybe something can be done about this. The two cases that we care
-  // about are vmov as an LType and vmov as a WType.
-  if (Prefix == "vmov") {
-    Result.push_back(Prefix + " " + RegisterSuffix);
-    return;
-  }
-
-  // In the following section, we handle special cases.
-
-  if (OutTypeCode == "64") {
-    // If we have a 64 bit vdup/vext and are handling an uint64x1_t
-    // type, the intrinsic will be optimized away, so just return
-    // nothing.  On the other hand if we are handling an uint64x2_t
-    // (i.e. quad instruction), vdup/vmov instructions should be
-    // emitted.
-    if (Prefix == "vdup" || Prefix == "vext") {
-      if (IsQuad) {
-        Result.push_back("{{vmov|vdup}}");
-      }
-      return;
-    }
-
-    // v{st,ld}{2,3,4}_{u,s}64 emit v{st,ld}1.64 instructions with
-    // multiple register operands.
-    bool MultiLoadPrefix = Prefix == "vld2" || Prefix == "vld3"
-                            || Prefix == "vld4";
-    bool MultiStorePrefix = Prefix == "vst2" || Prefix == "vst3"
-                            || Prefix == "vst4";
-    if (MultiLoadPrefix || MultiStorePrefix) {
-      Result.push_back(NameRef.slice(0, 3).str() + "1.64");
-      return;
-    }
-
-    // v{st,ld}1_{lane,dup}_{u64,s64} use vldr/vstr/vmov/str instead of
-    // emitting said instructions. So return a check for
-    // vldr/vstr/vmov/str instead.
-    if (HasLanePostfix || HasDupPostfix) {
-      if (Prefix == "vst1") {
-        Result.push_back("{{str|vstr|vmov}}");
-        return;
-      } else if (Prefix == "vld1") {
-        Result.push_back("{{ldr|vldr|vmov}}");
-        return;
-      }
-    }
-  }
-
-  // vzip.32/vuzp.32 are the same instruction as vtrn.32 and are
-  // sometimes disassembled as vtrn.32. We use a regex to handle both
-  // cases.
-  if ((Prefix == "vzip" || Prefix == "vuzp") && OutTypeCode == "32") {
-    Result.push_back("{{vtrn|" + Prefix + "}}.32 " + RegisterSuffix);
-    return;
-  }
-
-  // Currently on most ARM processors, we do not use vmla/vmls for
-  // quad floating point operations. Instead we output vmul + vadd. So
-  // check if we have one of those instructions and just output a
-  // check for vmul.
-  if (OutTypeCode == "f32") {
-    if (Prefix == "vmls") {
-      Result.push_back("vmul." + OutTypeCode + " " + RegisterSuffix);
-      Result.push_back("vsub." + OutTypeCode);
-      return;
-    } else if (Prefix == "vmla") {
-      Result.push_back("vmul." + OutTypeCode + " " + RegisterSuffix);
-      Result.push_back("vadd." + OutTypeCode);
-      return;
-    }
-  }
-
-  // If we have vcvt, get the input type from the instruction name
-  // (which should be of the form instname_inputtype) and append it
-  // before the output type.
-  if (Prefix == "vcvt") {
-    const std::string inTypeCode = NameRef.substr(NameRef.find_last_of("_")+1);
-    Prefix += "." + inTypeCode;
-  }
-
-  // Append output type code to get our final mangled instruction.
-  Prefix += "." + OutTypeCode;
-
-  Result.push_back(Prefix + " " + RegisterSuffix);
-}
-
-/// UseMacro - Examine the prototype string to determine if the intrinsic
-/// should be defined as a preprocessor macro instead of an inline function.
-static bool UseMacro(const std::string &proto) {
-  // If this builtin takes an immediate argument, we need to #define it rather
-  // than use a standard declaration, so that SemaChecking can range check
-  // the immediate passed by the user.
-  if (proto.find('i') != std::string::npos)
-    return true;
-
-  // Pointer arguments need to use macros to avoid hiding aligned attributes
-  // from the pointer type.
-  if (proto.find('p') != std::string::npos ||
-      proto.find('c') != std::string::npos)
-    return true;
-
-  return false;
-}
-
-/// MacroArgUsedDirectly - Return true if argument i for an intrinsic that is
-/// defined as a macro should be accessed directly instead of being first
-/// assigned to a local temporary.
-static bool MacroArgUsedDirectly(const std::string &proto, unsigned i) {
-  // True for constant ints (i), pointers (p) and const pointers (c).
-  return (proto[i] == 'i' || proto[i] == 'p' || proto[i] == 'c');
-}
-
-// Generate the string "(argtype a, argtype b, ...)"
-static std::string GenArgs(const std::string &proto, StringRef typestr,
-                           const std::string &name) {
-  bool define = UseMacro(proto);
-  char arg = 'a';
-
-  std::string s;
-  s += "(";
-
-  for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) {
-    if (define) {
-      // Some macro arguments are used directly instead of being assigned
-      // to local temporaries; prepend an underscore prefix to make their
-      // names consistent with the local temporaries.
-      if (MacroArgUsedDirectly(proto, i))
-        s += "__";
-    } else {
-      s += TypeString(proto[i], typestr) + " __";
-    }
-    s.push_back(arg);
-    //To avoid argument being multiple defined, add extra number for renaming.
-    if (name == "vcopy_lane" || name == "vcopy_laneq")
-      s.push_back('1');
-    if ((i + 1) < e)
-      s += ", ";
-  }
-
-  s += ")";
-  return s;
-}
-
-// Macro arguments are not type-checked like inline function arguments, so
-// assign them to local temporaries to get the right type checking.
-static std::string GenMacroLocals(const std::string &proto, StringRef typestr,
-                                  const std::string &name ) {
-  char arg = 'a';
-  std::string s;
-  bool generatedLocal = false;
-
-  for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) {
-    // Do not create a temporary for an immediate argument.
-    // That would defeat the whole point of using a macro!
-    if (MacroArgUsedDirectly(proto, i))
-      continue;
-    generatedLocal = true;
-    bool extranumber = false;
-    if (name == "vcopy_lane" || name == "vcopy_laneq")
-      extranumber = true;
-
-    s += TypeString(proto[i], typestr) + " __";
-    s.push_back(arg);
-    if(extranumber)
-      s.push_back('1');
-    s += " = (";
-    s.push_back(arg);
-    if(extranumber)
-      s.push_back('1');
-    s += "); ";
-  }
-
-  if (generatedLocal)
-    s += "\\\n  ";
-  return s;
-}
-
-// Use the vmovl builtin to sign-extend or zero-extend a vector.
-static std::string Extend(StringRef typestr, const std::string &a, bool h=0) {
-  std::string s, high;
-  high = h ? "_high" : "";
-  s = MangleName("vmovl" + high, typestr, ClassS);
-  s += "(" + a + ")";
-  return s;
-}
-
-// Get the high 64-bit part of a vector
-static std::string GetHigh(const std::string &a, StringRef typestr) {
-  std::string s;
-  s = MangleName("vget_high", typestr, ClassS);
-  s += "(" + a + ")";
-  return s;
-}
-
-// Gen operation with two operands and get high 64-bit for both of two operands.
-static std::string Gen2OpWith2High(StringRef typestr,
-                                   const std::string &op,
-                                   const std::string &a,
-                                   const std::string &b) {
-  std::string s;
-  std::string Op1 = GetHigh(a, typestr);
-  std::string Op2 = GetHigh(b, typestr);
-  s = MangleName(op, typestr, ClassS);
-  s += "(" + Op1 + ", " + Op2 + ");";
-  return s;
-}
-
-// Gen operation with three operands and get high 64-bit of the latter 
-// two operands.
-static std::string Gen3OpWith2High(StringRef typestr,
-                                   const std::string &op,
-                                   const std::string &a,
-                                   const std::string &b,
-                                   const std::string &c) {
-  std::string s;
-  std::string Op1 = GetHigh(b, typestr);
-  std::string Op2 = GetHigh(c, typestr);
-  s = MangleName(op, typestr, ClassS);
-  s += "(" + a + ", " + Op1 + ", " + Op2 + ");";
-  return s;
-}
-
-// Gen combine operation by putting a on low 64-bit, and b on high 64-bit.
-static std::string GenCombine(std::string typestr,
-                              const std::string &a,
-                              const std::string &b) {
-  std::string s;
-  s = MangleName("vcombine", typestr, ClassS);
-  s += "(" + a + ", " + b + ")";
-  return s;
-}
-
-static std::string Duplicate(unsigned nElts, StringRef typestr,
-                             const std::string &a) {
-  std::string s;
-
-  s = "(" + TypeString('d', typestr) + "){ ";
-  for (unsigned i = 0; i != nElts; ++i) {
-    s += a;
-    if ((i + 1) < nElts)
-      s += ", ";
-  }
-  s += " }";
-
-  return s;
-}
-
-static std::string SplatLane(unsigned nElts, const std::string &vec,
-                             const std::string &lane) {
-  std::string s = "__builtin_shufflevector(" + vec + ", " + vec;
-  for (unsigned i = 0; i < nElts; ++i)
-    s += ", " + lane;
-  s += ")";
-  return s;
-}
-
-static std::string RemoveHigh(const std::string &name) {
-  std::string s = name;
-  std::size_t found = s.find("_high_");
-  if (found == std::string::npos)
-    PrintFatalError("name should contain \"_high_\" for high intrinsics");
-  s.replace(found, 5, "");
-  return s;
-}
-
-static unsigned GetNumElements(StringRef typestr, bool &quad) {
-  quad = false;
-  bool dummy = false;
-  char type = ClassifyType(typestr, quad, dummy, dummy);
-  unsigned nElts = 0;
-  switch (type) {
-  case 'c': nElts = 8; break;
-  case 's': nElts = 4; break;
-  case 'i': nElts = 2; break;
-  case 'l': nElts = 1; break;
-  case 'h': nElts = 4; break;
-  case 'f': nElts = 2; break;
-  case 'd':
-    nElts = 1;
-    break;
-  default:
-    PrintFatalError("unhandled type!");
-  }
-  if (quad) nElts <<= 1;
-  return nElts;
-}
-
-// Generate the definition for this intrinsic, e.g. "a + b" for OpAdd.
-static std::string GenOpString(const std::string &name, OpKind op,
-                               const std::string &proto, StringRef typestr) {
-  bool quad;
-  unsigned nElts = GetNumElements(typestr, quad);
-  bool define = UseMacro(proto);
-
-  std::string ts = TypeString(proto[0], typestr);
-  std::string s;
-  if (!define) {
-    s = "return ";
-  }
-
-  switch(op) {
-  case OpAdd:
-    s += "__a + __b;";
-    break;
-  case OpAddl:
-    s += Extend(typestr, "__a") + " + " + Extend(typestr, "__b") + ";";
-    break;
-  case OpAddlHi:
-    s += Extend(typestr, "__a", 1) + " + " + Extend(typestr, "__b", 1) + ";";
-    break;
-  case OpAddw:
-    s += "__a + " + Extend(typestr, "__b") + ";";
-    break;
-  case OpAddwHi:
-    s += "__a + " + Extend(typestr, "__b", 1) + ";";
-    break;
-  case OpSub:
-    s += "__a - __b;";
-    break;
-  case OpSubl:
-    s += Extend(typestr, "__a") + " - " + Extend(typestr, "__b") + ";";
-    break;
-  case OpSublHi:
-    s += Extend(typestr, "__a", 1) + " - " + Extend(typestr, "__b", 1) + ";";
-    break;
-  case OpSubw:
-    s += "__a - " + Extend(typestr, "__b") + ";";
-    break;
-  case OpSubwHi:
-    s += "__a - " + Extend(typestr, "__b", 1) + ";";
-    break;
-  case OpMulN:
-    s += "__a * " + Duplicate(nElts, typestr, "__b") + ";";
-    break;
-  case OpMulLane:
-    s += "__a * " + SplatLane(nElts, "__b", "__c") + ";";
-    break;
-  case OpMulXLane:
-    s += MangleName("vmulx", typestr, ClassS) + "(__a, " +
-      SplatLane(nElts, "__b", "__c") + ");";
-    break;
-  case OpMul:
-    s += "__a * __b;";
-    break;
-  case OpMullLane:
-    s += MangleName("vmull", typestr, ClassS) + "(__a, " +
-      SplatLane(nElts, "__b", "__c") + ");";
-    break;
-  case OpMullHiLane:
-    s += MangleName("vmull", typestr, ClassS) + "(" +
-      GetHigh("__a", typestr) + ", " + SplatLane(nElts, "__b", "__c") + ");";
-    break;
-  case OpMlaN:
-    s += "__a + (__b * " + Duplicate(nElts, typestr, "__c") + ");";
-    break;
-  case OpMlaLane:
-    s += "__a + (__b * " + SplatLane(nElts, "__c", "__d") + ");";
-    break;
-  case OpMla:
-    s += "__a + (__b * __c);";
-    break;
-  case OpMlalN:
-    s += "__a + " + MangleName("vmull", typestr, ClassS) + "(__b, " +
-      Duplicate(nElts, typestr, "__c") + ");";
-    break;
-  case OpMlalLane:
-    s += "__a + " + MangleName("vmull", typestr, ClassS) + "(__b, " +
-      SplatLane(nElts, "__c", "__d") + ");";
-    break;
-  case OpMlalHiLane:
-    s += "__a + " + MangleName("vmull", typestr, ClassS) + "(" +
-      GetHigh("__b", typestr) + ", " + SplatLane(nElts, "__c", "__d") + ");";
-    break;
-  case OpMlal:
-    s += "__a + " + MangleName("vmull", typestr, ClassS) + "(__b, __c);";
-    break;
-  case OpMullHi:
-    s += Gen2OpWith2High(typestr, "vmull", "__a", "__b");
-    break;
-  case OpMlalHi:
-    s += Gen3OpWith2High(typestr, "vmlal", "__a", "__b", "__c");
-    break;
-  case OpMlsN:
-    s += "__a - (__b * " + Duplicate(nElts, typestr, "__c") + ");";
-    break;
-  case OpMlsLane:
-    s += "__a - (__b * " + SplatLane(nElts, "__c", "__d") + ");";
-    break;
-  case OpFMSLane:
-    s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n  ";
-    s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n  ";
-    s += TypeString(proto[3], typestr) + " __c1 = __c; \\\n  ";
-    s += MangleName("vfma_lane", typestr, ClassS) + "(__a1, __b1, -__c1, __d);";
-    break;
-  case OpFMSLaneQ:
-    s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n  ";
-    s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n  ";
-    s += TypeString(proto[3], typestr) + " __c1 = __c; \\\n  ";
-    s += MangleName("vfma_laneq", typestr, ClassS) + "(__a1, __b1, -__c1, __d);";
-    break;
-  case OpMls:
-    s += "__a - (__b * __c);";
-    break;
-  case OpMlslN:
-    s += "__a - " + MangleName("vmull", typestr, ClassS) + "(__b, " +
-      Duplicate(nElts, typestr, "__c") + ");";
-    break;
-  case OpMlslLane:
-    s += "__a - " + MangleName("vmull", typestr, ClassS) + "(__b, " +
-      SplatLane(nElts, "__c", "__d") + ");";
-    break;
-  case OpMlslHiLane:
-    s += "__a - " + MangleName("vmull", typestr, ClassS) + "(" +
-      GetHigh("__b", typestr) + ", " + SplatLane(nElts, "__c", "__d") + ");";
-    break;
-  case OpMlsl:
-    s += "__a - " + MangleName("vmull", typestr, ClassS) + "(__b, __c);";
-    break;
-  case OpMlslHi:
-    s += Gen3OpWith2High(typestr, "vmlsl", "__a", "__b", "__c");
-    break;
-  case OpQDMullLane:
-    s += MangleName("vqdmull", typestr, ClassS) + "(__a, " +
-      SplatLane(nElts, "__b", "__c") + ");";
-    break;
-  case OpQDMullHiLane:
-    s += MangleName("vqdmull", typestr, ClassS) + "(" +
-      GetHigh("__a", typestr) + ", " + SplatLane(nElts, "__b", "__c") + ");";
-    break;
-  case OpQDMlalLane:
-    s += MangleName("vqdmlal", typestr, ClassS) + "(__a, __b, " +
-      SplatLane(nElts, "__c", "__d") + ");";
-    break;
-  case OpQDMlalHiLane:
-    s += MangleName("vqdmlal", typestr, ClassS) + "(__a, " +
-      GetHigh("__b", typestr) + ", " + SplatLane(nElts, "__c", "__d") + ");";
-    break;
-  case OpQDMlslLane:
-    s += MangleName("vqdmlsl", typestr, ClassS) + "(__a, __b, " +
-      SplatLane(nElts, "__c", "__d") + ");";
-    break;
-  case OpQDMlslHiLane:
-    s += MangleName("vqdmlsl", typestr, ClassS) + "(__a, " +
-      GetHigh("__b", typestr) + ", " + SplatLane(nElts, "__c", "__d") + ");";
-    break;
-  case OpQDMulhLane:
-    s += MangleName("vqdmulh", typestr, ClassS) + "(__a, " +
-      SplatLane(nElts, "__b", "__c") + ");";
-    break;
-  case OpQRDMulhLane:
-    s += MangleName("vqrdmulh", typestr, ClassS) + "(__a, " +
-      SplatLane(nElts, "__b", "__c") + ");";
-    break;
-  case OpEq:
-    s += "(" + ts + ")(__a == __b);";
-    break;
-  case OpGe:
-    s += "(" + ts + ")(__a >= __b);";
-    break;
-  case OpLe:
-    s += "(" + ts + ")(__a <= __b);";
-    break;
-  case OpGt:
-    s += "(" + ts + ")(__a > __b);";
-    break;
-  case OpLt:
-    s += "(" + ts + ")(__a < __b);";
-    break;
-  case OpNeg:
-    s += " -__a;";
-    break;
-  case OpNot:
-    s += " ~__a;";
-    break;
-  case OpAnd:
-    s += "__a & __b;";
-    break;
-  case OpOr:
-    s += "__a | __b;";
-    break;
-  case OpXor:
-    s += "__a ^ __b;";
-    break;
-  case OpAndNot:
-    s += "__a & ~__b;";
-    break;
-  case OpOrNot:
-    s += "__a | ~__b;";
-    break;
-  case OpCast:
-    s += "(" + ts + ")__a;";
-    break;
-  case OpConcat:
-    s += "(" + ts + ")__builtin_shufflevector((int64x1_t)__a";
-    s += ", (int64x1_t)__b, 0, 1);";
-    break;
-  case OpHi:
-    // nElts is for the result vector, so the source is twice that number.
-    s += "__builtin_shufflevector(__a, __a";
-    for (unsigned i = nElts; i < nElts * 2; ++i)
-      s += ", " + utostr(i);
-    s+= ");";
-    break;
-  case OpLo:
-    s += "__builtin_shufflevector(__a, __a";
-    for (unsigned i = 0; i < nElts; ++i)
-      s += ", " + utostr(i);
-    s+= ");";
-    break;
-  case OpDup:
-    s += Duplicate(nElts, typestr, "__a") + ";";
-    break;
-  case OpDupLane:
-    s += SplatLane(nElts, "__a", "__b") + ";";
-    break;
-  case OpSelect:
-    // ((0 & 1) | (~0 & 2))
-    s += "(" + ts + ")";
-    ts = TypeString(proto[1], typestr);
-    s += "((__a & (" + ts + ")__b) | ";
-    s += "(~__a & (" + ts + ")__c));";
-    break;
-  case OpRev16:
-    s += "__builtin_shufflevector(__a, __a";
-    for (unsigned i = 2; i <= nElts; i += 2)
-      for (unsigned j = 0; j != 2; ++j)
-        s += ", " + utostr(i - j - 1);
-    s += ");";
-    break;
-  case OpRev32: {
-    unsigned WordElts = nElts >> (1 + (int)quad);
-    s += "__builtin_shufflevector(__a, __a";
-    for (unsigned i = WordElts; i <= nElts; i += WordElts)
-      for (unsigned j = 0; j != WordElts; ++j)
-        s += ", " + utostr(i - j - 1);
-    s += ");";
-    break;
-  }
-  case OpRev64: {
-    unsigned DblWordElts = nElts >> (int)quad;
-    s += "__builtin_shufflevector(__a, __a";
-    for (unsigned i = DblWordElts; i <= nElts; i += DblWordElts)
-      for (unsigned j = 0; j != DblWordElts; ++j)
-        s += ", " + utostr(i - j - 1);
-    s += ");";
-    break;
-  }
-  case OpXtnHi: {
-    s = TypeString(proto[1], typestr) + " __a1 = " +
-        MangleName("vmovn", typestr, ClassS) + "(__b);\n  " +
-        "return __builtin_shufflevector(__a, __a1";
-    for (unsigned i = 0; i < nElts * 4; ++i)
-      s += ", " + utostr(i);
-    s += ");";
-    break;
-  }
-  case OpSqxtunHi: {
-    s = TypeString(proto[1], typestr) + " __a1 = " +
-        MangleName("vqmovun", typestr, ClassS) + "(__b);\n  " +
-        "return __builtin_shufflevector(__a, __a1";
-    for (unsigned i = 0; i < nElts * 4; ++i)
-      s += ", " + utostr(i);
-    s += ");";
-    break;
-  }
-  case OpQxtnHi: {
-    s = TypeString(proto[1], typestr) + " __a1 = " +
-        MangleName("vqmovn", typestr, ClassS) + "(__b);\n  " +
-        "return __builtin_shufflevector(__a, __a1";
-    for (unsigned i = 0; i < nElts * 4; ++i)
-      s += ", " + utostr(i);
-    s += ");";
-    break;
-  }
-  case OpFcvtnHi: {
-    std::string FName = (nElts == 1) ? "vcvt_f32" : "vcvt_f16";
-    s = TypeString(proto[1], typestr) + " __a1 = " +
-        MangleName(FName, typestr, ClassS) + "(__b);\n  " +
-        "return __builtin_shufflevector(__a, __a1";
-    for (unsigned i = 0; i < nElts * 4; ++i)
-      s += ", " + utostr(i);
-    s += ");";
-    break;
-  }
-  case OpFcvtlHi: {
-    std::string FName = (nElts == 2) ? "vcvt_f64" : "vcvt_f32";
-    s = TypeString('d', typestr) + " __a1 = " + GetHigh("__a", typestr) +
-        ";\n  return " + MangleName(FName, typestr, ClassS) + "(__a1);";
-    break;
-  }
-  case OpFcvtxnHi: {
-    s = TypeString(proto[1], typestr) + " __a1 = " +
-        MangleName("vcvtx_f32", typestr, ClassS) + "(__b);\n  " +
-        "return __builtin_shufflevector(__a, __a1";
-    for (unsigned i = 0; i < nElts * 4; ++i)
-      s += ", " + utostr(i);
-    s += ");";
-    break;
-  }
-  case OpUzp1:
-    s += "__builtin_shufflevector(__a, __b";
-    for (unsigned i = 0; i < nElts; i++)
-      s += ", " + utostr(2*i);
-    s += ");";
-    break;
-  case OpUzp2:
-    s += "__builtin_shufflevector(__a, __b";
-    for (unsigned i = 0; i < nElts; i++)
-      s += ", " + utostr(2*i+1);
-    s += ");";
-    break;
-  case OpZip1:
-    s += "__builtin_shufflevector(__a, __b";
-    for (unsigned i = 0; i < (nElts/2); i++)
-       s += ", " + utostr(i) + ", " + utostr(i+nElts);
-    s += ");";
-    break;
-  case OpZip2:
-    s += "__builtin_shufflevector(__a, __b";
-    for (unsigned i = nElts/2; i < nElts; i++)
-       s += ", " + utostr(i) + ", " + utostr(i+nElts);
-    s += ");";
-    break;
-  case OpTrn1:
-    s += "__builtin_shufflevector(__a, __b";
-    for (unsigned i = 0; i < (nElts/2); i++)
-       s += ", " + utostr(2*i) + ", " + utostr(2*i+nElts);
-    s += ");";
-    break;
-  case OpTrn2:
-    s += "__builtin_shufflevector(__a, __b";
-    for (unsigned i = 0; i < (nElts/2); i++)
-       s += ", " + utostr(2*i+1) + ", " + utostr(2*i+1+nElts);
-    s += ");";
-    break;
-  case OpAbdl: {
-    std::string abd = MangleName("vabd", typestr, ClassS) + "(__a, __b)";
-    if (typestr[0] != 'U') {
-      // vabd results are always unsigned and must be zero-extended.
-      std::string utype = "U" + typestr.str();
-      s += "(" + TypeString(proto[0], typestr) + ")";
-      abd = "(" + TypeString('d', utype) + ")" + abd;
-      s += Extend(utype, abd) + ";";
-    } else {
-      s += Extend(typestr, abd) + ";";
-    }
-    break;
-  }
-  case OpAbdlHi:
-    s += Gen2OpWith2High(typestr, "vabdl", "__a", "__b");
-    break;
-  case OpAddhnHi: {
-    std::string addhn = MangleName("vaddhn", typestr, ClassS) + "(__b, __c)";
-    s += GenCombine(GetNarrowTypestr(typestr), "__a", addhn);
-    s += ";";
-    break;
-  }
-  case OpRAddhnHi: {
-    std::string raddhn = MangleName("vraddhn", typestr, ClassS) + "(__b, __c)";
-    s += GenCombine(GetNarrowTypestr(typestr), "__a", raddhn);
-    s += ";";
-    break;
-  }
-  case OpSubhnHi: {
-    std::string subhn = MangleName("vsubhn", typestr, ClassS) + "(__b, __c)";
-    s += GenCombine(GetNarrowTypestr(typestr), "__a", subhn);
-    s += ";";
-    break;
-  }
-  case OpRSubhnHi: {
-    std::string rsubhn = MangleName("vrsubhn", typestr, ClassS) + "(__b, __c)";
-    s += GenCombine(GetNarrowTypestr(typestr), "__a", rsubhn);
-    s += ";";
-    break;
-  }
-  case OpAba:
-    s += "__a + " + MangleName("vabd", typestr, ClassS) + "(__b, __c);";
-    break;
-  case OpAbal:
-    s += "__a + " + MangleName("vabdl", typestr, ClassS) + "(__b, __c);";
-    break;
-  case OpAbalHi:
-    s += Gen3OpWith2High(typestr, "vabal", "__a", "__b", "__c");
-    break;
-  case OpQDMullHi:
-    s += Gen2OpWith2High(typestr, "vqdmull", "__a", "__b");
-    break;
-  case OpQDMlalHi:
-    s += Gen3OpWith2High(typestr, "vqdmlal", "__a", "__b", "__c");
-    break;
-  case OpQDMlslHi:
-    s += Gen3OpWith2High(typestr, "vqdmlsl", "__a", "__b", "__c");
-    break;
-  case OpDiv:
-    s += "__a / __b;";
-    break;
-  case OpMovlHi: {
-    s = TypeString(proto[1], typestr.drop_front()) + " __a1 = " +
-        MangleName("vget_high", typestr, ClassS) + "(__a);\n  " + s;
-    s += "(" + ts + ")" + MangleName("vshll_n", typestr, ClassS);
-    s += "(__a1, 0);";
-    break;
-  }
-  case OpLongHi: {
-    // Another local variable __a1 is needed for calling a Macro,
-    // or using __a will have naming conflict when Macro expanding.
-    s += TypeString(proto[1], typestr.drop_front()) + " __a1 = " +
-         MangleName("vget_high", typestr, ClassS) + "(__a); \\\n";
-    s += "  (" + ts + ")" + MangleName(RemoveHigh(name), typestr, ClassS) +
-         "(__a1, __b);";
-    break;
-  }
-  case OpNarrowHi: {
-    s += "(" + ts + ")" + MangleName("vcombine", typestr, ClassS) + "(__a, " +
-         MangleName(RemoveHigh(name), typestr, ClassS) + "(__b, __c));";
-    break;
-  }
-  case OpCopyLane: {
-    s += TypeString('s', typestr) + " __c2 = " +
-         MangleName("vget_lane", typestr, ClassS) + "(__c1, __d1); \\\n  " +
-         MangleName("vset_lane", typestr, ClassS) + "(__c2, __a1, __b1);";
-    break;
-  }
-  case OpCopyQLane: {
-    std::string typeCode = "";
-    InstructionTypeCode(typestr, ClassS, quad, typeCode);
-    s += TypeString('s', typestr) + " __c2 = vget_lane_" + typeCode +
-         "(__c1, __d1); \\\n  vsetq_lane_" + typeCode + "(__c2, __a1, __b1);";
-    break;
-  }
-  case OpCopyLaneQ: {
-    std::string typeCode = "";
-    InstructionTypeCode(typestr, ClassS, quad, typeCode);
-    s += TypeString('s', typestr) + " __c2 = vgetq_lane_" + typeCode +
-         "(__c1, __d1); \\\n  vset_lane_" + typeCode + "(__c2, __a1, __b1);";
-    break;
-  }
-  case OpScalarMulLane: {
-    std::string typeCode = "";
-    InstructionTypeCode(typestr, ClassS, quad, typeCode);
-	s += TypeString('s', typestr) + " __d1 = vget_lane_" + typeCode +
-	  "(__b, __c);\\\n  __a * __d1;";
-    break;
-  }
-  case OpScalarMulLaneQ: {
-    std::string typeCode = "";
-    InstructionTypeCode(typestr, ClassS, quad, typeCode);
-        s += TypeString('s', typestr) + " __d1 = vgetq_lane_" + typeCode +
-          "(__b, __c);\\\n  __a * __d1;";
-    break;
-  }
-  case OpScalarMulXLane: {
-    bool dummy = false;
-    char type = ClassifyType(typestr, dummy, dummy, dummy);
-    if (type == 'f') type = 's';
-    std::string typeCode = "";
-    InstructionTypeCode(typestr, ClassS, quad, typeCode);
-    s += TypeString('s', typestr) + " __d1 = vget_lane_" + typeCode +
-      "(__b, __c);\\\n  vmulx" + type + "_" +
-      typeCode +  "(__a, __d1);";
-    break;
-  }
-  case OpScalarMulXLaneQ: {
-    bool dummy = false;
-    char type = ClassifyType(typestr, dummy, dummy, dummy);
-    if (type == 'f') type = 's';
-    std::string typeCode = "";
-    InstructionTypeCode(typestr, ClassS, quad, typeCode);
-    s += TypeString('s', typestr) + " __d1 = vgetq_lane_" +
-      typeCode + "(__b, __c);\\\n  vmulx" + type +
-      "_" + typeCode +  "(__a, __d1);";
-    break;
-  }
-
-  case OpScalarVMulXLane: {
-    bool dummy = false;
-    char type = ClassifyType(typestr, dummy, dummy, dummy);
-    if (type == 'f') type = 's';
-    std::string typeCode = "";
-    InstructionTypeCode(typestr, ClassS, quad, typeCode);
-    s += TypeString('s', typestr) + " __d1 = vget_lane_" +
-      typeCode + "(__a, 0);\\\n" +
-      "  " + TypeString('s', typestr) + " __e1 = vget_lane_" +
-      typeCode + "(__b, __c);\\\n" +
-      "  " + TypeString('s', typestr) + " __f1 = vmulx" + type + "_" +
-      typeCode + "(__d1, __e1);\\\n" +
-      "  " + TypeString('d', typestr) + " __g1;\\\n" +
-      "  vset_lane_" + typeCode + "(__f1, __g1, __c);";
-    break;
-  }
-
-  case OpScalarVMulXLaneQ: {
-    bool dummy = false;
-    char type = ClassifyType(typestr, dummy, dummy, dummy);
-    if (type == 'f') type = 's';
-    std::string typeCode = "";
-    InstructionTypeCode(typestr, ClassS, quad, typeCode);
-    s += TypeString('s', typestr) + " __d1 = vget_lane_" +
-      typeCode + "(__a, 0);\\\n" +
-      "  " + TypeString('s', typestr) + " __e1 = vgetq_lane_" +
-      typeCode + "(__b, __c);\\\n" +
-      "  " + TypeString('s', typestr) + " __f1 = vmulx" + type + "_" +
-      typeCode + "(__d1, __e1);\\\n" +
-      "  " + TypeString('d', typestr) + " __g1;\\\n" +
-      "  vset_lane_" + typeCode + "(__f1, __g1, 0);";
-    break;
-  }
-
-  default:
-    PrintFatalError("unknown OpKind!");
-  }
-  return s;
-}
-
-static unsigned GetNeonEnum(const std::string &proto, StringRef typestr) {
-  unsigned mod = proto[0];
-
-  if (mod == 'v' || mod == 'f')
-    mod = proto[1];
-
-  bool quad = false;
-  bool poly = false;
-  bool usgn = false;
-  bool scal = false;
-  bool cnst = false;
-  bool pntr = false;
-
-  // Base type to get the type string for.
-  char type = ClassifyType(typestr, quad, poly, usgn);
-
-  // Based on the modifying character, change the type and width if necessary.
-  type = ModType(mod, type, quad, poly, usgn, scal, cnst, pntr);
-
-  NeonTypeFlags::EltType ET;
-  switch (type) {
-    case 'c':
-      ET = poly ? NeonTypeFlags::Poly8 : NeonTypeFlags::Int8;
-      break;
-    case 's':
-      ET = poly ? NeonTypeFlags::Poly16 : NeonTypeFlags::Int16;
-      break;
-    case 'i':
-      ET = NeonTypeFlags::Int32;
-      break;
-    case 'l':
-      ET = poly ? NeonTypeFlags::Poly64 : NeonTypeFlags::Int64;
-      break;
-    case 'h':
-      ET = NeonTypeFlags::Float16;
-      break;
-    case 'f':
-      ET = NeonTypeFlags::Float32;
-      break;
-    case 'd':
-      ET = NeonTypeFlags::Float64;
-      break;
-    default:
-      PrintFatalError("unhandled type!");
-  }
-  NeonTypeFlags Flags(ET, usgn, quad && proto[1] != 'g');
-  return Flags.getFlags();
-}
-
-static bool ProtoHasScalar(const std::string proto)
-{
-  return (proto.find('s') != std::string::npos
-          || proto.find('r') != std::string::npos);
-}
-
-// Generate the definition for this intrinsic, e.g. __builtin_neon_cls(a)
-static std::string GenBuiltin(const std::string &name, const std::string &proto,
-                              StringRef typestr, ClassKind ck) {
-  std::string s;
-
-  // If this builtin returns a struct 2, 3, or 4 vectors, pass it as an implicit
-  // sret-like argument.
-  bool sret = IsMultiVecProto(proto[0]);
-
-  bool define = UseMacro(proto);
-
+std::string Intrinsic::getMangledName(bool ForceClassS) {
   // Check if the prototype has a scalar operand with the type of the vector
   // elements.  If not, bitcasting the args will take care of arg checking.
   // The actual signedness etc. will be taken care of with special enums.
-  if (!ProtoHasScalar(proto))
-    ck = ClassB;
+  ClassKind LocalCK = CK;
+  if (!protoHasScalar())
+    LocalCK = ClassB;
 
-  if (proto[0] != 'v') {
-    std::string ts = TypeString(proto[0], typestr);
+  return mangleName(Name, ForceClassS ? ClassS : LocalCK);
+}
 
-    if (define) {
-      if (sret)
-        s += ts + " r; ";
-      else
-        s += "(" + ts + ")";
-    } else if (sret) {
-      s += ts + " r; ";
-    } else {
-      s += "return (" + ts + ")";
+std::string Intrinsic::mangleName(std::string Name, ClassKind LocalCK) {
+  std::string typeCode = getInstTypeCode(BaseType, LocalCK);
+  std::string S = Name;
+
+  if (Name == "vcvt_f32_f16" || Name == "vcvt_f32_f64" ||
+      Name == "vcvt_f64_f32")
+    return Name;
+
+  if (typeCode.size() > 0) {
+    // If the name ends with _xN (N = 2,3,4), insert the typeCode before _xN.
+    if (Name.size() >= 3 && isdigit(Name.back()) &&
+        Name[Name.length() - 2] == 'x' && Name[Name.length() - 3] == '_')
+      S.insert(S.length() - 3, "_" + typeCode);
+    else
+      S += "_" + typeCode;
+  }
+
+  if (BaseType != InBaseType) {
+    // A reinterpret - out the input base type at the end.
+    S += "_" + getInstTypeCode(InBaseType, LocalCK);
+  }
+
+  if (LocalCK == ClassB)
+    S += "_v";
+
+  // Insert a 'q' before the first '_' character so that it ends up before
+  // _lane or _n on vector-scalar operations.
+  if (BaseType.getSizeInBits() == 128 && !BaseType.noManglingQ()) {
+    size_t Pos = S.find('_');
+    S.insert(Pos, "q");
+  }
+
+  char Suffix = '\0';
+  if (BaseType.isScalarForMangling()) {
+    switch (BaseType.getElementSizeInBits()) {
+    case 8: Suffix = 'b'; break;
+    case 16: Suffix = 'h'; break;
+    case 32: Suffix = 's'; break;
+    case 64: Suffix = 'd'; break;
+    default: llvm_unreachable("Bad suffix!");
     }
   }
-
-  bool splat = proto.find('a') != std::string::npos;
-
-  s += "__builtin_neon_";
-  if (splat) {
-    // Call the non-splat builtin: chop off the "_n" suffix from the name.
-    std::string vname(name, 0, name.size()-2);
-    s += MangleName(vname, typestr, ck);
-  } else {
-    s += MangleName(name, typestr, ck);
+  if (Suffix != '\0') {
+    size_t Pos = S.find('_');
+    S.insert(Pos, &Suffix, 1);
   }
-  s += "(";
 
-  // Pass the address of the return variable as the first argument to sret-like
-  // builtins.
-  if (sret)
-    s += "&r, ";
+  return S;
+}
 
-  char arg = 'a';
-  for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) {
-    std::string args = std::string(&arg, 1);
+std::string Intrinsic::replaceParamsIn(std::string S) {
+  while (S.find('$') != std::string::npos) {
+    size_t Pos = S.find('$');
+    size_t End = Pos + 1;
+    while (isalpha(S[End]))
+      ++End;
 
-    // Use the local temporaries instead of the macro arguments.
-    args = "__" + args;
+    std::string VarName = S.substr(Pos + 1, End - Pos - 1);
+    assert_with_loc(Variables.find(VarName) != Variables.end(),
+                    "Variable not defined!");
+    S.replace(Pos, End - Pos, Variables.find(VarName)->second.getName());
+  }
 
-    bool argQuad = false;
-    bool argPoly = false;
-    bool argUsgn = false;
-    bool argScalar = false;
-    bool dummy = false;
-    char argType = ClassifyType(typestr, argQuad, argPoly, argUsgn);
-    argType = ModType(proto[i], argType, argQuad, argPoly, argUsgn, argScalar,
-                      dummy, dummy);
+  return S;
+}
+
+void Intrinsic::initVariables() {
+  Variables.clear();
+
+  // Modify the TypeSpec per-argument to get a concrete Type, and create
+  // known variables for each.
+  for (unsigned I = 1; I < Proto.size(); ++I) {
+    char NameC = '0' + (I - 1);
+    std::string Name = "p";
+    Name.push_back(NameC);
+
+    Variables[Name] = Variable(Types[I], Name + VariablePostfix);
+  }
+  RetVar = Variable(Types[0], "ret" + VariablePostfix);
+}
+
+void Intrinsic::emitPrototype(StringRef NamePrefix) {
+  if (UseMacro)
+    OS << "#define ";
+  else
+    OS << "__ai " << Types[0].str() << " ";
+
+  OS << NamePrefix.str() << mangleName(Name, ClassS) << "(";
+
+  for (unsigned I = 0; I < getNumParams(); ++I) {
+    if (I != 0)
+      OS << ", ";
+
+    char NameC = '0' + I;
+    std::string Name = "p";
+    Name.push_back(NameC);
+    assert(Variables.find(Name) != Variables.end());
+    Variable &V = Variables[Name];
+
+    if (!UseMacro)
+      OS << V.getType().str() << " ";
+    OS << V.getName();
+  }
+
+  OS << ")";
+}
+
+void Intrinsic::emitOpeningBrace() {
+  if (UseMacro)
+    OS << " __extension__ ({";
+  else
+    OS << " {";
+  emitNewLine();
+}
+
+void Intrinsic::emitClosingBrace() {
+  if (UseMacro)
+    OS << "})";
+  else
+    OS << "}";
+}
+
+void Intrinsic::emitNewLine() {
+  if (UseMacro)
+    OS << " \\\n";
+  else
+    OS << "\n";
+}
+
+void Intrinsic::emitReverseVariable(Variable &Dest, Variable &Src) {
+  if (Dest.getType().getNumVectors() > 1) {
+    emitNewLine();
+
+    for (unsigned K = 0; K < Dest.getType().getNumVectors(); ++K) {
+      OS << "  " << Dest.getName() << ".val[" << utostr(K) << "] = "
+         << "__builtin_shufflevector("
+         << Src.getName() << ".val[" << utostr(K) << "], "
+         << Src.getName() << ".val[" << utostr(K) << "]";
+      for (int J = Dest.getType().getNumElements() - 1; J >= 0; --J)
+        OS << ", " << utostr(J);
+      OS << ");";
+      emitNewLine();
+    }
+  } else {
+    OS << "  " << Dest.getName()
+       << " = __builtin_shufflevector(" << Src.getName() << ", " << Src.getName();
+    for (int J = Dest.getType().getNumElements() - 1; J >= 0; --J)
+      OS << ", " << utostr(J);
+    OS << ");";
+    emitNewLine();
+  }
+}
+
+void Intrinsic::emitArgumentReversal() {
+  if (BigEndianSafe)
+    return;
+
+  // Reverse all vector arguments.
+  for (unsigned I = 0; I < getNumParams(); ++I) {
+    std::string Name = "p" + utostr(I);
+    std::string NewName = "rev" + utostr(I);
+
+    Variable &V = Variables[Name];
+    Variable NewV(V.getType(), NewName + VariablePostfix);
+
+    if (!NewV.getType().isVector() || NewV.getType().getNumElements() == 1)
+      continue;
+
+    OS << "  " << NewV.getType().str() << " " << NewV.getName() << ";";
+    emitReverseVariable(NewV, V);
+    V = NewV;
+  }
+}
+
+void Intrinsic::emitReturnReversal() {
+  if (BigEndianSafe)
+    return;
+  if (!getReturnType().isVector() || getReturnType().isVoid() ||
+      getReturnType().getNumElements() == 1)
+    return;
+  emitReverseVariable(RetVar, RetVar);
+}
+
+
+void Intrinsic::emitShadowedArgs() {
+  // Macro arguments are not type-checked like inline function arguments,
+  // so assign them to local temporaries to get the right type checking.
+  if (!UseMacro)
+    return;
+
+  for (unsigned I = 0; I < getNumParams(); ++I) {
+    // Do not create a temporary for an immediate argument.
+    // That would defeat the whole point of using a macro!
+    if (hasImmediate() && Proto[I+1] == 'i')
+      continue;
+    // Do not create a temporary for pointer arguments. The input
+    // pointer may have an alignment hint.
+    if (getParamType(I).isPointer())
+      continue;
+
+    std::string Name = "p" + utostr(I);
+
+    assert(Variables.find(Name) != Variables.end());
+    Variable &V = Variables[Name];
+
+    std::string NewName = "s" + utostr(I);
+    Variable V2(V.getType(), NewName + VariablePostfix);
+
+    OS << "  " << V2.getType().str() << " " << V2.getName() << " = "
+       << V.getName() << ";";
+    emitNewLine();
+
+    V = V2;
+  }
+}
+
+// We don't check 'a' in this function, because for builtin function the
+// argument matching to 'a' uses a vector type splatted from a scalar type.
+bool Intrinsic::protoHasScalar() {
+  return (Proto.find('s') != std::string::npos ||
+          Proto.find('z') != std::string::npos ||
+          Proto.find('r') != std::string::npos ||
+          Proto.find('b') != std::string::npos ||
+          Proto.find('$') != std::string::npos ||
+          Proto.find('y') != std::string::npos ||
+          Proto.find('o') != std::string::npos);
+}
+
+void Intrinsic::emitBodyAsBuiltinCall() {
+  std::string S;
+
+  // If this builtin returns a struct 2, 3, or 4 vectors, pass it as an implicit
+  // sret-like argument.
+  bool SRet = getReturnType().getNumVectors() >= 2;
+
+  StringRef N = Name;
+  if (hasSplat()) {
+    // Call the non-splat builtin: chop off the "_n" suffix from the name.
+    assert(N.endswith("_n"));
+    N = N.drop_back(2);
+  }
+
+  ClassKind LocalCK = CK;
+  if (!protoHasScalar())
+    LocalCK = ClassB;
+
+  if (!getReturnType().isVoid() && !SRet)
+    S += "(" + RetVar.getType().str() + ") ";
+
+  S += "__builtin_neon_" + mangleName(N, LocalCK) + "(";
+
+  if (SRet)
+    S += "&" + RetVar.getName() + ", ";
+
+  for (unsigned I = 0; I < getNumParams(); ++I) {
+    Variable &V = Variables["p" + utostr(I)];
+    Type T = V.getType();
 
     // Handle multiple-vector values specially, emitting each subvector as an
-    // argument to the __builtin.
-    unsigned NumOfVec = 0;
-    if (proto[i] >= '2' && proto[i] <= '4') {
-      NumOfVec = proto[i] - '0';
-    } else if (proto[i] >= 'B' && proto[i] <= 'D') {
-      NumOfVec = proto[i] - 'A' + 1;
-    }
-    
-    if (NumOfVec > 0) {
+    // argument to the builtin.
+    if (T.getNumVectors() > 1) {
       // Check if an explicit cast is needed.
-      if (argType != 'c' || argPoly || argUsgn)
-        args = (argQuad ? "(int8x16_t)" : "(int8x8_t)") + args;
-
-      for (unsigned vi = 0, ve = NumOfVec; vi != ve; ++vi) {
-        s += args + ".val[" + utostr(vi) + "]";
-        if ((vi + 1) < ve)
-          s += ", ";
+      std::string Cast;
+      if (T.isChar() || T.isPoly() || !T.isSigned()) {
+        Type T2 = T;
+        T2.makeOneVector();
+        T2.makeInteger(8, /*Signed=*/true);
+        Cast = "(" + T2.str() + ")";
       }
-      if ((i + 1) < e)
-        s += ", ";
 
+      for (unsigned J = 0; J < T.getNumVectors(); ++J)
+        S += Cast + V.getName() + ".val[" + utostr(J) + "], ";
       continue;
     }
 
-    if (splat && (i + 1) == e)
-      args = Duplicate(GetNumElements(typestr, argQuad), typestr, args);
+    std::string Arg;
+    Type CastToType = T;
+    if (hasSplat() && I == getSplatIdx()) {
+      Arg = "(" + BaseType.str() + ") {";
+      for (unsigned J = 0; J < BaseType.getNumElements(); ++J) {
+        if (J != 0)
+          Arg += ", ";
+        Arg += V.getName();
+      }
+      Arg += "}";
 
-    // Check if an explicit cast is needed.
-    if ((splat || !argScalar) &&
-        ((ck == ClassB && argType != 'c') || argPoly || argUsgn)) {
-      std::string argTypeStr = "c";
-      if (ck != ClassB)
-        argTypeStr = argType;
-      if (argQuad)
-        argTypeStr = "Q" + argTypeStr;
-      args = "(" + TypeString('d', argTypeStr) + ")" + args;
+      CastToType = BaseType;
+    } else {
+      Arg = V.getName();
     }
 
-    s += args;
-    if ((i + 1) < e)
-      s += ", ";
+    // Check if an explicit cast is needed.
+    if (CastToType.isVector()) {
+      CastToType.makeInteger(8, true);
+      Arg = "(" + CastToType.str() + ")" + Arg;
+    }
+
+    S += Arg + ", ";
   }
 
   // Extra constant integer to hold type class enum for this function, e.g. s8
-  if (ck == ClassB)
-    s += ", " + utostr(GetNeonEnum(proto, typestr));
+  if (getClassKind(true) == ClassB) {
+    Type ThisTy = getReturnType();
+    if (Proto[0] == 'v' || Proto[0] == 'f' || Proto[0] == 'F')
+      ThisTy = getParamType(0);
+    if (ThisTy.isPointer())
+      ThisTy = getParamType(1);
 
-  s += ");";
-
-  if (proto[0] != 'v' && sret) {
-    if (define)
-      s += " r;";
-    else
-      s += " return r;";
+    S += utostr(ThisTy.getNeonEnum());
+  } else {
+    // Remove extraneous ", ".
+    S.pop_back();
+    S.pop_back();
   }
-  return s;
+  S += ");";
+
+  std::string RetExpr;
+  if (!SRet && !RetVar.getType().isVoid())
+    RetExpr = RetVar.getName() + " = ";
+
+  OS << "  " << RetExpr << S;
+  emitNewLine();
 }
 
-static std::string GenBuiltinDef(const std::string &name,
-                                 const std::string &proto,
-                                 StringRef typestr, ClassKind ck) {
-  std::string s("BUILTIN(__builtin_neon_");
+void Intrinsic::emitBody(StringRef CallPrefix) {
+  std::vector<std::string> Lines;
 
-  // If all types are the same size, bitcasting the args will take care
-  // of arg checking.  The actual signedness etc. will be taken care of with
-  // special enums.
-  if (!ProtoHasScalar(proto))
-    ck = ClassB;
+  assert(RetVar.getType() == Types[0]);
+  // Create a return variable, if we're not void.
+  if (!RetVar.getType().isVoid()) {
+    OS << "  " << RetVar.getType().str() << " " << RetVar.getName() << ";";
+    emitNewLine();
+  }
 
-  s += MangleName(name, typestr, ck);
-  s += ", \"";
+  if (!Body || Body->getValues().size() == 0) {
+    // Nothing specific to output - must output a builtin.
+    emitBodyAsBuiltinCall();
+    return;
+  }
 
-  for (unsigned i = 0, e = proto.size(); i != e; ++i)
-    s += BuiltinTypeString(proto[i], typestr, ck, i == 0);
+  // We have a list of "things to output". The last should be returned.
+  for (auto *I : Body->getValues()) {
+    if (StringInit *SI = dyn_cast<StringInit>(I)) {
+      Lines.push_back(replaceParamsIn(SI->getAsString()));
+    } else if (DagInit *DI = dyn_cast<DagInit>(I)) {
+      DagEmitter DE(*this, CallPrefix);
+      Lines.push_back(DE.emitDag(DI).second + ";");
+    }
+  }
 
-  // Extra constant integer to hold type class enum for this function, e.g. s8
-  if (ck == ClassB)
-    s += "i";
+  assert(Lines.size() && "Empty def?");
+  if (!RetVar.getType().isVoid())
+    Lines.back().insert(0, RetVar.getName() + " = ");
 
-  s += "\", \"n\")";
-  return s;
+  for (auto &L : Lines) {
+    OS << "  " << L;
+    emitNewLine();
+  }
 }
 
-static std::string GenIntrinsic(const std::string &name,
-                                const std::string &proto,
-                                StringRef outTypeStr, StringRef inTypeStr,
-                                OpKind kind, ClassKind classKind) {
-  assert(!proto.empty() && "");
-  bool define = UseMacro(proto) && kind != OpUnavailable;
-  std::string s;
-
-  // static always inline + return type
-  if (define)
-    s += "#define ";
+void Intrinsic::emitReturn() {
+  if (RetVar.getType().isVoid())
+    return;
+  if (UseMacro)
+    OS << "  " << RetVar.getName() << ";";
   else
-    s += "__ai " + TypeString(proto[0], outTypeStr) + " ";
+    OS << "  return " << RetVar.getName() << ";";
+  emitNewLine();
+}
 
-  // Function name with type suffix
-  std::string mangledName = MangleName(name, outTypeStr, ClassS);
-  if (outTypeStr != inTypeStr) {
-    // If the input type is different (e.g., for vreinterpret), append a suffix
-    // for the input type.  String off a "Q" (quad) prefix so that MangleName
-    // does not insert another "q" in the name.
-    unsigned typeStrOff = (inTypeStr[0] == 'Q' ? 1 : 0);
-    StringRef inTypeNoQuad = inTypeStr.substr(typeStrOff);
-    mangledName = MangleName(mangledName, inTypeNoQuad, ClassS);
+std::pair<Type, std::string> Intrinsic::DagEmitter::emitDag(DagInit *DI) {
+  // At this point we should only be seeing a def.
+  DefInit *DefI = cast<DefInit>(DI->getOperator());
+  std::string Op = DefI->getAsString();
+
+  if (Op == "cast" || Op == "bitcast")
+    return emitDagCast(DI, Op == "bitcast");
+  if (Op == "shuffle")
+    return emitDagShuffle(DI);
+  if (Op == "dup")
+    return emitDagDup(DI);
+  if (Op == "splat")
+    return emitDagSplat(DI);
+  if (Op == "save_temp")
+    return emitDagSaveTemp(DI);
+  if (Op == "op")
+    return emitDagOp(DI);
+  if (Op == "call")
+    return emitDagCall(DI);
+  if (Op == "name_replace")
+    return emitDagNameReplace(DI);
+  if (Op == "literal")
+    return emitDagLiteral(DI);
+  assert_with_loc(false, "Unknown operation!");
+  return std::make_pair(Type::getVoid(), "");
+}
+
+std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagOp(DagInit *DI) {
+  std::string Op = cast<StringInit>(DI->getArg(0))->getAsUnquotedString();
+  if (DI->getNumArgs() == 2) {
+    // Unary op.
+    std::pair<Type, std::string> R =
+        emitDagArg(DI->getArg(1), DI->getArgName(1));
+    return std::make_pair(R.first, Op + R.second);
+  } else {
+    assert(DI->getNumArgs() == 3 && "Can only handle unary and binary ops!");
+    std::pair<Type, std::string> R1 =
+        emitDagArg(DI->getArg(1), DI->getArgName(1));
+    std::pair<Type, std::string> R2 =
+        emitDagArg(DI->getArg(2), DI->getArgName(2));
+    assert_with_loc(R1.first == R2.first, "Argument type mismatch!");
+    return std::make_pair(R1.first, R1.second + " " + Op + " " + R2.second);
   }
-  s += mangledName;
+}
 
-  // Function arguments
-  s += GenArgs(proto, inTypeStr, name);
+std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagCall(DagInit *DI) {
+  std::vector<Type> Types;
+  std::vector<std::string> Values;
+  for (unsigned I = 0; I < DI->getNumArgs() - 1; ++I) {
+    std::pair<Type, std::string> R =
+        emitDagArg(DI->getArg(I + 1), DI->getArgName(I + 1));
+    Types.push_back(R.first);
+    Values.push_back(R.second);
+  }
 
-  // Definition.
-  if (define) {
-    s += " __extension__ ({ \\\n  ";
-    s += GenMacroLocals(proto, inTypeStr, name);
-  } else if (kind == OpUnavailable) {
-    s += " __attribute__((unavailable));\n";
-    return s;
-  } else
-    s += " {\n  ";
-
-  if (kind != OpNone)
-    s += GenOpString(name, kind, proto, outTypeStr);
+  // Look up the called intrinsic.
+  std::string N;
+  if (StringInit *SI = dyn_cast<StringInit>(DI->getArg(0)))
+    N = SI->getAsUnquotedString();
   else
-    s += GenBuiltin(name, proto, outTypeStr, classKind);
-  if (define)
-    s += " })";
-  else
-    s += " }";
-  s += "\n";
-  return s;
+    N = emitDagArg(DI->getArg(0), "").second;
+  Intrinsic *Callee = Intr.Emitter.getIntrinsic(N, Types);
+  assert(Callee && "getIntrinsic should not return us nullptr!");
+
+  // Make sure the callee is known as an early def.
+  Callee->setNeededEarly();
+  Intr.Dependencies.insert(Callee);
+
+  // Now create the call itself.
+  std::string S = CallPrefix.str() + Callee->getMangledName(true) + "(";
+  for (unsigned I = 0; I < DI->getNumArgs() - 1; ++I) {
+    if (I != 0)
+      S += ", ";
+    S += Values[I];
+  }
+  S += ")";
+
+  return std::make_pair(Callee->getReturnType(), S);
+}
+
+std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagCast(DagInit *DI,
+                                                                bool IsBitCast){
+  // (cast MOD* VAL) -> cast VAL to type given by MOD.
+  std::pair<Type, std::string> R = emitDagArg(
+      DI->getArg(DI->getNumArgs() - 1), DI->getArgName(DI->getNumArgs() - 1));
+  Type castToType = R.first;
+  for (unsigned ArgIdx = 0; ArgIdx < DI->getNumArgs() - 1; ++ArgIdx) {
+
+    // MOD can take several forms:
+    //   1. $X - take the type of parameter / variable X.
+    //   2. The value "R" - take the type of the return type.
+    //   3. a type string
+    //   4. The value "U" or "S" to switch the signedness.
+    //   5. The value "H" or "D" to half or double the bitwidth.
+    //   6. The value "8" to convert to 8-bit (signed) integer lanes.
+    if (DI->getArgName(ArgIdx).size()) {
+      assert_with_loc(Intr.Variables.find(DI->getArgName(ArgIdx)) !=
+                      Intr.Variables.end(),
+                      "Variable not found");
+      castToType = Intr.Variables[DI->getArgName(ArgIdx)].getType();
+    } else {
+      StringInit *SI = dyn_cast<StringInit>(DI->getArg(ArgIdx));
+      assert_with_loc(SI, "Expected string type or $Name for cast type");
+
+      if (SI->getAsUnquotedString() == "R") {
+        castToType = Intr.getReturnType();
+      } else if (SI->getAsUnquotedString() == "U") {
+        castToType.makeUnsigned();
+      } else if (SI->getAsUnquotedString() == "S") {
+        castToType.makeSigned();
+      } else if (SI->getAsUnquotedString() == "H") {
+        castToType.halveLanes();
+      } else if (SI->getAsUnquotedString() == "D") {
+        castToType.doubleLanes();
+      } else if (SI->getAsUnquotedString() == "8") {
+        castToType.makeInteger(8, true);
+      } else {
+        castToType = Type::fromTypedefName(SI->getAsUnquotedString());
+        assert_with_loc(!castToType.isVoid(), "Unknown typedef");
+      }
+    }
+  }
+
+  std::string S;
+  if (IsBitCast) {
+    // Emit a reinterpret cast. The second operand must be an lvalue, so create
+    // a temporary.
+    std::string N = "reint";
+    unsigned I = 0;
+    while (Intr.Variables.find(N) != Intr.Variables.end())
+      N = "reint" + utostr(++I);
+    Intr.Variables[N] = Variable(R.first, N + Intr.VariablePostfix);
+
+    Intr.OS << R.first.str() << " " << Intr.Variables[N].getName() << " = "
+            << R.second << ";";
+    Intr.emitNewLine();
+
+    S = "*(" + castToType.str() + " *) &" + Intr.Variables[N].getName() + "";
+  } else {
+    // Emit a normal (static) cast.
+    S = "(" + castToType.str() + ")(" + R.second + ")";
+  }
+
+  return std::make_pair(castToType, S);
+}
+
+std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagShuffle(DagInit *DI){
+  // See the documentation in arm_neon.td for a description of these operators.
+  class LowHalf : public SetTheory::Operator {
+  public:
+    virtual void anchor() {}
+    virtual ~LowHalf() {}
+    virtual void apply(SetTheory &ST, DagInit *Expr, SetTheory::RecSet &Elts,
+                       ArrayRef<SMLoc> Loc) {
+      SetTheory::RecSet Elts2;
+      ST.evaluate(Expr->arg_begin(), Expr->arg_end(), Elts2, Loc);
+      Elts.insert(Elts2.begin(), Elts2.begin() + (Elts2.size() / 2));
+    }
+  };
+  class HighHalf : public SetTheory::Operator {
+  public:
+    virtual void anchor() {}
+    virtual ~HighHalf() {}
+    virtual void apply(SetTheory &ST, DagInit *Expr, SetTheory::RecSet &Elts,
+                       ArrayRef<SMLoc> Loc) {
+      SetTheory::RecSet Elts2;
+      ST.evaluate(Expr->arg_begin(), Expr->arg_end(), Elts2, Loc);
+      Elts.insert(Elts2.begin() + (Elts2.size() / 2), Elts2.end());
+    }
+  };
+  class Rev : public SetTheory::Operator {
+    unsigned ElementSize;
+
+  public:
+    Rev(unsigned ElementSize) : ElementSize(ElementSize) {}
+    virtual void anchor() {}
+    virtual ~Rev() {}
+    virtual void apply(SetTheory &ST, DagInit *Expr, SetTheory::RecSet &Elts,
+                       ArrayRef<SMLoc> Loc) {
+      SetTheory::RecSet Elts2;
+      ST.evaluate(Expr->arg_begin() + 1, Expr->arg_end(), Elts2, Loc);
+
+      int64_t VectorSize = cast<IntInit>(Expr->getArg(0))->getValue();
+      VectorSize /= ElementSize;
+
+      std::vector<Record *> Revved;
+      for (unsigned VI = 0; VI < Elts2.size(); VI += VectorSize) {
+        for (int LI = VectorSize - 1; LI >= 0; --LI) {
+          Revved.push_back(Elts2[VI + LI]);
+        }
+      }
+
+      Elts.insert(Revved.begin(), Revved.end());
+    }
+  };
+  class MaskExpander : public SetTheory::Expander {
+    unsigned N;
+
+  public:
+    MaskExpander(unsigned N) : N(N) {}
+    virtual void anchor() {}
+    virtual ~MaskExpander() {}
+    virtual void expand(SetTheory &ST, Record *R, SetTheory::RecSet &Elts) {
+      unsigned Addend = 0;
+      if (R->getName() == "mask0")
+        Addend = 0;
+      else if (R->getName() == "mask1")
+        Addend = N;
+      else
+        return;
+      for (unsigned I = 0; I < N; ++I)
+        Elts.insert(R->getRecords().getDef("sv" + utostr(I + Addend)));
+    }
+  };
+
+  // (shuffle arg1, arg2, sequence)
+  std::pair<Type, std::string> Arg1 =
+      emitDagArg(DI->getArg(0), DI->getArgName(0));
+  std::pair<Type, std::string> Arg2 =
+      emitDagArg(DI->getArg(1), DI->getArgName(1));
+  assert_with_loc(Arg1.first == Arg2.first,
+                  "Different types in arguments to shuffle!");
+
+  SetTheory ST;
+  LowHalf LH;
+  HighHalf HH;
+  MaskExpander ME(Arg1.first.getNumElements());
+  Rev R(Arg1.first.getElementSizeInBits());
+  SetTheory::RecSet Elts;
+  ST.addOperator("lowhalf", &LH);
+  ST.addOperator("highhalf", &HH);
+  ST.addOperator("rev", &R);
+  ST.addExpander("MaskExpand", &ME);
+  ST.evaluate(DI->getArg(2), Elts, ArrayRef<SMLoc>());
+
+  std::string S = "__builtin_shufflevector(" + Arg1.second + ", " + Arg2.second;
+  for (auto &E : Elts) {
+    StringRef Name = E->getName();
+    assert_with_loc(Name.startswith("sv"),
+                    "Incorrect element kind in shuffle mask!");
+    S += ", " + Name.drop_front(2).str();
+  }
+  S += ")";
+
+  // Recalculate the return type - the shuffle may have halved or doubled it.
+  Type T(Arg1.first);
+  if (Elts.size() > T.getNumElements()) {
+    assert_with_loc(
+        Elts.size() == T.getNumElements() * 2,
+        "Can only double or half the number of elements in a shuffle!");
+    T.doubleLanes();
+  } else if (Elts.size() < T.getNumElements()) {
+    assert_with_loc(
+        Elts.size() == T.getNumElements() / 2,
+        "Can only double or half the number of elements in a shuffle!");
+    T.halveLanes();
+  }
+
+  return std::make_pair(T, S);
+}
+
+std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagDup(DagInit *DI) {
+  assert_with_loc(DI->getNumArgs() == 1, "dup() expects one argument");
+  std::pair<Type, std::string> A = emitDagArg(DI->getArg(0), DI->getArgName(0));
+  assert_with_loc(A.first.isScalar(), "dup() expects a scalar argument");
+
+  Type T = Intr.getBaseType();
+  assert_with_loc(T.isVector(), "dup() used but default type is scalar!");
+  std::string S = "(" + T.str() + ") {";
+  for (unsigned I = 0; I < T.getNumElements(); ++I) {
+    if (I != 0)
+      S += ", ";
+    S += A.second;
+  }
+  S += "}";
+
+  return std::make_pair(T, S);
+}
+
+std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagSplat(DagInit *DI) {
+  assert_with_loc(DI->getNumArgs() == 2, "splat() expects two arguments");
+  std::pair<Type, std::string> A = emitDagArg(DI->getArg(0), DI->getArgName(0));
+  std::pair<Type, std::string> B = emitDagArg(DI->getArg(1), DI->getArgName(1));
+
+  assert_with_loc(B.first.isScalar(),
+                  "splat() requires a scalar int as the second argument");
+
+  std::string S = "__builtin_shufflevector(" + A.second + ", " + A.second;
+  for (unsigned I = 0; I < Intr.getBaseType().getNumElements(); ++I) {
+    S += ", " + B.second;
+  }
+  S += ")";
+
+  return std::make_pair(Intr.getBaseType(), S);
+}
+
+std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagSaveTemp(DagInit *DI) {
+  assert_with_loc(DI->getNumArgs() == 2, "save_temp() expects two arguments");
+  std::pair<Type, std::string> A = emitDagArg(DI->getArg(1), DI->getArgName(1));
+
+  assert_with_loc(!A.first.isVoid(),
+                  "Argument to save_temp() must have non-void type!");
+
+  std::string N = DI->getArgName(0);
+  assert_with_loc(N.size(), "save_temp() expects a name as the first argument");
+
+  assert_with_loc(Intr.Variables.find(N) == Intr.Variables.end(),
+                  "Variable already defined!");
+  Intr.Variables[N] = Variable(A.first, N + Intr.VariablePostfix);
+
+  std::string S =
+      A.first.str() + " " + Intr.Variables[N].getName() + " = " + A.second;
+
+  return std::make_pair(Type::getVoid(), S);
+}
+
+std::pair<Type, std::string>
+Intrinsic::DagEmitter::emitDagNameReplace(DagInit *DI) {
+  std::string S = Intr.Name;
+
+  assert_with_loc(DI->getNumArgs() == 2, "name_replace requires 2 arguments!");
+  std::string ToReplace = cast<StringInit>(DI->getArg(0))->getAsUnquotedString();
+  std::string ReplaceWith = cast<StringInit>(DI->getArg(1))->getAsUnquotedString();
+
+  size_t Idx = S.find(ToReplace);
+
+  assert_with_loc(Idx != std::string::npos, "name should contain '" + ToReplace + "'!");
+  S.replace(Idx, ToReplace.size(), ReplaceWith);
+
+  return std::make_pair(Type::getVoid(), S);
+}
+
+std::pair<Type, std::string> Intrinsic::DagEmitter::emitDagLiteral(DagInit *DI){
+  std::string Ty = cast<StringInit>(DI->getArg(0))->getAsUnquotedString();
+  std::string Value = cast<StringInit>(DI->getArg(1))->getAsUnquotedString();
+  return std::make_pair(Type::fromTypedefName(Ty), Value);
+}
+
+std::pair<Type, std::string>
+Intrinsic::DagEmitter::emitDagArg(Init *Arg, std::string ArgName) {
+  if (ArgName.size()) {
+    assert_with_loc(!Arg->isComplete(),
+                    "Arguments must either be DAGs or names, not both!");
+    assert_with_loc(Intr.Variables.find(ArgName) != Intr.Variables.end(),
+                    "Variable not defined!");
+    Variable &V = Intr.Variables[ArgName];
+    return std::make_pair(V.getType(), V.getName());
+  }
+
+  assert(Arg && "Neither ArgName nor Arg?!");
+  DagInit *DI = dyn_cast<DagInit>(Arg);
+  assert_with_loc(DI, "Arguments must either be DAGs or names!");
+
+  return emitDag(DI);
+}
+
+std::string Intrinsic::generate() {
+  // Little endian intrinsics are simple and don't require any argument
+  // swapping.
+  OS << "#ifdef __LITTLE_ENDIAN__\n";
+
+  generateImpl(false, "", "");
+
+  OS << "#else\n";
+
+  // Big endian intrinsics are more complex. The user intended these
+  // intrinsics to operate on a vector "as-if" loaded by (V)LDR,
+  // but we load as-if (V)LD1. So we should swap all arguments and
+  // swap the return value too.
+  //
+  // If we call sub-intrinsics, we should call a version that does
+  // not re-swap the arguments!
+  generateImpl(true, "", "__noswap_");
+
+  // If we're needed early, create a non-swapping variant for
+  // big-endian.
+  if (NeededEarly) {
+    generateImpl(false, "__noswap_", "__noswap_");
+  }
+  OS << "#endif\n\n";
+
+  return OS.str();
+}
+
+void Intrinsic::generateImpl(bool ReverseArguments,
+                             StringRef NamePrefix, StringRef CallPrefix) {
+  CurrentRecord = R;
+
+  // If we call a macro, our local variables may be corrupted due to
+  // lack of proper lexical scoping. So, add a globally unique postfix
+  // to every variable.
+  //
+  // indexBody() should have set up the Dependencies set by now.
+  for (auto *I : Dependencies)
+    if (I->UseMacro) {
+      VariablePostfix = "_" + utostr(Emitter.getUniqueNumber());
+      break;
+    }
+
+  initVariables();
+
+  emitPrototype(NamePrefix);
+
+  if (IsUnavailable) {
+    OS << " __attribute__((unavailable));";
+  } else {
+    emitOpeningBrace();
+    emitShadowedArgs();
+    if (ReverseArguments)
+      emitArgumentReversal();
+    emitBody(CallPrefix);
+    if (ReverseArguments)
+      emitReturnReversal();
+    emitReturn();
+    emitClosingBrace();
+  }
+  OS << "\n";
+
+  CurrentRecord = nullptr;
+}
+
+void Intrinsic::indexBody() {
+  CurrentRecord = R;
+
+  initVariables();
+  emitBody("");
+  OS.str("");
+
+  CurrentRecord = nullptr;
+}
+
+//===----------------------------------------------------------------------===//
+// NeonEmitter implementation
+//===----------------------------------------------------------------------===//
+
+Intrinsic *NeonEmitter::getIntrinsic(StringRef Name, ArrayRef<Type> Types) {
+  // First, look up the name in the intrinsic map.
+  assert_with_loc(IntrinsicMap.find(Name.str()) != IntrinsicMap.end(),
+                  ("Intrinsic '" + Name + "' not found!").str());
+  std::vector<Intrinsic *> &V = IntrinsicMap[Name.str()];
+  std::vector<Intrinsic *> GoodVec;
+
+  // Create a string to print if we end up failing.
+  std::string ErrMsg = "looking up intrinsic '" + Name.str() + "(";
+  for (unsigned I = 0; I < Types.size(); ++I) {
+    if (I != 0)
+      ErrMsg += ", ";
+    ErrMsg += Types[I].str();
+  }
+  ErrMsg += ")'\n";
+  ErrMsg += "Available overloads:\n";
+
+  // Now, look through each intrinsic implementation and see if the types are
+  // compatible.
+  for (auto *I : V) {
+    ErrMsg += "  - " + I->getReturnType().str() + " " + I->getMangledName();
+    ErrMsg += "(";
+    for (unsigned A = 0; A < I->getNumParams(); ++A) {
+      if (A != 0)
+        ErrMsg += ", ";
+      ErrMsg += I->getParamType(A).str();
+    }
+    ErrMsg += ")\n";
+
+    if (I->getNumParams() != Types.size())
+      continue;
+
+    bool Good = true;
+    for (unsigned Arg = 0; Arg < Types.size(); ++Arg) {
+      if (I->getParamType(Arg) != Types[Arg]) {
+        Good = false;
+        break;
+      }
+    }
+    if (Good)
+      GoodVec.push_back(I);
+  }
+
+  assert_with_loc(GoodVec.size() > 0,
+                  "No compatible intrinsic found - " + ErrMsg);
+  assert_with_loc(GoodVec.size() == 1, "Multiple overloads found - " + ErrMsg);
+
+  return GoodVec.front();
+}
+
+void NeonEmitter::createIntrinsic(Record *R,
+                                  SmallVectorImpl<Intrinsic *> &Out) {
+  std::string Name = R->getValueAsString("Name");
+  std::string Proto = R->getValueAsString("Prototype");
+  std::string Types = R->getValueAsString("Types");
+  Record *OperationRec = R->getValueAsDef("Operation");
+  bool CartesianProductOfTypes = R->getValueAsBit("CartesianProductOfTypes");
+  bool BigEndianSafe  = R->getValueAsBit("BigEndianSafe");
+  std::string Guard = R->getValueAsString("ArchGuard");
+  bool IsUnavailable = OperationRec->getValueAsBit("Unavailable");
+
+  // Set the global current record. This allows assert_with_loc to produce
+  // decent location information even when highly nested.
+  CurrentRecord = R;
+
+  ListInit *Body = OperationRec->getValueAsListInit("Ops");
+
+  std::vector<TypeSpec> TypeSpecs = TypeSpec::fromTypeSpecs(Types);
+
+  ClassKind CK = ClassNone;
+  if (R->getSuperClasses().size() >= 2)
+    CK = ClassMap[R->getSuperClasses()[1]];
+
+  std::vector<std::pair<TypeSpec, TypeSpec>> NewTypeSpecs;
+  for (auto TS : TypeSpecs) {
+    if (CartesianProductOfTypes) {
+      Type DefaultT(TS, 'd');
+      for (auto SrcTS : TypeSpecs) {
+        Type DefaultSrcT(SrcTS, 'd');
+        if (TS == SrcTS ||
+            DefaultSrcT.getSizeInBits() != DefaultT.getSizeInBits())
+          continue;
+        NewTypeSpecs.push_back(std::make_pair(TS, SrcTS));
+      }
+    } else {
+      NewTypeSpecs.push_back(std::make_pair(TS, TS));
+    }
+  }
+
+  std::sort(NewTypeSpecs.begin(), NewTypeSpecs.end());
+  std::unique(NewTypeSpecs.begin(), NewTypeSpecs.end());
+
+  for (auto &I : NewTypeSpecs) {
+    Intrinsic *IT = new Intrinsic(R, Name, Proto, I.first, I.second, CK, Body,
+                                  *this, Guard, IsUnavailable, BigEndianSafe);
+
+    IntrinsicMap[Name].push_back(IT);
+    Out.push_back(IT);
+  }
+
+  CurrentRecord = nullptr;
+}
+
+/// genBuiltinsDef: Generate the BuiltinsARM.def and  BuiltinsAArch64.def
+/// declaration of builtins, checking for unique builtin declarations.
+void NeonEmitter::genBuiltinsDef(raw_ostream &OS,
+                                 SmallVectorImpl<Intrinsic *> &Defs) {
+  OS << "#ifdef GET_NEON_BUILTINS\n";
+
+  // We only want to emit a builtin once, and we want to emit them in
+  // alphabetical order, so use a std::set.
+  std::set<std::string> Builtins;
+
+  for (auto *Def : Defs) {
+    if (Def->hasBody())
+      continue;
+    // Functions with 'a' (the splat code) in the type prototype should not get
+    // their own builtin as they use the non-splat variant.
+    if (Def->hasSplat())
+      continue;
+
+    std::string S = "BUILTIN(__builtin_neon_" + Def->getMangledName() + ", \"";
+
+    S += Def->getBuiltinTypeStr();
+    S += "\", \"n\")";
+
+    Builtins.insert(S);
+  }
+
+  for (auto &S : Builtins)
+    OS << S << "\n";
+  OS << "#endif\n\n";
+}
+
+/// Generate the ARM and AArch64 overloaded type checking code for
+/// SemaChecking.cpp, checking for unique builtin declarations.
+void NeonEmitter::genOverloadTypeCheckCode(raw_ostream &OS,
+                                           SmallVectorImpl<Intrinsic *> &Defs) {
+  OS << "#ifdef GET_NEON_OVERLOAD_CHECK\n";
+
+  // We record each overload check line before emitting because subsequent Inst
+  // definitions may extend the number of permitted types (i.e. augment the
+  // Mask). Use std::map to avoid sorting the table by hash number.
+  struct OverloadInfo {
+    uint64_t Mask;
+    int PtrArgNum;
+    bool HasConstPtr;
+    OverloadInfo() : Mask(0ULL), PtrArgNum(0), HasConstPtr(false) {}
+  };
+  std::map<std::string, OverloadInfo> OverloadMap;
+
+  for (auto *Def : Defs) {
+    // If the def has a body (that is, it has Operation DAGs), it won't call
+    // __builtin_neon_* so we don't need to generate a definition for it.
+    if (Def->hasBody())
+      continue;
+    // Functions with 'a' (the splat code) in the type prototype should not get
+    // their own builtin as they use the non-splat variant.
+    if (Def->hasSplat())
+      continue;
+    // Functions which have a scalar argument cannot be overloaded, no need to
+    // check them if we are emitting the type checking code.
+    if (Def->protoHasScalar())
+      continue;
+
+    uint64_t Mask = 0ULL;
+    Type Ty = Def->getReturnType();
+    if (Def->getProto()[0] == 'v' || Def->getProto()[0] == 'f' ||
+        Def->getProto()[0] == 'F')
+      Ty = Def->getParamType(0);
+    if (Ty.isPointer())
+      Ty = Def->getParamType(1);
+
+    Mask |= 1ULL << Ty.getNeonEnum();
+
+    // Check if the function has a pointer or const pointer argument.
+    std::string Proto = Def->getProto();
+    int PtrArgNum = -1;
+    bool HasConstPtr = false;
+    for (unsigned I = 0; I < Def->getNumParams(); ++I) {
+      char ArgType = Proto[I + 1];
+      if (ArgType == 'c') {
+        HasConstPtr = true;
+        PtrArgNum = I;
+        break;
+      }
+      if (ArgType == 'p') {
+        PtrArgNum = I;
+        break;
+      }
+    }
+    // For sret builtins, adjust the pointer argument index.
+    if (PtrArgNum >= 0 && Def->getReturnType().getNumVectors() > 1)
+      PtrArgNum += 1;
+
+    std::string Name = Def->getName();
+    // Omit type checking for the pointer arguments of vld1_lane, vld1_dup,
+    // and vst1_lane intrinsics.  Using a pointer to the vector element
+    // type with one of those operations causes codegen to select an aligned
+    // load/store instruction.  If you want an unaligned operation,
+    // the pointer argument needs to have less alignment than element type,
+    // so just accept any pointer type.
+    if (Name == "vld1_lane" || Name == "vld1_dup" || Name == "vst1_lane") {
+      PtrArgNum = -1;
+      HasConstPtr = false;
+    }
+
+    if (Mask) {
+      std::string Name = Def->getMangledName();
+      OverloadMap.insert(std::make_pair(Name, OverloadInfo()));
+      OverloadInfo &OI = OverloadMap[Name];
+      OI.Mask |= Mask;
+      OI.PtrArgNum |= PtrArgNum;
+      OI.HasConstPtr = HasConstPtr;
+    }
+  }
+
+  for (auto &I : OverloadMap) {
+    OverloadInfo &OI = I.second;
+
+    OS << "case NEON::BI__builtin_neon_" << I.first << ": ";
+    OS << "mask = 0x" << utohexstr(OI.Mask) << "ULL";
+    if (OI.PtrArgNum >= 0)
+      OS << "; PtrArgNum = " << OI.PtrArgNum;
+    if (OI.HasConstPtr)
+      OS << "; HasConstPtr = true";
+    OS << "; break;\n";
+  }
+  OS << "#endif\n\n";
+}
+
+void
+NeonEmitter::genIntrinsicRangeCheckCode(raw_ostream &OS,
+                                        SmallVectorImpl<Intrinsic *> &Defs) {
+  OS << "#ifdef GET_NEON_IMMEDIATE_CHECK\n";
+
+  std::set<std::string> Emitted;
+
+  for (auto *Def : Defs) {
+    if (Def->hasBody())
+      continue;
+    // Functions with 'a' (the splat code) in the type prototype should not get
+    // their own builtin as they use the non-splat variant.
+    if (Def->hasSplat())
+      continue;
+    // Functions which do not have an immediate do not need to have range
+    // checking code emitted.
+    if (!Def->hasImmediate())
+      continue;
+    if (Emitted.find(Def->getMangledName()) != Emitted.end())
+      continue;
+
+    std::string LowerBound, UpperBound;
+
+    Record *R = Def->getRecord();
+    if (R->getValueAsBit("isVCVT_N")) {
+      // VCVT between floating- and fixed-point values takes an immediate
+      // in the range [1, 32) for f32 or [1, 64) for f64.
+      LowerBound = "1";
+      if (Def->getBaseType().getElementSizeInBits() == 32)
+        UpperBound = "31";
+      else
+        UpperBound = "63";
+    } else if (R->getValueAsBit("isScalarShift")) {
+      // Right shifts have an 'r' in the name, left shifts do not. Convert
+      // instructions have the same bounds and right shifts.
+      if (Def->getName().find('r') != std::string::npos ||
+          Def->getName().find("cvt") != std::string::npos)
+        LowerBound = "1";
+
+      UpperBound = utostr(Def->getReturnType().getElementSizeInBits() - 1);
+    } else if (R->getValueAsBit("isShift")) {
+      // Builtins which are overloaded by type will need to have their upper
+      // bound computed at Sema time based on the type constant.
+
+      // Right shifts have an 'r' in the name, left shifts do not.
+      if (Def->getName().find('r') != std::string::npos)
+        LowerBound = "1";
+      UpperBound = "RFT(TV, true)";
+    } else if (Def->getClassKind(true) == ClassB) {
+      // ClassB intrinsics have a type (and hence lane number) that is only
+      // known at runtime.
+      if (R->getValueAsBit("isLaneQ"))
+        UpperBound = "RFT(TV, false, true)";
+      else
+        UpperBound = "RFT(TV, false, false)";
+    } else {
+      // The immediate generally refers to a lane in the preceding argument.
+      assert(Def->getImmediateIdx() > 0);
+      Type T = Def->getParamType(Def->getImmediateIdx() - 1);
+      UpperBound = utostr(T.getNumElements() - 1);
+    }
+
+    // Calculate the index of the immediate that should be range checked.
+    unsigned Idx = Def->getNumParams();
+    if (Def->hasImmediate())
+      Idx = Def->getGeneratedParamIdx(Def->getImmediateIdx());
+
+    OS << "case NEON::BI__builtin_neon_" << Def->getMangledName() << ": "
+       << "i = " << Idx << ";";
+    if (LowerBound.size())
+      OS << " l = " << LowerBound << ";";
+    if (UpperBound.size())
+      OS << " u = " << UpperBound << ";";
+    OS << " break;\n";
+
+    Emitted.insert(Def->getMangledName());
+  }
+
+  OS << "#endif\n\n";
+}
+
+/// runHeader - Emit a file with sections defining:
+/// 1. the NEON section of BuiltinsARM.def and BuiltinsAArch64.def.
+/// 2. the SemaChecking code for the type overload checking.
+/// 3. the SemaChecking code for validation of intrinsic immediate arguments.
+void NeonEmitter::runHeader(raw_ostream &OS) {
+  std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst");
+
+  SmallVector<Intrinsic *, 128> Defs;
+  for (auto *R : RV)
+    createIntrinsic(R, Defs);
+
+  // Generate shared BuiltinsXXX.def
+  genBuiltinsDef(OS, Defs);
+
+  // Generate ARM overloaded type checking code for SemaChecking.cpp
+  genOverloadTypeCheckCode(OS, Defs);
+
+  // Generate ARM range checking code for shift/lane immediates.
+  genIntrinsicRangeCheckCode(OS, Defs);
 }
 
 /// run - Read the records in arm_neon.td and output arm_neon.h.  arm_neon.h
 /// is comprised of type definitions and function declarations.
 void NeonEmitter::run(raw_ostream &OS) {
-  OS << 
-    "/*===---- arm_neon.h - ARM Neon intrinsics ------------------------------"
-    "---===\n"
-    " *\n"
-    " * Permission is hereby granted, free of charge, to any person obtaining "
-    "a copy\n"
-    " * of this software and associated documentation files (the \"Software\"),"
-    " to deal\n"
-    " * in the Software without restriction, including without limitation the "
-    "rights\n"
-    " * to use, copy, modify, merge, publish, distribute, sublicense, "
-    "and/or sell\n"
-    " * copies of the Software, and to permit persons to whom the Software is\n"
-    " * furnished to do so, subject to the following conditions:\n"
-    " *\n"
-    " * The above copyright notice and this permission notice shall be "
-    "included in\n"
-    " * all copies or substantial portions of the Software.\n"
-    " *\n"
-    " * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, "
-    "EXPRESS OR\n"
-    " * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF "
-    "MERCHANTABILITY,\n"
-    " * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT "
-    "SHALL THE\n"
-    " * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR "
-    "OTHER\n"
-    " * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, "
-    "ARISING FROM,\n"
-    " * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER "
-    "DEALINGS IN\n"
-    " * THE SOFTWARE.\n"
-    " *\n"
-    " *===--------------------------------------------------------------------"
-    "---===\n"
-    " */\n\n";
+  OS << "/*===---- arm_neon.h - ARM Neon intrinsics "
+        "------------------------------"
+        "---===\n"
+        " *\n"
+        " * Permission is hereby granted, free of charge, to any person "
+        "obtaining "
+        "a copy\n"
+        " * of this software and associated documentation files (the "
+        "\"Software\"),"
+        " to deal\n"
+        " * in the Software without restriction, including without limitation "
+        "the "
+        "rights\n"
+        " * to use, copy, modify, merge, publish, distribute, sublicense, "
+        "and/or sell\n"
+        " * copies of the Software, and to permit persons to whom the Software "
+        "is\n"
+        " * furnished to do so, subject to the following conditions:\n"
+        " *\n"
+        " * The above copyright notice and this permission notice shall be "
+        "included in\n"
+        " * all copies or substantial portions of the Software.\n"
+        " *\n"
+        " * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, "
+        "EXPRESS OR\n"
+        " * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF "
+        "MERCHANTABILITY,\n"
+        " * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT "
+        "SHALL THE\n"
+        " * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR "
+        "OTHER\n"
+        " * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, "
+        "ARISING FROM,\n"
+        " * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER "
+        "DEALINGS IN\n"
+        " * THE SOFTWARE.\n"
+        " *\n"
+        " *===-----------------------------------------------------------------"
+        "---"
+        "---===\n"
+        " */\n\n";
 
   OS << "#ifndef __ARM_NEON_H\n";
   OS << "#define __ARM_NEON_H\n\n";
 
-  OS << "#if !defined(__ARM_NEON__) && !defined(__ARM_NEON)\n";
+  OS << "#if !defined(__ARM_NEON)\n";
   OS << "#error \"NEON support not enabled\"\n";
   OS << "#endif\n\n";
 
@@ -2424,6 +2248,7 @@
   OS << "typedef uint8_t poly8_t;\n";
   OS << "typedef uint16_t poly16_t;\n";
   OS << "typedef uint64_t poly64_t;\n";
+  OS << "typedef __uint128_t poly128_t;\n";
   OS << "#else\n";
   OS << "typedef int8_t poly8_t;\n";
   OS << "typedef int16_t poly16_t;\n";
@@ -2432,834 +2257,132 @@
   // Emit Neon vector typedefs.
   std::string TypedefTypes(
       "cQcsQsiQilQlUcQUcUsQUsUiQUiUlQUlhQhfQfdQdPcQPcPsQPsPlQPl");
-  SmallVector<StringRef, 24> TDTypeVec;
-  ParseTypes(0, TypedefTypes, TDTypeVec);
+  std::vector<TypeSpec> TDTypeVec = TypeSpec::fromTypeSpecs(TypedefTypes);
 
   // Emit vector typedefs.
-  bool isA64 = false;
-  bool preinsert;
-  bool postinsert;
-  for (unsigned i = 0, e = TDTypeVec.size(); i != e; ++i) {
-    bool dummy, quad = false, poly = false;
-    char type = ClassifyType(TDTypeVec[i], quad, poly, dummy);
-    preinsert = false;
-    postinsert = false;
+  bool InIfdef = false;
+  for (auto &TS : TDTypeVec) {
+    bool IsA64 = false;
+    Type T(TS, 'd');
+    if (T.isDouble() || (T.isPoly() && T.isLong()))
+      IsA64 = true;
 
-    if (type == 'd' || (type == 'l' && poly)) {
-      preinsert = isA64? false: true;
-      isA64 = true;
-    } else {
-      postinsert = isA64? true: false;
-      isA64 = false;
-    }
-    if (postinsert)
+    if (InIfdef && !IsA64) {
       OS << "#endif\n";
-    if (preinsert)
+      InIfdef = false;
+    }
+    if (!InIfdef && IsA64) {
       OS << "#ifdef __aarch64__\n";
+      InIfdef = true;
+    }
 
-    if (poly)
+    if (T.isPoly())
       OS << "typedef __attribute__((neon_polyvector_type(";
     else
       OS << "typedef __attribute__((neon_vector_type(";
 
-    unsigned nElts = GetNumElements(TDTypeVec[i], quad);
-    OS << utostr(nElts) << "))) ";
-    if (nElts < 10)
-      OS << " ";
-
-    OS << TypeString('s', TDTypeVec[i]);
-    OS << " " << TypeString('d', TDTypeVec[i]) << ";\n";
-
+    Type T2 = T;
+    T2.makeScalar();
+    OS << utostr(T.getNumElements()) << "))) ";
+    OS << T2.str();
+    OS << " " << T.str() << ";\n";
   }
-  postinsert = isA64? true: false;
-  if (postinsert)
+  if (InIfdef)
     OS << "#endif\n";
   OS << "\n";
 
   // Emit struct typedefs.
-  isA64 = false;
-  for (unsigned vi = 2; vi != 5; ++vi) {
-    for (unsigned i = 0, e = TDTypeVec.size(); i != e; ++i) {
-      bool dummy, quad = false, poly = false;
-      char type = ClassifyType(TDTypeVec[i], quad, poly, dummy);
-      preinsert = false;
-      postinsert = false;
+  InIfdef = false;
+  for (unsigned NumMembers = 2; NumMembers <= 4; ++NumMembers) {
+    for (auto &TS : TDTypeVec) {
+      bool IsA64 = false;
+      Type T(TS, 'd');
+      if (T.isDouble() || (T.isPoly() && T.isLong()))
+        IsA64 = true;
 
-      if (type == 'd' || (type == 'l' && poly)) {
-        preinsert = isA64? false: true;
-        isA64 = true;
-      } else {
-        postinsert = isA64? true: false;
-        isA64 = false;
-      }
-      if (postinsert)
+      if (InIfdef && !IsA64) {
         OS << "#endif\n";
-      if (preinsert)
+        InIfdef = false;
+      }
+      if (!InIfdef && IsA64) {
         OS << "#ifdef __aarch64__\n";
+        InIfdef = true;
+      }
 
-      std::string ts = TypeString('d', TDTypeVec[i]);
-      std::string vs = TypeString('0' + vi, TDTypeVec[i]);
-      OS << "typedef struct " << vs << " {\n";
-      OS << "  " << ts << " val";
-      OS << "[" << utostr(vi) << "]";
+      char M = '2' + (NumMembers - 2);
+      Type VT(TS, M);
+      OS << "typedef struct " << VT.str() << " {\n";
+      OS << "  " << T.str() << " val";
+      OS << "[" << utostr(NumMembers) << "]";
       OS << ";\n} ";
-      OS << vs << ";\n";
+      OS << VT.str() << ";\n";
       OS << "\n";
     }
   }
-  postinsert = isA64? true: false;
-  if (postinsert)
+  if (InIfdef)
     OS << "#endif\n";
   OS << "\n";
 
-  OS<<"#define __ai static inline __attribute__((__always_inline__, __nodebug__))\n\n";
+  OS << "#define __ai static inline __attribute__((__always_inline__, "
+        "__nodebug__))\n\n";
 
-  std::vector<Record*> RV = Records.getAllDerivedDefinitions("Inst");
+  SmallVector<Intrinsic *, 128> Defs;
+  std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst");
+  for (auto *R : RV)
+    createIntrinsic(R, Defs);
 
-  StringMap<ClassKind> EmittedMap;
+  for (auto *I : Defs)
+    I->indexBody();
 
-  // Emit vmovl, vmull and vabd intrinsics first so they can be used by other
-  // intrinsics.  (Some of the saturating multiply instructions are also
-  // used to implement the corresponding "_lane" variants, but tablegen
-  // sorts the records into alphabetical order so that the "_lane" variants
-  // come after the intrinsics they use.)
-  emitIntrinsic(OS, Records.getDef("VMOVL"), EmittedMap);
-  emitIntrinsic(OS, Records.getDef("VMULL"), EmittedMap);
-  emitIntrinsic(OS, Records.getDef("VABD"), EmittedMap);
-  emitIntrinsic(OS, Records.getDef("VABDL"), EmittedMap);
+  std::stable_sort(
+      Defs.begin(), Defs.end(),
+      [](const Intrinsic *A, const Intrinsic *B) { return *A < *B; });
 
-  // ARM intrinsics must be emitted before AArch64 intrinsics to ensure
-  // common intrinsics appear only once in the output stream.
-  // The check for uniquiness is done in emitIntrinsic.
-  // Emit ARM intrinsics.
-  for (unsigned i = 0, e = RV.size(); i != e; ++i) {
-    Record *R = RV[i];
+  // Only emit a def when its requirements have been met.
+  // FIXME: This loop could be made faster, but it's fast enough for now.
+  bool MadeProgress = true;
+  std::string InGuard = "";
+  while (!Defs.empty() && MadeProgress) {
+    MadeProgress = false;
 
-    // Skip AArch64 intrinsics; they will be emitted at the end.
-    bool isA64 = R->getValueAsBit("isA64");
-    if (isA64)
-      continue;
+    for (SmallVector<Intrinsic *, 128>::iterator I = Defs.begin();
+         I != Defs.end(); /*No step*/) {
+      bool DependenciesSatisfied = true;
+      for (auto *II : (*I)->getDependencies()) {
+        if (std::find(Defs.begin(), Defs.end(), II) != Defs.end())
+          DependenciesSatisfied = false;
+      }
+      if (!DependenciesSatisfied) {
+        // Try the next one.
+        ++I;
+        continue;
+      }
 
-    if (R->getName() != "VMOVL" && R->getName() != "VMULL" &&
-        R->getName() != "VABD")
-      emitIntrinsic(OS, R, EmittedMap);
+      // Emit #endif/#if pair if needed.
+      if ((*I)->getGuard() != InGuard) {
+        if (!InGuard.empty())
+          OS << "#endif\n";
+        InGuard = (*I)->getGuard();
+        if (!InGuard.empty())
+          OS << "#if " << InGuard << "\n";
+      }
+
+      // Actually generate the intrinsic code.
+      OS << (*I)->generate();
+
+      MadeProgress = true;
+      I = Defs.erase(I);
+    }
   }
+  assert(Defs.empty() && "Some requirements were not satisfied!");
+  if (!InGuard.empty())
+    OS << "#endif\n";
 
-  // Emit AArch64-specific intrinsics.
-  OS << "#ifdef __aarch64__\n";
-
-  emitIntrinsic(OS, Records.getDef("VMOVL_HIGH"), EmittedMap);
-  emitIntrinsic(OS, Records.getDef("VMULL_HIGH"), EmittedMap);
-  emitIntrinsic(OS, Records.getDef("VABDL_HIGH"), EmittedMap);
-
-  for (unsigned i = 0, e = RV.size(); i != e; ++i) {
-    Record *R = RV[i];
-
-    // Skip ARM intrinsics already included above.
-    bool isA64 = R->getValueAsBit("isA64");
-    if (!isA64)
-      continue;
-
-    // Skip crypto temporarily, and will emit them all together at the end.
-    bool isCrypto = R->getValueAsBit("isCrypto");
-    if (isCrypto)
-      continue;
-
-    emitIntrinsic(OS, R, EmittedMap);
-  }
-
-  OS << "#ifdef __ARM_FEATURE_CRYPTO\n";
-
-  for (unsigned i = 0, e = RV.size(); i != e; ++i) {
-    Record *R = RV[i];
-
-    // Skip crypto temporarily, and will emit them all together at the end.
-    bool isCrypto = R->getValueAsBit("isCrypto");
-    if (!isCrypto)
-      continue;
-
-    emitIntrinsic(OS, R, EmittedMap);
-  }
-  
-  OS << "#endif\n\n";
-
-  OS << "#endif\n\n";
-
+  OS << "\n";
   OS << "#undef __ai\n\n";
   OS << "#endif /* __ARM_NEON_H */\n";
 }
 
-/// emitIntrinsic - Write out the arm_neon.h header file definitions for the
-/// intrinsics specified by record R checking for intrinsic uniqueness.
-void NeonEmitter::emitIntrinsic(raw_ostream &OS, Record *R,
-                                StringMap<ClassKind> &EmittedMap) {
-  std::string name = R->getValueAsString("Name");
-  std::string Proto = R->getValueAsString("Prototype");
-  std::string Types = R->getValueAsString("Types");
-
-  SmallVector<StringRef, 16> TypeVec;
-  ParseTypes(R, Types, TypeVec);
-
-  OpKind kind = OpMap[R->getValueAsDef("Operand")->getName()];
-
-  ClassKind classKind = ClassNone;
-  if (R->getSuperClasses().size() >= 2)
-    classKind = ClassMap[R->getSuperClasses()[1]];
-  if (classKind == ClassNone && kind == OpNone)
-    PrintFatalError(R->getLoc(), "Builtin has no class kind");
-
-  for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) {
-    if (kind == OpReinterpret) {
-      bool outQuad = false;
-      bool dummy = false;
-      (void)ClassifyType(TypeVec[ti], outQuad, dummy, dummy);
-      for (unsigned srcti = 0, srcte = TypeVec.size();
-           srcti != srcte; ++srcti) {
-        bool inQuad = false;
-        (void)ClassifyType(TypeVec[srcti], inQuad, dummy, dummy);
-        if (srcti == ti || inQuad != outQuad)
-          continue;
-        std::string s = GenIntrinsic(name, Proto, TypeVec[ti], TypeVec[srcti],
-                                     OpCast, ClassS);
-        if (EmittedMap.count(s))
-          continue;
-        EmittedMap[s] = ClassS;
-        OS << s;
-      }
-    } else {
-      std::string s =
-          GenIntrinsic(name, Proto, TypeVec[ti], TypeVec[ti], kind, classKind);
-      if (EmittedMap.count(s))
-        continue;
-      EmittedMap[s] = classKind;
-      OS << s;
-    }
-  }
-  OS << "\n";
-}
-
-static unsigned RangeFromType(const char mod, StringRef typestr) {
-  // base type to get the type string for.
-  bool quad = false, dummy = false;
-  char type = ClassifyType(typestr, quad, dummy, dummy);
-  type = ModType(mod, type, quad, dummy, dummy, dummy, dummy, dummy);
-
-  switch (type) {
-    case 'c':
-      return (8 << (int)quad) - 1;
-    case 'h':
-    case 's':
-      return (4 << (int)quad) - 1;
-    case 'f':
-    case 'i':
-      return (2 << (int)quad) - 1;
-    case 'd':
-    case 'l':
-      return (1 << (int)quad) - 1;
-    default:
-      PrintFatalError("unhandled type!");
-  }
-}
-
-static unsigned RangeScalarShiftImm(const char mod, StringRef typestr) {
-  // base type to get the type string for.
-  bool dummy = false;
-  char type = ClassifyType(typestr, dummy, dummy, dummy);
-  type = ModType(mod, type, dummy, dummy, dummy, dummy, dummy, dummy);
-
-  switch (type) {
-    case 'c':
-      return 7;
-    case 'h':
-    case 's':
-      return 15;
-    case 'f':
-    case 'i':
-      return 31;
-    case 'd':
-    case 'l':
-      return 63;
-    default:
-      PrintFatalError("unhandled type!");
-  }
-}
-
-/// Generate the ARM and AArch64 intrinsic range checking code for
-/// shift/lane immediates, checking for unique declarations.
-void
-NeonEmitter::genIntrinsicRangeCheckCode(raw_ostream &OS,
-                                        StringMap<ClassKind> &A64IntrinsicMap,
-                                        bool isA64RangeCheck) {
-  std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst");
-  StringMap<OpKind> EmittedMap;
-
-  // Generate the intrinsic range checking code for shift/lane immediates.
-  if (isA64RangeCheck)
-    OS << "#ifdef GET_NEON_AARCH64_IMMEDIATE_CHECK\n";
-  else
-    OS << "#ifdef GET_NEON_IMMEDIATE_CHECK\n";
-
-  for (unsigned i = 0, e = RV.size(); i != e; ++i) {
-    Record *R = RV[i];
-
-    OpKind k = OpMap[R->getValueAsDef("Operand")->getName()];
-    if (k != OpNone)
-      continue;
-
-    std::string name = R->getValueAsString("Name");
-    std::string Proto = R->getValueAsString("Prototype");
-    std::string Types = R->getValueAsString("Types");
-    std::string Rename = name + "@" + Proto;
-
-    // Functions with 'a' (the splat code) in the type prototype should not get
-    // their own builtin as they use the non-splat variant.
-    if (Proto.find('a') != std::string::npos)
-      continue;
-
-    // Functions which do not have an immediate do not need to have range
-    // checking code emitted.
-    size_t immPos = Proto.find('i');
-    if (immPos == std::string::npos)
-      continue;
-
-    SmallVector<StringRef, 16> TypeVec;
-    ParseTypes(R, Types, TypeVec);
-
-    if (R->getSuperClasses().size() < 2)
-      PrintFatalError(R->getLoc(), "Builtin has no class kind");
-
-    ClassKind ck = ClassMap[R->getSuperClasses()[1]];
-
-    // Do not include AArch64 range checks if not generating code for AArch64.
-    bool isA64 = R->getValueAsBit("isA64");
-    if (!isA64RangeCheck && isA64)
-      continue;
-
-    // Include ARM range checks in AArch64 but only if ARM intrinsics are not
-    // redefined by AArch64 to handle new types.
-    if (isA64RangeCheck && !isA64 && A64IntrinsicMap.count(Rename)) {
-      ClassKind &A64CK = A64IntrinsicMap[Rename];
-      if (A64CK == ck && ck != ClassNone)
-        continue;
-    }
-
-    for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) {
-      std::string namestr, shiftstr, rangestr;
-
-      if (R->getValueAsBit("isVCVT_N")) {
-        // VCVT between floating- and fixed-point values takes an immediate
-        // in the range [1, 32] for f32, or [1, 64] for f64.
-        ck = ClassB;
-        if (name.find("32") != std::string::npos)
-          rangestr = "l = 1; u = 31"; // upper bound = l + u
-        else if (name.find("64") != std::string::npos)
-          rangestr = "l = 1; u = 63";
-        else
-          PrintFatalError(R->getLoc(),
-              "Fixed point convert name should contains \"32\" or \"64\"");
-
-      } else if (R->getValueAsBit("isScalarShift")) {
-        // Right shifts have an 'r' in the name, left shifts do not.  Convert
-        // instructions have the same bounds and right shifts.
-        if (name.find('r') != std::string::npos ||
-            name.find("cvt") != std::string::npos)
-          rangestr = "l = 1; ";
-
-        rangestr += "u = " +
-          utostr(RangeScalarShiftImm(Proto[immPos - 1], TypeVec[ti]));
-      } else if (!ProtoHasScalar(Proto)) {
-        // Builtins which are overloaded by type will need to have their upper
-        // bound computed at Sema time based on the type constant.
-        ck = ClassB;
-        if (R->getValueAsBit("isShift")) {
-          shiftstr = ", true";
-
-          // Right shifts have an 'r' in the name, left shifts do not.
-          if (name.find('r') != std::string::npos)
-            rangestr = "l = 1; ";
-        }
-        rangestr += "u = RFT(TV" + shiftstr + ")";
-      } else {
-        // The immediate generally refers to a lane in the preceding argument.
-        assert(immPos > 0 && "unexpected immediate operand");
-        rangestr =
-            "u = " + utostr(RangeFromType(Proto[immPos - 1], TypeVec[ti]));
-      }
-      // Make sure cases appear only once by uniquing them in a string map.
-      namestr = MangleName(name, TypeVec[ti], ck);
-      if (EmittedMap.count(namestr))
-        continue;
-      EmittedMap[namestr] = OpNone;
-
-      // Calculate the index of the immediate that should be range checked.
-      unsigned immidx = 0;
-
-      // Builtins that return a struct of multiple vectors have an extra
-      // leading arg for the struct return.
-      if (IsMultiVecProto(Proto[0]))
-        ++immidx;
-
-      // Add one to the index for each argument until we reach the immediate
-      // to be checked.  Structs of vectors are passed as multiple arguments.
-      for (unsigned ii = 1, ie = Proto.size(); ii != ie; ++ii) {
-        switch (Proto[ii]) {
-        default:
-          immidx += 1;
-          break;
-        case '2':
-        case 'B':
-          immidx += 2;
-          break;
-        case '3':
-        case 'C':
-          immidx += 3;
-          break;
-        case '4':
-        case 'D':
-          immidx += 4;
-          break;
-        case 'i':
-          ie = ii + 1;
-          break;
-        }
-      }
-      if (isA64RangeCheck)
-        OS << "case AArch64::BI__builtin_neon_";
-      else
-        OS << "case ARM::BI__builtin_neon_";
-      OS << MangleName(name, TypeVec[ti], ck) << ": i = " << immidx << "; "
-         << rangestr << "; break;\n";
-    }
-  }
-  OS << "#endif\n\n";
-}
-
-/// Generate the ARM and AArch64 overloaded type checking code for
-/// SemaChecking.cpp, checking for unique builtin declarations.
-void
-NeonEmitter::genOverloadTypeCheckCode(raw_ostream &OS,
-                                      StringMap<ClassKind> &A64IntrinsicMap,
-                                      bool isA64TypeCheck) {
-  std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst");
-  StringMap<OpKind> EmittedMap;
-
-  // Generate the overloaded type checking code for SemaChecking.cpp
-  if (isA64TypeCheck)
-    OS << "#ifdef GET_NEON_AARCH64_OVERLOAD_CHECK\n";
-  else
-    OS << "#ifdef GET_NEON_OVERLOAD_CHECK\n";
-
-  for (unsigned i = 0, e = RV.size(); i != e; ++i) {
-    Record *R = RV[i];
-    OpKind k = OpMap[R->getValueAsDef("Operand")->getName()];
-    if (k != OpNone)
-      continue;
-
-    std::string Proto = R->getValueAsString("Prototype");
-    std::string Types = R->getValueAsString("Types");
-    std::string name = R->getValueAsString("Name");
-    std::string Rename = name + "@" + Proto;
-    
-    // Functions with 'a' (the splat code) in the type prototype should not get
-    // their own builtin as they use the non-splat variant.
-    if (Proto.find('a') != std::string::npos)
-      continue;
-
-    // Functions which have a scalar argument cannot be overloaded, no need to
-    // check them if we are emitting the type checking code.
-    if (ProtoHasScalar(Proto))
-      continue;
-
-    SmallVector<StringRef, 16> TypeVec;
-    ParseTypes(R, Types, TypeVec);
-
-    if (R->getSuperClasses().size() < 2)
-      PrintFatalError(R->getLoc(), "Builtin has no class kind");
-
-    // Do not include AArch64 type checks if not generating code for AArch64.
-    bool isA64 = R->getValueAsBit("isA64");
-    if (!isA64TypeCheck && isA64)
-      continue;
-
-    // Include ARM  type check in AArch64 but only if ARM intrinsics
-    // are not redefined in AArch64 to handle new types, e.g. "vabd" is a SIntr
-    // redefined in AArch64 to handle an additional 2 x f64 type.
-    ClassKind ck = ClassMap[R->getSuperClasses()[1]];
-    if (isA64TypeCheck && !isA64 && A64IntrinsicMap.count(Rename)) {
-      ClassKind &A64CK = A64IntrinsicMap[Rename];
-      if (A64CK == ck && ck != ClassNone)
-        continue;
-    }
-
-    int si = -1, qi = -1;
-    uint64_t mask = 0, qmask = 0;
-    for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) {
-      // Generate the switch case(s) for this builtin for the type validation.
-      bool quad = false, poly = false, usgn = false;
-      (void) ClassifyType(TypeVec[ti], quad, poly, usgn);
-
-      if (quad) {
-        qi = ti;
-        qmask |= 1ULL << GetNeonEnum(Proto, TypeVec[ti]);
-      } else {
-        si = ti;
-        mask |= 1ULL << GetNeonEnum(Proto, TypeVec[ti]);
-      }
-    }
-
-    // Check if the builtin function has a pointer or const pointer argument.
-    int PtrArgNum = -1;
-    bool HasConstPtr = false;
-    for (unsigned arg = 1, arge = Proto.size(); arg != arge; ++arg) {
-      char ArgType = Proto[arg];
-      if (ArgType == 'c') {
-        HasConstPtr = true;
-        PtrArgNum = arg - 1;
-        break;
-      }
-      if (ArgType == 'p') {
-        PtrArgNum = arg - 1;
-        break;
-      }
-    }
-    // For sret builtins, adjust the pointer argument index.
-    if (PtrArgNum >= 0 && IsMultiVecProto(Proto[0]))
-      PtrArgNum += 1;
-
-    // Omit type checking for the pointer arguments of vld1_lane, vld1_dup,
-    // and vst1_lane intrinsics.  Using a pointer to the vector element
-    // type with one of those operations causes codegen to select an aligned
-    // load/store instruction.  If you want an unaligned operation,
-    // the pointer argument needs to have less alignment than element type,
-    // so just accept any pointer type.
-    if (name == "vld1_lane" || name == "vld1_dup" || name == "vst1_lane") {
-      PtrArgNum = -1;
-      HasConstPtr = false;
-    }
-
-    if (mask) {
-      if (isA64TypeCheck)
-        OS << "case AArch64::BI__builtin_neon_";
-      else
-        OS << "case ARM::BI__builtin_neon_";
-      OS << MangleName(name, TypeVec[si], ClassB) << ": mask = "
-         << "0x" << utohexstr(mask) << "ULL";
-      if (PtrArgNum >= 0)
-        OS << "; PtrArgNum = " << PtrArgNum;
-      if (HasConstPtr)
-        OS << "; HasConstPtr = true";
-      OS << "; break;\n";
-    }
-    if (qmask) {
-      if (isA64TypeCheck)
-        OS << "case AArch64::BI__builtin_neon_";
-      else
-        OS << "case ARM::BI__builtin_neon_";
-      OS << MangleName(name, TypeVec[qi], ClassB) << ": mask = "
-         << "0x" << utohexstr(qmask) << "ULL";
-      if (PtrArgNum >= 0)
-        OS << "; PtrArgNum = " << PtrArgNum;
-      if (HasConstPtr)
-        OS << "; HasConstPtr = true";
-      OS << "; break;\n";
-    }
-  }
-  OS << "#endif\n\n";
-}
-
-/// genBuiltinsDef: Generate the BuiltinsARM.def and  BuiltinsAArch64.def
-/// declaration of builtins, checking for unique builtin declarations.
-void NeonEmitter::genBuiltinsDef(raw_ostream &OS,
-                                 StringMap<ClassKind> &A64IntrinsicMap,
-                                 bool isA64GenBuiltinDef) {
-  std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst");
-  StringMap<OpKind> EmittedMap;
-
-  // Generate BuiltinsARM.def and BuiltinsAArch64.def
-  if (isA64GenBuiltinDef)
-    OS << "#ifdef GET_NEON_AARCH64_BUILTINS\n";
-  else
-    OS << "#ifdef GET_NEON_BUILTINS\n";
-
-  for (unsigned i = 0, e = RV.size(); i != e; ++i) {
-    Record *R = RV[i];
-    OpKind k = OpMap[R->getValueAsDef("Operand")->getName()];
-    if (k != OpNone)
-      continue;
-
-    std::string Proto = R->getValueAsString("Prototype");
-    std::string name = R->getValueAsString("Name");
-    std::string Rename = name + "@" + Proto;
-
-    // Functions with 'a' (the splat code) in the type prototype should not get
-    // their own builtin as they use the non-splat variant.
-    if (Proto.find('a') != std::string::npos)
-      continue;
-
-    std::string Types = R->getValueAsString("Types");
-    SmallVector<StringRef, 16> TypeVec;
-    ParseTypes(R, Types, TypeVec);
-
-    if (R->getSuperClasses().size() < 2)
-      PrintFatalError(R->getLoc(), "Builtin has no class kind");
-
-    ClassKind ck = ClassMap[R->getSuperClasses()[1]];
-
-    // Do not include AArch64 BUILTIN() macros if not generating
-    // code for AArch64
-    bool isA64 = R->getValueAsBit("isA64");
-    if (!isA64GenBuiltinDef && isA64)
-      continue;
-
-    // Include ARM  BUILTIN() macros  in AArch64 but only if ARM intrinsics
-    // are not redefined in AArch64 to handle new types, e.g. "vabd" is a SIntr
-    // redefined in AArch64 to handle an additional 2 x f64 type.
-    if (isA64GenBuiltinDef && !isA64 && A64IntrinsicMap.count(Rename)) {
-      ClassKind &A64CK = A64IntrinsicMap[Rename];
-      if (A64CK == ck && ck != ClassNone)
-        continue;
-    }
-
-    for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) {
-      // Generate the declaration for this builtin, ensuring
-      // that each unique BUILTIN() macro appears only once in the output
-      // stream.
-      std::string bd = GenBuiltinDef(name, Proto, TypeVec[ti], ck);
-      if (EmittedMap.count(bd))
-        continue;
-
-      EmittedMap[bd] = OpNone;
-      OS << bd << "\n";
-    }
-  }
-  OS << "#endif\n\n";
-}
-
-/// runHeader - Emit a file with sections defining:
-/// 1. the NEON section of BuiltinsARM.def and BuiltinsAArch64.def.
-/// 2. the SemaChecking code for the type overload checking.
-/// 3. the SemaChecking code for validation of intrinsic immediate arguments.
-void NeonEmitter::runHeader(raw_ostream &OS) {
-  std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst");
-
-  // build a map of AArch64 intriniscs to be used in uniqueness checks.
-  StringMap<ClassKind> A64IntrinsicMap;
-  for (unsigned i = 0, e = RV.size(); i != e; ++i) {
-    Record *R = RV[i];
-
-    bool isA64 = R->getValueAsBit("isA64");
-    if (!isA64)
-      continue;
-
-    ClassKind CK = ClassNone;
-    if (R->getSuperClasses().size() >= 2)
-      CK = ClassMap[R->getSuperClasses()[1]];
-
-    std::string Name = R->getValueAsString("Name");
-    std::string Proto = R->getValueAsString("Prototype");
-    std::string Rename = Name + "@" + Proto;
-    if (A64IntrinsicMap.count(Rename))
-      continue;
-    A64IntrinsicMap[Rename] = CK;
-  }
-
-  // Generate BuiltinsARM.def for ARM
-  genBuiltinsDef(OS, A64IntrinsicMap, false);
-
-  // Generate BuiltinsAArch64.def for AArch64
-  genBuiltinsDef(OS, A64IntrinsicMap, true);
-
-  // Generate ARM overloaded type checking code for SemaChecking.cpp
-  genOverloadTypeCheckCode(OS, A64IntrinsicMap, false);
-
-  // Generate AArch64 overloaded type checking code for SemaChecking.cpp
-  genOverloadTypeCheckCode(OS, A64IntrinsicMap, true);
-
-  // Generate ARM range checking code for shift/lane immediates.
-  genIntrinsicRangeCheckCode(OS, A64IntrinsicMap, false);
-
-  // Generate the AArch64 range checking code for shift/lane immediates.
-  genIntrinsicRangeCheckCode(OS, A64IntrinsicMap, true);
-}
-
-/// GenTest - Write out a test for the intrinsic specified by the name and
-/// type strings, including the embedded patterns for FileCheck to match.
-static std::string GenTest(const std::string &name,
-                           const std::string &proto,
-                           StringRef outTypeStr, StringRef inTypeStr,
-                           bool isShift, bool isHiddenLOp,
-                           ClassKind ck, const std::string &InstName,
-                           bool isA64,
-                           std::string & testFuncProto) {
-  assert(!proto.empty() && "");
-  std::string s;
-
-  // Function name with type suffix
-  std::string mangledName = MangleName(name, outTypeStr, ClassS);
-  if (outTypeStr != inTypeStr) {
-    // If the input type is different (e.g., for vreinterpret), append a suffix
-    // for the input type.  String off a "Q" (quad) prefix so that MangleName
-    // does not insert another "q" in the name.
-    unsigned typeStrOff = (inTypeStr[0] == 'Q' ? 1 : 0);
-    StringRef inTypeNoQuad = inTypeStr.substr(typeStrOff);
-    mangledName = MangleName(mangledName, inTypeNoQuad, ClassS);
-  }
-
-  // todo: GenerateChecksForIntrinsic does not generate CHECK
-  // for aarch64 instructions yet
-  std::vector<std::string> FileCheckPatterns;
-  if (!isA64) {
-	GenerateChecksForIntrinsic(name, proto, outTypeStr, inTypeStr, ck, InstName,
-							   isHiddenLOp, FileCheckPatterns);
-	s+= "// CHECK_ARM: test_" + mangledName + "\n";
-  }
-  s += "// CHECK_AARCH64: test_" + mangledName + "\n";
-
-  // Emit the FileCheck patterns.
-  // If for any reason we do not want to emit a check, mangledInst
-  // will be the empty string.
-  if (FileCheckPatterns.size()) {
-    for (std::vector<std::string>::const_iterator i = FileCheckPatterns.begin(),
-                                                  e = FileCheckPatterns.end();
-         i != e;
-         ++i) {
-      s += "// CHECK_ARM: " + *i + "\n";
-    }
-  }
-
-  // Emit the start of the test function.
-
-  testFuncProto = TypeString(proto[0], outTypeStr) + " test_" + mangledName + "(";
-  char arg = 'a';
-  std::string comma;
-  for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) {
-    // Do not create arguments for values that must be immediate constants.
-    if (proto[i] == 'i')
-      continue;
-    testFuncProto += comma + TypeString(proto[i], inTypeStr) + " ";
-    testFuncProto.push_back(arg);
-    comma = ", ";
-  }
-  testFuncProto += ")";
-
-  s+= testFuncProto;
-  s+= " {\n  ";
-
-  if (proto[0] != 'v')
-    s += "return ";
-  s += mangledName + "(";
-  arg = 'a';
-  for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) {
-    if (proto[i] == 'i') {
-      // For immediate operands, test the maximum value.
-      if (isShift)
-        s += "1"; // FIXME
-      else
-        // The immediate generally refers to a lane in the preceding argument.
-        s += utostr(RangeFromType(proto[i-1], inTypeStr));
-    } else {
-      s.push_back(arg);
-    }
-    if ((i + 1) < e)
-      s += ", ";
-  }
-  s += ");\n}\n\n";
-  return s;
-}
-
-/// Write out all intrinsic tests for the specified target, checking
-/// for intrinsic test uniqueness.
-void NeonEmitter::genTargetTest(raw_ostream &OS, StringMap<OpKind> &EmittedMap,
-                                bool isA64GenTest) {
-  if (isA64GenTest)
-	OS << "#ifdef __aarch64__\n";
-
-  std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst");
-  for (unsigned i = 0, e = RV.size(); i != e; ++i) {
-    Record *R = RV[i];
-    std::string name = R->getValueAsString("Name");
-    std::string Proto = R->getValueAsString("Prototype");
-    std::string Types = R->getValueAsString("Types");
-    bool isShift = R->getValueAsBit("isShift");
-    std::string InstName = R->getValueAsString("InstName");
-    bool isHiddenLOp = R->getValueAsBit("isHiddenLInst");
-    bool isA64 = R->getValueAsBit("isA64");
-
-    // do not include AArch64 intrinsic test if not generating
-    // code for AArch64
-    if (!isA64GenTest && isA64)
-      continue;
-
-    SmallVector<StringRef, 16> TypeVec;
-    ParseTypes(R, Types, TypeVec);
-
-    ClassKind ck = ClassMap[R->getSuperClasses()[1]];
-    OpKind kind = OpMap[R->getValueAsDef("Operand")->getName()];
-    if (kind == OpUnavailable)
-      continue;
-    for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) {
-      if (kind == OpReinterpret) {
-        bool outQuad = false;
-        bool dummy = false;
-        (void)ClassifyType(TypeVec[ti], outQuad, dummy, dummy);
-        for (unsigned srcti = 0, srcte = TypeVec.size();
-             srcti != srcte; ++srcti) {
-          bool inQuad = false;
-          (void)ClassifyType(TypeVec[srcti], inQuad, dummy, dummy);
-          if (srcti == ti || inQuad != outQuad)
-            continue;
-		  std::string testFuncProto;
-          std::string s = GenTest(name, Proto, TypeVec[ti], TypeVec[srcti],
-                                  isShift, isHiddenLOp, ck, InstName, isA64,
-								  testFuncProto);
-          if (EmittedMap.count(testFuncProto))
-            continue;
-          EmittedMap[testFuncProto] = kind;
-          OS << s << "\n";
-        }
-      } else {
-		std::string testFuncProto;
-        std::string s = GenTest(name, Proto, TypeVec[ti], TypeVec[ti], isShift,
-                                isHiddenLOp, ck, InstName, isA64, testFuncProto);
-        if (EmittedMap.count(testFuncProto))
-          continue;
-        EmittedMap[testFuncProto] = kind;
-        OS << s << "\n";
-      }
-    }
-  }
-
-  if (isA64GenTest)
-	OS << "#endif\n";
-}
-/// runTests - Write out a complete set of tests for all of the Neon
-/// intrinsics.
-void NeonEmitter::runTests(raw_ostream &OS) {
-  OS << "// RUN: %clang_cc1 -triple thumbv7s-apple-darwin -target-abi "
-        "apcs-gnu\\\n"
-        "// RUN:  -target-cpu swift -ffreestanding -Os -S -o - %s\\\n"
-        "// RUN:  | FileCheck %s -check-prefix=CHECK_ARM\n"
-		"\n"
-	    "// RUN: %clang_cc1 -triple aarch64-none-linux-gnu \\\n"
-	    "// RUN -target-feature +neon  -ffreestanding -S -o - %s \\\n"
-	    "// RUN:  | FileCheck %s -check-prefix=CHECK_AARCH64\n"
-        "\n"
-        "// REQUIRES: long_tests\n"
-        "\n"
-        "#include <arm_neon.h>\n"
-        "\n";
-
-  // ARM tests must be emitted before AArch64 tests to ensure
-  // tests for intrinsics that are common to ARM and AArch64
-  // appear only once in the output stream.
-  // The check for uniqueness is done in genTargetTest.
-  StringMap<OpKind> EmittedMap;
-
-  genTargetTest(OS, EmittedMap, false);
-
-  genTargetTest(OS, EmittedMap, true);
-}
-
 namespace clang {
 void EmitNeon(RecordKeeper &Records, raw_ostream &OS) {
   NeonEmitter(Records).run(OS);
@@ -3268,6 +2391,6 @@
   NeonEmitter(Records).runHeader(OS);
 }
 void EmitNeonTest(RecordKeeper &Records, raw_ostream &OS) {
-  NeonEmitter(Records).runTests(OS);
+  llvm_unreachable("Neon test generation no longer implemented!");
 }
 } // End namespace clang
diff --git a/utils/TableGen/TableGen.cpp b/utils/TableGen/TableGen.cpp
index 0e45d81..4484e65 100644
--- a/utils/TableGen/TableGen.cpp
+++ b/utils/TableGen/TableGen.cpp
@@ -24,15 +24,14 @@
 
 enum ActionType {
   GenClangAttrClasses,
-  GenClangAttrIdentifierArgList,
-  GenClangAttrTypeArgList,
+  GenClangAttrParserStringSwitches,
   GenClangAttrImpl,
   GenClangAttrList,
   GenClangAttrPCHRead,
   GenClangAttrPCHWrite,
-  GenClangAttrSpellingList,
+  GenClangAttrHasAttributeImpl,
   GenClangAttrSpellingListIndex,
-  GenClangAttrLateParsedList,
+  GenClangAttrASTVisitor,
   GenClangAttrTemplateInstantiate,
   GenClangAttrParsedAttrList,
   GenClangAttrParsedAttrImpl,
@@ -52,7 +51,8 @@
   GenClangCommentCommandList,
   GenArmNeon,
   GenArmNeonSema,
-  GenArmNeonTest
+  GenArmNeonTest,
+  GenAttrDocs
 };
 
 namespace {
@@ -61,14 +61,9 @@
     cl::values(
         clEnumValN(GenClangAttrClasses, "gen-clang-attr-classes",
                    "Generate clang attribute clases"),
-        clEnumValN(GenClangAttrIdentifierArgList,
-                   "gen-clang-attr-identifier-arg-list",
-                   "Generate a list of attributes that take an "
-                   "identifier as their first argument"),
-        clEnumValN(GenClangAttrTypeArgList,
-                   "gen-clang-attr-type-arg-list",
-                   "Generate a list of attributes that take a type as their "
-                   "first argument"),
+        clEnumValN(GenClangAttrParserStringSwitches,
+                   "gen-clang-attr-parser-string-switches",
+                   "Generate all parser-related attribute string switches"),
         clEnumValN(GenClangAttrImpl, "gen-clang-attr-impl",
                    "Generate clang attribute implementations"),
         clEnumValN(GenClangAttrList, "gen-clang-attr-list",
@@ -77,14 +72,15 @@
                    "Generate clang PCH attribute reader"),
         clEnumValN(GenClangAttrPCHWrite, "gen-clang-attr-pch-write",
                    "Generate clang PCH attribute writer"),
-        clEnumValN(GenClangAttrSpellingList, "gen-clang-attr-spelling-list",
+        clEnumValN(GenClangAttrHasAttributeImpl,
+                   "gen-clang-attr-has-attribute-impl",
                    "Generate a clang attribute spelling list"),
         clEnumValN(GenClangAttrSpellingListIndex,
                    "gen-clang-attr-spelling-index",
                    "Generate a clang attribute spelling index"),
-        clEnumValN(GenClangAttrLateParsedList,
-                   "gen-clang-attr-late-parsed-list",
-                   "Generate a clang attribute LateParsed list"),
+        clEnumValN(GenClangAttrASTVisitor,
+                   "gen-clang-attr-ast-visitor",
+                   "Generate a recursive AST visitor for clang attributes"),
         clEnumValN(GenClangAttrTemplateInstantiate,
                    "gen-clang-attr-template-instantiate",
                    "Generate a clang template instantiate code"),
@@ -135,6 +131,8 @@
                    "Generate ARM NEON sema support for clang"),
         clEnumValN(GenArmNeonTest, "gen-arm-neon-test",
                    "Generate ARM NEON tests for clang"),
+        clEnumValN(GenAttrDocs, "gen-attr-docs",
+                   "Generate attribute documentation"),
         clEnumValEnd));
 
 cl::opt<std::string>
@@ -147,11 +145,8 @@
   case GenClangAttrClasses:
     EmitClangAttrClass(Records, OS);
     break;
-  case GenClangAttrIdentifierArgList:
-    EmitClangAttrIdentifierArgList(Records, OS);
-    break;
-  case GenClangAttrTypeArgList:
-    EmitClangAttrTypeArgList(Records, OS);
+  case GenClangAttrParserStringSwitches:
+    EmitClangAttrParserStringSwitches(Records, OS);
     break;
   case GenClangAttrImpl:
     EmitClangAttrImpl(Records, OS);
@@ -165,14 +160,14 @@
   case GenClangAttrPCHWrite:
     EmitClangAttrPCHWrite(Records, OS);
     break;
-  case GenClangAttrSpellingList:
-    EmitClangAttrSpellingList(Records, OS);
+  case GenClangAttrHasAttributeImpl:
+    EmitClangAttrHasAttrImpl(Records, OS);
     break;
   case GenClangAttrSpellingListIndex:
     EmitClangAttrSpellingListIndex(Records, OS);
     break;
-  case GenClangAttrLateParsedList:
-    EmitClangAttrLateParsedList(Records, OS);
+  case GenClangAttrASTVisitor:
+    EmitClangAttrASTVisitor(Records, OS);
     break;
   case GenClangAttrTemplateInstantiate:
     EmitClangAttrTemplateInstantiate(Records, OS);
@@ -235,6 +230,9 @@
   case GenArmNeonTest:
     EmitNeonTest(Records, OS);
     break;
+  case GenAttrDocs:
+    EmitClangAttrDocs(Records, OS);
+    break;
   }
 
   return false;
@@ -248,3 +246,12 @@
 
   return TableGenMain(argv[0], &ClangTableGenMain);
 }
+
+#ifdef __has_feature
+#if __has_feature(address_sanitizer)
+#include <sanitizer/lsan_interface.h>
+// Disable LeakSanitizer for this binary as it has too many leaks that are not
+// very interesting to fix. See compiler-rt/include/sanitizer/lsan_interface.h .
+int __lsan_is_turned_off() { return 1; }
+#endif  // __has_feature(address_sanitizer)
+#endif  // defined(__has_feature)
diff --git a/utils/TableGen/TableGenBackends.h b/utils/TableGen/TableGenBackends.h
index 8904287..78745f1 100644
--- a/utils/TableGen/TableGenBackends.h
+++ b/utils/TableGen/TableGenBackends.h
@@ -29,16 +29,15 @@
 void EmitClangASTNodes(RecordKeeper &RK, raw_ostream &OS,
                        const std::string &N, const std::string &S);
 
+void EmitClangAttrParserStringSwitches(RecordKeeper &Records, raw_ostream &OS);
 void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS);
-void EmitClangAttrIdentifierArgList(RecordKeeper &Records, raw_ostream &OS);
-void EmitClangAttrTypeArgList(RecordKeeper &Records, raw_ostream &OS);
 void EmitClangAttrImpl(RecordKeeper &Records, raw_ostream &OS);
 void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS);
 void EmitClangAttrPCHRead(RecordKeeper &Records, raw_ostream &OS);
 void EmitClangAttrPCHWrite(RecordKeeper &Records, raw_ostream &OS);
-void EmitClangAttrSpellingList(RecordKeeper &Records, raw_ostream &OS);
+void EmitClangAttrHasAttrImpl(RecordKeeper &Records, raw_ostream &OS);
 void EmitClangAttrSpellingListIndex(RecordKeeper &Records, raw_ostream &OS);
-void EmitClangAttrLateParsedList(RecordKeeper &Records, raw_ostream &OS);
+void EmitClangAttrASTVisitor(RecordKeeper &Records, raw_ostream &OS);
 void EmitClangAttrTemplateInstantiate(RecordKeeper &Records, raw_ostream &OS);
 void EmitClangAttrParsedAttrList(RecordKeeper &Records, raw_ostream &OS);
 void EmitClangAttrParsedAttrImpl(RecordKeeper &Records, raw_ostream &OS);
@@ -62,5 +61,10 @@
 void EmitNeon(RecordKeeper &Records, raw_ostream &OS);
 void EmitNeonSema(RecordKeeper &Records, raw_ostream &OS);
 void EmitNeonTest(RecordKeeper &Records, raw_ostream &OS);
+void EmitNeon2(RecordKeeper &Records, raw_ostream &OS);
+void EmitNeonSema2(RecordKeeper &Records, raw_ostream &OS);
+void EmitNeonTest2(RecordKeeper &Records, raw_ostream &OS);
+
+void EmitClangAttrDocs(RecordKeeper &Records, raw_ostream &OS);
 
 } // end namespace clang
diff --git a/utils/analyzer/SATestBuild.py b/utils/analyzer/SATestBuild.py
index 51bc6e2..441032e 100755
--- a/utils/analyzer/SATestBuild.py
+++ b/utils/analyzer/SATestBuild.py
@@ -168,7 +168,7 @@
 SBOutputDirReferencePrefix = "Ref"
 
 # The list of checkers used during analyzes.
-# Currently, consists of all the non experimental checkers, plus a few alpha
+# Currently, consists of all the non-experimental checkers, plus a few alpha
 # checkers we don't want to regress on.
 Checkers="alpha.unix.SimpleStream,alpha.security.taint,alpha.cplusplus.NewDeleteLeaks,core,cplusplus,deadcode,security,unix,osx"
 
@@ -363,7 +363,7 @@
     if TotalFailed == 0:
         CleanUpEmptyPlists(SBOutputDir)
         Plists = glob.glob(SBOutputDir + "/*/*.plist")
-        print "Number of bug reports (non empty plist files) produced: %d" %\
+        print "Number of bug reports (non-empty plist files) produced: %d" %\
            len(Plists)
         return;
     
diff --git a/utils/clang.natvis b/utils/clang.natvis
new file mode 100644
index 0000000..107af50
--- /dev/null
+++ b/utils/clang.natvis
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>

+<!--

+Visual Studio 2012 Native Debugging Visualizers for LLVM

+

+Put this file into "%USERPROFILE%\Documents\Visual Studio 2012\Visualizers"

+or create a symbolic link so it updates automatically.

+-->

+<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">

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

+    <DisplayString Condition="Entry != 0">({((llvm::StringMapEntry&lt;clang::IdentifierInfo *&gt;*)Entry)+1,s})</DisplayString>

+    <Expand>

+      <Item Condition="Entry != 0" Name="[Identifier]">((llvm::StringMapEntry&lt;clang::IdentifierInfo *&gt;*)Entry)+1,s</Item>

+      <Item Name="Token Kind">(clang::tok::TokenKind)TokenID</Item>

+    </Expand>

+  </Type>

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

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

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

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

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

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

+    <Expand>

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

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

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

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

+    </Expand>

+  </Type>

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

+    <DisplayString>{(clang::tok::TokenKind)Kind}</DisplayString>

+  </Type>

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

+    <DisplayString>[{(clang::DeclSpec::SCS)StorageClassSpec}], [{(clang::TypeSpecifierType)TypeSpecType}]</DisplayString>

+  </Type>

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

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

+  </Type>

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

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

+  </Type>

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

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

+  </Type>

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

+    <Expand>

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

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

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

+    </Expand>

+  </Type>

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

+    <DisplayString>{Name}</DisplayString>

+    <Expand>

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

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

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

+    </Expand>

+  </Type>

+</AutoVisualizer>

diff --git a/utils/clangVisualizers.txt b/utils/clangVisualizers.txt
deleted file mode 100644
index 8019b9c..0000000
--- a/utils/clangVisualizers.txt
+++ /dev/null
@@ -1,391 +0,0 @@
-
-[Visualizer]
-
-llvm::SmallVector<*,*>{
-	preview (
-		#if ((($T1*)$e.EndX - ($T1*)$e.BeginX) == 0) ( "empty" )
-		#else (
-			#(
-				"[",
-				($T1*)$e.EndX - ($T1*)$e.BeginX,
-				"](",
-				#array(
-					expr: (($T1*)$e.BeginX)[$i],
-					size: ($T1*)$e.EndX - ($T1*)$e.BeginX
-				),
-				")"
-			)
-		)
-	)
-
-	children (
-		#(
-			#([size] : ($T1*)$e.EndX - ($T1*)$e.BeginX),
-			#([capacity] : ($T1*)$e.CapacityX - ($T1*)$e.BeginX),
-			#array(
-				expr: (($T1*)$e.BeginX)[$i],
-				size: ($T1*)$e.EndX - ($T1*)$e.BeginX
-			)
-		)
-	)
-}
-
-llvm::SmallVectorImpl<*>{
-	preview (
-		#if ((($T1*)$e.EndX - ($T1*)$e.BeginX) == 0) ( "empty" )
-		#else (
-			#(
-				"[",
-				($T1*)$e.EndX - ($T1*)$e.BeginX,
-				"](",
-				#array(
-					expr: (($T1*)$e.BeginX)[$i],
-					size: ($T1*)$e.EndX - ($T1*)$e.BeginX
-				),
-				")"
-			)
-		)
-	)
-
-	children (
-		#(
-			#([size] : ($T1*)$e.EndX - ($T1*)$e.BeginX),
-			#([capacity] : ($T1*)$e.CapacityX - ($T1*)$e.BeginX),
-			#array(
-				expr: (($T1*)$e.BeginX)[$i],
-				size: ($T1*)$e.EndX - ($T1*)$e.BeginX
-			)
-		)
-	)
-}
-
-llvm::SmallString<*>{
-	preview ([$e.BeginX,s])
-	stringview ([$e.BeginX,sb])
-}
-
-llvm::StringRef{
-	preview ([$e.Data,s])
-	stringview ([$e.Data,sb])
-
-	children (
-		#(
-			#([size] : $e.Length),
-			#array(expr: $e.Data[$i], size: $e.Length)
-		)
-	)
-}
-
-clang::Token{
-	preview((clang::tok::TokenKind)(int)$e.Kind)
-}
-
-llvm::PointerIntPair<*,*,*,*>{
-	preview (
-		#(
-			($T1*)($e.Value & $e.PointerBitMask),
-			" [",
-			($T3)(($e.Value >> $e.IntShift) & $e.IntMask),
-			"]"
-		)
-	)
-	
-	children (
-		#(
-			#([raw members] : [$e,!]),
-			#([ptr] : ($T1*)($e.Value & $e.PointerBitMask)),
-			#([int] : ($T3)($e.Value >> $e.IntShift) & $e.IntMask)
-		)
-	)
-}
-
-llvm::PointerUnion<*,*>{
-	preview (
-		#if ((($e.Val.Value >> $e.Val.IntShift) & $e.Val.IntMask) == 0) ( "PT1" )
-		#else ( "PT2" )
-	)
-	
-	children (
-		#(
-			#([raw members] : [$e,!]),
-			#if ((($e.Val.Value >> $e.Val.IntShift) & $e.Val.IntMask) == 0) (
-				#([ptr] : ($T1)($e.Val.Value & $e.Val.PointerBitMask))
-			) #else (
-				#([ptr] : ($T2)($e.Val.Value & $e.Val.PointerBitMask))
-			)
-		)
-	)
-}
-
-llvm::PointerUnion3<*,*,*>{
-	preview (
-		#if (($e.Val.Val.Value & 0x2) == 2) ( "PT2" )
-		#elif (($e.Val.Val.Value & 0x1) == 1) ( "PT3" )
-		#else ( "PT1" )
-	)
-	
-	children (
-		#(
-			#if (($e.Val.Val.Value & 0x2) == 2) (
-				#([ptr] : ($T2)(($e.Val.Val.Value >> 2) << 2))
-			) #elif (($e.Val.Val.Value & 0x1) == 1) (
-				#([ptr] : ($T3)(($e.Val.Val.Value >> 2) << 2))
-			) #else (
-				#([ptr] : ($T1)(($e.Val.Val.Value >> 2) << 2))
-			)
-		)
-	)
-}
-
-llvm::PointerUnion4<*,*,*,*>{
-	preview (
-		#if (($e.Val.Val.Value & 0x3) == 3) ( "PT4" )
-		#elif (($e.Val.Val.Value & 0x2) == 2) ( "PT2" )
-		#elif (($e.Val.Val.Value & 0x1) == 1) ( "PT3" )
-		#else ( "PT1" )
-	)
-	
-	children (
-		#(
-			#if (($e.Val.Val.Value & 0x3) == 3) (
-				#([ptr] : ($T4)(($e.Val.Val.Value >> 2) << 2))
-			) #elif (($e.Val.Val.Value & 0x2) == 2) (
-				#([ptr] : ($T2)(($e.Val.Val.Value >> 2) << 2))
-			) #elif (($e.Val.Val.Value & 0x1) == 1) (
-				#([ptr] : ($T3)(($e.Val.Val.Value >> 2) << 2))
-			) #else (
-				#([ptr] : ($T1)(($e.Val.Val.Value >> 2) << 2))
-			)
-		)
-	)
-}
-
-llvm::IntrusiveRefCntPtr<*>{
-	preview (
-		#if ($e.Obj == 0) ( "empty" )
-		#else (
-			#(
-				"[RefCnt=", $e.Obj->ref_cnt,
-				", ",
-				"Obj=", $e.Obj,
-				"]"
-			)
-		)
-	)
-
-	children (
-		#if ($e.Obj == 0) ( #array(expr: 0, size: 0) )
-		#else (
-			#(
-				#(RefCnt : $e.Obj->ref_cnt),
-				#(Obj : $e.Obj)
-			)
-		)
-	)
-}
-
-llvm::OwningPtr<*>{
-	preview (
-		#if ($e.Ptr == 0) ( "empty" )
-		#else ( $e.Ptr )
-	)
-
-	children (
-		#if ($e.Ptr == 0) ( #array(expr: 0, size: 0) )
-		#else ( #(Ptr : $e.Ptr) )
-	)	
-}
-
-llvm::SmallPtrSet<*,*>{
-	preview (
-		#(
-			#if (($e.CurArray) == ($e.SmallArray)) ( "[Small Mode] " )
-			#else ( "[Big Mode] " ),
-			"NumElements=", $e.NumElements,
-			" CurArraySize=", $e.CurArraySize
-		)
-	)
-
-	children (
-		#(
-			#([raw members] : [$c,!]),
-			#(NumElements : $e.NumElements),
-			#(CurArraySize : $e.CurArraySize),
-			#array(
-				expr: $e.CurArray[$i],
-				size: $e.CurArraySize + 1
-			) : ($T1*)&$e
-		)
-	)
-}
-
-llvm::DenseMap<*,*,*>{
-	preview (
-		#if ($e.NumEntries == 0) ( "empty" )
-		#else (
-			#(
-				"[NumEntries=", $e.NumEntries,
-				" NumBuckets=", $e.NumBuckets,
-				"]"
-			)
-		)
-	)
-
-	children (
-		#if ($e.NumEntries == 0) ( #array(expr: 0, size: 0) )
-		#else (
-			#(
-				#([raw members] : [$c,!]),
-				#(NumEntries : $e.NumEntries),
-				#(NumBuckets : $e.NumBuckets),
-				#array(
-					expr: $e.Buckets[$i],
-					size: $e.NumBuckets
-				)
-			)
-		)
-	)
-}
-
-llvm::StringMap<*,*>{
-	preview (
-		#(
-			"[NumBuckets=", $e.NumBuckets,
-			" ItemSize=", $e.ItemSize,
-			"]"
-		)
-	)
-
-	children (
-		#(
-			#([raw members] : [$c,!]),
-			#(NumBuckets : $e.NumBuckets),
-			#(ItemSize : $e.ItemSize),
-			#array(
-				expr: $e.TheTable[$i],
-				size: $e.NumBuckets,
-			) : (llvm::StringMapEntry<$T1>*)&$e
-		)
-	)
-}
-
-llvm::StringMapEntry<*>{
-	preview (
-		#if ($e.StrLen == 0) ( "empty" )
-		#else (	#(Entry : $e.second) )
-	)
-
-	children (
-		#if ($e.StrLen == 0) ( "empty" )
-		#else ( #(Entry : $e.second) )	
-	)
-}
-
-clang::DirectoryEntry|clang::FileEntry|clang::PragmaHandler{
-	preview ( [$e.Name,s] )
-	children (
-		#(
-			#([raw members] : [$c,!]),
-			#(Name : [$e.Name,s])
-		)
-	)
-}
-
-clang::DeclarationName{
-	preview (
-		; enum values from clang::DeclarationName::StoredNameKind
-		#if ($e.Ptr == 0) (
-			"empty"
-		) #elif (($e.Ptr & $e.PtrMask) == $e.StoredIdentifier) (
-			#else ( #("Identifier, ", (clang::IdentifierInfo*)($e.Ptr & ~$e.PtrMask)) )
-		) #elif (($e.Ptr & $e.PtrMask) == $e.StoredObjCZeroArgSelector) (
-			#("ZeroArgSelector, ", (clang::IdentifierInfo*)($e.Ptr & ~$e.PtrMask))
-		) #elif (($e.Ptr & $e.PtrMask) == $e.StoredObjCOneArgSelector) (
-			#("OneArgSelector, ", (clang::IdentifierInfo*)($e.Ptr & ~$e.PtrMask))
-		) #elif (($e.Ptr & $e.PtrMask) == $e.StoredDeclarationNameExtra) (
-			#switch (((clang::DeclarationNameExtra*)($e.Ptr & ~$e.PtrMask)).ExtraKindOrNumArgs)
-			#case 0 ( ;DeclarationNameExtra::CXXConstructor
-				#("CXXConstructorName, ", (clang::CXXSpecialName*)($e.Ptr & ~$e.PtrMask))
-			)
-			#case 1 ( ;DeclarationNameExtra::CXXDestructor
-				#("CXXDestructorName, ", (clang::CXXSpecialName*)($e.Ptr & ~$e.PtrMask))
-			)
-			#case 2 ( ;DeclarationNameExtra::CXXConversionFunction
-				#("CXXConversionFunctionName, ", (clang::CXXSpecialName*)($e.Ptr & ~$e.PtrMask))
-			)
-			#case 46 ( ;DeclarationNameExtra::CXXLiteralOperator
-				#("CXXLiteralOperatorName, ", (clang::CXXLiteralOperatorIdName*)($e.Ptr & ~$e.PtrMask))
-			)
-			#case 47 ( ;DeclarationNameExtra::CXXUsingDirective
-				#("CXXUsingDirective")	;TODO What to add here?
-			)
-			#default (
-				#if (((clang::DeclarationNameExtra*)($e.Ptr & ~$e.PtrMask)).ExtraKindOrNumArgs < 47) (
-					#("CXXOperatorName, ", (clang::CXXOperatorIdName*)($e.Ptr & ~$e.PtrMask))
-				) #else (
-					#("ObjCMultiArgSelector, ", (clang::MultiKeywordSelector*)($e.Ptr & ~$e.PtrMask))
-				)
-			)
-		)
-	)
-
-	children (
-		#(
-			; enum values from clang::DeclarationName::StoredNameKind
-			#if ($e.Ptr == 0) (
-				#array( expr: 0, size: 0 )
-			) #else (
-				#(
-					#([raw members] : [$e.Ptr,!]),
-					if (($e.Ptr & $e.PtrMask) == $e.StoredIdentifier) (
-						#(Ptr : (clang::IdentifierInfo*)($e.Ptr & ~$e.PtrMask))
-					) #elif (($e.Ptr & $e.PtrMask) == $e.StoredObjCZeroArgSelector) (
-						#(Ptr : (clang::IdentifierInfo*)($e.Ptr & ~$e.PtrMask))
-					) #elif (($e.Ptr & $e.PtrMask) == $e.StoredObjCOneArgSelector) (
-						#(Ptr : (clang::IdentifierInfo*)($e.Ptr & ~$e.PtrMask))
-					) #elif (($e.Ptr & $e.PtrMask) == $e.StoredDeclarationNameExtra) (
-						#switch (((clang::DeclarationNameExtra*)($e.Ptr & ~$e.PtrMask)).ExtraKindOrNumArgs)
-						#case 0 ( ;DeclarationNameExtra::CXXConstructor
-							#(Ptr : (clang::CXXSpecialName*)($e.Ptr & ~$e.PtrMask))
-						)
-						#case 1 ( ;DeclarationNameExtra::CXXDestructor
-							#(Ptr : (clang::CXXSpecialName*)($e.Ptr & ~$e.PtrMask))
-						)
-						#case 2 ( ;DeclarationNameExtra::CXXConversionFunction
-							#(Ptr : (clang::CXXSpecialName*)($e.Ptr & ~$e.PtrMask))
-						)
-						#case 46 ( ;DeclarationNameExtra::CXXLiteralOperator
-							#(Ptr : (clang::CXXLiteralOperatorIdName*)($e.Ptr & ~$e.PtrMask))
-						)
-						#case 47 ( ;DeclarationNameExtra::CXXUsingDirective
-							#(Ptr : $e.Ptr)	;TODO What to add here?
-						)
-						#default (
-							#if (((clang::DeclarationNameExtra*)($e.Ptr & ~$e.PtrMask)).ExtraKindOrNumArgs < 47) (
-								#(Ptr : (CXXOperatorIdName*)($e.Ptr & ~$e.PtrMask))
-							) #else (
-								#(Ptr : (clang::MultiKeywordSelector*)($e.Ptr & ~$e.PtrMask))
-							)
-						)
-					)
-				)
-			)
-		)
-	)
-}
-
-clang::DeclSpec{
-	preview (
-		#(
-			"[",
-			(clang::DeclSpec::SCS)$e.StorageClassSpec,
-			", ",
-			(clang::TypeSpecifierType)$e.TypeSpecType,
-			"]"
-		)
-	)
-}
-
-llvm::Triple{
-	preview ( $e.Data )
-}
diff --git a/www/analyzer/alpha_checks.html b/www/analyzer/alpha_checks.html
new file mode 100644
index 0000000..6f5e4f1
--- /dev/null
+++ b/www/analyzer/alpha_checks.html
@@ -0,0 +1,848 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <title>Alpha Checks</title>
+  <link type="text/css" rel="stylesheet" href="menu.css">
+  <link type="text/css" rel="stylesheet" href="content.css">
+  <script type="text/javascript" src="scripts/menu.js"></script>
+  <script type="text/javascript" src="scripts/expandcollapse.js"></script>
+  <style type="text/css">
+  tr:first-child { width:20%; }
+  </style>
+</head>
+<body onload="initExpandCollapse()">
+
+<div id="page">
+<!--#include virtual="menu.html.incl"-->
+
+<div id="content">
+<h1>Alpha Checkers</h1>
+Experimental checkers in addition to the <a href = "available_checks.html">
+Default Checkers</a>. These are checkers with known issues or limitations that
+keep them from being on by default. They are likely to have false positives.
+Bug reports are welcome but will likely not be investigated for some time.
+Patches welcome!
+<ul>
+<li><a href="#core_alpha_checkers">Core Alpha Checkers</a></li>
+<li><a href="#cplusplus_alpha_checkers">C++ Alpha Checkers</a></li>
+<li><a href="#deadcode_alpha_checkers">Dead Code Alpha Checkers</a></li>
+<li><a href="#osx_alpha_checkers">OS X Alpha Checkers</a></li>
+<li><a href="#security_alpha_checkers">Security Alpha Checkers</a></li>
+<li><a href="#unix_alpha_checkers">Unix Alpha Checkers</a></li>
+</ul>
+
+<!------------------------------ core alpha ----------------------------------->
+<h3 id="core_alpha_checkers">Core Alpha Checkers</h3>
+<table class="checkers">
+<colgroup><col class="namedescr"><col class="example"></colgroup>
+<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
+
+<tbody>
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.core.BoolAssignment</span><span class="lang">
+(ObjC)</span><div class="descr">
+Warn about assigning non-{0,1} values to boolean variables.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  BOOL b = -1; // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.core.CastSize</span><span class="lang">
+(C)</span><div class="descr">
+Check when casting a malloc'ed type T, whether the size is a multiple of the 
+size of T (Works only with <span class="name">unix.Malloc</span>
+or <span class="name">alpha.unix.MallocWithAnnotations</span> 
+checks enabled).</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  int *x = (int *)malloc(11); // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.core.CastToStruct</span><span class="lang">
+(C, C++)</span><div class="descr">
+Check for cast from non-struct pointer to struct pointer.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+// C
+struct s {};
+
+void test(int *p) {
+  struct s *ps = (struct s *) p; // warn
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+// C++
+class c {};
+
+void test(int *p) {
+  c *pc = (c *) p; // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.core.FixedAddr</span><span class="lang">
+(C)</span><div class="descr">
+Check for assignment of a fixed address to a pointer.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  int *p;
+  p = (int *) 0x10000; // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.core.IdenticalExpr</span><span class="lang">
+(C, C++)</span><div class="descr">
+Warn about suspicious uses of identical expressions.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+// C
+void test() {
+  int a = 5;
+  int b = a | 4 | a; // warn: identical expr on both sides
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+// C++
+bool f(void);
+
+void test(bool b) {
+  int i = 10;
+  if (f()) { // warn: true and false branches are identical
+    do {
+      i--;
+    } while (f());
+  } else {
+    do {
+      i--;
+    } while (f());
+  }
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.core.PointerArithm</span><span class="lang">
+(C)</span><div class="descr">
+Check for pointer arithmetic on locations other than array 
+elements.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  int x;
+  int *p;
+  p = &amp;x + 1; // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.core.PointerSub</span><span class="lang">
+(C)</span><div class="descr">
+Check for pointer subtractions on two pointers pointing to different memory 
+chunks.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  int x, y;
+  int d = &amp;y - &amp;x; // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.core.SizeofPtr</span><span class="lang">
+(C)</span><div class="descr">
+Warn about unintended use of <code>sizeof()</code> on pointer 
+expressions.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+struct s {};
+
+int test(struct s *p) {
+  return sizeof(p); 
+    // warn: sizeof(ptr) can produce an unexpected result
+}
+</pre></div></div></td></tr>
+
+</tbody></table>
+
+<!--------------------------- cplusplus alpha --------------------------------->
+<h3 id="cplusplus_alpha_checkers">C++ Alpha Checkers</h3>
+<table class="checkers">
+<colgroup><col class="namedescr"><col class="example"></colgroup>
+<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
+
+<tbody>
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.cplusplus.NewDeleteLeaks</span><span class="lang">
+(C++)</span><div class="descr">
+Check for memory leaks. Traces memory managed by <code>new</code>/<code>
+delete</code>.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  int *p = new int;
+} // warn
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.cplusplus.VirtualCall</span><span class="lang">
+(C++)</span><div class="descr">
+Check virtual member function calls during construction or 
+destruction.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+class A {
+public:
+  A() { 
+    f(); // warn
+  }
+  virtual void f();
+};
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+class A {
+public:
+  ~A() {
+    this-&gt;f(); // warn
+  }
+  virtual void f();
+};
+</pre></div></div></td></tr>
+
+</tbody></table>
+
+<!--------------------------- dead code alpha --------------------------------->
+<h3 id="deadcode_alpha_checkers">Dead Code Alpha Checkers</h3>
+<table class="checkers">
+<colgroup><col class="namedescr"><col class="example"></colgroup>
+<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
+
+<tbody>
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.deadcode.UnreachableCode</span><span class="lang">
+(C, C++, ObjC)</span><div class="descr">
+Check unreachable code.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+// C
+int test() {
+  int x = 1;
+  while(x);
+  return x; // warn
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+// C++
+void test() {
+  int a = 2;
+
+  while (a > 1)
+    a--;
+
+  if (a > 1)
+    a++; // warn
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+// Objective-C
+void test(id x) {
+  return;
+  [x retain]; // warn
+}
+</pre></div></div></td></tr>
+</tbody></table>
+
+<!---------------------------- OS X alpha -------------------------------------->
+<h3 id="osx_alpha_checkers">OS X Alpha Checkers</h3>
+<table class="checkers">
+<colgroup><col class="namedescr"><col class="example"></colgroup>
+<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
+
+<tbody>
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.osx.cocoa.Dealloc</span><span class="lang">
+(ObjC)</span><div class="descr">
+Warn about Objective-C classes that lack a correct implementation 
+of <code>-dealloc</code>.
+</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+@interface MyObject : NSObject {
+  id _myproperty;  
+}
+@end
+
+@implementation MyObject // warn: lacks 'dealloc'
+@end
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+@interface MyObject : NSObject {}
+@property(assign) id myproperty;
+@end
+
+@implementation MyObject // warn: does not send 'dealloc' to super
+- (void)dealloc {
+  self.myproperty = 0;
+}
+@end
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+@interface MyObject : NSObject {
+  id _myproperty;
+}
+@property(retain) id myproperty;
+@end
+
+@implementation MyObject
+@synthesize myproperty = _myproperty;
+  // warn: var was retained but wasn't released
+- (void)dealloc {
+  [super dealloc];
+}
+@end
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+@interface MyObject : NSObject {
+  id _myproperty;
+}
+@property(assign) id myproperty;
+@end
+
+@implementation MyObject
+@synthesize myproperty = _myproperty;
+  // warn: var wasn't retained but was released
+- (void)dealloc {
+  [_myproperty release];
+  [super dealloc];
+}
+@end
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.osx.cocoa.DirectIvarAssignment</span><span class="lang">
+(ObjC)</span><div class="descr">
+Check that Objective C properties follow the following rule: the property 
+should be set with the setter, not though a direct assignment.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+@interface MyClass : NSObject {}
+@property (readonly) id A;
+- (void) foo;
+@end
+
+@implementation MyClass
+- (void) foo {
+  _A = 0; // warn
+}
+@end
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.osx.cocoa.DirectIvarAssignmentForAnnotatedFunctions</span><span class="lang">
+(ObjC)</span><div class="descr">
+Check for direct assignments to instance variables in the methods annotated 
+with <code>objc_no_direct_instance_variable_assignment</code>.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+@interface MyClass : NSObject {}
+@property (readonly) id A;
+- (void) fAnnotated __attribute__((
+    annotate("objc_no_direct_instance_variable_assignment")));
+- (void) fNotAnnotated;
+@end
+
+@implementation MyClass
+- (void) fAnnotated {
+  _A = 0; // warn
+}
+- (void) fNotAnnotated {
+  _A = 0; // no warn
+}
+@end
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.osx.cocoa.InstanceVariableInvalidation</span><span class="lang">
+(ObjC)</span><div class="descr">
+Check that the invalidatable instance variables are invalidated in the methods
+annotated with <code>objc_instance_variable_invalidator</code>.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+@protocol Invalidation &lt;NSObject&gt;
+- (void) invalidate 
+  __attribute__((annotate("objc_instance_variable_invalidator")));
+@end 
+
+@interface InvalidationImpObj : NSObject &lt;Invalidation&gt;
+@end
+
+@interface SubclassInvalidationImpObj : InvalidationImpObj {
+  InvalidationImpObj *var;
+}
+- (void)invalidate;
+@end
+
+@implementation SubclassInvalidationImpObj
+- (void) invalidate {}
+@end
+// warn: var needs to be invalidated or set to nil
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.osx.cocoa.MissingInvalidationMethod</span><span class="lang">
+(ObjC)</span><div class="descr">
+Check that the invalidation methods are present in classes that contain 
+invalidatable instance variables.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+@protocol Invalidation &lt;NSObject&gt;
+- (void)invalidate 
+  __attribute__((annotate("objc_instance_variable_invalidator")));
+@end
+
+@interface NeedInvalidation : NSObject &lt;Invalidation&gt;
+@end
+
+@interface MissingInvalidationMethodDecl : NSObject {
+  NeedInvalidation *Var; // warn
+}
+@end
+
+@implementation MissingInvalidationMethodDecl
+@end
+</pre></div></div></td></tr>
+
+</tbody></table>
+
+<!------------------------- security alpha ------------------------------------>
+<h3 id="security_alpha_checkers">Security Alpha Checkers</h3>
+<table class="checkers">
+<colgroup><col class="namedescr"><col class="example"></colgroup>
+<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
+
+<tbody>
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.security.ArrayBound</span><span class="lang">
+(C)</span><div class="descr">
+Warn about buffer overflows (older checker).</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  char *s = "";
+  char c = s[1]; // warn
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+struct seven_words {
+  int c[7];
+};
+
+void test() {
+  struct seven_words a, *p;
+  p = &a;
+  p[0] = a;
+  p[1] = a;
+  p[2] = a; // warn
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+// note: requires unix.Malloc or 
+// alpha.unix.MallocWithAnnotations checks enabled.
+void test() {
+  int *p = malloc(12);
+  p[3] = 4; // warn
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+void test() {
+  char a[2];
+  int *b = (int*)a;
+  b[1] = 3; // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.security.ArrayBoundV2</span><span class="lang">
+(C)</span><div class="descr">
+Warn about buffer overflows (newer checker).</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  char *s = "";
+  char c = s[1]; // warn
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+void test() {
+  int buf[100];
+  int *p = buf;
+  p = p + 99;
+  p[1] = 1; // warn
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+// note: compiler has internal check for this.
+// Use -Wno-array-bounds to suppress compiler warning.
+void test() {
+  int buf[100][100];
+  buf[0][-1] = 1; // warn
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+// note: requires alpha.security.taint check turned on.
+void test() {
+  char s[] = "abc";
+  int x = getchar();
+  char c = s[x]; // warn: index is tainted
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.security.MallocOverflow</span><span class="lang">
+(C)</span><div class="descr">
+Check for overflows in the arguments to <code>malloc()</code>.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test(int n) {
+  void *p = malloc(n * sizeof(int)); // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.security.ReturnPtrRange</span><span class="lang">
+(C)</span><div class="descr">
+Check for an out-of-bound pointer being returned to callers.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+static int A[10];
+
+int *test() {
+  int *p = A + 10;
+  return p; // warn
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+int test(void) {
+  int x;
+  return x; // warn: undefined or garbage returned
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.security.taint.TaintPropagation</span><span class="lang">
+(C)</span><div class="descr">
+Generate taint information used by other checkers.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  char x = getchar(); // 'x' marked as tainted
+  system(&x); // warn: untrusted data is passed to a system call
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+// note: compiler internally checks if the second param to
+// sprintf is a string literal or not. 
+// Use -Wno-format-security to suppress compiler warning.
+void test() {
+  char s[10], buf[10];
+  fscanf(stdin, "%s", s); // 's' marked as tainted
+
+  sprintf(buf, s); // warn: untrusted data as a format string
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+void test() {
+  size_t ts;
+  scanf("%zd", &ts); // 'ts' marked as tainted
+  int *p = (int *)malloc(ts * sizeof(int)); 
+    // warn: untrusted data as bufer size
+}
+</pre></div></div></td></tr>
+
+</tbody></table>
+
+<!--------------------------- unix alpha -------------------------------------->
+<h3 id="unix_alpha_checkers">Unix Alpha Checkers</h3>
+<table class="checkers">
+<colgroup><col class="namedescr"><col class="example"></colgroup>
+<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
+
+<tbody>
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.unix.Chroot</span><span class="lang">
+(C)</span><div class="descr">
+Check improper use of <code>chroot</code>.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void f();
+
+void test() {
+  chroot("/usr/local");
+  f(); // warn: no call of chdir("/") immediately after chroot
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.unix.MallocWithAnnotations</span><span class="lang">
+(C)</span><div class="descr">
+Check for memory leaks, double free, and use-after-free problems. Assumes that
+all user-defined functions which might free a pointer are
+annotated.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void __attribute((ownership_returns(malloc))) *my_malloc(size_t);
+
+void test() {
+  int *p = my_malloc(1);
+} // warn: potential leak
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+void __attribute((ownership_returns(malloc))) *my_malloc(size_t);
+void __attribute((ownership_takes(malloc, 1))) my_free(void *);
+
+void test() {
+  int *p = my_malloc(1);
+  my_free(p);
+  my_free(p); // warn: attempt to free released
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+void __attribute((ownership_returns(malloc))) *my_malloc(size_t);
+void __attribute((ownership_holds(malloc, 1))) my_hold(void *);
+
+void test() {
+  int *p = my_malloc(1);
+  my_hold(p);
+  free(p); // warn: attempt to free non-owned memory
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+void __attribute((ownership_takes(malloc, 1))) my_free(void *);
+
+void test() {
+  int *p = malloc(1);
+  my_free(p);
+  *p = 1; // warn: use after free
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.unix.PthreadLock</span><span class="lang">
+(C)</span><div class="descr">
+Simple lock -> unlock checker; applies to:<div class=functions>
+pthread_mutex_lock<br>
+pthread_rwlock_rdlock<br>
+pthread_rwlock_wrlock<br>
+lck_mtx_lock<br>
+lck_rw_lock_exclusive<br>
+lck_rw_lock_shared<br>
+pthread_mutex_trylock<br>
+pthread_rwlock_tryrdlock<br>
+pthread_rwlock_tryrwlock<br>
+lck_mtx_try_lock<br>
+lck_rw_try_lock_exclusive<br>
+lck_rw_try_lock_shared<br>
+pthread_mutex_unlock<br>
+pthread_rwlock_unlock<br>
+lck_mtx_unlock<br>
+lck_rw_done</div></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+pthread_mutex_t mtx;
+
+void test() {
+  pthread_mutex_lock(&mtx);
+  pthread_mutex_lock(&mtx); 
+    // warn: this lock has already been acquired
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+lck_mtx_t lck1, lck2;
+
+void test() {
+  lck_mtx_lock(&lck1);
+  lck_mtx_lock(&lck2);
+  lck_mtx_unlock(&lck1); 
+    // warn: this was not the most recently acquired lock
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+lck_mtx_t lck1, lck2;
+
+void test() {
+  if (lck_mtx_try_lock(&lck1) == 0)
+    return;
+
+  lck_mtx_lock(&lck2);
+  lck_mtx_unlock(&lck1);
+    // warn: this was not the most recently acquired lock
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.unix.SimpleStream</span><span class="lang">
+(C)</span><div class="descr">
+Check for misuses of stream APIs:<div class=functions>
+fopen<br>
+fclose</div>(demo checker, the subject of the demo
+(<a href="http://llvm.org/devmtg/2012-11/Zaks-Rose-Checker24Hours.pdf">Slides</a>
+,<a href="http://llvm.org/devmtg/2012-11/videos/Zaks-Rose-Checker24Hours.mp4">Video</a>) 
+by Anna Zaks and Jordan Rose presented at the <a href="http://llvm.org/devmtg/2012-11/">
+2012 LLVM Developers' Meeting).</a></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  FILE *F = fopen("myfile.txt", "w");
+} // warn: opened file is never closed
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+void test() {
+  FILE *F = fopen("myfile.txt", "w");
+
+  if (F)
+    fclose(F);
+
+  fclose(F); // warn: closing a previously closed file stream
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.unix.Stream</span><span class="lang">
+(C)</span><div class="descr">
+Check stream handling functions:<div class=functions>fopen<br>
+tmpfile<br>
+fclose<br>
+fread<br>
+fwrite<br>
+fseek<br>
+ftell<br>
+rewind<br>
+fgetpos<br>
+fsetpos<br>
+clearerr<br>
+feof<br>
+ferror<br>
+fileno</div></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  FILE *p = fopen("foo", "r");
+} // warn: opened file is never closed
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+void test() {
+  FILE *p = fopen("foo", "r");
+  fseek(p, 1, SEEK_SET); // warn: stream pointer might be NULL
+  fclose(p); 
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+void test() {
+  FILE *p = fopen("foo", "r");
+
+  if (p)
+    fseek(p, 1, 3);
+     // warn: third arg should be SEEK_SET, SEEK_END, or SEEK_CUR
+
+  fclose(p); 
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+void test() {
+  FILE *p = fopen("foo", "r");
+  fclose(p); 
+  fclose(p); // warn: already closed
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+void test() {
+  FILE *p = tmpfile();
+  ftell(p); // warn: stream pointer might be NULL
+  fclose(p);
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.unix.cstring.BufferOverlap</span><span class="lang">
+(C)</span><div class="descr">
+Checks for overlap in two buffer arguments; applies to:<div class=functions>
+memcpy<br>
+mempcpy</div></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  int a[4] = {0};
+  memcpy(a + 2, a + 1, 8); // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.unix.cstring.NotNullTerminated</span><span class="lang">
+(C)</span><div class="descr">
+Check for arguments which are not null-terminated strings; applies
+to:<div class=functions>
+strlen<br>
+strnlen<br>
+strcpy<br>
+strncpy<br>
+strcat<br>
+strncat</div></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  int y = strlen((char *)&test); // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.unix.cstring.OutOfBounds</span><span class="lang">
+(C)</span><div class="descr">
+Check for out-of-bounds access in string functions; applies
+to:<div class=functions>
+strncopy<br>
+strncat</div></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test(char *y) {
+  char x[4];
+  if (strlen(y) == 4)
+    strncpy(x, y, 5); // warn
+}
+</pre></div></div></td></tr>
+
+</tbody></table>
+
+</div> <!-- page -->
+</div> <!-- content -->
+</body>
+</html>
diff --git a/www/analyzer/available_checks.html b/www/analyzer/available_checks.html
index 8c7d9e9..7707fc0 100644
--- a/www/analyzer/available_checks.html
+++ b/www/analyzer/available_checks.html
@@ -2,187 +2,30 @@
           "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 <head>
-  <title>Available Checks</title>
+  <title>Available Checkers</title>
   <link type="text/css" rel="stylesheet" href="menu.css">
   <link type="text/css" rel="stylesheet" href="content.css">
   <script type="text/javascript" src="scripts/menu.js"></script>
+  <script type="text/javascript" src="scripts/expandcollapse.js"></script>
   <style type="text/css">
   tr:first-child { width:20%; }
   </style>
 </head>
-<body>
+<body onload="initExpandCollapse()">
 
 <div id="page">
 <!--#include virtual="menu.html.incl"-->
 
 <div id="content">
-
-<h1>Available Checks</h1>
-
-<h3>The list of the checks the analyzer performs by default</h3>
-<p>
-<table border="0" cellpadding="3" cellspacing="3" width="100%">
-<!--  <tr>
-<th><h4>Checker Name</h4></th>
-<th><h4>Description</h4></th>
-</tr>-->
-<tr>
-<td><b>core.AdjustedReturnValue</b></td><td>Check to see if the return value of a function call is different than the caller expects (e.g., from calls through function pointers).</td>
-</tr>
-<tr>
-<td><b>core.CallAndMessage</b></td><td>Check for logical errors for function calls and Objective-C message expressions (e.g., uninitialized arguments, null function pointers).</td>
-</tr>
-<tr>
-<td><b>core.DivideZero</b></td><td>Check for division by zero.</td>
-</tr>
-<tr>
-<td><b>core.NonNullParamChecker</b></td><td>Check for null pointers passed as arguments to a function whose arguments are known to be non-null.</td>
-</tr>
-<tr>
-<td><b>core.NullDereference</b></td><td>Check for dereferences of null pointers.</td>
-</tr>
-<tr>
-<td><b>core.StackAddressEscape</b></td><td>Check that addresses to stack memory do not escape the function.</td>
-</tr>
-<tr>
-<td><b>core.UndefinedBinaryOperatorResult</b></td><td>Check for undefined results of binary operators.</td>
-</tr>
-<tr>
-<td><b>core.VLASize</b></td><td>Check for declarations of VLA of undefined or zero size.</td>
-</tr>
-<tr>
-<td><b>core.builtin.BuiltinFunctions</b></td><td>Evaluate compiler builtin functions (e.g., alloca()).</td>
-</tr>
-<tr>
-<td><b>core.builtin.NoReturnFunctions</b></td><td>Evaluate "panic" functions that are known to not return to the caller.</td>
-</tr>
-<tr>
-<td><b>core.uninitialized.ArraySubscript</b></td><td>Check for uninitialized values used as array subscripts.</td>
-</tr>
-<tr>
-<td><b>core.uninitialized.Assign</b></td><td>Check for assigning uninitialized values.</td>
-</tr>
-<tr>
-<td><b>core.uninitialized.Branch</b></td><td>Check for uninitialized values used as branch conditions.</td>
-</tr>
-<tr>
-<td><b>core.uninitialized.CapturedBlockVariable</b></td><td>Check for blocks that capture uninitialized values.</td>
-</tr>
-<tr>
-<td><b>core.uninitialized.UndefReturn</b></td><td>Check for uninitialized values being returned to the caller.</td>
-</tr>
-<tr>
-<td><b>cplusplus.NewDelete</b></td><td>Check for double-free and use-after-free problems involving C++ <code>delete</code>.</td>
-</tr>
-<tr>
-<td><b>deadcode.DeadStores</b></td><td>Check for values stored to variables that are never read afterwards.</td>
-</tr>
-<!-- 
-<tr>
-<td><b>deadcode.IdempotentOperations</b></td><td>Warn about idempotent operations.</td>
-</tr>
--->
-<tr>
-<td><b>osx.API</b></td><td>Check for proper uses of various Apple APIs.</td>
-</tr>
-<tr>
-<td><b>osx.SecKeychainAPI</b></td><td>Check for proper uses of Secure Keychain APIs.</td>
-</tr>
-<tr>
-<td><b>osx.cocoa.AtSync</b></td><td>Check for nil pointers used as mutexes for @synchronized.</td>
-</tr>
-<tr>
-<td><b>osx.cocoa.ClassRelease</b></td><td>Check for sending 'retain', 'release', or 'autorelease' directly to a Class.</td>
-</tr>
-<tr>
-<td><b>osx.cocoa.IncompatibleMethodTypes</b></td><td>Warn about Objective-C method signatures with type incompatibilities.</td>
-</tr>
-<tr>
-<td><b>osx.cocoa.NSAutoreleasePool</b></td><td>Warn for suboptimal uses of NSAutoreleasePool in Objective-C GC mode.</td>
-</tr>
-<tr>
-<td><b>osx.cocoa.NSError</b></td><td>Check usage of NSError** parameters.</td>
-</tr>
-<tr>
-<td><b>osx.cocoa.NilArg</b></td><td>Check for prohibited nil arguments to ObjC method calls.</td>
-</tr>
-<tr>
-<td><b>osx.cocoa.RetainCount</b></td><td>Check for leaks and improper reference count management.</td>
-</tr>
-<tr>
-<td><b>osx.cocoa.SelfInit</b></td><td>Check that 'self' is properly initialized inside an initializer method.</td>
-</tr>
-<tr>
-<td><b>osx.cocoa.UnusedIvars</b></td><td>Warn about private ivars that are never used.</td>
-</tr>
-<tr>
-<td><b>osx.cocoa.VariadicMethodTypes</b></td><td>Check for passing non-Objective-C types to variadic methods that expect only Objective-C types.</td>
-</tr>
-<tr>
-<td><b>osx.coreFoundation.CFError</b></td><td>Check usage of CFErrorRef* parameters.</td>
-</tr>
-<tr>
-<td><b>osx.coreFoundation.CFNumber</b></td><td>Check for proper uses of CFNumberCreate.</td>
-</tr>
-<tr>
-<td><b>osx.coreFoundation.CFRetainRelease</b></td><td>Check for null arguments to CFRetain/CFRelease/CFMakeCollectable.</td>
-</tr>
-<tr>
-<td><b>osx.coreFoundation.containers.OutOfBounds</b></td><td>Checks for index out-of-bounds when using 'CFArray' API.</td>
-</tr>
-<tr>
-<td><b>osx.coreFoundation.containers.PointerSizedValues</b></td><td>Warns if 'CFArray', 'CFDictionary', 'CFSet' are created with non-pointer-size values.</td>
-</tr>
-<tr>
-<td><b>security.FloatLoopCounter</b></td><td>Warn on using a floating point value as a loop counter (CERT: FLP30-C, FLP30-CPP).</td>
-</tr>
-<tr>
-<td><b>security.insecureAPI.UncheckedReturn</b></td><td>Warn on uses of functions whose return values must be always checked.</td>
-</tr>
-<tr>
-<td><b>security.insecureAPI.getpw</b></td><td>Warn on uses of the 'getpw' function.</td>
-</tr>
-<tr>
-<td><b>security.insecureAPI.gets</b></td><td>Warn on uses of the 'gets' function.</td>
-</tr>
-<tr>
-<td><b>security.insecureAPI.mkstemp</b></td><td>Warn when 'mkstemp' is passed fewer than 6 X's in the format string.</td>
-</tr>
-<tr>
-<td><b>security.insecureAPI.mktemp</b></td><td>Warn on uses of the 'mktemp' function.</td>
-</tr>
-<tr>
-<td><b>security.insecureAPI.rand</b></td><td>Warn on uses of the 'rand', 'random', and related functions.</td>
-</tr>
-<tr>
-<td><b>security.insecureAPI.strcpy</b></td><td>Warn on uses of the 'strcpy' and 'strcat' functions.</td>
-</tr>
-<tr>
-<td><b>security.insecureAPI.vfork</b></td><td>Warn on uses of the 'vfork' function.</td>
-</tr>
-<tr>
-<td><b>unix.API</b></td><td>Check calls to various UNIX/Posix functions.</td>
-</tr>
-<tr>
-<td><b>unix.Malloc</b></td><td>Check for memory leaks, double free, and use-after-free problems involving <code>malloc</code>.</td>
-</tr>
-<tr>
-<td><b>unix.MallocSizeof</b></td><td>Check for dubious malloc arguments involving sizeof.</td>
-</tr>
-<tr>
-<td><b>unix.MismatchedDeallocator</b></td><td>Check for mismatched deallocators (e.g. passing a pointer allocating with <code>new</code> to <code>free()</code>).</td>
-</tr>
-<tr>
-<td><b>unix.cstring.BadSizeArg</b></td><td>Check the size argument passed into C string functions for common erroneous patterns.</td>
-</tr>
-<tr>
-<td><b>unix.cstring.NullArg</b></td><td>Check for null pointers being passed as arguments to C string functions.</td>
-</table>
-
-<p>In addition to these the analyzer contains numerous experimental (alpha) checkers.</p>
+<h1>Available Checkers</h1>
+The analyzer performs checks that are categorized into families or "checkers". The
+default set of checkers covers a variety of checks targeted at finding security
+and API usage bugs, dead code, and other logic errors. See the
+<a href = "#default_checkers">Default Checkers</a> list below. In addition to
+these, the analyzer contains a number of <a href = "alpha_checks.html">
+Experimental (Alpha) Checkers</a>.
 
 <h3>Writeups with examples of some of the bugs that the analyzer finds</h3>
-
 <ul>
 <li><a href="http://www.mobileorchard.com/bug-finding-with-clang-5-resources-to-get-you-started/">Bug Finding With Clang: 5 Resources To Get You Started</a></li>
 <li><a href="http://fruitstandsoftware.com/blog/index.php/2008/08/finding-memory-leaks-with-the-llvmclang-static-analyzer/#comment-2">Finding Memory Leaks With The LLVM/Clang Static Analyzer</a></li>
@@ -190,9 +33,1200 @@
 <li><a href="http://www.mikeash.com/?page=pyblog/friday-qa-2009-03-06-using-the-clang-static-analyzer.html">Mike Ash - Using the Clang Static Analyzer</a></li>
 </ul>
 
+<h2 id="default_checkers">Default Checkers</h2>
+<ul>
+<li><a href="#core_checkers">Core Checkers</a> model core language features and perform general-purpose checks such as division by zero, null pointer dereference, usage of uninitialized values, etc.</li>
+<li><a href="#cplusplus_checkers">C++ Checkers</a> perform C++-specific checks</li>
+<li><a href="#deadcode_checkers">Dead Code Checkers</a> check for unused code</li>
+<li><a href="#osx_checkers">OS X Checkers</a> perform Objective-C-specific checks and check the use of Apple's SDKs (OS X and iOS)</li>
+<li><a href="#security_checkers">Security Checkers</a> check for insecure API usage and perform checks based on the CERT Secure Coding Standards</li>
+<li><a href="#unix_checkers">Unix Checkers</a> check the use of Unix and POSIX APIs</li>
+</ul>
 
-</div>
-</div>
+<!------------------------------------ core ----------------------------------->
+<h3 id="core_checkers">Core Checkers</h3>
+<table class="checkers">
+<colgroup><col class="namedescr"><col class="example"></colgroup>
+<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
+
+<tbody>
+<tr><td><div class="namedescr expandable"><span class="name">
+core.CallAndMessage</span><span class="lang">
+(C, C++, ObjC)</span><div class="descr">
+Check for logical errors for function calls and Objective-C message expressions
+(e.g., uninitialized arguments, null function pointers).</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+// C
+struct S {
+  int x;
+};
+
+void f(struct S s);
+
+void test() {
+  struct S s;
+  f(s); // warn: passed-by-value arg contain uninitialized data
+}
+</pre></div>
+<div class="example"><pre>
+// C
+void test() {
+  void (*foo)(void);
+  foo(); // warn: function pointer is uninitialized
+}
+</pre></div>
+<div class="example"><pre>
+// C
+void test() {
+  void (*foo)(void);
+  foo = 0;
+  foo(); // warn: function pointer is null
+}
+</pre></div>
+<div class="example"><pre>
+// C++
+class C {
+public:
+  void f();
+};
+
+void test() {
+  C *pc;
+  pc-&gt;f(); // warn: object pointer is uninitialized
+}
+</pre></div>
+<div class="example"><pre>
+// C++
+class C {
+public:
+  void f();
+};
+
+void test() {
+  C *pc = 0;
+  pc-&gt;f(); // warn: object pointer is null
+}
+</pre></div>
+<div class="example"><pre>
+// Objective-C
+@interface MyClass : NSObject
+@property (readwrite,assign) id x;
+- (long double)longDoubleM;
+@end
+
+void test() {
+  MyClass *obj1;
+  long double ld1 = [obj1 longDoubleM];
+    // warn: receiver is uninitialized
+}
+</pre></div>
+<div class="example"><pre>
+// Objective-C
+@interface MyClass : NSObject
+@property (readwrite,assign) id x;
+- (long double)longDoubleM;
+@end
+
+void test() {
+  MyClass *obj1;
+  id i = obj1.x; // warn: uninitialized object pointer
+}
+</pre></div>
+<div class="example"><pre>
+// Objective-C
+@interface Subscriptable : NSObject
+- (id)objectAtIndexedSubscript:(unsigned int)index;
+@end
+
+@interface MyClass : Subscriptable
+@property (readwrite,assign) id x;
+- (long double)longDoubleM;
+@end
+
+void test() {
+  MyClass *obj1;
+  id i = obj1[0]; // warn: uninitialized object pointer
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+core.DivideZero</span><span class="lang">
+(C, C++, ObjC)</span><div class="descr">
+Check for division by zero.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test(int z) {
+  if (z == 0)
+    int x = 1 / z; // warn
+}
+</pre></div>
+<div class="example"><pre>
+void test() {
+  int x = 1;
+  int y = x % 0; // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+core.NonNullParamChecker</span><span class="lang">
+(C, C++, ObjC)</span><div class="descr">
+Check for null pointers passed as arguments to a function whose arguments are
+marked with the <code>nonnull</code> attribute.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+int f(int *p) __attribute__((nonnull));
+
+void test(int *p) {
+  if (!p)
+    f(p); // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+core.NullDereference</span><span class="lang">
+(C, C++, ObjC)</span><div class="descr">
+Check for dereferences of null pointers.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+// C
+void test(int *p) {
+  if (p)
+    return;
+
+  int x = p[0]; // warn
+}
+</pre></div>
+<div class="example"><pre>
+// C
+void test(int *p) {
+  if (!p)
+    *p = 0; // warn
+}
+</pre></div>
+<div class="example"><pre>
+// C++
+class C {
+public:
+  int x;
+};
+
+void test() {
+  C *pc = 0;
+  int k = pc->x; // warn
+}
+</pre></div>
+<div class="example"><pre>
+// Objective-C
+@interface MyClass {
+@public
+  int x;
+}
+@end
+
+void test() {
+  MyClass *obj = 0;
+  obj-&gt;x = 1; // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+core.StackAddressEscape</span><span class="lang">
+(C)</span><div class="descr">
+Check that addresses of stack memory do not escape the function.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+char const *p;
+
+void test() {
+  char const str[] = "string";
+  p = str; // warn
+}
+</pre></div>
+<div class="example"><pre>
+void* test() {
+   return __builtin_alloca(12); // warn
+}
+</pre></div>
+<div class="example"><pre>
+void test() {
+  static int *x;
+  int y;
+  x = &amp;y; // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+core.UndefinedBinaryOperatorResult</span><span class="lang">
+(C)</span><div class="descr">
+Check for undefined results of binary operators.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  int x;
+  int y = x + 1; // warn: left operand is garbage
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+core.VLASize</span><span class="lang">
+(C)</span><div class="descr">
+Check for declarations of VLA of undefined or zero size.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  int x;
+  int vla1[x]; // warn: garbage as size
+}
+</pre></div>
+<div class="example"><pre>
+void test() {
+  int x = 0;
+  int vla2[x]; // warn: zero size
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+core.uninitialized.ArraySubscript</span><span class="lang">
+(C)</span><div class="descr">
+Check for uninitialized values used as array subscripts.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  int i, a[10];
+  int x = a[i]; // warn: array subscript is undefined
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+core.uninitialized.Assign</span><span class="lang">
+(C)</span><div class="descr">
+Check for assigning uninitialized values.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  int x;
+  x |= 1; // warn: left expression is unitialized
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+core.uninitialized.Branch</span><span class="lang">
+(C)</span><div class="descr">
+Check for uninitialized values used as branch conditions.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  int x;
+  if (x) // warn
+    return;
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+core.uninitialized.CapturedBlockVariable</span><span class="lang">
+(C)</span><div class="descr">
+Check for blocks that capture uninitialized values.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  int x;
+  ^{ int y = x; }(); // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+core.uninitialized.UndefReturn</span><span class="lang">
+(C)</span><div class="descr">
+Check for uninitialized values being returned to the caller.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+int test() {
+  int x;
+  return x; // warn
+}
+</pre></div></div></td></tr>
+
+</tbody></table>
+
+<!------------------------------------ C++ ------------------------------------>
+<h3 id="cplusplus_checkers">C++ Checkers</h3>
+<table class="checkers">
+<colgroup><col class="namedescr"><col class="example"></colgroup>
+<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
+
+<tbody>
+<tr><td><div class="namedescr expandable"><span class="name">
+cplusplus.NewDelete</span><span class="lang">
+(C++)</span><div class="descr">
+Check for double-free, use-after-free and offset problems involving C++ <code>
+delete</code>.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void f(int *p);
+
+void testUseMiddleArgAfterDelete(int *p) {
+  delete p;
+  f(p); // warn: use after free
+}
+</pre></div>
+<div class="example"><pre>
+class SomeClass {
+public:
+  void f();
+};
+
+void test() {
+  SomeClass *c = new SomeClass;
+  delete c;
+  c-&gt;f(); // warn: use after free
+}
+</pre></div>
+<div class="example"><pre>
+void test() {
+  int *p = (int *)__builtin_alloca(sizeof(int));
+  delete p; // warn: deleting memory allocated by alloca
+}
+</pre></div>
+<div class="example"><pre>
+void test() {
+  int *p = new int;
+  delete p;
+  delete p; // warn: attempt to free released
+}
+</pre></div>
+<div class="example"><pre>
+void test() {
+  int i;
+  delete &amp;i; // warn: delete address of local
+}
+</pre></div>
+<div class="example"><pre>
+void test() {
+  int *p = new int[1];
+  delete[] (++p);
+    // warn: argument to 'delete[]' is offset by 4 bytes
+    // from the start of memory allocated by 'new[]'
+}
+</pre></div></div></td></tr>
+
+</tbody></table>
+
+<!--------------------------------- dead code --------------------------------->
+<h3 id="deadcode_checkers">Dead Code Checkers</h3>
+<table class="checkers">
+<colgroup><col class="namedescr"><col class="example"></colgroup>
+<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
+
+<tbody>
+<tr><td><div class="namedescr expandable"><span class="name">
+deadcode.DeadStores</span><span class="lang">
+(C)</span><div class="descr">
+Check for values stored to variables that are never read afterwards.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  int x;
+  x = 1; // warn
+}
+</pre></div></div></td></tr>
+
+</tbody></table>
+
+<!---------------------------------- OS X ------------------------------------>
+<h3 id="osx_checkers">OS X Checkers</h3>
+<table class="checkers">
+<colgroup><col class="namedescr"><col class="example"></colgroup>
+<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
+
+<tbody>
+<tr><td><div class="namedescr expandable"><span class="name">
+osx.API</span><span class="lang">
+(C)</span><div class="descr">
+Check for proper uses of various Apple APIs:<div class=functions>
+dispatch_once</div></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  dispatch_once_t pred = 0;
+  dispatch_once(&amp;pred, ^(){}); // warn: dispatch_once uses local
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+osx.SecKeychainAPI</span><span class="lang">
+(C)</span><div class="descr">
+Check for improper uses of the Security framework's Keychain APIs:<div class=functions>
+SecKeychainItemCopyContent<br>
+SecKeychainFindGenericPassword<br>
+SecKeychainFindInternetPassword<br>
+SecKeychainItemFreeContent<br>
+SecKeychainItemCopyAttributesAndData<br>
+SecKeychainItemFreeAttributesAndData</div></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  unsigned int *ptr = 0;
+  UInt32 length;
+
+  SecKeychainItemFreeContent(ptr, &amp;length);
+    // warn: trying to free data which has not been allocated
+}
+</pre></div>
+<div class="example"><pre>
+void test() {
+  unsigned int *ptr = 0;
+  UInt32 *length = 0;
+  void *outData;
+
+  OSStatus st =
+    SecKeychainItemCopyContent(2, ptr, ptr, length, outData);
+    // warn: data is not released
+}
+</pre></div>
+<div class="example"><pre>
+void test() {
+  unsigned int *ptr = 0;
+  UInt32 *length = 0;
+  void *outData;
+
+  OSStatus st =
+    SecKeychainItemCopyContent(2, ptr, ptr, length, &amp;outData);
+
+  SecKeychainItemFreeContent(ptr, outData);
+    // warn: only call free if a non-NULL buffer was returned
+}
+</pre></div>
+<div class="example"><pre>
+void test() {
+  unsigned int *ptr = 0;
+  UInt32 *length = 0;
+  void *outData;
+
+  OSStatus st =
+    SecKeychainItemCopyContent(2, ptr, ptr, length, &amp;outData);
+
+  st = SecKeychainItemCopyContent(2, ptr, ptr, length, &amp;outData);
+    // warn: release data before another call to the allocator
+
+  if (st == noErr)
+    SecKeychainItemFreeContent(ptr, outData);
+}
+</pre></div>
+<div class="example"><pre>
+void test() {
+  SecKeychainItemRef itemRef = 0;
+  SecKeychainAttributeInfo *info = 0;
+  SecItemClass *itemClass = 0;
+  SecKeychainAttributeList *attrList = 0;
+  UInt32 *length = 0;
+  void *outData = 0;
+
+  OSStatus st =
+    SecKeychainItemCopyAttributesAndData(itemRef, info,
+                                         itemClass, &amp;attrList,
+                                         length, &amp;outData);
+
+  SecKeychainItemFreeContent(attrList, outData);
+    // warn: deallocator doesn't match the allocator
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+osx.cocoa.AtSync</span><span class="lang">
+(ObjC)</span><div class="descr">
+Check for nil pointers used as mutexes for <code>@synchronized</code>.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test(id x) {
+  if (!x)
+    @synchronized(x) {} // warn: nil value used as mutex
+}
+</pre></div>
+<div class="example"><pre>
+void test() {
+  id y;
+  @synchronized(y) {} // warn: uninitialized value used as mutex
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+osx.cocoa.ClassRelease</span><span class="lang">
+(ObjC)</span><div class="descr">
+Check for sending <code>retain</code>, <code>release</code>, or <code>
+autorelease</code> directly to a class.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+@interface MyClass : NSObject
+@end
+
+void test(void) {
+  [MyClass release]; // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+osx.cocoa.IncompatibleMethodTypes</span><span class="lang">
+(ObjC)</span><div class="descr">
+Check for an incompatible type signature when overriding an Objective-C method.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+@interface MyClass1 : NSObject
+- (int)foo;
+@end
+
+@implementation MyClass1
+- (int)foo { return 1; }
+@end
+
+@interface MyClass2 : MyClass1
+- (float)foo;
+@end
+
+@implementation MyClass2
+- (float)foo { return 1.0; } // warn
+@end
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.osx.cocoa.MissingSuperCall</span><span class="lang">
+(ObjC)</span><div class="descr">
+Warn about Objective-C methods that lack a necessary call to super. (Note: The
+compiler now has a warning for methods annotated with <code>objc_requires_super</code>
+attribute. The checker exists to check methods in the Cocoa frameworks
+that haven't yet adopted this attribute.)</div></div></td>
+<td><div class="example"><pre>
+@interface Test : UIViewController
+@end
+@implementation test
+- (void)viewDidLoad {} // warn
+@end
+</pre></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+osx.cocoa.NSAutoreleasePool</span><span class="lang">
+(ObjC)</span><div class="descr">
+Warn for suboptimal uses of NSAutoreleasePool in Objective-C
+GC mode (<code>-fobjc-gc</code> compiler option).</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+  [pool release]; // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+osx.cocoa.NSError</span><span class="lang">
+(ObjC)</span><div class="descr">
+Check usage of <code>NSError**</code> parameters.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+@interface A : NSObject
+- (void)foo:(NSError **)error;
+@end
+
+@implementation A
+- (void)foo:(NSError **)error {
+  // warn: method accepting NSError** should have a non-void
+  // return value
+}
+@end
+</pre></div>
+<div class="example"><pre>
+@interface A : NSObject
+- (BOOL)foo:(NSError **)error;
+@end
+
+@implementation A
+- (BOOL)foo:(NSError **)error {
+  *error = 0; // warn: potential null dereference
+  return 0;
+}
+@end
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+osx.cocoa.NilArg</span><span class="lang">
+(ObjC)</span><div class="descr">
+Check for prohibited nil arguments in specific Objective-C method calls:<div class=functions>
+- caseInsensitiveCompare:<br>
+- compare:<br>
+- compare:options:<br>
+- compare:options:range:<br>
+- compare:options:range:locale:<br>
+- componentsSeparatedByCharactersInSet:<br>
+- initWithFormat:</div></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+NSComparisonResult test(NSString *s) {
+  NSString *aString = nil;
+  return [s caseInsensitiveCompare:aString];
+    // warn: argument to 'NSString' method
+    // 'caseInsensitiveCompare:' cannot be nil
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+osx.cocoa.RetainCount</span><span class="lang">
+(ObjC)</span><div class="descr">
+Check for leaks and violations of the Cocoa Memory Management rules.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  NSString *s = [[NSString alloc] init]; // warn
+}
+</pre></div>
+<div class="example"><pre>
+CFStringRef test(char *bytes) {
+  return CFStringCreateWithCStringNoCopy(
+           0, bytes, NSNEXTSTEPStringEncoding, 0); // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+osx.cocoa.SelfInit</span><span class="lang">
+(ObjC)</span><div class="descr">
+Check that <code>self</code> is properly initialized inside an initializer
+method.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+@interface MyObj : NSObject {
+  id x;
+}
+- (id)init;
+@end
+
+@implementation MyObj
+- (id)init {
+  [super init];
+  x = 0; // warn: instance variable used while 'self' is not
+         // initialized
+  return 0;
+}
+@end
+</pre></div>
+<div class="example"><pre>
+@interface MyObj : NSObject
+- (id)init;
+@end
+
+@implementation MyObj
+- (id)init {
+  [super init];
+  return self; // warn: returning uninitialized 'self'
+}
+@end
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+osx.cocoa.UnusedIvars</span><span class="lang">
+(ObjC)</span><div class="descr">
+Warn about private ivars that are never used.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+@interface MyObj : NSObject {
+@private
+  id x; // warn
+}
+@end
+
+@implementation MyObj
+@end
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+osx.cocoa.VariadicMethodTypes</span><span class="lang">
+(ObjC)</span><div class="descr">
+Check for passing non-Objective-C types to variadic collection initialization
+methods that expect only Objective-C types.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  [NSSet setWithObjects:@"Foo", "Bar", nil];
+    // warn: argument should be an ObjC pointer type, not 'char *'
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+osx.coreFoundation.CFError</span><span class="lang">
+(C)</span><div class="descr">
+Check usage of <code>CFErrorRef*</code> parameters.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test(CFErrorRef *error) {
+  // warn: function accepting CFErrorRef* should have a
+  // non-void return
+}
+</pre></div>
+<div class="example"><pre>
+int foo(CFErrorRef *error) {
+  *error = 0; // warn: potential null dereference
+  return 0;
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+osx.coreFoundation.CFNumber</span><span class="lang">
+(C)</span><div class="descr">
+Check for improper uses of <code>CFNumberCreate</code>.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+CFNumberRef test(unsigned char x) {
+  return CFNumberCreate(0, kCFNumberSInt16Type, &amp;x);
+   // warn: 8 bit integer is used to initialize a 16 bit integer
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+osx.coreFoundation.CFRetainRelease</span><span class="lang">
+(C)</span><div class="descr">
+Check for null arguments to <code>CFRetain</code>, <code>CFRelease</code>,
+<code>CFMakeCollectable</code>.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test(CFTypeRef p) {
+  if (!p)
+    CFRetain(p); // warn
+}
+</pre></div>
+<div class="example"><pre>
+void test(int x, CFTypeRef p) {
+  if (p)
+    return;
+
+  CFRelease(p); // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+osx.coreFoundation.containers.OutOfBounds</span><span class="lang">
+(C)</span><div class="descr">
+Checks for index out-of-bounds when using <code>CFArray</code> API.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  CFArrayRef A = CFArrayCreate(0, 0, 0, &amp;kCFTypeArrayCallBacks);
+  CFArrayGetValueAtIndex(A, 0); // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+osx.coreFoundation.containers.PointerSizedValues</span><span class="lang">
+(C)</span><div class="descr">
+Warns if <code>CFArray</code>, <code>CFDictionary</code>, <code>CFSet</code> are
+created with non-pointer-size values.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  int x[] = { 1 };
+  CFArrayRef A = CFArrayCreate(0, (const void **)x, 1,
+                               &amp;kCFTypeArrayCallBacks); // warn
+}
+</pre></div></div></td></tr>
+
+</tbody></table>
+
+<!------------------------------- security ------------------------------------>
+<h3 id="security_checkers">Security Checkers</h3>
+<table class="checkers">
+<colgroup><col class="namedescr"><col class="example"></colgroup>
+<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
+
+<tbody>
+<tr><td><div class="namedescr expandable"><span class="name">
+security.FloatLoopCounter</span><span class="lang">
+(C)</span><div class="descr">
+Warn on using a floating point value as a loop counter (CERT: FLP30-C,
+FLP30-CPP).</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  for (float x = 0.1f; x <= 1.0f; x += 0.1f) {} // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+security.insecureAPI.UncheckedReturn</span><span class="lang">
+(C)</span><div class="descr">
+Warn on uses of functions whose return values must be always checked:<div class=functions>
+setuid<br>
+setgid<br>
+seteuid<br>
+setegid<br>
+setreuid<br>
+setregid</div></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  setuid(1); // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+security.insecureAPI.getpw</span><span class="lang">
+(C)</span><div class="descr">
+Warn on uses of the <code>getpw</code> function.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  char buff[1024];
+  getpw(2, buff); // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+security.insecureAPI.gets</span><span class="lang">
+(C)</span><div class="descr">
+Warn on uses of the <code>gets</code> function.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  char buff[1024];
+  gets(buff); // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+security.insecureAPI.mkstemp</span><span class="lang">
+(C)</span><div class="descr">
+Warn when <code>mktemp</code>, <code>mkstemp</code>, <code>mkstemps</code> or
+<code>mkdtemp</code> is passed fewer than 6
+X's in the format string.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  mkstemp("XX"); // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+security.insecureAPI.mktemp</span><span class="lang">
+(C)</span><div class="descr">
+Warn on uses of the <code>mktemp</code> function.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  char *x = mktemp("/tmp/zxcv"); // warn: insecure, use mkstemp
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+security.insecureAPI.rand</span><span class="lang">
+(C)</span><div class="descr">
+Warn on uses of inferior random number generating functions (only if <code>arc4random</code>
+function is available):<div class=functions>
+drand48<br>
+erand48<br>
+jrand48<br>
+lcong48<br>
+lrand48<br>
+mrand48<br>
+nrand48<br>
+random<br>
+rand_r</div></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  random(); // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+security.insecureAPI.strcpy</span><span class="lang">
+(C)</span><div class="descr">
+Warn on uses of the <code>strcpy</code> and <code>strcat</code> functions.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  char x[4];
+  char *y = "abcd";
+
+  strcpy(x, y); // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+security.insecureAPI.vfork</span><span class="lang">
+(C)</span><div class="descr">
+Warn on uses of the <code>vfork</code> function.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  vfork(); // warn
+}
+</pre></div></div></td></tr>
+
+</tbody></table>
+
+<!--------------------------------- unix -------------------------------------->
+<h3 id="unix_checkers">Unix Checkers</h3>
+<table class="checkers">
+<colgroup><col class="namedescr"><col class="example"></colgroup>
+<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
+
+<tbody>
+<tr><td><div class="namedescr expandable"><span class="name">
+unix.API</span><span class="lang">
+(C)</span><div class="descr">
+Check calls to various UNIX/POSIX functions:<div class=functions>
+open<br>
+pthread_once<br>
+calloc<br>
+malloc<br>
+realloc<br>
+alloca<br>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+// Currently the check is performed for apple targets only.
+void test(const char *path) {
+  int fd = open(path, O_CREAT);
+    // warn: call to 'open' requires a third argument when the
+    // 'O_CREAT' flag is set
+}
+</pre></div>
+<div class="example"><pre>
+void f();
+
+void test() {
+  pthread_once_t pred = {0x30B1BCBA, {0}};
+  pthread_once(&amp;pred, f);
+    // warn: call to 'pthread_once' uses the local variable
+}
+</pre></div>
+<div class="example"><pre>
+void test() {
+  void *p = malloc(0); // warn: allocation size of 0 bytes
+}
+</pre></div>
+<div class="example"><pre>
+void test() {
+  void *p = calloc(0, 42); // warn: allocation size of 0 bytes
+}
+</pre></div>
+<div class="example"><pre>
+void test() {
+  void *p = malloc(1);
+  p = realloc(p, 0); // warn: allocation size of 0 bytes
+}
+</pre></div>
+<div class="example"><pre>
+void test() {
+  void *p = alloca(0); // warn: allocation size of 0 bytes
+}
+</pre></div>
+<div class="example"><pre>
+void test() {
+  void *p = valloc(0); // warn: allocation size of 0 bytes
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+unix.Malloc</span><span class="lang">
+(C)</span><div class="descr">
+Check for memory leaks, double free, and use-after-free and offset problems
+involving <code>malloc</code>.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  int *p = malloc(1);
+  free(p);
+  free(p); // warn: attempt to free released memory
+}
+</pre></div>
+<div class="example"><pre>
+void test() {
+  int *p = malloc(sizeof(int));
+  free(p);
+  *p = 1; // warn: use after free
+}
+</pre></div>
+<div class="example"><pre>
+void test() {
+  int *p = malloc(1);
+  if (p)
+    return; // warn: memory is never released
+}
+</pre></div>
+<div class="example"><pre>
+void test() {
+  int a[] = { 1 };
+  free(a); // warn: argument is not allocated by malloc
+}
+</pre></div>
+<div class="example"><pre>
+void test() {
+  int *p = malloc(sizeof(char));
+  p = p - 1;
+  free(p); // warn: argument to free() is offset by -4 bytes
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+unix.MallocSizeof</span><span class="lang">
+(C)</span><div class="descr">
+Check for dubious <code>malloc</code>, <code>calloc</code> or
+<code>realloc</code> arguments involving <code>sizeof</code>.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  long *p = malloc(sizeof(short));
+    // warn: result is converted to 'long *', which is
+    // incompatible with operand type 'short'
+  free(p);
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+unix.MismatchedDeallocator</span><span class="lang">
+(C, C++, ObjC)</span><div class="descr">
+Check for mismatched deallocators (e.g. passing a pointer allocating
+with <code>new</code> to <code>free()</code>).</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+// C, C++
+void test() {
+  int *p = (int *)malloc(sizeof(int));
+  delete p; // warn
+}
+</pre></div>
+<div class="example"><pre>
+// C, C++
+void __attribute((ownership_returns(malloc))) *user_malloc(size_t);
+
+void test() {
+  int *p = (int *)user_malloc(sizeof(int));
+  delete p; // warn
+}
+</pre></div>
+<div class="example"><pre>
+// C, C++
+void test() {
+  int *p = new int;
+  free(p); // warn
+}
+</pre></div>
+<div class="example"><pre>
+// C, C++
+void test() {
+  int *p = new int[1];
+  realloc(p, sizeof(long)); // warn
+}
+</pre></div>
+<div class="example"><pre>
+// C, C++
+template &lt;typename T&gt;
+struct SimpleSmartPointer {
+  T *ptr;
+
+  explicit SimpleSmartPointer(T *p = 0) : ptr(p) {}
+  ~SimpleSmartPointer() {
+    delete ptr; // warn
+  }
+};
+
+void test() {
+  SimpleSmartPointer&lt;int&gt; a((int *)malloc(4));
+}
+</pre></div>
+<div class="example"><pre>
+// C++
+void test() {
+  int *p = (int *)operator new(0);
+  delete[] p; // warn
+}
+</pre></div>
+<div class="example"><pre>
+// Objective-C, C++
+void test(NSUInteger dataLength) {
+  int *p = new int;
+  NSData *d = [NSData dataWithBytesNoCopy:p
+               length:sizeof(int) freeWhenDone:1];
+    // warn +dataWithBytesNoCopy:length:freeWhenDone: cannot take
+    // ownership of memory allocated by 'new'
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+unix.cstring.BadSizeArg</span><span class="lang">
+(C)</span><div class="descr">
+Check the size argument passed to <code>strncat</code> for common erroneous
+patterns. Use <code>-Wno-strncat-size</code> compiler option to mute other
+<code>strncat</code>-related compiler warnings.
+</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  char dest[3];
+  strncat(dest, "***", sizeof(dest));
+    // warn: potential buffer overflow
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+unix.cstring.NullArg</span><span class="lang">
+(C)</span><div class="descr">
+Check for null pointers being passed as arguments to C string functions:<div class=functions>
+strlen<br>
+strnlen<br>
+strcpy<br>
+strncpy<br>
+strcat<br>
+strncat<br>
+strcmp<br>
+strncmp<br>
+strcasecmp<br>
+strncasecmp</div></div></div></td>
+<td><div class="example"><pre>
+int test() {
+  return strlen(0); // warn
+}
+</pre></div></td></tr>
+
+</tbody></table>
+
+</div> <!-- page -->
+</div> <!-- content -->
 </body>
 </html>
-
diff --git a/www/analyzer/checker_dev_manual.html b/www/analyzer/checker_dev_manual.html
index 2216176..9c7cd98 100644
--- a/www/analyzer/checker_dev_manual.html
+++ b/www/analyzer/checker_dev_manual.html
@@ -47,6 +47,7 @@
       <li><a href="#testing">Testing</a></li>
       <li><a href="#commands">Useful Commands/Debugging Hints</a></li>
       <li><a href="#additioninformation">Additional Sources of Information</a></li>
+      <li><a href="#links">Useful Links</a></li>
     </ul>
 
 <h2 id=start>Getting Started</h2>
@@ -605,6 +606,11 @@
 are available.
 </ul>
 
+<h2 id=links>Useful Links</h2>
+<ul>
+<li>The list of <a href="implicit_checks.html">Implicit Checkers</a></li>
+</ul>
+
 </div>
 </div>
 </body>
diff --git a/www/analyzer/content.css b/www/analyzer/content.css
index 929d520..c4d601b 100644
--- a/www/analyzer/content.css
+++ b/www/analyzer/content.css
@@ -38,7 +38,7 @@
 
 #content {
   clear: left;
-  padding: 1em 2em 0 2em;
+  padding: 1em 2em 1em 2em;
   background-color: #ffffff;
 }
 
@@ -54,9 +54,7 @@
   text-align:left;
   border-top: 2px solid #cccccc;
   border-bottom: 2px solid #cccccc;
-  font-weight: bold; font-family: Verdana;
-  table-layout: fixed;
-  width: 100%
+  font-weight: bold; font-family: Verdana
 }
 table.options { border: 1px #cccccc solid }
 table.options { border-collapse: collapse; border-spacing: 0px }
@@ -64,7 +62,6 @@
 table.options td { border-bottom: 1px #cccccc dotted }
 table.options td { padding:5px; padding-left:8px; padding-right:8px }
 table.options td { text-align:left; font-size:9pt }
-table.options col.option { width:207px }
 
 table.checkers { 
   border: 1px #cccccc solid;
@@ -76,41 +73,28 @@
   word-wrap :break-word;
   font-size: 100%;
 }
-
 table.checkers thead {
   background-color:#eee; color:#666666;
   border-top: 2px solid #cccccc;
   border-bottom: 2px solid #cccccc;
   font-weight: bold; font-family: Verdana;
 }
-
-table.checkers td { 
-  padding:5px; padding-left:8px; padding-right:8px;
-  border-right: 1px #cccccc dotted;
-  border-bottom: 1px #cccccc dotted;
-}
-
+table.checkers td { border-right: 1px #cccccc dotted; border-bottom: 1px #cccccc dotted; }
 table.checkers td.aligned { text-align: center; vertical-align: middle; }
 table.checkers col.namedescr { width: 45% }
 table.checkers col.example { width: 55% }
 table.checkers col.progress { width: 84px }
-table.checkers pre { margin:1px; font-size: 100%; word-wrap :break-word; }
-table.checkers .name { font-weight:bold; }
-table.checkers .checked { background-color:#81F781; }
-table.checkers .commented { color:#909090; }
-
-/* Collapsing Trees: http://dbtree.megalingo.com/web/demo/simple-collapsible-tree.cfm  */
-#collapsetree, #collapsetree a:link, #collapsetree li a:link, #collapsetree a:visited, #collapsetree li a:visited{color:#000;text-decoration:none}
-#collapsetree,#collapsetree ul{list-style-type:none; width:auto; margin:0; padding:0}
-#collapsetree ul{padding-left:20px;display:none;overflow:auto}
-#collapsetree li ul{margin:0 auto}
-#collapsetree li{display:block;width:100%;line-height:20px;white-space:nowrap}
-#collapsetree li a{display:block;padding-left:20px;color:#000;text-decoration:none;background:url(images/tree/bullet.gif) center left no-repeat;white-space:nowrap}
-#collapsetree li a:hover{text-decoration:underline;background-color:transparent;color:#000}
-#collapsetree li ul.click{display:block}
-#collapsetree li.click a{background:url(images/tree/bullet.gif) center left no-repeat}
-#collapsetree ul li.click a{background:url(images/tree/bullet.gif) center left no-repeat}
-#collapsetree li a.subMenu,#collapsetree ul li a.subMenu{background:url(images/tree/plus.gif) center left no-repeat}
-#collapsetree li a.click{background:url(images/tree/minus.gif) center left no-repeat}
-#collapsetree ul li a.click{background:url(images/tree/minus.gif) center left no-repeat}
+table.checkers thead td,
+table.checkers div.namedescr,
+table.checkers div.exampleContainer { overflow: hidden; padding: 5px 8px 10px 8px }
+/* table.checkers tbody div.example { font-family: monospace; white-space: pre } */
+table.checkers div.example { border-top:1px #cccccc dashed; width:100%; padding-top: 5px; margin-top: 5px }
+table.checkers div.example:first-child { border-top:none; padding-top: 0px; margin-top: 0px }
+table.checkers span.name { font-weight: bold }
+table.checkers span.lang { font-weight: bold; padding-left: 7px; /* display:block; */ }
+table.checkers div.descr { margin-top:7px }
+table.checkers div.functions { margin-top: 2px; font-style: italic; font-size: 90%; color:#00B }
+table.checkers pre { margin: 1px; font-size: 100%; word-wrap: break-word }
+table.checkers p { margin: 10px 0px 0px 0px; }
+table.checkers ul, li { margin: 0 }
 
diff --git a/www/analyzer/images/expandcollapse/arrows_dark.gif b/www/analyzer/images/expandcollapse/arrows_dark.gif
new file mode 100644
index 0000000..445a3c5
--- /dev/null
+++ b/www/analyzer/images/expandcollapse/arrows_dark.gif
Binary files differ
diff --git a/www/analyzer/images/expandcollapse/arrows_light.gif b/www/analyzer/images/expandcollapse/arrows_light.gif
new file mode 100644
index 0000000..4534d05
--- /dev/null
+++ b/www/analyzer/images/expandcollapse/arrows_light.gif
Binary files differ
diff --git a/www/analyzer/images/expandcollapse/ellipses_dark.gif b/www/analyzer/images/expandcollapse/ellipses_dark.gif
new file mode 100644
index 0000000..8ed43b0
--- /dev/null
+++ b/www/analyzer/images/expandcollapse/ellipses_dark.gif
Binary files differ
diff --git a/www/analyzer/images/expandcollapse/ellipses_light.gif b/www/analyzer/images/expandcollapse/ellipses_light.gif
new file mode 100644
index 0000000..90141ba
--- /dev/null
+++ b/www/analyzer/images/expandcollapse/ellipses_light.gif
Binary files differ
diff --git a/www/analyzer/images/tree/bullet.gif b/www/analyzer/images/tree/bullet.gif
deleted file mode 100644
index de15348..0000000
--- a/www/analyzer/images/tree/bullet.gif
+++ /dev/null
Binary files differ
diff --git a/www/analyzer/images/tree/minus.gif b/www/analyzer/images/tree/minus.gif
deleted file mode 100644
index 225f40d..0000000
--- a/www/analyzer/images/tree/minus.gif
+++ /dev/null
Binary files differ
diff --git a/www/analyzer/images/tree/plus.gif b/www/analyzer/images/tree/plus.gif
deleted file mode 100644
index 5398c80..0000000
--- a/www/analyzer/images/tree/plus.gif
+++ /dev/null
Binary files differ
diff --git a/www/analyzer/implicit_checks.html b/www/analyzer/implicit_checks.html
new file mode 100644
index 0000000..a476c9b
--- /dev/null
+++ b/www/analyzer/implicit_checks.html
@@ -0,0 +1,165 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <title>Implicit Checks</title>
+  <link type="text/css" rel="stylesheet" href="menu.css">
+  <link type="text/css" rel="stylesheet" href="content.css">
+  <script type="text/javascript" src="scripts/menu.js"></script>
+  <script type="text/javascript" src="scripts/expandcollapse.js"></script>
+  <style type="text/css">
+  tr:first-child { width:20%; }
+  </style>
+</head>
+<body onload="initExpandCollapse()">
+
+<div id="page">
+<!--#include virtual="menu.html.incl"-->
+
+<div id="content">
+<h1>Implicit Checkers</h1>
+Even though the implicit checkers do not produce any warnings, they are used to 
+support the analyzer core and model known APIs. See also 
+<a href = "available_checks.html">Default Checkers</a>
+and <a href = "alpha_checks.html">Experimental (Alpha) Checkers</a>.
+<ul>
+<li><a href="#core_implicit_checkers">Core Implicit Checkers</a></li>
+<li><a href="#osx_implicit_checkers">OS X Implicit Checkers</a></li>
+</ul>
+
+<!------------------------------- core implicit ------------------------------->
+<h3 id="core_implicit_checkers">Core Implicit Checkers</h3>
+<table class="checkers">
+<colgroup><col class="namedescr"><col class="example"></colgroup>
+<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
+
+<tbody>
+<tr><td><div class="namedescr expandable"><span class="name">
+core.DynamicTypePropagation</span><span class="lang">
+(C++, ObjC)</span><div class="descr">
+Generate dynamic type information.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+// C++
+class A {
+public:
+  A(int x) {}
+  virtual int foo();
+};
+
+class B: public A {
+public:
+  B()
+  :A(foo()) 
+  // DynamicTypeInfo for 'this' rigion will wrap type 'A'
+  // unless the base constructor call expression is processed
+  {} 
+  virtual int foo();
+};
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+// Objective-C
+@interface MyClass : NSObject {}
+@end
+
+@implementation MyClass
++ (void)foo {
+  MyClass *x = [[self alloc] init];
+  // DynamicTypeInfo from a cast: from 'id' to 'MyClass *'
+}
+@end
+
+void test() {
+  MyClass *x = [MyClass alloc];
+  // DynamicTypeInfo from a call to alloc:
+  // from 'id' to 'MyClass *'
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+core.builtin.BuiltinFunctions</span><span class="lang">
+(C)</span><div class="descr">
+Evaluate compiler builtin functions (e.g., <code>alloca()</code>)</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test(int x) {
+  int *p = (int *)__builtin_alloca(8);
+    // evaluates to AllocaRegion
+
+  if(__builtin_expect(x > 10, 0)) // evaluates to 'x > 10'
+    x = 0;
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+core.builtin.NoReturnFunctions</span><span class="lang">
+(C, ObjC)</span><div class="descr">
+Evaluate "panic" functions that are known to not return to the caller.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+// C
+void test() {
+  panic(); // generate sink
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+// Objective-C
+@interface MyObj : NSObject {}
+- (void)foo;
+@end
+
+@implementation MyObj
+- (void)foo {
+  [[NSAssertionHandler currentHandler] handleFailureInMethod:_cmd 
+                                       object:self 
+                                       file:(@"somefile.m") 
+                                       lineNumber:1 
+                                       description:(@"some text")];
+    // generate sink
+}
+@end
+</pre></div></div></td></tr>
+
+</tbody></table>
+
+<!---------------------------- OS X implicit ---------------------------------->
+<h3 id="osx_implicit_checkers">OS X Implicit Checkers</h3>
+<table class="checkers">
+<colgroup><col class="namedescr"><col class="example"></colgroup>
+<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
+
+<tbody>
+<tr><td><div class="namedescr expandable"><span class="name">
+osx.cocoa.Loops</span><span class="lang">
+(ObjC)</span><div class="descr">
+Improved modeling of loops using Cocoa collection types.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  id x;
+  for (x in [NSArray testObject]) { 
+    // assume the value of 'x' is non-nil
+  }
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+osx.cocoa.NonNilReturnValue</span><span class="lang">
+(ObjC)</span><div class="descr">
+Model the APIs that are guaranteed to return a non-nil value.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test(NSArray *A) {
+  id subscriptObj = A[1]; // assume the value is non-nil
+}
+</pre></div></div></td></tr>
+
+</tbody></table>
+
+</div> <!-- page -->
+</div> <!-- content -->
+</body>
+</html>
diff --git a/www/analyzer/latest_checker.html.incl b/www/analyzer/latest_checker.html.incl
index 5062622..99ed3d8 100644
--- a/www/analyzer/latest_checker.html.incl
+++ b/www/analyzer/latest_checker.html.incl
@@ -1 +1 @@
-<b><a href="downloads/checker-275.tar.bz2">checker-275.tar.bz2</a></b> (built May 23, 2013)
+<b><a href="downloads/checker-276.tar.bz2">checker-276.tar.bz2</a></b> (built February 19, 2014)
diff --git a/www/analyzer/open_projects.html b/www/analyzer/open_projects.html
index 4a888ad..75c0692 100644
--- a/www/analyzer/open_projects.html
+++ b/www/analyzer/open_projects.html
@@ -56,7 +56,7 @@
     <li>Enhance CFG to model C++ temporaries properly.
     <p>There is an existing implementation of this, but it's not complete and
     is disabled in the analyzer.
-    <i>(Difficulty: Medium)</i></p>    
+    <i>(Difficulty: Medium; current contact: Alex McCarthy)</i></p>    
 
     <li>Enhance CFG to model exception-handling properly.
     <p>Currently exceptions are treated as "black holes", and exception-handling
@@ -70,7 +70,7 @@
     (<code>operator new</code>), then initialize the result with a constructor
     call. The problem is discussed at length in
     <a href="http://llvm.org/bugs/show_bug.cgi?id=12014">PR12014</a>.
-    <i>(Difficulty: Easy)</i></p>    
+    <i>(Difficulty: Easy; current contact: Karthik Bhat)</i></p>
 
     <li>Enhance CFG to model C++ <code>delete</code> more precisely.
     <p>Similarly, the representation of <code>delete</code> does not include
@@ -78,7 +78,14 @@
     function (<code>operator delete</code>). One particular issue 
     (<tt>noreturn</tt> destructors) is discussed in
     <a href="http://llvm.org/bugs/show_bug.cgi?id=15599">PR15599</a>
-    <i>(Difficulty: Easy)</i></p>    
+    <i>(Difficulty: Easy; current contact: Karthik Bhat)</i></p>    
+
+    <li>Implement a BitwiseConstraintManager to handle <a href="http://llvm.org/bugs/show_bug.cgi?id=3098">PR3098</a>.
+    <p>Constraints on the bits of an integer are not easily representable as
+    ranges. A bitwise constraint manager would model constraints such as "bit 32
+    is known to be 1". This would help code that made use of bitmasks</code>.
+    <i>(Difficulty: Medium)</i></p>
+    </li>
 
     <li>Track type info through casts more precisely.
     <p>The DynamicTypePropagation checker is in charge of inferring a region's
@@ -107,14 +114,6 @@
     display such paths in HTML output. <i>(Difficulty: Medium)</i> </p>
     </li>
     
-    <li>Relate bugs to checkers / "bug types"
-    <p>We need to come up with an API which will relate bug reports 
-    to the checkers that produce them and refactor the existing code to use the 
-    new API. This would allow us to identify the checker from the bug report,
-    which paves the way for selective control of certain checks.
-    <i>(Difficulty: Easy-Medium)</i></p>
-    </li>
-    
     <li>Refactor path diagnostic generation in <a href="http://clang.llvm.org/doxygen/BugReporter_8cpp_source.html">BugReporter.cpp</a>.
     <p>It would be great to have more code reuse between "Minimal" and 
     "Extensive" PathDiagnostic generation algorithms. One idea is to create an 
@@ -182,7 +181,7 @@
     <p>Take a look at the
     <a href="http://pages.cs.wisc.edu/~shanlu/paper/TSE-CPMiner.pdf">CP-Miner</a>
     paper for inspiration. 
-    <i>(Difficulty: Medium-Hard)</i></p>
+    <i>(Difficulty: Medium-Hard; current contacts: Per Viberg and Daniel Fahlgren)</i></p>
     </li>  
   </ul>
   </li>
diff --git a/www/analyzer/potential_checkers.html b/www/analyzer/potential_checkers.html
index ab8917c..a06e942 100644
--- a/www/analyzer/potential_checkers.html
+++ b/www/analyzer/potential_checkers.html
@@ -5,10 +5,10 @@
   <title>List of potential checkers</title>
   <link type="text/css" rel="stylesheet" href="content.css">
   <link type="text/css" rel="stylesheet" href="menu.css">
+  <script type="text/javascript" src="scripts/expandcollapse.js"></script>
   <script type="text/javascript" src="scripts/menu.js"></script>
-  <script type="text/javascript" src="scripts/dbtree.js"></script>
 </head>
-<body>
+<body onload="initExpandCollapse()">
 
 <div id="page">
 
@@ -21,120 +21,88 @@
 <p>This page contains a list of potential checkers to implement in the static analyzer.  If you are interested in contributing to the analyzer's development, this is a good resource to help you get started.  The specific names of the checkers are subject to review, and are provided here as suggestions.</p>
 
 <!-- ========================= allocation/deallocation ======================= -->
-<h3>allocation/deallocation</h3>
+<h3>memory</h3>
 <table class="checkers">
 <col class="namedescr"><col class="example"><col class="progress">
 <thead><tr><td>Name, Description</td><td>Example</td><td>Progress</td></tr></thead>
 
-<tr><td><span class="name">memory.LeakNeverReleased<br>
-(C, C++)</span><br><br>
-Memory may be never released, potential leak of memory
-</td><td>
-<pre>
-#include &lt;stdlib.h&gt;
-
-int f() {};
-
-void test() { 
-  int *p1 = (int*)malloc(sizeof(int)); // warn
-  int *p2 = new int; // warn
-  int x = f();
-  if (x==1)
-    return;
-  delete p2;
-}
-</pre></td><td class="aligned"><a href="http://llvm.org/bugs/show_bug.cgi?id=15237">PR15237</a>
-</td></tr>
-
-<tr><td><span class="name">memory.MismatchedFree
-<br>enhancement to unix.Malloc<br>(C, C++)</span><br><br>
-Mismatched deallocation function is used
-</td><td><pre>
-#include &lt;stdlib.h&gt;
+<tr><td><div class="namedescr expandable"><span class="name">
+memory.LeakEvalOrder</span><span class="lang">
+(C, C++)</span><div class="descr">
+Potential memory leaks caused by an undefined argument evaluation order.
+<p>Source: <a href="http://www.boost.org/doc/libs/1_49_0/libs/smart_ptr/shared_ptr.htm#BestPractices">
+boost docs: shared_ptr</a>.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void f(int, int);
+int g(void *);
+int h() __attribute__((noreturn));
 
 void test() {
-  int *p1 = new int;
-  int *p2 = new int[1];
-
-  free(p1); // warn
-  free(p2); // warn
+  // It is possible that 'malloc(1)' is called first,
+  // then 'h()', that is (or calls) noreturn and eventually
+  // 'g()' is never called.
+  f(g(malloc(1)), h()); // warn: 'g()' may never be called.
 }
-</pre></td><td class="aligned"><a href="http://llvm.org/bugs/show_bug.cgi?id=15238">PR15238</a>
-</td></tr>
-
-<tr><td><span class="name">memory.LeakPtrValChanged
-<br>enhancement to unix.Malloc<br>(C, C++)</span><br><br>
-Potential memory leak: a pointer to newly allocated data loses its original 
-value
-</td><td><pre>
-#include &lt;stdlib.h&gt;
-
-void f(const int *);
-void g(int *);
+</pre></div>
+<div class="example"><pre>
+void f(int, int);
+int g(int *);
+int h() { throw 1; };
 
 void test() {
-  int *p1 = new int;
-  p1++; // warn
-  int *p2 = (int *)malloc(sizeof(int));
-  p2 = p1; // warn
-  int *p3 = new int;
-  f(p3);
-  p3++; // warn
-  int *p4 = new int;
-  f(p4);
-  p4++; // ok
+  // It is possible that 'new int' is called first,
+  // then 'h()', that throws an exception and eventually
+  // 'g()' is never called.
+  f(g(new int), h()); // warn: 'g()' may never be called.
 }
-</pre></td><td class="aligned">done at r174678 (C case)
-</td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">memory.LeakEvalOrder<br>
-(C, C++)</span><br><br>
-Potential memory leak: argument evaluation order is undefined, g() may never be called
-</td><td><pre>
-#include &lt;stdlib.h&gt;
 
-void f1(int, int);
-void f2(int*, int*);
-int g(int *) { throw 1; };
-int h();
-
-void test() {
-  f1(g(new int), h()); // warn
-  f1(g((int *)malloc(sizeof(int))), h()); // warn
-  f2(new int, new int);
-}
-</pre></td><td class="aligned"></td></tr>
-
-<tr><td><span class="name">memory.DstBufferTooSmall
-<br>(C, C++)</span><br><br>
-Destination buffer too small
-</td><td><pre>
-#include &lt;string.h&gt;
-
+<tr><td><div class="namedescr expandable"><span class="name">
+memory.DstBufferTooSmall</span><span class="lang">
+(C, C++)</span><div class="descr">
+Destination buffer passed to memory function is too small.
+<br>Note: <span class="name">security.insecureAPI.strcpy</span> currently warns
+on usage of <code>strcpy</code> and suggests to replace it.
+<br>Note: <span class="name">alpha.unix.CStringChecker</span> contains some similar checks.
+<p>Source: <a href="https://cwe.mitre.org/data/definitions/120.html">CWE-120</a>.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 void test() {
   const char* s1 = "abc";
   char *s2 = new char;
   strcpy(s2, s1); // warn
-
+}
+</pre></div>
+<div class="example"><pre>
+void test() {
   int* p1 = new int[3];
   int* p2 = new int;
   memcpy(p2, p1, 3); // warn
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">memory.NegativeArraySize
-<br>enhancement to experimental.security.MallocOverflow<br>(C, C++)
-</span><br><br>
-'n' is used to specify the buffer size may be negative
-</td><td><pre>
-#include &lt;stdlib.h&gt;
 
+<tr><td><div class="namedescr expandable"><span class="name">
+memory.NegativeArraySize</span><span class="lang">
+(C, C++)</span><div class="descr">
+'n' is used to specify the buffer size may be negative.
+<br>Note: possibly an enhancement to <span class="name">
+alpha.security.MallocOverflow</span>.
+<p>Source: <a href="http://cwe.mitre.org/data/definitions/20.html">CWE-20,
+Example 2</a>.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 void test() {
   int *p;
   int n1 = -1;
   p = new int[n1]; // warn
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
 </table>
 
@@ -144,42 +112,45 @@
 <col class="namedescr"><col class="example"><col class="progress">
 <thead><tr><td>Name, Description</td><td>Example</td><td>Progress</td></tr></thead>
 
-<tr><td><span class="name">ctordtor.ExptInsideDtorExplicit<br>
-(C++)</span><br><br>
-It is dangerous to let an exception leave a destructor. Using try..catch will 
-solve the problem.
-</td><td><pre>
-void f();
-
+<tr><td><div class="namedescr expandable"><span class="name">
+ctordtor.ExptInsideDtor</span><span class="lang">
+(C++)</span><div class="descr">
+It is dangerous to let an exception leave a destructor.
+Using <code>try..catch</code> solves the problem.
+<p>Source: Scott Meyers "More Effective C++", item 11: Prevent exceptions from
+leaving destructors.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 class A {
   A() {}
   ~A() { throw 1; } // warn
 };
-</pre></td><td class="aligned"></td></tr>
-
-<tr><td><span class="name">ctordtor.ExptInsideDtorImplicit<br>
-(C++)</span><br><br>
-Calls to functions inside a destructor that are known to throw exceptions is 
-dangerous. Using try..catch will solve the problem.
-</td><td><pre>
-void f() { throw 1; };
+</pre></div>
+<div class="example"><pre>
+void f() throw(int);
 
 class A {
   A() {}
   ~A() { f(); } // warn
 };
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">ctordtor.PlacementSelfCopy<br>
-(C++11)</span><br><br>
-For a placement copy or move, it is almost certainly an error if the constructed object is also the object being copied from.
-</td><td><pre>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+ctordtor.PlacementSelfCopy</span><span class="lang">
+(C++11)</span><div class="descr">
+For a placement copy or move, it is almost certainly an error if the
+constructed object is also the object being copied from.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 class A {};
 
 void test(A *dst, A *src) {
   ::new (dst) A(*dst); // warn (should be 'src')
 }
-</pre></td><td class="aligned"><!--rdar://problem/13688366--></td></tr>
+</pre></div></div></td>
+<td class="aligned"><!--rdar://problem/13688366--></td></tr>
 
 </table>
 
@@ -189,37 +160,55 @@
 <col class="namedescr"><col class="example"><col class="progress">
 <thead><tr><td>Name, Description</td><td>Example</td><td>Progress</td></tr></thead>
 
-<tr><td><span class="name">valist.Uninitialized</span><br><br>
+<tr><td><div class="namedescr expandable"><span class="name">
+valist.Uninitialized</span><span class="lang">
+(C)</span><div class="descr">
 Calls to the <code>va_arg</code>, <code>va_copy</code>, or
 <code>va_end</code> macro must happen after calling <code>va_start</code> and
-before calling <code>va_end</code>.
-</td><td><pre>
+before calling <code>va_end</code>.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 #include &lt;stdarg.h&gt;
 
 void test(int x, ...) {
   va_list args;
   int y = va_arg(args, int); // warn
+}
+</pre></div>
+<div class="example"><pre>
+#include &lt;stdarg.h&gt;
+
+void test(int x, ...) {
+  va_list args;
   va_start(args, x); 
-  va_end(args, x);
+  va_end(args);
   int z = va_arg(args, int); // warn
 }
-</pre></td><td class="aligned"><a href="http://llvm.org/bugs/show_bug.cgi?id=16812">PR16811</a></td></tr>
+</pre></div></div></td>
+<td class="aligned"><a href="http://llvm.org/bugs/show_bug.cgi?id=16812">
+PR16811</a></td></tr>
 
-<tr><td><span class="name">valist.Unterminated</span><br><br>
+<tr><td><div class="namedescr expandable"><span class="name">
+valist.Unterminated</span><span class="lang">
+(C)</span><div class="descr">
 Every <code>va_start</code> must be matched by a <code>va_end</code>. A va_list
 can only be ended once.
 
-<i>This should be folded into the generalized "ownership checker" described on the <a href="open_projects.html">Open Projects</a> page.</i>
-</td><td><pre>
+<i>This should be folded into the generalized "ownership checker"
+described on the <a href="open_projects.html">
+Open Projects</a> page.</i></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 #include &lt;stdarg.h&gt;
 
 void test(int x, ...) {
   va_list args;
   va_start(args, x);
   int y = x + va_arg(args, int);
-  // missing va_end
-}
-</pre></td><td class="aligned"><a href="http://llvm.org/bugs/show_bug.cgi?id=16812">PR16812</a></td></tr>
+} // warn: missing va_end
+</pre></div></div></td>
+<td class="aligned"><a href="http://llvm.org/bugs/show_bug.cgi?id=16812">
+PR16812</a></td></tr>
 
 </table>
 
@@ -229,34 +218,48 @@
 <col class="namedescr"><col class="example"><col class="progress">
 <thead><tr><td>Name, Description</td><td>Example</td><td>Progress</td></tr></thead>
 
-<tr><td><span class="name">exceptions.ThrowSpecButNotThrow
-<br>(C++)</span><br><br>
-Function prototype has throw(T) specifier but the function do not throw
-</td><td><pre>
-void f() throw(int) { // warn
-}
-</pre></td><td class="aligned"></td></tr>
+<tr><td><div class="namedescr expandable"><span class="name">
+exceptions.ThrowSpecButNotThrow</span><span class="lang">
+(C++)</span><div class="descr">
+Function declaration has a <code>throw(<i>type</i>)</code> specifier but the
+function do not throw exceptions.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() throw(int) {
+} // warn
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">exceptions.NoThrowSpecButThrows
-<br>(C++)</span><br><br>
-An exception is throw from a function having the throw() specifier
-</td><td><pre>
-void f() throw() {
+
+<tr><td><div class="namedescr expandable"><span class="name">
+exceptions.NoThrowSpecButThrows</span><span class="lang">
+(C++)</span><div class="descr">
+An exception is throw from a function having a <code>throw()</code>
+specifier.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() throw() {
   throw(1); // warn
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">exceptions.ThrownTypeDiffersSpec
-<br>(C++)</span><br><br>
-The type of a thrown exception differs from those specified in the throw(T) 
-specifier
-</td><td><pre>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+exceptions.ThrownTypeDiffersSpec</span><span class="lang">
+(C++)</span><div class="descr">
+The type of a thrown exception differs from those specified in
+a <code>throw(<i>type</i>)</code> specifier.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 struct S{};
-void f() throw(int) {
+
+void test() throw(int) {
   S s;
   throw (s); // warn
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
 </table>
 
@@ -266,25 +269,36 @@
 <col class="namedescr"><col class="example"><col class="progress">
 <thead><tr><td>Name, Description</td><td>Example</td><td>Progress</td></tr></thead>
 
-<tr><td><span class="name">smartptr.SmartPtrInit<br>
-(C++)</span><br><br>
-C++03: auto_ptr should store a pointer to an object obtained via new as allocated
-memory will be cleaned using delete<br>
-C++11: one should use unique_ptr&lt;T[]&gt; to keep a pointer to memory
-allocated by new[]<br>
-C++11: to keep a pointer to memory allocated by new[] in a shared_ptr one
-should use a custom deleter that calls delete[]
-</td><td><pre>
+<tr><td><div class="namedescr expandable"><span class="name">
+smartptr.SmartPtrInit</span><span class="lang">
+(C++)</span><div class="descr">
+C++03: <code>auto_ptr</code> should store a pointer to an object obtained via
+new as allocated memory will be cleaned using <code>delete</code>.<br>
+C++11: one should use <code>unique_ptr&lt;<i>type</i>[]&gt;</code> to keep a
+pointer to memory allocated by <code>new[]</code>.<br>
+C++11: to keep a pointer to memory allocated by <code>new[]</code> in
+a <code>shared_ptr</code> one should use a custom deleter that calls <code>
+delete[].</code>.
+<p>Source: C++03 20.4.5p1; C++11 <code>auto_ptr</code> is deprecated (D.10).</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 #include &lt;stdlib.h&gt;
 #include &lt;memory&gt;
 
 void test() {
   std::auto_ptr&lt;int&gt; p1(new int); // Ok
   std::auto_ptr&lt;int&gt; p2(new int[3]); // warn
-  std::auto_ptr&lt;int&gt; 
-         p3((int *)malloc(sizeof(int))); // warn
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div>
+<div class="example"><pre>
+#include &lt;stdlib.h&gt;
+#include &lt;memory&gt;
+
+void test() {
+  std::auto_ptr&lt;int&gt; p((int *)malloc(sizeof(int))); // warn
+}
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
 </table>
 
@@ -294,23 +308,90 @@
 <col class="namedescr"><col class="example"><col class="progress">
 <thead><tr><td>Name, Description</td><td>Example</td><td>Progress</td></tr></thead>
 
-<tr><td><span class="name">deadcode.UnmodifiedVariable
-<br>(C, C++)</span><br><br>
-A variable is never modified but was not declared const and is not a reference.
-<br><br>
-<i>(opt-in checker)</i>
-</td><td><pre>
+<tr><td><div class="namedescr expandable"><span class="name">
+deadcode.UnmodifiedVariable</span><span class="lang">
+(C, C++)</span><div class="descr">
+A variable is never modified but was not declared const and is not a
+reference.<br><br><i>(opt-in checker)</i></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 extern int computeDelta();
 
-int foo(bool cond) {
+int test(bool cond) {
   int i = 0;
   if (cond) {
     const int delta = computeDelta();
-    // Forgot to modify 'i'.
+    // warn: forgot to modify 'i'
   }
   return i;
 }
-</pre></td><td class="aligned"><a href="http://llvm.org/bugs/show_bug.cgi?id=16890">PR16890</a></td></tr>
+</pre></div></div></td>
+<td class="aligned"><a href="http://llvm.org/bugs/show_bug.cgi?id=16890">PR16890</a></td></tr>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+deadcode.IdempotentOperations</span><span class="lang">
+(C)</span><div class="descr">
+Warn about idempotent operations.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  int x = 7;
+  x = x; // warn: value is always the same
+}
+</pre></div>
+<div class="example"><pre>
+void test() {
+  int x = 7;
+  x /= x; // warn: value is always 1
+}
+</pre></div>
+<div class="example"><pre>
+void test() {
+  int x = 7, one = 1;
+  x *= one; // warn: right op is always 1
+}
+</pre></div>
+<div class="example"><pre>
+void test() {
+  int x = 7, zero = 0;
+  x = x - zero;
+   // warn: the right operand to '-' is always 0
+}
+</pre></div></div></td>
+<td class="aligned">removed from alpha.deadcode.* at r198476</td></tr>
+
+</table>
+
+<!-- ================================ POSIX ================================ -->
+<h3>POSIX</h3>
+<table class="checkers">
+<col class="namedescr"><col class="example"><col class="progress">
+<thead><tr><td>Name, Description</td><td>Example</td><td>Progress</td></tr></thead>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+posix.Errno</span><span class="lang">
+(C)</span><div class="descr">
+Record that <code>errno</code> is non-zero when certain functions
+fail.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+#include &lt;stdlib.h&gt;
+
+int readWrapper(int fd, int *count) {
+  int lcount = read(fd, globalBuf, sizeof(globalBuf));
+  if (lcount < 0)
+    return errno;
+  *count = lcount;
+  return 0;
+}
+
+void use(int fd) {
+  int count;
+  if (!readWrapper(fd, &amp;count))
+    print("%d", count); // should not warn
+}
+</pre></div></div></td>
+<td class="aligned"><a href="http://llvm.org/bugs/show_bug.cgi?id=18701">PR18701</a></td></tr>
 
 </table>
 
@@ -320,11 +401,14 @@
 <col class="namedescr"><col class="example"><col class="progress">
 <thead><tr><td>Name, Description</td><td>Example</td><td>Progress</td></tr></thead>
 
-<tr><td><span class="name">undefbehavior.ExitInDtor
-<br>(C++)</span><br><br>
-Undefined behavior: std::exit is called to end the program during the 
-destruction of an object with static storage duration
-</td><td><pre>
+<tr><td><div class="namedescr expandable"><span class="name">
+undefbehavior.ExitInDtor</span><span class="lang">
+(C++)</span><div class="descr">
+Undefined behavior: <code>std::exit()</code> is called to end the program during
+the destruction of an object with static storage duration.
+<p>Source: C++11 3.6.1p4.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 #include &lt;cstdlib&gt;
 
 class A {
@@ -333,17 +417,20 @@
     std::exit(1); // warn
   }
 };
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-A a;
-</pre></td><td class="aligned"></td></tr>
 
-<tr><td><span class="name">undefbehavior.LocalStaticDestroyed
-<br>(C++)</span><br><br>
+<tr><td><div class="namedescr expandable"><span class="name">
+undefbehavior.LocalStaticDestroyed</span><span class="lang">
+(C++)</span><div class="descr">
 Undefined behavior: function containing a definition of static local object is 
 called during the destruction of an object with static storage duration so that 
 flow of control passes through the definition of the previously destroyed 
-static local object
-</td><td><pre>
+static local object.
+<p>Source: C++11 3.6.3p2.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 void f();
 
 class A {
@@ -358,299 +445,383 @@
 A a;
 
 void f() {
-  static B b; // &lt;-
+  static B b;
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">undefbehavior.UseAfterRelease
-<br>enhancement to unix.Malloc<br>(C, C++)</span><br><br>
-Pointer to deleted object is referenced (The effect of using an invalid pointer 
-value is undefined)
-</td><td><pre>
-#include &lt;stdlib.h&gt;
 
-void test() {
-  int *p = new int;
-  delete p;
-  int i = *p; // warn
-}
-
-</pre></td><td class="aligned"></td></tr>
-
-<tr><td><span class="name">undefbehavior.ZeroAllocDereference
-<br>enhancement to unix.Malloc<br>(C, C++)</span><br><br>
+<tr><td><div class="namedescr expandable"><span class="name">
+undefbehavior.ZeroAllocDereference</span><span class="lang">
+(C, C++)</span><div class="descr">
 The effect of dereferencing a pointer returned as a request for zero size is 
-undefined
-</td><td><pre>
-#include &lt;stdlib.h&gt;
+undefined.<br>
+Note: possibly an enhancement to <span class="name">
+unix.Malloc</span>.
+<p>Source: C++03 3.7.3.1p2; C++11 3.7.4.1p2.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+int *p = malloc(0);
+*p = 1; // warn
+</pre></div>
+<div class="example"><pre>
+int *p = new int{};
+int i = *p; // warn
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-int *p = new int[0];
-int i = p[0]; // warn
-</pre></td><td class="aligned"></td></tr>
 
-<tr><td><span class="name">undefbehavior.DeadReferenced
-<br>(C++)</span><br><br>
-Undefined behavior: the following usage of the pointer to the object whose 
-lifetime has ended can result in undefined behavior
-</td><td><pre>
-// C++03
+<tr><td><div class="namedescr expandable"><span class="name">
+undefbehavior.DeadReferenced</span><span class="lang">
+(C++)</span><div class="descr">
+Undefined behavior: the following usage of the pointer to the object whose
+lifetime has ended can result in undefined behavior:<br>
+The object will be or was of a class type with a non-trivial destructor and
+<ul><li>the pointer is used as the operand of a delete-expression</li></ul>
+The object will be or was of a non-POD class type (C++11: any class type) and
+<ul><li>the pointer is used to access a non-static data member or call a
+non-static member function of the object</li>
+<li>the pointer is implicitly converted to a pointer to a base class
+type</li>
+<li>the pointer is used as the operand of a <code>static_cast</code> (except
+when the conversion is to <code>void*</code>, or to <code>void*</code> and 
+subsequently to <code>char*</code>, or <code>unsigned char*</code>)</li>
+<li>the pointer is used as the operand of a <code>dynamic_cast</code></li></ul>
+<p>Source: C++03 3.8p5, p7; C++11 3.8p5, p7.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 #include &lt;new&gt;
 
 class A {
 public:
-  int i;
-  void f() {};
+  ~A();
 };
 
-class B : public A {
-};
-
-void test() {
-  B *b = new B;
-  new(b) A;
-  b->i; // warn
-  b->f(); // warn
-  static_cast&lt;A*&gt;(b); // warn
-  dynamic_cast&lt;A*&gt;(b); // warn
-  delete b; // warn
-}
-
-// C++11
-#include &lt;new&gt;
-
-class A {
-public:
-  int i;
-  void f() {};
-};
-
-class B : public A {
-public:
-  ~B() {};
-};
+class B : public A {};
 
 void test() {
   A *a = new A;
   new(a) B;
-  a->i; // warn
-  a->f(); // warn
-  B *b = new B;
-  new(b) A;
-  b->i; // warn
-  b->f(); // warn
-  static_cast&lt;A*&gt;(b); // warn
-  dynamic_cast&lt;A*&gt;(b); // warn
-  delete b; // warn
+  delete a; // warn
 }
-</pre></td><td class="aligned"></td></tr>
-
-<tr><td><span class="name">undefbehavior.ObjLocChanges
-<br>(C++)</span><br><br>
-Undefined behavior: the program must ensure that an object occupies the same 
-storage location when the implicit or explicit destructor call takes place
-</td><td><pre>
+</pre></div>
+<div class="example"><pre>
 #include &lt;new&gt;
 
-class T { };
-struct B {
+class A {
+public:
+  ~A();
+};
+
+class B {};
+
+void test() {
+  A *a = new A;
+  new(a) B;
+  a->~A();
+}
+</pre></div>
+<div class="example"><pre>
+#include &lt;new&gt;
+
+class A {
+public:
+  ~A();
+};
+
+class B : public A {};
+
+class C {};
+
+void f(A*);
+
+void test() {
+  B *b = new B;
+  new(b) C;
+  f(b); // warn
+}
+</pre></div>
+<div class="example"><pre>
+#include &lt;new&gt;
+
+class A {
+public:
+  ~A();
+};
+
+class B : public A {};
+
+class C {};
+
+A* test() {
+  B *b = new B;
+  new(b) C;
+  return static_cast&lt;A*&gt;(b); // warn
+}
+</pre></div>
+<div class="example"><pre>
+#include &lt;new&gt;
+
+class A {
+public:
+  ~A();
+};
+
+class B : public A {};
+
+class C {};
+
+A* test() {
+  B *b = new B;
+  new(b) C;
+  return dynamic_cast&lt;A*&gt;(b); // warn
+}
+</pre></div></div></td>
+<td class="aligned"></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+undefbehavior.ObjLocChanges</span><span class="lang">
+(C++)</span><div class="descr">
+Undefined behavior: the program must ensure that an object occupies the same 
+storage location when the implicit or explicit destructor call takes place.
+<p>Source: C++11 3.8p8.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+#include &lt;new&gt;
+
+class A {};
+
+class B {
+public:
   ~B();
 };
 
 void test() {
-  B *b1 = new B;
-  B b2;
-  new (b1) T;
-  new (&amp;b2) T;
-  delete b1; // warn
+  B b;
+  new (&b) A;
 } // warn
-</pre></td><td class="aligned"></td></tr>
+</pre></div>
+<div class="example"><pre>
+#include &lt;new&gt;
 
-<tr><td><span class="name">undefbehavior.ExprEvalOrderUndef
-<br>(C, C++03)</span><br><br>
-Undefined behavior: a scalar object shall have its stored value modified at 
-most once by the evaluation of an expression
-</td><td><pre>
-void test () {
-  int i = 0;
-  int v[1] = {0};
-  i = v[i++]; // warn
-  i = ++i + 1; // warn
-}
-</pre></td><td class="aligned"></td></tr>
+class A {};
 
-<tr><td><span class="name">undefbehavior.StaticInitReentered
-<br>(C)</span><br><br>
-Undefined behavior: static declaration is re-entered while the object is being 
-initialized
-</td><td><pre>
-int test(int i) {
-  static int s = test(2*i); // warn
-  return i+1;
-}
-</pre></td><td class="aligned"></td></tr>
-
-<tr><td><span class="name">undefbehavior.ConstModified
-<br>(C, C++)</span><br><br>
-Undefined behavior: const object is being modified
-</td><td><pre>
-#include &lt;stdlib.h&gt;
-
-class X {
-public :
-  mutable int i;
-  int j;
-};
-class Y {
-public :
-  X x;
-  Y();
+class B {
+public:
+  ~B();
 };
 
 void test() {
-  const int *ciq = 
-    (int *)malloc(sizeof(int));
-  int *iq = const_cast&lt;int *&gt;(ciq);
-  *iq = 1; // warn
-
-  const Y y;
-  Y* p = const_cast&lt;Y*&gt;(&amp;y);
-  p-&gt;x.i = 1; // ok
-  p-&gt;x.j = 1; // warn
+  B *b = new B;
+  new (b) A;
+  delete b; // warn
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">undefbehavior.DeadDestructed
-<br>(C++)</span><br><br>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+undefbehavior.ExprEvalOrderUndef</span><span class="lang">
+(C, C++03)</span><div class="descr">
+Undefined behavior: a scalar object shall have its stored value modified at 
+most once by the evaluation of an expression.<br>
+Note: most cases are currently handled by the Clang core (search for 'multiple
+unsequenced modifications' warning in Clang tests).
+<p>Source: C++03 5p4.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+int test () {
+  int i = 0;
+  i = ++i + 1; // warn
+  return i;
+}
+</pre></div></div></td>
+<td class="aligned"></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+undefbehavior.StaticInitReentered</span><span class="lang">
+(C++)</span><div class="descr">
+Undefined behavior: static declaration is re-entered while the object is being 
+initialized.
+<p>Source: C++11 6.7p4.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+int test(int i) {
+  static int s = test(2 * i); // warn
+  return i + 1;
+}
+</pre></div></div></td>
+<td class="aligned"></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+undefbehavior.ConstModified</span><span class="lang">
+(C, C++)</span><div class="descr">
+Undefined behavior: const object is being modified.
+<p>Source: C++03 7.1.5.1p4, C++11 7.1.6.1p4.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  const int *cp = new const int (0);
+  int *p = const_cast&lt;int *&gt;(cp);
+  *p = 1; // warn
+  delete p;
+}
+</pre></div>
+<div class="example"><pre>
+class C {
+public :
+  int i;
+  C();
+};
+
+void test() {
+  const C cb;
+
+  C* cp = const_cast&lt;C *&gt;(&cb);
+  cp-&gt;i = 1; // warn
+}
+</pre></div></div></td>
+<td class="aligned"></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+undefbehavior.DeadDestructed</span><span class="lang">
+(C++)</span><div class="descr">
 Undefined behavior: the destructor is invoked for an object whose lifetime 
-has ended
-</td><td><pre>
+has ended.
+<p>Source: C++11 12.4p14.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 class A {
 public:
-  void f() {};
-  A() {};
-  ~A() {};
+  void f();
+  A();
+  ~A();
 };
 
 void test() {
   A a;
   a.~A();
 } // warn
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">undefbehavior.MethodCallBeforeBaseInit
-<br>(C++)</span><br><br>
-Undefined behavior: calls member function but base not yet initialized
-</td><td><pre>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+undefbehavior.MethodCallBeforeBaseInit</span><span class="lang">
+(C++)</span><div class="descr">
+Undefined behavior: calls member function but base not yet initialized.
+<p>Source: C++03 12.6.2p8; C++11 12.6.2p13.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 class A {
 public :
-  A(int );
+  A(int);
 };
+
 class B : public A {
 public :
   int f();
   B() : A(f()) {} // warn
 };
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">undefbehavior.MemberOrBaseRefBeforeCtor
-<br>(C++)</span><br><br>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+undefbehavior.MemberOrBaseRefBeforeCtor</span><span class="lang">
+(C++)</span><div class="descr">
 C++ Undefined behavior: non-static member or base class of non-POD class type 
-is referred before constructor begins execution<br>
+is referred before constructor begins execution.<br>
 C++11 Undefined behavior: non-static member or base class of a class with a 
-non-trivial constructor is referred before constructor begins execution
-</td><td><pre>
-// C++03
+non-trivial constructor is referred before constructor begins execution.
+<p>Source: C++03 12.7p1; C++11 12.7p1.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+struct non_POD {
+  int i;
+  non_POD();
+};
+
+extern non_POD non_pod;
+
+int *p = &amp;non_pod.i; // warn
+</pre></div>
+<div class="example"><pre>
 struct POD { 
   int i; 
 };
 
-struct non_POD : public POD { 
-  int j; 
+struct non_POD : public POD {
   POD pod;
 };
 
-extern POD pod;
 extern non_POD non_pod;
 
-int *p1 = &amp;non_pod.j; // warn
-int *p2 = &amp;non_pod.pod.i; // warn
-int *p3 = &amp;pod.i; // ok
-POD *p4 = &amp;non_pod; // warn
+int *p = &amp;non_pod.pod.i; // warn
+</pre></div>
+<div class="example"><pre>
+struct POD {
+  int i; 
+};
 
-POD a;
-non_POD b;
+struct non_POD : public POD {};
+
+extern non_POD non_pod;
+
+POD *p = &amp;non_pod; // warn
+</pre></div>
+<div class="example"><pre>
+struct non_POD {
+  int i;
+  non_POD();
+};
 
 struct S {
   int *k;
   non_POD non_pod;
-  S() : k(&amp;non_pod.j) {} // warn
+  S() : k(&amp;non_pod.i) {} // warn
 };
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-// C++11
-struct trivial { 
-  int i; 
-};
 
-struct non_trivial: public trivial { 
-  non_trivial() {};
-  int j; 
-  trivial pod;
-};
-
-extern trivial t;
-extern non_trivial nt;
-
-int *p1 = &amp;nt.j; // warn
-int *p2 = &amp;nt.i; // warn
-int *p3 = &amp;t.i; // ok
-trivial *p4 = &amp;nt;
-
-trivial t;
-non_trivial nt;
-
-struct S {
-  int *k;
-  non_trivial nt;
-  S() : k(&amp;nt.j) {} // warn
-};
-</pre></td><td class="aligned"></td></tr>
-
-<tr><td><span class="name">undefbehavior.MemberRefAfterDtor
-<br>(C++)</span><br><br>
+<tr><td><div class="namedescr expandable"><span class="name">
+undefbehavior.MemberRefAfterDtor</span><span class="lang">
+(C++)</span><div class="descr">
 C++03: Undefined behavior: non-static member of non-POD class type is referred 
-after destructor ends execution<br>
+after destructor ends execution.<br>
 C++11: Undefined behavior: non-static member of a class with a non-trivial 
-destructor is referred after destructor ends execution
-</td><td><pre>
-// C++03
-struct non_POD {
-  virtual void f() {};
+destructor is referred after destructor ends execution.
+<p>Source: C++03 12.7p1; C++11 12.7p1.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+class C {
+public:
+  C();
+  void f();
 };
 
 void test() {
-  non_POD *non_pod = new non_POD();
-  non_pod->~non_POD();  
-  non_pod->f(); // warn
+  C *c = new C();
+  c-&gt;~C();
+  c-&gt;f(); // warn
 }
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-// C++11
-struct S {
-  ~S() {};
-  void f() {};
-};
 
-void test() {
-  S *s = new S();
-  s->~S();  
-  s->f(); // warn
-}
-</pre></td><td class="aligned"></td></tr>
-
-<tr><td><span class="name">undefbehavior.CtorForeignCall
-<br>(C++)</span><br><br>
+<tr><td><div class="namedescr expandable"><span class="name">
+undefbehavior.CtorForeignCall</span><span class="lang">
+(C++)</span><div class="descr">
 Undefined behavior: call to virtual function of an object under construction 
-whose type is neither the constructors own class or one of its bases
-</td><td><pre>
+whose type is neither the constructors own class or one of its bases.
+<p>Source: C++11 12.7p4.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 class A {
 public:
   virtual void f() {};
@@ -665,15 +836,47 @@
 public:
   C() : B((A*)this) {}
 };
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">undefbehavior.CtorForeignCast 
-undefbehavior.CtorForeignTypeid
-<br>(C++)</span><br><br>
-Undefined behavior: the operand of typeid/dynamic_cast is an object under 
+
+<tr><td><div class="namedescr expandable"><span class="name">
+undefbehavior.CtorForeignTypeid</span><span class="lang">
+(C++)</span><div class="descr">
+Undefined behavior: the operand of <code>typeid</code> is an object under
 construction whose type is neither the constructors own class or one of its 
-bases
-</td><td><pre>
+bases.
+<p>Source: C++11 12.7p5.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+#include &lt;typeinfo&gt;
+
+class A {};
+
+class B {
+public:
+  B(A* a) {
+    (void)typeid(*a); // warn
+  }
+};
+
+class C : public A, B {
+public:
+  C() : B((A*)this) {}
+};
+</pre></div></div></td>
+<td class="aligned"></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+undefbehavior.CtorForeignCast</span><span class="lang">
+(C++)</span><div class="descr">
+Undefined behavior: the operand of <code>dynamic_cast</code> is an object under
+construction whose type is neither the constructors own class or one of its
+bases.
+<p>Source: C++11 12.7p6.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 #include &lt;typeinfo&gt;
 
 class A {
@@ -684,8 +887,7 @@
 class B {
 public:
   B(A* a) { 
-    typeid(*a); // warn
-    dynamic_cast&lt;B*&gt;(a); //warn
+    (void)dynamic_cast&lt;B*&gt;(a); //warn
   }
 };
 
@@ -693,45 +895,83 @@
 public:
   C() : B((A*)this) {}
 };
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">undefbehavior.MemberRefInCatch 
-undefbehavior.BaseRefInCatch
-<br>(C++)</span><br><br>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+undefbehavior.MemberOrBaseRefInCatch</span><span class="lang">
+(C++)</span><div class="descr">
 Undefined behavior: referring to any non-static member or base class of an 
 object in the handler for a function-try-block of a constructor or destructor 
-for that object results in undefined behavior
-</td><td><pre>
+for that object results in undefined behavior.
+<p>Source: C++11 15.3p10.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void f() { throw 1; }
+
 class C {
   int i;
 public :
   C()
-  try
-  : i(1) {}
-  catch (...)
-  {
+  try {
+    f();
+  }
+  catch (...) {
     i=2; // warn
   }
 };
-</pre></td><td class="aligned"></td></tr>
+</pre></div>
+<div class="example"><pre>
+void f() { throw 1; }
 
-<tr><td><span class="name">undefbehavior.ReturnAtCatchEnd
-<br>(C++)</span><br><br>
+class Base {
+public:
+  int i;
+};
+
+class C: public Base {
+public :
+  ~C() try {
+    f();
+  }
+  catch (...) {
+    i=2; // warn
+  }
+};
+</pre></div></div></td>
+<td class="aligned"></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+undefbehavior.ReturnAtCatchEnd</span><span class="lang">
+(C++)</span><div class="descr">
 Undefined behavior: a function returns when control reaches the end of a 
-handler. This results in undefined behavior in a value-returning 
-function
-</td><td><pre>
+handler. This results in undefined behavior in a value-returning function.
+<p>Source: C++11 15.3p10.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void f() { throw 1; }
+
 int test() try {
+  f();
+  return 1;
 }
 catch(int) {
 } // warn
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">undefbehavior.AutoptrsOwnSameObj
-<br>(C++03)</span><br><br>
-Undefined behavior: if more than one auto_ptr owns the same object at the same 
-time the behavior of the program is undefined.
-</td><td><pre>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+undefbehavior.AutoptrsOwnSameObj</span><span class="lang">
+(C++03)</span><div class="descr">
+Undefined behavior: if more than one <code>auto_ptr</code> owns the same object
+at the same time the behavior of the program is undefined.
+<p>Source: C++03 20.4.5p3; C++11 <code>auto_ptr</code> is deprecated
+(D.10).</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 #include &lt;memory&gt;
 
 void test() {
@@ -739,71 +979,83 @@
   std::auto_ptr&lt;int&gt; p(data);
   std::auto_ptr&lt;int&gt; q(data); // warn
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">undefbehavior.BasicStringBoundAccess
-<br>(C++03)</span><br><br>
-Undefined behavior: out-of-bound basic_string access
-</td><td><pre>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+undefbehavior.BasicStringOutOfBound</span><span class="lang">
+(C++03)</span><div class="descr">
+Undefined behavior: out-of-bound <code>basic_string</code> access/modification.
+<br>Note: possibly an enhancement to <span class="name">
+alpha.security.ArrayBoundV2</span>.
+<p>Source: C++03 21.3.4p1; C++11 behavior is defined
+(21.4.5p2).</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+#include &lt;string&gt;
+
 void test() {
   std::basic_string&lt;char&gt; s;
   char c = s[10]; // warn
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div>
+<div class="example"><pre>
+#include &lt;string&gt;
 
-<tr><td><span class="name">undefbehavior.BasicStringBoundModification
-<br>(C++)</span><br><br>
-Undefined behavior: out-of-bound basic_string modification
-</td><td><pre>
 void test() {
   std::basic_string&lt;char&gt; s;
   s[10] = 0; // warn
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">undefbehavior.EosDereference
-<br>(C++)</span><br><br>
-Undefined behavior: the result of operator*() on an end of stream is 
-undefined
-</td><td><pre>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+undefbehavior.EosDereference</span><span class="lang">
+(C++)</span><div class="descr">
+Undefined behavior: the result of <code>operator*()</code> on an end of a
+stream is undefined.
+<p>Source: C++03 24.5.3p2; C++11 24.6.3p2.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 #include &lt;vector&gt;
 
-void test() {
+int test() {
   std::vector&lt;int&gt; v;
-  int i = *v.end(); // warn
-  *v.end() = 0; // warn
+  return *v.end(); // warn
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">undefbehavior.QsortNonPOD 
-undefbehavior.QsortNonTrivial
-<br>C++</span><br><br>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+undefbehavior.QsortNonPODNonTrivial</span><span class="lang">
+(C++)</span><div class="descr">
 C++03: Undefined behavior: the objects in the array passed to qsort are of 
-non-POD type<br>
+non-POD type.<br>
 C++11: Undefined behavior: the objects in the array passed to qsort are of 
-non-trivial type
-</td><td><pre>
+non-trivial type.
+<p>Source: C++03 25.4p4; C++11 25.5p4.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 // C++03
 #include &lt;cstdlib&gt;
 
+
 struct non_POD {
-  int i;
-  non_POD(int ii) : i(ii) {}
+  non_POD();
 };
 
-non_POD values[] = { non_POD(2), non_POD(1) };
+non_POD values[] = { non_POD(), non_POD() };
 
-int compare(const void *a, 
-            const void *b) {
-  return ( (*(non_POD*)a).i -
-           (*(non_POD*)b).i );
-}
+int compare(const void *a, const void *b);
 
 void test() {
-  qsort(values, 2, sizeof(non_POD), 
-        compare); // warn
+  qsort(values, 2, sizeof(non_POD), compare); // warn
 }
-
+</pre></div>
+<div class="example"><pre>
 // C++11
 #include &lt;cstdlib&gt;
 
@@ -815,57 +1067,64 @@
 
 struct non_trivial {
   int i;
-  non_trivial() {}
+  non_trivial();
 };
 
 trivial_non_POD tnp[2];
 non_trivial nt[2];
 
-int compare1(const void *a, 
-             const void *b) {
-  return ( (*(trivial_non_POD *)a).i -
-           (*(trivial_non_POD *)b).i );
-}
+int compare1(const void *a, const void *b);
 
-int compare2(const void *a, 
-             const void *b) {
-  return ( (*(non_trivial *)a).i -
-           (*(non_trivial *)b).i );
-}
+int compare2(const void *a, const void *b);
 
 void test() {
-  qsort(tnp, 2, sizeof(trivial_non_POD), 
-        compare1); // ok
-  qsort(nt, 2, sizeof(non_trivial), 
-        compare2); // warn
+  qsort(tnp, 2, sizeof(trivial_non_POD), compare1); // ok
+  qsort(nt, 2, sizeof(non_trivial), compare2); // warn
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">undefbehavior.ThrowWhileCopy
-<br>C++</span><br><br>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+undefbehavior.ThrowWhileCopy</span><span class="lang">
+(C++)</span><div class="descr">
 Undefined behavior: copy constructor/assignment operator can throw an exception.
-The effects are undefined if an exception is thrown.
-</td><td><pre>
-struct S {
+The effects are undefined if an exception is thrown.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+class C {
+public:
   int i, j;
-  S (const S &amp;s) {
-    i = s.i;
+  C (const C &amp;c) {
+    i = c.i;
     throw 1; // warn
-    j = s.j;
+    j = c.j;
   };
-  S &amp;operator=(const S &amp;s) {
-    i = s.i;
-    throw 1; // warn
-    j = s.j;
-  }
 };
-</pre></td><td class="aligned"></td></tr>
+</pre></div>
+<div class="example"><pre>
+class C {
+public:
+  int i, j;
+  C &amp;operator=(const C &amp;c) {
+    i = c.i;
+    throw 1; // warn
+    j = c.j;
+  };
+};
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">undefbehavior.ValarrayArgBound
-<br>(C++)</span><br><br>
-Undefined behavior: the value of the second argument is greater than the number 
-of values pointed to by the first argument
-</td><td><pre>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+undefbehavior.ValarrayArgBound</span><span class="lang">
+(C++)</span><div class="descr">
+Undefined behavior: the value of the <code><i>n</i></code> argument passed
+to <code>valarray</code> constructor is greater than the number of values
+pointed to by the first argument (source).
+<p>Source: C++03 26.3.2.1p4; C++11 26.6.2.2p4.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 #include &lt;valarray&gt;
 
 struct S {
@@ -877,88 +1136,133 @@
   S s[] = { S(1), S(2) };
   std::valarray&lt;S&gt; v(s,3); // warn
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">undefbehavior.ValarrayLengthDiffer
-<br>(C++)</span><br><br>
-Undefined behavior: valarray operands are of different length
-</td><td><pre>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+undefbehavior.ValarrayLengthDiffer</span><span class="lang">
+(C++)</span><div class="descr">
+Undefined behavior: <code>valarray</code> operands are of different length.
+<p>Source: C++03 26.3.2.2p1, 26.3.2.6p3, 26.3.3.1p3, 26.3.3.2p3;
+C++11 defined (26.6.2.3p1), 26.6.2.7p3, 26.6.3.1p3,
+26.6.3.2p3.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 // C++03
 #include &lt;valarray&gt;
 
 void test(void) {
   std::valarray&lt;int&gt; a(0, 1), b(0, 2);
-  std::valarray&lt;bool&gt; c(false, 1);
   a = b; // warn
-  a *= b; // warn
-  a = a * b; // warn
-  c = a == b; // warn
   b.resize(1);
-  a = b; // OK
+  a = b; // ok
 }
+</pre></div>
+<div class="example"><pre>
+// C++03, C++11
+#include &lt;valarray&gt;
 
-// C++11
+void test(void) {
+  std::valarray&lt;int&gt; a(0, 1), b(0, 2);
+  a *= b; // warn
+}
+</pre></div>
+<div class="example"><pre>
+// C++03, C++11
+#include &lt;valarray&gt;
+
+void test(void) {
+  std::valarray&lt;int&gt; a(0, 1), b(0, 2);
+  a = a + b; // warn
+}
+</pre></div>
+<div class="example"><pre>
+// C++03, C++11
 #include &lt;valarray&gt;
 
 void test(void) {
   std::valarray&lt;int&gt; a(0, 1), b(0, 2);
   std::valarray&lt;bool&gt; c(false, 1);
-  a = b; // ok
-  a *= b; // ok
-  a = a * b; // warn
   c = a == b; // warn
-  b.resize(1);
-  a = b; // OK
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">undefbehavior.ValarrayZeroLength
-<br>(C++)</span><br><br>
-Undefined behavior: calling sum()/min()/max() method of an array having zero 
-length, the behavior is undefined
-</td><td><pre>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+undefbehavior.ValarrayZeroLength</span><span class="lang">
+(C++)</span><div class="descr">
+Undefined behavior: calling <code>sum()</code>/<code>min()</code>/<code>
+max()</code> methods of a zero length <code>valarray<code> the behavior is
+undefined.
+<p>Source: C++03 26.3.2.7p2, p3, p4; C++11 26.6.2.8p5, p6,
+p7.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 #include &lt;valarray&gt;
 
 void test(void) {
   std::valarray&lt;int&gt; v(0, 0);
   v.sum(); // warn
-  v.min(); // warn
-  v.max(); // warn
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">undefbehavior.ValarrayBadIndirection
-<br>(C++)</span><br><br>
-Undefined behavior: element N is specified more than once in the 
-indirection
-</td><td><pre>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+undefbehavior.ValarrayBadIndirection</span><span class="lang">
+(C++)</span><div class="descr">
+Undefined behavior: element is specified more than once in an indirection.
+<p>Source: C++03 26.3.9.2p2, 26.3.9.3p2; C++11 26.6.9.2p2,
+26.6.9.3p2.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 #include &lt;valarray&gt;
 
 void test() {
-  size_t addr[] = {0, 1, 1}; // N is 1
+  // '1' is specified more then once
+  size_t addr[] = {0, 1, 1};
   std::valarray&lt;size_t&gt;indirect(addr, 3);
   std::valarray&lt;int&gt; a(0, 5), b(1, 3);
   a[indirect] = b; //warn
+}
+</pre></div>
+<div class="example"><pre>
+#include &lt;valarray&gt;
+
+void test() {
+  // '1' is specified more then once
+  size_t addr[] = {0, 1, 1};
+  std::valarray&lt;size_t&gt;indirect(addr, 3);
+  std::valarray&lt;int&gt; a(0, 5), b(1, 3);
   a[indirect] *= b; //warn
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">undefbehavior.IosBaseDestroyedBeforeInit
-<br>(C++)</span><br>
-<br>Undefined behavior: ios_base object is destroyed before initialization have 
-taken place. basic_ios::init should be call to initialize ios_base 
-members
-</td><td><pre>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+undefbehavior.IosBaseDestroyedBeforeInit</span><span class="lang">
+(C++)</span><div class="descr">
+Undefined behavior: <code>ios_base</code> object is destroyed before
+initialization have taken place. <code>basic_ios::init</code> should be call to
+initialize <code>ios_base</code> members.
+<p>Source: C++03 27.4.2.7p1, 27.4.4.1p2; C++11 27.5.3.7p1,
+27.5.5.2p2.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 #include &lt;ios&gt;
 
 using namespace std;
-template &lt;class T, class Traits = std::char_traits&lt;T&gt;&gt;
+template &lt;class T, class Traits = std::char_traits&lt;T&gt; &gt;
 class my_stream1 : public std::basic_ios&lt;T, Traits&gt; {
 };
 
-template &lt;class T, class Traits = std::char_traits&lt;T&gt;&gt;
+template &lt;class T, class Traits = std::char_traits&lt;T&gt; &gt;
 class my_stream2 : public std::basic_ios&lt;T, Traits&gt; {
-  class my_streambuf : public std::basic_streambuf&lt;T, Traits&gt; {
+  class my_streambuf
+  : public std::basic_streambuf&lt;T, Traits&gt; {
   };
 public:
   my_stream2() {
@@ -967,28 +1271,35 @@
 };
 
 void test() {
-  my_stream1&lt;char&gt; *p1 = new my_stream1&lt;char&gt;
-  my_stream2&lt;char&gt; *p2 = new my_stream2&lt;char&gt;
+  my_stream1&lt;char&gt; *p1 = new my_stream1&lt;char&gt;;
+  my_stream2&lt;char&gt; *p2 = new my_stream2&lt;char&gt;;
   delete p1; // warn
   delete p2; // ok
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">undefbehavior.IosBaseUsedBeforeInit
-<br>(C++11)</span><br><br>
-Undefined behavior: ios_base object is used before initialization have taken 
-place. basic_ios::init should be call to initialize ios_base members
-</td><td><pre>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+undefbehavior.IosBaseUsedBeforeInit</span><span class="lang">
+(C++11)</span><div class="descr">
+Undefined behavior: <code>ios_base</code> object is used before initialization
+have taken place. <code>basic_ios::init</code> should be call to
+initialize <code>ios_base</code> members.
+<p>Source: C++11 27.5.3.7p1, 27.5.5.2p2.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 #include &lt;ios&gt;
 
 using namespace std;
-template &lt;class T, class Traits = std::char_traits&lt;T&gt;&gt;
+template &lt;class T, class Traits = std::char_traits&lt;T&gt; &gt;
 class my_stream1 : public std::basic_ios&lt;T, Traits&gt; {
 };
 
-template &lt;class T, class Traits = std::char_traits&lt;T&gt;&gt;
+template &lt;class T, class Traits = std::char_traits&lt;T&gt; &gt;
 class my_stream2 : public std::basic_ios&lt;T, Traits&gt; {
-  class my_streambuf : public std::basic_streambuf&lt;T, Traits&gt; {
+  class my_streambuf
+  : public std::basic_streambuf&lt;T, Traits&gt; {
   };
 public:
   my_stream2() {
@@ -997,20 +1308,24 @@
 };
 
 void test() {
-  my_stream1&lt;char&gt; *p1 = new my_stream1&lt;char&gt;
-  my_stream2&lt;char&gt; *p2 = new my_stream2&lt;char&gt;
+  my_stream1&lt;char&gt; *p1 = new my_stream1&lt;char&gt;;
+  my_stream2&lt;char&gt; *p2 = new my_stream2&lt;char&gt;;
   p1->narrow('a', 'b'); // warn
   p2->narrow('a', 'b'); // ok
-  delete p1; // warn
-  delete p2; // ok
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">undefbehavior.MinusOnePosType
-<br>(C++)</span><br><br>
-Undefined behavior: passing -1 to any streambuf/istream/ostream member that 
-accepts a value of type traits::pos_type result in undefined behavior
-</td><td><pre>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+undefbehavior.MinusOnePosType</span><span class="lang">
+(C++)</span><div class="descr">
+Undefined behavior: passing -1 to any <code>streambuf</code>/<code>
+istream</code>/<code>ostream</code> member that accepts a value of
+type <code>traits::pos_type</code> result in undefined behavior.
+<p>Source: C++03 27.4.3.2p3; C++11 27.5.4.2p3.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 #include &lt;fstream&gt;
 
 class my_streambuf : public std::streambuf {
@@ -1018,16 +1333,19 @@
     seekpos(-1); // warn
   }
 };
+</pre></div>
+<div class="example"><pre>
+#include &lt;fstream&gt;
 
 void test() {
   std::filebuf fb;
   std::istream in(&amp;fb);
-  std::ostream out(&amp;fb);
   std::filebuf::off_type pos(-1);
   in.seekg(pos); // warn
-  out.seekp(-1); // warn
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
+
 </table>
 
 <!-- ============================ different ================================ -->
@@ -1037,472 +1355,505 @@
 <thead><tr><td>Name, Description</td><td>Example</td><td>Progress</td></tr>
 </thead>
 
-<tr><td><span class="name">different.ArgEvalOrderUndef
-<br>(C)</span><br><br>
-Errors because of the order of evaluation of function arguments is undefined
-</td><td><pre>
-void f(int, int);
-
-void test() {
-  int i = 0;
-  int v[1] = {0};
-  f(v[i], i++); // warn
-}
-</pre></td><td class="aligned"></td></tr>
-
-<tr><td><span class="name">different.IdenticalExprBinOp
-<br>(C)</span><br><br>
-There are identical sub-expressions to the left and to the right of the 
-operator
-</td><td><pre>
-#define A 1
-#define B 1
-
-bool isNan(double d) { 
-  return d != d; // ok
-}
-
-int f();
-
-void test() {
-  int i = 0;
-  if (i != 0 && i != 0) {} // warn
-
-  if(i == A || i == B) {} // ok
-
-  if (++i != 0 && ++i != 0) {} // ok
-
-  if (f() && f()) {} // ok
-}
-</pre></td><td class="aligned"></td></tr>
-
-<tr><td><span class="name">different.FuncPtrInsteadOfCall
-<br>(C)</span><br><br>
-Possibly a function call should be used instead of a pointer to function
-</td><td><pre>
-int f();
-
-void test() {
-  if (f == 0) {} // warn
-}
-</pre></td><td class="aligned"></td></tr>
-
-<tr><td><span class="name">different.IdenticalCondIfElseIf
-<br>(C)</span><br><br>
-The use of 'if (A) {...} else if (A) {...}' pattern was detected. There is a 
-probability of logical error presence
-</td><td><pre>
-void test() { 
-  int i = 7;
-  if (i == 1) {}
-  else if (i == 1) {} // warn
-}
-</pre></td><td class="aligned"></td></tr>
-
-<tr><td><span class="name">SuccessiveAssign
-<br>(C)</span><br><br>
-Successive assign to a variable
-</td><td><pre>
-void test() { 
-  int i=0;
+<tr><td><div class="namedescr expandable"><span class="name">
+different.SuccessiveAssign</span><span class="lang">
+(C)</span><div class="descr">
+Successive assign to a variable.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+int test() {
+  int i;
   i=1;
   i=2; // warn
+  return i;
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">different.NullDerefStmtOrder
-<br>enhancement to core.NullDereference<br>(C)</span><br><br>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+different.NullDerefStmtOrder</span><span class="lang">
+(C)</span><div class="descr">
 Dereferencing of the null pointer might take place. Checking the pointer for 
-null should be performed first
-</td><td><pre>
+null should be performed first.
+<br>Note: possibly an enhancement to <span class="name">
+core.NullDereference</span>.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 struct S {
   int x;
 };
 
-S* f();
+struct S* f();
 
 void test() {
-  S *p1 = f();
+  struct S *p1 = f();
   int x1 = p1-&gt;x; // warn
   if (p1) {};
 
-  S *p2 = f();
+  struct S *p2 = f();
   int x2 = p2-&gt;x; // ok
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">different.NullDerefCondOrder
-<br>enhancement to core.NullDereference<br>(C)</span><br><br>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+different.NullDerefCondOrder</span><span class="lang">
+(C)</span><div class="descr">
 Dereferencing of the null pointer might take place. Checking the pointer for 
-null should be performed first
-</td><td><pre>
-struct S{bool b;};
+null should be performed first.
+<br>Note: possibly an enhancement to <span class="name">
+core.NullDereference</span>.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+struct S {int i;};
 
-S* f();
+struct S* f();
 
 void test() {
-  S *p = f();
-  if (p-&gt;b && p) {}; // warn
+  struct S *p = f();
+  if (p-&gt;i && p) {}; // warn
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">different.IdenticalStmtThenElse
-<br>(C)</span><br><br>
-The 'else' statement is equivalent to the 'then' statement
-</td><td><pre>
-void test() {
-  int i;
-  if (i==1) {
-    i++;
-  }
-  else { // warn
-    i++;
-  }
-}
-</pre></td><td class="aligned"></td></tr>
 
-<tr><td><span class="name">different.MultipleAccessors
-<br>(C++)</span><br><br>
-multiple accessors met for 'class::field'
-</td><td><pre>
+<tr><td><div class="namedescr expandable"><span class="name">
+different.MultipleAccessors</span><span class="lang">
+(C++)</span><div class="descr">
+Identical accessor bodies. Possibly a misprint.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 class A {
   int i;
   int j;
 public:
   int getI() { return i; }
   int getJ() { return i; } // warn
+};
+</pre></div>
+<div class="example"><pre>
+class A {
+  int i;
+  int j;
+public:
   void setI(int& ii) { i = ii; }
   void setJ(int& jj) { i = jj; } // warn
 };
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">different.AccessorsForPublic
-<br>(C++)</span><br><br>
-Accessors exist for 'class::field'. Should this field really be public?
-</td><td><pre>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+different.AccessorsForPublic</span><span class="lang">
+(C++)</span><div class="descr">
+Accessors exist for a public class field. Should this field really be
+public?</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 class A {
 public:
   int i; // warn
   int getI() { return i; }
   void setI(int& ii) { i = ii; }
 };
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">different.LibFuncResultUnised
-<br>(C, C++)</span><br><br>
-Calling 'f' ignoring its return value is of no use (* create the list of known 
-system/library/API functions falling into this category)
-</td><td><pre>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+different.LibFuncResultUnised</span><span class="lang">
+(C, C++)</span><div class="descr">
+Calling a function ignoring its return value is of no use (create the list of
+known system/library/API functions falling into this category).</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 #include &lt;vector&gt;
 
 void test() {
   std::vector&lt;int&gt; v;
   v.empty(); // warn
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">different.WrongVarForStmt
-<br>(C, C++)</span><br><br>
-Possibly wrong variable is used in the loop/cond-expression of the 'for'
-statement. Did you mean 'proper_variable_name'?
-</td><td><pre>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+different.WrongVarForStmt</span><span class="lang">
+(C, C++)</span><div class="descr">
+Wrong variable is possibly used in the loop/cond-expression of
+the <code>for</code> statement. Did you mean
+'proper_variable_name'?</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 void test() {
-  int i;
-  int j;
-  for (j=0; j&lt;3; ++i); // warn
-  for (int j=0; i&lt;3; ++j); // warn
+  int i = 0;
+  int j = 0;
+  for (i = 0; i < 3; j += 1); // warn
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div>
+<div class="example"><pre>
+void test() {
+  int i = 0;
+  int j = 0;
+  for (int j = 0; i < 3; ++j); // warn
+}
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">different.FloatingCompare
-<br>(C)</span><br><br>
-Comparing floating point numbers may be not precise
-</td><td><pre>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+different.FloatingCompare</span><span class="lang">
+(C)</span><div class="descr">
+Comparing floating point numbers may be not precise.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 #include &lt;math.h&gt;
 
-void test() {
+double test() {
   double b = sin(M_PI / 6.0);
   if (b == 0.5) // warn
     b = 0;
+  return b;
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">different.BoolCompare
-<br>maybe merge with experimental.core.BoolAssignment<br>(C, C++)</span><br><br>
-Comparing boolean to a value other then 0 or 1
-</td><td><pre>
-void test() {
-  int i;
-  if (0 < i < 3) {}; // warn
-  bool b;
-  if (b == 3) {}; // warn
-}
-</pre></td><td class="aligned"></td></tr>
 
-<tr><td><span class="name">different.BitwiseOpBoolArg
-<br>maybe join with experimental.core.BoolAssignment<br>(C, C++)</span><br><br>
-bool value is used at the left/right part of the &amp; (|) operator. Did you mean 
-&amp;&amp; (||) ?
-</td><td><pre>
+<tr><td><div class="namedescr expandable"><span class="name">
+different.BitwiseOpBoolArg</span><span class="lang">
+(C, C++)</span><div class="descr">
+Boolean value met at the left/right part of the bitwise <code>&amp;</code>
+or <code>|</code> operator.
+Did you mean <code>&amp;&amp;</code> (<code>||</code>) ?</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 int f();
 
 void test() {
   bool b = true;
   if (b &amp; f()) {} // warn
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">different.LabelInsideSwitch
-<br>(C)</span><br><br>
-Possible misprint: label found inside the switch() statement. (* did you mean 
-'default'?)
-</td><td><pre>
-void test() {
-  int c = 7;
+
+<tr><td><div class="namedescr expandable"><span class="name">
+different.LabelInsideSwitch</span><span class="lang">
+(C)</span><div class="descr">
+Possibly a misprint: label found inside a <code>switch()</code>
+statement.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test(int c) {
   switch(c){
   case 1:
     c += 1; break;
-  defalt: // warn
+  defalt: // warn (did you mean 'default'?)
     c -= 1; break;
   }
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">different.IdenticalCondIfIf
-<br>(C)</span><br><br>
-The conditions of two subsequent 'if' statements are identical
-</td><td><pre>
-void test() {
-  int c = 7;
-  if (c &gt; 5) // &lt;-
+
+<tr><td><div class="namedescr expandable"><span class="name">
+different.IdenticalCondIfIf</span><span class="lang">
+(C)</span><div class="descr">
+The conditions of two subsequent <code>if</code> statements are
+identical.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+int test(int c) {
+  if (c &gt; 5)
     c += 1;
   if (c &gt; 5) // warn
     c -= 1;
+  return c;
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">different.CondOpIdenticalReturn
-<br>(C)</span><br><br>
-The return expressions of the '?:' operator are identical
-</td><td><pre>
-void test() {
-  unsigned a;
-  a = a > 5 ? a : a; // warn
-}
-</pre></td><td class="aligned"></td></tr>
 
-<tr><td><span class="name">different.LogicalOpUselessArg
-<br>(C)</span><br><br>
-The second operand of the &amp;&amp; operator has no impact on expression result
-</td><td><pre>
-void test() {
-  unsigned a;
+<tr><td><div class="namedescr expandable"><span class="name">
+different.LogicalOpUselessArg</span><span class="lang">
+(C)</span><div class="descr">
+The second operand of a <code>&amp;&amp;</code> operator has no impact on
+expression result.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test(unsigned a) {
   if (a&lt;7 &amp;&amp; a&lt;10) {}; // warn
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">different.SameResLogicalExpr
-<br>(C)</span><br><br>
-The expression always evaluates to true/false
-</td><td><pre>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+different.SameResLogicalExpr</span><span class="lang">
+(C)</span><div class="descr">
+An expression is always evaluated to true/false.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 void test() {
-  int i=0;
-  if (i!=0) {}; // warn
-  if (i==0 &amp;&amp; i==1) {}; // warn
-  if (i<0 || i>=0) {}; // warn
+  int i = 0;
+  if (i != 0) {}; // warn
 }
-</pre></td><td class="aligned"></td></tr>
-
-<tr><td><span class="name">different.SameResUnsignedCmp
-<br>(C)</span><br><br>
-Comparison of unsigned expression 'op expr' is always true/false
-</td><td><pre>
-void test() {
-  unsigned u;
-  if (u &lt; -1) {}; // warn
-  if (u &gt;= 0) {}; // warn
+</pre></div>
+<div class="example"><pre>
+void test(int i) {
+  if (i == 0 &amp;&amp; i == 1) {}; // warn
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div>
+<div class="example"><pre>
+void test(int i) {
+  if (i < 0 || i >= 0) {}; // warn
+}
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">different.OpPrecedenceAssignCmp
-<br>(C)</span><br><br>
-Comparison operation has higher precedence then assignment. Bool value is 
-assigned to variable of type 'type'. Parenthesis may bee required around an 
-assignment
-</td><td><pre>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+different.OpPrecedenceAssignCmp</span><span class="lang">
+(C, C++)</span><div class="descr">
+Comparison operation has higher precedence then assignment. Boolean value is
+assigned to a variable of other type. Parenthesis may bee required around an
+assignment.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 int f();
 
-void test() {
+void test(int x, int y) {
   bool b;
-  int x, y;
   if((b = x != y)) {} // ok
   if((x = f() != y)) {} // warn
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">different.OpPrecedenceIifShift
-<br>(C)</span><br><br>
-?: has lower precedence then &lt;&lt;
-</td><td><pre>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+different.OpPrecedenceIifShift</span><span class="lang">
+(C, C++)</span><div class="descr">
+<code>?:</code> has lower precedence then <code>&lt;&lt;</code>.
+<p>Source: Stephen C. Dewhurst "C++ Gotchas: Avoiding Common Problems in Coding
+and Design", advise 15.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 #include &lt;iostream&gt;
 
-void test() {
-  int a;
+void test(int a) {
   std::cout &lt;&lt; a ? "a" : "b"; // warn
-  a &lt;&lt; a&gt;7 ? 1 : 2; // warn
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div>
+<div class="example"><pre>
+void test(int a) {
+  a &lt;&lt; a &gt; 7 ? 1 : 2; // warn
+}
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">different.ObjectUnused
-<br>(C++)</span><br><br>
-The object was created but is not being used<br><br>
-The exception object was created but is not being used. Did you mean 
-'throw std::exception();'?
-</td><td><pre>
-#include &lt;exception&gt;
 
+<tr><td><div class="namedescr expandable"><span class="name">
+different.ObjectUnused</span><span class="lang">
+(C++)</span><div class="descr">
+The object was created but is not being used.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 struct S {
   int x, y;
-  S(int xx, int yy) : x(xx), y(yy) {
-  }
+  S(int xx, int yy) : x(xx), y(yy) {}
   S(int xx) {
     S(xx, 0); // warn
   }
 };
+</pre></div>
+<div class="example"><pre>
+#include &lt;exception&gt;
 
 void test() {
-  S(0, 0); // warn
-  std::exception(); // warn
+  std::exception();
+    // warn (did you mean 'throw std::exception()'?)
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">different.StaticArrayPtrCompare
-<br>(C)</span><br><br>
-Pointer to static array is being compared to NULL. May the subscripting is 
-missing
-</td><td><pre>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+different.StaticArrayPtrCompare</span><span class="lang">
+(C)</span><div class="descr">
+Pointer to static array is being compared to NULL. May the subscripting is
+missing.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 void test() {
-  int a1[1];
-  if (a1 == 0) {}; // warn
-
-  int a2[1][1];
-  if (a2[0]) {}; // warn
+  int a[1][1];
+  if (a[0] == 0) {}; // warn
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">different.ConversionToBool
-<br>maybe join with experimental.core.BoolAssignment<br>(C, C++)</span><br><br>
-Odd implicit conversion from 'type' to 'bool'
-</td><td><pre>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+different.ConversionToBool</span><span class="lang">
+(C, C++)</span><div class="descr">
+Odd implicit conversion to boolean.
+<br>Note: possibly merge with <span class="name">
+alpha.core.BoolAssignment</span>.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 bool test() {
   return 1.; // warn
+}
+</pre></div>
+<div class="example"><pre>
+bool test() {
   return ""; // warn
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">different.ArrayBound
-<br>enhancement to experimental.security.ArrayBound[v2]<br>(C, C++)</span><br><br>
-Out-of-bound dynamic array access
-</td><td><pre>
-#include &lt;stdlib.h&gt;
 
+<tr><td><div class="namedescr expandable"><span class="name">
+different.ArrayBound</span><span class="lang">
+(C++)</span><div class="descr">
+Out-of-bound dynamic array access.
+<br>Note: possibly an enhancement to <span class="name">
+alpha.security.ArrayBoundV2</span>.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 void test() {
-  int *p2 = new int[1];
-  if(p2[1]) {}; // warn
+  int *p = new int[1];
   int i = 1;
-  if(p2[i]) {}; // warn
+  if(p[i]) {}; // warn
+  delete[] p;
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">different.StrcpyInputSize
-<BR>enhancement to experimental.unix.cstring.OutOfBounds<br>(C)</span><br><br>
-Buffer copy without checking size of input
-</td><td><pre>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+different.StrcpyInputSize</span><span class="lang">
+(C)</span><div class="descr">
+Buffer copy without checking the size of input.
+<br>Note: possibly an enhancement to <span class="name">
+alpha.unix.cstring.OutOfBounds</span>.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 void test(char* string) {
   char buf[24];
   strcpy(buf, string); // warn
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">different.IntegerOverflow
-<br>(C)</span><br><br>
-Integer overflow
-</td><td><pre>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+different.IntegerOverflow</span><span class="lang">
+(C)</span><div class="descr">
+Integer overflow.
+<br>Note: partially handled by Clang core
+(search for 'overflow in expression' warning in Clang tests).
+<p>Source: <a href="http://cwe.mitre.org/data/definitions/190.html">
+CWE-190</a>.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 #include &lt;limits.h&gt;
 
-int f(int x) {
-  return INT_MAX+1; // warn
-}
+int f(int x);
 
 void test() {
-  int x = INT_MAX+1; // warn
-  f(INT_MAX+1); // warn
-
-  int y = INT_MAX/2+1; // warn
-  x = y*2; // warn
+  f(INT_MAX + 1); // warn
 }
-</pre></td><td class="aligned"></td></tr>
-
-<tr><td><span class="name">different.SignExtension
-<br>(C)</span><br><br>
-Unexpected sign extension might take place
-</td><td><pre>
-void f(unsigned int i);
-int g();
-
-unsigned int test() {
-  long long sll;
-  unsigned long long ull = sll; // warn
-  long sl;
-  unsigned long ul = sl; // warn
-  int si;
-  unsigned int ui = si; // warn
-  short ss;
-  unsigned short us = ss; // warn
-  signed char sc;
-  unsigned char uc = sc; // warn
-  f(si); // warn
-  ui = g(); // warn
-  return si; // warn
-}
-</pre></td><td class="aligned"></td></tr>
-
-<tr><td><span class="name">different.NumericTruncation
-<br>(C)</span><br><br>
-Numeric truncation might take place
-</td><td><pre>
-void f(int i);
-int g();
+</pre></div>
+<div class="example"><pre>
+#include &lt;limits.h&gt;
 
 int test() {
-  unsigned long long ull;
-  long long sll;
-  unsigned long ul = ull; // warn
-  long sl = sll; // warn
-  unsigned int ui = ul; // warn
-  int si = sl; // warn
-  unsigned short us = ui; // warn
-  short ss = si; // warn
-  unsigned char uc = us; // warn
-  signed char sc = uc; // warn
-  f(sll); // warn
-  ss = g(); // warn
-  return sll; // warn
+  int x = INT_MAX / 2 + 1;
+  return x * 2; // warn
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">different.MissingCopyCtorAssignOp
-<br>(C, C++)</span><br><br>
-The class has dynamically allocated data members but do not define a copy 
-constructor/assignment operator
-</td><td><pre>
-class C { // warn
-  int *p; // &lt;-
+
+<tr><td><div class="namedescr expandable"><span class="name">
+different.SignExtension</span><span class="lang">
+(C)</span><div class="descr">
+Unexpected sign extension might take place.
+<p>Source: <a href="http://cwe.mitre.org/data/definitions/194.html">
+CWE-194</a>.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+unsigned long long test(long long sll) {
+  unsigned long long ull = sll; // warn
+  return ull;
+}
+</pre></div>
+<div class="example"><pre>
+void f(unsigned int i);
+
+void test(int si) {
+  f(si); // warn
+}
+</pre></div>
+<div class="example"><pre>
+unsigned int test(int i) {
+  return i;
+}
+</pre></div></div></td>
+<td class="aligned"></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+different.NumericTruncation</span><span class="lang">
+(C)</span><div class="descr">
+Numeric truncation might take place.
+<p>Source: <a href="http://cwe.mitre.org/data/definitions/197.html">
+CWE-197</a>.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+unsigned long test(unsigned long long ull) {
+  unsigned long ul = ull; // warn
+  return ul;
+}
+</pre></div>
+<div class="example"><pre>
+void f(int i);
+
+void test(long long sll) {
+  f(sll); // warn
+}
+</pre></div>
+<div class="example"><pre>
+int f();
+
+short test(long long sll) {
+  short ss = f();
+  return ss;
+}
+</pre></div></div></td>
+<td class="aligned"></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+different.MissingCopyCtorAssignOp</span><span class="lang">
+(C++)</span><div class="descr">
+A class has dynamically allocated data members but do not define a copy
+constructor/assignment operator.
+<p>Source: Scott Meyers "Effective C++", item 11: Prevent exceptions from
+leaving destructors.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+class C {
+  int *p; // warn
 public:
   C() { p = new int; }
   ~C() { delete p; }
 };
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
 </table>
 
@@ -1512,57 +1863,73 @@
 <col class="namedescr"><col class="example"><col class="progress">
 <thead><tr><td>Name, Description</td><td>Example</td><td>Progress</td></tr></thead>
 
-<tr><td><span class="name">WinAPI.CreateProcess
-<br>(C)</span><br><br>
-After calling CreateProcess(), ensure that process and thread handles get closed
-(* for the given example: examine data flow from pi, pi.hProcess and pi.hThread)
-</td><td><pre>
+<tr><td><div class="namedescr expandable"><span class="name">
+WinAPI.CreateProcess</span><span class="lang">
+(C)</span><div class="descr">
+<code>CreateProcess()</code>: if the first parameter <code><i>
+lpApplicationName</i></code> is NULL then the executable name must be in the
+white space-delimited string pointed to by <code><i>lpCommandLine</code></i>.
+If the executable or path name has a space in it, there is a risk that a
+different executable could be run because of the way the function parses
+spaces.
+<p>Source: <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425%28v=vs.85%29.aspx">
+MSDN: CreateProcess function, Security Remarks</a>.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 #include &lt;windows.h&gt;
 
 void test() {
   STARTUPINFO si;
   PROCESS_INFORMATION pi;
-  BOOL fSuccess;
-  fSuccess = CreateProcess(
-    NULL, TEXT("MyProgram.exe"), NULL, NULL, 
-    TRUE, 0, NULL, NULL, &amp;si, &amp;pi);
-} // warn
-</pre></td><td class="aligned"></td></tr>
+  CreateProcess(NULL, TEXT("C:\\Program Files\\App -L -S"),
+                NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
+    // warn
+}
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">WinAPI.LoadLibrary
-<br>(C)</span><br><br>
-Calling LoadLibrary without a fully qualified path may allow to load a DLL from 
-arbitrary location
-</td><td><pre>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+WinAPI.LoadLibrary</span><span class="lang">
+(C)</span><div class="descr">
+The <code>SearchPath()</code> function is used to retrieve a path to a DLL for
+a subsequent <code>LoadLibrary()</code> call.
+<p>Source: <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms684175%28v=vs.85%29.aspx">
+MSDN: LoadLibrary function, Security Remarks</a>.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+#include &lt;windows.h&gt;
+
+HINSTANCE test() {
+  char filePath[100];
+  SearchPath(NULL, "file.dll", NULL, 100, filePath, NULL);
+  return LoadLibrary(filePath); // warn
+}
+</pre></div></div></td>
+<td class="aligned"></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+WinAPI.WideCharToMultiByte</span><span class="lang">
+(C)</span><div class="descr">
+Buffer overrun while calling <code>WideCharToMultiByte()</code>. The size of
+the input buffer equals the number of characters in the Unicode string, while
+the size of the output buffer equals the number of bytes.
+<p>Source: <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd374130%28v=vs.85%29.aspx">
+MSDN: WideCharToMultiByte function</a>.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 #include &lt;windows.h&gt;
 
 void test() {
-  HINSTANCE h = LoadLibrary("X.dll"); // warn
-}
-</pre></td><td class="aligned"></td></tr>
-
-<tr><td><span class="name">WinAPI.WideCharToMultiByte
-<br>(C)</span><br><br>
-Buffer overrun while calling WideCharToMultiByte
-</td><td><pre>
-#include &lt;windows.h&gt;
-
-void test() 
-{
   wchar_t ws[] = L"abc";
   char s[3];
-  int res1 = WideCharToMultiByte(
-               CP_UTF8, 0, ws, -1, s, 
-               3, NULL, NULL); // warn
-  int res2 = WideCharToMultiByte(
-               CP_UTF8, 0, ws, -1, s, 
-               3, NULL, NULL); // ok
-  if (res2 == sizeof(s))
-    s[res2-1] = 0;
-  else
-   s[res2] = 0;
+  WideCharToMultiByte(CP_UTF8, 0, ws, -1, s,
+                      3, NULL, NULL); // warn
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
+
 
 </table>
 
@@ -1572,25 +1939,30 @@
 <col class="namedescr"><col class="example"><col class="progress">
 <thead><tr><td>Name, Description</td><td>Example</td><td>Progress</td></tr></thead>
 
-<tr><td><span class="name">optimization.PassConstObjByValue
-<br>(C, C++)</span><br><br>
-Optimization: It is more effective to pass const n-th parameter by reference to 
-avoid unnecessary object copying
-</td><td><pre>
-struct A {
-  int a[20];
-  int b;
-};
+<tr><td><div class="namedescr expandable"><span class="name">
+optimization.PassConstObjByValue</span><span class="lang">
+(C, C++)</span><div class="descr">
+Optimization: It is more effective to pass constant parameter by reference to
+avoid unnecessary object copying.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+struct A {};
 
-bool FirstIsZero(const struct A a) { // warn
-  return a.a[0] == 0;
-}
-</pre></td><td class="aligned"></td></tr>
+void f(const struct A a); // warn
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">optimization.PostfixIncIter
-<br>(C++)</span><br><br>
-Optimization: It is more effective to use prefix ++ with iterator here
-</td><td><pre>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+optimization.PostfixIncIter</span><span class="lang">
+(C++)</span><div class="descr">
+Optimization: It is more effective to use prefix increment operator with
+iterator.
+<p>Source: Scott Meyers "More Effective C++", item 6:
+Distinguish between prefix and postfix forms of increment and decrement
+operators.</p></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 #include &lt;vector&gt;
 
 void test() {
@@ -1599,41 +1971,35 @@
   for(it = v.begin(); 
       it != v.end(); it++) {}; // warn
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">optimization.MultipleCallsStrlen
-<br>(C)</span><br><br>
-Optimization: multiple calls to strlen for a given string in the given 
-expression. It is more effective to hold strlen result in a temporary 
-variable
-</td><td><pre>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+optimization.MultipleCallsStrlen</span><span class="lang">
+(C)</span><div class="descr">
+Optimization: multiple calls to <code>strlen()</code> for a string in an
+expression. It is more effective to hold a value returned
+from <code>strlen()</code> in a temporary variable.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 #include &lt;string.h&gt;
 
-void test() {
-  const char* s = "abc";
+void test(const char* s) {
   if (strlen(s) &gt; 0 &amp;&amp;
       strlen(s) &lt; 7) {}; // warn
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">optimization.EmptyCstrDetect
-<br>(C)</span><br><br>
-Optimization: it is more efficient to use "str[0] != '\0'" to identify an empty 
-string
-</td><td><pre>
-#include &lt;string.h&gt;
 
-void test() {
-  const char* s = "abc";
-  if (strlen(s) &gt; 0) {}; // warn
-}
-</pre></td><td class="aligned"></td></tr>
-
-<tr><td><span class="name">optimization.StrLengthCalculation
-<br>(C, C++)</span><br><br>
-Optimization: it is more efficient to use string::length() method to calculate 
-string length
-</td><td><pre>
+<tr><td><div class="namedescr expandable"><span class="name">
+optimization.StrLengthCalculation</span><span class="lang">
+(C++)</span><div class="descr">
+Optimization: it is more efficient to use <code>string::length()</code> to
+calculate the length of an <code>std::string</code>.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 #include &lt;string&gt;
 #include &lt;string.h&gt;
 
@@ -1641,20 +2007,26 @@
   std::string s;
   if (strlen(s.c_str()) != 0) {}; // warn
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
 
-<tr><td><span class="name">optimization.EmptyContainerDetect
-<br>(C, C++)</span><br><br>
-Optimization: It is more efficient to use container.empty() to identify an 
-empty container
-</td><td><pre>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+optimization.EmptyContainerDetect</span><span class="lang">
+(C++)</span><div class="descr">
+Optimization: It is more efficient to use containers <code>empty()</code>
+method to identify an empty container.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
 #include &lt;list&gt;
 
 void test() {
   std::list&lt;int&gt; l;
   if (l.size() != 0) {}; // warn
 }
-</pre></td><td class="aligned"></td></tr>
+</pre></div></div></td>
+<td class="aligned"></td></tr>
+
 
 </table>
 
diff --git a/www/analyzer/release_notes.html b/www/analyzer/release_notes.html
index bc052bb..81f9c9a 100644
--- a/www/analyzer/release_notes.html
+++ b/www/analyzer/release_notes.html
@@ -15,6 +15,18 @@
 
 <h1>Release notes for <tt>checker-XXX</tt> builds</h1>
 
+<h4 id="checker_276">checker-276</h4>
+<p><b>built:</b> February 19, 2014</br>
+	<b>download:</b> <a href="downloads/checker-276.tar.bz2">checker-276.tar.bz2</a></p>
+	<p><b>highlights:</b></p>
+	<ul>
+    <li>Includes about 9 months of change to Clang itself (improved C++11/14 support, etc.)</li>
+    <li>More precise modeling of Objective-C properties, which enables the analyzer to find more bugs.</li>
+    <li>Includes a new "missing call to <tt>super</tt>" warning, which looks for common pattern in iOS/OSX APIs that require chaining a call to a super class's implementation of a method.</li>
+    <li>Accepts <tt>-arch arm64</tt> (which may be passed by Xcode 5.0), but for the time being analyzes code in such cases as <tt>-arch armv7s</tt>.</li>
+    <li>Many sundry fixes, improvements to C++ support, etc.</li>
+	</ul>
+  
 <h4 id="checker_275">checker-275</h4>
 <p><b>built:</b> May 23, 2013</br>
 	<b>download:</b> <a href="downloads/checker-275.tar.bz2">checker-275.tar.bz2</a></p>
diff --git a/www/analyzer/scan-build.html b/www/analyzer/scan-build.html
index 9c4070b..abd2bc0 100644
--- a/www/analyzer/scan-build.html
+++ b/www/analyzer/scan-build.html
@@ -6,7 +6,6 @@
   <link type="text/css" rel="stylesheet" href="content.css">
   <link type="text/css" rel="stylesheet" href="menu.css">
   <script type="text/javascript" src="scripts/menu.js"></script>
-  <script type="text/javascript" src="scripts/dbtree.js"></script>
 </head>
 <body>
 
@@ -53,7 +52,7 @@
 
 <h2>Contents</h2>
 
-<ul id="collapsetree" class="dbtree onclick multiple">
+<ul>
 <li><a href="#scanbuild">Getting Started</a>
  <ul>
   <li><a href="#scanbuild_basicusage">Basic Usage</a></li>
diff --git a/www/analyzer/scripts/dbtree.js b/www/analyzer/scripts/dbtree.js
deleted file mode 100644
index 5face5d..0000000
--- a/www/analyzer/scripts/dbtree.js
+++ /dev/null
@@ -1 +0,0 @@
-eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('7 5,r,Q,u;7 17=[];5=H;1i();9(!1Z.1j.20){1Z.1j.20=k(a){C[C.D]=a}}7 19=\'35+/\';k 36(a){7 b,R=\'\',i=0;I(;i<a.D;i+=4){b=(19.1k(a.1l(i))&1a)<<18|(19.1k(a.1l(i+1))&1a)<<12|(19.1k(a.1l(i+2))&1a)<<6|19.1k(a.1l(i+3))&1a;R+=37.38((b&39)>>16,(b&3a)>>8,b&1a)}9(a.21(i-2)==22)1m=R.23(0,R.D-2);s 9(a.21(i-1)==22)1m=R.23(0,R.D-1);s 1m=R;z 3b(1m)}7 A={24:k(){7 a=l.E(\'X\');I(7 i=0;i<a.D;i++){9(a[i].h.F(/\\1n\\b/)==-1)3c;7 b=a[i];9(b.h.F(/\\1E\\b/)!=-1){7 c=b.E(\'a\');I(7 j=0;j<c.D;j++){m.B(c[j],\'25\',1F,o);m.B(c[j],\'26\',1G,o);m.B(c[j],\'1o\',1b,o);c[j].Y=\'1H:1I(0)\'}}7 d=b.E(\'X\');I(7 j=0;j<d.D;j++){7 e=d[j].p;e.27=J;9(b.h.F(/\\3d\\b/)!=-1){m.B(e,\'w\',A.w,o);9(b.h.F(/\\3e\\b/)==-1){e.E(\'a\')[0].Y=\'1H:1I(0)\'}}s{7 t=b.h.3f(/1J(.*)1J/);t=t?t[1]:H;m.B(e,\'3g\',A.28(e,t),o);m.B(e,\'3h\',A.29(e),o)}e.E(\'a\')[0].h+=\' 2a\'}9(b.h.F(/\\3i\\b/)!=-1)A.2b(b.v)}},2b:k(a){7 b=l.G(a+\'3j\');9(b){A.1p(b);b=b.p;1c(!!b&&(b.v!=a)){9((!b.h)||(b.h==\'\')){b.h=\'w\'}s{b.h+=\' w\'}9(b.1d.K.L()==\'a\')b.1d.h+=\' w\';b=b.p}}},29:k(a){z k(){A.1p(a)}},28:k(a,b){z k(){A.2c(a,b)}},1p:k(a){7 b=a;3k(b.2d);I(7 i=0;i<b.S.D;i++){7 c=b.S[i];9(c.K.L()==\'X\'){b.E(\'a\')[0].h+=\' w\';b.h+=\' w\';c.h+=\' w\'}}},2c:k(a,b){7 c=a;c.2d=3l(k(){A.1q(c)},b)},1q:k(a){I(7 i=0;i<a.S.D;i++){7 b=a.S[i];9(b.K.L()==\'X\'){a.E(\'a\')[0].h=a.E(\'a\')[0].h.1K(/w/g,\'\');b.h=b.h.1K(/w/g,\'\');a.h=a.h.1K(/w/g,\'\')}}},w:k(e){9(M.T){M.T.1L=J}9(e&&e.1r){e.1r()}7 a=(M.T)?M.T.2e:(e)?e.1M:H;9(!a||!(a=A.1N(a,\'2f\')))z;9(a.E(\'a\')[0].h.F(/\\2g\\b/)==-1){7 b=1e(a);9(2h(b)){9(l.G(b).h.F(/\\3m\\b/)==-1){I(n=0;n<a.p.S.D;n++){N=a.p.S[n];9(N.K.L()==\'2f\'){9(N.h.F(/\\2g\\b/)!=-1)A.1q(a.p.S[n])}}}}A.1p(a)}s{A.1q(a)}9(2h(1e(a))){z J}s{z o}},1N:k(a,b){9(a.K.L()!=b&&a.K.L()!=\'U\'){z A.1N(a.p,b)}s 9(a.K.L()==\'U\'){z H}s{z a}}};k 1i(){3n{u=M.2i?O 2i():O 3o(\'3p.3q\')}3r(e){2j(\'2k 2l: 3s 3t 3u 3v 3w-3x!\')}}k 1O(a,x){a.1f.3y=x+\'2m\'}k 1P(a,y){a.1f.3z=y+\'2m\'}k 1e(a){1c(a.h.F(/\\1n\\b/)==-1){a=a.p}9((a.h.F(/\\1n\\b/)!=-1)&&(a.h.F(/\\1E\\b/)!=-1)){I(i=0;i<17.D;i++){9(a.v==17[i].q)z i}}z a.v}k 1G(a){a=O m(a);r=a.P.p.p.v;7 b=r.1s(\'Z\');r=b[1];5=17[1e(a.P)];7 c=l.G(5.q+\'10\').3A(J);7 d=l.G(5.q+\'10\');d.p.2n(d);c.v=5.q+\'10\';l.U.2o(c);1O(c,a.x);1P(c,a.y);c.1f.1Q=\'2p\';a.1t();m.B(l,\'1u\',1R,o);z o}k 1R(c){c=O m(c);7 e;7 a=c.P;7 b=a;1c((b!=H)&&(b.K.L()!=\'U\')){9(b.v==5.q+\'10\')1g;b=b.p}9((b!=H)&&(b.v==5.q+\'10\')){3B(a.p.h){1S\'3C\':a.Y=5.V+\'11=1T&N=\'+5.13;1g;1S\'1T\':a.Y=5.V+\'11=1T&N=\'+r;1g;1S\'2q\':a.Y=5.V+\'11=2q&N=\'+r;1g;3D:e=5.2r+\'?q=\'+5.q;e+=\'&13=\'+5.13;9(a.p.h==\'3E\'){e+=\'&11=2s&N=\'+r+\'&2t=\'+5.13}s{e+=\'&11=\'+a.p.h+\'&N=\'+r}7 d=O 2u();7 f=d.2v();e+=\'&2w=\'+f;e+=\'&1v=\'+5.1v;e+=\'&1w=\'+5.1w;e+=\'&1x=\'+5.1x;e+=\'&1y=\'+5.1y;e+=\'&1z=\'+5.1z;e+=\'&1A=\'+5.1A;e+=\'&v=\'+5.v;e+=\'&1B=\'+5.1B;e+=\'&1C=\'+5.1C;e+=\'&V=\'+5.V;u.2x=1U;u.1V(\'2y\',e,J);u.14(\'2z\',\'2A-2B\');u.14(\'2C-2D\',\'2E-2F\');u.14(\'2G-2H-2I\',l.2J);u.2K(H)}}7 g=l.G(5.q+\'10\');9(g){g.1f.1Q=\'3F\'};m.1h(l,\'1u\',1R,o)}k 1F(a){a=O m(a);r=a.P.p.p.v;7 b=r.1s(\'Z\');r=b[1];5=17[1e(a.P)];9(!l.G(5.q+\'15\')){7 c=(!l.G(5.q+\'15\'))?l.3G(\'3H\'):l.G(5.q+\'15\');c.v=5.q+\'15\';c.2L=a.P.1d.3I;l.U.2o(c)}m.B(l,\'2M\',1W,o);m.B(l,\'1u\',1X,o);m.B(l,\'1o\',1b,o);a.1t();z o}k 1b(a){9(!a&&M.T)a=M.T;9(a!=H){9(3J(a.1Y)==\'k\')a.1Y();s a.2N=o}z o}k 1W(a){a=O m(a);7 b=l.G(5.q+\'15\');1O(b,a.x);1P(b,a.y);b.1f.1Q=\'2p\';a.1t();z o}k 1X(a){a=O m(a);7 b=a.P.p;9(b.K.L()==\'a\'){r=5.q+\'Z\'+r;9(r!=b.p.v){7 c=J;7 d=b.p;1c(!!d&&(d.v!=5.q)){9(d.v==r){c=o;1g}s{d=d.p}}9(c==J){7 e=r.1s(\'Z\');r=e[1];Q=b.p.v;7 f=Q.1s(\'Z\');Q=f[1];2O(a)}}}7 g=l.G(5.q+\'15\');9(g){g.p.2n(g)};m.1h(l,\'2M\',1W,o);m.1h(l,\'1u\',1X,o);m.1h(l,\'1o\',1b,o)}k 2O(a){7 d=O 2u();7 b=d.2v();7 c;c=5.2r+\'?q=\'+5.q+\'&11=2s&13=\'+5.13+\'&N=\'+r+\'&2t=\'+Q+\'&2w=\'+b;c+=\'&1v=\'+5.1v;c+=\'&1w=\'+5.1w;c+=\'&1x=\'+5.1x;c+=\'&1y=\'+5.1y;c+=\'&1z=\'+5.1z;c+=\'&1A=\'+5.1A;c+=\'&v=\'+5.v;c+=\'&1B=\'+5.1B;c+=\'&1C=\'+5.1C;c+=\'&V=\'+5.V;u.2x=1U;u.1V(\'2y\',c,J);u.14(\'2z\',\'2A-2B\');u.14(\'2C-2D\',\'2E-2F\');u.14(\'2G-2H-2I\',l.2J);u.2K(H)}k 2P(){7 a=(!!Q)?Q:r;a=5.q+\'Z\'+a;a=l.G(a);9(a){a=a.E(\'X\')[0];1c(!!a&&(a.h.F(/\\1n\\b/)==-1)&&(a.h.F(/\\1E\\b/)==-1)){9((!a.h)||(a.h==\'\')){a.h=\'w\'}s{a.h+=\' w\'}9(a.1d.K.L()==\'a\')a.1d.h+=\' w\';a=a.p}}}k 3K(a,b){9(a!=\'3L\'){3M(a+".3N=\'"+b.2Q[b.2R].2S+"\'")}s{M.1V(b.2Q[b.2R].2S)}}k 2T(a){7 b=l.G(a);7 c=b.E(\'X\');I(7 j=0;j<c.D;j++){7 d=c[j].p;d.27=J;m.B(d,\'w\',A.w,o);d.E(\'a\')[0].h+=\' 2a\'}7 e=b.E(\'a\');I(7 j=0;j<e.D;j++){m.B(e[j],\'25\',1F,o);m.B(e[j],\'26\',1G,o);m.B(e[j],\'1o\',1b,o);e[j].Y=\'1H:1I(0)\'}}k 1U(){9(u.3O==4){9(u.3P==3Q){l.G(5.q+\'3R\').2L=u.3S;2T(5.q);2P();1i()}s{2j(\'2k 2l: 3T, 3U 3V 1J 3W a 3X 3Y 3Z 40:\\n\'+u.41);1i()}}}k m(a){C.W=a?a:M.T;C.P=a.1M?a.1M:a.2e;C.x=a.2U?(a.2U):(a.42+2V.2W(l.U.2X,l.2Y.2X));C.y=a.2Z?(a.2Z):(a.43+2V.2W(l.U.30,l.2Y.30))}m.1j.44=k(){z\'m [ x = \'+C.x+\', y = \'+C.y+\' ]\'};m.1j.1t=k(){9(C.W.1r){C.W.1r();C.W.1Y()}s 9(C.W.1L){C.W.1L=J;C.W.2N=o}};m.B=k(a,b,c,d){9(l.31){a.31(b,c,d)}s 9(l.32){a.32(\'1D\'+b,c,d)}s{a[\'1D\'+b]=c}};m.1h=k(a,b,c,d){9(l.33){a.33(b,c,d)}s 9(l.34){a.34(\'1D\'+b,c,d)}s{a[\'1D\'+b]=H}};m.B(M,\'45\',A.24,o);',62,254,'|||||instance||var||if||||||||className|||function|document|Evt||false|parentNode|instanceName|nid|else||client|id|click|||return|dbTree|addEvent|this|length|getElementsByTagName|search|getElementById|null|for|true|nodeName|toLowerCase|window|node|new|source|nto|decOut|childNodes|event|body|editpage|evt|ul|href|_|_options|action||rootnode|setRequestHeader|_tip||dbtreeObj||b64s|0xff|PreventDefault|while|firstChild|getObj|style|break|removeEvent|createClient|prototype|indexOf|charAt|undecOut|bdbtree|selectstart|mOver|mOut|stopPropagation|split|consume|mouseup|type|query|datasource|username|password|table|parent|contentfield|on|bedit|dragPress|contextMenu|javascript|void|to|replace|cancelBubble|target|getTarget|setX|setY|display|contextAction|case|add|callback|open|dragMove|dragRelease|preventDefault|Array|push|charCodeAt|61|substring|init|mousedown|contextmenu|hasSubMenu|getMoutFor|getMoverFor|subMenu|mExp|mTimeout|timeout|srcElement|li|bclick|isNaN|XMLHttpRequest|alert|DBTree|Error|px|removeChild|appendChild|block|edit|tagpath|move|nodeto|Date|getTime|time|onreadystatechange|get|Pragma|no|cache|Cache|Control|must|revalidate|If|Modified|Since|lastModified|send|innerHTML|mousemove|returnValue|dragBoxDropped|expandtree|options|selectedIndex|value|reinit|pageX|Math|max|scrollLeft|documentElement|pageY|scrollTop|addEventListener|attachEvent|removeEventListener|detachEvent|ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789|decode|String|fromCharCode|0xff0000|0xff00|unescape|continue|bonclick|blinkparent|match|mouseout|mouseover|bexpand|_active|clearTimeout|setTimeout|bmultiple|try|ActiveXObject|Microsoft|XMLHTTP|catch|Your|browser|is|not|Ajax|enabled|left|top|cloneNode|switch|addroot|default|moveroot|none|createElement|div|nodeValue|typeof|jumpTo|blank|eval|location|readyState|status|200|_edit|responseText|Sorry|there|seems|be|problem|retrieving|the|response|statusText|clientX|clientY|toString|load'.split('|'),0,{}))
diff --git a/www/analyzer/scripts/expandcollapse.js b/www/analyzer/scripts/expandcollapse.js
new file mode 100644
index 0000000..593a983
--- /dev/null
+++ b/www/analyzer/scripts/expandcollapse.js
@@ -0,0 +1,191 @@
+// expand/collapse button (expander) is added if height of a cell content 
+// exceeds CLIP_HEIGHT px.
+var CLIP_HEIGHT = 135;
+
+// Height in pixels of an expander image.
+var EXPANDER_HEIGHT = 13;
+
+// Path to images for an expander.
+var imgPath = "./images/expandcollapse/";
+
+// array[group][cell] of { 'height', 'expanded' }.
+// group: a number; cells of the same group belong to the same table row.
+// cell: a number; unique index of a cell in a group.
+// height: a number, px; original height of a cell in a table.
+// expanded: boolean; is a cell expanded or collapsed?
+var CellsInfo = [];
+
+// Extracts group and cell indices from an id of the form identifier_group_cell.
+function getCellIdx(id) {
+  var idx = id.substr(id.indexOf("_") + 1).split("_");
+  return { 'group': idx[0], 'cell': idx[1] };
+}
+
+// Returns { 'height', 'expanded' } info for a cell with a given id.
+function getCellInfo(id) { 
+  var idx = getCellIdx(id); 
+  return CellsInfo[idx.group][idx.cell]; 
+}
+
+// Initialization, add nodes, collect info.
+function initExpandCollapse() {
+  if (!document.getElementById)
+    return;
+
+  var groupCount = 0;
+
+  // Examine all table rows in the document.
+  var rows = document.body.getElementsByTagName("tr");
+  for (var i=0; i<rows.length; i+=1) {
+
+    var cellCount=0, newGroupCreated = false;
+
+    // Examine all divs in a table row.
+    var divs = rows[i].getElementsByTagName("div");
+    for (var j=0; j<divs.length; j+=1) {
+
+      var expandableDiv = divs[j];
+
+      if (expandableDiv.className.indexOf("expandable") == -1)
+        continue;
+
+      if (expandableDiv.offsetHeight <= CLIP_HEIGHT)
+        continue;
+
+      // We found a div wrapping a cell content whose height exceeds 
+      // CLIP_HEIGHT.
+      var originalHeight = expandableDiv.offsetHeight;
+      // Unique postfix for ids for generated nodes for a given cell.
+      var idxStr = "_" + groupCount + "_" + cellCount;
+      // Create an expander and an additional wrapper for a cell content.
+      //
+      //                                --- expandableDiv ----
+      //  --- expandableDiv ---         | ------ data ------ |
+      //  |    cell content   |   ->    | |  cell content  | | 
+      //  ---------------------         | ------------------ |
+      //                                | ---- expander ---- |
+      //                                ----------------------
+      var data = document.createElement("div");
+      data.className = "data";
+      data.id = "data" + idxStr;
+      data.innerHTML = expandableDiv.innerHTML;
+      with (data.style) { height = (CLIP_HEIGHT - EXPANDER_HEIGHT) + "px";
+                          overflow = "hidden" }
+
+      var expander = document.createElement("img");
+      with (expander.style) { display = "block"; paddingTop = "5px"; }
+      expander.src = imgPath + "ellipses_light.gif";
+      expander.id = "expander" + idxStr;
+
+      // Add mouse calbacks to expander.
+      expander.onclick = function() {
+        expandCollapse(this.id);
+        // Hack for Opera - onmouseout callback is not invoked when page 
+        // content changes dinamically and mouse pointer goes out of an element.
+        this.src = imgPath + 
+                   (getCellInfo(this.id).expanded ? "arrows_light.gif"
+                                                  : "ellipses_light.gif");
+      }
+      expander.onmouseover = function() { 
+        this.src = imgPath + 
+                   (getCellInfo(this.id).expanded ? "arrows_dark.gif"
+                                                  : "ellipses_dark.gif");
+      }
+      expander.onmouseout = function() { 
+        this.src = imgPath + 
+                   (getCellInfo(this.id).expanded ? "arrows_light.gif"
+                                                  : "ellipses_light.gif");
+      }
+
+      expandableDiv.innerHTML = "";
+      expandableDiv.appendChild(data);
+      expandableDiv.appendChild(expander);
+      expandableDiv.style.height = CLIP_HEIGHT + "px";
+      expandableDiv.id = "cell"+ idxStr;
+
+      // Keep original cell height and its ecpanded/cpllapsed state.
+      if (!newGroupCreated) {
+        CellsInfo[groupCount] = [];
+        newGroupCreated = true;
+      }
+      CellsInfo[groupCount][cellCount] = { 'height' : originalHeight,
+                                           'expanded' : false };
+      cellCount += 1;
+    }
+    groupCount += newGroupCreated ? 1 : 0;
+  }
+}
+
+function isElemTopVisible(elem) {
+  var body = document.body,
+      html = document.documentElement,
+      // Calculate expandableDiv absolute Y coordinate from the top of body.
+      bodyRect = body.getBoundingClientRect(),
+      elemRect = elem.getBoundingClientRect(),
+      elemOffset = Math.floor(elemRect.top - bodyRect.top),
+      // Calculate the absoute Y coordinate of visible area.
+      scrollTop = html.scrollTop || body && body.scrollTop || 0;
+  scrollTop -= html.clientTop; // IE<8
+
+  
+  if (elemOffset < scrollTop)
+    return false;
+
+  return true;
+}
+
+// Invoked when an expander is pressed; expand/collapse a cell.
+function expandCollapse(id) {
+  var cellInfo = getCellInfo(id);
+  var idx = getCellIdx(id);
+
+  // New height of a row.
+  var newHeight;
+  // Smart page scrolling may be done after collapse.
+  var mayNeedScroll;
+
+  if (cellInfo.expanded) {
+    // Cell is expanded - collapse the row height to CLIP_HEIGHT.
+    newHeight = CLIP_HEIGHT;
+    mayNeedScroll = true;
+  }
+  else {
+    // Cell is collapsed - expand the row height to the cells original height.
+    newHeight = cellInfo.height;
+    mayNeedScroll = false;
+  }
+
+  // Update all cells (height and expanded/collapsed state) in a row according 
+  // to the new height of the row.
+  for (var i = 0; i < CellsInfo[idx.group].length; i++) {
+    var idxStr = "_" + idx.group + "_" + i;
+    var expandableDiv = document.getElementById("cell" + idxStr);
+    expandableDiv.style.height = newHeight + "px";
+    var data = document.getElementById("data" + idxStr);
+    var expander = document.getElementById("expander" + idxStr);
+    var state = CellsInfo[idx.group][i];
+
+    if (state.height > newHeight) {
+      // Cell height exceeds row height - collapse a cell.
+      data.style.height = (newHeight - EXPANDER_HEIGHT) + "px";
+      expander.src = imgPath + "ellipses_light.gif";
+      CellsInfo[idx.group][i].expanded = false;
+    } else {
+      // Cell height is less then or equal to row height - expand a cell.
+      data.style.height = "";
+      expander.src = imgPath + "arrows_light.gif";
+      CellsInfo[idx.group][i].expanded = true;
+    }
+  }
+
+  if (mayNeedScroll) {
+    var idxStr = "_" + idx.group + "_" + idx.cell;
+    var clickedExpandableDiv = document.getElementById("cell" + idxStr);
+    // Scroll page up if a row is collapsed and the rows top is above the 
+    // viewport. The amount of scroll is the difference between a new and old 
+    // row height.
+    if (!isElemTopVisible(clickedExpandableDiv)) {
+      window.scrollBy(0, newHeight - cellInfo.height);
+    }
+  }
+}
diff --git a/www/analyzer/xcode.html b/www/analyzer/xcode.html
index 4bae1c1..e01f32b 100644
--- a/www/analyzer/xcode.html
+++ b/www/analyzer/xcode.html
@@ -6,7 +6,6 @@
   <link type="text/css" rel="stylesheet" href="content.css">
   <link type="text/css" rel="stylesheet" href="menu.css">
   <script type="text/javascript" src="scripts/menu.js"></script>
-  <script type="text/javascript" src="scripts/dbtree.js"></script>  
 </head>
 <body>
 
diff --git a/www/comparison.html b/www/comparison.html
index afc321e..4bca65d 100644
--- a/www/comparison.html
+++ b/www/comparison.html
@@ -31,7 +31,7 @@
        analysis, you may not care that something lacks codegen support, for
        example.</p>
        
-    <p>Please email cfe-dev if you think we should add another compiler to this
+    <p>Please email <a href="get_involved.html">cfe-dev</a> if you think we should add another compiler to this
        list or if you think some characterization is unfair here.</p>
     
     <ul>
@@ -49,10 +49,16 @@
     
     <ul>
     <li>GCC supports languages that clang does not aim to, such as Java, Ada,
-        FORTRAN, etc.</li>
+        FORTRAN, Go, etc.</li>
     <li>GCC supports more targets than LLVM.</li>
+    <li>GCC supports many language extensions, some of which are not implemented
+    by Clang. For instance, in C mode, GCC supports
+    <a href="http://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html">nested
+    functions</a> and has an
+    <a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37428">undocumented
+    extension allowing VLAs in structs</a>.
     </ul>
-    
+
     <p>Pro's of clang vs GCC:</p>
     
     <ul>
@@ -76,12 +82,6 @@
         custom garbage collector, uses global variables extensively, is not
         reentrant or multi-threadable, etc.  Clang has none of these problems.
         </li>
-    <li>For every token, clang tracks information about where it was written and
-        where it was ultimately expanded into if it was involved in a macro.
-        GCC does not track information about macro instantiations when parsing
-        source code.  This makes it very difficult for source rewriting tools
-        (e.g. for refactoring) to work in the presence of (even simple) 
-        macros.</li>
     <li>Clang does not implicitly simplify code as it parses it like GCC does.
         Doing so causes many problems for source analysis tools: as one simple
         example, if you write "x-x" in your source code, the GCC AST will
@@ -108,9 +108,13 @@
         including support for a bytecode representation for intermediate code,
         pluggable optimizers, link-time optimization support, Just-In-Time
         compilation, ability to link in multiple code generators, etc.</li>
-    <li><a href="compatibility.html#c++">Clang's support for C++</a> is more
-        compliant than GCC's in many ways (e.g. conformant two phase name
-        lookup).</li>
+    <li><a href="compatibility.html#cxx">Clang's support for C++</a> is more
+        compliant than GCC's in many ways.</li>
+    <li>Clang supports
+        <a href="http://clang.llvm.org/docs/LanguageExtensions.html">many language
+        extensions</a>, some of which are not implemented by GCC. For instance,
+        Clang provides attributes for checking thread safety and extended vector
+        types.</li>
     </ul>
 
     <!--=====================================================================-->
diff --git a/www/cxx_dr_status.html b/www/cxx_dr_status.html
index 94510d4..6d27d00 100644
--- a/www/cxx_dr_status.html
+++ b/www/cxx_dr_status.html
@@ -1,5 +1,6 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
           "http://www.w3.org/TR/html4/strict.dtd">
+<!-- This file is auto-generated by make_cxx_dr_status. Do not modify. -->
 <html>
 <head>
   <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -14,7 +15,7 @@
     .na { background-color: #DDDDDD }
     .open * { color: #AAAAAA }
     //.open { filter: opacity(0.2) }
-    span:target { background-color: #FFFFBB; outline: #DDDD55 solid thin; }
+    tr:target { background-color: #FFFFBB }
     th { background-color: #FFDDAA }
   </style>
 </head>
@@ -40,3231 +41,3231 @@
     <th>Issue title</th>
     <th>Available in Clang?</th>
   </tr>
-  <tr>
+  <tr id="1">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1">1</a></td>
     <td>TC1</td>
     <td>What if two using-declarations refer to the same function but the declarations introduce different default-arguments?</td>
     <td class="none" align="center">No</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="2">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2">2</a></td>
     <td>drafting</td>
     <td>How can dependent names be used in member declarations that appear outside of the class template definition?</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="3">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#3">3</a></td>
     <td>NAD</td>
     <td>The template compilation model rules render some explicit specialization declarations not visible during instantiation</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="4">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#4">4</a></td>
     <td>CD1</td>
     <td>Does extern "C" affect the linkage of function names with internal linkage?</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="5">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#5">5</a></td>
     <td>CD1</td>
     <td>CV-qualifiers and type conversions</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="6">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#6">6</a></td>
     <td>open</td>
     <td>Should the optimization that allows a class object to alias another object also allow the case of a parameter in an inline function to alias its argument?</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="7">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#7">7</a></td>
     <td>NAD</td>
     <td>Can a class with a private virtual base class be derived from?</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="8">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#8">8</a></td>
     <td>CD1</td>
     <td>Access to template arguments used in a function return type and in the nested name specifier</td>
-    <td class="full" align="center">Duplicate of 45</td>
+    <td class="full" align="center">Duplicate of <a href="#45">45</a></td>
   </tr>
-  <tr>
+  <tr id="9">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#9">9</a></td>
     <td>CD1</td>
     <td>Clarification of access to base class members</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="10">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#10">10</a></td>
     <td>CD1</td>
     <td>Can a nested class access its own class name as a qualified name if it is a private member of the enclosing class?</td>
-    <td class="full" align="center">Duplicate of 45</td>
+    <td class="full" align="center">Duplicate of <a href="#45">45</a></td>
   </tr>
-  <tr>
+  <tr id="11">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#11">11</a></td>
     <td>CD1</td>
     <td>How do the keywords typename/template interact with using-declarations?</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="12">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#12">12</a></td>
     <td>dup</td>
     <td>Default arguments on different declarations for the same function and the Koenig lookup</td>
-    <td class="full" align="center">Superseded by 239</td>
+    <td class="full" align="center">Superseded by <a href="#239">239</a></td>
   </tr>
-  <tr class="open">
+  <tr id="13">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#13">13</a></td>
-    <td>extension</td>
+    <td>NAD</td>
     <td>extern "C" for Parameters of Function Templates</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">No</td>
   </tr>
-  <tr>
+  <tr id="14">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#14">14</a></td>
     <td>NAD</td>
     <td>extern "C" functions and declarations in different namespaces</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="15">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#15">15</a></td>
     <td>dup</td>
     <td>Default arguments for parameters of function templates</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="16">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#16">16</a></td>
     <td>CD1</td>
     <td>Access to members of indirect private base classes</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="17">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#17">17</a></td>
     <td>NAD</td>
     <td>Footnote 99 should discuss the naming class when describing members that can be accessed from friends</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="18">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#18">18</a></td>
     <td>NAD</td>
     <td>f(TYPE) where TYPE is void should be allowed</td>
-    <td class="full" align="center">Yes</td>
+    <td class="none" align="center">Superseded by <a href="#577">577</a></td>
   </tr>
-  <tr>
+  <tr id="19">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#19">19</a></td>
     <td>NAD</td>
     <td>Clarify protected member access</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="20">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#20">20</a></td>
     <td>TC1</td>
     <td>Some clarifications needed for 12.8 para 15</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="21">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#21">21</a></td>
     <td>TC1</td>
     <td>Can a default argument for a template parameter appear in a friend declaration?</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="22">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#22">22</a></td>
     <td>TC1</td>
     <td>Template parameter with a default argument that refers to itself</td>
-    <td class="none" align="center">Superseded by 481</td>
+    <td class="full" align="center">Superseded by <a href="#481">481</a></td>
   </tr>
-  <tr>
+  <tr id="23">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#23">23</a></td>
     <td>NAD</td>
     <td>Some questions regarding partial ordering of function templates</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="24">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#24">24</a></td>
     <td>TC1</td>
     <td>Errors in examples in 14.7.3</td>
     <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="25">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#25">25</a></td>
     <td>TC1</td>
     <td>Exception specifications and pointers to members</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="26">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#26">26</a></td>
     <td>NAD</td>
     <td>Copy constructors and default arguments</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="27">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#27">27</a></td>
     <td>NAD</td>
     <td>Overload ambiguities for builtin ?: prototypes</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="28">
     <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>
   </tr>
-  <tr>
+  <tr id="29">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#29">29</a></td>
     <td>CD1</td>
     <td>Linkage of locally declared functions</td>
-    <td class="svn" align="center">SVN</td>
+    <td class="full" align="center">Clang 3.4</td>
   </tr>
-  <tr>
+  <tr id="30">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#30">30</a></td>
     <td>TC1</td>
     <td>Valid uses of "<TT>::template</TT>"</td>
-    <td class="none" align="center">Superseded by 468 (C++11 onwards)</td>
+    <td class="full" align="center">Superseded by <a href="#468">468</a> (C++11 onwards)</td>
   </tr>
-  <tr>
+  <tr id="31">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#31">31</a></td>
     <td>NAD</td>
     <td>Looking up new/delete</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="32">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#32">32</a></td>
     <td>TC1</td>
     <td>Clarification of explicit instantiation of non-exported templates</td>
     <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="33">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#33">33</a></td>
     <td>TC1</td>
     <td>Argument dependent lookup and overloaded functions</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="34">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#34">34</a></td>
     <td>NAD</td>
     <td>Argument dependent lookup and points of instantiation</td>
     <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="35">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#35">35</a></td>
     <td>TC1</td>
     <td>Definition of default-initialization</td>
-    <td class="full" align="center">Duplicate of 178</td>
+    <td class="full" align="center">Duplicate of <a href="#178">178</a></td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="36">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#36">36</a></td>
     <td>open</td>
     <td><I>using-declaration</I>s in multiple-declaration contexts</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="37">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#37">37</a></td>
     <td>NAD</td>
     <td>When is uncaught_exception() true?</td>
-    <td class="none" align="center">Superseded by 475</td>
+    <td class="none" align="center">Superseded by <a href="#475">475</a></td>
   </tr>
-  <tr>
+  <tr id="38">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#38">38</a></td>
     <td>TC1</td>
     <td>Explicit template arguments and operator functions</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="39">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#39">39</a></td>
     <td>CD1</td>
     <td>Conflicting ambiguity rules</td>
     <td class="none" align="center">No</td>
   </tr>
-  <tr>
+  <tr id="40">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#40">40</a></td>
     <td>TC1</td>
     <td>Syntax of <I>declarator-id</I></td>
     <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="41">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#41">41</a></td>
     <td>TC1</td>
     <td>Clarification of lookup of names after declarator-id</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="42">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#42">42</a></td>
     <td>NAD</td>
     <td>Redefining names from base classes</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="43">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#43">43</a></td>
     <td>TC1</td>
     <td>Copying base classes (PODs) using memcpy</td>
     <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="44">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#44">44</a></td>
     <td>CD1</td>
     <td>Member specializations</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="45">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#45">45</a></td>
     <td>CD1</td>
     <td>Access to nested classes</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="46">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#46">46</a></td>
     <td>NAD</td>
     <td>Explicit instantiation of member templates</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="47">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#47">47</a></td>
     <td>NAD</td>
     <td>Template friend issues</td>
-    <td class="none" align="center">No</td>
+    <td class="svn" align="center">Superseded by <a href="#329">329</a></td>
   </tr>
-  <tr>
+  <tr id="48">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#48">48</a></td>
     <td>TC1</td>
     <td>Definitions of unused static members</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="49">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#49">49</a></td>
     <td>TC1</td>
     <td>Restriction on non-type, non-value template arguments</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="50">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#50">50</a></td>
     <td>NAD</td>
     <td>Converting pointer to incomplete type to same type</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="51">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#51">51</a></td>
     <td>TC1</td>
     <td>Overloading and user-defined conversions</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="52">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#52">52</a></td>
     <td>TC1</td>
     <td>Non-static members, member selection and access checking</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="53">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#53">53</a></td>
     <td>TC1</td>
     <td>Lvalue-to-rvalue conversion before certain static_casts</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="54">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#54">54</a></td>
     <td>CD1</td>
     <td>Static_cast from private base to derived class</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="55">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#55">55</a></td>
     <td>NAD</td>
     <td>Adding/subtracting pointer and enumeration value</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="56">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#56">56</a></td>
     <td>TC1</td>
     <td>Redeclaring typedefs within classes</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="57">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#57">57</a></td>
     <td>open</td>
     <td>Empty unions</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="58">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#58">58</a></td>
     <td>CD1</td>
     <td>Signedness of bit fields of enum type</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="59">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#59">59</a></td>
     <td>TC1</td>
     <td>Clarification of overloading and UDC to reference type</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="60">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#60">60</a></td>
     <td>CD1</td>
     <td>Reference binding and valid conversion sequences</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="61">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#61">61</a></td>
     <td>NAD</td>
     <td>Address of static member function "<TT>&amp;p-&gt;f</TT>"</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="62">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#62">62</a></td>
     <td>CD1</td>
     <td>Unnamed members of classes used as type parameters</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="63">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#63">63</a></td>
     <td>CD1</td>
     <td>Class instantiation from pointer conversion to void*, null and self</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="64">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#64">64</a></td>
     <td>TC1</td>
     <td>Partial ordering to disambiguate explicit specialization</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="65">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#65">65</a></td>
     <td>TC1</td>
     <td>Typo in default argument example</td>
     <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="66">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#66">66</a></td>
     <td>NAD</td>
     <td>Visibility of default args vs overloads added after using-declaration</td>
     <td class="none" align="center">No</td>
   </tr>
-  <tr>
+  <tr id="67">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#67">67</a></td>
     <td>TC1</td>
     <td>Evaluation of left side of object-expression</td>
     <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="68">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#68">68</a></td>
     <td>TC1</td>
     <td>Grammar does not allow "friend class A&lt;int&gt;;"</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="69">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#69">69</a></td>
     <td>TC1</td>
     <td>Storage class specifiers on template declarations</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="70">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#70">70</a></td>
     <td>CD1</td>
     <td>Is an array bound a nondeduced context?</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="71">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#71">71</a></td>
     <td>NAD</td>
     <td>Incorrect cross reference</td>
     <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="72">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#72">72</a></td>
     <td>dup</td>
     <td>Linkage and storage class specifiers for templates</td>
-    <td class="full" align="center">Duplicate of 69</td>
+    <td class="full" align="center">Duplicate of <a href="#69">69</a></td>
   </tr>
-  <tr>
+  <tr id="73">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#73">73</a></td>
     <td>TC1</td>
     <td>Pointer equality</td>
     <td class="none" align="center">No</td>
   </tr>
-  <tr>
+  <tr id="74">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#74">74</a></td>
     <td>TC1</td>
     <td>Enumeration value in direct-new-declarator</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="75">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#75">75</a></td>
     <td>TC1</td>
     <td>In-class initialized members must be const</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="76">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#76">76</a></td>
     <td>TC1</td>
     <td>Are const volatile variables considered "constant expressions"?</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="77">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#77">77</a></td>
     <td>CD1</td>
     <td>The definition of friend does not allow nested classes to be friends</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="78">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#78">78</a></td>
     <td>CD1</td>
     <td>Section 8.5 paragraph 9 should state it only applies to non-static objects</td>
-    <td class="none" align="center">Superseded by ????</td>
+    <td class="none" align="center">Superseded by <a href="#????">????</a></td>
   </tr>
-  <tr>
+  <tr id="79">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#79">79</a></td>
     <td>dup</td>
     <td>Alignment and placement new</td>
     <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="80">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#80">80</a></td>
     <td>TC1</td>
     <td>Class members with same name as class</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="81">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#81">81</a></td>
     <td>NAD</td>
-    <td>Null pointers and C compatability</td>
+    <td>Null pointers and C compatibility</td>
     <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="82">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#82">82</a></td>
     <td>dup</td>
     <td>Definition of "using" a constant expression</td>
-    <td class="full" align="center">Duplicate of 48</td>
+    <td class="full" align="center">Duplicate of <a href="#48">48</a></td>
   </tr>
-  <tr>
+  <tr id="83">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#83">83</a></td>
     <td>TC1</td>
     <td>Overloading and deprecated conversion of string literal</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="84">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#84">84</a></td>
     <td>TC1</td>
     <td>Overloading and conversion loophole used by <TT>auto_ptr</TT></td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="85">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#85">85</a></td>
     <td>TC1</td>
     <td>Redeclaration of member class</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="86">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#86">86</a></td>
     <td>CD1</td>
     <td>Lifetime of temporaries in query expressions</td>
-    <td class="none" align="center">Duplicate of 446</td>
+    <td class="full" align="center">Duplicate of <a href="#446">446</a></td>
   </tr>
-  <tr>
+  <tr id="87">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#87">87</a></td>
     <td>CD1</td>
     <td>Exception specifications on function parameters</td>
     <td class="none" align="center">No</td>
   </tr>
-  <tr>
+  <tr id="88">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#88">88</a></td>
     <td>NAD</td>
     <td>Specialization of member constant templates</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="89">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#89">89</a></td>
     <td>TC1</td>
     <td>Object lifetime does not account for reference rebinding</td>
     <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="90">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#90">90</a></td>
     <td>TC1</td>
     <td>Should the enclosing class be an "associated class" too?</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="91">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#91">91</a></td>
     <td>NAD</td>
     <td>A union's associated types should include the union itself</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr class="open">
+  <tr id="92">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#92">92</a></td>
-    <td>extension</td>
+    <td>NAD</td>
     <td>Should <I>exception-specification</I>s be part of the type system?</td>
-    <td align="center">Not resolved</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="93">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#93">93</a></td>
     <td>TC1</td>
     <td>Missing word in 3.8 <U>basic.life</U> paragraph 2</td>
     <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="94">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#94">94</a></td>
     <td>TC1</td>
     <td>Inconsistencies in the descriptions of constant expressions</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="95">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#95">95</a></td>
     <td>NAD</td>
     <td>Elaborated type specifiers referencing names declared in friend decls</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="96">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#96">96</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Syntactic disambiguation using the <TT>template</TT> keyword</td>
     <td class="none" align="center">No</td>
   </tr>
-  <tr>
+  <tr id="97">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#97">97</a></td>
     <td>NAD</td>
     <td>Use of bool constants in integral constant expressions</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="98">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#98">98</a></td>
     <td>TC1</td>
     <td>Branching into try block</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="99">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#99">99</a></td>
     <td>NAD</td>
     <td>Partial ordering, references and cv-qualifiers</td>
-    <td class="full" align="center">Superseded by 214</td>
+    <td class="full" align="center">Superseded by <a href="#214">214</a></td>
   </tr>
-  <tr>
+  <tr id="100">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#100">100</a></td>
     <td>TC1</td>
     <td>Clarify why string literals are not allowed as template arguments</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="101">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#101">101</a></td>
     <td>TC1</td>
     <td>Redeclaration of extern "C" names via using-declarations</td>
-    <td class="full" align="center">Yes</td>
+    <td class="svn" align="center">SVN</td>
   </tr>
-  <tr>
+  <tr id="102">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#102">102</a></td>
     <td>NAD</td>
     <td>Operator lookup rules do not work well with parts of the library</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="103">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#103">103</a></td>
     <td>TC1</td>
     <td>Is it <I>extended-namespace-definition</I> or <I>extension-namespace-definition</I> ?</td>
     <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="104">
     <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>
   </tr>
-  <tr>
+  <tr id="105">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#105">105</a></td>
     <td>TC1</td>
     <td>Meaning of "template function"</td>
     <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="106">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#106">106</a></td>
     <td>CD1</td>
     <td>Creating references to references during template deduction/instantiation</td>
-    <td class="none" align="center">Superseded by 540</td>
+    <td class="none" align="center">Superseded by <a href="#540">540</a></td>
   </tr>
-  <tr>
+  <tr id="107">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#107">107</a></td>
     <td>NAD</td>
     <td>Linkage of operator functions</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="108">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#108">108</a></td>
     <td>TC1</td>
     <td>Are classes nested in templates dependent?</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="109">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#109">109</a></td>
     <td>NAD</td>
     <td>Allowing <TT>::template</TT> in <I>using-declaration</I>s</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="110">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#110">110</a></td>
     <td>open</td>
     <td>Can template functions and classes be declared in the same scope?</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="111">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#111">111</a></td>
     <td>NAD</td>
     <td>Copy constructors and cv-qualifiers</td>
-    <td class="none" align="center">Duplicate of 535</td>
+    <td class="none" align="center">Duplicate of <a href="#535">535</a></td>
   </tr>
-  <tr>
+  <tr id="112">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#112">112</a></td>
     <td>CD1</td>
     <td>Array types and cv-qualifiers</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="113">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#113">113</a></td>
     <td>CD1</td>
     <td>Visibility of called function</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="114">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#114">114</a></td>
     <td>NAD</td>
     <td>Virtual overriding by template member function specializations</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="115">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#115">115</a></td>
     <td>CD1</td>
     <td>Address of template-id</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="116">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#116">116</a></td>
     <td>TC1</td>
     <td>Equivalent and functionally-equivalent function templates</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="117">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#117">117</a></td>
     <td>NAD</td>
     <td>Timing of destruction of temporaries</td>
     <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="118">
     <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>
   </tr>
-  <tr>
+  <tr id="119">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#119">119</a></td>
     <td>CD1</td>
     <td>Object lifetime and aggregate initialization</td>
     <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="120">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#120">120</a></td>
     <td>TC1</td>
     <td>Nonexistent non-terminal <I>qualified-name</I></td>
     <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="121">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#121">121</a></td>
     <td>TC1</td>
     <td>Dependent type names with non-dependent <I>nested-name-specifier</I>s</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="122">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#122">122</a></td>
     <td>CD1</td>
     <td><I>template-id</I>s as <I>unqualified-id</I>s</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="123">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#123">123</a></td>
     <td>TC1</td>
     <td>Bad cross-reference</td>
     <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="124">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#124">124</a></td>
     <td>CD1</td>
     <td>Lifetime of temporaries in default initialization of class arrays</td>
-    <td class="none" align="center">Duplicate of 201</td>
+    <td class="none" align="center">Duplicate of <a href="#201">201</a></td>
   </tr>
-  <tr>
+  <tr id="125">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#125">125</a></td>
     <td>CD1</td>
     <td>Ambiguity in <TT>friend</TT> declaration syntax</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="126">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#126">126</a></td>
     <td>TC1</td>
     <td>Exception specifications and <TT>const</TT></td>
     <td class="none" align="center">No</td>
   </tr>
-  <tr>
+  <tr id="127">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#127">127</a></td>
     <td>TC1</td>
     <td>Ambiguity in description of matching deallocation function</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="128">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#128">128</a></td>
     <td>TC1</td>
     <td>Casting between enum types</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="129">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#129">129</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Stability of uninitialized auto variables</td>
-    <td class="none" align="center">Duplicate of 616</td>
+    <td class="none" align="center">Duplicate of <a href="#616">616</a></td>
   </tr>
-  <tr>
+  <tr id="130">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#130">130</a></td>
     <td>NAD</td>
     <td>Sequence points and <I>new-expression</I>s</td>
     <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="131">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#131">131</a></td>
     <td>TC1</td>
     <td>Typo in Lao characters</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="132">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#132">132</a></td>
     <td>NAD</td>
     <td>Local types and linkage</td>
     <td class="none" align="center">No</td>
   </tr>
-  <tr>
+  <tr id="133">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#133">133</a></td>
     <td>dup</td>
     <td>Exception specifications and checking</td>
-    <td class="none" align="center">Duplicate of 87</td>
+    <td class="none" align="center">Duplicate of <a href="#87">87</a></td>
   </tr>
-  <tr>
+  <tr id="134">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#134">134</a></td>
     <td>TC1</td>
     <td>Template classes and <I>declarator-id</I>s</td>
     <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="135">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#135">135</a></td>
     <td>TC1</td>
     <td>Class type in in-class member function definitions</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="136">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#136">136</a></td>
     <td>CD1</td>
     <td>Default arguments and friend declarations</td>
-    <td class="svn" align="center">SVN</td>
+    <td class="full" align="center">Clang 3.4</td>
   </tr>
-  <tr>
+  <tr id="137">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#137">137</a></td>
     <td>TC1</td>
     <td><TT>static_cast</TT> of <I>cv</I> <TT>void*</TT></td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="138">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#138">138</a></td>
     <td>drafting</td>
     <td>Friend declaration name lookup</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="139">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#139">139</a></td>
     <td>CD1</td>
     <td>Error in <TT>friend</TT> lookup example</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="140">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#140">140</a></td>
     <td>CD1</td>
     <td>Agreement of parameter declarations</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="141">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#141">141</a></td>
     <td>CD1</td>
     <td>Non-member function templates in member access expressions</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="142">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#142">142</a></td>
     <td>TC1</td>
     <td>Injection-related errors in access example</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="143">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#143">143</a></td>
     <td>CD1</td>
     <td>Friends and Koenig lookup</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="144">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#144">144</a></td>
     <td>open</td>
     <td>Position of <TT>friend</TT> specifier</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="145">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#145">145</a></td>
     <td>TC1</td>
     <td>Deprecation of prefix <TT>++</TT></td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="146">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#146">146</a></td>
     <td>open</td>
     <td>Floating-point zero</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="147">
     <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>
   </tr>
-  <tr>
+  <tr id="148">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#148">148</a></td>
     <td>TC1</td>
     <td>POD classes and pointers to members</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="149">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#149">149</a></td>
     <td>TC1</td>
     <td>Accessibility and ambiguity</td>
     <td class="na" align="center">N/A</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="150">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#150">150</a></td>
     <td>open</td>
     <td>Template template parameters and default arguments</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="151">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#151">151</a></td>
     <td>TC1</td>
     <td>Terminology of zero-initialization</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="152">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#152">152</a></td>
     <td>TC1</td>
     <td><TT>explicit</TT> copy constructors</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="153">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#153">153</a></td>
     <td>TC1</td>
     <td>Misleading wording (rank of conversion)</td>
     <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="154">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#154">154</a></td>
     <td>NAD</td>
     <td>Anonymous unions in unnamed namespaces</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="155">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#155">155</a></td>
     <td>dup</td>
     <td>Brace initializer for scalar</td>
-    <td class="none" align="center">Duplicate of 632</td>
+    <td class="none" align="center">Duplicate of <a href="#632">632</a></td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="156">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#156">156</a></td>
     <td>drafting</td>
     <td>Name lookup for conversion functions</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="157">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#157">157</a></td>
     <td>open</td>
     <td>Omitted typedef declarator</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="158">
     <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>
   </tr>
-  <tr>
+  <tr id="159">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#159">159</a></td>
     <td>TC1</td>
     <td>Namespace qualification in declarators</td>
-    <td class="none" align="center">No</td>
+    <td class="svn" align="center">SVN</td>
   </tr>
-  <tr>
+  <tr id="160">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#160">160</a></td>
     <td>CD1</td>
     <td>Missing <TT>std::</TT> qualification</td>
     <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="161">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#161">161</a></td>
     <td>TC1</td>
     <td>Access to protected nested type</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="162">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#162">162</a></td>
     <td>CD1</td>
     <td>(<TT>&amp;C::f)()</TT> with nonstatic members</td>
     <td class="none" align="center">No</td>
   </tr>
-  <tr>
+  <tr id="163">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#163">163</a></td>
     <td>TC1</td>
     <td>Description of subaggregate initializer</td>
     <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="164">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#164">164</a></td>
     <td>TC1</td>
     <td>Overlap between Koenig and normal lookup</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="165">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#165">165</a></td>
     <td>NAD</td>
     <td>Definitions of friends and block-scope externs</td>
     <td class="none" align="center">No</td>
   </tr>
-  <tr>
+  <tr id="166">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#166">166</a></td>
     <td>TC1</td>
     <td>Friend declarations of <I>template-id</I>s</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="167">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#167">167</a></td>
     <td>NAD</td>
     <td>Deprecating static functions</td>
-    <td class="none" align="center">Superseded by 1012</td>
+    <td class="none" align="center">Superseded by <a href="#1012">1012</a></td>
   </tr>
-  <tr>
+  <tr id="168">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#168">168</a></td>
     <td>NAD</td>
     <td>C linkage for static member functions</td>
     <td class="none" align="center">No</td>
   </tr>
-  <tr>
+  <tr id="169">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#169">169</a></td>
     <td>NAD</td>
     <td><I>template-id</I>s in <I>using-declaration</I>s</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="170">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#170">170</a></td>
     <td>drafting</td>
     <td>Pointer-to-member conversions</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="171">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#171">171</a></td>
     <td>TC1</td>
     <td>Global namespace scope</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="172">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#172">172</a></td>
     <td>CD1</td>
     <td>Unsigned int as underlying type of enum</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="173">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#173">173</a></td>
     <td>TC1</td>
     <td>Constraints on execution character set</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="174">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#174">174</a></td>
     <td>NAD</td>
     <td>Undeprecating global static</td>
-    <td class="none" align="center">Superseded by 1012</td>
+    <td class="none" align="center">Superseded by <a href="#1012">1012</a></td>
   </tr>
-  <tr>
+  <tr id="175">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#175">175</a></td>
     <td>CD1</td>
     <td>Class name injection and base name access</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="176">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#176">176</a></td>
     <td>TC1</td>
     <td>Name injection and templates</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="177">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#177">177</a></td>
     <td>CD1</td>
     <td>Lvalues vs rvalues in copy-initialization</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="178">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#178">178</a></td>
     <td>TC1</td>
     <td>More on value-initialization</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="179">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#179">179</a></td>
     <td>TC1</td>
     <td>Function pointers and subtraction</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="180">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#180">180</a></td>
     <td>CD1</td>
     <td><TT>typename</TT> and elaborated types</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="181">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#181">181</a></td>
     <td>TC1</td>
     <td>Errors in template <I>template-parameter</I> example</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="182">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#182">182</a></td>
     <td>NAD</td>
     <td>Access checking on explicit specializations</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="183">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#183">183</a></td>
     <td>TC1</td>
     <td><TT>typename</TT> in explicit specializations</td>
-    <td class="none" align="center">Superseded by 382</td>
+    <td class="full" align="center">Superseded by <a href="#382">382</a></td>
   </tr>
-  <tr>
+  <tr id="184">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#184">184</a></td>
     <td>CD1</td>
     <td>Default arguments in template <I>template-parameter</I>s</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="185">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#185">185</a></td>
     <td>TC1</td>
     <td>"Named" temporaries and copy elision</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="186">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#186">186</a></td>
     <td>open</td>
     <td>Name hiding and template <I>template-parameter</I>s</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="187">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#187">187</a></td>
     <td>TC1</td>
     <td>Scope of template parameter names</td>
-    <td class="none" align="center">Superseded by 481</td>
+    <td class="full" align="center">Superseded by <a href="#481">481</a></td>
   </tr>
-  <tr>
+  <tr id="188">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#188">188</a></td>
     <td>TC1</td>
     <td>Comma operator and rvalue conversion</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="189">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#189">189</a></td>
     <td>drafting</td>
     <td>Definition of <I>operator</I> and <I>punctuator</I></td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="190">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#190">190</a></td>
     <td>TC1</td>
     <td>Layout-compatible POD-struct types</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="191">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#191">191</a></td>
     <td>open</td>
     <td>Name lookup does not handle complex nesting</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="192">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#192">192</a></td>
     <td>drafting</td>
     <td>Name lookup in parameters</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="193">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#193">193</a></td>
     <td>TC1</td>
     <td>Order of destruction of local automatics of destructor</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="194">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#194">194</a></td>
     <td>TC1</td>
     <td>Identifying constructors</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="195">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#195">195</a></td>
     <td>CD1</td>
     <td>Converting between function and object pointers</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="196">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#196">196</a></td>
     <td>open</td>
     <td>Arguments to deallocation functions</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="197">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#197">197</a></td>
     <td>CD1</td>
     <td>Issues with two-stage lookup of dependent names</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="198">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#198">198</a></td>
     <td>CD1</td>
     <td>Definition of "use" in local and nested classes</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="199">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#199">199</a></td>
     <td>CD1</td>
     <td>Order of destruction of temporaries</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="200">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#200">200</a></td>
     <td>dup</td>
     <td>Partial ordering and explicit arguments</td>
-    <td class="full" align="center">Duplicate of 214</td>
+    <td class="full" align="center">Duplicate of <a href="#214">214</a></td>
   </tr>
-  <tr>
+  <tr id="201">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#201">201</a></td>
     <td>CD1</td>
     <td>Order of destruction of temporaries in initializers</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="202">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#202">202</a></td>
     <td>TC1</td>
     <td>Use of overloaded function name</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="203">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#203">203</a></td>
     <td>extension</td>
     <td>Type of address-of-member expression</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="204">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#204">204</a></td>
     <td>CD1</td>
     <td>Exported class templates</td>
     <td class="none" align="center">No</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="205">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#205">205</a></td>
     <td>drafting</td>
     <td>Templates and static data members</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="206">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#206">206</a></td>
     <td>TC1</td>
     <td>Semantic constraints on non-dependent names</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="207">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#207">207</a></td>
     <td>CD1</td>
     <td><I>using-declaration</I>s and protected access</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="208">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#208">208</a></td>
     <td>CD1</td>
     <td>Rethrowing exceptions in nested handlers</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="209">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#209">209</a></td>
     <td>NAD</td>
     <td>Must friend declaration names be

 accessible?</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="210">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#210">210</a></td>
     <td>TC1</td>
     <td>What is the type matched by an exception handler?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="211">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#211">211</a></td>
     <td>NAD</td>
     <td>Constructors should not be allowed to return normally after an exception</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="212">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#212">212</a></td>
     <td>drafting</td>
     <td>Implicit instantiation is not described clearly enough</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="213">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#213">213</a></td>
     <td>TC1</td>
     <td>Lookup in dependent base classes</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="214">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#214">214</a></td>
     <td>CD1</td>
     <td>Partial ordering of function templates is underspecified</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="215">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#215">215</a></td>
     <td>CD1</td>
     <td>Template parameters are not allowed in <I>nested-name-specifier</I>s</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="216">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#216">216</a></td>
     <td>CD1</td>
     <td>Linkage of nameless class-scope enumeration types</td>
     <td class="none" align="center">No</td>
   </tr>
-  <tr>
+  <tr id="217">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#217">217</a></td>
     <td>TC1</td>
     <td>Default arguments for non-template member functions of class templates</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="218">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#218">218</a></td>
     <td>CD1</td>
     <td>Specification of Koenig lookup</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="219">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#219">219</a></td>
     <td>NAD</td>
     <td>Cannot defend against destructors that throw exceptions</td>
     <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="220">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#220">220</a></td>
     <td>CD1</td>
     <td>All deallocation functions should be required not to throw</td>
     <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="221">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#221">221</a></td>
     <td>CD1</td>
     <td>Must compound assignment operators be member functions?</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="222">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#222">222</a></td>
     <td>CD1</td>
     <td>Sequence points and lvalue-returning operators</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">Duplicate of <a href="#637">637</a></td>
   </tr>
-  <tr>
+  <tr id="223">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#223">223</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>The meaning of deprecation</td>
     <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="224">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#224">224</a></td>
     <td>CD1</td>
     <td>Definition of dependent names</td>
     <td class="none" align="center">No</td>
   </tr>
-  <tr>
+  <tr id="225">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#225">225</a></td>
     <td>NAD</td>
     <td>Koenig lookup and fundamental types</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="226">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#226">226</a></td>
     <td>CD1</td>
     <td>Default template arguments for function templates</td>
     <td class="none" align="center">No</td>
   </tr>
-  <tr>
+  <tr id="227">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#227">227</a></td>
     <td>TC1</td>
     <td>How many scopes in an <TT>if</TT> statement?</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="228">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#228">228</a></td>
     <td>CD1</td>
     <td>Use of <TT>template</TT> keyword with non-member templates</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="229">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#229">229</a></td>
     <td>NAD</td>
     <td>Partial specialization of function templates</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr class="open">
+  <tr id="230">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#230">230</a></td>
-    <td>extension</td>
+    <td>NAD</td>
     <td>Calls to pure virtual functions</td>
-    <td align="center">Not resolved</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="231">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#231">231</a></td>
     <td>NAD</td>
     <td>Visibility of names after <I>using-directive</I>s</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="232">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#232">232</a></td>
     <td>drafting</td>
     <td>Is indirection through a null pointer undefined behavior?</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="233">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#233">233</a></td>
     <td>open</td>
     <td>References vs pointers in UDC overload resolution</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="234">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#234">234</a></td>
     <td>NAD</td>
     <td>Reuse of base class subobjects</td>
     <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="235">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#235">235</a></td>
     <td>TC1</td>
     <td>Assignment vs initialization</td>
     <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="236">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#236">236</a></td>
     <td>NAD</td>
     <td>Explicit temporaries and integral constant expressions</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="237">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#237">237</a></td>
     <td>CD1</td>
     <td>Explicit instantiation and base class members</td>
-    <td class="none" align="center">Duplicate of 470</td>
+    <td class="full" align="center">Duplicate of <a href="#470">470</a></td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="238">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#238">238</a></td>
     <td>open</td>
     <td>Precision and accuracy constraints on floating point</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="239">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#239">239</a></td>
     <td>CD1</td>
     <td>Footnote 116 and Koenig lookup</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="240">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#240">240</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Uninitialized values and undefined behavior</td>
-    <td class="none" align="center">Duplicate of 616</td>
+    <td class="none" align="center">Duplicate of <a href="#616">616</a></td>
   </tr>
-  <tr>
+  <tr id="241">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#241">241</a></td>
     <td>TC1</td>
     <td>Error in example in 14.8.1</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="242">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#242">242</a></td>
     <td>open</td>
     <td>Interpretation of old-style casts</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="243">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#243">243</a></td>
     <td>NAD</td>
     <td>Weighting of conversion functions in direct-initialization</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="244">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#244">244</a></td>
     <td>CD1</td>
     <td>Destructor lookup</td>
-    <td class="none" align="center">No</td>
+    <td class="svn" align="center">SVN</td>
   </tr>
-  <tr>
+  <tr id="245">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#245">245</a></td>
     <td>CD1</td>
     <td>Name lookup in <I>elaborated-type-specifier</I>s</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="246">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#246">246</a></td>
     <td>CD1</td>
     <td>Jumps in <I>function-try-block</I> handlers</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="247">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#247">247</a></td>
     <td>NAD</td>
     <td>Pointer-to-member casts and function overload resolution</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="248">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#248">248</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Identifier characters</td>
     <td class="full" align="center">Yes (C++11 onwards)</td>
   </tr>
-  <tr>
+  <tr id="249">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#249">249</a></td>
     <td>TC1</td>
     <td>What is a member function template?</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="250">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#250">250</a></td>
     <td>TC1</td>
     <td>Address of function template specialization with non-deduced template arguments</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="251">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#251">251</a></td>
     <td>open</td>
     <td>How many signed integer types are there?</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="252">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#252">252</a></td>
     <td>CD1</td>
     <td>Looking up deallocation functions in virtual destructors</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="253">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#253">253</a></td>
     <td>drafting</td>
     <td>Why must empty or fully-initialized const objects be initialized?</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="254">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#254">254</a></td>
     <td>CD1</td>
     <td>Definitional problems with <I>elaborated-type-specifier</I>s</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="255">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#255">255</a></td>
     <td>drafting</td>
     <td>Placement deallocation functions and lookup ambiguity</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="256">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#256">256</a></td>
     <td>CD1</td>
     <td>Overflow in size calculations</td>
-    <td class="none" align="center">Duplicate of 624</td>
+    <td class="none" align="center">Duplicate of <a href="#624">624</a></td>
   </tr>
-  <tr>
+  <tr id="257">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#257">257</a></td>
     <td>CD2</td>
     <td>Abstract base constructors and virtual base initialization</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="258">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#258">258</a></td>
     <td>CD1</td>
     <td><I>using-declaration</I>s and cv-qualifiers</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="259">
     <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="full" align="center">Yes (C++11 onwards)</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="260">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#260">260</a></td>
     <td>open</td>
     <td>User-defined conversions and built-in <TT>operator=</TT></td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="261">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#261">261</a></td>
     <td>CD1</td>
     <td>When is a deallocation function "used?"</td>
     <td class="none" align="center">No</td>
   </tr>
-  <tr>
+  <tr id="262">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#262">262</a></td>
     <td>CD1</td>
     <td>Default arguments and ellipsis</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="263">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#263">263</a></td>
     <td>CD1</td>
     <td>Can a constructor be declared a friend?</td>
     <td class="full" align="center">Yes</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="264">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#264">264</a></td>
     <td>open</td>
     <td>Unusable template constructors and conversion functions</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="265">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#265">265</a></td>
     <td>dup</td>
     <td>Destructors, exceptions, and deallocation</td>
-    <td class="none" align="center">Duplicate of 353</td>
+    <td class="none" align="center">Duplicate of <a href="#353">353</a></td>
   </tr>
-  <tr>
+  <tr id="266">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#266">266</a></td>
     <td>NAD</td>
     <td>No grammar sentence symbol</td>
     <td class="na" align="center">N/A</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="267">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#267">267</a></td>
     <td>open</td>
     <td>Alignment requirement for <I>new-expression</I>s</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="268">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#268">268</a></td>
     <td>open</td>
     <td>Macro name suppression in rescanned replacement text</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="269">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#269">269</a></td>
     <td>NAD</td>
     <td>Order of initialization of multiply-defined static data members

 of class templates</td>
     <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="270">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#270">270</a></td>
     <td>CD1</td>
     <td>Order of initialization of static data members of class templates</td>
     <td class="na" align="center">N/A</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="271">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#271">271</a></td>
     <td>open</td>
     <td>Explicit instantiation and template argument deduction</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="272">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#272">272</a></td>
     <td>CD1</td>
     <td>Explicit destructor invocation and <I>qualified-id</I>s</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="273">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#273">273</a></td>
     <td>CD1</td>
     <td>POD classes and <TT>operator&amp;()</TT></td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="274">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#274">274</a></td>
     <td>CD1</td>
     <td>Cv-qualification and char-alias access to out-of-lifetime objects</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="275">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#275">275</a></td>
     <td>CD1</td>
     <td>Explicit instantiation/specialization and <I>using-directive</I>s</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">No</td>
   </tr>
-  <tr>
+  <tr id="276">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#276">276</a></td>
     <td>CD1</td>
     <td>Order of destruction of parameters and temporaries</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="277">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#277">277</a></td>
     <td>CD1</td>
     <td>Zero-initialization of pointers</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="278">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#278">278</a></td>
     <td>open</td>
     <td>External linkage and nameless entities</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="279">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#279">279</a></td>
     <td>open</td>
     <td>Correspondence of "names for linkage purposes"</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="280">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#280">280</a></td>
     <td>CD1</td>
     <td>Access and surrogate call functions</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="281">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#281">281</a></td>
     <td>CD1</td>
     <td><TT>inline</TT> specifier in <TT>friend</TT> declarations</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">No</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="282">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#282">282</a></td>
     <td>open</td>
     <td>Namespace for <TT>extended_type_info</TT></td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="283">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#283">283</a></td>
     <td>CD1</td>
     <td>Template <I>type-parameter</I>s are not syntactically <I>type-name</I>s</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="284">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#284">284</a></td>
     <td>CD1</td>
     <td><I>qualified-id</I>s in class declarations</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">No</td>
   </tr>
-  <tr>
+  <tr id="285">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#285">285</a></td>
     <td>NAD</td>
     <td>Identifying a function template being specialized</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="286">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#286">286</a></td>
     <td>CD1</td>
     <td>Incorrect example in partial specialization</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="287">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#287">287</a></td>
     <td>drafting</td>
     <td>Order dependencies in template instantiation</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="288">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#288">288</a></td>
     <td>CD1</td>
     <td>Misuse of "static type" in describing pointers</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="289">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#289">289</a></td>
     <td>CD1</td>
     <td>Incomplete list of contexts requiring a complete type</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="290">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#290">290</a></td>
     <td>NAD</td>
     <td>Should memcpy be allowed into a POD with a const member?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="291">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#291">291</a></td>
     <td>CD1</td>
     <td>Overload resolution needed when binding reference to class rvalue</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Duplicate of <a href="#391">391</a></td>
   </tr>
-  <tr>
+  <tr id="292">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#292">292</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Deallocation on exception in <TT>new</TT> before arguments evaluated</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="293">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#293">293</a></td>
     <td>open</td>
     <td>Syntax of explicit instantiation/specialization too permissive</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="294">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#294">294</a></td>
     <td>NAD</td>
     <td>Can <TT>static_cast</TT> drop exception specifications?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">No</td>
   </tr>
-  <tr>
+  <tr id="295">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#295">295</a></td>
     <td>CD1</td>
     <td>cv-qualifiers on function types</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">No</td>
   </tr>
-  <tr>
+  <tr id="296">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#296">296</a></td>
     <td>CD1</td>
     <td>Can conversion functions be static?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="297">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#297">297</a></td>
     <td>open</td>
     <td>Which template does an explicit specialization specialize?</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="298">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#298">298</a></td>
     <td>CD1</td>
     <td><TT>T::x</TT> when <TT>T</TT> is cv-qualified</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="299">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#299">299</a></td>
     <td>CD1</td>
     <td>Conversion on array bound expression in <TT>new</TT></td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes (C++11 onwards)</td>
   </tr>
-  <tr>
+  <tr id="300">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#300">300</a></td>
     <td>CD1</td>
     <td>References to functions in template argument deduction</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="301">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#301">301</a></td>
     <td>CD1</td>
     <td>Syntax for <I>template-name</I></td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="302">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#302">302</a></td>
     <td>CD1</td>
     <td>Value-initialization and generation of default constructor</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="303">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#303">303</a></td>
     <td>NAD</td>
     <td>Integral promotions on bit-fields</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="304">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#304">304</a></td>
     <td>TC1</td>
     <td>Value-initialization of a reference</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="305">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#305">305</a></td>
     <td>CD1</td>
     <td>Name lookup in destructor call</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">No</td>
   </tr>
-  <tr>
+  <tr id="306">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#306">306</a></td>
     <td>CD1</td>
     <td>Ambiguity by class name injection</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">No</td>
   </tr>
-  <tr>
+  <tr id="307">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#307">307</a></td>
     <td>NAD</td>
     <td>Initialization of a virtual base class subobject</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="308">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#308">308</a></td>
     <td>NAD</td>
     <td>Catching exceptions with ambiguous base classes</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="309">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#309">309</a></td>
     <td>CD1</td>
     <td>Linkage of entities whose names are not simply identifiers, in introduction</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Duplicate of <a href="#485">485</a></td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="310">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#310">310</a></td>
     <td>open</td>
     <td>Can function templates differing only in parameter cv-qualifiers be overloaded?</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="311">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#311">311</a></td>
     <td>NAD</td>
     <td>Using qualified name to reopen nested namespace</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="312">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#312">312</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>&#8220;use&#8221; of invalid pointer value not defined</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">Duplicate of <a href="#616">616</a></td>
   </tr>
-  <tr>
+  <tr id="313">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#313">313</a></td>
     <td>dup</td>
     <td>Class with single conversion function to integral as array size in <TT>new</TT></td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Duplicate of <a href="#299">299</a> (C++11 onwards)</td>
   </tr>
-  <tr class="open">
+  <tr id="314">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#314">314</a></td>
-    <td>drafting</td>
+    <td>ready</td>
     <td><TT>template</TT> in base class specifier</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Duplicate of <a href="#1710">1710</a></td>
   </tr>
-  <tr>
+  <tr id="315">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#315">315</a></td>
     <td>NAD</td>
     <td>Is call of static member function through null pointer undefined?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="316">
     <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">Unknown</td>
+    <td class="none" align="center">Superseded by <a href="#1004">1004</a></td>
   </tr>
-  <tr>
+  <tr id="317">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#317">317</a></td>
     <td>CD1</td>
     <td>Can a function be declared inline after it has been called?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="svn" align="center">SVN</td>
   </tr>
-  <tr>
+  <tr id="318">
     <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">Unknown</td>
+    <td class="none" align="center">Superseded by <a href="#1310">1310</a></td>
   </tr>
-  <tr>
+  <tr id="319">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#319">319</a></td>
     <td>CD1</td>
     <td>Use of names without linkage in declaring entities with linkage</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">No</td>
   </tr>
-  <tr>
+  <tr id="320">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#320">320</a></td>
     <td>CD1</td>
     <td>Question on copy constructor elision example</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="321">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#321">321</a></td>
     <td>dup</td>
     <td>Associated classes and namespaces for argument-dependent lookup</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">Duplicate of <a href="#557">557</a></td>
   </tr>
-  <tr>
+  <tr id="322">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#322">322</a></td>
     <td>CD1</td>
     <td>Deduction of reference conversions</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="323">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#323">323</a></td>
     <td>CD1</td>
     <td>Where must <TT>export</TT> appear?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">No</td>
   </tr>
-  <tr>
+  <tr id="324">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#324">324</a></td>
     <td>CD1</td>
     <td>Can "<TT>&amp;</TT>" be applied to assignment to bit-field?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="325">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#325">325</a></td>
     <td>drafting</td>
     <td>When are default arguments parsed?</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="326">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#326">326</a></td>
     <td>CD1</td>
     <td>Wording for definition of trivial constructor</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="327">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#327">327</a></td>
     <td>CD1</td>
     <td>Use of "structure" without definition</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">Duplicate of <a href="#538">538</a></td>
   </tr>
-  <tr>
+  <tr id="328">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#328">328</a></td>
     <td>CD1</td>
     <td>Missing requirement that class member types be complete</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="329">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#329">329</a></td>
     <td>CD1</td>
     <td>Evaluation of friends of templates</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="svn" align="center">SVN</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="330">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#330">330</a></td>
     <td>open</td>
     <td>Qualification conversions and pointers to arrays of pointers</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="331">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#331">331</a></td>
     <td>CD1</td>
     <td>Allowed copy constructor signatures</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="332">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#332">332</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>cv-qualified <TT>void</TT> parameter types</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">Duplicate of <a href="#557">557</a></td>
   </tr>
-  <tr>
+  <tr id="333">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#333">333</a></td>
     <td>NAD</td>
     <td>Ambiguous use of "declaration" in disambiguation section</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="334">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#334">334</a></td>
     <td>NAD</td>
     <td>Is a comma-expression dependent if its first operand is?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="335">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#335">335</a></td>
     <td>CD1</td>
     <td>Allowing <TT>export</TT> on template members of nontemplate classes</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">No</td>
   </tr>
-  <tr>
+  <tr id="336">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#336">336</a></td>
     <td>CD1</td>
     <td>Explicit specialization examples are still incorrect</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="337">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#337">337</a></td>
     <td>CD1</td>
     <td>Attempt to create array of abtract type should cause deduction to fail</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="338">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#338">338</a></td>
     <td>open</td>
     <td>Enumerator name with linkage used as class name in other translation unit</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="339">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#339">339</a></td>
     <td>CD1</td>
     <td>Overload resolution in operand of <TT>sizeof</TT> in constant expression</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="340">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#340">340</a></td>
     <td>NAD</td>
     <td>Unclear wording in disambiguation section</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="341">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#341">341</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td><TT>extern "C"</TT> namespace member function versus global variable</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">Superseded by <a href="#1708">1708</a></td>
   </tr>
-  <tr>
+  <tr id="342">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#342">342</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Terminology: "indirection" versus "dereference"</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="na" align="center">N/A</td>
   </tr>
-  <tr class="open">
+  <tr id="343">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#343">343</a></td>
-    <td>open</td>
+    <td>ready</td>
     <td>Make <TT>template</TT> optional in contexts that require a type</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">No</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#344">344</a></td>
-    <td>open</td>
+  <tr id="344">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#344">344</a></td>
+    <td>CD3</td>
     <td>Naming destructors</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Duplicate of <a href="#1435">1435</a></td>
   </tr>
-  <tr>
+  <tr id="345">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#345">345</a></td>
     <td>CD1</td>
     <td>Misleading comment on example in templates chapter</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="346">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#346">346</a></td>
     <td>NAD</td>
     <td>Typo in 15.4</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="347">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#347">347</a></td>
     <td>NAD</td>
     <td>Use of derived class name in defining base class nested class</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="348">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#348">348</a></td>
     <td>CD1</td>
     <td><TT>delete</TT> and user-written deallocation functions</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="349">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#349">349</a></td>
     <td>CD1</td>
     <td>Template argument deduction for conversion functions and qualification conversions</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">No</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="350">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#350">350</a></td>
     <td>open</td>
     <td><TT>signed char</TT> underlying representation for objects</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="351">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#351">351</a></td>
     <td>CD1</td>
     <td>Sequence point error: unspecified or undefined?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="352">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#352">352</a></td>
     <td>CD1</td>
     <td>Nondeduced contexts</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="353">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#353">353</a></td>
     <td>CD1</td>
     <td>Is deallocation routine called if destructor throws exception in delete?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="354">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#354">354</a></td>
     <td>CD1</td>
     <td>Null as nontype template argument</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes (C++11 onwards)</td>
   </tr>
-  <tr>
+  <tr id="355">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#355">355</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Global-scope <TT>::</TT> in <I>nested-name-specifier</I></td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="356">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#356">356</a></td>
     <td>NAD</td>
     <td>Wording of behavior of generated copy constructor for scalar members</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="357">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#357">357</a></td>
     <td>CD1</td>
     <td>Definition of signature should include name</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="358">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#358">358</a></td>
     <td>NAD</td>
     <td>Namespaces and extern "C"</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="359">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#359">359</a></td>
     <td>NAD</td>
     <td>Type definition in anonymous union</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="360">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#360">360</a></td>
     <td>open</td>
     <td>Using-declaration that reduces access</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="361">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#361">361</a></td>
     <td>open</td>
     <td>Forward reference to default argument</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="362">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#362">362</a></td>
     <td>CD1</td>
     <td>Order of initialization in instantiation units</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="363">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#363">363</a></td>
     <td>NAD</td>
     <td>Initialization of class from self</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="364">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#364">364</a></td>
     <td>CD1</td>
     <td>Calling overloaded function with static in set, with no object</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="365">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#365">365</a></td>
     <td>open</td>
     <td>Storage duration and temporaries</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="366">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#366">366</a></td>
     <td>CD1</td>
     <td>String literal allowed in integral constant expression?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="367">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#367">367</a></td>
     <td>CD1</td>
     <td><TT>throw</TT> operator allowed in constant expression?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="368">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#368">368</a></td>
     <td>CD1</td>
     <td>Uses of non-type parameters that should cause deduction to fail</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="369">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#369">369</a></td>
     <td>drafting</td>
     <td>Are <TT>new</TT>/<TT>delete</TT> identifiers or <I>preprocessing-op-or-punc</I>?</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="370">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#370">370</a></td>
     <td>CD1</td>
     <td>Can <TT>#include &lt;...&gt;</TT> form be used other than for standard C++ headers?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="na" align="center">N/A</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="371">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#371">371</a></td>
     <td>open</td>
     <td>Interleaving of constructor calls</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="372">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#372">372</a></td>
     <td>CD1</td>
     <td>Is access granted by base class specifiers available in following base class specifiers?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">No</td>
   </tr>
-  <tr>
+  <tr id="373">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#373">373</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Lookup on namespace qualified name in using-directive</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">No</td>
   </tr>
-  <tr>
+  <tr id="374">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#374">374</a></td>
     <td>CD2</td>
     <td>Can explicit specialization outside namespace use qualified name?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes (C++11 onwards)</td>
   </tr>
-  <tr>
+  <tr id="375">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#375">375</a></td>
     <td>dup</td>
     <td>Confusing example on lookup with <TT>typename</TT></td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Duplicate of <a href="#345">345</a></td>
   </tr>
-  <tr>
+  <tr id="376">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#376">376</a></td>
     <td>NAD</td>
     <td>Class "definition" versus class "declaration"</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="377">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#377">377</a></td>
     <td>CD1</td>
     <td>Enum whose enumerators will not fit in any integral type</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="378">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#378">378</a></td>
     <td>CD1</td>
     <td>Wording that says temporaries are declared</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="na" align="center">Duplicate of <a href="#276">276</a></td>
   </tr>
-  <tr>
+  <tr id="379">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#379">379</a></td>
     <td>CD1</td>
     <td>Change "class declaration" to "class definition"</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="na" align="center">N/A</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="380">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#380">380</a></td>
     <td>open</td>
     <td>Definition of "ambiguous base class" missing</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="381">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#381">381</a></td>
     <td>CD1</td>
     <td>Incorrect example of base class member lookup</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="382">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#382">382</a></td>
     <td>CD1</td>
     <td>Allow <TT>typename</TT> outside of templates</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes (C++11 onwards)</td>
   </tr>
-  <tr>
+  <tr id="383">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#383">383</a></td>
     <td>CD1</td>
     <td>Is a class with a declared but not defined destructor a POD?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="384">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#384">384</a></td>
     <td>NAD</td>
     <td>Argument-dependent lookup and operator functions</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="385">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#385">385</a></td>
     <td>CD1</td>
     <td>How does protected member check of 11.5 interact with using-declarations?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="386">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#386">386</a></td>
     <td>drafting</td>
     <td>Friend declaration of name brought in by <I>using-declaration</I></td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="387">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#387">387</a></td>
     <td>CD1</td>
     <td>Errors in example in 14.6.5</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="388">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#388">388</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Catching base<TT>*&amp;</TT> from a throw of derived<TT>*</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="389">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#389">389</a></td>
     <td>CD1</td>
     <td>Unnamed types in entities with linkage</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">No</td>
   </tr>
-  <tr>
+  <tr id="390">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#390">390</a></td>
     <td>CD1</td>
     <td>Pure virtual must be defined when implicitly called</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="391">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#391">391</a></td>
     <td>CD1</td>
     <td>Require direct binding of short-lived references to rvalues</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes (C++11 onwards)</td>
   </tr>
-  <tr>
+  <tr id="392">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#392">392</a></td>
     <td>CD1</td>
     <td>Use of full expression lvalue before temporary destruction</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr id="393">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#393">393</a></td>
-    <td>open</td>
+    <td>ready</td>
     <td>Pointer to array of unknown bound in template argument list in parameter</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="394">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#394">394</a></td>
     <td>CD1</td>
     <td><I>identifier-list</I> is never defined</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="395">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#395">395</a></td>
     <td>NAD</td>
     <td>Conversion operator template syntax</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="396">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#396">396</a></td>
     <td>CD1</td>
     <td>Misleading note regarding use of <TT>auto</TT> for disambiguation</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="397">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#397">397</a></td>
     <td>CD1</td>
     <td>Same address for string literals from default arguments in inline functions?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">Superseded by <a href="#1823">1823</a></td>
   </tr>
-  <tr>
+  <tr id="398">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#398">398</a></td>
     <td>CD1</td>
     <td>Ambiguous wording on naming a type in deduction</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="399">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#399">399</a></td>
     <td>drafting</td>
     <td>Destructor lookup redux</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="400">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#400">400</a></td>
     <td>CD1</td>
     <td>Using-declarations and the "struct hack"</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="401">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#401">401</a></td>
     <td>CD1</td>
     <td>When is access for template parameter default arguments checked?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="402">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#402">402</a></td>
     <td>open</td>
     <td>More on partial ordering of function templates</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="403">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#403">403</a></td>
     <td>CD1</td>
     <td>Reference to a type as a <I>template-id</I></td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="404">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#404">404</a></td>
     <td>CD1</td>
     <td>Unclear reference to construction with non-trivial constructor</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="na" align="center">N/A</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="405">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#405">405</a></td>
     <td>open</td>
     <td>Unqualified function name lookup</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="406">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#406">406</a></td>
     <td>CD1</td>
     <td>Static data member in class with name for linkage purposes</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="407">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#407">407</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Named class with associated typedef: two names or one?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">No</td>
   </tr>
-  <tr>
+  <tr id="408">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#408">408</a></td>
     <td>CD2</td>
     <td>sizeof applied to unknown-bound array static data member of template</td>
-    <td class="svn" align="center">SVN</td>
+    <td class="full" align="center">Clang 3.4</td>
   </tr>
-  <tr>
+  <tr id="409">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#409">409</a></td>
     <td>CD1</td>
     <td>Obsolete paragraph missed by changes for issue 224</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="410">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#410">410</a></td>
     <td>CD1</td>
     <td>Paragraph missed in changes for issue 166</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">No</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="411">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#411">411</a></td>
     <td>open</td>
     <td>Use of universal-character-name in character versus string literals</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="412">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#412">412</a></td>
     <td>NAD</td>
     <td>Can a replacement allocation function be inline?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="413">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#413">413</a></td>
     <td>CD1</td>
     <td>Definition of "empty class"</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="414">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#414">414</a></td>
     <td>CD1</td>
     <td>Multiple types found on destructor lookup</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">Duplicate of <a href="#305">305</a></td>
   </tr>
-  <tr>
+  <tr id="415">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#415">415</a></td>
     <td>CD1</td>
     <td>Template deduction does not cause instantiation</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="416">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#416">416</a></td>
     <td>CD1</td>
     <td>Class must be complete to allow operator lookup?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="417">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#417">417</a></td>
     <td>CD1</td>
     <td>Using derived-class qualified name in out-of-class nested class definition</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">No</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="418">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#418">418</a></td>
     <td>open</td>
     <td>Imperfect wording on error on multiple default arguments on a called function</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="419">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#419">419</a></td>
     <td>open</td>
     <td>Can cast to virtual base class be done on partially-constructed object?</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="420">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#420">420</a></td>
     <td>CD1</td>
     <td>postfixexpression-&gt;scalar_type_dtor() inconsistent</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="421">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#421">421</a></td>
     <td>CD1</td>
     <td>Is rvalue.field an rvalue?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="422">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#422">422</a></td>
     <td>NAD</td>
     <td>Is a typedef redeclaration allowed with a template type that might be the same?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="423">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#423">423</a></td>
     <td>NAD</td>
     <td>Can a conversion be done on the left operand of a compound assignment?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="424">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#424">424</a></td>
     <td>CD1</td>
     <td>Wording problem with issue 56 resolution on redeclaring typedefs in class scope</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="425">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#425">425</a></td>
     <td>CD1</td>
     <td>Set of candidates for overloaded built-in operator with float operand</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr class="open">
+  <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>Identically-named variables, one internally and one externally linked, allowed?</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="427">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#427">427</a></td>
     <td>CD1</td>
     <td><TT>static_cast</TT> ambiguity: conversion versus cast to derived</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="428">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#428">428</a></td>
     <td>CD1</td>
     <td>Mention of expression with reference type</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="429">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#429">429</a></td>
     <td>CD1</td>
     <td>Matching deallocation function chosen based on syntax or signature?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes (C++11 onwards)</td>
   </tr>
-  <tr>
+  <tr id="430">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#430">430</a></td>
     <td>CD1</td>
     <td>Ordering of expression evaluation in initializer list</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes (C++11 onwards)</td>
   </tr>
-  <tr>
+  <tr id="431">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#431">431</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Defect in wording in 14.2</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="432">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#432">432</a></td>
     <td>CD1</td>
     <td>Is injected class name visible in base class specifier list?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="433">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#433">433</a></td>
     <td>CD1</td>
     <td>Do elaborated type specifiers in templates inject into enclosing namespace scope?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="434">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#434">434</a></td>
     <td>NAD</td>
     <td>Unclear suppression of standard conversions while binding reference to lvalue</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="435">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#435">435</a></td>
     <td>NAD</td>
     <td>Change "declararation or definition" to "declaration"</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="436">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#436">436</a></td>
     <td>CD1</td>
     <td>Problem in example in 9.6 paragraph 4</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="437">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#437">437</a></td>
     <td>CD1</td>
     <td>Is type of class allowed in member function exception specification?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">No</td>
   </tr>
-  <tr>
+  <tr id="438">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#438">438</a></td>
     <td>CD2</td>
     <td>Possible flaw in wording for multiple accesses to object between sequence points</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="439">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#439">439</a></td>
     <td>CD1</td>
     <td>Guarantees on casting pointer back to cv-qualified version of original type</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="440">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#440">440</a></td>
     <td>open</td>
     <td>Allow implicit pointer-to-member conversion on nontype template argument</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="441">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#441">441</a></td>
     <td>CD1</td>
     <td>Ordering of static reference initialization</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="442">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#442">442</a></td>
     <td>CD1</td>
     <td>Incorrect use of null pointer constant in description of delete operator</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="na" align="center">Superseded by <a href="#348">348</a></td>
   </tr>
-  <tr>
+  <tr id="443">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#443">443</a></td>
     <td>CD1</td>
     <td>Wording nit in description of lifetime of temporaries</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="444">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#444">444</a></td>
     <td>NAD</td>
     <td>Overriding and the generated copy assignment operator</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="445">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#445">445</a></td>
     <td>NAD</td>
     <td>Wording issue on friend declarations</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="446">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#446">446</a></td>
     <td>CD1</td>
     <td>Does an lvalue-to-rvalue conversion on the "?" operator produce a temporary?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="447">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#447">447</a></td>
     <td>CD1</td>
     <td>Is offsetof type-dependent?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="448">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#448">448</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Set of template functions in call with dependent explicit argument</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="449">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#449">449</a></td>
     <td>NAD</td>
     <td>Consistency in use of hyphen with names of "non" entities</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="450">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#450">450</a></td>
     <td>CD1</td>
     <td>Binding a reference to const to a cv-qualified array rvalue</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="451">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#451">451</a></td>
     <td>CD1</td>
     <td>Expressions with invalid results and ill-formedness</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="452">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#452">452</a></td>
     <td>CD1</td>
     <td>Wording nit on description of <TT>this</TT></td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="453">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#453">453</a></td>
     <td>drafting</td>
     <td>References may only bind to &#8220;valid&#8221; objects</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="454">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#454">454</a></td>
     <td>CD1</td>
     <td>When is a definition of a static data member required?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="455">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#455">455</a></td>
     <td>drafting</td>
     <td>Partial ordering and non-deduced arguments</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="456">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#456">456</a></td>
     <td>NAD</td>
     <td>Is initialized const int or const bool variable a null pointer constant?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="457">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#457">457</a></td>
     <td>CD1</td>
     <td>Wording nit on use of const variables in constant expressions</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="458">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#458">458</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Hiding of member template parameters by other members</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">No</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="459">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#459">459</a></td>
     <td>open</td>
     <td>Hiding of template parameters by base class members</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="460">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#460">460</a></td>
     <td>CD1</td>
     <td>Can a <I>using-declaration</I> name a namespace?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="461">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#461">461</a></td>
     <td>NAD</td>
     <td>Make <TT>asm</TT> conditionally-supported</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="462">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#462">462</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Lifetime of temporaries bound to comma expressions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="463">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#463">463</a></td>
     <td>CD1</td>
     <td><TT>reinterpret_cast&lt;T*&gt;(0)</TT></td>
-    <td class="none" align="center">Unknown</td>
+    <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="464">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#464">464</a></td>
     <td>CD1</td>
     <td>Wording nit on lifetime of temporaries to which references are bound</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="465">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#465">465</a></td>
     <td>NAD</td>
     <td>May constructors of global objects call <TT>exit()</TT>?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="466">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#466">466</a></td>
     <td>CD1</td>
     <td>cv-qualifiers on pseudo-destructor type</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">No</td>
   </tr>
-  <tr>
+  <tr id="467">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#467">467</a></td>
     <td>NAD</td>
     <td>Jump past initialization of local static variable</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="468">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#468">468</a></td>
     <td>CD1</td>
     <td>Allow <TT>::template</TT> outside of templates</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes (C++11 onwards)</td>
   </tr>
-  <tr>
+  <tr id="469">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#469">469</a></td>
     <td>NAD</td>
     <td>Const template specializations and reference arguments</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">No</td>
   </tr>
-  <tr>
+  <tr id="470">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#470">470</a></td>
     <td>CD1</td>
     <td>Instantiation of members of an explicitly-instantiated class template</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="471">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#471">471</a></td>
     <td>NAD</td>
     <td>Conflicting inherited access specifications</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="472">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#472">472</a></td>
     <td>drafting</td>
     <td>Casting across protected inheritance</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="473">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#473">473</a></td>
     <td>open</td>
     <td>Block-scope declarations of allocator functions</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="474">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#474">474</a></td>
     <td>CD1</td>
     <td>Block-scope <TT>extern</TT> declarations in namespace members</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="475">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#475">475</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>When is <TT>std::uncaught_exception()</TT> true? (take 2)</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="476">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#476">476</a></td>
     <td>extension</td>
     <td>Determining the buffer size for placement new</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="477">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#477">477</a></td>
     <td>CD1</td>
     <td>Can <TT>virtual</TT> appear in a <TT>friend</TT> declaration?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="svn" align="center">SVN</td>
   </tr>
-  <tr>
+  <tr id="478">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#478">478</a></td>
     <td>NAD</td>
     <td>May a function parameter be an array of an abstract class type?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="479">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#479">479</a></td>
     <td>CD1</td>
     <td>Copy elision in exception handling</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="480">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#480">480</a></td>
     <td>CD1</td>
     <td>Is a base of a virtual base also virtual?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="481">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#481">481</a></td>
     <td>CD2</td>
     <td>Scope of template parameters</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="482">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#482">482</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Qualified declarators in redeclarations</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="svn" align="center">SVN</td>
   </tr>
-  <tr>
+  <tr id="483">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#483">483</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Normative requirements on integral ranges</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="484">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#484">484</a></td>
     <td>CD1</td>
     <td>Can a <I>base-specifier</I> name a cv-qualified class type?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="485">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#485">485</a></td>
     <td>CD1</td>
     <td>What is a &#8220;name&#8221;?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="486">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#486">486</a></td>
     <td>CD1</td>
     <td>Invalid return types and template argument deduction</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="487">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#487">487</a></td>
     <td>NAD</td>
     <td>Operator overloading in constant expressions</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="488">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#488">488</a></td>
     <td>CD1</td>
     <td>Local types, overload resolution, and template argument deduction</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes (C++11 onwards)</td>
   </tr>
-  <tr>
+  <tr id="489">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#489">489</a></td>
     <td>NAD</td>
     <td>Must member function templates be instantiated during overload resolution?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="490">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#490">490</a></td>
     <td>CD2</td>
     <td>Name lookup in friend declarations</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="491">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#491">491</a></td>
     <td>CD1</td>
     <td>Initializers for empty-class aggregrate members</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Duplicate of <a href="#413">413</a></td>
   </tr>
-  <tr>
+  <tr id="492">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#492">492</a></td>
     <td>CD1</td>
     <td><TT>typeid</TT> constness inconsistent with example</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="493">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#493">493</a></td>
     <td>CD2</td>
     <td>Type deduction from a <TT>bool</TT> context</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">Duplicate of <a href="#976">976</a></td>
   </tr>
-  <tr>
+  <tr id="494">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#494">494</a></td>
     <td>CD1</td>
     <td>Problems with the resolution of issue 45</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">Duplicate of <a href="#372">372</a></td>
   </tr>
-  <tr>
+  <tr id="495">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#495">495</a></td>
     <td>CD2</td>
     <td>Overload resolution with template and non-template conversion functions</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="svn" align="center">SVN</td>
   </tr>
-  <tr>
+  <tr id="496">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#496">496</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Is a volatile-qualified type really a POD?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">No</td>
   </tr>
-  <tr>
+  <tr id="497">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#497">497</a></td>
     <td>CD1</td>
     <td>Missing required initialization in example</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="498">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#498">498</a></td>
     <td>open</td>
     <td>Storage class specifiers in definitions of class members</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="499">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#499">499</a></td>
     <td>CD2</td>
     <td>Throwing an array of unknown size</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="500">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#500">500</a></td>
     <td>CD1</td>
     <td>Access in <I>base-specifier</I>s of friend and nested classes</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">Duplicate of <a href="#372">372</a></td>
   </tr>
-  <tr>
+  <tr id="501">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#501">501</a></td>
     <td>NAD</td>
     <td>Visibility of friend declarations within the befriending class</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="502">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#502">502</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Dependency of nested enumerations and enumerators</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="503">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#503">503</a></td>
     <td>open</td>
     <td>Cv-qualified function types in template argument deduction</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="504">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#504">504</a></td>
     <td>open</td>
     <td>Should use of a variable in its own initializer require a diagnostic?</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="505">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#505">505</a></td>
     <td>CD1</td>
     <td>Conditionally-supported behavior for unknown character escapes</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="506">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#506">506</a></td>
     <td>CD1</td>
     <td>Conditionally-supported behavior for non-POD objects passed to ellipsis</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="507">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#507">507</a></td>
     <td>dup</td>
     <td>Ambiguity assigning class object to built-in type</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">Duplicate of <a href="#260">260</a></td>
   </tr>
-  <tr>
+  <tr id="508">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#508">508</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Non-constructed value-initialized objects</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="509">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#509">509</a></td>
     <td>CD1</td>
     <td>Dead code in the specification of default initialization</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="510">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#510">510</a></td>
     <td>CD1</td>
     <td>Default initialization of POD classes?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="na" align="center">N/A</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="511">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#511">511</a></td>
     <td>open</td>
     <td>POD-structs with template assignment operators</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="512">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#512">512</a></td>
     <td>NAD</td>
     <td>Union members with user-declared non-default constructors</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="513">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#513">513</a></td>
     <td>CD1</td>
     <td>Non-class &#8220;most-derived&#8221; objects</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="514">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#514">514</a></td>
     <td>CD1</td>
     <td>Is the initializer for a namespace member in the scope of the namespace?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="515">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#515">515</a></td>
     <td>CD1</td>
     <td>Non-dependent references to base class members</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">Superseded by <a href="#1017">1017</a></td>
   </tr>
-  <tr>
+  <tr id="516">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#516">516</a></td>
     <td>CD1</td>
     <td>Use of <TT>signed</TT> in bit-field declarations</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="517">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#517">517</a></td>
     <td>CD1</td>
     <td>Partial specialization following explicit instantiation</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">No</td>
   </tr>
-  <tr>
+  <tr id="518">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#518">518</a></td>
     <td>CD1</td>
     <td>Trailing comma following <I>enumerator-list</I></td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes (C++11 onwards)</td>
   </tr>
-  <tr>
+  <tr id="519">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#519">519</a></td>
     <td>CD1</td>
     <td>Null pointer preservation in <TT>void*</TT> conversions</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="520">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#520">520</a></td>
     <td>CD1</td>
     <td>Old-style casts between incomplete class types</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="na" align="center">N/A</td>
   </tr>
-  <tr>
+  <tr id="521">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#521">521</a></td>
     <td>CD1</td>
     <td>Requirements for exceptions thrown by allocation functions</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="none" align="center">No</td>
   </tr>
-  <tr>
+  <tr id="522">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#522">522</a></td>
     <td>CD1</td>
     <td>Array-to-pointer decay in template argument deduction</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="523">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#523">523</a></td>
     <td>open</td>
     <td>Can a one-past-the-end pointer be invalidated by deleting an adjacent object?</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="524">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#524">524</a></td>
     <td>CD1</td>
     <td>Can function-notation calls to operator functions be dependent?</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="525">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#525">525</a></td>
     <td>CD1</td>
     <td>Missing <TT>*</TT> in example</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="526">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#526">526</a></td>
     <td>CD1</td>
     <td>Confusing aspects in the specification of non-deduced contexts</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="527">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#527">527</a></td>
     <td>CD2</td>
     <td>Problems with linkage of types</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="528">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#528">528</a></td>
     <td>open</td>
     <td>Why are incomplete class types not allowed with <TT>typeid</TT>?</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="529">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#529">529</a></td>
     <td>drafting</td>
     <td>Use of <TT>template&lt;&gt;</TT> with &#8220;explicitly-specialized&#8221; class templates</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="530">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#530">530</a></td>
     <td>CD1</td>
     <td>Nontype template arguments in constant expressions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="531">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#531">531</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Defining members of explicit specializations</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="532">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#532">532</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Member/nonmember operator template partial ordering</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="svn" align="center">SVN</td>
   </tr>
-  <tr>
+  <tr id="533">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#533">533</a></td>
     <td>NAD</td>
     <td>Special treatment for C-style header names</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="534">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#534">534</a></td>
     <td>CD1</td>
     <td><I>template-name</I>s and <I>operator-function-id</I>s</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="535">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#535">535</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Copy construction without a copy constructor</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="536">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#536">536</a></td>
     <td>drafting</td>
     <td>Problems in the description of <I>id-expression</I>s</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="537">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#537">537</a></td>
     <td>CD1</td>
     <td>Definition of &#8220;signature&#8221;</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="538">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#538">538</a></td>
     <td>CD1</td>
     <td>Definition and usage

@@ -3272,7318 +3273,8134 @@
 and <I>POD class</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="539">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#539">539</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Constraints on <I>type-specifier-seq</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="540">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#540">540</a></td>
     <td>CD1</td>
     <td>Propagation of cv-qualifiers in reference-to-reference collapse</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="541">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#541">541</a></td>
     <td>CD2</td>
     <td>Dependent function types</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="542">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#542">542</a></td>
     <td>CD2</td>
     <td>Value initialization of arrays of POD-structs</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="543">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#543">543</a></td>
     <td>CD1</td>
     <td>Value initialization and default constructors</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="544">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#544">544</a></td>
     <td>NAD</td>
     <td>Base class lookup in explicit specialization</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="545">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#545">545</a></td>
     <td>open</td>
     <td>User-defined conversions and built-in operator overload resolution</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="546">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#546">546</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Explicit instantiation of class template members</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="547">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#547">547</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Partial specialization on member function types</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="548">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#548">548</a></td>
     <td>dup</td>
     <td><I>qualified-id</I>s in declarations</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="549">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#549">549</a></td>
     <td>drafting</td>
     <td>Non-deducible parameters in partial specializations</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="550">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#550">550</a></td>
     <td>open</td>
     <td>Pointer to array of unknown bound in parameter declarations</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="551">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#551">551</a></td>
     <td>CD1</td>
     <td>When is <TT>inline</TT> permitted in an explicit instantiation?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="552">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#552">552</a></td>
     <td>NAD</td>
     <td>Use of <TT>typename</TT> in the type in a non-type <I>parameter-declaration</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="553">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#553">553</a></td>
     <td>NAD</td>
     <td>Problems with friend allocation and deallocation functions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="554">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#554">554</a></td>
     <td>drafting</td>
     <td>Definition of &#8220;declarative region&#8221; and &#8220;scope&#8221;</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="555">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#555">555</a></td>
     <td>drafting</td>
     <td>Pseudo-destructor name lookup</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="556">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#556">556</a></td>
     <td>CD2</td>
     <td>Conflicting requirements for acceptable aliasing</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="557">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#557">557</a></td>
     <td>CD1</td>
     <td>Does argument-dependent lookup cause template instantiation?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="558">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#558">558</a></td>
     <td>CD1</td>
     <td>Excluded characters in universal character names</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="559">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#559">559</a></td>
     <td>CD1</td>
     <td>Editing error in issue 382 resolution</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="560">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#560">560</a></td>
     <td>drafting</td>
     <td>Use of the <TT>typename</TT> keyword in return types</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="561">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#561">561</a></td>
     <td>CD2</td>
     <td>Internal linkage functions in dependent name lookup</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="562">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#562">562</a></td>
     <td>open</td>
     <td><I>qualified-id</I>s in non-expression contexts</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="563">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#563">563</a></td>
     <td>open</td>
     <td>Linkage specification for objects</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="564">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#564">564</a></td>
     <td>CD2</td>
     <td>Agreement of language linkage or <I>linkage-specification</I>s?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="565">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#565">565</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Conflict rules for <I>using-declaration</I>s naming function templates</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="566">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#566">566</a></td>
     <td>NAD</td>
     <td>Conversion of negative floating point values to integer type</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="567">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#567">567</a></td>
     <td>NAD</td>
     <td>Can <TT>size_t</TT> and <TT>ptrdiff_t</TT> be larger than <TT>long</TT>?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="568">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#568">568</a></td>
     <td>CD1</td>
     <td>Definition of POD is too strict</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="569">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#569">569</a></td>
     <td>CD2</td>
     <td>Spurious semicolons at namespace scope should be allowed</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="570">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#570">570</a></td>
     <td>CD2</td>
     <td>Are references subject to the ODR?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="571">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#571">571</a></td>
     <td>CD2</td>
     <td>References declared <TT>const</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="572">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#572">572</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Standard conversions for non-built-in types</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="573">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#573">573</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Conversions between function pointers and <TT>void*</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="574">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#574">574</a></td>
     <td>NAD</td>
     <td>Definition of &#8220;copy assignment operator&#8221;</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="575">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#575">575</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Criteria for deduction failure</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="576">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#576">576</a></td>
     <td>CD2</td>
     <td>Typedefs in function definitions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="577">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#577">577</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td><TT>void</TT> in an empty parameter list</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="578">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#578">578</a></td>
     <td>open</td>
     <td>Phase 1 replacement of characters with <I>universal-character-name</I>s</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="579">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#579">579</a></td>
     <td>open</td>
     <td>What is a &#8220;nested&#8221; <TT>&gt;</TT> or <TT>&gt;&gt;</TT>?</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="580">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#580">580</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Access in <I>template-parameter</I>s of member and friend definitions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="581">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#581">581</a></td>
     <td>open</td>
     <td>Can a templated constructor be explicitly instantiated or specialized?</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="582">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#582">582</a></td>
     <td>CD1</td>
     <td>Template conversion functions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="583">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#583">583</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Relational pointer comparisons against the null pointer constant</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="584">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#584">584</a></td>
     <td>NAD</td>
     <td>Unions and aliasing</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="585">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#585">585</a></td>
     <td>NAD</td>
     <td>Friend template template parameters</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="586">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#586">586</a></td>
     <td>NAD</td>
     <td>Default <I>template-argument</I>s and template argument deduction</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="587">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#587">587</a></td>
     <td>CD2</td>
     <td>Lvalue operands of a conditional expression differing only in cv-qualification</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="588">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#588">588</a></td>
     <td>CD2</td>
     <td>Searching dependent bases of classes local to function templates</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="589">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#589">589</a></td>
     <td>CD2</td>
     <td>Direct binding of class and array rvalues in reference initialization</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="590">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#590">590</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Nested classes and the &#8220;current instantiation&#8221;</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr id="591">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#591">591</a></td>
-    <td>drafting</td>
+    <td>ready</td>
     <td>When a dependent base class is the current instantiation</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="592">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#592">592</a></td>
     <td>CD1</td>
     <td>Exceptions during construction of local static objects</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="593">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#593">593</a></td>
     <td>NAD</td>
     <td>Falling off the end of a destructor's <I>function-try-block</I> handler</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="594">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#594">594</a></td>
     <td>CD1</td>
     <td>Coordinating issues 119 and 404 with delegating constructors</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="595">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#595">595</a></td>
     <td>dup</td>
     <td>Exception specifications in templates instantiated from class bodies</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="596">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#596">596</a></td>
     <td>open</td>
     <td>Replacing an exception object</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="597">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#597">597</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Conversions applied to out-of-lifetime non-POD lvalues</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="598">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#598">598</a></td>
     <td>CD2</td>
     <td>Associated namespaces of overloaded functions and function templates</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="599">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#599">599</a></td>
     <td>CD2</td>
     <td>Deleting a null function pointer</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="600">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#600">600</a></td>
     <td>open</td>
     <td>Does access control apply to members or to names?</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="601">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#601">601</a></td>
     <td>CD2</td>
     <td>Type of literals in preprocessing expressions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="602">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#602">602</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>When is the injected-class-name of a class template a template?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="603">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#603">603</a></td>
     <td>CD1</td>
     <td>Type equivalence and unsigned overflow</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="604">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#604">604</a></td>
     <td>CD2</td>
     <td>Argument list for overload resolution in copy-initialization</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="605">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#605">605</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Linkage of explicit specializations</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="606">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#606">606</a></td>
     <td>CD1</td>
     <td>Template argument deduction for rvalue references</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="607">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#607">607</a></td>
     <td>open</td>
     <td>Lookup of <I>mem-initializer-id</I>s</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="608">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#608">608</a></td>
     <td>CD2</td>
     <td>Determining the final overrider of a virtual function</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr id="609">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#609">609</a></td>
-    <td>open</td>
+    <td>ready</td>
     <td>What is a &#8220;top-level&#8221; cv-qualifier?</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="610">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#610">610</a></td>
     <td>NAD</td>
     <td>Computing the negative of <TT>0U</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="611">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#611">611</a></td>
     <td>CD2</td>
     <td>Zero-initializing references</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="612">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#612">612</a></td>
     <td>CD2</td>
     <td>Requirements on a conforming implementation</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="613">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#613">613</a></td>
     <td>CD1</td>
     <td>Unevaluated uses of non-static class members</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="614">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#614">614</a></td>
     <td>CD1</td>
     <td>Results of integer <TT>/</TT> and <TT>%</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="615">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#615">615</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Incorrect description of variables that can be initialized</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="616">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#616">616</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Definition of &#8220;indeterminate value&#8221;</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="617">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#617">617</a></td>
     <td>drafting</td>
     <td>Lvalue-to-rvalue conversions of uninitialized <TT>char</TT> objects</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="618">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#618">618</a></td>
     <td>CD2</td>
     <td>Casts in preprocessor conditional expressions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="619">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#619">619</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Completeness of array types</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="620">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#620">620</a></td>
     <td>CD1</td>
     <td>Declaration order in layout-compatible POD structs</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="621">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#621">621</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Template argument deduction from function return types</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="622">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#622">622</a></td>
     <td>extension</td>
     <td>Relational comparisons of arbitrary pointers</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#623">623</a></td>
-    <td>extension</td>
+  <tr id="623">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#623">623</a></td>
+    <td>CD3</td>
     <td>Use of pointers to deallocated storage</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="624">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#624">624</a></td>
     <td>CD1</td>
     <td>Overflow in calculating size of allocation</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="625">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#625">625</a></td>
     <td>CD2</td>
     <td>Use of <TT>auto</TT> as a <I>template-argument</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="626">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#626">626</a></td>
     <td>CD2</td>
     <td>Preprocessor string literals</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="627">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#627">627</a></td>
     <td>NAD</td>
     <td>Values behaving as types</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="628">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#628">628</a></td>
     <td>CD2</td>
     <td>The values of an enumeration with no enumerator</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="629">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#629">629</a></td>
     <td>CD1</td>
     <td><TT>auto</TT> parsing ambiguity</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="630">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#630">630</a></td>
     <td>CD2</td>
     <td>Equality of narrow and wide character values in the basic character set</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="631">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#631">631</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Jumping into a &#8220;then&#8221; clause</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="632">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#632">632</a></td>
     <td>CD1</td>
     <td>Brace-enclosed initializer for scalar member of aggregate</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="633">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#633">633</a></td>
     <td>CD2</td>
     <td>Specifications for variables that should also apply to references</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="634">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#634">634</a></td>
     <td>CD1</td>
     <td>Conditionally-supported behavior for non-POD objects passed to ellipsis redux</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="635">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#635">635</a></td>
     <td>NAD</td>
     <td>Names of constructors and destructors of templates</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="636">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#636">636</a></td>
     <td>drafting</td>
     <td>Dynamic type of objects and aliasing</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="637">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#637">637</a></td>
     <td>CD1</td>
     <td>Sequencing rules and example disagree</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="638">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#638">638</a></td>
     <td>CD2</td>
     <td>Explicit specialization and friendship</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="639">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#639">639</a></td>
     <td>CD1</td>
     <td>What makes side effects &#8220;different&#8221; from one another?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="640">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#640">640</a></td>
     <td>open</td>
     <td>Accessing destroyed local objects of static storage duration</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="641">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#641">641</a></td>
     <td>CD2</td>
     <td>Overload resolution and conversion-to-same-type operators</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="642">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#642">642</a></td>
     <td>CD2</td>
     <td>Definition and use of &#8220;block scope&#8221; and &#8220;local scope&#8221;</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="643">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#643">643</a></td>
     <td>NAD</td>
     <td>Use of <TT>decltype</TT> in a class <I>member-specification</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="644">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#644">644</a></td>
     <td>CD1</td>
     <td>Should a trivial class type be a literal type?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="645">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#645">645</a></td>
     <td>CD2</td>
     <td>Are bit-field and non-bit-field members layout compatible?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="646">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#646">646</a></td>
     <td>NAD</td>
     <td>Can a class with a constexpr copy constructor be a literal type?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="647">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#647">647</a></td>
     <td>CD1</td>
     <td>Non-constexpr instances of constexpr constructor templates</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="648">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#648">648</a></td>
     <td>CD1</td>
     <td>Constant expressions in constexpr initializers</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="649">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#649">649</a></td>
     <td>CD1</td>
     <td>Optionally ill-formed extended alignment requests</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="650">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#650">650</a></td>
     <td>CD2</td>
     <td>Order of destruction for temporaries bound to the returned value of a function</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="651">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#651">651</a></td>
     <td>CD1</td>
     <td>Problems in <TT>decltype</TT> specification and examples</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="652">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#652">652</a></td>
     <td>CD2</td>
     <td>Compile-time evaluation of floating-point expressions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="653">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#653">653</a></td>
     <td>CD2</td>
     <td>Copy assignment of unions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="654">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#654">654</a></td>
     <td>CD1</td>
     <td>Conversions to and from <TT>nullptr_t</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="655">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#655">655</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Initialization not specified for forwarding constructors</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="656">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#656">656</a></td>
     <td>CD2</td>
     <td>Direct binding to the result of a conversion operator</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="657">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#657">657</a></td>
     <td>CD2</td>
     <td>Abstract class parameter in synthesized declaration</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="658">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#658">658</a></td>
     <td>CD2</td>
     <td>Defining <TT>reinterpret_cast</TT> for pointer types</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="659">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#659">659</a></td>
     <td>CD1</td>
     <td>Alignment of function types</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="660">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#660">660</a></td>
     <td>CD1</td>
     <td>Unnamed scoped enumerations</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="661">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#661">661</a></td>
     <td>CD1</td>
     <td>Semantics of arithmetic comparisons</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="662">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#662">662</a></td>
     <td>NAD</td>
     <td>Forming a pointer to a reference type</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="663">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#663">663</a></td>
     <td>CD1</td>
     <td>Valid Cyrillic identifier characters</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="664">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#664">664</a></td>
     <td>CD2</td>
     <td>Direct binding of references to non-class rvalue references</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="665">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#665">665</a></td>
     <td>CD2</td>
     <td>Problems in the specification of <TT>dynamic_cast</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="666">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#666">666</a></td>
     <td>CD1</td>
     <td>Dependent <I>qualified-id</I>s without the <TT>typename</TT> keyword</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="667">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#667">667</a></td>
     <td>CD2</td>
     <td>Trivial special member functions that cannot be implicitly defined</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="668">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#668">668</a></td>
     <td>CD2</td>
     <td>Throwing an exception from the destructor of a local static object</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="669">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#669">669</a></td>
     <td>NAD</td>
     <td>Confusing specification of the meaning of <TT>decltype</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="670">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#670">670</a></td>
     <td>open</td>
     <td>Copy initialization via derived-to-base conversion in the second step</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="671">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#671">671</a></td>
     <td>CD1</td>
     <td>Explicit conversion from a scoped enumeration type to integral type</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="672">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#672">672</a></td>
     <td>CD2</td>
     <td>Sequencing of initialization in <I>new-expression</I>s</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="673">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#673">673</a></td>
     <td>NAD</td>
     <td>Injection of names from <I>elaborated-type-specifier</I>s in <TT>friend</TT> declarations</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="674">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#674">674</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>&#8220;matching specialization&#8221; for a friend declaration</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="675">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#675">675</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Signedness of bit-field with typedef or template parameter type</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="676">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#676">676</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td><I>static_assert-declaration</I>s and general requirements for declarations</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="677">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#677">677</a></td>
     <td>CD1</td>
     <td>Deleted <TT>operator delete</TT> and virtual destructors</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="678">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#678">678</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Language linkage of member function parameter types and the ODR</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="679">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#679">679</a></td>
     <td>CD1</td>
     <td>Equivalence of <I>template-id</I>s and operator function templates</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="680">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#680">680</a></td>
     <td>CD2</td>
     <td>What is a move constructor?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="681">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#681">681</a></td>
     <td>CD1</td>
     <td>Restrictions on declarators with late-specified return types</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="682">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#682">682</a></td>
     <td>drafting</td>
     <td>Missing description of lookup of template aliases</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="683">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#683">683</a></td>
     <td>CD1</td>
     <td>Requirements for trivial subobject special functions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="684">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#684">684</a></td>
     <td>CD1</td>
     <td>Constant expressions involving the address of an automatic variable</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="685">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#685">685</a></td>
     <td>CD2</td>
     <td>Integral promotion of enumeration ignores fixed underlying type</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="686">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#686">686</a></td>
     <td>CD1</td>
     <td>Type declarations/definitions in <I>type-specifier-seq</I>s and <I>type-id</I>s</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="687">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#687">687</a></td>
     <td>extension</td>
     <td><TT>template</TT> keyword with <I>unqualified-id</I>s</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="688">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#688">688</a></td>
     <td>CD1</td>
     <td>Constexpr constructors and static initialization</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="689">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#689">689</a></td>
     <td>open</td>
     <td>Maximum values of signed and unsigned integers</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="690">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#690">690</a></td>
     <td>CD2</td>
     <td>The dynamic type of an rvalue reference</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="691">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#691">691</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Template parameter packs in class template partial specializations</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="692">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#692">692</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Partial ordering of variadic class template partial specializations</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="693">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#693">693</a></td>
     <td>CD2</td>
     <td>New string types and deprecated conversion</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="694">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#694">694</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Zero- and value-initialization of union objects</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="695">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#695">695</a></td>
     <td>CD2</td>
     <td>Compile-time calculation errors in constexpr functions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="696">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#696">696</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Use of block-scope constants in local classes</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="697">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#697">697</a></td>
     <td>open</td>
     <td>Deduction rules apply to more than functions</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="698">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#698">698</a></td>
     <td>open</td>
     <td>The definition of &#8220;sequenced before&#8221; is too narrow</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="699">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#699">699</a></td>
     <td>CD2</td>
     <td>Must constexpr member functions be defined in the class <I>member-specification</I>?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="700">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#700">700</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Constexpr member functions of class templates</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="701">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#701">701</a></td>
     <td>CD2</td>
     <td>When is the array-to-pointer conversion applied?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="702">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#702">702</a></td>
     <td>CD2</td>
     <td>Preferring conversion to <TT>std::initializer_list</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="703">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#703">703</a></td>
     <td>CD2</td>
     <td>Narrowing for literals that cannot be exactly represented</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="704">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#704">704</a></td>
     <td>CD2</td>
     <td>To which <I>postfix-expression</I>s does overload resolution apply?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="705">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#705">705</a></td>
     <td>CD2</td>
     <td>Suppressing argument-dependent lookup via parentheses</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="706">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#706">706</a></td>
     <td>NAD</td>
     <td>Use of <TT>auto</TT> with rvalue references</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="707">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#707">707</a></td>
     <td>CD2</td>
     <td>Undefined behavior in integral-to-floating conversions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="708">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#708">708</a></td>
     <td>open</td>
     <td>Partial specialization of member templates of class templates</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="709">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#709">709</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Enumeration names as <I>nested-name-specifier</I>s in deduction failure</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="710">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#710">710</a></td>
     <td>CD2</td>
     <td>Data races during construction</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="711">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#711">711</a></td>
     <td>CD2</td>
     <td><TT>auto</TT> with <I>braced-init-list</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="712">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#712">712</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Are integer constant operands of a <I>conditional-expression</I> &#8220;used?&#8221;</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="713">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#713">713</a></td>
     <td>CD2</td>
     <td>Unclear note about cv-qualified function types</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="714">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#714">714</a></td>
     <td>CD2</td>
     <td>Static const data members and <I>braced-init-list</I>s</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="715">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#715">715</a></td>
     <td>CD2</td>
     <td>Class member access constant expressions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="716">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#716">716</a></td>
     <td>CD2</td>
     <td>Specifications that should apply only to non-static union data members</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="717">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#717">717</a></td>
     <td>CD2</td>
     <td>Unintentional restrictions on the use of <TT>thread_local</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="718">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#718">718</a></td>
     <td>open</td>
     <td>Non-class, non-function friend declarations</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="719">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#719">719</a></td>
     <td>CD2</td>
     <td>Specifications for <I>operator-function-id</I> that should also apply to <I>literal-operator-id</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="720">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#720">720</a></td>
     <td>CD2</td>
     <td>Need examples of <I>lambda-expression</I>s</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="721">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#721">721</a></td>
     <td>CD2</td>
     <td>Where must a variable be initialized to be used in a constant expression?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="722">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#722">722</a></td>
     <td>CD2</td>
     <td>Can <TT>nullptr</TT> be passed to an ellipsis?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="726">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#726">726</a></td>
     <td>CD2</td>
     <td>Atomic and non-atomic objects in the memory model</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="727">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#727">727</a></td>
-    <td>open</td>
+    <td>drafting</td>
     <td>In-class explicit specializations</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="728">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#728">728</a></td>
     <td>extension</td>
     <td>Restrictions on local classes</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="729">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#729">729</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Qualification conversions and handlers of reference-to-pointer type</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="730">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#730">730</a></td>
     <td>CD2</td>
     <td>Explicit specializations of members of non-template classes</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="731">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#731">731</a></td>
     <td>CD2</td>
     <td>Omitted reference qualification of member function type</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="732">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#732">732</a></td>
     <td>CD2</td>
     <td>Late-specified return types in function definitions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="733">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#733">733</a></td>
     <td>NAD</td>
     <td>Reference qualification of copy assignment operators</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="734">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#734">734</a></td>
     <td>CD2</td>
     <td>Are unique addresses required for namespace-scope variables?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="735">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#735">735</a></td>
     <td>CD2</td>
     <td>Missing case in specification of safely-derived pointers</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="736">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#736">736</a></td>
     <td>NAD</td>
     <td>Is the <TT>&amp;</TT> <I>ref-qualifier</I> needed?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="737">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#737">737</a></td>
     <td>CD2</td>
     <td>Uninitialized trailing characters in string initialization</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="738">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#738">738</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td><TT>constexpr</TT> not permitted by the syntax of constructor declarations</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="739">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#739">739</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Signedness of plain bit-fields</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="740">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#740">740</a></td>
     <td>CD2</td>
     <td>Incorrect note on data races</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="741">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#741">741</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>&#8220;plain&#8221; <TT>long long</TT> bit-fields</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="742">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#742">742</a></td>
     <td>open</td>
     <td>Postfix increment/decrement with long bit-field operands</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="743">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#743">743</a></td>
     <td>CD2</td>
     <td>Use of <TT>decltype</TT> in a <I>nested-name-specifier</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="744">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#744">744</a></td>
     <td>CD2</td>
     <td>Matching template arguments with template template parameters with parameter packs</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="745">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#745">745</a></td>
     <td>open</td>
     <td>Effect of ill-formedness resulting from <TT>#error</TT></td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="746">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#746">746</a></td>
     <td>CD2</td>
     <td>Use of <TT>auto</TT> in <I>new-expression</I>s</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="747">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#747">747</a></td>
     <td>dup</td>
     <td>Access of protected base classes</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="749">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#749">749</a></td>
     <td>CD2</td>
     <td>References to function types with a <I>cv-qualifier</I> or <I>ref-qualifier</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="750">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#750">750</a></td>
     <td>CD2</td>
     <td>Implementation constraints on reference-only closure objects</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="751">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#751">751</a></td>
     <td>CD2</td>
     <td>Deriving from closure classes</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="752">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#752">752</a></td>
     <td>CD2</td>
     <td>Name lookup in nested <I>lambda-expression</I>s</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="753">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#753">753</a></td>
     <td>CD2</td>
     <td>Array names in lambda capture sets</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="754">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#754">754</a></td>
     <td>CD2</td>
     <td>Lambda expressions in default arguments of block-scope function declarations</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#755">755</a></td>
-    <td>extension</td>
+  <tr id="755">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#755">755</a></td>
+    <td>CD3</td>
     <td>Generalized <I>lambda-capture</I>s</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="756">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#756">756</a></td>
     <td>CD2</td>
     <td>Dropping cv-qualification on members of closure objects</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="757">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#757">757</a></td>
     <td>CD2</td>
     <td>Types without linkage in declarations</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="758">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#758">758</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Missing cases of declarations that are not definitions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="759">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#759">759</a></td>
     <td>CD2</td>
     <td>Destruction of closure objects</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="760">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#760">760</a></td>
     <td>CD2</td>
     <td><TT>this</TT> inside a nested class of a non-static member function</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="761">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#761">761</a></td>
     <td>CD2</td>
     <td>Inferred return type of closure object call operator</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="762">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#762">762</a></td>
     <td>CD2</td>
     <td>Name lookup in the <I>compound-statement</I> of a lambda expression</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="763">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#763">763</a></td>
     <td>CD2</td>
     <td>Is a closure object's <TT>operator()</TT> inline?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="764">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#764">764</a></td>
     <td>CD2</td>
     <td>Capturing unused variables in a lambda expression</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="765">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#765">765</a></td>
     <td>CD2</td>
     <td>Local types in inline functions with external linkage</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="766">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#766">766</a></td>
     <td>CD2</td>
     <td>Where may lambda expressions appear?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="767">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#767">767</a></td>
     <td>CD2</td>
     <td><TT>void</TT> and other unnamed <I>lambda-parameter</I>s</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="768">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#768">768</a></td>
     <td>CD2</td>
     <td>Ellipsis in a lambda parameter list</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="769">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#769">769</a></td>
     <td>CD2</td>
     <td>Initialization of closure objects</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="770">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#770">770</a></td>
     <td>CD2</td>
     <td>Ambiguity in late-specified return type</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="771">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#771">771</a></td>
     <td>CD2</td>
     <td>Move-construction of reference members of closure objects</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="772">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#772">772</a></td>
     <td>CD2</td>
     <td><I>capture-default</I> in lambdas in local default arguments</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="773">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#773">773</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Parentheses in address non-type template arguments</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="774">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#774">774</a></td>
     <td>CD2</td>
     <td>Can a closure class be a POD?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="775">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#775">775</a></td>
     <td>CD2</td>
     <td>Capturing references to functions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="776">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#776">776</a></td>
     <td>CD2</td>
     <td>Delegating constructors, destructors, and <TT>std::exit</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="777">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#777">777</a></td>
     <td>CD2</td>
     <td>Default arguments and parameter packs</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="778">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#778">778</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Template parameter packs in non-type template parameters</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="779">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#779">779</a></td>
     <td>CD2</td>
     <td>Rvalue reference members of closure objects?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="782">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#782">782</a></td>
     <td>CD2</td>
     <td>Lambda expressions and argument-dependent lookup</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="783">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#783">783</a></td>
     <td>open</td>
     <td>Definition of &#8220;argument&#8221;</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="784">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#784">784</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>List of incompatibilities with the previous Standard</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="785">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#785">785</a></td>
     <td>CD2</td>
     <td>&#8220;Execution sequence&#8221; is inappropriate phraseology</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="786">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#786">786</a></td>
     <td>CD2</td>
     <td>Definition of &#8220;thread&#8221;</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="787">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#787">787</a></td>
     <td>CD2</td>
     <td>Unnecessary lexical undefined behavior</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="788">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#788">788</a></td>
     <td>CD2</td>
     <td>Relationship between locale and values of the execution character set</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="789">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#789">789</a></td>
     <td>CD2</td>
     <td>Deprecating trigraphs</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="790">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#790">790</a></td>
     <td>CD2</td>
     <td>Concatenation of raw and non-raw string literals</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="792">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#792">792</a></td>
     <td>CD2</td>
     <td>Effects of <TT>std::quick_exit</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="793">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#793">793</a></td>
     <td>CD2</td>
     <td>Use of class members during destruction</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="794">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#794">794</a></td>
     <td>extension</td>
     <td>Base-derived conversion in member type of pointer-to-member conversion</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="795">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#795">795</a></td>
     <td>NAD</td>
     <td>Dependency of lambdas on <TT>&lt;functional&gt;</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="796">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#796">796</a></td>
     <td>CD2</td>
     <td>Lifetime of a closure object with members captured by reference</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="797">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#797">797</a></td>
     <td>CD2</td>
     <td>Converting a no-capture lambda to a function type</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="798">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#798">798</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Overloaded subscript operator described in clause 5</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="799">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#799">799</a></td>
     <td>CD2</td>
     <td>Can <TT>reinterpret_cast</TT> be used to cast an operand to its own type?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="800">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#800">800</a></td>
     <td>NAD</td>
     <td>Safely-derived pointers and object pointers converted from function pointers</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="801">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#801">801</a></td>
     <td>CD2</td>
     <td>Casting away constness in a cast to rvalue reference type</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="803">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#803">803</a></td>
     <td>CD2</td>
     <td><TT>sizeof</TT> an enumeration type with a fixed underlying type</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="804">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#804">804</a></td>
     <td>CD2</td>
     <td>Deducing the type in <TT>new auto(x)</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="805">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#805">805</a></td>
     <td>CD2</td>
     <td>Which exception to throw for overflow in array size calculation</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="806">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#806">806</a></td>
     <td>CD2</td>
     <td>Enumeration types in integral constant expressions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="807">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#807">807</a></td>
     <td>NAD</td>
     <td><TT>typeid</TT> expressions in constant expressions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="808">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#808">808</a></td>
     <td>CD2</td>
     <td>Non-type <I>decl-specifier</I>s versus max-munch</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="809">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#809">809</a></td>
     <td>CD2</td>
     <td>Deprecation of the <TT>register</TT> keyword</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="810">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#810">810</a></td>
     <td>CD2</td>
     <td>Block-scope <TT>thread_local</TT> variables should be implicitly <TT>static</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="811">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#811">811</a></td>
     <td>CD2</td>
     <td>Unclear implications of const-qualification</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="812">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#812">812</a></td>
     <td>CD2</td>
     <td>Duplicate names in inline namespaces</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="813">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#813">813</a></td>
     <td>open</td>
     <td><TT>typename</TT> in a <I>using-declaration</I> with a non-dependent name</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="814">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#814">814</a></td>
     <td>CD2</td>
     <td>Attribute to indicate that a function throws nothing</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="815">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#815">815</a></td>
     <td>CD2</td>
     <td>Parameter pack expansion inside attributes</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="816">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#816">816</a></td>
     <td>CD2</td>
     <td>Diagnosing violations of <TT>[[final]]</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="817">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#817">817</a></td>
     <td>CD2</td>
     <td>Meaning of <TT>[[final]]</TT> applied to a class definition</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="818">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#818">818</a></td>
     <td>CD2</td>
     <td>Function parameter packs in non-final positions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="819">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#819">819</a></td>
     <td>NAD</td>
     <td>Access control and deleted implicitly-declared special member functions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="820">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#820">820</a></td>
     <td>CD2</td>
     <td>Deprecation of <TT>export</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="822">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#822">822</a></td>
     <td>extension</td>
     <td>Additional contexts for template aliases</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="823">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#823">823</a></td>
     <td>CD2</td>
     <td>Literal types with constexpr conversions as non-type template arguments</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="828">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#828">828</a></td>
     <td>CD2</td>
     <td>Destruction of exception objects</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="829">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#829">829</a></td>
     <td>NAD</td>
     <td>At what point is <TT>std::unexpected</TT> called?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="830">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#830">830</a></td>
     <td>CD2</td>
     <td>Deprecating exception specifications</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="831">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#831">831</a></td>
     <td>CD2</td>
     <td>Limit on recursively nested template instantiations</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="832">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#832">832</a></td>
     <td>CD2</td>
     <td>Value of preprocessing numbers</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="833">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#833">833</a></td>
     <td>CD2</td>
     <td>Explicit conversion of a scoped enumeration value to a floating type</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="834">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#834">834</a></td>
     <td>CD2</td>
     <td>What is an &#8220;ordinary string literal&#8221;?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="835">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#835">835</a></td>
     <td>CD2</td>
     <td>Scoped enumerations and the &#8220;usual arithmetic conversions&#8221;</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="836">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#836">836</a></td>
     <td>NAD</td>
     <td><TT>[[noreturn]]</TT> applied to function types</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="837">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#837">837</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Constexpr functions and <TT>return</TT> <I>braced-init-list</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="838">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#838">838</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Use of <TT>this</TT> in a <I>brace-or-equal-initializer</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="839">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#839">839</a></td>
     <td>dup</td>
     <td><TT>sizeof</TT> with opaque enumerations</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="840">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#840">840</a></td>
     <td>CD2</td>
     <td>Rvalue references as nontype template parameters</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="842">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#842">842</a></td>
     <td>CD2</td>
     <td>Casting to rvalue reference type</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="845">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#845">845</a></td>
     <td>CD2</td>
     <td>What is the &#8220;first declaration&#8221; of an explicit specialization?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="846">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#846">846</a></td>
     <td>CD2</td>
     <td>Rvalue references to functions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="847">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#847">847</a></td>
     <td>CD2</td>
     <td>Error in rvalue reference deduction example</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="850">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#850">850</a></td>
     <td>CD2</td>
     <td>Restrictions on use of non-static data members</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="852">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#852">852</a></td>
     <td>open</td>
     <td><I>using-declaration</I>s and dependent base classes</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="853">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#853">853</a></td>
     <td>CD2</td>
     <td>Support for relaxed pointer safety</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="854">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#854">854</a></td>
     <td>CD2</td>
     <td>Left shift and unsigned extended types</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="855">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#855">855</a></td>
     <td>CD2</td>
     <td>Incorrect comments in <I>braced-init-list</I> assignment example</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="858">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#858">858</a></td>
     <td>CD2</td>
     <td>Example binding an rvalue reference to an lvalue</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="860">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#860">860</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Explicit qualification of constexpr member functions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="861">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#861">861</a></td>
     <td>CD2</td>
     <td>Unintended ambiguity in inline namespace lookup</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="862">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#862">862</a></td>
     <td>CD2</td>
     <td>Undefined behavior with enumerator value overflow</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="863">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#863">863</a></td>
     <td>CD2</td>
     <td>Rvalue reference cast to incomplete type</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="864">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#864">864</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td><I>braced-init-list</I> in the range-based <TT>for</TT> statement</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="865">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#865">865</a></td>
     <td>CD2</td>
     <td>Initializing a <TT>std::initializer_list</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="869">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#869">869</a></td>
     <td>CD2</td>
     <td>Uninitialized <TT>thread_local</TT> objects</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="872">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#872">872</a></td>
     <td>CD2</td>
     <td>Lexical issues with raw strings</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="873">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#873">873</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Deducing rvalue references in declarative contexts</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="874">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#874">874</a></td>
     <td>CD2</td>
     <td>Class-scope definitions of enumeration types</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="876">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#876">876</a></td>
     <td>CD2</td>
     <td>Type references in rvalue reference deduction specification</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="877">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#877">877</a></td>
     <td>CD2</td>
     <td>Viable functions and binding references to rvalues</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="879">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#879">879</a></td>
     <td>CD2</td>
     <td>Missing built-in comparison operators for pointer types</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="880">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#880">880</a></td>
     <td>CD2</td>
     <td>Built-in conditional operator for scoped enumerations</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="882">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#882">882</a></td>
     <td>CD2</td>
     <td>Defining <TT>main</TT> as deleted</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="883">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#883">883</a></td>
     <td>CD2</td>
     <td><TT>std::memcpy</TT> vs <TT>std::memmove</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="884">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#884">884</a></td>
     <td>CD2</td>
     <td>Defining an explicitly-specialized static data member</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="885">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#885">885</a></td>
     <td>NAD</td>
     <td>Partial ordering of function templates with unordered parameter pairs</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="886">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#886">886</a></td>
     <td>CD2</td>
     <td>Member initializers and aggregates</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="887">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#887">887</a></td>
     <td>CD2</td>
     <td>Move construction of thrown object</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="888">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#888">888</a></td>
     <td>CD2</td>
     <td>Union member initializers</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="891">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#891">891</a></td>
     <td>CD2</td>
     <td><TT>const_cast</TT> to rvalue reference from objectless rvalue</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="892">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#892">892</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Missing requirements for constexpr constructors</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="893">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#893">893</a></td>
     <td>NAD</td>
     <td>Brace syntax for <I>enumerator-definition</I>s</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="896">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#896">896</a></td>
     <td>CD2</td>
     <td>Rvalue references and rvalue-reference conversion functions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="897">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#897">897</a></td>
     <td>open</td>
     <td><TT>_Pragma</TT> and extended <I>string-literal</I>s</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="898">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#898">898</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Declarations in constexpr functions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="899">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#899">899</a></td>
     <td>CD2</td>
     <td>Explicit conversion functions in direct class initialization</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="900">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#900">900</a></td>
     <td>NAD</td>
     <td>Lifetime of temporaries in range-based <TT>for</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="901">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#901">901</a></td>
     <td>drafting</td>
     <td>Deleted <TT>operator delete</TT></td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="902">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#902">902</a></td>
     <td>NAD</td>
     <td>In-class initialization of non-constant static data members</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="903">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#903">903</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Value-dependent integral null pointer constants</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="904">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#904">904</a></td>
     <td>CD2</td>
     <td>Parameter packs in <I>lambda-capture</I>s</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="905">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#905">905</a></td>
     <td>CD2</td>
     <td>Explicit defaulted copy constructors and trivial copyability</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="906">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#906">906</a></td>
     <td>CD2</td>
     <td>Which special member functions can be defaulted?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="908">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#908">908</a></td>
     <td>CD2</td>
     <td>Deleted global allocation and deallocation functions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="909">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#909">909</a></td>
     <td>NAD</td>
     <td>Old-style casts with conversion functions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="910">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#910">910</a></td>
     <td>CD2</td>
     <td>Move constructors and implicitly-declared copy constructors</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="912">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#912">912</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Character literals and <I>universal-character-name</I>s</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="913">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#913">913</a></td>
     <td>CD2</td>
     <td>Deduction rules for array- and function-type conversion functions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="914">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#914">914</a></td>
     <td>extension</td>
     <td>Value-initialization of array types</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="915">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#915">915</a></td>
     <td>CD2</td>
     <td>Deleted specializations of member function templates</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="916">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#916">916</a></td>
     <td>open</td>
     <td>Does a reference type have a destructor?</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="919">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#919">919</a></td>
     <td>CD2</td>
     <td>Contradictions regarding inline namespaces</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="920">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#920">920</a></td>
     <td>CD2</td>
     <td>Interaction of inline namespaces and <I>using-declaration</I>s</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="921">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#921">921</a></td>
     <td>CD2</td>
     <td>Unclear specification of inline namespaces</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="922">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#922">922</a></td>
     <td>CD2</td>
     <td>Implicit default constructor definitions and <TT>const</TT> variant members</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="923">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#923">923</a></td>
     <td>CD2</td>
     <td>Inline explicit specializations</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="924">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#924">924</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td><I>alias-declaration</I> as a class member</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="925">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#925">925</a></td>
     <td>open</td>
     <td>Type of character literals in preprocessor expressions</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="926">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#926">926</a></td>
     <td>CD2</td>
     <td>Inline unnamed namespaces</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="927">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#927">927</a></td>
     <td>CD2</td>
     <td>Implicitly-deleted default constructors and member initializers</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="928">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#928">928</a></td>
     <td>CD2</td>
     <td>Defaulting a function that would be implicitly defined as deleted</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="929">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#929">929</a></td>
     <td>CD2</td>
     <td>What is a template alias?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="930">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#930">930</a></td>
     <td>CD2</td>
     <td><TT>alignof</TT> with incomplete array type</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="931">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#931">931</a></td>
     <td>CD2</td>
     <td>Confusing reference to the length of a user-defined string literal</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="932">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#932">932</a></td>
     <td>CD2</td>
     <td>UCNs in closing delimiters of raw string literals</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="933">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#933">933</a></td>
     <td>CD2</td>
     <td>32-bit UCNs with 16-bit <TT>wchar_t</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="934">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#934">934</a></td>
     <td>CD2</td>
     <td>List-initialization of references</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="935">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#935">935</a></td>
     <td>CD2</td>
     <td>Missing overloads for character types for user-defined literals</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="936">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#936">936</a></td>
     <td>CD2</td>
     <td>Array initialization with new string literals</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="937">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#937">937</a></td>
     <td>NAD</td>
     <td>Restrictions on values of template arguments in user-defined literals</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="938">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#938">938</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Initializer lists and array new</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="939">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#939">939</a></td>
     <td>CD2</td>
     <td>Explicitly checking virtual function overriding</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="940">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#940">940</a></td>
     <td>CD2</td>
     <td>Global anonymous unions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="941">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#941">941</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Explicit specialization of deleted function template</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="942">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#942">942</a></td>
     <td>CD2</td>
     <td>Is <TT>this</TT> an entity?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="943">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#943">943</a></td>
     <td>open</td>
     <td>Is <TT>T()</TT> a temporary?</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="944">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#944">944</a></td>
     <td>open</td>
     <td><TT>reinterpret_cast</TT> for all types with the same size and alignment</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="945">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#945">945</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Use of <TT>this</TT> in a late-specified return type</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="946">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#946">946</a></td>
     <td>CD2</td>
     <td>Order of destruction of local static objects and calls to <TT>std::atexit</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr id="947">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#947">947</a></td>
-    <td>extension</td>
+    <td>NAD</td>
     <td>Deducing type template arguments from default function arguments</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="948">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#948">948</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td><TT>constexpr</TT> in <I>condition</I>s</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="949">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#949">949</a></td>
     <td>open</td>
     <td>Requirements for freestanding implementations</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="950">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#950">950</a></td>
     <td>CD2</td>
     <td>Use of <TT>decltype</TT> as a <I>class-name</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="951">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#951">951</a></td>
     <td>CD2</td>
     <td>Problems with <I>attribute-specifier</I>s</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="952">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#952">952</a></td>
     <td>drafting</td>
     <td>Insufficient description of &#8220;naming class&#8221;</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="953">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#953">953</a></td>
     <td>CD2</td>
     <td>Rvalue references and function viability</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="954">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#954">954</a></td>
     <td>open</td>
     <td>Overload resolution of conversion operator templates with built-in types</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="955">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#955">955</a></td>
     <td>CD2</td>
     <td>Can a closure type's <TT>operator()</TT> be virtual?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="956">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#956">956</a></td>
     <td>CD2</td>
     <td>Function prototype scope with late-specified return types</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="957">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#957">957</a></td>
     <td>CD2</td>
     <td>Alternative tokens and <I>attribute-token</I>s</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="958">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#958">958</a></td>
     <td>NAD</td>
     <td>Lambdas and <TT>decltype</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="959">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#959">959</a></td>
     <td>CD2</td>
     <td>Alignment attribute for class and enumeration types</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="960">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#960">960</a></td>
     <td>CD2</td>
     <td>Covariant functions and lvalue/rvalue references</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="961">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#961">961</a></td>
     <td>CD2</td>
     <td>Overload resolution and conversion of <TT>std::nullptr_t</TT> to <TT>bool</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="962">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#962">962</a></td>
     <td>CD2</td>
     <td>Attributes appertaining to class and enum types</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="963">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#963">963</a></td>
     <td>CD2</td>
     <td>Comparing <TT>nullptr</TT> with 0</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="964">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#964">964</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Incorrect description of when the lvalue-to-rvalue conversion applies</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="965">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#965">965</a></td>
     <td>CD2</td>
     <td>Limiting the applicability of the <TT>carries_dependency</TT> attribute</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="966">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#966">966</a></td>
     <td>CD2</td>
     <td>Nested types without linkage</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="967">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#967">967</a></td>
     <td>open</td>
     <td>Exception specification of replacement allocation function</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="968">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#968">968</a></td>
     <td>CD2</td>
     <td>Syntactic ambiguity of the attribute notation</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="969">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#969">969</a></td>
     <td>CD2</td>
     <td>Explicit instantiation declarations of class template specializations</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="970">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#970">970</a></td>
     <td>CD2</td>
     <td>Consistent use of &#8220;appertain&#8221; and &#8220;apply&#8221;</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="971">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#971">971</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Incorrect treatment of <I>exception-declaration</I>s</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="972">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#972">972</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Allowing multiple <I>attribute-specifier</I>s</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="973">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#973">973</a></td>
     <td>CD2</td>
     <td>Function types in <I>exception-specification</I>s</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="974">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#974">974</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Default arguments for lambdas</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="975">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#975">975</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Restrictions on return type deduction for lambdas</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="976">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#976">976</a></td>
     <td>CD2</td>
     <td>Deduction for <TT>const T&amp;</TT> conversion operators</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="977">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#977">977</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>When is an enumeration type complete?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="978">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#978">978</a></td>
     <td>CD2</td>
     <td>Incorrect specification for copy initialization</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="979">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#979">979</a></td>
     <td>CD2</td>
     <td>Position of <I>attribute-specifier</I> in declarator syntax</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="980">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#980">980</a></td>
     <td>CD2</td>
     <td>Explicit instantiation of a member of a class template</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="981">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#981">981</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Constexpr constructor templates and literal types</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="982">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#982">982</a></td>
     <td>NAD</td>
     <td>Initialization with an empty initializer list</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="983">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#983">983</a></td>
     <td>CD2</td>
     <td>Ambiguous pointer-to-member constant</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="984">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#984">984</a></td>
     <td>CD2</td>
     <td>&#8220;Deduced type&#8221; is unclear in <TT>auto</TT> type deduction</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="985">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#985">985</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Alternative tokens and user-defined literals</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="986">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#986">986</a></td>
     <td>CD2</td>
     <td>Transitivity of <I>using-directive</I>s versus qualified lookup</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="987">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#987">987</a></td>
     <td>open</td>
     <td>Which declarations introduce namespace members?</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="988">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#988">988</a></td>
     <td>CD2</td>
     <td>Reference-to-reference collapsing with <TT>decltype</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="989">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#989">989</a></td>
     <td>CD2</td>
     <td>Misplaced list-initialization example</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="990">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#990">990</a></td>
     <td>CD2</td>
     <td>Value initialization with multiple initializer-list constructors</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="svn" align="center">SVN</td>
   </tr>
-  <tr>
+  <tr id="991">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#991">991</a></td>
     <td>CD2</td>
     <td>Reference parameters of constexpr functions and constructors</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="992">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#992">992</a></td>
     <td>NAD</td>
     <td>Inheriting explicitness</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="993">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#993">993</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Freedom to perform instantiation at the end of the translation unit</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="994">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#994">994</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td><I>braced-init-list</I> as a default argument</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="995">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#995">995</a></td>
     <td>CD2</td>
     <td>Incorrect example for <I>using-declaration</I> and explicit instantiation</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="996">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#996">996</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Ambiguous partial specializations of member class templates</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="997">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#997">997</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Argument-dependent lookup and dependent function template parameter types</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="998">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#998">998</a></td>
     <td>dup</td>
     <td>Function parameter transformations and template functions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="999">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#999">999</a></td>
     <td>CD2</td>
     <td>&#8220;Implicit&#8221; or &#8220;implied&#8221; object argument/parameter?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1000">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1000">1000</a></td>
     <td>CD2</td>
     <td>Mistaking member typedefs for constructors</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1001">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1001">1001</a></td>
     <td>drafting</td>
     <td>Parameter type adjustment in dependent parameter types</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1002">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1002">1002</a></td>
     <td>NAD</td>
     <td>Pack expansion for function arguments</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1003">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1003">1003</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Acceptable definitions of <TT>main</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1004">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1004">1004</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Injected-class-names as arguments for template template parameters</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1005">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1005">1005</a></td>
     <td>NAD</td>
     <td>Qualified name resolution in member functions of class templates</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1006">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1006">1006</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td><TT>std::nullptr_t</TT> as a non-type template parameter</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1007">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1007">1007</a></td>
     <td>NAD</td>
     <td>Protected access and pointers to members</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1008">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1008">1008</a></td>
     <td>extension</td>
     <td>Querying the alignment of an object</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1009">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1009">1009</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Missing cases in the <I>declarator-id</I> of a function template declaration</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1010">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1010">1010</a></td>
     <td>CD2</td>
     <td>Address of object with dynamic storage duration in constant expression</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1011">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1011">1011</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Standard conversions that cannot be inverted</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1012">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1012">1012</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Undeprecating <TT>static</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1013">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1013">1013</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Uninitialized <TT>std::nullptr_t</TT> objects</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1014">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1014">1014</a></td>
     <td>NAD</td>
     <td>Overload resolution between <TT>const T&amp;</TT> and <TT>T&amp;&amp;</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1015">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1015">1015</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Template arguments and argument-dependent lookup</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1016">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1016">1016</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Overloadable declarations, function templates, and references</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1017">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1017">1017</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Member access transformation in unevaluated operands</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1018">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1018">1018</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Ambiguity between <I>simple-declaration</I> and <I>attribute-declaration</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1019">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1019">1019</a></td>
     <td>dup</td>
     <td>Dependent <I>simple-template-id</I>s in <I>base-specifier</I>s and <I>mem-initializer</I>s</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1020">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1020">1020</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Implicitly-defined copy constructors and explicit base class constructors</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1021">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1021">1021</a></td>
-    <td>open</td>
+    <td>drafting</td>
     <td>Definitions of namespace members</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1022">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1022">1022</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Can an enumeration variable have values outside the values of the enumeration?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1023">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1023">1023</a></td>
     <td>dup</td>
     <td><TT>thread_local</TT> objects as non-type template arguments</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1024">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1024">1024</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Limits on multicharacter literals</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1025">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1025">1025</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Use of a reference as a non-type template argument</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1026">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1026">1026</a></td>
     <td>NAD</td>
     <td>Cv-qualified non-class rvalues</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1027">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1027">1027</a></td>
     <td>drafting</td>
     <td>Type consistency and reallocation of scalar types</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1028">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1028">1028</a></td>
     <td>open</td>
     <td>Dependent names in non-defining declarations</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1029">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1029">1029</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Type of a destructor call</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1030">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1030">1030</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Evaluation order in <I>initializer-list</I>s used in aggregate initialization</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1031">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1031">1031</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Optional elements in attributes</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1032">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1032">1032</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Empty pack expansions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1033">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1033">1033</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Restrictions on alignment attributes</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1034">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1034">1034</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Attributes for <TT>return</TT> statements in lambdas</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1035">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1035">1035</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Omitted and required <I>decl-specifier</I>s</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1036">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1036">1036</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Alignment attribute in an <I>exception-declaration</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1037">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1037">1037</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Requirements for operands of <I>delete-expression</I>s and deallocation functions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1038">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1038">1038</a></td>
     <td>open</td>
     <td>Overload resolution of <TT>&amp;x.static_func</TT></td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1039">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1039">1039</a></td>
     <td>dup</td>
     <td>Coordinating C and C++ alignment specifications</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1040">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1040">1040</a></td>
     <td>NAD</td>
     <td>Memory model issues</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1041">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1041">1041</a></td>
     <td>dup</td>
     <td><I>alias-declaration</I>s as class members</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1042">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1042">1042</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Attributes in <I>alias-declaration</I>s</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1043">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1043">1043</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Qualified name lookup in the current instantiation</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1044">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1044">1044</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Point of declaration for an <I>alias-declaration</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1045">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1045">1045</a></td>
     <td>NAD</td>
     <td>Requiring explicit instantiation declarations</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1046">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1046">1046</a></td>
     <td>open</td>
     <td>What is a &#8220;use&#8221; of a class specialization?</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1047">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1047">1047</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>When is <TT>typeid</TT> value-dependent?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1048">1048</a></td>
-    <td>extension</td>
+  <tr class="open" id="1048">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1048">1048</a></td>
+    <td>open</td>
     <td><TT>auto</TT> deduction and lambda return type deduction.</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1049">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1049">1049</a></td>
     <td>open</td>
     <td>Copy elision through reference parameters of inline functions</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1050">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1050">1050</a></td>
     <td>NAD</td>
     <td>Effects of thread support on object lifetime</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1051">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1051">1051</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Reference members and generated copy constructors</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1052">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1052">1052</a></td>
     <td>dup</td>
     <td><TT>const</TT> non-static data member and PODness</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1053">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1053">1053</a></td>
     <td>NAD</td>
     <td>Terminate vs undefined behavior for noexcept violation</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1054">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1054">1054</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Lvalue-to-rvalue conversions in expression statements</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1055">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1055">1055</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Permissible uses of <TT>void</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1056">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1056">1056</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Template aliases, member definitions, and the current instantiation</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1057">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1057">1057</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td><TT>decltype</TT> and the current instantiation</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1058">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1058">1058</a></td>
     <td>NAD</td>
     <td>Reference binding of incompatible array types</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1059">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1059">1059</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Cv-qualified array types (with rvalues)</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1060">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1060">1060</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Scoped enumerators in integral constant expressions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1061">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1061">1061</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Negative array bounds in a <I>new-expression</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1062">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1062">1062</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Syntax of <I>attribute-specifier</I>s in lambdas</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1063">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1063">1063</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td><TT>[[hiding]]</TT> with non-attribute declarations</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1064">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1064">1064</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Defaulted move constructor for a union</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1065">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1065">1065</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td><TT>[[hiding]]</TT> with <TT>[[override]]</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1066">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1066">1066</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>When is a copy/move assignment operator implicitly defined?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1067">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1067">1067</a></td>
     <td>NAD</td>
     <td><TT>[[hiding]]</TT>, <I>using-declaration</I>s, and multiple inheritance</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1068">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1068">1068</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Template aliases with default arguments and template parameter packs</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1069">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1069">1069</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Incorrect function type with <I>trailing-return-type</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1070">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1070">1070</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Missing initializer clauses in aggregate initialization</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="svn" align="center">SVN</td>
   </tr>
-  <tr>
+  <tr id="1071">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1071">1071</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Literal class types and trivial default constructors</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1072">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1072">1072</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Scoped enumerator with the same name as its containing class</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1073">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1073">1073</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Merging <I>dynamic-exception-specification</I>s and <I>noexcept-specification</I>s</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1074">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1074">1074</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Value-dependent <I>noexcept-expression</I>s</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1075">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1075">1075</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Grammar does not allow template alias in <I>type-name</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1076">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1076">1076</a></td>
     <td>open</td>
     <td>Value categories and lvalue temporaries</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1077">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1077">1077</a></td>
     <td>extension</td>
     <td>Explicit specializations in non-containing namespaces</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1078">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1078">1078</a></td>
     <td>NAD</td>
     <td>Narrowing and the usual arithmetic conversions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1079">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1079">1079</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Overload resolution involving aggregate initialization</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1080">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1080">1080</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Confusing relationship between templates and copy constructors</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1081">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1081">1081</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Defaulted destructor and unusable operator delete</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1082">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1082">1082</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Implicit copy function if subobject has none?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1083">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1083">1083</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Passing an object to ellipsis with non-trivial move constructor</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1084">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1084">1084</a></td>
     <td>NAD</td>
     <td>Conditions for a deleted move function</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1085">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1085">1085</a></td>
     <td>NAD</td>
     <td>Move assignment operators and virtual bases</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1086">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1086">1086</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td><TT>const_cast</TT> to rvalue reference to function type</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1087">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1087">1087</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Additional applications of issue 899</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1088">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1088">1088</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Dependent non-type template arguments</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1089">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1089">1089</a></td>
     <td>drafting</td>
     <td>Template parameters in member selections</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1090">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1090">1090</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Alignment of subobjects</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1091">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1091">1091</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Inconsistent use of the term &#8220;object expression&#8221;</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1092">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1092">1092</a></td>
     <td>drafting</td>
     <td>Cycles in overload resolution during instantiation</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1093">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1093">1093</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Value-initializing non-objects</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1094">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1094">1094</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Converting floating-point values to scoped enumeration types</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1095">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1095">1095</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>List-initialization of references</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1096">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1096">1096</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Missing requirement for template definitions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1097">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1097">1097</a></td>
     <td>NAD</td>
     <td>Aggregate initialization of function parameters</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1098">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1098">1098</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Pointer conversions in constant expressions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1099">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1099">1099</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Infinite recursion in <TT>constexpr</TT> functions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1100">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1100">1100</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td><TT>constexpr</TT> conversion functions and non-type template arguments</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1101">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1101">1101</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Non-integral initialized static data members</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1102">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1102">1102</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Better example of undefined behavior</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1103">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1103">1103</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Reversion of phase 1 and 2 transformations in raw string literals</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1104">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1104">1104</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Global-scope template arguments vs the <TT>&lt;:</TT> digraph</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1105">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1105">1105</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Issues relating to TR 10176:2003</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1106">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1106">1106</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Need more detail in <TT>nullptr</TT> keyword description</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1107">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1107">1107</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Overload resolution for user-defined integer literals</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1108">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1108">1108</a></td>
     <td>NAD</td>
     <td>User-defined literals have not been implemented</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1109">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1109">1109</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>When is &#8220;use&#8221; a reference to the ODR meaning?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1110">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1110">1110</a></td>
     <td>NAD</td>
     <td>Incomplete return type should be allowed in <TT>decltype</TT> operand</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1111">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1111">1111</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Remove dual-scope lookup of member template names</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1112">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1112">1112</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td><TT>constexpr</TT> variables should have internal linkage like <TT>const</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1113">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1113">1113</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Linkage of namespace member of unnamed namespace</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1114">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1114">1114</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Incorrect use of placement <TT>new</TT> in example</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1115">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1115">1115</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>C-compatible alignment specification</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <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>
     <td>Aliasing of union members</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1117">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1117">1117</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Incorrect note about xvalue member access expressions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1118">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1118">1118</a></td>
     <td>NAD</td>
     <td>Implicit lambda capture via explicit copy constructor</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1119">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1119">1119</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Missing case in description of member access ambiguity</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1120">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1120">1120</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td><TT>reinterpret_cast</TT> and <TT>void*</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1121">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1121">1121</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Unnecessary ambiguity error in formation of pointer to member</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1122">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1122">1122</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Circular definition of <TT>std::size_t</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1123">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1123">1123</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Destructors should be <TT>noexcept</TT> by default</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1124">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1124">1124</a></td>
     <td>NAD</td>
     <td>Error in description of value category of pointer-to-member expression</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1125">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1125">1125</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Unclear definition of &#8220;potential constant expression&#8221;</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1126">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1126">1126</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td><TT>constexpr</TT> functions in <TT>const</TT> initializers</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1127">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1127">1127</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Overload resolution in <TT>constexpr</TT> functions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1128">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1128">1128</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td><I>attribute-specifier</I>s in <I>decl-specifier-seq</I>s</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1129">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1129">1129</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Default <TT>nothrow</TT> for <TT>constexpr</TT> functions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1130">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1130">1130</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Function parameter type adjustments and <TT>decltype</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1131">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1131">1131</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Template aliases in <I>elaborated-type-specifier</I>s</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1132">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1132">1132</a></td>
     <td>NAD</td>
     <td>Keyword vs attribute for <TT>noreturn</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1133">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1133">1133</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Keywords vs attributes for control of hiding and overriding</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1134">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1134">1134</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>When is an explicitly-defaulted function defined?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1135">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1135">1135</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Explicitly-defaulted non-public special member functions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1136">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1136">1136</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Explicitly-defaulted explicit constructors</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1137">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1137">1137</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Explicitly-defaulted virtual special member functions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1138">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1138">1138</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Rvalue-ness check for rvalue reference binding is wrong</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1139">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1139">1139</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Rvalue reference binding to scalar xvalues</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1140">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1140">1140</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Incorrect redefinition of POD class</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1141">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1141">1141</a></td>
     <td>NAD</td>
     <td>Non-static data member initializers have not been implemented</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1142">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1142">1142</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td><TT>friend</TT> declaration of member function of containing class</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1143">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1143">1143</a></td>
     <td>NAD</td>
     <td>Move semantics for <TT>*this</TT> have not been implemented</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1144">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1144">1144</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Remove access declarations</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1145">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1145">1145</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Defaulting and triviality</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1146">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1146">1146</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td><I>exception-specification</I>s of defaulted functions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1147">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1147">1147</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Destructors should be default <TT>nothrow</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1148">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1148">1148</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Copy elision and move construction of function parameters</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1149">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1149">1149</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Trivial non-public copy operators in subobjects</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1150">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1150">1150</a></td>
     <td>NAD</td>
     <td>Inheriting constructors have not been implemented</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1151">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1151">1151</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Overload resolution with initializer-list and non-list constructors</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1152">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1152">1152</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Rules for determining existence of implicit conversion sequence</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1153">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1153">1153</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Type matching in address of overloaded function</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1154">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1154">1154</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Address of <TT>thread_local</TT> variable as non-type template argument</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1155">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1155">1155</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Internal-linkage non-type template arguments</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1156">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1156">1156</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Partial ordering in a non-call context</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1157">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1157">1157</a></td>
     <td>open</td>
     <td>Partial ordering of function templates is still underspecified</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1158">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1158">1158</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Recursive instantiation via alias template</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1159">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1159">1159</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Class and enumeration definitions in template aliases</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1160">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1160">1160</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Definitions of template members and the current instantiation</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1161">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1161">1161</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Dependent <I>nested-name-specifier</I> in a pointer-to-member declarator</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1162">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1162">1162</a></td>
     <td>NAD</td>
     <td>Dependent <I>elaborated-type-specifier</I>s in non-deduced contexts</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1163">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1163">1163</a></td>
     <td>NAD</td>
     <td><TT>extern template</TT> prevents inlining functions not marked <TT>inline</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1164">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1164">1164</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Partial ordering of <TT>f(T&amp;)</TT> and <TT>f(T&amp;&amp;)</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1165">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1165">1165</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Exceptions when destroying array elements</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1166">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1166">1166</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td><I>exception-declaration</I>s that do not declare objects</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1167">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1167">1167</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td><I>function-try-block</I>s for destructors</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1168">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1168">1168</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Additional reasons to call <TT>std::terminate</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1169">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1169">1169</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Missing feature macro for strict pointer safety</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1170">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1170">1170</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Access checking during template argument deduction</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1171">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1171">1171</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Partial stack unwinding with <TT>noexcept</TT> violation</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1172">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1172">1172</a></td>
     <td>drafting</td>
     <td>&#8220;instantiation-dependent&#8221; constructs</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1173">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1173">1173</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Unclear specification of effects of signal handling</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1174">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1174">1174</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>When is a pure virtual function &#8220;used?&#8221;</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1175">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1175">1175</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Disambiguating user-defined literals</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1176">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1176">1176</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Definition of release sequence</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1177">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1177">1177</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Intra-thread dependency-ordered-before</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1178">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1178">1178</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Deduction failure matching placement new</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1179">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1179">1179</a></td>
     <td>NAD</td>
     <td>Cv-qualification of non-type template parameters</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1180">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1180">1180</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Over-aligned class types</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1181">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1181">1181</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>What is a &#8220;built-in type?&#8221;</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1182">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1182">1182</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Incorrect description of pack expansion syntax</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1183">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1183">1183</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Expansion of parameter packs in declarators</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1184">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1184">1184</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Argument conversions to nondeduced parameter types</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1185">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1185">1185</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Misleading description of language linkage and member function types</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1186">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1186">1186</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Non-dependent <TT>constexpr</TT> violations in function templates</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1187">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1187">1187</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Problems in initialization example</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1188">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1188">1188</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Type punning in constant expressions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1189">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1189">1189</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Address of distinct base class subobjects</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1190">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1190">1190</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Operations on non-safely-derived pointers</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1191">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1191">1191</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Deleted subobject destructors and implicitly-defined constructors</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1192">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1192">1192</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Inadvertent change to ODR and templates</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1193">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1193">1193</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Use of address-constant pointers in constant expressions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1194">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1194">1194</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Constexpr references</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1195">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1195">1195</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>References to non-literal types in constexpr functions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1196">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1196">1196</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Definition required for explicit instantiation after explicit specialization?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1197">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1197">1197</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Constexpr arrays</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1198">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1198">1198</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Literal types and copy constructors</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1199">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1199">1199</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Deleted constexpr functions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1200">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1200">1200</a></td>
     <td>open</td>
     <td>Lookup rules for template parameters</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1201">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1201">1201</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Are deleted and defaulted functions definitions?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1202">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1202">1202</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Calling virtual functions during destruction</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1203">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1203">1203</a></td>
     <td>dup</td>
     <td>Misleading note regarding initialized static data members</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1204">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1204">1204</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Specifiers in a <I>for-range-declaration</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1205">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1205">1205</a></td>
     <td>dup</td>
     <td>Lvalue reference binding and function viability</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1206">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1206">1206</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Defining opaque enumeration members of class templates</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1207">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1207">1207</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Type of class member in <I>trailing-return-type</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1208">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1208">1208</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Explicit <TT>noexcept</TT> in defaulted definition</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1209">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1209">1209</a></td>
     <td>open</td>
     <td>Is a potentially-evaluated expression in a template definition a &#8220;use?&#8221;</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1210">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1210">1210</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Injection of <I>elaborated-type-specifier</I> in enumeration scope</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1211">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1211">1211</a></td>
     <td>drafting</td>
     <td>Misaligned lvalues</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1212">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1212">1212</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Non-function-call xvalues and <TT>decltype</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1213">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1213">1213</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Array subscripting and xvalues</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1214">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1214">1214</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Kinds of initializers</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1215">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1215">1215</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Definition of POD struct</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1216">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1216">1216</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Exceptions &#8220;allowed&#8221; by a <I>noexcept-specification</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1217">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1217">1217</a></td>
     <td>NAD</td>
     <td>Are deleted functions implicitly <TT>noexcept</TT>?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1218">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1218">1218</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>What is the &#8220;currently-handled exception&#8221; in a multi-threaded program?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1219">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1219">1219</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Non-static data member initializers in constant expressions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1220">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1220">1220</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Looking up <I>conversion-type-id</I>s</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1221">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1221">1221</a></td>
     <td>open</td>
     <td>Partial ordering and reference collapsing</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1222">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1222">1222</a></td>
     <td>NAD</td>
     <td>Unnecessary restriction on <TT>auto</TT> array types</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1223">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1223">1223</a></td>
     <td>drafting</td>
     <td>Syntactic disambiguation and <I>trailing-return-type</I>s</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1224">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1224">1224</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td><TT>constexpr</TT> defaulted copy constructors</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1225">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1225">1225</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td><TT>constexpr</TT> constructors and virtual bases</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1226">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1226">1226</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Converting a <I>braced-init-list</I> default argument</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1227">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1227">1227</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Mixing immediate and non-immediate contexts in deduction failure</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1228">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1228">1228</a></td>
     <td>NAD</td>
     <td>Copy-list-initialization and <TT>explicit</TT> constructors</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1229">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1229">1229</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Overload resolution with empty <I>braced-init-list</I> argument</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1230">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1230">1230</a></td>
     <td>open</td>
     <td>Confusing description of ambiguity of destructor name</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1231">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1231">1231</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Variadic templates requiring an empty pack expansion</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1232">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1232">1232</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Creation of array temporaries using a <I>braced-init-list</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1233">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1233">1233</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Pack expansions and dependent calls</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1234">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1234">1234</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td><I>abstract-declarator</I> does not permit <TT>...</TT> after <I>ptr-operator</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1235">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1235">1235</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>&#8220;Unused&#8221; ellipsis and default arguments in partial ordering</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1236">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1236">1236</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Inconsistently-interrelated examples</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1237">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1237">1237</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Deprecated implicit copy assignment in example</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1238">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1238">1238</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Overloading ambiguity binding reference to function</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1239">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1239">1239</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Hexadecimal floating-point literals vs user-defined literals</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1240">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1240">1240</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td><TT>constexpr</TT> defaulted constructors</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1241">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1241">1241</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Which members does a destructor destroy?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1242">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1242">1242</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Initializing variant class members</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1243">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1243">1243</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Misleading footnote regarding multiple-declarator declarations</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1244">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1244">1244</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Equivalence of alias templates and class templates</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1245">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1245">1245</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Matching declarations involving <TT>decltype</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1246">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1246">1246</a></td>
-    <td>FDIS</td>
+    <td>C++11</td>
     <td>Non-deduced non-final parameter packs</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1247">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1247">1247</a></td>
     <td>drafting</td>
     <td>Restriction on alias name appearing in <I>type-id</I></td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1248">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1248">1248</a></td>
     <td>open</td>
     <td>Updating Annex C to C99</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1249">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1249">1249</a></td>
     <td>drafting</td>
     <td>Cv-qualification of nested lambda capture</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1250">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1250">1250</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Cv-qualification of incomplete virtual function return types</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1251">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1251">1251</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>C compatibility: casting to unqualified <TT>void*</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1252">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1252">1252</a></td>
     <td>drafting</td>
     <td>Overloading member function templates based on dependent return type</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1253">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1253">1253</a></td>
     <td>drafting</td>
     <td>Generic non-template members</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1254">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1254">1254</a></td>
     <td>NAD</td>
     <td>odr-use vs template arguments and constexpr functions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1255">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1255">1255</a></td>
     <td>drafting</td>
     <td>Definition problems with <TT>constexpr</TT> functions</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1256">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1256">1256</a></td>
     <td>open</td>
     <td>Unevaluated operands are not necessarily constant expressions</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1257">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1257">1257</a></td>
     <td>open</td>
     <td>Instantiation via non-dependent references in uninstantiated templates</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1258">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1258">1258</a></td>
     <td>drafting</td>
     <td>&#8220;Instantiation context&#8221; differs from dependent lookup rules</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1259">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1259">1259</a></td>
     <td>extension</td>
     <td>Deleting a POD via a pointer to base</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1260">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1260">1260</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Incorrect use of term &#8220;overloaded&#8221; in description of odr-use</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1261">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1261">1261</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Explicit handling of cv-qualification with non-class prvalues</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1262">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1262">1262</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Default template arguments and deduction failure</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1263">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1263">1263</a></td>
     <td>NAD</td>
     <td>Mismatch between rvalue reference binding and overload resolution</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1264">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1264">1264</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Use of <TT>this</TT> in <TT>constexpr</TT> constructor</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1265">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1265">1265</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Mixed use of the <TT>auto</TT> specifier</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1266">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1266">1266</a></td>
     <td>open</td>
     <td><I>user-defined-integer-literal</I> overflow</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1267">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1267">1267</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Rvalue reference types in <I>exception-specification</I>s</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1268">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1268">1268</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td><TT>reinterpret_cast</TT> of an xvalue operand</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1269">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1269">1269</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td><TT>dynamic_cast</TT> of an xvalue operand</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1270">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1270">1270</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Brace elision in array temporary initialization</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1271">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1271">1271</a></td>
     <td>drafting</td>
     <td>Imprecise wording regarding dependent types</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1272">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1272">1272</a></td>
     <td>extension</td>
     <td>Implicit definition of static data member of const literal type</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1273">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1273">1273</a></td>
     <td>NAD</td>
     <td>Accessibility and function signatures</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1274">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1274">1274</a></td>
     <td>drafting</td>
     <td>Common nonterminal for <I>expression</I> and <I>braced-init-list</I></td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1275">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1275">1275</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Incorrect comment in example of template parameter pack restriction</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1276">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1276">1276</a></td>
     <td>NAD</td>
     <td>Reference to <TT>stdint.h</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1277">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1277">1277</a></td>
     <td>NAD</td>
     <td>Lax definition of <TT>intmax_t</TT> and <TT>uintmax_t</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1278">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1278">1278</a></td>
     <td>drafting</td>
     <td>Incorrect treatment of contrived object</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1279">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1279">1279</a></td>
     <td>drafting</td>
     <td>Additional differences between C++ 2003 and C++ 2011</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1280">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1280">1280</a></td>
     <td>NAD</td>
     <td>Object reallocation and reference members</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1281">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1281">1281</a></td>
     <td>NAD</td>
     <td>Virtual and dependent base classes</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1282">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1282">1282</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Underspecified destructor <I>exception-specification</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1283">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1283">1283</a></td>
     <td>drafting</td>
     <td>Static data members of classes with typedef name for linkage purposes</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1284">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1284">1284</a></td>
     <td>drafting</td>
     <td>Should the lifetime of an array be independent of that of its elements?</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1285">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1285">1285</a></td>
     <td>open</td>
     <td>Trivial destructors and object lifetime</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1286">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1286">1286</a></td>
     <td>drafting</td>
     <td>Equivalence of alias templates</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1287">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1287">1287</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Direct initialization vs &#8220;implicit&#8221; conversion in reference binding</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1288">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1288">1288</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Reference list initialization</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1289">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1289">1289</a></td>
     <td>NAD</td>
     <td>Can an alias template name the current instantiation?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1290">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1290">1290</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Lifetime of the underlying array of an <TT>initializer_list</TT> member</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1291">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1291">1291</a></td>
     <td>drafting</td>
     <td>Looking up a <I>conversion-type-id</I></td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr id="1292">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1292">1292</a></td>
-    <td>drafting</td>
+    <td>ready</td>
     <td>Dependent calls with <I>braced-init-list</I>s containing a pack expansion</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1293">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1293">1293</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>String literals in constant expressions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1294">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1294">1294</a></td>
     <td>drafting</td>
     <td>Side effects in dynamic/static initialization</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1295">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1295">1295</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Binding a reference to an rvalue bit-field</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1296">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1296">1296</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Ill-formed template declarations (not just definitions)</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1297">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1297">1297</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Misplaced function <I>attribute-specifier</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1298">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1298">1298</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Incorrect example in overload resolution</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr id="1299">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1299">1299</a></td>
-    <td>drafting</td>
+    <td>ready</td>
     <td>&#8220;Temporary objects&#8221; vs &#8220;temporary expressions&#8221;</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr id="1300">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1300">1300</a></td>
-    <td>extension</td>
+    <td>dup</td>
     <td><TT>T()</TT> for array types</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1301">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1301">1301</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Value initialization of union</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1302">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1302">1302</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td><TT>noexcept</TT> applied to expression of type <TT>void</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1303">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1303">1303</a></td>
     <td>NAD</td>
     <td>C language linkage for template with internal linkage</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1304">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1304">1304</a></td>
     <td>drafting</td>
     <td>Omitted array bound with string initialization</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1305">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1305">1305</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td><TT>alignof</TT> applied to array of unknown size</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1306">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1306">1306</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Modifying an object within a <TT>const</TT> member function</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1307">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1307">1307</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Overload resolution based on size of array <I>initializer-list</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1308">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1308">1308</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Completeness of class type within an <I>exception-specification</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1309">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1309">1309</a></td>
     <td>drafting</td>
     <td>Incorrect note regarding lookup of a member of the current instantiation</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1310">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1310">1310</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>What is an &#8220;acceptable lookup result?&#8221;</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1311">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1311">1311</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Volatile lvalues in constant expressions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1312">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1312">1312</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Simulated <TT>reinterpret_cast</TT> in constant expressions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1313">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1313">1313</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Undefined pointer arithmetic in constant expressions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1314">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1314">1314</a></td>
     <td>NAD</td>
     <td>Pointer arithmetic within standard-layout objects</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1315">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1315">1315</a></td>
     <td>drafting</td>
     <td>Restrictions on non-type template arguments in partial specializations</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1316">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1316">1316</a></td>
     <td>NAD</td>
     <td><TT>constexpr</TT> function requirements and class scope</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1317">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1317">1317</a></td>
     <td>NAD</td>
     <td>Unnamed scoped enumerations</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1318">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1318">1318</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Syntactic ambiguities with <TT>final</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1319">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1319">1319</a></td>
     <td>NAD</td>
     <td>Error in pack expansion example</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1320">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1320">1320</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Converting scoped enumerations to <TT>bool</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1321">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1321">1321</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Equivalency of dependent calls</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1322">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1322">1322</a></td>
     <td>drafting</td>
     <td>Function parameter type decay in templates</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1323">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1323">1323</a></td>
     <td>NAD</td>
     <td>Nonexistent nonterminal in <I>alignment-specifier</I> grammar</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1324">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1324">1324</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Value initialization and defaulted constructors</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1325">1325</a></td>
-    <td>drafting</td>
+  <tr id="1325">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1325">1325</a></td>
+    <td>NAD</td>
     <td>Omitted declarator in <TT>friend</TT> declarations</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1326">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1326">1326</a></td>
     <td>extension</td>
     <td>Deducing an array bound from an <I>initializer-list</I></td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1327">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1327">1327</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td><I>virt-specifier</I> in a defaulted definition</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1328">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1328">1328</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Conflict in reference binding vs overload resolution</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1329">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1329">1329</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Recursive deduction substitutions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1330">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1330">1330</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Delayed instantiation of <TT>noexcept</TT> specifiers</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1331">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1331">1331</a></td>
     <td>extension</td>
     <td><TT>const</TT> mismatch with defaulted copy constructor</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1332">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1332">1332</a></td>
     <td>drafting</td>
     <td>Handling of invalid universal-character-names</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1333">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1333">1333</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Omission of <TT>const</TT> in a defaulted copy constructor</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1334">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1334">1334</a></td>
     <td>NAD</td>
     <td>Layout compatibility and cv-qualification</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1335">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1335">1335</a></td>
     <td>drafting</td>
     <td>Stringizing, extended characters, and universal-character-names</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1336">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1336">1336</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Definition of &#8220;converting constructor&#8221;</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1337">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1337">1337</a></td>
     <td>dup</td>
     <td>Partial ordering and non-deduced parameters</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr id="1338">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1338">1338</a></td>
-    <td>drafting</td>
+    <td>ready</td>
     <td>Aliasing and allocation functions</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1339">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1339">1339</a></td>
     <td>NAD</td>
     <td>Parenthesized <I>braced-init-list</I> and arrays</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1340">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1340">1340</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Complete type in member pointer expressions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1341">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1341">1341</a></td>
     <td>drafting</td>
     <td>Bit-field initializers</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1342">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1342">1342</a></td>
     <td>drafting</td>
     <td>Order of initialization with multiple declarators</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" 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>Sequencing of non-class initialization</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1344">1344</a></td>
-    <td>ready</td>
+  <tr id="1344">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1344">1344</a></td>
+    <td>DR</td>
     <td>Adding new special member functions to a class via default arguments</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1345">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1345">1345</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Initialization of anonymous union class members</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1346">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1346">1346</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td><I>expression-list</I> initializers and the <TT>auto</TT> specifier</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="svn" align="center">SVN</td>
   </tr>
-  <tr>
+  <tr id="1347">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1347">1347</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Consistency of <TT>auto</TT> in multiple-declarator declarations</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1348">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1348">1348</a></td>
     <td>drafting</td>
     <td>Use of <TT>auto</TT> in a <I>trailing-return-type</I></td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1349">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1349">1349</a></td>
     <td>drafting</td>
     <td>Consistency of alias template redeclarations</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1350">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1350">1350</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Incorrect exception specification for inherited constructors</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1351">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1351">1351</a></td>
     <td>review</td>
     <td>Problems with implicitly-declared <I>exception-specification</I>s</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1352">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1352">1352</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Inconsistent class scope and completeness rules</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1353">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1353">1353</a></td>
     <td>drafting</td>
     <td>Array and variant members and deleted special member functions</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1354">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1354">1354</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Destructor exceptions for temporaries in noexcept expressions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1355">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1355">1355</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Aggregates and &#8220;user-provided&#8221; constructors</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1356">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1356">1356</a></td>
     <td>review</td>
     <td>Exception specifications of copy assignment operators with virtual bases</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1357">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1357">1357</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td><I>brace-or-equal-initializer</I>s for function and typedef members</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1358">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1358">1358</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Unintentionally ill-formed <TT>constexpr</TT> function template instances</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1359">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1359">1359</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td><TT>constexpr</TT> union constructors</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1360">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1360">1360</a></td>
     <td>drafting</td>
     <td><TT>constexpr</TT> defaulted default constructors</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1361">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1361">1361</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Requirement on <I>brace-or-equal-initializer</I>s of literal types</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1362">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1362">1362</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Complete type required for implicit conversion to <TT>T&amp;</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1363">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1363">1363</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Triviality vs multiple default constructors</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1364">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1364">1364</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td><TT>constexpr</TT> function parameters</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1365">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1365">1365</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Calling undefined <TT>constexpr</TT> functions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1366">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1366">1366</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Deleted <TT>constexpr</TT> constructors and virtual base classes</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1367">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1367">1367</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Use of <TT>this</TT> in a constant expression</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1368">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1368">1368</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Value initialization and defaulted constructors (part 2)</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1369">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1369">1369</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Function invocation substitution of <TT>this</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1370">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1370">1370</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td><I>identifier-list</I> cannot contain ellipsis</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1371">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1371">1371</a></td>
     <td>NAD</td>
     <td>Deduction from <TT>T&amp;&amp;</TT> in return types</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1372">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1372">1372</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Cross-references incorrect in conversion function template argument deduction</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1373">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1373">1373</a></td>
     <td>dup</td>
     <td>Overload resolution changes matching reference-binding changes</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1374">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1374">1374</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Qualification conversion vs difference in reference binding</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1375">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1375">1375</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Reference to anonymous union?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1376">1376</a></td>
-    <td>ready</td>
+  <tr id="1376">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1376">1376</a></td>
+    <td>DR</td>
     <td><TT>static_cast</TT> of temporary to rvalue reference</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1377">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1377">1377</a></td>
     <td>dup</td>
     <td>Access declarations not mentioned in Annex C</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1378">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1378">1378</a></td>
     <td>open</td>
     <td>When is an instantiation required?</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1379">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1379">1379</a></td>
     <td>NAD</td>
     <td>Is <TT>std::initializer_list</TT> an aggregate?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1380">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1380">1380</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Type definitions in <I>template-parameter</I> <I>parameter-declaration</I>s</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1381">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1381">1381</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Implicitly-declared special member functions and default <TT>nothrow</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1382">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1382">1382</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Dead code for constructor names</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1383">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1383">1383</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Clarifying discarded-value expressions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1384">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1384">1384</a></td>
     <td>NAD</td>
     <td><TT>reinterpret_cast</TT> in constant expressions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1385">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1385">1385</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Syntactic forms of conversion functions for surrogate call functions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1386">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1386">1386</a></td>
     <td>NAD</td>
     <td>Explicitly-specified partial argument list with multiple parameter packs</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1387">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1387">1387</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Missing non-deduced context for <TT>decltype</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1388">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1388">1388</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Missing non-deduced context following a function parameter pack</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1389">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1389">1389</a></td>
     <td>NAD</td>
     <td>Recursive reference in <I>trailing-return-type</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1390">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1390">1390</a></td>
     <td>drafting</td>
     <td>Dependency of alias template specializations</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1391">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1391">1391</a></td>
     <td>drafting</td>
-    <td>Conversions to parameter types with non deduced template arguments</td>
+    <td>Conversions to parameter types with non-deduced template arguments</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1392">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1392">1392</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Explicit conversion functions for references and non-references</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1393">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1393">1393</a></td>
     <td>extension</td>
     <td>Pack expansions in <I>using-declaration</I>s</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1394">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1394">1394</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Incomplete types as parameters of deleted functions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" 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>Partial ordering of variadic templates reconsidered</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1396">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1396">1396</a></td>
     <td>drafting</td>
     <td>Deferred instantiation and checking of non-static data member initializers</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr id="1397">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1397">1397</a></td>
-    <td>drafting</td>
+    <td>ready</td>
     <td>Class completeness in non-static data member initializers</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1398">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1398">1398</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Non-type template parameters of type <TT>std::nullptr_t</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1399">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1399">1399</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Deduction with multiple function parameter packs</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1400">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1400">1400</a></td>
     <td>NAD</td>
     <td>Function pointer equality</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1401">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1401">1401</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Similar types and reference compatibility</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1402">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1402">1402</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Move functions too often deleted</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1403">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1403">1403</a></td>
     <td>open</td>
     <td>Universal-character-names in comments</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1404">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1404">1404</a></td>
     <td>drafting</td>
     <td>Object reallocation in unions</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1405">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1405">1405</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td><TT>constexpr</TT> and mutable members of literal types</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1406">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1406">1406</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td><I>ref-qualifier</I>s and added parameters of non-static member function templates</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1407">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1407">1407</a></td>
     <td>NAD</td>
     <td>Integral to <TT>bool</TT> conversion in converted constant expressions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1408">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1408">1408</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>What is &#8220;the same aggregate initialization?&#8221;</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1409">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1409">1409</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>What is the second standard conversion sequence of a list-initialization sequence?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1410">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1410">1410</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Reference overload tiebreakers should apply to rvalue references</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1411">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1411">1411</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>More on global scope <TT>::</TT> in <I>nested-name-specifier</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1412">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1412">1412</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Problems in specifying pointer conversions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1413">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1413">1413</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Missing cases of value-dependency</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1414">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1414">1414</a></td>
     <td>drafting</td>
     <td>Binding an rvalue reference to a reference-unrelated lvalue</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1415">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1415">1415</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Missing prohibition of block-scope definition of <TT>extern</TT> object</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1416">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1416">1416</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Function cv-qualifiers and <TT>typeid</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1417">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1417">1417</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Pointers/references to functions with cv-qualifiers or <I>ref-qualifier</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1418">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1418">1418</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Type of <TT>initializer_list</TT> backing array</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1419">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1419">1419</a></td>
     <td>NAD</td>
     <td>Evaluation order in aggregate initialization</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1420">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1420">1420</a></td>
     <td>NAD</td>
     <td>Abstract final classes</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1421">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1421">1421</a></td>
     <td>NAD</td>
     <td>Full expressions and aggregate initialization</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1422">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1422">1422</a></td>
     <td>dup</td>
     <td>Type of character literals containing universal-character-names</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1423">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1423">1423</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Convertibility of <TT>nullptr</TT> to <TT>bool</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1424">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1424">1424</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>When must sub-object destructors be accessible?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1425">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1425">1425</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Base-class subobjects of standard-layout structs</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1426">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1426">1426</a></td>
     <td>extension</td>
     <td>Allowing additional parameter types in defaulted functions</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1427">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1427">1427</a></td>
     <td>NAD</td>
     <td>Default constructor and deleted or inaccessible destructors</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1428">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1428">1428</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Dynamic const objects</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1429">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1429">1429</a></td>
     <td>NAD</td>
     <td>Scope of a member template's template parameter</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1430">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1430">1430</a></td>
     <td>drafting</td>
     <td>Pack expansion into fixed alias template parameter list</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1431">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1431">1431</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Exceptions from other than <I>throw-expression</I>s</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1432">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1432">1432</a></td>
     <td>drafting</td>
     <td>Newly-ambiguous variadic template expansions</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1433">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1433">1433</a></td>
     <td>extension</td>
     <td><I>trailing-return-type</I> and point of declaration</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1434">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1434">1434</a></td>
     <td>NAD</td>
     <td>Parenthesized <I>braced-init-list</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1435">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1435">1435</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td><I>template-id</I> as the declarator for a class template constructor</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1436">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1436">1436</a></td>
     <td>drafting</td>
     <td>Interaction of constant expression changes with preprocessor expressions</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1437">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1437">1437</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td><TT>alignas</TT> in <I>alias-declaration</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1438">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1438">1438</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Non-dereference use of invalid pointers</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1439">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1439">1439</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Lookup and friend template declarations</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1440">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1440">1440</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Acceptable <I>decltype-specifier</I>s used as <I>nested-name-specifier</I>s</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1441">1441</a></td>
-    <td>concurrency</td>
+  <tr id="1441">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1441">1441</a></td>
+    <td>DR</td>
     <td>Unclear wording for signal handler restrictions</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1442">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1442">1442</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Argument-dependent lookup in the range-based <TT>for</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1443">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1443">1443</a></td>
     <td>NAD</td>
     <td>Default arguments and non-static data members</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1444">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1444">1444</a></td>
     <td>drafting</td>
     <td>Type adjustments of non-type template parameters</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1445">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1445">1445</a></td>
     <td>dup</td>
     <td>Argument-dependent lookup of <TT>begin</TT> and <TT>end</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr id="1446">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1446">1446</a></td>
-    <td>drafting</td>
+    <td>ready</td>
     <td>Member function with no <I>ref-qualifier</I> and non-member function with rvalue reference</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1447">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1447">1447</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td><TT>static_cast</TT> of bit-field lvalue to rvalue reference</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1448">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1448">1448</a></td>
     <td>NAD</td>
     <td>Integral values of type <TT>bool</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1449">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1449">1449</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Narrowing conversion of negative value to unsigned type</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1450">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1450">1450</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td><TT>INT_MIN % -1</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1451">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1451">1451</a></td>
     <td>extension</td>
     <td>Objects with no linkage in non-type template arguments</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1452">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1452">1452</a></td>
     <td>drafting</td>
     <td>Value-initialized objects may be constants</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1453">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1453">1453</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Volatile members in literal classes?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1454">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1454">1454</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Passing constants through <TT>constexpr</TT> functions via references</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1455">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1455">1455</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Lvalue converted constant expressions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1456">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1456">1456</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Address constant expression designating the one-past-the-end address</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1457">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1457">1457</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Undefined behavior in left-shift</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1458">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1458">1458</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Address of incomplete type vs <TT>operator&amp;()</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1459">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1459">1459</a></td>
     <td>open</td>
     <td>Reference-binding tiebreakers in overload resolution</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1460">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1460">1460</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>What is an empty union?</td>
+    <td class="svn" align="center">SVN</td>
+  </tr>
+  <tr id="1461">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1461">1461</a></td>
+    <td>NAD</td>
+    <td>Narrowing conversions to bit-fields</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1461">1461</a></td>
-    <td>extension</td>
-    <td>Narrowing conversions to bit-fields</td>
-    <td align="center">Not resolved</td>
-  </tr>
-  <tr>
+  <tr id="1462">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1462">1462</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Deduction failure vs &#8220;ill-formed, no diagnostic required&#8221;</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1463">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1463">1463</a></td>
     <td>extension</td>
     <td><TT>extern "C"</TT> alias templates</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1464">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1464">1464</a></td>
-    <td>WP</td>
+    <td>CD3</td>
     <td>Negative array bound in a <I>new-expression</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1465">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1465">1465</a></td>
     <td>review</td>
     <td><TT>noexcept</TT> and <TT>std::bad_array_new_length</TT></td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1466">1466</a></td>
-    <td>concurrency</td>
+  <tr id="1466">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1466">1466</a></td>
+    <td>DR</td>
     <td>Visible sequences of side effects are redundant</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1467">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1467">1467</a></td>
     <td>drafting</td>
     <td>List-initialization of aggregate from same-type object</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1468">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1468">1468</a></td>
     <td>drafting</td>
     <td><TT>typeid</TT>, overload resolution, and implicit lambda capture</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1469">1469</a></td>
-    <td>drafting</td>
+  <tr class="open" id="1469">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1469">1469</a></td>
+    <td>extension</td>
     <td>Omitted bound in array <I>new-expression</I></td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1470">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1470">1470</a></td>
     <td>NAD</td>
     <td>Thread migration</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1471">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1471">1471</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Nested type of non-dependent base</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1472">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1472">1472</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>odr-use of reference variables</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1473">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1473">1473</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Syntax of <I>literal-operator-id</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr id="1474">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1474">1474</a></td>
-    <td>extension</td>
+    <td>NAD</td>
     <td>User-defined literals and <TT>&lt;inttypes.h&gt;</TT> format macros</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1475">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1475">1475</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Errors in <TT>[[carries_dependency]]</TT> example</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1476">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1476">1476</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Definition of user-defined type</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1477">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1477">1477</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Definition of a <TT>friend</TT> outside its namespace</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1478">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1478">1478</a></td>
     <td>drafting</td>
     <td><TT>template</TT> keyword for dependent template template arguments</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1479">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1479">1479</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Literal operators and default arguments</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1480">1480</a></td>
-    <td>drafting</td>
+  <tr id="1480">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1480">1480</a></td>
+    <td>CD3</td>
     <td>Constant initialization via non-constant temporary</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1481">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1481">1481</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Increment/decrement operators with reference parameters</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1482">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1482">1482</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Point of declaration of enumeration</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1483">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1483">1483</a></td>
     <td>NAD</td>
     <td>Non-dependent <I>static_assert-declaration</I>s</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr id="1484">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1484">1484</a></td>
-    <td>review</td>
+    <td>ready</td>
     <td>Unused local classes of function templates</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1485">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1485">1485</a></td>
     <td>drafting</td>
     <td>Out-of-class definition of member unscoped opaque enumeration</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1486">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1486">1486</a></td>
     <td>drafting</td>
     <td>Base-derived conversion in member pointer deduction</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1487">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1487">1487</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>When are inheriting constructors declared?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1488">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1488">1488</a></td>
     <td>drafting</td>
     <td><I>abstract-pack-declarator</I>s in <I>type-id</I>s</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1489">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1489">1489</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Is value-initialization of an array constant initialization?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1490">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1490">1490</a></td>
     <td>drafting</td>
     <td>List-initialization from a string literal</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1491">1491</a></td>
-    <td>drafting</td>
+  <tr id="1491">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1491">1491</a></td>
+    <td>CD3</td>
     <td>Move construction and rvalue reference members</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr id="1492">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1492">1492</a></td>
-    <td>drafting</td>
-    <td>Exception specifications on template destructors</td>
-    <td align="center">Not resolved</td>
-  </tr>
-  <tr>
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1493">1493</a></td>
     <td>ready</td>
+    <td>Exception specifications on template destructors</td>
+    <td class="none" align="center">Unknown</td>
+  </tr>
+  <tr id="1493">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1493">1493</a></td>
+    <td>DR</td>
     <td>Criteria for move-construction</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1494">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1494">1494</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Temporary initialization for reference binding in list-initialization</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1495">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1495">1495</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Partial specialization of variadic class template</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1496">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1496">1496</a></td>
     <td>drafting</td>
     <td>Triviality with deleted and missing default constructors</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1497">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1497">1497</a></td>
     <td>NAD</td>
     <td>Aggregate initialization with parenthesized string literal</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1498">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1498">1498</a></td>
     <td>dup</td>
     <td>Lifetime of temporaries in range-based <TT>for</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1499">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1499">1499</a></td>
     <td>drafting</td>
     <td>Missing case for deleted move assignment operator</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1500">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1500">1500</a></td>
     <td>open</td>
     <td>Name lookup of dependent conversion function</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1501">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1501">1501</a></td>
     <td>NAD</td>
     <td>Nested braces in list-initialization</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1502">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1502">1502</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Value initialization of unions with member initializers</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1503">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1503">1503</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Exceptions during copy to exception object</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1504">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1504">1504</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Pointer arithmetic after derived-base conversion</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1505">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1505">1505</a></td>
     <td>dup</td>
     <td>Direct binding of reference to temporary in list-initialization</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1506">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1506">1506</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Value category of <TT>initializer_list</TT> object</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1507">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1507">1507</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Value initialization with trivial inaccessible default constructor</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1508">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1508">1508</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Template initializer-list constructors</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1509">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1509">1509</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Definition of &#8220;non-template function&#8221;</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1510">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1510">1510</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>cv-qualified references via <TT>decltype</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1511">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1511">1511</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td><TT>const volatile</TT> variables and the one-definition rule</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1512">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1512">1512</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Pointer comparison vs qualification conversions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1513">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1513">1513</a></td>
     <td>drafting</td>
     <td><TT>initializer_list</TT> deduction failure</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1514">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1514">1514</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Ambiguity between enumeration definition and zero-length bit-field</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1515">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1515">1515</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Modulo 2<SUP><I>n</I></SUP> arithmetic for implicitly-unsigned types</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1516">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1516">1516</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Definition of &#8220;virtual function call&#8221;</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1517">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1517">1517</a></td>
-    <td>review</td>
+    <td>drafting</td>
     <td>Unclear/missing description of behavior during construction/destruction</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <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>drafting</td>
     <td>Explicit default constructors and copy-list-initialization</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr id="1519">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1519">1519</a></td>
-    <td>extension</td>
+    <td>NAD</td>
     <td>Conflicting default and variadic constructors</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1520">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1520">1520</a></td>
     <td>NAD</td>
     <td>Alias template specialization vs pack expansion</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1521">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1521">1521</a></td>
     <td>drafting</td>
     <td><TT>T{</TT><I>expr</I><TT>}</TT> with reference types</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1522">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1522">1522</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Access checking for <TT>initializer_list</TT> array initialization</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1523">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1523">1523</a></td>
     <td>drafting</td>
     <td>Point of declaration in range-based <TT>for</TT></td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1524">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1524">1524</a></td>
     <td>drafting</td>
     <td>Incompletely-defined class template base</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1525">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1525">1525</a></td>
     <td>NAD</td>
     <td>Array bound inference in temporary array</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1526">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1526">1526</a></td>
     <td>dup</td>
     <td>Dependent-class lookup in the current instantiation</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1527">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1527">1527</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Assignment from <I>braced-init-list</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1528">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1528">1528</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Repeated <I>cv-qualifier</I>s in declarators</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1529">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1529">1529</a></td>
     <td>drafting</td>
     <td>Nomenclature for variable vs reference non-static data member</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1530">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1530">1530</a></td>
     <td>drafting</td>
     <td>Member access in out-of-lifetime objects</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1531">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1531">1531</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Definition of &#8220;access&#8221; (verb)</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1532">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1532">1532</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Explicit instantiation and member templates</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1533">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1533">1533</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Function pack expansion for member initialization</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1534">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1534">1534</a></td>
     <td>dup</td>
     <td>cv-qualification of prvalue of type &#8220;array of class&#8221;</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1535">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1535">1535</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td><TT>typeid</TT> in core constant expressions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1536">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1536">1536</a></td>
     <td>drafting</td>
     <td>Overload resolution with temporary from initializer list</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1537">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1537">1537</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Optional compile-time evaluation of constant expressions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1538">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1538">1538</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>C-style cast in <I>braced-init-list</I> assignment</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1539">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1539">1539</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Definition of &#8220;character type&#8221;</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1540">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1540">1540</a></td>
     <td>NAD</td>
     <td>Use of address constants in constant expressions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1541">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1541">1541</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td><I>cv</I> <TT>void</TT> return types</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1542">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1542">1542</a></td>
     <td>drafting</td>
     <td>Compound assignment of <I>braced-init-list</I></td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1543">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1543">1543</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Implicit conversion sequence for empty initializer list</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1544">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1544">1544</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Linkage of member of unnamed namespace</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1545">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1545">1545</a></td>
     <td>drafting</td>
     <td><TT>friend</TT> function templates defined in class templates</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1546">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1546">1546</a></td>
     <td>NAD</td>
     <td>Errors in function template default arguments</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1547">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1547">1547</a></td>
     <td>NAD</td>
     <td><TT>typename</TT> keyword in <I>alias-declaration</I>s</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1548">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1548">1548</a></td>
     <td>drafting</td>
     <td>Copy/move construction and conversion functions</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1549">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1549">1549</a></td>
     <td>open</td>
     <td>Overloaded comma operator with <TT>void</TT> operand</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1550">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1550">1550</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Parenthesized <I>throw-expression</I> operand of <I>conditional-expression</I></td>
-    <td class="none" align="center">Unknown</td>
+    <td class="full" align="center">Yes</td>
   </tr>
-  <tr>
+  <tr id="1551">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1551">1551</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Wording problems in <I>using-declaration</I> specification</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr id="1552">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1552">1552</a></td>
-    <td>drafting</td>
+    <td>ready</td>
     <td><I>exception-specification</I>s and defaulted special member functions</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1553">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1553">1553</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td><TT>sizeof</TT> and xvalue bit-fields</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <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>drafting</td>
     <td>Access and alias templates</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1555">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1555">1555</a></td>
     <td>extension</td>
     <td>Language linkage and function type compatibility</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1556">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1556">1556</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Constructors and explicit conversion functions in direct initialization</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1557">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1557">1557</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Language linkage of converted lambda function pointer</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr id="1558">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1558">1558</a></td>
-    <td>drafting</td>
+    <td>ready</td>
     <td>Unused arguments in alias template specializations</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1559">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1559">1559</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>String too long in initializer list of <I>new-expression</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1560">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1560">1560</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Gratuitous lvalue-to-rvalue conversion in <I>conditional-expression</I> with <I>throw-expression</I> operand</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="svn" align="center">SVN</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1561">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1561">1561</a></td>
     <td>extension</td>
     <td>Aggregates with empty base classes</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1562">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1562">1562</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Non-static data member initializers and union <I>ctor-initializer</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1563">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1563">1563</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>List-initialization and overloaded function disambiguation</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1564">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1564">1564</a></td>
     <td>extension</td>
     <td>Template argument deduction from an initializer list</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1565">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1565">1565</a></td>
     <td>drafting</td>
     <td>Copy elision and lifetime of <TT>initializer_list</TT> underlying array</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1566">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1566">1566</a></td>
     <td>NAD</td>
     <td>Should <TT>new std::initializer_list&lt;T&gt;</TT> be ill-formed?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1567">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1567">1567</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Inheriting constructors and copy/move constructors</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1568">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1568">1568</a></td>
     <td>dup</td>
     <td>Temporary lifetime extension with intervening cast</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1569">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1569">1569</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Deducing a function parameter pack before ellipsis</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1570">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1570">1570</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Address of subobject as non-type template argument</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr id="1571">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1571">1571</a></td>
-    <td>drafting</td>
+    <td>ready</td>
     <td>cv-qualification for indirect reference binding via conversion function</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr id="1572">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1572">1572</a></td>
-    <td>drafting</td>
+    <td>ready</td>
     <td>Incorrect example for rvalue reference binding via conversion function</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr id="1573">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1573">1573</a></td>
-    <td>drafting</td>
+    <td>ready</td>
     <td>Inherited constructor characteristics</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1574">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1574">1574</a></td>
     <td>NAD</td>
     <td>Explicitly-defaulted <TT>constexpr</TT> functions in wrapper templates</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1575">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1575">1575</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Incorrect definition of &#8220;strict pointer safety&#8221;</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1576">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1576">1576</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Discarded-value volatile xvalues</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1577">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1577">1577</a></td>
     <td>extension</td>
     <td>Unnecessary restrictions on partial specializations</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1578">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1578">1578</a></td>
     <td>NAD</td>
     <td>Value-initialization of aggregates</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1579">1579</a></td>
-    <td>ready</td>
+  <tr id="1579">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1579">1579</a></td>
+    <td>DR</td>
     <td>Return by converting move constructor</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1580">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1580">1580</a></td>
     <td>drafting</td>
     <td>Default arguments in explicit instantiations</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1581">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1581">1581</a></td>
     <td>drafting</td>
     <td>When are <TT>constexpr</TT> member functions defined?</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1582">1582</a></td>
-    <td>drafting</td>
+  <tr class="open" id="1582">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1582">1582</a></td>
+    <td>extension</td>
     <td>Template default arguments and deduction failure</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1583">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1583">1583</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Incorrect example of unspecified behavior</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr id="1584">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1584">1584</a></td>
-    <td>review</td>
+    <td>ready</td>
     <td>Deducing function types from cv-qualified types</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1585">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1585">1585</a></td>
     <td>NAD</td>
     <td>Value category of member access of rvalue reference member</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1586">1586</a></td>
-    <td>drafting</td>
+  <tr class="open" id="1586">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1586">1586</a></td>
+    <td>extension</td>
     <td>Naming a destructor via <TT>decltype</TT></td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1587">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1587">1587</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td><TT>constexpr</TT> initialization and nested anonymous unions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1588">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1588">1588</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Deducing cv-qualified <TT>auto</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1589">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1589">1589</a></td>
     <td>drafting</td>
     <td>Ambiguous ranking of list-initialization sequences</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1590">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1590">1590</a></td>
     <td>review</td>
     <td>Bypassing non-copy/move constructor copying</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr id="1591">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1591">1591</a></td>
-    <td>drafting</td>
+    <td>ready</td>
     <td>Deducing array bound and element type from initializer list</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1592">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1592">1592</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>When do template parameters match?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1593">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1593">1593</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>&#8220;Parameter type&#8221; of special member functions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1594">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1594">1594</a></td>
     <td>drafting</td>
     <td>Lazy declaration of special members vs overload errors</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1595">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1595">1595</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Constructors &#8220;involved in&#8221; subobject initialization</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr id="1596">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1596">1596</a></td>
-    <td>review</td>
+    <td>ready</td>
     <td>Non-array objects as <TT>array[1]</TT></td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1597">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1597">1597</a></td>
-    <td>WP</td>
+    <td>CD3</td>
     <td>Misleading <TT>constexpr</TT> example</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1598">1598</a></td>
-    <td>drafting</td>
+  <tr id="1598">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1598">1598</a></td>
+    <td>DR</td>
     <td>Criterion for equality of pointers to members</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1599">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1599">1599</a></td>
     <td>open</td>
     <td>Lifetime of <TT>initializer_list</TT> underlying array</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr id="1600">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1600">1600</a></td>
-    <td>review</td>
+    <td>ready</td>
     <td>Erroneous reference initialization in example</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1601">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1601">1601</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Promotion of enumeration with fixed underlying type</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1602">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1602">1602</a></td>
     <td>open</td>
     <td>Linkage of specialization vs linkage of template arguments</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1603">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1603">1603</a></td>
     <td>review</td>
     <td>Errors resulting from giving unnamed namespaces internal linkage</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1604">1604</a></td>
-    <td>ready</td>
+  <tr id="1604">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1604">1604</a></td>
+    <td>DR</td>
     <td>Double temporaries in reference initialization</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1605">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1605">1605</a></td>
-    <td>DRWP</td>
+    <td>CD3</td>
     <td>Misleading parenthetical comment for explicit destructor call</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1606">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1606">1606</a></td>
     <td>NAD</td>
     <td><TT>sizeof</TT> closure class</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1607">1607</a></td>
-    <td>ready</td>
+  <tr id="1607">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1607">1607</a></td>
+    <td>DR</td>
     <td>Lambdas in template parameters</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1608">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1608">1608</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Operator lookup in trailing return type</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1609">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1609">1609</a></td>
     <td>open</td>
     <td>Default arguments and function parameter packs</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1610">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1610">1610</a></td>
     <td>drafting</td>
     <td>Cv-qualification in deduction of reference to array</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1611">1611</a></td>
-    <td>tentatively ready</td>
+  <tr id="1611">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1611">1611</a></td>
+    <td>DR</td>
     <td>Deleted default constructor for abstract class</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1612">1612</a></td>
-    <td>ready</td>
+  <tr id="1612">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1612">1612</a></td>
+    <td>DR</td>
     <td>Implicit lambda capture and anonymous unions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1613">1613</a></td>
-    <td>ready</td>
+  <tr id="1613">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1613">1613</a></td>
+    <td>DR</td>
     <td>Constant expressions and lambda capture</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr id="1614">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1614">1614</a></td>
-    <td>review</td>
+    <td>ready</td>
     <td>Address of pure virtual function vs odr-use</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr id="1615">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1615">1615</a></td>
-    <td>review</td>
+    <td>ready</td>
     <td>Alignment of types, variables, and members</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1616">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1616">1616</a></td>
     <td>drafting</td>
     <td>Disambiguation parsing and template parameters</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1617">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1617">1617</a></td>
     <td>open</td>
     <td><TT>alignas</TT> and non-defining declarations</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1618">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1618">1618</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Gratuitously-unsigned underlying enum type</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1619">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1619">1619</a></td>
     <td>open</td>
     <td>Definition of current instantiation</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1620">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1620">1620</a></td>
     <td>open</td>
     <td>User-defined literals and extended integer types</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1621">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1621">1621</a></td>
     <td>drafting</td>
     <td>Member initializers in anonymous unions</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1622">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1622">1622</a></td>
     <td>drafting</td>
     <td>Empty aggregate initializer for union</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1623">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1623">1623</a></td>
     <td>drafting</td>
     <td>Deleted default union constructor and member initializers</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1624">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1624">1624</a></td>
     <td>NAD</td>
     <td>Destruction of union members with member initializers</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1625">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1625">1625</a></td>
     <td>open</td>
     <td>Adding spaces between tokens in stringizing</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1626">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1626">1626</a></td>
     <td>drafting</td>
     <td><TT>constexpr</TT> member functions in <I>brace-or-equal-initializer</I>s</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1627">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1627">1627</a></td>
     <td>NAD</td>
     <td>Agreement of dependent <TT>alignas</TT> specifiers</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1628">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1628">1628</a></td>
     <td>open</td>
     <td>Deallocation function templates</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1629">1629</a></td>
-    <td>drafting</td>
+  <tr id="1629">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1629">1629</a></td>
+    <td>DR</td>
     <td>Can a closure class be a literal type?</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1630">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1630">1630</a></td>
     <td>drafting</td>
     <td>Multiple default constructor templates</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1631">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1631">1631</a></td>
     <td>drafting</td>
     <td>Incorrect overload resolution for single-element <I>initializer-list</I></td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1632">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1632">1632</a></td>
     <td>open</td>
     <td>Lambda capture in member initializers</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1633">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1633">1633</a></td>
     <td>review</td>
     <td>Copy-initialization in member initialization</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1634">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1634">1634</a></td>
     <td>drafting</td>
     <td>Temporary storage duration</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1635">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1635">1635</a></td>
     <td>drafting</td>
     <td>How similar are template default arguments to function default arguments?</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1636">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1636">1636</a></td>
     <td>drafting</td>
     <td>Bits required for negative enumerator values</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1637">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1637">1637</a></td>
     <td>NAD</td>
     <td>Recursion in <TT>constexpr</TT> template default constructor</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1638">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1638">1638</a></td>
     <td>drafting</td>
     <td>Declaring an explicit specialization of a scoped enumeration</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1639">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1639">1639</a></td>
     <td>review</td>
     <td><I>exception-specification</I>s and pointer/pointer-to-member expressions</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1640">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1640">1640</a></td>
     <td>drafting</td>
     <td>Array of abstract instance of class template</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1641">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1641">1641</a></td>
     <td>NAD</td>
     <td>Assignment in member initializer</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1642">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1642">1642</a></td>
     <td>open</td>
     <td>Missing requirements for prvalue operands</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1643">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1643">1643</a></td>
     <td>extension</td>
     <td>Default arguments for template parameter packs</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1644">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1644">1644</a></td>
     <td>open</td>
     <td>Equivalent <I>exception-specification</I>s in function template declarations</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1645">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1645">1645</a></td>
     <td>drafting</td>
     <td>Identical inheriting constructors via default arguments</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1646">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1646">1646</a></td>
     <td>drafting</td>
     <td><I>decltype-specifier</I>s, abstract classes, and deduction failure</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1647">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1647">1647</a></td>
     <td>drafting</td>
     <td>Type agreement of non-type template arguments in partial specializations</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1648">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1648">1648</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td><TT>thread_local</TT> vs block extern declarations</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1649">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1649">1649</a></td>
-    <td>DR</td>
+    <td>DRWP</td>
     <td>Error in the syntax of <I>mem-initializer-list</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1650">1650</a></td>
-    <td>open</td>
+  <tr id="1650">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1650">1650</a></td>
+    <td>NAD</td>
     <td>Class prvalues in reference initialization</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr id="1651">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1651">1651</a></td>
-    <td>drafting</td>
+    <td>ready</td>
     <td>Lifetime extension of temporary via reference to subobject</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1652">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1652">1652</a></td>
     <td>drafting</td>
     <td>Object addresses in <TT>constexpr</TT> expressions</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1653">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1653">1653</a></td>
     <td>drafting</td>
     <td>Removing deprecated increment of <TT>bool</TT></td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1654">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1654">1654</a></td>
     <td>dup</td>
     <td>Literal types and <TT>constexpr</TT> defaulted constructors</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1655">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1655">1655</a></td>
     <td>drafting</td>
     <td>Line endings in raw string literals</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1656">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1656">1656</a></td>
     <td>drafting</td>
     <td>Encoding of numerically-escaped characters</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1657">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1657">1657</a></td>
     <td>extension</td>
     <td>Attributes for namespaces and enumerators</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1658">1658</a></td>
-    <td>drafting</td>
+  <tr id="1658">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1658">1658</a></td>
+    <td>DR</td>
     <td>Deleted default constructor for abstract class via destructor</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1659">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1659">1659</a></td>
     <td>open</td>
     <td>Initialization order of thread_local template static data members</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1660">1660</a></td>
-    <td>open</td>
+  <tr id="1660">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1660">1660</a></td>
+    <td>DR</td>
     <td><I>member-declaration</I> requirements and unnamed bit-fields</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1661">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1661">1661</a></td>
     <td>concurrency</td>
     <td>Preservation of infinite loops</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1662">1662</a></td>
-    <td>ready</td>
+  <tr id="1662">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1662">1662</a></td>
+    <td>DR</td>
     <td>Capturing function parameter packs</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1663">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1663">1663</a></td>
     <td>NAD</td>
     <td>Capturing an empty pack expansion</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1664">1664</a></td>
-    <td>ready</td>
+  <tr id="1664">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1664">1664</a></td>
+    <td>DR</td>
     <td>Argument-dependent lookup of lambdas used in default arguments</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1665">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1665">1665</a></td>
     <td>drafting</td>
     <td>Declaration matching in explicit instantiations</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1666">1666</a></td>
-    <td>drafting</td>
+  <tr id="1666">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1666">1666</a></td>
+    <td>DR</td>
     <td>Address constant expressions</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1667">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1667">1667</a></td>
     <td>NAD</td>
     <td>Function exiting via exception called by destructor during unwinding</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1668">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1668">1668</a></td>
     <td>drafting</td>
     <td>Parameter type determination still not clear enough</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1669">1669</a></td>
-    <td>drafting</td>
+  <tr id="1669">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1669">1669</a></td>
+    <td>accepted</td>
     <td><TT>auto</TT> return type for <TT>main</TT></td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1670">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1670">1670</a></td>
-    <td>open</td>
+    <td>drafting</td>
     <td><TT>auto</TT> as <I>conversion-type-id</I></td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1671">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1671">1671</a></td>
     <td>NAD</td>
     <td>Unclear rules for deduction with cv-qualification</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1672">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1672">1672</a></td>
     <td>drafting</td>
     <td>Layout compatibility with multiple empty bases</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1673">1673</a></td>
-    <td>review</td>
+  <tr id="1673">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1673">1673</a></td>
+    <td>DR</td>
     <td>Clarifying overload resolution for the second step of copy-initialization</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1674">1674</a></td>
-    <td>drafting</td>
+  <tr id="1674">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1674">1674</a></td>
+    <td>accepted</td>
     <td>Return type deduction for address of function</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1675">1675</a></td>
-    <td>ready</td>
+  <tr id="1675">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1675">1675</a></td>
+    <td>NAD</td>
     <td>Size limit for automatic array object</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1676">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1676">1676</a></td>
     <td>drafting</td>
     <td><TT>auto</TT> return type for allocation and deallocation functions</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1677">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1677">1677</a></td>
     <td>drafting</td>
     <td>Constant initialization via aggregate initialization</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1678">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1678">1678</a></td>
     <td>NAD</td>
     <td>Naming the type of an array of runtime bound</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1679">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1679">1679</a></td>
     <td>NAD</td>
     <td>Range-based <TT>for</TT> and array of runtime bound</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1680">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1680">1680</a></td>
     <td>drafting</td>
     <td>Including <TT>&lt;initializer_list&gt;</TT> for range-based <TT>for</TT></td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1681">1681</a></td>
-    <td>ready</td>
+  <tr id="1681">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1681">1681</a></td>
+    <td>accepted</td>
     <td><I>init-capture</I>s and nested lambdas</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1682">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1682">1682</a></td>
     <td>open</td>
     <td>Overly-restrictive rules on function templates as allocation functions</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1683">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1683">1683</a></td>
     <td>review</td>
     <td>Incorrect example after <TT>constexpr</TT> changes</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1684">1684</a></td>
-    <td>drafting</td>
+  <tr id="1684">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1684">1684</a></td>
+    <td>accepted</td>
     <td>Static <TT>constexpr</TT> member functions for non-literal classes</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1685">1685</a></td>
-    <td>review</td>
+  <tr id="1685">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1685">1685</a></td>
+    <td>NAD</td>
     <td>Value category of <TT>noexcept</TT> expression</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr id="1686">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1686">1686</a></td>
-    <td>review</td>
+    <td>ready</td>
     <td>Which variables are &#8220;explicitly declared <TT>const</TT>?&#8221;</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1687">1687</a></td>
-    <td>drafting</td>
+  <tr id="1687">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1687">1687</a></td>
+    <td>DR</td>
     <td>Conversions of operands of built-in operators</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
+  <tr id="1688">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1688">1688</a></td>
     <td>NAD</td>
     <td>Volatile <TT>constexpr</TT> variables</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1689">1689</a></td>
-    <td>drafting</td>
+  <tr id="1689">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1689">1689</a></td>
+    <td>DR</td>
     <td>Syntactic nonterminal for operand of <TT>alignas</TT></td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1690">1690</a></td>
-    <td>ready</td>
+  <tr id="1690">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1690">1690</a></td>
+    <td>DR</td>
     <td>Associated namespace for local type</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1691">1691</a></td>
-    <td>ready</td>
+  <tr id="1691">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1691">1691</a></td>
+    <td>DR</td>
     <td>Argument-dependent lookup and opaque enumerations</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1692">1692</a></td>
-    <td>ready</td>
+  <tr id="1692">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1692">1692</a></td>
+    <td>DR</td>
     <td>Associated namespaces of doubly-nested classes</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1693">1693</a></td>
-    <td>drafting</td>
+  <tr id="1693">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1693">1693</a></td>
+    <td>DR</td>
     <td>Superfluous semicolons in class definitions</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr id="1694">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1694">1694</a></td>
-    <td>review</td>
+    <td>ready</td>
     <td>Restriction on reference to temporary as a constant expression</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1695">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1695">1695</a></td>
     <td>drafting</td>
     <td>Lifetime extension via <I>init-capture</I></td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1696">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1696">1696</a></td>
-    <td>open</td>
+    <td>drafting</td>
     <td>Temporary lifetime and non-static data member initializers</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1697">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1697">1697</a></td>
     <td>drafting</td>
     <td>Lifetime extension and copy elision</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1698">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1698">1698</a></td>
     <td>open</td>
     <td>Files ending in <TT>\</TT></td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1699">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1699">1699</a></td>
     <td>drafting</td>
     <td>Does befriending a class befriend its friends?</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1700">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1700">1700</a></td>
     <td>NAD</td>
     <td>Does the special rvalue-reference deduction apply to alias templates?</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1701">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1701">1701</a></td>
     <td>drafting</td>
     <td>Array vs sequence in object representation</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1702">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1702">1702</a></td>
     <td>drafting</td>
     <td>Rephrasing the definition of &#8220;anonymous union&#8221;</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1703">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1703">1703</a></td>
     <td>NAD</td>
     <td>Language linkage of names of functions with internal linkage</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1704">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1704">1704</a></td>
     <td>drafting</td>
     <td>Type checking in explicit instantiation of variable templates</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr id="1705">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1705">1705</a></td>
-    <td>review</td>
+    <td>ready</td>
     <td>Unclear specification of &#8220;more specialized&#8221;</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1706">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1706">1706</a></td>
-    <td>open</td>
+    <td>drafting</td>
     <td><TT>alignas</TT> pack expansion syntax</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1707">1707</a></td>
-    <td>drafting</td>
+  <tr id="1707">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1707">1707</a></td>
+    <td>DR</td>
     <td><TT>template</TT> in <I>elaborated-type-specifier</I> without <I>nested-name-specifier</I></td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1708">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1708">1708</a></td>
-    <td>drafting</td>
+    <td>review</td>
     <td>overly-strict requirements for names with C language linkage</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1709">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1709">1709</a></td>
     <td>drafting</td>
     <td>Stringizing raw string literals containing newline</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr id="1710">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1710">1710</a></td>
-    <td>drafting</td>
+    <td>ready</td>
     <td>Missing <TT>template</TT> keyword in <I>class-or-decltype</I></td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1711">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1711">1711</a></td>
-    <td>open</td>
+    <td>drafting</td>
     <td>Missing specification of variable template partial specializations</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr id="1712">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1712">1712</a></td>
-    <td>drafting</td>
+    <td>ready</td>
     <td><TT>constexpr</TT> variable template declarations</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1713">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1713">1713</a></td>
-    <td>open</td>
+    <td>drafting</td>
     <td>Linkage of variable template specializations</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1714">1714</a></td>
-    <td>drafting</td>
+  <tr id="1714">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1714">1714</a></td>
+    <td>NAD</td>
     <td>odr-use of <TT>this</TT> from a local class</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr id="1715">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1715">1715</a></td>
-    <td>drafting</td>
-    <td>Access and inherited constructor templates</td>
-    <td align="center">Not resolved</td>
-  </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1716">1716</a></td>
-    <td>drafting</td>
-    <td>When are default arguments evaluated?</td>
-    <td align="center">Not resolved</td>
-  </tr>
-  <tr>
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1717">1717</a></td>
     <td>ready</td>
+    <td>Access and inherited constructor templates</td>
+    <td class="none" align="center">Unknown</td>
+  </tr>
+  <tr id="1716">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1716">1716</a></td>
+    <td>DR</td>
+    <td>When are default arguments evaluated?</td>
+    <td class="none" align="center">Unknown</td>
+  </tr>
+  <tr id="1717">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1717">1717</a></td>
+    <td>accepted</td>
     <td>Missing specification of type of binary literal</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1718">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1718">1718</a></td>
-    <td>open</td>
+    <td>drafting</td>
     <td>Macro invocation spanning end-of-file</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1719">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1719">1719</a></td>
-    <td>open</td>
+    <td>drafting</td>
     <td>Layout compatibility and cv-qualification revisited</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1720">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1720">1720</a></td>
     <td>NAD</td>
     <td>Macro invocation in <TT>#include</TT> directive</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1721">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1721">1721</a></td>
     <td>drafting</td>
     <td>Diagnosing ODR violations for static data members</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1722">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1722">1722</a></td>
     <td>drafting</td>
     <td>Should lambda to function pointer conversion function be <TT>noexcept</TT>?</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1723">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1723">1723</a></td>
     <td>drafting</td>
     <td>Multicharacter user-defined character literals</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1724">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1724">1724</a></td>
     <td>drafting</td>
     <td>Unclear rules for deduction failure</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1725">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1725">1725</a></td>
     <td>NAD</td>
     <td>Trailing return type with nested function declarator</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1726">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1726">1726</a></td>
     <td>drafting</td>
     <td>Declarator operators and conversion function</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1727">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1727">1727</a></td>
     <td>NAD</td>
     <td>Type of a specialization of a variable template</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1728">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1728">1728</a></td>
     <td>drafting</td>
     <td>Type of an explicit instantiation of a variable template</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1729">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1729">1729</a></td>
     <td>drafting</td>
     <td>Matching declarations and definitions of variable templates</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1730">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1730">1730</a></td>
     <td>drafting</td>
     <td>Can a variable template have an unnamed type?</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
+  <tr id="1731">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1731">1731</a></td>
     <td>NAD</td>
     <td><TT>is_trivially_</TT><I>X</I> and definitions of special member functions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1732">1732</a></td>
-    <td>drafting</td>
+  <tr id="1732">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1732">1732</a></td>
+    <td>DR</td>
     <td>Defining types in <I>condition</I>s and range-based <TT>for</TT> statements</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1733">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1733">1733</a></td>
     <td>drafting</td>
     <td>Return type and value for <TT>operator=</TT> with <I>ref-qualifier</I></td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1734">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1734">1734</a></td>
     <td>drafting</td>
     <td>Nontrivial deleted copy functions</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1735">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1735">1735</a></td>
     <td>drafting</td>
     <td>Out-of-range literals in <I>user-defined-literal</I>s</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1736">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1736">1736</a></td>
     <td>drafting</td>
     <td>Inheriting constructor templates in a local class</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1737">1737</a></td>
-    <td>drafting</td>
+  <tr id="1737">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1737">1737</a></td>
+    <td>DR</td>
     <td>Type dependence of call to a member of the current instantiation</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1738">1738</a></td>
-    <td>drafting</td>
+  <tr id="1738">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1738">1738</a></td>
+    <td>DR</td>
     <td>Explicit instantiation/specialization of inheriting constructor templates</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1739">1739</a></td>
-    <td>drafting</td>
+  <tr id="1739">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1739">1739</a></td>
+    <td>DR</td>
     <td>Conversion of floating point to enumeration</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1740">1740</a></td>
-    <td>ready</td>
+  <tr id="1740">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1740">1740</a></td>
+    <td>DR</td>
     <td>Disambiguation of <TT>noexcept</TT></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1741">1741</a></td>
-    <td>ready</td>
+  <tr id="1741">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1741">1741</a></td>
+    <td>DR</td>
     <td>odr-use of class object in lvalue-to-rvalue conversion</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1742">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1742">1742</a></td>
     <td>open</td>
     <td><I>using-declaration</I>s and scoped enumerators</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1743">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1743">1743</a></td>
     <td>open</td>
     <td><I>init-capture</I>s in nested lambdas</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1744">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1744">1744</a></td>
-    <td>open</td>
+    <td>review</td>
     <td>Unordered initialization for variable template specializations</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1745">1745</a></td>
-    <td>open</td>
+  <tr id="1745">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1745">1745</a></td>
+    <td>NAD</td>
     <td><TT>thread_local constexpr</TT> variable</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1746">1746</a></td>
-    <td>open</td>
+  <tr id="1746">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1746">1746</a></td>
+    <td>DR</td>
     <td>Are volatile scalar types trivially copyable?</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1747">1747</a></td>
-    <td>open</td>
+  <tr id="1747">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1747">1747</a></td>
+    <td>DR</td>
     <td>Constant initialization of reference to function</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr id="1748">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1748">1748</a></td>
-    <td>open</td>
+    <td>ready</td>
     <td>Placement new with a null pointer</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1749">1749</a></td>
-    <td>open</td>
+  <tr id="1749">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1749">1749</a></td>
+    <td>NAD</td>
     <td>Confusing definition for constant initializer</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr id="1750">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1750">1750</a></td>
-    <td>open</td>
+    <td>ready</td>
     <td>&#8220;Argument&#8221; vs &#8220;parameter&#8221;</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr id="1751">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1751">1751</a></td>
-    <td>open</td>
+    <td>ready</td>
     <td>Non-trivial operations vs non-trivial initialization</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr id="1752">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1752">1752</a></td>
-    <td>open</td>
+    <td>ready</td>
     <td>Right-recursion in <I>mem-initializer-list</I></td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr id="1753">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1753">1753</a></td>
-    <td>open</td>
+    <td>ready</td>
     <td><I>decltype-specifier</I> in <I>nested-name-specifier</I> of destructor</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1754">1754</a></td>
-    <td>open</td>
+  <tr class="open" id="1754">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1754">1754</a></td>
+    <td>extension</td>
     <td>Declaration of partial specialization of static data member template</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1755">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1755">1755</a></td>
-    <td>open</td>
+    <td>drafting</td>
     <td>Out-of-class partial specializations of member templates</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1756">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1756">1756</a></td>
-    <td>open</td>
+    <td>review</td>
     <td>Direct-list-initialization of a non-class object</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr id="1757">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1757">1757</a></td>
-    <td>open</td>
+    <td>ready</td>
     <td>Const integral subobjects</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1758">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1758">1758</a></td>
     <td>open</td>
     <td>Explicit conversion in copy/move list initialization</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1759">1759</a></td>
-    <td>drafting</td>
+  <tr id="1759">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1759">1759</a></td>
+    <td>DR</td>
     <td>UTF-8 code units in plain <TT>char</TT></td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1760">1760</a></td>
-    <td>ready</td>
+  <tr id="1760">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1760">1760</a></td>
+    <td>accepted</td>
     <td>Access of member corresponding to <I>init-capture</I></td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1761">1761</a></td>
-    <td>ready</td>
+  <tr id="1761">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1761">1761</a></td>
+    <td>NAD</td>
     <td>Runtime check on size of automatic array</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1762">1762</a></td>
-    <td>ready</td>
+  <tr id="1762">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1762">1762</a></td>
+    <td>DR</td>
     <td>Reserved identifier used in <I>literal-operator-id</I> example</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1763">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1763">1763</a></td>
     <td>open</td>
     <td>Length mismatch in template type deduction</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1764">1764</a></td>
-    <td>ready</td>
+  <tr id="1764">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1764">1764</a></td>
+    <td>DR</td>
     <td>Hiding of function from using-declaration by signature</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1765">1765</a></td>
-    <td>ready</td>
+  <tr id="1765">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1765">1765</a></td>
+    <td>DR</td>
     <td>Overflow of enumeration used as enumerator value</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr id="1766">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1766">1766</a></td>
-    <td>open</td>
-    <td>Values outside the range of the values of an enumeration</td>
-    <td align="center">Not resolved</td>
-  </tr>
-  <tr>
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1767">1767</a></td>
     <td>ready</td>
+    <td>Values outside the range of the values of an enumeration</td>
+    <td class="none" align="center">Unknown</td>
+  </tr>
+  <tr id="1767">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1767">1767</a></td>
+    <td>DR</td>
     <td>Scoped enumeration in a <TT>switch</TT> statement</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1768">1768</a></td>
-    <td>ready</td>
+  <tr id="1768">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1768">1768</a></td>
+    <td>NAD</td>
     <td>Zero-element array of runtime bound</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1769">1769</a></td>
-    <td>review</td>
+  <tr id="1769">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1769">1769</a></td>
+    <td>DR</td>
     <td>Catching a base class of the exception object</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1770">1770</a></td>
-    <td>ready</td>
+  <tr id="1770">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1770">1770</a></td>
+    <td>DR</td>
     <td>Type matching of non-type template parameters and arguments</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1771">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1771">1771</a></td>
     <td>open</td>
     <td>Restricted lookup in <I>nested-name-specifier</I></td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1772">1772</a></td>
-    <td>ready</td>
+  <tr id="1772">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1772">1772</a></td>
+    <td>DR</td>
     <td><TT>__func__</TT> in a lambda body</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr>
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1773">1773</a></td>
-    <td>ready</td>
+  <tr id="1773">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1773">1773</a></td>
+    <td>DR</td>
     <td>Out-of-lifetime lvalue-to-rvalue conversion</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1774">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1774">1774</a></td>
-    <td>open</td>
+    <td>drafting</td>
     <td>Discrepancy between subobject destruction and stack unwinding</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr>
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1775">1775</a></td>
-    <td>ready</td>
+  <tr id="1775">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1775">1775</a></td>
+    <td>DR</td>
     <td>Undefined behavior of line splice in raw string literal</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <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>open</td>
+    <td>drafting</td>
     <td>Replacement of class objects containing reference members</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr id="1777">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1777">1777</a></td>
-    <td>open</td>
-    <td>Empty pack expansion in <I>dynamic-exception-specification</I></td>
-    <td align="center">Not resolved</td>
-  </tr>
-  <tr>
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1778">1778</a></td>
     <td>ready</td>
+    <td>Empty pack expansion in <I>dynamic-exception-specification</I></td>
+    <td class="none" align="center">Unknown</td>
+  </tr>
+  <tr id="1778">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1778">1778</a></td>
+    <td>DR</td>
     <td><I>exception-specification</I> in explicitly-defaulted functions</td>
     <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr id="1779">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1779">1779</a></td>
-    <td>open</td>
+    <td>ready</td>
     <td>Type dependency of <TT>__func__</TT></td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr id="1780">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1780">1780</a></td>
-    <td>open</td>
+    <td>ready</td>
     <td>Explicit instantiation/specialization of generic lambda <TT>operator()</TT></td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1781">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1781">1781</a></td>
     <td>open</td>
     <td>Converting from <TT>nullptr_t</TT> to <TT>bool</TT> in overload resolution</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr id="1782">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1782">1782</a></td>
-    <td>open</td>
+    <td>ready</td>
     <td>Form of initialization for <TT>nullptr_t</TT> to <TT>bool</TT> conversion</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1783">1783</a></td>
-    <td>open</td>
+  <tr id="1783">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1783">1783</a></td>
+    <td>NAD</td>
     <td>Why are virtual destructors non-trivial?</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1784">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1784">1784</a></td>
     <td>concurrency</td>
     <td>Concurrent execution during static local initialization</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1785">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1785">1785</a></td>
-    <td>open</td>
+    <td>drafting</td>
     <td>Conflicting diagnostic requirements for template definitions</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1786">1786</a></td>
-    <td>drafting</td>
+  <tr id="1786">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1786">1786</a></td>
+    <td>DR</td>
     <td>Effect of merging allocations on memory leakage</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1787">1787</a></td>
-    <td>drafting</td>
+  <tr id="1787">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1787">1787</a></td>
+    <td>DR</td>
     <td>Uninitialized <TT>unsigned char</TT> values</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1788">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1788">1788</a></td>
-    <td>open</td>
+    <td>review</td>
     <td>Sized deallocation of array of non-class type</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1789">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1789">1789</a></td>
-    <td>open</td>
+    <td>drafting</td>
     <td>Array reference vs array decay in overload resolution</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr class="open" id="1790">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1790">1790</a></td>
     <td>open</td>
     <td>Ellipsis following function parameter pack</td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
+  <tr id="1791">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1791">1791</a></td>
-    <td>open</td>
+    <td>ready</td>
     <td>Incorrect restrictions on <I>cv-qualifier-seq</I> and <I>ref-qualifier</I></td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1792">1792</a></td>
-    <td>open</td>
+  <tr id="1792">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1792">1792</a></td>
+    <td>NAD</td>
     <td>Incorrect example of explicit specialization of member enumeration</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr id="1793">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1793">1793</a></td>
-    <td>open</td>
+    <td>ready</td>
     <td><TT>thread_local</TT> in explicit specializations</td>
-    <td align="center">Not resolved</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
-  <tr class="open">
+  <tr id="1794">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1794">1794</a></td>
-    <td>open</td>
+    <td>ready</td>
     <td><TT>template</TT> keyword and alias templates</td>
+    <td class="none" align="center">Unknown</td>
+  </tr>
+  <tr class="open" id="1795">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1795">1795</a></td>
+    <td>drafting</td>
+    <td>Disambiguating <I>original-namespace-definition</I> and <I>extension-namespace-definition</I></td>
     <td align="center">Not resolved</td>
   </tr>
-  <tr class="open">
-    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1795">1795</a></td>
+  <tr id="1796">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1796">1796</a></td>
+    <td>ready</td>
+    <td>Is all-bits-zero for null characters a meaningful requirement?</td>
+    <td class="none" align="center">Unknown</td>
+  </tr>
+  <tr id="1797">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1797">1797</a></td>
+    <td>ready</td>
+    <td>Are all bit patterns of <TT>unsigned char</TT> distinct numbers?</td>
+    <td class="none" align="center">Unknown</td>
+  </tr>
+  <tr class="open" id="1798">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1798">1798</a></td>
+    <td>extension</td>
+    <td><I>exception-specification</I>s of template arguments</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr id="1799">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1799">1799</a></td>
+    <td>ready</td>
+    <td><TT>mutable</TT> and non-explicit const qualification</td>
+    <td class="none" align="center">Unknown</td>
+  </tr>
+  <tr id="1800">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1800">1800</a></td>
+    <td>ready</td>
+    <td>Pointer to member of nested anonymous union</td>
+    <td class="none" align="center">Unknown</td>
+  </tr>
+  <tr class="open" id="1801">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1801">1801</a></td>
+    <td>drafting</td>
+    <td>Kind of expression referring to member of anonymous union</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr id="1802">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1802">1802</a></td>
+    <td>ready</td>
+    <td><TT>char16_t</TT> string literals and surrogate pairs</td>
+    <td class="none" align="center">Unknown</td>
+  </tr>
+  <tr class="open" id="1803">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1803">1803</a></td>
+    <td>drafting</td>
+    <td><I>opaque-enum-declaration</I> as <I>member-declaration</I></td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr id="1804">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1804">1804</a></td>
+    <td>ready</td>
+    <td>Partial specialization and friendship</td>
+    <td class="none" align="center">Unknown</td>
+  </tr>
+  <tr id="1805">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1805">1805</a></td>
+    <td>ready</td>
+    <td>Conversions of array operands in <I>conditional-expression</I>s</td>
+    <td class="none" align="center">Unknown</td>
+  </tr>
+  <tr class="open" id="1806">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1806">1806</a></td>
+    <td>review</td>
+    <td>Virtual bases and move-assignment</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr id="1807">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1807">1807</a></td>
+    <td>ready</td>
+    <td>Order of destruction of array elements after an exception</td>
+    <td class="none" align="center">Unknown</td>
+  </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>Disambiguating <I>original-namespace-definition</I> and <I>extension-namespace-definition</I></td>
+    <td>Constructor templates vs default constructors</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr id="1809">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1809">1809</a></td>
+    <td>ready</td>
+    <td>Narrowing and template argument deduction</td>
+    <td class="none" align="center">Unknown</td>
+  </tr>
+  <tr class="open" id="1810">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1810">1810</a></td>
+    <td>review</td>
+    <td>Invalid <I>ud-suffix</I>es</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr id="1811">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1811">1811</a></td>
+    <td>tentatively ready</td>
+    <td>Lookup of deallocation function in a virtual destructor definition</td>
+    <td class="none" align="center">Unknown</td>
+  </tr>
+  <tr id="1812">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1812">1812</a></td>
+    <td>ready</td>
+    <td>Omission of <TT>template</TT> in a <I>typename-specifier</I></td>
+    <td class="none" align="center">Unknown</td>
+  </tr>
+  <tr class="open" id="1813">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1813">1813</a></td>
+    <td>drafting</td>
+    <td>Direct vs indirect bases in standard-layout classes</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr id="1814">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1814">1814</a></td>
+    <td>ready</td>
+    <td>Default arguments in <I>lambda-expression</I>s</td>
+    <td class="none" align="center">Unknown</td>
+  </tr>
+  <tr class="open" id="1815">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1815">1815</a></td>
+    <td>drafting</td>
+    <td>Lifetime extension in aggregate initialization</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr id="1816">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1816">1816</a></td>
+    <td>ready</td>
+    <td>Unclear specification of bit-field values</td>
+    <td class="none" align="center">Unknown</td>
+  </tr>
+  <tr id="1817">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1817">1817</a></td>
+    <td>ready</td>
+    <td>Linkage specifications and nested scopes</td>
+    <td class="none" align="center">Unknown</td>
+  </tr>
+  <tr class="open" id="1818">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1818">1818</a></td>
+    <td>open</td>
+    <td>Visibility and inherited language linkage</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1819">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1819">1819</a></td>
+    <td>review</td>
+    <td>Acceptable scopes for definition of partial specialization</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1820">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1820">1820</a></td>
+    <td>open</td>
+    <td>Qualified typedef names</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1821">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1821">1821</a></td>
+    <td>open</td>
+    <td>Qualified redeclarations in a class <I>member-specification</I></td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1822">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1822">1822</a></td>
+    <td>open</td>
+    <td>Lookup of parameter names in <I>lambda-expression</I>s</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1823">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1823">1823</a></td>
+    <td>review</td>
+    <td>String literal uniqueness in inline functions</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr id="1824">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1824">1824</a></td>
+    <td>ready</td>
+    <td>Completeness of return type vs point of instantiation</td>
+    <td class="none" align="center">Unknown</td>
+  </tr>
+  <tr class="open" 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>Partial ordering between variadic and non-variadic function templates</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1826">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1826">1826</a></td>
+    <td>extension</td>
+    <td><TT>const</TT> floating-point in constant expressions</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1827">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1827">1827</a></td>
+    <td>drafting</td>
+    <td>Reference binding with ambiguous conversions</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1828">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1828">1828</a></td>
+    <td>drafting</td>
+    <td><I>nested-name-specifier</I> ambiguity</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1829">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1829">1829</a></td>
+    <td>open</td>
+    <td>Dependent unnamed types</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr id="1830">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1830">1830</a></td>
+    <td>ready</td>
+    <td>Repeated specifiers</td>
+    <td class="none" align="center">Unknown</td>
+  </tr>
+  <tr id="1831">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1831">1831</a></td>
+    <td>NAD</td>
+    <td>Explicitly vs implicitly deleted move constructors</td>
+    <td class="none" align="center">Unknown</td>
+  </tr>
+  <tr id="1832">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1832">1832</a></td>
+    <td>ready</td>
+    <td>Casting to incomplete enumeration</td>
+    <td class="none" align="center">Unknown</td>
+  </tr>
+  <tr class="open" id="1833">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1833">1833</a></td>
+    <td>extension</td>
+    <td><TT>friend</TT> declarations naming implicitly-declared member functions</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr id="1834">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1834">1834</a></td>
+    <td>ready</td>
+    <td>Constant initialization binding a reference to an xvalue</td>
+    <td class="none" align="center">Unknown</td>
+  </tr>
+  <tr class="open" id="1835">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1835">1835</a></td>
+    <td>drafting</td>
+    <td>Dependent member lookup before <TT>&lt;</TT></td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1836">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1836">1836</a></td>
+    <td>drafting</td>
+    <td>Use of class type being defined in <I>trailing-return-type</I></td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1837">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1837">1837</a></td>
+    <td>drafting</td>
+    <td>Use of <TT>this</TT> in <TT>friend</TT> and local class declarations</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1838">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1838">1838</a></td>
+    <td>drafting</td>
+    <td>Definition via <I>unqualified-id</I> and <I>using-declaration</I></td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1839">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1839">1839</a></td>
+    <td>drafting</td>
+    <td>Lookup of block-scope <TT>extern</TT> declarations</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1840">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1840">1840</a></td>
+    <td>drafting</td>
+    <td>Non-deleted explicit specialization of deleted function template</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1841">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1841">1841</a></td>
+    <td>drafting</td>
+    <td><TT>&lt;</TT> following template injected-class-name</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1842">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1842">1842</a></td>
+    <td>concurrency</td>
+    <td>Unevaluated operands and &#8220;carries a dependency&#8221;</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr id="1843">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1843">1843</a></td>
+    <td>ready</td>
+    <td>Bit-field in conditional operator with <TT>throw</TT> operand</td>
+    <td class="none" align="center">Unknown</td>
+  </tr>
+  <tr class="open" id="1844">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1844">1844</a></td>
+    <td>drafting</td>
+    <td>Defining &#8220;immediate context&#8221;</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1845">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1845">1845</a></td>
+    <td>drafting</td>
+    <td>Point of instantiation of a variable template specialization</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1846">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1846">1846</a></td>
+    <td>review</td>
+    <td>Declaring explicitly-defaulted implicitly-deleted functions</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1847">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1847">1847</a></td>
+    <td>drafting</td>
+    <td>Clarifying compatibility during partial ordering</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1848">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1848">1848</a></td>
+    <td>open</td>
+    <td>Parenthesized constructor and destructor declarators</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1849">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1849">1849</a></td>
+    <td>drafting</td>
+    <td>Variable templates and the ODR</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr id="1850">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1850">1850</a></td>
+    <td>ready</td>
+    <td>Differences between definition context and point of instantiation</td>
+    <td class="none" align="center">Unknown</td>
+  </tr>
+  <tr id="1851">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1851">1851</a></td>
+    <td>ready</td>
+    <td><TT>decltype(auto)</TT> in <I>new-expression</I>s</td>
+    <td class="none" align="center">Unknown</td>
+  </tr>
+  <tr id="1852">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1852">1852</a></td>
+    <td>ready</td>
+    <td>Wording issues regarding <TT>decltype(auto)</TT></td>
+    <td class="none" align="center">Unknown</td>
+  </tr>
+  <tr class="open" id="1853">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1853">1853</a></td>
+    <td>drafting</td>
+    <td>Defining &#8220;allocated storage&#8221;</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1854">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1854">1854</a></td>
+    <td>open</td>
+    <td>Disallowing use of implicitly-deleted functions</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1855">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1855">1855</a></td>
+    <td>open</td>
+    <td>Out-of-lifetime access to nonstatic data members</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1856">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1856">1856</a></td>
+    <td>open</td>
+    <td>Indirect nested classes of class templates</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1857">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1857">1857</a></td>
+    <td>open</td>
+    <td>Additional questions about bits</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1858">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1858">1858</a></td>
+    <td>open</td>
+    <td>Comparing pointers to union members</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1859">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1859">1859</a></td>
+    <td>open</td>
+    <td>UTF-16 in <TT>char16_t</TT> string literals</td>
+    <td align="center">Not resolved</td>
+  </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>open</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>open</td>
+    <td>Values of a bit-field</td>
+    <td align="center">Not resolved</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>
+    <td>open</td>
+    <td>Determining &#8220;corresponding members&#8221; for friendship</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1863">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1863">1863</a></td>
+    <td>open</td>
+    <td>Requirements on thrown object type to support <TT>std::current_exception()</TT></td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1864">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1864">1864</a></td>
+    <td>open</td>
+    <td>List-initialization of array objects</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1865">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1865">1865</a></td>
+    <td>open</td>
+    <td>Pointer arithmetic and multi-level qualification conversions</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1866">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1866">1866</a></td>
+    <td>open</td>
+    <td>Initializing variant members with non-trivial destructors</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1867">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1867">1867</a></td>
+    <td>open</td>
+    <td>Function/expression ambiguity with qualified parameter name</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1868">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1868">1868</a></td>
+    <td>open</td>
+    <td>Meaning of &#8220;placeholder type&#8221;</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1869">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1869">1869</a></td>
+    <td>open</td>
+    <td><TT>thread_local</TT> vs <I>linkage-specification</I>s</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1870">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1870">1870</a></td>
+    <td>open</td>
+    <td>Contradictory wording about definitions vs explicit specialization/instantiation</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1871">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1871">1871</a></td>
+    <td>open</td>
+    <td>Non-identifier characters in <I>ud-suffix</I></td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1872">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1872">1872</a></td>
+    <td>open</td>
+    <td>Instantiations of <TT>constexpr</TT> templates that cannot appear in constant expressions</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1873">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1873">1873</a></td>
+    <td>open</td>
+    <td>Protected member access from derived class friends</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1874">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1874">1874</a></td>
+    <td>open</td>
+    <td>Type vs non-type template parameters with <TT>class</TT> keyword</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1875">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1875">1875</a></td>
+    <td>open</td>
+    <td>Reordering declarations in class scope</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1876">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1876">1876</a></td>
+    <td>open</td>
+    <td>Preventing explicit specialization</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1877">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1877">1877</a></td>
+    <td>open</td>
+    <td>Return type deduction from <TT>return</TT> with no operand</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1878">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1878">1878</a></td>
+    <td>open</td>
+    <td><TT>operator auto</TT> template</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1879">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1879">1879</a></td>
+    <td>open</td>
+    <td>Inadequate definition of alignment requirement</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1880">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1880">1880</a></td>
+    <td>open</td>
+    <td>When are parameter objects destroyed?</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1881">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1881">1881</a></td>
+    <td>open</td>
+    <td>Standard-layout classes and unnamed bit-fields</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1882">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1882">1882</a></td>
+    <td>open</td>
+    <td>Reserved names without library use</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1883">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1883">1883</a></td>
+    <td>open</td>
+    <td>Protected access to constructors in <I>mem-initializer</I>s</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1884">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1884">1884</a></td>
+    <td>open</td>
+    <td>Unclear requirements for same-named external-linkage entities</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1885">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1885">1885</a></td>
+    <td>open</td>
+    <td>Return value of a function is underspecified</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1886">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1886">1886</a></td>
+    <td>open</td>
+    <td>Language linkage for <TT>main()</TT></td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1887">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1887">1887</a></td>
+    <td>open</td>
+    <td>Problems with <TT>::</TT> as <I>nested-name-specifier</I></td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1888">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1888">1888</a></td>
+    <td>open</td>
+    <td>Implicitly-declared default constructors and <TT>explicit</TT></td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1889">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1889">1889</a></td>
+    <td>open</td>
+    <td>Unclear effect of <TT>#pragma</TT> on conformance</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1890">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1890">1890</a></td>
+    <td>open</td>
+    <td>Member type depending on definition of member function</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1891">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1891">1891</a></td>
+    <td>open</td>
+    <td>Move constructor/assignment for closure class</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1892">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1892">1892</a></td>
+    <td>open</td>
+    <td>Use of <TT>auto</TT> in function type</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1893">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1893">1893</a></td>
+    <td>open</td>
+    <td>Function-syle cast with <I>braced-init-list</I>s and empty pack expansions</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1894">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1894">1894</a></td>
+    <td>open</td>
+    <td><I>typedef-name</I>s and <I>using-declaration</I>s</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1895">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1895">1895</a></td>
+    <td>open</td>
+    <td>Deleted conversions in conditional operator operands</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1896">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1896">1896</a></td>
+    <td>open</td>
+    <td>Repeated alias templates</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1897">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1897">1897</a></td>
+    <td>open</td>
+    <td>ODR vs alternative tokens</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1898">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1898">1898</a></td>
+    <td>open</td>
+    <td>Use of &#8220;equivalent&#8221; in overload resolution</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1899">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1899">1899</a></td>
+    <td>open</td>
+    <td>Value-dependent constant expressions</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1900">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1900">1900</a></td>
+    <td>open</td>
+    <td>Do <TT>friend</TT> declarations count as &#8220;previous declarations&#8221;?</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1901">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1901">1901</a></td>
+    <td>open</td>
+    <td><I>punctuator</I> referenced but not defined</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1902">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1902">1902</a></td>
+    <td>open</td>
+    <td>What makes a conversion &#8220;otherwise ill-formed&#8221;?</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1903">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1903">1903</a></td>
+    <td>open</td>
+    <td>What declarations are introduced by a non-member <I>using-declaration</I>?</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1904">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1904">1904</a></td>
+    <td>open</td>
+    <td>Default template arguments for members of class templates</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1905">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1905">1905</a></td>
+    <td>open</td>
+    <td>Dependent types and injected-class-names</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1906">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1906">1906</a></td>
+    <td>open</td>
+    <td>Name lookup in member <TT>friend</TT> declaration</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1907">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1907">1907</a></td>
+    <td>open</td>
+    <td><I>using-declaration</I>s and default arguments</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1908">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1908">1908</a></td>
+    <td>open</td>
+    <td>Dual destructor lookup and <I>template-id</I>s</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1909">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1909">1909</a></td>
+    <td>open</td>
+    <td>Member class template with the same name as the class</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1910">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1910">1910</a></td>
+    <td>open</td>
+    <td>&#8220;Shall&#8221; requirement applied to runtime behavior</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1911">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1911">1911</a></td>
+    <td>open</td>
+    <td><TT>constexpr</TT> constructor with non-literal base class</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1912">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1912">1912</a></td>
+    <td>open</td>
+    <td><I>exception-specification</I> of defaulted function</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1913">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1913">1913</a></td>
+    <td>open</td>
+    <td><TT>decltype((x))</TT> in <I>lambda-expression</I>s</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1914">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1914">1914</a></td>
+    <td>open</td>
+    <td>Duplicate standard attributes</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1915">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1915">1915</a></td>
+    <td>open</td>
+    <td>Potentially-invoked destructors in non-throwing constructors</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1916">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1916">1916</a></td>
+    <td>open</td>
+    <td>&#8220;Same cv-unqualified type&#8221;</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1917">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1917">1917</a></td>
+    <td>open</td>
+    <td>decltype-qualified enumeration names</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1918">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1918">1918</a></td>
+    <td>open</td>
+    <td><TT>friend</TT> templates with dependent scopes</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1919">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1919">1919</a></td>
+    <td>open</td>
+    <td>Overload resolution for <TT>!</TT> with explicit conversion operator</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1920">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1920">1920</a></td>
+    <td>open</td>
+    <td>Qualification mismatch in <I>pseudo-destructor-name</I></td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1921">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1921">1921</a></td>
+    <td>open</td>
+    <td><TT>constexpr</TT> constructors and point of initialization of <TT>const</TT> variables</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1922">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1922">1922</a></td>
+    <td>open</td>
+    <td>Injected class template names and default arguments</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1923">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1923">1923</a></td>
+    <td>open</td>
+    <td>Lvalues of type <TT>void</TT></td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1924">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1924">1924</a></td>
+    <td>open</td>
+    <td>Definition of &#8220;literal&#8221; and kinds of literals</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1925">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1925">1925</a></td>
+    <td>open</td>
+    <td>Bit-field prvalues</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1926">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1926">1926</a></td>
+    <td>open</td>
+    <td>Potential results of subscript operator</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1927">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1927">1927</a></td>
+    <td>open</td>
+    <td>Lifetime of temporaries in <I>init-capture</I>s</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1928">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1928">1928</a></td>
+    <td>open</td>
+    <td>Triviality of deleted special member functions</td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1929">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1929">1929</a></td>
+    <td>open</td>
+    <td><TT>template</TT> keyword following namespace <I>nested-name-specifier</I></td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1930">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1930">1930</a></td>
+    <td>open</td>
+    <td><I>init-declarator-list</I> vs <I>member-declarator-list</I></td>
+    <td align="center">Not resolved</td>
+  </tr>
+  <tr class="open" id="1931">
+    <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1931">1931</a></td>
+    <td>open</td>
+    <td>Default-constructible and copy-assignable closure types</td>
     <td align="center">Not resolved</td>
   </tr>
 </table>
diff --git a/www/cxx_status.html b/www/cxx_status.html
index b0eccee..f2ab072 100644
--- a/www/cxx_status.html
+++ b/www/cxx_status.html
@@ -3,7 +3,7 @@
 <html>
 <head>
   <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
-  <title>Clang - C++98, C++11, and C++14 Status</title>
+  <title>Clang - C++1z, C++14, C++11 and C++98 Status</title>
   <link type="text/css" rel="stylesheet" href="menu.css">
   <link type="text/css" rel="stylesheet" href="content.css">
   <style type="text/css">
@@ -23,22 +23,38 @@
 <div id="content">
 
 <!--*************************************************************************-->
-<h1>C++98, C++11, and C++14 Support in Clang</h1>
+<h1>C++ Support in Clang</h1>
 <!--*************************************************************************-->
 <p>Last updated: $Date$</p>
 
+<p>Clang fully implements all published ISO C++ standards including <a
+href="#cxx11">C++11</a>, as well as the upcoming standard provisionally named <a
+href="#cxx14">C++14</a>, and some parts of the fledgling <a
+href="#cxx17">C++1z</a> standard,
+and is considered a production-quality C++ compiler.
+
+<p>The Clang community is continually striving to improve C++ standards
+compliance between releases by submitting and tracking <a
+href="cxx_dr_status.html">C++ Defect Reports</a> and implementing resolutions
+as they become available.</p>
+
+<p>Experimental work is also under way to implement <a href="#ts">C++ Technical
+Specifications</a> that will help drive the future of the C++ programming
+language.</p>
+
+<p>The <a href="http://llvm.org/bugs/">LLVM bug tracker</a> contains Clang
+C++ components that track known bugs with Clang's language conformance in
+each language mode.</p>
+
 <h2 id="cxx98">C++98 implementation status</h2>
 
-<p>Clang currently implements all of the ISO C++ 1998 standard
+<p>Clang implements all of the ISO C++ 1998 standard
   (including the defects addressed in the ISO C++ 2003 standard)
-  except for <tt>export</tt> (which has been removed in C++11)
-  and is considered a production-quality C++ compiler.  The <a
-   href="http://llvm.org/bugs/">LLVM bug tracker</a> contains a Clang
-  C++ component that tracks known Clang C++ bugs.</p>
+  except for <tt>export</tt> (which was removed in C++11).
 
 <h2 id="cxx11">C++11 implementation status</h2>
 
-  <p>Clang implements all of the <a
+  <p>Clang 3.3 and later implement all of the <a
     href="http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=50372">ISO
     C++ 2011 standard</a>. The following table describes the Clang version
   in which each feature became available.</p>
@@ -52,7 +68,7 @@
 <a href="libstdc++4.6-clang11.patch">libstdc++-4.6</a>
 and <a href="libstdc++4.7-clang11.patch">libstdc++-4.7</a> work with Clang
 releases prior to version 3.2 in C++11 mode. <tt>thread_local</tt> support
-currently requires g++-4.8's C++ runtime library.</p>
+currently requires the C++ runtime library from g++-4.8 or later.</p>
 
 <table width="689" border="1" cellspacing="0">
  <tr>
@@ -177,7 +193,7 @@
       <td class="full" align="center">Clang 3.1</td>
     </tr>
     <tr>
-      <td>Generalized attributes</td>
+      <td>Standardized attribute syntax</td>
       <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2761.pdf">N2761</a></td>
       <td class="full" align="center">Clang 3.3 <a href="#n2761">(1)</a></td>
     </tr>
@@ -191,8 +207,16 @@
       <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2341.pdf">N2341</a></td>
       <td class="full" align="center">Clang 3.3</td>
     </tr>
-    <!-- Skipped N1627: Conditionally-support behavior -->
-    <!-- Skipped N1727: Changing Undefined Behavior into Diagnosable Errors -->
+    <tr>
+      <td>Conditionally-support behavior</td>
+      <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1627.pdf">N1627</a></td>
+      <td class="full" align="center">Clang 2.9</td>
+    </tr>
+    <tr>
+      <td>Changing undefined behavior into diagnosable errors</td>
+      <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1727.pdf">N1727</a></td>
+      <td class="full" align="center">Clang 2.9</td>
+    </tr>
     <tr>
       <td>Delegating constructors</td>
       <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1986.pdf">N1986</a></td>
@@ -289,7 +313,7 @@
     <tr>
       <td>Minimal support for garbage collection and reachability-based leak detection</td>
       <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2670.htm">N2670</a></td>
-      <td class="na" align="center">N/A</td>
+      <td class="na" align="center">N/A <a href="#n2670">(2)</a></td>
     </tr>
     <tr>
       <td>Allowing move constructors to throw [noexcept]</td>
@@ -318,7 +342,7 @@
     <tr>
       <td>Strong Compare and Exchange</td>
       <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2748.html">N2748</a></td>
-      <td class="full" align="center">Clang 3.1 <a href="#n2748">(2)</a></td>
+      <td class="full" align="center">Clang 3.1 <a href="#n2748">(3)</a></td>
     </tr>
     <tr>
       <td>Bidirectional Fences</td>
@@ -334,7 +358,7 @@
     <tr>
       <td>Data-dependency ordering: atomics and memory model</td>
       <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2664.htm">N2664</a></td>
-      <td class="full" align="center">Clang 3.2 <a href="#n2664">(3)</a></td>
+      <td class="full" align="center">Clang 3.2 <a href="#n2664">(4)</a></td>
     </tr>
     <tr>
       <td>Propagating exceptions</td>
@@ -342,11 +366,6 @@
       <td class="full" align="center">Clang 2.9</td>
     </tr>
     <tr>
-      <td>Abandoning a process and at_quick_exit</td>
-      <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2440.htm">N2440</a></td>
-      <td class="na" align="center">N/A</td>
-    </tr>
-    <tr>
       <td>Allow atomics use in signal handlers</td>
       <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2547.htm">N2547</a></td>
       <td class="full" align="center">Clang 3.1</td>
@@ -383,26 +402,31 @@
     <tr>
       <td>Extended integral types</td>
       <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1988.pdf">N1988</a></td>
-      <td class="na" align="center">N/A <a href="#n1988">(4)</a></td>
+      <td class="na" align="center">N/A <a href="#n1988">(5)</a></td>
     </tr>
 </table>
 
 <p>
 <span id="n2761">(1): The <code>[[carries_dependency]]</code> attribute
 has no effect.</span><br>
-<span id="n2748">(2): All compare-exchange operations are emitted as
+<span id="n2670">(2): No compiler changes are required for an implementation
+such as Clang that does not provide garbage collection.</span><br>
+<span id="n2748">(3): All compare-exchange operations are emitted as
 strong compare-exchanges.</span><br>
-<span id="n2664">(3): <code>memory_order_consume</code> is lowered to
+<span id="n2664">(4): <code>memory_order_consume</code> is lowered to
 <code>memory_order_acquire</code>.</span><br>
-<span id="n1988">(4): <code>__int128</code> is not treated as an extended
-integer type, because changing <code>intmax_t</code> would be an
-ABI-incompatible change.</span>
+<span id="n1988">(5): No compiler changes are required for an implementation
+such as Clang that does not provide any extended integer types.
+<code>__int128</code> is not treated as an extended integer type,
+because changing <code>intmax_t</code> would be an ABI-incompatible
+change.</span>
 </p>
 
 <h2 id="cxx14">C++1y implementation status</h2>
 
-<p>Clang implements all of the
-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.pdf">current draft</a>
+<p>Clang 3.4 and later implement all of the Draft International Standard (see <a
+href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.pdf">most
+recent publicly available draft</a>)
 of the upcoming C++ language standard, provisionally named C++1y.  The following
 table describes the Clang version in which each feature became available.</p>
 
@@ -417,7 +441,7 @@
     <tr>
       <td>Tweak to certain C++ contextual conversions</td>
       <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3323.pdf">N3323</a></td>
-      <td class="svn" align="center">SVN</td>
+      <td class="full" align="center">Clang 3.4</td>
     </tr>
     <tr>
       <td>Binary literals</td>
@@ -431,27 +455,27 @@
     </tr>
     <tr>
       <td>Return type deduction for normal functions</td>
-      <td class="svn" align="center">SVN</td>
+      <td class="full" align="center">Clang 3.4</td>
     </tr>
     <tr>
       <td>Initialized lambda captures</td>
       <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3648.html">N3648</a></td>
-      <td class="svn" align="center">SVN</td>
+      <td class="full" align="center">Clang 3.4</td>
     </tr>
     <tr>
       <td>Generic lambdas</td>
       <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3649.html">N3649</a></td>
-      <td class="svn" align="center">SVN</td>
+      <td class="full" align="center">Clang 3.4</td>
     </tr>
     <tr>
       <td>Variable templates</td>
       <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3651.pdf">N3651</a></td>
-      <td class="svn" align="center">SVN</td>
+      <td class="full" align="center">Clang 3.4</td>
     </tr>
     <tr>
       <td>Relaxing requirements on constexpr functions</td>
       <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3652.html">N3652</a></td>
-      <td class="svn" align="center">SVN</td>
+      <td class="full" align="center">Clang 3.4</td>
     </tr>
     <tr>
       <td>Member initializers and aggregates</td>
@@ -461,35 +485,100 @@
     <tr>
       <td>Clarifying memory allocation</td>
       <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3664.html">N3664</a></td>
-      <td class="svn" align="center">SVN</td>
+      <td class="full" align="center">Clang 3.4</td>
     </tr>
     <tr>
       <td><tt>[[deprecated]]</tt> attribute</td>
       <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3760.html">N3760</a></td>
-      <td class="svn" align="center">SVN</td>
+      <td class="full" align="center">Clang 3.4</td>
     </tr>
     <tr>
       <td>Single quotation mark as digit separator</td>
       <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3781.pdf">N3781</a></td>
-      <td class="svn" align="center">SVN</td>
+      <td class="full" align="center">Clang 3.4</td>
     </tr>
     <tr>
       <td>C++ Sized Deallocation</td>
       <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3778.html">N3778</a></td>
-      <td class="svn" align="center">SVN</td>
+      <td class="full" align="center">Clang 3.4</td>
     </tr>
 </table>
 
-<!--
 <h2 id="cxx17">C++1z implementation status</h2>
 
-<p>Clang implements none of the upcoming C++ language standard,
+<p>Clang has <b>highly experimental</b> support for some proposed features of
+the C++ standard following C++1y,
 provisionally named C++1z.  The following table describes which C++1z features
 have been implemented in Clang and in which Clang version they became
 available.</p>
 
+<p>Note that support for these features may change or be removed without notice,
+as the draft C++1z standard evolves.</p>
+
 <p>You can use Clang in C++1z mode with the <code>-std=c++1z</code> option.</p>
--->
+
+<table width="689" border="1" cellspacing="0">
+ <tr>
+    <th>Language Feature</th>
+    <th>C++1z Proposal</th>
+    <th>Available in Clang?</th>
+ </tr>
+    <tr>
+      <td><tt>static_assert</tt> with no message</td>
+      <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3928.pdf">N3928</a></td>
+      <td class="svn" align="center">SVN</td>
+    </tr>
+    <tr>
+      <td>Disabling trigraph expansion by default</td>
+      <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3981.html">N3981</a></td>
+      <td class="svn" align="center">SVN</td>
+    </tr>
+    <tr>
+      <td>Terse range-based for loops</td>
+      <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3994.htm">N3994</a></td>
+      <td class="svn" align="center">SVN</td>
+    </tr>
+    <tr>
+      <td><tt>typename</tt> in a template template parameter</td>
+      <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4051.html">N4051</a></td>
+      <td class="svn" align="center">SVN</td>
+    </tr>
+</table>
+
+<h2 id="ts">Technical specifications and standing documents</h2>
+
+<p>ISO C++ also publishes a number of documents describing additional language
+and library features that are not part of standard C++. The following table
+describes which language features have been implemented in Clang and in which
+Clang version they became available:</p>
+
+<table width="689" border="1" cellspacing="0">
+ <tr>
+    <th>Document</th>
+    <th>Latest draft</th>
+    <th>Available in Clang?</th>
+ </tr>
+    <tr>
+      <td>SD-6: SG10 feature test recommendations</td>
+      <td><a href="http://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations">SD-6</a></td>
+      <td class="full" align="center">Clang 3.4 (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3745">N3745</a>)</td>
+    </tr>
+    <tr>
+      <td>[DRAFT TS] Array extensions (arrays of runtime bound)</td>
+      <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3820.html">N3820</a></td>
+      <td class="none" align="center">No</td>
+    </tr>
+    <tr>
+      <td>[DRAFT TS] Library fundamentals (invocation type traits)</td>
+      <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3908.html">N3908</a></td>
+      <td class="none" align="center">No</td>
+    </tr>
+    <tr>
+      <td>[DRAFT TS] Concepts</td>
+      <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3929.pdf">N3929</a></td>
+      <td class="none" align="center">No</td>
+    </tr>
+</table>
 
 </div>
 </body>
diff --git a/www/diagnostics.html b/www/diagnostics.html
index bd9a89d..00a3f9a 100644
--- a/www/diagnostics.html
+++ b/www/diagnostics.html
@@ -7,10 +7,14 @@
   <link type="text/css" rel="stylesheet" href="menu.css">
   <link type="text/css" rel="stylesheet" href="content.css">
   <style type="text/css">
-  .warn { color:magenta; }
-  .err { color:red; }
-  .snip { color:darkgreen; }
-  .point { color:blue; }
+  .loc { font-weight: bold; }
+  .err { color:red; font-weight: bold; }
+  .warn { color:magenta; font-weight: bold; }
+  .note { color:gray; font-weight: bold; }
+  .msg { font-weight: bold; }
+  .cmd { font-style: italic; }
+  .snip { }
+  .point { color:green; font-weight: bold; }
   </style>
 </head>
 <body>
@@ -29,10 +33,7 @@
 making the diagnostics (error and warning messages) generated by the compiler
 be as useful as possible.  There are several ways that we do this.  This section
 talks about the experience provided by the command line compiler, contrasting
-Clang output to GCC 4.2's output in several examples.
-<!--
-Other clients
-that embed Clang and extract equivalent information through internal APIs.-->
+Clang output to GCC 4.9's output in some cases.
 </p>
 
 <h2>Column Numbers and Caret Diagnostics</h2>
@@ -41,25 +42,35 @@
 information. The clang command-line compiler driver uses this information
 to print "point diagnostics".
 (IDEs can use the information to display in-line error markup.)
-Precise error location in the source is a feature provided by many commercial
-compilers, but is generally missing from open source
-compilers.  This is nice because it makes it very easy to understand exactly
-what is wrong in a particular piece of code</p>
+This is nice because it makes it very easy to understand exactly
+what is wrong in a particular piece of code.</p>
 
-<p>The point (the blue "^" character) exactly shows where the problem is, even
+<p>The point (the green "^" character) exactly shows where the problem is, even
 inside of a string.  This makes it really easy to jump to the problem and
-helps when multiple instances of the same character occur on a line. (We'll 
+helps when multiple instances of the same character occur on a line. (We'll
 revisit this more in following examples.)</p>
 
 <pre>
-  $ <b>gcc-4.2 -fsyntax-only -Wformat format-strings.c</b>
-  format-strings.c:91: warning: too few arguments for format
-  $ <b>clang -fsyntax-only format-strings.c</b>
-  format-strings.c:91:13: <span class="warn">warning:</span> '.*' specified field precision is missing a matching 'int' argument
-  <span class="snip">  printf("%.*d");</span>
+  $ <span class="cmd">gcc-4.9 -fsyntax-only -Wformat format-strings.c</span>
+  format-strings.c: In function 'void f()':
+  format-strings.c:91:16: warning: field precision specifier '.*' expects a matching 'int' argument [-Wformat=]
+     printf("%.*d");
+                  ^
+  format-strings.c:91:16: warning: format '%d' expects a matching 'int' argument [-Wformat=]
+  $ <span class="cmd">clang -fsyntax-only format-strings.c</span>
+  <span class="loc">format-strings.c:91:13:</span> <span class="warn">warning:</span> <span class="msg">'.*' specified field precision is missing a matching 'int' argument</span>
+  <span class="snip" >  printf("%.*d");</span>
   <span class="point">            ^</span>
 </pre>
 
+<p>Note that modern versions of GCC have followed Clang's lead, and are
+now able to give a column for a diagnostic, and include a snippet of source
+text in the result. However, Clang's column number is much more accurate,
+pointing at the problematic format specifier, rather than the <tt>)</tt>
+character the parser had reached when the problem was detected.
+Also, Clang's diagnostic is colored by default, making it easier to
+distinguish from nearby text.</p>
+
 <h2>Range Highlighting for Related Text</h2>
 
 <p>Clang captures and accurately tracks range information for expressions,
@@ -74,11 +85,14 @@
 cases involving precedence issues and many other cases.</p>
 
 <pre>
-  $ <b>gcc-4.2 -fsyntax-only t.c</b>
-  t.c:7: error: invalid operands to binary + (have 'int' and 'struct A')
-  $ <b>clang -fsyntax-only t.c</b>
-  t.c:7:39: <span class="err">error:</span> invalid operands to binary expression ('int' and 'struct A')
-  <span class="snip">  return y + func(y ? ((SomeA.X + 40) + SomeA) / 42 + SomeA.X : SomeA.X);</span>
+  $ <span class="cmd">gcc-4.9 -fsyntax-only t.c</span>
+  t.c: In function 'int f(int, int)':
+  t.c:7:39: error: invalid operands to binary + (have 'int' and 'struct A')
+     return y + func(y ? ((SomeA.X + 40) + SomeA) / 42 + SomeA.X : SomeA.X);
+                                         ^
+  $ <span class="cmd">clang -fsyntax-only t.c</span>
+  <span class="loc">t.c:7:39:</span> <span class="err">error:</span> <span class="msg">invalid operands to binary expression ('int' and 'struct A')</span>
+  <span class="snip" >  return y + func(y ? ((SomeA.X + 40) + SomeA) / 42 + SomeA.X : SomeA.X);</span>
   <span class="point">                       ~~~~~~~~~~~~~~ ^ ~~~~~</span>
 </pre>
 
@@ -90,62 +104,24 @@
 the left and right hand sides, and we don't repeat what is obvious from the
 point (e.g., that this is a "binary +").</p>
 
-<p>Many other examples abound. In the following example, not only do we tell you that there is a problem with the *
+<p>Many other examples abound. In the following example, not only do we tell you
+that there is a problem with the <tt>*</tt>
 and point to it, we say exactly why and tell you what the type is (in case it is
 a complicated subexpression, such as a call to an overloaded function).  This
 sort of attention to detail makes it much easier to understand and fix problems
 quickly.</p>
 
 <pre>
-  $ <b>gcc-4.2 -fsyntax-only t.c</b>
-  t.c:5: error: invalid type argument of 'unary *'
-  $ <b>clang -fsyntax-only t.c</b>
-  t.c:5:11: <span class="err">error:</span> indirection requires pointer operand ('int' invalid)
-  <span class="snip">  int y = *SomeA.X;</span>
+  $ <span class="cmd">gcc-4.9 -fsyntax-only t.c</span>
+  t.c:5:11: error: invalid type argument of unary '*' (have 'int')
+    return *SomeA.X;
+           ^
+  $ <span class="cmd">clang -fsyntax-only t.c</span>
+  <span class="loc">t.c:5:11:</span> <span class="err">error:</span> <span class="msg">indirection requires pointer operand ('int' invalid)</span>
+  <span class="snip" >  int y = *SomeA.X;</span>
   <span class="point">          ^~~~~~~~</span>
 </pre>
 
-<h2>No Pretty Printing of Expressions in Diagnostics</h2>
-
-<p>Since Clang has range highlighting, it never needs to pretty print your code
-back out to you.  GCC can produce inscrutible error messages in some cases when
-it tries to do this.  In this example P and Q have type "int*":</p>
-
-<pre>
-  $ <b>gcc-4.2 -fsyntax-only t.c</b>
-  #'exact_div_expr' not supported by pp_c_expression#'t.c:12: error: called object  is not a function
-  $ <b>clang -fsyntax-only t.c</b>
-  t.c:12:8: <span class="err">error:</span> called object type 'int' is not a function or function pointer
-  <span class="snip">  (P-Q)();</span>
-  <span class="point">  ~~~~~^</span>
-</pre>
-
-<p>This can be particularly bad in G++, which often emits errors
-   containing lowered vtable references.  For example:</p>
-  
-<pre>
-  $ <b>cat t.cc</b>
-  struct a {
-    virtual int bar();
-  };
-  
-  struct foo : public virtual a {
-  };
-  
-  void test(foo *P) {
-    return P->bar() + *P;
-  }
-  $ <b>gcc-4.2 t.cc</b>
-  t.cc: In function 'void test(foo*)':
-  t.cc:9: error: no match for 'operator+' in '(((a*)P) + (*(long int*)(P-&gt;foo::&lt;anonymous&gt;.a::_vptr$a + -0x00000000000000020)))-&gt;a::bar() + * P'
-  t.cc:9: error: return-statement with a value, in function returning 'void'
-  $ <b>clang t.cc</b>
-  t.cc:9:18: <span class="err">error:</span> invalid operands to binary expression ('int' and 'foo')
-  <span class="snip">  return P->bar() + *P;</span>
-  <span class="point">         ~~~~~~~~ ^ ~~</span>
-</pre>
-  
-
 <h2>Typedef Preservation and Selective Unwrapping</h2>
 
 <p>Many programmers use high-level user defined types, typedefs, and other
@@ -156,15 +132,11 @@
 is going on.  Clang aims to handle both cases well.<p>
 
 <p>The following example shows where it is important to preserve
-a typedef in C. Here the type printed by GCC isn't even valid, but if the error
-were about a very long and complicated type (as often happens in C++) the error
-message would be ugly just because it was long and hard to read.</p>
+a typedef in C.</p>
 
 <pre>
-  $ <b>gcc-4.2 -fsyntax-only t.c</b>
-  t.c:15: error: invalid operands to binary / (have 'float __vector__' and 'const int *')
-  $ <b>clang -fsyntax-only t.c</b>
-  t.c:15:11: <span class="err">error:</span> can't convert between vector values of different size ('__m128' and 'int const *')
+  $ <span class="cmd">clang -fsyntax-only t.c</span>
+  <span class="loc">t.c:15:11:</span> <span class="err">error:</span> <span class="msg">can't convert between vector values of different size ('__m128' and 'int const *')</span>
   <span class="snip">  myvec[1]/P;</span>
   <span class="point">  ~~~~~~~~^~</span>
 </pre>
@@ -174,10 +146,8 @@
 system "pid_t" typedef is defined, Clang helpfully displays it with "aka".</p>
 
 <pre>
-  $ <b>gcc-4.2 -fsyntax-only t.c</b>
-  t.c:13: error: request for member 'x' in something not a structure or union
-  $ <b>clang -fsyntax-only t.c</b>
-  t.c:13:9: <span class="err">error:</span> member reference base type 'pid_t' (aka 'int') is not a structure or union
+  $ <span class="cmd">clang -fsyntax-only t.c</span>
+  <span class="loc">t.c:13:9:</span> <span class="err">error:</span> <span class="msg">member reference base type 'pid_t' (aka 'int') is not a structure or union</span>
   <span class="snip">  myvar = myvar.x;</span>
   <span class="point">          ~~~~~ ^</span>
 </pre>
@@ -202,13 +172,11 @@
 </pre>
 </blockquote>
 
-<p>and then compile it, we see that Clang is both providing more accurate information and is retaining the types as written by the user (e.g., "servers::Server", "::services::WebService"):
+<p>and then compile it, we see that Clang is both providing accurate information and is retaining the types as written by the user (e.g., "servers::Server", "::services::WebService"):
 
 <pre>
-  $ <b>g++-4.2 -fsyntax-only t.cpp</b>
-  t.cpp:9: error: no match for 'operator+=' in 'server += http'
-  $ <b>clang -fsyntax-only t.cpp</b>
-  t.cpp:9:10: <span class="err">error:</span> invalid operands to binary expression ('servers::Server const' and '::services::WebService const *')
+  $ <span class="cmd">clang -fsyntax-only t.cpp</span>
+  <span class="loc">t.cpp:9:10:</span> <span class="err">error:</span> <span class="msg">invalid operands to binary expression ('servers::Server const' and '::services::WebService const *')</span>
     <span class="snip">server += http;</span>
     <span class="point">~~~~~~ ^  ~~~~</span>
 </pre>
@@ -216,10 +184,8 @@
 <p>Naturally, type preservation extends to uses of templates, and Clang retains information about how a particular template specialization (like <code>std::vector&lt;Real&gt;</code>) was spelled within the source code. For example:</p>
 
 <pre>
-  $ <b>g++-4.2 -fsyntax-only t.cpp</b>
-  t.cpp:12: error: no match for 'operator=' in 'str = vec'
-  $ <b>clang -fsyntax-only t.cpp</b>
-  t.cpp:12:7: <span class="err">error:</span> incompatible type assigning 'vector&lt;Real&gt;', expected 'std::string' (aka 'class std::basic_string&lt;char&gt;')
+  $ <span class="cmd">clang -fsyntax-only t.cpp</span>
+  <span class="loc">t.cpp:12:7:</span> <span class="err">error:</span> <span class="msg">incompatible type assigning 'vector&lt;Real&gt;', expected 'std::string' (aka 'class std::basic_string&lt;char&gt;')</span>
     <span class="snip">str = vec</span>;
         <span class="point">^ ~~~</span>
 </pre>
@@ -237,14 +203,14 @@
 point line (".x =" or ".y =", respectively).</p>
 
 <pre>
-  $ <b>clang t.c</b>
-  t.c:5:28: <span class="warn">warning:</span> use of GNU old-style field designator extension
+  $ <span class="cmd">clang t.c</span>
+  <span class="loc">t.c:5:28:</span> <span class="warn">warning:</span> <span class="msg">use of GNU old-style field designator extension</span>
   <span class="snip">struct point origin = { x: 0.0, y: 0.0 };</span>
-                          <span class="err">~~</span> <span class="point">^</span>
+                          <span class="err">~~</span> <span class="msg"><span class="point">^</span></span>
                           <span class="snip">.x = </span>
-  t.c:5:36: <span class="warn">warning:</span> use of GNU old-style field designator extension
+  <span class="loc">t.c:5:36:</span> <span class="warn">warning:</span> <span class="msg">use of GNU old-style field designator extension</span>
   <span class="snip">struct point origin = { x: 0.0, y: 0.0 };</span>
-                                  <span class="err">~~</span> <span class="point">^</span>
+                                  <span class="err">~~</span> <span class="msg"><span class="point">^</span></span>
                                   <span class="snip">.y = </span>
 </pre>
 
@@ -256,8 +222,8 @@
 diagnostic.<p>
 
 <pre>
-  $ <b>clang t.cpp</b>
-  t.cpp:9:3: <span class="err">error:</span> template specialization requires 'template&lt;&gt;'
+  $ <span class="cmd">clang t.cpp</span>
+  <span class="loc">t.cpp:9:3:</span> <span class="err">error:</span> <span class="msg">template specialization requires 'template&lt;&gt;'</span>
     struct iterator_traits&lt;file_iterator&gt; {
     <span class="point">^</span>
     <span class="snip">template&lt;&gt; </span>
@@ -273,15 +239,15 @@
 
 Default: template diff with type elision
 <pre>
-t.cc:4:5: <span class="note">note:</span> candidate function not viable: no known conversion from 'vector&lt;map&lt;[...], <span class="template-highlight">float</span>&gt;&gt;' to 'vector&lt;map&lt;[...], <span class="template-highlight">double</span>&gt;&gt;' for 1st argument;
+<span class="loc">t.cc:4:5:</span> <span class="note">note:</span> candidate function not viable: no known conversion from 'vector&lt;map&lt;[...], <span class="template-highlight">float</span>&gt;&gt;' to 'vector&lt;map&lt;[...], <span class="template-highlight">double</span>&gt;&gt;' for 1st argument;
 </pre>
 -fno-elide-type: template diff without elision
 <pre>
-t.cc:4:5: <span class="note">note:</span> candidate function not viable: no known conversion from 'vector&lt;map&lt;int, <span class="template-highlight">float</span>&gt;&gt;' to 'vector&lt;map&lt;int, <span class="template-highlight">double</span>&gt;&gt;' for 1st argument;
+<span class="loc">t.cc:4:5:</span> <span class="note">note:</span> candidate function not viable: no known conversion from 'vector&lt;map&lt;int, <span class="template-highlight">float</span>&gt;&gt;' to 'vector&lt;map&lt;int, <span class="template-highlight">double</span>&gt;&gt;' for 1st argument;
 </pre>
 -fdiagnostics-show-template-tree: template tree printing with elision
 <pre>
-t.cc:4:5: <span class="note">note:</span> candidate function not viable: no known conversion for 1st argument;
+<span class="loc">t.cc:4:5:</span> <span class="note">note:</span> candidate function not viable: no known conversion for 1st argument;
   vector&lt;
     map&lt;
       [...], 
@@ -289,7 +255,7 @@
 </pre>
 -fdiagnostics-show-template-tree -fno-elide-type: template tree printing with no elision
 <pre>
-t.cc:4:5: <span class="note">note:M</span> candidate function not viable: no known conversion for 1st argument;
+<span class="loc">t.cc:4:5:</span> <span class="note">note:</span> candidate function not viable: no known conversion for 1st argument;
   vector&lt;
     map&lt;
       int, 
@@ -306,14 +272,11 @@
 and also shows how some of the other pieces work in a bigger example.</p>
 
 <pre>
-  $ <b>gcc-4.2 -fsyntax-only t.c</b>
-  t.c: In function 'test':
-  t.c:80: error: invalid operands to binary &lt; (have 'struct mystruct' and 'float')
-  $ <b>clang -fsyntax-only t.c</b>
-  t.c:80:3: <span class="err">error:</span> invalid operands to binary expression ('typeof(P)' (aka 'struct mystruct') and 'typeof(F)' (aka 'float'))
+  $ <span class="cmd">clang -fsyntax-only t.c</span>
+  <span class="loc">t.c:80:3:</span> <span class="err">error:</span> <span class="msg">invalid operands to binary expression ('typeof(P)' (aka 'struct mystruct') and 'typeof(F)' (aka 'float'))</span>
   <span class="snip">  X = MYMAX(P, F);</span>
   <span class="point">      ^~~~~~~~~~~</span>
-  t.c:76:94: note: expanded from:
+  <span class="loc">t.c:76:94:</span> <span class="note">note:</span> expanded from:
   <span class="snip">#define MYMAX(A,B)    __extension__ ({ __typeof__(A) __a = (A); __typeof__(B) __b = (B); __a &lt; __b ? __b : __a; })</span>
   <span class="point">                                                                                         ~~~ ^ ~~~</span>
 </pre>
@@ -322,14 +285,14 @@
 implements the "wwopen" class of APIs):</p>
 
 <pre>
-  $ <b>clang -fsyntax-only t.c</b>
-  t.c:22:2: <span class="warn">warning:</span> type specifier missing, defaults to 'int'
+  $ <span class="cmd">clang -fsyntax-only t.c</span>
+  <span class="loc">t.c:22:2:</span> <span class="warn">warning:</span> <span class="msg">type specifier missing, defaults to 'int'</span>
   <span class="snip">        ILPAD();</span>
   <span class="point">        ^</span>
-  t.c:17:17: note: expanded from:
+  <span class="loc">t.c:17:17:</span> <span class="note">note:</span> expanded from:
   <span class="snip">#define ILPAD() PAD((NROW - tt.tt_row) * 10)    /* 1 ms per char */</span>
   <span class="point">                ^</span>
-  t.c:14:2: note: expanded from:
+  <span class="loc">t.c:14:2:</span> <span class="note">note:</span> expanded from:
   <span class="snip">        register i; \</span>
   <span class="point">        ^</span>
 </pre>
@@ -342,63 +305,65 @@
 <p>Finally, we have put a lot of work polishing the little things, because
 little things add up over time and contribute to a great user experience.</p>
 
-<p>The following example shows a trivial little tweak, where we tell you to put the semicolon at
-the end of the line that is missing it (line 4) instead of at the beginning of
-the following line (line 5).  This is particularly important with fixit hints
-and point diagnostics, because otherwise you don't get the important context.
-</p>
-
-<pre>
-  $ <b>gcc-4.2 t.c</b>
-  t.c: In function 'foo':
-  t.c:5: error: expected ';' before '}' token
-  $ <b>clang t.c</b>
-  t.c:4:8: <span class="err">error:</span> expected ';' after expression
-  <span class="snip">  bar()</span>
-  <span class="point">       ^</span>
-  <span class="point">       ;</span>
-</pre>
-
-<p>The following example shows much better error recovery than GCC. The message coming out
-of GCC is completely useless for diagnosing the problem. Clang tries much harder
-and produces a much more useful diagnosis of the problem.</p>
-
-<pre>
-  $ <b>gcc-4.2 t.c</b>
-  t.c:3: error: expected '=', ',', ';', 'asm' or '__attribute__' before '*' token
-  $ <b>clang t.c</b>
-  t.c:3:1: <span class="err">error:</span> unknown type name 'foo_t'
-  <span class="snip">foo_t *P = 0;</span>
-  <span class="point">^</span>
-</pre>
-
 <p>The following example shows that we recover from the simple case of
 forgetting a ; after a struct definition much better than GCC.</p>
 
 <pre>
-  $ <b>cat t.cc</b>
+  $ <span class="cmd">cat t.cc</span>
   template&lt;class T&gt;
-  class a {}
-  class temp {};
-  a&lt;temp&gt; b;
-  struct b {
-  }
-  $ <b>gcc-4.2 t.cc</b>
-  t.cc:3: error: multiple types in one declaration
-  t.cc:4: error: non-template type 'a' used as a template
-  t.cc:4: error: invalid type in declaration before ';' token
-  t.cc:6: error: expected unqualified-id at end of input
-  $ <b>clang t.cc</b>
-  t.cc:2:11: <span class="err">error:</span> expected ';' after class
-  <span class="snip">class a {}</span>
-  <span class="point">          ^</span>
-  <span class="point">          ;</span>
-  t.cc:6:2: <span class="err">error:</span> expected ';' after struct
-  <span class="snip">}</span>
-  <span class="point"> ^</span>
-  <span class="point"> ;</span>
+  class a {};
+  struct b {}
+  a&lt;int&gt; c;
+  $ <span class="cmd">gcc-4.9 t.cc</span>
+  t.cc:4:8: error: invalid declarator before 'c'
+   a&lt;int&gt; c;
+           ^
+  $ <span class="cmd">clang t.cc</span>
+  <span class="loc">t.cc:3:12:</span> <span class="err">error:</span> <span class="msg">expected ';' after struct</span>
+  <span class="snip" >struct b {}</span>
+  <span class="point">           ^</span>
+  <span class="point">           ;</span>
 </pre>
 
+<p>The following example shows that we diagnose and recover from a missing
+<tt>typename</tt> keyword well, even in complex circumstances where GCC
+cannot cope.</p>
+
+<pre>
+  $ <span class="cmd">cat t.cc</span>
+  template&lt;class T&gt; void f(T::type) { }
+  struct A { };
+  void g()
+  {
+      A a;
+      f&lt;A&gt;(a);
+  }
+  $ <span class="cmd">gcc-4.9 t.cc</span>
+  t.cc:1:33: error: variable or field 'f' declared void
+   template&lt;class T&gt; void f(T::type) { }
+                                   ^
+  t.cc: In function 'void g()':
+  t.cc:6:5: error: 'f' was not declared in this scope
+       f&lt;A&gt;(a);
+       ^
+  t.cc:6:8: error: expected primary-expression before '>' token
+       f&lt;A&gt;(a);
+          ^
+  $ <span class="cmd">clang t.cc</span>
+  <span class="loc">t.cc:1:26:</span> <span class="err">error:</span> <span class="msg">missing 'typename' prior to dependent type name 'T::type'</span>
+  <span class="snip" >template&lt;class T&gt; void f(T::type) { }</span>
+  <span class="point">                         ^~~~~~~</span>
+  <span class="point">                         typename </span>
+  <span class="loc">t.cc:6:5:</span> <span class="err">error:</span> <span class="msg">no matching function for call to 'f'</span>
+  <span class="snip" >    f&lt;A&gt;(a);</span>
+  <span class="point">    ^~~~</span>
+  <span class="loc">t.cc:1:24:</span> <span class="note">note:</span> <span class="msg">candidate template ignored: substitution failure [with T = A]: no type named 'type' in 'A'</span>
+  <span class="snip" >template&lt;class T&gt; void f(T::type) { }</span>
+  <span class="point">                       ^    ~~~~</span>
+</pre>
+
+
+
 <p>While each of these details is minor, we feel that they all add up to provide
 a much more polished experience.</p>
 
diff --git a/www/features.html b/www/features.html
index 2d3191e..8a1c856 100644
--- a/www/features.html
+++ b/www/features.html
@@ -65,71 +65,18 @@
 <p>A major focus of our work on clang is to make it fast, light and scalable.
 The library-based architecture of clang makes it straight-forward to time and
 profile the cost of each layer of the stack, and the driver has a number of
-options for performance analysis.</p>
-
-<p>While there is still much that can be done, we find that the clang front-end
-is significantly quicker than gcc and uses less memory  For example, when
-compiling "Carbon.h" on Mac OS/X, we see that clang is 2.5x faster than GCC:</p>
-
-<img class="img_slide" src="feature-compile1.png" width="400" height="300"
-     alt="Time to parse carbon.h: -fsyntax-only">
-
-<p>Carbon.h is a monster: it transitively includes 558 files, 12.3M of code,
-declares 10000 functions, has 2000 struct definitions, 8000 fields, 20000 enum
-constants, etc (see slide 25+ of the <a href="clang_video-07-25-2007.html">clang 
-talk</a> for more information). It is also #include'd into almost every C file
-in a GUI app on the Mac, so its compile time is very important.</p>
-
-<p>From the slide above, you can see that we can measure the time to preprocess
-the file independently from the time to parse it, and independently from the
-time to build the ASTs for the code.  GCC doesn't provide a way to measure the
-parser without AST building (it only provides -fsyntax-only).  In our
-measurements, we find that clang's preprocessor is consistently 40% faster than
-GCCs, and the parser + AST builder is ~4x faster than GCC's.  If you have
-sources that do not depend as heavily on the preprocessor (or if you 
-use Precompiled Headers) you may see a much bigger speedup from clang.
-</p>
+options for performance analysis. Many detailed benchmarks can be found online.</p>
 
 <p>Compile time performance is important, but when using clang as an API, often
 memory use is even moreso: the less memory the code takes the more code you can
 fit into memory at a time (useful for whole program analysis tools, for
 example).</p>
 
-<img class="img_slide" src="feature-memory1.png" width="400" height="300"
-     alt="Space">
-
-<p>Here we see a huge advantage of clang: its ASTs take <b>5x less memory</b>
-than GCC's syntax trees, despite the fact that clang's ASTs capture far more 
-source-level information than GCC's trees do.  This feat is accomplished through
-the use of carefully designed APIs and efficient representations.</p>
-
 <p>In addition to being efficient when pitted head-to-head against GCC in batch
-mode, clang is built with a <a href="#libraryarch">library based 
+mode, clang is built with a <a href="#libraryarch">library based
 architecture</a> that makes it relatively easy to adapt it and build new tools
 with it.  This means that it is often possible to apply out-of-the-box thinking
-and novel techniques to improve compilation in various ways.</p> 
-  
-<img class="img_slide" src="feature-compile2.png" width="400" height="300"
-     alt="Preprocessor Speeds: GCC 4.2 vs clang-all">
-
-<p>This slide shows how the clang preprocessor can be used to make "distcc"
-parallelization <b>3x</b> more scalable than when using the GCC preprocessor.
-"distcc" quickly bottlenecks on the preprocessor running on the central driver
-machine, so a fast preprocessor is very useful.  Comparing the first two bars
-of each group shows how a ~40% faster preprocessor can reduce preprocessing time
-of these large C++ apps by about 40% (shocking!).</p>
-
-<p>The third bar on the slide is the interesting part: it shows how trivial
-caching of file system accesses across invocations of the preprocessor allows 
-clang to reduce time spent in the kernel by 10x, making distcc over 3x more
-scalable.  This is obviously just one simple hack, doing more interesting things
-(like caching tokens across preprocessed files) would yield another substantial
-speedup.</p>
-
-<p>The clean framework-based design of clang means that many things are possible
-that would be very difficult in other systems, for example incremental
-compilation, multithreading, intelligent caching, etc.  We are only starting
-to tap the full potential of the clang design.</p>
+and novel techniques to improve compilation in various ways.</p>
 
 
 <!--=======================================================================-->
@@ -157,7 +104,7 @@
 </pre>
 
 <p>Here you can see that you don't even need to see the original source code to
-understand what is wrong based on the Clang error: Because clang prints a
+understand what is wrong based on the Clang error: Because Clang prints a
 caret, you know exactly <em>which</em> plus it is complaining about.  The range
 information highlights the left and right side of the plus which makes it
 immediately obvious what the compiler is talking about, which is very useful for
diff --git a/www/get_involved.html b/www/get_involved.html
index 9ed2d47..06fee59 100644
--- a/www/get_involved.html
+++ b/www/get_involved.html
@@ -21,6 +21,11 @@
 the development of the project to see it progress.
 </p>
 
+<h2>Contribute</h2>
+
+See the <a href="hacking.html">hacking</a> document for information on how
+to author patches.
+
 <h2>Follow what's going on</h2>
 
 <p>Clang is a subproject of the <a href="http://llvm.org">LLVM Project</a>, but
@@ -54,7 +59,13 @@
 list</a>.  All of these lists have archives, so you can browse through previous
 discussions or follow the list development on the web if you prefer.</p>
 
-<p>If you're looking for something to work on, check out our <a href="OpenProjects.html">Open Projects</a> page or go look through the <a href="http://llvm.org/bugs/">Bugzilla bug database</a>.</p>
+<p>You can also follow the <a href="http://planet.clang.org/">Planet Clang</a>
+community news feed which offers a window into the world, work and lives of
+Clang developers, contributors and the standards they implement.</p>
+
+<p>If you're looking for something to work on, check out our <a
+href="OpenProjects.html">Open Projects</a> page or look through the <a
+href="http://llvm.org/bugs/">Bugzilla bug database</a>.</p>
 
 <h2 id="criteria">Contributing Extensions to Clang</h2>
 
diff --git a/www/get_started.html b/www/get_started.html
index 5128331..6f08f5e 100644
--- a/www/get_started.html
+++ b/www/get_started.html
@@ -23,9 +23,8 @@
 
 <h2 id="download">Release Clang Versions</h2>
 
-<p>Clang has been released as part of regular LLVM releases since LLVM 2.6. You
-can download the release versions
-from <a href="http://llvm.org/releases/">http://llvm.org/releases/</a>.</p>
+<p>Clang is released as part of regular LLVM releases. You can download the release versions from <a href="http://llvm.org/releases/">http://llvm.org/releases/</a>.</p>
+<p>Clang is also provided in all major BSD or GNU/Linux distributions as part of their respective packaging systems. From Xcode 4.2, Clang is the default compiler for Mac OS X.</p>
 
 <h2 id="build">Building Clang and Working with the Code</h2>
 
@@ -142,7 +141,7 @@
         project files.  Get it from:
         <a href="http://www.cmake.org/cmake/resources/software.html">
         http://www.cmake.org/cmake/resources/software.html</a></li>
-    <li><b>Visual Studio 2008 or 2010</b></li>
+    <li><b>Visual Studio 2012 or later</b></li>
     <li><b>Python</b>.  This is needed only if you will be running the tests
         (which is essential, if you will be developing for clang).
         Get it from:
@@ -174,8 +173,7 @@
     <li><tt>cd ..\..</tt>  (back to where you started)</li>
     <li><tt>mkdir build</tt> (for building without polluting the source dir)</li>
     <li><tt>cd build</tt></li>
-    <li>If you are using Visual Studio 2008:  <tt>cmake -G "Visual Studio 9 2008" ..\llvm</tt></li>
-    <li>Or if you are using Visual Studio 2010:  <tt>cmake -G "Visual Studio 10" ..\llvm</tt></li>
+    <li>If you are using Visual Studio 2012:  <tt>cmake -G "Visual Studio 11" ..\llvm</tt></li>
     <li>See the <a href="http://www.llvm.org/docs/CMake.html">LLVM CMake guide</a> for
         more information on other configuration options for CMake.</li>
     <li>The above, if successful, will have created an LLVM.sln file in the
diff --git a/www/hacking.html b/www/hacking.html
index a1ff8d4..4535ef4 100644
--- a/www/hacking.html
+++ b/www/hacking.html
@@ -97,31 +97,20 @@
   <h3 id="debuggingVisualStudio">Debugging using Visual Studio</h3>
   <!--=====================================================================-->
 
-  <p>The file <tt>utils/clangVisualizers.txt</tt> provides debugger visualizers that make debugging
-  of more complex data types much easier.</p>
-  <p>There are two ways to install them:</p>
-  
-  <ul>
-      <li>Put the path to <tt>clangVisualizers.txt</tt> in the environment variable called
-      <tt>_vcee_autoexp</tt>. This method should work for Visual Studio 2008 and above.
-      </li>
-      <li>Edit your local <tt>autoexp.dat</tt> (make sure you make a backup first!), 
-      located in <tt>Visual Studio Directory\Common7\Packages\Debugger</tt> and append 
-      the contents of <tt>clangVisuailzers.txt</tt> to it. This method should work for 
-      Visual Studio 2008 and above.
-       </li>
-  </ul>
-
-  <p><i>[Note: To disable the visualizer for any specific variable, type 
-  <tt>variable_name,!</tt> inside the watch window.]</i></p>
+  <p>The files 
+    <a href="http://llvm.org/svn/llvm-project/llvm/trunk/utils/llvm.natvis">
+      <tt>utils/llvm.natvis</tt></a> and 
+    <a href="http://llvm.org/svn/llvm-project/cfe/trunk/utils/clang.natvis">
+      <tt>utils/clang.natvis</tt></a> provide debugger visualizers 
+      that make debugging of more complex data types much easier.</p>
+  <p>Put the files into 
+    <tt>%USERPROFILE%\Documents\Visual Studio 2012\Visualizers</tt> or 
+    create a symbolic link so they update automatically.</p>
 
   <!--=====================================================================-->
   <h2 id="testing">Testing</h2>
   <!--=====================================================================-->
 
-  <p><i>[Note: The test running mechanism is currently under revision, so the
-  following might change shortly.]</i></p>
-
   <!--=====================================================================-->
   <h3 id="testingNonWindows">Testing on Unix-like Systems</h3>
   <!--=====================================================================-->
@@ -287,9 +276,10 @@
   <p>To return changes to the Clang team, unless you have checkin
   privileges, the preferred way is to send patch files to the
   cfe-commits mailing list, with an explanation of what the patch is
-  for.  If your patch requires a wider discussion (for example,
-  because it is an architectural change), you can use the cfe-dev
-  mailing list.  </p>
+  for.  clang follows <a
+  href="http://llvm.org/docs/DeveloperPolicy.html">LLVM's developer policy</a>.
+  If your patch requires a wider discussion (for example, because it is an
+  architectural change), you can use the cfe-dev mailing list.</p>
 
   <p>To create these patch files, change directory
   to the llvm/tools/clang root and run:</p>
diff --git a/www/index.html b/www/index.html
index 23d82e3..2d3ca8f 100644
--- a/www/index.html
+++ b/www/index.html
@@ -40,7 +40,7 @@
   <ul>
   <li>Modular library based architecture</li>
   <li>Support diverse clients (refactoring, static analysis, code generation,
-   etc)</li>
+   etc.)</li>
   <li>Allow tight integration with IDEs</li>
   <li>Use the LLVM 'BSD' License</li>
   </ul>
@@ -65,7 +65,7 @@
   <h2>Why?</h2>
   <!--=====================================================================-->
   
-  <p>The development of a new front-end was started out of a need -- a need
+  <p>Development of the new front-end was started out of a need
      for a compiler that allows better diagnostics, better integration with
      IDEs, a license that is compatible with commercial products, and a
      nimble compiler that is easy to develop and maintain.  All of these were
@@ -89,7 +89,7 @@
   <h2>Current Status</h2>
   <!--=====================================================================-->
   
-  <p>Clang is still under heavy development.  Clang is considered to
+  <p>Clang is considered to
    be a production quality C, Objective-C, C++ and Objective-C++ compiler when 
    targeting X86-32, X86-64, and ARM (other targets may have caveats, but are 
    usually easy to fix).  If you are looking for source analysis or
diff --git a/www/make_cxx_dr_status b/www/make_cxx_dr_status
index 4750e1b..82e8abd 100755
--- a/www/make_cxx_dr_status
+++ b/www/make_cxx_dr_status
@@ -51,6 +51,7 @@
 print >> out_file, '''\
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
           "http://www.w3.org/TR/html4/strict.dtd">
+<!-- This file is auto-generated by make_cxx_dr_status. Do not modify. -->
 <html>
 <head>
   <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
@@ -65,7 +66,7 @@
     .na { background-color: #DDDDDD }
     .open * { color: #AAAAAA }
     //.open { filter: opacity(0.2) }
-    span:target { background-color: #FFFFBB; outline: #DDDD55 solid thin; }
+    tr:target { background-color: #FFFFBB }
     th { background-color: #FFDDAA }
   </style>
 </head>
@@ -101,10 +102,10 @@
   if status == 'unknown':
     avail = 'Unknown'
     avail_style = ' class="none"'
-  elif status == '3.4':
+  elif status == '3.5':
     avail = 'SVN'
     avail_style = ' class="svn"'
-  elif status in ('3.1', '3.2', '3.3'):
+  elif status in ('3.1', '3.2', '3.3', '3.4'):
     avail = 'Clang %s' % status
     avail_style = ' class="full"'
   elif status == 'yes':
@@ -121,7 +122,7 @@
     avail_style = ' class="na"'
   elif status.startswith('sup '):
     dup = status.split(' ', 1)[1]
-    avail = 'Superseded by %s' % dup
+    avail = 'Superseded by <a href="#%s">%s</a>' % (dup, dup)
     try:
       _, avail_style = availability(int(dup))
     except:
@@ -129,7 +130,7 @@
       avail_style = ' class="none"'
   elif status.startswith('dup '):
     dup = int(status.split(' ', 1)[1])
-    avail = 'Duplicate of %s' % dup
+    avail = 'Duplicate of <a href="#%s">%s</a>' % (dup, dup)
     _, avail_style = availability(dup)
   else:
     assert False, 'unknown status %s for issue %s' % (status, dr.issue)
@@ -153,13 +154,12 @@
       count[avail] = count.get(avail, 0) + 1
 
   print >> out_file, '''\
-  <tr%s>
+  <tr%s id="%s">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/%s">%s</a></td>
     <td>%s</td>
     <td>%s</td>
     <td%s align="center">%s</td>
-  </tr>''' % (row_style, dr.url, dr.issue, dr.status, dr.title, avail_style,
-              avail)
+  </tr>''' % (row_style, dr.issue, dr.url, dr.issue, dr.status, dr.title, avail_style, avail)
 
 for status, num in count.items():
   print "%s: %s" % (status, num)
diff --git a/www/menu.html.incl b/www/menu.html.incl
index 4382991..b8689d1 100644
--- a/www/menu.html.incl
+++ b/www/menu.html.incl
@@ -35,8 +35,9 @@
     <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-users">cfe-users List</a>
     <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev">cfe-dev List</a>
     <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits">cfe-commits List</a>
-    <a href="irc://irc.oftc.net/llvm">IRC: irc.oftc.net#llvm</a>
     <a href="http://llvm.org/bugs/">Bug Reports</a>
+    <a href="http://planet.clang.org/">Planet Clang</a>
+    <a href="irc://irc.oftc.net/llvm">IRC: irc.oftc.net#llvm</a>
   </div>
 
   <div class="submenu">
diff --git a/www/related.html b/www/related.html
index 8191daa..62dd263 100644
--- a/www/related.html
+++ b/www/related.html
@@ -19,7 +19,7 @@
       custom analysis tools using Clang. This page tracks some of those Clang
       related projects.</p>
 
-    <p>Please email cfe-dev if you have a Clang related project you would like
+    <p>Please email <a href="get_involved.html">cfe-dev</a> if you have a Clang related project you would like
       added to this list.</p>
 
     <dl>